#!/usr/bin/env bash
set -eu

if [[ $EUID -ne 0 ]]; then
  echo 'Run this installer as root.'
  exit 1
fi

# Refuse replacement while a maintenance/audit run holds the lock.
if command -v flock >/dev/null 2>&1; then
  exec 8>/run/lock/mgh-db-doctor.lock
  if ! flock -n 8; then
    echo 'MGH Database Doctor is currently running.'
    echo 'Allow the existing run to finish before installing v1.2.0.'
    exit 1
  fi
fi

STAMP="$(date +%Y%m%d-%H%M%S)"
mkdir -p /usr/local/sbin /etc /var/log/mgh-db-doctor /var/lib/mgh-db-doctor/prechange-dumps

[[ -f /usr/local/sbin/mgh-db-manager ]] && cp -a /usr/local/sbin/mgh-db-manager "/usr/local/sbin/mgh-db-manager.backup-$STAMP"
[[ -e /usr/local/sbin/mgh-db-safe-run ]] && cp -aL /usr/local/sbin/mgh-db-safe-run "/usr/local/sbin/mgh-db-safe-run.backup-$STAMP" 2>/dev/null || true
[[ -f /etc/mgh-db-doctor.conf ]] && cp -a /etc/mgh-db-doctor.conf "/etc/mgh-db-doctor.conf.backup-$STAMP"

