From 4c4ee15ea4411368f8840d96f3a47751fe212427 Mon Sep 17 00:00:00 2001 From: Duncaen Date: Tue, 4 Feb 2025 14:18:48 +0100 Subject: [PATCH 1/4] New package: wasi-libc-25 --- srcpkgs/wasi-libc/template | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 srcpkgs/wasi-libc/template diff --git a/srcpkgs/wasi-libc/template b/srcpkgs/wasi-libc/template new file mode 100644 index 00000000000000..db04d661f64cfc --- /dev/null +++ b/srcpkgs/wasi-libc/template @@ -0,0 +1,36 @@ +# Template file for 'wasi-libc' +pkgname=wasi-libc +version=25 +revision=1 +_llvmver=19 +hostmakedepends="clang${_llvmver} llvm${_llvmver}" +short_desc="WASI libc implementation for WebAssembly" +maintainer="Duncaen " +license="MIT, custom:Apache-2.0-with-llvm-exception" +homepage="https://github.com/WebAssembly/wasi-libc" +distfiles="https://github.com/WebAssembly/wasi-libc/archive/refs/tags/wasi-sdk-${version}.tar.gz" +checksum=42e6eb03fd097f8a0f76c0db3c6364b71c97bc11aedc3cd73266fad587a1ea11 + +nostrip=yes + +post_patch() { + # avoid building again at install step + vsed -e 's/\(install:\) finish/\1/' -i Makefile +} + +do_build() { + # https://bugzilla.mozilla.org/show_bug.cgi?id=1773200#c4 + make ${makejobs} AR=llvm-ar CC=clang NM=llvm-nm BULK_MEMORY_SOURCES= + make ${makejobs} AR=llvm-ar CC=clang NM=llvm-nm THREAD_MODEL=posix + + # new wasm targets needed by rust + make ${makejobs} AR=llvm-ar CC=clang NM=llvm-nm TARGET_TRIPLE=wasm32-wasip1 + make ${makejobs} AR=llvm-ar CC=clang NM=llvm-nm TARGET_TRIPLE=wasm32-wasip1-threads THREAD_MODEL=posix + make ${makejobs} AR=llvm-ar CC=clang NM=llvm-nm TARGET_TRIPLE=wasm32-wasip2 WASI_SNAPSHOT=p2 +} + +do_install() { + make CC=clang INSTALL_DIR="${DESTDIR}/usr/share/wasi-sysroot" install + vlicense LICENSE-MIT + vlicense LICENSE-APACHE-LLVM +} From 01f1d32c16559e5a0bddc08a19dc34f5f921e078 Mon Sep 17 00:00:00 2001 From: Duncaen Date: Tue, 4 Feb 2025 14:18:53 +0100 Subject: [PATCH 2/4] New package: wasi-sdk-25 --- srcpkgs/wasi-compiler-rt | 1 + srcpkgs/wasi-libcxx | 1 + srcpkgs/wasi-sdk/template | 157 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 120000 srcpkgs/wasi-compiler-rt create mode 120000 srcpkgs/wasi-libcxx create mode 100644 srcpkgs/wasi-sdk/template diff --git a/srcpkgs/wasi-compiler-rt b/srcpkgs/wasi-compiler-rt new file mode 120000 index 00000000000000..88ddd205c6ddd6 --- /dev/null +++ b/srcpkgs/wasi-compiler-rt @@ -0,0 +1 @@ +wasi-sdk \ No newline at end of file diff --git a/srcpkgs/wasi-libcxx b/srcpkgs/wasi-libcxx new file mode 120000 index 00000000000000..88ddd205c6ddd6 --- /dev/null +++ b/srcpkgs/wasi-libcxx @@ -0,0 +1 @@ +wasi-sdk \ No newline at end of file diff --git a/srcpkgs/wasi-sdk/template b/srcpkgs/wasi-sdk/template new file mode 100644 index 00000000000000..e1b55179d8b937 --- /dev/null +++ b/srcpkgs/wasi-sdk/template @@ -0,0 +1,157 @@ +# Template file for 'wasi-sdk' +pkgname=wasi-sdk +version=25 +revision=1 +_llvmversion="19.1.7" +_llvmver="${_llvmversion%%.*}" +_wasi_sdk_ver=25 +build_wrksrc="llvm-project-${_llvmversion}.src" +build_style=cmake +hostmakedepends="python3 clang${_llvmver} llvm${_llvmver} chroot-git ninja" +makedepends="wasi-libc" +depends="wasi-libc wasi-libcxx wasi-compiler-rt" +short_desc="WASI-enabled WebAssembly C/C++ toolchain" +maintainer="Duncaen " +license="custom:Apache-2.0-with-llvm-exception" +homepage="https://github.com/WebAssembly/wasi-sdk" +distfiles="https://github.com/llvm/llvm-project/releases/download/llvmorg-${_llvmversion}/llvm-project-${_llvmversion}.src.tar.xz + https://github.com/WebAssembly/wasi-sdk/archive/refs/tags/wasi-sdk-${version}.tar.gz" +checksum="82401fea7b79d0078043f7598b835284d6650a75b93e64b6f761ea7b63097501 + 4ab1ad1b5fc60d3c9c36905fea8ed899f5fdc5bd0bd77849c112e0b5a1788916" + +nostrip=yes + +export CMAKE_GENERATOR=Ninja + +post_extract() { + cp "wasi-sdk-wasi-sdk-${version}/wasi-sdk.cmake" "llvm-project-${_llvmversion}.src"/wasi-sdk.cmake + cp -r "wasi-sdk-wasi-sdk-${version}/cmake/Platform" "llvm-project-${_llvmversion}.src"/cmake +} + +_configure_libcxx() { + local target="$1" + local destdir="$2" + local want_threads="OFF" + local extra_cflags="" + + case "$target" in + *-threads) + want_threads="ON" + extra_cflags="-pthread" + ;; + esac + + cmake -B "$destdir" -G Ninja -S runtimes -Wno-dev \ + -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi" \ + -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=ON \ + -DCMAKE_BUILD_TYPE=MinSizeRel \ + -DCMAKE_MODULE_PATH="${wrksrc}/${build_wrksrc}/cmake" \ + -DCMAKE_TOOLCHAIN_FILE="${wrksrc}/${build_wrksrc}/wasi-sdk.cmake" \ + -DCMAKE_C_COMPILER_WORKS=ON \ + -DCMAKE_CXX_COMPILER_WORKS=ON \ + -DCMAKE_C_FLAGS="$CFLAGS $extra_cflags --target=$target" \ + -DCMAKE_CXX_FLAGS="$CXXFLAGS $extra_cflags --target=$target" \ + -DCMAKE_ASM_COMPILER_TARGET="$target" \ + -DCMAKE_CXX_COMPILER_TARGET="$target" \ + -DCMAKE_C_COMPILER_TARGET="$target" \ + -DLLVM_DEFAULT_TARGET_TRIPLE="$target" \ + -DCMAKE_STAGING_PREFIX="${XBPS_CROSS_BASE}/usr/share/wasi-sysroot" \ + -DCXX_SUPPORTS_CXX11=ON \ + -DLIBCXX_ABI_VERSION=2 \ + -DLIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY=OFF \ + -DLIBCXX_CXX_ABI=libcxxabi \ + -DLIBCXX_CXX_ABI_INCLUDE_PATHS=libcxxabi/include \ + -DLIBCXX_ENABLE_EXCEPTIONS=OFF \ + -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=OFF \ + -DLIBCXX_ENABLE_FILESYSTEM=OFF \ + -DLIBCXX_ENABLE_SHARED=OFF \ + -DLIBCXX_ENABLE_THREADS=$want_threads \ + -DLIBCXX_HAS_EXTERNAL_THREAD_API=OFF \ + -DLIBCXX_HAS_MUSL_LIBC=ON \ + -DLIBCXX_HAS_PTHREAD_API=$want_threads \ + -DLIBCXX_HAS_WIN32_THREAD_API=OFF \ + -DLIBCXX_INCLUDE_TESTS="$([ "$CHECK_PKGS" ] && echo ON || echo OFF)" \ + -DLIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY=OFF \ + -DLIBCXXABI_ENABLE_EXCEPTIONS=OFF \ + -DLIBCXXABI_ENABLE_PIC=OFF \ + -DLIBCXXABI_ENABLE_SHARED=OFF \ + -DLIBCXXABI_ENABLE_THREADS=$want_threads \ + -DLIBCXXABI_HAS_EXTERNAL_THREAD_API=OFF \ + -DLIBCXXABI_HAS_PTHREAD_API=$want_threads \ + -DLIBCXXABI_HAS_WIN32_THREAD_API=OFF \ + -DLIBCXXABI_INCLUDE_TESTS="$([ "$CHECK_PKGS" ] && echo ON || echo OFF)" \ + -DLIBCXXABI_LIBCXX_INCLUDES="${wrksrc}/${build_wrksrc}/build-libcxx/include/c++/v1" \ + -DLIBCXXABI_LIBCXX_PATH=libcxx \ + -DLIBCXXABI_SILENT_TERMINATE:BOOL=ON \ + -DLIBCXXABI_USE_LLVM_UNWINDER=OFF \ + -DUNIX=ON \ + -DWASI_SDK_PREFIX=/usr \ + -DLIBCXX_INSTALL_INCLUDE_DIR=include/$target/c++/v1 \ + -DLIBCXX_INSTALL_INCLUDE_TARGET_DIR=include/$target/c++/v1 \ + -DLIBCXXABI_INSTALL_INCLUDE_DIR=include/$target/c++/v1 +} + +do_configure() { + export CFLAGS="-O2 -fno-exceptions --sysroot=${XBPS_CROSS_BASE}/usr/share/wasi-sysroot" + export CXXFLAGS="-O2 -fno-exceptions --sysroot=${XBPS_CROSS_BASE}/usr/share/wasi-sysroot" + + _configure_libcxx wasm32-wasi build + _configure_libcxx wasm32-wasi-threads build-threads + + cmake -B build-compiler-rt -G Ninja -S compiler-rt -Wno-dev \ + -DCMAKE_BUILD_TYPE=MinSizeRel \ + -DCMAKE_MODULE_PATH="${wrksrc}/${build_wrksrc}/cmake" \ + -DCMAKE_TOOLCHAIN_FILE="${wrksrc}/${build_wrksrc}/wasi-sdk.cmake" \ + -DCMAKE_C_COMPILER_WORKS=ON \ + -DCMAKE_CXX_COMPILER_WORKS=ON \ + -DCOMPILER_RT_BAREMETAL_BUILD=ON \ + -DCOMPILER_RT_INCLUDE_TESTS=OFF \ + -DCOMPILER_RT_HAS_FPIC_FLAG=OFF \ + -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \ + -DCOMPILER_RT_OS_DIR=wasi \ + -DWASI_SDK_PREFIX=/usr \ + -DCMAKE_INSTALL_PREFIX="/usr/lib/llvm/${_llvmver}/lib/clang/${_llvmver}/" +} + +do_build() { + cmake --build build ${makejobs} + cmake --build build-threads ${makejobs} + cmake --build build-compiler-rt ${makejobs} +} + +do_install() { + DESTDIR="$DESTDIR" cmake --install build-compiler-rt + rm -r "$DESTDIR/usr/lib/llvm/${_llvmver}/lib/clang/${_llvmver}/include" + + DESTDIR="$DESTDIR" cmake --install build + mv -v "${DESTDIR}"/usr/share/wasi-sysroot/lib/wasm32-{unknown-,}wasi + DESTDIR="$DESTDIR" cmake --install build-threads + mv -v "${DESTDIR}"/usr/share/wasi-sysroot/lib/wasm32-{unknown-,}wasi-threads + + mkdir -p "${DESTDIR}/etc/clang${_llvmver}" + cat <<-EOF >"${DESTDIR}/etc/clang${_llvmver}/wasm32-unknown-wasi.cfg" + --sysroot /usr/share/wasi-sysroot + EOF + ln -svf wasm32-unknown-wasi.cfg "${DESTDIR}/etc/clang$_llvmver/wasm32-unknown-wasi-threads.cfg" + vlicense "../wasi-sdk-wasi-sdk-${version}/LICENSE" +} + +wasi-libcxx_package() { + short_desc+=" - C++ standard library" + nostrip=yes + make_dirs="/usr/share/wasi-sysroot/include/c++/v1 0755 root root" + pkg_install() { + vmove usr/share/wasi-sysroot/include + vmove usr/share/wasi-sysroot/share + vmove usr/share/wasi-sysroot/lib/wasm32-wasi + vmove usr/share/wasi-sysroot/lib/wasm32-wasi-threads + } +} + +wasi-compiler-rt_package() { + short_desc+=" - runtime libraries" + nostrip=yes + pkg_install() { + vmove "usr/lib/llvm/${_llvmver}/lib/clang/${_llvmver}/lib/wasi/libclang_rt.builtins-wasm32.a" + } +} From bb2a568aebd3667344572da13cd2dbe7fc469761 Mon Sep 17 00:00:00 2001 From: Duncaen Date: Tue, 4 Feb 2025 14:19:26 +0100 Subject: [PATCH 3/4] firefox: update to 135.0. --- .../patches/clang-sysroot-toolchain-fix.patch | 18 +++ srcpkgs/firefox/template | 103 +++++++----------- 2 files changed, 58 insertions(+), 63 deletions(-) create mode 100644 srcpkgs/firefox/patches/clang-sysroot-toolchain-fix.patch diff --git a/srcpkgs/firefox/patches/clang-sysroot-toolchain-fix.patch b/srcpkgs/firefox/patches/clang-sysroot-toolchain-fix.patch new file mode 100644 index 00000000000000..898603f529316c --- /dev/null +++ b/srcpkgs/firefox/patches/clang-sysroot-toolchain-fix.patch @@ -0,0 +1,18 @@ +We need to pass --sysroot and --gcc-toolchain explicitly for cross compiling with glibc +because when the lld tries to link libc, it will read the gcc libc linker script which +includes absolute paths to actual libc files and without the sysroot argument it picks +the host ones, even though it discovered the linker script in the sysroot already. +linker-script = /usr/aarch64-linux-gnu/lib64/libc.so +--- a/build/moz.configure/toolchain.configure ++++ b/build/moz.configure/toolchain.configure +@@ -725,6 +725,10 @@ + flags.append("--target=%s" % toolchain) + has_target = True + ++ if info.type == "clang" and not target.os == "WASI" and (info.cpu != target.cpu): ++ flags.append("--sysroot=/usr/%s" % toolchain) ++ flags.append("--gcc-toolchain=/usr") ++ + if not has_target and (not info.cpu or info.cpu != target.cpu): + same_arch = same_arch_different_bits() + if (target.cpu, info.cpu) in same_arch: diff --git a/srcpkgs/firefox/template b/srcpkgs/firefox/template index 277ffd6c666e5b..e195f0a7446bca 100644 --- a/srcpkgs/firefox/template +++ b/srcpkgs/firefox/template @@ -3,7 +3,7 @@ # THIS PKG MUST BE SYNCHRONIZED WITH "srcpkgs/firefox-i18n". # pkgname=firefox -version=134.0 +version=135.0 revision=1 build_helper="rust" short_desc="Mozilla Firefox web browser" @@ -12,29 +12,31 @@ license="MPL-2.0, GPL-2.0-or-later, LGPL-2.1-or-later" homepage="https://www.mozilla.org/firefox/" changelog="https://www.mozilla.org/en-US/firefox/${version}/releasenotes/" distfiles="${MOZILLA_SITE}/firefox/releases/${version/beta/b}/source/firefox-${version/beta/b}.source.tar.xz" -checksum=ca88068bd72784c10de16df62359b2dc354672a1a427b4fd6a5fcdb34c06457e +checksum=827e12a962ef47511089af4498f65ebf42fa57ca31db790bfd7e9a820d16b960 lib32disabled=yes _llvmver=19 # needs to match rust hostmakedepends="autoconf213 unzip zip pkg-config perl python3 yasm rust - cargo llvm${_llvmver} clang${_llvmver} lld${_llvmver} nodejs cbindgen nasm which tar - $(vopt_if pgo 'xvfb-run dbus')" + cargo llvm${_llvmver} clang${_llvmver} lld${_llvmver} nodejs cbindgen nasm which + tar xz $(vopt_if pgo 'xvfb-run dbus mesa-dri vulkan-loader pciutils') + $(vopt_if wasi wasi-sdk)" makedepends="nss-devel libjpeg-turbo-devel gtk+3-devel pixman-devel libevent-devel libnotify-devel libvpx-devel libwebp-devel libXrender-devel libXcomposite-devel libSM-devel libXt-devel rust-std - libXdamage-devel freetype-devel + libXdamage-devel freetype-devel $(vopt_if wasi wasi-sdk) $(vopt_if alsa alsa-lib-devel) $(vopt_if dbus dbus-glib-devel) $(vopt_if pulseaudio pulseaudio-devel) $(vopt_if xscreensaver libXScrnSaver-devel) $(vopt_if sndio sndio-devel) $(vopt_if jack jack-devel)" -depends="nss>=3.72 nspr>=4.32 desktop-file-utils hicolor-icon-theme" +depends="nss>=3.72 nspr>=4.32 desktop-file-utils hicolor-icon-theme pciutils" conflicts="firefox-esr>=0" -build_options="alsa jack dbus pulseaudio xscreensaver sndio wayland lto pgo clang" -build_options_default="alsa jack dbus pulseaudio xscreensaver sndio wayland clang" +build_options="alsa jack dbus pulseaudio xscreensaver sndio wayland lto pgo clang wasi" +build_options_default="alsa jack dbus pulseaudio xscreensaver sndio wayland clang wasi" desc_option_lto="Enable Link Time Optimization" desc_option_pgo="Enable Profile-guided Optimization" desc_option_clang="Build with clang" +desc_option_wasi="Build wasm sandboxed libraries" case $XBPS_TARGET_MACHINE in armv[56]*) broken="required NEON extensions are not supported on armv6" ;; @@ -42,6 +44,10 @@ case $XBPS_TARGET_MACHINE in ppc*) broken="xptcall bitrot" ;; esac +if [ "$CROSS_BUILD" -a "$build_option_pgo" ]; then + broken="pgo can't be enabled for cross-compilation" +fi + # we need this because cargo verifies checksums of all files in vendor # crates when it builds and gives us no way to override or update the # file sanely... so just clear out the file list @@ -66,60 +72,23 @@ post_patch() { } do_build() { + export AS="${CC}" + export CFLAGS="-O2" + export CXXFLAGS="-O2" + export HOST_CFLAGS="" + export HOST_CXXFLAGS="" + export LDFLAGS="-Wl,-rpath=/usr/lib/firefox" + # export LDFLAGS+="-Wl,--threads=${XBPS_MAKEJOBS}" + if [ "$build_option_clang" ]; then export CC=clang export CXX=clang++ - - if [ "$CROSS_BUILD" ]; then - mkdir -p wrapper - - local gcc_version=$(gcc -dumpversion) - local clang_version=$(clang -dumpversion) - - cat <<-! >"wrapper/${XBPS_TARGET_MACHINE}-clang" - #!/bin/sh - exec clang \ - --target="${XBPS_CROSS_TRIPLET}" \ - --sysroot="${XBPS_CROSS_BASE}" \ - --gcc-toolchain=/usr \ - -isystem "${XBPS_CROSS_BASE}/usr/include" \ - "\$@" - ! - - cat <<-! >"wrapper/${XBPS_TARGET_MACHINE}-clang++" - #!/bin/sh - exec clang++ \ - --target="${XBPS_CROSS_TRIPLET}" \ - --sysroot="${XBPS_CROSS_BASE}" \ - --gcc-toolchain=/usr \ - -isystem "${XBPS_CROSS_BASE}/usr/include/c++/${gcc_version%.*}" \ - -isystem "${XBPS_CROSS_BASE}/usr/include/c++/${gcc_version%.*}/${XBPS_CROSS_TRIPLET}" \ - -isystem "${XBPS_CROSS_BASE}/usr/include/c++/${gcc_version%.*}/backward" \ - -isystem "${XBPS_CROSS_BASE}/usr/include" \ - "\$@" - ! - - chmod +x wrapper/* - - export PATH="${wrksrc}/wrapper:$PATH" - export CC=${XBPS_TARGET_MACHINE}-clang - export CXX=${XBPS_TARGET_MACHINE}-clang++ - fi - export AR=llvm-ar export NM=llvm-nm export HOST_CC=clang export HOST_CXX=clang++ fi - export AS="${CC}" - export CFLAGS="-O2" - export CXXFLAGS="-O2" - export HOST_CFLAGS="" - export HOST_CXXFLAGS="" - export LDFLAGS="-Wl,-rpath=/usr/lib/firefox" - # export LDFLAGS+="-Wl,--threads=${XBPS_MAKEJOBS}" - disable_jemalloc() { if [ "$XBPS_TARGET_LIBC" = "musl" ]; then echo "ac_add_options --disable-jemalloc" @@ -153,6 +122,14 @@ do_build() { fi } + disable_wasi() { + if [ "$build_option_wasi" ]; then + echo "ac_add_options --with-wasi-sysroot=/usr/share/wasi-sysroot" + else + echo "ac_add_options --without-wasm-sandboxed-libraries" + fi + } + cat <<-! >.mozconfig ac_add_options --prefix=/usr ac_add_options --libdir=/usr/lib @@ -178,9 +155,7 @@ do_build() { $(disable_elfhack) $(disable_webrtc) - # XXX: wasi currently not ready - # ac_add_options --with-wasi-sysroot=/usr/share/wasi-sysroot - ac_add_options --without-wasm-sandboxed-libraries + $(disable_wasi) ac_add_options --with-mozilla-api-keyfile="${wrksrc}/mozilla-api-key" @@ -208,6 +183,8 @@ do_build() { ac_add_options $(vopt_enable sndio) ac_add_options --enable-default-toolkit=$(vopt_if wayland 'cairo-gtk3-wayland' 'cairo-gtk3') + mk_add_options MOZ_OBJDIR="${wrksrc}/obj" + MOZ_APP_REMOTINGNAME=Firefox ! @@ -235,16 +212,16 @@ do_build() { ./mach build ./mach package - LLVM_PROFDATA=llvm-profdata JARLOG_FILE="$PWD/jarlog" \ - dbus-run-session \ + LLVM_PROFDATA=llvm-profdata \ + JARLOG_FILE="$PWD/jarlog" \ + GDK_BACKEND=x11 \ + LD_LIBRARY_PATH="$PWD/obj/dist/firefox" \ + XDG_RUNTIME_DIR="$(mktemp -d "${wrksrc}/pgo-runtime-XXXXXX")" \ + MOZ_ENABLE_WAYLAND=0 \ xvfb-run -s "-screen 0 1920x1080x24 -nolisten local" \ - ./mach python build/pgo/profileserver.py - + dbus-run-session -- ./mach python build/pgo/profileserver.py - stat -c "Profile data found (%s bytes)" merged.profdata test -s merged.profdata - - stat -c "Jar log found (%s bytes)" jarlog test -s jarlog ./mach clobber objdir From 1d66f10854ef69d20652cb543097b204473363fc Mon Sep 17 00:00:00 2001 From: Duncaen Date: Tue, 4 Feb 2025 14:22:48 +0100 Subject: [PATCH 4/4] firefox-i18n: update to 135.0. --- srcpkgs/firefox-i18n/template | 196 +++++++++++++++++----------------- 1 file changed, 98 insertions(+), 98 deletions(-) diff --git a/srcpkgs/firefox-i18n/template b/srcpkgs/firefox-i18n/template index d5b6b283348c86..f166ddebc44dfc 100644 --- a/srcpkgs/firefox-i18n/template +++ b/srcpkgs/firefox-i18n/template @@ -1,6 +1,6 @@ # Template file for 'firefox-i18n' pkgname=firefox-i18n -version=134.0 +version=135.0 revision=1 build_style=meta short_desc="Firefox language packs" @@ -141,100 +141,100 @@ _pkgtmpl() { } } -checksum="ca6f48f598c50ca32edf23f0ef101991db82eccca54d5d8c497a1681f96dc932 - 63f2071743478164bff06cac4916a0e33c56fce1927a9575bab6c4a0f6ba1e4d - 79a3861ed70b7fc99964a23c5792e0ac3693c58f9aa5153a3f8b11c52f4d50fb - 7a5de153c4cb458be8a2edc4352f4af1b2a026c1032d733b1a0f1975b1fc900c - 7356274b193b334f1435e705630814abab65e8cc9fe26faffbfd1d0ff40cd2ff - 95d6f87db116b96c953e61439d43eb3e78b187fb147ca21166126c0de7ee118e - 74c4caa5403b4c43730c38c9f1d273204f10250ad7a6b249e5530efa60811b06 - abdfbdd20f7994869b1ec393837b9b6480b9b1782c484100e81b2f5653957375 - 9f7b83a2e8a18e1a55594bca6b3edd7897da97b7c38e0e036a274d79f9cae5b2 - 6fa69f3722b81e9a03a3d2319fc6047601dbb31f2fe7996fe02d472d05fbb0c8 - 8a6bd122fc5bd5ccf063d2d5613c124e350a5d5c5a12e14142309db7f447da7d - 17dfc0b1f554b80138661c1852f905bb5d71ced8282994896469f833bec5ebcc - 857868b45274b003131bc13cd6cb3c272480b94d5bc07ccb23e37ccb458c58a0 - 62d1fa257fabadecca33e9caf9ea49558aedb9c3b8989fa5558da6a046d02e09 - ec6589167bee670811ffc7e7f7dc2c4ca58a0d6f8677f0bf3b1e743c6086bc76 - e87c2030d54806d4832c5407889693439b3ef06eb96c427f2bfb35ff26283a86 - 5eb333505077eaf4fb771747e1f95682c9254a947fc18f651d188fc378d7ec42 - 8a8f7a95713db855d09fe3ec09a8f80b477f572c3412cd78ac5539c07841384a - 611b76e988eb8b8f0821146133bbf8a8835d484aaff0b826033355a3f77e99ff - f85b9184bbf8d9aaecb1f3db7beefe22db6b64f86c1965d93a0189c81aaf5e9e - 79498224ebf702a2b7de3fb1699df3ded757cfd89e4537076d314a62c04806c0 - 68803debb9336a4aff37bcff7e64471d5dadbbfb68e408b98fdf7e23f8b2bc2a - 8af14f55f5b493b932cab215147e152ed2d699025894780277d3ed4813d748aa - 1d0c2fc91dfc8b1041ca3254548439602f634bce30da63f1a94836fcf6f5891c - d5c2b119156b0bd2934048d7b3fc4a70de8598ef8c22ddfaa80174854520b3c8 - bd88505901ceac5b420f87e08c6e88e0a25279a3b77a732926c73547b13133e6 - 8a103d2d7537bbb0f8bdcb7f17bd0a662bac3ca1232361e6c64e44e9117132d0 - dd410d8a6926ce790fe6ac09cd6508c87d83bbc1516f7b05cf3eeda8f0a82b75 - 723917ebaaa39ffa2644e5088e36b0d6e5a22b37f780c8e2e493d9053ab7f563 - 7b236e52cacad43b63bf5655fd1e98acd457c5c7c83a124968adc2dcffefebcc - d6e0d9f185c391d3f608d07f627052f7274d1a05f0a18eea1b9d5eab7429bd52 - c8cc97084402f2ae90e538338943617a896c802a5f8c24edb8f58a2cc5ac2fd6 - 33f1b747604a52299ceebf554db6e724ce5eb37b059eb8605363fccbf64fda50 - 6ac218cf3e74259293c3f0920449a343444a2127541472666285eb5b6057286b - 2309306067e64c6d10faee5972fc8b17443f1d2abba66c391c73ec46b8d17019 - bdacd2761e9bd7c490b8b0eade5ff94b39677d70e1556681a5bf9361bbc9a4c4 - 8f44c3e332e3fc8728a3c18ec7f5c9d9481dbc1a9fda77067b71ebfa369e9923 - 1023583b9b97be369688bda65e5778590c8ab9a710f85e945f58a385e4a06bea - 94eb41fc132d4377ad90ab858a8edbd8ce5400edf1be3338a4133b8f7e025f13 - 71e09f33207494f6fa4a6dcd3601eafa543c43342ccc5577c93ad20242050eb0 - 4763b5608ad6681ffa11507b91c7ccf1d06089b2a084478f65bf11318cce0be8 - 8f08fc5221d5930799a5dd9b5baa59d6d279c8377bcb17a47fe2eabb6494bf84 - 4f89f1ff215f7fa9e1145b89c25720aa41f99fb42e6eb72086627d682168c353 - 83171d5170af27a64fb4997d543bb1136749dd5fe73eb6ed0f642bc62ca9f66e - 78fe66ab7b6751a2d38d76d72658d5cc816d680f793318db4d526e6b701e8141 - 8f218ba5f7d5c032988aa8dc21a621e9faa62f2a711578ac8d5d6a643a530f0d - 1e61e7fe0f9cf01e5bb87e07f77771fde9db3fdba9015d2453cdb03b92866456 - 3ff420dc5ed935cca418a2dc51210b406bcd76f198b4cf2a72d7aa0cac81777e - 86afa140cb1ea536ae9c6be146a7005e872bfe0c36327513cd16517fd906bd20 - b654599d6cecd703e993e3c0c3b820a2924d7f3554ba7f4a64dfea1e4198103c - 1b1deb0cc4b91fa27eb790780a95d8f8198881da62f2147d45c9f26f7d5e8e6b - a42aabd098a040ffd690ebd3d2fc551894494ca97a2ece2c61ac8f0bec05bf43 - c441d4abf06e1a768dd328c7c84bd09fb165a53b161bcbd02687b638c0edb3b9 - 22aba14c2752bbf86add1f31140fb962de9f7eed0a1be6f39a73bca4fab8e05e - 6be86f370a9ef341a7e83d737db546ca899c4b94bb1d5f26b3b73ea53ff7e650 - 109de67210784a0d81e8e87cee9c7a1f704eb2c089ad4f9e813e7291fd52854f - 987345af5409c80f91e40525840a7068407ac9beaf728488ded1ab5afa33f8aa - 1488d2b01df23c547b41c0e6a3803bd197d06860cd037990e603a9cc44d766e1 - 21cf30ed298ac38dc63ce35296c21ee597f2518b955a80d20232596c1086393a - 6674e25196437749dda799987cd5b485f56b009f1035d053c5711e6d3a963a3a - a4113d1e11b3bf080abd9e4858f53221c18dba16953c71415ab5d74b6b3473e2 - a699871947d12d0b5ec918d6a120df57b3708dedb70bfadf5efacb7d1648dae1 - f1f59841dd6820c3d017a93c0e1fff98903528466ca20975ed15f9778b5a86dd - e151f4762cf679492577e4f59b906f30907273aadb1d679da514448c0d2fe52a - 9701c1271ef388e7de3620243f6ba1dec07007d4ffebdcf47db6dcaa9fb21977 - fd022b824775553264061ae66f005c10debfbcd0c7938d7317bb67d6ac90cf8f - 79c73d210816dd6429c85e6339f17eecb8b0f6d52d8fd2af06b2a3c7f910e503 - bc993823ef2bd0cac22241e74b4f95e29d8bc8131dcd8a987f67a80acf1daef7 - a634a4d82fbc0787f4732146e65228ea6b7e1a3b9cfd86a8a0a3110b71372391 - 3b8ffe651a59e330760564cfa78d3df52b066c0db21dd7d1253e3386953a52b5 - 174dd9dab27baaa000496a7b9663551edb62d5777f3ebf6a6e996f46436bbed7 - 61630880de9b09ef0845400575f4622352492ca09197cfd86ffda6666cb09222 - a03beffc092829fe06625cae62e0b9e9e946aeeb2d7d80244be4ea747ae45f13 - 5bcd0870b0c8bbc6dee1f7cc3f84132a94bc1e197ded176da7e1ec48613cd5c7 - 6152c53a38c3fb6853923e3f46be852bc4b997b431b521f893c371b1aa9580d1 - cd204b1a240e0653cb11ba5469f9128065c76a870072c6faac3200b0827adc78 - b439d9dfea67964606290a8013c62c90d7628c536477a6001966a5d5179786da - 1e42e18e61aaac307630dafe50001cbac558c2f3ce243887a49fbaeea5b9de49 - 7037c105459905a43cc6b792c8f75afc6a178ef15be6df18a33711fb0858e91e - e34834734ba5bf5a97e1d3aeb7cd9699fd6cb1ad7cc07ee6f8e8425f66ca2f07 - eea74c715da0c685608db991494cfa32004be899bf96f5efb5274ef22ef673a2 - 928228f6a9fcb10259ab6959a4b55b6f761c14c4424ad007fe75cf626f06c7c7 - 3795e3d6fc43f4eaa7defa7d73d428f67345278cadd63f7bef8d720d552db956 - e13168975ebbac2ba2b807f7cabc1b2dabb9cb5eb293da58db5e413b45a3210b - 8793c6c39f8e3504753d2c5da2a689d2880a3c9e42ddcfb567567383273935ab - 0135c35877883d749c79e5cce92c04c0d2725e81ed11638400f783e106d07752 - 40e30b35dcba81894031f7970bdf503572d114d097f4d0de6a236f7eb33c2dc5 - 5f749a4d2fdd6d45d03fc5facc25d18f08dfa2bf088dd94466094e7d44baa409 - 517ed762de1a4ac10dc0059bcae60aa8e40f4e45da4a04966b93e8ad180626f2 - 13cb6dbaf43b4523c7fefdeaa1dce4ef641d8edd324c9ecd0961f19b774f77df - 88dc5c26ec7a96a5afb798b6e3ac27185eb7ae0fc894343f7f022306e07ad44b - 7653d2b06298cf7f9242f33bc6a718cd65fdb7f6d4a207e8a36d94a866036b10 - ae0dc3349dcf8acc8fae3569fe89fc0470eb91a219e93039bcab061eb5db7a9a - ee99c1aa6e09d7481fb2a13db9a71a7f522dc29c5a2651aaef22ef81df90b03f - e01cf73a874e3ab6cb131e2b7ac1877c9c716f13b059701efabc76546522e594 - afb236b43e3af13d1a6c56a4224e695c51b8ddfc6814dc167a3a5c4fd6f668dc - ec90a5b5471673f10c4771f071a90b1177257a8dfebdaccf19ffa27fc80a1d19" +checksum="76217b8865e8a454b813d5d3cb7b11330740202625eaaf6e22a3bc60f546429e + db8cf4504dc8ab0740cb15b3bdc2f812aa868395554a8d10069cffa0ac3802ea + 720ddce8ab20e69c3450c299b067170f85820ad56b60c5f80bf1e3bd71593b5d + b3ed9d07ff7b3ae531e3367656f5a5205a3ac54fb890bbb8741583178d9dae09 + 7b6a84e1894fe0f89a627718de48d691877e72b1785cb828e9b25b526fb91db7 + 039ca15880065c711e519fdbf4e0c10792e52f78cf4f80296c747d45cca4c210 + 660d5100d4b58426ff452d33cd62d8187371d77bb9b3aeecc4f72adf64becc5c + adc9570c70d83a96f9dbeb8014a246c63915b068e3fa13cafd26891ec730ec65 + 656811f6b4cd4c9c324761b903367ad6d9e013fdc388ede1a98b7d5e4fe0ba34 + d9c640c8488fba2278ded8b1372f33b22e178b518dbcb9ef9207bbfefc35c3c6 + f3297510dc35db7736c1a9a9cc8a4eda91cc38380567876512f0c3747f657ea4 + 5f37e32f917c4d368255ace22b2b92fb1c4ef5680bc29007f7200d5ecb00227c + 9e60b32e877ab37b6fb0c017ccf3fdf8d9eea710bfcf9beea7d702fdc932f7fe + e23ab2f663be37b36da193d1b25710ea7593bc91601361784d1d7cc391358ddd + 9af2b4a2b99466ea63d9362f7bef0af04984ff5d76573aa2fe3575fe439321db + b2eb62e0339aba733df4e2bfc225bcd74650f29544c8943218af98bf1d41b4b1 + 14a0054f6ae570cf5d95b6f6eec91e57d6968bad1852af95a80e6686136befe4 + abf9037a97612db09e5e051224128795d46ede4b731a497e2557af1f84d12035 + f55556126c5a5c7fae091dd6e42c13b218291a597d29f6bef9314c30c8cada0b + 6f9e5fb165416ab38fbc93571338c7b920c22c3171422410e94a46320f2f4dae + 841c4c7da73a508427dfb3a90b2c59b3681ef41e59f900fd606e1f989cabb594 + 28ec62bc298653d7c86c1213cb32273bae261208963323424de0d4d07d9063b6 + dafd4d59a3ae233ac7f641bd4c1fe88b2ab375bb1c1b88c7625d9d2a7f37cfff + 25bc0bb64e005e9c6f375efd9dcbb0c239d116c702d8368d3c5af8a68e236e71 + 52ea5e16428e6886d014a1a05d152d0a8a17e37f7647dee695bccb912ca17033 + bdb96dd72ff08c6fa1529560cf08e15158404cf2ef9d460bd0036c710324151e + 1b949d425d015d0a62ce0a958be6d03e144bec2605b079343c7a005fcbfab30b + 3521feaad6417594d33b42bfe32943b96583658758169be97321682913d16960 + aef64a56cc2759f55d9cc5cb82d217527bfe2bbce2d9869ec4ae092a9a722496 + f1d0fd24ff2e69cd84621601f1db49d445be6b66c4df2057ec5173fa9a80f1c1 + 2885174b1b525b942983ef1996261bd738574264678e2fe6ef4fb3c5ebfdae1e + 5e3cc64dbe8d5fafc1232562bdab44c3d6cfd093e7333483cb8ad3ea0f99655c + 2155aee7f8bb8404163775943bfe77011b82227e2afc1289ed3bb5b27ffd548e + a963f95832050b693c9e09b045732412e6a057bc3ed2609c970e0948065dd32a + 7bf670e11b18deadf0a3a637057e980c435973628b3ac209fe559d3c22ec7127 + e77a27afcfad4d7d0ec9ccda6fbb364116fc60d3611102552a68666f034a1e72 + e93fe5b5f51d4d7b1a03dfe33c5593a32d10e3cc7ae18eaf3fe51945a5671920 + 3ed1770d00e5c581bd3aa13feaf83dd575cda47ab53bc5729dc55d6bb86b5523 + 14330c5cb4c576701606f0934594388f185d5a966556d8238a42b989a9d10c44 + 61f66e25b682bf4b4ddc1c3337767984f088d1c3558651469417f2e6eb0a7669 + ab03d30040c604b07b577793d827edc4b555b07c54c095f0f96463401b0a4668 + 986316ee1b41e0f69616a9b6be5753da15dfcb91081d1eaa906ed48c728054f6 + 8706795aab0d52294cdf3f2d30051b6ad67f7ad3dcb89d8401b2c695115c17f4 + 0edfecffcb79ac9a47ec20b0a7d5b252027e134c97eb93ae8a22fe5aa8463b4a + 82632d2b4726820a14bbb277eeb55fdb41563987213d1a2e9fe634680827dffa + 7767d47859a9e5487906dab6fdb2cb915196381ecd6e7c64b625fe4d2a0d5292 + ddcbb55d8a5ec3cf1d84ed2ba6ecb7cd58d2891956431ec530e771246b2f3b39 + 5d4a84599d64e47ab4bbb0a71a5d5db8d7303ee1e29e38ecc4c56f54e40a0238 + c5ded9f79e0c9bd529e173f6d1fb10194150e1a60628ea2b073ebf04f51a6ff0 + 19cf809bf7cc6eb8f986978c8cb46cc307ceb394bbcad2e1431de10a061061ba + c7b86cb56c01d45c65aea2e6d86560a10fdb6aa61dffac819519a8eac23a86f5 + 2d411ea972529ca82958e0d391482cefa065bc639f6f9a93229191301041f6ab + a5fa539bb322690d4bc65a81923bf276f51affb7b90cf02bed7a5f685d5e6f3a + 18a8c092190535c49821c3f6a938e3fd617066bed78989e512910f9a98592ff6 + f7654c4e0b358dd26e0edfaf02713af4cc6048f32008a756300cdb86ba9958f3 + 5f58c003bbb259350c6b8dd9f9bb125dac584df0d29b3810909b2bceeef320b6 + b1f22d1634febda1fd3e89ff5eb66f5a8b3b1c8a1afad136ee320c33f734ae00 + 78e353f1db4e925b13e66d81419c7806c9164cd5647141f87385b9a660a483a5 + 904893210b3e90c74efe3c8e1c00501dd9e52fca1a33bbfe5d32028c1c1de62c + 3b3c350fb90155ac27f3de2b5005f913ade861a7bae516d679f720cb497d5feb + 6bc6a9b95f2bdb2810c4843023bf6903640d370c72b2ace0edcabc12359d2126 + 7db65e3290978690a76a49dd02cf81af3d22f1cf46069243e4f80ff32ffa1088 + b2e52c5c0ac9c311612070c5f2f444c17511ad5cc5f8a3b9c1aa4690c44770f1 + 0f8783aa62d81c316104c4f3f0c146d48ce6ac3530cfa539e20fbcb7e45ec91c + 181e3b11576c9ff3c98c70f4a8016ad3bed6ccb23b9953ff3044f5d9b477a98e + cf8f1cc9a681ef9b4845e01e7dc2e45f215081c25fe82bffba19fb268665df49 + 131ed6c850a7a033c98f29e3c13c6407aa7d722ba5fedb7f983a7effc2445119 + 27aacaaf0550a2d2fd9f200b1517c03e043ce1af75438ece0e9cc4a5c6894eed + 1d499db8ac89406b6ea8a17b95deb7e520fef695e8ea42f8ade4603deb9c9b33 + e80490f499a3f32c2319b0995b33ff37cec2dd2cc9fe21e39cd1419315592edf + 827bb7710b1ddebac9a7fa11864f1166699a84f3747a638b788a6b906dfb29e1 + 5611ba980ec43b905e7b9aa04e0c6009ba686f910f084747896c3491b2eac9b9 + 8d6ef652184a869cb5611af86adef1255dc25a5ef5ee89a9af5abac60f7b83f7 + 70d7e264b037c0ea887b6a558293bfaeb531720b9eaaa036032d776186c39520 + 1fd05a3f42006131f95d711ed042f423362cc75ea9eb524a84a0d9a746dac69e + 2199cb358ae9fa24ed90a93e1a47635d9fa399dcbff82f824eab7fbf143896d4 + 3a2800f50b5720c4e0c80efd926e9ffe32a4d182bf3a6fe3ab3fe04882d1a780 + ffeae211ed6efc624e867ce1985cc707fdc5a6376dc635e9b4fb090bf3464e31 + 82b10fd1ff32066c086f6ec98c068feed4c9adbc72ecad0efe72c918668e4ba8 + d99298715ef9f1d9b888c757307595efd89473b3d7b6dbfa80a0f5f4c5d9a05a + 543e12ee1fa3a0c42695363576a4a3d89b1a6907b9efeefcd9f15ba78af90e86 + 8c8d8eade2bee44ce34b469c962d85a17fc806b0ef9c4b2dd71fbb019886c641 + 1ece4b9f3500f436dcaf1fd488d2caf6db71db5b4792c317c4718ecbc209f432 + 3cb1fb4dce1d8ec0859bfe144139c5b566678b345a95b99518e6a0195bc3f46b + ba7203d7a9a9d7b3f0f8ad73b3d53c095c7d58b8ad8dc3cffd92f46d1ad89f64 + cb982965b56c67cef270ecc6ad4a8ee3e3e13f20b173546e70ce8e27f775154d + 009897b3dff49bd5e3f6b140cbd731b3953bec9c8c89da9cb56abe6423d7b070 + cdfd9281e28e327d10f503a7f2c6b7c7c677b4f26368b1efd2862dd8efa2b785 + 6134803da459c6438236c1d1f5a0b97b9b0fd7410830fff31b403e08cfd0a84b + ccb079ba9782b829d1c5faeae2b35a9dd07b86997b47c90b42430c3fba35a1da + 0493fcfb205cb4d00d8e4078597cbd2b41e188ee5809ae36f6d2d8f485459847 + a96a82919ecb20dee0869ad9116ef793b8460ff4fe164e63dd1093521153fd5a + 8dabd013ec7b634db648f37f3d9ef0069d235fc651db9950d96e5c49557aa14c + 666bd953784ef9d0730367f0b0ca5b8c4be1869af16cafce944ae52935e287d7 + f77883d4792fe2f9080d4ee8338ea378d9d7f7e7b2f4ec5f0dcdc333c6b03d84 + 2aaa7f8157dfbff66b7d037686c34837723eec54233e0dd41b8e5451be015a29 + 722bc2daf5fa6220cc20ab54acd92c30f93538e200b0444ba25e5e6456636491"