diff --git a/packages/emscripten/build.sh b/packages/emscripten/build.sh index bb738170b6..fdcb8e3a12 100644 --- a/packages/emscripten/build.sh +++ b/packages/emscripten/build.sh @@ -2,18 +2,21 @@ TERMUX_PKG_HOMEPAGE=https://emscripten.org TERMUX_PKG_DESCRIPTION="Emscripten: An LLVM-to-WebAssembly Compiler" TERMUX_PKG_LICENSE="MIT" TERMUX_PKG_MAINTAINER="@termux" -TERMUX_PKG_VERSION="3.1.56" +TERMUX_PKG_VERSION="3.1.57" TERMUX_PKG_SRCURL=git+https://github.com/emscripten-core/emscripten TERMUX_PKG_GIT_BRANCH=${TERMUX_PKG_VERSION} -TERMUX_PKG_PLATFORM_INDEPENDENT=true -TERMUX_PKG_DEPENDS="emscripten-binaryen, emscripten-llvm" -TERMUX_PKG_RECOMMENDS="nodejs-lts | nodejs, python" +TERMUX_PKG_DEPENDS="nodejs-lts | nodejs, python" +TERMUX_PKG_ANTI_BUILD_DEPENDS="nodejs, nodejs-lts, python" TERMUX_PKG_HOSTBUILD=true TERMUX_PKG_NO_STATICSPLIT=true +TERMUX_PKG_PLATFORM_INDEPENDENT=true TERMUX_PKG_AUTO_UPDATE=true -# remove files according to emsdk/upstream directory after running +# remove files according to emsdk/upstream directory +# git clone https://github.com/emscripten-core/emsdk --depth=1 +# cd emsdk # ./emsdk install latest +# ls ./upstream/bin/* TERMUX_PKG_RM_AFTER_INSTALL=" opt/emscripten-llvm/bin/amdgpu-arch opt/emscripten-llvm/bin/clang-check @@ -23,6 +26,7 @@ opt/emscripten-llvm/bin/clang-extdef-mapping opt/emscripten-llvm/bin/clang-format opt/emscripten-llvm/bin/clang-func-mapping opt/emscripten-llvm/bin/clang-import-test +opt/emscripten-llvm/bin/clang-installapi opt/emscripten-llvm/bin/clang-linker-wrapper opt/emscripten-llvm/bin/clang-nvlink-wrapper opt/emscripten-llvm/bin/clang-offload-bundler @@ -41,12 +45,14 @@ opt/emscripten-llvm/bin/ld64.lld opt/emscripten-llvm/bin/ld64.lld.darwin* opt/emscripten-llvm/bin/lld-link opt/emscripten-llvm/bin/llvm-cov +opt/emscripten-llvm/bin/llvm-dlltool opt/emscripten-llvm/bin/llvm-lib +opt/emscripten-llvm/bin/llvm-link +opt/emscripten-llvm/bin/llvm-mca opt/emscripten-llvm/bin/llvm-ml opt/emscripten-llvm/bin/llvm-pdbutil opt/emscripten-llvm/bin/llvm-profdata opt/emscripten-llvm/bin/llvm-rc -opt/emscripten-llvm/bin/llvm-strings opt/emscripten-llvm/bin/nvptx-arch opt/emscripten-llvm/lib/libclang.so* opt/emscripten-llvm/share @@ -55,13 +61,13 @@ opt/emscripten/LICENSE # https://github.com/emscripten-core/emscripten/issues/11362 # can switch to stable LLVM to save space once above is fixed -_LLVM_COMMIT=34ba90745fa55777436a2429a51a3799c83c6d4c -_LLVM_TGZ_SHA256=ec54a5c05e4c4a971ca5392bc114f740ec9ed3274f6432f00b2273f84cc0abd0 +_LLVM_COMMIT=ccdebbae4d77d3efc236af92c22941de5d437e01 +_LLVM_TGZ_SHA256=32a4416ae815be3622de7501011d3f67a5ffe86e15072aa22e613aed5340ce98 # https://github.com/emscripten-core/emscripten/issues/12252 # upstream says better bundle the right binaryen revision for now -_BINARYEN_COMMIT=6e8fefe1ea13346f8908075d1f35b23317cfcc0f -_BINARYEN_TGZ_SHA256=2c067e2e474123ad6e84b6530c18e1f11a002dd08981b1bea5ea93baf4390551 +_BINARYEN_COMMIT=f0dd9941de2df62e0a29f2faeadf007e37a425a9 +_BINARYEN_TGZ_SHA256=32b12fcb4bc96e3d43e329b90f617993c90150c5414f950fe4f65b1b9cd0251e # https://github.com/emscripten-core/emsdk/blob/main/emsdk.py # https://chromium.googlesource.com/emscripten-releases/+/refs/heads/main/src/build.py @@ -146,11 +152,12 @@ termux_pkg_auto_update() { _BINARYEN_COMMIT ${binaryen_commit} = ${binaryen_tgz_sha256} EOL - sed -i "${TERMUX_PKG_BUILDER_DIR}/build.sh" \ + sed \ -e "s|^_LLVM_COMMIT=.*|_LLVM_COMMIT=${llvm_commit}|" \ -e "s|^_LLVM_TGZ_SHA256=.*|_LLVM_TGZ_SHA256=${llvm_tgz_sha256}|" \ -e "s|^_BINARYEN_COMMIT=.*|_BINARYEN_COMMIT=${binaryen_commit}|" \ - -e "s|^_BINARYEN_TGZ_SHA256=.*|_BINARYEN_TGZ_SHA256=${binaryen_tgz_sha256}|" + -e "s|^_BINARYEN_TGZ_SHA256=.*|_BINARYEN_TGZ_SHA256=${binaryen_tgz_sha256}|" \ + -i "${TERMUX_PKG_BUILDER_DIR}/build.sh" rm -fr "${tmpdir}" @@ -169,7 +176,7 @@ termux_step_post_get_source() { tar -xf "${TERMUX_PKG_CACHEDIR}/llvm.tar.gz" -C "${TERMUX_PKG_CACHEDIR}" tar -xf "${TERMUX_PKG_CACHEDIR}/binaryen.tar.gz" -C "${TERMUX_PKG_CACHEDIR}" - local llvm_patches=$(find "${TERMUX_PKG_BUILDER_DIR}" -mindepth 1 -maxdepth 1 -type f -name 'llvm-project-*.patch.diff') + local llvm_patches=$(find "${TERMUX_PKG_BUILDER_DIR}" -mindepth 1 -maxdepth 1 -type f -name 'llvm-project-*.diff') if [[ -n "${llvm_patches}" ]]; then pushd "${TERMUX_PKG_CACHEDIR}/llvm-project-${_LLVM_COMMIT}" for patch in ${llvm_patches}; do @@ -187,7 +194,7 @@ termux_step_post_get_source() { popd fi - local binaryen_patches=$(find "${TERMUX_PKG_BUILDER_DIR}" -mindepth 1 -maxdepth 1 -type f -name 'binaryen-*.patch.diff') + local binaryen_patches=$(find "${TERMUX_PKG_BUILDER_DIR}" -mindepth 1 -maxdepth 1 -type f -name 'binaryen-*.diff') if [[ -n "${binaryen_patches}" ]]; then pushd "${TERMUX_PKG_CACHEDIR}/binaryen-${_BINARYEN_COMMIT}" for patch in ${binaryen_patches}; do @@ -226,6 +233,9 @@ termux_step_host_build() { } termux_step_pre_configure() { + # this is a workaround for build-all.sh issue + TERMUX_PKG_DEPENDS+=", emscripten-binaryen, emscripten-llvm" + # https://github.com/termux/termux-packages/issues/16358 # TODO libclang-cpp.so* is not affected if [[ "${TERMUX_ON_DEVICE_BUILD}" == "true" ]]; then @@ -305,11 +315,12 @@ termux_step_make_install() { # first run generates .emscripten and exits immediately rm -f "${TERMUX_PKG_SRCDIR}/.emscripten" ./emcc --generate-config - sed -i .emscripten \ + sed \ -e "s|^EMSCRIPTEN_ROOT.*|EMSCRIPTEN_ROOT = '${TERMUX_PREFIX}/opt/emscripten' # directory|" \ -e "s|^LLVM_ROOT.*|LLVM_ROOT = '${TERMUX_PREFIX}/opt/emscripten-llvm/bin' # directory|" \ -e "s|^BINARYEN_ROOT.*|BINARYEN_ROOT = '${TERMUX_PREFIX}/opt/emscripten-binaryen' # directory|" \ - -e "s|^NODE_JS.*|NODE_JS = '${TERMUX_PREFIX}/bin/node' # executable|" + -e "s|^NODE_JS.*|NODE_JS = '${TERMUX_PREFIX}/bin/node' # executable|" \ + -i .emscripten grep "${TERMUX_PREFIX}" "${TERMUX_PKG_SRCDIR}/.emscripten" install -Dm644 "${TERMUX_PKG_SRCDIR}/.emscripten" "${TERMUX_PREFIX}/opt/emscripten/.emscripten" diff --git a/packages/emscripten/emscripten-binaryen.subpackage.sh b/packages/emscripten/emscripten-binaryen.subpackage.sh index d5ab2135ca..9b5202d38d 100644 --- a/packages/emscripten/emscripten-binaryen.subpackage.sh +++ b/packages/emscripten/emscripten-binaryen.subpackage.sh @@ -1,4 +1,5 @@ TERMUX_SUBPKG_DESCRIPTION="Emscripten-compatible Binaryen" TERMUX_SUBPKG_DEPENDS="libc++" +TERMUX_SUBPKG_DEPEND_ON_PARENT=no TERMUX_SUBPKG_PLATFORM_INDEPENDENT=false TERMUX_SUBPKG_INCLUDE="opt/emscripten-binaryen" diff --git a/packages/emscripten/emscripten-llvm.subpackage.sh b/packages/emscripten/emscripten-llvm.subpackage.sh index 992e28ede6..3fa2a20add 100644 --- a/packages/emscripten/emscripten-llvm.subpackage.sh +++ b/packages/emscripten/emscripten-llvm.subpackage.sh @@ -1,4 +1,5 @@ TERMUX_SUBPKG_DESCRIPTION="Emscripten-compatible LLVM" TERMUX_SUBPKG_DEPENDS="libc++" +TERMUX_SUBPKG_DEPEND_ON_PARENT=no TERMUX_SUBPKG_PLATFORM_INDEPENDENT=false TERMUX_SUBPKG_INCLUDE="opt/emscripten-llvm" diff --git a/packages/emscripten/emscripten-tests-third-party.subpackage.sh b/packages/emscripten/emscripten-tests-third-party.subpackage.sh index c7cdb447a0..30d8ed06ae 100644 --- a/packages/emscripten/emscripten-tests-third-party.subpackage.sh +++ b/packages/emscripten/emscripten-tests-third-party.subpackage.sh @@ -1,3 +1,4 @@ TERMUX_SUBPKG_DESCRIPTION="Emscripten third party test suite files" +TERMUX_SUBPKG_DEPEND_ON_PARENT=no TERMUX_SUBPKG_PLATFORM_INDEPENDENT=true TERMUX_SUBPKG_INCLUDE="opt/emscripten/test/third_party" diff --git a/packages/emscripten/llvm-project-clang-lib-Driver-ToolChain.cpp.diff b/packages/emscripten/llvm-project-clang-lib-Driver-ToolChain.cpp.diff new file mode 100644 index 0000000000..e0a206aaa2 --- /dev/null +++ b/packages/emscripten/llvm-project-clang-lib-Driver-ToolChain.cpp.diff @@ -0,0 +1,11 @@ +--- a/clang/lib/Driver/ToolChain.cpp ++++ b/clang/lib/Driver/ToolChain.cpp +@@ -1282,7 +1282,7 @@ + + switch (Type) { + case ToolChain::CST_Libcxx: +- CmdArgs.push_back("-lc++"); ++ CmdArgs.push_back("-lc++_shared"); + if (Args.hasArg(options::OPT_fexperimental_library)) + CmdArgs.push_back("-lc++experimental"); + break; diff --git a/packages/emscripten/llvm-project-clang-lib-Driver-ToolChain.cpp.patch.diff b/packages/emscripten/llvm-project-clang-lib-Driver-ToolChain.cpp.patch.diff deleted file mode 100644 index 1ab1035242..0000000000 --- a/packages/emscripten/llvm-project-clang-lib-Driver-ToolChain.cpp.patch.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff -uNr llvm-project/clang/lib/Driver/ToolChain.cpp llvm-project.mod/clang/lib/Driver/ToolChain.cpp ---- llvm-project/clang/lib/Driver/ToolChain.cpp 2022-07-22 22:56:15.000000000 +0800 -+++ llvm-project.mod/clang/lib/Driver/ToolChain.cpp 2022-07-23 14:50:06.701119073 +0800 -@@ -1012,7 +1012,7 @@ - - switch (Type) { - case ToolChain::CST_Libcxx: -- CmdArgs.push_back("-lc++"); -+ CmdArgs.push_back("-lc++_shared"); - if (Args.hasArg(options::OPT_fexperimental_library)) - CmdArgs.push_back("-lc++experimental"); - break; diff --git a/packages/emscripten/llvm-project-clang-lib-Driver-ToolChains-Linux.cpp.patch.diff b/packages/emscripten/llvm-project-clang-lib-Driver-ToolChains-Linux.cpp.diff similarity index 79% rename from packages/emscripten/llvm-project-clang-lib-Driver-ToolChains-Linux.cpp.patch.diff rename to packages/emscripten/llvm-project-clang-lib-Driver-ToolChains-Linux.cpp.diff index c756f6a6cc..e82dc23f6e 100644 --- a/packages/emscripten/llvm-project-clang-lib-Driver-ToolChains-Linux.cpp.patch.diff +++ b/packages/emscripten/llvm-project-clang-lib-Driver-ToolChains-Linux.cpp.diff @@ -1,7 +1,6 @@ -diff -uNr llvm-project/clang/lib/Driver/ToolChains/Linux.cpp llvm-project.mod/clang/lib/Driver/ToolChains/Linux.cpp ---- llvm-project/clang/lib/Driver/ToolChains/Linux.cpp 2022-06-20 05:49:00.000000000 +0800 -+++ llvm-project.mod/clang/lib/Driver/ToolChains/Linux.cpp 2022-06-28 23:43:47.540674027 +0800 -@@ -164,8 +164,8 @@ +--- a/clang/lib/Driver/ToolChains/Linux.cpp ++++ b/clang/lib/Driver/ToolChains/Linux.cpp +@@ -200,8 +200,8 @@ // FIXME: This is a bit of a hack. We should really unify this code for // reasoning about oslibdir spellings with the lib dir spellings in the // GCCInstallationDetector, but that is a more significant refactoring. @@ -12,7 +11,7 @@ diff -uNr llvm-project/clang/lib/Driver/ToolChains/Linux.cpp llvm-project.mod/cl return "lib32"; if (Triple.getArch() == llvm::Triple::x86_64 && Triple.isX32()) -@@ -297,7 +297,7 @@ +@@ -333,7 +333,7 @@ if (Triple.getVendor() == llvm::Triple::OpenEmbedded && Triple.isArch64Bit()) addPathIfExists(D, concat(SysRoot, "/usr", OSLibDir), Paths); @@ -21,8 +20,8 @@ diff -uNr llvm-project/clang/lib/Driver/ToolChains/Linux.cpp llvm-project.mod/cl addPathIfExists(D, concat(SysRoot, "/usr/lib/..", OSLibDir), Paths); if (IsRISCV) { StringRef ABIName = tools::riscv::getRISCVABI(Args, Triple); -@@ -315,7 +315,15 @@ - addPathIfExists(D, D.Dir + "/../lib", Paths); +@@ -344,7 +344,15 @@ + Generic_GCC::AddMultiarchPaths(D, SysRoot, OSLibDir, Paths); addPathIfExists(D, concat(SysRoot, "/lib"), Paths); - addPathIfExists(D, concat(SysRoot, "/usr/lib"), Paths); diff --git a/packages/emscripten/llvm-project-compiler-rt-CMakeLists.txt.patch.diff b/packages/emscripten/llvm-project-compiler-rt-CMakeLists.txt.diff similarity index 76% rename from packages/emscripten/llvm-project-compiler-rt-CMakeLists.txt.patch.diff rename to packages/emscripten/llvm-project-compiler-rt-CMakeLists.txt.diff index 462c50dad7..82536fd3f9 100644 --- a/packages/emscripten/llvm-project-compiler-rt-CMakeLists.txt.patch.diff +++ b/packages/emscripten/llvm-project-compiler-rt-CMakeLists.txt.diff @@ -1,7 +1,6 @@ -diff -uNr llvm-project/compiler-rt/CMakeLists.txt llvm-project.mod/compiler-rt/CMakeLists.txt ---- llvm-project/compiler-rt/CMakeLists.txt 2022-07-22 22:56:15.000000000 +0800 -+++ llvm-project.mod/compiler-rt/CMakeLists.txt 2022-07-23 14:45:26.423586698 +0800 -@@ -187,6 +187,9 @@ +--- a/compiler-rt/CMakeLists.txt ++++ b/compiler-rt/CMakeLists.txt +@@ -203,6 +203,9 @@ elseif (FUCHSIA) set(${var}_LIBNAME "libc++") set(${var}_INTREE 1) @@ -11,7 +10,7 @@ diff -uNr llvm-project/compiler-rt/CMakeLists.txt llvm-project.mod/compiler-rt/C else() set(${var}_LIBNAME "libstdc++") set(${var}_SYSTEM 1) -@@ -202,7 +205,7 @@ +@@ -218,7 +221,7 @@ # TODO: Mark this as internal flag, most users should use COMPILER_RT_CXX_LIBRARY. set(SANITIZER_CXX_ABI "default" CACHE STRING "Specify C++ ABI library to use.") @@ -20,7 +19,7 @@ diff -uNr llvm-project/compiler-rt/CMakeLists.txt llvm-project.mod/compiler-rt/C set_property(CACHE SANITIZER_CXX_ABI PROPERTY STRINGS ;${CXXABIS}) handle_default_cxx_lib(SANITIZER_CXX_ABI) -@@ -594,6 +597,8 @@ +@@ -639,6 +642,8 @@ list(APPEND SANITIZER_CXX_ABI_LIBRARIES "c++abi") elseif (SANITIZER_CXX_ABI_LIBNAME STREQUAL "libstdc++") append_list_if(COMPILER_RT_HAS_LIBSTDCXX stdc++ SANITIZER_CXX_ABI_LIBRARIES) diff --git a/packages/emscripten/llvm-project-compiler-rt-lib-builtins-CMakeLists.txt.patch.diff b/packages/emscripten/llvm-project-compiler-rt-lib-builtins-CMakeLists.txt.diff similarity index 54% rename from packages/emscripten/llvm-project-compiler-rt-lib-builtins-CMakeLists.txt.patch.diff rename to packages/emscripten/llvm-project-compiler-rt-lib-builtins-CMakeLists.txt.diff index 70137287b7..e33541a62d 100644 --- a/packages/emscripten/llvm-project-compiler-rt-lib-builtins-CMakeLists.txt.patch.diff +++ b/packages/emscripten/llvm-project-compiler-rt-lib-builtins-CMakeLists.txt.diff @@ -1,7 +1,6 @@ -diff -uNr llvm-project/compiler-rt/lib/builtins/CMakeLists.txt llvm-project.mod/compiler-rt/lib/builtins/CMakeLists.txt ---- llvm-project/compiler-rt/lib/builtins/CMakeLists.txt 2022-06-20 05:49:00.000000000 +0800 -+++ llvm-project.mod/compiler-rt/lib/builtins/CMakeLists.txt 2022-06-28 23:33:05.436005528 +0800 -@@ -752,6 +752,8 @@ +--- a/compiler-rt/lib/builtins/CMakeLists.txt ++++ b/compiler-rt/lib/builtins/CMakeLists.txt +@@ -846,6 +846,8 @@ # Release mode already sets it via -O2/3, Debug mode doesn't. if (${arch} STREQUAL "armhf") list(APPEND BUILTIN_CFLAGS_${arch} -fomit-frame-pointer -DCOMPILER_RT_ARMHF_TARGET) diff --git a/packages/emscripten/llvm-project-libunwind-CMakeLists.txt.patch.diff b/packages/emscripten/llvm-project-libunwind-CMakeLists.txt.diff similarity index 52% rename from packages/emscripten/llvm-project-libunwind-CMakeLists.txt.patch.diff rename to packages/emscripten/llvm-project-libunwind-CMakeLists.txt.diff index c48b30d342..318ed5681b 100644 --- a/packages/emscripten/llvm-project-libunwind-CMakeLists.txt.patch.diff +++ b/packages/emscripten/llvm-project-libunwind-CMakeLists.txt.diff @@ -1,7 +1,6 @@ -diff -uNr llvm-project/libunwind/CMakeLists.txt llvm-project.mod/libunwind/CMakeLists.txt ---- llvm-project/libunwind/CMakeLists.txt 2022-06-20 05:49:00.000000000 +0800 -+++ llvm-project.mod/libunwind/CMakeLists.txt 2022-06-28 23:33:05.439005615 +0800 -@@ -159,6 +159,10 @@ +--- a/libunwind/CMakeLists.txt ++++ b/libunwind/CMakeLists.txt +@@ -176,6 +176,10 @@ add_compile_flags_if_supported(-Werror=return-type) if (LIBUNWIND_ENABLE_CET) @@ -11,4 +10,4 @@ diff -uNr llvm-project/libunwind/CMakeLists.txt llvm-project.mod/libunwind/CMake + endif() add_compile_flags_if_supported(-fcf-protection=full) add_compile_flags_if_supported(-mshstk) - if (NOT LIBUNWIND_SUPPORTS_FCF_PROTECTION_EQ_FULL_FLAG) + if (NOT CXX_SUPPORTS_FCF_PROTECTION_EQ_FULL_FLAG) diff --git a/packages/emscripten/llvm-project-llvm-tools-llvm-exegesis-lib-SubprocessMemory.cpp.diff b/packages/emscripten/llvm-project-llvm-tools-llvm-exegesis-lib-SubprocessMemory.cpp.diff new file mode 100644 index 0000000000..643b3ec638 --- /dev/null +++ b/packages/emscripten/llvm-project-llvm-tools-llvm-exegesis-lib-SubprocessMemory.cpp.diff @@ -0,0 +1,22 @@ +--- a/llvm/tools/llvm-exegesis/lib/SubprocessMemory.cpp ++++ b/llvm/tools/llvm-exegesis/lib/SubprocessMemory.cpp +@@ -22,7 +22,7 @@ + namespace llvm { + namespace exegesis { + +-#if defined(__linux__) && !defined(__ANDROID__) ++#if defined(__linux__) + + long SubprocessMemory::getCurrentTID() { + // We're using the raw syscall here rather than the gettid() function provided +@@ -31,6 +31,10 @@ + return syscall(SYS_gettid); + } + ++#endif ++ ++#if defined(__linux__) && !defined(__ANDROID__) ++ + Error SubprocessMemory::initializeSubprocessMemory(pid_t ProcessID) { + // Add the PID to the shared memory name so that if we're running multiple + // processes at the same time, they won't interfere with each other. diff --git a/packages/emscripten/llvm-project-llvm-tools-llvm-rtdyld-llvm-rtdyld.cpp.patch.diff b/packages/emscripten/llvm-project-llvm-tools-llvm-rtdyld-llvm-rtdyld.cpp.diff similarity index 80% rename from packages/emscripten/llvm-project-llvm-tools-llvm-rtdyld-llvm-rtdyld.cpp.patch.diff rename to packages/emscripten/llvm-project-llvm-tools-llvm-rtdyld-llvm-rtdyld.cpp.diff index bf3bbd7f99..ed4c71e089 100644 --- a/packages/emscripten/llvm-project-llvm-tools-llvm-rtdyld-llvm-rtdyld.cpp.patch.diff +++ b/packages/emscripten/llvm-project-llvm-tools-llvm-rtdyld-llvm-rtdyld.cpp.diff @@ -1,6 +1,5 @@ -diff -uNr llvm-project/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp llvm-project.mod/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp ---- llvm-project/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp 2022-06-20 05:49:00.000000000 +0800 -+++ llvm-project.mod/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp 2022-06-28 23:33:05.451005964 +0800 +--- a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp ++++ b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -285,7 +285,7 @@ uintptr_t SlabSize = 0; uintptr_t CurrentSlabOffset = 0;