printf '%s' 'IyEvdXNyL2Jpbi9lbnYgYmFzaAojIE1HSCBVbml2ZXJzYWwgRGF0YWJhc2UgRG9jdG9yCiMgQXVkaXQtZmlyc3QsIHNlcnZlci13aWRlIE15U1FML01hcmlhREIgbWFpbnRlbmFuY2UgZm9yIGNQYW5lbC9XSE0gc2VydmVycy4KClZFUlNJT049IjEuMi4wLXVuaXZlcnNhbCIKQ09ORklHPSIvZXRjL21naC1kYi1kb2N0b3IuY29uZiIKTE9HX0RJUj0iL3Zhci9sb2cvbWdoLWRiLWRvY3RvciIKRFVNUF9ESVI9Ii92YXIvbGliL21naC1kYi1kb2N0b3IvcHJlY2hhbmdlLWR1bXBzIgpMT0NLX0ZJTEU9Ii9ydW4vbG9jay9tZ2gtZGItZG9jdG9yLmxvY2siCk1PREU9ImF1ZGl0IgpBUFBMWT0ibm8iCkFTU1VNRV9ZRVM9Im5vIgpSVU5fSUQ9IiQoZGF0ZSArJVklbSVkLSVIJU0lUyktJCQiClJFUE9SVD0iIgpERVRBSUw9IiIKCiMgQ291bnRlcnMKREJfRk9VTkQ9MDsgREJfU0NBTk5FRD0wOyBEQl9FTVBUWT0wOyBEQl9TS0lQUEVEPTA7IERCX0ZBSUxFRD0wClRBQkxFU19DSEVDS0VEPTA7IFRBQkxFU19PSz0wOyBUQUJMRVNfVU5TVVBQT1JURUQ9MDsgVEFCTEVTX0JBRD0wOyBUQUJMRVNfUkVQQUlSRUQ9MApUQUJMRVNfT1BUSU1JWkVEPTA7IFRBQkxFU19BTkFMWVpFRD0wOyBUQUJMRVNfT1BUSU1JWkVfU0tJUFBFRD0wCldQX0RCUz0wOyBXUF9UUkFOU0lFTlRfUk9XUz0wOyBXQ19TRVNTSU9OX1JPV1M9MApBU19DT01QTEVURV9DQU5ESURBVEVTPTA7IEFTX0NBTkNFTEVEX0NBTkRJREFURVM9MDsgQVNfRkFJTEVEX0NBTkRJREFURVM9MDsgQVNfT1JQSEFOX0xPR1M9MApBU19BQ1RJT05TX1JFTU9WRUQ9MDsgQVNfTE9HU19SRU1PVkVEPTA7IEFTX1NLSVBQRURfREFUQUJBU0VTPTAKV1BfUkVWSVNJT05TX0ZPVU5EPTA7IFdQX0FVVE9EUkFGVFNfRk9VTkQ9MDsgV1BfVFJBU0hfUE9TVFNfRk9VTkQ9MApXUF9TUEFNX0NPTU1FTlRTX0ZPVU5EPTA7IFdQX1RSQVNIX0NPTU1FTlRTX0ZPVU5EPTA7IFdQX0FVVE9MT0FEX0JZVEVTPTAKV0FSTklOR1M9MDsgRVJST1JTPTAKREJfU0VSVkVSX0ZMQVZPUj0iVW5rbm93biI7IERCX1NFUlZFUl9WRVJTSU9OPSJVbmtub3duIgpEQl9DTElFTlQ9IiI7IERCX0NIRUNLPSIiOyBEQl9EVU1QPSIiOyBBVVRIX01PREU9IiIKCiMgQ29uc2VydmF0aXZlIGRlZmF1bHRzLCBvdmVycmlkZGVuIGJ5IGNvbmZpZy4KTUlOX0ZSRUVfR0I9MjAKTUlOX0ZSRUVfUEVSQ0VOVD0xMApNQVhfTE9BRF9QRVJfQ1BVPTEuNTAKTUFYX0lPV0FJVF9QRVJDRU5UPTMwCk1BWF9EQl9EVU1QX01CPTAKTUFYX09QVElNSVpFX1RBQkxFX01CPTEwMjQKTUlOX1JFQ0xBSU1fTUI9NjQKTUlOX1JFQ0xBSU1fUEVSQ0VOVD0xNQpRVUVSWV9USU1FT1VUPTMwMApTTEVFUF9CRVRXRUVOX1RBQkxFUz0xClNMRUVQX0JFVFdFRU5fQU5BTFlaRT0wCkFOQUxZWkVfQkFUQ0hfU0laRT0yNQpBTkFMWVpFX0JBVENIX0ZBTExCQUNLPXllcwpFTkFCTEVfV1BfVFJBTlNJRU5UX0NMRUFOVVA9eWVzCkVOQUJMRV9XQ19TRVNTSU9OX0NMRUFOVVA9eWVzCkVOQUJMRV9BQ1RJT05fU0NIRURVTEVSX0NMRUFOVVA9eWVzCkFDVElPTl9TQ0hFRFVMRVJfQ09NUExFVEVfREFZUz00NQpBQ1RJT05fU0NIRURVTEVSX0NBTkNFTEVEX0RBWVM9NDUKQUNUSU9OX1NDSEVEVUxFUl9GQUlMRURfREFZUz05MApNQVhfQUNUSU9OX1NDSEVEVUxFUl9ERUxFVEVfUk9XUz01MDAwMApFTkFCTEVfRU5HSU5FX1NBRkVfT1BUSU1JWkU9eWVzCkVYQ0xVREVEX0RCX1JFR0VYPSdeKGluZm9ybWF0aW9uX3NjaGVtYXxwZXJmb3JtYW5jZV9zY2hlbWF8bXlzcWx8c3lzfGNwaHVsa2R8ZXhpbXN0YXRzfG1vZHNlY3xyb3VuZGN1YmV8bGVlY2hwcm90ZWN0KSQnClNFTlNJVElWRV9EQl9SRUdFWD0nKHdobWNzfGJpbGxpbmd8aW52b2ljZXxhY2NvdW50aW5nfGZpbmFuY2V8Y3JtKScKCnNheSgpeyBwcmludGYgJyVzXG4nICIkKiI7IH0KbG9nKCl7CiAgbG9jYWwgbGV2ZWw9IiQxIjsgc2hpZnQKICBsb2NhbCBsaW5lPSIkKGRhdGUgLUlzKSBbJGxldmVsXSAkKiIKICBzYXkgIiRsaW5lIgogIFtbIC1uICIkUkVQT1JUIiBdXSAmJiBwcmludGYgJyVzXG4nICIkbGluZSIgPj4gIiRSRVBPUlQiCiAgW1sgIiRsZXZlbCIgPT0gV0FSTiBdXSAmJiBXQVJOSU5HUz0kKChXQVJOSU5HUysxKSkKICBbWyAiJGxldmVsIiA9PSBFUlJPUiBdXSAmJiBFUlJPUlM9JCgoRVJST1JTKzEpKQogIHJldHVybiAwCn0KcnVuX3RpbWVvdXQoKXsKICBpZiBjb21tYW5kIC12IHRpbWVvdXQgPi9kZXYvbnVsbCAyPiYxOyB0aGVuIHRpbWVvdXQgLS1zaWduYWw9VEVSTSAtLWtpbGwtYWZ0ZXI9MTUgIiRRVUVSWV9USU1FT1VUIiAiJEAiOyBlbHNlICIkQCI7IGZpCn0KdHJpbSgpeyBsb2NhbCB4PSIkKiI7IHg9IiR7eCMke3glJVshWzpzcGFjZTpdXSp9fSI7IHg9IiR7eCUke3gjIypbIVs6c3BhY2U6XV19fSI7IHByaW50ZiAnJXMnICIkeCI7IH0KcXVvdGVfaWRlbnQoKXsgbG9jYWwgeD0iJHsxLy9cYC9cYFxgfSI7IHByaW50ZiAnYCVzYCcgIiR4IjsgfQpzcWxfbGl0KCl7IHByaW50ZiAnJXMnICIkMSIgfCBzZWQgInMvJy8nJy9nIjsgfQoKdXNhZ2UoKXsgY2F0IDw8RU9GCk1HSCBVbml2ZXJzYWwgRGF0YWJhc2UgRG9jdG9yICRWRVJTSU9OCgpDb21tYW5kczoKICBtZ2gtZGItbWFuYWdlciBhdWRpdCAgICAgICAgICAgICBTYWZlIHNlcnZlci13aWRlIGhlYWx0aCArIFdvcmRQcmVzcyBvcHBvcnR1bml0eSBzY2FuOyBtYWtlcyBubyBjaGFuZ2VzCiAgbWdoLWRiLW1hbmFnZXIgc2FmZS1ydW4gICAgICAgICAgR3VhcmRlZCBzZXJ2ZXItd2lkZSByZXBhaXIvY2xlYW51cC9vcHRpbWl6YXRpb24KICBtZ2gtZGItbWFuYWdlciAtLXZlcnNpb24KClRoZSBzYWZlLXJ1biBjb21tYW5kIHByb2Nlc3NlcyBldmVyeSBlbGlnaWJsZSBub24tZW1wdHkgY3VzdG9tZXIgZGF0YWJhc2UgYXV0b21hdGljYWxseS4KRU9GCn0KCmxvYWRfY29uZmlnKCl7CiAgaWYgW1sgLXIgIiRDT05GSUciIF1dOyB0aGVuCiAgICAjIHNoZWxsY2hlY2sgZGlzYWJsZT1TQzEwOTAKICAgIC4gIiRDT05GSUciCiAgZmkKICBta2RpciAtcCAiJExPR19ESVIiICIkRFVNUF9ESVIiIC9ydW4vbG9jayAyPi9kZXYvbnVsbAogIGNobW9kIDcwMCAiJERVTVBfRElSIiAyPi9kZXYvbnVsbAogIFJFUE9SVD0iJExPR19ESVIvcmVwb3J0LSRSVU5fSUQudHh0IgogIERFVEFJTD0iJExPR19ESVIvZGV0YWlsLSRSVU5fSUQudHh0IgogIDogPiAiJFJFUE9SVCI7IDogPiAiJERFVEFJTCIKfQoKcGFyc2VfYXJncygpewogICMgU3VwcG9ydCBib3RoOgogICMgICBtZ2gtZGItbWFuYWdlciBzYWZlLXJ1bgogICMgICBtZ2gtZGItc2FmZS1ydW4KICAjIFRoZSBsYXR0ZXIgbWF5IGJlIGEgd3JhcHBlciBvciBzeW1saW5rLgogIGxvY2FsIGludm9rZWRfYXMKICBpbnZva2VkX2FzPSIkKGJhc2VuYW1lICIkMCIpIgogIGxvY2FsIGRlZmF1bHRfY29tbWFuZD0iYXVkaXQiCiAgW1sgIiRpbnZva2VkX2FzIiA9PSAibWdoLWRiLXNhZmUtcnVuIiBdXSAmJiBkZWZhdWx0X2NvbW1hbmQ9InNhZmUtcnVuIgoKICBjYXNlICIkezE6LSRkZWZhdWx0X2NvbW1hbmR9IiBpbgogICAgYXVkaXQpIE1PREU9ImF1ZGl0IiA7OwogICAgc2FmZS1ydW58bWFpbnRhaW4pIE1PREU9InNhZmUtcnVuIjsgQVBQTFk9InllcyIgOzsKICAgIC0tdmVyc2lvbnwtVikgc2F5ICIkVkVSU0lPTiI7IGV4aXQgMCA7OwogICAgLS1oZWxwfC1oKSB1c2FnZTsgZXhpdCAwIDs7CiAgICAqKSB1c2FnZTsgZXhpdCAyIDs7CiAgZXNhYwoKICAjIFNoaWZ0IG9ubHkgd2hlbiBhbiBleHBsaWNpdCBjb21tYW5kL29wdGlvbiB3YXMgc3VwcGxpZWQuCiAgW1sgJCMgLWd0IDAgXV0gJiYgc2hpZnQgfHwgdHJ1ZQogIHdoaWxlIFtbICQjIC1ndCAwIF1dOyBkbwogICAgY2FzZSAiJDEiIGluIC0teWVzKSBBU1NVTUVfWUVTPXllcyA7OyAqKSBsb2cgRVJST1IgIlVua25vd24gb3B0aW9uOiAkMSI7IGV4aXQgMiA7OyBlc2FjCiAgICBzaGlmdAogIGRvbmUKfQoKYWNxdWlyZV9sb2NrKCl7CiAgZXhlYyA5PiIkTE9DS19GSUxFIiB8fCB7IGxvZyBFUlJPUiAiQ2Fubm90IGNyZWF0ZSBsb2NrIGZpbGUiOyBleGl0IDE7IH0KICBpZiBjb21tYW5kIC12IGZsb2NrID4vZGV2L251bGwgMj4mMTsgdGhlbiBmbG9jayAtbiA5IHx8IHsgbG9nIEVSUk9SICJBbm90aGVyIGRhdGFiYXNlIGRvY3RvciBydW4gaXMgYWxyZWFkeSBhY3RpdmUiOyBleGl0IDE7IH07IGZpCn0KCnNlbGVjdF9jbGllbnRzKCl7CiAgaWYgY29tbWFuZCAtdiBtYXJpYWRiID4vZGV2L251bGwgMj4mMTsgdGhlbiBEQl9DTElFTlQ9Im1hcmlhZGIiOyBlbGlmIGNvbW1hbmQgLXYgbXlzcWwgPi9kZXYvbnVsbCAyPiYxOyB0aGVuIERCX0NMSUVOVD0ibXlzcWwiOyBlbHNlIGxvZyBFUlJPUiAiTmVpdGhlciBteXNxbCBub3IgbWFyaWFkYiBjbGllbnQgaXMgaW5zdGFsbGVkIjsgcmV0dXJuIDE7IGZpCiAgaWYgY29tbWFuZCAtdiBtYXJpYWRiLWNoZWNrID4vZGV2L251bGwgMj4mMTsgdGhlbiBEQl9DSEVDSz0ibWFyaWFkYi1jaGVjayI7IGVsaWYgY29tbWFuZCAtdiBteXNxbGNoZWNrID4vZGV2L251bGwgMj4mMTsgdGhlbiBEQl9DSEVDSz0ibXlzcWxjaGVjayI7IGVsc2UgREJfQ0hFQ0s9IiI7IGZpCiAgaWYgY29tbWFuZCAtdiBtYXJpYWRiLWR1bXAgPi9kZXYvbnVsbCAyPiYxOyB0aGVuIERCX0RVTVA9Im1hcmlhZGItZHVtcCI7IGVsaWYgY29tbWFuZCAtdiBteXNxbGR1bXAgPi9kZXYvbnVsbCAyPiYxOyB0aGVuIERCX0RVTVA9Im15c3FsZHVtcCI7IGVsc2UgREJfRFVNUD0iIjsgZmkKfQoKc2V0X2F1dGgoKXsKICBsb2NhbCBjYW5kaWRhdGVzPSgiL3Jvb3QvLm15LmNuZiIgIi91c3IvbG9jYWwvY3BhbmVsL2V0Yy9teS5jbmYiKSBmCiAgZm9yIGYgaW4gIiR7Y2FuZGlkYXRlc1tAXX0iOyBkbwogICAgW1sgLXIgIiRmIiBdXSB8fCBjb250aW51ZQogICAgaWYgIiREQl9DTElFTlQiIC0tZGVmYXVsdHMtZXh0cmEtZmlsZT0iJGYiIC0tYmF0Y2ggLS1za2lwLWNvbHVtbi1uYW1lcyAtZSAnU0VMRUNUIDEnID4vZGV2L251bGwgMj4mMTsgdGhlbiBBVVRIX01PREU9Ii0tZGVmYXVsdHMtZXh0cmEtZmlsZT0kZiI7IHJldHVybiAwOyBmaQogIGRvbmUKICBpZiAiJERCX0NMSUVOVCIgLS1iYXRjaCAtLXNraXAtY29sdW1uLW5hbWVzIC1lICdTRUxFQ1QgMScgPi9kZXYvbnVsbCAyPiYxOyB0aGVuIEFVVEhfTU9ERT0iIjsgcmV0dXJuIDA7IGZpCiAgbG9nIEVSUk9SICJDYW5ub3QgYXV0aGVudGljYXRlIGFzIGRhdGFiYXNlIGFkbWluaXN0cmF0b3IuIGNQYW5lbCBub3JtYWxseSBwcm92aWRlcyAvcm9vdC8ubXkuY25mIgogIHJldHVybiAxCn0KCmRiX3F1ZXJ5KCl7CiAgIyBBVVRIX01PREUgaW50ZW50aW9uYWxseSB3b3JkLXNwbGl0IGludG8gb25lIG9wdGlvbiBvciBlbXB0eS4KICBpZiBbWyAtbiAiJEFVVEhfTU9ERSIgXV07IHRoZW4gcnVuX3RpbWVvdXQgIiREQl9DTElFTlQiICIkQVVUSF9NT0RFIiAtLWJhdGNoIC0tc2tpcC1jb2x1bW4tbmFtZXMgLS1yYXcgIiRAIjsgZWxzZSBydW5fdGltZW91dCAiJERCX0NMSUVOVCIgLS1iYXRjaCAtLXNraXAtY29sdW1uLW5hbWVzIC0tcmF3ICIkQCI7IGZpCn0KY2hlY2tfY29tbWFuZCgpewogIGlmIFtbIC16ICIkREJfQ0hFQ0siIF1dOyB0aGVuIHJldHVybiAxMjc7IGZpCiAgaWYgW1sgLW4gIiRBVVRIX01PREUiIF1dOyB0aGVuIHJ1bl90aW1lb3V0ICIkREJfQ0hFQ0siICIkQVVUSF9NT0RFIiAiJEAiOyBlbHNlIHJ1bl90aW1lb3V0ICIkREJfQ0hFQ0siICIkQCI7IGZpCn0KZHVtcF9jb21tYW5kKCl7CiAgaWYgW1sgLXogIiREQl9EVU1QIiBdXTsgdGhlbiByZXR1cm4gMTI3OyBmaQogIGlmIFtbIC1uICIkQVVUSF9NT0RFIiBdXTsgdGhlbiAiJERCX0RVTVAiICIkQVVUSF9NT0RFIiAiJEAiOyBlbHNlICIkREJfRFVNUCIgIiRAIjsgZmkKfQoKZGV0ZWN0X2Vudmlyb25tZW50KCl7CiAgW1sgIiRFVUlEIiAtZXEgMCBdXSB8fCB7IGxvZyBFUlJPUiAiUnVuIHRoaXMgY29tbWFuZCBhcyByb290IjsgcmV0dXJuIDE7IH0KICBzZWxlY3RfY2xpZW50cyB8fCByZXR1cm4gMQogIHNldF9hdXRoIHx8IHJldHVybiAxCiAgbG9jYWwgdmVyIGNvbW1lbnQKICB2ZXI9IiQoZGJfcXVlcnkgLWUgJ1NFTEVDVCBWRVJTSU9OKCknIDI+L2Rldi9udWxsIHwgaGVhZCAtbjEpIgogIGNvbW1lbnQ9IiQoZGJfcXVlcnkgLWUgIlNIT1cgVkFSSUFCTEVTIExJS0UgJ3ZlcnNpb25fY29tbWVudCciIDI+L2Rldi9udWxsIHwgYXdrICdOUj09MXtwcmludCAkMn0nKSIKICBEQl9TRVJWRVJfVkVSU0lPTj0iJHt2ZXI6LVVua25vd259IgogIGNhc2UgIiR7dmVyLCx9ICR7Y29tbWVudCwsfSIgaW4gKm1hcmlhZGIqKSBEQl9TRVJWRVJfRkxBVk9SPSJNYXJpYURCIiA7OyAqcGVyY29uYSopIERCX1NFUlZFUl9GTEFWT1I9IlBlcmNvbmEgU2VydmVyIiA7OyAqKSBEQl9TRVJWRVJfRkxBVk9SPSJNeVNRTC1jb21wYXRpYmxlIiA7OyBlc2FjCiAgbG9nIElORk8gIlZlcnNpb246ICRWRVJTSU9OOyBtb2RlOiAkTU9ERSIKICBsb2cgSU5GTyAiRGF0YWJhc2U6ICREQl9TRVJWRVJfRkxBVk9SICREQl9TRVJWRVJfVkVSU0lPTjsgY2xpZW50OiAkREJfQ0xJRU5UIgogIFtbIC1mIC9ldGMvcmVkaGF0LXJlbGVhc2UgXV0gJiYgbG9nIElORk8gIk9TOiAkKGNhdCAvZXRjL3JlZGhhdC1yZWxlYXNlKSIKICBpZiBbWyAtZCAvdXNyL2xvY2FsL2NwYW5lbCBdXTsgdGhlbiBsb2cgSU5GTyAiY1BhbmVsL1dITSBkZXRlY3RlZCI7IGVsc2UgbG9nIFdBUk4gImNQYW5lbC9XSE0gbm90IGRldGVjdGVkOyBkYXRhYmFzZSBvd25lcnNoaXAgd2lsbCBiZSBpbmZlcnJlZCI7IGZpCiAgaWYgY29tbWFuZCAtdiBsc3dzY3RybCA+L2Rldi9udWxsIDI+JjEgfHwgW1sgLXggL3Vzci9sb2NhbC9sc3dzL2Jpbi9sc3dzY3RybCBdXTsgdGhlbiBsb2cgSU5GTyAiTGl0ZVNwZWVkIGRldGVjdGVkIjsgZWxzZSBsb2cgSU5GTyAiTGl0ZVNwZWVkIG5vdCBpbnN0YWxsZWQ7IGNvbnRpbnVpbmciOyBmaQogIGlmIGNvbW1hbmQgLXYgaW11bmlmeTM2MC1hZ2VudCA+L2Rldi9udWxsIDI+JjEgfHwgW1sgLXggL3Vzci9iaW4vaW11bmlmeTM2MC1hZ2VudCBdXTsgdGhlbiBsb2cgSU5GTyAiSW11bmlmeTM2MCBkZXRlY3RlZCI7IGVsc2UgbG9nIElORk8gIkltdW5pZnkzNjAgbm90IGluc3RhbGxlZDsgY29udGludWluZyI7IGZpCiAgaWYgW1sgLWQgL3Vzci9zaGFyZS9sdmUgXV0gfHwgY29tbWFuZCAtdiBsdmVpbmZvID4vZGV2L251bGwgMj4mMTsgdGhlbiBsb2cgSU5GTyAiQ2xvdWRMaW51eCBkZXRlY3RlZCI7IGVsc2UgbG9nIElORk8gIkNsb3VkTGludXggbm90IGluc3RhbGxlZDsgY29udGludWluZyI7IGZpCiAgaWYgY29tbWFuZCAtdiBqZXRiYWNrdXA1YXBpID4vZGV2L251bGwgMj4mMSB8fCBbWyAtZCAvdXNyL2xvY2FsL2pldGFwcHMvdXNyL2pldGJhY2t1cDUgXV07IHRoZW4gbG9nIElORk8gIkpldEJhY2t1cCBkZXRlY3RlZCI7IGVsc2UgbG9nIElORk8gIkpldEJhY2t1cCBub3QgaW5zdGFsbGVkOyBsb2NhbCBwcmUtY2hhbmdlIGR1bXBzIHdpbGwgYmUgdXNlZCI7IGZpCiAgcmV0dXJuIDAKfQoKcHJlZmxpZ2h0KCl7CiAgbG9jYWwgZGJkaXI9Ii92YXIvbGliL215c3FsIiBsaW5lIGZzIHRvdGFsIHVzZWQgYXZhaWwgcGN0IG1vdW50IGZyZWVfZ2IgZnJlZV9wY3QgY3B1cyBsb2FkIG1heCBpb3dhaXQKICBbWyAtZCAiJGRiZGlyIiBdXSB8fCBkYmRpcj0iLyIKICBsaW5lPSIkKGRmIC1QayAiJGRiZGlyIiAyPi9kZXYvbnVsbCB8IGF3ayAnTlI9PTJ7cHJpbnQgJDEifCIkMiJ8IiQzInwiJDQifCIkNSJ8IiQ2fScpIgogIElGUz0nfCcgcmVhZCAtciBmcyB0b3RhbCB1c2VkIGF2YWlsIHBjdCBtb3VudCA8PDwgIiRsaW5lIgogIHBjdD0iJHtwY3QlJSV9IgogIFtbICIkYXZhaWwiID1+IF5bMC05XSskIF1dIHx8IHsgbG9nIEVSUk9SICJDb3VsZCBub3QgcmVhZCBmcmVlIGRpc2sgc3BhY2UgZm9yICRkYmRpciI7IHJldHVybiAxOyB9CiAgZnJlZV9nYj0kKChhdmFpbC8xMDI0LzEwMjQpKTsgZnJlZV9wY3Q9JCgoMTAwLXBjdCkpCiAgbG9nIElORk8gIkRhdGFiYXNlIGZpbGVzeXN0ZW06ICR7ZnM6LXVua25vd259IG1vdW50ZWQgb24gJHttb3VudDotdW5rbm93bn07IGZyZWU9JHtmcmVlX2difSBHQiAoJHtmcmVlX3BjdH0lKSIKICBpZiAoKCBmcmVlX2diIDwgTUlOX0ZSRUVfR0IgfHwgZnJlZV9wY3QgPCBNSU5fRlJFRV9QRVJDRU5UICkpOyB0aGVuIGxvZyBFUlJPUiAiSW5zdWZmaWNpZW50IGZyZWUgZGlzayBzcGFjZSI7IHJldHVybiAxOyBmaQogIGNwdXM9IiQoZ2V0Y29uZiBfTlBST0NFU1NPUlNfT05MTiAyPi9kZXYvbnVsbCB8fCBlY2hvIDEpIjsgbG9hZD0iJChhd2sgJ3twcmludCAkMX0nIC9wcm9jL2xvYWRhdmcgMj4vZGV2L251bGwpIgogIG1heD0iJChhd2sgLXYgYz0iJGNwdXMiIC12IHA9IiRNQVhfTE9BRF9QRVJfQ1BVIiAnQkVHSU57cHJpbnRmICIlLjJmIixjKnB9JykiCiAgaWYgISBhd2sgLXYgbD0iJGxvYWQiIC12IG09IiRtYXgiICdCRUdJTntleGl0ICEobDw9bSl9JzsgdGhlbiBsb2cgRVJST1IgIlNlcnZlciBsb2FkICRsb2FkIGV4Y2VlZHMgc2FmZSBsaW1pdCAkbWF4IjsgcmV0dXJuIDE7IGZpCiAgaW93YWl0PSIiCiAgaWYgY29tbWFuZCAtdiBtcHN0YXQgPi9kZXYvbnVsbCAyPiYxOyB0aGVuIGlvd2FpdD0iJChMQ19BTEw9QyBtcHN0YXQgMSAxIDI+L2Rldi9udWxsIHwgYXdrICcvQXZlcmFnZTovICYmICgkMj09ImFsbCIgfHwgJDM9PSJhbGwiKSB7cHJpbnQgJChORi0zKTsgZXhpdH0nKSI7IGZpCiAgaWYgW1sgIiRpb3dhaXQiID1+IF5bMC05XSsoWy5dWzAtOV0rKT8kIF1dICYmICEgYXdrIC12IGk9IiRpb3dhaXQiIC12IG09IiRNQVhfSU9XQUlUX1BFUkNFTlQiICdCRUdJTntleGl0ICEoaTw9bSl9JzsgdGhlbiBsb2cgRVJST1IgIkkvTyB3YWl0ICR7aW93YWl0fSUgZXhjZWVkcyBzYWZlIGxpbWl0IjsgcmV0dXJuIDE7IGZpCiAgaWYgISBkYl9xdWVyeSAtZSAnU0VMRUNUIDEnID4vZGV2L251bGwgMj4mMTsgdGhlbiBsb2cgRVJST1IgIkRhdGFiYXNlIHNlcnZpY2UgaXMgbm90IHJlc3BvbmRpbmciOyByZXR1cm4gMTsgZmkKICByZXR1cm4gMAp9Cgpjb25maXJtX3NhZmVfcnVuKCl7CiAgW1sgIiRNT0RFIiA9PSBhdWRpdCBdXSAmJiByZXR1cm4gMAogIHNheSAiIgogIHNheSAiTUdIIFNBRkUtUlVOIHdpbGwgcHJvY2VzcyBBTEwgZWxpZ2libGUgZGF0YWJhc2VzIG9uIHRoaXMgc2VydmVyLiIKICBzYXkgIkl0IHdpbGwgbmV2ZXIgZHJvcCB0YWJsZXMsIGRlbGV0ZSBwb3N0cy91c2Vycy9vcmRlcnMsIHB1cmdlIGJpbmFyeSBsb2dzLCBvciBmb3JjZSBJbm5vREIgcmVjb3ZlcnkuIgogIHNheSAiSXQgbWF5IHJlcGFpciBjb25maXJtZWQgTXlJU0FNIGVycm9ycywgcmVtb3ZlIG9ubHkgZXhwaXJlZCBXb3JkUHJlc3MgdGVtcG9yYXJ5IHJlY29yZHMsIgogIHNheSAicmVtb3ZlIG9sZCB0ZXJtaW5hbCBBY3Rpb24gU2NoZWR1bGVyIHJlY29yZHMgYW5kIG9ycGhhbiBsb2dzLCBhbmFseXplIGFsbCBJbm5vREIgdGFibGVzLCIKICBzYXkgImFuZCBvcHRpbWl6ZSBlbGlnaWJsZSBNeUlTQU0vQXJpYSB0YWJsZXMgYWZ0ZXIgYSBsb2NhbCBjb21wcmVzc2VkIGR1bXAuXG5Jbm5vREIgc3RhdGlzdGljcyBhcmUgYW5hbHl6ZWQgaW4gY29uc2VydmF0aXZlIGJhdGNoZXMgd2l0aCBhdXRvbWF0aWMgcGVyLXRhYmxlIGZhbGxiYWNrLiIKICBzYXkgIiIKICBbWyAiJEFTU1VNRV9ZRVMiID09IHllcyBdXSAmJiByZXR1cm4gMAogIHByaW50ZiAnVHlwZSBTQUZFLVJVTiB0byBjb250aW51ZTogJwogIGxvY2FsIGFuc3dlcj0iIjsgSUZTPSByZWFkIC1yIGFuc3dlcgogIFtbICIkYW5zd2VyIiA9PSAiU0FGRS1SVU4iIF1dIHx8IHsgbG9nIFdBUk4gIkNhbmNlbGxlZCBieSBhZG1pbmlzdHJhdG9yIjsgZXhpdCAwOyB9Cn0KCmlzX2V4Y2x1ZGVkX2RiKCl7IGxvY2FsIGQ9IiQxIjsgW1sgIiRkIiA9fiAkRVhDTFVERURfREJfUkVHRVggXV07IH0KaXNfc2Vuc2l0aXZlX2RiKCl7IGxvY2FsIGQ9IiQxIjsgW1sgIiR7ZCwsfSIgPX4gJFNFTlNJVElWRV9EQl9SRUdFWCBdXTsgfQpvd25lcl9mb3JfZGIoKXsKICBsb2NhbCBkPSIkMSIgbz0iIgogIGlmIFtbIC1yIC92YXIvY3BhbmVsL2RhdGFiYXNlcy9kYmluZGV4LmRiIF1dOyB0aGVuIG89IiQoYXdrIC1GOiAtdiBxPSIkZCIgJyQxPT1xe3ByaW50ICQyO2V4aXR9JyAvdmFyL2NwYW5lbC9kYXRhYmFzZXMvZGJpbmRleC5kYiAyPi9kZXYvbnVsbCkiOyBmaQogIFtbIC1uICIkbyIgXV0gfHwgbz0iJHtkJSVfKn0iCiAgcHJpbnRmICclcycgIiRvIgp9CgpkYl9zaXplX21iKCl7IGRiX3F1ZXJ5IC1lICJTRUxFQ1QgUk9VTkQoQ09BTEVTQ0UoU1VNKERBVEFfTEVOR1RIK0lOREVYX0xFTkdUSCksMCkvMTAyNC8xMDI0KSBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5UQUJMRVMgV0hFUkUgVEFCTEVfU0NIRU1BPSckKHNxbF9saXQgIiQxIiknIiAyPi9kZXYvbnVsbCB8IGhlYWQgLW4xOyB9CmRiX3RhYmxlX2NvdW50KCl7IGRiX3F1ZXJ5IC1lICJTRUxFQ1QgQ09VTlQoKikgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEuVEFCTEVTIFdIRVJFIFRBQkxFX1NDSEVNQT0nJChzcWxfbGl0ICIkMSIpJyBBTkQgVEFCTEVfVFlQRT0nQkFTRSBUQUJMRSciIDI+L2Rldi9udWxsIHwgaGVhZCAtbjE7IH0KCndwX3ByZWZpeGVzKCl7CiAgbG9jYWwgZD0iJChzcWxfbGl0ICIkMSIpIgogIGRiX3F1ZXJ5IC1lICJTRUxFQ1QgRElTVElOQ1QgTEVGVChvLlRBQkxFX05BTUUsTEVOR1RIKG8uVEFCTEVfTkFNRSktNykgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEuVEFCTEVTIG8gV0hFUkUgby5UQUJMRV9TQ0hFTUE9JyRkJyBBTkQgby5UQUJMRV9UWVBFPSdCQVNFIFRBQkxFJyBBTkQgUklHSFQoby5UQUJMRV9OQU1FLDgpPSdfb3B0aW9ucycgQU5EIEVYSVNUUyhTRUxFQ1QgMSBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5UQUJMRVMgcCBXSEVSRSBwLlRBQkxFX1NDSEVNQT1vLlRBQkxFX1NDSEVNQSBBTkQgcC5UQUJMRV9OQU1FPUNPTkNBVChMRUZUKG8uVEFCTEVfTkFNRSxMRU5HVEgoby5UQUJMRV9OQU1FKS03KSwncG9zdHMnKSkiIDI+L2Rldi9udWxsCn0KCm1ha2VfZHVtcCgpewogIGxvY2FsIGRiPSIkMSIgc2l6ZT0iJDIiIG91dCBmcmVlX21iIHJlcXVpcmVkX21iCiAgW1sgIiRNT0RFIiA9PSBzYWZlLXJ1biBdXSB8fCByZXR1cm4gMAogIFtbIC1uICIkREJfRFVNUCIgXV0gfHwgeyBsb2cgV0FSTiAiTm8gZHVtcCB1dGlsaXR5OyBza2lwcGluZyBhbGwgY2hhbmdlcyBmb3IgJGRiIjsgcmV0dXJuIDE7IH0KICBbWyAiJHNpemUiID1+IF5bMC05XSskIF1dIHx8IHNpemU9MAoKICAjIE1BWF9EQl9EVU1QX01CPTAgbWVhbnMgbm8gYXJiaXRyYXJ5IGRhdGFiYXNlLXNpemUgY2FwLgogIGlmICgoIE1BWF9EQl9EVU1QX01CID4gMCAmJiBzaXplID4gTUFYX0RCX0RVTVBfTUIgKSk7IHRoZW4KICAgIGxvZyBXQVJOICJTa2lwcGluZyBjaGFuZ2VzIGZvciAkZGI6ICR7c2l6ZX0gTUIgZXhjZWVkcyBjb25maWd1cmVkIGR1bXAgbGltaXQgJHtNQVhfREJfRFVNUF9NQn0gTUIiCiAgICByZXR1cm4gMQogIGZpCgogIGZyZWVfbWI9IiQoZGYgLVBtICIkRFVNUF9ESVIiIDI+L2Rldi9udWxsIHwgYXdrICdOUj09MntwcmludCAkNH0nKSIKICBbWyAiJGZyZWVfbWIiID1+IF5bMC05XSskIF1dIHx8IGZyZWVfbWI9MAogIHJlcXVpcmVkX21iPSQoKCBzaXplICsgKE1JTl9GUkVFX0dCICogMTAyNCkgKSkKCiAgaWYgKCggZnJlZV9tYiA8IHJlcXVpcmVkX21iICkpOyB0aGVuCiAgICBsb2cgV0FSTiAiU2tpcHBpbmcgY2hhbmdlcyBmb3IgJGRiOiBuZWVkIGFwcHJveGltYXRlbHkgJHtyZXF1aXJlZF9tYn0gTUIgZnJlZSB0byBwcmVzZXJ2ZSBzYWZldHkgbWFyZ2luOyBhdmFpbGFibGU9JHtmcmVlX21ifSBNQiIKICAgIHJldHVybiAxCiAgZmkKCiAgb3V0PSIkRFVNUF9ESVIvJHtkYn0tJHtSVU5fSUR9LnNxbC5neiIKICBpZiAoKCBzaXplID49IDQwOTYgKSk7IHRoZW4KICAgIGxvZyBJTkZPICJDcmVhdGluZyBzdHJlYW1lZCBjb21wcmVzc2VkIHByZS1jaGFuZ2UgZHVtcCBmb3IgbGFyZ2UgZGF0YWJhc2UgJGRiICgke3NpemV9IE1CKTsgbm8gc2l6ZS1iYXNlZCBza2lwIgogIGVsc2UKICAgIGxvZyBJTkZPICJDcmVhdGluZyBsb2NhbCBwcmUtY2hhbmdlIGR1bXAgZm9yICRkYiIKICBmaQoKICBpZiBkdW1wX2NvbW1hbmQgLS1zaW5nbGUtdHJhbnNhY3Rpb24gLS1xdWljayAtLXJvdXRpbmVzIC0tZXZlbnRzIC0tdHJpZ2dlcnMgLS1oZXgtYmxvYiAiJGRiIiAyPj4iJERFVEFJTCIgfCBnemlwIC0xID4gIiRvdXQiOyB0aGVuCiAgICBpZiBbWyAtcyAiJG91dCIgXV07IHRoZW4KICAgICAgaWYgZ3ppcCAtdCAiJG91dCIgMj4+IiRERVRBSUwiOyB0aGVuCiAgICAgICAgY2htb2QgNjAwICIkb3V0IgogICAgICAgIGxvZyBJTkZPICJWZXJpZmllZCBwcmUtY2hhbmdlIGR1bXAgZm9yICRkYjogJG91dCIKICAgICAgICByZXR1cm4gMAogICAgICBmaQogICAgICBsb2cgV0FSTiAiQ29tcHJlc3NlZCBkdW1wIHZlcmlmaWNhdGlvbiBmYWlsZWQgZm9yICRkYiIKICAgIGZpCiAgZmkKICBybSAtZiAiJG91dCIKICBsb2cgV0FSTiAiRHVtcCBmYWlsZWQ7IHNraXBwaW5nIGV2ZXJ5IGNoYW5nZSBmb3IgJGRiIgogIHJldHVybiAxCn0KCmNoZWNrX3RhYmxlcygpewogIGxvY2FsIGRiPSIkMSIgY291bnQ9IiQyIiBvdXRwdXQgcmMgb2sgdW5zdXBwb3J0ZWQgYmFkCiAgaWYgW1sgLW4gIiREQl9DSEVDSyIgXV07IHRoZW4KICAgIG91dHB1dD0iJChjaGVja19jb21tYW5kIC0tY2hlY2sgLS1xdWljayAiJGRiIiAyPiYxKSI7IHJjPSQ/CiAgICBwcmludGYgJyVzXG4nICIkb3V0cHV0IiA+PiAiJERFVEFJTCIKICAgIG9rPSIkKGdyZXAgLWNFICdbWzpzcGFjZTpdXU9LJCcgPDw8ICIkb3V0cHV0IiB8fCB0cnVlKSIKICAgIHVuc3VwcG9ydGVkPSIkKGdyZXAgLWNpRSAiZG9lc24ndCBzdXBwb3J0IGNoZWNrfGRvZXMgbm90IHN1cHBvcnQgY2hlY2t8bm90IHN1cHBvcnRlZCBmb3IgdGhpcyBlbmdpbmUiIDw8PCAiJG91dHB1dCIgfHwgdHJ1ZSkiCiAgICBbWyAiJG9rIiA9fiBeWzAtOV0rJCBdXSB8fCBvaz0wCiAgICBbWyAiJHVuc3VwcG9ydGVkIiA9fiBeWzAtOV0rJCBdXSB8fCB1bnN1cHBvcnRlZD0wCiAgICBiYWQ9JCgoY291bnQtb2stdW5zdXBwb3J0ZWQpKTsgKCggYmFkIDwgMCApKSAmJiBiYWQ9MAogICAgVEFCTEVTX0NIRUNLRUQ9JCgoVEFCTEVTX0NIRUNLRUQrY291bnQpKQogICAgVEFCTEVTX09LPSQoKFRBQkxFU19PSytvaykpCiAgICBUQUJMRVNfVU5TVVBQT1JURUQ9JCgoVEFCTEVTX1VOU1VQUE9SVEVEK3Vuc3VwcG9ydGVkKSkKICAgIFRBQkxFU19CQUQ9JCgoVEFCTEVTX0JBRCtiYWQpKQogICAgaWYgKCggdW5zdXBwb3J0ZWQgPiAwICkpOyB0aGVuIGxvZyBJTkZPICIkZGI6ICR1bnN1cHBvcnRlZCB0YWJsZSBjaGVjayhzKSB1bnN1cHBvcnRlZCBieSBzdG9yYWdlIGVuZ2luZTsgbm90IHRyZWF0ZWQgYXMgZGFtYWdlIjsgZmkKICAgIGlmICgoIGJhZCA+IDAgKSk7IHRoZW4KICAgICAgbG9nIFdBUk4gIiRkYjogJGJhZCB0YWJsZSByZXN1bHQocykgcmVxdWlyZSByZXZpZXciCiAgICAgIHByaW50ZiAnJXNcbicgIiRvdXRwdXQiIHwgZ3JlcCAtdkUgJ1tbOnNwYWNlOl1dT0skfGRvZXNuLnQgc3VwcG9ydCBjaGVja3xkb2VzIG5vdCBzdXBwb3J0IGNoZWNrfG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgZW5naW5lfF5bWzpzcGFjZTpdXSokJyA+PiAiJFJFUE9SVCIgfHwgdHJ1ZQogICAgZmkKICAgIHJldHVybiAwCiAgZmkKICBsb2cgV0FSTiAiTm8gbXlzcWxjaGVjay9tYXJpYWRiLWNoZWNrIHV0aWxpdHk7IHVzaW5nIFNRTCBDSEVDSyBUQUJMRSBwZXIgdGFibGUiCiAgbG9jYWwgdCBxZCBxdCByZXMKICB3aGlsZSBJRlM9IHJlYWQgLXIgdDsgZG8KICAgIFtbIC1uICIkdCIgXV0gfHwgY29udGludWUKICAgIHFkPSIkKHF1b3RlX2lkZW50ICIkZGIiKSI7IHF0PSIkKHF1b3RlX2lkZW50ICIkdCIpIgogICAgcmVzPSIkKGRiX3F1ZXJ5IC1lICJDSEVDSyBUQUJMRSAkcWQuJHF0IFFVSUNLIiAyPiYxKSI7IHByaW50ZiAnJXNcbicgIiRyZXMiID4+ICIkREVUQUlMIgogICAgVEFCTEVTX0NIRUNLRUQ9JCgoVEFCTEVTX0NIRUNLRUQrMSkpCiAgICBpZiBncmVwIC1xICQnc3RhdHVzXHRPSycgPDw8ICIkcmVzIjsgdGhlbiBUQUJMRVNfT0s9JCgoVEFCTEVTX09LKzEpKQogICAgZWxpZiBncmVwIC1xaUUgImRvZXNuJ3Qgc3VwcG9ydCBjaGVja3xkb2VzIG5vdCBzdXBwb3J0IGNoZWNrfG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgZW5naW5lIiA8PDwgIiRyZXMiOyB0aGVuIFRBQkxFU19VTlNVUFBPUlRFRD0kKChUQUJMRVNfVU5TVVBQT1JURUQrMSkpCiAgICBlbHNlIFRBQkxFU19CQUQ9JCgoVEFCTEVTX0JBRCsxKSk7IGxvZyBXQVJOICJUYWJsZSBjaGVjayBpc3N1ZTogJGRiLiR0IjsgZmkKICBkb25lIDwgPChkYl9xdWVyeSAtZSAiU0VMRUNUIFRBQkxFX05BTUUgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEuVEFCTEVTIFdIRVJFIFRBQkxFX1NDSEVNQT0nJChzcWxfbGl0ICIkZGIiKScgQU5EIFRBQkxFX1RZUEU9J0JBU0UgVEFCTEUnIiAyPi9kZXYvbnVsbCkKICByZXR1cm4gMAp9CgpyZXBhaXJfbXlpc2FtKCl7CiAgbG9jYWwgZGI9IiQxIiBjaGFuZ2VkPTAgdCBlbmdpbmUgcWQgcXQgcmVzCiAgd2hpbGUgSUZTPSQnXHQnIHJlYWQgLXIgdCBlbmdpbmU7IGRvCiAgICBbWyAtbiAiJHQiIF1dIHx8IGNvbnRpbnVlCiAgICBjYXNlICIke2VuZ2luZV5efSIgaW4gTVlJU0FNfEFSQ0hJVkV8Q1NWKSA7OyAqKSBjb250aW51ZSA7OyBlc2FjCiAgICBxZD0iJChxdW90ZV9pZGVudCAiJGRiIikiOyBxdD0iJChxdW90ZV9pZGVudCAiJHQiKSIKICAgIHJlcz0iJChkYl9xdWVyeSAtZSAiQ0hFQ0sgVEFCTEUgJHFkLiRxdCBFWFRFTkRFRCIgMj4mMSkiOyBwcmludGYgJyVzXG4nICIkcmVzIiA+PiAiJERFVEFJTCIKICAgIGlmIGdyZXAgLUVxICQnXHQoZXJyb3J8d2FybmluZylcdCcgPDw8ICIkcmVzIjsgdGhlbgogICAgICBsb2cgV0FSTiAiQ29uZmlybWVkIHJlcGFpcmFibGUgZXJyb3I6ICRkYi4kdCAoJGVuZ2luZSkiCiAgICAgIGlmIGRiX3F1ZXJ5IC1lICJSRVBBSVIgVEFCTEUgJHFkLiRxdCIgPj4iJERFVEFJTCIgMj4mMTsgdGhlbiBUQUJMRVNfUkVQQUlSRUQ9JCgoVEFCTEVTX1JFUEFJUkVEKzEpKTsgY2hhbmdlZD0xOyBlbHNlIGxvZyBXQVJOICJSZXBhaXIgZmFpbGVkOiAkZGIuJHQiOyBmaQogICAgZmkKICBkb25lIDwgPChkYl9xdWVyeSAtZSAiU0VMRUNUIFRBQkxFX05BTUUsQ09BTEVTQ0UoRU5HSU5FLCcnKSBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5UQUJMRVMgV0hFUkUgVEFCTEVfU0NIRU1BPSckKHNxbF9saXQgIiRkYiIpJyBBTkQgVEFCTEVfVFlQRT0nQkFTRSBUQUJMRSciIDI+L2Rldi9udWxsKQogIHJldHVybiAkY2hhbmdlZAp9Cgp0YWJsZV9leGlzdHMoKXsKICBsb2NhbCBkYj0iJDEiIHRhYmxlPSIkMiIgbgogIG49IiQoZGJfcXVlcnkgLWUgIlNFTEVDVCBDT1VOVCgqKSBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5UQUJMRVMgV0hFUkUgVEFCTEVfU0NIRU1BPSckKHNxbF9saXQgIiRkYiIpJyBBTkQgVEFCTEVfTkFNRT0nJChzcWxfbGl0ICIkdGFibGUiKSciIDI+L2Rldi9udWxsIHwgaGVhZCAtbjEpIgogIFtbICIkbiIgPT0gMSBdXQp9Cgp3cF9vcHBvcnR1bml0eV9hdWRpdCgpewogIGxvY2FsIGRiPSIkMSIgcHJlZml4IHFkIHBvc3RzIGNvbW1lbnRzIG9wdGlvbnMgYWN0aW9ucyBsb2dzIG4gY29tcGxldGUgY2FuY2VsZWQgZmFpbGVkIG9ycGhhbiByZXZpc2lvbnMgYXV0b2RyYWZ0cyB0cmFzaHBvc3RzIHNwYW0gdHJhc2hjb21tZW50cyBhdXRvbG9hZAogIHdoaWxlIElGUz0gcmVhZCAtciBwcmVmaXg7IGRvCiAgICBbWyAtbiAiJHByZWZpeCIgXV0gfHwgY29udGludWUKICAgIHFkPSIkKHF1b3RlX2lkZW50ICIkZGIiKSIKICAgIHBvc3RzPSIkKHF1b3RlX2lkZW50ICIke3ByZWZpeH1wb3N0cyIpIjsgY29tbWVudHM9IiQocXVvdGVfaWRlbnQgIiR7cHJlZml4fWNvbW1lbnRzIikiOyBvcHRpb25zPSIkKHF1b3RlX2lkZW50ICIke3ByZWZpeH1vcHRpb25zIikiCiAgICByZXZpc2lvbnM9IiQoZGJfcXVlcnkgLWUgIlNFTEVDVCBDT1VOVCgqKSBGUk9NICRxZC4kcG9zdHMgV0hFUkUgcG9zdF90eXBlPSdyZXZpc2lvbiciIDI+L2Rldi9udWxsIHwgaGVhZCAtbjEpIjsgW1sgIiRyZXZpc2lvbnMiID1+IF5bMC05XSskIF1dIHx8IHJldmlzaW9ucz0wCiAgICBhdXRvZHJhZnRzPSIkKGRiX3F1ZXJ5IC1lICJTRUxFQ1QgQ09VTlQoKikgRlJPTSAkcWQuJHBvc3RzIFdIRVJFIHBvc3Rfc3RhdHVzPSdhdXRvLWRyYWZ0JyIgMj4vZGV2L251bGwgfCBoZWFkIC1uMSkiOyBbWyAiJGF1dG9kcmFmdHMiID1+IF5bMC05XSskIF1dIHx8IGF1dG9kcmFmdHM9MAogICAgdHJhc2hwb3N0cz0iJChkYl9xdWVyeSAtZSAiU0VMRUNUIENPVU5UKCopIEZST00gJHFkLiRwb3N0cyBXSEVSRSBwb3N0X3N0YXR1cz0ndHJhc2gnIiAyPi9kZXYvbnVsbCB8IGhlYWQgLW4xKSI7IFtbICIkdHJhc2hwb3N0cyIgPX4gXlswLTldKyQgXV0gfHwgdHJhc2hwb3N0cz0wCiAgICBzcGFtPTA7IHRyYXNoY29tbWVudHM9MAogICAgaWYgdGFibGVfZXhpc3RzICIkZGIiICIke3ByZWZpeH1jb21tZW50cyI7IHRoZW4KICAgICAgc3BhbT0iJChkYl9xdWVyeSAtZSAiU0VMRUNUIENPVU5UKCopIEZST00gJHFkLiRjb21tZW50cyBXSEVSRSBjb21tZW50X2FwcHJvdmVkPSdzcGFtJyIgMj4vZGV2L251bGwgfCBoZWFkIC1uMSkiOyBbWyAiJHNwYW0iID1+IF5bMC05XSskIF1dIHx8IHNwYW09MAogICAgICB0cmFzaGNvbW1lbnRzPSIkKGRiX3F1ZXJ5IC1lICJTRUxFQ1QgQ09VTlQoKikgRlJPTSAkcWQuJGNvbW1lbnRzIFdIRVJFIGNvbW1lbnRfYXBwcm92ZWQ9J3RyYXNoJyIgMj4vZGV2L251bGwgfCBoZWFkIC1uMSkiOyBbWyAiJHRyYXNoY29tbWVudHMiID1+IF5bMC05XSskIF1dIHx8IHRyYXNoY29tbWVudHM9MAogICAgZmkKICAgIGF1dG9sb2FkPSIkKGRiX3F1ZXJ5IC1lICJTRUxFQ1QgQ09BTEVTQ0UoU1VNKExFTkdUSChvcHRpb25fdmFsdWUpKSwwKSBGUk9NICRxZC4kb3B0aW9ucyBXSEVSRSBhdXRvbG9hZCBJTiAoJ3llcycsJ29uJywnYXV0by1vbicsJ2F1dG8nKSIgMj4vZGV2L251bGwgfCBoZWFkIC1uMSkiOyBbWyAiJGF1dG9sb2FkIiA9fiBeWzAtOV0rJCBdXSB8fCBhdXRvbG9hZD0wCiAgICBXUF9SRVZJU0lPTlNfRk9VTkQ9JCgoV1BfUkVWSVNJT05TX0ZPVU5EK3JldmlzaW9ucykpOyBXUF9BVVRPRFJBRlRTX0ZPVU5EPSQoKFdQX0FVVE9EUkFGVFNfRk9VTkQrYXV0b2RyYWZ0cykpOyBXUF9UUkFTSF9QT1NUU19GT1VORD0kKChXUF9UUkFTSF9QT1NUU19GT1VORCt0cmFzaHBvc3RzKSkKICAgIFdQX1NQQU1fQ09NTUVOVFNfRk9VTkQ9JCgoV1BfU1BBTV9DT01NRU5UU19GT1VORCtzcGFtKSk7IFdQX1RSQVNIX0NPTU1FTlRTX0ZPVU5EPSQoKFdQX1RSQVNIX0NPTU1FTlRTX0ZPVU5EK3RyYXNoY29tbWVudHMpKTsgV1BfQVVUT0xPQURfQllURVM9JCgoV1BfQVVUT0xPQURfQllURVMrYXV0b2xvYWQpKQoKICAgIGFjdGlvbnM9IiR7cHJlZml4fWFjdGlvbnNjaGVkdWxlcl9hY3Rpb25zIjsgbG9ncz0iJHtwcmVmaXh9YWN0aW9uc2NoZWR1bGVyX2xvZ3MiCiAgICBpZiB0YWJsZV9leGlzdHMgIiRkYiIgIiRhY3Rpb25zIjsgdGhlbgogICAgICBjb21wbGV0ZT0iJChkYl9xdWVyeSAtZSAiU0VMRUNUIENPVU5UKCopIEZST00gJHFkLiQocXVvdGVfaWRlbnQgIiRhY3Rpb25zIikgV0hFUkUgc3RhdHVzPSdjb21wbGV0ZScgQU5EIHNjaGVkdWxlZF9kYXRlX2dtdCA8IFVUQ19USU1FU1RBTVAoKS1JTlRFUlZBTCAke0FDVElPTl9TQ0hFRFVMRVJfQ09NUExFVEVfREFZU30gREFZIiAyPi9kZXYvbnVsbCB8IGhlYWQgLW4xKSI7IFtbICIkY29tcGxldGUiID1+IF5bMC05XSskIF1dIHx8IGNvbXBsZXRlPTAKICAgICAgY2FuY2VsZWQ9IiQoZGJfcXVlcnkgLWUgIlNFTEVDVCBDT1VOVCgqKSBGUk9NICRxZC4kKHF1b3RlX2lkZW50ICIkYWN0aW9ucyIpIFdIRVJFIHN0YXR1cz0nY2FuY2VsZWQnIEFORCBzY2hlZHVsZWRfZGF0ZV9nbXQgPCBVVENfVElNRVNUQU1QKCktSU5URVJWQUwgJHtBQ1RJT05fU0NIRURVTEVSX0NBTkNFTEVEX0RBWVN9IERBWSIgMj4vZGV2L251bGwgfCBoZWFkIC1uMSkiOyBbWyAiJGNhbmNlbGVkIiA9fiBeWzAtOV0rJCBdXSB8fCBjYW5jZWxlZD0wCiAgICAgIGZhaWxlZD0iJChkYl9xdWVyeSAtZSAiU0VMRUNUIENPVU5UKCopIEZST00gJHFkLiQocXVvdGVfaWRlbnQgIiRhY3Rpb25zIikgV0hFUkUgc3RhdHVzPSdmYWlsZWQnIEFORCBzY2hlZHVsZWRfZGF0ZV9nbXQgPCBVVENfVElNRVNUQU1QKCktSU5URVJWQUwgJHtBQ1RJT05fU0NIRURVTEVSX0ZBSUxFRF9EQVlTfSBEQVkiIDI+L2Rldi9udWxsIHwgaGVhZCAtbjEpIjsgW1sgIiRmYWlsZWQiID1+IF5bMC05XSskIF1dIHx8IGZhaWxlZD0wCiAgICAgIG9ycGhhbj0wCiAgICAgIGlmIHRhYmxlX2V4aXN0cyAiJGRiIiAiJGxvZ3MiOyB0aGVuCiAgICAgICAgb3JwaGFuPSIkKGRiX3F1ZXJ5IC1lICJTRUxFQ1QgQ09VTlQoKikgRlJPTSAkcWQuJChxdW90ZV9pZGVudCAiJGxvZ3MiKSBsIExFRlQgSk9JTiAkcWQuJChxdW90ZV9pZGVudCAiJGFjdGlvbnMiKSBhIE9OIGEuYWN0aW9uX2lkPWwuYWN0aW9uX2lkIFdIRVJFIGEuYWN0aW9uX2lkIElTIE5VTEwiIDI+L2Rldi9udWxsIHwgaGVhZCAtbjEpIjsgW1sgIiRvcnBoYW4iID1+IF5bMC05XSskIF1dIHx8IG9ycGhhbj0wCiAgICAgIGZpCiAgICAgIEFTX0NPTVBMRVRFX0NBTkRJREFURVM9JCgoQVNfQ09NUExFVEVfQ0FORElEQVRFUytjb21wbGV0ZSkpOyBBU19DQU5DRUxFRF9DQU5ESURBVEVTPSQoKEFTX0NBTkNFTEVEX0NBTkRJREFURVMrY2FuY2VsZWQpKTsgQVNfRkFJTEVEX0NBTkRJREFURVM9JCgoQVNfRkFJTEVEX0NBTkRJREFURVMrZmFpbGVkKSk7IEFTX09SUEhBTl9MT0dTPSQoKEFTX09SUEhBTl9MT0dTK29ycGhhbikpCiAgICAgIGlmICgoIGNvbXBsZXRlK2NhbmNlbGVkK2ZhaWxlZCtvcnBoYW4gPiAwICkpOyB0aGVuIGxvZyBJTkZPICJBY3Rpb24gU2NoZWR1bGVyIG9wcG9ydHVuaXR5ICRkYi8kcHJlZml4OiBjb21wbGV0ZT0kY29tcGxldGUgY2FuY2VsZWQ9JGNhbmNlbGVkIGZhaWxlZD0kZmFpbGVkIG9ycGhhbl9sb2dzPSRvcnBoYW4iOyBmaQogICAgZmkKICAgIGlmICgoIHJldmlzaW9ucythdXRvZHJhZnRzK3RyYXNocG9zdHMrc3BhbSt0cmFzaGNvbW1lbnRzID4gMCB8fCBhdXRvbG9hZCA+IDEwNDg1NzYgKSk7IHRoZW4KICAgICAgbG9nIElORk8gIldQIGRpYWdub3N0aWMgJGRiLyRwcmVmaXg6IHJldmlzaW9ucz0kcmV2aXNpb25zIGF1dG9fZHJhZnRzPSRhdXRvZHJhZnRzIHRyYXNoX3Bvc3RzPSR0cmFzaHBvc3RzIHNwYW1fY29tbWVudHM9JHNwYW0gdHJhc2hfY29tbWVudHM9JHRyYXNoY29tbWVudHMgYXV0b2xvYWRfYnl0ZXM9JGF1dG9sb2FkIChkaWFnbm9zdGljIG9ubHkpIgogICAgZmkKICBkb25lIDwgPCh3cF9wcmVmaXhlcyAiJGRiIikKfQoKY2xlYW51cF9hY3Rpb25fc2NoZWR1bGVyKCl7CiAgbG9jYWwgZGI9IiQxIiBwcmVmaXggcWQgYWN0aW9ucyBsb2dzIHFhIHFsIGNvbXBsZXRlIGNhbmNlbGVkIGZhaWxlZCBvcnBoYW4gdG90YWwgdGVybWluYWxfbG9ncwogIFtbICIkRU5BQkxFX0FDVElPTl9TQ0hFRFVMRVJfQ0xFQU5VUCIgPT0geWVzIF1dIHx8IHJldHVybiAwCiAgd2hpbGUgSUZTPSByZWFkIC1yIHByZWZpeDsgZG8KICAgIFtbIC1uICIkcHJlZml4IiBdXSB8fCBjb250aW51ZQogICAgYWN0aW9ucz0iJHtwcmVmaXh9YWN0aW9uc2NoZWR1bGVyX2FjdGlvbnMiOyBsb2dzPSIke3ByZWZpeH1hY3Rpb25zY2hlZHVsZXJfbG9ncyIKICAgIHRhYmxlX2V4aXN0cyAiJGRiIiAiJGFjdGlvbnMiIHx8IGNvbnRpbnVlCiAgICBxZD0iJChxdW90ZV9pZGVudCAiJGRiIikiOyBxYT0iJChxdW90ZV9pZGVudCAiJGFjdGlvbnMiKSI7IHFsPSIkKHF1b3RlX2lkZW50ICIkbG9ncyIpIgogICAgY29tcGxldGU9IiQoZGJfcXVlcnkgLWUgIlNFTEVDVCBDT1VOVCgqKSBGUk9NICRxZC4kcWEgV0hFUkUgc3RhdHVzPSdjb21wbGV0ZScgQU5EIHNjaGVkdWxlZF9kYXRlX2dtdCA8IFVUQ19USU1FU1RBTVAoKS1JTlRFUlZBTCAke0FDVElPTl9TQ0hFRFVMRVJfQ09NUExFVEVfREFZU30gREFZIiAyPi9kZXYvbnVsbCB8IGhlYWQgLW4xKSI7IFtbICIkY29tcGxldGUiID1+IF5bMC05XSskIF1dIHx8IGNvbXBsZXRlPTAKICAgIGNhbmNlbGVkPSIkKGRiX3F1ZXJ5IC1lICJTRUxFQ1QgQ09VTlQoKikgRlJPTSAkcWQuJHFhIFdIRVJFIHN0YXR1cz0nY2FuY2VsZWQnIEFORCBzY2hlZHVsZWRfZGF0ZV9nbXQgPCBVVENfVElNRVNUQU1QKCktSU5URVJWQUwgJHtBQ1RJT05fU0NIRURVTEVSX0NBTkNFTEVEX0RBWVN9IERBWSIgMj4vZGV2L251bGwgfCBoZWFkIC1uMSkiOyBbWyAiJGNhbmNlbGVkIiA9fiBeWzAtOV0rJCBdXSB8fCBjYW5jZWxlZD0wCiAgICBmYWlsZWQ9IiQoZGJfcXVlcnkgLWUgIlNFTEVDVCBDT1VOVCgqKSBGUk9NICRxZC4kcWEgV0hFUkUgc3RhdHVzPSdmYWlsZWQnIEFORCBzY2hlZHVsZWRfZGF0ZV9nbXQgPCBVVENfVElNRVNUQU1QKCktSU5URVJWQUwgJHtBQ1RJT05fU0NIRURVTEVSX0ZBSUxFRF9EQVlTfSBEQVkiIDI+L2Rldi9udWxsIHwgaGVhZCAtbjEpIjsgW1sgIiRmYWlsZWQiID1+IF5bMC05XSskIF1dIHx8IGZhaWxlZD0wCiAgICB0b3RhbD0kKChjb21wbGV0ZStjYW5jZWxlZCtmYWlsZWQpKQogICAgb3JwaGFuPTA7IHRlcm1pbmFsX2xvZ3M9MAogICAgaWYgdGFibGVfZXhpc3RzICIkZGIiICIkbG9ncyI7IHRoZW4KICAgICAgb3JwaGFuPSIkKGRiX3F1ZXJ5IC1lICJTRUxFQ1QgQ09VTlQoKikgRlJPTSAkcWQuJHFsIGwgTEVGVCBKT0lOICRxZC4kcWEgYSBPTiBhLmFjdGlvbl9pZD1sLmFjdGlvbl9pZCBXSEVSRSBhLmFjdGlvbl9pZCBJUyBOVUxMIiAyPi9kZXYvbnVsbCB8IGhlYWQgLW4xKSI7IFtbICIkb3JwaGFuIiA9fiBeWzAtOV0rJCBdXSB8fCBvcnBoYW49MAogICAgICB0ZXJtaW5hbF9sb2dzPSIkKGRiX3F1ZXJ5IC1lICJTRUxFQ1QgQ09VTlQoKikgRlJPTSAkcWQuJHFsIGwgSk9JTiAkcWQuJHFhIGEgT04gYS5hY3Rpb25faWQ9bC5hY3Rpb25faWQgV0hFUkUgKGEuc3RhdHVzPSdjb21wbGV0ZScgQU5EIGEuc2NoZWR1bGVkX2RhdGVfZ210PFVUQ19USU1FU1RBTVAoKS1JTlRFUlZBTCAke0FDVElPTl9TQ0hFRFVMRVJfQ09NUExFVEVfREFZU30gREFZKSBPUiAoYS5zdGF0dXM9J2NhbmNlbGVkJyBBTkQgYS5zY2hlZHVsZWRfZGF0ZV9nbXQ8VVRDX1RJTUVTVEFNUCgpLUlOVEVSVkFMICR7QUNUSU9OX1NDSEVEVUxFUl9DQU5DRUxFRF9EQVlTfSBEQVkpIE9SIChhLnN0YXR1cz0nZmFpbGVkJyBBTkQgYS5zY2hlZHVsZWRfZGF0ZV9nbXQ8VVRDX1RJTUVTVEFNUCgpLUlOVEVSVkFMICR7QUNUSU9OX1NDSEVEVUxFUl9GQUlMRURfREFZU30gREFZKSIgMj4vZGV2L251bGwgfCBoZWFkIC1uMSkiOyBbWyAiJHRlcm1pbmFsX2xvZ3MiID1+IF5bMC05XSskIF1dIHx8IHRlcm1pbmFsX2xvZ3M9MAogICAgZmkKICAgIGlmICgoIHRvdGFsICsgb3JwaGFuID4gTUFYX0FDVElPTl9TQ0hFRFVMRVJfREVMRVRFX1JPV1MgKSk7IHRoZW4KICAgICAgQVNfU0tJUFBFRF9EQVRBQkFTRVM9JCgoQVNfU0tJUFBFRF9EQVRBQkFTRVMrMSkpOyBsb2cgV0FSTiAiU2tpcHBpbmcgQWN0aW9uIFNjaGVkdWxlciBjbGVhbnVwIGZvciAkZGIvJHByZWZpeDogJCgodG90YWwrb3JwaGFuKSkgcm93cyBleGNlZWRzIGxpbWl0ICRNQVhfQUNUSU9OX1NDSEVEVUxFUl9ERUxFVEVfUk9XUyI7IGNvbnRpbnVlCiAgICBmaQogICAgaWYgKCggdG90YWwgPT0gMCAmJiBvcnBoYW4gPT0gMCApKTsgdGhlbiBjb250aW51ZTsgZmkKICAgIGxvZyBJTkZPICJDbGVhbmluZyBvbGQgdGVybWluYWwgQWN0aW9uIFNjaGVkdWxlciBkYXRhIGluICRkYi8kcHJlZml4OiBhY3Rpb25zPSR0b3RhbCB0ZXJtaW5hbF9sb2dzPSR0ZXJtaW5hbF9sb2dzIG9ycGhhbl9sb2dzPSRvcnBoYW4iCiAgICBsb2NhbCBsb2dfY2xlYW51cF9vaz15ZXMKICAgIGlmIHRhYmxlX2V4aXN0cyAiJGRiIiAiJGxvZ3MiOyB0aGVuCiAgICAgICMgUnVuIGVhY2ggREVMRVRFIGluZGVwZW5kZW50bHkuIFRoaXMgZ2l2ZXMgYWNjdXJhdGUgZXJyb3IgcmVwb3J0aW5nIGFuZAogICAgICAjIGF2b2lkcyBhIG11bHRpLXN0YXRlbWVudCBmYWlsdXJlIGhpZGluZyB3aGljaCBvcGVyYXRpb24gd2FzIHJlamVjdGVkLgogICAgICBpZiAoKCB0ZXJtaW5hbF9sb2dzID4gMCApKTsgdGhlbgogICAgICAgIGlmIGRiX3F1ZXJ5IC1lICIKICAgICAgICAgIERFTEVURSBGUk9NICRxZC4kcWwKICAgICAgICAgIFdIRVJFIGFjdGlvbl9pZCBJTiAoCiAgICAgICAgICAgIFNFTEVDVCBhY3Rpb25faWQgRlJPTSAkcWQuJHFhCiAgICAgICAgICAgIFdIRVJFIChzdGF0dXM9J2NvbXBsZXRlJyBBTkQgc2NoZWR1bGVkX2RhdGVfZ210PFVUQ19USU1FU1RBTVAoKS1JTlRFUlZBTCAke0FDVElPTl9TQ0hFRFVMRVJfQ09NUExFVEVfREFZU30gREFZKQogICAgICAgICAgICAgICBPUiAoc3RhdHVzPSdjYW5jZWxlZCcgQU5EIHNjaGVkdWxlZF9kYXRlX2dtdDxVVENfVElNRVNUQU1QKCktSU5URVJWQUwgJHtBQ1RJT05fU0NIRURVTEVSX0NBTkNFTEVEX0RBWVN9IERBWSkKICAgICAgICAgICAgICAgT1IgKHN0YXR1cz0nZmFpbGVkJyBBTkQgc2NoZWR1bGVkX2RhdGVfZ210PFVUQ19USU1FU1RBTVAoKS1JTlRFUlZBTCAke0FDVElPTl9TQ0hFRFVMRVJfRkFJTEVEX0RBWVN9IERBWSkKICAgICAgICAgICkiID4+IiRERVRBSUwiIDI+JjE7IHRoZW4KICAgICAgICAgIEFTX0xPR1NfUkVNT1ZFRD0kKChBU19MT0dTX1JFTU9WRUQrdGVybWluYWxfbG9ncykpCiAgICAgICAgZWxzZQogICAgICAgICAgbG9nX2NsZWFudXBfb2s9bm8KICAgICAgICAgIGxvZyBXQVJOICJUZXJtaW5hbCBBY3Rpb24gU2NoZWR1bGVyIGxvZyBjbGVhbnVwIGZhaWxlZCBmb3IgJGRiLyRwcmVmaXg7IGFjdGlvbnMgcmV0YWluZWQiCiAgICAgICAgZmkKICAgICAgZmkKCiAgICAgIGlmICgoIG9ycGhhbiA+IDAgKSk7IHRoZW4KICAgICAgICBpZiBkYl9xdWVyeSAtZSAiCiAgICAgICAgICBERUxFVEUgbCBGUk9NICRxZC4kcWwgQVMgbAogICAgICAgICAgTEVGVCBKT0lOICRxZC4kcWEgQVMgYSBPTiBhLmFjdGlvbl9pZD1sLmFjdGlvbl9pZAogICAgICAgICAgV0hFUkUgYS5hY3Rpb25faWQgSVMgTlVMTCIgPj4iJERFVEFJTCIgMj4mMTsgdGhlbgogICAgICAgICAgQVNfTE9HU19SRU1PVkVEPSQoKEFTX0xPR1NfUkVNT1ZFRCtvcnBoYW4pKQogICAgICAgIGVsc2UKICAgICAgICAgIGxvZyBXQVJOICJPcnBoYW4gQWN0aW9uIFNjaGVkdWxlciBsb2cgY2xlYW51cCBmYWlsZWQgZm9yICRkYi8kcHJlZml4IgogICAgICAgIGZpCiAgICAgIGZpCiAgICBmaQoKICAgICMgTmV2ZXIgZGVsZXRlIHRlcm1pbmFsIGFjdGlvbnMgaWYgdGhlaXIgY29ycmVzcG9uZGluZyBsb2dzIGNvdWxkIG5vdCBiZQogICAgIyByZW1vdmVkLiBUaGlzIHByZXNlcnZlcyByZWZlcmVudGlhbCBpbnRlZ3JpdHkgb24gc3RyaWN0ZXIgc2NoZW1hcy4KICAgIGlmICgoIHRvdGFsID4gMCApKSAmJiBbWyAiJGxvZ19jbGVhbnVwX29rIiA9PSB5ZXMgXV07IHRoZW4KICAgICAgaWYgZGJfcXVlcnkgLWUgIgogICAgICAgIERFTEVURSBGUk9NICRxZC4kcWEKICAgICAgICBXSEVSRSAoc3RhdHVzPSdjb21wbGV0ZScgQU5EIHNjaGVkdWxlZF9kYXRlX2dtdDxVVENfVElNRVNUQU1QKCktSU5URVJWQUwgJHtBQ1RJT05fU0NIRURVTEVSX0NPTVBMRVRFX0RBWVN9IERBWSkKICAgICAgICAgICBPUiAoc3RhdHVzPSdjYW5jZWxlZCcgQU5EIHNjaGVkdWxlZF9kYXRlX2dtdDxVVENfVElNRVNUQU1QKCktSU5URVJWQUwgJHtBQ1RJT05fU0NIRURVTEVSX0NBTkNFTEVEX0RBWVN9IERBWSkKICAgICAgICAgICBPUiAoc3RhdHVzPSdmYWlsZWQnIEFORCBzY2hlZHVsZWRfZGF0ZV9nbXQ8VVRDX1RJTUVTVEFNUCgpLUlOVEVSVkFMICR7QUNUSU9OX1NDSEVEVUxFUl9GQUlMRURfREFZU30gREFZKSIgPj4iJERFVEFJTCIgMj4mMTsgdGhlbgogICAgICAgIEFTX0FDVElPTlNfUkVNT1ZFRD0kKChBU19BQ1RJT05TX1JFTU9WRUQrdG90YWwpKQogICAgICBlbHNlCiAgICAgICAgbG9nIFdBUk4gIkFjdGlvbiBTY2hlZHVsZXIgYWN0aW9uIGNsZWFudXAgZmFpbGVkIGZvciAkZGIvJHByZWZpeCIKICAgICAgZmkKICAgIGZpCiAgZG9uZSA8IDwod3BfcHJlZml4ZXMgIiRkYiIpCn0KCmNsZWFudXBfd3AoKXsKICBsb2NhbCBkYj0iJDEiIHByZWZpeCBxZCBxbyBxcyBiZWZvcmUgYWZ0ZXIgbgogIHdoaWxlIElGUz0gcmVhZCAtciBwcmVmaXg7IGRvCiAgICBbWyAtbiAiJHByZWZpeCIgXV0gfHwgY29udGludWUKICAgIHFkPSIkKHF1b3RlX2lkZW50ICIkZGIiKSI7IHFvPSIkKHF1b3RlX2lkZW50ICIke3ByZWZpeH1vcHRpb25zIikiCiAgICBpZiBbWyAiJEVOQUJMRV9XUF9UUkFOU0lFTlRfQ0xFQU5VUCIgPT0geWVzIF1dOyB0aGVuCiAgICAgIGJlZm9yZT0iJChkYl9xdWVyeSAtZSAiU0VMRUNUIENPVU5UKCopIEZST00gJHFkLiRxbyBXSEVSRSAob3B0aW9uX25hbWUgTElLRSAnXFxfdHJhbnNpZW50XFxfdGltZW91dFxcXyUnIE9SIG9wdGlvbl9uYW1lIExJS0UgJ1xcX3NpdGVcXF90cmFuc2llbnRcXF90aW1lb3V0XFxfJScpIEFORCBDQVNUKG9wdGlvbl92YWx1ZSBBUyBVTlNJR05FRCk8VU5JWF9USU1FU1RBTVAoKSIgMj4vZGV2L251bGwgfCBoZWFkIC1uMSkiOyBbWyAiJGJlZm9yZSIgPX4gXlswLTldKyQgXV0gfHwgYmVmb3JlPTAKICAgICAgaWYgKCggYmVmb3JlID4gMCApKTsgdGhlbgogICAgICAgIGRiX3F1ZXJ5IC1lICJERUxFVEUgdiBGUk9NICRxZC4kcW8gdiBKT0lOICRxZC4kcW8gdCBPTiB0Lm9wdGlvbl9uYW1lPUNPTkNBVCgnX3RyYW5zaWVudF90aW1lb3V0XycsU1VCU1RSSU5HKHYub3B0aW9uX25hbWUsMTIpKSBXSEVSRSB2Lm9wdGlvbl9uYW1lIExJS0UgJ1xcX3RyYW5zaWVudFxcXyUnIEFORCB2Lm9wdGlvbl9uYW1lIE5PVCBMSUtFICdcXF90cmFuc2llbnRcXF90aW1lb3V0XFxfJScgQU5EIENBU1QodC5vcHRpb25fdmFsdWUgQVMgVU5TSUdORUQpPFVOSVhfVElNRVNUQU1QKCk7IERFTEVURSB2IEZST00gJHFkLiRxbyB2IEpPSU4gJHFkLiRxbyB0IE9OIHQub3B0aW9uX25hbWU9Q09OQ0FUKCdfc2l0ZV90cmFuc2llbnRfdGltZW91dF8nLFNVQlNUUklORyh2Lm9wdGlvbl9uYW1lLDE3KSkgV0hFUkUgdi5vcHRpb25fbmFtZSBMSUtFICdcXF9zaXRlXFxfdHJhbnNpZW50XFxfJScgQU5EIHYub3B0aW9uX25hbWUgTk9UIExJS0UgJ1xcX3NpdGVcXF90cmFuc2llbnRcXF90aW1lb3V0XFxfJScgQU5EIENBU1QodC5vcHRpb25fdmFsdWUgQVMgVU5TSUdORUQpPFVOSVhfVElNRVNUQU1QKCk7IERFTEVURSBGUk9NICRxZC4kcW8gV0hFUkUgKG9wdGlvbl9uYW1lIExJS0UgJ1xcX3RyYW5zaWVudFxcX3RpbWVvdXRcXF8lJyBPUiBvcHRpb25fbmFtZSBMSUtFICdcXF9zaXRlXFxfdHJhbnNpZW50XFxfdGltZW91dFxcXyUnKSBBTkQgQ0FTVChvcHRpb25fdmFsdWUgQVMgVU5TSUdORUQpPFVOSVhfVElNRVNUQU1QKCk7IiA+PiIkREVUQUlMIiAyPiYxCiAgICAgICAgV1BfVFJBTlNJRU5UX1JPV1M9JCgoV1BfVFJBTlNJRU5UX1JPV1MrYmVmb3JlKSkKICAgICAgZmkKICAgIGZpCiAgICBxcz0iJChxdW90ZV9pZGVudCAiJHtwcmVmaXh9d29vY29tbWVyY2Vfc2Vzc2lvbnMiKSIKICAgIG49IiQoZGJfcXVlcnkgLWUgIlNFTEVDVCBDT1VOVCgqKSBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5UQUJMRVMgV0hFUkUgVEFCTEVfU0NIRU1BPSckKHNxbF9saXQgIiRkYiIpJyBBTkQgVEFCTEVfTkFNRT0nJChzcWxfbGl0ICIke3ByZWZpeH13b29jb21tZXJjZV9zZXNzaW9ucyIpJyIgMj4vZGV2L251bGwgfCBoZWFkIC1uMSkiCiAgICBpZiBbWyAiJEVOQUJMRV9XQ19TRVNTSU9OX0NMRUFOVVAiID09IHllcyAmJiAiJG4iID09IDEgXV07IHRoZW4KICAgICAgYmVmb3JlPSIkKGRiX3F1ZXJ5IC1lICJTRUxFQ1QgQ09VTlQoKikgRlJPTSAkcWQuJHFzIFdIRVJFIHNlc3Npb25fZXhwaXJ5PFVOSVhfVElNRVNUQU1QKCkiIDI+L2Rldi9udWxsIHwgaGVhZCAtbjEpIjsgW1sgIiRiZWZvcmUiID1+IF5bMC05XSskIF1dIHx8IGJlZm9yZT0wCiAgICAgIGlmICgoIGJlZm9yZSA+IDAgKSk7IHRoZW4gZGJfcXVlcnkgLWUgIkRFTEVURSBGUk9NICRxZC4kcXMgV0hFUkUgc2Vzc2lvbl9leHBpcnk8VU5JWF9USU1FU1RBTVAoKSIgPj4iJERFVEFJTCIgMj4mMSAmJiBXQ19TRVNTSU9OX1JPV1M9JCgoV0NfU0VTU0lPTl9ST1dTK2JlZm9yZSkpOyBmaQogICAgZmkKICBkb25lIDwgPCh3cF9wcmVmaXhlcyAiJGRiIikKfQoKYW5hbHl6ZV9pbm5vZGJfdGFibGVzKCl7CiAgbG9jYWwgZGI9IiQxIiBxZCB0b3RhbCBwcm9jZXNzZWQ9MCBiYXRjaF9ubz0wIGJhdGNoX3RvdGFsIGkgZW5kIHQgcXQgc3FsIGxpc3QKICBsb2NhbCAtYSB0YWJsZXMgYmF0Y2gKCiAgcWQ9IiQocXVvdGVfaWRlbnQgIiRkYiIpIgogIG1hcGZpbGUgLXQgdGFibGVzIDwgPCgKICAgIGRiX3F1ZXJ5IC1lICJTRUxFQ1QgVEFCTEVfTkFNRQogICAgICAgICAgICAgICAgIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLlRBQkxFUwogICAgICAgICAgICAgICAgIFdIRVJFIFRBQkxFX1NDSEVNQT0nJChzcWxfbGl0ICIkZGIiKScKICAgICAgICAgICAgICAgICAgIEFORCBUQUJMRV9UWVBFPSdCQVNFIFRBQkxFJwogICAgICAgICAgICAgICAgICAgQU5EIEVOR0lORT0nSW5ub0RCJwogICAgICAgICAgICAgICAgIE9SREVSIEJZIFRBQkxFX05BTUUiIDI+L2Rldi9udWxsCiAgKQoKICB0b3RhbD0iJHsjdGFibGVzW0BdfSIKICAoKCB0b3RhbCA+IDAgKSkgfHwgcmV0dXJuIDAKCiAgW1sgIiRBTkFMWVpFX0JBVENIX1NJWkUiID1+IF5bMC05XSskIF1dIHx8IEFOQUxZWkVfQkFUQ0hfU0laRT0yNQogICgoIEFOQUxZWkVfQkFUQ0hfU0laRSA+PSAxICkpIHx8IEFOQUxZWkVfQkFUQ0hfU0laRT0yNQogICMgS2VlcCBzdGF0ZW1lbnRzIG1vZGVzdCBldmVuIGlmIHRoZSBjb25maWd1cmF0aW9uIGlzIGVkaXRlZCBpbmNvcnJlY3RseS4KICAoKCBBTkFMWVpFX0JBVENIX1NJWkUgPD0gMTAwICkpIHx8IEFOQUxZWkVfQkFUQ0hfU0laRT0xMDAKCiAgYmF0Y2hfdG90YWw9JCgoICh0b3RhbCArIEFOQUxZWkVfQkFUQ0hfU0laRSAtIDEpIC8gQU5BTFlaRV9CQVRDSF9TSVpFICkpCiAgbG9nIElORk8gIkFuYWx5emluZyAkdG90YWwgSW5ub0RCIHRhYmxlcyBpbiAkZGIgdXNpbmcgJGJhdGNoX3RvdGFsIGJhdGNoKGVzKSwgdXAgdG8gJEFOQUxZWkVfQkFUQ0hfU0laRSB0YWJsZXMgZWFjaCIKCiAgZm9yICgoIGk9MDsgaTx0b3RhbDsgaSs9QU5BTFlaRV9CQVRDSF9TSVpFICkpOyBkbwogICAgaWYgISBwcmVmbGlnaHQgPi9kZXYvbnVsbCAyPiYxOyB0aGVuCiAgICAgIGxvY2FsIHJlbWFpbmluZz0kKCh0b3RhbC1wcm9jZXNzZWQpKQogICAgICBUQUJMRVNfT1BUSU1JWkVfU0tJUFBFRD0kKChUQUJMRVNfT1BUSU1JWkVfU0tJUFBFRCtyZW1haW5pbmcpKQogICAgICBsb2cgV0FSTiAiTG9hZC9kaXNrIHNhZmV0eSB0aHJlc2hvbGQgY2hhbmdlZDsgc2tpcHBpbmcgcmVtYWluaW5nICRyZW1haW5pbmcgQU5BTFlaRSBvcGVyYXRpb24ocykgaW4gJGRiIgogICAgICByZXR1cm4gMAogICAgZmkKCiAgICBlbmQ9JCgoaStBTkFMWVpFX0JBVENIX1NJWkUpKQogICAgKCggZW5kID4gdG90YWwgKSkgJiYgZW5kPSR0b3RhbAogICAgYmF0Y2g9KCAiJHt0YWJsZXNbQF06aTplbmQtaX0iICkKICAgIGJhdGNoX25vPSQoKGJhdGNoX25vKzEpKQogICAgbGlzdD0iIgoKICAgIGZvciB0IGluICIke2JhdGNoW0BdfSI7IGRvCiAgICAgIHF0PSIkKHF1b3RlX2lkZW50ICIkdCIpIgogICAgICBbWyAtbiAiJGxpc3QiIF1dICYmIGxpc3QrPSIsIgogICAgICBsaXN0Kz0iJHFkLiRxdCIKICAgIGRvbmUKCiAgICBsb2cgSU5GTyAiQU5BTFlaRSBwcm9ncmVzcyAkZGI6IGJhdGNoICRiYXRjaF9uby8kYmF0Y2hfdG90YWwsIHRhYmxlcyAkKChpKzEpKS0kZW5kIG9mICR0b3RhbCIKCiAgICBpZiBkYl9xdWVyeSAtZSAiQU5BTFlaRSBUQUJMRSAkbGlzdCIgPj4iJERFVEFJTCIgMj4mMTsgdGhlbgogICAgICBUQUJMRVNfQU5BTFlaRUQ9JCgoVEFCTEVTX0FOQUxZWkVEKyR7I2JhdGNoW0BdfSkpCiAgICAgIHByb2Nlc3NlZD0kKChwcm9jZXNzZWQrJHsjYmF0Y2hbQF19KSkKICAgIGVsc2UKICAgICAgbG9nIFdBUk4gIkJhdGNoIEFOQUxZWkUgZmFpbGVkIGZvciAkZGIgYmF0Y2ggJGJhdGNoX25vLyRiYXRjaF90b3RhbCIKICAgICAgaWYgW1sgIiRBTkFMWVpFX0JBVENIX0ZBTExCQUNLIiA9PSB5ZXMgXV07IHRoZW4KICAgICAgICBsb2cgSU5GTyAiUmV0cnlpbmcgdGhlIGFmZmVjdGVkIGJhdGNoIHRhYmxlLWJ5LXRhYmxlIHRvIHByZXNlcnZlIGNvbXBsZXRlIGNvdmVyYWdlIgogICAgICAgIGZvciB0IGluICIke2JhdGNoW0BdfSI7IGRvCiAgICAgICAgICBxdD0iJChxdW90ZV9pZGVudCAiJHQiKSIKICAgICAgICAgIGlmIGRiX3F1ZXJ5IC1lICJBTkFMWVpFIFRBQkxFICRxZC4kcXQiID4+IiRERVRBSUwiIDI+JjE7IHRoZW4KICAgICAgICAgICAgVEFCTEVTX0FOQUxZWkVEPSQoKFRBQkxFU19BTkFMWVpFRCsxKSkKICAgICAgICAgIGVsc2UKICAgICAgICAgICAgVEFCTEVTX09QVElNSVpFX1NLSVBQRUQ9JCgoVEFCTEVTX09QVElNSVpFX1NLSVBQRUQrMSkpCiAgICAgICAgICAgIGxvZyBXQVJOICJBTkFMWVpFIGZhaWxlZCBvciB0aW1lZCBvdXQ6ICRkYi4kdCIKICAgICAgICAgIGZpCiAgICAgICAgICBwcm9jZXNzZWQ9JCgocHJvY2Vzc2VkKzEpKQogICAgICAgIGRvbmUKICAgICAgZWxzZQogICAgICAgIFRBQkxFU19PUFRJTUlaRV9TS0lQUEVEPSQoKFRBQkxFU19PUFRJTUlaRV9TS0lQUEVEKyR7I2JhdGNoW0BdfSkpCiAgICAgICAgcHJvY2Vzc2VkPSQoKHByb2Nlc3NlZCskeyNiYXRjaFtAXX0pKQogICAgICBmaQogICAgZmkKCiAgICBpZiBbWyAiJFNMRUVQX0JFVFdFRU5fQU5BTFlaRSIgIT0gIjAiIF1dOyB0aGVuCiAgICAgIHNsZWVwICIkU0xFRVBfQkVUV0VFTl9BTkFMWVpFIgogICAgZmkKICBkb25lCgogIGxvZyBJTkZPICJDb21wbGV0ZWQgSW5ub0RCIHN0YXRpc3RpY3MgYW5hbHlzaXMgZm9yICRkYjogJHByb2Nlc3NlZC8kdG90YWwgdGFibGUocykgcHJvY2Vzc2VkIgp9CgpvcHRpbWl6ZV90YWJsZXMoKXsKICBsb2NhbCBkYj0iJDEiIHQgZW5naW5lIHNpemUgZnJlZSBwY3QgcWQgcXQKICBbWyAiJEVOQUJMRV9FTkdJTkVfU0FGRV9PUFRJTUlaRSIgPT0geWVzIF1dIHx8IHJldHVybiAwCiAgd2hpbGUgSUZTPSQnXHQnIHJlYWQgLXIgdCBlbmdpbmUgc2l6ZSBmcmVlIHBjdDsgZG8KICAgIFtbIC1uICIkdCIgXV0gfHwgY29udGludWUKICAgIGNhc2UgIiR7ZW5naW5lXl59IiBpbiBNWUlTQU18QVJJQSkgOzsgKikgY29udGludWUgOzsgZXNhYwogICAgaWYgISBhd2sgLXYgZj0iJGZyZWUiIC12IGZtPSIkTUlOX1JFQ0xBSU1fTUIiIC12IHA9IiRwY3QiIC12IHBtPSIkTUlOX1JFQ0xBSU1fUEVSQ0VOVCIgLXYgcz0iJHNpemUiIC12IHNtPSIkTUFYX09QVElNSVpFX1RBQkxFX01CIiAnQkVHSU57ZXhpdCAhKChmPj1mbSkmJihwPj1wbSkmJihzPD1zbSkmJihmPD1zKSl9JzsgdGhlbiBjb250aW51ZTsgZmkKICAgIGlmICEgcHJlZmxpZ2h0ID4vZGV2L251bGwgMj4mMTsgdGhlbiBUQUJMRVNfT1BUSU1JWkVfU0tJUFBFRD0kKChUQUJMRVNfT1BUSU1JWkVfU0tJUFBFRCsxKSk7IGxvZyBXQVJOICJMb2FkL2Rpc2sgY2hhbmdlZDsgc2tpcHBpbmcgb3B0aW1pemUgJGRiLiR0IjsgY29udGludWU7IGZpCiAgICBxZD0iJChxdW90ZV9pZGVudCAiJGRiIikiOyBxdD0iJChxdW90ZV9pZGVudCAiJHQiKSIKICAgIGxvZyBJTkZPICJPcHRpbWl6aW5nIGVuZ2luZS1zYWZlIHRhYmxlICRkYi4kdCAoJGVuZ2luZTsgJHtzaXplfSBNQjsgZXN0aW1hdGVkIHJlY2xhaW0gJHtmcmVlfSBNQikiCiAgICBpZiBkYl9xdWVyeSAtZSAiT1BUSU1JWkUgVEFCTEUgJHFkLiRxdCIgPj4iJERFVEFJTCIgMj4mMTsgdGhlbiBUQUJMRVNfT1BUSU1JWkVEPSQoKFRBQkxFU19PUFRJTUlaRUQrMSkpOyBlbHNlIFRBQkxFU19PUFRJTUlaRV9TS0lQUEVEPSQoKFRBQkxFU19PUFRJTUlaRV9TS0lQUEVEKzEpKTsgbG9nIFdBUk4gIk9wdGltaXplIGZhaWxlZCBvciB3YXMgcmVmdXNlZDogJGRiLiR0IjsgZmkKICAgIHNsZWVwICIkU0xFRVBfQkVUV0VFTl9UQUJMRVMiCiAgZG9uZSA8IDwoZGJfcXVlcnkgLWUgIlNFTEVDVCBUQUJMRV9OQU1FLENPQUxFU0NFKEVOR0lORSwnJyksUk9VTkQoKERBVEFfTEVOR1RIK0lOREVYX0xFTkdUSCkvMTAyNC8xMDI0LDIpLFJPVU5EKERBVEFfRlJFRS8xMDI0LzEwMjQsMiksUk9VTkQoSUYoREFUQV9MRU5HVEgrSU5ERVhfTEVOR1RIPTAsMCxEQVRBX0ZSRUUqMTAwLyhEQVRBX0xFTkdUSCtJTkRFWF9MRU5HVEgpKSwyKSBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5UQUJMRVMgV0hFUkUgVEFCTEVfU0NIRU1BPSckKHNxbF9saXQgIiRkYiIpJyBBTkQgVEFCTEVfVFlQRT0nQkFTRSBUQUJMRSciIDI+L2Rldi9udWxsKQp9Cgpwcm9jZXNzX2RiKCl7CiAgbG9jYWwgZGI9IiQxIiBvd25lciBzaXplIGNvdW50IHByZWZpeGVzIGNoYW5nZV9vaz1ubwogIERCX1NDQU5ORUQ9JCgoREJfU0NBTk5FRCsxKSkKICBvd25lcj0iJChvd25lcl9mb3JfZGIgIiRkYiIpIgogIGNvdW50PSIkKGRiX3RhYmxlX2NvdW50ICIkZGIiKSI7IHNpemU9IiQoZGJfc2l6ZV9tYiAiJGRiIikiCiAgW1sgIiRjb3VudCIgPX4gXlswLTldKyQgXV0gfHwgeyBsb2cgV0FSTiAiQ2Fubm90IGludmVudG9yeSAkZGI7IGNvbnRpbnVpbmciOyBEQl9GQUlMRUQ9JCgoREJfRkFJTEVEKzEpKTsgcmV0dXJuIDA7IH0KICBbWyAiJHNpemUiID1+IF5bMC05XSskIF1dIHx8IHNpemU9MAogIGlmICgoIGNvdW50ID09IDAgKSk7IHRoZW4gREJfRU1QVFk9JCgoREJfRU1QVFkrMSkpOyBsb2cgSU5GTyAiWyREQl9TQ0FOTkVELyREQl9GT1VORF0gJGRiIG93bmVyPSRvd25lcjogZW1wdHkgZGF0YWJhc2UsIHNraXBwZWQiOyByZXR1cm4gMDsgZmkKICBsb2cgSU5GTyAiWyREQl9TQ0FOTkVELyREQl9GT1VORF0gQXVkaXRpbmcgJGRiIG93bmVyPSRvd25lcjogJGNvdW50IHRhYmxlcywgJHtzaXplfSBNQiIKICBjaGVja190YWJsZXMgIiRkYiIgIiRjb3VudCIgfHwgbG9nIFdBUk4gIkRhdGFiYXNlIGNoZWNrZXIgcmV0dXJuZWQgYSB3YXJuaW5nIGZvciAkZGI7IGNvbnRpbnVpbmciCiAgcHJlZml4ZXM9IiQod3BfcHJlZml4ZXMgIiRkYiIpIgogIGlmIFtbIC1uICIkcHJlZml4ZXMiIF1dOyB0aGVuCiAgICBXUF9EQlM9JCgoV1BfREJTKzEpKQogICAgd3Bfb3Bwb3J0dW5pdHlfYXVkaXQgIiRkYiIKICBmaQogIFtbICIkTU9ERSIgPT0gYXVkaXQgXV0gJiYgcmV0dXJuIDAKICBpZiBpc19zZW5zaXRpdmVfZGIgIiRkYiI7IHRoZW4gREJfU0tJUFBFRD0kKChEQl9TS0lQUEVEKzEpKTsgbG9nIFdBUk4gIlNlbnNpdGl2ZSBkYXRhYmFzZSBuYW1lIGRldGVjdGVkOyBtYWludGVuYW5jZSBza2lwcGVkIGZvciAkZGIiOyByZXR1cm4gMDsgZmkKICBpZiBtYWtlX2R1bXAgIiRkYiIgIiRzaXplIjsgdGhlbiBjaGFuZ2Vfb2s9eWVzOyBmaQogIFtbICIkY2hhbmdlX29rIiA9PSB5ZXMgXV0gfHwgcmV0dXJuIDAKICByZXBhaXJfbXlpc2FtICIkZGIiCiAgaWYgW1sgLW4gIiRwcmVmaXhlcyIgXV07IHRoZW4KICAgIGNsZWFudXBfd3AgIiRkYiIKICAgIGNsZWFudXBfYWN0aW9uX3NjaGVkdWxlciAiJGRiIgogIGZpCiAgYW5hbHl6ZV9pbm5vZGJfdGFibGVzICIkZGIiCiAgb3B0aW1pemVfdGFibGVzICIkZGIiCiAgcmV0dXJuIDAKfQoKbGlzdF9kYXRhYmFzZXMoKXsgZGJfcXVlcnkgLWUgJ1NIT1cgREFUQUJBU0VTJyAyPi9kZXYvbnVsbDsgfQoKc3VtbWFyeSgpewogIGNhdCB8IHRlZSAtYSAiJFJFUE9SVCIgPDxFT0YKCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQpNR0ggVU5JVkVSU0FMIERBVEFCQVNFIERPQ1RPUiDigJQgRklOQUwgU1VNTUFSWQo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KTW9kZTogICAgICAgICAgICAgICAgICAgICAgICAgJE1PREUKRGF0YWJhc2UgcGxhdGZvcm06ICAgICAgICAgICAgJERCX1NFUlZFUl9GTEFWT1IgJERCX1NFUlZFUl9WRVJTSU9OCkRhdGFiYXNlcyBkaXNjb3ZlcmVkOiAgICAgICAgICREQl9GT1VORApEYXRhYmFzZXMgc2Nhbm5lZDogICAgICAgICAgICAkREJfU0NBTk5FRApFbXB0eSBkYXRhYmFzZXMgc2tpcHBlZDogICAgICAkREJfRU1QVFkKU2Vuc2l0aXZlIGRhdGFiYXNlcyBza2lwcGVkOiAgJERCX1NLSVBQRUQKRGF0YWJhc2UtbGV2ZWwgZmFpbHVyZXM6ICAgICAgJERCX0ZBSUxFRApUYWJsZXMgY2hlY2tlZDogICAgICAgICAgICAgICAkVEFCTEVTX0NIRUNLRUQKSGVhbHRoeSB0YWJsZSByZXN1bHRzOiAgICAgICAgJFRBQkxFU19PSwpVbnN1cHBvcnRlZCBlbmdpbmUgY2hlY2tzOiAgICAkVEFCTEVTX1VOU1VQUE9SVEVECkNvbmZpcm1lZC9yZXZpZXcgdGFibGUgaXNzdWVzOiAkVEFCTEVTX0JBRApUYWJsZXMgcmVwYWlyZWQ6ICAgICAgICAgICAgICAkVEFCTEVTX1JFUEFJUkVECklubm9EQiB0YWJsZXMgYW5hbHl6ZWQ6ICAgICAgICRUQUJMRVNfQU5BTFlaRUQKQW5hbHl6ZSBiYXRjaCBzaXplOiAgICAgICAgICAgICRBTkFMWVpFX0JBVENIX1NJWkUKVGFibGVzIG9wdGltaXplZC9yZWJ1aWx0OiAgICAgJFRBQkxFU19PUFRJTUlaRUQKT3B0aW1pemF0aW9ucyBza2lwcGVkOiAgICAgICAgJFRBQkxFU19PUFRJTUlaRV9TS0lQUEVECldvcmRQcmVzcyBkYXRhYmFzZXMgZGV0ZWN0ZWQ6ICRXUF9EQlMKRXhwaXJlZCBXUCByZWNvcmRzIHJlbW92ZWQ6ICAgJFdQX1RSQU5TSUVOVF9ST1dTCkV4cGlyZWQgV0Mgc2Vzc2lvbnMgcmVtb3ZlZDogICRXQ19TRVNTSU9OX1JPV1MKQVMgY29tcGxldGUgY2FuZGlkYXRlczogICAgICAgJEFTX0NPTVBMRVRFX0NBTkRJREFURVMKQVMgY2FuY2VsZWQgY2FuZGlkYXRlczogICAgICAgJEFTX0NBTkNFTEVEX0NBTkRJREFURVMKQVMgZmFpbGVkIGNhbmRpZGF0ZXM6ICAgICAgICAgJEFTX0ZBSUxFRF9DQU5ESURBVEVTCkFTIG9ycGhhbiBsb2cgY2FuZGlkYXRlczogICAgICRBU19PUlBIQU5fTE9HUwpBUyB0ZXJtaW5hbCBhY3Rpb25zIHJlbW92ZWQ6ICAkQVNfQUNUSU9OU19SRU1PVkVECkFTIGxvZyByb3dzIHJlbW92ZWQ6ICAgICAgICAgICRBU19MT0dTX1JFTU9WRUQKQVMgZGF0YWJhc2VzIHNhZmV0eS1za2lwcGVkOiAgJEFTX1NLSVBQRURfREFUQUJBU0VTCldQIHJldmlzaW9ucyBmb3VuZCAocmVwb3J0KTogICRXUF9SRVZJU0lPTlNfRk9VTkQKV1AgYXV0by1kcmFmdHMgZm91bmQgKHJlcG9ydCk6ICRXUF9BVVRPRFJBRlRTX0ZPVU5ECldQIHRyYXNoIHBvc3RzIGZvdW5kIChyZXBvcnQpOiAkV1BfVFJBU0hfUE9TVFNfRk9VTkQKV1Agc3BhbSBjb21tZW50cyAocmVwb3J0KTogICAgJFdQX1NQQU1fQ09NTUVOVFNfRk9VTkQKV1AgdHJhc2ggY29tbWVudHMgKHJlcG9ydCk6ICAgJFdQX1RSQVNIX0NPTU1FTlRTX0ZPVU5ECldQIGF1dG9sb2FkIGJ5dGVzIChyZXBvcnQpOiAgICRXUF9BVVRPTE9BRF9CWVRFUwpXYXJuaW5nczogICAgICAgICAgICAgICAgICAgICAkV0FSTklOR1MKRXJyb3JzOiAgICAgICAgICAgICAgICAgICAgICAgJEVSUk9SUwpSZXBvcnQ6ICAgICAgICAgICAgICAgICAgICAgICAkUkVQT1JUCkRldGFpbGVkIHRhYmxlIGxvZzogICAgICAgICAgICRERVRBSUwKUHJlLWNoYW5nZSBkdW1wczogICAgICAgICAgICAgICREVU1QX0RJUgo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KRU9GCn0KCm1haW4oKXsKICBwYXJzZV9hcmdzICIkQCIKICBsb2FkX2NvbmZpZwogIGFjcXVpcmVfbG9jawogIGRldGVjdF9lbnZpcm9ubWVudCB8fCB7IHN1bW1hcnk7IGV4aXQgMTsgfQogIHByZWZsaWdodCB8fCB7IHN1bW1hcnk7IGV4aXQgMTsgfQogIGNvbmZpcm1fc2FmZV9ydW4KICBsb2NhbCBhbGwgZGIKICBhbGw9IiQobGlzdF9kYXRhYmFzZXMpIgogIHdoaWxlIElGUz0gcmVhZCAtciBkYjsgZG8gW1sgLW4gIiRkYiIgXV0gfHwgY29udGludWU7IGlzX2V4Y2x1ZGVkX2RiICIkZGIiICYmIGNvbnRpbnVlOyBEQl9GT1VORD0kKChEQl9GT1VORCsxKSk7IGRvbmUgPDw8ICIkYWxsIgogIHdoaWxlIElGUz0gcmVhZCAtciBkYjsgZG8KICAgIFtbIC1uICIkZGIiIF1dIHx8IGNvbnRpbnVlCiAgICBpZiBpc19leGNsdWRlZF9kYiAiJGRiIjsgdGhlbiBjb250aW51ZTsgZmkKICAgIHByb2Nlc3NfZGIgIiRkYiIgfHwgeyBEQl9GQUlMRUQ9JCgoREJfRkFJTEVEKzEpKTsgbG9nIFdBUk4gIlVuZXhwZWN0ZWQgZXJyb3Igd2hpbGUgcHJvY2Vzc2luZyAkZGI7IGNvbnRpbnVpbmciOyB9CiAgZG9uZSA8PDwgIiRhbGwiCiAgc3VtbWFyeQogIHJldHVybiAwCn0KCm1haW4gIiRAIgo=' | base64 -d > /usr/local/sbin/mgh-db-manager
chmod 700 /usr/local/sbin/mgh-db-manager

