#! /bin/bash # Based on UnRen for Mac v 0.3 by goobdoob - https://f95zone.com/members/goobdoob.334840/ # Original version by jimmy5 - https://f95zone.com/members/jimmy5.179689/ # https://f95zone.com/threads/unren-for-macos.16887/ # Based on UnRen.bat by Sam - https://f95zone.com/members/sam.7899/ # https://f95zone.com/threads/unren-bat-v0-7-rpa-extractor-rpyc-decompiler-console-developer-menu-enabler.3083/ # Using: # rpatool - https://github.com/Shizmob/rpatool # unrpyc - https://github.com/CensoredUsername/unrpyc # Change Log: # # v0.5: @mrunkel # Cleaned up various shell issues, including: # * problems with spaces in file names. # * handling of failed pushd calls # # v0.4: # Fixed a bug when working with more than 1 .rpa file # # v0.3: # Changed rpyc decompile to decompile rpyc files in all game directories recursively. # Added option to overwrite existing rpy files. Thanks to randomname42 @ www.f95zone.com for the suggestion. # Changed base64 option -D to --decode because -D doesn't work on GNU base64. # Changed base64 option -o to > because -o doesn't work on GNU base64. Thanks to cold_arctus @ www.f95zone.com for the base64 bug reports. # Fixed a bug having to do with spaces in the path to the game. Thanks to waveofpig @ www.f95zone.com for the bug report. # Changed to splash screen to say "@ www.f95zone.com" instead of "@f95zone". # Detect if there are no .rpa files to extract and report that, instead of getting an error from the shell. # # v0.2: # Added line to force script to run in bash. # Allow user to specify game directory on the command line. # Extract packages in place instead of in a subfolder, which caused games to crash with # double definitions. # Print names of rpa packages being extracted. # Changed script decompile to use unrpyc under python instead of un.rpyc inside the game. # Removed options to uninstall un.rpyc and remove extracted packages. # Added option to quit from main menu. # Fixed handling of games with spaces in their names. # Simplified code by removing some recursion and putting main menu in a loop. # Check for pc game folder if the script can't find it in the Mac location. # # ------------------------------------------------------------------------------------------ # Configuration quicksavekey="K_F5" quickloadkey="K_F9" # End of Configuration ARG1=$1 num_args=$# # ------------------------------------------------------------------------------------------ # If you touch anything other than the config, and this stops working don't complain. # ------------------------------------------------------------------------------------------ version="0.5" clear #Splash Screen function init { setup_scripts echo "UnRen for Mac v$version" if command -v python &>/dev/null; then echo "Python is installed, detected" else echo "Python is not installed, or not added to your PATH. Please install/reinstall it from python.org" exit fi if [ $num_args -ne 1 ]; then echo "Please drag + drop the game you are wanting to modify into the terminal." read appdir else echo "Working with directory $ARG1" appdir="$ARG1" fi game="$appdir/Contents/Resources/autorun/game" if [ ! -d "$game" ]; then # Can't find the game directory in the Mac spot; see if it's in the PC spot game="$appdir/game" if [ ! -d "$game" ]; then echo "Can't find the game directory in $appdir! Exiting now" exit fi fi menu } function menu { while : do echo echo "What would you like to do?" echo " 1) Extract RPA packages" echo " 2) Decompile rpyc files" echo " 3) Decompile rpyc files, overwriting existing rpy files" echo " 4) Enable Console and Developer Menu" echo " 5) Enable Quick Save and Quick Load" echo " 6) Force enable skipping of unseen content" echo " 7) Force enable rollback (scroll wheel)" echo " 8) Open game directory" echo echo " 99) Options 1-7 (no overwrite)" echo echo " q) quit UnRen" echo choice done } function choice { read -r choicev case "$choicev" in "1") extract ;; "2") decompile ;; "3") decompileoverwrite ;; "4") console ;; "5") quick ;; "6") skip ;; "7") rollback ;; "8") opengame ;; "99") extract decompile console quick skip rollback ;; "q") rm -r /tmp/rpatool.py /tmp/unrpyc.py /tmp/decompiler.tar /tmp/decompiler exit ;; *) echo "Please make a valid selection" choice ;; esac } function opengame { open "$game" } function extract { pushd "$game" || return > /dev/null files=(*.rpa) if [ -e "${files[0]}" ]; then echo "Extracting RPA packages" for f in *.rpa; do echo "extracting $f" python "/tmp/rpatool.py" -x "$f" done else echo "No RPA packages found" fi popd || return > /dev/null } function decompile { echo "Decompiling rpyc files" pushd "$game" || return > /dev/null python "/tmp/unrpyc.py" "." popd || return > /dev/null } function decompileoverwrite { echo "Decompiling rpyc files, overwriting existing rpy files" pushd "$game"|| reutrn > /dev/null python "/tmp/unrpyc.py" "." "-c" popd || return > /dev/null } function console { if [ -f "$game/unren-dev.rpy" ]; then rm "$game/unren-dev.rpy" fi touch "$game/unren-dev.rpy" echo "init 999 python:" > "$game/unren-dev.rpy" echo " config.developer = True" >> "$game/unren-dev.rpy" echo " config.console = True" >> "$game/unren-dev.rpy" echo "Added - Console: Shift + O" echo "Added - Dev Menu: Shift + D" } function quick { if [ -f "$game/unren-quick.rpy" ]; then rm "$game/unren-quick.rpy" fi touch "$game/unren-quick.rpy" echo "init 999 python:" > "$game/unren-quick.rpy" echo " try:" >> "$game/unren-quick.rpy" echo " config.underlay[0].keymap['quickSave'] = QuickSave()" >> "$game/unren-quick.rpy" echo " config.keymap['quickSave'] = '$quicksavekey'" >> "$game/unren-quick.rpy" echo " config.underlay[0].keymap['quickLoad'] = QuickLoad()" >> "$game/unren-quick.rpy" echo " config.keymap['quickLoad'] = '$quickloadkey'" >> "$game/unren-quick.rpy" echo " except:" >> "$game/unren-quick.rpy" echo " pass" >> "$game/unren-quick.rpy" echo "Added - Quick Save: $quicksavekey" echo "Added - Quick Load: $quickloadkey" } function skip { if [ -f "$game/unren-skip.rpy" ]; then rm "$game/unren-skip.rpy" fi touch "$game/unren-skip.rpy" echo "init 999 python:" > "$game/unren-skip.rpy" echo " _preferences.skip_unseen = True" >> "$game/unren-skip.rpy" echo " renpy.game.preferences.skip_unseen = True" >> "$game/unren-skip.rpy" echo " renpy.config.allow_skipping = True" >> "$game/unren-skip.rpy" echo " renpy.config.fast_skipping = True" >> "$game/unren-skip.rpy" echo "Added - You can now skip text with Tab & Command keys." } function rollback { if [ -f "$game/unren-rollback.rpy" ]; then rm "$game/unren-rollback.rpy" fi touch "$game/unren-rollback.rpy" echo "init 999 python:" > "$game/unren-rollback.rpy" echo " renpy.config.rollback_enabled = True" >> "$game/unren-rollback.rpy" echo " renpy.config.hard_rollback_limit = 256" >> "$game/unren-rollback.rpy" echo " renpy.config.rollback_length = 256" >> "$game/unren-rollback.rpy" echo " def unren_noblock( *args, **kwargs ):" >> "$game/unren-rollback.rpy" echo " return" >> "$game/unren-rollback.rpy" echo " renpy.block_rollback = unren_noblock" >> "$game/unren-rollback.rpy" echo "You can now rollback using the scroll wheel" } function setup_scripts { # ------------------------------------------------------------------------------------------ # The below variables are Base64 encoded strings for the python files of unrpyc and rpatool. # ------------------------------------------------------------------------------------------ # unrpyc - https://github.com/CensoredUsername/unrpyc unrpyc=" IyEvdXNyL2Jpbi9lbnYgcHl0aG9uCgojIENvcHlyaWdodCAoYykgMjAxMiBZdXJpIEsuIFNjaGxlc25lcgojCiMgUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQojIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCiMgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwojIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKIyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKIyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgojCiMgVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KIyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KIwojIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCiMgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiMgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiMgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgojIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiMgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUKIyBTT0ZUV0FSRS4KCmltcG9ydCBhcmdwYXJzZQpmcm9tIG9zIGltcG9ydCBwYXRoLCB3YWxrCmltcG9ydCBjb2RlY3MKaW1wb3J0IGdsb2IKaW1wb3J0IGl0ZXJ0b29scwppbXBvcnQgdHJhY2ViYWNrCmltcG9ydCBzdHJ1Y3QKZnJvbSBtdWx0aXByb2Nlc3NpbmcgaW1wb3J0IFBvb2wsIExvY2ssIGNwdV9jb3VudApmcm9tIG9wZXJhdG9yIGltcG9ydCBpdGVtZ2V0dGVyCgppbXBvcnQgZGVjb21waWxlcgpmcm9tIGRlY29tcGlsZXIgaW1wb3J0IG1hZ2ljLCBhc3RkdW1wLCB0cmFuc2xhdGUKCiMgc3BlY2lhbCBkZWZpbml0aW9ucyBmb3Igc3BlY2lhbCBjbGFzc2VzCgpjbGFzcyBQeUV4cHIobWFnaWMuRmFrZVN0cmljdCwgdW5pY29kZSk6CiAgICBfX21vZHVsZV9fID0gInJlbnB5LmFzdCIKICAgIGRlZiBfX25ld19fKGNscywgcywgZmlsZW5hbWUsIGxpbmVudW1iZXIpOgogICAgICAgIHNlbGYgPSB1bmljb2RlLl9fbmV3X18oY2xzLCBzKQogICAgICAgIHNlbGYuZmlsZW5hbWUgPSBmaWxlbmFtZQogICAgICAgIHNlbGYubGluZW51bWJlciA9IGxpbmVudW1iZXIKICAgICAgICByZXR1cm4gc2VsZgoKICAgIGRlZiBfX2dldG5ld2FyZ3NfXyhzZWxmKToKICAgICAgICByZXR1cm4gdW5pY29kZShzZWxmKSwgc2VsZi5maWxlbmFtZSwgc2VsZi5saW5lbnVtYmVyCgpjbGFzcyBQeUNvZGUobWFnaWMuRmFrZVN0cmljdCk6CiAgICBfX21vZHVsZV9fID0gInJlbnB5LmFzdCIKICAgIGRlZiBfX3NldHN0YXRlX18oc2VsZiwgc3RhdGUpOgogICAgICAgIChfLCBzZWxmLnNvdXJjZSwgc2VsZi5sb2NhdGlvbiwgc2VsZi5tb2RlKSA9IHN0YXRlCiAgICAgICAgc2VsZi5ieXRlY29kZSA9IE5vbmUKCmNsYXNzX2ZhY3RvcnkgPSBtYWdpYy5GYWtlQ2xhc3NGYWN0b3J5KChQeUV4cHIsIFB5Q29kZSksIG1hZ2ljLkZha2VTdHJpY3QpCgpwcmludGxvY2sgPSBMb2NrKCkKCiMgQVBJCgpkZWYgcmVhZF9hc3RfZnJvbV9maWxlKGluX2ZpbGUpOgogICAgIyAucnB5YyBmaWxlcyBhcmUganVzdCB6bGliIGNvbXByZXNzZWQgcGlja2xlcyBvZiBhIHR1cGxlIG9mIHNvbWUgZGF0YSBhbmQgdGhlIGFjdHVhbCBBU1Qgb2YgdGhlIGZpbGUKICAgIHJhd19jb250ZW50cyA9IGluX2ZpbGUucmVhZCgpCiAgICBpZiByYXdfY29udGVudHMuc3RhcnRzd2l0aCgiUkVOUFkgUlBDMiIpOgogICAgICAgICMgcGFyc2UgdGhlIGFyY2hpdmUgc3RydWN0dXJlCiAgICAgICAgcG9zaXRpb24gPSAxMAogICAgICAgIGNodW5rcyA9IHt9CiAgICAgICAgd2hpbGUgVHJ1ZToKICAgICAgICAgICAgc2xvdCwgc3RhcnQsIGxlbmd0aCA9IHN0cnVjdC51bnBhY2soIklJSSIsIHJhd19jb250ZW50c1twb3NpdGlvbjogcG9zaXRpb24gKyAxMl0pCiAgICAgICAgICAgIGlmIHNsb3QgPT0gMDoKICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgIHBvc2l0aW9uICs9IDEyCgogICAgICAgICAgICBjaHVua3Nbc2xvdF0gPSByYXdfY29udGVudHNbc3RhcnQ6IHN0YXJ0ICsgbGVuZ3RoXQoKICAgICAgICByYXdfY29udGVudHMgPSBjaHVua3NbMV0KCiAgICByYXdfY29udGVudHMgPSByYXdfY29udGVudHMuZGVjb2RlKCd6bGliJykKICAgIGRhdGEsIHN0bXRzID0gbWFnaWMuc2FmZV9sb2FkcyhyYXdfY29udGVudHMsIGNsYXNzX2ZhY3RvcnksIHsiX2FzdCJ9KQogICAgcmV0dXJuIHN0bXRzCgpkZWYgZGVjb21waWxlX3JweWMoaW5wdXRfZmlsZW5hbWUsIG92ZXJ3cml0ZT1GYWxzZSwgZHVtcD1GYWxzZSwgZGVjb21waWxlX3B5dGhvbj1GYWxzZSwKICAgICAgICAgICAgICAgICAgIGNvbXBhcmFibGU9RmFsc2UsIG5vX3B5ZXhwcj1GYWxzZSwgdHJhbnNsYXRvcj1Ob25lLCBpbml0X29mZnNldD1GYWxzZSk6CiAgICAjIE91dHB1dCBmaWxlbmFtZSBpcyBpbnB1dCBmaWxlbmFtZSBidXQgd2l0aCAucnB5IGV4dGVuc2lvbgogICAgZmlsZXBhdGgsIGV4dCA9IHBhdGguc3BsaXRleHQoaW5wdXRfZmlsZW5hbWUpCiAgICBvdXRfZmlsZW5hbWUgPSBmaWxlcGF0aCArICgnLnR4dCcgaWYgZHVtcCBlbHNlICcucnB5JykKCiAgICB3aXRoIHByaW50bG9jazoKICAgICAgICBwcmludCgiRGVjb21waWxpbmcgJXMgdG8gJXMuLi4iICUgKGlucHV0X2ZpbGVuYW1lLCBvdXRfZmlsZW5hbWUpKQoKICAgICAgICBpZiBub3Qgb3ZlcndyaXRlIGFuZCBwYXRoLmV4aXN0cyhvdXRfZmlsZW5hbWUpOgogICAgICAgICAgICBwcmludCgiT3V0cHV0IGZpbGUgYWxyZWFkeSBleGlzdHMuIFBhc3MgLS1jbG9iYmVyIHRvIG92ZXJ3cml0ZS4iKQogICAgICAgICAgICByZXR1cm4gRmFsc2UgIyBEb24ndCBzdG9wIGRlY29tcGlsaW5nIGlmIG9uZSBmaWxlIGFscmVhZHkgZXhpc3RzCgogICAgd2l0aCBvcGVuKGlucHV0X2ZpbGVuYW1lLCAncmInKSBhcyBpbl9maWxlOgogICAgICAgIGFzdCA9IHJlYWRfYXN0X2Zyb21fZmlsZShpbl9maWxlKQoKICAgIHdpdGggY29kZWNzLm9wZW4ob3V0X2ZpbGVuYW1lLCAndycsIGVuY29kaW5nPSd1dGYtOCcpIGFzIG91dF9maWxlOgogICAgICAgIGlmIGR1bXA6CiAgICAgICAgICAgIGFzdGR1bXAucHByaW50KG91dF9maWxlLCBhc3QsIGRlY29tcGlsZV9weXRob249ZGVjb21waWxlX3B5dGhvbiwgY29tcGFyYWJsZT1jb21wYXJhYmxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub19weWV4cHI9bm9fcHlleHByKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGRlY29tcGlsZXIucHByaW50KG91dF9maWxlLCBhc3QsIGRlY29tcGlsZV9weXRob249ZGVjb21waWxlX3B5dGhvbiwgcHJpbnRsb2NrPXByaW50bG9jaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNsYXRvcj10cmFuc2xhdG9yLCBpbml0X29mZnNldD1pbml0X29mZnNldCkKICAgIHJldHVybiBUcnVlCgpkZWYgZXh0cmFjdF90cmFuc2xhdGlvbnMoaW5wdXRfZmlsZW5hbWUsIGxhbmd1YWdlKToKICAgIHdpdGggcHJpbnRsb2NrOgogICAgICAgIHByaW50KCJFeHRyYWN0aW5nIHRyYW5zbGF0aW9ucyBmcm9tICVzLi4uIiAlIGlucHV0X2ZpbGVuYW1lKQoKICAgIHdpdGggb3BlbihpbnB1dF9maWxlbmFtZSwgJ3JiJykgYXMgaW5fZmlsZToKICAgICAgICBhc3QgPSByZWFkX2FzdF9mcm9tX2ZpbGUoaW5fZmlsZSkKCiAgICB0cmFuc2xhdG9yID0gdHJhbnNsYXRlLlRyYW5zbGF0b3IobGFuZ3VhZ2UsIFRydWUpCiAgICB0cmFuc2xhdG9yLnRyYW5zbGF0ZV9kaWFsb2d1ZShhc3QpCiAgICAjIHdlIHBpY2tsZSBhbmQgdW5waWNrbGUgdGhpcyBtYW51YWxseSBiZWNhdXNlIHRoZSByZWd1bGFyIHVucGlja2xlciB3aWxsIGNob2tlIG9uIGl0CiAgICByZXR1cm4gbWFnaWMuc2FmZV9kdW1wcyh0cmFuc2xhdG9yLmRpYWxvZ3VlKSwgdHJhbnNsYXRvci5zdHJpbmdzCgpkZWYgd29ya2VyKHQpOgogICAgKGFyZ3MsIGZpbGVuYW1lLCBmaWxlc2l6ZSkgPSB0CiAgICB0cnk6CiAgICAgICAgaWYgYXJncy53cml0ZV90cmFuc2xhdGlvbl9maWxlOgogICAgICAgICAgICByZXR1cm4gZXh0cmFjdF90cmFuc2xhdGlvbnMoZmlsZW5hbWUsIGFyZ3MubGFuZ3VhZ2UpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgaWYgYXJncy50cmFuc2xhdGlvbl9maWxlIGlzIG5vdCBOb25lOgogICAgICAgICAgICAgICAgdHJhbnNsYXRvciA9IHRyYW5zbGF0ZS5UcmFuc2xhdG9yKE5vbmUpCiAgICAgICAgICAgICAgICB0cmFuc2xhdG9yLmxhbmd1YWdlLCB0cmFuc2xhdG9yLmRpYWxvZ3VlLCB0cmFuc2xhdG9yLnN0cmluZ3MgPSBtYWdpYy5sb2FkcyhhcmdzLnRyYW5zbGF0aW9ucywgY2xhc3NfZmFjdG9yeSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHRyYW5zbGF0b3IgPSBOb25lCiAgICAgICAgICAgIHJldHVybiBkZWNvbXBpbGVfcnB5YyhmaWxlbmFtZSwgYXJncy5jbG9iYmVyLCBhcmdzLmR1bXAsIGRlY29tcGlsZV9weXRob249YXJncy5kZWNvbXBpbGVfcHl0aG9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm9fcHlleHByPWFyZ3Mubm9fcHlleHByLCBjb21wYXJhYmxlPWFyZ3MuY29tcGFyYWJsZSwgdHJhbnNsYXRvcj10cmFuc2xhdG9yLCBpbml0X29mZnNldD1hcmdzLmluaXRfb2Zmc2V0KQogICAgZXhjZXB0IEV4Y2VwdGlvbiBhcyBlOgogICAgICAgIHdpdGggcHJpbnRsb2NrOgogICAgICAgICAgICBwcmludCgiRXJyb3Igd2hpbGUgZGVjb21waWxpbmcgJXM6IiAlIGZpbGVuYW1lKQogICAgICAgICAgICBwcmludCh0cmFjZWJhY2suZm9ybWF0X2V4YygpKQogICAgICAgIHJldHVybiBGYWxzZQoKZGVmIHNoYXJlbG9jayhsb2NrKToKICAgIGdsb2JhbCBwcmludGxvY2sKICAgIHByaW50bG9jayA9IGxvY2sKCmRlZiBtYWluKCk6CiAgICAjIHB5dGhvbjI3IHVucnB5Yy5weSBbLWNdIFstZF0gWy0tcHl0aG9uLXNjcmVlbnN8LS1hc3Qtc2NyZWVuc3wtLW5vLXNjcmVlbnNdIGZpbGUgW2ZpbGUgLi4uXQogICAgcGFyc2VyID0gYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoZGVzY3JpcHRpb249IkRlY29tcGlsZSAucnB5YyBmaWxlcyIpCgogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLWMnLCAnLS1jbG9iYmVyJywgZGVzdD0nY2xvYmJlcicsIGFjdGlvbj0nc3RvcmVfdHJ1ZScsCiAgICAgICAgICAgICAgICAgICAgICAgIGhlbHA9Im92ZXJ3cml0ZXMgZXhpc3Rpbmcgb3V0cHV0IGZpbGVzIikKCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctZCcsICctLWR1bXAnLCBkZXN0PSdkdW1wJywgYWN0aW9uPSdzdG9yZV90cnVlJywKICAgICAgICAgICAgICAgICAgICAgICAgaGVscD0iaW5zdGVhZCBvZiBkZWNvbXBpbGluZywgcHJldHR5IHByaW50IHRoZSBhc3QgdG8gYSBmaWxlIikKCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctcCcsICctLXByb2Nlc3NlcycsIGRlc3Q9J3Byb2Nlc3NlcycsIGFjdGlvbj0nc3RvcmUnLCBkZWZhdWx0PWNwdV9jb3VudCgpLAogICAgICAgICAgICAgICAgICAgICAgICBoZWxwPSJ1c2UgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgcHJvY2Vzc2VzIHRvIGRlY29tcGlsZSIpCgogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLXQnLCAnLS10cmFuc2xhdGlvbi1maWxlJywgZGVzdD0ndHJhbnNsYXRpb25fZmlsZScsIGFjdGlvbj0nc3RvcmUnLCBkZWZhdWx0PU5vbmUsCiAgICAgICAgICAgICAgICAgICAgICAgIGhlbHA9InVzZSB0aGUgc3BlY2lmaWVkIGZpbGUgdG8gdHJhbnNsYXRlIGR1cmluZyBkZWNvbXBpbGF0aW9uIikKCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctVCcsICctLXdyaXRlLXRyYW5zbGF0aW9uLWZpbGUnLCBkZXN0PSd3cml0ZV90cmFuc2xhdGlvbl9maWxlJywgYWN0aW9uPSdzdG9yZScsIGRlZmF1bHQ9Tm9uZSwKICAgICAgICAgICAgICAgICAgICAgICAgaGVscD0ic3RvcmUgdHJhbnNsYXRpb25zIGluIHRoZSBzcGVjaWZpZWQgZmlsZSBpbnN0ZWFkIG9mIGRlY29tcGlsaW5nIikKCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctbCcsICctLWxhbmd1YWdlJywgZGVzdD0nbGFuZ3VhZ2UnLCBhY3Rpb249J3N0b3JlJywgZGVmYXVsdD0nZW5nbGlzaCcsCiAgICAgICAgICAgICAgICAgICAgICAgIGhlbHA9ImlmIHdyaXRpbmcgYSB0cmFuc2xhdGlvbiBmaWxlLCB0aGUgbGFuZ3VhZ2Ugb2YgdGhlIHRyYW5zbGF0aW9ucyB0byB3cml0ZSIpCgogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLS1zbDEtYXMtcHl0aG9uJywgZGVzdD0nZGVjb21waWxlX3B5dGhvbicsIGFjdGlvbj0nc3RvcmVfdHJ1ZScsCiAgICAgICAgICAgICAgICAgICAgICAgIGhlbHA9Ik9ubHkgZHVtcGluZyBhbmQgZm9yIGRlY29tcGlsaW5nIHNjcmVlbiBsYW5ndWFnZSAxIHNjcmVlbnMuICIKICAgICAgICAgICAgICAgICAgICAgICAgIkNvbnZlcnQgU0wxIFB5dGhvbiBBU1QgdG8gUHl0aG9uIGNvZGUgaW5zdGVhZCBvZiBkdW1waW5nIGl0IG9yIGNvbnZlcnRpbmcgaXQgdG8gc2NyZWVubGFuZy4iKQoKICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy0tY29tcGFyYWJsZScsIGRlc3Q9J2NvbXBhcmFibGUnLCBhY3Rpb249J3N0b3JlX3RydWUnLAogICAgICAgICAgICAgICAgICAgICAgICBoZWxwPSJPbmx5IGZvciBkdW1waW5nLCByZW1vdmUgc2V2ZXJhbCBmYWxzZSBkaWZmZXJlbmNlcyB3aGVuIGNvbXBhcmluZyBkdW1wcy4gIgogICAgICAgICAgICAgICAgICAgICAgICAiVGhpcyBzdXBwcmVzc2VzIGF0dHJpYnV0ZXMgdGhhdCBhcmUgZGlmZmVyZW50IGV2ZW4gd2hlbiB0aGUgY29kZSBpcyBpZGVudGljYWwsIHN1Y2ggYXMgZmlsZSBtb2RpZmljYXRpb24gdGltZXMuICIpCgogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLS1uby1weWV4cHInLCBkZXN0PSdub19weWV4cHInLCBhY3Rpb249J3N0b3JlX3RydWUnLAogICAgICAgICAgICAgICAgICAgICAgICBoZWxwPSJPbmx5IGZvciBkdW1waW5nLCBkaXNhYmxlIHNwZWNpYWwgaGFuZGxpbmcgb2YgUHlFeHByIG9iamVjdHMsIGluc3RlYWQgcHJpbnRpbmcgdGhlbSBhcyBzdHJpbmdzLiAiCiAgICAgICAgICAgICAgICAgICAgICAgICJUaGlzIGlzIHVzZWZ1bCB3aGVuIGNvbXBhcmluZyBkdW1wcyBmcm9tIGRpZmZlcmVudCB2ZXJzaW9ucyBvZiBSZW4nUHkuICIKICAgICAgICAgICAgICAgICAgICAgICAgIkl0IHNob3VsZCBvbmx5IGJlIHVzZWQgaWYgbmVjZXNzYXJ5LCBzaW5jZSBpdCB3aWxsIGNhdXNlIGxvc3Mgb2YgaW5mb3JtYXRpb24gc3VjaCBhcyBsaW5lIG51bWJlcnMuIikKCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctLWluaXQtb2Zmc2V0JywgZGVzdD0naW5pdF9vZmZzZXQnLCBhY3Rpb249J3N0b3JlX3RydWUnLAogICAgICAgICAgICAgICAgICAgICAgICBoZWxwPSJBdHRlbXB0IHRvIGd1ZXNzIHdoZW4gaW5pdCBvZmZzZXQgc3RhdGVtZW50cyB3ZXJlIHVzZWQgYW5kIGluc2VydCB0aGVtLiAiCiAgICAgICAgICAgICAgICAgICAgICAgICJUaGlzIGlzIGFsd2F5cyBzYWZlIHRvIGVuYWJsZSBpZiB0aGUgZ2FtZSdzIFJlbidQeSB2ZXJzaW9uIHN1cHBvcnRzIGluaXQgb2Zmc2V0IHN0YXRlbWVudHMsICIKICAgICAgICAgICAgICAgICAgICAgICAgImFuZCB0aGUgZ2VuZXJhdGVkIGNvZGUgaXMgZXhhY3RseSBlcXVpdmFsZW50LCBvbmx5IGxlc3MgY2x1dHRlcmVkLiIpCgogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnZmlsZScsIHR5cGU9c3RyLCBuYXJncz0nKycsCiAgICAgICAgICAgICAgICAgICAgICAgIGhlbHA9IlRoZSBmaWxlbmFtZXMgdG8gZGVjb21waWxlLiAiCiAgICAgICAgICAgICAgICAgICAgICAgICJBbGwgLnJweWMgZmlsZXMgaW4gYW55IGRpcmVjdG9yaWVzIHBhc3NlZCBvciB0aGVpciBzdWJkaXJlY3RvcmllcyB3aWxsIGFsc28gYmUgZGVjb21waWxlZC4iKQoKICAgIGFyZ3MgPSBwYXJzZXIucGFyc2VfYXJncygpCgogICAgaWYgYXJncy53cml0ZV90cmFuc2xhdGlvbl9maWxlIGFuZCBub3QgYXJncy5jbG9iYmVyIGFuZCBwYXRoLmV4aXN0cyhhcmdzLndyaXRlX3RyYW5zbGF0aW9uX2ZpbGUpOgogICAgICAgICMgRmFpbCBlYXJseSB0byBhdm9pZCB3YXN0aW5nIHRpbWUgZ29pbmcgdGhyb3VnaCB0aGUgZmlsZXMKICAgICAgICBwcmludCgiT3V0cHV0IHRyYW5zbGF0aW9uIGZpbGUgYWxyZWFkeSBleGlzdHMuIFBhc3MgLS1jbG9iYmVyIHRvIG92ZXJ3cml0ZS4iKQogICAgICAgIHJldHVybgoKICAgIGlmIGFyZ3MudHJhbnNsYXRpb25fZmlsZToKICAgICAgICB3aXRoIG9wZW4oYXJncy50cmFuc2xhdGlvbl9maWxlLCAncmInKSBhcyBpbl9maWxlOgogICAgICAgICAgICBhcmdzLnRyYW5zbGF0aW9ucyA9IGluX2ZpbGUucmVhZCgpCgogICAgIyBFeHBhbmQgd2lsZGNhcmRzCiAgICBkZWYgZ2xvYl9vcl9jb21wbGFpbihzKToKICAgICAgICByZXR2YWwgPSBnbG9iLmdsb2IocykKICAgICAgICBpZiBub3QgcmV0dmFsOgogICAgICAgICAgICBwcmludCgiRmlsZSBub3QgZm91bmQ6ICIgKyBzKQogICAgICAgIHJldHVybiByZXR2YWwKICAgIGZpbGVzQW5kRGlycyA9IG1hcChnbG9iX29yX2NvbXBsYWluLCBhcmdzLmZpbGUpCiAgICAjIENvbmNhdGVuYXRlIGxpc3RzCiAgICBmaWxlc0FuZERpcnMgPSBsaXN0KGl0ZXJ0b29scy5jaGFpbigqZmlsZXNBbmREaXJzKSkKCiAgICAjIFJlY3Vyc2l2ZWx5IGFkZCAucnB5YyBmaWxlcyBmcm9tIGFueSBkaXJlY3RvcmllcyBwYXNzZWQKICAgIGZpbGVzID0gW10KICAgIGZvciBpIGluIGZpbGVzQW5kRGlyczoKICAgICAgICBpZiBwYXRoLmlzZGlyKGkpOgogICAgICAgICAgICBmb3IgZGlycGF0aCwgZGlybmFtZXMsIGZpbGVuYW1lcyBpbiB3YWxrKGkpOgogICAgICAgICAgICAgICAgZmlsZXMuZXh0ZW5kKHBhdGguam9pbihkaXJwYXRoLCBqKSBmb3IgaiBpbiBmaWxlbmFtZXMgaWYgbGVuKGopID49IDUgYW5kIGpbLTU6XSA9PSAnLnJweWMnKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGZpbGVzLmFwcGVuZChpKQoKICAgICMgQ2hlY2sgaWYgd2UgYWN0dWFsbHkgaGF2ZSBmaWxlcy4gRG9uJ3Qgd29ycnkgYWJvdXQKICAgICMgbm8gcGFyYW1ldGVycyBwYXNzZWQsIHNpbmNlIEFyZ3VtZW50UGFyc2VyIGNhdGNoZXMgdGhhdAogICAgaWYgbGVuKGZpbGVzKSA9PSAwOgogICAgICAgIHByaW50KCJObyBzY3JpcHQgZmlsZXMgdG8gZGVjb21waWxlLiIpCiAgICAgICAgcmV0dXJuCgogICAgZmlsZXMgPSBtYXAobGFtYmRhIHg6IChhcmdzLCB4LCBwYXRoLmdldHNpemUoeCkpLCBmaWxlcykKICAgIHByb2Nlc3NlcyA9IGludChhcmdzLnByb2Nlc3NlcykKICAgIGlmIHByb2Nlc3NlcyA+IDE6CiAgICAgICAgIyBJZiBhIGJpZyBmaWxlIHN0YXJ0cyBuZWFyIHRoZSBlbmQsIHRoZXJlIGNvdWxkIGJlIGEgbG9uZyB0aW1lIHdpdGgKICAgICAgICAjIG9ubHkgb25lIHRocmVhZCBydW5uaW5nLCB3aGljaCBpcyBpbmVmZmljaWVudC4gQXZvaWQgdGhpcyBieSBzdGFydGluZwogICAgICAgICMgYmlnIGZpbGVzIGZpcnN0LgogICAgICAgIGZpbGVzLnNvcnQoa2V5PWl0ZW1nZXR0ZXIoMiksIHJldmVyc2U9VHJ1ZSkKICAgICAgICByZXN1bHRzID0gUG9vbChpbnQoYXJncy5wcm9jZXNzZXMpLCBzaGFyZWxvY2ssIFtwcmludGxvY2tdKS5tYXAod29ya2VyLCBmaWxlcywgMSkKICAgIGVsc2U6CiAgICAgICAgIyBEZWNvbXBpbGUgaW4gdGhlIG9yZGVyIFJlbidQeSBsb2FkcyBpbgogICAgICAgIGZpbGVzLnNvcnQoa2V5PWl0ZW1nZXR0ZXIoMSkpCiAgICAgICAgcmVzdWx0cyA9IG1hcCh3b3JrZXIsIGZpbGVzKQoKICAgIGlmIGFyZ3Mud3JpdGVfdHJhbnNsYXRpb25fZmlsZToKICAgICAgICBwcmludCgiV3JpdGluZyB0cmFuc2xhdGlvbnMgdG8gJXMuLi4iICUgYXJncy53cml0ZV90cmFuc2xhdGlvbl9maWxlKQogICAgICAgIHRyYW5zbGF0ZWRfZGlhbG9ndWUgPSB7fQogICAgICAgIHRyYW5zbGF0ZWRfc3RyaW5ncyA9IHt9CiAgICAgICAgZ29vZCA9IDAKICAgICAgICBiYWQgPSAwCiAgICAgICAgZm9yIHJlc3VsdCBpbiByZXN1bHRzOgogICAgICAgICAgICBpZiBub3QgcmVzdWx0OgogICAgICAgICAgICAgICAgYmFkICs9IDEKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIGdvb2QgKz0gMQogICAgICAgICAgICB0cmFuc2xhdGVkX2RpYWxvZ3VlLnVwZGF0ZShtYWdpYy5sb2FkcyhyZXN1bHRbMF0sIGNsYXNzX2ZhY3RvcnkpKQogICAgICAgICAgICB0cmFuc2xhdGVkX3N0cmluZ3MudXBkYXRlKHJlc3VsdFsxXSkKICAgICAgICB3aXRoIG9wZW4oYXJncy53cml0ZV90cmFuc2xhdGlvbl9maWxlLCAnd2InKSBhcyBvdXRfZmlsZToKICAgICAgICAgICAgbWFnaWMuc2FmZV9kdW1wKChhcmdzLmxhbmd1YWdlLCB0cmFuc2xhdGVkX2RpYWxvZ3VlLCB0cmFuc2xhdGVkX3N0cmluZ3MpLCBvdXRfZmlsZSkKCiAgICBlbHNlOgogICAgICAgICMgQ2hlY2sgcGVyIGZpbGUgaWYgZXZlcnl0aGluZyB3ZW50IHdlbGwgYW5kIHJlcG9ydCBiYWNrCiAgICAgICAgZ29vZCA9IHJlc3VsdHMuY291bnQoVHJ1ZSkKICAgICAgICBiYWQgPSByZXN1bHRzLmNvdW50KEZhbHNlKQoKICAgIGlmIGJhZCA9PSAwOgogICAgICAgIHByaW50KCJEZWNvbXBpbGF0aW9uIG9mICVkIHNjcmlwdCBmaWxlJXMgc3VjY2Vzc2Z1bCIgJSAoZ29vZCwgJ3MnIGlmIGdvb2Q+MSBlbHNlICcnKSkKICAgIGVsaWYgZ29vZCA9PSAwOgogICAgICAgIHByaW50KCJEZWNvbXBpbGF0aW9uIG9mICVkIGZpbGUlcyBmYWlsZWQiICUgKGJhZCwgJ3MnIGlmIGJhZD4xIGVsc2UgJycpKQogICAgZWxzZToKICAgICAgICBwcmludCgiRGVjb21waWxhdGlvbiBvZiAlZCBmaWxlJXMgc3VjY2Vzc2Z1bCwgYnV0IGRlY29tcGlsYXRpb24gb2YgJWQgZmlsZSVzIGZhaWxlZCIgJSAoZ29vZCwgJ3MnIGlmIGdvb2Q+MSBlbHNlICcnLCBiYWQsICdzJyBpZiBiYWQ+MSBlbHNlICcnKSkKCmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CiAgICBtYWluKCkK" base64 --decode <<< "$unrpyc" > /tmp/unrpyc.py # ------------------------------------------------------------------------------------------ # unrpyc decompiler decompiler=" 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NzE3MTY3MSAwMTQ3NTIAIDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdXN0YXIAMDB0ZWQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHN0YWZmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMDAwIAAwMDAwMDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUJ1ZDEAABAAAAAIAAAAEAAAAAQKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAkAAAABAAAQAABpAHQAXwBfAC4AcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAACAAAAABAAAAQAAAAAEAAACAAAAAAQAAAQAAAAABAAACAAAAAAEAAAQAAAAAAAAAAAEAABAAAAAAAQAAIAAAAAABAABAAAAAAAEAAIAAAAAAAQABAAAAAAABAAIAAAAAAAEABAAAAAAAAQAIAAAAAAABABAAAAAAAAEAIAAAAAAAAQBAAAAAAAABAIAAAAAAAAEBAAAAAAAAAQIAAAAAAAABBAAAAAAAAAEIAAAAAAAAARAAAAAAAAABIAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAEAsAAABFAAAECgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBERTREIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAIAAAAGAAAAAAAAAAAQAAAIAAAAABAAABAAAAAAEAAAIAAAAAAAAAAAIAAAgAAAAYAAAAAAAAAAABAAAgAAAAAAEAAEAAAAAAAQAAgAAAAAABAAEAAAAAAAEAAgAAAAAAAQAEAAAAAAABAAgAAAAAAAEAEAAAAAAAAQAgAAAAAAABAEAAAAAAAAEAgAAAAAAAAQEAAAAAAAABAgAAAAAAAAEEAAAAAAAAAQgAAAAAAAABEAAAAAAAAAEgAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuL2RlY29tcGlsZXIvLl9fX2luaXRfXy5weQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwNzU1IAAwMDA3NjcgADAwMDAyNCAAMDAwMDAwMDA1NzEgMTMyMTU1MjUwNjQgMDE1NjE2ACAwAAAAAAAAAAAAAAAAAAAA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ZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgojCiMgVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KIyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KIwojIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCiMgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiMgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiMgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgojIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiMgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUKIyBTT0ZUV0FSRS4KCmZyb20gX19mdXR1cmVfXyBpbXBvcnQgdW5pY29kZV9saXRlcmFscwpmcm9tIHV0aWwgaW1wb3J0IERlY29tcGlsZXJCYXNlLCBGaXJzdCwgV29yZENvbmNhdGVuYXRvciwgcmVjb25zdHJ1Y3RfcGFyYW1pbmZvLCBcCiAgICAgICAgICAgICAgICAgcmVjb25zdHJ1Y3RfYXJnaW5mbywgc3RyaW5nX2VzY2FwZSwgc3BsaXRfbG9naWNhbF9saW5lcywgRGlzcGF0Y2hlcgpmcm9tIHV0aWwgaW1wb3J0IHNheV9nZXRfY29kZQoKZnJvbSBvcGVyYXRvciBpbXBvcnQgaXRlbWdldHRlcgpmcm9tIFN0cmluZ0lPIGltcG9ydCBTdHJpbmdJTwoKaW1wb3J0IG1hZ2ljCm1hZ2ljLmZha2VfcGFja2FnZShiInJlbnB5IikKaW1wb3J0IHJlbnB5CgppbXBvcnQgc2NyZWVuZGVjb21waWxlcgppbXBvcnQgc2wyZGVjb21waWxlcgppbXBvcnQgdGVzdGNhc2VkZWNvbXBpbGVyCmltcG9ydCBjb2RlZ2VuCmltcG9ydCBhc3RkdW1wCgpfX2FsbF9fID0gWyJhc3RkdW1wIiwgImNvZGVnZW4iLCAibWFnaWMiLCAic2NyZWVuZGVjb21waWxlciIsICJzbDJkZWNvbXBpbGVyIiwgInRlc3RjYXNlZGVjb21waWxlciIsICJ0cmFuc2xhdGUiLCAidXRpbCIsICJwcHJpbnQiLCAiRGVjb21waWxlciJdCgojIE1haW4gQVBJCgpkZWYgcHByaW50KG91dF9maWxlLCBhc3QsIGluZGVudF9sZXZlbD0wLAogICAgICAgICAgIGRlY29tcGlsZV9weXRob249RmFsc2UsIHByaW50bG9jaz1Ob25lLCB0cmFuc2xhdG9yPU5vbmUsIGluaXRfb2Zmc2V0PUZhbHNlKToKICAgIERlY29tcGlsZXIob3V0X2ZpbGUsIHByaW50bG9jaz1wcmludGxvY2ssCiAgICAgICAgICAgICAgIGRlY29tcGlsZV9weXRob249ZGVjb21waWxlX3B5dGhvbiwgdHJhbnNsYXRvcj10cmFuc2xhdG9yKS5kdW1wKGFzdCwgaW5kZW50X2xldmVsLCBpbml0X29mZnNldCkKCiMgSW1wbGVtZW50YXRpb24KCmNsYXNzIERlY29tcGlsZXIoRGVjb21waWxlckJhc2UpOgogICAgIiIiCiAgICBBbiBvYmplY3Qgd2hpY2ggaGFubGRlcyB0aGUgZGVjb21waWxhdGlvbiBvZiByZW5weSBhc3RzIHRvIGEgZ2l2ZW4gc3RyZWFtCiAgICAiIiIKCiAgICAjIFRoaXMgZGljdGlvbmFyeSBpcyBhIG1hcHBpbmcgb2YgQ2xhc3M6IHVuYm91bnRfbWV0aG9kLCB3aGljaCBpcyB1c2VkIHRvIGRldGVybWluZQogICAgIyB3aGF0IG1ldGhvZCB0byBjYWxsIGZvciB3aGljaCBhc3QgY2xhc3MKICAgIGRpc3BhdGNoID0gRGlzcGF0Y2hlcigpCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG91dF9maWxlPU5vbmUsIGRlY29tcGlsZV9weXRob249RmFsc2UsCiAgICAgICAgICAgICAgICAgaW5kZW50YXRpb24gPSAnICAgICcsIHByaW50bG9jaz1Ob25lLCB0cmFuc2xhdG9yPU5vbmUpOgogICAgICAgIHN1cGVyKERlY29tcGlsZXIsIHNlbGYpLl9faW5pdF9fKG91dF9maWxlLCBpbmRlbnRhdGlvbiwgcHJpbnRsb2NrKQogICAgICAgIHNlbGYuZGVjb21waWxlX3B5dGhvbiA9IGRlY29tcGlsZV9weXRob24KICAgICAgICBzZWxmLnRyYW5zbGF0b3IgPSB0cmFuc2xhdG9yCgogICAgICAgIHNlbGYucGFpcmVkX3dpdGggPSBGYWxzZQogICAgICAgIHNlbGYuc2F5X2luc2lkZV9tZW51ID0gTm9uZQogICAgICAgIHNlbGYubGFiZWxfaW5zaWRlX21lbnUgPSBOb25lCiAgICAgICAgc2VsZi5pbl9pbml0ID0gRmFsc2UKICAgICAgICBzZWxmLm1pc3NpbmdfaW5pdCA9IEZhbHNlCiAgICAgICAgc2VsZi5pbml0X29mZnNldCA9IDAKICAgICAgICBzZWxmLmlzXzM1NmM2ZTM0X29yX2xhdGVyID0gRmFsc2UKCiAgICBkZWYgZHVtcChzZWxmLCBhc3QsIGluZGVudF9sZXZlbD0wLCBpbml0X29mZnNldD1GYWxzZSk6CiAgICAgICAgaWYgKGlzaW5zdGFuY2UoYXN0LCAodHVwbGUsIGxpc3QpKSBhbmQgbGVuKGFzdCkgPiAxIGFuZAogICAgICAgICAgICBpc2luc3RhbmNlKGFzdFstMV0sIHJlbnB5LmFzdC5SZXR1cm4pIGFuZAogICAgICAgICAgICAobm90IGhhc2F0dHIoYXN0Wy0xXSwgJ2V4cHJlc3Npb24nKSBvciBhc3RbLTFdLmV4cHJlc3Npb24gaXMgTm9uZSkgYW5kCiAgICAgICAgICAgIGFzdFstMV0ubGluZW51bWJlciA9PSBhc3RbLTJdLmxpbmVudW1iZXIpOgogICAgICAgICAgICAjIEEgdmVyeSBjcnVkZSB2ZXJzaW9uIGNoZWNrLCBidXQgY3VycmVudGx5IHRoZSBiZXN0IHdlIGNhbiBkby4KICAgICAgICAgICAgIyBOb3RlIHRoYXQgdGhpcyBjb21taXQgZmlyc3QgYXBwZWFycyBpbiB0aGUgNi45OSByZWxlYXNlLgogICAgICAgICAgICBzZWxmLmlzXzM1NmM2ZTM0X29yX2xhdGVyID0gVHJ1ZQoKICAgICAgICBpZiBzZWxmLnRyYW5zbGF0b3I6CiAgICAgICAgICAgIHNlbGYudHJhbnNsYXRvci50cmFuc2xhdGVfZGlhbG9ndWUoYXN0KQoKICAgICAgICBpZiBpbml0X29mZnNldCBhbmQgaXNpbnN0YW5jZShhc3QsICh0dXBsZSwgbGlzdCkpOgogICAgICAgICAgICBzZWxmLnNldF9iZXN0X2luaXRfb2Zmc2V0KGFzdCkKCiAgICAgICAgIyBza2lwX2luZGVudF91bnRpbF93cml0ZSBhdm9pZHMgYW4gaW5pdGlhbCBibGFuayBsaW5lCiAgICAgICAgc3VwZXIoRGVjb21waWxlciwgc2VsZikuZHVtcChhc3QsIGluZGVudF9sZXZlbCwgc2tpcF9pbmRlbnRfdW50aWxfd3JpdGU9VHJ1ZSkKICAgICAgICAjIGlmIHRoZXJlJ3MgYW55dGhpbmcgd2Ugd2FudGVkIHRvIHdyaXRlIG91dCBidXQgZGlkbid0IHlldCwgZG8gaXQgbm93CiAgICAgICAgZm9yIG0gaW4gc2VsZi5ibGFua19saW5lX3F1ZXVlOgogICAgICAgICAgICBtKE5vbmUpCiAgICAgICAgc2VsZi53cml0ZSgiXG4jIERlY29tcGlsZWQgYnkgdW5ycHljOiBodHRwczovL2dpdGh1Yi5jb20vQ2Vuc29yZWRVc2VybmFtZS91bnJweWNcbiIpCiAgICAgICAgYXNzZXJ0IG5vdCBzZWxmLm1pc3NpbmdfaW5pdCwgIkEgcmVxdWlyZWQgaW5pdCwgaW5pdCBsYWJlbCwgb3IgdHJhbnNsYXRlIGJsb2NrIHdhcyBtaXNzaW5nIgoKICAgIGRlZiBwcmludF9ub2RlKHNlbGYsIGFzdCk6CiAgICAgICAgIyBXZSBzcGVjaWFsLWNhc2UgbGluZSBhZHZhbmNlbWVudCBmb3IgVHJhbnNsYXRlU3RyaW5nIGluIGl0cyBwcmludAogICAgICAgICMgbWV0aG9kLCBzbyBkb24ndCBhZHZhbmNlIGxpbmVzIGZvciBpdCBoZXJlLgogICAgICAgIGlmIGhhc2F0dHIoYXN0LCAnbGluZW51bWJlcicpIGFuZCBub3QgaXNpbnN0YW5jZShhc3QsIHJlbnB5LmFzdC5UcmFuc2xhdGVTdHJpbmcpOgogICAgICAgICAgICBzZWxmLmFkdmFuY2VfdG9fbGluZShhc3QubGluZW51bWJlcikKICAgICAgICAjIEl0IGRvZXNuJ3QgbWF0dGVyIHdoYXQgbGluZSAiYmxvY2s6IiBpcyBvbi4gVGhlIGxvYyBvZiBhIFJhd0Jsb2NrCiAgICAgICAgIyByZWZlcnMgdG8gdGhlIGZpcnN0IHN0YXRlbWVudCBpbnNpZGUgdGhlIGJsb2NrLCB3aGljaCB3ZSBhZHZhbmNlCiAgICAgICAgIyB0byBmcm9tIHByaW50X2F0bC4KICAgICAgICBlbGlmIGhhc2F0dHIoYXN0LCAnbG9jJykgYW5kIG5vdCBpc2luc3RhbmNlKGFzdCwgcmVucHkuYXRsLlJhd0Jsb2NrKToKICAgICAgICAgICAgc2VsZi5hZHZhbmNlX3RvX2xpbmUoYXN0LmxvY1sxXSkKICAgICAgICBzZWxmLmRpc3BhdGNoLmdldCh0eXBlKGFzdCksIHR5cGUoc2VsZikucHJpbnRfdW5rbm93bikoc2VsZiwgYXN0KQoKICAgICMgQVRMIHByaW50aW5nIGZ1bmN0aW9ucwoKICAgIGRlZiBwcmludF9hdGwoc2VsZiwgYXN0KToKICAgICAgICB3aXRoIHNlbGYuaW5jcmVhc2VfaW5kZW50KCk6CiAgICAgICAgICAgIHNlbGYuYWR2YW5jZV90b19saW5lKGFzdC5sb2NbMV0pCiAgICAgICAgICAgIGlmIGFzdC5zdGF0ZW1lbnRzOgogICAgICAgICAgICAgICAgc2VsZi5wcmludF9ub2Rlcyhhc3Quc3RhdGVtZW50cykKICAgICAgICAgICAgIyBJZiBhIHN0YXRlbWVudCBlbmRzIHdpdGggYSBjb2xvbiBidXQgaGFzIG5vIGJsb2NrIGFmdGVyIGl0LCBsb2Mgd2lsbAogICAgICAgICAgICAjIGdldCBzZXQgdG8gKCcnLCAwKS4gVGhhdCBpc24ndCBzdXBwb3NlZCB0byBiZSB2YWxpZCBzeW50YXgsIGJ1dCBpdCdzCiAgICAgICAgICAgICMgdGhlIG9ubHkgdGhpbmcgdGhhdCBjYW4gZ2VuZXJhdGUgdGhhdC4KICAgICAgICAgICAgZWxpZiBhc3QubG9jICE9ICgnJywgMCk6CiAgICAgICAgICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCJwYXNzIikKCiAgICBAZGlzcGF0Y2gocmVucHkuYXRsLlJhd011bHRpcHVycG9zZSkKICAgIGRlZiBwcmludF9hdGxfcmF3bXVsdGkoc2VsZiwgYXN0KToKICAgICAgICB3YXJwX3dvcmRzID0gV29yZENvbmNhdGVuYXRvcihGYWxzZSkKCiAgICAgICAgIyB3YXJwZXJzCiAgICAgICAgaWYgYXN0LndhcnBfZnVuY3Rpb246CiAgICAgICAgICAgIHdhcnBfd29yZHMuYXBwZW5kKCJ3YXJwIiwgYXN0LndhcnBfZnVuY3Rpb24sIGFzdC5kdXJhdGlvbikKICAgICAgICBlbGlmIGFzdC53YXJwZXI6CiAgICAgICAgICAgIHdhcnBfd29yZHMuYXBwZW5kKGFzdC53YXJwZXIsIGFzdC5kdXJhdGlvbikKICAgICAgICBlbGlmIGFzdC5kdXJhdGlvbiAhPSAiMCI6CiAgICAgICAgICAgIHdhcnBfd29yZHMuYXBwZW5kKCJwYXVzZSIsIGFzdC5kdXJhdGlvbikKCiAgICAgICAgd2FycCA9IHdhcnBfd29yZHMuam9pbigpCiAgICAgICAgd29yZHMgPSBXb3JkQ29uY2F0ZW5hdG9yKHdhcnAgYW5kIHdhcnBbLTFdICE9ICcgJywgVHJ1ZSkKCiAgICAgICAgIyByZXZvbHV0aW9uCiAgICAgICAgaWYgYXN0LnJldm9sdXRpb246CiAgICAgICAgICAgIHdvcmRzLmFwcGVuZChhc3QucmV2b2x1dGlvbikKCiAgICAgICAgIyBjaXJjbGVzCiAgICAgICAgaWYgYXN0LmNpcmNsZXMgIT0gIjAiOgogICAgICAgICAgICB3b3Jkcy5hcHBlbmQoImNpcmNsZXMgJXMiICUgYXN0LmNpcmNsZXMpCgogICAgICAgICMgc3BsaW5lcwogICAgICAgIHNwbGluZV93b3JkcyA9IFdvcmRDb25jYXRlbmF0b3IoRmFsc2UpCiAgICAgICAgZm9yIG5hbWUsIGV4cHJlc3Npb25zIGluIGFzdC5zcGxpbmVzOgogICAgICAgICAgICBzcGxpbmVfd29yZHMuYXBwZW5kKG5hbWUsIGV4cHJlc3Npb25zWy0xXSkKICAgICAgICAgICAgZm9yIGV4cHJlc3Npb24gaW4gZXhwcmVzc2lvbnNbOi0xXToKICAgICAgICAgICAgICAgIHNwbGluZV93b3Jkcy5hcHBlbmQoImtub3QiLCBleHByZXNzaW9uKQogICAgICAgIHdvcmRzLmFwcGVuZChzcGxpbmVfd29yZHMuam9pbigpKQoKICAgICAgICAjIHByb3BlcnRpZXMKICAgICAgICBwcm9wZXJ0eV93b3JkcyA9IFdvcmRDb25jYXRlbmF0b3IoRmFsc2UpCiAgICAgICAgZm9yIGtleSwgdmFsdWUgaW4gYXN0LnByb3BlcnRpZXM6CiAgICAgICAgICAgIHByb3BlcnR5X3dvcmRzLmFwcGVuZChrZXksIHZhbHVlKQogICAgICAgIHdvcmRzLmFwcGVuZChwcm9wZXJ0eV93b3Jkcy5qb2luKCkpCgogICAgICAgICMgd2l0aAogICAgICAgIGV4cHJlc3Npb25fd29yZHMgPSBXb3JkQ29uY2F0ZW5hdG9yKEZhbHNlKQogICAgICAgICMgVE9ETyBUaGVyZSdzIGEgbG90IG9mIGNhc2VzIHdoZXJlIHBhc3MgaXNuJ3QgbmVlZGVkLCBzaW5jZSB3ZSBjb3VsZAogICAgICAgICMgcmVvcmRlciBzdHVmZiBzbyB0aGVyZSdzIG5ldmVyIDIgZXhwcmVzc2lvbnMgaW4gYSByb3cuIChBbmQgaXQncyBuZXZlcgogICAgICAgICMgbmVjZXNzYXJ5IGZvciB0aGUgbGFzdCBvbmUsIGJ1dCB3ZSBkb24ndCBrbm93IHdoYXQgdGhlIGxhc3Qgb25lIGlzCiAgICAgICAgIyBzaW5jZSBpdCBjb3VsZCBnZXQgcmVvcmRlcmVkLikKICAgICAgICBuZWVkc19wYXNzID0gbGVuKGFzdC5leHByZXNzaW9ucykgPiAxCiAgICAgICAgZm9yIChleHByZXNzaW9uLCB3aXRoX2V4cHJlc3Npb24pIGluIGFzdC5leHByZXNzaW9uczoKICAgICAgICAgICAgZXhwcmVzc2lvbl93b3Jkcy5hcHBlbmQoZXhwcmVzc2lvbikKICAgICAgICAgICAgaWYgd2l0aF9leHByZXNzaW9uOgogICAgICAgICAgICAgICAgZXhwcmVzc2lvbl93b3Jkcy5hcHBlbmQoIndpdGgiLCB3aXRoX2V4cHJlc3Npb24pCiAgICAgICAgICAgIGlmIG5lZWRzX3Bhc3M6CiAgICAgICAgICAgICAgICBleHByZXNzaW9uX3dvcmRzLmFwcGVuZCgicGFzcyIpCiAgICAgICAgd29yZHMuYXBwZW5kKGV4cHJlc3Npb25fd29yZHMuam9pbigpKQoKICAgICAgICB0b193cml0ZSA9IHdhcnAgKyB3b3Jkcy5qb2luKCkKICAgICAgICBpZiB0b193cml0ZToKICAgICAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgICAgICBzZWxmLndyaXRlKHRvX3dyaXRlKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgICMgQSB0cmFpbGluZyBjb21tYSByZXN1bHRzIGluIGFuIGVtcHR5IFJhd011bHRpcHVycG9zZSBiZWluZwogICAgICAgICAgICAjIGdlbmVyYXRlZCBvbiB0aGUgc2FtZSBsaW5lIGFzIHRoZSBsYXN0IHJlYWwgb25lLgogICAgICAgICAgICBzZWxmLndyaXRlKCIsIikKCiAgICBAZGlzcGF0Y2gocmVucHkuYXRsLlJhd0Jsb2NrKQogICAgZGVmIHByaW50X2F0bF9yYXdibG9jayhzZWxmLCBhc3QpOgogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCJibG9jazoiKQogICAgICAgIHNlbGYucHJpbnRfYXRsKGFzdCkKCiAgICBAZGlzcGF0Y2gocmVucHkuYXRsLlJhd0NoaWxkKQogICAgZGVmIHByaW50X2F0bF9yYXdjaGlsZChzZWxmLCBhc3QpOgogICAgICAgIGZvciBjaGlsZCBpbiBhc3QuY2hpbGRyZW46CiAgICAgICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICAgICAgc2VsZi53cml0ZSgiY29udGFpbnM6IikKICAgICAgICAgICAgc2VsZi5wcmludF9hdGwoY2hpbGQpCgogICAgQGRpc3BhdGNoKHJlbnB5LmF0bC5SYXdDaG9pY2UpCiAgICBkZWYgcHJpbnRfYXRsX3Jhd2Nob2ljZShzZWxmLCBhc3QpOgogICAgICAgIGZvciBjaGFuY2UsIGJsb2NrIGluIGFzdC5jaG9pY2VzOgogICAgICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgICAgIHNlbGYud3JpdGUoImNob2ljZSIpCiAgICAgICAgICAgIGlmIGNoYW5jZSAhPSAiMS4wIjoKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoIiAlcyIgJSBjaGFuY2UpCiAgICAgICAgICAgIHNlbGYud3JpdGUoIjoiKQogICAgICAgICAgICBzZWxmLnByaW50X2F0bChibG9jaykKICAgICAgICBpZiAoc2VsZi5pbmRleCArIDEgPCBsZW4oc2VsZi5ibG9jaykgYW5kCiAgICAgICAgICAgIGlzaW5zdGFuY2Uoc2VsZi5ibG9ja1tzZWxmLmluZGV4ICsgMV0sIHJlbnB5LmF0bC5SYXdDaG9pY2UpKToKICAgICAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgICAgICBzZWxmLndyaXRlKCJwYXNzIikKCiAgICBAZGlzcGF0Y2gocmVucHkuYXRsLlJhd0NvbnRhaW5zRXhwcikKICAgIGRlZiBwcmludF9hdGxfcmF3Y29udGFpbnNleHByKHNlbGYsIGFzdCk6CiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoImNvbnRhaW5zICVzIiAlIGFzdC5leHByZXNzaW9uKQoKICAgIEBkaXNwYXRjaChyZW5weS5hdGwuUmF3RXZlbnQpCiAgICBkZWYgcHJpbnRfYXRsX3Jhd2V2ZW50KHNlbGYsIGFzdCk6CiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoImV2ZW50ICVzIiAlIGFzdC5uYW1lKQoKICAgIEBkaXNwYXRjaChyZW5weS5hdGwuUmF3RnVuY3Rpb24pCiAgICBkZWYgcHJpbnRfYXRsX3Jhd2Z1bmN0aW9uKHNlbGYsIGFzdCk6CiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoImZ1bmN0aW9uICVzIiAlIGFzdC5leHByKQoKICAgIEBkaXNwYXRjaChyZW5weS5hdGwuUmF3T24pCiAgICBkZWYgcHJpbnRfYXRsX3Jhd29uKHNlbGYsIGFzdCk6CiAgICAgICAgZm9yIG5hbWUsIGJsb2NrIGluIHNvcnRlZChhc3QuaGFuZGxlcnMuaXRlbXMoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleT1sYW1iZGEgaTogaVsxXS5sb2NbMV0pOgogICAgICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgICAgIHNlbGYud3JpdGUoIm9uICVzOiIgJSBuYW1lKQogICAgICAgICAgICBzZWxmLnByaW50X2F0bChibG9jaykKCiAgICBAZGlzcGF0Y2gocmVucHkuYXRsLlJhd1BhcmFsbGVsKQogICAgZGVmIHByaW50X2F0bF9yYXdwYXJhbGxlbChzZWxmLCBhc3QpOgogICAgICAgIGZvciBibG9jayBpbiBhc3QuYmxvY2tzOgogICAgICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgICAgIHNlbGYud3JpdGUoInBhcmFsbGVsOiIpCiAgICAgICAgICAgIHNlbGYucHJpbnRfYXRsKGJsb2NrKQogICAgICAgIGlmIChzZWxmLmluZGV4ICsgMSA8IGxlbihzZWxmLmJsb2NrKSBhbmQKICAgICAgICAgICAgaXNpbnN0YW5jZShzZWxmLmJsb2NrW3NlbGYuaW5kZXggKyAxXSwgcmVucHkuYXRsLlJhd1BhcmFsbGVsKSk6CiAgICAgICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICAgICAgc2VsZi53cml0ZSgicGFzcyIpCgogICAgQGRpc3BhdGNoKHJlbnB5LmF0bC5SYXdSZXBlYXQpCiAgICBkZWYgcHJpbnRfYXRsX3Jhd3JlcGVhdChzZWxmLCBhc3QpOgogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCJyZXBlYXQiKQogICAgICAgIGlmIGFzdC5yZXBlYXRzOgogICAgICAgICAgICBzZWxmLndyaXRlKCIgJXMiICUgYXN0LnJlcGVhdHMpICMgbm90IHN1cmUgaWYgdGhpcyBpcyBldmVuIGEgc3RyaW5nCgogICAgQGRpc3BhdGNoKHJlbnB5LmF0bC5SYXdUaW1lKQogICAgZGVmIHByaW50X2F0bF9yYXd0aW1lKHNlbGYsIGFzdCk6CiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoInRpbWUgJXMiICUgYXN0LnRpbWUpCgogICAgIyBEaXNwbGF5YWJsZSByZWxhdGVkIGZ1bmN0aW9ucwoKICAgIGRlZiBwcmludF9pbXNwZWMoc2VsZiwgaW1zcGVjKToKICAgICAgICBpZiBpbXNwZWNbMV0gaXMgbm90IE5vbmU6CiAgICAgICAgICAgIGJlZ2luID0gImV4cHJlc3Npb24gJXMiICUgaW1zcGVjWzFdCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYmVnaW4gPSAiICIuam9pbihpbXNwZWNbMF0pCgogICAgICAgIHdvcmRzID0gV29yZENvbmNhdGVuYXRvcihiZWdpbiBhbmQgYmVnaW5bLTFdICE9ICcgJywgVHJ1ZSkKICAgICAgICBpZiBpbXNwZWNbMl0gaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHdvcmRzLmFwcGVuZCgiYXMgJXMiICUgaW1zcGVjWzJdKQoKICAgICAgICBpZiBsZW4oaW1zcGVjWzZdKSA+IDA6CiAgICAgICAgICAgIHdvcmRzLmFwcGVuZCgiYmVoaW5kICVzIiAlICcsICcuam9pbihpbXNwZWNbNl0pKQoKICAgICAgICBpZiBpc2luc3RhbmNlKGltc3BlY1s0XSwgdW5pY29kZSk6CiAgICAgICAgICAgIHdvcmRzLmFwcGVuZCgib25sYXllciAlcyIgJSBpbXNwZWNbNF0pCgogICAgICAgIGlmIGltc3BlY1s1XSBpcyBub3QgTm9uZToKICAgICAgICAgICAgd29yZHMuYXBwZW5kKCJ6b3JkZXIgJXMiICUgaW1zcGVjWzVdKQoKICAgICAgICBpZiBsZW4oaW1zcGVjWzNdKSA+IDA6CiAgICAgICAgICAgIHdvcmRzLmFwcGVuZCgiYXQgJXMiICUgJywgJy5qb2luKGltc3BlY1szXSkpCgogICAgICAgIHNlbGYud3JpdGUoYmVnaW4gKyB3b3Jkcy5qb2luKCkpCiAgICAgICAgcmV0dXJuIHdvcmRzLm5lZWRzX3NwYWNlCgogICAgQGRpc3BhdGNoKHJlbnB5LmFzdC5JbWFnZSkKICAgIGRlZiBwcmludF9pbWFnZShzZWxmLCBhc3QpOgogICAgICAgIHNlbGYucmVxdWlyZV9pbml0KCkKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZSgiaW1hZ2UgJXMiICUgJyAnLmpvaW4oYXN0LmltZ25hbWUpKQogICAgICAgIGlmIGFzdC5jb2RlIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLndyaXRlKCIgPSAlcyIgJSBhc3QuY29kZS5zb3VyY2UpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgaWYgaGFzYXR0cihhc3QsICJhdGwiKSBhbmQgYXN0LmF0bCBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoIjoiKQogICAgICAgICAgICAgICAgc2VsZi5wcmludF9hdGwoYXN0LmF0bCkKCiAgICBAZGlzcGF0Y2gocmVucHkuYXN0LlRyYW5zZm9ybSkKICAgIGRlZiBwcmludF90cmFuc2Zvcm0oc2VsZiwgYXN0KToKICAgICAgICBzZWxmLnJlcXVpcmVfaW5pdCgpCiAgICAgICAgc2VsZi5pbmRlbnQoKQoKICAgICAgICAjIElmIHdlIGhhdmUgYW4gaW1wbGljaXQgaW5pdCBibG9jayB3aXRoIGEgbm9uLWRlZmF1bHQgcHJpb3JpdHksIHdlIG5lZWQgdG8gc3RvcmUgdGhlIHByaW9yaXR5IGhlcmUuCiAgICAgICAgcHJpb3JpdHkgPSAiIgogICAgICAgIGlmIGlzaW5zdGFuY2Uoc2VsZi5wYXJlbnQsIHJlbnB5LmFzdC5Jbml0KToKICAgICAgICAgICAgaW5pdCA9IHNlbGYucGFyZW50CiAgICAgICAgICAgIGlmIGluaXQucHJpb3JpdHkgIT0gc2VsZi5pbml0X29mZnNldCBhbmQgbGVuKGluaXQuYmxvY2spID09IDEgYW5kIG5vdCBzZWxmLnNob3VsZF9jb21lX2JlZm9yZShpbml0LCBhc3QpOgogICAgICAgICAgICAgICAgcHJpb3JpdHkgPSAiICVkIiAlIChpbml0LnByaW9yaXR5IC0gc2VsZi5pbml0X29mZnNldCkKICAgICAgICBzZWxmLndyaXRlKCJ0cmFuc2Zvcm0lcyAlcyIgJSAocHJpb3JpdHksIGFzdC52YXJuYW1lKSkKICAgICAgICBpZiBhc3QucGFyYW1ldGVycyBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi53cml0ZShyZWNvbnN0cnVjdF9wYXJhbWluZm8oYXN0LnBhcmFtZXRlcnMpKQoKICAgICAgICBpZiBoYXNhdHRyKGFzdCwgImF0bCIpIGFuZCBhc3QuYXRsIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLndyaXRlKCI6IikKICAgICAgICAgICAgc2VsZi5wcmludF9hdGwoYXN0LmF0bCkKCiAgICAjIERpcmVjdGluZyByZWxhdGVkIGZ1bmN0aW9ucwoKICAgIEBkaXNwYXRjaChyZW5weS5hc3QuU2hvdykKICAgIGRlZiBwcmludF9zaG93KHNlbGYsIGFzdCk6CiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoInNob3cgIikKICAgICAgICBuZWVkc19zcGFjZSA9IHNlbGYucHJpbnRfaW1zcGVjKGFzdC5pbXNwZWMpCgogICAgICAgIGlmIHNlbGYucGFpcmVkX3dpdGg6CiAgICAgICAgICAgIGlmIG5lZWRzX3NwYWNlOgogICAgICAgICAgICAgICAgc2VsZi53cml0ZSgiICIpCiAgICAgICAgICAgIHNlbGYud3JpdGUoIndpdGggJXMiICUgc2VsZi5wYWlyZWRfd2l0aCkKICAgICAgICAgICAgc2VsZi5wYWlyZWRfd2l0aCA9IFRydWUKCiAgICAgICAgaWYgaGFzYXR0cihhc3QsICJhdGwiKSBhbmQgYXN0LmF0bCBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi53cml0ZSgiOiIpCiAgICAgICAgICAgIHNlbGYucHJpbnRfYXRsKGFzdC5hdGwpCgogICAgQGRpc3BhdGNoKHJlbnB5LmFzdC5TaG93TGF5ZXIpCiAgICBkZWYgcHJpbnRfc2hvd2xheWVyKHNlbGYsIGFzdCk6CiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoInNob3cgbGF5ZXIgJXMiICUgYXN0LmxheWVyKQoKICAgICAgICBpZiBhc3QuYXRfbGlzdDoKICAgICAgICAgICAgc2VsZi53cml0ZSgiIGF0ICVzIiAlICcsICcuam9pbihhc3QuYXRfbGlzdCkpCgogICAgICAgIGlmIGhhc2F0dHIoYXN0LCAiYXRsIikgYW5kIGFzdC5hdGwgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYud3JpdGUoIjoiKQogICAgICAgICAgICBzZWxmLnByaW50X2F0bChhc3QuYXRsKQoKICAgIEBkaXNwYXRjaChyZW5weS5hc3QuU2NlbmUpCiAgICBkZWYgcHJpbnRfc2NlbmUoc2VsZiwgYXN0KToKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZSgic2NlbmUiKQoKICAgICAgICBpZiBhc3QuaW1zcGVjIGlzIE5vbmU6CiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UoYXN0LmxheWVyLCB1bmljb2RlKToKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoIiBvbmxheWVyICVzIiAlIGFzdC5sYXllcikKICAgICAgICAgICAgbmVlZHNfc3BhY2UgPSBUcnVlCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi53cml0ZSgiICIpCiAgICAgICAgICAgIG5lZWRzX3NwYWNlID0gc2VsZi5wcmludF9pbXNwZWMoYXN0Lmltc3BlYykKCiAgICAgICAgaWYgc2VsZi5wYWlyZWRfd2l0aDoKICAgICAgICAgICAgaWYgbmVlZHNfc3BhY2U6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCIgIikKICAgICAgICAgICAgc2VsZi53cml0ZSgid2l0aCAlcyIgJSBzZWxmLnBhaXJlZF93aXRoKQogICAgICAgICAgICBzZWxmLnBhaXJlZF93aXRoID0gVHJ1ZQoKICAgICAgICBpZiBoYXNhdHRyKGFzdCwgImF0bCIpIGFuZCBhc3QuYXRsIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLndyaXRlKCI6IikKICAgICAgICAgICAgc2VsZi5wcmludF9hdGwoYXN0LmF0bCkKCiAgICBAZGlzcGF0Y2gocmVucHkuYXN0LkhpZGUpCiAgICBkZWYgcHJpbnRfaGlkZShzZWxmLCBhc3QpOgogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCJoaWRlICIpCiAgICAgICAgbmVlZHNfc3BhY2UgPSBzZWxmLnByaW50X2ltc3BlYyhhc3QuaW1zcGVjKQogICAgICAgIGlmIHNlbGYucGFpcmVkX3dpdGg6CiAgICAgICAgICAgIGlmIG5lZWRzX3NwYWNlOgogICAgICAgICAgICAgICAgc2VsZi53cml0ZSgiICIpCiAgICAgICAgICAgIHNlbGYud3JpdGUoIndpdGggJXMiICUgc2VsZi5wYWlyZWRfd2l0aCkKICAgICAgICAgICAgc2VsZi5wYWlyZWRfd2l0aCA9IFRydWUKCiAgICBAZGlzcGF0Y2gocmVucHkuYXN0LldpdGgpCiAgICBkZWYgcHJpbnRfd2l0aChzZWxmLCBhc3QpOgogICAgICAgICMgdGhlICdwYWlyZWQnIGF0dHJpYnV0ZSBpbmRpY2F0ZXMgdGhhdCB0aGlzIHdpdGgKICAgICAgICAjIGFuZCB3aXRoIG5vZGUgYWZ0ZXJ3YXJkcyBhcmUgcGFydCBvZiBhIHBvc3RmaXgKICAgICAgICAjIHdpdGggc3RhdGVtZW50LiBkZXRlY3QgdGhpcyBhbmQgcHJvY2VzcyBpdCBwcm9wZXJseQogICAgICAgIGlmIGhhc2F0dHIoYXN0LCAicGFpcmVkIikgYW5kIGFzdC5wYWlyZWQgaXMgbm90IE5vbmU6CiAgICAgICAgICAgICMgU2FuaXR5IGNoZWNrLiBjaGVjayBpZiB0aGVyZSdzIGEgbWF0Y2hpbmcgd2l0aCBzdGF0ZW1lbnQgdHdvIG5vZGVzIGZ1cnRoZXIKICAgICAgICAgICAgaWYgbm90KGlzaW5zdGFuY2Uoc2VsZi5ibG9ja1tzZWxmLmluZGV4ICsgMl0sIHJlbnB5LmFzdC5XaXRoKSBhbmQKICAgICAgICAgICAgICAgICAgIHNlbGYuYmxvY2tbc2VsZi5pbmRleCArIDJdLmV4cHIgPT0gYXN0LnBhaXJlZCk6CiAgICAgICAgICAgICAgICByYWlzZSBFeGNlcHRpb24oIlVubWF0Y2hlZCBwYWlyZWQgd2l0aCB7MH0gIT0gezF9Ii5mb3JtYXQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVwcihzZWxmLnBhaXJlZF93aXRoKSwgcmVwcihhc3QuZXhwcikpKQoKICAgICAgICAgICAgc2VsZi5wYWlyZWRfd2l0aCA9IGFzdC5wYWlyZWQKCiAgICAgICAgZWxpZiBzZWxmLnBhaXJlZF93aXRoOgogICAgICAgICAgICAjIENoZWNrIGlmIGl0IHdhcyBjb25zdW1lZCBieSBhIHNob3cvc2NlbmUgc3RhdGVtZW50CiAgICAgICAgICAgIGlmIHNlbGYucGFpcmVkX3dpdGggaXMgbm90IFRydWU6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCIgd2l0aCAlcyIgJSBhc3QuZXhwcikKICAgICAgICAgICAgc2VsZi5wYWlyZWRfd2l0aCA9IEZhbHNlCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgICAgICBzZWxmLndyaXRlKCJ3aXRoICVzIiAlIGFzdC5leHByKQogICAgICAgICAgICBzZWxmLnBhaXJlZF93aXRoID0gRmFsc2UKCiAgICAjIEZsb3cgY29udHJvbAoKICAgIEBkaXNwYXRjaChyZW5weS5hc3QuTGFiZWwpCiAgICBkZWYgcHJpbnRfbGFiZWwoc2VsZiwgYXN0KToKICAgICAgICAjIElmIGEgQ2FsbCBibG9jayBwcmVjZWRlZCB1cywgaXQgcHJpbnRlZCB1cyBhcyAiZnJvbSIKICAgICAgICBpZiAoc2VsZi5pbmRleCBhbmQgaXNpbnN0YW5jZShzZWxmLmJsb2NrW3NlbGYuaW5kZXggLSAxXSwgcmVucHkuYXN0LkNhbGwpKToKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgcmVtYWluaW5nX2Jsb2NrcyA9IGxlbihzZWxmLmJsb2NrKSAtIHNlbGYuaW5kZXgKICAgICAgICAjIFNlZSBpZiB3ZSdyZSB0aGUgbGFiZWwgZm9yIGEgbWVudSwgcmF0aGVyIHRoYW4gYSBzdGFuZGFsb25lIGxhYmVsLgogICAgICAgIGlmIHJlbWFpbmluZ19ibG9ja3MgPiAxIGFuZCBub3QgYXN0LmJsb2NrIGFuZCAobm90IGhhc2F0dHIoYXN0LCAncGFyYW1ldGVycycpIG9yIGFzdC5wYXJhbWV0ZXJzIGlzIE5vbmUpOgogICAgICAgICAgICBuZXh0X2FzdCA9IHNlbGYuYmxvY2tbc2VsZi5pbmRleCArIDFdCiAgICAgICAgICAgIGlmIChoYXNhdHRyKG5leHRfYXN0LCAnbGluZW51bWJlcicpIGFuZCBuZXh0X2FzdC5saW5lbnVtYmVyID09IGFzdC5saW5lbnVtYmVyIGFuZAogICAgICAgICAgICAgICAgKGlzaW5zdGFuY2UobmV4dF9hc3QsIHJlbnB5LmFzdC5NZW51KSBvciAocmVtYWluaW5nX2Jsb2NrcyA+IDIgYW5kCiAgICAgICAgICAgICAgICBpc2luc3RhbmNlKG5leHRfYXN0LCByZW5weS5hc3QuU2F5KSBhbmQKICAgICAgICAgICAgICAgIHNlbGYuc2F5X2JlbG9uZ3NfdG9fbWVudShuZXh0X2FzdCwgc2VsZi5ibG9ja1tzZWxmLmluZGV4ICsgMl0pKSkpOgogICAgICAgICAgICAgICAgc2VsZi5sYWJlbF9pbnNpZGVfbWVudSA9IGFzdAogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgc2VsZi5pbmRlbnQoKQoKICAgICAgICAjIEl0J3MgcG9zc2libGUgdGhhdCB3ZSdyZSBhbiAiaW5pdCBsYWJlbCIsIG5vdCBhIHJlZ3VsYXIgbGFiZWwuIFRoZXJlJ3Mgbm8gd2F5IHRvIGtub3cKICAgICAgICAjIGlmIHdlIGFyZSB1bnRpbCB3ZSBwYXJzZSBvdXIgY2hpbGRyZW4sIHNvIHRlbXBvcmFyaWx5IHJlZGlyZWN0IGFsbCBvZiBvdXIgb3V0cHV0IHVudGlsCiAgICAgICAgIyB0aGF0J3MgZG9uZSwgc28gdGhhdCB3ZSBjYW4gc3F1ZWV6ZSBpbiBhbiAiaW5pdCAiIGlmIHdlIGFyZS4KICAgICAgICBvdXRfZmlsZSA9IHNlbGYub3V0X2ZpbGUKICAgICAgICBzZWxmLm91dF9maWxlID0gU3RyaW5nSU8oKQogICAgICAgIG1pc3NpbmdfaW5pdCA9IHNlbGYubWlzc2luZ19pbml0CiAgICAgICAgc2VsZi5taXNzaW5nX2luaXQgPSBGYWxzZQogICAgICAgIHRyeToKICAgICAgICAgICAgc2VsZi53cml0ZSgibGFiZWwgJXMlcyVzOiIgJSAoCiAgICAgICAgICAgICAgICBhc3QubmFtZSwKICAgICAgICAgICAgICAgIHJlY29uc3RydWN0X3BhcmFtaW5mbyhhc3QucGFyYW1ldGVycykgaWYgaGFzYXR0cihhc3QsICdwYXJhbWV0ZXJzJykgZWxzZSAnJywKICAgICAgICAgICAgICAgICIgaGlkZSIgaWYgaGFzYXR0cihhc3QsICdoaWRlJykgYW5kIGFzdC5oaWRlIGVsc2UgIiIpKQogICAgICAgICAgICBzZWxmLnByaW50X25vZGVzKGFzdC5ibG9jaywgMSkKICAgICAgICBmaW5hbGx5OgogICAgICAgICAgICBpZiBzZWxmLm1pc3NpbmdfaW5pdDoKICAgICAgICAgICAgICAgIG91dF9maWxlLndyaXRlKCJpbml0ICIpCiAgICAgICAgICAgIHNlbGYubWlzc2luZ19pbml0ID0gbWlzc2luZ19pbml0CiAgICAgICAgICAgIG91dF9maWxlLndyaXRlKHNlbGYub3V0X2ZpbGUuZ2V0dmFsdWUoKSkKICAgICAgICAgICAgc2VsZi5vdXRfZmlsZSA9IG91dF9maWxlCgogICAgQGRpc3BhdGNoKHJlbnB5LmFzdC5KdW1wKQogICAgZGVmIHByaW50X2p1bXAoc2VsZiwgYXN0KToKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZSgianVtcCAlcyVzIiAlICgiZXhwcmVzc2lvbiAiIGlmIGFzdC5leHByZXNzaW9uIGVsc2UgIiIsIGFzdC50YXJnZXQpKQoKICAgIEBkaXNwYXRjaChyZW5weS5hc3QuQ2FsbCkKICAgIGRlZiBwcmludF9jYWxsKHNlbGYsIGFzdCk6CiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHdvcmRzID0gV29yZENvbmNhdGVuYXRvcihGYWxzZSkKICAgICAgICB3b3Jkcy5hcHBlbmQoImNhbGwiKQogICAgICAgIGlmIGFzdC5leHByZXNzaW9uOgogICAgICAgICAgICB3b3Jkcy5hcHBlbmQoImV4cHJlc3Npb24iKQogICAgICAgIHdvcmRzLmFwcGVuZChhc3QubGFiZWwpCgogICAgICAgIGlmIGhhc2F0dHIoYXN0LCAnYXJndW1lbnRzJykgYW5kIGFzdC5hcmd1bWVudHMgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIGlmIGFzdC5leHByZXNzaW9uOgogICAgICAgICAgICAgICAgd29yZHMuYXBwZW5kKCJwYXNzIikKICAgICAgICAgICAgd29yZHMuYXBwZW5kKHJlY29uc3RydWN0X2FyZ2luZm8oYXN0LmFyZ3VtZW50cykpCgogICAgICAgICMgV2UgZG9uJ3QgaGF2ZSB0byBjaGVjayBpZiB0aGVyZSdzIGVub3VnaCBlbGVtZW50cyBoZXJlLAogICAgICAgICMgc2luY2UgYSBMYWJlbCBvciBhIFBhc3MgaXMgYWx3YXlzIGVtaXR0ZWQgYWZ0ZXIgYSBDYWxsLgogICAgICAgIG5leHRfYmxvY2sgPSBzZWxmLmJsb2NrW3NlbGYuaW5kZXggKyAxXQogICAgICAgIGlmIGlzaW5zdGFuY2UobmV4dF9ibG9jaywgcmVucHkuYXN0LkxhYmVsKToKICAgICAgICAgICAgd29yZHMuYXBwZW5kKCJmcm9tICVzIiAlIG5leHRfYmxvY2submFtZSkKCiAgICAgICAgc2VsZi53cml0ZSh3b3Jkcy5qb2luKCkpCgogICAgQGRpc3BhdGNoKHJlbnB5LmFzdC5SZXR1cm4pCiAgICBkZWYgcHJpbnRfcmV0dXJuKHNlbGYsIGFzdCk6CiAgICAgICAgaWYgKChub3QgaGFzYXR0cihhc3QsICdleHByZXNzaW9uJykgb3IgYXN0LmV4cHJlc3Npb24gaXMgTm9uZSkgYW5kIHNlbGYucGFyZW50IGlzIE5vbmUgYW5kCiAgICAgICAgICAgIHNlbGYuaW5kZXggKyAxID09IGxlbihzZWxmLmJsb2NrKSBhbmQgc2VsZi5pbmRleCBhbmQKICAgICAgICAgICAgYXN0LmxpbmVudW1iZXIgPT0gc2VsZi5ibG9ja1tzZWxmLmluZGV4IC0gMV0ubGluZW51bWJlcik6CiAgICAgICAgICAgICMgQXMgb2YgUmVuJ1B5IGNvbW1pdCAzNTZjNmUzNCwgYSByZXR1cm4gc3RhdGVtZW50IGlzIGFkZGVkIHRvCiAgICAgICAgICAgICMgdGhlIGVuZCBvZiBlYWNoIHJweWMgZmlsZS4gRG9uJ3QgaW5jbHVkZSB0aGlzIGluIHRoZSBzb3VyY2UuCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZSgicmV0dXJuIikKCiAgICAgICAgaWYgaGFzYXR0cihhc3QsICdleHByZXNzaW9uJykgYW5kIGFzdC5leHByZXNzaW9uIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLndyaXRlKCIgJXMiICUgYXN0LmV4cHJlc3Npb24pCgogICAgQGRpc3BhdGNoKHJlbnB5LmFzdC5JZikKICAgIGRlZiBwcmludF9pZihzZWxmLCBhc3QpOgogICAgICAgIHN0YXRlbWVudCA9IEZpcnN0KCJpZiAlczoiLCAiZWxpZiAlczoiKQoKICAgICAgICBmb3IgaSwgKGNvbmRpdGlvbiwgYmxvY2spIGluIGVudW1lcmF0ZShhc3QuZW50cmllcyk6CiAgICAgICAgICAgICMgVGhlIG5vbi1Vbmljb2RlIHN0cmluZyAiVHJ1ZSIgaXMgdGhlIGNvbmRpdGlvbiBmb3IgZWxzZTouCiAgICAgICAgICAgIGlmIChpICsgMSkgPT0gbGVuKGFzdC5lbnRyaWVzKSBhbmQgbm90IGlzaW5zdGFuY2UoY29uZGl0aW9uLCB1bmljb2RlKToKICAgICAgICAgICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoImVsc2U6IikKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGlmKGhhc2F0dHIoY29uZGl0aW9uLCAnbGluZW51bWJlcicpKToKICAgICAgICAgICAgICAgICAgICBzZWxmLmFkdmFuY2VfdG9fbGluZShjb25kaXRpb24ubGluZW51bWJlcikKICAgICAgICAgICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoc3RhdGVtZW50KCkgJSBjb25kaXRpb24pCgogICAgICAgICAgICBzZWxmLnByaW50X25vZGVzKGJsb2NrLCAxKQoKICAgIEBkaXNwYXRjaChyZW5weS5hc3QuV2hpbGUpCiAgICBkZWYgcHJpbnRfd2hpbGUoc2VsZiwgYXN0KToKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZSgid2hpbGUgJXM6IiAlIGFzdC5jb25kaXRpb24pCgogICAgICAgIHNlbGYucHJpbnRfbm9kZXMoYXN0LmJsb2NrLCAxKQoKICAgIEBkaXNwYXRjaChyZW5weS5hc3QuUGFzcykKICAgIGRlZiBwcmludF9wYXNzKHNlbGYsIGFzdCk6CiAgICAgICAgaWYgKHNlbGYuaW5kZXggYW5kCiAgICAgICAgICAgIGlzaW5zdGFuY2Uoc2VsZi5ibG9ja1tzZWxmLmluZGV4IC0gMV0sIHJlbnB5LmFzdC5DYWxsKSk6CiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBpZiAoc2VsZi5pbmRleCA+IDEgYW5kCiAgICAgICAgICAgIGlzaW5zdGFuY2Uoc2VsZi5ibG9ja1tzZWxmLmluZGV4IC0gMl0sIHJlbnB5LmFzdC5DYWxsKSBhbmQKICAgICAgICAgICAgaXNpbnN0YW5jZShzZWxmLmJsb2NrW3NlbGYuaW5kZXggLSAxXSwgcmVucHkuYXN0LkxhYmVsKSBhbmQKICAgICAgICAgICAgc2VsZi5ibG9ja1tzZWxmLmluZGV4IC0gMl0ubGluZW51bWJlciA9PSBhc3QubGluZW51bWJlcik6CiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZSgicGFzcyIpCgogICAgZGVmIHNob3VsZF9jb21lX2JlZm9yZShzZWxmLCBmaXJzdCwgc2Vjb25kKToKICAgICAgICByZXR1cm4gZmlyc3QubGluZW51bWJlciA8IHNlY29uZC5saW5lbnVtYmVyCgogICAgZGVmIHJlcXVpcmVfaW5pdChzZWxmKToKICAgICAgICBpZiBub3Qgc2VsZi5pbl9pbml0OgogICAgICAgICAgICBzZWxmLm1pc3NpbmdfaW5pdCA9IFRydWUKCiAgICBkZWYgc2V0X2Jlc3RfaW5pdF9vZmZzZXQoc2VsZiwgbm9kZXMpOgogICAgICAgIHZvdGVzID0ge30KICAgICAgICBmb3IgYXN0IGluIG5vZGVzOgogICAgICAgICAgICBpZiBub3QgaXNpbnN0YW5jZShhc3QsIHJlbnB5LmFzdC5Jbml0KToKICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgIG9mZnNldCA9IGFzdC5wcmlvcml0eQogICAgICAgICAgICAjIEtlZXAgdGhpcyBibG9jayBpbiBzeW5jIHdpdGggcHJpbnRfaW5pdAogICAgICAgICAgICBpZiBsZW4oYXN0LmJsb2NrKSA9PSAxIGFuZCBub3Qgc2VsZi5zaG91bGRfY29tZV9iZWZvcmUoYXN0LCBhc3QuYmxvY2tbMF0pOgogICAgICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShhc3QuYmxvY2tbMF0sIHJlbnB5LmFzdC5TY3JlZW4pOgogICAgICAgICAgICAgICAgICAgIG9mZnNldCAtPSAtNTAwCiAgICAgICAgICAgICAgICBlbGlmIGlzaW5zdGFuY2UoYXN0LmJsb2NrWzBdLCByZW5weS5hc3QuVGVzdGNhc2UpOgogICAgICAgICAgICAgICAgICAgIG9mZnNldCAtPSA1MDAKICAgICAgICAgICAgICAgIGVsaWYgaXNpbnN0YW5jZShhc3QuYmxvY2tbMF0sIHJlbnB5LmFzdC5JbWFnZSk6CiAgICAgICAgICAgICAgICAgICAgb2Zmc2V0IC09IDUwMCBpZiBzZWxmLmlzXzM1NmM2ZTM0X29yX2xhdGVyIGVsc2UgOTkwCiAgICAgICAgICAgIHZvdGVzW29mZnNldF0gPSB2b3Rlcy5nZXQob2Zmc2V0LCAwKSArIDEKICAgICAgICBpZiB2b3RlczoKICAgICAgICAgICAgd2lubmVyID0gbWF4KHZvdGVzLCBrZXk9dm90ZXMuZ2V0KQogICAgICAgICAgICAjIEl0J3Mgb25seSB3b3J0aCBzZXR0aW5nIGFuIGluaXQgb2Zmc2V0IGlmIGl0IHdvdWxkIHNhdmUKICAgICAgICAgICAgIyBtb3JlIHRoYW4gb25lIHByaW9yaXR5IHNwZWNpZmljYXRpb24gdmVyc3VzIG5vdCBzZXR0aW5nIG9uZS4KICAgICAgICAgICAgaWYgdm90ZXMuZ2V0KDAsIDApICsgMSA8IHZvdGVzW3dpbm5lcl06CiAgICAgICAgICAgICAgICBzZWxmLnNldF9pbml0X29mZnNldCh3aW5uZXIpCgogICAgZGVmIHNldF9pbml0X29mZnNldChzZWxmLCBvZmZzZXQpOgogICAgICAgIGRlZiBkb19zZXRfaW5pdF9vZmZzZXQobGluZW51bWJlcik6CiAgICAgICAgICAgICMgaWYgd2UgZ290IHRvIHRoZSBlbmQgb2YgdGhlIGZpbGUgYW5kIGhhdmVuJ3QgZW1pdHRlZCB0aGlzIHlldCwKICAgICAgICAgICAgIyBkb24ndCBib3RoZXIsIHNpbmNlIGl0IG9ubHkgYXBwbGllcyB0byBzdHVmZiBiZWxvdyBpdC4KICAgICAgICAgICAgaWYgbGluZW51bWJlciBpcyBOb25lIG9yIGxpbmVudW1iZXIgLSBzZWxmLmxpbmVudW1iZXIgPD0gMSBvciBzZWxmLmluZGVudF9sZXZlbDoKICAgICAgICAgICAgICAgIHJldHVybiBUcnVlCiAgICAgICAgICAgIGlmIG9mZnNldCAhPSBzZWxmLmluaXRfb2Zmc2V0OgogICAgICAgICAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgICAgICAgICAgc2VsZi53cml0ZSgiaW5pdCBvZmZzZXQgPSAlcyIgJSBvZmZzZXQpCiAgICAgICAgICAgICAgICBzZWxmLmluaXRfb2Zmc2V0ID0gb2Zmc2V0CiAgICAgICAgICAgIHJldHVybiBGYWxzZQoKICAgICAgICBzZWxmLmRvX3doZW5fYmxhbmtfbGluZShkb19zZXRfaW5pdF9vZmZzZXQpCgogICAgQGRpc3BhdGNoKHJlbnB5LmFzdC5Jbml0KQogICAgZGVmIHByaW50X2luaXQoc2VsZiwgYXN0KToKICAgICAgICBpbl9pbml0ID0gc2VsZi5pbl9pbml0CiAgICAgICAgc2VsZi5pbl9pbml0ID0gVHJ1ZQogICAgICAgIHRyeToKICAgICAgICAgICAgIyBBIGJ1bmNoIG9mIHN0YXRlbWVudHMgY2FuIGhhdmUgaW1wbGljaXQgaW5pdCBibG9ja3MKICAgICAgICAgICAgIyBEZWZpbmUgaGFzIGEgZGVmYXVsdCBwcmlvcml0eSBvZiAwLCBzY3JlZW4gb2YgLTUwMCBhbmQgaW1hZ2Ugb2YgOTkwCiAgICAgICAgICAgICMgS2VlcCB0aGlzIGJsb2NrIGluIHN5bmMgd2l0aCBzZXRfYmVzdF9pbml0X29mZnNldAogICAgICAgICAgICAjIFRPRE8gbWVyZ2UgdGhpcyBhbmQgcmVxdWlyZV9pbml0IGludG8gYW5vdGhlciBkZWNvcmF0b3Igb3Igc29tZXRoaW5nCiAgICAgICAgICAgIGlmIGxlbihhc3QuYmxvY2spID09IDEgYW5kICgKICAgICAgICAgICAgICAgIGlzaW5zdGFuY2UoYXN0LmJsb2NrWzBdLCAocmVucHkuYXN0LkRlZmluZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVucHkuYXN0LkRlZmF1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbnB5LmFzdC5UcmFuc2Zvcm0pKSBvcgogICAgICAgICAgICAgICAgKGFzdC5wcmlvcml0eSA9PSAtNTAwICsgc2VsZi5pbml0X29mZnNldCBhbmQgaXNpbnN0YW5jZShhc3QuYmxvY2tbMF0sIHJlbnB5LmFzdC5TY3JlZW4pKSBvcgogICAgICAgICAgICAgICAgKGFzdC5wcmlvcml0eSA9PSBzZWxmLmluaXRfb2Zmc2V0IGFuZCBpc2luc3RhbmNlKGFzdC5ibG9ja1swXSwgcmVucHkuYXN0LlN0eWxlKSkgb3IKICAgICAgICAgICAgICAgIChhc3QucHJpb3JpdHkgPT0gNTAwICsgc2VsZi5pbml0X29mZnNldCBhbmQgaXNpbnN0YW5jZShhc3QuYmxvY2tbMF0sIHJlbnB5LmFzdC5UZXN0Y2FzZSkpIG9yCiAgICAgICAgICAgICAgICAjIEltYWdlcyBoYWQgdGhlaXIgZGVmYXVsdCBpbml0IHByaW9yaXR5IGNoYW5nZWQgaW4gY29tbWl0IDY3OWY5ZTMxIChSZW4nUHkgNi45OS4xMCkuCiAgICAgICAgICAgICAgICAjIFdlIGRvbid0IGhhdmUgYW55IHdheSBvZiBkZXRlY3RpbmcgdGhpcyBjb21taXQsIHRob3VnaC4gVGhlIGNsb3Nlc3Qgb25lIHdlIGNhbgogICAgICAgICAgICAgICAgIyBkZXRlY3QgaXMgMzU2YzZlMzQgKFJlbidQeSA2Ljk5KS4gRm9yIGFueSB2ZXJzaW9ucyBpbiBiZXR3ZWVuIHRoZXNlLCB3ZSdsbCBlbWl0CiAgICAgICAgICAgICAgICAjIGFuIHVubmVjZXNzYXJ5ICJpbml0IDk5MCAiIGJlZm9yZSBpbWFnZSBzdGF0ZW1lbnRzLCBidXQgdGhpcyBkb2Vzbid0IGFmZmVjdCB0aGUgQVNULAogICAgICAgICAgICAgICAgIyBhbmQgYW55IG90aGVyIHNvbHV0aW9uIHdvdWxkIHJlc3VsdCBpbiBpbmNvcnJlY3QgY29kZSBiZWluZyBnZW5lcmF0ZWQgaW4gc29tZSBjYXNlcy4KICAgICAgICAgICAgICAgIChhc3QucHJpb3JpdHkgPT0gKDUwMCBpZiBzZWxmLmlzXzM1NmM2ZTM0X29yX2xhdGVyIGVsc2UgOTkwKSArIHNlbGYuaW5pdF9vZmZzZXQgYW5kIGlzaW5zdGFuY2UoYXN0LmJsb2NrWzBdLCByZW5weS5hc3QuSW1hZ2UpKSkgYW5kIG5vdCAoCiAgICAgICAgICAgICAgICBzZWxmLnNob3VsZF9jb21lX2JlZm9yZShhc3QsIGFzdC5ibG9ja1swXSkpOgogICAgICAgICAgICAgICAgIyBJZiB0aGV5IGZ1bGZpbGwgdGhpcyBjcml0ZXJpYSB3ZSBqdXN0IHByaW50IHRoZSBjb250YWluZWQgc3RhdGVtZW50CiAgICAgICAgICAgICAgICBzZWxmLnByaW50X25vZGVzKGFzdC5ibG9jaykKCiAgICAgICAgICAgICMgdHJhbnNsYXRlc3RyaW5nIHN0YXRlbWVudHMgYXJlIHNwbGl0IGFwYXJ0IGFuZCBwdXQgaW4gYW4gaW5pdCBibG9jay4KICAgICAgICAgICAgZWxpZiAobGVuKGFzdC5ibG9jaykgPiAwIGFuZAogICAgICAgICAgICAgICAgICAgIGFzdC5wcmlvcml0eSA9PSBzZWxmLmluaXRfb2Zmc2V0IGFuZAogICAgICAgICAgICAgICAgICAgIGFsbChpc2luc3RhbmNlKGksIHJlbnB5LmFzdC5UcmFuc2xhdGVTdHJpbmcpIGZvciBpIGluIGFzdC5ibG9jaykgYW5kCiAgICAgICAgICAgICAgICAgICAgYWxsKGkubGFuZ3VhZ2UgPT0gYXN0LmJsb2NrWzBdLmxhbmd1YWdlIGZvciBpIGluIGFzdC5ibG9ja1sxOl0pKToKICAgICAgICAgICAgICAgIHNlbGYucHJpbnRfbm9kZXMoYXN0LmJsb2NrKQoKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoImluaXQiKQogICAgICAgICAgICAgICAgaWYgYXN0LnByaW9yaXR5ICE9IHNlbGYuaW5pdF9vZmZzZXQ6CiAgICAgICAgICAgICAgICAgICAgc2VsZi53cml0ZSgiICVkIiAlIChhc3QucHJpb3JpdHkgLSBzZWxmLmluaXRfb2Zmc2V0KSkKCiAgICAgICAgICAgICAgICBpZiBsZW4oYXN0LmJsb2NrKSA9PSAxIGFuZCBub3Qgc2VsZi5zaG91bGRfY29tZV9iZWZvcmUoYXN0LCBhc3QuYmxvY2tbMF0pOgogICAgICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoIiAiKQogICAgICAgICAgICAgICAgICAgIHNlbGYuc2tpcF9pbmRlbnRfdW50aWxfd3JpdGUgPSBUcnVlCiAgICAgICAgICAgICAgICAgICAgc2VsZi5wcmludF9ub2Rlcyhhc3QuYmxvY2spCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoIjoiKQogICAgICAgICAgICAgICAgICAgIHNlbGYucHJpbnRfbm9kZXMoYXN0LmJsb2NrLCAxKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIHNlbGYuaW5faW5pdCA9IGluX2luaXQKCiAgICBAZGlzcGF0Y2gocmVucHkuYXN0Lk1lbnUpCiAgICBkZWYgcHJpbnRfbWVudShzZWxmLCBhc3QpOgogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCJtZW51IikKICAgICAgICBpZiBzZWxmLmxhYmVsX2luc2lkZV9tZW51IGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLndyaXRlKCIgJXMiICUgc2VsZi5sYWJlbF9pbnNpZGVfbWVudS5uYW1lKQogICAgICAgICAgICBzZWxmLmxhYmVsX2luc2lkZV9tZW51ID0gTm9uZQogICAgICAgIHNlbGYud3JpdGUoIjoiKQogICAgICAgIHdpdGggc2VsZi5pbmNyZWFzZV9pbmRlbnQoKToKICAgICAgICAgICAgaWYgc2VsZi5zYXlfaW5zaWRlX21lbnUgaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICBzZWxmLnByaW50X3NheShzZWxmLnNheV9pbnNpZGVfbWVudSwgaW5tZW51PVRydWUpCiAgICAgICAgICAgICAgICBzZWxmLnNheV9pbnNpZGVfbWVudSA9IE5vbmUKCiAgICAgICAgICAgIGlmIGFzdC53aXRoXyBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoIndpdGggJXMiICUgYXN0LndpdGhfKQoKICAgICAgICAgICAgaWYgYXN0LnNldCBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoInNldCAlcyIgJSBhc3Quc2V0KQoKICAgICAgICAgICAgZm9yIGxhYmVsLCBjb25kaXRpb24sIGJsb2NrIGluIGFzdC5pdGVtczoKICAgICAgICAgICAgICAgIGlmIHNlbGYudHJhbnNsYXRvcjoKICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHNlbGYudHJhbnNsYXRvci5zdHJpbmdzLmdldChsYWJlbCwgbGFiZWwpCgogICAgICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShjb25kaXRpb24sIHVuaWNvZGUpOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYWR2YW5jZV90b19saW5lKGNvbmRpdGlvbi5saW5lbnVtYmVyKQogICAgICAgICAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgICAgICAgICAgc2VsZi53cml0ZSgnIiVzIicgJSBzdHJpbmdfZXNjYXBlKGxhYmVsKSkKCiAgICAgICAgICAgICAgICBpZiBibG9jayBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICBpZiBpc2luc3RhbmNlKGNvbmRpdGlvbiwgdW5pY29kZSk6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoIiBpZiAlcyIgJSBjb25kaXRpb24pCiAgICAgICAgICAgICAgICAgICAgc2VsZi53cml0ZSgiOiIpCiAgICAgICAgICAgICAgICAgICAgc2VsZi5wcmludF9ub2RlcyhibG9jaywgMSkKCiAgICAjIFByb2dyYW1taW5nIHJlbGF0ZWQgZnVuY3Rpb25zCgogICAgQGRpc3BhdGNoKHJlbnB5LmFzdC5QeXRob24pCiAgICBkZWYgcHJpbnRfcHl0aG9uKHNlbGYsIGFzdCwgZWFybHk9RmFsc2UpOgogICAgICAgIHNlbGYuaW5kZW50KCkKCiAgICAgICAgY29kZSA9IGFzdC5jb2RlLnNvdXJjZQogICAgICAgIGlmIGNvZGVbMF0gPT0gJ1xuJzoKICAgICAgICAgICAgY29kZSA9IGNvZGVbMTpdCiAgICAgICAgICAgIHNlbGYud3JpdGUoInB5dGhvbiIpCiAgICAgICAgICAgIGlmIGVhcmx5OgogICAgICAgICAgICAgICAgc2VsZi53cml0ZSgiIGVhcmx5IikKICAgICAgICAgICAgaWYgYXN0LmhpZGU6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCIgaGlkZSIpCiAgICAgICAgICAgIGlmIGhhc2F0dHIoYXN0LCAic3RvcmUiKSBhbmQgYXN0LnN0b3JlICE9ICJzdG9yZSI6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCIgaW4gIikKICAgICAgICAgICAgICAgICMgU3RyaXAgcHJlcGVuZGVkICJzdG9yZS4iCiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKGFzdC5zdG9yZVs2Ol0pCiAgICAgICAgICAgIHNlbGYud3JpdGUoIjoiKQoKICAgICAgICAgICAgd2l0aCBzZWxmLmluY3JlYXNlX2luZGVudCgpOgogICAgICAgICAgICAgICAgc2VsZi53cml0ZV9saW5lcyhzcGxpdF9sb2dpY2FsX2xpbmVzKGNvZGUpKQoKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLndyaXRlKCIkICVzIiAlIGNvZGUpCgogICAgQGRpc3BhdGNoKHJlbnB5LmFzdC5FYXJseVB5dGhvbikKICAgIGRlZiBwcmludF9lYXJseXB5dGhvbihzZWxmLCBhc3QpOgogICAgICAgIHNlbGYucHJpbnRfcHl0aG9uKGFzdCwgZWFybHk9VHJ1ZSkKCiAgICBAZGlzcGF0Y2gocmVucHkuYXN0LkRlZmluZSkKICAgIEBkaXNwYXRjaChyZW5weS5hc3QuRGVmYXVsdCkKICAgIGRlZiBwcmludF9kZWZpbmUoc2VsZiwgYXN0KToKICAgICAgICBzZWxmLnJlcXVpcmVfaW5pdCgpCiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIGlmIGlzaW5zdGFuY2UoYXN0LCByZW5weS5hc3QuRGVmYXVsdCk6CiAgICAgICAgICAgIG5hbWUgPSAiZGVmYXVsdCIKICAgICAgICBlbHNlOgogICAgICAgICAgICBuYW1lID0gImRlZmluZSIKCiAgICAgICAgIyBJZiB3ZSBoYXZlIGFuIGltcGxpY2l0IGluaXQgYmxvY2sgd2l0aCBhIG5vbi1kZWZhdWx0IHByaW9yaXR5LCB3ZSBuZWVkIHRvIHN0b3JlIHRoZSBwcmlvcml0eSBoZXJlLgogICAgICAgIHByaW9yaXR5ID0gIiIKICAgICAgICBpZiBpc2luc3RhbmNlKHNlbGYucGFyZW50LCByZW5weS5hc3QuSW5pdCk6CiAgICAgICAgICAgIGluaXQgPSBzZWxmLnBhcmVudAogICAgICAgICAgICBpZiBpbml0LnByaW9yaXR5ICE9IHNlbGYuaW5pdF9vZmZzZXQgYW5kIGxlbihpbml0LmJsb2NrKSA9PSAxIGFuZCBub3Qgc2VsZi5zaG91bGRfY29tZV9iZWZvcmUoaW5pdCwgYXN0KToKICAgICAgICAgICAgICAgIHByaW9yaXR5ID0gIiAlZCIgJSAoaW5pdC5wcmlvcml0eSAtIHNlbGYuaW5pdF9vZmZzZXQpCiAgICAgICAgaWYgbm90IGhhc2F0dHIoYXN0LCAic3RvcmUiKSBvciBhc3Quc3RvcmUgPT0gInN0b3JlIjoKICAgICAgICAgICAgc2VsZi53cml0ZSgiJXMlcyAlcyA9ICVzIiAlIChuYW1lLCBwcmlvcml0eSwgYXN0LnZhcm5hbWUsIGFzdC5jb2RlLnNvdXJjZSkpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi53cml0ZSgiJXMlcyAlcy4lcyA9ICVzIiAlIChuYW1lLCBwcmlvcml0eSwgYXN0LnN0b3JlWzY6XSwgYXN0LnZhcm5hbWUsIGFzdC5jb2RlLnNvdXJjZSkpCgogICAgIyBTcGVjaWFscwoKICAgICMgUmV0dXJucyB3aGV0aGVyIGEgU2F5IHN0YXRlbWVudCBpbW1lZGlhdGVseSBwcmVjZWRpbmcgYSBNZW51IHN0YXRlbWVudAogICAgIyBhY3R1YWxseSBiZWxvbmdzIGluc2lkZSBvZiB0aGUgTWVudSBzdGF0ZW1lbnQuCiAgICBkZWYgc2F5X2JlbG9uZ3NfdG9fbWVudShzZWxmLCBzYXksIG1lbnUpOgogICAgICAgIHJldHVybiAobm90IHNheS5pbnRlcmFjdCBhbmQgc2F5LndobyBpcyBub3QgTm9uZSBhbmQKICAgICAgICAgICAgc2F5LndpdGhfIGlzIE5vbmUgYW5kIAogICAgICAgICAgICAobm90IGhhc2F0dHIoc2F5LCAiYXR0cmlidXRlcyIpIG9yIHNheS5hdHRyaWJ1dGVzIGlzIE5vbmUpIGFuZAogICAgICAgICAgICBpc2luc3RhbmNlKG1lbnUsIHJlbnB5LmFzdC5NZW51KSBhbmQKICAgICAgICAgICAgbWVudS5pdGVtc1swXVsyXSBpcyBub3QgTm9uZSBhbmQKICAgICAgICAgICAgbm90IHNlbGYuc2hvdWxkX2NvbWVfYmVmb3JlKHNheSwgbWVudSkpCgogICAgQGRpc3BhdGNoKHJlbnB5LmFzdC5TYXkpCiAgICBkZWYgcHJpbnRfc2F5KHNlbGYsIGFzdCwgaW5tZW51PUZhbHNlKToKICAgICAgICBpZiAobm90IGlubWVudSBhbmQgc2VsZi5pbmRleCArIDEgPCBsZW4oc2VsZi5ibG9jaykgYW5kCiAgICAgICAgICAgIHNlbGYuc2F5X2JlbG9uZ3NfdG9fbWVudShhc3QsIHNlbGYuYmxvY2tbc2VsZi5pbmRleCArIDFdKSk6CiAgICAgICAgICAgIHNlbGYuc2F5X2luc2lkZV9tZW51ID0gYXN0CiAgICAgICAgICAgIHJldHVybgogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKHNheV9nZXRfY29kZShhc3QsIGlubWVudSkpCgogICAgQGRpc3BhdGNoKHJlbnB5LmFzdC5Vc2VyU3RhdGVtZW50KQogICAgZGVmIHByaW50X3VzZXJzdGF0ZW1lbnQoc2VsZiwgYXN0KToKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZShhc3QubGluZSkKCiAgICBAZGlzcGF0Y2gocmVucHkuYXN0LlN0eWxlKQogICAgZGVmIHByaW50X3N0eWxlKHNlbGYsIGFzdCk6CiAgICAgICAgc2VsZi5yZXF1aXJlX2luaXQoKQogICAgICAgIGtleXdvcmRzID0ge2FzdC5saW5lbnVtYmVyOiBXb3JkQ29uY2F0ZW5hdG9yKEZhbHNlLCBUcnVlKX0KCiAgICAgICAgIyBUaGVzZSBkb24ndCBzdG9yZSBhIGxpbmUgbnVtYmVyLCBzbyBqdXN0IHB1dCB0aGVtIG9uIHRoZSBmaXJzdCBsaW5lCiAgICAgICAgaWYgYXN0LnBhcmVudCBpcyBub3QgTm9uZToKICAgICAgICAgICAga2V5d29yZHNbYXN0LmxpbmVudW1iZXJdLmFwcGVuZCgiaXMgJXMiICUgYXN0LnBhcmVudCkKICAgICAgICBpZiBhc3QuY2xlYXI6CiAgICAgICAgICAgIGtleXdvcmRzW2FzdC5saW5lbnVtYmVyXS5hcHBlbmQoImNsZWFyIikKICAgICAgICBpZiBhc3QudGFrZSBpcyBub3QgTm9uZToKICAgICAgICAgICAga2V5d29yZHNbYXN0LmxpbmVudW1iZXJdLmFwcGVuZCgidGFrZSAlcyIgJSBhc3QudGFrZSkKICAgICAgICBmb3IgZGVsbmFtZSBpbiBhc3QuZGVsYXR0cjoKICAgICAgICAgICAga2V5d29yZHNbYXN0LmxpbmVudW1iZXJdLmFwcGVuZCgiZGVsICVzIiAlIGRlbG5hbWUpCgogICAgICAgICMgVGhlc2UgZG8gc3RvcmUgYSBsaW5lIG51bWJlcgogICAgICAgIGlmIGFzdC52YXJpYW50IGlzIG5vdCBOb25lOgogICAgICAgICAgICBpZiBhc3QudmFyaWFudC5saW5lbnVtYmVyIG5vdCBpbiBrZXl3b3JkczoKICAgICAgICAgICAgICAgIGtleXdvcmRzW2FzdC52YXJpYW50LmxpbmVudW1iZXJdID0gV29yZENvbmNhdGVuYXRvcihGYWxzZSkKICAgICAgICAgICAga2V5d29yZHNbYXN0LnZhcmlhbnQubGluZW51bWJlcl0uYXBwZW5kKCJ2YXJpYW50ICVzIiAlIGFzdC52YXJpYW50KQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGFzdC5wcm9wZXJ0aWVzLml0ZXJpdGVtcygpOgogICAgICAgICAgICBpZiB2YWx1ZS5saW5lbnVtYmVyIG5vdCBpbiBrZXl3b3JkczoKICAgICAgICAgICAgICAgIGtleXdvcmRzW3ZhbHVlLmxpbmVudW1iZXJdID0gV29yZENvbmNhdGVuYXRvcihGYWxzZSkKICAgICAgICAgICAga2V5d29yZHNbdmFsdWUubGluZW51bWJlcl0uYXBwZW5kKCIlcyAlcyIgJSAoa2V5LCB2YWx1ZSkpCgogICAgICAgIGtleXdvcmRzID0gc29ydGVkKFsoaywgdi5qb2luKCkpIGZvciBrLCB2IGluIGtleXdvcmRzLml0ZW1zKCldLAogICAgICAgICAgICAgICAgICAgICAgICAgIGtleT1pdGVtZ2V0dGVyKDApKQogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCJzdHlsZSAlcyIgJSBhc3Quc3R5bGVfbmFtZSkKICAgICAgICBpZiBrZXl3b3Jkc1swXVsxXToKICAgICAgICAgICAgc2VsZi53cml0ZSgiICVzIiAlIGtleXdvcmRzWzBdWzFdKQogICAgICAgIGlmIGxlbihrZXl3b3JkcykgPiAxOgogICAgICAgICAgICBzZWxmLndyaXRlKCI6IikKICAgICAgICAgICAgd2l0aCBzZWxmLmluY3JlYXNlX2luZGVudCgpOgogICAgICAgICAgICAgICAgZm9yIGkgaW4ga2V5d29yZHNbMTpdOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYWR2YW5jZV90b19saW5lKGlbMF0pCiAgICAgICAgICAgICAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoaVsxXSkKCiAgICAjIFRyYW5zbGF0aW9uIGZ1bmN0aW9ucwoKICAgIEBkaXNwYXRjaChyZW5weS5hc3QuVHJhbnNsYXRlKQogICAgZGVmIHByaW50X3RyYW5zbGF0ZShzZWxmLCBhc3QpOgogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCJ0cmFuc2xhdGUgJXMgJXM6IiAlIChhc3QubGFuZ3VhZ2Ugb3IgIk5vbmUiLCBhc3QuaWRlbnRpZmllcikpCgogICAgICAgIHNlbGYucHJpbnRfbm9kZXMoYXN0LmJsb2NrLCAxKQoKICAgIEBkaXNwYXRjaChyZW5weS5hc3QuRW5kVHJhbnNsYXRlKQogICAgZGVmIHByaW50X2VuZHRyYW5zbGF0ZShzZWxmLCBhc3QpOgogICAgICAgICMgYW4gaW1wbGljaXRseSBhZGRlZCBub2RlIHdoaWNoIGRvZXMgbm90aGluZy4uLgogICAgICAgIHBhc3MKCiAgICBAZGlzcGF0Y2gocmVucHkuYXN0LlRyYW5zbGF0ZVN0cmluZykKICAgIGRlZiBwcmludF90cmFuc2xhdGVzdHJpbmcoc2VsZiwgYXN0KToKICAgICAgICBzZWxmLnJlcXVpcmVfaW5pdCgpCiAgICAgICAgIyBXYXMgdGhlIGxhc3Qgbm9kZSBhIHRyYW5zbGF0ZXN0cmluZ3Mgbm9kZT8KICAgICAgICBpZiBub3Qoc2VsZi5pbmRleCBhbmQKICAgICAgICAgICAgICAgaXNpbnN0YW5jZShzZWxmLmJsb2NrW3NlbGYuaW5kZXggLSAxXSwgcmVucHkuYXN0LlRyYW5zbGF0ZVN0cmluZykgYW5kCiAgICAgICAgICAgICAgIHNlbGYuYmxvY2tbc2VsZi5pbmRleCAtIDFdLmxhbmd1YWdlID09IGFzdC5sYW5ndWFnZSk6CiAgICAgICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICAgICAgc2VsZi53cml0ZSgidHJhbnNsYXRlICVzIHN0cmluZ3M6IiAlIGFzdC5sYW5ndWFnZSBvciAiTm9uZSIpCgogICAgICAgICMgVHJhbnNsYXRlU3RyaW5nJ3MgbGluZW51bWJlciByZWZlcnMgdG8gdGhlIGxpbmUgd2l0aCAib2xkIiwgbm90IHRvIHRoZQogICAgICAgICMgbGluZSB3aXRoICJ0cmFuc2xhdGUgJXMgc3RyaW5nczoiCiAgICAgICAgd2l0aCBzZWxmLmluY3JlYXNlX2luZGVudCgpOgogICAgICAgICAgICBzZWxmLmFkdmFuY2VfdG9fbGluZShhc3QubGluZW51bWJlcikKICAgICAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgICAgICBzZWxmLndyaXRlKCdvbGQgIiVzIicgJSBzdHJpbmdfZXNjYXBlKGFzdC5vbGQpKQogICAgICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgICAgIHNlbGYud3JpdGUoJ25ldyAiJXMiJyAlIHN0cmluZ19lc2NhcGUoYXN0Lm5ldykpCgogICAgQGRpc3BhdGNoKHJlbnB5LmFzdC5UcmFuc2xhdGVCbG9jaykKICAgIEBkaXNwYXRjaChyZW5weS5hc3QuVHJhbnNsYXRlRWFybHlCbG9jaykKICAgIGRlZiBwcmludF90cmFuc2xhdGVibG9jayhzZWxmLCBhc3QpOgogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCJ0cmFuc2xhdGUgJXMgIiAlIChhc3QubGFuZ3VhZ2Ugb3IgIk5vbmUiKSkKCiAgICAgICAgc2VsZi5za2lwX2luZGVudF91bnRpbF93cml0ZSA9IFRydWUKCiAgICAgICAgaW5faW5pdCA9IHNlbGYuaW5faW5pdAogICAgICAgIGlmIGxlbihhc3QuYmxvY2spID09IDEgYW5kIGlzaW5zdGFuY2UoYXN0LmJsb2NrWzBdLCAocmVucHkuYXN0LlB5dGhvbiwgcmVucHkuYXN0LlN0eWxlKSk6CiAgICAgICAgICAgICMgUmVuJ1B5IGNvdW50cyB0aGUgVHJhbnNsYXRlQmxvY2sgZnJvbSAidHJhbnNsYXRlIHB5dGhvbiIgYW5kICJ0cmFuc2xhdGUgc3R5bGUiIGFzIGFuIEluaXQuCiAgICAgICAgICAgIHNlbGYuaW5faW5pdCA9IFRydWUKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNlbGYucHJpbnRfbm9kZXMoYXN0LmJsb2NrKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIHNlbGYuaW5faW5pdCA9IGluX2luaXQKCiAgICAjIFNjcmVlbnMKCiAgICBAZGlzcGF0Y2gocmVucHkuYXN0LlNjcmVlbikKICAgIGRlZiBwcmludF9zY3JlZW4oc2VsZiwgYXN0KToKICAgICAgICBzZWxmLnJlcXVpcmVfaW5pdCgpCiAgICAgICAgc2NyZWVuID0gYXN0LnNjcmVlbgogICAgICAgIGlmIGlzaW5zdGFuY2Uoc2NyZWVuLCByZW5weS5zY3JlZW5sYW5nLlNjcmVlbkxhbmdTY3JlZW4pOgogICAgICAgICAgICBzZWxmLmxpbmVudW1iZXIgPSBzY3JlZW5kZWNvbXBpbGVyLnBwcmludChzZWxmLm91dF9maWxlLCBzY3JlZW4sIHNlbGYuaW5kZW50X2xldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxpbmVudW1iZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZGVjb21waWxlX3B5dGhvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5za2lwX2luZGVudF91bnRpbF93cml0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5wcmludGxvY2spCiAgICAgICAgICAgIHNlbGYuc2tpcF9pbmRlbnRfdW50aWxfd3JpdGUgPSBGYWxzZQoKICAgICAgICBlbGlmIGlzaW5zdGFuY2Uoc2NyZWVuLCByZW5weS5zbDIuc2xhc3QuU0xTY3JlZW4pOgogICAgICAgICAgICBzZWxmLmxpbmVudW1iZXIgPSBzbDJkZWNvbXBpbGVyLnBwcmludChzZWxmLm91dF9maWxlLCBzY3JlZW4sIHNlbGYuaW5kZW50X2xldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmxpbmVudW1iZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc2tpcF9pbmRlbnRfdW50aWxfd3JpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYucHJpbnRsb2NrKQogICAgICAgICAgICBzZWxmLnNraXBfaW5kZW50X3VudGlsX3dyaXRlID0gRmFsc2UKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLnByaW50X3Vua25vd24oc2NyZWVuKQoKICAgICMgVGVzdGNhc2VzCgogICAgQGRpc3BhdGNoKHJlbnB5LmFzdC5UZXN0Y2FzZSkKICAgIGRlZiBwcmludF90ZXN0Y2FzZShzZWxmLCBhc3QpOgogICAgICAgIHNlbGYucmVxdWlyZV9pbml0KCkKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZSgndGVzdGNhc2UgJXM6JyAlIGFzdC5sYWJlbCkKICAgICAgICBzZWxmLmxpbmVudW1iZXIgPSB0ZXN0Y2FzZWRlY29tcGlsZXIucHByaW50KHNlbGYub3V0X2ZpbGUsIGFzdC50ZXN0LmJsb2NrLCBzZWxmLmluZGVudF9sZXZlbCArIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5saW5lbnVtYmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc2tpcF9pbmRlbnRfdW50aWxfd3JpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5wcmludGxvY2spCiAgICAgICAgc2VsZi5za2lwX2luZGVudF91bnRpbF93cml0ZSA9IEZhbHNlCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuL2RlY29tcGlsZXIvLl9hc3RkdW1wLnB5AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwNzU1IAAwMDA3NjcgADAwMDAyNCAAMDAwMDAwMDA1NzEgMTMyMTU1MjUwNjQgMDE1NTM0ACAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHVzdGFyADAwdGVkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABzdGFmZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMCAAMDAwMDAwIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFFgcAAgAATWFjIE9TIFggICAgICAgIAACAAAACQAAADIAAAFHAAAAAgAAAXkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEFUVFIAAAAAAAABeQAAALgAAADBAAAAAAAAAAAAAAAAAAAAAgAAALgAAACAAAATY29tLmFwcGxlLmFjbC50ZXh0AAAAAAABOAAAAEEAABVjb20uYXBwbGUucXVhcmFudGluZQAhI2FjbCAxCnVzZXI6RkZGRkVFRUUtRERERC1DQ0NDLUJCQkItQUFBQTAwMDAwMDU5Ol9zcG90bGlnaHQ6ODk6YWxsb3csaW5oZXJpdGVkOnJlYWQsZXhlY3V0ZSxyZWFkYXR0cixyZWFkZXh0YXR0cixyZWFkc2VjdXJpdHkKAHEvMDA4MTs1YTcxMjdiMTtGaXJlZm94LmFwcDtENTc0REM3Qy0wNzAzLTQ3RDAtODJGMS05MDBFNDg0NkY4RjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALi9kZWNvbXBpbGVyL2FzdGR1bXAucHkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDc1NSAAMDAwNzY3IAAwMDAwMjQgADAwMDAwMDI0MDAxIDEzMjE1NTI1MDY0IDAxNTMxMQAgMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1c3RhcgAwMHRlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc3RhZmYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAgADAwMDAwMCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjIENvcHlyaWdodCAoYykgMjAxMyBDZW5zb3JlZFVzZXJuYW1lCiMKIyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5CiMgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKIyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCiMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbAojIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwojIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiMKIyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgojIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgojCiMgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKIyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKIyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKIyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiMgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKIyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRQojIFNPRlRXQVJFLgoKZnJvbSBfX2Z1dHVyZV9fIGltcG9ydCB1bmljb2RlX2xpdGVyYWxzCgppbXBvcnQgc3lzCmltcG9ydCBpbnNwZWN0CmltcG9ydCBjb2RlZ2VuCmltcG9ydCBhc3QgYXMgcHlfYXN0CmltcG9ydCByZW5weQoKZGVmIHBwcmludChvdXRfZmlsZSwgYXN0LCBkZWNvbXBpbGVfcHl0aG9uPUZhbHNlLCBjb21wYXJhYmxlPUZhbHNlLCBub19weWV4cHI9RmFsc2UpOgogICAgIyBUaGUgbWFpbiBmdW5jdGlvbiBvZiB0aGlzIG1vZHVsZSwgYSB3cmFwcGVyIHdoaWNoIHNldHMKICAgICMgdGhlIGNvbmZpZyBhbmQgY3JlYXRlcyB0aGUgQXN0RHVtcGVyIGluc3RhbmNlCiAgICBBc3REdW1wZXIob3V0X2ZpbGUsIGRlY29tcGlsZV9weXRob249ZGVjb21waWxlX3B5dGhvbiwgY29tcGFyYWJsZT1jb21wYXJhYmxlLCBub19weWV4cHI9bm9fcHlleHByKS5kdW1wKGFzdCkKCmNsYXNzIEFzdER1bXBlcihvYmplY3QpOgogICAgIiIiCiAgICBBbiBvYmplY3Qgd2hpY2ggaGFuZGxlcyB0aGUgd2Fsa2luZyBvZiBhIHRyZWUgb2YgcHl0aG9uIG9iamVjdHMKICAgIGl0IHdpbGwgY3JlYXRlIGEgaHVtYW4tcmVhZGFibGUgcmVwcmVzZW50YXRpb24gb2YgYWxsIGludGVyZXN0aW5nCiAgICBhdHRyaWJ1dGVzIGFuZCB3cml0ZSB0aGlzIHRvIGEgZ2l2ZW4gc3RyZWFtCiAgICAiIiIKICAgIE1BUF9PUEVOID0ge2xpc3Q6ICdbJywgdHVwbGU6ICcoJywgc2V0OiAneycsIGZyb3plbnNldDogJ2Zyb3plbnNldCh7J30KICAgIE1BUF9DTE9TRSA9IHtsaXN0OiAnXScsIHR1cGxlOiAnKScsIHNldDogJ30nLCBmcm96ZW5zZXQ6ICd9KSd9CgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG91dF9maWxlPU5vbmUsIGRlY29tcGlsZV9weXRob249RmFsc2UsIG5vX3B5ZXhwcj1GYWxzZSwKICAgICAgICAgICAgICAgICBjb21wYXJhYmxlPUZhbHNlLCBpbmRlbnRhdGlvbj11JyAgICAnKToKICAgICAgICBzZWxmLmluZGVudGF0aW9uID0gaW5kZW50YXRpb24KICAgICAgICBzZWxmLm91dF9maWxlID0gb3V0X2ZpbGUgb3Igc3lzLnN0ZG91dAogICAgICAgIHNlbGYuZGVjb21waWxlX3B5dGhvbiA9IGRlY29tcGlsZV9weXRob24KICAgICAgICBzZWxmLmNvbXBhcmFibGUgPSBjb21wYXJhYmxlCiAgICAgICAgc2VsZi5ub19weWV4cHIgPSBub19weWV4cHIKCiAgICBkZWYgZHVtcChzZWxmLCBhc3QpOgogICAgICAgIHNlbGYuaW5kZW50ID0gMAogICAgICAgIHNlbGYucGFzc2VkID0gW10gIyBXZSdsbCBrZWVwIGEgc3RhY2sgb2Ygb2JqZWN0cyB3aGljaCB3ZSd2ZSB0cmF2ZXJzZWQgaGVyZSBzbyB3ZSBkb24ndCByZWN1cnNlIGVuZGxlc3NseSBvbiBjaXJjdWxhciByZWZlcmVuY2VzCiAgICAgICAgc2VsZi5wcmludF9hc3QoYXN0KQoKICAgIGRlZiBwcmludF9hc3Qoc2VsZiwgYXN0KToKICAgICAgICAjIERlY2lkZXMgd2hpY2ggZnVuY3Rpb24gc2hvdWxkIGJlIHVzZWQgdG8gcHJpbnQgdGhlIGdpdmVuIGFzdCBvYmplY3QuCiAgICAgICAgaWYgYXN0IGluIHNlbGYucGFzc2VkOgogICAgICAgICAgICBzZWxmLnByaW50X290aGVyKGFzdCkKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgc2VsZi5wYXNzZWQuYXBwZW5kKGFzdCkKICAgICAgICBpZiBpc2luc3RhbmNlKGFzdCwgKGxpc3QsIHR1cGxlLCBzZXQsIGZyb3plbnNldCkpOgogICAgICAgICAgICBzZWxmLnByaW50X2xpc3QoYXN0KQogICAgICAgIGVsaWYgaXNpbnN0YW5jZShhc3QsIHJlbnB5LmFzdC5QeUV4cHIpOgogICAgICAgICAgICBzZWxmLnByaW50X3B5ZXhwcihhc3QpCiAgICAgICAgZWxpZiBpc2luc3RhbmNlKGFzdCwgZGljdCk6CiAgICAgICAgICAgIHNlbGYucHJpbnRfZGljdChhc3QpCiAgICAgICAgZWxpZiBpc2luc3RhbmNlKGFzdCwgKHN0ciwgdW5pY29kZSkpOgogICAgICAgICAgICBzZWxmLnByaW50X3N0cmluZyhhc3QpCiAgICAgICAgZWxpZiBpc2luc3RhbmNlKGFzdCwgKGludCwgYm9vbCkpIG9yIGFzdCBpcyBOb25lOgogICAgICAgICAgICBzZWxmLnByaW50X290aGVyKGFzdCkKICAgICAgICBlbGlmIGluc3BlY3QuaXNjbGFzcyhhc3QpOgogICAgICAgICAgICBzZWxmLnByaW50X2NsYXNzKGFzdCkKICAgICAgICBlbGlmIGlzaW5zdGFuY2UoYXN0LCBvYmplY3QpOgogICAgICAgICAgICBzZWxmLnByaW50X29iamVjdChhc3QpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5wcmludF9vdGhlcihhc3QpCiAgICAgICAgc2VsZi5wYXNzZWQucG9wKCkKCiAgICBkZWYgcHJpbnRfbGlzdChzZWxmLCBhc3QpOgogICAgICAgICMgaGFuZGxlcyB0aGUgcHJpbnRpbmcgb2Ygc2ltcGxlIGNvbnRhaW5lcnMgb2YgTiBlbGVtZW50cy4KICAgICAgICBzZWxmLnAoc2VsZi5NQVBfT1BFTlthc3QuX19jbGFzc19fXSkKCiAgICAgICAgc2VsZi5pbmQoMSwgYXN0KQogICAgICAgIGZvciBpLCBvYmogaW4gZW51bWVyYXRlKGFzdCk6CiAgICAgICAgICAgIHNlbGYucHJpbnRfYXN0KG9iaikKICAgICAgICAgICAgaWYgaSsxICE9IGxlbihhc3QpOgogICAgICAgICAgICAgICAgc2VsZi5wKCcsJykKICAgICAgICAgICAgICAgIHNlbGYuaW5kKCkKICAgICAgICBzZWxmLmluZCgtMSwgYXN0KQogICAgICAgIHNlbGYucChzZWxmLk1BUF9DTE9TRVthc3QuX19jbGFzc19fXSkKCiAgICBkZWYgcHJpbnRfZGljdChzZWxmLCBhc3QpOgogICAgICAgICMgaGFuZGxlcyB0aGUgcHJpbnRpbmcgb2YgZGljdGlvbmFyaWVzCiAgICAgICAgc2VsZi5wKCd7JykKCiAgICAgICAgc2VsZi5pbmQoMSwgYXN0KQogICAgICAgIGZvciBpLCBrZXkgaW4gZW51bWVyYXRlKGFzdCk6CiAgICAgICAgICAgIHNlbGYucHJpbnRfYXN0KGtleSkKICAgICAgICAgICAgc2VsZi5wKCc6ICcpCiAgICAgICAgICAgIHNlbGYucHJpbnRfYXN0KGFzdFtrZXldKQogICAgICAgICAgICBpZiBpKzEgIT0gbGVuKGFzdCk6CiAgICAgICAgICAgICAgICBzZWxmLnAoJywnKQogICAgICAgICAgICAgICAgc2VsZi5pbmQoKQogICAgICAgIHNlbGYuaW5kKC0xLCBhc3QpCiAgICAgICAgc2VsZi5wKCd9JykKCiAgICBkZWYgc2hvdWxkX3ByaW50X2tleShzZWxmLCBhc3QsIGtleSk6CiAgICAgICAgaWYga2V5LnN0YXJ0c3dpdGgoJ18nKSBvciBub3QgaGFzYXR0cihhc3QsIGtleSkgb3IgaW5zcGVjdC5pc3JvdXRpbmUoZ2V0YXR0cihhc3QsIGtleSkpOgogICAgICAgICAgICByZXR1cm4gRmFsc2UKICAgICAgICBlbGlmIG5vdCBzZWxmLmNvbXBhcmFibGU6CiAgICAgICAgICAgIHJldHVybiBUcnVlCiAgICAgICAgZWxpZiBrZXkgPT0gJ3NlcmlhbCc6CiAgICAgICAgICAgIGFzdC5zZXJpYWwgPSAwCiAgICAgICAgZWxpZiBrZXkgPT0gJ2NvbF9vZmZzZXQnOgogICAgICAgICAgICBhc3QuY29sX29mZnNldCA9IDAgIyBUT0RPIG1heWJlIG1ha2UgdGhpcyBtYXRjaD8KICAgICAgICBlbGlmIGtleSA9PSAnbmFtZScgYW5kIHR5cGUoYXN0Lm5hbWUpID09IHR1cGxlOgogICAgICAgICAgICBuYW1lID0gYXN0Lm5hbWVbMF0KICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShuYW1lLCB1bmljb2RlKToKICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lLmVuY29kZSgndXRmLTgnKQogICAgICAgICAgICBhc3QubmFtZSA9IChuYW1lLnNwbGl0KGInLycpWy0xXSwgMCwgMCkKICAgICAgICBlbGlmIGtleSA9PSAnbG9jYXRpb24nIGFuZCB0eXBlKGFzdC5sb2NhdGlvbikgPT0gdHVwbGU6CiAgICAgICAgICAgIGlmIGxlbihhc3QubG9jYXRpb24pID09IDQ6CiAgICAgICAgICAgICAgICBhc3QubG9jYXRpb24gPSAoYXN0LmxvY2F0aW9uWzBdLnNwbGl0KCcvJylbLTFdLnNwbGl0KCdcXCcpWy0xXSwgYXN0LmxvY2F0aW9uWzFdLCBhc3QubG9jYXRpb25bMl0sIDApCiAgICAgICAgICAgIGVsaWYgbGVuKGFzdC5sb2NhdGlvbikgPT0gMzoKICAgICAgICAgICAgICAgIGFzdC5sb2NhdGlvbiA9IChhc3QubG9jYXRpb25bMF0uc3BsaXQoJy8nKVstMV0uc3BsaXQoJ1xcJylbLTFdLCBhc3QubG9jYXRpb25bMV0sIDApCiAgICAgICAgICAgIGVsaWYgbGVuKGFzdC5sb2NhdGlvbikgPT0gMjoKICAgICAgICAgICAgICAgIGFzdC5sb2NhdGlvbiA9IChhc3QubG9jYXRpb25bMF0uc3BsaXQoJy8nKVstMV0uc3BsaXQoJ1xcJylbLTFdLCBhc3QubG9jYXRpb25bMV0pCiAgICAgICAgZWxpZiBrZXkgPT0gJ2xvYycgYW5kIHR5cGUoYXN0LmxvYykgPT0gdHVwbGU6CiAgICAgICAgICAgIGFzdC5sb2MgPSAoYXN0LmxvY1swXS5zcGxpdCgnLycpWy0xXS5zcGxpdCgnXFwnKVstMV0sIGFzdC5sb2NbMV0pCiAgICAgICAgZWxpZiBrZXkgPT0gJ2ZpbGVuYW1lJzoKICAgICAgICAgICAgYXN0LmZpbGVuYW1lID0gYXN0LmZpbGVuYW1lLnNwbGl0KCcvJylbLTFdLnNwbGl0KCdcXCcpWy0xXQogICAgICAgIGVsaWYgKGtleSA9PSAncGFyYW1ldGVycycgYW5kIGFzdC5wYXJhbWV0ZXJzIGlzIE5vbmUgYW5kCiAgICAgICAgICAgIGlzaW5zdGFuY2UoYXN0LCByZW5weS5zY3JlZW5sYW5nLlNjcmVlbkxhbmdTY3JlZW4pKToKICAgICAgICAgICAgIyBXaGVuIG5vIHBhcmFtZXRlcnMgZXhpc3QsIHNvbWUgdmVyc2lvbnMgb2YgUmVuJ1B5IHNldCBwYXJhbWV0ZXJzCiAgICAgICAgICAgICMgdG8gTm9uZSBhbmQgc29tZSBkb24ndCBzZXQgaXQgYXQgYWxsLgogICAgICAgICAgICByZXR1cm4gRmFsc2UKICAgICAgICBlbGlmIChrZXkgPT0gJ2hpZGUnIGFuZCBhc3QuaGlkZSA9PSBGYWxzZSBhbmQKICAgICAgICAgICAgKGlzaW5zdGFuY2UoYXN0LCByZW5weS5hc3QuUHl0aG9uKSBvcgogICAgICAgICAgICBpc2luc3RhbmNlKGFzdCwgcmVucHkuYXN0LkxhYmVsKSkpOgogICAgICAgICAgICAjIFdoZW4gaGlkZSBpc24ndCBzZXQsIHNvbWUgdmVyc2lvbnMgb2YgUmVuJ1B5IHNldCBpdCB0byBGYWxzZSBhbmQKICAgICAgICAgICAgIyBzb21lIGRvbid0IHNldCBpdCBhdCBhbGwuCiAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgIGVsaWYgKGtleSA9PSAnYXR0cmlidXRlcycgYW5kIGFzdC5hdHRyaWJ1dGVzIGlzIE5vbmUgYW5kCiAgICAgICAgICAgIGlzaW5zdGFuY2UoYXN0LCByZW5weS5hc3QuU2F5KSk6CiAgICAgICAgICAgICMgV2hlbiBubyBhdHRyaWJ1dGVzIGFyZSBzZXQsIHNvbWUgdmVyc2lvbnMgb2YgUmVuJ1B5IHNldCBpdCB0byBOb25lCiAgICAgICAgICAgICMgYW5kIHNvbWUgZG9uJ3Qgc2V0IGl0IGF0IGFsbC4KICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgZWxpZiAoa2V5ID09ICdibG9jaycgYW5kIGFzdC5ibG9jayA9PSBbXSBhbmQKICAgICAgICAgICAgaXNpbnN0YW5jZShhc3QsIHJlbnB5LmFzdC5Vc2VyU3RhdGVtZW50KSk6CiAgICAgICAgICAgICMgV2hlbiB0aGVyZSdzIG5vIGJsb2NrLCBzb21lIHZlcnNpb25zIG9mIFJlbidQeSBzZXQgaXQgdG8gTm9uZQogICAgICAgICAgICAjIGFuZCBzb21lIGRvbid0IHNldCBpdCBhdCBhbGwuCiAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgIGVsaWYgKGtleSA9PSAnc3RvcmUnIGFuZCBhc3Quc3RvcmUgPT0gJ3N0b3JlJyBhbmQKICAgICAgICAgICAgaXNpbnN0YW5jZShhc3QsIHJlbnB5LmFzdC5QeXRob24pKToKICAgICAgICAgICAgIyBXaGVuIGEgc3RvcmUgaXNuJ3Qgc3BlY2lmaWVkLCBzb21lIHZlcnNpb25zIG9mIFJlbidQeSBzZXQgaXQgdG8KICAgICAgICAgICAgIyAic3RvcmUiIGFuZCBzb21lIGRvbid0IHNldCBpdCBhdCBhbGwuCiAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgIGVsaWYga2V5ID09ICd0cmFuc2xhdGFibGUnIGFuZCBpc2luc3RhbmNlKGFzdCwgcmVucHkuYXN0LlVzZXJTdGF0ZW1lbnQpOgogICAgICAgICAgICAjIE9sZCB2ZXJzaW9ucyBvZiBSZW4nUHkgZGlkbid0IGhhdmUgdGhpcyBhdHRyaWJ1dGUsIGFuZCBpdCdzIG5vdAogICAgICAgICAgICAjIGNvbnRyb2xsYWJsZSBmcm9tIHRoZSBzb3VyY2UuCiAgICAgICAgICAgIHJldHVybiBGYWxzZQogICAgICAgIGVsaWYga2V5ID09ICdob3RzcG90JyBhbmQgaXNpbnN0YW5jZShhc3QsIHJlbnB5LnNsMi5zbGFzdC5TTERpc3BsYXlhYmxlKToKICAgICAgICAgICAgIyBPbGQgdmVyc2lvbnMgb2YgUmVuJ1B5IGRpZG4ndCBoYXZlIHRoaXMgYXR0cmlidXRlLCBhbmQgaXQncyBub3QKICAgICAgICAgICAgIyBjb250cm9sbGFibGUgZnJvbSB0aGUgc291cmNlLgogICAgICAgICAgICByZXR1cm4gRmFsc2UKICAgICAgICByZXR1cm4gVHJ1ZQoKICAgIGRlZiBwcmludF9vYmplY3Qoc2VsZiwgYXN0KToKICAgICAgICAjIGhhbmRsZXMgdGhlIHByaW50aW5nIG9mIGFueXRoaW5nIHVua25vd24gd2hpY2ggaW5oZXJ0cyBmcm9tIG9iamVjdC4KICAgICAgICAjIHByaW50cyB0aGUgdmFsdWVzIG9mIHJlbGV2YW50IGF0dHJpYnV0ZXMgaW4gYSBkaWN0aW9uYXJ5LWxpa2Ugd2F5CiAgICAgICAgIyBpdCB3aWxsIG5vdCBwcmludCBhbnl0aGluZyB3aGljaCBpcyBhIGJvdW5kIG1ldGhvZCBvciBzdGFydHMgd2l0aCBhIF8KICAgICAgICBzZWxmLnAoJzwnKQogICAgICAgIHNlbGYucChzdHIoYXN0Ll9fY2xhc3NfXylbODotMl0gaWYgaGFzYXR0cihhc3QsICdfX2NsYXNzX18nKSAgZWxzZSBzdHIoYXN0KSkKCiAgICAgICAgaWYgaXNpbnN0YW5jZShhc3QsIHB5X2FzdC5Nb2R1bGUpIGFuZCBzZWxmLmRlY29tcGlsZV9weXRob246CiAgICAgICAgICAgIHNlbGYucCgnLmNvZGUgPSAnKQogICAgICAgICAgICBzZWxmLnByaW50X2FzdChjb2RlZ2VuLnRvX3NvdXJjZShhc3QsIHVuaWNvZGUoc2VsZi5pbmRlbnRhdGlvbikpKQogICAgICAgICAgICBzZWxmLnAoJz4nKQogICAgICAgICAgICByZXR1cm4KCiAgICAgICAga2V5cyA9IGxpc3QoaSBmb3IgaSBpbiBkaXIoYXN0KSBpZiBzZWxmLnNob3VsZF9wcmludF9rZXkoYXN0LCBpKSkKICAgICAgICBpZiBrZXlzOgogICAgICAgICAgICBzZWxmLnAoJyAnKQogICAgICAgIHNlbGYuaW5kKDEsIGtleXMpCiAgICAgICAgZm9yIGksIGtleSBpbiBlbnVtZXJhdGUoa2V5cyk6CiAgICAgICAgICAgIHNlbGYucCgnLicpCiAgICAgICAgICAgIHNlbGYucChzdHIoa2V5KSkKICAgICAgICAgICAgc2VsZi5wKCcgPSAnKQogICAgICAgICAgICBzZWxmLnByaW50X2FzdChnZXRhdHRyKGFzdCwga2V5KSkKICAgICAgICAgICAgaWYgaSsxICE9IGxlbihrZXlzKToKICAgICAgICAgICAgICAgIHNlbGYucCgnLCcpCiAgICAgICAgICAgICAgICBzZWxmLmluZCgpCiAgICAgICAgc2VsZi5pbmQoLTEsIGtleXMpCiAgICAgICAgc2VsZi5wKCc+JykKCiAgICBkZWYgcHJpbnRfcHlleHByKHNlbGYsIGFzdCk6CiAgICAgICAgaWYgbm90IHNlbGYubm9fcHlleHByOgogICAgICAgICAgICBzZWxmLnByaW50X29iamVjdChhc3QpCiAgICAgICAgICAgIHNlbGYucCgnID0gJykKICAgICAgICBzZWxmLnByaW50X3N0cmluZyhhc3QpCgogICAgZGVmIHByaW50X2NsYXNzKHNlbGYsIGFzdCk6CiAgICAgICAgIyBoYW5kbGVzIHRoZSBwcmludGluZyBvZiBjbGFzc2VzCiAgICAgICAgc2VsZi5wKCc8Y2xhc3MgJykKICAgICAgICBzZWxmLnAoc3RyKGFzdClbODotMl0pCiAgICAgICAgc2VsZi5wKCc+JykKCiAgICBkZWYgcHJpbnRfc3RyaW5nKHNlbGYsIGFzdCk6CiAgICAgICAgIyBwcmludHMgdGhlIHJlcHJlc2VudGF0aW9uIG9mIGEgc3RyaW5nLiBJZiB0aGVyZSBhcmUgbmV3bGluZXMgaW4gdGhpcyBzdHJpbmcsCiAgICAgICAgIyBpdCB3aWxsIHByaW50IGl0IGFzIGEgZG9jc3RyaW5nLgogICAgICAgIGlmIGInXG4nIGluIGFzdDoKICAgICAgICAgICAgYXN0bGlzdCA9IGFzdC5zcGxpdChiJ1xuJykKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShhc3QsIHVuaWNvZGUpOgogICAgICAgICAgICAgICAgc2VsZi5wKCd1JykKICAgICAgICAgICAgc2VsZi5wKCciIiInKQogICAgICAgICAgICBzZWxmLnAoc2VsZi5lc2NhcGVfc3RyaW5nKGFzdGxpc3QucG9wKDApKSkKICAgICAgICAgICAgZm9yIGksIGl0ZW0gaW4gZW51bWVyYXRlKGFzdGxpc3QpOgogICAgICAgICAgICAgICAgc2VsZi5wKCdcbicpCiAgICAgICAgICAgICAgICBzZWxmLnAoc2VsZi5lc2NhcGVfc3RyaW5nKGl0ZW0pKQogICAgICAgICAgICBzZWxmLnAoJyIiIicpCiAgICAgICAgICAgIHNlbGYuaW5kKCkKCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5wKHJlcHIoYXN0KSkKCiAgICBkZWYgZXNjYXBlX3N0cmluZyhzZWxmLCBzdHJpbmcpOgogICAgICAgICMgZXNzZW50aWFsbHkgdGhlIHJlcHJlc2VudGF0aW9uIG9mIGEgc3RyaW5nIHdpdGhvdXQgdGhlIHN1cnJvdW5kaW5nIHF1b3RlcwogICAgICAgIGlmIGlzaW5zdGFuY2Uoc3RyaW5nLCB1bmljb2RlKToKICAgICAgICAgICAgcmV0dXJuIHJlcHIoc3RyaW5nKVsyOi0xXQogICAgICAgIGVsaWYgaXNpbnN0YW5jZShzdHJpbmcsIHN0cik6CiAgICAgICAgICAgIHJldHVybiByZXByKHN0cmluZylbMTotMV0KICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gc3RyaW5nCgogICAgZGVmIHByaW50X290aGVyKHNlbGYsIGFzdCk6CiAgICAgICAgIyB1c2VkIGFzIGEgbGFzdCBmYWxsYmFjayBhbmQgdG8gcHJpbnQgdGhpbmdzIHdoZW4gYSByZWN1cnNpdmUgbG9va3VwIGlzIGRldGVjdGVkCiAgICAgICAgc2VsZi5wKHJlcHIoYXN0KSkKCiAgICBkZWYgaW5kKHNlbGYsIGRpZmZfaW5kZW50PTAsIGFzdD1Ob25lKToKICAgICAgICAjIHByaW50IGEgbmV3bGluZSBhbmQgaW5kZW50LiBkaWZmX2luZGVudCByZXByZXNlbnRzIHRoZSBkaWZmZXJlbmNlIGluIGluZGVudGF0aW9uCiAgICAgICAgIyBjb21wYXJlZCB0byB0aGUgbGFzdCBsaW5lLiBpdCB3aWxsIGNoZWNoIHRoZSBsZW5ndGggb2YgYXN0IHRvIGRldGVybWluZSBpZiBpdAogICAgICAgICMgc2hvdWxkbid0IGluZGVudCBpbiBjYXNlIHRoZXJlJ3Mgb25seSBvbmUgb3IgemVybyBvYmplY3RzIGluIHRoaXMgb2JqZWN0IHRvIHByaW50CiAgICAgICAgaWYgYXN0IGlzIE5vbmUgb3IgbGVuKGFzdCkgPiAxOgogICAgICAgICAgICBzZWxmLmluZGVudCArPSBkaWZmX2luZGVudAogICAgICAgICAgICBzZWxmLnAodSdcbicgKyBzZWxmLmluZGVu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IG1hdGVyaWFscwojICAgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgojIC0gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgPE9SR0FOSVpBVElPTj4gbm9yIHRoZSBuYW1lcyBvZiBpdHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvCiMgICBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCAgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbgojICAgcGVybWlzc2lvbi4KCiMgVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUgojIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORAojIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgojIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKIyBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCiMgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIKIyBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GCiMgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgoKIyBUYWtlbiBmcm9tIGh0dHA6Ly9naXRodWIuY29tL2pvbmF0aGFuZXVuaWNlL2NvZGVnZW4KCiIiIgogICAgY29kZWdlbgogICAgfn5+fn5+fgoKICAgIEV4dGVuc2lvbiB0byBhc3QgdGhhdCBhbGxvdyBhc3QgLT4gcHl0aG9uIGNvZGUgZ2VuZXJhdGlvbi4KCiAgICA6Y29weXJpZ2h0OiBDb3B5cmlnaHQgMjAwOCBieSBBcm1pbiBSb25hY2hlci4KICAgIDpsaWNlbnNlOiBCU0QuCiIiIgoKaW1wb3J0IHN5cwpQWTMgPSBzeXMudmVyc2lvbl9pbmZvID49ICgzLCAwKQojIFRoZXNlIG1pZ2h0IG5vdCBleGlzdCwgc28gd2UgcHV0IHRoZW0gZXF1YWwgdG8gTm9uZVR5cGUKVHJ5ID0gVHJ5RXhjZXB0ID0gVHJ5RmluYWxseSA9IFlpZWxkRnJvbSA9IE1hdE11bHQgPSBBd2FpdCA9IHR5cGUoTm9uZSkKCmZyb20gYXN0IGltcG9ydCAqCgpjbGFzcyBTZXAob2JqZWN0KToKICAgICMgUGVyZm9ybXMgdGhlIGNvbW1vbiBwYXR0ZXJuIG9mIHJldHVybmluZyBhIGRpZmZlcmVudCBzeW1ib2wgdGhlIGZpcnN0CiAgICAjIHRpbWUgdGhlIG9iamVjdCBpcyBjYWxsZWQKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBsYXN0LCBmaXJzdD0nJyk6CiAgICAgICAgc2VsZi5sYXN0ID0gbGFzdAogICAgICAgIHNlbGYuZmlyc3QgPSBmaXJzdAogICAgICAgIHNlbGYuYmVnaW4gPSBUcnVlCiAgICBkZWYgX19jYWxsX18oc2VsZik6CiAgICAgICAgaWYgc2VsZi5iZWdpbjoKICAgICAgICAgICAgc2VsZi5iZWdpbiA9IEZhbHNlCiAgICAgICAgICAgIHJldHVybiBzZWxmLmZpcnN0CiAgICAgICAgcmV0dXJuIHNlbGYubGFzdAoKZGVmIHRvX3NvdXJjZShub2RlLCBpbmRlbnRfd2l0aD0nICcgKiA0LCBhZGRfbGluZV9pbmZvcm1hdGlvbj1GYWxzZSwgY29ycmVjdF9saW5lX251bWJlcnM9RmFsc2UpOgogICAgIiIiVGhpcyBmdW5jdGlvbiBjYW4gY29udmVydCBhIG5vZGUgdHJlZSBiYWNrIGludG8gcHl0aG9uIHNvdXJjZWNvZGUuCiAgICBUaGlzIGlzIHVzZWZ1bCBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLCBlc3BlY2lhbGx5IGlmIHlvdSdyZSBkZWFsaW5nIHdpdGgKICAgIGN1c3RvbSBhc3RzIG5vdCBnZW5lcmF0ZWQgYnkgcHl0aG9uIGl0c2VsZi4KCiAgICBJdCBjb3VsZCBiZSB0aGF0IHRoZSBzb3VyY2Vjb2RlIGlzIGV2YWx1YWJsZSB3aGVuIHRoZSBBU1QgaXRzZWxmIGlzIG5vdAogICAgY29tcGlsYWJsZSAvIGV2YWx1YWJsZS4gIFRoZSByZWFzb24gZm9yIHRoaXMgaXMgdGhhdCB0aGUgQVNUIGNvbnRhaW5zIHNvbWUKICAgIG1vcmUgZGF0YSB0aGFuIHJlZ3VsYXIgc291cmNlY29kZSBkb2VzLCB3aGljaCBpcyBkcm9wcGVkIGR1cmluZwogICAgY29udmVyc2lvbi4KCiAgICBFYWNoIGxldmVsIG9mIGluZGVudGF0aW9uIGlzIHJlcGxhY2VkIHdpdGggYGluZGVudF93aXRoYC4gIFBlciBkZWZhdWx0IHRoaXMKICAgIHBhcmFtZXRlciBpcyBlcXVhbCB0byBmb3VyIHNwYWNlcyBhcyBzdWdnZXN0ZWQgYnkgUEVQIDgsIGJ1dCBpdCBtaWdodCBiZQogICAgYWRqdXN0ZWQgdG8gbWF0Y2ggdGhlIGFwcGxpY2F0aW9uJ3Mgc3R5bGVndWlkZS4KCiAgICBJZiBgYWRkX2xpbmVfaW5mb3JtYXRpb25gIGlzIHNldCB0byBgVHJ1ZWAgY29tbWVudHMgZm9yIHRoZSBsaW5lIG51bWJlcnMKICAgIG9mIHRoZSBub2RlcyBhcmUgYWRkZWQgdG8gdGhlIG91dHB1dC4gIFRoaXMgY2FuIGJlIHVzZWQgdG8gc3BvdCB3cm9uZyBsaW5lCiAgICBudW1iZXIgaW5mb3JtYXRpb24gb2Ygc3RhdGVtZW50IG5vZGVzLgogICAgIiIiCiAgICBpZiBjb3JyZWN0X2xpbmVfbnVtYmVyczoKICAgICAgICBpZiBoYXNhdHRyKG5vZGUsICdsaW5lbm8nKToKICAgICAgICAgICAgcmV0dXJuIFNvdXJjZUdlbmVyYXRvcihpbmRlbnRfd2l0aCwgYWRkX2xpbmVfaW5mb3JtYXRpb24sIFRydWUsIG5vZGUubGluZW5vKS5wcm9jZXNzKG5vZGUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIFNvdXJjZUdlbmVyYXRvcihpbmRlbnRfd2l0aCwgYWRkX2xpbmVfaW5mb3JtYXRpb24sIFRydWUpLnByb2Nlc3Mobm9kZSkKICAgIGVsc2U6CiAgICAgICAgcmV0dXJuIFNvdXJjZUdlbmVyYXRvcihpbmRlbnRfd2l0aCwgYWRkX2xpbmVfaW5mb3JtYXRpb24pLnByb2Nlc3Mobm9kZSkKCgpjbGFzcyBTb3VyY2VHZW5lcmF0b3IoTm9kZVZpc2l0b3IpOgogICAgIiIiVGhpcyB2aXNpdG9yIGlzIGFibGUgdG8gdHJhbnNmb3JtIGEgd2VsbCBmb3JtZWQgc3ludGF4IHRyZWUgaW50byBweXRob24KICAgIHNvdXJjZWNvZGUuICBGb3IgbW9yZSBkZXRhaWxzIGhhdmUgYSBsb29rIGF0IHRoZSBkb2NzdHJpbmcgb2YgdGhlCiAgICBgbm9kZV90b19zb3VyY2VgIGZ1bmN0aW9uLgogICAgIiIiCgogICAgQ09NTUEgPSAnLCAnCiAgICBDT0xPTiA9ICc6ICcKICAgIEFTU0lHTiA9ICcgPSAnCiAgICBTRU1JQ09MT04gPSAnOyAnCiAgICBBUlJPVyA9ICcgLT4gJwoKICAgIEJPT0xPUF9TWU1CT0xTID0gewogICAgICAgIEFuZDogICAgICAgICgnIGFuZCAnLCA1KSwKICAgICAgICBPcjogICAgICAgICAoJyBvciAnLCAgNCkKICAgIH0KCiAgICBCSU5PUF9TWU1CT0xTID0gewogICAgICAgIEFkZDogICAgICAgICgnICsgJywgIDEyKSwKICAgICAgICBTdWI6ICAgICAgICAoJyAtICcsICAxMiksCiAgICAgICAgTXVsdDogICAgICAgKCcgKiAnLCAgMTMpLAogICAgICAgIE1hdE11bHQ6ICAgICgnIEAgJywgIDEzKSwKICAgICAgICBEaXY6ICAgICAgICAoJyAvICcsICAxMyksCiAgICAgICAgRmxvb3JEaXY6ICAgKCcgLy8gJywgMTMpLAogICAgICAgIE1vZDogICAgICAgICgnICUgJywgIDEzKSwKICAgICAgICBQb3c6ICAgICAgICAoJyAqKiAnLCAxNSksCiAgICAgICAgTFNoaWZ0OiAgICAgKCcgPDwgJywgMTEpLAogICAgICAgIFJTaGlmdDogICAgICgnID4+ICcsIDExKSwKICAgICAgICBCaXRPcjogICAgICAoJyB8ICcsICA4KSwKICAgICAgICBCaXRBbmQ6ICAgICAoJyAmICcsICAxMCksCiAgICAgICAgQml0WG9yOiAgICAgKCcgXiAnLCAgOSkKICAgIH0KCiAgICBDTVBPUF9TWU1CT0xTID0gewogICAgICAgIEVxOiAgICAgICAgICgnID09ICcsICAgICA3KSwKICAgICAgICBHdDogICAgICAgICAoJyA+ICcsICAgICAgNyksCiAgICAgICAgR3RFOiAgICAgICAgKCcgPj0gJywgICAgIDcpLAogICAgICAgIEluOiAgICAgICAgICgnIGluICcsICAgICA3KSwKICAgICAgICBJczogICAgICAgICAoJyBpcyAnLCAgICAgNyksCiAgICAgICAgSXNOb3Q6ICAgICAgKCcgaXMgbm90ICcsIDcpLAogICAgICAgIEx0OiAgICAgICAgICgnIDwgJywgICAgICA3KSwKICAgICAgICBMdEU6ICAgICAgICAoJyA8PSAnLCAgICAgNyksCiAgICAgICAgTm90RXE6ICAgICAgKCcgIT0gJywgICAgIDcpLAogICAgICAgIE5vdEluOiAgICAgICgnIG5vdCBpbiAnLCA3KQogICAgfQoKICAgIFVOQVJZT1BfU1lNQk9MUyA9IHsKICAgICAgICBJbnZlcnQ6ICAgICAoJ34nLCAgICAxNCksCiAgICAgICAgTm90OiAgICAgICAgKCdub3QgJywgNiksCiAgICAgICAgVUFkZDogICAgICAgKCcrJywgICAgMTQpLAogICAgICAgIFVTdWI6ICAgICAgICgnLScsICAgIDE0KQogICAgfQoKICAgIEJMT0NLX05PREVTID0gKElmLCBGb3IsIFdoaWxlLCBXaXRoLCBUcnksIFRyeUV4Y2VwdCwgVHJ5RmluYWxseSwKICAgICAgICAgICAgICAgICAgIEZ1bmN0aW9uRGVmLCBDbGFzc0RlZikKCiAgICBkZWYgX19pbml0X18oc2VsZiwgaW5kZW50X3dpdGgsIGFkZF9saW5lX2luZm9ybWF0aW9uPUZhbHNlLCBjb3JyZWN0X2xpbmVfbnVtYmVycz1GYWxzZSwgbGluZV9udW1iZXI9MSk6CiAgICAgICAgc2VsZi5yZXN1bHQgPSBbXQogICAgICAgIHNlbGYuaW5kZW50X3dpdGggPSBpbmRlbnRfd2l0aAogICAgICAgIHNlbGYuYWRkX2xpbmVfaW5mb3JtYXRpb24gPSBhZGRfbGluZV9pbmZvcm1hdGlvbgogICAgICAgIHNlbGYuaW5kZW50YXRpb24gPSAwCiAgICAgICAgc2VsZi5uZXdfbGluZXMgPSAwCgogICAgICAgICMgcHJlY2VkZW5jZV9zdGFjazogd2hhdCBwcmVjZWRlbmNlIGxldmVsIGFyZSB3ZSBvbiwgY291bGQgd2Ugc2FmZWx5IG5ld2xpbmUgYmVmb3JlIGFuZCBpcyB0aGlzIG9wZXJhdG9yIGxlZnQtdG8tcmlnaHQKICAgICAgICBzZWxmLnByZWNlZGVuY2Vfc3RhY2sgPSBbWzAsIEZhbHNlLCBOb25lXV0KCiAgICAgICAgc2VsZi5jb3JyZWN0X2xpbmVfbnVtYmVycyA9IGNvcnJlY3RfbGluZV9udW1iZXJzCiAgICAgICAgIyBUaGUgY3VycmVudCBsaW5lIG51bWJlciB3ZSAqdGhpbmsqIHdlIGFyZSBvbi4gQXMgaW4gaXQncyBtb3N0IGxpa2VseQogICAgICAgICMgdGhlIGxpbmUgbnVtYmVyIG9mIHRoZSBsYXN0IG5vZGUgd2UgcGFzc2VkIHdoaWNoIGNhbiBkaWZmZXIgd2hlbgogICAgICAgICMgdGhlIGFzdCBpcyBicm9rZW4KICAgICAgICBzZWxmLmxpbmVfbnVtYmVyID0gbGluZV9udW1iZXIKICAgICAgICAjIENhbiB3ZSBpbnNlcnQgYSBuZXdsaW5lIGhlcmUgd2l0aG91dCBoYXZpbmcgdG8gZXNjYXBlIGl0PwogICAgICAgICMgKGFyZSB3ZSBiZXR3ZWVuIGRlbGltaXRpbmcgY2hhcmFjdGVycykKICAgICAgICBzZWxmLmNhbl9uZXdsaW5lID0gRmFsc2UKICAgICAgICAjIGFmdGVyIGEgY29sb24sIHdlIGRvbid0IGhhdmUgdG8gcHJpbnQgYSBzZW1pIGNvbG9uLiBzZXQgdG8gMSB3aGVuIHNlbGYuYm9keSgpIGlzIGNhbGxlZCwKICAgICAgICAjIHNldCB0byAyIG9yIDAgd2hlbiBpdCdzIGFjdHVhbGx5IHVzZWQuIHNldCB0byAwIGF0IHRoZSBlbmQgb2YgdGhlIGJvZHkKICAgICAgICBzZWxmLmFmdGVyX2NvbG9uID0gMAogICAgICAgICMgcmVzZXQgYnkgYSBjYWxsIHRvIHNlbGYubmV3bGluZSwgc2V0IGJ5IHRoZSBmaXJzdCBjYWxsIHRvIHdyaXRlKCkgYWZ0ZXJ3YXJkcwogICAgICAgICMgZGV0ZXJtaW5lcyBpZiB3ZSBoYXZlIHRvIHByaW50IHRoZSBuZXdsaW5lcyBhbmQgaW5kZW50CiAgICAgICAgc2VsZi5pbmRlbnRlZCA9IEZhbHNlCiAgICAgICAgIyB0aGUgYW1vdW50IG9mIG5ld2xpbmVzIHRvIGJlIHByaW50ZWQKICAgICAgICBzZWxmLm5ld2xpbmVzID0gMAogICAgICAgICMgZm9yY2UgdGhlIHByaW50aW5nIG9mIGEgcHJvcGVyIG5ld2xpbmUgKGFuZCBub3QgYSBzZW1pY29sb24pCiAgICAgICAgc2VsZi5mb3JjZV9uZXdsaW5lID0gRmFsc2UKCiAgICBkZWYgcHJvY2VzcyhzZWxmLCBub2RlKToKICAgICAgICBzZWxmLnZpc2l0KG5vZGUpCiAgICAgICAgcmVzdWx0ID0gJycuam9pbihzZWxmLnJlc3VsdCkKICAgICAgICBzZWxmLnJlc3VsdCA9IFtdCiAgICAgICAgcmV0dXJuIHJlc3VsdAoKICAgICMgUHJlY2VkZW5jZSBtYW5hZ2VtZW50CgogICAgZGVmIHByZWNfc3RhcnQoc2VsZiwgdmFsdWUsIGx0cj1Ob25lKToKICAgICAgICBuZXdsaW5lID0gc2VsZi5jYW5fbmV3bGluZQogICAgICAgIGlmIHZhbHVlIDwgc2VsZi5wcmVjZWRlbmNlX3N0YWNrWy0xXVswXToKICAgICAgICAgICAgc2VsZi53cml0ZSgnKCcpCiAgICAgICAgICAgIHNlbGYuY2FuX25ld2xpbmUgPSBUcnVlCiAgICAgICAgaWYgbHRyID09IEZhbHNlOgogICAgICAgICAgICB2YWx1ZSArPSAxCiAgICAgICAgc2VsZi5wcmVjZWRlbmNlX3N0YWNrLmFwcGVuZChbdmFsdWUsIG5ld2xpbmUsIGx0cl0pCgogICAgZGVmIHByZWNfbWlkZGxlKHNlbGYsIGxldmVsPU5vbmUpOgogICAgICAgIGlmIGxldmVsIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLnByZWNlZGVuY2Vfc3RhY2tbLTFdWzBdID0gbGV2ZWwKICAgICAgICBlbGlmIHNlbGYucHJlY2VkZW5jZV9zdGFja1stMV1bMl06CiAgICAgICAgICAgIHNlbGYucHJlY2VkZW5jZV9zdGFja1stMV1bMF0gKz0gMQogICAgICAgIGVsaWYgc2VsZi5wcmVjZWRlbmNlX3N0YWNrWy0xXVsyXSBpcyBGYWxzZToKICAgICAgICAgICAgc2VsZi5wcmVjZWRlbmNlX3N0YWNrWy0xXVswXSAtPSAxCgogICAgZGVmIHByZWNfZW5kKHNlbGYpOgogICAgICAgIHByZWNlZGVuY2UsIG5ld2xpbmUsIGx0ciA9IHNlbGYucHJlY2VkZW5jZV9zdGFjay5wb3AoKQogICAgICAgIGlmIGx0cjoKICAgICAgICAgICAgcHJlY2VkZW5jZSAtPSAxCiAgICAgICAgaWYgcHJlY2VkZW5jZSA8IHNlbGYucHJlY2VkZW5jZV9zdGFja1stMV1bMF06CiAgICAgICAgICAgIHNlbGYud3JpdGUoJyknKQogICAgICAgICAgICBzZWxmLmNhbl9uZXdsaW5lID0gbmV3bGluZQoKICAgIGRlZiBwYXJlbl9zdGFydChzZWxmLCBzeW1ib2w9JygnKToKICAgICAgICBzZWxmLnByZWNlZGVuY2Vfc3RhY2suYXBwZW5kKFswLCBzZWxmLmNhbl9uZXdsaW5lLCBOb25lXSkKICAgICAgICBzZWxmLndyaXRlKHN5bWJvbCkKICAgICAgICBzZWxmLmNhbl9uZXdsaW5lID0gVHJ1ZQoKICAgIGRlZiBwYXJlbl9lbmQoc2VsZiwgc3ltYm9sPScpJyk6CiAgICAgICAgXywgc2VsZi5jYW5fbmV3bGluZSwgXyA9IHNlbGYucHJlY2VkZW5jZV9zdGFjay5wb3AoKQogICAgICAgIHNlbGYud3JpdGUoc3ltYm9sKQoKICAgICMgY29udmVuaWVuY2UgZnVuY3Rpb25zCgogICAgZGVmIHdyaXRlKHNlbGYsIHgpOgogICAgICAgICMgaWdub3JlIGVtcHR5IHdyaXRlcwogICAgICAgIGlmIG5vdCB4OgogICAgICAgICAgICByZXR1cm4KCiAgICAgICAgIyBCZWZvcmUgd2Ugd3JpdGUsIHdlIG11c3QgY2hlY2sgaWYgbmV3bGluZXMgaGF2ZSBiZWVuIHF1ZXVlZC4KICAgICAgICAjIElmIHRoaXMgaXMgdGhlIGNhc2UsIHdlIGhhdmUgdG8gaGFuZGxlIHRoZW0gcHJvcGVybHkKICAgICAgICBpZiBzZWxmLmNvcnJlY3RfbGluZV9udW1iZXJzOgogICAgICAgICAgICBpZiBub3Qgc2VsZi5pbmRlbnRlZDoKICAgICAgICAgICAgICAgIHNlbGYubmV3X2xpbmVzID0gbWF4KHNlbGYubmV3X2xpbmVzLCAxIGlmIHNlbGYuZm9yY2VfbmV3bGluZSBlbHNlIDApCiAgICAgICAgICAgICAgICBzZWxmLmZvcmNlX25ld2xpbmUgPSBGYWxzZQoKICAgICAgICAgICAgICAgIGlmIHNlbGYubmV3X2xpbmVzOgogICAgICAgICAgICAgICAgICAgICMgd2UgaGF2ZSBuZXcgbGluZXMgdG8gcHJpbnQKICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLmFmdGVyX2NvbG9uID09IDI6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYucmVzdWx0LmFwcGVuZCgnOycrJ1xcXG4nICogc2VsZi5uZXdfbGluZXMpCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5hZnRlcl9jb2xvbiA9IDAKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5yZXN1bHQuYXBwZW5kKCdcbicgKiBzZWxmLm5ld19saW5lcykKICAgICAgICAgICAgICAgICAgICBzZWxmLnJlc3VsdC5hcHBlbmQoc2VsZi5pbmRlbnRfd2l0aCAqIHNlbGYuaW5kZW50YXRpb24pCiAgICAgICAgICAgICAgICBlbGlmIHNlbGYuYWZ0ZXJfY29sb24gPT0gMToKICAgICAgICAgICAgICAgICAgICAjIHdlJ3JlIGRpcmVjdGx5IGFmdGVyIGEgYmxvY2staGF2aW5nIHN0YXRlbWVudCBhbmQgY2FuIHdyaXRlIG9uIHRoZSBzYW1lIGxpbmUKICAgICAgICAgICAgICAgICAgICBzZWxmLmFmdGVyX2NvbG9uID0gMgogICAgICAgICAgICAgICAgICAgIHNlbGYucmVzdWx0LmFwcGVuZCgnICcpCiAgICAgICAgICAgICAgICBlbGlmIHNlbGYucmVzdWx0OgogICAgICAgICAgICAgICAgICAgICMgd2UncmUgYWZ0ZXIgYW55IHN0YXRlbWVudC4gb3IgYXQgdGhlIHN0YXJ0IG9mIHRoZSBmaWxlCiAgICAgICAgICAgICAgICAgICAgc2VsZi5yZXN1bHQuYXBwZW5kKHNlbGYuU0VNSUNPTE9OKQogICAgICAgICAgICAgICAgc2VsZi5pbmRlbnRlZCA9IFRydWUKICAgICAgICAgICAgZWxpZiBzZWxmLm5ld19saW5lcyA+IDA6CiAgICAgICAgICAgICAgICBpZiBzZWxmLmNhbl9uZXdsaW5lOgogICAgICAgICAgICAgICAgICAgIHNlbGYucmVzdWx0LmFwcGVuZCgnXG4nICogc2VsZi5uZXdfbGluZXMpCiAgICAgICAgICAgICAgICAgICAgc2VsZi5yZXN1bHQuYXBwZW5kKHNlbGYuaW5kZW50X3dpdGggKiAoc2VsZi5pbmRlbnRhdGlvbiArIDEpKQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLnJlc3VsdC5hcHBlbmQoJ1xcXG4nICogc2VsZi5uZXdfbGluZXMpCiAgICAgICAgICAgICAgICAgICAgc2VsZi5yZXN1bHQuYXBwZW5kKHNlbGYuaW5kZW50X3dpdGggKiAoc2VsZi5pbmRlbnRhdGlvbiArIDEpKQogICAgICAgICAgICBzZWxmLm5ld19saW5lcyA9IDAKCgogICAgICAgIGVsaWYgc2VsZi5uZXdfbGluZXM6CiAgICAgICAgICAgICMgbm9ybWFsIGJlaGF2aW91cgogICAgICAgICAgICBzZWxmLnJlc3VsdC5hcHBlbmQoJ1xuJyAqIHNlbGYubmV3X2xpbmVzKQogICAgICAgICAgICBzZWxmLnJlc3VsdC5hcHBlbmQoc2VsZi5pbmRlbnRfd2l0aCAqIHNlbGYuaW5kZW50YXRpb24pCiAgICAgICAgICAgIHNlbGYubmV3X2xpbmVzID0gMAogICAgICAgIHNlbGYucmVzdWx0LmFwcGVuZCh4KQoKICAgIGRlZiBuZXdsaW5lKHNlbGYsIG5vZGU9Tm9uZSwgZXh0cmE9MCwgZm9yY2U9RmFsc2UpOgogICAgICAgIGlmIG5vdCBzZWxmLmNvcnJlY3RfbGluZV9udW1iZXJzOgogICAgICAgICAgICBzZWxmLm5ld19saW5lcyA9IG1heChzZWxmLm5ld19saW5lcywgMSArIGV4dHJhKQogICAgICAgICAgICBpZiBub3Qgc2VsZi5yZXN1bHQ6CiAgICAgICAgICAgICAgICBzZWxmLm5ld19saW5lcyA9IDAKICAgICAgICAgICAgaWYgbm9kZSBpcyBub3QgTm9uZSBhbmQgc2VsZi5hZGRfbGluZV9pbmZvcm1hdGlvbjoKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoJyMgbGluZTogJXMnICUgbm9kZS5saW5lbm8pCiAgICAgICAgICAgICAgICBzZWxmLm5ld19saW5lcyA9IDEKICAgICAgICBlbHNlOgogICAgICAgICAgICBpZiBleHRyYToKICAgICAgICAgICAgICAgICNJZ25vcmUgZXh0cmEKICAgICAgICAgICAgICAgIHJldHVybgoKICAgICAgICAgICAgc2VsZi5pbmRlbnRlZCA9IEZhbHNlCgogICAgICAgICAgICBpZiBub2RlIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAjIGVsc2UvZmluYWxseSBzdGF0ZW1lbnQuIGluc2VydCBvbmUgdHJ1ZSBuZXdsaW5lLiBib2R5IGlzIGltcGxpY2l0CiAgICAgICAgICAgICAgICBzZWxmLmZvcmNlX25ld2xpbmUgPSBUcnVlCiAgICAgICAgICAgICAgICBzZWxmLm5ld19saW5lcyArPSAxCiAgICAgICAgICAgICAgICBzZWxmLmxpbmVfbnVtYmVyICs9IDEKCiAgICAgICAgICAgIGVsaWYgZm9yY2U6CiAgICAgICAgICAgICAgICAjIHN0YXRlbWVudCB3aXRoIGEgYmxvY2s6IG5lZWRzIGEgdHJ1ZSBuZXdsaW5lIGJlZm9yZSBpdAogICAgICAgICAgICAgICAgc2VsZi5mb3JjZV9uZXdsaW5lID0gVHJ1ZQogICAgICAgICAgICAgICAgc2VsZi5uZXdfbGluZXMgKz0gbm9kZS5saW5lbm8gLSBzZWxmLmxpbmVfbnVtYmVyCiAgICAgICAgICAgICAgICBzZWxmLmxpbmVfbnVtYmVyID0gbm9kZS5saW5lbm8KCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAjIGJsb2NrLWxlc3Mgc3RhdGVtZW50OiBuZWVkcyBhIHNlbWljb2xvbiwgY29sb24sIG9yIG5ld2xpbmUgaW4gZnJvbnQgb2YgaXQKICAgICAgICAgICAgICAgIHNlbGYubmV3X2xpbmVzICs9IG5vZGUubGluZW5vIC0gc2VsZi5saW5lX251bWJlcgogICAgICAgICAgICAgICAgc2VsZi5saW5lX251bWJlciA9IG5vZGUubGluZW5vCgogICAgZGVmIG1heWJlX2JyZWFrKHNlbGYsIG5vZGUpOgogICAgICAgIGlmIHNlbGYuY29ycmVjdF9saW5lX251bWJlcnM6CiAgICAgICAgICAgIHNlbGYubmV3X2xpbmVzICs9IG5vZGUubGluZW5vIC0gc2VsZi5saW5lX251bWJlcgogICAgICAgICAgICBzZWxmLmxpbmVfbnVtYmVyID0gbm9kZS5saW5lbm8KCiAgICBkZWYgYm9keShzZWxmLCBzdGF0ZW1lbnRzKToKICAgICAgICBzZWxmLmZvcmNlX25ld2xpbmUgPSBhbnkoaXNpbnN0YW5jZShpLCBzZWxmLkJMT0NLX05PREVTKSBmb3IgaSBpbiBzdGF0ZW1lbnRzKQogICAgICAgIHNlbGYuaW5kZW50YXRpb24gKz0gMQogICAgICAgIHNlbGYuYWZ0ZXJfY29sb24gPSAxCiAgICAgICAgZm9yIHN0bXQgaW4gc3RhdGVtZW50czoKICAgICAgICAgICAgc2VsZi52aXNpdChzdG10KQogICAgICAgIHNlbGYuaW5kZW50YXRpb24gLT0gMQogICAgICAgIHNlbGYuZm9yY2VfbmV3bGluZSA9IFRydWUKICAgICAgICBzZWxmLmFmdGVyX2NvbG9uID0gMCAjIGRvIGVtcHR5IGJsb2NrcyBldmVuIGV4aXN0PwoKICAgIGRlZiBib2R5X29yX2Vsc2Uoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5ib2R5KG5vZGUuYm9keSkKICAgICAgICBpZiBub2RlLm9yZWxzZToKICAgICAgICAgICAgc2VsZi5uZXdsaW5lKCkKICAgICAgICAgICAgc2VsZi53cml0ZSgnZWxzZTonKQogICAgICAgICAgICBzZWxmLmJvZHkobm9kZS5vcmVsc2UpCgogICAgZGVmIHZpc2l0X2JhcmUoc2VsZiwgbm9kZSk6CiAgICAgICAgIyB0aGlzIG5vZGUgaXMgYWxsb3dlZCB0byBiZSBhIGJhcmUgdHVwbGUKICAgICAgICBpZiBpc2luc3RhbmNlKG5vZGUsIFR1cGxlKToKICAgICAgICAgICAgc2VsZi52aXNpdF9UdXBsZShub2RlLCBGYWxzZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLnZpc2l0KG5vZGUpCgogICAgZGVmIHZpc2l0X2JhcmV5aWVsZChzZWxmLCBub2RlKToKICAgICAgICBpZiBpc2luc3RhbmNlKG5vZGUsIFlpZWxkKToKICAgICAgICAgICAgc2VsZi52aXNpdF9ZaWVsZChub2RlLCBGYWxzZSkKICAgICAgICBlbGlmIGlzaW5zdGFuY2Uobm9kZSwgWWllbGRGcm9tKToKICAgICAgICAgICAgc2VsZi52aXNpdF9ZaWVsZEZyb20obm9kZSwgRmFsc2UpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi52aXNpdF9iYXJlKG5vZGUpCgogICAgZGVmIGRlY29yYXRvcnMoc2VsZiwgbm9kZSk6CiAgICAgICAgZm9yIGRlY29yYXRvciBpbiBub2RlLmRlY29yYXRvcl9saXN0OgogICAgICAgICAgICBzZWxmLm5ld2xpbmUoZGVjb3JhdG9yLCBmb3JjZT1UcnVlKQogICAgICAgICAgICBzZWxmLndyaXRlKCdAJykKICAgICAgICAgICAgc2VsZi52aXNpdChkZWNvcmF0b3IpCiAgICAgICAgaWYgbm9kZS5kZWNvcmF0b3JfbGlzdDoKICAgICAgICAgICAgc2VsZi5uZXdsaW5lKCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLm5ld2xpbmUobm9kZSwgZm9yY2U9VHJ1ZSkKCiAgICAjIE1vZHVsZQogICAgZGVmIHZpc2l0X01vZHVsZShzZWxmLCBub2RlKToKICAgICAgICBzZWxmLmdlbmVyaWNfdmlzaXQobm9kZSkKICAgICAgICBzZWxmLndyaXRlKCdcbicpCiAgICAgICAgc2VsZi5saW5lX251bWJlciArPSAxCgogICAgIyBTdGF0ZW1lbnRzCgogICAgZGVmIHZpc2l0X0Fzc2VydChzZWxmLCBub2RlKToKICAgICAgICBzZWxmLm5ld2xpbmUobm9kZSkKICAgICAgICBzZWxmLndyaXRlKCdhc3NlcnQgJykKICAgICAgICBzZWxmLnZpc2l0KG5vZGUudGVzdCkKICAgICAgICBpZiBub2RlLm1zZzoKICAgICAgICAgICAgc2VsZi53cml0ZShzZWxmLkNPTU1BKQogICAgICAgICAgICBzZWxmLnZpc2l0KG5vZGUubXNnKQoKICAgIGRlZiB2aXNpdF9Bc3NpZ24oc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5uZXdsaW5lKG5vZGUpCiAgICAgICAgZm9yIHRhcmdldCBpbiBub2RlLnRhcmdldHM6CiAgICAgICAgICAgIHNlbGYudmlzaXRfYmFyZSh0YXJnZXQpCiAgICAgICAgICAgIHNlbGYud3JpdGUoc2VsZi5BU1NJR04pCiAgICAgICAgc2VsZi52aXNpdF9iYXJleWllbGQobm9kZS52YWx1ZSkKCiAgICBkZWYgdmlzaXRfQXVnQXNzaWduKHNlbGYsIG5vZGUpOgogICAgICAgIHNlbGYubmV3bGluZShub2RlKQogICAgICAgIHNlbGYudmlzaXRfYmFyZShub2RlLnRhcmdldCkKICAgICAgICBzZWxmLndyaXRlKHNlbGYuQklOT1BfU1lNQk9MU1t0eXBlKG5vZGUub3ApXVswXS5yc3RyaXAoKSArIHNlbGYuQVNTSUdOLmxzdHJpcCgpKQogICAgICAgIHNlbGYudmlzaXRfYmFyZXlpZWxkKG5vZGUudmFsdWUpCgogICAgZGVmIHZpc2l0X0F3YWl0KHNlbGYsIG5vZGUpOgogICAgICAgIHNlbGYubWF5YmVfYnJlYWsobm9kZSkKICAgICAgICBzZWxmLnByZWNfc3RhcnQoMTYsIFRydWUpCiAgICAgICAgc2VsZi5wcmVjX21pZGRsZSgpCiAgICAgICAgc2VsZi53cml0ZSgnYXdhaXQgJykKICAgICAgICBzZWxmLnZpc2l0KG5vZGUudmFsdWUpCiAgICAgICAgc2VsZi5wcmVjX2VuZCgpCgogICAgZGVmIHZpc2l0X0ltcG9ydEZyb20oc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5uZXdsaW5lKG5vZGUpCiAgICAgICAgc2VsZi53cml0ZSgnZnJvbSAnKQogICAgICAgIHNlbGYud3JpdGUoJyVzJXMnICUgKCcuJyAqIG5vZGUubGV2ZWwsIG5vZGUubW9kdWxlIG9yICcnKSkKICAgICAgICBzZWxmLndyaXRlKCcgaW1wb3J0ICcpCiAgICAgICAgc2VwID0gU2VwKHNlbGYuQ09NTUEpCiAgICAgICAgZm9yIGl0ZW0gaW4gbm9kZS5uYW1lczoKICAgICAgICAgICAgc2VsZi53cml0ZShzZXAoKSkKICAgICAgICAgICAgc2VsZi52aXNpdChpdGVtKQoKICAgIGRlZiB2aXNpdF9JbXBvcnQoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5uZXdsaW5lKG5vZGUpCiAgICAgICAgc2VsZi53cml0ZSgnaW1wb3J0ICcpCiAgICAgICAgc2VwID0gU2VwKHNlbGYuQ09NTUEpCiAgICAgICAgZm9yIGl0ZW0gaW4gbm9kZS5uYW1lczoKICAgICAgICAgICAgc2VsZi53cml0ZShzZXAoKSkKICAgICAgICAgICAgc2VsZi52aXNpdChpdGVtKQoKICAgIGRlZiB2aXNpdF9FeGVjKHNlbGYsIG5vZGUpOgogICAgICAgIHNlbGYubmV3bGluZShub2RlKQogICAgICAgIHNlbGYud3JpdGUoJ2V4ZWMgJykKICAgICAgICBzZWxmLnZpc2l0KG5vZGUuYm9keSkKICAgICAgICBpZiBub2RlLmdsb2JhbHM6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJyBpbiAnKQogICAgICAgICAgICBzZWxmLnZpc2l0KG5vZGUuZ2xvYmFscykKICAgICAgICBpZiBub2RlLmxvY2FsczoKICAgICAgICAgICAgc2VsZi53cml0ZShzZWxmLkNPTU1BKQogICAgICAgICAgICBzZWxmLnZpc2l0KG5vZGUubG9jYWxzKQoKICAgIGRlZiB2aXNpdF9FeHByKHNlbGYsIG5vZGUpOgogICAgICAgIHNlbGYubmV3bGluZShub2RlKQogICAgICAgIHNlbGYudmlzaXRfYmFyZXlpZWxkKG5vZGUudmFsdWUpCgogICAgZGVmIHZpc2l0X0FzeW5jRnVuY3Rpb25EZWYoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi52aXNpdF9GdW5jdGlvbkRlZihub2RlLCBUcnVlKQoKICAgIGRlZiB2aXNpdF9GdW5jdGlvbkRlZihzZWxmLCBub2RlLCBhc3luYz1GYWxzZSk6CiAgICAgICAgc2VsZi5uZXdsaW5lKGV4dHJhPTEpCiAgICAgICAgIyBmaXJzdCBkZWNvcmF0b3IgbGluZSBudW1iZXIgd2lsbCBiZSB1c2VkCiAgICAgICAgc2VsZi5kZWNvcmF0b3JzKG5vZGUpCiAgICAgICAgaWYgYXN5bmM6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJ2FzeW5jICcpCiAgICAgICAgc2VsZi53cml0ZSgnZGVmICcpCiAgICAgICAgc2VsZi53cml0ZShub2RlLm5hbWUpCiAgICAgICAgc2VsZi5wYXJlbl9zdGFydCgpCiAgICAgICAgc2VsZi52aXNpdF9hcmd1bWVudHMobm9kZS5hcmdzKQogICAgICAgIHNlbGYucGFyZW5fZW5kKCkKICAgICAgICBpZiBoYXNhdHRyKG5vZGUsICdyZXR1cm5zJykgYW5kIG5vZGUucmV0dXJucyBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi53cml0ZShzZWxmLkFSUk9XKQogICAgICAgICAgICBzZWxmLnZpc2l0KG5vZGUucmV0dXJucykKICAgICAgICBzZWxmLndyaXRlKCc6JykKICAgICAgICBzZWxmLmJvZHkobm9kZS5ib2R5KQoKICAgIGRlZiB2aXNpdF9hcmd1bWVudHMoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VwID0gU2VwKHNlbGYuQ09NTUEpCiAgICAgICAgcGFkZGluZyA9IFtOb25lXSAqIChsZW4obm9kZS5hcmdzKSAtIGxlbihub2RlLmRlZmF1bHRzKSkKICAgICAgICBpZiBoYXNhdHRyKG5vZGUsICdrd29ubHlhcmdzJyk6CiAgICAgICAgICAgIGZvciBhcmcsIGRlZmF1bHQgaW4gemlwKG5vZGUuYXJncywgcGFkZGluZyArIG5vZGUuZGVmYXVsdHMpOgogICAgICAgICAgICAgICAgc2VsZi53cml0ZShzZXAoKSkKICAgICAgICAgICAgICAgIHNlbGYudmlzaXQoYXJnKQogICAgICAgICAgICAgICAgaWYgZGVmYXVsdCBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCc9JykKICAgICAgICAgICAgICAgICAgICBzZWxmLnZpc2l0KGRlZmF1bHQpCiAgICAgICAgICAgIGlmIG5vZGUudmFyYXJnIGlzIG5vdCBOb25lOgogICAgICAgICAgICAgICAgc2VsZi53cml0ZShzZXAoKSkKICAgICAgICAgICAgICAgIGlmIGhhc2F0dHIobm9kZSwgJ3ZhcmFyZ2Fubm90YXRpb24nKToKICAgICAgICAgICAgICAgICAgICBpZiBub2RlLnZhcmFyZ2Fubm90YXRpb24gaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53cml0ZSgnKicgKyBub2RlLnZhcmFyZykKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm1heWJlX2JyZWFrKG5vZGUudmFyYXJnYW5ub3RhdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53cml0ZSgnKicgKyBub2RlLnZhcmFyZykKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53cml0ZShzZWxmLkNPTE9OKQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnZpc2l0KG5vZGUudmFyYXJnYW5ub3RhdGlvbikKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5tYXliZV9icmVhayhub2RlLnZhcmFyZykKICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCcqJykKICAgICAgICAgICAgICAgICAgICBzZWxmLnZpc2l0KG5vZGUudmFyYXJnKQogICAgICAgICAgICBlbGlmIG5vZGUua3dvbmx5YXJnczoKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoc2VwKCkgKyAnKicpCgogICAgICAgICAgICBmb3IgYXJnLCBkZWZhdWx0IGluIHppcChub2RlLmt3b25seWFyZ3MsIG5vZGUua3dfZGVmYXVsdHMpOgogICAgICAgICAgICAgICAgc2VsZi53cml0ZShzZXAoKSkKICAgICAgICAgICAgICAgIHNlbGYudmlzaXQoYXJnKQogICAgICAgICAgICAgICAgaWYgZGVmYXVsdCBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCc9JykKICAgICAgICAgICAgICAgICAgICBzZWxmLnZpc2l0KGRlZmF1bHQpCiAgICAgICAgICAgIGlmIG5vZGUua3dhcmcgaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKHNlcCgpKQogICAgICAgICAgICAgICAgaWYgaGFzYXR0cihub2RlLCAna3dhcmdhbm5vdGF0aW9uJyk6CiAgICAgICAgICAgICAgICAgICAgaWYgbm9kZS5rd2FyZ2Fubm90YXRpb24gaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53cml0ZSgnKionICsgbm9kZS5rd2FyZykKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLm1heWJlX2JyZWFrKG5vZGUua3dhcmdhbm5vdGF0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCcqKicgKyBub2RlLmt3YXJnKQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKHNlbGYuQ09MT04pCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYudmlzaXQobm9kZS5rd2FyZ2Fubm90YXRpb24pCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYubWF5YmVfYnJlYWsobm9kZS5rd2FyZykKICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCcqKicpCiAgICAgICAgICAgICAgICAgICAgc2VsZi52aXNpdChub2RlLmt3YXJnKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIGZvciBhcmcsIGRlZmF1bHQgaW4gemlwKG5vZGUuYXJncywgcGFkZGluZyArIG5vZGUuZGVmYXVsdHMpOgogICAgICAgICAgICAgICAgc2VsZi53cml0ZShzZXAoKSkKICAgICAgICAgICAgICAgIHNlbGYudmlzaXQoYXJnKQogICAgICAgICAgICAgICAgaWYgZGVmYXVsdCBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCc9JykKICAgICAgICAgICAgICAgICAgICBzZWxmLnZpc2l0KGRlZmF1bHQpCiAgICAgICAgICAgIGlmIG5vZGUudmFyYXJnIGlzIG5vdCBOb25lOgogICAgICAgICAgICAgICAgc2VsZi53cml0ZShzZXAoKSkKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoJyonICsgbm9kZS52YXJhcmcpCiAgICAgICAgICAgIGlmIG5vZGUua3dhcmcgaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKHNlcCgpKQogICAgICAgICAgICAgICAgc2VsZi53cml0ZSgnKionICsgbm9kZS5rd2FyZykKCiAgICBkZWYgdmlzaXRfYXJnKHNlbGYsIG5vZGUpOgogICAgICAgICMgUHkzIG9ubHkKICAgICAgICBzZWxmLm1heWJlX2JyZWFrKG5vZGUpCiAgICAgICAgc2VsZi53cml0ZShub2RlLmFyZykKICAgICAgICBpZiBub2RlLmFubm90YXRpb24gaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYud3JpdGUoc2VsZi5DT0xPTikKICAgICAgICAgICAgc2VsZi52aXNpdChub2RlLmFubm90YXRpb24pCgogICAgZGVmIHZpc2l0X2tleXdvcmQoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5tYXliZV9icmVhayhub2RlLnZhbHVlKQogICAgICAgIGlmIG5vZGUuYXJnIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLndyaXRlKG5vZGUuYXJnICsgJz0nKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJyoqJykKICAgICAgICBzZWxmLnZpc2l0KG5vZGUudmFsdWUpCgogICAgZGVmIHZpc2l0X0NsYXNzRGVmKHNlbGYsIG5vZGUpOgogICAgICAgIHNlbGYubmV3bGluZShleHRyYT0yKQogICAgICAgICMgZmlyc3QgZGVjb3JhdG9yIGxpbmUgbnVtYmVyIHdpbGwgYmUgdXNlZAogICAgICAgIHNlbGYuZGVjb3JhdG9ycyhub2RlKQogICAgICAgIHNlbGYud3JpdGUoJ2NsYXNzICVzJyAlIG5vZGUubmFtZSkKCiAgICAgICAgaWYgKG5vZGUuYmFzZXMgb3IgKGhhc2F0dHIobm9kZSwgJ2tleXdvcmRzJykgYW5kIG5vZGUua2V5d29yZHMpIG9yCiAgICAgICAgICAgICAgICAoaGFzYXR0cihub2RlLCAnc3RhcmFyZ3MnKSBhbmQgKG5vZGUuc3RhcmFyZ3Mgb3Igbm9kZS5rd2FyZ3MpKSk6CiAgICAgICAgICAgIHNlbGYucGFyZW5fc3RhcnQoKQogICAgICAgICAgICBzZXAgPSBTZXAoc2VsZi5DT01NQSkKCiAgICAgICAgICAgIGZvciBiYXNlIGluIG5vZGUuYmFzZXM6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKHNlcCgpKQogICAgICAgICAgICAgICAgc2VsZi52aXNpdChiYXNlKQogICAgICAgICAgICAjIFhYWDogdGhlIGlmIGhlcmUgaXMgdXNlZCB0byBrZWVwIHRoaXMgbW9kdWxlIGNvbXBhdGlibGUKICAgICAgICAgICAgIyAgICAgIHdpdGggcHl0aG9uIDIuNi4KICAgICAgICAgICAgaWYgaGFzYXR0cihub2RlLCAna2V5d29yZHMnKToKICAgICAgICAgICAgICAgIGZvciBrZXl3b3JkIGluIG5vZGUua2V5d29yZHM6CiAgICAgICAgICAgICAgICAgICAgc2VsZi53cml0ZShzZXAoKSkKICAgICAgICAgICAgICAgICAgICBzZWxmLnZpc2l0KGtleXdvcmQpCiAgICAgICAgICAgICAgICBpZiBoYXNhdHRyKG5vZGUsICdzdGFyYXJncycpOgogICAgICAgICAgICAgICAgICAgIGlmIG5vZGUuc3RhcmFyZ3MgaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoc2VwKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubWF5YmVfYnJlYWsobm9kZS5zdGFyYXJncykKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53cml0ZSgnKicpCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYudmlzaXQobm9kZS5zdGFyYXJncykKICAgICAgICAgICAgICAgICAgICBpZiBub2RlLmt3YXJncyBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53cml0ZShzZXAoKSkKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5tYXliZV9icmVhayhub2RlLmt3YXJncykKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi53cml0ZSgnKionKQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnZpc2l0KG5vZGUua3dhcmdzKQogICAgICAgICAgICBzZWxmLnBhcmVuX2VuZCgpCiAgICAgICAgc2VsZi53cml0ZSgnOicpCiAgICAgICAgc2VsZi5ib2R5KG5vZGUuYm9keSkKCiAgICBkZWYgdmlzaXRfSWYoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5uZXdsaW5lKG5vZGUsIGZvcmNlPVRydWUpCiAgICAgICAgc2VsZi53cml0ZSgnaWYgJykKICAgICAgICBzZWxmLnZpc2l0KG5vZGUudGVzdCkKICAgICAgICBzZWxmLndyaXRlKCc6JykKICAgICAgICBzZWxmLmJvZHkobm9kZS5ib2R5KQogICAgICAgIHdoaWxlIFRydWU6CiAgICAgICAgICAgIGlmIGxlbihub2RlLm9yZWxzZSkgPT0gMSBhbmQgaXNpbnN0YW5jZShub2RlLm9yZWxzZVswXSwgSWYpOgogICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUub3JlbHNlWzBdCiAgICAgICAgICAgICAgICBzZWxmLm5ld2xpbmUobm9kZS50ZXN0LCBmb3JjZT1UcnVlKQogICAgICAgICAgICAgICAgc2VsZi53cml0ZSgnZWxpZiAnKQogICAgICAgICAgICAgICAgc2VsZi52aXNpdChub2RlLnRlc3QpCiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCc6JykKICAgICAgICAgICAgICAgIHNlbGYuYm9keShub2RlLmJvZHkpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBpZiBub2RlLm9yZWxzZToKICAgICAgICAgICAgICAgICAgICBzZWxmLm5ld2xpbmUoKQogICAgICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoJ2Vsc2U6JykKICAgICAgICAgICAgICAgICAgICBzZWxmLmJvZHkobm9kZS5vcmVsc2UpCiAgICAgICAgICAgICAgICBicmVhawoKICAgIGRlZiB2aXNpdF9Bc3luY0ZvcihzZWxmLCBub2RlKToKICAgICAgICBzZWxmLnZpc2l0X0Zvcihub2RlLCBUcnVlKQoKICAgIGRlZiB2aXNpdF9Gb3Ioc2VsZiwgbm9kZSwgYXN5bmM9RmFsc2UpOgogICAgICAgIHNlbGYubmV3bGluZShub2RlLCBmb3JjZT1UcnVlKQogICAgICAgIGlmIGFzeW5jOgogICAgICAgICAgICBzZWxmLndyaXRlKCdhc3luYyAnKQogICAgICAgIHNlbGYud3JpdGUoJ2ZvciAnKQogICAgICAgIHNlbGYudmlzaXRfYmFyZShub2RlLnRhcmdldCkKICAgICAgICBzZWxmLndyaXRlKCcgaW4gJykKICAgICAgICBzZWxmLnZpc2l0KG5vZGUuaXRlcikKICAgICAgICBzZWxmLndyaXRlKCc6JykKICAgICAgICBzZWxmLmJvZHlfb3JfZWxzZShub2RlKQoKICAgIGRlZiB2aXNpdF9XaGlsZShzZWxmLCBub2RlKToKICAgICAgICBzZWxmLm5ld2xpbmUobm9kZSwgZm9yY2U9VHJ1ZSkKICAgICAgICBzZWxmLndyaXRlKCd3aGlsZSAnKQogICAgICAgIHNlbGYudmlzaXQobm9kZS50ZXN0KQogICAgICAgIHNlbGYud3JpdGUoJzonKQogICAgICAgIHNlbGYuYm9keV9vcl9lbHNlKG5vZGUpCgogICAgZGVmIHZpc2l0X0FzeW5jV2l0aChzZWxmLCBub2RlKToKICAgICAgICBzZWxmLnZpc2l0X1dpdGgobm9kZSwgVHJ1ZSkKCiAgICBkZWYgdmlzaXRfV2l0aChzZWxmLCBub2RlLCBhc3luYz1GYWxzZSk6CiAgICAgICAgc2VsZi5uZXdsaW5lKG5vZGUsIGZvcmNlPVRydWUpCiAgICAgICAgaWYgYXN5bmM6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJ2FzeW5jICcpCiAgICAgICAgc2VsZi53cml0ZSgnd2l0aCAnKQoKICAgICAgICBpZiBoYXNhdHRyKG5vZGUsICdpdGVtcycpOgogICAgICAgICAgICBzZXAgPSBTZXAoc2VsZi5DT01NQSkKICAgICAgICAgICAgZm9yIGl0ZW0gaW4gbm9kZS5pdGVtczoKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoc2VwKCkpCiAgICAgICAgICAgICAgICBzZWxmLnZpc2l0X3dpdGhpdGVtKGl0ZW0pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBpbiBweXRob24gMiwgc2ltaWxhcmx5IHRvIHRoZSBlbGlmIHN0YXRlbWVudCwgbXVsdGlwbGUgbmVzdGVkIGNvbnRleHQgbWFuYWdlcnMKICAgICAgICAgICAgIyBhcmUgZ2VuZXJhbGx5IHRoZSBtdWx0aS1mb3JtIG9mIGEgc2luZ2xlIHdpdGggc3RhdGVtZW50CiAgICAgICAgICAgIHNlbGYudmlzaXRfd2l0aGl0ZW0obm9kZSkKICAgICAgICAgICAgd2hpbGUgbGVuKG5vZGUuYm9keSkgPT0gMSBhbmQgaXNpbnN0YW5jZShub2RlLmJvZHlbMF0sIFdpdGgpOgogICAgICAgICAgICAgICAgbm9kZSA9IG5vZGUuYm9keVswXQogICAgICAgICAgICAgICAgc2VsZi53cml0ZShzZWxmLkNPTU1BKQogICAgICAgICAgICAgICAgc2VsZi52aXNpdF93aXRoaXRlbShub2RlKQogICAgICAgIHNlbGYud3JpdGUoJzonKQogICAgICAgIHNlbGYuYm9keShub2RlLmJvZHkpCgogICAgZGVmIHZpc2l0X3dpdGhpdGVtKHNlbGYsIG5vZGUpOgogICAgICAgIHNlbGYudmlzaXQobm9kZS5jb250ZXh0X2V4cHIpCiAgICAgICAgaWYgbm9kZS5vcHRpb25hbF92YXJzIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLndyaXRlKCcgYXMgJykKICAgICAgICAgICAgc2VsZi52aXNpdChub2RlLm9wdGlvbmFsX3ZhcnMpCgogICAgZGVmIHZpc2l0X1Bhc3Moc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5uZXdsaW5lKG5vZGUpCiAgICAgICAgc2VsZi53cml0ZSgncGFzcycpCgogICAgZGVmIHZpc2l0X1ByaW50KHNlbGYsIG5vZGUpOgogICAgICAgICMgWFhYOiBweXRob24gMiBvbmx5CiAgICAgICAgc2VsZi5uZXdsaW5lKG5vZGUpCiAgICAgICAgc2VsZi53cml0ZSgncHJpbnQgJykKICAgICAgICBzZXAgPSBTZXAoc2VsZi5DT01NQSkKICAgICAgICBpZiBub2RlLmRlc3QgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJyA+PiAnKQogICAgICAgICAgICBzZWxmLnZpc2l0KG5vZGUuZGVzdCkKICAgICAgICAgICAgc2VwKCkKICAgICAgICBmb3IgdmFsdWUgaW4gbm9kZS52YWx1ZXM6CiAgICAgICAgICAgIHNlbGYud3JpdGUoc2VwKCkpCiAgICAgICAgICAgIHNlbGYudmlzaXQodmFsdWUpCiAgICAgICAgaWYgbm90IG5vZGUubmw6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJywnKQoKICAgIGRlZiB2aXNpdF9EZWxldGUoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5uZXdsaW5lKG5vZGUpCiAgICAgICAgc2VsZi53cml0ZSgnZGVsICcpCiAgICAgICAgc2VwID0gU2VwKHNlbGYuQ09NTUEpCiAgICAgICAgZm9yIHRhcmdldCBpbiBub2RlLnRhcmdldHM6CiAgICAgICAgICAgIHNlbGYud3JpdGUoc2VwKCkpCiAgICAgICAgICAgIHNlbGYudmlzaXQodGFyZ2V0KQoKICAgIGRlZiB2aXNpdF9Ucnkoc2VsZiwgbm9kZSk6CiAgICAgICAgIyBQeXRob24gMyBvbmx5LiBleHBsb2l0cyB0aGUgZmFjdCB0aGF0IFRyeUV4Y2VwdCB1c2VzIHRoZSBzYW1lIGF0dHJpYnV0ZSBuYW1lcwogICAgICAgIHNlbGYudmlzaXRfVHJ5RXhjZXB0KG5vZGUpCiAgICAgICAgaWYgbm9kZS5maW5hbGJvZHk6CiAgICAgICAgICAgIHNlbGYubmV3bGluZSgpCiAgICAgICAgICAgIHNlbGYud3JpdGUoJ2ZpbmFsbHk6JykKICAgICAgICAgICAgc2VsZi5ib2R5KG5vZGUuZmluYWxib2R5KQoKICAgIGRlZiB2aXNpdF9UcnlFeGNlcHQoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5uZXdsaW5lKG5vZGUsIGZvcmNlPVRydWUpCiAgICAgICAgc2VsZi53cml0ZSgndHJ5OicpCiAgICAgICAgc2VsZi5ib2R5KG5vZGUuYm9keSkKICAgICAgICBmb3IgaGFuZGxlciBpbiBub2RlLmhhbmRsZXJzOgogICAgICAgICAgICBzZWxmLnZpc2l0KGhhbmRsZXIpCiAgICAgICAgaWYgbm9kZS5vcmVsc2U6CiAgICAgICAgICAgIHNlbGYubmV3bGluZSgpCiAgICAgICAgICAgIHNlbGYud3JpdGUoJ2Vsc2U6JykKICAgICAgICAgICAgc2VsZi5ib2R5KG5vZGUub3JlbHNlKQoKICAgIGRlZiB2aXNpdF9UcnlGaW5hbGx5KHNlbGYsIG5vZGUpOgogICAgICAgICMgUHl0aG9uIDIgb25seQogICAgICAgIGlmIGxlbihub2RlLmJvZHkpID09IDEgYW5kIGlzaW5zdGFuY2Uobm9kZS5ib2R5WzBdLCBUcnlFeGNlcHQpOgogICAgICAgICAgICBzZWxmLnZpc2l0X1RyeUV4Y2VwdChub2RlLmJvZHlbMF0pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5uZXdsaW5lKG5vZGUsIGZvcmNlPVRydWUpCiAgICAgICAgICAgIHNlbGYud3JpdGUoJ3RyeTonKQogICAgICAgICAgICBzZWxmLmJvZHkobm9kZS5ib2R5KQogICAgICAgIHNlbGYubmV3bGluZSgpCiAgICAgICAgc2VsZi53cml0ZSgnZmluYWxseTonKQogICAgICAgIHNlbGYuYm9keShub2RlLmZpbmFsYm9keSkKCiAgICBkZWYgdmlzaXRfRXhjZXB0SGFuZGxlcihzZWxmLCBub2RlKToKICAgICAgICBzZWxmLm5ld2xpbmUobm9kZSwgZm9yY2U9VHJ1ZSkKICAgICAgICBzZWxmLndyaXRlKCdleGNlcHQnKQogICAgICAgIGlmIG5vZGUudHlwZToKICAgICAgICAgICAgc2VsZi53cml0ZSgnICcpCiAgICAgICAgICAgIHNlbGYudmlzaXQobm9kZS50eXBlKQogICAgICAgICAgICBpZiBub2RlLm5hbWU6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCcgYXMgJykKICAgICAgICAgICAgICAgICMgQ29tcGF0YWJpbGl0eQogICAgICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShub2RlLm5hbWUsIEFTVCk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi52aXNpdChub2RlLm5hbWUpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYud3JpdGUobm9kZS5uYW1lKQogICAgICAgIHNlbGYud3JpdGUoJzonKQogICAgICAgIHNlbGYuYm9keShub2RlLmJvZHkpCgogICAgZGVmIHZpc2l0X0dsb2JhbChzZWxmLCBub2RlKToKICAgICAgICBzZWxmLm5ld2xpbmUobm9kZSkKICAgICAgICBzZWxmLndyaXRlKCdnbG9iYWwgJyArIHNlbGYuQ09NTUEuam9pbihub2RlLm5hbWVzKSkKCiAgICBkZWYgdmlzaXRfTm9ubG9jYWwoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5uZXdsaW5lKG5vZGUpCiAgICAgICAgc2VsZi53cml0ZSgnbm9ubG9jYWwgJyArIHNlbGYuQ09NTUEuam9pbihub2RlLm5hbWVzKSkKCiAgICBkZWYgdmlzaXRfUmV0dXJuKHNlbGYsIG5vZGUpOgogICAgICAgIHNlbGYubmV3bGluZShub2RlKQogICAgICAgIGlmIG5vZGUudmFsdWUgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJ3JldHVybiAnKQogICAgICAgICAgICBzZWxmLnZpc2l0KG5vZGUudmFsdWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi53cml0ZSgncmV0dXJuJykKCiAgICBkZWYgdmlzaXRfQnJlYWsoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5uZXdsaW5lKG5vZGUpCiAgICAgICAgc2VsZi53cml0ZSgnYnJlYWsnKQoKICAgIGRlZiB2aXNpdF9Db250aW51ZShzZWxmLCBub2RlKToKICAgICAgICBzZWxmLm5ld2xpbmUobm9kZSkKICAgICAgICBzZWxmLndyaXRlKCdjb250aW51ZScpCgogICAgZGVmIHZpc2l0X1JhaXNlKHNlbGYsIG5vZGUpOgogICAgICAgICMgWFhYOiBQeXRob24gMi42IC8gMy4wIGNvbXBhdGliaWxpdHkKICAgICAgICBzZWxmLm5ld2xpbmUobm9kZSkKICAgICAgICBpZiBoYXNhdHRyKG5vZGUsICdleGMnKSBhbmQgbm9kZS5leGMgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJ3JhaXNlICcpCiAgICAgICAgICAgIHNlbGYudmlzaXQobm9kZS5leGMpCiAgICAgICAgICAgIGlmIG5vZGUuY2F1c2UgaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCcgZnJvbSAnKQogICAgICAgICAgICAgICAgc2VsZi52aXNpdChub2RlLmNhdXNlKQogICAgICAgIGVsaWYgaGFzYXR0cihub2RlLCAndHlwZScpIGFuZCBub2RlLnR5cGUgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJ3JhaXNlICcpCiAgICAgICAgICAgIHNlbGYudmlzaXQobm9kZS50eXBlKQogICAgICAgICAgICBpZiBub2RlLmluc3QgaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKHNlbGYuQ09NTUEpCiAgICAgICAgICAgICAgICBzZWxmLnZpc2l0KG5vZGUuaW5zdCkKICAgICAgICAgICAgaWYgbm9kZS50YmFjayBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoc2VsZi5DT01NQSkKICAgICAgICAgICAgICAgIHNlbGYudmlzaXQobm9kZS50YmFjaykKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLndyaXRlKCdyYWlzZScpCgogICAgIyBFeHByZXNzaW9ucwoKICAgIGRlZiB2aXNpdF9BdHRyaWJ1dGUoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5tYXliZV9icmVhayhub2RlKQogICAgICAgICMgRWRnZSBjYXNlOiBkdWUgdG8gdGhlIHVzZSBvZiBcZCpbLl1cZCogZm9yIGZsb2F0cyBcZCpbLl1cdyosIHlvdSBoYXZlCiAgICAgICAgIyB0byBwdXQgcGFyZW50aGVzaXMgYXJvdW5kIGFuIGludGVnZXIgbGl0ZXJhbCBkbyBnZXQgYW4gYXR0cmlidXRlIGZyb20gaXQKICAgICAgICBpZiBpc2luc3RhbmNlKG5vZGUudmFsdWUsIE51bSk6CiAgICAgICAgICAgIHNlbGYucGFyZW5fc3RhcnQoKQogICAgICAgICAgICBzZWxmLnZpc2l0KG5vZGUudmFsdWUpCiAgICAgICAgICAgIHNlbGYucGFyZW5fZW5kKCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLnByZWNfc3RhcnQoMTcpCiAgICAgICAgICAgIHNlbGYudmlzaXQobm9kZS52YWx1ZSkKICAgICAgICAgICAgc2VsZi5wcmVjX2VuZCgpCiAgICAgICAgc2VsZi53cml0ZSgnLicgKyBub2RlLmF0dHIpCgogICAgZGVmIHZpc2l0X0NhbGwoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5tYXliZV9icmVhayhub2RlKQogICAgICAgICNuZWVkIHRvIHB1dCBwYXJlbnRoZXNpcyBhcm91bmQgbnVtYmVycyBiZWluZyBjYWxsZWQgKHRoaXMgbWFrZXMgbm8gc2Vuc2UpCiAgICAgICAgaWYgaXNpbnN0YW5jZShub2RlLmZ1bmMsIE51bSk6CiAgICAgICAgICAgIHNlbGYucGFyZW5fc3RhcnQoKQogICAgICAgICAgICBzZWxmLnZpc2l0X051bShub2RlLmZ1bmMpCiAgICAgICAgICAgIHNlbGYucGFyZW5fZW5kKCkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLnByZWNfc3RhcnQoMTcpCiAgICAgICAgICAgIHNlbGYudmlzaXQobm9kZS5mdW5jKQogICAgICAgICAgICBzZWxmLnByZWNfZW5kKCkKICAgICAgICAjIHNwZWNpYWwgY2FzZSBnZW5lcmF0b3IgZXhwcmVzc2lvbnMgYXMgb25seSBhcmd1bWVudAogICAgICAgIGlmIChsZW4obm9kZS5hcmdzKSA9PSAxIGFuZCBpc2luc3RhbmNlKG5vZGUuYXJnc1swXSwgR2VuZXJhdG9yRXhwKSBhbmQKICAgICAgICAgICAgICAgIG5vdCBub2RlLmtleXdvcmRzIGFuZCBoYXNhdHRyKG5vZGUsICdzdGFyYXJncycpIGFuZCAKICAgICAgICAgICAgICAgIG5vdCBub2RlLnN0YXJhcmdzIGFuZCBub3Qgbm9kZS5rd2FyZ3MpOgogICAgICAgICAgICBzZWxmLnZpc2l0X0dlbmVyYXRvckV4cChub2RlLmFyZ3NbMF0pCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBzZWxmLnBhcmVuX3N0YXJ0KCkKICAgICAgICBzZXAgPSBTZXAoc2VsZi5DT01NQSkKICAgICAgICBmb3IgYXJnIGluIG5vZGUuYXJnczoKICAgICAgICAgICAgc2VsZi53cml0ZShzZXAoKSkKICAgICAgICAgICAgc2VsZi5tYXliZV9icmVhayhhcmcpCiAgICAgICAgICAgIHNlbGYudmlzaXQoYXJnKQogICAgICAgIGZvciBrZXl3b3JkIGluIG5vZGUua2V5d29yZHM6CiAgICAgICAgICAgIHNlbGYud3JpdGUoc2VwKCkpCiAgICAgICAgICAgIHNlbGYudmlzaXQoa2V5d29yZCkKICAgICAgICBpZiBoYXNhdHRyKG5vZGUsICdzdGFyYXJncycpOgogICAgICAgICAgICBpZiBub2RlLnN0YXJhcmdzIGlzIG5vdCBOb25lOgogICAgICAgICAgICAgICAgc2VsZi53cml0ZShzZXAoKSkKICAgICAgICAgICAgICAgIHNlbGYubWF5YmVfYnJlYWsobm9kZS5zdGFyYXJncykKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoJyonKQogICAgICAgICAgICAgICAgc2VsZi52aXNpdChub2RlLnN0YXJhcmdzKQogICAgICAgICAgICBpZiBub2RlLmt3YXJncyBpcyBub3QgTm9uZToKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoc2VwKCkpCiAgICAgICAgICAgICAgICBzZWxmLm1heWJlX2JyZWFrKG5vZGUua3dhcmdzKQogICAgICAgICAgICAgICAgc2VsZi53cml0ZSgnKionKQogICAgICAgICAgICAgICAgc2VsZi52aXNpdChub2RlLmt3YXJncykKICAgICAgICBzZWxmLnBhcmVuX2VuZCgpCgogICAgZGVmIHZpc2l0X05hbWUoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5tYXliZV9icmVhayhub2RlKQogICAgICAgIHNlbGYud3JpdGUobm9kZS5pZCkKCiAgICBkZWYgdmlzaXRfTmFtZUNvbnN0YW50KHNlbGYsIG5vZGUpOgogICAgICAgIHNlbGYubWF5YmVfYnJlYWsobm9kZSkKICAgICAgICBzZWxmLndyaXRlKHJlcHIobm9kZS52YWx1ZSkpCgogICAgZGVmIHZpc2l0X1N0cihzZWxmLCBub2RlLCBmcm9tYnl0ZXM9RmFsc2UpOgogICAgICAgIHNlbGYubWF5YmVfYnJlYWsobm9kZSkKICAgICAgICBpZiBmcm9tYnl0ZXM6CiAgICAgICAgICAgIG5ld2xpbmVfY291bnQgPSBub2RlLnMuY291bnQoJ1xuJy5lbmNvZGUoJ3V0Zi04JykpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgbmV3bGluZV9jb3VudCA9IG5vZGUucy5jb3VudCgnXG4nKQoKICAgICAgICAjIGhldXJpc3RpYywgZXhwYW5kIHdoZW4gbW9yZSB0aGFuIDEgbmV3bGluZSBhbmQgd2hlbiBhdCBsZWFzdCA4MCUKICAgICAgICAjIG9mIHRoZSBjaGFyYWN0ZXJzIGFyZW4ndCBuZXdsaW5lcwogICAgICAgIGV4cGFuZCA9IG5ld2xpbmVfY291bnQgPiAxIGFuZCBsZW4obm9kZS5zKSA+IDUgKiBuZXdsaW5lX2NvdW50CiAgICAgICAgaWYgc2VsZi5jb3JyZWN0X2xpbmVfbnVtYmVyczoKICAgICAgICAgICAgIyBBbHNvIGNoZWNrIGlmIHdlIGhhdmUgZW5vdWduIG5ld2xpbmVzIHRvIGV4cGFuZCBpbiBpZiB3ZSdyZSBnb2luZyBmb3IgY29ycmVjdCBsaW5lIG51bWJlcnMKICAgICAgICAgICAgaWYgc2VsZi5hZnRlcl9jb2xvbjoKICAgICAgICAgICAgICAgICMgQWx0aG91Z2ggdGhpcyBtYWtlcyBsaXR0bGUgc2Vuc2UganVzdCBhZnRlciBhIGNvbG9uCiAgICAgICAgICAgICAgICBleHBhbmQgPSBleHBhbmQgYW5kIHNlbGYubmV3X2xpbmVzID4gbmV3bGluZV9jb3VudAogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgZXhwYW5kID0gZXhwYW5kIGFuZCBzZWxmLm5ld19saW5lcyA+PSBuZXdsaW5lX2NvdW50CgogICAgICAgIGlmIGV4cGFuZCBhbmQgKG5vdCBzZWxmLmNvcnJlY3RfbGluZV9udW1iZXJzIG9yIHNlbGYubmV3X2xpbmVzID49IG5ld2xpbmVfY291bnQpOgogICAgICAgICAgICBpZiBzZWxmLmNvcnJlY3RfbGluZV9udW1iZXJzOgogICAgICAgICAgICAgICAgc2VsZi5uZXdfbGluZXMgLT0gbmV3bGluZV9jb3VudAoKICAgICAgICAgICAgYSA9IHJlcHIobm9kZS5zKQogICAgICAgICAgICBkZWxpbWl0ZXIgPSBhWy0xXQogICAgICAgICAgICBoZWFkZXIsIGNvbnRlbnQgPSBhWzotMV0uc3BsaXQoZGVsaW1pdGVyLCAxKQogICAgICAgICAgICBsaW5lcyA9IFtdCiAgICAgICAgICAgIGNoYWluID0gRmFsc2UKICAgICAgICAgICAgZm9yIGkgaW4gY29udGVudC5zcGxpdCgnXFxuJyk6CiAgICAgICAgICAgICAgICBpZiBjaGFpbjoKICAgICAgICAgICAgICAgICAgICBpID0gbGluZXMucG9wKCkgKyBpCiAgICAgICAgICAgICAgICAgICAgY2hhaW4gPSBGYWxzZQogICAgICAgICAgICAgICAgaWYgKGxlbihpKSAtIGxlbihpLnJzdHJpcCgnXFwnKSkpICUgMjoKICAgICAgICAgICAgICAgICAgICBpICs9ICdcXG4nCiAgICAgICAgICAgICAgICAgICAgY2hhaW4gPSBUcnVlCiAgICAgICAgICAgICAgICBsaW5lcy5hcHBlbmQoaSkKICAgICAgICAgICAgYXNzZXJ0IG5ld2xpbmVfY291bnQgKyAxID09IGxlbihsaW5lcykKICAgICAgICAgICAgc2VsZi53cml0ZShoZWFkZXIpCiAgICAgICAgICAgIHNlbGYud3JpdGUoZGVsaW1pdGVyICogMykKICAgICAgICAgICAgc2VsZi53cml0ZSgnXG4nLmpvaW4obGluZXMpKQogICAgICAgICAgICBzZWxmLndyaXRlKGRlbGltaXRlciAqIDMpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi53cml0ZShyZXByKG5vZGUucykpCgogICAgZGVmIHZpc2l0X0J5dGVzKHNlbGYsIG5vZGUpOgogICAgICAgIHNlbGYudmlzaXRfU3RyKG5vZGUsIFRydWUpCgogICAgZGVmIHZpc2l0X051bShzZWxmLCBub2RlKToKICAgICAgICBzZWxmLm1heWJlX2JyZWFrKG5vZGUpCgogICAgICAgIG5lZ2F0aXZlID0gKG5vZGUubi5pbWFnIG9yIG5vZGUubi5yZWFsKSA8IDAgYW5kIG5vdCBQWTMKICAgICAgICBpZiBuZWdhdGl2ZToKICAgICAgICAgICAgc2VsZi5wcmVjX3N0YXJ0KHNlbGYuVU5BUllPUF9TWU1CT0xTW1VTdWJdWzFdKQoKICAgICAgICAjIDFlOTk5IGFuZCByZWxhdGVkIGZyaWVuZHMgYXJlIHBhcnNlZCBpbnRvIGluZgogICAgICAgIGlmIGFicyhub2RlLm4pID09IDFlOTk5OgogICAgICAgICAgICBpZiBuZWdhdGl2ZToKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoJy0nKQogICAgICAgICAgICBzZWxmLndyaXRlKCcxZTk5OScpCiAgICAgICAgICAgIGlmIG5vZGUubi5pbWFnOgogICAgICAgICAgICAgICAgc2VsZi53cml0ZSgnaicpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi53cml0ZShyZXByKG5vZGUubikpCgogICAgICAgIGlmIG5lZ2F0aXZlOgogICAgICAgICAgICBzZWxmLnByZWNfZW5kKCkKCiAgICBkZWYgdmlzaXRfVHVwbGUoc2VsZiwgbm9kZSwgZ3VhcmQ9VHJ1ZSk6CiAgICAgICAgaWYgZ3VhcmQgb3Igbm90IG5vZGUuZWx0czoKICAgICAgICAgICAgc2VsZi5wYXJlbl9zdGFydCgpCiAgICAgICAgc2VwID0gU2VwKHNlbGYuQ09NTUEpCiAgICAgICAgZm9yIGl0ZW0gaW4gbm9kZS5lbHRzOgogICAgICAgICAgICBzZWxmLndyaXRlKHNlcCgpKQogICAgICAgICAgICBzZWxmLnZpc2l0KGl0ZW0pCiAgICAgICAgaWYgbGVuKG5vZGUuZWx0cykgPT0gMToKICAgICAgICAgICAgc2VsZi53cml0ZSgnLCcpCiAgICAgICAgaWYgZ3VhcmQgb3Igbm90IG5vZGUuZWx0czoKICAgICAgICAgICAgc2VsZi5wYXJlbl9lbmQoKQoKICAgIGRlZiBfc2VxdWVuY2VfdmlzaXQobGVmdCwgcmlnaHQpOiAjIHB5bGludDogZGlzYWJsZT1FMDIxMwogICAgICAgIGRlZiB2aXNpdChzZWxmLCBub2RlKToKICAgICAgICAgICAgc2VsZi5tYXliZV9icmVhayhub2RlKQogICAgICAgICAgICBzZWxmLnBhcmVuX3N0YXJ0KGxlZnQpCiAgICAgICAgICAgIHNlcCA9IFNlcChzZWxmLkNPTU1BKQogICAgICAgICAgICBmb3IgaXRlbSBpbiBub2RlLmVsdHM6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKHNlcCgpKQogICAgICAgICAgICAgICAgc2VsZi52aXNpdChpdGVtKQogICAgICAgICAgICBzZWxmLnBhcmVuX2VuZChyaWdodCkKICAgICAgICByZXR1cm4gdmlzaXQKCiAgICB2aXNpdF9MaXN0ID0gX3NlcXVlbmNlX3Zpc2l0KCdbJywgJ10nKQogICAgdmlzaXRfU2V0ID0gX3NlcXVlbmNlX3Zpc2l0KCd7JywgJ30nKQoKICAgIGRlZiB2aXNpdF9EaWN0KHNlbGYsIG5vZGUpOgogICAgICAgIHNlbGYubWF5YmVfYnJlYWsobm9kZSkKICAgICAgICBzZWxmLnBhcmVuX3N0YXJ0KCd7JykKICAgICAgICBzZXAgPSBTZXAoc2VsZi5DT01NQSkKICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiB6aXAobm9kZS5rZXlzLCBub2RlLnZhbHVlcyk6CiAgICAgICAgICAgIHNlbGYud3JpdGUoc2VwKCkpCiAgICAgICAgICAgIHNlbGYudmlzaXQoa2V5KQogICAgICAgICAgICBzZWxmLndyaXRlKHNlbGYuQ09MT04pCiAgICAgICAgICAgIHNlbGYudmlzaXQodmFsdWUpCiAgICAgICAgc2VsZi5wYXJlbl9lbmQoJ30nKQoKICAgIGRlZiB2aXNpdF9CaW5PcChzZWxmLCBub2RlKToKICAgICAgICBzZWxmLm1heWJlX2JyZWFrKG5vZGUpCiAgICAgICAgc3ltYm9sLCBwcmVjZWRlbmNlID0gc2VsZi5CSU5PUF9TWU1CT0xTW3R5cGUobm9kZS5vcCldCiAgICAgICAgc2VsZi5wcmVjX3N0YXJ0KHByZWNlZGVuY2UsIHR5cGUobm9kZS5vcCkgIT0gUG93KQoKICAgICAgICAjIHdvcmsgYXJvdW5kIHB5dGhvbidzIG5lZ2F0aXZlIGludGVnZXIgbGl0ZXJhbCBvcHRpbWl6YXRpb24KICAgICAgICBpZiBpc2luc3RhbmNlKG5vZGUub3AsIFBvdyk6CiAgICAgICAgICAgIHNlbGYudmlzaXQobm9kZS5sZWZ0KQogICAgICAgICAgICBzZWxmLnByZWNfbWlkZGxlKDE0KQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYudmlzaXQobm9kZS5sZWZ0KQogICAgICAgICAgICBzZWxmLnByZWNfbWlkZGxlKCkKICAgICAgICBzZWxmLndyaXRlKHN5bWJvbCkKICAgICAgICBzZWxmLnZpc2l0KG5vZGUucmlnaHQpCiAgICAgICAgc2VsZi5wcmVjX2VuZCgpCgogICAgZGVmIHZpc2l0X0Jvb2xPcChzZWxmLCBub2RlKToKICAgICAgICBzZWxmLm1heWJlX2JyZWFrKG5vZGUpCiAgICAgICAgc3ltYm9sLCBwcmVjZWRlbmNlID0gc2VsZi5CT09MT1BfU1lNQk9MU1t0eXBlKG5vZGUub3ApXQogICAgICAgIHNlbGYucHJlY19zdGFydChwcmVjZWRlbmNlLCBUcnVlKQogICAgICAgIHNlbGYucHJlY19taWRkbGUoKQogICAgICAgIHNlcCA9IFNlcChzeW1ib2wpCiAgICAgICAgZm9yIHZhbHVlIGluIG5vZGUudmFsdWVzOgogICAgICAgICAgICBzZWxmLndyaXRlKHNlcCgpKQogICAgICAgICAgICBzZWxmLnZpc2l0KHZhbHVlKQogICAgICAgIHNlbGYucHJlY19lbmQoKQoKICAgIGRlZiB2aXNpdF9Db21wYXJlKHNlbGYsIG5vZGUpOgogICAgICAgIHNlbGYubWF5YmVfYnJlYWsobm9kZSkKICAgICAgICBzZWxmLnByZWNfc3RhcnQoNywgVHJ1ZSkKICAgICAgICBzZWxmLnByZWNfbWlkZGxlKCkKICAgICAgICBzZWxmLnZpc2l0KG5vZGUubGVmdCkKICAgICAgICBmb3Igb3AsIHJpZ2h0IGluIHppcChub2RlLm9wcywgbm9kZS5jb21wYXJhdG9ycyk6CiAgICAgICAgICAgIHNlbGYud3JpdGUoc2VsZi5DTVBPUF9TWU1CT0xTW3R5cGUob3ApXVswXSkKICAgICAgICAgICAgc2VsZi52aXNpdChyaWdodCkKICAgICAgICBzZWxmLnByZWNfZW5kKCkKCiAgICBkZWYgdmlzaXRfVW5hcnlPcChzZWxmLCBub2RlKToKICAgICAgICBzZWxmLm1heWJlX2JyZWFrKG5vZGUpCiAgICAgICAgc3ltYm9sLCBwcmVjZWRlbmNlID0gc2VsZi5VTkFSWU9QX1NZTUJPTFNbdHlwZShub2RlLm9wKV0KICAgICAgICBzZWxmLnByZWNfc3RhcnQocHJlY2VkZW5jZSkKICAgICAgICBzZWxmLndyaXRlKHN5bWJvbCkKICAgICAgICAjIHdvcmthcm91bmQ6IGluIHB5dGhvbiAyLCBhbiBleHBsaWNpdCBVU3ViIG5vZGUgYXJvdW5kIGEgbnVtYmVyIGxpdGVyYWwKICAgICAgICAjIGluZGljYXRlcyB0aGUgbGl0ZXJhbCB3YXMgc3Vycm91bmRlZCBieSBwYXJlbnRoZXNpcwogICAgICAgIGlmIChub3QgUFkzIGFuZCBpc2luc3RhbmNlKG5vZGUub3AsIFVTdWIpIGFuZCBpc2luc3RhbmNlKG5vZGUub3BlcmFuZCwgTnVtKSAKICAgICAgICAgICAgICAgIGFuZCAobm9kZS5vcGVyYW5kLm4ucmVhbCBvciBub2RlLm9wZXJhbmQubi5pbWFnKSA+PSAwKToKICAgICAgICAgICAgc2VsZi5wYXJlbl9zdGFydCgpCiAgICAgICAgICAgIHNlbGYudmlzaXQobm9kZS5vcGVyYW5kKQogICAgICAgICAgICBzZWxmLnBhcmVuX2VuZCgpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi52aXNpdChub2RlLm9wZXJhbmQpCiAgICAgICAgc2VsZi5wcmVjX2VuZCgpCgogICAgZGVmIHZpc2l0X1N1YnNjcmlwdChzZWxmLCBub2RlKToKICAgICAgICBzZWxmLm1heWJlX2JyZWFrKG5vZGUpCiAgICAgICAgIyBoYXZlIHRvIHN1cnJvdW5kIGxpdGVyYWxzIGJ5IHBhcmVudGhlc2lzIChhdCBsZWFzdCBpbiBQeTIpCiAgICAgICAgaWYgaXNpbnN0YW5jZShub2RlLnZhbHVlLCBOdW0pOgogICAgICAgICAgICBzZWxmLnBhcmVuX3N0YXJ0KCkKICAgICAgICAgICAgc2VsZi52aXNpdF9OdW0obm9kZS52YWx1ZSkKICAgICAgICAgICAgc2VsZi5wYXJlbl9lbmQoKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYucHJlY19zdGFydCgxNykKICAgICAgICAgICAgc2VsZi52aXNpdChub2RlLnZhbHVlKQogICAgICAgICAgICBzZWxmLnByZWNfZW5kKCkKICAgICAgICBzZWxmLnBhcmVuX3N0YXJ0KCdbJykKICAgICAgICBzZWxmLnZpc2l0KG5vZGUuc2xpY2UpCiAgICAgICAgc2VsZi5wYXJlbl9lbmQoJ10nKQoKICAgIGRlZiB2aXNpdF9JbmRleChzZWxmLCBub2RlLCBndWFyZD1GYWxzZSk6CiAgICAgICAgIyBJbmRleCBoYXMgbm8gbGluZW5vIGluZm9ybWF0aW9uCiAgICAgICAgIyBXaGVuIGEgc3Vic2NyaXB0IGluY2x1ZGVzIGEgdHVwbGUgZGlyZWN0bHksIHRoZSBwYXJlbnRoZXNpcyBjYW4gYmUgZHJvcHBlZAogICAgICAgIGlmIG5vdCBndWFyZDoKICAgICAgICAgICAgc2VsZi52aXNpdF9iYXJlKG5vZGUudmFsdWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi52aXNpdChub2RlLnZhbHVlKQoKICAgIGRlZiB2aXNpdF9TbGljZShzZWxmLCBub2RlKToKICAgICAgICAjIFNsaWNlIGhhcyBubyBsaW5lbm8gaW5mb3JtYXRpb24KICAgICAgICBpZiBub2RlLmxvd2VyIGlzIG5vdCBOb25lOgogICAgICAgICAgICBzZWxmLnZpc2l0KG5vZGUubG93ZXIpCiAgICAgICAgc2VsZi53cml0ZSgnOicpCiAgICAgICAgaWYgbm9kZS51cHBlciBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi52aXNpdChub2RlLnVwcGVyKQogICAgICAgIGlmIG5vZGUuc3RlcCBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi53cml0ZSgnOicpCiAgICAgICAgICAgIGlmIG5vdCAoaXNpbnN0YW5jZShub2RlLnN0ZXAsIE5hbWUpIGFuZCBub2RlLnN0ZXAuaWQgPT0gJ05vbmUnKToKICAgICAgICAgICAgICAgIHNlbGYudmlzaXQobm9kZS5zdGVwKQoKICAgIGRlZiB2aXNpdF9FbGxpcHNpcyhzZWxmLCBub2RlKToKICAgICAgICAjIEVsbGlwc2lzIGhhcyBubyBsaW5lbm8gaW5mb3JtYXRpb24KICAgICAgICBzZWxmLndyaXRlKCcuLi4nKQoKICAgIGRlZiB2aXNpdF9FeHRTbGljZShzZWxmLCBub2RlKToKICAgICAgICAjIEV4dHNsaWNlIGhhcyBubyBsaW5lbm8gaW5mb3JtYXRpb24KICAgICAgICBmb3IgaWR4LCBpdGVtIGluIGVudW1lcmF0ZShub2RlLmRpbXMpOgogICAgICAgICAgICBpZiBpZHg6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKHNlbGYuQ09NTUEpCiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UoaXRlbSwgSW5kZXgpOgogICAgICAgICAgICAgICAgc2VsZi52aXNpdF9JbmRleChpdGVtLCBUcnVlKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi52aXNpdChpdGVtKQoKICAgIGRlZiB2aXNpdF9ZaWVsZChzZWxmLCBub2RlLCBwYXJlbj1UcnVlKToKICAgICAgICAjIHlpZWxkIGNhbiBvbmx5IGJlIHVzZWQgaW4gYSBzdGF0ZW1lbnQgY29udGV4dCwgb3Igd2UncmUgYmV0d2VlbiBwYXJlbnRoZXNpcwogICAgICAgIHNlbGYubWF5YmVfYnJlYWsobm9kZSkKICAgICAgICBpZiBwYXJlbjoKICAgICAgICAgICAgc2VsZi5wYXJlbl9zdGFydCgpCiAgICAgICAgaWYgbm9kZS52YWx1ZSBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi53cml0ZSgneWllbGQgJykKICAgICAgICAgICAgc2VsZi52aXNpdF9iYXJlKG5vZGUudmFsdWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi53cml0ZSgneWllbGQnKQogICAgICAgIGlmIHBhcmVuOgogICAgICAgICAgICBzZWxmLnBhcmVuX2VuZCgpCgogICAgZGVmIHZpc2l0X1lpZWxkRnJvbShzZWxmLCBub2RlLCBwYXJlbj1UcnVlKToKICAgICAgICAjIEV2ZW4gdGhvdWdoIHlpZWxkIGFuZCB5aWVsZCBmcm9tIHRlY2huaWNhbGx5IG9jY3VweSBwcmVjZWRlbmNlIGxldmVsIDEsIGNlcnRhaW4gY29kZQogICAgICAgICMgdXNpbmcgdGhlbSBpcyBpbGxlZ2FsIGUuZy4gInJldHVybiB5aWVsZCBmcm9tIGEoKSIgd2lsbCBub3Qgd29yayB1bmxlc3MgeW91IAogICAgICAgICMgcHV0IHRoZSB5aWVsZCBmcm9tIHN0YXRlbWVudCB3aXRoaW4gcGFyZW50aGVzaXMuIAogICAgICAgIHNlbGYubWF5YmVfYnJlYWsobm9kZSkKICAgICAgICBpZiBwYXJlbjoKICAgICAgICAgICAgc2VsZi5wYXJlbl9zdGFydCgpCiAgICAgICAgc2VsZi53cml0ZSgneWllbGQgZnJvbSAnKQogICAgICAgIHNlbGYudmlzaXQobm9kZS52YWx1ZSkKICAgICAgICBpZiBwYXJlbjoKICAgICAgICAgICAgc2VsZi5wYXJlbl9lbmQoKQoKICAgIGRlZiB2aXNpdF9MYW1iZGEoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5tYXliZV9icmVhayhub2RlKQogICAgICAgIHNlbGYucHJlY19zdGFydCgyKQogICAgICAgIHNlbGYud3JpdGUoJ2xhbWJkYSAnKQogICAgICAgIHNlbGYudmlzaXRfYXJndW1lbnRzKG5vZGUuYXJncykKICAgICAgICBzZWxmLndyaXRlKHNlbGYuQ09MT04pCiAgICAgICAgc2VsZi52aXNpdChub2RlLmJvZHkpCiAgICAgICAgc2VsZi5wcmVjX2VuZCgpCgogICAgZGVmIF9nZW5lcmF0b3JfdmlzaXQobGVmdCwgcmlnaHQpOgogICAgICAgIGRlZiB2aXNpdChzZWxmLCBub2RlKToKICAgICAgICAgICAgc2VsZi5tYXliZV9icmVhayhub2RlKQogICAgICAgICAgICBzZWxmLnBhcmVuX3N0YXJ0KGxlZnQpCiAgICAgICAgICAgIHNlbGYudmlzaXQobm9kZS5lbHQpCiAgICAgICAgICAgIGZvciBjb21wcmVoZW5zaW9uIGluIG5vZGUuZ2VuZXJhdG9yczoKICAgICAgICAgICAgICAgIHNlbGYudmlzaXQoY29tcHJlaGVuc2lvbikKICAgICAgICAgICAgc2VsZi5wYXJlbl9lbmQocmlnaHQpCiAgICAgICAgcmV0dXJuIHZpc2l0CgogICAgdmlzaXRfTGlzdENvbXAgPSBfZ2VuZXJhdG9yX3Zpc2l0KCdbJywgJ10nKQogICAgdmlzaXRfR2VuZXJhdG9yRXhwID0gX2dlbmVyYXRvcl92aXNpdCgnKCcsICcpJykKICAgIHZpc2l0X1NldENvbXAgPSBfZ2VuZXJhdG9yX3Zpc2l0KCd7JywgJ30nKQoKICAgIGRlZiB2aXNpdF9EaWN0Q29tcChzZWxmLCBub2RlKToKICAgICAgICBzZWxmLm1heWJlX2JyZWFrKG5vZGUpCiAgICAgICAgc2VsZi5wYXJlbl9zdGFydCgneycpCiAgICAgICAgc2VsZi52aXNpdChub2RlLmtleSkKICAgICAgICBzZWxmLndyaXRlKHNlbGYuQ09MT04pCiAgICAgICAgc2VsZi52aXNpdChub2RlLnZhbHVlKQogICAgICAgIGZvciBjb21wcmVoZW5zaW9uIGluIG5vZGUuZ2VuZXJhdG9yczoKICAgICAgICAgICAgc2VsZi52aXNpdChjb21wcmVoZW5zaW9uKQogICAgICAgIHNlbGYucGFyZW5fZW5kKCd9JykKCiAgICBkZWYgdmlzaXRfSWZFeHAoc2VsZiwgbm9kZSk6CiAgICAgICAgc2VsZi5tYXliZV9icmVhayhub2RlKQogICAgICAgIHNlbGYucHJlY19zdGFydCgzLCBGYWxzZSkKICAgICAgICBzZWxmLnZpc2l0KG5vZGUuYm9keSkKICAgICAgICBzZWxmLndyaXRlKCcgaWYgJykKICAgICAgICBzZWxmLnZpc2l0KG5vZGUudGVzdCkKICAgICAgICBzZWxmLnByZWNfbWlkZGxlKDIpCiAgICAgICAgc2VsZi53cml0ZSgnIGVsc2UgJykKICAgICAgICBzZWxmLnZpc2l0KG5vZGUub3JlbHNlKQogICAgICAgIHNlbGYucHJlY19lbmQoKQoKICAgIGRlZiB2aXNpdF9TdGFycmVkKHNlbGYsIG5vZGUpOgogICAgICAgIHNlbGYubWF5YmVfYnJlYWsobm9kZSkKICAgICAgICBzZWxmLndyaXRlKCcqJykKICAgICAgICBzZWxmLnZpc2l0KG5vZGUudmFsdWUpCgogICAgZGVmIHZpc2l0X1JlcHIoc2VsZiwgbm9kZSk6CiAgICAgICAgIyBYWFg6IHB5dGhvbiAyLjYgb25seQogICAgICAgIHNlbGYubWF5YmVfYnJlYWsobm9kZSkKICAgICAgICBzZWxmLndyaXRlKCdgJykKICAgICAgICBzZWxmLnZpc2l0KG5vZGUudmFsdWUpCiAgICAgICAgc2VsZi53cml0ZSgnYCcpCgogICAgIyBIZWxwZXIgTm9kZXMKCiAgICBkZWYgdmlzaXRfYWxpYXMoc2VsZiwgbm9kZSk6CiAgICAgICAgIyBhbGlhcyBkb2VzIG5vdCBoYXZlIGxpbmUgbnVtYmVyIGluZm9ybWF0aW9uCiAgICAgICAgc2VsZi53cml0ZShub2RlLm5hbWUpCiAgICAgICAgaWYgbm9kZS5hc25hbWUgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJyBhcyAnICsgbm9kZS5hc25hbWUpCgogICAgZGVmIHZpc2l0X2NvbXByZWhlbnNpb24oc2VsZiwg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AAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMDAwIAAwMDAwMDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIyBDb3B5cmlnaHQgKGMpIDIwMTUgQ2Vuc29yZWRVc2VybmFtZQoKIyBUaGlzIG1vZHVsZSBwcm92aWRlcyB0b29scyBmb3Igc2FmZWx5IGFuYWx5aXppbmcgcGlja2xlIGZpbGVzIHByb2dyYW1tYXRpY2FsbHkKCmltcG9ydCBzeXMKClBZMyA9IHN5cy52ZXJzaW9uX2luZm8gPj0gKDMsIDApClBZMiA9IG5vdCBQWTMKCmltcG9ydCB0eXBlcwppbXBvcnQgcGlja2xlCmltcG9ydCBzdHJ1Y3QKCmlmIFBZMzoKICAgIGZyb20gaW8gaW1wb3J0IEJ5dGVzSU8gYXMgU3RyaW5nSU8KZWxzZToKICAgIGZyb20gY1N0cmluZ0lPIGltcG9ydCBTdHJpbmdJTwoKX19hbGxfXyA9IFsKICAgICJsb2FkIiwgImxvYWRzIiwgInNhZmVfbG9hZCIsICJzYWZlX2xvYWRzIiwgInNhZmVfZHVtcCIsICJzYWZlX2R1bXBzIiwKICAgICJmYWtlX3BhY2thZ2UiLCAicmVtb3ZlX2Zha2VfcGFja2FnZSIsCiAgICAiRmFrZU1vZHVsZSIsICJGYWtlUGFja2FnZSIsICJGYWtlUGFja2FnZUxvYWRlciIsCiAgICAiRmFrZUNsYXNzVHlwZSIsICJGYWtlQ2xhc3NGYWN0b3J5IiwKICAgICJGYWtlQ2xhc3MiLCAiRmFrZVN0cmljdCIsICJGYWtlV2FybmluZyIsICJGYWtlSWdub3JlIiwKICAgICJGYWtlVW5waWNrbGluZ0Vycm9yIiwgIkZha2VVbnBpY2tsZXIiLCAiU2FmZVVucGlja2xlciIsCiAgICAiU2FmZVBpY2tsZXIiCl0KCiMgRmFrZSBjbGFzcyBpbXBsZW1lbnRhdGlvbgoKY2xhc3MgRmFrZUNsYXNzVHlwZSh0eXBlKToKICAgICIiIgogICAgVGhlIG1ldGFjbGFzcyB1c2VkIHRvIGNyZWF0ZSBmYWtlIGNsYXNzZXMuIFRvIHN1cHBvcnQgY29tcGFyaXNvbnMgYmV0d2VlbgogICAgZmFrZSBjbGFzc2VzIGFuZCA6Y2xhc3M6YEZha2VNb2R1bGVgIGluc3RhbmNlcyBjdXN0b20gYmVoYXZpb3VyIGlzIGRlZmluZWQKICAgIGhlcmUgd2hpY2ggZm9sbG93cyB0aGlzIGxvZ2ljOgoKICAgIElmIHRoZSBvdGhlciBvYmplY3QgZG9lcyBub3QgaGF2ZSBgYG90aGVyLl9fbmFtZV9fYGAgc2V0LCB0aGV5IGFyZSBub3QgZXF1YWwuCgogICAgRWxzZSBpZiBpdCBkb2VzIG5vdCBoYXZlIGBgb3RoZXIuX19tb2R1bGVfX2BgIHNldCwgdGhleSBhcmUgZXF1YWwgaWYKICAgIGBgc2VsZi5fX21vZHVsZV9fICsgIi4iICsgc2VsZi5fX25hbWVfXyA9PSBvdGhlci5fX25hbWVfX2BgLgoKICAgIEVsc2UsIHRoZXkgYXJlIGVxdWFsIGlmCiAgICBgYHNlbGYuX19tb2R1bGVfXyA9PSBvdGhlci5fX21vZHVsZV9fIGFuZCBzZWxmLl9fbmFtZV9fID09IG90aGVyLl9fbmFtZV9fYGAKCiAgICBVc2luZyB0aGlzIGJlaGF2aW91ciwgYGA9PWBgLCBgYCE9YGAsIGBgaGFzaCgpYGAsIGBgaXNpbnN0YW5jZSgpYGAgYW5kIGBgaXNzdWJjbGFzcygpYGAKICAgIGFyZSBpbXBsZW1lbnRlZCBhbGxvd2luZyBjb21wYXJpc29uIGJldHdlZW4gOmNsYXNzOmBGYWtlQ2xhc3NUeXBlYCBpbnN0YW5jZXMKICAgIGFuZCA6Y2xhc3M6YEZha2VNb2R1bGVgIGluc3RhbmNlcyB0byBzdWNjZWVkIGlmIHRoZXkgYXJlIHByZXRlbmRpbmcgdG8gYmUgaW4gdGhlIHNhbWUKICAgIHBsYWNlIGluIHRoZSBweXRob24gbW9kdWxlIGhpZXJhcmNoeS4KCiAgICBUbyBjcmVhdGUgYSBmYWtlIGNsYXNzIHVzaW5nIHRoaXMgbWV0YWNsYXNzLCB5b3UgY2FuIGVpdGhlciB1c2UgdGhpcyBtZXRhY2xhc3MgZGlyZWN0bHkgb3IKICAgIGluaGVyaXQgZnJvbSB0aGUgZmFrZSBjbGFzcyBiYXNlIGluc3RhbmNlcyBnaXZlbiBiZWxvdy4gV2hlbiBkb2luZyB0aGlzLCB0aGUgbW9kdWxlIHRoYXQKICAgIHRoaXMgZmFrZSBjbGFzcyBpcyBwcmV0ZW5kaW5nIHRvIGJlIGluIHNob3VsZCBiZSBzcGVjaWZpZWQgdXNpbmcgdGhlICptb2R1bGUqIGFyZ3VtZW50CiAgICB3aGVuIHRoZSBtZXRhY2xhc3MgaXMgY2FsbGVkIGRpcmVjdGx5IG9yIGEgOmF0dHI6YGBfX21vZHVsZV9fYGAgY2xhc3MgYXR0cmlidXRlIGluIGEgY2xhc3Mgc3RhdGVtZW50LgoKICAgIFRoaXMgaXMgYSBzdWJjbGFzcyBvZiA6Y2xhc3M6YHR5cGVgLgogICAgIiIiCgogICAgIyBpbnN0YW5jZSBjcmVhdGlvbiBsb2dpYwoKICAgIGRlZiBfX25ld19fKGNscywgbmFtZSwgYmFzZXMsIGF0dHJpYnV0ZXMsIG1vZHVsZT1Ob25lKToKICAgICAgICAjIFRoaXMgd291bGQgYmUgYSBsaWUKICAgICAgICBhdHRyaWJ1dGVzLnBvcCgiX19xdWFsbmFtZV9fIiwgTm9uZSkKCiAgICAgICAgIyBmaWd1cmUgb3V0IHdoYXQgbW9kdWxlIHdlIHNob3VsZCBzYXkgd2UncmUgaW4KICAgICAgICAjIG5vdGUgdGhhdCBpZiBubyBtb2R1bGUgaXMgZXhwbGljaXRseSBwYXNzZWQsIHRoZSBjdXJyZW50IG1vZHVsZSB3aWxsIGJlIGNob3NlbgogICAgICAgICMgZHVlIHRvIHRoZSBjbGFzcyBzdGF0ZW1lbnQgaW1wbGljaXRseSBzcGVjaWZ5aW5nIF9fbW9kdWxlX18gYXMgX19uYW1lX18KICAgICAgICBpZiBtb2R1bGUgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIGF0dHJpYnV0ZXNbIl9fbW9kdWxlX18iXSA9IG1vZHVsZQoKICAgICAgICBpZiAiX19tb2R1bGVfXyIgbm90IGluIGF0dHJpYnV0ZXM6CiAgICAgICAgICAgIHJhaXNlIFR5cGVFcnJvcigiTm8gbW9kdWxlIGhhcyBiZWVuIHNwZWNpZmllZCBmb3IgRmFrZUNsYXNzVHlwZSB7MH0iLmZvcm1hdChuYW1lKSkKCiAgICAgICAgIyBhc3NlbWJsZSBpbnN0YW5jZQogICAgICAgIHJldHVybiB0eXBlLl9fbmV3X18oY2xzLCBuYW1lLCBiYXNlcywgYXR0cmlidXRlcykKCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSwgYmFzZXMsIGF0dHJpYnV0ZXMsIG1vZHVsZT1Ob25lKToKICAgICAgICB0eXBlLl9faW5pdF9fKHNlbGYsIG5hbWUsIGJhc2VzLCBhdHRyaWJ1dGVzKQoKICAgICMgY29tcGFyaXNvbiBsb2dpYwoKICAgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgogICAgICAgIGlmIG5vdCBoYXNhdHRyKG90aGVyLCAiX19uYW1lX18iKToKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgaWYgaGFzYXR0cihvdGhlciwgIl9fbW9kdWxlX18iKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX19tb2R1bGVfXyA9PSBvdGhlci5fX21vZHVsZV9fIGFuZCBzZWxmLl9fbmFtZV9fID09IG90aGVyLl9fbmFtZV9fCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX19tb2R1bGVfXyArICIuIiArIHNlbGYuX19uYW1lX18gPT0gb3RoZXIuX19uYW1lX18KCiAgICBkZWYgX19uZV9fKHNlbGYsIG90aGVyKToKICAgICAgICByZXR1cm4gbm90IHNlbGYgPT0gb3RoZXIKCiAgICBkZWYgX19oYXNoX18oc2VsZik6CiAgICAgICAgcmV0dXJuIGhhc2goc2VsZi5fX21vZHVsZV9fICsgIi4iICsgc2VsZi5fX25hbWVfXykKCiAgICBkZWYgX19pbnN0YW5jZWNoZWNrX18oc2VsZiwgaW5zdGFuY2UpOgogICAgICAgIHJldHVybiBzZWxmLl9fc3ViY2xhc3NjaGVja19fKGluc3RhbmNlLl9fY2xhc3NfXykKCiAgICBkZWYgX19zdWJjbGFzc2NoZWNrX18oc2VsZiwgc3ViY2xhc3MpOgogICAgICAgIHJldHVybiAoc2VsZiA9PSBzdWJjbGFzcyBvcgogICAgICAgICAgICAgICAgKGJvb2woc3ViY2xhc3MuX19iYXNlc19fKSBhbmQKICAgICAgICAgICAgICAgICBhbnkoc2VsZi5fX3N1YmNsYXNzY2hlY2tfXyhiYXNlKSBmb3IgYmFzZSBpbiBzdWJjbGFzcy5fX2Jhc2VzX18pKSkKCiMgUFkyIGRvZXNuJ3QgbGlrZSB0aGUgUFkzIHdheSBvZiBtZXRhY2xhc3NlcyBhbmQgUFkzIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgUFkyIHdheQojIHNvIHdlIGNhbGwgdGhlIG1ldGFjbGFzcyBkaXJlY3RseQpGYWtlQ2xhc3MgPSBGYWtlQ2xhc3NUeXBlKCJGYWtlQ2xhc3MiLCAoKSwgeyJfX2RvY19fIjogIiIiCkEgYmFyZWJvbmVzIGluc3RhbmNlIG9mIDpjbGFzczpgRmFrZUNsYXNzVHlwZWAuIEluaGVyaXQgZnJvbSB0aGlzIHRvIGNyZWF0ZSBmYWtlIGNsYXNzZXMuCiIiIn0sIG1vZHVsZT1fX25hbWVfXykKCmNsYXNzIEZha2VTdHJpY3QoRmFrZUNsYXNzLCBvYmplY3QpOgogICAgZGVmIF9fbmV3X18oY2xzLCAqYXJncywgKiprd2FyZ3MpOgogICAgICAgIHNlbGYgPSBGYWtlQ2xhc3MuX19uZXdfXyhjbHMpCiAgICAgICAgaWYgYXJncyBvciBrd2FyZ3M6CiAgICAgICAgICAgIHJhaXNlIEZha2VVbnBpY2tsaW5nRXJyb3IoInswfSB3YXMgaW5zdGFudGlhdGVkIHdpdGggdW5leHBlY3RlZCBhcmd1bWVudHMgezF9LCB7Mn0iLmZvcm1hdChjbHMsIGFyZ3MsIGt3YXJncykpCiAgICAgICAgcmV0dXJuIHNlbGYKCiAgICBkZWYgX19zZXRzdGF0ZV9fKHNlbGYsIHN0YXRlKToKICAgICAgICBzbG90c3RhdGUgPSBOb25lCgogICAgICAgIGlmIChpc2luc3RhbmNlKHN0YXRlLCB0dXBsZSkgYW5kIGxlbihzdGF0ZSkgPT0gMiBhbmQKICAgICAgICAgICAgKHN0YXRlWzBdIGlzIE5vbmUgb3IgaXNpbnN0YW5jZShzdGF0ZVswXSwgZGljdCkpIGFuZAogICAgICAgICAgICAoc3RhdGVbMV0gaXMgTm9uZSBvciBpc2luc3RhbmNlKHN0YXRlWzFdLCBkaWN0KSkpOgogICAgICAgICAgICBzdGF0ZSwgc2xvdHN0YXRlID0gc3RhdGUKCiAgICAgICAgaWYgc3RhdGU6CiAgICAgICAgICAgICMgRG9uJ3QgaGF2ZSB0byBjaGVjayBmb3Igc2xvdHN0YXRlIGhlcmUgc2luY2UgaXQncyBlaXRoZXIgTm9uZSBvciBhIGRpY3QKICAgICAgICAgICAgaWYgbm90IGlzaW5zdGFuY2Uoc3RhdGUsIGRpY3QpOgogICAgICAgICAgICAgICAgcmFpc2UgRmFrZVVucGlja2xpbmdFcnJvcigiezB9Ll9fc2V0c3RhdGVfXygpIGdvdCB1bmV4cGVjdGVkIGFyZ3VtZW50cyB7MX0iLmZvcm1hdChzZWxmLl9fY2xhc3NfXywgc3RhdGUpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5fX2RpY3RfXy51cGRhdGUoc3RhdGUpCgogICAgICAgIGlmIHNsb3RzdGF0ZToKICAgICAgICAgICAgc2VsZi5fX2RpY3RfXy51cGRhdGUoc2xvdHN0YXRlKQoKY2xhc3MgRmFrZVdhcm5pbmcoRmFrZUNsYXNzLCBvYmplY3QpOgogICAgZGVmIF9fbmV3X18oY2xzLCAqYXJncywgKiprd2FyZ3MpOgogICAgICAgIHNlbGYgPSBGYWtlQ2xhc3MuX19uZXdfXyhjbHMpCiAgICAgICAgaWYgYXJncyBvciBrd2FyZ3M6CiAgICAgICAgICAgIHByaW50KCJ7MH0gd2FzIGluc3RhbnRpYXRlZCB3aXRoIHVuZXhwZWN0ZWQgYXJndW1lbnRzIHsxfSwgezJ9Ii5mb3JtYXQoY2xzLCBhcmdzLCBrd2FyZ3MpKQogICAgICAgICAgICBzZWxmLl9uZXdfYXJncyA9IGFyZ3MKICAgICAgICByZXR1cm4gc2VsZgoKICAgIGRlZiBfX3NldHN0YXRlX18oc2VsZiwgc3RhdGUpOgogICAgICAgIHNsb3RzdGF0ZSA9IE5vbmUKCiAgICAgICAgaWYgKGlzaW5zdGFuY2Uoc3RhdGUsIHR1cGxlKSBhbmQgbGVuKHN0YXRlKSA9PSAyIGFuZAogICAgICAgICAgICAoc3RhdGVbMF0gaXMgTm9uZSBvciBpc2luc3RhbmNlKHN0YXRlWzBdLCBkaWN0KSkgYW5kCiAgICAgICAgICAgIChzdGF0ZVsxXSBpcyBOb25lIG9yIGlzaW5zdGFuY2Uoc3RhdGVbMV0sIGRpY3QpKSk6CiAgICAgICAgICAgIHN0YXRlLCBzbG90c3RhdGUgPSBzdGF0ZQoKICAgICAgICBpZiBzdGF0ZToKICAgICAgICAgICAgIyBEb24ndCBoYXZlIHRvIGNoZWNrIGZvciBzbG90c3RhdGUgaGVyZSBzaW5jZSBpdCdzIGVpdGhlciBOb25lIG9yIGEgZGljdAogICAgICAgICAgICBpZiBub3QgaXNpbnN0YW5jZShzdGF0ZSwgZGljdCk6CiAgICAgICAgICAgICAgICBwcmludCgiezB9Ll9fc2V0c3RhdGVfXygpIGdvdCB1bmV4cGVjdGVkIGFyZ3VtZW50cyB7MX0iLmZvcm1hdChzZWxmLl9fY2xhc3NfXywgc3RhdGUpKQogICAgICAgICAgICAgICAgc2VsZi5fc2V0c3RhdGVfYXJncyA9IHN0YXRlCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLl9fZGljdF9fLnVwZGF0ZShzdGF0ZSkKCiAgICAgICAgaWYgc2xvdHN0YXRlOgogICAgICAgICAgICBzZWxmLl9fZGljdF9fLnVwZGF0ZShzbG90c3RhdGUpCgpjbGFzcyBGYWtlSWdub3JlKEZha2VDbGFzcywgb2JqZWN0KToKICAgIGRlZiBfX25ld19fKGNscywgKmFyZ3MsICoqa3dhcmdzKToKICAgICAgICBzZWxmID0gRmFrZUNsYXNzLl9fbmV3X18oY2xzKQogICAgICAgIGlmIGFyZ3M6CiAgICAgICAgICAgIHNlbGYuX25ld19hcmdzID0gYXJncwogICAgICAgIGlmIGt3YXJnczoKICAgICAgICAgICAgc2VsZi5fbmV3X2t3YXJncyA9IGt3YXJncwogICAgICAgIHJldHVybiBzZWxmCgogICAgZGVmIF9fc2V0c3RhdGVfXyhzZWxmLCBzdGF0ZSk6CiAgICAgICAgc2xvdHN0YXRlID0gTm9uZQoKICAgICAgICBpZiAoaXNpbnN0YW5jZShzdGF0ZSwgdHVwbGUpIGFuZCBsZW4oc3RhdGUpID09IDIgYW5kCiAgICAgICAgICAgIChzdGF0ZVswXSBpcyBOb25lIG9yIGlzaW5zdGFuY2Uoc3RhdGVbMF0sIGRpY3QpKSBhbmQKICAgICAgICAgICAgKHN0YXRlWzFdIGlzIE5vbmUgb3IgaXNpbnN0YW5jZShzdGF0ZVsxXSwgZGljdCkpKToKICAgICAgICAgICAgc3RhdGUsIHNsb3RzdGF0ZSA9IHN0YXRlCgogICAgICAgIGlmIHN0YXRlOgogICAgICAgICAgICAjIERvbid0IGhhdmUgdG8gY2hlY2sgZm9yIHNsb3RzdGF0ZSBoZXJlIHNpbmNlIGl0J3MgZWl0aGVyIE5vbmUgb3IgYSBkaWN0CiAgICAgICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKHN0YXRlLCBkaWN0KToKICAgICAgICAgICAgICAgIHNlbGYuX3NldHN0YXRlX2FyZ3MgPSBzdGF0ZQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5fX2RpY3RfXy51cGRhdGUoc3RhdGUpCgogICAgICAgIGlmIHNsb3RzdGF0ZToKICAgICAgICAgICAgc2VsZi5fX2RpY3RfXy51cGRhdGUoc2xvdHN0YXRlKQoKY2xhc3MgRmFrZUNsYXNzRmFjdG9yeShvYmplY3QpOgogICAgIiIiCiAgICBGYWN0b3J5IG9mIGZha2UgY2xhc3NzZXMuIEl0IHdpbGwgY3JlYXRlIGZha2UgY2xhc3MgZGVmaW5pdGlvbnMgb24gZGVtYW5kCiAgICBiYXNlZCBvbiB0aGUgcGFzc2VkIGFyZ3VtZW50cy4KICAgICIiIgoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBzcGVjaWFsX2Nhc2VzPSgpLCBkZWZhdWx0X2NsYXNzPUZha2VTdHJpY3QpOgogICAgICAgICIiIgogICAgICAgICpzcGVjaWFsX2Nhc2VzKiBzaG91bGQgYmUgYW4gaXRlcmFibGUgY29udGFpbmluZyBmYWtlIGNsYXNzZXMgd2hpY2ggc2hvdWxkIGJlIHRyZWF0ZWQKICAgICAgICBhcyBzcGVjaWFsIGNhc2VzIGR1cmluZyB0aGUgZmFrZSB1bnBpY2tsaW5nIHByb2Nlc3MuIFRoaXMgd2F5IHlvdSBjYW4gc3BlY2lmeSBjdXN0b20gbWV0aG9kcwogICAgICAgIGFuZCBhdHRyaWJ1dGVzIG9uIHRoZXNlIGNsYXNzZXMgYXMgdGhleSdyZSB1c2VkIGR1cmluZyB1bnBpY2tsaW5nLgoKICAgICAgICAqZGVmYXVsdF9jbGFzcyogc2hvdWxkIGJlIGEgRmFrZUNsYXNzVHlwZSBpbnN0YW5jZSB3aGljaCB3aWxsIGJlIHN1YmNsYXNzZWQgdG8gY3JlYXRlIHRoZQogICAgICAgIG5lY2Vzc2FyeSBub24tc3BlY2lhbCBjYXNlIGZha2UgY2xhc3NlcyBkdXJpbmcgdW5waWNrbGluZy4gVGhpcyBzaG91bGQgdXN1YWxseSBiZSBzZXQgdG8KICAgICAgICA6Y2xhc3M6YEZha2VTdHJpY3RgLCA6Y2xhc3M6YEZha2VXYXJuaW5nYCBvciA6Y2xhc3M6YEZha2VJZ25vcmVgLiBUaGVzZSBjbGFzc2VzIGhhdmUKICAgICAgICA6bWV0aDpgX19uZXdfX2AgYW5kIDptZXRoOmBfX3NldHN0YXRlX19gIG1ldGhvZHMgd2hpY2ggZXh0cmFjdCBkYXRhIGZyb20gdGhlIHBpY2tsZSBzdHJlYW0KICAgICAgICBhbmQgcHJvdmlkZSBtZWFucyBvZiBpbnNwZWN0aW5nIHRoZSBzdHJlYW0gd2hlbiBpdCBpcyBub3QgY2xlYXIgaG93IHRoZSBkYXRhIHNob3VsZCBiZSBpbnRlcnByZXRlZC4KCiAgICAgICAgQXMgYW4gZXhhbXBsZSwgd2UgY2FuIGRlZmluZSB0aGUgZmFrZSBjbGFzcyBnZW5lcmF0ZWQgZm9yIGRlZmluaXRpb24gYmFyIGluIG1vZHVsZSBmb28sCiAgICAgICAgd2hpY2ggaGFzIGEgOm1ldGg6YF9fc3RyX19gIG1ldGhvZCB3aGljaCByZXR1cm5zIGBgImJheiJgYDo6CgogICAgICAgICAgIGNsYXNzIGJhcihGYWtlU3RyaWN0LCBvYmplY3QpOgogICAgICAgICAgICAgICBkZWYgX19zdHJfXyhzZWxmKToKICAgICAgICAgICAgICAgICAgIHJldHVybiAiYmF6IgoKICAgICAgICAgICBzcGVjaWFsX2Nhc2VzID0gW2Jhcl0KCiAgICAgICAgQWx0ZXJuYXRpdmVseSB0aGV5IGNhbiBhbHNvIGJlIGluc3RhbnRpYXRlZCB1c2luZyA6Y2xhc3M6YEZha2VDbGFzc1R5cGVgIGRpcmVjdGx5OjoKICAgICAgICAgICBzcGVjaWFsX2Nhc2VzID0gW0Zha2VDbGFzc1R5cGUoYy5fX25hbWVfXywgYy5fX2Jhc2VzX18sIGMuX19kaWN0X18sIGMuX19tb2R1bGVfXyldCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5zcGVjaWFsX2Nhc2VzID0gZGljdCgoKGkuX19tb2R1bGVfXywgaS5fX25hbWVfXyksIGkpIGZvciBpIGluIHNwZWNpYWxfY2FzZXMpCiAgICAgICAgc2VsZi5kZWZhdWx0ID0gZGVmYXVsdF9jbGFzcwoKICAgICAgICBzZWxmLmNsYXNzX2NhY2hlID0ge30KCiAgICBkZWYgX19jYWxsX18oc2VsZiwgbmFtZSwgbW9kdWxlKToKICAgICAgICAiIiIKICAgICAgICBSZXR1cm4gdGhlIHJpZ2h0IGNsYXNzIGZvciB0aGUgc3BlY2lmaWVkICptb2R1bGUqIGFuZCAqbmFtZSouCgogICAgICAgIFRoaXMgY2xhc3Mgd2lsbCBlaXRoZXIgYmUgb25lIG9mIHRoZSBzcGVjaWFsIGNhc2VzIGluIGNhc2UgdGhlIG5hbWUgYW5kIG1vZHVsZSBtYXRjaCwKICAgICAgICBvciBhIHN1YmNsYXNzIG9mICpkZWZhdWx0X2NsYXNzKiB3aWxsIGJlIGNyZWF0ZWQgd2l0aCB0aGUgY29ycmVjdCBuYW1lIGFuZCBtb2R1bGUuCgogICAgICAgIENyZWF0ZWQgY2xhc3MgZGVmaW5pdGlvbnMgYXJlIGNhY2hlZCBwZXIgZmFjdG9yeSBpbnN0YW5jZS4KICAgICAgICAiIiIKICAgICAgICAjIENoZWNrIGlmIHdlJ3ZlIGdvdCB0aGlzIGNsYXNzIGNhY2hlZAogICAgICAgIGtsYXNzID0gc2VsZi5jbGFzc19jYWNoZS5nZXQoKG1vZHVsZSwgbmFtZSksIE5vbmUpCiAgICAgICAgaWYga2xhc3MgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHJldHVybiBrbGFzcwoKICAgICAgICBrbGFzcyA9IHNlbGYuc3BlY2lhbF9jYXNlcy5nZXQoKG1vZHVsZSwgbmFtZSksIE5vbmUpCgogICAgICAgIGlmIG5vdCBrbGFzczoKICAgICAgICAgICAgIyBnZW5lcmF0ZSBhIG5ldyBjbGFzcyBkZWYgd2hpY2ggaW5oZXJpdHMgZnJvbSB0aGUgZGVmYXVsdCBmYWtlIGNsYXNzCiAgICAgICAgICAgIGtsYXNzID0gdHlwZShuYW1lLCAoc2VsZi5kZWZhdWx0LCksIHsiX19tb2R1bGVfXyI6IG1vZHVsZX0pCgogICAgICAgIHNlbGYuY2xhc3NfY2FjaGVbKG1vZHVsZSwgbmFtZSldID0ga2xhc3MKICAgICAgICByZXR1cm4ga2xhc3MKCiMgRmFrZSBtb2R1bGUgaW1wbGVtZW50YXRpb24KCmNsYXNzIEZha2VNb2R1bGUodHlwZXMuTW9kdWxlVHlwZSk6CiAgICAiIiIKICAgIEFuIG9iamVjdCB3aGljaCBwcmV0ZW5kcyB0byBiZSBhIG1vZHVsZS4KCiAgICAqbmFtZSogaXMgdGhlIG5hbWUgb2YgdGhlIG1vZHVsZSBhbmQgc2hvdWxkIGJlIGEgYGAiLiJgYCBzZXBhcmF0ZWQKICAgIGFscGhhbnVtZXJpYyBzdHJpbmcuCgogICAgT24gaW5pdGlhbGl6YXRpb24gdGhlIG1vZHVsZSBpcyBhZGRlZCB0byBzeXMubW9kdWxlcyBzbyBpdCBjYW4gYmUKICAgIGltcG9ydGVkIHByb3Blcmx5LiBGdXJ0aGVyIGlmICpuYW1lKiBpcyBhIHN1Ym1vZHVsZSBhbmQgaWYgaXRzIHBhcmVudAogICAgZG9lcyBub3QgZXhpc3QsIGl0IHdpbGwgYXV0b21hdGljYWxseSBjcmVhdGUgYSBwYXJlbnQgOmNsYXNzOmBGYWtlTW9kdWxlYC4KICAgIFRoaXMgb3BlcmF0ZXMgcmVjdXJzaXZlbHkgdW50aWwgdGhlIHBhcmVudCBpcyBhIHRvcC1sZXZlbCBtb2R1bGUgb3IKICAgIHdoZW4gdGhlIHBhcmVudCBpcyBhbiBleGlzdGluZyBtb2R1bGUuCgogICAgSWYgYW55IGZha2Ugc3VibW9kdWxlcyBhcmUgcmVtb3ZlZCBmcm9tIHRoaXMgbW9kdWxlIHRoZXkgd2lsbAogICAgYXV0b21hdGljYWxseSBiZSByZW1vdmVkIGZyb20gOmRhdGE6YHN5cy5tb2R1bGVzYC4KCiAgICBKdXN0IGFzIDpjbGFzczpgRmFrZUNsYXNzVHlwZWAsIGl0IHN1cHBvcnRzIGNvbXBhcmlzb24gd2l0aAogICAgOmNsYXNzOmBGYWtlQ2xhc3NUeXBlYCBpbnN0YW5jZXMsIHVzaW5nIHRoZSBmb2xsb3dpbmcgbG9naWM6CgogICAgSWYgdGhlIG9iamVjdCBkb2VzIG5vdCBoYXZlIGBgb3RoZXIuX19uYW1lX19gYCBzZXQsIHRoZXkgYXJlIG5vdCBlcXVhbC4KCiAgICBFbHNlIGlmIHRoZSBvdGhlciBvYmplY3QgZG9lcyBub3QgaGF2ZSBgYG90aGVyLl9fbW9kdWxlX19gYCBzZXQsIHRoZXkgYXJlIGVxdWFsIGlmOgogICAgYGBzZWxmLl9fbmFtZV9fID09IG90aGVyLl9fbmFtZV9fYGAKCiAgICBFbHNlLCB0aGV5IGFyZSBlcXVhbCBpZjoKICAgIGBgc2VsZi5fX25hbWVfXyA9PSBvdGhlci5fX21vZHVsZV9fICsgIi4iICsgb3RoZXIuX19uYW1lX19gYAoKICAgIFVzaW5nIHRoaXMgYmVoYXZpb3VyLCBgYD09YGAsIGBgIT1gYCwgYGBoYXNoKClgYCwgYGBpc2luc3RhbmNlKClgYCBhbmQgYGBpc3N1YmNsYXNzKClgYAogICAgYXJlIGltcGxlbWVudGVkIGFsbG93aW5nIGNvbXBhcmlzb24gYmV0d2VlbiA6Y2xhc3M6YEZha2VDbGFzc1R5cGVgIGluc3RhbmNlcwogICAgYW5kIDpjbGFzczpgRmFrZU1vZHVsZWAgaW5zdGFuY2VzIHRvIHN1Y2NlZWQgaWYgdGhleSBhcmUgcHJldGVuZGluZyB0byBiZWluIHRoZSBzYW1lCiAgICBwbGFjZSBpbiB0aGUgcHl0aG9uIG1vZHVsZSBoaWVyYXJjaHkuCgogICAgSXQgaW5oZXJpdHMgZnJvbSA6Y2xhc3M6YHR5cGVzLk1vZHVsZVR5cGVgLgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgbmFtZSk6CiAgICAgICAgc3VwZXIoRmFrZU1vZHVsZSwgc2VsZikuX19pbml0X18obmFtZSkKICAgICAgICBzeXMubW9kdWxlc1tuYW1lXSA9IHNlbGYKCiAgICAgICAgaWYgIi4iIGluIG5hbWU6CiAgICAgICAgICAgIHBhcmVudF9uYW1lLCBjaGlsZF9uYW1lID0gbmFtZS5yc3BsaXQoIi4iLCAxKQoKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgX19pbXBvcnRfXyhwYXJlbnRfbmFtZSkKICAgICAgICAgICAgICAgIHBhcmVudCA9IHN5cy5tb2R1bGVzW3BhcmVudF9uYW1lXQogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBwYXJlbnQgPSBGYWtlTW9kdWxlKHBhcmVudF9uYW1lKQogICAgICAgICAgICBzZXRhdHRyKHBhcmVudCwgY2hpbGRfbmFtZSwgc2VsZikKCiAgICBkZWYgX19yZXByX18oc2VsZik6CiAgICAgICAgcmV0dXJuICI8bW9kdWxlICd7MH0nIChmYWtlKT4iLmZvcm1hdChzZWxmLl9fbmFtZV9fKQoKICAgIGRlZiBfX3N0cl9fKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLl9fcmVwcl9fKCkKCiAgICBkZWYgX19zZXRhdHRyX18oc2VsZiwgbmFtZSwgdmFsdWUpOgogICAgICAgICMgSWYgYSBmYWtlbW9kdWxlIGlzIHJlbW92ZWQgd2UgbmVlZCB0byByZW1vdmUgaXRzIGVudHJ5IGZyb20gc3lzLm1vZHVsZXMKICAgICAgICBpZiAobmFtZSBpbiBzZWxmLl9fZGljdF9fIGFuZAogICAgICAgICAgICBpc2luc3RhbmNlKHNlbGYuX19kaWN0X19bbmFtZV0sIEZha2VNb2R1bGUpIGFuZCBub3QKICAgICAgICAgICAgaXNpbnN0YW5jZSh2YWx1ZSwgRmFrZU1vZHVsZSkpOgoKICAgICAgICAgICAgc2VsZi5fX2RpY3RfX1tuYW1lXS5fcmVtb3ZlKCkKICAgICAgICBzZWxmLl9fZGljdF9fW25hbWVdID0gdmFsdWUKCiAgICBkZWYgX19kZWxhdHRyX18oc2VsZiwgbmFtZSk6CiAgICAgICAgaWYgaXNpbnN0YW5jZShzZWxmLl9fZGljdF9fW25hbWVdLCBGYWtlTW9kdWxlKToKICAgICAgICAgICAgc2VsZi5fX2RpY3RfX1tuYW1lXS5fcmVtb3ZlKCkKICAgICAgICBkZWwgc2VsZi5fX2RpY3RfX1tuYW1lXQoKICAgIGRlZiBfcmVtb3ZlKHNlbGYpOgogICAgICAgICIiIgogICAgICAgIFJlbW92ZXMgdGhpcyBtb2R1bGUgZnJvbSA6ZGF0YTpgc3lzLm1vZHVsZXNgIGFuZCBjYWxscyA6bWV0aDpgX3JlbW92ZWAgb24gYW55CiAgICAgICAgc3ViLUZha2VNb2R1bGVzLgogICAgICAgICIiIgogICAgICAgIGZvciBpIGluIHR1cGxlKHNlbGYuX19kaWN0X18ua2V5cygpKToKICAgICAgICAgICAgaWYgaXNpbnN0YW5jZShzZWxmLl9fZGljdF9fW2ldLCBGYWtlTW9kdWxlKToKICAgICAgICAgICAgICAgIHNlbGYuX19kaWN0X19baV0uX3JlbW92ZSgpCiAgICAgICAgICAgICAgICBkZWwgc2VsZi5fX2RpY3RfX1tpXQogICAgICAgIGRlbCBzeXMubW9kdWxlc1tzZWxmLl9fbmFtZV9fXQoKICAgIGRlZiBfX2VxX18oc2VsZiwgb3RoZXIpOgogICAgICAgIGlmIG5vdCBoYXNhdHRyKG90aGVyLCAiX19uYW1lX18iKToKICAgICAgICAgICAgcmV0dXJuIEZhbHNlCiAgICAgICAgb3RoZXJuYW1lID0gb3RoZXIuX19uYW1lX18KICAgICAgICBpZiBoYXNhdHRyKG90aGVyLCAiX19tb2R1bGVfXyIpOgogICAgICAgICAgICBvdGhlcm5hbWUgPSBvdGhlci5fX21vZHVsZV9fICsgIi4iICsgb3RoZXIuX19uYW1lX18KCiAgICAgICAgcmV0dXJuIHNlbGYuX19uYW1lX18gPT0gb3RoZXJuYW1lCgogICAgZGVmIF9fbmVfXyhzZWxmLCBvdGhlcik6CiAgICAgICAgcmV0dXJuIG5vdCBzZWxmID09IG90aGVyCgogICAgZGVmIF9faGFzaF9fKHNlbGYpOgogICAgICAgIHJldHVybiBoYXNoKHNlbGYuX19uYW1lX18pCgogICAgZGVmIF9faW5zdGFuY2VjaGVja19fKHNlbGYsIGluc3RhbmNlKToKICAgICAgICByZXR1cm4gc2VsZi5fX3N1YmNsYXNzY2hlY2tfXyhpbnN0YW5jZS5fX2NsYXNzX18pCgogICAgZGVmIF9fc3ViY2xhc3NjaGVja19fKHNlbGYsIHN1YmNsYXNzKToKICAgICAgICByZXR1cm4gKHNlbGYgPT0gc3ViY2xhc3Mgb3IKICAgICAgICAgICAgICAgIChib29sKHN1YmNsYXNzLl9fYmFzZXNfXykgYW5kCiAgICAgICAgICAgICAgICAgYW55KHNlbGYuX19zdWJjbGFzc2NoZWNrX18oYmFzZSkgZm9yIGJhc2UgaW4gc3ViY2xhc3MuX19iYXNlc19fKSkpCgpjbGFzcyBGYWtlUGFja2FnZShGYWtlTW9kdWxlKToKICAgICIiIgogICAgQSA6Y2xhc3M6YEZha2VNb2R1bGVgIHN1YmNsYXNzIHdoaWNoIGxhemlseSBjcmVhdGVzIDpjbGFzczpgRmFrZVBhY2thZ2VgCiAgICBpbnN0YW5jZXMgb24gaXRzIGF0dHJpYnV0ZXMgd2hlbiB0aGV5J3JlIHJlcXVlc3RlZC4KCiAgICBUaGlzIGVuc3VyZXMgdGhhdCBhbnkgYXR0cmlidXRlIG9mIHRoaXMgbW9kdWxlIGlzIGEgdmFsaWQgRmFrZU1vZHVsZQogICAgd2hpY2ggY2FuIGJlIHVzZWQgdG8gY29tcGFyZSBhZ2FpbnN0IGZha2UgY2xhc3Nlcy4KICAgICIiIgogICAgX19wYXRoX18gPSBbXQoKICAgIGRlZiBfX2NhbGxfXyhzZWxmLCAqYXJncywgKiprd2FyZ3MpOgogICAgICAgICMgVGhpcyBtYWlubHkgZXhpc3RzIHRvIHByaW50IGEgbmljZXIgZXJyb3IgbWVzc2FnZSB3aGVuCiAgICAgICAgIyBzb21lb25lIHRyaWVzIHRvIGNhbGwgYSBGYWtlUGFja2FnZSBpbnN0YW5jZQogICAgICAgIHJhaXNlIFR5cGVFcnJvcigiJ3swfScgRmFrZVBhY2thZ2Ugb2JqZWN0IGlzIG5vdCBjYWxsYWJsZSIuZm9ybWF0KHNlbGYuX19uYW1lX18pKQoKICAgIGRlZiBfX2dldGF0dHJfXyhzZWxmLCBuYW1lKToKICAgICAgICBtb2RuYW1lID0gc2VsZi5fX25hbWVfXyArICIuIiArIG5hbWUKICAgICAgICBtb2QgPSBzeXMubW9kdWxlcy5nZXQobW9kbmFtZSwgTm9uZSkKICAgICAgICBpZiBtb2QgaXMgTm9uZToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgX19pbXBvcnRfXyhtb2RuYW1lKQogICAgICAgICAgICBleGNlcHQ6CiAgICAgICAgICAgICAgICBtb2QgPSBGYWtlUGFja2FnZShtb2RuYW1lKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgbW9kID0gc3lzLm1vZHVsZXNbbW9kbmFtZV0KICAgICAgICByZXR1cm4gbW9kCgpjbGFzcyBGYWtlUGFja2FnZUxvYWRlcihvYmplY3QpOgogICAgIiIiCiAgICBBIDp0ZXJtOmBsb2FkZXJgIG9mIDpjbGFzczpgRmFrZVBhY2thZ2VgIG1vZHVsZXMuIFdoZW4gYWRkZWQgdG8KICAgIDpkYXRhOmBzeXMubWV0YV9wYXRoYCBpdCB3aWxsIGVuc3VyZSB0aGF0IGFueSBhdHRlbXB0IHRvIGltcG9ydAogICAgbW9kdWxlICpyb290KiBvciBpdHMgc3VibW9kdWxlcyByZXN1bHRzIGluIGEgRmFrZVBhY2thZ2UuCgogICAgVG9nZXRoZXIgd2l0aCB0aGUgYXR0cmlidXRlIGNyZWF0aW9uIGZyb20gOmNsYXNzOmBGYWtlUGFja2FnZWAKICAgIHRoaXMgZW5zdXJlcyB0aGF0IGFueSBhdHRlbXB0IHRvIGdldCBhIHN1Ym1vZHVsZSBmcm9tIG1vZHVsZSAqcm9vdCoKICAgIHJlc3VsdHMgaW4gYSBGYWtlUGFja2FnZSwgY3JlYXRpbmcgdGhlIGlsbHVzaW9uIHRoYXQgKnJvb3QqIGlzIGFuCiAgICBhY3R1YWwgcGFja2FnZSB0cmVlLgogICAgIiIiCiAgICBkZWYgX19pbml0X18oc2VsZiwgcm9vdCk6CiAgICAgICAgc2VsZi5yb290ID0gcm9vdAoKICAgIGRlZiBmaW5kX21vZHVsZShzZWxmLCBmdWxsbmFtZSwgcGF0aD1Ob25lKToKICAgICAgICBpZiBmdWxsbmFtZSA9PSBzZWxmLnJvb3Qgb3IgZnVsbG5hbWUuc3RhcnRzd2l0aChzZWxmLnJvb3QgKyAiLiIpOgogICAgICAgICAgICByZXR1cm4gc2VsZgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgZGVmIGxvYWRfbW9kdWxlKHNlbGYsIGZ1bGxuYW1lKToKICAgICAgICByZXR1cm4gRmFrZVBhY2thZ2UoZnVsbG5hbWUpCgojIEZha2UgdW5waWNrbGVyIGltcGxlbWVudGF0aW9uCgpjbGFzcyBGYWtlVW5waWNrbGluZ0Vycm9yKHBpY2tsZS5VbnBpY2tsaW5nRXJyb3IpOgogICAgIiIiCiAgICBFcnJvciByYWlzZWQgd2hlbiB0aGVyZSBpcyBub3QgZW5vdWdoIGluZm9ybWF0aW9uIHRvIHBlcmZvcm0gdGhlIGZha2UKICAgIHVucGlja2xpbmcgcHJvY2VzcyBjb21wbGV0ZWx5LiBJdCBpbmhlcml0cyBmcm9tIDpleGM6YHBpY2tsZS5VbnBpY2tsaW5nRXJyb3JgLgogICAgIiIiCiAgICBwYXNzCgpjbGFzcyBGYWtlVW5waWNrbGVyKHBpY2tsZS5VbnBpY2tsZXIgaWYgUFkyIGVsc2UgcGlja2xlLl9VbnBpY2tsZXIpOgogICAgIiIiCiAgICBBIGZvcmdpdmluZyB1bnBpY2tsZXIuIE9uIHVuY291bnRlcmluZyByZWZlcmVuY2VzIHRvIGNsYXNzIGRlZmluaXRpb25zCiAgICBpbiB0aGUgcGlja2xlIHN0cmVhbSB3aGljaCBpdCBjYW5ub3QgbG9jYXRlLCBpdCB3aWxsIGNyZWF0ZSBmYWtlIGNsYXNzZXMKICAgIGFuZCBpZiBuZWNlc3NhcnkgZmFrZSBtb2R1bGVzIHRvIGhvdXNlIHRoZW0gaW4uIFNpbmNlIGl0IHN0aWxsIGFsbG93cyBhY2Nlc3MKICAgIHRvIGFsbCBtb2R1bGVzIGFuZCBidWlsdGlucywgaXQgc2hvdWxkIG9ubHkgYmUgdXNlZCB0byB1bnBpY2tsZSB0cnVzdGVkIGRhdGEuCgogICAgKmZpbGUqIGlzIHRoZSA6dGVybTpgYmluYXJ5IGZpbGVgIHRvIHVuc2VyaWFsaXplLgoKICAgIFRoZSBvcHRpb25hbCBrZXl3b3JkIGFyZ3VtZW50cyBhcmUgKmNsYXNzX2ZhY3RvcnkqLCAqZW5jb2RpbmcgYW5kICplcnJvcnMqLgogICAgKmNsYXNzX2ZhY3RvcnkqIGNhbiBiZSB1c2VkIHRvIGNvbnRyb2wgaG93IHRoZSBtaXNzaW5nIGNsYXNzIGRlZmluaXRpb25zIGFyZQogICAgY3JlYXRlZC4gSWYgc2V0IHRvIGBgTm9uZWBgLCBgYEZha2VDbGFzc0ZhY3RvcnkoKCksIEZha2VTdHJpY3QpYGAgd2lsbCBiZSB1c2VkLgoKICAgIEluIFB5dGhvbiAzLCB0aGUgb3B0aW9uYWwga2V5d29yZCBhcmd1bWVudHMgKmVuY29kaW5nKiBhbmQgKmVycm9ycyogY2FuIGJlIHVzZWQKICAgIHRvIGluZGljYXRlIGhvdyB0aGUgdW5waWNrbGVyIHNob3VsZCBkZWFsIHdpdGggcGlja2xlIHN0cmVhbXMgZ2VuZXJhdGVkIGluIHB5dGhvbgogICAgMiwgc3BlY2lmaWNhbGx5IGhvdyB0byBkZWFsIHdpdGggOC1iaXQgc3RyaW5nIGluc3RhbmNlcy4gSWYgc2V0IHRvICJieXRlcyIgaXQgd2lsbAogICAgbG9hZCB0aGVtIGFzIGJ5dGVzIG9iamVjdHMsIG90aGVyd2lzZSBpdCB3aWxsIGF0dGVtcHQgdG8gZGVjb2RlIHRoZW0gaW50byB1bmljb2RlCiAgICB1c2luZyB0aGUgZ2l2ZW4gKmVuY29kaW5nKiBhbmQgKmVycm9ycyogYXJndW1lbnRzLgoKICAgIEl0IGluaGVyaXRzIGZyb20gOmNsYXNzOmBwaWNrbGUuVW5waWNrbGVyYC4gKEluIFB5dGhvbiAzIHRoaXMgaXMgYWN0dWFsbHkKICAgIGBgcGlja2xlLl9VbnBpY2tsZXJgYCkKICAgICIiIgogICAgaWYgUFkyOgogICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmaWxlLCBjbGFzc19mYWN0b3J5PU5vbmUsIGVuY29kaW5nPSJieXRlcyIsIGVycm9ycz0ic3RyaWN0Iik6CiAgICAgICAgICAgIHBpY2tsZS5VbnBpY2tsZXIuX19pbml0X18oc2VsZiwgZmlsZSwpCiAgICAgICAgICAgIHNlbGYuY2xhc3NfZmFjdG9yeSA9IGNsYXNzX2ZhY3Rvcnkgb3IgRmFrZUNsYXNzRmFjdG9yeSgpCiAgICBlbHNlOgogICAgICAgIGRlZiBfX2luaXRfXyhzZWxmLCBmaWxlLCBjbGFzc19mYWN0b3J5PU5vbmUsIGVuY29kaW5nPSJieXRlcyIsIGVycm9ycz0ic3RyaWN0Iik6CiAgICAgICAgICAgIHN1cGVyKCkuX19pbml0X18oZmlsZSwgZml4X2ltcG9ydHM9RmFsc2UsIGVuY29kaW5nPWVuY29kaW5nLCBlcnJvcnM9ZXJyb3JzKQogICAgICAgICAgICBzZWxmLmNsYXNzX2ZhY3RvcnkgPSBjbGFzc19mYWN0b3J5IG9yIEZha2VDbGFzc0ZhY3RvcnkoKQoKICAgIGRlZiBmaW5kX2NsYXNzKHNlbGYsIG1vZHVsZSwgbmFtZSk6CiAgICAgICAgbW9kID0gc3lzLm1vZHVsZXMuZ2V0KG1vZHVsZSwgTm9uZSkKICAgICAgICBpZiBtb2QgaXMgTm9uZToKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgX19pbXBvcnRfXyhtb2R1bGUpCiAgICAgICAgICAgIGV4Y2VwdDoKICAgICAgICAgICAgICAgIG1vZCA9IEZha2VNb2R1bGUobW9kdWxlKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgbW9kID0gc3lzLm1vZHVsZXNbbW9kdWxlXQoKICAgICAgICBrbGFzcyA9IGdldGF0dHIobW9kLCBuYW1lLCBOb25lKQogICAgICAgIGlmIGtsYXNzIGlzIE5vbmUgb3IgaXNpbnN0YW5jZShrbGFzcywgRmFrZU1vZHVsZSk6CiAgICAgICAgICAgIGtsYXNzID0gc2VsZi5jbGFzc19mYWN0b3J5KG5hbWUsIG1vZHVsZSkKICAgICAgICAgICAgc2V0YXR0cihtb2QsIG5hbWUsIGtsYXNzKQoKICAgICAgICByZXR1cm4ga2xhc3MKCmNsYXNzIFNhZmVVbnBpY2tsZXIoRmFrZVVucGlja2xlcik6CiAgICAiIiIKICAgIEEgc2FmZSB1bnBpY2tsZXIuIEl0IHdpbGwgY3JlYXRlIGZha2UgY2xhc3NlcyBmb3IgYW55IHJlZmVyZW5jZXMgdG8gY2xhc3MKICAgIGRlZmluaXRpb25zIGluIHRoZSBwaWNrbGUgc3RyZWFtLiBGdXJ0aGVyIGl0IGNhbiBibG9jayBhY2Nlc3MgdG8gdGhlIGV4dGVuc2lvbgogICAgcmVnaXN0cnkgbWFraW5nIHRoaXMgdW5waWNrbGVyIHNhZmUgdG8gdXNlIG9uIHVudHJ1c3RlZCBkYXRhLgoKICAgICpmaWxlKiBpcyB0aGUgOnRlcm06YGJpbmFyeSBmaWxlYCB0byB1bnNlcmlhbGl6ZS4KCiAgICBUaGUgb3B0aW9uYWwga2V5d29yZCBhcmd1bWVudHMgYXJlICpjbGFzc19mYWN0b3J5KiwgKnNhZmVfbW9kdWxlcyosICp1c2VfY29weXJlZyosCiAgICAqZW5jb2RpbmcqIGFuZCAqZXJyb3JzKi4gKmNsYXNzX2ZhY3RvcnkqIGNhbiBiZSB1c2VkIHRvIGNvbnRyb2wgaG93IHRoZSBtaXNzaW5nIGNsYXNzCiAgICBkZWZpbml0aW9ucyBhcmUgY3JlYXRlZC4gSWYgc2V0IHRvIGBgTm9uZWBgLCBgYEZha2VDbGFzc0ZhY3RvcnkoKCksIEZha2VTdHJpY3QpYGAgd2lsbCBiZQogICAgdXNlZC4gKnNhZmVfbW9kdWxlcyogY2FuIGJlIHNldCB0byBhIHNldCBvZiBzdHJpbmdzIG9mIG1vZHVsZSBuYW1lcywgd2hpY2ggd2lsbCBiZQogICAgcmVnYXJkZWQgYXMgc2FmZSBieSB0aGUgdW5waWNrbGluZyBwcm9jZXNzLCBtZWFuaW5nIHRoYXQgaXQgd2lsbCBpbXBvcnQgb2JqZWN0cwogICAgZnJvbSB0aGF0IG1vZHVsZSBpbnN0ZWFkIG9mIGdlbmVyYXRpbmcgZmFrZSBjbGFzc2VzICh0aGlzIGRvZXMgbm90IGFwcGx5IHRvIG9iamVjdHMKICAgIGluIHN1Ym1vZHVsZXMpLiAqdXNlX2NvcHlyZWcqIGlzIGEgYm9vbGVhbiB2YWx1ZSBpbmRpY2F0aW5nIGlmIGl0J3MgYWxsb3dlZCB0bwogICAgdXNlIGV4dGVuc2lvbnMgZnJvbSB0aGUgcGlja2xlIGV4dGVuc2lvbiByZWdpc3RyeSAoZG9jdW1lbnRlZCBpbiB0aGUgOm1vZDpgY29weXJlZ2AKICAgIG1vZHVsZSkuCgogICAgSW4gUHl0aG9uIDMsIHRoZSBvcHRpb25hbCBrZXl3b3JkIGFyZ3VtZW50cyAqZW5jb2RpbmcqIGFuZCAqZXJyb3JzKiBjYW4gYmUgdXNlZAogICAgdG8gaW5kaWNhdGUgaG93IHRoZSB1bnBpY2tsZXIgc2hvdWxkIGRlYWwgd2l0aCBwaWNrbGUgc3RyZWFtcyBnZW5lcmF0ZWQgaW4gcHl0aG9uCiAgICAyLCBzcGVjaWZpY2FsbHkgaG93IHRvIGRlYWwgd2l0aCA4LWJpdCBzdHJpbmcgaW5zdGFuY2VzLiBJZiBzZXQgdG8gImJ5dGVzIiBpdCB3aWxsCiAgICBsb2FkIHRoZW0gYXMgYnl0ZXMgb2JqZWN0cywgb3RoZXJ3aXNlIGl0IHdpbGwgYXR0ZW1wdCB0byBkZWNvZGUgdGhlbSBpbnRvIHVuaWNvZGUKICAgIHVzaW5nIHRoZSBnaXZlbiAqZW5jb2RpbmcqIGFuZCAqZXJyb3JzKiBhcmd1bWVudHMuCgogICAgVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byB1bnBpY2tsZSB1bnRydXN0ZWQgZGF0YSBzYWZlbHkgd2l0aCB0aGUgZGVmYXVsdAogICAgY2xhc3NfZmFjdG9yeSB3aGVuICpzYWZlX21vZHVsZXMqIGlzIGVtcHR5IGFuZCAqdXNlX2NvcHlyZWcqIGlzIEZhbHNlLgogICAgSXQgaW5oZXJpdHMgZnJvbSA6Y2xhc3M6YHBpY2tsZS5VbnBpY2tsZXJgLiAoSW4gUHl0aG9uIDMgdGhpcyBpcyBhY3R1YWxseQogICAgYGBwaWNrbGUuX1VucGlja2xlcmBgKQoKICAgIEl0IHNob3VsZCBiZSBub3RlZCB0aG91Z2ggdGhhdCB3aGVuIHRoZSB1bnBpY2tsZXIgdHJpZXMgdG8gZ2V0IGEgbm9uZXhpc3RlbnQKICAgIGF0dHJpYnV0ZSBvZiBhIHNhZmUgbW9kdWxlLCBhbiA6ZXhjOmBBdHRyaWJ1dGVFcnJvcmAgd2lsbCBiZSByYWlzZWQuCgogICAgVGhpcyBpbmhlcml0cyBmcm9tIDpjbGFzczpgRmFrZVVucGlja2xlcmAKICAgICIiIgogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGUsIGNsYXNzX2ZhY3Rvcnk9Tm9uZSwgc2FmZV9tb2R1bGVzPSgpLAogICAgICAgICAgICAgICAgIHVzZV9jb3B5cmVnPUZhbHNlLCBlbmNvZGluZz0iYnl0ZXMiLCBlcnJvcnM9InN0cmljdCIpOgogICAgICAgIEZha2VVbnBpY2tsZXIuX19pbml0X18oc2VsZiwgZmlsZSwgY2xhc3NfZmFjdG9yeSwgZW5jb2Rpbmc9ZW5jb2RpbmcsIGVycm9ycz1lcnJvcnMpCiAgICAgICAgIyBBIHNldCBvZiBtb2R1bGVzIHdoaWNoIGFyZSBzYWZlIHRvIGxvYWQKICAgICAgICBzZWxmLnNhZmVfbW9kdWxlcyA9IHNldChzYWZlX21vZHVsZXMpCiAgICAgICAgc2VsZi51c2VfY29weXJlZyA9IHVzZV9jb3B5cmVnCgogICAgZGVmIGZpbmRfY2xhc3Moc2VsZiwgbW9kdWxlLCBuYW1lKToKICAgICAgICBpZiBtb2R1bGUgaW4gc2VsZi5zYWZlX21vZHVsZXM6CiAgICAgICAgICAgIF9faW1wb3J0X18obW9kdWxlKQogICAgICAgICAgICBtb2QgPSBzeXMubW9kdWxlc1ttb2R1bGVdCiAgICAgICAgICAgIGtsYXNzID0gZ2V0YXR0cihtb2QsIG5hbWUpCiAgICAgICAgICAgIHJldHVybiBrbGFzcwoKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gc2VsZi5jbGFzc19mYWN0b3J5KG5hbWUsIG1vZHVsZSkKCiAgICBkZWYgZ2V0X2V4dGVuc2lvbihzZWxmLCBjb2RlKToKICAgICAgICBpZiBzZWxmLnVzZV9jb3B5cmVnOgogICAgICAgICAgICByZXR1cm4gRmFrZVVucGlja2xlci5nZXRfZXh0ZW5zaW9uKHNlbGYsIGNvZGUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYuY2xhc3NfZmFjdG9yeSgiZXh0ZW5zaW9uX2NvZGVfezB9Ii5mb3JtYXQoY29kZSksICJjb3B5cmVnIikKCmNsYXNzIFNhZmVQaWNrbGVyKHBpY2tsZS5QaWNrbGVyIGlmIFBZMiBlbHNlIHBpY2tsZS5fUGlja2xlcik6CiAgICAiIiIKICAgIEEgcGlja2xlciB3aGljaCBjYW4gcmVwaWNrbGUgb2JqZWN0IGhpZXJhcmNoaWVzIGNvbnRhaW5pbmcgb2JqZWN0cyBjcmVhdGVkIGJ5IFNhZmVVbnBpY2tsZXIuCiAgICBEdWUgdG8gcmVhc29ucyB1bmtub3duLCBweXRob25zIHBpY2tsZSBpbXBsZW1lbnRhdGlvbiB3aWxsIG5vcm1hbGx5IGNoZWNrIGlmIGEgZ2l2ZW4gY2xhc3MKICAgIGFjdHVhbGx5IG1hdGNoZXMgd2l0aCB0aGUgb2JqZWN0IHNwZWNpZmllZCBhdCB0aGUgX19tb2R1bGVfXyBhbmQgX19uYW1lX18gb2YgdGhlIGNsYXNzLiBTaW5jZQogICAgdGhpcyBjaGVjayBpcyBwZXJmb3JtZWQgd2l0aCBvYmplY3QgaWRlbnRpdHkgaW5zdGVhZCBvZiBvYmplY3QgZXF1YWxpdHkgd2UgY2Fubm90IGZha2UgdGhpcyBmcm9tCiAgICB0aGUgY2xhc3NlcyB0aGVtc2VsdmVzLCBhbmQgd2UgbmVlZCB0byBvdmVycmlkZSB0aGUgbWV0aG9kIHVzZWQgZm9yIG5vcm1hbGx5IHNhdmluZyBjbGFzc2VzLgogICAgIiIiCgogICAgZGVmIHNhdmVfZ2xvYmFsKHNlbGYsIG9iaiwgbmFtZT1Ob25lLCBwYWNrPXN0cnVjdC5wYWNrKToKICAgICAgICBpZiBpc2luc3RhbmNlKG9iaiwgRmFrZUNsYXNzVHlwZSk6CiAgICAgICAgICAgIHNlbGYud3JpdGUocGlja2xlLkdMT0JBTCArIG9iai5fX21vZHVsZV9fICsgJ1xuJyArIG9iai5fX25hbWVfXyArICdcbicpCiAgICAgICAgICAgIHNlbGYubWVtb2l6ZShvYmopCiAgICAgICAgICAgIHJldHVybgoKICAgICAgICBwaWNrbGUuUGlja2xlci5zYXZlX2dsb2JhbChzZWxmLCBvYmosIG5hbWUsIHBhY2spCgojIHRoZSBtYWluIEFQSQoKZGVmIGxvYWQoZmlsZSwgY2xhc3NfZmFjdG9yeT1Ob25lLCBlbmNvZGluZz0iYnl0ZXMiLCBlcnJvcnM9ImVycm9ycyIpOgogICAgIiIiCiAgICBSZWFkIGEgcGlja2xlZCBvYmplY3QgcmVwcmVzZW50YXRpb24gZnJvbSB0aGUgb3BlbiBiaW5hcnkgOnRlcm06YGZpbGUgb2JqZWN0YCAqZmlsZSoKICAgIGFuZCByZXR1cm4gdGhlIHJlY29uc3RpdHV0ZGVkIG9iamVjdCBoaWVyYXJjaHkgc3BlY2lmaWVkIHRoZXJlaW4sIGdlbmVyYXRpbmcKICAgIGFueSBtaXNzaW5nIGNsYXNzIGRlZmluaXRpb25zIGF0IHJ1bnRpbWUuIFRoaXMgaXMgZXF1aXZhbGVudCB0bwogICAgYGBGYWtlVW5waWNrbGVyKGZpbGUpLmxvYWQoKWBgLgoKICAgIFRoZSBvcHRpb25hbCBrZXl3b3JkIGFyZ3VtZW50cyBhcmUgKmNsYXNzX2ZhY3RvcnkqLCAqZW5jb2RpbmcqIGFuZCAqZXJyb3JzKi4KICAgICpjbGFzc19mYWN0b3J5KiBjYW4gYmUgdXNlZCB0byBjb250cm9sIGhvdyB0aGUgbWlzc2luZyBjbGFzcyBkZWZpbml0aW9ucyBhcmUKICAgIGNyZWF0ZWQuIElmIHNldCB0byBgYE5vbmVgYCwgYGBGYWtlQ2xhc3NGYWN0b3J5KHt9LCAnc3RyaWN0JylgYCB3aWxsIGJlIHVzZWQuCgogICAgSW4gUHl0aG9uIDMsIHRoZSBvcHRpb25hbCBrZXl3b3JkIGFyZ3VtZW50cyAqZW5jb2RpbmcqIGFuZCAqZXJyb3JzKiBjYW4gYmUgdXNlZAogICAgdG8gaW5kaWNhdGUgaG93IHRoZSB1bnBpY2tsZXIgc2hvdWxkIGRlYWwgd2l0aCBwaWNrbGUgc3RyZWFtcyBnZW5lcmF0ZWQgaW4gcHl0aG9uCiAgICAyLCBzcGVjaWZpY2FsbHkgaG93IHRvIGRlYWwgd2l0aCA4LWJpdCBzdHJpbmcgaW5zdGFuY2VzLiBJZiBzZXQgdG8gImJ5dGVzIiBpdCB3aWxsCiAgICBsb2FkIHRoZW0gYXMgYnl0ZXMgb2JqZWN0cywgb3RoZXJ3aXNlIGl0IHdpbGwgYXR0ZW1wdCB0byBkZWNvZGUgdGhlbSBpbnRvIHVuaWNvZGUKICAgIHVzaW5nIHRoZSBnaXZlbiAqZW5jb2RpbmcqIGFuZCAqZXJyb3JzKiBhcmd1bWVudHMuCgogICAgVGhpcyBmdW5jdGlvbiBzaG91bGQgb25seSBiZSB1c2VkIHRvIHVucGlja2xlIHRydXN0ZWQgZGF0YS4KICAgICIiIgogICAgcmV0dXJuIEZha2VVbnBpY2tsZXIoZmlsZSwgY2xhc3NfZmFjdG9yeSwgZW5jb2Rpbmc9ZW5jb2RpbmcsIGVycm9ycz1lcnJvcnMpLmxvYWQoKQoKZGVmIGxvYWRzKHN0cmluZywgY2xhc3NfZmFjdG9yeT1Ob25lLCBlbmNvZGluZz0iYnl0ZXMiLCBlcnJvcnM9ImVycm9ycyIpOgogICAgIiIiCiAgICBTaW1qaWxhciB0byA6ZnVuYzpgbG9hZGAsIGJ1dCB0YWtlcyBhbiA4LWJpdCBzdHJpbmcgKGJ5dGVzIGluIFB5dGhvbiAzLCBzdHIgaW4gUHl0aG9uIDIpCiAgICBhcyBpdHMgZmlyc3QgYXJndW1lbnQgaW5zdGVhZCBvZiBhIGJpbmFyeSA6dGVybTpgZmlsZSBvYmplY3RgLgogICAgIiIiCiAgICByZXR1cm4gRmFrZVVucGlja2xlcihTdHJpbmdJTyhzdHJpbmcpLCBjbGFzc19mYWN0b3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2Rpbmc9ZW5jb2RpbmcsIGVycm9ycz1lcnJvcnMpLmxvYWQoKQoKZGVmIHNhZmVfbG9hZChmaWxlLCBjbGFzc19mYWN0b3J5PU5vbmUsIHNhZmVfbW9kdWxlcz0oKSwgdXNlX2NvcHlyZWc9RmFsc2UsCiAgICAgICAgICAgICAgZW5jb2Rpbmc9ImJ5dGVzIiwgZXJyb3JzPSJlcnJvcnMiKToKICAgICIiIgogICAgUmVhZCBhIHBpY2tsZWQgb2JqZWN0IHJlcHJlc2VudGF0aW9uIGZyb20gdGhlIG9wZW4gYmluYXJ5IDp0ZXJtOmBmaWxlIG9iamVjdGAgKmZpbGUqCiAgICBhbmQgcmV0dXJuIHRoZSByZWNvbnN0aXR1dGRlZCBvYmplY3QgaGllcmFyY2h5IHNwZWNpZmllZCB0aGVyZWluLCBzdWJzdGl0dXRpbmcgYW55CiAgICBjbGFzcyBkZWZpbml0aW9ucyBieSBmYWtlIGNsYXNzZXMsIGVuc3VyaW5nIHNhZmV0eSBpbiB0aGUgdW5waWNrbGluZyBwcm9jZXNzLgogICAgVGhpcyBpcyBlcXVpdmFsZW50IHRvIGBgU2FmZVVucGlja2xlcihmaWxlKS5sb2FkKClgYC4KCiAgICBUaGUgb3B0aW9uYWwga2V5d29yZCBhcmd1bWVudHMgYXJlICpjbGFzc19mYWN0b3J5KiwgKnNhZmVfbW9kdWxlcyosICp1c2VfY29weXJlZyosCiAgICAqZW5jb2RpbmcqIGFuZCAqZXJyb3JzKi4gKmNsYXNzX2ZhY3RvcnkqIGNhbiBiZSB1c2VkIHRvIGNvbnRyb2wgaG93IHRoZSBtaXNzaW5nIGNsYXNzCiAgICBkZWZpbml0aW9ucyBhcmUgY3JlYXRlZC4gSWYgc2V0IHRvIGBgTm9uZWBgLCBgYEZha2VDbGFzc0ZhY3Rvcnkoe30sICdzdHJpY3QnKWBgIHdpbGwgYmUKICAgIHVzZWQuICpzYWZlX21vZHVsZXMqIGNhbiBiZSBzZXQgdG8gYSBzZXQgb2Ygc3RyaW5ncyBvZiBtb2R1bGUgbmFtZXMsIHdoaWNoIHdpbGwgYmUKICAgIHJlZ2FyZGVkIGFzIHNhZmUgYnkgdGhlIHVucGlja2xpbmcgcHJvY2VzcywgbWVhbmluZyB0aGF0IGl0IHdpbGwgaW1wb3J0IG9iamVjdHMKICAgIGZyb20gdGhhdCBtb2R1bGUgaW5zdGVhZCBvZiBnZW5lcmF0aW5nIGZha2UgY2xhc3NlcyAodGhpcyBkb2VzIG5vdCBhcHBseSB0byBvYmplY3RzCiAgICBpbiBzdWJtb2R1bGVzKS4gKnVzZV9jb3B5cmVnKiBpcyBhIGJvb2xlYW4gdmFsdWUgaW5kaWNhdGluZyBpZiBpdCdzIGFsbG93ZWQgdG8KICAgIHVzZSBleHRlbnNpb25zIGZyb20gdGhlIHBpY2tsZSBleHRlbnNpb24gcmVnaXN0cnkgKGRvY3VtZW50ZWQgaW4gdGhlIDptb2Q6YGNvcHlyZWdgCiAgICBtb2R1bGUpLgoKICAgIEluIFB5dGhvbiAzLCB0aGUgb3B0aW9uYWwga2V5d29yZCBhcmd1bWVudHMgKmVuY29kaW5nKiBhbmQgKmVycm9ycyogY2FuIGJlIHVzZWQKICAgIHRvIGluZGljYXRlIGhvdyB0aGUgdW5waWNrbGVyIHNob3VsZCBkZWFsIHdpdGggcGlja2xlIHN0cmVhbXMgZ2VuZXJhdGVkIGluIHB5dGhvbgogICAgMiwgc3BlY2lmaWNhbGx5IGhvdyB0byBkZWFsIHdpdGggOC1iaXQgc3RyaW5nIGluc3RhbmNlcy4gSWYgc2V0IHRvICJieXRlcyIgaXQgd2lsbAogICAgbG9hZCB0aGVtIGFzIGJ5dGVzIG9iamVjdHMsIG90aGVyd2lzZSBpdCB3aWxsIGF0dGVtcHQgdG8gZGVjb2RlIHRoZW0gaW50byB1bmljb2RlCiAgICB1c2luZyB0aGUgZ2l2ZW4gKmVuY29kaW5nKiBhbmQgKmVycm9ycyogYXJndW1lbnRzLgoKICAgIFRoaXMgZnVuY3Rpb24gY2FuIGJlIHVzZWQgdG8gdW5waWNrbGUgdW50cnVzdGVkIGRhdGEgc2FmZWx5IHdpdGggdGhlIGRlZmF1bHQKICAgIGNsYXNzX2ZhY3Rvcnkgd2hlbiAqc2FmZV9tb2R1bGVzKiBpcyBlbXB0eSBhbmQgKnVzZV9jb3B5cmVnKiBpcyBGYWxzZS4KICAgICIiIgogICAgcmV0dXJuIFNhZmVVbnBpY2tsZXIoZmlsZSwgY2xhc3NfZmFjdG9yeSwgc2FmZV9tb2R1bGVzLCB1c2VfY29weXJlZywKICAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kaW5nPWVuY29kaW5nLCBlcnJvcnM9ZXJyb3JzKS5sb2FkKCkKCmRlZiBzYWZlX2xvYWRzKHN0cmluZywgY2xhc3NfZmFjdG9yeT1Ob25lLCBzYWZlX21vZHVsZXM9KCksIHVzZV9jb3B5cmVnPUZhbHNlLAogICAgICAgICAgICAgICBlbmNvZGluZz0iYnl0ZXMiLCBlcnJvcnM9ImVycm9ycyIpOgogICAgIiIiCiAgICBTaW1pbGFyIHRvIDpmdW5jOmBzYWZlX2xvYWRgLCBidXQgdGFrZXMgYW4gOC1iaXQgc3RyaW5nIChieXRlcyBpbiBQeXRob24gMywgc3RyIGluIFB5dGhvbiAyKQogICAgYXMgaXRzIGZpcnN0IGFyZ3VtZW50IGluc3RlYWQgb2YgYSBiaW5hcnkgOnRlcm06YGZpbGUgb2JqZWN0YC4KICAgICIiIgogICAgcmV0dXJuIFNhZmVVbnBpY2tsZXIoU3RyaW5nSU8oc3RyaW5nKSwgY2xhc3NfZmFjdG9yeSwgc2FmZV9tb2R1bGVzLCB1c2VfY29weXJlZywKICAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kaW5nPWVuY29kaW5nLCBlcnJvcnM9ZXJyb3JzKS5sb2FkKCkKCmRlZiBzYWZlX2R1bXAob2JqLCBmaWxlLCBwcm90b2NvbD1waWNrbGUuSElHSEVTVF9QUk9UT0NPTCk6CiAgICAiIiIKICAgIEEgY29udmVuaWVuY2UgZnVuY3Rpb24gd3JhcHBpbmcgU2FmZVBpY2tsZXIuIEl0IGZ1bmN0aW9ucyBzaW1pbGFybHkgdG8gcGlja2xlLmR1bXAKICAgICIiIgogICAgU2FmZVBpY2tsZXIoZmlsZSwgcHJvdG9jb2wpLmR1bXAob2JqKQoKZGVmIHNhZmVfZHVtcHMob2JqLCBwcm90b2NvbD1waWNrbGUuSElHSEVTVF9QUk9UT0NPTCk6CiAgICAiIiIKICAgIEEgY29udmVuaWVuY2UgZnVuY3Rpb24gd3JhcHBpbmcgU2FmZVBpY2tsZXIuIEl0IGZ1bmN0aW9ucyBzaW1pbGFybHkgdG8gcGlja2xlLmR1bXBzCiAgICAiIiIKICAgIGZpbGUgPSBTdHJpbmdJTygpCiAgICBTYWZlUGlja2xlcihmaWxlLCBwcm90b2NvbCkuZHVtcChvYmopCiAgICByZXR1cm4gZmlsZS5nZXR2YWx1ZSgpCgpkZWYgZmFrZV9wYWNrYWdlKG5hbWUpOgogICAgIiIiCiAgICBNb3VudHMgYSBmYWtlIHBhY2thZ2UgdHJlZSB3aXRoIHRoZSBuYW1lICpuYW1lKi4gVGhpcyBjYXVzZXMgYW55IGF0dGVtcHQgdG8gaW1wb3J0CiAgICBtb2R1bGUgKm5hbWUqLCBhdHRyaWJ1dGVzIG9mIHRoZSBtb2R1bGUgb3Igc3VibW9kdWxlcyB3aWxsIHJldHVybiBhIDpjbGFzczpgRmFrZVBhY2thZ2VgCiAgICBpbnN0YW5jZSB3aGljaCBpbXBsZW1lbnRzIHRoZSBzYW1lIGJlaGF2aW91ci4gVGhlc2UgOmNsYXNzOmBGYWtlUGFja2FnZWAgaW5zdGFuY2VzIGNvbXBhcmUKICAgIHByb3Blcmx5IHdpdGggOmNsYXNzOmBGYWtlQ2xhc3NUeXBlYCBpbnN0YW5jZXMgYWxsb3dpbmcgeW91IHRvIGNvZGUgdXNpbmcgRmFrZVBhY2thZ2VzIGFzCiAgICBpZiB0aGUgbW9kdWxlcyBhbmQgdGhlaXIgYXR0cmlidXRlcyBhY3R1YWxseSBleGlzdGVkLgoKICAgIFRoaXMgaXMgaW1wbGVtZW50ZWQgYnkgY3JlYXRpbmcgYSA6Y2xhc3M6YEZha2VQYWNrYWdlTG9hZGVyYCBpbnN0YW5jZSB3aXRoIHJvb3QgKm5hbWUqCiAgICBhbmQgaW5zZXJ0aW5nIGl0IGluIHRoZSBmaXJzdCBzcG90IGluIDpkYXRhOmBzeXMubWV0YV9wYXRoYC4gVGhpcyBlbnN1cmVzIHRoYXQgaW1wb3J0aW5nIHRoZQogICAgbW9kdWxlIGFuZCBzdWJtb2R1bGVzIHdpbGwgd29yayBwcm9wZXJseS4gRnVydGhlciB0aGUgOmNsYXNzOmBGYWtlUGFja2FnZWAgaW5zdGFuY2VzIHRha2UKICAgIGNhcmUgb2YgZ2VuZXJhdGluZyBzdWJtb2R1bGVzIGFzIGF0dHJpYnV0ZXMgb24gcmVxdWVzdC4KCiAgICBJZiBhIGZha2UgcGFja2FnZSB0cmVlIHdpdGggdGhlIHNhbWUgKm5hbWUqIGlzIGFscmVhZHkgcmVnaXN0ZXJlZCwgbm8gbmV3IGZha2UgcGFja2FnZQogICAgdHJlZSB3aWxsIGJlIG1vdW50ZWQuCgogICAgVGhpcyByZXR1cm5zIHRoZSA6Y2xhc3M6YEZha2VQYWNrYWdlYCBpbnN0YW5jZSAqbmFtZSouCiAgICAiIiIKICAgIGlmIG5hbWUgaW4gc3lzLm1vZHVsZXMgYW5kIGlzaW5zdGFuY2Uoc3lzLm1vZHVsZXNbbmFtZV0sIEZha2VQYWNrYWdlKToKICAgICAgICByZXR1cm4gc3lzLm1vZHVsZXNbbmFtZV0KICAgIGVsc2U6CiAgICAgICAgbG9hZGVyID0gRmFrZVBhY2thZ2VMb2FkZXIobmFtZSkKICAgICAgICBzeXMubWV0YV9wYXRoLmluc2VydCgwLCBsb2FkZXIpCiAgICAgICAgcmV0dXJuIF9faW1wb3J0X18obmFtZSkKCmRlZiByZW1vdmVfZmFrZV9wYWNrYWdlKG5hbWUpOgogICAgIiIiCiAgICBSZW1vdmVzIHRoZSBmYWtlIHBhY2thZ2UgdHJlZSBtb3VudGVkIGF0ICpuYW1lKi4KCiAgICBUaGlzIHdvcmtzIGJ5IGZpcnN0IGxvb2tpbmcgZm9yIGFueSBGYWtlUGFja2FnZUxvYWRlcnMgaW4gOmRhdGE6YHN5cy5wYXRoYAogICAgd2l0aCB0aGVpciByb290IHNldCB0byAqbmFtZSogYW5kIHJlbW92aW5nIHRoZW0gZnJvbSBzeXMucGF0aC4gTmV4dCBpdCB3aWxsCiAgICBmaW5kIHRoZSB0b3AtbGV2ZWwgOmNsYXNzOmBGYWtlUGFja2FnZWAgaW5zdGFuY2UgKm5hbWUqIGFuZCBmcm9tIHRoaXMgcG9pbnQKICAgIHRyYXZlcnNlIHRoZSB0cmVlIG9mIGNyZWF0ZWQgc3VibW9kdWxlcywgcmVtb3ZpbmcgdGhlbSBmcm9tIDpkYXRhOmBzeXMucGF0aGAKICAgIGFuZCByZW1vdmluZyB0aGVpciBhdHRyaWJ1dGVzLiBBZnRlciB0aGlzIHRoZSBtb2R1bGVzIGFyZSBub3QgcmVnaXN0ZXJlZAogICAgYW55bW9yZSBhbmQgaWYgdGhleSBhcmUgbm90IHJlZmVyZW5jZWQgZnJvbSB1c2VyIGNvZGUgYW55bW9yZSB0aGV5IHdpbGwgYmUKICAgIGdhcmJhZ2UgY29sbGVjdGVkLgoKICAgIElmIG5vIGZha2UgcGFja2FnZSB0cmVlICpuYW1lKiBleGlzdHMgYSA6ZXhjOmBWYWx1ZUVycm9yYCB3aWxsIGJlIHJhaXNlZC4KICAgICIiIgoKICAgICMgR2V0IHRoZSBwYWNrYWdlIGVudHJ5IHZpYSBpdHMgZW50cnkgaW4gc3lzLm1vZHVsZXMKICAgIHBhY2thZ2UgPSBzeXMubW9kdWxlcy5nZXQobmFtZSwgTm9uZSkKICAgIGlmIHBhY2thZ2UgaXMgTm9uZToKICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCJObyBmYWtlIHBhY2thZ2Ugd2l0aCB0aGUgbmFtZSB7MH0gZm91bmQiLmZvcm1hdChuYW1lKSkKCiAgICBpZiBub3QgaXNpbnN0YW5jZShwYWNrYWdlLCBGYWtlUGFja2FnZSk6CiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigiVGhlIG1vZHVsZSB7MH0gaXMgbm90IGEgZmFrZSBwYWNrYWdlIi5mb3JtYXQobmFtZSkpCgogICAgIyBBdHRlbXB0IHRvIHJlbW92ZSB0aGUgbG9hZGVyIGZyb20gc3lzLm1ldGFfcGF0aAoKICAgIGxvYWRlcnMgPSBbaSBmb3IgaSBpbiBzeXMubWV0YV9wYXRoIGlmIGlzaW5zdGFuY2UoaSwgRmFrZVBhY2thZ2VMb2FkZXIpIGFuZCBpLnJvb3QgPT0gbmFtZV0KICAgIGZvciBsb2FkZXIgaW4gbG9hZGVyczoKICAgICAgICBzeXMubWV0YV9wYXRoLnJlbW92ZShsb2FkZXIpCgogICAgIyBSZW1vdmUgYWxsIG1vZHVsZSBhbmQgc3VibW9kdWxlIGVudHJpZXMgZnJvbSBzeXMubW9kdWxlcwogICAgcGFja2FnZS5fcmVtb3ZlKCkKCiAgICAjIEl0IGlzIGltcG9zc2libGUgdG8ga2lsbCByZWZlcmVuY2VzIHRvIHRoZSBtb2R1bGVzLCBidXQgYWxsIHRyYWNlcwogICAgIyBvZiBpdCBoYXZl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TVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKIyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKIyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiMgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKIyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRQojIFNPRlRXQVJFLgoKZnJvbSBfX2Z1dHVyZV9fIGltcG9ydCB1bmljb2RlX2xpdGVyYWxzCgppbXBvcnQgcmUKaW1wb3J0IGFzdApmcm9tIG9wZXJhdG9yIGltcG9ydCBpdGVtZ2V0dGVyCmZyb20gY29udGV4dGxpYiBpbXBvcnQgY29udGV4dG1hbmFnZXIKCmZyb20gdXRpbCBpbXBvcnQgRGVjb21waWxlckJhc2UsIFdvcmRDb25jYXRlbmF0b3IsIHJlY29uc3RydWN0X3BhcmFtaW5mbywgXAogICAgICAgICAgICAgICAgIHNpbXBsZV9leHByZXNzaW9uX2d1YXJkLCBzcGxpdF9sb2dpY2FsX2xpbmVzLCBEaXNwYXRjaGVyCmltcG9ydCBjb2RlZ2VuCgojIE1haW4gQVBJCgpkZWYgcHByaW50KG91dF9maWxlLCBhc3QsIGluZGVudF9sZXZlbD0wLCBsaW5lbnVtYmVyPTEsCiAgICAgICAgICAgZGVjb21waWxlX3B5dGhvbj1GYWxzZSwKICAgICAgICAgICBza2lwX2luZGVudF91bnRpbF93cml0ZT1GYWxzZSwgcHJpbnRsb2NrPU5vbmUpOgogICAgcmV0dXJuIFNMRGVjb21waWxlcihvdXRfZmlsZSwgcHJpbnRsb2NrPXByaW50bG9jaywKICAgICAgICAgICAgICAgICBkZWNvbXBpbGVfcHl0aG9uPWRlY29tcGlsZV9weXRob24pLmR1bXAoCiAgICAgICAgICAgICAgICAgICAgIGFzdCwgaW5kZW50X2xldmVsLCBsaW5lbnVtYmVyLCBza2lwX2luZGVudF91bnRpbF93cml0ZSkKCiMgaW1wbGVtZW50YXRpb24KCmNsYXNzIFNMRGVjb21waWxlcihEZWNvbXBpbGVyQmFzZSk6CiAgICAiIiIKICAgIGFuIG9iamVjdCB3aGljaCBoYW5kbGVzIHRoZSBkZWNvbXBpbGF0aW9uIG9mIHJlbnB5IHNjcmVlbiBsYW5ndWFnZSAxIHNjcmVlbnMgdG8gYSBnaXZlbiBzdHJlYW0KICAgICIiIgoKICAgICMgVGhpcyBkaWN0aW9uYXJ5IGlzIGEgbWFwcGluZyBvZiBzdHJpbmc6IHVuYm91bmRfbWV0aG9kLCB3aGljaCBpcyB1c2VkIHRvIGRldGVybWluZQogICAgIyB3aGF0IG1ldGhvZCB0byBjYWxsIGZvciB3aGljaCBzdGF0ZW1lbnQKICAgIGRpc3BhdGNoID0gRGlzcGF0Y2hlcigpCgogICAgZGVmIF9faW5pdF9fKHNlbGYsIG91dF9maWxlPU5vbmUsIGRlY29tcGlsZV9weXRob249RmFsc2UsCiAgICAgICAgICAgICAgICAgaW5kZW50YXRpb249IiAgICAiLCBwcmludGxvY2s9Tm9uZSk6CiAgICAgICAgc3VwZXIoU0xEZWNvbXBpbGVyLCBzZWxmKS5fX2luaXRfXyhvdXRfZmlsZSwgaW5kZW50YXRpb24sIHByaW50bG9jaykKICAgICAgICBzZWxmLmRlY29tcGlsZV9weXRob24gPSBkZWNvbXBpbGVfcHl0aG9uCiAgICAgICAgc2VsZi5zaG91bGRfYWR2YW5jZV90b19saW5lID0gVHJ1ZQogICAgICAgIHNlbGYuaXNfcm9vdCA9IFRydWUKCiAgICBkZWYgZHVtcChzZWxmLCBhc3QsIGluZGVudF9sZXZlbD0wLCBsaW5lbnVtYmVyPTEsIHNraXBfaW5kZW50X3VudGlsX3dyaXRlPUZhbHNlKToKICAgICAgICBzZWxmLmluZGVudF9sZXZlbCA9IGluZGVudF9sZXZlbAogICAgICAgIHNlbGYubGluZW51bWJlciA9IGxpbmVudW1iZXIKICAgICAgICBzZWxmLnNraXBfaW5kZW50X3VudGlsX3dyaXRlID0gc2tpcF9pbmRlbnRfdW50aWxfd3JpdGUKICAgICAgICBzZWxmLnByaW50X3NjcmVlbihhc3QpCiAgICAgICAgcmV0dXJuIHNlbGYubGluZW51bWJlcgoKICAgIGRlZiBhZHZhbmNlX3RvX2xpbmUoc2VsZiwgbGluZW51bWJlcik6CiAgICAgICAgaWYgc2VsZi5zaG91bGRfYWR2YW5jZV90b19saW5lOgogICAgICAgICAgICBzdXBlcihTTERlY29tcGlsZXIsIHNlbGYpLmFkdmFuY2VfdG9fbGluZShsaW5lbnVtYmVyKQoKICAgIGRlZiBzYXZlX3N0YXRlKHNlbGYpOgogICAgICAgIHJldHVybiAoc3VwZXIoU0xEZWNvbXBpbGVyLCBzZWxmKS5zYXZlX3N0YXRlKCksCiAgICAgICAgICAgICAgICBzZWxmLnNob3VsZF9hZHZhbmNlX3RvX2xpbmUsIHNlbGYuaXNfcm9vdCkKCiAgICBkZWYgY29tbWl0X3N0YXRlKHNlbGYsIHN0YXRlKToKICAgICAgICBzdXBlcihTTERlY29tcGlsZXIsIHNlbGYpLmNvbW1pdF9zdGF0ZShzdGF0ZVswXSkKCiAgICBkZWYgcm9sbGJhY2tfc3RhdGUoc2VsZiwgc3RhdGUpOgogICAgICAgIHNlbGYuc2hvdWxkX2FkdmFuY2VfdG9fbGluZSA9IHN0YXRlWzFdCiAgICAgICAgc2VsZi5pc19yb290ID0gc3RhdGVbMl0KICAgICAgICBzdXBlcihTTERlY29tcGlsZXIsIHNlbGYpLnJvbGxiYWNrX3N0YXRlKHN0YXRlWzBdKQoKICAgIGRlZiB0b19zb3VyY2Uoc2VsZiwgbm9kZSk6CiAgICAgICAgcmV0dXJuIGNvZGVnZW4udG9fc291cmNlKG5vZGUsIHNlbGYuaW5kZW50YXRpb24sIEZhbHNlLCBUcnVlKQoKICAgIEBjb250ZXh0bWFuYWdlcgogICAgZGVmIG5vdF9yb290KHNlbGYpOgogICAgICAgICMgV2hlbmV2ZXIgYW55dGhpbmcgZXhjZXB0IHNjcmVlbiBpdHNlbGYgcHJpbnRzIGFueSBjaGlsZCBub2RlcywgaXQKICAgICAgICAjIHNob3VsZCBiZSBpbnNpZGUgYSAid2l0aCBzZWxmLm5vdF9yb290KCkiIGJsb2NrLiBJdCBkb2Vzbid0IG1hdHRlciBpZgogICAgICAgICMgeW91IGNhdGNoIG1vcmUgaW5zaWRlIG9mIHRoZSB3aXRoIGJsb2NrIHRoYW4geW91IG5lZWQsIGFzIGxvbmcgYXMgeW91CiAgICAgICAgIyBkb24ndCBmYWxsIGJhY2sgdG8gY2FsbGluZyBwcmludF9weXRob24oKSBmcm9tIGluc2lkZSBpdC4KICAgICAgICBpc19yb290ID0gc2VsZi5pc19yb290CiAgICAgICAgc2VsZi5pc19yb290ID0gRmFsc2UKICAgICAgICB0cnk6CiAgICAgICAgICAgIHlpZWxkCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgc2VsZi5pc19yb290ID0gaXNfcm9vdAoKICAgICMgRW50cnkgcG9pbnQgZnVuY3Rpb25zCgogICAgZGVmIHByaW50X3NjcmVlbihzZWxmLCBhc3QpOgogICAgICAgICMgSGVyZSB3ZSBkbyB0aGUgcHJvY2Vzc2luZyBvZiB0aGUgc2NyZWVuIHN0YXRlbWVudCwgYW5kIHdlCiAgICAgICAgIyBzd2l0Y2ggb3ZlciB0byBwYXJzaW5nIG9mIHRoZSBweXRob24gc3RyaW5nIHJlcHJlc2VudGF0aW9uCgogICAgICAgICMgUHJpbnQgdGhlIHNjcmVlbiBzdGF0ZW1lbnQgYW5kIGNyZWF0ZSB0aGUgYmxvY2sKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZSgic2NyZWVuICVzIiAlIGFzdC5uYW1lKQogICAgICAgICMgSWYgd2UgaGF2ZSBwYXJhbWV0ZXJzLCBwcmludCB0aGVtLgogICAgICAgIGlmIGhhc2F0dHIoYXN0LCAicGFyYW1ldGVycyIpIGFuZCBhc3QucGFyYW1ldGVyczoKICAgICAgICAgICAgc2VsZi53cml0ZShyZWNvbnN0cnVjdF9wYXJhbWluZm8oYXN0LnBhcmFtZXRlcnMpKQoKICAgICAgICBpZiBhc3QudGFnOgogICAgICAgICAgICBzZWxmLndyaXRlKCIgdGFnICVzIiAlIGFzdC50YWcpCgogICAgICAgIGtleXdvcmRzID0ge2FzdC5jb2RlLmxvY2F0aW9uWzFdOiBXb3JkQ29uY2F0ZW5hdG9yKEZhbHNlLCBUcnVlKX0KICAgICAgICBmb3Iga2V5IGluICgnbW9kYWwnLCAnem9yZGVyJywgJ3ZhcmlhbnQnLCAncHJlZGljdCcpOgogICAgICAgICAgICB2YWx1ZSA9IGdldGF0dHIoYXN0LCBrZXkpCiAgICAgICAgICAgICMgTm9uLVVuaWNvZGUgc3RyaW5ncyBhcmUgZGVmYXVsdCB2YWx1ZXMgcmF0aGVyIHRoYW4gdXNlci1zdXBwbGllZAogICAgICAgICAgICAjIHZhbHVlcywgc28gd2UgZG9uJ3QgbmVlZCB0byB3cml0ZSB0aGVtIG91dC4KICAgICAgICAgICAgaWYgaXNpbnN0YW5jZSh2YWx1ZSwgdW5pY29kZSk6CiAgICAgICAgICAgICAgICBpZiB2YWx1ZS5saW5lbnVtYmVyIG5vdCBpbiBrZXl3b3JkczoKICAgICAgICAgICAgICAgICAgICBrZXl3b3Jkc1t2YWx1ZS5saW5lbnVtYmVyXSA9IFdvcmRDb25jYXRlbmF0b3IoRmFsc2UsIFRydWUpCiAgICAgICAgICAgICAgICBrZXl3b3Jkc1t2YWx1ZS5saW5lbnVtYmVyXS5hcHBlbmQoIiVzICVzIiAlIChrZXksIHZhbHVlKSkKICAgICAgICBrZXl3b3JkcyA9IHNvcnRlZChbKGssIHYuam9pbigpKSBmb3IgaywgdiBpbiBrZXl3b3Jkcy5pdGVtcygpXSwKICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk9aXRlbWdldHRlcigwKSkgIyBzbyB0aGUgZmlyc3Qgb25lIGlzIHJpZ2h0CiAgICAgICAgaWYgc2VsZi5kZWNvbXBpbGVfcHl0aG9uOgogICAgICAgICAgICBzZWxmLnByaW50X2tleXdvcmRzX2FuZF9ub2RlcyhrZXl3b3JkcywgTm9uZSwgVHJ1ZSkKICAgICAgICAgICAgd2l0aCBzZWxmLmluY3JlYXNlX2luZGVudCgpOgogICAgICAgICAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgICAgICAgICAgc2VsZi53cml0ZSgicHl0aG9uOiIpCiAgICAgICAgICAgICAgICB3aXRoIHNlbGYuaW5jcmVhc2VfaW5kZW50KCk6CiAgICAgICAgICAgICAgICAgICAgIyBUaGUgZmlyc3QgbGluZSBpcyBhbHdheXMgIl8xID0gKF9uYW1lLCAwKSIsIHdoaWNoIGdldHMgaW5jbHVkZWQKICAgICAgICAgICAgICAgICAgICAjIGV2ZW4gaWYgdGhlIHB5dGhvbjogYmxvY2sgaXMgdGhlIG9ubHkgdGhpbmcgaW4gdGhlIHNjcmVlbi4gRG9uJ3QKICAgICAgICAgICAgICAgICAgICAjIGluY2x1ZGUgb3Vycywgc2luY2UgaWYgd2UgZG8sIGl0J2xsIGJlIGluY2x1ZGVkIHR3aWNlIHdoZW4KICAgICAgICAgICAgICAgICAgICAjIHJlY29tcGlsZWQuCiAgICAgICAgICAgICAgICAgICAgc2VsZi53cml0ZV9saW5lcyhzZWxmLnRvX3NvdXJjZShhc3QuY29kZS5zb3VyY2UpLnNwbGl0bGluZXMoKVsxOl0pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5wcmludF9rZXl3b3Jkc19hbmRfbm9kZXMoa2V5d29yZHMsIGFzdC5jb2RlLnNvdXJjZS5ib2R5LCBGYWxzZSkKCiAgICBkZWYgc3BsaXRfbm9kZXNfYXRfaGVhZGVycyhzZWxmLCBub2Rlcyk6CiAgICAgICAgaWYgbm90IG5vZGVzOgogICAgICAgICAgICByZXR1cm4gW10KICAgICAgICBydiA9IFtub2Rlc1s6MV1dCiAgICAgICAgcGFyZW50X2lkID0gc2VsZi5wYXJzZV9oZWFkZXIobm9kZXNbMF0pCiAgICAgICAgaWYgcGFyZW50X2lkIGlzIE5vbmU6CiAgICAgICAgICAgIHJhaXNlIEV4Y2VwdGlvbigKICAgICAgICAgICAgICAgICJGaXJzdCBub2RlIHBhc3NlZCB0byBzcGxpdF9ub2Rlc19hdF9oZWFkZXJzIHdhcyBub3QgYSBoZWFkZXIiKQogICAgICAgIGZvciBpIGluIG5vZGVzWzE6XToKICAgICAgICAgICAgaWYgc2VsZi5wYXJzZV9oZWFkZXIoaSkgPT0gcGFyZW50X2lkOgogICAgICAgICAgICAgICAgcnYuYXBwZW5kKFtpXSkKICAgICAgICAgICAgICAgIGhlYWRlciA9IGkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHJ2Wy0xXS5hcHBlbmQoaSkKICAgICAgICByZXR1cm4gcnYKCiAgICBkZWYgcHJpbnRfbm9kZXMoc2VsZiwgbm9kZXMsIGV4dHJhX2luZGVudD0wLCBoYXNfYmxvY2s9RmFsc2UpOgogICAgICAgICMgUHJpbnQgYSBibG9jayBvZiBzdGF0ZW1lbnRzLCBzcGxpdHRpbmcgaXQgdXAgb24gb25lIGxldmVsLgogICAgICAgICMgVGhlIHNjcmVlbiBsYW5ndWFnZSBwYXJzZXIgZW1pdHMgbGluZXMgaW4gdGhlIHNoYXBlIF8wID0gKF8wLCAwKSBmcm9tIHdoaWNoIGluZGVudGF0aW9uIGNhbiBiZSByZXZlYWxlZC4KICAgICAgICAjIEl0IHRyYW5zbGF0ZXMgcm91Z2hseSB0byAiaWQgPSAocGFyZW50X2lkLCBpbmRleF9pbl9wYXJlbnRfY2hpbGRyZW4pIi4gV2hlbiBwYXJzaW5nIGEgYmxvY2sKICAgICAgICAjIHBhcnNlIHRoZSBmaXJzdCBoZWFkZXIgbGluZSB0byBmaW5kIHRoZSBwYXJlbnRfaWQsIGFuZCB0aGVuIHNwbGl0IGFyb3VuZCBoZWFkZXJzIHdpdGggdGhlIHNhbWUgcGFyZW50IGlkCiAgICAgICAgIyBpbiB0aGlzIGJsb2NrLgogICAgICAgIGlmIGhhc19ibG9jayBhbmQgbm90IG5vZGVzOgogICAgICAgICAgICByYWlzZSBCYWRIYXNCbG9ja0V4Y2VwdGlvbigpCiAgICAgICAgc3BsaXQgPSBzZWxmLnNwbGl0X25vZGVzX2F0X2hlYWRlcnMobm9kZXMpCiAgICAgICAgd2l0aCBzZWxmLmluY3JlYXNlX2luZGVudChleHRyYV9pbmRlbnQpOgogICAgICAgICAgICBmb3IgaSBpbiBzcGxpdDoKICAgICAgICAgICAgICAgIHNlbGYucHJpbnRfbm9kZShpWzBdLCBpWzE6XSwgaGFzX2Jsb2NrKQoKICAgIGRlZiBnZXRfZmlyc3RfbGluZShzZWxmLCBub2Rlcyk6CiAgICAgICAgaWYgc2VsZi5nZXRfZGlzcGF0Y2hfa2V5KG5vZGVzWzBdKToKICAgICAgICAgICAgcmV0dXJuIG5vZGVzWzBdLnZhbHVlLmxpbmVubwogICAgICAgIGVsaWYgc2VsZi5pc19yZW5weV9mb3Iobm9kZXMpOgogICAgICAgICAgICByZXR1cm4gbm9kZXNbMV0udGFyZ2V0LmxpbmVubwogICAgICAgIGVsaWYgc2VsZi5pc19yZW5weV9pZihub2Rlcyk6CiAgICAgICAgICAgIHJldHVybiBub2Rlc1swXS50ZXN0LmxpbmVubwogICAgICAgIGVsc2U6CiAgICAgICAgICAgICMgV2Ugc2hvdWxkIG5ldmVyIGdldCBoZXJlLCBidXQganVzdCBpbiBjYXNlLi4uCiAgICAgICAgICAgIHJldHVybiBub2Rlc1swXS5saW5lbm8KCiAgICBkZWYgbWFrZV9wcmludGFibGVfa2V5d29yZHMoc2VsZiwga2V5d29yZHMsIGxpbmVubyk6CiAgICAgICAga2V5d29yZHMgPSBbKGkuYXJnLCBzaW1wbGVfZXhwcmVzc2lvbl9ndWFyZChzZWxmLnRvX3NvdXJjZShpLnZhbHVlKSksCiAgICAgICAgICAgIGkudmFsdWUubGluZW5vKSBmb3IgaSBpbiBrZXl3b3JkcyBpZiBub3QgKGlzaW5zdGFuY2UoCiAgICAgICAgICAgIGkudmFsdWUsIGFzdC5OYW1lKSBhbmQgKAogICAgICAgICAgICAoaS5hcmcgPT0gJ2lkJyBhbmQgaS52YWx1ZS5pZC5zdGFydHN3aXRoKCdfJykpIG9yCiAgICAgICAgICAgIChpLmFyZyA9PSAnc2NvcGUnIGFuZCBpLnZhbHVlLmlkID09ICdfc2NvcGUnKSkpXQogICAgICAgICMgU29ydCB0aGUga2V5d29yZHMgYWNjb3JkaW5nIHRvIHdoYXQgbGluZSB0aGV5IGJlbG9uZyBvbgogICAgICAgICMgVGhlIGZpcnN0IGVsZW1lbnQgYWx3YXlzIGV4aXN0cyBmb3IgdGhlIGxpbmUgdGhlIGJsb2NrIHN0YXJ0cyBvbiwKICAgICAgICAjIGV2ZW4gaWYgdGhlcmUncyBubyBrZXl3b3JkcyB0aGF0IGdvIG9uIGl0CiAgICAgICAga2V5d29yZHNfYnlfbGluZSA9IFtdCiAgICAgICAgY3VycmVudF9saW5lID0gW10KICAgICAgICBmb3IgaSBpbiBrZXl3b3JkczoKICAgICAgICAgICAgaWYgaVsyXSA+IGxpbmVubzoKICAgICAgICAgICAgICAgIGtleXdvcmRzX2J5X2xpbmUuYXBwZW5kKChsaW5lbm8sICcgJy5qb2luKGN1cnJlbnRfbGluZSkpKQogICAgICAgICAgICAgICAgbGluZW5vID0gaVsyXQogICAgICAgICAgICAgICAgY3VycmVudF9saW5lID0gW10KICAgICAgICAgICAgY3VycmVudF9saW5lLmV4dGVuZChpWzoyXSkKICAgICAgICBrZXl3b3Jkc19ieV9saW5lLmFwcGVuZCgobGluZW5vLCAnICcuam9pbihjdXJyZW50X2xpbmUpKSkKICAgICAgICByZXR1cm4ga2V5d29yZHNfYnlfbGluZQoKICAgIGRlZiBwcmludF9rZXl3b3Jkc19hbmRfbm9kZXMoc2VsZiwga2V5d29yZHMsIG5vZGVzLCBuZWVkc19jb2xvbik6CiAgICAgICAgIyBLZXl3b3JkcyBhbmQgY2hpbGQgbm9kZXMgY2FuIGJlIG1peGVkIHdpdGggZWFjaCBvdGhlciwgc28gdGhleSBuZWVkCiAgICAgICAgIyB0byBiZSBwcmludGVkIGF0IHRoZSBzYW1lIHRpbWUuIFRoaXMgZnVuY3Rpb24gdGFrZXMgZWFjaCBsaXN0IGFuZAogICAgICAgICMgY29tYmluZXMgdGhlbSBpbnRvIG9uZSwgdGhlbiBwcmludHMgaXQuCiAgICAgICAgIwogICAgICAgICMgVGhpcyBmdW5jdGlvbiBhc3N1bWVzIGxpbmUgbnVtYmVycyBvZiBub2RlcyBiZWZvcmUga2V5d29yZHMgYXJlCiAgICAgICAgIyBjb3JyZWN0LCB3aGljaCBpcyB0aGUgY2FzZSBmb3IgdGhlICJzY3JlZW4iIHN0YXRlbWVudCBpdHNlbGYuCiAgICAgICAgaWYga2V5d29yZHM6CiAgICAgICAgICAgIGlmIGtleXdvcmRzWzBdWzFdOgogICAgICAgICAgICAgICAgc2VsZi53cml0ZSgiICVzIiAlIGtleXdvcmRzWzBdWzFdKQogICAgICAgICAgICBpZiBsZW4oa2V5d29yZHMpICE9IDE6CiAgICAgICAgICAgICAgICBuZWVkc19jb2xvbiA9IFRydWUKICAgICAgICBpZiBub2RlczoKICAgICAgICAgICAgbm9kZWxpc3RzID0gWyhzZWxmLmdldF9maXJzdF9saW5lKGlbMTpdKSwgaSkKICAgICAgICAgICAgICAgICAgICAgICAgIGZvciBpIGluIHNlbGYuc3BsaXRfbm9kZXNfYXRfaGVhZGVycyhub2RlcyldCiAgICAgICAgICAgIG5lZWRzX2NvbG9uID0gVHJ1ZQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIG5vZGVsaXN0cyA9IFtdCiAgICAgICAgaWYgbmVlZHNfY29sb246CiAgICAgICAgICAgIHNlbGYud3JpdGUoIjoiKQogICAgICAgIHN0dWZmX3RvX3ByaW50ID0gc29ydGVkKGtleXdvcmRzWzE6XSArIG5vZGVsaXN0cywga2V5PWl0ZW1nZXR0ZXIoMCkpCiAgICAgICAgd2l0aCBzZWxmLmluY3JlYXNlX2luZGVudCgpOgogICAgICAgICAgICBmb3IgaSBpbiBzdHVmZl90b19wcmludDoKICAgICAgICAgICAgICAgICMgTm9kZXMgYXJlIGxpc3RzLiBLZXl3b3JkcyBhcmUgcmVhZHktdG8tcHJpbnQgc3RyaW5ncy4KICAgICAgICAgICAgICAgIGlmIHR5cGUoaVsxXSkgPT0gbGlzdDoKICAgICAgICAgICAgICAgICAgICBzZWxmLnByaW50X25vZGUoaVsxXVswXSwgaVsxXVsxOl0pCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuYWR2YW5jZV90b19saW5lKGlbMF0pCiAgICAgICAgICAgICAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoaVsxXSkKCiAgICBkZWYgZ2V0X2xpbmVzX3VzZWRfYnlfbm9kZShzZWxmLCBub2RlKToKICAgICAgICBzdGF0ZSA9IHNlbGYuc2F2ZV9zdGF0ZSgpCiAgICAgICAgc2VsZi5wcmludF9ub2RlKG5vZGVbMF0sIG5vZGVbMTpdKQogICAgICAgIGxpbmVudW1iZXIgPSBzZWxmLmxpbmVudW1iZXIKICAgICAgICBzZWxmLnJvbGxiYWNrX3N0YXRlKHN0YXRlKQogICAgICAgIHJldHVybiBsaW5lbnVtYmVyIC0gc2VsZi5saW5lbnVtYmVyCgogICAgZGVmIHByaW50X2J1Z2d5X2tleXdvcmRzX2FuZF9ub2RlcyhzZWxmLCBrZXl3b3Jkcywgbm9kZXMsIG5lZWRzX2NvbG9uLCBoYXNfYmxvY2spOgogICAgICAgICMgS2V5d29yZHMgYW5kIGNoaWxkIG5vZGVzIGNhbiBiZSBtaXhlZCB3aXRoIGVhY2ggb3RoZXIsIHNvIHRoZXkgbmVlZAogICAgICAgICMgdG8gYmUgcHJpbnRlZCBhdCB0aGUgc2FtZSB0aW1lLiBUaGlzIGZ1bmN0aW9uIHRha2VzIGVhY2ggbGlzdCBhbmQKICAgICAgICAjIGNvbWJpbmVzIHRoZW0gaW50byBvbmUsIHRoZW4gcHJpbnRzIGl0LgogICAgICAgICMKICAgICAgICAjIFRoaXMgZnVuY3Rpb24gYXNzdW1lcyBsaW5lIG51bWJlcnMgb2Ygbm9kZXMgYmVmb3JlIGtleXdvcmRzIGFyZQogICAgICAgICMgaW5jb3JyZWN0LCB3aGljaCBpcyB0aGUgY2FzZSBmb3IgZXZlcnl0aGluZyBleGNlcHQgdGhlICJzY3JlZW4iCiAgICAgICAgIyBzdGF0ZW1lbnQgaXRzZWxmLgogICAgICAgIGxhc3Rfa2V5d29yZF9saW5lbm8gPSBOb25lCiAgICAgICAgaWYga2V5d29yZHM6CiAgICAgICAgICAgIGlmIGtleXdvcmRzWzBdWzFdOgogICAgICAgICAgICAgICAgc2VsZi53cml0ZSgiICVzIiAlIGtleXdvcmRzWzBdWzFdKQogICAgICAgICAgICByZW1haW5pbmdfa2V5d29yZHMgPSBrZXl3b3Jkc1sxOl0KICAgICAgICAgICAgaWYgcmVtYWluaW5nX2tleXdvcmRzOgogICAgICAgICAgICAgICAgbmVlZHNfY29sb24gPSBUcnVlCiAgICAgICAgICAgICAgICBsYXN0X2tleXdvcmRfbGluZW5vID0gcmVtYWluaW5nX2tleXdvcmRzWy0xXVswXQogICAgICAgIGlmIG5vZGVzOgogICAgICAgICAgICBub2RlbGlzdHMgPSBbKHNlbGYuZ2V0X2ZpcnN0X2xpbmUoaVsxOl0pLCBpKQogICAgICAgICAgICAgICAgICAgICAgICAgZm9yIGkgaW4gc2VsZi5zcGxpdF9ub2Rlc19hdF9oZWFkZXJzKG5vZGVzKV0KICAgICAgICBlbHNlOgogICAgICAgICAgICBub2RlbGlzdHMgPSBbXQogICAgICAgIGZvciBrZXksIHZhbHVlIGluIGVudW1lcmF0ZShub2RlbGlzdHMpOgogICAgICAgICAgICBpZiBsYXN0X2tleXdvcmRfbGluZW5vIGlzIE5vbmUgb3IgdmFsdWVbMF0gPiBsYXN0X2tleXdvcmRfbGluZW5vOgogICAgICAgICAgICAgICAgbm9kZXNfYmVmb3JlX2tleXdvcmRzID0gbm9kZWxpc3RzWzprZXldCiAgICAgICAgICAgICAgICBub2Rlc19hZnRlcl9rZXl3b3JkcyA9IG5vZGVsaXN0c1trZXk6XQogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBlbHNlOgogICAgICAgICAgICBub2Rlc19iZWZvcmVfa2V5d29yZHMgPSBub2RlbGlzdHMKICAgICAgICAgICAgbm9kZXNfYWZ0ZXJfa2V5d29yZHMgPSBbXQogICAgICAgIGlmIG5vZGVzX2JlZm9yZV9rZXl3b3JkcyBvciAobm90IGhhc19ibG9jayBhbmQgbm9kZXNfYWZ0ZXJfa2V5d29yZHMpOgogICAgICAgICAgICBuZWVkc19jb2xvbiA9IFRydWUKICAgICAgICBpZiBuZWVkc19jb2xvbjoKICAgICAgICAgICAgc2VsZi53cml0ZSgiOiIpCiAgICAgICAgd2l0aCBzZWxmLmluY3JlYXNlX2luZGVudCgpOgogICAgICAgICAgICBzaG91bGRfYWR2YW5jZV90b19saW5lID0gc2VsZi5zaG91bGRfYWR2YW5jZV90b19saW5lCiAgICAgICAgICAgIHNlbGYuc2hvdWxkX2FkdmFuY2VfdG9fbGluZSA9IEZhbHNlCiAgICAgICAgICAgIHdoaWxlIG5vZGVzX2JlZm9yZV9rZXl3b3JkczoKICAgICAgICAgICAgICAgIGlmIG5vdCByZW1haW5pbmdfa2V5d29yZHM6CiAgICAgICAgICAgICAgICAgICAgIyBTb21ldGhpbmcgd2VudCB3cm9uZy4gV2UgYWxyZWFkeSBwcmludGVkIHRoZSBsYXN0IGtleXdvcmQsCiAgICAgICAgICAgICAgICAgICAgIyB5ZXQgdGhlcmUncyBzdGlsbCBub2RlcyBsZWZ0IHRoYXQgc2hvdWxkIGhhdmUgYmVlbiBwcmludGVkCiAgICAgICAgICAgICAgICAgICAgIyBiZWZvcmUgdGhlIGxhc3Qga2V5d29yZC4gSnVzdCBwcmludCB0aGVtIG5vdy4KICAgICAgICAgICAgICAgICAgICBmb3IgaSBpbiBub2Rlc19iZWZvcmVfa2V5d29yZHM6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYucHJpbnRfbm9kZShpWzFdWzBdLCBpWzFdWzE6XSkKICAgICAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICAgICAgIyBzdWJ0cmFjdCAxIGxpbmUgc2luY2UgLmluZGVudCgpIHVzZXMgMQogICAgICAgICAgICAgICAgbGluZXNfdG9fZ28gPSByZW1haW5pbmdfa2V5d29yZHNbMF1bMF0gLSBzZWxmLmxpbmVudW1iZXIgLSAxCiAgICAgICAgICAgICAgICBuZXh0X25vZGUgPSBub2Rlc19iZWZvcmVfa2V5d29yZHNbMF1bMV0KICAgICAgICAgICAgICAgIGlmIGxpbmVzX3RvX2dvID49IHNlbGYuZ2V0X2xpbmVzX3VzZWRfYnlfbm9kZShuZXh0X25vZGUpOgogICAgICAgICAgICAgICAgICAgIHNlbGYucHJpbnRfbm9kZShuZXh0X25vZGVbMF0sIG5leHRfbm9kZVsxOl0pCiAgICAgICAgICAgICAgICAgICAgbm9kZXNfYmVmb3JlX2tleXdvcmRzLnBvcCgwKQogICAgICAgICAgICAgICAgZWxpZiBub3Qgc2hvdWxkX2FkdmFuY2VfdG9fbGluZSBvciBsaW5lc190b19nbyA8PSAwOgogICAgICAgICAgICAgICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKHJlbWFpbmluZ19rZXl3b3Jkcy5wb3AoMClbMV0pCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoIlxuIiAqIGxpbmVzX3RvX2dvKQogICAgICAgICAgICBzZWxmLnNob3VsZF9hZHZhbmNlX3RvX2xpbmUgPSBzaG91bGRfYWR2YW5jZV90b19saW5lCiAgICAgICAgICAgIGZvciBpIGluIHJlbWFpbmluZ19rZXl3b3JkczoKICAgICAgICAgICAgICAgIHNlbGYuYWR2YW5jZV90b19saW5lKGlbMF0pCiAgICAgICAgICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKGlbMV0pCiAgICAgICAgd2l0aCBzZWxmLmluY3JlYXNlX2luZGVudCgxIGlmIG5vdCBoYXNfYmxvY2sgZWxzZSAwKToKICAgICAgICAgICAgZm9yIGkgaW4gbm9kZXNfYWZ0ZXJfa2V5d29yZHM6CiAgICAgICAgICAgICAgICBzZWxmLnByaW50X25vZGUoaVsxXVswXSwgaVsxXVsxOl0pCgogICAgZGVmIGdldF9kaXNwYXRjaF9rZXkoc2VsZiwgbm9kZSk6CiAgICAgICAgaWYgKGlzaW5zdGFuY2Uobm9kZSwgYXN0LkV4cHIpIGFuZAogICAgICAgICAgICAgICAgaXNpbnN0YW5jZShub2RlLnZhbHVlLCBhc3QuQ2FsbCkgYW5kCiAgICAgICAgICAgICAgICBpc2luc3RhbmNlKG5vZGUudmFsdWUuZnVuYywgYXN0LkF0dHJpYnV0ZSkgYW5kCiAgICAgICAgICAgICAgICBpc2luc3RhbmNlKG5vZGUudmFsdWUuZnVuYy52YWx1ZSwgYXN0Lk5hbWUpKToKICAgICAgICAgICAgcmV0dXJuIG5vZGUudmFsdWUuZnVuYy52YWx1ZS5pZCwgbm9kZS52YWx1ZS5mdW5jLmF0dHIKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gTm9uZQoKICAgIGRlZiBwcmludF9ub2RlKHNlbGYsIGhlYWRlciwgY29kZSwgaGFzX2Jsb2NrPUZhbHNlKToKICAgICAgICAjIEhlcmUgd2UgZGVyZXJtaW5lIGhvdyB0byBoYW5kbGUgYSBzdGF0ZW1lbnQuCiAgICAgICAgIyBUbyBkbyB0aGlzIHdlIGxvb2sgYXQgaG93IHRoZSBmaXJzdCBsaW5lIGluIHRoZSBzdGF0ZW1lbnQgY29kZSBzdGFydHMsIGFmdGVyIHRoZSBoZWFkZXIuCiAgICAgICAgIyBUaGVuIHdlIGNhbGwgdGhlIGFwcHJvcHJpYXRlIGZ1bmN0aW9uIGFzIHNwZWNpZmllZCBpbiB1aV9mdW5jdGlvbl9kaWN0LgogICAgICAgICMgSWYgdGhlIHN0YXRlbWVudCBpcyB1bmtub3duLCB3ZSBjYW4gc3RpbGwgZW1pdCB2YWxpZCBzY3JlZW4gY29kZSBieSBqdXN0CiAgICAgICAgIyBzdHVmZmluZyBpdCBpbnNpZGUgYSBweXRob24gYmxvY2suCgogICAgICAgICMgVGhlcmUncyAzIGNhdGVnb3JpZXMgb2YgdGhpbmdzIHRoYXQgd2UgY2FuIGNvbnZlcnQgdG8gc2NyZWVuY29kZToKICAgICAgICAjIGlmIHN0YXRlbWVudHMsIGZvciBzdGF0ZW1lbnRzLCBhbmQgZnVuY3Rpb24gY2FsbHMgb2YgdGhlCiAgICAgICAgIyBmb3JtICJmaXJzdC5zZWNvbmQoLi4uKSIuIEFueXRoaW5nIGVsc2UgZ2V0cyBjb252ZXJ0ZWQgdG8gUHl0aG9uLgogICAgICAgIGRpc3BhdGNoX2tleSA9IHNlbGYuZ2V0X2Rpc3BhdGNoX2tleShjb2RlWzBdKQogICAgICAgIGlmIGRpc3BhdGNoX2tleToKICAgICAgICAgICAgZnVuYyA9IHNlbGYuZGlzcGF0Y2guZ2V0KGRpc3BhdGNoX2tleSwgc2VsZi5wcmludF9weXRob24uX19mdW5jX18pCiAgICAgICAgICAgIGlmIGhhc19ibG9jazoKICAgICAgICAgICAgICAgIGlmIGZ1bmMgbm90IGluIChzZWxmLnByaW50X29uZWNoaWxkLl9fZnVuY19fLAogICAgICAgICAgICAgICAgICAgIHNlbGYucHJpbnRfbWFueWNoaWxkcmVuLl9fZnVuY19fKToKICAgICAgICAgICAgICAgICAgICByYWlzZSBCYWRIYXNCbG9ja0V4Y2VwdGlvbigpCiAgICAgICAgICAgICAgICBmdW5jKHNlbGYsIGhlYWRlciwgY29kZSwgVHJ1ZSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGZ1bmMoc2VsZiwgaGVhZGVyLCBjb2RlKQogICAgICAgIGVsaWYgaGFzX2Jsb2NrOgogICAgICAgICAgICByYWlzZSBCYWRIYXNCbG9ja0V4Y2VwdGlvbigpCiAgICAgICAgZWxpZiBzZWxmLmlzX3JlbnB5X2Zvcihjb2RlKToKICAgICAgICAgICAgc2VsZi5wcmludF9mb3IoaGVhZGVyLCBjb2RlKQogICAgICAgIGVsaWYgc2VsZi5pc19yZW5weV9pZihjb2RlKToKICAgICAgICAgICAgc2VsZi5wcmludF9pZihoZWFkZXIsIGNvZGUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgc2VsZi5wcmludF9weXRob24oaGVhZGVyLCBjb2RlKQogICAgIyBIZWxwZXIgcHJpbnRpbmcgZnVuY3Rpb25zCgogICAgZGVmIHByaW50X2FyZ3Moc2VsZiwgbm9kZSk6CiAgICAgICAgaWYgbm9kZS5hcmdzOgogICAgICAgICAgICBzZWxmLndyaXRlKCIgIiArICIgIi5qb2luKFtzaW1wbGVfZXhwcmVzc2lvbl9ndWFyZCgKICAgICAgICAgICAgICAgIHNlbGYudG9fc291cmNlKGkpKSBmb3IgaSBpbiBub2RlLmFyZ3NdKSkKCiAgICAjIE5vZGUgcHJpbnRpbmcgZnVuY3Rpb25zCgogICAgZGVmIHByaW50X3B5dGhvbihzZWxmLCBoZWFkZXIsIGNvZGUpOgogICAgICAgICMgVGhpcyBmdW5jdGlvbiBoYW5kbGVzIGFueSBzdGF0ZW1lbnQgd2hpY2ggaXMgYSBibG9jayBidXQgY291bGRuJ3QgbG9naWNhbGx5IGJlCiAgICAgICAgIyBUcmFuc2xhdGVkIHRvIGEgc2NyZWVuIHN0YXRlbWVudC4KICAgICAgICAjCiAgICAgICAgIyBSZW4nUHkncyBsaW5lIG51bWJlcnMgYXJlIHJlYWxseSwgcmVhbGx5IGJ1Z2d5LiBIZXJlJ3MgYSBzdW1tYXJ5OgogICAgICAgICMgSWYgd2UncmUgbm90IGRpcmVjdGx5IHVuZGVyIHRoZSByb290IHNjcmVlbiwgYW5kIGEga2V5d29yZCBmb3Igb3VyCiAgICAgICAgIyBwYXJlbnQgZm9sbG93cyB1cywgdGhlbiBhbGwgb2Ygb3VyIGxpbmUgbnVtYmVycyB3aWxsIGJlIGVxdWFsIHRvIHRoZQogICAgICAgICMgbGluZSBudW1iZXIgb2YgdGhhdCBrZXl3b3JkLgogICAgICAgICMgSWYgd2UncmUgbm90IGRpcmVjdGx5IHVuZGVyIHRoZSByb290IHNjcmVlbiwgYW5kIG5vIGtleXdvcmRzIGZvciBvdXIKICAgICAgICAjIHBhcmVudCBmb2xsb3cgdXMsIHRoZW4gaGVhZGVyLmxpbmVubyBpcyB0aGUgbGluZSBudW1iZXIgb2Ygd2hhdGV2ZXIKICAgICAgICAjIGl0IGlzIHRoYXQgcHJlY2VkZWQgdXMgKHdoaWNoIGlzIGNvbXBsZXRlbHkgdXNlbGVzcykuCiAgICAgICAgIyBJZiB3ZSdyZSBkaXJlY3RseSB1bmRlciB0aGUgcm9vdCAic2NyZWVuIiwgdGhlbiBoZWFkZXIubGluZW5vIGlzIHRoZQogICAgICAgICMgbGluZSB0aGF0ICIkIiBvciAicHl0aG9uOiIgYXBwZWFyZWQgb24uCiAgICAgICAgIyBJZiB3ZSdyZSBub3QgYSBjaGlsZCBmb2xsb3dlZCBieSBhIGtleXdvcmQsIGFuZCAiJCIgd2FzIHVzZWQsIHRoZW4KICAgICAgICAjIGNvZGVbMF0ubGluZW5vIGlzIHRoZSBsaW5lIHRoYXQgdGhlIGNvZGUgYWN0dWFsbHkgc3RhcnRzIG9uLCBidXQgaWYKICAgICAgICAjICJweXRob246IiB3YXMgdXNlZCwgdGhlbiBhbGwgb2YgY29kZSdzIGxpbmUgbnVtYmVycyB3aWxsIGJlIDEgZ3JlYXRlcgogICAgICAgICMgdGhhbiB0aGUgbGluZSBlYWNoIG9uZSBzaG91bGQgYmUuCiAgICAgICAgc291cmNlID0gc2VsZi50b19zb3VyY2UoYXN0Lk1vZHVsZShib2R5PWNvZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lbm89Y29kZVswXS5saW5lbm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xfb2Zmc2V0PTApKS5yc3RyaXAoKS5sc3RyaXAoJ1xuJykKICAgICAgICBsaW5lcyA9IHNvdXJjZS5zcGxpdGxpbmVzKCkKICAgICAgICBpZiBsZW4oc3BsaXRfbG9naWNhbF9saW5lcyhzb3VyY2UpKSA9PSAxIGFuZCAoCiAgICAgICAgICAgICAgICAobm90IHNlbGYuaXNfcm9vdCBhbmQgY29kZVswXS5saW5lbm8gPCBzZWxmLmxpbmVudW1iZXIgKyAzKSBvcgogICAgICAgICAgICAgICAgaGVhZGVyLmxpbmVubyA+PSBjb2RlWzBdLmxpbmVubyk6CiAgICAgICAgICAgICMgVGhpcyBpcyBvbmx5IG9uZSBsb2dpY2FsIGxpbmUsIHNvIGl0J3MgcG9zc2libGUgdGhhdCBpdCB3YXMgJCwKICAgICAgICAgICAgIyBhbmQgZWl0aGVyIGl0J3Mgbm90IGluIHRoZSByb290IChzbyB3ZSBkb24ndCBrbm93IHdoYXQgdGhlCiAgICAgICAgICAgICMgb3JpZ2luYWwgc291cmNlIHVzZWQpLCBvciBpdCBpcyBpbiB0aGUgcm9vdCBhbmQgd2Uga25vdyBpdCB1c2VkICQuCiAgICAgICAgICAgICMgQWxzbywgaWYgd2UgZG9uJ3Qga25vdyBmb3Igc3VyZSB3aGF0IHdhcyB1c2VkLCBidXQgd2UgaGF2ZSBlbm91Z2gKICAgICAgICAgICAgIyByb29tIHRvIHVzZSBhICJweXRob24iIGJsb2NrLCB0aGVuIHVzZSBpdCBpbnN0ZWFkLCBzaW5jZSBpdCdsbAogICAgICAgICAgICAjIHJlc3VsdCBpbiBldmVyeXRoaW5nIHRha2luZyB1cCBvbmUgZmV3ZXIgbGluZSAoc2luY2UgaXQnbGwgdXNlCiAgICAgICAgICAgICMgb25lIG1vcmUsIGJ1dCBzdGFydCB0d28gc29vbmVyKS4KICAgICAgICAgICAgc2VsZi5hZHZhbmNlX3RvX2xpbmUoY29kZVswXS5saW5lbm8pCiAgICAgICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICAgICAgc2VsZi53cml0ZSgiJCAlcyIgJSBsaW5lc1swXSkKICAgICAgICAgICAgc2VsZi53cml0ZV9saW5lcyhsaW5lc1sxOl0pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBFaXRoZXIgdGhpcyBpcyBtb3JlIHRoYW4gb25lIGxvZ2ljYWwgbGluZSwgc28gaXQgaGFzIHRvIGJlIGEKICAgICAgICAgICAgIyBweXRob24gYmxvY2ssIG9yIGl0IHdhcyBpbiB0aGUgcm9vdCBhbmQgd2UgY2FuIHRlbGwgdGhhdCBpdCB3YXMKICAgICAgICAgICAgIyBvcmlnaW5hbGx5IGEgcHl0aG9uIGJsb2NrLgogICAgICAgICAgICBpZiBzZWxmLmlzX3Jvb3Q6CiAgICAgICAgICAgICAgICBzZWxmLmFkdmFuY2VfdG9fbGluZShoZWFkZXIubGluZW5vKQogICAgICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgICAgIHNlbGYud3JpdGUoInB5dGhvbjoiKQogICAgICAgICAgICBzZWxmLmFkdmFuY2VfdG9fbGluZShjb2RlWzBdLmxpbmVubyAtIDEpCiAgICAgICAgICAgIHdpdGggc2VsZi5pbmNyZWFzZV9pbmRlbnQoKToKICAgICAgICAgICAgICAgIHNlbGYud3JpdGVfbGluZXMobGluZXMpCgogICAgZGVmIGlzX3JlbnB5X2lmKHNlbGYsIG5vZGVzKToKICAgICAgICByZXR1cm4gbGVuKG5vZGVzKSA9PSAxIGFuZCBpc2luc3RhbmNlKG5vZGVzWzBdLCBhc3QuSWYpIGFuZCAoCiAgICAgICAgICAgIG5vZGVzWzBdLmJvZHkgYW5kIHNlbGYucGFyc2VfaGVhZGVyKG5vZGVzWzBdLmJvZHlbMF0pKSBhbmQgKAogICAgICAgICAgICAgICAgbm90IG5vZGVzWzBdLm9yZWxzZSBvciBzZWxmLmlzX3JlbnB5X2lmKG5vZGVzWzBdLm9yZWxzZSkgb3IKICAgICAgICAgICAgICAgIHNlbGYucGFyc2VfaGVhZGVyKG5vZGVzWzBdLm9yZWxzZVswXSkpCgogICAgZGVmIGlzX3JlbnB5X2ZvcihzZWxmLCBub2Rlcyk6CiAgICAgICAgcmV0dXJuIChsZW4obm9kZXMpID09IDIgYW5kIGlzaW5zdGFuY2Uobm9kZXNbMF0sIGFzdC5Bc3NpZ24pIGFuZAogICAgICAgICAgICBsZW4obm9kZXNbMF0udGFyZ2V0cykgPT0gMSBhbmQKICAgICAgICAgICAgaXNpbnN0YW5jZShub2Rlc1swXS50YXJnZXRzWzBdLCBhc3QuTmFtZSkgYW5kCiAgICAgICAgICAgIHJlLm1hdGNoKHIiX1swLTldKyQiLCBub2Rlc1swXS50YXJnZXRzWzBdLmlkKSBhbmQKICAgICAgICAgICAgaXNpbnN0YW5jZShub2Rlc1swXS52YWx1ZSwgYXN0Lk51bSkgYW5kIG5vZGVzWzBdLnZhbHVlLm4gPT0gMCBhbmQKICAgICAgICAgICAgaXNpbnN0YW5jZShub2Rlc1sxXSwgYXN0LkZvcikgYW5kIG5vdCBub2Rlc1sxXS5vcmVsc2UgYW5kCiAgICAgICAgICAgIG5vZGVzWzFdLmJvZHkgYW5kIHNlbGYucGFyc2VfaGVhZGVyKG5vZGVzWzFdLmJvZHlbMF0pIGFuZAogICAgICAgICAgICBpc2luc3RhbmNlKG5vZGVzWzFdLmJvZHlbLTFdLCBhc3QuQXVnQXNzaWduKSBhbmQKICAgICAgICAgICAgaXNpbnN0YW5jZShub2Rlc1sxXS5ib2R5Wy0xXS5vcCwgYXN0LkFkZCkgYW5kCiAgICAgICAgICAgIGlzaW5zdGFuY2Uobm9kZXNbMV0uYm9keVstMV0udGFyZ2V0LCBhc3QuTmFtZSkgYW5kCiAgICAgICAgICAgIHJlLm1hdGNoKHIiX1swLTldKyQiLCBub2Rlc1sxXS5ib2R5Wy0xXS50YXJnZXQuaWQpIGFuZAogICAgICAgICAgICBpc2luc3RhbmNlKG5vZGVzWzFdLmJvZHlbLTFdLnZhbHVlLCBhc3QuTnVtKSBhbmQKICAgICAgICAgICAgbm9kZXNbMV0uYm9keVstMV0udmFsdWUubiA9PSAxKQoKICAgIGRlZiBzdHJpcF9wYXJlbnMoc2VsZiwgdGV4dCk6CiAgICAgICAgaWYgdGV4dCBhbmQgdGV4dFswXSA9PSAnKCcgYW5kIHRleHRbLTFdID09ICcpJzoKICAgICAgICAgICAgcmV0dXJuIHRleHRbMTotMV0KICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gdGV4dAoKICAgIGRlZiBwcmludF9pZihzZWxmLCBoZWFkZXIsIGNvZGUpOgogICAgICAgICMgSGVyZSB3ZSBoYW5kbGUgdGhlIGlmIHN0YXRlbWVudC4gSXQgbWlnaHQgYmUgdmFsaWQgcHl0aG9uIGJ1dCB3ZSBjYW4gY2hlY2sgZm9yIHRoaXMgYnkKICAgICAgICAjIGNoZWNraW5nIGZvciB0aGUgaGVhZGVyIHRoYXQgc2hvdWxkIG5vcm1hbGx5IG9jY3VyIHdpdGhpbiB0aGUgaWYgc3RhdGVtZW50LgogICAgICAgICMgVGhlIGlmIHN0YXRlbWVudCBwYXJzZXIgbWlnaHQgYWxzbyBnZW5lcmF0ZSBhIHNlY29uZCBoZWFkZXIgaWYgdGhlcmUncyBtb3JlIHRoYW4gb25lIHNjcmVlbgogICAgICAgICMgc3RhdGVtZW50IGVuY2xvc2VkIGluIHRoZSBpZi9lbGlmL2Vsc2Ugc3RhdGVtZW50cy4gV2UnbGwgdGFrZSBjYXJlIG9mIHRoYXQgdG9vLgogICAgICAgIHNlbGYuYWR2YW5jZV90b19saW5lKHNlbGYuZ2V0X2ZpcnN0X2xpbmUoY29kZSkpCiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoImlmICVzOiIgJSBzZWxmLnN0cmlwX3BhcmVucyhzZWxmLnRvX3NvdXJjZShjb2RlWzBdLnRlc3QpKSkKICAgICAgICBpZiAobGVuKGNvZGVbMF0uYm9keSkgPj0gMiBhbmQgc2VsZi5wYXJzZV9oZWFkZXIoY29kZVswXS5ib2R5WzBdKSBhbmQKICAgICAgICAgICAgc2VsZi5wYXJzZV9oZWFkZXIoY29kZVswXS5ib2R5WzFdKSk6CiAgICAgICAgICAgIGJvZHkgPSBjb2RlWzBdLmJvZHlbMTpdCiAgICAgICAgZWxzZToKICAgICAgICAgICAgYm9keSA9IGNvZGVbMF0uYm9keQogICAgICAgIHdpdGggc2VsZi5ub3Rfcm9vdCgpOgogICAgICAgICAgICBzZWxmLnByaW50X25vZGVzKGJvZHksIDEpCiAgICAgICAgICAgIGlmIGNvZGVbMF0ub3JlbHNlOgogICAgICAgICAgICAgICAgaWYgc2VsZi5pc19yZW5weV9pZihjb2RlWzBdLm9yZWxzZSk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5hZHZhbmNlX3RvX2xpbmUoY29kZVswXS5vcmVsc2VbMF0udGVzdC5saW5lbm8pCiAgICAgICAgICAgICAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoImVsIikgIyBiZWdpbm5pbmcgb2YgImVsaWYiCiAgICAgICAgICAgICAgICAgICAgc2VsZi5za2lwX2luZGVudF91bnRpbF93cml0ZSA9IFRydWUKICAgICAgICAgICAgICAgICAgICBzZWxmLnByaW50X2lmKGhlYWRlciwgY29kZVswXS5vcmVsc2UpCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCJlbHNlOiIpCiAgICAgICAgICAgICAgICAgICAgaWYgKGxlbihjb2RlWzBdLm9yZWxzZSkgPj0gMiBhbmQKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5wYXJzZV9oZWFkZXIoY29kZVswXS5vcmVsc2VbMF0pIGFuZAogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnBhcnNlX2hlYWRlcihjb2RlWzBdLm9yZWxzZVsxXSkpOgogICAgICAgICAgICAgICAgICAgICAgICBvcmVsc2UgPSBjb2RlWzBdLm9yZWxzZVsxOl0KICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBvcmVsc2UgPSBjb2RlWzBdLm9yZWxzZQogICAgICAgICAgICAgICAgICAgIHNlbGYucHJpbnRfbm9kZXMob3JlbHNlLCAxKQoKICAgIGRlZiBwcmludF9mb3Ioc2VsZiwgaGVhZGVyLCBjb2RlKToKICAgICAgICAjIEhlcmUgd2UgaGFuZGxlIHRoZSBmb3Igc3RhdGVtZW50LiBOb3RlIHRoYXQgdGhlIGZvciBzdGF0ZW1lbnQgZ2VuZXJhdGVzIHNvbWUgZXh0cmEgcHl0aG9uIGNvZGUgdG8KICAgICAgICAjIEtlZXAgdHJhY2sgb2YgaXQncyBoZWFkZXIgaW5kaWNlcy4gVGhlIGZpcnN0IG9uZSBpcyBpZ25vcmVkIGJ5IHRoZSBzdGF0ZW1lbnQgcGFyc2VyLAogICAgICAgICMgdGhlIHNlY29uZCBsaW5lIGlzIGp1c3QgaW5nb3JlZCBoZXJlLgogICAgICAgIGxpbmUgPSBjb2RlWzFdCiAgICAgICAgc2VsZi5hZHZhbmNlX3RvX2xpbmUoc2VsZi5nZXRfZmlyc3RfbGluZShjb2RlKSkKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZSgiZm9yICVzIGluICVzOiIgJSAoCiAgICAgICAgICAgIHNlbGYuc3RyaXBfcGFyZW5zKHNlbGYudG9fc291cmNlKGxpbmUudGFyZ2V0KSksCiAgICAgICAgICAgIHNlbGYudG9fc291cmNlKGxpbmUuaXRlcikpKQogICAgICAgIGlmIChsZW4obGluZS5ib2R5KSA+PSAzIGFuZCBzZWxmLnBhcnNlX2hlYWRlcihsaW5lLmJvZHlbMF0pIGFuZAogICAgICAgICAgICBzZWxmLnBhcnNlX2hlYWRlcihsaW5lLmJvZHlbMV0pKToKICAgICAgICAgICAgYm9keSA9IGxpbmUuYm9keVsxOl0KICAgICAgICBlbHNlOgogICAgICAgICAgICBib2R5ID0gbGluZS5ib2R5CiAgICAgICAgd2l0aCBzZWxmLm5vdF9yb290KCk6CiAgICAgICAgICAgIHNlbGYucHJpbnRfbm9kZXMoYm9keVs6LTFdLCAxKQoKICAgIEBkaXNwYXRjaCgoJ3JlbnB5JywgJ3VzZV9zY3JlZW4nKSkKICAgIGRlZiBwcmludF91c2Uoc2VsZiwgaGVhZGVyLCBjb2RlKToKICAgICAgICAjIFRoaXMgZnVuY3Rpb24gaGFuZGxlcyB0aGUgdXNlIHN0YXRlbWVudCwgd2hpY2ggdHJhbnNsYXRlcyBpbnRvIGEgcHl0aG9uIGV4cHJlc3Npb24gInJlbnB5LnVzZV9zY3JlZW4iLgogICAgICAgICMgSXQgd291bGQgdGVjaG5pY2FsbHkgYmUgcG9zc2libGUgZm9yIHRoaXMgdG8gYmUgYSBweXRob24gc3RhdGVtZW50LCBidXQgdGhlIG9kZHMgb2YgdGhpcyBhcmUgdmVyeSBzbWFsbC4KICAgICAgICAjIHJlbnB5IGl0c2VsZiB3aWxsIGluc2VydCBzb21lIGt3YXJncywgd2UnbGwgZGVsZXRlIHRob3NlIGFuZCB0aGVuIHBhcnNlIHRoZSBjb21tYW5kIGhlcmUuCiAgICAgICAgaWYgKGxlbihjb2RlKSAhPSAxIG9yIG5vdCBjb2RlWzBdLnZhbHVlLmFyZ3Mgb3IKICAgICAgICAgICAgbm90IGlzaW5zdGFuY2UoY29kZVswXS52YWx1ZS5hcmdzWzBdLCBhc3QuU3RyKSk6CiAgICAgICAgICAgIHJldHVybiBzZWxmLnByaW50X3B5dGhvbihoZWFkZXIsIGNvZGUpCiAgICAgICAgYXJncywga3dhcmdzLCBleGFyZ3MsIGV4a3dhcmdzID0gc2VsZi5wYXJzZV9hcmdzKGNvZGVbMF0pCiAgICAgICAga3dhcmdzID0gWyhrZXksIHZhbHVlKSBmb3Iga2V5LCB2YWx1ZSBpbiBrd2FyZ3MgaWYgbm90CiAgICAgICAgICAgICAgICAgIChrZXkgPT0gJ19zY29wZScgb3Iga2V5ID09ICdfbmFtZScpXQoKICAgICAgICBzZWxmLmFkdmFuY2VfdG9fbGluZShzZWxmLmdldF9maXJzdF9saW5lKGNvZGUpKQogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCJ1c2UgJXMiICUgY29kZVswXS52YWx1ZS5hcmdzWzBdLnMpCiAgICAgICAgYXJncy5wb3AoMCkKCiAgICAgICAgYXJnbGlzdCA9IFtdCiAgICAgICAgaWYgYXJncyBvciBrd2FyZ3Mgb3IgZXhhcmdzIG9yIGV4a3dhcmdzOgogICAgICAgICAgICBzZWxmLndyaXRlKCIoIikKICAgICAgICAgICAgYXJnbGlzdC5leHRlbmQoYXJncykKICAgICAgICAgICAgYXJnbGlzdC5leHRlbmQoIiVzPSVzIiAlIGkgZm9yIGkgaW4ga3dhcmdzKQogICAgICAgICAgICBpZiBleGFyZ3M6CiAgICAgICAgICAgICAgICBhcmdsaXN0LmFwcGVuZCgiKiVzIiAlIGV4YXJncykKICAgICAgICAgICAgaWYgZXhrd2FyZ3M6CiAgICAgICAgICAgICAgICBhcmdsaXN0LmFwcGVuZCgiKiolcyIgJSBleGt3YXJncykKICAgICAgICAgICAgc2VsZi53cml0ZSgiLCAiLmpvaW4oYXJnbGlzdCkpCiAgICAgICAgICAgIHNlbGYud3JpdGUoIikiKQoKICAgIEBkaXNwYXRjaCgoJ19zY29wZScsICdzZXRkZWZhdWx0JykpCiAgICBkZWYgcHJpbnRfZGVmYXVsdChzZWxmLCBoZWFkZXIsIGNvZGUpOgogICAgICAgIGlmIChsZW4oY29kZSkgIT0gMSBvciBjb2RlWzBdLnZhbHVlLmtleXdvcmRzIG9yIGNvZGVbMF0udmFsdWUua3dhcmdzIG9yCiAgICAgICAgICAgIGxlbihjb2RlWzBdLnZhbHVlLmFyZ3MpICE9IDIgb3IgY29kZVswXS52YWx1ZS5zdGFyYXJncyBvcgogICAgICAgICAgICBub3QgaXNpbnN0YW5jZShjb2RlWzBdLnZhbHVlLmFyZ3NbMF0sIGFzdC5TdHIpKToKICAgICAgICAgICAgcmV0dXJuIHNlbGYucHJpbnRfcHl0aG9uKGhlYWRlciwgY29kZSkKICAgICAgICBzZWxmLmFkdmFuY2VfdG9fbGluZShzZWxmLmdldF9maXJzdF9saW5lKGNvZGUpKQogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCJkZWZhdWx0ICVzID0gJXMiICUKICAgICAgICAgICAgKGNvZGVbMF0udmFsdWUuYXJnc1swXS5zLCBzZWxmLnRvX3NvdXJjZShjb2RlWzBdLnZhbHVlLmFyZ3NbMV0pKSkKCiAgICAjIFRoZXNlIG5ldmVyIGhhdmUgYSB1aS5jbG9zZSgpIGF0IHRoZSBlbmQKICAgIEBkaXNwYXRjaCgoJ3VpJywgJ2FkZCcpKQogICAgQGRpc3BhdGNoKCgndWknLCAnaW1hZ2VidXR0b24nKSkKICAgIEBkaXNwYXRjaCgoJ3VpJywgJ2lucHV0JykpCiAgICBAZGlzcGF0Y2goKCd1aScsICdrZXknKSkKICAgIEBkaXNwYXRjaCgoJ3VpJywgJ2xhYmVsJykpCiAgICBAZGlzcGF0Y2goKCd1aScsICd0ZXh0JykpCiAgICBAZGlzcGF0Y2goKCd1aScsICdudWxsJykpCiAgICBAZGlzcGF0Y2goKCd1aScsICdtb3VzZWFyZWEnKSkKICAgIEBkaXNwYXRjaCgoJ3VpJywgJ3RleHRidXR0b24nKSkKICAgIEBkaXNwYXRjaCgoJ3VpJywgJ3RpbWVyJykpCiAgICBAZGlzcGF0Y2goKCd1aScsICdiYXInKSkKICAgIEBkaXNwYXRjaCgoJ3VpJywgJ3ZiYXInKSkKICAgIEBkaXNwYXRjaCgoJ3VpJywgJ2hvdGJhcicpKQogICAgQGRpc3BhdGNoKCgndWknLCAnb24nKSkKICAgIEBkaXNwYXRjaCgoJ3VpJywgJ2ltYWdlJykpCiAgICBkZWYgcHJpbnRfbm9jaGlsZChzZWxmLCBoZWFkZXIsIGNvZGUpOgogICAgICAgIGlmIGxlbihjb2RlKSAhPSAxOgogICAgICAgICAgICBzZWxmLnByaW50X3B5dGhvbihoZWFkZXIsIGNvZGUpCiAgICAgICAgICAgIHJldHVybgogICAgICAgIGxpbmUgPSBjb2RlWzBdCiAgICAgICAgc2VsZi5hZHZhbmNlX3RvX2xpbmUoc2VsZi5nZXRfZmlyc3RfbGluZShjb2RlKSkKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZShsaW5lLnZhbHVlLmZ1bmMuYXR0cikKICAgICAgICBzZWxmLnByaW50X2FyZ3MobGluZS52YWx1ZSkKICAgICAgICB3aXRoIHNlbGYubm90X3Jvb3QoKToKICAgICAgICAgICAgc2VsZi5wcmludF9idWdneV9rZXl3b3Jkc19hbmRfbm9kZXMoCiAgICAgICAgICAgICAgICBzZWxmLm1ha2VfcHJpbnRhYmxlX2tleXdvcmRzKGxpbmUudmFsdWUua2V5d29yZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUudmFsdWUubGluZW5vKSwKICAgICAgICAgICAgICAgIE5vbmUsIEZhbHNlLCBGYWxzZSkKCiAgICAjIFRoZXNlIGZ1bmN0aW9ucyB0aGVtc2VsdmVzIGRvbid0IGhhdmUgYSB1aS5jbG9zZSgpIGF0IHRoZSBlbmQsIGJ1dAogICAgIyB0aGV5J3JlIGFsd2F5cyBpbW1lZGlhdGVseSBmb2xsb3dlZCBieSBvbmUgdGhhdCBkb2VzICh1c3VhbGx5CiAgICAjIHVpLmNoaWxkX29yX2ZpeGVkKCksIGJ1dCBhbHNvIHBvc3NpYmx5IG9uZSBzZXQgd2l0aCAiaGFzIikKICAgIEBkaXNwYXRjaCgoJ3VpJywgJ2J1dHRvbicpKQogICAgQGRpc3BhdGNoKCgndWknLCAnZnJhbWUnKSkKICAgIEBkaXNwYXRjaCgoJ3VpJywgJ3RyYW5zZm9ybScpKQogICAgQGRpc3BhdGNoKCgndWknLCAndmlld3BvcnQnKSkKICAgIEBkaXNwYXRjaCgoJ3VpJywgJ3dpbmRvdycpKQogICAgQGRpc3BhdGNoKCgndWknLCAnZHJhZycpKQogICAgQGRpc3BhdGNoKCgndWknLCAnaG90c3BvdF93aXRoX2NoaWxkJykpCiAgICBkZWYgcHJpbnRfb25lY2hpbGQoc2VsZiwgaGVhZGVyLCBjb2RlLCBoYXNfYmxvY2s9RmFsc2UpOgogICAgICAgICMgV2UgZXhwZWN0IHRvIGhhdmUgYXQgbGVhc3Qgb3Vyc2VsZiwgb25lIGNoaWxkLCBhbmQgdWkuY2xvc2UoKQogICAgICAgIGlmIGxlbihjb2RlKSA8IDMgb3Igc2VsZi5nZXRfZGlzcGF0Y2hfa2V5KGNvZGVbLTFdKSAhPSAoJ3VpJywgJ2Nsb3NlJyk6CiAgICAgICAgICAgIGlmIGhhc19ibG9jazoKICAgICAgICAgICAgICAgIHJhaXNlIEJhZEhhc0Jsb2NrRXhjZXB0aW9uKCkKICAgICAgICAgICAgc2VsZi5wcmludF9weXRob24oaGVhZGVyLCBjb2RlKQogICAgICAgICAgICByZXR1cm4KICAgICAgICBsaW5lID0gY29kZVswXQogICAgICAgIG5hbWUgPSBsaW5lLnZhbHVlLmZ1bmMuYXR0cgogICAgICAgIGlmIG5hbWUgPT0gJ2hvdHNwb3Rfd2l0aF9jaGlsZCc6CiAgICAgICAgICAgIG5hbWUgPSAnaG90c3BvdCcKICAgICAgICBpZiBzZWxmLmdldF9kaXNwYXRjaF9rZXkoY29kZVsxXSkgIT0gKCd1aScsICdjaGlsZF9vcl9maXhlZCcpOgogICAgICAgICAgICAjIEhhbmRsZSB0aGUgY2FzZSB3aGVyZSBhICJoYXMiIHN0YXRlbWVudCB3YXMgdXNlZAogICAgICAgICAgICBpZiBoYXNfYmxvY2s6CiAgICAgICAgICAgICAgICAjIFJlbidQeSBsZXRzIHVzZXJzIG5lc3QgImhhcyIgYmxvY2tzIGZvciBzb21lIHJlYXNvbiwgYW5kIGl0CiAgICAgICAgICAgICAgICAjIHB1dHMgdGhlIHVpLmNsb3NlKCkgc3RhdGVtZW50IGluIHRoZSB3cm9uZyBwbGFjZSB3aGVuIHRoZXkgZG8uCiAgICAgICAgICAgICAgICAjIFNpbmNlIHdlIGNoZWNrZWQgZm9yIHVpLmNsb3NlKCkgYmVpbmcgaW4gdGhlIHJpZ2h0IHBsYWNlCiAgICAgICAgICAgICAgICAjIGJlZm9yZSwgdGhlIG9ubHkgd2F5IHdlIGNvdWxkIGV2ZXIgZ2V0IGhlcmUgaXMgaWYgYSB1c2VyIGFkZGVkCiAgICAgICAgICAgICAgICAjIG9uZSBpbnNpZGUgYSBweXRob24gYmxvY2sgYXQgdGhlIGVuZC4gSWYgdGhpcyBoYXBwZW5zLCB0dXJuCiAgICAgICAgICAgICAgICAjIHRoZSB3aG9sZSBvdXRlciBibG9jayBpbnRvIFB5dGhvbiBpbnN0ZWFkIG9mIHNjcmVlbmNvZGUuCiAgICAgICAgICAgICAgICByYWlzZSBCYWRIYXNCbG9ja0V4Y2VwdGlvbigpCiAgICAgICAgICAgIGlmIG5vdCBzZWxmLnBhcnNlX2hlYWRlcihjb2RlWzFdKToKICAgICAgICAgICAgICAgIHNlbGYucHJpbnRfcHl0aG9uKGhlYWRlciwgY29kZSkKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBibG9jayA9IGNvZGVbMTpdCiAgICAgICAgICAgIHN0YXRlID0gc2VsZi5zYXZlX3N0YXRlKCkKICAgICAgICAgICAgdHJ5OgogICAgICAgICAgICAgICAgc2VsZi5hZHZhbmNlX3RvX2xpbmUoc2VsZi5nZXRfZmlyc3RfbGluZShjb2RlKSkKICAgICAgICAgICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUobmFtZSkKICAgICAgICAgICAgICAgIHNlbGYucHJpbnRfYXJncyhsaW5lLnZhbHVlKQogICAgICAgICAgICAgICAgd2l0aCBzZWxmLm5vdF9yb290KCk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5wcmludF9idWdneV9rZXl3b3Jkc19hbmRfbm9kZXMoCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYubWFrZV9wcmludGFibGVfa2V5d29yZHMobGluZS52YWx1ZS5rZXl3b3JkcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lLnZhbHVlLmxpbmVubyksCiAgICAgICAgICAgICAgICAgICAgICAgIE5vbmUsIFRydWUsIEZhbHNlKQogICAgICAgICAgICAgICAgICAgIHdpdGggc2VsZi5pbmNyZWFzZV9pbmRlbnQoKToKICAgICAgICAgICAgICAgICAgICAgICAgaWYgbGVuKGJsb2NrKSA+IDEgYW5kIGlzaW5zdGFuY2UoYmxvY2tbMV0sIGFzdC5FeHByKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgSWYgdGhpcyBpc24ndCB0cnVlLCB3ZSdsbCBnZXQgYSBCYWRIYXNCbG9ja0V4Y2VwdGlvbgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBsYXRlciBhbnl3YXkuIFRoaXMgY2hlY2sgaXMganVzdCB0byBrZWVwIGl0IGZyb20gYmVpbmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgYW4gZXhjZXB0aW9uIHRoYXQgd2UgY2FuJ3QgaGFuZGxlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5hZHZhbmNlX3RvX2xpbmUoYmxvY2tbMV0udmFsdWUubGluZW5vKQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoImhhcyAiKQogICAgICAgICAgICAgICAgICAgIHNlbGYuc2tpcF9pbmRlbnRfdW50aWxfd3JpdGUgPSBUcnVlCiAgICAgICAgICAgICAgICAgICAgc2VsZi5wcmludF9ub2RlcyhibG9jaywgMSwgVHJ1ZSkKICAgICAgICAgICAgZXhjZXB0IEJhZEhhc0Jsb2NrRXhjZXB0aW9uIGFzIGU6CiAgICAgICAgICAgICAgICBzZWxmLnJvbGxiYWNrX3N0YXRlKHN0YXRlKQogICAgICAgICAgICAgICAgc2VsZi5wcmludF9weXRob24oaGVhZGVyLCBjb2RlKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgc2VsZi5jb21taXRfc3RhdGUoc3RhdGUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgIyBSZW1vdmUgb3Vyc2VsZiwgdWkuY2hpbGRfb3JfZml4ZWQoKSwgYW5kIHVpLmNsb3NlKCkKICAgICAgICAgICAgYmxvY2sgPSBjb2RlWzI6LTFdCiAgICAgICAgICAgIGlmIGJsb2NrIGFuZCBub3Qgc2VsZi5wYXJzZV9oZWFkZXIoYmxvY2tbMF0pOgogICAgICAgICAgICAgICAgaWYgaGFzX2Jsb2NrOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIEJhZEhhc0Jsb2NrRXhjZXB0aW9uKCkKICAgICAgICAgICAgICAgIHNlbGYucHJpbnRfcHl0aG9uKGhlYWRlciwgY29kZSkKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICBpZiBub3QgaGFzX2Jsb2NrOgogICAgICAgICAgICAgICAgc2VsZi5hZHZhbmNlX3RvX2xpbmUoc2VsZi5nZXRfZmlyc3RfbGluZShjb2RlKSkKICAgICAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgICAgICBzZWxmLndyaXRlKG5hbWUpCiAgICAgICAgICAgIHNlbGYucHJpbnRfYXJncyhsaW5lLnZhbHVlKQogICAgICAgICAgICB3aXRoIHNlbGYubm90X3Jvb3QoKToKICAgICAgICAgICAgICAgIHNlbGYucHJpbnRfYnVnZ3lfa2V5d29yZHNfYW5kX25vZGVzKAogICAgICAgICAgICAgICAgICAgIHNlbGYubWFrZV9wcmludGFibGVfa2V5d29yZHMobGluZS52YWx1ZS5rZXl3b3JkcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUudmFsdWUubGluZW5vKSwKICAgICAgICAgICAgICAgICAgICBibG9jaywgRmFsc2UsIGhhc19ibG9jaykKCiAgICAjIFRoZXNlIGFsd2F5cyBoYXZlIGEgdWkuY2xvc2UoKSBhdCB0aGUgZW5kCiAgICBAZGlzcGF0Y2goKCd1aScsICdmaXhlZCcpKQogICAgQGRpc3BhdGNoKCgndWknLCAnZ3JpZCcpKQogICAgQGRpc3BhdGNoKCgndWknLCAnaGJveCcpKQogICAgQGRpc3BhdGNoKCgndWknLCAnc2lkZScpKQogICAgQGRpc3BhdGNoKCgndWknLCAndmJveCcpKQogICAgQGRpc3BhdGNoKCgndWknLCAnaW1hZ2VtYXAnKSkKICAgIEBkaXNwYXRjaCgoJ3VpJywgJ2RyYWdncm91cCcpKQogICAgZGVmIHByaW50X21hbnljaGlsZHJlbihzZWxmLCBoZWFkZXIsIGNvZGUsIGhhc19ibG9jaz1GYWxzZSk6CiAgICAgICAgaWYgKHNlbGYuZ2V0X2Rpc3BhdGNoX2tleShjb2RlWy0xXSkgIT0gKCd1aScsICdjbG9zZScpIG9yCiAgICAgICAgICAgIChsZW4oY29kZSkgIT0gMiBhbmQgbm90IHNlbGYucGFyc2VfaGVhZGVyKGNvZGVbMV0pKSk6CiAgICAgICAgICAgIGlmIGhhc19ibG9jazoKICAgICAgICAgICAgICAgIHJhaXNlIEJhZEhhc0Jsb2NrRXhjZXB0aW9uKCkKICAgICAgICAgICAgc2VsZi5wcmludF9weXRob24oaGVhZGVyLCBjb2RlKQogICAgICAgICAgICByZXR1cm4KICAgICAgICBsaW5lID0gY29kZVswXQogICAgICAgIGJsb2NrID0gY29kZVsxOi0xXQogICAgICAgIGlmIG5vdCBoYXNfYmxvY2s6CiAgICAgICAgICAgIHNlbGYuYWR2YW5jZV90b19saW5lKHNlbGYuZ2V0X2ZpcnN0X2xpbmUoY29kZSkpCiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUobGluZS52YWx1ZS5mdW5jLmF0dHIpCiAgICAgICAgc2VsZi5wcmludF9hcmdzKGxpbmUudmFsdWUpCiAgICAgICAgd2l0aCBzZWxmLm5vdF9yb290KCk6CiAgICAgICAgICAgIHNlbGYucHJpbnRfYnVnZ3lfa2V5d29yZHNfYW5kX25vZGVzKAogICAgICAgICAgICAgICAgc2VsZi5tYWtlX3ByaW50YWJsZV9rZXl3b3JkcyhsaW5lLnZhbHVlLmtleXdvcmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lLnZhbHVlLmxpbmVubyksCiAgICAgICAgICAgICAgICBibG9jaywgRmFsc2UsIGhhc19ibG9jaykKCiAgICAjIFBhcnNpbmcgZnVuY3Rpb25zCgogICAgZGVmIHBhcnNlX2hlYWRlcihzZWxmLCBoZWFkZXIpOgogICAgICAgICMgR2l2ZW4gYSBQeXRob24gQVNUIG5vZGUsIHJldHVybnMgdGhlIHBhcmVudCBJRCBpZiB0aGUgbm9kZSByZXByZXNlbnRzCiAgICAgICAgIyBhIGhlYWRlciwgb3IgTm9uZSBvdGhlcndpc2UuCiAgICAgICAgaWYgKGlzaW5zdGFuY2UoaGVhZGVyLCBhc3QuQXNzaWduKSBhbmQgbGVuKGhlYWRlci50YXJnZXRzKSA9PSAxIGFuZAogICAgICAgICAgICAgICAgaXNpbnN0YW5jZShoZWFkZXIudGFyZ2V0c1swXSwgYXN0Lk5hbWUpIGFuZAogICAgICAgICAgICAgICAgcmUubWF0Y2gociJfWzAtOV0rJCIsIGhlYWRlci50YXJnZXRzWzBdLmlkKSBhbmQKICAgICAgICAgICAgICAgIGlzaW5zdGFuY2UoaGVhZGVyLnZhbHVlLCBhc3QuVHVwbGUpIGFuZAogICAgICAgICAgICAgICAgbGVuKGhlYWRlci52YWx1ZS5lbHRzKSA9PSAyIGFuZAogICAgICAgICAgICAgICAgaXNpbnN0YW5jZShoZWFkZXIudmFsdWUuZWx0c1swXSwgYXN0Lk5hbWUpKToKICAgICAgICAgICAgcGFyZW50X2lkID0gaGVhZGVyLnZhbHVlLmVsdHNbMF0uaWQKICAgICAgICAgICAgaW5kZXggPSBoZWFkZXIudmFsdWUuZWx0c1sxXQogICAgICAgICAgICBpZiByZS5tYXRjaChyIl8oWzAtOV0rfG5hbWUpJCIsIHBhcmVudF9pZCkgYW5kICgKICAgICAgICAgICAgICAgICAgICBpc2luc3RhbmNlKGluZGV4LCBhc3QuTnVtKSBvcgogICAgICAgICAgICAgICAgICAgIChpc2luc3RhbmNlKGluZGV4LCBhc3QuTmFtZSkgYW5kCiAgICAgICAgICAgICAgICAgICAgcmUubWF0Y2gociJfWzAtOV0rJCIsIGluZGV4LmlkKSkpOgogICAgICAgICAgICAgICAgcmV0dXJuIHBhcmVudF9pZAogICAgICAgIHJldHVybiBOb25lCgogICAgZGVmIHBhcnNlX2FyZ3Moc2VsZiwgbm9kZSk6CiAgICAgICAgcmV0dXJuIChbc2VsZi50b19zb3VyY2UoaSkgZm9yIGkgaW4gbm9kZS52YWx1ZS5hcmdzXSwKICAgICAgICAgICAgWyhpLmFyZywgc2VsZi50b19zb3VyY2UoaS52YWx1ZSkpIGZvciBp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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjIENvcHlyaWdodCAoYykgMjAxNCBDZW5zb3JlZFVzZXJuYW1lCiMKIyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5CiMgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKIyBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCiMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbAojIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwojIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiMKIyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgojIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgojCiMgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKIyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKIyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKIyBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiMgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKIyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRQojIFNPRlRXQVJFLgoKZnJvbSBfX2Z1dHVyZV9fIGltcG9ydCB1bmljb2RlX2xpdGVyYWxzCmltcG9ydCBzeXMKZnJvbSBvcGVyYXRvciBpbXBvcnQgaXRlbWdldHRlcgoKZnJvbSB1dGlsIGltcG9ydCBEZWNvbXBpbGVyQmFzZSwgRmlyc3QsIHJlY29uc3RydWN0X3BhcmFtaW5mbywgXAogICAgICAgICAgICAgICAgIHJlY29uc3RydWN0X2FyZ2luZm8sIHNwbGl0X2xvZ2ljYWxfbGluZXMsIERpc3BhdGNoZXIKCmZyb20gcmVucHkgaW1wb3J0IHVpLCBzbDIKZnJvbSByZW5weS50ZXh0IGltcG9ydCB0ZXh0CmZyb20gcmVucHkuc2wyIGltcG9ydCBzbGRpc3BsYXlhYmxlcyBhcyBzbGQKZnJvbSByZW5weS5kaXNwbGF5IGltcG9ydCBsYXlvdXQsIGJlaGF2aW9yLCBpbSwgbW90aW9uLCBkcmFnZHJvcAoKIyBNYWluIEFQSQoKZGVmIHBwcmludChvdXRfZmlsZSwgYXN0LCBpbmRlbnRfbGV2ZWw9MCwgbGluZW51bWJlcj0xLAogICAgICAgICAgIHNraXBfaW5kZW50X3VudGlsX3dyaXRlPUZhbHNlLCBwcmludGxvY2s9Tm9uZSk6CiAgICByZXR1cm4gU0wyRGVjb21waWxlcihvdXRfZmlsZSwgcHJpbnRsb2NrPXByaW50bG9jaykuZHVtcCgKICAgICAgICBhc3QsIGluZGVudF9sZXZlbCwgbGluZW51bWJlciwgc2tpcF9pbmRlbnRfdW50aWxfd3JpdGUpCgojIEltcGxlbWVudGF0aW9uCgpjbGFzcyBTTDJEZWNvbXBpbGVyKERlY29tcGlsZXJCYXNlKToKICAgICIiIgogICAgQW4gb2JqZWN0IHdoaWNoIGhhbmRsZXMgdGhlIGRlY29tcGlsYXRpb24gb2YgcmVucHkgc2NyZWVuIGxhbmd1YWdlIDIgc2NyZWVucyB0byBhIGdpdmVuIHN0cmVhbQogICAgIiIiCgogICAgIyBUaGlzIGRpY3Rpb25hcnkgaXMgYSBtYXBwaW5nIG9mIENsYXNzOiB1bmJvdW5kX21ldGhvZCwgd2hpY2ggaXMgdXNlZCB0byBkZXRlcm1pbmUKICAgICMgd2hhdCBtZXRob2QgdG8gY2FsbCBmb3Igd2hpY2ggc2xhc3QgY2xhc3MKICAgIGRpc3BhdGNoID0gRGlzcGF0Y2hlcigpCgogICAgZGVmIHByaW50X25vZGUoc2VsZiwgYXN0KToKICAgICAgICBzZWxmLmFkdmFuY2VfdG9fbGluZShhc3QubG9jYXRpb25bMV0pCiAgICAgICAgc2VsZi5kaXNwYXRjaC5nZXQodHlwZShhc3QpLCB0eXBlKHNlbGYpLnByaW50X3Vua25vd24pKHNlbGYsIGFzdCkKCiAgICBAZGlzcGF0Y2goc2wyLnNsYXN0LlNMU2NyZWVuKQogICAgZGVmIHByaW50X3NjcmVlbihzZWxmLCBhc3QpOgoKICAgICAgICAjIFByaW50IHRoZSBzY3JlZW4gc3RhdGVtZW50IGFuZCBjcmVhdGUgdGhlIGJsb2NrCiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoInNjcmVlbiAlcyIgJSBhc3QubmFtZSkKICAgICAgICAjIElmIHdlIGhhdmUgcGFyYW1ldGVycywgcHJpbnQgdGhlbS4KICAgICAgICBpZiBhc3QucGFyYW1ldGVyczoKICAgICAgICAgICAgc2VsZi53cml0ZShyZWNvbnN0cnVjdF9wYXJhbWluZm8oYXN0LnBhcmFtZXRlcnMpKQogICAgICAgICMgUHJpbnQgYW55IGtleXdvcmRzCiAgICAgICAgaWYgYXN0LnRhZzoKICAgICAgICAgICAgc2VsZi53cml0ZSgiIHRhZyAlcyIgJSBhc3QudGFnKQogICAgICAgICMgSWYgd2UncmUgZGVjb21waWxpbmcgc2NyZWVuY29kZSwgcHJpbnQgaXQuIEVsc2UsIGluc2VydCBhIHBhc3Mgc3RhdGVtZW50CiAgICAgICAgc2VsZi5wcmludF9rZXl3b3Jkc19hbmRfY2hpbGRyZW4oYXN0LmtleXdvcmQsCiAgICAgICAgICAgIGFzdC5jaGlsZHJlbiwgYXN0LmxvY2F0aW9uWzFdKQoKICAgIEBkaXNwYXRjaChzbDIuc2xhc3QuU0xJZikKICAgIGRlZiBwcmludF9pZihzZWxmLCBhc3QpOgogICAgICAgICMgaWYgYW5kIHNob3dpZiBzaGFyZSBhIGxvdCBvZiB0aGUgc2FtZSBpbmZyYXN0cnVjdHVyZQogICAgICAgIHNlbGYuX3ByaW50X2lmKGFzdCwgImlmIikKCiAgICBAZGlzcGF0Y2goc2wyLnNsYXN0LlNMU2hvd0lmKQogICAgZGVmIHByaW50X3Nob3dpZihzZWxmLCBhc3QpOgogICAgICAgICMgc28gZm9yIGlmIGFuZCBzaG93aWYgd2UganVzdCBjYWxsIGFuIHVuZGVybHlpbmcgZnVuY3Rpb24gd2l0aCBhbiBleHRyYSBhcmd1bWVudAogICAgICAgIHNlbGYuX3ByaW50X2lmKGFzdCwgInNob3dpZiIpCgogICAgZGVmIF9wcmludF9pZihzZWxmLCBhc3QsIGtleXdvcmQpOgogICAgICAgICMgdGhlIGZpcnN0IGNvbmRpdGlvbiBpcyBuYW1lZCBpZiBvciBzaG93aWYsIHRoZSByZXN0IGVsaWYKICAgICAgICBrZXl3b3JkID0gRmlyc3Qoa2V5d29yZCwgImVsaWYiKQogICAgICAgIGZvciBjb25kaXRpb24sIGJsb2NrIGluIGFzdC5lbnRyaWVzOgogICAgICAgICAgICBzZWxmLmFkdmFuY2VfdG9fbGluZShibG9jay5sb2NhdGlvblsxXSkKICAgICAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgICAgICAjIGlmIGNvbmRpdGlvbiBpcyBOb25lLCB0aGlzIGlzIHRoZSBlbHNlIGNsYXVzZQogICAgICAgICAgICBpZiBjb25kaXRpb24gaXMgTm9uZToKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoImVsc2U6IikKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNlbGYud3JpdGUoIiVzICVzOiIgJSAoa2V5d29yZCgpLCBjb25kaXRpb24pKQoKICAgICAgICAgICAgIyBFdmVyeSBjb25kaXRpb24gaGFzIGEgYmxvY2sgb2YgdHlwZSBzbGFzdC5TTEJsb2NrCiAgICAgICAgICAgIGlmIGJsb2NrLmtleXdvcmQgb3IgYmxvY2suY2hpbGRyZW46CiAgICAgICAgICAgICAgICBzZWxmLnByaW50X2Jsb2NrKGJsb2NrKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgd2l0aCBzZWxmLmluY3JlYXNlX2luZGVudCgpOgogICAgICAgICAgICAgICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCJwYXNzIikKCiAgICBAZGlzcGF0Y2goc2wyLnNsYXN0LlNMQmxvY2spCiAgICBkZWYgcHJpbnRfYmxvY2soc2VsZiwgYXN0KToKICAgICAgICAjIEEgYmxvY2sgY29udGFpbnMgcG9zc2libGUga2V5d29yZCBhcmd1bWVudHMgYW5kIGEgbGlzdCBvZiBjaGlsZCBub2RlcwogICAgICAgICMgdGhpcyBpcyB0aGUgcmVhc29uIGlmIGRvZXNuJ3Qga2VlcCBhIGxpc3Qgb2YgY2hpbGRyZW4gYnV0IHNwZWNpYWwgQmxvY2tzCiAgICAgICAgc2VsZi5wcmludF9rZXl3b3Jkc19hbmRfY2hpbGRyZW4oYXN0LmtleXdvcmQsIGFzdC5jaGlsZHJlbiwgTm9uZSkKCiAgICBAZGlzcGF0Y2goc2wyLnNsYXN0LlNMRm9yKQogICAgZGVmIHByaW50X2ZvcihzZWxmLCBhc3QpOgogICAgICAgICMgU2luY2UgdHVwbGUgdW5waWNrbGluZyBpcyBoYXJkLCByZW5weSBqdXN0IGdpdmVzIHVwIGFuZCBpbnNlcnRzIGEKICAgICAgICAjICQgYSxiLGMgPSBfc2wyX2kgYWZ0ZXIgdGhlIGZvciBzdGF0ZW1lbnQgaWYgYW55IHR1cGxlIHVucGFja2luZyB3YXMKICAgICAgICAjIGF0dGVtcHRlZCBpbiB0aGUgZm9yIHN0YXRlbWVudC4gRGV0ZWN0IHRoaXMgYW5kIGlnbm9yZSB0aGlzIHNsYXN0LlNMUHl0aG9uIGVudHJ5CiAgICAgICAgaWYgYXN0LnZhcmlhYmxlID09ICJfc2wyX2kiOgogICAgICAgICAgICB2YXJpYWJsZSA9IGFzdC5jaGlsZHJlblswXS5jb2RlLnNvdXJjZVs6LTldCiAgICAgICAgICAgIGNoaWxkcmVuID0gYXN0LmNoaWxkcmVuWzE6XQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHZhcmlhYmxlID0gYXN0LnZhcmlhYmxlLnN0cmlwKCkgKyAiICIKICAgICAgICAgICAgY2hpbGRyZW4gPSBhc3QuY2hpbGRyZW4KCiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoImZvciAlc2luICVzOiIgJSAodmFyaWFibGUsIGFzdC5leHByZXNzaW9uKSkKCiAgICAgICAgIyBJbnRlcmVzdGluZ2x5LCBmb3IgZG9lc24ndCBjb250YWluIGEgYmxvY2ssIGJ1dCBqdXN0IGEgbGlzdCBvZiBjaGlsZCBub2RlcwogICAgICAgIHNlbGYucHJpbnRfbm9kZXMoY2hpbGRyZW4sIDEpCgogICAgQGRpc3BhdGNoKHNsMi5zbGFzdC5TTFB5dGhvbikKICAgIGRlZiBwcmludF9weXRob24oc2VsZiwgYXN0KToKICAgICAgICBzZWxmLmluZGVudCgpCgogICAgICAgICMgRXh0cmFjdCB0aGUgc291cmNlIGNvZGUgZnJvbSB0aGUgc2xhc3QuU0xQeXRob24gb2JqZWN0LiBJZiBpdCBzdGFydHMgd2l0aCBhCiAgICAgICAgIyBuZXdsaW5lLCBwcmludCBpdCBhcyBhIHB5dGhvbiBibG9jaywgZWxzZSwgcHJpbnQgaXQgYXMgYSAkIHN0YXRlbWVudAogICAgICAgIGNvZGUgPSBhc3QuY29kZS5zb3VyY2UKICAgICAgICBpZiBjb2RlWzBdID09ICJcbiI6CiAgICAgICAgICAgIGNvZGUgPSBjb2RlWzE6XQogICAgICAgICAgICBzZWxmLndyaXRlKCJweXRob246IikKICAgICAgICAgICAgd2l0aCBzZWxmLmluY3JlYXNlX2luZGVudCgpOgogICAgICAgICAgICAgICAgc2VsZi53cml0ZV9saW5lcyhzcGxpdF9sb2dpY2FsX2xpbmVzKGNvZGUpKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYud3JpdGUoIiQgJXMiICUgY29kZSkKCiAgICBAZGlzcGF0Y2goc2wyLnNsYXN0LlNMUGFzcykKICAgIGRlZiBwcmludF9wYXNzKHNlbGYsIGFzdCk6CiAgICAgICAgIyBBIHBhc3Mgc3RhdGVtZW50CiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoInBhc3MiKQoKICAgIEBkaXNwYXRjaChzbDIuc2xhc3QuU0xVc2UpCiAgICBkZWYgcHJpbnRfdXNlKHNlbGYsIGFzdCk6CiAgICAgICAgIyBBIHVzZSBzdGF0ZW1lbnQgcmVxdWlyZXMgcmVjb25zdHJ1Y3RpbmcgdGhlIGFyZ3VtZW50cyBpdCB3YW50cyB0byBwYXNzCiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoInVzZSAlcyVzIiAlIChhc3QudGFyZ2V0LCByZWNvbnN0cnVjdF9hcmdpbmZvKGFzdC5hcmdzKSkpCiAgICAgICAgaWYgaGFzYXR0cihhc3QsICdpZCcpIGFuZCBhc3QuaWQgaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYud3JpdGUoIiBpZCAlcyIgJSBhc3QuaWQpCgogICAgICAgIGlmIGhhc2F0dHIoYXN0LCAnYmxvY2snKSBhbmQgYXN0LmJsb2NrOgogICAgICAgICAgICBzZWxmLndyaXRlKCI6IikKICAgICAgICAgICAgc2VsZi5wcmludF9ibG9jayhhc3QuYmxvY2spCgogICAgQGRpc3BhdGNoKHNsMi5zbGFzdC5TTFRyYW5zY2x1ZGUpCiAgICBkZWYgcHJpbnRfdHJhbnNjbHVkZShzZWxmLCBhc3QpOgogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCJ0cmFuc2NsdWRlIikKCiAgICBAZGlzcGF0Y2goc2wyLnNsYXN0LlNMRGVmYXVsdCkKICAgIGRlZiBwcmludF9kZWZhdWx0KHNlbGYsIGFzdCk6CiAgICAgICAgIyBBIGRlZmF1bHQgc3RhdGVtZW50CiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoImRlZmF1bHQgJXMgPSAlcyIgJSAoYXN0LnZhcmlhYmxlLCBhc3QuZXhwcmVzc2lvbikpCgogICAgQGRpc3BhdGNoKHNsMi5zbGFzdC5TTERpc3BsYXlhYmxlKQogICAgZGVmIHByaW50X2Rpc3BsYXlhYmxlKHNlbGYsIGFzdCwgaGFzX2Jsb2NrPUZhbHNlKToKICAgICAgICAjIHNsYXN0LlNMRGlzcGxheWFibGUgcmVwcmVzZW50cyBhIHZhcmlldHkgb2Ygc3RhdGVtZW50cy4gV2UgY2FuIGZpZ3VyZSBvdXQKICAgICAgICAjIHdoYXQgc3RhdGVtZW50IGl0IHJlcHJlc2VudHMgYnkgYW5hbHl6aW5nIHRoZSBjYWxsZWQgZGlzcGxheWFibGUgYW5kIHN0eWxlCiAgICAgICAgIyBhdHRyaWJ1dGVzLgogICAgICAgIGtleSA9IChhc3QuZGlzcGxheWFibGUsIGFzdC5zdHlsZSkKICAgICAgICBuYW1lQW5kQ2hpbGRyZW4gPSBzZWxmLmRpc3BsYXlhYmxlX25hbWVzLmdldChrZXkpCiAgICAgICAgaWYgbmFtZUFuZENoaWxkcmVuIGlzIE5vbmU6CiAgICAgICAgICAgICMgVGhpcyBpcyBlaXRoZXIgYSBkaXNwbGF5YWJsZSB3ZSBkb24ndCBrbm93IGFib3V0LCBvciBhIHVzZXItZGVmaW5lZCBkaXNwbGF5YWJsZQoKICAgICAgICAgICAgIyB3b3JrYXJvdW5kOiBhc3N1bWUgdGhlIG5hbWUgb2YgdGhlIGRpc3BsYXlhYmxlIG1hdGNoZXMgdGhlIGdpdmVuIHN0eWxlCiAgICAgICAgICAgICMgdGhpcyBpcyByYXRoZXIgb2Z0ZW4gdGhlIGNhc2UuIEhvd2V2ZXIsIGFzIGl0IG1heSBiZSB3cm9uZyB3ZSBoYXZlIHRvCiAgICAgICAgICAgICMgcHJpbnQgYSBkZWJ1ZyBtZXNzYWdlCiAgICAgICAgICAgIG5hbWVBbmRDaGlsZHJlbiA9IChhc3Quc3R5bGUsICdtYW55JykKICAgICAgICAgICAgc2VsZi5wcmludF9kZWJ1ZygKICIiIldhcm5pbmc6IEVuY291bnRlcmVkIGEgdXNlci1kZWZpbmVkIGRpc3BsYXlhYmxlIG9mIHR5cGUgJ3t9Jy4KICAgIFVuZm9ydHVuYXRlbHksIHRoZSBuYW1lIG9mIHVzZXItZGVmaW5lZCBkaXNwbGF5YWJsZXMgaXMgbm90IHJlY29yZGVkIGluIHRoZSBjb21waWxlZCBmaWxlLgogICAgRm9yIG5vdyB0aGUgc3R5bGUgbmFtZSAne30nIHdpbGwgYmUgc3Vic3RpdHV0ZWQuCiAgICBUbyBjaGVjayBpZiB0aGlzIGlzIGNvcnJlY3QsIGZpbmQgdGhlIGNvcnJlc3BvbmRpbmcgcmVucHkucmVnaXN0ZXJfc2xfZGlzcGxheWFibGUgY2FsbC4iIiIuZm9ybWF0KAogICAgICAgICAgICAgICAgICAgIGFzdC5kaXNwbGF5YWJsZSwgYXN0LnN0eWxlCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICkKICAgICAgICAobmFtZSwgY2hpbGRyZW4pID0gbmFtZUFuZENoaWxkcmVuCiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUobmFtZSkKICAgICAgICBpZiBhc3QucG9zaXRpb25hbDoKICAgICAgICAgICAgc2VsZi53cml0ZSgiICIgKyAiICIuam9pbihhc3QucG9zaXRpb25hbCkpCiAgICAgICAgIyBUaGUgQVNUIGNvbnRhaW5zIG5vIGluZGljYXRpb24gb2Ygd2hldGhlciBvciBub3QgImhhcyIgYmxvY2tzCiAgICAgICAgIyB3ZXJlIHVzZWQuIFdlJ2xsIHVzZSBvbmUgYW55IHRpbWUgaXQncyBwb3NzaWJsZSAoZXhjZXB0IGZvcgogICAgICAgICMgZGlyZWN0bHkgbmVzdGluZyB0aGVtLCBvciBpZiB0aGV5IHdvdWxkbid0IGNvbnRhaW4gYW55IGNoaWxkcmVuKSwKICAgICAgICAjIHNpbmNlIGl0IHJlc3VsdHMgaW4gY2xlYW5lciBjb2RlLgogICAgICAgIGlmIChub3QgaGFzX2Jsb2NrIGFuZCBjaGlsZHJlbiA9PSAxIGFuZCBsZW4oYXN0LmNoaWxkcmVuKSA9PSAxIGFuZAogICAgICAgICAgICBpc2luc3RhbmNlKGFzdC5jaGlsZHJlblswXSwgc2wyLnNsYXN0LlNMRGlzcGxheWFibGUpIGFuZAogICAgICAgICAgICBhc3QuY2hpbGRyZW5bMF0uY2hpbGRyZW4gYW5kIChub3QgYXN0LmtleXdvcmQgb3IKICAgICAgICAgICAgICAgIGFzdC5jaGlsZHJlblswXS5sb2NhdGlvblsxXSA+IGFzdC5rZXl3b3JkWy0xXVsxXS5saW5lbnVtYmVyKSk6CiAgICAgICAgICAgIHNlbGYucHJpbnRfa2V5d29yZHNfYW5kX2NoaWxkcmVuKGFzdC5rZXl3b3JkLCBbXSwKICAgICAgICAgICAgICAgIGFzdC5sb2NhdGlvblsxXSwgbmVlZHNfY29sb249VHJ1ZSkKICAgICAgICAgICAgc2VsZi5hZHZhbmNlX3RvX2xpbmUoYXN0LmNoaWxkcmVuWzBdLmxvY2F0aW9uWzFdKQogICAgICAgICAgICB3aXRoIHNlbGYuaW5jcmVhc2VfaW5kZW50KCk6CiAgICAgICAgICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCJoYXMgIikKICAgICAgICAgICAgICAgIHNlbGYuc2tpcF9pbmRlbnRfdW50aWxfd3JpdGUgPSBUcnVlCiAgICAgICAgICAgICAgICBzZWxmLnByaW50X2Rpc3BsYXlhYmxlKGFzdC5jaGlsZHJlblswXSwgVHJ1ZSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLnByaW50X2tleXdvcmRzX2FuZF9jaGlsZHJlbihhc3Qua2V5d29yZCwgYXN0LmNoaWxkcmVuLAogICAgICAgICAgICAgICAgIGFzdC5sb2NhdGlvblsxXSwgaGFzX2Jsb2NrPWhhc19ibG9jaykKCiAgICBkaXNwbGF5YWJsZV9uYW1lcyA9IHsKICAgICAgICAoYmVoYXZpb3IuT25FdmVudCwgTm9uZSk6ICAgICAgICAgICgib24iLCAwKSwKICAgICAgICAoYmVoYXZpb3IuT25FdmVudCwgMCk6ICAgICAgICAgICAgICgib24iLCAwKSwKICAgICAgICAoYmVoYXZpb3IuTW91c2VBcmVhLCAwKTogICAgICAgICAgICgibW91c2VhcmVhIiwgMCksCiAgICAgICAgKHVpLl9hZGQsIE5vbmUpOiAgICAgICAgICAgICAgICAgICAoImFkZCIsIDApLAogICAgICAgIChzbGQuc2wyYWRkLCBOb25lKTogICAgICAgICAgICAgICAgKCJhZGQiLCAwKSwKICAgICAgICAodWkuX2hvdGJhciwgImhvdGJhciIpOiAgICAgICAgICAgICgiaG90YmFyIiwgMCksCiAgICAgICAgKHNsZC5zbDJ2YmFyLCBOb25lKTogICAgICAgICAgICAgICAoInZiYXIiLCAwKSwKICAgICAgICAoc2xkLnNsMmJhciwgTm9uZSk6ICAgICAgICAgICAgICAgICgiYmFyIiwgMCksCiAgICAgICAgKHVpLl9sYWJlbCwgImxhYmVsIik6ICAgICAgICAgICAgICAoImxhYmVsIiwgMCksCiAgICAgICAgKHVpLl90ZXh0YnV0dG9uLCAwKTogICAgICAgICAgICAgICAoInRleHRidXR0b24iLCAwKSwKICAgICAgICAodWkuX2ltYWdlYnV0dG9uLCAiaW1hZ2VfYnV0dG9uIik6ICgiaW1hZ2VidXR0b24iLCAwKSwKICAgICAgICAoaW0uaW1hZ2UsICJkZWZhdWx0Iik6ICAgICAgICAgICAgICgiaW1hZ2UiLCAwKSwKICAgICAgICAoYmVoYXZpb3IuSW5wdXQsICJpbnB1dCIpOiAgICAgICAgICgiaW5wdXQiLCAwKSwKICAgICAgICAoYmVoYXZpb3IuVGltZXIsICJkZWZhdWx0Iik6ICAgICAgICgidGltZXIiLCAwKSwKICAgICAgICAodWkuX2tleSwgTm9uZSk6ICAgICAgICAgICAgICAgICAgICgia2V5IiwgMCksCiAgICAgICAgKHRleHQuVGV4dCwgInRleHQiKTogICAgICAgICAgICAgICAoInRleHQiLCAwKSwKICAgICAgICAobGF5b3V0Lk51bGwsICJkZWZhdWx0Iik6ICAgICAgICAgICgibnVsbCIsIDApLAogICAgICAgIChkcmFnZHJvcC5EcmFnLCBOb25lKTogICAgICAgICAgICAgKCJkcmFnIiwgMSksCiAgICAgICAgKGRyYWdkcm9wLkRyYWcsICJkcmFnIik6ICAgICAgICAgICAoImRyYWciLCAxKSwKICAgICAgICAobW90aW9uLlRyYW5zZm9ybSwgInRyYW5zZm9ybSIpOiAgICgidHJhbnNmb3JtIiwgMSksCiAgICAgICAgKHVpLl9ob3RzcG90LCAiaG90c3BvdCIpOiAgICAgICAgICAoImhvdHNwb3QiLCAxKSwKICAgICAgICAoc2xkLnNsMnZpZXdwb3J0LCAidmlld3BvcnQiKTogICAgICgidmlld3BvcnQiLCAxKSwKICAgICAgICAoYmVoYXZpb3IuQnV0dG9uLCAiYnV0dG9uIik6ICAgICAgICgiYnV0dG9uIiwgMSksCiAgICAgICAgKGxheW91dC5XaW5kb3csICJmcmFtZSIpOiAgICAgICAgICAoImZyYW1lIiwgMSksCiAgICAgICAgKGxheW91dC5XaW5kb3csICJ3aW5kb3ciKTogICAgICAgICAoIndpbmRvdyIsIDEpLAogICAgICAgIChkcmFnZHJvcC5EcmFnR3JvdXAsIE5vbmUpOiAgICAgICAgKCJkcmFnZ3JvdXAiLCAnbWFueScpLAogICAgICAgICh1aS5faW1hZ2VtYXAsICJpbWFnZW1hcCIpOiAgICAgICAgKCJpbWFnZW1hcCIsICdtYW55JyksCiAgICAgICAgKGxheW91dC5TaWRlLCAic2lkZSIpOiAgICAgICAgICAgICAoInNpZGUiLCAnbWFueScpLAogICAgICAgIChsYXlvdXQuR3JpZCwgImdyaWQiKTogICAgICAgICAgICAgKCJncmlkIiwgJ21hbnknKSwKICAgICAgICAoc2xkLnNsMnZwZ3JpZCwgInZwZ3JpZCIpOiAgICAgICAgICgidnBncmlkIiwgJ21hbnknKSwKICAgICAgICAobGF5b3V0Lk11bHRpQm94LCAiZml4ZWQiKTogICAgICAgICgiZml4ZWQiLCAnbWFueScpLAogICAgICAgIChsYXlvdXQuTXVsdGlCb3gsICJ2Ym94Iik6ICAgICAgICAgKCJ2Ym94IiwgJ21hbnknKSwKICAgICAgICAobGF5b3V0Lk11bHRpQm94LCAiaGJveCIpOiAgICAgICAgICgiaGJveCIsICdtYW55JykKICAgIH0KCiAgICBkZWYgcHJpbnRfa2V5d29yZHNfYW5kX2NoaWxkcmVuKHNlbGYsIGtleXdvcmRzLCBjaGlsZHJlbiwgbGluZW5vLCBuZWVkc19jb2xvbj1GYWxzZSwgaGFzX2Jsb2NrPUZhbHNlKToKICAgICAgICAjIFRoaXMgZnVuY3Rpb24gcHJpbnRzIHRoZSBrZXl3b3JkIGFyZ3VtZW50cyBhbmQgY2hpbGQgbm9kZXMKICAgICAgICAjIFVzZWQgaW4gYSBkaXNwbGF5YWJsZSBzY3JlZW4gc3RhdGVtZW50CgogICAgICAgICMgSWYgbGluZW5vIGlzIE5vbmUsIHdlJ3JlIGFscmVhZHkgaW5zaWRlIG9mIGEgYmxvY2suCiAgICAgICAgIyBPdGhlcndpc2UsIHdlJ3JlIG9uIHRoZSBsaW5lIHRoYXQgY291bGQgc3RhcnQgYSBibG9jay4KICAgICAgICBrZXl3b3Jkc19ieV9saW5lID0gW10KICAgICAgICBjdXJyZW50X2xpbmUgPSAobGluZW5vLCBbXSkKICAgICAgICBmb3Iga2V5LCB2YWx1ZSBpbiBrZXl3b3JkczoKICAgICAgICAgICAgaWYgdmFsdWUgaXMgTm9uZToKICAgICAgICAgICAgICAgIHZhbHVlID0gIiIKICAgICAgICAgICAgICAgIGlmIGN1cnJlbnRfbGluZVswXSBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgIGtleXdvcmRzX2J5X2xpbmUuYXBwZW5kKGN1cnJlbnRfbGluZSkKICAgICAgICAgICAgICAgICAgICBjdXJyZW50X2xpbmUgPSAoMCwgW10pCiAgICAgICAgICAgIGVsaWYgY3VycmVudF9saW5lWzBdIGlzIE5vbmUgb3IgdmFsdWUubGluZW51bWJlciA+IGN1cnJlbnRfbGluZVswXToKICAgICAgICAgICAgICAgIGtleXdvcmRzX2J5X2xpbmUuYXBwZW5kKGN1cnJlbnRfbGluZSkKICAgICAgICAgICAgICAgIGN1cnJlbnRfbGluZSA9ICh2YWx1ZS5saW5lbnVtYmVyLCBbXSkKICAgICAgICAgICAgY3VycmVudF9saW5lWzFdLmV4dGVuZCgoa2V5LCB2YWx1ZSkpCiAgICAgICAga2V5d29yZHNfYnlfbGluZS5hcHBlbmQoY3VycmVudF9saW5lKQogICAgICAgIGxhc3Rfa2V5d29yZF9saW5lID0ga2V5d29yZHNfYnlfbGluZVstMV1bMF0KICAgICAgICBjaGlsZHJlbl93aXRoX2tleXdvcmRzID0gW10KICAgICAgICBjaGlsZHJlbl9hZnRlcl9rZXl3b3JkcyA9IFtdCiAgICAgICAgZm9yIGkgaW4gY2hpbGRyZW46CiAgICAgICAgICAgIGlmIGkubG9jYXRpb25bMV0gPiBsYXN0X2tleXdvcmRfbGluZToKICAgICAgICAgICAgICAgIGNoaWxkcmVuX2FmdGVyX2tleXdvcmRzLmFwcGVuZChpKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgY2hpbGRyZW5fd2l0aF9rZXl3b3Jkcy5hcHBlbmQoKGkubG9jYXRpb25bMV0sIGkpKQogICAgICAgICMgdGhlIGtleXdvcmRzIGluIGtleXdvcmRzX2J5X2xpbmVbMF0gZ28gb24gdGhlIGxpbmUgdGhhdCBzdGFydHMgdGhlCiAgICAgICAgIyBibG9jaywgbm90IGluIGl0CiAgICAgICAgYmxvY2tfY29udGVudHMgPSBzb3J0ZWQoa2V5d29yZHNfYnlfbGluZVsxOl0gKyBjaGlsZHJlbl93aXRoX2tleXdvcmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleT1pdGVtZ2V0dGVyKDApKQogICAgICAgIGlmIGtleXdvcmRzX2J5X2xpbmVbMF1bMV06ICMgdGhpcyBuZXZlciBoYXBwZW5zIGlmIGxpbmVubyB3YXMgTm9uZQogICAgICAgICAgICBzZWxmLndyaXRlKCIgJXMiICUgJyAnLmpvaW4oa2V5d29yZHNfYnlfbGluZVswXVsxXSkpCiAgICAgICAgaWYgYmxvY2tfY29udGVudHMgb3Ig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dG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKIyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgojCiMgVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KIyBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KIwojIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCiMgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiMgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiMgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgojIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiMgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUKIyBTT0ZUV0FSRS4KCmZyb20gX19mdXR1cmVfXyBpbXBvcnQgdW5pY29kZV9saXRlcmFscwpmcm9tIHV0aWwgaW1wb3J0IERlY29tcGlsZXJCYXNlLCBzcGxpdF9sb2dpY2FsX2xpbmVzLCBEaXNwYXRjaGVyLCBzdHJpbmdfZXNjYXBlCmZyb20gcmVucHkudGVzdCBpbXBvcnQgdGVzdGFzdAoKIyBNYWluIEFQSQoKZGVmIHBwcmludChvdXRfZmlsZSwgYXN0LCBpbmRlbnRfbGV2ZWw9MCwgbGluZW51bWJlcj0xLAogICAgICAgICAgIHNraXBfaW5kZW50X3VudGlsX3dyaXRlPUZhbHNlLCBwcmludGxvY2s9Tm9uZSk6CiAgICByZXR1cm4gVGVzdGNhc2VEZWNvbXBpbGVyKG91dF9maWxlLCBwcmludGxvY2s9cHJpbnRsb2NrKS5kdW1wKAogICAgICAgIGFzdCwgaW5kZW50X2xldmVsLCBsaW5lbnVtYmVyLCBza2lwX2luZGVudF91bnRpbF93cml0ZSkKCiMgSW1wbGVtZW50YXRpb24KCmNsYXNzIFRlc3RjYXNlRGVjb21waWxlcihEZWNvbXBpbGVyQmFzZSk6CiAgICAiIiIKICAgIEFuIG9iamVjdCB3aGljaCBoYW5kbGVzIHRoZSBkZWNvbXBpbGF0aW9uIG9mIHJlbnB5IHRlc3RjYXNlIHN0YXRlbWVudHMKICAgICIiIgoKICAgICMgVGhpcyBkaWN0aW9uYXJ5IGlzIGEgbWFwcGluZyBvZiBDbGFzczogdW5ib3VuZF9tZXRob2QsIHdoaWNoIGlzIHVzZWQgdG8gZGV0ZXJtaW5lCiAgICAjIHdoYXQgbWV0aG9kIHRvIGNhbGwgZm9yIHdoaWNoIHRlc3Rhc3QgY2xhc3MKICAgIGRpc3BhdGNoID0gRGlzcGF0Y2hlcigpCgogICAgZGVmIHByaW50X25vZGUoc2VsZiwgYXN0KToKICAgICAgICBpZiBoYXNhdHRyKGFzdCwgJ2xpbmVudW1iZXInKToKICAgICAgICAgICAgc2VsZi5hZHZhbmNlX3RvX2xpbmUoYXN0LmxpbmVudW1iZXIpCiAgICAgICAgc2VsZi5kaXNwYXRjaC5nZXQodHlwZShhc3QpLCB0eXBlKHNlbGYpLnByaW50X3Vua25vd24pKHNlbGYsIGFzdCkKCiAgICBAZGlzcGF0Y2godGVzdGFzdC5QeXRob24pCiAgICBkZWYgcHJpbnRfcHl0aG9uKHNlbGYsIGFzdCk6CiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIGNvZGUgPSBhc3QuY29kZS5zb3VyY2UKICAgICAgICBpZiBjb2RlWzBdID09ICdcbic6CiAgICAgICAgICAgIHNlbGYud3JpdGUoInB5dGhvbjoiKQogICAgICAgICAgICB3aXRoIHNlbGYuaW5jcmVhc2VfaW5kZW50KCk6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlX2xpbmVzKHNwbGl0X2xvZ2ljYWxfbGluZXMoY29kZVsxOl0pKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYud3JpdGUoIiQgJXMiICUgY29kZSkKCiAgICBAZGlzcGF0Y2godGVzdGFzdC5Bc3NlcnQpCiAgICBkZWYgcHJpbnRfYXNzZXJ0KHNlbGYsIGFzdCk6CiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoJ2Fzc2VydCAlcycgJSBhc3QuZXhwcikKCiAgICBAZGlzcGF0Y2godGVzdGFzdC5KdW1wKQogICAgZGVmIHByaW50X2p1bXAoc2VsZiwgYXN0KToKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZSgnanVtcCAlcycgJSBhc3QudGFyZ2V0KQoKICAgIEBkaXNwYXRjaCh0ZXN0YXN0LkNhbGwpCiAgICBkZWYgcHJpbnRfY2FsbChzZWxmLCBhc3QpOgogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCdjYWxsICVzJyAlIGFzdC50YXJnZXQpCgogICAgQGRpc3BhdGNoKHRlc3Rhc3QuQWN0aW9uKQogICAgZGVmIHByaW50X2FjdGlvbihzZWxmLCBhc3QpOgogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCdydW4gJXMnICUgYXN0LmV4cHIpCgogICAgQGRpc3BhdGNoKHRlc3Rhc3QuUGF1c2UpCiAgICBkZWYgcHJpbnRfcGF1c2Uoc2VsZiwgYXN0KToKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZSgncGF1c2UgJXMnICUgYXN0LmV4cHIpCgogICAgQGRpc3BhdGNoKHRlc3Rhc3QuTGFiZWwpCiAgICBkZWYgcHJpbnRfbGFiZWwoc2VsZiwgYXN0KToKICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgc2VsZi53cml0ZSgnbGFiZWwgJXMnICUgYXN0Lm5hbWUpCgogICAgQGRpc3BhdGNoKHRlc3Rhc3QuVHlwZSkKICAgIGRlZiBwcmludF90eXBlKHNlbGYsIGFzdCk6CiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIGlmIGxlbihhc3Qua2V5c1swXSkgPT0gMToKICAgICAgICAgICAgc2VsZi53cml0ZSgndHlwZSAiJXMiJyAlIHN0cmluZ19lc2NhcGUoJycuam9pbihhc3Qua2V5cykpKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJ3R5cGUgJXMnICUgYXN0LmtleXNbMF0pCiAgICAgICAgaWYgYXN0LnBhdHRlcm4gaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJyBwYXR0ZXJuICIlcyInICUgc3RyaW5nX2VzY2FwZShhc3QucGF0dGVybikpCiAgICAgICAgaWYgaGFzYXR0cihhc3QsICdwb3NpdGlvbicpIGFuZCBhc3QucG9zaXRpb24gaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJyBwb3MgJXMnICUgYXN0LnBvc2l0aW9uKQoKICAgIEBkaXNwYXRjaCh0ZXN0YXN0LkRyYWcpCiAgICBkZWYgcHJpbnRfZHJhZyhzZWxmLCBhc3QpOgogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCdkcmFnICVzJyAlIGFzdC5wb2ludHMpCiAgICAgICAgaWYgYXN0LmJ1dHRvbiAhPSAxOgogICAgICAgICAgICBzZWxmLndyaXRlKCcgYnV0dG9uICVkJyAlIGFzdC5idXR0b24pCiAgICAgICAgaWYgYXN0LnBhdHRlcm4gaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJyBwYXR0ZXJuICIlcyInICUgc3RyaW5nX2VzY2FwZShhc3QucGF0dGVybikpCiAgICAgICAgaWYgYXN0LnN0ZXBzICE9IDEwOgogICAgICAgICAgICBzZWxmLndyaXRlKCcgc3RlcHMgJWQnICUgYXN0LnN0ZXBzKQoKICAgIEBkaXNwYXRjaCh0ZXN0YXN0Lk1vdmUpCiAgICBkZWYgcHJpbnRfbW92ZShzZWxmLCBhc3QpOgogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBzZWxmLndyaXRlKCdtb3ZlICVzJyAlIGFzdC5wb3NpdGlvbikKICAgICAgICBpZiBhc3QucGF0dGVybiBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi53cml0ZSgnIHBhdHRlcm4gIiVzIicgJSBzdHJpbmdfZXNjYXBlKGFzdC5wYXR0ZXJuKSkKCiAgICBAZGlzcGF0Y2godGVzdGFzdC5DbGljaykKICAgIGRlZiBwcmludF9jbGljayhzZWxmLCBhc3QpOgogICAgICAgIHNlbGYuaW5kZW50KCkKICAgICAgICBpZiBhc3QucGF0dGVybiBpcyBub3QgTm9uZToKICAgICAgICAgICAgc2VsZi53cml0ZSgnIiVzIicgJSBzdHJpbmdfZXNjYXBlKGFzdC5wYXR0ZXJuKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLndyaXRlKCdjbGljaycpCiAgICAgICAgaWYgaGFzYXR0cihhc3QsICdidXR0b24nKSBhbmQgYXN0LmJ1dHRvbiAhPSAxOgogICAgICAgICAgICBzZWxmLndyaXRlKCcgYnV0dG9uICVkJyAlIGFzdC5idXR0b24pCiAgICAgICAgaWYgaGFzYXR0cihhc3QsICdwb3NpdGlvbicpIGFuZCBhc3QucG9zaXRpb24gaXMgbm90IE5vbmU6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJyBwb3MgJXMnICUgYXN0LnBvc2l0aW9uKQogICAgICAgIGlmIGhhc2F0dHIoYXN0LCAnYWx3YXlzJykgYW5kIGFzdC5hbHdheXM6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJyBhbHdheXMnKQoKICAgIEBkaXNwYXRjaCh0ZXN0YXN0LlVudGlsKQogICAgZGVmIHByaW50X3VudGlsKHNlbGYsIGFzdCk6CiAgICAgICAgaWYgaGFzYXR0cihhc3QucmlnaHQsICdsaW5lbnVtYmVyJyk6CiAgICAgICAgICAgICMgV2UgZG9uJ3QgaGF2ZSBvdXIgb3duIGxpbmUgbnVtYmVyLCBhbmQgaXQncyBub3QgZ3VhcmFu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aGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKIwojIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCiMgYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCiMKIyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgojIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAojIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRQojIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKIyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAojIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFCiMgU09GVFdBUkUuCgpmcm9tIHV0aWwgaW1wb3J0IHNheV9nZXRfY29kZQppbXBvcnQgcmVucHkKCmltcG9ydCBoYXNobGliCmltcG9ydCByZQpmcm9tIGNvcHkgaW1wb3J0IGNvcHkKCmNsYXNzIFRyYW5zbGF0b3Iob2JqZWN0KToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBsYW5ndWFnZSwgc2F2aW5nX3RyYW5zbGF0aW9ucz1GYWxzZSk6CiAgICAgICAgc2VsZi5sYW5ndWFnZSA9IGxhbmd1YWdlCiAgICAgICAgc2VsZi5zYXZpbmdfdHJhbnNsYXRpb25zID0gc2F2aW5nX3RyYW5zbGF0aW9ucwogICAgICAgIHNlbGYuc3RyaW5ncyA9IHt9CiAgICAgICAgc2VsZi5kaWFsb2d1ZSA9IHt9CiAgICAgICAgc2VsZi5pZGVudGlmaWVycyA9IHNldCgpCgogICAgIyBBZGFwdGVkIGZyb20gUmVuJ1B5J3MgUmVzdHJ1Y3R1cmVyLmNyZWF0ZV90cmFuc2xhdGUKICAgIGRlZiBjcmVhdGVfdHJhbnNsYXRlKHNlbGYsIGJsb2NrKToKICAgICAgICBpZiBzZWxmLnNhdmluZ190cmFuc2xhdGlvbnM6CiAgICAgICAgICAgIHJldHVybiBbXSAjIERvZXNuJ3QgbWF0dGVyLCBzaW5jZSB3ZSdyZSB0aHJvd2luZyB0aGlzIGF3YXkgaW4gdGhpcyBjYXNlCgogICAgICAgIG1kNSA9IGhhc2hsaWIubWQ1KCkKCiAgICAgICAgZm9yIGkgaW4gYmxvY2s6CiAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UoaSwgcmVucHkuYXN0LlNheSk6CiAgICAgICAgICAgICAgICBjb2RlID0gc2F5X2dldF9jb2RlKGkpCiAgICAgICAgICAgIGVsaWYgaXNpbnN0YW5jZShpLCByZW5weS5hc3QuVXNlclN0YXRlbWVudCk6CiAgICAgICAgICAgICAgICBjb2RlID0gaS5saW5lCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICByYWlzZSBFeGNlcHRpb24oIkRvbid0IGtub3cgaG93IHRvIGdldCBjYW5vbmljYWwgY29kZSBmb3IgYSAlcyIgJSBzdHIodHlwZShpKSkpCiAgICAgICAgICAgIG1kNS51cGRhdGUoY29kZS5lbmNvZGUoInV0Zi04IikgKyBiIlxyXG4iKQoKICAgICAgICBpZiBzZWxmLmxhYmVsOgogICAgICAgICAgICBiYXNlID0gc2VsZi5sYWJlbCArICJfIiArIG1kNS5oZXhkaWdlc3QoKVs6OF0KICAgICAgICBlbHNlOgogICAgICAgICAgICBiYXNlID0gbWQ1LmhleGRpZ2VzdCgpWzo4XQoKICAgICAgICBpID0gMAogICAgICAgIHN1ZmZpeCA9ICIiCgogICAgICAgIHdoaWxlIFRydWU6CgogICAgICAgICAgICBpZGVudGlmaWVyID0gYmFzZSArIHN1ZmZpeAoKICAgICAgICAgICAgaWYgaWRlbnRpZmllciBub3QgaW4gc2VsZi5pZGVudGlmaWVyczoKICAgICAgICAgICAgICAgIGJyZWFrCgogICAgICAgICAgICBpICs9IDEKICAgICAgICAgICAgc3VmZml4ID0gIl97MH0iLmZvcm1hdChpKQoKICAgICAgICBzZWxmLmlkZW50aWZpZXJzLmFkZChpZGVudGlmaWVyKQoKICAgICAgICB0cmFuc2xhdGVkX2Jsb2NrID0gc2VsZi5kaWFsb2d1ZS5nZXQoaWRlbnRpZmllcikKICAgICAgICBpZiB0cmFuc2xhdGVkX2Jsb2NrIGlzIE5vbmU6CiAgICAgICAgICAgIHJldHVybiBibG9jawoKICAgICAgICBuZXdfYmxvY2sgPSBbXQogICAgICAgIG9sZF9saW5lbnVtYmVyID0gYmxvY2tbMF0ubGluZW51bWJlcgogICAgICAgIGZvciBhc3QgaW4gdHJhbnNsYXRlZF9ibG9jazoKICAgICAgICAgICAgbmV3X2FzdCA9IGNvcHkoYXN0KQogICAgICAgICAgICBuZXdfYXN0LmxpbmVudW1iZXIgPSBvbGRfbGluZW51bWJlcgogICAgICAgICAgICBuZXdfYmxvY2suYXBwZW5kKG5ld19hc3QpCiAgICAgICAgcmV0dXJuIG5ld19ibG9jawoKICAgIGRlZiB3YWxrKHNlbGYsIGFzdCwgZik6CiAgICAgICAgaWYgaXNpbnN0YW5jZShhc3QsIChyZW5weS5hc3QuSW5pdCwgcmVucHkuYXN0LkxhYmVsLCByZW5weS5hc3QuV2hpbGUsIHJlbnB5LmFzdC5UcmFuc2xhdGUsIHJlbnB5LmFzdC5UcmFuc2xhdGVCbG9jaykpOgogICAgICAgICAgICBmKGFzdC5ibG9jaykKICAgICAgICBlbGlmIGlzaW5zdGFuY2UoYXN0LCByZW5weS5hc3QuTWVudSk6CiAgICAgICAgICAgIGZvciBpIGluIGFzdC5pdGVtczoKICAgICAgICAgICAgICAgIGlmIGlbMl0gaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICAgICAgZihpWzJdKQogICAgICAgIGVsaWYgaXNpbnN0YW5jZShhc3QsIHJlbnB5LmFzdC5JZik6CiAgICAgICAgICAgIGZvciBpIGluIGFzdC5lbnRyaWVzOgogICAgICAgICAgICAgICAgZihpWzFdKQoKICAgICMgQWRhcHRlZCBmcm9tIFJlbidQeSdzIFJlc3RydWN0dXJlci5jYWxsYmFjawogICAgZGVmIHRyYW5zbGF0ZV9kaWFsb2d1ZShzZWxmLCBjaGlsZHJlbik6CiAgICAgICAgbmV3X2NoaWxkcmVuID0gWyBdCiAgICAgICAgZ3JvdXAgPSBbIF0KCiAgICAgICAgZm9yIGkgaW4gY2hpbGRyZW46CgogICAgICAgICAgICBpZiBpc2luc3RhbmNlKGksIHJlbnB5LmFzdC5MYWJlbCk6CiAgICAgICAgICAgICAgICBpZiBub3QgKGhhc2F0dHIoaSwgJ2hpZGUnKSBhbmQgaS5oaWRlKToKICAgICAgICAgICAgICAgICAgICBzZWxmLmxhYmVsID0gaS5uYW1lCgogICAgICAgICAgICBpZiBzZWxmLnNhdmluZ190cmFuc2xhdGlvbnMgYW5kIGlzaW5zdGFuY2UoaSwgcmVucHkuYXN0LlRyYW5zbGF0ZVN0cmluZykgYW5kIGkubGFuZ3VhZ2UgPT0gc2VsZi5sYW5ndWFnZToKICAgICAgICAgICAgICAgIHNlbGYuc3RyaW5nc1tpLm9sZF0gPSBpLm5ldwoKICAgICAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UoaSwgcmVucHkuYXN0LlRyYW5zbGF0ZSk6CiAgICAgICAgICAgICAgICBzZWxmLndhbGsoaSwgc2VsZi50cmFuc2xhdGVfZGlhbG9ndWUpCiAgICAgICAgICAgIGVsaWYgc2VsZi5zYXZpbmdfdHJhbnNsYXRpb25zIGFuZCBpLmxhbmd1YWdlID09IHNlbGYubGFuZ3VhZ2U6CiAgICAgICAgICAgICAgICBzZWxmLmRpYWxvZ3VlW2kuaWRlbnRpZmllcl0gPSBpLmJsb2NrCgogICAgICAgICAgICBpZiBpc2luc3RhbmNlKGksIHJlbnB5LmFzdC5TYXkpOgogICAgICAgICAg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SU8gaW1wb3J0IFN0cmluZ0lPCmZyb20gY29udGV4dGxpYiBpbXBvcnQgY29udGV4dG1hbmFnZXIKCmNsYXNzIERlY29tcGlsZXJCYXNlKG9iamVjdCk6CiAgICBkZWYgX19pbml0X18oc2VsZiwgb3V0X2ZpbGU9Tm9uZSwgaW5kZW50YXRpb249JyAgICAnLCBwcmludGxvY2s9Tm9uZSk6CiAgICAgICAgc2VsZi5vdXRfZmlsZSA9IG91dF9maWxlIG9yIHN5cy5zdGRvdXQKICAgICAgICBzZWxmLmluZGVudGF0aW9uID0gaW5kZW50YXRpb24KICAgICAgICBzZWxmLnNraXBfaW5kZW50X3VudGlsX3dyaXRlID0gRmFsc2UKICAgICAgICBzZWxmLnByaW50bG9jayA9IHByaW50bG9jawoKICAgICAgICBzZWxmLmxpbmVudW1iZXIgPSAwCgogICAgICAgIHNlbGYuYmxvY2tfc3RhY2sgPSBbXQogICAgICAgIHNlbGYuaW5kZXhfc3RhY2sgPSBbXQogICAgICAgIHNlbGYuYmxhbmtfbGluZV9xdWV1ZSA9IFtdCgogICAgZGVmIGR1bXAoc2VsZiwgYXN0LCBpbmRlbnRfbGV2ZWw9MCwgbGluZW51bWJlcj0xLCBza2lwX2luZGVudF91bnRpbF93cml0ZT1GYWxzZSk6CiAgICAgICAgIiIiCiAgICAgICAgV3JpdGUgdGhlIGRlY29tcGlsZWQgcmVwcmVzZW50YXRpb24gb2YgYGFzdGAgaW50byB0aGUgb3BlbmVkIGZpbGUgZ2l2ZW4gaW4gdGhlIGNvbnN0cnVjdG9yCiAgICAgICAgIiIiCiAgICAgICAgc2VsZi5pbmRlbnRfbGV2ZWwgPSBpbmRlbnRfbGV2ZWwKICAgICAgICBzZWxmLmxpbmVudW1iZXIgPSBsaW5lbnVtYmVyCiAgICAgICAgc2VsZi5za2lwX2luZGVudF91bnRpbF93cml0ZSA9IHNraXBfaW5kZW50X3VudGlsX3dyaXRlCiAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UoYXN0LCAodHVwbGUsIGxpc3QpKToKICAgICAgICAgICAgYXN0ID0gW2FzdF0KICAgICAgICBzZWxmLnByaW50X25vZGVzKGFzdCkKICAgICAgICByZXR1cm4gc2VsZi5saW5lbnVtYmVyCgogICAgQGNvbnRleHRtYW5hZ2VyCiAgICBkZWYgaW5jcmVhc2VfaW5kZW50KHNlbGYsIGFtb3VudD0xKToKICAgICAgICBzZWxmLmluZGVudF9sZXZlbCArPSBhbW91bnQKICAgICAgICB0cnk6CiAgICAgICAgICAgIHlpZWxkCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgc2VsZi5pbmRlbnRfbGV2ZWwgLT0gYW1vdW50CgogICAgZGVmIHdyaXRlKHNlbGYsIHN0cmluZyk6CiAgICAgICAgIiIiCiAgICAgICAgU2hvcnRoYW5kIG1ldGhvZCBmb3Igd3JpdGluZyBgc3RyaW5nYCB0byB0aGUgZmlsZQogICAgICAgICIiIgogICAgICAgIHN0cmluZyA9IHVuaWNvZGUoc3RyaW5nKQogICAgICAgIHNlbGYubGluZW51bWJlciArPSBzdHJpbmcuY291bnQoJ1xuJykKICAgICAgICBzZWxmLnNraXBfaW5kZW50X3VudGlsX3dyaXRlID0gRmFsc2UKICAgICAgICBzZWxmLm91dF9maWxlLndyaXRlKHN0cmluZykKCiAgICBkZWYgd3JpdGVfbGluZXMoc2VsZiwgbGluZXMpOgogICAgICAgICIiIgogICAgICAgIFdyaXRlIGVhY2ggbGluZSBpbiBsaW5lcyB0byB0aGUgZmlsZSB3aXRob3V0IHdyaXRpbmcgd2hpdGVzcGFjZS1vbmx5IGxpbmVzCiAgICAgICAgIiIiCiAgICAgICAgZm9yIGxpbmUgaW4gbGluZXM6CiAgICAgICAgICAgIGlmIGxpbmUgPT0gJyc6CiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKCdcbicpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLmluZGVudCgpCiAgICAgICAgICAgICAgICBzZWxmLndyaXRlKGxpbmUpCgogICAgZGVmIHNhdmVfc3RhdGUoc2VsZik6CiAgICAgICAgIiIiCiAgICAgICAgU2F2ZSBvdXIgY3VycmVudCBzdGF0ZS4KICAgICAgICAiIiIKICAgICAgICBzdGF0ZSA9IChzZWxmLm91dF9maWxlLCBzZWxmLnNraXBfaW5kZW50X3VudGlsX3dyaXRlLCBzZWxmLmxpbmVudW1iZXIsCiAgICAgICAgICAgIHNlbGYuYmxvY2tfc3RhY2ssIHNlbGYuaW5kZXhfc3RhY2ssIHNlbGYuaW5kZW50X2xldmVsLCBzZWxmLmJsYW5rX2xpbmVfcXVldWUpCiAgICAgICAgc2VsZi5vdXRfZmlsZSA9IFN0cmluZ0lPKCkKICAgICAgICByZXR1cm4gc3RhdGUKCiAgICBkZWYgY29tbWl0X3N0YXRlKHNlbGYsIHN0YXRlKToKICAgICAgICAiIiIKICAgICAgICBDb21taXQgY2hhbmdlcyBzaW5jZSBhIHNhdmVkIHN0YXRlLgogICAgICAgICIiIgogICAgICAgIG91dF9maWxlID0gc3RhdGVbMF0KICAgICAgICBvdXRfZmlsZS53cml0ZShzZWxmLm91dF9maWxlLmdldHZhbHVlKCkpCiAgICAgICAgc2VsZi5vdXRfZmlsZSA9IG91dF9maWxlCgogICAgZGVmIHJvbGxiYWNrX3N0YXRlKHNlbGYsIHN0YXRlKToKICAgICAgICAiIiIKICAgICAgICBSb2xsIGJhY2sgdG8gYSBzYXZlZCBzdGF0ZS4KICAgICAgICAiIiIKICAgICAgICAoc2VsZi5vdXRfZmlsZSwgc2VsZi5za2lwX2luZGVudF91bnRpbF93cml0ZSwgc2VsZi5saW5lbnVtYmVyLAogICAgICAgICAgICBzZWxmLmJsb2NrX3N0YWNrLCBzZWxmLmluZGV4X3N0YWNrLCBzZWxmLmluZGVudF9sZXZlbCwgc2VsZi5ibGFua19saW5lX3F1ZXVlKSA9IHN0YXRlCgogICAgZGVmIGFkdmFuY2VfdG9fbGluZShzZWxmLCBsaW5lbnVtYmVyKToKICAgICAgICAjIElmIHRoZXJlIHdhcyBhbnl0aGluZyB0aGF0IHdlIHdhbnRlZCB0byBkbyBhcyBzb29uIGFzIHdlIGZvdW5kIGEgYmxhbmsgbGluZSwKICAgICAgICAjIHRyeSB0byBkbyBpdCBub3cuCiAgICAgICAgc2VsZi5ibGFua19saW5lX3F1ZXVlID0gZmlsdGVyKGxhbWJkYSBtOiBtKGxpbmVudW1iZXIpLCBzZWxmLmJsYW5rX2xpbmVfcXVldWUpCiAgICAgICAgaWYgc2VsZi5saW5lbnVtYmVyIDwgbGluZW51bWJlcjoKICAgICAgICAgICAgIyBTdG9wIG9uZSBsaW5lIHNob3J0LCBzaW5jZSB0aGUgY2FsbCB0byBpbmRlbnQoKSB3aWxsIGFkdmFuY2UgdGhlIGxhc3QgbGluZS4KICAgICAgICAgICAgIyBOb3RlIHRoYXQgaWYgc2VsZi5saW5lbnVtYmVyID09IGxpbmVudW1iZXIgLSAxLCB0aGlzIHdpbGwgd3JpdGUgdGhlIGVtcHR5IHN0cmluZy4KICAgICAgICAgICAgIyBUaGlzIGlzIHRvIG1ha2Ugc3VyZSB0aGF0IHNraXBfaW5kZW50X3VudGlsX3dyaXRlIGlzIGNsZWFyZWQgaW4gdGhhdCBjYXNlLgogICAgICAgICAgICBzZWxmLndyaXRlKCJcbiIgKiAobGluZW51bWJlciAtIHNlbGYubGluZW51bWJlciAtIDEpKQoKICAgIGRlZiBkb193aGVuX2JsYW5rX2xpbmUoc2VsZiwgbSk6CiAgICAgICAgIiIiCiAgICAgICAgRG8gc29tZXRoaW5nIHRoZSBuZXh0IHRpbWUgd2UgZmluZCBhIGJsYW5rIGxpbmUuIG0gc2hvdWxkIGJlIGEgbWV0aG9kIHRoYXQgdGFrZXMgb25lCiAgICAgICAgcGFyYW1ldGVyICh0aGUgbGluZSB3ZSdyZSBhZHZhbmNpbmcgdG8pLCBhbmQgcmV0dXJucyB3aGV0aGVyIG9yIG5vdCBpdCBuZWVkcyB0byBydW4KICAgICAgICBhZ2Fpbi4KICAgICAgICAiIiIKICAgICAgICBzZWxmLmJsYW5rX2xpbmVfcXVldWUuYXBwZW5kKG0pCgogICAgZGVmIGluZGVudChzZWxmKToKICAgICAgICAiIiIKICAgICAgICBTaG9ydGhhbmQgbWV0aG9kIGZvciBwdXNoaW5nIGEgbmV3bGluZSBhbmQgaW5kZW50aW5nIHRvIHRoZSBwcm9wZXIgaW5kZW50IGxldmVsCiAgICAgICAgU2V0dGluZyBza2lwX2luZGVudF91bnRpbF93cml0ZSBjYXVzZXMgY2FsbHMgdG8gdGhpcyBtZXRob2QgdG8gYmUgaWdub3JlZCB1bnRpbCBzb21ldGhpbmcKICAgICAgICBjYWxscyB0aGUgd3JpdGUgbWV0aG9kCiAgICAgICAgIiIiCiAgICAgICAgaWYgbm90IHNlbGYuc2tpcF9pbmRlbnRfdW50aWxfd3JpdGU6CiAgICAgICAgICAgIHNlbGYud3JpdGUoJ1xuJyArIHNlbGYuaW5kZW50YXRpb24gKiBzZWxmLmluZGVudF9sZXZlbCkKCiAgICBkZWYgcHJpbnRfbm9kZXMoc2VsZiwgYXN0LCBleHRyYV9pbmRlbnQ9MCk6CiAgICAgICAgIyBUaGlzIG5vZGUgaXMgYSBsaXN0IG9mIG5vZGVzCiAgICAgICAgIyBQcmludCBldmVyeSBub2RlCiAgICAgICAgd2l0aCBzZWxmLmluY3JlYXNlX2luZGVudChleHRyYV9pbmRlbnQpOgogICAgICAgICAgICBzZWxmLmJsb2NrX3N0YWNrLmFwcGVuZChhc3QpCiAgICAgICAgICAgIHNlbGYuaW5kZXhfc3RhY2suYXBwZW5kKDApCgogICAgICAgICAgICBmb3IgaSwgbm9kZSBpbiBlbnVtZXJhdGUoYXN0KToKICAgICAgICAgICAgICAgIHNlbGYuaW5kZXhfc3RhY2tbLTFdID0gaQogICAgICAgICAgICAgICAgc2VsZi5wcmludF9ub2RlKG5vZGUpCgogICAgICAgICAgICBzZWxmLmJsb2NrX3N0YWNrLnBvcCgpCiAgICAgICAgICAgIHNlbGYuaW5kZXhfc3RhY2sucG9wKCkKCiAgICBAcHJvcGVydHkKICAgIGRlZiBibG9jayhzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5ibG9ja19zdGFja1stMV0KCiAgICBAcHJvcGVydHkKICAgIGRlZiBpbmRleChzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5pbmRleF9zdGFja1stMV0KCiAgICBAcHJvcGVydHkKICAgIGRlZiBwYXJlbnQoc2VsZik6CiAgICAgICAgaWYgbGVuKHNlbGYuYmxvY2tfc3RhY2spIDwgMjoKICAgICAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICByZXR1cm4gc2VsZi5ibG9ja19zdGFja1stMl1bc2VsZi5pbmRleF9zdGFja1stMl1dCgogICAgZGVmIHByaW50X2RlYnVnKHNlbGYsIG1lc3NhZ2UpOgogICAgICAgIGlmIHNlbGYucHJpbnRsb2NrOgogICAgICAgICAgICBzZWxmLnByaW50bG9jay5hY3F1aXJlKCkKICAgICAgICB0cnk6CiAgICAgICAgICAgIHByaW50KG1lc3NhZ2UpCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgaWYgc2VsZi5wcmludGxvY2s6CiAgICAgICAgICAgICAgICBzZWxmLnByaW50bG9jay5yZWxlYXNlKCkKCiAgICBkZWYgd3JpdGVfZmFpbHVyZShzZWxmLCBtZXNzYWdlKToKICAgICAgICBzZWxmLnByaW50X2RlYnVnKG1lc3NhZ2UpCiAgICAgICAgc2VsZi5pbmRlbnQoKQogICAgICAgIHNlbGYud3JpdGUoInBhc3MgIyA8PDxDT1VMRCBOT1QgREVDT01QSUxFOiAlcz4+PiIgJSBtZXNzYWdlKQoKICAgIGRlZiBwcmludF91bmtub3duKHNlbGYsIGFzdCk6CiAgICAgICAgIyBJZiB3ZSBlbmNvdW50ZXIgYSBwbGFjZWhvbGRlciBub3RlLCBwcmludCBhIHdhcm5pbmcgYW5kIGluc2VydCBhIHBsYWNlaG9sZGVyCiAgICAgICAgc2VsZi53cml0ZV9mYWlsdXJlKCJVbmtub3duIEFTVCBub2RlOiAlcyIgJSBzdHIodHlwZShhc3QpKSkKCiAgICBkZWYgcHJpbnRfbm9kZShzZWxmLCBhc3QpOgogICAgICAgIHJhaXNlIE5vdEltcGxlbWVudGVkRXJyb3IoKQoKY2xhc3MgRmlyc3Qob2JqZWN0KToKICAgICMgQW4gb2Z0ZW4gdXNlZCBwYXR0ZXJuIGlzIHRoYXQgb24gdGhlIGZpcnN0IGl0ZW0KICAgICMgb2YgYSBsb29wIHNvbWV0aGluZyBzcGVjaWFsIGhhcyB0byBiZSBkb25lLiBUaGlzIGNsYXNzCiAgICAjIHByb3ZpZGVzIGFuIGVhc3kgb2JqZWN0IHdoaWNoIG9uIHRoZSBmaXJzdCBhY2Nlc3MKICAgICMgd2lsbCByZXR1cm4gVHJ1ZSwgYnV0IGFueSBzdWJzZXF1ZW50IGFjY2Vzc2VzIEZhbHNlCiAgICBkZWYgX19pbml0X18oc2VsZiwgeWVzX3ZhbHVlPVRydWUsIG5vX3ZhbHVlPUZhbHNlKToKICAgICAgICBzZWxmLnllc192YWx1ZSA9IHllc192YWx1ZQogICAgICAgIHNlbGYubm9fdmFsdWUgPSBub192YWx1ZQogICAgICAgIHNlbGYuZmlyc3QgPSBUcnVlCgogICAgZGVmIF9fY2FsbF9fKHNlbGYpOgogICAgICAgIGlmIHNlbGYuZmlyc3Q6CiAgICAgICAgICAgIHNlbGYuZmlyc3QgPSBGYWxzZQogICAgICAgICAgICByZXR1cm4gc2VsZi55ZXNfdmFsdWUKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gc2VsZi5ub192YWx1ZQoKZGVmIHJlY29uc3RydWN0X3BhcmFtaW5mbyhwYXJhbWluZm8pOgogICAgaWYgcGFyYW1pbmZvIGlzIE5vbmU6CiAgICAgICAgcmV0dXJuICIiCgogICAgcnYgPSBbIigiXQoKICAgIHNlcCA9IEZpcnN0KCIiLCAiLCAiKQogICAgcG9zaXRpb25hbCA9IFtpIGZvciBpIGluIHBhcmFtaW5mby5wYXJhbWV0ZXJzIGlmIGlbMF0gaW4gcGFyYW1pbmZvLnBvc2l0aW9uYWxdCiAgICBuYW1lb25seSA9IFtpIGZvciBpIGluIHBhcmFtaW5mby5wYXJhbWV0ZXJzIGlmIGkgbm90IGluIHBvc2l0aW9uYWxdCiAgICBmb3IgcGFyYW1ldGVyIGluIHBvc2l0aW9uYWw6CiAgICAgICAgcnYuYXBwZW5kKHNlcCgpKQogICAgICAgIHJ2LmFwcGVuZChwYXJhbWV0ZXJbMF0pCiAgICAgICAgaWYgcGFyYW1ldGVyWzFdIGlzIG5vdCBOb25lOgogICAgICAgICAgICBydi5hcHBlbmQoIj0lcyIgJSBwYXJhbWV0ZXJbMV0pCiAgICBpZiBwYXJhbWluZm8uZXh0cmFwb3M6CiAgICAgICAgcnYuYXBwZW5kKHNlcCgpKQogICAgICAgIHJ2LmFwcGVuZCgiKiVzIiAlIHBhcmFtaW5mby5leHRyYXBvcykKICAgIGlmIG5hbWVvbmx5OgogICAgICAgIGlmIG5vdCBwYXJhbWluZm8uZXh0cmFwb3M6CiAgICAgICAgICAgIHJ2LmFwcGVuZChzZXAoKSkKICAgICAgICAgICAgcnYuYXBwZW5kKCIqIikKICAgICAgICBmb3IgcGFyYW0gaW4gbmFtZW9ubHk6CiAgICAgICAgICAgIHJ2LmFwcGVuZChzZXAoKSkKICAgICAgICAgICAgcnYuYXBwZW5kKHBhcmFtZXRlclswXSkKICAgICAgICAgICAgaWYgcGFyYW1bMV0gaXMgbm90IE5vbmU6CiAgICAgICAgICAgICAgICBydi5hcHBlbmQoIj0lcyIgJSBwYXJhbWV0ZXJbMV0pCiAgICBpZiBwYXJhbWluZm8uZXh0cmFrdzoKICAgICAgICBydi5hcHBlbmQoc2VwKCkpCiAgICAgICAgcnYuYXBwZW5kKCIqKiVzIiAlIHBhcmFtaW5mby5leHRyYWt3KQoKICAgIHJ2LmFwcGVuZCgiKSIpCgogICAgcmV0dXJuICIiLmpvaW4ocnYpCgpkZWYgcmVjb25zdHJ1Y3RfYXJnaW5mbyhhcmdpbmZvKToKICAgIGlmIGFyZ2luZm8gaXMgTm9uZToKICAgICAgICByZXR1cm4gIiIKCiAgICBydiA9IFsiKCJdCiAgICBzZXAgPSBGaXJzdCgiIiwgIiwgIikKICAgIGZvciAobmFtZSwgdmFsKSBpbiBhcmdpbmZvLmFyZ3VtZW50czoKICAgICAgICBydi5hcHBlbmQoc2VwKCkpCiAgICAgICAgaWYgbmFtZSBpcyBub3QgTm9uZToKICAgICAgICAgICAgcnYuYXBwZW5kKCIlcz0iICUgbmFtZSkKICAgICAgICBydi5hcHBlbmQodmFsKQogICAgaWYgYXJnaW5mby5leHRyYXBvczoKICAgICAgICBydi5hcHBlbmQoc2VwKCkpCiAgICAgICAgcnYuYXBwZW5kKCIqJXMiICUgYXJnaW5mby5leHRyYXBvcykKICAgIGlmIGFyZ2luZm8uZXh0cmFrdzoKICAgICAgICBydi5hcHBlbmQoc2VwKCkpCiAgICAgICAgcnYuYXBwZW5kKCIqKiVzIiAlIGFyZ2luZm8uZXh0cmFrdykKICAgIHJ2LmFwcGVuZCgiKSIpCgogICAgcmV0dXJuICIiLmpvaW4ocnYpCgpkZWYgc3RyaW5nX2VzY2FwZShzKTogIyBUT0RPIHNlZSBpZiB0aGlzIG5lZWRzIHRvIHdvcmsgbGlrZSBlbmNvZGVfc2F5X3N0cmluZyBlbHNld2hlcmUKICAgIHMgPSBzLnJlcGxhY2UoJ1xcJywgJ1xcXFwnKQogICAgcyA9IHMucmVwbGFjZSgnIicsICdcXCInKQogICAgcyA9IHMucmVwbGFjZSgnXG4nLCAnXFxuJykKICAgIHMgPSBzLnJlcGxhY2UoJ1x0JywgJ1xcdCcpCiAgICByZXR1cm4gcwoKIyBrZXl3b3JkcyB1c2VkIGJ5IHJlbidweSdzIHBhcnNlcgpLRVlXT1JEUyA9IHNldChbJyQnLCAnYXMnLCAnYXQnLCAnYmVoaW5kJywgJ2NhbGwnLCAnZXhwcmVzc2lvbicsICdoaWRlJywKICAgICAgICAgICAgICAgICdpZicsICdpbicsICdpbWFnZScsICdpbml0JywgJ2p1bXAnLCAnbWVudScsICdvbmxheWVyJywKICAgICAgICAgICAgICAgICdweXRob24nLCAncmV0dXJuJywgJ3NjZW5lJywgJ3NldCcsICdzaG93JywgJ3dpdGgnLAogICAgICAgICAgICAgICAgJ3doaWxlJywgJ3pvcmRlcicsICd0cmFuc2Zvcm0nXSkKCndvcmRfcmVnZXhwID0gJ1thLXpBLVpfXHUwMGEwLVx1ZmZmZF1bMC05YS16QS1aX1x1MDBhMC1cdWZmZmRdKicKCmRlZiBzaW1wbGVfZXhwcmVzc2lvbl9ndWFyZChzKToKICAgICMgU29tZSB0aGluZ3Mgd2UgZGVhbCB3aXRoIGFyZSBzdXBwb3NlZCB0byBiZSBwYXJzZWQgYnkKICAgICMgcmVuJ3B5J3MgTGV4ZXIuc2ltcGxlX2V4cHJlc3Npb24gYnV0IGFjdHVhbGx5IGNhbm5vdAogICAgIyBiZSBwYXJzZWQgYnkgaXQuIGZpZ3VyZSBvdXQgaWYgdGhpcyBpcyB0aGUgY2FzZQogICAgIyBhIHNsaWdodGx5IG1vcmUgbmFpdmUgYXBwcm9hY2ggd291ZGwgYmUgdG8gY2hlY2sKICAgICMgZm9yIHNwYWNlcyBpbiBpdCBhbmQgc3Vycm91bmQgaXQgd2l0aCAoKSBpZiBuZWNlc3NhcnkKICAgICMgYnV0IHdlJ3JlIG5vdCBuYWl2ZQogICAgcyA9IHMuc3RyaXAoKQoKICAgIGlmIExleGVyKHMpLnNpbXBsZV9leHByZXNzaW9uKCk6CiAgICAgICAgcmV0dXJuIHMKICAgIGVsc2U6CiAgICAgICAgcmV0dXJuICIoJXMpIiAlIHMKCmRlZiBzcGxpdF9sb2dpY2FsX2xpbmVzKHMpOgogICAgcmV0dXJuIExleGVyKHMpLnNwbGl0X2xvZ2ljYWxfbGluZXMoKQoKY2xhc3MgTGV4ZXIob2JqZWN0KToKICAgICMgc3BlY2lhbCBsZXhlciBmb3Igc2ltcGxlX2V4cHJlc3Npb25zIHRoZSByZW4ncHkgd2F5CiAgICAjIGZhbHNlIG5lZ2F0aXZlcyBhcmVuJ3QgZGFuZ2Vyb3VzLiBidXQgZmFsc2UgcG9zaXRpdmVzIGFyZQogICAgZGVmIF9faW5pdF9fKHNlbGYsIHN0cmluZyk6CiAgICAgICAgc2VsZi5wb3MgPSAwCiAgICAgICAgc2VsZi5sZW5ndGggPSBsZW4oc3RyaW5nKQogICAgICAgIHNlbGYuc3RyaW5nID0gc3RyaW5nCgogICAgZGVmIHJlKHNlbGYsIHJlZ2V4cCk6CiAgICAgICAgIyBzZWUgaWYgcmVnZXhwIG1hdGNoZXMgYXQgc2VsZi5zdHJpbmdbc2VsZi5wb3NdLgogICAgICAgICMgaWYgaXQgZG9lcywgaW5jcmVtZW50IHNlbGYucG9zCiAgICAgICAgaWYgc2VsZi5sZW5ndGggPT0gc2VsZi5wb3M6CiAgICAgICAgICAgIHJldHVybiBOb25lCgogICAgICAgIG1hdGNoID0gcmUuY29tcGlsZShyZWdleHAsIHJlLkRPVEFMTCkubWF0Y2goc2VsZi5zdHJpbmcsIHNlbGYucG9zKQogICAgICAgIGlmIG5vdCBtYXRjaDoKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgc2VsZi5wb3MgPSBtYXRjaC5lbmQoKQogICAgICAgIHJldHVybiBtYXRjaC5ncm91cCgwKQoKICAgIGRlZiBlb2woc2VsZik6CiAgICAgICAgIyBlYXQgdGhlIG5leHQgd2hpdGVzcGFjZSBhbmQgY2hlY2sgZm9yIHRoZSBlbmQgb2YgdGhpcyBzaW1wbGVfZXhwcmVzc2lvbgogICAgICAgIHNlbGYucmUociIoXHMrfFxcXG4pKyIpCiAgICAgICAgcmV0dXJuIHNlbGYucG9zID49IHNlbGYubGVuZ3RoCgogICAgZGVmIG1hdGNoKHNlbGYsIHJlZ2V4cCk6CiAgICAgICAgIyBzdHJpcCB3aGl0ZXNwYWNlIGFuZCBtYXRjaCByZWdleHAKICAgICAgICBzZWxmLnJlKHIiKFxzK3xcXFxuKSsiKQogICAgICAgIHJldHVybiBzZWxmLnJlKHJlZ2V4cCkKCiAgICBkZWYgcHl0aG9uX3N0cmluZyhzZWxmLCBjbGVhcl93aGl0ZXNwYWNlPVRydWUpOgogICAgICAgICMgcGFyc2Ugc3RyaW5ncyB0aGUgcmVuJ3B5IHdheSAoZG9uJ3QgcGFyc2UgZG9jc3RyaW5ncywgbm8gYi9yIGluIGZyb250IGFsbG93ZWQpCiAgICAgICAgaWYgY2xlYXJfd2hpdGVzcGFjZToKICAgICAgICAgICAgcmV0dXJuIHNlbGYubWF0Y2gociIiIih1Pyg/UDxhPiJ8JykuKj8oPzw9W15cXF0pKD86XFxcXCkqKD9QPWEpKSIiIikKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gc2VsZi5yZShyIiIiKHU/KD9QPGE+InwnKS4qPyg/PD1bXlxcXSkoPzpcXFxcKSooP1A9YSkpIiIiKQoKCiAgICBkZWYgY29udGFpbmVyKHNlbGYpOgogICAgICAgICMgcGFyc2VzIHNvbWV0aGluZyBlbmNsb3NlZCBieSBbXSwgKCkgb3Ige30ncy4ga2V5d29yZCBzb21ldGhpbmcKICAgICAgICBjb250YWluZXJzID0geyJ7IjogIn0iLCAiWyI6ICJdIiwgIigiOiAiKSJ9CiAgICAgICAgaWYgc2VsZi5lb2woKToKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgYyA9IHNlbGYuc3RyaW5nW3NlbGYucG9zXQogICAgICAgIGlmIGMgbm90IGluIGNvbnRhaW5lcnM6CiAgICAgICAgICAgIHJldHVybiBOb25lCiAgICAgICAgc2VsZi5wb3MgKz0gMQoKICAgICAgICBjID0gY29udGFpbmVyc1tjXQoKICAgICAgICB3aGlsZSBub3Qgc2VsZi5lb2woKToKICAgICAgICAgICAgaWYgYyA9PSBzZWxmLnN0cmluZ1tzZWxmLnBvc106CiAgICAgICAgICAgICAgICBzZWxmLnBvcyArPSAxCiAgICAgICAgICAgICAgICByZXR1cm4gVHJ1ZQoKICAgICAgICAgICAgaWYgc2VsZi5weXRob25fc3RyaW5nKCkgb3Igc2VsZi5jb250YWluZXIoKToKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICBzZWxmLnBvcyArPSAxCgogICAgICAgIHJldHVybiBOb25lCgogICAgZGVmIG51bWJlcihzZWxmKToKICAgICAgICAjIHBhcnNlcyBhIG51bWJlciwgZmxvYXQgb3IgaW50IChidXQgbm90IGZvcmNlZCBsb25nKQogICAgICAgIHJldHVybiBzZWxmLm1hdGNoKHInKFwrfFwtKT8oXGQrXC4/XGQqfFwuXGQrKSg/OltlRV1bLStdP1xkKyk/JykKCiAgICBkZWYgd29yZChzZWxmKToKICAgICAgICAjIHBhcnNlcyBhIHdvcmQKICAgICAgICByZXR1cm4gc2VsZi5tYXRjaCh3b3JkX3JlZ2V4cCkKCiAgICBkZWYgbmFtZShzZWxmKToKICAgICAgICAjIHBhcnNlcyBhIHdvcmQgdW5sZXNzIGl0J3MgaW4gS0VZV09SRFMuCiAgICAgICAgcG9zID0gc2VsZi5wb3MKICAgICAgICB3b3JkID0gc2VsZi53b3JkKCkKCiAgICAgICAgaWYgd29yZCBpbiBLRVlXT1JEUzoKICAgICAgICAgICAgc2VsZi5wb3MgPSBwb3MKICAgICAgICAgICAgcmV0dXJuIE5vbmUKCiAgICAgICAgcmV0dXJuIHdvcmQKCiAgICBkZWYgc2ltcGxlX2V4cHJlc3Npb24oc2VsZik6CiAgICAgICAgIyB0ZXN0IGlmIHRoZSBzdGFydCBzdHJpbmcgd2FzIGEgc2ltcGxlIGV4cHJlc3Npb24KICAgICAgICBzdGFydCA9IHNlbGYucG9zCgogICAgICAgICMgY2hlY2sgaWYgdGhlcmUncyBhbnl0aGluZyBpbiBoZXJlIGFjY3R1YWxseQogICAgICAgIGlmIHNlbGYuZW9sKCk6CiAgICAgICAgICAgIHJldHVybiBGYWxzZQoKICAgICAgICAjIHBhcnNlIGFueXRoaW5nIHdoaWNoIGNhbiBiZSBjYWxsZWQgb3IgaGF2ZSBhdHRyaWJ1dGVzIHJlcXVlc3RlZAogICAgICAgIGlmIG5vdChzZWxmLnB5dGhvbl9zdHJpbmcoKSBvcgogICAgICAgICAgICAgICBzZWxmLm51bWJlcigpIG9yCiAgICAgICAgICAgICAgIHNlbGYuY29udGFpbmVyKCkgb3IKICAgICAgICAgICAgICAgc2VsZi5uYW1lKCkpOgogICAgICAgICAgICByZXR1cm4gRmFsc2UKCiAgICAgICAgd2hpbGUgbm90IHNlbGYuZW9sKCk6CgogICAgICAgICAgICAjIGlmIHRoZSBwcmV2aW91cyB3YXMgZm9sbG93ZWQgYnkgYSBkb3QsIHRoZXJlIHNob3VsZCBiZSBhIHdvcmQgYWZ0ZXIgaXQKICAgICAgICAgICAgaWYgc2VsZi5tYXRjaChyJ1wuJyk6CiAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5uYW1lKCk6CiAgICAgICAgICAgICAgICAgICAgIyByZW4ncHkgZXJyb3JzIGhlcmUuIEkganVzdCBzdG9wIGNhcmluZwogICAgICAgICAgICAgICAgICAgIHJldHVybiBGYWxzZQoKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICAjIHBhcnNlcyBzbGljZXMsIGZ1bmN0aW9uIGNhbGxzLCBhbmQgcG9zdGZpeCB7fQogICAgICAgICAgICBpZiBzZWxmLmNvbnRhaW5lcigpOgogICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgIGJyZWFrCgogICAgICAgICAgICAjIGFyZSB3ZSBhdCB0aGUgZW5kIG9mIHRoZSBzaW1wbGUgZXhwcmVzc2lvbj8KICAgICAgICByZXR1cm4gc2VsZi5lb2woKQoKICAgIGRlZiBzcGxpdF9sb2dpY2FsX2xpbmVzKHNlbGYpOgogICAgICAgICMgc3BsaXQgYSBzZXF1ZW5jZSBpbiBsb2dpY2FsIGxpbmVzCiAgICAgICAgIyB0aGlzIGJlaGF2ZXMgc2ltaWxhcmx5IHRvIC5zcGxpdGxpbmVzKCkgd2hpY2ggd2lsbCBpZ25vcmUKICAgICAgICAjIGEgdHJhaWxpbmcgXG4KICAgICAgICBsaW5lcyA9IFtdCgogICAgICAgIGNvbnRhaW5lZCA9IDAKCiAgICAgICAgc3RhcnRwb3MgPSBzZWxmLnBvcwoKICAgICAgICB3aGlsZSBzZWxmLnBvcyA8IHNlbGYubGVuZ3RoOgogICAgICAgICAgICBjID0gc2VsZi5zdHJpbmdbc2VsZi5wb3NdCgogICAgICAgICAgICBpZiBjID09ICdcbicgYW5kIG5vdCBjb250YWluZWQgYW5kIChub3Qgc2VsZi5wb3Mgb3Igc2VsZi5zdHJpbmdbc2VsZi5wb3MgLSAxXSAhPSAnXFwnKToKICAgICAgICAgICAgICAgIGxpbmVzLmFwcGVuZChzZWxmLnN0cmluZ1tzdGFydHBvczpzZWxmLnBvc10pCiAgICAgICAgICAgICAgICAjIHRoZSAnXG4nIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGUgZW1pdHRlZCBsaW5lCiAgICAgICAgICAgICAgICBzZWxmLnBvcyArPSAxCiAgICAgICAgICAgICAgICBzdGFydHBvcyA9IHNlbGYucG9zCiAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgaWYgYyBpbiAoJygnLCAnWycsICd7Jyk6CiAgICAgICAgICAgICAgICBjb250YWluZWQgKz0gMQogICAgICAgICAgICAgICAgc2VsZi5wb3MgKz0gMQogICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgIGlmIGMgaW4gKCcpJywgJ10nLCAnfScpIGFuZCBjb250YWluZWQ6CiAgICAgICAgICAgICAgICBjb250YWluZWQgLT0gMQogICAgICAgICAgICAgICAgc2VsZi5wb3MgKz0gMQogICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgIGlmIGMgPT0gJyMnOgogICAgICAgICAgICAgICAgc2VsZi5yZSgiW15cbl0qIikKICAgICAgICAgICAgICAgIGNvbnRpbnVlCgogICAgICAgICAgICBpZiBzZWxmLnB5dGhvbl9zdHJpbmcoRmFsc2UpOgogICAgICAgICAgICAgICAgY29udGludWUKCiAgICAgICAgICAgIHNlbGYucmUocidcdyt8ICt8LicpICMgY29uc3VtZSBhIHdvcmQsIHdoaXRlc3BhY2Ugb3Igb25lIHN5bWJvbAoKICAgICAgICBpZiBzZWxmLnBvcyAhPSBzdGFydHBvczoKICAgICAgICAgICAgbGluZXMuYXBwZW5kKHNlbGYuc3RyaW5nW3N0YXJ0cG9zOl0pCiAgICAgICAgcmV0dXJuIGxpbmVzCgojIFZlcnNpb25zIG9mIFJlbidQeSBwcmlvciB0byA2LjE3IHB1dCB0cmFpbGluZyB3aGl0ZXNwYWNlIG9uIHRoZSBlbmQgb2YKIyBzaW1wbGVfZXhwcmVzc2lvbnMuIFRoaXMgY2xhc3MgYXR0ZW1wdHMgdG8gcHJlc2VydmUgdGhlIGFtb3VudCBvZgojIHdoaXRlc3BhY2UgaWYgcG9zc2libGUuCmNsYXNzIFdvcmRDb25jYXRlbmF0b3Iob2JqZWN0KToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBuZWVkc19zcGFjZSwgcmVvcmRlcmFibGU9RmFsc2UpOgogICAgICAgIHNlbGYud29yZHMgPSBbXQogICAgICAgIHNlbGYubmVlZHNfc3BhY2UgPSBuZWVkc19zcGFjZQogICAgICAgIHNlbGYucmVvcmRlcmFibGUgPSByZW9yZGVyYWJsZQoKICAgIGRlZiBhcHBlbmQoc2VsZiwgKmFyZ3MpOgogICAgICAgIHNlbGYud29yZHMuZXh0ZW5kKGZpbHRlcihOb25lLCBhcmdzKSkKCiAgICBkZWYgam9pbihzZWxmKToKICAgICAgICBpZiBub3Qgc2VsZi53b3JkczoKICAgICAgICAgICAgcmV0dXJuICcnCiAgICAgICAgaWYgc2VsZi5yZW9yZGVyYWJsZSBhbmQgc2VsZi53b3Jkc1stMV1bLTFdID09ICcgJzoKICAgICAgICAgICAgZm9yIGkgaW4geHJhbmdlKGxlbihzZWxmLndvcmRzKSAtIDEsIC0xLCAtMSk6CiAgICAgICAgICAgICAgICBpZiBzZWxmLndvcmRzW2ldWy0xXSAhPSAnICc6CiAgICAgICAgICAgICAgICAgICAgc2VsZi53b3Jkcy5hcHBlbmQoc2VsZi53b3Jkcy5wb3AoaSkpCiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICBsYXN0X3dvcmQgPSBzZWxmLndvcmRzWy0xXQogICAgICAgIHNlbGYud29yZHMgPSBtYXAobGFtYmRhIHg6IHhbOi0xXSBpZiB4Wy0xXSA9PSAnICcgZWxzZSB4LCBzZWxmLndvcmRzWzotMV0pCiAgICAgICAgc2VsZi53b3Jkcy5hcHBlbmQobGFzdF93b3JkKQogICAgICAgIHJ2ID0gKCcgJyBpZiBzZWxmLm5lZWRzX3NwYWNlIGVsc2UgJycpICsgJyAnLmpvaW4oc2VsZi53b3JkcykKICAgICAgICBzZWxmLm5lZWRzX3NwYWNlID0gcnZbLTFdICE9ICcgJwogICAgICAgIHJldHVybiBydgoKIyBEaWN0IHN1YmNsYXNzIGZvciBhZXN0aGV0aWMgZGlzcGF0Y2hpbmcuIHVzZSBARGlzcGF0Y2hlcihkYXRhKSB0byBkaXNwYXRjaApjbGFzcyBEaXNwYXRjaGVyKGRpY3QpOgogICAgZGVmIF9fY2FsbF9fKHNlbGYsIG5hbWUpOgogICAgICAgIGRlZiBjbG9zdXJlKGZ1bmMpOgogICAgICAgICAgICBzZWxmW25hbWVdID0gZnVuYwogICAgICAgICAgICByZXR1cm4gZnVuYwogICAgICAgIHJldHVybiBjbG9zdXJlCgojIHJlbidweSBzdHJpbmcgaGFuZGxpbmcKZGVmIGVuY29kZV9zYXlfc3RyaW5nKHMpOgogICAgIiIiCiAgICBFbmNvZGVzIGEgc3RyaW5nIGluIHRoZSBmb3JtYXQgdXNlZCBieSBSZW4nUHkgc2F5IHN0YXRlbWVudHMuCiAgICAiIiIKCiAgICBzID0gcy5yZXBsYWNlKCJcXCIsICJcXFxcIikKICAgIHMgPSBzLnJlcGxhY2UoIlxuIiwgIlxcbiIpCiAgICBzID0gcy5yZXBsYWNlKCJcIiIsICJcXFwiIikKICAgIHMgPSByZS5zdWIocicoPzw9ICkgJywgJ1xcICcsIHMpCgogICAgcmV0dXJuICJcIiIgKyBzICsgIlwiIgoKIyBBZGFwdGVkIGZyb20gUmVuJ1B5J3MgU2F5LmdldF9jb2RlCmRlZiBzYXlfZ2V0X2NvZGUoYXN0LCBpbm1lbnU9RmFsc2UpOgogICAgcnYgPSBbIF0KCiAgICBpZiBhc3Qud2hvOgogICAgICAgIHJ2LmFwcGVuZChhc3Qud2hvKQoKICAgIGlmIGhhc2F0dHIoYXN0LCAnYXR0cmlidXRlcycpIGFuZCBhc3QuYXR0cmlidXRlcyBpcyBub3QgTm9uZToKICAgICAgICBydi5leHRlbmQoYXN0LmF0dHJpYnV0ZXMpCgogICAgIyBubyBkaWFsb2d1ZV9maWx0ZXIgYXBwbGllcyB0byB1cwoKICAgIHJ2LmFwcGVuZChlbmNvZGVfc2F5X3N0cmluZyhhc3Qud2hhdCkpCgogICAgaWYgbm90IGFzdC5pbnRlcmFjdCBhbmQgbm90IGlubWVudToKICAgICAgICBydi5hcHBlbmQoIm5vaW50ZXJhY3QiKQoKICAgIGlmIGFzdC53aXRoXzoKICAgICAgICBydi5hcHBlbmQoIndpdGgiKQogICAgICAgIHJ2LmFwcGVuZChhc3Qud2l0aF8pCgogICAgcmV0dXJuICIgIi5qb2luKHJ2KQoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" base64 --decode <<< "$decompiler" > /tmp/decompiler.tar pushd /tmp > /dev/null || exit tar xf decompiler.tar popd > /dev/null || exit # ------------------------------------------------------------------------------------------ # rpatool - https://github.com/Shizmob/rpatool rpatool="IyEvdXNyL2Jpbi9lbnYgcHl0aG9uDQoNCmZyb20gX19mdXR1cmVfXyBpbXBvcnQgcHJpbnRfZnVuY3Rpb24NCg0KaW1wb3J0IHN5cw0KaW1wb3J0IG9zDQppbXBvcnQgY29kZWNzDQppbXBvcnQgcGlja2xlDQppbXBvcnQgZXJybm8NCmltcG9ydCByYW5kb20NCg0KaWYgc3lzLnZlcnNpb25faW5mb1swXSA+PSAzOg0KICAgIGRlZiBfdW5pY29kZSh0ZXh0KToNCiAgICAgICAgcmV0dXJuIHRleHQNCg0KICAgIGRlZiBfcHJpbnRhYmxlKHRleHQpOg0KICAgICAgICByZXR1cm4gdGV4dA0KDQogICAgZGVmIF91bm1hbmdsZShkYXRhKToNCiAgICAgICAgcmV0dXJuIGRhdGEuZW5jb2RlKCdsYXRpbjEnKQ0KDQogICAgZGVmIF91bnBpY2tsZShkYXRhKToNCiAgICAgICAgIyBTcGVjaWZ5IGxhdGluMSBlbmNvZGluZyB0byBwcmV2ZW50IHJhdyBieXRlIHZhbHVlcyBmcm9tIGNhdXNpbmcgYW4gQVNDSUkgZGVjb2RlIGVycm9yLg0KICAgICAgICByZXR1cm4gcGlja2xlLmxvYWRzKGRhdGEsIGVuY29kaW5nPSdsYXRpbjEnKQ0KZWxpZiBzeXMudmVyc2lvbl9pbmZvWzBdID09IDI6DQogICAgZGVmIF91bmljb2RlKHRleHQpOg0KICAgICAgICBpZiBpc2luc3RhbmNlKHRleHQsIHVuaWNvZGUpOg0KICAgICAgICAgICAgcmV0dXJuIHRleHQNCiAgICAgICAgcmV0dXJuIHRleHQuZGVjb2RlKCd1dGYtOCcpDQoNCiAgICBkZWYgX3ByaW50YWJsZSh0ZXh0KToNCiAgICAgICAgcmV0dXJuIHRleHQuZW5jb2RlKCd1dGYtOCcpDQoNCiAgICBkZWYgX3VubWFuZ2xlKGRhdGEpOg0KICAgICAgICByZXR1cm4gZGF0YQ0KDQogICAgZGVmIF91bnBpY2tsZShkYXRhKToNCiAgICAgICAgcmV0dXJuIHBpY2tsZS5sb2FkcyhkYXRhKQ0KDQpjbGFzcyBSZW5QeUFyY2hpdmU6DQogICAgZmlsZSA9IE5vbmUNCiAgICBoYW5kbGUgPSBOb25lDQoNCiAgICBmaWxlcyA9IHt9DQogICAgaW5kZXhlcyA9IHt9DQoNCiAgICB2ZXJzaW9uID0gTm9uZQ0KICAgIHBhZGxlbmd0aCA9IDANCiAgICBrZXkgPSBOb25lDQogICAgdmVyYm9zZSA9IEZhbHNlDQoNCiAgICBSUEEyX01BR0lDID0gJ1JQQS0yLjAgJw0KICAgIFJQQTNfTUFHSUMgPSAnUlBBLTMuMCAnDQoNCiAgICAjIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5LCBvdGhlcndpc2UgUHl0aG9uMy1wYWNrZWQgYXJjaGl2ZXMgd29uJ3QgYmUgcmVhZCBieSBQeXRob24yDQogICAgUElDS0xFX1BST1RPQ09MID0gMg0KDQogICAgZGVmIF9faW5pdF9fKHNlbGYsIGZpbGUgPSBOb25lLCB2ZXJzaW9uID0gMywgcGFkbGVuZ3RoID0gMCwga2V5ID0gMHhERUFEQkVFRiwgdmVyYm9zZSA9IEZhbHNlKToNCiAgICAgICAgc2VsZi5wYWRsZW5ndGggPSBwYWRsZW5ndGgNCiAgICAgICAgc2VsZi5rZXkgPSBrZXkNCiAgICAgICAgc2VsZi52ZXJib3NlID0gdmVyYm9zZQ0KDQogICAgICAgIGlmIGZpbGUgaXMgbm90IE5vbmU6DQogICAgICAgICAgICBzZWxmLmxvYWQoZmlsZSkNCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIHNlbGYudmVyc2lvbiA9IHZlcnNpb24NCg0KICAgIGRlZiBfX2RlbF9fKHNlbGYpOg0KICAgICAgICBpZiBzZWxmLmhhbmRsZSBpcyBub3QgTm9uZToNCiAgICAgICAgICAgIHNlbGYuaGFuZGxlLmNsb3NlKCkNCg0KICAgICMgRGV0ZXJtaW5lIGFyY2hpdmUgdmVyc2lvbi4NCiAgICBkZWYgZ2V0X3ZlcnNpb24oc2VsZik6DQogICAgICAgIHNlbGYuaGFuZGxlLnNlZWsoMCkNCiAgICAgICAgbWFnaWMgPSBzZWxmLmhhbmRsZS5yZWFkbGluZSgpLmRlY29kZSgndXRmLTgnKQ0KDQogICAgICAgIGlmIG1hZ2ljLnN0YXJ0c3dpdGgoc2VsZi5SUEEzX01BR0lDKToNCiAgICAgICAgICAgIHJldHVybiAzDQogICAgICAgIGVsaWYgbWFnaWMuc3RhcnRzd2l0aChzZWxmLlJQQTJfTUFHSUMpOg0KICAgICAgICAgICAgcmV0dXJuIDINCiAgICAgICAgZWxpZiBzZWxmLmZpbGUuZW5kc3dpdGgoJy5ycGknKToNCiAgICAgICAgICAgIHJldHVybiAxDQoNCiAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigndGhlIGdpdmVuIGZpbGUgaXMgbm90IGEgdmFsaWQgUmVuXCdQeSBhcmNoaXZlLCBvciBhbiB1bnN1cHBvcnRlZCB2ZXJzaW9uJykNCg0KICAgICMgRXh0cmFjdCBmaWxlIGluZGV4ZXMgZnJvbSBvcGVuZWQgYXJjaGl2ZS4NCiAgICBkZWYgZXh0cmFjdF9pbmRleGVzKHNlbGYpOg0KICAgICAgICBzZWxmLmhhbmRsZS5zZWVrKDApDQogICAgICAgIGluZGV4ZXMgPSBOb25lDQoNCiAgICAgICAgaWYgc2VsZi52ZXJzaW9uID09IDIgb3Igc2VsZi52ZXJzaW9uID09IDM6DQogICAgICAgICAgICAjIEZldGNoIG1ldGFkYXRhLg0KICAgICAgICAgICAgbWV0YWRhdGEgPSBzZWxmLmhhbmRsZS5yZWFkbGluZSgpDQogICAgICAgICAgICB2YWxzID0gbWV0YWRhdGEuc3BsaXQoKQ0KICAgICAgICAgICAgb2Zmc2V0ID0gaW50KHZhbHNbMV0sIDE2KQ0KICAgICAgICAgICAgaWYgc2VsZi52ZXJzaW9uID09IDM6DQogICAgICAgICAgICAgICAgc2VsZi5rZXkgPSAwDQogICAgICAgICAgICAgICAgZm9yIHN1YmtleSBpbiB2YWxzWzI6XToNCiAgICAgICAgICAgICAgICAgICAgc2VsZi5rZXkgXj0gaW50KHN1YmtleSwgMTYpDQoNCiAgICAgICAgICAgICMgTG9hZCBpbiBpbmRleGVzLg0KICAgICAgICAgICAgc2VsZi5oYW5kbGUuc2VlayhvZmZzZXQpDQogICAgICAgICAgICBjb250ZW50cyA9IGNvZGVjcy5kZWNvZGUoc2VsZi5oYW5kbGUucmVhZCgpLCAnemxpYicpDQogICAgICAgICAgICBpbmRleGVzID0gX3VucGlja2xlKGNvbnRlbnRzKQ0KDQogICAgICAgICAgICAjIERlb2JmdXNjYXRlIGluZGV4ZXMuDQogICAgICAgICAgICBpZiBzZWxmLnZlcnNpb24gPT0gMzoNCiAgICAgICAgICAgICAgICBvYmZ1c2NhdGVkX2luZGV4ZXMgPSBpbmRleGVzDQogICAgICAgICAgICAgICAgaW5kZXhlcyA9IHt9DQogICAgICAgICAgICAgICAgZm9yIGkgaW4gb2JmdXNjYXRlZF9pbmRleGVzLmtleXMoKToNCiAgICAgICAgICAgICAgICAgICAgaWYgbGVuKG9iZnVzY2F0ZWRfaW5kZXhlc1tpXVswXSkgPT0gMjoNCiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ZXNbaV0gPSBbIChvZmZzZXQgXiBzZWxmLmtleSwgbGVuZ3RoIF4gc2VsZi5rZXkpIGZvciBvZmZzZXQsIGxlbmd0aCBpbiBvYmZ1c2NhdGVkX2luZGV4ZXNbaV0gXQ0KICAgICAgICAgICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXhlc1tpXSA9IFsgKG9mZnNldCBeIHNlbGYua2V5LCBsZW5ndGggXiBzZWxmLmtleSwgcHJlZml4KSBmb3Igb2Zmc2V0LCBsZW5ndGgsIHByZWZpeCBpbiBvYmZ1c2NhdGVkX2luZGV4ZXNbaV0gXQ0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgaW5kZXhlcyA9IHBpY2tsZS5sb2Fkcyhjb2RlY3MuZGVjb2RlKHNlbGYuaGFuZGxlLnJlYWQoKSwgJ3psaWInKSkNCg0KICAgICAgICByZXR1cm4gaW5kZXhlcw0KDQogICAgIyBHZW5lcmF0ZSBwc2V1ZG9yYW5kb20gcGFkZGluZyAoZm9yIHdoYXRldmVyIHJlYXNvbikuDQogICAgZGVmIGdlbmVyYXRlX3BhZGRpbmcoc2VsZik6DQogICAgICAgIGxlbmd0aCA9IHJhbmRvbS5yYW5kaW50KDEsIHNlbGYucGFkbGVuZ3RoKQ0KDQogICAgICAgIHBhZGRpbmcgPSAnJw0KICAgICAgICB3aGlsZSBsZW5ndGggPiAwOg0KICAgICAgICAgICAgcGFkZGluZyArPSBjaHIocmFuZG9tLnJhbmRpbnQoMSwgMjU1KSkNCiAgICAgICAgICAgIGxlbmd0aCAtPSAxDQoNCiAgICAgICAgcmV0dXJuIHBhZGRpbmcNCg0KICAgICMgQ29udmVydHMgYSBmaWxlbmFtZSB0byBhcmNoaXZlIGZvcm1hdC4NCiAgICBkZWYgY29udmVydF9maWxlbmFtZShzZWxmLCBmaWxlbmFtZSk6DQogICAgICAgIChkcml2ZSwgZmlsZW5hbWUpID0gb3MucGF0aC5zcGxpdGRyaXZlKG9zLnBhdGgubm9ybXBhdGgoZmlsZW5hbWUpLnJlcGxhY2Uob3Muc2VwLCAnLycpKQ0KICAgICAgICByZXR1cm4gZmlsZW5hbWUNCg0KICAgICMgRGVidWcgKHZlcmJvc2UpIG1lc3NhZ2VzLg0KICAgIGRlZiB2ZXJib3NlX3ByaW50KHNlbGYsIG1lc3NhZ2UpOg0KICAgICAgICBpZiBzZWxmLnZlcmJvc2U6DQogICAgICAgICAgICBwcmludChtZXNzYWdlKQ0KDQoNCiAgICAjIExpc3QgZmlsZXMgaW4gYXJjaGl2ZSBhbmQgY3VycmVudCBpbnRlcm5hbCBzdG9yYWdlLg0KICAgIGRlZiBsaXN0KHNlbGYpOg0KICAgICAgICByZXR1cm4gbGlzdChzZWxmLmluZGV4ZXMua2V5cygpKSArIGxpc3Qoc2VsZi5maWxlcy5rZXlzKCkpDQoNCiAgICAjIENoZWNrIGlmIGEgZmlsZSBleGlzdHMgaW4gdGhlIGFyY2hpdmUuDQogICAgZGVmIGhhc19maWxlKHNlbGYsIGZpbGVuYW1lKToNCiAgICAgICAgZmlsZW5hbWUgPSBfdW5pY29kZShmaWxlbmFtZSkNCiAgICAgICAgcmV0dXJuIGZpbGVuYW1lIGluIHNlbGYuaW5kZXhlcy5rZXlzKCkgb3IgZmlsZW5hbWUgaW4gc2VsZi5maWxlcy5rZXlzKCkNCg0KICAgICMgUmVhZCBmaWxlIGZyb20gYXJjaGl2ZSBvciBpbnRlcm5hbCBzdG9yYWdlLg0KICAgIGRlZiByZWFkKHNlbGYsIGZpbGVuYW1lKToNCiAgICAgICAgZmlsZW5hbWUgPSBzZWxmLmNvbnZlcnRfZmlsZW5hbWUoX3VuaWNvZGUoZmlsZW5hbWUpKQ0KDQogICAgICAgICMgQ2hlY2sgaWYgdGhlIGZpbGUgZXhpc3RzIGluIG91ciBpbmRleGVzLg0KICAgICAgICBpZiBmaWxlbmFtZSBub3QgaW4gc2VsZi5maWxlcyBhbmQgZmlsZW5hbWUgbm90IGluIHNlbGYuaW5kZXhlczoNCiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoZXJybm8uRU5PRU5ULCAndGhlIHJlcXVlc3RlZCBmaWxlIHswfSBkb2VzIG5vdCBleGlzdCBpbiB0aGUgZ2l2ZW4gUmVuXCdQeSBhcmNoaXZlJy5mb3JtYXQoDQogICAgICAgICAgICAgICAgX3ByaW50YWJsZShmaWxlbmFtZSkpKQ0KDQogICAgICAgICMgSWYgaXQncyBpbiBvdXIgb3BlbmVkIGFyY2hpdmUgaW5kZXgsIGFuZCBvdXIgYXJjaGl2ZSBoYW5kbGUgaXNuJ3QgdmFsaWQsIHNvbWV0aGluZyBpcyBvYnZpb3VzbHkgd3JvbmcuDQogICAgICAgIGlmIGZpbGVuYW1lIG5vdCBpbiBzZWxmLmZpbGVzIGFuZCBmaWxlbmFtZSBpbiBzZWxmLmluZGV4ZXMgYW5kIHNlbGYuaGFuZGxlIGlzIE5vbmU6DQogICAgICAgICAgICByYWlzZSBJT0Vycm9yKGVycm5vLkVOT0VOVCwgJ3RoZSByZXF1ZXN0ZWQgZmlsZSB7MH0gZG9lcyBub3QgZXhpc3QgaW4gdGhlIGdpdmVuIFJlblwnUHkgYXJjaGl2ZScuZm9ybWF0KA0KICAgICAgICAgICAgICAgIF9wcmludGFibGUoZmlsZW5hbWUpKSkNCg0KICAgICAgICAjIENoZWNrIG91ciBzaW1wbGlmaWVkIGludGVybmFsIGluZGV4ZXMgZmlyc3QsIGluIGNhc2Ugc29tZW9uZSB3YW50cyB0byByZWFkIGEgZmlsZSB0aGV5IGFkZGVkIGJlZm9yZSB3aXRob3V0IHNhdmluZywgZm9yIHNvbWUgdW5ob2x5IHJlYXNvbi4NCiAgICAgICAgaWYgZmlsZW5hbWUgaW4gc2VsZi5maWxlczoNCiAgICAgICAgICAgIHNlbGYudmVyYm9zZV9wcmludCgnUmVhZGluZyBmaWxlIHswfSBmcm9tIGludGVybmFsIHN0b3JhZ2UuLi4nLmZvcm1hdChfcHJpbnRhYmxlKGZpbGVuYW1lKSkpDQogICAgICAgICAgICByZXR1cm4gc2VsZi5maWxlc1tmaWxlbmFtZV0NCiAgICAgICAgIyBXZSBuZWVkIHRvIHJlYWQgdGhlIGZpbGUgZnJvbSBvdXIgb3BlbiBhcmNoaXZlLg0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgIyBSZWFkIG9mZnNldCBhbmQgbGVuZ3RoLCBzZWVrIHRvIHRoZSBvZmZzZXQgYW5kIHJlYWQgdGhlIGZpbGUgY29udGVudHMuDQogICAgICAgICAgICBpZiBsZW4oc2VsZi5pbmRleGVzW2ZpbGVuYW1lXVswXSkgPT0gMzoNCiAgICAgICAgICAgICAgICAob2Zmc2V0LCBsZW5ndGgsIHByZWZpeCkgPSBzZWxmLmluZGV4ZXNbZmlsZW5hbWVdWzBdDQogICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgIChvZmZzZXQsIGxlbmd0aCkgPSBzZWxmLmluZGV4ZXNbZmlsZW5hbWVdWzBdDQogICAgICAgICAgICAgICAgcHJlZml4ID0gJycNCg0KICAgICAgICAgICAgc2VsZi52ZXJib3NlX3ByaW50KCdSZWFkaW5nIGZpbGUgezB9IGZyb20gZGF0YSBmaWxlIHsxfS4uLiAob2Zmc2V0ID0gezJ9LCBsZW5ndGggPSB7M30gYnl0ZXMpJy5mb3JtYXQoDQogICAgICAgICAgICAgICAgX3ByaW50YWJsZShmaWxlbmFtZSksIHNlbGYuZmlsZSwgb2Zmc2V0LCBsZW5ndGgpKQ0KICAgICAgICAgICAgc2VsZi5oYW5kbGUuc2VlayhvZmZzZXQpDQogICAgICAgICAgICByZXR1cm4gX3VubWFuZ2xlKHByZWZpeCkgKyBzZWxmLmhhbmRsZS5yZWFkKGxlbmd0aCAtIGxlbihwcmVmaXgpKQ0KDQogICAgIyBNb2RpZnkgYSBmaWxlIGluIGFyY2hpdmUgb3IgaW50ZXJuYWwgc3RvcmFnZS4NCiAgICBkZWYgY2hhbmdlKHNlbGYsIGZpbGVuYW1lLCBjb250ZW50cyk6DQogICAgICAgIGZpbGVuYW1lID0gX3VuaWNvZGUoZmlsZW5hbWUpDQoNCiAgICAgICAgIyBPdXIgJ2NoYW5nZScgaXMgYmFzaWNhbGx5IHJlbW92aW5nIHRoZSBmaWxlIGZyb20gb3VyIGluZGV4ZXMgZmlyc3QsIGFuZCB0aGVuIHJlLWFkZGluZyBpdC4NCiAgICAgICAgc2VsZi5yZW1vdmUoZmlsZW5hbWUpDQogICAgICAgIHNlbGYuYWRkKGZpbGVuYW1lLCBjb250ZW50cykNCg0KICAgICMgQWRkIGEgZmlsZSB0byB0aGUgaW50ZXJuYWwgc3RvcmFnZS4NCiAgICBkZWYgYWRkKHNlbGYsIGZpbGVuYW1lLCBjb250ZW50cyk6DQogICAgICAgIGZpbGVuYW1lID0gc2VsZi5jb252ZXJ0X2ZpbGVuYW1lKF91bmljb2RlKGZpbGVuYW1lKSkNCiAgICAgICAgaWYgZmlsZW5hbWUgaW4gc2VsZi5maWxlcyBvciBmaWxlbmFtZSBpbiBzZWxmLmluZGV4ZXM6DQogICAgICAgICAgICByYWlzZSBWYWx1ZUVycm9yKCdmaWxlIHswfSBhbHJlYWR5IGV4aXN0cyBpbiBhcmNoaXZlJy5mb3JtYXQoX3ByaW50YWJsZShmaWxlbmFtZSkpKQ0KDQogICAgICAgIHNlbGYudmVyYm9zZV9wcmludCgnQWRkaW5nIGZpbGUgezB9IHRvIGFyY2hpdmUuLi4gKGxlbmd0aCA9IHsxfSBieXRlcyknLmZvcm1hdCgNCiAgICAgICAgICAgIF9wcmludGFibGUoZmlsZW5hbWUpLCBsZW4oY29udGVudHMpKSkNCiAgICAgICAgc2VsZi5maWxlc1tmaWxlbmFtZV0gPSBjb250ZW50cw0KDQogICAgIyBSZW1vdmUgYSBmaWxlIGZyb20gYXJjaGl2ZSBvciBpbnRlcm5hbCBzdG9yYWdlLg0KICAgIGRlZiByZW1vdmUoc2VsZiwgZmlsZW5hbWUpOg0KICAgICAgICBmaWxlbmFtZSA9IF91bmljb2RlKGZpbGVuYW1lKQ0KICAgICAgICBpZiBmaWxlbmFtZSBpbiBzZWxmLmZpbGVzOg0KICAgICAgICAgICAgc2VsZi52ZXJib3NlX3ByaW50KCdSZW1vdmluZyBmaWxlIHswfSBmcm9tIGludGVybmFsIHN0b3JhZ2UuLi4nLmZvcm1hdChfcHJpbnRhYmxlKGZpbGVuYW1lKSkpDQogICAgICAgICAgICBkZWwgc2VsZi5maWxlc1tmaWxlbmFtZV0NCiAgICAgICAgZWxpZiBmaWxlbmFtZSBpbiBzZWxmLmluZGV4ZXM6DQogICAgICAgICAgICBzZWxmLnZlcmJvc2VfcHJpbnQoJ1JlbW92aW5nIGZpbGUgezB9IGZyb20gYXJjaGl2ZSBpbmRleGVzLi4uJy5mb3JtYXQoX3ByaW50YWJsZShmaWxlbmFtZSkpKQ0KICAgICAgICAgICAgZGVsIHNlbGYuaW5kZXhlc1tmaWxlbmFtZV0NCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIHJhaXNlIElPRXJyb3IoZXJybm8uRU5PRU5ULCAndGhlIHJlcXVlc3RlZCBmaWxlIHswfSBkb2VzIG5vdCBleGlzdCBpbiB0aGlzIGFyY2hpdmUnLmZvcm1hdChfcHJpbnRhYmxlKGZpbGVuYW1lKSkpDQoNCiAgICAjIExvYWQgYXJjaGl2ZS4NCiAgICBkZWYgbG9hZChzZWxmLCBmaWxlbmFtZSk6DQogICAgICAgIGZpbGVuYW1lID0gX3VuaWNvZGUoZmlsZW5hbWUpDQoNCiAgICAgICAgaWYgc2VsZi5oYW5kbGUgaXMgbm90IE5vbmU6DQogICAgICAgICAgICBzZWxmLmhhbmRsZS5jbG9zZSgpDQogICAgICAgIHNlbGYuZmlsZSA9IGZpbGVuYW1lDQogICAgICAgIHNlbGYuZmlsZXMgPSB7fQ0KICAgICAgICBzZWxmLmhhbmRsZSA9IG9wZW4oc2VsZi5maWxlLCAncmInKQ0KICAgICAgICBzZWxmLnZlcnNpb24gPSBzZWxmLmdldF92ZXJzaW9uKCkNCiAgICAgICAgc2VsZi5pbmRleGVzID0gc2VsZi5leHRyYWN0X2luZGV4ZXMoKQ0KDQogICAgIyBTYXZlIGN1cnJlbnQgc3RhdGUgaW50byBhIG5ldyBmaWxlLCBtZXJnaW5nIGFyY2hpdmUgYW5kIGludGVybmFsIHN0b3JhZ2UsIHJlYnVpbGRpbmcgaW5kZXhlcywgYW5kIG9wdGlvbmFsbHkgc2F2aW5nIGluIGFub3RoZXIgZm9ybWF0IHZlcnNpb24uDQogICAgZGVmIHNhdmUoc2VsZiwgZmlsZW5hbWUgPSBOb25lKToNCiAgICAgICAgZmlsZW5hbWUgPSBfdW5pY29kZShmaWxlbmFtZSkNCg0KICAgICAgICBpZiBmaWxlbmFtZSBpcyBOb25lOg0KICAgICAgICAgICAgZmlsZW5hbWUgPSBzZWxmLmZpbGUNCiAgICAgICAgaWYgZmlsZW5hbWUgaXMgTm9uZToNCiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ25vIHRhcmdldCBmaWxlIGZvdW5kIGZvciBzYXZpbmcgYXJjaGl2ZScpDQogICAgICAgIGlmIHNlbGYudmVyc2lvbiAhPSAyIGFuZCBzZWxmLnZlcnNpb24gIT0gMzoNCiAgICAgICAgICAgIHJhaXNlIFZhbHVlRXJyb3IoJ3NhdmluZyBpcyBvbmx5IHN1cHBvcnRlZCBmb3IgdmVyc2lvbiAyIGFuZCAzIGFyY2hpdmVzJykNCg0KICAgICAgICBzZWxmLnZlcmJvc2VfcHJpbnQoJ1JlYnVpbGRpbmcgYXJjaGl2ZSBpbmRleC4uLicpDQogICAgICAgICMgRmlsbCBvdXIgb3duIGZpbGVzIHN0cnVjdHVyZSB3aXRoIHRoZSBmaWxlcyBhZGRlZCBvciBjaGFuZ2VkIGluIHRoaXMgc2Vzc2lvbi4NCiAgICAgICAgZmlsZXMgPSBzZWxmLmZpbGVzDQogICAgICAgICMgRmlyc3QsIHJlYWQgZmlsZXMgZnJvbSB0aGUgY3VycmVudCBhcmNoaXZlIGludG8gb3VyIGZpbGVzIHN0cnVjdHVyZS4NCiAgICAgICAgZm9yIGZpbGUgaW4gbGlzdChzZWxmLmluZGV4ZXMua2V5cygpKToNCiAgICAgICAgICAgIGNvbnRlbnQgPSBzZWxmLnJlYWQoZmlsZSkNCiAgICAgICAgICAgICMgUmVtb3ZlIGZyb20gaW5kZXhlcyBhcnJheSBvbmNlIHJlYWQsIGFkZCB0byBvdXIgb3duIGFycmF5Lg0KICAgICAgICAgICAgZGVsIHNlbGYuaW5kZXhlc1tmaWxlXQ0KICAgICAgICAgICAgZmlsZXNbZmlsZV0gPSBjb250ZW50DQoNCiAgICAgICAgIyBQcmVkaWN0IGhlYWRlciBsZW5ndGgsIHdlJ2xsIHdyaXRlIHRoYXQgb25lIGxhc3QuDQogICAgICAgIG9mZnNldCA9IDANCiAgICAgICAgaWYgc2VsZi52ZXJzaW9uID09IDM6DQogICAgICAgICAgICBvZmZzZXQgPSAzNA0KICAgICAgICBlbGlmIHNlbGYudmVyc2lvbiA9PSAyOg0KICAgICAgICAgICAgb2Zmc2V0ID0gMjUNCiAgICAgICAgYXJjaGl2ZSA9IG9wZW4oZmlsZW5hbWUsICd3YicpDQogICAgICAgIGFyY2hpdmUuc2VlayhvZmZzZXQpDQoNCiAgICAgICAgIyBCdWlsZCBvdXIgb3duIGluZGV4ZXMgd2hpbGUgd3JpdGluZyBmaWxlcyB0byB0aGUgYXJjaGl2ZS4NCiAgICAgICAgaW5kZXhlcyA9IHt9DQogICAgICAgIHNlbGYudmVyYm9zZV9wcmludCgnV3JpdGluZyBmaWxlcyB0byBhcmNoaXZlIGZpbGUuLi4nKQ0KICAgICAgICBmb3IgZmlsZSwgY29udGVudCBpbiBmaWxlcy5pdGVtcygpOg0KICAgICAgICAgICAgIyBHZW5lcmF0ZSByYW5kb20gcGFkZGluZywgZm9yIHdoYXRldmVyIHJlYXNvbi4NCiAgICAgICAgICAgIGlmIHNlbGYucGFkbGVuZ3RoID4gMDoNCiAgICAgICAgICAgICAgICBwYWRkaW5nID0gc2VsZi5nZW5lcmF0ZV9wYWRkaW5nKCkNCiAgICAgICAgICAgICAgICBhcmNoaXZlLndyaXRlKHBhZGRpbmcpDQogICAgICAgICAgICAgICAgb2Zmc2V0ICs9IGxlbihwYWRkaW5nKQ0KDQogICAgICAgICAgICBhcmNoaXZlLndyaXRlKGNvbnRlbnQpDQogICAgICAgICAgICAjIFVwZGF0ZSBpbmRleC4NCiAgICAgICAgICAgIGlmIHNlbGYudmVyc2lvbiA9PSAzOg0KICAgICAgICAgICAgICAgIGluZGV4ZXNbZmlsZV0gPSBbIChvZmZzZXQgXiBzZWxmLmtleSwgbGVuKGNvbnRlbnQpIF4gc2VsZi5rZXkpIF0NCiAgICAgICAgICAgIGVsaWYgc2VsZi52ZXJzaW9uID09IDI6DQogICAgICAgICAgICAgICAgaW5kZXhlc1tmaWxlXSA9IFsgKG9mZnNldCwgbGVuKGNvbnRlbnQpKSBdDQogICAgICAgICAgICBvZmZzZXQgKz0gbGVuKGNvbnRlbnQpDQoNCiAgICAgICAgIyBXcml0ZSB0aGUgaW5kZXhlcy4NCiAgICAgICAgc2VsZi52ZXJib3NlX3ByaW50KCdXcml0aW5nIGFyY2hpdmUgaW5kZXggdG8gYXJjaGl2ZSBmaWxlLi4uJykNCiAgICAgICAgYXJjaGl2ZS53cml0ZShjb2RlY3MuZW5jb2RlKHBpY2tsZS5kdW1wcyhpbmRleGVzLCBzZWxmLlBJQ0tMRV9QUk9UT0NPTCksICd6bGliJykpDQogICAgICAgICMgTm93IHdyaXRlIHRoZSBoZWFkZXIuDQogICAgICAgIHNlbGYudmVyYm9zZV9wcmludCgnV3JpdGluZyBoZWFkZXIgdG8gYXJjaGl2ZSBmaWxlLi4uICh2ZXJzaW9uID0gUlBBdnswfSknLmZvcm1hdChzZWxmLnZlcnNpb24pKQ0KICAgICAgICBhcmNoaXZlLnNlZWsoMCkNCiAgICAgICAgaWYgc2VsZi52ZXJzaW9uID09IDM6DQogICAgICAgICAgICBhcmNoaXZlLndyaXRlKGNvZGVjcy5lbmNvZGUoJ3t9ezowMTZ4fSB7OjA4eH1cbicuZm9ybWF0KHNlbGYuUlBBM19NQUdJQywgb2Zmc2V0LCBzZWxmLmtleSkpKQ0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgYXJjaGl2ZS53cml0ZShjb2RlY3MuZW5jb2RlKCd7fXs6MDE2eH1cbicuZm9ybWF0KHNlbGYuUlBBMl9NQUdJQywgb2Zmc2V0KSkpDQogICAgICAgICMgV2UncmUgZG9uZSwgY2xvc2UgaXQuDQogICAgICAgIGFyY2hpdmUuY2xvc2UoKQ0KDQogICAgICAgICMgUmVsb2FkIHRoZSBmaWxlIGluIG91ciBpbm5lciBkYXRhYmFzZS4NCiAgICAgICAgc2VsZi5sb2FkKGZpbGVuYW1lKQ0KDQppZiBfX25hbWVfXyA9PSAiX19tYWluX18iOg0KICAgIGltcG9ydCBhcmdwYXJzZQ0KDQogICAgcGFyc2VyID0gYXJncGFyc2UuQXJndW1lbnRQYXJzZXIoDQogICAgICAgIGRlc2NyaXB0aW9uPSdBIHRvb2wgZm9yIHdvcmtpbmcgd2l0aCBSZW5cJ1B5IGFyY2hpdmUgZmlsZXMuJywNCiAgICAgICAgZXBpbG9nPSdUaGUgRklMRSBhcmd1bWVudCBjYW4gb3B0aW9uYWxseSBiZSBpbiBBUkNISVZFPVJFQUwgZm9ybWF0LCBtYXBwaW5nIGEgZmlsZSBpbiB0aGUgYXJjaGl2ZSBmaWxlIHN5c3RlbSB0byBhIGZpbGUgb24geW91ciByZWFsIGZpbGUgc3lzdGVtLiBBbiBleGFtcGxlIG9mIHRoaXM6IHJwYXRvb2wgLXggdGVzdC5ycGEgc2NyaXB0LnJweWM9L2hvbWUvZm9vL3Rlc3QucnB5YycsDQogICAgICAgIGFkZF9oZWxwPUZhbHNlKQ0KDQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnYXJjaGl2ZScsIG1ldGF2YXI9J0FSQ0hJVkUnLCBoZWxwPSdUaGUgUmVuXCdweSBhcmNoaXZlIGZpbGUgdG8gb3BlcmF0ZSBvbi4nKQ0KICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJ2ZpbGVzJywgbWV0YXZhcj0nRklMRScsIG5hcmdzPScqJywgYWN0aW9uPSdhcHBlbmQnLCBoZWxwPSdaZXJvIG9yIG1vcmUgZmlsZXMgdG8gb3BlcmF0ZSBvbi4nKQ0KDQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLWwnLCAnLS1saXN0JywgYWN0aW9uPSdzdG9yZV90cnVlJywgaGVscD0nTGlzdCBmaWxlcyBpbiBhcmNoaXZlIEFSQ0hJVkUuJykNCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCcteCcsICctLWV4dHJhY3QnLCBhY3Rpb249J3N0b3JlX3RydWUnLCBoZWxwPSdFeHRyYWN0IEZJTEVzIGZyb20gQVJDSElWRS4nKQ0KICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy1jJywgJy0tY3JlYXRlJywgYWN0aW9uPSdzdG9yZV90cnVlJywgaGVscD0nQ3JlYXRpdmUgQVJDSElWRSBmcm9tIEZJTEVzLicpDQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLWQnLCAnLS1kZWxldGUnLCBhY3Rpb249J3N0b3JlX3RydWUnLCBoZWxwPSdEZWxldGUgRklMRXMgZnJvbSBBUkNISVZFLicpDQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLWEnLCAnLS1hcHBlbmQnLCBhY3Rpb249J3N0b3JlX3RydWUnLCBoZWxwPSdBcHBlbmQgRklMRXMgdG8gQVJDSElWRS4nKQ0KDQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLTInLCAnLS10d28nLCBhY3Rpb249J3N0b3JlX3RydWUnLCBoZWxwPSdVc2UgdGhlIFJQQXYyIGZvcm1hdCBmb3IgY3JlYXRpbmcvYXBwZW5kaW5nIHRvIGFyY2hpdmVzLicpDQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLTMnLCAnLS10aHJlZScsIGFjdGlvbj0nc3RvcmVfdHJ1ZScsIGhlbHA9J1VzZSB0aGUgUlBBdjMgZm9ybWF0IGZvciBjcmVhdGluZy9hcHBlbmRpbmcgdG8gYXJjaGl2ZXMgKGRlZmF1bHQpLicpDQoNCiAgICBwYXJzZXIuYWRkX2FyZ3VtZW50KCctaycsICctLWtleScsIG1ldGF2YXI9J0tFWScsIGhlbHA9J1RoZSBvYmZ1c2NhdGlvbiBrZXkgdXNlZCBmb3IgY3JlYXRpbmcgUlBBdjMgYXJjaGl2ZXMsIGluIGhleGFkZWNpbWFsIChkZWZhdWx0OiAweERFQURCRUVGKS4nKQ0KICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy1wJywgJy0tcGFkZGluZycsIG1ldGF2YXI9J0NPVU5UJywgaGVscD0nVGhlIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIG9mIHBhZGRpbmcgdG8gYWRkIGJldHdlZW4gZmlsZXMgKGRlZmF1bHQ6IDApLicpDQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLW8nLCAnLS1vdXRmaWxlJywgaGVscD0nQW4gYWx0ZXJuYXRpdmUgb3V0cHV0IGFyY2hpdmUgZmlsZSB3aGVuIGFwcGVuZGluZyB0byBvciBkZWxldGluZyBmcm9tIGFyY2hpdmVzLCBvciBvdXRwdXQgZGlyZWN0b3J5IHdoZW4gZXh0cmFjdGluZy4nKQ0KDQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLWgnLCAnLS1oZWxwJywgYWN0aW9uPSdoZWxwJywgaGVscD0nUHJpbnQgdGhpcyBoZWxwIGFuZCBleGl0LicpDQogICAgcGFyc2VyLmFkZF9hcmd1bWVudCgnLXYnLCAnLS12ZXJib3NlJywgYWN0aW9uPSdzdG9yZV90cnVlJywgaGVscD0nQmUgYSBiaXQgbW9yZSB2ZXJib3NlIHdoaWxlIHBlcmZvcm1pbmcgb3BlcmF0aW9ucy4nKQ0KICAgIHBhcnNlci5hZGRfYXJndW1lbnQoJy1WJywgJy0tdmVyc2lvbicsIGFjdGlvbj0ndmVyc2lvbicsIHZlcnNpb249J3JwYXRvb2wgdjAuOCcsIGhlbHA9J1Nob3cgdmVyc2lvbiBpbmZvcm1hdGlvbi4nKQ0KICAgIGFyZ3VtZW50cyA9IHBhcnNlci5wYXJzZV9hcmdzKCkNCg0KICAgICMgRGV0ZXJtaW5lIFJQQSB2ZXJzaW9uLg0KICAgIGlmIGFyZ3VtZW50cy50d286DQogICAgICAgIHZlcnNpb24gPSAyDQogICAgZWxzZToNCiAgICAgICAgdmVyc2lvbiA9IDMNCg0KICAgICMgRGV0ZXJtaW5lIFJQQXYzIGtleS4NCiAgICBpZiAna2V5JyBpbiBhcmd1bWVudHMgYW5kIGFyZ3VtZW50cy5rZXkgaXMgbm90IE5vbmU6DQogICAgICAgIGtleSA9IGludChhcmd1bWVudHMua2V5LCAxNikNCiAgICBlbHNlOg0KICAgICAgICBrZXkgPSAweERFQURCRUVGDQoNCiAgICAjIERldGVybWluZSBwYWRkaW5nIGJ5dGVzLg0KICAgIGlmICdwYWRkaW5nJyBpbiBhcmd1bWVudHMgYW5kIGFyZ3VtZW50cy5wYWRkaW5nIGlzIG5vdCBOb25lOg0KICAgICAgICBwYWRkaW5nID0gaW50KGFyZ3VtZW50cy5wYWRkaW5nKQ0KICAgIGVsc2U6DQogICAgICAgIHBhZGRpbmcgPSAwDQoNCiAgICAjIERldGVybWluZSBvdXRwdXQgZmlsZS9kaXJlY3RvcnkgYW5kIGlucHV0IGFyY2hpdmUNCiAgICBpZiBhcmd1bWVudHMuY3JlYXRlOg0KICAgICAgICBhcmNoaXZlID0gTm9uZQ0KICAgICAgICBvdXRwdXQgPSBfdW5pY29kZShhcmd1bWVudHMuYXJjaGl2ZSkNCiAgICBlbHNlOg0KICAgICAgICBhcmNoaXZlID0gX3VuaWNvZGUoYXJndW1lbnRzLmFyY2hpdmUpDQogICAgICAgIGlmICdvdXRmaWxlJyBpbiBhcmd1bWVudHMgYW5kIGFyZ3VtZW50cy5vdXRmaWxlIGlzIG5vdCBOb25lOg0KICAgICAgICAgICAgb3V0cHV0ID0gX3VuaWNvZGUoYXJndW1lbnRzLm91dGZpbGUpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICAjIERlZmF1bHQgb3V0cHV0IGRpcmVjdG9yeSBmb3IgZXh0cmFjdGlvbiBpcyB0aGUgY3VycmVudCBkaXJlY3RvcnkuDQogICAgICAgICAgICBpZiBhcmd1bWVudHMuZXh0cmFjdDoNCiAgICAgICAgICAgICAgICBvdXRwdXQgPSAnLicNCiAgICAgICAgICAgIGVsc2U6DQogICAgICAgICAgICAgICAgb3V0cHV0ID0gX3VuaWNvZGUoYXJndW1lbnRzLmFyY2hpdmUpDQoNCiAgICAjIE5vcm1hbGl6ZSBmaWxlcy4NCiAgICBpZiBsZW4oYXJndW1lbnRzLmZpbGVzKSA+IDAgYW5kIGlzaW5zdGFuY2UoYXJndW1lbnRzLmZpbGVzWzBdLCBsaXN0KToNCiAgICAgICAgYXJndW1lbnRzLmZpbGVzID0gYXJndW1lbnRzLmZpbGVzWzBdDQoNCiAgICB0cnk6DQogICAgICAgIGFyY2hpdmUgPSBSZW5QeUFyY2hpdmUoYXJjaGl2ZSwgcGFkbGVuZ3RoPXBhZGRpbmcsIGtleT1rZXksIHZlcnNpb249dmVyc2lvbiwgdmVyYm9zZT1hcmd1bWVudHMudmVyYm9zZSkNCiAgICBleGNlcHQgSU9FcnJvciBhcyBlOg0KICAgICAgICBwcmludCgnQ291bGQgbm90IG9wZW4gYXJjaGl2ZSBmaWxlIHswfSBmb3IgcmVhZGluZzogezF9Jy5mb3JtYXQoYXJjaGl2ZSwgZSksIGZpbGU9c3lzLnN0ZGVycikNCiAgICAgICAgc3lzLmV4aXQoMSkNCg0KICAgIGlmIGFyZ3VtZW50cy5jcmVhdGUgb3IgYXJndW1lbnRzLmFwcGVuZDoNCiAgICAgICAgIyBXZSBuZWVkIHRoaXMgc2VwZXJhdGUgZnVuY3Rpb24gdG8gcmVjdXJzaXZlbHkgcHJvY2VzcyBkaXJlY3Rvcmllcy4NCiAgICAgICAgZGVmIGFkZF9maWxlKGZpbGVuYW1lKToNCiAgICAgICAgICAgICMgSWYgdGhlIGFyY2hpdmUgcGF0aCBkaWZmZXJzIGZyb20gdGhlIGFjdHVhbCBmaWxlIHBhdGgsIGFzIGdpdmVuIGluIHRoZSBhcmd1bWVudCwNCiAgICAgICAgICAgICMgZXh0cmFjdCB0aGUgYXJjaGl2ZSBwYXRoIGFuZCBhY3R1YWwgZmlsZSBwYXRoLg0KICAgICAgICAgICAgaWYgZmlsZW5hbWUuZmluZCgnPScpICE9IC0xOg0KICAgICAgICAgICAgICAgIChvdXRmaWxlLCBmaWxlbmFtZSkgPSBmaWxlbmFtZS5zcGxpdCgnPScsIDIpDQogICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgIG91dGZpbGUgPSBmaWxlbmFtZQ0KDQogICAgICAgICAgICBpZiBvcy5wYXRoLmlzZGlyKGZpbGVuYW1lKToNCiAgICAgICAgICAgICAgICBmb3IgZmlsZSBpbiBvcy5saXN0ZGlyKGZpbGVuYW1lKToNCiAgICAgICAgICAgICAgICAgICAgIyBXZSBuZWVkIHRvIGRvIHRoaXMgaW4gb3JkZXIgdG8gbWFpbnRhaW4gYSBwb3NzaWJsZSBBUkNISVZFPVJFQUwgbWFwcGluZyBiZXR3ZWVuIGRpcmVjdG9yaWVzLg0KICAgICAgICAgICAgICAgICAgICBhZGRfZmlsZShvdXRmaWxlICsgb3Muc2VwICsgZmlsZSArICc9JyArIGZpbGVuYW1lICsgb3Muc2VwICsgZmlsZSkNCiAgICAgICAgICAgIGVsc2U6DQogICAgICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgICAgICB3aXRoIG9wZW4oZmlsZW5hbWUsICdyYicpIGFzIGZpbGU6DQogICAgICAgICAgICAgICAgICAgICAgICBhcmNoaXZlLmFkZChvdXRmaWxlLCBmaWxlLnJlYWQoKSkNCiAgICAgICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6DQogICAgICAgICAgICAgICAgICAgIHByaW50KCdDb3VsZCBub3QgYWRkIGZpbGUgezB9IHRvIGFyY2hpdmU6IHsxfScuZm9ybWF0KGZpbGVuYW1lLCBlKSwgZmlsZT1zeXMuc3RkZXJyKQ0KDQogICAgICAgICMgSXRlcmF0ZSBvdmVyIHRoZSBnaXZlbiBmaWxlcyB0byBhZGQgdG8gYXJjaGl2ZS4NCiAgICAgICAgZm9yIGZpbGVuYW1lIGluIGFyZ3VtZW50cy5maWxlczoNCiAgICAgICAgICAgIGFkZF9maWxlKF91bmljb2RlKGZpbGVuYW1lKSkNCg0KICAgICAgICAjIFNldCB2ZXJzaW9uIGZvciBzYXZpbmcsIGFuZCBzYXZlLg0KICAgICAgICBhcmNoaXZlLnZlcnNpb24gPSB2ZXJzaW9uDQogICAgICAgIHRyeToNCiAgICAgICAgICAgIGFyY2hpdmUuc2F2ZShvdXRwdXQpDQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToNCiAgICAgICAgICAgIHByaW50KCdDb3VsZCBub3Qgc2F2ZSBhcmNoaXZlIGZpbGU6IHswfScuZm9ybWF0KGUpLCBmaWxlPXN5cy5zdGRlcnIpDQogICAgZWxpZiBhcmd1bWVudHMuZGVsZXRlOg0KICAgICAgICAjIEl0ZXJhdGUgb3ZlciB0aGUgZ2l2ZW4gZmlsZXMgdG8gZGVsZXRlIGZyb20gdGhlIGFyY2hpdmUuDQogICAgICAgIGZvciBmaWxlbmFtZSBpbiBhcmd1bWVudHMuZmlsZXM6DQogICAgICAgICAgICB0cnk6DQogICAgICAgICAgICAgICAgYXJjaGl2ZS5yZW1vdmUoZmlsZW5hbWUpDQogICAgICAgICAgICBleGNlcHQgRXhjZXB0aW9uIGFzIGU6DQogICAgICAgICAgICAgICAgcHJpbnQoJ0NvdWxkIG5vdCBkZWxldGUgZmlsZSB7MH0gZnJvbSBhcmNoaXZlOiB7MX0nLmZvcm1hdChmaWxlbmFtZSwgZSksIGZpbGU9c3lzLnN0ZGVycikNCg0KICAgICAgICAjIFNldCB2ZXJzaW9uIGZvciBzYXZpbmcsIGFuZCBzYXZlLg0KICAgICAgICBhcmNoaXZlLnZlcnNpb24gPSB2ZXJzaW9uDQogICAgICAgIHRyeToNCiAgICAgICAgICAgIGFyY2hpdmUuc2F2ZShvdXRwdXQpDQogICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToNCiAgICAgICAgICAgIHByaW50KCdDb3VsZCBub3Qgc2F2ZSBhcmNoaXZlIGZpbGU6IHswfScuZm9ybWF0KGUpLCBmaWxlPXN5cy5zdGRlcnIpDQogICAgZWxpZiBhcmd1bWVudHMuZXh0cmFjdDoNCiAgICAgICAgIyBFaXRoZXIgZXh0cmFjdCB0aGUgZ2l2ZW4gZmlsZXMsIG9yIGFsbCBmaWxlcyBpZiBubyBmaWxlcyBhcmUgZ2l2ZW4uDQogICAgICAgIGlmIGxlbihhcmd1bWVudHMuZmlsZXMpID4gMDoNCiAgICAgICAgICAgIGZpbGVzID0gYXJndW1lbnRzLmZpbGVzDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICBmaWxlcyA9IGFyY2hpdmUubGlzdCgpDQoNCiAgICAgICAgIyBDcmVhdGUgb3V0cHV0IGRpcmVjdG9yeSBpZiBub3QgcHJlc2VudC4NCiAgICAgICAgaWYgbm90IG9zLnBhdGguZXhpc3RzKG91dHB1dCk6DQogICAgICAgICAgICBvcy5tYWtlZGlycyhvdXRwdXQpDQoNCiAgICAgICAgIyBJdGVyYXRlIG92ZXIgZmlsZXMgdG8gZXh0cmFjdC4NCiAgICAgICAgZm9yIGZpbGVuYW1lIGluIGZpbGVzOg0KICAgICAgICAgICAgaWYgZmlsZW5hbWUuZmluZCgnPScpICE9IC0xOg0KICAgICAgICAgICAgICAgIChvdXRmaWxlLCBmaWxlbmFtZSkgPSBmaWxlbmFtZS5zcGxpdCgnPScsIDIpDQogICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgIG91dGZpbGUgPSBmaWxlbmFtZQ0KDQogICAgICAgICAgICB0cnk6DQogICAgICAgICAgICAgICAgY29udGVudHMgPSBhcmNoaXZlLnJlYWQoZmlsZW5hbWUpDQoNCiAgICAgICAgICAgICAgICAjIENyZWF0ZSBvdXRwdXQgZGlyZWN0b3J5IGZvciBmaWxlIGlmIG5vdCBwcmVzZW50Lg0KICAgICAgICAgICAgICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhvcy5wYXRoLmRpcm5hbWUob3MucGF0aC5qb2luKG91dHB1dCwgb3V0ZmlsZSkpKToNCiAgICAgICAgICAgICAgICAgICAgb3MubWFrZWRpcnMob3MucGF0aC5kaXJuYW1lKG9zLnBhdGguam9pbihvdXRwdXQsIG91dGZpbGUpKSkNCg0KICAgICAgICAgICAgICAgIHdpdGggb3Blbihvcy5wYXRoLmpvaW4ob3V0cHV0LCBvdXRmaWxlKSwgJ3diJykgYXMgZmlsZToNCiAgICAgICAgICAgICAgICAgICAgZmlsZS53cml0ZShjb250ZW50cykNCiAgICAgICAgICAgIGV4Y2VwdCBFeGNlcHRpb24gYXMgZToNCiAgICAgICAgICAgICAgICBwcmludCgnQ291bGQgbm90IGV4dHJhY3QgZmlsZSB7MH0gZnJvbSBhcmNoaXZlOiB7MX0nLmZvcm1hdChmaWxlbmFtZSwgZSksIGZpbGU9c3lzLnN0ZGVycikNCiAgICBlbGlmIGFyZ3VtZW50cy5saXN0Og0KICAgICAgICAjIFByaW50IHRoZSBzb3J0ZWQgZmlsZSBsaXN0Lg0KICAgICAgICBsaXN0ID0gYXJjaGl2ZS5saXN0KCkNCiAgICAgICAgbGlzdC5zb3J0KCkNCiAgICAgICAgZm9yIGZpbGUgaW4gbGlzdDoNCiAgICAgICAgICAgIHByaW50KGZpbGUpDQogICAgZWxzZToNCiAgICAgICAgcHJpbnQoJ05vIG9wZXJhdGlvbiBnaXZlbiA6KCcpDQogICAgICAgIHByaW50KCdVc2UgezB9IC0taGVscCBmb3IgdXNhZ2UgZGV0YWlscy4nLmZvcm1hdChzeXMuYXJndlswXSkpDQo=" base64 --decode <<< "$rpatool" > /tmp/rpatool.py } init