<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/65473>65473</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[compiler-rt] merge-posix.test fails due to build directory location
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
user-45-20
</td>
</tr>
</table>
<pre>
OS: Ubuntu 22.04
LLVM version: 16.0.6 (latest stable at the time of writing)
I'm doing a standalone build of compiler-rt and running fuzzer tests subsequently. merge-posix is the only test that fails:
```
FAIL: libFuzzer :: merge-posix.test (60 of 138)
******************** TEST 'libFuzzer :: merge-posix.test' FAILED ********************
Script:
--
: 'RUN: at line 3'; /tmp/llvm/bin/clang --driver-mode=g++ -O2 -gline-tables-only -fsanitize=address,fuzzer -I/tmp/llvm-project-16.0.6.src/compiler-rt/lib/fuzzer -m64 /tmp/llvm-project-16.0.6.src/compiler-rt/test/fuzzer/FullCoverageSetTest.cpp -o /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmp-FullCoverageSetTest
: 'RUN: at line 5'; rm -rf /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T1 /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2
: 'RUN: at line 6'; mkdir -p /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T1 /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2
: 'RUN: at line 8'; echo F..... > /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T1/1
: 'RUN: at line 9'; echo .U.... > /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T1/2
: 'RUN: at line 10'; echo ..Z... > /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T1/3
: 'RUN: at line 12'; echo .....F > /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/1
: 'RUN: at line 13'; echo ....U. > /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/2
: 'RUN: at line 14'; echo ...Z.. > /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/3
: 'RUN: at line 15'; echo ...Z.. > /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/4
: 'RUN: at line 16'; echo ....E. > /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/5
: 'RUN: at line 17'; echo .....R > /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/6
: 'RUN: at line 20'; (ulimit -f 1; not /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmp-FullCoverageSetTest -merge=1 /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T1 /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2 2>&1 | FileCheck /tmp/llvm-project-16.0.6.src/compiler-rt/test/fuzzer/merge-posix.test --check-prefix=SIGXFSZ)
: 'RUN: at line 24'; TMPDIR=DIR_DOES_NOT_EXIST not /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmp-FullCoverageSetTest -merge=1 /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T1 /tmp/llvm-project-16.0.6.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2 2>&1 | FileCheck /tmp/llvm-project-16.0.6.src/compiler-rt/test/fuzzer/merge-posix.test --check-prefix=TMPDIR
--
Exit Code: 1
********************
********************
Failed Tests (1):
libFuzzer :: merge-posix.test
Testing Time: 16.94s
Unsupported : 7
Passed : 127
Expectedly Failed: 3
Failed : 1
```
I've been able to trace the cause and it has to do with the name of the directory the tests are running out of.
I find it easiest to repro in a Docker container, repro is attached below. If you're trying to repro this locally, make sure you use the exact same paths as I am below:
```sh
docker run -it ubuntu:22.04
apt update
apt install -y clang lld wget ninja-build sudo xz-utils cmake
useradd -m -d /home/user -s /bin/bash -G sudo user
echo 'user ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
su user
cd /tmp
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-16.0.6/llvm-project-16.0.6.src.tar.xz
tar xf llvm-project-16.0.6.src.tar.xz
cd llvm-project-16.0.6.src
# first bootstrap clang 16 with llvm 14
cmake -S llvm -B build -GNinja \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_ENABLE_RUNTIMES="" \
-DLLVM_TARGETS_TO_BUILD=X86 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_COMPILER=clang++ \
-DCMAKE_C_COMPILER=clang \
-DLLVM_USE_LINKER=lld \
-DLLVM_PARALLEL_COMPILE_JOBS="32" \
-DLLVM_PARALLEL_LINK_JOBS=6 \
-DLLVM_INCLUDE_TESTS=Off \
-DCMAKE_INSTALL_PREFIX=/tmp/llvm
cmake --build build
cmake --build build --target install/strip
# this will work: if the name of the build directory is long enough, everything is ok
cmake -GNinja -S compiler-rt -B build_rt_longername -DCMAKE_BUILD_TYPE=Release -DCOMPILER_RT_INCLUDE_TESTS=On -DLLVM_CMAKE_DIR="$PWD/build" -DCOMPILER_RT_TEST_STANDALONE_BUILD_LIBS=Off -DCOMPILER_RT_STANDALONE_BUILD=On -DCMAKE_CXX_COMPILER=/tmp/llvm/bin/clang++ -DCMAKE_C_COMPILER=/tmp/llvm/bin/clang -DCMAKE_INSTALL_PREFIX="/tmp/llvm/lib/clang/16"
cmake --build build_rt_longername
cmake --build build_rt_longername --target install
cmake --build build_rt_longername --target check-fuzzer
# this will fail
cmake -GNinja -S compiler-rt -B build_rt -DCMAKE_BUILD_TYPE=Release -DCOMPILER_RT_INCLUDE_TESTS=On -DLLVM_CMAKE_DIR="$PWD/build" -DCOMPILER_RT_TEST_STANDALONE_BUILD_LIBS=Off -DCOMPILER_RT_STANDALONE_BUILD=On -DCMAKE_CXX_COMPILER=/tmp/llvm/bin/clang++ -DCMAKE_C_COMPILER=/tmp/llvm/bin/clang -DCMAKE_INSTALL_PREFIX="/tmp/llvm/lib/clang/16"
cmake --build build_rt
cmake --build build_rt --target install
cmake --build build_rt --target check-fuzzer # error!
```
I've investigated this a bit, here are my findings. This is the complete test:
```
XFAIL: ios
UNSUPPORTED: windows
RUN: %cpp_compiler %S/FullCoverageSetTest.cpp -o %t-FullCoverageSetTest
RUN: rm -rf %tmp/T1 %tmp/T2
RUN: mkdir -p %tmp/T1 %tmp/T2
RUN: echo F..... > %tmp/T1/1
RUN: echo .U.... > %tmp/T1/2
RUN: echo ..Z... > %tmp/T1/3
RUN: echo .....F > %tmp/T2/1
RUN: echo ....U. > %tmp/T2/2
RUN: echo ...Z.. > %tmp/T2/3
RUN: echo ...Z.. > %tmp/T2/4
RUN: echo ....E. > %tmp/T2/5
RUN: echo .....R > %tmp/T2/6
# Check that we can report an error if file size exceeded
RUN: (ulimit -f 1; not %run %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=SIGXFSZ)
SIGXFSZ: ERROR: libFuzzer: file size exceeded
# Check that we honor TMPDIR
RUN: TMPDIR=DIR_DOES_NOT_EXIST not %run %t-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=TMPDIR
TMPDIR: MERGE-OUTER: failed to write to the control file: DIR_DOES_NOT_EXIST/libFuzzerTemp
```
the part that fails is "# Check that we can report an error if file size exceeded" - verified by commenting it out and running the test again.
This test sets the file size limit to "1" i.e. 1024 bytes. Attempting to write more than this will result in SIGXFSZ being sent to the process.
It then tries to run a fuzzed executable with the "-merge" option to verify it fails with the correct error ("file size exceeded"). However, looking at the code in FuzzerDriver.cpp, it looks like the framework will call `CrashResistantMerge` which will then first write the control file and then re-run itself as a subprocess with the `merge_inner` attribute and pass the control file to it, and the subprocess will append content to it (see [here](https://github.com/llvm/llvm-project/blob/7cbf1a2591520c2491aa35339f227775f4d3adf6/compiler-rt/lib/fuzzer/FuzzerMerge.cpp#L506)).
`CrashResistantMerge` does **not** check the result code of the subcommands it spawns - so basically, the "file size exceeded" failure needs to happen in the main parent process (the one that runs the outer merge) and not the children. If it happens in the parent, it'll be caught and reported correctly to _lit_, which expects a failure in this test.
The contents of the control file include full paths to the passed corpus:
```sh
$ cat /tmp/libFuzzerTemp.Merge11178.txt
9
3
/tmp/llvm-project-16.0.5.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T1/2
/tmp/llvm-project-16.0.5.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T1/1
/tmp/llvm-project-16.0.5.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T1/3
/tmp/llvm-project-16.0.5.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/4
/tmp/llvm-project-16.0.5.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/5
/tmp/llvm-project-16.0.5.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/2
/tmp/llvm-project-16.0.5.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/1
/tmp/llvm-project-16.0.5.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/6
/tmp/llvm-project-16.0.5.src/build_rt/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/3
STARTED 0 7
FT 0 0 16 48 64 88
```
the paths are written by the parent, the "STARTED" lines by the children performing inner merges (see [here](https://github.com/llvm/llvm-project/blob/7cbf1a2591520c2491aa35339f227775f4d3adf6/compiler-rt/lib/fuzzer/FuzzerMerge.cpp#L231).
If the path to the build folder is short enough, as in the example above, then the parent process is able to write all the paths successfully and the error only occurs in the child, so it's not reported to lit and the test fails as it expects an error.
If we use a longer path, like `build_rt_longername`, this happens:
```sh
$ cat /tmp/libFuzzerTemp.Merge29409.txt
9
3
/tmp/llvm-project-16.0.5.src/build_rt_longername/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T1/2
/tmp/llvm-project-16.0.5.src/build_rt_longername/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T1/1
/tmp/llvm-project-16.0.5.src/build_rt_longername/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T1/3
/tmp/llvm-project-16.0.5.src/build_rt_longername/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/4
/tmp/llvm-project-16.0.5.src/build_rt_longername/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/5
/tmp/llvm-project-16.0.5.src/build_rt_longername/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/2
/tmp/llvm-project-16.0.5.src/build_rt_longername/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/1
/tmp/llvm-project-16.0.5.src/build_rt_longername/test/fuzzer/X86_64DefaultLinuxConfig/Output/merge-posix.test.tmpmp/T2/6
/tmp/llvm-project-16.0.5.src/build_rt_longername/tes
```
One last thought - the test does `ulimit -1`, on my system the block size is 1024 so that's the limit that gets set - maybe this was tested on a system where the block size is e.g. 512 bytes, so this problem is a lot less likely to get triggered?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsW19z4jqy_zTKS5cpI_P3IQ8kwFx2mSQFZHfueaFkWwZthOUryUmYT3-rJZtAIOTknJ1NtupMTaUwbnW3Wq3-85NgxohVzvklaV-R9vCClXat9GVpuA5a7YCGF7FKt5e3cxIN4D4uc1sCpY2wRcIhCQfT6T--wyPXRqgcKZqdRtjoAKE9ySw3FoxlseTALNg1Bys2HFQGT1pYka8I7Xs2_u-E0O4GUiXyFTAcmadMqpxDXAqZ4rhEbQohuQ60BZanoMs8R-qs_PmTa0CJBkwZG_5_Jc-t3DZgw_WKB4Uy4hmEcVqoXG4dLdg1s5AxIQ2JKiVIJ6z-u8fxYDLFiUkRj70QpIwG-3wbjhehvU6ISjaj3svE6B__D4vRfAGEdt-VTWgXUNHREP6MQK_yPNGisDt7BEE1k2iAuszub_ATsyBFziEitEuiKyB0bDcFoWMpHzeEjmOREzpOJMtXAEGQavHIdbBRKSfRcEXoFaFXENxSCFbIJ3BeYgK3MkFmWC6s-Im0LE01N4bQ62qNg8mBrKDQ6l88sYH3vIbRCQp-8ROkEzGh43r8ptOCD7PwVq54EDoel1Jeq0eu2YrPuV1wYxtJUUCgfg9v58_Lk4x_9DrLTmvIM1ZKOxV5-Xyt8kysCB3flrYokfj18jfspghOaHRu4drVwgHoDQQ6-yS1ncRF81Ol03N26uzstHlIhYag-MtSpy3V21mKJ2sF4wb-AxKNPtdghI6b59TuH6rduP8yap-1djN8pXfjt6-id3RWb_pa70ajMf50vel7btKMjvW-_3x703f9pHWk929fwE_ou37S_rJ6t87q3Tn2k9HX0Lt9Vu_uiX05-xJ6d87pTV_iIKG9UoqNsBBk0MTvcmW_UDkGgaMk0fBzs_gn1xBASTQitNME0r2GsZD8es2Thz9fkx91ZEGQIOeg0DwTzyQazifffoznv710Z6dd6iVkLr7fDSczEg2Hk9lyeDuaL29uF8vRj8l88Zdz_eVcB85V-cpB0zx6FhauXdc7gOY-1vHn4YF_F4cxE5KnsHDYCaG9Jm6PuvuH94GP41khK5GvYCE2vAKF-i1TMbzPTVkUSluegvuHFADdWt4dM6Z-tXvfpLv3o-eCJ5ancgtec3wf1W-ryRyOhp3pD7GdF9TpkUPMeQ4Oq7IKrGYJd1hRwkrDHdYkLKyZwbepgidh1-59zjyihZ9ToXlild56rMsZlGm-Q6lUaUFljUosZMJz5cwIB0Yp0LzQCkQODIYqeeAaEpVbJnL0wev6tQFmLUvWPIWYS_XUgEkGW1US2tUcrN6isB03uxYGpEqYlFtksmEPHEypOQ4BnB1qy59ZYsHgbApm1waYgQmwjZfwgo4d2tGs_RepV1aXOQTCQulwQhIN9pBC_5cVFsoiZZa_PIvcWCYlBFvwgJGUKTytuIVc5P9igUf_TJkqeP4ZlFZIAwnOYp9xabhmaQrBBoIUt_tabTihY_weAnTsCpOKmVlD8M3zw7d-vCt6CO06-sF0SqIhoT38QPtwc3s3mM__OURncl91sTCqaiNuMXogO64rJzflHmf_N0nrGOQe3fTW1hYOeKRjQscrYddl3EjU5gVG249WhI41l5wZbggdp-opl4qlFZHSqyqavR3jGpbpxvNPr4BlGp4z-D2kSfoW2WEoiyAT2liIlbLGalZUy9ns-O2CTLAf8UydGwZz_21wVWG8wbcbXHMg7et6SwMEw-n0H9-Xo5vB1XS0vJvd_m10vZi7FaJOBImupEwJpbA38HDU7P5mMfk-qkYh6SkRi8Hs22gxXy5ul1f3k-mQRMMfvc4B0-vvg7-P_Nvl4n_vRiQazvyyvOboKa9__Fhe336_m0xHWEh4fT3-ecz2-oj0pJr389FyOrn5uyPD3XI067vBbDCdjqY1v-Xfbq-quUdvzn43CHnXIzonSSc319P74Wi5GM3dStxm2YnpTG7mi8F0urybjcaTH078Pky87wjVLnd_33wBQWCZxq1TxQzceFaL4lRmjXzkexJSwpPSD7h5RXYUtD3jl9DtgmW-Ap6rcrXGgMkfud7aNQZVYUA9HKhX-WswPzibqP15qe0SuXHtRJ71nmBYr_1ytjg2cF6b3rPwZalz5dbdP4d1UYVLe8gIGSzni8HNcDC9vallTydX9bIdkr-mrEWfdOYzqH8N8Z9y7HOHBWdch74e53H9StwYO2_6puscrsTvJDv2t4-O8zViVUW-46QZE_JjvvWXQ32qQ5179yHXOe0vDtKIgGutNKHnStiDQlbkj1h_rxhW2M67GMTCYiRbc81dRbrZuupT5CvTgAXSVEej6GiSW1-9vlX1-ccf9dGoUFXZc38zv7-7u50tRq5SehJ5qp6qd1WPTWg7KYpl7c_4PH_vOK1tzxxu7TOvTrLckJdutP5MD2j3TnPOEB8MOT7W2I18QY_3aQ_OEvZp6Qnaffx-nzZ6S5MD5PxF79Oa7KPV-7QnNdlDWvdpow_Qtk7rMDpF235jbrMTtJ3X4dO39-4c_wm7tRy7HuWuB_idgzk_E5KDET-xzUk4T3n6yilPA4dt7Gfe8r9DwOWkD70NRrTN--BU_RwNYDSb3c4ObiHgw1uzess4a5UrDfswRTX_91Gu_6wl9lWsdRvA99Hs2yi4vV-M3GPmO32r3GUS37W7AJZbraQzDpIdT8nHeW_GBa8bspNxFRkWTO_fE8FA6TLHH3c9zKjwyLXIBHbwWwy6G547yERYhxLs322psQRgKybyxgHQgpHbX7Ph1gfwF3neoy1GUNpEoaLBG9AMaQvireWmAQNr-aawFVrgzbhRmuOc8r3CRHNTSkxkUPkkxBwHGZ7b2u6FVgk3pgY33HWfHKwW3EEm6D_MX9NJgT_zpPT3gnY4CqG0ciNKQRVWqBzHOTNt0Sze-jv6RGms2CtDE9ojlJ60NaH9BvyPesIqHnOgVOrBXTCyFZ8UUyZ4fxi6eyqYepBUWEdtQIoHj5Jkmm04NhPeMAmTEkgnvNbMrGfcCGNZbr-7aXRCeFqLZO0pnTV8e1y56ytfdUvuqDQP0FrCGi4zYJi-TRlX9t0zWCd09lqKPOcaxTFrtYhL63kVzJhjKVaBLwUqcYespQRWFDxP3aBqdYW72mQ49rdXWEGQ9pDQ3ofBi1gqrK66SZw1GW33m20aJrTVbzIWtaOon1Ha7XbbWSuNWJp1zt7icSUDfnC29usVTdthB6Mn7TdelS1vrE-quKkuTOXKVpeukmpX89rtnYdUzaIpY9ysLE8N2sUU7Ck3EIBREDMjdhhb5dGnNz96cqk55JynbnOsndHRC3Hchokcow6av14aQnv-4hr38UaXeXWVrbRcQ7Vx-m5VMWK7dV8LmWqeO3TQgZcoxdRivATv5oR2pYTYoZ2rdRV-eAXSVjtNblHVpRR2iYO8b3MHxqKL1pMSVeBwuPxhrOK1V5nanAeuKfJElimHrJSywiDr2OIh4UTpojxxUa8GIQltQcL2D2X2w3zDLXuz2ez2Gva5Kh-rVFvXWG8fErT_kxc-PlmN5tdQ4wssyv5p_yer0f4aanwBF6Vfw0X3u5FPVqPaKfPFAFtvCOvDtPECQgih2YFWDzot6PXerXXdyY_mrkixPMfq9DBZVJmtkoXpTIqcm5qwTjpQcJ0pvXE1LRYoPkeZ_5ZSgkbN13XEJIPaRnVi8ihOpmTKNTYGZo3l_wtyzHbZlj-zTYFVXqweeWXH_Ty8y_TC7A4hfaHIfPVYrY0pEyTDHLnd1XC-BnZ3p1WSlHon1a0GSjO-7OsaVx3sUrtVIIXd8XGdhK-zmatvdum9amhe2-OJu_NDBh76dDq6GhvrZdIJTyGvndBPX5i6IvlzGZ32W2H_35DR93X8Gsn9V2v08SD6qzX6Wqv2x7L_r9bo44XAr9boa3n2HysPfrVGH68UjjQ6k7tvcw6Sud8zKdfABS_x3De5nbBGOJtVBFY5bLZgtsbyjU9mUiUPvlsVxuNERrl20yUOJKkgJexAV9waMBxFbdg25hVcxHznx1Pkz2r2T-7g4VgIb6wa0G5SD0hVicoxKrSKJd-4dAhSWZCYHDGv-D50xS1YLVYrrnlKovFFehml_ajPLvhls9NvhWGHdsOL9WXMo04YZozyfpN1WzELWYf1-jHvZq2kGfUvxCUNaRT2w04zanZb3UYrSXpxn8ZZO-wltNUkrZBvmJANXLOG0qsLYUzJLzvtVje6kCzm0rhfz1Ga8ydwLwmlpD280JduneNyZUgrlMJY88LFCivdz-72a5P28PiHZT4jp6UrCl4fV0uVMCtUflFqefnhQsopa9A_cTL_HwAA__9KdKDA">