# Preserve existing configuration. Create defaults only for a new installation,
# then append v1.2 settings only when absent.
if [[ ! -f /etc/mgh-db-doctor.conf ]]; then
cat > /etc/mgh-db-doctor.conf <<'CONF'
# MGH Universal Database Doctor configuration
MIN_FREE_GB=20
MIN_FREE_PERCENT=10
MAX_LOAD_PER_CPU=1.50
MAX_IOWAIT_PERCENT=30
MAX_DB_DUMP_MB=0
MAX_OPTIMIZE_TABLE_MB=1024
MIN_RECLAIM_MB=64
MIN_RECLAIM_PERCENT=15
QUERY_TIMEOUT=300
SLEEP_BETWEEN_TABLES=1
SLEEP_BETWEEN_ANALYZE=0
ANALYZE_BATCH_SIZE=25
ANALYZE_BATCH_FALLBACK=yes
ENABLE_WP_TRANSIENT_CLEANUP=yes
ENABLE_WC_SESSION_CLEANUP=yes
ENABLE_ACTION_SCHEDULER_CLEANUP=yes
ACTION_SCHEDULER_COMPLETE_DAYS=45
ACTION_SCHEDULER_CANCELED_DAYS=45
ACTION_SCHEDULER_FAILED_DAYS=90
MAX_ACTION_SCHEDULER_DELETE_ROWS=50000
ENABLE_ENGINE_SAFE_OPTIMIZE=yes
EXCLUDED_DB_REGEX='^(information_schema|performance_schema|mysql|sys|cphulkd|eximstats|modsec|roundcube|leechprotect)$'
SENSITIVE_DB_REGEX='(whmcs|billing|invoice|accounting|finance|crm)'
CONF
else
  grep -q '^ANALYZE_BATCH_SIZE=' /etc/mgh-db-doctor.conf || echo 'ANALYZE_BATCH_SIZE=25' >> /etc/mgh-db-doctor.conf
  grep -q '^ANALYZE_BATCH_FALLBACK=' /etc/mgh-db-doctor.conf || echo 'ANALYZE_BATCH_FALLBACK=yes' >> /etc/mgh-db-doctor.conf
fi
chmod 600 /etc/mgh-db-doctor.conf

rm -f /usr/local/sbin/mgh-db-safe-run
cat > /usr/local/sbin/mgh-db-safe-run <<'WRAP'
#!/usr/bin/env bash
exec /usr/local/sbin/mgh-db-manager safe-run "$@"
WRAP
chmod 700 /usr/local/sbin/mgh-db-safe-run

bash -n /usr/local/sbin/mgh-db-manager
bash -n /usr/local/sbin/mgh-db-safe-run

echo
echo 'MGH Universal Database Doctor 1.2.0 installed successfully.'
echo 'Existing configuration was preserved.'
echo 'InnoDB ANALYZE now runs in conservative batches with automatic table-level fallback.'
echo 'Audit:       mgh-db-manager audit'
echo 'Maintenance: mgh-db-safe-run'
