[clang] [compiler-rt] [lld] [llvm] [Coverage][WebAssembly] Add initial support for WebAssembly/WASI (PR #111332)
Yuta Saito via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 7 00:11:01 PDT 2024
https://github.com/kateinoigakukun updated https://github.com/llvm/llvm-project/pull/111332
>From 605e1ad180c9f75fd59d8b783ae2041cbaf34e50 Mon Sep 17 00:00:00 2001
From: Yuta Saito <kateinoigakukun at gmail.com>
Date: Sat, 5 Oct 2024 16:54:57 +0000
Subject: [PATCH 1/7] [compiler-rt][profile] Add initial support for
WebAssembly/WASI
This patch adds initial support for WebAssembly/WASI to the profile
runtime library on the top of wasi-libc. This is a part of the ongoing
patch series to add coverage support for WebAssembly/WASI.
The patch includes the following changes:
* Add wasm32-wasi to the list of supported architectures/OSes.
* Exclude unsupported features for WASI: flock, madvise, uname.
* Enable some user-space emulation provided by wasi-libc: mmap, getpid
---
.../cmake/Modules/AllSupportedArchDefs.cmake | 2 +-
compiler-rt/cmake/config-ix.cmake | 2 +-
compiler-rt/lib/profile/CMakeLists.txt | 24 +++++++++++++++++++
compiler-rt/lib/profile/GCDAProfiling.c | 2 +-
compiler-rt/lib/profile/InstrProfilingPort.h | 2 +-
compiler-rt/lib/profile/InstrProfilingUtil.c | 12 ++++++----
6 files changed, 36 insertions(+), 8 deletions(-)
diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
index 809e9277156912..d00d39518104bf 100644
--- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
+++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake
@@ -77,7 +77,7 @@ set(ALL_HWASAN_SUPPORTED_ARCH ${X86_64} ${ARM64} ${RISCV64})
set(ALL_MEMPROF_SUPPORTED_ARCH ${X86_64})
set(ALL_PROFILE_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} ${PPC64}
${MIPS32} ${MIPS64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON}
- ${RISCV32} ${RISCV64} ${LOONGARCH64})
+ ${RISCV32} ${RISCV64} ${LOONGARCH64} ${WASM32})
set(ALL_CTX_PROFILE_SUPPORTED_ARCH ${X86_64})
if (OS_NAME MATCHES "FreeBSD")
set(ALL_TSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})
diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake
index a93a88a9205001..a494e0532a50bc 100644
--- a/compiler-rt/cmake/config-ix.cmake
+++ b/compiler-rt/cmake/config-ix.cmake
@@ -822,7 +822,7 @@ else()
endif()
if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND
- OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX")
+ OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD|AIX|WASI")
set(COMPILER_RT_HAS_PROFILE TRUE)
else()
set(COMPILER_RT_HAS_PROFILE FALSE)
diff --git a/compiler-rt/lib/profile/CMakeLists.txt b/compiler-rt/lib/profile/CMakeLists.txt
index ef23492514898b..a6402f80b890a2 100644
--- a/compiler-rt/lib/profile/CMakeLists.txt
+++ b/compiler-rt/lib/profile/CMakeLists.txt
@@ -38,6 +38,17 @@ int main() {
" COMPILER_RT_TARGET_HAS_FCNTL_LCK)
+CHECK_CXX_SOURCE_COMPILES("
+#include <sys/file.h>
+
+int fd;
+int main() {
+ flock(fd, LOCK_EX);
+ return 0;
+}
+
+" COMPILER_RT_TARGET_HAS_FLOCK)
+
CHECK_CXX_SOURCE_COMPILES("
#include <sys/utsname.h>
int main() {
@@ -93,6 +104,13 @@ if(FUCHSIA OR UNIX)
-Wno-pedantic)
endif()
+if(CMAKE_SYSTEM_NAME STREQUAL "WASI")
+ set(EXTRA_FLAGS
+ ${EXTRA_FLAGS}
+ -D_WASI_EMULATED_MMAN
+ -D_WASI_EMULATED_GETPID)
+endif()
+
if(COMPILER_RT_TARGET_HAS_ATOMICS)
set(EXTRA_FLAGS
${EXTRA_FLAGS}
@@ -105,6 +123,12 @@ if(COMPILER_RT_TARGET_HAS_FCNTL_LCK)
-DCOMPILER_RT_HAS_FCNTL_LCK=1)
endif()
+if(COMPILER_RT_TARGET_HAS_FLOCK)
+ set(EXTRA_FLAGS
+ ${EXTRA_FLAGS}
+ -DCOMPILER_RT_HAS_FLOCK=1)
+endif()
+
if(COMPILER_RT_TARGET_HAS_UNAME)
set(EXTRA_FLAGS
${EXTRA_FLAGS}
diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
index d6e2175169e4a5..a207ddf97c8831 100644
--- a/compiler-rt/lib/profile/GCDAProfiling.c
+++ b/compiler-rt/lib/profile/GCDAProfiling.c
@@ -584,7 +584,7 @@ void llvm_reset_counters(void) {
}
}
-#if !defined(_WIN32)
+#if !defined(_WIN32) && !defined(__wasi__)
COMPILER_RT_VISIBILITY
pid_t __gcov_fork() {
pid_t parent_pid = getpid();
diff --git a/compiler-rt/lib/profile/InstrProfilingPort.h b/compiler-rt/lib/profile/InstrProfilingPort.h
index ed0905cc5f2022..8715a3b0d2a6f0 100644
--- a/compiler-rt/lib/profile/InstrProfilingPort.h
+++ b/compiler-rt/lib/profile/InstrProfilingPort.h
@@ -54,7 +54,7 @@
#endif
#define COMPILER_RT_MAX_HOSTLEN 128
-#ifdef __ORBIS__
+#if defined(__ORBIS__) || defined(__wasi__)
#define COMPILER_RT_GETHOSTNAME(Name, Len) ((void)(Name), (void)(Len), (-1))
#else
#define COMPILER_RT_GETHOSTNAME(Name, Len) lprofGetHostName(Name, Len)
diff --git a/compiler-rt/lib/profile/InstrProfilingUtil.c b/compiler-rt/lib/profile/InstrProfilingUtil.c
index 642393d432d7ea..95ec4080ba2504 100644
--- a/compiler-rt/lib/profile/InstrProfilingUtil.c
+++ b/compiler-rt/lib/profile/InstrProfilingUtil.c
@@ -152,9 +152,11 @@ COMPILER_RT_VISIBILITY int lprofLockFd(int fd) {
}
}
return 0;
-#else
+#elif defined(COMPILER_RT_HAS_FLOCK)
flock(fd, LOCK_EX);
return 0;
+#else
+ return 0;
#endif
}
@@ -177,9 +179,11 @@ COMPILER_RT_VISIBILITY int lprofUnlockFd(int fd) {
}
}
return 0;
-#else
+#elif defined(COMPILER_RT_HAS_FLOCK)
flock(fd, LOCK_UN);
return 0;
+#else
+ return 0;
#endif
}
@@ -353,8 +357,8 @@ COMPILER_RT_VISIBILITY void lprofRestoreSigKill(void) {
COMPILER_RT_VISIBILITY int lprofReleaseMemoryPagesToOS(uintptr_t Begin,
uintptr_t End) {
-#if defined(__ve__)
- // VE doesn't support madvise.
+#if defined(__ve__) || defined(__wasi__)
+ // VE and WASI doesn't support madvise.
return 0;
#else
size_t PageSize = getpagesize();
>From 5939422c1022d8d85355a800ea7341d56c0378bb Mon Sep 17 00:00:00 2001
From: Yuta Saito <kateinoigakukun at gmail.com>
Date: Sat, 5 Oct 2024 17:08:14 +0000
Subject: [PATCH 2/7] [compiler-rt][profile] Use encapsulation symbols for Wasm
format
Use `InstrProfilingPlatformLinux.c` for Wasm as well as Wasm format
has encapsulation symbols (`__start_` and `__stop_`) similar to ELF.
This unlocks several additional profile features like value profiling.
---
compiler-rt/lib/profile/InstrProfilingPlatformLinux.c | 8 ++++----
compiler-rt/lib/profile/InstrProfilingPlatformOther.c | 3 ++-
llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp | 5 +++--
llvm/test/Instrumentation/InstrProfiling/profiling.ll | 7 +------
4 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
index b766436497b741..02f23379ce98bf 100644
--- a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
+++ b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c
@@ -6,11 +6,11 @@
|*
\*===----------------------------------------------------------------------===*/
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
- (defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) || \
- defined(_AIX)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
+ (defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) || \
+ defined(_AIX) || defined(__wasm__)
-#if !defined(_AIX)
+#if !defined(_AIX) && !defined(__wasm__)
#include <elf.h>
#include <link.h>
#endif
diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
index aa79a5641ceca6..52e82273f8aade 100644
--- a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
+++ b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c
@@ -8,7 +8,8 @@
#if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) && \
!defined(__Fuchsia__) && !(defined(__sun__) && defined(__svr4__)) && \
- !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX)
+ !defined(__NetBSD__) && !defined(_WIN32) && !defined(_AIX) && \
+ !defined(__wasm__)
#include <stdlib.h>
#include <stdio.h>
diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
index 1c95a4606ecc56..929c787442057a 100644
--- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -1406,9 +1406,10 @@ static inline Constant *getFuncAddrForProfData(Function *Fn) {
static bool needsRuntimeRegistrationOfSectionRange(const Triple &TT) {
// compiler-rt uses linker support to get data/counters/name start/end for
- // ELF, COFF, Mach-O and XCOFF.
+ // ELF, COFF, Mach-O, XCOFF, and Wasm.
if (TT.isOSBinFormatELF() || TT.isOSBinFormatCOFF() ||
- TT.isOSBinFormatMachO() || TT.isOSBinFormatXCOFF())
+ TT.isOSBinFormatMachO() || TT.isOSBinFormatXCOFF() ||
+ TT.isOSBinFormatWasm())
return false;
return true;
diff --git a/llvm/test/Instrumentation/InstrProfiling/profiling.ll b/llvm/test/Instrumentation/InstrProfiling/profiling.ll
index e7678a9dce0891..74dd54cef50fb5 100644
--- a/llvm/test/Instrumentation/InstrProfiling/profiling.ll
+++ b/llvm/test/Instrumentation/InstrProfiling/profiling.ll
@@ -114,11 +114,6 @@ declare void @llvm.instrprof.increment(ptr, i64, i32, i32)
; PS: %[[REG:.*]] = load i32, ptr @__llvm_profile_runtime
; XCOFF-NOT: define .* __llvm_profile_runtime_user
-; WASM: define internal void @__llvm_profile_register_functions() unnamed_addr {
-; WASM-NEXT: call void @__llvm_profile_register_function(ptr @__profd_foo)
-; WASM-NEXT: call void @__llvm_profile_register_function(ptr @__profd_foo_weak)
-; WASM: call void @__llvm_profile_register_names_function(ptr @__llvm_prf_nm
-; WASM-NEXT: ret void
-; WASM-NEXT: }
+; WASM-NOT: internal void @__llvm_profile_register_functions()
; XCOFF-NOT: internal void @__llvm_profile_register_functions()
>From 141f533bb4b5bcf73aacfbca53eee5b8e8dee067 Mon Sep 17 00:00:00 2001
From: Yuta Saito <kateinoigakukun at gmail.com>
Date: Sat, 5 Oct 2024 17:23:53 +0000
Subject: [PATCH 3/7] [WebAssembly] Emit `__llvm_covmap` and `__llvm_covfun` as
custom sections
This patch makes `__llvm_covmap` and `__llvm_covfun` as custom sections
in the wasm object file because they will not be referenced at runtime
but just used by `llvm-cov` post-processing tools. The same approach is
used in the ELF object file to emit them without `SHF_ALLOC` flag.
Those sections have their associated comdat group symbols, which are
section symbols (not data symbols) in the wasm object file. This patch
also sets the symbol type explicitly not to hit an assertion in the
`WasmObjectWriter::writeOneObject` ("data symbols must live in a data
section").
---
.../CodeGen/TargetLoweringObjectFileImpl.cpp | 6 ++-
llvm/lib/MC/MCContext.cpp | 5 ++
llvm/test/CodeGen/WebAssembly/profile.ll | 47 +++++++++++++++++++
3 files changed, 57 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/WebAssembly/profile.ll
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 0d3e4ba5662e01..ce50a3c19ffe04 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -2171,7 +2171,11 @@ MCSection *TargetLoweringObjectFileWasm::getExplicitSectionGlobal(
// This could be avoided if all data segements (the wasm sense) were
// represented as their own sections (in the llvm sense).
// TODO(sbc): https://github.com/WebAssembly/tool-conventions/issues/138
- if (Name == ".llvmcmd" || Name == ".llvmbc")
+ if (Name == getInstrProfSectionName(IPSK_covmap, Triple::Wasm,
+ /*AddSegmentInfo=*/false) ||
+ Name == getInstrProfSectionName(IPSK_covfun, Triple::Wasm,
+ /*AddSegmentInfo=*/false) ||
+ Name == ".llvmbc" || Name == ".llvmcmd")
Kind = SectionKind::getMetadata();
StringRef Group = "";
diff --git a/llvm/lib/MC/MCContext.cpp b/llvm/lib/MC/MCContext.cpp
index ac3946b6ef46f3..b97f9d9f5fed0f 100644
--- a/llvm/lib/MC/MCContext.cpp
+++ b/llvm/lib/MC/MCContext.cpp
@@ -757,6 +757,11 @@ MCSectionWasm *MCContext::getWasmSection(const Twine &Section, SectionKind K,
if (!Group.isTriviallyEmpty() && !Group.str().empty()) {
GroupSym = cast<MCSymbolWasm>(getOrCreateSymbol(Group));
GroupSym->setComdat(true);
+ if (K.isMetadata() && !GroupSym->getType().has_value()) {
+ // Comdat group symbol associated with a custom section is a section
+ // symbol (not a data symbol).
+ GroupSym->setType(wasm::WASM_SYMBOL_TYPE_SECTION);
+ }
}
return getWasmSection(Section, K, Flags, GroupSym, UniqueID);
diff --git a/llvm/test/CodeGen/WebAssembly/profile.ll b/llvm/test/CodeGen/WebAssembly/profile.ll
new file mode 100644
index 00000000000000..27802cc3bf3567
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/profile.ll
@@ -0,0 +1,47 @@
+; RUN: llc < %s --filetype=obj | obj2yaml | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+$__covrec_A = comdat any
+$__covrec_B = comdat any
+
+ at __covrec_A = linkonce_odr hidden constant <{ i64, i32, i64, i64, [4 x i8] }> <{
+ i64 -1978722966671112904,
+ i32 4,
+ i64 0,
+ i64 -8102528905418564625,
+ [4 x i8] c"\01\01\04\11"
+}>, section "__llvm_covfun", comdat, align 8
+ at __covrec_B = linkonce_odr hidden constant <{ i64, i32, i64, i64, [4 x i8] }> <{
+ i64 8006510647218728891,
+ i32 9,
+ i64 0,
+ i64 -8102528905418564625,
+ [4 x i8] c"\01\01\00\01"
+}>, section "__llvm_covfun", comdat, align 8
+ at __llvm_coverage_mapping = private constant { { i32, i32, i32, i32 }, [4 x i8] } {
+ { i32, i32, i32, i32 } { i32 0, i32 87, i32 0, i32 5 },
+ [4 x i8] c"\01\01\00\02"
+}, section "__llvm_covmap", align 8
+
+; CHECK: - Type: CUSTOM
+; CHECK-NEXT: Name: __llvm_covfun
+; CHECK-NEXT: Payload: 3845A90EF2298AE4040000000000000000000000EF1B31BAE3088E8F01010411
+; CHECK-NEXT: - Type: CUSTOM
+; CHECK-NEXT: Name: __llvm_covfun
+; CHECK-NEXT: Payload: BBEFDA6903D71C6F090000000000000000000000EF1B31BAE3088E8F01010001
+; CHECK-NEXT: - Type: CUSTOM
+; CHECK-NEXT: Name: __llvm_covmap
+; CHECK-NEXT: Payload: '0000000057000000000000000500000001010002'
+; CHECK-NEXT: - Type: CUSTOM
+; CHECK-NEXT: Name: linking
+; CHECK-NEXT: Version: 2
+; CHECK-NEXT: Comdats:
+; CHECK-NEXT: - Name: __covrec_A
+; CHECK-NEXT: Entries:
+; CHECK-NEXT: - Kind: SECTION
+; CHECK-NEXT: Index: 1
+; CHECK-NEXT: - Name: __covrec_B
+; CHECK-NEXT: Entries:
+; CHECK-NEXT: - Kind: SECTION
+; CHECK-NEXT: Index: 2
>From 29cc14ffa418bf61ed677b5495a4606de660bf8d Mon Sep 17 00:00:00 2001
From: Yuta Saito <kateinoigakukun at gmail.com>
Date: Sat, 5 Oct 2024 17:40:17 +0000
Subject: [PATCH 4/7] [wasm-ld][Coverage] Align `__llvm_{covfun,covmap}`
sections to 8 bytes
This patch aligns the `__llvm_{covfun,covmap}` sections to 8 bytes at
the linking stage. This is required because llvm-cov assumes that
records in the sections are 8-byte aligned. Unfortunately, custom
sections does not have an alignment attribute in the WebAssembly linking
spec, so we temporarily do a special case for the metadata sections.
In the future, we should generalize this to support alignment for
relocatable custom sections.
---
lld/test/wasm/custom-section-align.s | 31 ++++++++++++++++++++++++++++
lld/wasm/InputChunks.h | 10 +++++----
lld/wasm/InputFiles.cpp | 18 ++++++++++++++--
lld/wasm/OutputSections.cpp | 1 +
4 files changed, 54 insertions(+), 6 deletions(-)
create mode 100644 lld/test/wasm/custom-section-align.s
diff --git a/lld/test/wasm/custom-section-align.s b/lld/test/wasm/custom-section-align.s
new file mode 100644
index 00000000000000..0e46177f4cdb79
--- /dev/null
+++ b/lld/test/wasm/custom-section-align.s
@@ -0,0 +1,31 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
+# RUN: wasm-ld --no-entry %t.o -o %t.wasm
+# RUN: obj2yaml %t.wasm | FileCheck %s
+
+# Check that "__llvm_covfun" custom section is aligned to 8 bytes.
+
+ .section .custom_section.__llvm_covfun,"GR",@,__covrec_A
+ .int32 1
+ .int8 2
+# pad .int8 0
+# .int8 0
+# .int8 0
+
+ .section .custom_section.__llvm_covfun,"GR",@,__covrec_B
+ .int32 3
+
+# CHECK: - Type: CUSTOM
+# CHECK-NEXT: Name: __llvm_covfun
+# CHECK-NEXT: Payload: '010000000200000003000000'
+
+# Check that regular custom sections are not aligned.
+ .section .custom_section.foo,"GR",@,foo_A
+ .int32 1
+ .int8 2
+
+ .section .custom_section.foo,"GR",@,foo_B
+ .int32 3
+
+# CHECK: - Type: CUSTOM
+# CHECK-NEXT: Name: foo
+# CHECK-NEXT: Payload: '010000000203000000'
diff --git a/lld/wasm/InputChunks.h b/lld/wasm/InputChunks.h
index 14eb008c212fb5..d6769bcf5c8232 100644
--- a/lld/wasm/InputChunks.h
+++ b/lld/wasm/InputChunks.h
@@ -177,8 +177,9 @@ class MergeInputChunk : public InputChunk {
inputSectionOffset = seg.SectionOffset;
}
- MergeInputChunk(const WasmSection &s, ObjFile *f)
- : InputChunk(f, Merge, s.Name, 0, llvm::wasm::WASM_SEG_FLAG_STRINGS) {
+ MergeInputChunk(const WasmSection &s, ObjFile *f, uint32_t alignment)
+ : InputChunk(f, Merge, s.Name, alignment,
+ llvm::wasm::WASM_SEG_FLAG_STRINGS) {
assert(s.Type == llvm::wasm::WASM_SEC_CUSTOM);
comdat = s.Comdat;
rawData = s.Content;
@@ -234,6 +235,7 @@ class SyntheticMergedChunk : public InputChunk {
void addMergeChunk(MergeInputChunk *ms) {
comdat = ms->getComdat();
+ alignment = std::max(alignment, ms->alignment);
ms->parent = this;
chunks.push_back(ms);
}
@@ -337,8 +339,8 @@ class SyntheticFunction : public InputFunction {
// Represents a single Wasm Section within an input file.
class InputSection : public InputChunk {
public:
- InputSection(const WasmSection &s, ObjFile *f)
- : InputChunk(f, InputChunk::Section, s.Name),
+ InputSection(const WasmSection &s, ObjFile *f, uint32_t alignment)
+ : InputChunk(f, InputChunk::Section, s.Name, alignment),
tombstoneValue(getTombstoneForSection(s.Name)), section(s) {
assert(section.Type == llvm::wasm::WASM_SEC_CUSTOM);
comdat = section.Comdat;
diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp
index de8e707ab2b497..a60deba9113cd4 100644
--- a/lld/wasm/InputFiles.cpp
+++ b/lld/wasm/InputFiles.cpp
@@ -18,6 +18,7 @@
#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/Wasm.h"
+#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TarWriter.h"
#include "llvm/Support/raw_ostream.h"
@@ -451,6 +452,18 @@ void SharedFile::parse() {
}
}
+/// Returns the alignment for a custom section. This is used to concatenate
+/// custom sections with the same name into a single custom section.
+static uint32_t getCustomSectionAlignment(const WasmSection &sec) {
+ // TODO: Add a section attribute for alignment in the linking spec.
+ if (sec.Name == getInstrProfSectionName(IPSK_covfun, Triple::Wasm) ||
+ sec.Name == getInstrProfSectionName(IPSK_covmap, Triple::Wasm)) {
+ // llvm-cov assumes that coverage metadata sections are 8-byte aligned.
+ return 8;
+ }
+ return 1;
+}
+
WasmFileBase::WasmFileBase(Kind k, MemoryBufferRef m) : InputFile(k, m) {
// Parse a memory buffer as a wasm file.
LLVM_DEBUG(dbgs() << "Reading object: " << toString(this) << "\n");
@@ -520,10 +533,11 @@ void ObjFile::parse(bool ignoreComdats) {
dataSection = §ion;
} else if (section.Type == WASM_SEC_CUSTOM) {
InputChunk *customSec;
+ uint32_t alignment = getCustomSectionAlignment(section);
if (shouldMerge(section))
- customSec = make<MergeInputChunk>(section, this);
+ customSec = make<MergeInputChunk>(section, this, alignment);
else
- customSec = make<InputSection>(section, this);
+ customSec = make<InputSection>(section, this, alignment);
customSec->discarded = isExcludedByComdat(customSec);
customSections.emplace_back(customSec);
customSections.back()->setRelocations(section.Relocations);
diff --git a/lld/wasm/OutputSections.cpp b/lld/wasm/OutputSections.cpp
index b0b2446cb56bfc..e4f75829ec4c3e 100644
--- a/lld/wasm/OutputSections.cpp
+++ b/lld/wasm/OutputSections.cpp
@@ -244,6 +244,7 @@ void CustomSection::finalizeContents() {
for (InputChunk *section : inputSections) {
assert(!section->discarded);
+ payloadSize = alignTo(payloadSize, section->alignment);
section->outSecOff = payloadSize;
payloadSize += section->getSize();
}
>From f2ad45c9e45708d02810d38680e3e5bfd811b425 Mon Sep 17 00:00:00 2001
From: Yuta Saito <kateinoigakukun at gmail.com>
Date: Sun, 6 Oct 2024 09:24:58 +0000
Subject: [PATCH 5/7] [llvm-cov][WebAssembly] Align coverage mapping section to
8 bytes
Wasm format does not have a good way to insert padding bytes to align
the start of a section contents because the size of each section header
depends on the size of the section contents (leb128 encoding). This
design makes it difficult to align section contents to a specific
alignment to load them by post-processing tools like llvm-cov.
This patch copies the coverage mapping section to a new buffer that is
aligned to 8 bytes if the original section is not aligned. This is
not an ideal solution but it works for now.
---
.../Coverage/CoverageMappingReader.h | 13 +++++++++--
.../Coverage/CoverageMappingReader.cpp | 23 ++++++++++++++-----
2 files changed, 28 insertions(+), 8 deletions(-)
diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
index f05b90114d75a6..886b4d3d6894dc 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
@@ -180,6 +180,7 @@ class BinaryCoverageReader : public CoverageMappingReader {
};
using FuncRecordsStorage = std::unique_ptr<MemoryBuffer>;
+ using CoverageMapCopyStorage = std::unique_ptr<MemoryBuffer>;
private:
std::vector<std::string> Filenames;
@@ -195,9 +196,16 @@ class BinaryCoverageReader : public CoverageMappingReader {
// D69471, which can split up function records into multiple sections on ELF.
FuncRecordsStorage FuncRecords;
+ // Used to tie the lifetimes of an optional copy of the coverage mapping data
+ // to the lifetime of this BinaryCoverageReader instance. Needed to support
+ // Wasm object format, which might require realignment of section contents.
+ CoverageMapCopyStorage CoverageMapCopy;
+
BinaryCoverageReader(std::unique_ptr<InstrProfSymtab> Symtab,
- FuncRecordsStorage &&FuncRecords)
- : ProfileNames(std::move(Symtab)), FuncRecords(std::move(FuncRecords)) {}
+ FuncRecordsStorage &&FuncRecords,
+ CoverageMapCopyStorage &&CoverageMapCopy)
+ : ProfileNames(std::move(Symtab)), FuncRecords(std::move(FuncRecords)),
+ CoverageMapCopy(std::move(CoverageMapCopy)) {}
public:
BinaryCoverageReader(const BinaryCoverageReader &) = delete;
@@ -212,6 +220,7 @@ class BinaryCoverageReader : public CoverageMappingReader {
static Expected<std::unique_ptr<BinaryCoverageReader>>
createCoverageReaderFromBuffer(
StringRef Coverage, FuncRecordsStorage &&FuncRecords,
+ CoverageMapCopyStorage &&CoverageMap,
std::unique_ptr<InstrProfSymtab> ProfileNamesPtr, uint8_t BytesInAddress,
llvm::endianness Endian, StringRef CompilationDir = "");
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
index bc4e780fb67a60..8881bffe41c57c 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -894,13 +894,15 @@ static Error readCoverageMappingData(
Expected<std::unique_ptr<BinaryCoverageReader>>
BinaryCoverageReader::createCoverageReaderFromBuffer(
StringRef Coverage, FuncRecordsStorage &&FuncRecords,
+ CoverageMapCopyStorage &&CoverageMap,
std::unique_ptr<InstrProfSymtab> ProfileNamesPtr, uint8_t BytesInAddress,
llvm::endianness Endian, StringRef CompilationDir) {
if (ProfileNamesPtr == nullptr)
return make_error<CoverageMapError>(coveragemap_error::malformed,
"Caller must provide ProfileNames");
- std::unique_ptr<BinaryCoverageReader> Reader(new BinaryCoverageReader(
- std::move(ProfileNamesPtr), std::move(FuncRecords)));
+ std::unique_ptr<BinaryCoverageReader> Reader(
+ new BinaryCoverageReader(std::move(ProfileNamesPtr),
+ std::move(FuncRecords), std::move(CoverageMap)));
InstrProfSymtab &ProfileNames = *Reader->ProfileNames;
StringRef FuncRecordsRef = Reader->FuncRecords->getBuffer();
if (BytesInAddress == 4 && Endian == llvm::endianness::little) {
@@ -1035,8 +1037,8 @@ loadTestingFormat(StringRef Data, StringRef CompilationDir) {
MemoryBuffer::getMemBuffer(Data);
return BinaryCoverageReader::createCoverageReaderFromBuffer(
- CoverageMapping, std::move(CoverageRecords), std::move(ProfileNames),
- BytesInAddress, Endian, CompilationDir);
+ CoverageMapping, std::move(CoverageRecords), nullptr,
+ std::move(ProfileNames), BytesInAddress, Endian, CompilationDir);
}
/// Find all sections that match \p IPSK name. There may be more than one if
@@ -1136,6 +1138,15 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
return CoverageMappingOrErr.takeError();
StringRef CoverageMapping = CoverageMappingOrErr.get();
+ // If the coverage mapping section is not aligned to 8 bytes, copy it to a
+ // new buffer that is. Wasm format typically has unaligned section contents
+ // because it doesn't have a good way to insert padding bytes.
+ std::unique_ptr<MemoryBuffer> CoverageMapCopy;
+ if (!isAddrAligned(Align(8), CoverageMapping.data())) {
+ CoverageMapCopy = MemoryBuffer::getMemBufferCopy(CoverageMapping);
+ CoverageMapping = CoverageMapCopy->getBuffer();
+ }
+
// Look for the coverage records section (Version4 only).
auto CoverageRecordsSections = lookupSections(*OF, IPSK_covfun);
@@ -1184,8 +1195,8 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
*BinaryID = getBuildID(OF.get());
return BinaryCoverageReader::createCoverageReaderFromBuffer(
- CoverageMapping, std::move(FuncRecords), std::move(ProfileNames),
- BytesInAddress, Endian, CompilationDir);
+ CoverageMapping, std::move(FuncRecords), std::move(CoverageMapCopy),
+ std::move(ProfileNames), BytesInAddress, Endian, CompilationDir);
}
/// Determine whether \p Arch is invalid or empty, given \p Bin.
>From 641dd03d2a61ca49934a73fbc831bcb23cb6c772 Mon Sep 17 00:00:00 2001
From: Yuta Saito <kateinoigakukun at gmail.com>
Date: Sat, 5 Oct 2024 17:33:58 +0000
Subject: [PATCH 6/7] [llvm-cov][WebAssembly] Read `__llvm_prf_names` from data
segments
On WebAssembly, most coverage metadata contents read by llvm-cov (like
`__llvm_covmap` and `__llvm_covfun`) are stored in custom sections
because they are not referenced at runtime. However, `__llvm_prf_names`
is referenced at runtime by the profile runtime library and is read
by llvm-cov post-processing tools, so it needs to be stored in a data
segment, which is allocatable at runtime and accessible by tools as long
as "name" section is present in the binary.
This patch changes the way llvm-cov reads `__llvm_prf_names` on
WebAssembly. Instead of looking for a section, it looks for a data
segment with the same name.
---
.../Coverage/CoverageMappingReader.cpp | 64 +++++++++++++++---
.../llvm-cov/Inputs/binary-formats.v6.wasm32 | Bin 0 -> 87834 bytes
.../Inputs/binary-formats.wasm.proftext | 4 ++
llvm/test/tools/llvm-cov/binary-formats.c | 6 ++
4 files changed, 65 insertions(+), 9 deletions(-)
create mode 100755 llvm/test/tools/llvm-cov/Inputs/binary-formats.v6.wasm32
create mode 100644 llvm/test/tools/llvm-cov/Inputs/binary-formats.wasm.proftext
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
index 8881bffe41c57c..461fc43d32f8df 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -18,12 +18,14 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Wasm.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/COFF.h"
#include "llvm/Object/Error.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/Wasm.h"
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compression.h"
@@ -1077,6 +1079,53 @@ lookupSections(ObjectFile &OF, InstrProfSectKind IPSK) {
return Sections;
}
+/// Find a section that matches \p Name and is allocatable at runtime.
+///
+/// Returns the contents of the section and its start offset in the object file.
+static Expected<std::pair<StringRef, uint64_t>>
+lookupAllocatableSection(ObjectFile &OF, InstrProfSectKind IPSK) {
+ // On Wasm, allocatable sections can live only in data segments.
+ if (auto *WOF = dyn_cast<WasmObjectFile>(&OF)) {
+ std::vector<const WasmSegment *> Segments;
+ auto ObjFormat = OF.getTripleObjectFormat();
+ auto Name =
+ getInstrProfSectionName(IPSK, ObjFormat, /*AddSegmentInfo=*/false);
+ for (const auto &DebugName : WOF->debugNames()) {
+ if (DebugName.Type != wasm::NameType::DATA_SEGMENT ||
+ DebugName.Name != Name)
+ continue;
+ if (DebugName.Index >= WOF->dataSegments().size())
+ return make_error<CoverageMapError>(coveragemap_error::malformed);
+ auto &Segment = WOF->dataSegments()[DebugName.Index];
+ Segments.push_back(&Segment);
+ }
+ if (Segments.empty())
+ return make_error<CoverageMapError>(coveragemap_error::no_data_found);
+ if (Segments.size() != 1)
+ return make_error<CoverageMapError>(coveragemap_error::malformed);
+
+ const auto &Segment = *Segments.front();
+ auto &Data = Segment.Data;
+ StringRef Content(reinterpret_cast<const char *>(Data.Content.data()),
+ Data.Content.size());
+ return std::make_pair(Content, Segment.SectionOffset);
+ }
+
+ // On other object file types, delegate to lookupSections to find the section.
+ auto Sections = lookupSections(OF, IPSK);
+ if (!Sections)
+ return Sections.takeError();
+ if (Sections->size() != 1)
+ return make_error<CoverageMapError>(
+ coveragemap_error::malformed,
+ "the size of coverage mapping section is not one");
+ auto &Section = Sections->front();
+ auto ContentsOrErr = Section.getContents();
+ if (!ContentsOrErr)
+ return ContentsOrErr.takeError();
+ return std::make_pair(*ContentsOrErr, Section.getAddress());
+}
+
static Expected<std::unique_ptr<BinaryCoverageReader>>
loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
StringRef CompilationDir = "",
@@ -1107,23 +1156,20 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
// Look for the sections that we are interested in.
auto ProfileNames = std::make_unique<InstrProfSymtab>();
- std::vector<SectionRef> NamesSectionRefs;
// If IPSK_name is not found, fallback to search for IPK_covname, which is
// used when binary correlation is enabled.
- auto NamesSection = lookupSections(*OF, IPSK_name);
+ auto NamesSection = lookupAllocatableSection(*OF, IPSK_name);
if (auto E = NamesSection.takeError()) {
consumeError(std::move(E));
- NamesSection = lookupSections(*OF, IPSK_covname);
+ NamesSection = lookupAllocatableSection(*OF, IPSK_covname);
if (auto E = NamesSection.takeError())
return std::move(E);
}
- NamesSectionRefs = *NamesSection;
- if (NamesSectionRefs.size() != 1)
- return make_error<CoverageMapError>(
- coveragemap_error::malformed,
- "the size of coverage mapping section is not one");
- if (Error E = ProfileNames->create(NamesSectionRefs.back()))
+ uint64_t NamesAddress;
+ StringRef NamesContent;
+ std::tie(NamesContent, NamesAddress) = *NamesSection;
+ if (Error E = ProfileNames->create(NamesContent, NamesAddress))
return std::move(E);
auto CoverageSection = lookupSections(*OF, IPSK_covmap);
diff --git a/llvm/test/tools/llvm-cov/Inputs/binary-formats.v6.wasm32 b/llvm/test/tools/llvm-cov/Inputs/binary-formats.v6.wasm32
new file mode 100755
index 0000000000000000000000000000000000000000..37a25088b99edb56649f399b9e54258d0f68d76e
GIT binary patch
literal 87834
zcmd4437B0~mG^zmxwod=O6nx3kV;Y{dsiw at AqfNsNeBUQLa0hem?D#a5{5vy6(E;X
z7&Ihd6cq#<5ET>@2?9}^XGKNDc4!>i?$#ESZm~rhyR~1(_Wk|W-se_T2K0TO at A<w@
zi=2DT+2h)4ueJ7nuf0y`{LPmorBW&Rr)2uNWP52{dHeS5$##D7Pij9){A%K<-SDWi
zuB2q!wkO+2u`RykcKf<YOjY5n?%OQews2D-eWK*e_B3SIzs=i}f^vDgEtFA;S&Q;`
zzpWHAstC0*HX_ujhpkE-D@(U-PqxNpm(n|$#_xCa`I|32Z}a8nZ`!=!ilOs1UAg|M
zOV?k0XzTe`Ub6YTOV$sS%KJz$&Qff?^cCx0JY9AD<yT#L<rSB|Xkp`vM1Q@!){8GX
z at 4}5&Y+heV_tCPkq`3H^%|qu8y=a{ihm&nyKXl&38_&OF^FDjqsl=CVTyLc+xf)t(
z+eZu3MksmyMWr$ONHH#?_?sF at NtW)SORqfd^7AiSUrP2-XbXi}t<@JvuzCIZ!BYD^
z5~$%<UwP@!`qI9Nn6&Bqp$+F<NHs(2&!a`_FC4n!%4_%8q&7=_#isR_m&Wd+&bCcg
zUUA`h>#w<Vs8lNdH2HDT($rF}6#q*r<2uGw#%1HjPZ(brUzymPq at ATCO(s>7%DA?+
zG%ct4UrSoquTm~2m8NpJd2+cq;ilYD=_<FRE&Q+2Qb{Z2w53uhPaz8x at u*ZuLguu&
z(vqe;EH}4JEh%R?EtlKIl#^<EwLGmvvV_uF%GHF@(nM`&NlPtcNT@$alGfHFDXAUh
zgd}NFrNC-Z?k*=yUHi9?jWiTNb-GrXl1<5e`!$ux)4XZo_9VaaPnGKSQeM(OkI&b?
z&y4u at f7$Pc?cea$652oCKUk>~{qy`mjh|2cm%V)O_jVbl=TC%39o3eJY4c_4FJsiw
zQuBFm)|Er0iETZJN||)X3CA3_`oxn?K4s16L+ekyHThWb#pKJ$7m_EEpC)5|{*}s)
zlS(POrV0hCYm;Pqx-4Bb^ZFe-c9ilR at 8{oIUs at Vl8ucVk7N(`_E~UxtBx%W)vXATP
zN at J6bDh0Vx_JAIgsxK{9wwJf1+h>xRglV4nvP)fg&{tf=l at _M$Tqv(KFZm|dG`sxp
z<4V`OJn=2A*|lu-dei3GT<fCnj at vPAOh<LUB;C$$D(y=j|E)45j at mou!^|73GG4{|
z8+W_EX}9~Ece}r3xBFM^c7N+`_pctlpOsXK&L(s=b%{#{>2ujSOM~fmM^&lvn?zq9
zX{*+|QjH8L6jz3h>ck}3w*2~czvYh)z3$$RY*$x1sxL2>x3_F7 at 2ieQ<yKdoU2gT2
z<t-4j;+k%Rn5_^Ka$e_Kc?v0A+l?aPPG8OclK6I4b?tRO){X6`cBSaUZ8Kj}bZB-t
z()HS8{Pz6T7i)3on{P^&x$^O2OZjb<xH+&+Xh6-kx>j|sjl^SIo3FYtq51(;@0+Tw
z$&bqu-{Ho&j=IlW)=~XtQtqHl4IV1x4q}yDGALs8(o*>FZfmfy*21(qd$ZkE;IzuZ
zv at 3h7-8OOCv@q?=-e$MW+%_*vv+N$bZQ-^Be$3utx2 at c^!j~G3ZfM4(izajFq}5z9
z8qTGihI484<KWRTqNE$^#%1reLON(_MnPH4k9XrkQ(Z?#^}Xe`HtUkQRoOOf``F>`
zHRn&40`CusS}{|r*k=tR$6Q&-C0&@V;8I=)wOiH6rCjLTV$pZ8#<(wCDiXUfgN$-1
zP<hCxJkE{V1%+E($D;ClC0s)zxvZp-nH!%yWNn{7f(eVteR{LPPt;|Z?{pJgXSUN4
zOd`RgMP=t&XP5i at e!4h6S(o{~EAR4Cct54)r at E<r8Z)7r+wPj*-|g?G=dFGQw=-(q
zIp at 9G&rNn+Zkn48xgJ*GG`Pq0WN){MX6D~7`Cd2E_163>H_IR34%p=n4Au6z16|)%
zKU;TQ{vbEo9kkWY32m9{=D4|A{XE at e{$MxH9lX^aqPzKizB|Ot-|7$5U8_IL9qJC-
z>JJy`7tpW;HGhOVB9i{_j_Ss8)4ruxOg2iIxr#W0`6te3c1^B1dyn;{WqBW?+TvQb
zF$XdRsN%-dV5n*=rLCiST~m|sMmo$Bqs8XmSmC3g!t4>d!b)&O+b*hXabvc at 6Jp?s
zYp;nXVv*I3>T_vF)AkerBLg;x*9yN=`>!E*n)CU4<x=Aqml$8TbWynra>AvZT;Njp
zOkCQYJ!Xw+leTefV at u+$PCsUONfN<T7nOM;c4~L+*#nkztR&Sq&8<4T+p#OKY^HhT
zvY5WhPjC}r`iV+!>{|De+ at xJ%P>soCSZzPjw<lFq(dWCC!(CHgzbRYAtJyBAZdzzj
zx9fJ(8m)nM<Ll{qox#L2-1J7}@N#_ZLtU`2^SrJ?tC{qCW(_v(4Ycm4-khY8YkyTU
zHh4*tLwf|4sz`Q~bceLaBU9C2s-!XN^|BHs{-7UA8YAE3BA+DdF43-|dM{SY_U3J^
zg+?jC7<-7<cN$U3%emP9GSpbvRc`c63>o|_RtS8(cDM<3U$ybAN*hScq^_N at hw{vS
zq^29ooypR6gnmZ5QrA&a(;_>L>!?1moACcXm<jtPS7S;r4_}OAG2I?yqpcH|IumM$
z#fh=4P_l~Yf#5PV{j;Q5Q>e)(+f)p4f<72&5iBZa($-KjYRjgmEt|1 at nrcwBMdLeS
z?jkO3V2+eEN1~>0X9&hRNQeS8y?KVuAh*f#x}RV}Fkx6BPmEP`I%Y>rb3;|^=l0Xo
z*yX!|`Ct>`IwnNfO=S`@X4Eo`J7z-{^-J0^IXbGRCM^Z$j2 at ej#$9CLnXiR;j9(he
zE6W5nZC4+qezA>ST}hS|MV29$aoQllv?-FhNkw<NCh5X1F6hEe*CaLFoL9t&u0 at 7M
zlk|5x1JcINHe^q_th`L=BzCz-kDK)&>bbG2b~8MVADbvu7lgDt6DWJ4o8Tr6Ay&q_
z&Pcinq_bp`L$WTC8S#c7-efnm2Gyo%%66mWx;LW#n%w at fD=gFWkZA^)9J0g>p$t)i
zHEBN$%S at V&=JT^$FKTa=J7B;c$k>|JtNYnDwzC;q71NITJ4l)4gtF&`vgc8@>AoR!
z-&}V{4c#|i$qv<f>ApD*?U(&b2K!WrMQhpNA@>4uAK at 0bBZmA!ceq<v^NZXf)wLMG
zy_lM-mcG>=sr2oBiCdzwk8(%3BWr%CTjG{VOz|%BN7M3S+|llsnm-mQ9Ltcjlb<dw
zW0-Ru<u$+DE$@|xDY<1G)jQH;|AG}pThlR3w5s1|re-B_Hk{%rHN;Z0n$iN(!dR{O
zJ(kG$f=Tb%^l}U@$4IJ{MT%%A6|>2W8}J>pIddH at tNZcvcs!Eqek*4}tPBYtLC{G-
zovLNW6D8(U*-fHU=80&sUnqUDE)`6p`+rUM{FGP#I!9&_ToTNnjN&nXWH6PZ!4x|?
zt)u$pBpF)}q(U0A at CVh^Fx{GMEyW#k0u3R}TM`*G&A2qCnLTVT%<w=0-dC6smJGe?
zs^U`aBwg$wcB6^xaM!`O8D$v8j_RXn;){m8$Vdf(m=delN})-D=}x2QK2{1L3#%2i
z1VhQSjW_;4tA=53kA%dGku^grl`=L at Vh~|H-c1<r6B*0GB48{h4OhKiEW(U~8Zxj;
zMNEkmjGV_MNj*0uHUSds&$uz4OOd^%Gv}w*%rMYXSy_&8bTuZn598QT{Y)jv3u2YA
z4fZbK`e0)uTrU?!(`gPl>Ds=ukI_UiWC*!t(_rDD(Wo67wMpp*skVBQR5N*zMS0N&
zZN_IG61Pc9IMWf^k#S9K;=*)pdm5&8FEncsZ%e66;wPMK;?_y>x&4sAkOArECYw}N
zE0M}-<rFtXJU7*K!QNA$+%(s{+V4*})7}1Vdfm^k2F++R$T=s%Ln>W*LMb!dOx^WD
z%30JhtL9k%L^0UwF#lc8cx2a(Qb_{QNgU?ek%dj}Aa$c$jWVqd!8k`#!31L;>w<Zr
z;lT*SgKNmfCU*$>LUp$L`G`H_qdT;Qd_2q_j_8}8y*EzG1-u9=1iz4Ui at 04>^NZbL
ze<WR7;*N9+-IDBmN<CG at wIU9U9!uR)-5rf^JbDmOXb+Ed$GT&nuE{})T1KNyrq1;_
zys?}|%WM8PcU&(8?kKsuqxzaOnOgAAXp<tQF|mjym- at 2FhNLi3Yr2KUCLJXfOgffm
zIOc>jrpdytARwhFO+X5SF{?uqvSN`C8Wkp;F5|*OEKA*C)cEm~I6=!vROYy1d?qqJ
z6T|pKf!Ph4g}jrfVm~)Y3}v)HTpCB&>u$uRgP+QAMH&0q)lvO(l1wUSvG2LWkZUe!
zN->vuBV1q$Gp1IA3tD)Krs$4vfoTe%2LUdKRzzon3os!hHnRv9Fk%vz#y)eIehjUH
zI9$3R4wo)$GcKJFhl}PO7l|e=?V5Cbsb-p?2hul2I4!n6qEYvgU<I3QHJNF>ffXio
zRDUw=Kw0k<mS<^PqUoAqd+NVd(1kYs3u*K$EaPVIu6e|NReo3aZ(>2pw*2XIcp*`&
zP6757rcb2^VTk#pu2Ay{T~Rcj(v>yd$8=?>@*!PWq&%)GbbU-$80_IR3(JZ2#&SZ-
z0eXI;AGaLI?Z!#5NOHUJYyAWm$?UE=<f%#!JxD=){OczfPfL!I%`8|=b>2OhB7(R+
zkp^2VLK=c1CRg2Lq)}Cd>^((6-BwU{D98|s;euwwg3LaPt9S&IpI&v-5m8mwv#5Nh
z74)gp&s5@%rLx&vZ^TJvk!IGS@~uUh17ey3-2v{vEUeP|NYl5dyrXE)uw}=rz^wCg
zVuKz_5nt5tc#8a*>*ft2zYg|us%{Pv>=2oDk0H3K?$AZ$-zBa(n?54JxZau~#kl at 1
z at eA^M5{$a4JEDeBx6m)j?@SP1Rkyf?8F!>#lHZyjva0SVS#V2{SBD}07Pv)Nb4Le!
zMkVb?5n)w#49&Kh?o2W3s_xiD<!iG0jcJ#0yKGVU{v-}~&V3Gyo6srjya?|g+WZQ)
z;xT_bua93;e%wmC#`kmEzo`7N(2c|oa6ho9{Dj at _Nc>9fS1u|)W%u-875A$am7lhI
zx_JWkCoC#|pZh+T)34SQ&RFACyETLUM0cV;$(^*zpG>-w7nPr}bkOw_cZxsNox01f
z<;B`X<>wN>=$G*OC5y^0SRz>OG$h$+fnQGN)#=I)6Q05EGnA#8-=Fw1xjVDw&vIw^
zm-6$a3)6Livd-rB*$dN)VC-}FdCtOg0|YsjpXV-2H>#CSrT%5^WfG+?kGJRL&y at T+
zlB}!w^WFLW0y1Cd&T|*I3*E~L at p_T5@kK$vt|#&Oh3VJQ$T^gGvAa0Z{1P<e26u_S
z)NSxJcd4uO`$0<F=my=!y1$IhT^35YoKh}tl;W>YbLjpit7((clziRQ{guNLX0zMu
zudKQ&{gAuD4aqc0{1$$0k!}ebd6m0rr at xwKSIcBB`D^%jjTUQ}zm}iZ*8D4Y`bvJj
zGT0qk`MFhghw>->I(OYpzl~?xWPM<H@^d?qoBZ(NE8LEx=C3ct{f30MHz2SaDR0!x
zjb>I+6qDkn#NCwa^f&AI%~BCme2Z>w;btxczAAAP^(sodRebwuy?Zt9=2O~hbn_Z+
z7N}wH;A<22T1vZ3&u`=TViMi1o7=frN@=f4+^vaw9i`o2?Rz-&cP1hxB)>C3IS2aQ
zmAJbSR-iHpUZ1$vC;kmdq%a)%#>Bl*Ppa+>iGNe#DC$j=FGAmKcXxAVv}PK-IdN~M
zN%z=`dw3y&zs2s}!kre#Z?(I(awi+_ZFcuI?u^{Xf_oEpFGbvEFYe=oX#RG)dpmdC
zkw at Q=xOXIC+WW0*Fx&(D at b66WX8*3lar4f^@#FraVAu!gx_gk0%3^yriQT&?&sa8l
zmx+*vl;R;vQSv*LVrP*e*7~qj_Mz0j$9_DS`bX>svj5S<@s{U2c{IsBY9&6VLLRe1
zOjmp@^}7;jyZ7qFdl{McCGLGmRI$6*QhIGUIiS#smE4V3bj3ur`0BzIr_ at d^D8-Bm
zI#JX$K*E+|Qvaep=)80*78O|MfNzJIrvK`GoH4>Un^qkZ(E)We?#(hF0LC(Q$99xZ
zjm>U+T%O5>Xm%5*!0-)H3a8-Gj=r3T#oigrs#Sh6^>nd5>8i^z7rsHNR?KrQo#;f%
z+RbtlGd=s5RkT0U-#-k`bZVKd=9H~D6+Z(+(UhXrHqFk{0xjo5p+fJ&(qbk>%nU{J
zlB{>QN39+-Kl^|xf+z>@@&I010o~a5ECP7cR|DLi9SMCPE8q#q^^L8dvH<(x)st37
zBZp)q`5BTGTo{sN!(*|SpSE^lQWjKOS^$?C7A!b+a!v#_9SJ%|k}U&YbHO~RiTK)S
zX{;@Wp!ftgsU~~mkc5R1RdwZm`AZp^Pj*x4eyZI}(|$*tCDByZJ+PN05t6{lbr9L8
zYmktinaj3tu6GF9&9t=;<(nnJ{EwWn0>br)4Q8v1W!Mi^)ExR^TOvc44hOk;HGeSO
zIK&+sF(I|~P<N=CJ^ls_Ny#6UUxUqn?ys>a((D#!ElNqf{)oH-!{G=+gYr$74vXC4
zx)2~1KP-O+F&>U$mNdpf1X at Z*j;55OYgi4(_+#nFGPl$%8}c~|pxl5TcNConjXjR!
z8n+cS%!1>6KgkE&ac*D;wcqbn*3kB=Bx+6wEm{o~*0>WKx;=Z&fGlI9rT#=ZeUdxT
zomBHDQ{2f6c)_GAr0G at 0sVZZcUrUuQA<au_{xo-*Ki#c$r at K?f+upG>d$T(Ofo>D@
z44a^5^5{%<<r-v1(aWZPse9 at 8n*s^XCJCy3zG_&Ewr`fUhnU)II~SAwWjuLV4K4q2
ze;%OtI(IHQeO>lJn|$XpbIuPl=K|7QFtVx(-G!RF7g5G~-mR}mx%*4pCGMhP_%`tF
zQr=x!L&ew7 at 2x?<*ZgH@{mb2DX!Fb66$5?~G^)Ezu8ta~$}2;ao5{L4R0(m1xI>qZ
zm at Qk#b(PzK8ovtteYLyhM1L)hUg55Fuc)KDU&(Bt%B^HXb0ZH$<LltKZSFd^t%lC#
z$x`$+nXXSz*{InekFws5vaU%{-<XIcZ<5x%Ik8!TV!kOsGuP3|_Tbh8rHw|dOE06T
zU!4q~lqnHKjB<W0FK$DF(5u@}u5qB2dQ at _=sbr+Jn)SMbcA-Vl&UaAvohBKV`nyyT
z>KASNdfN7e1Qm_Stpx?F#=R*t1Fef1zMI<6w$12URAd-r)Gjq-DBQeLdbZiUmHepK
zx0zbyHOloZNgVO}r0wpD`Va-%?4)1Uw1Xs4$_gJfY(*N at 8vcM9j#hm at y0s=P%j2c~
zK{XtG`e1 at W9r6#E+I@%wXwaQT)rUjF(TxvFL)N7<`9n3w$&c=|hNCX|`B*ZDmZUwq
zXivM|tdzdA%HEeSaUR#p$Eo4{iF<$IKaenCKPWxwK1c&Tl(-Kh?nAu(aN<5}Ho`|N
zcf0>+g3fi^eY7CL$3%pWMIwA$<$gR80Y><Q?mxl3E9AEGpR}Tu`A>-$pHAGT68CAU
z`iwnZ>OU)DJdwE1ChiH^^0~zE=5r+YeBwTD#P~uW#*>NrLgJo;7+*}>Clmjr#C<XG
zUrro9zMQP`PpP1<B<`uieT77Sm$<*9m157Ys#Ra5RVKYw_^&1IYxJ_+e?7M08+LX6
z?-R#Q{{4DV2$rXn_i6H0M9zx;Cf$bs-wgc9j)gt_R+2vh{#5ecP9j$Moy76?ZTj)u
z#C_Lj`n|+`EAju3xbG$Y`-$Vn_mkEBAJy!CO58st?w at G(KZo-F*$5oU{6SIX4-?1V
z4=D3r68A4w=8qEhqr^XB)~B`P$BFx~9#q{kiT{Zj{}URIHWh>ZG;u#ATc>|EcKlys
z$N$Z)CI2(Kw)*Fi{E1(yKR++({`bW3_jBt0MdHXt4t|jSxx_u2jK4Vu)aS|Xo-Zi9
z(*H7+_p1aX?mrUutHk{WgZx5K{I84R|1)v?{hH$cD{<uF-xmsw`wb*<zlj|8Th;Je
zYFN|W8jYF%wn{4ge<hB;|7I at yPKkauJZQg9-0vB%VEs7%2a)`biTgw1{z#2~QtCgE
z+DZ3B&Gcub`Jcr7IdT6(n!hN`Ur1y637!HAXm&fWTh>^HHU9ck*3J!jd_#(WOx=xX
zw05pfJF1mZeo*yC<qmB-7VwWC9l<=w_KCndZ9I>=%_Ve0;!2}^XaXu at J~Zs&M-;3Q
z;V;{1h-d}olxt>(Kf-7&5kE7(hKP{hFyq?TDva>hn24I0#XE>~CAXQej{%LPZXCOy
z*?p$*I<kB1YWoU<V2Ik$2SL0Hi*_RBZ0BQGSE;;CT4UY&aSLLIr;oN#Cog9|Ul#5y
zSX(@Ce(Lh+!k*o<Td=jJxbCe0_Pprw)0cOG(oc6YZt)H<+HLh-FIs)i at -e_TJ#OYL
zSX$ooZpG5F90x2nOG}$?SXO;*_8I;lhHwtH)SSAXYqNGPx>N2z6`{-Wof0~82zrOS
zU^D)ZDj?0FZk9WAE3gd3_5}-Tt6vZ?6WeUt3a~sMU^$JzavbJ`?ADK&*UEruU at PEy
zP5h^;?o(V;MqcH3SG-I3oscfLaVTvQUPoe#kVn_a1#_g-J?x|x>#hj;>vNUh+QF7>
zUswlWv1<djkG)r*jmG9HkK{Ggrcnu=X0Fv$Ym7WDC(@22=z<3<9a}aU642wFnAXBZ
zLH;%}^kc&wdqo=(ovxw*?UcJlT+{%C;yH90_H`0)KCEjShN&`P5(d8FrfClVVPzGu
zccVesKhm0A2=M?6z}D+p at 5$1`koVO6Oe<z4gK7Ej+7N5ZiZ~WKv9h_v39fIgpG`jV
zJgUPCbBa83-CT8QUS!mR<0LVAJ5G}MZXV1qA5LHccCA00aux__tIPYSC<la2Y_cfM
z$Hj3z9_bdlBjbEr;uc|YF9EDO$}L?xyw6$(kUO?0XPH|zyS&)vaYinWGx9jM+#NS4
z08WPXW1wz1mUcg8_JCWt)~}*XC%9GaggW at y>Y}VQZq4lSDgH!&F^p?0>yxmhPj;uQ
z^{0}4tvl7Ntz%2S1npSm!D)=cX~j5b5Kj+eJ;R+L{y0-ZdX_uWowXI)*$95NJ6ps%
zXL%pE*g5XpZCJ`LbuZhBrEKrdbLXiu>)gxTx~=~F at bCh6fhcuhblbSdU4(7CeixSU
zh3?{Q7{}+kOSS at gojweEorYPwC+wAA9ajW<6`a$Bsa$baV8+JL+{EoBEFm*OXi<g%
z&85>{2^O~5u&>Q-XqAsfvb(B|oqRRqP^t`j`5N)zwYqD^WPXM2Ug at sIT7D(q)>e1j
zTEC5kZFk$;_BuAQvEvRjOvrz|jAe1;4OU=#u$J}UrUdI*Xx2 at MU@U&zlB|`roB&_R
zLXNibs~cs#MwYT>>uY0Kw<Q?MdT_f8Xdza&Ck^9x0OOdlu!u2*@4}qGJbt~bAdNEy
zas~TXbOR)?p1x7WA+|A))tk_AcPoX^sVsE;&3cUy{N}{n!)suv3f3@$jgA3t)dK-j
zY>83cTr6jV6DD&7ySXMr>b at ijsJDUCymR~%?R1PqvNf56Ot!U{WK2ymN;R(L{bYNe
zZkxxodsyl{Be&baH+iJkJB#Y at XgeiN|E3Z97Pf_Sqi;dJqy7qH$BkL*MG!*~@T|4r
z8;ekyd7J6C#vb+SUnd(Vizc1<vI$baw at 7f_&tI>%6VZS;>U6Rzgbd8SVar<zpF}eD
zV$Y4z?JN+7ige*pQEI8SiDs9Vp$@xtA{;Ajiiz*O^ehkv=9?+S8cNX;v*)3iINeR(
ziA3xUo|zTrus)Pv4a(8d0qba9vL(Bd4cR`AUy7Tx(I0 at +JfMb5thfW^pGw-5NXLrn
zlSe9di_w@?0DBplqjTaMMMz3h?m|z_aR+bH9>z`-<!m><hGeX`L$z8a;{s%)<!2{W
z6MunQuoEG9SlGg_H~6LK4coBU14iT{<pHSO*d=wO<HE3;QIS8&{7~f4x-15cI2t*5
z3~<D;ZrLg}T at yAZa<{zhkHaiHE~t_fG-kyxvDY9hEADu(r6>^kx$R#_dWxKn0Ij$I
zn6?lPD-fr=SP5#eQsNX at dV*WM%CDiW69FwwtZOSGiic&$QxY#jqykT5+Kb3OZ9Q6x
zj9ptpuvXkl0Anx`qhxiVCni=`09Bl!d}r!mUl6Q=2-efxOKa>sR0K#woqY~NX!3Os
z`C4%=i!8E2fP^H#c|1I?p{>`^y>+Ho&*%C1qDGkJ-Ts2mfD7FP{vvlFV)r7qewDwN
z?p at +8c9+!s2AcvK3I%eh(l5}~gC7K&uziP<{bi&FmvEQYk+)YAX*We)F$vox3G1%h
zh>+dnHrK!<te`D;PDL=nUA@|0LqXTNYuvSU3D+o{UP+_bPEezv+*a<iqfiV{Cvumf
zx&%*1?jm$SB6hIsyIukhL5tA60fBd;fC-9>!r-Q)Aq}!1cM-ZbB72bth}&C|Aa{jN
zAb?+uFy0qFA=8l-nB3*s86<D9S8zu%uT+xo?P>_$p&)z_!&^-B3YtUCTHaA2_ioFJ
ztnF&Z+9AnW{_Y_!LYBWb&^K at iB=p;oB_+d3tTht0YR!E~UKZ$&%zb+ at Bq)M6??4FO
zpSb%`MkW7%rR)_RVL9HV91j}y at E|$fZTSDY$?;GEq^}%11xEm0Z1oT85m<!0Wkc at w
zi0qF<_`W7AzXB4$h?#15;=d#sA1hXOyAsFWW0d_~;R!<ZfF(+TCEk|^lXzU11jqz9
z!~nnqMSn=p1ein}Ov0G+!>B}LDY-tPx;{c(S-~9{I0bn=CYZv1JOQ2%62Xs8BqxGD
z at aj{741gZ$LLfdZ22nRwfI{RB2tt^{XKCIO_BaEDAkXK8Lx4dH`7b136QB<@|D+HI
zK}%l at pv0F1LV!Tj0U~JHQ-UG_2q6FhG~(~*&{tL3*AgHIaEH232kLensDZz)Q!0o<
z1=xWVsNQ7$X=V6k0`36NQ1jo?>u;&U298?hZ$lN}g at BszWUl{?6?>NO22Al&{PzSj
z>=fR>lYgKXFo*9X;0?eI4Zz`K00-*&LE`>d$U@!!Q04y67Tbwnh6+G~W at V+yfhG;=
zkBUKkCIMmqeW>{#Ctwa5)Sp-r<_c$^Ny`K?@RNUkl8nDaGSa5dT>q~z-M<M(P{yAb
zrtmY$dQMe7N0q^(SOEfo6g21o0K(9R3dn=D4Xldi_4=0ypaZZ$&HqZ-f5q!%(L at 1s
zsDL at p1!LTEg*`k|^1s$&!404e|CvN<;stD!z85_pBwv_z`RsI5Hznf=+hnvyU2yda
z31JCanGdo4k~dHEeKk)W9D0Nix8*I`ZL)I)`85rj1Ya8buVWevl8)+SoH>j5z-U+A
zk+x8AUQ5K$35TZaGp3uG^?()t!x#=Qge}zU+G>7Gp0T6CZlo4}?Xf7%Z(Wd#DQX+t
zy_lptvYUY{)TX61u1m2}e22}~mnz!mk7{#cV*b{S>OUvRw7u71WkWmLI|^H(O%xyp
zdz<nQPW2d#&DT!7Y92Q4R*f?69Hw0o5|3jP%n4h5>{f~`W at Xe(m{-D>lTlJQAu2(u
zHj1=g6#boSK;$JFm$W)SgAaDGxn?==744|rIKmb5Zy;bL`<#ta?50)IzDF0W_%@d6
zZP{ln`4|RK2UMUij$eD67CAg=eh~r(l2jmx at u<1va-J(qW)5c>=@371<h#igM+a9i
zsYM%od5 at RnRg^J$(Rr<_7_u&QSCe9pU^;eJPaL(o>c+)^>K51_;@cqU6bV&Cu*qcw
zG&_;1KpxEFjonn!5}iRHlDr)Y+#1FJ>dyRoGYoDk%6!1x<f5plc(zTAG{ucx3RRAz
z({v!JEC<rg=ms~P9vCiF^X52;^<^^IviRJAP?TLy&0~T`a`}$x&(maXLDIdQ-+)%}
zXk2^#EK3j=KQ1{SYV?)P9 at oMGnucR=;cVMq-K`cy4e at FhMaAJ6R)+EXka*sW-y-a;
zkq8Vgd)6wNls{{L_MX1CTGf>Dr%V~xrYUm(s at RH!H`SQ2J9dG!i~OWnyGYQ_&;$d}
z@%$6eoYj6Nxy>W1?q{XT+$@>&q4EP_83%&ouz=}PX2bTZo(xzgbqCc1>jYwVR6p3%
zre);*0A^(XHGyai;4I1a#m!yIqpShz%y-}#ir9`-%XhnpqaKWr3C`iZ7Xmc8KGX7Q
zqv5+dJ*(j+cdX&&g6XmXpn!MUqeJF+Mq@${Kqul<m>_*{xvXoo7^g-TvPZ6#9EdX6
zqrB5dXx_U+u<KN}zfoI83e;w2+wikG6!*Kto?1!5o~~yrR4=<;JLRHcW>JitV$f2t
ztfiu@^Fxk4NCfGHqy<d%3_q9j=H*uR2ixR3SR<GCL-@}Q at YPu)9xCkNhn&b|!#a{w
z?z)GuX`TO&bF3xSiHF-dG5?IMrx$T6f8G4wOYB)MW at UJ!TabNNOo{Djt!Ep1r#}i+
zW{6t$8e`a_Y4Xtxjd={?6<3YS%4IGe at XKkI!D)5B!kW8+)|OZ)mbFqeKMoTO{mc*`
zHaAdXS;&)CP&VykuVhiUD*L0!-PMe?;5K^=+?L&{HjwN at N;@%>Ms+7~cM^9dJi7hK
zxntE>cBj;|YK-#X<c{inBaYPURXzlkEJylbez<b2A#klP%|`hanjT>OKof)cHH?hG
z(>9&Q#4_ZmkK#b(YgUdWpB<yB;h6s&OPG-$oQqY02{?Q<ICJ$V&V&;1W-0%g352d#
zJ{~Nt%TAXndxJqGPhn6^qA`esX~X#L%H8l?b4rPL4EU}}nU#OW_-J>jfDi!4DCMtZ
zcS1~hpqpKTPiKMrrxB0QvSAMC=8Pi7+}Kzk4mVf+7G1&LBKwmK at _aJP7f0CvV)<Th
zI_I!RpTo&xo)-($G_Vf2T(Bpw&@EaG^Crf-N7nrk=(9xh(W#qME)*J#P~=h`fOoXV
zLv}}_#gE~U9l$v at vd7UK)sMB$l1$UCksO8vk7<)Zn*w?sHVwii!-TlmptGUjzci)|
z=?*K at P(?<tseL=15-V$VB^?QE-rZA5huNBiEZH#?yri_9D5H*t@|D7 at T~t1c3;x5W
zap5 at EDO|=ZDz8+^(@^%!^1sGqM2jxDUExtBmJ3pGU at u4Ff+DAam44##l4N4Bui*Au
zJIYxK3QvitRXT3OG8U#$2|^Ku>kj7`1`vm)dmJFJCzEFaTYKaU^(7nfnLK7&!46m0
zD`UMbKa2LyVo^bv(GhAXKM&+7QgX3MSq7lS<rKCXQVB_S&=4Hg=jPNrD4KX=9;xR6
zm at VH9oYw3PW)qJx4&mn^OG*ctkwgItINTsdAKP{ayH5j%N_hlx%&QKUEtDpJE@#1Q
zmH|vntMwz<W&lsqR)ah0R6KeTJbIS8qwD?{dUXsus9Y-%i<Zka99j{MIQVP at Qd{Ph
zGtAL_Yypz;IE^hMCP46b_8<Cj^f9 at 3nqNuTs}P8*>iz`EKEcXX+u4Lrt~GROjgA^y
zO($}POk8Xmr3(;>%@T at B!^@N1$zmn3%PHo2Gp}^u at HU0eG+ch5k6BsGdU;wj4o;7=
z7d*|KUIR}%Q&c|7od%e87D(Dl-PtGmb7-kSXm$TGTKcls(#3+%)Y9_;P1d>d{P}Jj
zK-u~3g0uXE<N_#j7uEfG6R+zV`7WkC7h6L$0+)nNY;bt%>Y%X^7_Xjyo`Ii<q)c~v
zKB(u5LDM#>=F33R2CoB9+vqMQm5#w=Up6MZf-2a|Fh8UPxc|t7cT=%-;WiKWA({uI
z=C;)RRdnjA##A|rZ49fM9SnDMqe0h(hqjT?D&HS>?N$)BSGcWIO!3!I;dKHZ$h!=L
zjms&1JAAw&fNVp6Y;1L0&vN+&p=_e_je<LF64<uecE-S-+Zjee+tRQKUIY88hS$mq
zh3$;jYDZ(p-)=rZw^PaMEWrYHHK^lG^ZVi7JCdk;@8UJ6n)d5OTA}H$S4#Fb at WcgT
z3vRdkcoX2u-NHB6z_?r67<CXfD0YwVjgS+N?JaaD17 at QL5Vp6P=MVlrAZb8o_ff>#
zRRoCI+l8pr1EN;se?W`7cM2tQ!!AAx<l<8jr1mbk_~7UhoBoiR{*anp_#yzX?MzS)
zLB&6uM5e~`hrfp*#v}6l5yc;st52wQ0ni$7TCh5*66L#8 at Gg?SR{&cO=N;AQNqKwz
zoaysD<Ct_*f76=WK{yteZb!+F-d5HMd at gndO_h`~O<}mS7U8x%JXZ^S30hm_+Xk>u
zsMh>xGX&aVM_BP|;V*jw<zV<vA7%&cn<zd?W{+7wN3Y30FpA#dMBMNplM_cDGU=53
zBjsGo5FK*EK-Tiy@;27xBaipW5(ZIs-A5(t-5iok at cUEobhC|TusWGh_s(wYaBtoB
z;KA85;Ab-E!^;x5W>%PIRMh1U;HCL>vMQly><=SKC*ofxLd- at +@Dt%;z|SMC9r3OE
zLu at J>BJQJ at PRwL3-TqJ}g6%R7A at S!&yTTs<dsCXufE>YT5X8OpaWRQ)dwGbXAc5FN
zMPhRtMEfX5yQAF_967O&v4P#OHIJ}&i)15}5cn0B!+-_B9kSnua-7j%1#X-x>InSh
z!vcTRD1k3=FYaDVL8}?W(33ShVXvgvaCRpT_*3ZjsqPeaYTd83ey@%F?)5LB52v}8
zxYLIG>9G%I#6BR$-5GW&LsI>v^ua`V4fo7*G!4#Gea^p(5?=0J=3YL8496|A=GVD(
zdVju-Uj)kGh3PM-+NMXvU4$i9^tsiqr at 0rq_1gdN$Zoe`z+Xyp?XX3iO^?CIWbJ+<
zk1s<=Usfx&ovp{M+5?f?h<nYg1vK04>ssxN+G$=rYNr`iVz0TRRM$X5ovbiyvK<f2
zFrKf7w2-KNMGaBCRqHd`0qJGuISo6{Lz2(eu?b?QDXupmfqXXd+$cGXaIQ&4^LH(K
z2I0-k5 at xr=z2_RjnkKx;gsJ?aj1z7R*mkieQfE&@d2J6GVf`9PMQm4)+P1bauDo5v
zBDj&_@%TgqiOs|==+Y%gekTa)RsT0QCUp?0C6cEllE;D))G$MJ_^&zpn#r+!0h+fZ
zNmj_ZGBVrHD~nqYkjy5 at Ivpy+r;E5uB6vK2Xy at Yvy>O^kN3?k-*ft)(8$z~4-<f#i
z(ooQ1IaQ!847R~8gnV!l0?eG>WJtrFk~w?QdSXGQzEy6Tg)!gEe+~Gz3Atx&8&spz
z{BABZzl#ga at 8rVihKvgb{@UYVWH=t^5NrKKPBv(Q+R<guBA-dUa at P$wk<x5Dy at ve6
zI0l_ at 3<yx6U<*P?*#)1>bTtpJ8W07ii%VGJlpt$7l{N0VM?w^OPmC6yvDEaA*0P~p
zp_!hazL>6L$LmX_w0l4cALA{!S*wPHa2+Asrx{Bs`PI*sJ$#VvIx)hngt at fLz>1-;
znXMzmhq!}eBUvWgzhspi8ZsRgG96APbNLz43NIeW)8Rc9*{aEcEo5wJx46aP8mp-|
zWsC$qiWjW-f^4uHNa&90<-=PCqmlf;iKca1HRBAy7nPbB at y70f&4o6mn{6A6<UeUT
zBJqIv82ec$o{s8A%E{t_^HT~M_M%XI=q+3BLHDTT&H1AX4#VYDQ^M+Na6fmQFT(v4
z6PI;T;4bSgkS#Z%?kAcWup`D=(N%O at RKN?FqPs+UA)*zR!72v&5(P$~Ue<;Ns4$YH
z_JVrt2lsffj+?m(uZYB(S47=&Og#$uRu8}^YNN{4yBAr)@xDDMb7P=+B^(DO$XT$t
zL+il}B14G>go_?>EW_y8&asR{7(ocqQIR?h at ES#mg(_kpkRooo(eFogRPSzTn$NVC
zi%jF-?`SKn*GxCE?$uf|i^R;d><cDPqNOHmo>7%OHp1*`Q_XYXDIz&2(8P!+1$&FV
zVy#w$f+wu#=oHgQ(Gw|JuslEG5Rb4m7-n_XF!>5r+a!sL0B5cmhLLshhU31bbuz5A
z*06$C;0CfgWCb397PCPE&_jhiO8}lrjB>@zgp36jb^BgdnOCZU9Wh7-Zq^y>UPd~4
ziLM&uCF<}HwOTt77F5MpBLd7Ra0p{<UT}OlRN}=vUgRH2vM!_qmrkUFWeRZzfP#h?
z*dyY>U5S?^ND-aYU6MT|vW3(~!5D^Q%5tj+#54<|8v`yGHsC4>J<vU at O><tFBaEUC
zRNQgV0(E``FIca;<7-%O=Jw)>Tp0`af$Z}(Vk>#KGBRiHup?ouu<J~5=kr<1SKOK!
zw%v(=+lY^m#z2&=obR~do25ERqnwxPJ<WN!Ukemz5mam)S~4hkH)q0sPjB<>9aR$m
zsS>1lW$y``mP5Pea(GA7dH|+QwwJ(iBZ@@#-y;0AM<^)1(<5H8Dnc)Eyu~$1YTKzl
z#G14u4W&%qY)vZXPTgqsX?dAFP;f#b3}vsgg3I~#6DZs2L>lGO`Z0m&jzTG#I8|iG
z#FYm<d0ctdR>exB9|1_pOD-8c_f(x%N|(7(evM*xx&(^t)?40fs1=BEbzRanEWGy>
zo-;5~Qyv0CHqX4>hFHcyb0gN0ahsyd8H?Jw44uX9RBO2j5p!!}CAjZ64SjSDa*m97
zf at iUofeP$o;Tg1*A}fk`ppr8&ECUnLrX;3OHzJ0ML&VrQJ|Tho4DZy7(PVk{5#EWo
z0#t&Z at vs;f7$rt*EEPFG#q<IOT4~dn)V7N^gebwg+(e1AjKwtRMT}UoUXq!z81e_O
zVZsiS>4^%`!%CYSk{v`cb2A at e#W!0>GJvwImV@<Pm~sz5Am{k9 at 7PYo{E(XfCZfh+
z<hEmcLkN*WW8 at O$UI+#Vo{R+H{N6w#c!}KQ;Gd)D6BB(Yqy|Es+ul^fQRzj9Siz0u
z-w?~cqusI^OTSzqZMhL;d4nj&h4d?Eh{=s1<i>HXzb0X!kzE<uyDB6*fn??%H-u<d
z6-9&Edy-q}PTGifT$9f61w~Fn+F1wc5Z at _sJO<8N>t3=N3@^dU_%wHVUG8v_xt8)w
zBz-uJe`Z+qt=<j5qvHnQS?ZTNj^)XEX!Wf9{CQOa at tWlN){23D0S&pJ#xeX0{Y5IC
zMV~HR(eLddR(<O^aUaHHLr8I{vjg|?dUJyV!)w2~znrQs4>Z4mg2CtJ>HvzByGa+;
zeYn1D8f4|y<gSd$T^6*}xmlN9{NcECvl^_(AI at Dh1YkGhuCB2VyhfzHHY9sRNcKvS
z;d1P at 4zc!og}bf>Hn&Y3+0H4x?HgJCLB{J7x0y8{=v?;q#$GodnSke5|Bb}waC_@#
z*+&Led at TQ71(0=XLZ at zxzCNt>ns9&%yu?b-8am1u&Q^U*Vbv#%!m!@1OgcP|w+<QR
zvI0b9+ at YuOq~4uLFS2MyiB(}o^)Ic-oeeRw*PX6s3_RM$P8Ss-&=4;%O6~yOD~aTY
ztJXaXXMEkRK?=o;jcXL#XWUq}wu<mKnXHEKlr}+DfjRIJy+pt5aBv;-q|@y;Flv*5
zEe0tw)-$QxJ#0%Y)G{sB(r_5qzb_ at a#B^voz0s5zF%i&`ym!6x1Zqf-H$9CcGh-6A
z9Nf&B=kT>y<pAo8hZ(g0>Shn at X0SB!&x`pv)1uSEEN}YKhqV(szmeq7n1rB7ik*a+
zO6U!pYFN-nazso5>ZJ9Kt#C at npvBoQjk}Jd|3{AM|B{$PLFHKUSQMp_FsPX07==}W
zAjjtI2qMlDn;?oWm*?9sUpV7XW2 at m<w_+nA=$K%-kP8Y8<PHI}G at dDrxlUj!mK>|y
zfLpy0G1MQ#5IMU2Nf0cacnIjz07r)vAq2rwS6~pvMWI0=kL+z1p<6;IR`pWy8UQsY
z0Lsgqn+gd3;c+NC7YOP^_wpJLR4Py0)>!DeND{CpMFipGgAK)nRDGeuu5Bn at ly?PB
zTpbQhwW-jmqA%h1B`9Xomv&ZZLoD^uSSrVbb!r%p%0_P^G7EqzxaO|%SJ2>1?h3c5
zE`cP`YPDUNU#F7~!6`S at VPV_XtRRa58($Sm=OBc;$^??zQUj5CEFK!JY2!c>XDjWt
zLl8p}NA9{Uemk4FJJ>3aEZQ;bjC+zc38D}JgQ~Mp00C|`?A_XgINIJ2M+)FU*Kb9b
zAXly9uU2-jCq$DlC!nX4%>rm+_N*0go1O`WDmGEUp)8C?TEI|uBvAm}jsV&@sr+m0
ziyl5~QoRtJZ!F|_Olk|N4H&)@d{Ly&?hYYZ>^Ig?E5qI1;%3u at Vlke=dr+WbnEUoP
zS};L{;*ldlYcVxRQpv;-P9XZ-1>Ry2B8XNn+SGB~K|<|MyV+siC{7JSJ3S69Sc{_H
zA%bi|dfMU}6QL(2GS?7`glqE;G1N%1$HqHh47&YaLA>1|jr{Xt71~PY1OZaWrUhbX
zY$<z}nXG?J6d|pUMNA=#*o*v;^x()w@%s`)wxrsKDIUpjOl$_Hue8?=HZG!L92GJN
z0xpk7D>fjV?6tX@>RbWvxH~?E<5Vj)XqBZi7=_OWqqYiDXjMd9H{d!_aVLx#kkzpT
zc#gQ$tgVoYjVK5w$5xy|E_OuELjIkKkU6!6{j at f|i$@Gjb0=y5PNPPQDJ-ee*#$kr
zojKsog6r4?buX>^vyJD at 9_G1oV&&%oo1asYC{rOAQ?YOkZ~1jW%n3_hM^GaqSVaL2
zWXWB~&kGeQsf1Z&u==^hYI`N}3{tEUvhFUfA<8ZhA8#P(rQ+S1+u&-T>-xRXU23t6
z+ at QN`z+X;#E!;sJ*+twUTZ69*r?%D!OLte+5MP^B+z|4|c0YBd04s_Z2l*@vsH=6R
zAOtw*_phWtGo9-Gx;X8wljNm&D-m1P%I&0)*g|F*f?mOfqGQOk#!jc|Lx^<+O9~-2
zq}@*bZo)Ai at rCd(b4s%7RY~I%LH}PnMX*7Z6OA}`H^^M)e>g-CrtMwDX5j0!vB{2S
zjV(@C#dbJ3vQ=vY7Xnuw!I5X#IW85>wx{iU)^xC-!nUV8xiLwN3haCu8Qy9q4H|I|
z)a85C<zoMHNXH8JyN at ovBgvmD`TMmG>K{lPTK%1I>$Bg#OVawmc%Gon=BF{<yG`6v
z(FUC>urBYk!vs5N|HJm=G|ypz(B(&pE<b8<4IUxQV at ZzVnzlP#+}|V at yPWSC+2zwX
zPY?=!T!#tV`^flyo^YgKWS2i+iPmw#fP)5{FUY=cLgz!FsUK2Phk5zKG4V$f6M^#v
zH4YhYzCiT(nCSCyoipH&!H~`x at b_`(!&!shmBL{I9W+2%eMZL(I9 at QoDFf*9L=1FL
z=ZJy(92Le&KChQw&}jn~j~P at rXaF}#)is9fi!t?=;;Dlgrw%x9pe7OhpsNx6U?@aC
z;QYZB9X|L?DV#pg$%C&YI(NX2Z?GQtd)4~1MLc*K{oIIc5NFB;J9!{R`nEzBSTuw0
z6hrmhVyM2Sa|WC-sOhM|Kd=kct&;|f^eH-P at EsjDAh^K@{@kF`2gV7UIk0p;h{q3V
z96ulm0_P7D;vheS!v-8ba6d|xlx*srLSO at 0{NuzulW^pq77rYp>wjto4SvFtXDN~s
z2O~%QUukm5|C?U?8!3LKumw72 at UIC64YGeU7Wg?VKy(8To0e+!aeMUdMNfZG^z?Z<
zX7CHj_ at z!8nDY9S#YOm4vPt0$!byWJ81 at C-yg*708vHupltK0hEA+p3t~Kay^!_(A
zQ$Xy0>0C|zUGs+gZBf~OE0h6|4r;_T$fqcz!G9*iG*F0xO7?xT#ec6teorCnZj0>1
zHP{~F8Yrg09~1xQgt!KTFz6?e0d)I|Vi~x<Fw#3xo18n+AQHP3y`W3M3$9NUx!?u@
zuPJ_kyD2 at v-<*>5mek#xx?560yQJ<_0C*S|UH;aT2HXmk7I5ng{?$AXzq}@O{CrJ{
z(UwAu+m!A$?ru-r?WupArRw%~V9sHurS6V&1bcLQ;x$?+ccqTMJIVKY74Uj0I+p+q
z!}H+{mT;YaW9s<%MiRa$b#F>FAMUnS8~mGNS@)<HZ%G|NCEr52x2nLmsz67IdwBA;
z)bV$B3ae=!RBG&A<+(3)_onVXQoLPx-cBByluEL}zatiZf9m*oKdBx_QFrf5-2<t6
zrwR+{-le?nBJV~kd!v6amGXGE9>1Gh52fy*G+Lhz5-#HN<>csL8+9b?H_}8E^Dz84
zgbEd4`$iao?F?FQdeNbkVX_kgLxT2Q+ZNW#)$9dhMq4twb_}S7ABH(6T501#X^jZm
z`bNq)H-5xXi7xPcLZB+77JGnOfZ~vSqp-OCfW<*Yi=<Ttf173t<NX8Q={qCVW=9f_
zUFsD_YesaSSMz&meglF7zuzJVE+aI_juP(R^7fqV4`S-F`)8DH1&Ol~=d$5w`+fLz
zIu5Un*skdcyEQ{HK;5BR{NZXh+kBw+3&IXfzt+9}psG7a)@Fz$+Su09an*`Ba at tU~
z<7r3mbRLD+S#f;W=DVemEFT`jzhU2v{=`i;My9+>9WnPB?JTg at Ei2W~Tg7Y$2ZjK6
z!@(WV%3NvK2XPhcc#MN`=5jv7MjTslTR=R1DNo)JKIZ+bFSNV}KIV{7p1i77=Onmv
z4)5X;C0bF?rzm2BC29BFCPNHdC2c!{%eP}>IO>SRj6gL9UD(yNIKtK}PqTU)Q5=Rq
zS=p4^!Vu5b5CgGV*amkXXOk(yz>c~G*Qz;44O747P{3S9bgts0F~VEeqB&AqG$0)c
z-oZZH34p3e09ES(Hzcj14%If?m at vp28DuMQF(nobHTX^*xrG5<Wap7-nYmCZ8gxZr
zplxF&^T$%WoktdwVeT~AE7$6MIk(FTdDzY3;kb_KSJI at n;Dfz_UU3C#OLA at 8S7yG>
z7 at T>nac!b~HmQefyT5tMUyD-ch}yy^W&doY*mpbBbQa9*INB;cp#@!MoyqqS23Thb
z`08|%0KSaY`yCIlE%oHQ9M3xG3qVt{AE-o;lDA-CmRiv~VuPnqGyKuY-0S8i8$T8C
zgTk<<T9dX?({z3ksF0Xhwt%0ZOT{}9dF|>sA1cw2rXG^^j5tfvQT at +k_=^L3CFPsh
z`GA~pi30(nr+hp<W1(@3&JvjMP>1AWm{9|M_pkuW2?YiSZ3Rcvcy!R#Olz3&uEUMT
zp+mnXGRGz=2J!^gIWTHkxyfN&-bHV^0&*6LBL<F+{TIl^RC;U#)Up5WC`P6dL%Joo
zqF|qWZ_Vr$LOa^i&5;m|ouDX0?28*tBIOCW5m>BjKG~rI=@I$GMNd030lQd5pOdhk
zU)P5gpvritB1SOOcLEfN#{&W<4WJAX=>j*o?z>3dg_3#D++Ftku!2}g-wT0V0*vf}
zgWkySF9Y6Fpa~8O|Ket9RH)o}cB6zmo0iCaVTKV~`{8Y$KQL0FFH!=9p`eunI*{x3
z6Banj^3S0U$Q3CKGzK4|8W?qu#X5axtaL7_gG{|a#$-RVc at _mt_Ak0K!t^0*!n$T*
ztR1zY{eP5-J3_UG9vn&4(Q`X&1P}Pe$2bTQV^tF<CcnX$ds!?Cz(QE6A~lDzVaHJn
z?t5Sq=B(}d2S85~&{IOi)cq<(VHNF<XDWbDMfcUQfoo!+Z1W0BCES7DvX>*4Aksnh
zBkSX-4AZG{FtR<KEdMoMV=MW!F*6}$6ae8g82NNk;J$Z;Tg@)d8O13K34_pyGh-Hj
zR>fc at CS&Zx*>vI at cQ$T*=KxKd>s~hCUrr~^b1!%2)%`j;v2M5%;1g;lJ3V5A3w7xR
zmAELjc75#J#j!HQUj&xGTU)s<4V?o`jmZaT^PmJ}le<(hqDcXoD_np(O8HLf>c&`<
zytg;XBk%%uIlIIm>PNMjJtHzjEb9sydj*Znerz0({lqTl6!weUrkdc{ULNh>vw>fk
zntZnr{VUBm4nORq6Vf2baPrWCSr(tU7e{xU`}GX3To&zt*><1wKn7+3>i8`mC|Z~j
z^+nsSBO^ZD84J0MtF3E@{}u5d3_+=rn-Yl&j?Xecm=lE(+1HmlLR0oUJ*XmZ4QseA
z+kVf~NL77hWvYok4Ul>1{#79mJKY<L0I$@C=#T(XD;SFmKuofy2v98?9vt16Jx&EZ
zsUvL)5Oy%e#UXJcUu1d^zn>r%kT!vAhsC-MkIg|S$eovfQSLCfND?z7WPc at l-h|bn
zm}POyg71$!Mii^nTy_=gof92WnY3alqrrx++}MMKc#n>GQ07hX>pj_jils17N<ub$
z4ig>=4Pv#}Cw*id-g8+Yjdna12FE*G|Bz?T*Y$6~;nz at 1u*(<?Wq at s#H9jXo{BY3L
zx<8rHPaZBE%+g9XuU`W!Rr*UPy>Rv=%*kn6{22gtAeC&hoEc!set$NToO$ogsrz${
zrsu|DY3$2*XTHALXt9td_ZXY<YF+I5`EH#%KX&~B8g&8Msa((+$kLi+M>=YNl<U>3
zi)ogHKN*rlaF=ZHmug8iD(Ff7sGuj-F3o6_2lmy7%vuAYtZ38se!&QvLIPrdZ;ns`
zVNkT=lI7pDHU5 at 3(gt7F{ME?IYxs|NQx;pD{ai(CeMMa5zmlPdfu}$&3C_C4k3cT#
zY`ReA^}?>AXuo0jjD{M at 9w2kK0%R#M_Ln=w9XA&!!!5QMd^0EmIOdHOf~pb2XuD8N
z*7xLlEMc>|u%RiC9hpGVQM)s*H6-dbAyK#MOb0u|LjpMYyB#Eo;~ap8NSZrhgenC{
zxl7n)zktnnbOT_s4zOvoep3M+-mB2*q%brSOmhUFd9S*Ew|s_J-z&{qBc7>vDZF~y
z2+G{6BORLb_gVYt2)HI|dV1*c2aGcBC at 6zi<xde*9+0?vrxL~!9^`&NIA;;;X}e(0
zihD2+s%<2p-fb1Zs1MmekVcSKG2p`@)O!+#P=61Edc;D!z6U}*YLMMyf<OcE>ED~U
zT|zzk!8z&T<3c#WIqQI&MyU6zllh13?Dz+Y9)NNh&{<P3l at BFR!G5?<6CbhH4O|nD
zQ$W&34Zs87ER77L0<bBF^OL}sgmFy*wh6FV2j7IopMm_5`93RvQzU-EdJc&{C)#|D
z!sq87xI at hM`J#beu!ydohs00HZQzSa_(kr%lqlTFlZvY{Ok$AE3RtJ{V%rE-e9G#9
z!e2>3=+{~RKSg1%&#p$`l_9~O{Cy1ye<R6%T2k1RZ$$jF5pAU(%##ilfM=bsDs=EW
zqHk2|-_?Wfj^L{A2>?}>!9T-%`@Y)xecHM#e}>Q3mH<NIl>aBgH~*1N5_jc^k^-+(
zh`VCIC)oi+e>kGgV4orW3iGe68Yv7W`Xj3jEcA<J5&pO+{U?gFV!-H6mGh^x;FSCp
zK7U;D&)TbJsR=mr>CtfLGco$gFtMLgc12;ai649Qa~_%;{r3c at lxQpwKK}&-fh4~$
z9t?W_`JzR?v}mr+Q!PO0uV^-q_<v}N_60?P6*~HY&`~f_;LU!5ze0PkQDD;Fz+Ar-
zsee0y)c-9|RHPOPYN8E9v|^!N*X3X3v%)3+`=aVUSb*2xQ}rKV`H~>f3UFvms3_V0
zC}4EB#{i=h&{6C0m_l&?n1&wjNP$fW_sTwzFjDc>4MI$B6jlmQIwZW*Ak!_vOXoN6
z(m~;+9IyZhWcxZ4c56x}fk#14UrmW%r4^u3>GaqqK+%vA+?3x9;8fMVPSpaO8frQu
zsFc4u(k=e3R4^7m>0PM at 41GP{p@^vH0H`Q6f{22S-VKEN<`lBNIW<K#k9PTcRA>Q?
z4hbCP?=2MiwiL7k_!DIG-gKj|&_H!Tp~eb;p8S3X-MC-yr&{=c3M&B6A^)xv+!H8t
ziy+VWLOdT#fjkEVc~ag(WZfwW>>Np=ht=Tsr0(I=y at v#kD8VB}B15-m@}p at qn;uK!
z)Y_Fg{vIRwdsFvbPz6}+efs6z$Fs-N98ZS#r|$98y`TFJq>jHwskBri{-7%5vq&FI
z-G at l=VaxkrYW<Y05<|~FlIF;okE%f*B at tg!;(J0LPu)jS_wh7tCVWC~KS9PFHljNc
z|4C8&lPN|?v+>q#M5NNAPiYY1y#93RK5ekdXUJ~6{aKasS<2azzs1DJ6GdM?mpcBQ
zpaGvZ9Qg}M`2}vDOdZ)jpSmZDqwj19d{J+|NI51(=;W95;7dFR<~|MlazW0giYmU6
zI{u!b%)d(=e_tl~!+>1+UmX0eieO($-B(lhHPU at urGA}c_lRDW2qWnmMah3(l>Bt+
z`1^Zud^2_YeS<9b8>LY5-?B&F;*qU!zO6F9&D~?ca%K#_W9y^u>cw{{<9n(5UK-a(
z-vK#)PEmy-Z|r%rMzW)fZUYw*ULJ6 at 0gxblV2$t1)_ohp(k5*hB-!2qCR9L1gbKwZ
z<01p%U*^Wy2Xa-5eB&)DMB#R@`zI-L))nEaYB-y at NpW2fQIg3Z>yw8+bqG2KQdFXq
zQ~8Pi*%LUk{5eTR#5T#iJdl}J92?S7F@}z+F#fhs#M2ot&km8So+^P|{NFW?tCW(o
z%<|$FrYc%ve{`;@Rf|UZ#$3BXfZb*GYc(clcc4W2K()oHYFFgGw_AceC_*r5Azvv$
z#LPw+A4{+hH2O|&h~y)D;2qY6J&qTZ6+08CjEEcdmFSM at uSOheDdo;5t`q}iYw;X7
zBKw{#h8S&~go at FGnovK*CP}`jG44(Wx&YP(SsGU%X2DctMJ|Y8gJR?Y*2e!}1 at mD&
zt&RB>sE~&a80$rs#<12TgU#~ynBv}Zc^r+jDU`%_M-@~DXpCc1qd!7Ituq8v7%?2B
zI=E593&r|KUAzmmqcRh=(Lq*y^X!9KauTvi&DG~!Sbpy)`1k;l9}s<<vD^A6SKBI-
z8`96tAGP=!2gTx9IV<{(`8;P|x3%m%T1Jcm3klWf52hERfcb$@z&z#ScNmM;*@+{v
zuUPY{jOId00x1J93nST4y)zm9xGGNmBgQ+9b?_i6i?3bT3XYQ1_Q!;yf6{nscYMU9
zb~HK0b8SNmSfnyQ(Gl at O=ED`7+8z-l&Axx at 3uJb$XmkVEZ at 1Mt(w*ROQEKeXpA3z~
zmfkQPy|*}KR>-(mNJktB+u_j;9eZ at _&`H%9xUaahol?q^(8;#XGXyFNF1rO-KYZ?a
zN<1vk_|Pq1zR7OXI0&U?mj~`4hDL}gWYB$x{;SWcry&xpD~8B(FeLjYu~f8`OAJK`
z%lTP7o67g=Kc6IxvrKy>*@M3&<z4`MiPUBrS{*Nev5H7o at K5$d<KmEYcj-m*%|lq?
z6WK%I?XkxQ@%TmB?4!oL#ZHNBO=zn`k;l at w=NbCw_?YgPQuc4wpN{HJo15kkvABs)
zEIq at VfO)+)VML>&AX=Qg!&=f5WUy;$EG{@qq1~#;xOV7Hd$>D|arZb=Z=$J`Kl)bd
z7W~>SY1~S`%7tZXAODn$S|dUQaoEA!>QFQm#K4N!O+vbhaW)0M(MARzaAae!a}d7S
zZ<IK+AjV`Rh%sHV<DO9*+801s^{C)w?EMn?CkU{>K?5ARkKxnm-o#eJ`0;XxF8Q8(
zmx-7?e4)z<zcN4n)0@=O1MrZRph5`r(G~j!RgWX=Ptj?8U$(68%UY-3X|$fR{4eo;
zhV#3*H~M+Ybw*=eA*0;<wVcFH!1jsvUiXL7kHg`$I2IszYT*$vu<XJS#aYy!8-?oc
zWFxUG|LD$KhrP;fiBO;axLd8>{g6J~bqpyi+RqX0Xm{*z>mi^{ds*vmGS<v_k}K4V
zQC67$&#YI+ at tmVy7N}~aUqO>s3^$pG at oI8^$TTpM)i>=}=~n6~UueocWM!W~8Tcpm
zav2a1@)aZU9zKeWT>-*b=}S%h>=K+Dn`_EpF^4?tu>bHOkN#1IJZKolJWAQks?oBn
z1OY7D2b%154L*y^o0sy;;vk<L=i6Bw)jyPzhQDr-?=yzm at bqe*36w)mn`Yi+S0<GJ
z@>2Gk-L{w*X`wkHjG__>ATQ!mA}s*Mv!7d13#!NvMkS?BB8<)c-Cjl2&)H=P$^KT|
zk2S{k#%0Ucx!3S%?a5J!6AWBN-;|lJw;C`2Wa^c&U+6YeGcB)R5ENe?XET)`TG at B>
zKKqJgnxS;<-jU9e4)u=};HCW8T+KdgX*ANkQA=ljR`$F-jr;FRDL$Lfk6Z8XXA_KI
zb0WbqH2&P|?=+B8BSq&iyz?5bIe?Juu-69D7<o92P$+jbP?0an3a(XzMmv;oJ&Z at h
zg~J^<j{Tt>)eAW)9d+H_jCstIGVMgc>kG=#`q?k7GtF?r?q@~Z7 at f*%@+0?n-Pn%m
z=PG4~PxzEVfTy%&@7phXIV&BB7yUNusBiYSY%GUuW!8BaTdd=<zo^wy#b!LRZ*2tA
zEZpkTg4f$z9nY$VPYc3zmi4c0yh0Rhz4EnmGO~ma*M+Q8b<uYP`T9zR(q+EjMy5?z
zb8^6)!$v)N>U4_LBsOMH;*0=rXWqe5U$u7m<p^(wTSs=g-NSIGu~3sDq1)~(_GUPu
zbO6&})S;IC-43;k(1CWAPG4#<!W<HX7^hm)8a&CP5aT$mc38CIe~4858{ViM?XeAW
zFdH!iz#UqrjhJ9|(o8%;wCOTTrQOeE!x~FSV`ux1ifqbJ?Jp!rXTd%~w}zKuF-=&K
zMP`Xs02l31HBm3}sbE*vI^Y|J`|G}Hqfm{LtKy?XGCwV{^J(V%5nEF2vE~{J(*&!W
z at Tp>&V)ZnE2HJ|tti#wqVp6;@#ThzA1KO)?Hf+x3Pg|XpD7gN=3{!f~`!&#euB0qX
zsp}G#OhH7LFpZ%ir{!<7Ox;+*geFylQh7DW<;1*Gbk2N6pi4(}76GC2hnXNHzc&da
znv`Rz$NpNX`<q&(AZhlqD1DV};|ppF7~8wV>4Vt-C40rIe9}j(lBci=@lISzoK3CF
zrs%?g^5QUD|EQ?C#z2Y#8x5J_7+jo5tQkZjR^o9c#q;~6{Q5Vj(|fGMGti1+3Q_Z9
zS~yv!2E%mk!yxR+o;D%CJ}-2i`WQln=Jz6BSj#Rd+xA&svAv51n;ttdgW@<IhvITU
znDqOZ44u}ly~D9#V>fJvm$PxP8w3DRH*oKW-8hJLVF70OSFIa!BCDdi6q9crV~t1&
zet`$Nd8nuO<&N#BrixTk(W72Tnb~Dd{4YnKxWn)$Ggm=(#2I`CDnVv&(7)~%BN!KJ
znp#)c#8s9h`gTtI_D^snJ8k$>e_b22!{d_cbS at rb`JJ{)a$IaMpZ?KVx8rHl at v_eD
zdXq+_pQrtt(9Lx^j)VL)?78J`0GqDSjd<)t-GFUYlZt3fIM~p>xqRAUK1cd1?nLwT
zh%#UeA;HQmiYeK|f0OucLcyW?c0A%Nbol6$Mb5#GM_&-a;@T-L71QFm7?p$_kAh-V
z2-yy!;=IWJ+gyA0Ez>_^g9C>h*JM71yMkTejZuDU{d at OYi`-E}4T;>*2u3qCa>q1U
ztvR26!}P=+!HT<J%fhXLnrDz4#Kl;`oJ`Ps8Y~~W8#Lc1trIihgTgsU;U{{PZkGDu
zSh&n`2V~ziT^}2Yhk_FH<=@9vg at 5Cy%Rh-IrgNxwj+i)%`dpssc)2leQ()e{-I=$k
zU|vR at Gv@k8OK_{gYl%@moJS#WX)o>AQF4cIEG|i=79%}ceYw(-63fMTr4E3Lu7D&G
z%w7id7R;POg`O3{$Bj7&+lrxOh{rOpWBFh*9%LO5#KKTpDSL at Ojr-=P=$>l?QFwwY
zbVT1nJP-MFn8O$D|GJ^`|6gwCAChExLDA7Mej?Q?!f3IyB;CP$WU~X)N}-Rk1=j4{
z7J$Nm%7ji3mB(Rh<$tiH^X`yP{v<e$<a=gcYs+t8ae-9lmat8e@^3d8E;JFLKE4rU
z*_wl3S94-~mY_h__(s$noViV3R&=DWp)cM39o3uCVJFSe+$8*CxBiEYH$`8gXhuhZ
z0DojRm?mk3twyQ1-9O76ILsQ{L9;CM5O^4PhQ+NS^bmkQSeTnQC|E;EyU`HhnHxe_
zffA#74wV~$w((>nLi`JAjakkWl-jiH_nJYn8_aYzQz8`GQ9XQLACidmnnfr)nYy!2
zsN7QZOO>%5*anim?floqe--}IiPe^2ZgTsu6^hk~I>A)U#Y)6Fv7-R6KQTG7U#Y#Y
z)OMh53j>B6CKO{oR^;eos^O68b_iJ!bRP_2MX(u<>>lMqzIK$eD|3CatvA#dyj=@R
zx=RZX<)6yJ)IR)YZeG}4ta07`*?(BWrkkjp?xPXld_Ra#;w^Sl-S<*>FZz;1vnU-v
zs3^UHWVO;QBxCj|E3Ck;qoBnykf1#%|DbJA>~0TGAi#C;QLlrs670ypK?Dgaj2+Rn
zBI`i?z$Vzqigms_EXs3QMJyn9_;9Nf6=*?JeMe*uTB9rgR9GWLHe$)4@*;S&h_40)
z{h-=9{Svw#-M_Soi{4*Fn5d(32Zn at add+i~H8K_vqvybT+5fT%OZnqwl@`0=>}xpo
zz~d$nu7~4=+5S{%DZk`+(pJj;Tld6k81dnP(K9*L6`5EoaNA)imNeV}xU?GT%_=2+
z$pVjSnXQUQ(<)H94UJ+a85F||%XJIfNce^%Kp23Sl0SBM+JZMI3tKoYTT-I=D%HLV
z(Hf?>c9G(-=`N-??(9R%XE5(Az?6rK7GwRR#8|P;l?7|XP7gH~-+6#8a3l-Al7TSo
zz9;*G(bo7f+Zkj6+O6z+Ljkiw0jBP4L&f!y*-CFk)yKmP@<KM0(&ED*MCNddZHkE+
z$XhHv-ls|XB8!hllccefD8mvq7>&?|T at C{+`0TQen#mH;c>;p=2qLkdJ-EDzoX80A
z+$cf2kF|tS0(ynQZ1+KvM=tSAT54)yLbeIqP2kSFp}RFe9o0*QKP)p^G44$vQi~SH
zNU<oR#X=^dVIjTK9wiJl2Fwn}Rx`d8yo{X&t=r;ab~Ni+Jv0uv`?scAKOBQ;bXmRd
z!49}0wB49T;yhp?BfsS$S=^lc+1RFqp=Nhhd#f}*7SYmC{eP;K|9R0`zL4_a$_8QP
z?*ppni&E1Rqqffexc99ydZB at T)DZ4bTW7@%gr)+g3i6MXncZcD{pAxI_wT?nU at UYn
z6jieubJ2BV at 77!jlbp4Vvbqqc#f><%v~o9%gIcgJ5NI!=ETv;+y5*gc?=qlb4+mqu
zHJp9cDvKX at v6<V;`oFBxDHzP;pG(B}`Aq$Cj1U!vYDP!({Qnb%K>FAYeD-szFn%E?
z?$7Uw84gIw#VGB2nsijFNN;%A<aQZ}J%(S|t5i?*(Zd>nR`YDICkd^WuzT_U=cT^%
zYtk7#sg6VI_BQOCQV-~AURu6=QF at PV`MG1qO|aS%rA6tT;fYJ~)>^))o`3(5?>^GB
zxreh%mX!c!SiAR!MEd!{?<k>~@7QrG1>O0ln|72|jg`w`I`YwA{*OE+D@%`<YGL{t
z<s80!QVq?SfeX{`hoAZOh3R+V&k^P0*#A3aEiZGG`~|(Q@#9(hp>}E#SMnc(du<kQ
z_gqL8?|xTgdVWMA=6FcE1C?n-{wBPQMaH~;3VCB%SL><dJJNx%kia^hUlXo_c}Kmc
zQtKf$UTribR at QoG-yr!C+>Av4hUH!nbYc3m3Wo-GI6M)5BIs=hT{#q7Q-Q>nECo2R
zls}*F`I2;*O8JoT5W6pPrF^1Bk85?+w4Ro{d{qyB6+-)Ab(xl=`noG$nJ1fjn)32c
zPr0BNDkl;XsocZdY3*sDf3&JO-{zXGt}hJr7)s<?wB`xHX_;v7jHxUuk$>o*G+2|m
zOi7{3mG%h)qg8u9W$kS}acsiGuQXcb%0oF{haIB5kYe!4`UYBOx5c0~##>E9iL~~V
zhMQQvn)rny8rdX~-s%7$3^*mWYiyW$s-D+qV#{Dp7+`cz4 at qrsDm1H=X1Uh<ntG&<
zb_Dv;r_^#E92A;!&Qn0)p`JDZ4~kB%jgH%3IF{5R6cJ{K*C&Jo#vzQaE>awjPok8s
zY!E4j?{`5y3ZT7K0Y7P!Q3;x<-j5l@#>lc7vmsB1@@KIPOA0^O!`lkYq$ik!$az_8
zv|rl2r$Qf^@=i+!ol}F3V(K1KZmztlr)e5FS<O0rKzQF|!FedROW3vJM|)43D-q^U
zzgsmteW^{`Ra5C1Ov`FdeQ9qWZyBhuM|$7tCoK&*ek>K_e2%86TBdR6tV&PYsB~@i
z*0sfUvx6@&Q)<tu*ySx`{_J*ruSXnC3y6(m0}==$a2+9owaOsxNF{P+prBg_r2Cf^
z<!Z at UUgWJ;UD8t-yh<|wmK++)vAPwp$!J%IRK|1^eVeRk`fMXAQATN{d<yB3s|NXZ
zM*p-Suj<<h!WR at qPY~?VHACJe425PZDg18o6+7L~7#;&;=-vKT5mmDWEkwVjel4_`
zr%`8#1~WRerYagk?<=i1qFB4u#*`t9nrO{%j^+~2VNISVBEHr at fnj=R;3|(?(6g+E
zvZ0G{i?-RM<w}7y82xE<fJTP~n0p<wh_N*;g at EcPW7p+VisMH+v#Cui!|&Z#hFSv4
zFuv{WiYV%KV}%CG1f~cqgAv(N8pSe!p~RHN>NGj9%s7f{w5^BnG95H}_VSdepJ%+%
zd>k?PxvkV}w^=WO%&>(8#3>{j65i~pDA^c%F+h`eshGL^Eao$m(hP@{L%U4IGyhsn
zq;kFnr^2`!MBGU?nD~q0pHdJRmO&|F1JdF0LW!oMZ4&gQZ<J2)WwYP^nyzoJ4eR<B
z)%57HiZ9bYFX1S<e7RKXX at zWR;b2d59TB0a#?%0Lw=k=X{ys0YExwHU>RG$jc6|@Z
zLqvc((FRuh=mPT6ypow3%!;wdHq&9LdTM5buh^V}eNkC1)l_HnVDOr5!to)vPm?Au
zWxK9dJ3t@$$0Docj3h2G%LkFNUD~Q7MTt-=4N_34M&~MnbsR4>9T+ZVY5qS!sKngE
zeN$OQ&zcc{>X}w&mDOWg$R2BFCJ&6&SsVwe3_9r6C{YpcV-wW}s#Zt(B{`YDkew#v
zPnBw#YBZP0#WNz}4ytAwb#$5yM;%VGW{S2IU!ppVS}5Ie(mP-!rj)%TQ}bYWJC!)3
zda4=*#x~<JTEfPW at N3tl)Q)RC6dXXAFj7<;M+d$QCLwb<QYhggm)0Lmj`&N0jF#go
z94^#zvhE-_(x at e0Tnl{AASTW1L0lMN>4WK>=fppBjb`)8?&x3mzcL2fw>*kV9BECY
z8dZDRpes7aWD|~tWeL^54yM?QS(Syx(NE1}doB`adSYjoEgD`G7VQYTl~&lC95!kx
zVuxmCS)KU*kNL`YTm$i=*$P+W7^*OBVW`quk#ygND&i>^s_?T}s1=-qHF?CQC_4#Q
z=-i&ShA7k5ATCrJ#-WuQWE-QLG9Qr0CIO}27<rS0d#N57TiD5vHQLE8jnyY&b}KuK
zWg9ISF^0 at 0EHcIrW2BHG1@~xhH1nE_MGNjo<qAKqq%KH at 7MX@c4|83j2eN6#YU($H
z4`Sb<(TIg0grx{Q8>YPaUWoQ4hNDRYQmky#4H$M6I)pk7wl21#^*9VnAfNP6p(e1(
z0};clM<+(j*T^1?OuY!|J7kZlyvQ!|o)wmCFr<|tM9Unn=Luo~jdo4l%ibyzIzfHs
zeXBaIB}W_Pbu^oMO8vO1>uo#IwaJ>Gdd*5^UC}nYu0Tk_HU0V;FXJn;TQ;+fTaY`L
zqE-xb$*!;p(IMEN at R>4 at TN#=({LKwRfi<tvW<AIQY^f18C`S1RgF@*>8Wh}Pw+Dj)
z>uJ<9Ny9Y3_H9fP8qpT`Pwmea#X-#T8j6vcsFxL4TRwANJY9?*oZ49X$^6Mnv(rCG
z;4OlGXwU4hfL=r>4&AphN$fRudzVUu;2|-`s!^B>Fgye^vZR#d!3?z(idk#2*DCoo
zR(qO)G<>kfI2YnJ)<*j9jm8|BG?quOXu7O1vYN-d*5XLP<!M`!D>W8JT4Jy`lJqry
zE*og(MjS;bp~aDyKt{|AV}I(5wtOi+fTH(i%QH-9f6z)-UJkj~`4~3kwJ=ii!h!+!
z99J2_YM~d#XKEr6hbCHrP`$vY*d{LRYBT9D{h45x{*_?*LqSA_PMtv7HZ6S2yk@;5
zEw}$w7|vR4$aZE3f^pviN0xfpM0n<s2E+OrD^%}QuPUTC3>e)is)3%uON at w;LLnuk
z$6Ceo1(`@<*_FDFdQb)?qDcm3!(LUULWELGAwml&R1OBFg|n3gXqa>@(txyDD=v*V
z&8I8fjCW(vB<w)Ta$07bQxY!JAbo))7 at 4Ih*n7)6U6mQiyq;Ezc_e3<QaZPxO5*&5
z<wOE)A&3MJFDzFyx5bW~Ea?L=!)w;1a6E0qP^Ao6u%dTl?}mJnq-!vDB{H`LF$%G;
z;8zy{(jw+&EdX<4l+rZ at rqW>UG7_J*3qY||SFzTQh=~m(^);9qFoD7f=C0($LbV(g
zs^wy#O4AKK;6p)yxy!>OAI;oMRG}zBC1{zZI!%PV8_bPWDh6V6R_tUKV{VN!4&cVz
z<-pu9nV6fgE-!N|NF#Gs#N1^uHv=N(CLQ#T%#8 at a%nnk;B+bYQg at UNw5zNi4m^-v4
zFt_DUQe$qg09!z%67917jr9;uyR)8 at w^$E*QhZ>n2ZtGc)dMp%xDG at XuH$$_#wvAp
zu0#Hc>nPoj3lWcIXd^YSl~$|jqE<A4>v$b2?V^d~E$1DQkjPJ4-o<qrl0XtyRzg(K
zaEi7+dW?(=kc4hA33(Ry*~$wdS9-VL%DsqOsb7$-f-ALL4R{o+FM^xMg_DA+3>^|g
zM*G{jNW73Nid<BC6uD)%5|OYM_(Ymfxw~CyuOb)Xo1|?C%&1X;8DZrHGs2@{MhGcp
zw2Lugd7qLN?{Ao~rNNARvLs4co5w-YwiL{0lC~vC+Q1YeDpaRc?+9k(R?HY$6PVGO
zsHAihQ%FkJCV9GSSPoLozL^nh3|^2NbYosj0G7mxA+ZU-wn6|>c4S4v+r)|_LjX$V
zHCR!6sWyrg?e$1jWOPTeB5C$yMUXJFUITN|;er*>JPlTSF=RBbWCIsvdHcVMI}<oL
z at AAIC?;Ly0t~6ThY9+0XcgB{H4;=(!8*}NECE4;JDUxm6^cYsVv(oG_vznP*Nnl%x
z4Y?pqL&yO+FeE7i3^6%r1Bsz&nzl|uTGF%$r9cWv+t4_Cdhq!qgnoa||Np)-d&m}n
zBnIug$NzZ#&;30A<2C*0EbCP=qsDtq(1F`@fq`$CId~&UiNc)bp=!_~0H0^UJ-VLx
zi)9Am=1smw5q{yBp|JM~#0i{yUYaR~)Opkpl|g{Y0n_Ka&yWd3NHdlm4<r63RA!iI
zk*@cFAk!N7;nXmtLoIu0K)DD!;|&ItWvOXx33J%-fP2gX=ItPEer}Bi+?81;^2W2o
z1E!pWfyQ7)LT~}bIfCk3&GgteXLQ}CCh>p?6;y%Rs*shM3}FW4$Qcl0q-?Q_=49!B
zJm8#CYPexhhV(;sIrERPm{wdu!-7>9%0fD{7V{cJ00biB=^3fHi7+)qT=3vczR+!P
z+(x+zc<|b)Va#Ya-hm&|aTid+rn3!roY>XwLQWw<s<@eLLvfQ=FM<T5g#lB?q=o!}
zQ{2g5c_F+M9bS+Y;lwZ^#?Zj^8U|1+dhPPHnz3M at VKQeTz>Qlna0?e%aff+KModl3
zuL;OVj)4>xoP`NCx>$!8N=}i-o4YigvUI5RV7F-xUJBH;L$&L{U3c{Wr-~d*Btjpi
z1svmY?d``4GASefCYY4kj!CT<{450&T*IWPJgv{G*%drU70;`Rn*MscnlNVsY8*mz
z<&Cc8F}u0aW~shKT$#NZS0=++!<8ES3v%U}5v*V&*eDf1<DT`xvy50+RB#?F?g!ZD
z3eRwDQePoMmJeS6x$KjxkMfX7L~}^Rgr<}Dfyw$1 at 7<R0UoSe#I0qI%ax*RX`c`>I
z6gpQS(@_En at f>_6=qM$MI!6XANXHr^9F=+v7<_pRs1pa2KoroF!-b_!;<Jo%VJ*#v
z7Ba7)M=G%spJn92q9o+PQVyNqU08@^A0v~ir0(gd)8U}+R~^cuDti?9rJxuH2b)>8
z&@hD_6!t%@c|2vBIp;YFS-xx!3WeE>RtO3Q+H8x?%-CQ)6onspyqtX>u+dCYNqB;F
zs-k`mN8kOvIJkSf<eXx+WT5O#-lH at 70_bbWY?@;i^q<HwZU;eyuk^91z;zUbu9~q;
z7#~vOonS9Ui7=-e`Z?uLbIL#>OKLG5TAU;hakas%NoF&qnt#*hgO~zu`m0%u-7?f5
z`hg)gI6j|-CCjt85nw1z=lYTLWmd)vjKZ=D%{T+uO=^@V3%xH*6p^~oV$R~*G(xR@
zqq$yn*iq3wG}eSPJ&<9R_3CcixGMu$QdRCi!8{~793BA-<fPL<M?)t{*>%9E4JDn?
z$oX2)p)8XdjcZki05)Sa_Tp${W?aPvMEIJr%y$q$*-$3kM-lJ~JO?9)(jAA1#=NP(
z7zkNqrZz<*O>3*aeus2^W=jJGai2F6nzyD4O>dVAUA|18`7*p66tHW2nL;O<hqSX?
z6<@{%CB1<wXCg}Nt?pY-0&1{K1S&(}x)j~a at xoA0$q6?LlvL9o?3JldOj-_IrDB=W
zh4^l)Oog9ZM$s_T?s9xhjJH~FMsc|{pbDO%QSgRKuTM_7<^{*fbOv}f{{(c14f|I6
zC+5JV{>h;ECwxbkZ}-X)xH{&a^l9mo0!z9usA)_?M8s4K2SkIjp~*kd2ol|6uc<lU
z!b;B({T+^ADy^F%#HH)A9194%05Jt74n)m+HUf-+6;kB2gB(cd0yr4ik4fMQMqJzr
z?7 at JQjB!Qh<KylS_)^FcCUeE3&@4#di-Td$l?XM-R~8M=kXh+u^S_l<772N#Sv<;^
z__%VGfD~7lusM%A$vN}Xa%1aw+-gi2XZ-DqQ at v*RlHkj3G}A>f=d)P(o~~66*=|<E
z^oSLi9uX_rWSmV!n}2PYW090BR2CF<`z+Zm|JpLq_SPq~y8LTmauEWQIR9Ge!sn?F
z>Qs`=2&3fCg5JLtOqMhE5rgteI;CZ$+f5a*b+_9sA|k+UOla5DY<*R?+k({f+-|xs
z9GIncSvu!eCqb%Z>CEj0O5d}~mx$JxLkSAJpAF%<mALHa8b3QUo$YjViWO);O|P9_
z$j`POI$B&k*q!4T?^|0BUXdnv7X_SfO3tKC9oKU0{A at W-1cNpmvNjmxt!GXk6|Czs
z=X#_i7^Jr2S!)JEBK2t<z5vf!Oqh{UOnH_nMlW>0UyEl^@hOvb5TdKA`PrszzC~=9
zxtgDy3~LP=YV at XJ(&(?74c8mN3PyrZsUUiX$<aE5{_$tz*;!g4b10=K0*6*MKU<oP
z25=EmKRa8pQ^^p-z7l301&Hh-kNhYRCP@}h+?k)Pj76BH<ihv{?v#>SCsAyb)0A9y
zqB!TE>v-8Dip?jm+@>IepHeRyc;(5WJsd~^5QfLuSeqvnTdi at j`8F=TmUFVv_R14?
zIoVLkJK0zkX at u_nG<J1Mf97L*^cb9=$NAV+A;D6i at Up<v2=T?=1KT at X90LlAKPul)
zDQWX*tzlcD5??9&LdXJKx0*UW$PCH#mQb>GvWKrcq$*wCKXy%8V&)bXne2rufD!MV
ziRD)2m}D!y)4FqsYJ}@KDO&!@d8R<$O!0?RfM>r+Dl5wE3yL^q^5nrk4x9(g_oaQe
zcr3a2;EaO}AHKj4itkY)LE-npbfK|U2?w14c&(~*83-GkDZbrxD`UXwH58jSyMzAg
z%RWJrbGxkd8goqW at B>y4)Kd>^vf*+$C_xa^h6jnm%vcdr{C)=#<67sEhU_ at CuD8h}
z8g;KaZERwQJT_{;_1Oyr|Aa1<6>oN)JhA4<lbt6Ug{n7q?tLq7S at YyO*F5>I&XX~N
zM*5D;0qoLS1p!OzlP8;f$s(JSl4ql7?V=so<e=|*$`bc=%5uV3@^qVPA#}U!iuQF0
z*UFxx?TmXT2qU+-+)j&erHo<hOqHPU&P*nACG)uF`G{p_D_I7PrQ_$r3;J1 at iMMG5
zaX-@;v8D2J at e}zAL*e0%eeJIv)3W%Oi6(Jwx0GlN$l+i6+SebmQm(=1!gx7<_!Cbo
zXWk5a*2i)P*V}wO8Y`6xn^%#p>_~#9)K~_ZGg-^TS6cB_TgC}<#)C`o*LSm~`Nr&4
z#gk7;gSjWnZx^2uM=JA)9H+8nQ5Ei%lE~RON|-oTxDEwkZ1--fMyTKw23j~#7%vHm
zKdZMYS^Oa at x2|G&PZ%Z#!b>i at kQ{^8Wf!T_J!|mZZ|mxxw!dNV?Rx8G5rvkO?@^h>
z52{mO2O~fM9JW?Vit3hR>76nYu30J|M(?#Ms1c>q9Jx^=t3b?j_ at Em^P`o~fHl+ks
zSH16mNTMwPF{?FWt3k}J3u2}l#CNa6;@=^N#h*%WxB|djfDZm#nC?|tp at X%2 at uQBc
zX8%{*VgE(FtSA^p($d9usSD#)u-fNhm+(&4gbzFR1%0 at CXkt7_ba+Q|o2q7!-;b#c
z at +TM@3bB4fyWS9#;s@*nk%d3i5<4!hRqK=1*WJLBFiYV_GK|oeEr>HS8!}-CGhrZt
z%ptiu&uEb4j4nT>OQSV at t*$lKf|<);|6?rYcsa2zc^Kjf_MO=!-e%iAdSuE$vTyBh
zN#4MkVQB6&PKPoft(@H#1o3Hs6KGb`jYlaHyV9=r(9P23;sY$Z<ax%AnCe+~e826A
z0SxH}s@>+sVm_RpH^>xS<BZ_F*#ZM8h2r~#&Y<uQJMIHg?%fAeu-rG{EAA5Z5TfKH
zErAzuFF`ynKCR}oKp~eRJ<1k7o?)|Hq?BPP>(ovbzyZ?@{Q$1NV!fR8l+qz@>MlWl
z4?@^WHI$=Lj|xXvx+~wS-<b at b{ONToLkHYiT(uYtC_ogB`Q)5o5Y#e5Jy86T at e(UM
z1sNMZmC&IJR(+dGp{Iip;kD%<4NBFtTh?6Z0f|m?dTqKBXmTv_ACN+ZE0hUAT_`(~
zsx;#iY}<_54(JPW#3T#AAqUojI6nTG4q=G0IvFDBEu07#1lswvaB|z6cIP>$`}oTJ
zHl4$(r9(J}iGoVjx>$#<UP9|_G$+P*TKhSzeDUXmh(h7nt2$wHG${8A>3)YH%|Md)
z%DOyj0uo{_4d0STxm|#VtJRTh1UOElCWMa at 5$<-S^z;YSgDBt&p!uE5bPG6*aT>3N
z09dJjzf&r#_+d35oW-v${tsP?@lBW|AWGguQYNg{&5E?r=pG$j&cs$W0Ie<)Uz&PT
zoow-cx$*0oQBpmAHLGyVzYj{9!nf5rpapa&%22k57_;zU=^h6fFi4xM=v2=XBao94
z=Byr3zaExC- at VpWce=M=10SUL^MXjyY%)a+&<tqS7Hp`;OhfcQyskVqo&Sc&R#pO3
z&Q|fQhN(R3x|R0yWCNHGbXn3v%ddL;7ZMp+LKH?Fn}W0U+@&K7Dv_RTMY^R*0LwC#
zH0XR8tLX<oi;N)guCEk+S)_DWdd>iKRY-{#x1ntPx_Ot#GXf)>a7BPiV+>=mf+U)X
z_wPWdsaB{2YNbkSVLc#;;G&7OkHQ3JBBsZSFu>SQi1wb#45THQBWP%wRi^5?Q20oQ
z$CNolgMJz#;XyQqX$+|l&v_tM+JVE)yk91Wg&p;!K+B!OODP^QHmB*ztP##6HWTPg
z#))fS&ObI9a>cOXSIcG+yaSm5>q)1AwEPhjb*%Xi+TUUNfB%KC1Z{psSE7%*V#lK%
z04>!O2HwXB9PRj1Kg+|J17Q&V;!o&G`TUXM$JBJ;fveaQVnZD`0w%RM0Hm>&$Rg+X
z8PiCA@?+FaPdiAo)-Qzwhz`h489NBOBG;#l9m4D(Kx0CRY%mj2dX|Btad^*ApjUe{
zR?Emrk@(G_vMAi<^t;K-8_lH+N|Sb)V#L9{W~6*O#IkW@*ok~^LX0F1sdPP|Ryd;k
zJ&qev08C&0CkHa!*_E#WjXT|E;t09q$(v!bB$9QcHqL-B9u$~PBTpLPni?>s;lL;_
z5ezkAm!FV!h%Jh;suqTCvM4bqYzT_KEaDY^*GM?F;ufayp>dAE76!!%Vewb3<l8eD
zc<Ackn6b6Uvmuuc!i-H`hu#^CvYn{O3898#5~1y7#6&C`I{a+#B!OD?KsZneA#LvP
z6U*U~r_A`}`GM9D at u{$hFGxz<?jqe-p1V_G*-B_NipoD5sE9f-R)8gG8Vo{7MPJ1q
z(cp|`$O7dYrX6T2L{~9_>6J7N3k%bo(24jo?8GI)TW83!Kd&tD2&XvKZd_dz<Ll*X
zhc<^QiqkW!Wjzb_w3|%fEm;(0Cl1bZ`iVcHUFT7FOCa|mSNx(zBdM{S%!$^qNvZg&
ziJ_K4p at 5rJQe+(PIU+anYN2Zw-|Tjf%WTAbIK$caE2PtH3##-~7=JNvC6G`tqq68h
z>=Lxaj|+zF8X~sM)S9_vpO<~6GV{Iol~xFzbt{`_QTav?AkW*kfWgHRgqp5jsdAn8
z%Z6sAnUvK6TRJr{$LA=J1|_&SibfNMLGjlFgMiD$15}c?io>-`jqACz$W`0^b1_G@
z=_#k`#Fj2H%~kw;RhN^O>5w5;P|JHWcNBkGZwnVXwC{w?@JP<-_xK9x1kA3WK?JFk
zoWa#9{<vCM9r3HakNP>lTXsEhd{{cRutMEt9T$kN1+>{kcv~2z8oT3hUu4|6`%!qq
zn4W`}sX=mc_?Xz7Ohs3RnZjR&VLsuz&KO-+W at 0$GKpQ$N8_eMgB9vyI6g>oYvs20@
zqCuJF&H+pZYO_{08)u52a2VEDZSz_2lOE-8CQBeFOcP*`!AR-G5i|U`aq);TGh`RU
zW!p8&#}(9$mE7w)C5q5Wa`?jJ9YEDLX=BrzFc~u;=&Gm(F0~U=GFt!DHTs^y)OzUl
z2oAv_u?7|Jmw%#*l6bnSQG6J^VKmk0JElQWnueAv1VLhp;%}&(Z<?=uvJ09tlk|do
z^{W}yA$s+)g3Miv1y!NLR;@hnlpo<62qHd{b<XKD;V|O<rh$N`ti=Pi3nuG5IqZXp
zMJYtokvo$1EV9X>Jv^CB3$RN67%5%Y2pZ2i^^G54w~(AkbA^Vsu37 at cDvGFYe74*R
zwI%U`D3QK#{3G+W;Q~GGFX7q>WF}9AaJC6YeQe|^dSFpb_|cw+7^S8Y_!-fUYTQEO
ztk7FSKpes!m6)J(?4)9iOyvhRS-Ka!o;egL{Bx=<DE^j^Q~W*swbh-JJ?MiH)w}h!
z%&k(Ix^#g88k!TyO_3rAi5HBh1st=kW>of+^M`@L1yW-0X5mjV=2At at B!rnm at +rP5
zHxFq at uM@!OLeHLhrt{ve-Fw<&@R>snbaRAgBzwrg3Z7sO^L|l!22!*M;Fg1cja9x3
zeO at tj<L+6#s9JqxTY)FJ$<96<gFmJcHd*qTl|bkNO0DD-t;>>fb|9(zt+tLo!3SZ+
zi$kSqBZ4R?oGV+`ECX~-JR-RkoOMBogF-oQJ>F5KMW^|(Qr_p+yhy;QJJ~BS7<tNh
zF1lQ%M_2<ph<z<*#%bM~-f_%1ubYxP?3=T;<7E&VFGo#fr?^<oG$YtE{(tCmem)-@
zYtoB(`W?TZ+bc+|kxLgRadPpwH$kZ4Kh<B_4e+Sdt~<BJ*5wAy=;@$+3w3W_Pd7^Q
z%NR&vGR6O*)}URNPR%HE()uy9XVxv^O3b50IN{UDdT04a#u^r*W7~9>n|=B*=TV4s
zdU6$p>muz+deO7Am$6;KVr~*n`90ejpeT!$gSf$RUT{%(Z^$%6__!WkPdpHI1e$39
ziBX8-(*ejYbfYctr)T4G_Hb}U-cKS5FqzpS478v9lXB%517-SG3}XtHMrNOWROz-X
zhu|zP_t6US_3D(hloEJf;mNGY`8O__UQVu&^;0>^9Fn5=ODPgt$|t<OFiF6!?6uMH
zg(b|jZA$8IsBKef-}1H#{{WeA%=0P)8s9=L?W-JWB;wkY3vVH)`hce?o)s*&SH^W+
zvjZ3Mv8lYvIk<HLVgoE%rugqAX0VMOdv{ycBjx;T6l!lX%o*A1L?2s*3?ECypd-Rg
zQ&>fX45e)L5T$LaN)}hClw?qFm&(1Us(3(#(l?r&r3eO<hLXn1SXr&6%z}WDOfzi&
z0|2=#l)#cCDey$aGm2zKWSX^v8ZY;UGFpR$?96#r8b{9#{V*uA>45dvP0A57YQVj-
z+6QmmiE|GVn9Mz-w)2iD%cxIK(C_c$LZ7VSJ^%9ALtuu$W5yRyri`($j*z|I{T&P-
zo>oj4z~}A40NeO%Jt@<FgtPq)1A?%`*5O{N<r56pdTu^(Z5UuDu?}#ccU)KLzYJzH
z97n*xO})^EzW+-|UBK+$PUwN9Hy^^XfcOm5vwWcG6=*J(0ZQ^4Bwj+{6)UuM&Ib@~
z4gk2|5)w>bFug6hr*3Mt at XHyh#-VdqU}N<be?7PlFsX+F9h=P+X7^?+vE<7vUtxOo
z*Ja>QTYMJ41=b+7yPDdveP}$4UrU9sd1nCZ-1RKQ&+3lo(r3=Fp3lg5 at N)SOWuIl6
zhk5^<s>bq~aQ&QBO&UsDjyXp?b4U#=KRUz2^K1P$(!NF9FdkltpI^6uwEa$tobcB*
zK;;UgvkO~=Df7N$UuZKZ{%7I0 at cm&X<hWJ6{dhTZ_*NE4f1T3?SeLaCT=AGyczSsx
z at c*5)5sRF*Xfk>6{9W%wqW;imM*GGC at gZ}Bl`fVbK5 at xzGs$;kzH9l)lV(h?C(pn3
z&A;xvlj}`;`H2>$u3<ig8H*>v;-}UA-Q$I~$<Fvl;Zyk1+3pzhId%3FVO2CEpB_Ps
zKN_Z&&!m at n`F_gk_bGnmH2hYWIV9#WfPafTR+ewH=r8RRKdatNWI?N~`G?6+SHce;
z2a0{1n2Rei*-+N~PcLr~gVK}|1~kzfaM&^T5m1skAUu=ot42`?Tf9`{%d1u+9H6WV
zmfWFS99<|efXMRtbi+7kDN#Rc{8!HapgF?5DIBH~llTXW>s%`n4C*pRVCDlW0Ri%K
zz?oMtRQ#!M#^XFF{GVg_?PTP_NBgdXk9w*+-$P8}OXTC<;Aj}W)P!=Qjpu`zSthUY
z at t?k42cxq2U&lhaLVRv)fJ<;Ly)Bie%f4obJ%)DK-{hoiS9V~A!xZxzf#N<z1L8LE
zZ`dI{dnj^W1lxpMu`RQ8FUEjld^sXHp-bo2j!`WS%Pej#h0?tGUo@=H+C3hQ_h=JW
z$cf5fY1nl0Fq5V69=YhlE;1aEh8>A`t`A8KlQ=I^HX5};Zi=QfQm_-5%Ru7cDv#Vd
z#AKjP;Y+VaN*(EAW<l{kh~wCWFg&D89L*2I5?d%uqAe_s#iwS<qqfvUS*}ccz0@`9
z=P0KVS<ZnCIa_kHv_)*CrPO2b>y at G1jiQOeC~R~6J-?eXhhSLk>+_6Tg}Z2LlfxxP
z%frg(`C5^Vp7F)HDl1^Mrf;Hqhd7`UY at vfq7;&%>JZqXpxiHWsKtYrWXWL99#LJH<
zMQ&fOun!OwIXT1iCj^;)Pz1njI^@Evc0d<7(<-t#R18XdC}x`?ADoD2+iZ#BtWnM6
zUbm8-Rb7MB!KTxGhD)RVg%NdI{M<W#;Y+e7F#NW7V6HrhLjXEPJ-O~1r%8caa;PYe
z3fFG112VV3aL>>NC5Bxo2u1~?U01naa7a^ju#i;;^R}*lK?;>c8|o&G5b~U;{Db9&
z>DE#>q<a7=Q~a-D5Nfz3e^ete;0hGi6d1G?vPprhYYNy}e@?6REktVyj93f#q`=-a
z1<1<)Lr+rR;F<zEtUzy4;Epu~A}c_C%8lY#P4pz=)F`j#J#3})hgeC{iu+?zELwaA
zH^35m<r~8K!k`ppcO&*#$6J{!jS0cgsKjo+M0u3RiVsoJxgI+qOWB(HOcz^IE4vO`
zk1CdeVN`epTaRf-MW7tDRTXsLSlXU at c2;G{#;DkNtbn|-c5C;NK}0?A3H40y$K!sT
zTfv83fLLwt!(Oq{X!a01$H1Z;-ORj0%p68+u~3NabRx_=COmDop>j(37%iw56xV1p
zuCb2Ca5VxBnh_P3;2)0Pa%CnyCT=&SB*i)!-#IrE|J(;)#~H9$Mp2=+RaF=UnBjQb
zbR}yfx!dA``y3bOgJ at V|*0Po@%Bb-jk=wI(pfM at vP_$`qgKPopGMq4jrjEBr&~5QP
z%JS$C8&kG2vNv8R at 8G*)Cij>t)a8r)k6~Pyk)j*MbkoH!=LyAZOw_o>%R4zrac09E
z#o?jhVzD^f`EO8{+2p=B+?Ut;JP-QATxNK9U^viw5oSE*;Me7V({}k<$Q`BK=m(y9
zTa|zZ5-~U%`T}OHay#=qI~lW5gqy(5pgU69-;5`3p2oi!#6Y-muMC61ZOIM3>L7b$
zIxWCX?#3!@5p(tFpSS>2Vq~}IgW5Y+zzYckae4PCS;vi~&1lPLryPw at -N6={6_sp`
zcE3+Zd-lVg0isbk%hB$`8y`l)?LM6QZa$eX3_GYN>`j(Na*GZtGkhg6QySOg7)^G1
zbRDkfqW404&^O%c8qOvSuK?TklHnT$8~FkPghh*wMZ@<pR>xRwRJLL{${z;O$I83m
zI;0_`mD2)S;^m^tukhwgj*61DCv at osKyNq-<Kv}W#_bGOIg;XcFo4~q$gqa!uS6Gx
z2A0dw;ep2=dtW*xiRHUP4J`8LDn!xy%mwM7LHs#T$M6r#&H9?d7+RTYD)R9&GsoLS
zuQ7=k$H;CmvEXd@?c=2#DS{6Nr%@m}M4B%c2t57`OJzEwMZ1yzVUM+~_70oHZaetl
zRl)7uTn*N?lG%0*3>0FEu25mg2bQGy#Cy=;>$c!%c)YZ^fRn>FpPepBe%TZC=dx+#
zt#Wp{1qW4lF9!tTOd#sL*iUPbKF72b2f$GXw)<YkQ3%G at FbBjHrc(2B`Ypk$(s-1{
z(HqGe0;wZ_Ssrz3Px5GAzDxZF1^}+mJ!P=TCqZGHS%qdJQth0x&v!+H7!)9#qI8D9
z8Nl8%G$54)!#tb2U{$gFESjQkeBL<X%MZh|<&k(fLrZM?ERT-6+0O0M;xozSfmn*(
zTtHWg!W}=5YLCy*f^DSGG=U6Pr!c-{T9zi|&@$E$u}(5dVCfzspF}C+vfgJ)Z at ODk
zp-y86IV0ap`@?1pXx!AR{LR0^F{*F<L#l_}>1`dZ=ghkN&8XTEBPQyZGb2>`xD)u&
zyGkW^whVTzi@(=o`ua7}?%sZ1`ZoS2Ch>38UnlY9 at zV8C`Dp1nk)5_BzV=^`2DV at Q
zx)QEYS-vg|XUw4^z5si~vj%G<#2O>gQczoeu7NeEwSqOM25Tr}fm2tr2Gr~dCji4j
zyJ5#V3?Zeoy(kT9Jnn7$D>?>0{+LbgOYfJ5$K&tQ2SwuN?Ah>mREkPx$K!0;NJj|d
zdOIHZI~y!K3vQ!rDUUctfGhqqm~jb<G6Q(3Tsji?|0X1|(k^r0^9tHyP8P3O-owm>
zKa4cJKQ`1G_n;u8X~%J-R0|_1eFp|7v5Zt-Q6lN*nfSe>l2n#-Lx7WtkfCvI7{?<j
zzhtJoOM>fw^^iRuPew`YAegqOt at J@y-+VvRJmM)w%B!hTH2l%`Sk>xp|91S|t^tz6
zfkx1Ha~vuGIf6diMIZ#!{FtTL$-AA5NalD%JJ at lBl<eC4p;B}>DD9>YcIf5w7JVnC
zOkBV5$w$k47U}TvJO1Zqvdd+E@%Uq}q0q2zg1l$}SHT6<qk4!k1!lmZ#S!(Q?dDco
zni&n|Yz}CZ9TzrnMER;wY|Es?YAAJ0&~J~o&BXn6`N(^5fdN&zwjb#G8HacDO at BG>
zdPHb5SfjC}(hlOiv9?mB<0ysA(Wt3SzMmw;iGf^-Hk)J4x56((J0P)PS-MjS(YF|F
zmeIwwhzi3}nGnTs5}&zs!0*y0rjN?&W$1h2FKIo?NVM0v!PFg at jWdhUUa_kNNmkr~
z6$S60N_k~kP?@-YP9|UQZ8j%89x#}<3IkiQtRwRHM}%=<i6{Z5*mXFoySushV`lrt
zFMuaH-sKyOFU}ZG#LL7 at G~GW>{0~ds=vg(4|8)>KF1=v}B}5X3*us>Xta<<3EaiJO
z^@w*lTizS@@+~S~02 at 9N>v(Af%vlIy9%RhgCx8FI9Aq8SDF=8X5M8(wPcRCjx4cYy
zu|tU6Yy7*zMz68f%X^{`b*;9eVfN8E4&P(b-ClqW-Bl{lpb=fm+X;5WZ9CvY8B$H7
zg at q%bsR5NO_<EmvZ6blm#aCZzy^Q<k+>X(3xK!Rt)G!w9<>ZH(K>Bq+bG at 40CoOo>
zyZHW%OizKH!IiOdfcm`Ysi-8Sqo*>+un(0zpu$#PbORs9!-5z>Q2kgmD-w;0Bb*@F
zLn#6AEKDGN3uxt0>cL81|3So3wt+_=ka*&+!ARhW2wUs|rxG~m69srf(Mx6%cM8cE
zCjJ_I08)f>YrPA@<zc`wc{b9G1Ghqfl9HZy6U4b!V9O8}6)mv!ULL*i-V5asg0LAv
z+$(HF=X$5UIHqdly)f8CMNs&EV2%#N3;wexIA`&|0wv%}#F>O0;z&YK-mDXg1%m|m
zoFK_G?<DwR*$kAT%3eOw#V}`(28 at 8DIk;DVZI6bf=bg$`p{-Et>g5Uy>1*i5UU$ed
z<@Ywr*Nxvh)W_v at 2qDX(W=eYuBT4_|8yJv8RZ3Nf%K>n~6G33g-b%|e?E%?6B`GqC
zcXuzAhg-Oq4AZ}1+#?Flj9>~HKua1lC~y<C6gw#NAC91j>53k7XB<kYjzk-{rh)h%
zylHvY*?4KjyRBj+oQ{`7I~D7xr+8m{vmm`^Tu*x73vkvM2~HWeGA8A8bbUN3&y>cY
zfcKoY(DAlte5HHDx|%NcXr#+?X7R*Y&-t5lk0i6^S9d!{Qlo&lY_no306Zvo|JDGE
zZXkS?9T|;w-8Wv|S{ieXg7L+e#K1iNK2sN#Ha8xH(yPKoQ4HN+93Yd2#c}!p<uMAi
z$-N^pjCw4x6%HdLuHwu+L-s9(5pB4#WAppT1yI7Kzw+_HJA+4}L1R?cM1*-1$sHua
z9P2v_Hzn=EuL(ENQIH~jI2z(r$EQT1(L7_(E|Oj%#B~U8r?}h4g7)Z&e<*}LkuBTq
z#Re#MNS(U-1Zj~&8PA76#*p)a_|fee0m71{0yHZ0VU%6)y&3c=_(o=Iq&k>Axh9yB
zGm?&a{UMJ4Z@>QCGu{~o_ZLlZx#90n4xS?Sif;IuFu$CAng$H~A13xbr|?xtZMW)&
zl`T4v8l9FVHWbT8Tgdf|mB<inMF8=YpkOqHj^pd-sch!O*U@%y!?tMD6d=<Tc`&=f
z1-U!G8t;VUB*?{uTM^`L=@L~Wd#$MA{;r5*zOf*;!!f%6wTt`$(TVB`0729$0LQxk
zL<4 at S0R*od^c+O(WA_<ik^|V<)jRC-t?s>p9vqGidW?RUx}2k)7C5^U#cJey%Tg4+
z3nU_;5iANL;fdno$`ymb^@CTz-$bW*;Y8SBV2NX*&ol$#Ghy8_*{#xWf>W84wn(e?
zBTzD$9cAU5#j$AAa at 4M*TtllO;c{1r+`79&t8{QonlT-oQbO2vsZV?r#>oZ|`b-P2
zRavI-%#ltD(J@*<|5oY*!UTlht3<C86a{%*usz0e!DVr}pwnmc60^x&Fv{dAsC5Qc
z1AgA;BmRc$neT#urF;NZuE+b at -i~(@)$sX{UEpjiF5s-nq{V|0nPK9HGTP32+y at Vp
zZW0N{;x;($dI*d7*|wX~r|-q at c76~TigD&}k;Hpr at f%$@LZz<KoqFHQ6 at 3mXno-hQ
zo$Zoob8!GcKy=f4o+1*^5X}F-={<x6X231)uvPr3IgE}^m-0W8>DcqQkn(?bCb*mb
zyG^>|e_xfU_zwS{j0WV!m*Y$m!Skv8Vfl4 at rZ(O<BS+3=b5^)^=DN!x#7A&u(#>W>
zrFVLyeJ-9<r=<^=gNiO*UcRLHZ#a6*GyzfBueel25F9*2UIcuJia4&;1KucZIS=tq
zpqeeT=ww1BBv- at ney!Efw7Yugyj8Np`QY&W_F01Y9S~(U8oP%HeIi?s={un}`Lnzk
z=h at gevl_%6U5+U^S|=xF?bel(u`YE^V6s-7f2$nRUFgb0g2Y~<iM4wX$MkOvK(B3A
z07-Z&N!C_5uW97Bq)E at eHLqS_TZ%lPE=g1Vodq5EE^@U<Q-U9 at 3MA{}{5RIv!oXKb
zn=Dt at GjqKpDTp=|ej#V-QA*>5|Ht&^#hDGmn*wGfv-zIhzW#y2;LwJRMZ|v9GKwGy
zZ_P0K>W;5tU1X51u;3NxzN@{u_F8f847neg)x1m)(X7q)uHWOgg;(wIWmkW7Ft}>1
zm#%#E4FR)i_%B-bMGJJ}_M1WA&Dr1;B3beCa{UQG)>0KpijN9E8FtoQE^~Nj-mw!3
zgf*9nxY^dm?3Ls*3iXV|brMkhIbP0r?PhDw*}k_*y=7FgBUjYHim;S$&6EV~b(Ldt
zUB<I at VMh>u at m&nU?a(cLMg!WO?9Bc7u(RxMS-XC`Eac##T>MvB=3$!y+lY&vz*~f9
zEDUDl>V51qyQF70x-Q^k-?HDx_d}8>+lNPi|E*1YM_5$CS0?;^KCqK)7)qDCJO9xR
z3&{yjexCuz2ZLRU<JerTO*wlrN9+(-TP?^U+#Cz*c<6QylvymN-Dkb}2&s&wwg~mE
zSe?s$H8v7SU~I9jeVv3=d~VAr{j)ot%C_*2<uI$3_Cm~+mGf*x(jsSf*a<?YO>-<j
z)T(cO_|ik+nUKAn_(g%%MTBvavjqq<G09m_8^)0wWnE_CHz=uycalrA5U(Ga*^tcy
zA=t<&NY3gtbER=;n+a)>1w1^<7-l;w#j^641HGW<452m~rPQxgu<osMtKin9Pzo4W
zaXnu6iZ&VP{%$P~cK at S}JJnaqk?Bm1HQ=$#LJ3)bir6%!g$JyA)KMR*>xQZGd9 at 8f
z#}Y)jw3<GH#zF2~Wm)F;f at L4;Dw}=5vTQnK?K#bpEOnrW$pBD*f=M??-3^PZsE#;x
zLyF(@#GCu(N&&cIr4++!m38(L4SxM=e{pe!HOdsY#OYHI-g?Tro-8Yjby4=)wIuw5
zE$hnm3A3!2N)Sh3oG at huDkvNW<&X<}M-IdEEgZA_p2cmf9#v at J7YT`bAfI76;}5N%
zIljZn*a~0jwL=(0Hi|^>6!jblXgQ3yr9nBPYQR$oaMZXRuByZOK at r@dlA)YI5z0#9
z6RISn(lM+nOJ?p2MAFAxNv3I45<;ylnY}Y$kuW&3HVuPXa0Ua}a#{NO%K_jsOQs at f
z$#w>0KqdWZ2a}DDtw>7SXOlf>*?2)G1r()r!N`r6S;%KseSElz$~q$z%-gBF86k|)
zqB~89+UwQPv!Z>~NmpBMN4Rq=iMDq5L1AbuXvR*+wE!h!>$SQXvn3PSmu;VqU=W;P
zV3UsY=j at 5tPfa;~k{g=gWWJ+r7zcvjm7s%tnXXfQSQVLZ(=6)7(-V9NEAD?$HjWsW
zp-F_^kj(}m`xRW5)*hW^X7+|CY#5oFo|zkQ1v2bbAnHY1<n<HA8`w*dk2k1fiC;eG
z0 at _?N;v&^#*<e63$Tv6nnH%v9G8zo4gw+f`VLW8b45=i|Y^0ftfeWBUM0P7jenlj$
z_#vsAAiOQGmTwI5w+A#E<qrfyuMCECwJ+FsXRwj3ps2dy2ieOqvB7EIDV$|^Q;<UJ
zC2^^)`nYlcXC3tHkf4EH2R+{f;rMZDlAjQGg at lbB`XO-+w#9v}6<XkXF=qOpUDc9P
zW}7Pk#gUq4!jTn$)GES{Cf6w9NX;`(YKZTO at MFWVjcMw};f3r+;k&b$texFXpCz#{
z;)>uDOm1jZYDCXW(j#UdWkCF`ZPs%yP0WRfERyS9bN+8y(B>Ge70e|Pn>5gGJ;wAf
zD}f}VjGH5K;B=?^E;^#Ym+In2aZ)89)W#;#SZuXfrl{TJ_9KE^@~<;wB9emJ)Qy$c
z>V60@^{(iC2C24?R+~$&&Zk#XNmEcScOl-|be~y~Xhhi$9mXqKE<P^WM#4BMfNyf#
zp55wx>;oRRXYKnY+W(M|*o$(=yIcFMG*Mxv;n^Qs6bL6!$zkKzc;WMI%dVG7!%?zV
z&@?EdGDXk+5Py2MH>;uB7lMEHWjSv%Zd<FgbQY8gez$ibOK;k5EM~T<%-O0 at Y3XY$
ziI#rxlC%iN+MI!{dV!x>@We`!C?q-SDP*GMTjIO5<ro~Tm9N?m%xft)StvDR!`48V
z`J}EJD6R*EvW0WnJ|)pew{p4<v&qOL9tsVVRE?jI23={7d26z}fB;ubd^2_6Ze|Pn
z=|`A#1QAGK_fc6UO5WK-ClsCw<wpf2sA2RFxdUARsfdm2XcLjOW7ZV-c;%phc+PBh
zKZH(eAA&|bbUp_*RSfz at KT6XvfKM5VLD!>&P%VrYYNCwLs1buG`~X7$2%jyy(G4Ec
ztG&i<NR)M$)*wKyc@#!?Vb4ZW)=B942Dp3!PE*nkL=})Cg(1V-0BgYdlOH4<o-{FA
z__J*4(^$t;Yk7=O)|@+eoaQ*wut|q|0lI-0A|xl?8OZ2FUYNvbtT-MRR2zdvo;a{H
zXHaqumyynG2jXySwUIN6a&!ovQp#HO5@*)cgMcqokNufi%BFgWW9#Zc;}@#eOFhIe
z3uLk%RL98$vy5K$jx7UNQBDBtTw*}{Q*0J=(5M&zSkb`ohhY!Yp;$m^3N~!C=wqc=
zTbyY@(|VnIzgO<1I0 at K<A^Di}m2_kzg~)>3C~t^{IJPVY{AXiSy^ARQk-IEW|1*nQ
zQL@{^5Lu!~=+4B^Q3JCP;~y^+-f?4|1;l-YPu;NZ<|v8|K63C<u<zg_Hy?b2>wO0=
z-F)y;#G|R|^u*#^d;dbSG2NWF7#yq3RqGS;)u`TRN3Ci*IK5b}*Xrk@#$r2aOh>Ku
zM7uT_O*R(m?P{|XOw7$SCMVj}hbQJ1tEXs$`gbKSC(l<WXAg5X)e7#v|KSHBUm$wj
zL{p948SQBW57lSujf-_!YE~zvE=L!ewRXE&59$;3V6stf*XoOn#a1-mn5ss#R<u}e
zEiNoHn(gXT)Tl at 8^E_Lan`lorn)AtM1UU811#=UVvyniGfO1w(YV~Paou8kmPepUJ
zdNrulmuk&MeZE?6M at tjU+QiwpYH+;1G%;73ii8!_o|<S+MD0d2Uu~YN27BhF_&2v$
z*)tU!INzAB9+(9KwFBqQUpR2F(VX3HxBI86O9xsPYt!w0t;S+=vU*@{ZfSlWP0my&
z+Xnz*fu@`Ln(YH~wX+9&R|k&QTkWR96Yv^Z_fP&!cO$CP%f#8Bc{BemP6Q7=aO%kM
z)4_ at OM9_rPH8>(Zbv!tJ;+Rpg^6;t3;fIbLJ9 at fu=J<CUO`kmwKT<jI&;yl+<NME4
zPTAWB{o7NgPaZpd|Iy0BM^7I<d1lo^y$LE6F-avUc>2N0 at e{`%teiY?*U{iE<AiQT
zm|Sc&A==z!*nmGBu7DGw2PP)Z?>l)*boBmXkw|^l$z#VNvB*TbwLdsgJ-c`=f)yGt
zGOfTqHF#;NQEfTCcN~_IUu1_E(L_7)$k-o=PVnn3jwd2yCn*k(wp6-(9=7u&pY|No
znA;yXZb(Wy_JoPsjYia(N1payMOGfFi#NrF=c;XM-4Q8TkA-iEn$_tl2%1DrYIOu{
zfAmlamY4cyVWNHh+PXX6Xthl*2)mLAyP-Z>;A*X_$hEb;fUJGP4POP1Qd|-)XbQUa
z2Yc&_b8|Na$EPkuuX=TKrriYg=!P4j^6~mq^^yp+FwsKSwVS$D;fOKK*Xk4PMzb88
zSe$?OOsx%Pye2wm^*T=`C+aV0M`x?i8>-Dlc_rD7Hk*y66x_hN&pX64osx2c_~aIp
zTsNs(wKr71`Ieg1i?#aH)!T78ry4!rnH^<sx^GV_nx25*FHrS`2ZOR*xOx+*DR`kq
zt`7Av15H99yHRx at m-n>F-(Zz>il>mFd%Uu7%}-2DR$DC at BQuhzIa;R;&jlD!Q=w8t
zH7WQ-*&C;ImN28zKJzuCzdd<Ax-+U?TEIjgxO>nqXED4I_&rmrI4Om1&z?(BiyF1*
zTD2LSpJ>67 at ObiQ%2W#$?{Xv{0Ne!j>aESERhtnk?({2M-f0koV2od+naQ-mH{Q&N
zMjMtt32vG-?0#deV~eG;B2hS6s!bqYqJ7ux{#E00Eu8^@-oiQ>S}WI5GZ70@;G(zp
zPt>jCLqw;~Gu~vF7Bf2|2L!i+KU0lGDQ;YfMPa`cbxhY(ttCmH+CT7M13hk1Uu)kI
zO-xNi`{pL`7Hai&3nJ`OOZ$9FbZy3^R-cuslQRPdajR8rnj!1RYqWPyOAzvJ>c&-=
zN%^NEdF`egrh4_F2i67`MF>C(GBmwmYb;nV`{rfcqJ2vX`x19>-vSOz3psrCtLm>2
zh7$J>_pRwMkkTQkB(v(hA!E?}k<e)}795|OtDc*fi_Ts~wp-N;i!x}zk;eQ4+y`?s
zn!)L63kTLju~}VcR$G!Ra2i1Q2(PVuIXESK-ZCkhs at 7}Oso*4lI`I=pxtW*KIYk{D
z31rYTAC_*a)<hB;&CBT<xJc4(jxvH;YqeW}d1)qPa}zj-X3Ctwzq}wg5QGT?X0AGo
z4~?HuU8*sPlg^`_uY#M)8isj^$b0KD4k$LLxws%D(7KGLF^?q9&2>ug1Sc4O71sxA
zv4k45K_{MTt6H56?rJt#t$nULdAqaJpP1Tb{*sN*H60vDMrl~2WpD<~>kM6*NjSyK
zT?S9pW*6$DO>n{&+bauCFSfwsJva=`U&pPVJa53oQ&Y5M3Wzen;bvnNJ+)8+NyiVI
z^z=+f;K7Cn2!pDnB=Goi^zBgScnflOZXc{(YCAd_Mvq>qPI?c}ca)$Cl9 at UVVt)au
zfL;EWgf2L9dH!r;j-W>v<WXax6D6gE9;CFX*v0}w5^`;r9>I*s at I6&+O*U%_Fch$+
zG&?+j_d^XBBYCZ{PM)thwP*aMLJ1;{sjzh|b_>$J1)!lx(N1>{DRWIhf4z(@HWq2T
zF^MV)&R~gLzz4H8(78seQ%%@Z4mZIWqCd4#Y*0y)RTNinY_aaRM1oYCUzn at Pv^i12
z*t8~)2V4n;29sfmBoW7v!nU(kO}KxF()SCu9n)0>3Z9~T+l|S_oTr#@;M)X2lI|8`
zAxJ$^ZJ}<RKzk&?wHFrEW$=K9qJyxs*^5MeIO at P;GV5DQUu#GmGOc)=h8qS*=PqIK
z>4|xXrdmi}nh5z31xdk`eVnMa6+udHrW6z>_lxz86s;$jbyu%j5GT%BkStC*yEsiO
z;I&X^KxYhjW{{k)gDn3{P)()}JK8b{($T&P&Bi$s%g)>Gr!W;vYHWQT`-DFJ_QeKK
zboJ6?wK^rTptWn~8w;p^DKoLmT at wovXKQn{cFm-x1=zL88oUy${BJRHBKVKt7jpkB
zw>A97`7dX-<h~O8NH)ygk^i~yiST6hKyFv?>HK?x;q0#LC&SNX`+}$QK{%E9^RSw~
zHS at O2?_~C6 at 6Y{F{@t0c=62-!@*m0Emmkes3QlKUmHqSVe+&La_OaY^!3VOJ^VetU
z;e587`(W-!@E75SgD11E555 at o=H8L}N4cAWN5WTxZx241|FQ6{%(3wQ=7Zpwu^`wM
z3<TS at Z4<~m(SQB=Q_vs%w=LK-!29e#ZxD|6b9z$H-^0s7(4#uOrj_)6HY7K+Jf!zS
zB$0xCJ?;<qo4!xVrN4veRS;~}wf*ULkNMmEzN;vg#je|pT<7#B=y#9#+x@<)D3`-s
zx0`frfBM~H{__9rJl(!sf7kzS#d|~E`sLE6Bk5HTKmq@!-#zAU_xrA*TyE*Q9o4n{
z>35I$%l{9)^xIx`>&tJu{f<|}hwnOa^cY7i?Js;fOe*&I3t<FWLYW}Q at -N3f(Z7d(
zz5G*!PrZUa{HHn^*MM%i{@Y2VFH=yPb3E_Z+x6fVLWSDF*K{?&rTW)@YQtS!+h4J6
z5WoLmAsG;N&m1fq{Kdb&`G<FneQ-Hx<*TdOO%ah4h(C9*FjgGB^apSK{@;1vx#!+`
z@|Jr~_H3#KFaKgsBY4?Rr6RYnf}xpStS60k6ZsGS-ABXL;K%<>7zSaO+Z)^z%yd;E
zm{dpi`rd at y%#ph<{XzZ{ZyH*T26NBexFh at c*zJ2CdCy1kZ#nyg|NGher|WNf>yPJu
z<~4i2u=q1S`m6E(dHGN8dBf|^Rp0foPki~<+mHQG;oR<HubKR- at YGLj{W6Vxc7INJ
zi(uQ<vsjeo<$X!kXz8~77bjZtFZ;Iem-c=o3~s7auy&?mD?G1NTJ?#A*7-)ef)Bb>
zt6qF*1>@YR5W0m2ud%EGeXEh#_u at 5t)<+#=Uv}-q(>`+7FoNl+%H&+5Rm~rG at eU|E
zJ*D)pAnJMfH&OxjvNAn4ajw;S+qG4bd!?RKQ3L9`wy{8&iK+f;pax at 6B;f}$aBYK0
zYT$xa#6pD|uW2xXY4F;L%Bdf^wxL=!WW((*4uJyU$|OLvtCiGw-gxshR+P6}yq3a5
zO%<Z0_NGl0i3{>iI8#w*)f&Eq34-c0$@r<t#p=ZDomK)j;Ou0Dr&ARYv<9UGlbd at g
z(52ZP$teaL9rx-4Z$!RE#ph=$#23vi+g80iTP2NKQDinYw(3=te)MAN_Ej%j9nrJ3
zZR at Ics$_4r?_Bl9)k-4V at zqeOV)Amw>X)wWQk at Bp*3Q*KP)+x0S26 at 6b;W6`N^PpO
zdw5RRz+Dwajx5eE;CHVE9T~06Pn at ewmabm~y57_m=PL_1(xfmd3cXw9)o4*EpSijY
z<~5a`(4f|0aLL3?MH4p_m)e-RzPzfanvnok(6SZhrtX2ARy4OxnF?7E^3D@;H|$ua
zu;^&5z9d at bZGv|zu@^<Vrn6+^PE`uBq|S}2X_X*LUEWk$)t0Zt;M>j1*4 at p!R~1R>
zCmr0fxsG?-y35U=opL1Dw;N%ZTx6D_dRW9bVGi_zjZ?%{@m%d(eSfi5ueA at Gm;XAY
zL7N9Q84q+nI=I;$-DRTgUK~I9(xOIxJgt5F<hQwEM+old&YC=a@@0;tl3VNJ)|JnW
z%`LXhzkGxBVegNClG|LF^!_;U;qAj01)}9l#G@*A$EZC!Szr116+PgGxq&;!t=YS)
z?fV-OQx7zz7U!yG823bbu~~iPYM!!LM at Z(T02EGKe${G5u%vrsy4jfbT=(h?EgB?c
zaD4i8wfb$hzGeqqr!bx-E^bcUgQl)F&%my)-Lm$ro*x=t``jAQAmd$YUurHvX+ga|
zyiTJhfatC<>K&^!TdUzYGSc0knh*>}#|&9yJQo+z0iXz)$95#yxbDZE)mnFNOx{9;
z6Ugj6H>~2-PU5<P0;cQAl0ZK`k`U+NQ-a~NVd-Ad!^CmSqQ0R+Q=bNR*t~BiO>~d{
zSOeU)tFLQLERc}9f9v|MPe1s;3M41P_SH^oQZ=x4BE{>;;jWf!D(Ccrr>s~P@=rhb
z?GA66{^&q#1IlRz<4n)|Vx8XyH)vqWz!+CI9~zLBb=MDzAa^Y`^;UM_{%ZYP`~2%R
ztbF>&PH9JsSL-MS at nqdNdG1V-!2f$iiW?NC8jU$o^gDK~p+tgO4CGw(?~hU=>GRY?
z`xtC}w7&EYHZM#xTh+Ke1urD8|KW%|Ol~PHMf#7n;O%q at J=i$nmIYM$Y5CNNGt8R3
zelxQcbxrj%Kux@=iHUND%HG~UMG_Q#)*ex<p4}$Kfw?qVH`aSBA<%41uC{KS)}~e)
zl_s{EJZQ6Gn!?6i0T|k>Zm~y#=XJIAdGe8`;r(WPdUflan&<k{D(CyB8h*;FHY|5W
z?Jx-cY-Y&g_T*Vj+s_Vxrp1NhC!H#s6KRuyQ*VB(*7CPT!PClE1NBs0>ZGfn$lB?o
zF)9vAUZ;I8Y^b$PH0s~M<l>Rqxmx=|Z>?n)%|h48idNBiZ@&7GTC=@LXjy^k#o|<>
z3oz{Z(rBeJdFfK+++5 at A#2ljB#HiNV7dM^ui1xy|_r^<mD|g?2@^E~ArP5kFTRC1i
zzG8`jFSmbkVd3&>MkSxP$n4fqwK6}8bNPn#%%|LC`3P?;njSd})893}@W|x(bC0?w
zr`pY9RVK#Bm_1goGWV0XIyUwAklj2~S3>jH)D>sA>>Z?VJhmK;b{9&YzbV{k&&gdG
z!H-^gBHV6Ij^S~dvIUW6stAjwfu9Vw*-MQaPF{i9H;1m{GmFfRA#1gB_toa+-r}E<
zd8NLrm7acQ*rOT##^iT}eN%Jp^1H*_bhBFhp0H<XP8Z)B_Q*GGOujYj#a8R;ZQ&3T
zMGFLCmC5sq_1W(W`==9W{KsM5!kX_7^A$<hKM4yJJUjf{rABS)2f~fcn@)q#w}%kk
z0#*x8TQH)9oIe;2`{!MO<vT+BMk|~=Ow0dJ+Hw*k{%|<r3$F+Te<Z|rv^F}A5h54x
z{b&eFq%R?l#aw!=j^5ebhmG=GDfBBtv>)s4WOX3+<Kc!*C!lodC%PXfsQSt7j!ZSY
zJH)dzz}5|ro(hZIucbHM(|MExJMRq<2sL7{OuaFAajK%CM6UIQc>bqC9KuxvOj6Pk
zKON>R0{@vXr<(sX+|pG+Pkc-73-ea-{bAk`zdxJ6Z(T1m7R-HARI5s at 4}>pCTxh~8
zuUY*|!Z47#Xkt~J`d~<$k%HJAk3GHi&BR$|y4vSI6y{oIo3kGd(ZFd{dc|AA8MgIS
zKNk`*rSCd=KY9O5DBq959|`*^m4!uJ{(LxC(fdkszJh1`3t<n8!u>CXeN3s_Y~U}2
zq>3hNBDA7e&|el|$umv1Dvi1YpuZCKIJ5E5Fef?tXW@#7bV?EFKM!-#puZaCrxxeu
zFMllT#{f?<Ia+UhJj_o|vg+v91QwIGOfUYrE~lr2*Jsszt36d~xV*_H!o2ux>62kj
zzyCr5aIbay8(}Z)ivRv)=Y?*6Gwd-YT>4j?_UyrLd5HdX*fVWx at o%`8mgoI%xj=mC
zjpx+Vw3y2>D!&c9g6!Xgz0)?CJpDU7Q750`w_Tl^``u388uY){VA~Dr?my^y+Ac4B
znhxyh_rifnr7=BMK{3t#M^)C1W0&7o1>HiP{{&U)uFL-%_FkN9wj1+j|A3JZ^v|FD
zLwawr&fzosLfzJX3Hz2jfS(Nut{Ogkv-)4dUbt84>vLh2$n5i|VkT`WZYmt^M^z*%
zFuoA>FC~5ck-B%z!hZ{MDDm1CQNGpr$@9%Gxr_OQKXw-jm;b~r;HLi$Pqmwr`5#iF
z?vf=z|I<C5U-(nIm|9%;vR#1i{}uL9tUfuv at Mju)tG!U4T)6zaf4Xq_&)pRzdq0-n
z9KepKxXIbdLc;_w+<o`S2lr3mH}6jbazFap=7cL}CtB6ajq4Sljb^)&x`or0yU6Zc
zzbNQiRWf(e`XyI2YPpU4RRCDosuk_IO3_u#B0sI(Yl2lJ`>w6gB^H_XUsIzhIdIE*
z2w0H`U`1b&;V4|E(o!QGBAGwnyujC4$UV4qZIj44YH4WK+Be9UW?7BI8`d4+3SdmO
zi6}OXt!;`P>W!kcu?~plho%9a;+ai5*S7KSDJyqRqcJ<YMXy)3B)_EpXg=uO-)x9i
z!@RL<25$CXPFF;$Z1)2d%wZ<e62>FJ4gCu=vN*}Ir*M!<&2Cqx_MN>fOE*zJ*Yncb
z_aEGUTk!BkA7xIHo5XUo@;4XGF3!#FbHZ`+z`Q09Ed;%J<NTtbbD#5OTQ_e^S3mC4
Q>~8Dkz82yAKH|dv4{GV#wg3PC
literal 0
HcmV?d00001
diff --git a/llvm/test/tools/llvm-cov/Inputs/binary-formats.wasm.proftext b/llvm/test/tools/llvm-cov/Inputs/binary-formats.wasm.proftext
new file mode 100644
index 00000000000000..20fc3816c2255a
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/binary-formats.wasm.proftext
@@ -0,0 +1,4 @@
+__main_argc_argv
+0x0
+1
+100
diff --git a/llvm/test/tools/llvm-cov/binary-formats.c b/llvm/test/tools/llvm-cov/binary-formats.c
index a5bfc012860ec3..5f52694559d3b2 100644
--- a/llvm/test/tools/llvm-cov/binary-formats.c
+++ b/llvm/test/tools/llvm-cov/binary-formats.c
@@ -10,4 +10,10 @@ int main(int argc, const char *argv[]) {}
// RUN: llvm-cov show %S/Inputs/binary-formats.v3.macho64l -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck %s
// RUN: llvm-cov show %S/Inputs/binary-formats.v6.linux64l -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck %s
+// RUN: llvm-profdata merge %S/Inputs/binary-formats.wasm.proftext -o %t.wasm.profdata
+// NOTE: The wasm binary is built with the following command:
+// clang -target wasm32-unknown-wasi %s -o %S/Inputs/binary-formats.v6.wasm32 \
+// -fprofile-instr-generate -fcoverage-mapping -lwasi-emulated-getpid -lwasi-emulated-mman
+// RUN: llvm-cov show %S/Inputs/binary-formats.v6.wasm32 -instr-profile %t.wasm.profdata -path-equivalence=/tmp,%S %s | FileCheck %s
+
// RUN: llvm-cov export %S/Inputs/binary-formats.macho64l -instr-profile %t.profdata | FileCheck %S/Inputs/binary-formats.canonical.json
>From ca1c78b79159ed421345575845ecc51d255477f9 Mon Sep 17 00:00:00 2001
From: Yuta Saito <kateinoigakukun at gmail.com>
Date: Sun, 6 Oct 2024 04:22:12 +0000
Subject: [PATCH 7/7] [clang][WebAssembly] Link with profile runtime libraries
if requested
This patch teaches the WebAssembly toolchain to link with the profile
runtime libraries if profile instrumentation is requested. With this
change, the following command will work with profile rt installed:
```
$ clang -target wasm32-unknown-wasi -fprofile-instr-generate \
-lwasi-emulated-getpid -lwasi-emulated-mman -o foo.wasm foo.c
```
---
clang/lib/Driver/ToolChains/WebAssembly.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 9aec11e69fde1d..44a6894d30fb29 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -163,6 +163,8 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
AddRunTimeLibs(ToolChain, ToolChain.getDriver(), CmdArgs, Args);
}
+ ToolChain.addProfileRTLibs(Args, CmdArgs);
+
CmdArgs.push_back("-o");
CmdArgs.push_back(Output.getFilename());
More information about the cfe-commits
mailing list