[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 19:42:26 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/9] [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/9] [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/9] [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/9] [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/9] [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 efc9dd4118a7ada7d8c898582f16db64827f7ce0 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/9] [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 -> 87781 bytes
.../Inputs/binary-formats.wasm.proftext | 4 ++
llvm/test/tools/llvm-cov/binary-formats.c | 7 ++
4 files changed, 66 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..5a606d5a2f69fd150690bd17ebb9d922cc17c383
GIT binary patch
literal 87781
zcmd4437B0~mG^zmxwod=O6nx3kV;Y{dsiw at AqfNsNeBUQLa0hem?D#k5{5vy6(E;X
z7&Ihd6cuDp5fu~^2?9}^XGKNDc4$<z>27Ut=oZ_d(bj&Qx_N*9wfDJIl>vR<=X<{I
z(<0}dbN0CQ+H0---)pZ^I(PFWNvTvy{wbNhF4<mMSKhvTd$OIM{FB<x62F>wYBxM8
ztt%<nw(ZF_Qf!NFx!u055>r)ptNS*~wk_P0NS`Qqvpo&j^>6bwrJ!8iZVP3UV%DNO
z-ft_#j4DE{jExAj>S3!=$I8;J+mo%a*`@Thrt$k-dG6+m&)IzGxtlg`xNPX0O_#5~
z;^OsJ9@={D<ri%}=c4sPrSd*fjI$J*FMief7f)ARf9Vw$Uw+x8FIw36BGF$jul2$U
z&N+YMWt-QR(tWgSEGaI$VDr$qLoZtA#NlL{*AJa@;l^_>+Pu%+b}I438`oQ at O0I^M
z+V;@`wGm35dqHW;K2nSeDgLHLQj(>+;Nr{Ax%Avi)|Zlf6xu?eR%`V|5^P?-ez4TO
zj|6J?m6u;Uw7#^jA|`D*cWA>o=Tptl`g3T}`tye_yZq{XHmS{$U$$xerKPd^sIzU;
z<(Hj*&ibn^9x9c}KS_R+v^2GpE5-lP%D9ekm2uhl at e{^Z##bgbCuwIXNs~#{q%y9p
zElta*{@0RL_N$c3Nu{Y=Zk}9jPPi$zRJzJ7X$$|Wv{cecIc=#_%2UWfMLa51l8`xV
zuC$~n56jJMQ%lNOPRr%CG3BJ%UM){6ku0IKmU1<rv@}s0TGCPr84~JGlBBgYNlI!*
zIUz}!R4K5Ul)KAGQ`i12WFrklP at S%oressH-+oPH at -%OnxIM{l|4XI1y_A>q&tvoT
z at 3SNR{jL3e$o>s)EusDM%)v^X=$~I6)cE<tf7;6j{%DtRdj5EL)KP7jm^NRs{t`wl
zEj6D5XI(y2n%LHpsFX>EoN&x>t4}=X<Wtt1KD7SSo0E?xUrN4`d@*@E`AIV7=U=V-
zD5;dPtEy12x;9C+r_0i1Gq2sTV at E09@d5s=^`)h;rBP4vWMNv$?ogWSc9NESDf@)3
zt~563s8WzCW%uhrsru4#WqWyBx_u_8NtouDFT2#02Ytm=Txnt2&V}+?^OA3JO|#1n
zJ*ITc%M;(?nqA9QuQzS3&9yEH at 3<Y~#&lHoOVaK9rqaIjvEM6G;;6lYKFqw%D&tkW
zzkav-8+N<Daku-McDsMgZud9ucK_Pp`&mh)=xjn~Q<u1OkUp2Kvox4~cT|-szd`i%
zk+y2RE7i!5LUCp2s7_3hZOgBH&s+ce;2ZAw=yr9rqx#Bnd3(#Y^1kX=RBm<U+2vMW
zS>6IcE3WB!h}jA;A?G!|m8X!>wOubF?)26Cg~YeJs%x+Nv2JWfwJSv*ZkzeKqC>OG
zk*-%K<G1HGzgUYy-+WWL%$1KHTgq>-#La<qLIY~P)wQa7Z6qG!+I-cG3Dpm%df!xa
zO at 3US_zpMDb<}<4vX1Jvl5z)aYVc4gcMz-Ol0gxxmzKhZcUgmtwHBt`*<0+k0;g3L
zrd`?F?6!&9riE!|_IA5%=C*lZnq_y}Z40+8 at MHE?yKUvR6~5GPbVD;PT{M|XC#~j^
z(Qq#9G at MJT9|w<)5hdMNH!gdR71BXdGYZOTe!LqWn(8__s_!eewON<ct;)7>+s6)f
zuQ`9J6nKA7)QXu}#Xf5oIp)erF6qK_1()(dsNJegF6Bb!7K^@%HO77EQjyq=8Dx}8
zfyzTh<#BG at E-2jUIu@1ZE8!X%$z>&t%-s0wL2LU25=>ZB?$etUexfeRe5ae}I<uXY
zU=j%?Eh;<LI=kHG_tVAs$-2z<U3r(E!uu&TKh;h3)0hd}+;-Re{%(IiJ#Y0hxSdh+
z&N=Vher~esa?{*&$n}s4r@=k0CwqrgG&6su<a^yr*IV<m+$?{9J7AYTFjU*;4s?B6
z{cPQJ`GeeSchFWpC$wd*o8#tg_49O>`Geg&ckot!i0<b5`R))mf2%)Kcdh;~cc?pT
zt3O<%UqHha)cg_dh)DXwJE|MYP5YK&G1(|-<|^V0=ASsD*)_T5?7h~PmgRknYKv>#
z#vI5Ppo$w)gQ2Ril(vrQHBC*%8|g4lj24 at JV}*}|3bTjp3M;`CZM&$l#f{kpPl$ml
zuDvFnh(%UAs?VhzP1{ohj11T$UMu`g?Z1ZLY0l^Gl}n9dTw;9T(naMi$O)Hra)C?X
zGjVBq_NX<gP1?q_jV+10I{ldCB}oKVT~y|Y*s0yMXZKsuv658dG`H&TZpW^`vYF<U
z%VPR2Kfz6i=_e|^v1{E=a+7w6K{Y0mVYU58-=0)eMW63l4tGs~{ibXcuV%Zfx at n<B
z-LBhBYqSR5jjyNcbp{j9aMK%=!^`ot4|T!9&hxqot!C2mnKjtBH_*DHdSjAGuKiWb
z*x)5m4($<Gsv_A{(jC$wk4#mAsglO5*UL(n_=A2dX^ecAihPo+yF|N=>OEL7+ncww
z78<1lW9%Vb-(^H8FXv+a%TQxwSGnFdF=X(!SRwHB+TkYDebvUdDs3P&le%`s9?CQS
zk(zEScP2~Q5&9YJN?k`yO^fU}uA}<!Zo>cnU?%LFT#YHgJbW>d#dLd+jkZo;>P)C1
z7AMBGLdhzo2ZGDg^v{xJO`#^EY*R7F3Ho59MX;!xNn1nBs4bhKwrs}sX{tfh7LD(S
zxr?~CjyY1+9EqB~ogo<OAR!9W^yV2pgWM*|>wba_!GvLjJTX?$>6jfg%?(wtpW9DU
zW0&s==7UX$YnTvaH<d}um{H3#?wAc-)Gukv<mjlLnzR(0GkR=B8h4R}XTBchF at 9+<
zuPhVTv|W9a`o%VSZ6#S&6j_E~#%Y5H)22x3CKcW7nxqT6xS$I=U6a&wb6ycAx)vE4
zP14`(3`iS4+mJo!vhp&eli1}VJ#N;AsOQG6+RgAder%#tT at cdpOrY$EZi1UQgjgBx
zIwR>Skj|1#4#~PmX2ctUc$3}K8dRI6Dcg;f>)wd|YjXR`uCPqgL#7#Ia>x=lgfc`4
z)};M3EHi07n$OR2y{Nre?tlS*AY*G<ukL5t*v at 8bRZKhT?;vHG6Uv?&%AQBrru&A_
zeRJI*HFV#6B|B8_rTgYMv|si!8SGOf7OiE6hujOueS}-!ju`R_-QjLw%`b9`RM%nz
z_hM?UTKZOhq|&$hC2onzKFS^Cj;#5mZi!neF~z&gA5F`TaYwsjYW`TLa4bX8PJX($
zjA71sl-K-nx4c&(rsS4&RBua@{R>tYZB55C(W-uvnVOZz*>H-h)DTO}YDx=C3uCqB
zcUvOk3nsm5)5|fu93!b(7Ac~gRLmwfZoqfY=FD}ttnSCt<MBwc`>dP^u`(op1VJYS
zb*h#fkC&KJWjBdZnJ1#jexdZqx>PWY?)weh^HX90=p30za7i$OGK$9llEGAt22<?p
zw2taql4NW_kP2zc!XH#u!*px5wG?;E2{eQ>Z%Jg(G~?2kX7;eXFv9~0cwb>kSTgjk
ztBOmxlXS6%*o`K#!(9jCW|UzVJF1VQi7y)VA|n+DVoI!HD}^QrrrV98`&cQ2EUZ at 4
z5)38RHs1IHtr~{CJrWW#M%E0iRLa;qi9v+*csF6dPh>0$i-575G+gz5u?RB`YRJGY
z6)`1NFmfK3B=y{s*aS$hKjX%HE=Bg5&YYiKGs8enWo0?W(bbsPK8#~W^|O^EFNjsf
zHrTs_>w}GvaJ^g at O{Y2Jq-*=qK1LJ8kRjxnO at oDpMx%CU)F!1Lq}u9HQqAN=7Ue}B
zv>Bg$SllKp;Y>$tN5(a|i3`)Y?P-|Wz0j;lye*|NiJx$`iCZVh=k`MeLk6Uun`}~9
ztwbuTl~ddl@!V9`1$$40a?@P*YQI0_On3Xc>2*KD8Z at KPAm^M252<wN38l<*Gj-Ps
zDQ8j3teR&55XE4x!~AzW<B?rEN+k(ICvli>M;11 at gVc?3HOjO;1mhe{1rv;YtPAFe
zh6f`Q53V5_o7^Gj3)R`~=OgxzkM7VK^6 at Z#IHGTU_P#hV7w{si5d1>YE#h`j%`bL~
z{gHHSi96CQbW5`LEA><r*NQkadMtHIb$2wv@#sNBp*=j-9qW#Px+VuHY8j0-nL5|!
z at Wyf;EwB0G+;P1WxTECqj_T{uWNN`bqfLsK#>66;T<Xgv8<N6Et?3pXn{<>|FzHyL
z;g}QBm?jImf`F8!Gyy3P#;gue$cjZmXjGVVx{M1Cu`G3mQRBx`;sh-xQJLe4 at tMf@
zObp`_1!gyF7V=J_iv8RqF_h5)acLZ7ue%YO4t^@f6=m#aS4Z`~lVnmsi+#@}hFo(=
zQ;NCN8{q<5m@%~?T+qT>G(~rW3rtf8JqU0?v?4kqT!0B7v6)4<fDx0xH1?Ux^kZlp
z#NpBnakzA0n{nxcI9xRMxJWc{Y1gFdOEuFBJ&?XJ!fCPnQH{Ev1S{BdtI1634XiM!
zqx$1<2g-V{usloS5>3|>+f)Cwf-bc2Ur3{8VHr1rcg-XItMa?Te-jH*w&hQy!wZRG
zbqcVzFnuyb2t&*#bcLFa>x!cJw63i2KCUZEl at II6BIPk%q3ff%!e9 at jSy)cAH<lAx
z4$$-K{kY{wZZ}SfMUvZ%U+X8pNM?7{Ax~9;=m84q<6l3?cv^CtY-Yh~s`KuN6cNPr
z at if?C5z-J8F}dm{BaNyuWbZBt>b8QqLqUd63>P#b7G(BWT*V`x{Pe1uj)<zdo<-%`
zt)Ne*ex?$CJeAGndLvFUi!`$qm2WQ691znS=nilPW?_}yN1DDx<sC(XhAlg01!kR}
z6C3nsiuj_A$5Q0iTsLnJ`E{_LQ+0EYV28-GdlbP{b%!o0{~>YJ+4K<!#`WeDDaQ2=
ziC>W4onX{e-4Qj6x`lpGetUxWs=CEB%(x@{lKkcbkyUj^$%0#oygCf|x4<pJnman+
zGb(9EiU_N^V`#S3bbE?fS9QlODqoe|XH2_{+hvQ&_a$+_bMA9s+=NbH=S6r2(dJjU
z6_5Jkd42q%@?%!oRlc9w{zc`Fhi)W(fct?(<;U%QN8(p<zj9IeNxP>9tGHjasQi at O
z)6EmOKVeb%8SeXFPQO}LIAe`l?bZzX6WxjaBzMv-e=_M#UQ~Y8(m~f#+$sK4cj_*`
zmKSRmm7hxhqhG at Bmn<qjZ;4>N(~xAR1%5f5SEnmKOn3&r&rp_XeqZ9x<nGLxKg*rv
zU&_yyE=<=6%6b{UU$!v40LFefKVQBu-2g$(=I7Z9(~WB7lc|4&dxb>lE931s`LiXz
zjwI`9{#<viKab4kyK~%m?tJ&kLcCsJY<xiwu<J>@eqs9cG;$7QUg$22G`|Q9xxroJ
zFLoPz&0Xwj{eF-VH at ZQ$vF<OSbC-ltE~S)98>RTm)Ev6M$!gl9G$mhmb$|KrgxTyi
z`^&5DazErQb3-zX62FC?Tcle8M_%Es*y*q2*_ASxOa3Z;UZura=C9`G)iwVrp1zu&
zuMT#{R(@`k-J$%6zs6m&({JP1Hd!B7p8VX7<R(A7_$s#}srhS*albC%?R5w&N6PDU
zbG?~W6vd>tA#pb(JN=D%exp<b72l+ro4A=vfv-s%MZJa+Zx-LaR_|WRyZMy%I^DdE
zn+0kZJox&=y`Iu;(eqn)zL-R}>gHB%mQvaq5_far-au)$S^FMJ{q2c}3CV9yP|ktA
zcO>qPgcYcaf;$s;XX4+OL<+;9Z%W*o^rY(EnD{p*j-uX7`6BdPc6S$dMr)?QTN3vc
znsm3lxSJOu_*?Dnt=wsW{5HFL8+Wqt-fnkq=g!EDEVw6e_fW*W_TpY%i01FGyLWKc
z9eMPfiF;=vroGR)2E*OY5C5(tZ}#s_95?Su96#<$3Wj}vuDb{5s4TYkkl4M4@{DD(
zcbf=#P$?d?6eYh?DRveqVyzEZWgkxcd+o;)sejmhAp0Ll9B+BflSh*5V^-p$D&$cs
z#B{~iQ@<;bwtJsmypNH2f8ySsL>0S>Ev46&lLHF9SjpXpMORE at i?1$haZ2svf>O-5
zpc6%110-xYCiO4sgU(C0Vo`y04)}JcY5K43#~CAxvuV{q5gkxh<K8R-0$?m-cWg%q
z)!6LD$K{!9h-No|3Jl*MrEm%^?dZ#iSnQp_tXkzKQ%@J`ldiffbKx7LYQ;R~(uq#A
ztlca}G1Ie;TSfar{r$u6OsAIVYEIdjQ}HuE6iq2=ZPV;LEzoj46e{#SEG=eI#LQ4c
zFUfj`d(`Sd^Ro}CB8YMTFAw0Q70``+&mw?FeKo-S*^$r(vI3rvT-(?RDhse5UOj1b
zG;&B*lAj at 2!G$4NHar%K`Dtq>CS^gjr3G-QVZnl9C+9>^(~+QaB-t|XH5bg2nuxER
zmd4t02#QZ|lWMX at 4oO%TQB_y|!V6_+KG{vF`>A#_P5T{nmPAus_rPA3L`VWF*Fj{X
zu0cY6W-i;px!xgYH`CTaly8;<^FMOR3JBLHHkhq4mSI0wQFG{vZHWwFIvnKY)%?M9
z;}Can#Dvt^L*1cn_W0{GBqe`Xeib$Yy1&MzNV8j at wJ0U^`XllV42L5O4azrRIxKRF
z>q3B7{IL8P#CSN0S<)B_5ojqLIhs<Au3<GC<Bz2y%iL18Y{=&<fN}$V+);EQH1;@>
zYur}UFbj_N{Ujf7$GL$a)PBEPSwq{elBhW$v}iR{SmRD`==SV61G0>bmiiOv^hxeS
zcT&xtOmQbO;02Sekfv7|r>cx)el1nLgfuUy`P1BK{&ct2o$gK at Z+pkm?9J{B1iDSo
zGi-vM$)hvbm1~e4MK7EFrS7HUZwMrO8A(v}^HsxQw0*O*J;c;z+u4}(ui(imYH0aa
z`f~uq*SWLN>Fcr&+2lKynR9NKIp>k?ypdI%@6OlUy?`>-^KN}j%H3b&E^-$X!?%HV
z7xV7o8Y;eqes2x>z2+}L>tE_FL7QLdE*tQhpi$jza&^==RbC#d+)UQZp-PB5#2vbP
z#BA9 at t}EOY)c6(X?<?I^C;F>-^eT6?dsQ9X{c2_lRc<9Cnj3j28eap)ZFASSZ8dZ@
zPnM#u$#iXk%0|r&d6e~blyyyt`uapHd4sg>jfu?~6!Q%Unz at cvwg)#SC~Y)qU3wW!
z{n}&zrA&z^VwCgid2tIGgkIf(a*YGE)T5G{O(i3()vPxpv<oeYcD{|eZ#T)f)Zd|!
zP`_y7J89b+6I3)Rw-ywz8u#YV474t4_%3Qg+cu+bQITPgQM=TTp>Xp~>DgxYHu9rl
z-)?G^*C^MwCUL~?mA1P#>O&N4vy*;Z(+-kIDJy)`uoY=oYxw<YI9m07>DHRGERUD^
z2h?!%=>rK0b;v(xYWG1Bph0&URUZlsM>jqs4Oy4c<PX&xCqKH=8jiZ;=cCCWT9Wqc
zqCM?;vr_ufDtmvz#Cc3FAESm3B<=%=|6sy|{gCvi`w$KIaN<6gxDWICBZ>Qn*$5xC
z-0l8j2|Cwt_pyQq9~Tim9*OV?mHUZE1Q_9yy8k5iu8`Z#f69tl=07cBd?s<9PTXgx
z>a+HEssEga at p$4sm$=7i%jXlvo6nQr3yJ%J5#x)27*8bbi-~&zVtgrapGy3f6ZfUW
ze<gAJ_)4<MKdFMgnz$zu_f-=8UE=<ZR*F5prdEB8R+;o#;lG}^uhYwR|Bcv&Z`#%Q
zzfT-L`S%-1Ay}SL-lxc05jiXVTXY`+d at JxPI~Mlz+e!W`_*2P$Cy7|)(~0BnJM`nb
ziTke6^m~c>cH;jbao<b)Gl}EJGs$ZIk81WmCGH;+_fItYpF{coYy=Kve!nR52Z`hF
z`;_ at FiTf8T^M{H1Vd9 at P>(g5Dqs0A45326j#Q#{0|1ph6n~FhylDMCct<(QBcKlys
z$N$Z)CI2(Kw)*Fi{PEwYKR++({`bW3_jBt0MdHXt4t|jSxy1c68GmCCsJ|q?`(;7t
zmHt<;yk93EasQFHUnlNA806=R;(t>V|J%gz_Zy1;&%}|7f1fWn?st&H{VsCc?^VO^
zsbNifYcyv5%POh(|CKoY{)@Tr2POK$@Sy!MaerjMg7xG4pG5LMC+<&)`!hBEMXCQn
zYA4+jHPe49&Hp6szZ3UAq<KMUULcL>CwK}hpxN!fZdqd)*7$2vSv%M1 at pUNzGIiId
z(b~B-?Wk5t`9akmmOHfVSinDmbOiGx+b06=wDCOdHkZ&1i7Sovp$Vvr`OvV7A5pMM
zguiU3A)*zSQ?8jE{s^PBMEuPB8X`i1!;EWVt1!Z2V<Kv17VjX|mE2~=J_<CJx^e7+
zX7`%L>&Wi0tL-Zcf+1>09|Z9dEZT{fvz?D(U8V9mX^nO7$1R8<o<7<}oxGg=d|9|R
zVQulm`KimN3ww6cZo<}@;<~p2*z=;xPhZ{%N<ZDrxXC-fXt&jSy=e74%f|rY^thQf
zVQG2SyA?~zavZSSEG=!mVOjOL*=P8J7{WQ&QgiBluFcxH=uWu<RfI0fcS`8YA?O|Q
zg3b6ts(>_yx>@eft-vxA+ZQaXt$snoOl-4lE5P!6faNp-%W;?&vRgl9UMmBtfvte+
zHSwRWx=(RY8F`iCUGXmAcS5 at 0#-X%LcpZr`LLOZw7tE1T_pp;*th*xUug_J2YX at 7l
zePJDh#jXw9KK5RLHX56+Jd)Q`n?@ygnz>e2tugYroJc#8pbH+bbZpsZNI;KwVp<Cu
z1^L^^(2os!>=kWDbh?TLv{UXHaZv*lis#U2*w;zG`LM2S7^cdENf`Kwo2ESggq2mq
z-i-!j|43_gA;beP09&tXy(dc#L*7&OGp(4J45sD7YeTFtE8<w}#LDItC%C?~em42c
z^QaCp%qjBBb#v9Jd67{Mj+4af?Kny1yLm9fd^mv(*tPy}%2^<!tuF7Qq8t!9vB{!1
z9~Z~@c%)nGj*RnhiCcupy#%oCD7SR&@IGrDK<?P0oMmp=?DArt#~Hai&dB53a(CRI
z05}=ikAk}8Sla!V*#mCnTEB`mo#0lv6YAh+tBbPMxHYrOr}z^A#xSn2tWUz0KG~hJ
z)}KoHweD26wvH|R60~EL2d6O(rxoL%K|DQ>^$d50_~T3s=~?bfch**HXCwH_+{;9~
zmoM)F7kjxodmEPWOWiBBVkz7EbKE)V%sTf<w{ELHH#|JgohM42AKf-Ca2H at 3uiu4b
ze7?JI8^-au?xL;0UZ)SkUZ-Ie?+JS)SjQE?UIpiLVJcVLWtg#XG&ga(2}{U~5L%RB
zKy&HzmxG0EHtcJ&8(QU~k?gLhV<%q;Ig~2HUcO3vc(v}@F_~YbyH~rbv6f#AxV6<?
zv(|5;VcXp{x4n*yZ0xuL4HNQTD`Qz4d7Ty59;{_OxFNxM7MgWKA{dJwHzjLjEhoTN
zvXG;#{MtrYual*$+4}le)-4IfvL4(j16qjHtx3Z;9>6%JEG%M7;X5!VFpuw)6{K;-
zK(1gPi*A4f*3&o1IK(yvvU)RG?k=SeI+ca4zeTSxg5Q$3yLk;PRlypDu+cH#ZF(SJ
ziY+n9n~UX)aKdD+U^mx<NZp%60rhr}ns<$#qMeShNVX=Ekjb_dlZ>fJMybZtyq|3E
z({1y(b`MLvXXSQV_$H4OduLG{9&M+@>EASB-@>+#uJ<j-chp~j?6@&&y$E6`0-m)t
zd}9$xGjB2d*4U%I^9{0rvS`woFPk6*e2WC<{rpb7orng+QKyq#A!K0oO<Uel_#~3C
z7khS;ZfAiwRHO at +ic(9pO*Ff_40YJG6X95KQ%rpKrDuUaFyBlm)=-L;m^}~8#OZGO
zP9$P?@XV|@hxMTZYfz4s4p>L?k}cVtY{>R`{8HSkjs5_n<^eTiV#OUO|5VbhL^@Vn
zpFC2zTa3oE0@%yY9Gw&AC_+-2au<4Xjyrgp_Aqv$C}+F*H6&xj9jetb85bZUEk8T4
zn)nOcf}IG-!@?GZy}>U<Z`g*-?l&SIDGxyH#xAKN9T$e(jEekG=7%DW)@3np#L>vf
zV}K)$b<0+<>6)-Pk-Oz}e;j7vaY2==pfM|kiM<A4S#igMEk%LQ&u#xg(o^Jo1Zc$#
zz_f*USb;d@#Y#|%l at h1O(i7b3RelY1od{@gVqIGiQ9LX|o|1SOA{BTd(_TdO8SBwn
zWbE1+g0<pa0vLml7$vI<Ju$Jm0;u8)<vUXk`+{H{M6jOjURq=Cp&~#c>g<;@geG4H
zk*^i^ipU}>1V~5%oWsL&8rpgt-CJjh^<18xD{6#k-tEr|4LIMO=Pz*QBX%!v>sR>;
z>E1=|LU&Q!Z?Gw_p-><fEByj(J@`Se3EOu#*<V6>a0z#59eI0Mk#<w$6_c=ClCbXb
zjR at IIZgUM>!V21g=TrnE+?A{SRTOl!yUJZ%mvD{J>D4rv?F2O%%5CLNI|{`Rbs~2u
zs!Q;M<Ss%NBw`24zH24$5VQ#0>kxR?3z(qDC=6~$8qy#Oau=a{J+c>xfVjOW336BX
z1OoWA2;+U>6EYoXfyrI2ok8*zdj+>8^GYQN->!!69SXu1F}%e at ub?^PtmPdga__Rd
z$l9)ktR0f9<?n9tB4qh{BYgvxKtjJgSyD2r#9AX^tJd6`<Yj^W$lP}%LxLiB^G<~D
zeTlmdWmNL_TgqPH5tifK%JG0<4-b&zJ%<0kha3+kK>EtDQ*Z>}#a9229)U&3TQ=l=
zugLyzgzsy@@+%+_jF_p0$Ny8J at zG*+w<~e{JxbZ{6P_Sc4_KlkSmOPOFp0;6Nq|g%
zLks{+Q1pidO at K+%!6b}1KY~g`mXhnEs_UcFl@;8Pfm4v@<AN#tClcTZArbueWO5?-
z1Ft?U$N=b}E(GE;Vi0v>1t>)BfFOi9e2(TlZjUoi2=aVEI0P8PkpE%=HUauj^G^tY
z5VZ8A07`sWAOr|R9Uy|HJt-(6fDi&8KqLN+4t-6feLVq!0C%Vhb)atNfg1Sx2Bm^H
zRDc~=f$B}>pHhZzCEyMK4K at F5z5cd3Y~ZM6{ti?DUI?fePv-ikt=O}KH(-jN;=d=L
zVW;p0p8NyFfH^#!fHwd;GysQ_0UW67`-%H!Aq#c?1C{#&TWlwS87cq`nw6C*2bwgf
zKP(3I*#w9I^r7Z|lz=&CP=9Pqm at AxtCM^@pz)$}DaWeiU$w-?*bN#=@bpIwCK^cE$
zn8ME}>p4~V990IBVg(2UQqZ6W00=`LDj*NqHn1vwsn@?s03Co0YW~;C{%c+ at izW)7
zLj}x%E*RsUE$rdhlK+h!3vK{)_-zuciRZCV`d;*akbGg<<+IaK-IR<gY?IL*b-~py
zB!newWj at 6EOWr)u_tiXkaOe?6+?Ka!x5>^K<X1Ip5`1a!zm91zNII&QaON!H1EXDe
zN7_Qgc`Xq~Cmfox&zf#()&p7q3}ZOJ5VlaWYpeM&dB%<kyOCP_wa213zja<Rrl at Un
z_hORr$ZiI*P at 9(4xGu#?@f|i_U#e)MKdQ}*iTPVQs{foM)AnA6l at 0A|?<j1EHc@~a
z>}|?JIMrh`HeWmSs(IMFTQ$nObC`BXNIZ^FFehyJv0Ev&n3YjCVO|MiPDV-Lgs23q
z+9=X~QS^7R0g;zzT+-?Q4L;b#=9=ZeSG1#g{Rmgkzkz_2?DIBGv71&+`yO4i;@eoN
zw`HHR<YO2_9Z-S7IDYMMTIBGg`9%mENK%0$#-rwv%XzLenK_(kq(l73k?$r~935Q6
zq!w-T<vm`OS5e03Md!7yV#vDKT}_HXg6Y^@J#p0Tsv8#vs#{=#h;M_WQzTRo!6ug#
z(CkF20(mfxH+EA^OLPW-Nb+_paBCO?s5|rT%`mvFDDwe#lZ&FJ;@LJe(iAs(DO5R<
zPSb&?vK&Y|qZ{0GdSJLz&70#W)|bg-%i?nfLQ!@-HIE4%$>lq$KTngn1xfdIegj&?
zqjBx|Pg#P%_;JYrQKPSP_LvqH&@>!_3uoK@>Tb0tYKT|6C at K!muriG2hs5)4{1#z%
zjYMF0*-x#aN%>C=(B9McR;!v){-h}b+caekKowiD at TM9wcE>KTc9EYnYZnRn8Jb`K
zI-Y+5nzP!^B)55F)%~n=nVTh(K2&}{EaO0s92PKr%52!4)sq41r0$@aV4Xnhj_QY+
z+O&+^AHb{(pe7Kl0h}fIzPPz-d6YF^o%s%2LlN7tYWZ$Aanyq`GQm0A_d<Y1*JoN@
zZ8Us$r)M?X<c>AmTrgc$02J^}dvwSg&uB~t0_a4X3KOIcE|+z!7UR_DLiWhjk^@mD
zdz5z?3C(+V2zH(7_BU$FNP*hyY#V-7hvI&h*i$P>*wgiFh3aM3Yo}aP%q)trQw&-v
zmbFy0b$-av2Z<oPkhFlQp5f<`-n`uE{$QJY2W#XKe+d8C0lqqm#6yKW{D2d=Y*<H<
z%3b#`Hm&m?aE`UaI`ME at C+45E_4Fcc<*%Fndx<^k#jFgEbPKYNh$*o>t at UhU@AOBZ
z$_!D<US|w at G)+Fbp)rqPyyB{nS-H&R1AaNpGB~a7S6Fjb(Ap9!#j;k4=Eq^8p`RH7
z#O4NSEDL$k3d*LP?3FAES7m=Txx1Rt7Tjj9f!ng1)drHCNNFdA(x~nv?oQ&)gh#hO
zId`lY%kGq#R*g|UoZL~pcf^sJy~>BclI2K0%nw(tH3Y8prP(OoLem4xA82AQzlM=9
zc*>^pm{^89^-&zCe9g+S<g;T`H5~JwwuBi8!ns%_n1I7)gELo;;!G$3Z<g|}n?UG_
z<>SHPy6kkRvNsr1@)QQuBpQQAm^O^>uG|gZHK&w_$AIsulv(*_jgNMh3J3v!j8gu3
zb|=K72fEoc_;eP?e;V-^EgR;LZq6uT%#Do&;&5~2Z_yR}EwaDZAkQbmd~uW=AeQe1
zr*jUA^f{b7=6SI|O#|zY%LRJ^3*DmCFmGbKdt}`&fj&z_ADy~M<wBv+2t_XC0eDAy
zJY;t?TKpIu*#VqmBYPa(QT=%PEXg$O8p&Z;@R&9kv?-wHVbdUNGE9h at 4LTbd{!3%p
zknXTT4OL_Wo7%VIDY3F<SJIKt=G{G|beOGK$dVmX!AnZpi8AVVC|@be+C}BFxZpp0
z8W)apox)|zqVh_mJPl>vEdOg<MzrXX+Z7&FV!0p{2ljF#E+}#;Sm`G&FG(gA`wDKq
zwWFM+pzxHKTBYMgEMs9Bl^_&hxbASCVE}Pxy2k+mdop<@u(e0tP+ztopUGpk73^?@
zy)xG8^0R3FEEW}%86BaP^7BBRA|)5Alw|;FTux!TA(fDH2Mxh-eQr+8gQAH?=8<|H
zfZ6ixz-i6yU^ek6;}CuxvZQpN8A%kdfWr-P^s#M+u=_NCsFX)A$Gqxr*+OXo=yDd^
zW*NZLv|2xsZ3gf(Z8f-~PQ{}q!J}uXJG$<Vp;yPigUYoMv1qw$!=V-7h=b2oAhl&~
zIl~;?#}*(dkJH#PVgdw at XaAueM<0`mr}>qXy$XT2s_svq>=UePwVh1}<yu3h*666Q
z)pR0v$i&6AQMv%3*es#AG`u|7oh()oyPRUaH}gsd4sTNkO~d5}`k0l~te2-n<KXl-
zd%@G(={4}QGezaI+-ZPmXMv=>)V=Iv|8iPt5L(^8f|kA_wsf%|G_~}cK$CUu9DlA`
z2T*pdJMS!iKDhwO+y!;N-o)$rM!pMa&xO`djle~r6B``fx;kiV1jef;pl9G`A}Q0|
zo)7BzV$igWs`(O-w83it)Hb?HNu^^j*;kASFQW=JGt3WZ0q#F?;oVehUAWByeu(A)
zsktq6e+8YoqA^v at VjIKiW(UJv*=W$!;h}A0w95C#UA+~A?Nx3o6;u2*RCtZR2l6fh
zVdHX&-wq$|2q4=KARAj9*Rou`PAHq`e7)d~8w9rPww*Ds=XQpX(6%(Jg4e;ms^RtW
zLSZ}O_1e)G^0%5#(5+PR21~GjT at C8E-TZ#|_qHS|-#d5>s;2#VkydE>ol4362A;S;
zY{Bi8A8!VHxl8y48yI(K8>0 at w2F30cz7cW)vb~iKWx#9{0mAk+^Zdd82P6#$?Ouv_
zhl&7EdxsFUdO*~Q{P$~d_b#DiZrH_Vfn0n_g4EtE7atsbV$&Z~(;rmR3tt2Pww(#;
zA*lF=lE~C}{_yt@#CTYqKce^}a`g$-E&y5sP778?Rib>C3f at KX_X%JN;=H3eJt=R`
zpEG^FXB?A`>hD^U+X%-3)9onv(c8*efzQRxpsA8lrYQ`U)*{@thv#acFF|XoeA at sP
z3e}oFWrjdo><BA<E&OF~pd1YU>BH>6eG|n;$?P!;=;$^12S(9boQNAfWOCx at LnfV)
zf25p?8KOgO7|2?lTi(XHeB|+7S;8RduKTEjy_-Xl34VVno^H1B3|1#I>fYIn9qz6B
z9y~aE2K-D0eRx>{*USp at jEcJa0lYN7PF5upjs0On=|ueNM2OkQ2!0}54ETAZwIjZD
ze~3+mL&SX)(}|hPrQ09MM6g}vAte6%Xjk|nU~fv(8IU754T8A0J}xG)Z7&aT6eJM)
zs7P#%gJ>V+Xm_+*f+HsuGB&U~w&oG`Zjo%H5(2;Cau~26xI^|EQI0bjtiX+PMIC{^
zd|2SG8YS>0?#11!DQGo=7<#gXC+w9J8_w?J0e=epKGmJ#POba3*6+2k- at X1N^x-u3
z5_j5=KRx#0jMxX{xI4p6Wk{;Ols=d!ui>8ga!rG?RiE>(poCYtSGZRWA;WRYtoe0r
zo!+0T;}?N)cwzeUs<!D-aTj386 at 6~?>uK(VZoT$DJhIzu81NU<Tsv%0XVYUaGFiLd
z$m2^8(wEeVZD;FotM))7H{xD%YXQx+`?^+pqjs8CkJ at R5mDp=8Db-cbP$w%4n{3BJ
zGmPh}A}u7UUsXd?Z`JzDc0hXBc}~O5^N{58HEe>|X^Lx2NFbk$Jl9K3Bb;lJ(fnP_
zo<VqXqlDQ_aqqc?u%-#GF<~nIDC2~i1GZi4iPYH>QC{1FMp(a&QW4t~q_(YXj4N+d
zu?TLYcsxE)L1Htp3%YbklHU%(dd2?@j!7LvYKi1&iR7`M1U1Z19sX<1zHV}CUx4N<
zNs<+^u8hn!^vdEE1SGRbvQCEz@#!KilL#IUAlmtOK`$KY)e&vp3AT*~@P?3W(RU^u
zxil2CSWXqF3xjR23n3rega9+=HyF~er)18au%1|usc)B?W?{@X^Irr0Z9?u at +XmGr
zHNTq+&F|tu^E<h4x*_Ajfxq^67#WTSI>cIkk&_LYpmuZ_w8&>tuiSM5PNXy&Pp=_A
zF^)lJ90LMWDA<BfQg*>7GhNNYs|G~D>EaUBI3>s$Pi2j}?vW6M-V>w6XDl_nqqS^k
zS7 at f^r!S@}+41^PDeWH6!pC?EZq}+{AzViY_i4tGN`CdTWe*>uyH1R7D`74zGq7SP
zY-a07 at geRY*+`ZN_b*vxhlWgtg-nN&$y|Phw8D!A@^pBQMYd|PU<(<W+AVIexW;NK
zP8lPCkKzR at z91Vc2NJrYdg<`i!Du8uaH475R?Rp=@I|F&M!d0mU~{33>1NvoBl%C7
zjz~OUKE{3)il?Lc(Q>l5;QW+=hP^0MA9~A{d(b^<d2{~gg2Qlm)s(RM8r;ua=ZkPZ
z#l&Tu6u8U!3uMbpsQZbg2JDEjR&*5|7ZvbArsyuwUWjPLWw45YzC?jhsF$^&0V<4S
zslA|H`@ub4tm9^`!Yd;2<`q%*98-@%zSRRTirT1h_3lNMaJ+91%G?-eUJ1uR333)}
z?$CO0gUC?g0pX&D9Lq3zwsR~a5k?S#bX25{1H49&Vxfvy2&9PHZuI++9o4&<n&va@
z<s#EK_&eH4>owDjtb4WA%px%}E&HMglxV35n`cyIkBu<9+Envgc#2343N$eyO2OV@
zuUM-Uq2O^VIy%L4QuIWM7A()tIK(4t4Tf3WHB7#O)iz1uBEXrehGAr#yy3X7X`Kvf
ztu?IR6}W-y4q1Umpv7#^0Q68{&k}&=5~EykGa+NaMcuyFRpyndU`Gs+ftz&(yO)uU
zUZSf;d5JnaM6K3NgauVG)`$Re3LL^%n-?5k4wZN at j~DrelB^3U!KD)^VVOeQ0id8E
z2KI<}a984G2~tF7b(dsMifkeEQ80!fnX=p}0x`|P=*ECch7GuiLJxEgYtx*U<_M$c
z0~L2%v_PF-!3);w?)VxOoVmTYB3H%&ejxjTjo3=wt&GgsJM2hUE9^Q`-1&Ug@)ftH
zhHZCZ;5Oo8q%jbsE9X0|`&Oxr(kSQUdQWp+?$-iES_Bnahn5UV-p!ftKhoQLdq>p-
zK&k|3UfFvBr{&P at xg6dRwH|<}lkFw2+=wF4{Wl4J?GXx!@AQb5tcuW!9B*+=lG=9a
z53wdKNkb{qH(Qg+xl=cqeOg{-4-}k`2t(N$tl)CK{RGOkI*~^Cw0=xrx}#8vCQcO@
zGI8ZWPaap^wN<ea=|=#P@{&u2&plP=mC|LdlwYOToi2f5yY-fL8)^ljTwRy64GZsm
zh35>6)Rc$7kj*o1wIP;q(A<c%WZb4GbH<{!E<<OrJJnilLd4wMSPAYsPD3A^gPbE{
zp5R%mWuO8(S$GC*rO1jR9;oC at 49mcTv?+;c)QyPY;t(-*j!#J7KEpfpVl-KveS~)+
zt^k$bXFM!M21bby8%sqFP%*uLfmYgdCbjM24IxVKE;mskEn_iFdJ!X*te0e_EQb66
zY?!bEWqP85^sv%qhhztl%-qa}Sn<skk_ at 0MtL0$57pB|;5Xd>c>}lJnm>+Tzz(mwI
zjNEpNZwMiBXpCH<+zY_~!IP07oZlO01TT at h9Q<<>ePW_7h15XEbK9GWI4Zpe5i7W{
z{2OBVceGnpW9gSmq%Ak1EN>9yxR8DY4KcYfgxomJ_17dUG_os0dsl^ICy>ni<Ax9o
ztD<O7drxvJ-ANnqj%(66zM#lyNIUC59pXDhj>o`xYu!s$gW)B38K34(uge`yGS^a`
ziKGw5 at y`sazSX+{cy!z#JWKsb$FV$F53QcHpFgK+AYPMP-&!&7&!Zvd)i{QKzP~`l
zv*^>MEBd`%z^ZROC+@?TYzQeXc6Q)iUT<!2V0i6U_m@)jrGe&`Q84)2Tpd8MayRM1
zx)0a4O at plbn%w14xyypKIydXmi$5HfZdQX8`NO#@h5+n_+?6#Jf>(*uSBGS;3dvqg
zGF*<`)*;q at uX5Maz~;88BilK}w|yhaKgf7(;x at Ae1f9$N-q`CpBopu)>%Wos9Byy@
zEc?j7ijU>rYXGutPUzIl(btF7UK0**ftOebT0=)U!`Z5 at DXjXWQ5e=+l}U%^@zx>3
zTvmXnjN9}yp47WN=|vXpD6uN+sJ_se+};o~d)?`J*1)5E>~v8f0uAvJqvQ_Yy^=_d
zxN6<QaK_i|8l+In*tkZ)ea4MtYpV!<lgVlrPiYfm6_^7r(M$B(4hPpUPdeRx1EV$>
z*kX_}V?C3~-NUxjLM_u`Ee(f({rgg)OH7Bh(;H2h5fcF|$$Qs3PoRbbdDGKKGBYM&
z%fZd8c at AHTRSuxec$h)^uWt6hZU##u|Gb!=Gc7tj%<`r$eMmd8^BYMHjY$Zaq}WNA
zsf6CpsfGoOBuB&~piWxv*b1kF3|gH1%DC%D`hVo8{x69+6jY8ik3~@`34 at 9`j!{@8
z2y$%Rjv(Spu?eF1a(TWD^Mx}GHMSa#bt^U^f{qEM3%Q`sK<*GgOXHd1nCk?#V#%@E
z4Y<`C5kvh!43VSTp9I0;iHCqb4RCZ=5ke3=bp-}tTof84^2pwH5xOOWVpT6CuK`el
z0-(Iyxv7BgA0CIYvw@&abg!%dL8bD<ZH<MlizESyQbZ6=KG;y4Pu1s3?AnIn1$kHS
z#MR;8RGSK|D*7URUxZ>deQ9TvHpEgdj-_&3Sf_>osciH%BC`Off@|(7e;Ezl<SuiY
z>Jms2tybIR`87KE5S(&T9Tv8I%?h$8u<;eKbPhteD at -7{Ej19SN8_R4nl=tJakkQK
zI|MN#apbPq;<vMzyMwI)$)X*@&bTLOlOPHqFsM2k1rXpy!``h;h@<Tdaijnqbp2+8
z33Ams{#s=RdqOk`a{_uw*(`uIX3ts?x9FL0sA3Zp9LmCYqy-FhTM`A(tq7o<lghu*
zzUbk at Ce`!N`Nl$?$E3EP+JNCp!52jO?Cubv#eQQQwKCl8Ep9elC>G->yaxq3hPiK#
zqXiRGC>}W?v=&p7B$Z4Y;RK at JUEnPiA%bWHqfH&x9VFELw3{9FjpEcWwA16zg0(36
z9U{mkq^B*uF%f!VB6AI~NVqot5JQb5du+TD#-Q8(6~x;e(#StQR-vtQP7ol4Y+4|O
z#+I^oo5}juL=n;oS;Q2=h`qocNe_-}6u&P)WJ{`znBtKf$HZoE`bvB4VB;b>#!(@Y
zAmH+Nv|<C&$zGegsm>JukGtbzI8L=<gH~BOgHia5FlwtXg;qtxbpx&=6?ej at 0a+be
zfai!?&Dsjd*ocB~a%{yZ<YGtkEacy*2$@rB*iUQYyLiOlG<Tu~;52H)n8K1eon6o~
z+?fOZEVzzcQ1{Zhf0^;z%Z7RG<+1X!fz4lDlPFUm7*nxu4sZE&LCgtDUq?_QBv?fO
z4rIxl&(HG}Dyf87Ww83$#cF#c@(fa}6SD3utRc!S5+83M>BZvRn%m%NpzHd*(Oqn@
zjNG8RWWZladoA2S9oa?PB3py645zl%2}^gE*AQQuRooEr$96w;rT{C77zg<*45%x0
zrXU13==ZOtKr@}{{+c-Lu94)Wc`FfH*2?Xqk=R0J8G>HHhN5H0w8l=S>O+Wi1xpGc
zHl*E7{%*iAAMu6oFmp<>>orN^6hZ%AJ4LWTmJ^LQdpF2j=YKdv5T at -N#b)50+Sp{r
zv&I%DtYSNy9NDThf(wDGkKo9&>>QU0XWP?uK5IHyP+{9sp4^zEMg?|0jSO$IlLn2r
z2kP=Y>T<FFIizC+{M}2J-<jmkmHd6$2le+S4z2#Kxb at lZ-z{nVKs--SXY<n-?>#2&
zsc3`F6<C*d+F^p7wErP{a+>EbLFn?sMVBA3xCRfC=Fud_aZTHuF79uVi(St5j_mSj
zoF at o{Kc>S3?)_x^08cnlFtW=Zv_$JTVZcEH&KG3Qn9%ufXzGX6)L~x!NKE`u#YEt|
zL5)KOoG%c4J}&xvLgx%PWH6+&2K;>j`f%3Z52bL}KnD$wR-e^z1CAFAaLNGsJRSob
z)H!0{K2L?Qk}v4x7j at de#bX8)4jRCXQgw|X`%+B(<#_6##;F4i9H>b|Kj>;iKNt$p
z4>*6YMTZZ5R|=;Obn at WqiOwDH<D0Ap{$8~{Wf2daLO(ZR8^oEi!A>5Ck-nqQ1s2WV
z>0+q9TMX6rbk2Y?1~nZu_y=~Ox^>ckkv>Id4W8C<1A-fj;Li;@ePEoxnFCAr{doMK
z#_<E9AaMRbArA6GIBdZ21NXyZNy(<}DFim4#Xm~ivk6BIYVp9q+5RVX(BQ{B`6)$m
z;$Y;c|0_){`G3=ke<Q`u6t+O;4E{CYph5PJ#sWWw1&D3{V$)L1K4Fjkz3AyLik|+`
zjv4%dGJd7g2By4zZE+EPoorHggK*NI3x<7OH_wxjg9g7zIAxH1(hB`go@)*IJH7uM
z%@h#(pE_5Qf7iSre_vGgUkYVFq=Oo94e}`pY4F>Gm<9 at QP|2P#Tl|kI<c}1>?zYHI
zT!ZZ)u7P42{5kReoe<Z65C;83GJtL`D3*bHfsx*k+T`4k29emU=mlL0UT|%y$OYFC
zcunyO+zsgo{>GH7H>K{z)ZLU4+9h?b0l>q!=<+wGG~i~iw18W0 at UP{8_~mt}<LB#A
zjJ6bN+ at f^1aCd9!ZcY6gELFF^4Ra1VEp at l0BiN(c6R*)qxg&M_-A=wcRluE8bT$DR
zhUdc at E#W%<rquECO(cAC>fW4cKHO!mHu$&1vhG$d-kLgsO1_nJZ&QJ9Q-O{Yck|@!
zspIdi6jswdsMOd!%5!h(?n&Lfq<Dw&yn{S8DV1b{e`hTIzSQyaK2qJEqVC?6y8Bc2
zE)^Eiy<2(TP2P=G_D26eD&_GWJ$?_l9!%YXX|z5cAY8;3%E{5gHtI;&Z={JT=3)48
z2o);8_Kh$E+ZnXr^rAy6!(=B0h6L at qwk@oetJ(9$jJ9NU?HEuEKMZqDw9>|f(i#!A
z^^KHqZv2R&5?$c?gg{kDE%pGn0L3BuMqzRN0gHo*7D=lP{x;1P#`_1p(|1O!&5k4<
zyVNU=){N*tujcpC{00OEe!oQ!Tt;Y;9VOhs<?T7!AH>vU_s=NZ3KC}}&Sk^V_WSVb
zbR1qCv0c*@c58-YfVxAs_`}t1w)sHs7la*}eyw}`K~;B<tj!Qhw6U$H<Ej;N<g}q|
z$J37B={yRtv*P%$&398JSw1|5f5W~T{fV1yj7)i%I%4iM+F4+)TUM%}w~E;i4h#YC
zhJ!nzmATTe58^7?@fZi?%;kKDjX1XAwt#s2N}jwUe9Ze<Uuby|e9R%EJb6{E&Pj0T
z9NxtxO0=S&Pf^4MOVaMUO@<h_O4 at b?mv6_&aMTfr8G&jJy0EKjafGc|o at VtpqBsnJ
zva%_+g(04=AqHZ#unq1&&L&fYfgN=Xu2pl88m4~Dp at 6xJ=v>7~V}!S`MRTOKXh1p?
zyn}tX6983{0IJpnZb({19ja}(F=3E5GRRiqVoEF=YVe&rati~z$j&3vGIOC+H0X-L
zK-<Pl=8vU#JC7_V!`x}KSFY9ja&DIw^01r5!*Lzeuck?F!3TQ<z2XYgmgL&FugrXd
zF*x&D<Jv^~Y*G)|c7OAhzZRv?5w(R;%Kq6(vF~=M=`5JrakN!@LJPXiI+O1u46x1=
z at YU%i0el&)_d6b9Tk6SqIi7XW7l5W at -&ctuC2zsPEVZI}#0F2JX85C(x!284HhwDN
z2ZdozwI*$)rs at 17P$4n1Yym$*mx^~J^4isNK2)M3O+6&-8F7}Tqx#!q_=^L3CFNV#
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
ztYDvgZ_Vr$LOa^i&5;m|ouDX0?28*tBIR+p5m>BjKG~rI=@I$GMNd030lQd5pOdhk
zU)P5gpvritB1SOOcLEfN#{&W<4WJAX=>j*o?z>3dg_3!|++Ftku!2}g-wT0V0*vf}
zgWkySF9Y6Fpa~8O|Ket9RH)o}cB6zmo0iCaVTKV~`{8Y$KQL0FFH!=9p`eunI*{x3
z;}$r}^3S0U$Q3CKGzK4|8W?qu#X5axtaL7_gG{|a#$-RRc at _mt_Ak0K!t^0*!n$T*
ztR1zY{eP5-J3_UG9vn&4(Q`X&1P}Pe$2bTQV^tF<Ccn;@ds!?Cz(QE6A~lDzVaHJn
z?t5Sq=B(}d2S85~&{IOi)cq<(VHNF<XDWbDMfcUQfoo!+Z1W0BCES7DvX>*4Aksnh
zL+j(I4AZG{FtR<KEdLE(V=MW!F*6}$6ae8g82NNk;J$Z;Tg@)d8O13K34_pyGh-Hj
zR>fc at CS&Zx%jm?*-OF(EdpXd=+3pns{*`p%9QR6hPTjAg6YGXM0Y0H-veP3*IA51;
zP>Bm-YuCrlT^K7<{6%01ytS3<;?OzJ)R=sbHV;ZrHo1!>BbpSTxxxjwqm=Kou5OG)
z$$NXFJOa;im$FM7qJC7X*|Q>3#Ii1<v6s=<>_^5C*^ljlPGP^uZK?^L?d8!9J{$Pe
zsmXU6(ZAB1<M6{yIw1{`3?~mQm}T*qdvSEvxlhmV%4N|Wm~Hn-4`g5#ppM`2fue;e
zQD3zEIx^zZ?Xi$sxZ1jg_+JqZ!Vr`?xgn9b;P@;9ggH?tk$ru+BQ#~t(}OAk*RY1`
zvhDXwja1cFR;HTx(*T*5?q3xGvD3Y=2=GdMhz<!LwSuw80K_DFiU8HZ;la_3+2d5u
z6FSnS0AUAXTpSWN@<pZx at cRjJ0cjJ+c37<I at Yo!Lg4}rt808LwizG2aLiSg(Uz)I5
z6tgUjS at 8Xl$B1IJn#-<&y>p^NDw9?$Wi;6El^c7o5bxG856ZkDe!VCAtyl^Zr6gq2
z=P=>1&>&WeebPtf;XRiX(rCwHVQ{>|^$&UWd|m$*9DWVO1iOsUPzKm$S>tme#198;
zt^1QH{p8`&!7QzG^ZGTwQl-Cy(hFx_!knD8#h(FS2U5v4%b5YD?DsEYk~8n!%j^DZ
zqv_ePSQ`5Z-kGnjHd-v?$=$}LyjmB#ey&^R&W&9^k4Bw`b}ARN2C}qf*^!PKAmw^B
z>q44k;ZKGn5!^*v{KZ<5jS70wKPu>nwM#Qv<$--QBD2<jC at b3Zy-zU0rjURb;F}|q
zKo}J5xMcaaY>mGqj<ms-HGd`Y at +$r#-ju~wXFpdFTVEAd`LAXuV&Ex|OM<hm at gtDS
zI-4%kd9ARkDB7<ZKBJ+AvIofAtpHg{jJ<HXxZ}nGWw^;UgKq?70LQ%ELQpkg7;P7-
z$@-prk0xw(7dA8nvLh2nI%;?3^@c><A|&coo#|j_ct`*zf471}ahwD25J_`ej8LTj
zDR&6l>=&>Zk8S{L)&Vw+)^9Gr!+R7uofL*<f at zKbH1ARO?~>0D>wBenTf{RJFNIfc
zA3>RWbfiO*{$6W89Rb&5O-~P9e!o%XodsnOtNbZ~%KZ|T?^42e!h_uR3+F6?J#824
zS#b{pLbZ(~)O)NV81+Fr2+|1hDh7N=gnDn{5bE!RP!C&(*Y`rGM+~xiR1j!DKK=U=
zw at avJKR72{d`t)@IA<M@(+Kqebu#~mogM#R(F0IU13GI8rt;w=D%g({YT~2zx`Ar~
zatcWLm;rbIoTZV0Q~)*waefLIlQ6DHz%~Ik>)@Nv__L5dGT-L}aEio_ThAf!=S7>(
zQ~3P+gSUzKzECvqix$!K3y}B;xea_t3BSbMmlK6sc|vhjhDi+4Spn-bUThn|iceZS
zQ247!2>n_M;HM}I_Sw}4yfP&ClfSP+;cq7SPf7~A^38~UHlnTcgL%@y0`RO8R)r2e
zE&4{a{#`xz?g*~>o&ZpF8T>QMw`bJWXK3rP{8>I<TLK7;Q~sX}-~2~9N!*pkOA5SF
zA?}I+pJWFR{lSPngMEhhE6l&PYNRlj=nt(ru+T4=Mfjtl^dBqIiUFfPQO=*xf>ZLF
z`22Cn|I}Xnl$wA;pBfE^J{zO23={h~WmgmyoA|L;Kj)#z(SJ{XN{Pl2;qzZW5J>V1
z<H4Z!e_6EXR~F6nmsAT-`fHjEB>o at TqJ3VGV1<r8FLV@)6nL|r;IGggY!sOEcQDuQ
zMe5&=AoYI<6cwq3f|_Up5v^FL*LC^V_^fcr|FNk0PZr?yk5v6<SiU4kv;rJj6Dmsf
zKMNQg?lHh<1$5MUJf=__0H&eGJ5pd%!o9LjB#czNb)68?>xGp9lnx0mHOO>}@Y4AW
zymU}_DF-Y-0@=O}h25OeN#Ie?)7MfWSZM{QR60HO2~aeo1UKb(12|Q+Z&0-Wr-qsi
z2`c69wsecXBNdDVP<lt|0YmTPI}{NW9RL-jMi5cZ(Yt_f-;zSsx1^@X=Fu*Hw+b!5
z(IJ7O{JoVz-=2b&0Dppv-ji+=78<B7DAZU1(39Wqq#O4M{!|O^S78MJI^^G-f_nmm
zZV}`;Ux?=eDUj!&AWzDBkgPjJft at 2s^pG0--qbymy7!XcVI_FjNMz_1O at 1VeX49i-
zoLak5$KRtQe_!g}2dV(8y<flF`+4?Qn&Zjvfz&;gx({&w!PN2h2$hzK#2-?nd=}|L
zsrxV~K4N)4Lam>+RbuG*N7Ecx^D#B(V<h5hN_<b~6RG=X>OPUi&4f?t?I+2&!$x#R
z;y)#de=5Z&X*S-vg@{yo^l1%3oY$X8-DeC|`7GIuw?C(HK1Vs5^0%58dA#WB=Tpbu
z<22w4h9iGbDZj|=6R9Kn7gF~`arB)nfiLOpmng@?2%Y at 09(<Vx!Q7{TUn$7>WKqRe
zQ^((vl=*k5<L at gZe+ZCE|BHkFH4*IVsry>$zD~MtsMK$e>~7J^5 at 95LvncuRi;|y8
z9e;mMj&G%ozi*P|KBE+B{@eEG+dQ&0&UaMicer~rSk8>$)3!ePu3mhXGQO9(@1=2#
z^fbu%bBZbyd1KF`HIf}=bQ`#k at bZAG4S)pc18aP5w(i>)mNseAAj$R?Frfl6B2*|Q
z85bE4|1vkuK9H+g<Qs2MAquyH-9Jg0v#tnVRm0iLO^WM^h>}bOS)V-osYB2?kfIW;
zoXSu9&mPB_<-e0;L~N7H%LAEt#jznR6=UeA3gd4JMLeAW^Xw4G>Zuag#s6LNxJoHW
z%PcQ`VXC4v_DAQcTD54jZ_KqT1lS#BzgA;{b_YtN4^&&Ms&+;0dxs_1gCYc at 7V?!6
zM9gfI at v#I8L8I^VhDbib2i|FI*yDInS+O&L%80mOUy1Ih{(8i*mQwC~;z}`KwieHU
zBeL(=Vu;b!NvIf2s0sB`Y?9=g8sqMCpbKDqkfm`IVirtQR^);hHYi3eU~T*lRxlsd
z)7qGCfeLx(fU#b5X$)&kGT1DCuPN?5m&egan?gx^cT_=jfW|mBHTokY)H*{zg%QJ1
zs)HLvyilx<)Wy3{J1R3_8y#fTH_tw#B_|=P)Lebuh2{5-f{za%`2o?#8N02Ia<#2O
zxgq`R{1J=4aZoItm9wJnn9p<e4O`33qh-W6u#ixl{$P4B3YZ at l1<X at EeuuGmot-!$
z`>Hjs%4ja6B#<%yvoMk!)!UQdkE`P3KVrP&SO*WHviRDSt>7qGZGTKS`lpPycE?9t
zYDbe}Jl8hFfJG_;6de&iWIkNMsqGO_((L=UzCdR8ibgkp{dQZeBi#ue7p2DD{K?Q*
zZ0QZ-(R+(yW`&H4g>=NBupJ)l(6L9y4xLn;f%}R}+bN|y37u^FJVT(e;IdnQ^~2|$
zr^LeojSt=O<(uq!je}5Xc6s0)VrYb at LI&N3=)d~BdKx0px?+et2Sc)d5=%u}xx`SE
zu$+IYXH)rp{TGs?ah7SXBzxfZq}&UDFOk}8L#yK at Fjf%>3;xNzWLzAw?k>G(zIg~s
zd?I@&ygl|9As)X-n|;i<x7aDMtqE<FDDqeu_dG)%9Us#jQ_B9$`qNSUNpsU2A{I9h
zilt|m6ELs$CX8rw6hw=&cUnuDf(&*|jl~6rDYRP^8P^WoX%Ba&G438`>P<A2@<-lg
z-GX1+C5>C at SGllk?c<-4QENn~APzg2TOEqVf*4p4yGclQG0vvIH`>VH1CDGAb`HWf
z`;8KZ7Q~pW1Tm&dcHA?HL;C_Ks~#1+jJ;nX{{#URIB0-F_c450-J95I7(ZSP(IwxL
z?=lgyhc9$l;aBG8e|fWddH^2M5>yC*KDuJxpz3ji{V6)F at 5`3;eOc at DyNuRzmcJ1H
zXE?u`d%d5xTxT at q6*9`rU&~4S1Z<yp?{$AT{Wu(6i(>(jrxqR&1IsQPQJh8nxn8LL
zPBs$D@{jJ!b=a%ymI(FvkGs_B-4E%*UB{5ZqWv7<j&{cmw;lrOw3oI124l^fC%Hn+
z7-fa||IB)I9M3uWWr3<z`V};J#c-2}7_TPxhfD)AS$)%vm2Rb;@`a}C!&deQl!1R@
zFP8xUAzw8j at 8P59*cBk0mA=%}&o05qvAL!k7IVnM4*L%u^5`FR$b*J)%%haus2VNH
zN)W)ZeW1y1*Wk0rym=|lEDrL^;(R-+qxz?E((u<!@_oi|8=hY6Gl6pGY17O*?8>AP
zKwiq8v)dLEBP}#Xgi%yN0pvw|N~8tAc=mHkYC#nl!l<P5NrbW4zuT**`Z>EyA=%%m
z`?1FO-neWTJNFtstvxwPae{%%=$kV0POAX}K&D<P`-N^pHPiA620`)VaW+#4qLn?Z
z_t{r1(+s6+_l|U)bf|x<059dw=4$p4OQVtQjaoYMv$9{>)42c6l;X1q{kZiGe>TAg
zHYXA+L*viQ{!RlqHBxjQ!#l6>nga;g4ts4djgg1b2!(Q20~PtAtl(NjXtYBa*TZ;3
zTsYi;<JceCQ9Yld(oxs#&6vkbDbr3AyuP3;t)KnMI at 1g{?0#0njnS#RCO>kI*NyF{
ze!fz6_=Ha>1b9kY_P+hHm$TB5c+qdej{0VQ%f at opR%V at -vBf$rdqJ(9DmLSheQP6_
zX5m(!7QEKx>UdT?d|D8$v#fu0;}xQ4>y at vilaVEaxGrR!s*AoW$k$gglrHlHH!^L)
znv(<W95(9FQ>Rm`Cb2Pt5@!T}JM#{f`kJ-NFGqMg+&Z#b?H-0hjfI*N3Eg&Qu{XmJ
zr307-qYkz7?{=tVgbuW`box?@5$2F6#5mQW*5FAVg&4<iwZozv|3jqe-}ol=Xpe1}
zgV~5F0PfH_ZNvn#lV;)(qD_}!D(!wQ8`fAt8avy6RAf_*YJV|FIt%s at x;4BMi)q4=
zEHX>90=Q_8s)>4$PX)WW)&bu*++X)q8-;3|TooTBlKE+ooli6858IMzk2Tj=m?l`|
zgijUI6sxBRG|*ODW*x=`5|iRhDbCO_8qi*Cvte^Kf6D5tM8Wm{Wth^tKcIo$b0uYA
zN?n(@WC|j}glP;FIW2#aW$MNfCN!xcl*+3~E+^)lqI2dm0$n<)vj_;CKg0wn`MpUX
z(WD$xJ^I&D-PhDI1xd4?Md_<-8(&acz}Vg;P9Mw$DA_As<&!>Ql{|%2h<D;z;%sVV
zHboZ}loyBL`bS08H3m`~*l5TU$Kc{jV$C2Lu at a9nDW2ai<=4JZo!(<5o`F^rQ;3=;
z)56I*H5jIQ9|mDp_LK<$_IaWE)JG9AG`|=5!diAw*|yL6itSxA*!0+u85GCyI24x)
z!ld8NWazYZ?H!H{8 at pjUyqt}T-5>ynx`BH~?8ZT~3kxvIzh>Q-6Im7ArI>v47;8jI
z at C!W9%|kuKFL!K5HC3dViXQb!%FHfv;(s{;#T|x6nYjwOBhKJEPzf at FgZ_2D7{Rz$
z)6}}kCa$t9(YJHrw|{~w*=fV4`s>=D9Uhllr*rWj%Wt<`lH+27`Sg#@x*boWj+b?I
z$D1`O{XFgGgl?|WaUA5YVb3jh1K4zpZp33J>IQ7Hnp8w<!oi02&E?Y;^EuLAaVMIu
zN0b3;2nkkhQB27u{+q;q6ABL9x8o6Kp~FX~EOHKhJo<tV7S~R3shAee#i%6gcoY<?
zLdbR)73W3%-{#u0Z=3!Z8yq<7xF+*4+!gE!Z;bL=>)*TITI7x*YDnacMlhPGkvpc*
zYR&olo2DoB2v*z$TNZ8|)I5XaATGud=468A(_s0~-JtnCWu2G_9~90>3O~`SbhFeK
z$HHZnJ0Sax>H64EJQS3mFMkGG75<H*F8?H=n9iZzIbz~4>T`Lj<K at P@O at Vp)c4ywE
zf_WKr&Y0^XEy1k{uO&wPa2|!grM<LcN68(=vA86eT8#8)_2o)SN-P)Wl{x?}x&o3&
zFnbx)TQGAD6?#?(A2;SCY%7MAAs)-Xj^%^Nc#w5K5DP<XrR*jCH13<DqI<3pMBxdp
z&=GwP at jT?yVGduo|Lca%|9`ome at c?+1w}{4_=!}n2&2W)l5_|2k<AWFD}_GF7Fe@)
zTL20NDib<ER33-1mH)|>&bvcG`4iwglJA*)tu4Qa#RXEGTf#O?%D>ZOxX?s|`uIka
zWor(CUCoK{S%Lyx;~P<TaOO6BS<#WghQ4(BcT{gkhn+M>bCd9o-TEIo-V}X}q8S|t
z0{oF(XPTrHwi>14cK<AQ;4o`&2hFn3L*QZH85XyS&_e+JU}0|JpkNIt?M6e0XKn~#
z1xk$SIaF>0+QyTS2=ULWHD)<iP- at e%KWYZaZZOl?Oo>ozNA>W1eMlnKYZjsKWa`d7
zsd7uzFIUEPU>ivKw)0;b|5f-;CstdAxykLrRwz~{>I73Y7b_9##Et^M{>0?Sey#Sx
zQrm&LEesfPm{5%USdpWTsfI(U+aY8{(0wq76~SgavU`*d`Pxy=uFUnxw%$-<@OCXM
z=`Jlmlz%D<Q~U6rxp`rGvBq`#Xa8Xhn{J|Zx{pSH^Zg(~iMQBIb>B<jz3594&7yPw
zp`!E(lGRGLkc`=<t*`>Wj)E4;K!Wz5{6n at yvAaD$fdJRVN4*ZlO0XjX2N5K!Fm^=O
zimU_m1DjwcE7tk$uqe-I6|sQa;lr&`RG<Y>^&OEtV2!c>P+^S}*@z{F%8TI9BEA|J
z^n+^a^h at Y|bpO&SE_#0zVWN)C9T*ax={3(`*2q{yjGhDUW&g`6Eai`xRa)$dv#;UU
z1CN_TxE_udX8RMRrTmiPNn0uVFWnQbVZ?_EM$hC}S7c(Xz-@=6SkiC@;L>WSH>;HR
zB?~;RWwt6JO{+lZHZ+QzWKaw<EY~e?BjFp80AT=PO8(g4X$#(<ENtPpY)Ogct5o|g
zL~EGh+C_ at Trn{KpxU&y2pTWGh08<_^T8#CN5 at W?WR~D=lJ3Z7~eCGkWz>zHcN(RET
z`=0DiMqA^{Y-f-OXt%QO4F${!1(>?G4Hef*W-GlFRUZ#G$P3v}N{bJN5Sha*wkalR
zAaAkwc)up?i!44KNs`7=q6|yeU^GG-b~y~R;Iqp<Y9>oW=LrbfBZ$O;_Tcg=av~$d
zbE5?9KGqUS3Fs9Hv)u<x9=XIfX{o7+3E3uaH-S6zhVIq?byP1J{;<qw#ke<xNG)0%
zBgLYO77Lk-hK2M_dz3KL7%)2=Tg~`Z at G^E9v~G)w+0m?P_0Txv?%$ef{csGX(Pj0*
z2Rq=3&~{@UiSvMojQp01WN~x$-^MmA3^lv6+FPahv51zA>i<)<{LhQl^2L-7S2hSU
ze;-gqUzD1r7`1iw=e=*8(F+ayBZhE~+Bz$CAT$*?RgizQ%<L{J>@T0#xNirZ0b`+q
zp{SbOn2W9>dynQ)nB=T=l+}emEpEiArIovB9Mpn+fk1l^Whosq(=G3me3t<gdpH>L
zt>Nr*R$2VOi_P3#*8gRlPQhR%|6C%*&u8kFV}z(UR5LoN=l-8C1k%TL;Ip4wh4BkH
zaesba%y2+bE=FnJ)1;$XMS8=_Cb!E->@obxUZZ-dj~vzrw3=swJxOT2gx!n(KQHyA
zUzg74Np&1rx3^&DlzKo{^V0I|i_*Jw%g-G<Zh+MuFD*)M4^Lc at x7PAa_57KKzx#00
z<{r*6Sylp^VeQ@*66xpjf1reFzGKJD6m<JvZrD*;HC8T%>BvWe`9JcQtSmiZs)gzA
zlyms at 2{kll1};pW2|x4g3)83L&k^P0*#8G*EiZGG{CT~v@#ClVL+#WguH at ej_u4Gr
z?zxaG-u<D-^ve;6nByVs4pgQU`MdBo78&#YCFG51U9G2*???y6LIUf2epR>*<{kB(
zO09?3c(u`#SXt|#eS_pna5EMG7?yiP(1qz!DjXW%;qZ9;iJ-S3bmdTRO$8EPvJ~LN
zQvS<?&zGdjRLX~yhuD3YE9Db4dR(ikruDSs<tuvls}R}`tIM<`)z at A5@;uqx)0CHo
zdddaGP&tv9NaY^pPHRsK{i9XQ`8L;dWqo0&$50~IqBTzlPRm4tXG~>TiTpzcrNNri
zWl9QNuCz}e7_Hj-X=`umiDMHcex=beS02jwI_wbbg%pFA*Ei5QyDbK_G2Ut-N~E=?
zG~C4UmBcR`(a0u=^i~H5VZbS|U1P)4Q}w(?6I%v*!T_U#dPr)6Q=wU{G|RQ-SJfkZ
zv?I`$KB<=b;Goc)bDjbU5B0PWcu;h5ZFJlQ!?C0mp@=X;ygnf$Fb-jSb&=wLd=jO6
zWrIjLe7_6wQ2_0=3iwH*j7rc<^?uwaHb$1!m<@S4l>Zdlu%z&VJ-n^ZOnQPzh at 6+j
zM*F4Rdn)vyDets&&^a~eD5mZ)<>tz(dYYz at lhv%_2ZZ-c7MzE2yM$dkezf<rxe{Rx
z^}AKW)0f(`T{V at S!L+RQ)R*@5 at s@!ad!+ZRe$vvA<Hu4#&gW>Fs%097&Z_jZjY`*M
zZ(Un#H#_(eGo|*die279=Fe@{_j<(Pw1C)1HXwm80 at o2TSgQ>3j#MIN1`4``K)Nrq
zC|66)@*;1&;-a3);1!wyu;kESj at 7M*O-8#yq%x+X=-XsP(`Oq|i84wn<x at zPTrtSM
zGy10uc~#$55Wb)=dV*k=t{L(+VJI|PN#S>suh{8^#_$**L+|##f~cA`Xd(JF^=qNk
zJdHX_G?>w$HC53VdS7nE5yjfIHl_?=)I at 8Bb2OKD4r}r}5%IMK3JlXj16O(Ef}UkP
zlnq^sTeQt4EmsPx!RSw;12j4`z})MYMU1U+DFjqU8M`i at QXD_pnN4kC8Gi4^GSm`S
zhVgB0S42^_8!I$eCNM={8H~uD(kPY*3?-&CR;S5<WyVotqisEmm+7F<vzMn#{XFB9
z=HrOT&uyh<yUltLWQHv)AWk9Kknm<#MajnCivgO%OU2CPXEC3llx8 at r9NJ|vp83~u
zB9-$sI2Fd-AmUEC!Ngw_|CEBrunbBW8;}l{7fLi8ZIhrceUo&GFPr`T*K~b*ZCKa8
zsHR7kReYKLc?n0+<twFHPb*|o3kQ3e>xc+VHKqp0yM<Y8^!Jxi+v3ZpuYPLx+OF?G
zd58#bC)&V at A6-CRnpZMYgIO^a*=9N{RZq=~@D-bLurDghrJCxD9t>X7O*lRT_i57P
zrEJ%=Y6s{;|5#+ToRP#OX89mewo6-;q$m+;r9lcR)#zMhu#V%UrUS#pEY1HX2$h(7
zxNj<}=vgxYP(9P?tg?D+3)y4s%;bTwI*a3Al|cvH8YL<Mer%%pK-KC<za%H~7qZiY
z{K-;HQ;p^_xp+oI+(FfBqmE9q;i$t&)=bg1;!9MgQ46J8PI?Ed#FVm^WNID^Z>JK6
zR8LjIz}RM7MoZW at 5`OKvl-hBvhk^qr6Gn=P<LJP*!6alZM+zl;<kI at 1$q|1^kkN8{
zg~Nq<PSza+M;f){i)(=o8pNcTJ%|e<EPXKD^PKpHuF-5>*&Y20|5wIf`<6#>i6gCv
zRHJH78+1hnnQX$*uq>e(*ufN=F{`rBIQprXY|ljkO;79$vqi(J!lE5vx6%rmlfy<W
zMeNYbEUOd$|1n<~kE<YlG+W_{977eREeut9E0XTpP(?fiLlu5D3$=oiuqKb#6lEs?
z3!U5Z)(~a-D#V3q!#K2(gKT4zQ|1E_*(9L!8zXPBa4*#(V+%VOvPL`ErLp=%%x-0e
zv23FyBgT-~ghj>}VvH10q~IP6j%Hqyv1q{^sa)abmDC04&?3{Y=wYr)^guSvSWW$g
z at ImZbG#arGgs>E$XTy|N-wV;+#Bel;K#G-Zx&gzkLWfYt!Pdogv>u0n3FMPLD%1p4
zc_3n#_2|T?`5M`yk*OC!eTVE(l^5A%-m}7z4TiK*glL)L^*li=pwX_Xd)ZrMLMN#2
zyl+*<wd82SypCpbPpKbQb-iszx;9x8RIgddtSj1v*A)m!xTarU<7Iq>cFShgaSL(>
zQ`Cx~F4+}UAvy#b6h2c1aw|iVhQGOCD6r;L+N=k8fGst`2E`~JVNfXDNP~iV?Dk+#
zU_FhRCTW-^*uITvLL=G&|Ec}?qBw|oUPCcb6ZNtpYs+Wui>Hh6gHs!8Kbb#yX?FS-
z3A{z{5AB&97SM|b#i9FFCW*b~Ztqg55IiL2STzch0fvWQMwXPaJeZ-jLNRMi_F5(1
z#%fPfkcJQT80SLV#@a|9zR{RNlg9E07EPBmMppBf*IFDYxIArZa;3)NNJ|VBN0Pqg
z&t(J6+=!zHCA2sa6Uc~}VeC(x(Uvde2T=6hY<Y$W?GIY%%F7`aJ0HWQycR}kURW^T
zp5rP*SS|Fz_)JYi;?P7(5ULj#72Cw6U2P^Erau!5)4vi-e<+B^(5Vwh+opw&nb)kB
zq~-R%0>fFW4cX2NK``!n;K))>n+VTb(qLGBV}<Iy>Q#jlhXJEoMK#b<c!?2FQYfUP
z^jNEyz917xEW1+oQ4h+%L^R33Y}l*HRESWDDMV-?h04Lev~af401cC_MH-M+YsIAz
zr}=cHoAGWenuHx_Sx(E0b4tR68l*3<1S7LF1$%FKr>inUnb*^5F^}XdQ%dJHR7sq_
zu$)MsEd-GO;)Ugk=C;_elO=s1W_ZoI6pp8j7^;*Z3s&@w?A?%Wl5`E`u0-b6AVwh;
z7X0c$Kw8AytOa0hj8eMBz*HK{T}I;5b^$21>MGXy5izlWq`n4o113;d!Q7R+Sg4l6
zLbY5hRB5`w2Ye_fFn4*F<fECJi7FIDs01z3RHuoscZ0dHO2t5I&WfGvV$7|P#sS=z
zyBwGsCKGcr*5zf61!-jNikQ1B=4L>|+ at yp4k+~5enAt(9n4}q5p->RjJA%2n6?2Ey
z1m?CJN@~mv7GMjgRH9whzp)<TX?NC>@)ql1Pl^wW_24kWuX<pn2G at be!gU;v$XKQB
z&UMINaUG=_av|c;3~i(aw$f@<UDS#ua2>B>rCl_Uyyd(@5)%1o%e%O4LlQ{h%1VeT
z8cxynM~{(_0g})yCLzxPKU;Z0<Vx=rT)7vKEA<PqRdA)2s{xOK^+j+Kxo}cYm7zm|
z$Y_5%7l{{=MUjhYk0Q4WS0WPj0-s1TDtEUl?N#JLe3P^-ff+R_Fe9woU`BXU%m^XH
zjCL_*Ebmj&;{6RXwltWLPnJYUYx6ir+LnSDP13dmNgJ4AM1|_K>K(z1+=>}PYXUP`
z6P1*XVhTy=+9Xex4a-5w**7zSjlm0&gKo@=3BZzAF(ftt*j5NY%8smPc$-*}WC%dX
zyap?ZFV#k|qP-r;ij3|^RwT`ytOycj)@xu+I$W?Kny0~vFNTZ;mTcgnEN}mJac2VN
z)^*+Y_W;Za4he!Y9Fjwk50EHR3m3<VB+DBgMN*;`k|ibCO&4T1z>t^)7y_6fX-nor
za<(RET4%M>#Im~Bv1Lcj-o{Q8H%-%4X`R+-y11#G)=t_cjpDD1zb|p!-~ZhE9)Ovl
zM8{4dn}fI9<=nHMbC+lO(OK5(WJZnmoS*}@=>h}aGIQ`ok`jeE%|q3oMF2j}f_roe
z^B1cO#?702ry~6P3uEEXHHZ^9`Mfe$4yp5`Au59al>?^Fd7mK at h>&J1Jsw8<PpHf=
z(;{8(13{)W at WZKLN{3qZ(tvUic*YwHD$7#S+6v~d>j4j%2h7_|xcRwt9&k@)oyZ%{
z5)YVi5(XNB841A!80QG8b2T$)-<;9)u$sgJCR9)bYO6w4YBGcwlp|+AjFGa1GMba6
z1M+}#N~z(7MH$i$z2(e5#$sA=2 at MNYVJHjf&|1uE5CIT~kf&#)<|e|_6mh|WH~B)h
z#c^BYF5tmytA;V7;dnQGNY`CJ37gI~;BjKtx(hjl2&v*`whhHiUcCSkkQN3^9g`OF
z2TpM(gXM+rQgC=dT7(nBh!{fy*J~I+t?0GO*J{RsfriPPi2yfl$-pgKWW^okF&Qy6
zHNP$(BRK|ATyPd9*yv#$VkkL99&hf_c*@eD)`Q)qJ$NZl*ACUL2Y21m1Dq;yFp&s-
zm=<u1%eA*3ugIi~{A*xRYC9&iX7IBVP;d>Crt-8guV(vrkSd;66*c|ocr{_p2-G-)
z=*k;i%VYL(rOi@(owzc4J+4fKwT>$_`d8%2btC9wB-khwK;xc`!n2H6SX6KxEba%`
z=n2noZBkz$LzWL;0l6HOtB>-KNknr<#e}Al_<_lW5%0a0 at ZTsp%Qy!XL2@%K`1)3P
zcN98TA=6a?3h^9#Cg><7iaJLIEl9^2Bpj7`4H$fR4X6_blt2{Fl*5IkPvWzTb73vb
zhZZugVNfcu8=qz5!lESP!cq>M;9XdVWgjDxtEBGfsoUWu->*89M^*MH@=HN65Dqr8
zY at uNaJt*vdTJw0yG;_{#6taBT9^~`$8Lbc$4z$@8otd%0d?X4#^3HPh1HeWzEhXUz
z)~Sm6JsN$-2jbv?sgiSw-I9T_H+fIa9SESWC9`RcUC_TL%eV^!<-a)0ssh(h6uN50
zHeq~3jdz2+7$w4-a_HxjL(M4zi7ctbcxZ8wK*ZGsw<ej*m}>q_pATXRyydUvHFnET
zgXl-c+~D|p8kTH;#f<<%aXQzJtS_ at NW?&SSU24S{$Zk at jL|N#4X`+bKjTUnjzFQ;I
z>NlDjQioj??L%WtNYeuuW?8S^#*Mo&kR?^+4iwBoqQl`4z(7vA9dtExqLf_+jM`Ar
z9gUo?z7A!X+-O{@LIkiGtFaeHBQxVFHXy>+l;uDd5tI#O(tQ*Gzrb at af+*c}m}tzK
z3XFk}Rc2~aG}5%T`Wtab=V!h&Y7h^5Gog8Fy3q7?Ip5>U44W^*+f4#?oiCH`X7iAC
zmaF2+*r230aOF%yslCH}>q$UuDieXqP`EBdH*>r&6jXA;%>pIWGzf=eDio8JLszL#
z=5!&x8!J=cCznw)47Il$UlZf47MxLBZVjk{r)U(s;nM4qQ?7Zz(Vxx$&*q<i4zc0z
zTK~ixxYR${Wc~@?5$4;yvIMS<`6t6#I;FspE(~fK(-09c6~h71;B08}Pc(u=_t<M{
zj=HeYbHqrOBbZ9-<p^=<#w^DI0xv*Jfr$fA^PY_WW3*3-ympWSDO~^uBl|H4e8Gr|
zdx<?5u#z#Z=zMa at 9RgnpS;Azlcodoi$$x%RICw2WP4bmR!!u-7I@$bhWtBxjo at o}3
zGA2H*oFyQ|6((%X<4$tUJhj}|1|GK>Q^py8JL6QZ8NMX=vK!5GQOx-)R(`N&l|#0d
z6)`<xMW#o at iZ&T%Q_<#MTjp3KB at 2}WMZG>tw#UD=OtiiA39TOgnwVUK042`9mb&nH
zDug<fWHZ7jIkcenuLYCk%zeb5{E|*->36%SBDU^zyG29<*o_J8x|Xf4>vmg^x{=#W
z7ls3~)GkZs{OTk~wJe>v-9YJkcKH&~I&&mJf%mf^T(1(B9bM;Vho-Zgj!v-x4XEk0
z^DFt;)<ai|s|UMt9OHd!>%lA11n;7N6HdvQ)T!fIuAQGP=ZRp at rbE^TgS_?338aE`
zW9Hn5v;>3Hc06m%U`V7st;1K~S&IoXQi>_hQpM<n4){~?EGj-_(k?=Dbv-}Zw9VIv
z4KvsCvy)-1V?&MJR7 at KE^|IkcBj{r!2$c$=cbFWlL+BrWMxLFe6*5OsiXw1mW%IM8
z>1Y5KG4->vB|DW2K^!h&=23viF7n8a5 at C{L0mYs9*~(aiX-Y1PZ{<!YxeXG<Ryj?{
z^(KmQ4!W+FO`_O*0?Ta*Lij25vVm8gEZW0?BmiM}oQ?H)VzJdaC!25M;%hl48*Q&V
zagUP?rM#1kWsyec?N4J at xAbQ|wnvY_33{B5Z50wM<@2u#OpOp<{AIAc+r=@Uu<*n3
z4V98MpVk_-B`Wc?{7;1}z;&ys<HO95++qnOYbSg3+T*Iy^ZjGjq$OtVbdkw^$O0Jg
z{<&CgWsXU<!h5Vcm#9X#UXr5aubgKJ49^vQPz8AQtE94`+<~BgV<t}?{NuoR(0pIo
zcZ<i8ix1B^*zn==459FTH4@~1GfWp6Yn5=&9e~%WN|%AKO>>2JyKZF+SiOc~^JaIG
z|N62|5arx1YrV!C6FmHFs|V_-2R7Moxf+xp2x`NF#9?Nv2r7K91Br2Ma7jaUoLbM@
z<PnX!SKT(YGDIF5HQ at T}rM!Pa7psalyHB28_vD%GlPyBkySn$jm2X}5<lELg`S$LU
zNrOiEj?Dq=(pv)oOY4&-+kD9ao0O7g6KU;&9ogid?|I4+_YKN&!dUWjr)wc}yX*?~
zbqUwXzNGDpdnX7Zx4GO-i*colVeCwmApf3BCUY(GPS5iZ%g*{)29BlUm%~f?S(=M?
zY6bBK(;2a)@^kUi1DD3aqaXkB|9eWy;$tS7#JRmvqBS5#fAPy-dCE$;2BS+;<$<HW
z{Pb$(UBG93tcGyC&DW!`Qn|2s73s>ZBxp*FWuQ5ewM=}i9q+JZoG at p+X(j&3Ue+|<
zmffLv@)>C`_k{WF!n5K?Wj>MPRJJUt!rf95IU7d_6X)_bqd<)9-e=Va6}-Yg3nvQW
zH9_IW^;RVdKVaoHR4nfg!{k7C$z>0cWAM7_B6YfF4c-TBUH$X+H!QqcZ`~}S(9-`N
zm09?(It6wx0u;buYqg}P?o5{6DKp`kr2=B~oK-=MD5d7ejT%`4Vy4Rny&!_(jX|_2
zC9t~YeHTO$Z3&23tr=SjVs=9iGrb_buOEwlfgl$CZi2%;0CNF4__JZUSE)}2Yx&~O
zJF=Sn at 4LhPi+Wj6FpQ+73-47I#;ss=*u^g4eXa=~b{q(Xare-~c#!DuuI4sX%_6 at a
zQ5)n>Fg6ro{fKtGAt;3p*$W~If2t*RTwbfzCvB{|fhl2@{10Uqp)p$!XXZ9%!VqS{
zKm?g1a(7<PAj=tDeq5JEYy4VWYpw+|m%;wWSk9?(VqXSeh-=t)W|w%I?fB at CDF?~E
zwZkQO18at%xzjiu%7nCX_COHCX9Z56Sxq+{rA+KfyWT at LOPh-ivFwuP89!pGXWjAr
zwkrlOq#vkuw;PN3aDv_-Q*@0pg7;<%45Sna9~3%+{9o(34 at kLpA5g(^--NHYN7zG%
zl9RLqUdX)!@x1W7n$rS>T#EE4oBu?H&32JehNY}iJ6Qk+OgHpHxc-Xua at JEyhXGS}
z3Hk>S!Xc`m9F=-hIKt9h`CcQ=WccLIkXso#>ek|_#b{IkqHxS7=M00OmKo~N!WWE}
zSm7zi*!Zc04qdS7+gu7g-4qdCTOQJ&R86~O&6OUI=rpI-raOTq$0GkxDP*`pnGn>4
zvNNelGfu&_&8h8xzA#5jvH%=%U_FTA<1gzFhA69(A)=xDsenPCo!<f{cg$&bo`brN
zuRUVZIlNjqf^(QCsAR2+b?E9PwBAW`VvOgtpVP`0enN=I=U=?86Glgy<bEOD-)~4W
zkR-mcE-#vZgqTaiw<J<-7vSM)b!8g?juWW~;p0SvdtE6#{XX>|3itwOekU`%0#0L`
z#;YL!Rx04{kqRq(R1FAc at tX?&UDslK6J`mBk~fi*39EIpBCRyKM~9a)v6T%#tINcf
zrruO1Tlk-D{JLh8RFB`pDqQpLgOaB3ZM6<)0Ue4mlr190%zsq6$AJb6(k6YK>X~8$
za#F&a)g$WH!&2zG*V^iC_ZDp6gA{&J5J{R%rl<j$0nOTi4fU95h(U<gljo-MUlG~L
zN`T7QDtwn=YJhd!N_%>;0Za(GEa{=;SA+fwiHs~E3Zsrq!C8Cm(h&xgNYAz+-BKlh
zWf at BvbiRz$^aG$pMv!>d*YZCrQaUWXWPrLVq(qF{P_};Eyi4R6fsszQBEY3FhA~+|
z5>3VXcc9c%D^votQYE&q9*{(E(Zt$EVS+Oe)8j=LU~DKvd(UMC(vr*(G_=hsQ+1us
ze=Njf${e9VKaG*_AezH8hE#~>Jdi8xz+q?JFB8PVj`~ud<<8-y6b~7j({yFl2xk(T
z3G^o8#5FMI?-~ucVp#E;WHSlgfy{vQq*Fm!{+Nn7)_ff8?=bzp{@7T8Hb0{)(Z^k}
z<53TQmg))vALay(PW-7K=i%I;Fo=KpM|Guq{&?ZzYC8Yub!-Z;p$;4YlUf`A(pXDm
zk#qclX{6u#5o)KW9VA-oXF>u*2jr)W9fVzx>(j;#VfF~1F(E}Zm<cI8%RtgNd~ht#
ztNj_PWn`sD{H{=06mE0+-D>8I=F$eGNxMxk;@}}OQobEx**G%nM7}p6MiPfqx}H!g
z98vy$#|<d}rZ4}U1DWpZ%GZF#-R?7Sgk19EU9eda$vRRSXFwPa3QVVwCyj7T4H(mK
zV3d~#h8nTUPe?n&7DZWA3&Xcslo;eU2Zf&%@e03TB%JKKg=u_foMW*0O=5+x at C#P*
z-I)wLbp3G5*jnV-oEr$jj7?sL-WiOt-Kfb4p at w4;q3vbFL at XOR`eN`5fm-%ZI9duJ
zZSLsPtKl<e%=iuP1Fa$AvtbKgkd(OHMY^#(celi<mC$Mwm47i%5p`m$087#|7=)6F
zz6w92!5Phv1<E;0JJ9+>S22R=l{5|u^RwO1iTE_^#wEgAcgV6oZz%Byr#RMbTwN97
zTjXnpHis&T(=)7PJqz}<n at s*&vna}L9GvO)6Msy*&ZF?oK<-7Z at Oh0!Qe!)r6Rl&D
zQt_7(LoJ0u0XM6p$T;A0L~iEQLf0_9!|foK*@%a6hO_Y(NvGQuROzWO{(Rs{AfaML
zWzmD!C1?wu5DdFCL~NU>HFL{8C;Log=6mrgtq?rxRyNV1@{J%sp0{rSgNr8!HC?|_
z<vQ_~4b4n5DXRsxbZTOb&ru)^N^o%$jV2C*!Y>L20hfzMsU&X|hijD at w{U5ZtG4~;
zVvcOnQ%=>1EnQ at qtMFT@E+;S3B||Q+miK4wE&M&b&0p%$z8f~fBRQwv<7=oBFxy9i
z2vR9IgR52eJ8ETZ#IO23>gND&+4aQnVd>aXpSsODE)ZV}XtRs(wlGXJcE{ts$hh_P
zqwt0?y#z5+gXHG$F|j$Bik=QL`9BH6frRh6V{~1aiQ(h|ZRoIUFo!RQP?~*G^bkD2
zPAQv+24$K%2QVF|&05)PoGJXW!?4C`o6icL^eBfjSpq>}ngD|gMoKr1nBmV&iARi?
zA-f<h+pbwYuAp|T<bK~NQG`~K!xtv+0II%88=K~Y$(RX2S4D$xshyaT(fY5R(GTXU
z8=>1HI0TEt8dShv{?Q&v;_0qM at lo`K(Nw4Jm<CB{8d|at1c at yQzoK@&X1 at Bd9%#}`
z(kt at SFJxGU=+#RfnR^%uszQeyT6y3pKh8H0M0_UeoYQH-VZ{Aa0|8H2iwA5MOxAmH
z*as7fQi!M{cO>muWRpdEcru$7V3qy}Qo67aG at f_r8$ZHsAvu%g3Jq;twFHV)6w&b1
ze0d0JOX4 at 7M24sEkIdVK3-oxTglj91nLHK3*(MwfvyrRdfkiptM|&P(l$uW9XIww3
zaVL$lLT?=baR`4{VuI4KlZrJmmEW}0(!J>Q%#ldppHp=~;n#$m!f)!Yt?s1kVIP#J
z-d%TR?vm2fr3)0$(40taiWEsmykJBv;Fxtaqq1k5KMWKukP?Hp^1qicmnw25A<P_+
zPw^$Wc}PQgod8Z3diLxK-S>9w-qRj~&m3`}n<GRc*&_~C at C199_lwdqkfN;sw;BX&
ztny{(^O~s}chBlY)fz6_3Ovb8cK-Po{4tfV)sok&1VSHBs-IW1E=$VUfu!<x**g9N
zAA}jN4wb5n3!<cOu54Yi4A438h~#>3HUuRO^5wwwcyE~&o#w|%d7oeNA_1rFWUs|w
z<XPvr=yH`FVGZmc_O+auqIGY2r!eQdZb|O2Z_e6Il|gL08nu+2;$k(^ieS(9|Dw<N
z`CM?KMK9**cm0B1uOPKXE?u0&$%U7`1ws}6f&S8NfJd!%-MKZkE;n#SPY3N=sC&;w
zx>1^6#y}F2Df}n32JL!uYDS at x){mh*vu+VrVjeBR37=2aJIhBh*02~I+orqR{PRya
zk3yu=lj|^C4{7`9MbFY+#&!vdxk)(X_iSr`qAXet;wH;^!A1VLkZFkUoqBi+ at j%!W
zXr=`uMj?(*7a+gTjkd&}o{h`dqro|OKZz*7WM+>r(0=w$%9Upfl<8kFj450inScIC
zrQ5O`g0s3hOe at IOn^M+NO5g+eXR;>eU%hC0Ik`dBPvtCgM2g~1q)2QjpYZz1Bmuj!
z*G9)zmN3`0DXBlBwoR#h-P_LpRb;|3&l?eFd<(g>Z*-`Uh-+6ayoI3Z1D>XM`dDti
zjO&JG2QK7eQv)vN;MNU at 4X|jL!oQZ7!8UsA-ECcumj~vfP<xwU&d6RT`q(mL_*g0i
z9T9e#!YV3cC}p!pC~aF+vbaj6B!hyxR31WA#iKHmzR~PFMKGu|lr&z(%4#)b76g=J
znrQ<V0LX2j1ePR8fhQ`SQ6xJq)2t=bc)352(HbmdXTiJDIC^&Ihe4T52du|#QjVBW
z10I^!K6vv^oO_tSWbPrgop(%GMtzEcet#zy`eYUF`8SX~0%iz2=6nHV$`}jl2-*8R
z(!~JcX~l#AeBK at mu#L~wlQR8BI6LAnAP7rr9Uh|EK!O2V&&?;U4Fl{X)&UOmj_WG@
zm%)sNQwTV?Y2=5|_kRMZ^O*g62tBa$=0jK(5TAj1mJc+&0?p+zKuLas#7oG(zE5lC
zd;sC*0DucFA;I)Jrng1+)J at Iie>OwaICKsRY^>hmuLKVRCiQTjW3#!!?EZ`;mVBAj
zYfR7nk_<d*i_ZeMz#63XR#RKH4~>WMTc{AW?hAmOyTO(CMcoly`pg;D^930XUalUY
z?2BykFz>%x)mUB=uAjB4NkeJNG3Tgfj;MjvC+C=Wev2PR+P8=s#>JKR<qaE1+wZo>
z34c8URIWfeJHJDiGVe?Fg*Jo2zZZV<-y3E^j$75+Pn0u9?_!bkS2%5eby-`$6^~hk
zr<cb9|KE8VvB+tQCX*L0-~SvE^&gF9v~N5RA2CN*>0$}u(^u>^lYB?!+gGnWW5xt~
z^732W^-In>xy7`XpJ-v~8s=k|v3MdZd|K^4FqQvq*%==xd<tJW+Z%(vq|TlttcvF3
z(<6xS&xh&d3+bg^evq>IeU at K24Zjv<j)-{-;9nz;mE{{P`b&F--&XG?vY^%0{KI6Z
zE8&Na1I0d0%*7R%Y$)sgr<Zq%L1{_}1Dfa!IP94F2q;M%5S~f)RimJUEnX_}<yET@
z4p24(OYTrEjxLoLKxBD+x?vo&l&Bvz{;OvI&>Z3Z6b{pgN&ExGb*_~O26dSuF!O<x
zfB*w at z?oMtRQ#!M&f`4D|L+q6yU56ePYz!TpY&9Dd61aKml%kDg`;8kQWMIJHeL?q
z=9#=2h=2c^bucQM|8*>+E5zr<M!5v%(%Vvbx*Tqm*kfpyBP~wac4bHBI81SXBT(F@
zXh7Un{uLe4vqvKLMX;^N727h~4`B>A#+M_K6S{PN?HJW^QD$*lDU{~b|DvKoYxlSq
z at 6#r(kQ0@|QqgpCk;&3{pIr2!iwwu5VaFq$>qAmS66a;gMiW-ZP0^Ib^L8S08Av=_
z<?)Bcm<;qOeChQ_sUv;NEGYaNaU8o4iet*e(R>k>*iLB at ZDDybJ~LOIu%#x-a%JLM
zq^?;%M>&<qat>_B*^(2b?P4n}rJjtxSsB{BD4IBo!VcHp`5QTN2#RW7pJ&`5+(kQD
z94<LgE-ItvYehPG#uw|Utbo;;zMbwJ;($)Dg$_1h#KA`JtZ5qM!a$n<1yL%T?J$uL
zuRf&|xqZFDK0s99<P6uJ5M=&A0RVUEkPEZg0bS%wtH|b1F(~n&n4OAza3Z3e^Cgb6
zMm3Xr-9dU*bq!Jnn@;;FmL~iQBkIohrT6^Q7i3Rh_?_|SLU{s*0CY at vay>jnlLEQq
zP*I)`uH9fqWp07t!LiLs47*Ygj0#4(o^rvaF-_UQLRKBj+qwb<DO470s9QNg$aA9d
z50)FITT9`P?g6Mw;XjK(sNt6UQH{iaD^OThV3W0wO$zK-SHRZ#b6T};AzD{p+*%k&
z3hZB3fV>Pa3?>B*uPd<I3JfI$?p;?PvI69%+$dhuL{BnKjq(=W!&XXvh?OL*xIZ?<
zqQ!S`11zy$z9FnH3`$}4He!!;yp_q)q!1iUNbC+ulqZO+_z)$X>#-BEl&!hX^sqIx
zvKz4VgkmWeMuq#>dQw9w0Of?Os-OeM()Qf5vnoqACdAH at dE}L~TYFawBI=1xsAqyd
z6_4oL3O at 7##A<^d_KKAzvPa-K1{Uq^W#-*t<}hN5g+g?v6Jh2_;c1r*l~c+mX+gc9
zxF(`0jdd!9s}XR}jHtK-e=+{nYjg1lal0ucDb|VjzJ<B?Cq4u_&VkJ`iVD50s=_e9
z6yqt=m8_BEZo3Qab6lVgqN2vEWi8v4QR6!z_hj!yV^YweXzQlUvIVe9F<}Nx9dDPQ
z+v0tc<?%5#rtDy3 at 3>Un&3DC2?lD)W%UAm!!?-plMOVah(?yZ<gkm-(YFtz0n>b2w
zZu7l`;#jdzC=|Q at ZPH~nxi1ul2lRe`2P0uFQ!I`a1HBhvreY3$T at 5&Gm#>A~TiT0$
z;HkG&33wn8gR^-!VAd*k)4<?Oj9Dqdtzc)9J5t);OeJrg$G_QxfpF#C5C)reCO7!1
zo7f}MZ2 at +2H&$u8m}^-7#08)dBfDK6)V`??UPvH_%X`nrI&LX#Lt92S$<dh59c-~p
zQOUMw?+1jm7eDG5AexY~9PK^2<q0(0-lMti;FAeO*g-vEZ?ZI!TXtBP<12}o(v&90
zXtLX*>#(njp-b^$-|&!YIGZ%w2e$7e!#51J at C5`2ix!`ZiVrbX$5?JuwqiLNI0~ds
zmG{DRNJC01rv<jhs|A-|;mx-=DoWa()}<Q&z2PWKO_lZ-w=-PjNDAM?0QQz5!y2OB
zk1h(0u9l;tqwjp`1L>F~mhTHSu*jn;A4MN97o>{@@#km*!#}z(?`sw at v@+LJ<l|>%
zj(3S(lM*wIk=<@$!P)S;rb at e01Ro8~qCj+rG+!_fc>F6$Wjdrqdy)U5$J!2ihs|QQ
z9sKad;GSNt25URWY`X?V^RY!&sIcS%OVWJeJ?QWiTX0mIDs9W-<nYaBr;Czb_C)=W
zY+8AToSk05K@~p40f9IZi24xr(^{m at No~aea1?^=zSnUSg7MAF0da+?)cl-&OYo{R
z9;I>g#xqAi>NsGQC*0bT0kkjQrTz~F0Itx3Ww6O7L1CPEg=XVY?VPjEcSVF46d;|V
zbjH9Lz&<!ODwPGpyqLRWRk8dmnxb!f-Z<jR55 at WNc)XgSCANK*C#KwN=PqjTnPl at o
zEJbfFpsPjUt{+IXch1p*ZKTjNfecr-FurA4mL}!UGS+diPBKbh=^Z1VL at DF4K5R>G
zdRtSWZes{JBi}~*MY9GpZt7M3=3n3#)wlj3)kSxDTbJuOvu at xHRBee76ZI^Z5h{Jc
z34H0jr4l?_20J&$f5T+ at mUYtZ-hNN|HvU^C@!zGtPU6c`rCXx%@zTvAJ8esR?Y|%m
zY`^psC0wJjd|epMm_tW=0rt3O4c17AHO8f-ptk<p0BcaIk2R<UYba!aQ`fQv)a(f-
z0K-DNqGKI~kW$)Sl!_XUdmI0pj=_&VZqxhH`{m+P{5|@hNc at sLD^5kFsC0fR&ZdoY
zg+Q*i<B`9x!NRlPHrko;h+_n};`f6&m#`=^fM?64V}bu~S|Tg$vH(7>p*<F4 at ml45
z%xw6>NYnchV?*&E3PPH83P(z{Fp|=DU~mS at NcFxFNk1>d&y`A2S<(#wPAWo%#<_J0
zkEr~bx$+(ft^?LX_HsNECAEWK)}pr3hhcs5{ZR9WryMD-rb<!q=ihHtYrp>M at pC-`
zB!>fypz*diR047weYl4}2&nlnOLG(NZem0-$K%?;jw_^O*S3$8qN71+FNLr}-$-xK
zw_(b}^;@2Kvdm|Zj;?<H|M*OHwd^n6`P7>!RP;@d7tP};xS)DM4^gJT3^=qnu3og=
z+=@#xqrsfb0j;v*!X}O=Up0ztnUq)!rLGD3UGdJjc%&g8c|R^Npi0+{0R0H#@Q%Le
zFXvs43vC8#G`UjRO}sbRQL1zbrLZlUFty3|lcYE?kSozPbIkcx_@!t!BsMHdcS<4p
z7Nc!4y4V&`p(vFJQ5+}nnOg_^9(`i^xV&D5zAyfQ*0YR9`<)w1-SPQ2vmEUgyK0bR
z#VuG- at D8e!SEdD(iANS>@&(^EbJF8cgL#KAumj6FE{}g)7#Eg^5^#!Lhx597fSccC
zwr}bZc%tJyzR~#dobg1wO58-#Ba6iUu;gu?Rm1q71(D;@Tjx+hByor>Ou5OLk1Whn
zen?Y~c$f3#{qYdrqVff>;d8N$muA46g)r$s#;kqvw+<~p)=8amfHwlsg-h`SqcD2Q
z%d{7}h1mVZzq at Vp8f&AxFB(_ZYC9^jkIr%UKAZ0L0(9j5Qi%qQ=vv-Rup at 5U4Ij#o
zY8oxf9}7(lsBGTX`|Mj12}~}&^cL%7%0K6Jl7_>T at _wR*$!I?(Kim$|Zw8uM)bs&q
z!Q0=<_ito+^7IU at jGY72=k3o%B`F;}l|hDmsO$k1wuYly`8XaH#1Mk&$D&!0XhIy}
z1j!ys35aK50`XfwD^F4nR{F~KA(pZYJOY8l6MqUu0#`)XVi!1-z(JoVz#EEQGoQFq
zNJf$PYvNHz5z?*oE)188fMxP*q?-b6g#sldJ at F=pbFaacAucLfV8=r|ddEYT%HsrK
zbA-6p*ow~eP5R=Ps+IS{V3!p^;s1d-IuI}T&!XU*#iL7<fG-he5_X6q2}OCcPArxT
z65w-!B-4Bo!5_<JpcGa1^N}uwIfpc01SHMDLjr79RFs}~Dp!SeK(XtW%QK`eqZ^0Z
zA<vZG-zwic_0ZTbmp3DXERUKi?K6xd{g-cLKoV6cRV6M*!39qQfhl_{EzfiiWDl04
z$SmI7yId}|aWNUDf5W)P6`mQv6f}UAG-y!ZCTb~mQ0QNbpo!^<L3C#vN~w-Vo4KZe
z_%OU_dDr=PWzM^;VkMl8*F-ld)>BXMf%pzV`rwqF48j-StUD5%GHzu|%IWBac~qV&
zO+f+gId7-qozYakd&Ih$9`|Ux$8%=!#Cp&9Yjlq!v*uU#I!98YfVgV2VtoJ}7QBCM
z07kbGKFf|wM0*~dD(@&wI!D3yVp3vYp8v3^3rm|Dk3#7+VWTL9ZZHmz$;09}{ebeA
zfZF8Vkr_rk8QBVlaS~T?=D{)h7Q?tUT-mYtBjf at oVbfm&@!|V|w?&(bQC$-e=20Yf
zkQ6!Aw+J^S?ZdALH_=g$BEA at n@v7 at nBGG7`$!HHrFA?Hq1h`w=?PEcE^u#|DLZ8T%
z?eby+l)I%)-F<?z$f1nqV<2P9`9b{XcAWrW$x;ED5c)96F8JOC`V at R4Gd5Bk%${5m
zOvxEZN4 at co$ANc5{~ny`j)VKlrnubjcPj@^k%vS#{7sl&&OS{82L2Bdd!JSKs-(7C
z^~1^*ok)#NOA{N4<)iK7`X)<ch;|@=_)1VPnncI(b at Ws=2gKLWE^))oXu=dA(-i|?
zcDD<1cY`(F3CT&2iwoBm<ZkZ~RU~`8sN(+iMKWJqklW>$J%HLneu3yjwGTiLwFbbc
z9stpRUvB`xYZpC-QTy0^hM434cJ%ZP`+U87 at 1h5Xql+G+AEqwnsHX+aE=92xIbXLF
zh3^81NN5C$!bo_c__%V#U~v85Rq!{_X<j%Hb{JUVnCLUjfcQ*UuT1u;G at Rg6CZ#RX
zsv`)LjAmC^IcIS)ny?(TD=F8|sz|upRU)_UF3~Do9Ft~Dho_Vfwq5EIUxjh9L4-cj
z!s}I*X*_eJ(?WENR?xqGoj{m?@Ozc$b%LTGuM2j?crLgsP8W3hj9z0lxd%p>Tm`kx
z;A+4x`+UTokv;QWFtC&lz{)LnU%NW-UZNU4AF>CWO~!egRhhJSlSHOS98pHwd5`<>
zk<#rV;bhza$2|{W5kK2 at d;0V_{BGw5fuR^@4i`zhHyOXfg(FnzDc!C2wOr9>QPGT&
z-s)_ROq+`X2m+$p-~TL;fQDfH|LyN5EHDFZd50b1SIuE`eY%wYnM}u?$N7~1do#hk
z{NHQR9sm2POvQKk|8z7eH at +NaS_qy`?HA?O at tN9q%bXlJo6YHS?aXzTM~IK$%%q#m
zh)VDANc(I&qfSd7G6xl1yt;Zt^WSjvx at iKUvY&IQiXb?AguDp&5*2Y=tp~hO+;Se`
zpFlNRXwl7tOiQkc at j<QC(X_jI>AqF6!};Lw{;qj~`P~p at KAL=x34J14km)<2H~F)?
znc~^x6tfz{9zBjJIa((tX6-hVlgS=+PGGWLoqxR?(>>_QM1sU#6N$BZ702|?4M4AL
z`+y|8l_YDcoYyq+ThgTGpPN^&uq{QNP?w}B|H6U}d>6S|q$$CVRt1vvasC@?Y+>MQ
zrLC4L9GtsFk`zQ+^FNg{^(dwB%Ku|}^YYy0;?{s!$?U-3(D2A;e$&|IEd|7W%`%E0
z3h&A=`|6IbV_jsBuCU-0>Avf|y75}^&>XoRn$^5a5Yep7_io(dH-y*i at padKbvU?g
zt=IOy`l^6gGyGSr`>F+car?C(@Q!TodXcQ~Il2CXAnU0LCB;Yi9}Bx{FIPD{bilC_
z3WPP6in!U<#_W~kGYa*L#dQ);{W)3AdF^Iv&)L4WM!jWJvMX2A!HTeyaNU#y?e&yn
zb6v)>b$)jcfBwA;!tKy4d`1J>mF&#@$*{ZZZ&kZ~ye#D4qFns{w9Lac2X+t_J%P6f
z(O4MF%GHP2X?8`=aCBY3$-ZU3k?#j2QMM0{0{=^!_>Qrtgs)8a{d{02*)WtYd3XM!
z9Tt)kp8P%okPilX7RRx<T$^(CXO7t+u(n!|MYuT@*74Bo9w at U|PP@;B^bt}SO>Gex
z>RX-5el<1{NnmWTu6><^ReWyCDgCoMpUSrIkL56Hmi9u-{>lSvMbaW?ci0I+s7-S$
zK-8*le)!Tu{)Ldep7=$9)<uMIi?am?Gcn0oP#eaP9A#Z*;<qcQh<B1pv=FZ!pWB?x
z1R>bSDoD=iHFKqLXqyRXk_9|G%NS<6E5)+%m;=3_=M14X8>Q5*Rj}@@bF1LirBDhO
zSaCg-|DrY->HYyN4|e~fjyu&?%aQ3!jy2%1%t8rSfQr~OriBNrd(=@Ms_TZS^Le!m
zLdOzBxwM)-gT_JbJ!M(u_ljko>M5Ij#j<QVW$ii5lPq<hh{*s at fPzUkN!<&Jtf-DS
zc0-E4<>_|~FO&js$4V)N*DmYqCmQ_9m;d<k9BY&*aD~&SAiVW7;CiyGFxExcZ`YFW
z54Nl;+b7JjVk$u#g>k}^8K at wC5|l$O at Eth})3<QU at _QDyv3gXYg<m8j?ty%U>5M<L
zg68-RD`U%lVaN_)5ZNda!Bf<8B%tLm;+6*GjH&@oCBRYRcDSkz>jy<}i%N!a21O_<
ziBG7KkV?m}_Lt1u7l@=!xspuNsw9M3Uov}Nz#?IAW^Eb<wcrc}vgNY$_a~#kXO>Jw
z)ROHC$bd at v)ea^bA6t=>w$CPe(6aH8P6{YU?ShfpFtd=)u7>$=6_s^HDwwxZc{4&7
zrA2p|5Vbd|qh|&Cs*|pE+=FoESQ2gR at Poq8TF{K0kZS=-#@1`~G-gXCv at hE}AHg6v
z!@wpT>Cf2{v7ef9{3JIt!^wQd-7pRX!5csa`!Zdp{IDuA<EB~Eji)F05?0**qHG*7
zFhi3Fy*Zl=LiQ`TF0DN}&CKl&QP?mtH-mGx;R<Bftw7X^wiwV)7;k1T$w0hWB}@GB
zK^M^Gnh_VNCd&o`nnAv~8JN2b-yoyGuu53X at Ds*k*36hn(##f`$r!i*YD8qWa^zP;
z(uyCFx(UL&18e!VVBnsBW}|^a!PpyuF<l)9w%iwNp(`k=uJ}RrvP^7n+II?P8Qv76
z5PL;js;gnH9KcxzJv$_5V8}twcR at IQ+?wPk1YRLwi-&$poP%v~pKFB{_+E^eK4 at 39
z<doUwN<eX>=9zG0MIg0`@T18!ia1j9%##}8yCVG9aBO3mx^Z|R`;q^SY$j`Gx6@}y
zER47!IC+yBT9q2nGn4d)8Aurre`}ld+)ER4VIqs<y4Rfln-;V=Mr#FgiNq!ij98B`
zJ<LlW$tdII$Q(G`>As7OXz-=F_(_~p2?({Zi8K~lZI&r&ce(wDAXohB44H_e;7)a8
zC3d(ULQK6YxSvf_TS}`fq*oWyt7_5|)XQCpceLDRRwNox_9I8}idGBn6m27692LMf
zIqu2sa6k3|k9)HAeG~0}$Vlu(Ipp1~{Z^VNf0N<aA6pa%Cs4^@<HS_{b8gG7mrBD?
zvRBYFD5Nq)&;Ag9dbT&Kq1zXNfA<G+-sar4R%z)hC>Q*0??jf~wBK0FY*m at FRio0<
zH&_xa{puxY5stMv16%b1KegeBev>F9IqNB8qUGD-yY=N59IchF+YroaDL7duHDtrq
zK$-cZt{W(>2Zgfv3)(&<(MY#)x(~C-$Rr*L4U|-kpO6M!X^(kpvbTT$S515~b>MF1
z^9Siim~{jZNMY|$Std%}*+eJgUkc?%1tq9q^bolNT>+_xjqGR>k+oyi6!>`Mpn-VK
zZ1+BdPU|0nMm=;s2R2m<`VK!z(=mWg8H+(TqJ>Z`j2LR7jL at hNgDCs}LjVY$&%eVB
z9 at DG6#%@TIb(q#5K(BceMtEV*MpM>F==uh at d;?BX(ho!xkRpX4!`uLC!1|LPBpseK
zF`xg#Z0gfk$5d;3j8WE{J9(VuIMc96hkF6KffynrC*B#z=tN$a#A&QJ9vD;`gGQb>
zury~-at at b~&TR+caBQ`aGmCP344+cUTJ;iV*42Z6uT+oynOe%GdWmD}>OtdIsy9SE
z#4rnFvL95($py2FUiOYH16WZ`0PJ33K>Sl|7Ie_47y($(!10G+57ePpKxqm#Y_#d4
zU#u<8w4iCD&b{9&_fnh$Y{HOyO!`VXGLk}ML2i^cL_-`~mIMB?F{<80l>W$FmZ<-s
z#jPmWU15kUQ6zL{;^?S>`H1mP<@4Wr+W-rQhx4Dh^}rob6dius;VZ#`!*9Fe at Y}dP
zaQMm{hp$9Ds at 7(wmlrw*ms-u)*7W7zM17&wm|m<!jb<lm*E+%3<wm34xDYj$J5h5s
zYImkP^_gg<x!mZ~TJ2zZVWBxQ-Kjk>y|7$6LnG9`KY2NGu{JY*l)Gv>c;t~M9*ul~
z=&jQ&HF{sPuN^$zm~S*MH)yF<o337sF1PBPPOT9%rW?Ubv(c$HmYd7%Xt7zXMfG;H
z+-NT^Ej3%6S~Y4mqRvI0EiFuUW}B_WWHbVtdKZF)>6!URAVokquP61!EUhjsPB*I2
zLcLK7YK at h8tJzqrH9FDCbgMpnexVkeY^+Q#)T@!OqT1Ez&UDmiMvJx9g<7z0p~}C7
z<;uQlaOh%lv36)44Ac)@xOnN%<z{RCpxqv<)>aO+FV|-~2inc$)=cft!otep0h*kv
z&2$a{#1c)n4zxOl7V75@`K}I~Y_vNqhbQ1Qv>u%Kv+hPzr<dvTLF*3wU7ijed-Tk)
zlV^id at u{E%sq1h=eCA|u^3(~VWaWu7m7|ZJIC1=J<=n|{I-WjzG=5v<)Z>p<o`@eg
zS2<&EAM<a|oIQQw<Rix`PaHpc^z^wk5A`OfRKz5eq~O`dDko2!e5`W%)cwbU`;8NN
z8DVC*)q-dXS78JGbh!dfh#sAuxp?68ozd|}PDCR0{ijcyh{Ph(o%X at tSnd4sg$Pz?
z!pO7&`_$p3YO~gMeD63cCBMiHF{0^C<dJbO5}n}JI~`9%$WBrm9&M|1=OS$9Nj~d2
zsJU=3aNLlTcI*igcbd(py@)&=ypF6q-Vkq!4KLI>*1987v=Iy68MSJ&H4rp|oYWf#
z+QI1Y6f7_G(b9D1;*E88vDxmJUJ!OA6Lv#=w7~URSCJcQeF<6nsvEuz9;LV>T+kGB
z9Srt2mKPRo3r<$AL~ndkbgt6^_UP7Iqw>i{wRS~>TAFU7>pCr6t8m1a7VC}aPP0`G
zPAxA!ajxEhGu|8>wtC$sGt-UNbfWXM=<T&uv)oU%<E>V+B?ULS;qxvrO{b*XAU?Sh
zCD%*pcKz+Ouf3&K?Q*?Qy?#4R=hUJ{J+q_iP513<N3+uq{1vLc@?cQ5OV at 8AH3hHK
z$n~K<VW3GUWH)LK<nq3D`Kzq5LGctabdOgyuKDSinOeIoV`N4$HAfq?;kf`KYARH!
zs4fM+EPLa$&I)E!+Gnwj^mk at 1M)yUvD@&LN1a}|$<vfO00>7`ihLckG_U*e8wW(2`
zt=C%7#pyOI36Cd_s-{}7cvm9<0pKRE*Kchxt=fuUai?G5@@|751Y`Uv&CH|~zWQcP
zH9N5UX>il3WA~d2U0W=j6^X*pN_`sn6773#53U)PYv~*a^cL39&|0~Xnu%DL0vEl#
zf1++BA0j$^p7SQdw3yi$IUu+l{HZpVrMPh^mWBOx)HPkzdRvlSJvjPU6FqKHU+>%*
zO;@YYfrS~og?gjYh6o4L(gEKRU7K;KH|C}4<jep<+-}!eX2`no8tvcL7KHq(-nIra
zDgSgOuhWvl)Tmwdz}n!V2mxqAhL$&M%_ZyQz at n^MbYNxaK;jM_Si+%cBZqH#W8=-j
zP~slqzO_6CQaU7+WLCX5WDI&R5;{%Bf|CmiwF}b=(fO;$cDr_ISq3dQ)?A#1`(Tb{
zD>z$g<G`9IwrWeQT3eC at P6H?(;k9+H24|$t+a_hzTBBa82B!hkiJwTy&7z#nDs^xq
zkU`UYSh{Mxg(NmxSJO9ek)+=oWdya}?z98*(oD)0rg0F>lsSWcbxCj_2-676LTwfw
z8b719QfCyWokzV`12<PS4D%9^_x4pBP;5|Zc}Ys3eHBk*5lLKF=$7IMPB8u|t`F8?
z1vO}cPCVCktu`Or-)gqo2V8gZcIT--T|Hp_l8w+c9UMzWX;`FXa0bmA3|*Q at IK|9e
z1y8kB59*{%aKe{6{e@?j+hFoR90upF<JQkyG~nWDm9|U)Q6 at OrYR;plmg*qs<e}4^
zo(Ty&*bo6>P_>i<9)FI$T?(CSL+<YFW3?+CM at Pfx@hi0%?*aOb5>!DlQ^!H<FF+Nr
z%O8`_1?R3Vo^LJ?^az7IYA$u7q_ogulr|OHTw+K<t_{;8m at yf?tF`t_tG)z70c%RL
zqtkdl)POOP*Ba~0#kx~_#&0T=AmW4yTi0T at AnjWK8k!XC^!AW4R~7o}Wpuf at OykWN
zR8epaOXLDRn7xV4HDaA<!KQM!3C<AxYQNZ^l4fcsuHeLS!*PiOslK?hP?KqMqJ*(&
zPa_Yw5)2I{!xTv(P9lXJXRTUr{|coa5pKJts|FN2MfrA`GtC80G2y_s34$cuZN@^7
zdaTw)-8zBxNP=rGEvw7mQ4d8IVQI6MiTrTXfyrdnx0b%vkh)~*dz^+F21xfVVe#4N
zMTw?bNMD)=`4I(4!Tvr@)jEnGB{)?D#mW70qbo%lNoK><>lMW5^A;qFlg=;C5({`O
z)E&?{L!KEVC+r~0KND0l>BFwJOoDW@?^3II!Njurw)ZJa1(O<EU&KD4kN?tglPJ1&
zWu{iEiY#dD`o-oF>R-xCEOY<#()9WILcLQr>1hLYeWnht1pWUlXHEtGHvFC3Kg{h2
z|K`9SWVYwN82nH+%-%cj6XDb0>FlB0p5W61&jrQop6n;X-_8yP&kqD)HS<SdZQ!oV
zcW3 at p=0Nt5+<zH(U*=1>-2=k|AIm&EFp;?uoXxy3`$yUT8vNtzQ at NLd4`r_o+>&X8
zi`jDS!?|O at ABP_ep2>c5 at cD2k_x-uQp1UJ>Tlo6$-N7dZek8m<b0Yjd13~b at WDx8O
zMuVL at cM4>l=)V#D$?K2)+Zk*f<$ZQ^C<v!UI6WyC8RTU?7*ri!(@Oe3o0A(_9 at G0V
zl1Rab9*+e4P2VTw(%((#RS;~`wfz}!kNMmCzNaXcg`V3jT<7#B7;%sJ+xxz!D3`^a
z+pW5`KO^ojfBF9|p6=SEzZ?J8_ui1Vak=#AczP8CP{98gagX`i`@W|rm)m=8Cv<Ip
zM%-im^8drH{f5`w^^JGmbMNcpqxT;>euATx4(2}{CKZSMg)jmwp-d2D`IqCL=s(E6
zA^xetr(Vw={!<-|Yg9Kq|J_8TKcJvC=Xl<+w;RDPgbKBr-rUmwm+D{tsSS5^V}HfE
zLHxnP`D8%cy>K{x_^1EMwjbOx`Qg>1l`pMnH$_BJApY#(e6c__M^0J=3pJxZE5Yl=
zDiwK*6>QAxawBQCm%h&(dh*h#OYi$fVHkvAZhvrla9>X);z;#jlEtqOo7o=Z4s{ln
z3g=P(t*Zx;6wizb{`SF~QV_w;9c$jM+<ox!bbIl2-w^)H{x62X?Uf3K%d};M=k-dv
zF}>8j*z8nrCs*pV%dgb{+7+U(@bC?mRm^TRG6!D0hEL$AgY4^Wym;D2?gmCMTdmA2
zG~2a-L$BTeWoN6(^a`TEZ~SU1;3-yS7p5<?hwi?yYVwrSlPYRJ!#6e-C^KChxdCc0
z76k=<Frzm%n4|{YWJN5LzwL$wBbYYbSW)@sV>dQbOKfbu=hY!lOk0@&h)%7N`oUZ7
zxWS5YTnjf+m;k6k;M3W<wIXpro{3B<ijvyJJIVFeX348pE0=52^Y>W^Ec*GG3QwyQ
za;*lX#f94jE6}CY8P7>mOiX$8fMX%Iq2g1m6+(s9_MK~9p0AOSttiNvoLuv&Mn8J7
zW7nD&u8!#0-nnDVJ5{nbyKY+Z#??xK)v2{ms$%kT_u7}P?n;BXi}p=xhoGA7)t+Ps
zM(T>wR+W0Sy|=g^Y~XncBgd8(mvEuif{u)$YA at 7hO1G>5U2hu8i<KpOVzLnxMbYi@
zTC}K?PeR=c^O}lIXi#r6xMU8dqB)p~%TiQtDX%H2W+cEBba2Iaocmy>zUDS4Qz5}Y
z3VC|r*4-Nv79FkC*F+n<P4I3d_M>Rmb(W0WsY*eX)VXaftrBFZ%iBw9+VZs+e5ZBQ
zy1QfVnj%U4q=P%RHE?v>_q)lkGmZoY_984Z%S<@bj*1wk%ol#Fd4 at 14UZ`Ja94you
z_0Caq*x#y*X6w*a<AL5shqu|I`%To{i<75cThQoFrnOI={svd<7;zfiS(7JEzs|8#
za%+9u)&K0o!gBlKH*U5*?ENuNa<?m!-k&7YyQg?rAX at rEJgRc{PS~^4jsC~49|S+7
z`R|*uW*?|^9%)WjA8l5b7i#Ai_jG5uReQr)p0Wu<NanKniVUv4aV;ZQ{=72VYA$-N
zd(-AN4HEsIoPBG(ara$s-c8pjjAsdPTh#~A)V0<**!3;j*T2>CBU9_2TO%4|yl4GO
zO$#W)r}sxUX!H~i-9Jga6ZKYmEj-7 at dmB^}g5mh2A&cbY@=`hg6hZ66?j*6+``EKu
z`++UVTc~gfnSJoqHN4u*L03?~bX{2y=qJY$;yiIiFq}0kJw&FLkc<h at w|8mkGujTD
z58p%+z2iU81h<{qTU*mh<klY9vGMD(k3HIl<Yd^s+NrIo2G&lccs*V0X~||~&OUa=
ziuEA>>|=k);Y~9cU5IT!IZZ~K8(ds&@cY<i4NS=t<LcJqqtdeO`Uw%_{^ge5$}T)o
zYh37DeCy`^r*FGS+7aW`K8`^=-7rpGIG5z&|8jxi2F00Xb3qjSrakK at k)Rd>xlsEn
z6VyohJTu)n0b3t$to+q&OVh1(EpAldh2-^L8 at GqaEv2PM|N3^koo=DWn#bG>e`SQ0
z&zw5P1lTukV*;X~S$hVkIaD<<UG7rZ+Z(7zuE9^hBdWFYJH<FKmqzQx`k=-3t at g}X
z>(*_py4I+)u-&9ITNTq3Htq_*&}MDBJrX=`t#>YxT09Hyw;Ho+TkqDqFp^feI8tr;
z*{ga{?u^=D5dPWRn8)qu^O}L59|KLxOD9h|Rk$G1CIhG5;$*$;Z;gUym3#*3YD4Oz
zr=ZB%?W8#&4ohCAeJ^dUw@)=2-^4uOvHFF2=h9HUZ5OS4&mxI-!Fg}K`muVevsGy6
zL-lf at +Ux-gyS_3}smxrtQn|3uJU_jFD7P at G_0Hw3XFa05u<pO@%Kpj&kDNXlKT at f*
zm(N#DR!;V<Ht^*R&MYlmUCXGX2A7$rTB%hQ=W#CIzLEKqyDT5!9R<@PM`8N=7nj~P
zbMeBH?#Y=>>qLz?E|OnQ<*m#k<e*Me-#KPCk2jQ?JW;*o441uw6pqJM!-?KP>GN+1
zx7c&iP)6|MSDp at c*^?7^oTh9+<hdHcq8Z(1!kzX~BZrgwQ2VaXb$o7_sV-!#e&ONz
z!os)urzBCSFKeZz-xdyPvc5U<?cs2B!Cihwn44|YYTp?SRu^>fH^M>r#?6`U3Wu=O
zy87;Lj5(hr0<p@>#pTBQ_k<&}i8TJraKOTv?+phklCZxO=6w*o(yUkicDTiP(`hjJ
z?hwLTz-r-X8%DH{^ZUZ0f8G;Vet(GHXoZu9Y55;WTTX(+9}LHR;l5DtheCWuYoq%Z
zA#wrV4~MWs`V#V3%%#`r=smrC*eKtdLf;>v{YY;oYXh;r6K?Ky0!pht+WSC3)sOXd
zWUAqPA)ciHwqbzuY*^@hExqyn?xQ5wc`igC)QH70jpoedYDGnfTpLaC{ND|62-g%a
zNl8omy>P%H at V_7CRP!H%+j}bLiErrx;eb{AU^rko+#gTix2~6(OXfZ*s#T at -hr-t+
zE;Qkl*R1{}VHn6=HnFNzKO7Qgq#*XjW6!UDGku;(tIoxbgt_+l*8E39G;ms#Uh&p&
zhHdH8PlSX_>ASApPu{-}%J-x2$HL)CWocQLKN)VS=zXQNSiv*?sc;ZR;r^$?VP?l|
zV((`{Qa{r+r&-a2=Ff_-<c((9m1e^N(4Pwjo!R*LFef?thhbktT2(~)kHVZZ=r4o=
z)#b&-s~-<XFu*g+b2i$a2nS|oSU~iP0*iTAW(t2vm$Oyj^+k2x?o{hdmpA$4a6tUF
z^2so#-+!zDxYxS<m2il5#ee^#`$D(B8V(v0uKd$(d-mYhJVgI29Go?__~%^A%Jcpg
zTp&J;=1Xd7R?KA?m0t&5LG~}hp;?<3p8Z!mQ750`w^LhK_>FGg8uY)`U^`9g?%(Ko
z)-JDnnhxyhH^b3Nr8&D$K{3t$TUFMLW0&7j1>HiPe+N|>uFHQP4qcvUb()Lk{{tf<
z=wCelAL+ftl7-Lk3w7K7DI8w$0RDEEch&IWTebfj4#B-rU!M)LL}s5u6*K=*akJWR
zKdK^GOz}J6$V$@Ze^K|&S@^GE4kcdyJj%DWICHV}1$VKy^t<k2>FV#<1>E%C;HgfF
zGXGs_)LpW==YP1zi%Y+67uDsZKd=iB{y)PZiZx~ym;O+LZ+Dg&GfP)r_D`3t{*k+)
z<j}_lwgs>wDsE=JveYyI4EH{8`muvm{N{s+KpsSY+w^Yb{B*mPxox8Yw9)ERQnzr{
zau?bC8y5wAYf9#B-?-$OMlH87a2){pTeYHt*D1QDS>&fZbVIPJ<nWC(y25(VksE4M
zB}ebv2myVW02b#Z8IJtTDlIkAC6f6A&I^32h1{EVtZx!oM=g!*S^owZ(}by!c=LuM
z>;uMRn}}k|<oc%Qq0uZ at 8ykRVerOu-DW2JS)A}}^IAi4=Y&PeM+x5D?CHW;I#|MI;
zgRQ1`H5 at RO&A`nb%-M=)mF<0?f;r4&TEciFxOHTSMwVw-!4z)dQWMp+>VflDW$C6H
z7Y1K@&%wh7?+%{W;-k!2a+6q&_P`za^UDkK2b^%+F}kR^Knp?d*s{26=se)O+4db<
V(uIr%G*R2WW4KLte}K5~{{w2iz+3<T
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..bb61b288cfc62e 100644
--- a/llvm/test/tools/llvm-cov/binary-formats.c
+++ b/llvm/test/tools/llvm-cov/binary-formats.c
@@ -10,4 +10,11 @@ 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 \
+// -mllvm -enable-name-compression=false \
+// -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 07bb6c2f6af962a1bb0586cc3a8068fe0d129599 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/9] [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());
>From a68edc19853522a8ef8e965e4b11337e2d46249f Mon Sep 17 00:00:00 2001
From: Yuta Saito <kateinoigakukun at gmail.com>
Date: Mon, 7 Oct 2024 16:54:44 +0000
Subject: [PATCH 8/9] fixup! [compiler-rt][profile] Add initial support for
WebAssembly/WASI
---
compiler-rt/lib/profile/GCDAProfiling.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
index a207ddf97c8831..f67d95d21a7b54 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) && !defined(__wasi__)
+#if !defined(_WIN32) && !defined(__wasm__)
COMPILER_RT_VISIBILITY
pid_t __gcov_fork() {
pid_t parent_pid = getpid();
>From dc7043e64fe2440e939e8f64d92d8ac1f1ee44b6 Mon Sep 17 00:00:00 2001
From: Yuta Saito <kateinoigakukun at gmail.com>
Date: Tue, 8 Oct 2024 02:17:07 +0000
Subject: [PATCH 9/9] fixup! [wasm-ld][Coverage] Align `__llvm_{covfun,covmap}`
sections to 8 bytes
---
lld/wasm/InputFiles.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lld/wasm/InputFiles.cpp b/lld/wasm/InputFiles.cpp
index a60deba9113cd4..420865e2aea8e3 100644
--- a/lld/wasm/InputFiles.cpp
+++ b/lld/wasm/InputFiles.cpp
@@ -452,8 +452,8 @@ 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.
+// 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) ||
More information about the cfe-commits
mailing list