diff --git a/.cspell/bash.txt b/.cspell/bash.txt index 2bed087a..9fe0c70f 100644 --- a/.cspell/bash.txt +++ b/.cspell/bash.txt @@ -116,3 +116,5 @@ hlocalhost uuser ppassword DELIMS +Facadesh +Scriptsh diff --git a/bin/cli b/bin/cli index 340599a1..d1c8454a 100755 --- a/bin/cli +++ b/bin/cli @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management diff --git a/bin/dbImport b/bin/dbImport index f60c8e5a..08d1c973 100755 --- a/bin/dbImport +++ b/bin/dbImport @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management diff --git a/bin/dbImportProfile b/bin/dbImportProfile index 70b85a95..7b05dd83 100755 --- a/bin/dbImportProfile +++ b/bin/dbImportProfile @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management diff --git a/bin/dbImportStream b/bin/dbImportStream index 210b0409..045b6309 100755 --- a/bin/dbImportStream +++ b/bin/dbImportStream @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management diff --git a/bin/dbQueryAllDatabases b/bin/dbQueryAllDatabases index 0fc29e68..2b198934 100755 --- a/bin/dbQueryAllDatabases +++ b/bin/dbQueryAllDatabases @@ -59,7 +59,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management @@ -1295,8 +1299,8 @@ Array::contains() { # @require Compiler::Embed::requireEmbedBinDir -declare -gx embed_function_DbQueryOneDatabase="${PERSISTENT_TMPDIR:-/tmp}/bin/370dab633b77b22851fe46e08d43de97/dbQueryOneDatabase" -declare -gx encoded_binary_file_DbQueryOneDatabase="IyEvdXNyL2Jpbi9lbnYgYmFzaAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgR0VORVJBVEVEIEZBQ0FERSBGUk9NIGh0dHBzOi8vZ2l0aHViLmNvbS9mY2hhc3RhbmV0L2Jhc2gtdG9vbHMvdHJlZS9tYXN0ZXIvLi4vYmFzaC1kZXYtZW52L3ZlbmRvci9iYXNoLXRvb2xzLWZyYW1ld29yay9zcmMvQ29tcGlsZXIvRW1iZWQvZW1iZWRGcmFtZXdvcmtGdW5jdGlvbi5iaW5GaWxlLnRwbAojIERPIE5PVCBFRElUIElUCiMgQGdlbmVyYXRlZAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjI4OCxTQzIwMzQKIyBCSU5fRklMRT0ke0JJTl9GSUxFfQojIEZBQ0FERQoKIyBlbnN1cmUgdGhhdCBubyB1c2VyIGFsaWFzZXMgY291bGQgaW50ZXJmZXJlIHdpdGgKIyBjb21tYW5kcyB1c2VkIGluIHRoaXMgc2NyaXB0CnVuYWxpYXMgLWEgfHwgdHJ1ZQpzaG9wdCAtdSBleHBhbmRfYWxpYXNlcwoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CigoZmFpbHVyZXMgPSAwKSkgfHwgdHJ1ZQoKIyBCYXNoIHdpbGwgcmVtZW1iZXIgJiByZXR1cm4gdGhlIGhpZ2hlc3QgZXhpdCBjb2RlIGluIGEgY2hhaW4gb2YgcGlwZXMuCiMgVGhpcyB3YXkgeW91IGNhbiBjYXRjaCB0aGUgZXJyb3IgaW5zaWRlIHBpcGVzLCBlLmcuIG15c3FsZHVtcCB8IGd6aXAKc2V0IC1vIHBpcGVmYWlsCnNldCAtbyBlcnJleGl0CgojIENvbW1hbmQgU3Vic3RpdHV0aW9uIGNhbiBpbmhlcml0IGVycmV4aXQgb3B0aW9uIHNpbmNlIGJhc2ggdjQuNApzaG9wdCAtcyBpbmhlcml0X2VycmV4aXQgfHwgdHJ1ZQoKIyBhIGxvZyBpcyBnZW5lcmF0ZWQgd2hlbiBhIGNvbW1hbmQgZmFpbHMKc2V0IC1vIGVycnRyYWNlCgojIHVzZSBudWxsZ2xvYiBzbyB0aGF0IChmaWxlKi5waHApIHdpbGwgcmV0dXJuIGFuIGVtcHR5IGFycmF5IGlmIG5vIGZpbGUgbWF0Y2hlcyB0aGUgd2lsZGNhcmQKc2hvcHQgLXMgbnVsbGdsb2IKCiMgZW5zdXJlIHJlZ2V4cCBhcmUgaW50ZXJwcmV0ZWQgd2l0aG91dCBhY2NlbnR1YXRlZCBjaGFyYWN0ZXJzCmV4cG9ydCBMQ19BTEw9UE9TSVgKCmV4cG9ydCBURVJNPXh0ZXJtLTI1NmNvbG9yCgojIGF2b2lkIGludGVyYWN0aXZlIGluc3RhbGwKZXhwb3J0IERFQklBTl9GUk9OVEVORD1ub25pbnRlcmFjdGl2ZQpleHBvcnQgREVCQ09ORl9OT05JTlRFUkFDVElWRV9TRUVOPXRydWUKCiMgc3RvcmUgY29tbWFuZCBhcmd1bWVudHMgZm9yIGxhdGVyIHVzYWdlCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIEJBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIE9SSUdJTkFMX0JBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCgojIEBzZWUgaHR0cHM6Ly91bml4LnN0YWNrZXhjaGFuZ2UuY29tL2EvMzg2ODU2CiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwppbnRlcnJ1cHRNYW5hZ2VtZW50KCkgewogICMgcmVzdG9yZSBTSUdJTlQgaGFuZGxlcgogIHRyYXAgLSBJTlQKICAjIGVuc3VyZSB0aGF0IEN0cmwtQyBpcyB0cmFwcGVkIGJ5IHRoaXMgc2NyaXB0IGFuZCBub3QgYnkgc3ViIHByb2Nlc3MKICAjIHJlcG9ydCB0byB0aGUgcGFyZW50IHRoYXQgd2UgaGF2ZSBpbmRlZWQgYmVlbiBpbnRlcnJ1cHRlZAogIGtpbGwgLXMgSU5UICIkJCIKfQp0cmFwIGludGVycnVwdE1hbmFnZW1lbnQgSU5UClNDUklQVF9OQU1FPSR7MCMjKi99ClJFQUxfU0NSSVBUX0ZJTEU9IiQocmVhZGxpbmsgLWUgIiQocmVhbHBhdGggIiR7QkFTSF9TT1VSQ0VbMF19IikiKSIKQ1VSUkVOVF9ESVI9IiQoY2QgIiQocmVhZGxpbmsgLWUgIiR7UkVBTF9TQ1JJUFRfRklMRSUvKn0iKSIgJiYgcHdkIC1QKSIKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIFRlbXAgZGlyIG1hbmFnZW1lbnQKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpLRUVQX1RFTVBfRklMRVM9IiR7S0VFUF9URU1QX0ZJTEVTOi0wfSIKZXhwb3J0IEtFRVBfVEVNUF9GSUxFUwoKIyBQRVJTSVNURU5UX1RNUERJUiBpcyBub3QgZGVsZXRlZCBieSB0cmFwcwpQRVJTSVNURU5UX1RNUERJUj0iJHtUTVBESVI6LS90bXB9L2Jhc2gtZnJhbWV3b3JrIgpleHBvcnQgUEVSU0lTVEVOVF9UTVBESVIKbWtkaXIgLXAgIiR7UEVSU0lTVEVOVF9UTVBESVJ9IgoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0ClRNUERJUj0iJChta3RlbXAgLWQgLXAgIiR7UEVSU0lTVEVOVF9UTVBESVI6LS90bXB9IiAtdCBiYXNoLWZyYW1ld29yay0kJC1YWFhYWFgpIgpleHBvcnQgVE1QRElSCgojIHRlbXAgZGlyIGNsZWFuaW5nCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwpjbGVhbk9uRXhpdCgpIHsKICBpZiBbWyAiJHtLRUVQX1RFTVBfRklMRVM6LTB9IiA9ICIxIiBdXTsgdGhlbgogICAgTG9nOjpkaXNwbGF5SW5mbyAiS0VFUF9URU1QX0ZJTEVTPTEgdGVtcCBmaWxlcyBrZXB0IGhlcmUgJyR7VE1QRElSfSciCiAgZWxpZiBbWyAtbiAiJHtUTVBESVIreHh4fSIgXV07IHRoZW4KICAgIExvZzo6ZGlzcGxheURlYnVnICJLRUVQX1RFTVBfRklMRVM9MCByZW1vdmluZyB0ZW1wIGZpbGVzICcke1RNUERJUn0nIgogICAgcm0gLVJmICIke1RNUERJUjotL3RtcC9mYWtlfSIgPi9kZXYvbnVsbCAyPiYxCiAgZmkKfQp0cmFwIGNsZWFuT25FeGl0IEVYSVQgSFVQIFFVSVQgQUJSVCBURVJNCgojIFZBUl9NQUlOX0ZVTkNUSU9OX1ZBUl9OQU1FPWRiUXVlcnlBbGxEYXRhYmFzZXNGYWNhZGUKCiMgQGRlc2NyaXB0aW9uIHVzZWQgdG8gZXhlY3V0ZSBnaXZlbiBxdWVyeSB3aGVuIHVzaW5nCiMgZGJTY3JpcHRBbGxEYXRhYmFzZXMKIyBAYXJnICQxIGRzbjpTdHJpbmcKIyBAYXJnICQyIGRiOlN0cmluZwojIEBlbnYgcXVlcnkgU3RyaW5nCiMgQGVudiBvcHRpb25TZXBhcmF0b3IgU3RyaW5nCiMgQHJlcXVpcmUgTGludXg6OnJlcXVpcmVFeGVjdXRlZEFzVXNlcgpEYjo6cXVlcnlPbmVEYXRhYmFzZSgpIHsKICAjIHF1ZXJ5IGFuZCBvcHRpb25TZXBhcmF0b3IgYXJlIHBhc3NlZCB2aWEgZXhwb3J0CiAgbG9jYWwgZHNuPSIkMSIKICBsb2NhbCBkYj0iJDIiCgogIGxvY2FsIC1BIGRiSW5zdGFuY2UKICBEYXRhYmFzZTo6bmV3SW5zdGFuY2UgZGJJbnN0YW5jZSAiJHtkc259IgogIERhdGFiYXNlOjpzZXRRdWVyeU9wdGlvbnMgZGJJbnN0YW5jZSAiJHtkYkluc3RhbmNlW1FVRVJZX09QVElPTlNdfSAtLWNvbm5lY3QtdGltZW91dD01IgoKICAjIGlkZW50aWZ5IGNvbHVtbnMgaGVhZGVyCiAgZWNobyAtbiAiQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAiCiAgRGF0YWJhc2U6OnNraXBDb2x1bW5OYW1lcyBkYkluc3RhbmNlIDAKCiAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU0CiAgaWYgISBEYXRhYmFzZTo6cXVlcnkgZGJJbnN0YW5jZSAiJHtxdWVyeX0iICIke2RifSIgfCBzZWQgInMvXHQvJHtvcHRpb25TZXBhcmF0b3J9L2ciOyB0aGVuCiAgICBMb2c6OmZhdGFsICJkYXRhYmFzZSAke2RifSBlcnJvciIgMT4mMgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIExvZyBuYW1lc3BhY2UgcHJvdmlkZXMgMiBraW5kIG9mIGZ1bmN0aW9ucwojIC0gTG9nOjpkaXNwbGF5KiBhbGxvd3MgdG8gZGlzcGxheSBnaXZlbiBtZXNzYWdlIHdpdGgKIyAgIGdpdmVuIGRpc3BsYXkgbGV2ZWwKIyAtIExvZzo6bG9nKiBhbGxvd3MgdG8gbG9nIGdpdmVuIG1lc3NhZ2Ugd2l0aAojICAgZ2l2ZW4gbG9nIGxldmVsCiMgTG9nOjpkaXNwbGF5KiBmdW5jdGlvbnMgYXV0b21hdGljYWxseSBsb2cgdGhlIG1lc3NhZ2UgdG9vCiMgQHNlZSBFbnY6OnJlcXVpcmVMb2FkIHRvIGxvYWQgdGhlIGRpc3BsYXkgYW5kIGxvZyBsZXZlbCBmcm9tIC5lbnYgZmlsZQoKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIG9mZgpleHBvcnQgX19MRVZFTF9PRkY9MAojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgZXJyb3IKZXhwb3J0IF9fTEVWRUxfRVJST1I9MQojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgd2FybmluZwpleHBvcnQgX19MRVZFTF9XQVJOSU5HPTIKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIGluZm8KZXhwb3J0IF9fTEVWRUxfSU5GTz0zCiMgQGRlc2NyaXB0aW9uIGxvZyBsZXZlbCBzdWNjZXNzCmV4cG9ydCBfX0xFVkVMX1NVQ0NFU1M9MwojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgZGVidWcKZXhwb3J0IF9fTEVWRUxfREVCVUc9NAoKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBvZmYKZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9PRkY9MAojIEBkZXNjcmlwdGlvbiB2ZXJib3NlIGxldmVsIGluZm8KZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9JTkZPPTEKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBpbmZvCmV4cG9ydCBfX1ZFUkJPU0VfTEVWRUxfREVCVUc9MgojIEBkZXNjcmlwdGlvbiB2ZXJib3NlIGxldmVsIGluZm8KZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9UUkFDRT0zCgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgZGVidWcgY29sb3IgKGdyZXkpCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6ZGlzcGxheURlYnVnKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0RFQlVHKSk7IHRoZW4KICAgIGVjaG8gLWUgIiR7X19ERUJVR19DT0xPUn1ERUJVRyAgIC0gJHsxfSR7X19SRVNFVF9DT0xPUn0iID4mMgogIGZpCiAgTG9nOjpsb2dEZWJ1ZyAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBpbmZvIGNvbG9yIChiZyBsaWdodCBibHVlL2ZnIHdoaXRlKQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlJbmZvKCkgewogIGxvY2FsIHR5cGU9IiR7MjotSU5GT30iCiAgaWYgKChCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMID49IF9fTEVWRUxfSU5GTykpOyB0aGVuCiAgICBlY2hvIC1lICIke19fSU5GT19DT0xPUn0ke3R5cGV9ICAgIC0gJHsxfSR7X19SRVNFVF9DT0xPUn0iID4mMgogIGZpCiAgTG9nOjpsb2dJbmZvICIkMSIgIiR7dHlwZX0iCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBDT01NQU5EX0JJTl9ESVIgZW52IHZhciBpcyBzZXQKIyBhbmQgUEFUSCBjb3JyZWN0bHkgcHJlcGFyZWQKIyBAbm9hcmdzCiMgQHNldCBDT01NQU5EX0JJTl9ESVIgc3RyaW5nIHRoZSBkaXJlY3Rvcnkgd2hlcmUgdG8gZmluZCB0aGlzIGNvbW1hbmQKIyBAc2V0IFBBVEggc3RyaW5nIGFkZCBkaXJlY3Rvcnkgd2hlcmUgdG8gZmluZCB0aGlzIGNvbW1hbmQgYmluYXJ5CkNvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyKCkgewogIENPTU1BTkRfQklOX0RJUj0iJHtDVVJSRU5UX0RJUn0iCiAgRW52OjpwYXRoUHJlcGVuZCAiJHtDT01NQU5EX0JJTl9ESVJ9Igp9CgojIEBkZXNjcmlwdGlvbiBjcmVhdGUgYSBuZXcgZGIgaW5zdGFuY2UKIyBSZXR1cm5zIGltbWVkaWF0ZWx5IGlmIHRoZSBpbnN0YW5jZSBpcyBhbHJlYWR5IGluaXRpYWxpemVkCiMKIyBAYXJnICQxIGluc3RhbmNlTmV3SW5zdGFuY2U6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBkc246U3RyaW5nIGRzbiBwcm9maWxlIC0gbG9hZCB0aGUgZHNuLmVudiBwcm9maWxlIGRlZHVjZWQgdXNpbmcgcnVsZXMgZGVmaW5lZCBpbiBDb25mOjpnZXRBYnNvbHV0ZUZpbGUKIwojIEBleGFtcGxlCiMgICBkZWNsYXJlIC1BZ3ggZGJJbnN0YW5jZQojICAgRGF0YWJhc2U6Om5ld0luc3RhbmNlIGRiSW5zdGFuY2UgImRlZmF1bHQubG9jYWwiCiMKIyBAZXhpdGNvZGUgMSBpZiBkbnMgZmlsZSBub3QgYWJsZSB0byBsb2FkZWQKRGF0YWJhc2U6Om5ld0luc3RhbmNlKCkgewogIGxvY2FsIC1uIGluc3RhbmNlTmV3SW5zdGFuY2U9JDEKICBsb2NhbCBkc249IiQyIgogIGxvY2FsIERTTl9GSUxFCgogIGlmIFtbIC12IGluc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ10gJiYgIiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnSU5JVElBTElaRUQnXTotMH0iID09ICIxIiBdXTsgdGhlbgogICAgcmV0dXJuCiAgZmkKCiAgIyBmaW5hbCBhdXRoIGZpbGUgZ2VuZXJhdGVkIGZyb20gZG5zIGZpbGUKICBpbnN0YW5jZU5ld0luc3RhbmNlWydBVVRIX0ZJTEUnXT0iIgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0RTTl9GSUxFJ109IiIKCiAgIyBjaGVjayBkc24gZmlsZQogIERTTl9GSUxFPSIkKENvbmY6OmdldEFic29sdXRlRmlsZSAiZHNuIiAiJHtkc259IiAiZW52IikiIHx8IHJldHVybiAxCiAgRGF0YWJhc2U6OmNoZWNrRHNuRmlsZSAiJHtEU05fRklMRX0iIHx8IHJldHVybiAxCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnRFNOX0ZJTEUnXT0iJHtEU05fRklMRX0iCgogICMgc2hlbGxjaGVjayBzb3VyY2U9L3NyYy9EYXRhYmFzZS90ZXN0c0RhdGEvZHNuX3ZhbGlkLmVudgogIHNvdXJjZSAiJHtpbnN0YW5jZU5ld0luc3RhbmNlWydEU05fRklMRSddfSIKCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnVVNFUiddPSIke1VTRVJ9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1BBU1NXT1JEJ109IiR7UEFTU1dPUkR9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0hPU1ROQU1FJ109IiR7SE9TVE5BTUV9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1BPUlQnXT0iJHtQT1JUfSIKCiAgIyBnZW5lcmF0ZSBhdXRoRmlsZSBmb3IgZWFzeSBhdXRoZW50aWNhdGlvbgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0FVVEhfRklMRSddPSQobWt0ZW1wIC1wICIke1RNUERJUjotL3RtcH0iIC10ICJteXNxbC5YWFhYWFhYWFhYWFgiKQogICgKICAgIGVjaG8gIltjbGllbnRdIgogICAgZWNobyAidXNlciA9ICR7VVNFUn0iCiAgICBlY2hvICJwYXNzd29yZCA9ICR7UEFTU1dPUkR9IgogICAgZWNobyAiaG9zdCA9ICR7SE9TVE5BTUV9IgogICAgZWNobyAicG9ydCA9ICR7UE9SVH0iCiAgKSA+IiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnQVVUSF9GSUxFJ119IgoKICAjIHNvbWUgb2YgdGhvc2UgdmFsdWVzIGNhbiBiZSBvdmVycmlkZGVuIHVzaW5nIHRoZSBkc24gZmlsZQogICMgU0tJUF9DT0xVTU5fTkFNRVMgZW5hYmxlZCBieSBkZWZhdWx0CiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnU0tJUF9DT0xVTU5fTkFNRVMnXT0iJHtTS0lQX0NPTFVNTl9OQU1FUzotMX0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnU1NMX09QVElPTlMnXT0iJHtNWVNRTF9TU0xfT1BUSU9OUzotLS1zc2wtbW9kZT1ESVNBQkxFRH0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnUVVFUllfT1BUSU9OUyddPSIke01ZU1FMX1FVRVJZX09QVElPTlM6LS0tYmF0Y2ggLS1yYXcgLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOH0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnRFVNUF9PUFRJT05TJ109IiR7TVlTUUxfRFVNUF9PUFRJT05TOi0tLWRlZmF1bHQtY2hhcmFjdGVyLXNldD11dGY4IC0tY29tcHJlc3MgLS1oZXgtYmxvYiAtLXJvdXRpbmVzIC0tdHJpZ2dlcnMgLS1zaW5nbGUtdHJhbnNhY3Rpb24gLS1zZXQtZ3RpZC1wdXJnZWQ9T0ZGIC0tY29sdW1uLXN0YXRpc3RpY3M9MCAke2luc3RhbmNlTmV3SW5zdGFuY2VbJ1NTTF9PUFRJT05TJ119fSIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydEQl9JTVBPUlRfT1BUSU9OUyddPSIke0RCX0lNUE9SVF9PUFRJT05TOi0tLWNvbm5lY3QtdGltZW91dD01IC0tYmF0Y2ggLS1yYXcgLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOH0iCgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ109MQp9CgojIEBkZXNjcmlwdGlvbiBteXNxbCBxdWVyeSBvbiBhIGdpdmVuIGRiCiMgQHdhcm5pbmcgY291bGQgdXNlIFFVRVJZX09QVElPTlMgdmFyaWFibGUgZnJvbSBkc24gaWYgZGVmaW5lZAojIEBleGFtcGxlCiMgICBjYXQgZmlsZS5zcWwgfCBEYXRhYmFzZTo6cXVlcnkgLi4uCiMgQGFyZyAkMSBpbnN0YW5jZVF1ZXJ5OiZNYXA8U3RyaW5nLFN0cmluZz4gKHBhc3NlZCBieSByZWZlcmVuY2UpIGRhdGFiYXNlIGluc3RhbmNlIHRvIHVzZQojIEBhcmcgJDIgc3FsUXVlcnk6U3RyaW5nIChvcHRpb25hbCkgc3FsIHF1ZXJ5IG9yIHNxbCBmaWxlIHRvIGV4ZWN1dGUuIGlmIG5vdCBwcm92aWRlZCBvciBlbXB0eSwgdGhlIGNvbW1hbmQgY2FuIGJlIHBpcGVkCiMgQGFyZyAkMyBkYk5hbWU6U3RyaW5nIChvcHRpb25hbCkgdGhlIGRiIG5hbWUKIwojIEBleGl0Y29kZSBteXNxbCBjb21tYW5kIHN0YXR1cyBjb2RlCkRhdGFiYXNlOjpxdWVyeSgpIHsKICBsb2NhbCAtbiBpbnN0YW5jZVF1ZXJ5PSQxCiAgbG9jYWwgLWEgbXlzcWxDb21tYW5kPSgpCiAgbG9jYWwgLWEgcXVlcnlPcHRpb25zCgogIG15c3FsQ29tbWFuZCs9KG15c3FsKQogIG15c3FsQ29tbWFuZCs9KCItLWRlZmF1bHRzLWV4dHJhLWZpbGU9JHtpbnN0YW5jZVF1ZXJ5WydBVVRIX0ZJTEUnXX0iKQogIElGUz0nICcgcmVhZCAtciAtYSBxdWVyeU9wdGlvbnMgPDw8IiR7aW5zdGFuY2VRdWVyeVsnUVVFUllfT1BUSU9OUyddfSIKICBteXNxbENvbW1hbmQrPSgiJHtxdWVyeU9wdGlvbnNbQF19IikKICBpZiBbWyAiJHtpbnN0YW5jZVF1ZXJ5WydTS0lQX0NPTFVNTl9OQU1FUyddfSIgPSAiMSIgXV07IHRoZW4KICAgIG15c3FsQ29tbWFuZCs9KCItcyIgIi0tc2tpcC1jb2x1bW4tbmFtZXMiKQogIGZpCiAgIyBhZGQgb3B0aW9uYWwgZGIgbmFtZQogIGlmIFtbIC1uICIkezMreH0iIF1dOyB0aGVuCiAgICBteXNxbENvbW1hbmQrPSgiJDMiKQogIGZpCiAgIyBhZGQgb3B0aW9uYWwgc3FsIHF1ZXJ5CiAgaWYgW1sgLW4gIiR7Mit4fSIgJiYgLW4gIiQyIiAmJiAhIC1mICIkMiIgXV07IHRoZW4KICAgIG15c3FsQ29tbWFuZCs9KCItZSIpCiAgICBteXNxbENvbW1hbmQrPSgiJDIiKQogIGZpCiAgTG9nOjpkaXNwbGF5RGVidWcgIiQocHJpbnRmICJleGVjdXRlIGNvbW1hbmQ6ICclcyciICIke215c3FsQ29tbWFuZFsqXX0iKSIKCiAgaWYgW1sgLWYgIiQyIiBdXTsgdGhlbgogICAgIiR7bXlzcWxDb21tYW5kW0BdfSIgPCIkMiIKICBlbHNlCiAgICAiJHtteXNxbENvbW1hbmRbQF19IgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIHNldCB0aGUgZ2VuZXJhbCBvcHRpb25zIHRvIHVzZSBvbiBteXNxbCBjb21tYW5kIHRvIHF1ZXJ5IHRoZSBkYXRhYmFzZQojIERpZmZlcnMgdGhhbiBzZXRPcHRpb25zIGluIHRoZSB3YXkgdGhhdCB0aGVzZSBvcHRpb25zIGNvdWxkIGNoYW5nZSBlYWNoIHRpbWUKIwojIEBhcmcgJDEgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBvcHRpb25zTGlzdDpTdHJpbmcgcXVlcnkgb3B0aW9ucyBsaXN0CkRhdGFiYXNlOjpzZXRRdWVyeU9wdGlvbnMoKSB7CiAgbG9jYWwgLW4gaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM9JDEKICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICBpbnN0YW5jZVNldFF1ZXJ5T3B0aW9uc1snUVVFUllfT1BUSU9OUyddPSIkMiIKfQoKIyBAZGVzY3JpcHRpb24gYnkgZGVmYXVsdCB3ZSBza2lwIHRoZSBjb2x1bW4gbmFtZXMKIyBidXQgc29tZXRpbWVzIHdlIG5lZWQgY29sdW1uIG5hbWVzIHRvIGRpc3BsYXkgc29tZSByZXN1bHRzCiMgZGlzYWJsZSB0aGlzIG9wdGlvbiB0ZW1wb3JhcmlseSBhbmQgdGhlbiByZXN0b3JlIGl0IHRvIHRydWUKIwojIEBhcmcgJDEgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBza2lwQ29sdW1uTmFtZXM6Qm9vbGVhbiAwIHRvIGRpc2FibGUsIDEgdG8gZW5hYmxlIChoaWRlIGNvbHVtbiBuYW1lcykKRGF0YWJhc2U6OnNraXBDb2x1bW5OYW1lcygpIHsKICBsb2NhbCAtbiBpbnN0YW5jZVNraXBDb2x1bW5OYW1lcz0kMQogICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogIGluc3RhbmNlU2tpcENvbHVtbk5hbWVzWydTS0lQX0NPTFVNTl9OQU1FUyddPSIkMiIKfQoKIyBAZGVzY3JpcHRpb24gcHJlcGVuZCBkaXJlY3RvcmllcyB0byB0aGUgUEFUSCBlbnZpcm9ubWVudCB2YXJpYWJsZQojIEBhcmcgJEAgYXJnczpTdHJpbmdbXSBsaXN0IG9mIGRpcmVjdG9yaWVzIHRvIHByZXBlbmQKIyBAc2V0IFBBVEggdXBkYXRlIFBBVEggd2l0aCB0aGUgZGlyZWN0b3JpZXMgcHJlcGVuZGVkCkVudjo6cGF0aFByZXBlbmQoKSB7CiAgbG9jYWwgYXJnCiAgZm9yIGFyZyBpbiAiJEAiOyBkbwogICAgaWYgW1sgLWQgIiR7YXJnfSIgJiYgIjoke1BBVEh9OiIgIT0gKiI6JHthcmd9OiIqIF1dOyB0aGVuCiAgICAgIFBBVEg9IiQocmVhbHBhdGggIiR7YXJnfSIpOiR7UEFUSH0iCiAgICBmaQogIGRvbmUKfQoKIyBAZGVzY3JpcHRpb24gRGlzcGxheSBtZXNzYWdlIHVzaW5nIGVycm9yIGNvbG9yIChyZWQpIGFuZCBleGl0IGltbWVkaWF0ZWx5IHdpdGggZXJyb3Igc3RhdHVzIDEKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpmYXRhbCgpIHsKICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RkFUQUwgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBMb2c6OmxvZ0ZhdGFsICIkMSIKICBleGl0IDEKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ0RlYnVnKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID49IF9fTEVWRUxfREVCVUcpKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LURFQlVHfSIgIiQxIgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dJbmZvKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID49IF9fTEVWRUxfSU5GTykpOyB0aGVuCiAgICBMb2c6OmxvZ01lc3NhZ2UgIiR7MjotSU5GT30iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBlbnN1cmUgcnVubmluZyB1c2VyIGlzIG5vdCByb290CiMgQGV4aXRjb2RlIDEgaWYgY3VycmVudCB1c2VyIGlzIHJvb3QKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZApMaW51eDo6cmVxdWlyZUV4ZWN1dGVkQXNVc2VyKCkgewogIGlmIFtbICIkKGlkIC11KSIgPSAiMCIgXV07IHRoZW4KICAgIExvZzo6ZmF0YWwgInRoaXMgc2NyaXB0IHNob3VsZCBiZSBleGVjdXRlZCBhcyBub3JtYWwgdXNlciIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBnZXQgYWJzb2x1dGUgY29uZiBmaWxlIGZyb20gc3BlY2lmaWVkIGNvbmYgZm9sZGVyIGRlZHVjZWQgdXNpbmcgdGhlc2UgcnVsZXMKIyAgICogZnJvbSBhYnNvbHV0ZSBmaWxlIChpZ25vcmVzIDxjb25mRm9sZGVyPiBhbmQgPGV4dGVuc2lvbj4pCiMgICAqIHJlbGF0aXZlIHRvIHdoZXJlIHNjcmlwdCBpcyBleGVjdXRlZCAoaWdub3JlcyA8Y29uZkZvbGRlcj4gYW5kIDxleHRlbnNpb24+KQojICAgKiBmcm9tIGhvbWUvLmJhc2gtdG9vbHMvPGNvbmZGb2xkZXI+CiMgICAqIGZyb20gZnJhbWV3b3JrIGNvbmYvPGNvbmZGb2xkZXI+CiMKIyBAYXJnICQxIGNvbmZGb2xkZXI6U3RyaW5nIHRoZSBkaXJlY3RvcnkgbmFtZSAobm90IHRoZSBwYXRoKSB0byBsaXN0CiMgQGFyZyAkMiBjb25mOlN0cmluZyBmaWxlIHRvIHVzZSB3aXRob3V0IGV4dGVuc2lvbgojIEBhcmcgJDMgZXh0ZW5zaW9uOlN0cmluZyB0aGUgZXh0ZW5zaW9uICguc2ggYnkgZGVmYXVsdCkKIwojIEBzdGRvdXQgYWJzb2x1dGUgY29uZiBmaWxlbmFtZQojIEBleGl0Y29kZSAxIGlmIGZpbGUgaXMgbm90IGZvdW5kIGluIGFueSBsb2NhdGlvbgpDb25mOjpnZXRBYnNvbHV0ZUZpbGUoKSB7CiAgbG9jYWwgY29uZkZvbGRlcj0iJDEiCiAgbG9jYWwgY29uZj0iJDIiCiAgbG9jYWwgZXh0ZW5zaW9uPSIkezMtLnNofSIKICBpZiBbWyAtbiAiJHtleHRlbnNpb259IiAmJiAiJHtleHRlbnNpb246MDoxfSIgIT0gIi4iIF1dOyB0aGVuCiAgICBleHRlbnNpb249Ii4ke2V4dGVuc2lvbn0iCiAgZmkKCiAgdGVzdEFicygpIHsKICAgIGxvY2FsIHJlc3VsdAogICAgcmVzdWx0PSIkKHJlYWxwYXRoIC1lICIkMSIgMj4vZGV2L251bGwpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTgxCiAgICBpZiBbWyAiJD8iID0gIjAiICYmIC1mICIke3Jlc3VsdH0iIF1dOyB0aGVuCiAgICAgIGVjaG8gIiR7cmVzdWx0fSIKICAgICAgcmV0dXJuIDAKICAgIGZpCiAgICByZXR1cm4gMQogIH0KCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pCiAgdGVzdEFicyAiJHtjb25mRm9sZGVyfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICAjIGNvbmYgaXMgYWJzb2x1dGUgZmlsZQogIHRlc3RBYnMgIiR7Y29uZkZvbGRlcn0iICYmIHJldHVybiAwCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pCiAgdGVzdEFicyAiJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICAjIGNvbmYgaXMgYWJzb2x1dGUgZmlsZQogIHRlc3RBYnMgIiR7Y29uZn0iICYmIHJldHVybiAwCgogICMgcmVsYXRpdmUgdG8gd2hlcmUgc2NyaXB0IGlzIGV4ZWN1dGVkIChpbmNsdWRpbmcgZXh0ZW5zaW9uKQogIGlmIFtbIC1uICIke0NVUlJFTlRfRElSK3h4eH0iIF1dOyB0aGVuCiAgICB0ZXN0QWJzICIkKEZpbGU6OmNvbmNhdGVuYXRlUGF0aCAiJHtDVVJSRU5UX0RJUn0iICIke2NvbmZGb2xkZXJ9IikvJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICBmaQogICMgZnJvbSBob21lLy5iYXNoLXRvb2xzLzxjb25mRm9sZGVyPgogIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0hPTUV9Ly5iYXNoLXRvb2xzIiAiJHtjb25mRm9sZGVyfSIpLyR7Y29uZn0ke2V4dGVuc2lvbn0iICYmIHJldHVybiAwCgogIGlmIFtbIC1uICIke0ZSQU1FV09SS19ST09UX0RJUit4eHh9IiBdXTsgdGhlbgogICAgIyBmcm9tIGZyYW1ld29yayBjb25mLzxjb25mRm9sZGVyPiAoaW5jbHVkaW5nIGV4dGVuc2lvbikKICAgIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0ZSQU1FV09SS19ST09UX0RJUn0vY29uZiIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9JHtleHRlbnNpb259IiAmJiByZXR1cm4gMAoKICAgICMgZnJvbSBmcmFtZXdvcmsgY29uZi88Y29uZkZvbGRlcj4KICAgIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0ZSQU1FV09SS19ST09UX0RJUn0vY29uZiIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9IiAmJiByZXR1cm4gMAogIGZpCgogICMgZmlsZSBub3QgZm91bmQKICBMb2c6OmRpc3BsYXlFcnJvciAiY29uZiBmaWxlICcke2NvbmZ9JyBub3QgZm91bmQiCgogIHJldHVybiAxCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIGRzbiBmaWxlIGhhcyBhbGwgdGhlIG1hbmRhdG9yeSB2YXJpYWJsZXMgc2V0CiMgTWFuZGF0b3J5IHZhcmlhYmxlcyBhcmU6IEhPU1ROQU1FLCBVU0VSLCBQQVNTV09SRCwgUE9SVAojCiMgQGFyZyAkMSBkc25GaWxlTmFtZTpTdHJpbmcgZHNuIGFic29sdXRlIGZpbGVuYW1lCiMgQHNldCBIT1NUTkFNRSBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgUE9SVCBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgVVNFUiBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgUEFTU1dPUkQgbG9hZGVkIGZyb20gZHNuIGZpbGUKIyBAZXhpdGNvZGUgMCBvbiB2YWxpZCBmaWxlCiMgQGV4aXRjb2RlIDEgaWYgb25lIG9mIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBjb25mIGZpbGUgaXMgaW52YWxpZCBvciBpZiBmaWxlIG5vdCBmb3VuZAojIEBzdGRlcnIgbG9nIG91dHB1dCBpZiBlcnJvciBmb3VuZCBpbiBjb25mIGZpbGUKRGF0YWJhc2U6OmNoZWNrRHNuRmlsZSgpIHsKICBsb2NhbCBkc25GaWxlTmFtZT0iJDEiCiAgaWYgW1sgISAtZiAiJHtkc25GaWxlTmFtZX0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gbm90IGZvdW5kIgogICAgcmV0dXJuIDEKICBmaQoKICAoCiAgICB1bnNldCBIT1NUTkFNRSBQT1JUIFBBU1NXT1JEIFVTRVIKICAgICMgc2hlbGxjaGVjayBzb3VyY2U9L3NyYy9EYXRhYmFzZS90ZXN0c0RhdGEvZHNuX3ZhbGlkLmVudgogICAgc291cmNlICIke2RzbkZpbGVOYW1lfSIKICAgIGlmIFtbIC16ICR7SE9TVE5BTUUreH0gXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogSE9TVE5BTUUgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke0hPU1ROQU1FfSIgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5V2FybmluZyAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBIT1NUTkFNRSB2YWx1ZSBub3QgcHJvdmlkZWQiCiAgICBmaQogICAgaWYgW1sgIiR7SE9TVE5BTUV9IiA9ICJsb2NhbGhvc3QiIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheVdhcm5pbmcgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogY2hlY2sgdGhhdCBIT1NUTkFNRSBzaG91bGQgbm90IGJlIDEyNy4wLjAuMSBpbnN0ZWFkIG9mIGxvY2FsaG9zdCIKICAgIGZpCiAgICBpZiBbWyAteiAiJHtQT1JUK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBQT1JUIG5vdCBwcm92aWRlZCIKICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBpZiAhIFtbICR7UE9SVH0gPX4gXlswLTldKyQgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogUE9SVCBpbnZhbGlkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke1VTRVIreH0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJkc24gZmlsZSAke2RzbkZpbGVOYW1lfSA6IFVTRVIgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke1BBU1NXT1JEK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBQQVNTV09SRCBub3QgcHJvdmlkZWQiCiAgICAgIHJldHVybiAxCiAgICBmaQogICkKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ0ZhdGFsKCkgewogIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1GQVRBTH0iICIkMSIKfQoKIyBAZGVzY3JpcHRpb24gSW50ZXJuYWw6IGNvbW1vbiBsb2cgbWVzc2FnZQojIEBleGFtcGxlIHRleHQKIyAgIFtkYXRlXXxbbGV2ZWxNc2ddfG1lc3NhZ2UKIwojIEBleGFtcGxlIHRleHQKIyAgIDIwMjAtMDEtMTkgMTk6MjA6MjF8RVJST1IgIHxsb2cgZXJyb3IKIyAgIDIwMjAtMDEtMTkgMTk6MjA6MjF8U0tJUFBFRHxsb2cgc2tpcHBlZAojCiMgQGFyZyAkMSBsZXZlbE1zZzpTdHJpbmcgbWVzc2FnZSdzIGxldmVsIGRlc2NyaXB0aW9uIChlZzogU1RBVFVTLCBFUlJPUiwgLi4uKQojIEBhcmcgJDIgbXNnOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfRklMRSBTdHJpbmcgbG9nIGZpbGUgdG8gdXNlLCBkbyBub3RoaW5nIGlmIGVtcHR5CiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgaW50IGxvZyBsZXZlbCBsb2cgb25seSBpZiA+IE9GRiBvciBmYXRhbCBtZXNzYWdlcwojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gaXMgZGlzcGxheWVkCiMgQHJlcXVpcmUgRW52OjpyZXF1aXJlTG9hZAojIEByZXF1aXJlIExvZzo6cmVxdWlyZUxvYWQKTG9nOjpsb2dNZXNzYWdlKCkgewogIGxvY2FsIGxldmVsTXNnPSIkMSIKICBsb2NhbCBtc2c9IiQyIgogIGxvY2FsIGRhdGUKCiAgaWYgW1sgLW4gIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXSAmJiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+IF9fTEVWRUxfT0ZGKSk7IHRoZW4KICAgIGRhdGU9IiQoZGF0ZSAnKyVZLSVtLSVkICVIOiVNOiVTJykiCiAgICB0b3VjaCAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iCiAgICBwcmludGYgIiVzfCU3c3wlc1xuIiAiJHtkYXRlfSIgIiR7bGV2ZWxNc2d9IiAiJHttc2d9IiA+PiIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBjb25jYXRlbmF0ZSAyIHBhdGhzIGFuZCBlbnN1cmUgdGhlIHBhdGggaXMgY29ycmVjdCB1c2luZyByZWFscGF0aCAtbQojIEBhcmcgJDEgYmFzZVBhdGg6U3RyaW5nCiMgQGFyZyAkMiBzdWJQYXRoOlN0cmluZwojIEByZXF1aXJlIExpbnV4OjpyZXF1aXJlUmVhbHBhdGhDb21tYW5kCkZpbGU6OmNvbmNhdGVuYXRlUGF0aCgpIHsKICBsb2NhbCBiYXNlUGF0aD0iJDEiCiAgbG9jYWwgc3ViUGF0aD0iJDIiCiAgbG9jYWwgZnVsbFBhdGg9IiR7YmFzZVBhdGg6KyR7YmFzZVBhdGh9L30ke3N1YlBhdGh9IgoKICByZWFscGF0aCAtbSAiJHtmdWxsUGF0aH0iIDI+L2Rldi9udWxsCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBlcnJvciBjb2xvciAocmVkKQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlFcnJvcigpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUwgPj0gX19MRVZFTF9FUlJPUikpOyB0aGVuCiAgICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RVJST1IgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nRXJyb3IgIiQxIgp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgd2FybmluZyBjb2xvciAoeWVsbG93KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlXYXJuaW5nKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX1dBUk5JTkcpKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX1dBUk5JTkdfQ09MT1J9V0FSTiAgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nV2FybmluZyAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBlbnYgZmlsZXMgYXJlIGxvYWRlZAojIEBub2FyZ3MKIyBAZXhpdGNvZGUgMSBpZiBnZXRPcmRlcmVkQ29uZkZpbGVzIGZhaWxzCiMgQGV4aXRjb2RlIDIgaWYgb25lIG9mIGVudiBmaWxlcyBmYWlscyB0byBsb2FkCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKRW52OjpyZXF1aXJlTG9hZCgpIHsKICBsb2NhbCBjb25maWdGaWxlc1N0cgogIGNvbmZpZ0ZpbGVzU3RyPSIkKEVudjo6Z2V0T3JkZXJlZENvbmZGaWxlcykiIHx8IHJldHVybiAxCgogIGxvY2FsIC1hIGNvbmZpZ0ZpbGVzCiAgcmVhZGFycmF5IC10IGNvbmZpZ0ZpbGVzIDw8PCIke2NvbmZpZ0ZpbGVzU3RyfSIKCiAgIyBpZiBlbXB0eSBzdHJpbmcsIHRoZXJlIHdpbGwgYmUgb25lIGVsZW1lbnQKICBpZiAoKCR7I2NvbmZpZ0ZpbGVzW0BdfSA9PSAwKSkgfHwgW1sgLXogIiR7Y29uZmlnRmlsZXNTdHJ9IiBdXTsgdGhlbgogICAgIyBzaG91bGQgbm90IGhhcHBlbiwgYXMgdGhlcmUgaXMgYWx3YXlzIGRlZmF1bHQgZmlsZQogICAgTG9nOjpkaXNwbGF5U2tpcHBlZCAibm8gZW52IGZpbGUgdG8gbG9hZCIKICAgIHJldHVybiAwCiAgZmkKCiAgRW52OjptZXJnZUNvbmZGaWxlcyAiJHtjb25maWdGaWxlc1tAXX0iIHx8IHsKICAgIExvZzo6ZGlzcGxheUVycm9yICJ3aGlsZSBsb2FkaW5nIGNvbmZpZyBmaWxlczogJHtjb25maWdGaWxlc1sqXX0iCiAgICByZXR1cm4gMgogIH0KfQoKIyBAZGVzY3JpcHRpb24gYWN0aXZhdGUgb3Igbm90IExvZzo6ZGlzcGxheSogYW5kIExvZzo6bG9nKiBmdW5jdGlvbnMKIyBiYXNlZCBvbiBCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMIGFuZCBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwKIyBlbnZpcm9ubWVudCB2YXJpYWJsZXMgbG9hZGVkIGJ5IEVudjo6cmVxdWlyZUxvYWQKIyB0cnkgdG8gY3JlYXRlIGxvZyBmaWxlIGFuZCByb3RhdGUgaXQgaWYgbmVjZXNzYXJ5CiMgQG5vYXJncwojIEBzZXQgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludCB0byBPRkYgbGV2ZWwgaWYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgaXMgZW1wdHkgb3Igbm90IHdyaXRhYmxlCiMgQGVudiBCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMIGludAojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludAojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgU3RyaW5nCiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfRklMRV9NQVhfUk9UQVRJT04gaW50IGRvIGxvZyByb3RhdGlvbiBpZiA+IDAKIyBAZXhpdGNvZGUgMCBhbHdheXMgc3VjY2Vzc2Z1bAojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gYWJvdXQgbG9nIGZpbGUgaXMgZGlzcGxheWVkCiMgQHJlcXVpcmUgRW52OjpyZXF1aXJlTG9hZAojIEByZXF1aXJlIFVJOjpyZXF1aXJlVGhlbWUKTG9nOjpyZXF1aXJlTG9hZCgpIHsKICBpZiBbWyAteiAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRTotfSIgXV07IHRoZW4KICAgIEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTD0ke19fTEVWRUxfT0ZGfQogICAgZXhwb3J0IEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTAogIGZpCgogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID4gX19MRVZFTF9PRkYpKTsgdGhlbgogICAgaWYgW1sgISAtZiAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iIF1dOyB0aGVuCiAgICAgIGlmCiAgICAgICAgISBta2RpciAtcCAiJChkaXJuYW1lICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIpIiAyPi9kZXYvbnVsbCB8fAogICAgICAgICAgISB0b3VjaCAtLW5vLWNyZWF0ZSAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iIDI+L2Rldi9udWxsCiAgICAgIHRoZW4KICAgICAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgICAgICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RVJST1IgICAtIEZpbGUgJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0gaXMgbm90IHdyaXRhYmxlJHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgICAgIGZpCiAgICBlbGlmIFtbICEgLXcgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXTsgdGhlbgogICAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgICAgZWNobyAtZSAiJHtfX0VSUk9SX0NPTE9SfUVSUk9SICAgLSBGaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IGlzIG5vdCB3cml0YWJsZSR7X19SRVNFVF9DT0xPUn0iID4mMgogICAgZmkKCiAgZmkKCiAgaWYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPiBfX0xFVkVMX09GRikpOyB0aGVuCiAgICAjIHdpbGwgYWx3YXlzIGJlIGNyZWF0ZWQgZXZlbiBpZiBub3QgaW4gaW5mbyBsZXZlbAogICAgTG9nOjpsb2dNZXNzYWdlICJJTkZPIiAiTG9nZ2luZyB0byBmaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IC0gTG9nIGxldmVsICR7QkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMfSIKICAgIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OID4gMCkpOyB0aGVuCiAgICAgIExvZzo6cm90YXRlICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OfSIKICAgIGZpCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZ2V0IGxpc3Qgb2YgZW52IGZpbGVzIHRvIGxvYWQKIyBpbiBvcmRlciB0byBtYWtlIHRoZW0gYXZhaWxhYmxlIGZvciBFbnY6OnJlcXVpcmVMb2FkCiMgQGVudiBCQVNIX0ZSQU1FV09SS19FTlZfRklMRVMgU3RyaW5nW10gbGlzdCBvZiBlbnYgZmlsZXMgdGhhdCBzaG91bGQgYmUgbG9hZGVkCiMgQGV4aXRjb2RlIDEgaWYgb25lIG9mIHRoZSBlbnYgZmlsZSBjYW5ub3QgYmUgZ2VuZXJhdGVkCiMgQGV4aXRjb2RlIDIgaWYgb25lIG9mIHRoZSBlbnYgZmlsZSBpcyBub3QgYSBmaWxlIG9yIHJlYWRhYmxlCiMgQHN0ZG91dCB0aGUgZW52IGZpbGVzIGFza2VkIHRvIGJlIGxvYWRlZAojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiBvbiBmYWlsdXJlCiMgQHNlZSBodHRwczovL2dpdGh1Yi5jb20vZmNoYXN0YW5ldC9iYXNoLXRvb2xzLWZyYW1ld29yay9ibG9iL21hc3Rlci9GcmFtZXdvcmtEb2MubWQjY29uZmlnX2ZpbGVfb3JkZXIKRW52OjpnZXRPcmRlcmVkQ29uZkZpbGVzKCkgewogIGxvY2FsIC1hIGNvbmZpZ0ZpbGVzPSgpCgogIGlmIFtbIC1uICIke0JBU0hfRlJBTUVXT1JLX0VOVl9GSUxFU1swXSsxfSIgXV07IHRoZW4KICAgICMgQkFTSF9GUkFNRVdPUktfRU5WX0ZJTEVTIGlzIGFuIGFycmF5CiAgICBjb25maWdGaWxlcys9KCIke0JBU0hfRlJBTUVXT1JLX0VOVl9GSUxFU1tAXX0iKQogIGZpCgogIGxvY2FsIGRlZmF1bHRFbnZGaWxlCiAgZGVmYXVsdEVudkZpbGU9IiQoRW52OjpjcmVhdGVEZWZhdWx0RW52RmlsZSkiIHx8IHJldHVybiAxCiAgY29uZmlnRmlsZXMrPSgiJHtkZWZhdWx0RW52RmlsZX0iKQoKICBsb2NhbCBmaWxlCiAgZm9yIGZpbGUgaW4gIiR7Y29uZmlnRmlsZXNbQF19IjsgZG8KICAgIGlmIFtbICEgLWYgIiR7ZmlsZX0iIHx8ICEgLXIgIiR7ZmlsZX0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJPbmUgb2YgdGhlIGNvbmZpZyBmaWxlIGlzIG5vdCBhdmFpbGFibGUgJyR7ZmlsZX0nIgogICAgICByZXR1cm4gMgogICAgZmkKICAgIGVjaG8gIiR7ZmlsZX0iCiAgZG9uZQp9CgojIEBkZXNjcmlwdGlvbiBtZXJnZSBhbmQgbG9hZCBjb25mIGZpbGVzIHNwZWNpZmllZCBhcyBhcmd1bWVudAojIC0gZmlsZXMgYXJlIGNsZWFuZWQgZnJvbSBheSBjb21tZW50CiMgLSBtaXNzaW5nIHF1b3RlcyBhZnRlciBwcm9wZXJ0eSA9IHNpZ24gYXJlIGFkZGVkIGF1dG9tYXRpY2FsbHkKIyAtIGF1dG9tYXRpYyByZW1vdmUgb2YgYWxsIHdoaXRlc3BhY2UgYmVmb3JlIGFuZCBhZnRlciBkZWNsYXJhdGlvbnMKIyAtIGJhc2ggYXJyYXlzIGFyZSBub3Qgc3VwcG9ydGVkCiMgLSBpZiBhIHZhcmlhYmxlIGlzIGRlY2xhcmVkIGluIGZpcnN0IGZpbGUgYW5kIG92ZXJyaWRkZW4gbGF0ZXIgb24KIyAgIGluIHRoZSBzYW1lIGZpbGUgb3IgaW4gc3Vic2VxdWVudCBmaWxlcywgdGhvc2Ugb3ZlcmxvYWRzIHdpbGwgYmUKIyAgIGlnbm9yZWQKIyBAd2FybmluZyBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgbG9hZGluZyBvbmUgb2YgdGhlIGNvbmZpZyBmaWxlLCBleGl0IGNvZGUgMyBidXQgZW52aXJvbm1lbnQgY291bGQgYmUgcGFydGlhbGx5IGxvYWRlZAojIEBhcmcgJEAgYXJnczpTdHJpbmdbXSBsaXN0IG9mIGNvbmZpZ3VyYXRpb24gZmlsZXMgdG8gbG9hZCBpbiBvcmRlcgojIEBzZXQgZW52VmFycyBTdHJpbmcgd2lsbCBzZXQgaW4gZW52aXJvbm1lbnQgYWxsIHRoZSB2YXJpYWJsZXMgdGhhdCBoYXZlIGJlZW4gZGVjbGFyZWQgaW4gdGhlIGNvbmZpZyBmaWxlcwojIEBlbnYgZW52VmFycyBTdHJpbmcgdGhlIGVudiB2YXJpYWJsZXMgb2YgdGhlIGN1cnJlbnQgc2NyaXB0IGNvdWxkIGJlIHVzZWQgdG8gaW50ZXJwcmV0IHZhcmlhYmxlcyBkdXJpbmcgY29uZmlnIGZpbGVzIHBhcnNpbmcKIyBAZXhpdGNvZGUgMCBpZiBubyBjb25maWcgZmlsZXMgcHJvdmlkZWQgb3IgbG9hZCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5CiMgQGV4aXRjb2RlIDEgaWYgZXJyb3Igb2NjdXJyZWQgZHVyaW5nIHBhcnNpbmcgdGhlIGNvbmZpZyBmaWxlcyAoZmlsZSBub3QgZm91bmQsIGdyZXAsIGF3ayBvciBzZWQgZXJyb3IpCiMgQGV4aXRjb2RlIDIgaWYgdGVtcG9yYXJ5IGZpbGUgY2Fubm90IGJlIGNyZWF0ZWQKIyBAZXhpdGNvZGUgMyBpZiBhbiBlcnJvciBvY2N1cnJlZCBkdXJpbmcgY29uZmlnIGZpbGUgc291cmNpbmcKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZAojIEBzZWUgbGFyZ2VseSBpbnNwaXJlZCBidXQgbW9kaWZpZWQgZnJvbSBodHRwczovL29wZW5zb3VyY2UuY29tL2FydGljbGUvMjEvNS9wcm9jZXNzaW5nLWNvbmZpZ3VyYXRpb24tZmlsZXMtc2hlbGwKRW52OjptZXJnZUNvbmZGaWxlcygpIHsKICBsb2NhbCAtYSBjb25maWdGaWxlTGlzdD0oIiRAIikKCiAgaWYgKCgkeyNjb25maWdGaWxlTGlzdFtAXX0gPT0gMCkpOyB0aGVuCiAgICByZXR1cm4gMAogIGZpCgogIGxvY2FsIGNvbWJpbmVkQ29uZmlnRmlsZQogIGNvbWJpbmVkQ29uZmlnRmlsZT0iJChGcmFtZXdvcms6OmNyZWF0ZVRlbXBGaWxlICJtZXJnZUNvbmZGaWxlcyIpIiB8fCByZXR1cm4gMgoKICAoCiAgICAjIHJlbW92ZXMgYW55IHRyYWlsaW5nIHdoaXRlc3BhY2UgZnJvbSBlYWNoIGZpbGUsIGlmIGFueQogICAgIyB0aGlzIGlzIGFic29sdXRlbHkgcmVxdWlyZWQgd2hlbiBpbXBvcnRpbmcgaW50byBDb25maWdNYXBzCiAgICAjIHB1dCBxdW90ZXMgYXJvdW5kIHZhbHVlcwogICAgc2VkIC1FIC1lICQncy9ccyokLy8gOyAvXiQvZCA7IC9eIy4qJC9kIDsgcy89KFteIlwnXS4qKSQvPSJcXDEiLycgIiR7Y29uZmlnRmlsZUxpc3RbQF19IiB8CiAgICAgICMgcmVtb3ZlIGFsbCBjb21tZW50IGxpbmVzCiAgICAgIEZpbHRlcnM6OmNvbW1lbnRMaW5lcyB8CiAgICAgICMgaXRlcmF0ZXMgb3ZlciBlYWNoIGZpbGUgYW5kIHByaW50cyAoZGVmYXVsdCBhd2sgYmVoYXZpb3IpCiAgICAgICMgZWFjaCB1bmlxdWUgbGluZTsgb25seSB0YWtlcyBmaXJzdCB2YWx1ZSBhbmQgaWdub3JlcyBkdXBsaWNhdGVzCiAgICAgIGF3ayAtRj0gJyFsaW5lWyQxXSsrJwogICkgPiIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAxCgogICMgaGF2ZSB0byBleHBvcnQgZXZlcnl0aGluZywgYW5kIHNvdXJjZSBpdCB0d2ljZToKICAjIDEpIGZpcnN0IHNvdXJjZSBpcyB0byByZWFsaXplIHZhcmlhYmxlcwogICMgMikgc2Vjb25kIHRpbWUgaXMgdG8gcmVhbGl6ZSByZWZlcmVuY2VzCiAgc2V0IC1vIGFsbGV4cG9ydAogICMgc2hlbGxjaGVjayBzb3VyY2U9LmZyYW1ld29yay1jb25maWcKICBzb3VyY2UgIiR7Y29tYmluZWRDb25maWdGaWxlfSIgfHwgcmV0dXJuIDMKICAjIHNoZWxsY2hlY2sgc291cmNlPS5mcmFtZXdvcmstY29uZmlnCiAgc291cmNlICIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAzCiAgc2V0ICtvIGFsbGV4cG9ydAp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgc2tpcCBjb2xvciAoeWVsbG93KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlTa2lwcGVkKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX1NLSVBQRURfQ09MT1J9U0tJUFBFRCAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nU2tpcHBlZCAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dFcnJvcigpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0VSUk9SKSk7IHRoZW4KICAgIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1FUlJPUn0iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nV2FybmluZygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX1dBUk5JTkcpKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LVdBUk5JTkd9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gVG8gYmUgY2FsbGVkIGJlZm9yZSBsb2dnaW5nIGluIHRoZSBsb2cgZmlsZQojIEBhcmcgJDEgZmlsZTpzdHJpbmcgbG9nIGZpbGUgbmFtZQojIEBhcmcgJDIgbWF4TG9nRmlsZXNDb3VudDppbnQgbWF4aW11bSBudW1iZXIgb2YgbG9nIGZpbGVzCkxvZzo6cm90YXRlKCkgewogIGxvY2FsIGZpbGU9IiQxIgogIGxvY2FsIG1heExvZ0ZpbGVzQ291bnQ9IiR7MjotNX0iCgogIGlmIFtbICEgLWYgIiR7ZmlsZX0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlTa2lwcGVkICJMb2cgZmlsZSAke2ZpbGV9IGRvZXNuJ3QgZXhpc3QgeWV0IgogICAgcmV0dXJuIDAKICBmaQogIGZvciBpIGluICQoc2VxICQoKG1heExvZ0ZpbGVzQ291bnQgLSAxKSkgLTEgMSk7IGRvCiAgICBMb2c6OmRpc3BsYXlJbmZvICJMb2cgcm90YXRpb24gJHtmaWxlfS4ke2l9IHRvICR7ZmlsZX0uJCgoaSArIDEpKSIKICAgIG12ICIke2ZpbGV9LiJ7IiR7aX0iLCIkKChpICsgMSkpIn0gJj4vZGV2L251bGwgfHwgdHJ1ZQogIGRvbmUKICBpZiBjcCAiJHtmaWxlfSIgIiR7ZmlsZX0uMSIgJj4vZGV2L251bGw7IHRoZW4KICAgIGVjaG8gPiIke2ZpbGV9IiAjIHJlc2V0IGxvZyBmaWxlCiAgICBMb2c6OmRpc3BsYXlJbmZvICJMb2cgcm90YXRpb24gJHtmaWxlfSB0byAke2ZpbGV9LjEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZW5zdXJlIGNvbW1hbmQgcmVhbHBhdGggaXMgYXZhaWxhYmxlCiMgQGV4aXRjb2RlIDEgaWYgcmVhbHBhdGggY29tbWFuZCBub3QgYXZhaWxhYmxlCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKTGludXg6OnJlcXVpcmVSZWFscGF0aENvbW1hbmQoKSB7CiAgQXNzZXJ0Ojpjb21tYW5kRXhpc3RzIHJlYWxwYXRoCn0KCiMgQGRlc2NyaXB0aW9uIGxvYWQgY29sb3IgdGhlbWUKIyBAbm9hcmdzCiMgQGVudiBCQVNIX0ZSQU1FV09SS19USEVNRSBTdHJpbmcgdGhlbWUgdG8gdXNlCiMgQGV4aXRjb2RlIDAgYWx3YXlzIHN1Y2Nlc3NmdWwKVUk6OnJlcXVpcmVUaGVtZSgpIHsKICBVSTo6dGhlbWUgIiR7QkFTSF9GUkFNRVdPUktfVEhFTUUtZGVmYXVsdH0iCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIGNvbW1hbmQgc3BlY2lmaWVkIGV4aXN0cyBvciByZXR1cm4gMQojIHdpdGggZXJyb3IgYW5kIG1lc3NhZ2UgaWYgbm90CiMKIyBAYXJnICQxIGNvbW1hbmROYW1lOlN0cmluZyBvbiB3aGljaCBleGlzdGVuY2UgbXVzdCBiZSBjaGVja2VkCiMgQGFyZyAkMiBoZWxwSWZOb3RFeGlzdHM6U3RyaW5nIGEgaGVscCBjb21tYW5kIHRvIGRpc3BsYXkgaWYgdGhlIGNvbW1hbmQgZG9lcyBub3QgZXhpc3QKIwojIEBleGl0Y29kZSAxIGlmIHRoZSBjb21tYW5kIHNwZWNpZmllZCBkb2VzIG5vdCBleGlzdAojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiArIGhlbHAgaWYgc2Vjb25kIGFyZ3VtZW50IGlzIHByb3ZpZGVkCkFzc2VydDo6Y29tbWFuZEV4aXN0cygpIHsKICBsb2NhbCBjb21tYW5kTmFtZT0iJDEiCiAgbG9jYWwgaGVscElmTm90RXhpc3RzPSIkMiIKCiAgIiR7QkFTSF9GUkFNRVdPUktfQ09NTUFORDotY29tbWFuZH0iIC12ICIke2NvbW1hbmROYW1lfSIgPi9kZXYvbnVsbCAyPi9kZXYvbnVsbCB8fCB7CiAgICBMb2c6OmRpc3BsYXlFcnJvciAiJHtjb21tYW5kTmFtZX0gaXMgbm90IGluc3RhbGxlZCwgcGxlYXNlIGluc3RhbGwgaXQiCiAgICBpZiBbWyAtbiAiJHtoZWxwSWZOb3RFeGlzdHN9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlJbmZvICIke2hlbHBJZk5vdEV4aXN0c30iCiAgICBmaQogICAgcmV0dXJuIDEKICB9CiAgcmV0dXJuIDAKfQoKIyBAZGVzY3JpcHRpb24gZGVmYXVsdCBlbnYgZmlsZSB3aXRoIGFsbCBkZWZhdWx0IHZhbHVlcwojIEBzdGRvdXQgdGhlIGRlZmF1bHQgZW52IGZpbGVwYXRoCkVudjo6Y3JlYXRlRGVmYXVsdEVudkZpbGUoKSB7CiAgbG9jYWwgZW52RmlsZQogIGVudkZpbGU9IiQoRnJhbWV3b3JrOjpjcmVhdGVUZW1wRmlsZSAiY3JlYXRlRGVmYXVsdEVudkZpbGVFbnZGaWxlIikiIHx8IHJldHVybiAyCgogICgKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX1RIRU1FPSR7QkFTSF9GUkFNRVdPUktfVEhFTUU6LWRlZmF1bHR9IgogICAgZWNobyAiQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMPSR7QkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMOi0wfSIKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUw9JHtCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMOi0ke19fTEVWRUxfV0FSTklOR319IgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDE2CiAgICBlY2hvICdCQVNIX0ZSQU1FV09SS19MT0dfRklMRT0iJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRTotIiR7RlJBTUVXT1JLX1JPT1RfRElSfS9sb2dzLyR7U0NSSVBUX05BTUV9LmxvZyJ9IicKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTj0ke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTjotNX0iCiAgKSA+IiR7ZW52RmlsZX0iCiAgZWNobyAiJHtlbnZGaWxlfSIKfQoKIyBAZGVzY3JpcHRpb24gcmVtb3ZlIGNvbW1lbnQgbGluZXMgZnJvbSBpbnB1dCBvciBmaWxlcyBwcm92aWRlZCBhcyBhcmd1bWVudHMKIyBAYXJnICRAIGZpbGVzOlN0cmluZ1tdIChvcHRpb25hbCkgdGhlIGZpbGVzIHRvIGZpbHRlcgojIEBlbnYgY29tbWVudExpbmVQcmVmaXggU3RyaW5nIHRoZSBjb21tZW50IGxpbmUgcHJlZml4IChkZWZhdWx0IHZhbHVlOiAjKQojIEBleGl0Y29kZSAwIGlmIGxpbmVzIGZpbHRlcmVkIG9yIG5vdAojIEBleGl0Y29kZSAyIGlmIGdyZXAgZmFpbHMgZm9yIGFueSBvdGhlciByZWFzb25zIHRoYW4gbm90IGZvdW5kCiMgQHN0ZGluIHRoZSBmaWxlIGFzIHN0ZGluIHRvIGZpbHRlciAoYWx0ZXJuYXRpdmUgdG8gZmlsZXMgYXJndW1lbnQpCiMgQHN0ZG91dCB0aGUgZmlsdGVyZWQgbGluZXMKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTIwCkZpbHRlcnM6OmNvbW1lbnRMaW5lcygpIHsKICBncmVwIC12eEUgIltbOmJsYW5rOl1dKigke2NvbW1lbnRMaW5lUHJlZml4Oi0jfS4qKT8iICIkQCIgfHwgdGVzdCAkPyA9IDEKfQoKIyBAZGVzY3JpcHRpb24gY3JlYXRlIGEgdGVtcCBmaWxlIHVzaW5nIGRlZmF1bHQgVE1QRElSIHZhcmlhYmxlCiMgaW5pdGlhbGl6ZWQgaW4gX2luY2x1ZGVzL19jb21tb25IZWFkZXIuc2gKIyBAZW52IFRNUERJUiBTdHJpbmcgKGRlZmF1bHQgdmFsdWUgL3RtcCkKIyBAYXJnICQxIHRlbXBsYXRlTmFtZTpTdHJpbmcgdGVtcGxhdGUgbmFtZSB0byB1c2Uob3B0aW9uYWwpCkZyYW1ld29yazo6Y3JlYXRlVGVtcEZpbGUoKSB7CiAgbWt0ZW1wIC1wICIke1RNUERJUjotL3RtcH0iIC10ICIkezE6LX0uWFhYWFhYWFhYWFhYIgp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nU2tpcHBlZCgpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LVNLSVBQRUR9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gbG9hZCBjb2xvcnMgdGhlbWUgY29uc3RhbnRzCiMgQHdhcm5pbmcgaWYgdHR5IG5vdCBvcGVuZWQsIG5vQ29sb3IgdGhlbWUgd2lsbCBiZSBjaG9zZW4KIyBAYXJnICQxIHRoZW1lOlN0cmluZyB0aGUgdGhlbWUgdG8gdXNlIChkZWZhdWx0LCBub0NvbG9yKQojIEBhcmcgJEAgYXJnczpTdHJpbmdbXQojIEBzZXQgX19FUlJPUl9DT0xPUiBTdHJpbmcgaW5kaWNhdGUgZXJyb3Igc3RhdHVzCiMgQHNldCBfX0lORk9fQ09MT1IgU3RyaW5nIGluZGljYXRlIGluZm8gc3RhdHVzCiMgQHNldCBfX1NVQ0NFU1NfQ09MT1IgU3RyaW5nIGluZGljYXRlIHN1Y2Nlc3Mgc3RhdHVzCiMgQHNldCBfX1dBUk5JTkdfQ09MT1IgU3RyaW5nIGluZGljYXRlIHdhcm5pbmcgc3RhdHVzCiMgQHNldCBfX1NLSVBQRURfQ09MT1IgU3RyaW5nIGluZGljYXRlIHNraXBwZWQgc3RhdHVzCiMgQHNldCBfX0RFQlVHX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSBkZWJ1ZyBzdGF0dXMKIyBAc2V0IF9fSEVMUF9DT0xPUiBTdHJpbmcgaW5kaWNhdGUgaGVscCBzdGF0dXMKIyBAc2V0IF9fVEVTVF9DT0xPUiBTdHJpbmcgbm90IHVzZWQKIyBAc2V0IF9fVEVTVF9FUlJPUl9DT0xPUiBTdHJpbmcgbm90IHVzZWQKIyBAc2V0IF9fSEVMUF9USVRMRV9DT0xPUiBTdHJpbmcgdXNlZCB0byBkaXNwbGF5IGhlbHAgdGl0bGUgaW4gaGVscCBzdHJpbmdzCiMgQHNldCBfX0hFTFBfT1BUSU9OX0NPTE9SIFN0cmluZyB1c2VkIHRvIGRpc3BsYXkgaGlnaGxpZ2h0IG9wdGlvbnMgaW4gaGVscCBzdHJpbmdzCiMKIyBAc2V0IF9fUkVTRVRfQ09MT1IgU3RyaW5nIHJlc2V0IGRlZmF1bHQgY29sb3IKIwojIEBzZXQgX19IRUxQX0VYQU1QTEUgU3RyaW5nIHRvIHJlbW92ZQojIEBzZXQgX19IRUxQX1RJVExFIFN0cmluZyB0byByZW1vdmUKIyBAc2V0IF9fSEVMUF9OT1JNQUwgU3RyaW5nIHRvIHJlbW92ZQojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKVUk6OnRoZW1lKCkgewogIGxvY2FsIHRoZW1lPSIkezEtZGVmYXVsdH0iCiAgaWYgW1sgISAiJHt0aGVtZX0iID1+IC1mb3JjZSQgXV0gJiYgISBBc3NlcnQ6OnR0eTsgdGhlbgogICAgdGhlbWU9Im5vQ29sb3IiCiAgZmkKICBjYXNlICIke3RoZW1lfSIgaW4KICAgIGRlZmF1bHQgfCBkZWZhdWx0LWZvcmNlKQogICAgICB0aGVtZT0iZGVmYXVsdCIKICAgICAgOzsKICAgIG5vQ29sb3IpIDs7CiAgICAqKQogICAgICBMb2c6OmZhdGFsICJpbnZhbGlkIHRoZW1lIHByb3ZpZGVkIgogICAgICA7OwogIGVzYWMKICBpZiBbWyAiJHt0aGVtZX0iID0gImRlZmF1bHQiIF1dOyB0aGVuCiAgICBCQVNIX0ZSQU1FV09SS19USEVNRT0iZGVmYXVsdCIKICAgICMgY2hlY2sgY29sb3JzIGFwcGxpY2FibGUgaHR0cHM6Ly9taXNjLmZsb2dpc29mdC5jb20vYmFzaC90aXBfY29sb3JzX2FuZF9mb3JtYXR0aW5nCiAgICBfX0VSUk9SX0NPTE9SPSdcZVszMW0nICAgICAgICAgIyBSZWQKICAgIF9fSU5GT19DT0xPUj0nXGVbNDRtJyAgICAgICAgICAjIHdoaXRlIG9uIGxpZ2h0Qmx1ZQogICAgX19TVUNDRVNTX0NPTE9SPSdcZVszMm0nICAgICAgICMgR3JlZW4KICAgIF9fV0FSTklOR19DT0xPUj0nXGVbMzNtJyAgICAgICAjIFllbGxvdwogICAgX19TS0lQUEVEX0NPTE9SPSdcZVszM20nICAgICAgICMgWWVsbG93CiAgICBfX0RFQlVHX0NPTE9SPSdcZVszN20nICAgICAgICAgIyBHcmV5CiAgICBfX0hFTFBfQ09MT1I9J1xlWzc7NDk7MzNtJyAgICAgIyBCbGFjayBvbiBHb2xkCiAgICBfX1RFU1RfQ09MT1I9J1xlWzEwMG0nICAgICAgICAgIyBMaWdodCBtYWdlbnRhCiAgICBfX1RFU1RfRVJST1JfQ09MT1I9J1xlWzQxbScgICAgIyB3aGl0ZSBvbiByZWQKICAgIF9fSEVMUF9USVRMRV9DT0xPUj0iXGVbMTszN20iICAjIEJvbGQKICAgIF9fSEVMUF9PUFRJT05fQ09MT1I9IlxlWzE7MzRtIiAjIEJsdWUKICAgICMgSW50ZXJuYWw6IHJlc2V0IGNvbG9yCiAgICBfX1JFU0VUX0NPTE9SPSdcZVswbScgIyBSZXNldCBDb2xvcgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU1LFNDMjAzNAogICAgX19IRUxQX0VYQU1QTEU9IiQoZWNobyAtZSAiXGVbMjs5N20iKSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE1NSxTQzIwMzQKICAgIF9fSEVMUF9USVRMRT0iJChlY2hvIC1lICJcZVsxOzM3bSIpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU1LFNDMjAzNAogICAgX19IRUxQX05PUk1BTD0iJChlY2hvIC1lICJcMDMzWzBtIikiCiAgZWxzZQogICAgQkFTSF9GUkFNRVdPUktfVEhFTUU9Im5vQ29sb3IiCiAgICAjIGNoZWNrIGNvbG9ycyBhcHBsaWNhYmxlIGh0dHBzOi8vbWlzYy5mbG9naXNvZnQuY29tL2Jhc2gvdGlwX2NvbG9yc19hbmRfZm9ybWF0dGluZwogICAgX19FUlJPUl9DT0xPUj0nJwogICAgX19JTkZPX0NPTE9SPScnCiAgICBfX1NVQ0NFU1NfQ09MT1I9JycKICAgIF9fV0FSTklOR19DT0xPUj0nJwogICAgX19TS0lQUEVEX0NPTE9SPScnCiAgICBfX0RFQlVHX0NPTE9SPScnCiAgICBfX0hFTFBfQ09MT1I9JycKICAgIF9fVEVTVF9DT0xPUj0nJwogICAgX19URVNUX0VSUk9SX0NPTE9SPScnCiAgICBfX0hFTFBfVElUTEVfQ09MT1I9JycKICAgIF9fSEVMUF9PUFRJT05fQ09MT1I9JycKICAgICMgSW50ZXJuYWw6IHJlc2V0IGNvbG9yCiAgICBfX1JFU0VUX0NPTE9SPScnCiAgICBfX0hFTFBfRVhBTVBMRT0nJwogICAgX19IRUxQX1RJVExFPScnCiAgICBfX0hFTFBfTk9STUFMPScnCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gY2hlY2sgaWYgdHR5IChpbnRlcmFjdGl2ZSBtb2RlKSBpcyBhY3RpdmUKIyBAbm9hcmdzCiMgQGV4aXRjb2RlIDEgaWYgdHR5IG5vdCBhY3RpdmUKIyBAZW52IE5PTl9JTlRFUkFDVElWRSBpZiAxIGNvbnNpZGVyIGFzIG5vdCBpbnRlcmFjdGl2ZSBldmVuIGlmIGVudmlyb25tZW50IGlzIGludGVyYWN0aXZlCiMgQGVudiBJTlRFUkFDVElWRSBpZiAxIGNvbnNpZGVyIGFzIGludGVyYWN0aXZlIGV2ZW4gaWYgZW52aXJvbm1lbnQgaXMgbm90IGludGVyYWN0aXZlCiMgQHN0ZGVyciBkaWFnbm9zdGljIGluZm9ybWF0aW9uICsgaGVscCBpZiBzZWNvbmQgYXJndW1lbnQgaXMgcHJvdmlkZWQKQXNzZXJ0Ojp0dHkoKSB7CiAgaWYgW1sgIiR7Tk9OX0lOVEVSQUNUSVZFOi0wfSIgPSAiMSIgXV07IHRoZW4KICAgIHJldHVybiAxCiAgZmkKICBpZiBbWyAiJHtJTlRFUkFDVElWRTotMH0iID0gIjEiIF1dOyB0aGVuCiAgICByZXR1cm4gMAogIGZpCiAgW1sgLXQgMSB8fCAtdCAyIF1dCn0KCiMgRlVOQ1RJT05TCgpmYWNhZGVfbWFpbl9lbWJlZEZyYW1ld29ya0Z1bmN0aW9uYmluRmlsZXRwbCgpIHsKIyBSRVFVSVJFUwpMaW51eDo6cmVxdWlyZUV4ZWN1dGVkQXNVc2VyCkVudjo6cmVxdWlyZUxvYWQKTG9nOjpyZXF1aXJlTG9hZApMaW51eDo6cmVxdWlyZVJlYWxwYXRoQ29tbWFuZApVSTo6cmVxdWlyZVRoZW1lCkNvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyCgojIEByZXF1aXJlIENvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyCgojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIxNTQsU0MyMDE2CmZ1bmN0aW9uVG9DYWxsPSdEYjo6cXVlcnlPbmVEYXRhYmFzZScKIiR7ZnVuY3Rpb25Ub0NhbGx9IiAiJEAiCgp9CgpmYWNhZGVfbWFpbl9lbWJlZEZyYW1ld29ya0Z1bmN0aW9uYmluRmlsZXRwbCAiJEAiCg==" +declare -gx embed_function_DbQueryOneDatabase="${PERSISTENT_TMPDIR:-/tmp}/bin/db083cb53bb15c706d27273bb2620268/dbQueryOneDatabase" +declare -gx encoded_binary_file_DbQueryOneDatabase="IyEvdXNyL2Jpbi9lbnYgYmFzaAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgR0VORVJBVEVEIEZBQ0FERSBGUk9NIGh0dHBzOi8vZ2l0aHViLmNvbS9mY2hhc3RhbmV0L2Jhc2gtdG9vbHMvdHJlZS9tYXN0ZXIvLi4vYmFzaC1kZXYtZW52L3ZlbmRvci9iYXNoLXRvb2xzLWZyYW1ld29yay9zcmMvQ29tcGlsZXIvRW1iZWQvZW1iZWRGcmFtZXdvcmtGdW5jdGlvbi5iaW5GaWxlLnRwbAojIERPIE5PVCBFRElUIElUCiMgQGdlbmVyYXRlZAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjI4OCxTQzIwMzQKIyBCSU5fRklMRT0ke0JJTl9GSUxFfQojIEZBQ0FERQoKIyBlbnN1cmUgdGhhdCBubyB1c2VyIGFsaWFzZXMgY291bGQgaW50ZXJmZXJlIHdpdGgKIyBjb21tYW5kcyB1c2VkIGluIHRoaXMgc2NyaXB0CnVuYWxpYXMgLWEgfHwgdHJ1ZQpzaG9wdCAtdSBleHBhbmRfYWxpYXNlcwoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CigoZmFpbHVyZXMgPSAwKSkgfHwgdHJ1ZQoKIyBCYXNoIHdpbGwgcmVtZW1iZXIgJiByZXR1cm4gdGhlIGhpZ2hlc3QgZXhpdCBjb2RlIGluIGEgY2hhaW4gb2YgcGlwZXMuCiMgVGhpcyB3YXkgeW91IGNhbiBjYXRjaCB0aGUgZXJyb3IgaW5zaWRlIHBpcGVzLCBlLmcuIG15c3FsZHVtcCB8IGd6aXAKc2V0IC1vIHBpcGVmYWlsCnNldCAtbyBlcnJleGl0CgojIENvbW1hbmQgU3Vic3RpdHV0aW9uIGNhbiBpbmhlcml0IGVycmV4aXQgb3B0aW9uIHNpbmNlIGJhc2ggdjQuNApzaG9wdCAtcyBpbmhlcml0X2VycmV4aXQgfHwgdHJ1ZQoKIyBhIGxvZyBpcyBnZW5lcmF0ZWQgd2hlbiBhIGNvbW1hbmQgZmFpbHMKc2V0IC1vIGVycnRyYWNlCgojIHVzZSBudWxsZ2xvYiBzbyB0aGF0IChmaWxlKi5waHApIHdpbGwgcmV0dXJuIGFuIGVtcHR5IGFycmF5IGlmIG5vIGZpbGUgbWF0Y2hlcyB0aGUgd2lsZGNhcmQKc2hvcHQgLXMgbnVsbGdsb2IKCiMgZW5zdXJlIHJlZ2V4cCBhcmUgaW50ZXJwcmV0ZWQgd2l0aG91dCBhY2NlbnR1YXRlZCBjaGFyYWN0ZXJzCmV4cG9ydCBMQ19BTEw9UE9TSVgKCmV4cG9ydCBURVJNPXh0ZXJtLTI1NmNvbG9yCgojIGF2b2lkIGludGVyYWN0aXZlIGluc3RhbGwKZXhwb3J0IERFQklBTl9GUk9OVEVORD1ub25pbnRlcmFjdGl2ZQpleHBvcnQgREVCQ09ORl9OT05JTlRFUkFDVElWRV9TRUVOPXRydWUKCiMgc3RvcmUgY29tbWFuZCBhcmd1bWVudHMgZm9yIGxhdGVyIHVzYWdlCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIEJBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIE9SSUdJTkFMX0JBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCgojIEBzZWUgaHR0cHM6Ly91bml4LnN0YWNrZXhjaGFuZ2UuY29tL2EvMzg2ODU2CiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwppbnRlcnJ1cHRNYW5hZ2VtZW50KCkgewogICMgcmVzdG9yZSBTSUdJTlQgaGFuZGxlcgogIHRyYXAgLSBJTlQKICAjIGVuc3VyZSB0aGF0IEN0cmwtQyBpcyB0cmFwcGVkIGJ5IHRoaXMgc2NyaXB0IGFuZCBub3QgYnkgc3ViIHByb2Nlc3MKICAjIHJlcG9ydCB0byB0aGUgcGFyZW50IHRoYXQgd2UgaGF2ZSBpbmRlZWQgYmVlbiBpbnRlcnJ1cHRlZAogIGtpbGwgLXMgSU5UICIkJCIKfQp0cmFwIGludGVycnVwdE1hbmFnZW1lbnQgSU5UClNDUklQVF9OQU1FPSR7MCMjKi99ClJFQUxfU0NSSVBUX0ZJTEU9IiQocmVhZGxpbmsgLWUgIiQocmVhbHBhdGggIiR7QkFTSF9TT1VSQ0VbMF19IikiKSIKaWYgW1sgLW4gIiR7RU1CRURfQ1VSUkVOVF9ESVJ9IiBdXTsgdGhlbgogIENVUlJFTlRfRElSPSIke0VNQkVEX0NVUlJFTlRfRElSfSIKZWxzZQogIENVUlJFTlRfRElSPSIkKGNkICIkKHJlYWRsaW5rIC1lICIke1JFQUxfU0NSSVBUX0ZJTEUlLyp9IikiICYmIHB3ZCAtUCkiCmZpCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBUZW1wIGRpciBtYW5hZ2VtZW50CiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKS0VFUF9URU1QX0ZJTEVTPSIke0tFRVBfVEVNUF9GSUxFUzotMH0iCmV4cG9ydCBLRUVQX1RFTVBfRklMRVMKCiMgUEVSU0lTVEVOVF9UTVBESVIgaXMgbm90IGRlbGV0ZWQgYnkgdHJhcHMKUEVSU0lTVEVOVF9UTVBESVI9IiR7VE1QRElSOi0vdG1wfS9iYXNoLWZyYW1ld29yayIKZXhwb3J0IFBFUlNJU1RFTlRfVE1QRElSCm1rZGlyIC1wICIke1BFUlNJU1RFTlRfVE1QRElSfSIKCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApUTVBESVI9IiQobWt0ZW1wIC1kIC1wICIke1BFUlNJU1RFTlRfVE1QRElSOi0vdG1wfSIgLXQgYmFzaC1mcmFtZXdvcmstJCQtWFhYWFhYKSIKZXhwb3J0IFRNUERJUgoKIyB0ZW1wIGRpciBjbGVhbmluZwojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIzMTcKY2xlYW5PbkV4aXQoKSB7CiAgaWYgW1sgIiR7S0VFUF9URU1QX0ZJTEVTOi0wfSIgPSAiMSIgXV07IHRoZW4KICAgIExvZzo6ZGlzcGxheUluZm8gIktFRVBfVEVNUF9GSUxFUz0xIHRlbXAgZmlsZXMga2VwdCBoZXJlICcke1RNUERJUn0nIgogIGVsaWYgW1sgLW4gIiR7VE1QRElSK3h4eH0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlEZWJ1ZyAiS0VFUF9URU1QX0ZJTEVTPTAgcmVtb3ZpbmcgdGVtcCBmaWxlcyAnJHtUTVBESVJ9JyIKICAgIHJtIC1SZiAiJHtUTVBESVI6LS90bXAvZmFrZX0iID4vZGV2L251bGwgMj4mMQogIGZpCn0KdHJhcCBjbGVhbk9uRXhpdCBFWElUIEhVUCBRVUlUIEFCUlQgVEVSTQoKIyBWQVJfTUFJTl9GVU5DVElPTl9WQVJfTkFNRT1kYlF1ZXJ5QWxsRGF0YWJhc2VzRmFjYWRlCgojIEBkZXNjcmlwdGlvbiB1c2VkIHRvIGV4ZWN1dGUgZ2l2ZW4gcXVlcnkgd2hlbiB1c2luZwojIGRiU2NyaXB0QWxsRGF0YWJhc2VzCiMgQGFyZyAkMSBkc246U3RyaW5nCiMgQGFyZyAkMiBkYjpTdHJpbmcKIyBAZW52IHF1ZXJ5IFN0cmluZwojIEBlbnYgb3B0aW9uU2VwYXJhdG9yIFN0cmluZwojIEByZXF1aXJlIExpbnV4OjpyZXF1aXJlRXhlY3V0ZWRBc1VzZXIKRGI6OnF1ZXJ5T25lRGF0YWJhc2UoKSB7CiAgIyBxdWVyeSBhbmQgb3B0aW9uU2VwYXJhdG9yIGFyZSBwYXNzZWQgdmlhIGV4cG9ydAogIGxvY2FsIGRzbj0iJDEiCiAgbG9jYWwgZGI9IiQyIgoKICBsb2NhbCAtQSBkYkluc3RhbmNlCiAgRGF0YWJhc2U6Om5ld0luc3RhbmNlIGRiSW5zdGFuY2UgIiR7ZHNufSIKICBEYXRhYmFzZTo6c2V0UXVlcnlPcHRpb25zIGRiSW5zdGFuY2UgIiR7ZGJJbnN0YW5jZVtRVUVSWV9PUFRJT05TXX0gLS1jb25uZWN0LXRpbWVvdXQ9NSIKCiAgIyBpZGVudGlmeSBjb2x1bW5zIGhlYWRlcgogIGVjaG8gLW4gIkBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAIgogIERhdGFiYXNlOjpza2lwQ29sdW1uTmFtZXMgZGJJbnN0YW5jZSAwCgogICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE1NAogIGlmICEgRGF0YWJhc2U6OnF1ZXJ5IGRiSW5zdGFuY2UgIiR7cXVlcnl9IiAiJHtkYn0iIHwgc2VkICJzL1x0LyR7b3B0aW9uU2VwYXJhdG9yfS9nIjsgdGhlbgogICAgTG9nOjpmYXRhbCAiZGF0YWJhc2UgJHtkYn0gZXJyb3IiIDE+JjIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBMb2cgbmFtZXNwYWNlIHByb3ZpZGVzIDIga2luZCBvZiBmdW5jdGlvbnMKIyAtIExvZzo6ZGlzcGxheSogYWxsb3dzIHRvIGRpc3BsYXkgZ2l2ZW4gbWVzc2FnZSB3aXRoCiMgICBnaXZlbiBkaXNwbGF5IGxldmVsCiMgLSBMb2c6OmxvZyogYWxsb3dzIHRvIGxvZyBnaXZlbiBtZXNzYWdlIHdpdGgKIyAgIGdpdmVuIGxvZyBsZXZlbAojIExvZzo6ZGlzcGxheSogZnVuY3Rpb25zIGF1dG9tYXRpY2FsbHkgbG9nIHRoZSBtZXNzYWdlIHRvbwojIEBzZWUgRW52OjpyZXF1aXJlTG9hZCB0byBsb2FkIHRoZSBkaXNwbGF5IGFuZCBsb2cgbGV2ZWwgZnJvbSAuZW52IGZpbGUKCiMgQGRlc2NyaXB0aW9uIGxvZyBsZXZlbCBvZmYKZXhwb3J0IF9fTEVWRUxfT0ZGPTAKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIGVycm9yCmV4cG9ydCBfX0xFVkVMX0VSUk9SPTEKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIHdhcm5pbmcKZXhwb3J0IF9fTEVWRUxfV0FSTklORz0yCiMgQGRlc2NyaXB0aW9uIGxvZyBsZXZlbCBpbmZvCmV4cG9ydCBfX0xFVkVMX0lORk89MwojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgc3VjY2VzcwpleHBvcnQgX19MRVZFTF9TVUNDRVNTPTMKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIGRlYnVnCmV4cG9ydCBfX0xFVkVMX0RFQlVHPTQKCiMgQGRlc2NyaXB0aW9uIHZlcmJvc2UgbGV2ZWwgb2ZmCmV4cG9ydCBfX1ZFUkJPU0VfTEVWRUxfT0ZGPTAKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBpbmZvCmV4cG9ydCBfX1ZFUkJPU0VfTEVWRUxfSU5GTz0xCiMgQGRlc2NyaXB0aW9uIHZlcmJvc2UgbGV2ZWwgaW5mbwpleHBvcnQgX19WRVJCT1NFX0xFVkVMX0RFQlVHPTIKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBpbmZvCmV4cG9ydCBfX1ZFUkJPU0VfTEVWRUxfVFJBQ0U9MwoKIyBAZGVzY3JpcHRpb24gRGlzcGxheSBtZXNzYWdlIHVzaW5nIGRlYnVnIGNvbG9yIChncmV5KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlEZWJ1ZygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUwgPj0gX19MRVZFTF9ERUJVRykpOyB0aGVuCiAgICBlY2hvIC1lICIke19fREVCVUdfQ09MT1J9REVCVUcgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nRGVidWcgIiQxIgp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgaW5mbyBjb2xvciAoYmcgbGlnaHQgYmx1ZS9mZyB3aGl0ZSkKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpkaXNwbGF5SW5mbygpIHsKICBsb2NhbCB0eXBlPSIkezI6LUlORk99IgogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX0lORk9fQ09MT1J9JHt0eXBlfSAgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nSW5mbyAiJDEiICIke3R5cGV9Igp9CgojIEBkZXNjcmlwdGlvbiBlbnN1cmUgQ09NTUFORF9CSU5fRElSIGVudiB2YXIgaXMgc2V0CiMgYW5kIFBBVEggY29ycmVjdGx5IHByZXBhcmVkCiMgQG5vYXJncwojIEBzZXQgQ09NTUFORF9CSU5fRElSIHN0cmluZyB0aGUgZGlyZWN0b3J5IHdoZXJlIHRvIGZpbmQgdGhpcyBjb21tYW5kCiMgQHNldCBQQVRIIHN0cmluZyBhZGQgZGlyZWN0b3J5IHdoZXJlIHRvIGZpbmQgdGhpcyBjb21tYW5kIGJpbmFyeQpDb21waWxlcjo6RmFjYWRlOjpyZXF1aXJlQ29tbWFuZEJpbkRpcigpIHsKICBDT01NQU5EX0JJTl9ESVI9IiR7Q1VSUkVOVF9ESVJ9IgogIEVudjo6cGF0aFByZXBlbmQgIiR7Q09NTUFORF9CSU5fRElSfSIKfQoKIyBAZGVzY3JpcHRpb24gY3JlYXRlIGEgbmV3IGRiIGluc3RhbmNlCiMgUmV0dXJucyBpbW1lZGlhdGVseSBpZiB0aGUgaW5zdGFuY2UgaXMgYWxyZWFkeSBpbml0aWFsaXplZAojCiMgQGFyZyAkMSBpbnN0YW5jZU5ld0luc3RhbmNlOiZNYXA8U3RyaW5nLFN0cmluZz4gKHBhc3NlZCBieSByZWZlcmVuY2UpIGRhdGFiYXNlIGluc3RhbmNlIHRvIHVzZQojIEBhcmcgJDIgZHNuOlN0cmluZyBkc24gcHJvZmlsZSAtIGxvYWQgdGhlIGRzbi5lbnYgcHJvZmlsZSBkZWR1Y2VkIHVzaW5nIHJ1bGVzIGRlZmluZWQgaW4gQ29uZjo6Z2V0QWJzb2x1dGVGaWxlCiMKIyBAZXhhbXBsZQojICAgZGVjbGFyZSAtQWd4IGRiSW5zdGFuY2UKIyAgIERhdGFiYXNlOjpuZXdJbnN0YW5jZSBkYkluc3RhbmNlICJkZWZhdWx0LmxvY2FsIgojCiMgQGV4aXRjb2RlIDEgaWYgZG5zIGZpbGUgbm90IGFibGUgdG8gbG9hZGVkCkRhdGFiYXNlOjpuZXdJbnN0YW5jZSgpIHsKICBsb2NhbCAtbiBpbnN0YW5jZU5ld0luc3RhbmNlPSQxCiAgbG9jYWwgZHNuPSIkMiIKICBsb2NhbCBEU05fRklMRQoKICBpZiBbWyAtdiBpbnN0YW5jZU5ld0luc3RhbmNlWydJTklUSUFMSVpFRCddICYmICIke2luc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ106LTB9IiA9PSAiMSIgXV07IHRoZW4KICAgIHJldHVybgogIGZpCgogICMgZmluYWwgYXV0aCBmaWxlIGdlbmVyYXRlZCBmcm9tIGRucyBmaWxlCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnQVVUSF9GSUxFJ109IiIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydEU05fRklMRSddPSIiCgogICMgY2hlY2sgZHNuIGZpbGUKICBEU05fRklMRT0iJChDb25mOjpnZXRBYnNvbHV0ZUZpbGUgImRzbiIgIiR7ZHNufSIgImVudiIpIiB8fCByZXR1cm4gMQogIERhdGFiYXNlOjpjaGVja0RzbkZpbGUgIiR7RFNOX0ZJTEV9IiB8fCByZXR1cm4gMQogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0RTTl9GSUxFJ109IiR7RFNOX0ZJTEV9IgoKICAjIHNoZWxsY2hlY2sgc291cmNlPS9zcmMvRGF0YWJhc2UvdGVzdHNEYXRhL2Rzbl92YWxpZC5lbnYKICBzb3VyY2UgIiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnRFNOX0ZJTEUnXX0iCgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1VTRVInXT0iJHtVU0VSfSIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydQQVNTV09SRCddPSIke1BBU1NXT1JEfSIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydIT1NUTkFNRSddPSIke0hPU1ROQU1FfSIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydQT1JUJ109IiR7UE9SVH0iCgogICMgZ2VuZXJhdGUgYXV0aEZpbGUgZm9yIGVhc3kgYXV0aGVudGljYXRpb24KICBpbnN0YW5jZU5ld0luc3RhbmNlWydBVVRIX0ZJTEUnXT0kKG1rdGVtcCAtcCAiJHtUTVBESVI6LS90bXB9IiAtdCAibXlzcWwuWFhYWFhYWFhYWFhYIikKICAoCiAgICBlY2hvICJbY2xpZW50XSIKICAgIGVjaG8gInVzZXIgPSAke1VTRVJ9IgogICAgZWNobyAicGFzc3dvcmQgPSAke1BBU1NXT1JEfSIKICAgIGVjaG8gImhvc3QgPSAke0hPU1ROQU1FfSIKICAgIGVjaG8gInBvcnQgPSAke1BPUlR9IgogICkgPiIke2luc3RhbmNlTmV3SW5zdGFuY2VbJ0FVVEhfRklMRSddfSIKCiAgIyBzb21lIG9mIHRob3NlIHZhbHVlcyBjYW4gYmUgb3ZlcnJpZGRlbiB1c2luZyB0aGUgZHNuIGZpbGUKICAjIFNLSVBfQ09MVU1OX05BTUVTIGVuYWJsZWQgYnkgZGVmYXVsdAogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1NLSVBfQ09MVU1OX05BTUVTJ109IiR7U0tJUF9DT0xVTU5fTkFNRVM6LTF9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1NTTF9PUFRJT05TJ109IiR7TVlTUUxfU1NMX09QVElPTlM6LS0tc3NsLW1vZGU9RElTQUJMRUR9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1FVRVJZX09QVElPTlMnXT0iJHtNWVNRTF9RVUVSWV9PUFRJT05TOi0tLWJhdGNoIC0tcmF3IC0tZGVmYXVsdC1jaGFyYWN0ZXItc2V0PXV0Zjh9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0RVTVBfT1BUSU9OUyddPSIke01ZU1FMX0RVTVBfT1BUSU9OUzotLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOCAtLWNvbXByZXNzIC0taGV4LWJsb2IgLS1yb3V0aW5lcyAtLXRyaWdnZXJzIC0tc2luZ2xlLXRyYW5zYWN0aW9uIC0tc2V0LWd0aWQtcHVyZ2VkPU9GRiAtLWNvbHVtbi1zdGF0aXN0aWNzPTAgJHtpbnN0YW5jZU5ld0luc3RhbmNlWydTU0xfT1BUSU9OUyddfX0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnREJfSU1QT1JUX09QVElPTlMnXT0iJHtEQl9JTVBPUlRfT1BUSU9OUzotLS1jb25uZWN0LXRpbWVvdXQ9NSAtLWJhdGNoIC0tcmF3IC0tZGVmYXVsdC1jaGFyYWN0ZXItc2V0PXV0Zjh9IgoKICBpbnN0YW5jZU5ld0luc3RhbmNlWydJTklUSUFMSVpFRCddPTEKfQoKIyBAZGVzY3JpcHRpb24gbXlzcWwgcXVlcnkgb24gYSBnaXZlbiBkYgojIEB3YXJuaW5nIGNvdWxkIHVzZSBRVUVSWV9PUFRJT05TIHZhcmlhYmxlIGZyb20gZHNuIGlmIGRlZmluZWQKIyBAZXhhbXBsZQojICAgY2F0IGZpbGUuc3FsIHwgRGF0YWJhc2U6OnF1ZXJ5IC4uLgojIEBhcmcgJDEgaW5zdGFuY2VRdWVyeTomTWFwPFN0cmluZyxTdHJpbmc+IChwYXNzZWQgYnkgcmVmZXJlbmNlKSBkYXRhYmFzZSBpbnN0YW5jZSB0byB1c2UKIyBAYXJnICQyIHNxbFF1ZXJ5OlN0cmluZyAob3B0aW9uYWwpIHNxbCBxdWVyeSBvciBzcWwgZmlsZSB0byBleGVjdXRlLiBpZiBub3QgcHJvdmlkZWQgb3IgZW1wdHksIHRoZSBjb21tYW5kIGNhbiBiZSBwaXBlZAojIEBhcmcgJDMgZGJOYW1lOlN0cmluZyAob3B0aW9uYWwpIHRoZSBkYiBuYW1lCiMKIyBAZXhpdGNvZGUgbXlzcWwgY29tbWFuZCBzdGF0dXMgY29kZQpEYXRhYmFzZTo6cXVlcnkoKSB7CiAgbG9jYWwgLW4gaW5zdGFuY2VRdWVyeT0kMQogIGxvY2FsIC1hIG15c3FsQ29tbWFuZD0oKQogIGxvY2FsIC1hIHF1ZXJ5T3B0aW9ucwoKICBteXNxbENvbW1hbmQrPShteXNxbCkKICBteXNxbENvbW1hbmQrPSgiLS1kZWZhdWx0cy1leHRyYS1maWxlPSR7aW5zdGFuY2VRdWVyeVsnQVVUSF9GSUxFJ119IikKICBJRlM9JyAnIHJlYWQgLXIgLWEgcXVlcnlPcHRpb25zIDw8PCIke2luc3RhbmNlUXVlcnlbJ1FVRVJZX09QVElPTlMnXX0iCiAgbXlzcWxDb21tYW5kKz0oIiR7cXVlcnlPcHRpb25zW0BdfSIpCiAgaWYgW1sgIiR7aW5zdGFuY2VRdWVyeVsnU0tJUF9DT0xVTU5fTkFNRVMnXX0iID0gIjEiIF1dOyB0aGVuCiAgICBteXNxbENvbW1hbmQrPSgiLXMiICItLXNraXAtY29sdW1uLW5hbWVzIikKICBmaQogICMgYWRkIG9wdGlvbmFsIGRiIG5hbWUKICBpZiBbWyAtbiAiJHszK3h9IiBdXTsgdGhlbgogICAgbXlzcWxDb21tYW5kKz0oIiQzIikKICBmaQogICMgYWRkIG9wdGlvbmFsIHNxbCBxdWVyeQogIGlmIFtbIC1uICIkezIreH0iICYmIC1uICIkMiIgJiYgISAtZiAiJDIiIF1dOyB0aGVuCiAgICBteXNxbENvbW1hbmQrPSgiLWUiKQogICAgbXlzcWxDb21tYW5kKz0oIiQyIikKICBmaQogIExvZzo6ZGlzcGxheURlYnVnICIkKHByaW50ZiAiZXhlY3V0ZSBjb21tYW5kOiAnJXMnIiAiJHtteXNxbENvbW1hbmRbKl19IikiCgogIGlmIFtbIC1mICIkMiIgXV07IHRoZW4KICAgICIke215c3FsQ29tbWFuZFtAXX0iIDwiJDIiCiAgZWxzZQogICAgIiR7bXlzcWxDb21tYW5kW0BdfSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBzZXQgdGhlIGdlbmVyYWwgb3B0aW9ucyB0byB1c2Ugb24gbXlzcWwgY29tbWFuZCB0byBxdWVyeSB0aGUgZGF0YWJhc2UKIyBEaWZmZXJzIHRoYW4gc2V0T3B0aW9ucyBpbiB0aGUgd2F5IHRoYXQgdGhlc2Ugb3B0aW9ucyBjb3VsZCBjaGFuZ2UgZWFjaCB0aW1lCiMKIyBAYXJnICQxIGluc3RhbmNlU2V0UXVlcnlPcHRpb25zOiZNYXA8U3RyaW5nLFN0cmluZz4gKHBhc3NlZCBieSByZWZlcmVuY2UpIGRhdGFiYXNlIGluc3RhbmNlIHRvIHVzZQojIEBhcmcgJDIgb3B0aW9uc0xpc3Q6U3RyaW5nIHF1ZXJ5IG9wdGlvbnMgbGlzdApEYXRhYmFzZTo6c2V0UXVlcnlPcHRpb25zKCkgewogIGxvY2FsIC1uIGluc3RhbmNlU2V0UXVlcnlPcHRpb25zPSQxCiAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnNbJ1FVRVJZX09QVElPTlMnXT0iJDIiCn0KCiMgQGRlc2NyaXB0aW9uIGJ5IGRlZmF1bHQgd2Ugc2tpcCB0aGUgY29sdW1uIG5hbWVzCiMgYnV0IHNvbWV0aW1lcyB3ZSBuZWVkIGNvbHVtbiBuYW1lcyB0byBkaXNwbGF5IHNvbWUgcmVzdWx0cwojIGRpc2FibGUgdGhpcyBvcHRpb24gdGVtcG9yYXJpbHkgYW5kIHRoZW4gcmVzdG9yZSBpdCB0byB0cnVlCiMKIyBAYXJnICQxIGluc3RhbmNlU2V0UXVlcnlPcHRpb25zOiZNYXA8U3RyaW5nLFN0cmluZz4gKHBhc3NlZCBieSByZWZlcmVuY2UpIGRhdGFiYXNlIGluc3RhbmNlIHRvIHVzZQojIEBhcmcgJDIgc2tpcENvbHVtbk5hbWVzOkJvb2xlYW4gMCB0byBkaXNhYmxlLCAxIHRvIGVuYWJsZSAoaGlkZSBjb2x1bW4gbmFtZXMpCkRhdGFiYXNlOjpza2lwQ29sdW1uTmFtZXMoKSB7CiAgbG9jYWwgLW4gaW5zdGFuY2VTa2lwQ29sdW1uTmFtZXM9JDEKICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICBpbnN0YW5jZVNraXBDb2x1bW5OYW1lc1snU0tJUF9DT0xVTU5fTkFNRVMnXT0iJDIiCn0KCiMgQGRlc2NyaXB0aW9uIHByZXBlbmQgZGlyZWN0b3JpZXMgdG8gdGhlIFBBVEggZW52aXJvbm1lbnQgdmFyaWFibGUKIyBAYXJnICRAIGFyZ3M6U3RyaW5nW10gbGlzdCBvZiBkaXJlY3RvcmllcyB0byBwcmVwZW5kCiMgQHNldCBQQVRIIHVwZGF0ZSBQQVRIIHdpdGggdGhlIGRpcmVjdG9yaWVzIHByZXBlbmRlZApFbnY6OnBhdGhQcmVwZW5kKCkgewogIGxvY2FsIGFyZwogIGZvciBhcmcgaW4gIiRAIjsgZG8KICAgIGlmIFtbIC1kICIke2FyZ30iICYmICI6JHtQQVRIfToiICE9ICoiOiR7YXJnfToiKiBdXTsgdGhlbgogICAgICBQQVRIPSIkKHJlYWxwYXRoICIke2FyZ30iKToke1BBVEh9IgogICAgZmkKICBkb25lCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBlcnJvciBjb2xvciAocmVkKSBhbmQgZXhpdCBpbW1lZGlhdGVseSB3aXRoIGVycm9yIHN0YXR1cyAxCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6ZmF0YWwoKSB7CiAgZWNobyAtZSAiJHtfX0VSUk9SX0NPTE9SfUZBVEFMICAgLSAkezF9JHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgTG9nOjpsb2dGYXRhbCAiJDEiCiAgZXhpdCAxCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dEZWJ1ZygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0RFQlVHKSk7IHRoZW4KICAgIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1ERUJVR30iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nSW5mbygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LUlORk99IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZW5zdXJlIHJ1bm5pbmcgdXNlciBpcyBub3Qgcm9vdAojIEBleGl0Y29kZSAxIGlmIGN1cnJlbnQgdXNlciBpcyByb290CiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKTGludXg6OnJlcXVpcmVFeGVjdXRlZEFzVXNlcigpIHsKICBpZiBbWyAiJChpZCAtdSkiID0gIjAiIF1dOyB0aGVuCiAgICBMb2c6OmZhdGFsICJ0aGlzIHNjcmlwdCBzaG91bGQgYmUgZXhlY3V0ZWQgYXMgbm9ybWFsIHVzZXIiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZ2V0IGFic29sdXRlIGNvbmYgZmlsZSBmcm9tIHNwZWNpZmllZCBjb25mIGZvbGRlciBkZWR1Y2VkIHVzaW5nIHRoZXNlIHJ1bGVzCiMgICAqIGZyb20gYWJzb2x1dGUgZmlsZSAoaWdub3JlcyA8Y29uZkZvbGRlcj4gYW5kIDxleHRlbnNpb24+KQojICAgKiByZWxhdGl2ZSB0byB3aGVyZSBzY3JpcHQgaXMgZXhlY3V0ZWQgKGlnbm9yZXMgPGNvbmZGb2xkZXI+IGFuZCA8ZXh0ZW5zaW9uPikKIyAgICogZnJvbSBob21lLy5iYXNoLXRvb2xzLzxjb25mRm9sZGVyPgojICAgKiBmcm9tIGZyYW1ld29yayBjb25mLzxjb25mRm9sZGVyPgojCiMgQGFyZyAkMSBjb25mRm9sZGVyOlN0cmluZyB0aGUgZGlyZWN0b3J5IG5hbWUgKG5vdCB0aGUgcGF0aCkgdG8gbGlzdAojIEBhcmcgJDIgY29uZjpTdHJpbmcgZmlsZSB0byB1c2Ugd2l0aG91dCBleHRlbnNpb24KIyBAYXJnICQzIGV4dGVuc2lvbjpTdHJpbmcgdGhlIGV4dGVuc2lvbiAoLnNoIGJ5IGRlZmF1bHQpCiMKIyBAc3Rkb3V0IGFic29sdXRlIGNvbmYgZmlsZW5hbWUKIyBAZXhpdGNvZGUgMSBpZiBmaWxlIGlzIG5vdCBmb3VuZCBpbiBhbnkgbG9jYXRpb24KQ29uZjo6Z2V0QWJzb2x1dGVGaWxlKCkgewogIGxvY2FsIGNvbmZGb2xkZXI9IiQxIgogIGxvY2FsIGNvbmY9IiQyIgogIGxvY2FsIGV4dGVuc2lvbj0iJHszLS5zaH0iCiAgaWYgW1sgLW4gIiR7ZXh0ZW5zaW9ufSIgJiYgIiR7ZXh0ZW5zaW9uOjA6MX0iICE9ICIuIiBdXTsgdGhlbgogICAgZXh0ZW5zaW9uPSIuJHtleHRlbnNpb259IgogIGZpCgogIHRlc3RBYnMoKSB7CiAgICBsb2NhbCByZXN1bHQKICAgIHJlc3VsdD0iJChyZWFscGF0aCAtZSAiJDEiIDI+L2Rldi9udWxsKSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE4MQogICAgaWYgW1sgIiQ/IiA9ICIwIiAmJiAtZiAiJHtyZXN1bHR9IiBdXTsgdGhlbgogICAgICBlY2hvICIke3Jlc3VsdH0iCiAgICAgIHJldHVybiAwCiAgICBmaQogICAgcmV0dXJuIDEKICB9CgogICMgY29uZiBpcyBhYnNvbHV0ZSBmaWxlIChpbmNsdWRpbmcgZXh0ZW5zaW9uKQogIHRlc3RBYnMgIiR7Y29uZkZvbGRlcn0ke2V4dGVuc2lvbn0iICYmIHJldHVybiAwCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUKICB0ZXN0QWJzICIke2NvbmZGb2xkZXJ9IiAmJiByZXR1cm4gMAogICMgY29uZiBpcyBhYnNvbHV0ZSBmaWxlIChpbmNsdWRpbmcgZXh0ZW5zaW9uKQogIHRlc3RBYnMgIiR7Y29uZn0ke2V4dGVuc2lvbn0iICYmIHJldHVybiAwCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUKICB0ZXN0QWJzICIke2NvbmZ9IiAmJiByZXR1cm4gMAoKICAjIHJlbGF0aXZlIHRvIHdoZXJlIHNjcmlwdCBpcyBleGVjdXRlZCAoaW5jbHVkaW5nIGV4dGVuc2lvbikKICBpZiBbWyAtbiAiJHtDVVJSRU5UX0RJUit4eHh9IiBdXTsgdGhlbgogICAgdGVzdEFicyAiJChGaWxlOjpjb25jYXRlbmF0ZVBhdGggIiR7Q1VSUkVOVF9ESVJ9IiAiJHtjb25mRm9sZGVyfSIpLyR7Y29uZn0ke2V4dGVuc2lvbn0iICYmIHJldHVybiAwCiAgZmkKICAjIGZyb20gaG9tZS8uYmFzaC10b29scy88Y29uZkZvbGRlcj4KICB0ZXN0QWJzICIkKEZpbGU6OmNvbmNhdGVuYXRlUGF0aCAiJHtIT01FfS8uYmFzaC10b29scyIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9JHtleHRlbnNpb259IiAmJiByZXR1cm4gMAoKICBpZiBbWyAtbiAiJHtGUkFNRVdPUktfUk9PVF9ESVIreHh4fSIgXV07IHRoZW4KICAgICMgZnJvbSBmcmFtZXdvcmsgY29uZi88Y29uZkZvbGRlcj4gKGluY2x1ZGluZyBleHRlbnNpb24pCiAgICB0ZXN0QWJzICIkKEZpbGU6OmNvbmNhdGVuYXRlUGF0aCAiJHtGUkFNRVdPUktfUk9PVF9ESVJ9L2NvbmYiICIke2NvbmZGb2xkZXJ9IikvJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKCiAgICAjIGZyb20gZnJhbWV3b3JrIGNvbmYvPGNvbmZGb2xkZXI+CiAgICB0ZXN0QWJzICIkKEZpbGU6OmNvbmNhdGVuYXRlUGF0aCAiJHtGUkFNRVdPUktfUk9PVF9ESVJ9L2NvbmYiICIke2NvbmZGb2xkZXJ9IikvJHtjb25mfSIgJiYgcmV0dXJuIDAKICBmaQoKICAjIGZpbGUgbm90IGZvdW5kCiAgTG9nOjpkaXNwbGF5RXJyb3IgImNvbmYgZmlsZSAnJHtjb25mfScgbm90IGZvdW5kIgoKICByZXR1cm4gMQp9CgojIEBkZXNjcmlwdGlvbiBjaGVjayBpZiBkc24gZmlsZSBoYXMgYWxsIHRoZSBtYW5kYXRvcnkgdmFyaWFibGVzIHNldAojIE1hbmRhdG9yeSB2YXJpYWJsZXMgYXJlOiBIT1NUTkFNRSwgVVNFUiwgUEFTU1dPUkQsIFBPUlQKIwojIEBhcmcgJDEgZHNuRmlsZU5hbWU6U3RyaW5nIGRzbiBhYnNvbHV0ZSBmaWxlbmFtZQojIEBzZXQgSE9TVE5BTUUgbG9hZGVkIGZyb20gZHNuIGZpbGUKIyBAc2V0IFBPUlQgbG9hZGVkIGZyb20gZHNuIGZpbGUKIyBAc2V0IFVTRVIgbG9hZGVkIGZyb20gZHNuIGZpbGUKIyBAc2V0IFBBU1NXT1JEIGxvYWRlZCBmcm9tIGRzbiBmaWxlCiMgQGV4aXRjb2RlIDAgb24gdmFsaWQgZmlsZQojIEBleGl0Y29kZSAxIGlmIG9uZSBvZiB0aGUgcHJvcGVydGllcyBvZiB0aGUgY29uZiBmaWxlIGlzIGludmFsaWQgb3IgaWYgZmlsZSBub3QgZm91bmQKIyBAc3RkZXJyIGxvZyBvdXRwdXQgaWYgZXJyb3IgZm91bmQgaW4gY29uZiBmaWxlCkRhdGFiYXNlOjpjaGVja0RzbkZpbGUoKSB7CiAgbG9jYWwgZHNuRmlsZU5hbWU9IiQxIgogIGlmIFtbICEgLWYgIiR7ZHNuRmlsZU5hbWV9IiBdXTsgdGhlbgogICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IG5vdCBmb3VuZCIKICAgIHJldHVybiAxCiAgZmkKCiAgKAogICAgdW5zZXQgSE9TVE5BTUUgUE9SVCBQQVNTV09SRCBVU0VSCiAgICAjIHNoZWxsY2hlY2sgc291cmNlPS9zcmMvRGF0YWJhc2UvdGVzdHNEYXRhL2Rzbl92YWxpZC5lbnYKICAgIHNvdXJjZSAiJHtkc25GaWxlTmFtZX0iCiAgICBpZiBbWyAteiAke0hPU1ROQU1FK3h9IF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJkc24gZmlsZSAke2RzbkZpbGVOYW1lfSA6IEhPU1ROQU1FIG5vdCBwcm92aWRlZCIKICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBpZiBbWyAteiAiJHtIT1NUTkFNRX0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheVdhcm5pbmcgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogSE9TVE5BTUUgdmFsdWUgbm90IHByb3ZpZGVkIgogICAgZmkKICAgIGlmIFtbICIke0hPU1ROQU1FfSIgPSAibG9jYWxob3N0IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlXYXJuaW5nICJkc24gZmlsZSAke2RzbkZpbGVOYW1lfSA6IGNoZWNrIHRoYXQgSE9TVE5BTUUgc2hvdWxkIG5vdCBiZSAxMjcuMC4wLjEgaW5zdGVhZCBvZiBsb2NhbGhvc3QiCiAgICBmaQogICAgaWYgW1sgLXogIiR7UE9SVCt4fSIgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogUE9SVCBub3QgcHJvdmlkZWQiCiAgICAgIHJldHVybiAxCiAgICBmaQogICAgaWYgISBbWyAke1BPUlR9ID1+IF5bMC05XSskIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJkc24gZmlsZSAke2RzbkZpbGVOYW1lfSA6IFBPUlQgaW52YWxpZCIKICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBpZiBbWyAteiAiJHtVU0VSK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBVU0VSIG5vdCBwcm92aWRlZCIKICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBpZiBbWyAteiAiJHtQQVNTV09SRCt4fSIgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogUEFTU1dPUkQgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICApCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dGYXRhbCgpIHsKICBMb2c6OmxvZ01lc3NhZ2UgIiR7MjotRkFUQUx9IiAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIEludGVybmFsOiBjb21tb24gbG9nIG1lc3NhZ2UKIyBAZXhhbXBsZSB0ZXh0CiMgICBbZGF0ZV18W2xldmVsTXNnXXxtZXNzYWdlCiMKIyBAZXhhbXBsZSB0ZXh0CiMgICAyMDIwLTAxLTE5IDE5OjIwOjIxfEVSUk9SICB8bG9nIGVycm9yCiMgICAyMDIwLTAxLTE5IDE5OjIwOjIxfFNLSVBQRUR8bG9nIHNraXBwZWQKIwojIEBhcmcgJDEgbGV2ZWxNc2c6U3RyaW5nIG1lc3NhZ2UncyBsZXZlbCBkZXNjcmlwdGlvbiAoZWc6IFNUQVRVUywgRVJST1IsIC4uLikKIyBAYXJnICQyIG1zZzpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgU3RyaW5nIGxvZyBmaWxlIHRvIHVzZSwgZG8gbm90aGluZyBpZiBlbXB0eQojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludCBsb2cgbGV2ZWwgbG9nIG9ubHkgaWYgPiBPRkYgb3IgZmF0YWwgbWVzc2FnZXMKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZAojIEByZXF1aXJlIEVudjo6cmVxdWlyZUxvYWQKIyBAcmVxdWlyZSBMb2c6OnJlcXVpcmVMb2FkCkxvZzo6bG9nTWVzc2FnZSgpIHsKICBsb2NhbCBsZXZlbE1zZz0iJDEiCiAgbG9jYWwgbXNnPSIkMiIKICBsb2NhbCBkYXRlCgogIGlmIFtbIC1uICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIgXV0gJiYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPiBfX0xFVkVMX09GRikpOyB0aGVuCiAgICBkYXRlPSIkKGRhdGUgJyslWS0lbS0lZCAlSDolTTolUycpIgogICAgdG91Y2ggIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IgogICAgcHJpbnRmICIlc3wlN3N8JXNcbiIgIiR7ZGF0ZX0iICIke2xldmVsTXNnfSIgIiR7bXNnfSIgPj4iJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gY29uY2F0ZW5hdGUgMiBwYXRocyBhbmQgZW5zdXJlIHRoZSBwYXRoIGlzIGNvcnJlY3QgdXNpbmcgcmVhbHBhdGggLW0KIyBAYXJnICQxIGJhc2VQYXRoOlN0cmluZwojIEBhcmcgJDIgc3ViUGF0aDpTdHJpbmcKIyBAcmVxdWlyZSBMaW51eDo6cmVxdWlyZVJlYWxwYXRoQ29tbWFuZApGaWxlOjpjb25jYXRlbmF0ZVBhdGgoKSB7CiAgbG9jYWwgYmFzZVBhdGg9IiQxIgogIGxvY2FsIHN1YlBhdGg9IiQyIgogIGxvY2FsIGZ1bGxQYXRoPSIke2Jhc2VQYXRoOiske2Jhc2VQYXRofS99JHtzdWJQYXRofSIKCiAgcmVhbHBhdGggLW0gIiR7ZnVsbFBhdGh9IiAyPi9kZXYvbnVsbAp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgZXJyb3IgY29sb3IgKHJlZCkKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpkaXNwbGF5RXJyb3IoKSB7CiAgaWYgKChCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMID49IF9fTEVWRUxfRVJST1IpKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX0VSUk9SX0NPTE9SfUVSUk9SICAgLSAkezF9JHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgZmkKICBMb2c6OmxvZ0Vycm9yICIkMSIKfQoKIyBAZGVzY3JpcHRpb24gRGlzcGxheSBtZXNzYWdlIHVzaW5nIHdhcm5pbmcgY29sb3IgKHllbGxvdykKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpkaXNwbGF5V2FybmluZygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUwgPj0gX19MRVZFTF9XQVJOSU5HKSk7IHRoZW4KICAgIGVjaG8gLWUgIiR7X19XQVJOSU5HX0NPTE9SfVdBUk4gICAgLSAkezF9JHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgZmkKICBMb2c6OmxvZ1dhcm5pbmcgIiQxIgp9CgojIEBkZXNjcmlwdGlvbiBlbnN1cmUgZW52IGZpbGVzIGFyZSBsb2FkZWQKIyBAbm9hcmdzCiMgQGV4aXRjb2RlIDEgaWYgZ2V0T3JkZXJlZENvbmZGaWxlcyBmYWlscwojIEBleGl0Y29kZSAyIGlmIG9uZSBvZiBlbnYgZmlsZXMgZmFpbHMgdG8gbG9hZAojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gaXMgZGlzcGxheWVkCkVudjo6cmVxdWlyZUxvYWQoKSB7CiAgbG9jYWwgY29uZmlnRmlsZXNTdHIKICBjb25maWdGaWxlc1N0cj0iJChFbnY6OmdldE9yZGVyZWRDb25mRmlsZXMpIiB8fCByZXR1cm4gMQoKICBsb2NhbCAtYSBjb25maWdGaWxlcwogIHJlYWRhcnJheSAtdCBjb25maWdGaWxlcyA8PDwiJHtjb25maWdGaWxlc1N0cn0iCgogICMgaWYgZW1wdHkgc3RyaW5nLCB0aGVyZSB3aWxsIGJlIG9uZSBlbGVtZW50CiAgaWYgKCgkeyNjb25maWdGaWxlc1tAXX0gPT0gMCkpIHx8IFtbIC16ICIke2NvbmZpZ0ZpbGVzU3RyfSIgXV07IHRoZW4KICAgICMgc2hvdWxkIG5vdCBoYXBwZW4sIGFzIHRoZXJlIGlzIGFsd2F5cyBkZWZhdWx0IGZpbGUKICAgIExvZzo6ZGlzcGxheVNraXBwZWQgIm5vIGVudiBmaWxlIHRvIGxvYWQiCiAgICByZXR1cm4gMAogIGZpCgogIEVudjo6bWVyZ2VDb25mRmlsZXMgIiR7Y29uZmlnRmlsZXNbQF19IiB8fCB7CiAgICBMb2c6OmRpc3BsYXlFcnJvciAid2hpbGUgbG9hZGluZyBjb25maWcgZmlsZXM6ICR7Y29uZmlnRmlsZXNbKl19IgogICAgcmV0dXJuIDIKICB9Cn0KCiMgQGRlc2NyaXB0aW9uIGFjdGl2YXRlIG9yIG5vdCBMb2c6OmRpc3BsYXkqIGFuZCBMb2c6OmxvZyogZnVuY3Rpb25zCiMgYmFzZWQgb24gQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCBhbmQgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMCiMgZW52aXJvbm1lbnQgdmFyaWFibGVzIGxvYWRlZCBieSBFbnY6OnJlcXVpcmVMb2FkCiMgdHJ5IHRvIGNyZWF0ZSBsb2cgZmlsZSBhbmQgcm90YXRlIGl0IGlmIG5lY2Vzc2FyeQojIEBub2FyZ3MKIyBAc2V0IEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCBpbnQgdG8gT0ZGIGxldmVsIGlmIEJBU0hfRlJBTUVXT1JLX0xPR19GSUxFIGlzIGVtcHR5IG9yIG5vdCB3cml0YWJsZQojIEBlbnYgQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCBpbnQKIyBAZW52IEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCBpbnQKIyBAZW52IEJBU0hfRlJBTUVXT1JLX0xPR19GSUxFIFN0cmluZwojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OIGludCBkbyBsb2cgcm90YXRpb24gaWYgPiAwCiMgQGV4aXRjb2RlIDAgYWx3YXlzIHN1Y2Nlc3NmdWwKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGFib3V0IGxvZyBmaWxlIGlzIGRpc3BsYXllZAojIEByZXF1aXJlIEVudjo6cmVxdWlyZUxvYWQKIyBAcmVxdWlyZSBVSTo6cmVxdWlyZVRoZW1lCkxvZzo6cmVxdWlyZUxvYWQoKSB7CiAgaWYgW1sgLXogIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEU6LX0iIF1dOyB0aGVuCiAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgIGV4cG9ydCBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwKICBmaQoKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+IF9fTEVWRUxfT0ZGKSk7IHRoZW4KICAgIGlmIFtbICEgLWYgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXTsgdGhlbgogICAgICBpZgogICAgICAgICEgbWtkaXIgLXAgIiQoZGlybmFtZSAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iKSIgMj4vZGV2L251bGwgfHwKICAgICAgICAgICEgdG91Y2ggLS1uby1jcmVhdGUgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiAyPi9kZXYvbnVsbAogICAgICB0aGVuCiAgICAgICAgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMPSR7X19MRVZFTF9PRkZ9CiAgICAgICAgZWNobyAtZSAiJHtfX0VSUk9SX0NPTE9SfUVSUk9SICAgLSBGaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IGlzIG5vdCB3cml0YWJsZSR7X19SRVNFVF9DT0xPUn0iID4mMgogICAgICBmaQogICAgZWxpZiBbWyAhIC13ICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIgXV07IHRoZW4KICAgICAgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMPSR7X19MRVZFTF9PRkZ9CiAgICAgIGVjaG8gLWUgIiR7X19FUlJPUl9DT0xPUn1FUlJPUiAgIC0gRmlsZSAke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSBpcyBub3Qgd3JpdGFibGUke19fUkVTRVRfQ09MT1J9IiA+JjIKICAgIGZpCgogIGZpCgogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID4gX19MRVZFTF9PRkYpKTsgdGhlbgogICAgIyB3aWxsIGFsd2F5cyBiZSBjcmVhdGVkIGV2ZW4gaWYgbm90IGluIGluZm8gbGV2ZWwKICAgIExvZzo6bG9nTWVzc2FnZSAiSU5GTyIgIkxvZ2dpbmcgdG8gZmlsZSAke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSAtIExvZyBsZXZlbCAke0JBU0hfRlJBTUVXT1JLX0xPR19MRVZFTH0iCiAgICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTiA+IDApKTsgdGhlbgogICAgICBMb2c6OnJvdGF0ZSAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTn0iCiAgICBmaQogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGdldCBsaXN0IG9mIGVudiBmaWxlcyB0byBsb2FkCiMgaW4gb3JkZXIgdG8gbWFrZSB0aGVtIGF2YWlsYWJsZSBmb3IgRW52OjpyZXF1aXJlTG9hZAojIEBlbnYgQkFTSF9GUkFNRVdPUktfRU5WX0ZJTEVTIFN0cmluZ1tdIGxpc3Qgb2YgZW52IGZpbGVzIHRoYXQgc2hvdWxkIGJlIGxvYWRlZAojIEBleGl0Y29kZSAxIGlmIG9uZSBvZiB0aGUgZW52IGZpbGUgY2Fubm90IGJlIGdlbmVyYXRlZAojIEBleGl0Y29kZSAyIGlmIG9uZSBvZiB0aGUgZW52IGZpbGUgaXMgbm90IGEgZmlsZSBvciByZWFkYWJsZQojIEBzdGRvdXQgdGhlIGVudiBmaWxlcyBhc2tlZCB0byBiZSBsb2FkZWQKIyBAc3RkZXJyIGRpYWdub3N0aWMgaW5mb3JtYXRpb24gb24gZmFpbHVyZQojIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZjaGFzdGFuZXQvYmFzaC10b29scy1mcmFtZXdvcmsvYmxvYi9tYXN0ZXIvRnJhbWV3b3JrRG9jLm1kI2NvbmZpZ19maWxlX29yZGVyCkVudjo6Z2V0T3JkZXJlZENvbmZGaWxlcygpIHsKICBsb2NhbCAtYSBjb25maWdGaWxlcz0oKQoKICBpZiBbWyAtbiAiJHtCQVNIX0ZSQU1FV09SS19FTlZfRklMRVNbMF0rMX0iIF1dOyB0aGVuCiAgICAjIEJBU0hfRlJBTUVXT1JLX0VOVl9GSUxFUyBpcyBhbiBhcnJheQogICAgY29uZmlnRmlsZXMrPSgiJHtCQVNIX0ZSQU1FV09SS19FTlZfRklMRVNbQF19IikKICBmaQoKICBsb2NhbCBkZWZhdWx0RW52RmlsZQogIGRlZmF1bHRFbnZGaWxlPSIkKEVudjo6Y3JlYXRlRGVmYXVsdEVudkZpbGUpIiB8fCByZXR1cm4gMQogIGNvbmZpZ0ZpbGVzKz0oIiR7ZGVmYXVsdEVudkZpbGV9IikKCiAgbG9jYWwgZmlsZQogIGZvciBmaWxlIGluICIke2NvbmZpZ0ZpbGVzW0BdfSI7IGRvCiAgICBpZiBbWyAhIC1mICIke2ZpbGV9IiB8fCAhIC1yICIke2ZpbGV9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiT25lIG9mIHRoZSBjb25maWcgZmlsZSBpcyBub3QgYXZhaWxhYmxlICcke2ZpbGV9JyIKICAgICAgcmV0dXJuIDIKICAgIGZpCiAgICBlY2hvICIke2ZpbGV9IgogIGRvbmUKfQoKIyBAZGVzY3JpcHRpb24gbWVyZ2UgYW5kIGxvYWQgY29uZiBmaWxlcyBzcGVjaWZpZWQgYXMgYXJndW1lbnQKIyAtIGZpbGVzIGFyZSBjbGVhbmVkIGZyb20gYXkgY29tbWVudAojIC0gbWlzc2luZyBxdW90ZXMgYWZ0ZXIgcHJvcGVydHkgPSBzaWduIGFyZSBhZGRlZCBhdXRvbWF0aWNhbGx5CiMgLSBhdXRvbWF0aWMgcmVtb3ZlIG9mIGFsbCB3aGl0ZXNwYWNlIGJlZm9yZSBhbmQgYWZ0ZXIgZGVjbGFyYXRpb25zCiMgLSBiYXNoIGFycmF5cyBhcmUgbm90IHN1cHBvcnRlZAojIC0gaWYgYSB2YXJpYWJsZSBpcyBkZWNsYXJlZCBpbiBmaXJzdCBmaWxlIGFuZCBvdmVycmlkZGVuIGxhdGVyIG9uCiMgICBpbiB0aGUgc2FtZSBmaWxlIG9yIGluIHN1YnNlcXVlbnQgZmlsZXMsIHRob3NlIG92ZXJsb2FkcyB3aWxsIGJlCiMgICBpZ25vcmVkCiMgQHdhcm5pbmcgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGxvYWRpbmcgb25lIG9mIHRoZSBjb25maWcgZmlsZSwgZXhpdCBjb2RlIDMgYnV0IGVudmlyb25tZW50IGNvdWxkIGJlIHBhcnRpYWxseSBsb2FkZWQKIyBAYXJnICRAIGFyZ3M6U3RyaW5nW10gbGlzdCBvZiBjb25maWd1cmF0aW9uIGZpbGVzIHRvIGxvYWQgaW4gb3JkZXIKIyBAc2V0IGVudlZhcnMgU3RyaW5nIHdpbGwgc2V0IGluIGVudmlyb25tZW50IGFsbCB0aGUgdmFyaWFibGVzIHRoYXQgaGF2ZSBiZWVuIGRlY2xhcmVkIGluIHRoZSBjb25maWcgZmlsZXMKIyBAZW52IGVudlZhcnMgU3RyaW5nIHRoZSBlbnYgdmFyaWFibGVzIG9mIHRoZSBjdXJyZW50IHNjcmlwdCBjb3VsZCBiZSB1c2VkIHRvIGludGVycHJldCB2YXJpYWJsZXMgZHVyaW5nIGNvbmZpZyBmaWxlcyBwYXJzaW5nCiMgQGV4aXRjb2RlIDAgaWYgbm8gY29uZmlnIGZpbGVzIHByb3ZpZGVkIG9yIGxvYWQgY29tcGxldGVkIHN1Y2Nlc3NmdWxseQojIEBleGl0Y29kZSAxIGlmIGVycm9yIG9jY3VycmVkIGR1cmluZyBwYXJzaW5nIHRoZSBjb25maWcgZmlsZXMgKGZpbGUgbm90IGZvdW5kLCBncmVwLCBhd2sgb3Igc2VkIGVycm9yKQojIEBleGl0Y29kZSAyIGlmIHRlbXBvcmFyeSBmaWxlIGNhbm5vdCBiZSBjcmVhdGVkCiMgQGV4aXRjb2RlIDMgaWYgYW4gZXJyb3Igb2NjdXJyZWQgZHVyaW5nIGNvbmZpZyBmaWxlIHNvdXJjaW5nCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKIyBAc2VlIGxhcmdlbHkgaW5zcGlyZWQgYnV0IG1vZGlmaWVkIGZyb20gaHR0cHM6Ly9vcGVuc291cmNlLmNvbS9hcnRpY2xlLzIxLzUvcHJvY2Vzc2luZy1jb25maWd1cmF0aW9uLWZpbGVzLXNoZWxsCkVudjo6bWVyZ2VDb25mRmlsZXMoKSB7CiAgbG9jYWwgLWEgY29uZmlnRmlsZUxpc3Q9KCIkQCIpCgogIGlmICgoJHsjY29uZmlnRmlsZUxpc3RbQF19ID09IDApKTsgdGhlbgogICAgcmV0dXJuIDAKICBmaQoKICBsb2NhbCBjb21iaW5lZENvbmZpZ0ZpbGUKICBjb21iaW5lZENvbmZpZ0ZpbGU9IiQoRnJhbWV3b3JrOjpjcmVhdGVUZW1wRmlsZSAibWVyZ2VDb25mRmlsZXMiKSIgfHwgcmV0dXJuIDIKCiAgKAogICAgIyByZW1vdmVzIGFueSB0cmFpbGluZyB3aGl0ZXNwYWNlIGZyb20gZWFjaCBmaWxlLCBpZiBhbnkKICAgICMgdGhpcyBpcyBhYnNvbHV0ZWx5IHJlcXVpcmVkIHdoZW4gaW1wb3J0aW5nIGludG8gQ29uZmlnTWFwcwogICAgIyBwdXQgcXVvdGVzIGFyb3VuZCB2YWx1ZXMKICAgIHNlZCAtRSAtZSAkJ3MvXHMqJC8vIDsgL14kL2QgOyAvXiMuKiQvZCA7IHMvPShbXiJcJ10uKikkLz0iXFwxIi8nICIke2NvbmZpZ0ZpbGVMaXN0W0BdfSIgfAogICAgICAjIHJlbW92ZSBhbGwgY29tbWVudCBsaW5lcwogICAgICBGaWx0ZXJzOjpjb21tZW50TGluZXMgfAogICAgICAjIGl0ZXJhdGVzIG92ZXIgZWFjaCBmaWxlIGFuZCBwcmludHMgKGRlZmF1bHQgYXdrIGJlaGF2aW9yKQogICAgICAjIGVhY2ggdW5pcXVlIGxpbmU7IG9ubHkgdGFrZXMgZmlyc3QgdmFsdWUgYW5kIGlnbm9yZXMgZHVwbGljYXRlcwogICAgICBhd2sgLUY9ICchbGluZVskMV0rKycKICApID4iJHtjb21iaW5lZENvbmZpZ0ZpbGV9IiB8fCByZXR1cm4gMQoKICAjIGhhdmUgdG8gZXhwb3J0IGV2ZXJ5dGhpbmcsIGFuZCBzb3VyY2UgaXQgdHdpY2U6CiAgIyAxKSBmaXJzdCBzb3VyY2UgaXMgdG8gcmVhbGl6ZSB2YXJpYWJsZXMKICAjIDIpIHNlY29uZCB0aW1lIGlzIHRvIHJlYWxpemUgcmVmZXJlbmNlcwogIHNldCAtbyBhbGxleHBvcnQKICAjIHNoZWxsY2hlY2sgc291cmNlPS5mcmFtZXdvcmstY29uZmlnCiAgc291cmNlICIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAzCiAgIyBzaGVsbGNoZWNrIHNvdXJjZT0uZnJhbWV3b3JrLWNvbmZpZwogIHNvdXJjZSAiJHtjb21iaW5lZENvbmZpZ0ZpbGV9IiB8fCByZXR1cm4gMwogIHNldCArbyBhbGxleHBvcnQKfQoKIyBAZGVzY3JpcHRpb24gRGlzcGxheSBtZXNzYWdlIHVzaW5nIHNraXAgY29sb3IgKHllbGxvdykKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpkaXNwbGF5U2tpcHBlZCgpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUwgPj0gX19MRVZFTF9JTkZPKSk7IHRoZW4KICAgIGVjaG8gLWUgIiR7X19TS0lQUEVEX0NPTE9SfVNLSVBQRUQgLSAkezF9JHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgZmkKICBMb2c6OmxvZ1NraXBwZWQgIiQxIgp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nRXJyb3IoKSB7CiAgaWYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPj0gX19MRVZFTF9FUlJPUikpOyB0aGVuCiAgICBMb2c6OmxvZ01lc3NhZ2UgIiR7MjotRVJST1J9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ1dhcm5pbmcoKSB7CiAgaWYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPj0gX19MRVZFTF9XQVJOSU5HKSk7IHRoZW4KICAgIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1XQVJOSU5HfSIgIiQxIgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIFRvIGJlIGNhbGxlZCBiZWZvcmUgbG9nZ2luZyBpbiB0aGUgbG9nIGZpbGUKIyBAYXJnICQxIGZpbGU6c3RyaW5nIGxvZyBmaWxlIG5hbWUKIyBAYXJnICQyIG1heExvZ0ZpbGVzQ291bnQ6aW50IG1heGltdW0gbnVtYmVyIG9mIGxvZyBmaWxlcwpMb2c6OnJvdGF0ZSgpIHsKICBsb2NhbCBmaWxlPSIkMSIKICBsb2NhbCBtYXhMb2dGaWxlc0NvdW50PSIkezI6LTV9IgoKICBpZiBbWyAhIC1mICIke2ZpbGV9IiBdXTsgdGhlbgogICAgTG9nOjpkaXNwbGF5U2tpcHBlZCAiTG9nIGZpbGUgJHtmaWxlfSBkb2Vzbid0IGV4aXN0IHlldCIKICAgIHJldHVybiAwCiAgZmkKICBmb3IgaSBpbiAkKHNlcSAkKChtYXhMb2dGaWxlc0NvdW50IC0gMSkpIC0xIDEpOyBkbwogICAgTG9nOjpkaXNwbGF5SW5mbyAiTG9nIHJvdGF0aW9uICR7ZmlsZX0uJHtpfSB0byAke2ZpbGV9LiQoKGkgKyAxKSkiCiAgICBtdiAiJHtmaWxlfS4ieyIke2l9IiwiJCgoaSArIDEpKSJ9ICY+L2Rldi9udWxsIHx8IHRydWUKICBkb25lCiAgaWYgY3AgIiR7ZmlsZX0iICIke2ZpbGV9LjEiICY+L2Rldi9udWxsOyB0aGVuCiAgICBlY2hvID4iJHtmaWxlfSIgIyByZXNldCBsb2cgZmlsZQogICAgTG9nOjpkaXNwbGF5SW5mbyAiTG9nIHJvdGF0aW9uICR7ZmlsZX0gdG8gJHtmaWxlfS4xIgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBjb21tYW5kIHJlYWxwYXRoIGlzIGF2YWlsYWJsZQojIEBleGl0Y29kZSAxIGlmIHJlYWxwYXRoIGNvbW1hbmQgbm90IGF2YWlsYWJsZQojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gaXMgZGlzcGxheWVkCkxpbnV4OjpyZXF1aXJlUmVhbHBhdGhDb21tYW5kKCkgewogIEFzc2VydDo6Y29tbWFuZEV4aXN0cyByZWFscGF0aAp9CgojIEBkZXNjcmlwdGlvbiBsb2FkIGNvbG9yIHRoZW1lCiMgQG5vYXJncwojIEBlbnYgQkFTSF9GUkFNRVdPUktfVEhFTUUgU3RyaW5nIHRoZW1lIHRvIHVzZQojIEBleGl0Y29kZSAwIGFsd2F5cyBzdWNjZXNzZnVsClVJOjpyZXF1aXJlVGhlbWUoKSB7CiAgVUk6OnRoZW1lICIke0JBU0hfRlJBTUVXT1JLX1RIRU1FLWRlZmF1bHR9Igp9CgojIEBkZXNjcmlwdGlvbiBjaGVjayBpZiBjb21tYW5kIHNwZWNpZmllZCBleGlzdHMgb3IgcmV0dXJuIDEKIyB3aXRoIGVycm9yIGFuZCBtZXNzYWdlIGlmIG5vdAojCiMgQGFyZyAkMSBjb21tYW5kTmFtZTpTdHJpbmcgb24gd2hpY2ggZXhpc3RlbmNlIG11c3QgYmUgY2hlY2tlZAojIEBhcmcgJDIgaGVscElmTm90RXhpc3RzOlN0cmluZyBhIGhlbHAgY29tbWFuZCB0byBkaXNwbGF5IGlmIHRoZSBjb21tYW5kIGRvZXMgbm90IGV4aXN0CiMKIyBAZXhpdGNvZGUgMSBpZiB0aGUgY29tbWFuZCBzcGVjaWZpZWQgZG9lcyBub3QgZXhpc3QKIyBAc3RkZXJyIGRpYWdub3N0aWMgaW5mb3JtYXRpb24gKyBoZWxwIGlmIHNlY29uZCBhcmd1bWVudCBpcyBwcm92aWRlZApBc3NlcnQ6OmNvbW1hbmRFeGlzdHMoKSB7CiAgbG9jYWwgY29tbWFuZE5hbWU9IiQxIgogIGxvY2FsIGhlbHBJZk5vdEV4aXN0cz0iJDIiCgogICIke0JBU0hfRlJBTUVXT1JLX0NPTU1BTkQ6LWNvbW1hbmR9IiAtdiAiJHtjb21tYW5kTmFtZX0iID4vZGV2L251bGwgMj4vZGV2L251bGwgfHwgewogICAgTG9nOjpkaXNwbGF5RXJyb3IgIiR7Y29tbWFuZE5hbWV9IGlzIG5vdCBpbnN0YWxsZWQsIHBsZWFzZSBpbnN0YWxsIGl0IgogICAgaWYgW1sgLW4gIiR7aGVscElmTm90RXhpc3RzfSIgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5SW5mbyAiJHtoZWxwSWZOb3RFeGlzdHN9IgogICAgZmkKICAgIHJldHVybiAxCiAgfQogIHJldHVybiAwCn0KCiMgQGRlc2NyaXB0aW9uIGRlZmF1bHQgZW52IGZpbGUgd2l0aCBhbGwgZGVmYXVsdCB2YWx1ZXMKIyBAc3Rkb3V0IHRoZSBkZWZhdWx0IGVudiBmaWxlcGF0aApFbnY6OmNyZWF0ZURlZmF1bHRFbnZGaWxlKCkgewogIGxvY2FsIGVudkZpbGUKICBlbnZGaWxlPSIkKEZyYW1ld29yazo6Y3JlYXRlVGVtcEZpbGUgImNyZWF0ZURlZmF1bHRFbnZGaWxlRW52RmlsZSIpIiB8fCByZXR1cm4gMgoKICAoCiAgICBlY2hvICJCQVNIX0ZSQU1FV09SS19USEVNRT0ke0JBU0hfRlJBTUVXT1JLX1RIRU1FOi1kZWZhdWx0fSIKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTD0ke0JBU0hfRlJBTUVXT1JLX0xPR19MRVZFTDotMH0iCiAgICBlY2hvICJCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMPSR7QkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTDotJHtfX0xFVkVMX1dBUk5JTkd9fSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAxNgogICAgZWNobyAnQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEU9IiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEU6LSIke0ZSQU1FV09SS19ST09UX0RJUn0vbG9ncy8ke1NDUklQVF9OQU1FfS5sb2cifSInCiAgICBlY2hvICJCQVNIX0ZSQU1FV09SS19MT0dfRklMRV9NQVhfUk9UQVRJT049JHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRV9NQVhfUk9UQVRJT046LTV9IgogICkgPiIke2VudkZpbGV9IgogIGVjaG8gIiR7ZW52RmlsZX0iCn0KCiMgQGRlc2NyaXB0aW9uIHJlbW92ZSBjb21tZW50IGxpbmVzIGZyb20gaW5wdXQgb3IgZmlsZXMgcHJvdmlkZWQgYXMgYXJndW1lbnRzCiMgQGFyZyAkQCBmaWxlczpTdHJpbmdbXSAob3B0aW9uYWwpIHRoZSBmaWxlcyB0byBmaWx0ZXIKIyBAZW52IGNvbW1lbnRMaW5lUHJlZml4IFN0cmluZyB0aGUgY29tbWVudCBsaW5lIHByZWZpeCAoZGVmYXVsdCB2YWx1ZTogIykKIyBAZXhpdGNvZGUgMCBpZiBsaW5lcyBmaWx0ZXJlZCBvciBub3QKIyBAZXhpdGNvZGUgMiBpZiBncmVwIGZhaWxzIGZvciBhbnkgb3RoZXIgcmVhc29ucyB0aGFuIG5vdCBmb3VuZAojIEBzdGRpbiB0aGUgZmlsZSBhcyBzdGRpbiB0byBmaWx0ZXIgKGFsdGVybmF0aXZlIHRvIGZpbGVzIGFyZ3VtZW50KQojIEBzdGRvdXQgdGhlIGZpbHRlcmVkIGxpbmVzCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjEyMApGaWx0ZXJzOjpjb21tZW50TGluZXMoKSB7CiAgZ3JlcCAtdnhFICJbWzpibGFuazpdXSooJHtjb21tZW50TGluZVByZWZpeDotI30uKik/IiAiJEAiIHx8IHRlc3QgJD8gPSAxCn0KCiMgQGRlc2NyaXB0aW9uIGNyZWF0ZSBhIHRlbXAgZmlsZSB1c2luZyBkZWZhdWx0IFRNUERJUiB2YXJpYWJsZQojIGluaXRpYWxpemVkIGluIF9pbmNsdWRlcy9fY29tbW9uSGVhZGVyLnNoCiMgQGVudiBUTVBESVIgU3RyaW5nIChkZWZhdWx0IHZhbHVlIC90bXApCiMgQGFyZyAkMSB0ZW1wbGF0ZU5hbWU6U3RyaW5nIHRlbXBsYXRlIG5hbWUgdG8gdXNlKG9wdGlvbmFsKQpGcmFtZXdvcms6OmNyZWF0ZVRlbXBGaWxlKCkgewogIG1rdGVtcCAtcCAiJHtUTVBESVI6LS90bXB9IiAtdCAiJHsxOi19LlhYWFhYWFhYWFhYWCIKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ1NraXBwZWQoKSB7CiAgaWYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPj0gX19MRVZFTF9JTkZPKSk7IHRoZW4KICAgIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1TS0lQUEVEfSIgIiQxIgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGxvYWQgY29sb3JzIHRoZW1lIGNvbnN0YW50cwojIEB3YXJuaW5nIGlmIHR0eSBub3Qgb3BlbmVkLCBub0NvbG9yIHRoZW1lIHdpbGwgYmUgY2hvc2VuCiMgQGFyZyAkMSB0aGVtZTpTdHJpbmcgdGhlIHRoZW1lIHRvIHVzZSAoZGVmYXVsdCwgbm9Db2xvcikKIyBAYXJnICRAIGFyZ3M6U3RyaW5nW10KIyBAc2V0IF9fRVJST1JfQ09MT1IgU3RyaW5nIGluZGljYXRlIGVycm9yIHN0YXR1cwojIEBzZXQgX19JTkZPX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSBpbmZvIHN0YXR1cwojIEBzZXQgX19TVUNDRVNTX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSBzdWNjZXNzIHN0YXR1cwojIEBzZXQgX19XQVJOSU5HX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSB3YXJuaW5nIHN0YXR1cwojIEBzZXQgX19TS0lQUEVEX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSBza2lwcGVkIHN0YXR1cwojIEBzZXQgX19ERUJVR19DT0xPUiBTdHJpbmcgaW5kaWNhdGUgZGVidWcgc3RhdHVzCiMgQHNldCBfX0hFTFBfQ09MT1IgU3RyaW5nIGluZGljYXRlIGhlbHAgc3RhdHVzCiMgQHNldCBfX1RFU1RfQ09MT1IgU3RyaW5nIG5vdCB1c2VkCiMgQHNldCBfX1RFU1RfRVJST1JfQ09MT1IgU3RyaW5nIG5vdCB1c2VkCiMgQHNldCBfX0hFTFBfVElUTEVfQ09MT1IgU3RyaW5nIHVzZWQgdG8gZGlzcGxheSBoZWxwIHRpdGxlIGluIGhlbHAgc3RyaW5ncwojIEBzZXQgX19IRUxQX09QVElPTl9DT0xPUiBTdHJpbmcgdXNlZCB0byBkaXNwbGF5IGhpZ2hsaWdodCBvcHRpb25zIGluIGhlbHAgc3RyaW5ncwojCiMgQHNldCBfX1JFU0VUX0NPTE9SIFN0cmluZyByZXNldCBkZWZhdWx0IGNvbG9yCiMKIyBAc2V0IF9fSEVMUF9FWEFNUExFIFN0cmluZyB0byByZW1vdmUKIyBAc2V0IF9fSEVMUF9USVRMRSBTdHJpbmcgdG8gcmVtb3ZlCiMgQHNldCBfX0hFTFBfTk9STUFMIFN0cmluZyB0byByZW1vdmUKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0ClVJOjp0aGVtZSgpIHsKICBsb2NhbCB0aGVtZT0iJHsxLWRlZmF1bHR9IgogIGlmIFtbICEgIiR7dGhlbWV9IiA9fiAtZm9yY2UkIF1dICYmICEgQXNzZXJ0Ojp0dHk7IHRoZW4KICAgIHRoZW1lPSJub0NvbG9yIgogIGZpCiAgY2FzZSAiJHt0aGVtZX0iIGluCiAgICBkZWZhdWx0IHwgZGVmYXVsdC1mb3JjZSkKICAgICAgdGhlbWU9ImRlZmF1bHQiCiAgICAgIDs7CiAgICBub0NvbG9yKSA7OwogICAgKikKICAgICAgTG9nOjpmYXRhbCAiaW52YWxpZCB0aGVtZSBwcm92aWRlZCIKICAgICAgOzsKICBlc2FjCiAgaWYgW1sgIiR7dGhlbWV9IiA9ICJkZWZhdWx0IiBdXTsgdGhlbgogICAgQkFTSF9GUkFNRVdPUktfVEhFTUU9ImRlZmF1bHQiCiAgICAjIGNoZWNrIGNvbG9ycyBhcHBsaWNhYmxlIGh0dHBzOi8vbWlzYy5mbG9naXNvZnQuY29tL2Jhc2gvdGlwX2NvbG9yc19hbmRfZm9ybWF0dGluZwogICAgX19FUlJPUl9DT0xPUj0nXGVbMzFtJyAgICAgICAgICMgUmVkCiAgICBfX0lORk9fQ09MT1I9J1xlWzQ0bScgICAgICAgICAgIyB3aGl0ZSBvbiBsaWdodEJsdWUKICAgIF9fU1VDQ0VTU19DT0xPUj0nXGVbMzJtJyAgICAgICAjIEdyZWVuCiAgICBfX1dBUk5JTkdfQ09MT1I9J1xlWzMzbScgICAgICAgIyBZZWxsb3cKICAgIF9fU0tJUFBFRF9DT0xPUj0nXGVbMzNtJyAgICAgICAjIFllbGxvdwogICAgX19ERUJVR19DT0xPUj0nXGVbMzdtJyAgICAgICAgICMgR3JleQogICAgX19IRUxQX0NPTE9SPSdcZVs3OzQ5OzMzbScgICAgICMgQmxhY2sgb24gR29sZAogICAgX19URVNUX0NPTE9SPSdcZVsxMDBtJyAgICAgICAgICMgTGlnaHQgbWFnZW50YQogICAgX19URVNUX0VSUk9SX0NPTE9SPSdcZVs0MW0nICAgICMgd2hpdGUgb24gcmVkCiAgICBfX0hFTFBfVElUTEVfQ09MT1I9IlxlWzE7MzdtIiAgIyBCb2xkCiAgICBfX0hFTFBfT1BUSU9OX0NPTE9SPSJcZVsxOzM0bSIgIyBCbHVlCiAgICAjIEludGVybmFsOiByZXNldCBjb2xvcgogICAgX19SRVNFVF9DT0xPUj0nXGVbMG0nICMgUmVzZXQgQ29sb3IKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE1NSxTQzIwMzQKICAgIF9fSEVMUF9FWEFNUExFPSIkKGVjaG8gLWUgIlxlWzI7OTdtIikiCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIxNTUsU0MyMDM0CiAgICBfX0hFTFBfVElUTEU9IiQoZWNobyAtZSAiXGVbMTszN20iKSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE1NSxTQzIwMzQKICAgIF9fSEVMUF9OT1JNQUw9IiQoZWNobyAtZSAiXDAzM1swbSIpIgogIGVsc2UKICAgIEJBU0hfRlJBTUVXT1JLX1RIRU1FPSJub0NvbG9yIgogICAgIyBjaGVjayBjb2xvcnMgYXBwbGljYWJsZSBodHRwczovL21pc2MuZmxvZ2lzb2Z0LmNvbS9iYXNoL3RpcF9jb2xvcnNfYW5kX2Zvcm1hdHRpbmcKICAgIF9fRVJST1JfQ09MT1I9JycKICAgIF9fSU5GT19DT0xPUj0nJwogICAgX19TVUNDRVNTX0NPTE9SPScnCiAgICBfX1dBUk5JTkdfQ09MT1I9JycKICAgIF9fU0tJUFBFRF9DT0xPUj0nJwogICAgX19ERUJVR19DT0xPUj0nJwogICAgX19IRUxQX0NPTE9SPScnCiAgICBfX1RFU1RfQ09MT1I9JycKICAgIF9fVEVTVF9FUlJPUl9DT0xPUj0nJwogICAgX19IRUxQX1RJVExFX0NPTE9SPScnCiAgICBfX0hFTFBfT1BUSU9OX0NPTE9SPScnCiAgICAjIEludGVybmFsOiByZXNldCBjb2xvcgogICAgX19SRVNFVF9DT0xPUj0nJwogICAgX19IRUxQX0VYQU1QTEU9JycKICAgIF9fSEVMUF9USVRMRT0nJwogICAgX19IRUxQX05PUk1BTD0nJwogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIHR0eSAoaW50ZXJhY3RpdmUgbW9kZSkgaXMgYWN0aXZlCiMgQG5vYXJncwojIEBleGl0Y29kZSAxIGlmIHR0eSBub3QgYWN0aXZlCiMgQGVudiBOT05fSU5URVJBQ1RJVkUgaWYgMSBjb25zaWRlciBhcyBub3QgaW50ZXJhY3RpdmUgZXZlbiBpZiBlbnZpcm9ubWVudCBpcyBpbnRlcmFjdGl2ZQojIEBlbnYgSU5URVJBQ1RJVkUgaWYgMSBjb25zaWRlciBhcyBpbnRlcmFjdGl2ZSBldmVuIGlmIGVudmlyb25tZW50IGlzIG5vdCBpbnRlcmFjdGl2ZQojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiArIGhlbHAgaWYgc2Vjb25kIGFyZ3VtZW50IGlzIHByb3ZpZGVkCkFzc2VydDo6dHR5KCkgewogIGlmIFtbICIke05PTl9JTlRFUkFDVElWRTotMH0iID0gIjEiIF1dOyB0aGVuCiAgICByZXR1cm4gMQogIGZpCiAgaWYgW1sgIiR7SU5URVJBQ1RJVkU6LTB9IiA9ICIxIiBdXTsgdGhlbgogICAgcmV0dXJuIDAKICBmaQogIFtbIC10IDEgfHwgLXQgMiBdXQp9CgojIEZVTkNUSU9OUwoKZmFjYWRlX21haW5fZW1iZWRGcmFtZXdvcmtGdW5jdGlvbmJpbkZpbGV0cGwoKSB7CiMgUkVRVUlSRVMKTGludXg6OnJlcXVpcmVFeGVjdXRlZEFzVXNlcgpFbnY6OnJlcXVpcmVMb2FkCkxvZzo6cmVxdWlyZUxvYWQKTGludXg6OnJlcXVpcmVSZWFscGF0aENvbW1hbmQKVUk6OnJlcXVpcmVUaGVtZQpDb21waWxlcjo6RmFjYWRlOjpyZXF1aXJlQ29tbWFuZEJpbkRpcgoKIyBAcmVxdWlyZSBDb21waWxlcjo6RmFjYWRlOjpyZXF1aXJlQ29tbWFuZEJpbkRpcgoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU0LFNDMjAxNgpmdW5jdGlvblRvQ2FsbD0nRGI6OnF1ZXJ5T25lRGF0YWJhc2UnCiIke2Z1bmN0aW9uVG9DYWxsfSIgIiRAIgoKfQoKZmFjYWRlX21haW5fZW1iZWRGcmFtZXdvcmtGdW5jdGlvbmJpbkZpbGV0cGwgIiRAIgo=" Compiler::Embed::extractFileFromBase64 \ "${embed_function_DbQueryOneDatabase}" \ diff --git a/bin/dbScriptAllDatabases b/bin/dbScriptAllDatabases index f9a955ab..3a6f5f7b 100755 --- a/bin/dbScriptAllDatabases +++ b/bin/dbScriptAllDatabases @@ -59,7 +59,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management @@ -1215,8 +1219,8 @@ Array::contains() { # @require Compiler::Embed::requireEmbedBinDir -declare -gx embed_function_DbQueryOneDatabase="${PERSISTENT_TMPDIR:-/tmp}/bin/370dab633b77b22851fe46e08d43de97/dbQueryOneDatabase" -declare -gx encoded_binary_file_DbQueryOneDatabase="IyEvdXNyL2Jpbi9lbnYgYmFzaAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgR0VORVJBVEVEIEZBQ0FERSBGUk9NIGh0dHBzOi8vZ2l0aHViLmNvbS9mY2hhc3RhbmV0L2Jhc2gtdG9vbHMvdHJlZS9tYXN0ZXIvLi4vYmFzaC1kZXYtZW52L3ZlbmRvci9iYXNoLXRvb2xzLWZyYW1ld29yay9zcmMvQ29tcGlsZXIvRW1iZWQvZW1iZWRGcmFtZXdvcmtGdW5jdGlvbi5iaW5GaWxlLnRwbAojIERPIE5PVCBFRElUIElUCiMgQGdlbmVyYXRlZAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjI4OCxTQzIwMzQKIyBCSU5fRklMRT0ke0JJTl9GSUxFfQojIEZBQ0FERQoKIyBlbnN1cmUgdGhhdCBubyB1c2VyIGFsaWFzZXMgY291bGQgaW50ZXJmZXJlIHdpdGgKIyBjb21tYW5kcyB1c2VkIGluIHRoaXMgc2NyaXB0CnVuYWxpYXMgLWEgfHwgdHJ1ZQpzaG9wdCAtdSBleHBhbmRfYWxpYXNlcwoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CigoZmFpbHVyZXMgPSAwKSkgfHwgdHJ1ZQoKIyBCYXNoIHdpbGwgcmVtZW1iZXIgJiByZXR1cm4gdGhlIGhpZ2hlc3QgZXhpdCBjb2RlIGluIGEgY2hhaW4gb2YgcGlwZXMuCiMgVGhpcyB3YXkgeW91IGNhbiBjYXRjaCB0aGUgZXJyb3IgaW5zaWRlIHBpcGVzLCBlLmcuIG15c3FsZHVtcCB8IGd6aXAKc2V0IC1vIHBpcGVmYWlsCnNldCAtbyBlcnJleGl0CgojIENvbW1hbmQgU3Vic3RpdHV0aW9uIGNhbiBpbmhlcml0IGVycmV4aXQgb3B0aW9uIHNpbmNlIGJhc2ggdjQuNApzaG9wdCAtcyBpbmhlcml0X2VycmV4aXQgfHwgdHJ1ZQoKIyBhIGxvZyBpcyBnZW5lcmF0ZWQgd2hlbiBhIGNvbW1hbmQgZmFpbHMKc2V0IC1vIGVycnRyYWNlCgojIHVzZSBudWxsZ2xvYiBzbyB0aGF0IChmaWxlKi5waHApIHdpbGwgcmV0dXJuIGFuIGVtcHR5IGFycmF5IGlmIG5vIGZpbGUgbWF0Y2hlcyB0aGUgd2lsZGNhcmQKc2hvcHQgLXMgbnVsbGdsb2IKCiMgZW5zdXJlIHJlZ2V4cCBhcmUgaW50ZXJwcmV0ZWQgd2l0aG91dCBhY2NlbnR1YXRlZCBjaGFyYWN0ZXJzCmV4cG9ydCBMQ19BTEw9UE9TSVgKCmV4cG9ydCBURVJNPXh0ZXJtLTI1NmNvbG9yCgojIGF2b2lkIGludGVyYWN0aXZlIGluc3RhbGwKZXhwb3J0IERFQklBTl9GUk9OVEVORD1ub25pbnRlcmFjdGl2ZQpleHBvcnQgREVCQ09ORl9OT05JTlRFUkFDVElWRV9TRUVOPXRydWUKCiMgc3RvcmUgY29tbWFuZCBhcmd1bWVudHMgZm9yIGxhdGVyIHVzYWdlCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIEJBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIE9SSUdJTkFMX0JBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCgojIEBzZWUgaHR0cHM6Ly91bml4LnN0YWNrZXhjaGFuZ2UuY29tL2EvMzg2ODU2CiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwppbnRlcnJ1cHRNYW5hZ2VtZW50KCkgewogICMgcmVzdG9yZSBTSUdJTlQgaGFuZGxlcgogIHRyYXAgLSBJTlQKICAjIGVuc3VyZSB0aGF0IEN0cmwtQyBpcyB0cmFwcGVkIGJ5IHRoaXMgc2NyaXB0IGFuZCBub3QgYnkgc3ViIHByb2Nlc3MKICAjIHJlcG9ydCB0byB0aGUgcGFyZW50IHRoYXQgd2UgaGF2ZSBpbmRlZWQgYmVlbiBpbnRlcnJ1cHRlZAogIGtpbGwgLXMgSU5UICIkJCIKfQp0cmFwIGludGVycnVwdE1hbmFnZW1lbnQgSU5UClNDUklQVF9OQU1FPSR7MCMjKi99ClJFQUxfU0NSSVBUX0ZJTEU9IiQocmVhZGxpbmsgLWUgIiQocmVhbHBhdGggIiR7QkFTSF9TT1VSQ0VbMF19IikiKSIKQ1VSUkVOVF9ESVI9IiQoY2QgIiQocmVhZGxpbmsgLWUgIiR7UkVBTF9TQ1JJUFRfRklMRSUvKn0iKSIgJiYgcHdkIC1QKSIKCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojIFRlbXAgZGlyIG1hbmFnZW1lbnQKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCgpLRUVQX1RFTVBfRklMRVM9IiR7S0VFUF9URU1QX0ZJTEVTOi0wfSIKZXhwb3J0IEtFRVBfVEVNUF9GSUxFUwoKIyBQRVJTSVNURU5UX1RNUERJUiBpcyBub3QgZGVsZXRlZCBieSB0cmFwcwpQRVJTSVNURU5UX1RNUERJUj0iJHtUTVBESVI6LS90bXB9L2Jhc2gtZnJhbWV3b3JrIgpleHBvcnQgUEVSU0lTVEVOVF9UTVBESVIKbWtkaXIgLXAgIiR7UEVSU0lTVEVOVF9UTVBESVJ9IgoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0ClRNUERJUj0iJChta3RlbXAgLWQgLXAgIiR7UEVSU0lTVEVOVF9UTVBESVI6LS90bXB9IiAtdCBiYXNoLWZyYW1ld29yay0kJC1YWFhYWFgpIgpleHBvcnQgVE1QRElSCgojIHRlbXAgZGlyIGNsZWFuaW5nCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwpjbGVhbk9uRXhpdCgpIHsKICBpZiBbWyAiJHtLRUVQX1RFTVBfRklMRVM6LTB9IiA9ICIxIiBdXTsgdGhlbgogICAgTG9nOjpkaXNwbGF5SW5mbyAiS0VFUF9URU1QX0ZJTEVTPTEgdGVtcCBmaWxlcyBrZXB0IGhlcmUgJyR7VE1QRElSfSciCiAgZWxpZiBbWyAtbiAiJHtUTVBESVIreHh4fSIgXV07IHRoZW4KICAgIExvZzo6ZGlzcGxheURlYnVnICJLRUVQX1RFTVBfRklMRVM9MCByZW1vdmluZyB0ZW1wIGZpbGVzICcke1RNUERJUn0nIgogICAgcm0gLVJmICIke1RNUERJUjotL3RtcC9mYWtlfSIgPi9kZXYvbnVsbCAyPiYxCiAgZmkKfQp0cmFwIGNsZWFuT25FeGl0IEVYSVQgSFVQIFFVSVQgQUJSVCBURVJNCgojIFZBUl9NQUlOX0ZVTkNUSU9OX1ZBUl9OQU1FPWRiUXVlcnlBbGxEYXRhYmFzZXNGYWNhZGUKCiMgQGRlc2NyaXB0aW9uIHVzZWQgdG8gZXhlY3V0ZSBnaXZlbiBxdWVyeSB3aGVuIHVzaW5nCiMgZGJTY3JpcHRBbGxEYXRhYmFzZXMKIyBAYXJnICQxIGRzbjpTdHJpbmcKIyBAYXJnICQyIGRiOlN0cmluZwojIEBlbnYgcXVlcnkgU3RyaW5nCiMgQGVudiBvcHRpb25TZXBhcmF0b3IgU3RyaW5nCiMgQHJlcXVpcmUgTGludXg6OnJlcXVpcmVFeGVjdXRlZEFzVXNlcgpEYjo6cXVlcnlPbmVEYXRhYmFzZSgpIHsKICAjIHF1ZXJ5IGFuZCBvcHRpb25TZXBhcmF0b3IgYXJlIHBhc3NlZCB2aWEgZXhwb3J0CiAgbG9jYWwgZHNuPSIkMSIKICBsb2NhbCBkYj0iJDIiCgogIGxvY2FsIC1BIGRiSW5zdGFuY2UKICBEYXRhYmFzZTo6bmV3SW5zdGFuY2UgZGJJbnN0YW5jZSAiJHtkc259IgogIERhdGFiYXNlOjpzZXRRdWVyeU9wdGlvbnMgZGJJbnN0YW5jZSAiJHtkYkluc3RhbmNlW1FVRVJZX09QVElPTlNdfSAtLWNvbm5lY3QtdGltZW91dD01IgoKICAjIGlkZW50aWZ5IGNvbHVtbnMgaGVhZGVyCiAgZWNobyAtbiAiQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAiCiAgRGF0YWJhc2U6OnNraXBDb2x1bW5OYW1lcyBkYkluc3RhbmNlIDAKCiAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU0CiAgaWYgISBEYXRhYmFzZTo6cXVlcnkgZGJJbnN0YW5jZSAiJHtxdWVyeX0iICIke2RifSIgfCBzZWQgInMvXHQvJHtvcHRpb25TZXBhcmF0b3J9L2ciOyB0aGVuCiAgICBMb2c6OmZhdGFsICJkYXRhYmFzZSAke2RifSBlcnJvciIgMT4mMgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIExvZyBuYW1lc3BhY2UgcHJvdmlkZXMgMiBraW5kIG9mIGZ1bmN0aW9ucwojIC0gTG9nOjpkaXNwbGF5KiBhbGxvd3MgdG8gZGlzcGxheSBnaXZlbiBtZXNzYWdlIHdpdGgKIyAgIGdpdmVuIGRpc3BsYXkgbGV2ZWwKIyAtIExvZzo6bG9nKiBhbGxvd3MgdG8gbG9nIGdpdmVuIG1lc3NhZ2Ugd2l0aAojICAgZ2l2ZW4gbG9nIGxldmVsCiMgTG9nOjpkaXNwbGF5KiBmdW5jdGlvbnMgYXV0b21hdGljYWxseSBsb2cgdGhlIG1lc3NhZ2UgdG9vCiMgQHNlZSBFbnY6OnJlcXVpcmVMb2FkIHRvIGxvYWQgdGhlIGRpc3BsYXkgYW5kIGxvZyBsZXZlbCBmcm9tIC5lbnYgZmlsZQoKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIG9mZgpleHBvcnQgX19MRVZFTF9PRkY9MAojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgZXJyb3IKZXhwb3J0IF9fTEVWRUxfRVJST1I9MQojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgd2FybmluZwpleHBvcnQgX19MRVZFTF9XQVJOSU5HPTIKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIGluZm8KZXhwb3J0IF9fTEVWRUxfSU5GTz0zCiMgQGRlc2NyaXB0aW9uIGxvZyBsZXZlbCBzdWNjZXNzCmV4cG9ydCBfX0xFVkVMX1NVQ0NFU1M9MwojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgZGVidWcKZXhwb3J0IF9fTEVWRUxfREVCVUc9NAoKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBvZmYKZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9PRkY9MAojIEBkZXNjcmlwdGlvbiB2ZXJib3NlIGxldmVsIGluZm8KZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9JTkZPPTEKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBpbmZvCmV4cG9ydCBfX1ZFUkJPU0VfTEVWRUxfREVCVUc9MgojIEBkZXNjcmlwdGlvbiB2ZXJib3NlIGxldmVsIGluZm8KZXhwb3J0IF9fVkVSQk9TRV9MRVZFTF9UUkFDRT0zCgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgZGVidWcgY29sb3IgKGdyZXkpCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6ZGlzcGxheURlYnVnKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0RFQlVHKSk7IHRoZW4KICAgIGVjaG8gLWUgIiR7X19ERUJVR19DT0xPUn1ERUJVRyAgIC0gJHsxfSR7X19SRVNFVF9DT0xPUn0iID4mMgogIGZpCiAgTG9nOjpsb2dEZWJ1ZyAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBpbmZvIGNvbG9yIChiZyBsaWdodCBibHVlL2ZnIHdoaXRlKQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlJbmZvKCkgewogIGxvY2FsIHR5cGU9IiR7MjotSU5GT30iCiAgaWYgKChCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMID49IF9fTEVWRUxfSU5GTykpOyB0aGVuCiAgICBlY2hvIC1lICIke19fSU5GT19DT0xPUn0ke3R5cGV9ICAgIC0gJHsxfSR7X19SRVNFVF9DT0xPUn0iID4mMgogIGZpCiAgTG9nOjpsb2dJbmZvICIkMSIgIiR7dHlwZX0iCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBDT01NQU5EX0JJTl9ESVIgZW52IHZhciBpcyBzZXQKIyBhbmQgUEFUSCBjb3JyZWN0bHkgcHJlcGFyZWQKIyBAbm9hcmdzCiMgQHNldCBDT01NQU5EX0JJTl9ESVIgc3RyaW5nIHRoZSBkaXJlY3Rvcnkgd2hlcmUgdG8gZmluZCB0aGlzIGNvbW1hbmQKIyBAc2V0IFBBVEggc3RyaW5nIGFkZCBkaXJlY3Rvcnkgd2hlcmUgdG8gZmluZCB0aGlzIGNvbW1hbmQgYmluYXJ5CkNvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyKCkgewogIENPTU1BTkRfQklOX0RJUj0iJHtDVVJSRU5UX0RJUn0iCiAgRW52OjpwYXRoUHJlcGVuZCAiJHtDT01NQU5EX0JJTl9ESVJ9Igp9CgojIEBkZXNjcmlwdGlvbiBjcmVhdGUgYSBuZXcgZGIgaW5zdGFuY2UKIyBSZXR1cm5zIGltbWVkaWF0ZWx5IGlmIHRoZSBpbnN0YW5jZSBpcyBhbHJlYWR5IGluaXRpYWxpemVkCiMKIyBAYXJnICQxIGluc3RhbmNlTmV3SW5zdGFuY2U6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBkc246U3RyaW5nIGRzbiBwcm9maWxlIC0gbG9hZCB0aGUgZHNuLmVudiBwcm9maWxlIGRlZHVjZWQgdXNpbmcgcnVsZXMgZGVmaW5lZCBpbiBDb25mOjpnZXRBYnNvbHV0ZUZpbGUKIwojIEBleGFtcGxlCiMgICBkZWNsYXJlIC1BZ3ggZGJJbnN0YW5jZQojICAgRGF0YWJhc2U6Om5ld0luc3RhbmNlIGRiSW5zdGFuY2UgImRlZmF1bHQubG9jYWwiCiMKIyBAZXhpdGNvZGUgMSBpZiBkbnMgZmlsZSBub3QgYWJsZSB0byBsb2FkZWQKRGF0YWJhc2U6Om5ld0luc3RhbmNlKCkgewogIGxvY2FsIC1uIGluc3RhbmNlTmV3SW5zdGFuY2U9JDEKICBsb2NhbCBkc249IiQyIgogIGxvY2FsIERTTl9GSUxFCgogIGlmIFtbIC12IGluc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ10gJiYgIiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnSU5JVElBTElaRUQnXTotMH0iID09ICIxIiBdXTsgdGhlbgogICAgcmV0dXJuCiAgZmkKCiAgIyBmaW5hbCBhdXRoIGZpbGUgZ2VuZXJhdGVkIGZyb20gZG5zIGZpbGUKICBpbnN0YW5jZU5ld0luc3RhbmNlWydBVVRIX0ZJTEUnXT0iIgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0RTTl9GSUxFJ109IiIKCiAgIyBjaGVjayBkc24gZmlsZQogIERTTl9GSUxFPSIkKENvbmY6OmdldEFic29sdXRlRmlsZSAiZHNuIiAiJHtkc259IiAiZW52IikiIHx8IHJldHVybiAxCiAgRGF0YWJhc2U6OmNoZWNrRHNuRmlsZSAiJHtEU05fRklMRX0iIHx8IHJldHVybiAxCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnRFNOX0ZJTEUnXT0iJHtEU05fRklMRX0iCgogICMgc2hlbGxjaGVjayBzb3VyY2U9L3NyYy9EYXRhYmFzZS90ZXN0c0RhdGEvZHNuX3ZhbGlkLmVudgogIHNvdXJjZSAiJHtpbnN0YW5jZU5ld0luc3RhbmNlWydEU05fRklMRSddfSIKCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnVVNFUiddPSIke1VTRVJ9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1BBU1NXT1JEJ109IiR7UEFTU1dPUkR9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0hPU1ROQU1FJ109IiR7SE9TVE5BTUV9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1BPUlQnXT0iJHtQT1JUfSIKCiAgIyBnZW5lcmF0ZSBhdXRoRmlsZSBmb3IgZWFzeSBhdXRoZW50aWNhdGlvbgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0FVVEhfRklMRSddPSQobWt0ZW1wIC1wICIke1RNUERJUjotL3RtcH0iIC10ICJteXNxbC5YWFhYWFhYWFhYWFgiKQogICgKICAgIGVjaG8gIltjbGllbnRdIgogICAgZWNobyAidXNlciA9ICR7VVNFUn0iCiAgICBlY2hvICJwYXNzd29yZCA9ICR7UEFTU1dPUkR9IgogICAgZWNobyAiaG9zdCA9ICR7SE9TVE5BTUV9IgogICAgZWNobyAicG9ydCA9ICR7UE9SVH0iCiAgKSA+IiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnQVVUSF9GSUxFJ119IgoKICAjIHNvbWUgb2YgdGhvc2UgdmFsdWVzIGNhbiBiZSBvdmVycmlkZGVuIHVzaW5nIHRoZSBkc24gZmlsZQogICMgU0tJUF9DT0xVTU5fTkFNRVMgZW5hYmxlZCBieSBkZWZhdWx0CiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnU0tJUF9DT0xVTU5fTkFNRVMnXT0iJHtTS0lQX0NPTFVNTl9OQU1FUzotMX0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnU1NMX09QVElPTlMnXT0iJHtNWVNRTF9TU0xfT1BUSU9OUzotLS1zc2wtbW9kZT1ESVNBQkxFRH0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnUVVFUllfT1BUSU9OUyddPSIke01ZU1FMX1FVRVJZX09QVElPTlM6LS0tYmF0Y2ggLS1yYXcgLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOH0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnRFVNUF9PUFRJT05TJ109IiR7TVlTUUxfRFVNUF9PUFRJT05TOi0tLWRlZmF1bHQtY2hhcmFjdGVyLXNldD11dGY4IC0tY29tcHJlc3MgLS1oZXgtYmxvYiAtLXJvdXRpbmVzIC0tdHJpZ2dlcnMgLS1zaW5nbGUtdHJhbnNhY3Rpb24gLS1zZXQtZ3RpZC1wdXJnZWQ9T0ZGIC0tY29sdW1uLXN0YXRpc3RpY3M9MCAke2luc3RhbmNlTmV3SW5zdGFuY2VbJ1NTTF9PUFRJT05TJ119fSIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydEQl9JTVBPUlRfT1BUSU9OUyddPSIke0RCX0lNUE9SVF9PUFRJT05TOi0tLWNvbm5lY3QtdGltZW91dD01IC0tYmF0Y2ggLS1yYXcgLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOH0iCgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ109MQp9CgojIEBkZXNjcmlwdGlvbiBteXNxbCBxdWVyeSBvbiBhIGdpdmVuIGRiCiMgQHdhcm5pbmcgY291bGQgdXNlIFFVRVJZX09QVElPTlMgdmFyaWFibGUgZnJvbSBkc24gaWYgZGVmaW5lZAojIEBleGFtcGxlCiMgICBjYXQgZmlsZS5zcWwgfCBEYXRhYmFzZTo6cXVlcnkgLi4uCiMgQGFyZyAkMSBpbnN0YW5jZVF1ZXJ5OiZNYXA8U3RyaW5nLFN0cmluZz4gKHBhc3NlZCBieSByZWZlcmVuY2UpIGRhdGFiYXNlIGluc3RhbmNlIHRvIHVzZQojIEBhcmcgJDIgc3FsUXVlcnk6U3RyaW5nIChvcHRpb25hbCkgc3FsIHF1ZXJ5IG9yIHNxbCBmaWxlIHRvIGV4ZWN1dGUuIGlmIG5vdCBwcm92aWRlZCBvciBlbXB0eSwgdGhlIGNvbW1hbmQgY2FuIGJlIHBpcGVkCiMgQGFyZyAkMyBkYk5hbWU6U3RyaW5nIChvcHRpb25hbCkgdGhlIGRiIG5hbWUKIwojIEBleGl0Y29kZSBteXNxbCBjb21tYW5kIHN0YXR1cyBjb2RlCkRhdGFiYXNlOjpxdWVyeSgpIHsKICBsb2NhbCAtbiBpbnN0YW5jZVF1ZXJ5PSQxCiAgbG9jYWwgLWEgbXlzcWxDb21tYW5kPSgpCiAgbG9jYWwgLWEgcXVlcnlPcHRpb25zCgogIG15c3FsQ29tbWFuZCs9KG15c3FsKQogIG15c3FsQ29tbWFuZCs9KCItLWRlZmF1bHRzLWV4dHJhLWZpbGU9JHtpbnN0YW5jZVF1ZXJ5WydBVVRIX0ZJTEUnXX0iKQogIElGUz0nICcgcmVhZCAtciAtYSBxdWVyeU9wdGlvbnMgPDw8IiR7aW5zdGFuY2VRdWVyeVsnUVVFUllfT1BUSU9OUyddfSIKICBteXNxbENvbW1hbmQrPSgiJHtxdWVyeU9wdGlvbnNbQF19IikKICBpZiBbWyAiJHtpbnN0YW5jZVF1ZXJ5WydTS0lQX0NPTFVNTl9OQU1FUyddfSIgPSAiMSIgXV07IHRoZW4KICAgIG15c3FsQ29tbWFuZCs9KCItcyIgIi0tc2tpcC1jb2x1bW4tbmFtZXMiKQogIGZpCiAgIyBhZGQgb3B0aW9uYWwgZGIgbmFtZQogIGlmIFtbIC1uICIkezMreH0iIF1dOyB0aGVuCiAgICBteXNxbENvbW1hbmQrPSgiJDMiKQogIGZpCiAgIyBhZGQgb3B0aW9uYWwgc3FsIHF1ZXJ5CiAgaWYgW1sgLW4gIiR7Mit4fSIgJiYgLW4gIiQyIiAmJiAhIC1mICIkMiIgXV07IHRoZW4KICAgIG15c3FsQ29tbWFuZCs9KCItZSIpCiAgICBteXNxbENvbW1hbmQrPSgiJDIiKQogIGZpCiAgTG9nOjpkaXNwbGF5RGVidWcgIiQocHJpbnRmICJleGVjdXRlIGNvbW1hbmQ6ICclcyciICIke215c3FsQ29tbWFuZFsqXX0iKSIKCiAgaWYgW1sgLWYgIiQyIiBdXTsgdGhlbgogICAgIiR7bXlzcWxDb21tYW5kW0BdfSIgPCIkMiIKICBlbHNlCiAgICAiJHtteXNxbENvbW1hbmRbQF19IgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIHNldCB0aGUgZ2VuZXJhbCBvcHRpb25zIHRvIHVzZSBvbiBteXNxbCBjb21tYW5kIHRvIHF1ZXJ5IHRoZSBkYXRhYmFzZQojIERpZmZlcnMgdGhhbiBzZXRPcHRpb25zIGluIHRoZSB3YXkgdGhhdCB0aGVzZSBvcHRpb25zIGNvdWxkIGNoYW5nZSBlYWNoIHRpbWUKIwojIEBhcmcgJDEgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBvcHRpb25zTGlzdDpTdHJpbmcgcXVlcnkgb3B0aW9ucyBsaXN0CkRhdGFiYXNlOjpzZXRRdWVyeU9wdGlvbnMoKSB7CiAgbG9jYWwgLW4gaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM9JDEKICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICBpbnN0YW5jZVNldFF1ZXJ5T3B0aW9uc1snUVVFUllfT1BUSU9OUyddPSIkMiIKfQoKIyBAZGVzY3JpcHRpb24gYnkgZGVmYXVsdCB3ZSBza2lwIHRoZSBjb2x1bW4gbmFtZXMKIyBidXQgc29tZXRpbWVzIHdlIG5lZWQgY29sdW1uIG5hbWVzIHRvIGRpc3BsYXkgc29tZSByZXN1bHRzCiMgZGlzYWJsZSB0aGlzIG9wdGlvbiB0ZW1wb3JhcmlseSBhbmQgdGhlbiByZXN0b3JlIGl0IHRvIHRydWUKIwojIEBhcmcgJDEgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnM6Jk1hcDxTdHJpbmcsU3RyaW5nPiAocGFzc2VkIGJ5IHJlZmVyZW5jZSkgZGF0YWJhc2UgaW5zdGFuY2UgdG8gdXNlCiMgQGFyZyAkMiBza2lwQ29sdW1uTmFtZXM6Qm9vbGVhbiAwIHRvIGRpc2FibGUsIDEgdG8gZW5hYmxlIChoaWRlIGNvbHVtbiBuYW1lcykKRGF0YWJhc2U6OnNraXBDb2x1bW5OYW1lcygpIHsKICBsb2NhbCAtbiBpbnN0YW5jZVNraXBDb2x1bW5OYW1lcz0kMQogICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNAogIGluc3RhbmNlU2tpcENvbHVtbk5hbWVzWydTS0lQX0NPTFVNTl9OQU1FUyddPSIkMiIKfQoKIyBAZGVzY3JpcHRpb24gcHJlcGVuZCBkaXJlY3RvcmllcyB0byB0aGUgUEFUSCBlbnZpcm9ubWVudCB2YXJpYWJsZQojIEBhcmcgJEAgYXJnczpTdHJpbmdbXSBsaXN0IG9mIGRpcmVjdG9yaWVzIHRvIHByZXBlbmQKIyBAc2V0IFBBVEggdXBkYXRlIFBBVEggd2l0aCB0aGUgZGlyZWN0b3JpZXMgcHJlcGVuZGVkCkVudjo6cGF0aFByZXBlbmQoKSB7CiAgbG9jYWwgYXJnCiAgZm9yIGFyZyBpbiAiJEAiOyBkbwogICAgaWYgW1sgLWQgIiR7YXJnfSIgJiYgIjoke1BBVEh9OiIgIT0gKiI6JHthcmd9OiIqIF1dOyB0aGVuCiAgICAgIFBBVEg9IiQocmVhbHBhdGggIiR7YXJnfSIpOiR7UEFUSH0iCiAgICBmaQogIGRvbmUKfQoKIyBAZGVzY3JpcHRpb24gRGlzcGxheSBtZXNzYWdlIHVzaW5nIGVycm9yIGNvbG9yIChyZWQpIGFuZCBleGl0IGltbWVkaWF0ZWx5IHdpdGggZXJyb3Igc3RhdHVzIDEKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpmYXRhbCgpIHsKICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RkFUQUwgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBMb2c6OmxvZ0ZhdGFsICIkMSIKICBleGl0IDEKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ0RlYnVnKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID49IF9fTEVWRUxfREVCVUcpKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LURFQlVHfSIgIiQxIgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dJbmZvKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID49IF9fTEVWRUxfSU5GTykpOyB0aGVuCiAgICBMb2c6OmxvZ01lc3NhZ2UgIiR7MjotSU5GT30iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBlbnN1cmUgcnVubmluZyB1c2VyIGlzIG5vdCByb290CiMgQGV4aXRjb2RlIDEgaWYgY3VycmVudCB1c2VyIGlzIHJvb3QKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZApMaW51eDo6cmVxdWlyZUV4ZWN1dGVkQXNVc2VyKCkgewogIGlmIFtbICIkKGlkIC11KSIgPSAiMCIgXV07IHRoZW4KICAgIExvZzo6ZmF0YWwgInRoaXMgc2NyaXB0IHNob3VsZCBiZSBleGVjdXRlZCBhcyBub3JtYWwgdXNlciIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBnZXQgYWJzb2x1dGUgY29uZiBmaWxlIGZyb20gc3BlY2lmaWVkIGNvbmYgZm9sZGVyIGRlZHVjZWQgdXNpbmcgdGhlc2UgcnVsZXMKIyAgICogZnJvbSBhYnNvbHV0ZSBmaWxlIChpZ25vcmVzIDxjb25mRm9sZGVyPiBhbmQgPGV4dGVuc2lvbj4pCiMgICAqIHJlbGF0aXZlIHRvIHdoZXJlIHNjcmlwdCBpcyBleGVjdXRlZCAoaWdub3JlcyA8Y29uZkZvbGRlcj4gYW5kIDxleHRlbnNpb24+KQojICAgKiBmcm9tIGhvbWUvLmJhc2gtdG9vbHMvPGNvbmZGb2xkZXI+CiMgICAqIGZyb20gZnJhbWV3b3JrIGNvbmYvPGNvbmZGb2xkZXI+CiMKIyBAYXJnICQxIGNvbmZGb2xkZXI6U3RyaW5nIHRoZSBkaXJlY3RvcnkgbmFtZSAobm90IHRoZSBwYXRoKSB0byBsaXN0CiMgQGFyZyAkMiBjb25mOlN0cmluZyBmaWxlIHRvIHVzZSB3aXRob3V0IGV4dGVuc2lvbgojIEBhcmcgJDMgZXh0ZW5zaW9uOlN0cmluZyB0aGUgZXh0ZW5zaW9uICguc2ggYnkgZGVmYXVsdCkKIwojIEBzdGRvdXQgYWJzb2x1dGUgY29uZiBmaWxlbmFtZQojIEBleGl0Y29kZSAxIGlmIGZpbGUgaXMgbm90IGZvdW5kIGluIGFueSBsb2NhdGlvbgpDb25mOjpnZXRBYnNvbHV0ZUZpbGUoKSB7CiAgbG9jYWwgY29uZkZvbGRlcj0iJDEiCiAgbG9jYWwgY29uZj0iJDIiCiAgbG9jYWwgZXh0ZW5zaW9uPSIkezMtLnNofSIKICBpZiBbWyAtbiAiJHtleHRlbnNpb259IiAmJiAiJHtleHRlbnNpb246MDoxfSIgIT0gIi4iIF1dOyB0aGVuCiAgICBleHRlbnNpb249Ii4ke2V4dGVuc2lvbn0iCiAgZmkKCiAgdGVzdEFicygpIHsKICAgIGxvY2FsIHJlc3VsdAogICAgcmVzdWx0PSIkKHJlYWxwYXRoIC1lICIkMSIgMj4vZGV2L251bGwpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTgxCiAgICBpZiBbWyAiJD8iID0gIjAiICYmIC1mICIke3Jlc3VsdH0iIF1dOyB0aGVuCiAgICAgIGVjaG8gIiR7cmVzdWx0fSIKICAgICAgcmV0dXJuIDAKICAgIGZpCiAgICByZXR1cm4gMQogIH0KCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pCiAgdGVzdEFicyAiJHtjb25mRm9sZGVyfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICAjIGNvbmYgaXMgYWJzb2x1dGUgZmlsZQogIHRlc3RBYnMgIiR7Y29uZkZvbGRlcn0iICYmIHJldHVybiAwCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUgKGluY2x1ZGluZyBleHRlbnNpb24pCiAgdGVzdEFicyAiJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICAjIGNvbmYgaXMgYWJzb2x1dGUgZmlsZQogIHRlc3RBYnMgIiR7Y29uZn0iICYmIHJldHVybiAwCgogICMgcmVsYXRpdmUgdG8gd2hlcmUgc2NyaXB0IGlzIGV4ZWN1dGVkIChpbmNsdWRpbmcgZXh0ZW5zaW9uKQogIGlmIFtbIC1uICIke0NVUlJFTlRfRElSK3h4eH0iIF1dOyB0aGVuCiAgICB0ZXN0QWJzICIkKEZpbGU6OmNvbmNhdGVuYXRlUGF0aCAiJHtDVVJSRU5UX0RJUn0iICIke2NvbmZGb2xkZXJ9IikvJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKICBmaQogICMgZnJvbSBob21lLy5iYXNoLXRvb2xzLzxjb25mRm9sZGVyPgogIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0hPTUV9Ly5iYXNoLXRvb2xzIiAiJHtjb25mRm9sZGVyfSIpLyR7Y29uZn0ke2V4dGVuc2lvbn0iICYmIHJldHVybiAwCgogIGlmIFtbIC1uICIke0ZSQU1FV09SS19ST09UX0RJUit4eHh9IiBdXTsgdGhlbgogICAgIyBmcm9tIGZyYW1ld29yayBjb25mLzxjb25mRm9sZGVyPiAoaW5jbHVkaW5nIGV4dGVuc2lvbikKICAgIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0ZSQU1FV09SS19ST09UX0RJUn0vY29uZiIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9JHtleHRlbnNpb259IiAmJiByZXR1cm4gMAoKICAgICMgZnJvbSBmcmFtZXdvcmsgY29uZi88Y29uZkZvbGRlcj4KICAgIHRlc3RBYnMgIiQoRmlsZTo6Y29uY2F0ZW5hdGVQYXRoICIke0ZSQU1FV09SS19ST09UX0RJUn0vY29uZiIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9IiAmJiByZXR1cm4gMAogIGZpCgogICMgZmlsZSBub3QgZm91bmQKICBMb2c6OmRpc3BsYXlFcnJvciAiY29uZiBmaWxlICcke2NvbmZ9JyBub3QgZm91bmQiCgogIHJldHVybiAxCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIGRzbiBmaWxlIGhhcyBhbGwgdGhlIG1hbmRhdG9yeSB2YXJpYWJsZXMgc2V0CiMgTWFuZGF0b3J5IHZhcmlhYmxlcyBhcmU6IEhPU1ROQU1FLCBVU0VSLCBQQVNTV09SRCwgUE9SVAojCiMgQGFyZyAkMSBkc25GaWxlTmFtZTpTdHJpbmcgZHNuIGFic29sdXRlIGZpbGVuYW1lCiMgQHNldCBIT1NUTkFNRSBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgUE9SVCBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgVVNFUiBsb2FkZWQgZnJvbSBkc24gZmlsZQojIEBzZXQgUEFTU1dPUkQgbG9hZGVkIGZyb20gZHNuIGZpbGUKIyBAZXhpdGNvZGUgMCBvbiB2YWxpZCBmaWxlCiMgQGV4aXRjb2RlIDEgaWYgb25lIG9mIHRoZSBwcm9wZXJ0aWVzIG9mIHRoZSBjb25mIGZpbGUgaXMgaW52YWxpZCBvciBpZiBmaWxlIG5vdCBmb3VuZAojIEBzdGRlcnIgbG9nIG91dHB1dCBpZiBlcnJvciBmb3VuZCBpbiBjb25mIGZpbGUKRGF0YWJhc2U6OmNoZWNrRHNuRmlsZSgpIHsKICBsb2NhbCBkc25GaWxlTmFtZT0iJDEiCiAgaWYgW1sgISAtZiAiJHtkc25GaWxlTmFtZX0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gbm90IGZvdW5kIgogICAgcmV0dXJuIDEKICBmaQoKICAoCiAgICB1bnNldCBIT1NUTkFNRSBQT1JUIFBBU1NXT1JEIFVTRVIKICAgICMgc2hlbGxjaGVjayBzb3VyY2U9L3NyYy9EYXRhYmFzZS90ZXN0c0RhdGEvZHNuX3ZhbGlkLmVudgogICAgc291cmNlICIke2RzbkZpbGVOYW1lfSIKICAgIGlmIFtbIC16ICR7SE9TVE5BTUUreH0gXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogSE9TVE5BTUUgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke0hPU1ROQU1FfSIgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5V2FybmluZyAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBIT1NUTkFNRSB2YWx1ZSBub3QgcHJvdmlkZWQiCiAgICBmaQogICAgaWYgW1sgIiR7SE9TVE5BTUV9IiA9ICJsb2NhbGhvc3QiIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheVdhcm5pbmcgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogY2hlY2sgdGhhdCBIT1NUTkFNRSBzaG91bGQgbm90IGJlIDEyNy4wLjAuMSBpbnN0ZWFkIG9mIGxvY2FsaG9zdCIKICAgIGZpCiAgICBpZiBbWyAteiAiJHtQT1JUK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBQT1JUIG5vdCBwcm92aWRlZCIKICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBpZiAhIFtbICR7UE9SVH0gPX4gXlswLTldKyQgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogUE9SVCBpbnZhbGlkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke1VTRVIreH0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJkc24gZmlsZSAke2RzbkZpbGVOYW1lfSA6IFVTRVIgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICAgIGlmIFtbIC16ICIke1BBU1NXT1JEK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBQQVNTV09SRCBub3QgcHJvdmlkZWQiCiAgICAgIHJldHVybiAxCiAgICBmaQogICkKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ0ZhdGFsKCkgewogIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1GQVRBTH0iICIkMSIKfQoKIyBAZGVzY3JpcHRpb24gSW50ZXJuYWw6IGNvbW1vbiBsb2cgbWVzc2FnZQojIEBleGFtcGxlIHRleHQKIyAgIFtkYXRlXXxbbGV2ZWxNc2ddfG1lc3NhZ2UKIwojIEBleGFtcGxlIHRleHQKIyAgIDIwMjAtMDEtMTkgMTk6MjA6MjF8RVJST1IgIHxsb2cgZXJyb3IKIyAgIDIwMjAtMDEtMTkgMTk6MjA6MjF8U0tJUFBFRHxsb2cgc2tpcHBlZAojCiMgQGFyZyAkMSBsZXZlbE1zZzpTdHJpbmcgbWVzc2FnZSdzIGxldmVsIGRlc2NyaXB0aW9uIChlZzogU1RBVFVTLCBFUlJPUiwgLi4uKQojIEBhcmcgJDIgbXNnOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfRklMRSBTdHJpbmcgbG9nIGZpbGUgdG8gdXNlLCBkbyBub3RoaW5nIGlmIGVtcHR5CiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgaW50IGxvZyBsZXZlbCBsb2cgb25seSBpZiA+IE9GRiBvciBmYXRhbCBtZXNzYWdlcwojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gaXMgZGlzcGxheWVkCiMgQHJlcXVpcmUgRW52OjpyZXF1aXJlTG9hZAojIEByZXF1aXJlIExvZzo6cmVxdWlyZUxvYWQKTG9nOjpsb2dNZXNzYWdlKCkgewogIGxvY2FsIGxldmVsTXNnPSIkMSIKICBsb2NhbCBtc2c9IiQyIgogIGxvY2FsIGRhdGUKCiAgaWYgW1sgLW4gIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXSAmJiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+IF9fTEVWRUxfT0ZGKSk7IHRoZW4KICAgIGRhdGU9IiQoZGF0ZSAnKyVZLSVtLSVkICVIOiVNOiVTJykiCiAgICB0b3VjaCAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iCiAgICBwcmludGYgIiVzfCU3c3wlc1xuIiAiJHtkYXRlfSIgIiR7bGV2ZWxNc2d9IiAiJHttc2d9IiA+PiIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBjb25jYXRlbmF0ZSAyIHBhdGhzIGFuZCBlbnN1cmUgdGhlIHBhdGggaXMgY29ycmVjdCB1c2luZyByZWFscGF0aCAtbQojIEBhcmcgJDEgYmFzZVBhdGg6U3RyaW5nCiMgQGFyZyAkMiBzdWJQYXRoOlN0cmluZwojIEByZXF1aXJlIExpbnV4OjpyZXF1aXJlUmVhbHBhdGhDb21tYW5kCkZpbGU6OmNvbmNhdGVuYXRlUGF0aCgpIHsKICBsb2NhbCBiYXNlUGF0aD0iJDEiCiAgbG9jYWwgc3ViUGF0aD0iJDIiCiAgbG9jYWwgZnVsbFBhdGg9IiR7YmFzZVBhdGg6KyR7YmFzZVBhdGh9L30ke3N1YlBhdGh9IgoKICByZWFscGF0aCAtbSAiJHtmdWxsUGF0aH0iIDI+L2Rldi9udWxsCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBlcnJvciBjb2xvciAocmVkKQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlFcnJvcigpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUwgPj0gX19MRVZFTF9FUlJPUikpOyB0aGVuCiAgICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RVJST1IgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nRXJyb3IgIiQxIgp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgd2FybmluZyBjb2xvciAoeWVsbG93KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlXYXJuaW5nKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX1dBUk5JTkcpKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX1dBUk5JTkdfQ09MT1J9V0FSTiAgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nV2FybmluZyAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBlbnYgZmlsZXMgYXJlIGxvYWRlZAojIEBub2FyZ3MKIyBAZXhpdGNvZGUgMSBpZiBnZXRPcmRlcmVkQ29uZkZpbGVzIGZhaWxzCiMgQGV4aXRjb2RlIDIgaWYgb25lIG9mIGVudiBmaWxlcyBmYWlscyB0byBsb2FkCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKRW52OjpyZXF1aXJlTG9hZCgpIHsKICBsb2NhbCBjb25maWdGaWxlc1N0cgogIGNvbmZpZ0ZpbGVzU3RyPSIkKEVudjo6Z2V0T3JkZXJlZENvbmZGaWxlcykiIHx8IHJldHVybiAxCgogIGxvY2FsIC1hIGNvbmZpZ0ZpbGVzCiAgcmVhZGFycmF5IC10IGNvbmZpZ0ZpbGVzIDw8PCIke2NvbmZpZ0ZpbGVzU3RyfSIKCiAgIyBpZiBlbXB0eSBzdHJpbmcsIHRoZXJlIHdpbGwgYmUgb25lIGVsZW1lbnQKICBpZiAoKCR7I2NvbmZpZ0ZpbGVzW0BdfSA9PSAwKSkgfHwgW1sgLXogIiR7Y29uZmlnRmlsZXNTdHJ9IiBdXTsgdGhlbgogICAgIyBzaG91bGQgbm90IGhhcHBlbiwgYXMgdGhlcmUgaXMgYWx3YXlzIGRlZmF1bHQgZmlsZQogICAgTG9nOjpkaXNwbGF5U2tpcHBlZCAibm8gZW52IGZpbGUgdG8gbG9hZCIKICAgIHJldHVybiAwCiAgZmkKCiAgRW52OjptZXJnZUNvbmZGaWxlcyAiJHtjb25maWdGaWxlc1tAXX0iIHx8IHsKICAgIExvZzo6ZGlzcGxheUVycm9yICJ3aGlsZSBsb2FkaW5nIGNvbmZpZyBmaWxlczogJHtjb25maWdGaWxlc1sqXX0iCiAgICByZXR1cm4gMgogIH0KfQoKIyBAZGVzY3JpcHRpb24gYWN0aXZhdGUgb3Igbm90IExvZzo6ZGlzcGxheSogYW5kIExvZzo6bG9nKiBmdW5jdGlvbnMKIyBiYXNlZCBvbiBCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMIGFuZCBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwKIyBlbnZpcm9ubWVudCB2YXJpYWJsZXMgbG9hZGVkIGJ5IEVudjo6cmVxdWlyZUxvYWQKIyB0cnkgdG8gY3JlYXRlIGxvZyBmaWxlIGFuZCByb3RhdGUgaXQgaWYgbmVjZXNzYXJ5CiMgQG5vYXJncwojIEBzZXQgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludCB0byBPRkYgbGV2ZWwgaWYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgaXMgZW1wdHkgb3Igbm90IHdyaXRhYmxlCiMgQGVudiBCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMIGludAojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludAojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgU3RyaW5nCiMgQGVudiBCQVNIX0ZSQU1FV09SS19MT0dfRklMRV9NQVhfUk9UQVRJT04gaW50IGRvIGxvZyByb3RhdGlvbiBpZiA+IDAKIyBAZXhpdGNvZGUgMCBhbHdheXMgc3VjY2Vzc2Z1bAojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gYWJvdXQgbG9nIGZpbGUgaXMgZGlzcGxheWVkCiMgQHJlcXVpcmUgRW52OjpyZXF1aXJlTG9hZAojIEByZXF1aXJlIFVJOjpyZXF1aXJlVGhlbWUKTG9nOjpyZXF1aXJlTG9hZCgpIHsKICBpZiBbWyAteiAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRTotfSIgXV07IHRoZW4KICAgIEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTD0ke19fTEVWRUxfT0ZGfQogICAgZXhwb3J0IEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTAogIGZpCgogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID4gX19MRVZFTF9PRkYpKTsgdGhlbgogICAgaWYgW1sgISAtZiAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iIF1dOyB0aGVuCiAgICAgIGlmCiAgICAgICAgISBta2RpciAtcCAiJChkaXJuYW1lICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIpIiAyPi9kZXYvbnVsbCB8fAogICAgICAgICAgISB0b3VjaCAtLW5vLWNyZWF0ZSAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iIDI+L2Rldi9udWxsCiAgICAgIHRoZW4KICAgICAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgICAgICBlY2hvIC1lICIke19fRVJST1JfQ09MT1J9RVJST1IgICAtIEZpbGUgJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0gaXMgbm90IHdyaXRhYmxlJHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgICAgIGZpCiAgICBlbGlmIFtbICEgLXcgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXTsgdGhlbgogICAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgICAgZWNobyAtZSAiJHtfX0VSUk9SX0NPTE9SfUVSUk9SICAgLSBGaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IGlzIG5vdCB3cml0YWJsZSR7X19SRVNFVF9DT0xPUn0iID4mMgogICAgZmkKCiAgZmkKCiAgaWYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPiBfX0xFVkVMX09GRikpOyB0aGVuCiAgICAjIHdpbGwgYWx3YXlzIGJlIGNyZWF0ZWQgZXZlbiBpZiBub3QgaW4gaW5mbyBsZXZlbAogICAgTG9nOjpsb2dNZXNzYWdlICJJTkZPIiAiTG9nZ2luZyB0byBmaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IC0gTG9nIGxldmVsICR7QkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMfSIKICAgIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OID4gMCkpOyB0aGVuCiAgICAgIExvZzo6cm90YXRlICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OfSIKICAgIGZpCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZ2V0IGxpc3Qgb2YgZW52IGZpbGVzIHRvIGxvYWQKIyBpbiBvcmRlciB0byBtYWtlIHRoZW0gYXZhaWxhYmxlIGZvciBFbnY6OnJlcXVpcmVMb2FkCiMgQGVudiBCQVNIX0ZSQU1FV09SS19FTlZfRklMRVMgU3RyaW5nW10gbGlzdCBvZiBlbnYgZmlsZXMgdGhhdCBzaG91bGQgYmUgbG9hZGVkCiMgQGV4aXRjb2RlIDEgaWYgb25lIG9mIHRoZSBlbnYgZmlsZSBjYW5ub3QgYmUgZ2VuZXJhdGVkCiMgQGV4aXRjb2RlIDIgaWYgb25lIG9mIHRoZSBlbnYgZmlsZSBpcyBub3QgYSBmaWxlIG9yIHJlYWRhYmxlCiMgQHN0ZG91dCB0aGUgZW52IGZpbGVzIGFza2VkIHRvIGJlIGxvYWRlZAojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiBvbiBmYWlsdXJlCiMgQHNlZSBodHRwczovL2dpdGh1Yi5jb20vZmNoYXN0YW5ldC9iYXNoLXRvb2xzLWZyYW1ld29yay9ibG9iL21hc3Rlci9GcmFtZXdvcmtEb2MubWQjY29uZmlnX2ZpbGVfb3JkZXIKRW52OjpnZXRPcmRlcmVkQ29uZkZpbGVzKCkgewogIGxvY2FsIC1hIGNvbmZpZ0ZpbGVzPSgpCgogIGlmIFtbIC1uICIke0JBU0hfRlJBTUVXT1JLX0VOVl9GSUxFU1swXSsxfSIgXV07IHRoZW4KICAgICMgQkFTSF9GUkFNRVdPUktfRU5WX0ZJTEVTIGlzIGFuIGFycmF5CiAgICBjb25maWdGaWxlcys9KCIke0JBU0hfRlJBTUVXT1JLX0VOVl9GSUxFU1tAXX0iKQogIGZpCgogIGxvY2FsIGRlZmF1bHRFbnZGaWxlCiAgZGVmYXVsdEVudkZpbGU9IiQoRW52OjpjcmVhdGVEZWZhdWx0RW52RmlsZSkiIHx8IHJldHVybiAxCiAgY29uZmlnRmlsZXMrPSgiJHtkZWZhdWx0RW52RmlsZX0iKQoKICBsb2NhbCBmaWxlCiAgZm9yIGZpbGUgaW4gIiR7Y29uZmlnRmlsZXNbQF19IjsgZG8KICAgIGlmIFtbICEgLWYgIiR7ZmlsZX0iIHx8ICEgLXIgIiR7ZmlsZX0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJPbmUgb2YgdGhlIGNvbmZpZyBmaWxlIGlzIG5vdCBhdmFpbGFibGUgJyR7ZmlsZX0nIgogICAgICByZXR1cm4gMgogICAgZmkKICAgIGVjaG8gIiR7ZmlsZX0iCiAgZG9uZQp9CgojIEBkZXNjcmlwdGlvbiBtZXJnZSBhbmQgbG9hZCBjb25mIGZpbGVzIHNwZWNpZmllZCBhcyBhcmd1bWVudAojIC0gZmlsZXMgYXJlIGNsZWFuZWQgZnJvbSBheSBjb21tZW50CiMgLSBtaXNzaW5nIHF1b3RlcyBhZnRlciBwcm9wZXJ0eSA9IHNpZ24gYXJlIGFkZGVkIGF1dG9tYXRpY2FsbHkKIyAtIGF1dG9tYXRpYyByZW1vdmUgb2YgYWxsIHdoaXRlc3BhY2UgYmVmb3JlIGFuZCBhZnRlciBkZWNsYXJhdGlvbnMKIyAtIGJhc2ggYXJyYXlzIGFyZSBub3Qgc3VwcG9ydGVkCiMgLSBpZiBhIHZhcmlhYmxlIGlzIGRlY2xhcmVkIGluIGZpcnN0IGZpbGUgYW5kIG92ZXJyaWRkZW4gbGF0ZXIgb24KIyAgIGluIHRoZSBzYW1lIGZpbGUgb3IgaW4gc3Vic2VxdWVudCBmaWxlcywgdGhvc2Ugb3ZlcmxvYWRzIHdpbGwgYmUKIyAgIGlnbm9yZWQKIyBAd2FybmluZyBpZiBhbiBlcnJvciBvY2N1cnMgd2hpbGUgbG9hZGluZyBvbmUgb2YgdGhlIGNvbmZpZyBmaWxlLCBleGl0IGNvZGUgMyBidXQgZW52aXJvbm1lbnQgY291bGQgYmUgcGFydGlhbGx5IGxvYWRlZAojIEBhcmcgJEAgYXJnczpTdHJpbmdbXSBsaXN0IG9mIGNvbmZpZ3VyYXRpb24gZmlsZXMgdG8gbG9hZCBpbiBvcmRlcgojIEBzZXQgZW52VmFycyBTdHJpbmcgd2lsbCBzZXQgaW4gZW52aXJvbm1lbnQgYWxsIHRoZSB2YXJpYWJsZXMgdGhhdCBoYXZlIGJlZW4gZGVjbGFyZWQgaW4gdGhlIGNvbmZpZyBmaWxlcwojIEBlbnYgZW52VmFycyBTdHJpbmcgdGhlIGVudiB2YXJpYWJsZXMgb2YgdGhlIGN1cnJlbnQgc2NyaXB0IGNvdWxkIGJlIHVzZWQgdG8gaW50ZXJwcmV0IHZhcmlhYmxlcyBkdXJpbmcgY29uZmlnIGZpbGVzIHBhcnNpbmcKIyBAZXhpdGNvZGUgMCBpZiBubyBjb25maWcgZmlsZXMgcHJvdmlkZWQgb3IgbG9hZCBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5CiMgQGV4aXRjb2RlIDEgaWYgZXJyb3Igb2NjdXJyZWQgZHVyaW5nIHBhcnNpbmcgdGhlIGNvbmZpZyBmaWxlcyAoZmlsZSBub3QgZm91bmQsIGdyZXAsIGF3ayBvciBzZWQgZXJyb3IpCiMgQGV4aXRjb2RlIDIgaWYgdGVtcG9yYXJ5IGZpbGUgY2Fubm90IGJlIGNyZWF0ZWQKIyBAZXhpdGNvZGUgMyBpZiBhbiBlcnJvciBvY2N1cnJlZCBkdXJpbmcgY29uZmlnIGZpbGUgc291cmNpbmcKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZAojIEBzZWUgbGFyZ2VseSBpbnNwaXJlZCBidXQgbW9kaWZpZWQgZnJvbSBodHRwczovL29wZW5zb3VyY2UuY29tL2FydGljbGUvMjEvNS9wcm9jZXNzaW5nLWNvbmZpZ3VyYXRpb24tZmlsZXMtc2hlbGwKRW52OjptZXJnZUNvbmZGaWxlcygpIHsKICBsb2NhbCAtYSBjb25maWdGaWxlTGlzdD0oIiRAIikKCiAgaWYgKCgkeyNjb25maWdGaWxlTGlzdFtAXX0gPT0gMCkpOyB0aGVuCiAgICByZXR1cm4gMAogIGZpCgogIGxvY2FsIGNvbWJpbmVkQ29uZmlnRmlsZQogIGNvbWJpbmVkQ29uZmlnRmlsZT0iJChGcmFtZXdvcms6OmNyZWF0ZVRlbXBGaWxlICJtZXJnZUNvbmZGaWxlcyIpIiB8fCByZXR1cm4gMgoKICAoCiAgICAjIHJlbW92ZXMgYW55IHRyYWlsaW5nIHdoaXRlc3BhY2UgZnJvbSBlYWNoIGZpbGUsIGlmIGFueQogICAgIyB0aGlzIGlzIGFic29sdXRlbHkgcmVxdWlyZWQgd2hlbiBpbXBvcnRpbmcgaW50byBDb25maWdNYXBzCiAgICAjIHB1dCBxdW90ZXMgYXJvdW5kIHZhbHVlcwogICAgc2VkIC1FIC1lICQncy9ccyokLy8gOyAvXiQvZCA7IC9eIy4qJC9kIDsgcy89KFteIlwnXS4qKSQvPSJcXDEiLycgIiR7Y29uZmlnRmlsZUxpc3RbQF19IiB8CiAgICAgICMgcmVtb3ZlIGFsbCBjb21tZW50IGxpbmVzCiAgICAgIEZpbHRlcnM6OmNvbW1lbnRMaW5lcyB8CiAgICAgICMgaXRlcmF0ZXMgb3ZlciBlYWNoIGZpbGUgYW5kIHByaW50cyAoZGVmYXVsdCBhd2sgYmVoYXZpb3IpCiAgICAgICMgZWFjaCB1bmlxdWUgbGluZTsgb25seSB0YWtlcyBmaXJzdCB2YWx1ZSBhbmQgaWdub3JlcyBkdXBsaWNhdGVzCiAgICAgIGF3ayAtRj0gJyFsaW5lWyQxXSsrJwogICkgPiIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAxCgogICMgaGF2ZSB0byBleHBvcnQgZXZlcnl0aGluZywgYW5kIHNvdXJjZSBpdCB0d2ljZToKICAjIDEpIGZpcnN0IHNvdXJjZSBpcyB0byByZWFsaXplIHZhcmlhYmxlcwogICMgMikgc2Vjb25kIHRpbWUgaXMgdG8gcmVhbGl6ZSByZWZlcmVuY2VzCiAgc2V0IC1vIGFsbGV4cG9ydAogICMgc2hlbGxjaGVjayBzb3VyY2U9LmZyYW1ld29yay1jb25maWcKICBzb3VyY2UgIiR7Y29tYmluZWRDb25maWdGaWxlfSIgfHwgcmV0dXJuIDMKICAjIHNoZWxsY2hlY2sgc291cmNlPS5mcmFtZXdvcmstY29uZmlnCiAgc291cmNlICIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAzCiAgc2V0ICtvIGFsbGV4cG9ydAp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgc2tpcCBjb2xvciAoeWVsbG93KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlTa2lwcGVkKCkgewogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX1NLSVBQRURfQ09MT1J9U0tJUFBFRCAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nU2tpcHBlZCAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dFcnJvcigpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0VSUk9SKSk7IHRoZW4KICAgIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1FUlJPUn0iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nV2FybmluZygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX1dBUk5JTkcpKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LVdBUk5JTkd9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gVG8gYmUgY2FsbGVkIGJlZm9yZSBsb2dnaW5nIGluIHRoZSBsb2cgZmlsZQojIEBhcmcgJDEgZmlsZTpzdHJpbmcgbG9nIGZpbGUgbmFtZQojIEBhcmcgJDIgbWF4TG9nRmlsZXNDb3VudDppbnQgbWF4aW11bSBudW1iZXIgb2YgbG9nIGZpbGVzCkxvZzo6cm90YXRlKCkgewogIGxvY2FsIGZpbGU9IiQxIgogIGxvY2FsIG1heExvZ0ZpbGVzQ291bnQ9IiR7MjotNX0iCgogIGlmIFtbICEgLWYgIiR7ZmlsZX0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlTa2lwcGVkICJMb2cgZmlsZSAke2ZpbGV9IGRvZXNuJ3QgZXhpc3QgeWV0IgogICAgcmV0dXJuIDAKICBmaQogIGZvciBpIGluICQoc2VxICQoKG1heExvZ0ZpbGVzQ291bnQgLSAxKSkgLTEgMSk7IGRvCiAgICBMb2c6OmRpc3BsYXlJbmZvICJMb2cgcm90YXRpb24gJHtmaWxlfS4ke2l9IHRvICR7ZmlsZX0uJCgoaSArIDEpKSIKICAgIG12ICIke2ZpbGV9LiJ7IiR7aX0iLCIkKChpICsgMSkpIn0gJj4vZGV2L251bGwgfHwgdHJ1ZQogIGRvbmUKICBpZiBjcCAiJHtmaWxlfSIgIiR7ZmlsZX0uMSIgJj4vZGV2L251bGw7IHRoZW4KICAgIGVjaG8gPiIke2ZpbGV9IiAjIHJlc2V0IGxvZyBmaWxlCiAgICBMb2c6OmRpc3BsYXlJbmZvICJMb2cgcm90YXRpb24gJHtmaWxlfSB0byAke2ZpbGV9LjEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZW5zdXJlIGNvbW1hbmQgcmVhbHBhdGggaXMgYXZhaWxhYmxlCiMgQGV4aXRjb2RlIDEgaWYgcmVhbHBhdGggY29tbWFuZCBub3QgYXZhaWxhYmxlCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKTGludXg6OnJlcXVpcmVSZWFscGF0aENvbW1hbmQoKSB7CiAgQXNzZXJ0Ojpjb21tYW5kRXhpc3RzIHJlYWxwYXRoCn0KCiMgQGRlc2NyaXB0aW9uIGxvYWQgY29sb3IgdGhlbWUKIyBAbm9hcmdzCiMgQGVudiBCQVNIX0ZSQU1FV09SS19USEVNRSBTdHJpbmcgdGhlbWUgdG8gdXNlCiMgQGV4aXRjb2RlIDAgYWx3YXlzIHN1Y2Nlc3NmdWwKVUk6OnJlcXVpcmVUaGVtZSgpIHsKICBVSTo6dGhlbWUgIiR7QkFTSF9GUkFNRVdPUktfVEhFTUUtZGVmYXVsdH0iCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIGNvbW1hbmQgc3BlY2lmaWVkIGV4aXN0cyBvciByZXR1cm4gMQojIHdpdGggZXJyb3IgYW5kIG1lc3NhZ2UgaWYgbm90CiMKIyBAYXJnICQxIGNvbW1hbmROYW1lOlN0cmluZyBvbiB3aGljaCBleGlzdGVuY2UgbXVzdCBiZSBjaGVja2VkCiMgQGFyZyAkMiBoZWxwSWZOb3RFeGlzdHM6U3RyaW5nIGEgaGVscCBjb21tYW5kIHRvIGRpc3BsYXkgaWYgdGhlIGNvbW1hbmQgZG9lcyBub3QgZXhpc3QKIwojIEBleGl0Y29kZSAxIGlmIHRoZSBjb21tYW5kIHNwZWNpZmllZCBkb2VzIG5vdCBleGlzdAojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiArIGhlbHAgaWYgc2Vjb25kIGFyZ3VtZW50IGlzIHByb3ZpZGVkCkFzc2VydDo6Y29tbWFuZEV4aXN0cygpIHsKICBsb2NhbCBjb21tYW5kTmFtZT0iJDEiCiAgbG9jYWwgaGVscElmTm90RXhpc3RzPSIkMiIKCiAgIiR7QkFTSF9GUkFNRVdPUktfQ09NTUFORDotY29tbWFuZH0iIC12ICIke2NvbW1hbmROYW1lfSIgPi9kZXYvbnVsbCAyPi9kZXYvbnVsbCB8fCB7CiAgICBMb2c6OmRpc3BsYXlFcnJvciAiJHtjb21tYW5kTmFtZX0gaXMgbm90IGluc3RhbGxlZCwgcGxlYXNlIGluc3RhbGwgaXQiCiAgICBpZiBbWyAtbiAiJHtoZWxwSWZOb3RFeGlzdHN9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlJbmZvICIke2hlbHBJZk5vdEV4aXN0c30iCiAgICBmaQogICAgcmV0dXJuIDEKICB9CiAgcmV0dXJuIDAKfQoKIyBAZGVzY3JpcHRpb24gZGVmYXVsdCBlbnYgZmlsZSB3aXRoIGFsbCBkZWZhdWx0IHZhbHVlcwojIEBzdGRvdXQgdGhlIGRlZmF1bHQgZW52IGZpbGVwYXRoCkVudjo6Y3JlYXRlRGVmYXVsdEVudkZpbGUoKSB7CiAgbG9jYWwgZW52RmlsZQogIGVudkZpbGU9IiQoRnJhbWV3b3JrOjpjcmVhdGVUZW1wRmlsZSAiY3JlYXRlRGVmYXVsdEVudkZpbGVFbnZGaWxlIikiIHx8IHJldHVybiAyCgogICgKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX1RIRU1FPSR7QkFTSF9GUkFNRVdPUktfVEhFTUU6LWRlZmF1bHR9IgogICAgZWNobyAiQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMPSR7QkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMOi0wfSIKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUw9JHtCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMOi0ke19fTEVWRUxfV0FSTklOR319IgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDE2CiAgICBlY2hvICdCQVNIX0ZSQU1FV09SS19MT0dfRklMRT0iJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRTotIiR7RlJBTUVXT1JLX1JPT1RfRElSfS9sb2dzLyR7U0NSSVBUX05BTUV9LmxvZyJ9IicKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTj0ke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTjotNX0iCiAgKSA+IiR7ZW52RmlsZX0iCiAgZWNobyAiJHtlbnZGaWxlfSIKfQoKIyBAZGVzY3JpcHRpb24gcmVtb3ZlIGNvbW1lbnQgbGluZXMgZnJvbSBpbnB1dCBvciBmaWxlcyBwcm92aWRlZCBhcyBhcmd1bWVudHMKIyBAYXJnICRAIGZpbGVzOlN0cmluZ1tdIChvcHRpb25hbCkgdGhlIGZpbGVzIHRvIGZpbHRlcgojIEBlbnYgY29tbWVudExpbmVQcmVmaXggU3RyaW5nIHRoZSBjb21tZW50IGxpbmUgcHJlZml4IChkZWZhdWx0IHZhbHVlOiAjKQojIEBleGl0Y29kZSAwIGlmIGxpbmVzIGZpbHRlcmVkIG9yIG5vdAojIEBleGl0Y29kZSAyIGlmIGdyZXAgZmFpbHMgZm9yIGFueSBvdGhlciByZWFzb25zIHRoYW4gbm90IGZvdW5kCiMgQHN0ZGluIHRoZSBmaWxlIGFzIHN0ZGluIHRvIGZpbHRlciAoYWx0ZXJuYXRpdmUgdG8gZmlsZXMgYXJndW1lbnQpCiMgQHN0ZG91dCB0aGUgZmlsdGVyZWQgbGluZXMKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTIwCkZpbHRlcnM6OmNvbW1lbnRMaW5lcygpIHsKICBncmVwIC12eEUgIltbOmJsYW5rOl1dKigke2NvbW1lbnRMaW5lUHJlZml4Oi0jfS4qKT8iICIkQCIgfHwgdGVzdCAkPyA9IDEKfQoKIyBAZGVzY3JpcHRpb24gY3JlYXRlIGEgdGVtcCBmaWxlIHVzaW5nIGRlZmF1bHQgVE1QRElSIHZhcmlhYmxlCiMgaW5pdGlhbGl6ZWQgaW4gX2luY2x1ZGVzL19jb21tb25IZWFkZXIuc2gKIyBAZW52IFRNUERJUiBTdHJpbmcgKGRlZmF1bHQgdmFsdWUgL3RtcCkKIyBAYXJnICQxIHRlbXBsYXRlTmFtZTpTdHJpbmcgdGVtcGxhdGUgbmFtZSB0byB1c2Uob3B0aW9uYWwpCkZyYW1ld29yazo6Y3JlYXRlVGVtcEZpbGUoKSB7CiAgbWt0ZW1wIC1wICIke1RNUERJUjotL3RtcH0iIC10ICIkezE6LX0uWFhYWFhYWFhYWFhYIgp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nU2tpcHBlZCgpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LVNLSVBQRUR9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gbG9hZCBjb2xvcnMgdGhlbWUgY29uc3RhbnRzCiMgQHdhcm5pbmcgaWYgdHR5IG5vdCBvcGVuZWQsIG5vQ29sb3IgdGhlbWUgd2lsbCBiZSBjaG9zZW4KIyBAYXJnICQxIHRoZW1lOlN0cmluZyB0aGUgdGhlbWUgdG8gdXNlIChkZWZhdWx0LCBub0NvbG9yKQojIEBhcmcgJEAgYXJnczpTdHJpbmdbXQojIEBzZXQgX19FUlJPUl9DT0xPUiBTdHJpbmcgaW5kaWNhdGUgZXJyb3Igc3RhdHVzCiMgQHNldCBfX0lORk9fQ09MT1IgU3RyaW5nIGluZGljYXRlIGluZm8gc3RhdHVzCiMgQHNldCBfX1NVQ0NFU1NfQ09MT1IgU3RyaW5nIGluZGljYXRlIHN1Y2Nlc3Mgc3RhdHVzCiMgQHNldCBfX1dBUk5JTkdfQ09MT1IgU3RyaW5nIGluZGljYXRlIHdhcm5pbmcgc3RhdHVzCiMgQHNldCBfX1NLSVBQRURfQ09MT1IgU3RyaW5nIGluZGljYXRlIHNraXBwZWQgc3RhdHVzCiMgQHNldCBfX0RFQlVHX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSBkZWJ1ZyBzdGF0dXMKIyBAc2V0IF9fSEVMUF9DT0xPUiBTdHJpbmcgaW5kaWNhdGUgaGVscCBzdGF0dXMKIyBAc2V0IF9fVEVTVF9DT0xPUiBTdHJpbmcgbm90IHVzZWQKIyBAc2V0IF9fVEVTVF9FUlJPUl9DT0xPUiBTdHJpbmcgbm90IHVzZWQKIyBAc2V0IF9fSEVMUF9USVRMRV9DT0xPUiBTdHJpbmcgdXNlZCB0byBkaXNwbGF5IGhlbHAgdGl0bGUgaW4gaGVscCBzdHJpbmdzCiMgQHNldCBfX0hFTFBfT1BUSU9OX0NPTE9SIFN0cmluZyB1c2VkIHRvIGRpc3BsYXkgaGlnaGxpZ2h0IG9wdGlvbnMgaW4gaGVscCBzdHJpbmdzCiMKIyBAc2V0IF9fUkVTRVRfQ09MT1IgU3RyaW5nIHJlc2V0IGRlZmF1bHQgY29sb3IKIwojIEBzZXQgX19IRUxQX0VYQU1QTEUgU3RyaW5nIHRvIHJlbW92ZQojIEBzZXQgX19IRUxQX1RJVExFIFN0cmluZyB0byByZW1vdmUKIyBAc2V0IF9fSEVMUF9OT1JNQUwgU3RyaW5nIHRvIHJlbW92ZQojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKVUk6OnRoZW1lKCkgewogIGxvY2FsIHRoZW1lPSIkezEtZGVmYXVsdH0iCiAgaWYgW1sgISAiJHt0aGVtZX0iID1+IC1mb3JjZSQgXV0gJiYgISBBc3NlcnQ6OnR0eTsgdGhlbgogICAgdGhlbWU9Im5vQ29sb3IiCiAgZmkKICBjYXNlICIke3RoZW1lfSIgaW4KICAgIGRlZmF1bHQgfCBkZWZhdWx0LWZvcmNlKQogICAgICB0aGVtZT0iZGVmYXVsdCIKICAgICAgOzsKICAgIG5vQ29sb3IpIDs7CiAgICAqKQogICAgICBMb2c6OmZhdGFsICJpbnZhbGlkIHRoZW1lIHByb3ZpZGVkIgogICAgICA7OwogIGVzYWMKICBpZiBbWyAiJHt0aGVtZX0iID0gImRlZmF1bHQiIF1dOyB0aGVuCiAgICBCQVNIX0ZSQU1FV09SS19USEVNRT0iZGVmYXVsdCIKICAgICMgY2hlY2sgY29sb3JzIGFwcGxpY2FibGUgaHR0cHM6Ly9taXNjLmZsb2dpc29mdC5jb20vYmFzaC90aXBfY29sb3JzX2FuZF9mb3JtYXR0aW5nCiAgICBfX0VSUk9SX0NPTE9SPSdcZVszMW0nICAgICAgICAgIyBSZWQKICAgIF9fSU5GT19DT0xPUj0nXGVbNDRtJyAgICAgICAgICAjIHdoaXRlIG9uIGxpZ2h0Qmx1ZQogICAgX19TVUNDRVNTX0NPTE9SPSdcZVszMm0nICAgICAgICMgR3JlZW4KICAgIF9fV0FSTklOR19DT0xPUj0nXGVbMzNtJyAgICAgICAjIFllbGxvdwogICAgX19TS0lQUEVEX0NPTE9SPSdcZVszM20nICAgICAgICMgWWVsbG93CiAgICBfX0RFQlVHX0NPTE9SPSdcZVszN20nICAgICAgICAgIyBHcmV5CiAgICBfX0hFTFBfQ09MT1I9J1xlWzc7NDk7MzNtJyAgICAgIyBCbGFjayBvbiBHb2xkCiAgICBfX1RFU1RfQ09MT1I9J1xlWzEwMG0nICAgICAgICAgIyBMaWdodCBtYWdlbnRhCiAgICBfX1RFU1RfRVJST1JfQ09MT1I9J1xlWzQxbScgICAgIyB3aGl0ZSBvbiByZWQKICAgIF9fSEVMUF9USVRMRV9DT0xPUj0iXGVbMTszN20iICAjIEJvbGQKICAgIF9fSEVMUF9PUFRJT05fQ09MT1I9IlxlWzE7MzRtIiAjIEJsdWUKICAgICMgSW50ZXJuYWw6IHJlc2V0IGNvbG9yCiAgICBfX1JFU0VUX0NPTE9SPSdcZVswbScgIyBSZXNldCBDb2xvcgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU1LFNDMjAzNAogICAgX19IRUxQX0VYQU1QTEU9IiQoZWNobyAtZSAiXGVbMjs5N20iKSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE1NSxTQzIwMzQKICAgIF9fSEVMUF9USVRMRT0iJChlY2hvIC1lICJcZVsxOzM3bSIpIgogICAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU1LFNDMjAzNAogICAgX19IRUxQX05PUk1BTD0iJChlY2hvIC1lICJcMDMzWzBtIikiCiAgZWxzZQogICAgQkFTSF9GUkFNRVdPUktfVEhFTUU9Im5vQ29sb3IiCiAgICAjIGNoZWNrIGNvbG9ycyBhcHBsaWNhYmxlIGh0dHBzOi8vbWlzYy5mbG9naXNvZnQuY29tL2Jhc2gvdGlwX2NvbG9yc19hbmRfZm9ybWF0dGluZwogICAgX19FUlJPUl9DT0xPUj0nJwogICAgX19JTkZPX0NPTE9SPScnCiAgICBfX1NVQ0NFU1NfQ09MT1I9JycKICAgIF9fV0FSTklOR19DT0xPUj0nJwogICAgX19TS0lQUEVEX0NPTE9SPScnCiAgICBfX0RFQlVHX0NPTE9SPScnCiAgICBfX0hFTFBfQ09MT1I9JycKICAgIF9fVEVTVF9DT0xPUj0nJwogICAgX19URVNUX0VSUk9SX0NPTE9SPScnCiAgICBfX0hFTFBfVElUTEVfQ09MT1I9JycKICAgIF9fSEVMUF9PUFRJT05fQ09MT1I9JycKICAgICMgSW50ZXJuYWw6IHJlc2V0IGNvbG9yCiAgICBfX1JFU0VUX0NPTE9SPScnCiAgICBfX0hFTFBfRVhBTVBMRT0nJwogICAgX19IRUxQX1RJVExFPScnCiAgICBfX0hFTFBfTk9STUFMPScnCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gY2hlY2sgaWYgdHR5IChpbnRlcmFjdGl2ZSBtb2RlKSBpcyBhY3RpdmUKIyBAbm9hcmdzCiMgQGV4aXRjb2RlIDEgaWYgdHR5IG5vdCBhY3RpdmUKIyBAZW52IE5PTl9JTlRFUkFDVElWRSBpZiAxIGNvbnNpZGVyIGFzIG5vdCBpbnRlcmFjdGl2ZSBldmVuIGlmIGVudmlyb25tZW50IGlzIGludGVyYWN0aXZlCiMgQGVudiBJTlRFUkFDVElWRSBpZiAxIGNvbnNpZGVyIGFzIGludGVyYWN0aXZlIGV2ZW4gaWYgZW52aXJvbm1lbnQgaXMgbm90IGludGVyYWN0aXZlCiMgQHN0ZGVyciBkaWFnbm9zdGljIGluZm9ybWF0aW9uICsgaGVscCBpZiBzZWNvbmQgYXJndW1lbnQgaXMgcHJvdmlkZWQKQXNzZXJ0Ojp0dHkoKSB7CiAgaWYgW1sgIiR7Tk9OX0lOVEVSQUNUSVZFOi0wfSIgPSAiMSIgXV07IHRoZW4KICAgIHJldHVybiAxCiAgZmkKICBpZiBbWyAiJHtJTlRFUkFDVElWRTotMH0iID0gIjEiIF1dOyB0aGVuCiAgICByZXR1cm4gMAogIGZpCiAgW1sgLXQgMSB8fCAtdCAyIF1dCn0KCiMgRlVOQ1RJT05TCgpmYWNhZGVfbWFpbl9lbWJlZEZyYW1ld29ya0Z1bmN0aW9uYmluRmlsZXRwbCgpIHsKIyBSRVFVSVJFUwpMaW51eDo6cmVxdWlyZUV4ZWN1dGVkQXNVc2VyCkVudjo6cmVxdWlyZUxvYWQKTG9nOjpyZXF1aXJlTG9hZApMaW51eDo6cmVxdWlyZVJlYWxwYXRoQ29tbWFuZApVSTo6cmVxdWlyZVRoZW1lCkNvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyCgojIEByZXF1aXJlIENvbXBpbGVyOjpGYWNhZGU6OnJlcXVpcmVDb21tYW5kQmluRGlyCgojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIxNTQsU0MyMDE2CmZ1bmN0aW9uVG9DYWxsPSdEYjo6cXVlcnlPbmVEYXRhYmFzZScKIiR7ZnVuY3Rpb25Ub0NhbGx9IiAiJEAiCgp9CgpmYWNhZGVfbWFpbl9lbWJlZEZyYW1ld29ya0Z1bmN0aW9uYmluRmlsZXRwbCAiJEAiCg==" +declare -gx embed_function_DbQueryOneDatabase="${PERSISTENT_TMPDIR:-/tmp}/bin/db083cb53bb15c706d27273bb2620268/dbQueryOneDatabase" +declare -gx encoded_binary_file_DbQueryOneDatabase="IyEvdXNyL2Jpbi9lbnYgYmFzaAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgR0VORVJBVEVEIEZBQ0FERSBGUk9NIGh0dHBzOi8vZ2l0aHViLmNvbS9mY2hhc3RhbmV0L2Jhc2gtdG9vbHMvdHJlZS9tYXN0ZXIvLi4vYmFzaC1kZXYtZW52L3ZlbmRvci9iYXNoLXRvb2xzLWZyYW1ld29yay9zcmMvQ29tcGlsZXIvRW1iZWQvZW1iZWRGcmFtZXdvcmtGdW5jdGlvbi5iaW5GaWxlLnRwbAojIERPIE5PVCBFRElUIElUCiMgQGdlbmVyYXRlZAojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjI4OCxTQzIwMzQKIyBCSU5fRklMRT0ke0JJTl9GSUxFfQojIEZBQ0FERQoKIyBlbnN1cmUgdGhhdCBubyB1c2VyIGFsaWFzZXMgY291bGQgaW50ZXJmZXJlIHdpdGgKIyBjb21tYW5kcyB1c2VkIGluIHRoaXMgc2NyaXB0CnVuYWxpYXMgLWEgfHwgdHJ1ZQpzaG9wdCAtdSBleHBhbmRfYWxpYXNlcwoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CigoZmFpbHVyZXMgPSAwKSkgfHwgdHJ1ZQoKIyBCYXNoIHdpbGwgcmVtZW1iZXIgJiByZXR1cm4gdGhlIGhpZ2hlc3QgZXhpdCBjb2RlIGluIGEgY2hhaW4gb2YgcGlwZXMuCiMgVGhpcyB3YXkgeW91IGNhbiBjYXRjaCB0aGUgZXJyb3IgaW5zaWRlIHBpcGVzLCBlLmcuIG15c3FsZHVtcCB8IGd6aXAKc2V0IC1vIHBpcGVmYWlsCnNldCAtbyBlcnJleGl0CgojIENvbW1hbmQgU3Vic3RpdHV0aW9uIGNhbiBpbmhlcml0IGVycmV4aXQgb3B0aW9uIHNpbmNlIGJhc2ggdjQuNApzaG9wdCAtcyBpbmhlcml0X2VycmV4aXQgfHwgdHJ1ZQoKIyBhIGxvZyBpcyBnZW5lcmF0ZWQgd2hlbiBhIGNvbW1hbmQgZmFpbHMKc2V0IC1vIGVycnRyYWNlCgojIHVzZSBudWxsZ2xvYiBzbyB0aGF0IChmaWxlKi5waHApIHdpbGwgcmV0dXJuIGFuIGVtcHR5IGFycmF5IGlmIG5vIGZpbGUgbWF0Y2hlcyB0aGUgd2lsZGNhcmQKc2hvcHQgLXMgbnVsbGdsb2IKCiMgZW5zdXJlIHJlZ2V4cCBhcmUgaW50ZXJwcmV0ZWQgd2l0aG91dCBhY2NlbnR1YXRlZCBjaGFyYWN0ZXJzCmV4cG9ydCBMQ19BTEw9UE9TSVgKCmV4cG9ydCBURVJNPXh0ZXJtLTI1NmNvbG9yCgojIGF2b2lkIGludGVyYWN0aXZlIGluc3RhbGwKZXhwb3J0IERFQklBTl9GUk9OVEVORD1ub25pbnRlcmFjdGl2ZQpleHBvcnQgREVCQ09ORl9OT05JTlRFUkFDVElWRV9TRUVOPXRydWUKCiMgc3RvcmUgY29tbWFuZCBhcmd1bWVudHMgZm9yIGxhdGVyIHVzYWdlCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIEJBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApkZWNsYXJlIC1hIE9SSUdJTkFMX0JBU0hfRlJBTUVXT1JLX0FSR1Y9KCIkQCIpCgojIEBzZWUgaHR0cHM6Ly91bml4LnN0YWNrZXhjaGFuZ2UuY29tL2EvMzg2ODU2CiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjMxNwppbnRlcnJ1cHRNYW5hZ2VtZW50KCkgewogICMgcmVzdG9yZSBTSUdJTlQgaGFuZGxlcgogIHRyYXAgLSBJTlQKICAjIGVuc3VyZSB0aGF0IEN0cmwtQyBpcyB0cmFwcGVkIGJ5IHRoaXMgc2NyaXB0IGFuZCBub3QgYnkgc3ViIHByb2Nlc3MKICAjIHJlcG9ydCB0byB0aGUgcGFyZW50IHRoYXQgd2UgaGF2ZSBpbmRlZWQgYmVlbiBpbnRlcnJ1cHRlZAogIGtpbGwgLXMgSU5UICIkJCIKfQp0cmFwIGludGVycnVwdE1hbmFnZW1lbnQgSU5UClNDUklQVF9OQU1FPSR7MCMjKi99ClJFQUxfU0NSSVBUX0ZJTEU9IiQocmVhZGxpbmsgLWUgIiQocmVhbHBhdGggIiR7QkFTSF9TT1VSQ0VbMF19IikiKSIKaWYgW1sgLW4gIiR7RU1CRURfQ1VSUkVOVF9ESVJ9IiBdXTsgdGhlbgogIENVUlJFTlRfRElSPSIke0VNQkVEX0NVUlJFTlRfRElSfSIKZWxzZQogIENVUlJFTlRfRElSPSIkKGNkICIkKHJlYWRsaW5rIC1lICIke1JFQUxfU0NSSVBUX0ZJTEUlLyp9IikiICYmIHB3ZCAtUCkiCmZpCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKIyBUZW1wIGRpciBtYW5hZ2VtZW50CiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKS0VFUF9URU1QX0ZJTEVTPSIke0tFRVBfVEVNUF9GSUxFUzotMH0iCmV4cG9ydCBLRUVQX1RFTVBfRklMRVMKCiMgUEVSU0lTVEVOVF9UTVBESVIgaXMgbm90IGRlbGV0ZWQgYnkgdHJhcHMKUEVSU0lTVEVOVF9UTVBESVI9IiR7VE1QRElSOi0vdG1wfS9iYXNoLWZyYW1ld29yayIKZXhwb3J0IFBFUlNJU1RFTlRfVE1QRElSCm1rZGlyIC1wICIke1BFUlNJU1RFTlRfVE1QRElSfSIKCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAzNApUTVBESVI9IiQobWt0ZW1wIC1kIC1wICIke1BFUlNJU1RFTlRfVE1QRElSOi0vdG1wfSIgLXQgYmFzaC1mcmFtZXdvcmstJCQtWFhYWFhYKSIKZXhwb3J0IFRNUERJUgoKIyB0ZW1wIGRpciBjbGVhbmluZwojIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIzMTcKY2xlYW5PbkV4aXQoKSB7CiAgaWYgW1sgIiR7S0VFUF9URU1QX0ZJTEVTOi0wfSIgPSAiMSIgXV07IHRoZW4KICAgIExvZzo6ZGlzcGxheUluZm8gIktFRVBfVEVNUF9GSUxFUz0xIHRlbXAgZmlsZXMga2VwdCBoZXJlICcke1RNUERJUn0nIgogIGVsaWYgW1sgLW4gIiR7VE1QRElSK3h4eH0iIF1dOyB0aGVuCiAgICBMb2c6OmRpc3BsYXlEZWJ1ZyAiS0VFUF9URU1QX0ZJTEVTPTAgcmVtb3ZpbmcgdGVtcCBmaWxlcyAnJHtUTVBESVJ9JyIKICAgIHJtIC1SZiAiJHtUTVBESVI6LS90bXAvZmFrZX0iID4vZGV2L251bGwgMj4mMQogIGZpCn0KdHJhcCBjbGVhbk9uRXhpdCBFWElUIEhVUCBRVUlUIEFCUlQgVEVSTQoKIyBWQVJfTUFJTl9GVU5DVElPTl9WQVJfTkFNRT1kYlF1ZXJ5QWxsRGF0YWJhc2VzRmFjYWRlCgojIEBkZXNjcmlwdGlvbiB1c2VkIHRvIGV4ZWN1dGUgZ2l2ZW4gcXVlcnkgd2hlbiB1c2luZwojIGRiU2NyaXB0QWxsRGF0YWJhc2VzCiMgQGFyZyAkMSBkc246U3RyaW5nCiMgQGFyZyAkMiBkYjpTdHJpbmcKIyBAZW52IHF1ZXJ5IFN0cmluZwojIEBlbnYgb3B0aW9uU2VwYXJhdG9yIFN0cmluZwojIEByZXF1aXJlIExpbnV4OjpyZXF1aXJlRXhlY3V0ZWRBc1VzZXIKRGI6OnF1ZXJ5T25lRGF0YWJhc2UoKSB7CiAgIyBxdWVyeSBhbmQgb3B0aW9uU2VwYXJhdG9yIGFyZSBwYXNzZWQgdmlhIGV4cG9ydAogIGxvY2FsIGRzbj0iJDEiCiAgbG9jYWwgZGI9IiQyIgoKICBsb2NhbCAtQSBkYkluc3RhbmNlCiAgRGF0YWJhc2U6Om5ld0luc3RhbmNlIGRiSW5zdGFuY2UgIiR7ZHNufSIKICBEYXRhYmFzZTo6c2V0UXVlcnlPcHRpb25zIGRiSW5zdGFuY2UgIiR7ZGJJbnN0YW5jZVtRVUVSWV9PUFRJT05TXX0gLS1jb25uZWN0LXRpbWVvdXQ9NSIKCiAgIyBpZGVudGlmeSBjb2x1bW5zIGhlYWRlcgogIGVjaG8gLW4gIkBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAIgogIERhdGFiYXNlOjpza2lwQ29sdW1uTmFtZXMgZGJJbnN0YW5jZSAwCgogICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE1NAogIGlmICEgRGF0YWJhc2U6OnF1ZXJ5IGRiSW5zdGFuY2UgIiR7cXVlcnl9IiAiJHtkYn0iIHwgc2VkICJzL1x0LyR7b3B0aW9uU2VwYXJhdG9yfS9nIjsgdGhlbgogICAgTG9nOjpmYXRhbCAiZGF0YWJhc2UgJHtkYn0gZXJyb3IiIDE+JjIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBMb2cgbmFtZXNwYWNlIHByb3ZpZGVzIDIga2luZCBvZiBmdW5jdGlvbnMKIyAtIExvZzo6ZGlzcGxheSogYWxsb3dzIHRvIGRpc3BsYXkgZ2l2ZW4gbWVzc2FnZSB3aXRoCiMgICBnaXZlbiBkaXNwbGF5IGxldmVsCiMgLSBMb2c6OmxvZyogYWxsb3dzIHRvIGxvZyBnaXZlbiBtZXNzYWdlIHdpdGgKIyAgIGdpdmVuIGxvZyBsZXZlbAojIExvZzo6ZGlzcGxheSogZnVuY3Rpb25zIGF1dG9tYXRpY2FsbHkgbG9nIHRoZSBtZXNzYWdlIHRvbwojIEBzZWUgRW52OjpyZXF1aXJlTG9hZCB0byBsb2FkIHRoZSBkaXNwbGF5IGFuZCBsb2cgbGV2ZWwgZnJvbSAuZW52IGZpbGUKCiMgQGRlc2NyaXB0aW9uIGxvZyBsZXZlbCBvZmYKZXhwb3J0IF9fTEVWRUxfT0ZGPTAKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIGVycm9yCmV4cG9ydCBfX0xFVkVMX0VSUk9SPTEKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIHdhcm5pbmcKZXhwb3J0IF9fTEVWRUxfV0FSTklORz0yCiMgQGRlc2NyaXB0aW9uIGxvZyBsZXZlbCBpbmZvCmV4cG9ydCBfX0xFVkVMX0lORk89MwojIEBkZXNjcmlwdGlvbiBsb2cgbGV2ZWwgc3VjY2VzcwpleHBvcnQgX19MRVZFTF9TVUNDRVNTPTMKIyBAZGVzY3JpcHRpb24gbG9nIGxldmVsIGRlYnVnCmV4cG9ydCBfX0xFVkVMX0RFQlVHPTQKCiMgQGRlc2NyaXB0aW9uIHZlcmJvc2UgbGV2ZWwgb2ZmCmV4cG9ydCBfX1ZFUkJPU0VfTEVWRUxfT0ZGPTAKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBpbmZvCmV4cG9ydCBfX1ZFUkJPU0VfTEVWRUxfSU5GTz0xCiMgQGRlc2NyaXB0aW9uIHZlcmJvc2UgbGV2ZWwgaW5mbwpleHBvcnQgX19WRVJCT1NFX0xFVkVMX0RFQlVHPTIKIyBAZGVzY3JpcHRpb24gdmVyYm9zZSBsZXZlbCBpbmZvCmV4cG9ydCBfX1ZFUkJPU0VfTEVWRUxfVFJBQ0U9MwoKIyBAZGVzY3JpcHRpb24gRGlzcGxheSBtZXNzYWdlIHVzaW5nIGRlYnVnIGNvbG9yIChncmV5KQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmRpc3BsYXlEZWJ1ZygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUwgPj0gX19MRVZFTF9ERUJVRykpOyB0aGVuCiAgICBlY2hvIC1lICIke19fREVCVUdfQ09MT1J9REVCVUcgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nRGVidWcgIiQxIgp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgaW5mbyBjb2xvciAoYmcgbGlnaHQgYmx1ZS9mZyB3aGl0ZSkKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpkaXNwbGF5SW5mbygpIHsKICBsb2NhbCB0eXBlPSIkezI6LUlORk99IgogIGlmICgoQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX0lORk9fQ09MT1J9JHt0eXBlfSAgICAtICR7MX0ke19fUkVTRVRfQ09MT1J9IiA+JjIKICBmaQogIExvZzo6bG9nSW5mbyAiJDEiICIke3R5cGV9Igp9CgojIEBkZXNjcmlwdGlvbiBlbnN1cmUgQ09NTUFORF9CSU5fRElSIGVudiB2YXIgaXMgc2V0CiMgYW5kIFBBVEggY29ycmVjdGx5IHByZXBhcmVkCiMgQG5vYXJncwojIEBzZXQgQ09NTUFORF9CSU5fRElSIHN0cmluZyB0aGUgZGlyZWN0b3J5IHdoZXJlIHRvIGZpbmQgdGhpcyBjb21tYW5kCiMgQHNldCBQQVRIIHN0cmluZyBhZGQgZGlyZWN0b3J5IHdoZXJlIHRvIGZpbmQgdGhpcyBjb21tYW5kIGJpbmFyeQpDb21waWxlcjo6RmFjYWRlOjpyZXF1aXJlQ29tbWFuZEJpbkRpcigpIHsKICBDT01NQU5EX0JJTl9ESVI9IiR7Q1VSUkVOVF9ESVJ9IgogIEVudjo6cGF0aFByZXBlbmQgIiR7Q09NTUFORF9CSU5fRElSfSIKfQoKIyBAZGVzY3JpcHRpb24gY3JlYXRlIGEgbmV3IGRiIGluc3RhbmNlCiMgUmV0dXJucyBpbW1lZGlhdGVseSBpZiB0aGUgaW5zdGFuY2UgaXMgYWxyZWFkeSBpbml0aWFsaXplZAojCiMgQGFyZyAkMSBpbnN0YW5jZU5ld0luc3RhbmNlOiZNYXA8U3RyaW5nLFN0cmluZz4gKHBhc3NlZCBieSByZWZlcmVuY2UpIGRhdGFiYXNlIGluc3RhbmNlIHRvIHVzZQojIEBhcmcgJDIgZHNuOlN0cmluZyBkc24gcHJvZmlsZSAtIGxvYWQgdGhlIGRzbi5lbnYgcHJvZmlsZSBkZWR1Y2VkIHVzaW5nIHJ1bGVzIGRlZmluZWQgaW4gQ29uZjo6Z2V0QWJzb2x1dGVGaWxlCiMKIyBAZXhhbXBsZQojICAgZGVjbGFyZSAtQWd4IGRiSW5zdGFuY2UKIyAgIERhdGFiYXNlOjpuZXdJbnN0YW5jZSBkYkluc3RhbmNlICJkZWZhdWx0LmxvY2FsIgojCiMgQGV4aXRjb2RlIDEgaWYgZG5zIGZpbGUgbm90IGFibGUgdG8gbG9hZGVkCkRhdGFiYXNlOjpuZXdJbnN0YW5jZSgpIHsKICBsb2NhbCAtbiBpbnN0YW5jZU5ld0luc3RhbmNlPSQxCiAgbG9jYWwgZHNuPSIkMiIKICBsb2NhbCBEU05fRklMRQoKICBpZiBbWyAtdiBpbnN0YW5jZU5ld0luc3RhbmNlWydJTklUSUFMSVpFRCddICYmICIke2luc3RhbmNlTmV3SW5zdGFuY2VbJ0lOSVRJQUxJWkVEJ106LTB9IiA9PSAiMSIgXV07IHRoZW4KICAgIHJldHVybgogIGZpCgogICMgZmluYWwgYXV0aCBmaWxlIGdlbmVyYXRlZCBmcm9tIGRucyBmaWxlCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnQVVUSF9GSUxFJ109IiIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydEU05fRklMRSddPSIiCgogICMgY2hlY2sgZHNuIGZpbGUKICBEU05fRklMRT0iJChDb25mOjpnZXRBYnNvbHV0ZUZpbGUgImRzbiIgIiR7ZHNufSIgImVudiIpIiB8fCByZXR1cm4gMQogIERhdGFiYXNlOjpjaGVja0RzbkZpbGUgIiR7RFNOX0ZJTEV9IiB8fCByZXR1cm4gMQogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0RTTl9GSUxFJ109IiR7RFNOX0ZJTEV9IgoKICAjIHNoZWxsY2hlY2sgc291cmNlPS9zcmMvRGF0YWJhc2UvdGVzdHNEYXRhL2Rzbl92YWxpZC5lbnYKICBzb3VyY2UgIiR7aW5zdGFuY2VOZXdJbnN0YW5jZVsnRFNOX0ZJTEUnXX0iCgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1VTRVInXT0iJHtVU0VSfSIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydQQVNTV09SRCddPSIke1BBU1NXT1JEfSIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydIT1NUTkFNRSddPSIke0hPU1ROQU1FfSIKICBpbnN0YW5jZU5ld0luc3RhbmNlWydQT1JUJ109IiR7UE9SVH0iCgogICMgZ2VuZXJhdGUgYXV0aEZpbGUgZm9yIGVhc3kgYXV0aGVudGljYXRpb24KICBpbnN0YW5jZU5ld0luc3RhbmNlWydBVVRIX0ZJTEUnXT0kKG1rdGVtcCAtcCAiJHtUTVBESVI6LS90bXB9IiAtdCAibXlzcWwuWFhYWFhYWFhYWFhYIikKICAoCiAgICBlY2hvICJbY2xpZW50XSIKICAgIGVjaG8gInVzZXIgPSAke1VTRVJ9IgogICAgZWNobyAicGFzc3dvcmQgPSAke1BBU1NXT1JEfSIKICAgIGVjaG8gImhvc3QgPSAke0hPU1ROQU1FfSIKICAgIGVjaG8gInBvcnQgPSAke1BPUlR9IgogICkgPiIke2luc3RhbmNlTmV3SW5zdGFuY2VbJ0FVVEhfRklMRSddfSIKCiAgIyBzb21lIG9mIHRob3NlIHZhbHVlcyBjYW4gYmUgb3ZlcnJpZGRlbiB1c2luZyB0aGUgZHNuIGZpbGUKICAjIFNLSVBfQ09MVU1OX05BTUVTIGVuYWJsZWQgYnkgZGVmYXVsdAogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1NLSVBfQ09MVU1OX05BTUVTJ109IiR7U0tJUF9DT0xVTU5fTkFNRVM6LTF9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1NTTF9PUFRJT05TJ109IiR7TVlTUUxfU1NMX09QVElPTlM6LS0tc3NsLW1vZGU9RElTQUJMRUR9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ1FVRVJZX09QVElPTlMnXT0iJHtNWVNRTF9RVUVSWV9PUFRJT05TOi0tLWJhdGNoIC0tcmF3IC0tZGVmYXVsdC1jaGFyYWN0ZXItc2V0PXV0Zjh9IgogIGluc3RhbmNlTmV3SW5zdGFuY2VbJ0RVTVBfT1BUSU9OUyddPSIke01ZU1FMX0RVTVBfT1BUSU9OUzotLS1kZWZhdWx0LWNoYXJhY3Rlci1zZXQ9dXRmOCAtLWNvbXByZXNzIC0taGV4LWJsb2IgLS1yb3V0aW5lcyAtLXRyaWdnZXJzIC0tc2luZ2xlLXRyYW5zYWN0aW9uIC0tc2V0LWd0aWQtcHVyZ2VkPU9GRiAtLWNvbHVtbi1zdGF0aXN0aWNzPTAgJHtpbnN0YW5jZU5ld0luc3RhbmNlWydTU0xfT1BUSU9OUyddfX0iCiAgaW5zdGFuY2VOZXdJbnN0YW5jZVsnREJfSU1QT1JUX09QVElPTlMnXT0iJHtEQl9JTVBPUlRfT1BUSU9OUzotLS1jb25uZWN0LXRpbWVvdXQ9NSAtLWJhdGNoIC0tcmF3IC0tZGVmYXVsdC1jaGFyYWN0ZXItc2V0PXV0Zjh9IgoKICBpbnN0YW5jZU5ld0luc3RhbmNlWydJTklUSUFMSVpFRCddPTEKfQoKIyBAZGVzY3JpcHRpb24gbXlzcWwgcXVlcnkgb24gYSBnaXZlbiBkYgojIEB3YXJuaW5nIGNvdWxkIHVzZSBRVUVSWV9PUFRJT05TIHZhcmlhYmxlIGZyb20gZHNuIGlmIGRlZmluZWQKIyBAZXhhbXBsZQojICAgY2F0IGZpbGUuc3FsIHwgRGF0YWJhc2U6OnF1ZXJ5IC4uLgojIEBhcmcgJDEgaW5zdGFuY2VRdWVyeTomTWFwPFN0cmluZyxTdHJpbmc+IChwYXNzZWQgYnkgcmVmZXJlbmNlKSBkYXRhYmFzZSBpbnN0YW5jZSB0byB1c2UKIyBAYXJnICQyIHNxbFF1ZXJ5OlN0cmluZyAob3B0aW9uYWwpIHNxbCBxdWVyeSBvciBzcWwgZmlsZSB0byBleGVjdXRlLiBpZiBub3QgcHJvdmlkZWQgb3IgZW1wdHksIHRoZSBjb21tYW5kIGNhbiBiZSBwaXBlZAojIEBhcmcgJDMgZGJOYW1lOlN0cmluZyAob3B0aW9uYWwpIHRoZSBkYiBuYW1lCiMKIyBAZXhpdGNvZGUgbXlzcWwgY29tbWFuZCBzdGF0dXMgY29kZQpEYXRhYmFzZTo6cXVlcnkoKSB7CiAgbG9jYWwgLW4gaW5zdGFuY2VRdWVyeT0kMQogIGxvY2FsIC1hIG15c3FsQ29tbWFuZD0oKQogIGxvY2FsIC1hIHF1ZXJ5T3B0aW9ucwoKICBteXNxbENvbW1hbmQrPShteXNxbCkKICBteXNxbENvbW1hbmQrPSgiLS1kZWZhdWx0cy1leHRyYS1maWxlPSR7aW5zdGFuY2VRdWVyeVsnQVVUSF9GSUxFJ119IikKICBJRlM9JyAnIHJlYWQgLXIgLWEgcXVlcnlPcHRpb25zIDw8PCIke2luc3RhbmNlUXVlcnlbJ1FVRVJZX09QVElPTlMnXX0iCiAgbXlzcWxDb21tYW5kKz0oIiR7cXVlcnlPcHRpb25zW0BdfSIpCiAgaWYgW1sgIiR7aW5zdGFuY2VRdWVyeVsnU0tJUF9DT0xVTU5fTkFNRVMnXX0iID0gIjEiIF1dOyB0aGVuCiAgICBteXNxbENvbW1hbmQrPSgiLXMiICItLXNraXAtY29sdW1uLW5hbWVzIikKICBmaQogICMgYWRkIG9wdGlvbmFsIGRiIG5hbWUKICBpZiBbWyAtbiAiJHszK3h9IiBdXTsgdGhlbgogICAgbXlzcWxDb21tYW5kKz0oIiQzIikKICBmaQogICMgYWRkIG9wdGlvbmFsIHNxbCBxdWVyeQogIGlmIFtbIC1uICIkezIreH0iICYmIC1uICIkMiIgJiYgISAtZiAiJDIiIF1dOyB0aGVuCiAgICBteXNxbENvbW1hbmQrPSgiLWUiKQogICAgbXlzcWxDb21tYW5kKz0oIiQyIikKICBmaQogIExvZzo6ZGlzcGxheURlYnVnICIkKHByaW50ZiAiZXhlY3V0ZSBjb21tYW5kOiAnJXMnIiAiJHtteXNxbENvbW1hbmRbKl19IikiCgogIGlmIFtbIC1mICIkMiIgXV07IHRoZW4KICAgICIke215c3FsQ29tbWFuZFtAXX0iIDwiJDIiCiAgZWxzZQogICAgIiR7bXlzcWxDb21tYW5kW0BdfSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBzZXQgdGhlIGdlbmVyYWwgb3B0aW9ucyB0byB1c2Ugb24gbXlzcWwgY29tbWFuZCB0byBxdWVyeSB0aGUgZGF0YWJhc2UKIyBEaWZmZXJzIHRoYW4gc2V0T3B0aW9ucyBpbiB0aGUgd2F5IHRoYXQgdGhlc2Ugb3B0aW9ucyBjb3VsZCBjaGFuZ2UgZWFjaCB0aW1lCiMKIyBAYXJnICQxIGluc3RhbmNlU2V0UXVlcnlPcHRpb25zOiZNYXA8U3RyaW5nLFN0cmluZz4gKHBhc3NlZCBieSByZWZlcmVuY2UpIGRhdGFiYXNlIGluc3RhbmNlIHRvIHVzZQojIEBhcmcgJDIgb3B0aW9uc0xpc3Q6U3RyaW5nIHF1ZXJ5IG9wdGlvbnMgbGlzdApEYXRhYmFzZTo6c2V0UXVlcnlPcHRpb25zKCkgewogIGxvY2FsIC1uIGluc3RhbmNlU2V0UXVlcnlPcHRpb25zPSQxCiAgIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0CiAgaW5zdGFuY2VTZXRRdWVyeU9wdGlvbnNbJ1FVRVJZX09QVElPTlMnXT0iJDIiCn0KCiMgQGRlc2NyaXB0aW9uIGJ5IGRlZmF1bHQgd2Ugc2tpcCB0aGUgY29sdW1uIG5hbWVzCiMgYnV0IHNvbWV0aW1lcyB3ZSBuZWVkIGNvbHVtbiBuYW1lcyB0byBkaXNwbGF5IHNvbWUgcmVzdWx0cwojIGRpc2FibGUgdGhpcyBvcHRpb24gdGVtcG9yYXJpbHkgYW5kIHRoZW4gcmVzdG9yZSBpdCB0byB0cnVlCiMKIyBAYXJnICQxIGluc3RhbmNlU2V0UXVlcnlPcHRpb25zOiZNYXA8U3RyaW5nLFN0cmluZz4gKHBhc3NlZCBieSByZWZlcmVuY2UpIGRhdGFiYXNlIGluc3RhbmNlIHRvIHVzZQojIEBhcmcgJDIgc2tpcENvbHVtbk5hbWVzOkJvb2xlYW4gMCB0byBkaXNhYmxlLCAxIHRvIGVuYWJsZSAoaGlkZSBjb2x1bW4gbmFtZXMpCkRhdGFiYXNlOjpza2lwQ29sdW1uTmFtZXMoKSB7CiAgbG9jYWwgLW4gaW5zdGFuY2VTa2lwQ29sdW1uTmFtZXM9JDEKICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIwMzQKICBpbnN0YW5jZVNraXBDb2x1bW5OYW1lc1snU0tJUF9DT0xVTU5fTkFNRVMnXT0iJDIiCn0KCiMgQGRlc2NyaXB0aW9uIHByZXBlbmQgZGlyZWN0b3JpZXMgdG8gdGhlIFBBVEggZW52aXJvbm1lbnQgdmFyaWFibGUKIyBAYXJnICRAIGFyZ3M6U3RyaW5nW10gbGlzdCBvZiBkaXJlY3RvcmllcyB0byBwcmVwZW5kCiMgQHNldCBQQVRIIHVwZGF0ZSBQQVRIIHdpdGggdGhlIGRpcmVjdG9yaWVzIHByZXBlbmRlZApFbnY6OnBhdGhQcmVwZW5kKCkgewogIGxvY2FsIGFyZwogIGZvciBhcmcgaW4gIiRAIjsgZG8KICAgIGlmIFtbIC1kICIke2FyZ30iICYmICI6JHtQQVRIfToiICE9ICoiOiR7YXJnfToiKiBdXTsgdGhlbgogICAgICBQQVRIPSIkKHJlYWxwYXRoICIke2FyZ30iKToke1BBVEh9IgogICAgZmkKICBkb25lCn0KCiMgQGRlc2NyaXB0aW9uIERpc3BsYXkgbWVzc2FnZSB1c2luZyBlcnJvciBjb2xvciAocmVkKSBhbmQgZXhpdCBpbW1lZGlhdGVseSB3aXRoIGVycm9yIHN0YXR1cyAxCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6ZmF0YWwoKSB7CiAgZWNobyAtZSAiJHtfX0VSUk9SX0NPTE9SfUZBVEFMICAgLSAkezF9JHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgTG9nOjpsb2dGYXRhbCAiJDEiCiAgZXhpdCAxCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dEZWJ1ZygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0RFQlVHKSk7IHRoZW4KICAgIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1ERUJVR30iICIkMSIKICBmaQp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nSW5mbygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+PSBfX0xFVkVMX0lORk8pKTsgdGhlbgogICAgTG9nOjpsb2dNZXNzYWdlICIkezI6LUlORk99IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZW5zdXJlIHJ1bm5pbmcgdXNlciBpcyBub3Qgcm9vdAojIEBleGl0Y29kZSAxIGlmIGN1cnJlbnQgdXNlciBpcyByb290CiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKTGludXg6OnJlcXVpcmVFeGVjdXRlZEFzVXNlcigpIHsKICBpZiBbWyAiJChpZCAtdSkiID0gIjAiIF1dOyB0aGVuCiAgICBMb2c6OmZhdGFsICJ0aGlzIHNjcmlwdCBzaG91bGQgYmUgZXhlY3V0ZWQgYXMgbm9ybWFsIHVzZXIiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gZ2V0IGFic29sdXRlIGNvbmYgZmlsZSBmcm9tIHNwZWNpZmllZCBjb25mIGZvbGRlciBkZWR1Y2VkIHVzaW5nIHRoZXNlIHJ1bGVzCiMgICAqIGZyb20gYWJzb2x1dGUgZmlsZSAoaWdub3JlcyA8Y29uZkZvbGRlcj4gYW5kIDxleHRlbnNpb24+KQojICAgKiByZWxhdGl2ZSB0byB3aGVyZSBzY3JpcHQgaXMgZXhlY3V0ZWQgKGlnbm9yZXMgPGNvbmZGb2xkZXI+IGFuZCA8ZXh0ZW5zaW9uPikKIyAgICogZnJvbSBob21lLy5iYXNoLXRvb2xzLzxjb25mRm9sZGVyPgojICAgKiBmcm9tIGZyYW1ld29yayBjb25mLzxjb25mRm9sZGVyPgojCiMgQGFyZyAkMSBjb25mRm9sZGVyOlN0cmluZyB0aGUgZGlyZWN0b3J5IG5hbWUgKG5vdCB0aGUgcGF0aCkgdG8gbGlzdAojIEBhcmcgJDIgY29uZjpTdHJpbmcgZmlsZSB0byB1c2Ugd2l0aG91dCBleHRlbnNpb24KIyBAYXJnICQzIGV4dGVuc2lvbjpTdHJpbmcgdGhlIGV4dGVuc2lvbiAoLnNoIGJ5IGRlZmF1bHQpCiMKIyBAc3Rkb3V0IGFic29sdXRlIGNvbmYgZmlsZW5hbWUKIyBAZXhpdGNvZGUgMSBpZiBmaWxlIGlzIG5vdCBmb3VuZCBpbiBhbnkgbG9jYXRpb24KQ29uZjo6Z2V0QWJzb2x1dGVGaWxlKCkgewogIGxvY2FsIGNvbmZGb2xkZXI9IiQxIgogIGxvY2FsIGNvbmY9IiQyIgogIGxvY2FsIGV4dGVuc2lvbj0iJHszLS5zaH0iCiAgaWYgW1sgLW4gIiR7ZXh0ZW5zaW9ufSIgJiYgIiR7ZXh0ZW5zaW9uOjA6MX0iICE9ICIuIiBdXTsgdGhlbgogICAgZXh0ZW5zaW9uPSIuJHtleHRlbnNpb259IgogIGZpCgogIHRlc3RBYnMoKSB7CiAgICBsb2NhbCByZXN1bHQKICAgIHJlc3VsdD0iJChyZWFscGF0aCAtZSAiJDEiIDI+L2Rldi9udWxsKSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE4MQogICAgaWYgW1sgIiQ/IiA9ICIwIiAmJiAtZiAiJHtyZXN1bHR9IiBdXTsgdGhlbgogICAgICBlY2hvICIke3Jlc3VsdH0iCiAgICAgIHJldHVybiAwCiAgICBmaQogICAgcmV0dXJuIDEKICB9CgogICMgY29uZiBpcyBhYnNvbHV0ZSBmaWxlIChpbmNsdWRpbmcgZXh0ZW5zaW9uKQogIHRlc3RBYnMgIiR7Y29uZkZvbGRlcn0ke2V4dGVuc2lvbn0iICYmIHJldHVybiAwCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUKICB0ZXN0QWJzICIke2NvbmZGb2xkZXJ9IiAmJiByZXR1cm4gMAogICMgY29uZiBpcyBhYnNvbHV0ZSBmaWxlIChpbmNsdWRpbmcgZXh0ZW5zaW9uKQogIHRlc3RBYnMgIiR7Y29uZn0ke2V4dGVuc2lvbn0iICYmIHJldHVybiAwCiAgIyBjb25mIGlzIGFic29sdXRlIGZpbGUKICB0ZXN0QWJzICIke2NvbmZ9IiAmJiByZXR1cm4gMAoKICAjIHJlbGF0aXZlIHRvIHdoZXJlIHNjcmlwdCBpcyBleGVjdXRlZCAoaW5jbHVkaW5nIGV4dGVuc2lvbikKICBpZiBbWyAtbiAiJHtDVVJSRU5UX0RJUit4eHh9IiBdXTsgdGhlbgogICAgdGVzdEFicyAiJChGaWxlOjpjb25jYXRlbmF0ZVBhdGggIiR7Q1VSUkVOVF9ESVJ9IiAiJHtjb25mRm9sZGVyfSIpLyR7Y29uZn0ke2V4dGVuc2lvbn0iICYmIHJldHVybiAwCiAgZmkKICAjIGZyb20gaG9tZS8uYmFzaC10b29scy88Y29uZkZvbGRlcj4KICB0ZXN0QWJzICIkKEZpbGU6OmNvbmNhdGVuYXRlUGF0aCAiJHtIT01FfS8uYmFzaC10b29scyIgIiR7Y29uZkZvbGRlcn0iKS8ke2NvbmZ9JHtleHRlbnNpb259IiAmJiByZXR1cm4gMAoKICBpZiBbWyAtbiAiJHtGUkFNRVdPUktfUk9PVF9ESVIreHh4fSIgXV07IHRoZW4KICAgICMgZnJvbSBmcmFtZXdvcmsgY29uZi88Y29uZkZvbGRlcj4gKGluY2x1ZGluZyBleHRlbnNpb24pCiAgICB0ZXN0QWJzICIkKEZpbGU6OmNvbmNhdGVuYXRlUGF0aCAiJHtGUkFNRVdPUktfUk9PVF9ESVJ9L2NvbmYiICIke2NvbmZGb2xkZXJ9IikvJHtjb25mfSR7ZXh0ZW5zaW9ufSIgJiYgcmV0dXJuIDAKCiAgICAjIGZyb20gZnJhbWV3b3JrIGNvbmYvPGNvbmZGb2xkZXI+CiAgICB0ZXN0QWJzICIkKEZpbGU6OmNvbmNhdGVuYXRlUGF0aCAiJHtGUkFNRVdPUktfUk9PVF9ESVJ9L2NvbmYiICIke2NvbmZGb2xkZXJ9IikvJHtjb25mfSIgJiYgcmV0dXJuIDAKICBmaQoKICAjIGZpbGUgbm90IGZvdW5kCiAgTG9nOjpkaXNwbGF5RXJyb3IgImNvbmYgZmlsZSAnJHtjb25mfScgbm90IGZvdW5kIgoKICByZXR1cm4gMQp9CgojIEBkZXNjcmlwdGlvbiBjaGVjayBpZiBkc24gZmlsZSBoYXMgYWxsIHRoZSBtYW5kYXRvcnkgdmFyaWFibGVzIHNldAojIE1hbmRhdG9yeSB2YXJpYWJsZXMgYXJlOiBIT1NUTkFNRSwgVVNFUiwgUEFTU1dPUkQsIFBPUlQKIwojIEBhcmcgJDEgZHNuRmlsZU5hbWU6U3RyaW5nIGRzbiBhYnNvbHV0ZSBmaWxlbmFtZQojIEBzZXQgSE9TVE5BTUUgbG9hZGVkIGZyb20gZHNuIGZpbGUKIyBAc2V0IFBPUlQgbG9hZGVkIGZyb20gZHNuIGZpbGUKIyBAc2V0IFVTRVIgbG9hZGVkIGZyb20gZHNuIGZpbGUKIyBAc2V0IFBBU1NXT1JEIGxvYWRlZCBmcm9tIGRzbiBmaWxlCiMgQGV4aXRjb2RlIDAgb24gdmFsaWQgZmlsZQojIEBleGl0Y29kZSAxIGlmIG9uZSBvZiB0aGUgcHJvcGVydGllcyBvZiB0aGUgY29uZiBmaWxlIGlzIGludmFsaWQgb3IgaWYgZmlsZSBub3QgZm91bmQKIyBAc3RkZXJyIGxvZyBvdXRwdXQgaWYgZXJyb3IgZm91bmQgaW4gY29uZiBmaWxlCkRhdGFiYXNlOjpjaGVja0RzbkZpbGUoKSB7CiAgbG9jYWwgZHNuRmlsZU5hbWU9IiQxIgogIGlmIFtbICEgLWYgIiR7ZHNuRmlsZU5hbWV9IiBdXTsgdGhlbgogICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IG5vdCBmb3VuZCIKICAgIHJldHVybiAxCiAgZmkKCiAgKAogICAgdW5zZXQgSE9TVE5BTUUgUE9SVCBQQVNTV09SRCBVU0VSCiAgICAjIHNoZWxsY2hlY2sgc291cmNlPS9zcmMvRGF0YWJhc2UvdGVzdHNEYXRhL2Rzbl92YWxpZC5lbnYKICAgIHNvdXJjZSAiJHtkc25GaWxlTmFtZX0iCiAgICBpZiBbWyAteiAke0hPU1ROQU1FK3h9IF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJkc24gZmlsZSAke2RzbkZpbGVOYW1lfSA6IEhPU1ROQU1FIG5vdCBwcm92aWRlZCIKICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBpZiBbWyAteiAiJHtIT1NUTkFNRX0iIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheVdhcm5pbmcgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogSE9TVE5BTUUgdmFsdWUgbm90IHByb3ZpZGVkIgogICAgZmkKICAgIGlmIFtbICIke0hPU1ROQU1FfSIgPSAibG9jYWxob3N0IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlXYXJuaW5nICJkc24gZmlsZSAke2RzbkZpbGVOYW1lfSA6IGNoZWNrIHRoYXQgSE9TVE5BTUUgc2hvdWxkIG5vdCBiZSAxMjcuMC4wLjEgaW5zdGVhZCBvZiBsb2NhbGhvc3QiCiAgICBmaQogICAgaWYgW1sgLXogIiR7UE9SVCt4fSIgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogUE9SVCBub3QgcHJvdmlkZWQiCiAgICAgIHJldHVybiAxCiAgICBmaQogICAgaWYgISBbWyAke1BPUlR9ID1+IF5bMC05XSskIF1dOyB0aGVuCiAgICAgIExvZzo6ZGlzcGxheUVycm9yICJkc24gZmlsZSAke2RzbkZpbGVOYW1lfSA6IFBPUlQgaW52YWxpZCIKICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBpZiBbWyAteiAiJHtVU0VSK3h9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiZHNuIGZpbGUgJHtkc25GaWxlTmFtZX0gOiBVU0VSIG5vdCBwcm92aWRlZCIKICAgICAgcmV0dXJuIDEKICAgIGZpCiAgICBpZiBbWyAteiAiJHtQQVNTV09SRCt4fSIgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5RXJyb3IgImRzbiBmaWxlICR7ZHNuRmlsZU5hbWV9IDogUEFTU1dPUkQgbm90IHByb3ZpZGVkIgogICAgICByZXR1cm4gMQogICAgZmkKICApCn0KCiMgQGRlc2NyaXB0aW9uIGxvZyBtZXNzYWdlIHRvIGZpbGUKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpsb2dGYXRhbCgpIHsKICBMb2c6OmxvZ01lc3NhZ2UgIiR7MjotRkFUQUx9IiAiJDEiCn0KCiMgQGRlc2NyaXB0aW9uIEludGVybmFsOiBjb21tb24gbG9nIG1lc3NhZ2UKIyBAZXhhbXBsZSB0ZXh0CiMgICBbZGF0ZV18W2xldmVsTXNnXXxtZXNzYWdlCiMKIyBAZXhhbXBsZSB0ZXh0CiMgICAyMDIwLTAxLTE5IDE5OjIwOjIxfEVSUk9SICB8bG9nIGVycm9yCiMgICAyMDIwLTAxLTE5IDE5OjIwOjIxfFNLSVBQRUR8bG9nIHNraXBwZWQKIwojIEBhcmcgJDEgbGV2ZWxNc2c6U3RyaW5nIG1lc3NhZ2UncyBsZXZlbCBkZXNjcmlwdGlvbiAoZWc6IFNUQVRVUywgRVJST1IsIC4uLikKIyBAYXJnICQyIG1zZzpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEUgU3RyaW5nIGxvZyBmaWxlIHRvIHVzZSwgZG8gbm90aGluZyBpZiBlbXB0eQojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMIGludCBsb2cgbGV2ZWwgbG9nIG9ubHkgaWYgPiBPRkYgb3IgZmF0YWwgbWVzc2FnZXMKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGlzIGRpc3BsYXllZAojIEByZXF1aXJlIEVudjo6cmVxdWlyZUxvYWQKIyBAcmVxdWlyZSBMb2c6OnJlcXVpcmVMb2FkCkxvZzo6bG9nTWVzc2FnZSgpIHsKICBsb2NhbCBsZXZlbE1zZz0iJDEiCiAgbG9jYWwgbXNnPSIkMiIKICBsb2NhbCBkYXRlCgogIGlmIFtbIC1uICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIgXV0gJiYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPiBfX0xFVkVMX09GRikpOyB0aGVuCiAgICBkYXRlPSIkKGRhdGUgJyslWS0lbS0lZCAlSDolTTolUycpIgogICAgdG91Y2ggIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IgogICAgcHJpbnRmICIlc3wlN3N8JXNcbiIgIiR7ZGF0ZX0iICIke2xldmVsTXNnfSIgIiR7bXNnfSIgPj4iJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gY29uY2F0ZW5hdGUgMiBwYXRocyBhbmQgZW5zdXJlIHRoZSBwYXRoIGlzIGNvcnJlY3QgdXNpbmcgcmVhbHBhdGggLW0KIyBAYXJnICQxIGJhc2VQYXRoOlN0cmluZwojIEBhcmcgJDIgc3ViUGF0aDpTdHJpbmcKIyBAcmVxdWlyZSBMaW51eDo6cmVxdWlyZVJlYWxwYXRoQ29tbWFuZApGaWxlOjpjb25jYXRlbmF0ZVBhdGgoKSB7CiAgbG9jYWwgYmFzZVBhdGg9IiQxIgogIGxvY2FsIHN1YlBhdGg9IiQyIgogIGxvY2FsIGZ1bGxQYXRoPSIke2Jhc2VQYXRoOiske2Jhc2VQYXRofS99JHtzdWJQYXRofSIKCiAgcmVhbHBhdGggLW0gIiR7ZnVsbFBhdGh9IiAyPi9kZXYvbnVsbAp9CgojIEBkZXNjcmlwdGlvbiBEaXNwbGF5IG1lc3NhZ2UgdXNpbmcgZXJyb3IgY29sb3IgKHJlZCkKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpkaXNwbGF5RXJyb3IoKSB7CiAgaWYgKChCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMID49IF9fTEVWRUxfRVJST1IpKTsgdGhlbgogICAgZWNobyAtZSAiJHtfX0VSUk9SX0NPTE9SfUVSUk9SICAgLSAkezF9JHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgZmkKICBMb2c6OmxvZ0Vycm9yICIkMSIKfQoKIyBAZGVzY3JpcHRpb24gRGlzcGxheSBtZXNzYWdlIHVzaW5nIHdhcm5pbmcgY29sb3IgKHllbGxvdykKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpkaXNwbGF5V2FybmluZygpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUwgPj0gX19MRVZFTF9XQVJOSU5HKSk7IHRoZW4KICAgIGVjaG8gLWUgIiR7X19XQVJOSU5HX0NPTE9SfVdBUk4gICAgLSAkezF9JHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgZmkKICBMb2c6OmxvZ1dhcm5pbmcgIiQxIgp9CgojIEBkZXNjcmlwdGlvbiBlbnN1cmUgZW52IGZpbGVzIGFyZSBsb2FkZWQKIyBAbm9hcmdzCiMgQGV4aXRjb2RlIDEgaWYgZ2V0T3JkZXJlZENvbmZGaWxlcyBmYWlscwojIEBleGl0Y29kZSAyIGlmIG9uZSBvZiBlbnYgZmlsZXMgZmFpbHMgdG8gbG9hZAojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gaXMgZGlzcGxheWVkCkVudjo6cmVxdWlyZUxvYWQoKSB7CiAgbG9jYWwgY29uZmlnRmlsZXNTdHIKICBjb25maWdGaWxlc1N0cj0iJChFbnY6OmdldE9yZGVyZWRDb25mRmlsZXMpIiB8fCByZXR1cm4gMQoKICBsb2NhbCAtYSBjb25maWdGaWxlcwogIHJlYWRhcnJheSAtdCBjb25maWdGaWxlcyA8PDwiJHtjb25maWdGaWxlc1N0cn0iCgogICMgaWYgZW1wdHkgc3RyaW5nLCB0aGVyZSB3aWxsIGJlIG9uZSBlbGVtZW50CiAgaWYgKCgkeyNjb25maWdGaWxlc1tAXX0gPT0gMCkpIHx8IFtbIC16ICIke2NvbmZpZ0ZpbGVzU3RyfSIgXV07IHRoZW4KICAgICMgc2hvdWxkIG5vdCBoYXBwZW4sIGFzIHRoZXJlIGlzIGFsd2F5cyBkZWZhdWx0IGZpbGUKICAgIExvZzo6ZGlzcGxheVNraXBwZWQgIm5vIGVudiBmaWxlIHRvIGxvYWQiCiAgICByZXR1cm4gMAogIGZpCgogIEVudjo6bWVyZ2VDb25mRmlsZXMgIiR7Y29uZmlnRmlsZXNbQF19IiB8fCB7CiAgICBMb2c6OmRpc3BsYXlFcnJvciAid2hpbGUgbG9hZGluZyBjb25maWcgZmlsZXM6ICR7Y29uZmlnRmlsZXNbKl19IgogICAgcmV0dXJuIDIKICB9Cn0KCiMgQGRlc2NyaXB0aW9uIGFjdGl2YXRlIG9yIG5vdCBMb2c6OmRpc3BsYXkqIGFuZCBMb2c6OmxvZyogZnVuY3Rpb25zCiMgYmFzZWQgb24gQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCBhbmQgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMCiMgZW52aXJvbm1lbnQgdmFyaWFibGVzIGxvYWRlZCBieSBFbnY6OnJlcXVpcmVMb2FkCiMgdHJ5IHRvIGNyZWF0ZSBsb2cgZmlsZSBhbmQgcm90YXRlIGl0IGlmIG5lY2Vzc2FyeQojIEBub2FyZ3MKIyBAc2V0IEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCBpbnQgdG8gT0ZGIGxldmVsIGlmIEJBU0hfRlJBTUVXT1JLX0xPR19GSUxFIGlzIGVtcHR5IG9yIG5vdCB3cml0YWJsZQojIEBlbnYgQkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTCBpbnQKIyBAZW52IEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCBpbnQKIyBAZW52IEJBU0hfRlJBTUVXT1JLX0xPR19GSUxFIFN0cmluZwojIEBlbnYgQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEVfTUFYX1JPVEFUSU9OIGludCBkbyBsb2cgcm90YXRpb24gaWYgPiAwCiMgQGV4aXRjb2RlIDAgYWx3YXlzIHN1Y2Nlc3NmdWwKIyBAc3RkZXJyIGRpYWdub3N0aWNzIGluZm9ybWF0aW9uIGFib3V0IGxvZyBmaWxlIGlzIGRpc3BsYXllZAojIEByZXF1aXJlIEVudjo6cmVxdWlyZUxvYWQKIyBAcmVxdWlyZSBVSTo6cmVxdWlyZVRoZW1lCkxvZzo6cmVxdWlyZUxvYWQoKSB7CiAgaWYgW1sgLXogIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEU6LX0iIF1dOyB0aGVuCiAgICBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUw9JHtfX0xFVkVMX09GRn0KICAgIGV4cG9ydCBCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwKICBmaQoKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTCA+IF9fTEVWRUxfT0ZGKSk7IHRoZW4KICAgIGlmIFtbICEgLWYgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiBdXTsgdGhlbgogICAgICBpZgogICAgICAgICEgbWtkaXIgLXAgIiQoZGlybmFtZSAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iKSIgMj4vZGV2L251bGwgfHwKICAgICAgICAgICEgdG91Y2ggLS1uby1jcmVhdGUgIiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IiAyPi9kZXYvbnVsbAogICAgICB0aGVuCiAgICAgICAgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMPSR7X19MRVZFTF9PRkZ9CiAgICAgICAgZWNobyAtZSAiJHtfX0VSUk9SX0NPTE9SfUVSUk9SICAgLSBGaWxlICR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEV9IGlzIG5vdCB3cml0YWJsZSR7X19SRVNFVF9DT0xPUn0iID4mMgogICAgICBmaQogICAgZWxpZiBbWyAhIC13ICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSIgXV07IHRoZW4KICAgICAgQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMPSR7X19MRVZFTF9PRkZ9CiAgICAgIGVjaG8gLWUgIiR7X19FUlJPUl9DT0xPUn1FUlJPUiAgIC0gRmlsZSAke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSBpcyBub3Qgd3JpdGFibGUke19fUkVTRVRfQ09MT1J9IiA+JjIKICAgIGZpCgogIGZpCgogIGlmICgoQkFTSF9GUkFNRVdPUktfTE9HX0xFVkVMID4gX19MRVZFTF9PRkYpKTsgdGhlbgogICAgIyB3aWxsIGFsd2F5cyBiZSBjcmVhdGVkIGV2ZW4gaWYgbm90IGluIGluZm8gbGV2ZWwKICAgIExvZzo6bG9nTWVzc2FnZSAiSU5GTyIgIkxvZ2dpbmcgdG8gZmlsZSAke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFfSAtIExvZyBsZXZlbCAke0JBU0hfRlJBTUVXT1JLX0xPR19MRVZFTH0iCiAgICBpZiAoKEJBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTiA+IDApKTsgdGhlbgogICAgICBMb2c6OnJvdGF0ZSAiJHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRX0iICIke0JBU0hfRlJBTUVXT1JLX0xPR19GSUxFX01BWF9ST1RBVElPTn0iCiAgICBmaQogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGdldCBsaXN0IG9mIGVudiBmaWxlcyB0byBsb2FkCiMgaW4gb3JkZXIgdG8gbWFrZSB0aGVtIGF2YWlsYWJsZSBmb3IgRW52OjpyZXF1aXJlTG9hZAojIEBlbnYgQkFTSF9GUkFNRVdPUktfRU5WX0ZJTEVTIFN0cmluZ1tdIGxpc3Qgb2YgZW52IGZpbGVzIHRoYXQgc2hvdWxkIGJlIGxvYWRlZAojIEBleGl0Y29kZSAxIGlmIG9uZSBvZiB0aGUgZW52IGZpbGUgY2Fubm90IGJlIGdlbmVyYXRlZAojIEBleGl0Y29kZSAyIGlmIG9uZSBvZiB0aGUgZW52IGZpbGUgaXMgbm90IGEgZmlsZSBvciByZWFkYWJsZQojIEBzdGRvdXQgdGhlIGVudiBmaWxlcyBhc2tlZCB0byBiZSBsb2FkZWQKIyBAc3RkZXJyIGRpYWdub3N0aWMgaW5mb3JtYXRpb24gb24gZmFpbHVyZQojIEBzZWUgaHR0cHM6Ly9naXRodWIuY29tL2ZjaGFzdGFuZXQvYmFzaC10b29scy1mcmFtZXdvcmsvYmxvYi9tYXN0ZXIvRnJhbWV3b3JrRG9jLm1kI2NvbmZpZ19maWxlX29yZGVyCkVudjo6Z2V0T3JkZXJlZENvbmZGaWxlcygpIHsKICBsb2NhbCAtYSBjb25maWdGaWxlcz0oKQoKICBpZiBbWyAtbiAiJHtCQVNIX0ZSQU1FV09SS19FTlZfRklMRVNbMF0rMX0iIF1dOyB0aGVuCiAgICAjIEJBU0hfRlJBTUVXT1JLX0VOVl9GSUxFUyBpcyBhbiBhcnJheQogICAgY29uZmlnRmlsZXMrPSgiJHtCQVNIX0ZSQU1FV09SS19FTlZfRklMRVNbQF19IikKICBmaQoKICBsb2NhbCBkZWZhdWx0RW52RmlsZQogIGRlZmF1bHRFbnZGaWxlPSIkKEVudjo6Y3JlYXRlRGVmYXVsdEVudkZpbGUpIiB8fCByZXR1cm4gMQogIGNvbmZpZ0ZpbGVzKz0oIiR7ZGVmYXVsdEVudkZpbGV9IikKCiAgbG9jYWwgZmlsZQogIGZvciBmaWxlIGluICIke2NvbmZpZ0ZpbGVzW0BdfSI7IGRvCiAgICBpZiBbWyAhIC1mICIke2ZpbGV9IiB8fCAhIC1yICIke2ZpbGV9IiBdXTsgdGhlbgogICAgICBMb2c6OmRpc3BsYXlFcnJvciAiT25lIG9mIHRoZSBjb25maWcgZmlsZSBpcyBub3QgYXZhaWxhYmxlICcke2ZpbGV9JyIKICAgICAgcmV0dXJuIDIKICAgIGZpCiAgICBlY2hvICIke2ZpbGV9IgogIGRvbmUKfQoKIyBAZGVzY3JpcHRpb24gbWVyZ2UgYW5kIGxvYWQgY29uZiBmaWxlcyBzcGVjaWZpZWQgYXMgYXJndW1lbnQKIyAtIGZpbGVzIGFyZSBjbGVhbmVkIGZyb20gYXkgY29tbWVudAojIC0gbWlzc2luZyBxdW90ZXMgYWZ0ZXIgcHJvcGVydHkgPSBzaWduIGFyZSBhZGRlZCBhdXRvbWF0aWNhbGx5CiMgLSBhdXRvbWF0aWMgcmVtb3ZlIG9mIGFsbCB3aGl0ZXNwYWNlIGJlZm9yZSBhbmQgYWZ0ZXIgZGVjbGFyYXRpb25zCiMgLSBiYXNoIGFycmF5cyBhcmUgbm90IHN1cHBvcnRlZAojIC0gaWYgYSB2YXJpYWJsZSBpcyBkZWNsYXJlZCBpbiBmaXJzdCBmaWxlIGFuZCBvdmVycmlkZGVuIGxhdGVyIG9uCiMgICBpbiB0aGUgc2FtZSBmaWxlIG9yIGluIHN1YnNlcXVlbnQgZmlsZXMsIHRob3NlIG92ZXJsb2FkcyB3aWxsIGJlCiMgICBpZ25vcmVkCiMgQHdhcm5pbmcgaWYgYW4gZXJyb3Igb2NjdXJzIHdoaWxlIGxvYWRpbmcgb25lIG9mIHRoZSBjb25maWcgZmlsZSwgZXhpdCBjb2RlIDMgYnV0IGVudmlyb25tZW50IGNvdWxkIGJlIHBhcnRpYWxseSBsb2FkZWQKIyBAYXJnICRAIGFyZ3M6U3RyaW5nW10gbGlzdCBvZiBjb25maWd1cmF0aW9uIGZpbGVzIHRvIGxvYWQgaW4gb3JkZXIKIyBAc2V0IGVudlZhcnMgU3RyaW5nIHdpbGwgc2V0IGluIGVudmlyb25tZW50IGFsbCB0aGUgdmFyaWFibGVzIHRoYXQgaGF2ZSBiZWVuIGRlY2xhcmVkIGluIHRoZSBjb25maWcgZmlsZXMKIyBAZW52IGVudlZhcnMgU3RyaW5nIHRoZSBlbnYgdmFyaWFibGVzIG9mIHRoZSBjdXJyZW50IHNjcmlwdCBjb3VsZCBiZSB1c2VkIHRvIGludGVycHJldCB2YXJpYWJsZXMgZHVyaW5nIGNvbmZpZyBmaWxlcyBwYXJzaW5nCiMgQGV4aXRjb2RlIDAgaWYgbm8gY29uZmlnIGZpbGVzIHByb3ZpZGVkIG9yIGxvYWQgY29tcGxldGVkIHN1Y2Nlc3NmdWxseQojIEBleGl0Y29kZSAxIGlmIGVycm9yIG9jY3VycmVkIGR1cmluZyBwYXJzaW5nIHRoZSBjb25maWcgZmlsZXMgKGZpbGUgbm90IGZvdW5kLCBncmVwLCBhd2sgb3Igc2VkIGVycm9yKQojIEBleGl0Y29kZSAyIGlmIHRlbXBvcmFyeSBmaWxlIGNhbm5vdCBiZSBjcmVhdGVkCiMgQGV4aXRjb2RlIDMgaWYgYW4gZXJyb3Igb2NjdXJyZWQgZHVyaW5nIGNvbmZpZyBmaWxlIHNvdXJjaW5nCiMgQHN0ZGVyciBkaWFnbm9zdGljcyBpbmZvcm1hdGlvbiBpcyBkaXNwbGF5ZWQKIyBAc2VlIGxhcmdlbHkgaW5zcGlyZWQgYnV0IG1vZGlmaWVkIGZyb20gaHR0cHM6Ly9vcGVuc291cmNlLmNvbS9hcnRpY2xlLzIxLzUvcHJvY2Vzc2luZy1jb25maWd1cmF0aW9uLWZpbGVzLXNoZWxsCkVudjo6bWVyZ2VDb25mRmlsZXMoKSB7CiAgbG9jYWwgLWEgY29uZmlnRmlsZUxpc3Q9KCIkQCIpCgogIGlmICgoJHsjY29uZmlnRmlsZUxpc3RbQF19ID09IDApKTsgdGhlbgogICAgcmV0dXJuIDAKICBmaQoKICBsb2NhbCBjb21iaW5lZENvbmZpZ0ZpbGUKICBjb21iaW5lZENvbmZpZ0ZpbGU9IiQoRnJhbWV3b3JrOjpjcmVhdGVUZW1wRmlsZSAibWVyZ2VDb25mRmlsZXMiKSIgfHwgcmV0dXJuIDIKCiAgKAogICAgIyByZW1vdmVzIGFueSB0cmFpbGluZyB3aGl0ZXNwYWNlIGZyb20gZWFjaCBmaWxlLCBpZiBhbnkKICAgICMgdGhpcyBpcyBhYnNvbHV0ZWx5IHJlcXVpcmVkIHdoZW4gaW1wb3J0aW5nIGludG8gQ29uZmlnTWFwcwogICAgIyBwdXQgcXVvdGVzIGFyb3VuZCB2YWx1ZXMKICAgIHNlZCAtRSAtZSAkJ3MvXHMqJC8vIDsgL14kL2QgOyAvXiMuKiQvZCA7IHMvPShbXiJcJ10uKikkLz0iXFwxIi8nICIke2NvbmZpZ0ZpbGVMaXN0W0BdfSIgfAogICAgICAjIHJlbW92ZSBhbGwgY29tbWVudCBsaW5lcwogICAgICBGaWx0ZXJzOjpjb21tZW50TGluZXMgfAogICAgICAjIGl0ZXJhdGVzIG92ZXIgZWFjaCBmaWxlIGFuZCBwcmludHMgKGRlZmF1bHQgYXdrIGJlaGF2aW9yKQogICAgICAjIGVhY2ggdW5pcXVlIGxpbmU7IG9ubHkgdGFrZXMgZmlyc3QgdmFsdWUgYW5kIGlnbm9yZXMgZHVwbGljYXRlcwogICAgICBhd2sgLUY9ICchbGluZVskMV0rKycKICApID4iJHtjb21iaW5lZENvbmZpZ0ZpbGV9IiB8fCByZXR1cm4gMQoKICAjIGhhdmUgdG8gZXhwb3J0IGV2ZXJ5dGhpbmcsIGFuZCBzb3VyY2UgaXQgdHdpY2U6CiAgIyAxKSBmaXJzdCBzb3VyY2UgaXMgdG8gcmVhbGl6ZSB2YXJpYWJsZXMKICAjIDIpIHNlY29uZCB0aW1lIGlzIHRvIHJlYWxpemUgcmVmZXJlbmNlcwogIHNldCAtbyBhbGxleHBvcnQKICAjIHNoZWxsY2hlY2sgc291cmNlPS5mcmFtZXdvcmstY29uZmlnCiAgc291cmNlICIke2NvbWJpbmVkQ29uZmlnRmlsZX0iIHx8IHJldHVybiAzCiAgIyBzaGVsbGNoZWNrIHNvdXJjZT0uZnJhbWV3b3JrLWNvbmZpZwogIHNvdXJjZSAiJHtjb21iaW5lZENvbmZpZ0ZpbGV9IiB8fCByZXR1cm4gMwogIHNldCArbyBhbGxleHBvcnQKfQoKIyBAZGVzY3JpcHRpb24gRGlzcGxheSBtZXNzYWdlIHVzaW5nIHNraXAgY29sb3IgKHllbGxvdykKIyBAYXJnICQxIG1lc3NhZ2U6U3RyaW5nIHRoZSBtZXNzYWdlIHRvIGRpc3BsYXkKTG9nOjpkaXNwbGF5U2tpcHBlZCgpIHsKICBpZiAoKEJBU0hfRlJBTUVXT1JLX0RJU1BMQVlfTEVWRUwgPj0gX19MRVZFTF9JTkZPKSk7IHRoZW4KICAgIGVjaG8gLWUgIiR7X19TS0lQUEVEX0NPTE9SfVNLSVBQRUQgLSAkezF9JHtfX1JFU0VUX0NPTE9SfSIgPiYyCiAgZmkKICBMb2c6OmxvZ1NraXBwZWQgIiQxIgp9CgojIEBkZXNjcmlwdGlvbiBsb2cgbWVzc2FnZSB0byBmaWxlCiMgQGFyZyAkMSBtZXNzYWdlOlN0cmluZyB0aGUgbWVzc2FnZSB0byBkaXNwbGF5CkxvZzo6bG9nRXJyb3IoKSB7CiAgaWYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPj0gX19MRVZFTF9FUlJPUikpOyB0aGVuCiAgICBMb2c6OmxvZ01lc3NhZ2UgIiR7MjotRVJST1J9IiAiJDEiCiAgZmkKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ1dhcm5pbmcoKSB7CiAgaWYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPj0gX19MRVZFTF9XQVJOSU5HKSk7IHRoZW4KICAgIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1XQVJOSU5HfSIgIiQxIgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIFRvIGJlIGNhbGxlZCBiZWZvcmUgbG9nZ2luZyBpbiB0aGUgbG9nIGZpbGUKIyBAYXJnICQxIGZpbGU6c3RyaW5nIGxvZyBmaWxlIG5hbWUKIyBAYXJnICQyIG1heExvZ0ZpbGVzQ291bnQ6aW50IG1heGltdW0gbnVtYmVyIG9mIGxvZyBmaWxlcwpMb2c6OnJvdGF0ZSgpIHsKICBsb2NhbCBmaWxlPSIkMSIKICBsb2NhbCBtYXhMb2dGaWxlc0NvdW50PSIkezI6LTV9IgoKICBpZiBbWyAhIC1mICIke2ZpbGV9IiBdXTsgdGhlbgogICAgTG9nOjpkaXNwbGF5U2tpcHBlZCAiTG9nIGZpbGUgJHtmaWxlfSBkb2Vzbid0IGV4aXN0IHlldCIKICAgIHJldHVybiAwCiAgZmkKICBmb3IgaSBpbiAkKHNlcSAkKChtYXhMb2dGaWxlc0NvdW50IC0gMSkpIC0xIDEpOyBkbwogICAgTG9nOjpkaXNwbGF5SW5mbyAiTG9nIHJvdGF0aW9uICR7ZmlsZX0uJHtpfSB0byAke2ZpbGV9LiQoKGkgKyAxKSkiCiAgICBtdiAiJHtmaWxlfS4ieyIke2l9IiwiJCgoaSArIDEpKSJ9ICY+L2Rldi9udWxsIHx8IHRydWUKICBkb25lCiAgaWYgY3AgIiR7ZmlsZX0iICIke2ZpbGV9LjEiICY+L2Rldi9udWxsOyB0aGVuCiAgICBlY2hvID4iJHtmaWxlfSIgIyByZXNldCBsb2cgZmlsZQogICAgTG9nOjpkaXNwbGF5SW5mbyAiTG9nIHJvdGF0aW9uICR7ZmlsZX0gdG8gJHtmaWxlfS4xIgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGVuc3VyZSBjb21tYW5kIHJlYWxwYXRoIGlzIGF2YWlsYWJsZQojIEBleGl0Y29kZSAxIGlmIHJlYWxwYXRoIGNvbW1hbmQgbm90IGF2YWlsYWJsZQojIEBzdGRlcnIgZGlhZ25vc3RpY3MgaW5mb3JtYXRpb24gaXMgZGlzcGxheWVkCkxpbnV4OjpyZXF1aXJlUmVhbHBhdGhDb21tYW5kKCkgewogIEFzc2VydDo6Y29tbWFuZEV4aXN0cyByZWFscGF0aAp9CgojIEBkZXNjcmlwdGlvbiBsb2FkIGNvbG9yIHRoZW1lCiMgQG5vYXJncwojIEBlbnYgQkFTSF9GUkFNRVdPUktfVEhFTUUgU3RyaW5nIHRoZW1lIHRvIHVzZQojIEBleGl0Y29kZSAwIGFsd2F5cyBzdWNjZXNzZnVsClVJOjpyZXF1aXJlVGhlbWUoKSB7CiAgVUk6OnRoZW1lICIke0JBU0hfRlJBTUVXT1JLX1RIRU1FLWRlZmF1bHR9Igp9CgojIEBkZXNjcmlwdGlvbiBjaGVjayBpZiBjb21tYW5kIHNwZWNpZmllZCBleGlzdHMgb3IgcmV0dXJuIDEKIyB3aXRoIGVycm9yIGFuZCBtZXNzYWdlIGlmIG5vdAojCiMgQGFyZyAkMSBjb21tYW5kTmFtZTpTdHJpbmcgb24gd2hpY2ggZXhpc3RlbmNlIG11c3QgYmUgY2hlY2tlZAojIEBhcmcgJDIgaGVscElmTm90RXhpc3RzOlN0cmluZyBhIGhlbHAgY29tbWFuZCB0byBkaXNwbGF5IGlmIHRoZSBjb21tYW5kIGRvZXMgbm90IGV4aXN0CiMKIyBAZXhpdGNvZGUgMSBpZiB0aGUgY29tbWFuZCBzcGVjaWZpZWQgZG9lcyBub3QgZXhpc3QKIyBAc3RkZXJyIGRpYWdub3N0aWMgaW5mb3JtYXRpb24gKyBoZWxwIGlmIHNlY29uZCBhcmd1bWVudCBpcyBwcm92aWRlZApBc3NlcnQ6OmNvbW1hbmRFeGlzdHMoKSB7CiAgbG9jYWwgY29tbWFuZE5hbWU9IiQxIgogIGxvY2FsIGhlbHBJZk5vdEV4aXN0cz0iJDIiCgogICIke0JBU0hfRlJBTUVXT1JLX0NPTU1BTkQ6LWNvbW1hbmR9IiAtdiAiJHtjb21tYW5kTmFtZX0iID4vZGV2L251bGwgMj4vZGV2L251bGwgfHwgewogICAgTG9nOjpkaXNwbGF5RXJyb3IgIiR7Y29tbWFuZE5hbWV9IGlzIG5vdCBpbnN0YWxsZWQsIHBsZWFzZSBpbnN0YWxsIGl0IgogICAgaWYgW1sgLW4gIiR7aGVscElmTm90RXhpc3RzfSIgXV07IHRoZW4KICAgICAgTG9nOjpkaXNwbGF5SW5mbyAiJHtoZWxwSWZOb3RFeGlzdHN9IgogICAgZmkKICAgIHJldHVybiAxCiAgfQogIHJldHVybiAwCn0KCiMgQGRlc2NyaXB0aW9uIGRlZmF1bHQgZW52IGZpbGUgd2l0aCBhbGwgZGVmYXVsdCB2YWx1ZXMKIyBAc3Rkb3V0IHRoZSBkZWZhdWx0IGVudiBmaWxlcGF0aApFbnY6OmNyZWF0ZURlZmF1bHRFbnZGaWxlKCkgewogIGxvY2FsIGVudkZpbGUKICBlbnZGaWxlPSIkKEZyYW1ld29yazo6Y3JlYXRlVGVtcEZpbGUgImNyZWF0ZURlZmF1bHRFbnZGaWxlRW52RmlsZSIpIiB8fCByZXR1cm4gMgoKICAoCiAgICBlY2hvICJCQVNIX0ZSQU1FV09SS19USEVNRT0ke0JBU0hfRlJBTUVXT1JLX1RIRU1FOi1kZWZhdWx0fSIKICAgIGVjaG8gIkJBU0hfRlJBTUVXT1JLX0xPR19MRVZFTD0ke0JBU0hfRlJBTUVXT1JLX0xPR19MRVZFTDotMH0iCiAgICBlY2hvICJCQVNIX0ZSQU1FV09SS19ESVNQTEFZX0xFVkVMPSR7QkFTSF9GUkFNRVdPUktfRElTUExBWV9MRVZFTDotJHtfX0xFVkVMX1dBUk5JTkd9fSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjAxNgogICAgZWNobyAnQkFTSF9GUkFNRVdPUktfTE9HX0ZJTEU9IiR7QkFTSF9GUkFNRVdPUktfTE9HX0ZJTEU6LSIke0ZSQU1FV09SS19ST09UX0RJUn0vbG9ncy8ke1NDUklQVF9OQU1FfS5sb2cifSInCiAgICBlY2hvICJCQVNIX0ZSQU1FV09SS19MT0dfRklMRV9NQVhfUk9UQVRJT049JHtCQVNIX0ZSQU1FV09SS19MT0dfRklMRV9NQVhfUk9UQVRJT046LTV9IgogICkgPiIke2VudkZpbGV9IgogIGVjaG8gIiR7ZW52RmlsZX0iCn0KCiMgQGRlc2NyaXB0aW9uIHJlbW92ZSBjb21tZW50IGxpbmVzIGZyb20gaW5wdXQgb3IgZmlsZXMgcHJvdmlkZWQgYXMgYXJndW1lbnRzCiMgQGFyZyAkQCBmaWxlczpTdHJpbmdbXSAob3B0aW9uYWwpIHRoZSBmaWxlcyB0byBmaWx0ZXIKIyBAZW52IGNvbW1lbnRMaW5lUHJlZml4IFN0cmluZyB0aGUgY29tbWVudCBsaW5lIHByZWZpeCAoZGVmYXVsdCB2YWx1ZTogIykKIyBAZXhpdGNvZGUgMCBpZiBsaW5lcyBmaWx0ZXJlZCBvciBub3QKIyBAZXhpdGNvZGUgMiBpZiBncmVwIGZhaWxzIGZvciBhbnkgb3RoZXIgcmVhc29ucyB0aGFuIG5vdCBmb3VuZAojIEBzdGRpbiB0aGUgZmlsZSBhcyBzdGRpbiB0byBmaWx0ZXIgKGFsdGVybmF0aXZlIHRvIGZpbGVzIGFyZ3VtZW50KQojIEBzdGRvdXQgdGhlIGZpbHRlcmVkIGxpbmVzCiMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjEyMApGaWx0ZXJzOjpjb21tZW50TGluZXMoKSB7CiAgZ3JlcCAtdnhFICJbWzpibGFuazpdXSooJHtjb21tZW50TGluZVByZWZpeDotI30uKik/IiAiJEAiIHx8IHRlc3QgJD8gPSAxCn0KCiMgQGRlc2NyaXB0aW9uIGNyZWF0ZSBhIHRlbXAgZmlsZSB1c2luZyBkZWZhdWx0IFRNUERJUiB2YXJpYWJsZQojIGluaXRpYWxpemVkIGluIF9pbmNsdWRlcy9fY29tbW9uSGVhZGVyLnNoCiMgQGVudiBUTVBESVIgU3RyaW5nIChkZWZhdWx0IHZhbHVlIC90bXApCiMgQGFyZyAkMSB0ZW1wbGF0ZU5hbWU6U3RyaW5nIHRlbXBsYXRlIG5hbWUgdG8gdXNlKG9wdGlvbmFsKQpGcmFtZXdvcms6OmNyZWF0ZVRlbXBGaWxlKCkgewogIG1rdGVtcCAtcCAiJHtUTVBESVI6LS90bXB9IiAtdCAiJHsxOi19LlhYWFhYWFhYWFhYWCIKfQoKIyBAZGVzY3JpcHRpb24gbG9nIG1lc3NhZ2UgdG8gZmlsZQojIEBhcmcgJDEgbWVzc2FnZTpTdHJpbmcgdGhlIG1lc3NhZ2UgdG8gZGlzcGxheQpMb2c6OmxvZ1NraXBwZWQoKSB7CiAgaWYgKChCQVNIX0ZSQU1FV09SS19MT0dfTEVWRUwgPj0gX19MRVZFTF9JTkZPKSk7IHRoZW4KICAgIExvZzo6bG9nTWVzc2FnZSAiJHsyOi1TS0lQUEVEfSIgIiQxIgogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGxvYWQgY29sb3JzIHRoZW1lIGNvbnN0YW50cwojIEB3YXJuaW5nIGlmIHR0eSBub3Qgb3BlbmVkLCBub0NvbG9yIHRoZW1lIHdpbGwgYmUgY2hvc2VuCiMgQGFyZyAkMSB0aGVtZTpTdHJpbmcgdGhlIHRoZW1lIHRvIHVzZSAoZGVmYXVsdCwgbm9Db2xvcikKIyBAYXJnICRAIGFyZ3M6U3RyaW5nW10KIyBAc2V0IF9fRVJST1JfQ09MT1IgU3RyaW5nIGluZGljYXRlIGVycm9yIHN0YXR1cwojIEBzZXQgX19JTkZPX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSBpbmZvIHN0YXR1cwojIEBzZXQgX19TVUNDRVNTX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSBzdWNjZXNzIHN0YXR1cwojIEBzZXQgX19XQVJOSU5HX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSB3YXJuaW5nIHN0YXR1cwojIEBzZXQgX19TS0lQUEVEX0NPTE9SIFN0cmluZyBpbmRpY2F0ZSBza2lwcGVkIHN0YXR1cwojIEBzZXQgX19ERUJVR19DT0xPUiBTdHJpbmcgaW5kaWNhdGUgZGVidWcgc3RhdHVzCiMgQHNldCBfX0hFTFBfQ09MT1IgU3RyaW5nIGluZGljYXRlIGhlbHAgc3RhdHVzCiMgQHNldCBfX1RFU1RfQ09MT1IgU3RyaW5nIG5vdCB1c2VkCiMgQHNldCBfX1RFU1RfRVJST1JfQ09MT1IgU3RyaW5nIG5vdCB1c2VkCiMgQHNldCBfX0hFTFBfVElUTEVfQ09MT1IgU3RyaW5nIHVzZWQgdG8gZGlzcGxheSBoZWxwIHRpdGxlIGluIGhlbHAgc3RyaW5ncwojIEBzZXQgX19IRUxQX09QVElPTl9DT0xPUiBTdHJpbmcgdXNlZCB0byBkaXNwbGF5IGhpZ2hsaWdodCBvcHRpb25zIGluIGhlbHAgc3RyaW5ncwojCiMgQHNldCBfX1JFU0VUX0NPTE9SIFN0cmluZyByZXNldCBkZWZhdWx0IGNvbG9yCiMKIyBAc2V0IF9fSEVMUF9FWEFNUExFIFN0cmluZyB0byByZW1vdmUKIyBAc2V0IF9fSEVMUF9USVRMRSBTdHJpbmcgdG8gcmVtb3ZlCiMgQHNldCBfX0hFTFBfTk9STUFMIFN0cmluZyB0byByZW1vdmUKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMDM0ClVJOjp0aGVtZSgpIHsKICBsb2NhbCB0aGVtZT0iJHsxLWRlZmF1bHR9IgogIGlmIFtbICEgIiR7dGhlbWV9IiA9fiAtZm9yY2UkIF1dICYmICEgQXNzZXJ0Ojp0dHk7IHRoZW4KICAgIHRoZW1lPSJub0NvbG9yIgogIGZpCiAgY2FzZSAiJHt0aGVtZX0iIGluCiAgICBkZWZhdWx0IHwgZGVmYXVsdC1mb3JjZSkKICAgICAgdGhlbWU9ImRlZmF1bHQiCiAgICAgIDs7CiAgICBub0NvbG9yKSA7OwogICAgKikKICAgICAgTG9nOjpmYXRhbCAiaW52YWxpZCB0aGVtZSBwcm92aWRlZCIKICAgICAgOzsKICBlc2FjCiAgaWYgW1sgIiR7dGhlbWV9IiA9ICJkZWZhdWx0IiBdXTsgdGhlbgogICAgQkFTSF9GUkFNRVdPUktfVEhFTUU9ImRlZmF1bHQiCiAgICAjIGNoZWNrIGNvbG9ycyBhcHBsaWNhYmxlIGh0dHBzOi8vbWlzYy5mbG9naXNvZnQuY29tL2Jhc2gvdGlwX2NvbG9yc19hbmRfZm9ybWF0dGluZwogICAgX19FUlJPUl9DT0xPUj0nXGVbMzFtJyAgICAgICAgICMgUmVkCiAgICBfX0lORk9fQ09MT1I9J1xlWzQ0bScgICAgICAgICAgIyB3aGl0ZSBvbiBsaWdodEJsdWUKICAgIF9fU1VDQ0VTU19DT0xPUj0nXGVbMzJtJyAgICAgICAjIEdyZWVuCiAgICBfX1dBUk5JTkdfQ09MT1I9J1xlWzMzbScgICAgICAgIyBZZWxsb3cKICAgIF9fU0tJUFBFRF9DT0xPUj0nXGVbMzNtJyAgICAgICAjIFllbGxvdwogICAgX19ERUJVR19DT0xPUj0nXGVbMzdtJyAgICAgICAgICMgR3JleQogICAgX19IRUxQX0NPTE9SPSdcZVs3OzQ5OzMzbScgICAgICMgQmxhY2sgb24gR29sZAogICAgX19URVNUX0NPTE9SPSdcZVsxMDBtJyAgICAgICAgICMgTGlnaHQgbWFnZW50YQogICAgX19URVNUX0VSUk9SX0NPTE9SPSdcZVs0MW0nICAgICMgd2hpdGUgb24gcmVkCiAgICBfX0hFTFBfVElUTEVfQ09MT1I9IlxlWzE7MzdtIiAgIyBCb2xkCiAgICBfX0hFTFBfT1BUSU9OX0NPTE9SPSJcZVsxOzM0bSIgIyBCbHVlCiAgICAjIEludGVybmFsOiByZXNldCBjb2xvcgogICAgX19SRVNFVF9DT0xPUj0nXGVbMG0nICMgUmVzZXQgQ29sb3IKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE1NSxTQzIwMzQKICAgIF9fSEVMUF9FWEFNUExFPSIkKGVjaG8gLWUgIlxlWzI7OTdtIikiCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzIxNTUsU0MyMDM0CiAgICBfX0hFTFBfVElUTEU9IiQoZWNobyAtZSAiXGVbMTszN20iKSIKICAgICMgc2hlbGxjaGVjayBkaXNhYmxlPVNDMjE1NSxTQzIwMzQKICAgIF9fSEVMUF9OT1JNQUw9IiQoZWNobyAtZSAiXDAzM1swbSIpIgogIGVsc2UKICAgIEJBU0hfRlJBTUVXT1JLX1RIRU1FPSJub0NvbG9yIgogICAgIyBjaGVjayBjb2xvcnMgYXBwbGljYWJsZSBodHRwczovL21pc2MuZmxvZ2lzb2Z0LmNvbS9iYXNoL3RpcF9jb2xvcnNfYW5kX2Zvcm1hdHRpbmcKICAgIF9fRVJST1JfQ09MT1I9JycKICAgIF9fSU5GT19DT0xPUj0nJwogICAgX19TVUNDRVNTX0NPTE9SPScnCiAgICBfX1dBUk5JTkdfQ09MT1I9JycKICAgIF9fU0tJUFBFRF9DT0xPUj0nJwogICAgX19ERUJVR19DT0xPUj0nJwogICAgX19IRUxQX0NPTE9SPScnCiAgICBfX1RFU1RfQ09MT1I9JycKICAgIF9fVEVTVF9FUlJPUl9DT0xPUj0nJwogICAgX19IRUxQX1RJVExFX0NPTE9SPScnCiAgICBfX0hFTFBfT1BUSU9OX0NPTE9SPScnCiAgICAjIEludGVybmFsOiByZXNldCBjb2xvcgogICAgX19SRVNFVF9DT0xPUj0nJwogICAgX19IRUxQX0VYQU1QTEU9JycKICAgIF9fSEVMUF9USVRMRT0nJwogICAgX19IRUxQX05PUk1BTD0nJwogIGZpCn0KCiMgQGRlc2NyaXB0aW9uIGNoZWNrIGlmIHR0eSAoaW50ZXJhY3RpdmUgbW9kZSkgaXMgYWN0aXZlCiMgQG5vYXJncwojIEBleGl0Y29kZSAxIGlmIHR0eSBub3QgYWN0aXZlCiMgQGVudiBOT05fSU5URVJBQ1RJVkUgaWYgMSBjb25zaWRlciBhcyBub3QgaW50ZXJhY3RpdmUgZXZlbiBpZiBlbnZpcm9ubWVudCBpcyBpbnRlcmFjdGl2ZQojIEBlbnYgSU5URVJBQ1RJVkUgaWYgMSBjb25zaWRlciBhcyBpbnRlcmFjdGl2ZSBldmVuIGlmIGVudmlyb25tZW50IGlzIG5vdCBpbnRlcmFjdGl2ZQojIEBzdGRlcnIgZGlhZ25vc3RpYyBpbmZvcm1hdGlvbiArIGhlbHAgaWYgc2Vjb25kIGFyZ3VtZW50IGlzIHByb3ZpZGVkCkFzc2VydDo6dHR5KCkgewogIGlmIFtbICIke05PTl9JTlRFUkFDVElWRTotMH0iID0gIjEiIF1dOyB0aGVuCiAgICByZXR1cm4gMQogIGZpCiAgaWYgW1sgIiR7SU5URVJBQ1RJVkU6LTB9IiA9ICIxIiBdXTsgdGhlbgogICAgcmV0dXJuIDAKICBmaQogIFtbIC10IDEgfHwgLXQgMiBdXQp9CgojIEZVTkNUSU9OUwoKZmFjYWRlX21haW5fZW1iZWRGcmFtZXdvcmtGdW5jdGlvbmJpbkZpbGV0cGwoKSB7CiMgUkVRVUlSRVMKTGludXg6OnJlcXVpcmVFeGVjdXRlZEFzVXNlcgpFbnY6OnJlcXVpcmVMb2FkCkxvZzo6cmVxdWlyZUxvYWQKTGludXg6OnJlcXVpcmVSZWFscGF0aENvbW1hbmQKVUk6OnJlcXVpcmVUaGVtZQpDb21waWxlcjo6RmFjYWRlOjpyZXF1aXJlQ29tbWFuZEJpbkRpcgoKIyBAcmVxdWlyZSBDb21waWxlcjo6RmFjYWRlOjpyZXF1aXJlQ29tbWFuZEJpbkRpcgoKIyBzaGVsbGNoZWNrIGRpc2FibGU9U0MyMTU0LFNDMjAxNgpmdW5jdGlvblRvQ2FsbD0nRGI6OnF1ZXJ5T25lRGF0YWJhc2UnCiIke2Z1bmN0aW9uVG9DYWxsfSIgIiRAIgoKfQoKZmFjYWRlX21haW5fZW1iZWRGcmFtZXdvcmtGdW5jdGlvbmJpbkZpbGV0cGwgIiRAIgo=" Compiler::Embed::extractFileFromBase64 \ "${embed_function_DbQueryOneDatabase}" \ diff --git a/bin/doc b/bin/doc index 1a773670..fcf0212d 100755 --- a/bin/doc +++ b/bin/doc @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management @@ -1636,10 +1640,13 @@ updateArgListTraceVerboseCallback() { BASH_FRAMEWORK_ARGV_FILTERED+=(-vvv) } +docCommand parse "${BASH_FRAMEWORK_ARGV[@]}" + run() { if [[ "${IN_BASH_DOCKER:-}" != "You're in docker" ]]; then DOCKER_RUN_OPTIONS=$"-e ORIGINAL_DOC_DIR=${DOC_DIR}" \ - "${COMMAND_BIN_DIR}/runBuildContainer" "/bash/bin/doc" "${RUN_CONTAINER_ARGV_FILTERED[@]}" + "${COMMAND_BIN_DIR}/runBuildContainer" "/bash/bin/doc" \ + "${RUN_CONTAINER_ARGV_FILTERED[@]}" return $? fi @@ -1669,7 +1676,7 @@ run() { ShellDoc::generateMdFileFromTemplate \ "${BASH_TOOLS_ROOT_DIR}/Commands.tmpl.md" \ "${DOC_DIR}/Commands.md" \ - "${FRAMEWORK_BIN_DIR}" \ + "${BASH_TOOLS_ROOT_DIR}/bin" \ TOKEN_NOT_FOUND_COUNT \ '(bash-tpl|plantuml|definitionLint|compile|installFacadeExample)$' diff --git a/bin/dockerLint b/bin/dockerLint deleted file mode 100755 index 03b9d49e..00000000 --- a/bin/dockerLint +++ /dev/null @@ -1,759 +0,0 @@ -#!/usr/bin/env bash - -##################################### -# GENERATED FILE FROM https://github.com/fchastanet/bash-tools/tree/master/src/build/dockerLint.sh -# DO NOT EDIT IT -##################################### - -# shellcheck disable=SC2034 -SCRIPT_NAME=${0##*/} -REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -# shellcheck disable=SC2034 -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" -BIN_DIR="${CURRENT_DIR}" -ROOT_DIR="$(cd "${BIN_DIR}/.." && pwd -P)" -# shellcheck disable=SC2034 -SRC_DIR="${ROOT_DIR}/src" -# shellcheck disable=SC2034 -VENDOR_DIR="${ROOT_DIR}/vendor" -# shellcheck disable=SC2034 -VENDOR_BIN_DIR="${ROOT_DIR}/vendor/bin" -export PATH="${BIN_DIR}":"${VENDOR_BIN_DIR}":${PATH} - -# shellcheck disable=SC2034 -TMPDIR="$(mktemp -d -p "${TMPDIR:-/tmp}" -t bash-framework-$$-XXXXXX)" -export TMPDIR - -# temp dir cleaning -cleanOnExit() { - rm -Rf "${TMPDIR}" >/dev/null 2>&1 -} -trap cleanOnExit EXIT HUP QUIT ABRT TERM - -# @see https://unix.stackexchange.com/a/386856 -interruptManagement() { - # restore SIGINT handler - trap - INT - # ensure that Ctrl-C is trapped by this script and not by sub process - # report to the parent that we have indeed been interrupted - kill -s INT "$$" -} -trap interruptManagement INT - -# shellcheck disable=SC2034 -((failures = 0)) || true - -shopt -s expand_aliases - -# Bash will remember & return the highest exit code in a chain of pipes. -# This way you can catch the error inside pipes, e.g. mysqldump | gzip -set -o pipefail -set -o errexit - -# a log is generated when a command fails -set -o errtrace - -# use nullglob so that (file*.php) will return an empty array if no file matches the wildcard -shopt -s nullglob - -export TERM=xterm-256color - -#avoid interactive install -export DEBIAN_FRONTEND=noninteractive -export DEBCONF_NONINTERACTIVE_SEEN=true - -if [[ -t 1 || -t 2 ]]; then - # check colors applicable https://misc.flogisoft.com/bash/tip_colors_and_formatting - readonly __ERROR_COLOR='\e[31m' # Red - readonly __INFO_COLOR='\e[44m' # white on lightBlue - readonly __SUCCESS_COLOR='\e[32m' # Green - readonly __WARNING_COLOR='\e[33m' # Yellow - readonly __TEST_COLOR='\e[100m' # Light magenta - readonly __TEST_ERROR_COLOR='\e[41m' # white on red - readonly __SKIPPED_COLOR='\e[33m' # Yellow - readonly __HELP_COLOR='\e[7;49;33m' # Black on Gold - readonly __DEBUG_COLOR='\e[37m' # Grey - # Internal: reset color - readonly __RESET_COLOR='\e[0m' # Reset Color - # shellcheck disable=SC2155,SC2034 - readonly __HELP_EXAMPLE="$(echo -e "\e[1;30m")" - # shellcheck disable=SC2155,SC2034 - readonly __HELP_TITLE="$(echo -e "\e[1;37m")" - # shellcheck disable=SC2155,SC2034 - readonly __HELP_NORMAL="$(echo -e "\033[0m")" -else - # check colors applicable https://misc.flogisoft.com/bash/tip_colors_and_formatting - readonly __ERROR_COLOR='' - readonly __INFO_COLOR='' - readonly __SUCCESS_COLOR='' - readonly __WARNING_COLOR='' - readonly __SKIPPED_COLOR='' - readonly __HELP_COLOR='' - readonly __TEST_COLOR='' - readonly __TEST_ERROR_COLOR='' - readonly __DEBUG_COLOR='' - # Internal: reset color - readonly __RESET_COLOR='' - readonly __HELP_EXAMPLE='' - readonly __HELP_TITLE='' - readonly __HELP_NORMAL='' -fi -export __ERROR_COLOR -export __INFO_COLOR -export __SUCCESS_COLOR -export __WARNING_COLOR -export __SKIPPED_COLOR -export __TEST_COLOR -export __TEST_ERROR_COLOR -export __SKIPPED_COLOR -export __HELP_COLOR -export __DEBUG_COLOR -export __RESET_COLOR -export __HELP_EXAMPLE -export __HELP_TITLE -export __HELP_NORMAL - -Args::defaultHelpNoExit() { - local helpArg=$1 - shift || true - # shellcheck disable=SC2034 - local args - args="$(getopt -l help -o h -- "$@" 2>/dev/null)" || true - eval set -- "${args}" - - while true; do - case $1 in - -h | --help) - if [[ "$(type -t "${helpArg}")" = "function" ]]; then - "${helpArg}" "$@" - else - Args::showHelp "${helpArg}" - fi - return 1 - ;; - --) - break - ;; - *) - # ignore - ;; - esac - done -} - -# upgrade given binary to latest github release using retry -# @param {String} targetFile target binary file (eg: /usr/local/bin/kind) -# @param {String} releaseUrl github release url (eg: https://github.com/kubernetes-sigs/kind/releases/download/@latestVersion@/kind-linux-amd64) -# the placeholder @latestVersion@ will be replaced by the latest release version -# @param {Function} versionCallback function called to get software version (default: Version::getCommandVersionFromPlainText will call software with argument --version) -# @param {Function} installCallback function called to install the file retrieved on github (default copy as is and set execution bit) -# @output log messages about retry, install, upgrade -Github::upgradeRelease() { - local targetFile="$1" - local releaseUrl="$2" - local argVersion="${3:---version}" - local versionCallback="${4:-Version::getCommandVersionFromPlainText}" - # shellcheck disable=SC2034 - local installCallback="${5:-}" - local latestVersion - local repo - - repo="$(Github::extractRepoFromGithubUrl "${releaseUrl}")" - Github::getLatestRelease "${repo}" latestVersion || - Log::fatal "Repo ${repo} latest version not found" - Log::displayInfo "Repo ${repo} latest version found is ${latestVersion}" - - local currentVersion="not existing" - if [[ -f "${targetFile}" ]]; then - currentVersion="$(${versionCallback} "${targetFile}" "${argVersion}" 2>&1 || true)" - fi - if [[ "${currentVersion}" = "${latestVersion}" ]]; then - Log::displayInfo "${targetFile} version ${latestVersion} already installed" - else - if [[ -z "${currentVersion}" ]]; then - Log::displayInfo "Installing ${targetFile} with version ${latestVersion}" - else - Log::displayInfo "Upgrading ${targetFile} from version ${currentVersion} to ${latestVersion}" - fi - local url - url="$(echo "${releaseUrl}" | sed -E "s/@latestVersion@/${latestVersion}/g")" - Log::displayInfo "Using url ${url}" - newSoftware=$(mktemp -p "${TMPDIR:-/tmp}" -t github.newSoftware.XXXX) - Retry::default curl \ - -L \ - -o "${newSoftware}" \ - --fail \ - "${url}" - - Github::defaultInstall "${newSoftware}" "${targetFile}" "${latestVersion}" "${installCallback}" - fi -} - -# Check that command version is greater than expected minimal version -# display warning if command version greater than expected minimal version -# display error if command version less than expected minimal version and exit 1 -# @param {String} $1 command path -# @param {String} $2 command line parameters to launch to get command version -# @param {String} $3 expected minimal command version -# @param {String} $4 optional help message to display if command does not exist -# @return 1 if command version less than expected minimal version, 0 otherwise -# @return 2 if command does not exist -Version::checkMinimal() { - local commandName="$1" - local argVersion="$2" - local minimalVersion="$3" - local parseVersionCallback=${4:-Version::parse} - local help="${4:-}" - - Assert::commandExists "${commandName}" "${help}" || return 2 - - local version - version="$("${commandName}" "${argVersion}" 2>&1 | ${parseVersionCallback})" - - Log::displayDebug "check ${commandName} version ${version} against minimal ${minimalVersion}" - - Version::compare "${version}" "${minimalVersion}" || { - local result=$? - if [[ "${result}" = "1" ]]; then - Log::displayWarning "${commandName} version is ${version} greater than ${minimalVersion}, OK let's continue" - elif [[ "${result}" = "2" ]]; then - Log::displayError "${commandName} minimal version is ${minimalVersion}, your version is ${version}" - return 1 - fi - return 0 - } - -} - -Args::showHelp() { - local helpArg="$1" - echo -e "${helpArg}" -} - -# Public: check if command specified exists or return 1 -# with error and message if not -# -# **Arguments**: -# * $1 commandName on which existence must be checked -# * $2 helpIfNotExists a help command to display if the command does not exist -# -# **Exit**: code 1 if the command specified does not exist -Assert::commandExists() { - local commandName="$1" - local helpIfNotExists="$2" - - "${BASH_FRAMEWORK_COMMAND:-command}" -v "${commandName}" >/dev/null 2>/dev/null || { - Log::displayError "${commandName} is not installed, please install it" - if [[ -n "${helpIfNotExists}" ]]; then - Log::displayInfo "${helpIfNotExists}" - fi - return 1 - } - return 0 -} - -Github::defaultInstall() { - local newSoftware="$1" - local targetFile="$2" - local version="$3" - local installCallback=$4 - # shellcheck disable=SC2086 - mkdir -p "$(dirname "${targetFile}")" - if [[ "$(type -t "${installCallback}")" = "function" ]]; then - ${installCallback} "${newSoftware}" "${targetFile}" "${version}" - else - mv "${newSoftware}" "${targetFile}" - fi - chmod +x "${targetFile}" - hash -r - rm -f "${newSoftware}" || true -} - -# github repository eg: kubernetes-sigs/kind -# @param {String} githubUrl eg: https://github.com/kubernetes-sigs/kind/releases/download/@latestVersion@/kind-linux-amd64 -Github::extractRepoFromGithubUrl() { - local githubUrl="$1" - echo "${githubUrl}" | sed -E 's#^https://github.com/([^/]+)/([^/]+)/.*$#\1/\2#' -} - -# Retrieve the latest version number of a github release using Github API using retry -# @param {String} $1 repository in the format fchastanet/bash-tools -# that would match https://github.com/fchastanet/bash-tools -# @param {String} $2 reference to a variable that will contain the result of the command -# @output log messages about retry -Github::getLatestRelease() { - local repo="$1" - # we need to pass the result through a reference instead of output directly - # because retry can output too - local -n resultRef=$2 - resultRef="" - local resultFile - resultFile="$(mktemp -p "${TMPDIR:-/tmp}" -t githubLatestRelease.XXXX)" - # Get latest release from GitHub api - if Retry::default curl \ - -o "${resultFile}" \ - --fail \ - --silent \ - "https://api.github.com/repos/${repo}/releases/latest"; then - # shellcheck disable=SC2034 - resultRef="$(Version::githubApiExtractVersion <"${resultFile}")" - return 0 - fi - # display curl result in case of failure - cat >&2 "${resultFile}" - rm -f "${resultFile}" -} - -# Public: log level off -export __LEVEL_OFF=0 -# Public: log level error -export __LEVEL_ERROR=1 -# Public: log level warning -export __LEVEL_WARNING=2 -# Public: log level info -export __LEVEL_INFO=3 -# Public: log level success -export __LEVEL_SUCCESS=3 -# Public: log level debug -export __LEVEL_DEBUG=4 - -export __LEVEL_OFF -export __LEVEL_ERROR -export __LEVEL_WARNING -export __LEVEL_INFO -export __LEVEL_SUCCESS -export __LEVEL_DEBUG - -# Display message using debug color (grey) -# @param {String} $1 message -Log::displayDebug() { - echo -e "${__DEBUG_COLOR}DEBUG - ${1}${__RESET_COLOR}" >&2 - Log::logDebug "$1" -} - -# Display message using error color (red) -# @param {String} $1 message -Log::displayError() { - echo -e "${__ERROR_COLOR}ERROR - ${1}${__RESET_COLOR}" >&2 - Log::logError "$1" -} - -# Display message using info color (bg light blue/fg white) -# @param {String} $1 message -Log::displayInfo() { - echo -e "${__INFO_COLOR}INFO - ${1}${__RESET_COLOR}" >&2 - Log::logInfo "$1" -} - -# Display message using warning color (yellow) -# @param {String} $1 message -Log::displayWarning() { - echo -e "${__WARNING_COLOR}WARN - ${1}${__RESET_COLOR}" >&2 - Log::logWarning "$1" -} - -# Display message using error color (red) and exit immediately with error status 1 -# @param {String} $1 message -Log::fatal() { - echo -e "${__ERROR_COLOR}FATAL - ${1}${__RESET_COLOR}" >&2 - Log::logFatal "$1" - exit 1 -} - -# Retry a command 5 times with a delay of 15 seconds between each attempt -# @param $@ the command to run -# @return 0 on success, 1 if max retries count reached -Retry::default() { - Retry::parameterized 5 15 "" "$@" -} - -# @param $1 version 1 -# @param $2 version 2 -# @return -# 0 if equal -# 1 if version1 > version2 -# 2 else -Version::compare() { - if [[ "$1" = "$2" ]]; then - return 0 - fi - local IFS=. - # shellcheck disable=2206 - local i ver1=($1) ver2=($2) - # fill empty fields in ver1 with zeros - for ((i = ${#ver1[@]}; i < ${#ver2[@]}; i++)); do - ver1[i]=0 - done - for ((i = 0; i < ${#ver1[@]}; i++)); do - if [[ -z "${ver2[i]+unset}" ]] || [[ -z ${ver2[i]} ]]; then - # fill empty fields in ver2 with zeros - ver2[i]=0 - fi - if ((10#${ver1[i]} > 10#${ver2[i]})); then - return 1 - fi - if ((10#${ver1[i]} < 10#${ver2[i]})); then - return 2 - fi - done - return 0 -} - -# extract software version number -# @param $1 the command that will be called with --version parameter -Version::getCommandVersionFromPlainText() { - local command="$1" - local argVersion="${2:---version}" - "${command}" "${argVersion}" 2>&1 | - Version::parse # keep only version numbers -} - -# filter to keep only version number from a string -# @stdin the string to parse -Version::parse() { - sed -En 's/[^0-9]*(([0-9]+\.)*[0-9]+).*/\1/p' | head -n1 -} - -# lazy initialization -declare -g BASH_FRAMEWORK_INITIALIZED="0" -declare -g BASH_FRAMEWORK_CACHED_ENV_FILE -declare -g BASH_FRAMEWORK_DEFAULT_ENV_FILE - -# load variables in order(from less specific to more specific) from : -# - ${ROOT_DIR}/src/Env/testsData/.env file -# - ${ROOT_DIR}/conf/.env file if exists -# - ~/.env file if exists -# - ~/.bash-tools/.env file if exists -# - BASH_FRAMEWORK_ENV_FILEPATH= -Env::load() { - if [[ "${BASH_FRAMEWORK_INITIALIZED}" = "1" ]]; then - return 0 - fi - BASH_FRAMEWORK_CACHED_ENV_FILE="$(mktemp -p "${TMPDIR:-/tmp}" -t "env_vars.XXXXXXX")" - BASH_FRAMEWORK_DEFAULT_ENV_FILE="$(mktemp -p "${TMPDIR:-/tmp}" -t "default_env_file.XXXXXXX")" - # shellcheck source=src/Env/testsData/.env - ( - echo "BASH_FRAMEWORK_LOG_LEVEL=${BASH_FRAMEWORK_LOG_LEVEL:-0}" - echo "BASH_FRAMEWORK_DISPLAY_LEVEL=${BASH_FRAMEWORK_DISPLAY_LEVEL:-3}" - echo "BASH_FRAMEWORK_LOG_FILE=${BASH_FRAMEWORK_LOG_FILE:-${ROOT_DIR}/logs/${SCRIPT_NAME}.log}" - echo "BASH_FRAMEWORK_LOG_FILE_MAX_ROTATION=${BASH_FRAMEWORK_LOG_FILE_MAX_ROTATION:-5}" - ) >"${BASH_FRAMEWORK_DEFAULT_ENV_FILE}" - - ( - # reset temp file - echo >"${BASH_FRAMEWORK_CACHED_ENV_FILE}" - - # list .env files that need to be loaded - local -a files=() - if [[ -f "${BASH_FRAMEWORK_DEFAULT_ENV_FILE}" ]]; then - files+=("${BASH_FRAMEWORK_DEFAULT_ENV_FILE}") - fi - if [[ -f "${ROOT_DIR}/conf/.env" && -r "${ROOT_DIR}/conf/.env" ]]; then - files+=("${ROOT_DIR}/conf/.env") - fi - if [[ -f "${HOME}/.env" && -r "${HOME}/.env" ]]; then - files+=("${HOME}/.env") - fi - local file - for file in "$@"; do - if [[ -f "${file}" && -r "${file}" ]]; then - files+=("${file}") - fi - done - # import custom .env file - if [[ -n "${BASH_FRAMEWORK_ENV_FILEPATH+xxx}" ]]; then - # load BASH_FRAMEWORK_ENV_FILEPATH - if [[ -f "${BASH_FRAMEWORK_ENV_FILEPATH}" && -r "${BASH_FRAMEWORK_ENV_FILEPATH}" ]]; then - files+=("${BASH_FRAMEWORK_ENV_FILEPATH}") - else - Log::displayWarning "env file not not found - ${BASH_FRAMEWORK_ENV_FILEPATH}" - fi - fi - - # add all files added as parameters - files+=("$@") - - # source each file in order - local file - for file in "${files[@]}"; do - # shellcheck source=src/Env/testsData/.env - source "${file}" || { - Log::displayWarning "Cannot load '${file}'" - } - done - - # copy only the variables to the tmp file - local varName overrideVarName - while IFS=$'\n' read -r varName; do - overrideVarName="OVERRIDE_${varName}" - if [[ -z ${!overrideVarName+xxx} ]]; then - echo "${varName}='${!varName}'" >>"${BASH_FRAMEWORK_CACHED_ENV_FILE}" - else - # variable is overridden - echo "${varName}='${!overrideVarName}'" >>"${BASH_FRAMEWORK_CACHED_ENV_FILE}" - fi - - # using awk deduce all variables that need to be copied in tmp file - # from less specific file to the most - done < <(awk -F= '!a[$1]++' "${files[@]}" | grep -v '^$\|^\s*\#' | cut -d= -f1) - ) || exit 1 - - # ensure all sourced variables will be exported - set -o allexport - - # Finally load the temp file to make the variables available in current script - # shellcheck source=src/Env/testsData/.env - source "${BASH_FRAMEWORK_CACHED_ENV_FILE}" - - export BASH_FRAMEWORK_INITIALIZED=1 - - set +o allexport -} - -# Display message using info color (bg light blue/fg white) -# @param {String} $1 message -Log::displayHelp() { - echo -e "${__HELP_COLOR}HELP - ${1}${__RESET_COLOR}" >&2 - Log::logHelp "$1" -} - -# Display message using skip color (yellow) -# @param {String} $1 message -Log::displaySkipped() { - echo -e "${__SKIPPED_COLOR}SKIPPED - ${1}${__RESET_COLOR}" >&2 - Log::logSkipped "$1" -} - -# Display message using success color (bg green/fg white) -# @param {String} $1 message -Log::displaySuccess() { - echo -e "${__SUCCESS_COLOR}SUCCESS - ${1}${__RESET_COLOR}" >&2 - Log::logSuccess "$1" -} - -# log message to file -# @param {String} $1 message -Log::logDebug() { - Log::logMessage "DEBUG" "$@" -} - -# log message to file -# @param {String} $1 message -Log::logError() { - Log::logMessage "ERROR" "$@" -} - -# log message to file -# @param {String} $1 message -Log::logFatal() { - Log::logMessage "FATAL" "$@" -} - -# log message to file -# @param {String} $1 message -Log::logHelp() { - Log::logMessage "HELP" "$@" -} - -# log message to file -# @param {String} $1 message -Log::logInfo() { - Log::logMessage "INFO" "$@" -} - -# log message to file -# @param {String} $1 message -Log::logSkipped() { - Log::logMessage "SKIPPED" "$@" -} - -# log message to file -# @param {String} $1 message -Log::logSuccess() { - Log::logMessage "SUCCESS" "$@" -} - -# log message to file -# @param {String} $1 message -Log::logWarning() { - Log::logMessage "WARNING" "$@" -} - -# To be called before logging in the log file -# @param $1 log file name -# @param $2 maximum number of log files -Log::rotate() { - local FILENAME="$1" - local MAX_LOG="${2:-5}" - for i in $(seq $((MAX_LOG - 1)) -1 1); do - Log::displayInfo "Log rotation ${FILENAME}.${i} to ${FILENAME}.$((i + 1))" - mv "${FILENAME}."{"${i}","$((i + 1))"} &>/dev/null || true - done - if mv "${FILENAME}" "${FILENAME}.1" &>/dev/null; then - Log::displayInfo "Log rotation ${FILENAME} to ${FILENAME}.1" - fi -} - -# Retry a command several times depending on parameters -# @param {int} $1 max retries -# @param {int} $2 delay between attempt -# @param {String} $3 message to display to describe the attempt -# @param ... $@ rest of parameters, the command to run -# @return 0 on success -# @return 1 if max retries count reached -# @return 2 if maxRetries invalid value -Retry::parameterized() { - local maxRetries=$1 - shift || true - local delayBetweenTries=$1 - shift || true - local message="$1" - shift || true - local retriesCount=1 - if [[ "${maxRetries}" -lt 1 ]]; then - Log::displayError "invalid maxRetry value" - return 2 - fi - - while true; do - Log::displayInfo "Attempt ${retriesCount}/${maxRetries}: ${message}" - if "$@"; then - break - elif [[ "${retriesCount}" -lt "${maxRetries}" ]]; then - Log::displayWarning "Command failed. Wait for ${delayBetweenTries} seconds" - ((retriesCount++)) - sleep "${delayBetweenTries}" - else - Log::displayError "The command has failed after ${retriesCount} attempts." - return 1 - fi - done - return 0 -} - -# extract version number from github api -# @stdin json result of github API -Version::githubApiExtractVersion() { - jq -r ".tag_name" | Version::parse -} - -# Internal: common log message -# -# **Arguments**: -# * $1 - message's level description -# * $2 - message -# **Output**: -# [date]|[levelMsg]|message -# -# **Examples**: -#
-# 2020-01-19 19:20:21|ERROR  |log error
-# 2020-01-19 19:20:21|SKIPPED|log skipped
-# 
-Log::logMessage() { - local levelMsg="$1" - local msg="$2" - local date - - if ((BASH_FRAMEWORK_LOG_LEVEL > __LEVEL_OFF)); then - date="$(date '+%Y-%m-%d %H:%M:%S')" - printf "%s|%7s|%s\n" "${date}" "${levelMsg}" "${msg}" >>"${BASH_FRAMEWORK_LOG_FILE}" - fi -} - -# FUNCTIONS - -Env::load - -# disable display methods following display level -if ((BASH_FRAMEWORK_DISPLAY_LEVEL < __LEVEL_DEBUG)); then - Log::displayDebug() { :; } -fi -if ((BASH_FRAMEWORK_DISPLAY_LEVEL < __LEVEL_INFO)); then - Log::displayHelp() { :; } - Log::displayInfo() { :; } - Log::displaySkipped() { :; } - Log::displaySuccess() { :; } -fi -if ((BASH_FRAMEWORK_DISPLAY_LEVEL < __LEVEL_WARNING)); then - Log::displayWarning() { :; } -fi -if ((BASH_FRAMEWORK_DISPLAY_LEVEL < __LEVEL_ERROR)); then - Log::displayError() { :; } -fi -# disable log methods following log level -if ((BASH_FRAMEWORK_LOG_LEVEL < __LEVEL_DEBUG)); then - Log::logDebug() { :; } -fi -if ((BASH_FRAMEWORK_LOG_LEVEL < __LEVEL_INFO)); then - Log::logHelp() { :; } - Log::logInfo() { :; } - Log::logSkipped() { :; } - Log::logSuccess() { :; } -fi -if ((BASH_FRAMEWORK_LOG_LEVEL < __LEVEL_WARNING)); then - Log::logWarning() { :; } -fi -if ((BASH_FRAMEWORK_LOG_LEVEL < __LEVEL_ERROR)); then - Log::logError() { :; } -fi - -if ((BASH_FRAMEWORK_LOG_LEVEL > __LEVEL_OFF)); then - if [[ -z "${BASH_FRAMEWORK_LOG_FILE}" ]]; then - BASH_FRAMEWORK_LOG_LEVEL=${__LEVEL_OFF} - export BASH_FRAMEWORK_LOG_LEVEL - elif [[ ! -f "${BASH_FRAMEWORK_LOG_FILE}" ]]; then - if ! mkdir -p "$(dirname "${BASH_FRAMEWORK_LOG_FILE}")" 2>/dev/null; then - BASH_FRAMEWORK_LOG_LEVEL=__LEVEL_OFF - Log::displayWarning "Log dir cannot be created $(dirname "${BASH_FRAMEWORK_LOG_FILE}")" - fi - if ! touch --no-create "${BASH_FRAMEWORK_LOG_FILE}" 2>/dev/null; then - BASH_FRAMEWORK_LOG_LEVEL=__LEVEL_OFF - Log::displayWarning "Log file '${BASH_FRAMEWORK_LOG_FILE}' cannot be created" - fi - fi - Log::displayInfo "Logging to file ${BASH_FRAMEWORK_LOG_FILE}" - if ((BASH_FRAMEWORK_LOG_FILE_MAX_ROTATION > 0)); then - Log::rotate "${BASH_FRAMEWORK_LOG_FILE}" "${BASH_FRAMEWORK_LOG_FILE_MAX_ROTATION}" - fi -fi - -DEFAULT_ARGS=(-f checkstyle) -MIN_HADOLINT_VERSION="2.12.0" -HELP="$( - cat <${MIN_HADOLINT_VERSION}) automatically -- lint this project files using default files filter -- use the default options '${DEFAULT_ARGS[*]}' if no parameter specified - -${__HELP_TITLE}Usage:${__HELP_NORMAL} ${SCRIPT_NAME} - -${__HELP_TITLE}Author:${__HELP_NORMAL} -[François Chastanet](https://github.com/fchastanet) - -${__HELP_TITLE}Source file:${__HELP_NORMAL} -https://github.com/fchastanet/bash-tools/tree/master/src/build/dockerLint.sh - -${__HELP_TITLE}License:${__HELP_NORMAL} -MIT License - -Copyright (c) 2022 François Chastanet -EOF -)" -Args::defaultHelpNoExit "${HELP}" "$@" || true - -# check if command in PATH is already the minimal version needed -if ! Version::checkMinimal "hadolint" "--version" "${MIN_HADOLINT_VERSION}" >/dev/null 2>&1; then - Github::upgradeRelease \ - "${VENDOR_BIN_DIR}/hadolint" \ - "https://github.com/hadolint/hadolint/releases/download/v@latestVersion@/hadolint-Linux-x86_64" -fi - -if (($# == 0)); then - set -- "${DEFAULT_ARGS[@]}" -fi -while IFS='' read -r file; do - hadolint "$@" "${file}" - echo -done < <(git ls-files --exclude-standard | grep -E '/Dockerfile.*' || true) diff --git a/bin/gitIsAncestorOf b/bin/gitIsAncestorOf index e19f3ad2..92bd0884 100755 --- a/bin/gitIsAncestorOf +++ b/bin/gitIsAncestorOf @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management diff --git a/bin/gitIsBranch b/bin/gitIsBranch index 28ec6a54..db8d3d7e 100755 --- a/bin/gitIsBranch +++ b/bin/gitIsBranch @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management @@ -1501,6 +1505,8 @@ gitIsBranchCommand() { fi } +gitIsBranchCommand parse "${BASH_FRAMEWORK_ARGV[@]}" + # @require Linux::requireExecutedAsUser run() { # check various branch hierarchies, adjust as needed diff --git a/bin/gitRenameBranch b/bin/gitRenameBranch index ee9aaf01..c27ed4c2 100755 --- a/bin/gitRenameBranch +++ b/bin/gitRenameBranch @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management diff --git a/bin/installRequirements b/bin/installRequirements index f55e72a6..b5b1e355 100755 --- a/bin/installRequirements +++ b/bin/installRequirements @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management diff --git a/bin/mysql2puml b/bin/mysql2puml index 54e7f1fb..4d153384 100755 --- a/bin/mysql2puml +++ b/bin/mysql2puml @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management diff --git a/bin/upgradeGithubRelease b/bin/upgradeGithubRelease index bdf51ca0..530eb068 100755 --- a/bin/upgradeGithubRelease +++ b/bin/upgradeGithubRelease @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management diff --git a/bin/waitForIt b/bin/waitForIt index 460b992c..99da67d8 100755 --- a/bin/waitForIt +++ b/bin/waitForIt @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management diff --git a/bin/waitForMysql b/bin/waitForMysql index 86db4069..4b129253 100755 --- a/bin/waitForMysql +++ b/bin/waitForMysql @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management diff --git a/conf/dbScripts/extractData b/conf/dbScripts/extractData index 53bf2742..77c0629e 100755 --- a/conf/dbScripts/extractData +++ b/conf/dbScripts/extractData @@ -57,7 +57,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management diff --git a/install b/install index 278a454c..e4711ce5 100755 --- a/install +++ b/install @@ -58,7 +58,11 @@ interruptManagement() { trap interruptManagement INT SCRIPT_NAME=${0##*/} REAL_SCRIPT_FILE="$(readlink -e "$(realpath "${BASH_SOURCE[0]}")")" -CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +if [[ -n "${EMBED_CURRENT_DIR}" ]]; then + CURRENT_DIR="${EMBED_CURRENT_DIR}" +else + CURRENT_DIR="$(cd "$(readlink -e "${REAL_SCRIPT_FILE%/*}")" && pwd -P)" +fi ################################################ # Temp dir management diff --git a/src/_binaries/Git/gitIsBranch.options.tpl b/src/_binaries/Git/gitIsBranch.options.tpl index 243b6e0a..283f794e 100644 --- a/src/_binaries/Git/gitIsBranch.options.tpl +++ b/src/_binaries/Git/gitIsBranch.options.tpl @@ -24,3 +24,5 @@ options+=( ) Options::generateCommand "${options[@]}" % + +<% ${commandFunctionName} %> parse "${BASH_FRAMEWORK_ARGV[@]}" diff --git a/src/_binaries/build/doc.options.tpl b/src/_binaries/build/doc.options.tpl index 15c16a48..c1bf2b0d 100644 --- a/src/_binaries/build/doc.options.tpl +++ b/src/_binaries/build/doc.options.tpl @@ -32,3 +32,5 @@ updateArgListTraceVerboseCallback() { RUN_CONTAINER_ARGV_FILTERED+=(-vvv) BASH_FRAMEWORK_ARGV_FILTERED+=(-vvv) } + +<% ${commandFunctionName} %> parse "${BASH_FRAMEWORK_ARGV[@]}" diff --git a/src/_binaries/build/doc.sh b/src/_binaries/build/doc.sh index 71e5ff28..bcbc7a6a 100755 --- a/src/_binaries/build/doc.sh +++ b/src/_binaries/build/doc.sh @@ -13,7 +13,8 @@ declare -a RUN_CONTAINER_ARGV_FILTERED=() run() { if [[ "${IN_BASH_DOCKER:-}" != "You're in docker" ]]; then DOCKER_RUN_OPTIONS=$"-e ORIGINAL_DOC_DIR=${DOC_DIR}" \ - "${COMMAND_BIN_DIR}/runBuildContainer" "/bash/bin/doc" "${RUN_CONTAINER_ARGV_FILTERED[@]}" + "${COMMAND_BIN_DIR}/runBuildContainer" "/bash/bin/doc" \ + "${RUN_CONTAINER_ARGV_FILTERED[@]}" return $? fi @@ -43,7 +44,7 @@ run() { ShellDoc::generateMdFileFromTemplate \ "${BASH_TOOLS_ROOT_DIR}/Commands.tmpl.md" \ "${DOC_DIR}/Commands.md" \ - "${FRAMEWORK_BIN_DIR}" \ + "${BASH_TOOLS_ROOT_DIR}/bin" \ TOKEN_NOT_FOUND_COUNT \ '(bash-tpl|plantuml|definitionLint|compile|installFacadeExample)$'