[3rd] prebuilt v8 #1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: '[3rd] prebuilt v8' | |
on: | |
workflow_dispatch: | |
inputs: | |
v8_revision: | |
description: 'V8 TAG(Branch) to build' | |
type: string | |
required: true | |
build_args: | |
description: 'Build args' | |
type: string | |
default: 'v8_use_external_startup_data=false v8_enable_i18n_support=false treat_warnings_as_errors=false symbol_level=1 v8_enable_webassembly=false' | |
required: true | |
build_type: | |
description: 'Build type' | |
type: choice | |
options: | |
- debug | |
- release | |
default: 'release' | |
required: true | |
hip_v8_root: | |
description: 'HIP V8 root path' | |
type: string | |
default: 'global_packages' | |
required: true | |
writing_mode: | |
description: 'The mode of writing' | |
type: choice | |
options: | |
- preserve | |
- overwrite | |
default: 'preserve' | |
required: true | |
is_build_for_android: | |
description: 'Build for Android platform' | |
type: boolean | |
default: true | |
required: false | |
is_build_for_ios: | |
description: 'Build for iOS platform' | |
type: boolean | |
default: false | |
required: false | |
is_build_for_windows: | |
description: 'Build for Windows platform' | |
type: boolean | |
default: false | |
required: false | |
is_build_for_macos: | |
description: 'Build for MacOS platform' | |
type: boolean | |
default: false | |
required: false | |
is_build_for_linux: | |
description: 'Build for Linux platform' | |
type: boolean | |
default: false | |
required: false | |
env: | |
publish_package_script: | | |
from qcloud_cos import CosS3Client, CosConfig | |
import hashlib | |
import os | |
try: | |
from urllib.parse import urlencode | |
except ImportError: | |
from urllib import urlencode | |
metadata = {} | |
metadata["ci-name"] = "Github Action" | |
metadata["ci-id"] = "${{ github.run_id }}" | |
metadata["ci-url"] = "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" | |
metadata["v8-builder"] = "${{ github.event.sender.login }}" | |
with open(os.environ["local_file"], "rb") as artifact_file: | |
metadata["v8-md5"] = hashlib.md5(artifact_file.read()).hexdigest() | |
metadata["v8-revision"] = "${{ github.event.inputs.v8_revision }}" | |
metadata["v8-head"] = os.environ["v8_head"] | |
config = CosConfig(Region="${{ secrets.COS_REGION }}", SecretId="${{ secrets.TC_SECRET_ID }}", SecretKey="${{ secrets.TC_SECRET_KEY }}") | |
client = CosS3Client(config) | |
if "${{ github.event.inputs.writing_mode }}" == "preserve" and client.object_exists( | |
Bucket="${{ secrets.COS_BUCKET }}", | |
Key=os.environ["cos_key"] | |
): | |
raise Exception("Package already exists") | |
response = client.upload_file( | |
Bucket="${{ secrets.COS_BUCKET }}", | |
Key=os.environ["cos_key"], | |
LocalFilePath=os.environ["local_file"], | |
EnableMD5=True, | |
ContentMD5=metadata["v8-md5"], | |
Metadata={"x-cos-tagging": urlencode(metadata)} | |
) | |
print("ETag: " + response["ETag"]) | |
cmakelists_template: | | |
# | |
# Tencent is pleased to support the open source community by making | |
# Hippy available. | |
# | |
# Copyright (C) 2022 THL A29 Limited, a Tencent company. | |
# All rights reserved. | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
# | |
cmake_minimum_required(VERSION 3.0) | |
project(v8) | |
add_library(${{ '${{PROJECT_NAME}}' }} INTERFACE) | |
target_include_directories(${{ '${{PROJECT_NAME}}' }} | |
INTERFACE "include" | |
INTERFACE "include/v8") | |
target_compile_definitions(${{ '${{PROJECT_NAME}}' }} | |
INTERFACE "-DV8_IMMINENT_DEPRECATION_WARNINGS" | |
INTERFACE "-DV8_DEPRECATION_WARNINGS" | |
{0}) | |
add_library(${{ '${{PROJECT_NAME}}' }}_library STATIC IMPORTED) | |
set_property(TARGET ${{ '${{PROJECT_NAME}}' }}_library PROPERTY | |
IMPORTED_LOCATION "{1}") | |
target_link_libraries(${{ '${{PROJECT_NAME}}' }} | |
INTERFACE ${{ '${{PROJECT_NAME}}' }}_library) | |
jobs: | |
context_in_lowercase: | |
if: github.event.inputs.is_build_for_android == 'true' || github.event.inputs.is_build_for_linux == 'true' | |
runs-on: ubuntu-latest | |
outputs: | |
repository_owner: ${{ steps.get_owner.outputs.lowercase }} | |
steps: | |
- name: Get repo owner(in lowercase) | |
id: get_owner | |
uses: ASzc/change-string-case-action@v2 | |
with: | |
string: ${{ github.repository_owner }} | |
android_prebuilt: | |
if: github.event.inputs.is_build_for_android == 'true' | |
needs: context_in_lowercase | |
runs-on: [self-hosted, linux, shared] | |
container: | |
image: ghcr.io/${{ needs.context_in_lowercase.outputs.repository_owner }}/android-release:latest | |
strategy: | |
matrix: | |
cpu: [arm, arm64, x86, x64] | |
include: | |
- cpu: arm | |
arch: arm | |
- cpu: arm64 | |
arch: arm64 | |
- cpu: x86 | |
arch: x86 | |
- cpu: x64 | |
arch: x86_64 | |
steps: | |
- name: Setup GN | |
run: | | |
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git /usr/local/opt/depot_tools | |
export PATH=/usr/local/opt/depot_tools:$PATH | |
- name: Fetch v8 | |
run: | | |
export PATH=/usr/local/opt/depot_tools:$PATH | |
fetch v8 | |
cd v8 | |
git checkout ${{ github.event.inputs.v8_revision }} | |
- name: Fetch patch | |
uses: actions/checkout@v2 | |
with: | |
path: ${{ github.repository }} | |
- name: Apply patch | |
if: ${{ !startsWith(github.event.inputs.v8_revision, '7.7') }} | |
working-directory: ./v8 | |
continue-on-error: true | |
run: | | |
git apply ../${{ github.repository }}/.github/workflows/tools/v8_remove_requests_revision.patch | |
- name: Sync third_party | |
working-directory: ./v8 | |
run: | | |
echo "target_os = ['android']" >> ../.gclient | |
gclient sync -D | |
- name: Prepare android_ndk | |
if: ${{ startsWith(github.event.inputs.v8_revision, '7.7') }} | |
working-directory: ./v8 | |
run: | | |
if [ -d third_party/android_tools ]; then | |
rm -rf third_party/android_tools | |
mkdir third_party/android_tools | |
ln -s $ANDROID_NDK_HOME third_party/android_tools/ndk | |
fi | |
if [ -f third_party/android_ndk/BUILD.gn ]; then | |
cp third_party/android_ndk/BUILD.gn $ANDROID_NDK_HOME | |
fi | |
if [ -d third_party/android_tools -o -f third_party/android_ndk/BUILD.gn ]; then | |
rm -rf third_party/android_ndk | |
ln -s $ANDROID_NDK_HOME third_party/android_ndk | |
fi | |
- name: Apply 7.7 build patch | |
if: ${{ startsWith(github.event.inputs.v8_revision, '7.7') }} | |
working-directory: ./v8/build | |
run: | | |
git apply ../../${{ github.repository }}/.github/workflows/tools/v8_7_7_229_build.patch | |
- name: Generate ${{ matrix.arch }} | |
working-directory: ./v8 | |
run: | | |
gn gen out --args="target_os=\"android\" target_cpu=\"${{ matrix.cpu }}\" v8_target_cpu=\"${{ matrix.cpu }}\" android_ndk_root=\"${ANDROID_NDK_HOME}\" is_component_build=false v8_monolithic=true android32_ndk_api_level=21 android64_ndk_api_level=21 clang_use_chrome_plugins=false use_thin_lto=false use_custom_libcxx=false ${{ github.event.inputs.build_type == 'release' && 'is_debug=false is_official_build=true' || 'is_debug=true' }} ${{ github.event.inputs.build_args }}" | |
- name: Compile ${{ matrix.arch }} | |
working-directory: ./v8 | |
run: | | |
ninja -C out v8_monolith | |
- name: Prepare package | |
working-directory: ./v8/out | |
run: | | |
mkdir -p artifact/include/v8 artifact/lib | |
cp obj/libv8_monolith.a artifact/lib | |
cp -r ../include/* artifact/include/v8/ | |
cp -r gen/include/* artifact/include/v8/ | |
find artifact/include/v8/. ! -name "*.h" -type f -delete | |
- name: Generate CMakeLists | |
uses: DamianReeves/[email protected] | |
with: | |
path: ./v8/out/artifact/CMakeLists.txt | |
write-mode: overwrite | |
contents: ${{ format(env.cmakelists_template, (!startsWith(github.event.inputs.v8_revision, '7.7') && endsWith(matrix.arch, '64')) && 'INTERFACE "-DV8_COMPRESS_POINTERS"' || '', '${CMAKE_CURRENT_SOURCE_DIR}/lib/libv8_monolith.a') }} | |
- name: Release package | |
id: release_package | |
working-directory: ./v8 | |
run: | | |
echo "head_full=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT | |
cd out | |
tar -zcvf android-${{ matrix.arch }}.tgz -C artifact . | |
- name: Install Requirement | |
shell: bash | |
run: | | |
pip3 install -U cos-python-sdk-v5 | |
- name: Publish package | |
shell: python3 {0} | |
env: | |
local_file: ./v8/out/android-${{ matrix.arch }}.tgz | |
cos_key: hippy/${{ github.event.inputs.hip_v8_root }}/v8/${{ github.event.inputs.v8_revision }}/${{ github.event.inputs.build_type }}/android-${{ matrix.arch }}.tgz | |
v8_head: ${{ steps.release_package.outputs.head_full }} | |
run: ${{ env.publish_package_script }} | |
windows_prebuilt: | |
if: github.event.inputs.is_build_for_windows == 'true' | |
runs-on: windows-2019 | |
strategy: | |
matrix: | |
arch: [x86, x64, arm64] | |
steps: | |
- name: Setup GN | |
run: | | |
Invoke-WebRequest -OutFile depot_tools.zip https://storage.googleapis.com/chrome-infra/depot_tools.zip | |
Expand-Archive depot_tools.zip -DestinationPath C:\depot_tools | |
rm depot_tools.zip | |
choco install ninja | |
- name: Install Clang 15.0.1 | |
id: install-clang | |
uses: KyleMayes/install-llvm-action@v1 | |
with: | |
version: "15.0.1" | |
directory: "./llvm" | |
- name: Checkout v8 | |
run: | | |
$env:DEPOT_TOOLS_WIN_TOOLCHAIN = 0 | |
$env:Path += ";C:\depot_tools" | |
fetch v8 | |
cd v8 | |
git checkout ${{ github.event.inputs.v8_revision }} | |
gclient sync -D | |
- name: Generate ${{ matrix.arch }} | |
working-directory: ./v8 | |
run: | | |
$env:DEPOT_TOOLS_WIN_TOOLCHAIN = 0 | |
$env:Path += ";C:\depot_tools" | |
$llvmPath = $($env:GITHUB_WORKSPACE + "\llvm") | |
& $($llvmPath + "\bin\clang.exe") --version | |
echo $llvmPath | |
gn gen out --args="target_cpu=""""""${{ matrix.arch }}"""""" v8_target_cpu=""""""${{ matrix.arch }}"""""" is_component_build=false v8_monolithic=true use_custom_libcxx=false chrome_pgo_phase=0 ${{ github.event.inputs.build_type == 'release' && 'is_debug=false is_official_build=true clang_use_chrome_plugins=false clang_base_path=""""$llvmPath""""' || 'is_debug=true enable_iterator_debugging=true' }} ${{ github.event.inputs.build_args }}" | |
type out/args.gn | |
- name: Compile ${{ matrix.arch }} | |
working-directory: ./v8 | |
run: | | |
$env:Path += ";C:\depot_tools" | |
ninja -C out v8_monolith | |
- name: Prepare package | |
working-directory: ./v8/out | |
run: | | |
New-Item -type directory -Path artifact/include/v8, artifact/lib | |
Copy-Item obj/v8_monolith.lib artifact/lib | |
Copy-Item -r ../include/* artifact/include/v8/ | |
Copy-Item -r gen/include/* artifact/include/v8/ | |
Get-ChildItem -Exclude *.h -Recurse -File -Path artifact/include/v8 | Remove-Item | |
- name: Generate CMakeLists | |
uses: DamianReeves/[email protected] | |
with: | |
path: ./v8/out/artifact/CMakeLists.txt | |
write-mode: overwrite | |
contents: ${{ format(env.cmakelists_template, endsWith(matrix.arch, '64') && 'INTERFACE "-DV8_COMPRESS_POINTERS"' || '', '${CMAKE_CURRENT_SOURCE_DIR}/lib/v8_monolith.lib') }} | |
- name: Release package | |
id: release_package | |
working-directory: ./v8 | |
run: | | |
Write-Output "head_full=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT | |
cd out | |
Compress-Archive -Path artifact\* -DestinationPath windows-${{ matrix.arch }}.zip | |
- name: Install Requirement | |
shell: bash | |
run: | | |
pip install -U cos-python-sdk-v5 | |
- name: Publish package | |
shell: python | |
env: | |
local_file: ./v8/out/windows-${{ matrix.arch }}.zip | |
cos_key: hippy/${{ github.event.inputs.hip_v8_root }}/v8/${{ github.event.inputs.v8_revision }}/${{ github.event.inputs.build_type }}/windows-${{ matrix.arch }}.zip | |
v8_head: ${{ steps.release_package.outputs.head_full }} | |
run: ${{ env.publish_package_script }} | |
macos_prebuilt: | |
if: github.event.inputs.is_build_for_macos == 'true' | |
runs-on: macos-latest | |
strategy: | |
matrix: | |
arch: [x64, arm64] | |
steps: | |
- name: Setup GN | |
run: | | |
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git /usr/local/opt/depot_tools | |
export PATH=/usr/local/opt/depot_tools:$PATH | |
- name: Checkout v8 | |
run: | | |
export PATH=/usr/local/opt/depot_tools:$PATH | |
fetch v8 | |
cd v8 | |
git checkout ${{ github.event.inputs.v8_revision }} | |
gclient sync -D | |
- name: Generate ${{ matrix.arch }} | |
working-directory: ./v8 | |
run: | | |
export PATH=/usr/local/opt/depot_tools:$PATH | |
gn gen out --args="target_cpu=\"${{ matrix.arch }}\" v8_target_cpu=\"${{ matrix.arch }}\" chrome_pgo_phase=0 is_component_build=false v8_monolithic=true ${{ github.event.inputs.build_type == 'release' && 'is_debug=false is_official_build=true' || 'is_debug=true' }} ${{ github.event.inputs.build_args }}" | |
- name: Compile ${{ matrix.arch }} | |
working-directory: ./v8 | |
run: | | |
export PATH=/usr/local/opt/depot_tools:$PATH | |
ninja -C out v8_monolith | |
- name: Prepare package | |
working-directory: ./v8/out | |
run: | | |
mkdir -p artifact/include/v8 artifact/lib | |
cp obj/libv8_monolith.a artifact/lib | |
cp -r ../include/* artifact/include/v8/ | |
cp -r gen/include/* artifact/include/v8/ | |
find artifact/include/v8/. ! -name "*.h" -type f -delete | |
- name: Generate CMakeLists | |
uses: DamianReeves/[email protected] | |
with: | |
path: ./v8/out/artifact/CMakeLists.txt | |
write-mode: overwrite | |
contents: ${{ format(env.cmakelists_template, endsWith(matrix.arch, '64') && 'INTERFACE "-DV8_COMPRESS_POINTERS"' || '', '${CMAKE_CURRENT_SOURCE_DIR}/lib/libv8_monolith.a') }} | |
- name: Release package | |
id: release_package | |
working-directory: ./v8 | |
run: | | |
echo "head_full=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT | |
cd out | |
tar -zcvf macos-${{ matrix.arch }}.tgz -C artifact . | |
- name: Install Requirement | |
shell: bash | |
run: | | |
pip install -U cos-python-sdk-v5 | |
- name: Publish package | |
shell: python | |
env: | |
local_file: ./v8/out/macos-${{ matrix.arch }}.tgz | |
cos_key: hippy/${{ github.event.inputs.hip_v8_root }}/v8/${{ github.event.inputs.v8_revision }}/${{ github.event.inputs.build_type }}/macos-${{ matrix.arch }}.tgz | |
v8_head: ${{ steps.release_package.outputs.head_full }} | |
run: ${{ env.publish_package_script }} | |
linux_prebuilt: | |
if: github.event.inputs.is_build_for_linux == 'true' | |
needs: context_in_lowercase | |
runs-on: [self-hosted, linux, shared] | |
container: | |
image: ghcr.io/${{ needs.context_in_lowercase.outputs.repository_owner }}/linux-release:latest | |
strategy: | |
matrix: | |
arch: [x86, x64, arm64, arm] | |
steps: | |
- name: Checkout v8 | |
run: | | |
fetch v8 | |
cd v8 | |
git checkout ${{ github.event.inputs.v8_revision }} | |
gclient sync -D | |
- name: Install sysroot(${{ matrix.arch }}) | |
if: ${{ contains(matrix.arch, 'arm') }} | |
working-directory: ./v8 | |
run: | | |
build/linux/sysroot_scripts/install-sysroot.py --arch=${{ matrix.arch }} | |
- name: Generate ${{ matrix.arch }} | |
working-directory: ./v8 | |
run: | | |
gn gen out --args="target_cpu=\"${{ matrix.arch }}\" v8_target_cpu=\"${{ matrix.arch }}\" chrome_pgo_phase=0 is_component_build=false v8_monolithic=true ${{ github.event.inputs.build_type == 'release' && 'is_debug=false is_official_build=true' || 'is_debug=true' }} ${{ github.event.inputs.build_args }}" | |
- name: Compile ${{ matrix.arch }} | |
working-directory: ./v8 | |
run: | | |
ninja -C out v8_monolith | |
- name: Prepare package | |
working-directory: ./v8/out | |
run: | | |
mkdir -p artifact/include/v8 artifact/lib | |
cp obj/libv8_monolith.a artifact/lib | |
cp -r ../include/* artifact/include/v8/ | |
cp -r gen/include/* artifact/include/v8/ | |
find artifact/include/v8/. ! -name "*.h" -type f -delete | |
- name: Generate CMakeLists | |
uses: DamianReeves/[email protected] | |
with: | |
path: ./v8/out/artifact/CMakeLists.txt | |
write-mode: overwrite | |
contents: ${{ format(env.cmakelists_template, endsWith(matrix.arch, '64') && 'INTERFACE "-DV8_COMPRESS_POINTERS"' || '', '${CMAKE_CURRENT_SOURCE_DIR}/lib/libv8_monolith.a') }} | |
- name: Release package | |
id: release_package | |
working-directory: ./v8 | |
run: | | |
echo "head_full=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT | |
cd out | |
tar -zcvf linux-${{ matrix.arch }}.tgz -C artifact . | |
- name: Install Requirement | |
shell: bash | |
run: | | |
pip3 install -U cos-python-sdk-v5 | |
- name: Publish package | |
shell: python3 {0} | |
env: | |
local_file: ./v8/out/linux-${{ matrix.arch }}.tgz | |
cos_key: hippy/${{ github.event.inputs.hip_v8_root }}/v8/${{ github.event.inputs.v8_revision }}/${{ github.event.inputs.build_type }}/linux-${{ matrix.arch }}.tgz | |
v8_head: ${{ steps.release_package.outputs.head_full }} | |
run: ${{ env.publish_package_script }} | |
ios_prebuilt: | |
if: github.event.inputs.is_build_for_ios == 'true' | |
runs-on: macos-latest | |
strategy: | |
matrix: | |
arch: [x64, arm64] | |
steps: | |
- name: Setup GN | |
run: | | |
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git /usr/local/opt/depot_tools | |
export PATH=/usr/local/opt/depot_tools:$PATH | |
- name: Checkout v8 | |
run: | | |
export PATH=/usr/local/opt/depot_tools:$PATH | |
fetch v8 | |
cd v8 | |
git checkout ${{ github.event.inputs.v8_revision }} | |
- name: Sync third_party | |
working-directory: ./v8 | |
run: | | |
export PATH=/usr/local/opt/depot_tools:$PATH | |
echo "target_os = ['ios']" >> ../.gclient | |
gclient sync -D | |
- name: Remove compiler flags | |
working-directory: ./v8/build/config/compiler | |
run: | | |
awk '!/"-mllvm"/' BUILD.gn > BUILD.gn.0 && mv -f BUILD.gn.0 BUILD.gn | |
awk '!/"-instcombine-lower-dbg-declare=0"/' BUILD.gn > BUILD.gn.0 && mv -f BUILD.gn.0 BUILD.gn | |
awk '!/ldflags \+= \[ "-Wl,-mllvm,-instcombine-lower-dbg-declare=0" \]/' BUILD.gn > BUILD.gn.0 && mv -f BUILD.gn.0 BUILD.gn | |
- name: Generate ${{ matrix.arch }} | |
working-directory: ./v8 | |
run: | | |
export PATH=/usr/local/opt/depot_tools:$PATH | |
gn gen out --args="target_os=\"ios\" target_cpu=\"${{ matrix.arch }}\" v8_target_cpu=\"${{ matrix.arch }}\" is_component_build=false v8_monolithic=true chrome_pgo_phase=0 enable_ios_bitcode=true ios_deployment_target=10 v8_enable_pointer_compression=false use_custom_libcxx=false ios_enable_code_signing=false ${{ github.event.inputs.build_type == 'release' && 'is_debug=false is_official_build=true' || 'is_debug=true' }} ${{ github.event.inputs.build_args }}" | |
- name: Compile ${{ matrix.arch }} | |
working-directory: ./v8 | |
run: | | |
export PATH=/usr/local/opt/depot_tools:$PATH | |
ninja -C out v8_monolith | |
- name: Prepare package | |
working-directory: ./v8/out | |
run: | | |
mkdir -p artifact/include/v8 artifact/lib | |
cp obj/libv8_monolith.a artifact/lib | |
cp -r ../include/* artifact/include/v8/ | |
cp -r gen/include/* artifact/include/v8/ | |
find artifact/include/v8/. ! -name "*.h" -type f -delete | |
- name: Generate CMakeLists | |
uses: DamianReeves/[email protected] | |
with: | |
path: ./v8/out/artifact/CMakeLists.txt | |
write-mode: overwrite | |
contents: ${{ format(env.cmakelists_template, '', '${CMAKE_CURRENT_SOURCE_DIR}/lib/libv8_monolith.a') }} | |
- name: Release package | |
id: release_package | |
working-directory: ./v8 | |
run: | | |
echo "head_full=$(git rev-parse HEAD)" >> $GITHUB_OUTPUT | |
cd out | |
tar -zcvf ios-${{ matrix.arch }}.tgz -C artifact . | |
- name: Install Requirement | |
shell: bash | |
run: | | |
pip install -U cos-python-sdk-v5 | |
- name: Publish package | |
shell: python | |
env: | |
local_file: ./v8/out/ios-${{ matrix.arch }}.tgz | |
cos_key: hippy/${{ github.event.inputs.hip_v8_root }}/v8/${{ github.event.inputs.v8_revision }}/${{ github.event.inputs.build_type }}/ios-${{ matrix.arch }}.tgz | |
v8_head: ${{ steps.release_package.outputs.head_full }} | |
run: ${{ env.publish_package_script }} |