From 827a3676f7e8b7fb8fe1296d4825820547d5b49c Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Tue, 28 May 2019 10:10:56 -0700 Subject: [PATCH] Minor MeshCMD help fix. --- agents/MeshCmd-signed.exe | Bin 5164384 -> 5174040 bytes agents/MeshCmd64-signed.exe | Bin 5140832 -> 5150488 bytes agents/meshcmd.js | 5 +- agents/meshcmd.min.js | 2 +- public/commander.htm | 1662 +++++++++++----------- public/scripts/amt-desktop-0.0.2-slow.js | 834 +++++++++++ public/scripts/amt-desktop-0.0.2.js | 151 +- sample-config.json | 1 + 8 files changed, 1776 insertions(+), 879 deletions(-) create mode 100644 public/scripts/amt-desktop-0.0.2-slow.js diff --git a/agents/MeshCmd-signed.exe b/agents/MeshCmd-signed.exe index 95b1acd1e1be3b9afde9a78f21cc6fb09b14fef0..f2b8fc73584e91b0a8c699f59dbbe5ee565f9f1c 100644 GIT binary patch delta 8148 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 HG{^l9<0pcf diff --git a/agents/MeshCmd64-signed.exe b/agents/MeshCmd64-signed.exe index 76b52f39366c01d5f5d698167a297b1758f108d3..209cf3f8ea3198f193595596c5265de694838ade 100644 GIT binary patch delta 8149 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.log(b)}}function exit(b){if(b==null){b=0}try{process.exit(b)}catch(a){}}function getInstance(b,c){for(var a in b){if(b[a]["InstanceID"]==c){return b[a]}}return null}function md5hex(a){return require("MD5Stream").create().syncHash(a).toString("hex")}function guidToStr(a){return a.substring(6,8)+a.substring(4,6)+a.substring(2,4)+a.substring(0,2)+"-"+a.substring(10,12)+a.substring(8,10)+"-"+a.substring(14,16)+a.substring(12,14)+"-"+a.substring(16,20)+"-"+a.substring(20)}function parceArguments(a){var d={};for(var b in a){b=parseInt(b);if(a[b].startsWith("--")==true){var c=a[b].substring(2).toLowerCase(),e=true;if(((b+1)8){return"[...]"}if(e==undefined){return"[undefined]"}if(typeof e=="string"){if(b==0){return e}return'"'+(e.split("\0")[0])+'"'}if(typeof e=="buffer"){return"[buffer]"}if(typeof e!="object"){return e}var c="{"+(d?"\r\n":" ");for(var a in e){if(a!="_ObjectID"){c+=(addPad(b+2,d)+a+": "+objToString(e[a],b+2,d)+(d?"\r\n":" "))}}return c+addPad(b,d)+"}"}function addPad(b,d){var c="";for(var a=0;a=2){settings={action:j[1]}}}if(settings==null){settings={}}var p={};for(var m in settings){p[m.toLowerCase()]=settings[m]}settings=p;if((typeof h.action)=="string"){settings.action=h.action}if((typeof h.localport)=="string"){settings.localport=parseInt(h.localport)}if((typeof h.remotenodeid)=="string"){settings.remotenodeid=h.remotenodeid}if((typeof h.username)=="string"){settings.username=h.username}if((typeof h.password)=="string"){settings.password=h.password}if((typeof h.user)=="string"){settings.username=h.user}if((typeof h.pass)=="string"){settings.password=h.pass}if((typeof h.host)=="string"){settings.hostname=h.host}if((typeof h.hostname)=="string"){settings.hostname=h.hostname}if((typeof h.serverid)=="string"){settings.serverid=h.serverid}if((typeof h.serverhttpshash)=="string"){settings.serverhttpshash=h.serverhttpshash}if((typeof h.remoteport)=="string"){settings.remoteport=parseInt(h.remoteport)}if((typeof h.out)=="string"){settings.output=h.out}if((typeof h.output)=="string"){settings.output=h.output}if((typeof h.debug)=="string"){settings.debuglevel=parseInt(h.debug)}if((typeof h.debugflags)=="string"){globalDebugFlags=parseInt(h.debugflags)}if((typeof h.script)=="string"){settings.script=h.script}if((typeof h.agent)=="string"){settings.agent=h.agent}if((typeof h.proxy)=="string"){settings.proxy=h.proxy}if(h.debug){try{waitForDebugger()}catch(k){}}if(h.noconsole){settings.noconsole=true}if(h.nocommander){settings.noconsole=true}if(h.lmsdebug){settings.lmsdebug=true}if(h.tls){settings.tls=true}if((j.length>1)&&(d.indexOf(j[1].toUpperCase())>=0)){settings.action=j[1]}if(settings.action==null){console.log("MeshCentral Command (MeshCmd) "+meshCmdVersion);console.log("No action specified, use MeshCmd like this:\r\n");console.log(" meshcmd [action] [arguments...]\r\n");console.log("Valid MeshCentral actions:");console.log(" Route - Map a local TCP port to a remote computer.");console.log("\r\nValid local actions:");console.log(" SMBios - Display System Management BIOS tables for this computer.");console.log(" RawSMBios - Display RAW System Management BIOS tables for this computer.");console.log(" MicroLMS - Run MicroLMS, allowing local access to Intel AMT.");console.log(" AmtInfo - Show Intel AMT version and activation state.");console.log(" AmtVersions - Show all Intel ME version information.");console.log(" AmtHashes - Show all Intel AMT trusted activation hashes.");console.log(" AmtCCM - Activate Intel AMT into Client Control Mode.");console.log(" AmtDeactivate - Deactivate Intel AMT if activated in Client Control mode.");console.log("\r\nValid local or remote actions:");console.log(" MeshCommander - Launch a local MeshCommander web server.");console.log(" AmtUUID - Show Intel AMT unique identifier.");console.log(" AmtAuditLog - Show the Intel AMT audit log.");console.log(" AmtLoadWebApp - Load MeshCommander in Intel AMT 11.6+ firmware.");console.log(" AmtClearWebApp - Clear everything from Intel AMT web storage.");console.log(" AmtStorageState - Show contents of the Intel AMT web storage.");console.log(" AmtSaveState - Save all Intel AMT WSMAN object to file.");console.log(" AmtPresence - Heartbeat a local Intel AMT watchdog agent.");console.log(" AmtScript - Run .mescript on Intel AMT.");console.log("\r\nHelp on a specific action using:\r\n");console.log(" meshcmd help [action]");exit(1);return}if(settings.action=="help"){if(j.length<=2){d.shift();console.log("Help usage:\r\n\r\n MeshCmd help [action]\r\n\r\nValid actions are: "+d.join(", ")+".");exit(1);return}var a=j[2].toLowerCase();if(a=="route"){console.log("The route action is used along with a MeshCentral account to map a local TCP port to a remote port on any computer on your MeshCentral account. This action requires many arguments, to avoid specifying them all it's best to download the meshaction.txt file from the web site and place it in the current folder. Example usage:\r\n\r\n (Place meshaction.txt file in current folder)\r\n meshcmd route --pass myAccountPassword")}else{if(a=="smbios"){console.log("SMBios action will display this computer's system management BIOS information. Example usage:\r\n\r\n meshcmd smbios --out smbios.txt\r\n");console.log("\rOptional arguments:\r\n");console.log(" --output [filename] Optional filename to write the results to.")}else{if(a=="rawsmbios"){console.log("RawSMBios action will display this computer's system management BIOS information in raw hexdecimal form. Example usage:\r\n\r\n meshcmd rawsmbios --out smbios.txt\r\n");console.log("\rOptional arguments:\r\n");console.log(" --output [filename] Optional filename to write the results to.")}else{if(a=="amtinfo"){console.log("AmtInfo action will get the version and activation state of Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Example usage:\r\n\r\n meshcmd amtinfo")}else{if((a=="amtversion")||(a=="amtversions")){console.log("AmtVersions will display all version information about Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Example usage:\r\n\r\n meshcmd amtversions")}else{if(a=="amthashes"){console.log("Amthashes will display all trusted activations hashes for Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd amthashes")}else{if((a=="microlms")||(a=="lms")||(a=="amtlms")){console.log("Starts MicroLMS on this computer, allowing local access to Intel AMT on TCP ports 16992 and 16993 when applicable. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd microlms");console.log("\r\nPossible arguments:\r\n");console.log(" --noconsole MeshCommander for LMS will no be available on port 16994.");console.log("\r\nRun as a background service:\r\n");console.log(" microlms install/uninstall/start/stop.")}else{if(a=="amtccm"){console.log('AmtCCM will attempt to activate Intel AMT on this computer into client control mode (CCM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be in "pre-provisioning" state for this command to work and a administrator password must be provided. Example usage:\r\n\r\n meshcmd amtccm --pass mypassword')}else{if(a=="amtdeactivate"){console.log("AmtDeactivate will attempt to deactivate Intel AMT on this computer when in client control mode (CCM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be activated in client control mode for this command to work. Example usage:\r\n\r\n meshcmd amtdeactivate")}else{if(a=="amtuuid"){console.log("AmtUUID action will get the unique identifier of the local or remote Intel AMT computer. By default, the local UUID is obtained unless a host is specified. Intel AMT must be activated for this command to work. Example usage:\r\n\r\n meshcmd amtuuid --host 1.2.3.4 --user admin --pass mypassword --tls");console.log("\r\nPossible arguments:\r\n");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{if((a=="amtloadwebapp")||(a=="amtloadsmallwebapp")||(a=="amtloadlargewebapp")||(a=="amtclearwebapp")||(a=="amtstoragestate")){console.log('AmtLoadWebApp action will load MeshCommander into Intel AMT 11.6 or higher. If the computer is in ACM mode, MeshCommander will replace the default index.htm on HTTP/16992 or HTTPS/16993. If Intel AMT is in CCM mode, MeshCommander will be installed alongside the default web page and will be accessible in the "Web Applications" section. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtloadwebapp --host 1.2.3.4 --user admin --pass mypassword --tls');console.log("\r\nPossible arguments:\r\n");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{if(a=="amtclearwebstorage"){console.log("AmtClearWebStorage will clear the web storage of Intel AMT, removing any loaded firmware version of MeshCommander. This command can clear the local or a remote Intel AMT computer. By default, the local computer storage is cleared unless a host is specified. Intel AMT must be activated for this command to work. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtclearwebstorage --host 1.2.3.4 --user admin --pass mypassword --tls");console.log("\r\nPossible arguments:\r\n");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{if(a=="amtstoragestate"){console.log("AmtStorageState will display the content of the web storage of Intel AMT including any loaded firmware version of MeshCommander. This command can read the storage state of a local or remote Intel AMT computer. By default, the local computer storage state is displayed unless a host is specified. Intel AMT must be activated for this command to work. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtstoragestate --host 1.2.3.4 --user admin --pass mypassword --tls");console.log("\r\nPossible arguments:\r\n");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{if(a=="amtsavestate"){console.log("AmtSaveState action will fetch all the entire state of Intel AMT and save it as a JSON file. This action will take multiple minutes to perform. The command will fetch the local computer state unless host is specified. Intel AMT must be ativated for this command to work. Example usage:\r\n\r\n meshcmd amtsavestate --host 1.2.3.4 --user admin --pass mypassword --tls --output state.json");console.log("\r\nPossible arguments:\r\n");console.log(" --output [filename] The output file for the Intel AMT state in JSON format.");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{if(a=="amtpresence"){console.log("AmtPresence will heartbeat a local Intel AMT watchdog agent. Example usage:\r\n\r\n meshcmd amtpresence --agent B4B6A24C-255E-A75C-F5E8-B00B4D946AA7");console.log("\r\nPossible arguments:\r\n");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --agent [uuid] The unique identifier of the watchdog agent.")}else{if(a=="amtscript"){console.log("AmtScript will run a .mescript file on the local or remote Intel AMT. Script files can be built using the MeshCommander script editor and be used to setup or perform actions on Intel AMT. Example usage:\r\n\r\n meshcmd amtscript --script myscript.mescript --host 1.2.3.4 --user admin --pass mypassword --tls");console.log("\r\nPossible arguments:\r\n");console.log(" --script [filename] The script file to run on Intel AMT.");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{if(a=="meshcommander"){console.log("This action launched a local web server that hosts MeshCommander, a Intel AMT management console.");console.log("\r\nPossible arguments:\r\n");console.log(" --localport [port] Local port used for the web server, 3000 is default.");console.log("\r\nRun as a background service:\r\n");console.log(" meshcommander install/uninstall/start/stop.")}else{if(a=="amtauditlog"){console.log("AmtAuditLog action will fetch the local or remote audit log. If used localy, no username/password is required. Example usage:\r\n\r\n meshcmd amtauditlog --host 1.2.3.4 --user admin --pass mypassword --tls --output audit.json");console.log("\r\nPossible arguments:\r\n");console.log(" --output [filename] The output file for the Intel AMT state in JSON format.");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{d.shift();console.log("Invalid action, usage:\r\n\r\n meshcmd help [action]\r\n\r\nValid actions are: "+d.join(", ")+".")}}}}}}}}}}}}}}}}}}exit(1);return}settings.action=settings.action.toLowerCase();debug(1,"Settings: "+JSON.stringify(settings));if((typeof settings.proxy)=="string"){var n=settings.proxy.split(":"),o=(n.length==2)?parseInt(n[1]):0;if((n.length!=2)||(n[0].length<1)||(o<1)||(o>65535)){console.log('Invalid "proxy" specified, use --proxy [hostname]:[port].');exit(1);return}try{require("global-tunnel").initialize({host:n[0],port:o})}catch(l){console.log(l);exit(1);return}console.log("Proxy set to "+n[0]+":"+o)}if(settings.action=="smbios"){SMBiosTables=require("smbios");SMBiosTables.get(function(e){var t=SMBiosTables.parse(e);var s=objToString(t,0,"\r\n");if(settings.output==null){console.log(s)}else{var q=fs.openSync(settings.output,"w");fs.writeSync(q,Buffer.from(s,"utf8"));fs.closeSync(q)}exit(1)})}else{if(settings.action=="rawsmbios"){SMBiosTables=require("smbios");SMBiosTables.get(function(e){var u="";for(var s in e){var r=false;for(var t in e[s]){if(e[s][t].length>0){if(r==false){u+=("Table type #"+s+((SMBiosTables.smTableTypes[s]==null)?"":(", "+SMBiosTables.smTableTypes[s])))+"\r\n";r=true}u+=(" "+e[s][t].toString("hex"))+"\r\n"}}}if(settings.output==null){console.log(u)}else{var q=fs.openSync(settings.output,"w");fs.writeSync(q,Buffer.from(u,"utf8"));fs.closeSync(q)}exit(1)})}else{if(settings.action=="route"){if((settings.localport==null)||(typeof settings.localport!="number")||(settings.localport<0)||(settings.localport>65535)){console.log('No or invalid "localPort" specified, use --localport [localport].');exit(1);return}if((settings.remotenodeid==null)||(typeof settings.remotenodeid!="string")){console.log('No or invalid "remoteNodeId" specified.');exit(1);return}if((settings.username==null)||(typeof settings.username!="string")||(settings.username=="")){console.log('No or invalid "username" specified, use --username [username].');exit(1);return}if((settings.password==null)||(typeof settings.password!="string")||(settings.password=="")){console.log('No or invalid "password" specified, use --password [password].');exit(1);return}if((settings.serverid==null)||(typeof settings.serverid!="string")||(settings.serverid.length!=96)){console.log('No or invalid "serverId" specified.');exit(1);return}if((settings.serverhttpshash==null)||(typeof settings.serverhttpshash!="string")||(settings.serverhttpshash.length!=96)){console.log('No or invalid "serverHttpsHash" specified.');exit(1);return}if((settings.remoteport==null)||(typeof settings.remoteport!="number")||(settings.remoteport<0)||(settings.remoteport>65535)){console.log('No or invalid "remotePort" specified, use --remoteport [remoteport].');exit(1);return}if(settings.serverurl!=null){startRouter()}else{discoverMeshServer()}}else{if((settings.action=="amtloadwebapp")||(settings.action=="amtloadsmallwebapp")||(settings.action=="amtloadlargewebapp")||(settings.action=="amtclearwebapp")||(settings.action=="amtstoragestate")){if((settings.password==null)||(typeof settings.password!="string")||(settings.password=="")){console.log('No or invalid "password" specified, use --password [password].');exit(1);return}if((settings.hostname==null)||(typeof settings.hostname!="string")||(settings.hostname=="")){settings.hostname="127.0.0.1"}if((settings.username==null)||(typeof settings.username!="string")||(settings.username=="")){settings.username="admin"}settings.protocol="http:";settings.localport=16992;debug(1,"Settings: "+JSON.stringify(settings));digest=require("http-digest").create(settings.username,settings.password);digest.http=require("http");if(settings.action=="amtstoragestate"){getAmtStorage(function(q,e){if(q==200){console.log("Storage State: "+JSON.stringify(e,null,2));exit();return}else{console.log("Unable to read storage state.");exit();return}})}else{if(settings.action=="amtloadwebapp"){settings.webapp=Medium_IntelAmtWebApp}else{if(settings.action=="amtloadsmallwebapp"){settings.webapp=Small_IntelAmtWebApp}else{if(settings.action=="amtloadlargewebapp"){settings.webapp=Large_IntelAmtWebApp}else{if(settings.action=="amtclearwebapp"){settings.webapp=null}}}}nextStepStorageUpload()}}else{if((settings.action=="amtversion")||(settings.action=="amtversions")||(settings.action=="amtver")){var g,f;try{g=require("amt-mei");f=new g()}catch(l){console.log(l);exit(1);return}f.on("error",function(q){console.log("ERROR: "+q);exit(1);return});f.getVersion(function(e){console.log("MEI Version = "+e.BiosVersion.toString());for(var q in e.Versions){console.log(e.Versions[q].Description+" = "+e.Versions[q].Version)}exit(1);return})}else{if(settings.action=="amthashes"){var g,f;try{g=require("amt-mei");f=new g()}catch(l){console.log(l);exit(1);return}f.on("error",function(q){console.log("ERROR: "+q);exit(1);return});f.getHashHandles(function(e){exitOnCount=e.length;for(var q=0;q100){lmsNotifications.shift()}var l=Buffer.concat([Buffer.from("0900","hex"),Buffer.from(JSON.stringify(k))]);for(var j in lmsControlSockets){lmsControlSockets[j].write(l)}}}});amtLms.on("bind",function(g){if(g[16992]){this.removeAllListeners("bind")}else{return}amtLms.connected=true;this.promise._res();if(settings.noconsole!==true){startMeshCommanderLms();tempTimer=setTimeout(function(){delete tempTimer;setupMeiOsAdmin(b,2)},100)}else{tempTimer=setTimeout(function(){delete tempTimer;setupMeiOsAdmin(b,1)},100)}});return(f)}function startMeshCommanderLms(){var b="C2ZfnIbUEl7w4c1S1Xbd";var a="77u/PCFET0NUWVBFIGh0bWw+DQo8aHRtbCBzdHlsZT0iaGVpZ2h0OjEwMCUiPg0KPGhlYWQ+DQogICAgPG1ldGEgaHR0cC1lcXVpdj0iWC1VQS1Db21wYXRpYmxlIiBjb250ZW50PSJJRT1lZGdlIj4gDQogICAgPG1ldGEgY29udGVudD0idGV4dC9odG1sO2NoYXJzZXQ9dXRmLTgiIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSI+DQogICAgPG1ldGEgbmFtZT0iZm9ybWF0LWRldGVjdGlvbiIgY29udGVudD0idGVsZXBob25lPW5vIj4NCiAgICA8bGluayByZWw9Imljb24iIHR5cGU9ImltYWdlL3BuZyIgaHJlZj0iZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvPSI+IDwhLS0gU3RvcCBmYXZpY29uLmljbyBmcm9tIGxvYWRpbmcgLS0+DQogICAgPHN0eWxlPmJvZHkgew0KICAgIGhlaWdodDogMTAwJTsNCiAgICBtYXgtaGVpZ2h0OiAxMDAlOw0KICAgIG92ZXJmbG93OiBoaWRkZW47DQogICAgZm9udC1mYW1pbHk6IGFyaWFsLCBoZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQogICAgZm9udC1zaXplOiA5cHQ7DQogICAgY29sb3I6IGJsYWNrOw0KICAgIGJhY2tncm91bmQ6IHdoaXRlOw0KICAgIG1hcmdpbi10b3A6IDA7DQogICAgbWFyZ2luLWxlZnQ6IDA7DQogICAgbWFyZ2luLXJpZ2h0OiAwOw0KICAgIC13ZWJraXQtdG91Y2gtY2FsbG91dDogbm9uZTsNCiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lOw0KICAgIC1raHRtbC11c2VyLXNlbGVjdDogbm9uZTsNCiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lOw0KICAgIC1tcy11c2VyLXNlbGVjdDogbm9uZTsNCiAgICB1c2VyLXNlbGVjdDogbm9uZTsNCn0NCg0KbGkgew0KICAgIG1hcmdpbjogMDsNCiAgICBwYWRkaW5nOiAwOw0KfQ0KDQpsYWJlbCB7DQogICAgZGlzcGxheTogYmxvY2s7DQogICAgY29sb3I6IHdpbmRvd3RleHQ7DQogICAgYmFja2dyb3VuZC1jb2xvcjogd2luZG93Ow0KICAgIG1hcmdpbjogMDsNCiAgICBwYWRkaW5nOiAwOw0KICAgIHdpZHRoOiAxMDAlOw0KfQ0KDQogICAgbGFiZWw6aG92ZXIgew0KICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBoaWdobGlnaHQ7DQogICAgICAgIGNvbG9yOiBoaWdobGlnaHR0ZXh0Ow0KICAgIH0NCg0KYTp2aXNpdGVkIHsNCiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7DQogICAgY29sb3I6ICMwNGY7DQp9DQoNCmE6bGluayB7DQogICAgdGV4dC1kZWNvcmF0aW9uOiBub25lOw0KICAgIGNvbG9yOiAjMDRmOw0KfQ0KDQphOmhvdmVyIHsNCiAgICBjb2xvcjogIzU1NTsNCn0NCg0KaDEgew0KICAgIGZvbnQtc2l6ZTogMTFwdDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBjb2xvcjogYmxhY2s7DQogICAgbWFyZ2luLWxlZnQ6IDVweDsNCiAgICBtYXJnaW4tdG9wOiAxMHB4Ow0KICAgIG1hcmdpbi1ib3R0b206IDZweDsNCn0NCg0KaDIgew0KICAgIGZvbnQtc2l6ZTogOXB0Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGNvbG9yOiBibGFjazsNCiAgICBtYXJnaW4tbGVmdDogNnB4Ow0KICAgIG1hcmdpbi10b3A6IDZweDsNCiAgICBtYXJnaW4tYm90dG9tOiAwOw0KfQ0KDQpwIHsNCiAgICBtYXJnaW4tbGVmdDogNnB4Ow0KICAgIG1hcmdpbi10b3A6IDRweDsNCiAgICBtYXJnaW4tYm90dG9tOiAwOw0KICAgIG1hcmdpbi1yaWdodDogMnB4Ow0KfQ0KDQp0ZCB7DQogICAgZm9udC1zaXplOiA5cHQ7DQp9DQoNCnRoIHsNCiAgICBmb250LXNpemU6IDlwdDsNCn0NCg0KICAgIHRoOmhvdmVyIHsNCiAgICAgICAgY3Vyc29yOiBwb2ludGVyOw0KICAgICAgICBiYWNrZ3JvdW5kOiAjYWFhOw0KICAgIH0NCg0KLmhlYWRlciB7DQogICAgcG9zaXRpb246IGZpeGVkOw0KICAgIHRvcDogMDsNCiAgICBsZWZ0OiAwOw0KICAgIHJpZ2h0OiAwOw0KICAgIGhlaWdodDogNjdweDsNCiAgICBiYWNrZ3JvdW5kOiAjMDM2Ow0KICAgIC8qIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICM2YTY5NjAgMCUsIzQyNDEzYyAxMDAlKTsgKi8NCn0NCg0KLnByb2dyZXNzYmFyIHsNCiAgICBwb3NpdGlvbjogZml4ZWQ7DQogICAgdG9wOiA2N3B4Ow0KICAgIGxlZnQ6IDA7DQogICAgcmlnaHQ6IDA7DQogICAgaGVpZ2h0OiAycHg7DQogICAgYmFja2dyb3VuZDogIzAzNjsNCn0NCg0KLmluIHsNCiAgICBtYXJnaW4tbGVmdDogNDBweDsNCn0NCg0KLmxvZyB7DQogICAgYmFja2dyb3VuZDogI2JiYmFiNTsNCn0NCg0KLmxvZzEgew0KICAgIGJhY2tncm91bmQ6ICNiYmJhYjU7DQp9DQoNCi5sb2cgdGJvZHkgdHI6bnRoLWNoaWxkKG9kZCkgew0KICAgIGJhY2tncm91bmQ6ICNlOGVlZmU7DQp9DQoNCi5mdWxsY2VsbCB7DQogICAgcG9zaXRpb246IGZpeGVkOw0KICAgIHRvcDogNjlweDsNCiAgICByaWdodDogMDsNCiAgICBib3R0b206IDA7DQogICAgbGVmdDogMHB4Ow0KICAgIG92ZXJmbG93OiBoaWRkZW47DQp9DQoNCi5tYWluY2VsbCB7DQogICAgcG9zaXRpb246IGZpeGVkOw0KICAgIHRvcDogNjlweDsNCiAgICByaWdodDogMDsNCiAgICBib3R0b206IDA7DQogICAgbGVmdDogMTU2cHg7DQogICAgb3ZlcmZsb3c6IGhpZGRlbjsNCiAgICBwYWRkaW5nLWxlZnQ6IDJweDsNCiAgICB2ZXJ0aWNhbC1hbGlnbjogdG9wOw0KfQ0KDQoubmF2YmFyIHsNCiAgICBwb3NpdGlvbjogZml4ZWQ7DQogICAgdG9wOiA2OXB4Ow0KICAgIGxlZnQ6IDA7DQogICAgYm90dG9tOiAwOw0KICAgIHdpZHRoOiAxNTZweDsNCiAgICBib3JkZXItcmlnaHQ6IDJweCBzb2xpZCAjQjBDNkZDOw0KICAgIHZlcnRpY2FsLWFsaWduOiB0b3A7DQogICAgYmFja2dyb3VuZDogIzAzNjsNCiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQodG8gYm90dG9tLCAjYmZkMWZjIDAlLCNlOGVlZmUgMTAwJSk7DQp9DQoNCi5uYXYxIHsNCiAgICBwYWRkaW5nOiAxcHggMHB4IDFweCA4cHg7DQogICAgbWFyZ2luOiAwcHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgY29sb3I6IGJsYWNrOw0KICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KfQ0KDQoubmF2MiB7DQogICAgbWFyZ2luLWxlZnQ6IDMycHg7DQogICAgbWFyZ2luLXRvcDogMDsNCiAgICBjb2xvcjogYmxhY2s7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KfQ0KDQouciB7DQogICAgZm9udC1zaXplOiAxMXB0Ow0KfQ0KDQoucjAgew0KICAgIGJhY2tncm91bmQ6IHdoaXRlOw0KfQ0KDQoucjEgew0KICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCBncmF5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCi5yMiB7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLnIzIHsNCiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgZ3JheTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQogICAgLnIzOmhvdmVyIHsNCiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogIzgzODI3YjsNCiAgICAgICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIH0NCg0KLnNwcmVhZCB7DQogICAgaGVpZ2h0OiAxMDAlOw0KICAgIHdpZHRoOiAxMDAlOw0KICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlOw0KfQ0KDQoudGltZXIgew0KICAgIGJvcmRlcjogMXB4IHNvbGlkICNhYmNhZTE7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI2FiY2FlMTsNCn0NCg0KLnRtIHsNCiAgICBmb250LXNpemU6IDdwdDsNCn0NCg0KLnRvcDEgew0KICAgIGZvbnQtc2l6ZTogMjBwdDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBjb2xvcjogI0M4QzhDODsNCiAgICBtYXJnaW4tdG9wOiA2cHg7DQogICAgbWFyZ2luLWxlZnQ6IDEwcHg7DQp9DQoNCi50b3AyIHsNCiAgICBjb2xvcjogI0M4QzhDODsNCiAgICBtYXJnaW4tbGVmdDogMTBweDsNCn0NCg0KLndhcm4gew0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGNvbG9yOiAjYzAwMDAwOw0KfQ0KDQouaWNvbjEgew0KICAgIHdpZHRoOiAxNHB4Ow0KICAgIGhlaWdodDogMTVweDsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybCgiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoRUFBUUFMTVBBTEMyeXg5RHIwbHkyV3VSOEZkdXVoUXlsb09XenpkZ3ltNkd5WnVxMS92NytxQ2hwY2pKMEplWG03ZTV2di8vL3lINUJBRUFBQThBTEFBQUFBQVFBQkFBQUFSeThNbEpxMTJPTWJlc2JFQXlqRU1DTkJWb2pJb3lDTWhKQVlZZ0RPMXd3TUMwSkxhZzRFQThHRG9QQnlLWWFCRUNVSUpEd2hnT0V3d0ZvZ0FOTUtqRFF3Q3JNSENoM3lSQ1BNNXVvOVBId3RBbEU4N0hDZUE1ZG5JSlBSTWdUekY3QlFRSktCUXFmQVFHTWg0WUdod2VsUllSQURzPSIpOw0KfQ0KDQouaWNvbjIgew0KICAgIHdpZHRoOiAxNHB4Ow0KICAgIGhlaWdodDogMTVweDsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybCgiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoRUFBUUFKRURBUERWTWFtTUR3QUFBUC8vL3lINUJBRUFBQU1BTEFBQUFBQVFBQkFBQUFJeW5JK3BCckFhV25pb05XcWluYlFKY1QzYUp6MFdHU1lhZ0FKY3RhME9JbHNiZklMMlViZWxEUXhLQXNTaXNUakRJQW9BT3c9PSIpOw0KfQ0KDQouaWNvbjMgew0KICAgIHdpZHRoOiAxNHB4Ow0KICAgIGhlaWdodDogMTVweDsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybCgiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoRUFBUUFLSUhBTEVjSGVYdDdhQ2hwY2pKMEplWG03ZTV2di8vLy8vLy95SDVCQUVBQUFjQUxBQUFBQUFRQUJBQUFBTmFlTHJjTG1XTUlwd2lwWkJOSUdsWUI0ekFwakZhWUJBallRVFk0aFhHU3FoQ1dSM2FTTCtCbkU4eElBRUVnYUJ4UURRaUE0V2xvZ2VnU1FMRjRVSEFzbzRHaG1KbkVTVmtSN0FxUTJRa2NVSFUxc2tDa1ZBc2VFY0NBRHM9Iik7DQp9DQoNCi5pdGVtQmFyIHsNCiAgICBwYWRkaW5nOiA3cHg7DQogICAgbWluLWhlaWdodDogMjBweDsNCiAgICBtYXJnaW4tdG9wOiA0cHg7DQogICAgbWFyZ2luLXJpZ2h0OiA4cHg7DQogICAgd2lkdGg6IGF1dG87DQogICAgYm9yZGVyLXJhZGl1czogOHB4Ow0KICAgIGJhY2tncm91bmQtY29sb3I6ICM4YzhiODE7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KfQ0KDQouY29tcHV0ZXJpdGVtY2lyIHsNCiAgICB3aWR0aDogMTJweDsNCiAgICBoZWlnaHQ6IDEycHg7DQogICAgYm9yZGVyLXJhZGl1czogNHB4Ow0KICAgIGJhY2tncm91bmQ6IGdyYXk7DQogICAgbWFyZ2luLXJpZ2h0OjRweDsNCn0NCg0KLmNvbXB1dGVyaXRlbSB7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIHdpZHRoOiBhdXRvOw0KICAgIC8qDQogICAgYm9yZGVyLXJhZGl1czogNXB4Ow0KICAgIGJhY2tncm91bmQtY29sb3I6ICNhNmE1YTA7DQogICAgKi8NCiAgICBoZWlnaHQ6IDI4cHg7DQogICAgbWFyZ2luOiA0cHg7DQogICAgcGFkZGluZzogMnB4Ow0KfQ0KDQogICAgLmNvbXB1dGVyaXRlbTpob3ZlciB7DQogICAgICAgIGJhY2tncm91bmQtY29sb3I6ICM4MzgyN2I7DQogICAgfQ0KDQoudXMgew0KICAgIC13ZWJraXQtdG91Y2gtY2FsbG91dDogaW5pdGlhbDsNCiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBhdXRvOw0KICAgIC1raHRtbC11c2VyLXNlbGVjdDogdGV4dDsNCiAgICAtbW96LXVzZXItc2VsZWN0OiB0ZXh0Ow0KICAgIC1tcy11c2VyLXNlbGVjdDogdGV4dDsNCiAgICB1c2VyLXNlbGVjdDogdGV4dDsNCn0NCg0KDQovKiBTdHlsZXMgYmVsb3cgYXJlIG9ubHkgdXNlZCBpbiBOb2RlSlMsIFdlYlNpdGUgY29tcGlsZXIgc2hvdWxkIHJlbW92ZSB0aGVzZSBpbiB0aGUgZnV0dXJlICovDQoNCi50b3BDZWxsIHsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOnVybCgnaW1hZ2VzLWNvbW1hbmRlci9sb2dvYmFjay5wbmcnKTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpuby1yZXBlYXQ7DQp9DQoNCi5pMSB7DQogICAgYmFja2dyb3VuZDogdXJsKGltYWdlcy1jb21tYW5kZXIvaWNvbnM1MC5wbmcpIDBweCAwcHg7DQogICAgaGVpZ2h0OiA1MHB4Ow0KICAgIHdpZHRoOiA1MHB4Ow0KICAgIGN1cnNvcjogcG9pbnRlcjsNCiAgICBib3JkZXI6IG5vbmU7DQp9DQoNCi5pMiB7DQogICAgYmFja2dyb3VuZDogdXJsKGltYWdlcy1jb21tYW5kZXIvaWNvbnM1MC5wbmcpIC01MHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmkzIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczUwLnBuZykgLTEwMHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmk0IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczUwLnBuZykgLTE1MHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmk1IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczUwLnBuZykgLTIwMHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmk2IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczUwLnBuZykgLTI1MHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmoxIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczI2LnBuZykgMHB4IDBweDsNCiAgICBoZWlnaHQ6IDI2cHg7DQogICAgd2lkdGg6IDI2cHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmoyIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczI2LnBuZykgLTI2cHggMHB4Ow0KICAgIGhlaWdodDogMjZweDsNCiAgICB3aWR0aDogMjZweDsNCiAgICBjdXJzb3I6IHBvaW50ZXI7DQogICAgYm9yZGVyOiBub25lOw0KfQ0KDQouajMgew0KICAgIGJhY2tncm91bmQ6IHVybChpbWFnZXMtY29tbWFuZGVyL2ljb25zMjYucG5nKSAtNTJweCAwcHg7DQogICAgaGVpZ2h0OiAyNnB4Ow0KICAgIHdpZHRoOiAyNnB4Ow0KICAgIGN1cnNvcjogcG9pbnRlcjsNCiAgICBib3JkZXI6IG5vbmU7DQp9DQoNCi5qNCB7DQogICAgYmFja2dyb3VuZDogdXJsKGltYWdlcy1jb21tYW5kZXIvaWNvbnMyNi5wbmcpIC03OHB4IDBweDsNCiAgICBoZWlnaHQ6IDI2cHg7DQogICAgd2lkdGg6IDI2cHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmo1IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczI2LnBuZykgLTEwNHB4IDBweDsNCiAgICBoZWlnaHQ6IDI2cHg7DQogICAgd2lkdGg6IDI2cHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmo2IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczI2LnBuZykgLTEzMHB4IDBweDsNCiAgICBoZWlnaHQ6IDI2cHg7DQogICAgd2lkdGg6IDI2cHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmdyYXkgew0KICAgIC8qZmlsdGVyOiB1cmwoImRhdGE6aW1hZ2Uvc3ZnK3htbDt1dGY4LCZsdDtzdmcgeG1sbnM9XCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wnJmd0OyZsdDtmaWx0ZXIgaWQ9XCdncmF5c2NhbGVcJyZndDsmbHQ7ZmVDb2xvck1hdHJpeCB0eXBlPVwnbWF0cml4XCcgdmFsdWVzPVwnMC4zMzMzIDAuMzMzMyAwLjMzMzMgMCAwIDAuMzMzMyAwLjMzMzMgMC4zMzMzIDAgMCAwLjMzMzMgMC4zMzMzIDAuMzMzMyAwIDAgMCAwIDAgMSAwXCcvJmd0OyZsdDsvZmlsdGVyJmd0OyZsdDsvc3ZnJmd0OyNncmF5c2NhbGUiKTsqLyAvKiBGaXJlZm94IDEwKywgRmlyZWZveCBvbiBBbmRyb2lkICovDQogICAgZmlsdGVyOiBncmF5OyAvKiBJRTYtOSAqLw0KICAgIC13ZWJraXQtZmlsdGVyOiBncmF5c2NhbGUoMTAwJSkgb3BhY2l0eSg2MCUpOyAvKiBDaHJvbWUgMTkrLCBTYWZhcmkgNissIFNhZmFyaSA2KyBpT1MgKi8NCn0NCg0KLmcxIHsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwJSAwJTsNCiAgICB3aWR0aDogMTRweDsNCiAgICBoZWlnaHQ6IDEwMCU7DQogICAgZmxvYXQ6IGxlZnQ7DQogICAgLyogZmFsbGJhY2sgKE9wZXJhKSAqLw0KICAgIC8qIE1vemlsbGE6ICovDQogICAgLyogQ2hyb21lLCBTYWZhcmk6Ki8NCiAgICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsICNmZmZmZmYgMCUsICNjOWM5YzkgMTAwJSk7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI2M5YzljOTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtYXR0YWNobWVudDogc2Nyb2xsOw0KfQ0KDQouZzIgew0KICAgIGJhY2tncm91bmQtcG9zaXRpb246IDAlIDAlOw0KICAgIHdpZHRoOiAxNHB4Ow0KICAgIGhlaWdodDogMTAwJTsNCiAgICBmbG9hdDogcmlnaHQ7DQogICAgLyogZmFsbGJhY2sgKE9wZXJhKSAqLw0KICAgIC8qIE1vemlsbGE6ICovDQogICAgLyogQ2hyb21lLCBTYWZhcmk6Ki8NCiAgICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsICNjOWM5YzkgMCUsICNmZmZmZmYgMTAwJSk7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI2M5YzljOTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtYXR0YWNobWVudDogc2Nyb2xsOw0KfQ0KDQouZzFzIHsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwJSAwJTsNCiAgICB3aWR0aDogMTRweDsNCiAgICBoZWlnaHQ6IDEwMCU7DQogICAgZmxvYXQ6IGxlZnQ7DQogICAgLyogZmFsbGJhY2sgKE9wZXJhKSAqLw0KICAgIC8qIE1vemlsbGE6ICovDQogICAgLyogQ2hyb21lLCBTYWZhcmk6Ki8NCiAgICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsICNmZmZmZmYgMCUsICNhMGEwYTAgMTAwJSk7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI2EwYTBhMDsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtYXR0YWNobWVudDogc2Nyb2xsOw0KfQ0KDQouZzJzIHsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwJSAwJTsNCiAgICB3aWR0aDogMTRweDsNCiAgICBoZWlnaHQ6IDEwMCU7DQogICAgZmxvYXQ6IHJpZ2h0Ow0KICAgIC8qIGZhbGxiYWNrIChPcGVyYSkgKi8NCiAgICAvKiBNb3ppbGxhOiAqLw0KICAgIC8qIENocm9tZSwgU2FmYXJpOiovDQogICAgYmFja2dyb3VuZC1pbWFnZTogbGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCAjYTBhMGEwIDAlLCAjZmZmZmZmIDEwMCUpOw0KICAgIGJhY2tncm91bmQtY29sb3I6ICNhMGEwYTA7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6IHJlcGVhdDsNCiAgICBiYWNrZ3JvdW5kLWF0dGFjaG1lbnQ6IHNjcm9sbDsNCn0NCg0KDQoubGJidXR0b24gew0KICAgIHdpZHRoOjQ0cHg7DQogICAgaGVpZ2h0OjQ0cHg7DQogICAgYm9yZGVyLXJhZGl1czo1cHg7DQogICAgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsNCiAgICBtYXJnaW4tbGVmdDo0cHg7DQogICAgbWFyZ2luLXRvcDo0cHg7DQogICAgcG9zaXRpb246cmVsYXRpdmU7DQogICAgY3Vyc29yOnBvaW50ZXI7DQogICAgb3BhY2l0eTowLjU7DQp9DQoNCi5sYmJ1dHRvbjpob3ZlciB7DQogICAgb3BhY2l0eToxOw0KfQ0KDQoubGJidXR0b25zZWwgew0KICAgIG9wYWNpdHk6MC45Ow0KfQ0KDQoubGJidXR0b25zZWwyIHsNCiAgICB3aWR0aDo4MnB4Ow0KICAgIGJvcmRlci1yYWRpdXM6NXB4IDBweCAwcHggNXB4Ow0KICAgIG9wYWNpdHk6MTsNCn0NCg0KLmxiMSB7DQogICAgYmFja2dyb3VuZDogdXJsKGltYWdlcy1jb21tYW5kZXIvbGVmdGJhci0zMi5wbmcpIC0wcHggMHB4Ow0KICAgIGhlaWdodDogMzJweDsNCiAgICB3aWR0aDogMzJweDsNCiAgICBjdXJzb3I6IHBvaW50ZXI7DQogICAgYm9yZGVyOiBub25lOw0KfQ0KDQoubGIyIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9sZWZ0YmFyLTMyLnBuZykgLTMycHggMHB4Ow0KICAgIGhlaWdodDogMzJweDsNCiAgICB3aWR0aDogMzJweDsNCiAgICBjdXJzb3I6IHBvaW50ZXI7DQogICAgYm9yZGVyOiBub25lOw0KfQ0KDQoubGIzIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9sZWZ0YmFyLTMyLnBuZykgLTY0cHggMHB4Ow0KICAgIGhlaWdodDogMzJweDsNCiAgICB3aWR0aDogMzJweDsNCiAgICBjdXJzb3I6IHBvaW50ZXI7DQogICAgYm9yZGVyOiBub25lOw0KfTwvc3R5bGU+DQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgPHN0eWxlPg0KICAgICAgICAubWVudWl0ZW0geyBjdXJzb3I6IHBvaW50ZXI7IGJvcmRlcjogbm9uZTsgcGFkZGluZzo1cHg7IH0NCiAgICAgICAgLm1lbnVpdGVtOmhvdmVyIHsgYmFja2dyb3VuZC1jb2xvcjogIzZiOWRjNzsgfQ0KICAgIDwvc3R5bGU+DQogICAgICAgICAgICAgICAgPHRpdGxlPkxNUyBNZXNoQ29tbWFuZGVyPC90aXRsZT4NCiAgICAgICAgICAgIDwvaGVhZD4NCjxib2R5IG9udW5sb2FkPSJjbGVhbnVwKCkiPg0KICAgIDxkaXYgaWQ9ImlkX3RvcGhlYWRlciIgY2xhc3M9ImhlYWRlciI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzcz0idG9wQ2VsbCIgc3R5bGU9IndpZHRoOjEwMCU7aGVpZ2h0OjU1cHgiPg0KICAgICAgICAgICAgPHRyPg0KICAgICAgICAgICAgICAgIDx0ZCB2YWxpZ249InRvcCIgbm93cmFwPSJub3dyYXAiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJ0b3AxIj5MTVMgTWVzaENvbW1hbmRlcjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJ0b3AyIiBpZD0iaWRfY29tcHV0ZXJuYW1lIj4NCiAgICAgICAgICAgICAgICA8L3RkPg0KICAgICAgICAgICAgICAgIDx0ZCB2YWxpZ249InRvcCI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+DQogICAgICAgICAgICA8L3RyPg0KICAgICAgICA8L3RhYmxlPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9InByb2dyZXNzYmFyIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImlkX3Byb2dyZXNzYmFyIiBzdHlsZT0iaGVpZ2h0OjJweDt3aWR0aDowJTtiYWNrZ3JvdW5kLWNvbG9yOnJlZCI+PC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgIDwvZGl2Pg0KICAgIDxkaXYgaWQ9ImlkX21lc3NhZ2V2aWV3IiBjbGFzcz0iZnVsbGNlbGwiIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlcjtwYWRkaW5nLXRvcDoxMDBweDtmb250LXNpemU6MjBweCI+DQogICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfbWVzc2FnZXZpZXdzdHIiPkxvYWRpbmcuLi48L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxicj48YnI+PGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkNsb3NlIiBvbmNsaWNrPSJkaXNjb25uZWN0KCkiPg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgIDxkaXYgaWQ9ImlkX2xtc01haW5QYW5lbCIgY2xhc3M9ImZ1bGxjZWxsIiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgPGRpdiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjpsaWdodGdyYXk7aGVpZ2h0OjI0cHg7bWFyZ2luLWJvdHRvbTo2cHg7cGFkZGluZy10b3A6MnB4Ij4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImlkX2xtc1Rvb2xCYXJDb250ZW50IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZmxvYXQ6bGVmdDtoZWlnaHQ6MjZweDt3aWR0aDoyNnB4O2N1cnNvcjpwb2ludGVyIiBvbmNsaWNrPSJ0b29sbWVudWNsaWNrKDApIj4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxNnB4Ij4mbmJzcDsmIzk3NzY7PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iUmVmcmVzaCIgb25jbGljaz0ibG1zUmVmcmVzaCgpIj4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJpZF9sbXNBY3RpdmF0ZUJ1dHRvbiIgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iQWN0aXZhdGUuLi4iIHN0eWxlPSJkaXNwbGF5Om5vbmUiIG9uY2xpY2s9Imxtc0FjdGl2YXRlKCkiPg0KICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9ImlkX2xtc0RlYWN0aXZhdGVCdXR0b24iIHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkRlYWN0aXZhdGUuLi4iIHN0eWxlPSJkaXNwbGF5Om5vbmUiIG9uY2xpY2s9Imxtc0RlYWN0aXZhdGUoKSI+DQogICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iaWRfbG1zTG9naW5CdXR0b24iIHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkxvZ2luLi4uIiBzdHlsZT0iZGlzcGxheTpub25lIiBvbmNsaWNrPSJsbXNMb2dpbigpIj4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJpZF9sbXNDb25maWd1cmVCdXR0b24iIHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkludGVsJnJlZzsgQU1UIExvZ2luLi4uIiBzdHlsZT0iZGlzcGxheTpub25lIiBvbmNsaWNrPSJsbXNDb25maWd1cmUoKSI+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgPC9kaXY+DQogICAgICAgIDxkaXYgaWQ9ImlkX2xtc0RhdGEiIHN0eWxlPSJtYXJnaW46MTBweCI+PC9kaXY+DQogICAgICAgIDxkaXYgaWQ9ImlkX2xtc0RhdGEyIiBzdHlsZT0ibWFyZ2luOjEwcHgiPjwvZGl2Pg0KICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9jb21wdXRlclNlbGVjdG9yTWVudSIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6I0VFRUVFRTtkaXNwbGF5Om5vbmU7cG9zaXRpb246YWJzb2x1dGU7bGVmdDowO3RvcDo5NHB4O3dpZHRoOjIwMHB4O3BhZGRpbmc6M3B4O3otaW5kZXg6MTAwMDtib3gtc2hhZG93OjVweCA1cHggNXB4ICM4ODg4ODg7Ym9yZGVyOjFweCBzb2xpZCBncmF5Ij4NCiAgICAgICAgPGRpdiBjbGFzcz0ibWVudWl0ZW0iIG9uY2xpY2s9InRvb2xtZW51Y2xpY2soMTAxKSI+PHNwYW4gaWQ9ImlkX21lbnVpdGVtMSI+JmJ1bGw7IDwvc3Bhbj5Db21wdXRlciBDb25maWd1cmF0aW9uPC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0ibWVudWl0ZW0iIG9uY2xpY2s9InRvb2xtZW51Y2xpY2soMTAyKSI+PHNwYW4gaWQ9ImlkX21lbnVpdGVtMiIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+JmJ1bGw7IDwvc3Bhbj5VU0IgU2V0dXAuYmluIEVkaXRvcjwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJpZF91c2JTZXR1cFBhbmVsIiBjbGFzcz0iZnVsbGNlbGwiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgIDx0YWJsZSBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojODA4MDgwO3dpZHRoOjEwMCUiPg0KICAgICAgICAgICAgPHRyPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9IndpZHRoOjI2cHg7Y3Vyc29yOnBvaW50ZXIiIG9uY2xpY2s9InRvb2xtZW51Y2xpY2soMCkiPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT0iZm9udC1zaXplOjE2cHgiPiZuYnNwOyYjOTc3Njs8L3NwYW4+DQogICAgICAgICAgICAgICAgPC90ZD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPg0KICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iTmV3Li4uIiBvbmNsaWNrPSJ1c2JfbmV3U2V0dXBCaW4oKSI+DQogICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJPcGVuLi4uIiBvbmNsaWNrPSJ1c2Jfb3BlblNldHVwQmluKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iaWRfc2F2ZVNldHVwQmluIiB0eXBlPSJidXR0b24iIHZhbHVlPSJTYXZlLi4uIiBvbmNsaWNrPSJ1c2Jfc2F2ZVNldHVwQmluKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD4NCiAgICAgICAgICAgIDwvdHI+DQogICAgICAgIDwvdGFibGU+DQogICAgICAgIDxkaXYgaWQ9ImlkX3VzYlNldHVwUGFuZWwyIiBzdHlsZT0icG9zaXRpb246Zml4ZWQ7b3ZlcmZsb3cteTpzY3JvbGw7bGVmdDowO3JpZ2h0OjA7Ym90dG9tOjA7dG9wOjk2cHgiPg0KICAgICAgICAgICAgPGRpdiBpZD0iaWRfU3RhcnR1cFNjcmVlbiIgc3R5bGU9IndpZHRoOjEwMCU7dGV4dC1hbGlnbjpjZW50ZXI7Y29sb3I6Z3JheTttYXJnaW4tdG9wOjM2cHgiPg0KICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPSJmb250LXNpemU6MjBweCI+SW50ZWw8c3VwIHN0eWxlPSJmb250LXNpemU6MTBweCI+JnJlZzs8L3N1cD4gQU1UIFVTQiBTZXR1cC5iaW4gTWFuYWdlcjwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJtYXJnaW46NHB4Ij5HZXQgc3RhcnRlZCBieSA8YSBvbmNsaWNrPSJ1c2JfbmV3U2V0dXBCaW4oKSIgc3R5bGU9ImN1cnNvcjpwb2ludGVyIj48dT5jcmVhdGluZzwvdT48L2E+IGEgbmV3IGZpbGUsIDxhIG9uY2xpY2s9InVzYl9vcGVuU2V0dXBCaW4oKSIgc3R5bGU9ImN1cnNvcjpwb2ludGVyIj48dT5vcGVuaW5nPC91PjwvYT4gYW4gZXhpc3Rpbmcgb25lPGJyPm9yIGRyYWcgJiBkcm9wcGluZyBhIHNldHVwLmJpbiBmaWxlIGluIHRoaXMgd2luZG93LjwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJpZF9TZXR1cEJpbkFyZWEiIHN0eWxlPSJtYXJnaW46MTBweCI+PC9kaXY+DQogICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImlkX21haW52aWV3IiBzdHlsZT0iaGVpZ2h0OjEwMCU7ZGlzcGxheTpub25lIj4NCiAgICAgICAgPGRpdiBpZD0iaWRfbGVmdGJhciIgY2xhc3M9Im5hdmJhciI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdwYWRkaW5nOjhweCc+DQogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgaWQ9ImRpc2Nvbm5lY3RCdXR0b24iIHZhbHVlPSJEaXNjb25uZWN0IiBvbmtleXByZXNzPSJyZXR1cm4gZmFsc2UiIG9ua2V5ZG93bj0icmV0dXJuIGZhbHNlIiBvbmNsaWNrPSJkaXNjb25uZWN0KCkiIHN0eWxlPSJ3aWR0aDoxMzhweCI+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzEiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbygxKSI+PGE+U3lzdGVtIFN0YXR1czwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBpZD0iZ28yIiBjbGFzcz0ibmF2MSIgb25jbGljaz0iZ28oMikiPjxhPkhhcmR3YXJlIEluZm9ybWF0aW9uPC9hPjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzYiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbyg2KSI+PGE+RXZlbnQgTG9nPC9hPjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzE1IiBjbGFzcz0ibmF2MSIgb25jbGljaz0iZ28oMTUpIj48YT5BdWRpdCBMb2c8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgaWQ9ImdvMjEiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbygyMSkiPjxhPlN0b3JhZ2U8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgaWQ9ImdvOCIgY2xhc3M9Im5hdjEiIG9uY2xpY2s9ImdvKDgpIj48YT5OZXR3b3JrIFNldHRpbmdzPC9hPjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzE3IiBjbGFzcz0ibmF2MSIgb25jbGljaz0iZ28oMTcpIj48YT5JbnRlcm5ldCBTZXR0aW5nczwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBpZD0iZ28xNiIgY2xhc3M9Im5hdjEiIG9uY2xpY2s9ImdvKDE2KSI+PGE+U2VjdXJpdHkgU2V0dGluZ3M8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgaWQ9ImdvMTkiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbygxOSkiPjxhPkFnZW50IFByZXNlbmNlPC9hPjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzE4IiBjbGFzcz0ibmF2MSIgb25jbGljaz0iZ28oMTgpIj48YT5TeXN0ZW0gRGVmZW5zZTwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgICAgICA8cCBpZD0iZ28xMSIgY2xhc3M9Im5hdjEiIG9uY2xpY2s9ImdvKDExKSI+PGE+VXNlciBBY2NvdW50czwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBpZD0iZ28yMyIgY2xhc3M9Im5hdjEiIG9uY2xpY2s9ImdvKDIzKSI+PGE+V2FrZSBBbGFybXM8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgaWQ9ImdvMjAiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbygyMCkiPjxhPlNjcmlwdCBFZGl0b3I8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgPGRpdiBpZD0iaWRfbWFpbmFyZWEiIGNsYXNzPSJtYWluY2VsbCI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9zY3JpcHRzdGF0dXMiIHN0eWxlPSJoZWlnaHQ6MjFweDtiYWNrZ3JvdW5kOiM4ZmFjOGQ7cGFkZGluZzo1cHg7bWFyZ2luLWJvdHRvbToxcHg7ZGlzcGxheTpub25lO292ZXJmbG93OmhpZGRlbiI+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZmxvYXQ6cmlnaHQiPjxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJTdG9wIFNjcmlwdCIgb25jbGljaz0ic2NyaXB0X1N0b3AoKSI+PC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZm9udC1zaXplOjE2cHg7cGFkZGluZy10b3A6MnB4O292ZXJmbG93OmhpZGRlbiI+Jm5ic3A7PGI+UnVubmluZyBTY3JpcHQ8L2I+PHNwYW4gc3R5bGU9Im92ZXJmbG93OmhpZGRlbiIgaWQ9ImlkX3NjcmlwdHN0YXR1c3N0ciI+PC9zcGFuPjwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9tYWluYXJlYV9mcmFtZSIgc3R5bGU9IndpZHRoOjEwMCU7aGVpZ2h0OjEwMCUiPg0KICAgICAgICAgICAgICAgIDxpZnJhbWUgaWQ9ImlkX1N0b3JhZ2VJRnJhbWUiIHN0eWxlPSJ3aWR0aDoxMDAlO2hlaWdodDoxMDAlO2JvcmRlcjowIj48L2lmcmFtZT4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iaWRfbWFpbmFyZWFfcGFkIiBzdHlsZT0icGFkZGluZzo4cHg7b3ZlcmZsb3cteDpoaWRkZW4iPg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAwIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPkxvYWRpbmcuLi48L2gxPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAxIiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPlN5c3RlbSBTdGF0dXM8L2gxPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVTeXNTdGF0dXMiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDIiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgICAgICA8aDEgc3R5bGU9Im1hcmdpbi1ib3R0b206MTZweCI+SGFyZHdhcmUgSW5mb3JtYXRpb248L2gxPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVTeXNJbmZvIj48L3NwYW4+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJwNiIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+DQogICAgICAgICAgICAgICAgICAgIDxoMT5FdmVudCBMb2c8L2gxPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVFdmVudExvZyI+PC9zcGFuPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVFdmVudExvZzIiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InA4IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPk5ldHdvcmsgU2V0dGluZ3M8L2gxPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVOZXR3b3JrU2V0dGluZ3NTcGFuIj48L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlV2lmaTIiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJwMTEiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgICAgICA8aDE+VXNlciBBY2NvdW50czwvaDE+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIGlkPSJpZF9UYWJsZVVzZXJBY2NvdW50cyI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJwMTUiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVBdWRpdExvZzEiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPkF1ZGl0IExvZzwvaDE+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIGlkPSJpZF9UYWJsZUF1ZGl0TG9nMiI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDE2IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPlNlY3VyaXR5IFNldHRpbmdzPC9oMT4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlQ2VydHMiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAxNyIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+DQogICAgICAgICAgICAgICAgICAgIDxoMT5JbnRlcm5ldCBTZXR0aW5nczwvaDE+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIGlkPSJpZF9UYWJsZVJlbW90ZUFjY2VzcyI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDE4IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPlN5c3RlbSBEZWZlbnNlPC9oMT4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlU3lzdGVtRGVmZW5zZSI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDE5IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPkFnZW50IFByZXNlbmNlPC9oMT4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlU3lzdGVtQWdlbnRQcmVzZW5jZSI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDIwIiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPlNjcmlwdCBFZGl0b3I8L2gxPg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJsb2cxIiBzdHlsZT0icGFkZGluZzo1cHg7Ym9yZGVyLXJhZGl1czo1cHgiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0nRWRpdFNjcmlwdFN0YXR1cycgc3R5bGU9ImZsb2F0OnJpZ2h0O2ZvbnQtd2VpZ2h0OmJvbGQ7cGFkZGluZzo1cHgiPlN0b3BwZWQ8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IlZpZXcgRWRpdG9yIiB0aXRsZT0iU3dpdGNoIHRvIHNjcmlwdCBsaW5lIGVkaXRvciB2aWV3IiBpZD0idmlld0VkaXRvckJ1dHRvbiIgb25jbGljaz0ic2NyaXB0Vmlld0J1dHRvbigwKSI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IlZpZXcgQnVpbGRlciIgdGl0bGU9IlN3aXRjaCB0byBibG9jayBlZGl0b3IgdmlldyIgaWQ9InZpZXdCdWlsZGVyQnV0dG9uIiBvbmNsaWNrPSJzY3JpcHRWaWV3QnV0dG9uKDEpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iTmV3Li4uIiB0aXRsZT0iQ2xlYXIgdGhlIHNjcmlwdCBlZGl0b3IiIG9uY2xpY2s9InNjcmlwdF9uZXdTY3JpcHREbGcoKSI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkxvYWQuLi4iIHRpdGxlPSJMb2FkIGEgc2NyaXB0IGZyb20gZmlsZSIgb25jbGljaz0ic2NyaXB0X3J1blNjcmlwdERsZygpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IlNhdmUuLi4iIHRpdGxlPSJTYXZlIGEgc2NyaXB0IHRvIGZpbGUiIG9uY2xpY2s9InNjcmlwdF9zYXZlU2NyaXB0KGV2ZW50KSI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJSZXN0YXJ0IiB0aXRsZT0iQ29tcGlsZSB0aGUgc2NyaXB0IGFuZCBnZXQgcmVhZHkgdG8gcnVuIGl0IGZyb20gdGhlIHN0YXJ0IiBvbmNsaWNrPSJyZXNldFNjcmlwdEJ1dHRvbigpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iQ29udGludWUiIHRpdGxlPSJSdW4gdGhlIHNjcmlwdCBmcm9tIHRoZSBjdXJyZW50IGV4ZWN1dGlvbiBwb2ludCIgb25jbGljaz0icnVuU2NyaXB0QnV0dG9uKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJCcmVhayIgdGl0bGU9IlBhdXNlIHRoZSBleGVjdXRpb24gb2YgdGhlIHNjcmlwdCIgb25jbGljaz0iYnJlYWtTY3JpcHRCdXR0b24oKSI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IlN0ZXAiIHRpdGxlPSJFeGVjdXRlIG9uZSBzdGVwIG9mIHRoZSBzY3JpcHQiIG9uY2xpY2s9InN0ZXBTY3JpcHRCdXR0b24oKSI+DQogICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InNjcmlwdGJ1aWxkZXIiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPGgyPlNjcmlwdCBCdWlsZGVyPC9oMj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9InBhZGRpbmc6MDttYXJnaW46MCI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0id2lkdGg6MjUwcHg7aGVpZ2h0OjQwMHB4O2Zsb2F0OmxlZnQ7cGFkZGluZzowO21hcmdpbjowO3BhZGRpbmctcmlnaHQ6M3B4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJibG9ja2ZpbHRlciIgc3R5bGU9IndpZHRoOmluaGVyaXQ7aGVpZ2h0OjI0cHg7cGFkZGluZzowO21hcmdpbjowO2JvcmRlcjoxcHggc29saWQgZ3JheTttYXJnaW4tYm90dG9tOjFweCIgcGxhY2Vob2xkZXI9IkZpbHRlciBibG9ja3MuLi4iIG9ua2V5dXA9InNjcmlwdF9mb25maWx0ZXJjaGFuZ2VkKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJibG9ja3MiIHN0eWxlPSJ3aWR0aDppbmhlcml0O2hlaWdodDozNzNweDtib3JkZXI6MXB4IHNvbGlkIGdyYXk7b3ZlcmZsb3cteTpzY3JvbGw7cGFkZGluZzowO21hcmdpbjowIj48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJzY3JpcHRibG9ja3MiIHN0eWxlPSJ3aWR0aDphdXRvO2hlaWdodDo0MDBweDtwYWRkaW5nOjA7bWFyZ2luOjA7Ym9yZGVyOjFweCBzb2xpZCBncmF5O292ZXJmbG93LXk6c2Nyb2xsIiBvbmRyb3A9InNjcmlwdF9mb25kcm9wKGV2ZW50LCB0aGlzKSIgb25jbGljaz0ic2NyaXB0X2ZvbmNsaWNrKGV2ZW50KSI+PC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InNjcmlwdGVkaXRvciI+DQogICAgICAgICAgICAgICAgICAgICAgICA8aDI+U2NyaXB0PC9oMj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZXh0YXJlYSBpZD0ic2NyaXB0YXJlYSIgc3R5bGU9IndpZHRoOjEwMCU7aGVpZ2h0OjE3NnB4O3Jlc2l6ZTp2ZXJ0aWNhbDttYXJnaW46MDtwYWRkaW5nOjA7Zm9udC1mYW1pbHk6QXJpYWwsSGVsdmV0aWNhLHNhbnMtc2VyaWYiIHNwZWxsY2hlY2s9ImZhbHNlIj48L3RleHRhcmVhPg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnI+PGgyPkNvbXBpbGVkIFNjcmlwdDwvaDI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIGlkPSJjb21waWxlZGFyZWEiIHN0eWxlPSJ3aWR0aDoxMDAlO2hlaWdodDoxNnB4O3Jlc2l6ZTp2ZXJ0aWNhbDttYXJnaW46MDtwYWRkaW5nOjAiIHNwZWxsY2hlY2s9ImZhbHNlIj48L3RleHRhcmVhPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxicj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGgyPlZhcmlhYmxlczwvaDI+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJ2YXJpYWJsZXMiIHN0eWxlPSJ3aWR0aDoxMDAlO2hlaWdodDoyMDBweDtyZXNpemU6dmVydGljYWw7Ym9yZGVyOjFweCBzb2xpZCBncmF5O292ZXJmbG93OnNjcm9sbDttYXJnaW46MDtwYWRkaW5nOjA7dXNlci1zZWxlY3Q6dGV4dDstd2Via2l0LXVzZXItc2VsZWN0OnRleHQ7LWtodG1sLXVzZXItc2VsZWN0OnRleHQ7LW1vei11c2VyLXNlbGVjdDp0ZXh0Oy1tcy11c2VyLXNlbGVjdDp0ZXh0Ij48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxoMj5Db25zb2xlPC9oMj4NCiAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIGlkPSJjb25zb2xlIiBzdHlsZT0id2lkdGg6MTAwJTtoZWlnaHQ6ODBweDtyZXNpemU6dmVydGljYWw7bWFyZ2luOjA7cGFkZGluZzowO3VzZXItc2VsZWN0OnRleHQ7LXdlYmtpdC11c2VyLXNlbGVjdDp0ZXh0Oy1raHRtbC11c2VyLXNlbGVjdDp0ZXh0Oy1tb3otdXNlci1zZWxlY3Q6dGV4dDstbXMtdXNlci1zZWxlY3Q6dGV4dCIgcmVhZG9ubHk9IiI+PC90ZXh0YXJlYT4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAyMSIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+DQogICAgICAgICAgICAgICAgICAgIDxoMT5TdG9yYWdlPC9oMT4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlU3lzdGVtU3RvcmFnZSI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAyMyIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+DQogICAgICAgICAgICAgICAgICAgIDxoMT5XYWtlIEFsYXJtczwvaDE+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIGlkPSJpZF9UYWJsZUFsYXJtIj48L3NwYW4+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICA8L2Rpdj4NCiAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZyIgc3R5bGU9InotaW5kZXg6MTAwMDtiYWNrZ3JvdW5kLWNvbG9yOiNFRUU7Ym94LXNoYWRvdzowcHggMHB4IDE1cHggIzY2Njtmb250LWZhbWlseTpBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmO2JvcmRlci1yYWRpdXM6NXB4O3Bvc2l0aW9uOmZpeGVkO3RvcDoxNjBweDt3aWR0aDo0MDBweDtkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgPGRpdiBzdHlsZT0id2lkdGg6MTAwJTtiYWNrZ3JvdW5kLWNvbG9yOiMwMDMzNjY7Y29sb3I6I0ZGRjtib3JkZXItcmFkaXVzOjVweCA1cHggMCAwIj4NCiAgICAgICAgICAgIDxkaXYgaWQ9J2lkX2RpYWxvZ2Nsb3NlJyBzdHlsZT0iZmxvYXQ6cmlnaHQ7cGFkZGluZzoxcHg7bWFyZ2luLXJpZ2h0OjVweDtjdXJzb3I6cG9pbnRlcjtmb250LXNpemU6MTVweCIgb25jbGljaz0ic2V0RGlhbG9nTW9kZSgpIj4mI3gyNzE2OzwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0naWRfZGlhbG9ndGl0bGUnIHN0eWxlPSJwYWRkaW5nOjVweCI+PC9kaXY+DQogICAgICAgICAgICA8ZGl2IHN0eWxlPSJ3aWR0aDoxMDAlO21hcmdpbjo2cHgiPjwvZGl2Pg0KICAgICAgICA8L2Rpdj4NCiAgICAgICAgPGRpdiBzdHlsZT0ibWFyZ2luLXJpZ2h0OjE2cHg7bWFyZ2luLWxlZnQ6OHB4Ij4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzEiIHN0eWxlPSJtYXJnaW46YXV0bzt0ZXh0LWFsaWduOmNlbnRlcjttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9kaWFsb2dNZXNzYWdlIiBzdHlsZT0icGFkZGluZzoxMHB4Ij48L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMiIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxicj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+PGlucHV0IGlkPSJkMnVzZXJuYW1lIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiIG9ua2V5dXA9InVwZGF0ZUFjY291bnREaWFsb2coKSI+PGRpdj5Vc2VybmFtZTwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImQycGFzc3dvcmQxIiB0eXBlPSJwYXNzd29yZCIgYXV0b2NvbXBsZXRlPSJvZmYiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25rZXl1cD0idXBkYXRlQWNjb3VudERpYWxvZygpIj48ZGl2PlBhc3N3b3JkKjwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImQycGFzc3dvcmQyIiB0eXBlPSJwYXNzd29yZCIgYXV0b2NvbXBsZXRlPSJvZmYiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25rZXl1cD0idXBkYXRlQWNjb3VudERpYWxvZygpIj48ZGl2PkNvbmZpcm0gUGFzc3dvcmQ8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9kMnBlcm1pc3Npb25zIj4NCiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0naGVpZ2h0OjI2cHgnPjxzZWxlY3QgaWQ9ImQycGVybWlzc2lvbiIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4Ij48b3B0aW9uIHZhbHVlPSIwIj5Mb2NhbDxvcHRpb24gdmFsdWU9IjEiPk5ldHdvcms8b3B0aW9uIHZhbHVlPSIyIj5Bbnk8L3NlbGVjdD48ZGl2PlBlcm1pc3Npb248L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPGRpdj5HcmFudGVkIFBlcm1pc3Npb25zPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDx1bCBpZD0iaWRfZDJyZWFsbXMiIHN0eWxlPSJsaXN0LXN0eWxlLXR5cGU6bm9uZTtoZWlnaHQ6MTAwcHg7b3ZlcmZsb3c6YXV0bzt3aWR0aDoxMDAlO2JvcmRlcjogMXB4IHNvbGlkICMwMDA7YmFja2dyb3VuZC1jb2xvcjp3aGl0ZTtvdmVyZmxvdy14OmhpZGRlbjttYXJnaW46MDtwYWRkaW5nOjAiPjwvdWw+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZm9udC1zaXplOjEwcHgiPjxicj4qTWluaW11bSA4IGNoYXJhY3RlcnMgd2l0aCB1cHBlciwgbG93ZXJjYXNlLCAwLTksIGFuZCBvbmUgb2YgIUAjJCVeJmFtcDsqKCkrLTwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2c0IiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImQ0dXNlcm5hbWUiIHBsYWNlaG9sZGVyPSJhZG1pbiIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IiBvbmtleXVwPSJsbXNVcGRhdGVMb2dpbkRpYWxvZyhldmVudCwgMSkiPjxkaXY+VXNlcm5hbWU8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+PGlucHV0IGlkPSJkNHBhc3N3b3JkIiB0eXBlPSJwYXNzd29yZCIgYXV0b2NvbXBsZXRlPSJvZmYiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25rZXl1cD0ibG1zVXBkYXRlTG9naW5EaWFsb2coZXZlbnQsIDIpIj48ZGl2PlBhc3N3b3JkKjwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImZvbnQtc2l6ZToxMHB4Ij48YnI+Kk1pbmltdW0gOCBjaGFyYWN0ZXJzIHdpdGggdXBwZXIsIGxvd2VyY2FzZSwgMC05LCBhbmQgb25lIG9mICFAIyQlXiZhbXA7KigpKy08L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nNSIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxicj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+DQogICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgaWQ9ImQ1YWN0aW9uU2VsZWN0IiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiPjwvc2VsZWN0Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2PlBvd2VyIEFjdGlvbjwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXY+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPldhcm5pbmc6PC9zcGFuPiBTb21lIHBvd2VyIGFjdGlvbnMgbWF5IHJlc3VsdCBpbiBkYXRhIGxvc3MgYW5kIG1heSBkaXNjb25uZWN0IHRoZSBkZXNrdG9wLCB0ZXJtaW5hbCBvciBkaXNrIHJlZGlyZWN0aW9uIHNlc3Npb25zLg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2c2IiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImQ2Q29uc2VudFRleHQiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgbWF4bGVuZ3RoPSI2IiBvbmtleXVwPSJjb25zZW50Q2hhbmdlZCgpIiBvbmtleXByZXNzPSJyZXR1cm4gbnVtYmVyc09ubHkoZXZlbnQpIj48ZGl2PkNvbnNlbnQgQ29kZTwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48c2VsZWN0IGlkPSJkNkRpc3BsYXkiIG9uY2hhbmdlPSJjaGFuZ2VDb25zZW50RGlzcGxheSgpIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiPjxvcHRpb24gdmFsdWU9IjAiPlByaW1hcnkgZGlzcGxheTxvcHRpb24gdmFsdWU9IjEiPlNlY29uZGFyeSBkaXNwbGF5PG9wdGlvbiBpZD0iZDZUaGlyZERpc3BsYXkiIHZhbHVlPSIyIiBzdHlsZT0iZGlzcGxheTpub25lIj5UaGlyZCBkaXNwbGF5PC9zZWxlY3Q+PGRpdj5Db25zZW50IERpc3BsYXk8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nOCIgc3R5bGU9ImRpc3BsYXk6dGFibGU7bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0ibWFyZ2luOjNweCAwIDNweCAwO3BhZGRpbmctdG9wOjVweCI+DQogICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iaWR4X2Q4dXNlcm5hbWUiIHZhbHVlPSJhZG1pbiIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIyMHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iaGVpZ2h0OjIwcHgiPlVzZXJuYW1lPC9kaXY+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0ibWFyZ2luOjNweCAwIDNweCAwIj4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJpZHhfZDhwYXNzd29yZCIgdHlwZT0icGFzc3dvcmQiIGF1dG9jb21wbGV0ZT0ib2ZmIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjIwcHgiPg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJoZWlnaHQ6MjBweCI+UGFzc3dvcmQ8L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nOSIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9J2lkeF9kOXJlZGlyJz5SZWRpcmVjdGlvbiBQb3J0PGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImlkeF9kOWt2bV9kaXYiPjxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9J2lkeF9kOWt2bSc+S1ZNIFJlbW90ZSBEZXNrdG9wPGJyPjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9J2lkeF9kOWlkZXInPklERS1SZWRpcmVjdGlvbjxicj4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSdpZHhfZDlzb2wnPlNlcmlhbC1vdmVyLUxBTjxicj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMTAiIHN0eWxlPSJtYXJnaW46YXV0bzttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0icmFkaW8iIG5hbWU9ImQxMCIgaWQ9J2lkeF9kMTBub25lJyB2YWx1ZT0iMCI+Tm90IFJlcXVpcmVkPGJyPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJyYWRpbyIgbmFtZT0iZDEwIiBpZD0naWR4X2QxMGt2bScgdmFsdWU9IjEiPlJlcXVpcmVkIGZvciBLVk0gb25seTxicj4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0icmFkaW8iIG5hbWU9ImQxMCIgaWQ9J2lkeF9kMTBhbGwnIHZhbHVlPSI0Mjk0OTY3Mjk1Ij5BbHdheXMgUmVxdWlyZWQ8YnI+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzExIiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGRpdiBpZD0iaWRfZGlhbG9nT3B0aW9ucyI+PC9kaXY+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzEyIiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImlkeF9kMTJuYW1lIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiIG1heGxlbmd0aD0iMzIiIG9ua2V5dXA9InVwZGF0ZVdpZmlEaWFsb2coKSIgdGl0bGU9Ik1heGltdW0gMzIgY2hhcmFjdGVycyI+PGRpdiB0aXRsZT0iTWF4aW11bSAzMiBjaGFyYWN0ZXJzIj5Qcm9maWxlIE5hbWU8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+PGlucHV0IGlkPSJpZHhfZDEyc3NpZCIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IiBtYXhsZW5ndGg9IjMyIiBvbmtleXVwPSJ1cGRhdGVXaWZpRGlhbG9nKCkiIHRpdGxlPSJNYXhpbXVtIDMyIGNoYXJhY3RlcnMiPjxkaXYgdGl0bGU9Ik1heGltdW0gMzIgY2hhcmFjdGVycyI+U1NJRDwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz4NCiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBpZD0iaWR4X2QxMnByaSIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IiBvbmNsaWNrPSJ1cGRhdGVXaWZpRGlhbG9nKCkiPjwvc2VsZWN0Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2PlByaW9yaXR5PC9kaXY+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0naGVpZ2h0OjI2cHgnPg0KICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGlkPSJpZHhfZDEyYXV0aCIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IiBvbmNsaWNrPSJ1cGRhdGVXaWZpRGlhbG9nKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPCEtLTxvcHRpb24gdmFsdWU9IjciPldQQTIgSUVFRSA4MDIuMXg8L29wdGlvbj4tLT4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjYiPldQQTIgUFNLDQogICAgICAgICAgICAgICAgICAgICAgICA8IS0tPG9wdGlvbiB2YWx1ZT0iNSI+V1BBIElFRUUgODAyLjF4PC9vcHRpb24+LS0+DQogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSI0Ij5XUEEgUFNLDQogICAgICAgICAgICAgICAgICAgICAgICA8IS0tPG9wdGlvbiB2YWx1ZT0iMyI+U2hhcmVkIEtleTwvb3B0aW9uPi0tPg0KICAgICAgICAgICAgICAgICAgICAgICAgPCEtLTxvcHRpb24gdmFsdWU9IjIiPk9wZW48L29wdGlvbj4tLT4NCiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgIDxkaXY+QXV0aGVudGljYXRpb248L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+DQogICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgaWQ9ImlkeF9kMTJlbmMiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25jbGljaz0idXBkYXRlV2lmaURpYWxvZygpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gaWQ9ImlkX2QxMmU0IiB2YWx1ZT0iNCI+Q0NNUC1BRVMNCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gaWQ9ImlkX2QxMmUzIiB2YWx1ZT0iMyI+VEtJUC1SQzQNCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gaWQ9ImlkX2QxMmUyIiB2YWx1ZT0iMiI+V0VQDQogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIGlkPSJpZF9kMTJlNSIgdmFsdWU9IjUiPk5vbmUNCiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgIDxkaXY+RW5jcnlwdGlvbjwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImlkeF9kMTJwYXNzd29yZDEiIHR5cGU9InBhc3N3b3JkIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiIG1heGxlbmd0aD0iNjMiIG9ua2V5dXA9InVwZGF0ZVdpZmlEaWFsb2coKSIgdGl0bGU9Ikxlbmd0aCBiZXR3ZWVuIDggYW5kIDYzIGNoYXJhY3RlcnMiPjxkaXYgdGl0bGU9Ikxlbmd0aCBiZXR3ZWVuIDggYW5kIDYzIGNoYXJhY3RlcnMiPlBhc3N3b3JkKjwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImlkeF9kMTJwYXNzd29yZDIiIHR5cGU9InBhc3N3b3JkIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiIG1heGxlbmd0aD0iNjMiIG9ua2V5dXA9InVwZGF0ZVdpZmlEaWFsb2coKSIgdGl0bGU9Ikxlbmd0aCBiZXR3ZWVuIDggYW5kIDYzIGNoYXJhY3RlcnMiPjxkaXYgdGl0bGU9Ikxlbmd0aCBiZXR3ZWVuIDggYW5kIDYzIGNoYXJhY3RlcnMiPkNvbmZpcm0gUGFzc3dvcmQ8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMTMiIHN0eWxlPSJtYXJnaW46YXV0bzttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSdkMTN2YWxpZCc+VmFsaWQgUmVjb3JkPGJyPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9J2QxM3NjcmFtYmxlJz5TY3JhbWJsZWQgUmVjb3JkPGJyPg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2cxNCIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz4NCiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBpZD0iaWR4X2QxNHZlcnNpb24iIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCI+DQogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSIxIj5WZXJzaW9uIDENCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjIiPlZlcnNpb24gMg0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMyI+VmVyc2lvbiAzDQogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSI0Ij5WZXJzaW9uIDQNCiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgIDxkaXY+U2V0dXAuYmluIHZlcnNpb248L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+DQogICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgaWQ9ImlkeF9kMTRjb25zdW1lIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMSI+UmVjb3JkcyB3aWxsIG5vdCBiZSBjb25zdW1lZA0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMCI+UmVjb3JkcyB3aWxsIGJlIGNvbnN1bWVkDQogICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2PlJlY29yZCBjb25zdW1wdGlvbjwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2cxNSIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iZDE1c2V0dXBiaW5maWxlIiB0eXBlPSJmaWxlIiBzdHlsZT0id2lkdGg6MTAwJSIgYWNjZXB0PSIuYmluIj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMTYiIHN0eWxlPSJtYXJnaW46YXV0bzttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+DQogICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgaWQ9ImQxNnR5cGUiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyNjBweCIgb25jaGFuZ2U9InVzYl9vbmQxNnR5cGVjaGFuZ2UoKSIgb25jbGljaz0idXNiX29uZDE2dHlwZWNoYW5nZSgpIiBvbnNjcm9sbD0idXNiX29uZDE2dHlwZWNoYW5nZSgpIiBvbmtleWRvd249InVzYl9vbmQxNnR5cGVjaGFuZ2UoKSI+PC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgIDxkaXY+VmFyaWFibGUgVHlwZTwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImQxNmdlbmVyaWN2YWx1ZSIgc3R5bGU9J2hlaWdodDoyNnB4Jz4NCiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBpZD0iaWR4X2QxNnZhbHVlMSIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4Ij48L3NlbGVjdD4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJpZHhfZDE2dmFsdWUyIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHg7ZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGRpdj5WYXJpYWJsZSBWYWx1ZTwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImQxNmN1c3RvbXZhbHVlIj48L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMTkiIHN0eWxlPSJtYXJnaW46YXV0bzttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICBUaGlzIHdpbGwgc2F2ZSB0aGUgZW50aXJlIHN0YXRlIG9mIEludGVsJnJlZzsgQU1UIGZvciB0aGlzIG1hY2hpbmUgaW50byBmaWxlLiBQYXNzd29yZHMgd2lsbCBub3QgYmUgc2F2ZWQsIGJ1dCBzb21lIHNlbnNpdGl2ZSBkYXRhIG1heSBiZSBpbmNsdWRlZC48YnI+PGJyPg0KICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iaWR4X2QxOXNhdmVzdGF0ZWZpbGVuYW1lIiBzdHlsZT0id2lkdGg6MTAwJSIgdmFsdWU9ImFtdHN0YXRlLmpzb24iPg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2cyMCIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJyYWRpbyIgbmFtZT0iZDIwIiBpZD0iZDIwYSIgdmFsdWU9IjAiPkRpc2FibGVkPGJyPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJyYWRpbyIgbmFtZT0iZDIwIiBpZD0iZDIwYiIgdmFsdWU9IjEiPklDTVAgcmVzcG9uc2U8YnI+DQogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJkMjAiIGlkPSJkMjBjIiB2YWx1ZT0iMiI+Uk1DUCByZXNwb25zZTxicj4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0icmFkaW8iIG5hbWU9ImQyMCIgaWQ9ImQyMGQiIHZhbHVlPSIzIj5JQ01QICYgUk1DUCByZXNwb25zZTxicj48YnI+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzIxIiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJkMjEiIGlkPSJkMjFvMCIgb25jbGljaz0idXBkYXRlSVBTZXR1cERsZygpIj48c3BhbiBpZD0iZDIxbDAiPjwvc3Bhbj48YnI+DQogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJkMjEiIGlkPSJkMjFvMSIgb25jbGljaz0idXBkYXRlSVBTZXR1cERsZygpIj48c3BhbiBpZD0iZDIxbDEiPjwvc3Bhbj48YnI+DQogICAgICAgICAgICAgICAgPGRpdiBpZD0iaWRfZDIxbWFudWFsZGl2Ij4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJkMjEiIGlkPSdkMjFvMicgb25jbGljaz0idXBkYXRlSVBTZXR1cERsZygpIj48c3BhbiBpZD0iZDIxbDIiPjwvc3Bhbj48YnI+PGJyPg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJtYXJnaW4tbGVmdDoyMHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4Ij48aW5wdXQgaWQ9ImlkeF9kMjFhZGRyZXNzIiBvbmtleXVwPSJ1cGRhdGVJUFNldHVwRGxnKCkiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMzBweCI+PGRpdj5JUCBhZGRyZXNzPC9kaXY+PC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJoZWlnaHQ6MjZweCIgaWQ9ImlkX2QyMXN1Ym5ldGRpdiI+PGlucHV0IGlkPSJpZHhfZDIxc3VibmV0IiBvbmtleXVwPSJ1cGRhdGVJUFNldHVwRGxnKCkiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMzBweCI+PGRpdj5TdWJuZXQgbWFyazwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iaGVpZ2h0OjI2cHgiPjxpbnB1dCBpZD0iaWR4X2QyMWdhdGV3YXkiIG9ua2V5dXA9InVwZGF0ZUlQU2V0dXBEbGcoKSIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4Ij48ZGl2PkdhdGV3YXk8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4Ij48aW5wdXQgaWQ9ImlkeF9kMjFkbnMxIiBvbmtleXVwPSJ1cGRhdGVJUFNldHVwRGxnKCkiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMzBweCI+PGRpdj5QcmltYXJ5IEROUzwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iaGVpZ2h0OjI2cHgiPjxpbnB1dCBpZD0iaWR4X2QyMWRuczIiIG9ua2V5dXA9InVwZGF0ZUlQU2V0dXBEbGcoKSIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4Ij48ZGl2PkFsdGVybmF0ZSBETlM8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzIzIiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz4NCiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBpZD0iaWR4X2QyM2RkbnMiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25jaGFuZ2U9InNob3dFZGl0RG5zRGxnQ2hhbmdlKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMCI+RGlzYWJsZWQNCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjEiPkRpc2FibGVkLCBESENQIHVwZGF0ZQ0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMiI+RW5hYmxlZA0KICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD4NCiAgICAgICAgICAgICAgICAgICAgPGRpdj5EeW5hbWljIEROUyBjbGllbnQ8L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+PGlucHV0IGlkPSJpZHhfZDIzaW50ZXJ2YWwiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCI+PGRpdj5VcGRhdGUgSW50ZXJ2YWwgKG1pbnV0ZXMpPC9kaXY+PC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0naGVpZ2h0OjI2cHgnPjxpbnB1dCBpZD0iaWR4X2QyM3R0bCIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4Ij48ZGl2PlRUTCAoc2Vjb25kcyk8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJmb250LXNpemU6MTBweCI+PGJyPkRlZmF1dCBJbnRlcnZhbCBpcyAxNDQwIG1pbnV0ZXMsIERlZmF1bHQgVFRMIGlzIDkwMCBzZWNvbmRzLjwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2cyNSIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9InRleHQtYWxpZ246bGVmdCI+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4Ij48aW5wdXQgaWQ9ImQyNWFsYXJtX25hbWUiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoxODBweCIgbWF4bGVuZ3RoPSIzMiIgb25rZXl1cD0iYWxlcnREaWFsb2dVcGRhdGUoKSI+PGRpdiBzdHlsZT0icGFkZGluZy10b3A6NHB4Ij5BbGFybSBuYW1lPC9kaXY+PC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9ImQyNWFsYXJtX3NkYXRlIiBzdHlsZT0id2lkdGg6MTgwcHgiIG1heGxlbmd0aD0iMTAiIG9ua2V5dXA9ImFsZXJ0RGlhbG9nVXBkYXRlKCkiIG9ua2V5cHJlc3M9InJldHVybiBudW1iZXJzT25seShldmVudCw0NSkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJwYWRkaW5nLXRvcDo0cHgiPldha2UgZGF0ZSAoeWVhci1tb250aC1kYXkpPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJoZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweCI+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJmbG9hdDpyaWdodCI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJkMjVhbGFybV9zdGltZSIgc3R5bGU9IndpZHRoOjE4MHB4IiBtYXhsZW5ndGg9IjEwIiBvbmtleXVwPSJhbGVydERpYWxvZ1VwZGF0ZSgpIiBvbmtleXByZXNzPSJyZXR1cm4gbnVtYmVyc09ubHkoZXZlbnQsNTgpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0icGFkZGluZy10b3A6NHB4Ij5XYWtlIHRpbWUgKGhvdXI6bWluOnNlYyk8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9ImQyNWFsYXJtX2ludGVydmFsIiBzdHlsZT0id2lkdGg6MTgwcHgiIG1heGxlbmd0aD0iMTAiIG9ua2V5dXA9ImFsZXJ0RGlhbG9nVXBkYXRlKCkiIG9ua2V5cHJlc3M9InJldHVybiBudW1iZXJzT25seShldmVudCw0NSkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJwYWRkaW5nLXRvcDo0cHgiPkludGVydmFsIChkYXlzLWhvdXJzLW1pbik8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjE4MHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGlkPSJkMjVhbGFybV9kb2MiIHN0eWxlPSJ3aWR0aDoxMDAlIiBvbmNoYW5nZT0ic2hvd0FkdlBvd2VyRGxnQ2hhbmdlKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSIwIj5LZWVwIGFsYXJtDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjEiPkRlbGV0ZSBvbiBjb21wbGV0aW9uDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9InBhZGRpbmctdG9wOjRweCI+QWZ0ZXIgd2FrZTwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgPGRpdiBzdHlsZT0icGFkZGluZzoxMHB4O21hcmdpbi1ib3R0b206NHB4Ij4NCiAgICAgICAgICAgIDxpbnB1dCBpZD0iaWR4X2RsZ0NhbmNlbEJ1dHRvbiIgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iQ2FuY2VsIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6ODBweDttYXJnaW4tbGVmdDo1cHgiIG9uY2xpY2s9ImRpYWxvZ2Nsb3NlKDApIj4NCiAgICAgICAgICAgIDxpbnB1dCBpZD0iaWR4X2RsZ09rQnV0dG9uIiB0eXBlPSJidXR0b24iIHZhbHVlPSJPSyIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjgwcHgiIG9uY2xpY2s9ImRpYWxvZ2Nsb3NlKDEpIj4NCiAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNXB4Ij48aW5wdXQgaWQ9ImlkeF9kbGdEZWxldGVCdXR0b24iIHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkRlbGV0ZSIgc3R5bGU9IndpZHRoOjgwcHg7ZGlzcGxheTpub25lIiBvbmNsaWNrPSJkaWFsb2djbG9zZSgyKSI+PC9kaXY+DQogICAgICAgIDwvZGl2Pg0KICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICANCjwvYm9keT4NCjwvaHRtbD4NCjxzY3JpcHQ+LyoqIA0KKiBAZGVzY3JpcHRpb24gU2V0IG9mIHNob3J0IGNvbW1vbmx5IHVzZWQgbWV0aG9kcyBmb3IgaGFuZGxpbmcgSFRNTCBlbGVtZW50cw0KKiBAYXV0aG9yIFlsaWFuIFNhaW50LUhpbGFpcmUNCiogQHZlcnNpb24gdjAuMC4xYg0KKi8NCg0KLy8gQWRkIHN0YXJ0c1dpdGggZm9yIElFIGJyb3dzZXINCmlmICghU3RyaW5nLnByb3RvdHlwZS5zdGFydHNXaXRoKSB7IFN0cmluZy5wcm90b3R5cGUuc3RhcnRzV2l0aCA9IGZ1bmN0aW9uIChzdHIpIHsgcmV0dXJuIHRoaXMubGFzdEluZGV4T2Yoc3RyLCAwKSA9PT0gMDsgfTsgfQ0KaWYgKCFTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoKSB7IFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGggPSBmdW5jdGlvbiAoc3RyKSB7IHJldHVybiB0aGlzLmluZGV4T2Yoc3RyLCB0aGlzLmxlbmd0aCAtIHN0ci5sZW5ndGgpICE9PSAtMTsgfTsgfQ0KDQovLyBRdWljayBVSSBmdW5jdGlvbnMsIGEgYml0IG9mIGEgcmVwbGFjZW1lbnQgZm9yIGpRdWVyeQ0KLy9mdW5jdGlvbiBRKHgpIHsgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHgpID09IG51bGwpIHsgY29uc29sZS5sb2coJ0ludmFsaWQgZWxlbWVudDogJyArIHgpOyB9IHJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh4KTsgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAiUSINCmZ1bmN0aW9uIFEoeCkgeyByZXR1cm4gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoeCk7IH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIlEiDQpmdW5jdGlvbiBRUyh4KSB7IHRyeSB7IHJldHVybiBRKHgpLnN0eWxlOyB9IGNhdGNoICh4KSB7IH0gfSAgICAgICAgICAgICAgICAgICAgIC8vICJRIiBzdHlsZQ0KZnVuY3Rpb24gUUUoeCwgeSkgeyB0cnkgeyBRKHgpLmRpc2FibGVkID0gIXk7IH0gY2F0Y2ggKHgpIHsgfSB9ICAgICAgICAgICAgICAgICAvLyAiUSIgZW5hYmxlDQpmdW5jdGlvbiBRVih4LCB5KSB7IHRyeSB7IFFTKHgpLmRpc3BsYXkgPSAoeSA/ICcnIDogJ25vbmUnKTsgfSBjYXRjaCAoeCkgeyB9IH0gIC8vICJRIiB2aXNpYmxlDQpmdW5jdGlvbiBRQSh4LCB5KSB7IFEoeCkuaW5uZXJIVE1MICs9IHk7IH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICJRIiBhcHBlbmQNCmZ1bmN0aW9uIFFIKHgsIHkpIHsgUSh4KS5pbm5lckhUTUwgPSB5OyB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIlEiIGh0bWwNCg0KLy8gTW92ZSBjdXJzb3IgdG8gZW5kIG9mIGlucHV0IGJveA0KZnVuY3Rpb24gaW5wdXRCb3hGb2N1cyh4KSB7IFEoeCkuZm9jdXMoKTsgdmFyIHYgPSBRKHgpLnZhbHVlOyBRKHgpLnZhbHVlID0gJyc7IFEoeCkudmFsdWUgPSB2OyB9DQoNCi8vIEJpbmFyeSBlbmNvZGluZyBhbmQgZGVjb2RpbmcgZnVuY3Rpb25zDQpmdW5jdGlvbiBSZWFkU2hvcnQodiwgcCkgeyByZXR1cm4gKHYuY2hhckNvZGVBdChwKSA8PCA4KSArIHYuY2hhckNvZGVBdChwICsgMSk7IH0NCmZ1bmN0aW9uIFJlYWRTaG9ydFgodiwgcCkgeyByZXR1cm4gKHYuY2hhckNvZGVBdChwICsgMSkgPDwgOCkgKyB2LmNoYXJDb2RlQXQocCk7IH0NCmZ1bmN0aW9uIFJlYWRJbnQodiwgcCkgeyByZXR1cm4gKHYuY2hhckNvZGVBdChwKSAqIDB4MTAwMDAwMCkgKyAodi5jaGFyQ29kZUF0KHAgKyAxKSA8PCAxNikgKyAodi5jaGFyQ29kZUF0KHAgKyAyKSA8PCA4KSArIHYuY2hhckNvZGVBdChwICsgMyk7IH0gLy8gV2UgdXNlICIqMHgxMDAwMDAwIiBpbnN0ZWFkIG9mICI8PDI0IiBiZWNhdXNlIHRoZSBzaGlmdCBjb252ZXJ0cyB0aGUgbnVtYmVyIHRvIHNpZ25lZCBpbnQzMi4NCmZ1bmN0aW9uIFJlYWRTSW50KHYsIHApIHsgcmV0dXJuICh2LmNoYXJDb2RlQXQocCkgPDwgMjQpICsgKHYuY2hhckNvZGVBdChwICsgMSkgPDwgMTYpICsgKHYuY2hhckNvZGVBdChwICsgMikgPDwgOCkgKyB2LmNoYXJDb2RlQXQocCArIDMpOyB9DQpmdW5jdGlvbiBSZWFkSW50WCh2LCBwKSB7IHJldHVybiAodi5jaGFyQ29kZUF0KHAgKyAzKSAqIDB4MTAwMDAwMCkgKyAodi5jaGFyQ29kZUF0KHAgKyAyKSA8PCAxNikgKyAodi5jaGFyQ29kZUF0KHAgKyAxKSA8PCA4KSArIHYuY2hhckNvZGVBdChwKTsgfQ0KZnVuY3Rpb24gU2hvcnRUb1N0cih2KSB7IHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKCh2ID4+IDgpICYgMHhGRiwgdiAmIDB4RkYpOyB9DQpmdW5jdGlvbiBTaG9ydFRvU3RyWCh2KSB7IHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKHYgJiAweEZGLCAodiA+PiA4KSAmIDB4RkYpOyB9DQpmdW5jdGlvbiBJbnRUb1N0cih2KSB7IHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKCh2ID4+IDI0KSAmIDB4RkYsICh2ID4+IDE2KSAmIDB4RkYsICh2ID4+IDgpICYgMHhGRiwgdiAmIDB4RkYpOyB9DQpmdW5jdGlvbiBJbnRUb1N0clgodikgeyByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSh2ICYgMHhGRiwgKHYgPj4gOCkgJiAweEZGLCAodiA+PiAxNikgJiAweEZGLCAodiA+PiAyNCkgJiAweEZGKTsgfQ0KZnVuY3Rpb24gTWFrZVRvQXJyYXkodikgeyBpZiAoIXYgfHwgdiA9PSBudWxsIHx8IHR5cGVvZiB2ID09ICdvYmplY3QnKSByZXR1cm4gdjsgcmV0dXJuIFt2XTsgfQ0KZnVuY3Rpb24gU3BsaXRBcnJheSh2KSB7IHJldHVybiB2LnNwbGl0KCcsJyk7IH0NCmZ1bmN0aW9uIENsb25lKHYpIHsgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodikpOyB9DQpmdW5jdGlvbiBFc2NhcGVIdG1sKHgpIHsgaWYgKHR5cGVvZiB4ID09ICJzdHJpbmciKSByZXR1cm4geC5yZXBsYWNlKC8mL2csICcmYW1wOycpLnJlcGxhY2UoLz4vZywgJyZndDsnKS5yZXBsYWNlKC88L2csICcmbHQ7JykucmVwbGFjZSgvIi9nLCAnJnF1b3Q7JykucmVwbGFjZSgvJy9nLCAnJmFwb3M7Jyk7IGlmICh0eXBlb2YgeCA9PSAiYm9vbGVhbiIpIHJldHVybiB4OyBpZiAodHlwZW9mIHggPT0gIm51bWJlciIpIHJldHVybiB4OyB9DQoNCi8vIE1vdmUgYW4gZWxlbWVudCBmcm9tIG9uZSBwb3NpdGlvbiBpbiBhbiBhcnJheSB0byBhIG5ldyBwb3NpdGlvbg0KZnVuY3Rpb24gQXJyYXlFbGVtZW50TW92ZShhcnIsIGZyb20sIHRvKSB7IGFyci5zcGxpY2UodG8sIDAsIGFyci5zcGxpY2UoZnJvbSwgMSlbMF0pOyB9Ow0KDQovLyBQcmludCBvYmplY3QgZm9yIEhUTUwNCmZ1bmN0aW9uIE9iamVjdFRvU3RyaW5nRXgoeCwgYykgew0KICAgIHZhciByID0gIiI7DQogICAgaWYgKHggIT0gMCAmJiAoIXggfHwgeCA9PSBudWxsKSkgcmV0dXJuICIoTnVsbCkiOw0KICAgIGlmICh4IGluc3RhbmNlb2YgQXJyYXkpIHsgZm9yICh2YXIgaSBpbiB4KSB7IHIgKz0gJzxiciAvPicgKyBnYXAoYykgKyAiSXRlbSAjIiArIGkgKyAiOiAiICsgT2JqZWN0VG9TdHJpbmdFeCh4W2ldLCBjICsgMSk7IH0gfQ0KICAgIGVsc2UgaWYgKHggaW5zdGFuY2VvZiBPYmplY3QpIHsgZm9yICh2YXIgaSBpbiB4KSB7IHIgKz0gJzxiciAvPicgKyBnYXAoYykgKyBpICsgIiA9ICIgKyBPYmplY3RUb1N0cmluZ0V4KHhbaV0sIGMgKyAxKTsgfSB9DQogICAgZWxzZSB7IHIgKz0gRXNjYXBlSHRtbCh4KTsgfQ0KICAgIHJldHVybiByOw0KfQ0KDQovLyBQcmludCBvYmplY3QgZm9yIGNvbnNvbGUNCmZ1bmN0aW9uIE9iamVjdFRvU3RyaW5nRXgyKHgsIGMpIHsNCiAgICB2YXIgciA9ICIiOw0KICAgIGlmICh4ICE9IDAgJiYgKCF4IHx8IHggPT0gbnVsbCkpIHJldHVybiAiKE51bGwpIjsNCiAgICBpZiAoeCBpbnN0YW5jZW9mIEFycmF5KSB7IGZvciAodmFyIGkgaW4geCkgeyByICs9ICdcclxuJyArIGdhcDIoYykgKyAiSXRlbSAjIiArIGkgKyAiOiAiICsgT2JqZWN0VG9TdHJpbmdFeDIoeFtpXSwgYyArIDEpOyB9IH0NCiAgICBlbHNlIGlmICh4IGluc3RhbmNlb2YgT2JqZWN0KSB7IGZvciAodmFyIGkgaW4geCkgeyByICs9ICdcclxuJyArIGdhcDIoYykgKyBpICsgIiA9ICIgKyBPYmplY3RUb1N0cmluZ0V4Mih4W2ldLCBjICsgMSk7IH0gfQ0KICAgIGVsc2UgeyByICs9IEVzY2FwZUh0bWwoeCk7IH0NCiAgICByZXR1cm4gcjsNCn0NCg0KLy8gQ3JlYXRlIGFuIGlkZW50IGdhcA0KZnVuY3Rpb24gZ2FwKGMpIHsgdmFyIHggPSAnJzsgZm9yICh2YXIgaSA9IDA7IGkgPCAoYyAqIDQpIDsgaSsrKSB7IHggKz0gJyZuYnNwOyc7IH0gcmV0dXJuIHg7IH0NCmZ1bmN0aW9uIGdhcDIoYykgeyB2YXIgeCA9ICcnOyBmb3IgKHZhciBpID0gMDsgaSA8IChjICogNCkgOyBpKyspIHsgeCArPSAnICc7IH0gcmV0dXJuIHg7IH0NCg0KLy8gUHJpbnQgYW4gb2JqZWN0IGluIGh0bWwNCmZ1bmN0aW9uIE9iamVjdFRvU3RyaW5nKHgpIHsgcmV0dXJuIE9iamVjdFRvU3RyaW5nRXgoeCwgMCk7IH0NCmZ1bmN0aW9uIE9iamVjdFRvU3RyaW5nMih4KSB7IHJldHVybiBPYmplY3RUb1N0cmluZ0V4Mih4LCAwKTsgfQ0KDQovLyBDb252ZXJ0IGEgaGV4IHN0cmluZyB0byBhIHJhdyBzdHJpbmcNCmZ1bmN0aW9uIGhleDJyc3RyKGQpIHsNCiAgICBpZiAodHlwZW9mIGQgIT0gInN0cmluZyIgfHwgZC5sZW5ndGggPT0gMCkgcmV0dXJuICcnOw0KICAgIHZhciByID0gJycsIG0gPSAoJycgKyBkKS5tYXRjaCgvLi4vZyksIHQ7DQogICAgd2hpbGUgKHQgPSBtLnNoaWZ0KCkpIHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgnMHgnICsgdCk7DQogICAgcmV0dXJuIHINCn0NCg0KLy8gQ29udmVydCBkZWNpbWFsIHRvIGhleA0KZnVuY3Rpb24gY2hhcjJoZXgoaSkgeyByZXR1cm4gKGkgKyAweDEwMCkudG9TdHJpbmcoMTYpLnN1YnN0cigtMikudG9VcHBlckNhc2UoKTsgfQ0KDQovLyBDb252ZXJ0IGEgcmF3IHN0cmluZyB0byBhIGhleCBzdHJpbmcNCmZ1bmN0aW9uIHJzdHIyaGV4KGlucHV0KSB7DQogICAgdmFyIHIgPSAnJywgaTsNCiAgICBmb3IgKGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHsgciArPSBjaGFyMmhleChpbnB1dC5jaGFyQ29kZUF0KGkpKTsgfQ0KICAgIHJldHVybiByOw0KfQ0KDQovLyBVVEYtOCBlbmNvZGluZyAmIGRlY29kaW5nIGZ1bmN0aW9ucw0KZnVuY3Rpb24gZW5jb2RlX3V0ZjgocykgeyByZXR1cm4gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KHMpKTsgfQ0KZnVuY3Rpb24gZGVjb2RlX3V0ZjgocykgeyByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZShzKSk7IH0NCg0KLy8gQ29udmVydCBhIHN0cmluZyBpbnRvIGEgYmxvYg0KZnVuY3Rpb24gZGF0YTJibG9iKGRhdGEpIHsNCiAgICB2YXIgYnl0ZXMgPSBuZXcgQXJyYXkoZGF0YS5sZW5ndGgpOw0KICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykgYnl0ZXNbaV0gPSBkYXRhLmNoYXJDb2RlQXQoaSk7DQogICAgdmFyIGJsb2IgPSBuZXcgQmxvYihbbmV3IFVpbnQ4QXJyYXkoYnl0ZXMpXSk7DQogICAgcmV0dXJuIGJsb2I7DQp9DQoNCi8vIEdlbmVyYXRlIHJhbmRvbSBudW1iZXJzDQpmdW5jdGlvbiByYW5kb20obWF4KSB7IHJldHVybiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBtYXgpOyB9DQoNCi8vIFRyYWRlbWFya3MNCmZ1bmN0aW9uIHRyYWRlbWFya3MoeCkgeyByZXR1cm4geC5yZXBsYWNlKC9cKFJcKS9nLCAnJnJlZzsnKS5yZXBsYWNlKC9cKFRNXCkvZywgJyZ0cmFkZTsnKTsgfQ0KDQoNCi8qKiANCiogQGRlc2NyaXB0aW9uIEludGVsIEFNVCBMTVMgY29udHJvbCBtb2R1bGUgLSB1c2luZyB3ZWJzb2NrZXQNCiogQGF1dGhvciBZbGlhbiBTYWludC1IaWxhaXJlDQoqIEB2ZXJzaW9uIHYwLjAuMQ0KKi8NCg0KLy8gQ29uc3RydWN0IGEgTE1TIGNvbnRyb2wgb2JqZWN0DQp2YXIgQ3JlYXRlTG1zQ29udHJvbCA9IGZ1bmN0aW9uICgpIHsNCiAgICB2YXIgb2JqID0ge307DQogICAgdmFyIHNvY2tldCA9IG51bGw7DQogICAgb2JqLlN0YXRlID0gMDsNCiAgICBvYmoub25TdGF0ZUNoYW5nZWQgPSBudWxsOw0KICAgIG9iai5vbkRhdGEgPSBudWxsOw0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBvYmouU3RhcnQgPSBmdW5jdGlvbiAoKSB7DQogICAgICAgIHNvY2tldCA9IG5ldyBXZWJTb2NrZXQod2luZG93LmxvY2F0aW9uLnByb3RvY29sLnJlcGxhY2UoImh0dHAiLCAid3MiKSArICIvLyIgKyB3aW5kb3cubG9jYXRpb24uaG9zdCArICIvbG1zLmFzaHgiKTsNCiAgICAgICAgc29ja2V0Lm9ub3BlbiA9IF9PblNvY2tldENvbm5lY3RlZDsNCiAgICAgICAgc29ja2V0Lm9ubWVzc2FnZSA9IF9Pbk1lc3NhZ2U7DQogICAgICAgIHNvY2tldC5vbmNsb3NlID0gb2JqLlN0b3A7DQogICAgICAgIF9TdGF0ZUNoYW5nZSgxKTsNCiAgICB9DQoNCiAgICBmdW5jdGlvbiBfT25Tb2NrZXRDb25uZWN0ZWQoKSB7DQogICAgICAgIF9TdGF0ZUNoYW5nZSgyKTsNCiAgICB9DQoNCiAgICAvLyBTZXR1cCB0aGUgZmlsZSByZWFkZXINCiAgICB2YXIgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQogICAgdmFyIGZpbGVSZWFkZXJJbnVzZSA9IGZhbHNlLCBmaWxlUmVhZGVyQWNjID0gW107DQogICAgaWYgKGZpbGVSZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKSB7DQogICAgICAgIC8vIENocm9tZSAmIEZpcmVmb3ggKERyYWZ0KQ0KICAgICAgICBmaWxlUmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uIChlKSB7IF9PblNvY2tldERhdGEoZS50YXJnZXQucmVzdWx0KTsgaWYgKGZpbGVSZWFkZXJBY2MubGVuZ3RoID09IDApIHsgZmlsZVJlYWRlckludXNlID0gZmFsc2U7IH0gZWxzZSB7IGZpbGVSZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKG5ldyBCbG9iKFtmaWxlUmVhZGVyQWNjLnNoaWZ0KCldKSk7IH0gfQ0KICAgIH0gZWxzZSBpZiAoZmlsZVJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcikgew0KICAgICAgICAvLyBDaHJvbWUgJiBGaXJlZm94IChTcGVjKQ0KICAgICAgICBmaWxlUmVhZGVyLm9ubG9hZGVuZCA9IGZ1bmN0aW9uIChlKSB7IF9PblNvY2tldERhdGEoZS50YXJnZXQucmVzdWx0KTsgaWYgKGZpbGVSZWFkZXJBY2MubGVuZ3RoID09IDApIHsgZmlsZVJlYWRlckludXNlID0gZmFsc2U7IH0gZWxzZSB7IGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZmlsZVJlYWRlckFjYy5zaGlmdCgpKTsgfSB9DQogICAgfQ0KDQogICAgZnVuY3Rpb24gX09uTWVzc2FnZShlKSB7DQogICAgICAgIGlmICh0eXBlb2YgZS5kYXRhID09ICdvYmplY3QnKSB7DQogICAgICAgICAgICBpZiAoZmlsZVJlYWRlckludXNlID09IHRydWUpIHsgZmlsZVJlYWRlckFjYy5wdXNoKGUuZGF0YSk7IHJldHVybjsgfQ0KICAgICAgICAgICAgaWYgKGZpbGVSZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKSB7DQogICAgICAgICAgICAgICAgLy8gQ2hyb21lICYgRmlyZWZveCAoRHJhZnQpDQogICAgICAgICAgICAgICAgZmlsZVJlYWRlckludXNlID0gdHJ1ZTsNCiAgICAgICAgICAgICAgICBmaWxlUmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyhuZXcgQmxvYihbZS5kYXRhXSkpOw0KICAgICAgICAgICAgfSBlbHNlIGlmIChmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKSB7DQogICAgICAgICAgICAgICAgLy8gQ2hyb21lICYgRmlyZWZveCAoU3BlYykNCiAgICAgICAgICAgICAgICBmaWxlUmVhZGVySW51c2UgPSB0cnVlOw0KICAgICAgICAgICAgICAgIGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZS5kYXRhKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gSUUxMCwgcmVhZEFzQmluYXJ5U3RyaW5nIGRvZXMgbm90IGV4aXN0LCB1c2UgYW4gYWx0ZXJuYXRpdmUuDQogICAgICAgICAgICAgICAgdmFyIGJpbmFyeSA9ICIiLCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGUuZGF0YSksIGxlbmd0aCA9IGJ5dGVzLmJ5dGVMZW5ndGg7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7IH0NCiAgICAgICAgICAgICAgICBfT25Tb2NrZXREYXRhKGJpbmFyeSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBfT25Tb2NrZXREYXRhKGUuZGF0YSk7DQogICAgICAgIH0NCiAgICB9Ow0KICAgDQogICAgZnVuY3Rpb24gX09uU29ja2V0RGF0YShkYXRhKSB7DQogICAgICAgIGlmICghZGF0YSkgcmV0dXJuOw0KDQogICAgICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcpIHsNCiAgICAgICAgICAgIC8vIFRoaXMgaXMgYW4gQXJyYXlCdWZmZXIsIGNvbnZlcnQgaXQgdG8gYSBzdHJpbmcgYXJyYXkgKHVzZWQgaW4gSUUpDQogICAgICAgICAgICB2YXIgYmluYXJ5ID0gIiI7DQogICAgICAgICAgICB2YXIgYnl0ZXMgPSBuZXcgVWludDhBcnJheShkYXRhKTsNCiAgICAgICAgICAgIHZhciBsZW5ndGggPSBieXRlcy5ieXRlTGVuZ3RoOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7IH0NCiAgICAgICAgICAgIGRhdGEgPSBiaW5hcnk7DQogICAgICAgIH0NCiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRhdGEgIT09ICdzdHJpbmcnKSB7IHJldHVybjsgfQ0KDQogICAgICAgIC8vIFNlbmQgdGhlIGRhdGEgdXANCiAgICAgICAgaWYgKG9iai5vbkRhdGEgIT0gbnVsbCkgb2JqLm9uRGF0YShvYmosIGRhdGEpOw0KICAgIH0NCiAgICANCiAgICBmdW5jdGlvbiBfU2VuZCh4KSB7DQogICAgICAgIGlmIChzb2NrZXQgIT0gbnVsbCAmJiBzb2NrZXQucmVhZHlTdGF0ZSA9PSBXZWJTb2NrZXQuT1BFTikgew0KICAgICAgICAgICAgdmFyIGIgPSBuZXcgVWludDhBcnJheSh4Lmxlbmd0aCk7DQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyArK2kpIHsgYltpXSA9IHguY2hhckNvZGVBdChpKTsgfQ0KICAgICAgICAgICAgc29ja2V0LnNlbmQoYi5idWZmZXIpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgb2JqLlNlbmRDbWQgPSBmdW5jdGlvbiAoY21kaWQsIGRhdGEpIHsNCiAgICAgICAgaWYgKHNvY2tldCA9PSBudWxsIHx8IG9iai5TdGF0ZSAhPSAyKSByZXR1cm47DQogICAgICAgIGlmICghZGF0YSB8fCBkYXRhID09IG51bGwpIGRhdGEgPSAiIjsNCiAgICAgICAgX1NlbmQoU2hvcnRUb1N0clgoY21kaWQpICsgZGF0YSk7DQogICAgfQ0KDQogICAgZnVuY3Rpb24gX1N0YXRlQ2hhbmdlKG5ld3N0YXRlKSB7DQogICAgICAgIGlmIChvYmouU3RhdGUgPT0gbmV3c3RhdGUpIHJldHVybjsNCiAgICAgICAgb2JqLlN0YXRlID0gbmV3c3RhdGU7DQogICAgICAgIGlmIChvYmoub25TdGF0ZUNoYW5nZWQgIT0gbnVsbCkgb2JqLm9uU3RhdGVDaGFuZ2VkKG9iaiwgb2JqLlN0YXRlKTsNCiAgICB9DQoNCiAgICBvYmouU3RvcCA9IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgX1N0YXRlQ2hhbmdlKDApOw0KICAgICAgICBpZiAoc29ja2V0ICE9IG51bGwpIHsgc29ja2V0LmNsb3NlKCk7IHNvY2tldCA9IG51bGw7IH0NCiAgICB9DQoNCiAgICByZXR1cm4gb2JqOw0KfS8qKiANCiogQGRlc2NyaXB0aW9uIFdTTUFOIGNvbW11bmljYXRpb24gdXNpbmcgd2Vic29ja2V0DQoqIEBhdXRob3IgWWxpYW4gU2FpbnQtSGlsYWlyZQ0KKiBAdmVyc2lvbiB2MC4yLjBjDQoqLw0KDQovLyBDb25zdHJ1Y3QgYSBXU01BTiBjb21tdW5pY2F0aW9uIG9iamVjdA0KdmFyIENyZWF0ZVdzbWFuQ29tbSA9IGZ1bmN0aW9uIChob3N0LCBwb3J0LCB1c2VyLCBwYXNzLCB0bHMpIHsNCiAgICB2YXIgb2JqID0ge307DQogICAgb2JqLlBlbmRpbmdBamF4ID0gW107ICAgICAgICAgICAgICAgLy8gTGlzdCBvZiBwZW5kaW5nIEFKQVggY2FsbHMuIFdoZW4gb25lIGZyZWVzIHVwLCBhbm90aGVyIHdpbGwgc3RhcnQuDQogICAgb2JqLkFjdGl2ZUFqYXhDb3VudCA9IDA7ICAgICAgICAgICAgLy8gTnVtYmVyIG9mIGN1cnJlbnRseSBhY3RpdmUgQUpBWCBjYWxscw0KICAgIG9iai5NYXhBY3RpdmVBamF4Q291bnQgPSAxOyAgICAgICAgIC8vIE1heGltdW0gbnVtYmVyIG9mIGFjdGl2YXRlIEFKQVggY2FsbHMgYXQgdGhlIHNhbWUgdGltZS4NCiAgICBvYmouRmFpbEFsbEVycm9yID0gMDsgICAgICAgICAgICAgICAvLyBTZXQgdGhpcyB0byBub24temVybyB0byBmYWlsIGFsbCBBSkFYIGNhbGxzIHdpdGggdGhhdCBlcnJvciBzdGF0dXMsIDk5OSBjYXVzZXMgcmVzcG9uc2VzIHRvIGJlIHNpbGVudC4NCiAgICBvYmouY2hhbGxlbmdlUGFyYW1zID0gbnVsbDsNCiAgICBvYmoubm9uY2Vjb3VudGVyID0gMTsNCiAgICBvYmouYXV0aGNvdW50ZXIgPSAwOw0KICAgIG9iai5zb2NrZXQgPSBudWxsOw0KICAgIG9iai5zb2NrZXRTdGF0ZSA9IDA7DQogICAgb2JqLmhvc3QgPSBob3N0Ow0KICAgIG9iai5wb3J0ID0gcG9ydDsNCiAgICBvYmoudXNlciA9IHVzZXI7DQogICAgb2JqLnBhc3MgPSBwYXNzOw0KICAgIG9iai50bHMgPSB0bHM7DQogICAgb2JqLnRsc3Yxb25seSA9IDA7DQogICAgb2JqLmNub25jZSA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZyg3KTsgLy8gR2VuZXJhdGUgYSByYW5kb20gY2xpZW50IG5vbmNlDQogICAgb2JqLmluRGF0YUNvdW50ID0gMDsNCiAgICBvYmouYW10VmVyc2lvbiA9IG51bGw7DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIC8vb2JqLkRlYnVnID0gZnVuY3Rpb24gKG1zZykgeyBjb25zb2xlLmxvZyhtc2cpOyB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIC8vICAgcHJpID0gcHJpb3JpdHksIGlmIHNldCB0byAxLCB0aGUgY2FsbCBpcyBoaWdoIHByaW9yaXR5IGFuZCBwdXQgb24gdG9wIG9mIHRoZSBzdGFjay4NCiAgICBvYmouUGVyZm9ybUFqYXggPSBmdW5jdGlvbiAocG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHByaSwgdXJsLCBhY3Rpb24pIHsNCiAgICAgICAgaWYgKG9iai5BY3RpdmVBamF4Q291bnQgPCBvYmouTWF4QWN0aXZlQWpheENvdW50ICYmIG9iai5QZW5kaW5nQWpheC5sZW5ndGggPT0gMCkgew0KICAgICAgICAgICAgLy8gVGhlcmUgYXJlIG5vIHBlbmRpbmcgQUpBWCBjYWxscywgcGVyZm9ybSB0aGUgY2FsbCBub3cuDQogICAgICAgICAgICBvYmouUGVyZm9ybUFqYXhFeChwb3N0ZGF0YSwgY2FsbGJhY2ssIHRhZywgdXJsLCBhY3Rpb24pOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhIGhpZ2ggcHJpb3JpdHkgY2FsbCwgcHV0IHRoaXMgY2FsbCBpbiBmcm9udCBvZiB0aGUgYXJyYXksIG90aGVyd2lzZSBwdXQgaXQgaW4gdGhlIGJhY2suDQogICAgICAgICAgICBpZiAocHJpID09IDEpIHsgb2JqLlBlbmRpbmdBamF4LnVuc2hpZnQoW3Bvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCB1cmwsIGFjdGlvbl0pOyB9IGVsc2UgeyBvYmouUGVuZGluZ0FqYXgucHVzaChbcG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHVybCwgYWN0aW9uXSk7IH0NCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIC8vIFByaXZhdGUgbWV0aG9kDQogICAgb2JqLlBlcmZvcm1OZXh0QWpheCA9IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgaWYgKG9iai5BY3RpdmVBamF4Q291bnQgPj0gb2JqLk1heEFjdGl2ZUFqYXhDb3VudCB8fCBvYmouUGVuZGluZ0FqYXgubGVuZ3RoID09IDApIHJldHVybjsNCiAgICAgICAgdmFyIHggPSBvYmouUGVuZGluZ0FqYXguc2hpZnQoKTsNCiAgICAgICAgb2JqLlBlcmZvcm1BamF4RXgoeFswXSwgeFsxXSwgeFsyXSwgeFszXSwgeFs0XSk7DQogICAgICAgIG9iai5QZXJmb3JtTmV4dEFqYXgoKTsNCiAgICB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIG9iai5QZXJmb3JtQWpheEV4ID0gZnVuY3Rpb24gKHBvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCB1cmwsIGFjdGlvbikgew0KICAgICAgICBpZiAob2JqLkZhaWxBbGxFcnJvciAhPSAwKSB7IG9iai5nb3ROZXh0TWVzc2FnZXNFcnJvcih7IHN0YXR1czogb2JqLkZhaWxBbGxFcnJvciB9LCAnZXJyb3InLCBudWxsLCBbcG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHVybCwgYWN0aW9uXSk7IHJldHVybjsgfQ0KICAgICAgICBpZiAoIXBvc3RkYXRhKSBwb3N0ZGF0YSA9ICIiOw0KICAgICAgICAvL2NvbnNvbGUubG9nKCJTRU5EOiAiICsgcG9zdGRhdGEpOyAvLyBERUJVRw0KDQogICAgICAgIC8vIFdlIGFyZSBpbiBhIHdlYnNvY2tldCByZWxheSBlbnZpcm9ubWVudCANCiAgICAgICAgb2JqLkFjdGl2ZUFqYXhDb3VudCsrOw0KICAgICAgICByZXR1cm4gb2JqLlBlcmZvcm1BamF4RXhOb2RlSlMocG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHVybCwgYWN0aW9uKTsNCiAgICB9DQoNCiAgICAvLyBXZWJzb2NrZXQgcmVsYXkgc3BlY2lmaWMgcHJpdmF0ZSBtZXRob2QNCiAgICBvYmoucGVuZGluZ0FqYXhDYWxsID0gW107DQoNCiAgICAvLyBXZWJzb2NrZXQgcmVsYXkgc3BlY2lmaWMgcHJpdmF0ZSBtZXRob2QNCiAgICBvYmouUGVyZm9ybUFqYXhFeE5vZGVKUyA9IGZ1bmN0aW9uIChwb3N0ZGF0YSwgY2FsbGJhY2ssIHRhZywgdXJsLCBhY3Rpb24pIHsgb2JqLlBlcmZvcm1BamF4RXhOb2RlSlMyKHBvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCB1cmwsIGFjdGlvbiwgMyk7IH0NCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZA0KICAgIG9iai5QZXJmb3JtQWpheEV4Tm9kZUpTMiA9IGZ1bmN0aW9uIChwb3N0ZGF0YSwgY2FsbGJhY2ssIHRhZywgdXJsLCBhY3Rpb24sIHJldHJ5KSB7DQogICAgICAgIGlmIChyZXRyeSA8PSAwIHx8IG9iai5GYWlsQWxsRXJyb3IgIT0gMCkgew0KICAgICAgICAgICAgLy8gVG9vIG1hbnkgcmV0cnksIGZhaWwgaGVyZS4NCiAgICAgICAgICAgIG9iai5BY3RpdmVBamF4Q291bnQtLTsNCiAgICAgICAgICAgIGlmIChvYmouRmFpbEFsbEVycm9yICE9IDk5OSkgb2JqLmdvdE5leHRNZXNzYWdlcyhudWxsLCAnZXJyb3InLCB7IHN0YXR1czogKChvYmouRmFpbEFsbEVycm9yID09IDApID8gNDA4IDogb2JqLkZhaWxBbGxFcnJvcikgfSwgW3Bvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCB1cmwsIGFjdGlvbl0pOyAvLyA0MDggaXMgdGltZW91dCBlcnJvcg0KICAgICAgICAgICAgb2JqLlBlcmZvcm1OZXh0QWpheCgpOw0KICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICB9DQogICAgICAgIG9iai5wZW5kaW5nQWpheENhbGwucHVzaChbcG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHVybCwgYWN0aW9uLCByZXRyeV0pOw0KICAgICAgICBpZiAob2JqLnNvY2tldFN0YXRlID09IDApIHsgb2JqLnh4Q29ubmVjdEh0dHBTb2NrZXQoKTsgfQ0KICAgICAgICBlbHNlIGlmIChvYmouc29ja2V0U3RhdGUgPT0gMikgeyBvYmouc2VuZFJlcXVlc3QocG9zdGRhdGEsIHVybCwgYWN0aW9uKTsgfQ0KICAgIH0NCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZCAoQ29udGVudCBMZW5ndGggRW5jb2RpbmcpDQogICAgb2JqLnNlbmRSZXF1ZXN0ID0gZnVuY3Rpb24gKHBvc3RkYXRhLCB1cmwsIGFjdGlvbikgew0KICAgICAgICB1cmwgPSB1cmwgPyB1cmwgOiAiL3dzbWFuIjsNCiAgICAgICAgYWN0aW9uID0gYWN0aW9uID8gYWN0aW9uIDogIlBPU1QiOw0KICAgICAgICB2YXIgaCA9IGFjdGlvbiArICIgIiArIHVybCArICIgSFRUUC8xLjFcclxuIjsNCiAgICAgICAgaWYgKG9iai5jaGFsbGVuZ2VQYXJhbXMgIT0gbnVsbCkgew0KICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gaGV4X21kNShoZXhfbWQ1KG9iai51c2VyICsgJzonICsgb2JqLmNoYWxsZW5nZVBhcmFtc1sicmVhbG0iXSArICc6JyArIG9iai5wYXNzKSArICc6JyArIG9iai5jaGFsbGVuZ2VQYXJhbXNbIm5vbmNlIl0gKyAnOicgKyBvYmoubm9uY2Vjb3VudGVyICsgJzonICsgb2JqLmNub25jZSArICc6JyArIG9iai5jaGFsbGVuZ2VQYXJhbXNbInFvcCJdICsgJzonICsgaGV4X21kNShhY3Rpb24gKyAnOicgKyB1cmwpKTsNCiAgICAgICAgICAgIGggKz0gJ0F1dGhvcml6YXRpb246ICcgKyBvYmoucmVuZGVyRGlnZXN0KHsgInVzZXJuYW1lIjogb2JqLnVzZXIsICJyZWFsbSI6IG9iai5jaGFsbGVuZ2VQYXJhbXNbInJlYWxtIl0sICJub25jZSI6IG9iai5jaGFsbGVuZ2VQYXJhbXNbIm5vbmNlIl0sICJ1cmkiOiB1cmwsICJxb3AiOiBvYmouY2hhbGxlbmdlUGFyYW1zWyJxb3AiXSwgInJlc3BvbnNlIjogcmVzcG9uc2UsICJuYyI6IG9iai5ub25jZWNvdW50ZXIrKywgImNub25jZSI6IG9iai5jbm9uY2UgfSkgKyAnXHJcbic7DQogICAgICAgIH0NCiAgICAgICAgaCArPSAnSG9zdDogJyArIG9iai5ob3N0ICsgJzonICsgb2JqLnBvcnQgKyAnXHJcbkNvbnRlbnQtTGVuZ3RoOiAnICsgcG9zdGRhdGEubGVuZ3RoICsgJ1xyXG5cclxuJyArIHBvc3RkYXRhOyAvLyBVc2UgQ29udGVudC1MZW5ndGgNCiAgICAgICAgLy9oICs9ICdIb3N0OiAnICsgb2JqLmhvc3QgKyAnOicgKyBvYmoucG9ydCArICdcclxuVHJhbnNmZXItRW5jb2Rpbmc6IGNodW5rZWRcclxuXHJcbicgKyBwb3N0ZGF0YS5sZW5ndGgudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCkgKyAnXHJcbicgKyBwb3N0ZGF0YSArICdcclxuMFxyXG5cclxuJzsgLy8gVXNlIENodW5rZWQtRW5jb2RpbmcNCiAgICAgICAgX1NlbmQoaCk7DQogICAgfQ0KDQogICAgLy8gV2Vic29ja2V0IHJlbGF5IHNwZWNpZmljIHByaXZhdGUgbWV0aG9kDQogICAgb2JqLnBhcnNlRGlnZXN0ID0gZnVuY3Rpb24gKGhlYWRlcikgew0KICAgICAgICB2YXIgdCA9IGhlYWRlci5zdWJzdHJpbmcoNykuc3BsaXQoJywnKTsNCiAgICAgICAgZm9yIChpIGluIHQpIHRbaV0gPSB0W2ldLnRyaW0oKTsNCiAgICAgICAgcmV0dXJuIHQucmVkdWNlKGZ1bmN0aW9uIChvYmosIHMpIHsgdmFyIHBhcnRzID0gcy5zcGxpdCgnPScpOyBvYmpbcGFydHNbMF1dID0gcGFydHNbMV0ucmVwbGFjZSgvIi9nLCAnJyk7IHJldHVybiBvYmo7IH0sIHt9KQ0KICAgIH0NCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZA0KICAgIG9iai5yZW5kZXJEaWdlc3QgPSBmdW5jdGlvbiAocGFyYW1zKSB7DQogICAgICAgIHZhciBwYXJhbXNuYW1lcyA9IFtdOw0KICAgICAgICBmb3IgKGkgaW4gcGFyYW1zKSB7IHBhcmFtc25hbWVzLnB1c2goaSk7IH0NCiAgICAgICAgcmV0dXJuICdEaWdlc3QgJyArIHBhcmFtc25hbWVzLnJlZHVjZShmdW5jdGlvbiAoczEsIGlpKSB7IHJldHVybiBzMSArICcsJyArIGlpICsgJz0iJyArIHBhcmFtc1tpaV0gKyAnIicgfSwgJycpLnN1YnN0cmluZygxKTsNCiAgICB9DQoNCiAgICAvLyBXZWJzb2NrZXQgcmVsYXkgc3BlY2lmaWMgcHJpdmF0ZSBtZXRob2QNCiAgICBvYmoueHhDb25uZWN0SHR0cFNvY2tldCA9IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgLy9vYmouRGVidWcoInh4Q29ubmVjdEh0dHBTb2NrZXQiKTsNCiAgICAgICAgb2JqLmluRGF0YUNvdW50ID0gMDsNCiAgICAgICAgb2JqLnNvY2tldFN0YXRlID0gMTsNCiAgICAgICAgb2JqLnNvY2tldCA9IG5ldyBXZWJTb2NrZXQod2luZG93LmxvY2F0aW9uLnByb3RvY29sLnJlcGxhY2UoImh0dHAiLCAid3MiKSArICIvLyIgKyB3aW5kb3cubG9jYXRpb24uaG9zdCArIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZS5zdWJzdHJpbmcoMCwgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLmxhc3RJbmRleE9mKCcvJykpICsgIi93ZWJyZWxheS5hc2h4P3A9MSZob3N0PSIgKyBvYmouaG9zdCArICImcG9ydD0iICsgb2JqLnBvcnQgKyAiJnRscz0iICsgb2JqLnRscyArICImdGxzMW9ubHk9IiArIG9iai50bHN2MW9ubHkgKyAoKHVzZXIgPT0gJyonKSA/ICImc2VydmVyYXV0aD0xIiA6ICIiKSArICgodHlwZW9mIHBhc3MgPT09ICJ1bmRlZmluZWQiKSA/ICgiJnNlcnZlcmF1dGg9MSZ1c2VyPSIgKyB1c2VyKSA6ICIiKSk7IC8vIFRoZSAicD0xIiBpbmRpY2F0ZXMgdG8gdGhlIHJlbGF5IHRoYXQgdGhpcyBpcyBhIFdTTUFOIHNlc3Npb24NCiAgICAgICAgb2JqLnNvY2tldC5vbm9wZW4gPSBfT25Tb2NrZXRDb25uZWN0ZWQ7DQogICAgICAgIG9iai5zb2NrZXQub25tZXNzYWdlID0gX09uTWVzc2FnZTsNCiAgICAgICAgb2JqLnNvY2tldC5vbmNsb3NlID0gX09uU29ja2V0Q2xvc2VkOw0KICAgIH0NCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZA0KICAgIGZ1bmN0aW9uIF9PblNvY2tldENvbm5lY3RlZCgpIHsNCiAgICAgICAgb2JqLnNvY2tldFN0YXRlID0gMjsNCiAgICAgICAgb2JqLnNvY2tldFBhcnNlU3RhdGUgPSAwOw0KICAgICAgICBvYmouc29ja2V0QWNjdW11bGF0b3IgPSAnJzsNCiAgICAgICAgb2JqLnNvY2tldEhlYWRlciA9IG51bGw7DQogICAgICAgIG9iai5zb2NrZXREYXRhID0gJyc7DQogICAgICAgIC8vY29uc29sZS5sb2coInh4T25Tb2NrZXRDb25uZWN0ZWQiKTsNCiAgICAgICAgZm9yIChpIGluIG9iai5wZW5kaW5nQWpheENhbGwpIHsgb2JqLnNlbmRSZXF1ZXN0KG9iai5wZW5kaW5nQWpheENhbGxbaV1bMF0sIG9iai5wZW5kaW5nQWpheENhbGxbaV1bM10sIG9iai5wZW5kaW5nQWpheENhbGxbaV1bNF0pOyB9DQogICAgfQ0KDQogICAgLy8gU2V0dXAgdGhlIGZpbGUgcmVhZGVyDQogICAgdmFyIGZpbGVSZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpOw0KICAgIHZhciBmaWxlUmVhZGVySW51c2UgPSBmYWxzZSwgZmlsZVJlYWRlckFjYyA9IFtdOw0KICAgIGlmIChmaWxlUmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZykgew0KICAgICAgICAvLyBDaHJvbWUgJiBGaXJlZm94IChEcmFmdCkNCiAgICAgICAgZmlsZVJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoZSkgeyBfT25Tb2NrZXREYXRhKGUudGFyZ2V0LnJlc3VsdCk7IGlmIChmaWxlUmVhZGVyQWNjLmxlbmd0aCA9PSAwKSB7IGZpbGVSZWFkZXJJbnVzZSA9IGZhbHNlOyB9IGVsc2UgeyBmaWxlUmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyhuZXcgQmxvYihbZmlsZVJlYWRlckFjYy5zaGlmdCgpXSkpOyB9IH0NCiAgICB9IGVsc2UgaWYgKGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIpIHsNCiAgICAgICAgLy8gQ2hyb21lICYgRmlyZWZveCAoU3BlYykNCiAgICAgICAgZmlsZVJlYWRlci5vbmxvYWRlbmQgPSBmdW5jdGlvbiAoZSkgeyBfT25Tb2NrZXREYXRhKGUudGFyZ2V0LnJlc3VsdCk7IGlmIChmaWxlUmVhZGVyQWNjLmxlbmd0aCA9PSAwKSB7IGZpbGVSZWFkZXJJbnVzZSA9IGZhbHNlOyB9IGVsc2UgeyBmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGZpbGVSZWFkZXJBY2Muc2hpZnQoKSk7IH0gfQ0KICAgIH0NCg0KICAgIGZ1bmN0aW9uIF9Pbk1lc3NhZ2UoZSkgew0KICAgICAgICBpZiAodHlwZW9mIGUuZGF0YSA9PSAnb2JqZWN0Jykgew0KICAgICAgICAgICAgaWYgKGZpbGVSZWFkZXJJbnVzZSA9PSB0cnVlKSB7IGZpbGVSZWFkZXJBY2MucHVzaChlLmRhdGEpOyByZXR1cm47IH0NCiAgICAgICAgICAgIGlmIChmaWxlUmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZykgew0KICAgICAgICAgICAgICAgIC8vIENocm9tZSAmIEZpcmVmb3ggKERyYWZ0KQ0KICAgICAgICAgICAgICAgIGZpbGVSZWFkZXJJbnVzZSA9IHRydWU7DQogICAgICAgICAgICAgICAgZmlsZVJlYWRlci5yZWFkQXNCaW5hcnlTdHJpbmcobmV3IEJsb2IoW2UuZGF0YV0pKTsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAoZmlsZVJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcikgew0KICAgICAgICAgICAgICAgIC8vIENocm9tZSAmIEZpcmVmb3ggKFNwZWMpDQogICAgICAgICAgICAgICAgZmlsZVJlYWRlckludXNlID0gdHJ1ZTsNCiAgICAgICAgICAgICAgICBmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGUuZGF0YSk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIC8vIElFMTAsIHJlYWRBc0JpbmFyeVN0cmluZyBkb2VzIG5vdCBleGlzdCwgdXNlIGFuIGFsdGVybmF0aXZlLg0KICAgICAgICAgICAgICAgIHZhciBiaW5hcnkgPSAiIiwgYnl0ZXMgPSBuZXcgVWludDhBcnJheShlLmRhdGEpLCBsZW5ndGggPSBieXRlcy5ieXRlTGVuZ3RoOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsgYmluYXJ5ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0pOyB9DQogICAgICAgICAgICAgICAgX09uU29ja2V0RGF0YShiaW5hcnkpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgX09uU29ja2V0RGF0YShlLmRhdGEpOw0KICAgICAgICB9DQogICAgfTsNCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZA0KICAgIGZ1bmN0aW9uIF9PblNvY2tldERhdGEoZGF0YSkgew0KICAgICAgICAvL29iai5EZWJ1ZygiX09uU29ja2V0RGF0YSAoIiArIGRhdGEubGVuZ3RoICsgIik6ICIgKyBkYXRhKTsNCg0KICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT09ICdvYmplY3QnKSB7DQogICAgICAgICAgICAvLyBUaGlzIGlzIGFuIEFycmF5QnVmZmVyLCBjb252ZXJ0IGl0IHRvIGEgc3RyaW5nIGFycmF5ICh1c2VkIGluIElFKQ0KICAgICAgICAgICAgdmFyIGJpbmFyeSA9ICIiLCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGRhdGEpLCBsZW5ndGggPSBieXRlcy5ieXRlTGVuZ3RoOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7IH0NCiAgICAgICAgICAgIGRhdGEgPSBiaW5hcnk7DQogICAgICAgIH0NCiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRhdGEgIT09ICdzdHJpbmcnKSByZXR1cm47DQoNCiAgICAgICAgLy9jb25zb2xlLmxvZygiUkVDVigiICsgb2JqLnNvY2tldFBhcnNlU3RhdGUgKyAiKTogIiArIGRhdGEpOyAvLyBERUJVRw0KDQogICAgICAgIG9iai5zb2NrZXRBY2N1bXVsYXRvciArPSBkYXRhOw0KICAgICAgICB3aGlsZSAodHJ1ZSkgew0KICAgICAgICAgICAgaWYgKG9iai5zb2NrZXRQYXJzZVN0YXRlID09IDApIHsNCiAgICAgICAgICAgICAgICB2YXIgaGVhZGVyc2l6ZSA9IG9iai5zb2NrZXRBY2N1bXVsYXRvci5pbmRleE9mKCJcclxuXHJcbiIpOw0KICAgICAgICAgICAgICAgIGlmIChoZWFkZXJzaXplIDwgMCkgcmV0dXJuOw0KICAgICAgICAgICAgICAgIC8vb2JqLkRlYnVnKG9iai5zb2NrZXRBY2N1bXVsYXRvci5zdWJzdHJpbmcoMCwgaGVhZGVyc2l6ZSkpOyAvLyBEaXNwbGF5IHJlY2VpdmVkIEhUVFAgaGVhZGVyDQogICAgICAgICAgICAgICAgb2JqLnNvY2tldEhlYWRlciA9IG9iai5zb2NrZXRBY2N1bXVsYXRvci5zdWJzdHJpbmcoMCwgaGVhZGVyc2l6ZSkuc3BsaXQoIlxyXG4iKTsNCiAgICAgICAgICAgICAgICBpZiAob2JqLmFtdFZlcnNpb24gPT0gbnVsbCkgeyBmb3IgKHZhciBpIGluIG9iai5zb2NrZXRIZWFkZXIpIHsgaWYgKG9iai5zb2NrZXRIZWFkZXJbaV0uaW5kZXhPZignU2VydmVyOiBJbnRlbChSKSBBY3RpdmUgTWFuYWdlbWVudCBUZWNobm9sb2d5ICcpID09IDApIHsgb2JqLmFtdFZlcnNpb24gPSBvYmouc29ja2V0SGVhZGVyW2ldLnN1YnN0cmluZyg0Nik7IH0gfSB9DQogICAgICAgICAgICAgICAgb2JqLnNvY2tldEFjY3VtdWxhdG9yID0gb2JqLnNvY2tldEFjY3VtdWxhdG9yLnN1YnN0cmluZyhoZWFkZXJzaXplICsgNCk7DQogICAgICAgICAgICAgICAgb2JqLnNvY2tldFBhcnNlU3RhdGUgPSAxOw0KICAgICAgICAgICAgICAgIG9iai5zb2NrZXREYXRhID0gJyc7DQogICAgICAgICAgICAgICAgb2JqLnNvY2tldFhIZWFkZXIgPSB7IERpcmVjdGl2ZTogb2JqLnNvY2tldEhlYWRlclswXS5zcGxpdCgnICcpIH07DQogICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZygiSGVhZGVyIiwgb2JqLnNvY2tldFhIZWFkZXIpOw0KICAgICAgICAgICAgICAgIGZvciAoaSBpbiBvYmouc29ja2V0SGVhZGVyKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChpICE9IDApIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4MiA9IG9iai5zb2NrZXRIZWFkZXJbaV0uaW5kZXhPZignOicpOw0KICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnNvY2tldFhIZWFkZXJbb2JqLnNvY2tldEhlYWRlcltpXS5zdWJzdHJpbmcoMCwgeDIpLnRvTG93ZXJDYXNlKCldID0gb2JqLnNvY2tldEhlYWRlcltpXS5zdWJzdHJpbmcoeDIgKyAyKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChvYmouc29ja2V0UGFyc2VTdGF0ZSA9PSAxKSB7DQogICAgICAgICAgICAgICAgdmFyIGNzaXplID0gLTE7DQogICAgICAgICAgICAgICAgaWYgKChvYmouc29ja2V0WEhlYWRlclsiY29ubmVjdGlvbiJdICE9IHVuZGVmaW5lZCkgJiYgKG9iai5zb2NrZXRYSGVhZGVyWyJjb25uZWN0aW9uIl0udG9Mb3dlckNhc2UoKSA9PSAnY2xvc2UnKSAmJiAoKG9iai5zb2NrZXRYSGVhZGVyWyJ0cmFuc2Zlci1lbmNvZGluZyJdID09IHVuZGVmaW5lZCkgfHwgKG9iai5zb2NrZXRYSGVhZGVyWyJ0cmFuc2Zlci1lbmNvZGluZyJdLnRvTG93ZXJDYXNlKCkgIT0gJ2NodW5rZWQnKSkpIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGJvZHkgZW5kcyB3aXRoIGEgY2xvc2UsIGluIHRoaXMgY2FzZSwgd2Ugd2lsbCBvbmx5IHByb2Nlc3MgdGhlIGhlYWRlcg0KICAgICAgICAgICAgICAgICAgICBjc2l6ZSA9IDA7DQogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvYmouc29ja2V0WEhlYWRlclsiY29udGVudC1sZW5ndGgiXSAhPSB1bmRlZmluZWQpIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGJvZHkgbGVuZ3RoIGlzIHNwZWNpZmllZCBieSB0aGUgY29udGVudC1sZW5ndGgNCiAgICAgICAgICAgICAgICAgICAgY3NpemUgPSBwYXJzZUludChvYmouc29ja2V0WEhlYWRlclsiY29udGVudC1sZW5ndGgiXSk7DQogICAgICAgICAgICAgICAgICAgIGlmIChvYmouc29ja2V0QWNjdW11bGF0b3IubGVuZ3RoIDwgY3NpemUpIHJldHVybjsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBvYmouc29ja2V0QWNjdW11bGF0b3Iuc3Vic3RyaW5nKDAsIGNzaXplKTsNCiAgICAgICAgICAgICAgICAgICAgb2JqLnNvY2tldEFjY3VtdWxhdG9yID0gb2JqLnNvY2tldEFjY3VtdWxhdG9yLnN1YnN0cmluZyhjc2l6ZSk7DQogICAgICAgICAgICAgICAgICAgIG9iai5zb2NrZXREYXRhID0gZGF0YTsNCiAgICAgICAgICAgICAgICAgICAgY3NpemUgPSAwOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIC8vIFRoZSBib2R5IGlzIGNodW5rZWQNCiAgICAgICAgICAgICAgICAgICAgdmFyIGNsZW4gPSBvYmouc29ja2V0QWNjdW11bGF0b3IuaW5kZXhPZigiXHJcbiIpOw0KICAgICAgICAgICAgICAgICAgICBpZiAoY2xlbiA8IDApIHJldHVybjsgLy8gQ2h1bmsgbGVuZ3RoIG5vdCBmb3VuZCwgZXhpdCBub3cgYW5kIGdldCBtb3JlIGRhdGEuDQogICAgICAgICAgICAgICAgICAgIC8vIENodW5rIGxlbmd0aCBpZiBmb3VuZCwgbGV0cyBzZWUgaWYgd2UgY2FuIGdldCB0aGUgZGF0YS4NCiAgICAgICAgICAgICAgICAgICAgY3NpemUgPSBwYXJzZUludChvYmouc29ja2V0QWNjdW11bGF0b3Iuc3Vic3RyaW5nKDAsIGNsZW4pLCAxNik7DQogICAgICAgICAgICAgICAgICAgIGlmIChpc05hTihjc2l6ZSkpIHsgaWYgKG9iai53ZWJzb2NrZXQpIHsgb2JqLndlYnNvY2tldC5jbG9zZSgpOyB9IHJldHVybjsgfSAvLyBDcml0aWNhbCBlcnJvciwgY2xvc2UgdGhlIHNvY2tldCBhbmQgZXhpdC4NCiAgICAgICAgICAgICAgICAgICAgaWYgKG9iai5zb2NrZXRBY2N1bXVsYXRvci5sZW5ndGggPCBjbGVuICsgMiArIGNzaXplICsgMikgcmV0dXJuOw0KICAgICAgICAgICAgICAgICAgICAvLyBXZSBnb3QgYSBjaHVuayB3aXRoIGFsbCBvZiB0aGUgZGF0YSwgaGFuZGxlIHRoZSBjaHVuY2sgbm93Lg0KICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IG9iai5zb2NrZXRBY2N1bXVsYXRvci5zdWJzdHJpbmcoY2xlbiArIDIsIGNsZW4gKyAyICsgY3NpemUpOw0KICAgICAgICAgICAgICAgICAgICBvYmouc29ja2V0QWNjdW11bGF0b3IgPSBvYmouc29ja2V0QWNjdW11bGF0b3Iuc3Vic3RyaW5nKGNsZW4gKyAyICsgY3NpemUgKyAyKTsNCiAgICAgICAgICAgICAgICAgICAgb2JqLnNvY2tldERhdGEgKz0gZGF0YTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKGNzaXplID09IDApIHsNCiAgICAgICAgICAgICAgICAgICAgLy9vYmouRGVidWcoIl9PblNvY2tldERhdGEgRE9ORTogKCIgKyBvYmouc29ja2V0RGF0YS5sZW5ndGggKyAiKTogIiArIG9iai5zb2NrZXREYXRhKTsNCiAgICAgICAgICAgICAgICAgICAgX1Byb2Nlc3NIdHRwUmVzcG9uc2Uob2JqLnNvY2tldFhIZWFkZXIsIG9iai5zb2NrZXREYXRhKTsNCiAgICAgICAgICAgICAgICAgICAgb2JqLnNvY2tldFBhcnNlU3RhdGUgPSAwOw0KICAgICAgICAgICAgICAgICAgICBvYmouc29ja2V0SGVhZGVyID0gbnVsbDsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQoNCiAgICAvLyBXZWJzb2NrZXQgcmVsYXkgc3BlY2lmaWMgcHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfUHJvY2Vzc0h0dHBSZXNwb25zZShoZWFkZXIsIGRhdGEpIHsNCiAgICAgICAgLy9vYmouRGVidWcoIl9Qcm9jZXNzSHR0cFJlc3BvbnNlOiAiICsgaGVhZGVyLkRpcmVjdGl2ZVsxXSk7DQoNCiAgICAgICAgdmFyIHMgPSBwYXJzZUludChoZWFkZXIuRGlyZWN0aXZlWzFdKTsNCiAgICAgICAgaWYgKGlzTmFOKHMpKSB7DQogICAgICAgICAgICBzID0gNjAyOw0KICAgICAgICB9DQogICAgICAgIGlmIChzID09IDQwMSAmJiArKyhvYmouYXV0aGNvdW50ZXIpIDwgMykgew0KICAgICAgICAgICAgb2JqLmNoYWxsZW5nZVBhcmFtcyA9IG9iai5wYXJzZURpZ2VzdChoZWFkZXJbJ3d3dy1hdXRoZW50aWNhdGUnXSk7IC8vIFNldCB0aGUgZGlnZXN0IHBhcmFtZXRlcnMsIGFmdGVyIHRoaXMsIHRoZSBzb2NrZXQgd2lsbCBjbG9zZSBhbmQgd2Ugd2lsbCBhdXRvLXJldHJ5DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICB2YXIgciA9IG9iai5wZW5kaW5nQWpheENhbGwuc2hpZnQoKTsNCiAgICAgICAgICAgIC8vIGlmIChzICE9IDIwMCkgeyBvYmouRGVidWcoIkVycm9yLCBzdGF0dXM9IiArIHMgKyAiXHJcblxyXG5yZXE9IiArIHJbMF0gKyAiXHJcblxyXG5yZXNwPSIgKyBkYXRhKTsgfSAvLyBEZWJ1ZzogRGlzcGxheSB0aGUgcmVxdWVzdCAmIHJlc3BvbnNlIGlmIHNvbWV0aGluZyBkaWQgbm90IHdvcmsuDQogICAgICAgICAgICBvYmouYXV0aGNvdW50ZXIgPSAwOw0KICAgICAgICAgICAgb2JqLkFjdGl2ZUFqYXhDb3VudC0tOw0KICAgICAgICAgICAgb2JqLmdvdE5leHRNZXNzYWdlcyhkYXRhLCAnc3VjY2VzcycsIHsgc3RhdHVzOiBzIH0sIHIpOw0KICAgICAgICAgICAgb2JqLlBlcmZvcm1OZXh0QWpheCgpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8gV2Vic29ja2V0IHJlbGF5IHNwZWNpZmljIHByaXZhdGUgbWV0aG9kDQogICAgZnVuY3Rpb24gX09uU29ja2V0Q2xvc2VkKGRhdGEpIHsNCiAgICAgICAgLy9jb25zb2xlLmxvZygiX09uU29ja2V0Q2xvc2VkIik7DQogICAgICAgIGlmIChvYmouaW5EYXRhQ291bnQgPT0gMCkgeyBvYmoudGxzdjFvbmx5ID0gKDEgLSBvYmoudGxzdjFvbmx5KTsgfQ0KICAgICAgICBvYmouc29ja2V0U3RhdGUgPSAwOw0KICAgICAgICBpZiAob2JqLnNvY2tldCAhPSBudWxsKSB7IG9iai5zb2NrZXQuY2xvc2UoKTsgb2JqLnNvY2tldCA9IG51bGw7IH0NCiAgICAgICAgaWYgKG9iai5wZW5kaW5nQWpheENhbGwubGVuZ3RoID4gMCkgew0KICAgICAgICAgICAgdmFyIHIgPSBvYmoucGVuZGluZ0FqYXhDYWxsLnNoaWZ0KCk7DQogICAgICAgICAgICB2YXIgcmV0cnkgPSByWzVdOw0KICAgICAgICAgICAgb2JqLlBlcmZvcm1BamF4RXhOb2RlSlMyKHJbMF0sIHJbMV0sIHJbMl0sIHJbM10sIHJbNF0sIC0tcmV0cnkpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8gV2Vic29ja2V0IHJlbGF5IHNwZWNpZmljIHByaXZhdGUgbWV0aG9kDQogICAgZnVuY3Rpb24gX1NlbmQoeCkgew0KICAgICAgICAvL2NvbnNvbGUubG9nKCJTRU5EOiAiICsgeCk7IC8vIERFQlVHDQogICAgICAgIGlmIChvYmouc29ja2V0U3RhdGUgPT0gMiAmJiBvYmouc29ja2V0ICE9IG51bGwgJiYgb2JqLnNvY2tldC5yZWFkeVN0YXRlID09IFdlYlNvY2tldC5PUEVOKSB7DQogICAgICAgICAgICB2YXIgYiA9IG5ldyBVaW50OEFycmF5KHgubGVuZ3RoKTsNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeC5sZW5ndGg7ICsraSkgeyBiW2ldID0geC5jaGFyQ29kZUF0KGkpOyB9DQogICAgICAgICAgICB0cnkgeyBvYmouc29ja2V0LnNlbmQoYi5idWZmZXIpOyB9IGNhdGNoIChlKSB7IH0NCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIC8vIFByaXZhdGUgbWV0aG9kDQogICAgb2JqLmdvdE5leHRNZXNzYWdlcyA9IGZ1bmN0aW9uIChkYXRhLCBzdGF0dXMsIHJlcXVlc3QsIGNhbGxBcmdzKSB7DQogICAgICAgIGlmIChvYmouRmFpbEFsbEVycm9yID09IDk5OSkgcmV0dXJuOw0KICAgICAgICBpZiAob2JqLkZhaWxBbGxFcnJvciAhPSAwKSB7IGNhbGxBcmdzWzFdKG51bGwsIG9iai5GYWlsQWxsRXJyb3IsIGNhbGxBcmdzWzJdKTsgcmV0dXJuOyB9DQogICAgICAgIGlmIChyZXF1ZXN0LnN0YXR1cyAhPSAyMDApIHsgY2FsbEFyZ3NbMV0obnVsbCwgcmVxdWVzdC5zdGF0dXMsIGNhbGxBcmdzWzJdKTsgcmV0dXJuOyB9DQogICAgICAgIGNhbGxBcmdzWzFdKGRhdGEsIDIwMCwgY2FsbEFyZ3NbMl0pOw0KICAgIH0NCg0KICAgIC8vIFByaXZhdGUgbWV0aG9kDQogICAgb2JqLmdvdE5leHRNZXNzYWdlc0Vycm9yID0gZnVuY3Rpb24gKHJlcXVlc3QsIHN0YXR1cywgZXJyb3JUaHJvd24sIGNhbGxBcmdzKSB7DQogICAgICAgIGlmIChvYmouRmFpbEFsbEVycm9yID09IDk5OSkgcmV0dXJuOw0KICAgICAgICBpZiAob2JqLkZhaWxBbGxFcnJvciAhPSAwKSB7IGNhbGxBcmdzWzFdKG51bGwsIG9iai5GYWlsQWxsRXJyb3IsIGNhbGxBcmdzWzJdKTsgcmV0dXJuOyB9DQogICAgICAgIGNhbGxBcmdzWzFdKG9iaiwgbnVsbCwgeyBIZWFkZXI6IHsgSHR0cEVycm9yOiByZXF1ZXN0LnN0YXR1cyB9IH0sIHJlcXVlc3Quc3RhdHVzLCBjYWxsQXJnc1syXSk7DQogICAgfQ0KDQogICAgLy8gQ2FuY2VsIGFsbCBwZW5kaW5nIHF1ZXJpZXMgd2l0aCBnaXZlbiBzdGF0dXMNCiAgICBvYmouQ2FuY2VsQWxsUXVlcmllcyA9IGZ1bmN0aW9uIChzKSB7DQogICAgICAgIHdoaWxlIChvYmouUGVuZGluZ0FqYXgubGVuZ3RoID4gMCkgeyB2YXIgeCA9IG9iai5QZW5kaW5nQWpheC5zaGlmdCgpOyB4WzFdKG51bGwsIHMsIHhbMl0pOyB9DQogICAgICAgIGlmIChvYmoud2Vic29ja2V0ICE9IG51bGwpIHsgb2JqLndlYnNvY2tldC5jbG9zZSgpOyBvYmoud2Vic29ja2V0ID0gbnVsbDsgb2JqLnNvY2tldFN0YXRlID0gMDsgfQ0KICAgIH0NCg0KICAgIHJldHVybiBvYmo7DQp9DQoNCi8qKiANCiogQGRlc2NyaXB0aW9uIEludGVsKHIpIEFNVCBXU01BTiBTdGFjaw0KKiBAYXV0aG9yIFlsaWFuIFNhaW50LUhpbGFpcmUNCiogQHZlcnNpb24gdjAuMi4wDQoqLw0KDQovLyBDb25zdHJ1Y3QgYSBNZXNoU2VydmVyIG9iamVjdA0KdmFyIFdzbWFuU3RhY2tDcmVhdGVTZXJ2aWNlID0gZnVuY3Rpb24gKGhvc3QsIHBvcnQsIHVzZXIsIHBhc3MsIHRscywgZXh0cmEpIHsNCiAgICB2YXIgb2JqID0ge307DQogICAgLy9vYmoub25EZWJ1Z01lc3NhZ2UgPSBudWxsOyAgICAgICAgICAvLyBTZXQgdG8gYSBmdW5jdGlvbiBpZiB5b3Ugd2FudCB0byBnZXQgZGVidWcgbWVzc2FnZXMuDQogICAgb2JqLk5leHRNZXNzYWdlSWQgPSAxOyAgICAgICAgICAgICAgLy8gTmV4dCBtZXNzYWdlIG51bWJlciwgdXNlZCB0byBsYWJlbCBXU01BTiBjYWxscy4NCiAgICBvYmouQWRkcmVzcyA9ICcvd3NtYW4nOw0KICAgIG9iai5jb21tID0gQ3JlYXRlV3NtYW5Db21tKGhvc3QsIHBvcnQsIHVzZXIsIHBhc3MsIHRscywgZXh0cmEpOw0KDQogICAgb2JqLlBlcmZvcm1BamF4ID0gZnVuY3Rpb24gKHBvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCBwcmksIG5hbWVzcGFjZXMpIHsNCiAgICAgICAgaWYgKG5hbWVzcGFjZXMgPT0gbnVsbCkgbmFtZXNwYWNlcyA9ICcnOw0KICAgICAgICBvYmouY29tbS5QZXJmb3JtQWpheCgnPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwidXRmLThcIj8+PEVudmVsb3BlIHhtbG5zOnhzaT1cImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlXCIgeG1sbnM6eHNkPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWFcIiB4bWxuczphPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciIHhtbG5zOnc9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMy8wNS9zb2FwLWVudmVsb3BlXCIgJyArIG5hbWVzcGFjZXMgKyAnPjxIZWFkZXI+PGE6QWN0aW9uPicgKyBwb3N0ZGF0YSwgZnVuY3Rpb24gKGRhdGEsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBjYWxsYmFjayhvYmosIG51bGwsIHsgSGVhZGVyOiB7IEh0dHBFcnJvcjogc3RhdHVzIH0gfSwgc3RhdHVzLCB0YWcpOyByZXR1cm47IH0NCiAgICAgICAgICAgIHZhciB3c3Jlc3BvbnNlID0gb2JqLlBhcnNlV3NtYW4oZGF0YSk7DQogICAgICAgICAgICBpZiAoIXdzcmVzcG9uc2UgfHwgd3NyZXNwb25zZSA9PSBudWxsKSB7IGNhbGxiYWNrKG9iaiwgbnVsbCwgeyBIZWFkZXI6IHsgSHR0cEVycm9yOiBzdGF0dXMgfSB9LCA2MDEsIHRhZyk7IH0gZWxzZSB7IGNhbGxiYWNrKG9iaiwgd3NyZXNwb25zZS5IZWFkZXJbIlJlc291cmNlVVJJIl0sIHdzcmVzcG9uc2UsIDIwMCwgdGFnKTsgfQ0KICAgICAgICB9LCB0YWcsIHByaSk7DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICAvL29iai5EZWJ1ZyA9IGZ1bmN0aW9uIChtc2cpIHsgLypjb25zb2xlLmxvZyhtc2cpOyovIH0NCg0KICAgIC8vIENhbmNlbCBhbGwgcGVuZGluZyBxdWVyaWVzIHdpdGggZ2l2ZW4gc3RhdHVzDQogICAgb2JqLkNhbmNlbEFsbFF1ZXJpZXMgPSBmdW5jdGlvbiAocykgeyBvYmouY29tbS5DYW5jZWxBbGxRdWVyaWVzKHMpOyB9DQoNCiAgICAvLyBHZXQgdGhlIGxhc3QgZWxlbWVudCBvZiBhIFVSSSBzdHJpbmcNCiAgICBvYmouR2V0TmFtZUZyb21VcmwgPSBmdW5jdGlvbiAocmVzdXJpKSB7DQogICAgICAgIHZhciB4ID0gcmVzdXJpLmxhc3RJbmRleE9mKCIvIik7DQogICAgICAgIHJldHVybiAoeCA9PSAtMSk/cmVzdXJpOnJlc3VyaS5zdWJzdHJpbmcoeCArIDEpOw0KICAgIH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiBTdWJzY3JpYmUgb3BlcmF0aW9uDQogICAgb2JqLkV4ZWNTdWJzY3JpYmUgPSBmdW5jdGlvbiAocmVzdXJpLCBkZWxpdmVyeSwgdXJsLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycywgb3BhcXVlLCB1c2VyLCBwYXNzKSB7DQogICAgICAgIHZhciBkaWdlc3QgPSAiIiwgZGlnZXN0MiA9ICIiLCBvcGFxdWUgPSAiIjsNCiAgICAgICAgaWYgKHVzZXIgIT0gbnVsbCAmJiBwYXNzICE9IG51bGwpIHsgZGlnZXN0ID0gJzx0Oklzc3VlZFRva2VucyB4bWxuczp0PSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzAyL3RydXN0IiB4bWxuczpzZT0iaHR0cDovL2RvY3Mub2FzaXMtb3Blbi5vcmcvd3NzLzIwMDQvMDEvb2FzaXMtMjAwNDAxLXdzcy13c3NlY3VyaXR5LXNlY2V4dC0xLjAueHNkIj48dDpSZXF1ZXN0U2VjdXJpdHlUb2tlblJlc3BvbnNlPjx0OlRva2VuVHlwZT5odHRwOi8vZG9jcy5vYXNpcy1vcGVuLm9yZy93c3MvMjAwNC8wMS9vYXNpcy0yMDA0MDEtd3NzLXVzZXJuYW1lLXRva2VuLXByb2ZpbGUtMS4wI1VzZXJuYW1lVG9rZW48L3Q6VG9rZW5UeXBlPjx0OlJlcXVlc3RlZFNlY3VyaXR5VG9rZW4+PHNlOlVzZXJuYW1lVG9rZW4+PHNlOlVzZXJuYW1lPicgKyB1c2VyICsgJzwvc2U6VXNlcm5hbWU+PHNlOlBhc3N3b3JkIFR5cGU9Imh0dHA6Ly9kb2NzLm9hc2lzLW9wZW4ub3JnL3dzcy8yMDA0LzAxL29hc2lzLTIwMDQwMS13c3Mtd3NzZWN1cml0eS1zZWNleHQtMS4wLnhzZCNQYXNzd29yZFRleHQiPicgKyBwYXNzICsgJzwvc2U6UGFzc3dvcmQ+PC9zZTpVc2VybmFtZVRva2VuPjwvdDpSZXF1ZXN0ZWRTZWN1cml0eVRva2VuPjwvdDpSZXF1ZXN0U2VjdXJpdHlUb2tlblJlc3BvbnNlPjwvdDpJc3N1ZWRUb2tlbnM+JzsgZGlnZXN0MiA9ICc8dzpBdXRoIFByb2ZpbGU9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi9zZWNwcm9maWxlL2h0dHAvZGlnZXN0Ii8+JzsgfQ0KICAgICAgICBpZiAob3BhcXVlICE9IG51bGwpIHsgb3BhcXVlID0gJzxhOlJlZmVyZW5jZVBhcmFtZXRlcnM+PG06YXJnPicgKyBvcGFxdWUgKyAnPC9tOmFyZz48L2E6UmVmZXJlbmNlUGFyYW1ldGVycz4nOyB9DQogICAgICAgIGlmIChkZWxpdmVyeSA9PSAnUHVzaFdpdGhBY2snKSB7IGRlbGl2ZXJ5ID0gJ2RtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi9QdXNoV2l0aEFjayc7IH0gZWxzZSBpZiAoZGVsaXZlcnkgPT0gJ1B1c2gnKSB7IGRlbGl2ZXJ5ID0gJ3htbHNvYXAub3JnL3dzLzIwMDQvMDgvZXZlbnRpbmcvRGVsaXZlcnlNb2Rlcy9QdXNoJzsgfQ0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2V2ZW50aW5nL1N1YnNjcmliZTwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz4iICsgX1B1dE9ialRvU2VsZWN0b3JzWG1sKHNlbGVjdG9ycykgKyBkaWdlc3QgKyAnPC9IZWFkZXI+PEJvZHk+PGU6U3Vic2NyaWJlPjxlOkRlbGl2ZXJ5IE1vZGU9Imh0dHA6Ly9zY2hlbWFzLicgKyBkZWxpdmVyeSArICciPjxlOk5vdGlmeVRvPjxhOkFkZHJlc3M+JyArIHVybCArICc8L2E6QWRkcmVzcz4nICsgb3BhcXVlICsgJzwvZTpOb3RpZnlUbz4nICsgZGlnZXN0MiArICc8L2U6RGVsaXZlcnk+PC9lOlN1YnNjcmliZT4nOw0KICAgICAgICBvYmouUGVyZm9ybUFqYXgoZGF0YSArICI8L0JvZHk+PC9FbnZlbG9wZT4iLCBjYWxsYmFjaywgdGFnLCBwcmksICd4bWxuczplPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2V2ZW50aW5nIiB4bWxuczptPSJodHRwOi8veC5jb20iJyk7DQogICAgfQ0KDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOIFVuU3Vic2NyaWJlIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjVW5TdWJzY3JpYmUgPSBmdW5jdGlvbiAocmVzdXJpLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycykgew0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2V2ZW50aW5nL1Vuc3Vic2NyaWJlPC9hOkFjdGlvbj48YTpUbz4iICsgb2JqLkFkZHJlc3MgKyAiPC9hOlRvPjx3OlJlc291cmNlVVJJPiIgKyByZXN1cmkgKyAiPC93OlJlc291cmNlVVJJPjxhOk1lc3NhZ2VJRD4iICsgKG9iai5OZXh0TWVzc2FnZUlkKyspICsgIjwvYTpNZXNzYWdlSUQ+PGE6UmVwbHlUbz48YTpBZGRyZXNzPmh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZy9yb2xlL2Fub255bW91czwvYTpBZGRyZXNzPjwvYTpSZXBseVRvPiIgKyBfUHV0T2JqVG9TZWxlY3RvcnNYbWwoc2VsZWN0b3JzKSArICc8L0hlYWRlcj48Qm9keT48ZTpVbnN1YnNjcmliZS8+JzsNCiAgICAgICAgb2JqLlBlcmZvcm1BamF4KGRhdGEgKyAiPC9Cb2R5PjwvRW52ZWxvcGU+IiwgY2FsbGJhY2ssIHRhZywgcHJpLCAneG1sbnM6ZT0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9ldmVudGluZyInKTsNCiAgICB9DQoNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gUFVUIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjUHV0ID0gZnVuY3Rpb24gKHJlc3VyaSwgcHV0b2JqLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycykgew0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L3RyYW5zZmVyL1B1dDwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjAuMDAwUzwvdzpPcGVyYXRpb25UaW1lb3V0PiIgKyBfUHV0T2JqVG9TZWxlY3RvcnNYbWwoc2VsZWN0b3JzKSArICc8L0hlYWRlcj48Qm9keT4nICsgX1B1dE9ialRvQm9keVhtbChyZXN1cmksIHB1dG9iaik7DQogICAgICAgIG9iai5QZXJmb3JtQWpheChkYXRhICsgIjwvQm9keT48L0VudmVsb3BlPiIsIGNhbGxiYWNrLCB0YWcsIHByaSk7DQogICAgfQ0KCQkNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gQ1JFQVRFIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjQ3JlYXRlID0gZnVuY3Rpb24gKHJlc3VyaSwgcHV0b2JqLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycykgew0KICAgICAgICB2YXIgb2JqbmFtZSA9IG9iai5HZXROYW1lRnJvbVVybChyZXN1cmkpOw0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L3RyYW5zZmVyL0NyZWF0ZTwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+IiArIF9QdXRPYmpUb1NlbGVjdG9yc1htbChzZWxlY3RvcnMpICsgIjwvSGVhZGVyPjxCb2R5PjxnOiIgKyBvYmpuYW1lICsgIiB4bWxuczpnPVwiIiArIHJlc3VyaSArICJcIj4iOw0KICAgICAgICBmb3IgKHZhciBuIGluIHB1dG9iaikgeyBkYXRhICs9ICI8ZzoiICsgbiArICI+IiArIHB1dG9ialtuXSArICI8L2c6IiArIG4gKyAiPiIgfSANCiAgICAgICAgb2JqLlBlcmZvcm1BamF4KGRhdGEgKyAiPC9nOiIgKyBvYmpuYW1lICsgIj48L0JvZHk+PC9FbnZlbG9wZT4iLCBjYWxsYmFjaywgdGFnLCBwcmkpOw0KICAgIH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiBERUxFVEUgb3BlcmF0aW9uDQogICAgb2JqLkV4ZWNEZWxldGUgPSBmdW5jdGlvbiAocmVzdXJpLCBwdXRvYmosIGNhbGxiYWNrLCB0YWcsIHByaSkgew0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L3RyYW5zZmVyL0RlbGV0ZTwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+IiArIF9QdXRPYmpUb1NlbGVjdG9yc1htbChwdXRvYmopICsgIjwvSGVhZGVyPjxCb2R5IC8+PC9FbnZlbG9wZT4iOw0KICAgICAgICBvYmouUGVyZm9ybUFqYXgoZGF0YSwgY2FsbGJhY2ssIHRhZywgcHJpKTsNCiAgICB9DQoNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gR0VUIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjR2V0ID0gZnVuY3Rpb24gKHJlc3VyaSwgY2FsbGJhY2ssIHRhZywgcHJpKSB7DQogICAgICAgIG9iai5QZXJmb3JtQWpheCgiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOS90cmFuc2Zlci9HZXQ8L2E6QWN0aW9uPjxhOlRvPiIgKyBvYmouQWRkcmVzcyArICI8L2E6VG8+PHc6UmVzb3VyY2VVUkk+IiArIHJlc3VyaSArICI8L3c6UmVzb3VyY2VVUkk+PGE6TWVzc2FnZUlEPiIgKyAob2JqLk5leHRNZXNzYWdlSWQrKykgKyAiPC9hOk1lc3NhZ2VJRD48YTpSZXBseVRvPjxhOkFkZHJlc3M+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL3JvbGUvYW5vbnltb3VzPC9hOkFkZHJlc3M+PC9hOlJlcGx5VG8+PHc6T3BlcmF0aW9uVGltZW91dD5QVDYwUzwvdzpPcGVyYXRpb25UaW1lb3V0PjwvSGVhZGVyPjxCb2R5IC8+PC9FbnZlbG9wZT4iLCBjYWxsYmFjaywgdGFnLCBwcmkpOw0KICAgIH0NCg0KCS8vIFBlcmZvcm0gYSBXU01BTiBtZXRob2QgY2FsbCBvcGVyYXRpb24NCiAgICBvYmouRXhlY01ldGhvZCA9IGZ1bmN0aW9uIChyZXN1cmksIG1ldGhvZCwgYXJncywgY2FsbGJhY2ssIHRhZywgcHJpLCBzZWxlY3RvcnMpIHsNCiAgICAgICAgdmFyIGFyZ3N4bWwgPSAiIjsNCiAgICAgICAgZm9yICh2YXIgaSBpbiBhcmdzKSB7IGlmIChhcmdzW2ldICE9IG51bGwpIHsgaWYgKEFycmF5LmlzQXJyYXkoYXJnc1tpXSkpIHsgZm9yICh2YXIgeCBpbiBhcmdzW2ldKSB7IGFyZ3N4bWwgKz0gIjxyOiIgKyBpICsgIj4iICsgYXJnc1tpXVt4XSArICI8L3I6IiArIGkgKyAiPiI7IH0gfSBlbHNlIHsgYXJnc3htbCArPSAiPHI6IiArIGkgKyAiPiIgKyBhcmdzW2ldICsgIjwvcjoiICsgaSArICI+IjsgfSB9IH0NCiAgICAgICAgb2JqLkV4ZWNNZXRob2RYbWwocmVzdXJpLCBtZXRob2QsIGFyZ3N4bWwsIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKTsNCiAgICB9DQoJDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOIG1ldGhvZCBjYWxsIG9wZXJhdGlvbi4gVGhlIGFyZ3VtZW50cyBhcmUgYWxyZWFkeSBmb3JtYXR0ZWQgaW4gWE1MLg0KICAgIG9iai5FeGVjTWV0aG9kWG1sID0gZnVuY3Rpb24gKHJlc3VyaSwgbWV0aG9kLCBhcmdzeG1sLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycykgew0KICAgICAgICBvYmouUGVyZm9ybUFqYXgocmVzdXJpICsgIi8iICsgbWV0aG9kICsgIjwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+IiArIF9QdXRPYmpUb1NlbGVjdG9yc1htbChzZWxlY3RvcnMpICsgIjwvSGVhZGVyPjxCb2R5PjxyOiIgKyBtZXRob2QgKyAnX0lOUFVUJyArICIgeG1sbnM6cj1cIiIgKyByZXN1cmkgKyAiXCI+IiArIGFyZ3N4bWwgKyAiPC9yOiIgKyBtZXRob2QgKyAiX0lOUFVUPjwvQm9keT48L0VudmVsb3BlPiIsIGNhbGxiYWNrLCB0YWcsIHByaSk7DQogICAgfQ0KDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOIEVOVU0gb3BlcmF0aW9uDQogICAgb2JqLkV4ZWNFbnVtID0gZnVuY3Rpb24gKHJlc3VyaSwgY2FsbGJhY2ssIHRhZywgcHJpKSB7DQogICAgICAgIG9iai5QZXJmb3JtQWpheCgiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOS9lbnVtZXJhdGlvbi9FbnVtZXJhdGU8L2E6QWN0aW9uPjxhOlRvPiIgKyBvYmouQWRkcmVzcyArICI8L2E6VG8+PHc6UmVzb3VyY2VVUkk+IiArIHJlc3VyaSArICI8L3c6UmVzb3VyY2VVUkk+PGE6TWVzc2FnZUlEPiIgKyAob2JqLk5leHRNZXNzYWdlSWQrKykgKyAiPC9hOk1lc3NhZ2VJRD48YTpSZXBseVRvPjxhOkFkZHJlc3M+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL3JvbGUvYW5vbnltb3VzPC9hOkFkZHJlc3M+PC9hOlJlcGx5VG8+PHc6T3BlcmF0aW9uVGltZW91dD5QVDYwUzwvdzpPcGVyYXRpb25UaW1lb3V0PjwvSGVhZGVyPjxCb2R5PjxFbnVtZXJhdGUgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L2VudW1lcmF0aW9uXCIgLz48L0JvZHk+PC9FbnZlbG9wZT4iLCBjYWxsYmFjaywgdGFnLCBwcmkpOw0KICAgIH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiBQVUxMIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjUHVsbCA9IGZ1bmN0aW9uIChyZXN1cmksIGVudW1jdHgsIGNhbGxiYWNrLCB0YWcsIHByaSkgew0KICAgICAgICBvYmouUGVyZm9ybUFqYXgoImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDkvZW51bWVyYXRpb24vUHVsbDwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+PC9IZWFkZXI+PEJvZHk+PFB1bGwgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L2VudW1lcmF0aW9uXCI+PEVudW1lcmF0aW9uQ29udGV4dD4iICsgZW51bWN0eCArICI8L0VudW1lcmF0aW9uQ29udGV4dD48L1B1bGw+PC9Cb2R5PjwvRW52ZWxvcGU+IiwgY2FsbGJhY2ssIHRhZywgcHJpKTsgLy8gPC9FbnVtZXJhdGlvbkNvbnRleHQ+LS08TWF4RWxlbWVudHM+OTk5PC9NYXhFbGVtZW50cz48TWF4Q2hhcmFjdGVycz45OTk5OTwvTWF4Q2hhcmFjdGVycz4tLTwvUHVsbD4NCiAgICB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIG9iai5QYXJzZVdzbWFuID0gZnVuY3Rpb24gKHhtbCkgew0KICAgICAgICB0cnkgew0KICAgICAgICAgICAgaWYgKCF4bWwuY2hpbGROb2RlcykgeG1sID0gX3R1cm5Ub1htbCh4bWwpOw0KICAgICAgICAgICAgdmFyIHIgPSB7IEhlYWRlcjp7fSB9LCBoZWFkZXIgPSB4bWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIkhlYWRlciIpWzBdLCB0Ow0KICAgICAgICAgICAgaWYgKCFoZWFkZXIpIGhlYWRlciA9IHhtbC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYTpIZWFkZXIiKVswXTsNCiAgICAgICAgICAgIGlmICghaGVhZGVyKSByZXR1cm4gbnVsbDsNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGVhZGVyLmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgICAgICB2YXIgY2hpbGQgPSBoZWFkZXIuY2hpbGROb2Rlc1tpXTsNCiAgICAgICAgICAgICAgICByLkhlYWRlcltjaGlsZC5sb2NhbE5hbWVdID0gY2hpbGQudGV4dENvbnRlbnQ7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB2YXIgYm9keSA9IHhtbC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiQm9keSIpWzBdOw0KICAgICAgICAgICAgaWYgKCFib2R5KSBib2R5ID0geG1sLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhOkJvZHkiKVswXTsNCiAgICAgICAgICAgIGlmICghYm9keSkgcmV0dXJuIG51bGw7DQogICAgICAgICAgICBpZiAoYm9keS5jaGlsZE5vZGVzLmxlbmd0aCA+IDApIHsNCiAgICAgICAgICAgICAgICB0ID0gYm9keS5jaGlsZE5vZGVzWzBdLmxvY2FsTmFtZTsNCiAgICAgICAgICAgICAgICBpZiAodC5pbmRleE9mKCJfT1VUUFVUIikgPT0gdC5sZW5ndGggLSA3KSB7IHQgPSB0LnN1YnN0cmluZygwLCB0Lmxlbmd0aCAtIDcpOyB9DQogICAgICAgICAgICAgICAgci5IZWFkZXJbJ01ldGhvZCddID0gdDsNCiAgICAgICAgICAgICAgICByLkJvZHkgPSBfUGFyc2VXc21hblJlYyhib2R5LmNoaWxkTm9kZXNbMF0pOw0KCQkgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIHI7DQogICAgICAgIH0gY2F0Y2ggKGUpIHsNCiAgICAgICAgICAgIGNvbnNvbGUubG9nKCJVbmFibGUgdG8gcGFyc2UgWE1MOiAiICsgeG1sKTsNCiAgICAgICAgICAgIHJldHVybiBudWxsOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfUGFyc2VXc21hblJlYyhub2RlKSB7DQogICAgICAgIHZhciBkYXRhLCByID0ge307DQogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICB2YXIgY2hpbGQgPSBub2RlLmNoaWxkTm9kZXNbaV07DQogICAgICAgICAgICBpZiAoKGNoaWxkLmNoaWxkRWxlbWVudENvdW50ID09IG51bGwpIHx8IChjaGlsZC5jaGlsZEVsZW1lbnRDb3VudCA9PSAwKSkgeyBkYXRhID0gY2hpbGQudGV4dENvbnRlbnQ7IH0gZWxzZSB7IGRhdGEgPSBfUGFyc2VXc21hblJlYyhjaGlsZCk7IH0NCiAgICAgICAgICAgIGlmIChkYXRhID09ICd0cnVlJykgZGF0YSA9IHRydWU7IC8vIENvbnZlcnQgJ3RydWUnIGludG8gdHJ1ZQ0KICAgICAgICAgICAgaWYgKGRhdGEgPT0gJ2ZhbHNlJykgZGF0YSA9IGZhbHNlOyAvLyBDb252ZXJ0ICdmYWxzZScgaW50byBmYWxzZQ0KICAgICAgICAgICAgaWYgKChwYXJzZUludChkYXRhKSArICcnKSA9PT0gZGF0YSkgZGF0YSA9IHBhcnNlSW50KGRhdGEpOyAvLyBDb252ZXJ0IGludGVnZXJzDQoNCiAgICAgICAgICAgIHZhciBjaGlsZE9iaiA9IGRhdGE7DQogICAgICAgICAgICBpZiAoKGNoaWxkLmF0dHJpYnV0ZXMgIT0gbnVsbCkgJiYgKGNoaWxkLmF0dHJpYnV0ZXMubGVuZ3RoID4gMCkpIHsNCgkJCQljaGlsZE9iaiA9IHsgJ1ZhbHVlJzogZGF0YSB9Ow0KCQkJCWZvcih2YXIgaiA9IDA7IGogPCBjaGlsZC5hdHRyaWJ1dGVzLmxlbmd0aDsgaisrKSB7DQoJCQkJCWNoaWxkT2JqWydAJyArIGNoaWxkLmF0dHJpYnV0ZXNbal0ubmFtZV0gPSBjaGlsZC5hdHRyaWJ1dGVzW2pdLnZhbHVlOw0KCQkJCX0NCgkJCX0NCgkJCQ0KICAgICAgICAgICAgaWYgKHJbY2hpbGQubG9jYWxOYW1lXSBpbnN0YW5jZW9mIEFycmF5KSB7IHJbY2hpbGQubG9jYWxOYW1lXS5wdXNoKGNoaWxkT2JqKTsgfQ0KICAgICAgICAgICAgZWxzZSBpZiAocltjaGlsZC5sb2NhbE5hbWVdID09IG51bGwpIHsgcltjaGlsZC5sb2NhbE5hbWVdID0gY2hpbGRPYmo7IH0NCiAgICAgICAgICAgIGVsc2UgeyByW2NoaWxkLmxvY2FsTmFtZV0gPSBbcltjaGlsZC5sb2NhbE5hbWVdLCBjaGlsZE9ial07IH0NCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gcjsNCiAgICB9DQoNCiAgICBmdW5jdGlvbiBfUHV0T2JqVG9Cb2R5WG1sKHJlc3VyaSwgcHV0T2JqKSB7DQogICAgICAgIGlmICghcmVzdXJpIHx8IHB1dE9iaiA9PSBudWxsKSByZXR1cm4gJyc7DQoJCXZhciBvYmpuYW1lID0gb2JqLkdldE5hbWVGcm9tVXJsKHJlc3VyaSk7DQoJCXZhciByZXN1bHQgPSAnPHI6JyArIG9iam5hbWUgKyAnIHhtbG5zOnI9IicgKyByZXN1cmkgKyAnIj4nOw0KDQoJCWZvciAodmFyIHByb3AgaW4gcHV0T2JqKSB7DQoJCQlpZiAoIXB1dE9iai5oYXNPd25Qcm9wZXJ0eShwcm9wKSB8fCBwcm9wLmluZGV4T2YoJ19fJykgPT09IDAgfHwgcHJvcC5pbmRleE9mKCdAJykgPT09IDApIGNvbnRpbnVlOw0KCQkJaWYgKHB1dE9ialtwcm9wXSA9PSBudWxsIHx8IHR5cGVvZiBwdXRPYmpbcHJvcF0gPT09ICdmdW5jdGlvbicpIGNvbnRpbnVlOw0KCQkJaWYgKHR5cGVvZiBwdXRPYmpbcHJvcF0gPT09ICdvYmplY3QnICYmIHB1dE9ialtwcm9wXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddKSB7DQoJCQkJcmVzdWx0ICs9ICc8cjonICsgcHJvcCArICc+PGE6QWRkcmVzcz4nICsgcHV0T2JqW3Byb3BdLkFkZHJlc3MgKyAnPC9hOkFkZHJlc3M+PGE6UmVmZXJlbmNlUGFyYW1ldGVycz48dzpSZXNvdXJjZVVSST4nICsgcHV0T2JqW3Byb3BdWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bIlJlc291cmNlVVJJIl0gKyAnPC93OlJlc291cmNlVVJJPjx3OlNlbGVjdG9yU2V0Pic7DQoJCQkJdmFyIHNlbGVjdG9yQXJyYXkgPSBwdXRPYmpbcHJvcF1bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXTsNCgkJCQlpZiAoQXJyYXkuaXNBcnJheShzZWxlY3RvckFycmF5KSkgew0KCQkJCQlmb3IgKHZhciBpPTA7IGk8IHNlbGVjdG9yQXJyYXkubGVuZ3RoOyBpKyspIHsNCgkJCQkJCXJlc3VsdCArPSAnPHc6U2VsZWN0b3InICsgX09iamVjdFRvWG1sQXR0cmlidXRlcyhzZWxlY3RvckFycmF5W2ldKSArICc+JyArIHNlbGVjdG9yQXJyYXlbaV1bJ1ZhbHVlJ10gKyAnPC93OlNlbGVjdG9yPic7DQoJCQkJCX0NCgkJCQl9DQoJCQkJZWxzZSB7DQoJCQkJCXJlc3VsdCArPSAnPHc6U2VsZWN0b3InICsgX09iamVjdFRvWG1sQXR0cmlidXRlcyhzZWxlY3RvckFycmF5KSArICc+JyArIHNlbGVjdG9yQXJyYXlbJ1ZhbHVlJ10gKyAnPC93OlNlbGVjdG9yPic7DQoJCQkJfQ0KCQkJCXJlc3VsdCArPSAnPC93OlNlbGVjdG9yU2V0PjwvYTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjwvcjonICsgcHJvcCArICc+JzsNCgkJCX0NCgkJCWVsc2Ugew0KCQkJICAgIGlmIChBcnJheS5pc0FycmF5KHB1dE9ialtwcm9wXSkpIHsNCgkJCSAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwdXRPYmpbcHJvcF0ubGVuZ3RoOyBpKyspIHsNCgkJCSAgICAgICAgICAgIHJlc3VsdCArPSAnPHI6JyArIHByb3AgKyAnPicgKyBwdXRPYmpbcHJvcF1baV0udG9TdHJpbmcoKSArICc8L3I6JyArIHByb3AgKyAnPic7DQoJCQkgICAgICAgIH0NCgkJCSAgICB9IGVsc2Ugew0KCQkJICAgICAgICByZXN1bHQgKz0gJzxyOicgKyBwcm9wICsgJz4nICsgcHV0T2JqW3Byb3BdLnRvU3RyaW5nKCkgKyAnPC9yOicgKyBwcm9wICsgJz4nOw0KCQkJICAgIH0NCgkJCX0NCgkJfQ0KDQoJCXJlc3VsdCArPSAnPC9yOicgKyBvYmpuYW1lICsgJz4nOw0KCQlyZXR1cm4gcmVzdWx0Ow0KCX0NCg0KCS8qIA0KCWNvbnZlcnQgDQoJCXsgQE5hbWU6ICdJbnN0YW5jZUlEJywgQEF0dHJOYW1lOiAnQXR0cmlidXRlIFZhbHVlJ30NCglpbnRvDQoJCScgTmFtZT0iSW5zdGFuY2VJRCIgQXR0ck5hbWU9IkF0dHJpYnV0ZSBWYWx1ZSIgJw0KCSovDQogICAgZnVuY3Rpb24gX09iamVjdFRvWG1sQXR0cmlidXRlcyhvYmpXaXRoQXR0cmlidXRlcykgew0KCQlpZighb2JqV2l0aEF0dHJpYnV0ZXMpIHJldHVybiAnJzsNCgkJdmFyIHJlc3VsdCA9ICcnOw0KCQlmb3IgKHZhciBwcm9wTmFtZSBpbiBvYmpXaXRoQXR0cmlidXRlcykgew0KCQkJaWYgKCFvYmpXaXRoQXR0cmlidXRlcy5oYXNPd25Qcm9wZXJ0eShwcm9wTmFtZSkgfHwgcHJvcE5hbWUuaW5kZXhPZignQCcpICE9PSAwKSBjb250aW51ZTsNCgkJCXJlc3VsdCArPSAnICcgKyBwcm9wTmFtZS5zdWJzdHJpbmcoMSkgKyAnPSInICsgb2JqV2l0aEF0dHJpYnV0ZXNbcHJvcE5hbWVdICsgJyInOw0KCQl9DQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KDQogICAgZnVuY3Rpb24gX1B1dE9ialRvU2VsZWN0b3JzWG1sKHNlbGVjdG9yU2V0KSB7DQogICAgICAgIGlmICghc2VsZWN0b3JTZXQpIHJldHVybiAnJzsNCiAgICAgICAgaWYgKHR5cGVvZiBzZWxlY3RvclNldCA9PSAnc3RyaW5nJykgcmV0dXJuIHNlbGVjdG9yU2V0Ow0KICAgICAgICBpZiAoc2VsZWN0b3JTZXRbJ0luc3RhbmNlSUQnXSkgcmV0dXJuICI8dzpTZWxlY3RvclNldD48dzpTZWxlY3RvciBOYW1lPVwiSW5zdGFuY2VJRFwiPiIgKyBzZWxlY3RvclNldFsnSW5zdGFuY2VJRCddICsgIjwvdzpTZWxlY3Rvcj48L3c6U2VsZWN0b3JTZXQ+IjsNCgkJdmFyIHJlc3VsdCA9ICc8dzpTZWxlY3RvclNldD4nOw0KCQlmb3IodmFyIHByb3BOYW1lIGluIHNlbGVjdG9yU2V0KSB7DQoJCSAgICBpZiAoIXNlbGVjdG9yU2V0Lmhhc093blByb3BlcnR5KHByb3BOYW1lKSkgY29udGludWU7DQoJCSAgICByZXN1bHQgKz0gJzx3OlNlbGVjdG9yIE5hbWU9IicgKyBwcm9wTmFtZSArICciPic7DQoJCSAgICBpZiAoc2VsZWN0b3JTZXRbcHJvcE5hbWVdWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ10pIHsNCgkJICAgICAgICByZXN1bHQgKz0gJzxhOkVuZHBvaW50UmVmZXJlbmNlPic7DQoJCSAgICAgICAgcmVzdWx0ICs9ICc8YTpBZGRyZXNzPicgKyBzZWxlY3RvclNldFtwcm9wTmFtZV1bJ0FkZHJlc3MnXSArICc8L2E6QWRkcmVzcz48YTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjx3OlJlc291cmNlVVJJPicgKyBzZWxlY3RvclNldFtwcm9wTmFtZV1bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnUmVzb3VyY2VVUkknXSArICc8L3c6UmVzb3VyY2VVUkk+PHc6U2VsZWN0b3JTZXQ+JzsNCgkJICAgICAgICB2YXIgc2VsZWN0b3JBcnJheSA9IHNlbGVjdG9yU2V0W3Byb3BOYW1lXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddOw0KCQkgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHNlbGVjdG9yQXJyYXkpKSB7DQoJCSAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VsZWN0b3JBcnJheS5sZW5ndGg7IGkrKykgew0KCQkgICAgICAgICAgICAgICAgcmVzdWx0ICs9ICc8dzpTZWxlY3RvcicgKyBfT2JqZWN0VG9YbWxBdHRyaWJ1dGVzKHNlbGVjdG9yQXJyYXlbaV0pICsgJz4nICsgc2VsZWN0b3JBcnJheVtpXVsnVmFsdWUnXSArICc8L3c6U2VsZWN0b3I+JzsNCgkJICAgICAgICAgICAgfQ0KCQkgICAgICAgIH0NCgkJICAgICAgICBlbHNlIHsNCgkJICAgICAgICAgICAgcmVzdWx0ICs9ICc8dzpTZWxlY3RvcicgKyBfT2JqZWN0VG9YbWxBdHRyaWJ1dGVzKHNlbGVjdG9yQXJyYXkpICsgJz4nICsgc2VsZWN0b3JBcnJheVsnVmFsdWUnXSArICc8L3c6U2VsZWN0b3I+JzsNCgkJICAgICAgICB9DQoJCSAgICAgICAgcmVzdWx0ICs9ICc8L3c6U2VsZWN0b3JTZXQ+PC9hOlJlZmVyZW5jZVBhcmFtZXRlcnM+PC9hOkVuZHBvaW50UmVmZXJlbmNlPic7DQoJCSAgICB9IGVsc2Ugew0KCQkgICAgICAgIHJlc3VsdCArPSBzZWxlY3RvclNldFtwcm9wTmFtZV07DQoJCSAgICB9DQoJCQlyZXN1bHQgKz0gJzwvdzpTZWxlY3Rvcj4nOw0KCQl9DQoJCXJlc3VsdCArPSAnPC93OlNlbGVjdG9yU2V0Pic7DQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KDQogICAgZnVuY3Rpb24gX3R1cm5Ub1htbCh0ZXh0KSB7DQogICAgICAgIA0KICAgICAgICAvLyBOb2RlSlMgZGV0ZWN0aW9uDQogICAgICAgIHZhciBpc05vZGUgPSBuZXcgRnVuY3Rpb24oInRyeSB7cmV0dXJuIHRoaXM9PT1nbG9iYWw7fWNhdGNoKGUpe3JldHVybiBmYWxzZTt9Iik7DQogICAgICAgIGlmIChpc05vZGUoKSkgew0KICAgICAgICAgICAgdmFyIFhET01QYXJzZXIgPSByZXF1aXJlKCd4bWxkb20nKS5ET01QYXJzZXI7DQogICAgICAgICAgICByZXR1cm4gbmV3IFhET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcodGV4dCwgInRleHQveG1sIik7DQogICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAod2luZG93LkRPTVBhcnNlcikgew0KICAgICAgICAgICAgcmV0dXJuIG5ldyBET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcodGV4dCwgInRleHQveG1sIik7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAvLyBJbnRlcm5ldCBFeHBsb3Jlcg0KICAgICAgICAgICAgdmFyIHhtbERvYyA9IG5ldyBBY3RpdmVYT2JqZWN0KCJNaWNyb3NvZnQuWE1MRE9NIik7DQogICAgICAgICAgICB4bWxEb2MuYXN5bmMgPSBmYWxzZTsNCiAgICAgICAgICAgIHhtbERvYy5sb2FkWE1MKHRleHQpOw0KICAgICAgICAgICAgcmV0dXJuIHhtbERvYzsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIC8qDQogICAgLy8gVGhpcyBpcyBhIGRyb3AtaW4gcmVwbGFjZW1lbnQgdG8gX3R1cm5Ub1htbCgpIHRoYXQgd29ya3Mgd2l0aG91dCB4bWwgcGFyc2VyIGRlcGVuZGVuY3kuDQogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFycmF5LnByb3RvdHlwZSwgInBlZWsiLCB7IHZhbHVlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAodGhpcy5sZW5ndGggPiAwID8gdGhpc1t0aGlzLmxlbmd0aCAtIDFdIDogbnVsbCk7IH0gfSk7CiAgICBmdW5jdGlvbiBfdHJlZUJ1aWxkZXIoKSB7DQogICAgICAgIHRoaXMudHJlZSA9IFtdOwogICAgICAgIHRoaXMucHVzaCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7IHRoaXMudHJlZS5wdXNoKGVsZW1lbnQpOyB9OwogICAgICAgIHRoaXMucG9wID0gZnVuY3Rpb24gKCkgeyB2YXIgZWxlbWVudCA9IHRoaXMudHJlZS5wb3AoKTsgaWYgKHRoaXMudHJlZS5sZW5ndGggPiAwKSB7IHZhciB4ID0gdGhpcy50cmVlLnBlZWsoKTsgeC5jaGlsZE5vZGVzLnB1c2goZWxlbWVudCk7IHguY2hpbGRFbGVtZW50Q291bnQgPSB4LmNoaWxkTm9kZXMubGVuZ3RoOyB9IHJldHVybiAoZWxlbWVudCk7IH07CiAgICAgICAgdGhpcy5wZWVrID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gKHRoaXMudHJlZS5wZWVrKCkpOyB9CiAgICAgICAgdGhpcy5hZGROYW1lc3BhY2UgPSBmdW5jdGlvbiAocHJlZml4LCBuYW1lc3BhY2UpIHsgdGhpcy50cmVlLnBlZWsoKS5uc1RhYmxlW3ByZWZpeF0gPSBuYW1lc3BhY2U7IGlmICh0aGlzLnRyZWUucGVlaygpLmF0dHJpYnV0ZXMubGVuZ3RoID4gMCkgeyBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudHJlZS5wZWVrKCkuYXR0cmlidXRlczsgKytpKSB7IHZhciBhID0gdGhpcy50cmVlLnBlZWsoKS5hdHRyaWJ1dGVzW2ldOyBpZiAocHJlZml4ID09ICcqJyAmJiBhLm5hbWUgPT0gYS5sb2NhbE5hbWUpIHsgYS5uYW1lc3BhY2UgPSBuYW1lc3BhY2U7IH0gZWxzZSBpZiAocHJlZml4ICE9ICcqJyAmJiBhLm5hbWUgIT0gYS5sb2NhbE5hbWUpIHsgdmFyIHBmeCA9IGEubmFtZS5zcGxpdCgnOicpWzBdOyBpZiAocGZ4ID09IHByZWZpeCkgeyBhLm5hbWVzcGFjZSA9IG5hbWVzcGFjZTsgfSB9IH0gfSB9CiAgICAgICAgdGhpcy5nZXROYW1lc3BhY2UgPSBmdW5jdGlvbiAocHJlZml4KSB7IGZvciAodmFyIGkgPSB0aGlzLnRyZWUubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHsgaWYgKHRoaXMudHJlZVtpXS5uc1RhYmxlW3ByZWZpeF0gIT0gbnVsbCkgeyByZXR1cm4gKHRoaXMudHJlZVtpXS5uc1RhYmxlW3ByZWZpeF0pOyB9IH0gcmV0dXJuIG51bGw7IH0NCiAgICB9CiAgICBmdW5jdGlvbiBfdHVyblRvWG1sKHRleHQpIHsgaWYgKHRleHQgPT0gbnVsbCkgcmV0dXJuIG51bGw7IHJldHVybiAoeyBjaGlsZE5vZGVzOiBbX3R1cm5Ub1htbFJlYyh0ZXh0KV0sIGdldEVsZW1lbnRzQnlUYWdOYW1lOiBfZ2V0RWxlbWVudHNCeVRhZ05hbWUsIGdldENoaWxkRWxlbWVudHNCeVRhZ05hbWU6IF9nZXRDaGlsZEVsZW1lbnRzQnlUYWdOYW1lLCBnZXRFbGVtZW50c0J5VGFnTmFtZU5TOiBfZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyB9KTsgfQogICAgZnVuY3Rpb24gX2dldEVsZW1lbnRzQnlUYWdOYW1lTlMobnMsIG5hbWUpIHsgdmFyIHJldCA9IFtdOyBfeG1sVHJhdmVyc2VBbGxSZWModGhpcy5jaGlsZE5vZGVzLCBmdW5jdGlvbiAobm9kZSkgeyBpZiAobm9kZS5sb2NhbE5hbWUgPT0gbmFtZSAmJiAobm9kZS5uYW1lc3BhY2UgPT0gbnMgfHwgbnMgPT0gJyonKSkgeyByZXQucHVzaChub2RlKTsgfSB9KTsgcmV0dXJuIHJldDsgfQogICAgZnVuY3Rpb24gX2dldEVsZW1lbnRzQnlUYWdOYW1lKG5hbWUpIHsgdmFyIHJldCA9IFtdOyBfeG1sVHJhdmVyc2VBbGxSZWModGhpcy5jaGlsZE5vZGVzLCBmdW5jdGlvbiAobm9kZSkgeyBpZiAobm9kZS5sb2NhbE5hbWUgPT0gbmFtZSkgeyByZXQucHVzaChub2RlKTsgfSB9KTsgcmV0dXJuIHJldDsgfQogICAgZnVuY3Rpb24gX2dldENoaWxkRWxlbWVudHNCeVRhZ05hbWUobmFtZSkgeyB2YXIgcmV0ID0gW107IGlmICh0aGlzLmNoaWxkTm9kZXMgIT0gbnVsbCkgeyBmb3IgKHZhciBub2RlIGluIHRoaXMuY2hpbGROb2RlcykgeyBpZiAodGhpcy5jaGlsZE5vZGVzW25vZGVdLmxvY2FsTmFtZSA9PSBuYW1lKSB7IHJldC5wdXNoKHRoaXMuY2hpbGROb2Rlc1tub2RlXSk7IH0gfSB9IHJldHVybiAocmV0KTsgfQogICAgZnVuY3Rpb24gX2dldENoaWxkRWxlbWVudHNCeVRhZ05hbWVOUyhucywgbmFtZSkgeyB2YXIgcmV0ID0gW107IGlmICh0aGlzLmNoaWxkTm9kZXMgIT0gbnVsbCkgeyBmb3IgKHZhciBub2RlIGluIHRoaXMuY2hpbGROb2RlcykgeyBpZiAodGhpcy5jaGlsZE5vZGVzW25vZGVdLmxvY2FsTmFtZSA9PSBuYW1lICYmIChucyA9PSAnKicgfHwgdGhpcy5jaGlsZE5vZGVzW25vZGVdLm5hbWVzcGFjZSA9PSBucykpIHsgcmV0LnB1c2godGhpcy5jaGlsZE5vZGVzW25vZGVdKTsgfSB9IH0gcmV0dXJuIChyZXQpOyB9CiAgICBmdW5jdGlvbiBfeG1sVHJhdmVyc2VBbGxSZWMobm9kZXMsIGZ1bmMpIHsgZm9yICh2YXIgaSBpbiBub2RlcykgeyBmdW5jKG5vZGVzW2ldKTsgaWYgKG5vZGVzW2ldLmNoaWxkTm9kZXMpIHsgX3htbFRyYXZlcnNlQWxsUmVjKG5vZGVzW2ldLmNoaWxkTm9kZXMsIGZ1bmMpOyB9IH0gfQogICAgZnVuY3Rpb24gX3R1cm5Ub1htbFJlYyh0ZXh0KSB7DQogICAgICAgIHZhciBlbGVtZW50U3RhY2sgPSBuZXcgX3RyZWVCdWlsZGVyKCksIGxhc3RFbGVtZW50ID0gbnVsbCwgeDEgPSB0ZXh0LnNwbGl0KCc8JyksIHJldCA9IFtdLCBlbGVtZW50ID0gbnVsbCwgY3VycmVudEVsZW1lbnROYW1lID0gbnVsbDsKICAgICAgICBmb3IgKHZhciBpIGluIHgxKSB7DQogICAgICAgICAgICB2YXIgeDIgPSB4MVtpXS5zcGxpdCgnPicpLCB4MyA9IHgyWzBdLnNwbGl0KCcgJyksIGVsZW1lbnROYW1lID0geDNbMF07CiAgICAgICAgICAgIGlmICgoZWxlbWVudE5hbWUubGVuZ3RoID4gMCkgJiYgKGVsZW1lbnROYW1lWzBdICE9ICc/JykpIHsNCiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudE5hbWVbMF0gIT0gJy8nKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0gW10sIGxvY2FsTmFtZSwgbG9jYWxuYW1lMiA9IGVsZW1lbnROYW1lLnNwbGl0KCcgJylbMF0uc3BsaXQoJzonKSwgbG9jYWxOYW1lID0gKGxvY2FsbmFtZTIubGVuZ3RoID4gMSkgPyBsb2NhbG5hbWUyWzFdIDogbG9jYWxuYW1lMlswXTsKICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYXR0cmlidXRlcywgImdldCIsCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAxKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGEgaW4gdGhpcykgeyBpZiAodGhpc1thXS5uYW1lID09IGFyZ3VtZW50c1swXSkgeyByZXR1cm4gKHRoaXNbYV0pOyB9IH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDIpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgYSBpbiB0aGlzKSB7IGlmICh0aGlzW2FdLm5hbWUgPT0gYXJndW1lbnRzWzFdICYmIChhcmd1bWVudHNbMF0gPT0gJyonIHx8IHRoaXNbYV0ubmFtZXNwYWNlID09IGFyZ3VtZW50c1swXSkpIHsgcmV0dXJuICh0aGlzW2FdKTsgfSB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICgnYXR0cmlidXRlcy5nZXQoKTogSW52YWxpZCBudW1iZXIgb2YgcGFyYW1ldGVycycpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudFN0YWNrLnB1c2goeyBuYW1lOiBlbGVtZW50TmFtZSwgbG9jYWxOYW1lOiBsb2NhbE5hbWUsIGdldENoaWxkRWxlbWVudHNCeVRhZ05hbWU6IF9nZXRDaGlsZEVsZW1lbnRzQnlUYWdOYW1lLCBnZXRFbGVtZW50c0J5VGFnTmFtZU5TOiBfZ2V0RWxlbWVudHNCeVRhZ05hbWVOUywgZ2V0Q2hpbGRFbGVtZW50c0J5VGFnTmFtZU5TOiBfZ2V0Q2hpbGRFbGVtZW50c0J5VGFnTmFtZU5TLCBhdHRyaWJ1dGVzOiBhdHRyaWJ1dGVzLCBjaGlsZE5vZGVzOiBbXSwgbnNUYWJsZToge30gfSk7CiAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgQXR0cmlidXRlcwogICAgICAgICAgICAgICAgICAgIGlmICh4My5sZW5ndGggPiAwKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2tpcCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqIGluIHgzKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHgzW2pdID09ICcvJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYW4gZW1wdHkgRWxlbWVudAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdGFjay5wZWVrKCkubmFtZXNwYWNlID0gZWxlbWVudFN0YWNrLnBlZWsoKS5uYW1lID09IGVsZW1lbnRTdGFjay5wZWVrKCkubG9jYWxOYW1lID8gZWxlbWVudFN0YWNrLmdldE5hbWVzcGFjZSgnKicpIDogZWxlbWVudFN0YWNrLmdldE5hbWVzcGFjZShlbGVtZW50U3RhY2sucGVlaygpLm5hbWUuc3Vic3RyaW5nKDAsIGVsZW1lbnRTdGFjay5wZWVrKCkubmFtZS5pbmRleE9mKCc6JykpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3RhY2sucGVlaygpLnRleHRDb250ZW50ID0gJyc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdEVsZW1lbnQgPSBlbGVtZW50U3RhY2sucG9wKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2tpcCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGsgPSB4M1tqXS5pbmRleE9mKCc9Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoayA+IDApIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJOYW1lID0geDNbal0uc3Vic3RyaW5nKDAsIGspOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRyVmFsdWUgPSB4M1tqXS5zdWJzdHJpbmcoayArIDIsIHgzW2pdLmxlbmd0aCAtIDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRyTlMgPSBlbGVtZW50U3RhY2suZ2V0TmFtZXNwYWNlKCcqJyk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyTmFtZSA9PSAneG1sbnMnKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3RhY2suYWRkTmFtZXNwYWNlKCcqJywgYXR0clZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ck5TID0gYXR0clZhbHVlOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGF0dHJOYW1lLnN0YXJ0c1dpdGgoJ3htbG5zOicpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3RhY2suYWRkTmFtZXNwYWNlKGF0dHJOYW1lLnN1YnN0cmluZyg2KSwgYXR0clZhbHVlKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBheCA9IGF0dHJOYW1lLnNwbGl0KCc6Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChheC5sZW5ndGggPT0gMikgeyBhdHRyTmFtZSA9IGF4WzFdOyBhdHRyTlMgPSBlbGVtZW50U3RhY2suZ2V0TmFtZXNwYWNlKGF4WzBdKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHggPSB7IG5hbWU6IGF0dHJOYW1lLCB2YWx1ZTogYXR0clZhbHVlIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ck5TICE9IG51bGwpIHgubmFtZXNwYWNlID0gYXR0ck5TOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdGFjay5wZWVrKCkuYXR0cmlidXRlcy5wdXNoKHgpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNraXApIHsgY29udGludWU7IH0NCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdGFjay5wZWVrKCkubmFtZXNwYWNlID0gZWxlbWVudFN0YWNrLnBlZWsoKS5uYW1lID09IGVsZW1lbnRTdGFjay5wZWVrKCkubG9jYWxOYW1lID8gZWxlbWVudFN0YWNrLmdldE5hbWVzcGFjZSgnKicpIDogZWxlbWVudFN0YWNrLmdldE5hbWVzcGFjZShlbGVtZW50U3RhY2sucGVlaygpLm5hbWUuc3Vic3RyaW5nKDAsIGVsZW1lbnRTdGFjay5wZWVrKCkubmFtZS5pbmRleE9mKCc6JykpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoeDJbMV0pIHsgZWxlbWVudFN0YWNrLnBlZWsoKS50ZXh0Q29udGVudCA9IHgyWzFdOyB9DQogICAgICAgICAgICAgICAgfSBlbHNlIHsgbGFzdEVsZW1lbnQgPSBlbGVtZW50U3RhY2sucG9wKCk7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQogICAgICAgIHJldHVybiBsYXN0RWxlbWVudDsNCiAgICB9DQogICAgKi8NCg0KICAgIHJldHVybiBvYmo7DQp9DQovKioNCiogQGZpbGVvdmVydmlldyBJbnRlbChyKSBBTVQgQ29tbXVuaWNhdGlvbiBTdGFja1hYDQoqIEBhdXRob3IgWWxpYW4gU2FpbnQtSGlsYWlyZQ0KKiBAdmVyc2lvbiB2MC4yLjBiDQoqLw0KDQovKioNCiAqIENvbnN0cnVjdCBhIEFtdFN0YWNrQ3JlYXRlU2VydmljZSBvYmplY3QsIHRoaXMgaWEgdGhlIG1haW4gSW50ZWwgQU1UIGNvbW11bmljYXRpb24gc3RhY2suDQogKiBAY29uc3RydWN0b3INCiAqLw0KZnVuY3Rpb24gQW10U3RhY2tDcmVhdGVTZXJ2aWNlKHdzbWFuU3RhY2spIHsNCiAgICB2YXIgb2JqID0gbmV3IE9iamVjdCgpOw0KICAgIG9iai53c21hbiA9IHdzbWFuU3RhY2s7DQogICAgb2JqLnBmeCA9IFsiaHR0cDovL2ludGVsLmNvbS93YmVtL3dzY2ltLzEvYW10LXNjaGVtYS8xLyIsICJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yLyIsICJodHRwOi8vaW50ZWwuY29tL3diZW0vd3NjaW0vMS9pcHMtc2NoZW1hLzEvIl07DQogICAgb2JqLlBlbmRpbmdFbnVtcyA9IFtdOw0KICAgIG9iai5QZW5kaW5nQmF0Y2hPcGVyYXRpb25zID0gMDsNCiAgICBvYmouQWN0aXZlRW51bXNDb3VudCA9IDA7DQogICAgb2JqLk1heEFjdGl2ZUVudW1zQ291bnQgPSAxOyAvLyBNYXhpbXVtIG51bWJlciBvZiBlbnVtZXJhdGlvbnMgdGhhdCBjYW4gYmUgZG9uZSBhdCB0aGUgc2FtZSB0aW1lLg0KICAgIG9iai5vblByb2Nlc3NDaGFuZ2VkID0gbnVsbDsNCiAgICB2YXIgX01heFByb2Nlc3MgPSAwOw0KICAgIHZhciBfTGFzdFByb2Nlc3MgPSAwOw0KDQogICAgLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgcGVuZGluZyBhY3Rpb25zDQogICAgb2JqLkdldFBlbmRpbmdBY3Rpb25zID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gKG9iai5QZW5kaW5nRW51bXMubGVuZ3RoICogMikgKyAob2JqLkFjdGl2ZUVudW1zQ291bnQpICsgb2JqLndzbWFuLmNvbW0uUGVuZGluZ0FqYXgubGVuZ3RoICsgb2JqLndzbWFuLmNvbW0uQWN0aXZlQWpheENvdW50ICsgb2JqLlBlbmRpbmdCYXRjaE9wZXJhdGlvbnM7IH0NCg0KICAgIC8vIFByaXZhdGUgTWV0aG9kLCBVcGRhdGUgdGhlIGN1cnJlbnQgcHJvY2Vzc2luZyBzdGF0dXMsIHRoaXMgZ2l2ZXMgdGhlIGFwcGxpY2F0aW9uIGFuIGlkZWEgb2Ygd2hhdCBwcm9ncmVzcyBpcyBiZWluZyBkb25lIGJ5IHRoZSBXU01BTiBzdGFjaw0KICAgIGZ1bmN0aW9uIF91cCgpIHsNCiAgICAgICAgdmFyIHggPSBvYmouR2V0UGVuZGluZ0FjdGlvbnMoKTsNCiAgICAgICAgaWYgKF9NYXhQcm9jZXNzIDwgeCkgX01heFByb2Nlc3MgPSB4Ow0KICAgICAgICBpZiAob2JqLm9uUHJvY2Vzc0NoYW5nZWQgIT0gbnVsbCAmJiBfTGFzdFByb2Nlc3MgIT0geCkgew0KICAgICAgICAgICAgLy9jb25zb2xlLmxvZygiUHJvY2VzcyBPbGQ9IiArIF9MYXN0UHJvY2VzcyArICIsIE5ldz0iICsgeCArICIsIFBFbnVtcz0iICsgb2JqLlBlbmRpbmdFbnVtcy5sZW5ndGggKyAiLCBBRW51bXM9IiArIG9iai5BY3RpdmVFbnVtc0NvdW50ICsgIiwgUEFqYXg9IiArIG9iai53c21hbi5jb21tLlBlbmRpbmdBamF4Lmxlbmd0aCArICIsIEFBamF4PSIgKyBvYmoud3NtYW4uY29tbS5BY3RpdmVBamF4Q291bnQgKyAiLCBQQmF0Y2g9IiArIG9iai5QZW5kaW5nQmF0Y2hPcGVyYXRpb25zKTsNCiAgICAgICAgICAgIF9MYXN0UHJvY2VzcyA9IHg7DQogICAgICAgICAgICBvYmoub25Qcm9jZXNzQ2hhbmdlZCh4LCBfTWF4UHJvY2Vzcyk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKHggPT0gMCkgX01heFByb2Nlc3MgPSAwOw0KICAgIH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiAiU1VCU0NSSUJFIiBvcGVyYXRpb24uDQogICAgb2JqLlN1YnNjcmliZSA9IGZ1bmN0aW9uIChuYW1lLCBkZWxpdmVyeSwgdXJsLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycywgb3BhcXVlLCB1c2VyLCBwYXNzKSB7IG9iai53c21hbi5FeGVjU3Vic2NyaWJlKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIGRlbGl2ZXJ5LCB1cmwsIGZ1bmN0aW9uICh3cywgcmVzdXJpLCByZXNwb25zZSwgeHN0YXR1cykgeyBfdXAoKTsgY2FsbGJhY2sob2JqLCBuYW1lLCByZXNwb25zZSwgeHN0YXR1cywgdGFnKTsgfSwgMCwgcHJpLCBzZWxlY3RvcnMsIG9wYXF1ZSwgdXNlciwgcGFzcyk7IF91cCgpOyB9DQoNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gIlVOU1VCU0NSSUJFIiBvcGVyYXRpb24uDQogICAgb2JqLlVuU3Vic2NyaWJlID0gZnVuY3Rpb24gKG5hbWUsIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai53c21hbi5FeGVjVW5TdWJzY3JpYmUob2JqLkNvbXBsZXRlTmFtZShuYW1lKSwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcpOyB9LCAwLCBwcmksIHNlbGVjdG9ycyk7IF91cCgpOyB9DQoNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gIkdFVCIgb3BlcmF0aW9uLg0KICAgIG9iai5HZXQgPSBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2ssIHRhZywgcHJpKSB7IG9iai53c21hbi5FeGVjR2V0KG9iai5Db21wbGV0ZU5hbWUobmFtZSksIGZ1bmN0aW9uICh3cywgcmVzdXJpLCByZXNwb25zZSwgeHN0YXR1cykgeyBfdXAoKTsgY2FsbGJhY2sob2JqLCBuYW1lLCByZXNwb25zZSwgeHN0YXR1cywgdGFnKTsgfSwgMCwgcHJpKTsgX3VwKCk7IH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiAiUFVUIiBvcGVyYXRpb24uDQogICAgb2JqLlB1dCA9IGZ1bmN0aW9uIChuYW1lLCBwdXRvYmosIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai53c21hbi5FeGVjUHV0KG9iai5Db21wbGV0ZU5hbWUobmFtZSksIHB1dG9iaiwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcpOyB9LCAwLCBwcmksIHNlbGVjdG9ycyk7IF91cCgpOyB9DQoJDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOICJDUkVBVEUiIG9wZXJhdGlvbi4NCiAgICBvYmouQ3JlYXRlID0gZnVuY3Rpb24gKG5hbWUsIHB1dG9iaiwgY2FsbGJhY2ssIHRhZywgcHJpKSB7IG9iai53c21hbi5FeGVjQ3JlYXRlKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIHB1dG9iaiwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcpOyB9LCAwLCBwcmkpOyBfdXAoKTsgfQ0KDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOICJERUxFVEUiIG9wZXJhdGlvbi4NCiAgICBvYmouRGVsZXRlID0gZnVuY3Rpb24gKG5hbWUsIHB1dG9iaiwgY2FsbGJhY2ssIHRhZywgcHJpKSB7IG9iai53c21hbi5FeGVjRGVsZXRlKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIHB1dG9iaiwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcpOyB9LCAwLCBwcmkpOyBfdXAoKTsgfQ0KDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOIG1ldGhvZCBjYWxsIG9wZXJhdGlvbi4NCiAgICBvYmouRXhlYyA9IGZ1bmN0aW9uIChuYW1lLCBtZXRob2QsIGFyZ3MsIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai53c21hbi5FeGVjTWV0aG9kKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIG1ldGhvZCwgYXJncywgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIG9iai5Db21wbGV0ZUV4ZWNSZXNwb25zZShyZXNwb25zZSksIHhzdGF0dXMsIHRhZyk7IH0sIDAsIHByaSwgc2VsZWN0b3JzKTsgX3VwKCk7IH0NCgkNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gbWV0aG9kIGNhbGwgb3BlcmF0aW9uLg0KICAgIG9iai5FeGVjV2l0aFhtbCA9IGZ1bmN0aW9uIChuYW1lLCBtZXRob2QsIGFyZ3MsIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai53c21hbi5FeGVjTWV0aG9kWG1sKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIG1ldGhvZCwgZXhlY0FyZ3VtZW50c1RvWG1sKGFyZ3MpLCBmdW5jdGlvbiAod3MsIHJlc3VyaSwgcmVzcG9uc2UsIHhzdGF0dXMpIHsgX3VwKCk7IGNhbGxiYWNrKG9iaiwgbmFtZSwgb2JqLkNvbXBsZXRlRXhlY1Jlc3BvbnNlKHJlc3BvbnNlKSwgeHN0YXR1cywgdGFnKTsgfSwgMCwgcHJpLCBzZWxlY3RvcnMpOyBfdXAoKTsgfQ0KCQ0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiAiRU5VTUVSQVRFIiBvcGVyYXRpb24uDQogICAgb2JqLkVudW0gPSBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2ssIHRhZywgcHJpKSB7DQogICAgICAgIGlmIChvYmouQWN0aXZlRW51bXNDb3VudCA8IG9iai5NYXhBY3RpdmVFbnVtc0NvdW50KSB7DQogICAgICAgICAgICBvYmouQWN0aXZlRW51bXNDb3VudCsrOyBvYmoud3NtYW4uRXhlY0VudW0ob2JqLkNvbXBsZXRlTmFtZShuYW1lKSwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcwKSB7IF91cCgpOyBfRW51bVN0YXJ0U2luayhuYW1lLCByZXNwb25zZSwgY2FsbGJhY2ssIHJlc3VyaSwgeHN0YXR1cywgdGFnMCk7IH0sIHRhZywgcHJpKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIG9iai5QZW5kaW5nRW51bXMucHVzaChbbmFtZSwgY2FsbGJhY2ssIHRhZywgcHJpXSk7DQogICAgICAgIH0NCiAgICAgICAgX3VwKCk7DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfRW51bVN0YXJ0U2luayhuYW1lLCByZXNwb25zZSwgY2FsbGJhY2ssIHJlc3VyaSwgc3RhdHVzLCB0YWcsIHByaSkgew0KICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBjYWxsYmFjayhvYmosIG5hbWUsIG51bGwsIHN0YXR1cywgdGFnKTsgX0VudW1Eb05leHQoMSk7IHJldHVybjsgfQ0KICAgICAgICBpZiAocmVzcG9uc2UgPT0gbnVsbCB8fCByZXNwb25zZS5IZWFkZXJbIk1ldGhvZCJdICE9ICJFbnVtZXJhdGVSZXNwb25zZSIgfHwgIXJlc3BvbnNlLkJvZHlbIkVudW1lcmF0aW9uQ29udGV4dCJdKSB7IGNhbGxiYWNrKG9iaiwgbmFtZSwgbnVsbCwgNjAzLCB0YWcpOyBfRW51bURvTmV4dCgxKTsgcmV0dXJuOyB9DQogICAgICAgIHZhciBlbnVtY3R4ID0gcmVzcG9uc2UuQm9keVsiRW51bWVyYXRpb25Db250ZXh0Il07DQogICAgICAgIG9iai53c21hbi5FeGVjUHVsbChyZXN1cmksIGVudW1jdHgsIGZ1bmN0aW9uICh3cywgcmVzdXJpLCByZXNwb25zZSwgeHN0YXR1cykgeyBfRW51bUNvbnRpbnVlU2luayhuYW1lLCByZXNwb25zZSwgY2FsbGJhY2ssIHJlc3VyaSwgW10sIHhzdGF0dXMsIHRhZywgcHJpKTsgfSk7DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfRW51bUNvbnRpbnVlU2luayhuYW1lLCByZXNwb25zZSwgY2FsbGJhY2ssIHJlc3VyaSwgaXRlbXMsIHN0YXR1cywgdGFnLCBwcmkpIHsNCiAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsgY2FsbGJhY2sob2JqLCBuYW1lLCBudWxsLCBzdGF0dXMsIHRhZyk7IF9FbnVtRG9OZXh0KDEpOyByZXR1cm47IH0NCiAgICAgICAgaWYgKHJlc3BvbnNlID09IG51bGwgfHwgcmVzcG9uc2UuSGVhZGVyWyJNZXRob2QiXSAhPSAiUHVsbFJlc3BvbnNlIikgeyBjYWxsYmFjayhvYmosIG5hbWUsIG51bGwsIDYwNCwgdGFnKTsgX0VudW1Eb05leHQoMSk7IHJldHVybjsgfQ0KICAgICAgICBmb3IgKHZhciBpIGluIHJlc3BvbnNlLkJvZHlbIkl0ZW1zIl0pIHsNCiAgICAgICAgICAgIGlmIChyZXNwb25zZS5Cb2R5WyJJdGVtcyJdW2ldIGluc3RhbmNlb2YgQXJyYXkpIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBqIGluIHJlc3BvbnNlLkJvZHlbIkl0ZW1zIl1baV0pIHsgaWYgKHR5cGVvZiByZXNwb25zZS5Cb2R5WyJJdGVtcyJdW2ldW2pdICE9ICdmdW5jdGlvbicpIHsgaXRlbXMucHVzaChyZXNwb25zZS5Cb2R5WyJJdGVtcyJdW2ldW2pdKTsgfSB9DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzcG9uc2UuQm9keVsiSXRlbXMiXVtpXSAhPSAnZnVuY3Rpb24nKSB7IGl0ZW1zLnB1c2gocmVzcG9uc2UuQm9keVsiSXRlbXMiXVtpXSk7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBpZiAocmVzcG9uc2UuQm9keVsiRW51bWVyYXRpb25Db250ZXh0Il0pIHsNCiAgICAgICAgICAgIHZhciBlbnVtY3R4ID0gcmVzcG9uc2UuQm9keVsiRW51bWVyYXRpb25Db250ZXh0Il07DQogICAgICAgICAgICBvYmoud3NtYW4uRXhlY1B1bGwocmVzdXJpLCBlbnVtY3R4LCBmdW5jdGlvbiAod3MsIHJlc3VyaSwgcmVzcG9uc2UsIHhzdGF0dXMpIHsgX0VudW1Db250aW51ZVNpbmsobmFtZSwgcmVzcG9uc2UsIGNhbGxiYWNrLCByZXN1cmksIGl0ZW1zLCB4c3RhdHVzLCB0YWcsIDEpOyB9KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIF9FbnVtRG9OZXh0KDEpOw0KICAgICAgICAgICAgY2FsbGJhY2sob2JqLCBuYW1lLCBpdGVtcywgc3RhdHVzLCB0YWcpOw0KICAgICAgICAgICAgX3VwKCk7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIGZ1bmN0aW9uIF9FbnVtRG9OZXh0KGRlYykgew0KICAgICAgICBvYmouQWN0aXZlRW51bXNDb3VudCAtPSBkZWM7DQogICAgICAgIGlmIChvYmouQWN0aXZlRW51bXNDb3VudCA+PSBvYmouTWF4QWN0aXZlRW51bXNDb3VudCB8fCBvYmouUGVuZGluZ0VudW1zLmxlbmd0aCA9PSAwKSB7IF91cCgpOyByZXR1cm47IH0NCiAgICAgICAgdmFyIHggPSBvYmouUGVuZGluZ0VudW1zLnNoaWZ0KCk7DQogICAgICAgIG9iai5FbnVtKHhbMF0sIHhbMV0sIHhbMl0pOw0KICAgICAgICBfRW51bURvTmV4dCgwKTsNCiAgICB9DQoNCiAgICAvLyBQZXJmb3JtIGEgYmF0Y2ggb2YgV1NNQU4gIkVOVU0iIG9wZXJhdGlvbnMuDQogICAgb2JqLkJhdGNoRW51bSA9IGZ1bmN0aW9uIChiYXRjaG5hbWUsIG5hbWVzLCBjYWxsYmFjaywgdGFnLCBjb250aW51ZU9uRXJyb3IsIHByaSkgew0KICAgICAgICBvYmouUGVuZGluZ0JhdGNoT3BlcmF0aW9ucyArPSAobmFtZXMubGVuZ3RoICogMik7DQogICAgICAgIF9CYXRjaE5leHRFbnVtKGJhdGNobmFtZSwgQ2xvbmUobmFtZXMpLCBjYWxsYmFjaywgdGFnLCB7fSwgY29udGludWVPbkVycm9yLCBwcmkpOyBfdXAoKTsNCiAgICB9DQoNCiAgICAvLyBSZXF1ZXN0IGVhY2ggZW51bSBpbiB0aGUgYmF0Y2gsIHN0b3BwaW5nIGlmIHNvbWV0aGluZyBkb2VzIG5vdCByZXR1cm4gc3RhdHVzIDIwMA0KICAgIGZ1bmN0aW9uIF9CYXRjaE5leHRFbnVtKGJhdGNobmFtZSwgbmFtZXMsIGNhbGxiYWNrLCB0YWcsIHJlc3VsdHMsIGNvbnRpbnVlT25FcnJvciwgcHJpKSB7DQogICAgICAgIG9iai5QZW5kaW5nQmF0Y2hPcGVyYXRpb25zIC09IDI7DQogICAgICAgIHZhciBuID0gbmFtZXMuc2hpZnQoKSwgZiA9IG9iai5FbnVtOw0KICAgICAgICBpZiAoblswXSA9PSAnKicpIHsgZiA9IG9iai5HZXQ7IG4gPSBuLnN1YnN0cmluZygxKTsgfSAvLyBJZiB0aGUgbmFtZSBzdGFydHMgd2l0aCBhIHN0YXIsIGRvIGEgR0VUIGluc3RlYWQgb2YgYW4gRU5VTS4gVGhpcyB3aWxsIHJlZHVjZSByb3VuZCB0cmlwcy4NCiAgICAgICAgLy9jb25zb2xlLmxvZygoZiA9PSBvYmouR2V0PydHZXQgJzonRW51bSAnKSArIG4pOw0KICAgICAgICAvLyBQZXJmb3JtIGEgR0VUL0VOVU0gYWN0aW9uDQogICAgICAgIGYobiwgZnVuY3Rpb24gKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cywgdGFnMCkgew0KICAgICAgICAgICAgdGFnMFsyXVtuYW1lXSA9IHsgcmVzcG9uc2U6IChyZXNwb25zZXM9PW51bGw/bnVsbDpyZXNwb25zZXMuQm9keSksIHJlc3BvbnNlczogcmVzcG9uc2VzLCBzdGF0dXM6IHN0YXR1cyB9Ow0KICAgICAgICAgICAgaWYgKHRhZzBbMV0ubGVuZ3RoID09IDAgfHwgc3RhdHVzID09IDQwMSB8fCAoY29udGludWVPbkVycm9yICE9IHRydWUgJiYgc3RhdHVzICE9IDIwMCAmJiBzdGF0dXMgIT0gNDAwKSkgeyBvYmouUGVuZGluZ0JhdGNoT3BlcmF0aW9ucyAtPSAobmFtZXMubGVuZ3RoICogMik7IF91cCgpOyBjYWxsYmFjayhvYmosIGJhdGNobmFtZSwgdGFnMFsyXSwgc3RhdHVzLCB0YWcpOyB9DQogICAgICAgICAgICBlbHNlIHsgX3VwKCk7IF9CYXRjaE5leHRFbnVtKGJhdGNobmFtZSwgbmFtZXMsIGNhbGxiYWNrLCB0YWcsIHRhZzBbMl0sIHByaSk7IH0NCiAgICAgICAgfSwgW2JhdGNobmFtZSwgbmFtZXMsIHJlc3VsdHNdLCBwcmkpOw0KICAgICAgICBfdXAoKTsNCiAgICB9DQoNCiAgICAvLyBQZXJmb3JtIGEgYmF0Y2ggb2YgV1NNQU4gIkdFVCIgb3BlcmF0aW9ucy4NCiAgICBvYmouQmF0Y2hHZXQgPSBmdW5jdGlvbiAoYmF0Y2huYW1lLCBuYW1lcywgY2FsbGJhY2ssIHRhZywgcHJpKSB7DQogICAgICAgIF9GZXRjaE5leHQoeyBuYW1lOiBiYXRjaG5hbWUsIG5hbWVzOiBuYW1lcywgY2FsbGJhY2s6IGNhbGxiYWNrLCBjdXJyZW50OiAwLCByZXNwb25zZXM6IHt9LCB0YWc6IHRhZywgcHJpOiBwcmkgfSk7IF91cCgpOw0KICAgIH0NCg0KICAgIC8vIFByaXZhdGUgbWV0aG9kDQogICAgZnVuY3Rpb24gX0ZldGNoTmV4dChiYXRjaCkgew0KICAgICAgICBpZiAoYmF0Y2gubmFtZXMubGVuZ3RoIDw9IGJhdGNoLmN1cnJlbnQpIHsNCiAgICAgICAgICAgIGJhdGNoLmNhbGxiYWNrKG9iaiwgYmF0Y2gubmFtZSwgYmF0Y2gucmVzcG9uc2VzLCAyMDAsIGJhdGNoLnRhZyk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBvYmoud3NtYW4uRXhlY0dldChvYmouQ29tcGxldGVOYW1lKGJhdGNoLm5hbWVzW2JhdGNoLmN1cnJlbnRdKSwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF9GZXRjaGVkKGJhdGNoLCByZXNwb25zZSwgeHN0YXR1cyk7IH0sIGJhdGNoLnByaSk7DQogICAgICAgICAgICBiYXRjaC5jdXJyZW50Kys7DQogICAgICAgIH0NCiAgICAgICAgX3VwKCk7DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfRmV0Y2hlZChiYXRjaCwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICBpZiAocmVzcG9uc2UgPT0gbnVsbCB8fCBzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICBiYXRjaC5jYWxsYmFjayhvYmosIGJhdGNoLm5hbWUsIG51bGwsIHN0YXR1cywgYmF0Y2gudGFnKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGJhdGNoLnJlc3BvbnNlc1tyZXNwb25zZS5IZWFkZXJbIk1ldGhvZCJdXSA9IHJlc3BvbnNlOw0KICAgICAgICAgICAgX0ZldGNoTmV4dChiYXRjaCk7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIG9iai5Db21wbGV0ZU5hbWUgPSBmdW5jdGlvbihuYW1lKSB7DQogICAgICAgIGlmIChuYW1lLmluZGV4T2YoIkFNVF8iKSA9PSAwKSByZXR1cm4gb2JqLnBmeFswXSArIG5hbWU7DQogICAgICAgIGlmIChuYW1lLmluZGV4T2YoIkNJTV8iKSA9PSAwKSByZXR1cm4gb2JqLnBmeFsxXSArIG5hbWU7DQogICAgICAgIGlmIChuYW1lLmluZGV4T2YoIklQU18iKSA9PSAwKSByZXR1cm4gb2JqLnBmeFsyXSArIG5hbWU7DQogICAgfQ0KDQogICAgb2JqLkNvbXBsZXRlRXhlY1Jlc3BvbnNlID0gZnVuY3Rpb24gKHJlc3ApIHsNCiAgICAgICAgaWYgKHJlc3AgJiYgcmVzcCAhPSBudWxsICYmIHJlc3AuQm9keSAmJiAocmVzcC5Cb2R5WyJSZXR1cm5WYWx1ZSJdICE9IHVuZGVmaW5lZCkpIHsgcmVzcC5Cb2R5LlJldHVyblZhbHVlU3RyID0gb2JqLkFtdFN0YXR1c1RvU3RyKHJlc3AuQm9keVsiUmV0dXJuVmFsdWUiXSk7IH0NCiAgICAgICAgcmV0dXJuIHJlc3A7DQogICAgfQ0KDQogICAgb2JqLlJlcXVlc3RQb3dlclN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFBvd2VyU3RhdGUsIGNhbGxiYWNrX2Z1bmMpIHsNCiAgICAgICAgb2JqLkNJTV9Qb3dlck1hbmFnZW1lbnRTZXJ2aWNlX1JlcXVlc3RQb3dlclN0YXRlQ2hhbmdlKFBvd2VyU3RhdGUsICI8QWRkcmVzcyB4bWxucz1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZ1wiPmh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZzwvQWRkcmVzcz48UmVmZXJlbmNlUGFyYW1ldGVycyB4bWxucz1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZ1wiPjxSZXNvdXJjZVVSSSB4bWxucz1cImh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2RcIj5odHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9Db21wdXRlclN5c3RlbTwvUmVzb3VyY2VVUkk+PFNlbGVjdG9yU2V0IHhtbG5zPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZFwiPjxTZWxlY3RvciBOYW1lPVwiQ3JlYXRpb25DbGFzc05hbWVcIj5DSU1fQ29tcHV0ZXJTeXN0ZW08L1NlbGVjdG9yPjxTZWxlY3RvciBOYW1lPVwiTmFtZVwiPk1hbmFnZWRTeXN0ZW08L1NlbGVjdG9yPjwvU2VsZWN0b3JTZXQ+PC9SZWZlcmVuY2VQYXJhbWV0ZXJzPiIsIG51bGwsIG51bGwsIGNhbGxiYWNrX2Z1bmMpOw0KICAgIH0NCg0KICAgIG9iai5TZXRCb290Q29uZmlnUm9sZSA9IGZ1bmN0aW9uIChSb2xlLCBjYWxsYmFja19mdW5jKSB7DQogICAgICAgIG9iai5DSU1fQm9vdFNlcnZpY2VfU2V0Qm9vdENvbmZpZ1JvbGUoIjxBZGRyZXNzIHhtbG5zPVwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nXCI+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nPC9BZGRyZXNzPjxSZWZlcmVuY2VQYXJhbWV0ZXJzIHhtbG5zPVwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nXCI+PFJlc291cmNlVVJJIHhtbG5zPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZFwiPmh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NjaW0vMS9jaW0tc2NoZW1hLzIvQ0lNX0Jvb3RDb25maWdTZXR0aW5nPC9SZXNvdXJjZVVSST48U2VsZWN0b3JTZXQgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkXCI+PFNlbGVjdG9yIE5hbWU9XCJJbnN0YW5jZUlEXCI+SW50ZWwocikgQU1UOiBCb290IENvbmZpZ3VyYXRpb24gMDwvU2VsZWN0b3I+PC9TZWxlY3RvclNldD48L1JlZmVyZW5jZVBhcmFtZXRlcnM+IiwgUm9sZSwgY2FsbGJhY2tfZnVuYyk7DQogICAgfQ0KDQogICAgLy8gQ2FuY2VsIGFsbCBwZW5kaW5nIHF1ZXJpZXMgd2l0aCBnaXZlbiBzdGF0dXMNCiAgICBvYmouQ2FuY2VsQWxsUXVlcmllcyA9IGZ1bmN0aW9uIChzKSB7DQogICAgICAgIG9iai53c21hbi5DYW5jZWxBbGxRdWVyaWVzKHMpOw0KICAgIH0NCg0KICAgIC8vIEF1dG8gZ2VuZXJhdGVkIG1ldGhvZHMNCiAgICBvYmouQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ19SZWdpc3RlckFnZW50ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2ciLCAiUmVnaXN0ZXJBZ2VudCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nX0Fzc2VydFByZXNlbmNlID0gZnVuY3Rpb24gKFNlcXVlbmNlTnVtYmVyLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nIiwgIkFzc2VydFByZXNlbmNlIiwgeyAiU2VxdWVuY2VOdW1iZXIiOiBTZXF1ZW5jZU51bWJlciB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nX0Fzc2VydFNodXRkb3duID0gZnVuY3Rpb24gKFNlcXVlbmNlTnVtYmVyLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nIiwgIkFzc2VydFNodXRkb3duIiwgeyAiU2VxdWVuY2VOdW1iZXIiOiBTZXF1ZW5jZU51bWJlciB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nX0FkZEFjdGlvbiA9IGZ1bmN0aW9uIChPbGRTdGF0ZSwgTmV3U3RhdGUsIEV2ZW50T25UcmFuc2l0aW9uLCBBY3Rpb25TZCwgQWN0aW9uRWFjLCBjYWxsYmFja19mdW5jLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nIiwgIkFkZEFjdGlvbiIsIHsgIk9sZFN0YXRlIjogT2xkU3RhdGUsICJOZXdTdGF0ZSI6IE5ld1N0YXRlLCAiRXZlbnRPblRyYW5zaXRpb24iOiBFdmVudE9uVHJhbnNpdGlvbiwgIkFjdGlvblNkIjogQWN0aW9uU2QsICJBY3Rpb25FYWMiOiBBY3Rpb25FYWMgfSwgY2FsbGJhY2tfZnVuYywgdGFnLCBwcmksIHNlbGVjdG9ycyk7IH0NCiAgICBvYmouQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ19EZWxldGVBbGxBY3Rpb25zID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMsIHRhZywgcHJpLCBzZWxlY3RvcnMpIHsgb2JqLkV4ZWMoIkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2ciLCAiRGVsZXRlQWxsQWN0aW9ucyIsIHt9LCBjYWxsYmFja19mdW5jLCB0YWcsIHByaSwgc2VsZWN0b3JzKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nQWN0aW9uX0dldEFjdGlvbkVhYyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nQWN0aW9uIiwgIkdldEFjdGlvbkVhYyIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nVkFfUmVnaXN0ZXJBZ2VudCA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nVkEiLCAiUmVnaXN0ZXJBZ2VudCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nVkFfQXNzZXJ0UHJlc2VuY2UgPSBmdW5jdGlvbiAoU2VxdWVuY2VOdW1iZXIsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2dWQSIsICJBc3NlcnRQcmVzZW5jZSIsIHsgIlNlcXVlbmNlTnVtYmVyIjogU2VxdWVuY2VOdW1iZXIgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ1ZBX0Fzc2VydFNodXRkb3duID0gZnVuY3Rpb24gKFNlcXVlbmNlTnVtYmVyLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nVkEiLCAiQXNzZXJ0U2h1dGRvd24iLCB7ICJTZXF1ZW5jZU51bWJlciI6IFNlcXVlbmNlTnVtYmVyIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2dWQV9BZGRBY3Rpb24gPSBmdW5jdGlvbiAoT2xkU3RhdGUsIE5ld1N0YXRlLCBFdmVudE9uVHJhbnNpdGlvbiwgQWN0aW9uU2QsIEFjdGlvbkVhYywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ1ZBIiwgIkFkZEFjdGlvbiIsIHsgIk9sZFN0YXRlIjogT2xkU3RhdGUsICJOZXdTdGF0ZSI6IE5ld1N0YXRlLCAiRXZlbnRPblRyYW5zaXRpb24iOiBFdmVudE9uVHJhbnNpdGlvbiwgIkFjdGlvblNkIjogQWN0aW9uU2QsICJBY3Rpb25FYWMiOiBBY3Rpb25FYWMgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ1ZBX0RlbGV0ZUFsbEFjdGlvbnMgPSBmdW5jdGlvbiAoX21ldGhvZF9kdW1teSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ1ZBIiwgIkRlbGV0ZUFsbEFjdGlvbnMiLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQXVkaXRMb2dfQ2xlYXJMb2cgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0F1ZGl0TG9nIiwgIkNsZWFyTG9nIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdWRpdExvZ19SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdExvZyIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0F1ZGl0TG9nX1JlYWRSZWNvcmRzID0gZnVuY3Rpb24gKFN0YXJ0SW5kZXgsIGNhbGxiYWNrX2Z1bmMsIHRhZykgeyBvYmouRXhlYygiQU1UX0F1ZGl0TG9nIiwgIlJlYWRSZWNvcmRzIiwgeyAiU3RhcnRJbmRleCI6IFN0YXJ0SW5kZXggfSwgY2FsbGJhY2tfZnVuYywgdGFnKTsgfQ0KICAgIG9iai5BTVRfQXVkaXRMb2dfU2V0QXVkaXRMb2NrID0gZnVuY3Rpb24gKExvY2tUaW1lb3V0SW5TZWNvbmRzLCBGbGFnLCBIYW5kbGUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdExvZyIsICJTZXRBdWRpdExvY2siLCB7ICJMb2NrVGltZW91dEluU2Vjb25kcyI6IExvY2tUaW1lb3V0SW5TZWNvbmRzLCAiRmxhZyI6IEZsYWcsICJIYW5kbGUiOiBIYW5kbGUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0F1ZGl0TG9nX0V4cG9ydEF1ZGl0TG9nU2lnbmF0dXJlID0gZnVuY3Rpb24gKFNpZ25pbmdNZWNoYW5pc20sIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdExvZyIsICJFeHBvcnRBdWRpdExvZ1NpZ25hdHVyZSIsIHsgIlNpZ25pbmdNZWNoYW5pc20iOiBTaWduaW5nTWVjaGFuaXNtIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdWRpdExvZ19TZXRTaWduaW5nS2V5TWF0ZXJpYWwgPSBmdW5jdGlvbiAoU2lnbmluZ01lY2hhbmlzbVR5cGUsIFNpZ25pbmdLZXksIExlbmd0aE9mQ2VydGlmaWNhdGVzLCBDZXJ0aWZpY2F0ZXMsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdExvZyIsICJTZXRTaWduaW5nS2V5TWF0ZXJpYWwiLCB7ICJTaWduaW5nTWVjaGFuaXNtVHlwZSI6IFNpZ25pbmdNZWNoYW5pc21UeXBlLCAiU2lnbmluZ0tleSI6IFNpZ25pbmdLZXksICJMZW5ndGhPZkNlcnRpZmljYXRlcyI6IExlbmd0aE9mQ2VydGlmaWNhdGVzLCAiQ2VydGlmaWNhdGVzIjogQ2VydGlmaWNhdGVzIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdWRpdFBvbGljeVJ1bGVfU2V0QXVkaXRQb2xpY3kgPSBmdW5jdGlvbiAoRW5hYmxlLCBBdWRpdGVkQXBwSUQsIEV2ZW50SUQsIFBvbGljeVR5cGUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdFBvbGljeVJ1bGUiLCAiU2V0QXVkaXRQb2xpY3kiLCB7ICJFbmFibGUiOiBFbmFibGUsICJBdWRpdGVkQXBwSUQiOiBBdWRpdGVkQXBwSUQsICJFdmVudElEIjogRXZlbnRJRCwgIlBvbGljeVR5cGUiOiBQb2xpY3lUeXBlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdWRpdFBvbGljeVJ1bGVfU2V0QXVkaXRQb2xpY3lCdWxrID0gZnVuY3Rpb24gKEVuYWJsZSwgQXVkaXRlZEFwcElELCBFdmVudElELCBQb2xpY3lUeXBlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQXVkaXRQb2xpY3lSdWxlIiwgIlNldEF1ZGl0UG9saWN5QnVsayIsIHsgIkVuYWJsZSI6IEVuYWJsZSwgIkF1ZGl0ZWRBcHBJRCI6IEF1ZGl0ZWRBcHBJRCwgIkV2ZW50SUQiOiBFdmVudElELCAiUG9saWN5VHlwZSI6IFBvbGljeVR5cGUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX0FkZFVzZXJBY2xFbnRyeUV4ID0gZnVuY3Rpb24gKERpZ2VzdFVzZXJuYW1lLCBEaWdlc3RQYXNzd29yZCwgS2VyYmVyb3NVc2VyU2lkLCBBY2Nlc3NQZXJtaXNzaW9uLCBSZWFsbXMsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJBZGRVc2VyQWNsRW50cnlFeCIsIHsgIkRpZ2VzdFVzZXJuYW1lIjogRGlnZXN0VXNlcm5hbWUsICJEaWdlc3RQYXNzd29yZCI6IERpZ2VzdFBhc3N3b3JkLCAiS2VyYmVyb3NVc2VyU2lkIjogS2VyYmVyb3NVc2VyU2lkLCAiQWNjZXNzUGVybWlzc2lvbiI6IEFjY2Vzc1Blcm1pc3Npb24sICJSZWFsbXMiOiBSZWFsbXMgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX0VudW1lcmF0ZVVzZXJBY2xFbnRyaWVzID0gZnVuY3Rpb24gKFN0YXJ0SW5kZXgsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJFbnVtZXJhdGVVc2VyQWNsRW50cmllcyIsIHsgIlN0YXJ0SW5kZXgiOiBTdGFydEluZGV4IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRVc2VyQWNsRW50cnlFeCA9IGZ1bmN0aW9uIChIYW5kbGUsIGNhbGxiYWNrX2Z1bmMsIHRhZykgeyBvYmouRXhlYygiQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlIiwgIkdldFVzZXJBY2xFbnRyeUV4IiwgeyAiSGFuZGxlIjogSGFuZGxlIH0sIGNhbGxiYWNrX2Z1bmMsIHRhZyk7IH0NCiAgICBvYmouQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX1VwZGF0ZVVzZXJBY2xFbnRyeUV4ID0gZnVuY3Rpb24gKEhhbmRsZSwgRGlnZXN0VXNlcm5hbWUsIERpZ2VzdFBhc3N3b3JkLCBLZXJiZXJvc1VzZXJTaWQsIEFjY2Vzc1Blcm1pc3Npb24sIFJlYWxtcywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlIiwgIlVwZGF0ZVVzZXJBY2xFbnRyeUV4IiwgeyAiSGFuZGxlIjogSGFuZGxlLCAiRGlnZXN0VXNlcm5hbWUiOiBEaWdlc3RVc2VybmFtZSwgIkRpZ2VzdFBhc3N3b3JkIjogRGlnZXN0UGFzc3dvcmQsICJLZXJiZXJvc1VzZXJTaWQiOiBLZXJiZXJvc1VzZXJTaWQsICJBY2Nlc3NQZXJtaXNzaW9uIjogQWNjZXNzUGVybWlzc2lvbiwgIlJlYWxtcyI6IFJlYWxtcyB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfUmVtb3ZlVXNlckFjbEVudHJ5ID0gZnVuY3Rpb24gKEhhbmRsZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlIiwgIlJlbW92ZVVzZXJBY2xFbnRyeSIsIHsgIkhhbmRsZSI6IEhhbmRsZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfU2V0QWRtaW5BY2xFbnRyeUV4ID0gZnVuY3Rpb24gKFVzZXJuYW1lLCBEaWdlc3RQYXNzd29yZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlIiwgIlNldEFkbWluQWNsRW50cnlFeCIsIHsgIlVzZXJuYW1lIjogVXNlcm5hbWUsICJEaWdlc3RQYXNzd29yZCI6IERpZ2VzdFBhc3N3b3JkIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRBZG1pbkFjbEVudHJ5ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJHZXRBZG1pbkFjbEVudHJ5Iiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRBZG1pbkFjbEVudHJ5U3RhdHVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJHZXRBZG1pbkFjbEVudHJ5U3RhdHVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRBZG1pbk5ldEFjbEVudHJ5U3RhdHVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJHZXRBZG1pbk5ldEFjbEVudHJ5U3RhdHVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9TZXRBY2xFbmFibGVkU3RhdGUgPSBmdW5jdGlvbiAoSGFuZGxlLCBFbmFibGVkLCBjYWxsYmFja19mdW5jLCB0YWcpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJTZXRBY2xFbmFibGVkU3RhdGUiLCB7ICJIYW5kbGUiOiBIYW5kbGUsICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jLCB0YWcpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRBY2xFbmFibGVkU3RhdGUgPSBmdW5jdGlvbiAoSGFuZGxlLCBjYWxsYmFja19mdW5jLCB0YWcpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJHZXRBY2xFbmFibGVkU3RhdGUiLCB7ICJIYW5kbGUiOiBIYW5kbGUgfSwgY2FsbGJhY2tfZnVuYywgdGFnKTsgfQ0KICAgIG9iai5BTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZV9SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9FbmRwb2ludEFjY2Vzc0NvbnRyb2xTZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZV9HZXRQb3N0dXJlID0gZnVuY3Rpb24gKFBvc3R1cmVUeXBlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZSIsICJHZXRQb3N0dXJlIiwgeyAiUG9zdHVyZVR5cGUiOiBQb3N0dXJlVHlwZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZV9HZXRQb3N0dXJlSGFzaCA9IGZ1bmN0aW9uIChQb3N0dXJlVHlwZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0VuZHBvaW50QWNjZXNzQ29udHJvbFNlcnZpY2UiLCAiR2V0UG9zdHVyZUhhc2giLCB7ICJQb3N0dXJlVHlwZSI6IFBvc3R1cmVUeXBlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9FbmRwb2ludEFjY2Vzc0NvbnRyb2xTZXJ2aWNlX1VwZGF0ZVBvc3R1cmVTdGF0ZSA9IGZ1bmN0aW9uIChVcGRhdGVUeXBlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZSIsICJVcGRhdGVQb3N0dXJlU3RhdGUiLCB7ICJVcGRhdGVUeXBlIjogVXBkYXRlVHlwZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZV9HZXRFYWNPcHRpb25zID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9FbmRwb2ludEFjY2Vzc0NvbnRyb2xTZXJ2aWNlIiwgIkdldEVhY09wdGlvbnMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0VuZHBvaW50QWNjZXNzQ29udHJvbFNlcnZpY2VfU2V0RWFjT3B0aW9ucyA9IGZ1bmN0aW9uIChFYWNWZW5kb3JzLCBQb3N0dXJlSGFzaEFsZ29yaXRobSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0VuZHBvaW50QWNjZXNzQ29udHJvbFNlcnZpY2UiLCAiU2V0RWFjT3B0aW9ucyIsIHsgIkVhY1ZlbmRvcnMiOiBFYWNWZW5kb3JzLCAiUG9zdHVyZUhhc2hBbGdvcml0aG0iOiBQb3N0dXJlSGFzaEFsZ29yaXRobSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW52aXJvbm1lbnREZXRlY3Rpb25TZXR0aW5nRGF0YV9TZXRTeXN0ZW1EZWZlbnNlUG9saWN5ID0gZnVuY3Rpb24gKFBvbGljeSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0Vudmlyb25tZW50RGV0ZWN0aW9uU2V0dGluZ0RhdGEiLCAiU2V0U3lzdGVtRGVmZW5zZVBvbGljeSIsIHsgIlBvbGljeSI6IFBvbGljeSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW52aXJvbm1lbnREZXRlY3Rpb25TZXR0aW5nRGF0YV9FbmFibGVWcG5Sb3V0aW5nID0gZnVuY3Rpb24gKEVuYWJsZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0Vudmlyb25tZW50RGV0ZWN0aW9uU2V0dGluZ0RhdGEiLCAiRW5hYmxlVnBuUm91dGluZyIsIHsgIkVuYWJsZSI6IEVuYWJsZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRXRoZXJuZXRQb3J0U2V0dGluZ3NfU2V0TGlua1ByZWZlcmVuY2UgPSBmdW5jdGlvbiAoTGlua1ByZWZlcmVuY2UsIFRpbWVvdXQsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyIsICJTZXRMaW5rUHJlZmVyZW5jZSIsIHsgIkxpbmtQcmVmZXJlbmNlIjogTGlua1ByZWZlcmVuY2UsICJUaW1lb3V0IjogVGltZW91dCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfSGV1cmlzdGljUGFja2V0RmlsdGVyU3RhdGlzdGljc19SZXNldFNlbGVjdGVkU3RhdHMgPSBmdW5jdGlvbiAoU2VsZWN0ZWRTdGF0aXN0aWNzLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfSGV1cmlzdGljUGFja2V0RmlsdGVyU3RhdGlzdGljcyIsICJSZXNldFNlbGVjdGVkU3RhdHMiLCB7ICJTZWxlY3RlZFN0YXRpc3RpY3MiOiBTZWxlY3RlZFN0YXRpc3RpY3MgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0tlcmJlcm9zU2V0dGluZ0RhdGFfR2V0Q3JlZGVudGlhbENhY2hlU3RhdGUgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0tlcmJlcm9zU2V0dGluZ0RhdGEiLCAiR2V0Q3JlZGVudGlhbENhY2hlU3RhdGUiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0tlcmJlcm9zU2V0dGluZ0RhdGFfU2V0Q3JlZGVudGlhbENhY2hlU3RhdGUgPSBmdW5jdGlvbiAoRW5hYmxlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfS2VyYmVyb3NTZXR0aW5nRGF0YSIsICJTZXRDcmVkZW50aWFsQ2FjaGVTdGF0ZSIsIHsgIkVuYWJsZSI6IEVuYWJsZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfTWVzc2FnZUxvZ19DYW5jZWxJdGVyYXRpb24gPSBmdW5jdGlvbiAoSXRlcmF0aW9uSWRlbnRpZmllciwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX01lc3NhZ2VMb2ciLCAiQ2FuY2VsSXRlcmF0aW9uIiwgeyAiSXRlcmF0aW9uSWRlbnRpZmllciI6IEl0ZXJhdGlvbklkZW50aWZpZXIgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX01lc3NhZ2VMb2dfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfTWVzc2FnZUxvZyIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX01lc3NhZ2VMb2dfQ2xlYXJMb2cgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX01lc3NhZ2VMb2ciLCAiQ2xlYXJMb2ciLCB7IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9NZXNzYWdlTG9nX0dldFJlY29yZHMgPSBmdW5jdGlvbiAoSXRlcmF0aW9uSWRlbnRpZmllciwgTWF4UmVhZFJlY29yZHMsIGNhbGxiYWNrX2Z1bmMsIHRhZykgeyBvYmouRXhlYygiQU1UX01lc3NhZ2VMb2ciLCAiR2V0UmVjb3JkcyIsIHsgIkl0ZXJhdGlvbklkZW50aWZpZXIiOiBJdGVyYXRpb25JZGVudGlmaWVyLCAiTWF4UmVhZFJlY29yZHMiOiBNYXhSZWFkUmVjb3JkcyB9LCBjYWxsYmFja19mdW5jLCB0YWcpOyB9DQogICAgb2JqLkFNVF9NZXNzYWdlTG9nX0dldFJlY29yZCA9IGZ1bmN0aW9uIChJdGVyYXRpb25JZGVudGlmaWVyLCBQb3NpdGlvblRvTmV4dCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX01lc3NhZ2VMb2ciLCAiR2V0UmVjb3JkIiwgeyAiSXRlcmF0aW9uSWRlbnRpZmllciI6IEl0ZXJhdGlvbklkZW50aWZpZXIsICJQb3NpdGlvblRvTmV4dCI6IFBvc2l0aW9uVG9OZXh0IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9NZXNzYWdlTG9nX1Bvc2l0aW9uQXRSZWNvcmQgPSBmdW5jdGlvbiAoSXRlcmF0aW9uSWRlbnRpZmllciwgTW92ZUFic29sdXRlLCBSZWNvcmROdW1iZXIsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9NZXNzYWdlTG9nIiwgIlBvc2l0aW9uQXRSZWNvcmQiLCB7ICJJdGVyYXRpb25JZGVudGlmaWVyIjogSXRlcmF0aW9uSWRlbnRpZmllciwgIk1vdmVBYnNvbHV0ZSI6IE1vdmVBYnNvbHV0ZSwgIlJlY29yZE51bWJlciI6IFJlY29yZE51bWJlciB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfTWVzc2FnZUxvZ19Qb3NpdGlvblRvRmlyc3RSZWNvcmQgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYywgdGFnKSB7IG9iai5FeGVjKCJBTVRfTWVzc2FnZUxvZyIsICJQb3NpdGlvblRvRmlyc3RSZWNvcmQiLCB7fSwgY2FsbGJhY2tfZnVuYywgdGFnKTsgfQ0KICAgIG9iai5BTVRfTWVzc2FnZUxvZ19GcmVlemVMb2cgPSBmdW5jdGlvbiAoRnJlZXplLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfTWVzc2FnZUxvZyIsICJGcmVlemVMb2ciLCB7ICJGcmVlemUiOiBGcmVlemUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1B1YmxpY0tleU1hbmFnZW1lbnRTZXJ2aWNlX0FkZENSTCA9IGZ1bmN0aW9uIChVcmwsIFNlcmlhbE51bWJlcnMsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJBZGRDUkwiLCB7ICJVcmwiOiBVcmwsICJTZXJpYWxOdW1iZXJzIjogU2VyaWFsTnVtYmVycyB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfUmVzZXRDUkxMaXN0ID0gZnVuY3Rpb24gKF9tZXRob2RfZHVtbXksIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJSZXNldENSTExpc3QiLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfQWRkQ2VydGlmaWNhdGUgPSBmdW5jdGlvbiAoQ2VydGlmaWNhdGVCbG9iLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2UiLCAiQWRkQ2VydGlmaWNhdGUiLCB7ICJDZXJ0aWZpY2F0ZUJsb2IiOiBDZXJ0aWZpY2F0ZUJsb2IgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1B1YmxpY0tleU1hbmFnZW1lbnRTZXJ2aWNlX0FkZFRydXN0ZWRSb290Q2VydGlmaWNhdGUgPSBmdW5jdGlvbiAoQ2VydGlmaWNhdGVCbG9iLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2UiLCAiQWRkVHJ1c3RlZFJvb3RDZXJ0aWZpY2F0ZSIsIHsgIkNlcnRpZmljYXRlQmxvYiI6IENlcnRpZmljYXRlQmxvYiB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfQWRkS2V5ID0gZnVuY3Rpb24gKEtleUJsb2IsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJBZGRLZXkiLCB7ICJLZXlCbG9iIjogS2V5QmxvYiB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfR2VuZXJhdGVQS0NTMTBSZXF1ZXN0ID0gZnVuY3Rpb24gKEtleVBhaXIsIEROTmFtZSwgVXNhZ2UsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJHZW5lcmF0ZVBLQ1MxMFJlcXVlc3QiLCB7ICJLZXlQYWlyIjogS2V5UGFpciwgIkROTmFtZSI6IEROTmFtZSwgIlVzYWdlIjogVXNhZ2UgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1B1YmxpY0tleU1hbmFnZW1lbnRTZXJ2aWNlX0dlbmVyYXRlUEtDUzEwUmVxdWVzdEV4ID0gZnVuY3Rpb24gKEtleVBhaXIsIFNpZ25pbmdBbGdvcml0aG0sIE51bGxTaWduZWRDZXJ0aWZpY2F0ZVJlcXVlc3QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJHZW5lcmF0ZVBLQ1MxMFJlcXVlc3RFeCIsIHsgIktleVBhaXIiOiBLZXlQYWlyLCAiU2lnbmluZ0FsZ29yaXRobSI6IFNpZ25pbmdBbGdvcml0aG0sICJOdWxsU2lnbmVkQ2VydGlmaWNhdGVSZXF1ZXN0IjogTnVsbFNpZ25lZENlcnRpZmljYXRlUmVxdWVzdCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfR2VuZXJhdGVLZXlQYWlyID0gZnVuY3Rpb24gKEtleUFsZ29yaXRobSwgS2V5TGVuZ3RoLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2UiLCAiR2VuZXJhdGVLZXlQYWlyIiwgeyAiS2V5QWxnb3JpdGhtIjogS2V5QWxnb3JpdGhtLCAiS2V5TGVuZ3RoIjogS2V5TGVuZ3RoIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9SZWRpcmVjdGlvblNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1JlZGlyZWN0aW9uU2VydmljZV9UZXJtaW5hdGVTZXNzaW9uID0gZnVuY3Rpb24gKFNlc3Npb25UeXBlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlIiwgIlRlcm1pbmF0ZVNlc3Npb24iLCB7ICJTZXNzaW9uVHlwZSI6IFNlc3Npb25UeXBlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9SZW1vdGVBY2Nlc3NTZXJ2aWNlX0FkZE1wU2VydmVyID0gZnVuY3Rpb24gKEFjY2Vzc0luZm8sIEluZm9Gb3JtYXQsIFBvcnQsIEF1dGhNZXRob2QsIENlcnRpZmljYXRlLCBVc2VybmFtZSwgUGFzc3dvcmQsIENOLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVtb3RlQWNjZXNzU2VydmljZSIsICJBZGRNcFNlcnZlciIsIHsgIkFjY2Vzc0luZm8iOiBBY2Nlc3NJbmZvLCAiSW5mb0Zvcm1hdCI6IEluZm9Gb3JtYXQsICJQb3J0IjogUG9ydCwgIkF1dGhNZXRob2QiOiBBdXRoTWV0aG9kLCAiQ2VydGlmaWNhdGUiOiBDZXJ0aWZpY2F0ZSwgIlVzZXJuYW1lIjogVXNlcm5hbWUsICJQYXNzd29yZCI6IFBhc3N3b3JkLCAiQ04iOiBDTiB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUmVtb3RlQWNjZXNzU2VydmljZV9BZGRSZW1vdGVBY2Nlc3NQb2xpY3lSdWxlID0gZnVuY3Rpb24gKFRyaWdnZXIsIFR1bm5lbExpZmVUaW1lLCBFeHRlbmRlZERhdGEsIE1wU2VydmVyLCBJbnRlcm5hbE1wU2VydmVyLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVtb3RlQWNjZXNzU2VydmljZSIsICJBZGRSZW1vdGVBY2Nlc3NQb2xpY3lSdWxlIiwgeyAiVHJpZ2dlciI6IFRyaWdnZXIsICJUdW5uZWxMaWZlVGltZSI6IFR1bm5lbExpZmVUaW1lLCAiRXh0ZW5kZWREYXRhIjogRXh0ZW5kZWREYXRhLCAiTXBTZXJ2ZXIiOiBNcFNlcnZlciwgIkludGVybmFsTXBTZXJ2ZXIiOiBJbnRlcm5hbE1wU2VydmVyIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9SZW1vdGVBY2Nlc3NTZXJ2aWNlX0Nsb3NlUmVtb3RlQWNjZXNzQ29ubmVjdGlvbiA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVtb3RlQWNjZXNzU2VydmljZSIsICJDbG9zZVJlbW90ZUFjY2Vzc0Nvbm5lY3Rpb24iLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9Db21taXRDaGFuZ2VzID0gZnVuY3Rpb24gKF9tZXRob2RfZHVtbXksIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgIkNvbW1pdENoYW5nZXMiLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9VbnByb3Zpc2lvbiA9IGZ1bmN0aW9uIChQcm92aXNpb25pbmdNb2RlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJVbnByb3Zpc2lvbiIsIHsgIlByb3Zpc2lvbmluZ01vZGUiOiBQcm92aXNpb25pbmdNb2RlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlX1BhcnRpYWxVbnByb3Zpc2lvbiA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJQYXJ0aWFsVW5wcm92aXNpb24iLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9SZXNldEZsYXNoV2Vhck91dFByb3RlY3Rpb24gPSBmdW5jdGlvbiAoX21ldGhvZF9kdW1teSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2UiLCAiUmVzZXRGbGFzaFdlYXJPdXRQcm90ZWN0aW9uIiwgeyAiX21ldGhvZF9kdW1teSI6IF9tZXRob2RfZHVtbXkgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2VfRXh0ZW5kUHJvdmlzaW9uaW5nUGVyaW9kID0gZnVuY3Rpb24gKER1cmF0aW9uLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJFeHRlbmRQcm92aXNpb25pbmdQZXJpb2QiLCB7ICJEdXJhdGlvbiI6IER1cmF0aW9uIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlX1NldE1FQnhQYXNzd29yZCA9IGZ1bmN0aW9uIChQYXNzd29yZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2UiLCAiU2V0TUVCeFBhc3N3b3JkIiwgeyAiUGFzc3dvcmQiOiBQYXNzd29yZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9TZXRUTFNQU0sgPSBmdW5jdGlvbiAoUElELCBQUFMsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgIlNldFRMU1BTSyIsIHsgIlBJRCI6IFBJRCwgIlBQUyI6IFBQUyB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9HZXRQcm92aXNpb25pbmdBdWRpdFJlY29yZCA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJHZXRQcm92aXNpb25pbmdBdWRpdFJlY29yZCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9HZXRVdWlkID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgIkdldFV1aWQiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2VfR2V0VW5wcm92aXNpb25CbG9ja2luZ0NvbXBvbmVudHMgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2UiLCAiR2V0VW5wcm92aXNpb25CbG9ja2luZ0NvbXBvbmVudHMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2VfR2V0UHJvdmlzaW9uaW5nQXVkaXRSZWNvcmRWMiA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJHZXRQcm92aXNpb25pbmdBdWRpdFJlY29yZFYyIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9TeXN0ZW1EZWZlbnNlUG9saWN5X0dldFRpbWVvdXQgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1N5c3RlbURlZmVuc2VQb2xpY3kiLCAiR2V0VGltZW91dCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU3lzdGVtRGVmZW5zZVBvbGljeV9TZXRUaW1lb3V0ID0gZnVuY3Rpb24gKFRpbWVvdXQsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9TeXN0ZW1EZWZlbnNlUG9saWN5IiwgIlNldFRpbWVvdXQiLCB7ICJUaW1lb3V0IjogVGltZW91dCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU3lzdGVtRGVmZW5zZVBvbGljeV9VcGRhdGVTdGF0aXN0aWNzID0gZnVuY3Rpb24gKE5ldHdvcmtJbnRlcmZhY2UsIFJlc2V0T25SZWFkLCBjYWxsYmFja19mdW5jLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai5FeGVjKCJBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSIsICJVcGRhdGVTdGF0aXN0aWNzIiwgeyAiTmV0d29ya0ludGVyZmFjZSI6IE5ldHdvcmtJbnRlcmZhY2UsICJSZXNldE9uUmVhZCI6IFJlc2V0T25SZWFkIH0sIGNhbGxiYWNrX2Z1bmMsIHRhZywgcHJpLCBzZWxlY3RvcnMpOyB9DQogICAgb2JqLkFNVF9TeXN0ZW1Qb3dlclNjaGVtZV9TZXRQb3dlclNjaGVtZSA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jLCBzY2hlbWVJbnN0YW5jZUlkLCB0YWcpIHsgb2JqLkV4ZWMoIkFNVF9TeXN0ZW1Qb3dlclNjaGVtZSIsICJTZXRQb3dlclNjaGVtZSIsIHt9LCBjYWxsYmFja19mdW5jLCB0YWcsIDAsIHsgIkluc3RhbmNlSUQiOiBzY2hlbWVJbnN0YW5jZUlkIH0pOyB9DQogICAgb2JqLkFNVF9UaW1lU3luY2hyb25pemF0aW9uU2VydmljZV9HZXRMb3dBY2N1cmFjeVRpbWVTeW5jaCA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jLCB0YWcpIHsgb2JqLkV4ZWMoIkFNVF9UaW1lU3luY2hyb25pemF0aW9uU2VydmljZSIsICJHZXRMb3dBY2N1cmFjeVRpbWVTeW5jaCIsIHt9LCBjYWxsYmFja19mdW5jLCB0YWcpOyB9DQogICAgb2JqLkFNVF9UaW1lU3luY2hyb25pemF0aW9uU2VydmljZV9TZXRIaWdoQWNjdXJhY3lUaW1lU3luY2ggPSBmdW5jdGlvbiAoVGEwLCBUbTEsIFRtMiwgY2FsbGJhY2tfZnVuYywgdGFnKSB7IG9iai5FeGVjKCJBTVRfVGltZVN5bmNocm9uaXphdGlvblNlcnZpY2UiLCAiU2V0SGlnaEFjY3VyYWN5VGltZVN5bmNoIiwgeyAiVGEwIjogVGEwLCAiVG0xIjogVG0xLCAiVG0yIjogVG0yIH0sIGNhbGxiYWNrX2Z1bmMsIHRhZyk7IH0NCiAgICBvYmouQU1UX1VzZXJJbml0aWF0ZWRDb25uZWN0aW9uU2VydmljZV9SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9Vc2VySW5pdGlhdGVkQ29ubmVjdGlvblNlcnZpY2UiLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZSwgIlRpbWVvdXRQZXJpb2QiOiBUaW1lb3V0UGVyaW9kIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9XZWJVSVNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfV2ViVUlTZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZV9BZGRXaUZpU2V0dGluZ3MgPSBmdW5jdGlvbiAoV2lGaUVuZHBvaW50LCBXaUZpRW5kcG9pbnRTZXR0aW5nc0lucHV0LCBJRUVFODAyMXhTZXR0aW5nc0lucHV0LCBDbGllbnRDcmVkZW50aWFsLCBDQUNyZWRlbnRpYWwsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWNXaXRoWG1sKCJBTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZSIsICJBZGRXaUZpU2V0dGluZ3MiLCB7ICJXaUZpRW5kcG9pbnQiOiBXaUZpRW5kcG9pbnQsICJXaUZpRW5kcG9pbnRTZXR0aW5nc0lucHV0IjogV2lGaUVuZHBvaW50U2V0dGluZ3NJbnB1dCwgIklFRUU4MDIxeFNldHRpbmdzSW5wdXQiOiBJRUVFODAyMXhTZXR0aW5nc0lucHV0LCAiQ2xpZW50Q3JlZGVudGlhbCI6IENsaWVudENyZWRlbnRpYWwsICJDQUNyZWRlbnRpYWwiOiBDQUNyZWRlbnRpYWwgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1dpRmlQb3J0Q29uZmlndXJhdGlvblNlcnZpY2VfVXBkYXRlV2lGaVNldHRpbmdzID0gZnVuY3Rpb24gKFdpRmlFbmRwb2ludFNldHRpbmdzLCBXaUZpRW5kcG9pbnRTZXR0aW5nc0lucHV0LCBJRUVFODAyMXhTZXR0aW5nc0lucHV0LCBDbGllbnRDcmVkZW50aWFsLCBDQUNyZWRlbnRpYWwsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWNXaXRoWG1sKCJBTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZSIsICJVcGRhdGVXaUZpU2V0dGluZ3MiLCB7ICJXaUZpRW5kcG9pbnRTZXR0aW5ncyI6IFdpRmlFbmRwb2ludFNldHRpbmdzLCAiV2lGaUVuZHBvaW50U2V0dGluZ3NJbnB1dCI6IFdpRmlFbmRwb2ludFNldHRpbmdzSW5wdXQsICJJRUVFODAyMXhTZXR0aW5nc0lucHV0IjogSUVFRTgwMjF4U2V0dGluZ3NJbnB1dCwgIkNsaWVudENyZWRlbnRpYWwiOiBDbGllbnRDcmVkZW50aWFsLCAiQ0FDcmVkZW50aWFsIjogQ0FDcmVkZW50aWFsIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9XaUZpUG9ydENvbmZpZ3VyYXRpb25TZXJ2aWNlX0RlbGV0ZUFsbElUUHJvZmlsZXMgPSBmdW5jdGlvbiAoX21ldGhvZF9kdW1teSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1dpRmlQb3J0Q29uZmlndXJhdGlvblNlcnZpY2UiLCAiRGVsZXRlQWxsSVRQcm9maWxlcyIsIHsgIl9tZXRob2RfZHVtbXkiOiBfbWV0aG9kX2R1bW15IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9XaUZpUG9ydENvbmZpZ3VyYXRpb25TZXJ2aWNlX0RlbGV0ZUFsbFVzZXJQcm9maWxlcyA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZSIsICJEZWxldGVBbGxVc2VyUHJvZmlsZXMiLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fQWNjb3VudF9SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9BY2NvdW50IiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fQWNjb3VudE1hbmFnZW1lbnRTZXJ2aWNlX0NyZWF0ZUFjY291bnQgPSBmdW5jdGlvbiAoU3lzdGVtLCBBY2NvdW50VGVtcGxhdGUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9BY2NvdW50TWFuYWdlbWVudFNlcnZpY2UiLCAiQ3JlYXRlQWNjb3VudCIsIHsgIlN5c3RlbSI6IFN5c3RlbSwgIkFjY291bnRUZW1wbGF0ZSI6IEFjY291bnRUZW1wbGF0ZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fQm9vdENvbmZpZ1NldHRpbmdfQ2hhbmdlQm9vdE9yZGVyID0gZnVuY3Rpb24gKFNvdXJjZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX0Jvb3RDb25maWdTZXR0aW5nIiwgIkNoYW5nZUJvb3RPcmRlciIsIHsgIlNvdXJjZSI6IFNvdXJjZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fQm9vdFNlcnZpY2VfU2V0Qm9vdENvbmZpZ1JvbGUgPSBmdW5jdGlvbiAoQm9vdENvbmZpZ1NldHRpbmcsIFJvbGUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Cb290U2VydmljZSIsICJTZXRCb290Q29uZmlnUm9sZSIsIHsgIkJvb3RDb25maWdTZXR0aW5nIjogQm9vdENvbmZpZ1NldHRpbmcsICJSb2xlIjogUm9sZSB9LCBjYWxsYmFja19mdW5jLCAwLCAxKTsgfQ0KICAgIG9iai5DSU1fQ2FyZF9Db25uZWN0b3JQb3dlciA9IGZ1bmN0aW9uIChDb25uZWN0b3IsIFBvd2VyZWRPbiwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX0NhcmQiLCAiQ29ubmVjdG9yUG93ZXIiLCB7ICJDb25uZWN0b3IiOiBDb25uZWN0b3IsICJQb3dlcmVkT24iOiBQb3dlcmVkT24gfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX0NhcmRfSXNDb21wYXRpYmxlID0gZnVuY3Rpb24gKEVsZW1lbnRUb0NoZWNrLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fQ2FyZCIsICJJc0NvbXBhdGlibGUiLCB7ICJFbGVtZW50VG9DaGVjayI6IEVsZW1lbnRUb0NoZWNrIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9DaGFzc2lzX0lzQ29tcGF0aWJsZSA9IGZ1bmN0aW9uIChFbGVtZW50VG9DaGVjaywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX0NoYXNzaXMiLCAiSXNDb21wYXRpYmxlIiwgeyAiRWxlbWVudFRvQ2hlY2siOiBFbGVtZW50VG9DaGVjayB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fRmFuX1NldFNwZWVkID0gZnVuY3Rpb24gKERlc2lyZWRTcGVlZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX0ZhbiIsICJTZXRTcGVlZCIsIHsgIkRlc2lyZWRTcGVlZCI6IERlc2lyZWRTcGVlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fS1ZNUmVkaXJlY3Rpb25TQVBfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fS1ZNUmVkaXJlY3Rpb25TQVAiLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZS8qLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgKi99LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfTG9ja01lZGlhID0gZnVuY3Rpb24gKExvY2ssIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJMb2NrTWVkaWEiLCB7ICJMb2NrIjogTG9jayB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfU2V0UG93ZXJTdGF0ZSA9IGZ1bmN0aW9uIChQb3dlclN0YXRlLCBUaW1lLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fTWVkaWFBY2Nlc3NEZXZpY2UiLCAiU2V0UG93ZXJTdGF0ZSIsIHsgIlBvd2VyU3RhdGUiOiBQb3dlclN0YXRlLCAiVGltZSI6IFRpbWUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX01lZGlhQWNjZXNzRGV2aWNlX1Jlc2V0ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJSZXNldCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfRW5hYmxlRGV2aWNlID0gZnVuY3Rpb24gKEVuYWJsZWQsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJFbmFibGVEZXZpY2UiLCB7ICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfT25saW5lRGV2aWNlID0gZnVuY3Rpb24gKE9ubGluZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX01lZGlhQWNjZXNzRGV2aWNlIiwgIk9ubGluZURldmljZSIsIHsgIk9ubGluZSI6IE9ubGluZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfUXVpZXNjZURldmljZSA9IGZ1bmN0aW9uIChRdWllc2NlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fTWVkaWFBY2Nlc3NEZXZpY2UiLCAiUXVpZXNjZURldmljZSIsIHsgIlF1aWVzY2UiOiBRdWllc2NlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9NZWRpYUFjY2Vzc0RldmljZV9TYXZlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fTWVkaWFBY2Nlc3NEZXZpY2UiLCAiU2F2ZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX01lZGlhQWNjZXNzRGV2aWNlX1Jlc3RvcmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJSZXN0b3JlUHJvcGVydGllcyIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fTWVkaWFBY2Nlc3NEZXZpY2UiLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZSwgIlRpbWVvdXRQZXJpb2QiOiBUaW1lb3V0UGVyaW9kIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9QaHlzaWNhbEZyYW1lX0lzQ29tcGF0aWJsZSA9IGZ1bmN0aW9uIChFbGVtZW50VG9DaGVjaywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1BoeXNpY2FsRnJhbWUiLCAiSXNDb21wYXRpYmxlIiwgeyAiRWxlbWVudFRvQ2hlY2siOiBFbGVtZW50VG9DaGVjayB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUGh5c2ljYWxQYWNrYWdlX0lzQ29tcGF0aWJsZSA9IGZ1bmN0aW9uIChFbGVtZW50VG9DaGVjaywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1BoeXNpY2FsUGFja2FnZSIsICJJc0NvbXBhdGlibGUiLCB7ICJFbGVtZW50VG9DaGVjayI6IEVsZW1lbnRUb0NoZWNrIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qb3dlck1hbmFnZW1lbnRTZXJ2aWNlX1JlcXVlc3RQb3dlclN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFBvd2VyU3RhdGUsIE1hbmFnZWRFbGVtZW50LCBUaW1lLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUG93ZXJNYW5hZ2VtZW50U2VydmljZSIsICJSZXF1ZXN0UG93ZXJTdGF0ZUNoYW5nZSIsIHsgIlBvd2VyU3RhdGUiOiBQb3dlclN0YXRlLCAiTWFuYWdlZEVsZW1lbnQiOiBNYW5hZ2VkRWxlbWVudCwgIlRpbWUiOiBUaW1lLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYywgMCwgMSk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X1NldFBvd2VyU3RhdGUgPSBmdW5jdGlvbiAoUG93ZXJTdGF0ZSwgVGltZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Bvd2VyU3VwcGx5IiwgIlNldFBvd2VyU3RhdGUiLCB7ICJQb3dlclN0YXRlIjogUG93ZXJTdGF0ZSwgIlRpbWUiOiBUaW1lIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qb3dlclN1cHBseV9SZXNldCA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUG93ZXJTdXBwbHkiLCAiUmVzZXQiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X0VuYWJsZURldmljZSA9IGZ1bmN0aW9uIChFbmFibGVkLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUG93ZXJTdXBwbHkiLCAiRW5hYmxlRGV2aWNlIiwgeyAiRW5hYmxlZCI6IEVuYWJsZWQgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X09ubGluZURldmljZSA9IGZ1bmN0aW9uIChPbmxpbmUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Qb3dlclN1cHBseSIsICJPbmxpbmVEZXZpY2UiLCB7ICJPbmxpbmUiOiBPbmxpbmUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X1F1aWVzY2VEZXZpY2UgPSBmdW5jdGlvbiAoUXVpZXNjZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Bvd2VyU3VwcGx5IiwgIlF1aWVzY2VEZXZpY2UiLCB7ICJRdWllc2NlIjogUXVpZXNjZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUG93ZXJTdXBwbHlfU2F2ZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Bvd2VyU3VwcGx5IiwgIlNhdmVQcm9wZXJ0aWVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qb3dlclN1cHBseV9SZXN0b3JlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUG93ZXJTdXBwbHkiLCAiUmVzdG9yZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X1JlcXVlc3RTdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uIChSZXF1ZXN0ZWRTdGF0ZSwgVGltZW91dFBlcmlvZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Bvd2VyU3VwcGx5IiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUHJvY2Vzc29yX1NldFBvd2VyU3RhdGUgPSBmdW5jdGlvbiAoUG93ZXJTdGF0ZSwgVGltZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Byb2Nlc3NvciIsICJTZXRQb3dlclN0YXRlIiwgeyAiUG93ZXJTdGF0ZSI6IFBvd2VyU3RhdGUsICJUaW1lIjogVGltZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUHJvY2Vzc29yX1Jlc2V0ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Qcm9jZXNzb3IiLCAiUmVzZXQiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Byb2Nlc3Nvcl9FbmFibGVEZXZpY2UgPSBmdW5jdGlvbiAoRW5hYmxlZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Byb2Nlc3NvciIsICJFbmFibGVEZXZpY2UiLCB7ICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUHJvY2Vzc29yX09ubGluZURldmljZSA9IGZ1bmN0aW9uIChPbmxpbmUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Qcm9jZXNzb3IiLCAiT25saW5lRGV2aWNlIiwgeyAiT25saW5lIjogT25saW5lIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qcm9jZXNzb3JfUXVpZXNjZURldmljZSA9IGZ1bmN0aW9uIChRdWllc2NlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUHJvY2Vzc29yIiwgIlF1aWVzY2VEZXZpY2UiLCB7ICJRdWllc2NlIjogUXVpZXNjZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUHJvY2Vzc29yX1NhdmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Qcm9jZXNzb3IiLCAiU2F2ZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Byb2Nlc3Nvcl9SZXN0b3JlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUHJvY2Vzc29yIiwgIlJlc3RvcmVQcm9wZXJ0aWVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qcm9jZXNzb3JfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUHJvY2Vzc29yIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUmVjb3JkTG9nX0NsZWFyTG9nID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9SZWNvcmRMb2ciLCAiQ2xlYXJMb2ciLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1JlY29yZExvZ19SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9SZWNvcmRMb2ciLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZSwgIlRpbWVvdXRQZXJpb2QiOiBUaW1lb3V0UGVyaW9kIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9SZWRpcmVjdGlvblNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUmVkaXJlY3Rpb25TZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU2Vuc29yX1NldFBvd2VyU3RhdGUgPSBmdW5jdGlvbiAoUG93ZXJTdGF0ZSwgVGltZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1NlbnNvciIsICJTZXRQb3dlclN0YXRlIiwgeyAiUG93ZXJTdGF0ZSI6IFBvd2VyU3RhdGUsICJUaW1lIjogVGltZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU2Vuc29yX1Jlc2V0ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9TZW5zb3IiLCAiUmVzZXQiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1NlbnNvcl9FbmFibGVEZXZpY2UgPSBmdW5jdGlvbiAoRW5hYmxlZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1NlbnNvciIsICJFbmFibGVEZXZpY2UiLCB7ICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU2Vuc29yX09ubGluZURldmljZSA9IGZ1bmN0aW9uIChPbmxpbmUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9TZW5zb3IiLCAiT25saW5lRGV2aWNlIiwgeyAiT25saW5lIjogT25saW5lIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9TZW5zb3JfUXVpZXNjZURldmljZSA9IGZ1bmN0aW9uIChRdWllc2NlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fU2Vuc29yIiwgIlF1aWVzY2VEZXZpY2UiLCB7ICJRdWllc2NlIjogUXVpZXNjZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU2Vuc29yX1NhdmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9TZW5zb3IiLCAiU2F2ZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1NlbnNvcl9SZXN0b3JlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fU2Vuc29yIiwgIlJlc3RvcmVQcm9wZXJ0aWVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9TZW5zb3JfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fU2Vuc29yIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU3RhdGlzdGljYWxEYXRhX1Jlc2V0U2VsZWN0ZWRTdGF0cyA9IGZ1bmN0aW9uIChTZWxlY3RlZFN0YXRpc3RpY3MsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9TdGF0aXN0aWNhbERhdGEiLCAiUmVzZXRTZWxlY3RlZFN0YXRzIiwgeyAiU2VsZWN0ZWRTdGF0aXN0aWNzIjogU2VsZWN0ZWRTdGF0aXN0aWNzIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XYXRjaGRvZ19LZWVwQWxpdmUgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dhdGNoZG9nIiwgIktlZXBBbGl2ZSIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfU2V0UG93ZXJTdGF0ZSA9IGZ1bmN0aW9uIChQb3dlclN0YXRlLCBUaW1lLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2F0Y2hkb2ciLCAiU2V0UG93ZXJTdGF0ZSIsIHsgIlBvd2VyU3RhdGUiOiBQb3dlclN0YXRlLCAiVGltZSI6IFRpbWUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1dhdGNoZG9nX1Jlc2V0ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XYXRjaGRvZyIsICJSZXNldCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfRW5hYmxlRGV2aWNlID0gZnVuY3Rpb24gKEVuYWJsZWQsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XYXRjaGRvZyIsICJFbmFibGVEZXZpY2UiLCB7ICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfT25saW5lRGV2aWNlID0gZnVuY3Rpb24gKE9ubGluZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dhdGNoZG9nIiwgIk9ubGluZURldmljZSIsIHsgIk9ubGluZSI6IE9ubGluZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfUXVpZXNjZURldmljZSA9IGZ1bmN0aW9uIChRdWllc2NlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2F0Y2hkb2ciLCAiUXVpZXNjZURldmljZSIsIHsgIlF1aWVzY2UiOiBRdWllc2NlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XYXRjaGRvZ19TYXZlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2F0Y2hkb2ciLCAiU2F2ZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1dhdGNoZG9nX1Jlc3RvcmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XYXRjaGRvZyIsICJSZXN0b3JlUHJvcGVydGllcyIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2F0Y2hkb2ciLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZSwgIlRpbWVvdXRQZXJpb2QiOiBUaW1lb3V0UGVyaW9kIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9TZXRQb3dlclN0YXRlID0gZnVuY3Rpb24gKFBvd2VyU3RhdGUsIFRpbWUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XaUZpUG9ydCIsICJTZXRQb3dlclN0YXRlIiwgeyAiUG93ZXJTdGF0ZSI6IFBvd2VyU3RhdGUsICJUaW1lIjogVGltZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2lGaVBvcnRfUmVzZXQgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dpRmlQb3J0IiwgIlJlc2V0Iiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9FbmFibGVEZXZpY2UgPSBmdW5jdGlvbiAoRW5hYmxlZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dpRmlQb3J0IiwgIkVuYWJsZURldmljZSIsIHsgIkVuYWJsZWQiOiBFbmFibGVkIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9PbmxpbmVEZXZpY2UgPSBmdW5jdGlvbiAoT25saW5lLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2lGaVBvcnQiLCAiT25saW5lRGV2aWNlIiwgeyAiT25saW5lIjogT25saW5lIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9RdWllc2NlRGV2aWNlID0gZnVuY3Rpb24gKFF1aWVzY2UsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XaUZpUG9ydCIsICJRdWllc2NlRGV2aWNlIiwgeyAiUXVpZXNjZSI6IFF1aWVzY2UgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1dpRmlQb3J0X1NhdmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XaUZpUG9ydCIsICJTYXZlUHJvcGVydGllcyIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2lGaVBvcnRfUmVzdG9yZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dpRmlQb3J0IiwgIlJlc3RvcmVQcm9wZXJ0aWVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XaUZpUG9ydCIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX0hvc3RCYXNlZFNldHVwU2VydmljZV9TZXR1cCA9IGZ1bmN0aW9uIChOZXRBZG1pblBhc3NFbmNyeXB0aW9uVHlwZSwgTmV0d29ya0FkbWluUGFzc3dvcmQsIE1jTm9uY2UsIENlcnRpZmljYXRlLCBTaWduaW5nQWxnb3JpdGhtLCBEaWdpdGFsU2lnbmF0dXJlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlIiwgIlNldHVwIiwgeyAiTmV0QWRtaW5QYXNzRW5jcnlwdGlvblR5cGUiOiBOZXRBZG1pblBhc3NFbmNyeXB0aW9uVHlwZSwgIk5ldHdvcmtBZG1pblBhc3N3b3JkIjogTmV0d29ya0FkbWluUGFzc3dvcmQsICJNY05vbmNlIjogTWNOb25jZSwgIkNlcnRpZmljYXRlIjogQ2VydGlmaWNhdGUsICJTaWduaW5nQWxnb3JpdGhtIjogU2lnbmluZ0FsZ29yaXRobSwgIkRpZ2l0YWxTaWduYXR1cmUiOiBEaWdpdGFsU2lnbmF0dXJlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2VfQWRkTmV4dENlcnRJbkNoYWluID0gZnVuY3Rpb24gKE5leHRDZXJ0aWZpY2F0ZSwgSXNMZWFmQ2VydGlmaWNhdGUsIElzUm9vdENlcnRpZmljYXRlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlIiwgIkFkZE5leHRDZXJ0SW5DaGFpbiIsIHsgIk5leHRDZXJ0aWZpY2F0ZSI6IE5leHRDZXJ0aWZpY2F0ZSwgIklzTGVhZkNlcnRpZmljYXRlIjogSXNMZWFmQ2VydGlmaWNhdGUsICJJc1Jvb3RDZXJ0aWZpY2F0ZSI6IElzUm9vdENlcnRpZmljYXRlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2VfQWRtaW5TZXR1cCA9IGZ1bmN0aW9uIChOZXRBZG1pblBhc3NFbmNyeXB0aW9uVHlwZSwgTmV0d29ya0FkbWluUGFzc3dvcmQsIE1jTm9uY2UsIFNpZ25pbmdBbGdvcml0aG0sIERpZ2l0YWxTaWduYXR1cmUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2UiLCAiQWRtaW5TZXR1cCIsIHsgIk5ldEFkbWluUGFzc0VuY3J5cHRpb25UeXBlIjogTmV0QWRtaW5QYXNzRW5jcnlwdGlvblR5cGUsICJOZXR3b3JrQWRtaW5QYXNzd29yZCI6IE5ldHdvcmtBZG1pblBhc3N3b3JkLCAiTWNOb25jZSI6IE1jTm9uY2UsICJTaWduaW5nQWxnb3JpdGhtIjogU2lnbmluZ0FsZ29yaXRobSwgIkRpZ2l0YWxTaWduYXR1cmUiOiBEaWdpdGFsU2lnbmF0dXJlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2VfVXBncmFkZUNsaWVudFRvQWRtaW4gPSBmdW5jdGlvbiAoTWNOb25jZSwgU2lnbmluZ0FsZ29yaXRobSwgRGlnaXRhbFNpZ25hdHVyZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX0hvc3RCYXNlZFNldHVwU2VydmljZSIsICJVcGdyYWRlQ2xpZW50VG9BZG1pbiIsIHsgIk1jTm9uY2UiOiBNY05vbmNlLCAiU2lnbmluZ0FsZ29yaXRobSI6IFNpZ25pbmdBbGdvcml0aG0sICJEaWdpdGFsU2lnbmF0dXJlIjogRGlnaXRhbFNpZ25hdHVyZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlX0Rpc2FibGVDbGllbnRDb250cm9sTW9kZSA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlIiwgIkRpc2FibGVDbGllbnRDb250cm9sTW9kZSIsIHsgIl9tZXRob2RfZHVtbXkiOiBfbWV0aG9kX2R1bW15IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhX1Rlcm1pbmF0ZVNlc3Npb24gPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEiLCAiVGVybWluYXRlU2Vzc2lvbiIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfS1ZNUmVkaXJlY3Rpb25TZXR0aW5nRGF0YV9EYXRhQ2hhbm5lbFJlYWQgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEiLCAiRGF0YUNoYW5uZWxSZWFkIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhX0RhdGFDaGFubmVsV3JpdGUgPSBmdW5jdGlvbiAoRGF0YSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEiLCAiRGF0YUNoYW5uZWxXcml0ZSIsIHsgIkRhdGFNZXNzYWdlIjogRGF0YSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfT3B0SW5TZXJ2aWNlX1N0YXJ0T3B0SW4gPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX09wdEluU2VydmljZSIsICJTdGFydE9wdEluIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19PcHRJblNlcnZpY2VfQ2FuY2VsT3B0SW4gPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX09wdEluU2VydmljZSIsICJDYW5jZWxPcHRJbiIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfT3B0SW5TZXJ2aWNlX1NlbmRPcHRJbkNvZGUgPSBmdW5jdGlvbiAoT3B0SW5Db2RlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfT3B0SW5TZXJ2aWNlIiwgIlNlbmRPcHRJbkNvZGUiLCB7ICJPcHRJbkNvZGUiOiBPcHRJbkNvZGUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX09wdEluU2VydmljZV9TdGFydFNlcnZpY2UgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX09wdEluU2VydmljZSIsICJTdGFydFNlcnZpY2UiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX09wdEluU2VydmljZV9TdG9wU2VydmljZSA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfT3B0SW5TZXJ2aWNlIiwgIlN0b3BTZXJ2aWNlIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19PcHRJblNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfT3B0SW5TZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfUHJvdmlzaW9uaW5nUmVjb3JkTG9nX1JlcXVlc3RTdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uIChSZXF1ZXN0ZWRTdGF0ZSwgVGltZW91dFBlcmlvZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX1Byb3Zpc2lvbmluZ1JlY29yZExvZyIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX1Byb3Zpc2lvbmluZ1JlY29yZExvZ19DbGVhckxvZyA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfUHJvdmlzaW9uaW5nUmVjb3JkTG9nIiwgIkNsZWFyTG9nIiwgeyAiX21ldGhvZF9kdW1teSI6IF9tZXRob2RfZHVtbXkgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX1NjcmVlbkNvbmZpZ3VyYXRpb25TZXJ2aWNlX1NldFNlc3Npb25TdGF0ZSA9IGZ1bmN0aW9uIChTZXNzaW9uU3RhdGUsIENvbnNlY3V0aXZlUmVib290c051bSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX1NjcmVlbkNvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgIlNldFNlc3Npb25TdGF0ZSIsIHsgIlNlc3Npb25TdGF0ZSI6IFNlc3Npb25TdGF0ZSwgIkNvbnNlY3V0aXZlUmVib290c051bSI6IENvbnNlY3V0aXZlUmVib290c051bSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfU2VjSU9TZXJ2aWNlX1JlcXVlc3RTdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uIChSZXF1ZXN0ZWRTdGF0ZSwgVGltZW91dFBlcmlvZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX1NlY0lPU2VydmljZSIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX0hUVFBQcm94eVNlcnZpY2VfQWRkUHJveHlBY2Nlc3NQb2ludCA9IGZ1bmN0aW9uIChBY2Nlc3NJbmZvLCBJbmZvRm9ybWF0LCBQb3J0LCBOZXR3b3JrRG5zU3VmZml4LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfSFRUUFByb3h5U2VydmljZSIsICJBZGRQcm94eUFjY2Vzc1BvaW50IiwgeyAiQWNjZXNzSW5mbyI6IEFjY2Vzc0luZm8sICJJbmZvRm9ybWF0IjogSW5mb0Zvcm1hdCwgIlBvcnQiOiBQb3J0LCAiTmV0d29ya0Ruc1N1ZmZpeCI6IE5ldHdvcmtEbnNTdWZmaXggfSwgY2FsbGJhY2tfZnVuYyk7IH0NCg0KICAgIG9iai5BbXRTdGF0dXNUb1N0ciA9IGZ1bmN0aW9uIChjb2RlKSB7IGlmIChvYmouQW10U3RhdHVzQ29kZXNbY29kZV0pIHJldHVybiBvYmouQW10U3RhdHVzQ29kZXNbY29kZV07IGVsc2UgcmV0dXJuICJVTktOT1dOX0VSUk9SIiB9DQogICAgb2JqLkFtdFN0YXR1c0NvZGVzID0gew0KICAgICAgICAweDAwMDA6ICJTVUNDRVNTIiwNCiAgICAgICAgMHgwMDAxOiAiSU5URVJOQUxfRVJST1IiLA0KICAgICAgICAweDAwMDI6ICJOT1RfUkVBRFkiLA0KICAgICAgICAweDAwMDM6ICJJTlZBTElEX1BUX01PREUiLA0KICAgICAgICAweDAwMDQ6ICJJTlZBTElEX01FU1NBR0VfTEVOR1RIIiwNCiAgICAgICAgMHgwMDA1OiAiVEFCTEVfRklOR0VSUFJJTlRfTk9UX0FWQUlMQUJMRSIsDQogICAgICAgIDB4MDAwNjogIklOVEVHUklUWV9DSEVDS19GQUlMRUQiLA0KICAgICAgICAweDAwMDc6ICJVTlNVUFBPUlRFRF9JU1ZTX1ZFUlNJT04iLA0KICAgICAgICAweDAwMDg6ICJBUFBMSUNBVElPTl9OT1RfUkVHSVNURVJFRCIsDQogICAgICAgIDB4MDAwOTogIklOVkFMSURfUkVHSVNUUkFUSU9OX0RBVEEiLA0KICAgICAgICAweDAwMEE6ICJBUFBMSUNBVElPTl9ET0VTX05PVF9FWElTVCIsDQogICAgICAgIDB4MDAwQjogIk5PVF9FTk9VR0hfU1RPUkFHRSIsDQogICAgICAgIDB4MDAwQzogIklOVkFMSURfTkFNRSIsDQogICAgICAgIDB4MDAwRDogIkJMT0NLX0RPRVNfTk9UX0VYSVNUIiwNCiAgICAgICAgMHgwMDBFOiAiSU5WQUxJRF9CWVRFX09GRlNFVCIsDQogICAgICAgIDB4MDAwRjogIklOVkFMSURfQllURV9DT1VOVCIsDQogICAgICAgIDB4MDAxMDogIk5PVF9QRVJNSVRURUQiLA0KICAgICAgICAweDAwMTE6ICJOT1RfT1dORVIiLA0KICAgICAgICAweDAwMTI6ICJCTE9DS19MT0NLRURfQllfT1RIRVIiLA0KICAgICAgICAweDAwMTM6ICJCTE9DS19OT1RfTE9DS0VEIiwNCiAgICAgICAgMHgwMDE0OiAiSU5WQUxJRF9HUk9VUF9QRVJNSVNTSU9OUyIsDQogICAgICAgIDB4MDAxNTogIkdST1VQX0RPRVNfTk9UX0VYSVNUIiwNCiAgICAgICAgMHgwMDE2OiAiSU5WQUxJRF9NRU1CRVJfQ09VTlQiLA0KICAgICAgICAweDAwMTc6ICJNQVhfTElNSVRfUkVBQ0hFRCIsDQogICAgICAgIDB4MDAxODogIklOVkFMSURfQVVUSF9UWVBFIiwNCiAgICAgICAgMHgwMDE5OiAiQVVUSEVOVElDQVRJT05fRkFJTEVEIiwNCiAgICAgICAgMHgwMDFBOiAiSU5WQUxJRF9ESENQX01PREUiLA0KICAgICAgICAweDAwMUI6ICJJTlZBTElEX0lQX0FERFJFU1MiLA0KICAgICAgICAweDAwMUM6ICJJTlZBTElEX0RPTUFJTl9OQU1FIiwNCiAgICAgICAgMHgwMDFEOiAiVU5TVVBQT1JURURfVkVSU0lPTiIsDQogICAgICAgIDB4MDAxRTogIlJFUVVFU1RfVU5FWFBFQ1RFRCIsDQogICAgICAgIDB4MDAxRjogIklOVkFMSURfVEFCTEVfVFlQRSIsDQogICAgICAgIDB4MDAyMDogIklOVkFMSURfUFJPVklTSU9OSU5HX1NUQVRFIiwNCiAgICAgICAgMHgwMDIxOiAiVU5TVVBQT1JURURfT0JKRUNUIiwNCiAgICAgICAgMHgwMDIyOiAiSU5WQUxJRF9USU1FIiwNCiAgICAgICAgMHgwMDIzOiAiSU5WQUxJRF9JTkRFWCIsDQogICAgICAgIDB4MDAyNDogIklOVkFMSURfUEFSQU1FVEVSIiwNCiAgICAgICAgMHgwMDI1OiAiSU5WQUxJRF9ORVRNQVNLIiwNCiAgICAgICAgMHgwMDI2OiAiRkxBU0hfV1JJVEVfTElNSVRfRVhDRUVERUQiLA0KICAgICAgICAweDAwMjc6ICJJTlZBTElEX0lNQUdFX0xFTkdUSCIsDQogICAgICAgIDB4MDAyODogIklOVkFMSURfSU1BR0VfU0lHTkFUVVJFIiwNCiAgICAgICAgMHgwMDI5OiAiUFJPUE9TRV9BTk9USEVSX1ZFUlNJT04iLA0KICAgICAgICAweDAwMkE6ICJJTlZBTElEX1BJRF9GT1JNQVQiLA0KICAgICAgICAweDAwMkI6ICJJTlZBTElEX1BQU19GT1JNQVQiLA0KICAgICAgICAweDAwMkM6ICJCSVNUX0NPTU1BTkRfQkxPQ0tFRCIsDQogICAgICAgIDB4MDAyRDogIkNPTk5FQ1RJT05fRkFJTEVEIiwNCiAgICAgICAgMHgwMDJFOiAiQ09OTkVDVElPTl9UT09fTUFOWSIsDQogICAgICAgIDB4MDAyRjogIlJOR19HRU5FUkFUSU9OX0lOX1BST0dSRVNTIiwNCiAgICAgICAgMHgwMDMwOiAiUk5HX05PVF9SRUFEWSIsDQogICAgICAgIDB4MDAzMTogIkNFUlRJRklDQVRFX05PVF9SRUFEWSIsDQogICAgICAgIDB4MDQwMDogIkRJU0FCTEVEX0JZX1BPTElDWSIsDQogICAgICAgIDB4MDgwMDogIk5FVFdPUktfSUZfRVJST1JfQkFTRSIsDQogICAgICAgIDB4MDgwMTogIlVOU1VQUE9SVEVEX09FTV9OVU1CRVIiLA0KICAgICAgICAweDA4MDI6ICJVTlNVUFBPUlRFRF9CT09UX09QVElPTiIsDQogICAgICAgIDB4MDgwMzogIklOVkFMSURfQ09NTUFORCIsDQogICAgICAgIDB4MDgwNDogIklOVkFMSURfU1BFQ0lBTF9DT01NQU5EIiwNCiAgICAgICAgMHgwODA1OiAiSU5WQUxJRF9IQU5ETEUiLA0KICAgICAgICAweDA4MDY6ICJJTlZBTElEX1BBU1NXT1JEIiwNCiAgICAgICAgMHgwODA3OiAiSU5WQUxJRF9SRUFMTSIsDQogICAgICAgIDB4MDgwODogIlNUT1JBR0VfQUNMX0VOVFJZX0lOX1VTRSIsDQogICAgICAgIDB4MDgwOTogIkRBVEFfTUlTU0lORyIsDQogICAgICAgIDB4MDgwQTogIkRVUExJQ0FURSIsDQogICAgICAgIDB4MDgwQjogIkVWRU5UTE9HX0ZST1pFTiIsDQogICAgICAgIDB4MDgwQzogIlBLSV9NSVNTSU5HX0tFWVMiLA0KICAgICAgICAweDA4MEQ6ICJQS0lfR0VORVJBVElOR19LRVlTIiwNCiAgICAgICAgMHgwODBFOiAiSU5WQUxJRF9LRVkiLA0KICAgICAgICAweDA4MEY6ICJJTlZBTElEX0NFUlQiLA0KICAgICAgICAweDA4MTA6ICJDRVJUX0tFWV9OT1RfTUFUQ0giLA0KICAgICAgICAweDA4MTE6ICJNQVhfS0VSQl9ET01BSU5fUkVBQ0hFRCIsDQogICAgICAgIDB4MDgxMjogIlVOU1VQUE9SVEVEIiwNCiAgICAgICAgMHgwODEzOiAiSU5WQUxJRF9QUklPUklUWSIsDQogICAgICAgIDB4MDgxNDogIk5PVF9GT1VORCIsDQogICAgICAgIDB4MDgxNTogIklOVkFMSURfQ1JFREVOVElBTFMiLA0KICAgICAgICAweDA4MTY6ICJJTlZBTElEX1BBU1NQSFJBU0UiLA0KICAgICAgICAweDA4MTg6ICJOT19BU1NPQ0lBVElPTiIsDQogICAgICAgIDB4MDgxQjogIkFVRElUX0ZBSUwiLA0KICAgICAgICAweDA4MUM6ICJCTE9DS0lOR19DT01QT05FTlQiLA0KICAgICAgICAweDA4MjE6ICJVU0VSX0NPTlNFTlRfUkVRVUlSRUQiLA0KICAgICAgICAweDEwMDA6ICJBUFBfSU5URVJOQUxfRVJST1IiLA0KICAgICAgICAweDEwMDE6ICJOT1RfSU5JVElBTElaRUQiLA0KICAgICAgICAweDEwMDI6ICJMSUJfVkVSU0lPTl9VTlNVUFBPUlRFRCIsDQogICAgICAgIDB4MTAwMzogIklOVkFMSURfUEFSQU0iLA0KICAgICAgICAweDEwMDQ6ICJSRVNPVVJDRVMiLA0KICAgICAgICAweDEwMDU6ICJIQVJEV0FSRV9BQ0NFU1NfRVJST1IiLA0KICAgICAgICAweDEwMDY6ICJSRVFVRVNUT1JfTk9UX1JFR0lTVEVSRUQiLA0KICAgICAgICAweDEwMDc6ICJORVRXT1JLX0VSUk9SIiwNCiAgICAgICAgMHgxMDA4OiAiUEFSQU1fQlVGRkVSX1RPT19TSE9SVCIsDQogICAgICAgIDB4MTAwOTogIkNPTV9OT1RfSU5JVElBTElaRURfSU5fVEhSRUFEIiwNCiAgICAgICAgMHgxMDBBOiAiVVJMX1JFUVVJUkVEIg0KICAgIH0NCg0KICAgIC8vDQogICAgLy8gTWV0aG9kcyB1c2VkIGZvciBnZXR0aW5nIHRoZSBldmVudCBsb2cNCiAgICAvLw0KDQogICAgb2JqLkdldE1lc3NhZ2VMb2cgPSBmdW5jdGlvbiAoZnVuYywgdGFnKSB7DQogICAgICAgIG9iai5BTVRfTWVzc2FnZUxvZ19Qb3NpdGlvblRvRmlyc3RSZWNvcmQoX0dldE1lc3NhZ2VMb2cwLCBbZnVuYywgdGFnLCBbXV0pOw0KICAgIH0NCiAgICBmdW5jdGlvbiBfR2V0TWVzc2FnZUxvZzAoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzLCB0YWcpIHsNCiAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDAgfHwgcmVzcG9uc2VzLkJvZHlbIlJldHVyblZhbHVlIl0gIT0gJzAnKSB7IHRhZ1swXShvYmosIG51bGwsIHRhZ1syXSk7IHJldHVybjsgfQ0KICAgICAgICBvYmouQU1UX01lc3NhZ2VMb2dfR2V0UmVjb3JkcyhyZXNwb25zZXMuQm9keVsiSXRlcmF0aW9uSWRlbnRpZmllciJdLCAzOTAsIF9HZXRNZXNzYWdlTG9nMSwgdGFnKTsNCiAgICB9DQogICAgZnVuY3Rpb24gX0dldE1lc3NhZ2VMb2cxKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cywgdGFnKSB7DQogICAgICAgIGlmIChzdGF0dXMgIT0gMjAwIHx8IHJlc3BvbnNlcy5Cb2R5WyJSZXR1cm5WYWx1ZSJdICE9ICcwJykgeyB0YWdbMF0ob2JqLCBudWxsLCB0YWdbMl0pOyByZXR1cm47IH0NCiAgICAgICAgdmFyIGksIGosIHgsIGUsIEFtdE1lc3NhZ2VzID0gdGFnWzJdLCB0ID0gbmV3IERhdGUoKSwgVGltZVN0YW1wLCByYSA9IHJlc3BvbnNlcy5Cb2R5WyJSZWNvcmRBcnJheSJdOw0KICAgICAgICBpZiAodHlwZW9mIHJhID09PSAnc3RyaW5nJykgeyByZXNwb25zZXMuQm9keVsiUmVjb3JkQXJyYXkiXSA9IFtyZXNwb25zZXMuQm9keVsiUmVjb3JkQXJyYXkiXV07IH0NCg0KICAgICAgICBmb3IgKGkgaW4gcmEpIHsNCiAgICAgICAgICAgIGUgPSBudWxsOw0KICAgICAgICAgICAgdHJ5IHsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyBOb2RlSlMgZGV0ZWN0aW9uDQogICAgICAgICAgICAgICAgdmFyIGlzTm9kZSA9IG5ldyBGdW5jdGlvbigidHJ5IHtyZXR1cm4gdGhpcz09PWdsb2JhbDt9Y2F0Y2goZSl7cmV0dXJuIGZhbHNlO30iKTsNCiAgICAgICAgICAgICAgICBpZiAoaXNOb2RlKCkpIHsgZSA9IHJlcXVpcmUoJ2F0b2InKShyYVtpXSk7IH0gZWxzZSB7IGUgPSB3aW5kb3cuYXRvYihyYVtpXSk7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsgfQ0KICAgICAgICAgICAgaWYgKGUgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgIFRpbWVTdGFtcCA9IFJlYWRJbnRYKGUsIDApOw0KICAgICAgICAgICAgICAgIGlmICgoVGltZVN0YW1wID4gMCkgJiYgKFRpbWVTdGFtcCA8IDB4RkZGRkZGRkYpKSB7DQogICAgICAgICAgICAgICAgICAgIHggPSB7ICdEZXZpY2VBZGRyZXNzJzogZS5jaGFyQ29kZUF0KDQpLCAnRXZlbnRTZW5zb3JUeXBlJzogZS5jaGFyQ29kZUF0KDUpLCAnRXZlbnRUeXBlJzogZS5jaGFyQ29kZUF0KDYpLCAnRXZlbnRPZmZzZXQnOiBlLmNoYXJDb2RlQXQoNyksICdFdmVudFNvdXJjZVR5cGUnOiBlLmNoYXJDb2RlQXQoOCksICdFdmVudFNldmVyaXR5JzogZS5jaGFyQ29kZUF0KDkpLCAnU2Vuc29yTnVtYmVyJzogZS5jaGFyQ29kZUF0KDEwKSwgJ0VudGl0eSc6IGUuY2hhckNvZGVBdCgxMSksICdFbnRpdHlJbnN0YW5jZSc6IGUuY2hhckNvZGVBdCgxMiksICdFdmVudERhdGEnOiBbXSwgJ1RpbWUnOiBuZXcgRGF0ZSgoVGltZVN0YW1wICsgKHQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwKSkgKiAxMDAwKSB9Ow0KICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAxMzsgaiA8IDIxOyBqKyspIHsgeFsnRXZlbnREYXRhJ10ucHVzaChlLmNoYXJDb2RlQXQoaikpOyB9DQogICAgICAgICAgICAgICAgICAgIHhbJ0VudGl0eVN0ciddID0gX1N5c3RlbUVudGl0eVR5cGVzW3hbJ0VudGl0eSddXTsNCiAgICAgICAgICAgICAgICAgICAgeFsnRGVzYyddID0gX0dldEV2ZW50RGV0YWlsU3RyKHhbJ0V2ZW50U2Vuc29yVHlwZSddLCB4WydFdmVudE9mZnNldCddLCB4WydFdmVudERhdGEnXSwgeFsnRW50aXR5J10pOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIXhbJ0VudGl0eVN0ciddKSB4WydFbnRpdHlTdHInXSA9ICJVbmtub3duIjsNCiAgICAgICAgICAgICAgICAgICAgQW10TWVzc2FnZXMucHVzaCh4KTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBpZiAocmVzcG9uc2VzLkJvZHlbIk5vTW9yZVJlY29yZHMiXSAhPSB0cnVlKSB7IG9iai5BTVRfTWVzc2FnZUxvZ19HZXRSZWNvcmRzKHJlc3BvbnNlcy5Cb2R5WyJJdGVyYXRpb25JZGVudGlmaWVyIl0sIDM5MCwgX0dldE1lc3NhZ2VMb2cxLCBbdGFnWzBdLCBBbXRNZXNzYWdlcywgdGFnWzJdXSk7IH0gZWxzZSB7IHRhZ1swXShvYmosIEFtdE1lc3NhZ2VzLCB0YWdbMl0pOyB9DQogICAgfQ0KDQogICAgdmFyIF9FdmVudFRyYXBTb3VyY2VUeXBlcyA9ICJQbGF0Zm9ybSBmaXJtd2FyZSAoZS5nLiBCSU9TKXxTTUkgaGFuZGxlcnxJU1Ygc3lzdGVtIG1hbmFnZW1lbnQgc29mdHdhcmV8QWxlcnQgQVNJQ3xJUE1JfEJJT1MgdmVuZG9yfFN5c3RlbSBib2FyZCBzZXQgdmVuZG9yfFN5c3RlbSBpbnRlZ3JhdG9yfFRoaXJkIHBhcnR5IGFkZC1pbnxPU1Z8TklDfFN5c3RlbSBtYW5hZ2VtZW50IGNhcmQiLnNwbGl0KCd8Jyk7DQogICAgdmFyIF9TeXN0ZW1GaXJtd2FyZUVycm9yID0gIlVuc3BlY2lmaWVkLnxObyBzeXN0ZW0gbWVtb3J5IGlzIHBoeXNpY2FsbHkgaW5zdGFsbGVkIGluIHRoZSBzeXN0ZW0ufE5vIHVzYWJsZSBzeXN0ZW0gbWVtb3J5LCBhbGwgaW5zdGFsbGVkIG1lbW9yeSBoYXMgZXhwZXJpZW5jZWQgYW4gdW5yZWNvdmVyYWJsZSBmYWlsdXJlLnxVbnJlY292ZXJhYmxlIGhhcmQtZGlzay9BVEFQSS9JREUgZGV2aWNlIGZhaWx1cmUufFVucmVjb3ZlcmFibGUgc3lzdGVtLWJvYXJkIGZhaWx1cmUufFVucmVjb3ZlcmFibGUgZGlza2V0dGUgc3Vic3lzdGVtIGZhaWx1cmUufFVucmVjb3ZlcmFibGUgaGFyZC1kaXNrIGNvbnRyb2xsZXIgZmFpbHVyZS58VW5yZWNvdmVyYWJsZSBQUy8yIG9yIFVTQiBrZXlib2FyZCBmYWlsdXJlLnxSZW1vdmFibGUgYm9vdCBtZWRpYSBub3QgZm91bmQufFVucmVjb3ZlcmFibGUgdmlkZW8gY29udHJvbGxlciBmYWlsdXJlLnxObyB2aWRlbyBkZXZpY2UgZGV0ZWN0ZWQufEZpcm13YXJlIChCSU9TKSBST00gY29ycnVwdGlvbiBkZXRlY3RlZC58Q1BVIHZvbHRhZ2UgbWlzbWF0Y2ggKHByb2Nlc3NvcnMgdGhhdCBzaGFyZSBzYW1lIHN1cHBseSBoYXZlIG1pc21hdGNoZWQgdm9sdGFnZSByZXF1aXJlbWVudHMpfENQVSBzcGVlZCBtYXRjaGluZyBmYWlsdXJlIi5zcGxpdCgnfCcpOw0KICAgIHZhciBfU3lzdGVtRmlybXdhcmVQcm9ncmVzcyA9ICJVbnNwZWNpZmllZC58TWVtb3J5IGluaXRpYWxpemF0aW9uLnxTdGFydGluZyBoYXJkLWRpc2sgaW5pdGlhbGl6YXRpb24gYW5kIHRlc3R8U2Vjb25kYXJ5IHByb2Nlc3NvcihzKSBpbml0aWFsaXphdGlvbnxVc2VyIGF1dGhlbnRpY2F0aW9ufFVzZXItaW5pdGlhdGVkIHN5c3RlbSBzZXR1cHxVU0IgcmVzb3VyY2UgY29uZmlndXJhdGlvbnxQQ0kgcmVzb3VyY2UgY29uZmlndXJhdGlvbnxPcHRpb24gUk9NIGluaXRpYWxpemF0aW9ufFZpZGVvIGluaXRpYWxpemF0aW9ufENhY2hlIGluaXRpYWxpemF0aW9ufFNNIEJ1cyBpbml0aWFsaXphdGlvbnxLZXlib2FyZCBjb250cm9sbGVyIGluaXRpYWxpemF0aW9ufEVtYmVkZGVkIGNvbnRyb2xsZXIvbWFuYWdlbWVudCBjb250cm9sbGVyIGluaXRpYWxpemF0aW9ufERvY2tpbmcgc3RhdGlvbiBhdHRhY2htZW50fEVuYWJsaW5nIGRvY2tpbmcgc3RhdGlvbnxEb2NraW5nIHN0YXRpb24gZWplY3Rpb258RGlzYWJsaW5nIGRvY2tpbmcgc3RhdGlvbnxDYWxsaW5nIG9wZXJhdGluZyBzeXN0ZW0gd2FrZS11cCB2ZWN0b3J8U3RhcnRpbmcgb3BlcmF0aW5nIHN5c3RlbSBib290IHByb2Nlc3N8QmFzZWJvYXJkIG9yIG1vdGhlcmJvYXJkIGluaXRpYWxpemF0aW9ufHJlc2VydmVkfEZsb3BweSBpbml0aWFsaXphdGlvbnxLZXlib2FyZCB0ZXN0fFBvaW50aW5nIGRldmljZSB0ZXN0fFByaW1hcnkgcHJvY2Vzc29yIGluaXRpYWxpemF0aW9uIi5zcGxpdCgnfCcpOw0KICAgIHZhciBfU3lzdGVtRW50aXR5VHlwZXMgPSAiVW5zcGVjaWZpZWR8T3RoZXJ8VW5rbm93bnxQcm9jZXNzb3J8RGlza3xQZXJpcGhlcmFsfFN5c3RlbSBtYW5hZ2VtZW50IG1vZHVsZXxTeXN0ZW0gYm9hcmR8TWVtb3J5IG1vZHVsZXxQcm9jZXNzb3IgbW9kdWxlfFBvd2VyIHN1cHBseXxBZGQgaW4gY2FyZHxGcm9udCBwYW5lbCBib2FyZHxCYWNrIHBhbmVsIGJvYXJkfFBvd2VyIHN5c3RlbSBib2FyZHxEcml2ZSBiYWNrcGxhbmV8U3lzdGVtIGludGVybmFsIGV4cGFuc2lvbiBib2FyZHxPdGhlciBzeXN0ZW0gYm9hcmR8UHJvY2Vzc29yIGJvYXJkfFBvd2VyIHVuaXR8UG93ZXIgbW9kdWxlfFBvd2VyIG1hbmFnZW1lbnQgYm9hcmR8Q2hhc3NpcyBiYWNrIHBhbmVsIGJvYXJkfFN5c3RlbSBjaGFzc2lzfFN1YiBjaGFzc2lzfE90aGVyIGNoYXNzaXMgYm9hcmR8RGlzayBkcml2ZSBiYXl8UGVyaXBoZXJhbCBiYXl8RGV2aWNlIGJheXxGYW4gY29vbGluZ3xDb29saW5nIHVuaXR8Q2FibGUgaW50ZXJjb25uZWN0fE1lbW9yeSBkZXZpY2V8U3lzdGVtIG1hbmFnZW1lbnQgc29mdHdhcmV8QklPU3xJbnRlbChyKSBNRXxTeXN0ZW0gYnVzfEdyb3VwfEludGVsKHIpIE1FfEV4dGVybmFsIGVudmlyb25tZW50fEJhdHRlcnl8UHJvY2Vzc2luZyBibGFkZXxDb25uZWN0aXZpdHkgc3dpdGNofFByb2Nlc3Nvci9tZW1vcnkgbW9kdWxlfEkvTyBtb2R1bGV8UHJvY2Vzc29yIEkvTyBtb2R1bGV8TWFuYWdlbWVudCBjb250cm9sbGVyIGZpcm13YXJlfElQTUkgY2hhbm5lbHxQQ0kgYnVzfFBDSSBleHByZXNzIGJ1c3xTQ1NJIGJ1c3xTQVRBL1NBUyBidXN8UHJvY2Vzc29yIGZyb250IHNpZGUgYnVzIi5zcGxpdCgnfCcpOw0KICAgIG9iai5SZWFsbU5hbWVzID0gInx8UmVkaXJlY3Rpb258fEhhcmR3YXJlIEFzc2V0fFJlbW90ZSBDb250cm9sfFN0b3JhZ2V8RXZlbnQgTWFuYWdlcnxTdG9yYWdlIEFkbWlufEFnZW50IFByZXNlbmNlIExvY2FsfEFnZW50IFByZXNlbmNlIFJlbW90ZXxDaXJjdWl0IEJyZWFrZXJ8TmV0d29yayBUaW1lfEdlbmVyYWwgSW5mb3JtYXRpb258RmlybXdhcmUgVXBkYXRlfEVJVHxMb2NhbFVOfEVuZHBvaW50IEFjY2VzcyBDb250cm9sfEVuZHBvaW50IEFjY2VzcyBDb250cm9sIEFkbWlufEV2ZW50IExvZyBSZWFkZXJ8QXVkaXQgTG9nfEFDTCBSZWFsbXx8fExvY2FsIFN5c3RlbSIuc3BsaXQoJ3wnKTsNCiAgICBvYmouV2F0Y2hkb2dDdXJyZW50U3RhdGVzID0geyAxOiAnTm90IFN0YXJ0ZWQnLCAyOiAnU3RvcHBlZCcsIDQ6ICdSdW5uaW5nJywgODogJ0V4cGlyZWQnLCAxNjogJ1N1c3BlbmRlZCcgfTsNCg0KICAgIGZ1bmN0aW9uIF9HZXRFdmVudERldGFpbFN0cihldmVudFNlbnNvclR5cGUsIGV2ZW50T2Zmc2V0LCBldmVudERhdGFGaWVsZCwgZW50aXR5KSB7DQoNCiAgICAgICAgaWYgKGV2ZW50U2Vuc29yVHlwZSA9PSAxNSkgew0KICAgICAgICAgICAgaWYgKGV2ZW50RGF0YUZpZWxkWzBdID09IDIzNSkgcmV0dXJuICJJbnZhbGlkIERhdGEiOw0KICAgICAgICAgICAgaWYgKGV2ZW50T2Zmc2V0ID09IDApIHJldHVybiBfU3lzdGVtRmlybXdhcmVFcnJvcltldmVudERhdGFGaWVsZFsxXV07DQogICAgICAgICAgICByZXR1cm4gX1N5c3RlbUZpcm13YXJlUHJvZ3Jlc3NbZXZlbnREYXRhRmllbGRbMV1dOw0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKChldmVudFNlbnNvclR5cGUgPT0gMTgpICYmIChldmVudERhdGFGaWVsZFswXSA9PSAxNzApKSB7IC8vIFN5c3RlbSB3YXRjaGRvZyBldmVudA0KICAgICAgICAgICAgcmV0dXJuICJBZ2VudCB3YXRjaGRvZyAiICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbNF0pICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbM10pICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbMl0pICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbMV0pICsgIi0iICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbNl0pICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbNV0pICsgIi0uLi4gY2hhbmdlZCB0byAiICsgb2JqLldhdGNoZG9nQ3VycmVudFN0YXRlc1tldmVudERhdGFGaWVsZFs3XV07DQogICAgICAgIH0NCg0KICAgICAgICBpZiAoKGV2ZW50U2Vuc29yVHlwZSA9PSA1KSAmJiAoZXZlbnRPZmZzZXQgPT0gMCkpIHsgLy8gU3lzdGVtIGNoYXNzaXMNCiAgICAgICAgICAgIHJldHVybiAiQ2FzZSBpbnRydXNpb24iOw0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKChldmVudFNlbnNvclR5cGUgPT0gMTkyKSAmJiAoZXZlbnRPZmZzZXQgPT0gMCkgJiYgKGV2ZW50RGF0YUZpZWxkWzBdID09IDE3MCkgJiYgKGV2ZW50RGF0YUZpZWxkWzFdID09IDQ4KSkNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKGV2ZW50RGF0YUZpZWxkWzJdID09IDApIHJldHVybiAiQSByZW1vdGUgU2VyaWFsIE92ZXIgTEFOIHNlc3Npb24gd2FzIGVzdGFibGlzaGVkLiI7DQogICAgICAgICAgICBpZiAoZXZlbnREYXRhRmllbGRbMl0gPT0gMSkgcmV0dXJuICJSZW1vdGUgU2VyaWFsIE92ZXIgTEFOIHNlc3Npb24gZmluaXNoZWQuIFVzZXIgY29udHJvbCB3YXMgcmVzdG9yZWQuIjsNCiAgICAgICAgICAgIGlmIChldmVudERhdGFGaWVsZFsyXSA9PSAyKSByZXR1cm4gIkEgcmVtb3RlIElERS1SZWRpcmVjdGlvbiBzZXNzaW9uIHdhcyBlc3RhYmxpc2hlZC4iOw0KICAgICAgICAgICAgaWYgKGV2ZW50RGF0YUZpZWxkWzJdID09IDMpIHJldHVybiAiUmVtb3RlIElERS1SZWRpcmVjdGlvbiBzZXNzaW9uIGZpbmlzaGVkLiBVc2VyIGNvbnRyb2wgd2FzIHJlc3RvcmVkLiI7DQogICAgICAgIH0NCg0KICAgICAgICBpZiAoZXZlbnRTZW5zb3JUeXBlID09IDM2KSB7DQogICAgICAgICAgICB2YXIgaGFuZGxlID0gKGV2ZW50RGF0YUZpZWxkWzFdIDw8IDI0KSArIChldmVudERhdGFGaWVsZFsyXSA8PCAxNikgKyAoZXZlbnREYXRhRmllbGRbM10gPDwgOCkgKyBldmVudERhdGFGaWVsZFs0XTsNCiAgICAgICAgICAgIHZhciBuaWMgPSAiIyIgKyBldmVudERhdGFGaWVsZFswXTsNCiAgICAgICAgICAgIGlmIChldmVudERhdGFGaWVsZFswXSA9PSAweEFBKSBuaWMgPSAid2lyZWQiOyAvLyBUT0RPOiBBZGQgd2lyZWxlc3MgKioqKioNCiAgICAgICAgICAgIC8vaWYgKGV2ZW50RGF0YUZpZWxkWzBdID09IDB4QUEpIG5pYyA9ICJ3aXJlbGVzcyI7DQoNCiAgICAgICAgICAgIGlmIChoYW5kbGUgPT0gNDI5NDk2NzI5MykgeyByZXR1cm4gIkFsbCByZWNlaXZlZCBwYWNrZXQgZmlsdGVyIHdhcyBtYXRjaGVkIG9uICIgKyBuaWMgKyAiIGludGVyZmFjZS4iOyB9DQogICAgICAgICAgICBpZiAoaGFuZGxlID09IDQyOTQ5NjcyOTIpIHsgcmV0dXJuICJBbGwgb3V0Ym91bmQgcGFja2V0IGZpbHRlciB3YXMgbWF0Y2hlZCBvbiAiICsgbmljICsgIiBpbnRlcmZhY2UuIjsgfQ0KICAgICAgICAgICAgaWYgKGhhbmRsZSA9PSA0Mjk0OTY3MjkwKSB7IHJldHVybiAiU3Bvb2ZlZCBwYWNrZXQgZmlsdGVyIHdhcyBtYXRjaGVkIG9uICIgKyBuaWMgKyAiIGludGVyZmFjZS4iOyB9DQogICAgICAgICAgICByZXR1cm4gIkZpbHRlciAiICsgaGFuZGxlICsgIiB3YXMgbWF0Y2hlZCBvbiAiICsgbmljICsgIiBpbnRlcmZhY2UuIjsNCiAgICAgICAgfQ0KDQogICAgICAgIGlmIChldmVudFNlbnNvclR5cGUgPT0gMTkyKSB7DQogICAgICAgICAgICBpZiAoZXZlbnREYXRhRmllbGRbMl0gPT0gMCkgcmV0dXJuICJTZWN1cml0eSBwb2xpY3kgaW52b2tlZC4gU29tZSBvciBhbGwgbmV0d29yayB0cmFmZmljIChUWCkgd2FzIHN0b3BwZWQuIjsNCiAgICAgICAgICAgIGlmIChldmVudERhdGFGaWVsZFsyXSA9PSAyKSByZXR1cm4gIlNlY3VyaXR5IHBvbGljeSBpbnZva2VkLiBTb21lIG9yIGFsbCBuZXR3b3JrIHRyYWZmaWMgKFJYKSB3YXMgc3RvcHBlZC4iOw0KICAgICAgICAgICAgcmV0dXJuICJTZWN1cml0eSBwb2xpY3kgaW52b2tlZC4iOw0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKGV2ZW50U2Vuc29yVHlwZSA9PSAxOTMpIHsNCiAgICAgICAgICAgIGlmICgoZXZlbnREYXRhRmllbGRbMF0gPT0gMHhBQSkgJiYgKGV2ZW50RGF0YUZpZWxkWzFdID09IDB4MzApICYmIChldmVudERhdGFGaWVsZFsyXSA9PSAweDAwKSAmJiAoZXZlbnREYXRhRmllbGRbM10gPT0gMHgwMCkpIHsgcmV0dXJuICJVc2VyIHJlcXVlc3QgZm9yIHJlbW90ZSBjb25uZWN0aW9uLiI7IH0NCiAgICAgICAgICAgIGlmICgoZXZlbnREYXRhRmllbGRbMF0gPT0gMHhBQSkgJiYgKGV2ZW50RGF0YUZpZWxkWzFdID09IDB4MjApICYmIChldmVudERhdGFGaWVsZFsyXSA9PSAweDAzKSAmJiAoZXZlbnREYXRhRmllbGRbM10gPT0gMHgwMSkpIHsgcmV0dXJuICJFQUMgZXJyb3I6IGF0dGVtcHQgdG8gZ2V0IHBvc3R1cmUgd2hpbGUgTkFDIGluIEludGVs77+9IEFNVCBpcyBkaXNhYmxlZC4iOyB9IC8vIGV2ZW50RGF0YUZpZWxkID0gMHhBQTIwMDMwMTAwMDAwMDAwDQogICAgICAgICAgICBpZiAoKGV2ZW50RGF0YUZpZWxkWzBdID09IDB4QUEpICYmIChldmVudERhdGFGaWVsZFsxXSA9PSAweDIwKSAmJiAoZXZlbnREYXRhRmllbGRbMl0gPT0gMHgwNCkgJiYgKGV2ZW50RGF0YUZpZWxkWzNdID09IDB4MDApKSB7IHJldHVybiAiQ2VydGlmaWNhdGUgcmV2b2tlZC4gIjsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKGV2ZW50U2Vuc29yVHlwZSA9PSA2KSByZXR1cm4gIkF1dGhlbnRpY2F0aW9uIGZhaWxlZCAiICsgKGV2ZW50RGF0YUZpZWxkWzFdICsgKGV2ZW50RGF0YUZpZWxkWzJdIDw8IDgpKSArICIgdGltZXMuIFRoZSBzeXN0ZW0gbWF5IGJlIHVuZGVyIGF0dGFjay4iOw0KICAgICAgICBpZiAoZXZlbnRTZW5zb3JUeXBlID09IDMwKSByZXR1cm4gIk5vIGJvb3RhYmxlIG1lZGlhIjsNCiAgICAgICAgaWYgKGV2ZW50U2Vuc29yVHlwZSA9PSAzMikgcmV0dXJuICJPcGVyYXRpbmcgc3lzdGVtIGxvY2t1cCBvciBwb3dlciBpbnRlcnJ1cHQiOw0KICAgICAgICBpZiAoZXZlbnRTZW5zb3JUeXBlID09IDM1KSByZXR1cm4gIlN5c3RlbSBib290IGZhaWx1cmUiOw0KICAgICAgICBpZiAoZXZlbnRTZW5zb3JUeXBlID09IDM3KSByZXR1cm4gIlN5c3RlbSBmaXJtd2FyZSBzdGFydGVkIChhdCBsZWFzdCBvbmUgQ1BVIGlzIHByb3Blcmx5IGV4ZWN1dGluZykuIjsNCiAgICAgICAgcmV0dXJuICJVbmtub3duIFNlbnNvciBUeXBlICMiICsgZXZlbnRTZW5zb3JUeXBlOw0KICAgIH0NCg0KDQoNCiAgICAvLyBVc2VmdWwgbGluazogaHR0cHM6Ly9zb2Z0d2FyZS5pbnRlbC5jb20vc2l0ZXMvbWFuYWdlYWJpbGl0eS9BTVRfSW1wbGVtZW50YXRpb25fYW5kX1JlZmVyZW5jZV9HdWlkZS9kZWZhdWx0Lmh0bT90dXJsPVdvcmREb2N1bWVudHMlMkZzZWN1cml0eWFkbWluZXZlbnRzLmh0bQ0KDQogICAgdmFyIF9BbXRBdWRpdFN0cmluZ1RhYmxlID0NCiAgICB7DQogICAgICAgIDE2OiAnU2VjdXJpdHkgQWRtaW4nLA0KICAgICAgICAxNzogJ1JDTycsDQogICAgICAgIDE4OiAnUmVkaXJlY3Rpb24gTWFuYWdlcicsDQogICAgICAgIDE5OiAnRmlybXdhcmUgVXBkYXRlIE1hbmFnZXInLA0KICAgICAgICAyMDogJ1NlY3VyaXR5IEF1ZGl0IExvZycsDQogICAgICAgIDIxOiAnTmV0d29yayBUaW1lJywNCiAgICAgICAgMjI6ICdOZXR3b3JrIEFkbWluaXN0cmF0aW9uJywNCiAgICAgICAgMjM6ICdTdG9yYWdlIEFkbWluaXN0cmF0aW9uJywNCiAgICAgICAgMjQ6ICdFdmVudCBNYW5hZ2VyJywNCiAgICAgICAgMjU6ICdDaXJjdWl0IEJyZWFrZXIgTWFuYWdlcicsDQogICAgICAgIDI2OiAnQWdlbnQgUHJlc2VuY2UgTWFuYWdlcicsDQogICAgICAgIDI3OiAnV2lyZWxlc3MgQ29uZmlndXJhdGlvbicsDQogICAgICAgIDI4OiAnRUFDJywNCiAgICAgICAgMjk6ICdLVk0nLA0KICAgICAgICAzMDogJ1VzZXIgT3B0LUluIEV2ZW50cycsDQogICAgICAgIDMyOiAnU2NyZWVuIEJsYW5raW5nJywNCiAgICAgICAgMzM6ICdXYXRjaGRvZyBFdmVudHMnLA0KICAgICAgICAxNjAwOiAnUHJvdmlzaW9uaW5nIFN0YXJ0ZWQnLA0KICAgICAgICAxNjAxOiAnUHJvdmlzaW9uaW5nIENvbXBsZXRlZCcsDQogICAgICAgIDE2MDI6ICdBQ0wgRW50cnkgQWRkZWQnLA0KICAgICAgICAxNjAzOiAnQUNMIEVudHJ5IE1vZGlmaWVkJywNCiAgICAgICAgMTYwNDogJ0FDTCBFbnRyeSBSZW1vdmVkJywNCiAgICAgICAgMTYwNTogJ0FDTCBBY2Nlc3Mgd2l0aCBJbnZhbGlkIENyZWRlbnRpYWxzJywNCiAgICAgICAgMTYwNjogJ0FDTCBFbnRyeSBTdGF0ZScsDQogICAgICAgIDE2MDc6ICdUTFMgU3RhdGUgQ2hhbmdlZCcsDQogICAgICAgIDE2MDg6ICdUTFMgU2VydmVyIENlcnRpZmljYXRlIFNldCcsDQogICAgICAgIDE2MDk6ICdUTFMgU2VydmVyIENlcnRpZmljYXRlIFJlbW92ZScsDQogICAgICAgIDE2MTA6ICdUTFMgVHJ1c3RlZCBSb290IENlcnRpZmljYXRlIEFkZGVkJywNCiAgICAgICAgMTYxMTogJ1RMUyBUcnVzdGVkIFJvb3QgQ2VydGlmaWNhdGUgUmVtb3ZlZCcsDQogICAgICAgIDE2MTI6ICdUTFMgUHJlc2hhcmVkIEtleSBTZXQnLA0KICAgICAgICAxNjEzOiAnS2VyYmVyb3MgU2V0dGluZ3MgTW9kaWZpZWQnLA0KICAgICAgICAxNjE0OiAnS2VyYmVyb3MgTWFzdGVyIEtleSBNb2RpZmllZCcsDQogICAgICAgIDE2MTU6ICdGbGFzaCBXZWFyIG91dCBDb3VudGVycyBSZXNldCcsDQogICAgICAgIDE2MTY6ICdQb3dlciBQYWNrYWdlIE1vZGlmaWVkJywNCiAgICAgICAgMTYxNzogJ1NldCBSZWFsbSBBdXRoZW50aWNhdGlvbiBNb2RlJywNCiAgICAgICAgMTYxODogJ1VwZ3JhZGUgQ2xpZW50IHRvIEFkbWluIENvbnRyb2wgTW9kZScsDQogICAgICAgIDE2MTk6ICdVbnByb3Zpc2lvbmluZyBTdGFydGVkJywNCiAgICAgICAgMTcwMDogJ1BlcmZvcm1lZCBQb3dlciBVcCcsDQogICAgICAgIDE3MDE6ICdQZXJmb3JtZWQgUG93ZXIgRG93bicsDQogICAgICAgIDE3MDI6ICdQZXJmb3JtZWQgUG93ZXIgQ3ljbGUnLA0KICAgICAgICAxNzAzOiAnUGVyZm9ybWVkIFJlc2V0JywNCiAgICAgICAgMTcwNDogJ1NldCBCb290IE9wdGlvbnMnLA0KICAgICAgICAxODAwOiAnSURFUiBTZXNzaW9uIE9wZW5lZCcsDQogICAgICAgIDE4MDE6ICdJREVSIFNlc3Npb24gQ2xvc2VkJywNCiAgICAgICAgMTgwMjogJ0lERVIgRW5hYmxlZCcsDQogICAgICAgIDE4MDM6ICdJREVSIERpc2FibGVkJywNCiAgICAgICAgMTgwNDogJ1NvTCBTZXNzaW9uIE9wZW5lZCcsDQogICAgICAgIDE4MDU6ICdTb0wgU2Vzc2lvbiBDbG9zZWQnLA0KICAgICAgICAxODA2OiAnU29MIEVuYWJsZWQnLA0KICAgICAgICAxODA3OiAnU29MIERpc2FibGVkJywNCiAgICAgICAgMTgwODogJ0tWTSBTZXNzaW9uIFN0YXJ0ZWQnLA0KICAgICAgICAxODA5OiAnS1ZNIFNlc3Npb24gRW5kZWQnLA0KICAgICAgICAxODEwOiAnS1ZNIEVuYWJsZWQnLA0KICAgICAgICAxODExOiAnS1ZNIERpc2FibGVkJywNCiAgICAgICAgMTgxMjogJ1ZOQyBQYXNzd29yZCBGYWlsZWQgMyBUaW1lcycsDQogICAgICAgIDE5MDA6ICdGaXJtd2FyZSBVcGRhdGVkJywNCiAgICAgICAgMTkwMTogJ0Zpcm13YXJlIFVwZGF0ZSBGYWlsZWQnLA0KICAgICAgICAyMDAwOiAnU2VjdXJpdHkgQXVkaXQgTG9nIENsZWFyZWQnLA0KICAgICAgICAyMDAxOiAnU2VjdXJpdHkgQXVkaXQgUG9saWN5IE1vZGlmaWVkJywNCiAgICAgICAgMjAwMjogJ1NlY3VyaXR5IEF1ZGl0IExvZyBEaXNhYmxlZCcsDQogICAgICAgIDIwMDM6ICdTZWN1cml0eSBBdWRpdCBMb2cgRW5hYmxlZCcsDQogICAgICAgIDIwMDQ6ICdTZWN1cml0eSBBdWRpdCBMb2cgRXhwb3J0ZWQnLA0KICAgICAgICAyMDA1OiAnU2VjdXJpdHkgQXVkaXQgTG9nIFJlY292ZXJlZCcsDQogICAgICAgIDIxMDA6ICdJbnRlbCZyZWc7IE1FIFRpbWUgU2V0JywNCiAgICAgICAgMjIwMDogJ1RDUElQIFBhcmFtZXRlcnMgU2V0JywNCiAgICAgICAgMjIwMTogJ0hvc3QgTmFtZSBTZXQnLA0KICAgICAgICAyMjAyOiAnRG9tYWluIE5hbWUgU2V0JywNCiAgICAgICAgMjIwMzogJ1ZMQU4gUGFyYW1ldGVycyBTZXQnLA0KICAgICAgICAyMjA0OiAnTGluayBQb2xpY3kgU2V0JywNCiAgICAgICAgMjIwNTogJ0lQdjYgUGFyYW1ldGVycyBTZXQnLA0KICAgICAgICAyMzAwOiAnR2xvYmFsIFN0b3JhZ2UgQXR0cmlidXRlcyBTZXQnLA0KICAgICAgICAyMzAxOiAnU3RvcmFnZSBFQUNMIE1vZGlmaWVkJywNCiAgICAgICAgMjMwMjogJ1N0b3JhZ2UgRlBBQ0wgTW9kaWZpZWQnLA0KICAgICAgICAyMzAzOiAnU3RvcmFnZSBXcml0ZSBPcGVyYXRpb24nLA0KICAgICAgICAyNDAwOiAnQWxlcnQgU3Vic2NyaWJlZCcsDQogICAgICAgIDI0MDE6ICdBbGVydCBVbnN1YnNjcmliZWQnLA0KICAgICAgICAyNDAyOiAnRXZlbnQgTG9nIENsZWFyZWQnLA0KICAgICAgICAyNDAzOiAnRXZlbnQgTG9nIEZyb3plbicsDQogICAgICAgIDI1MDA6ICdDQiBGaWx0ZXIgQWRkZWQnLA0KICAgICAgICAyNTAxOiAnQ0IgRmlsdGVyIFJlbW92ZWQnLA0KICAgICAgICAyNTAyOiAnQ0IgUG9saWN5IEFkZGVkJywNCiAgICAgICAgMjUwMzogJ0NCIFBvbGljeSBSZW1vdmVkJywNCiAgICAgICAgMjUwNDogJ0NCIERlZmF1bHQgUG9saWN5IFNldCcsDQogICAgICAgIDI1MDU6ICdDQiBIZXVyaXN0aWNzIE9wdGlvbiBTZXQnLA0KICAgICAgICAyNTA2OiAnQ0IgSGV1cmlzdGljcyBTdGF0ZSBDbGVhcmVkJywNCiAgICAgICAgMjYwMDogJ0FnZW50IFdhdGNoZG9nIEFkZGVkJywNCiAgICAgICAgMjYwMTogJ0FnZW50IFdhdGNoZG9nIFJlbW92ZWQnLA0KICAgICAgICAyNjAyOiAnQWdlbnQgV2F0Y2hkb2cgQWN0aW9uIFNldCcsDQogICAgICAgIDI3MDA6ICdXaXJlbGVzcyBQcm9maWxlIEFkZGVkJywNCiAgICAgICAgMjcwMTogJ1dpcmVsZXNzIFByb2ZpbGUgUmVtb3ZlZCcsDQogICAgICAgIDI3MDI6ICdXaXJlbGVzcyBQcm9maWxlIFVwZGF0ZWQnLA0KICAgICAgICAyODAwOiAnRUFDIFBvc3R1cmUgU2lnbmVyIFNFVCcsDQogICAgICAgIDI4MDE6ICdFQUMgRW5hYmxlZCcsDQogICAgICAgIDI4MDI6ICdFQUMgRGlzYWJsZWQnLA0KICAgICAgICAyODAzOiAnRUFDIFBvc3R1cmUgU3RhdGUnLA0KICAgICAgICAyODA0OiAnRUFDIFNldCBPcHRpb25zJywNCiAgICAgICAgMjkwMDogJ0tWTSBPcHQtaW4gRW5hYmxlZCcsDQogICAgICAgIDI5MDE6ICdLVk0gT3B0LWluIERpc2FibGVkJywNCiAgICAgICAgMjkwMjogJ0tWTSBQYXNzd29yZCBDaGFuZ2VkJywNCiAgICAgICAgMjkwMzogJ0tWTSBDb25zZW50IFN1Y2NlZWRlZCcsDQogICAgICAgIDI5MDQ6ICdLVk0gQ29uc2VudCBGYWlsZWQnLA0KICAgICAgICAzMDAwOiAnT3B0LUluIFBvbGljeSBDaGFuZ2UnLA0KICAgICAgICAzMDAxOiAnU2VuZCBDb25zZW50IENvZGUgRXZlbnQnLA0KICAgICAgICAzMDAyOiAnU3RhcnQgT3B0LUluIEJsb2NrZWQgRXZlbnQnDQogICAgfQ0KDQogICAgLy8gUmV0dXJuIGh1bWFuIHJlYWRhYmxlIGV4dGVuZGVkIGF1ZGl0IGxvZyBkYXRhDQogICAgLy8gVE9ETzogSnVzdCBwdXQgc29tZSBvZiB0aGVtIGhlcmUsIGJ1dCBtYW55IG1vcmUgc3RpbGwgbmVlZCB0byBiZSBhZGRlZCwgaGVscGZ1bCBsaW5rIGhlcmU6DQogICAgLy8gaHR0cHM6Ly9zb2Z0d2FyZS5pbnRlbC5jb20vc2l0ZXMvbWFuYWdlYWJpbGl0eS9BTVRfSW1wbGVtZW50YXRpb25fYW5kX1JlZmVyZW5jZV9HdWlkZS9kZWZhdWx0Lmh0bT90dXJsPVdvcmREb2N1bWVudHMlMkZzZWN1cml0eWFkbWluZXZlbnRzLmh0bQ0KICAgIG9iai5HZXRBdWRpdExvZ0V4dGVuZGVkRGF0YVN0ciA9IGZ1bmN0aW9uIChpZCwgZGF0YSkgew0KICAgICAgICBpZiAoKGlkID09IDE2MDIgfHwgaWQgPT0gMTYwNCkgJiYgZGF0YS5jaGFyQ29kZUF0KDApID09IDApIHsgcmV0dXJuIGRhdGEuc3Vic3RyaW5nKDIsIDIgKyBkYXRhLmNoYXJDb2RlQXQoMSkpOyB9IC8vIEFDTCBFbnRyeSBBZGRlZC9SZW1vdmVkIChEaWdlc3QpDQogICAgICAgIGlmIChpZCA9PSAxNjAzKSB7IGlmIChkYXRhLmNoYXJDb2RlQXQoMSkgPT0gMCkgeyByZXR1cm4gZGF0YS5zdWJzdHJpbmcoMyk7IH0gcmV0dXJuIG51bGw7IH0gLy8gQUNMIEVudHJ5IE1vZGlmaWVkDQogICAgICAgIGlmIChpZCA9PSAxNjA1KSB7IHJldHVybiBbIkludmFsaWQgTUUgYWNjZXNzIiwgIkludmFsaWQgTUVCeCBhY2Nlc3MiXVtkYXRhLmNoYXJDb2RlQXQoMCldOyB9IC8vIEFDTCBBY2Nlc3Mgd2l0aCBJbnZhbGlkIENyZWRlbnRpYWxzDQogICAgICAgIGlmIChpZCA9PSAxNjA2KSB7IHZhciByID0gWyJEaXNhYmxlZCIsICJFbmFibGVkIl1bZGF0YS5jaGFyQ29kZUF0KDApXTsgaWYgKGRhdGEuY2hhckNvZGVBdCgxKSA9PSAwKSB7IHIgKz0gIiwgIiArIGRhdGEuc3Vic3RyaW5nKDMpOyB9IHJldHVybiByO30gLy8gQUNMIEVudHJ5IFN0YXRlDQogICAgICAgIGlmIChpZCA9PSAxNjA3KSB7IHJldHVybiAiUmVtb3RlICIgKyBbIk5vQXV0aCIsICJTZXJ2ZXJBdXRoIiwgIk11dHVhbEF1dGgiXVtkYXRhLmNoYXJDb2RlQXQoMCldICsgIiwgTG9jYWwgIiArIFsiTm9BdXRoIiwgIlNlcnZlckF1dGgiLCAiTXV0dWFsQXV0aCJdW2RhdGEuY2hhckNvZGVBdCgxKV07IH0gLy8gVExTIFN0YXRlIENoYW5nZWQNCiAgICAgICAgaWYgKGlkID09IDE2MTcpIHsgcmV0dXJuIG9iai5SZWFsbU5hbWVzW1JlYWRJbnQoZGF0YSwgMCldICsgIiwgIiArIFsiTm9BdXRoIiwgIkF1dGgiLCAiRGlzYWJsZWQiXVtkYXRhLmNoYXJDb2RlQXQoNCldOyB9IC8vIFNldCBSZWFsbSBBdXRoZW50aWNhdGlvbiBNb2RlDQogICAgICAgIGlmIChpZCA9PSAxNjE5KSB7IHJldHVybiBbIkJJT1MiLCAiTUVCeCIsICJMb2NhbCBNRUkiLCAiTG9jYWwgV1NNQU4iLCAiUmVtb3RlIFdTQU1OIl1bZGF0YS5jaGFyQ29kZUF0KDApXTsgfSAvLyBJbnRlbCBBTVQgVW5wcm92aXNpb25pbmcgU3RhcnRlZA0KICAgICAgICBpZiAoaWQgPT0gMTkwMCkgeyByZXR1cm4gIkZyb20gIiArIFJlYWRTaG9ydChkYXRhLCAwKSArICIuIiArIFJlYWRTaG9ydChkYXRhLCAyKSArICIuIiArIFJlYWRTaG9ydChkYXRhLCA0KSArICIuIiArIFJlYWRTaG9ydChkYXRhLCA2KSArICIgdG8gIiArIFJlYWRTaG9ydChkYXRhLCA4KSArICIuIiArIFJlYWRTaG9ydChkYXRhLCAxMCkgKyAiLiIgKyBSZWFkU2hvcnQoZGF0YSwgMTIpICsgIi4iICsgUmVhZFNob3J0KGRhdGEsIDE0KTsgfSAvLyBGaXJtd2FyZSBVcGRhdGVkDQogICAgICAgIGlmIChpZCA9PSAyMTAwKSB7IHZhciB0NCA9IG5ldyBEYXRlKCk7IHQ0LnNldFRpbWUoUmVhZEludChkYXRhLCAwKSAqIDEwMDAgKyAobmV3IERhdGUoKS5nZXRUaW1lem9uZU9mZnNldCgpICogNjAwMDApKTsgcmV0dXJuIHQ0LnRvTG9jYWxlU3RyaW5nKCk7IH0gLy8gSW50ZWwgQU1UIFRpbWUgU2V0DQogICAgICAgIGlmIChpZCA9PSAzMDAwKSB7IHJldHVybiAiRnJvbSAiICsgWyJOb25lIiwgIktWTSIsICJBbGwiXVtkYXRhLmNoYXJDb2RlQXQoMCldICsgIiB0byAiICsgWyJOb25lIiwgIktWTSIsICJBbGwiXVtkYXRhLmNoYXJDb2RlQXQoMSldOyB9IC8vIE9wdC1JbiBQb2xpY3kgQ2hhbmdlDQogICAgICAgIGlmIChpZCA9PSAzMDAxKSB7IHJldHVybiBbIlN1Y2Nlc3MiLCAiRmFpbGVkIDMgdGltZXMiXVtkYXRhLmNoYXJDb2RlQXQoMCldOyB9IC8vIFNlbmQgQ29uc2VudCBDb2RlIEV2ZW50DQogICAgICAgIHJldHVybiBudWxsOw0KICAgIH0NCg0KICAgIG9iai5HZXRBdWRpdExvZyA9IGZ1bmN0aW9uIChmdW5jKSB7DQogICAgICAgIG9iai5BTVRfQXVkaXRMb2dfUmVhZFJlY29yZHMoMSwgX0dldEF1ZGl0TG9nMCwgW2Z1bmMsIFtdXSk7DQogICAgfQ0KDQogICAgZnVuY3Rpb24gX0dldEF1ZGl0TG9nMChzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMsIHRhZykgew0KICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyB0YWdbMF0ob2JqLCBbXSwgc3RhdHVzKTsgcmV0dXJuOyB9DQogICAgICAgIHZhciBwdHIsIGksIGUsIHgsIHIgPSB0YWdbMV0sIHQgPSBuZXcgRGF0ZSgpLCBUaW1lU3RhbXA7DQoNCiAgICAgICAgaWYgKHJlc3BvbnNlcy5Cb2R5WydSZWNvcmRzUmV0dXJuZWQnXSA+IDApIHsNCiAgICAgICAgICAgIHJlc3BvbnNlcy5Cb2R5WydFdmVudFJlY29yZHMnXSA9IE1ha2VUb0FycmF5KHJlc3BvbnNlcy5Cb2R5WydFdmVudFJlY29yZHMnXSk7DQoNCiAgICAgICAgICAgIGZvciAoaSBpbiByZXNwb25zZXMuQm9keVsnRXZlbnRSZWNvcmRzJ10pIHsNCiAgICAgICAgICAgICAgICBlID0gbnVsbDsNCiAgICAgICAgICAgICAgICB0cnkgew0KICAgICAgICAgICAgICAgICAgICBlID0gd2luZG93LmF0b2IocmVzcG9uc2VzLkJvZHlbJ0V2ZW50UmVjb3JkcyddW2ldKTsNCiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7DQogICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGUgKyAiICIgKyByZXNwb25zZXMuQm9keVsnRXZlbnRSZWNvcmRzJ11baV0pDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHggPSB7ICdBdWRpdEFwcElEJzogUmVhZFNob3J0KGUsIDApLCAnRXZlbnRJRCc6IFJlYWRTaG9ydChlLCAyKSwgJ0luaXRpYXRvclR5cGUnOiBlLmNoYXJDb2RlQXQoNCkgfTsNCiAgICAgICAgICAgICAgICB4WydBdWRpdEFwcCddID0gX0FtdEF1ZGl0U3RyaW5nVGFibGVbeFsnQXVkaXRBcHBJRCddXTsNCiAgICAgICAgICAgICAgICB4WydFdmVudCddID0gX0FtdEF1ZGl0U3RyaW5nVGFibGVbKHhbJ0F1ZGl0QXBwSUQnXSAqIDEwMCkgKyB4WydFdmVudElEJ11dOw0KICAgICAgICAgICAgICAgIGlmICgheFsnRXZlbnQnXSkgeFsnRXZlbnQnXSA9ICcjJyArIHhbJ0V2ZW50SUQnXTsNCg0KICAgICAgICAgICAgICAgIC8vIFJlYWQgYW5kIHByb2Nlc3MgdGhlIGluaXRpYXRvcg0KICAgICAgICAgICAgICAgIGlmICh4WydJbml0aWF0b3JUeXBlJ10gPT0gMCkgew0KICAgICAgICAgICAgICAgICAgICAvLyBIVFRQIGRpZ2VzdA0KICAgICAgICAgICAgICAgICAgICB2YXIgdXNlcmxlbiA9IGUuY2hhckNvZGVBdCg1KTsNCiAgICAgICAgICAgICAgICAgICAgeFsnSW5pdGlhdG9yJ10gPSBlLnN1YnN0cmluZyg2LCA2ICsgdXNlcmxlbik7DQogICAgICAgICAgICAgICAgICAgIHB0ciA9IDYgKyB1c2VybGVuOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAoeFsnSW5pdGlhdG9yVHlwZSddID09IDEpIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gS2VyYmVyb3MNCiAgICAgICAgICAgICAgICAgICAgeFsnS2VyYmVyb3NVc2VySW5Eb21haW4nXSA9IFJlYWRJbnQoZSwgNSk7DQogICAgICAgICAgICAgICAgICAgIHZhciB1c2VybGVuID0gZS5jaGFyQ29kZUF0KDkpOw0KICAgICAgICAgICAgICAgICAgICB4WydJbml0aWF0b3InXSA9IEdldFNpZFN0cmluZyhlLnN1YnN0cmluZygxMCwgMTAgKyB1c2VybGVuKSk7DQogICAgICAgICAgICAgICAgICAgIHB0ciA9IDEwICsgdXNlcmxlbjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKHhbJ0luaXRpYXRvclR5cGUnXSA9PSAyKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIExvY2FsDQogICAgICAgICAgICAgICAgICAgIHhbJ0luaXRpYXRvciddID0gJzxpPkxvY2FsPC9pPic7DQogICAgICAgICAgICAgICAgICAgIHB0ciA9IDU7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmICh4WydJbml0aWF0b3JUeXBlJ10gPT0gMykgew0KICAgICAgICAgICAgICAgICAgICAvLyBLVk0gRGVmYXVsdCBQb3J0DQogICAgICAgICAgICAgICAgICAgIHhbJ0luaXRpYXRvciddID0gJzxpPktWTSBEZWZhdWx0IFBvcnQ8L2k+JzsNCiAgICAgICAgICAgICAgICAgICAgcHRyID0gNTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAvLyBSZWFkIHRpbWVzdGFtcA0KICAgICAgICAgICAgICAgIFRpbWVTdGFtcCA9IFJlYWRJbnQoZSwgcHRyKTsNCiAgICAgICAgICAgICAgICB4WydUaW1lJ10gPSBuZXcgRGF0ZSgoVGltZVN0YW1wICsgKHQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwKSkgKiAxMDAwKTsNCiAgICAgICAgICAgICAgICBwdHIgKz0gNDsNCg0KICAgICAgICAgICAgICAgIC8vIFJlYWQgbmV0d29yayBhY2Nlc3MNCiAgICAgICAgICAgICAgICB4WydNQ0xvY2F0aW9uVHlwZSddID0gZS5jaGFyQ29kZUF0KHB0cisrKTsNCiAgICAgICAgICAgICAgICB2YXIgbmV0bGVuID0gZS5jaGFyQ29kZUF0KHB0cisrKTsNCiAgICAgICAgICAgICAgICB4WydOZXRBZGRyZXNzJ10gPSBlLnN1YnN0cmluZyhwdHIsIHB0ciArIG5ldGxlbik7DQoNCiAgICAgICAgICAgICAgICAvLyBSZWFkIGV4dGVuZGVkIGRhdGENCiAgICAgICAgICAgICAgICBwdHIgKz0gbmV0bGVuOw0KICAgICAgICAgICAgICAgIHZhciBleGxlbiA9IGUuY2hhckNvZGVBdChwdHIrKyk7DQogICAgICAgICAgICAgICAgeFsnRXgnXSA9IGUuc3Vic3RyaW5nKHB0ciwgcHRyICsgZXhsZW4pOw0KICAgICAgICAgICAgICAgIHhbJ0V4U3RyJ10gPSBvYmouR2V0QXVkaXRMb2dFeHRlbmRlZERhdGFTdHIoKHhbJ0F1ZGl0QXBwSUQnXSAqIDEwMCkgKyB4WydFdmVudElEJ10sIHhbJ0V4J10pOw0KDQogICAgICAgICAgICAgICAgci5wdXNoKHgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChyZXNwb25zZXMuQm9keVsnVG90YWxSZWNvcmRDb3VudCddID4gci5sZW5ndGgpIHsNCiAgICAgICAgICAgIG9iai5BTVRfQXVkaXRMb2dfUmVhZFJlY29yZHMoci5sZW5ndGggKyAxLCBfR2V0QXVkaXRMb2cwLCBbdGFnWzBdLCByXSk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICB0YWdbMF0ob2JqLCByLCBzdGF0dXMpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgDQogICAgcmV0dXJuIG9iajsNCn0NCg0KDQoNCg0KLy8gRm9yZ2UgTUQ1DQpmdW5jdGlvbiBoZXhfbWQ1KHN0cikgeyByZXR1cm4gZm9yZ2UubWQubWQ1LmNyZWF0ZSgpLnVwZGF0ZShzdHIpLmRpZ2VzdCgpLnRvSGV4KCk7IH0NCg0KDQoNCi8vIFBlcmZvcm0gTUQ1IG9uIHJhdyBzdHJpbmcgYW5kIHJldHVybiByYXcgc3RyaW5nIHJlc3VsdA0KZnVuY3Rpb24gcnN0cl9tZDUoc3RyKSB7IHJldHVybiBoZXgycnN0cihoZXhfbWQ1KHN0cikpOyB9DQoNCi8qDQpDb252ZXJ0IGFyZ3VtZW50cyBpbnRvIHNlbGVjdG9yIHNldCBhbmQgYm9keSBYTUwuIFVzZWQgYnkgQU1UX1dpRmlQb3J0Q29uZmlndXJhdGlvblNlcnZpY2VfVXBkYXRlV2lGaVNldHRpbmdzLg0KYXJncyA9IHsgDQoJIldpRmlFbmRwb2ludCI6IHsNCgkJX19wYXJhbWV0ZXJUeXBlOiAncmVmZXJlbmNlJywNCgkJX19yZXNvdXJjZVVyaTogJ2h0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NjaW0vMS9jaW0tc2NoZW1hLzIvQ0lNX1dpRmlFbmRwb2ludCcsDQoJCU5hbWU6ICdXaUZpIEVuZHBvaW50IDAnDQoJfSwgDQoJIldpRmlFbmRwb2ludFNldHRpbmdzSW5wdXQiOiANCgl7DQoJCV9fcGFyYW1ldGVyVHlwZTogJ2luc3RhbmNlJywNCgkJX19uYW1lc3BhY2U6ICdodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9XaUZpRW5kcG9pbnRTZXR0aW5ncycsDQoJCUVsZW1lbnROYW1lOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZWRpdFByb2ZpbGUtcHJvZmlsZU5hbWUnKS52YWx1ZSwNCgkJSW5zdGFuY2VJRDogJ0ludGVsKHIpIEFNVDpXaUZpIEVuZHBvaW50IFNldHRpbmdzICcgKyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZWRpdFByb2ZpbGUtcHJvZmlsZU5hbWUnKS52YWx1ZSwNCgkJQXV0aGVudGljYXRpb25NZXRob2Q6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNlZGl0UHJvZmlsZS1uZXR3b3JrQXV0aGVudGljYXRpb24nKS52YWx1ZSwNCgkJLy9CU1NUeXBlOiAzLCAvLyBJbnRlbChyKSBBTVQgc3VwcG9ydHMgb25seSBpbmZyYXN0cnVjdHVyZSBuZXR3b3Jrcw0KCQlFbmNyeXB0aW9uTWV0aG9kOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZWRpdFByb2ZpbGUtZW5jcnlwdGlvbicpLnZhbHVlLA0KCQlTU0lEOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZWRpdFByb2ZpbGUtbmV0d29ya05hbWUnKS52YWx1ZSwNCgkJUHJpb3JpdHk6IDEwMCwNCgkJUFNLUGFzc1BocmFzZTogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2VkaXRQcm9maWxlLXBhc3NQaHJhc2UnKS52YWx1ZQ0KCX0sIA0KCSJJRUVFODAyMXhTZXR0aW5nc0lucHV0IjogbnVsbCwgDQoJIkNsaWVudENyZWRlbnRpYWwiOiBudWxsLCANCgkiQ0FDcmVkZW50aWFsIjogbnVsbCANCn0sIA0KKi8NCmZ1bmN0aW9uIGV4ZWNBcmd1bWVudHNUb1htbChhcmdzKSB7DQoJaWYoYXJncyA9PT0gdW5kZWZpbmVkIHx8IGFyZ3MgPT09IG51bGwpIHJldHVybiBudWxsOw0KCQ0KCXZhciByZXN1bHQgPSAnJzsNCglmb3IodmFyIGFyZ05hbWUgaW4gYXJncykgew0KCQl2YXIgYXJnID0gYXJnc1thcmdOYW1lXTsNCgkJaWYoIWFyZykgY29udGludWU7DQoJCWlmKGFyZ1snX19wYXJhbWV0ZXJUeXBlJ10gPT09ICdyZWZlcmVuY2UnKSByZXN1bHQgKz0gcmVmZXJlbmNlVG9YbWwoYXJnTmFtZSwgYXJnKTsNCgkJZWxzZSByZXN1bHQgKz0gaW5zdGFuY2VUb1htbChhcmdOYW1lLCBhcmcpOw0KCQkvL2lmKGFyZ1snX19pc0luc3RhbmNlJ10pIHJlc3VsdCArPSBpbnN0YW5jZVRvWG1sKGFyZ05hbWUsIGFyZyk7DQoJfQ0KCXJldHVybiByZXN1bHQ7DQp9DQoNCi8qKg0KICogQ29udmVydCBKYXZhU2NyaXB0IG9iamVjdCBpbnRvIFhNTA0KIA0KCTxyOldpRmlFbmRwb2ludFNldHRpbmdzSW5wdXQgeG1sbnM6cT0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NpbS1zY2hlbWEvMi9DSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MiPg0KCQk8cTpFbGVtZW50TmFtZT5XaXJlbGVzcy1Qcm9maWxlLUFkbWluPC9xOkVsZW1lbnROYW1lPg0KCQk8cTpJbnN0YW5jZUlEPkludGVsKHIpIEFNVDpXaUZpIEVuZHBvaW50IFNldHRpbmdzIFdpcmVsZXNzLVByb2ZpbGUtQWRtaW48L3E6SW5zdGFuY2VJRD4NCgkJPHE6QXV0aGVudGljYXRpb25NZXRob2Q+NjwvcTpBdXRoZW50aWNhdGlvbk1ldGhvZD4NCgkJPHE6RW5jcnlwdGlvbk1ldGhvZD40PC9xOkVuY3J5cHRpb25NZXRob2Q+DQoJCTxxOlByaW9yaXR5PjEwMDwvcTpQcmlvcml0eT4NCgkJPHE6UFNLUGFzc1BocmFzZT54eHh4eHh4eDwvcTpQU0tQYXNzUGhyYXNlPg0KCTwvcjpXaUZpRW5kcG9pbnRTZXR0aW5nc0lucHV0Pg0KICovDQpmdW5jdGlvbiBpbnN0YW5jZVRvWG1sKGluc3RhbmNlTmFtZSwgaW5JbnN0YW5jZSkgew0KCWlmKGluSW5zdGFuY2UgPT09IHVuZGVmaW5lZCB8fCBpbkluc3RhbmNlID09PSBudWxsKSByZXR1cm4gbnVsbDsNCgkNCgl2YXIgaGFzTmFtZXNwYWNlID0gISFpbkluc3RhbmNlWydfX25hbWVzcGFjZSddOw0KCXZhciBzdGFydFRhZyA9IGhhc05hbWVzcGFjZSA/ICc8cTonIDogJzwnOw0KCXZhciBlbmRUYWcgPSBoYXNOYW1lc3BhY2UgPyAnPC9xOicgOiAnPC8nOw0KCXZhciBuYW1lc3BhY2VEZWYgPSBoYXNOYW1lc3BhY2UgPyAoJyB4bWxuczpxPSInICsgaW5JbnN0YW5jZVsnX19uYW1lc3BhY2UnXSArICciJyApOiAnJzsNCgl2YXIgcmVzdWx0ID0gJzxyOicgKyBpbnN0YW5jZU5hbWUgKyBuYW1lc3BhY2VEZWYgKyAnPic7DQoJZm9yKHZhciBwcm9wIGluIGluSW5zdGFuY2UpIHsNCgkJaWYgKCFpbkluc3RhbmNlLmhhc093blByb3BlcnR5KHByb3ApIHx8IHByb3AuaW5kZXhPZignX18nKSA9PT0gMCkgY29udGludWU7DQoJCQ0KCQlpZiAodHlwZW9mIGluSW5zdGFuY2VbcHJvcF0gPT09ICdmdW5jdGlvbicgfHwgQXJyYXkuaXNBcnJheShpbkluc3RhbmNlW3Byb3BdKSApIGNvbnRpbnVlOw0KCQkNCgkJaWYgKHR5cGVvZiBpbkluc3RhbmNlW3Byb3BdID09PSAnb2JqZWN0Jykgew0KCQkJLy9yZXN1bHQgKz0gc3RhcnRUYWcgKyBwcm9wICsnPicgKyBpbnN0YW5jZVRvWG1sKCdwcm9wJywgaW5JbnN0YW5jZVtwcm9wXSkgKyBlbmRUYWcgKyBwcm9wICsnPic7DQoJCQljb25zb2xlLmVycm9yKCdvbmx5IGNvbnZlcnQgb25lIGxldmVsIGRvd24uLi4nKTsNCgkJfQ0KCQllbHNlIHsNCgkJCXJlc3VsdCArPSBzdGFydFRhZyArIHByb3AgKyc+JyArIGluSW5zdGFuY2VbcHJvcF0udG9TdHJpbmcoKSArIGVuZFRhZyArIHByb3AgKyc+JzsNCgkJfQ0KCX0NCglyZXN1bHQgKz0gJzwvcjonICsgaW5zdGFuY2VOYW1lICsgJz4nOw0KCXJldHVybiByZXN1bHQ7DQp9DQoNCg0KLyoqDQogKiBDb252ZXJ0IGEgc2VsZWN0b3Igc2V0IGludG8gWE1MLiBFeHBlY3Qgbm8gbmVzdGluZy4NCiAqIHsNCiAqIAlzZWxlY3Rvck5hbWUgOiBzZWxlY3RvclZhbHVlLA0KICogCXNlbGVjdG9yTmFtZSA6IHNlbGVjdG9yVmFsdWUsDQogKgkuLi4gLi4uDQogKiB9DQogDQoJPHI6V2lGaUVuZHBvaW50Pg0KCQk8YTpBZGRyZXNzPmh0dHA6Ly8xOTIuMTY4LjEuMTAzOjE2OTkyL3dzbWFuPC9hOkFkZHJlc3M+DQoJCTxhOlJlZmVyZW5jZVBhcmFtZXRlcnM+DQoJCQk8dzpSZXNvdXJjZVVSST5odHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9XaUZpRW5kcG9pbnQ8L3c6UmVzb3VyY2VVUkk+DQoJCQk8dzpTZWxlY3RvclNldD4NCgkJCQk8dzpTZWxlY3RvciBOYW1lPSJOYW1lIj5XaUZpIEVuZHBvaW50IDA8L3c6U2VsZWN0b3I+DQoJCQk8L3c6U2VsZWN0b3JTZXQ+DQoJCTwvYTpSZWZlcmVuY2VQYXJhbWV0ZXJzPg0KCTwvcjpXaUZpRW5kcG9pbnQ+DQoJCQkNCiAqLw0KZnVuY3Rpb24gcmVmZXJlbmNlVG9YbWwocmVmZXJlbmNlTmFtZSwgaW5SZWZlcmVuY2UpIHsNCglpZihpblJlZmVyZW5jZSA9PT0gdW5kZWZpbmVkIHx8IGluUmVmZXJlbmNlID09PSBudWxsICkgcmV0dXJuIG51bGw7DQoJDQoJdmFyIHJlc3VsdCA9ICc8cjonICsgcmVmZXJlbmNlTmFtZSArICc+PGE6QWRkcmVzcz4vd3NtYW48L2E6QWRkcmVzcz48YTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjx3OlJlc291cmNlVVJJPicrIGluUmVmZXJlbmNlWydfX3Jlc291cmNlVXJpJ10rJzwvdzpSZXNvdXJjZVVSST48dzpTZWxlY3RvclNldD4nOw0KCWZvcih2YXIgc2VsZWN0b3JOYW1lIGluIGluUmVmZXJlbmNlKSB7DQoJCWlmICghaW5SZWZlcmVuY2UuaGFzT3duUHJvcGVydHkoc2VsZWN0b3JOYW1lKSB8fCBzZWxlY3Rvck5hbWUuaW5kZXhPZignX18nKSA9PT0gMCkgY29udGludWU7DQoJCQ0KCQlpZiAodHlwZW9mIGluUmVmZXJlbmNlW3NlbGVjdG9yTmFtZV0gPT09ICdmdW5jdGlvbicgfHwgDQoJCQl0eXBlb2YgaW5SZWZlcmVuY2Vbc2VsZWN0b3JOYW1lXSA9PT0gJ29iamVjdCcgfHwNCgkJCUFycmF5LmlzQXJyYXkoaW5SZWZlcmVuY2Vbc2VsZWN0b3JOYW1lXSkgKQ0KCQkJY29udGludWU7DQoJCQ0KCQlyZXN1bHQgKz0gJzx3OlNlbGVjdG9yIE5hbWU9IicgKyBzZWxlY3Rvck5hbWUgKyciPicgKyBpblJlZmVyZW5jZVtzZWxlY3Rvck5hbWVdLnRvU3RyaW5nKCkgKyAnPC93OlNlbGVjdG9yPic7DQoJfQ0KCQ0KCXJlc3VsdCArPSAnPC93OlNlbGVjdG9yU2V0PjwvYTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjwvcjonICsgcmVmZXJlbmNlTmFtZSArICc+JzsNCglyZXR1cm4gcmVzdWx0Ow0KfQ0KDQovLyBDb252ZXJ0IGEgYnl0ZSBhcnJheSBvZiBTSUQgaW50byBzdHJpbmcNCmZ1bmN0aW9uIEdldFNpZFN0cmluZyhzaWQpIHsNCiAgICB2YXIgciA9ICJTLSIgKyBzaWQuY2hhckNvZGVBdCgwKSArICItIiArIHNpZC5jaGFyQ29kZUF0KDcpOw0KICAgIGZvciAodmFyIGkgPSAyOyBpIDwgKHNpZC5sZW5ndGggLyA0KSA7IGkrKykgciArPSAiLSIgKyBSZWFkSW50WChzaWQsIGkgKiA0KTsNCiAgICByZXR1cm4gcjsNCn0NCg0KLy8gQ29udmVydCBhIFNJRCByZWFkYWJsZSBzdHJpbmcgaW50byBieXRlcw0KZnVuY3Rpb24gR2V0U2lkQnl0ZUFycmF5KHNpZFN0cmluZykgew0KICAgIGlmICghc2lkU3RyaW5nIHx8IHNpZFN0cmluZyA9PSBudWxsKSByZXR1cm4gbnVsbDsNCiAgICB2YXIgc2lkUGFydHMgPSBzaWRTdHJpbmcuc3BsaXQoJy0nKTsNCg0KICAgIC8vIE1ha2Ugc3VyZSB0aGUgU0lEIGhhcyBhdCBsZWFzdCA0IHBhcnRzIGFuZCBzdGFydHMgd2l0aCAnUycNCiAgICBpZiAoc2lkUGFydHMubGVuZ3RoIDwgNCB8fCAoc2lkUGFydHNbMF0gIT0gJ3MnICYmIHNpZFBhcnRzWzBdICE9ICdTJykpIHJldHVybiBudWxsOw0KDQogICAgLy8gQ2hlY2sgdGhhdCBlYWNoIHBhcnQgb2YgdGhlIFNJRCBpcyByZWFsbHkgYW4gaW50ZWdlcg0KICAgIGZvciAodmFyIGkgPSAxOyBpIDwgc2lkUGFydHMubGVuZ3RoOyBpKyspIHsgdmFyIHkgPSBwYXJzZUludChzaWRQYXJ0c1tpXSk7IGlmICh5ICE9IHNpZFBhcnRzW2ldKSByZXR1cm4gbnVsbDsgc2lkUGFydHNbaV0gPSB5OyB9DQoNCiAgICAvLyBWZXJzaW9uICg4IGJpdCkgKyBJZCBjb3VudCAoOCBiaXQpICsgNDggYml0IGluIGJpZyBlbmRpYW4gLS0gRE8gTk9UIHVzZSBiaXR3aXNlIHJpZ2h0IHNoaWZ0IG9wZXJhdG9yLiBKYXZhU2NyaXB0IGNvbnZlcnRzIHRoZSBudW1iZXIgaW50byBhIDMyIGJpdCBpbnRlZ2VyIGJlZm9yZSBzaGlmdGluZy4gSW4gcmVhbCB3b3JsZCwgaXQncyBoaWdobHkgbGlrZWx5IHRoaXMgcGFydCBpcyBhbHdheXMgMC4NCiAgICB2YXIgciA9IFN0cmluZy5mcm9tQ2hhckNvZGUoc2lkUGFydHNbMV0pICsgU3RyaW5nLmZyb21DaGFyQ29kZShzaWRQYXJ0cy5sZW5ndGggLSAzKSArIFNob3J0VG9TdHIoTWF0aC5mbG9vcihzaWRQYXJ0c1syXSAvIE1hdGgucG93KDIsIDMyKSkpICsgSW50VG9TdHIoKHNpZFBhcnRzWzJdKSAmIDB4RkZGRik7DQoNCiAgICAvLyB0aGUgcmVzdCBhcmUgaW4gMzIgYml0IGluIGxpdHRsZSBlbmRpYW4NCiAgICBmb3IgKHZhciBpID0gMzsgaSA8IHNpZFBhcnRzLmxlbmd0aDsgaSsrKSByICs9IEludFRvU3RyWChzaWRQYXJ0c1tpXSk7DQogICAgcmV0dXJuIHI7DQp9DQooZnVuY3Rpb24ocm9vdCwgZmFjdG9yeSkgewogIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkgewogICAgZGVmaW5lKFtdLCBmYWN0b3J5KTsKICB9IGVsc2UgewogICAgcm9vdC5mb3JnZSA9IGZhY3RvcnkoKTsKICB9Cn0pKHRoaXMsIGZ1bmN0aW9uKCkgewovKioKICogbGljZW5zZSBhbG1vbmQgMC4yLjkgQ29weXJpZ2h0IChjKSAyMDExLTIwMTQsIFRoZSBEb2pvIEZvdW5kYXRpb24gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogQXZhaWxhYmxlIHZpYSB0aGUgTUlUIG9yIG5ldyBCU0QgbGljZW5zZS4KICogc2VlOiBodHRwOi8vZ2l0aHViLmNvbS9qcmJ1cmtlL2FsbW9uZCBmb3IgZGV0YWlscwogKi8KLy9Hb2luZyBzbG9wcHkgdG8gYXZvaWQgJ3VzZSBzdHJpY3QnIHN0cmluZyBjb3N0LCBidXQgc3RyaWN0IHByYWN0aWNlcyBzaG91bGQKLy9iZSBmb2xsb3dlZC4KLypqc2xpbnQgc2xvcHB5OiB0cnVlICovCi8qZ2xvYmFsIHNldFRpbWVvdXQ6IGZhbHNlICovCgp2YXIgcmVxdWlyZWpzLCByZXF1aXJlLCBkZWZpbmU7CihmdW5jdGlvbiAodW5kZWYpIHsKICAgIHZhciBtYWluLCByZXEsIG1ha2VNYXAsIGhhbmRsZXJzLAogICAgICAgIGRlZmluZWQgPSB7fSwKICAgICAgICB3YWl0aW5nID0ge30sCiAgICAgICAgY29uZmlnID0ge30sCiAgICAgICAgZGVmaW5pbmcgPSB7fSwKICAgICAgICBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LAogICAgICAgIGFwcyA9IFtdLnNsaWNlLAogICAgICAgIGpzU3VmZml4UmVnRXhwID0gL1wuanMkLzsKCiAgICBmdW5jdGlvbiBoYXNQcm9wKG9iaiwgcHJvcCkgewogICAgICAgIHJldHVybiBoYXNPd24uY2FsbChvYmosIHByb3ApOwogICAgfQoKICAgIC8qKgogICAgICogR2l2ZW4gYSByZWxhdGl2ZSBtb2R1bGUgbmFtZSwgbGlrZSAuL3NvbWV0aGluZywgbm9ybWFsaXplIGl0IHRvCiAgICAgKiBhIHJlYWwgbmFtZSB0aGF0IGNhbiBiZSBtYXBwZWQgdG8gYSBwYXRoLgogICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgdGhlIHJlbGF0aXZlIG5hbWUKICAgICAqIEBwYXJhbSB7U3RyaW5nfSBiYXNlTmFtZSBhIHJlYWwgbmFtZSB0aGF0IHRoZSBuYW1lIGFyZyBpcyByZWxhdGl2ZQogICAgICogdG8uCiAgICAgKiBAcmV0dXJucyB7U3RyaW5nfSBub3JtYWxpemVkIG5hbWUKICAgICAqLwogICAgZnVuY3Rpb24gbm9ybWFsaXplKG5hbWUsIGJhc2VOYW1lKSB7CiAgICAgICAgdmFyIG5hbWVQYXJ0cywgbmFtZVNlZ21lbnQsIG1hcFZhbHVlLCBmb3VuZE1hcCwgbGFzdEluZGV4LAogICAgICAgICAgICBmb3VuZEksIGZvdW5kU3Rhck1hcCwgc3RhckksIGksIGosIHBhcnQsCiAgICAgICAgICAgIGJhc2VQYXJ0cyA9IGJhc2VOYW1lICYmIGJhc2VOYW1lLnNwbGl0KCIvIiksCiAgICAgICAgICAgIG1hcCA9IGNvbmZpZy5tYXAsCiAgICAgICAgICAgIHN0YXJNYXAgPSAobWFwICYmIG1hcFsnKiddKSB8fCB7fTsKCiAgICAgICAgLy9BZGp1c3QgYW55IHJlbGF0aXZlIHBhdGhzLgogICAgICAgIGlmIChuYW1lICYmIG5hbWUuY2hhckF0KDApID09PSAiLiIpIHsKICAgICAgICAgICAgLy9JZiBoYXZlIGEgYmFzZSBuYW1lLCB0cnkgdG8gbm9ybWFsaXplIGFnYWluc3QgaXQsCiAgICAgICAgICAgIC8vb3RoZXJ3aXNlLCBhc3N1bWUgaXQgaXMgYSB0b3AtbGV2ZWwgcmVxdWlyZSB0aGF0IHdpbGwKICAgICAgICAgICAgLy9iZSByZWxhdGl2ZSB0byBiYXNlVXJsIGluIHRoZSBlbmQuCiAgICAgICAgICAgIGlmIChiYXNlTmFtZSkgewogICAgICAgICAgICAgICAgLy9Db252ZXJ0IGJhc2VOYW1lIHRvIGFycmF5LCBhbmQgbG9wIG9mZiB0aGUgbGFzdCBwYXJ0LAogICAgICAgICAgICAgICAgLy9zbyB0aGF0IC4gbWF0Y2hlcyB0aGF0ICJkaXJlY3RvcnkiIGFuZCBub3QgbmFtZSBvZiB0aGUgYmFzZU5hbWUncwogICAgICAgICAgICAgICAgLy9tb2R1bGUuIEZvciBpbnN0YW5jZSwgYmFzZU5hbWUgb2YgIm9uZS90d28vdGhyZWUiLCBtYXBzIHRvCiAgICAgICAgICAgICAgICAvLyJvbmUvdHdvL3RocmVlLmpzIiwgYnV0IHdlIHdhbnQgdGhlIGRpcmVjdG9yeSwgIm9uZS90d28iIGZvcgogICAgICAgICAgICAgICAgLy90aGlzIG5vcm1hbGl6YXRpb24uCiAgICAgICAgICAgICAgICBiYXNlUGFydHMgPSBiYXNlUGFydHMuc2xpY2UoMCwgYmFzZVBhcnRzLmxlbmd0aCAtIDEpOwogICAgICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3BsaXQoJy8nKTsKICAgICAgICAgICAgICAgIGxhc3RJbmRleCA9IG5hbWUubGVuZ3RoIC0gMTsKCiAgICAgICAgICAgICAgICAvLyBOb2RlIC5qcyBhbGxvd2FuY2U6CiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm5vZGVJZENvbXBhdCAmJiBqc1N1ZmZpeFJlZ0V4cC50ZXN0KG5hbWVbbGFzdEluZGV4XSkpIHsKICAgICAgICAgICAgICAgICAgICBuYW1lW2xhc3RJbmRleF0gPSBuYW1lW2xhc3RJbmRleF0ucmVwbGFjZShqc1N1ZmZpeFJlZ0V4cCwgJycpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIG5hbWUgPSBiYXNlUGFydHMuY29uY2F0KG5hbWUpOwoKICAgICAgICAgICAgICAgIC8vc3RhcnQgdHJpbURvdHMKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuYW1lLmxlbmd0aDsgaSArPSAxKSB7CiAgICAgICAgICAgICAgICAgICAgcGFydCA9IG5hbWVbaV07CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnQgPT09ICIuIikgewogICAgICAgICAgICAgICAgICAgICAgICBuYW1lLnNwbGljZShpLCAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgaSAtPSAxOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydCA9PT0gIi4uIikgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PT0gMSAmJiAobmFtZVsyXSA9PT0gJy4uJyB8fCBuYW1lWzBdID09PSAnLi4nKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9FbmQgb2YgdGhlIGxpbmUuIEtlZXAgYXQgbGVhc3Qgb25lIG5vbi1kb3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcGF0aCBzZWdtZW50IGF0IHRoZSBmcm9udCBzbyBpdCBjYW4gYmUgbWFwcGVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NvcnJlY3RseSB0byBkaXNrLiBPdGhlcndpc2UsIHRoZXJlIGlzIGxpa2VseQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9ubyBwYXRoIG1hcHBpbmcgZm9yIGEgcGF0aCBzdGFydGluZyB3aXRoICcuLicuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1RoaXMgY2FuIHN0aWxsIGZhaWwsIGJ1dCBjYXRjaGVzIHRoZSBtb3N0IHJlYXNvbmFibGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdXNlcyBvZiAuLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUuc3BsaWNlKGkgLSAxLCAyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgLT0gMjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vZW5kIHRyaW1Eb3RzCgogICAgICAgICAgICAgICAgbmFtZSA9IG5hbWUuam9pbigiLyIpOwogICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWUuaW5kZXhPZignLi8nKSA9PT0gMCkgewogICAgICAgICAgICAgICAgLy8gTm8gYmFzZU5hbWUsIHNvIHRoaXMgaXMgSUQgaXMgcmVzb2x2ZWQgcmVsYXRpdmUKICAgICAgICAgICAgICAgIC8vIHRvIGJhc2VVcmwsIHB1bGwgb2ZmIHRoZSBsZWFkaW5nIGRvdC4KICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cmluZygyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy9BcHBseSBtYXAgY29uZmlnIGlmIGF2YWlsYWJsZS4KICAgICAgICBpZiAoKGJhc2VQYXJ0cyB8fCBzdGFyTWFwKSAmJiBtYXApIHsKICAgICAgICAgICAgbmFtZVBhcnRzID0gbmFtZS5zcGxpdCgnLycpOwoKICAgICAgICAgICAgZm9yIChpID0gbmFtZVBhcnRzLmxlbmd0aDsgaSA+IDA7IGkgLT0gMSkgewogICAgICAgICAgICAgICAgbmFtZVNlZ21lbnQgPSBuYW1lUGFydHMuc2xpY2UoMCwgaSkuam9pbigiLyIpOwoKICAgICAgICAgICAgICAgIGlmIChiYXNlUGFydHMpIHsKICAgICAgICAgICAgICAgICAgICAvL0ZpbmQgdGhlIGxvbmdlc3QgYmFzZU5hbWUgc2VnbWVudCBtYXRjaCBpbiB0aGUgY29uZmlnLgogICAgICAgICAgICAgICAgICAgIC8vU28sIGRvIGpvaW5zIG9uIHRoZSBiaWdnZXN0IHRvIHNtYWxsZXN0IGxlbmd0aHMgb2YgYmFzZVBhcnRzLgogICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IGJhc2VQYXJ0cy5sZW5ndGg7IGogPiAwOyBqIC09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbWFwVmFsdWUgPSBtYXBbYmFzZVBhcnRzLnNsaWNlKDAsIGopLmpvaW4oJy8nKV07CgogICAgICAgICAgICAgICAgICAgICAgICAvL2Jhc2VOYW1lIHNlZ21lbnQgaGFzICBjb25maWcsIGZpbmQgaWYgaXQgaGFzIG9uZSBmb3IKICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzIG5hbWUuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtYXBWYWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwVmFsdWUgPSBtYXBWYWx1ZVtuYW1lU2VnbWVudF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWFwVmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL01hdGNoLCB1cGRhdGUgbmFtZSB0byB0aGUgbmV3IHZhbHVlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kTWFwID0gbWFwVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRJID0gaTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoZm91bmRNYXApIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvL0NoZWNrIGZvciBhIHN0YXIgbWFwIG1hdGNoLCBidXQganVzdCBob2xkIG9uIHRvIGl0LAogICAgICAgICAgICAgICAgLy9pZiB0aGVyZSBpcyBhIHNob3J0ZXIgc2VnbWVudCBtYXRjaCBsYXRlciBpbiBhIG1hdGNoaW5nCiAgICAgICAgICAgICAgICAvL2NvbmZpZywgdGhlbiBmYXZvciBvdmVyIHRoaXMgc3RhciBtYXAuCiAgICAgICAgICAgICAgICBpZiAoIWZvdW5kU3Rhck1hcCAmJiBzdGFyTWFwICYmIHN0YXJNYXBbbmFtZVNlZ21lbnRdKSB7CiAgICAgICAgICAgICAgICAgICAgZm91bmRTdGFyTWFwID0gc3Rhck1hcFtuYW1lU2VnbWVudF07CiAgICAgICAgICAgICAgICAgICAgc3RhckkgPSBpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWZvdW5kTWFwICYmIGZvdW5kU3Rhck1hcCkgewogICAgICAgICAgICAgICAgZm91bmRNYXAgPSBmb3VuZFN0YXJNYXA7CiAgICAgICAgICAgICAgICBmb3VuZEkgPSBzdGFySTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGZvdW5kTWFwKSB7CiAgICAgICAgICAgICAgICBuYW1lUGFydHMuc3BsaWNlKDAsIGZvdW5kSSwgZm91bmRNYXApOwogICAgICAgICAgICAgICAgbmFtZSA9IG5hbWVQYXJ0cy5qb2luKCcvJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBuYW1lOwogICAgfQoKICAgIGZ1bmN0aW9uIG1ha2VSZXF1aXJlKHJlbE5hbWUsIGZvcmNlU3luYykgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vQSB2ZXJzaW9uIG9mIGEgcmVxdWlyZSBmdW5jdGlvbiB0aGF0IHBhc3NlcyBhIG1vZHVsZU5hbWUKICAgICAgICAgICAgLy92YWx1ZSBmb3IgaXRlbXMgdGhhdCBtYXkgbmVlZCB0bwogICAgICAgICAgICAvL2xvb2sgdXAgcGF0aHMgcmVsYXRpdmUgdG8gdGhlIG1vZHVsZU5hbWUKICAgICAgICAgICAgcmV0dXJuIHJlcS5hcHBseSh1bmRlZiwgYXBzLmNhbGwoYXJndW1lbnRzLCAwKS5jb25jYXQoW3JlbE5hbWUsIGZvcmNlU3luY10pKTsKICAgICAgICB9OwogICAgfQoKICAgIGZ1bmN0aW9uIG1ha2VOb3JtYWxpemUocmVsTmFtZSkgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAobmFtZSkgewogICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplKG5hbWUsIHJlbE5hbWUpOwogICAgICAgIH07CiAgICB9CgogICAgZnVuY3Rpb24gbWFrZUxvYWQoZGVwTmFtZSkgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgZGVmaW5lZFtkZXBOYW1lXSA9IHZhbHVlOwogICAgICAgIH07CiAgICB9CgogICAgZnVuY3Rpb24gY2FsbERlcChuYW1lKSB7CiAgICAgICAgaWYgKGhhc1Byb3Aod2FpdGluZywgbmFtZSkpIHsKICAgICAgICAgICAgdmFyIGFyZ3MgPSB3YWl0aW5nW25hbWVdOwogICAgICAgICAgICBkZWxldGUgd2FpdGluZ1tuYW1lXTsKICAgICAgICAgICAgZGVmaW5pbmdbbmFtZV0gPSB0cnVlOwogICAgICAgICAgICBtYWluLmFwcGx5KHVuZGVmLCBhcmdzKTsKICAgICAgICB9CgogICAgICAgIGlmICghaGFzUHJvcChkZWZpbmVkLCBuYW1lKSAmJiAhaGFzUHJvcChkZWZpbmluZywgbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyAnICsgbmFtZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBkZWZpbmVkW25hbWVdOwogICAgfQoKICAgIC8vVHVybnMgYSBwbHVnaW4hcmVzb3VyY2UgdG8gW3BsdWdpbiwgcmVzb3VyY2VdCiAgICAvL3dpdGggdGhlIHBsdWdpbiBiZWluZyB1bmRlZmluZWQgaWYgdGhlIG5hbWUKICAgIC8vZGlkIG5vdCBoYXZlIGEgcGx1Z2luIHByZWZpeC4KICAgIGZ1bmN0aW9uIHNwbGl0UHJlZml4KG5hbWUpIHsKICAgICAgICB2YXIgcHJlZml4LAogICAgICAgICAgICBpbmRleCA9IG5hbWUgPyBuYW1lLmluZGV4T2YoJyEnKSA6IC0xOwogICAgICAgIGlmIChpbmRleCA+IC0xKSB7CiAgICAgICAgICAgIHByZWZpeCA9IG5hbWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSwgbmFtZS5sZW5ndGgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gW3ByZWZpeCwgbmFtZV07CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWtlcyBhIG5hbWUgbWFwLCBub3JtYWxpemluZyB0aGUgbmFtZSwgYW5kIHVzaW5nIGEgcGx1Z2luCiAgICAgKiBmb3Igbm9ybWFsaXphdGlvbiBpZiBuZWNlc3NhcnkuIEdyYWJzIGEgcmVmIHRvIHBsdWdpbgogICAgICogdG9vLCBhcyBhbiBvcHRpbWl6YXRpb24uCiAgICAgKi8KICAgIG1ha2VNYXAgPSBmdW5jdGlvbiAobmFtZSwgcmVsTmFtZSkgewogICAgICAgIHZhciBwbHVnaW4sCiAgICAgICAgICAgIHBhcnRzID0gc3BsaXRQcmVmaXgobmFtZSksCiAgICAgICAgICAgIHByZWZpeCA9IHBhcnRzWzBdOwoKICAgICAgICBuYW1lID0gcGFydHNbMV07CgogICAgICAgIGlmIChwcmVmaXgpIHsKICAgICAgICAgICAgcHJlZml4ID0gbm9ybWFsaXplKHByZWZpeCwgcmVsTmFtZSk7CiAgICAgICAgICAgIHBsdWdpbiA9IGNhbGxEZXAocHJlZml4KTsKICAgICAgICB9CgogICAgICAgIC8vTm9ybWFsaXplIGFjY29yZGluZwogICAgICAgIGlmIChwcmVmaXgpIHsKICAgICAgICAgICAgaWYgKHBsdWdpbiAmJiBwbHVnaW4ubm9ybWFsaXplKSB7CiAgICAgICAgICAgICAgICBuYW1lID0gcGx1Z2luLm5vcm1hbGl6ZShuYW1lLCBtYWtlTm9ybWFsaXplKHJlbE5hbWUpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG5hbWUgPSBub3JtYWxpemUobmFtZSwgcmVsTmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBuYW1lID0gbm9ybWFsaXplKG5hbWUsIHJlbE5hbWUpOwogICAgICAgICAgICBwYXJ0cyA9IHNwbGl0UHJlZml4KG5hbWUpOwogICAgICAgICAgICBwcmVmaXggPSBwYXJ0c1swXTsKICAgICAgICAgICAgbmFtZSA9IHBhcnRzWzFdOwogICAgICAgICAgICBpZiAocHJlZml4KSB7CiAgICAgICAgICAgICAgICBwbHVnaW4gPSBjYWxsRGVwKHByZWZpeCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vVXNpbmcgcmlkaWN1bG91cyBwcm9wZXJ0eSBuYW1lcyBmb3Igc3BhY2UgcmVhc29ucwogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIGY6IHByZWZpeCA/IHByZWZpeCArICchJyArIG5hbWUgOiBuYW1lLCAvL2Z1bGxOYW1lCiAgICAgICAgICAgIG46IG5hbWUsCiAgICAgICAgICAgIHByOiBwcmVmaXgsCiAgICAgICAgICAgIHA6IHBsdWdpbgogICAgICAgIH07CiAgICB9OwoKICAgIGZ1bmN0aW9uIG1ha2VDb25maWcobmFtZSkgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAoY29uZmlnICYmIGNvbmZpZy5jb25maWcgJiYgY29uZmlnLmNvbmZpZ1tuYW1lXSkgfHwge307CiAgICAgICAgfTsKICAgIH0KCiAgICBoYW5kbGVycyA9IHsKICAgICAgICByZXF1aXJlOiBmdW5jdGlvbiAobmFtZSkgewogICAgICAgICAgICByZXR1cm4gbWFrZVJlcXVpcmUobmFtZSk7CiAgICAgICAgfSwKICAgICAgICBleHBvcnRzOiBmdW5jdGlvbiAobmFtZSkgewogICAgICAgICAgICB2YXIgZSA9IGRlZmluZWRbbmFtZV07CiAgICAgICAgICAgIGlmICh0eXBlb2YgZSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICAgICAgICAgIHJldHVybiBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIChkZWZpbmVkW25hbWVdID0ge30pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtb2R1bGU6IGZ1bmN0aW9uIChuYW1lKSB7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICBpZDogbmFtZSwKICAgICAgICAgICAgICAgIHVyaTogJycsCiAgICAgICAgICAgICAgICBleHBvcnRzOiBkZWZpbmVkW25hbWVdLAogICAgICAgICAgICAgICAgY29uZmlnOiBtYWtlQ29uZmlnKG5hbWUpCiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfTsKCiAgICBtYWluID0gZnVuY3Rpb24gKG5hbWUsIGRlcHMsIGNhbGxiYWNrLCByZWxOYW1lKSB7CiAgICAgICAgdmFyIGNqc01vZHVsZSwgZGVwTmFtZSwgcmV0LCBtYXAsIGksCiAgICAgICAgICAgIGFyZ3MgPSBbXSwKICAgICAgICAgICAgY2FsbGJhY2tUeXBlID0gdHlwZW9mIGNhbGxiYWNrLAogICAgICAgICAgICB1c2luZ0V4cG9ydHM7CgogICAgICAgIC8vVXNlIG5hbWUgaWYgbm8gcmVsTmFtZQogICAgICAgIHJlbE5hbWUgPSByZWxOYW1lIHx8IG5hbWU7CgogICAgICAgIC8vQ2FsbCB0aGUgY2FsbGJhY2sgdG8gZGVmaW5lIHRoZSBtb2R1bGUsIGlmIG5lY2Vzc2FyeS4KICAgICAgICBpZiAoY2FsbGJhY2tUeXBlID09PSAndW5kZWZpbmVkJyB8fCBjYWxsYmFja1R5cGUgPT09ICdmdW5jdGlvbicpIHsKICAgICAgICAgICAgLy9QdWxsIG91dCB0aGUgZGVmaW5lZCBkZXBlbmRlbmNpZXMgYW5kIHBhc3MgdGhlIG9yZGVyZWQKICAgICAgICAgICAgLy92YWx1ZXMgdG8gdGhlIGNhbGxiYWNrLgogICAgICAgICAgICAvL0RlZmF1bHQgdG8gW3JlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZV0gaWYgbm8gZGVwcwogICAgICAgICAgICBkZXBzID0gIWRlcHMubGVuZ3RoICYmIGNhbGxiYWNrLmxlbmd0aCA/IFsncmVxdWlyZScsICdleHBvcnRzJywgJ21vZHVsZSddIDogZGVwczsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGRlcHMubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgICAgICAgICAgIG1hcCA9IG1ha2VNYXAoZGVwc1tpXSwgcmVsTmFtZSk7CiAgICAgICAgICAgICAgICBkZXBOYW1lID0gbWFwLmY7CgogICAgICAgICAgICAgICAgLy9GYXN0IHBhdGggQ29tbW9uSlMgc3RhbmRhcmQgZGVwZW5kZW5jaWVzLgogICAgICAgICAgICAgICAgaWYgKGRlcE5hbWUgPT09ICJyZXF1aXJlIikgewogICAgICAgICAgICAgICAgICAgIGFyZ3NbaV0gPSBoYW5kbGVycy5yZXF1aXJlKG5hbWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkZXBOYW1lID09PSAiZXhwb3J0cyIpIHsKICAgICAgICAgICAgICAgICAgICAvL0NvbW1vbkpTIG1vZHVsZSBzcGVjIDEuMQogICAgICAgICAgICAgICAgICAgIGFyZ3NbaV0gPSBoYW5kbGVycy5leHBvcnRzKG5hbWUpOwogICAgICAgICAgICAgICAgICAgIHVzaW5nRXhwb3J0cyA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRlcE5hbWUgPT09ICJtb2R1bGUiKSB7CiAgICAgICAgICAgICAgICAgICAgLy9Db21tb25KUyBtb2R1bGUgc3BlYyAxLjEKICAgICAgICAgICAgICAgICAgICBjanNNb2R1bGUgPSBhcmdzW2ldID0gaGFuZGxlcnMubW9kdWxlKG5hbWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChoYXNQcm9wKGRlZmluZWQsIGRlcE5hbWUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc1Byb3Aod2FpdGluZywgZGVwTmFtZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzUHJvcChkZWZpbmluZywgZGVwTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBhcmdzW2ldID0gY2FsbERlcChkZXBOYW1lKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWFwLnApIHsKICAgICAgICAgICAgICAgICAgICBtYXAucC5sb2FkKG1hcC5uLCBtYWtlUmVxdWlyZShyZWxOYW1lLCB0cnVlKSwgbWFrZUxvYWQoZGVwTmFtZSksIHt9KTsKICAgICAgICAgICAgICAgICAgICBhcmdzW2ldID0gZGVmaW5lZFtkZXBOYW1lXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG5hbWUgKyAnIG1pc3NpbmcgJyArIGRlcE5hbWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXQgPSBjYWxsYmFjayA/IGNhbGxiYWNrLmFwcGx5KGRlZmluZWRbbmFtZV0sIGFyZ3MpIDogdW5kZWZpbmVkOwoKICAgICAgICAgICAgaWYgKG5hbWUpIHsKICAgICAgICAgICAgICAgIC8vSWYgc2V0dGluZyBleHBvcnRzIHZpYSAibW9kdWxlIiBpcyBpbiBwbGF5LAogICAgICAgICAgICAgICAgLy9mYXZvciB0aGF0IG92ZXIgcmV0dXJuIHZhbHVlIGFuZCBleHBvcnRzLiBBZnRlciB0aGF0LAogICAgICAgICAgICAgICAgLy9mYXZvciBhIG5vbi11bmRlZmluZWQgcmV0dXJuIHZhbHVlIG92ZXIgZXhwb3J0cyB1c2UuCiAgICAgICAgICAgICAgICBpZiAoY2pzTW9kdWxlICYmIGNqc01vZHVsZS5leHBvcnRzICE9PSB1bmRlZiAmJgogICAgICAgICAgICAgICAgICAgICAgICBjanNNb2R1bGUuZXhwb3J0cyAhPT0gZGVmaW5lZFtuYW1lXSkgewogICAgICAgICAgICAgICAgICAgIGRlZmluZWRbbmFtZV0gPSBjanNNb2R1bGUuZXhwb3J0czsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmV0ICE9PSB1bmRlZiB8fCAhdXNpbmdFeHBvcnRzKSB7CiAgICAgICAgICAgICAgICAgICAgLy9Vc2UgdGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBmdW5jdGlvbi4KICAgICAgICAgICAgICAgICAgICBkZWZpbmVkW25hbWVdID0gcmV0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChuYW1lKSB7CiAgICAgICAgICAgIC8vTWF5IGp1c3QgYmUgYW4gb2JqZWN0IGRlZmluaXRpb24gZm9yIHRoZSBtb2R1bGUuIE9ubHkKICAgICAgICAgICAgLy93b3JyeSBhYm91dCBkZWZpbmluZyBpZiBoYXZlIGEgbW9kdWxlIG5hbWUuCiAgICAgICAgICAgIGRlZmluZWRbbmFtZV0gPSBjYWxsYmFjazsKICAgICAgICB9CiAgICB9OwoKICAgIHJlcXVpcmVqcyA9IHJlcXVpcmUgPSByZXEgPSBmdW5jdGlvbiAoZGVwcywgY2FsbGJhY2ssIHJlbE5hbWUsIGZvcmNlU3luYywgYWx0KSB7CiAgICAgICAgaWYgKHR5cGVvZiBkZXBzID09PSAic3RyaW5nIikgewogICAgICAgICAgICBpZiAoaGFuZGxlcnNbZGVwc10pIHsKICAgICAgICAgICAgICAgIC8vY2FsbGJhY2sgaW4gdGhpcyBjYXNlIGlzIHJlYWxseSByZWxOYW1lCiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlcnNbZGVwc10oY2FsbGJhY2spOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vSnVzdCByZXR1cm4gdGhlIG1vZHVsZSB3YW50ZWQuIEluIHRoaXMgc2NlbmFyaW8sIHRoZQogICAgICAgICAgICAvL2RlcHMgYXJnIGlzIHRoZSBtb2R1bGUgbmFtZSwgYW5kIHNlY29uZCBhcmcgKGlmIHBhc3NlZCkKICAgICAgICAgICAgLy9pcyBqdXN0IHRoZSByZWxOYW1lLgogICAgICAgICAgICAvL05vcm1hbGl6ZSBtb2R1bGUgbmFtZSwgaWYgaXQgY29udGFpbnMgLiBvciAuLgogICAgICAgICAgICByZXR1cm4gY2FsbERlcChtYWtlTWFwKGRlcHMsIGNhbGxiYWNrKS5mKTsKICAgICAgICB9IGVsc2UgaWYgKCFkZXBzLnNwbGljZSkgewogICAgICAgICAgICAvL2RlcHMgaXMgYSBjb25maWcgb2JqZWN0LCBub3QgYW4gYXJyYXkuCiAgICAgICAgICAgIGNvbmZpZyA9IGRlcHM7CiAgICAgICAgICAgIGlmIChjb25maWcuZGVwcykgewogICAgICAgICAgICAgICAgcmVxKGNvbmZpZy5kZXBzLCBjb25maWcuY2FsbGJhY2spOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghY2FsbGJhY2spIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNhbGxiYWNrLnNwbGljZSkgewogICAgICAgICAgICAgICAgLy9jYWxsYmFjayBpcyBhbiBhcnJheSwgd2hpY2ggbWVhbnMgaXQgaXMgYSBkZXBlbmRlbmN5IGxpc3QuCiAgICAgICAgICAgICAgICAvL0FkanVzdCBhcmdzIGlmIHRoZXJlIGFyZSBkZXBlbmRlbmNpZXMKICAgICAgICAgICAgICAgIGRlcHMgPSBjYWxsYmFjazsKICAgICAgICAgICAgICAgIGNhbGxiYWNrID0gcmVsTmFtZTsKICAgICAgICAgICAgICAgIHJlbE5hbWUgPSBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZGVwcyA9IHVuZGVmOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvL1N1cHBvcnQgcmVxdWlyZShbJ2EnXSkKICAgICAgICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IGZ1bmN0aW9uICgpIHt9OwoKICAgICAgICAvL0lmIHJlbE5hbWUgaXMgYSBmdW5jdGlvbiwgaXQgaXMgYW4gZXJyYmFjayBoYW5kbGVyLAogICAgICAgIC8vc28gcmVtb3ZlIGl0LgogICAgICAgIGlmICh0eXBlb2YgcmVsTmFtZSA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICByZWxOYW1lID0gZm9yY2VTeW5jOwogICAgICAgICAgICBmb3JjZVN5bmMgPSBhbHQ7CiAgICAgICAgfQoKICAgICAgICAvL1NpbXVsYXRlIGFzeW5jIGNhbGxiYWNrOwogICAgICAgIGlmIChmb3JjZVN5bmMpIHsKICAgICAgICAgICAgbWFpbih1bmRlZiwgZGVwcywgY2FsbGJhY2ssIHJlbE5hbWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vVXNpbmcgYSBub24temVybyB2YWx1ZSBiZWNhdXNlIG9mIGNvbmNlcm4gZm9yIHdoYXQgb2xkIGJyb3dzZXJzCiAgICAgICAgICAgIC8vZG8sIGFuZCBsYXRlc3QgYnJvd3NlcnMgInVwZ3JhZGUiIHRvIDQgaWYgbG93ZXIgdmFsdWUgaXMgdXNlZDoKICAgICAgICAgICAgLy9odHRwOi8vd3d3LndoYXR3Zy5vcmcvc3BlY3Mvd2ViLWFwcHMvY3VycmVudC13b3JrL211bHRpcGFnZS90aW1lcnMuaHRtbCNkb20td2luZG93dGltZXJzLXNldHRpbWVvdXQ6CiAgICAgICAgICAgIC8vSWYgd2FudCBhIHZhbHVlIGltbWVkaWF0ZWx5LCB1c2UgcmVxdWlyZSgnaWQnKSBpbnN0ZWFkIC0tIHNvbWV0aGluZwogICAgICAgICAgICAvL3RoYXQgd29ya3MgaW4gYWxtb25kIG9uIHRoZSBnbG9iYWwgbGV2ZWwsIGJ1dCBub3QgZ3VhcmFudGVlZCBhbmQKICAgICAgICAgICAgLy91bmxpa2VseSB0byB3b3JrIGluIG90aGVyIEFNRCBpbXBsZW1lbnRhdGlvbnMuCiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgbWFpbih1bmRlZiwgZGVwcywgY2FsbGJhY2ssIHJlbE5hbWUpOwogICAgICAgICAgICB9LCA0KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXE7CiAgICB9OwoKICAgIC8qKgogICAgICogSnVzdCBkcm9wcyB0aGUgY29uZmlnIG9uIHRoZSBmbG9vciwgYnV0IHJldHVybnMgcmVxIGluIGNhc2UKICAgICAqIHRoZSBjb25maWcgcmV0dXJuIHZhbHVlIGlzIHVzZWQuCiAgICAgKi8KICAgIHJlcS5jb25maWcgPSBmdW5jdGlvbiAoY2ZnKSB7CiAgICAgICAgcmV0dXJuIHJlcShjZmcpOwogICAgfTsKCiAgICAvKioKICAgICAqIEV4cG9zZSBtb2R1bGUgcmVnaXN0cnkgZm9yIGRlYnVnZ2luZyBhbmQgdG9vbGluZwogICAgICovCiAgICByZXF1aXJlanMuX2RlZmluZWQgPSBkZWZpbmVkOwoKICAgIGRlZmluZSA9IGZ1bmN0aW9uIChuYW1lLCBkZXBzLCBjYWxsYmFjaykgewoKICAgICAgICAvL1RoaXMgbW9kdWxlIG1heSBub3QgaGF2ZSBkZXBlbmRlbmNpZXMKICAgICAgICBpZiAoIWRlcHMuc3BsaWNlKSB7CiAgICAgICAgICAgIC8vZGVwcyBpcyBub3QgYW4gYXJyYXksIHNvIHByb2JhYmx5IG1lYW5zCiAgICAgICAgICAgIC8vYW4gb2JqZWN0IGxpdGVyYWwgb3IgZmFjdG9yeSBmdW5jdGlvbiBmb3IKICAgICAgICAgICAgLy90aGUgdmFsdWUuIEFkanVzdCBhcmdzLgogICAgICAgICAgICBjYWxsYmFjayA9IGRlcHM7CiAgICAgICAgICAgIGRlcHMgPSBbXTsKICAgICAgICB9CgogICAgICAgIGlmICghaGFzUHJvcChkZWZpbmVkLCBuYW1lKSAmJiAhaGFzUHJvcCh3YWl0aW5nLCBuYW1lKSkgewogICAgICAgICAgICB3YWl0aW5nW25hbWVdID0gW25hbWUsIGRlcHMsIGNhbGxiYWNrXTsKICAgICAgICB9CiAgICB9OwoKICAgIGRlZmluZS5hbWQgPSB7CiAgICAgICAgalF1ZXJ5OiB0cnVlCiAgICB9Owp9KCkpOwoKZGVmaW5lKCJub2RlX21vZHVsZXMvYWxtb25kL2FsbW9uZCIsIGZ1bmN0aW9uKCl7fSk7CgovKioKICogVXRpbGl0eSBmdW5jdGlvbnMgZm9yIHdlYiBhcHBsaWNhdGlvbnMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKLyogVXRpbGl0aWVzIEFQSSAqLwp2YXIgdXRpbCA9IGZvcmdlLnV0aWwgPSBmb3JnZS51dGlsIHx8IHt9OwoKLy8gZGVmaW5lIHNldEltbWVkaWF0ZSBhbmQgbmV4dFRpY2sKKGZ1bmN0aW9uKCkgewogIC8vIHVzZSBuYXRpdmUgbmV4dFRpY2sKICBpZih0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvY2Vzcy5uZXh0VGljaykgewogICAgdXRpbC5uZXh0VGljayA9IHByb2Nlc3MubmV4dFRpY2s7CiAgICBpZih0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSAnZnVuY3Rpb24nKSB7CiAgICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gc2V0SW1tZWRpYXRlOwogICAgfSBlbHNlIHsKICAgICAgLy8gcG9seWZpbGwgc2V0SW1tZWRpYXRlIHdpdGggbmV4dFRpY2ssIG9sZGVyIHZlcnNpb25zIG9mIG5vZGUKICAgICAgLy8gKHRob3NlIHcvbyBzZXRJbW1lZGlhdGUpIHdvbid0IHRvdGFsbHkgc3RhcnZlIElPCiAgICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gdXRpbC5uZXh0VGljazsKICAgIH0KICAgIHJldHVybjsKICB9CgogIC8vIHBvbHlmaWxsIG5leHRUaWNrIHdpdGggbmF0aXZlIHNldEltbWVkaWF0ZQogIGlmKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicpIHsKICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gc2V0SW1tZWRpYXRlOwogICAgdXRpbC5uZXh0VGljayA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7CiAgICAgIHJldHVybiBzZXRJbW1lZGlhdGUoY2FsbGJhY2spOwogICAgfTsKICAgIHJldHVybjsKICB9CgogIC8qIE5vdGU6IEEgcG9seWZpbGwgdXBncmFkZSBwYXR0ZXJuIGlzIHVzZWQgaGVyZSB0byBhbGxvdyBjb21iaW5pbmcKICBwb2x5ZmlsbHMuIEZvciBleGFtcGxlLCBNdXRhdGlvbk9ic2VydmVyIGlzIGZhc3QsIGJ1dCBibG9ja3MgVUkgdXBkYXRlcywKICBzbyBpdCBuZWVkcyB0byBhbGxvdyBVSSB1cGRhdGVzIHBlcmlvZGljYWxseSwgc28gaXQgZmFsbHMgYmFjayBvbgogIHBvc3RNZXNzYWdlIG9yIHNldFRpbWVvdXQuICovCgogIC8vIHBvbHlmaWxsIHdpdGggc2V0VGltZW91dAogIHV0aWwuc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgIHNldFRpbWVvdXQoY2FsbGJhY2ssIDApOwogIH07CgogIC8vIHVwZ3JhZGUgcG9seWZpbGwgdG8gdXNlIHBvc3RNZXNzYWdlCiAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYKICAgIHR5cGVvZiB3aW5kb3cucG9zdE1lc3NhZ2UgPT09ICdmdW5jdGlvbicpIHsKICAgIHZhciBtc2cgPSAnZm9yZ2Uuc2V0SW1tZWRpYXRlJzsKICAgIHZhciBjYWxsYmFja3MgPSBbXTsKICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgICAgY2FsbGJhY2tzLnB1c2goY2FsbGJhY2spOwogICAgICAvLyBvbmx5IHNlbmQgbWVzc2FnZSB3aGVuIG9uZSBoYXNuJ3QgYmVlbiBzZW50IGluCiAgICAgIC8vIHRoZSBjdXJyZW50IHR1cm4gb2YgdGhlIGV2ZW50IGxvb3AKICAgICAgaWYoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMSkgewogICAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZShtc2csICcqJyk7CiAgICAgIH0KICAgIH07CiAgICBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50KSB7CiAgICAgIGlmKGV2ZW50LnNvdXJjZSA9PT0gd2luZG93ICYmIGV2ZW50LmRhdGEgPT09IG1zZykgewogICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgICAgIHZhciBjb3B5ID0gY2FsbGJhY2tzLnNsaWNlKCk7CiAgICAgICAgY2FsbGJhY2tzLmxlbmd0aCA9IDA7CiAgICAgICAgY29weS5mb3JFYWNoKGZ1bmN0aW9uKGNhbGxiYWNrKSB7CiAgICAgICAgICBjYWxsYmFjaygpOwogICAgICAgIH0pOwogICAgICB9CiAgICB9CiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGhhbmRsZXIsIHRydWUpOwogIH0KCiAgLy8gdXBncmFkZSBwb2x5ZmlsbCB0byB1c2UgTXV0YXRpb25PYnNlcnZlcgogIGlmKHR5cGVvZiBNdXRhdGlvbk9ic2VydmVyICE9PSAndW5kZWZpbmVkJykgewogICAgLy8gcG9seWZpbGwgd2l0aCBNdXRhdGlvbk9ic2VydmVyCiAgICB2YXIgbm93ID0gRGF0ZS5ub3coKTsKICAgIHZhciBhdHRyID0gdHJ1ZTsKICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICAgIHZhciBjYWxsYmFja3MgPSBbXTsKICAgIG5ldyBNdXRhdGlvbk9ic2VydmVyKGZ1bmN0aW9uKCkgewogICAgICB2YXIgY29weSA9IGNhbGxiYWNrcy5zbGljZSgpOwogICAgICBjYWxsYmFja3MubGVuZ3RoID0gMDsKICAgICAgY29weS5mb3JFYWNoKGZ1bmN0aW9uKGNhbGxiYWNrKSB7CiAgICAgICAgY2FsbGJhY2soKTsKICAgICAgfSk7CiAgICB9KS5vYnNlcnZlKGRpdiwge2F0dHJpYnV0ZXM6IHRydWV9KTsKICAgIHZhciBvbGRTZXRJbW1lZGlhdGUgPSB1dGlsLnNldEltbWVkaWF0ZTsKICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgICAgaWYoRGF0ZS5ub3coKSAtIG5vdyA+IDE1KSB7CiAgICAgICAgbm93ID0gRGF0ZS5ub3coKTsKICAgICAgICBvbGRTZXRJbW1lZGlhdGUoY2FsbGJhY2spOwogICAgICB9IGVsc2UgewogICAgICAgIGNhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTsKICAgICAgICAvLyBvbmx5IHRyaWdnZXIgb2JzZXJ2ZXIgd2hlbiBpdCBoYXNuJ3QgYmVlbiB0cmlnZ2VyZWQgaW4KICAgICAgICAvLyB0aGUgY3VycmVudCB0dXJuIG9mIHRoZSBldmVudCBsb29wCiAgICAgICAgaWYoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMSkgewogICAgICAgICAgZGl2LnNldEF0dHJpYnV0ZSgnYScsIGF0dHIgPSAhYXR0cik7CiAgICAgICAgfQogICAgICB9CiAgICB9OwogIH0KCiAgdXRpbC5uZXh0VGljayA9IHV0aWwuc2V0SW1tZWRpYXRlOwp9KSgpOwoKLy8gZGVmaW5lIGlzQXJyYXkKdXRpbC5pc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbih4KSB7CiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh4KSA9PT0gJ1tvYmplY3QgQXJyYXldJzsKfTsKCi8vIGRlZmluZSBpc0FycmF5QnVmZmVyCnV0aWwuaXNBcnJheUJ1ZmZlciA9IGZ1bmN0aW9uKHgpIHsKICByZXR1cm4gdHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB4IGluc3RhbmNlb2YgQXJyYXlCdWZmZXI7Cn07CgovLyBkZWZpbmUgaXNBcnJheUJ1ZmZlclZpZXcKdXRpbC5pc0FycmF5QnVmZmVyVmlldyA9IGZ1bmN0aW9uKHgpIHsKICByZXR1cm4geCAmJiB1dGlsLmlzQXJyYXlCdWZmZXIoeC5idWZmZXIpICYmIHguYnl0ZUxlbmd0aCAhPT0gdW5kZWZpbmVkOwp9OwoKLy8gVE9ETzogc2V0IEJ5dGVCdWZmZXIgdG8gYmVzdCBhdmFpbGFibGUgYmFja2luZwp1dGlsLkJ5dGVCdWZmZXIgPSBCeXRlU3RyaW5nQnVmZmVyOwoKLyoqIEJ1ZmZlciB3L0JpbmFyeVN0cmluZyBiYWNraW5nICovCgovKioKICogQ29uc3RydWN0b3IgZm9yIGEgYmluYXJ5IHN0cmluZyBiYWNrZWQgYnl0ZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBbYl0gdGhlIGJ5dGVzIHRvIHdyYXAgKGVpdGhlciBlbmNvZGVkIGFzIHN0cmluZywgb25lIGJ5dGUgcGVyCiAqICAgICAgICAgIGNoYXJhY3Rlciwgb3IgYXMgYW4gQXJyYXlCdWZmZXIgb3IgVHlwZWQgQXJyYXkpLgogKi8KZnVuY3Rpb24gQnl0ZVN0cmluZ0J1ZmZlcihiKSB7CiAgLy8gVE9ETzogdXBkYXRlIHRvIG1hdGNoIERhdGFCdWZmZXIgQVBJCgogIC8vIHRoZSBkYXRhIGluIHRoaXMgYnVmZmVyCiAgdGhpcy5kYXRhID0gJyc7CiAgLy8gdGhlIHBvaW50ZXIgZm9yIHJlYWRpbmcgZnJvbSB0aGlzIGJ1ZmZlcgogIHRoaXMucmVhZCA9IDA7CgogIGlmKHR5cGVvZiBiID09PSAnc3RyaW5nJykgewogICAgdGhpcy5kYXRhID0gYjsKICB9IGVsc2UgaWYodXRpbC5pc0FycmF5QnVmZmVyKGIpIHx8IHV0aWwuaXNBcnJheUJ1ZmZlclZpZXcoYikpIHsKICAgIC8vIGNvbnZlcnQgbmF0aXZlIGJ1ZmZlciB0byBmb3JnZSBidWZmZXIKICAgIC8vIEZJWE1FOiBzdXBwb3J0IG5hdGl2ZSBidWZmZXJzIGludGVybmFsbHkgaW5zdGVhZAogICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KGIpOwogICAgdHJ5IHsKICAgICAgdGhpcy5kYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBhcnIpOwogICAgfSBjYXRjaChlKSB7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyArK2kpIHsKICAgICAgICB0aGlzLnB1dEJ5dGUoYXJyW2ldKTsKICAgICAgfQogICAgfQogIH0gZWxzZSBpZihiIGluc3RhbmNlb2YgQnl0ZVN0cmluZ0J1ZmZlciB8fAogICAgKHR5cGVvZiBiID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgYi5kYXRhID09PSAnc3RyaW5nJyAmJgogICAgdHlwZW9mIGIucmVhZCA9PT0gJ251bWJlcicpKSB7CiAgICAvLyBjb3B5IGV4aXN0aW5nIGJ1ZmZlcgogICAgdGhpcy5kYXRhID0gYi5kYXRhOwogICAgdGhpcy5yZWFkID0gYi5yZWFkOwogIH0KCiAgLy8gdXNlZCBmb3Igdjggb3B0aW1pemF0aW9uCiAgdGhpcy5fY29uc3RydWN0ZWRTdHJpbmdMZW5ndGggPSAwOwp9CnV0aWwuQnl0ZVN0cmluZ0J1ZmZlciA9IEJ5dGVTdHJpbmdCdWZmZXI7CgovKiBOb3RlOiBUaGlzIGlzIGFuIG9wdGltaXphdGlvbiBmb3IgVjgtYmFzZWQgYnJvd3NlcnMuIFdoZW4gVjggY29uY2F0ZW5hdGVzCiAgYSBzdHJpbmcsIHRoZSBzdHJpbmdzIGFyZSBvbmx5IGpvaW5lZCBsb2dpY2FsbHkgdXNpbmcgYSAiY29ucyBzdHJpbmciIG9yCiAgImNvbnN0cnVjdGVkL2NvbmNhdGVuYXRlZCBzdHJpbmciLiBUaGVzZSBjb250YWluZXJzIGtlZXAgcmVmZXJlbmNlcyB0byBvbmUKICBhbm90aGVyIGFuZCBjYW4gcmVzdWx0IGluIHZlcnkgbGFyZ2UgbWVtb3J5IHVzYWdlLiBGb3IgZXhhbXBsZSwgaWYgYSAyTUIKICBzdHJpbmcgaXMgY29uc3RydWN0ZWQgYnkgY29uY2F0ZW5hdGluZyA0IGJ5dGVzIHRvZ2V0aGVyIGF0IGEgdGltZSwgdGhlCiAgbWVtb3J5IHVzYWdlIHdpbGwgYmUgfjQ0TUI7IHNvIH4yMnggaW5jcmVhc2UuIFRoZSBzdHJpbmdzIGFyZSBvbmx5IGpvaW5lZAogIHRvZ2V0aGVyIHdoZW4gYW4gb3BlcmF0aW9uIHJlcXVpcmluZyB0aGVpciBqb2luaW5nIHRha2VzIHBsYWNlLCBzdWNoIGFzCiAgc3Vic3RyKCkuIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW4gYWRkaW5nIGRhdGEgdG8gdGhpcyBidWZmZXIgdG8gZW5zdXJlCiAgdGhlc2UgdHlwZXMgb2Ygc3RyaW5ncyBhcmUgcGVyaW9kaWNhbGx5IGpvaW5lZCB0byByZWR1Y2UgdGhlIG1lbW9yeQogIGZvb3RwcmludC4gKi8KdmFyIF9NQVhfQ09OU1RSVUNURURfU1RSSU5HX0xFTkdUSCA9IDQwOTY7CnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUuX29wdGltaXplQ29uc3RydWN0ZWRTdHJpbmcgPSBmdW5jdGlvbih4KSB7CiAgdGhpcy5fY29uc3RydWN0ZWRTdHJpbmdMZW5ndGggKz0geDsKICBpZih0aGlzLl9jb25zdHJ1Y3RlZFN0cmluZ0xlbmd0aCA+IF9NQVhfQ09OU1RSVUNURURfU1RSSU5HX0xFTkdUSCkgewogICAgLy8gdGhpcyBzdWJzdHIoKSBzaG91bGQgY2F1c2UgdGhlIGNvbnN0cnVjdGVkIHN0cmluZyB0byBqb2luCiAgICB0aGlzLmRhdGEuc3Vic3RyKDAsIDEpOwogICAgdGhpcy5fY29uc3RydWN0ZWRTdHJpbmdMZW5ndGggPSAwOwogIH0KfTsKCi8qKgogKiBHZXRzIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUubGVuZ3RoID0gZnVuY3Rpb24oKSB7CiAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGggLSB0aGlzLnJlYWQ7Cn07CgovKioKICogR2V0cyB3aGV0aGVyIG9yIG5vdCB0aGlzIGJ1ZmZlciBpcyBlbXB0eS4KICoKICogQHJldHVybiB0cnVlIGlmIHRoaXMgYnVmZmVyIGlzIGVtcHR5LCBmYWxzZSBpZiBub3QuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmlzRW1wdHkgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gdGhpcy5sZW5ndGgoKSA8PSAwOwp9OwoKLyoqCiAqIFB1dHMgYSBieXRlIGluIHRoaXMgYnVmZmVyLgogKgogKiBAcGFyYW0gYiB0aGUgYnl0ZSB0byBwdXQuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dEJ5dGUgPSBmdW5jdGlvbihiKSB7CiAgcmV0dXJuIHRoaXMucHV0Qnl0ZXMoU3RyaW5nLmZyb21DaGFyQ29kZShiKSk7Cn07CgovKioKICogUHV0cyBhIGJ5dGUgaW4gdGhpcyBidWZmZXIgTiB0aW1lcy4KICoKICogQHBhcmFtIGIgdGhlIGJ5dGUgdG8gcHV0LgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIG9mIHZhbHVlIGIgdG8gcHV0LgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5maWxsV2l0aEJ5dGUgPSBmdW5jdGlvbihiLCBuKSB7CiAgYiA9IFN0cmluZy5mcm9tQ2hhckNvZGUoYik7CiAgdmFyIGQgPSB0aGlzLmRhdGE7CiAgd2hpbGUobiA+IDApIHsKICAgIGlmKG4gJiAxKSB7CiAgICAgIGQgKz0gYjsKICAgIH0KICAgIG4gPj4+PSAxOwogICAgaWYobiA+IDApIHsKICAgICAgYiArPSBiOwogICAgfQogIH0KICB0aGlzLmRhdGEgPSBkOwogIHRoaXMuX29wdGltaXplQ29uc3RydWN0ZWRTdHJpbmcobik7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBieXRlcyBpbiB0aGlzIGJ1ZmZlci4KICoKICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyAoYXMgYSBVVEYtOCBlbmNvZGVkIHN0cmluZykgdG8gcHV0LgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5wdXRCeXRlcyA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgdGhpcy5kYXRhICs9IGJ5dGVzOwogIHRoaXMuX29wdGltaXplQ29uc3RydWN0ZWRTdHJpbmcoYnl0ZXMubGVuZ3RoKTsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBQdXRzIGEgVVRGLTE2IGVuY29kZWQgc3RyaW5nIGludG8gdGhpcyBidWZmZXIuCiAqCiAqIEBwYXJhbSBzdHIgdGhlIHN0cmluZyB0byBwdXQuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dFN0cmluZyA9IGZ1bmN0aW9uKHN0cikgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKHV0aWwuZW5jb2RlVXRmOChzdHIpKTsKfTsKCi8qKgogKiBQdXRzIGEgMTYtYml0IGludGVnZXIgaW4gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlci4KICoKICogQHBhcmFtIGkgdGhlIDE2LWJpdCBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5wdXRJbnQxNiA9IGZ1bmN0aW9uKGkpIHsKICByZXR1cm4gdGhpcy5wdXRCeXRlcygKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiA4ICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpICYgMHhGRikpOwp9OwoKLyoqCiAqIFB1dHMgYSAyNC1iaXQgaW50ZWdlciBpbiB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyLgogKgogKiBAcGFyYW0gaSB0aGUgMjQtYml0IGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dEludDI0ID0gZnVuY3Rpb24oaSkgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKAogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpID4+IDE2ICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpID4+IDggJiAweEZGKSArCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgJiAweEZGKSk7Cn07CgovKioKICogUHV0cyBhIDMyLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAzMi1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUucHV0SW50MzIgPSBmdW5jdGlvbihpKSB7CiAgcmV0dXJuIHRoaXMucHV0Qnl0ZXMoCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgPj4gMjQgJiAweEZGKSArCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgPj4gMTYgJiAweEZGKSArCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgPj4gOCAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSAmIDB4RkYpKTsKfTsKCi8qKgogKiBQdXRzIGEgMTYtYml0IGludGVnZXIgaW4gdGhpcyBidWZmZXIgaW4gbGl0dGxlLWVuZGlhbiBvcmRlci4KICoKICogQHBhcmFtIGkgdGhlIDE2LWJpdCBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5wdXRJbnQxNkxlID0gZnVuY3Rpb24oaSkgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKAogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpID4+IDggJiAweEZGKSk7Cn07CgovKioKICogUHV0cyBhIDI0LWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAyNC1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUucHV0SW50MjRMZSA9IGZ1bmN0aW9uKGkpIHsKICByZXR1cm4gdGhpcy5wdXRCeXRlcygKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiA4ICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpID4+IDE2ICYgMHhGRikpOwp9OwoKLyoqCiAqIFB1dHMgYSAzMi1iaXQgaW50ZWdlciBpbiB0aGlzIGJ1ZmZlciBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyLgogKgogKiBAcGFyYW0gaSB0aGUgMzItYml0IGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dEludDMyTGUgPSBmdW5jdGlvbihpKSB7CiAgcmV0dXJuIHRoaXMucHV0Qnl0ZXMoCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgJiAweEZGKSArCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgPj4gOCAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiAxNiAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiAyNCAmIDB4RkYpKTsKfTsKCi8qKgogKiBQdXRzIGFuIG4tYml0IGludGVnZXIgaW4gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlci4KICoKICogQHBhcmFtIGkgdGhlIG4tYml0IGludGVnZXIuCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUucHV0SW50ID0gZnVuY3Rpb24oaSwgbikgewogIHZhciBieXRlcyA9ICcnOwogIGRvIHsKICAgIG4gLT0gODsKICAgIGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGkgPj4gbikgJiAweEZGKTsKICB9IHdoaWxlKG4gPiAwKTsKICByZXR1cm4gdGhpcy5wdXRCeXRlcyhieXRlcyk7Cn07CgovKioKICogUHV0cyBhIHNpZ25lZCBuLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuIFR3bydzCiAqIGNvbXBsZW1lbnQgcmVwcmVzZW50YXRpb24gaXMgdXNlZC4KICoKICogQHBhcmFtIGkgdGhlIG4tYml0IGludGVnZXIuCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUucHV0U2lnbmVkSW50ID0gZnVuY3Rpb24oaSwgbikgewogIGlmKGkgPCAwKSB7CiAgICBpICs9IDIgPDwgKG4gLSAxKTsKICB9CiAgcmV0dXJuIHRoaXMucHV0SW50KGksIG4pOwp9OwoKLyoqCiAqIFB1dHMgdGhlIGdpdmVuIGJ1ZmZlciBpbnRvIHRoaXMgYnVmZmVyLgogKgogKiBAcGFyYW0gYnVmZmVyIHRoZSBidWZmZXIgdG8gcHV0IGludG8gdGhpcyBvbmUuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dEJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKGJ1ZmZlci5nZXRCeXRlcygpKTsKfTsKCi8qKgogKiBHZXRzIGEgYnl0ZSBmcm9tIHRoaXMgYnVmZmVyIGFuZCBhZHZhbmNlcyB0aGUgcmVhZCBwb2ludGVyIGJ5IDEuCiAqCiAqIEByZXR1cm4gdGhlIGJ5dGUuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldEJ5dGUgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkKyspOwp9OwoKLyoqCiAqIEdldHMgYSB1aW50MTYgZnJvbSB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyIGFuZCBhZHZhbmNlcyB0aGUgcmVhZAogKiBwb2ludGVyIGJ5IDIuCiAqCiAqIEByZXR1cm4gdGhlIHVpbnQxNi4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUuZ2V0SW50MTYgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9ICgKICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCkgPDwgOCBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAxKSk7CiAgdGhpcy5yZWFkICs9IDI7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQyNCBmcm9tIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMy4KICoKICogQHJldHVybiB0aGUgdWludDI0LgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQyNCA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gKAogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkKSA8PCAxNiBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAxKSA8PCA4IF4KICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCArIDIpKTsKICB0aGlzLnJlYWQgKz0gMzsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGEgdWludDMyIGZyb20gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlciBhbmQgYWR2YW5jZXMgdGhlIHJlYWQKICogcG9pbnRlciBieSA0LgogKgogKiBAcmV0dXJuIHRoZSB3b3JkLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQzMiA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gKAogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkKSA8PCAyNCBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAxKSA8PCAxNiBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAyKSA8PCA4IF4KICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCArIDMpKTsKICB0aGlzLnJlYWQgKz0gNDsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGEgdWludDE2IGZyb20gdGhpcyBidWZmZXIgaW4gbGl0dGxlLWVuZGlhbiBvcmRlciBhbmQgYWR2YW5jZXMgdGhlIHJlYWQKICogcG9pbnRlciBieSAyLgogKgogKiBAcmV0dXJuIHRoZSB1aW50MTYuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldEludDE2TGUgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9ICgKICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCkgXgogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkICsgMSkgPDwgOCk7CiAgdGhpcy5yZWFkICs9IDI7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQyNCBmcm9tIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMy4KICoKICogQHJldHVybiB0aGUgdWludDI0LgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQyNExlID0gZnVuY3Rpb24oKSB7CiAgdmFyIHJ2YWwgPSAoCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQpIF4KICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCArIDEpIDw8IDggXgogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkICsgMikgPDwgMTYpOwogIHRoaXMucmVhZCArPSAzOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEdldHMgYSB1aW50MzIgZnJvbSB0aGlzIGJ1ZmZlciBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyIGFuZCBhZHZhbmNlcyB0aGUgcmVhZAogKiBwb2ludGVyIGJ5IDQuCiAqCiAqIEByZXR1cm4gdGhlIHdvcmQuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldEludDMyTGUgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9ICgKICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCkgXgogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkICsgMSkgPDwgOCBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAyKSA8PCAxNiBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAzKSA8PCAyNCk7CiAgdGhpcy5yZWFkICs9IDQ7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhbiBuLWJpdCBpbnRlZ2VyIGZyb20gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlciBhbmQgYWR2YW5jZXMgdGhlCiAqIHJlYWQgcG9pbnRlciBieSBuLzguCiAqCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGUgaW50ZWdlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUuZ2V0SW50ID0gZnVuY3Rpb24obikgewogIHZhciBydmFsID0gMDsKICBkbyB7CiAgICBydmFsID0gKHJ2YWwgPDwgOCkgKyB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQrKyk7CiAgICBuIC09IDg7CiAgfSB3aGlsZShuID4gMCk7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHNpZ25lZCBuLWJpdCBpbnRlZ2VyIGZyb20gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlciwgdXNpbmcKICogdHdvJ3MgY29tcGxlbWVudCwgYW5kIGFkdmFuY2VzIHRoZSByZWFkIHBvaW50ZXIgYnkgbi84LgogKgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhlIGludGVnZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldFNpZ25lZEludCA9IGZ1bmN0aW9uKG4pIHsKICB2YXIgeCA9IHRoaXMuZ2V0SW50KG4pOwogIHZhciBtYXggPSAyIDw8IChuIC0gMik7CiAgaWYoeCA+PSBtYXgpIHsKICAgIHggLT0gbWF4IDw8IDE7CiAgfQogIHJldHVybiB4Owp9OwoKLyoqCiAqIFJlYWRzIGJ5dGVzIG91dCBpbnRvIGEgVVRGLTggc3RyaW5nIGFuZCBjbGVhcnMgdGhlbSBmcm9tIHRoZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQsIHVuZGVmaW5lZCBvciBudWxsIGZvciBhbGwuCiAqCiAqIEByZXR1cm4gYSBVVEYtOCBzdHJpbmcgb2YgYnl0ZXMuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldEJ5dGVzID0gZnVuY3Rpb24oY291bnQpIHsKICB2YXIgcnZhbDsKICBpZihjb3VudCkgewogICAgLy8gcmVhZCBjb3VudCBieXRlcwogICAgY291bnQgPSBNYXRoLm1pbih0aGlzLmxlbmd0aCgpLCBjb3VudCk7CiAgICBydmFsID0gdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCwgdGhpcy5yZWFkICsgY291bnQpOwogICAgdGhpcy5yZWFkICs9IGNvdW50OwogIH0gZWxzZSBpZihjb3VudCA9PT0gMCkgewogICAgcnZhbCA9ICcnOwogIH0gZWxzZSB7CiAgICAvLyByZWFkIGFsbCBieXRlcywgb3B0aW1pemUgdG8gb25seSBjb3B5IHdoZW4gbmVlZGVkCiAgICBydmFsID0gKHRoaXMucmVhZCA9PT0gMCkgPyB0aGlzLmRhdGEgOiB0aGlzLmRhdGEuc2xpY2UodGhpcy5yZWFkKTsKICAgIHRoaXMuY2xlYXIoKTsKICB9CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIFVURi04IGVuY29kZWQgc3RyaW5nIG9mIHRoZSBieXRlcyBmcm9tIHRoaXMgYnVmZmVyIHdpdGhvdXQgbW9kaWZ5aW5nCiAqIHRoZSByZWFkIHBvaW50ZXIuCiAqCiAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGdldCwgb21pdCB0byBnZXQgYWxsLgogKgogKiBAcmV0dXJuIGEgc3RyaW5nIGZ1bGwgb2YgVVRGLTggZW5jb2RlZCBjaGFyYWN0ZXJzLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5ieXRlcyA9IGZ1bmN0aW9uKGNvdW50KSB7CiAgcmV0dXJuICh0eXBlb2YoY291bnQpID09PSAndW5kZWZpbmVkJyA/CiAgICB0aGlzLmRhdGEuc2xpY2UodGhpcy5yZWFkKSA6CiAgICB0aGlzLmRhdGEuc2xpY2UodGhpcy5yZWFkLCB0aGlzLnJlYWQgKyBjb3VudCkpOwp9OwoKLyoqCiAqIEdldHMgYSBieXRlIGF0IHRoZSBnaXZlbiBpbmRleCB3aXRob3V0IG1vZGlmeWluZyB0aGUgcmVhZCBwb2ludGVyLgogKgogKiBAcGFyYW0gaSB0aGUgYnl0ZSBpbmRleC4KICoKICogQHJldHVybiB0aGUgYnl0ZS4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUuYXQgPSBmdW5jdGlvbihpKSB7CiAgcmV0dXJuIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCArIGkpOwp9OwoKLyoqCiAqIFB1dHMgYSBieXRlIGF0IHRoZSBnaXZlbiBpbmRleCB3aXRob3V0IG1vZGlmeWluZyB0aGUgcmVhZCBwb2ludGVyLgogKgogKiBAcGFyYW0gaSB0aGUgYnl0ZSBpbmRleC4KICogQHBhcmFtIGIgdGhlIGJ5dGUgdG8gcHV0LgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5zZXRBdCA9IGZ1bmN0aW9uKGksIGIpIHsKICB0aGlzLmRhdGEgPSB0aGlzLmRhdGEuc3Vic3RyKDAsIHRoaXMucmVhZCArIGkpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoYikgKwogICAgdGhpcy5kYXRhLnN1YnN0cih0aGlzLnJlYWQgKyBpICsgMSk7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogR2V0cyB0aGUgbGFzdCBieXRlIHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSByZWFkIHBvaW50ZXIuCiAqCiAqIEByZXR1cm4gdGhlIGxhc3QgYnl0ZS4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUubGFzdCA9IGZ1bmN0aW9uKCkgewogIHJldHVybiB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLmRhdGEubGVuZ3RoIC0gMSk7Cn07CgovKioKICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIGNvcHkuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbigpIHsKICB2YXIgYyA9IHV0aWwuY3JlYXRlQnVmZmVyKHRoaXMuZGF0YSk7CiAgYy5yZWFkID0gdGhpcy5yZWFkOwogIHJldHVybiBjOwp9OwoKLyoqCiAqIENvbXBhY3RzIHRoaXMgYnVmZmVyLgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5jb21wYWN0ID0gZnVuY3Rpb24oKSB7CiAgaWYodGhpcy5yZWFkID4gMCkgewogICAgdGhpcy5kYXRhID0gdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCk7CiAgICB0aGlzLnJlYWQgPSAwOwogIH0KICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBDbGVhcnMgdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5kYXRhID0gJyc7CiAgdGhpcy5yZWFkID0gMDsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBTaG9ydGVucyB0aGlzIGJ1ZmZlciBieSB0cmltaW5nIGJ5dGVzIG9mZiBvZiB0aGUgZW5kIG9mIHRoaXMgYnVmZmVyLgogKgogKiBAcGFyYW0gY291bnQgdGhlIG51bWJlciBvZiBieXRlcyB0byB0cmltIG9mZi4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUudHJ1bmNhdGUgPSBmdW5jdGlvbihjb3VudCkgewogIHZhciBsZW4gPSBNYXRoLm1heCgwLCB0aGlzLmxlbmd0aCgpIC0gY291bnQpOwogIHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5zdWJzdHIodGhpcy5yZWFkLCBsZW4pOwogIHRoaXMucmVhZCA9IDA7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogQ29udmVydHMgdGhpcyBidWZmZXIgdG8gYSBoZXhhZGVjaW1hbCBzdHJpbmcuCiAqCiAqIEByZXR1cm4gYSBoZXhhZGVjaW1hbCBzdHJpbmcuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnRvSGV4ID0gZnVuY3Rpb24oKSB7CiAgdmFyIHJ2YWwgPSAnJzsKICBmb3IodmFyIGkgPSB0aGlzLnJlYWQ7IGkgPCB0aGlzLmRhdGEubGVuZ3RoOyArK2kpIHsKICAgIHZhciBiID0gdGhpcy5kYXRhLmNoYXJDb2RlQXQoaSk7CiAgICBpZihiIDwgMTYpIHsKICAgICAgcnZhbCArPSAnMCc7CiAgICB9CiAgICBydmFsICs9IGIudG9TdHJpbmcoMTYpOwogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDb252ZXJ0cyB0aGlzIGJ1ZmZlciB0byBhIFVURi0xNiBzdHJpbmcgKHN0YW5kYXJkIEphdmFTY3JpcHQgc3RyaW5nKS4KICoKICogQHJldHVybiBhIFVURi0xNiBzdHJpbmcuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7CiAgcmV0dXJuIHV0aWwuZGVjb2RlVXRmOCh0aGlzLmJ5dGVzKCkpOwp9OwoKLyoqIEVuZCBCdWZmZXIgdy9CaW5hcnlTdHJpbmcgYmFja2luZyAqLwoKCi8qKiBCdWZmZXIgdy9VSW50OEFycmF5IGJhY2tpbmcgKi8KCi8qKgogKiBGSVhNRTogRXhwZXJpbWVudGFsLiBEbyBub3QgdXNlIHlldC4KICoKICogQ29uc3RydWN0b3IgZm9yIGFuIEFycmF5QnVmZmVyLWJhY2tlZCBieXRlIGJ1ZmZlci4KICoKICogVGhlIGJ1ZmZlciBtYXkgYmUgY29uc3RydWN0ZWQgZnJvbSBhIHN0cmluZywgYW4gQXJyYXlCdWZmZXIsIERhdGFWaWV3LCBvciBhCiAqIFR5cGVkQXJyYXkuCiAqCiAqIElmIGEgc3RyaW5nIGlzIGdpdmVuLCBpdHMgZW5jb2Rpbmcgc2hvdWxkIGJlIHByb3ZpZGVkIGFzIGFuIG9wdGlvbiwKICogb3RoZXJ3aXNlIGl0IHdpbGwgZGVmYXVsdCB0byAnYmluYXJ5Jy4gQSAnYmluYXJ5JyBzdHJpbmcgaXMgZW5jb2RlZCBzdWNoCiAqIHRoYXQgZWFjaCBjaGFyYWN0ZXIgaXMgb25lIGJ5dGUgaW4gbGVuZ3RoIGFuZCBzaXplLgogKgogKiBJZiBhbiBBcnJheUJ1ZmZlciwgRGF0YVZpZXcsIG9yIFR5cGVkQXJyYXkgaXMgZ2l2ZW4sIGl0IHdpbGwgYmUgdXNlZAogKiAqZGlyZWN0bHkqIHdpdGhvdXQgYW55IGNvcHlpbmcuIE5vdGUgdGhhdCwgaWYgYSB3cml0ZSB0byB0aGUgYnVmZmVyIHJlcXVpcmVzCiAqIG1vcmUgc3BhY2UsIHRoZSBidWZmZXIgd2lsbCBhbGxvY2F0ZSBhIG5ldyBiYWNraW5nIEFycmF5QnVmZmVyIHRvCiAqIGFjY29tbW9kYXRlLiBUaGUgc3RhcnRpbmcgcmVhZCBhbmQgd3JpdGUgb2Zmc2V0cyBmb3IgdGhlIGJ1ZmZlciBtYXkgYmUKICogZ2l2ZW4gYXMgb3B0aW9ucy4KICoKICogQHBhcmFtIFtiXSB0aGUgaW5pdGlhbCBieXRlcyBmb3IgdGhpcyBidWZmZXIuCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgW3JlYWRPZmZzZXRdIHRoZSBzdGFydGluZyByZWFkIG9mZnNldCB0byB1c2UgKGRlZmF1bHQ6IDApLgogKiAgICAgICAgICBbd3JpdGVPZmZzZXRdIHRoZSBzdGFydGluZyB3cml0ZSBvZmZzZXQgdG8gdXNlIChkZWZhdWx0OiB0aGUKICogICAgICAgICAgICBsZW5ndGggb2YgdGhlIGZpcnN0IHBhcmFtZXRlcikuCiAqICAgICAgICAgIFtncm93U2l6ZV0gdGhlIG1pbmltdW0gYW1vdW50LCBpbiBieXRlcywgdG8gZ3JvdyB0aGUgYnVmZmVyIGJ5IHRvCiAqICAgICAgICAgICAgYWNjb21tb2RhdGUgd3JpdGVzIChkZWZhdWx0OiAxMDI0KS4KICogICAgICAgICAgW2VuY29kaW5nXSB0aGUgZW5jb2RpbmcgKCdiaW5hcnknLCAndXRmOCcsICd1dGYxNicsICdoZXgnKSBmb3IgdGhlCiAqICAgICAgICAgICAgZmlyc3QgcGFyYW1ldGVyLCBpZiBpdCBpcyBhIHN0cmluZyAoZGVmYXVsdDogJ2JpbmFyeScpLgogKi8KZnVuY3Rpb24gRGF0YUJ1ZmZlcihiLCBvcHRpb25zKSB7CiAgLy8gZGVmYXVsdCBvcHRpb25zCiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CgogIC8vIHBvaW50ZXJzIGZvciByZWFkIGZyb20vd3JpdGUgdG8gYnVmZmVyCiAgdGhpcy5yZWFkID0gb3B0aW9ucy5yZWFkT2Zmc2V0IHx8IDA7CiAgdGhpcy5ncm93U2l6ZSA9IG9wdGlvbnMuZ3Jvd1NpemUgfHwgMTAyNDsKCiAgdmFyIGlzQXJyYXlCdWZmZXIgPSB1dGlsLmlzQXJyYXlCdWZmZXIoYik7CiAgdmFyIGlzQXJyYXlCdWZmZXJWaWV3ID0gdXRpbC5pc0FycmF5QnVmZmVyVmlldyhiKTsKICBpZihpc0FycmF5QnVmZmVyIHx8IGlzQXJyYXlCdWZmZXJWaWV3KSB7CiAgICAvLyB1c2UgQXJyYXlCdWZmZXIgZGlyZWN0bHkKICAgIGlmKGlzQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5kYXRhID0gbmV3IERhdGFWaWV3KGIpOwogICAgfSBlbHNlIHsKICAgICAgLy8gVE9ETzogYWRqdXN0IHJlYWQvd3JpdGUgb2Zmc2V0IGJhc2VkIG9uIHRoZSB0eXBlIG9mIHZpZXcKICAgICAgLy8gb3Igc3BlY2lmeSB0aGF0IHRoaXMgbXVzdCBiZSBkb25lIGluIHRoZSBvcHRpb25zIC4uLiB0aGF0IHRoZQogICAgICAvLyBvZmZzZXRzIGFyZSBieXRlLWJhc2VkCiAgICAgIHRoaXMuZGF0YSA9IG5ldyBEYXRhVmlldyhiLmJ1ZmZlciwgYi5ieXRlT2Zmc2V0LCBiLmJ5dGVMZW5ndGgpOwogICAgfQogICAgdGhpcy53cml0ZSA9ICgnd3JpdGVPZmZzZXQnIGluIG9wdGlvbnMgPwogICAgICBvcHRpb25zLndyaXRlT2Zmc2V0IDogdGhpcy5kYXRhLmJ5dGVMZW5ndGgpOwogICAgcmV0dXJuOwogIH0KCiAgLy8gaW5pdGlhbGl6ZSB0byBlbXB0eSBhcnJheSBidWZmZXIgYW5kIGFkZCBhbnkgZ2l2ZW4gYnl0ZXMgdXNpbmcgcHV0Qnl0ZXMKICB0aGlzLmRhdGEgPSBuZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDApKTsKICB0aGlzLndyaXRlID0gMDsKCiAgaWYoYiAhPT0gbnVsbCAmJiBiICE9PSB1bmRlZmluZWQpIHsKICAgIHRoaXMucHV0Qnl0ZXMoYik7CiAgfQoKICBpZignd3JpdGVPZmZzZXQnIGluIG9wdGlvbnMpIHsKICAgIHRoaXMud3JpdGUgPSBvcHRpb25zLndyaXRlT2Zmc2V0OwogIH0KfQp1dGlsLkRhdGFCdWZmZXIgPSBEYXRhQnVmZmVyOwoKLyoqCiAqIEdldHMgdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGlzIGJ1ZmZlci4KICoKICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbigpIHsKICByZXR1cm4gdGhpcy53cml0ZSAtIHRoaXMucmVhZDsKfTsKCi8qKgogKiBHZXRzIHdoZXRoZXIgb3Igbm90IHRoaXMgYnVmZmVyIGlzIGVtcHR5LgogKgogKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBidWZmZXIgaXMgZW1wdHksIGZhbHNlIGlmIG5vdC4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uKCkgewogIHJldHVybiB0aGlzLmxlbmd0aCgpIDw9IDA7Cn07CgovKioKICogRW5zdXJlcyB0aGlzIGJ1ZmZlciBoYXMgZW5vdWdoIGVtcHR5IHNwYWNlIHRvIGFjY29tbW9kYXRlIHRoZSBnaXZlbiBudW1iZXIKICogb2YgYnl0ZXMuIEFuIG9wdGlvbmFsIHBhcmFtZXRlciBtYXkgYmUgZ2l2ZW4gdGhhdCBpbmRpY2F0ZXMgYSBtaW5pbXVtCiAqIGFtb3VudCB0byBncm93IHRoZSBidWZmZXIgaWYgbmVjZXNzYXJ5LiBJZiB0aGUgcGFyYW1ldGVyIGlzIG5vdCBnaXZlbiwKICogdGhlIGJ1ZmZlciB3aWxsIGJlIGdyb3duIGJ5IHNvbWUgcHJldmlvdXNseS1zcGVjaWZpZWQgZGVmYXVsdCBhbW91bnQKICogb3IgaGV1cmlzdGljLgogKgogKiBAcGFyYW0gYW1vdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gYWNjb21tb2RhdGUuCiAqIEBwYXJhbSBbZ3Jvd1NpemVdIHRoZSBtaW5pbXVtIGFtb3VudCwgaW4gYnl0ZXMsIHRvIGdyb3cgdGhlIGJ1ZmZlciBieSBpZgogKiAgICAgICAgICBuZWNlc3NhcnkuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLmFjY29tbW9kYXRlID0gZnVuY3Rpb24oYW1vdW50LCBncm93U2l6ZSkgewogIGlmKHRoaXMubGVuZ3RoKCkgPj0gYW1vdW50KSB7CiAgICByZXR1cm4gdGhpczsKICB9CiAgZ3Jvd1NpemUgPSBNYXRoLm1heChncm93U2l6ZSB8fCB0aGlzLmdyb3dTaXplLCBhbW91bnQpOwoKICAvLyBncm93IGJ1ZmZlcgogIHZhciBzcmMgPSBuZXcgVWludDhBcnJheSgKICAgIHRoaXMuZGF0YS5idWZmZXIsIHRoaXMuZGF0YS5ieXRlT2Zmc2V0LCB0aGlzLmRhdGEuYnl0ZUxlbmd0aCk7CiAgdmFyIGRzdCA9IG5ldyBVaW50OEFycmF5KHRoaXMubGVuZ3RoKCkgKyBncm93U2l6ZSk7CiAgZHN0LnNldChzcmMpOwogIHRoaXMuZGF0YSA9IG5ldyBEYXRhVmlldyhkc3QuYnVmZmVyKTsKCiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIGJ5dGUgaW4gdGhpcyBidWZmZXIuCiAqCiAqIEBwYXJhbSBiIHRoZSBieXRlIHRvIHB1dC4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0Qnl0ZSA9IGZ1bmN0aW9uKGIpIHsKICB0aGlzLmFjY29tbW9kYXRlKDEpOwogIHRoaXMuZGF0YS5zZXRVaW50OCh0aGlzLndyaXRlKyssIGIpOwogIHJldHVybiB0aGlzOwp9OwoKLyoqCiAqIFB1dHMgYSBieXRlIGluIHRoaXMgYnVmZmVyIE4gdGltZXMuCiAqCiAqIEBwYXJhbSBiIHRoZSBieXRlIHRvIHB1dC4KICogQHBhcmFtIG4gdGhlIG51bWJlciBvZiBieXRlcyBvZiB2YWx1ZSBiIHRvIHB1dC4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZmlsbFdpdGhCeXRlID0gZnVuY3Rpb24oYiwgbikgewogIHRoaXMuYWNjb21tb2RhdGUobik7CiAgZm9yKHZhciBpID0gMDsgaSA8IG47ICsraSkgewogICAgdGhpcy5kYXRhLnNldFVpbnQ4KGIpOwogIH0KICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBQdXRzIGJ5dGVzIGluIHRoaXMgYnVmZmVyLiBUaGUgYnl0ZXMgbWF5IGJlIGdpdmVuIGFzIGEgc3RyaW5nLCBhbgogKiBBcnJheUJ1ZmZlciwgYSBEYXRhVmlldywgb3IgYSBUeXBlZEFycmF5LgogKgogKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGVzIHRvIHB1dC4KICogQHBhcmFtIFtlbmNvZGluZ10gdGhlIGVuY29kaW5nIGZvciB0aGUgZmlyc3QgcGFyYW1ldGVyICgnYmluYXJ5JywgJ3V0ZjgnLAogKiAgICAgICAgICAndXRmMTYnLCAnaGV4JyksIGlmIGl0IGlzIGEgc3RyaW5nIChkZWZhdWx0OiAnYmluYXJ5JykuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dEJ5dGVzID0gZnVuY3Rpb24oYnl0ZXMsIGVuY29kaW5nKSB7CiAgaWYodXRpbC5pc0FycmF5QnVmZmVyVmlldyhieXRlcykpIHsKICAgIHZhciBzcmMgPSBuZXcgVWludDhBcnJheShieXRlcy5idWZmZXIsIGJ5dGVzLmJ5dGVPZmZzZXQsIGJ5dGVzLmJ5dGVMZW5ndGgpOwogICAgdmFyIGxlbiA9IHNyYy5ieXRlTGVuZ3RoIC0gc3JjLmJ5dGVPZmZzZXQ7CiAgICB0aGlzLmFjY29tbW9kYXRlKGxlbik7CiAgICB2YXIgZHN0ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5kYXRhLmJ1ZmZlciwgdGhpcy53cml0ZSk7CiAgICBkc3Quc2V0KHNyYyk7CiAgICB0aGlzLndyaXRlICs9IGxlbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgaWYodXRpbC5pc0FycmF5QnVmZmVyKGJ5dGVzKSkgewogICAgdmFyIHNyYyA9IG5ldyBVaW50OEFycmF5KGJ5dGVzKTsKICAgIHRoaXMuYWNjb21tb2RhdGUoc3JjLmJ5dGVMZW5ndGgpOwogICAgdmFyIGRzdCA9IG5ldyBVaW50OEFycmF5KHRoaXMuZGF0YS5idWZmZXIpOwogICAgZHN0LnNldChzcmMsIHRoaXMud3JpdGUpOwogICAgdGhpcy53cml0ZSArPSBzcmMuYnl0ZUxlbmd0aDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLy8gYnl0ZXMgaXMgYSB1dGlsLkRhdGFCdWZmZXIgb3IgZXF1aXZhbGVudAogIGlmKGJ5dGVzIGluc3RhbmNlb2YgdXRpbC5EYXRhQnVmZmVyIHx8CiAgICAodHlwZW9mIGJ5dGVzID09PSAnb2JqZWN0JyAmJgogICAgdHlwZW9mIGJ5dGVzLnJlYWQgPT09ICdudW1iZXInICYmIHR5cGVvZiBieXRlcy53cml0ZSA9PT0gJ251bWJlcicgJiYKICAgIHV0aWwuaXNBcnJheUJ1ZmZlclZpZXcoYnl0ZXMuZGF0YSkpKSB7CiAgICB2YXIgc3JjID0gbmV3IFVpbnQ4QXJyYXkoYnl0ZXMuZGF0YS5ieXRlTGVuZ3RoLCBieXRlcy5yZWFkLCBieXRlcy5sZW5ndGgoKSk7CiAgICB0aGlzLmFjY29tbW9kYXRlKHNyYy5ieXRlTGVuZ3RoKTsKICAgIHZhciBkc3QgPSBuZXcgVWludDhBcnJheShieXRlcy5kYXRhLmJ5dGVMZW5ndGgsIHRoaXMud3JpdGUpOwogICAgZHN0LnNldChzcmMpOwogICAgdGhpcy53cml0ZSArPSBzcmMuYnl0ZUxlbmd0aDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgaWYoYnl0ZXMgaW5zdGFuY2VvZiB1dGlsLkJ5dGVTdHJpbmdCdWZmZXIpIHsKICAgIC8vIGNvcHkgYmluYXJ5IHN0cmluZyBhbmQgcHJvY2VzcyBhcyB0aGUgc2FtZSBhcyBhIHN0cmluZyBwYXJhbWV0ZXIgYmVsb3cKICAgIGJ5dGVzID0gYnl0ZXMuZGF0YTsKICAgIGVuY29kaW5nID0gJ2JpbmFyeSc7CiAgfQoKICAvLyBzdHJpbmcgY29udmVyc2lvbgogIGVuY29kaW5nID0gZW5jb2RpbmcgfHwgJ2JpbmFyeSc7CiAgaWYodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykgewogICAgdmFyIHZpZXc7CgogICAgLy8gZGVjb2RlIGZyb20gc3RyaW5nCiAgICBpZihlbmNvZGluZyA9PT0gJ2hleCcpIHsKICAgICAgdGhpcy5hY2NvbW1vZGF0ZShNYXRoLmNlaWwoYnl0ZXMubGVuZ3RoIC8gMikpOwogICAgICB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5kYXRhLmJ1ZmZlciwgdGhpcy53cml0ZSk7CiAgICAgIHRoaXMud3JpdGUgKz0gdXRpbC5iaW5hcnkuaGV4LmRlY29kZShieXRlcywgdmlldywgdGhpcy53cml0ZSk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgaWYoZW5jb2RpbmcgPT09ICdiYXNlNjQnKSB7CiAgICAgIHRoaXMuYWNjb21tb2RhdGUoTWF0aC5jZWlsKGJ5dGVzLmxlbmd0aCAvIDQpICogMyk7CiAgICAgIHZpZXcgPSBuZXcgVWludDhBcnJheSh0aGlzLmRhdGEuYnVmZmVyLCB0aGlzLndyaXRlKTsKICAgICAgdGhpcy53cml0ZSArPSB1dGlsLmJpbmFyeS5iYXNlNjQuZGVjb2RlKGJ5dGVzLCB2aWV3LCB0aGlzLndyaXRlKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgLy8gZW5jb2RlIHRleHQgYXMgVVRGLTggYnl0ZXMKICAgIGlmKGVuY29kaW5nID09PSAndXRmOCcpIHsKICAgICAgLy8gZW5jb2RlIGFzIFVURi04IHRoZW4gZGVjb2RlIHN0cmluZyBhcyByYXcgYmluYXJ5CiAgICAgIGJ5dGVzID0gdXRpbC5lbmNvZGVVdGY4KGJ5dGVzKTsKICAgICAgZW5jb2RpbmcgPSAnYmluYXJ5JzsKICAgIH0KCiAgICAvLyBkZWNvZGUgc3RyaW5nIGFzIHJhdyBiaW5hcnkKICAgIGlmKGVuY29kaW5nID09PSAnYmluYXJ5JyB8fCBlbmNvZGluZyA9PT0gJ3JhdycpIHsKICAgICAgLy8gb25lIGJ5dGUgcGVyIGNoYXJhY3RlcgogICAgICB0aGlzLmFjY29tbW9kYXRlKGJ5dGVzLmxlbmd0aCk7CiAgICAgIHZpZXcgPSBuZXcgVWludDhBcnJheSh0aGlzLmRhdGEuYnVmZmVyLCB0aGlzLndyaXRlKTsKICAgICAgdGhpcy53cml0ZSArPSB1dGlsLmJpbmFyeS5yYXcuZGVjb2RlKHZpZXcpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICAvLyBlbmNvZGUgdGV4dCBhcyBVVEYtMTYgYnl0ZXMKICAgIGlmKGVuY29kaW5nID09PSAndXRmMTYnKSB7CiAgICAgIC8vIHR3byBieXRlcyBwZXIgY2hhcmFjdGVyCiAgICAgIHRoaXMuYWNjb21tb2RhdGUoYnl0ZXMubGVuZ3RoICogMik7CiAgICAgIHZpZXcgPSBuZXcgVWludDE2QXJyYXkodGhpcy5kYXRhLmJ1ZmZlciwgdGhpcy53cml0ZSk7CiAgICAgIHRoaXMud3JpdGUgKz0gdXRpbC50ZXh0LnV0ZjE2LmVuY29kZSh2aWV3KTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpOwogIH0KCiAgdGhyb3cgRXJyb3IoJ0ludmFsaWQgcGFyYW1ldGVyOiAnICsgYnl0ZXMpOwp9OwoKLyoqCiAqIFB1dHMgdGhlIGdpdmVuIGJ1ZmZlciBpbnRvIHRoaXMgYnVmZmVyLgogKgogKiBAcGFyYW0gYnVmZmVyIHRoZSBidWZmZXIgdG8gcHV0IGludG8gdGhpcyBvbmUuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dEJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikgewogIHRoaXMucHV0Qnl0ZXMoYnVmZmVyKTsKICBidWZmZXIuY2xlYXIoKTsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBQdXRzIGEgc3RyaW5nIGludG8gdGhpcyBidWZmZXIuCiAqCiAqIEBwYXJhbSBzdHIgdGhlIHN0cmluZyB0byBwdXQuCiAqIEBwYXJhbSBbZW5jb2RpbmddIHRoZSBlbmNvZGluZyBmb3IgdGhlIHN0cmluZyAoZGVmYXVsdDogJ3V0ZjE2JykuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dFN0cmluZyA9IGZ1bmN0aW9uKHN0cikgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKHN0ciwgJ3V0ZjE2Jyk7Cn07CgovKioKICogUHV0cyBhIDE2LWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAxNi1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0SW50MTYgPSBmdW5jdGlvbihpKSB7CiAgdGhpcy5hY2NvbW1vZGF0ZSgyKTsKICB0aGlzLmRhdGEuc2V0SW50MTYodGhpcy53cml0ZSwgaSk7CiAgdGhpcy53cml0ZSArPSAyOwogIHJldHVybiB0aGlzOwp9OwoKLyoqCiAqIFB1dHMgYSAyNC1iaXQgaW50ZWdlciBpbiB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyLgogKgogKiBAcGFyYW0gaSB0aGUgMjQtYml0IGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dEludDI0ID0gZnVuY3Rpb24oaSkgewogIHRoaXMuYWNjb21tb2RhdGUoMyk7CiAgdGhpcy5kYXRhLnNldEludDE2KHRoaXMud3JpdGUsIGkgPj4gOCAmIDB4RkZGRik7CiAgdGhpcy5kYXRhLnNldEludDgodGhpcy53cml0ZSwgaSA+PiAxNiAmIDB4RkYpOwogIHRoaXMud3JpdGUgKz0gMzsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBQdXRzIGEgMzItYml0IGludGVnZXIgaW4gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlci4KICoKICogQHBhcmFtIGkgdGhlIDMyLWJpdCBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5wdXRJbnQzMiA9IGZ1bmN0aW9uKGkpIHsKICB0aGlzLmFjY29tbW9kYXRlKDQpOwogIHRoaXMuZGF0YS5zZXRJbnQzMih0aGlzLndyaXRlLCBpKTsKICB0aGlzLndyaXRlICs9IDQ7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIDE2LWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAxNi1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0SW50MTZMZSA9IGZ1bmN0aW9uKGkpIHsKICB0aGlzLmFjY29tbW9kYXRlKDIpOwogIHRoaXMuZGF0YS5zZXRJbnQxNih0aGlzLndyaXRlLCBpLCB0cnVlKTsKICB0aGlzLndyaXRlICs9IDI7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIDI0LWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAyNC1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0SW50MjRMZSA9IGZ1bmN0aW9uKGkpIHsKICB0aGlzLmFjY29tbW9kYXRlKDMpOwogIHRoaXMuZGF0YS5zZXRJbnQ4KHRoaXMud3JpdGUsIGkgPj4gMTYgJiAweEZGKTsKICB0aGlzLmRhdGEuc2V0SW50MTYodGhpcy53cml0ZSwgaSA+PiA4ICYgMHhGRkZGLCB0cnVlKTsKICB0aGlzLndyaXRlICs9IDM7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIDMyLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAzMi1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0SW50MzJMZSA9IGZ1bmN0aW9uKGkpIHsKICB0aGlzLmFjY29tbW9kYXRlKDQpOwogIHRoaXMuZGF0YS5zZXRJbnQzMih0aGlzLndyaXRlLCBpLCB0cnVlKTsKICB0aGlzLndyaXRlICs9IDQ7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhbiBuLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSBuLWJpdCBpbnRlZ2VyLgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dEludCA9IGZ1bmN0aW9uKGksIG4pIHsKICB0aGlzLmFjY29tbW9kYXRlKG4gLyA4KTsKICBkbyB7CiAgICBuIC09IDg7CiAgICB0aGlzLmRhdGEuc2V0SW50OCh0aGlzLndyaXRlKyssIChpID4+IG4pICYgMHhGRik7CiAgfSB3aGlsZShuID4gMCk7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIHNpZ25lZCBuLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuIFR3bydzCiAqIGNvbXBsZW1lbnQgcmVwcmVzZW50YXRpb24gaXMgdXNlZC4KICoKICogQHBhcmFtIGkgdGhlIG4tYml0IGludGVnZXIuCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0U2lnbmVkSW50ID0gZnVuY3Rpb24oaSwgbikgewogIHRoaXMuYWNjb21tb2RhdGUobiAvIDgpOwogIGlmKGkgPCAwKSB7CiAgICBpICs9IDIgPDwgKG4gLSAxKTsKICB9CiAgcmV0dXJuIHRoaXMucHV0SW50KGksIG4pOwp9OwoKLyoqCiAqIEdldHMgYSBieXRlIGZyb20gdGhpcyBidWZmZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkIHBvaW50ZXIgYnkgMS4KICoKICogQHJldHVybiB0aGUgYnl0ZS4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0Qnl0ZSA9IGZ1bmN0aW9uKCkgewogIHJldHVybiB0aGlzLmRhdGEuZ2V0SW50OCh0aGlzLnJlYWQrKyk7Cn07CgovKioKICogR2V0cyBhIHVpbnQxNiBmcm9tIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMi4KICoKICogQHJldHVybiB0aGUgdWludDE2LgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQxNiA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gdGhpcy5kYXRhLmdldEludDE2KHRoaXMucmVhZCk7CiAgdGhpcy5yZWFkICs9IDI7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQyNCBmcm9tIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMy4KICoKICogQHJldHVybiB0aGUgdWludDI0LgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQyNCA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gKAogICAgdGhpcy5kYXRhLmdldEludDE2KHRoaXMucmVhZCkgPDwgOCBeCiAgICB0aGlzLmRhdGEuZ2V0SW50OCh0aGlzLnJlYWQgKyAyKSk7CiAgdGhpcy5yZWFkICs9IDM7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQzMiBmcm9tIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgNC4KICoKICogQHJldHVybiB0aGUgd29yZC4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0SW50MzIgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9IHRoaXMuZGF0YS5nZXRJbnQzMih0aGlzLnJlYWQpOwogIHRoaXMucmVhZCArPSA0OwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEdldHMgYSB1aW50MTYgZnJvbSB0aGlzIGJ1ZmZlciBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyIGFuZCBhZHZhbmNlcyB0aGUgcmVhZAogKiBwb2ludGVyIGJ5IDIuCiAqCiAqIEByZXR1cm4gdGhlIHVpbnQxNi4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0SW50MTZMZSA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gdGhpcy5kYXRhLmdldEludDE2KHRoaXMucmVhZCwgdHJ1ZSk7CiAgdGhpcy5yZWFkICs9IDI7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQyNCBmcm9tIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMy4KICoKICogQHJldHVybiB0aGUgdWludDI0LgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQyNExlID0gZnVuY3Rpb24oKSB7CiAgdmFyIHJ2YWwgPSAoCiAgICB0aGlzLmRhdGEuZ2V0SW50OCh0aGlzLnJlYWQpIF4KICAgIHRoaXMuZGF0YS5nZXRJbnQxNih0aGlzLnJlYWQgKyAxLCB0cnVlKSA8PCA4KTsKICB0aGlzLnJlYWQgKz0gMzsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGEgdWludDMyIGZyb20gdGhpcyBidWZmZXIgaW4gbGl0dGxlLWVuZGlhbiBvcmRlciBhbmQgYWR2YW5jZXMgdGhlIHJlYWQKICogcG9pbnRlciBieSA0LgogKgogKiBAcmV0dXJuIHRoZSB3b3JkLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQzMkxlID0gZnVuY3Rpb24oKSB7CiAgdmFyIHJ2YWwgPSB0aGlzLmRhdGEuZ2V0SW50MzIodGhpcy5yZWFkLCB0cnVlKTsKICB0aGlzLnJlYWQgKz0gNDsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGFuIG4tYml0IGludGVnZXIgZnJvbSB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyIGFuZCBhZHZhbmNlcyB0aGUKICogcmVhZCBwb2ludGVyIGJ5IG4vOC4KICoKICogQHBhcmFtIG4gdGhlIG51bWJlciBvZiBiaXRzIGluIHRoZSBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoZSBpbnRlZ2VyLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQgPSBmdW5jdGlvbihuKSB7CiAgdmFyIHJ2YWwgPSAwOwogIGRvIHsKICAgIHJ2YWwgPSAocnZhbCA8PCA4KSArIHRoaXMuZGF0YS5nZXRJbnQ4KHRoaXMucmVhZCsrKTsKICAgIG4gLT0gODsKICB9IHdoaWxlKG4gPiAwKTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGEgc2lnbmVkIG4tYml0IGludGVnZXIgZnJvbSB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyLCB1c2luZwogKiB0d28ncyBjb21wbGVtZW50LCBhbmQgYWR2YW5jZXMgdGhlIHJlYWQgcG9pbnRlciBieSBuLzguCiAqCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGUgaW50ZWdlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0U2lnbmVkSW50ID0gZnVuY3Rpb24obikgewogIHZhciB4ID0gdGhpcy5nZXRJbnQobik7CiAgdmFyIG1heCA9IDIgPDwgKG4gLSAyKTsKICBpZih4ID49IG1heCkgewogICAgeCAtPSBtYXggPDwgMTsKICB9CiAgcmV0dXJuIHg7Cn07CgovKioKICogUmVhZHMgYnl0ZXMgb3V0IGludG8gYSBVVEYtOCBzdHJpbmcgYW5kIGNsZWFycyB0aGVtIGZyb20gdGhlIGJ1ZmZlci4KICoKICogQHBhcmFtIGNvdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZCwgdW5kZWZpbmVkIG9yIG51bGwgZm9yIGFsbC4KICoKICogQHJldHVybiBhIFVURi04IHN0cmluZyBvZiBieXRlcy4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0Qnl0ZXMgPSBmdW5jdGlvbihjb3VudCkgewogIC8vIFRPRE86IGRlcHJlY2F0ZSB0aGlzIG1ldGhvZCwgaXQgaXMgcG9vcmx5IG5hbWVkIGFuZAogIC8vIHRoaXMudG9TdHJpbmcoJ2JpbmFyeScpIHJlcGxhY2VzIGl0CiAgLy8gYWRkIGEgdG9UeXBlZEFycmF5KCkvdG9BcnJheUJ1ZmZlcigpIGZ1bmN0aW9uCiAgdmFyIHJ2YWw7CiAgaWYoY291bnQpIHsKICAgIC8vIHJlYWQgY291bnQgYnl0ZXMKICAgIGNvdW50ID0gTWF0aC5taW4odGhpcy5sZW5ndGgoKSwgY291bnQpOwogICAgcnZhbCA9IHRoaXMuZGF0YS5zbGljZSh0aGlzLnJlYWQsIHRoaXMucmVhZCArIGNvdW50KTsKICAgIHRoaXMucmVhZCArPSBjb3VudDsKICB9IGVsc2UgaWYoY291bnQgPT09IDApIHsKICAgIHJ2YWwgPSAnJzsKICB9IGVsc2UgewogICAgLy8gcmVhZCBhbGwgYnl0ZXMsIG9wdGltaXplIHRvIG9ubHkgY29weSB3aGVuIG5lZWRlZAogICAgcnZhbCA9ICh0aGlzLnJlYWQgPT09IDApID8gdGhpcy5kYXRhIDogdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCk7CiAgICB0aGlzLmNsZWFyKCk7CiAgfQogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEdldHMgYSBVVEYtOCBlbmNvZGVkIHN0cmluZyBvZiB0aGUgYnl0ZXMgZnJvbSB0aGlzIGJ1ZmZlciB3aXRob3V0IG1vZGlmeWluZwogKiB0aGUgcmVhZCBwb2ludGVyLgogKgogKiBAcGFyYW0gY291bnQgdGhlIG51bWJlciBvZiBieXRlcyB0byBnZXQsIG9taXQgdG8gZ2V0IGFsbC4KICoKICogQHJldHVybiBhIHN0cmluZyBmdWxsIG9mIFVURi04IGVuY29kZWQgY2hhcmFjdGVycy4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuYnl0ZXMgPSBmdW5jdGlvbihjb3VudCkgewogIC8vIFRPRE86IGRlcHJlY2F0ZSB0aGlzIG1ldGhvZCwgaXQgaXMgcG9vcmx5IG5hbWVkLCBhZGQgImdldFN0cmluZygpIgogIHJldHVybiAodHlwZW9mKGNvdW50KSA9PT0gJ3VuZGVmaW5lZCcgPwogICAgdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCkgOgogICAgdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCwgdGhpcy5yZWFkICsgY291bnQpKTsKfTsKCi8qKgogKiBHZXRzIGEgYnl0ZSBhdCB0aGUgZ2l2ZW4gaW5kZXggd2l0aG91dCBtb2RpZnlpbmcgdGhlIHJlYWQgcG9pbnRlci4KICoKICogQHBhcmFtIGkgdGhlIGJ5dGUgaW5kZXguCiAqCiAqIEByZXR1cm4gdGhlIGJ5dGUuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLmF0ID0gZnVuY3Rpb24oaSkgewogIHJldHVybiB0aGlzLmRhdGEuZ2V0VWludDgodGhpcy5yZWFkICsgaSk7Cn07CgovKioKICogUHV0cyBhIGJ5dGUgYXQgdGhlIGdpdmVuIGluZGV4IHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSByZWFkIHBvaW50ZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSBieXRlIGluZGV4LgogKiBAcGFyYW0gYiB0aGUgYnl0ZSB0byBwdXQuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnNldEF0ID0gZnVuY3Rpb24oaSwgYikgewogIHRoaXMuZGF0YS5zZXRVaW50OChpLCBiKTsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBHZXRzIHRoZSBsYXN0IGJ5dGUgd2l0aG91dCBtb2RpZnlpbmcgdGhlIHJlYWQgcG9pbnRlci4KICoKICogQHJldHVybiB0aGUgbGFzdCBieXRlLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5sYXN0ID0gZnVuY3Rpb24oKSB7CiAgcmV0dXJuIHRoaXMuZGF0YS5nZXRVaW50OCh0aGlzLndyaXRlIC0gMSk7Cn07CgovKioKICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIGNvcHkuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gbmV3IHV0aWwuRGF0YUJ1ZmZlcih0aGlzKTsKfTsKCi8qKgogKiBDb21wYWN0cyB0aGlzIGJ1ZmZlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuY29tcGFjdCA9IGZ1bmN0aW9uKCkgewogIGlmKHRoaXMucmVhZCA+IDApIHsKICAgIHZhciBzcmMgPSBuZXcgVWludDhBcnJheSh0aGlzLmRhdGEuYnVmZmVyLCB0aGlzLnJlYWQpOwogICAgdmFyIGRzdCA9IG5ldyBVaW50OEFycmF5KHNyYy5ieXRlTGVuZ3RoKTsKICAgIGRzdC5zZXQoc3JjKTsKICAgIHRoaXMuZGF0YSA9IG5ldyBEYXRhVmlldyhkc3QpOwogICAgdGhpcy53cml0ZSAtPSB0aGlzLnJlYWQ7CiAgICB0aGlzLnJlYWQgPSAwOwogIH0KICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBDbGVhcnMgdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5kYXRhID0gbmV3IERhdGFWaWV3KG5ldyBBcnJheUJ1ZmZlcigwKSk7CiAgdGhpcy5yZWFkID0gdGhpcy53cml0ZSA9IDA7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogU2hvcnRlbnMgdGhpcyBidWZmZXIgYnkgdHJpbWluZyBieXRlcyBvZmYgb2YgdGhlIGVuZCBvZiB0aGlzIGJ1ZmZlci4KICoKICogQHBhcmFtIGNvdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gdHJpbSBvZmYuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnRydW5jYXRlID0gZnVuY3Rpb24oY291bnQpIHsKICB0aGlzLndyaXRlID0gTWF0aC5tYXgoMCwgdGhpcy5sZW5ndGgoKSAtIGNvdW50KTsKICB0aGlzLnJlYWQgPSBNYXRoLm1pbih0aGlzLnJlYWQsIHRoaXMud3JpdGUpOwogIHJldHVybiB0aGlzOwp9OwoKLyoqCiAqIENvbnZlcnRzIHRoaXMgYnVmZmVyIHRvIGEgaGV4YWRlY2ltYWwgc3RyaW5nLgogKgogKiBAcmV0dXJuIGEgaGV4YWRlY2ltYWwgc3RyaW5nLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS50b0hleCA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gJyc7CiAgZm9yKHZhciBpID0gdGhpcy5yZWFkOyBpIDwgdGhpcy5kYXRhLmJ5dGVMZW5ndGg7ICsraSkgewogICAgdmFyIGIgPSB0aGlzLmRhdGEuZ2V0VWludDgoaSk7CiAgICBpZihiIDwgMTYpIHsKICAgICAgcnZhbCArPSAnMCc7CiAgICB9CiAgICBydmFsICs9IGIudG9TdHJpbmcoMTYpOwogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDb252ZXJ0cyB0aGlzIGJ1ZmZlciB0byBhIHN0cmluZywgdXNpbmcgdGhlIGdpdmVuIGVuY29kaW5nLiBJZiBubwogKiBlbmNvZGluZyBpcyBnaXZlbiwgJ3V0ZjgnIChVVEYtOCkgaXMgdXNlZC4KICoKICogQHBhcmFtIFtlbmNvZGluZ10gdGhlIGVuY29kaW5nIHRvIHVzZTogJ2JpbmFyeScsICd1dGY4JywgJ3V0ZjE2JywgJ2hleCcsCiAqICAgICAgICAgICdiYXNlNjQnIChkZWZhdWx0OiAndXRmOCcpLgogKgogKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBieXRlcyBpbiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihlbmNvZGluZykgewogIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5kYXRhLCB0aGlzLnJlYWQsIHRoaXMubGVuZ3RoKCkpOwogIGVuY29kaW5nID0gZW5jb2RpbmcgfHwgJ3V0ZjgnOwoKICAvLyBlbmNvZGUgdG8gc3RyaW5nCiAgaWYoZW5jb2RpbmcgPT09ICdiaW5hcnknIHx8IGVuY29kaW5nID09PSAncmF3JykgewogICAgcmV0dXJuIHV0aWwuYmluYXJ5LnJhdy5lbmNvZGUodmlldyk7CiAgfQogIGlmKGVuY29kaW5nID09PSAnaGV4JykgewogICAgcmV0dXJuIHV0aWwuYmluYXJ5LmhleC5lbmNvZGUodmlldyk7CiAgfQogIGlmKGVuY29kaW5nID09PSAnYmFzZTY0JykgewogICAgcmV0dXJuIHV0aWwuYmluYXJ5LmJhc2U2NC5lbmNvZGUodmlldyk7CiAgfQoKICAvLyBkZWNvZGUgdG8gdGV4dAogIGlmKGVuY29kaW5nID09PSAndXRmOCcpIHsKICAgIHJldHVybiB1dGlsLnRleHQudXRmOC5kZWNvZGUodmlldyk7CiAgfQogIGlmKGVuY29kaW5nID09PSAndXRmMTYnKSB7CiAgICByZXR1cm4gdXRpbC50ZXh0LnV0ZjE2LmRlY29kZSh2aWV3KTsKICB9CgogIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBlbmNvZGluZzogJyArIGVuY29kaW5nKTsKfTsKCi8qKiBFbmQgQnVmZmVyIHcvVUludDhBcnJheSBiYWNraW5nICovCgoKLyoqCiAqIENyZWF0ZXMgYSBidWZmZXIgdGhhdCBzdG9yZXMgYnl0ZXMuIEEgdmFsdWUgbWF5IGJlIGdpdmVuIHRvIHB1dCBpbnRvIHRoZQogKiBidWZmZXIgdGhhdCBpcyBlaXRoZXIgYSBzdHJpbmcgb2YgYnl0ZXMgb3IgYSBVVEYtMTYgc3RyaW5nIHRoYXQgd2lsbAogKiBiZSBlbmNvZGVkIHVzaW5nIFVURi04ICh0byBkbyB0aGUgbGF0dGVyLCBzcGVjaWZ5ICd1dGY4JyBhcyB0aGUgZW5jb2RpbmcpLgogKgogKiBAcGFyYW0gW2lucHV0XSB0aGUgYnl0ZXMgdG8gd3JhcCAoYXMgYSBzdHJpbmcpIG9yIGEgVVRGLTE2IHN0cmluZyB0byBlbmNvZGUKICogICAgICAgICAgYXMgVVRGLTguCiAqIEBwYXJhbSBbZW5jb2RpbmddIChkZWZhdWx0OiAncmF3Jywgb3RoZXI6ICd1dGY4JykuCiAqLwp1dGlsLmNyZWF0ZUJ1ZmZlciA9IGZ1bmN0aW9uKGlucHV0LCBlbmNvZGluZykgewogIC8vIFRPRE86IGRlcHJlY2F0ZSwgdXNlIG5ldyBCeXRlQnVmZmVyKCkgaW5zdGVhZAogIGVuY29kaW5nID0gZW5jb2RpbmcgfHwgJ3Jhdyc7CiAgaWYoaW5wdXQgIT09IHVuZGVmaW5lZCAmJiBlbmNvZGluZyA9PT0gJ3V0ZjgnKSB7CiAgICBpbnB1dCA9IHV0aWwuZW5jb2RlVXRmOChpbnB1dCk7CiAgfQogIHJldHVybiBuZXcgdXRpbC5CeXRlQnVmZmVyKGlucHV0KTsKfTsKCi8qKgogKiBGaWxscyBhIHN0cmluZyB3aXRoIGEgcGFydGljdWxhciB2YWx1ZS4gSWYgeW91IHdhbnQgdGhlIHN0cmluZyB0byBiZSBhIGJ5dGUKICogc3RyaW5nLCBwYXNzIGluIFN0cmluZy5mcm9tQ2hhckNvZGUodGhlQnl0ZSkuCiAqCiAqIEBwYXJhbSBjIHRoZSBjaGFyYWN0ZXIgdG8gZmlsbCB0aGUgc3RyaW5nIHdpdGgsIHVzZSBTdHJpbmcuZnJvbUNoYXJDb2RlCiAqICAgICAgICAgIHRvIGZpbGwgdGhlIHN0cmluZyB3aXRoIGEgYnl0ZSB2YWx1ZS4KICogQHBhcmFtIG4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIG9mIHZhbHVlIGMgdG8gZmlsbCB3aXRoLgogKgogKiBAcmV0dXJuIHRoZSBmaWxsZWQgc3RyaW5nLgogKi8KdXRpbC5maWxsU3RyaW5nID0gZnVuY3Rpb24oYywgbikgewogIHZhciBzID0gJyc7CiAgd2hpbGUobiA+IDApIHsKICAgIGlmKG4gJiAxKSB7CiAgICAgIHMgKz0gYzsKICAgIH0KICAgIG4gPj4+PSAxOwogICAgaWYobiA+IDApIHsKICAgICAgYyArPSBjOwogICAgfQogIH0KICByZXR1cm4gczsKfTsKCi8qKgogKiBQZXJmb3JtcyBhIHBlciBieXRlIFhPUiBiZXR3ZWVuIHR3byBieXRlIHN0cmluZ3MgYW5kIHJldHVybnMgdGhlIHJlc3VsdCBhcyBhCiAqIHN0cmluZyBvZiBieXRlcy4KICoKICogQHBhcmFtIHMxIGZpcnN0IHN0cmluZyBvZiBieXRlcy4KICogQHBhcmFtIHMyIHNlY29uZCBzdHJpbmcgb2YgYnl0ZXMuCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gWE9SLgogKgogKiBAcmV0dXJuIHRoZSBYT1InZCByZXN1bHQuCiAqLwp1dGlsLnhvckJ5dGVzID0gZnVuY3Rpb24oczEsIHMyLCBuKSB7CiAgdmFyIHMzID0gJyc7CiAgdmFyIGIgPSAnJzsKICB2YXIgdCA9ICcnOwogIHZhciBpID0gMDsKICB2YXIgYyA9IDA7CiAgZm9yKDsgbiA+IDA7IC0tbiwgKytpKSB7CiAgICBiID0gczEuY2hhckNvZGVBdChpKSBeIHMyLmNoYXJDb2RlQXQoaSk7CiAgICBpZihjID49IDEwKSB7CiAgICAgIHMzICs9IHQ7CiAgICAgIHQgPSAnJzsKICAgICAgYyA9IDA7CiAgICB9CiAgICB0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYik7CiAgICArK2M7CiAgfQogIHMzICs9IHQ7CiAgcmV0dXJuIHMzOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgaGV4IHN0cmluZyBpbnRvIGEgJ2JpbmFyeScgZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMuCiAqCiAqIEBwYXJhbSBoZXggdGhlIGhleGFkZWNpbWFsIHN0cmluZyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMuCiAqLwp1dGlsLmhleFRvQnl0ZXMgPSBmdW5jdGlvbihoZXgpIHsKICAvLyBUT0RPOiBkZXByZWNhdGU6ICJEZXByZWNhdGVkLiBVc2UgdXRpbC5iaW5hcnkuaGV4LmRlY29kZSBpbnN0ZWFkLiIKICB2YXIgcnZhbCA9ICcnOwogIHZhciBpID0gMDsKICBpZihoZXgubGVuZ3RoICYgMSA9PSAxKSB7CiAgICAvLyBvZGQgbnVtYmVyIG9mIGNoYXJhY3RlcnMsIGNvbnZlcnQgZmlyc3QgY2hhcmFjdGVyIGFsb25lCiAgICBpID0gMTsKICAgIHJ2YWwgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChoZXhbMF0sIDE2KSk7CiAgfQogIC8vIGNvbnZlcnQgMiBjaGFyYWN0ZXJzICgxIGJ5dGUpIGF0IGEgdGltZQogIGZvcig7IGkgPCBoZXgubGVuZ3RoOyBpICs9IDIpIHsKICAgIHJ2YWwgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChoZXguc3Vic3RyKGksIDIpLCAxNikpOwogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDb252ZXJ0cyBhICdiaW5hcnknIGVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzIHRvIGhleC4KICoKICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlIHN0cmluZyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBzdHJpbmcgb2YgaGV4YWRlY2ltYWwgY2hhcmFjdGVycy4KICovCnV0aWwuYnl0ZXNUb0hleCA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgLy8gVE9ETzogZGVwcmVjYXRlOiAiRGVwcmVjYXRlZC4gVXNlIHV0aWwuYmluYXJ5LmhleC5lbmNvZGUgaW5zdGVhZC4iCiAgcmV0dXJuIHV0aWwuY3JlYXRlQnVmZmVyKGJ5dGVzKS50b0hleCgpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIDMyLWJpdCBpbnRlZ2VyIHRvIDQtYmlnLWVuZGlhbiBieXRlIHN0cmluZy4KICoKICogQHBhcmFtIGkgdGhlIGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhlIGJ5dGUgc3RyaW5nLgogKi8KdXRpbC5pbnQzMlRvQnl0ZXMgPSBmdW5jdGlvbihpKSB7CiAgcmV0dXJuICgKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiAyNCAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiAxNiAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiA4ICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpICYgMHhGRikpOwp9OwoKLy8gYmFzZTY0IGNoYXJhY3RlcnMsIHJldmVyc2UgbWFwcGluZwp2YXIgX2Jhc2U2NCA9CiAgJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89JzsKdmFyIF9iYXNlNjRJZHggPSBbCi8qNDMgLTQzID0gMCovCi8qJysnLCAgMSwgIDIsICAzLCcvJyAqLwogICA2MiwgLTEsIC0xLCAtMSwgNjMsCgovKicwJywnMScsJzInLCczJywnNCcsJzUnLCc2JywnNycsJzgnLCc5JyAqLwogICA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwKCi8qMTUsIDE2LCAxNywnPScsIDE5LCAyMCwgMjEgKi8KICAtMSwgLTEsIC0xLCA2NCwgLTEsIC0xLCAtMSwKCi8qNjUgLSA0MyA9IDIyKi8KLyonQScsJ0InLCdDJywnRCcsJ0UnLCdGJywnRycsJ0gnLCdJJywnSicsJ0snLCdMJywnTScsICovCiAgIDAsICAxLCAgMiwgIDMsICA0LCAgNSwgIDYsICA3LCAgOCwgIDksIDEwLCAxMSwgMTIsCgovKidOJywnTycsJ1AnLCdRJywnUicsJ1MnLCdUJywnVScsJ1YnLCdXJywnWCcsJ1knLCdaJyAqLwogICAxMywgMTQsIDE1LCAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwKCi8qOTEgLSA0MyA9IDQ4ICovCi8qNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MyAqLwogIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsCgovKjk3IC0gNDMgPSA1NCovCi8qJ2EnLCdiJywnYycsJ2QnLCdlJywnZicsJ2cnLCdoJywnaScsJ2onLCdrJywnbCcsJ20nICovCiAgIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LAoKLyonbicsJ28nLCdwJywncScsJ3InLCdzJywndCcsJ3UnLCd2JywndycsJ3gnLCd5JywneicgKi8KICAgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywgNDgsIDQ5LCA1MCwgNTEKXTsKCi8qKgogKiBCYXNlNjQgZW5jb2RlcyBhICdiaW5hcnknIGVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogKgogKiBAcGFyYW0gaW5wdXQgdGhlIGJpbmFyeSBlbmNvZGVkIHN0cmluZyBvZiBieXRlcyB0byBiYXNlNjQtZW5jb2RlLgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBudW1iZXIgb2YgZW5jb2RlZCBjaGFyYWN0ZXJzIHBlciBsaW5lIHRvIHVzZSwKICogICAgICAgICAgZGVmYXVsdHMgdG8gbm9uZS4KICoKICogQHJldHVybiB0aGUgYmFzZTY0LWVuY29kZWQgb3V0cHV0LgogKi8KdXRpbC5lbmNvZGU2NCA9IGZ1bmN0aW9uKGlucHV0LCBtYXhsaW5lKSB7CiAgLy8gVE9ETzogZGVwcmVjYXRlOiAiRGVwcmVjYXRlZC4gVXNlIHV0aWwuYmluYXJ5LmJhc2U2NC5lbmNvZGUgaW5zdGVhZC4iCiAgdmFyIGxpbmUgPSAnJzsKICB2YXIgb3V0cHV0ID0gJyc7CiAgdmFyIGNocjEsIGNocjIsIGNocjM7CiAgdmFyIGkgPSAwOwogIHdoaWxlKGkgPCBpbnB1dC5sZW5ndGgpIHsKICAgIGNocjEgPSBpbnB1dC5jaGFyQ29kZUF0KGkrKyk7CiAgICBjaHIyID0gaW5wdXQuY2hhckNvZGVBdChpKyspOwogICAgY2hyMyA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTsKCiAgICAvLyBlbmNvZGUgNCBjaGFyYWN0ZXIgZ3JvdXAKICAgIGxpbmUgKz0gX2Jhc2U2NC5jaGFyQXQoY2hyMSA+PiAyKTsKICAgIGxpbmUgKz0gX2Jhc2U2NC5jaGFyQXQoKChjaHIxICYgMykgPDwgNCkgfCAoY2hyMiA+PiA0KSk7CiAgICBpZihpc05hTihjaHIyKSkgewogICAgICBsaW5lICs9ICc9PSc7CiAgICB9IGVsc2UgewogICAgICBsaW5lICs9IF9iYXNlNjQuY2hhckF0KCgoY2hyMiAmIDE1KSA8PCAyKSB8IChjaHIzID4+IDYpKTsKICAgICAgbGluZSArPSBpc05hTihjaHIzKSA/ICc9JyA6IF9iYXNlNjQuY2hhckF0KGNocjMgJiA2Myk7CiAgICB9CgogICAgaWYobWF4bGluZSAmJiBsaW5lLmxlbmd0aCA+IG1heGxpbmUpIHsKICAgICAgb3V0cHV0ICs9IGxpbmUuc3Vic3RyKDAsIG1heGxpbmUpICsgJ1xyXG4nOwogICAgICBsaW5lID0gbGluZS5zdWJzdHIobWF4bGluZSk7CiAgICB9CiAgfQogIG91dHB1dCArPSBsaW5lOwogIHJldHVybiBvdXRwdXQ7Cn07CgovKioKICogQmFzZTY0IGRlY29kZXMgYSBzdHJpbmcgaW50byBhICdiaW5hcnknIGVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogKgogKiBAcGFyYW0gaW5wdXQgdGhlIGJhc2U2NC1lbmNvZGVkIGlucHV0LgogKgogKiBAcmV0dXJuIHRoZSBiaW5hcnkgZW5jb2RlZCBzdHJpbmcuCiAqLwp1dGlsLmRlY29kZTY0ID0gZnVuY3Rpb24oaW5wdXQpIHsKICAvLyBUT0RPOiBkZXByZWNhdGU6ICJEZXByZWNhdGVkLiBVc2UgdXRpbC5iaW5hcnkuYmFzZTY0LmRlY29kZSBpbnN0ZWFkLiIKCiAgLy8gcmVtb3ZlIGFsbCBub24tYmFzZTY0IGNoYXJhY3RlcnMKICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1teQS1aYS16MC05XCtcL1w9XS9nLCAnJyk7CgogIHZhciBvdXRwdXQgPSAnJzsKICB2YXIgZW5jMSwgZW5jMiwgZW5jMywgZW5jNDsKICB2YXIgaSA9IDA7CgogIHdoaWxlKGkgPCBpbnB1dC5sZW5ndGgpIHsKICAgIGVuYzEgPSBfYmFzZTY0SWR4W2lucHV0LmNoYXJDb2RlQXQoaSsrKSAtIDQzXTsKICAgIGVuYzIgPSBfYmFzZTY0SWR4W2lucHV0LmNoYXJDb2RlQXQoaSsrKSAtIDQzXTsKICAgIGVuYzMgPSBfYmFzZTY0SWR4W2lucHV0LmNoYXJDb2RlQXQoaSsrKSAtIDQzXTsKICAgIGVuYzQgPSBfYmFzZTY0SWR4W2lucHV0LmNoYXJDb2RlQXQoaSsrKSAtIDQzXTsKCiAgICBvdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoZW5jMSA8PCAyKSB8IChlbmMyID4+IDQpKTsKICAgIGlmKGVuYzMgIT09IDY0KSB7CiAgICAgIC8vIGRlY29kZWQgYXQgbGVhc3QgMiBieXRlcwogICAgICBvdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGVuYzIgJiAxNSkgPDwgNCkgfCAoZW5jMyA+PiAyKSk7CiAgICAgIGlmKGVuYzQgIT09IDY0KSB7CiAgICAgICAgLy8gZGVjb2RlZCAzIGJ5dGVzCiAgICAgICAgb3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChlbmMzICYgMykgPDwgNikgfCBlbmM0KTsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIG91dHB1dDsKfTsKCi8qKgogKiBVVEYtOCBlbmNvZGVzIHRoZSBnaXZlbiBVVEYtMTYgZW5jb2RlZCBzdHJpbmcgKGEgc3RhbmRhcmQgSmF2YVNjcmlwdAogKiBzdHJpbmcpLiBOb24tQVNDSUkgY2hhcmFjdGVycyB3aWxsIGJlIGVuY29kZWQgYXMgbXVsdGlwbGUgYnl0ZXMgYWNjb3JkaW5nCiAqIHRvIFVURi04LgogKgogKiBAcGFyYW0gc3RyIHRoZSBzdHJpbmcgdG8gZW5jb2RlLgogKgogKiBAcmV0dXJuIHRoZSBVVEYtOCBlbmNvZGVkIHN0cmluZy4KICovCnV0aWwuZW5jb2RlVXRmOCA9IGZ1bmN0aW9uKHN0cikgewogIHJldHVybiB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoc3RyKSk7Cn07CgovKioKICogRGVjb2RlcyBhIFVURi04IGVuY29kZWQgc3RyaW5nIGludG8gYSBVVEYtMTYgc3RyaW5nLgogKgogKiBAcGFyYW0gc3RyIHRoZSBzdHJpbmcgdG8gZGVjb2RlLgogKgogKiBAcmV0dXJuIHRoZSBVVEYtMTYgZW5jb2RlZCBzdHJpbmcgKHN0YW5kYXJkIEphdmFTY3JpcHQgc3RyaW5nKS4KICovCnV0aWwuZGVjb2RlVXRmOCA9IGZ1bmN0aW9uKHN0cikgewogIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKHN0cikpOwp9OwoKLy8gYmluYXJ5IGVuY29kaW5nL2RlY29kaW5nIHRvb2xzCi8vIEZJWE1FOiBFeHBlcmltZW50YWwuIERvIG5vdCB1c2UgeWV0Lgp1dGlsLmJpbmFyeSA9IHsKICByYXc6IHt9LAogIGhleDoge30sCiAgYmFzZTY0OiB7fQp9OwoKLyoqCiAqIEVuY29kZXMgYSBVaW50OEFycmF5IGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nLiBUaGlzIGVuY29kaW5nIHVzZXMKICogYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDI1NSBmb3IgZWFjaCBjaGFyYWN0ZXIuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgVWludDhBcnJheSB0byBlbmNvZGUuCiAqCiAqIEByZXR1cm4gdGhlIGJpbmFyeS1lbmNvZGVkIHN0cmluZy4KICovCnV0aWwuYmluYXJ5LnJhdy5lbmNvZGUgPSBmdW5jdGlvbihieXRlcykgewogIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGJ5dGVzKTsKfTsKCi8qKgogKiBEZWNvZGVzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIHRvIGEgVWludDhBcnJheS4gVGhpcyBlbmNvZGluZyB1c2VzCiAqIGEgdmFsdWUgYmV0d2VlbiAwIGFuZCAyNTUgZm9yIGVhY2ggY2hhcmFjdGVyLgogKgogKiBAcGFyYW0gc3RyIHRoZSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgdG8gZGVjb2RlLgogKiBAcGFyYW0gW291dHB1dF0gYW4gb3B0aW9uYWwgVWludDhBcnJheSB0byB3cml0ZSB0aGUgb3V0cHV0IHRvOyBpZiBpdAogKiAgICAgICAgICBpcyB0b28gc21hbGwsIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4KICogQHBhcmFtIFtvZmZzZXRdIHRoZSBzdGFydCBvZmZzZXQgZm9yIHdyaXRpbmcgdG8gdGhlIG91dHB1dCAoZGVmYXVsdDogMCkuCiAqCiAqIEByZXR1cm4gdGhlIFVpbnQ4QXJyYXkgb3IgdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIGlmIG91dHB1dCB3YXMgZ2l2ZW4uCiAqLwp1dGlsLmJpbmFyeS5yYXcuZGVjb2RlID0gZnVuY3Rpb24oc3RyLCBvdXRwdXQsIG9mZnNldCkgewogIHZhciBvdXQgPSBvdXRwdXQ7CiAgaWYoIW91dCkgewogICAgb3V0ID0gbmV3IFVpbnQ4QXJyYXkoc3RyLmxlbmd0aCk7CiAgfQogIG9mZnNldCA9IG9mZnNldCB8fCAwOwogIHZhciBqID0gb2Zmc2V0OwogIGZvcih2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHsKICAgIG91dFtqKytdID0gc3RyLmNoYXJDb2RlQXQoaSk7CiAgfQogIHJldHVybiBvdXRwdXQgPyAoaiAtIG9mZnNldCkgOiBvdXQ7Cn07CgovKioKICogRW5jb2RlcyBhICdiaW5hcnknIHN0cmluZywgQXJyYXlCdWZmZXIsIERhdGFWaWV3LCBUeXBlZEFycmF5LCBvcgogKiBCeXRlQnVmZmVyIGFzIGEgc3RyaW5nIG9mIGhleGFkZWNpbWFsIGNoYXJhY3RlcnMuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZXMgdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgc3RyaW5nIG9mIGhleGFkZWNpbWFsIGNoYXJhY3RlcnMuCiAqLwp1dGlsLmJpbmFyeS5oZXguZW5jb2RlID0gdXRpbC5ieXRlc1RvSGV4OwoKLyoqCiAqIERlY29kZXMgYSBoZXgtZW5jb2RlZCBzdHJpbmcgdG8gYSBVaW50OEFycmF5LgogKgogKiBAcGFyYW0gaGV4IHRoZSBoZXhhZGVjaW1hbCBzdHJpbmcgdG8gY29udmVydC4KICogQHBhcmFtIFtvdXRwdXRdIGFuIG9wdGlvbmFsIFVpbnQ4QXJyYXkgdG8gd3JpdGUgdGhlIG91dHB1dCB0bzsgaWYgaXQKICogICAgICAgICAgaXMgdG9vIHNtYWxsLCBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCiAqIEBwYXJhbSBbb2Zmc2V0XSB0aGUgc3RhcnQgb2Zmc2V0IGZvciB3cml0aW5nIHRvIHRoZSBvdXRwdXQgKGRlZmF1bHQ6IDApLgogKgogKiBAcmV0dXJuIHRoZSBVaW50OEFycmF5IG9yIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiBpZiBvdXRwdXQgd2FzIGdpdmVuLgogKi8KdXRpbC5iaW5hcnkuaGV4LmRlY29kZSA9IGZ1bmN0aW9uKGhleCwgb3V0cHV0LCBvZmZzZXQpIHsKICB2YXIgb3V0ID0gb3V0cHV0OwogIGlmKCFvdXQpIHsKICAgIG91dCA9IG5ldyBVaW50OEFycmF5KE1hdGguY2VpbChoZXgubGVuZ3RoIC8gMikpOwogIH0KICBvZmZzZXQgPSBvZmZzZXQgfHwgMDsKICB2YXIgaSA9IDAsIGogPSBvZmZzZXQ7CiAgaWYoaGV4Lmxlbmd0aCAmIDEpIHsKICAgIC8vIG9kZCBudW1iZXIgb2YgY2hhcmFjdGVycywgY29udmVydCBmaXJzdCBjaGFyYWN0ZXIgYWxvbmUKICAgIGkgPSAxOwogICAgb3V0W2orK10gPSBwYXJzZUludChoZXhbMF0sIDE2KTsKICB9CiAgLy8gY29udmVydCAyIGNoYXJhY3RlcnMgKDEgYnl0ZSkgYXQgYSB0aW1lCiAgZm9yKDsgaSA8IGhleC5sZW5ndGg7IGkgKz0gMikgewogICAgb3V0W2orK10gPSBwYXJzZUludChoZXguc3Vic3RyKGksIDIpLCAxNik7CiAgfQogIHJldHVybiBvdXRwdXQgPyAoaiAtIG9mZnNldCkgOiBvdXQ7Cn07CgovKioKICogQmFzZTY0LWVuY29kZXMgYSBVaW50OEFycmF5LgogKgogKiBAcGFyYW0gaW5wdXQgdGhlIFVpbnQ4QXJyYXkgdG8gZW5jb2RlLgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBudW1iZXIgb2YgZW5jb2RlZCBjaGFyYWN0ZXJzIHBlciBsaW5lIHRvIHVzZSwKICogICAgICAgICAgZGVmYXVsdHMgdG8gbm9uZS4KICoKICogQHJldHVybiB0aGUgYmFzZTY0LWVuY29kZWQgb3V0cHV0IHN0cmluZy4KICovCnV0aWwuYmluYXJ5LmJhc2U2NC5lbmNvZGUgPSBmdW5jdGlvbihpbnB1dCwgbWF4bGluZSkgewogIHZhciBsaW5lID0gJyc7CiAgdmFyIG91dHB1dCA9ICcnOwogIHZhciBjaHIxLCBjaHIyLCBjaHIzOwogIHZhciBpID0gMDsKICB3aGlsZShpIDwgaW5wdXQuYnl0ZUxlbmd0aCkgewogICAgY2hyMSA9IGlucHV0W2krK107CiAgICBjaHIyID0gaW5wdXRbaSsrXTsKICAgIGNocjMgPSBpbnB1dFtpKytdOwoKICAgIC8vIGVuY29kZSA0IGNoYXJhY3RlciBncm91cAogICAgbGluZSArPSBfYmFzZTY0LmNoYXJBdChjaHIxID4+IDIpOwogICAgbGluZSArPSBfYmFzZTY0LmNoYXJBdCgoKGNocjEgJiAzKSA8PCA0KSB8IChjaHIyID4+IDQpKTsKICAgIGlmKGlzTmFOKGNocjIpKSB7CiAgICAgIGxpbmUgKz0gJz09JzsKICAgIH0gZWxzZSB7CiAgICAgIGxpbmUgKz0gX2Jhc2U2NC5jaGFyQXQoKChjaHIyICYgMTUpIDw8IDIpIHwgKGNocjMgPj4gNikpOwogICAgICBsaW5lICs9IGlzTmFOKGNocjMpID8gJz0nIDogX2Jhc2U2NC5jaGFyQXQoY2hyMyAmIDYzKTsKICAgIH0KCiAgICBpZihtYXhsaW5lICYmIGxpbmUubGVuZ3RoID4gbWF4bGluZSkgewogICAgICBvdXRwdXQgKz0gbGluZS5zdWJzdHIoMCwgbWF4bGluZSkgKyAnXHJcbic7CiAgICAgIGxpbmUgPSBsaW5lLnN1YnN0cihtYXhsaW5lKTsKICAgIH0KICB9CiAgb3V0cHV0ICs9IGxpbmU7CiAgcmV0dXJuIG91dHB1dDsKfTsKCi8qKgogKiBEZWNvZGVzIGEgYmFzZTY0LWVuY29kZWQgc3RyaW5nIHRvIGEgVWludDhBcnJheS4KICoKICogQHBhcmFtIGlucHV0IHRoZSBiYXNlNjQtZW5jb2RlZCBpbnB1dCBzdHJpbmcuCiAqIEBwYXJhbSBbb3V0cHV0XSBhbiBvcHRpb25hbCBVaW50OEFycmF5IHRvIHdyaXRlIHRoZSBvdXRwdXQgdG87IGlmIGl0CiAqICAgICAgICAgIGlzIHRvbyBzbWFsbCwgYW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLgogKiBAcGFyYW0gW29mZnNldF0gdGhlIHN0YXJ0IG9mZnNldCBmb3Igd3JpdGluZyB0byB0aGUgb3V0cHV0IChkZWZhdWx0OiAwKS4KICoKICogQHJldHVybiB0aGUgVWludDhBcnJheSBvciB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gaWYgb3V0cHV0IHdhcyBnaXZlbi4KICovCnV0aWwuYmluYXJ5LmJhc2U2NC5kZWNvZGUgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBvZmZzZXQpIHsKICB2YXIgb3V0ID0gb3V0cHV0OwogIGlmKCFvdXQpIHsKICAgIG91dCA9IG5ldyBVaW50OEFycmF5KE1hdGguY2VpbChpbnB1dC5sZW5ndGggLyA0KSAqIDMpOwogIH0KCiAgLy8gcmVtb3ZlIGFsbCBub24tYmFzZTY0IGNoYXJhY3RlcnMKICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1teQS1aYS16MC05XCtcL1w9XS9nLCAnJyk7CgogIG9mZnNldCA9IG9mZnNldCB8fCAwOwogIHZhciBlbmMxLCBlbmMyLCBlbmMzLCBlbmM0OwogIHZhciBpID0gMCwgaiA9IG9mZnNldDsKCiAgd2hpbGUoaSA8IGlucHV0Lmxlbmd0aCkgewogICAgZW5jMSA9IF9iYXNlNjRJZHhbaW5wdXQuY2hhckNvZGVBdChpKyspIC0gNDNdOwogICAgZW5jMiA9IF9iYXNlNjRJZHhbaW5wdXQuY2hhckNvZGVBdChpKyspIC0gNDNdOwogICAgZW5jMyA9IF9iYXNlNjRJZHhbaW5wdXQuY2hhckNvZGVBdChpKyspIC0gNDNdOwogICAgZW5jNCA9IF9iYXNlNjRJZHhbaW5wdXQuY2hhckNvZGVBdChpKyspIC0gNDNdOwoKICAgIG91dFtqKytdID0gKGVuYzEgPDwgMikgfCAoZW5jMiA+PiA0KTsKICAgIGlmKGVuYzMgIT09IDY0KSB7CiAgICAgIC8vIGRlY29kZWQgYXQgbGVhc3QgMiBieXRlcwogICAgICBvdXRbaisrXSA9ICgoZW5jMiAmIDE1KSA8PCA0KSB8IChlbmMzID4+IDIpOwogICAgICBpZihlbmM0ICE9PSA2NCkgewogICAgICAgIC8vIGRlY29kZWQgMyBieXRlcwogICAgICAgIG91dFtqKytdID0gKChlbmMzICYgMykgPDwgNikgfCBlbmM0OwogICAgICB9CiAgICB9CiAgfQoKICAvLyBtYWtlIHN1cmUgcmVzdWx0IGlzIHRoZSBleGFjdCBkZWNvZGVkIGxlbmd0aAogIHJldHVybiBvdXRwdXQgPwogICAgICAgICAoaiAtIG9mZnNldCkgOgogICAgICAgICBvdXQuc3ViYXJyYXkoMCwgaik7Cn07CgovLyB0ZXh0IGVuY29kaW5nL2RlY29kaW5nIHRvb2xzCi8vIEZJWE1FOiBFeHBlcmltZW50YWwuIERvIG5vdCB1c2UgeWV0Lgp1dGlsLnRleHQgPSB7CiAgdXRmODoge30sCiAgdXRmMTY6IHt9Cn07CgovKioKICogRW5jb2RlcyB0aGUgZ2l2ZW4gc3RyaW5nIGFzIFVURi04IGluIGEgVWludDhBcnJheS4KICoKICogQHBhcmFtIHN0ciB0aGUgc3RyaW5nIHRvIGVuY29kZS4KICogQHBhcmFtIFtvdXRwdXRdIGFuIG9wdGlvbmFsIFVpbnQ4QXJyYXkgdG8gd3JpdGUgdGhlIG91dHB1dCB0bzsgaWYgaXQKICogICAgICAgICAgaXMgdG9vIHNtYWxsLCBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCiAqIEBwYXJhbSBbb2Zmc2V0XSB0aGUgc3RhcnQgb2Zmc2V0IGZvciB3cml0aW5nIHRvIHRoZSBvdXRwdXQgKGRlZmF1bHQ6IDApLgogKgogKiBAcmV0dXJuIHRoZSBVaW50OEFycmF5IG9yIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiBpZiBvdXRwdXQgd2FzIGdpdmVuLgogKi8KdXRpbC50ZXh0LnV0ZjguZW5jb2RlID0gZnVuY3Rpb24oc3RyLCBvdXRwdXQsIG9mZnNldCkgewogIHN0ciA9IHV0aWwuZW5jb2RlVXRmOChzdHIpOwogIHZhciBvdXQgPSBvdXRwdXQ7CiAgaWYoIW91dCkgewogICAgb3V0ID0gbmV3IFVpbnQ4QXJyYXkoc3RyLmxlbmd0aCk7CiAgfQogIG9mZnNldCA9IG9mZnNldCB8fCAwOwogIHZhciBqID0gb2Zmc2V0OwogIGZvcih2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHsKICAgIG91dFtqKytdID0gc3RyLmNoYXJDb2RlQXQoaSk7CiAgfQogIHJldHVybiBvdXRwdXQgPyAoaiAtIG9mZnNldCkgOiBvdXQ7Cn07CgovKioKICogRGVjb2RlcyB0aGUgVVRGLTggY29udGVudHMgZnJvbSBhIFVpbnQ4QXJyYXkuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgVWludDhBcnJheSB0byBkZWNvZGUuCiAqCiAqIEByZXR1cm4gdGhlIHJlc3VsdGluZyBzdHJpbmcuCiAqLwp1dGlsLnRleHQudXRmOC5kZWNvZGUgPSBmdW5jdGlvbihieXRlcykgewogIHJldHVybiB1dGlsLmRlY29kZVV0ZjgoU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBieXRlcykpOwp9OwoKLyoqCiAqIEVuY29kZXMgdGhlIGdpdmVuIHN0cmluZyBhcyBVVEYtMTYgaW4gYSBVaW50OEFycmF5LgogKgogKiBAcGFyYW0gc3RyIHRoZSBzdHJpbmcgdG8gZW5jb2RlLgogKiBAcGFyYW0gW291dHB1dF0gYW4gb3B0aW9uYWwgVWludDhBcnJheSB0byB3cml0ZSB0aGUgb3V0cHV0IHRvOyBpZiBpdAogKiAgICAgICAgICBpcyB0b28gc21hbGwsIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4KICogQHBhcmFtIFtvZmZzZXRdIHRoZSBzdGFydCBvZmZzZXQgZm9yIHdyaXRpbmcgdG8gdGhlIG91dHB1dCAoZGVmYXVsdDogMCkuCiAqCiAqIEByZXR1cm4gdGhlIFVpbnQ4QXJyYXkgb3IgdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIGlmIG91dHB1dCB3YXMgZ2l2ZW4uCiAqLwp1dGlsLnRleHQudXRmMTYuZW5jb2RlID0gZnVuY3Rpb24oc3RyLCBvdXRwdXQsIG9mZnNldCkgewogIHZhciBvdXQgPSBvdXRwdXQ7CiAgaWYoIW91dCkgewogICAgb3V0ID0gbmV3IFVpbnQ4QXJyYXkoc3RyLmxlbmd0aCAqIDIpOwogIH0KICB2YXIgdmlldyA9IG5ldyBVaW50MTZBcnJheShvdXQuYnVmZmVyKTsKICBvZmZzZXQgPSBvZmZzZXQgfHwgMDsKICB2YXIgaiA9IG9mZnNldDsKICB2YXIgayA9IG9mZnNldDsKICBmb3IodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7CiAgICB2aWV3W2srK10gPSBzdHIuY2hhckNvZGVBdChpKTsKICAgIGogKz0gMjsKICB9CiAgcmV0dXJuIG91dHB1dCA/IChqIC0gb2Zmc2V0KSA6IG91dDsKfTsKCi8qKgogKiBEZWNvZGVzIHRoZSBVVEYtMTYgY29udGVudHMgZnJvbSBhIFVpbnQ4QXJyYXkuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgVWludDhBcnJheSB0byBkZWNvZGUuCiAqCiAqIEByZXR1cm4gdGhlIHJlc3VsdGluZyBzdHJpbmcuCiAqLwp1dGlsLnRleHQudXRmMTYuZGVjb2RlID0gZnVuY3Rpb24oYnl0ZXMpIHsKICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDE2QXJyYXkoYnl0ZXMuYnVmZmVyKSk7Cn07CgovKioKICogRGVmbGF0ZXMgdGhlIGdpdmVuIGRhdGEgdXNpbmcgYSBmbGFzaCBpbnRlcmZhY2UuCiAqCiAqIEBwYXJhbSBhcGkgdGhlIGZsYXNoIGludGVyZmFjZS4KICogQHBhcmFtIGJ5dGVzIHRoZSBkYXRhLgogKiBAcGFyYW0gcmF3IHRydWUgdG8gcmV0dXJuIG9ubHkgcmF3IGRlZmxhdGUgZGF0YSwgZmFsc2UgdG8gaW5jbHVkZSB6bGliCiAqICAgICAgICAgIGhlYWRlciBhbmQgdHJhaWxlci4KICoKICogQHJldHVybiB0aGUgZGVmbGF0ZWQgZGF0YSBhcyBhIHN0cmluZy4KICovCnV0aWwuZGVmbGF0ZSA9IGZ1bmN0aW9uKGFwaSwgYnl0ZXMsIHJhdykgewogIGJ5dGVzID0gdXRpbC5kZWNvZGU2NChhcGkuZGVmbGF0ZSh1dGlsLmVuY29kZTY0KGJ5dGVzKSkucnZhbCk7CgogIC8vIHN0cmlwIHpsaWIgaGVhZGVyIGFuZCB0cmFpbGVyIGlmIG5lY2Vzc2FyeQogIGlmKHJhdykgewogICAgLy8gemxpYiBoZWFkZXIgaXMgMiBieXRlcyAoQ01GLEZMRykgd2hlcmUgRkxHIGluZGljYXRlcyB0aGF0CiAgICAvLyB0aGVyZSBpcyBhIDQtYnl0ZSBESUNUIChhbGRlci0zMikgYmxvY2sgYmVmb3JlIHRoZSBkYXRhIGlmCiAgICAvLyBpdHMgNXRoIGJpdCBpcyBzZXQKICAgIHZhciBzdGFydCA9IDI7CiAgICB2YXIgZmxnID0gYnl0ZXMuY2hhckNvZGVBdCgxKTsKICAgIGlmKGZsZyAmIDB4MjApIHsKICAgICAgc3RhcnQgPSA2OwogICAgfQogICAgLy8gemxpYiB0cmFpbGVyIGlzIDQgYnl0ZXMgb2YgYWRsZXItMzIKICAgIGJ5dGVzID0gYnl0ZXMuc3Vic3RyaW5nKHN0YXJ0LCBieXRlcy5sZW5ndGggLSA0KTsKICB9CgogIHJldHVybiBieXRlczsKfTsKCi8qKgogKiBJbmZsYXRlcyB0aGUgZ2l2ZW4gZGF0YSB1c2luZyBhIGZsYXNoIGludGVyZmFjZS4KICoKICogQHBhcmFtIGFwaSB0aGUgZmxhc2ggaW50ZXJmYWNlLgogKiBAcGFyYW0gYnl0ZXMgdGhlIGRhdGEuCiAqIEBwYXJhbSByYXcgdHJ1ZSBpZiB0aGUgaW5jb21pbmcgZGF0YSBoYXMgbm8gemxpYiBoZWFkZXIgb3IgdHJhaWxlciBhbmQgaXMKICogICAgICAgICAgcmF3IERFRkxBVEUgZGF0YS4KICoKICogQHJldHVybiB0aGUgaW5mbGF0ZWQgZGF0YSBhcyBhIHN0cmluZywgbnVsbCBvbiBlcnJvci4KICovCnV0aWwuaW5mbGF0ZSA9IGZ1bmN0aW9uKGFwaSwgYnl0ZXMsIHJhdykgewogIC8vIFRPRE86IGFkZCB6bGliIGhlYWRlciBhbmQgdHJhaWxlciBpZiBuZWNlc3NhcnkvcG9zc2libGUKICB2YXIgcnZhbCA9IGFwaS5pbmZsYXRlKHV0aWwuZW5jb2RlNjQoYnl0ZXMpKS5ydmFsOwogIHJldHVybiAocnZhbCA9PT0gbnVsbCkgPyBudWxsIDogdXRpbC5kZWNvZGU2NChydmFsKTsKfTsKCi8qKgogKiBTZXRzIGEgc3RvcmFnZSBvYmplY3QuCiAqCiAqIEBwYXJhbSBhcGkgdGhlIHN0b3JhZ2UgaW50ZXJmYWNlLgogKiBAcGFyYW0gaWQgdGhlIHN0b3JhZ2UgSUQgdG8gdXNlLgogKiBAcGFyYW0gb2JqIHRoZSBzdG9yYWdlIG9iamVjdCwgbnVsbCB0byByZW1vdmUuCiAqLwp2YXIgX3NldFN0b3JhZ2VPYmplY3QgPSBmdW5jdGlvbihhcGksIGlkLCBvYmopIHsKICBpZighYXBpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYlN0b3JhZ2Ugbm90IGF2YWlsYWJsZS4nKTsKICB9CgogIHZhciBydmFsOwogIGlmKG9iaiA9PT0gbnVsbCkgewogICAgcnZhbCA9IGFwaS5yZW1vdmVJdGVtKGlkKTsKICB9IGVsc2UgewogICAgLy8ganNvbi1lbmNvZGUgYW5kIGJhc2U2NC1lbmNvZGUgb2JqZWN0CiAgICBvYmogPSB1dGlsLmVuY29kZTY0KEpTT04uc3RyaW5naWZ5KG9iaikpOwogICAgcnZhbCA9IGFwaS5zZXRJdGVtKGlkLCBvYmopOwogIH0KCiAgLy8gaGFuZGxlIHBvdGVudGlhbCBmbGFzaCBlcnJvcgogIGlmKHR5cGVvZihydmFsKSAhPT0gJ3VuZGVmaW5lZCcgJiYgcnZhbC5ydmFsICE9PSB0cnVlKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IocnZhbC5lcnJvci5tZXNzYWdlKTsKICAgIGVycm9yLmlkID0gcnZhbC5lcnJvci5pZDsKICAgIGVycm9yLm5hbWUgPSBydmFsLmVycm9yLm5hbWU7CiAgICB0aHJvdyBlcnJvcjsKICB9Cn07CgovKioKICogR2V0cyBhIHN0b3JhZ2Ugb2JqZWN0LgogKgogKiBAcGFyYW0gYXBpIHRoZSBzdG9yYWdlIGludGVyZmFjZS4KICogQHBhcmFtIGlkIHRoZSBzdG9yYWdlIElEIHRvIHVzZS4KICoKICogQHJldHVybiB0aGUgc3RvcmFnZSBvYmplY3QgZW50cnkgb3IgbnVsbCBpZiBub25lIGV4aXN0cy4KICovCnZhciBfZ2V0U3RvcmFnZU9iamVjdCA9IGZ1bmN0aW9uKGFwaSwgaWQpIHsKICBpZighYXBpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYlN0b3JhZ2Ugbm90IGF2YWlsYWJsZS4nKTsKICB9CgogIC8vIGdldCB0aGUgZXhpc3RpbmcgZW50cnkKICB2YXIgcnZhbCA9IGFwaS5nZXRJdGVtKGlkKTsKCiAgLyogTm90ZTogV2UgY2hlY2sgYXBpLmluaXQgYmVjYXVzZSB3ZSBjYW4ndCBkbyAoYXBpID09IGxvY2FsU3RvcmFnZSkKICAgIG9uIElFIGJlY2F1c2Ugb2YgIkNsYXNzIGRvZXNuJ3Qgc3VwcG9ydCBBdXRvbWF0aW9uIiBleGNlcHRpb24uIE9ubHkKICAgIHRoZSBmbGFzaCBhcGkgaGFzIGFuIGluaXQgbWV0aG9kIHNvIHRoaXMgd29ya3MgdG9vLCBidXQgd2UgbmVlZCBhCiAgICBiZXR0ZXIgc29sdXRpb24gaW4gdGhlIGZ1dHVyZS4gKi8KCiAgLy8gZmxhc2ggcmV0dXJucyBpdGVtIHdyYXBwZWQgaW4gYW4gb2JqZWN0LCBoYW5kbGUgc3BlY2lhbCBjYXNlCiAgaWYoYXBpLmluaXQpIHsKICAgIGlmKHJ2YWwucnZhbCA9PT0gbnVsbCkgewogICAgICBpZihydmFsLmVycm9yKSB7CiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKHJ2YWwuZXJyb3IubWVzc2FnZSk7CiAgICAgICAgZXJyb3IuaWQgPSBydmFsLmVycm9yLmlkOwogICAgICAgIGVycm9yLm5hbWUgPSBydmFsLmVycm9yLm5hbWU7CiAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgIH0KICAgICAgLy8gbm8gZXJyb3IsIGJ1dCBhbHNvIG5vIGl0ZW0KICAgICAgcnZhbCA9IG51bGw7CiAgICB9IGVsc2UgewogICAgICBydmFsID0gcnZhbC5ydmFsOwogICAgfQogIH0KCiAgLy8gaGFuZGxlIGRlY29kaW5nCiAgaWYocnZhbCAhPT0gbnVsbCkgewogICAgLy8gYmFzZTY0LWRlY29kZSBhbmQganNvbi1kZWNvZGUgZGF0YQogICAgcnZhbCA9IEpTT04ucGFyc2UodXRpbC5kZWNvZGU2NChydmFsKSk7CiAgfQoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBTdG9yZXMgYW4gaXRlbSBpbiBsb2NhbCBzdG9yYWdlLgogKgogKiBAcGFyYW0gYXBpIHRoZSBzdG9yYWdlIGludGVyZmFjZS4KICogQHBhcmFtIGlkIHRoZSBzdG9yYWdlIElEIHRvIHVzZS4KICogQHBhcmFtIGtleSB0aGUga2V5IGZvciB0aGUgaXRlbS4KICogQHBhcmFtIGRhdGEgdGhlIGRhdGEgZm9yIHRoZSBpdGVtIChhbnkgamF2YXNjcmlwdCBvYmplY3QvcHJpbWl0aXZlKS4KICovCnZhciBfc2V0SXRlbSA9IGZ1bmN0aW9uKGFwaSwgaWQsIGtleSwgZGF0YSkgewogIC8vIGdldCBzdG9yYWdlIG9iamVjdAogIHZhciBvYmogPSBfZ2V0U3RvcmFnZU9iamVjdChhcGksIGlkKTsKICBpZihvYmogPT09IG51bGwpIHsKICAgIC8vIGNyZWF0ZSBhIG5ldyBzdG9yYWdlIG9iamVjdAogICAgb2JqID0ge307CiAgfQogIC8vIHVwZGF0ZSBrZXkKICBvYmpba2V5XSA9IGRhdGE7CgogIC8vIHNldCBzdG9yYWdlIG9iamVjdAogIF9zZXRTdG9yYWdlT2JqZWN0KGFwaSwgaWQsIG9iaik7Cn07CgovKioKICogR2V0cyBhbiBpdGVtIGZyb20gbG9jYWwgc3RvcmFnZS4KICoKICogQHBhcmFtIGFwaSB0aGUgc3RvcmFnZSBpbnRlcmZhY2UuCiAqIEBwYXJhbSBpZCB0aGUgc3RvcmFnZSBJRCB0byB1c2UuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSBmb3IgdGhlIGl0ZW0uCiAqCiAqIEByZXR1cm4gdGhlIGl0ZW0uCiAqLwp2YXIgX2dldEl0ZW0gPSBmdW5jdGlvbihhcGksIGlkLCBrZXkpIHsKICAvLyBnZXQgc3RvcmFnZSBvYmplY3QKICB2YXIgcnZhbCA9IF9nZXRTdG9yYWdlT2JqZWN0KGFwaSwgaWQpOwogIGlmKHJ2YWwgIT09IG51bGwpIHsKICAgIC8vIHJldHVybiBkYXRhIGF0IGtleQogICAgcnZhbCA9IChrZXkgaW4gcnZhbCkgPyBydmFsW2tleV0gOiBudWxsOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogUmVtb3ZlcyBhbiBpdGVtIGZyb20gbG9jYWwgc3RvcmFnZS4KICoKICogQHBhcmFtIGFwaSB0aGUgc3RvcmFnZSBpbnRlcmZhY2UuCiAqIEBwYXJhbSBpZCB0aGUgc3RvcmFnZSBJRCB0byB1c2UuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSBmb3IgdGhlIGl0ZW0uCiAqLwp2YXIgX3JlbW92ZUl0ZW0gPSBmdW5jdGlvbihhcGksIGlkLCBrZXkpIHsKICAvLyBnZXQgc3RvcmFnZSBvYmplY3QKICB2YXIgb2JqID0gX2dldFN0b3JhZ2VPYmplY3QoYXBpLCBpZCk7CiAgaWYob2JqICE9PSBudWxsICYmIGtleSBpbiBvYmopIHsKICAgIC8vIHJlbW92ZSBrZXkKICAgIGRlbGV0ZSBvYmpba2V5XTsKCiAgICAvLyBzZWUgaWYgZW50cnkgaGFzIG5vIGtleXMgcmVtYWluaW5nCiAgICB2YXIgZW1wdHkgPSB0cnVlOwogICAgZm9yKHZhciBwcm9wIGluIG9iaikgewogICAgICBlbXB0eSA9IGZhbHNlOwogICAgICBicmVhazsKICAgIH0KICAgIGlmKGVtcHR5KSB7CiAgICAgIC8vIHJlbW92ZSBlbnRyeSBlbnRpcmVseSBpZiBubyBrZXlzIGFyZSBsZWZ0CiAgICAgIG9iaiA9IG51bGw7CiAgICB9CgogICAgLy8gc2V0IHN0b3JhZ2Ugb2JqZWN0CiAgICBfc2V0U3RvcmFnZU9iamVjdChhcGksIGlkLCBvYmopOwogIH0KfTsKCi8qKgogKiBDbGVhcnMgdGhlIGxvY2FsIGRpc2sgc3RvcmFnZSBpZGVudGlmaWVkIGJ5IHRoZSBnaXZlbiBJRC4KICoKICogQHBhcmFtIGFwaSB0aGUgc3RvcmFnZSBpbnRlcmZhY2UuCiAqIEBwYXJhbSBpZCB0aGUgc3RvcmFnZSBJRCB0byB1c2UuCiAqLwp2YXIgX2NsZWFySXRlbXMgPSBmdW5jdGlvbihhcGksIGlkKSB7CiAgX3NldFN0b3JhZ2VPYmplY3QoYXBpLCBpZCwgbnVsbCk7Cn07CgovKioKICogQ2FsbHMgYSBzdG9yYWdlIGZ1bmN0aW9uLgogKgogKiBAcGFyYW0gZnVuYyB0aGUgZnVuY3Rpb24gdG8gY2FsbC4KICogQHBhcmFtIGFyZ3MgdGhlIGFyZ3VtZW50cyBmb3IgdGhlIGZ1bmN0aW9uLgogKiBAcGFyYW0gbG9jYXRpb24gdGhlIGxvY2F0aW9uIGFyZ3VtZW50LgogKgogKiBAcmV0dXJuIHRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgZnVuY3Rpb24uCiAqLwp2YXIgX2NhbGxTdG9yYWdlRnVuY3Rpb24gPSBmdW5jdGlvbihmdW5jLCBhcmdzLCBsb2NhdGlvbikgewogIHZhciBydmFsID0gbnVsbDsKCiAgLy8gZGVmYXVsdCBzdG9yYWdlIHR5cGVzCiAgaWYodHlwZW9mKGxvY2F0aW9uKSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIGxvY2F0aW9uID0gWyd3ZWInLCAnZmxhc2gnXTsKICB9CgogIC8vIGFwcGx5IHN0b3JhZ2UgdHlwZXMgaW4gb3JkZXIgb2YgcHJlZmVyZW5jZQogIHZhciB0eXBlOwogIHZhciBkb25lID0gZmFsc2U7CiAgdmFyIGV4Y2VwdGlvbiA9IG51bGw7CiAgZm9yKHZhciBpZHggaW4gbG9jYXRpb24pIHsKICAgIHR5cGUgPSBsb2NhdGlvbltpZHhdOwogICAgdHJ5IHsKICAgICAgaWYodHlwZSA9PT0gJ2ZsYXNoJyB8fCB0eXBlID09PSAnYm90aCcpIHsKICAgICAgICBpZihhcmdzWzBdID09PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXNoIGxvY2FsIHN0b3JhZ2Ugbm90IGF2YWlsYWJsZS4nKTsKICAgICAgICB9CiAgICAgICAgcnZhbCA9IGZ1bmMuYXBwbHkodGhpcywgYXJncyk7CiAgICAgICAgZG9uZSA9ICh0eXBlID09PSAnZmxhc2gnKTsKICAgICAgfQogICAgICBpZih0eXBlID09PSAnd2ViJyB8fCB0eXBlID09PSAnYm90aCcpIHsKICAgICAgICBhcmdzWzBdID0gbG9jYWxTdG9yYWdlOwogICAgICAgIHJ2YWwgPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpOwogICAgICAgIGRvbmUgPSB0cnVlOwogICAgICB9CiAgICB9IGNhdGNoKGV4KSB7CiAgICAgIGV4Y2VwdGlvbiA9IGV4OwogICAgfQogICAgaWYoZG9uZSkgewogICAgICBicmVhazsKICAgIH0KICB9CgogIGlmKCFkb25lKSB7CiAgICB0aHJvdyBleGNlcHRpb247CiAgfQoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBTdG9yZXMgYW4gaXRlbSBvbiBsb2NhbCBkaXNrLgogKgogKiBUaGUgYXZhaWxhYmxlIHR5cGVzIG9mIGxvY2FsIHN0b3JhZ2UgaW5jbHVkZSAnZmxhc2gnLCAnd2ViJywgYW5kICdib3RoJy4KICoKICogVGhlIHR5cGUgJ2ZsYXNoJyByZWZlcnMgdG8gZmxhc2ggbG9jYWwgc3RvcmFnZSAoU2hhcmVkT2JqZWN0KS4gSW4gb3JkZXIKICogdG8gdXNlIGZsYXNoIGxvY2FsIHN0b3JhZ2UsIHRoZSAnYXBpJyBwYXJhbWV0ZXIgbXVzdCBiZSB2YWxpZC4gVGhlIHR5cGUKICogJ3dlYicgcmVmZXJzIHRvIFdlYlN0b3JhZ2UsIGlmIHN1cHBvcnRlZCBieSB0aGUgYnJvd3Nlci4gVGhlIHR5cGUgJ2JvdGgnCiAqIHJlZmVycyB0byBzdG9yaW5nIHVzaW5nIGJvdGggJ2ZsYXNoJyBhbmQgJ3dlYicsIG5vdCBqdXN0IG9uZSBvciB0aGUKICogb3RoZXIuCiAqCiAqIFRoZSBsb2NhdGlvbiBhcnJheSBzaG91bGQgbGlzdCB0aGUgc3RvcmFnZSB0eXBlcyB0byB1c2UgaW4gb3JkZXIgb2YKICogcHJlZmVyZW5jZToKICoKICogWydmbGFzaCddOiBmbGFzaCBvbmx5IHN0b3JhZ2UKICogWyd3ZWInXTogd2ViIG9ubHkgc3RvcmFnZQogKiBbJ2JvdGgnXTogdHJ5IHRvIHN0b3JlIGluIGJvdGgKICogWydmbGFzaCcsJ3dlYiddOiBzdG9yZSBpbiBmbGFzaCBmaXJzdCwgYnV0IGlmIG5vdCBhdmFpbGFibGUsICd3ZWInCiAqIFsnd2ViJywnZmxhc2gnXTogc3RvcmUgaW4gd2ViIGZpcnN0LCBidXQgaWYgbm90IGF2YWlsYWJsZSwgJ2ZsYXNoJwogKgogKiBUaGUgbG9jYXRpb24gYXJyYXkgZGVmYXVsdHMgdG86IFsnd2ViJywgJ2ZsYXNoJ10KICoKICogQHBhcmFtIGFwaSB0aGUgZmxhc2ggaW50ZXJmYWNlLCBudWxsIHRvIHVzZSBvbmx5IFdlYlN0b3JhZ2UuCiAqIEBwYXJhbSBpZCB0aGUgc3RvcmFnZSBJRCB0byB1c2UuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSBmb3IgdGhlIGl0ZW0uCiAqIEBwYXJhbSBkYXRhIHRoZSBkYXRhIGZvciB0aGUgaXRlbSAoYW55IGphdmFzY3JpcHQgb2JqZWN0L3ByaW1pdGl2ZSkuCiAqIEBwYXJhbSBsb2NhdGlvbiBhbiBhcnJheSB3aXRoIHRoZSBwcmVmZXJyZWQgdHlwZXMgb2Ygc3RvcmFnZSB0byB1c2UuCiAqLwp1dGlsLnNldEl0ZW0gPSBmdW5jdGlvbihhcGksIGlkLCBrZXksIGRhdGEsIGxvY2F0aW9uKSB7CiAgX2NhbGxTdG9yYWdlRnVuY3Rpb24oX3NldEl0ZW0sIGFyZ3VtZW50cywgbG9jYXRpb24pOwp9OwoKLyoqCiAqIEdldHMgYW4gaXRlbSBvbiBsb2NhbCBkaXNrLgogKgogKiBTZXQgc2V0SXRlbSgpIGZvciBkZXRhaWxzIG9uIHN0b3JhZ2UgdHlwZXMuCiAqCiAqIEBwYXJhbSBhcGkgdGhlIGZsYXNoIGludGVyZmFjZSwgbnVsbCB0byB1c2Ugb25seSBXZWJTdG9yYWdlLgogKiBAcGFyYW0gaWQgdGhlIHN0b3JhZ2UgSUQgdG8gdXNlLgogKiBAcGFyYW0ga2V5IHRoZSBrZXkgZm9yIHRoZSBpdGVtLgogKiBAcGFyYW0gbG9jYXRpb24gYW4gYXJyYXkgd2l0aCB0aGUgcHJlZmVycmVkIHR5cGVzIG9mIHN0b3JhZ2UgdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSBpdGVtLgogKi8KdXRpbC5nZXRJdGVtID0gZnVuY3Rpb24oYXBpLCBpZCwga2V5LCBsb2NhdGlvbikgewogIHJldHVybiBfY2FsbFN0b3JhZ2VGdW5jdGlvbihfZ2V0SXRlbSwgYXJndW1lbnRzLCBsb2NhdGlvbik7Cn07CgovKioKICogUmVtb3ZlcyBhbiBpdGVtIG9uIGxvY2FsIGRpc2suCiAqCiAqIFNldCBzZXRJdGVtKCkgZm9yIGRldGFpbHMgb24gc3RvcmFnZSB0eXBlcy4KICoKICogQHBhcmFtIGFwaSB0aGUgZmxhc2ggaW50ZXJmYWNlLgogKiBAcGFyYW0gaWQgdGhlIHN0b3JhZ2UgSUQgdG8gdXNlLgogKiBAcGFyYW0ga2V5IHRoZSBrZXkgZm9yIHRoZSBpdGVtLgogKiBAcGFyYW0gbG9jYXRpb24gYW4gYXJyYXkgd2l0aCB0aGUgcHJlZmVycmVkIHR5cGVzIG9mIHN0b3JhZ2UgdG8gdXNlLgogKi8KdXRpbC5yZW1vdmVJdGVtID0gZnVuY3Rpb24oYXBpLCBpZCwga2V5LCBsb2NhdGlvbikgewogIF9jYWxsU3RvcmFnZUZ1bmN0aW9uKF9yZW1vdmVJdGVtLCBhcmd1bWVudHMsIGxvY2F0aW9uKTsKfTsKCi8qKgogKiBDbGVhcnMgdGhlIGxvY2FsIGRpc2sgc3RvcmFnZSBpZGVudGlmaWVkIGJ5IHRoZSBnaXZlbiBJRC4KICoKICogU2V0IHNldEl0ZW0oKSBmb3IgZGV0YWlscyBvbiBzdG9yYWdlIHR5cGVzLgogKgogKiBAcGFyYW0gYXBpIHRoZSBmbGFzaCBpbnRlcmZhY2UgaWYgZmxhc2ggaXMgYXZhaWxhYmxlLgogKiBAcGFyYW0gaWQgdGhlIHN0b3JhZ2UgSUQgdG8gdXNlLgogKiBAcGFyYW0gbG9jYXRpb24gYW4gYXJyYXkgd2l0aCB0aGUgcHJlZmVycmVkIHR5cGVzIG9mIHN0b3JhZ2UgdG8gdXNlLgogKi8KdXRpbC5jbGVhckl0ZW1zID0gZnVuY3Rpb24oYXBpLCBpZCwgbG9jYXRpb24pIHsKICBfY2FsbFN0b3JhZ2VGdW5jdGlvbihfY2xlYXJJdGVtcywgYXJndW1lbnRzLCBsb2NhdGlvbik7Cn07CgovKioKICogUGFyc2VzIHRoZSBzY2hlbWUsIGhvc3QsIGFuZCBwb3J0IGZyb20gYW4gaHR0cChzKSB1cmwuCiAqCiAqIEBwYXJhbSBzdHIgdGhlIHVybCBzdHJpbmcuCiAqCiAqIEByZXR1cm4gdGhlIHBhcnNlZCB1cmwgb2JqZWN0IG9yIG51bGwgaWYgdGhlIHVybCBpcyBpbnZhbGlkLgogKi8KdXRpbC5wYXJzZVVybCA9IGZ1bmN0aW9uKHN0cikgewogIC8vIEZJWE1FOiB0aGlzIHJlZ2V4IGxvb2tzIGEgYml0IGJyb2tlbgogIHZhciByZWdleCA9IC9eKGh0dHBzPyk6XC9cLyhbXjomXlwvXSopOj8oXGQqKSguKikkL2c7CiAgcmVnZXgubGFzdEluZGV4ID0gMDsKICB2YXIgbSA9IHJlZ2V4LmV4ZWMoc3RyKTsKICB2YXIgdXJsID0gKG0gPT09IG51bGwpID8gbnVsbCA6IHsKICAgIGZ1bGw6IHN0ciwKICAgIHNjaGVtZTogbVsxXSwKICAgIGhvc3Q6IG1bMl0sCiAgICBwb3J0OiBtWzNdLAogICAgcGF0aDogbVs0XQogIH07CiAgaWYodXJsKSB7CiAgICB1cmwuZnVsbEhvc3QgPSB1cmwuaG9zdDsKICAgIGlmKHVybC5wb3J0KSB7CiAgICAgIGlmKHVybC5wb3J0ICE9PSA4MCAmJiB1cmwuc2NoZW1lID09PSAnaHR0cCcpIHsKICAgICAgICB1cmwuZnVsbEhvc3QgKz0gJzonICsgdXJsLnBvcnQ7CiAgICAgIH0gZWxzZSBpZih1cmwucG9ydCAhPT0gNDQzICYmIHVybC5zY2hlbWUgPT09ICdodHRwcycpIHsKICAgICAgICB1cmwuZnVsbEhvc3QgKz0gJzonICsgdXJsLnBvcnQ7CiAgICAgIH0KICAgIH0gZWxzZSBpZih1cmwuc2NoZW1lID09PSAnaHR0cCcpIHsKICAgICAgdXJsLnBvcnQgPSA4MDsKICAgIH0gZWxzZSBpZih1cmwuc2NoZW1lID09PSAnaHR0cHMnKSB7CiAgICAgIHVybC5wb3J0ID0gNDQzOwogICAgfQogICAgdXJsLmZ1bGwgPSB1cmwuc2NoZW1lICsgJzovLycgKyB1cmwuZnVsbEhvc3Q7CiAgfQogIHJldHVybiB1cmw7Cn07CgovKiBTdG9yYWdlIGZvciBxdWVyeSB2YXJpYWJsZXMgKi8KdmFyIF9xdWVyeVZhcmlhYmxlcyA9IG51bGw7CgovKioKICogUmV0dXJucyB0aGUgd2luZG93IGxvY2F0aW9uIHF1ZXJ5IHZhcmlhYmxlcy4gUXVlcnkgaXMgcGFyc2VkIG9uIHRoZSBmaXJzdAogKiBjYWxsIGFuZCB0aGUgc2FtZSBvYmplY3QgaXMgcmV0dXJuZWQgb24gc3Vic2VxdWVudCBjYWxscy4gVGhlIG1hcHBpbmcKICogaXMgZnJvbSBrZXlzIHRvIGFuIGFycmF5IG9mIHZhbHVlcy4gUGFyYW1ldGVycyB3aXRob3V0IHZhbHVlcyB3aWxsIGhhdmUKICogYW4gb2JqZWN0IGtleSBzZXQgYnV0IG5vIHZhbHVlIGFkZGVkIHRvIHRoZSB2YWx1ZSBhcnJheS4gVmFsdWVzIGFyZQogKiB1bmVzY2FwZWQuCiAqCiAqIC4uLj9rMT12MSZrMj12MjoKICogewogKiAgICJrMSI6IFsidjEiXSwKICogICAiazIiOiBbInYyIl0KICogfQogKgogKiAuLi4/azE9djEmazE9djI6CiAqIHsKICogICAiazEiOiBbInYxIiwgInYyIl0KICogfQogKgogKiAuLi4/azE9djEmazI6CiAqIHsKICogICAiazEiOiBbInYxIl0sCiAqICAgImsyIjogW10KICogfQogKgogKiAuLi4/azE9djEmazE6CiAqIHsKICogICAiazEiOiBbInYxIl0KICogfQogKgogKiAuLi4/azEmazE6CiAqIHsKICogICAiazEiOiBbXQogKiB9CiAqCiAqIEBwYXJhbSBxdWVyeSB0aGUgcXVlcnkgc3RyaW5nIHRvIHBhcnNlIChvcHRpb25hbCwgZGVmYXVsdCB0byBjYWNoZWQKICogICAgICAgICAgcmVzdWx0cyBmcm9tIHBhcnNpbmcgd2luZG93IGxvY2F0aW9uIHNlYXJjaCBxdWVyeSkuCiAqCiAqIEByZXR1cm4gb2JqZWN0IG1hcHBpbmcga2V5cyB0byB2YXJpYWJsZXMuCiAqLwp1dGlsLmdldFF1ZXJ5VmFyaWFibGVzID0gZnVuY3Rpb24ocXVlcnkpIHsKICB2YXIgcGFyc2UgPSBmdW5jdGlvbihxKSB7CiAgICB2YXIgcnZhbCA9IHt9OwogICAgdmFyIGt2cGFpcnMgPSBxLnNwbGl0KCcmJyk7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwga3ZwYWlycy5sZW5ndGg7IGkrKykgewogICAgICB2YXIgcG9zID0ga3ZwYWlyc1tpXS5pbmRleE9mKCc9Jyk7CiAgICAgIHZhciBrZXk7CiAgICAgIHZhciB2YWw7CiAgICAgIGlmKHBvcyA+IDApIHsKICAgICAgICBrZXkgPSBrdnBhaXJzW2ldLnN1YnN0cmluZygwLCBwb3MpOwogICAgICAgIHZhbCA9IGt2cGFpcnNbaV0uc3Vic3RyaW5nKHBvcyArIDEpOwogICAgICB9IGVsc2UgewogICAgICAgIGtleSA9IGt2cGFpcnNbaV07CiAgICAgICAgdmFsID0gbnVsbDsKICAgICAgfQogICAgICBpZighKGtleSBpbiBydmFsKSkgewogICAgICAgIHJ2YWxba2V5XSA9IFtdOwogICAgICB9CiAgICAgIC8vIGRpc2FsbG93IG92ZXJyaWRpbmcgb2JqZWN0IHByb3RvdHlwZSBrZXlzCiAgICAgIGlmKCEoa2V5IGluIE9iamVjdC5wcm90b3R5cGUpICYmIHZhbCAhPT0gbnVsbCkgewogICAgICAgIHJ2YWxba2V5XS5wdXNoKHVuZXNjYXBlKHZhbCkpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAgdmFyIHJ2YWw7CiAgIGlmKHR5cGVvZihxdWVyeSkgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgLy8gc2V0IGNhY2hlZCB2YXJpYWJsZXMgaWYgbmVlZGVkCiAgICAgaWYoX3F1ZXJ5VmFyaWFibGVzID09PSBudWxsKSB7CiAgICAgICBpZih0eXBlb2Yod2luZG93KSAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LmxvY2F0aW9uICYmIHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpIHsKICAgICAgICAgIC8vIHBhcnNlIHdpbmRvdyBzZWFyY2ggcXVlcnkKICAgICAgICAgIF9xdWVyeVZhcmlhYmxlcyA9IHBhcnNlKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guc3Vic3RyaW5nKDEpKTsKICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBubyBxdWVyeSB2YXJpYWJsZXMgYXZhaWxhYmxlCiAgICAgICAgICBfcXVlcnlWYXJpYWJsZXMgPSB7fTsKICAgICAgIH0KICAgICB9CiAgICAgcnZhbCA9IF9xdWVyeVZhcmlhYmxlczsKICAgfSBlbHNlIHsKICAgICAvLyBwYXJzZSBnaXZlbiBxdWVyeQogICAgIHJ2YWwgPSBwYXJzZShxdWVyeSk7CiAgIH0KICAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogUGFyc2VzIGEgZnJhZ21lbnQgaW50byBhIHBhdGggYW5kIHF1ZXJ5LiBUaGlzIG1ldGhvZCB3aWxsIHRha2UgYSBVUkkKICogZnJhZ21lbnQgYW5kIGJyZWFrIGl0IHVwIGFzIGlmIGl0IHdlcmUgdGhlIG1haW4gVVJJLiBGb3IgZXhhbXBsZToKICogICAgL2Jhci9iYXo/YT0xJmI9MgogKiByZXN1bHRzIGluOgogKiAgICB7CiAqICAgICAgIHBhdGg6IFsiYmFyIiwgImJheiJdLAogKiAgICAgICBxdWVyeTogeyJrMSI6IFsidjEiXSwgImsyIjogWyJ2MiJdfQogKiAgICB9CiAqCiAqIEByZXR1cm4gb2JqZWN0IHdpdGggYSBwYXRoIGFycmF5IGFuZCBxdWVyeSBvYmplY3QuCiAqLwp1dGlsLnBhcnNlRnJhZ21lbnQgPSBmdW5jdGlvbihmcmFnbWVudCkgewogIC8vIGRlZmF1bHQgdG8gd2hvbGUgZnJhZ21lbnQKICB2YXIgZnAgPSBmcmFnbWVudDsKICB2YXIgZnEgPSAnJzsKICAvLyBzcGxpdCBpbnRvIHBhdGggYW5kIHF1ZXJ5IGlmIHBvc3NpYmxlIGF0IHRoZSBmaXJzdCAnPycKICB2YXIgcG9zID0gZnJhZ21lbnQuaW5kZXhPZignPycpOwogIGlmKHBvcyA+IDApIHsKICAgIGZwID0gZnJhZ21lbnQuc3Vic3RyaW5nKDAsIHBvcyk7CiAgICBmcSA9IGZyYWdtZW50LnN1YnN0cmluZyhwb3MgKyAxKTsKICB9CiAgLy8gc3BsaXQgcGF0aCBiYXNlZCBvbiAnLycgYW5kIGlnbm9yZSBmaXJzdCBlbGVtZW50IGlmIGVtcHR5CiAgdmFyIHBhdGggPSBmcC5zcGxpdCgnLycpOwogIGlmKHBhdGgubGVuZ3RoID4gMCAmJiBwYXRoWzBdID09PSAnJykgewogICAgcGF0aC5zaGlmdCgpOwogIH0KICAvLyBjb252ZXJ0IHF1ZXJ5IGludG8gb2JqZWN0CiAgdmFyIHF1ZXJ5ID0gKGZxID09PSAnJykgPyB7fSA6IHV0aWwuZ2V0UXVlcnlWYXJpYWJsZXMoZnEpOwoKICByZXR1cm4gewogICAgcGF0aFN0cmluZzogZnAsCiAgICBxdWVyeVN0cmluZzogZnEsCiAgICBwYXRoOiBwYXRoLAogICAgcXVlcnk6IHF1ZXJ5CiAgfTsKfTsKCi8qKgogKiBNYWtlcyBhIHJlcXVlc3Qgb3V0IG9mIGEgVVJJLWxpa2UgcmVxdWVzdCBzdHJpbmcuIFRoaXMgaXMgaW50ZW5kZWQgdG8KICogYmUgdXNlZCB3aGVyZSBhIGZyYWdtZW50IGlkIChhZnRlciBhIFVSSSAnIycpIGlzIHBhcnNlZCBhcyBhIFVSSSB3aXRoCiAqIHBhdGggYW5kIHF1ZXJ5IHBhcnRzLiBUaGUgc3RyaW5nIHNob3VsZCBoYXZlIGEgcGF0aCBiZWdpbm5pbmcgYW5kCiAqIGRlbGltaXRlZCBieSAnLycgYW5kIG9wdGlvbmFsIHF1ZXJ5IHBhcmFtZXRlcnMgZm9sbG93aW5nIGEgJz8nLiBUaGUKICogcXVlcnkgc2hvdWxkIGJlIGEgc3RhbmRhcmQgVVJMIHNldCBvZiBrZXkgdmFsdWUgcGFpcnMgZGVsaW1pdGVkIGJ5CiAqICcmJy4gRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHRoZSBpbml0aWFsICcvJyBvbiB0aGUgcGF0aCBpcyBub3QKICogcmVxdWlyZWQuIFRoZSByZXF1ZXN0IG9iamVjdCBoYXMgdGhlIGZvbGxvd2luZyBBUEksIChmdWxseSBkZXNjcmliZWQKICogaW4gdGhlIG1ldGhvZCBjb2RlKToKICogICAgewogKiAgICAgICBwYXRoOiA8dGhlIHBhdGggc3RyaW5nIHBhcnQ+LgogKiAgICAgICBxdWVyeTogPHRoZSBxdWVyeSBzdHJpbmcgcGFydD4sCiAqICAgICAgIGdldFBhdGgoaSk6IGdldCBwYXJ0IG9yIGFsbCBvZiB0aGUgc3BsaXQgcGF0aCBhcnJheSwKICogICAgICAgZ2V0UXVlcnkoaywgaSk6IGdldCBwYXJ0IG9yIGFsbCBvZiBhIHF1ZXJ5IGtleSBhcnJheSwKICogICAgICAgZ2V0UXVlcnlMYXN0KGssIF9kZWZhdWx0KTogZ2V0IGxhc3QgZWxlbWVudCBvZiBhIHF1ZXJ5IGtleSBhcnJheS4KICogICAgfQogKgogKiBAcmV0dXJuIG9iamVjdCB3aXRoIHJlcXVlc3QgcGFyYW1ldGVycy4KICovCnV0aWwubWFrZVJlcXVlc3QgPSBmdW5jdGlvbihyZXFTdHJpbmcpIHsKICB2YXIgZnJhZyA9IHV0aWwucGFyc2VGcmFnbWVudChyZXFTdHJpbmcpOwogIHZhciByZXEgPSB7CiAgICAvLyBmdWxsIHBhdGggc3RyaW5nCiAgICBwYXRoOiBmcmFnLnBhdGhTdHJpbmcsCiAgICAvLyBmdWxsIHF1ZXJ5IHN0cmluZwogICAgcXVlcnk6IGZyYWcucXVlcnlTdHJpbmcsCiAgICAvKioKICAgICAqIEdldCBwYXRoIG9yIGVsZW1lbnQgaW4gcGF0aC4KICAgICAqCiAgICAgKiBAcGFyYW0gaSBvcHRpb25hbCBwYXRoIGluZGV4LgogICAgICoKICAgICAqIEByZXR1cm4gcGF0aCBvciBwYXJ0IG9mIHBhdGggaWYgaSBwcm92aWRlZC4KICAgICAqLwogICAgZ2V0UGF0aDogZnVuY3Rpb24oaSkgewogICAgICByZXR1cm4gKHR5cGVvZihpKSA9PT0gJ3VuZGVmaW5lZCcpID8gZnJhZy5wYXRoIDogZnJhZy5wYXRoW2ldOwogICAgfSwKICAgIC8qKgogICAgICogR2V0IHF1ZXJ5LCB2YWx1ZXMgZm9yIGEga2V5LCBvciB2YWx1ZSBmb3IgYSBrZXkgaW5kZXguCiAgICAgKgogICAgICogQHBhcmFtIGsgb3B0aW9uYWwgcXVlcnkga2V5LgogICAgICogQHBhcmFtIGkgb3B0aW9uYWwgcXVlcnkga2V5IGluZGV4LgogICAgICoKICAgICAqIEByZXR1cm4gcXVlcnksIHZhbHVlcyBmb3IgYSBrZXksIG9yIHZhbHVlIGZvciBhIGtleSBpbmRleC4KICAgICAqLwogICAgZ2V0UXVlcnk6IGZ1bmN0aW9uKGssIGkpIHsKICAgICAgdmFyIHJ2YWw7CiAgICAgIGlmKHR5cGVvZihrKSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICBydmFsID0gZnJhZy5xdWVyeTsKICAgICAgfSBlbHNlIHsKICAgICAgICBydmFsID0gZnJhZy5xdWVyeVtrXTsKICAgICAgICBpZihydmFsICYmIHR5cGVvZihpKSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICAgICBydmFsID0gcnZhbFtpXTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIHJ2YWw7CiAgICB9LAogICAgZ2V0UXVlcnlMYXN0OiBmdW5jdGlvbihrLCBfZGVmYXVsdCkgewogICAgICB2YXIgcnZhbDsKICAgICAgdmFyIHZhbHMgPSByZXEuZ2V0UXVlcnkoayk7CiAgICAgIGlmKHZhbHMpIHsKICAgICAgICBydmFsID0gdmFsc1t2YWxzLmxlbmd0aCAtIDFdOwogICAgICB9IGVsc2UgewogICAgICAgIHJ2YWwgPSBfZGVmYXVsdDsKICAgICAgfQogICAgICByZXR1cm4gcnZhbDsKICAgIH0KICB9OwogIHJldHVybiByZXE7Cn07CgovKioKICogTWFrZXMgYSBVUkkgb3V0IG9mIGEgcGF0aCwgYW4gb2JqZWN0IHdpdGggcXVlcnkgcGFyYW1ldGVycywgYW5kIGEKICogZnJhZ21lbnQuIFVzZXMgalF1ZXJ5LnBhcmFtKCkgaW50ZXJuYWxseSBmb3IgcXVlcnkgc3RyaW5nIGNyZWF0aW9uLgogKiBJZiB0aGUgcGF0aCBpcyBhbiBhcnJheSwgaXQgd2lsbCBiZSBqb2luZWQgd2l0aCAnLycuCiAqCiAqIEBwYXJhbSBwYXRoIHN0cmluZyBwYXRoIG9yIGFycmF5IG9mIHN0cmluZ3MuCiAqIEBwYXJhbSBxdWVyeSBvYmplY3Qgd2l0aCBxdWVyeSBwYXJhbWV0ZXJzLiAob3B0aW9uYWwpCiAqIEBwYXJhbSBmcmFnbWVudCBmcmFnbWVudCBzdHJpbmcuIChvcHRpb25hbCkKICoKICogQHJldHVybiBzdHJpbmcgb2JqZWN0IHdpdGggcmVxdWVzdCBwYXJhbWV0ZXJzLgogKi8KdXRpbC5tYWtlTGluayA9IGZ1bmN0aW9uKHBhdGgsIHF1ZXJ5LCBmcmFnbWVudCkgewogIC8vIGpvaW4gcGF0aCBwYXJ0cyBpZiBuZWVkZWQKICBwYXRoID0galF1ZXJ5LmlzQXJyYXkocGF0aCkgPyBwYXRoLmpvaW4oJy8nKSA6IHBhdGg7CgogIHZhciBxc3RyID0galF1ZXJ5LnBhcmFtKHF1ZXJ5IHx8IHt9KTsKICBmcmFnbWVudCA9IGZyYWdtZW50IHx8ICcnOwogIHJldHVybiBwYXRoICsKICAgICgocXN0ci5sZW5ndGggPiAwKSA/ICgnPycgKyBxc3RyKSA6ICcnKSArCiAgICAoKGZyYWdtZW50Lmxlbmd0aCA+IDApID8gKCcjJyArIGZyYWdtZW50KSA6ICcnKTsKfTsKCi8qKgogKiBGb2xsb3dzIGEgcGF0aCBvZiBrZXlzIGRlZXAgaW50byBhbiBvYmplY3QgaGllcmFyY2h5IGFuZCBzZXQgYSB2YWx1ZS4KICogSWYgYSBrZXkgZG9lcyBub3QgZXhpc3Qgb3IgaXQncyB2YWx1ZSBpcyBub3QgYW4gb2JqZWN0LCBjcmVhdGUgYW4KICogb2JqZWN0IGluIGl0J3MgcGxhY2UuIFRoaXMgY2FuIGJlIGRlc3RydWN0aXZlIHRvIGEgb2JqZWN0IHRyZWUgaWYKICogbGVhZiBub2RlcyBhcmUgZ2l2ZW4gYXMgbm9uLWZpbmFsIHBhdGgga2V5cy4KICogVXNlZCB0byBhdm9pZCBleGNlcHRpb25zIGZyb20gbWlzc2luZyBwYXJ0cyBvZiB0aGUgcGF0aC4KICoKICogQHBhcmFtIG9iamVjdCB0aGUgc3RhcnRpbmcgb2JqZWN0LgogKiBAcGFyYW0ga2V5cyBhbiBhcnJheSBvZiBzdHJpbmcga2V5cy4KICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSB0byBzZXQuCiAqLwp1dGlsLnNldFBhdGggPSBmdW5jdGlvbihvYmplY3QsIGtleXMsIHZhbHVlKSB7CiAgLy8gbmVlZCB0byBzdGFydCBhdCBhbiBvYmplY3QKICBpZih0eXBlb2Yob2JqZWN0KSA9PT0gJ29iamVjdCcgJiYgb2JqZWN0ICE9PSBudWxsKSB7CiAgICB2YXIgaSA9IDA7CiAgICB2YXIgbGVuID0ga2V5cy5sZW5ndGg7CiAgICB3aGlsZShpIDwgbGVuKSB7CiAgICAgIHZhciBuZXh0ID0ga2V5c1tpKytdOwogICAgICBpZihpID09IGxlbikgewogICAgICAgIC8vIGxhc3QKICAgICAgICBvYmplY3RbbmV4dF0gPSB2YWx1ZTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBtb3JlCiAgICAgICAgdmFyIGhhc05leHQgPSAobmV4dCBpbiBvYmplY3QpOwogICAgICAgIGlmKCFoYXNOZXh0IHx8CiAgICAgICAgICAoaGFzTmV4dCAmJiB0eXBlb2Yob2JqZWN0W25leHRdKSAhPT0gJ29iamVjdCcpIHx8CiAgICAgICAgICAoaGFzTmV4dCAmJiBvYmplY3RbbmV4dF0gPT09IG51bGwpKSB7CiAgICAgICAgICBvYmplY3RbbmV4dF0gPSB7fTsKICAgICAgICB9CiAgICAgICAgb2JqZWN0ID0gb2JqZWN0W25leHRdOwogICAgICB9CiAgICB9CiAgfQp9OwoKLyoqCiAqIEZvbGxvd3MgYSBwYXRoIG9mIGtleXMgZGVlcCBpbnRvIGFuIG9iamVjdCBoaWVyYXJjaHkgYW5kIHJldHVybiBhIHZhbHVlLgogKiBJZiBhIGtleSBkb2VzIG5vdCBleGlzdCwgY3JlYXRlIGFuIG9iamVjdCBpbiBpdCdzIHBsYWNlLgogKiBVc2VkIHRvIGF2b2lkIGV4Y2VwdGlvbnMgZnJvbSBtaXNzaW5nIHBhcnRzIG9mIHRoZSBwYXRoLgogKgogKiBAcGFyYW0gb2JqZWN0IHRoZSBzdGFydGluZyBvYmplY3QuCiAqIEBwYXJhbSBrZXlzIGFuIGFycmF5IG9mIHN0cmluZyBrZXlzLgogKiBAcGFyYW0gX2RlZmF1bHQgdmFsdWUgdG8gcmV0dXJuIGlmIHBhdGggbm90IGZvdW5kLgogKgogKiBAcmV0dXJuIHRoZSB2YWx1ZSBhdCB0aGUgcGF0aCBpZiBmb3VuZCwgZWxzZSBkZWZhdWx0IGlmIGdpdmVuLCBlbHNlCiAqICAgICAgICAgdW5kZWZpbmVkLgogKi8KdXRpbC5nZXRQYXRoID0gZnVuY3Rpb24ob2JqZWN0LCBrZXlzLCBfZGVmYXVsdCkgewogIHZhciBpID0gMDsKICB2YXIgbGVuID0ga2V5cy5sZW5ndGg7CiAgdmFyIGhhc05leHQgPSB0cnVlOwogIHdoaWxlKGhhc05leHQgJiYgaSA8IGxlbiAmJgogICAgdHlwZW9mKG9iamVjdCkgPT09ICdvYmplY3QnICYmIG9iamVjdCAhPT0gbnVsbCkgewogICAgdmFyIG5leHQgPSBrZXlzW2krK107CiAgICBoYXNOZXh0ID0gbmV4dCBpbiBvYmplY3Q7CiAgICBpZihoYXNOZXh0KSB7CiAgICAgIG9iamVjdCA9IG9iamVjdFtuZXh0XTsKICAgIH0KICB9CiAgcmV0dXJuIChoYXNOZXh0ID8gb2JqZWN0IDogX2RlZmF1bHQpOwp9OwoKLyoqCiAqIEZvbGxvdyBhIHBhdGggb2Yga2V5cyBkZWVwIGludG8gYW4gb2JqZWN0IGhpZXJhcmNoeSBhbmQgZGVsZXRlIHRoZQogKiBsYXN0IG9uZS4gSWYgYSBrZXkgZG9lcyBub3QgZXhpc3QsIGRvIG5vdGhpbmcuCiAqIFVzZWQgdG8gYXZvaWQgZXhjZXB0aW9ucyBmcm9tIG1pc3NpbmcgcGFydHMgb2YgdGhlIHBhdGguCiAqCiAqIEBwYXJhbSBvYmplY3QgdGhlIHN0YXJ0aW5nIG9iamVjdC4KICogQHBhcmFtIGtleXMgYW4gYXJyYXkgb2Ygc3RyaW5nIGtleXMuCiAqLwp1dGlsLmRlbGV0ZVBhdGggPSBmdW5jdGlvbihvYmplY3QsIGtleXMpIHsKICAvLyBuZWVkIHRvIHN0YXJ0IGF0IGFuIG9iamVjdAogIGlmKHR5cGVvZihvYmplY3QpID09PSAnb2JqZWN0JyAmJiBvYmplY3QgIT09IG51bGwpIHsKICAgIHZhciBpID0gMDsKICAgIHZhciBsZW4gPSBrZXlzLmxlbmd0aDsKICAgIHdoaWxlKGkgPCBsZW4pIHsKICAgICAgdmFyIG5leHQgPSBrZXlzW2krK107CiAgICAgIGlmKGkgPT0gbGVuKSB7CiAgICAgICAgLy8gbGFzdAogICAgICAgIGRlbGV0ZSBvYmplY3RbbmV4dF07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gbW9yZQogICAgICAgIGlmKCEobmV4dCBpbiBvYmplY3QpIHx8CiAgICAgICAgICAodHlwZW9mKG9iamVjdFtuZXh0XSkgIT09ICdvYmplY3QnKSB8fAogICAgICAgICAgKG9iamVjdFtuZXh0XSA9PT0gbnVsbCkpIHsKICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgb2JqZWN0ID0gb2JqZWN0W25leHRdOwogICAgICB9CiAgICB9CiAgfQp9OwoKLyoqCiAqIENoZWNrIGlmIGFuIG9iamVjdCBpcyBlbXB0eS4KICoKICogVGFrZW4gZnJvbToKICogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82Nzk5MTUvaG93LWRvLWktdGVzdC1mb3ItYW4tZW1wdHktamF2YXNjcmlwdC1vYmplY3QtZnJvbS1qc29uLzY3OTkzNyM2Nzk5MzcKICoKICogQHBhcmFtIG9iamVjdCB0aGUgb2JqZWN0IHRvIGNoZWNrLgogKi8KdXRpbC5pc0VtcHR5ID0gZnVuY3Rpb24ob2JqKSB7CiAgZm9yKHZhciBwcm9wIGluIG9iaikgewogICAgaWYob2JqLmhhc093blByb3BlcnR5KHByb3ApKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CiAgcmV0dXJuIHRydWU7Cn07CgovKioKICogRm9ybWF0IHdpdGggc2ltcGxlIHByaW50Zi1zdHlsZSBpbnRlcnBvbGF0aW9uLgogKgogKiAlJTogbGl0ZXJhbCAnJScKICogJXMsJW86IGNvbnZlcnQgbmV4dCBhcmd1bWVudCBpbnRvIGEgc3RyaW5nLgogKgogKiBAcGFyYW0gZm9ybWF0IHRoZSBzdHJpbmcgdG8gZm9ybWF0LgogKiBAcGFyYW0gLi4uIGFyZ3VtZW50cyB0byBpbnRlcnBvbGF0ZSBpbnRvIHRoZSBmb3JtYXQgc3RyaW5nLgogKi8KdXRpbC5mb3JtYXQgPSBmdW5jdGlvbihmb3JtYXQpIHsKICB2YXIgcmUgPSAvJS4vZzsKICAvLyBjdXJyZW50IG1hdGNoCiAgdmFyIG1hdGNoOwogIC8vIGN1cnJlbnQgcGFydAogIHZhciBwYXJ0OwogIC8vIGN1cnJlbnQgYXJnIGluZGV4CiAgdmFyIGFyZ2kgPSAwOwogIC8vIGNvbGxlY3RlZCBwYXJ0cyB0byByZWNvbWJpbmUgbGF0ZXIKICB2YXIgcGFydHMgPSBbXTsKICAvLyBsYXN0IGluZGV4IGZvdW5kCiAgdmFyIGxhc3QgPSAwOwogIC8vIGxvb3Agd2hpbGUgbWF0Y2hlcyByZW1haW4KICB3aGlsZSgobWF0Y2ggPSByZS5leGVjKGZvcm1hdCkpKSB7CiAgICBwYXJ0ID0gZm9ybWF0LnN1YnN0cmluZyhsYXN0LCByZS5sYXN0SW5kZXggLSAyKTsKICAgIC8vIGRvbid0IGFkZCBlbXB0eSBzdHJpbmdzIChpZSwgcGFydHMgYmV0d2VlbiAlcyVzKQogICAgaWYocGFydC5sZW5ndGggPiAwKSB7CiAgICAgIHBhcnRzLnB1c2gocGFydCk7CiAgICB9CiAgICBsYXN0ID0gcmUubGFzdEluZGV4OwogICAgLy8gc3dpdGNoIG9uICUgY29kZQogICAgdmFyIGNvZGUgPSBtYXRjaFswXVsxXTsKICAgIHN3aXRjaChjb2RlKSB7CiAgICBjYXNlICdzJzoKICAgIGNhc2UgJ28nOgogICAgICAvLyBjaGVjayBpZiBlbm91Z2ggYXJndW1lbnRzIHdlcmUgZ2l2ZW4KICAgICAgaWYoYXJnaSA8IGFyZ3VtZW50cy5sZW5ndGgpIHsKICAgICAgICBwYXJ0cy5wdXNoKGFyZ3VtZW50c1thcmdpKysgKyAxXSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcGFydHMucHVzaCgnPD8+Jyk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICAvLyBGSVhNRTogZG8gcHJvcGVyIGZvcm1hdGluZyBmb3IgbnVtYmVycywgZXRjCiAgICAvL2Nhc2UgJ2YnOgogICAgLy9jYXNlICdkJzoKICAgIGNhc2UgJyUnOgogICAgICBwYXJ0cy5wdXNoKCclJyk7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgLy9wYXJ0cy5wdXNoKCc8JyArICclJyArIGNvZGUgKyAnPz4nKTsKICAgICAgcGFydHMucHVzaCgnPFx1MDAyMycgKyBjb2RlICsgJz8+Jyk7IC8vIE5lZWQgdG8gZXNjYXBlIHRoaXMgbGluZSBmb3IgQVNQLm5ldAogICAgfQogIH0KICAvLyBhZGQgdHJhaWxpbmcgcGFydCBvZiBmb3JtYXQgc3RyaW5nCiAgcGFydHMucHVzaChmb3JtYXQuc3Vic3RyaW5nKGxhc3QpKTsKICByZXR1cm4gcGFydHMuam9pbignJyk7Cn07CgovKioKICogRm9ybWF0cyBhIG51bWJlci4KICoKICogaHR0cDovL3NuaXBwbHIuY29tL3ZpZXcvNTk0NS9qYXZhc2NyaXB0LW51bWJlcmZvcm1hdC0tcG9ydGVkLWZyb20tcGhwLwogKi8KdXRpbC5mb3JtYXROdW1iZXIgPSBmdW5jdGlvbihudW1iZXIsIGRlY2ltYWxzLCBkZWNfcG9pbnQsIHRob3VzYW5kc19zZXApIHsKICAvLyBodHRwOi8va2V2aW4udmFuem9ubmV2ZWxkLm5ldAogIC8vICsgICBvcmlnaW5hbCBieTogSm9uYXMgUmFvbmkgU29hcmVzIFNpbHZhIChodHRwOi8vd3d3LmpzZnJvbWhlbGwuY29tKQogIC8vICsgICBpbXByb3ZlZCBieTogS2V2aW4gdmFuIFpvbm5ldmVsZCAoaHR0cDovL2tldmluLnZhbnpvbm5ldmVsZC5uZXQpCiAgLy8gKyAgICAgYnVnZml4IGJ5OiBNaWNoYWVsIFdoaXRlIChodHRwOi8vY3Jlc3RpZGcuY29tKQogIC8vICsgICAgIGJ1Z2ZpeCBieTogQmVuamFtaW4gTHVwdG9uCiAgLy8gKyAgICAgYnVnZml4IGJ5OiBBbGxhbiBKZW5zZW4gKGh0dHA6Ly93d3cud2ludGVybmV0Lm5vKQogIC8vICsgICAgcmV2aXNlZCBieTogSm9uYXMgUmFvbmkgU29hcmVzIFNpbHZhIChodHRwOi8vd3d3LmpzZnJvbWhlbGwuY29tKQogIC8vICogICAgIGV4YW1wbGUgMTogbnVtYmVyX2Zvcm1hdCgxMjM0LjU2NzgsIDIsICcuJywgJycpOwogIC8vICogICAgIHJldHVybnMgMTogMTIzNC41NwoKICB2YXIgbiA9IG51bWJlciwgYyA9IGlzTmFOKGRlY2ltYWxzID0gTWF0aC5hYnMoZGVjaW1hbHMpKSA/IDIgOiBkZWNpbWFsczsKICB2YXIgZCA9IGRlY19wb2ludCA9PT0gdW5kZWZpbmVkID8gJywnIDogZGVjX3BvaW50OwogIHZhciB0ID0gdGhvdXNhbmRzX3NlcCA9PT0gdW5kZWZpbmVkID8KICAgJy4nIDogdGhvdXNhbmRzX3NlcCwgcyA9IG4gPCAwID8gJy0nIDogJyc7CiAgdmFyIGkgPSBwYXJzZUludCgobiA9IE1hdGguYWJzKCtuIHx8IDApLnRvRml4ZWQoYykpLCAxMCkgKyAnJzsKICB2YXIgaiA9IChpLmxlbmd0aCA+IDMpID8gaS5sZW5ndGggJSAzIDogMDsKICByZXR1cm4gcyArIChqID8gaS5zdWJzdHIoMCwgaikgKyB0IDogJycpICsKICAgIGkuc3Vic3RyKGopLnJlcGxhY2UoLyhcZHszfSkoPz1cZCkvZywgJyQxJyArIHQpICsKICAgIChjID8gZCArIE1hdGguYWJzKG4gLSBpKS50b0ZpeGVkKGMpLnNsaWNlKDIpIDogJycpOwp9OwoKLyoqCiAqIEZvcm1hdHMgYSBieXRlIHNpemUuCiAqCiAqIGh0dHA6Ly9zbmlwcGxyLmNvbS92aWV3LzU5NDkvZm9ybWF0LWh1bWFuaXplLWZpbGUtYnl0ZS1zaXplLXByZXNlbnRhdGlvbi1pbi1qYXZhc2NyaXB0LwogKi8KdXRpbC5mb3JtYXRTaXplID0gZnVuY3Rpb24oc2l6ZSkgewogIGlmKHNpemUgPj0gMTA3Mzc0MTgyNCkgewogICAgc2l6ZSA9IHV0aWwuZm9ybWF0TnVtYmVyKHNpemUgLyAxMDczNzQxODI0LCAyLCAnLicsICcnKSArICcgR2lCJzsKICB9IGVsc2UgaWYoc2l6ZSA+PSAxMDQ4NTc2KSB7CiAgICBzaXplID0gdXRpbC5mb3JtYXROdW1iZXIoc2l6ZSAvIDEwNDg1NzYsIDIsICcuJywgJycpICsgJyBNaUInOwogIH0gZWxzZSBpZihzaXplID49IDEwMjQpIHsKICAgIHNpemUgPSB1dGlsLmZvcm1hdE51bWJlcihzaXplIC8gMTAyNCwgMCkgKyAnIEtpQic7CiAgfSBlbHNlIHsKICAgIHNpemUgPSB1dGlsLmZvcm1hdE51bWJlcihzaXplLCAwKSArICcgYnl0ZXMnOwogIH0KICByZXR1cm4gc2l6ZTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhbiBJUHY0IG9yIElQdjYgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGludG8gYnl0ZXMgKGluIG5ldHdvcmsgb3JkZXIpLgogKgogKiBAcGFyYW0gaXAgdGhlIElQdjQgb3IgSVB2NiBhZGRyZXNzIHRvIGNvbnZlcnQuCiAqCiAqIEByZXR1cm4gdGhlIDQtYnl0ZSBJUHY2IG9yIDE2LWJ5dGUgSVB2NiBhZGRyZXNzIG9yIG51bGwgaWYgdGhlIGFkZHJlc3MgY2FuJ3QKICogICAgICAgICBiZSBwYXJzZWQuCiAqLwp1dGlsLmJ5dGVzRnJvbUlQID0gZnVuY3Rpb24oaXApIHsKICBpZihpcC5pbmRleE9mKCcuJykgIT09IC0xKSB7CiAgICByZXR1cm4gdXRpbC5ieXRlc0Zyb21JUHY0KGlwKTsKICB9CiAgaWYoaXAuaW5kZXhPZignOicpICE9PSAtMSkgewogICAgcmV0dXJuIHV0aWwuYnl0ZXNGcm9tSVB2NihpcCk7CiAgfQogIHJldHVybiBudWxsOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIElQdjQgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGludG8gYnl0ZXMgKGluIG5ldHdvcmsgb3JkZXIpLgogKgogKiBAcGFyYW0gaXAgdGhlIElQdjQgYWRkcmVzcyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSA0LWJ5dGUgYWRkcmVzcyBvciBudWxsIGlmIHRoZSBhZGRyZXNzIGNhbid0IGJlIHBhcnNlZC4KICovCnV0aWwuYnl0ZXNGcm9tSVB2NCA9IGZ1bmN0aW9uKGlwKSB7CiAgaXAgPSBpcC5zcGxpdCgnLicpOwogIGlmKGlwLmxlbmd0aCAhPT0gNCkgewogICAgcmV0dXJuIG51bGw7CiAgfQogIHZhciBiID0gdXRpbC5jcmVhdGVCdWZmZXIoKTsKICBmb3IodmFyIGkgPSAwOyBpIDwgaXAubGVuZ3RoOyArK2kpIHsKICAgIHZhciBudW0gPSBwYXJzZUludChpcFtpXSwgMTApOwogICAgaWYoaXNOYU4obnVtKSkgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIGIucHV0Qnl0ZShudW0pOwogIH0KICByZXR1cm4gYi5nZXRCeXRlcygpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIElQdjYgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGludG8gYnl0ZXMgKGluIG5ldHdvcmsgb3JkZXIpLgogKgogKiBAcGFyYW0gaXAgdGhlIElQdjYgYWRkcmVzcyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSAxNi1ieXRlIGFkZHJlc3Mgb3IgbnVsbCBpZiB0aGUgYWRkcmVzcyBjYW4ndCBiZSBwYXJzZWQuCiAqLwp1dGlsLmJ5dGVzRnJvbUlQdjYgPSBmdW5jdGlvbihpcCkgewogIHZhciBibGFua3MgPSAwOwogIGlwID0gaXAuc3BsaXQoJzonKS5maWx0ZXIoZnVuY3Rpb24oZSkgewogICAgaWYoZS5sZW5ndGggPT09IDApICsrYmxhbmtzOwogICAgcmV0dXJuIHRydWU7CiAgfSk7CiAgdmFyIHplcm9zID0gKDggLSBpcC5sZW5ndGggKyBibGFua3MpICogMjsKICB2YXIgYiA9IHV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgZm9yKHZhciBpID0gMDsgaSA8IDg7ICsraSkgewogICAgaWYoIWlwW2ldIHx8IGlwW2ldLmxlbmd0aCA9PT0gMCkgewogICAgICBiLmZpbGxXaXRoQnl0ZSgwLCB6ZXJvcyk7CiAgICAgIHplcm9zID0gMDsKICAgICAgY29udGludWU7CiAgICB9CiAgICB2YXIgYnl0ZXMgPSB1dGlsLmhleFRvQnl0ZXMoaXBbaV0pOwogICAgaWYoYnl0ZXMubGVuZ3RoIDwgMikgewogICAgICBiLnB1dEJ5dGUoMCk7CiAgICB9CiAgICBiLnB1dEJ5dGVzKGJ5dGVzKTsKICB9CiAgcmV0dXJuIGIuZ2V0Qnl0ZXMoKTsKfTsKCi8qKgogKiBDb252ZXJ0cyA0LWJ5dGVzIGludG8gYW4gSVB2NCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb3IgMTYtYnl0ZXMgaW50bwogKiBhbiBJUHY2IHN0cmluZyByZXByZXNlbnRhdGlvbi4gVGhlIGJ5dGVzIG11c3QgYmUgaW4gbmV0d29yayBvcmRlci4KICoKICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBJUHY0IG9yIElQdjYgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGlmIDQgb3IgMTYgYnl0ZXMsCiAqICAgICAgICAgcmVzcGVjdGl2ZWx5LCBhcmUgZ2l2ZW4sIG90aGVyd2lzZSBudWxsLgogKi8KdXRpbC5ieXRlc1RvSVAgPSBmdW5jdGlvbihieXRlcykgewogIGlmKGJ5dGVzLmxlbmd0aCA9PT0gNCkgewogICAgcmV0dXJuIHV0aWwuYnl0ZXNUb0lQdjQoYnl0ZXMpOwogIH0KICBpZihieXRlcy5sZW5ndGggPT09IDE2KSB7CiAgICByZXR1cm4gdXRpbC5ieXRlc1RvSVB2NihieXRlcyk7CiAgfQogIHJldHVybiBudWxsOwp9OwoKLyoqCiAqIENvbnZlcnRzIDQtYnl0ZXMgaW50byBhbiBJUHY0IHN0cmluZyByZXByZXNlbnRhdGlvbi4gVGhlIGJ5dGVzIG11c3QgYmUKICogaW4gbmV0d29yayBvcmRlci4KICoKICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBJUHY0IHN0cmluZyByZXByZXNlbnRhdGlvbiBvciBudWxsIGZvciBhbiBpbnZhbGlkICMgb2YgYnl0ZXMuCiAqLwp1dGlsLmJ5dGVzVG9JUHY0ID0gZnVuY3Rpb24oYnl0ZXMpIHsKICBpZihieXRlcy5sZW5ndGggIT09IDQpIHsKICAgIHJldHVybiBudWxsOwogIH0KICB2YXIgaXAgPSBbXTsKICBmb3IodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyArK2kpIHsKICAgIGlwLnB1c2goYnl0ZXMuY2hhckNvZGVBdChpKSk7CiAgfQogIHJldHVybiBpcC5qb2luKCcuJyk7Cn07CgovKioKICogQ29udmVydHMgMTYtYnl0ZXMgaW50byBhbiBJUHYxNiBzdHJpbmcgcmVwcmVzZW50YXRpb24uIFRoZSBieXRlcyBtdXN0IGJlCiAqIGluIG5ldHdvcmsgb3JkZXIuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZXMgdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgSVB2MTYgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9yIG51bGwgZm9yIGFuIGludmFsaWQgIyBvZiBieXRlcy4KICovCnV0aWwuYnl0ZXNUb0lQdjYgPSBmdW5jdGlvbihieXRlcykgewogIGlmKGJ5dGVzLmxlbmd0aCAhPT0gMTYpIHsKICAgIHJldHVybiBudWxsOwogIH0KICB2YXIgaXAgPSBbXTsKICB2YXIgemVyb0dyb3VwcyA9IFtdOwogIHZhciB6ZXJvTWF4R3JvdXAgPSAwOwogIGZvcih2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikgewogICAgdmFyIGhleCA9IHV0aWwuYnl0ZXNUb0hleChieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSk7CiAgICAvLyBjYW5vbmljYWxpemUgemVybyByZXByZXNlbnRhdGlvbgogICAgd2hpbGUoaGV4WzBdID09PSAnMCcgJiYgaGV4ICE9PSAnMCcpIHsKICAgICAgaGV4ID0gaGV4LnN1YnN0cigxKTsKICAgIH0KICAgIGlmKGhleCA9PT0gJzAnKSB7CiAgICAgIHZhciBsYXN0ID0gemVyb0dyb3Vwc1t6ZXJvR3JvdXBzLmxlbmd0aCAtIDFdOwogICAgICB2YXIgaWR4ID0gaXAubGVuZ3RoOwogICAgICBpZighbGFzdCB8fCBpZHggIT09IGxhc3QuZW5kICsgMSkgewogICAgICAgIHplcm9Hcm91cHMucHVzaCh7c3RhcnQ6IGlkeCwgZW5kOiBpZHh9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBsYXN0LmVuZCA9IGlkeDsKICAgICAgICBpZigobGFzdC5lbmQgLSBsYXN0LnN0YXJ0KSA+CiAgICAgICAgICAoemVyb0dyb3Vwc1t6ZXJvTWF4R3JvdXBdLmVuZCAtIHplcm9Hcm91cHNbemVyb01heEdyb3VwXS5zdGFydCkpIHsKICAgICAgICAgIHplcm9NYXhHcm91cCA9IHplcm9Hcm91cHMubGVuZ3RoIC0gMTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGlwLnB1c2goaGV4KTsKICB9CiAgaWYoemVyb0dyb3Vwcy5sZW5ndGggPiAwKSB7CiAgICB2YXIgZ3JvdXAgPSB6ZXJvR3JvdXBzW3plcm9NYXhHcm91cF07CiAgICAvLyBvbmx5IHNob3J0ZW4gZ3JvdXAgb2YgbGVuZ3RoID4gMAogICAgaWYoZ3JvdXAuZW5kIC0gZ3JvdXAuc3RhcnQgPiAwKSB7CiAgICAgIGlwLnNwbGljZShncm91cC5zdGFydCwgZ3JvdXAuZW5kIC0gZ3JvdXAuc3RhcnQgKyAxLCAnJyk7CiAgICAgIGlmKGdyb3VwLnN0YXJ0ID09PSAwKSB7CiAgICAgICAgaXAudW5zaGlmdCgnJyk7CiAgICAgIH0KICAgICAgaWYoZ3JvdXAuZW5kID09PSA3KSB7CiAgICAgICAgaXAucHVzaCgnJyk7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIGlwLmpvaW4oJzonKTsKfTsKCi8qKgogKiBFc3RpbWF0ZXMgdGhlIG51bWJlciBvZiBwcm9jZXNzZXMgdGhhdCBjYW4gYmUgcnVuIGNvbmN1cnJlbnRseS4gSWYKICogY3JlYXRpbmcgV2ViIFdvcmtlcnMsIGtlZXAgaW4gbWluZCB0aGF0IHRoZSBtYWluIEphdmFTY3JpcHQgcHJvY2VzcyBuZWVkcwogKiBpdHMgb3duIGNvcmUuCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgdXBkYXRlIHRydWUgdG8gZm9yY2UgYW4gdXBkYXRlIChub3QgdXNlIHRoZSBjYWNoZWQgdmFsdWUpLgogKiBAcGFyYW0gY2FsbGJhY2soZXJyLCBtYXgpIGNhbGxlZCBvbmNlIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLgogKi8KdXRpbC5lc3RpbWF0ZUNvcmVzID0gZnVuY3Rpb24ob3B0aW9ucywgY2FsbGJhY2spIHsKICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykgewogICAgY2FsbGJhY2sgPSBvcHRpb25zOwogICAgb3B0aW9ucyA9IHt9OwogIH0KICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICBpZignY29yZXMnIGluIHV0aWwgJiYgIW9wdGlvbnMudXBkYXRlKSB7CiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgdXRpbC5jb3Jlcyk7CiAgfQogIGlmKHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmCiAgICAnaGFyZHdhcmVDb25jdXJyZW5jeScgaW4gbmF2aWdhdG9yICYmCiAgICBuYXZpZ2F0b3IuaGFyZHdhcmVDb25jdXJyZW5jeSA+IDApIHsKICAgIHV0aWwuY29yZXMgPSBuYXZpZ2F0b3IuaGFyZHdhcmVDb25jdXJyZW5jeTsKICAgIHJldHVybiBjYWxsYmFjayhudWxsLCB1dGlsLmNvcmVzKTsKICB9CiAgaWYodHlwZW9mIFdvcmtlciA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIC8vIHdvcmtlcnMgbm90IGF2YWlsYWJsZQogICAgdXRpbC5jb3JlcyA9IDE7CiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgdXRpbC5jb3Jlcyk7CiAgfQogIGlmKHR5cGVvZiBCbG9iID09PSAndW5kZWZpbmVkJykgewogICAgLy8gY2FuJ3QgZXN0aW1hdGUsIGRlZmF1bHQgdG8gMgogICAgdXRpbC5jb3JlcyA9IDI7CiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgdXRpbC5jb3Jlcyk7CiAgfQoKICAvLyBjcmVhdGUgd29ya2VyIGNvbmN1cnJlbmN5IGVzdGltYXRpb24gY29kZSBhcyBibG9iCiAgdmFyIGJsb2JVcmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKG5ldyBCbG9iKFsnKCcsCiAgICBmdW5jdGlvbigpIHsKICAgICAgc2VsZi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24oZSkgewogICAgICAgIC8vIHJ1biB3b3JrZXIgZm9yIDQgbXMKICAgICAgICB2YXIgc3QgPSBEYXRlLm5vdygpOwogICAgICAgIHZhciBldCA9IHN0ICsgNDsKICAgICAgICB3aGlsZShEYXRlLm5vdygpIDwgZXQpOwogICAgICAgIHNlbGYucG9zdE1lc3NhZ2Uoe3N0OiBzdCwgZXQ6IGV0fSk7CiAgICAgIH0pOwogICAgfS50b1N0cmluZygpLAogICcpKCknXSwge3R5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0J30pKTsKCiAgLy8gdGFrZSA1IHNhbXBsZXMgdXNpbmcgMTYgd29ya2VycwogIHNhbXBsZShbXSwgNSwgMTYpOwoKICBmdW5jdGlvbiBzYW1wbGUobWF4LCBzYW1wbGVzLCBudW1Xb3JrZXJzKSB7CiAgICBpZihzYW1wbGVzID09PSAwKSB7CiAgICAgIC8vIGdldCBvdmVybGFwIGF2ZXJhZ2UKICAgICAgdmFyIGF2ZyA9IE1hdGguZmxvb3IobWF4LnJlZHVjZShmdW5jdGlvbihhdmcsIHgpIHsKICAgICAgICByZXR1cm4gYXZnICsgeDsKICAgICAgfSwgMCkgLyBtYXgubGVuZ3RoKTsKICAgICAgdXRpbC5jb3JlcyA9IE1hdGgubWF4KDEsIGF2Zyk7CiAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwoYmxvYlVybCk7CiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCB1dGlsLmNvcmVzKTsKICAgIH0KICAgIG1hcChudW1Xb3JrZXJzLCBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHsKICAgICAgbWF4LnB1c2gocmVkdWNlKG51bVdvcmtlcnMsIHJlc3VsdHMpKTsKICAgICAgc2FtcGxlKG1heCwgc2FtcGxlcyAtIDEsIG51bVdvcmtlcnMpOwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiBtYXAobnVtV29ya2VycywgY2FsbGJhY2spIHsKICAgIHZhciB3b3JrZXJzID0gW107CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG51bVdvcmtlcnM7ICsraSkgewogICAgICB2YXIgd29ya2VyID0gbmV3IFdvcmtlcihibG9iVXJsKTsKICAgICAgd29ya2VyLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbihlKSB7CiAgICAgICAgcmVzdWx0cy5wdXNoKGUuZGF0YSk7CiAgICAgICAgaWYocmVzdWx0cy5sZW5ndGggPT09IG51bVdvcmtlcnMpIHsKICAgICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBudW1Xb3JrZXJzOyArK2kpIHsKICAgICAgICAgICAgd29ya2Vyc1tpXS50ZXJtaW5hdGUoKTsKICAgICAgICAgIH0KICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHJlc3VsdHMpOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIHdvcmtlcnMucHVzaCh3b3JrZXIpOwogICAgfQogICAgZm9yKHZhciBpID0gMDsgaSA8IG51bVdvcmtlcnM7ICsraSkgewogICAgICB3b3JrZXJzW2ldLnBvc3RNZXNzYWdlKGkpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gcmVkdWNlKG51bVdvcmtlcnMsIHJlc3VsdHMpIHsKICAgIC8vIGZpbmQgb3ZlcmxhcHBpbmcgdGltZSB3aW5kb3dzCiAgICB2YXIgb3ZlcmxhcHMgPSBbXTsKICAgIGZvcih2YXIgbiA9IDA7IG4gPCBudW1Xb3JrZXJzOyArK24pIHsKICAgICAgdmFyIHIxID0gcmVzdWx0c1tuXTsKICAgICAgdmFyIG92ZXJsYXAgPSBvdmVybGFwc1tuXSA9IFtdOwogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgbnVtV29ya2VyczsgKytpKSB7CiAgICAgICAgaWYobiA9PT0gaSkgewogICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIHZhciByMiA9IHJlc3VsdHNbaV07CiAgICAgICAgaWYoKHIxLnN0ID4gcjIuc3QgJiYgcjEuc3QgPCByMi5ldCkgfHwKICAgICAgICAgIChyMi5zdCA+IHIxLnN0ICYmIHIyLnN0IDwgcjEuZXQpKSB7CiAgICAgICAgICBvdmVybGFwLnB1c2goaSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICAvLyBnZXQgbWF4aW11bSBvdmVybGFwcyAuLi4gZG9uJ3QgaW5jbHVkZSBvdmVybGFwcGluZyB3b3JrZXIgaXRzZWxmCiAgICAvLyBhcyB0aGUgbWFpbiBKUyBwcm9jZXNzIHdhcyBhbHNvIGJlaW5nIHNjaGVkdWxlZCBkdXJpbmcgdGhlIHdvcmsgYW5kCiAgICAvLyB3b3VsZCBoYXZlIHRvIGJlIHN1YnRyYWN0ZWQgZnJvbSB0aGUgZXN0aW1hdGUgYW55d2F5CiAgICByZXR1cm4gb3ZlcmxhcHMucmVkdWNlKGZ1bmN0aW9uKG1heCwgb3ZlcmxhcCkgewogICAgICByZXR1cm4gTWF0aC5tYXgobWF4LCBvdmVybGFwLmxlbmd0aCk7CiAgICB9LCAwKTsKICB9Cn07Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICd1dGlsJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3V0aWwnLFsncmVxdWlyZScsICdtb2R1bGUnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogQ2lwaGVyIGJhc2UgQVBJLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCmZvcmdlLmNpcGhlciA9IGZvcmdlLmNpcGhlciB8fCB7fTsKCi8vIHJlZ2lzdGVyZWQgYWxnb3JpdGhtcwpmb3JnZS5jaXBoZXIuYWxnb3JpdGhtcyA9IGZvcmdlLmNpcGhlci5hbGdvcml0aG1zIHx8IHt9OwoKLyoqCiAqIENyZWF0ZXMgYSBjaXBoZXIgb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8gZW5jcnlwdCBkYXRhIHVzaW5nIHRoZSBnaXZlbgogKiBhbGdvcml0aG0gYW5kIGtleS4gVGhlIGFsZ29yaXRobSBtYXkgYmUgcHJvdmlkZWQgYXMgYSBzdHJpbmcgdmFsdWUgZm9yIGEKICogcHJldmlvdXNseSByZWdpc3RlcmVkIGFsZ29yaXRobSBvciBpdCBtYXkgYmUgZ2l2ZW4gYXMgYSBjaXBoZXIgYWxnb3JpdGhtCiAqIEFQSSBvYmplY3QuCiAqCiAqIEBwYXJhbSBhbGdvcml0aG0gdGhlIGFsZ29yaXRobSB0byB1c2UsIGVpdGhlciBhIHN0cmluZyBvciBhbiBhbGdvcml0aG0gQVBJCiAqICAgICAgICAgIG9iamVjdC4KICogQHBhcmFtIGtleSB0aGUga2V5IHRvIHVzZSwgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMgb3IgYQogKiAgICAgICAgICBieXRlIGJ1ZmZlci4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZm9yZ2UuY2lwaGVyLmNyZWF0ZUNpcGhlciA9IGZ1bmN0aW9uKGFsZ29yaXRobSwga2V5KSB7CiAgdmFyIGFwaSA9IGFsZ29yaXRobTsKICBpZih0eXBlb2YgYXBpID09PSAnc3RyaW5nJykgewogICAgYXBpID0gZm9yZ2UuY2lwaGVyLmdldEFsZ29yaXRobShhcGkpOwogICAgaWYoYXBpKSB7CiAgICAgIGFwaSA9IGFwaSgpOwogICAgfQogIH0KICBpZighYXBpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGFsZ29yaXRobTogJyArIGFsZ29yaXRobSk7CiAgfQoKICAvLyBhc3N1bWUgYmxvY2sgY2lwaGVyCiAgcmV0dXJuIG5ldyBmb3JnZS5jaXBoZXIuQmxvY2tDaXBoZXIoewogICAgYWxnb3JpdGhtOiBhcGksCiAgICBrZXk6IGtleSwKICAgIGRlY3J5cHQ6IGZhbHNlCiAgfSk7Cn07CgovKioKICogQ3JlYXRlcyBhIGRlY2lwaGVyIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIGRlY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4KICogYWxnb3JpdGhtIGFuZCBrZXkuIFRoZSBhbGdvcml0aG0gbWF5IGJlIHByb3ZpZGVkIGFzIGEgc3RyaW5nIHZhbHVlIGZvciBhCiAqIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCBhbGdvcml0aG0gb3IgaXQgbWF5IGJlIGdpdmVuIGFzIGEgY2lwaGVyIGFsZ29yaXRobQogKiBBUEkgb2JqZWN0LgogKgogKiBAcGFyYW0gYWxnb3JpdGhtIHRoZSBhbGdvcml0aG0gdG8gdXNlLCBlaXRoZXIgYSBzdHJpbmcgb3IgYW4gYWxnb3JpdGhtIEFQSQogKiAgICAgICAgICBvYmplY3QuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSB0byB1c2UsIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzIG9yIGEKICogICAgICAgICAgYnl0ZSBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmNpcGhlci5jcmVhdGVEZWNpcGhlciA9IGZ1bmN0aW9uKGFsZ29yaXRobSwga2V5KSB7CiAgdmFyIGFwaSA9IGFsZ29yaXRobTsKICBpZih0eXBlb2YgYXBpID09PSAnc3RyaW5nJykgewogICAgYXBpID0gZm9yZ2UuY2lwaGVyLmdldEFsZ29yaXRobShhcGkpOwogICAgaWYoYXBpKSB7CiAgICAgIGFwaSA9IGFwaSgpOwogICAgfQogIH0KICBpZighYXBpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGFsZ29yaXRobTogJyArIGFsZ29yaXRobSk7CiAgfQoKICAvLyBhc3N1bWUgYmxvY2sgY2lwaGVyCiAgcmV0dXJuIG5ldyBmb3JnZS5jaXBoZXIuQmxvY2tDaXBoZXIoewogICAgYWxnb3JpdGhtOiBhcGksCiAgICBrZXk6IGtleSwKICAgIGRlY3J5cHQ6IHRydWUKICB9KTsKfTsKCi8qKgogKiBSZWdpc3RlcnMgYW4gYWxnb3JpdGhtIGJ5IG5hbWUuIElmIHRoZSBuYW1lIHdhcyBhbHJlYWR5IHJlZ2lzdGVyZWQsIHRoZQogKiBhbGdvcml0aG0gQVBJIG9iamVjdCB3aWxsIGJlIG92ZXJ3cml0dGVuLgogKgogKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLgogKiBAcGFyYW0gYWxnb3JpdGhtIHRoZSBhbGdvcml0aG0gQVBJIG9iamVjdC4KICovCmZvcmdlLmNpcGhlci5yZWdpc3RlckFsZ29yaXRobSA9IGZ1bmN0aW9uKG5hbWUsIGFsZ29yaXRobSkgewogIG5hbWUgPSBuYW1lLnRvVXBwZXJDYXNlKCk7CiAgZm9yZ2UuY2lwaGVyLmFsZ29yaXRobXNbbmFtZV0gPSBhbGdvcml0aG07Cn07CgovKioKICogR2V0cyBhIHJlZ2lzdGVyZWQgYWxnb3JpdGhtIGJ5IG5hbWUuCiAqCiAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0uCiAqCiAqIEByZXR1cm4gdGhlIGFsZ29yaXRobSwgaWYgZm91bmQsIG51bGwgaWYgbm90LgogKi8KZm9yZ2UuY2lwaGVyLmdldEFsZ29yaXRobSA9IGZ1bmN0aW9uKG5hbWUpIHsKICBuYW1lID0gbmFtZS50b1VwcGVyQ2FzZSgpOwogIGlmKG5hbWUgaW4gZm9yZ2UuY2lwaGVyLmFsZ29yaXRobXMpIHsKICAgIHJldHVybiBmb3JnZS5jaXBoZXIuYWxnb3JpdGhtc1tuYW1lXTsKICB9CiAgcmV0dXJuIG51bGw7Cn07Cgp2YXIgQmxvY2tDaXBoZXIgPSBmb3JnZS5jaXBoZXIuQmxvY2tDaXBoZXIgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgdGhpcy5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobTsKICB0aGlzLm1vZGUgPSB0aGlzLmFsZ29yaXRobS5tb2RlOwogIHRoaXMuYmxvY2tTaXplID0gdGhpcy5tb2RlLmJsb2NrU2l6ZTsKICB0aGlzLl9maW5pc2ggPSBmYWxzZTsKICB0aGlzLl9pbnB1dCA9IG51bGw7CiAgdGhpcy5vdXRwdXQgPSBudWxsOwogIHRoaXMuX29wID0gb3B0aW9ucy5kZWNyeXB0ID8gdGhpcy5tb2RlLmRlY3J5cHQgOiB0aGlzLm1vZGUuZW5jcnlwdDsKICB0aGlzLl9kZWNyeXB0ID0gb3B0aW9ucy5kZWNyeXB0OwogIHRoaXMuYWxnb3JpdGhtLmluaXRpYWxpemUob3B0aW9ucyk7Cn07CgovKioKICogU3RhcnRzIG9yIHJlc3RhcnRzIHRoZSBlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24gcHJvY2Vzcywgd2hpY2hldmVyCiAqIHdhcyBwcmV2aW91c2x5IGNvbmZpZ3VyZWQuCiAqCiAqIEZvciBub24tR0NNIG1vZGUsIHRoZSBJViBtYXkgYmUgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5CiAqIG9mIGJ5dGVzLCBhIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgaW50ZWdlcnMuIElmIHRoZSBJViBpcyBpbgogKiBieXRlcywgdGhlbiBpdCBtdXN0IGJlIE5iICgxNikgYnl0ZXMgaW4gbGVuZ3RoLiBJZiB0aGUgSVYgaXMgZ2l2ZW4gaW4gYXMKICogMzItYml0IGludGVnZXJzLCB0aGVuIGl0IG11c3QgYmUgNCBpbnRlZ2VycyBsb25nLgogKgogKiBOb3RlOiBhbiBJViBpcyBub3QgcmVxdWlyZWQgb3IgdXNlZCBpbiBFQ0IgbW9kZS4KICoKICogRm9yIEdDTS1tb2RlLCB0aGUgSVYgbXVzdCBiZSBnaXZlbiBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBieXRlcyBvcgogKiBhIGJ5dGUgYnVmZmVyLiBUaGUgbnVtYmVyIG9mIGJ5dGVzIHNob3VsZCBiZSAxMiAoOTYgYml0cykgYXMgcmVjb21tZW5kZWQKICogYnkgTklTVCBTUC04MDAtMzhEIGJ1dCBhbm90aGVyIGxlbmd0aCBtYXkgYmUgZ2l2ZW4uCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YKICogICAgICAgICAgICBieXRlcywgbnVsbCB0byByZXVzZSB0aGUgbGFzdCBjaXBoZXJlZCBibG9jayBmcm9tIGEgcHJldmlvdXMKICogICAgICAgICAgICB1cGRhdGUoKSAodGhpcyAicmVzaWR1ZSIgbWV0aG9kIGlzIGZvciBsZWdhY3kgc3VwcG9ydCBvbmx5KS4KICogICAgICAgICAgYWRkaXRpb25hbERhdGEgYWRkaXRpb25hbCBhdXRoZW50aWNhdGlvbiBkYXRhIGFzIGEgYmluYXJ5LWVuY29kZWQKICogICAgICAgICAgICBzdHJpbmcgb2YgYnl0ZXMsIGZvciAnR0NNJyBtb2RlLCAoZGVmYXVsdDogbm9uZSkuCiAqICAgICAgICAgIHRhZ0xlbmd0aCBkZXNpcmVkIGxlbmd0aCBvZiBhdXRoZW50aWNhdGlvbiB0YWcsIGluIGJpdHMsIGZvcgogKiAgICAgICAgICAgICdHQ00nIG1vZGUgKDAtMTI4LCBkZWZhdWx0OiAxMjgpLgogKiAgICAgICAgICB0YWcgdGhlIGF1dGhlbnRpY2F0aW9uIHRhZyB0byBjaGVjayBpZiBkZWNyeXB0aW5nLCBhcyBhCiAqICAgICAgICAgICAgIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBieXRlcy4KICogICAgICAgICAgb3V0cHV0IHRoZSBvdXRwdXQgdGhlIGJ1ZmZlciB0byB3cml0ZSB0bywgbnVsbCB0byBjcmVhdGUgb25lLgogKi8KQmxvY2tDaXBoZXIucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24ob3B0aW9ucykgewogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHZhciBvcHRzID0ge307CiAgZm9yKHZhciBrZXkgaW4gb3B0aW9ucykgewogICAgb3B0c1trZXldID0gb3B0aW9uc1trZXldOwogIH0KICBvcHRzLmRlY3J5cHQgPSB0aGlzLl9kZWNyeXB0OwogIHRoaXMuX2ZpbmlzaCA9IGZhbHNlOwogIHRoaXMuX2lucHV0ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICB0aGlzLm91dHB1dCA9IG9wdGlvbnMub3V0cHV0IHx8IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdGhpcy5tb2RlLnN0YXJ0KG9wdHMpOwp9OwoKLyoqCiAqIFVwZGF0ZXMgdGhlIG5leHQgYmxvY2sgYWNjb3JkaW5nIHRvIHRoZSBjaXBoZXIgbW9kZS4KICoKICogQHBhcmFtIGlucHV0IHRoZSBidWZmZXIgdG8gcmVhZCBmcm9tLgogKi8KQmxvY2tDaXBoZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKGlucHV0KSB7CiAgaWYoaW5wdXQpIHsKICAgIC8vIGlucHV0IGdpdmVuLCBzbyBlbXB0eSBpdCBpbnRvIHRoZSBpbnB1dCBidWZmZXIKICAgIHRoaXMuX2lucHV0LnB1dEJ1ZmZlcihpbnB1dCk7CiAgfQoKICAvLyBkbyBjaXBoZXIgb3BlcmF0aW9uIHVudGlsIGl0IG5lZWRzIG1vcmUgaW5wdXQgYW5kIG5vdCBmaW5pc2hlZAogIHdoaWxlKCF0aGlzLl9vcC5jYWxsKHRoaXMubW9kZSwgdGhpcy5faW5wdXQsIHRoaXMub3V0cHV0LCB0aGlzLl9maW5pc2gpICYmCiAgICAhdGhpcy5fZmluaXNoKSB7fQoKICAvLyBmcmVlIGNvbnN1bWVkIG1lbW9yeSBmcm9tIGlucHV0IGJ1ZmZlcgogIHRoaXMuX2lucHV0LmNvbXBhY3QoKTsKfTsKCi8qKgogKiBGaW5pc2hlcyBlbmNyeXB0aW5nIG9yIGRlY3J5cHRpbmcuCiAqCiAqIEBwYXJhbSBwYWQgYSBwYWRkaW5nIGZ1bmN0aW9uIHRvIHVzZSBpbiBDQkMgbW9kZSwgbnVsbCBmb3IgZGVmYXVsdCwKICogICAgICAgICAgc2lnbmF0dXJlKGJsb2NrU2l6ZSwgYnVmZmVyLCBkZWNyeXB0KS4KICoKICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwsIGZhbHNlIG9uIGVycm9yLgogKi8KQmxvY2tDaXBoZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uKHBhZCkgewogIC8vIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5IHcvZGVwcmVjYXRlZCBwYWRkaW5nIEFQSQogIC8vIE5vdGU6IHdpbGwgb3ZlcndyaXRlIHBhZGRpbmcgZnVuY3Rpb25zIGV2ZW4gYWZ0ZXIgYW5vdGhlciBzdGFydCgpIGNhbGwKICBpZihwYWQgJiYgKHRoaXMubW9kZS5uYW1lID09PSAnRUNCJyB8fCB0aGlzLm1vZGUubmFtZSA9PT0gJ0NCQycpKSB7CiAgICB0aGlzLm1vZGUucGFkID0gZnVuY3Rpb24oaW5wdXQpIHsKICAgICAgcmV0dXJuIHBhZCh0aGlzLmJsb2NrU2l6ZSwgaW5wdXQsIGZhbHNlKTsKICAgIH07CiAgICB0aGlzLm1vZGUudW5wYWQgPSBmdW5jdGlvbihvdXRwdXQpIHsKICAgICAgcmV0dXJuIHBhZCh0aGlzLmJsb2NrU2l6ZSwgb3V0cHV0LCB0cnVlKTsKICAgIH07CiAgfQoKICAvLyBidWlsZCBvcHRpb25zIGZvciBwYWRkaW5nIGFuZCBhZnRlckZpbmlzaCBmdW5jdGlvbnMKICB2YXIgb3B0aW9ucyA9IHt9OwogIG9wdGlvbnMuZGVjcnlwdCA9IHRoaXMuX2RlY3J5cHQ7CgogIC8vIGdldCAjIG9mIGJ5dGVzIHRoYXQgd29uJ3QgZmlsbCBhIGJsb2NrCiAgb3B0aW9ucy5vdmVyZmxvdyA9IHRoaXMuX2lucHV0Lmxlbmd0aCgpICUgdGhpcy5ibG9ja1NpemU7CgogIGlmKCF0aGlzLl9kZWNyeXB0ICYmIHRoaXMubW9kZS5wYWQpIHsKICAgIGlmKCF0aGlzLm1vZGUucGFkKHRoaXMuX2lucHV0LCBvcHRpb25zKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQoKICAvLyBkbyBmaW5hbCB1cGRhdGUKICB0aGlzLl9maW5pc2ggPSB0cnVlOwogIHRoaXMudXBkYXRlKCk7CgogIGlmKHRoaXMuX2RlY3J5cHQgJiYgdGhpcy5tb2RlLnVucGFkKSB7CiAgICBpZighdGhpcy5tb2RlLnVucGFkKHRoaXMub3V0cHV0LCBvcHRpb25zKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQoKICBpZih0aGlzLm1vZGUuYWZ0ZXJGaW5pc2gpIHsKICAgIGlmKCF0aGlzLm1vZGUuYWZ0ZXJGaW5pc2godGhpcy5vdXRwdXQsIG9wdGlvbnMpKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CgogIHJldHVybiB0cnVlOwp9OwoKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ2NpcGhlcic7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9jaXBoZXInLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFN1cHBvcnRlZCBjaXBoZXIgbW9kZXMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UuY2lwaGVyID0gZm9yZ2UuY2lwaGVyIHx8IHt9OwoKLy8gc3VwcG9ydGVkIGNpcGhlciBtb2Rlcwp2YXIgbW9kZXMgPSBmb3JnZS5jaXBoZXIubW9kZXMgPSBmb3JnZS5jaXBoZXIubW9kZXMgfHwge307CgoKLyoqIEVsZWN0cm9uaWMgY29kZWJvb2sgKEVDQikgKERvbid0IHVzZSB0aGlzOyBpdCdzIG5vdCBzZWN1cmUpICoqLwoKbW9kZXMuZWNiID0gZnVuY3Rpb24ob3B0aW9ucykgewogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHRoaXMubmFtZSA9ICdFQ0InOwogIHRoaXMuY2lwaGVyID0gb3B0aW9ucy5jaXBoZXI7CiAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLmJsb2NrU2l6ZSB8fCAxNjsKICB0aGlzLl9pbnRzID0gdGhpcy5ibG9ja1NpemUgLyA0OwogIHRoaXMuX2luQmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fb3V0QmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7Cn07Cgptb2Rlcy5lY2IucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24ob3B0aW9ucykge307Cgptb2Rlcy5lY2IucHJvdG90eXBlLmVuY3J5cHQgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBmaW5pc2gpIHsKICAvLyBub3QgZW5vdWdoIGlucHV0IHRvIGVuY3J5cHQKICBpZihpbnB1dC5sZW5ndGgoKSA8IHRoaXMuYmxvY2tTaXplICYmICEoZmluaXNoICYmIGlucHV0Lmxlbmd0aCgpID4gMCkpIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZ2V0IG5leHQgYmxvY2sKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICB0aGlzLl9pbkJsb2NrW2ldID0gaW5wdXQuZ2V0SW50MzIoKTsKICB9CgogIC8vIGVuY3J5cHQgYmxvY2sKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gd3JpdGUgb3V0cHV0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX291dEJsb2NrW2ldKTsKICB9Cn07Cgptb2Rlcy5lY2IucHJvdG90eXBlLmRlY3J5cHQgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBmaW5pc2gpIHsKICAvLyBub3QgZW5vdWdoIGlucHV0IHRvIGRlY3J5cHQKICBpZihpbnB1dC5sZW5ndGgoKSA8IHRoaXMuYmxvY2tTaXplICYmICEoZmluaXNoICYmIGlucHV0Lmxlbmd0aCgpID4gMCkpIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZ2V0IG5leHQgYmxvY2sKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICB0aGlzLl9pbkJsb2NrW2ldID0gaW5wdXQuZ2V0SW50MzIoKTsKICB9CgogIC8vIGRlY3J5cHQgYmxvY2sKICB0aGlzLmNpcGhlci5kZWNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gd3JpdGUgb3V0cHV0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX291dEJsb2NrW2ldKTsKICB9Cn07Cgptb2Rlcy5lY2IucHJvdG90eXBlLnBhZCA9IGZ1bmN0aW9uKGlucHV0LCBvcHRpb25zKSB7CiAgLy8gYWRkIFBLQ1MjNyBwYWRkaW5nIHRvIGJsb2NrIChlYWNoIHBhZCBieXRlIGlzIHRoZQogIC8vIHZhbHVlIG9mIHRoZSBudW1iZXIgb2YgcGFkIGJ5dGVzKQogIHZhciBwYWRkaW5nID0gKGlucHV0Lmxlbmd0aCgpID09PSB0aGlzLmJsb2NrU2l6ZSA/CiAgICB0aGlzLmJsb2NrU2l6ZSA6ICh0aGlzLmJsb2NrU2l6ZSAtIGlucHV0Lmxlbmd0aCgpKSk7CiAgaW5wdXQuZmlsbFdpdGhCeXRlKHBhZGRpbmcsIHBhZGRpbmcpOwogIHJldHVybiB0cnVlOwp9OwoKbW9kZXMuZWNiLnByb3RvdHlwZS51bnBhZCA9IGZ1bmN0aW9uKG91dHB1dCwgb3B0aW9ucykgewogIC8vIGNoZWNrIGZvciBlcnJvcjogaW5wdXQgZGF0YSBub3QgYSBtdWx0aXBsZSBvZiBibG9ja1NpemUKICBpZihvcHRpb25zLm92ZXJmbG93ID4gMCkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgLy8gZW5zdXJlIHBhZGRpbmcgYnl0ZSBjb3VudCBpcyB2YWxpZAogIHZhciBsZW4gPSBvdXRwdXQubGVuZ3RoKCk7CiAgdmFyIGNvdW50ID0gb3V0cHV0LmF0KGxlbiAtIDEpOwogIGlmKGNvdW50ID4gKHRoaXMuYmxvY2tTaXplIDw8IDIpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICAvLyB0cmltIG9mZiBwYWRkaW5nIGJ5dGVzCiAgb3V0cHV0LnRydW5jYXRlKGNvdW50KTsKICByZXR1cm4gdHJ1ZTsKfTsKCgovKiogQ2lwaGVyLWJsb2NrIENoYWluaW5nIChDQkMpICoqLwoKbW9kZXMuY2JjID0gZnVuY3Rpb24ob3B0aW9ucykgewogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHRoaXMubmFtZSA9ICdDQkMnOwogIHRoaXMuY2lwaGVyID0gb3B0aW9ucy5jaXBoZXI7CiAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLmJsb2NrU2l6ZSB8fCAxNjsKICB0aGlzLl9pbnRzID0gdGhpcy5ibG9ja1NpemUgLyA0OwogIHRoaXMuX2luQmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fb3V0QmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7Cn07Cgptb2Rlcy5jYmMucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24ob3B0aW9ucykgewogIC8vIE5vdGU6IGxlZ2FjeSBzdXBwb3J0IGZvciB1c2luZyBJViByZXNpZHVlIChoYXMgc2VjdXJpdHkgZmxhd3MpCiAgLy8gaWYgSVYgaXMgbnVsbCwgcmV1c2UgYmxvY2sgZnJvbSBwcmV2aW91cyBwcm9jZXNzaW5nCiAgaWYob3B0aW9ucy5pdiA9PT0gbnVsbCkgewogICAgLy8gbXVzdCBoYXZlIGEgcHJldmlvdXMgYmxvY2sKICAgIGlmKCF0aGlzLl9wcmV2KSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBJViBwYXJhbWV0ZXIuJyk7CiAgICB9CiAgICB0aGlzLl9pdiA9IHRoaXMuX3ByZXYuc2xpY2UoMCk7CiAgfSBlbHNlIGlmKCEoJ2l2JyBpbiBvcHRpb25zKSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIElWIHBhcmFtZXRlci4nKTsKICB9IGVsc2UgewogICAgLy8gc2F2ZSBJViBhcyAicHJldmlvdXMiIGJsb2NrCiAgICB0aGlzLl9pdiA9IHRyYW5zZm9ybUlWKG9wdGlvbnMuaXYpOwogICAgdGhpcy5fcHJldiA9IHRoaXMuX2l2LnNsaWNlKDApOwogIH0KfTsKCm1vZGVzLmNiYy5wcm90b3R5cGUuZW5jcnlwdCA9IGZ1bmN0aW9uKGlucHV0LCBvdXRwdXQsIGZpbmlzaCkgewogIC8vIG5vdCBlbm91Z2ggaW5wdXQgdG8gZW5jcnlwdAogIGlmKGlucHV0Lmxlbmd0aCgpIDwgdGhpcy5ibG9ja1NpemUgJiYgIShmaW5pc2ggJiYgaW5wdXQubGVuZ3RoKCkgPiAwKSkgewogICAgcmV0dXJuIHRydWU7CiAgfQoKICAvLyBnZXQgbmV4dCBibG9jawogIC8vIENCQyBYT1IncyBJViAob3IgcHJldmlvdXMgYmxvY2spIHdpdGggcGxhaW50ZXh0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgdGhpcy5faW5CbG9ja1tpXSA9IHRoaXMuX3ByZXZbaV0gXiBpbnB1dC5nZXRJbnQzMigpOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jawogIHRoaXMuY2lwaGVyLmVuY3J5cHQodGhpcy5faW5CbG9jaywgdGhpcy5fb3V0QmxvY2spOwoKICAvLyB3cml0ZSBvdXRwdXQsIHNhdmUgcHJldmlvdXMgYmxvY2sKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICBvdXRwdXQucHV0SW50MzIodGhpcy5fb3V0QmxvY2tbaV0pOwogIH0KICB0aGlzLl9wcmV2ID0gdGhpcy5fb3V0QmxvY2s7Cn07Cgptb2Rlcy5jYmMucHJvdG90eXBlLmRlY3J5cHQgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBmaW5pc2gpIHsKICAvLyBub3QgZW5vdWdoIGlucHV0IHRvIGRlY3J5cHQKICBpZihpbnB1dC5sZW5ndGgoKSA8IHRoaXMuYmxvY2tTaXplICYmICEoZmluaXNoICYmIGlucHV0Lmxlbmd0aCgpID4gMCkpIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZ2V0IG5leHQgYmxvY2sKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICB0aGlzLl9pbkJsb2NrW2ldID0gaW5wdXQuZ2V0SW50MzIoKTsKICB9CgogIC8vIGRlY3J5cHQgYmxvY2sKICB0aGlzLmNpcGhlci5kZWNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gd3JpdGUgb3V0cHV0LCBzYXZlIHByZXZpb3VzIGNpcGhlcmVkIGJsb2NrCiAgLy8gQ0JDIFhPUidzIElWIChvciBwcmV2aW91cyBibG9jaykgd2l0aCBjaXBoZXJ0ZXh0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX3ByZXZbaV0gXiB0aGlzLl9vdXRCbG9ja1tpXSk7CiAgfQogIHRoaXMuX3ByZXYgPSB0aGlzLl9pbkJsb2NrLnNsaWNlKDApOwp9OwoKbW9kZXMuY2JjLnByb3RvdHlwZS5wYWQgPSBmdW5jdGlvbihpbnB1dCwgb3B0aW9ucykgewogIC8vIGFkZCBQS0NTIzcgcGFkZGluZyB0byBibG9jayAoZWFjaCBwYWQgYnl0ZSBpcyB0aGUKICAvLyB2YWx1ZSBvZiB0aGUgbnVtYmVyIG9mIHBhZCBieXRlcykKICB2YXIgcGFkZGluZyA9IChpbnB1dC5sZW5ndGgoKSA9PT0gdGhpcy5ibG9ja1NpemUgPwogICAgdGhpcy5ibG9ja1NpemUgOiAodGhpcy5ibG9ja1NpemUgLSBpbnB1dC5sZW5ndGgoKSkpOwogIGlucHV0LmZpbGxXaXRoQnl0ZShwYWRkaW5nLCBwYWRkaW5nKTsKICByZXR1cm4gdHJ1ZTsKfTsKCm1vZGVzLmNiYy5wcm90b3R5cGUudW5wYWQgPSBmdW5jdGlvbihvdXRwdXQsIG9wdGlvbnMpIHsKICAvLyBjaGVjayBmb3IgZXJyb3I6IGlucHV0IGRhdGEgbm90IGEgbXVsdGlwbGUgb2YgYmxvY2tTaXplCiAgaWYob3B0aW9ucy5vdmVyZmxvdyA+IDApIHsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIC8vIGVuc3VyZSBwYWRkaW5nIGJ5dGUgY291bnQgaXMgdmFsaWQKICB2YXIgbGVuID0gb3V0cHV0Lmxlbmd0aCgpOwogIHZhciBjb3VudCA9IG91dHB1dC5hdChsZW4gLSAxKTsKICBpZihjb3VudCA+ICh0aGlzLmJsb2NrU2l6ZSA8PCAyKSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgLy8gdHJpbSBvZmYgcGFkZGluZyBieXRlcwogIG91dHB1dC50cnVuY2F0ZShjb3VudCk7CiAgcmV0dXJuIHRydWU7Cn07CgoKLyoqIENpcGhlciBmZWVkYmFjayAoQ0ZCKSAqKi8KCm1vZGVzLmNmYiA9IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICB0aGlzLm5hbWUgPSAnQ0ZCJzsKICB0aGlzLmNpcGhlciA9IG9wdGlvbnMuY2lwaGVyOwogIHRoaXMuYmxvY2tTaXplID0gb3B0aW9ucy5ibG9ja1NpemUgfHwgMTY7CiAgdGhpcy5faW50cyA9IHRoaXMuYmxvY2tTaXplIC8gNDsKICB0aGlzLl9pbkJsb2NrID0gbnVsbDsKICB0aGlzLl9vdXRCbG9jayA9IG5ldyBBcnJheSh0aGlzLl9pbnRzKTsKICB0aGlzLl9wYXJ0aWFsQmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fcGFydGlhbE91dHB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKfTsKCm1vZGVzLmNmYi5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYoISgnaXYnIGluIG9wdGlvbnMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSVYgcGFyYW1ldGVyLicpOwogIH0KICAvLyB1c2UgSVYgYXMgZmlyc3QgaW5wdXQKICB0aGlzLl9pdiA9IHRyYW5zZm9ybUlWKG9wdGlvbnMuaXYpOwogIHRoaXMuX2luQmxvY2sgPSB0aGlzLl9pdi5zbGljZSgwKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwp9OwoKbW9kZXMuY2ZiLnByb3RvdHlwZS5lbmNyeXB0ID0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCwgZmluaXNoKSB7CiAgLy8gbm90IGVub3VnaCBpbnB1dCB0byBlbmNyeXB0CiAgdmFyIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoKCk7CiAgaWYoaW5wdXRMZW5ndGggPT09IDApIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jawogIHRoaXMuY2lwaGVyLmVuY3J5cHQodGhpcy5faW5CbG9jaywgdGhpcy5fb3V0QmxvY2spOwoKICAvLyBoYW5kbGUgZnVsbCBibG9jawogIGlmKHRoaXMuX3BhcnRpYWxCeXRlcyA9PT0gMCAmJiBpbnB1dExlbmd0aCA+PSB0aGlzLmJsb2NrU2l6ZSkgewogICAgLy8gWE9SIGlucHV0IHdpdGggb3V0cHV0LCB3cml0ZSBpbnB1dCBhcyBvdXRwdXQKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgICAgdGhpcy5faW5CbG9ja1tpXSA9IGlucHV0LmdldEludDMyKCkgXiB0aGlzLl9vdXRCbG9ja1tpXTsKICAgICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX2luQmxvY2tbaV0pOwogICAgfQogICAgcmV0dXJuOwogIH0KCiAgLy8gaGFuZGxlIHBhcnRpYWwgYmxvY2sKICB2YXIgcGFydGlhbEJ5dGVzID0gKHRoaXMuYmxvY2tTaXplIC0gaW5wdXRMZW5ndGgpICUgdGhpcy5ibG9ja1NpemU7CiAgaWYocGFydGlhbEJ5dGVzID4gMCkgewogICAgcGFydGlhbEJ5dGVzID0gdGhpcy5ibG9ja1NpemUgLSBwYXJ0aWFsQnl0ZXM7CiAgfQoKICAvLyBYT1IgaW5wdXQgd2l0aCBvdXRwdXQsIHdyaXRlIGlucHV0IGFzIHBhcnRpYWwgb3V0cHV0CiAgdGhpcy5fcGFydGlhbE91dHB1dC5jbGVhcigpOwogIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgIHRoaXMuX3BhcnRpYWxCbG9ja1tpXSA9IGlucHV0LmdldEludDMyKCkgXiB0aGlzLl9vdXRCbG9ja1tpXTsKICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQucHV0SW50MzIodGhpcy5fcGFydGlhbEJsb2NrW2ldKTsKICB9CgogIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgIC8vIGJsb2NrIHN0aWxsIGluY29tcGxldGUsIHJlc3RvcmUgaW5wdXQgYnVmZmVyCiAgICBpbnB1dC5yZWFkIC09IHRoaXMuYmxvY2tTaXplOwogIH0gZWxzZSB7CiAgICAvLyBibG9jayBjb21wbGV0ZSwgdXBkYXRlIGlucHV0IGJsb2NrCiAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgIHRoaXMuX2luQmxvY2tbaV0gPSB0aGlzLl9wYXJ0aWFsQmxvY2tbaV07CiAgICB9CiAgfQoKICAvLyBza2lwIGFueSBwcmV2aW91cyBwYXJ0aWFsIGJ5dGVzCiAgaWYodGhpcy5fcGFydGlhbEJ5dGVzID4gMCkgewogICAgdGhpcy5fcGFydGlhbE91dHB1dC5nZXRCeXRlcyh0aGlzLl9wYXJ0aWFsQnl0ZXMpOwogIH0KCiAgaWYocGFydGlhbEJ5dGVzID4gMCAmJiAhZmluaXNoKSB7CiAgICBvdXRwdXQucHV0Qnl0ZXModGhpcy5fcGFydGlhbE91dHB1dC5nZXRCeXRlcygKICAgICAgcGFydGlhbEJ5dGVzIC0gdGhpcy5fcGFydGlhbEJ5dGVzKSk7CiAgICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSBwYXJ0aWFsQnl0ZXM7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgaW5wdXRMZW5ndGggLSB0aGlzLl9wYXJ0aWFsQnl0ZXMpKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwp9OwoKbW9kZXMuY2ZiLnByb3RvdHlwZS5kZWNyeXB0ID0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCwgZmluaXNoKSB7CiAgLy8gbm90IGVub3VnaCBpbnB1dCB0byBkZWNyeXB0CiAgdmFyIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoKCk7CiAgaWYoaW5wdXRMZW5ndGggPT09IDApIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jayAoQ0ZCIGFsd2F5cyB1c2VzIGVuY3J5cHRpb24gbW9kZSkKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gaGFuZGxlIGZ1bGwgYmxvY2sKICBpZih0aGlzLl9wYXJ0aWFsQnl0ZXMgPT09IDAgJiYgaW5wdXRMZW5ndGggPj0gdGhpcy5ibG9ja1NpemUpIHsKICAgIC8vIFhPUiBpbnB1dCB3aXRoIG91dHB1dCwgd3JpdGUgaW5wdXQgYXMgb3V0cHV0CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgIHRoaXMuX2luQmxvY2tbaV0gPSBpbnB1dC5nZXRJbnQzMigpOwogICAgICBvdXRwdXQucHV0SW50MzIodGhpcy5faW5CbG9ja1tpXSBeIHRoaXMuX291dEJsb2NrW2ldKTsKICAgIH0KICAgIHJldHVybjsKICB9CgogIC8vIGhhbmRsZSBwYXJ0aWFsIGJsb2NrCiAgdmFyIHBhcnRpYWxCeXRlcyA9ICh0aGlzLmJsb2NrU2l6ZSAtIGlucHV0TGVuZ3RoKSAlIHRoaXMuYmxvY2tTaXplOwogIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgIHBhcnRpYWxCeXRlcyA9IHRoaXMuYmxvY2tTaXplIC0gcGFydGlhbEJ5dGVzOwogIH0KCiAgLy8gWE9SIGlucHV0IHdpdGggb3V0cHV0LCB3cml0ZSBpbnB1dCBhcyBwYXJ0aWFsIG91dHB1dAogIHRoaXMuX3BhcnRpYWxPdXRwdXQuY2xlYXIoKTsKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICB0aGlzLl9wYXJ0aWFsQmxvY2tbaV0gPSBpbnB1dC5nZXRJbnQzMigpOwogICAgdGhpcy5fcGFydGlhbE91dHB1dC5wdXRJbnQzMih0aGlzLl9wYXJ0aWFsQmxvY2tbaV0gXiB0aGlzLl9vdXRCbG9ja1tpXSk7CiAgfQoKICBpZihwYXJ0aWFsQnl0ZXMgPiAwKSB7CiAgICAvLyBibG9jayBzdGlsbCBpbmNvbXBsZXRlLCByZXN0b3JlIGlucHV0IGJ1ZmZlcgogICAgaW5wdXQucmVhZCAtPSB0aGlzLmJsb2NrU2l6ZTsKICB9IGVsc2UgewogICAgLy8gYmxvY2sgY29tcGxldGUsIHVwZGF0ZSBpbnB1dCBibG9jawogICAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgICB0aGlzLl9pbkJsb2NrW2ldID0gdGhpcy5fcGFydGlhbEJsb2NrW2ldOwogICAgfQogIH0KCiAgLy8gc2tpcCBhbnkgcHJldmlvdXMgcGFydGlhbCBieXRlcwogIGlmKHRoaXMuX3BhcnRpYWxCeXRlcyA+IDApIHsKICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQuZ2V0Qnl0ZXModGhpcy5fcGFydGlhbEJ5dGVzKTsKICB9CgogIGlmKHBhcnRpYWxCeXRlcyA+IDAgJiYgIWZpbmlzaCkgewogICAgb3V0cHV0LnB1dEJ5dGVzKHRoaXMuX3BhcnRpYWxPdXRwdXQuZ2V0Qnl0ZXMoCiAgICAgIHBhcnRpYWxCeXRlcyAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgdGhpcy5fcGFydGlhbEJ5dGVzID0gcGFydGlhbEJ5dGVzOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBvdXRwdXQucHV0Qnl0ZXModGhpcy5fcGFydGlhbE91dHB1dC5nZXRCeXRlcygKICAgIGlucHV0TGVuZ3RoIC0gdGhpcy5fcGFydGlhbEJ5dGVzKSk7CiAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKfTsKCi8qKiBPdXRwdXQgZmVlZGJhY2sgKE9GQikgKiovCgptb2Rlcy5vZmIgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdGhpcy5uYW1lID0gJ09GQic7CiAgdGhpcy5jaXBoZXIgPSBvcHRpb25zLmNpcGhlcjsKICB0aGlzLmJsb2NrU2l6ZSA9IG9wdGlvbnMuYmxvY2tTaXplIHx8IDE2OwogIHRoaXMuX2ludHMgPSB0aGlzLmJsb2NrU2l6ZSAvIDQ7CiAgdGhpcy5faW5CbG9jayA9IG51bGw7CiAgdGhpcy5fb3V0QmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fcGFydGlhbE91dHB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKfTsKCm1vZGVzLm9mYi5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYoISgnaXYnIGluIG9wdGlvbnMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSVYgcGFyYW1ldGVyLicpOwogIH0KICAvLyB1c2UgSVYgYXMgZmlyc3QgaW5wdXQKICB0aGlzLl9pdiA9IHRyYW5zZm9ybUlWKG9wdGlvbnMuaXYpOwogIHRoaXMuX2luQmxvY2sgPSB0aGlzLl9pdi5zbGljZSgwKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwp9OwoKbW9kZXMub2ZiLnByb3RvdHlwZS5lbmNyeXB0ID0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCwgZmluaXNoKSB7CiAgLy8gbm90IGVub3VnaCBpbnB1dCB0byBlbmNyeXB0CiAgdmFyIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoKCk7CiAgaWYoaW5wdXQubGVuZ3RoKCkgPT09IDApIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jayAoT0ZCIGFsd2F5cyB1c2VzIGVuY3J5cHRpb24gbW9kZSkKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gaGFuZGxlIGZ1bGwgYmxvY2sKICBpZih0aGlzLl9wYXJ0aWFsQnl0ZXMgPT09IDAgJiYgaW5wdXRMZW5ndGggPj0gdGhpcy5ibG9ja1NpemUpIHsKICAgIC8vIFhPUiBpbnB1dCB3aXRoIG91dHB1dCBhbmQgdXBkYXRlIG5leHQgaW5wdXQKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgICAgb3V0cHV0LnB1dEludDMyKGlucHV0LmdldEludDMyKCkgXiB0aGlzLl9vdXRCbG9ja1tpXSk7CiAgICAgIHRoaXMuX2luQmxvY2tbaV0gPSB0aGlzLl9vdXRCbG9ja1tpXTsKICAgIH0KICAgIHJldHVybjsKICB9CgogIC8vIGhhbmRsZSBwYXJ0aWFsIGJsb2NrCiAgdmFyIHBhcnRpYWxCeXRlcyA9ICh0aGlzLmJsb2NrU2l6ZSAtIGlucHV0TGVuZ3RoKSAlIHRoaXMuYmxvY2tTaXplOwogIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgIHBhcnRpYWxCeXRlcyA9IHRoaXMuYmxvY2tTaXplIC0gcGFydGlhbEJ5dGVzOwogIH0KCiAgLy8gWE9SIGlucHV0IHdpdGggb3V0cHV0CiAgdGhpcy5fcGFydGlhbE91dHB1dC5jbGVhcigpOwogIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQucHV0SW50MzIoaW5wdXQuZ2V0SW50MzIoKSBeIHRoaXMuX291dEJsb2NrW2ldKTsKICB9CgogIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgIC8vIGJsb2NrIHN0aWxsIGluY29tcGxldGUsIHJlc3RvcmUgaW5wdXQgYnVmZmVyCiAgICBpbnB1dC5yZWFkIC09IHRoaXMuYmxvY2tTaXplOwogIH0gZWxzZSB7CiAgICAvLyBibG9jayBjb21wbGV0ZSwgdXBkYXRlIGlucHV0IGJsb2NrCiAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgIHRoaXMuX2luQmxvY2tbaV0gPSB0aGlzLl9vdXRCbG9ja1tpXTsKICAgIH0KICB9CgogIC8vIHNraXAgYW55IHByZXZpb3VzIHBhcnRpYWwgYnl0ZXMKICBpZih0aGlzLl9wYXJ0aWFsQnl0ZXMgPiAwKSB7CiAgICB0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKHRoaXMuX3BhcnRpYWxCeXRlcyk7CiAgfQoKICBpZihwYXJ0aWFsQnl0ZXMgPiAwICYmICFmaW5pc2gpIHsKICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICBwYXJ0aWFsQnl0ZXMgLSB0aGlzLl9wYXJ0aWFsQnl0ZXMpKTsKICAgIHRoaXMuX3BhcnRpYWxCeXRlcyA9IHBhcnRpYWxCeXRlczsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgb3V0cHV0LnB1dEJ5dGVzKHRoaXMuX3BhcnRpYWxPdXRwdXQuZ2V0Qnl0ZXMoCiAgICBpbnB1dExlbmd0aCAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogIHRoaXMuX3BhcnRpYWxCeXRlcyA9IDA7Cn07Cgptb2Rlcy5vZmIucHJvdG90eXBlLmRlY3J5cHQgPSBtb2Rlcy5vZmIucHJvdG90eXBlLmVuY3J5cHQ7CgoKLyoqIENvdW50ZXIgKENUUikgKiovCgptb2Rlcy5jdHIgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdGhpcy5uYW1lID0gJ0NUUic7CiAgdGhpcy5jaXBoZXIgPSBvcHRpb25zLmNpcGhlcjsKICB0aGlzLmJsb2NrU2l6ZSA9IG9wdGlvbnMuYmxvY2tTaXplIHx8IDE2OwogIHRoaXMuX2ludHMgPSB0aGlzLmJsb2NrU2l6ZSAvIDQ7CiAgdGhpcy5faW5CbG9jayA9IG51bGw7CiAgdGhpcy5fb3V0QmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fcGFydGlhbE91dHB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKfTsKCm1vZGVzLmN0ci5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYoISgnaXYnIGluIG9wdGlvbnMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSVYgcGFyYW1ldGVyLicpOwogIH0KICAvLyB1c2UgSVYgYXMgZmlyc3QgaW5wdXQKICB0aGlzLl9pdiA9IHRyYW5zZm9ybUlWKG9wdGlvbnMuaXYpOwogIHRoaXMuX2luQmxvY2sgPSB0aGlzLl9pdi5zbGljZSgwKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwp9OwoKbW9kZXMuY3RyLnByb3RvdHlwZS5lbmNyeXB0ID0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCwgZmluaXNoKSB7CiAgLy8gbm90IGVub3VnaCBpbnB1dCB0byBlbmNyeXB0CiAgdmFyIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoKCk7CiAgaWYoaW5wdXRMZW5ndGggPT09IDApIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jayAoQ1RSIGFsd2F5cyB1c2VzIGVuY3J5cHRpb24gbW9kZSkKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gaGFuZGxlIGZ1bGwgYmxvY2sKICBpZih0aGlzLl9wYXJ0aWFsQnl0ZXMgPT09IDAgJiYgaW5wdXRMZW5ndGggPj0gdGhpcy5ibG9ja1NpemUpIHsKICAgIC8vIFhPUiBpbnB1dCB3aXRoIG91dHB1dAogICAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgICBvdXRwdXQucHV0SW50MzIoaW5wdXQuZ2V0SW50MzIoKSBeIHRoaXMuX291dEJsb2NrW2ldKTsKICAgIH0KICB9IGVsc2UgewogICAgLy8gaGFuZGxlIHBhcnRpYWwgYmxvY2sKICAgIHZhciBwYXJ0aWFsQnl0ZXMgPSAodGhpcy5ibG9ja1NpemUgLSBpbnB1dExlbmd0aCkgJSB0aGlzLmJsb2NrU2l6ZTsKICAgIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgICAgcGFydGlhbEJ5dGVzID0gdGhpcy5ibG9ja1NpemUgLSBwYXJ0aWFsQnl0ZXM7CiAgICB9CgogICAgLy8gWE9SIGlucHV0IHdpdGggb3V0cHV0CiAgICB0aGlzLl9wYXJ0aWFsT3V0cHV0LmNsZWFyKCk7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQucHV0SW50MzIoaW5wdXQuZ2V0SW50MzIoKSBeIHRoaXMuX291dEJsb2NrW2ldKTsKICAgIH0KCiAgICBpZihwYXJ0aWFsQnl0ZXMgPiAwKSB7CiAgICAgIC8vIGJsb2NrIHN0aWxsIGluY29tcGxldGUsIHJlc3RvcmUgaW5wdXQgYnVmZmVyCiAgICAgIGlucHV0LnJlYWQgLT0gdGhpcy5ibG9ja1NpemU7CiAgICB9CgogICAgLy8gc2tpcCBhbnkgcHJldmlvdXMgcGFydGlhbCBieXRlcwogICAgaWYodGhpcy5fcGFydGlhbEJ5dGVzID4gMCkgewogICAgICB0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKHRoaXMuX3BhcnRpYWxCeXRlcyk7CiAgICB9CgogICAgaWYocGFydGlhbEJ5dGVzID4gMCAmJiAhZmluaXNoKSB7CiAgICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICAgIHBhcnRpYWxCeXRlcyAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSBwYXJ0aWFsQnl0ZXM7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICBpbnB1dExlbmd0aCAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKICB9CgogIC8vIGJsb2NrIGNvbXBsZXRlLCBpbmNyZW1lbnQgY291bnRlciAoaW5wdXQgYmxvY2spCiAgaW5jMzIodGhpcy5faW5CbG9jayk7Cn07Cgptb2Rlcy5jdHIucHJvdG90eXBlLmRlY3J5cHQgPSBtb2Rlcy5jdHIucHJvdG90eXBlLmVuY3J5cHQ7CgoKLyoqIEdhbG9pcy9Db3VudGVyIE1vZGUgKEdDTSkgKiovCgptb2Rlcy5nY20gPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdGhpcy5uYW1lID0gJ0dDTSc7CiAgdGhpcy5jaXBoZXIgPSBvcHRpb25zLmNpcGhlcjsKICB0aGlzLmJsb2NrU2l6ZSA9IG9wdGlvbnMuYmxvY2tTaXplIHx8IDE2OwogIHRoaXMuX2ludHMgPSB0aGlzLmJsb2NrU2l6ZSAvIDQ7CiAgdGhpcy5faW5CbG9jayA9IG5ldyBBcnJheSh0aGlzLl9pbnRzKTsKICB0aGlzLl9vdXRCbG9jayA9IG5ldyBBcnJheSh0aGlzLl9pbnRzKTsKICB0aGlzLl9wYXJ0aWFsT3V0cHV0ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwoKICAvLyBSIGlzIGFjdHVhbGx5IHRoaXMgdmFsdWUgY29uY2F0ZW5hdGVkIHdpdGggMTIwIG1vcmUgemVybyBiaXRzLCBidXQKICAvLyB3ZSBvbmx5IFhPUiBhZ2FpbnN0IFIgc28gdGhlIG90aGVyIHplcm9zIGhhdmUgbm8gZWZmZWN0IC0tIHdlIGp1c3QKICAvLyBhcHBseSB0aGlzIHZhbHVlIHRvIHRoZSBmaXJzdCBpbnRlZ2VyIGluIGEgYmxvY2sKICB0aGlzLl9SID0gMHhFMTAwMDAwMDsKfTsKCm1vZGVzLmdjbS5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYoISgnaXYnIGluIG9wdGlvbnMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSVYgcGFyYW1ldGVyLicpOwogIH0KICAvLyBlbnN1cmUgSVYgaXMgYSBieXRlIGJ1ZmZlcgogIHZhciBpdiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKG9wdGlvbnMuaXYpOwoKICAvLyBubyBjaXBoZXJlZCBkYXRhIHByb2Nlc3NlZCB5ZXQKICB0aGlzLl9jaXBoZXJMZW5ndGggPSAwOwoKICAvLyBkZWZhdWx0IGFkZGl0aW9uYWwgZGF0YSBpcyBub25lCiAgdmFyIGFkZGl0aW9uYWxEYXRhOwogIGlmKCdhZGRpdGlvbmFsRGF0YScgaW4gb3B0aW9ucykgewogICAgYWRkaXRpb25hbERhdGEgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihvcHRpb25zLmFkZGl0aW9uYWxEYXRhKTsKICB9IGVsc2UgewogICAgYWRkaXRpb25hbERhdGEgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIH0KCiAgLy8gZGVmYXVsdCB0YWcgbGVuZ3RoIGlzIDEyOCBiaXRzCiAgaWYoJ3RhZ0xlbmd0aCcgaW4gb3B0aW9ucykgewogICAgdGhpcy5fdGFnTGVuZ3RoID0gb3B0aW9ucy50YWdMZW5ndGg7CiAgfSBlbHNlIHsKICAgIHRoaXMuX3RhZ0xlbmd0aCA9IDEyODsKICB9CgogIC8vIGlmIHRhZyBpcyBnaXZlbiwgZW5zdXJlIHRhZyBtYXRjaGVzIHRhZyBsZW5ndGgKICB0aGlzLl90YWcgPSBudWxsOwogIGlmKG9wdGlvbnMuZGVjcnlwdCkgewogICAgLy8gc2F2ZSB0YWcgdG8gY2hlY2sgbGF0ZXIKICAgIHRoaXMuX3RhZyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKG9wdGlvbnMudGFnKS5nZXRCeXRlcygpOwogICAgaWYodGhpcy5fdGFnLmxlbmd0aCAhPT0gKHRoaXMuX3RhZ0xlbmd0aCAvIDgpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignQXV0aGVudGljYXRpb24gdGFnIGRvZXMgbm90IG1hdGNoIHRhZyBsZW5ndGguJyk7CiAgICB9CiAgfQoKICAvLyBjcmVhdGUgdG1wIHN0b3JhZ2UgZm9yIGhhc2ggY2FsY3VsYXRpb24KICB0aGlzLl9oYXNoQmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CgogIC8vIG5vIHRhZyBnZW5lcmF0ZWQgeWV0CiAgdGhpcy50YWcgPSBudWxsOwoKICAvLyBnZW5lcmF0ZSBoYXNoIHN1YmtleQogIC8vIChhcHBseSBibG9jayBjaXBoZXIgdG8gInplcm8iIGJsb2NrKQogIHRoaXMuX2hhc2hTdWJrZXkgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5jaXBoZXIuZW5jcnlwdChbMCwgMCwgMCwgMF0sIHRoaXMuX2hhc2hTdWJrZXkpOwoKICAvLyBnZW5lcmF0ZSB0YWJsZSBNCiAgLy8gdXNlIDQtYml0IHRhYmxlcyAoMzIgY29tcG9uZW50IGRlY29tcG9zaXRpb24gb2YgYSAxNiBieXRlIHZhbHVlKQogIC8vIDgtYml0IHRhYmxlcyB0YWtlIG1vcmUgc3BhY2UgYW5kIGFyZSBrbm93biB0byBoYXZlIHNlY3VyaXR5CiAgLy8gdnVsbmVyYWJpbGl0aWVzIChpbiBuYXRpdmUgaW1wbGVtZW50YXRpb25zKQogIHRoaXMuY29tcG9uZW50Qml0cyA9IDQ7CiAgdGhpcy5fbSA9IHRoaXMuZ2VuZXJhdGVIYXNoVGFibGUodGhpcy5faGFzaFN1YmtleSwgdGhpcy5jb21wb25lbnRCaXRzKTsKCiAgLy8gTm90ZTogc3VwcG9ydCBJViBsZW5ndGggZGlmZmVyZW50IGZyb20gOTYgYml0cz8gKG9ubHkgc3VwcG9ydGluZwogIC8vIDk2IGJpdHMgaXMgcmVjb21tZW5kZWQgYnkgTklTVCBTUC04MDAtMzhEKQogIC8vIGdlbmVyYXRlIEpfMAogIHZhciBpdkxlbmd0aCA9IGl2Lmxlbmd0aCgpOwogIGlmKGl2TGVuZ3RoID09PSAxMikgewogICAgLy8gOTYtYml0IElWCiAgICB0aGlzLl9qMCA9IFtpdi5nZXRJbnQzMigpLCBpdi5nZXRJbnQzMigpLCBpdi5nZXRJbnQzMigpLCAxXTsKICB9IGVsc2UgewogICAgLy8gSVYgaXMgTk9UIDk2LWJpdHMKICAgIHRoaXMuX2owID0gWzAsIDAsIDAsIDBdOwogICAgd2hpbGUoaXYubGVuZ3RoKCkgPiAwKSB7CiAgICAgIHRoaXMuX2owID0gdGhpcy5naGFzaCgKICAgICAgICB0aGlzLl9oYXNoU3Via2V5LCB0aGlzLl9qMCwKICAgICAgICBbaXYuZ2V0SW50MzIoKSwgaXYuZ2V0SW50MzIoKSwgaXYuZ2V0SW50MzIoKSwgaXYuZ2V0SW50MzIoKV0pOwogICAgfQogICAgdGhpcy5fajAgPSB0aGlzLmdoYXNoKAogICAgICB0aGlzLl9oYXNoU3Via2V5LCB0aGlzLl9qMCwgWzAsIDBdLmNvbmNhdChmcm9tNjRUbzMyKGl2TGVuZ3RoICogOCkpKTsKICB9CgogIC8vIGdlbmVyYXRlIElDQiAoaW5pdGlhbCBjb3VudGVyIGJsb2NrKQogIHRoaXMuX2luQmxvY2sgPSB0aGlzLl9qMC5zbGljZSgwKTsKICBpbmMzMih0aGlzLl9pbkJsb2NrKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwoKICAvLyBjb25zdW1lIGF1dGhlbnRpY2F0aW9uIGRhdGEKICBhZGRpdGlvbmFsRGF0YSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGFkZGl0aW9uYWxEYXRhKTsKICAvLyBzYXZlIGFkZGl0aW9uYWwgZGF0YSBsZW5ndGggYXMgYSBCRSA2NC1iaXQgbnVtYmVyCiAgdGhpcy5fYURhdGFMZW5ndGggPSBmcm9tNjRUbzMyKGFkZGl0aW9uYWxEYXRhLmxlbmd0aCgpICogOCk7CiAgLy8gcGFkIGFkZGl0aW9uYWwgZGF0YSB0byAxMjggYml0ICgxNiBieXRlKSBibG9jayBzaXplCiAgdmFyIG92ZXJmbG93ID0gYWRkaXRpb25hbERhdGEubGVuZ3RoKCkgJSB0aGlzLmJsb2NrU2l6ZTsKICBpZihvdmVyZmxvdykgewogICAgYWRkaXRpb25hbERhdGEuZmlsbFdpdGhCeXRlKDAsIHRoaXMuYmxvY2tTaXplIC0gb3ZlcmZsb3cpOwogIH0KICB0aGlzLl9zID0gWzAsIDAsIDAsIDBdOwogIHdoaWxlKGFkZGl0aW9uYWxEYXRhLmxlbmd0aCgpID4gMCkgewogICAgdGhpcy5fcyA9IHRoaXMuZ2hhc2godGhpcy5faGFzaFN1YmtleSwgdGhpcy5fcywgWwogICAgICBhZGRpdGlvbmFsRGF0YS5nZXRJbnQzMigpLAogICAgICBhZGRpdGlvbmFsRGF0YS5nZXRJbnQzMigpLAogICAgICBhZGRpdGlvbmFsRGF0YS5nZXRJbnQzMigpLAogICAgICBhZGRpdGlvbmFsRGF0YS5nZXRJbnQzMigpCiAgICBdKTsKICB9Cn07Cgptb2Rlcy5nY20ucHJvdG90eXBlLmVuY3J5cHQgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBmaW5pc2gpIHsKICAvLyBub3QgZW5vdWdoIGlucHV0IHRvIGVuY3J5cHQKICB2YXIgaW5wdXRMZW5ndGggPSBpbnB1dC5sZW5ndGgoKTsKICBpZihpbnB1dExlbmd0aCA9PT0gMCkgewogICAgcmV0dXJuIHRydWU7CiAgfQoKICAvLyBlbmNyeXB0IGJsb2NrCiAgdGhpcy5jaXBoZXIuZW5jcnlwdCh0aGlzLl9pbkJsb2NrLCB0aGlzLl9vdXRCbG9jayk7CgogIC8vIGhhbmRsZSBmdWxsIGJsb2NrCiAgaWYodGhpcy5fcGFydGlhbEJ5dGVzID09PSAwICYmIGlucHV0TGVuZ3RoID49IHRoaXMuYmxvY2tTaXplKSB7CiAgICAvLyBYT1IgaW5wdXQgd2l0aCBvdXRwdXQKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX291dEJsb2NrW2ldIF49IGlucHV0LmdldEludDMyKCkpOwogICAgfQogICAgdGhpcy5fY2lwaGVyTGVuZ3RoICs9IHRoaXMuYmxvY2tTaXplOwogIH0gZWxzZSB7CiAgICAvLyBoYW5kbGUgcGFydGlhbCBibG9jawogICAgdmFyIHBhcnRpYWxCeXRlcyA9ICh0aGlzLmJsb2NrU2l6ZSAtIGlucHV0TGVuZ3RoKSAlIHRoaXMuYmxvY2tTaXplOwogICAgaWYocGFydGlhbEJ5dGVzID4gMCkgewogICAgICBwYXJ0aWFsQnl0ZXMgPSB0aGlzLmJsb2NrU2l6ZSAtIHBhcnRpYWxCeXRlczsKICAgIH0KCiAgICAvLyBYT1IgaW5wdXQgd2l0aCBvdXRwdXQKICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQuY2xlYXIoKTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgICAgdGhpcy5fcGFydGlhbE91dHB1dC5wdXRJbnQzMihpbnB1dC5nZXRJbnQzMigpIF4gdGhpcy5fb3V0QmxvY2tbaV0pOwogICAgfQoKICAgIGlmKHBhcnRpYWxCeXRlcyA9PT0gMCB8fCBmaW5pc2gpIHsKICAgICAgLy8gaGFuZGxlIG92ZXJmbG93IHByaW9yIHRvIGhhc2hpbmcKICAgICAgaWYoZmluaXNoKSB7CiAgICAgICAgLy8gZ2V0IGJsb2NrIG92ZXJmbG93CiAgICAgICAgdmFyIG92ZXJmbG93ID0gaW5wdXRMZW5ndGggJSB0aGlzLmJsb2NrU2l6ZTsKICAgICAgICB0aGlzLl9jaXBoZXJMZW5ndGggKz0gb3ZlcmZsb3c7CiAgICAgICAgLy8gdHJ1bmNhdGUgZm9yIGhhc2ggZnVuY3Rpb24KICAgICAgICB0aGlzLl9wYXJ0aWFsT3V0cHV0LnRydW5jYXRlKHRoaXMuYmxvY2tTaXplIC0gb3ZlcmZsb3cpOwogICAgICB9IGVsc2UgewogICAgICAgIHRoaXMuX2NpcGhlckxlbmd0aCArPSB0aGlzLmJsb2NrU2l6ZTsKICAgICAgfQoKICAgICAgLy8gZ2V0IG91dHB1dCBibG9jayBmb3IgaGFzaGluZwogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgICAgdGhpcy5fb3V0QmxvY2tbaV0gPSB0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEludDMyKCk7CiAgICAgIH0KICAgICAgdGhpcy5fcGFydGlhbE91dHB1dC5yZWFkIC09IHRoaXMuYmxvY2tTaXplOwogICAgfQoKICAgIC8vIHNraXAgYW55IHByZXZpb3VzIHBhcnRpYWwgYnl0ZXMKICAgIGlmKHRoaXMuX3BhcnRpYWxCeXRlcyA+IDApIHsKICAgICAgdGhpcy5fcGFydGlhbE91dHB1dC5nZXRCeXRlcyh0aGlzLl9wYXJ0aWFsQnl0ZXMpOwogICAgfQoKICAgIGlmKHBhcnRpYWxCeXRlcyA+IDAgJiYgIWZpbmlzaCkgewogICAgICAvLyBibG9jayBzdGlsbCBpbmNvbXBsZXRlLCByZXN0b3JlIGlucHV0IGJ1ZmZlciwgZ2V0IHBhcnRpYWwgb3V0cHV0LAogICAgICAvLyBhbmQgcmV0dXJuIGVhcmx5CiAgICAgIGlucHV0LnJlYWQgLT0gdGhpcy5ibG9ja1NpemU7CiAgICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICAgIHBhcnRpYWxCeXRlcyAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSBwYXJ0aWFsQnl0ZXM7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICBpbnB1dExlbmd0aCAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKICB9CgogIC8vIHVwZGF0ZSBoYXNoIGJsb2NrIFMKICB0aGlzLl9zID0gdGhpcy5naGFzaCh0aGlzLl9oYXNoU3Via2V5LCB0aGlzLl9zLCB0aGlzLl9vdXRCbG9jayk7CgogIC8vIGluY3JlbWVudCBjb3VudGVyIChpbnB1dCBibG9jaykKICBpbmMzMih0aGlzLl9pbkJsb2NrKTsKfTsKCm1vZGVzLmdjbS5wcm90b3R5cGUuZGVjcnlwdCA9IGZ1bmN0aW9uKGlucHV0LCBvdXRwdXQsIGZpbmlzaCkgewogIC8vIG5vdCBlbm91Z2ggaW5wdXQgdG8gZGVjcnlwdAogIHZhciBpbnB1dExlbmd0aCA9IGlucHV0Lmxlbmd0aCgpOwogIGlmKGlucHV0TGVuZ3RoIDwgdGhpcy5ibG9ja1NpemUgJiYgIShmaW5pc2ggJiYgaW5wdXRMZW5ndGggPiAwKSkgewogICAgcmV0dXJuIHRydWU7CiAgfQoKICAvLyBlbmNyeXB0IGJsb2NrIChHQ00gYWx3YXlzIHVzZXMgZW5jcnlwdGlvbiBtb2RlKQogIHRoaXMuY2lwaGVyLmVuY3J5cHQodGhpcy5faW5CbG9jaywgdGhpcy5fb3V0QmxvY2spOwoKICAvLyBpbmNyZW1lbnQgY291bnRlciAoaW5wdXQgYmxvY2spCiAgaW5jMzIodGhpcy5faW5CbG9jayk7CgogIC8vIHVwZGF0ZSBoYXNoIGJsb2NrIFMKICB0aGlzLl9oYXNoQmxvY2tbMF0gPSBpbnB1dC5nZXRJbnQzMigpOwogIHRoaXMuX2hhc2hCbG9ja1sxXSA9IGlucHV0LmdldEludDMyKCk7CiAgdGhpcy5faGFzaEJsb2NrWzJdID0gaW5wdXQuZ2V0SW50MzIoKTsKICB0aGlzLl9oYXNoQmxvY2tbM10gPSBpbnB1dC5nZXRJbnQzMigpOwogIHRoaXMuX3MgPSB0aGlzLmdoYXNoKHRoaXMuX2hhc2hTdWJrZXksIHRoaXMuX3MsIHRoaXMuX2hhc2hCbG9jayk7CgogIC8vIFhPUiBoYXNoIGlucHV0IHdpdGggb3V0cHV0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX291dEJsb2NrW2ldIF4gdGhpcy5faGFzaEJsb2NrW2ldKTsKICB9CgogIC8vIGluY3JlbWVudCBjaXBoZXIgZGF0YSBsZW5ndGgKICBpZihpbnB1dExlbmd0aCA8IHRoaXMuYmxvY2tTaXplKSB7CiAgICB0aGlzLl9jaXBoZXJMZW5ndGggKz0gaW5wdXRMZW5ndGggJSB0aGlzLmJsb2NrU2l6ZTsKICB9IGVsc2UgewogICAgdGhpcy5fY2lwaGVyTGVuZ3RoICs9IHRoaXMuYmxvY2tTaXplOwogIH0KfTsKCm1vZGVzLmdjbS5wcm90b3R5cGUuYWZ0ZXJGaW5pc2ggPSBmdW5jdGlvbihvdXRwdXQsIG9wdGlvbnMpIHsKICB2YXIgcnZhbCA9IHRydWU7CgogIC8vIGhhbmRsZSBvdmVyZmxvdwogIGlmKG9wdGlvbnMuZGVjcnlwdCAmJiBvcHRpb25zLm92ZXJmbG93KSB7CiAgICBvdXRwdXQudHJ1bmNhdGUodGhpcy5ibG9ja1NpemUgLSBvcHRpb25zLm92ZXJmbG93KTsKICB9CgogIC8vIGhhbmRsZSBhdXRoZW50aWNhdGlvbiB0YWcKICB0aGlzLnRhZyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIGNvbmNhdGVuYXRlIGFkZGl0aW9uYWwgZGF0YSBsZW5ndGggd2l0aCBjaXBoZXIgbGVuZ3RoCiAgdmFyIGxlbmd0aHMgPSB0aGlzLl9hRGF0YUxlbmd0aC5jb25jYXQoZnJvbTY0VG8zMih0aGlzLl9jaXBoZXJMZW5ndGggKiA4KSk7CgogIC8vIGluY2x1ZGUgbGVuZ3RocyBpbiBoYXNoCiAgdGhpcy5fcyA9IHRoaXMuZ2hhc2godGhpcy5faGFzaFN1YmtleSwgdGhpcy5fcywgbGVuZ3Rocyk7CgogIC8vIGRvIEdDVFIoSl8wLCBTKQogIHZhciB0YWcgPSBbXTsKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2owLCB0YWcpOwogIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgIHRoaXMudGFnLnB1dEludDMyKHRoaXMuX3NbaV0gXiB0YWdbaV0pOwogIH0KCiAgLy8gdHJpbSB0YWcgdG8gbGVuZ3RoCiAgdGhpcy50YWcudHJ1bmNhdGUodGhpcy50YWcubGVuZ3RoKCkgJSAodGhpcy5fdGFnTGVuZ3RoIC8gOCkpOwoKICAvLyBjaGVjayBhdXRoZW50aWNhdGlvbiB0YWcKICBpZihvcHRpb25zLmRlY3J5cHQgJiYgdGhpcy50YWcuYnl0ZXMoKSAhPT0gdGhpcy5fdGFnKSB7CiAgICBydmFsID0gZmFsc2U7CiAgfQoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBTZWUgTklTVCBTUC04MDAtMzhEIDYuMyAoQWxnb3JpdGhtIDEpLiBUaGlzIGZ1bmN0aW9uIHBlcmZvcm1zIEdhbG9pcwogKiBmaWVsZCBtdWx0aXBsaWNhdGlvbi4gVGhlIGZpZWxkLCBHRigyXjEyOCksIGlzIGRlZmluZWQgYnkgdGhlIHBvbHlub21pYWw6CiAqCiAqIHheMTI4ICsgeF43ICsgeF4yICsgeCArIDEKICoKICogV2hpY2ggaXMgcmVwcmVzZW50ZWQgaW4gbGl0dGxlLWVuZGlhbiBiaW5hcnkgZm9ybSBhczogMTExMDAwMDEgKDB4ZTEpLiBXaGVuCiAqIHRoZSB2YWx1ZSBvZiBhIGNvZWZmaWNpZW50IGlzIDEsIGEgYml0IGlzIHNldC4gVGhlIHZhbHVlIFIsIGlzIHRoZQogKiBjb25jYXRlbmF0aW9uIG9mIHRoaXMgdmFsdWUgYW5kIDEyMCB6ZXJvIGJpdHMsIHlpZWxkaW5nIGEgMTI4LWJpdCB2YWx1ZQogKiB3aGljaCBtYXRjaGVzIHRoZSBibG9jayBzaXplLgogKgogKiBUaGlzIGZ1bmN0aW9uIHdpbGwgbXVsdGlwbHkgdHdvIGVsZW1lbnRzICh2ZWN0b3JzIG9mIGJ5dGVzKSwgWCBhbmQgWSwgaW4KICogdGhlIGZpZWxkIEdGKDJeMTI4KS4gVGhlIHJlc3VsdCBpcyBpbml0aWFsaXplZCB0byB6ZXJvLiBGb3IgZWFjaCBiaXQgb2YKICogWCAob3V0IG9mIDEyOCksIHhfaSwgaWYgeF9pIGlzIHNldCwgdGhlbiB0aGUgcmVzdWx0IGlzIG11bHRpcGxpZWQgKFhPUidkKQogKiBieSB0aGUgY3VycmVudCB2YWx1ZSBvZiBZLiBGb3IgZWFjaCBiaXQsIHRoZSB2YWx1ZSBvZiBZIHdpbGwgYmUgcmFpc2VkIGJ5CiAqIGEgcG93ZXIgb2YgeCAobXVsdGlwbGllZCBieSB0aGUgcG9seW5vbWlhbCB4KS4gVGhpcyBjYW4gYmUgYWNoaWV2ZWQgYnkKICogc2hpZnRpbmcgWSBvbmNlIHRvIHRoZSByaWdodC4gSWYgdGhlIGN1cnJlbnQgdmFsdWUgb2YgWSwgcHJpb3IgdG8gYmVpbmcKICogbXVsdGlwbGllZCBieSB4LCBoYXMgMCBhcyBpdHMgTFNCLCB0aGVuIGl0IGlzIGEgMTI3dGggZGVncmVlIHBvbHlub21pYWwuCiAqIE90aGVyd2lzZSwgd2UgbXVzdCBkaXZpZGUgYnkgUiBhZnRlciBzaGlmdGluZyB0byBmaW5kIHRoZSByZW1haW5kZXIuCiAqCiAqIEBwYXJhbSB4IHRoZSBmaXJzdCBibG9jayB0byBtdWx0aXBseSBieSB0aGUgc2Vjb25kLgogKiBAcGFyYW0geSB0aGUgc2Vjb25kIGJsb2NrIHRvIG11bHRpcGx5IGJ5IHRoZSBmaXJzdC4KICoKICogQHJldHVybiB0aGUgYmxvY2sgcmVzdWx0IG9mIHRoZSBtdWx0aXBsaWNhdGlvbi4KICovCm1vZGVzLmdjbS5wcm90b3R5cGUubXVsdGlwbHkgPSBmdW5jdGlvbih4LCB5KSB7CiAgdmFyIHpfaSA9IFswLCAwLCAwLCAwXTsKICB2YXIgdl9pID0geS5zbGljZSgwKTsKCiAgLy8gY2FsY3VsYXRlIFpfMTI4IChibG9jayBoYXMgMTI4IGJpdHMpCiAgZm9yKHZhciBpID0gMDsgaSA8IDEyODsgKytpKSB7CiAgICAvLyBpZiB4X2kgaXMgMCwgWl97aSsxfSA9IFpfaSAodW5jaGFuZ2VkKQogICAgLy8gZWxzZSBaX3tpKzF9ID0gWl9pIF4gVl9pCiAgICAvLyBnZXQgeF9pIGJ5IGZpbmRpbmcgMzItYml0IGludCBwb3NpdGlvbiwgdGhlbiBsZWZ0IHNoaWZ0IDEgYnkgcmVtYWluZGVyCiAgICB2YXIgeF9pID0geFsoaSAvIDMyKSB8IDBdICYgKDEgPDwgKDMxIC0gaSAlIDMyKSk7CiAgICBpZih4X2kpIHsKICAgICAgel9pWzBdIF49IHZfaVswXTsKICAgICAgel9pWzFdIF49IHZfaVsxXTsKICAgICAgel9pWzJdIF49IHZfaVsyXTsKICAgICAgel9pWzNdIF49IHZfaVszXTsKICAgIH0KCiAgICAvLyBpZiBMU0IoVl9pKSBpcyAxLCBWX2kgPSBWX2kgPj4gMQogICAgLy8gZWxzZSBWX2kgPSAoVl9pID4+IDEpIF4gUgogICAgdGhpcy5wb3codl9pLCB2X2kpOwogIH0KCiAgcmV0dXJuIHpfaTsKfTsKCm1vZGVzLmdjbS5wcm90b3R5cGUucG93ID0gZnVuY3Rpb24oeCwgb3V0KSB7CiAgLy8gaWYgTFNCKHgpIGlzIDEsIHggPSB4ID4+PiAxCiAgLy8gZWxzZSB4ID0gKHggPj4+IDEpIF4gUgogIHZhciBsc2IgPSB4WzNdICYgMTsKCiAgLy8gYWx3YXlzIGRvIHggPj4+IDE6CiAgLy8gc3RhcnRpbmcgd2l0aCB0aGUgcmlnaHRtb3N0IGludGVnZXIsIHNoaWZ0IGVhY2ggaW50ZWdlciB0byB0aGUgcmlnaHQKICAvLyBvbmUgYml0LCBwdWxsaW5nIGluIHRoZSBiaXQgZnJvbSB0aGUgaW50ZWdlciB0byB0aGUgbGVmdCBhcyBpdHMgdG9wCiAgLy8gbW9zdCBiaXQgKGRvIHRoaXMgZm9yIHRoZSBsYXN0IDMgaW50ZWdlcnMpCiAgZm9yKHZhciBpID0gMzsgaSA+IDA7IC0taSkgewogICAgb3V0W2ldID0gKHhbaV0gPj4+IDEpIHwgKCh4W2kgLSAxXSAmIDEpIDw8IDMxKTsKICB9CiAgLy8gc2hpZnQgdGhlIGZpcnN0IGludGVnZXIgbm9ybWFsbHkKICBvdXRbMF0gPSB4WzBdID4+PiAxOwoKICAvLyBpZiBsc2Igd2FzIG5vdCBzZXQsIHRoZW4gcG9seW5vbWlhbCBoYWQgYSBkZWdyZWUgb2YgMTI3IGFuZCBkb2Vzbid0CiAgLy8gbmVlZCB0byBkaXZpZGVkOyBvdGhlcndpc2UsIFhPUiB3aXRoIFIgdG8gZmluZCB0aGUgcmVtYWluZGVyOyB3ZSBvbmx5CiAgLy8gbmVlZCB0byBYT1IgdGhlIGZpcnN0IGludGVnZXIgc2luY2UgUiB0ZWNobmljYWxseSBlbmRzIHcvMTIwIHplcm8gYml0cwogIGlmKGxzYikgewogICAgb3V0WzBdIF49IHRoaXMuX1I7CiAgfQp9OwoKbW9kZXMuZ2NtLnByb3RvdHlwZS50YWJsZU11bHRpcGx5ID0gZnVuY3Rpb24oeCkgewogIC8vIGFzc3VtZXMgNC1iaXQgdGFibGVzIGFyZSB1c2VkCiAgdmFyIHogPSBbMCwgMCwgMCwgMF07CiAgZm9yKHZhciBpID0gMDsgaSA8IDMyOyArK2kpIHsKICAgIHZhciBpZHggPSAoaSAvIDgpIHwgMDsKICAgIHZhciB4X2kgPSAoeFtpZHhdID4+PiAoKDcgLSAoaSAlIDgpKSAqIDQpKSAmIDB4RjsKICAgIHZhciBhaCA9IHRoaXMuX21baV1beF9pXTsKICAgIHpbMF0gXj0gYWhbMF07CiAgICB6WzFdIF49IGFoWzFdOwogICAgelsyXSBePSBhaFsyXTsKICAgIHpbM10gXj0gYWhbM107CiAgfQogIHJldHVybiB6Owp9OwoKLyoqCiAqIEEgY29udGludWluZyB2ZXJzaW9uIG9mIHRoZSBHSEFTSCBhbGdvcml0aG0gdGhhdCBvcGVyYXRlcyBvbiBhIHNpbmdsZQogKiBibG9jay4gVGhlIGhhc2ggYmxvY2ssIGxhc3QgaGFzaCB2YWx1ZSAoWW0pIGFuZCB0aGUgbmV3IGJsb2NrIHRvIGhhc2gKICogYXJlIGdpdmVuLgogKgogKiBAcGFyYW0gaCB0aGUgaGFzaCBibG9jay4KICogQHBhcmFtIHkgdGhlIHByZXZpb3VzIHZhbHVlIGZvciBZbSwgdXNlIFswLCAwLCAwLCAwXSBmb3IgYSBuZXcgaGFzaC4KICogQHBhcmFtIHggdGhlIGJsb2NrIHRvIGhhc2guCiAqCiAqIEByZXR1cm4gdGhlIGhhc2hlZCB2YWx1ZSAoWW0pLgogKi8KbW9kZXMuZ2NtLnByb3RvdHlwZS5naGFzaCA9IGZ1bmN0aW9uKGgsIHksIHgpIHsKICB5WzBdIF49IHhbMF07CiAgeVsxXSBePSB4WzFdOwogIHlbMl0gXj0geFsyXTsKICB5WzNdIF49IHhbM107CiAgcmV0dXJuIHRoaXMudGFibGVNdWx0aXBseSh5KTsKICAvL3JldHVybiB0aGlzLm11bHRpcGx5KHksIGgpOwp9OwoKLyoqCiAqIFByZWNvbXB1dGVzIGEgdGFibGUgZm9yIG11bHRpcGx5aW5nIGFnYWluc3QgdGhlIGhhc2ggc3Via2V5LiBUaGlzCiAqIG1lY2hhbmlzbSBwcm92aWRlcyBhIHN1YnN0YW50aWFsIHNwZWVkIGluY3JlYXNlIG92ZXIgbXVsdGlwbGljYXRpb24KICogcGVyZm9ybWVkIHdpdGhvdXQgYSB0YWJsZS4gVGhlIHRhYmxlLWJhc2VkIG11bHRpcGxpY2F0aW9uIHRoaXMgdGFibGUgaXMKICogZm9yIHNvbHZlcyBYICogSCBieSBtdWx0aXBseWluZyBlYWNoIGNvbXBvbmVudCBvZiBYIGJ5IEggYW5kIHRoZW4KICogY29tcG9zaW5nIHRoZSByZXN1bHRzIHRvZ2V0aGVyIHVzaW5nIFhPUi4KICoKICogVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZW5lcmF0ZSB0YWJsZXMgd2l0aCBkaWZmZXJlbnQgYml0IHNpemVzCiAqIGZvciB0aGUgY29tcG9uZW50cywgaG93ZXZlciwgdGhpcyBpbXBsZW1lbnRhdGlvbiBhc3N1bWVzIHRoZXJlIGFyZQogKiAzMiBjb21wb25lbnRzIG9mIFggKHdoaWNoIGlzIGEgMTYgYnl0ZSB2ZWN0b3IpLCB0aGVyZWZvcmUgZWFjaCBjb21wb25lbnQKICogdGFrZXMgNC1iaXRzIChzbyB0aGUgdGFibGUgaXMgY29uc3RydWN0ZWQgd2l0aCBiaXRzPTQpLgogKgogKiBAcGFyYW0gaCB0aGUgaGFzaCBzdWJrZXkuCiAqIEBwYXJhbSBiaXRzIHRoZSBiaXQgc2l6ZSBmb3IgYSBjb21wb25lbnQuCiAqLwptb2Rlcy5nY20ucHJvdG90eXBlLmdlbmVyYXRlSGFzaFRhYmxlID0gZnVuY3Rpb24oaCwgYml0cykgewogIC8vIFRPRE86IFRoZXJlIGFyZSBmdXJ0aGVyIG9wdGltaXphdGlvbnMgdGhhdCB3b3VsZCB1c2Ugb25seSB0aGUKICAvLyBmaXJzdCB0YWJsZSBNXzAgKG9yIHNvbWUgdmFyaWFudCkgYWxvbmcgd2l0aCBhIHJlbWFpbmRlciB0YWJsZTsKICAvLyB0aGlzIGNhbiBiZSBleHBsb3JlZCBpbiB0aGUgZnV0dXJlCiAgdmFyIG11bHRpcGxpZXIgPSA4IC8gYml0czsKICB2YXIgcGVySW50ID0gNCAqIG11bHRpcGxpZXI7CiAgdmFyIHNpemUgPSAxNiAqIG11bHRpcGxpZXI7CiAgdmFyIG0gPSBuZXcgQXJyYXkoc2l6ZSk7CiAgZm9yKHZhciBpID0gMDsgaSA8IHNpemU7ICsraSkgewogICAgdmFyIHRtcCA9IFswLCAwLCAwLCAwXTsKICAgIHZhciBpZHggPSAoaSAvIHBlckludCkgfCAwOwogICAgdmFyIHNoZnQgPSAoKHBlckludCAtIDEgLSAoaSAlIHBlckludCkpICogYml0cyk7CiAgICB0bXBbaWR4XSA9ICgxIDw8IChiaXRzIC0gMSkpIDw8IHNoZnQ7CiAgICBtW2ldID0gdGhpcy5nZW5lcmF0ZVN1Ykhhc2hUYWJsZSh0aGlzLm11bHRpcGx5KHRtcCwgaCksIGJpdHMpOwogIH0KICByZXR1cm4gbTsKfTsKCi8qKgogKiBHZW5lcmF0ZXMgYSB0YWJsZSBmb3IgbXVsdGlwbHlpbmcgYWdhaW5zdCB0aGUgaGFzaCBzdWJrZXkgZm9yIG9uZQogKiBwYXJ0aWN1bGFyIGNvbXBvbmVudCAob3V0IG9mIGFsbCBwb3NzaWJsZSBjb21wb25lbnQgdmFsdWVzKS4KICoKICogQHBhcmFtIG1pZCB0aGUgcHJlLW11bHRpcGxpZWQgdmFsdWUgZm9yIHRoZSBtaWRkbGUga2V5IG9mIHRoZSB0YWJsZS4KICogQHBhcmFtIGJpdHMgdGhlIGJpdCBzaXplIGZvciBhIGNvbXBvbmVudC4KICovCm1vZGVzLmdjbS5wcm90b3R5cGUuZ2VuZXJhdGVTdWJIYXNoVGFibGUgPSBmdW5jdGlvbihtaWQsIGJpdHMpIHsKICAvLyBjb21wdXRlIHRoZSB0YWJsZSBxdWlja2x5IGJ5IG1pbmltaXppbmcgdGhlIG51bWJlciBvZgogIC8vIFBPVyBvcGVyYXRpb25zIC0tIHRoZXkgb25seSBuZWVkIHRvIGJlIHBlcmZvcm1lZCBmb3IgcG93ZXJzIG9mIDIsCiAgLy8gYWxsIG90aGVyIGVudHJpZXMgY2FuIGJlIGNvbXBvc2VkIGZyb20gdGhvc2UgcG93ZXJzIHVzaW5nIFhPUgogIHZhciBzaXplID0gMSA8PCBiaXRzOwogIHZhciBoYWxmID0gc2l6ZSA+Pj4gMTsKICB2YXIgbSA9IG5ldyBBcnJheShzaXplKTsKICBtW2hhbGZdID0gbWlkLnNsaWNlKDApOwogIHZhciBpID0gaGFsZiA+Pj4gMTsKICB3aGlsZShpID4gMCkgewogICAgLy8gcmFpc2UgbTBbMiAqIGldIGFuZCBzdG9yZSBpbiBtMFtpXQogICAgdGhpcy5wb3cobVsyICogaV0sIG1baV0gPSBbXSk7CiAgICBpID4+PSAxOwogIH0KICBpID0gMjsKICB3aGlsZShpIDwgaGFsZikgewogICAgZm9yKHZhciBqID0gMTsgaiA8IGk7ICsraikgewogICAgICB2YXIgbV9pID0gbVtpXTsKICAgICAgdmFyIG1faiA9IG1bal07CiAgICAgIG1baSArIGpdID0gWwogICAgICAgIG1faVswXSBeIG1falswXSwKICAgICAgICBtX2lbMV0gXiBtX2pbMV0sCiAgICAgICAgbV9pWzJdIF4gbV9qWzJdLAogICAgICAgIG1faVszXSBeIG1falszXQogICAgICBdOwogICAgfQogICAgaSAqPSAyOwogIH0KICBtWzBdID0gWzAsIDAsIDAsIDBdOwogIC8qIE5vdGU6IFdlIGNvdWxkIGF2b2lkIHN0b3JpbmcgdGhlc2UgYnkgZG9pbmcgY29tcG9zaXRpb24gZHVyaW5nIG11bHRpcGx5CiAgY2FsY3VsYXRlIHRvcCBoYWxmIHVzaW5nIGNvbXBvc2l0aW9uIGJ5IHNwZWVkIGlzIHByZWZlcnJlZC4gKi8KICBmb3IoaSA9IGhhbGYgKyAxOyBpIDwgc2l6ZTsgKytpKSB7CiAgICB2YXIgYyA9IG1baSBeIGhhbGZdOwogICAgbVtpXSA9IFttaWRbMF0gXiBjWzBdLCBtaWRbMV0gXiBjWzFdLCBtaWRbMl0gXiBjWzJdLCBtaWRbM10gXiBjWzNdXTsKICB9CiAgcmV0dXJuIG07Cn07CgoKLyoqIFV0aWxpdHkgZnVuY3Rpb25zICovCgpmdW5jdGlvbiB0cmFuc2Zvcm1JVihpdikgewogIGlmKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHsKICAgIC8vIGNvbnZlcnQgaXYgc3RyaW5nIGludG8gYnl0ZSBidWZmZXIKICAgIGl2ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoaXYpOwogIH0KCiAgaWYoZm9yZ2UudXRpbC5pc0FycmF5KGl2KSAmJiBpdi5sZW5ndGggPiA0KSB7CiAgICAvLyBjb252ZXJ0IGl2IGJ5dGUgYXJyYXkgaW50byBieXRlIGJ1ZmZlcgogICAgdmFyIHRtcCA9IGl2OwogICAgaXYgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgZm9yKHZhciBpID0gMDsgaSA8IHRtcC5sZW5ndGg7ICsraSkgewogICAgICBpdi5wdXRCeXRlKHRtcFtpXSk7CiAgICB9CiAgfQogIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkoaXYpKSB7CiAgICAvLyBjb252ZXJ0IGl2IGJ5dGUgYnVmZmVyIGludG8gMzItYml0IGludGVnZXIgYXJyYXkKICAgIGl2ID0gW2l2LmdldEludDMyKCksIGl2LmdldEludDMyKCksIGl2LmdldEludDMyKCksIGl2LmdldEludDMyKCldOwogIH0KCiAgcmV0dXJuIGl2Owp9CgpmdW5jdGlvbiBpbmMzMihibG9jaykgewogIC8vIGluY3JlbWVudCBsYXN0IDMyIGJpdHMgb2YgYmxvY2sgb25seQogIGJsb2NrW2Jsb2NrLmxlbmd0aCAtIDFdID0gKGJsb2NrW2Jsb2NrLmxlbmd0aCAtIDFdICsgMSkgJiAweEZGRkZGRkZGOwp9CgpmdW5jdGlvbiBmcm9tNjRUbzMyKG51bSkgewogIC8vIGNvbnZlcnQgNjQtYml0IG51bWJlciB0byB0d28gQkUgSW50MzJzCiAgcmV0dXJuIFsobnVtIC8gMHgxMDAwMDAwMDApIHwgMCwgbnVtICYgMHhGRkZGRkZGRl07Cn0KCgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdjaXBoZXJNb2Rlcyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9jaXBoZXJNb2RlcycsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogQWR2YW5jZWQgRW5jcnlwdGlvbiBTdGFuZGFyZCAoQUVTKSBpbXBsZW1lbnRhdGlvbi4KICoKICogVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBiYXNlZCBvbiB0aGUgcHVibGljIGRvbWFpbiBsaWJyYXJ5ICdqc2NyeXB0bycgd2hpY2gKICogd2FzIHdyaXR0ZW4gYnk6CiAqCiAqIEVtaWx5IFN0YXJrIChlc3RhcmtAc3RhbmZvcmQuZWR1KQogKiBNaWtlIEhhbWJ1cmcgKG1oYW1idXJnQHN0YW5mb3JkLmVkdSkKICogRGFuIEJvbmVoIChkYWJvQGNzLnN0YW5mb3JkLmVkdSkKICoKICogUGFydHMgb2YgdGhpcyBjb2RlIGFyZSBiYXNlZCBvbiB0aGUgT3BlblNTTCBpbXBsZW1lbnRhdGlvbiBvZiBBRVM6CiAqIGh0dHA6Ly93d3cub3BlbnNzbC5vcmcKICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovKiBBRVMgQVBJICovCmZvcmdlLmFlcyA9IGZvcmdlLmFlcyB8fCB7fTsKCi8qKgogKiBEZXByZWNhdGVkLiBJbnN0ZWFkLCB1c2U6CiAqCiAqIHZhciBjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKCdBRVMtPG1vZGU+Jywga2V5KTsKICogY2lwaGVyLnN0YXJ0KHtpdjogaXZ9KTsKICoKICogQ3JlYXRlcyBhbiBBRVMgY2lwaGVyIG9iamVjdCB0byBlbmNyeXB0IGRhdGEgdXNpbmcgdGhlIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqIFRoZSBvdXRwdXQgd2lsbCBiZSBzdG9yZWQgaW4gdGhlICdvdXRwdXQnIG1lbWJlciBvZiB0aGUgcmV0dXJuZWQgY2lwaGVyLgogKgogKiBUaGUga2V5IGFuZCBpdiBtYXkgYmUgZ2l2ZW4gYXMgYSBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5IG9mIGJ5dGVzLAogKiBhIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UuCiAqIEBwYXJhbSBvdXRwdXQgdGhlIGJ1ZmZlciB0byB3cml0ZSB0bywgbnVsbCB0byBjcmVhdGUgb25lLgogKiBAcGFyYW0gbW9kZSB0aGUgY2lwaGVyIG1vZGUgdG8gdXNlIChkZWZhdWx0OiAnQ0JDJykuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmFlcy5zdGFydEVuY3J5cHRpbmcgPSBmdW5jdGlvbihrZXksIGl2LCBvdXRwdXQsIG1vZGUpIHsKICB2YXIgY2lwaGVyID0gX2NyZWF0ZUNpcGhlcih7CiAgICBrZXk6IGtleSwKICAgIG91dHB1dDogb3V0cHV0LAogICAgZGVjcnlwdDogZmFsc2UsCiAgICBtb2RlOiBtb2RlCiAgfSk7CiAgY2lwaGVyLnN0YXJ0KGl2KTsKICByZXR1cm4gY2lwaGVyOwp9OwoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogdmFyIGNpcGhlciA9IGZvcmdlLmNpcGhlci5jcmVhdGVDaXBoZXIoJ0FFUy08bW9kZT4nLCBrZXkpOwogKgogKiBDcmVhdGVzIGFuIEFFUyBjaXBoZXIgb2JqZWN0IHRvIGVuY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gc3ltbWV0cmljIGtleS4KICoKICogVGhlIGtleSBtYXkgYmUgZ2l2ZW4gYXMgYSBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5IG9mIGJ5dGVzLCBhCiAqIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gbW9kZSB0aGUgY2lwaGVyIG1vZGUgdG8gdXNlIChkZWZhdWx0OiAnQ0JDJykuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyID0gZnVuY3Rpb24oa2V5LCBtb2RlKSB7CiAgcmV0dXJuIF9jcmVhdGVDaXBoZXIoewogICAga2V5OiBrZXksCiAgICBvdXRwdXQ6IG51bGwsCiAgICBkZWNyeXB0OiBmYWxzZSwKICAgIG1vZGU6IG1vZGUKICB9KTsKfTsKCi8qKgogKiBEZXByZWNhdGVkLiBJbnN0ZWFkLCB1c2U6CiAqCiAqIHZhciBkZWNpcGhlciA9IGZvcmdlLmNpcGhlci5jcmVhdGVEZWNpcGhlcignQUVTLTxtb2RlPicsIGtleSk7CiAqIGRlY2lwaGVyLnN0YXJ0KHtpdjogaXZ9KTsKICoKICogQ3JlYXRlcyBhbiBBRVMgY2lwaGVyIG9iamVjdCB0byBkZWNyeXB0IGRhdGEgdXNpbmcgdGhlIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqIFRoZSBvdXRwdXQgd2lsbCBiZSBzdG9yZWQgaW4gdGhlICdvdXRwdXQnIG1lbWJlciBvZiB0aGUgcmV0dXJuZWQgY2lwaGVyLgogKgogKiBUaGUga2V5IGFuZCBpdiBtYXkgYmUgZ2l2ZW4gYXMgYSBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5IG9mIGJ5dGVzLAogKiBhIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UuCiAqIEBwYXJhbSBvdXRwdXQgdGhlIGJ1ZmZlciB0byB3cml0ZSB0bywgbnVsbCB0byBjcmVhdGUgb25lLgogKiBAcGFyYW0gbW9kZSB0aGUgY2lwaGVyIG1vZGUgdG8gdXNlIChkZWZhdWx0OiAnQ0JDJykuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmFlcy5zdGFydERlY3J5cHRpbmcgPSBmdW5jdGlvbihrZXksIGl2LCBvdXRwdXQsIG1vZGUpIHsKICB2YXIgY2lwaGVyID0gX2NyZWF0ZUNpcGhlcih7CiAgICBrZXk6IGtleSwKICAgIG91dHB1dDogb3V0cHV0LAogICAgZGVjcnlwdDogdHJ1ZSwKICAgIG1vZGU6IG1vZGUKICB9KTsKICBjaXBoZXIuc3RhcnQoaXYpOwogIHJldHVybiBjaXBoZXI7Cn07CgovKioKICogRGVwcmVjYXRlZC4gSW5zdGVhZCwgdXNlOgogKgogKiB2YXIgZGVjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlRGVjaXBoZXIoJ0FFUy08bW9kZT4nLCBrZXkpOwogKgogKiBDcmVhdGVzIGFuIEFFUyBjaXBoZXIgb2JqZWN0IHRvIGRlY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gc3ltbWV0cmljIGtleS4KICoKICogVGhlIGtleSBtYXkgYmUgZ2l2ZW4gYXMgYSBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5IG9mIGJ5dGVzLCBhCiAqIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gbW9kZSB0aGUgY2lwaGVyIG1vZGUgdG8gdXNlIChkZWZhdWx0OiAnQ0JDJykuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmFlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyID0gZnVuY3Rpb24oa2V5LCBtb2RlKSB7CiAgcmV0dXJuIF9jcmVhdGVDaXBoZXIoewogICAga2V5OiBrZXksCiAgICBvdXRwdXQ6IG51bGwsCiAgICBkZWNyeXB0OiB0cnVlLAogICAgbW9kZTogbW9kZQogIH0pOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgQUVTIGNpcGhlciBhbGdvcml0aG0gb2JqZWN0LgogKgogKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLgogKiBAcGFyYW0gbW9kZSB0aGUgbW9kZSBmYWN0b3J5IGZ1bmN0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBBRVMgYWxnb3JpdGhtIG9iamVjdC4KICovCmZvcmdlLmFlcy5BbGdvcml0aG0gPSBmdW5jdGlvbihuYW1lLCBtb2RlKSB7CiAgaWYoIWluaXQpIHsKICAgIGluaXRpYWxpemUoKTsKICB9CiAgdmFyIHNlbGYgPSB0aGlzOwogIHNlbGYubmFtZSA9IG5hbWU7CiAgc2VsZi5tb2RlID0gbmV3IG1vZGUoewogICAgYmxvY2tTaXplOiAxNiwKICAgIGNpcGhlcjogewogICAgICBlbmNyeXB0OiBmdW5jdGlvbihpbkJsb2NrLCBvdXRCbG9jaykgewogICAgICAgIHJldHVybiBfdXBkYXRlQmxvY2soc2VsZi5fdywgaW5CbG9jaywgb3V0QmxvY2ssIGZhbHNlKTsKICAgICAgfSwKICAgICAgZGVjcnlwdDogZnVuY3Rpb24oaW5CbG9jaywgb3V0QmxvY2spIHsKICAgICAgICByZXR1cm4gX3VwZGF0ZUJsb2NrKHNlbGYuX3csIGluQmxvY2ssIG91dEJsb2NrLCB0cnVlKTsKICAgICAgfQogICAgfQogIH0pOwogIHNlbGYuX2luaXQgPSBmYWxzZTsKfTsKCi8qKgogKiBJbml0aWFsaXplcyB0aGlzIEFFUyBhbGdvcml0aG0gYnkgZXhwYW5kaW5nIGl0cyBrZXkuCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZS4KICogICAgICAgICAga2V5IHRoZSBrZXkgdG8gdXNlIHdpdGggdGhpcyBhbGdvcml0aG0uCiAqICAgICAgICAgIGRlY3J5cHQgdHJ1ZSBpZiB0aGUgYWxnb3JpdGhtIHNob3VsZCBiZSBpbml0aWFsaXplZCBmb3IgZGVjcnlwdGlvbiwKICogICAgICAgICAgICBmYWxzZSBmb3IgZW5jcnlwdGlvbi4KICovCmZvcmdlLmFlcy5BbGdvcml0aG0ucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYodGhpcy5faW5pdCkgewogICAgcmV0dXJuOwogIH0KCiAgdmFyIGtleSA9IG9wdGlvbnMua2V5OwogIHZhciB0bXA7CgogIC8qIE5vdGU6IFRoZSBrZXkgbWF5IGJlIGEgc3RyaW5nIG9mIGJ5dGVzLCBhbiBhcnJheSBvZiBieXRlcywgYSBieXRlCiAgICBidWZmZXIsIG9yIGFuIGFycmF5IG9mIDMyLWJpdCBpbnRlZ2Vycy4gSWYgdGhlIGtleSBpcyBpbiBieXRlcywgdGhlbgogICAgaXQgbXVzdCBiZSAxNiwgMjQsIG9yIDMyIGJ5dGVzIGluIGxlbmd0aC4gSWYgaXQgaXMgaW4gMzItYml0CiAgICBpbnRlZ2VycywgaXQgbXVzdCBiZSA0LCA2LCBvciA4IGludGVnZXJzIGxvbmcuICovCgogIGlmKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnICYmCiAgICAoa2V5Lmxlbmd0aCA9PT0gMTYgfHwga2V5Lmxlbmd0aCA9PT0gMjQgfHwga2V5Lmxlbmd0aCA9PT0gMzIpKSB7CiAgICAvLyBjb252ZXJ0IGtleSBzdHJpbmcgaW50byBieXRlIGJ1ZmZlcgogICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoa2V5KTsKICB9IGVsc2UgaWYoZm9yZ2UudXRpbC5pc0FycmF5KGtleSkgJiYKICAgIChrZXkubGVuZ3RoID09PSAxNiB8fCBrZXkubGVuZ3RoID09PSAyNCB8fCBrZXkubGVuZ3RoID09PSAzMikpIHsKICAgIC8vIGNvbnZlcnQga2V5IGludGVnZXIgYXJyYXkgaW50byBieXRlIGJ1ZmZlcgogICAgdG1wID0ga2V5OwogICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0bXAubGVuZ3RoOyArK2kpIHsKICAgICAga2V5LnB1dEJ5dGUodG1wW2ldKTsKICAgIH0KICB9CgogIC8vIGNvbnZlcnQga2V5IGJ5dGUgYnVmZmVyIGludG8gMzItYml0IGludGVnZXIgYXJyYXkKICBpZighZm9yZ2UudXRpbC5pc0FycmF5KGtleSkpIHsKICAgIHRtcCA9IGtleTsKICAgIGtleSA9IFtdOwoKICAgIC8vIGtleSBsZW5ndGhzIG9mIDE2LCAyNCwgMzIgYnl0ZXMgYWxsb3dlZAogICAgdmFyIGxlbiA9IHRtcC5sZW5ndGgoKTsKICAgIGlmKGxlbiA9PT0gMTYgfHwgbGVuID09PSAyNCB8fCBsZW4gPT09IDMyKSB7CiAgICAgIGxlbiA9IGxlbiA+Pj4gMjsKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7CiAgICAgICAga2V5LnB1c2godG1wLmdldEludDMyKCkpOwogICAgICB9CiAgICB9CiAgfQoKICAvLyBrZXkgbXVzdCBiZSBhbiBhcnJheSBvZiAzMi1iaXQgaW50ZWdlcnMgYnkgbm93CiAgaWYoIWZvcmdlLnV0aWwuaXNBcnJheShrZXkpIHx8CiAgICAhKGtleS5sZW5ndGggPT09IDQgfHwga2V5Lmxlbmd0aCA9PT0gNiB8fCBrZXkubGVuZ3RoID09PSA4KSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGtleSBwYXJhbWV0ZXIuJyk7CiAgfQoKICAvLyBlbmNyeXB0aW9uIG9wZXJhdGlvbiBpcyBhbHdheXMgdXNlZCBmb3IgdGhlc2UgbW9kZXMKICB2YXIgbW9kZSA9IHRoaXMubW9kZS5uYW1lOwogIHZhciBlbmNyeXB0T3AgPSAoWydDRkInLCAnT0ZCJywgJ0NUUicsICdHQ00nXS5pbmRleE9mKG1vZGUpICE9PSAtMSk7CgogIC8vIGRvIGtleSBleHBhbnNpb24KICB0aGlzLl93ID0gX2V4cGFuZEtleShrZXksIG9wdGlvbnMuZGVjcnlwdCAmJiAhZW5jcnlwdE9wKTsKICB0aGlzLl9pbml0ID0gdHJ1ZTsKfTsKCi8qKgogKiBFeHBhbmRzIGEga2V5LiBUeXBpY2FsbHkgb25seSB1c2VkIGZvciB0ZXN0aW5nLgogKgogKiBAcGFyYW0ga2V5IHRoZSBzeW1tZXRyaWMga2V5IHRvIGV4cGFuZCwgYXMgYW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLgogKiBAcGFyYW0gZGVjcnlwdCB0cnVlIHRvIGV4cGFuZCBmb3IgZGVjcnlwdGlvbiwgZmFsc2UgZm9yIGVuY3J5cHRpb24uCiAqCiAqIEByZXR1cm4gdGhlIGV4cGFuZGVkIGtleS4KICovCmZvcmdlLmFlcy5fZXhwYW5kS2V5ID0gZnVuY3Rpb24oa2V5LCBkZWNyeXB0KSB7CiAgaWYoIWluaXQpIHsKICAgIGluaXRpYWxpemUoKTsKICB9CiAgcmV0dXJuIF9leHBhbmRLZXkoa2V5LCBkZWNyeXB0KTsKfTsKCi8qKgogKiBVcGRhdGVzIGEgc2luZ2xlIGJsb2NrLiBUeXBpY2FsbHkgb25seSB1c2VkIGZvciB0ZXN0aW5nLgogKgogKiBAcGFyYW0gdyB0aGUgZXhwYW5kZWQga2V5IHRvIHVzZS4KICogQHBhcmFtIGlucHV0IGFuIGFycmF5IG9mIGJsb2NrLXNpemUgMzItYml0IHdvcmRzLgogKiBAcGFyYW0gb3V0cHV0IGFuIGFycmF5IG9mIGJsb2NrLXNpemUgMzItYml0IHdvcmRzLgogKiBAcGFyYW0gZGVjcnlwdCB0cnVlIHRvIGRlY3J5cHQsIGZhbHNlIHRvIGVuY3J5cHQuCiAqLwpmb3JnZS5hZXMuX3VwZGF0ZUJsb2NrID0gX3VwZGF0ZUJsb2NrOwoKCi8qKiBSZWdpc3RlciBBRVMgYWxnb3JpdGhtcyAqKi8KCnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtRUNCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmVjYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtQ0JDJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmNiYyk7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtQ0ZCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmNmYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtT0ZCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLm9mYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtQ1RSJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmN0cik7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtR0NNJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmdjbSk7CgpmdW5jdGlvbiByZWdpc3RlckFsZ29yaXRobShuYW1lLCBtb2RlKSB7CiAgdmFyIGZhY3RvcnkgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBuZXcgZm9yZ2UuYWVzLkFsZ29yaXRobShuYW1lLCBtb2RlKTsKICB9OwogIGZvcmdlLmNpcGhlci5yZWdpc3RlckFsZ29yaXRobShuYW1lLCBmYWN0b3J5KTsKfQoKCi8qKiBBRVMgaW1wbGVtZW50YXRpb24gKiovCgp2YXIgaW5pdCA9IGZhbHNlOyAvLyBub3QgeWV0IGluaXRpYWxpemVkCnZhciBOYiA9IDQ7ICAgICAgIC8vIG51bWJlciBvZiB3b3JkcyBjb21wcmlzaW5nIHRoZSBzdGF0ZSAoQUVTID0gNCkKdmFyIHNib3g7ICAgICAgICAgLy8gbm9uLWxpbmVhciBzdWJzdGl0dXRpb24gdGFibGUgdXNlZCBpbiBrZXkgZXhwYW5zaW9uCnZhciBpc2JveDsgICAgICAgIC8vIGludmVyc2lvbiBvZiBzYm94CnZhciByY29uOyAgICAgICAgIC8vIHJvdW5kIGNvbnN0YW50IHdvcmQgYXJyYXkKdmFyIG1peDsgICAgICAgICAgLy8gbWl4LWNvbHVtbnMgdGFibGUKdmFyIGltaXg7ICAgICAgICAgLy8gaW52ZXJzZSBtaXgtY29sdW1ucyB0YWJsZQoKLyoqCiAqIFBlcmZvcm1zIGluaXRpYWxpemF0aW9uLCBpZTogcHJlY29tcHV0ZXMgdGFibGVzIHRvIG9wdGltaXplIGZvciBzcGVlZC4KICoKICogT25lIHdheSB0byB1bmRlcnN0YW5kIGhvdyBBRVMgd29ya3MgaXMgdG8gaW1hZ2luZSB0aGF0ICdhZGRpdGlvbicgYW5kCiAqICdtdWx0aXBsaWNhdGlvbicgYXJlIGludGVyZmFjZXMgdGhhdCByZXF1aXJlIGNlcnRhaW4gbWF0aGVtYXRpY2FsCiAqIHByb3BlcnRpZXMgdG8gaG9sZCB0cnVlIChpZTogdGhleSBhcmUgYXNzb2NpYXRpdmUpIGJ1dCB0aGV5IG1pZ2h0IGhhdmUKICogZGlmZmVyZW50IGltcGxlbWVudGF0aW9ucyBhbmQgcHJvZHVjZSBkaWZmZXJlbnQga2luZHMgb2YgcmVzdWx0cyAuLi4KICogcHJvdmlkZWQgdGhhdCB0aGVpciBtYXRoZW1hdGljYWwgcHJvcGVydGllcyByZW1haW4gdHJ1ZS4gQUVTIGRlZmluZXMKICogaXRzIG93biBtZXRob2RzIG9mIGFkZGl0aW9uIGFuZCBtdWx0aXBsaWNhdGlvbiBidXQga2VlcHMgc29tZSBpbXBvcnRhbnQKICogcHJvcGVydGllcyB0aGUgc2FtZSwgaWU6IGFzc29jaWF0aXZpdHkgYW5kIGRpc3RyaWJ1dGl2aXR5LiBUaGUKICogZXhwbGFuYXRpb24gYmVsb3cgdHJpZXMgdG8gc2hlZCBzb21lIGxpZ2h0IG9uIGhvdyBBRVMgZGVmaW5lcyBhZGRpdGlvbgogKiBhbmQgbXVsdGlwbGljYXRpb24gb2YgYnl0ZXMgYW5kIDMyLWJpdCB3b3JkcyBpbiBvcmRlciB0byBwZXJmb3JtIGl0cwogKiBlbmNyeXB0aW9uIGFuZCBkZWNyeXB0aW9uIGFsZ29yaXRobXMuCiAqCiAqIFRoZSBiYXNpY3M6CiAqCiAqIFRoZSBBRVMgYWxnb3JpdGhtIHZpZXdzIGJ5dGVzIGFzIGJpbmFyeSByZXByZXNlbnRhdGlvbnMgb2YgcG9seW5vbWlhbHMKICogdGhhdCBoYXZlIGVpdGhlciAxIG9yIDAgYXMgdGhlIGNvZWZmaWNpZW50cy4gSXQgZGVmaW5lcyB0aGUgYWRkaXRpb24KICogb3Igc3VidHJhY3Rpb24gb2YgdHdvIGJ5dGVzIGFzIHRoZSBYT1Igb3BlcmF0aW9uLiBJdCBhbHNvIGRlZmluZXMgdGhlCiAqIG11bHRpcGxpY2F0aW9uIG9mIHR3byBieXRlcyBhcyBhIGZpbml0ZSBmaWVsZCByZWZlcnJlZCB0byBhcyBHRigyXjgpCiAqIChOb3RlOiAnR0YnIG1lYW5zICJHYWxvaXMgRmllbGQiIHdoaWNoIGlzIGEgZmllbGQgdGhhdCBjb250YWlucyBhIGZpbml0ZQogKiBudW1iZXIgb2YgZWxlbWVudHMgc28gR0YoMl44KSBoYXMgMjU2IGVsZW1lbnRzKS4KICoKICogVGhpcyBtZWFucyB0aGF0IGFueSB0d28gYnl0ZXMgY2FuIGJlIHJlcHJlc2VudGVkIGFzIGJpbmFyeSBwb2x5bm9taWFsczsKICogd2hlbiB0aGV5IG11bHRpcGxpZWQgdG9nZXRoZXIgYW5kIG1vZHVsYXJseSByZWR1Y2VkIGJ5IGFuIGlycmVkdWNpYmxlCiAqIHBvbHlub21pYWwgb2YgdGhlIDh0aCBkZWdyZWUsIHRoZSByZXN1bHRzIGFyZSB0aGUgZmllbGQgR0YoMl44KS4gVGhlCiAqIHNwZWNpZmljIGlycmVkdWNpYmxlIHBvbHlub21pYWwgdGhhdCBBRVMgdXNlcyBpbiBoZXhhZGVjaW1hbCBpcyAweDExYi4KICogVGhpcyBtdWx0aXBsaWNhdGlvbiBpcyBhc3NvY2lhdGl2ZSB3aXRoIDB4MDEgYXMgdGhlIGlkZW50aXR5OgogKgogKiAoYiAqIDB4MDEgPSBHRihiLCAweDAxKSA9IGIpLgogKgogKiBUaGUgb3BlcmF0aW9uIEdGKGIsIDB4MDIpIGNhbiBiZSBwZXJmb3JtZWQgYXQgdGhlIGJ5dGUgbGV2ZWwgYnkgbGVmdAogKiBzaGlmdGluZyBiIG9uY2UgYW5kIHRoZW4gWE9SJ2luZyBpdCAodG8gcGVyZm9ybSB0aGUgbW9kdWxhciByZWR1Y3Rpb24pCiAqIHdpdGggMHgxMWIgaWYgYiBpcyA+PSAxMjguIFJlcGVhdGVkIGFwcGxpY2F0aW9uIG9mIHRoZSBtdWx0aXBsaWNhdGlvbgogKiBvZiAweDAyIGNhbiBiZSB1c2VkIHRvIGltcGxlbWVudCB0aGUgbXVsdGlwbGljYXRpb24gb2YgYW55IHR3byBieXRlcy4KICoKICogRm9yIGluc3RhbmNlLCBtdWx0aXBseWluZyAweDU3IGFuZCAweDEzLCBkZW5vdGVkIGFzIEdGKDB4NTcsIDB4MTMpLCBjYW4KICogYmUgcGVyZm9ybWVkIGJ5IGZhY3RvcmluZyAweDEzIGludG8gMHgwMSwgMHgwMiwgYW5kIDB4MTAuIFRoZW4gdGhlc2UKICogZmFjdG9ycyBjYW4gZWFjaCBiZSBtdWx0aXBsaWVkIGJ5IDB4NTcgYW5kIHRoZW4gYWRkZWQgdG9nZXRoZXIuIFRvIGRvCiAqIHRoZSBtdWx0aXBsaWNhdGlvbiwgdmFsdWVzIGZvciAweDU3IG11bHRpcGxpZWQgYnkgZWFjaCBvZiB0aGVzZSAzIGZhY3RvcnMKICogY2FuIGJlIHByZWNvbXB1dGVkIGFuZCBzdG9yZWQgaW4gYSB0YWJsZS4gVG8gYWRkIHRoZW0sIHRoZSB2YWx1ZXMgZnJvbQogKiB0aGUgdGFibGUgYXJlIFhPUidkIHRvZ2V0aGVyLgogKgogKiBBRVMgYWxzbyBkZWZpbmVzIGFkZGl0aW9uIGFuZCBtdWx0aXBsaWNhdGlvbiBvZiB3b3JkcywgdGhhdCBpcyA0LWJ5dGUKICogbnVtYmVycyByZXByZXNlbnRlZCBhcyBwb2x5bm9taWFscyBvZiAzIGRlZ3JlZXMgd2hlcmUgdGhlIGNvZWZmaWNpZW50cwogKiBhcmUgdGhlIHZhbHVlcyBvZiB0aGUgYnl0ZXMuCiAqCiAqIFRoZSB3b3JkIFthMCwgYTEsIGEyLCBhM10gaXMgYSBwb2x5bm9taWFsIGEzeF4zICsgYTJ4XjIgKyBhMXggKyBhMC4KICoKICogQWRkaXRpb24gaXMgcGVyZm9ybWVkIGJ5IFhPUidpbmcgbGlrZSBwb3dlcnMgb2YgeC4gTXVsdGlwbGljYXRpb24KICogaXMgcGVyZm9ybWVkIGluIHR3byBzdGVwcywgdGhlIGZpcnN0IGlzIGFuIGFsZ2VicmlhYyBleHBhbnNpb24gYXMKICogeW91IHdvdWxkIGRvIG5vcm1hbGx5ICh3aGVyZSBhZGRpdGlvbiBpcyBYT1IpLiBCdXQgdGhlIHJlc3VsdCBpcwogKiBhIHBvbHlub21pYWwgbGFyZ2VyIHRoYW4gMyBkZWdyZWVzIGFuZCB0aHVzIGl0IGNhbm5vdCBmaXQgaW4gYSB3b3JkLiBTbwogKiBuZXh0IHRoZSByZXN1bHQgaXMgbW9kdWxhcmx5IHJlZHVjZWQgYnkgYW4gQUVTLXNwZWNpZmljIHBvbHlub21pYWwgb2YKICogZGVncmVlIDQgd2hpY2ggd2lsbCBhbHdheXMgcHJvZHVjZSBhIHBvbHlub21pYWwgb2YgbGVzcyB0aGFuIDQgZGVncmVlcwogKiBzdWNoIHRoYXQgaXQgd2lsbCBmaXQgaW4gYSB3b3JkLiBJbiBBRVMsIHRoaXMgcG9seW5vbWlhbCBpcyB4XjQgKyAxLgogKgogKiBUaGUgbW9kdWxhciBwcm9kdWN0IG9mIHR3byBwb2x5bm9taWFscyAnYScgYW5kICdiJyBpcyB0aHVzOgogKgogKiBkKHgpID0gZDN4XjMgKyBkMnheMiArIGQxeCArIGQwCiAqIHdpdGgKICogZDAgPSBHRihhMCwgYjApIF4gR0YoYTMsIGIxKSBeIEdGKGEyLCBiMikgXiBHRihhMSwgYjMpCiAqIGQxID0gR0YoYTEsIGIwKSBeIEdGKGEwLCBiMSkgXiBHRihhMywgYjIpIF4gR0YoYTIsIGIzKQogKiBkMiA9IEdGKGEyLCBiMCkgXiBHRihhMSwgYjEpIF4gR0YoYTAsIGIyKSBeIEdGKGEzLCBiMykKICogZDMgPSBHRihhMywgYjApIF4gR0YoYTIsIGIxKSBeIEdGKGExLCBiMikgXiBHRihhMCwgYjMpCiAqCiAqIEFzIGEgbWF0cml4OgogKgogKiBbZDBdID0gW2EwIGEzIGEyIGExXVtiMF0KICogW2QxXSAgIFthMSBhMCBhMyBhMl1bYjFdCiAqIFtkMl0gICBbYTIgYTEgYTAgYTNdW2IyXQogKiBbZDNdICAgW2EzIGEyIGExIGEwXVtiM10KICoKICogU3BlY2lhbCBwb2x5bm9taWFscyBkZWZpbmVkIGJ5IEFFUyAoMHgwMiA9PSB7MDJ9KToKICogYSh4KSAgICA9IHswM314XjMgKyB7MDF9eF4yICsgezAxfXggKyB7MDJ9CiAqIGFeLTEoeCkgPSB7MGJ9eF4zICsgezBkfXheMiArIHswOX14ICsgezBlfS4KICoKICogVGhlc2UgcG9seW5vbWlhbHMgYXJlIHVzZWQgaW4gdGhlIE1peENvbHVtbnMoKSBhbmQgSW52ZXJzZU1peENvbHVtbnMoKQogKiBvcGVyYXRpb25zLCByZXNwZWN0aXZlbHksIHRvIGNhdXNlIGVhY2ggZWxlbWVudCBpbiB0aGUgc3RhdGUgdG8gYWZmZWN0CiAqIHRoZSBvdXRwdXQgKHJlZmVycmVkIHRvIGFzIGRpZmZ1c2luZykuCiAqCiAqIFJvdFdvcmQoKSB1c2VzOiBhMCA9IGExID0gYTIgPSB7MDB9IGFuZCBhMyA9IHswMX0sIHdoaWNoIGlzIHRoZQogKiBwb2x5bm9taWFsIHgzLgogKgogKiBUaGUgU2hpZnRSb3dzKCkgbWV0aG9kIG1vZGlmaWVzIHRoZSBsYXN0IDMgcm93cyBpbiB0aGUgc3RhdGUgKHdoZXJlCiAqIHRoZSBzdGF0ZSBpcyA0IHdvcmRzIHdpdGggNCBieXRlcyBwZXIgd29yZCkgYnkgc2hpZnRpbmcgYnl0ZXMgY3ljbGljYWxseS4KICogVGhlIDFzdCBieXRlIGluIHRoZSBzZWNvbmQgcm93IGlzIG1vdmVkIHRvIHRoZSBlbmQgb2YgdGhlIHJvdy4gVGhlIDFzdAogKiBhbmQgMm5kIGJ5dGVzIGluIHRoZSB0aGlyZCByb3cgYXJlIG1vdmVkIHRvIHRoZSBlbmQgb2YgdGhlIHJvdy4gVGhlIDFzdCwKICogMm5kLCBhbmQgM3JkIGJ5dGVzIGFyZSBtb3ZlZCBpbiB0aGUgZm91cnRoIHJvdy4KICoKICogTW9yZSBkZXRhaWxzIG9uIGhvdyBBRVMgYXJpdGhtZXRpYyB3b3JrczoKICoKICogSW4gdGhlIHBvbHlub21pYWwgcmVwcmVzZW50YXRpb24gb2YgYmluYXJ5IG51bWJlcnMsIFhPUiBwZXJmb3JtcyBhZGRpdGlvbgogKiBhbmQgc3VidHJhY3Rpb24gYW5kIG11bHRpcGxpY2F0aW9uIGluIEdGKDJeOCkgZGVub3RlZCBhcyBHRihhLCBiKQogKiBjb3JyZXNwb25kcyB3aXRoIHRoZSBtdWx0aXBsaWNhdGlvbiBvZiBwb2x5bm9taWFscyBtb2R1bG8gYW4gaXJyZWR1Y2libGUKICogcG9seW5vbWlhbCBvZiBkZWdyZWUgOC4gSW4gb3RoZXIgd29yZHMsIGZvciBBRVMsIEdGKGEsIGIpIHdpbGwgbXVsdGlwbHkKICogcG9seW5vbWlhbCAnYScgd2l0aCBwb2x5bm9taWFsICdiJyBhbmQgdGhlbiBkbyBhIG1vZHVsYXIgcmVkdWN0aW9uIGJ5CiAqIGFuIEFFUy1zcGVjaWZpYyBpcnJlZHVjaWJsZSBwb2x5bm9taWFsIG9mIGRlZ3JlZSA4LgogKgogKiBBIHBvbHlub21pYWwgaXMgaXJyZWR1Y2libGUgaWYgaXRzIG9ubHkgZGl2aXNvcnMgYXJlIG9uZSBhbmQgaXRzZWxmLiBGb3IKICogdGhlIEFFUyBhbGdvcml0aG0sIHRoaXMgaXJyZWR1Y2libGUgcG9seW5vbWlhbCBpczoKICoKICogbSh4KSA9IHheOCArIHheNCArIHheMyArIHggKyAxLAogKgogKiBvciB7MDF9ezFifSBpbiBoZXhhZGVjaW1hbCBub3RhdGlvbiwgd2hlcmUgZWFjaCBjb2VmZmljaWVudCBpcyBhIGJpdDoKICogMTAwMDExMDExID0gMjgzID0gMHgxMWIuCiAqCiAqIEZvciBleGFtcGxlLCBHRigweDU3LCAweDgzKSA9IDB4YzEgYmVjYXVzZQogKgogKiAweDU3ID0gODcgID0gMDEwMTAxMTEgPSB4XjYgKyB4XjQgKyB4XjIgKyB4ICsgMQogKiAweDg1ID0gMTMxID0gMTAwMDAxMDEgPSB4XjcgKyB4ICsgMQogKgogKiAoeF42ICsgeF40ICsgeF4yICsgeCArIDEpICogKHheNyArIHggKyAxKQogKiA9ICB4XjEzICsgeF4xMSArIHheOSArIHheOCArIHheNyArCiAqICAgIHheNyArIHheNSArIHheMyArIHheMiArIHggKwogKiAgICB4XjYgKyB4XjQgKyB4XjIgKyB4ICsgMQogKiA9ICB4XjEzICsgeF4xMSArIHheOSArIHheOCArIHheNiArIHheNSArIHheNCArIHheMyArIDEgPSB5CiAqICAgIHkgbW9kdWxvICh4XjggKyB4XjQgKyB4XjMgKyB4ICsgMSkKICogPSAgeF43ICsgeF42ICsgMS4KICoKICogVGhlIG1vZHVsYXIgcmVkdWN0aW9uIGJ5IG0oeCkgZ3VhcmFudGVlcyB0aGUgcmVzdWx0IHdpbGwgYmUgYSBiaW5hcnkKICogcG9seW5vbWlhbCBvZiBsZXNzIHRoYW4gZGVncmVlIDgsIHNvIHRoYXQgaXQgY2FuIGZpdCBpbiBhIGJ5dGUuCiAqCiAqIFRoZSBvcGVyYXRpb24gdG8gbXVsdGlwbHkgYSBiaW5hcnkgcG9seW5vbWlhbCBiIHdpdGggeCAodGhlIHBvbHlub21pYWwKICogeCBpbiBiaW5hcnkgcmVwcmVzZW50YXRpb24gaXMgMDAwMDAwMTApIGlzOgogKgogKiBiXzd4XjggKyBiXzZ4XjcgKyBiXzV4XjYgKyBiXzR4XjUgKyBiXzN4XjQgKyBiXzJ4XjMgKyBiXzF4XjIgKyBiXzB4XjEKICoKICogVG8gZ2V0IEdGKGIsIHgpIHdlIG11c3QgcmVkdWNlIHRoYXQgYnkgbSh4KS4gSWYgYl83IGlzIDAgKHRoYXQgaXMgdGhlCiAqIG1vc3Qgc2lnbmlmaWNhbnQgYml0IGlzIDAgaW4gYikgdGhlbiB0aGUgcmVzdWx0IGlzIGFscmVhZHkgcmVkdWNlZC4gSWYKICogaXQgaXMgMSwgdGhlbiB3ZSBjYW4gcmVkdWNlIGl0IGJ5IHN1YnRyYWN0aW5nIG0oeCkgdmlhIGFuIFhPUi4KICoKICogSXQgZm9sbG93cyB0aGF0IG11bHRpcGxpY2F0aW9uIGJ5IHggKDAwMDAwMDEwIG9yIDB4MDIpIGNhbiBiZSBpbXBsZW1lbnRlZAogKiBieSBwZXJmb3JtaW5nIGEgbGVmdCBzaGlmdCBmb2xsb3dlZCBieSBhIGNvbmRpdGlvbmFsIGJpdHdpc2UgWE9SIHdpdGgKICogMHgxYi4gVGhpcyBvcGVyYXRpb24gb24gYnl0ZXMgaXMgZGVub3RlZCBieSB4dGltZSgpLiBNdWx0aXBsaWNhdGlvbiBieQogKiBoaWdoZXIgcG93ZXJzIG9mIHggY2FuIGJlIGltcGxlbWVudGVkIGJ5IHJlcGVhdGVkIGFwcGxpY2F0aW9uIG9mIHh0aW1lKCkuCiAqCiAqIEJ5IGFkZGluZyBpbnRlcm1lZGlhdGUgcmVzdWx0cywgbXVsdGlwbGljYXRpb24gYnkgYW55IGNvbnN0YW50IGNhbiBiZQogKiBpbXBsZW1lbnRlZC4gRm9yIGluc3RhbmNlOgogKgogKiBHRigweDU3LCAweDEzKSA9IDB4ZmUgYmVjYXVzZToKICoKICogeHRpbWUoYikgPSAoYiAmIDEyOCkgPyAoYiA8PCAxIF4gMHgxMWIpIDogKGIgPDwgMSkKICoKICogTm90ZTogV2UgWE9SIHdpdGggMHgxMWIgaW5zdGVhZCBvZiAweDFiIGJlY2F1c2UgaW4gamF2YXNjcmlwdCBvdXIKICogZGF0YXR5cGUgZm9yIGIgY2FuIGJlIGxhcmdlciB0aGFuIDEgYnl0ZSwgc28gYSBsZWZ0IHNoaWZ0IHdpbGwgbm90CiAqIGF1dG9tYXRpY2FsbHkgZWxpbWluYXRlIGJpdHMgdGhhdCBvdmVyZmxvdyBhIGJ5dGUgLi4uIGJ5IFhPUidpbmcgdGhlCiAqIG92ZXJmbG93IGJpdCB3aXRoIDEgKHRoZSBleHRyYSBvbmUgZnJvbSAweDExYikgd2UgemVybyBpdCBvdXQuCiAqCiAqIEdGKDB4NTcsIDB4MDIpID0geHRpbWUoMHg1NykgPSAweGFlCiAqIEdGKDB4NTcsIDB4MDQpID0geHRpbWUoMHhhZSkgPSAweDQ3CiAqIEdGKDB4NTcsIDB4MDgpID0geHRpbWUoMHg0NykgPSAweDhlCiAqIEdGKDB4NTcsIDB4MTApID0geHRpbWUoMHg4ZSkgPSAweDA3CiAqCiAqIEdGKDB4NTcsIDB4MTMpID0gR0YoMHg1NywgKDB4MDEgXiAweDAyIF4gMHgxMCkpCiAqCiAqIEFuZCBieSB0aGUgZGlzdHJpYnV0aXZlIHByb3BlcnR5IChzaW5jZSBYT1IgaXMgYWRkaXRpb24gYW5kIEdGKCkgaXMKICogbXVsdGlwbGljYXRpb24pOgogKgogKiA9IEdGKDB4NTcsIDB4MDEpIF4gR0YoMHg1NywgMHgwMikgXiBHRigweDU3LCAweDEwKQogKiA9IDB4NTcgXiAweGFlIF4gMHgwNwogKiA9IDB4ZmUuCiAqLwpmdW5jdGlvbiBpbml0aWFsaXplKCkgewogIGluaXQgPSB0cnVlOwoKICAvKiBQb3B1bGF0ZSB0aGUgUmNvbiB0YWJsZS4gVGhlc2UgYXJlIHRoZSB2YWx1ZXMgZ2l2ZW4gYnkKICAgIFt4XihpLTEpLHswMH0sezAwfSx7MDB9XSB3aGVyZSB4XihpLTEpIGFyZSBwb3dlcnMgb2YgeCAoYW5kIHggPSAweDAyKQogICAgaW4gdGhlIGZpZWxkIG9mIEdGKDJeOCksIHdoZXJlIGkgc3RhcnRzIGF0IDEuCgogICAgcmNvblswXSA9IFsweDAwLCAweDAwLCAweDAwLCAweDAwXQogICAgcmNvblsxXSA9IFsweDAxLCAweDAwLCAweDAwLCAweDAwXSAyXigxLTEpID0gMl4wID0gMQogICAgcmNvblsyXSA9IFsweDAyLCAweDAwLCAweDAwLCAweDAwXSAyXigyLTEpID0gMl4xID0gMgogICAgLi4uCiAgICByY29uWzldICA9IFsweDFCLCAweDAwLCAweDAwLCAweDAwXSAyXig5LTEpICA9IDJeOCA9IDB4MUIKICAgIHJjb25bMTBdID0gWzB4MzYsIDB4MDAsIDB4MDAsIDB4MDBdIDJeKDEwLTEpID0gMl45ID0gMHgzNgoKICAgIFdlIG9ubHkgc3RvcmUgdGhlIGZpcnN0IGJ5dGUgYmVjYXVzZSBpdCBpcyB0aGUgb25seSBvbmUgdXNlZC4KICAqLwogIHJjb24gPSBbMHgwMCwgMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxQiwgMHgzNl07CgogIC8vIGNvbXB1dGUgeHRpbWUgdGFibGUgd2hpY2ggbWFwcyBpIG9udG8gR0YoaSwgMHgwMikKICB2YXIgeHRpbWUgPSBuZXcgQXJyYXkoMjU2KTsKICBmb3IodmFyIGkgPSAwOyBpIDwgMTI4OyArK2kpIHsKICAgIHh0aW1lW2ldID0gaSA8PCAxOwogICAgeHRpbWVbaSArIDEyOF0gPSAoaSArIDEyOCkgPDwgMSBeIDB4MTFCOwogIH0KCiAgLy8gY29tcHV0ZSBhbGwgb3RoZXIgdGFibGVzCiAgc2JveCA9IG5ldyBBcnJheSgyNTYpOwogIGlzYm94ID0gbmV3IEFycmF5KDI1Nik7CiAgbWl4ID0gbmV3IEFycmF5KDQpOwogIGltaXggPSBuZXcgQXJyYXkoNCk7CiAgZm9yKHZhciBpID0gMDsgaSA8IDQ7ICsraSkgewogICAgbWl4W2ldID0gbmV3IEFycmF5KDI1Nik7CiAgICBpbWl4W2ldID0gbmV3IEFycmF5KDI1Nik7CiAgfQogIHZhciBlID0gMCwgZWkgPSAwLCBlMiwgZTQsIGU4LCBzeCwgc3gyLCBtZSwgaW1lOwogIGZvcih2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkgewogICAgLyogV2UgbmVlZCB0byBnZW5lcmF0ZSB0aGUgU3ViQnl0ZXMoKSBzYm94IGFuZCBpc2JveCB0YWJsZXMgc28gdGhhdAogICAgICB3ZSBjYW4gcGVyZm9ybSBieXRlIHN1YnN0aXR1dGlvbnMuIFRoaXMgcmVxdWlyZXMgdXMgdG8gdHJhdmVyc2UKICAgICAgYWxsIG9mIHRoZSBlbGVtZW50cyBpbiBHRiwgZmluZCB0aGVpciBtdWx0aXBsaWNhdGl2ZSBpbnZlcnNlcywKICAgICAgYW5kIGFwcGx5IHRvIGVhY2ggdGhlIGZvbGxvd2luZyBhZmZpbmUgdHJhbnNmb3JtYXRpb246CgogICAgICBiaScgPSBiaSBeIGIoaSArIDQpIG1vZCA4IF4gYihpICsgNSkgbW9kIDggXiBiKGkgKyA2KSBtb2QgOCBeCiAgICAgICAgICAgIGIoaSArIDcpIG1vZCA4IF4gY2kKICAgICAgZm9yIDAgPD0gaSA8IDgsIHdoZXJlIGJpIGlzIHRoZSBpdGggYml0IG9mIHRoZSBieXRlLCBhbmQgY2kgaXMgdGhlCiAgICAgIGl0aCBiaXQgb2YgYSBieXRlIGMgd2l0aCB0aGUgdmFsdWUgezYzfSBvciB7MDExMDAwMTF9LgoKICAgICAgSXQgaXMgcG9zc2libGUgdG8gdHJhdmVyc2UgZXZlcnkgcG9zc2libGUgdmFsdWUgaW4gYSBHYWxvaXMgZmllbGQKICAgICAgdXNpbmcgd2hhdCBpcyByZWZlcnJlZCB0byBhcyBhICdnZW5lcmF0b3InLiBUaGVyZSBhcmUgbWFueQogICAgICBnZW5lcmF0b3JzICgxMjggb3V0IG9mIDI1Nik6IDMsNSw2LDksMTEsODIgdG8gbmFtZSBhIGZldy4gVG8gZnVsbHkKICAgICAgdHJhdmVyc2UgR0Ygd2UgaXRlcmF0ZSAyNTUgdGltZXMsIG11bHRpcGx5aW5nIGJ5IG91ciBnZW5lcmF0b3IKICAgICAgZWFjaCB0aW1lLgoKICAgICAgT24gZWFjaCBpdGVyYXRpb24gd2UgY2FuIGRldGVybWluZSB0aGUgbXVsdGlwbGljYXRpdmUgaW52ZXJzZSBmb3IKICAgICAgdGhlIGN1cnJlbnQgZWxlbWVudC4KCiAgICAgIFN1cHBvc2UgdGhlcmUgaXMgYW4gZWxlbWVudCBpbiBHRiAnZScuIEZvciBhIGdpdmVuIGdlbmVyYXRvciAnZycsCiAgICAgIGUgPSBnXnguIFRoZSBtdWx0aXBsaWNhdGl2ZSBpbnZlcnNlIG9mIGUgaXMgZ14oMjU1IC0geCkuIEl0IHR1cm5zCiAgICAgIG91dCB0aGF0IGlmIHVzZSB0aGUgaW52ZXJzZSBvZiBhIGdlbmVyYXRvciBhcyBhbm90aGVyIGdlbmVyYXRvcgogICAgICBpdCB3aWxsIHByb2R1Y2UgYWxsIG9mIHRoZSBjb3JyZXNwb25kaW5nIG11bHRpcGxpY2F0aXZlIGludmVyc2VzCiAgICAgIGF0IHRoZSBzYW1lIHRpbWUuIEZvciB0aGlzIHJlYXNvbiwgd2UgY2hvb3NlIDUgYXMgb3VyIGludmVyc2UKICAgICAgZ2VuZXJhdG9yIGJlY2F1c2UgaXQgb25seSByZXF1aXJlcyAyIG11bHRpcGxpZXMgYW5kIDEgYWRkIGFuZCBpdHMKICAgICAgaW52ZXJzZSwgODIsIHJlcXVpcmVzIHJlbGF0aXZlbHkgZmV3IG9wZXJhdGlvbnMgYXMgd2VsbC4KCiAgICAgIEluIG9yZGVyIHRvIGFwcGx5IHRoZSBhZmZpbmUgdHJhbnNmb3JtYXRpb24sIHRoZSBtdWx0aXBsaWNhdGl2ZQogICAgICBpbnZlcnNlICdlaScgb2YgJ2UnIGNhbiBiZSByZXBlYXRlZGx5IFhPUidkICg0IHRpbWVzKSB3aXRoIGEKICAgICAgYml0LWN5Y2xpbmcgb2YgJ2VpJy4gVG8gZG8gdGhpcyAnZWknIGlzIGZpcnN0IHN0b3JlZCBpbiAncycgYW5kCiAgICAgICd4Jy4gVGhlbiAncycgaXMgbGVmdCBzaGlmdGVkIGFuZCB0aGUgaGlnaCBiaXQgb2YgJ3MnIGlzIG1hZGUgdGhlCiAgICAgIGxvdyBiaXQuIFRoZSByZXN1bHRpbmcgdmFsdWUgaXMgc3RvcmVkIGluICdzJy4gVGhlbiAneCcgaXMgWE9SJ2QKICAgICAgd2l0aCAncycgYW5kIHN0b3JlZCBpbiAneCcuIE9uIGVhY2ggc3Vic2VxdWVudCBpdGVyYXRpb24gdGhlIHNhbWUKICAgICAgb3BlcmF0aW9uIGlzIHBlcmZvcm1lZC4gV2hlbiA0IGl0ZXJhdGlvbnMgYXJlIGNvbXBsZXRlLCAneCcgaXMKICAgICAgWE9SJ2Qgd2l0aCAnYycgKDB4NjMpIGFuZCB0aGUgdHJhbnNmb3JtZWQgdmFsdWUgaXMgc3RvcmVkIGluICd4Jy4KICAgICAgRm9yIGV4YW1wbGU6CgogICAgICBzID0gMDEwMDAwMDEKICAgICAgeCA9IDAxMDAwMDAxCgogICAgICBpdGVyYXRpb24gMTogcyA9IDEwMDAwMDEwLCB4IF49IHMKICAgICAgaXRlcmF0aW9uIDI6IHMgPSAwMDAwMDEwMSwgeCBePSBzCiAgICAgIGl0ZXJhdGlvbiAzOiBzID0gMDAwMDEwMTAsIHggXj0gcwogICAgICBpdGVyYXRpb24gNDogcyA9IDAwMDEwMTAwLCB4IF49IHMKICAgICAgeCBePSAweDYzCgogICAgICBUaGlzIGNhbiBiZSBkb25lIHdpdGggYSBsb29wIHdoZXJlIHMgPSAocyA8PCAxKSB8IChzID4+IDcpLiBIb3dldmVyLAogICAgICBpdCBjYW4gYWxzbyBiZSBkb25lIGJ5IHVzaW5nIGEgc2luZ2xlIDE2LWJpdCAoaW4gdGhpcyBjYXNlIDMyLWJpdCkKICAgICAgbnVtYmVyICdzeCcuIFNpbmNlIFhPUiBpcyBhbiBhc3NvY2lhdGl2ZSBvcGVyYXRpb24sIHdlIGNhbiBzZXQgJ3N4JwogICAgICB0byAnZWknIGFuZCB0aGVuIFhPUiBpdCB3aXRoICdzeCcgbGVmdC1zaGlmdGVkIDEsMiwzLCBhbmQgNCB0aW1lcy4KICAgICAgVGhlIG1vc3Qgc2lnbmlmaWNhbnQgYml0cyB3aWxsIGZsb3cgaW50byB0aGUgaGlnaCA4IGJpdCBwb3NpdGlvbnMKICAgICAgYW5kIGJlIGNvcnJlY3RseSBYT1InZCB3aXRoIG9uZSBhbm90aGVyLiBBbGwgdGhhdCByZW1haW5zIHdpbGwgYmUKICAgICAgdG8gY3ljbGUgdGhlIGhpZ2ggOCBiaXRzIGJ5IFhPUidpbmcgdGhlbSBhbGwgd2l0aCB0aGUgbG93ZXIgOCBiaXRzCiAgICAgIGFmdGVyd2FyZHMuCgogICAgICBBdCB0aGUgc2FtZSB0aW1lIHdlJ3JlIHBvcHVsYXRpbmcgc2JveCBhbmQgaXNib3ggd2UgY2FuIHByZWNvbXB1dGUKICAgICAgdGhlIG11bHRpcGxpY2F0aW9uIHdlJ2xsIG5lZWQgdG8gZG8gdG8gZG8gTWl4Q29sdW1ucygpIGxhdGVyLgogICAgKi8KCiAgICAvLyBhcHBseSBhZmZpbmUgdHJhbnNmb3JtYXRpb24KICAgIHN4ID0gZWkgXiAoZWkgPDwgMSkgXiAoZWkgPDwgMikgXiAoZWkgPDwgMykgXiAoZWkgPDwgNCk7CiAgICBzeCA9IChzeCA+PiA4KSBeIChzeCAmIDI1NSkgXiAweDYzOwoKICAgIC8vIHVwZGF0ZSB0YWJsZXMKICAgIHNib3hbZV0gPSBzeDsKICAgIGlzYm94W3N4XSA9IGU7CgogICAgLyogTWl4aW5nIGNvbHVtbnMgaXMgZG9uZSB1c2luZyBtYXRyaXggbXVsdGlwbGljYXRpb24uIFRoZSBjb2x1bW5zCiAgICAgIHRoYXQgYXJlIHRvIGJlIG1peGVkIGFyZSBlYWNoIGEgc2luZ2xlIHdvcmQgaW4gdGhlIGN1cnJlbnQgc3RhdGUuCiAgICAgIFRoZSBzdGF0ZSBoYXMgTmIgY29sdW1ucyAoNCBjb2x1bW5zKS4gVGhlcmVmb3JlIGVhY2ggY29sdW1uIGlzIGEKICAgICAgNCBieXRlIHdvcmQuIFNvIHRvIG1peCB0aGUgY29sdW1ucyBpbiBhIHNpbmdsZSBjb2x1bW4gJ2MnIHdoZXJlCiAgICAgIGl0cyByb3dzIGFyZSByMCwgcjEsIHIyLCBhbmQgcjMsIHdlIHVzZSB0aGUgZm9sbG93aW5nIG1hdHJpeAogICAgICBtdWx0aXBsaWNhdGlvbjoKCiAgICAgIFsyIDMgMSAxXSpbcjAsY109W3InMCxjXQogICAgICBbMSAyIDMgMV0gW3IxLGNdIFtyJzEsY10KICAgICAgWzEgMSAyIDNdIFtyMixjXSBbcicyLGNdCiAgICAgIFszIDEgMSAyXSBbcjMsY10gW3InMyxjXQoKICAgICAgcjAsIHIxLCByMiwgYW5kIHIzIGFyZSBlYWNoIDEgYnl0ZSBvZiBvbmUgb2YgdGhlIHdvcmRzIGluIHRoZQogICAgICBzdGF0ZSAoYSBjb2x1bW4pLiBUbyBkbyBtYXRyaXggbXVsdGlwbGljYXRpb24gZm9yIGVhY2ggbWl4ZWQKICAgICAgY29sdW1uIGMnIHdlIG11bHRpcGx5IHRoZSBjb3JyZXNwb25kaW5nIHJvdyBmcm9tIHRoZSBsZWZ0IG1hdHJpeAogICAgICB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIGNvbHVtbiBmcm9tIHRoZSByaWdodCBtYXRyaXguIEluIHRvdGFsLCB3ZQogICAgICBnZXQgNCBlcXVhdGlvbnM6CgogICAgICByMCxjJyA9IDIqcjAsYyArIDMqcjEsYyArIDEqcjIsYyArIDEqcjMsYwogICAgICByMSxjJyA9IDEqcjAsYyArIDIqcjEsYyArIDMqcjIsYyArIDEqcjMsYwogICAgICByMixjJyA9IDEqcjAsYyArIDEqcjEsYyArIDIqcjIsYyArIDMqcjMsYwogICAgICByMyxjJyA9IDMqcjAsYyArIDEqcjEsYyArIDEqcjIsYyArIDIqcjMsYwoKICAgICAgQXMgdXN1YWwsIHRoZSBtdWx0aXBsaWNhdGlvbiBpcyBhcyBwcmV2aW91c2x5IGRlZmluZWQgYW5kIHRoZQogICAgICBhZGRpdGlvbiBpcyBYT1IuIEluIG9yZGVyIHRvIG9wdGltaXplIG1peGluZyBjb2x1bW5zIHdlIGNhbiBzdG9yZQogICAgICB0aGUgbXVsdGlwbGljYXRpb24gcmVzdWx0cyBpbiB0YWJsZXMuIElmIHlvdSB0aGluayBvZiB0aGUgd2hvbGUKICAgICAgY29sdW1uIGFzIGEgd29yZCAoaXQgbWlnaHQgaGVscCB0byB2aXN1YWxpemUgYnkgbWVudGFsbHkgcm90YXRpbmcKICAgICAgdGhlIGVxdWF0aW9ucyBhYm92ZSBieSBjb3VudGVyY2xvY2t3aXNlIDkwIGRlZ3JlZXMpIHRoZW4geW91IGNhbgogICAgICBzZWUgdGhhdCBpdCB3b3VsZCBiZSB1c2VmdWwgdG8gbWFwIHRoZSBtdWx0aXBsaWNhdGlvbnMgcGVyZm9ybWVkIG9uCiAgICAgIGVhY2ggYnl0ZSAocjAsIHIxLCByMiwgcjMpIG9udG8gYSB3b3JkIGFzIHdlbGwuIEZvciBpbnN0YW5jZSwgd2UKICAgICAgY291bGQgbWFwIDIqcjAsMSpyMCwxKnIwLDMqcjAgb250byBhIHdvcmQgYnkgc3RvcmluZyAyKnIwIGluIHRoZQogICAgICBoaWdoZXN0IDggYml0cyBhbmQgMypyMCBpbiB0aGUgbG93ZXN0IDggYml0cyAod2l0aCB0aGUgb3RoZXIgdHdvCiAgICAgIHJlc3BlY3RpdmVseSBpbiB0aGUgbWlkZGxlKS4gVGhpcyBtZWFucyB0aGF0IGEgdGFibGUgY2FuIGJlCiAgICAgIGNvbnN0cnVjdGVkIHRoYXQgdXNlcyByMCBhcyBhbiBpbmRleCB0byB0aGUgd29yZC4gV2UgY2FuIGRvIHRoZQogICAgICBzYW1lIHdpdGggcjEsIHIyLCBhbmQgcjMsIGNyZWF0aW5nIGEgdG90YWwgb2YgNCB0YWJsZXMuCgogICAgICBUbyBjb25zdHJ1Y3QgYSBmdWxsIGMnLCB3ZSBjYW4ganVzdCBsb29rIHVwIGVhY2ggYnl0ZSBvZiBjIGluCiAgICAgIHRoZWlyIHJlc3BlY3RpdmUgdGFibGVzIGFuZCBYT1IgdGhlIHJlc3VsdHMgdG9nZXRoZXIuCgogICAgICBBbHNvLCB0byBidWlsZCBlYWNoIHRhYmxlIHdlIG9ubHkgaGF2ZSB0byBjYWxjdWxhdGUgdGhlIHdvcmQKICAgICAgZm9yIDIsMSwxLDMgZm9yIGV2ZXJ5IGJ5dGUgLi4uIHdoaWNoIHdlIGNhbiBkbyBvbiBlYWNoIGl0ZXJhdGlvbgogICAgICBvZiB0aGlzIGxvb3Agc2luY2Ugd2Ugd2lsbCBpdGVyYXRlIG92ZXIgZXZlcnkgYnl0ZS4gQWZ0ZXIgd2UgaGF2ZQogICAgICBjYWxjdWxhdGVkIDIsMSwxLDMgd2UgY2FuIGdldCB0aGUgcmVzdWx0cyBmb3IgdGhlIG90aGVyIHRhYmxlcwogICAgICBieSBjeWNsaW5nIHRoZSBieXRlIGF0IHRoZSBlbmQgdG8gdGhlIGJlZ2lubmluZy4gRm9yIGluc3RhbmNlCiAgICAgIHdlIGNhbiB0YWtlIHRoZSByZXN1bHQgb2YgdGFibGUgMiwxLDEsMyBhbmQgcHJvZHVjZSB0YWJsZSAzLDIsMSwxCiAgICAgIGJ5IG1vdmluZyB0aGUgcmlnaHQgbW9zdCBieXRlIHRvIHRoZSBsZWZ0IG1vc3QgcG9zaXRpb24ganVzdCBsaWtlCiAgICAgIGhvdyB5b3UgY2FuIGltYWdpbmUgdGhlIDMgbW92ZWQgb3V0IG9mIDIsMSwxLDMgYW5kIHRvIHRoZSBmcm9udAogICAgICB0byBwcm9kdWNlIDMsMiwxLDEuCgogICAgICBUaGVyZSBpcyBhbm90aGVyIG9wdGltaXphdGlvbiBpbiB0aGF0IHRoZSBzYW1lIG11bHRpcGxlcyBvZgogICAgICB0aGUgY3VycmVudCBlbGVtZW50IHdlIG5lZWQgaW4gb3JkZXIgdG8gYWR2YW5jZSBvdXIgZ2VuZXJhdG9yCiAgICAgIHRvIHRoZSBuZXh0IGl0ZXJhdGlvbiBjYW4gYmUgcmV1c2VkIGluIHBlcmZvcm1pbmcgdGhlIDIsMSwxLDMKICAgICAgY2FsY3VsYXRpb24uIFdlIGFsc28gY2FsY3VsYXRlIHRoZSBpbnZlcnNlIG1peCBjb2x1bW4gdGFibGVzLAogICAgICB3aXRoIGUsOSxkLGIgYmVpbmcgdGhlIGludmVyc2Ugb2YgMiwxLDEsMy4KCiAgICAgIFdoZW4gd2UncmUgZG9uZSwgYW5kIHdlIG5lZWQgdG8gYWN0dWFsbHkgbWl4IGNvbHVtbnMsIHRoZSBmaXJzdAogICAgICBieXRlIG9mIGVhY2ggc3RhdGUgd29yZCBzaG91bGQgYmUgcHV0IHRocm91Z2ggbWl4WzBdICgyLDEsMSwzKSwKICAgICAgdGhlIHNlY29uZCB0aHJvdWdoIG1peFsxXSAoMywyLDEsMSkgYW5kIHNvIGZvcnRoLiBUaGVuIHRoZXkgc2hvdWxkCiAgICAgIGJlIFhPUidkIHRvZ2V0aGVyIHRvIHByb2R1Y2UgdGhlIGZ1bGx5IG1peGVkIGNvbHVtbi4KICAgICovCgogICAgLy8gY2FsY3VsYXRlIG1peCBhbmQgaW1peCB0YWJsZSB2YWx1ZXMKICAgIHN4MiA9IHh0aW1lW3N4XTsKICAgIGUyID0geHRpbWVbZV07CiAgICBlNCA9IHh0aW1lW2UyXTsKICAgIGU4ID0geHRpbWVbZTRdOwogICAgbWUgPQogICAgICAoc3gyIDw8IDI0KSBeICAvLyAyCiAgICAgIChzeCA8PCAxNikgXiAgIC8vIDEKICAgICAgKHN4IDw8IDgpIF4gICAgLy8gMQogICAgICAoc3ggXiBzeDIpOyAgICAvLyAzCiAgICBpbWUgPQogICAgICAoZTIgXiBlNCBeIGU4KSA8PCAyNCBeICAvLyBFICgxNCkKICAgICAgKGUgXiBlOCkgPDwgMTYgXiAgICAgICAgLy8gOQogICAgICAoZSBeIGU0IF4gZTgpIDw8IDggXiAgICAvLyBEICgxMykKICAgICAgKGUgXiBlMiBeIGU4KTsgICAgICAgICAgLy8gQiAoMTEpCiAgICAvLyBwcm9kdWNlIGVhY2ggb2YgdGhlIG1peCB0YWJsZXMgYnkgcm90YXRpbmcgdGhlIDIsMSwxLDMgdmFsdWUKICAgIGZvcih2YXIgbiA9IDA7IG4gPCA0OyArK24pIHsKICAgICAgbWl4W25dW2VdID0gbWU7CiAgICAgIGltaXhbbl1bc3hdID0gaW1lOwogICAgICAvLyBjeWNsZSB0aGUgcmlnaHQgbW9zdCBieXRlIHRvIHRoZSBsZWZ0IG1vc3QgcG9zaXRpb24KICAgICAgLy8gaWU6IDIsMSwxLDMgYmVjb21lcyAzLDIsMSwxCiAgICAgIG1lID0gbWUgPDwgMjQgfCBtZSA+Pj4gODsKICAgICAgaW1lID0gaW1lIDw8IDI0IHwgaW1lID4+PiA4OwogICAgfQoKICAgIC8vIGdldCBuZXh0IGVsZW1lbnQgYW5kIGludmVyc2UKICAgIGlmKGUgPT09IDApIHsKICAgICAgLy8gMSBpcyB0aGUgaW52ZXJzZSBvZiAxCiAgICAgIGUgPSBlaSA9IDE7CiAgICB9IGVsc2UgewogICAgICAvLyBlID0gMmUgKyAyKjIqMiooMTBlKSkgPSBtdWx0aXBseSBlIGJ5IDgyIChjaG9zZW4gZ2VuZXJhdG9yKQogICAgICAvLyBlaSA9IGVpICsgMioyKmVpID0gbXVsdGlwbHkgZWkgYnkgNSAoaW52ZXJzZSBnZW5lcmF0b3IpCiAgICAgIGUgPSBlMiBeIHh0aW1lW3h0aW1lW3h0aW1lW2UyIF4gZThdXV07CiAgICAgIGVpIF49IHh0aW1lW3h0aW1lW2VpXV07CiAgICB9CiAgfQp9CgovKioKICogR2VuZXJhdGVzIGEga2V5IHNjaGVkdWxlIHVzaW5nIHRoZSBBRVMga2V5IGV4cGFuc2lvbiBhbGdvcml0aG0uCiAqCiAqIFRoZSBBRVMgYWxnb3JpdGhtIHRha2VzIHRoZSBDaXBoZXIgS2V5LCBLLCBhbmQgcGVyZm9ybXMgYSBLZXkgRXhwYW5zaW9uCiAqIHJvdXRpbmUgdG8gZ2VuZXJhdGUgYSBrZXkgc2NoZWR1bGUuIFRoZSBLZXkgRXhwYW5zaW9uIGdlbmVyYXRlcyBhIHRvdGFsCiAqIG9mIE5iKihOciArIDEpIHdvcmRzOiB0aGUgYWxnb3JpdGhtIHJlcXVpcmVzIGFuIGluaXRpYWwgc2V0IG9mIE5iIHdvcmRzLAogKiBhbmQgZWFjaCBvZiB0aGUgTnIgcm91bmRzIHJlcXVpcmVzIE5iIHdvcmRzIG9mIGtleSBkYXRhLiBUaGUgcmVzdWx0aW5nCiAqIGtleSBzY2hlZHVsZSBjb25zaXN0cyBvZiBhIGxpbmVhciBhcnJheSBvZiA0LWJ5dGUgd29yZHMsIGRlbm90ZWQgW3dpIF0sCiAqIHdpdGggaSBpbiB0aGUgcmFuZ2UgMCDiiaQgaSA8IE5iKE5yICsgMSkuCiAqCiAqIEtleUV4cGFuc2lvbihieXRlIGtleVs0Kk5rXSwgd29yZCB3W05iKihOcisxKV0sIE5rKQogKiBBRVMtMTI4IChOYj00LCBOaz00LCBOcj0xMCkKICogQUVTLTE5MiAoTmI9NCwgTms9NiwgTnI9MTIpCiAqIEFFUy0yNTYgKE5iPTQsIE5rPTgsIE5yPTE0KQogKiBOb3RlOiBOcj1Oays2LgogKgogKiBOYiBpcyB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgKDMyLWJpdCB3b3JkcykgY29tcHJpc2luZyB0aGUgU3RhdGUgKG9yCiAqIG51bWJlciBvZiBieXRlcyBpbiBhIGJsb2NrKS4gRm9yIEFFUywgTmI9NC4KICoKICogQHBhcmFtIGtleSB0aGUga2V5IHRvIHNjaGVkdWxlIChhcyBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMpLgogKiBAcGFyYW0gZGVjcnlwdCB0cnVlIHRvIG1vZGlmeSB0aGUga2V5IHNjaGVkdWxlIHRvIGRlY3J5cHQsIGZhbHNlIG5vdCB0by4KICoKICogQHJldHVybiB0aGUgZ2VuZXJhdGVkIGtleSBzY2hlZHVsZS4KICovCmZ1bmN0aW9uIF9leHBhbmRLZXkoa2V5LCBkZWNyeXB0KSB7CiAgLy8gY29weSB0aGUga2V5J3Mgd29yZHMgdG8gaW5pdGlhbGl6ZSB0aGUga2V5IHNjaGVkdWxlCiAgdmFyIHcgPSBrZXkuc2xpY2UoMCk7CgogIC8qIFJvdFdvcmQoKSB3aWxsIHJvdGF0ZSBhIHdvcmQsIG1vdmluZyB0aGUgZmlyc3QgYnl0ZSB0byB0aGUgbGFzdAogICAgYnl0ZSdzIHBvc2l0aW9uIChzaGlmdGluZyB0aGUgb3RoZXIgYnl0ZXMgbGVmdCkuCgogICAgV2Ugd2lsbCBiZSBnZXR0aW5nIHRoZSB2YWx1ZSBvZiBSY29uIGF0IGkgLyBOay4gJ2knIHdpbGwgaXRlcmF0ZQogICAgZnJvbSBOayB0byAoTmIgKiBOcisxKS4gTmsgPSA0ICg0IGJ5dGUga2V5KSwgTmIgPSA0ICg0IHdvcmRzIGluCiAgICBhIGJsb2NrKSwgTnIgPSBOayArIDYgKDEwKS4gVGhlcmVmb3JlICdpJyB3aWxsIGl0ZXJhdGUgZnJvbQogICAgNCB0byA0NCAoZXhjbHVzaXZlKS4gRWFjaCB0aW1lIHdlIGl0ZXJhdGUgNCB0aW1lcywgaSAvIE5rIHdpbGwKICAgIGluY3JlYXNlIGJ5IDEuIFdlIHVzZSBhIGNvdW50ZXIgaU5rIHRvIGtlZXAgdHJhY2sgb2YgdGhpcy4KICAgKi8KCiAgLy8gZ28gdGhyb3VnaCB0aGUgcm91bmRzIGV4cGFuZGluZyB0aGUga2V5CiAgdmFyIHRlbXAsIGlOayA9IDE7CiAgdmFyIE5rID0gdy5sZW5ndGg7CiAgdmFyIE5yMSA9IE5rICsgNiArIDE7CiAgdmFyIGVuZCA9IE5iICogTnIxOwogIGZvcih2YXIgaSA9IE5rOyBpIDwgZW5kOyArK2kpIHsKICAgIHRlbXAgPSB3W2kgLSAxXTsKICAgIGlmKGkgJSBOayA9PT0gMCkgewogICAgICAvLyB0ZW1wID0gU3ViV29yZChSb3RXb3JkKHRlbXApKSBeIFJjb25baSAvIE5rXQogICAgICB0ZW1wID0KICAgICAgICBzYm94W3RlbXAgPj4+IDE2ICYgMjU1XSA8PCAyNCBeCiAgICAgICAgc2JveFt0ZW1wID4+PiA4ICYgMjU1XSA8PCAxNiBeCiAgICAgICAgc2JveFt0ZW1wICYgMjU1XSA8PCA4IF4KICAgICAgICBzYm94W3RlbXAgPj4+IDI0XSBeIChyY29uW2lOa10gPDwgMjQpOwogICAgICBpTmsrKzsKICAgIH0gZWxzZSBpZihOayA+IDYgJiYgKGkgJSBOayA9PT0gNCkpIHsKICAgICAgLy8gdGVtcCA9IFN1YldvcmQodGVtcCkKICAgICAgdGVtcCA9CiAgICAgICAgc2JveFt0ZW1wID4+PiAyNF0gPDwgMjQgXgogICAgICAgIHNib3hbdGVtcCA+Pj4gMTYgJiAyNTVdIDw8IDE2IF4KICAgICAgICBzYm94W3RlbXAgPj4+IDggJiAyNTVdIDw8IDggXgogICAgICAgIHNib3hbdGVtcCAmIDI1NV07CiAgICB9CiAgICB3W2ldID0gd1tpIC0gTmtdIF4gdGVtcDsKICB9CgogICAvKiBXaGVuIHdlIGFyZSB1cGRhdGluZyBhIGNpcGhlciBibG9jayB3ZSBhbHdheXMgdXNlIHRoZSBjb2RlIHBhdGggZm9yCiAgICAgZW5jcnlwdGlvbiB3aGV0aGVyIHdlIGFyZSBkZWNyeXB0aW5nIG9yIG5vdCAodG8gc2hvcnRlbiBjb2RlIGFuZAogICAgIHNpbXBsaWZ5IHRoZSBnZW5lcmF0aW9uIG9mIGxvb2sgdXAgdGFibGVzKS4gSG93ZXZlciwgYmVjYXVzZSB0aGVyZQogICAgIGFyZSBkaWZmZXJlbmNlcyBpbiB0aGUgZGVjcnlwdGlvbiBhbGdvcml0aG0sIG90aGVyIHRoYW4ganVzdCBzd2FwcGluZwogICAgIGluIGRpZmZlcmVudCBsb29rIHVwIHRhYmxlcywgd2UgbXVzdCB0cmFuc2Zvcm0gb3VyIGtleSBzY2hlZHVsZSB0bwogICAgIGFjY291bnQgZm9yIHRoZXNlIGNoYW5nZXM6CgogICAgIDEuIFRoZSBkZWNyeXB0aW9uIGFsZ29yaXRobSBnZXRzIGl0cyBrZXkgcm91bmRzIGluIHJldmVyc2Ugb3JkZXIuCiAgICAgMi4gVGhlIGRlY3J5cHRpb24gYWxnb3JpdGhtIGFkZHMgdGhlIHJvdW5kIGtleSBiZWZvcmUgbWl4aW5nIGNvbHVtbnMKICAgICAgIGluc3RlYWQgb2YgYWZ0ZXJ3YXJkcy4KCiAgICAgV2UgZG9uJ3QgbmVlZCB0byBtb2RpZnkgb3VyIGtleSBzY2hlZHVsZSB0byBoYW5kbGUgdGhlIGZpcnN0IGNhc2UsCiAgICAgd2UgY2FuIGp1c3QgdHJhdmVyc2UgdGhlIGtleSBzY2hlZHVsZSBpbiByZXZlcnNlIG9yZGVyIHdoZW4gZGVjcnlwdGluZy4KCiAgICAgVGhlIHNlY29uZCBjYXNlIHJlcXVpcmVzIGEgbGl0dGxlIHdvcmsuCgogICAgIFRoZSB0YWJsZXMgd2UgYnVpbHQgZm9yIHBlcmZvcm1pbmcgcm91bmRzIHdpbGwgdGFrZSBhbiBpbnB1dCBhbmQgdGhlbgogICAgIHBlcmZvcm0gU3ViQnl0ZXMoKSBhbmQgTWl4Q29sdW1ucygpIG9yLCBmb3IgdGhlIGRlY3J5cHQgdmVyc2lvbiwKICAgICBJbnZTdWJCeXRlcygpIGFuZCBJbnZNaXhDb2x1bW5zKCkuIEJ1dCB0aGUgZGVjcnlwdCBhbGdvcml0aG0gcmVxdWlyZXMKICAgICB1cyB0byBBZGRSb3VuZEtleSgpIGJlZm9yZSBJbnZNaXhDb2x1bW5zKCkuIFRoaXMgbWVhbnMgd2UnbGwgbmVlZCB0bwogICAgIGFwcGx5IHNvbWUgdHJhbnNmb3JtYXRpb25zIHRvIHRoZSByb3VuZCBrZXkgdG8gaW52ZXJzZS1taXggaXRzIGNvbHVtbnMKICAgICBzbyB0aGV5J2xsIGJlIGNvcnJlY3QgZm9yIG1vdmluZyBBZGRSb3VuZEtleSgpIHRvIGFmdGVyIHRoZSBzdGF0ZSBoYXMKICAgICBoYWQgaXRzIGNvbHVtbnMgaW52ZXJzZS1taXhlZC4KCiAgICAgVG8gaW52ZXJzZS1taXggdGhlIGNvbHVtbnMgb2YgdGhlIHN0YXRlIHdoZW4gd2UncmUgZGVjcnlwdGluZyB3ZSB1c2UgYQogICAgIGxvb2t1cCB0YWJsZSB0aGF0IHdpbGwgYXBwbHkgSW52U3ViQnl0ZXMoKSBhbmQgSW52TWl4Q29sdW1ucygpIGF0IHRoZQogICAgIHNhbWUgdGltZS4gSG93ZXZlciwgdGhlIHJvdW5kIGtleSdzIGJ5dGVzIGFyZSBub3QgaW52ZXJzZS1zdWJzdGl0dXRlZAogICAgIGluIHRoZSBkZWNyeXB0aW9uIGFsZ29yaXRobS4gVG8gZ2V0IGFyb3VuZCB0aGlzIHByb2JsZW0sIHdlIGNhbiBmaXJzdAogICAgIHN1YnN0aXR1dGUgdGhlIGJ5dGVzIGluIHRoZSByb3VuZCBrZXkgc28gdGhhdCB3aGVuIHdlIGFwcGx5IHRoZQogICAgIHRyYW5zZm9ybWF0aW9uIHZpYSB0aGUgSW52U3ViQnl0ZXMoKStJbnZNaXhDb2x1bW5zKCkgdGFibGUsIGl0IHdpbGwKICAgICB1bmRvIG91ciBzdWJzdGl0dXRpb24gbGVhdmluZyB1cyB3aXRoIHRoZSBvcmlnaW5hbCB2YWx1ZSB0aGF0IHdlCiAgICAgd2FudCAtLSBhbmQgdGhlbiBpbnZlcnNlLW1peCB0aGF0IHZhbHVlLgoKICAgICBUaGlzIGNoYW5nZSB3aWxsIGNvcnJlY3RseSBhbHRlciBvdXIga2V5IHNjaGVkdWxlIHNvIHRoYXQgd2UgY2FuIFhPUgogICAgIGVhY2ggcm91bmQga2V5IHdpdGggb3VyIGFscmVhZHkgdHJhbnNmb3JtZWQgZGVjcnlwdGlvbiBzdGF0ZS4gVGhpcwogICAgIGFsbG93cyB1cyB0byB1c2UgdGhlIHNhbWUgY29kZSBwYXRoIGFzIHRoZSBlbmNyeXB0aW9uIGFsZ29yaXRobS4KCiAgICAgV2UgbWFrZSBvbmUgbW9yZSBjaGFuZ2UgdG8gdGhlIGRlY3J5cHRpb24ga2V5LiBTaW5jZSB0aGUgZGVjcnlwdGlvbgogICAgIGFsZ29yaXRobSBydW5zIGluIHJldmVyc2UgZnJvbSB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0sIHdlIHJldmVyc2UKICAgICB0aGUgb3JkZXIgb2YgdGhlIHJvdW5kIGtleXMgdG8gYXZvaWQgaGF2aW5nIHRvIGl0ZXJhdGUgb3ZlciB0aGUga2V5CiAgICAgc2NoZWR1bGUgYmFja3dhcmRzIHdoZW4gcnVubmluZyB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0gbGF0ZXIgaW4KICAgICBkZWNyeXB0aW9uIG1vZGUuIEluIGFkZGl0aW9uIHRvIHJldmVyc2luZyB0aGUgb3JkZXIgb2YgdGhlIHJvdW5kIGtleXMsCiAgICAgd2UgYWxzbyBzd2FwIGVhY2ggcm91bmQga2V5J3MgMm5kIGFuZCA0dGggcm93cy4gU2VlIHRoZSBjb21tZW50cwogICAgIHNlY3Rpb24gd2hlcmUgcm91bmRzIGFyZSBwZXJmb3JtZWQgZm9yIG1vcmUgZGV0YWlscyBhYm91dCB3aHkgdGhpcyBpcwogICAgIGRvbmUuIFRoZXNlIGNoYW5nZXMgYXJlIGRvbmUgaW5saW5lIHdpdGggdGhlIG90aGVyIHN1YnN0aXR1dGlvbgogICAgIGRlc2NyaWJlZCBhYm92ZS4KICAqLwogIGlmKGRlY3J5cHQpIHsKICAgIHZhciB0bXA7CiAgICB2YXIgbTAgPSBpbWl4WzBdOwogICAgdmFyIG0xID0gaW1peFsxXTsKICAgIHZhciBtMiA9IGltaXhbMl07CiAgICB2YXIgbTMgPSBpbWl4WzNdOwogICAgdmFyIHduZXcgPSB3LnNsaWNlKDApOwogICAgZW5kID0gdy5sZW5ndGg7CiAgICBmb3IodmFyIGkgPSAwLCB3aSA9IGVuZCAtIE5iOyBpIDwgZW5kOyBpICs9IE5iLCB3aSAtPSBOYikgewogICAgICAvLyBkbyBub3Qgc3ViIHRoZSBmaXJzdCBvciBsYXN0IHJvdW5kIGtleSAocm91bmQga2V5cyBhcmUgTmIKICAgICAgLy8gd29yZHMpIGFzIG5vIGNvbHVtbiBtaXhpbmcgaXMgcGVyZm9ybWVkIGJlZm9yZSB0aGV5IGFyZSBhZGRlZCwKICAgICAgLy8gYnV0IGRvIGNoYW5nZSB0aGUga2V5IG9yZGVyCiAgICAgIGlmKGkgPT09IDAgfHwgaSA9PT0gKGVuZCAtIE5iKSkgewogICAgICAgIHduZXdbaV0gPSB3W3dpXTsKICAgICAgICB3bmV3W2kgKyAxXSA9IHdbd2kgKyAzXTsKICAgICAgICB3bmV3W2kgKyAyXSA9IHdbd2kgKyAyXTsKICAgICAgICB3bmV3W2kgKyAzXSA9IHdbd2kgKyAxXTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBzdWJzdGl0dXRlIGVhY2ggcm91bmQga2V5IGJ5dGUgYmVjYXVzZSB0aGUgaW52ZXJzZS1taXgKICAgICAgICAvLyB0YWJsZSB3aWxsIGludmVyc2Utc3Vic3RpdHV0ZSBpdCAoZWZmZWN0aXZlbHkgY2FuY2VsIHRoZQogICAgICAgIC8vIHN1YnN0aXR1dGlvbiBiZWNhdXNlIHJvdW5kIGtleSBieXRlcyBhcmVuJ3Qgc3ViJ2QgaW4KICAgICAgICAvLyBkZWNyeXB0aW9uIG1vZGUpIGFuZCBzd2FwIGluZGV4ZXMgMyBhbmQgMQogICAgICAgIGZvcih2YXIgbiA9IDA7IG4gPCBOYjsgKytuKSB7CiAgICAgICAgICB0bXAgPSB3W3dpICsgbl07CiAgICAgICAgICB3bmV3W2kgKyAoMyYtbildID0KICAgICAgICAgICAgbTBbc2JveFt0bXAgPj4+IDI0XV0gXgogICAgICAgICAgICBtMVtzYm94W3RtcCA+Pj4gMTYgJiAyNTVdXSBeCiAgICAgICAgICAgIG0yW3Nib3hbdG1wID4+PiA4ICYgMjU1XV0gXgogICAgICAgICAgICBtM1tzYm94W3RtcCAmIDI1NV1dOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgdyA9IHduZXc7CiAgfQoKICByZXR1cm4gdzsKfQoKLyoqCiAqIFVwZGF0ZXMgYSBzaW5nbGUgYmxvY2sgKDE2IGJ5dGVzKSB1c2luZyBBRVMuIFRoZSB1cGRhdGUgd2lsbCBlaXRoZXIKICogZW5jcnlwdCBvciBkZWNyeXB0IHRoZSBibG9jay4KICoKICogQHBhcmFtIHcgdGhlIGtleSBzY2hlZHVsZS4KICogQHBhcmFtIGlucHV0IHRoZSBpbnB1dCBibG9jayAoYW4gYXJyYXkgb2YgMzItYml0IHdvcmRzKS4KICogQHBhcmFtIG91dHB1dCB0aGUgdXBkYXRlZCBvdXRwdXQgYmxvY2suCiAqIEBwYXJhbSBkZWNyeXB0IHRydWUgdG8gZGVjcnlwdCB0aGUgYmxvY2ssIGZhbHNlIHRvIGVuY3J5cHQgaXQuCiAqLwpmdW5jdGlvbiBfdXBkYXRlQmxvY2sodywgaW5wdXQsIG91dHB1dCwgZGVjcnlwdCkgewogIC8qCiAgQ2lwaGVyKGJ5dGUgaW5bNCpOYl0sIGJ5dGUgb3V0WzQqTmJdLCB3b3JkIHdbTmIqKE5yKzEpXSkKICBiZWdpbgogICAgYnl0ZSBzdGF0ZVs0LE5iXQogICAgc3RhdGUgPSBpbgogICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbMCwgTmItMV0pCiAgICBmb3Igcm91bmQgPSAxIHN0ZXAgMSB0byBOcuKAkzEKICAgICAgU3ViQnl0ZXMoc3RhdGUpCiAgICAgIFNoaWZ0Um93cyhzdGF0ZSkKICAgICAgTWl4Q29sdW1ucyhzdGF0ZSkKICAgICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbcm91bmQqTmIsIChyb3VuZCsxKSpOYi0xXSkKICAgIGVuZCBmb3IKICAgIFN1YkJ5dGVzKHN0YXRlKQogICAgU2hpZnRSb3dzKHN0YXRlKQogICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbTnIqTmIsIChOcisxKSpOYi0xXSkKICAgIG91dCA9IHN0YXRlCiAgZW5kCgogIEludkNpcGhlcihieXRlIGluWzQqTmJdLCBieXRlIG91dFs0Kk5iXSwgd29yZCB3W05iKihOcisxKV0pCiAgYmVnaW4KICAgIGJ5dGUgc3RhdGVbNCxOYl0KICAgIHN0YXRlID0gaW4KICAgIEFkZFJvdW5kS2V5KHN0YXRlLCB3W05yKk5iLCAoTnIrMSkqTmItMV0pCiAgICBmb3Igcm91bmQgPSBOci0xIHN0ZXAgLTEgZG93bnRvIDEKICAgICAgSW52U2hpZnRSb3dzKHN0YXRlKQogICAgICBJbnZTdWJCeXRlcyhzdGF0ZSkKICAgICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbcm91bmQqTmIsIChyb3VuZCsxKSpOYi0xXSkKICAgICAgSW52TWl4Q29sdW1ucyhzdGF0ZSkKICAgIGVuZCBmb3IKICAgIEludlNoaWZ0Um93cyhzdGF0ZSkKICAgIEludlN1YkJ5dGVzKHN0YXRlKQogICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbMCwgTmItMV0pCiAgICBvdXQgPSBzdGF0ZQogIGVuZAogICovCgogIC8vIEVuY3J5cHQ6IEFkZFJvdW5kS2V5KHN0YXRlLCB3WzAsIE5iLTFdKQogIC8vIERlY3J5cHQ6IEFkZFJvdW5kS2V5KHN0YXRlLCB3W05yKk5iLCAoTnIrMSkqTmItMV0pCiAgdmFyIE5yID0gdy5sZW5ndGggLyA0IC0gMTsKICB2YXIgbTAsIG0xLCBtMiwgbTMsIHN1YjsKICBpZihkZWNyeXB0KSB7CiAgICBtMCA9IGltaXhbMF07CiAgICBtMSA9IGltaXhbMV07CiAgICBtMiA9IGltaXhbMl07CiAgICBtMyA9IGltaXhbM107CiAgICBzdWIgPSBpc2JveDsKICB9IGVsc2UgewogICAgbTAgPSBtaXhbMF07CiAgICBtMSA9IG1peFsxXTsKICAgIG0yID0gbWl4WzJdOwogICAgbTMgPSBtaXhbM107CiAgICBzdWIgPSBzYm94OwogIH0KICB2YXIgYSwgYiwgYywgZCwgYTIsIGIyLCBjMjsKICBhID0gaW5wdXRbMF0gXiB3WzBdOwogIGIgPSBpbnB1dFtkZWNyeXB0ID8gMyA6IDFdIF4gd1sxXTsKICBjID0gaW5wdXRbMl0gXiB3WzJdOwogIGQgPSBpbnB1dFtkZWNyeXB0ID8gMSA6IDNdIF4gd1szXTsKICB2YXIgaSA9IDM7CgogIC8qIEluIG9yZGVyIHRvIHNoYXJlIGNvZGUgd2UgZm9sbG93IHRoZSBlbmNyeXB0aW9uIGFsZ29yaXRobSB3aGVuIGJvdGgKICAgIGVuY3J5cHRpbmcgYW5kIGRlY3J5cHRpbmcuIFRvIGFjY291bnQgZm9yIHRoZSBjaGFuZ2VzIHJlcXVpcmVkIGluIHRoZQogICAgZGVjcnlwdGlvbiBhbGdvcml0aG0sIHdlIHVzZSBkaWZmZXJlbnQgbG9va3VwIHRhYmxlcyB3aGVuIGRlY3J5cHRpbmcKICAgIGFuZCB1c2UgYSBtb2RpZmllZCBrZXkgc2NoZWR1bGUgdG8gYWNjb3VudCBmb3IgdGhlIGRpZmZlcmVuY2UgaW4gdGhlCiAgICBvcmRlciBvZiB0cmFuc2Zvcm1hdGlvbnMgYXBwbGllZCB3aGVuIHBlcmZvcm1pbmcgcm91bmRzLiBXZSBhbHNvIGdldAogICAga2V5IHJvdW5kcyBpbiByZXZlcnNlIG9yZGVyIChyZWxhdGl2ZSB0byBlbmNyeXB0aW9uKS4gKi8KICBmb3IodmFyIHJvdW5kID0gMTsgcm91bmQgPCBOcjsgKytyb3VuZCkgewogICAgLyogQXMgZGVzY3JpYmVkIGFib3ZlLCB3ZSdsbCBiZSB1c2luZyB0YWJsZSBsb29rdXBzIHRvIHBlcmZvcm0gdGhlCiAgICAgIGNvbHVtbiBtaXhpbmcuIEVhY2ggY29sdW1uIGlzIHN0b3JlZCBhcyBhIHdvcmQgaW4gdGhlIHN0YXRlICh0aGUKICAgICAgYXJyYXkgJ2lucHV0JyBoYXMgb25lIGNvbHVtbiBhcyBhIHdvcmQgYXQgZWFjaCBpbmRleCkuIEluIG9yZGVyIHRvCiAgICAgIG1peCBhIGNvbHVtbiwgd2UgcGVyZm9ybSB0aGVzZSB0cmFuc2Zvcm1hdGlvbnMgb24gZWFjaCByb3cgaW4gYywKICAgICAgd2hpY2ggaXMgMSBieXRlIGluIGVhY2ggd29yZC4gVGhlIG5ldyBjb2x1bW4gZm9yIGMwIGlzIGMnMDoKCiAgICAgICAgICAgICAgIG0wICAgICAgbTEgICAgICBtMiAgICAgIG0zCiAgICAgIHIwLGMnMCA9IDIqcjAsYzAgKyAzKnIxLGMwICsgMSpyMixjMCArIDEqcjMsYzAKICAgICAgcjEsYycwID0gMSpyMCxjMCArIDIqcjEsYzAgKyAzKnIyLGMwICsgMSpyMyxjMAogICAgICByMixjJzAgPSAxKnIwLGMwICsgMSpyMSxjMCArIDIqcjIsYzAgKyAzKnIzLGMwCiAgICAgIHIzLGMnMCA9IDMqcjAsYzAgKyAxKnIxLGMwICsgMSpyMixjMCArIDIqcjMsYzAKCiAgICAgIFNvIHVzaW5nIG1peCB0YWJsZXMgd2hlcmUgYzAgaXMgYSB3b3JkIHdpdGggcjAgYmVpbmcgaXRzIHVwcGVyCiAgICAgIDggYml0cyBhbmQgcjMgYmVpbmcgaXRzIGxvd2VyIDggYml0czoKCiAgICAgIG0wW2MwID4+IDI0XSB3aWxsIHlpZWxkIHRoaXMgd29yZDogWzIqcjAsMSpyMCwxKnIwLDMqcjBdCiAgICAgIC4uLgogICAgICBtM1tjMCAmIDI1NV0gd2lsbCB5aWVsZCB0aGlzIHdvcmQ6IFsxKnIzLDEqcjMsMypyMywyKnIzXQoKICAgICAgVGhlcmVmb3JlIHRvIG1peCB0aGUgY29sdW1ucyBpbiBlYWNoIHdvcmQgaW4gdGhlIHN0YXRlIHdlCiAgICAgIGRvIHRoZSBmb2xsb3dpbmcgKCYgMjU1IG9taXR0ZWQgZm9yIGJyZXZpdHkpOgogICAgICBjJzAscjAgPSBtMFtjMCA+PiAyNF0gXiBtMVtjMSA+PiAxNl0gXiBtMltjMiA+PiA4XSBeIG0zW2MzXQogICAgICBjJzAscjEgPSBtMFtjMCA+PiAyNF0gXiBtMVtjMSA+PiAxNl0gXiBtMltjMiA+PiA4XSBeIG0zW2MzXQogICAgICBjJzAscjIgPSBtMFtjMCA+PiAyNF0gXiBtMVtjMSA+PiAxNl0gXiBtMltjMiA+PiA4XSBeIG0zW2MzXQogICAgICBjJzAscjMgPSBtMFtjMCA+PiAyNF0gXiBtMVtjMSA+PiAxNl0gXiBtMltjMiA+PiA4XSBeIG0zW2MzXQoKICAgICAgSG93ZXZlciwgYmVmb3JlIG1peGluZywgdGhlIGFsZ29yaXRobSByZXF1aXJlcyB1cyB0byBwZXJmb3JtCiAgICAgIFNoaWZ0Um93cygpLiBUaGUgU2hpZnRSb3dzKCkgdHJhbnNmb3JtYXRpb24gY3ljbGljYWxseSBzaGlmdHMgdGhlCiAgICAgIGxhc3QgMyByb3dzIG9mIHRoZSBzdGF0ZSBvdmVyIGRpZmZlcmVudCBvZmZzZXRzLiBUaGUgZmlyc3Qgcm93CiAgICAgIChyID0gMCkgaXMgbm90IHNoaWZ0ZWQuCgogICAgICBzJ19yLGMgPSBzX3IsKGMgKyBzaGlmdChyLCBOYikgbW9kIE5iCiAgICAgIGZvciAwIDwgciA8IDQgYW5kIDAgPD0gYyA8IE5iIGFuZAogICAgICBzaGlmdCgxLCA0KSA9IDEKICAgICAgc2hpZnQoMiwgNCkgPSAyCiAgICAgIHNoaWZ0KDMsIDQpID0gMy4KCiAgICAgIFRoaXMgY2F1c2VzIHRoZSBmaXJzdCBieXRlIGluIHIgPSAxIHRvIGJlIG1vdmVkIHRvIHRoZSBlbmQgb2YKICAgICAgdGhlIHJvdywgdGhlIGZpcnN0IDIgYnl0ZXMgaW4gciA9IDIgdG8gYmUgbW92ZWQgdG8gdGhlIGVuZCBvZgogICAgICB0aGUgcm93LCB0aGUgZmlyc3QgMyBieXRlcyBpbiByID0gMyB0byBiZSBtb3ZlZCB0byB0aGUgZW5kIG9mCiAgICAgIHRoZSByb3c6CgogICAgICByMTogW2MwIGMxIGMyIGMzXSA9PiBbYzEgYzIgYzMgYzBdCiAgICAgIHIyOiBbYzAgYzEgYzIgYzNdICAgIFtjMiBjMyBjMCBjMV0KICAgICAgcjM6IFtjMCBjMSBjMiBjM10gICAgW2MzIGMwIGMxIGMyXQoKICAgICAgV2UgY2FuIG1ha2UgdGhlc2Ugc3Vic3RpdHV0aW9ucyBpbmxpbmUgd2l0aCBvdXIgY29sdW1uIG1peGluZyB0bwogICAgICBnZW5lcmF0ZSBhbiB1cGRhdGVkIHNldCBvZiBlcXVhdGlvbnMgdG8gcHJvZHVjZSBlYWNoIHdvcmQgaW4gdGhlCiAgICAgIHN0YXRlIChub3RlIHRoZSBjb2x1bW5zIGhhdmUgY2hhbmdlZCBwb3NpdGlvbnMpOgoKICAgICAgYzAgYzEgYzIgYzMgPT4gYzAgYzEgYzIgYzMKICAgICAgYzAgYzEgYzIgYzMgICAgYzEgYzIgYzMgYzAgIChjeWNsZWQgMSBieXRlKQogICAgICBjMCBjMSBjMiBjMyAgICBjMiBjMyBjMCBjMSAgKGN5Y2xlZCAyIGJ5dGVzKQogICAgICBjMCBjMSBjMiBjMyAgICBjMyBjMCBjMSBjMiAgKGN5Y2xlZCAzIGJ5dGVzKQoKICAgICAgVGhlcmVmb3JlOgoKICAgICAgYycwID0gMipyMCxjMCArIDMqcjEsYzEgKyAxKnIyLGMyICsgMSpyMyxjMwogICAgICBjJzAgPSAxKnIwLGMwICsgMipyMSxjMSArIDMqcjIsYzIgKyAxKnIzLGMzCiAgICAgIGMnMCA9IDEqcjAsYzAgKyAxKnIxLGMxICsgMipyMixjMiArIDMqcjMsYzMKICAgICAgYycwID0gMypyMCxjMCArIDEqcjEsYzEgKyAxKnIyLGMyICsgMipyMyxjMwoKICAgICAgYycxID0gMipyMCxjMSArIDMqcjEsYzIgKyAxKnIyLGMzICsgMSpyMyxjMAogICAgICBjJzEgPSAxKnIwLGMxICsgMipyMSxjMiArIDMqcjIsYzMgKyAxKnIzLGMwCiAgICAgIGMnMSA9IDEqcjAsYzEgKyAxKnIxLGMyICsgMipyMixjMyArIDMqcjMsYzAKICAgICAgYycxID0gMypyMCxjMSArIDEqcjEsYzIgKyAxKnIyLGMzICsgMipyMyxjMAoKICAgICAgLi4uIGFuZCBzbyBmb3J0aCBmb3IgYycyIGFuZCBjJzMuIFRoZSBpbXBvcnRhbnQgZGlzdGluY3Rpb24gaXMKICAgICAgdGhhdCB0aGUgY29sdW1ucyBhcmUgY3ljbGluZywgd2l0aCBjMCBiZWluZyB1c2VkIHdpdGggdGhlIG0wCiAgICAgIG1hcCB3aGVuIGNhbGN1bGF0aW5nIGMwLCBidXQgYzEgYmVpbmcgdXNlZCB3aXRoIHRoZSBtMCBtYXAgd2hlbgogICAgICBjYWxjdWxhdGluZyBjMSAuLi4gYW5kIHNvIGZvcnRoLgoKICAgICAgV2hlbiBwZXJmb3JtaW5nIHRoZSBpbnZlcnNlIHdlIHRyYW5zZm9ybSB0aGUgbWlycm9yIGltYWdlIGFuZAogICAgICBza2lwIHRoZSBib3R0b20gcm93LCBpbnN0ZWFkIG9mIHRoZSB0b3Agb25lLCBhbmQgbW92ZSB1cHdhcmRzOgoKICAgICAgYzMgYzIgYzEgYzAgPT4gYzAgYzMgYzIgYzEgIChjeWNsZWQgMyBieXRlcykgKnNhbWUgYXMgZW5jcnlwdGlvbgogICAgICBjMyBjMiBjMSBjMCAgICBjMSBjMCBjMyBjMiAgKGN5Y2xlZCAyIGJ5dGVzKQogICAgICBjMyBjMiBjMSBjMCAgICBjMiBjMSBjMCBjMyAgKGN5Y2xlZCAxIGJ5dGUpICAqc2FtZSBhcyBlbmNyeXB0aW9uCiAgICAgIGMzIGMyIGMxIGMwICAgIGMzIGMyIGMxIGMwCgogICAgICBJZiB5b3UgY29tcGFyZSB0aGUgcmVzdWx0aW5nIG1hdHJpY2VzIGZvciBTaGlmdFJvd3MoKStNaXhDb2x1bW5zKCkKICAgICAgYW5kIGZvciBJbnZTaGlmdFJvd3MoKStJbnZNaXhDb2x1bW5zKCkgdGhlIDJuZCBhbmQgNHRoIGNvbHVtbnMgYXJlCiAgICAgIGRpZmZlcmVudCAoaW4gZW5jcnlwdCBtb2RlIHZzLiBkZWNyeXB0IG1vZGUpLiBTbyBpbiBvcmRlciB0byB1c2UKICAgICAgdGhlIHNhbWUgY29kZSB0byBoYW5kbGUgYm90aCBlbmNyeXB0aW9uIGFuZCBkZWNyeXB0aW9uLCB3ZSB3aWxsCiAgICAgIG5lZWQgdG8gZG8gc29tZSBtYXBwaW5nLgoKICAgICAgSWYgaW4gZW5jcnlwdGlvbiBtb2RlIHdlIGxldCBhPWMwLCBiPWMxLCBjPWMyLCBkPWMzLCBhbmQgcjxOPiBiZQogICAgICBhIHJvdyBudW1iZXIgaW4gdGhlIHN0YXRlLCB0aGVuIHRoZSByZXN1bHRpbmcgbWF0cml4IGluIGVuY3J5cHRpb24KICAgICAgbW9kZSBmb3IgYXBwbHlpbmcgdGhlIGFib3ZlIHRyYW5zZm9ybWF0aW9ucyB3b3VsZCBiZToKCiAgICAgIHIxOiBhIGIgYyBkCiAgICAgIHIyOiBiIGMgZCBhCiAgICAgIHIzOiBjIGQgYSBiCiAgICAgIHI0OiBkIGEgYiBjCgogICAgICBJZiB3ZSBkaWQgdGhlIHNhbWUgaW4gZGVjcnlwdGlvbiBtb2RlIHdlIHdvdWxkIGdldDoKCiAgICAgIHIxOiBhIGQgYyBiCiAgICAgIHIyOiBiIGEgZCBjCiAgICAgIHIzOiBjIGIgYSBkCiAgICAgIHI0OiBkIGMgYiBhCgogICAgICBJZiBpbnN0ZWFkIHdlIHN3YXAgZCBhbmQgYiAoc2V0IGI9YzMgYW5kIGQ9YzEpLCB0aGVuIHdlIGdldDoKCiAgICAgIHIxOiBhIGIgYyBkCiAgICAgIHIyOiBkIGEgYiBjCiAgICAgIHIzOiBjIGQgYSBiCiAgICAgIHI0OiBiIGMgZCBhCgogICAgICBOb3cgdGhlIDFzdCBhbmQgM3JkIHJvd3MgYXJlIHRoZSBzYW1lIGFzIHRoZSBlbmNyeXB0aW9uIG1hdHJpeC4gQWxsCiAgICAgIHdlIG5lZWQgdG8gZG8gdGhlbiB0byBtYWtlIHRoZSBtYXBwaW5nIGV4YWN0bHkgdGhlIHNhbWUgaXMgdG8gc3dhcAogICAgICB0aGUgMm5kIGFuZCA0dGggcm93cyB3aGVuIGluIGRlY3J5cHRpb24gbW9kZS4gVG8gZG8gdGhpcyB3aXRob3V0CiAgICAgIGhhdmluZyB0byBkbyBpdCBvbiBlYWNoIGl0ZXJhdGlvbiwgd2Ugc3dhcHBlZCB0aGUgMm5kIGFuZCA0dGggcm93cwogICAgICBpbiB0aGUgZGVjcnlwdGlvbiBrZXkgc2NoZWR1bGUuIFdlIGFsc28gaGF2ZSB0byBkbyB0aGUgc3dhcCBhYm92ZQogICAgICB3aGVuIHdlIGZpcnN0IHB1bGwgaW4gdGhlIGlucHV0IGFuZCB3aGVuIHdlIHNldCB0aGUgZmluYWwgb3V0cHV0LiAqLwogICAgYTIgPQogICAgICBtMFthID4+PiAyNF0gXgogICAgICBtMVtiID4+PiAxNiAmIDI1NV0gXgogICAgICBtMltjID4+PiA4ICYgMjU1XSBeCiAgICAgIG0zW2QgJiAyNTVdIF4gd1srK2ldOwogICAgYjIgPQogICAgICBtMFtiID4+PiAyNF0gXgogICAgICBtMVtjID4+PiAxNiAmIDI1NV0gXgogICAgICBtMltkID4+PiA4ICYgMjU1XSBeCiAgICAgIG0zW2EgJiAyNTVdIF4gd1srK2ldOwogICAgYzIgPQogICAgICBtMFtjID4+PiAyNF0gXgogICAgICBtMVtkID4+PiAxNiAmIDI1NV0gXgogICAgICBtMlthID4+PiA4ICYgMjU1XSBeCiAgICAgIG0zW2IgJiAyNTVdIF4gd1srK2ldOwogICAgZCA9CiAgICAgIG0wW2QgPj4+IDI0XSBeCiAgICAgIG0xW2EgPj4+IDE2ICYgMjU1XSBeCiAgICAgIG0yW2IgPj4+IDggJiAyNTVdIF4KICAgICAgbTNbYyAmIDI1NV0gXiB3WysraV07CiAgICBhID0gYTI7CiAgICBiID0gYjI7CiAgICBjID0gYzI7CiAgfQoKICAvKgogICAgRW5jcnlwdDoKICAgIFN1YkJ5dGVzKHN0YXRlKQogICAgU2hpZnRSb3dzKHN0YXRlKQogICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbTnIqTmIsIChOcisxKSpOYi0xXSkKCiAgICBEZWNyeXB0OgogICAgSW52U2hpZnRSb3dzKHN0YXRlKQogICAgSW52U3ViQnl0ZXMoc3RhdGUpCiAgICBBZGRSb3VuZEtleShzdGF0ZSwgd1swLCBOYi0xXSkKICAgKi8KICAgLy8gTm90ZTogcm93cyBhcmUgc2hpZnRlZCBpbmxpbmUKICBvdXRwdXRbMF0gPQogICAgKHN1YlthID4+PiAyNF0gPDwgMjQpIF4KICAgIChzdWJbYiA+Pj4gMTYgJiAyNTVdIDw8IDE2KSBeCiAgICAoc3ViW2MgPj4+IDggJiAyNTVdIDw8IDgpIF4KICAgIChzdWJbZCAmIDI1NV0pIF4gd1srK2ldOwogIG91dHB1dFtkZWNyeXB0ID8gMyA6IDFdID0KICAgIChzdWJbYiA+Pj4gMjRdIDw8IDI0KSBeCiAgICAoc3ViW2MgPj4+IDE2ICYgMjU1XSA8PCAxNikgXgogICAgKHN1YltkID4+PiA4ICYgMjU1XSA8PCA4KSBeCiAgICAoc3ViW2EgJiAyNTVdKSBeIHdbKytpXTsKICBvdXRwdXRbMl0gPQogICAgKHN1YltjID4+PiAyNF0gPDwgMjQpIF4KICAgIChzdWJbZCA+Pj4gMTYgJiAyNTVdIDw8IDE2KSBeCiAgICAoc3ViW2EgPj4+IDggJiAyNTVdIDw8IDgpIF4KICAgIChzdWJbYiAmIDI1NV0pIF4gd1srK2ldOwogIG91dHB1dFtkZWNyeXB0ID8gMSA6IDNdID0KICAgIChzdWJbZCA+Pj4gMjRdIDw8IDI0KSBeCiAgICAoc3ViW2EgPj4+IDE2ICYgMjU1XSA8PCAxNikgXgogICAgKHN1YltiID4+PiA4ICYgMjU1XSA8PCA4KSBeCiAgICAoc3ViW2MgJiAyNTVdKSBeIHdbKytpXTsKfQoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogZm9yZ2UuY2lwaGVyLmNyZWF0ZUNpcGhlcignQUVTLTxtb2RlPicsIGtleSk7CiAqIGZvcmdlLmNpcGhlci5jcmVhdGVEZWNpcGhlcignQUVTLTxtb2RlPicsIGtleSk7CiAqCiAqIENyZWF0ZXMgYSBkZXByZWNhdGVkIEFFUyBjaXBoZXIgb2JqZWN0LiBUaGlzIG9iamVjdCdzIG1vZGUgd2lsbCBkZWZhdWx0IHRvCiAqIENCQyAoY2lwaGVyLWJsb2NrLWNoYWluaW5nKS4KICoKICogVGhlIGtleSBhbmQgaXYgbWF5IGJlIGdpdmVuIGFzIGEgc3RyaW5nIG9mIGJ5dGVzLCBhbiBhcnJheSBvZiBieXRlcywgYQogKiBieXRlIGJ1ZmZlciwgb3IgYW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLgogKgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UuCiAqICAgICAgICAgIG91dHB1dCB0aGUgYnVmZmVyIHRvIHdyaXRlIHRvLgogKiAgICAgICAgICBkZWNyeXB0IHRydWUgZm9yIGRlY3J5cHRpb24sIGZhbHNlIGZvciBlbmNyeXB0aW9uLgogKiAgICAgICAgICBtb2RlIHRoZSBjaXBoZXIgbW9kZSB0byB1c2UgKGRlZmF1bHQ6ICdDQkMnKS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZnVuY3Rpb24gX2NyZWF0ZUNpcGhlcihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdmFyIG1vZGUgPSAob3B0aW9ucy5tb2RlIHx8ICdDQkMnKS50b1VwcGVyQ2FzZSgpOwogIHZhciBhbGdvcml0aG0gPSAnQUVTLScgKyBtb2RlOwoKICB2YXIgY2lwaGVyOwogIGlmKG9wdGlvbnMuZGVjcnlwdCkgewogICAgY2lwaGVyID0gZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKGFsZ29yaXRobSwgb3B0aW9ucy5rZXkpOwogIH0gZWxzZSB7CiAgICBjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKGFsZ29yaXRobSwgb3B0aW9ucy5rZXkpOwogIH0KCiAgLy8gYmFja3dhcmRzIGNvbXBhdGlibGUgc3RhcnQgQVBJCiAgdmFyIHN0YXJ0ID0gY2lwaGVyLnN0YXJ0OwogIGNpcGhlci5zdGFydCA9IGZ1bmN0aW9uKGl2LCBvcHRpb25zKSB7CiAgICAvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eTogc3VwcG9ydCBzZWNvbmQgYXJnIGFzIG91dHB1dCBidWZmZXIKICAgIHZhciBvdXRwdXQgPSBudWxsOwogICAgaWYob3B0aW9ucyBpbnN0YW5jZW9mIGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcikgewogICAgICBvdXRwdXQgPSBvcHRpb25zOwogICAgICBvcHRpb25zID0ge307CiAgICB9CiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICAgIG9wdGlvbnMub3V0cHV0ID0gb3V0cHV0OwogICAgb3B0aW9ucy5pdiA9IGl2OwogICAgc3RhcnQuY2FsbChjaXBoZXIsIG9wdGlvbnMpOwogIH07CgogIHJldHVybiBjaXBoZXI7Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ2Flcyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKAogICdqcy9hZXMnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9jaXBoZXInLCAnLi9jaXBoZXJNb2RlcycsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogT2JqZWN0IElEcyBmb3IgQVNOLjEuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEzIERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UucGtpID0gZm9yZ2UucGtpIHx8IHt9Owp2YXIgb2lkcyA9IGZvcmdlLnBraS5vaWRzID0gZm9yZ2Uub2lkcyA9IGZvcmdlLm9pZHMgfHwge307CgovLyBhbGdvcml0aG0gT0lEcwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEuMSddID0gJ3JzYUVuY3J5cHRpb24nOwpvaWRzWydyc2FFbmNyeXB0aW9uJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xLjEnOwovLyBOb3RlOiBtZDIgJiBtZDQgbm90IGltcGxlbWVudGVkCi8vb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xLjInXSA9ICdtZDJXaXRoUlNBRW5jcnlwdGlvbic7Ci8vb2lkc1snbWQyV2l0aFJTQUVuY3J5cHRpb24nXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuMic7Ci8vb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xLjMnXSA9ICdtZDRXaXRoUlNBRW5jcnlwdGlvbic7Ci8vb2lkc1snbWQ0V2l0aFJTQUVuY3J5cHRpb24nXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuMyc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS40J10gPSAnbWQ1V2l0aFJTQUVuY3J5cHRpb24nOwpvaWRzWydtZDVXaXRoUlNBRW5jcnlwdGlvbiddID0gJzEuMi44NDAuMTEzNTQ5LjEuMS40JzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xLjUnXSA9ICdzaGExV2l0aFJTQUVuY3J5cHRpb24nOwpvaWRzWydzaGExV2l0aFJTQUVuY3J5cHRpb24nXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuNSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS43J10gPSAnUlNBRVMtT0FFUCc7Cm9pZHNbJ1JTQUVTLU9BRVAnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuNyc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS44J10gPSAnbWdmMSc7Cm9pZHNbJ21nZjEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuOCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS45J10gPSAncFNwZWNpZmllZCc7Cm9pZHNbJ3BTcGVjaWZpZWQnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuOSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS4xMCddID0gJ1JTQVNTQS1QU1MnOwpvaWRzWydSU0FTU0EtUFNTJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xLjEwJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xLjExJ10gPSAnc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24nOwpvaWRzWydzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbiddID0gJzEuMi44NDAuMTEzNTQ5LjEuMS4xMSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS4xMiddID0gJ3NoYTM4NFdpdGhSU0FFbmNyeXB0aW9uJzsKb2lkc1snc2hhMzg0V2l0aFJTQUVuY3J5cHRpb24nXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuMTInOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEuMTMnXSA9ICdzaGE1MTJXaXRoUlNBRW5jcnlwdGlvbic7Cm9pZHNbJ3NoYTUxMldpdGhSU0FFbmNyeXB0aW9uJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xLjEzJzsKCm9pZHNbJzEuMy4xNC4zLjIuNyddID0gJ2Rlc0NCQyc7Cm9pZHNbJ2Rlc0NCQyddID0gJzEuMy4xNC4zLjIuNyc7CgpvaWRzWycxLjMuMTQuMy4yLjI2J10gPSAnc2hhMSc7Cm9pZHNbJ3NoYTEnXSA9ICcxLjMuMTQuMy4yLjI2JzsKb2lkc1snMi4xNi44NDAuMS4xMDEuMy40LjIuMSddID0gJ3NoYTI1Nic7Cm9pZHNbJ3NoYTI1NiddID0gJzIuMTYuODQwLjEuMTAxLjMuNC4yLjEnOwpvaWRzWycyLjE2Ljg0MC4xLjEwMS4zLjQuMi4yJ10gPSAnc2hhMzg0JzsKb2lkc1snc2hhMzg0J10gPSAnMi4xNi44NDAuMS4xMDEuMy40LjIuMic7Cm9pZHNbJzIuMTYuODQwLjEuMTAxLjMuNC4yLjMnXSA9ICdzaGE1MTInOwpvaWRzWydzaGE1MTInXSA9ICcyLjE2Ljg0MC4xLjEwMS4zLjQuMi4zJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMi41J10gPSAnbWQ1JzsKb2lkc1snbWQ1J10gPSAnMS4yLjg0MC4xMTM1NDkuMi41JzsKCi8vIHBrY3MjNyBjb250ZW50IHR5cGVzCm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy4xJ10gPSAnZGF0YSc7Cm9pZHNbJ2RhdGEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjcuMSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy4yJ10gPSAnc2lnbmVkRGF0YSc7Cm9pZHNbJ3NpZ25lZERhdGEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjcuMic7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy4zJ10gPSAnZW52ZWxvcGVkRGF0YSc7Cm9pZHNbJ2VudmVsb3BlZERhdGEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjcuMyc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy40J10gPSAnc2lnbmVkQW5kRW52ZWxvcGVkRGF0YSc7Cm9pZHNbJ3NpZ25lZEFuZEVudmVsb3BlZERhdGEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjcuNCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy41J10gPSAnZGlnZXN0ZWREYXRhJzsKb2lkc1snZGlnZXN0ZWREYXRhJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS43LjUnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjcuNiddID0gJ2VuY3J5cHRlZERhdGEnOwpvaWRzWydlbmNyeXB0ZWREYXRhJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS43LjYnOwoKLy8gcGtjcyM5IG9pZHMKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS45LjEnXSA9ICdlbWFpbEFkZHJlc3MnOwpvaWRzWydlbWFpbEFkZHJlc3MnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuMSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4yJ10gPSAndW5zdHJ1Y3R1cmVkTmFtZSc7Cm9pZHNbJ3Vuc3RydWN0dXJlZE5hbWUnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuMic7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4zJ10gPSAnY29udGVudFR5cGUnOwpvaWRzWydjb250ZW50VHlwZSddID0gJzEuMi44NDAuMTEzNTQ5LjEuOS4zJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS45LjQnXSA9ICdtZXNzYWdlRGlnZXN0JzsKb2lkc1snbWVzc2FnZURpZ2VzdCddID0gJzEuMi44NDAuMTEzNTQ5LjEuOS40JzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS45LjUnXSA9ICdzaWduaW5nVGltZSc7Cm9pZHNbJ3NpZ25pbmdUaW1lJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS45LjUnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjkuNiddID0gJ2NvdW50ZXJTaWduYXR1cmUnOwpvaWRzWydjb3VudGVyU2lnbmF0dXJlJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS45LjYnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjkuNyddID0gJ2NoYWxsZW5nZVBhc3N3b3JkJzsKb2lkc1snY2hhbGxlbmdlUGFzc3dvcmQnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuNyc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS44J10gPSAndW5zdHJ1Y3R1cmVkQWRkcmVzcyc7Cm9pZHNbJ3Vuc3RydWN0dXJlZEFkZHJlc3MnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuOCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4xNCddID0gJ2V4dGVuc2lvblJlcXVlc3QnOwpvaWRzWydleHRlbnNpb25SZXF1ZXN0J10gPSAnMS4yLjg0MC4xMTM1NDkuMS45LjE0JzsKCm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4yMCddID0gJ2ZyaWVuZGx5TmFtZSc7Cm9pZHNbJ2ZyaWVuZGx5TmFtZSddID0gJzEuMi44NDAuMTEzNTQ5LjEuOS4yMCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4yMSddID0gJ2xvY2FsS2V5SWQnOwpvaWRzWydsb2NhbEtleUlkJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS45LjIxJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS45LjIyLjEnXSA9ICd4NTA5Q2VydGlmaWNhdGUnOwpvaWRzWyd4NTA5Q2VydGlmaWNhdGUnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuMjIuMSc7CgovLyBwa2NzIzEyIHNhZmUgYmFncwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEwLjEuMSddID0gJ2tleUJhZyc7Cm9pZHNbJ2tleUJhZyddID0gJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS4xJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xMi4xMC4xLjInXSA9ICdwa2NzOFNocm91ZGVkS2V5QmFnJzsKb2lkc1sncGtjczhTaHJvdWRlZEtleUJhZyddID0gJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS4yJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xMi4xMC4xLjMnXSA9ICdjZXJ0QmFnJzsKb2lkc1snY2VydEJhZyddID0gJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS4zJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xMi4xMC4xLjQnXSA9ICdjcmxCYWcnOwpvaWRzWydjcmxCYWcnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEyLjEwLjEuNCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS41J10gPSAnc2VjcmV0QmFnJzsKb2lkc1snc2VjcmV0QmFnJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xMi4xMC4xLjUnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEwLjEuNiddID0gJ3NhZmVDb250ZW50c0JhZyc7Cm9pZHNbJ3NhZmVDb250ZW50c0JhZyddID0gJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS42JzsKCi8vIHBhc3N3b3JkLWJhc2VkLWVuY3J5cHRpb24gZm9yIHBrY3MjMTIKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS41LjEzJ10gPSAncGtjczVQQkVTMic7Cm9pZHNbJ3BrY3M1UEJFUzInXSA9ICcxLjIuODQwLjExMzU0OS4xLjUuMTMnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjUuMTInXSA9ICdwa2NzNVBCS0RGMic7Cm9pZHNbJ3BrY3M1UEJLREYyJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS41LjEyJzsKCm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMTIuMS4xJ10gPSAncGJlV2l0aFNIQUFuZDEyOEJpdFJDNCc7Cm9pZHNbJ3BiZVdpdGhTSEFBbmQxMjhCaXRSQzQnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEyLjEuMSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMTIuMS4yJ10gPSAncGJlV2l0aFNIQUFuZDQwQml0UkM0JzsKb2lkc1sncGJlV2l0aFNIQUFuZDQwQml0UkM0J10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjInOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEuMyddID0gJ3BiZVdpdGhTSEFBbmQzLUtleVRyaXBsZURFUy1DQkMnOwpvaWRzWydwYmVXaXRoU0hBQW5kMy1LZXlUcmlwbGVERVMtQ0JDJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjMnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEuNCddID0gJ3BiZVdpdGhTSEFBbmQyLUtleVRyaXBsZURFUy1DQkMnOwpvaWRzWydwYmVXaXRoU0hBQW5kMi1LZXlUcmlwbGVERVMtQ0JDJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjQnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEuNSddID0gJ3BiZVdpdGhTSEFBbmQxMjhCaXRSQzItQ0JDJzsKb2lkc1sncGJlV2l0aFNIQUFuZDEyOEJpdFJDMi1DQkMnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEyLjEuNSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMTIuMS42J10gPSAncGJld2l0aFNIQUFuZDQwQml0UkMyLUNCQyc7Cm9pZHNbJ3BiZXdpdGhTSEFBbmQ0MEJpdFJDMi1DQkMnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEyLjEuNic7CgovLyBzeW1tZXRyaWMga2V5IGFsZ29yaXRobSBvaWRzCm9pZHNbJzEuMi44NDAuMTEzNTQ5LjMuNyddID0gJ2Rlcy1FREUzLUNCQyc7Cm9pZHNbJ2Rlcy1FREUzLUNCQyddID0gJzEuMi44NDAuMTEzNTQ5LjMuNyc7Cm9pZHNbJzIuMTYuODQwLjEuMTAxLjMuNC4xLjInXSA9ICdhZXMxMjgtQ0JDJzsKb2lkc1snYWVzMTI4LUNCQyddID0gJzIuMTYuODQwLjEuMTAxLjMuNC4xLjInOwpvaWRzWycyLjE2Ljg0MC4xLjEwMS4zLjQuMS4yMiddID0gJ2FlczE5Mi1DQkMnOwpvaWRzWydhZXMxOTItQ0JDJ10gPSAnMi4xNi44NDAuMS4xMDEuMy40LjEuMjInOwpvaWRzWycyLjE2Ljg0MC4xLjEwMS4zLjQuMS40MiddID0gJ2FlczI1Ni1DQkMnOwpvaWRzWydhZXMyNTYtQ0JDJ10gPSAnMi4xNi44NDAuMS4xMDEuMy40LjEuNDInOwoKLy8gY2VydGlmaWNhdGUgaXNzdWVyL3N1YmplY3QgT0lEcwpvaWRzWycyLjUuNC4zJ10gPSAnY29tbW9uTmFtZSc7Cm9pZHNbJ2NvbW1vbk5hbWUnXSA9ICcyLjUuNC4zJzsKb2lkc1snMi41LjQuNSddID0gJ3NlcmlhbE5hbWUnOwpvaWRzWydzZXJpYWxOYW1lJ10gPSAnMi41LjQuNSc7Cm9pZHNbJzIuNS40LjYnXSA9ICdjb3VudHJ5TmFtZSc7Cm9pZHNbJ2NvdW50cnlOYW1lJ10gPSAnMi41LjQuNic7Cm9pZHNbJzIuNS40LjcnXSA9ICdsb2NhbGl0eU5hbWUnOwpvaWRzWydsb2NhbGl0eU5hbWUnXSA9ICcyLjUuNC43JzsKb2lkc1snMi41LjQuOCddID0gJ3N0YXRlT3JQcm92aW5jZU5hbWUnOwpvaWRzWydzdGF0ZU9yUHJvdmluY2VOYW1lJ10gPSAnMi41LjQuOCc7Cm9pZHNbJzIuNS40LjEwJ10gPSAnb3JnYW5pemF0aW9uTmFtZSc7Cm9pZHNbJ29yZ2FuaXphdGlvbk5hbWUnXSA9ICcyLjUuNC4xMCc7Cm9pZHNbJzIuNS40LjExJ10gPSAnb3JnYW5pemF0aW9uYWxVbml0TmFtZSc7Cm9pZHNbJ29yZ2FuaXphdGlvbmFsVW5pdE5hbWUnXSA9ICcyLjUuNC4xMSc7CgovLyBYLjUwOSBleHRlbnNpb24gT0lEcwpvaWRzWycyLjE2Ljg0MC4xLjExMzczMC4xLjEnXSA9ICduc0NlcnRUeXBlJzsKb2lkc1snbnNDZXJ0VHlwZSddID0gJzIuMTYuODQwLjEuMTEzNzMwLjEuMSc7Cm9pZHNbJzIuNS4yOS4xJ10gPSAnYXV0aG9yaXR5S2V5SWRlbnRpZmllcic7IC8vIGRlcHJlY2F0ZWQsIHVzZSAuMzUKb2lkc1snMi41LjI5LjInXSA9ICdrZXlBdHRyaWJ1dGVzJzsgLy8gb2Jzb2xldGUgdXNlIC4zNyBvciAuMTUKb2lkc1snMi41LjI5LjMnXSA9ICdjZXJ0aWZpY2F0ZVBvbGljaWVzJzsgLy8gZGVwcmVjYXRlZCwgdXNlIC4zMgpvaWRzWycyLjUuMjkuNCddID0gJ2tleVVzYWdlUmVzdHJpY3Rpb24nOyAvLyBvYnNvbGV0ZSB1c2UgLjM3IG9yIC4xNQpvaWRzWycyLjUuMjkuNSddID0gJ3BvbGljeU1hcHBpbmcnOyAvLyBkZXByZWNhdGVkIHVzZSAuMzMKb2lkc1snMi41LjI5LjYnXSA9ICdzdWJ0cmVlc0NvbnN0cmFpbnQnOyAvLyBvYnNvbGV0ZSB1c2UgLjMwCm9pZHNbJzIuNS4yOS43J10gPSAnc3ViamVjdEFsdE5hbWUnOyAvLyBkZXByZWNhdGVkIHVzZSAuMTcKb2lkc1snMi41LjI5LjgnXSA9ICdpc3N1ZXJBbHROYW1lJzsgLy8gZGVwcmVjYXRlZCB1c2UgLjE4Cm9pZHNbJzIuNS4yOS45J10gPSAnc3ViamVjdERpcmVjdG9yeUF0dHJpYnV0ZXMnOwpvaWRzWycyLjUuMjkuMTAnXSA9ICdiYXNpY0NvbnN0cmFpbnRzJzsgLy8gZGVwcmVjYXRlZCB1c2UgLjE5Cm9pZHNbJzIuNS4yOS4xMSddID0gJ25hbWVDb25zdHJhaW50cyc7IC8vIGRlcHJlY2F0ZWQgdXNlIC4zMApvaWRzWycyLjUuMjkuMTInXSA9ICdwb2xpY3lDb25zdHJhaW50cyc7IC8vIGRlcHJlY2F0ZWQgdXNlIC4zNgpvaWRzWycyLjUuMjkuMTMnXSA9ICdiYXNpY0NvbnN0cmFpbnRzJzsgLy8gZGVwcmVjYXRlZCB1c2UgLjE5Cm9pZHNbJzIuNS4yOS4xNCddID0gJ3N1YmplY3RLZXlJZGVudGlmaWVyJzsKb2lkc1snc3ViamVjdEtleUlkZW50aWZpZXInXSA9ICcyLjUuMjkuMTQnOwpvaWRzWycyLjUuMjkuMTUnXSA9ICdrZXlVc2FnZSc7Cm9pZHNbJ2tleVVzYWdlJ10gPSAnMi41LjI5LjE1JzsKb2lkc1snMi41LjI5LjE2J10gPSAncHJpdmF0ZUtleVVzYWdlUGVyaW9kJzsKb2lkc1snMi41LjI5LjE3J10gPSAnc3ViamVjdEFsdE5hbWUnOwpvaWRzWydzdWJqZWN0QWx0TmFtZSddID0gJzIuNS4yOS4xNyc7Cm9pZHNbJzIuNS4yOS4xOCddID0gJ2lzc3VlckFsdE5hbWUnOwpvaWRzWydpc3N1ZXJBbHROYW1lJ10gPSAnMi41LjI5LjE4JzsKb2lkc1snMi41LjI5LjE5J10gPSAnYmFzaWNDb25zdHJhaW50cyc7Cm9pZHNbJ2Jhc2ljQ29uc3RyYWludHMnXSA9ICcyLjUuMjkuMTknOwpvaWRzWycyLjUuMjkuMjAnXSA9ICdjUkxOdW1iZXInOwpvaWRzWycyLjUuMjkuMjEnXSA9ICdjUkxSZWFzb24nOwpvaWRzWycyLjUuMjkuMjInXSA9ICdleHBpcmF0aW9uRGF0ZSc7Cm9pZHNbJzIuNS4yOS4yMyddID0gJ2luc3RydWN0aW9uQ29kZSc7Cm9pZHNbJzIuNS4yOS4yNCddID0gJ2ludmFsaWRpdHlEYXRlJzsKb2lkc1snMi41LjI5LjI1J10gPSAnY1JMRGlzdHJpYnV0aW9uUG9pbnRzJzsgLy8gZGVwcmVjYXRlZCB1c2UgLjMxCm9pZHNbJzIuNS4yOS4yNiddID0gJ2lzc3VpbmdEaXN0cmlidXRpb25Qb2ludCc7IC8vIGRlcHJlY2F0ZWQgdXNlIC4yOApvaWRzWycyLjUuMjkuMjcnXSA9ICdkZWx0YUNSTEluZGljYXRvcic7Cm9pZHNbJzIuNS4yOS4yOCddID0gJ2lzc3VpbmdEaXN0cmlidXRpb25Qb2ludCc7Cm9pZHNbJzIuNS4yOS4yOSddID0gJ2NlcnRpZmljYXRlSXNzdWVyJzsKb2lkc1snMi41LjI5LjMwJ10gPSAnbmFtZUNvbnN0cmFpbnRzJzsKb2lkc1snMi41LjI5LjMxJ10gPSAnY1JMRGlzdHJpYnV0aW9uUG9pbnRzJzsKb2lkc1snMi41LjI5LjMyJ10gPSAnY2VydGlmaWNhdGVQb2xpY2llcyc7Cm9pZHNbJzIuNS4yOS4zMyddID0gJ3BvbGljeU1hcHBpbmdzJzsKb2lkc1snMi41LjI5LjM0J10gPSAncG9saWN5Q29uc3RyYWludHMnOyAvLyBkZXByZWNhdGVkIHVzZSAuMzYKb2lkc1snMi41LjI5LjM1J10gPSAnYXV0aG9yaXR5S2V5SWRlbnRpZmllcic7Cm9pZHNbJzIuNS4yOS4zNiddID0gJ3BvbGljeUNvbnN0cmFpbnRzJzsKb2lkc1snMi41LjI5LjM3J10gPSAnZXh0S2V5VXNhZ2UnOwpvaWRzWydleHRLZXlVc2FnZSddID0gJzIuNS4yOS4zNyc7Cm9pZHNbJzIuNS4yOS40NiddID0gJ2ZyZXNoZXN0Q1JMJzsKb2lkc1snMi41LjI5LjU0J10gPSAnaW5oaWJpdEFueVBvbGljeSc7CgovLyBleHRLZXlVc2FnZSBwdXJwb3NlcwpvaWRzWycxLjMuNi4xLjUuNS43LjMuMSddID0gJ3NlcnZlckF1dGgnOwpvaWRzWydzZXJ2ZXJBdXRoJ10gPSAnMS4zLjYuMS41LjUuNy4zLjEnOwpvaWRzWycxLjMuNi4xLjUuNS43LjMuMiddID0gJ2NsaWVudEF1dGgnOwpvaWRzWydjbGllbnRBdXRoJ10gPSAnMS4zLjYuMS41LjUuNy4zLjInOwpvaWRzWycxLjMuNi4xLjUuNS43LjMuMyddID0gJ2NvZGVTaWduaW5nJzsKb2lkc1snY29kZVNpZ25pbmcnXSA9ICcxLjMuNi4xLjUuNS43LjMuMyc7Cm9pZHNbJzEuMy42LjEuNS41LjcuMy40J10gPSAnZW1haWxQcm90ZWN0aW9uJzsKb2lkc1snZW1haWxQcm90ZWN0aW9uJ10gPSAnMS4zLjYuMS41LjUuNy4zLjQnOwpvaWRzWycxLjMuNi4xLjUuNS43LjMuOCddID0gJ3RpbWVTdGFtcGluZyc7Cm9pZHNbJ3RpbWVTdGFtcGluZyddID0gJzEuMy42LjEuNS41LjcuMy44JzsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ29pZHMnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvb2lkcycsWydyZXF1aXJlJywgJ21vZHVsZSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIEFic3RyYWN0IFN5bnRheCBOb3RhdGlvbiBOdW1iZXIgT25lLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNSBEaWdpdGFsIEJhemFhciwgSW5jLgogKgogKiBBbiBBUEkgZm9yIHN0b3JpbmcgZGF0YSB1c2luZyB0aGUgQWJzdHJhY3QgU3ludGF4IE5vdGF0aW9uIE51bWJlciBPbmUKICogZm9ybWF0IHVzaW5nIERFUiAoRGlzdGluZ3Vpc2hlZCBFbmNvZGluZyBSdWxlcykgZW5jb2RpbmcuIFRoaXMgZW5jb2RpbmcgaXMKICogY29tbW9ubHkgdXNlZCB0byBzdG9yZSBkYXRhIGZvciBQS0ksIGkuZS4gWC41MDkgQ2VydGlmaWNhdGVzLCBhbmQgdGhpcwogKiBpbXBsZW1lbnRhdGlvbiBleGlzdHMgZm9yIHRoYXQgcHVycG9zZS4KICoKICogQWJzdHJhY3QgU3ludGF4IE5vdGF0aW9uIE51bWJlciBPbmUgKEFTTi4xKSBpcyB1c2VkIHRvIGRlZmluZSB0aGUgYWJzdHJhY3QKICogc3ludGF4IG9mIGluZm9ybWF0aW9uIHdpdGhvdXQgcmVzdHJpY3RpbmcgdGhlIHdheSB0aGUgaW5mb3JtYXRpb24gaXMgZW5jb2RlZAogKiBmb3IgdHJhbnNtaXNzaW9uLiBJdCBwcm92aWRlcyBhIHN0YW5kYXJkIHRoYXQgYWxsb3dzIGZvciBvcGVuIHN5c3RlbXMKICogY29tbXVuaWNhdGlvbi4gQVNOLjEgZGVmaW5lcyB0aGUgc3ludGF4IG9mIGluZm9ybWF0aW9uIGRhdGEgYW5kIGEgbnVtYmVyIG9mCiAqIHNpbXBsZSBkYXRhIHR5cGVzIGFzIHdlbGwgYXMgYSBub3RhdGlvbiBmb3IgZGVzY3JpYmluZyB0aGVtIGFuZCBzcGVjaWZ5aW5nCiAqIHZhbHVlcyBmb3IgdGhlbS4KICoKICogVGhlIFJTQSBhbGdvcml0aG0gY3JlYXRlcyBwdWJsaWMgYW5kIHByaXZhdGUga2V5cyB0aGF0IGFyZSBvZnRlbiBzdG9yZWQgaW4KICogWC41MDkgb3IgUEtDUyNYIGZvcm1hdHMgLS0gd2hpY2ggdXNlIEFTTi4xIChlbmNvZGVkIGluIERFUiBmb3JtYXQpLiBUaGlzCiAqIGNsYXNzIHByb3ZpZGVzIHRoZSBtb3N0IGJhc2ljIGZ1bmN0aW9uYWxpdHkgcmVxdWlyZWQgdG8gc3RvcmUgYW5kIGxvYWQgRFNBCiAqIGtleXMgdGhhdCBhcmUgZW5jb2RlZCBhY2NvcmRpbmcgdG8gQVNOLjEuCiAqCiAqIFRoZSBtb3N0IGNvbW1vbiBiaW5hcnkgZW5jb2RpbmdzIGZvciBBU04uMSBhcmUgQkVSIChCYXNpYyBFbmNvZGluZyBSdWxlcykKICogYW5kIERFUiAoRGlzdGluZ3Vpc2hlZCBFbmNvZGluZyBSdWxlcykuIERFUiBpcyBqdXN0IGEgc3Vic2V0IG9mIEJFUiB0aGF0CiAqIGhhcyBzdHJpY3RlciByZXF1aXJlbWVudHMgZm9yIGhvdyBkYXRhIG11c3QgYmUgZW5jb2RlZC4KICoKICogRWFjaCBBU04uMSBzdHJ1Y3R1cmUgaGFzIGEgdGFnIChhIGJ5dGUgaWRlbnRpZnlpbmcgdGhlIEFTTi4xIHN0cnVjdHVyZSB0eXBlKQogKiBhbmQgYSBieXRlIGFycmF5IGZvciB0aGUgdmFsdWUgb2YgdGhpcyBBU04xIHN0cnVjdHVyZSB3aGljaCBtYXkgYmUgZGF0YSBvciBhCiAqIGxpc3Qgb2YgQVNOLjEgc3RydWN0dXJlcy4KICoKICogRWFjaCBBU04uMSBzdHJ1Y3R1cmUgdXNpbmcgQkVSIGlzIChUYWctTGVuZ3RoLVZhbHVlKToKICoKICogfCBieXRlIDAgfCBieXRlcyBYIHwgYnl0ZXMgWSB8CiAqIHwtLS0tLS0tLXwtLS0tLS0tLS18LS0tLS0tLS0tLQogKiB8ICB0YWcgICB8IGxlbmd0aCAgfCAgdmFsdWUgIHwKICoKICogQVNOLjEgYWxsb3dzIGZvciB0YWdzIHRvIGJlIG9mICJIaWdoLXRhZy1udW1iZXIgZm9ybSIgd2hpY2ggYWxsb3dzIGEgdGFnIHRvCiAqIGJlIHR3byBvciBtb3JlIG9jdGV0cywgYnV0IHRoYXQgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGNsYXNzLiBBIHRhZyBpcwogKiBvbmx5IDEgYnl0ZS4gQml0cyAxLTUgZ2l2ZSB0aGUgdGFnIG51bWJlciAoaWUgdGhlIGRhdGEgdHlwZSB3aXRoaW4gYQogKiBwYXJ0aWN1bGFyICdjbGFzcycpLCA2IGluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgQVNOLjEgdmFsdWUgaXMKICogY29uc3RydWN0ZWQgZnJvbSBvdGhlciBBU04uMSB2YWx1ZXMsIGFuZCBiaXRzIDcgYW5kIDggZ2l2ZSB0aGUgJ2NsYXNzJy4gSWYKICogYml0cyA3IGFuZCA4IGFyZSBib3RoIHplcm8sIHRoZSBjbGFzcyBpcyBVTklWRVJTQUwuIElmIG9ubHkgYml0IDcgaXMgc2V0LAogKiB0aGVuIHRoZSBjbGFzcyBpcyBBUFBMSUNBVElPTi4gSWYgb25seSBiaXQgOCBpcyBzZXQsIHRoZW4gdGhlIGNsYXNzIGlzCiAqIENPTlRFWFRfU1BFQ0lGSUMuIElmIGJvdGggYml0cyA3IGFuZCA4IGFyZSBzZXQsIHRoZW4gdGhlIGNsYXNzIGlzIFBSSVZBVEUuCiAqIFRoZSB0YWcgbnVtYmVycyBmb3IgdGhlIGRhdGEgdHlwZXMgZm9yIHRoZSBjbGFzcyBVTklWRVJTQUwgYXJlIGxpc3RlZCBiZWxvdzoKICoKICogVU5JVkVSU0FMIDAgUmVzZXJ2ZWQgZm9yIHVzZSBieSB0aGUgZW5jb2RpbmcgcnVsZXMKICogVU5JVkVSU0FMIDEgQm9vbGVhbiB0eXBlCiAqIFVOSVZFUlNBTCAyIEludGVnZXIgdHlwZQogKiBVTklWRVJTQUwgMyBCaXRzdHJpbmcgdHlwZQogKiBVTklWRVJTQUwgNCBPY3RldHN0cmluZyB0eXBlCiAqIFVOSVZFUlNBTCA1IE51bGwgdHlwZQogKiBVTklWRVJTQUwgNiBPYmplY3QgaWRlbnRpZmllciB0eXBlCiAqIFVOSVZFUlNBTCA3IE9iamVjdCBkZXNjcmlwdG9yIHR5cGUKICogVU5JVkVSU0FMIDggRXh0ZXJuYWwgdHlwZSBhbmQgSW5zdGFuY2Utb2YgdHlwZQogKiBVTklWRVJTQUwgOSBSZWFsIHR5cGUKICogVU5JVkVSU0FMIDEwIEVudW1lcmF0ZWQgdHlwZQogKiBVTklWRVJTQUwgMTEgRW1iZWRkZWQtcGR2IHR5cGUKICogVU5JVkVSU0FMIDEyIFVURjhTdHJpbmcgdHlwZQogKiBVTklWRVJTQUwgMTMgUmVsYXRpdmUgb2JqZWN0IGlkZW50aWZpZXIgdHlwZQogKiBVTklWRVJTQUwgMTQtMTUgUmVzZXJ2ZWQgZm9yIGZ1dHVyZSBlZGl0aW9ucwogKiBVTklWRVJTQUwgMTYgU2VxdWVuY2UgYW5kIFNlcXVlbmNlLW9mIHR5cGVzCiAqIFVOSVZFUlNBTCAxNyBTZXQgYW5kIFNldC1vZiB0eXBlcwogKiBVTklWRVJTQUwgMTgtMjIsIDI1LTMwIENoYXJhY3RlciBzdHJpbmcgdHlwZXMKICogVU5JVkVSU0FMIDIzLTI0IFRpbWUgdHlwZXMKICoKICogVGhlIGxlbmd0aCBvZiBhbiBBU04uMSBzdHJ1Y3R1cmUgaXMgc3BlY2lmaWVkIGFmdGVyIHRoZSB0YWcgaWRlbnRpZmllci4KICogVGhlcmUgaXMgYSBkZWZpbml0ZSBmb3JtIGFuZCBhbiBpbmRlZmluaXRlIGZvcm0uIFRoZSBpbmRlZmluaXRlIGZvcm0gbWF5CiAqIGJlIHVzZWQgaWYgdGhlIGVuY29kaW5nIGlzIGNvbnN0cnVjdGVkIGFuZCBub3QgYWxsIGltbWVkaWF0ZWx5IGF2YWlsYWJsZS4KICogVGhlIGluZGVmaW5pdGUgZm9ybSBpcyBlbmNvZGVkIHVzaW5nIGEgbGVuZ3RoIGJ5dGUgd2l0aCBvbmx5IHRoZSA4dGggYml0CiAqIHNldC4gVGhlIGVuZCBvZiB0aGUgY29uc3RydWN0ZWQgb2JqZWN0IGlzIG1hcmtlZCB1c2luZyBlbmQtb2YtY29udGVudHMKICogb2N0ZXRzICh0d28gemVybyBieXRlcykuCiAqCiAqIFRoZSBkZWZpbml0ZSBmb3JtIGxvb2tzIGxpa2UgdGhpczoKICoKICogVGhlIGxlbmd0aCBtYXkgdGFrZSB1cCAxIG9yIG1vcmUgYnl0ZXMsIGl0IGRlcGVuZHMgb24gdGhlIGxlbmd0aCBvZiB0aGUKICogdmFsdWUgb2YgdGhlIEFTTi4xIHN0cnVjdHVyZS4gREVSIGVuY29kaW5nIHJlcXVpcmVzIHRoYXQgaWYgdGhlIEFTTi4xCiAqIHN0cnVjdHVyZSBoYXMgYSB2YWx1ZSB0aGF0IGhhcyBhIGxlbmd0aCBncmVhdGVyIHRoYW4gMTI3LCBtb3JlIHRoYW4gMSBieXRlCiAqIHdpbGwgYmUgdXNlZCB0byBzdG9yZSBpdHMgbGVuZ3RoLCBvdGhlcndpc2UganVzdCBvbmUgYnl0ZSB3aWxsIGJlIHVzZWQuCiAqIFRoaXMgaXMgc3RyaWN0LgogKgogKiBJbiB0aGUgY2FzZSB0aGF0IHRoZSBsZW5ndGggb2YgdGhlIEFTTi4xIHZhbHVlIGlzIGxlc3MgdGhhbiAxMjcsIDEgb2N0ZXQKICogKGJ5dGUpIGlzIHVzZWQgdG8gc3RvcmUgdGhlICJzaG9ydCBmb3JtIiBsZW5ndGguIFRoZSA4dGggYml0IGhhcyBhIHZhbHVlIG9mCiAqIDAgaW5kaWNhdGluZyB0aGUgbGVuZ3RoIGlzICJzaG9ydCBmb3JtIiBhbmQgbm90ICJsb25nIGZvcm0iIGFuZCBiaXRzIDctMQogKiBnaXZlIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEuIChUaGUgOHRoIGJpdCBpcyB0aGUgbGVmdC1tb3N0LCBtb3N0IHNpZ25pZmljYW50CiAqIGJpdDogYWxzbyBrbm93biBhcyBiaWcgZW5kaWFuIG9yIG5ldHdvcmsgZm9ybWF0KS4KICoKICogSW4gdGhlIGNhc2UgdGhhdCB0aGUgbGVuZ3RoIG9mIHRoZSBBU04uMSB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gMTI3LCAyIHRvCiAqIDEyNyBvY3RldHMgKGJ5dGVzKSBhcmUgdXNlZCB0byBzdG9yZSB0aGUgImxvbmcgZm9ybSIgbGVuZ3RoLiBUaGUgZmlyc3QKICogYnl0ZSdzIDh0aCBiaXQgaXMgc2V0IHRvIDEgdG8gaW5kaWNhdGUgdGhlIGxlbmd0aCBpcyAibG9uZyBmb3JtLiIgQml0cyA3LTEKICogZ2l2ZSB0aGUgbnVtYmVyIG9mIGFkZGl0aW9uYWwgb2N0ZXRzLiBBbGwgZm9sbG93aW5nIG9jdGV0cyBhcmUgaW4gYmFzZSAyNTYKICogd2l0aCB0aGUgbW9zdCBzaWduaWZpY2FudCBkaWdpdCBmaXJzdCAodHlwaWNhbCBiaWctZW5kaWFuIGJpbmFyeSB1bnNpZ25lZAogKiBpbnRlZ2VyIHN0b3JhZ2UpLiBTbywgZm9yIGluc3RhbmNlLCBpZiB0aGUgbGVuZ3RoIG9mIGEgdmFsdWUgd2FzIDI1NywgdGhlCiAqIGZpcnN0IGJ5dGUgd291bGQgYmUgc2V0IHRvOgogKgogKiAxMDAwMDAxMCA9IDEzMCA9IDB4ODIuCiAqCiAqIFRoaXMgaW5kaWNhdGVzIHRoZXJlIGFyZSAyIG9jdGV0cyAoYmFzZSAyNTYpIGZvciB0aGUgbGVuZ3RoLiBUaGUgc2Vjb25kIGFuZAogKiB0aGlyZCBieXRlcyAodGhlIG9jdGV0cyBqdXN0IG1lbnRpb25lZCkgd291bGQgc3RvcmUgdGhlIGxlbmd0aCBpbiBiYXNlIDI1NjoKICoKICogb2N0ZXQgMjogMDAwMDAwMDEgPSAxICogMjU2XjEgPSAyNTYKICogb2N0ZXQgMzogMDAwMDAwMDEgPSAxICogMjU2XjAgPSAxCiAqIHRvdGFsID0gMjU3CiAqCiAqIFRoZSBhbGdvcml0aG0gZm9yIGNvbnZlcnRpbmcgYSBqcyBpbnRlZ2VyIHZhbHVlIG9mIDI1NyB0byBiYXNlLTI1NiBpczoKICoKICogdmFyIHZhbHVlID0gMjU3OwogKiB2YXIgYnl0ZXMgPSBbXTsKICogYnl0ZXNbMF0gPSAodmFsdWUgPj4+IDgpICYgMHhGRjsgLy8gbW9zdCBzaWduaWZpY2FudCBieXRlIGZpcnN0CiAqIGJ5dGVzWzFdID0gdmFsdWUgJiAweEZGOyAgICAgICAgLy8gbGVhc3Qgc2lnbmlmaWNhbnQgYnl0ZSBsYXN0CiAqCiAqIE9uIHRoZSBBU04uMSBVTklWRVJTQUwgT2JqZWN0IElkZW50aWZpZXIgKE9JRCkgdHlwZToKICoKICogQW4gT0lEIGNhbiBiZSB3cml0dGVuIGxpa2U6ICJ2YWx1ZTEudmFsdWUyLnZhbHVlMy4uLnZhbHVlTiIKICoKICogVGhlIERFUiBlbmNvZGluZyBydWxlczoKICoKICogVGhlIGZpcnN0IGJ5dGUgaGFzIHRoZSB2YWx1ZSA0MCAqIHZhbHVlMSArIHZhbHVlMi4KICogVGhlIGZvbGxvd2luZyBieXRlcywgaWYgYW55LCBlbmNvZGUgdGhlIHJlbWFpbmluZyB2YWx1ZXMuIEVhY2ggdmFsdWUgaXMKICogZW5jb2RlZCBpbiBiYXNlIDEyOCwgbW9zdCBzaWduaWZpY2FudCBkaWdpdCBmaXJzdCAoYmlnIGVuZGlhbiksIHdpdGggYXMKICogZmV3IGRpZ2l0cyBhcyBwb3NzaWJsZSwgYW5kIHRoZSBtb3N0IHNpZ25pZmljYW50IGJpdCBvZiBlYWNoIGJ5dGUgc2V0CiAqIHRvIDEgZXhjZXB0IHRoZSBsYXN0IGluIGVhY2ggdmFsdWUncyBlbmNvZGluZy4gRm9yIGV4YW1wbGU6IEdpdmVuIHRoZQogKiBPSUQgIjEuMi44NDAuMTEzNTQ5IiwgaXRzIERFUiBlbmNvZGluZyBpcyAocmVtZW1iZXIgZWFjaCBieXRlIGV4Y2VwdCB0aGUKICogbGFzdCBvbmUgaW4gZWFjaCBlbmNvZGluZyBpcyBPUidkIHdpdGggMHg4MCk6CiAqCiAqIGJ5dGUgMTogNDAgKiAxICsgMiA9IDQyID0gMHgyQS4KICogYnl0ZXMgMi0zOiAxMjggKiA2ICsgNzIgPSA4NDAgPSA2IDcyID0gNiA3MiA9IDB4MDY0OCA9IDB4ODY0OAogKiBieXRlcyA0LTY6IDE2Mzg0ICogNiArIDEyOCAqIDExOSArIDEzID0gNiAxMTkgMTMgPSAweDA2NzcwRCA9IDB4ODZGNzBECiAqCiAqIFRoZSBmaW5hbCB2YWx1ZSBpczogMHgyQTg2NDg4NkY3MEQuCiAqIFRoZSBmdWxsIE9JRCAoaW5jbHVkaW5nIEFTTi4xIHRhZyBhbmQgbGVuZ3RoIG9mIDYgYnl0ZXMpIGlzOgogKiAweDA2MDYyQTg2NDg4NkY3MEQKICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovKiBBU04uMSBBUEkgKi8KdmFyIGFzbjEgPSBmb3JnZS5hc24xID0gZm9yZ2UuYXNuMSB8fCB7fTsKCi8qKgogKiBBU04uMSBjbGFzc2VzLgogKi8KYXNuMS5DbGFzcyA9IHsKICBVTklWRVJTQUw6ICAgICAgICAweDAwLAogIEFQUExJQ0FUSU9OOiAgICAgIDB4NDAsCiAgQ09OVEVYVF9TUEVDSUZJQzogMHg4MCwKICBQUklWQVRFOiAgICAgICAgICAweEMwCn07CgovKioKICogQVNOLjEgdHlwZXMuIE5vdCBhbGwgdHlwZXMgYXJlIHN1cHBvcnRlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uLCBvbmx5CiAqIHRob3NlIG5lY2Vzc2FyeSB0byBpbXBsZW1lbnQgYSBzaW1wbGUgUEtJIGFyZSBpbXBsZW1lbnRlZC4KICovCmFzbjEuVHlwZSA9IHsKICBOT05FOiAgICAgICAgICAgICAwLAogIEJPT0xFQU46ICAgICAgICAgIDEsCiAgSU5URUdFUjogICAgICAgICAgMiwKICBCSVRTVFJJTkc6ICAgICAgICAzLAogIE9DVEVUU1RSSU5HOiAgICAgIDQsCiAgTlVMTDogICAgICAgICAgICAgNSwKICBPSUQ6ICAgICAgICAgICAgICA2LAogIE9ERVNDOiAgICAgICAgICAgIDcsCiAgRVhURVJOQUw6ICAgICAgICAgOCwKICBSRUFMOiAgICAgICAgICAgICA5LAogIEVOVU1FUkFURUQ6ICAgICAgMTAsCiAgRU1CRURERUQ6ICAgICAgICAxMSwKICBVVEY4OiAgICAgICAgICAgIDEyLAogIFJPSUQ6ICAgICAgICAgICAgMTMsCiAgU0VRVUVOQ0U6ICAgICAgICAxNiwKICBTRVQ6ICAgICAgICAgICAgIDE3LAogIFBSSU5UQUJMRVNUUklORzogMTksCiAgSUE1U1RSSU5HOiAgICAgICAyMiwKICBVVENUSU1FOiAgICAgICAgIDIzLAogIEdFTkVSQUxJWkVEVElNRTogMjQsCiAgQk1QU1RSSU5HOiAgICAgICAzMAp9OwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgYXNuMSBvYmplY3QuCiAqCiAqIEBwYXJhbSB0YWdDbGFzcyB0aGUgdGFnIGNsYXNzIGZvciB0aGUgb2JqZWN0LgogKiBAcGFyYW0gdHlwZSB0aGUgZGF0YSB0eXBlICh0YWcgbnVtYmVyKSBmb3IgdGhlIG9iamVjdC4KICogQHBhcmFtIGNvbnN0cnVjdGVkIHRydWUgaWYgdGhlIGFzbjEgb2JqZWN0IGlzIGluIGNvbnN0cnVjdGVkIGZvcm0uCiAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgZm9yIHRoZSBvYmplY3QsIGlmIGl0IGlzIG5vdCBjb25zdHJ1Y3RlZC4KICoKICogQHJldHVybiB0aGUgYXNuMSBvYmplY3QuCiAqLwphc24xLmNyZWF0ZSA9IGZ1bmN0aW9uKHRhZ0NsYXNzLCB0eXBlLCBjb25zdHJ1Y3RlZCwgdmFsdWUpIHsKICAvKiBBbiBhc24xIG9iamVjdCBoYXMgYSB0YWdDbGFzcywgYSB0eXBlLCBhIGNvbnN0cnVjdGVkIGZsYWcsIGFuZCBhCiAgICB2YWx1ZS4gVGhlIHZhbHVlJ3MgdHlwZSBkZXBlbmRzIG9uIHRoZSBjb25zdHJ1Y3RlZCBmbGFnLiBJZgogICAgY29uc3RydWN0ZWQsIGl0IHdpbGwgY29udGFpbiBhIGxpc3Qgb2Ygb3RoZXIgYXNuMSBvYmplY3RzLiBJZiBub3QsCiAgICBpdCB3aWxsIGNvbnRhaW4gdGhlIEFTTi4xIHZhbHVlIGFzIGFuIGFycmF5IG9mIGJ5dGVzIGZvcm1hdHRlZAogICAgYWNjb3JkaW5nIHRvIHRoZSBBU04uMSBkYXRhIHR5cGUuICovCgogIC8vIHJlbW92ZSB1bmRlZmluZWQgdmFsdWVzCiAgaWYoZm9yZ2UudXRpbC5pc0FycmF5KHZhbHVlKSkgewogICAgdmFyIHRtcCA9IFtdOwogICAgZm9yKHZhciBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgKytpKSB7CiAgICAgIGlmKHZhbHVlW2ldICE9PSB1bmRlZmluZWQpIHsKICAgICAgICB0bXAucHVzaCh2YWx1ZVtpXSk7CiAgICAgIH0KICAgIH0KICAgIHZhbHVlID0gdG1wOwogIH0KCiAgcmV0dXJuIHsKICAgIHRhZ0NsYXNzOiB0YWdDbGFzcywKICAgIHR5cGU6IHR5cGUsCiAgICBjb25zdHJ1Y3RlZDogY29uc3RydWN0ZWQsCiAgICBjb21wb3NlZDogY29uc3RydWN0ZWQgfHwgZm9yZ2UudXRpbC5pc0FycmF5KHZhbHVlKSwKICAgIHZhbHVlOiB2YWx1ZQogIH07Cn07CgovKioKICogR2V0cyB0aGUgbGVuZ3RoIG9mIGEgQkVSLWVuY29kZWQgQVNOLjEgdmFsdWUuCiAqCiAqIEluIGNhc2UgdGhlIGxlbmd0aCBpcyBub3Qgc3BlY2lmaWVkLCB1bmRlZmluZWQgaXMgcmV0dXJuZWQuCiAqCiAqIEBwYXJhbSBiIHRoZSBCRVItZW5jb2RlZCBBU04uMSBieXRlIGJ1ZmZlciwgc3RhcnRpbmcgd2l0aCB0aGUgZmlyc3QKICogICAgICAgICAgbGVuZ3RoIGJ5dGUuCiAqCiAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgQkVSLWVuY29kZWQgQVNOLjEgdmFsdWUgb3IgdW5kZWZpbmVkLgogKi8KdmFyIF9nZXRWYWx1ZUxlbmd0aCA9IGFzbjEuZ2V0QmVyVmFsdWVMZW5ndGggPSBmdW5jdGlvbihiKSB7CiAgLy8gVE9ETzogbW92ZSB0aGlzIGZ1bmN0aW9uIGFuZCByZWxhdGVkIERFUi9CRVIgZnVuY3Rpb25zIHRvIGEgZGVyLmpzCiAgLy8gZmlsZTsgYmV0dGVyIGFic3RyYWN0IEFTTi4xIGF3YXkgZnJvbSBkZXIvYmVyLgogIHZhciBiMiA9IGIuZ2V0Qnl0ZSgpOwogIGlmKGIyID09PSAweDgwKSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0KCiAgLy8gc2VlIGlmIHRoZSBsZW5ndGggaXMgInNob3J0IGZvcm0iIG9yICJsb25nIGZvcm0iIChiaXQgOCBzZXQpCiAgdmFyIGxlbmd0aDsKICB2YXIgbG9uZ0Zvcm0gPSBiMiAmIDB4ODA7CiAgaWYoIWxvbmdGb3JtKSB7CiAgICAvLyBsZW5ndGggaXMganVzdCB0aGUgZmlyc3QgYnl0ZQogICAgbGVuZ3RoID0gYjI7CiAgfSBlbHNlIHsKICAgIC8vIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhlIGxlbmd0aCBpcyBzcGVjaWZpZWQgaW4gYml0cyA3IHRocm91Z2ggMQogICAgLy8gYW5kIGVhY2ggbGVuZ3RoIGJ5dGUgaXMgaW4gYmlnLWVuZGlhbiBiYXNlLTI1NgogICAgbGVuZ3RoID0gYi5nZXRJbnQoKGIyICYgMHg3RikgPDwgMyk7CiAgfQogIHJldHVybiBsZW5ndGg7Cn07CgovKioKICogUGFyc2VzIGFuIGFzbjEgb2JqZWN0IGZyb20gYSBieXRlIGJ1ZmZlciBpbiBERVIgZm9ybWF0LgogKgogKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYnVmZmVyIHRvIHBhcnNlIGZyb20uCiAqIEBwYXJhbSBzdHJpY3QgdHJ1ZSB0byBiZSBzdHJpY3Qgd2hlbiBjaGVja2luZyB2YWx1ZSBsZW5ndGhzLCBmYWxzZSB0bwogKiAgICAgICAgICBhbGxvdyB0cnVuY2F0ZWQgdmFsdWVzIChkZWZhdWx0OiB0cnVlKS4KICoKICogQHJldHVybiB0aGUgcGFyc2VkIGFzbjEgb2JqZWN0LgogKi8KYXNuMS5mcm9tRGVyID0gZnVuY3Rpb24oYnl0ZXMsIHN0cmljdCkgewogIGlmKHN0cmljdCA9PT0gdW5kZWZpbmVkKSB7CiAgICBzdHJpY3QgPSB0cnVlOwogIH0KCiAgLy8gd3JhcCBpbiBidWZmZXIgaWYgbmVlZGVkCiAgaWYodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykgewogICAgYnl0ZXMgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihieXRlcyk7CiAgfQoKICAvLyBtaW5pbXVtIGxlbmd0aCBmb3IgQVNOLjEgREVSIHN0cnVjdHVyZSBpcyAyCiAgaWYoYnl0ZXMubGVuZ3RoKCkgPCAyKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1RvbyBmZXcgYnl0ZXMgdG8gcGFyc2UgREVSLicpOwogICAgZXJyb3IuYnl0ZXMgPSBieXRlcy5sZW5ndGgoKTsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gZ2V0IHRoZSBmaXJzdCBieXRlCiAgdmFyIGIxID0gYnl0ZXMuZ2V0Qnl0ZSgpOwoKICAvLyBnZXQgdGhlIHRhZyBjbGFzcwogIHZhciB0YWdDbGFzcyA9IChiMSAmIDB4QzApOwoKICAvLyBnZXQgdGhlIHR5cGUgKGJpdHMgMS01KQogIHZhciB0eXBlID0gYjEgJiAweDFGOwoKICAvLyBnZXQgdGhlIHZhbHVlIGxlbmd0aAogIHZhciBsZW5ndGggPSBfZ2V0VmFsdWVMZW5ndGgoYnl0ZXMpOwoKICAvLyBlbnN1cmUgdGhlcmUgYXJlIGVub3VnaCBieXRlcyB0byBnZXQgdGhlIHZhbHVlCiAgaWYoYnl0ZXMubGVuZ3RoKCkgPCBsZW5ndGgpIHsKICAgIGlmKHN0cmljdCkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1RvbyBmZXcgYnl0ZXMgdG8gcmVhZCBBU04uMSB2YWx1ZS4nKTsKICAgICAgZXJyb3IuZGV0YWlsID0gYnl0ZXMubGVuZ3RoKCkgKyAnIDwgJyArIGxlbmd0aDsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CiAgICAvLyBOb3RlOiBiZSBsZW5pZW50IHdpdGggdHJ1bmNhdGVkIHZhbHVlcwogICAgbGVuZ3RoID0gYnl0ZXMubGVuZ3RoKCk7CiAgfQoKICAvLyBwcmVwYXJlIHRvIGdldCB2YWx1ZQogIHZhciB2YWx1ZTsKCiAgLy8gY29uc3RydWN0ZWQgZmxhZyBpcyBiaXQgNiAoMzIgPSAweDIwKSBvZiB0aGUgZmlyc3QgYnl0ZQogIHZhciBjb25zdHJ1Y3RlZCA9ICgoYjEgJiAweDIwKSA9PT0gMHgyMCk7CgogIC8vIGRldGVybWluZSBpZiB0aGUgdmFsdWUgaXMgY29tcG9zZWQgb2Ygb3RoZXIgQVNOLjEgb2JqZWN0cyAoaWYgaXRzCiAgLy8gY29uc3RydWN0ZWQgaXQgd2lsbCBiZSBhbmQgaWYgaXRzIGEgQklUU1RSSU5HIGl0IG1heSBiZSkKICB2YXIgY29tcG9zZWQgPSBjb25zdHJ1Y3RlZDsKICBpZighY29tcG9zZWQgJiYgdGFnQ2xhc3MgPT09IGFzbjEuQ2xhc3MuVU5JVkVSU0FMICYmCiAgICB0eXBlID09PSBhc24xLlR5cGUuQklUU1RSSU5HICYmIGxlbmd0aCA+IDEpIHsKICAgIC8qIFRoZSBmaXJzdCBvY3RldCBnaXZlcyB0aGUgbnVtYmVyIG9mIGJpdHMgYnkgd2hpY2ggdGhlIGxlbmd0aCBvZiB0aGUKICAgICAgYml0IHN0cmluZyBpcyBsZXNzIHRoYW4gdGhlIG5leHQgbXVsdGlwbGUgb2YgZWlnaHQgKHRoaXMgaXMgY2FsbGVkCiAgICAgIHRoZSAibnVtYmVyIG9mIHVudXNlZCBiaXRzIikuCgogICAgICBUaGUgc2Vjb25kIGFuZCBmb2xsb3dpbmcgb2N0ZXRzIGdpdmUgdGhlIHZhbHVlIG9mIHRoZSBiaXQgc3RyaW5nCiAgICAgIGNvbnZlcnRlZCB0byBhbiBvY3RldCBzdHJpbmcuICovCiAgICAvLyBpZiB0aGVyZSBhcmUgbm8gdW51c2VkIGJpdHMsIG1heWJlIHRoZSBiaXRzdHJpbmcgaG9sZHMgQVNOLjEgb2JqcwogICAgdmFyIHJlYWQgPSBieXRlcy5yZWFkOwogICAgdmFyIHVudXNlZCA9IGJ5dGVzLmdldEJ5dGUoKTsKICAgIGlmKHVudXNlZCA9PT0gMCkgewogICAgICAvLyBpZiB0aGUgZmlyc3QgYnl0ZSBpbmRpY2F0ZXMgVU5JVkVSU0FMIG9yIENPTlRFWFRfU1BFQ0lGSUMsCiAgICAgIC8vIGFuZCB0aGUgbGVuZ3RoIGlzIHZhbGlkLCBhc3N1bWUgd2UndmUgZ290IGFuIEFTTi4xIG9iamVjdAogICAgICBiMSA9IGJ5dGVzLmdldEJ5dGUoKTsKICAgICAgdmFyIHRjID0gKGIxICYgMHhDMCk7CiAgICAgIGlmKHRjID09PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fCB0YyA9PT0gYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHZhciBsZW4gPSBfZ2V0VmFsdWVMZW5ndGgoYnl0ZXMpOwogICAgICAgICAgY29tcG9zZWQgPSAobGVuID09PSBsZW5ndGggLSAoYnl0ZXMucmVhZCAtIHJlYWQpKTsKICAgICAgICAgIGlmKGNvbXBvc2VkKSB7CiAgICAgICAgICAgIC8vIGFkanVzdCByZWFkL2xlbmd0aCB0byBhY2NvdW50IGZvciB1bnVzZWQgYml0cyBieXRlCiAgICAgICAgICAgICsrcmVhZDsKICAgICAgICAgICAgLS1sZW5ndGg7CiAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaChleCkge30KICAgICAgfQogICAgfQogICAgLy8gcmVzdG9yZSByZWFkIHBvaW50ZXIKICAgIGJ5dGVzLnJlYWQgPSByZWFkOwogIH0KCiAgaWYoY29tcG9zZWQpIHsKICAgIC8vIHBhcnNlIGNoaWxkIGFzbjEgb2JqZWN0cyBmcm9tIHRoZSB2YWx1ZQogICAgdmFsdWUgPSBbXTsKICAgIGlmKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIC8vIGFzbjEgb2JqZWN0IG9mIGluZGVmaW5pdGUgbGVuZ3RoLCByZWFkIHVudGlsIGVuZCB0YWcKICAgICAgZm9yKDs7KSB7CiAgICAgICAgaWYoYnl0ZXMuYnl0ZXMoMikgPT09IFN0cmluZy5mcm9tQ2hhckNvZGUoMCwgMCkpIHsKICAgICAgICAgIGJ5dGVzLmdldEJ5dGVzKDIpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHZhbHVlLnB1c2goYXNuMS5mcm9tRGVyKGJ5dGVzLCBzdHJpY3QpKTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgLy8gcGFyc2luZyBhc24xIG9iamVjdCBvZiBkZWZpbml0ZSBsZW5ndGgKICAgICAgdmFyIHN0YXJ0ID0gYnl0ZXMubGVuZ3RoKCk7CiAgICAgIHdoaWxlKGxlbmd0aCA+IDApIHsKICAgICAgICB2YWx1ZS5wdXNoKGFzbjEuZnJvbURlcihieXRlcywgc3RyaWN0KSk7CiAgICAgICAgbGVuZ3RoIC09IHN0YXJ0IC0gYnl0ZXMubGVuZ3RoKCk7CiAgICAgICAgc3RhcnQgPSBieXRlcy5sZW5ndGgoKTsKICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICAvLyBhc24xIG5vdCBjb21wb3NlZCwgZ2V0IHJhdyB2YWx1ZQogICAgLy8gVE9ETzogZG8gREVSIHRvIE9JRCBjb252ZXJzaW9uIGFuZCB2aWNlLXZlcnNhIGluIC50b0Rlcj8KCiAgICBpZihsZW5ndGggPT09IHVuZGVmaW5lZCkgewogICAgICBpZihzdHJpY3QpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vbi1jb25zdHJ1Y3RlZCBBU04uMSBvYmplY3Qgb2YgaW5kZWZpbml0ZSBsZW5ndGguJyk7CiAgICAgIH0KICAgICAgLy8gYmUgbGVuaWVudCBhbmQgdXNlIHJlbWFpbmluZyBieXRlcwogICAgICBsZW5ndGggPSBieXRlcy5sZW5ndGgoKTsKICAgIH0KCiAgICBpZih0eXBlID09PSBhc24xLlR5cGUuQk1QU1RSSU5HKSB7CiAgICAgIHZhbHVlID0gJyc7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMikgewogICAgICAgIHZhbHVlICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXMuZ2V0SW50MTYoKSk7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHZhbHVlID0gYnl0ZXMuZ2V0Qnl0ZXMobGVuZ3RoKTsKICAgIH0KICB9CgogIC8vIGNyZWF0ZSBhbmQgcmV0dXJuIGFzbjEgb2JqZWN0CiAgcmV0dXJuIGFzbjEuY3JlYXRlKHRhZ0NsYXNzLCB0eXBlLCBjb25zdHJ1Y3RlZCwgdmFsdWUpOwp9OwoKLyoqCiAqIENvbnZlcnRzIHRoZSBnaXZlbiBhc24xIG9iamVjdCB0byBhIGJ1ZmZlciBvZiBieXRlcyBpbiBERVIgZm9ybWF0LgogKgogKiBAcGFyYW0gYXNuMSB0aGUgYXNuMSBvYmplY3QgdG8gY29udmVydCB0byBieXRlcy4KICoKICogQHJldHVybiB0aGUgYnVmZmVyIG9mIGJ5dGVzLgogKi8KYXNuMS50b0RlciA9IGZ1bmN0aW9uKG9iaikgewogIHZhciBieXRlcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIGJ1aWxkIHRoZSBmaXJzdCBieXRlCiAgdmFyIGIxID0gb2JqLnRhZ0NsYXNzIHwgb2JqLnR5cGU7CgogIC8vIGZvciBzdG9yaW5nIHRoZSBBU04uMSB2YWx1ZQogIHZhciB2YWx1ZSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIGlmIGNvbXBvc2VkLCB1c2UgZWFjaCBjaGlsZCBhc24xIG9iamVjdCdzIERFUiBieXRlcyBhcyB2YWx1ZQogIGlmKG9iai5jb21wb3NlZCkgewogICAgLy8gdHVybiBvbiA2dGggYml0ICgweDIwID0gMzIpIHRvIGluZGljYXRlIGFzbjEgaXMgY29uc3RydWN0ZWQKICAgIC8vIGZyb20gb3RoZXIgYXNuMSBvYmplY3RzCiAgICBpZihvYmouY29uc3RydWN0ZWQpIHsKICAgICAgYjEgfD0gMHgyMDsKICAgIH0gZWxzZSB7CiAgICAgIC8vIHR5cGUgaXMgYSBiaXQgc3RyaW5nLCBhZGQgdW51c2VkIGJpdHMgb2YgMHgwMAogICAgICB2YWx1ZS5wdXRCeXRlKDB4MDApOwogICAgfQoKICAgIC8vIGFkZCBhbGwgb2YgdGhlIGNoaWxkIERFUiBieXRlcyB0b2dldGhlcgogICAgZm9yKHZhciBpID0gMDsgaSA8IG9iai52YWx1ZS5sZW5ndGg7ICsraSkgewogICAgICBpZihvYmoudmFsdWVbaV0gIT09IHVuZGVmaW5lZCkgewogICAgICAgIHZhbHVlLnB1dEJ1ZmZlcihhc24xLnRvRGVyKG9iai52YWx1ZVtpXSkpOwogICAgICB9CiAgICB9CiAgfSBlbHNlIHsKICAgIC8vIHVzZSBhc24xLnZhbHVlIGRpcmVjdGx5CiAgICBpZihvYmoudHlwZSA9PT0gYXNuMS5UeXBlLkJNUFNUUklORykgewogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgb2JqLnZhbHVlLmxlbmd0aDsgKytpKSB7CiAgICAgICAgdmFsdWUucHV0SW50MTYob2JqLnZhbHVlLmNoYXJDb2RlQXQoaSkpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICB2YWx1ZS5wdXRCeXRlcyhvYmoudmFsdWUpOwogICAgfQogIH0KCiAgLy8gYWRkIHRhZyBieXRlCiAgYnl0ZXMucHV0Qnl0ZShiMSk7CgogIC8vIHVzZSAic2hvcnQgZm9ybSIgZW5jb2RpbmcKICBpZih2YWx1ZS5sZW5ndGgoKSA8PSAxMjcpIHsKICAgIC8vIG9uZSBieXRlIGRlc2NyaWJlcyB0aGUgbGVuZ3RoCiAgICAvLyBiaXQgOCA9IDAgYW5kIGJpdHMgNy0xID0gbGVuZ3RoCiAgICBieXRlcy5wdXRCeXRlKHZhbHVlLmxlbmd0aCgpICYgMHg3Rik7CiAgfSBlbHNlIHsKICAgIC8vIHVzZSAibG9uZyBmb3JtIiBlbmNvZGluZwogICAgLy8gMiB0byAxMjcgYnl0ZXMgZGVzY3JpYmUgdGhlIGxlbmd0aAogICAgLy8gZmlyc3QgYnl0ZTogYml0IDggPSAxIGFuZCBiaXRzIDctMSA9ICMgb2YgYWRkaXRpb25hbCBieXRlcwogICAgLy8gb3RoZXIgYnl0ZXM6IGxlbmd0aCBpbiBiYXNlIDI1NiwgYmlnLWVuZGlhbgogICAgdmFyIGxlbiA9IHZhbHVlLmxlbmd0aCgpOwogICAgdmFyIGxlbkJ5dGVzID0gJyc7CiAgICBkbyB7CiAgICAgIGxlbkJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUobGVuICYgMHhGRik7CiAgICAgIGxlbiA9IGxlbiA+Pj4gODsKICAgIH0gd2hpbGUobGVuID4gMCk7CgogICAgLy8gc2V0IGZpcnN0IGJ5dGUgdG8gIyBieXRlcyB1c2VkIHRvIHN0b3JlIHRoZSBsZW5ndGggYW5kIHR1cm4gb24KICAgIC8vIGJpdCA4IHRvIGluZGljYXRlIGxvbmctZm9ybSBsZW5ndGggaXMgdXNlZAogICAgYnl0ZXMucHV0Qnl0ZShsZW5CeXRlcy5sZW5ndGggfCAweDgwKTsKCiAgICAvLyBjb25jYXRlbmF0ZSBsZW5ndGggYnl0ZXMgaW4gcmV2ZXJzZSBzaW5jZSB0aGV5IHdlcmUgZ2VuZXJhdGVkCiAgICAvLyBsaXR0bGUgZW5kaWFuIGFuZCB3ZSBuZWVkIGJpZyBlbmRpYW4KICAgIGZvcih2YXIgaSA9IGxlbkJ5dGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7CiAgICAgIGJ5dGVzLnB1dEJ5dGUobGVuQnl0ZXMuY2hhckNvZGVBdChpKSk7CiAgICB9CiAgfQoKICAvLyBjb25jYXRlbmF0ZSB2YWx1ZSBieXRlcwogIGJ5dGVzLnB1dEJ1ZmZlcih2YWx1ZSk7CiAgcmV0dXJuIGJ5dGVzOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIE9JRCBkb3Qtc2VwYXJhdGVkIHN0cmluZyB0byBhIGJ5dGUgYnVmZmVyLiBUaGUgYnl0ZSBidWZmZXIKICogY29udGFpbnMgb25seSB0aGUgREVSLWVuY29kZWQgdmFsdWUsIG5vdCBhbnkgdGFnIG9yIGxlbmd0aCBieXRlcy4KICoKICogQHBhcmFtIG9pZCB0aGUgT0lEIGRvdC1zZXBhcmF0ZWQgc3RyaW5nLgogKgogKiBAcmV0dXJuIHRoZSBieXRlIGJ1ZmZlci4KICovCmFzbjEub2lkVG9EZXIgPSBmdW5jdGlvbihvaWQpIHsKICAvLyBzcGxpdCBPSUQgaW50byBpbmRpdmlkdWFsIHZhbHVlcwogIHZhciB2YWx1ZXMgPSBvaWQuc3BsaXQoJy4nKTsKICB2YXIgYnl0ZXMgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwoKICAvLyBmaXJzdCBieXRlIGlzIDQwICogdmFsdWUxICsgdmFsdWUyCiAgYnl0ZXMucHV0Qnl0ZSg0MCAqIHBhcnNlSW50KHZhbHVlc1swXSwgMTApICsgcGFyc2VJbnQodmFsdWVzWzFdLCAxMCkpOwogIC8vIG90aGVyIGJ5dGVzIGFyZSBlYWNoIHZhbHVlIGluIGJhc2UgMTI4IHdpdGggOHRoIGJpdCBzZXQgZXhjZXB0IGZvcgogIC8vIHRoZSBsYXN0IGJ5dGUgZm9yIGVhY2ggdmFsdWUKICB2YXIgbGFzdCwgdmFsdWVCeXRlcywgdmFsdWUsIGI7CiAgZm9yKHZhciBpID0gMjsgaSA8IHZhbHVlcy5sZW5ndGg7ICsraSkgewogICAgLy8gcHJvZHVjZSB2YWx1ZSBieXRlcyBpbiByZXZlcnNlIGJlY2F1c2Ugd2UgZG9uJ3Qga25vdyBob3cgbWFueQogICAgLy8gYnl0ZXMgaXQgd2lsbCB0YWtlIHRvIHN0b3JlIHRoZSB2YWx1ZQogICAgbGFzdCA9IHRydWU7CiAgICB2YWx1ZUJ5dGVzID0gW107CiAgICB2YWx1ZSA9IHBhcnNlSW50KHZhbHVlc1tpXSwgMTApOwogICAgZG8gewogICAgICBiID0gdmFsdWUgJiAweDdGOwogICAgICB2YWx1ZSA9IHZhbHVlID4+PiA3OwogICAgICAvLyBpZiB2YWx1ZSBpcyBub3QgbGFzdCwgdGhlbiB0dXJuIG9uIDh0aCBiaXQKICAgICAgaWYoIWxhc3QpIHsKICAgICAgICBiIHw9IDB4ODA7CiAgICAgIH0KICAgICAgdmFsdWVCeXRlcy5wdXNoKGIpOwogICAgICBsYXN0ID0gZmFsc2U7CiAgICB9IHdoaWxlKHZhbHVlID4gMCk7CgogICAgLy8gYWRkIHZhbHVlIGJ5dGVzIGluIHJldmVyc2UgKG5lZWRzIHRvIGJlIGluIGJpZyBlbmRpYW4pCiAgICBmb3IodmFyIG4gPSB2YWx1ZUJ5dGVzLmxlbmd0aCAtIDE7IG4gPj0gMDsgLS1uKSB7CiAgICAgIGJ5dGVzLnB1dEJ5dGUodmFsdWVCeXRlc1tuXSk7CiAgICB9CiAgfQoKICByZXR1cm4gYnl0ZXM7Cn07CgovKioKICogQ29udmVydHMgYSBERVItZW5jb2RlZCBieXRlIGJ1ZmZlciB0byBhbiBPSUQgZG90LXNlcGFyYXRlZCBzdHJpbmcuIFRoZQogKiBieXRlIGJ1ZmZlciBzaG91bGQgY29udGFpbiBvbmx5IHRoZSBERVItZW5jb2RlZCB2YWx1ZSwgbm90IGFueSB0YWcgb3IKICogbGVuZ3RoIGJ5dGVzLgogKgogKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYnVmZmVyLgogKgogKiBAcmV0dXJuIHRoZSBPSUQgZG90LXNlcGFyYXRlZCBzdHJpbmcuCiAqLwphc24xLmRlclRvT2lkID0gZnVuY3Rpb24oYnl0ZXMpIHsKICB2YXIgb2lkOwoKICAvLyB3cmFwIGluIGJ1ZmZlciBpZiBuZWVkZWQKICBpZih0eXBlb2YgYnl0ZXMgPT09ICdzdHJpbmcnKSB7CiAgICBieXRlcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGJ5dGVzKTsKICB9CgogIC8vIGZpcnN0IGJ5dGUgaXMgNDAgKiB2YWx1ZTEgKyB2YWx1ZTIKICB2YXIgYiA9IGJ5dGVzLmdldEJ5dGUoKTsKICBvaWQgPSBNYXRoLmZsb29yKGIgLyA0MCkgKyAnLicgKyAoYiAlIDQwKTsKCiAgLy8gb3RoZXIgYnl0ZXMgYXJlIGVhY2ggdmFsdWUgaW4gYmFzZSAxMjggd2l0aCA4dGggYml0IHNldCBleGNlcHQgZm9yCiAgLy8gdGhlIGxhc3QgYnl0ZSBmb3IgZWFjaCB2YWx1ZQogIHZhciB2YWx1ZSA9IDA7CiAgd2hpbGUoYnl0ZXMubGVuZ3RoKCkgPiAwKSB7CiAgICBiID0gYnl0ZXMuZ2V0Qnl0ZSgpOwogICAgdmFsdWUgPSB2YWx1ZSA8PCA3OwogICAgLy8gbm90IHRoZSBsYXN0IGJ5dGUgZm9yIHRoZSB2YWx1ZQogICAgaWYoYiAmIDB4ODApIHsKICAgICAgdmFsdWUgKz0gYiAmIDB4N0Y7CiAgICB9IGVsc2UgewogICAgICAvLyBsYXN0IGJ5dGUKICAgICAgb2lkICs9ICcuJyArICh2YWx1ZSArIGIpOwogICAgICB2YWx1ZSA9IDA7CiAgICB9CiAgfQoKICByZXR1cm4gb2lkOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgVVRDVGltZSB2YWx1ZSB0byBhIGRhdGUuCiAqCiAqIE5vdGU6IEdlbmVyYWxpemVkVGltZSBoYXMgNCBkaWdpdHMgZm9yIHRoZSB5ZWFyIGFuZCBpcyB1c2VkIGZvciBYLjUwOQogKiBkYXRlcyBwYXNzZWQgMjA0OS4gUGFyc2luZyB0aGF0IHN0cnVjdHVyZSBoYXNuJ3QgYmVlbiBpbXBsZW1lbnRlZCB5ZXQuCiAqCiAqIEBwYXJhbSB1dGMgdGhlIFVUQ1RpbWUgdmFsdWUgdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgZGF0ZS4KICovCmFzbjEudXRjVGltZVRvRGF0ZSA9IGZ1bmN0aW9uKHV0YykgewogIC8qIFRoZSBmb2xsb3dpbmcgZm9ybWF0cyBjYW4gYmUgdXNlZDoKCiAgICBZWU1NRERoaG1tWgogICAgWVlNTUREaGhtbStoaCdtbScKICAgIFlZTU1ERGhobW0taGgnbW0nCiAgICBZWU1NRERoaG1tc3NaCiAgICBZWU1NRERoaG1tc3MraGgnbW0nCiAgICBZWU1NRERoaG1tc3MtaGgnbW0nCgogICAgV2hlcmU6CgogICAgWVkgaXMgdGhlIGxlYXN0IHNpZ25pZmljYW50IHR3byBkaWdpdHMgb2YgdGhlIHllYXIKICAgIE1NIGlzIHRoZSBtb250aCAoMDEgdG8gMTIpCiAgICBERCBpcyB0aGUgZGF5ICgwMSB0byAzMSkKICAgIGhoIGlzIHRoZSBob3VyICgwMCB0byAyMykKICAgIG1tIGFyZSB0aGUgbWludXRlcyAoMDAgdG8gNTkpCiAgICBzcyBhcmUgdGhlIHNlY29uZHMgKDAwIHRvIDU5KQogICAgWiBpbmRpY2F0ZXMgdGhhdCBsb2NhbCB0aW1lIGlzIEdNVCwgKyBpbmRpY2F0ZXMgdGhhdCBsb2NhbCB0aW1lIGlzCiAgICBsYXRlciB0aGFuIEdNVCwgYW5kIC0gaW5kaWNhdGVzIHRoYXQgbG9jYWwgdGltZSBpcyBlYXJsaWVyIHRoYW4gR01UCiAgICBoaCcgaXMgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSBvZmZzZXQgZnJvbSBHTVQgaW4gaG91cnMKICAgIG1tJyBpcyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIG9mZnNldCBmcm9tIEdNVCBpbiBtaW51dGVzICovCiAgdmFyIGRhdGUgPSBuZXcgRGF0ZSgpOwoKICAvLyBpZiBZWSA+PSA1MCB1c2UgMTl4eCwgaWYgWVkgPCA1MCB1c2UgMjB4eAogIHZhciB5ZWFyID0gcGFyc2VJbnQodXRjLnN1YnN0cigwLCAyKSwgMTApOwogIHllYXIgPSAoeWVhciA+PSA1MCkgPyAxOTAwICsgeWVhciA6IDIwMDAgKyB5ZWFyOwogIHZhciBNTSA9IHBhcnNlSW50KHV0Yy5zdWJzdHIoMiwgMiksIDEwKSAtIDE7IC8vIHVzZSAwLTExIGZvciBtb250aAogIHZhciBERCA9IHBhcnNlSW50KHV0Yy5zdWJzdHIoNCwgMiksIDEwKTsKICB2YXIgaGggPSBwYXJzZUludCh1dGMuc3Vic3RyKDYsIDIpLCAxMCk7CiAgdmFyIG1tID0gcGFyc2VJbnQodXRjLnN1YnN0cig4LCAyKSwgMTApOwogIHZhciBzcyA9IDA7CgogIC8vIG5vdCBqdXN0IFlZTU1ERGhobW1aCiAgaWYodXRjLmxlbmd0aCA+IDExKSB7CiAgICAvLyBnZXQgY2hhcmFjdGVyIGFmdGVyIG1pbnV0ZXMKICAgIHZhciBjID0gdXRjLmNoYXJBdCgxMCk7CiAgICB2YXIgZW5kID0gMTA7CgogICAgLy8gc2VlIGlmIHNlY29uZHMgYXJlIHByZXNlbnQKICAgIGlmKGMgIT09ICcrJyAmJiBjICE9PSAnLScpIHsKICAgICAgLy8gZ2V0IHNlY29uZHMKICAgICAgc3MgPSBwYXJzZUludCh1dGMuc3Vic3RyKDEwLCAyKSwgMTApOwogICAgICBlbmQgKz0gMjsKICAgIH0KICB9CgogIC8vIHVwZGF0ZSBkYXRlCiAgZGF0ZS5zZXRVVENGdWxsWWVhcih5ZWFyLCBNTSwgREQpOwogIGRhdGUuc2V0VVRDSG91cnMoaGgsIG1tLCBzcywgMCk7CgogIGlmKGVuZCkgewogICAgLy8gZ2V0ICsvLSBhZnRlciBlbmQgb2YgdGltZQogICAgYyA9IHV0Yy5jaGFyQXQoZW5kKTsKICAgIGlmKGMgPT09ICcrJyB8fCBjID09PSAnLScpIHsKICAgICAgLy8gZ2V0IGhvdXJzK21pbnV0ZXMgb2Zmc2V0CiAgICAgIHZhciBoaG9mZnNldCA9IHBhcnNlSW50KHV0Yy5zdWJzdHIoZW5kICsgMSwgMiksIDEwKTsKICAgICAgdmFyIG1tb2Zmc2V0ID0gcGFyc2VJbnQodXRjLnN1YnN0cihlbmQgKyA0LCAyKSwgMTApOwoKICAgICAgLy8gY2FsY3VsYXRlIG9mZnNldCBpbiBtaWxsaXNlY29uZHMKICAgICAgdmFyIG9mZnNldCA9IGhob2Zmc2V0ICogNjAgKyBtbW9mZnNldDsKICAgICAgb2Zmc2V0ICo9IDYwMDAwOwoKICAgICAgLy8gYXBwbHkgb2Zmc2V0CiAgICAgIGlmKGMgPT09ICcrJykgewogICAgICAgIGRhdGUuc2V0VGltZSgrZGF0ZSAtIG9mZnNldCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgb2Zmc2V0KTsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIGRhdGU7Cn07CgovKioKICogQ29udmVydHMgYSBHZW5lcmFsaXplZFRpbWUgdmFsdWUgdG8gYSBkYXRlLgogKgogKiBAcGFyYW0gZ2VudGltZSB0aGUgR2VuZXJhbGl6ZWRUaW1lIHZhbHVlIHRvIGNvbnZlcnQuCiAqCiAqIEByZXR1cm4gdGhlIGRhdGUuCiAqLwphc24xLmdlbmVyYWxpemVkVGltZVRvRGF0ZSA9IGZ1bmN0aW9uKGdlbnRpbWUpIHsKICAvKiBUaGUgZm9sbG93aW5nIGZvcm1hdHMgY2FuIGJlIHVzZWQ6CgogICAgWVlZWU1NRERISE1NU1MKICAgIFlZWVlNTURESEhNTVNTLmZmZgogICAgWVlZWU1NRERISE1NU1NaCiAgICBZWVlZTU1EREhITU1TUy5mZmZaCiAgICBZWVlZTU1EREhITU1TUytoaCdtbScKICAgIFlZWVlNTURESEhNTVNTLmZmZitoaCdtbScKICAgIFlZWVlNTURESEhNTVNTLWhoJ21tJwogICAgWVlZWU1NRERISE1NU1MuZmZmLWhoJ21tJwoKICAgIFdoZXJlOgoKICAgIFlZWVkgaXMgdGhlIHllYXIKICAgIE1NIGlzIHRoZSBtb250aCAoMDEgdG8gMTIpCiAgICBERCBpcyB0aGUgZGF5ICgwMSB0byAzMSkKICAgIGhoIGlzIHRoZSBob3VyICgwMCB0byAyMykKICAgIG1tIGFyZSB0aGUgbWludXRlcyAoMDAgdG8gNTkpCiAgICBzcyBhcmUgdGhlIHNlY29uZHMgKDAwIHRvIDU5KQogICAgLmZmZiBpcyB0aGUgc2Vjb25kIGZyYWN0aW9uLCBhY2N1cmF0ZSB0byB0aHJlZSBkZWNpbWFsIHBsYWNlcwogICAgWiBpbmRpY2F0ZXMgdGhhdCBsb2NhbCB0aW1lIGlzIEdNVCwgKyBpbmRpY2F0ZXMgdGhhdCBsb2NhbCB0aW1lIGlzCiAgICBsYXRlciB0aGFuIEdNVCwgYW5kIC0gaW5kaWNhdGVzIHRoYXQgbG9jYWwgdGltZSBpcyBlYXJsaWVyIHRoYW4gR01UCiAgICBoaCcgaXMgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSBvZmZzZXQgZnJvbSBHTVQgaW4gaG91cnMKICAgIG1tJyBpcyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIG9mZnNldCBmcm9tIEdNVCBpbiBtaW51dGVzICovCiAgdmFyIGRhdGUgPSBuZXcgRGF0ZSgpOwoKICB2YXIgWVlZWSA9IHBhcnNlSW50KGdlbnRpbWUuc3Vic3RyKDAsIDQpLCAxMCk7CiAgdmFyIE1NID0gcGFyc2VJbnQoZ2VudGltZS5zdWJzdHIoNCwgMiksIDEwKSAtIDE7IC8vIHVzZSAwLTExIGZvciBtb250aAogIHZhciBERCA9IHBhcnNlSW50KGdlbnRpbWUuc3Vic3RyKDYsIDIpLCAxMCk7CiAgdmFyIGhoID0gcGFyc2VJbnQoZ2VudGltZS5zdWJzdHIoOCwgMiksIDEwKTsKICB2YXIgbW0gPSBwYXJzZUludChnZW50aW1lLnN1YnN0cigxMCwgMiksIDEwKTsKICB2YXIgc3MgPSBwYXJzZUludChnZW50aW1lLnN1YnN0cigxMiwgMiksIDEwKTsKICB2YXIgZmZmID0gMDsKICB2YXIgb2Zmc2V0ID0gMDsKICB2YXIgaXNVVEMgPSBmYWxzZTsKCiAgaWYoZ2VudGltZS5jaGFyQXQoZ2VudGltZS5sZW5ndGggLSAxKSA9PT0gJ1onKSB7CiAgICBpc1VUQyA9IHRydWU7CiAgfQoKICB2YXIgZW5kID0gZ2VudGltZS5sZW5ndGggLSA1LCBjID0gZ2VudGltZS5jaGFyQXQoZW5kKTsKICBpZihjID09PSAnKycgfHwgYyA9PT0gJy0nKSB7CiAgICAvLyBnZXQgaG91cnMrbWludXRlcyBvZmZzZXQKICAgIHZhciBoaG9mZnNldCA9IHBhcnNlSW50KGdlbnRpbWUuc3Vic3RyKGVuZCArIDEsIDIpLCAxMCk7CiAgICB2YXIgbW1vZmZzZXQgPSBwYXJzZUludChnZW50aW1lLnN1YnN0cihlbmQgKyA0LCAyKSwgMTApOwoKICAgIC8vIGNhbGN1bGF0ZSBvZmZzZXQgaW4gbWlsbGlzZWNvbmRzCiAgICBvZmZzZXQgPSBoaG9mZnNldCAqIDYwICsgbW1vZmZzZXQ7CiAgICBvZmZzZXQgKj0gNjAwMDA7CgogICAgLy8gYXBwbHkgb2Zmc2V0CiAgICBpZihjID09PSAnKycpIHsKICAgICAgb2Zmc2V0ICo9IC0xOwogICAgfQoKICAgIGlzVVRDID0gdHJ1ZTsKICB9CgogIC8vIGNoZWNrIGZvciBzZWNvbmQgZnJhY3Rpb24KICBpZihnZW50aW1lLmNoYXJBdCgxNCkgPT09ICcuJykgewogICAgZmZmID0gcGFyc2VGbG9hdChnZW50aW1lLnN1YnN0cigxNCksIDEwKSAqIDEwMDA7CiAgfQoKICBpZihpc1VUQykgewogICAgZGF0ZS5zZXRVVENGdWxsWWVhcihZWVlZLCBNTSwgREQpOwogICAgZGF0ZS5zZXRVVENIb3VycyhoaCwgbW0sIHNzLCBmZmYpOwoKICAgIC8vIGFwcGx5IG9mZnNldAogICAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgb2Zmc2V0KTsKICB9IGVsc2UgewogICAgZGF0ZS5zZXRGdWxsWWVhcihZWVlZLCBNTSwgREQpOwogICAgZGF0ZS5zZXRIb3VycyhoaCwgbW0sIHNzLCBmZmYpOwogIH0KCiAgcmV0dXJuIGRhdGU7Cn07CgovKioKICogQ29udmVydHMgYSBkYXRlIHRvIGEgVVRDVGltZSB2YWx1ZS4KICoKICogTm90ZTogR2VuZXJhbGl6ZWRUaW1lIGhhcyA0IGRpZ2l0cyBmb3IgdGhlIHllYXIgYW5kIGlzIHVzZWQgZm9yIFguNTA5CiAqIGRhdGVzIHBhc3NlZCAyMDQ5LiBDb252ZXJ0aW5nIHRvIGEgR2VuZXJhbGl6ZWRUaW1lIGhhc24ndCBiZWVuCiAqIGltcGxlbWVudGVkIHlldC4KICoKICogQHBhcmFtIGRhdGUgdGhlIGRhdGUgdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgVVRDVGltZSB2YWx1ZS4KICovCmFzbjEuZGF0ZVRvVXRjVGltZSA9IGZ1bmN0aW9uKGRhdGUpIHsKICAvLyBUT0RPOiB2YWxpZGF0ZTsgY3VycmVudGx5IGFzc3VtZXMgcHJvcGVyIGZvcm1hdAogIGlmKHR5cGVvZiBkYXRlID09PSAnc3RyaW5nJykgewogICAgcmV0dXJuIGRhdGU7CiAgfQoKICB2YXIgcnZhbCA9ICcnOwoKICAvLyBjcmVhdGUgZm9ybWF0IFlZTU1ERGhobW1zc1oKICB2YXIgZm9ybWF0ID0gW107CiAgZm9ybWF0LnB1c2goKCcnICsgZGF0ZS5nZXRVVENGdWxsWWVhcigpKS5zdWJzdHIoMikpOwogIGZvcm1hdC5wdXNoKCcnICsgKGRhdGUuZ2V0VVRDTW9udGgoKSArIDEpKTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDRGF0ZSgpKTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDSG91cnMoKSk7CiAgZm9ybWF0LnB1c2goJycgKyBkYXRlLmdldFVUQ01pbnV0ZXMoKSk7CiAgZm9ybWF0LnB1c2goJycgKyBkYXRlLmdldFVUQ1NlY29uZHMoKSk7CgogIC8vIGVuc3VyZSAyIGRpZ2l0cyBhcmUgdXNlZCBmb3IgZWFjaCBmb3JtYXQgZW50cnkKICBmb3IodmFyIGkgPSAwOyBpIDwgZm9ybWF0Lmxlbmd0aDsgKytpKSB7CiAgICBpZihmb3JtYXRbaV0ubGVuZ3RoIDwgMikgewogICAgICBydmFsICs9ICcwJzsKICAgIH0KICAgIHJ2YWwgKz0gZm9ybWF0W2ldOwogIH0KICBydmFsICs9ICdaJzsKCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ29udmVydHMgYSBkYXRlIHRvIGEgR2VuZXJhbGl6ZWRUaW1lIHZhbHVlLgogKgogKiBAcGFyYW0gZGF0ZSB0aGUgZGF0ZSB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBHZW5lcmFsaXplZFRpbWUgdmFsdWUgYXMgYSBzdHJpbmcuCiAqLwphc24xLmRhdGVUb0dlbmVyYWxpemVkVGltZSA9IGZ1bmN0aW9uKGRhdGUpIHsKICAvLyBUT0RPOiB2YWxpZGF0ZTsgY3VycmVudGx5IGFzc3VtZXMgcHJvcGVyIGZvcm1hdAogIGlmKHR5cGVvZiBkYXRlID09PSAnc3RyaW5nJykgewogICAgcmV0dXJuIGRhdGU7CiAgfQoKICB2YXIgcnZhbCA9ICcnOwoKICAvLyBjcmVhdGUgZm9ybWF0IFlZWVlNTURESEhNTVNTWgogIHZhciBmb3JtYXQgPSBbXTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDRnVsbFllYXIoKSk7CiAgZm9ybWF0LnB1c2goJycgKyAoZGF0ZS5nZXRVVENNb250aCgpICsgMSkpOwogIGZvcm1hdC5wdXNoKCcnICsgZGF0ZS5nZXRVVENEYXRlKCkpOwogIGZvcm1hdC5wdXNoKCcnICsgZGF0ZS5nZXRVVENIb3VycygpKTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDTWludXRlcygpKTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDU2Vjb25kcygpKTsKCiAgLy8gZW5zdXJlIDIgZGlnaXRzIGFyZSB1c2VkIGZvciBlYWNoIGZvcm1hdCBlbnRyeQogIGZvcih2YXIgaSA9IDA7IGkgPCBmb3JtYXQubGVuZ3RoOyArK2kpIHsKICAgIGlmKGZvcm1hdFtpXS5sZW5ndGggPCAyKSB7CiAgICAgIHJ2YWwgKz0gJzAnOwogICAgfQogICAgcnZhbCArPSBmb3JtYXRbaV07CiAgfQogIHJ2YWwgKz0gJ1onOwoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIGphdmFzY3JpcHQgaW50ZWdlciB0byBhIERFUi1lbmNvZGVkIGJ5dGUgYnVmZmVyIHRvIGJlIHVzZWQKICogYXMgdGhlIHZhbHVlIGZvciBhbiBJTlRFR0VSIHR5cGUuCiAqCiAqIEBwYXJhbSB4IHRoZSBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoZSBieXRlIGJ1ZmZlci4KICovCmFzbjEuaW50ZWdlclRvRGVyID0gZnVuY3Rpb24oeCkgewogIHZhciBydmFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBpZih4ID49IC0weDgwICYmIHggPCAweDgwKSB7CiAgICByZXR1cm4gcnZhbC5wdXRTaWduZWRJbnQoeCwgOCk7CiAgfQogIGlmKHggPj0gLTB4ODAwMCAmJiB4IDwgMHg4MDAwKSB7CiAgICByZXR1cm4gcnZhbC5wdXRTaWduZWRJbnQoeCwgMTYpOwogIH0KICBpZih4ID49IC0weDgwMDAwMCAmJiB4IDwgMHg4MDAwMDApIHsKICAgIHJldHVybiBydmFsLnB1dFNpZ25lZEludCh4LCAyNCk7CiAgfQogIGlmKHggPj0gLTB4ODAwMDAwMDAgJiYgeCA8IDB4ODAwMDAwMDApIHsKICAgIHJldHVybiBydmFsLnB1dFNpZ25lZEludCh4LCAzMik7CiAgfQogIHZhciBlcnJvciA9IG5ldyBFcnJvcignSW50ZWdlciB0b28gbGFyZ2U7IG1heCBpcyAzMi1iaXRzLicpOwogIGVycm9yLmludGVnZXIgPSB4OwogIHRocm93IGVycm9yOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgREVSLWVuY29kZWQgYnl0ZSBidWZmZXIgdG8gYSBqYXZhc2NyaXB0IGludGVnZXIuIFRoaXMgaXMKICogdHlwaWNhbGx5IHVzZWQgdG8gZGVjb2RlIHRoZSB2YWx1ZSBvZiBhbiBJTlRFR0VSIHR5cGUuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZSBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIGludGVnZXIuCiAqLwphc24xLmRlclRvSW50ZWdlciA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgLy8gd3JhcCBpbiBidWZmZXIgaWYgbmVlZGVkCiAgaWYodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykgewogICAgYnl0ZXMgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihieXRlcyk7CiAgfQoKICB2YXIgbiA9IGJ5dGVzLmxlbmd0aCgpICogODsKICBpZihuID4gMzIpIHsKICAgIHRocm93IG5ldyBFcnJvcignSW50ZWdlciB0b28gbGFyZ2U7IG1heCBpcyAzMi1iaXRzLicpOwogIH0KICByZXR1cm4gYnl0ZXMuZ2V0U2lnbmVkSW50KG4pOwp9OwoKLyoqCiAqIFZhbGlkYXRlcyB0aGUgdGhhdCBnaXZlbiBBU04uMSBvYmplY3QgaXMgYXQgbGVhc3QgYSBzdXBlciBzZXQgb2YgdGhlCiAqIGdpdmVuIEFTTi4xIHN0cnVjdHVyZS4gT25seSB0YWcgY2xhc3NlcyBhbmQgdHlwZXMgYXJlIGNoZWNrZWQuIEFuCiAqIG9wdGlvbmFsIG1hcCBtYXkgYWxzbyBiZSBwcm92aWRlZCB0byBjYXB0dXJlIEFTTi4xIHZhbHVlcyB3aGlsZSB0aGUKICogc3RydWN0dXJlIGlzIGNoZWNrZWQuCiAqCiAqIFRvIGNhcHR1cmUgYW4gQVNOLjEgdmFsdWUsIHNldCBhbiBvYmplY3QgaW4gdGhlIHZhbGlkYXRvcidzICdjYXB0dXJlJwogKiBwYXJhbWV0ZXIgdG8gdGhlIGtleSB0byB1c2UgaW4gdGhlIGNhcHR1cmUgbWFwLiBUbyBjYXB0dXJlIHRoZSBmdWxsCiAqIEFTTi4xIG9iamVjdCwgc3BlY2lmeSAnY2FwdHVyZUFzbjEnLgogKgogKiBPYmplY3RzIGluIHRoZSB2YWxpZGF0b3IgbWF5IHNldCBhIGZpZWxkICdvcHRpb25hbCcgdG8gdHJ1ZSB0byBpbmRpY2F0ZQogKiB0aGF0IGl0IGlzbid0IG5lY2Vzc2FyeSB0byBwYXNzIHZhbGlkYXRpb24uCiAqCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIG9iamVjdCB0byB2YWxpZGF0ZS4KICogQHBhcmFtIHYgdGhlIEFTTi4xIHN0cnVjdHVyZSB2YWxpZGF0b3IuCiAqIEBwYXJhbSBjYXB0dXJlIGFuIG9wdGlvbmFsIG1hcCB0byBjYXB0dXJlIHZhbHVlcyBpbi4KICogQHBhcmFtIGVycm9ycyBhbiBvcHRpb25hbCBhcnJheSBmb3Igc3RvcmluZyB2YWxpZGF0aW9uIGVycm9ycy4KICoKICogQHJldHVybiB0cnVlIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGZhaWx1cmUuCiAqLwphc24xLnZhbGlkYXRlID0gZnVuY3Rpb24ob2JqLCB2LCBjYXB0dXJlLCBlcnJvcnMpIHsKICB2YXIgcnZhbCA9IGZhbHNlOwoKICAvLyBlbnN1cmUgdGFnIGNsYXNzIGFuZCB0eXBlIGFyZSB0aGUgc2FtZSBpZiBzcGVjaWZpZWQKICBpZigob2JqLnRhZ0NsYXNzID09PSB2LnRhZ0NsYXNzIHx8IHR5cGVvZih2LnRhZ0NsYXNzKSA9PT0gJ3VuZGVmaW5lZCcpICYmCiAgICAob2JqLnR5cGUgPT09IHYudHlwZSB8fCB0eXBlb2Yodi50eXBlKSA9PT0gJ3VuZGVmaW5lZCcpKSB7CiAgICAvLyBlbnN1cmUgY29uc3RydWN0ZWQgZmxhZyBpcyB0aGUgc2FtZSBpZiBzcGVjaWZpZWQKICAgIGlmKG9iai5jb25zdHJ1Y3RlZCA9PT0gdi5jb25zdHJ1Y3RlZCB8fAogICAgICB0eXBlb2Yodi5jb25zdHJ1Y3RlZCkgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIHJ2YWwgPSB0cnVlOwoKICAgICAgLy8gaGFuZGxlIHN1YiB2YWx1ZXMKICAgICAgaWYodi52YWx1ZSAmJiBmb3JnZS51dGlsLmlzQXJyYXkodi52YWx1ZSkpIHsKICAgICAgICB2YXIgaiA9IDA7CiAgICAgICAgZm9yKHZhciBpID0gMDsgcnZhbCAmJiBpIDwgdi52YWx1ZS5sZW5ndGg7ICsraSkgewogICAgICAgICAgcnZhbCA9IHYudmFsdWVbaV0ub3B0aW9uYWwgfHwgZmFsc2U7CiAgICAgICAgICBpZihvYmoudmFsdWVbal0pIHsKICAgICAgICAgICAgcnZhbCA9IGFzbjEudmFsaWRhdGUob2JqLnZhbHVlW2pdLCB2LnZhbHVlW2ldLCBjYXB0dXJlLCBlcnJvcnMpOwogICAgICAgICAgICBpZihydmFsKSB7CiAgICAgICAgICAgICAgKytqOwogICAgICAgICAgICB9IGVsc2UgaWYodi52YWx1ZVtpXS5vcHRpb25hbCkgewogICAgICAgICAgICAgIHJ2YWwgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBpZighcnZhbCAmJiBlcnJvcnMpIHsKICAgICAgICAgICAgZXJyb3JzLnB1c2goCiAgICAgICAgICAgICAgJ1snICsgdi5uYW1lICsgJ10gJyArCiAgICAgICAgICAgICAgJ1RhZyBjbGFzcyAiJyArIHYudGFnQ2xhc3MgKyAnIiwgdHlwZSAiJyArCiAgICAgICAgICAgICAgdi50eXBlICsgJyIgZXhwZWN0ZWQgdmFsdWUgbGVuZ3RoICInICsKICAgICAgICAgICAgICB2LnZhbHVlLmxlbmd0aCArICciLCBnb3QgIicgKwogICAgICAgICAgICAgIG9iai52YWx1ZS5sZW5ndGggKyAnIicpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgaWYocnZhbCAmJiBjYXB0dXJlKSB7CiAgICAgICAgaWYodi5jYXB0dXJlKSB7CiAgICAgICAgICBjYXB0dXJlW3YuY2FwdHVyZV0gPSBvYmoudmFsdWU7CiAgICAgICAgfQogICAgICAgIGlmKHYuY2FwdHVyZUFzbjEpIHsKICAgICAgICAgIGNhcHR1cmVbdi5jYXB0dXJlQXNuMV0gPSBvYmo7CiAgICAgICAgfQogICAgICB9CiAgICB9IGVsc2UgaWYoZXJyb3JzKSB7CiAgICAgIGVycm9ycy5wdXNoKAogICAgICAgICdbJyArIHYubmFtZSArICddICcgKwogICAgICAgICdFeHBlY3RlZCBjb25zdHJ1Y3RlZCAiJyArIHYuY29uc3RydWN0ZWQgKyAnIiwgZ290ICInICsKICAgICAgICBvYmouY29uc3RydWN0ZWQgKyAnIicpOwogICAgfQogIH0gZWxzZSBpZihlcnJvcnMpIHsKICAgIGlmKG9iai50YWdDbGFzcyAhPT0gdi50YWdDbGFzcykgewogICAgICBlcnJvcnMucHVzaCgKICAgICAgICAnWycgKyB2Lm5hbWUgKyAnXSAnICsKICAgICAgICAnRXhwZWN0ZWQgdGFnIGNsYXNzICInICsgdi50YWdDbGFzcyArICciLCBnb3QgIicgKwogICAgICAgIG9iai50YWdDbGFzcyArICciJyk7CiAgICB9CiAgICBpZihvYmoudHlwZSAhPT0gdi50eXBlKSB7CiAgICAgIGVycm9ycy5wdXNoKAogICAgICAgICdbJyArIHYubmFtZSArICddICcgKwogICAgICAgICdFeHBlY3RlZCB0eXBlICInICsgdi50eXBlICsgJyIsIGdvdCAiJyArIG9iai50eXBlICsgJyInKTsKICAgIH0KICB9CiAgcmV0dXJuIHJ2YWw7Cn07CgovLyByZWdleCBmb3IgdGVzdGluZyBmb3Igbm9uLWxhdGluIGNoYXJhY3RlcnMKdmFyIF9ub25MYXRpblJlZ2V4ID0gL1teXFx1MDAwMC1cXHUwMGZmXS87CgovKioKICogUHJldHR5IHByaW50cyBhbiBBU04uMSBvYmplY3QgdG8gYSBzdHJpbmcuCiAqCiAqIEBwYXJhbSBvYmogdGhlIG9iamVjdCB0byB3cml0ZSBvdXQuCiAqIEBwYXJhbSBsZXZlbCB0aGUgbGV2ZWwgaW4gdGhlIHRyZWUuCiAqIEBwYXJhbSBpbmRlbnRhdGlvbiB0aGUgaW5kZW50YXRpb24gdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSBzdHJpbmcuCiAqLwphc24xLnByZXR0eVByaW50ID0gZnVuY3Rpb24ob2JqLCBsZXZlbCwgaW5kZW50YXRpb24pIHsKICB2YXIgcnZhbCA9ICcnOwoKICAvLyBzZXQgZGVmYXVsdCBsZXZlbCBhbmQgaW5kZW50YXRpb24KICBsZXZlbCA9IGxldmVsIHx8IDA7CiAgaW5kZW50YXRpb24gPSBpbmRlbnRhdGlvbiB8fCAyOwoKICAvLyBzdGFydCBuZXcgbGluZSBmb3IgZGVlcCBsZXZlbHMKICBpZihsZXZlbCA+IDApIHsKICAgIHJ2YWwgKz0gJ1xuJzsKICB9CgogIC8vIGNyZWF0ZSBpbmRlbnQKICB2YXIgaW5kZW50ID0gJyc7CiAgZm9yKHZhciBpID0gMDsgaSA8IGxldmVsICogaW5kZW50YXRpb247ICsraSkgewogICAgaW5kZW50ICs9ICcgJzsKICB9CgogIC8vIHByaW50IGNsYXNzOnR5cGUKICBydmFsICs9IGluZGVudCArICdUYWc6ICc7CiAgc3dpdGNoKG9iai50YWdDbGFzcykgewogIGNhc2UgYXNuMS5DbGFzcy5VTklWRVJTQUw6CiAgICBydmFsICs9ICdVbml2ZXJzYWw6JzsKICAgIGJyZWFrOwogIGNhc2UgYXNuMS5DbGFzcy5BUFBMSUNBVElPTjoKICAgIHJ2YWwgKz0gJ0FwcGxpY2F0aW9uOic7CiAgICBicmVhazsKICBjYXNlIGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQzoKICAgIHJ2YWwgKz0gJ0NvbnRleHQtU3BlY2lmaWM6JzsKICAgIGJyZWFrOwogIGNhc2UgYXNuMS5DbGFzcy5QUklWQVRFOgogICAgcnZhbCArPSAnUHJpdmF0ZTonOwogICAgYnJlYWs7CiAgfQoKICBpZihvYmoudGFnQ2xhc3MgPT09IGFzbjEuQ2xhc3MuVU5JVkVSU0FMKSB7CiAgICBydmFsICs9IG9iai50eXBlOwoKICAgIC8vIGtub3duIHR5cGVzCiAgICBzd2l0Y2gob2JqLnR5cGUpIHsKICAgIGNhc2UgYXNuMS5UeXBlLk5PTkU6CiAgICAgIHJ2YWwgKz0gJyAoTm9uZSknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkJPT0xFQU46CiAgICAgIHJ2YWwgKz0gJyAoQm9vbGVhbiknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkJJVFNUUklORzoKICAgICAgcnZhbCArPSAnIChCaXQgc3RyaW5nKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuSU5URUdFUjoKICAgICAgcnZhbCArPSAnIChJbnRlZ2VyKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuT0NURVRTVFJJTkc6CiAgICAgIHJ2YWwgKz0gJyAoT2N0ZXQgc3RyaW5nKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuTlVMTDoKICAgICAgcnZhbCArPSAnIChOdWxsKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuT0lEOgogICAgICBydmFsICs9ICcgKE9iamVjdCBJZGVudGlmaWVyKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuT0RFU0M6CiAgICAgIHJ2YWwgKz0gJyAoT2JqZWN0IERlc2NyaXB0b3IpJzsKICAgICAgYnJlYWs7CiAgICBjYXNlIGFzbjEuVHlwZS5FWFRFUk5BTDoKICAgICAgcnZhbCArPSAnIChFeHRlcm5hbCBvciBJbnN0YW5jZSBvZiknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlJFQUw6CiAgICAgIHJ2YWwgKz0gJyAoUmVhbCknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkVOVU1FUkFURUQ6CiAgICAgIHJ2YWwgKz0gJyAoRW51bWVyYXRlZCknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkVNQkVEREVEOgogICAgICBydmFsICs9ICcgKEVtYmVkZGVkIFBEViknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlVURjg6CiAgICAgIHJ2YWwgKz0gJyAoVVRGOCknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlJPSUQ6CiAgICAgIHJ2YWwgKz0gJyAoUmVsYXRpdmUgT2JqZWN0IElkZW50aWZpZXIpJzsKICAgICAgYnJlYWs7CiAgICBjYXNlIGFzbjEuVHlwZS5TRVFVRU5DRToKICAgICAgcnZhbCArPSAnIChTZXF1ZW5jZSknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlNFVDoKICAgICAgcnZhbCArPSAnIChTZXQpJzsKICAgICAgYnJlYWs7CiAgICBjYXNlIGFzbjEuVHlwZS5QUklOVEFCTEVTVFJJTkc6CiAgICAgIHJ2YWwgKz0gJyAoUHJpbnRhYmxlIFN0cmluZyknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLklBNVN0cmluZzoKICAgICAgcnZhbCArPSAnIChJQTVTdHJpbmcgKEFTQ0lJKSknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlVUQ1RJTUU6CiAgICAgIHJ2YWwgKz0gJyAoVVRDIHRpbWUpJzsKICAgICAgYnJlYWs7CiAgICBjYXNlIGFzbjEuVHlwZS5HRU5FUkFMSVpFRFRJTUU6CiAgICAgIHJ2YWwgKz0gJyAoR2VuZXJhbGl6ZWQgdGltZSknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkJNUFNUUklORzoKICAgICAgcnZhbCArPSAnIChCTVAgU3RyaW5nKSc7CiAgICAgIGJyZWFrOwogICAgfQogIH0gZWxzZSB7CiAgICBydmFsICs9IG9iai50eXBlOwogIH0KCiAgcnZhbCArPSAnXG4nOwogIHJ2YWwgKz0gaW5kZW50ICsgJ0NvbnN0cnVjdGVkOiAnICsgb2JqLmNvbnN0cnVjdGVkICsgJ1xuJzsKCiAgaWYob2JqLmNvbXBvc2VkKSB7CiAgICB2YXIgc3VidmFsdWVzID0gMDsKICAgIHZhciBzdWIgPSAnJzsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBvYmoudmFsdWUubGVuZ3RoOyArK2kpIHsKICAgICAgaWYob2JqLnZhbHVlW2ldICE9PSB1bmRlZmluZWQpIHsKICAgICAgICBzdWJ2YWx1ZXMgKz0gMTsKICAgICAgICBzdWIgKz0gYXNuMS5wcmV0dHlQcmludChvYmoudmFsdWVbaV0sIGxldmVsICsgMSwgaW5kZW50YXRpb24pOwogICAgICAgIGlmKChpICsgMSkgPCBvYmoudmFsdWUubGVuZ3RoKSB7CiAgICAgICAgICBzdWIgKz0gJywnOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcnZhbCArPSBpbmRlbnQgKyAnU3ViIHZhbHVlczogJyArIHN1YnZhbHVlcyArIHN1YjsKICB9IGVsc2UgewogICAgcnZhbCArPSBpbmRlbnQgKyAnVmFsdWU6ICc7CiAgICBpZihvYmoudHlwZSA9PT0gYXNuMS5UeXBlLk9JRCkgewogICAgICB2YXIgb2lkID0gYXNuMS5kZXJUb09pZChvYmoudmFsdWUpOwogICAgICBydmFsICs9IG9pZDsKICAgICAgaWYoZm9yZ2UucGtpICYmIGZvcmdlLnBraS5vaWRzKSB7CiAgICAgICAgaWYob2lkIGluIGZvcmdlLnBraS5vaWRzKSB7CiAgICAgICAgICBydmFsICs9ICcgKCcgKyBmb3JnZS5wa2kub2lkc1tvaWRdICsgJykgJzsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGlmKG9iai50eXBlID09PSBhc24xLlR5cGUuSU5URUdFUikgewogICAgICB0cnkgewogICAgICAgIHJ2YWwgKz0gYXNuMS5kZXJUb0ludGVnZXIob2JqLnZhbHVlKTsKICAgICAgfSBjYXRjaChleCkgewogICAgICAgIHJ2YWwgKz0gJzB4JyArIGZvcmdlLnV0aWwuYnl0ZXNUb0hleChvYmoudmFsdWUpOwogICAgICB9CiAgICB9IGVsc2UgaWYob2JqLnR5cGUgPT09IGFzbjEuVHlwZS5PQ1RFVFNUUklORykgewogICAgICBpZighX25vbkxhdGluUmVnZXgudGVzdChvYmoudmFsdWUpKSB7CiAgICAgICAgcnZhbCArPSAnKCcgKyBvYmoudmFsdWUgKyAnKSAnOwogICAgICB9CiAgICAgIHJ2YWwgKz0gJzB4JyArIGZvcmdlLnV0aWwuYnl0ZXNUb0hleChvYmoudmFsdWUpOwogICAgfSBlbHNlIGlmKG9iai50eXBlID09PSBhc24xLlR5cGUuVVRGOCkgewogICAgICBydmFsICs9IGZvcmdlLnV0aWwuZGVjb2RlVXRmOChvYmoudmFsdWUpOwogICAgfSBlbHNlIGlmKG9iai50eXBlID09PSBhc24xLlR5cGUuUFJJTlRBQkxFU1RSSU5HIHx8CiAgICAgIG9iai50eXBlID09PSBhc24xLlR5cGUuSUE1U3RyaW5nKSB7CiAgICAgIHJ2YWwgKz0gb2JqLnZhbHVlOwogICAgfSBlbHNlIGlmKF9ub25MYXRpblJlZ2V4LnRlc3Qob2JqLnZhbHVlKSkgewogICAgICBydmFsICs9ICcweCcgKyBmb3JnZS51dGlsLmJ5dGVzVG9IZXgob2JqLnZhbHVlKTsKICAgIH0gZWxzZSBpZihvYmoudmFsdWUubGVuZ3RoID09PSAwKSB7CiAgICAgIHJ2YWwgKz0gJ1tudWxsXSc7CiAgICB9IGVsc2UgewogICAgICBydmFsICs9IG9iai52YWx1ZTsKICAgIH0KICB9CgogIHJldHVybiBydmFsOwp9OwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAnYXNuMSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9hc24xJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCcsICcuL29pZHMnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogTWVzc2FnZSBEaWdlc3QgQWxnb3JpdGhtIDUgd2l0aCAxMjgtYml0IGRpZ2VzdCAoTUQ1KSBpbXBsZW1lbnRhdGlvbi4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7Cgp2YXIgbWQ1ID0gZm9yZ2UubWQ1ID0gZm9yZ2UubWQ1IHx8IHt9Owpmb3JnZS5tZCA9IGZvcmdlLm1kIHx8IHt9Owpmb3JnZS5tZC5hbGdvcml0aG1zID0gZm9yZ2UubWQuYWxnb3JpdGhtcyB8fCB7fTsKZm9yZ2UubWQubWQ1ID0gZm9yZ2UubWQuYWxnb3JpdGhtcy5tZDUgPSBtZDU7CgovKioKICogQ3JlYXRlcyBhbiBNRDUgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0LgogKgogKiBAcmV0dXJuIGEgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0LgogKi8KbWQ1LmNyZWF0ZSA9IGZ1bmN0aW9uKCkgewogIC8vIGRvIGluaXRpYWxpemF0aW9uIGFzIG5lY2Vzc2FyeQogIGlmKCFfaW5pdGlhbGl6ZWQpIHsKICAgIF9pbml0KCk7CiAgfQoKICAvLyBNRDUgc3RhdGUgY29udGFpbnMgZm91ciAzMi1iaXQgaW50ZWdlcnMKICB2YXIgX3N0YXRlID0gbnVsbDsKCiAgLy8gaW5wdXQgYnVmZmVyCiAgdmFyIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIHVzZWQgZm9yIHdvcmQgc3RvcmFnZQogIHZhciBfdyA9IG5ldyBBcnJheSgxNik7CgogIC8vIG1lc3NhZ2UgZGlnZXN0IG9iamVjdAogIHZhciBtZCA9IHsKICAgIGFsZ29yaXRobTogJ21kNScsCiAgICBibG9ja0xlbmd0aDogNjQsCiAgICBkaWdlc3RMZW5ndGg6IDE2LAogICAgLy8gNTYtYml0IGxlbmd0aCBvZiBtZXNzYWdlIHNvIGZhciAoZG9lcyBub3QgaW5jbHVkaW5nIHBhZGRpbmcpCiAgICBtZXNzYWdlTGVuZ3RoOiAwLAogICAgLy8gdHJ1ZSBtZXNzYWdlIGxlbmd0aAogICAgZnVsbE1lc3NhZ2VMZW5ndGg6IG51bGwsCiAgICAvLyBzaXplIG9mIG1lc3NhZ2UgbGVuZ3RoIGluIGJ5dGVzCiAgICBtZXNzYWdlTGVuZ3RoU2l6ZTogOAogIH07CgogIC8qKgogICAqIFN0YXJ0cyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQuc3RhcnQgPSBmdW5jdGlvbigpIHsKICAgIC8vIHVwIHRvIDU2LWJpdCBtZXNzYWdlIGxlbmd0aCBmb3IgY29udmVuaWVuY2UKICAgIG1kLm1lc3NhZ2VMZW5ndGggPSAwOwoKICAgIC8vIGZ1bGwgbWVzc2FnZSBsZW5ndGggKHNldCBtZC5tZXNzYWdlTGVuZ3RoNjQgZm9yIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5KQogICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGggPSBtZC5tZXNzYWdlTGVuZ3RoNjQgPSBbXTsKICAgIHZhciBpbnQzMnMgPSBtZC5tZXNzYWdlTGVuZ3RoU2l6ZSAvIDQ7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgaW50MzJzOyArK2kpIHsKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGgucHVzaCgwKTsKICAgIH0KICAgIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBfc3RhdGUgPSB7CiAgICAgIGgwOiAweDY3NDUyMzAxLAogICAgICBoMTogMHhFRkNEQUI4OSwKICAgICAgaDI6IDB4OThCQURDRkUsCiAgICAgIGgzOiAweDEwMzI1NDc2CiAgICB9OwogICAgcmV0dXJuIG1kOwogIH07CiAgLy8gc3RhcnQgZGlnZXN0IGF1dG9tYXRpY2FsbHkgZm9yIGZpcnN0IHRpbWUKICBtZC5zdGFydCgpOwoKICAvKioKICAgKiBVcGRhdGVzIHRoZSBkaWdlc3Qgd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZSBpbnB1dC4gVGhlIGdpdmVuIGlucHV0IGNhbgogICAqIHRyZWF0ZWQgYXMgcmF3IGlucHV0IChubyBlbmNvZGluZyB3aWxsIGJlIGFwcGxpZWQpIG9yIGFuIGVuY29kaW5nIG9mCiAgICogJ3V0ZjgnIG1heWJlIGdpdmVuIHRvIGVuY29kZSB0aGUgaW5wdXQgdXNpbmcgVVRGLTguCiAgICoKICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlIGlucHV0IHRvIHVwZGF0ZSB3aXRoLgogICAqIEBwYXJhbSBlbmNvZGluZyB0aGUgZW5jb2RpbmcgdG8gdXNlIChkZWZhdWx0OiAncmF3Jywgb3RoZXI6ICd1dGY4JykuCiAgICoKICAgKiBAcmV0dXJuIHRoaXMgZGlnZXN0IG9iamVjdC4KICAgKi8KICBtZC51cGRhdGUgPSBmdW5jdGlvbihtc2csIGVuY29kaW5nKSB7CiAgICBpZihlbmNvZGluZyA9PT0gJ3V0ZjgnKSB7CiAgICAgIG1zZyA9IGZvcmdlLnV0aWwuZW5jb2RlVXRmOChtc2cpOwogICAgfQoKICAgIC8vIHVwZGF0ZSBtZXNzYWdlIGxlbmd0aAogICAgdmFyIGxlbiA9IG1zZy5sZW5ndGg7CiAgICBtZC5tZXNzYWdlTGVuZ3RoICs9IGxlbjsKICAgIGxlbiA9IFsobGVuIC8gMHgxMDAwMDAwMDApID4+PiAwLCBsZW4gPj4+IDBdOwogICAgZm9yKHZhciBpID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGgubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHsKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gKz0gbGVuWzFdOwogICAgICBsZW5bMV0gPSBsZW5bMF0gKyAoKG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldIC8gMHgxMDAwMDAwMDApID4+PiAwKTsKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gPSBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSA+Pj4gMDsKICAgICAgbGVuWzBdID0gKChsZW5bMV0gLyAweDEwMDAwMDAwMCkgPj4+IDApOwogICAgfQoKICAgIC8vIGFkZCBieXRlcyB0byBpbnB1dCBidWZmZXIKICAgIF9pbnB1dC5wdXRCeXRlcyhtc2cpOwoKICAgIC8vIHByb2Nlc3MgYnl0ZXMKICAgIF91cGRhdGUoX3N0YXRlLCBfdywgX2lucHV0KTsKCiAgICAvLyBjb21wYWN0IGlucHV0IGJ1ZmZlciBldmVyeSAySyBvciBpZiBlbXB0eQogICAgaWYoX2lucHV0LnJlYWQgPiAyMDQ4IHx8IF9pbnB1dC5sZW5ndGgoKSA9PT0gMCkgewogICAgICBfaW5wdXQuY29tcGFjdCgpOwogICAgfQoKICAgIHJldHVybiBtZDsKICB9OwoKICAvKioKICAgKiBQcm9kdWNlcyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiBhIGJ5dGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGRpZ2VzdCB2YWx1ZS4KICAgKi8KICBtZC5kaWdlc3QgPSBmdW5jdGlvbigpIHsKICAgIC8qIE5vdGU6IEhlcmUgd2UgY29weSB0aGUgcmVtYWluaW5nIGJ5dGVzIGluIHRoZSBpbnB1dCBidWZmZXIgYW5kCiAgICBhZGQgdGhlIGFwcHJvcHJpYXRlIE1ENSBwYWRkaW5nLiBUaGVuIHdlIGRvIHRoZSBmaW5hbCB1cGRhdGUKICAgIG9uIGEgY29weSBvZiB0aGUgc3RhdGUgc28gdGhhdCBpZiB0aGUgdXNlciB3YW50cyB0byBnZXQKICAgIGludGVybWVkaWF0ZSBkaWdlc3RzIHRoZXkgY2FuIGRvIHNvLiAqLwoKICAgIC8qIERldGVybWluZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgbXVzdCBiZSBhZGRlZCB0byB0aGUgbWVzc2FnZQogICAgdG8gZW5zdXJlIGl0cyBsZW5ndGggaXMgY29uZ3J1ZW50IHRvIDQ0OCBtb2QgNTEyLiBJbiBvdGhlciB3b3JkcywKICAgIHRoZSBkYXRhIHRvIGJlIGRpZ2VzdGVkIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA1MTIgYml0cyAob3IgMTI4IGJ5dGVzKS4KICAgIFRoaXMgZGF0YSBpbmNsdWRlcyB0aGUgbWVzc2FnZSwgc29tZSBwYWRkaW5nLCBhbmQgdGhlIGxlbmd0aCBvZiB0aGUKICAgIG1lc3NhZ2UuIFNpbmNlIHRoZSBsZW5ndGggb2YgdGhlIG1lc3NhZ2Ugd2lsbCBiZSBlbmNvZGVkIGFzIDggYnl0ZXMgKDY0CiAgICBiaXRzKSwgdGhhdCBtZWFucyB0aGF0IHRoZSBsYXN0IHNlZ21lbnQgb2YgdGhlIGRhdGEgbXVzdCBoYXZlIDU2IGJ5dGVzCiAgICAoNDQ4IGJpdHMpIG9mIG1lc3NhZ2UgYW5kIHBhZGRpbmcuIFRoZXJlZm9yZSwgdGhlIGxlbmd0aCBvZiB0aGUgbWVzc2FnZQogICAgcGx1cyB0aGUgcGFkZGluZyBtdXN0IGJlIGNvbmdydWVudCB0byA0NDggbW9kIDUxMiBiZWNhdXNlCiAgICA1MTIgLSAxMjggPSA0NDguCgogICAgSW4gb3JkZXIgdG8gZmlsbCB1cCB0aGUgbWVzc2FnZSBsZW5ndGggaXQgbXVzdCBiZSBmaWxsZWQgd2l0aAogICAgcGFkZGluZyB0aGF0IGJlZ2lucyB3aXRoIDEgYml0IGZvbGxvd2VkIGJ5IGFsbCAwIGJpdHMuIFBhZGRpbmcKICAgIG11c3QgKmFsd2F5cyogYmUgcHJlc2VudCwgc28gaWYgdGhlIG1lc3NhZ2UgbGVuZ3RoIGlzIGFscmVhZHkKICAgIGNvbmdydWVudCB0byA0NDggbW9kIDUxMiwgdGhlbiA1MTIgcGFkZGluZyBiaXRzIG11c3QgYmUgYWRkZWQuICovCgogICAgdmFyIGZpbmFsQmxvY2sgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgZmluYWxCbG9jay5wdXRCeXRlcyhfaW5wdXQuYnl0ZXMoKSk7CgogICAgLy8gY29tcHV0ZSByZW1haW5pbmcgc2l6ZSB0byBiZSBkaWdlc3RlZCAoaW5jbHVkZSBtZXNzYWdlIGxlbmd0aCBzaXplKQogICAgdmFyIHJlbWFpbmluZyA9ICgKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGhbbWQuZnVsbE1lc3NhZ2VMZW5ndGgubGVuZ3RoIC0gMV0gKwogICAgICBtZC5tZXNzYWdlTGVuZ3RoU2l6ZSk7CgogICAgLy8gYWRkIHBhZGRpbmcgZm9yIG92ZXJmbG93IGJsb2NrU2l6ZSAtIG92ZXJmbG93CiAgICAvLyBfcGFkZGluZyBzdGFydHMgd2l0aCAxIGJ5dGUgd2l0aCBmaXJzdCBiaXQgaXMgc2V0IChieXRlIHZhbHVlIDEyOCksIHRoZW4KICAgIC8vIHRoZXJlIG1heSBiZSB1cCB0byAoYmxvY2tTaXplIC0gMSkgb3RoZXIgcGFkIGJ5dGVzCiAgICB2YXIgb3ZlcmZsb3cgPSByZW1haW5pbmcgJiAobWQuYmxvY2tMZW5ndGggLSAxKTsKICAgIGZpbmFsQmxvY2sucHV0Qnl0ZXMoX3BhZGRpbmcuc3Vic3RyKDAsIG1kLmJsb2NrTGVuZ3RoIC0gb3ZlcmZsb3cpKTsKCiAgICAvLyBzZXJpYWxpemUgbWVzc2FnZSBsZW5ndGggaW4gYml0cyBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyOyBzaW5jZSBsZW5ndGgKICAgIC8vIGlzIHN0b3JlZCBpbiBieXRlcyB3ZSBtdWx0aXBseSBieSA4IGFuZCBhZGQgY2FycnkKICAgIHZhciBiaXRzLCBjYXJyeSA9IDA7CiAgICBmb3IodmFyIGkgPSBtZC5mdWxsTWVzc2FnZUxlbmd0aC5sZW5ndGggLSAxOyBpID49IDA7IC0taSkgewogICAgICBiaXRzID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gKiA4ICsgY2Fycnk7CiAgICAgIGNhcnJ5ID0gKGJpdHMgLyAweDEwMDAwMDAwMCkgPj4+IDA7CiAgICAgIGZpbmFsQmxvY2sucHV0SW50MzJMZShiaXRzID4+PiAwKTsKICAgIH0KCiAgICB2YXIgczIgPSB7CiAgICAgIGgwOiBfc3RhdGUuaDAsCiAgICAgIGgxOiBfc3RhdGUuaDEsCiAgICAgIGgyOiBfc3RhdGUuaDIsCiAgICAgIGgzOiBfc3RhdGUuaDMKICAgIH07CiAgICBfdXBkYXRlKHMyLCBfdywgZmluYWxCbG9jayk7CiAgICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBydmFsLnB1dEludDMyTGUoczIuaDApOwogICAgcnZhbC5wdXRJbnQzMkxlKHMyLmgxKTsKICAgIHJ2YWwucHV0SW50MzJMZShzMi5oMik7CiAgICBydmFsLnB1dEludDMyTGUoczIuaDMpOwogICAgcmV0dXJuIHJ2YWw7CiAgfTsKCiAgcmV0dXJuIG1kOwp9OwoKLy8gcGFkZGluZywgY29uc3RhbnQgdGFibGVzIGZvciBjYWxjdWxhdGluZyBtZDUKdmFyIF9wYWRkaW5nID0gbnVsbDsKdmFyIF9nID0gbnVsbDsKdmFyIF9yID0gbnVsbDsKdmFyIF9rID0gbnVsbDsKdmFyIF9pbml0aWFsaXplZCA9IGZhbHNlOwoKLyoqCiAqIEluaXRpYWxpemVzIHRoZSBjb25zdGFudCB0YWJsZXMuCiAqLwpmdW5jdGlvbiBfaW5pdCgpIHsKICAvLyBjcmVhdGUgcGFkZGluZwogIF9wYWRkaW5nID0gU3RyaW5nLmZyb21DaGFyQ29kZSgxMjgpOwogIF9wYWRkaW5nICs9IGZvcmdlLnV0aWwuZmlsbFN0cmluZyhTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDApLCA2NCk7CgogIC8vIGcgdmFsdWVzCiAgX2cgPSBbCiAgICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAogICAgMSwgNiwgMTEsIDAsIDUsIDEwLCAxNSwgNCwgOSwgMTQsIDMsIDgsIDEzLCAyLCA3LCAxMiwKICAgIDUsIDgsIDExLCAxNCwgMSwgNCwgNywgMTAsIDEzLCAwLCAzLCA2LCA5LCAxMiwgMTUsIDIsCiAgICAwLCA3LCAxNCwgNSwgMTIsIDMsIDEwLCAxLCA4LCAxNSwgNiwgMTMsIDQsIDExLCAyLCA5XTsKCiAgLy8gcm91bmRzIHRhYmxlCiAgX3IgPSBbCiAgICA3LCAxMiwgMTcsIDIyLCAgNywgMTIsIDE3LCAyMiwgIDcsIDEyLCAxNywgMjIsICA3LCAxMiwgMTcsIDIyLAogICAgNSwgIDksIDE0LCAyMCwgIDUsICA5LCAxNCwgMjAsICA1LCAgOSwgMTQsIDIwLCAgNSwgIDksIDE0LCAyMCwKICAgIDQsIDExLCAxNiwgMjMsICA0LCAxMSwgMTYsIDIzLCAgNCwgMTEsIDE2LCAyMywgIDQsIDExLCAxNiwgMjMsCiAgICA2LCAxMCwgMTUsIDIxLCAgNiwgMTAsIDE1LCAyMSwgIDYsIDEwLCAxNSwgMjEsICA2LCAxMCwgMTUsIDIxXTsKCiAgLy8gZ2V0IHRoZSByZXN1bHQgb2YgYWJzKHNpbihpICsgMSkpIGFzIGEgMzItYml0IGludGVnZXIKICBfayA9IG5ldyBBcnJheSg2NCk7CiAgZm9yKHZhciBpID0gMDsgaSA8IDY0OyArK2kpIHsKICAgIF9rW2ldID0gTWF0aC5mbG9vcihNYXRoLmFicyhNYXRoLnNpbihpICsgMSkpICogMHgxMDAwMDAwMDApOwogIH0KCiAgLy8gbm93IGluaXRpYWxpemVkCiAgX2luaXRpYWxpemVkID0gdHJ1ZTsKfQoKLyoqCiAqIFVwZGF0ZXMgYW4gTUQ1IHN0YXRlIHdpdGggdGhlIGdpdmVuIGJ5dGUgYnVmZmVyLgogKgogKiBAcGFyYW0gcyB0aGUgTUQ1IHN0YXRlIHRvIHVwZGF0ZS4KICogQHBhcmFtIHcgdGhlIGFycmF5IHRvIHVzZSB0byBzdG9yZSB3b3Jkcy4KICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlIGJ1ZmZlciB0byB1cGRhdGUgd2l0aC4KICovCmZ1bmN0aW9uIF91cGRhdGUocywgdywgYnl0ZXMpIHsKICAvLyBjb25zdW1lIDUxMiBiaXQgKDY0IGJ5dGUpIGNodW5rcwogIHZhciB0LCBhLCBiLCBjLCBkLCBmLCByLCBpOwogIHZhciBsZW4gPSBieXRlcy5sZW5ndGgoKTsKICB3aGlsZShsZW4gPj0gNjQpIHsKICAgIC8vIGluaXRpYWxpemUgaGFzaCB2YWx1ZSBmb3IgdGhpcyBjaHVuawogICAgYSA9IHMuaDA7CiAgICBiID0gcy5oMTsKICAgIGMgPSBzLmgyOwogICAgZCA9IHMuaDM7CgogICAgLy8gcm91bmQgMQogICAgZm9yKGkgPSAwOyBpIDwgMTY7ICsraSkgewogICAgICB3W2ldID0gYnl0ZXMuZ2V0SW50MzJMZSgpOwogICAgICBmID0gZCBeIChiICYgKGMgXiBkKSk7CiAgICAgIHQgPSAoYSArIGYgKyBfa1tpXSArIHdbaV0pOwogICAgICByID0gX3JbaV07CiAgICAgIGEgPSBkOwogICAgICBkID0gYzsKICAgICAgYyA9IGI7CiAgICAgIGIgKz0gKHQgPDwgcikgfCAodCA+Pj4gKDMyIC0gcikpOwogICAgfQogICAgLy8gcm91bmQgMgogICAgZm9yKDsgaSA8IDMyOyArK2kpIHsKICAgICAgZiA9IGMgXiAoZCAmIChiIF4gYykpOwogICAgICB0ID0gKGEgKyBmICsgX2tbaV0gKyB3W19nW2ldXSk7CiAgICAgIHIgPSBfcltpXTsKICAgICAgYSA9IGQ7CiAgICAgIGQgPSBjOwogICAgICBjID0gYjsKICAgICAgYiArPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7CiAgICB9CiAgICAvLyByb3VuZCAzCiAgICBmb3IoOyBpIDwgNDg7ICsraSkgewogICAgICBmID0gYiBeIGMgXiBkOwogICAgICB0ID0gKGEgKyBmICsgX2tbaV0gKyB3W19nW2ldXSk7CiAgICAgIHIgPSBfcltpXTsKICAgICAgYSA9IGQ7CiAgICAgIGQgPSBjOwogICAgICBjID0gYjsKICAgICAgYiArPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7CiAgICB9CiAgICAvLyByb3VuZCA0CiAgICBmb3IoOyBpIDwgNjQ7ICsraSkgewogICAgICBmID0gYyBeIChiIHwgfmQpOwogICAgICB0ID0gKGEgKyBmICsgX2tbaV0gKyB3W19nW2ldXSk7CiAgICAgIHIgPSBfcltpXTsKICAgICAgYSA9IGQ7CiAgICAgIGQgPSBjOwogICAgICBjID0gYjsKICAgICAgYiArPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7CiAgICB9CgogICAgLy8gdXBkYXRlIGhhc2ggc3RhdGUKICAgIHMuaDAgPSAocy5oMCArIGEpIHwgMDsKICAgIHMuaDEgPSAocy5oMSArIGIpIHwgMDsKICAgIHMuaDIgPSAocy5oMiArIGMpIHwgMDsKICAgIHMuaDMgPSAocy5oMyArIGQpIHwgMDsKCiAgICBsZW4gLT0gNjQ7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdtZDUnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvbWQ1JyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBTZWN1cmUgSGFzaCBBbGdvcml0aG0gd2l0aCAxNjAtYml0IGRpZ2VzdCAoU0hBLTEpIGltcGxlbWVudGF0aW9uLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNSBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCnZhciBzaGExID0gZm9yZ2Uuc2hhMSA9IGZvcmdlLnNoYTEgfHwge307CmZvcmdlLm1kID0gZm9yZ2UubWQgfHwge307CmZvcmdlLm1kLmFsZ29yaXRobXMgPSBmb3JnZS5tZC5hbGdvcml0aG1zIHx8IHt9Owpmb3JnZS5tZC5zaGExID0gZm9yZ2UubWQuYWxnb3JpdGhtcy5zaGExID0gc2hhMTsKCi8qKgogKiBDcmVhdGVzIGEgU0hBLTEgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0LgogKgogKiBAcmV0dXJuIGEgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0LgogKi8Kc2hhMS5jcmVhdGUgPSBmdW5jdGlvbigpIHsKICAvLyBkbyBpbml0aWFsaXphdGlvbiBhcyBuZWNlc3NhcnkKICBpZighX2luaXRpYWxpemVkKSB7CiAgICBfaW5pdCgpOwogIH0KCiAgLy8gU0hBLTEgc3RhdGUgY29udGFpbnMgZml2ZSAzMi1iaXQgaW50ZWdlcnMKICB2YXIgX3N0YXRlID0gbnVsbDsKCiAgLy8gaW5wdXQgYnVmZmVyCiAgdmFyIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIHVzZWQgZm9yIHdvcmQgc3RvcmFnZQogIHZhciBfdyA9IG5ldyBBcnJheSg4MCk7CgogIC8vIG1lc3NhZ2UgZGlnZXN0IG9iamVjdAogIHZhciBtZCA9IHsKICAgIGFsZ29yaXRobTogJ3NoYTEnLAogICAgYmxvY2tMZW5ndGg6IDY0LAogICAgZGlnZXN0TGVuZ3RoOiAyMCwKICAgIC8vIDU2LWJpdCBsZW5ndGggb2YgbWVzc2FnZSBzbyBmYXIgKGRvZXMgbm90IGluY2x1ZGluZyBwYWRkaW5nKQogICAgbWVzc2FnZUxlbmd0aDogMCwKICAgIC8vIHRydWUgbWVzc2FnZSBsZW5ndGgKICAgIGZ1bGxNZXNzYWdlTGVuZ3RoOiBudWxsLAogICAgLy8gc2l6ZSBvZiBtZXNzYWdlIGxlbmd0aCBpbiBieXRlcwogICAgbWVzc2FnZUxlbmd0aFNpemU6IDgKICB9OwoKICAvKioKICAgKiBTdGFydHMgdGhlIGRpZ2VzdC4KICAgKgogICAqIEByZXR1cm4gdGhpcyBkaWdlc3Qgb2JqZWN0LgogICAqLwogIG1kLnN0YXJ0ID0gZnVuY3Rpb24oKSB7CiAgICAvLyB1cCB0byA1Ni1iaXQgbWVzc2FnZSBsZW5ndGggZm9yIGNvbnZlbmllbmNlCiAgICBtZC5tZXNzYWdlTGVuZ3RoID0gMDsKCiAgICAvLyBmdWxsIG1lc3NhZ2UgbGVuZ3RoIChzZXQgbWQubWVzc2FnZUxlbmd0aDY0IGZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSkKICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoID0gbWQubWVzc2FnZUxlbmd0aDY0ID0gW107CiAgICB2YXIgaW50MzJzID0gbWQubWVzc2FnZUxlbmd0aFNpemUgLyA0OwogICAgZm9yKHZhciBpID0gMDsgaSA8IGludDMyczsgKytpKSB7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLnB1c2goMCk7CiAgICB9CiAgICBfaW5wdXQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgX3N0YXRlID0gewogICAgICBoMDogMHg2NzQ1MjMwMSwKICAgICAgaDE6IDB4RUZDREFCODksCiAgICAgIGgyOiAweDk4QkFEQ0ZFLAogICAgICBoMzogMHgxMDMyNTQ3NiwKICAgICAgaDQ6IDB4QzNEMkUxRjAKICAgIH07CiAgICByZXR1cm4gbWQ7CiAgfTsKICAvLyBzdGFydCBkaWdlc3QgYXV0b21hdGljYWxseSBmb3IgZmlyc3QgdGltZQogIG1kLnN0YXJ0KCk7CgogIC8qKgogICAqIFVwZGF0ZXMgdGhlIGRpZ2VzdCB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlIGlucHV0LiBUaGUgZ2l2ZW4gaW5wdXQgY2FuCiAgICogdHJlYXRlZCBhcyByYXcgaW5wdXQgKG5vIGVuY29kaW5nIHdpbGwgYmUgYXBwbGllZCkgb3IgYW4gZW5jb2Rpbmcgb2YKICAgKiAndXRmOCcgbWF5YmUgZ2l2ZW4gdG8gZW5jb2RlIHRoZSBpbnB1dCB1c2luZyBVVEYtOC4KICAgKgogICAqIEBwYXJhbSBtc2cgdGhlIG1lc3NhZ2UgaW5wdXQgdG8gdXBkYXRlIHdpdGguCiAgICogQHBhcmFtIGVuY29kaW5nIHRoZSBlbmNvZGluZyB0byB1c2UgKGRlZmF1bHQ6ICdyYXcnLCBvdGhlcjogJ3V0ZjgnKS4KICAgKgogICAqIEByZXR1cm4gdGhpcyBkaWdlc3Qgb2JqZWN0LgogICAqLwogIG1kLnVwZGF0ZSA9IGZ1bmN0aW9uKG1zZywgZW5jb2RpbmcpIHsKICAgIGlmKGVuY29kaW5nID09PSAndXRmOCcpIHsKICAgICAgbXNnID0gZm9yZ2UudXRpbC5lbmNvZGVVdGY4KG1zZyk7CiAgICB9CgogICAgLy8gdXBkYXRlIG1lc3NhZ2UgbGVuZ3RoCiAgICB2YXIgbGVuID0gbXNnLmxlbmd0aDsKICAgIG1kLm1lc3NhZ2VMZW5ndGggKz0gbGVuOwogICAgbGVuID0gWyhsZW4gLyAweDEwMDAwMDAwMCkgPj4+IDAsIGxlbiA+Pj4gMF07CiAgICBmb3IodmFyIGkgPSBtZC5mdWxsTWVzc2FnZUxlbmd0aC5sZW5ndGggLSAxOyBpID49IDA7IC0taSkgewogICAgICBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSArPSBsZW5bMV07CiAgICAgIGxlblsxXSA9IGxlblswXSArICgobWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gLyAweDEwMDAwMDAwMCkgPj4+IDApOwogICAgICBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSA9IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldID4+PiAwOwogICAgICBsZW5bMF0gPSAoKGxlblsxXSAvIDB4MTAwMDAwMDAwKSA+Pj4gMCk7CiAgICB9CgogICAgLy8gYWRkIGJ5dGVzIHRvIGlucHV0IGJ1ZmZlcgogICAgX2lucHV0LnB1dEJ5dGVzKG1zZyk7CgogICAgLy8gcHJvY2VzcyBieXRlcwogICAgX3VwZGF0ZShfc3RhdGUsIF93LCBfaW5wdXQpOwoKICAgIC8vIGNvbXBhY3QgaW5wdXQgYnVmZmVyIGV2ZXJ5IDJLIG9yIGlmIGVtcHR5CiAgICBpZihfaW5wdXQucmVhZCA+IDIwNDggfHwgX2lucHV0Lmxlbmd0aCgpID09PSAwKSB7CiAgICAgIF9pbnB1dC5jb21wYWN0KCk7CiAgICB9CgogICAgcmV0dXJuIG1kOwogIH07CgogICAvKioKICAgICogUHJvZHVjZXMgdGhlIGRpZ2VzdC4KICAgICoKICAgICogQHJldHVybiBhIGJ5dGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGRpZ2VzdCB2YWx1ZS4KICAgICovCiAgIG1kLmRpZ2VzdCA9IGZ1bmN0aW9uKCkgewogICAgLyogTm90ZTogSGVyZSB3ZSBjb3B5IHRoZSByZW1haW5pbmcgYnl0ZXMgaW4gdGhlIGlucHV0IGJ1ZmZlciBhbmQKICAgIGFkZCB0aGUgYXBwcm9wcmlhdGUgU0hBLTEgcGFkZGluZy4gVGhlbiB3ZSBkbyB0aGUgZmluYWwgdXBkYXRlCiAgICBvbiBhIGNvcHkgb2YgdGhlIHN0YXRlIHNvIHRoYXQgaWYgdGhlIHVzZXIgd2FudHMgdG8gZ2V0CiAgICBpbnRlcm1lZGlhdGUgZGlnZXN0cyB0aGV5IGNhbiBkbyBzby4gKi8KCiAgICAvKiBEZXRlcm1pbmUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IG11c3QgYmUgYWRkZWQgdG8gdGhlIG1lc3NhZ2UKICAgIHRvIGVuc3VyZSBpdHMgbGVuZ3RoIGlzIGNvbmdydWVudCB0byA0NDggbW9kIDUxMi4gSW4gb3RoZXIgd29yZHMsCiAgICB0aGUgZGF0YSB0byBiZSBkaWdlc3RlZCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNTEyIGJpdHMgKG9yIDEyOCBieXRlcykuCiAgICBUaGlzIGRhdGEgaW5jbHVkZXMgdGhlIG1lc3NhZ2UsIHNvbWUgcGFkZGluZywgYW5kIHRoZSBsZW5ndGggb2YgdGhlCiAgICBtZXNzYWdlLiBTaW5jZSB0aGUgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlIHdpbGwgYmUgZW5jb2RlZCBhcyA4IGJ5dGVzICg2NAogICAgYml0cyksIHRoYXQgbWVhbnMgdGhhdCB0aGUgbGFzdCBzZWdtZW50IG9mIHRoZSBkYXRhIG11c3QgaGF2ZSA1NiBieXRlcwogICAgKDQ0OCBiaXRzKSBvZiBtZXNzYWdlIGFuZCBwYWRkaW5nLiBUaGVyZWZvcmUsIHRoZSBsZW5ndGggb2YgdGhlIG1lc3NhZ2UKICAgIHBsdXMgdGhlIHBhZGRpbmcgbXVzdCBiZSBjb25ncnVlbnQgdG8gNDQ4IG1vZCA1MTIgYmVjYXVzZQogICAgNTEyIC0gMTI4ID0gNDQ4LgoKICAgIEluIG9yZGVyIHRvIGZpbGwgdXAgdGhlIG1lc3NhZ2UgbGVuZ3RoIGl0IG11c3QgYmUgZmlsbGVkIHdpdGgKICAgIHBhZGRpbmcgdGhhdCBiZWdpbnMgd2l0aCAxIGJpdCBmb2xsb3dlZCBieSBhbGwgMCBiaXRzLiBQYWRkaW5nCiAgICBtdXN0ICphbHdheXMqIGJlIHByZXNlbnQsIHNvIGlmIHRoZSBtZXNzYWdlIGxlbmd0aCBpcyBhbHJlYWR5CiAgICBjb25ncnVlbnQgdG8gNDQ4IG1vZCA1MTIsIHRoZW4gNTEyIHBhZGRpbmcgYml0cyBtdXN0IGJlIGFkZGVkLiAqLwoKICAgIHZhciBmaW5hbEJsb2NrID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGZpbmFsQmxvY2sucHV0Qnl0ZXMoX2lucHV0LmJ5dGVzKCkpOwoKICAgIC8vIGNvbXB1dGUgcmVtYWluaW5nIHNpemUgdG8gYmUgZGlnZXN0ZWQgKGluY2x1ZGUgbWVzc2FnZSBsZW5ndGggc2l6ZSkKICAgIHZhciByZW1haW5pbmcgPSAoCiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW21kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aCAtIDFdICsKICAgICAgbWQubWVzc2FnZUxlbmd0aFNpemUpOwoKICAgIC8vIGFkZCBwYWRkaW5nIGZvciBvdmVyZmxvdyBibG9ja1NpemUgLSBvdmVyZmxvdwogICAgLy8gX3BhZGRpbmcgc3RhcnRzIHdpdGggMSBieXRlIHdpdGggZmlyc3QgYml0IGlzIHNldCAoYnl0ZSB2YWx1ZSAxMjgpLCB0aGVuCiAgICAvLyB0aGVyZSBtYXkgYmUgdXAgdG8gKGJsb2NrU2l6ZSAtIDEpIG90aGVyIHBhZCBieXRlcwogICAgdmFyIG92ZXJmbG93ID0gcmVtYWluaW5nICYgKG1kLmJsb2NrTGVuZ3RoIC0gMSk7CiAgICBmaW5hbEJsb2NrLnB1dEJ5dGVzKF9wYWRkaW5nLnN1YnN0cigwLCBtZC5ibG9ja0xlbmd0aCAtIG92ZXJmbG93KSk7CgogICAgLy8gc2VyaWFsaXplIG1lc3NhZ2UgbGVuZ3RoIGluIGJpdHMgaW4gYmlnLWVuZGlhbiBvcmRlcjsgc2luY2UgbGVuZ3RoCiAgICAvLyBpcyBzdG9yZWQgaW4gYnl0ZXMgd2UgbXVsdGlwbHkgYnkgOCBhbmQgYWRkIGNhcnJ5IGZyb20gbmV4dCBpbnQKICAgIHZhciBtZXNzYWdlTGVuZ3RoID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIHZhciBuZXh0LCBjYXJyeTsKICAgIHZhciBiaXRzID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbMF0gKiA4OwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aDsgKytpKSB7CiAgICAgIG5leHQgPSBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpICsgMV0gKiA4OwogICAgICBjYXJyeSA9IChuZXh0IC8gMHgxMDAwMDAwMDApID4+PiAwOwogICAgICBiaXRzICs9IGNhcnJ5OwogICAgICBmaW5hbEJsb2NrLnB1dEludDMyKGJpdHMgPj4+IDApOwogICAgICBiaXRzID0gbmV4dDsKICAgIH0KCiAgICB2YXIgczIgPSB7CiAgICAgIGgwOiBfc3RhdGUuaDAsCiAgICAgIGgxOiBfc3RhdGUuaDEsCiAgICAgIGgyOiBfc3RhdGUuaDIsCiAgICAgIGgzOiBfc3RhdGUuaDMsCiAgICAgIGg0OiBfc3RhdGUuaDQKICAgIH07CiAgICBfdXBkYXRlKHMyLCBfdywgZmluYWxCbG9jayk7CiAgICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBydmFsLnB1dEludDMyKHMyLmgwKTsKICAgIHJ2YWwucHV0SW50MzIoczIuaDEpOwogICAgcnZhbC5wdXRJbnQzMihzMi5oMik7CiAgICBydmFsLnB1dEludDMyKHMyLmgzKTsKICAgIHJ2YWwucHV0SW50MzIoczIuaDQpOwogICAgcmV0dXJuIHJ2YWw7CiAgfTsKCiAgcmV0dXJuIG1kOwp9OwoKLy8gc2hhLTEgcGFkZGluZyBieXRlcyBub3QgaW5pdGlhbGl6ZWQgeWV0CnZhciBfcGFkZGluZyA9IG51bGw7CnZhciBfaW5pdGlhbGl6ZWQgPSBmYWxzZTsKCi8qKgogKiBJbml0aWFsaXplcyB0aGUgY29uc3RhbnQgdGFibGVzLgogKi8KZnVuY3Rpb24gX2luaXQoKSB7CiAgLy8gY3JlYXRlIHBhZGRpbmcKICBfcGFkZGluZyA9IFN0cmluZy5mcm9tQ2hhckNvZGUoMTI4KTsKICBfcGFkZGluZyArPSBmb3JnZS51dGlsLmZpbGxTdHJpbmcoU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKSwgNjQpOwoKICAvLyBub3cgaW5pdGlhbGl6ZWQKICBfaW5pdGlhbGl6ZWQgPSB0cnVlOwp9CgovKioKICogVXBkYXRlcyBhIFNIQS0xIHN0YXRlIHdpdGggdGhlIGdpdmVuIGJ5dGUgYnVmZmVyLgogKgogKiBAcGFyYW0gcyB0aGUgU0hBLTEgc3RhdGUgdG8gdXBkYXRlLgogKiBAcGFyYW0gdyB0aGUgYXJyYXkgdG8gdXNlIHRvIHN0b3JlIHdvcmRzLgogKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYnVmZmVyIHRvIHVwZGF0ZSB3aXRoLgogKi8KZnVuY3Rpb24gX3VwZGF0ZShzLCB3LCBieXRlcykgewogIC8vIGNvbnN1bWUgNTEyIGJpdCAoNjQgYnl0ZSkgY2h1bmtzCiAgdmFyIHQsIGEsIGIsIGMsIGQsIGUsIGYsIGk7CiAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aCgpOwogIHdoaWxlKGxlbiA+PSA2NCkgewogICAgLy8gdGhlIHcgYXJyYXkgd2lsbCBiZSBwb3B1bGF0ZWQgd2l0aCBzaXh0ZWVuIDMyLWJpdCBiaWctZW5kaWFuIHdvcmRzCiAgICAvLyBhbmQgdGhlbiBleHRlbmRlZCBpbnRvIDgwIDMyLWJpdCB3b3JkcyBhY2NvcmRpbmcgdG8gU0hBLTEgYWxnb3JpdGhtCiAgICAvLyBhbmQgZm9yIDMyLTc5IHVzaW5nIE1heCBMb2NrdHl1a2hpbidzIG9wdGltaXphdGlvbgoKICAgIC8vIGluaXRpYWxpemUgaGFzaCB2YWx1ZSBmb3IgdGhpcyBjaHVuawogICAgYSA9IHMuaDA7CiAgICBiID0gcy5oMTsKICAgIGMgPSBzLmgyOwogICAgZCA9IHMuaDM7CiAgICBlID0gcy5oNDsKCiAgICAvLyByb3VuZCAxCiAgICBmb3IoaSA9IDA7IGkgPCAxNjsgKytpKSB7CiAgICAgIHQgPSBieXRlcy5nZXRJbnQzMigpOwogICAgICB3W2ldID0gdDsKICAgICAgZiA9IGQgXiAoYiAmIChjIF4gZCkpOwogICAgICB0ID0gKChhIDw8IDUpIHwgKGEgPj4+IDI3KSkgKyBmICsgZSArIDB4NUE4Mjc5OTkgKyB0OwogICAgICBlID0gZDsKICAgICAgZCA9IGM7CiAgICAgIGMgPSAoYiA8PCAzMCkgfCAoYiA+Pj4gMik7CiAgICAgIGIgPSBhOwogICAgICBhID0gdDsKICAgIH0KICAgIGZvcig7IGkgPCAyMDsgKytpKSB7CiAgICAgIHQgPSAod1tpIC0gM10gXiB3W2kgLSA4XSBeIHdbaSAtIDE0XSBeIHdbaSAtIDE2XSk7CiAgICAgIHQgPSAodCA8PCAxKSB8ICh0ID4+PiAzMSk7CiAgICAgIHdbaV0gPSB0OwogICAgICBmID0gZCBeIChiICYgKGMgXiBkKSk7CiAgICAgIHQgPSAoKGEgPDwgNSkgfCAoYSA+Pj4gMjcpKSArIGYgKyBlICsgMHg1QTgyNzk5OSArIHQ7CiAgICAgIGUgPSBkOwogICAgICBkID0gYzsKICAgICAgYyA9IChiIDw8IDMwKSB8IChiID4+PiAyKTsKICAgICAgYiA9IGE7CiAgICAgIGEgPSB0OwogICAgfQogICAgLy8gcm91bmQgMgogICAgZm9yKDsgaSA8IDMyOyArK2kpIHsKICAgICAgdCA9ICh3W2kgLSAzXSBeIHdbaSAtIDhdIF4gd1tpIC0gMTRdIF4gd1tpIC0gMTZdKTsKICAgICAgdCA9ICh0IDw8IDEpIHwgKHQgPj4+IDMxKTsKICAgICAgd1tpXSA9IHQ7CiAgICAgIGYgPSBiIF4gYyBeIGQ7CiAgICAgIHQgPSAoKGEgPDwgNSkgfCAoYSA+Pj4gMjcpKSArIGYgKyBlICsgMHg2RUQ5RUJBMSArIHQ7CiAgICAgIGUgPSBkOwogICAgICBkID0gYzsKICAgICAgYyA9IChiIDw8IDMwKSB8IChiID4+PiAyKTsKICAgICAgYiA9IGE7CiAgICAgIGEgPSB0OwogICAgfQogICAgZm9yKDsgaSA8IDQwOyArK2kpIHsKICAgICAgdCA9ICh3W2kgLSA2XSBeIHdbaSAtIDE2XSBeIHdbaSAtIDI4XSBeIHdbaSAtIDMyXSk7CiAgICAgIHQgPSAodCA8PCAyKSB8ICh0ID4+PiAzMCk7CiAgICAgIHdbaV0gPSB0OwogICAgICBmID0gYiBeIGMgXiBkOwogICAgICB0ID0gKChhIDw8IDUpIHwgKGEgPj4+IDI3KSkgKyBmICsgZSArIDB4NkVEOUVCQTEgKyB0OwogICAgICBlID0gZDsKICAgICAgZCA9IGM7CiAgICAgIGMgPSAoYiA8PCAzMCkgfCAoYiA+Pj4gMik7CiAgICAgIGIgPSBhOwogICAgICBhID0gdDsKICAgIH0KICAgIC8vIHJvdW5kIDMKICAgIGZvcig7IGkgPCA2MDsgKytpKSB7CiAgICAgIHQgPSAod1tpIC0gNl0gXiB3W2kgLSAxNl0gXiB3W2kgLSAyOF0gXiB3W2kgLSAzMl0pOwogICAgICB0ID0gKHQgPDwgMikgfCAodCA+Pj4gMzApOwogICAgICB3W2ldID0gdDsKICAgICAgZiA9IChiICYgYykgfCAoZCAmIChiIF4gYykpOwogICAgICB0ID0gKChhIDw8IDUpIHwgKGEgPj4+IDI3KSkgKyBmICsgZSArIDB4OEYxQkJDREMgKyB0OwogICAgICBlID0gZDsKICAgICAgZCA9IGM7CiAgICAgIGMgPSAoYiA8PCAzMCkgfCAoYiA+Pj4gMik7CiAgICAgIGIgPSBhOwogICAgICBhID0gdDsKICAgIH0KICAgIC8vIHJvdW5kIDQKICAgIGZvcig7IGkgPCA4MDsgKytpKSB7CiAgICAgIHQgPSAod1tpIC0gNl0gXiB3W2kgLSAxNl0gXiB3W2kgLSAyOF0gXiB3W2kgLSAzMl0pOwogICAgICB0ID0gKHQgPDwgMikgfCAodCA+Pj4gMzApOwogICAgICB3W2ldID0gdDsKICAgICAgZiA9IGIgXiBjIF4gZDsKICAgICAgdCA9ICgoYSA8PCA1KSB8IChhID4+PiAyNykpICsgZiArIGUgKyAweENBNjJDMUQ2ICsgdDsKICAgICAgZSA9IGQ7CiAgICAgIGQgPSBjOwogICAgICBjID0gKGIgPDwgMzApIHwgKGIgPj4+IDIpOwogICAgICBiID0gYTsKICAgICAgYSA9IHQ7CiAgICB9CgogICAgLy8gdXBkYXRlIGhhc2ggc3RhdGUKICAgIHMuaDAgPSAocy5oMCArIGEpIHwgMDsKICAgIHMuaDEgPSAocy5oMSArIGIpIHwgMDsKICAgIHMuaDIgPSAocy5oMiArIGMpIHwgMDsKICAgIHMuaDMgPSAocy5oMyArIGQpIHwgMDsKICAgIHMuaDQgPSAocy5oNCArIGUpIHwgMDsKCiAgICBsZW4gLT0gNjQ7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdzaGExJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3NoYTEnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFNlY3VyZSBIYXNoIEFsZ29yaXRobSB3aXRoIDI1Ni1iaXQgZGlnZXN0IChTSEEtMjU2KSBpbXBsZW1lbnRhdGlvbi4KICoKICogU2VlIEZJUFMgMTgwLTIgZm9yIGRldGFpbHMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDE1IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKdmFyIHNoYTI1NiA9IGZvcmdlLnNoYTI1NiA9IGZvcmdlLnNoYTI1NiB8fCB7fTsKZm9yZ2UubWQgPSBmb3JnZS5tZCB8fCB7fTsKZm9yZ2UubWQuYWxnb3JpdGhtcyA9IGZvcmdlLm1kLmFsZ29yaXRobXMgfHwge307CmZvcmdlLm1kLnNoYTI1NiA9IGZvcmdlLm1kLmFsZ29yaXRobXMuc2hhMjU2ID0gc2hhMjU2OwoKLyoqCiAqIENyZWF0ZXMgYSBTSEEtMjU2IG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICoKICogQHJldHVybiBhIG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICovCnNoYTI1Ni5jcmVhdGUgPSBmdW5jdGlvbigpIHsKICAvLyBkbyBpbml0aWFsaXphdGlvbiBhcyBuZWNlc3NhcnkKICBpZighX2luaXRpYWxpemVkKSB7CiAgICBfaW5pdCgpOwogIH0KCiAgLy8gU0hBLTI1NiBzdGF0ZSBjb250YWlucyBlaWdodCAzMi1iaXQgaW50ZWdlcnMKICB2YXIgX3N0YXRlID0gbnVsbDsKCiAgLy8gaW5wdXQgYnVmZmVyCiAgdmFyIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIHVzZWQgZm9yIHdvcmQgc3RvcmFnZQogIHZhciBfdyA9IG5ldyBBcnJheSg2NCk7CgogIC8vIG1lc3NhZ2UgZGlnZXN0IG9iamVjdAogIHZhciBtZCA9IHsKICAgIGFsZ29yaXRobTogJ3NoYTI1NicsCiAgICBibG9ja0xlbmd0aDogNjQsCiAgICBkaWdlc3RMZW5ndGg6IDMyLAogICAgLy8gNTYtYml0IGxlbmd0aCBvZiBtZXNzYWdlIHNvIGZhciAoZG9lcyBub3QgaW5jbHVkaW5nIHBhZGRpbmcpCiAgICBtZXNzYWdlTGVuZ3RoOiAwLAogICAgLy8gdHJ1ZSBtZXNzYWdlIGxlbmd0aAogICAgZnVsbE1lc3NhZ2VMZW5ndGg6IG51bGwsCiAgICAvLyBzaXplIG9mIG1lc3NhZ2UgbGVuZ3RoIGluIGJ5dGVzCiAgICBtZXNzYWdlTGVuZ3RoU2l6ZTogOAogIH07CgogIC8qKgogICAqIFN0YXJ0cyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQuc3RhcnQgPSBmdW5jdGlvbigpIHsKICAgIC8vIHVwIHRvIDU2LWJpdCBtZXNzYWdlIGxlbmd0aCBmb3IgY29udmVuaWVuY2UKICAgIG1kLm1lc3NhZ2VMZW5ndGggPSAwOwoKICAgIC8vIGZ1bGwgbWVzc2FnZSBsZW5ndGggKHNldCBtZC5tZXNzYWdlTGVuZ3RoNjQgZm9yIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5KQogICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGggPSBtZC5tZXNzYWdlTGVuZ3RoNjQgPSBbXTsKICAgIHZhciBpbnQzMnMgPSBtZC5tZXNzYWdlTGVuZ3RoU2l6ZSAvIDQ7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgaW50MzJzOyArK2kpIHsKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGgucHVzaCgwKTsKICAgIH0KICAgIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBfc3RhdGUgPSB7CiAgICAgIGgwOiAweDZBMDlFNjY3LAogICAgICBoMTogMHhCQjY3QUU4NSwKICAgICAgaDI6IDB4M0M2RUYzNzIsCiAgICAgIGgzOiAweEE1NEZGNTNBLAogICAgICBoNDogMHg1MTBFNTI3RiwKICAgICAgaDU6IDB4OUIwNTY4OEMsCiAgICAgIGg2OiAweDFGODNEOUFCLAogICAgICBoNzogMHg1QkUwQ0QxOQogICAgfTsKICAgIHJldHVybiBtZDsKICB9OwogIC8vIHN0YXJ0IGRpZ2VzdCBhdXRvbWF0aWNhbGx5IGZvciBmaXJzdCB0aW1lCiAgbWQuc3RhcnQoKTsKCiAgLyoqCiAgICogVXBkYXRlcyB0aGUgZGlnZXN0IHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UgaW5wdXQuIFRoZSBnaXZlbiBpbnB1dCBjYW4KICAgKiB0cmVhdGVkIGFzIHJhdyBpbnB1dCAobm8gZW5jb2Rpbmcgd2lsbCBiZSBhcHBsaWVkKSBvciBhbiBlbmNvZGluZyBvZgogICAqICd1dGY4JyBtYXliZSBnaXZlbiB0byBlbmNvZGUgdGhlIGlucHV0IHVzaW5nIFVURi04LgogICAqCiAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSBpbnB1dCB0byB1cGRhdGUgd2l0aC4KICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIHVzZSAoZGVmYXVsdDogJ3JhdycsIG90aGVyOiAndXRmOCcpLgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQudXBkYXRlID0gZnVuY3Rpb24obXNnLCBlbmNvZGluZykgewogICAgaWYoZW5jb2RpbmcgPT09ICd1dGY4JykgewogICAgICBtc2cgPSBmb3JnZS51dGlsLmVuY29kZVV0ZjgobXNnKTsKICAgIH0KCiAgICAvLyB1cGRhdGUgbWVzc2FnZSBsZW5ndGgKICAgIHZhciBsZW4gPSBtc2cubGVuZ3RoOwogICAgbWQubWVzc2FnZUxlbmd0aCArPSBsZW47CiAgICBsZW4gPSBbKGxlbiAvIDB4MTAwMDAwMDAwKSA+Pj4gMCwgbGVuID4+PiAwXTsKICAgIGZvcih2YXIgaSA9IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldICs9IGxlblsxXTsKICAgICAgbGVuWzFdID0gbGVuWzBdICsgKChtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSAvIDB4MTAwMDAwMDAwKSA+Pj4gMCk7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gPj4+IDA7CiAgICAgIGxlblswXSA9ICgobGVuWzFdIC8gMHgxMDAwMDAwMDApID4+PiAwKTsKICAgIH0KCiAgICAvLyBhZGQgYnl0ZXMgdG8gaW5wdXQgYnVmZmVyCiAgICBfaW5wdXQucHV0Qnl0ZXMobXNnKTsKCiAgICAvLyBwcm9jZXNzIGJ5dGVzCiAgICBfdXBkYXRlKF9zdGF0ZSwgX3csIF9pbnB1dCk7CgogICAgLy8gY29tcGFjdCBpbnB1dCBidWZmZXIgZXZlcnkgMksgb3IgaWYgZW1wdHkKICAgIGlmKF9pbnB1dC5yZWFkID4gMjA0OCB8fCBfaW5wdXQubGVuZ3RoKCkgPT09IDApIHsKICAgICAgX2lucHV0LmNvbXBhY3QoKTsKICAgIH0KCiAgICByZXR1cm4gbWQ7CiAgfTsKCiAgLyoqCiAgICogUHJvZHVjZXMgdGhlIGRpZ2VzdC4KICAgKgogICAqIEByZXR1cm4gYSBieXRlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBkaWdlc3QgdmFsdWUuCiAgICovCiAgbWQuZGlnZXN0ID0gZnVuY3Rpb24oKSB7CiAgICAvKiBOb3RlOiBIZXJlIHdlIGNvcHkgdGhlIHJlbWFpbmluZyBieXRlcyBpbiB0aGUgaW5wdXQgYnVmZmVyIGFuZAogICAgYWRkIHRoZSBhcHByb3ByaWF0ZSBTSEEtMjU2IHBhZGRpbmcuIFRoZW4gd2UgZG8gdGhlIGZpbmFsIHVwZGF0ZQogICAgb24gYSBjb3B5IG9mIHRoZSBzdGF0ZSBzbyB0aGF0IGlmIHRoZSB1c2VyIHdhbnRzIHRvIGdldAogICAgaW50ZXJtZWRpYXRlIGRpZ2VzdHMgdGhleSBjYW4gZG8gc28uICovCgogICAgLyogRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBtdXN0IGJlIGFkZGVkIHRvIHRoZSBtZXNzYWdlCiAgICB0byBlbnN1cmUgaXRzIGxlbmd0aCBpcyBjb25ncnVlbnQgdG8gNDQ4IG1vZCA1MTIuIEluIG90aGVyIHdvcmRzLAogICAgdGhlIGRhdGEgdG8gYmUgZGlnZXN0ZWQgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDUxMiBiaXRzIChvciAxMjggYnl0ZXMpLgogICAgVGhpcyBkYXRhIGluY2x1ZGVzIHRoZSBtZXNzYWdlLCBzb21lIHBhZGRpbmcsIGFuZCB0aGUgbGVuZ3RoIG9mIHRoZQogICAgbWVzc2FnZS4gU2luY2UgdGhlIGxlbmd0aCBvZiB0aGUgbWVzc2FnZSB3aWxsIGJlIGVuY29kZWQgYXMgOCBieXRlcyAoNjQKICAgIGJpdHMpLCB0aGF0IG1lYW5zIHRoYXQgdGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgZGF0YSBtdXN0IGhhdmUgNTYgYnl0ZXMKICAgICg0NDggYml0cykgb2YgbWVzc2FnZSBhbmQgcGFkZGluZy4gVGhlcmVmb3JlLCB0aGUgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlCiAgICBwbHVzIHRoZSBwYWRkaW5nIG11c3QgYmUgY29uZ3J1ZW50IHRvIDQ0OCBtb2QgNTEyIGJlY2F1c2UKICAgIDUxMiAtIDEyOCA9IDQ0OC4KCiAgICBJbiBvcmRlciB0byBmaWxsIHVwIHRoZSBtZXNzYWdlIGxlbmd0aCBpdCBtdXN0IGJlIGZpbGxlZCB3aXRoCiAgICBwYWRkaW5nIHRoYXQgYmVnaW5zIHdpdGggMSBiaXQgZm9sbG93ZWQgYnkgYWxsIDAgYml0cy4gUGFkZGluZwogICAgbXVzdCAqYWx3YXlzKiBiZSBwcmVzZW50LCBzbyBpZiB0aGUgbWVzc2FnZSBsZW5ndGggaXMgYWxyZWFkeQogICAgY29uZ3J1ZW50IHRvIDQ0OCBtb2QgNTEyLCB0aGVuIDUxMiBwYWRkaW5nIGJpdHMgbXVzdCBiZSBhZGRlZC4gKi8KCiAgICB2YXIgZmluYWxCbG9jayA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBmaW5hbEJsb2NrLnB1dEJ5dGVzKF9pbnB1dC5ieXRlcygpKTsKCiAgICAvLyBjb21wdXRlIHJlbWFpbmluZyBzaXplIHRvIGJlIGRpZ2VzdGVkIChpbmNsdWRlIG1lc3NhZ2UgbGVuZ3RoIHNpemUpCiAgICB2YXIgcmVtYWluaW5nID0gKAogICAgICBtZC5mdWxsTWVzc2FnZUxlbmd0aFttZC5mdWxsTWVzc2FnZUxlbmd0aC5sZW5ndGggLSAxXSArCiAgICAgIG1kLm1lc3NhZ2VMZW5ndGhTaXplKTsKCiAgICAvLyBhZGQgcGFkZGluZyBmb3Igb3ZlcmZsb3cgYmxvY2tTaXplIC0gb3ZlcmZsb3cKICAgIC8vIF9wYWRkaW5nIHN0YXJ0cyB3aXRoIDEgYnl0ZSB3aXRoIGZpcnN0IGJpdCBpcyBzZXQgKGJ5dGUgdmFsdWUgMTI4KSwgdGhlbgogICAgLy8gdGhlcmUgbWF5IGJlIHVwIHRvIChibG9ja1NpemUgLSAxKSBvdGhlciBwYWQgYnl0ZXMKICAgIHZhciBvdmVyZmxvdyA9IHJlbWFpbmluZyAmIChtZC5ibG9ja0xlbmd0aCAtIDEpOwogICAgZmluYWxCbG9jay5wdXRCeXRlcyhfcGFkZGluZy5zdWJzdHIoMCwgbWQuYmxvY2tMZW5ndGggLSBvdmVyZmxvdykpOwoKICAgIC8vIHNlcmlhbGl6ZSBtZXNzYWdlIGxlbmd0aCBpbiBiaXRzIGluIGJpZy1lbmRpYW4gb3JkZXI7IHNpbmNlIGxlbmd0aAogICAgLy8gaXMgc3RvcmVkIGluIGJ5dGVzIHdlIG11bHRpcGx5IGJ5IDggYW5kIGFkZCBjYXJyeSBmcm9tIG5leHQgaW50CiAgICB2YXIgbWVzc2FnZUxlbmd0aCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICB2YXIgbmV4dCwgY2Fycnk7CiAgICB2YXIgYml0cyA9IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoWzBdICogODsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtZC5mdWxsTWVzc2FnZUxlbmd0aC5sZW5ndGg7ICsraSkgewogICAgICBuZXh0ID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaSArIDFdICogODsKICAgICAgY2FycnkgPSAobmV4dCAvIDB4MTAwMDAwMDAwKSA+Pj4gMDsKICAgICAgYml0cyArPSBjYXJyeTsKICAgICAgZmluYWxCbG9jay5wdXRJbnQzMihiaXRzID4+PiAwKTsKICAgICAgYml0cyA9IG5leHQ7CiAgICB9CgogICAgdmFyIHMyID0gewogICAgICBoMDogX3N0YXRlLmgwLAogICAgICBoMTogX3N0YXRlLmgxLAogICAgICBoMjogX3N0YXRlLmgyLAogICAgICBoMzogX3N0YXRlLmgzLAogICAgICBoNDogX3N0YXRlLmg0LAogICAgICBoNTogX3N0YXRlLmg1LAogICAgICBoNjogX3N0YXRlLmg2LAogICAgICBoNzogX3N0YXRlLmg3CiAgICB9OwogICAgX3VwZGF0ZShzMiwgX3csIGZpbmFsQmxvY2spOwogICAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgcnZhbC5wdXRJbnQzMihzMi5oMCk7CiAgICBydmFsLnB1dEludDMyKHMyLmgxKTsKICAgIHJ2YWwucHV0SW50MzIoczIuaDIpOwogICAgcnZhbC5wdXRJbnQzMihzMi5oMyk7CiAgICBydmFsLnB1dEludDMyKHMyLmg0KTsKICAgIHJ2YWwucHV0SW50MzIoczIuaDUpOwogICAgcnZhbC5wdXRJbnQzMihzMi5oNik7CiAgICBydmFsLnB1dEludDMyKHMyLmg3KTsKICAgIHJldHVybiBydmFsOwogIH07CgogIHJldHVybiBtZDsKfTsKCi8vIHNoYS0yNTYgcGFkZGluZyBieXRlcyBub3QgaW5pdGlhbGl6ZWQgeWV0CnZhciBfcGFkZGluZyA9IG51bGw7CnZhciBfaW5pdGlhbGl6ZWQgPSBmYWxzZTsKCi8vIHRhYmxlIG9mIGNvbnN0YW50cwp2YXIgX2sgPSBudWxsOwoKLyoqCiAqIEluaXRpYWxpemVzIHRoZSBjb25zdGFudCB0YWJsZXMuCiAqLwpmdW5jdGlvbiBfaW5pdCgpIHsKICAvLyBjcmVhdGUgcGFkZGluZwogIF9wYWRkaW5nID0gU3RyaW5nLmZyb21DaGFyQ29kZSgxMjgpOwogIF9wYWRkaW5nICs9IGZvcmdlLnV0aWwuZmlsbFN0cmluZyhTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDApLCA2NCk7CgogIC8vIGNyZWF0ZSBLIHRhYmxlIGZvciBTSEEtMjU2CiAgX2sgPSBbCiAgICAweDQyOGEyZjk4LCAweDcxMzc0NDkxLCAweGI1YzBmYmNmLCAweGU5YjVkYmE1LAogICAgMHgzOTU2YzI1YiwgMHg1OWYxMTFmMSwgMHg5MjNmODJhNCwgMHhhYjFjNWVkNSwKICAgIDB4ZDgwN2FhOTgsIDB4MTI4MzViMDEsIDB4MjQzMTg1YmUsIDB4NTUwYzdkYzMsCiAgICAweDcyYmU1ZDc0LCAweDgwZGViMWZlLCAweDliZGMwNmE3LCAweGMxOWJmMTc0LAogICAgMHhlNDliNjljMSwgMHhlZmJlNDc4NiwgMHgwZmMxOWRjNiwgMHgyNDBjYTFjYywKICAgIDB4MmRlOTJjNmYsIDB4NGE3NDg0YWEsIDB4NWNiMGE5ZGMsIDB4NzZmOTg4ZGEsCiAgICAweDk4M2U1MTUyLCAweGE4MzFjNjZkLCAweGIwMDMyN2M4LCAweGJmNTk3ZmM3LAogICAgMHhjNmUwMGJmMywgMHhkNWE3OTE0NywgMHgwNmNhNjM1MSwgMHgxNDI5Mjk2NywKICAgIDB4MjdiNzBhODUsIDB4MmUxYjIxMzgsIDB4NGQyYzZkZmMsIDB4NTMzODBkMTMsCiAgICAweDY1MGE3MzU0LCAweDc2NmEwYWJiLCAweDgxYzJjOTJlLCAweDkyNzIyYzg1LAogICAgMHhhMmJmZThhMSwgMHhhODFhNjY0YiwgMHhjMjRiOGI3MCwgMHhjNzZjNTFhMywKICAgIDB4ZDE5MmU4MTksIDB4ZDY5OTA2MjQsIDB4ZjQwZTM1ODUsIDB4MTA2YWEwNzAsCiAgICAweDE5YTRjMTE2LCAweDFlMzc2YzA4LCAweDI3NDg3NzRjLCAweDM0YjBiY2I1LAogICAgMHgzOTFjMGNiMywgMHg0ZWQ4YWE0YSwgMHg1YjljY2E0ZiwgMHg2ODJlNmZmMywKICAgIDB4NzQ4ZjgyZWUsIDB4NzhhNTYzNmYsIDB4ODRjODc4MTQsIDB4OGNjNzAyMDgsCiAgICAweDkwYmVmZmZhLCAweGE0NTA2Y2ViLCAweGJlZjlhM2Y3LCAweGM2NzE3OGYyXTsKCiAgLy8gbm93IGluaXRpYWxpemVkCiAgX2luaXRpYWxpemVkID0gdHJ1ZTsKfQoKLyoqCiAqIFVwZGF0ZXMgYSBTSEEtMjU2IHN0YXRlIHdpdGggdGhlIGdpdmVuIGJ5dGUgYnVmZmVyLgogKgogKiBAcGFyYW0gcyB0aGUgU0hBLTI1NiBzdGF0ZSB0byB1cGRhdGUuCiAqIEBwYXJhbSB3IHRoZSBhcnJheSB0byB1c2UgdG8gc3RvcmUgd29yZHMuCiAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZSBidWZmZXIgdG8gdXBkYXRlIHdpdGguCiAqLwpmdW5jdGlvbiBfdXBkYXRlKHMsIHcsIGJ5dGVzKSB7CiAgLy8gY29uc3VtZSA1MTIgYml0ICg2NCBieXRlKSBjaHVua3MKICB2YXIgdDEsIHQyLCBzMCwgczEsIGNoLCBtYWosIGksIGEsIGIsIGMsIGQsIGUsIGYsIGcsIGg7CiAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aCgpOwogIHdoaWxlKGxlbiA+PSA2NCkgewogICAgLy8gdGhlIHcgYXJyYXkgd2lsbCBiZSBwb3B1bGF0ZWQgd2l0aCBzaXh0ZWVuIDMyLWJpdCBiaWctZW5kaWFuIHdvcmRzCiAgICAvLyBhbmQgdGhlbiBleHRlbmRlZCBpbnRvIDY0IDMyLWJpdCB3b3JkcyBhY2NvcmRpbmcgdG8gU0hBLTI1NgogICAgZm9yKGkgPSAwOyBpIDwgMTY7ICsraSkgewogICAgICB3W2ldID0gYnl0ZXMuZ2V0SW50MzIoKTsKICAgIH0KICAgIGZvcig7IGkgPCA2NDsgKytpKSB7CiAgICAgIC8vIFhPUiB3b3JkIDIgd29yZHMgYWdvIHJvdCByaWdodCAxNywgcm90IHJpZ2h0IDE5LCBzaGZ0IHJpZ2h0IDEwCiAgICAgIHQxID0gd1tpIC0gMl07CiAgICAgIHQxID0KICAgICAgICAoKHQxID4+PiAxNykgfCAodDEgPDwgMTUpKSBeCiAgICAgICAgKCh0MSA+Pj4gMTkpIHwgKHQxIDw8IDEzKSkgXgogICAgICAgICh0MSA+Pj4gMTApOwogICAgICAvLyBYT1Igd29yZCAxNSB3b3JkcyBhZ28gcm90IHJpZ2h0IDcsIHJvdCByaWdodCAxOCwgc2hmdCByaWdodCAzCiAgICAgIHQyID0gd1tpIC0gMTVdOwogICAgICB0MiA9CiAgICAgICAgKCh0MiA+Pj4gNykgfCAodDIgPDwgMjUpKSBeCiAgICAgICAgKCh0MiA+Pj4gMTgpIHwgKHQyIDw8IDE0KSkgXgogICAgICAgICh0MiA+Pj4gMyk7CiAgICAgIC8vIHN1bSh0MSwgd29yZCA3IGFnbywgdDIsIHdvcmQgMTYgYWdvKSBtb2R1bG8gMl4zMgogICAgICB3W2ldID0gKHQxICsgd1tpIC0gN10gKyB0MiArIHdbaSAtIDE2XSkgfCAwOwogICAgfQoKICAgIC8vIGluaXRpYWxpemUgaGFzaCB2YWx1ZSBmb3IgdGhpcyBjaHVuawogICAgYSA9IHMuaDA7CiAgICBiID0gcy5oMTsKICAgIGMgPSBzLmgyOwogICAgZCA9IHMuaDM7CiAgICBlID0gcy5oNDsKICAgIGYgPSBzLmg1OwogICAgZyA9IHMuaDY7CiAgICBoID0gcy5oNzsKCiAgICAvLyByb3VuZCBmdW5jdGlvbgogICAgZm9yKGkgPSAwOyBpIDwgNjQ7ICsraSkgewogICAgICAvLyBTdW0xKGUpCiAgICAgIHMxID0KICAgICAgICAoKGUgPj4+IDYpIHwgKGUgPDwgMjYpKSBeCiAgICAgICAgKChlID4+PiAxMSkgfCAoZSA8PCAyMSkpIF4KICAgICAgICAoKGUgPj4+IDI1KSB8IChlIDw8IDcpKTsKICAgICAgLy8gQ2goZSwgZiwgZykgKG9wdGltaXplZCB0aGUgc2FtZSB3YXkgYXMgU0hBLTEpCiAgICAgIGNoID0gZyBeIChlICYgKGYgXiBnKSk7CiAgICAgIC8vIFN1bTAoYSkKICAgICAgczAgPQogICAgICAgICgoYSA+Pj4gMikgfCAoYSA8PCAzMCkpIF4KICAgICAgICAoKGEgPj4+IDEzKSB8IChhIDw8IDE5KSkgXgogICAgICAgICgoYSA+Pj4gMjIpIHwgKGEgPDwgMTApKTsKICAgICAgLy8gTWFqKGEsIGIsIGMpIChvcHRpbWl6ZWQgdGhlIHNhbWUgd2F5IGFzIFNIQS0xKQogICAgICBtYWogPSAoYSAmIGIpIHwgKGMgJiAoYSBeIGIpKTsKCiAgICAgIC8vIG1haW4gYWxnb3JpdGhtCiAgICAgIHQxID0gaCArIHMxICsgY2ggKyBfa1tpXSArIHdbaV07CiAgICAgIHQyID0gczAgKyBtYWo7CiAgICAgIGggPSBnOwogICAgICBnID0gZjsKICAgICAgZiA9IGU7CiAgICAgIGUgPSAoZCArIHQxKSB8IDA7CiAgICAgIGQgPSBjOwogICAgICBjID0gYjsKICAgICAgYiA9IGE7CiAgICAgIGEgPSAodDEgKyB0MikgfCAwOwogICAgfQoKICAgIC8vIHVwZGF0ZSBoYXNoIHN0YXRlCiAgICBzLmgwID0gKHMuaDAgKyBhKSB8IDA7CiAgICBzLmgxID0gKHMuaDEgKyBiKSB8IDA7CiAgICBzLmgyID0gKHMuaDIgKyBjKSB8IDA7CiAgICBzLmgzID0gKHMuaDMgKyBkKSB8IDA7CiAgICBzLmg0ID0gKHMuaDQgKyBlKSB8IDA7CiAgICBzLmg1ID0gKHMuaDUgKyBmKSB8IDA7CiAgICBzLmg2ID0gKHMuaDYgKyBnKSB8IDA7CiAgICBzLmg3ID0gKHMuaDcgKyBoKSB8IDA7CiAgICBsZW4gLT0gNjQ7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdzaGEyNTYnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvc2hhMjU2JyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBTZWN1cmUgSGFzaCBBbGdvcml0aG0gd2l0aCBhIDEwMjQtYml0IGJsb2NrIHNpemUgaW1wbGVtZW50YXRpb24uCiAqCiAqIFRoaXMgaW5jbHVkZXM6IFNIQS01MTIsIFNIQS0zODQsIFNIQS01MTIvMjI0LCBhbmQgU0hBLTUxMi8yNTYuIEZvcgogKiBTSEEtMjU2IChibG9jayBzaXplIDUxMiBiaXRzKSwgc2VlIHNoYTI1Ni5qcy4KICoKICogU2VlIEZJUFMgMTgwLTQgZm9yIGRldGFpbHMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxNC0yMDE1IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKdmFyIHNoYTUxMiA9IGZvcmdlLnNoYTUxMiA9IGZvcmdlLnNoYTUxMiB8fCB7fTsKZm9yZ2UubWQgPSBmb3JnZS5tZCB8fCB7fTsKZm9yZ2UubWQuYWxnb3JpdGhtcyA9IGZvcmdlLm1kLmFsZ29yaXRobXMgfHwge307CgovLyBTSEEtNTEyCmZvcmdlLm1kLnNoYTUxMiA9IGZvcmdlLm1kLmFsZ29yaXRobXMuc2hhNTEyID0gc2hhNTEyOwoKLy8gU0hBLTM4NAp2YXIgc2hhMzg0ID0gZm9yZ2Uuc2hhMzg0ID0gZm9yZ2Uuc2hhNTEyLnNoYTM4NCA9IGZvcmdlLnNoYTUxMi5zaGEzODQgfHwge307CnNoYTM4NC5jcmVhdGUgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gc2hhNTEyLmNyZWF0ZSgnU0hBLTM4NCcpOwp9Owpmb3JnZS5tZC5zaGEzODQgPSBmb3JnZS5tZC5hbGdvcml0aG1zLnNoYTM4NCA9IHNoYTM4NDsKCi8vIFNIQS01MTIvMjU2CmZvcmdlLnNoYTUxMi5zaGEyNTYgPSBmb3JnZS5zaGE1MTIuc2hhMjU2IHx8IHsKICBjcmVhdGU6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHNoYTUxMi5jcmVhdGUoJ1NIQS01MTIvMjU2Jyk7CiAgfQp9Owpmb3JnZS5tZFsnc2hhNTEyLzI1NiddID0gZm9yZ2UubWQuYWxnb3JpdGhtc1snc2hhNTEyLzI1NiddID0KICBmb3JnZS5zaGE1MTIuc2hhMjU2OwoKLy8gU0hBLTUxMi8yMjQKZm9yZ2Uuc2hhNTEyLnNoYTIyNCA9IGZvcmdlLnNoYTUxMi5zaGEyMjQgfHwgewogIGNyZWF0ZTogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gc2hhNTEyLmNyZWF0ZSgnU0hBLTUxMi8yMjQnKTsKICB9Cn07CmZvcmdlLm1kWydzaGE1MTIvMjI0J10gPSBmb3JnZS5tZC5hbGdvcml0aG1zWydzaGE1MTIvMjI0J10gPQogIGZvcmdlLnNoYTUxMi5zaGEyMjQ7CgovKioKICogQ3JlYXRlcyBhIFNIQS0yIG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICoKICogQHBhcmFtIGFsZ29yaXRobSB0aGUgYWxnb3JpdGhtIHRvIHVzZSAoU0hBLTUxMiwgU0hBLTM4NCwgU0hBLTUxMi8yMjQsCiAqICAgICAgICAgIFNIQS01MTIvMjU2KS4KICoKICogQHJldHVybiBhIG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICovCnNoYTUxMi5jcmVhdGUgPSBmdW5jdGlvbihhbGdvcml0aG0pIHsKICAvLyBkbyBpbml0aWFsaXphdGlvbiBhcyBuZWNlc3NhcnkKICBpZighX2luaXRpYWxpemVkKSB7CiAgICBfaW5pdCgpOwogIH0KCiAgaWYodHlwZW9mIGFsZ29yaXRobSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIGFsZ29yaXRobSA9ICdTSEEtNTEyJzsKICB9CgogIGlmKCEoYWxnb3JpdGhtIGluIF9zdGF0ZXMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgU0hBLTUxMiBhbGdvcml0aG06ICcgKyBhbGdvcml0aG0pOwogIH0KCiAgLy8gU0hBLTUxMiBzdGF0ZSBjb250YWlucyBlaWdodCA2NC1iaXQgaW50ZWdlcnMgKGVhY2ggYXMgdHdvIDMyLWJpdCBpbnRzKQogIHZhciBfc3RhdGUgPSBfc3RhdGVzW2FsZ29yaXRobV07CiAgdmFyIF9oID0gbnVsbDsKCiAgLy8gaW5wdXQgYnVmZmVyCiAgdmFyIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIHVzZWQgZm9yIDY0LWJpdCB3b3JkIHN0b3JhZ2UKICB2YXIgX3cgPSBuZXcgQXJyYXkoODApOwogIGZvcih2YXIgd2kgPSAwOyB3aSA8IDgwOyArK3dpKSB7CiAgICBfd1t3aV0gPSBuZXcgQXJyYXkoMik7CiAgfQoKICAvLyBtZXNzYWdlIGRpZ2VzdCBvYmplY3QKICB2YXIgbWQgPSB7CiAgICAvLyBTSEEtNTEyID0+IHNoYTUxMgogICAgYWxnb3JpdGhtOiBhbGdvcml0aG0ucmVwbGFjZSgnLScsICcnKS50b0xvd2VyQ2FzZSgpLAogICAgYmxvY2tMZW5ndGg6IDEyOCwKICAgIGRpZ2VzdExlbmd0aDogNjQsCiAgICAvLyA1Ni1iaXQgbGVuZ3RoIG9mIG1lc3NhZ2Ugc28gZmFyIChkb2VzIG5vdCBpbmNsdWRpbmcgcGFkZGluZykKICAgIG1lc3NhZ2VMZW5ndGg6IDAsCiAgICAvLyB0cnVlIG1lc3NhZ2UgbGVuZ3RoCiAgICBmdWxsTWVzc2FnZUxlbmd0aDogbnVsbCwKICAgIC8vIHNpemUgb2YgbWVzc2FnZSBsZW5ndGggaW4gYnl0ZXMKICAgIG1lc3NhZ2VMZW5ndGhTaXplOiAxNgogIH07CgogIC8qKgogICAqIFN0YXJ0cyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQuc3RhcnQgPSBmdW5jdGlvbigpIHsKICAgIC8vIHVwIHRvIDU2LWJpdCBtZXNzYWdlIGxlbmd0aCBmb3IgY29udmVuaWVuY2UKICAgIG1kLm1lc3NhZ2VMZW5ndGggPSAwOwoKICAgIC8vIGZ1bGwgbWVzc2FnZSBsZW5ndGggKHNldCBtZC5tZXNzYWdlTGVuZ3RoMTI4IGZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSkKICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoID0gbWQubWVzc2FnZUxlbmd0aDEyOCA9IFtdOwogICAgdmFyIGludDMycyA9IG1kLm1lc3NhZ2VMZW5ndGhTaXplIC8gNDsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBpbnQzMnM7ICsraSkgewogICAgICBtZC5mdWxsTWVzc2FnZUxlbmd0aC5wdXNoKDApOwogICAgfQogICAgX2lucHV0ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIF9oID0gbmV3IEFycmF5KF9zdGF0ZS5sZW5ndGgpOwogICAgZm9yKHZhciBpID0gMDsgaSA8IF9zdGF0ZS5sZW5ndGg7ICsraSkgewogICAgICBfaFtpXSA9IF9zdGF0ZVtpXS5zbGljZSgwKTsKICAgIH0KICAgIHJldHVybiBtZDsKICB9OwogIC8vIHN0YXJ0IGRpZ2VzdCBhdXRvbWF0aWNhbGx5IGZvciBmaXJzdCB0aW1lCiAgbWQuc3RhcnQoKTsKCiAgLyoqCiAgICogVXBkYXRlcyB0aGUgZGlnZXN0IHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UgaW5wdXQuIFRoZSBnaXZlbiBpbnB1dCBjYW4KICAgKiB0cmVhdGVkIGFzIHJhdyBpbnB1dCAobm8gZW5jb2Rpbmcgd2lsbCBiZSBhcHBsaWVkKSBvciBhbiBlbmNvZGluZyBvZgogICAqICd1dGY4JyBtYXliZSBnaXZlbiB0byBlbmNvZGUgdGhlIGlucHV0IHVzaW5nIFVURi04LgogICAqCiAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSBpbnB1dCB0byB1cGRhdGUgd2l0aC4KICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIHVzZSAoZGVmYXVsdDogJ3JhdycsIG90aGVyOiAndXRmOCcpLgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQudXBkYXRlID0gZnVuY3Rpb24obXNnLCBlbmNvZGluZykgewogICAgaWYoZW5jb2RpbmcgPT09ICd1dGY4JykgewogICAgICBtc2cgPSBmb3JnZS51dGlsLmVuY29kZVV0ZjgobXNnKTsKICAgIH0KCiAgICAvLyB1cGRhdGUgbWVzc2FnZSBsZW5ndGgKICAgIHZhciBsZW4gPSBtc2cubGVuZ3RoOwogICAgbWQubWVzc2FnZUxlbmd0aCArPSBsZW47CiAgICBsZW4gPSBbKGxlbiAvIDB4MTAwMDAwMDAwKSA+Pj4gMCwgbGVuID4+PiAwXTsKICAgIGZvcih2YXIgaSA9IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldICs9IGxlblsxXTsKICAgICAgbGVuWzFdID0gbGVuWzBdICsgKChtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSAvIDB4MTAwMDAwMDAwKSA+Pj4gMCk7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gPj4+IDA7CiAgICAgIGxlblswXSA9ICgobGVuWzFdIC8gMHgxMDAwMDAwMDApID4+PiAwKTsKICAgIH0KCiAgICAvLyBhZGQgYnl0ZXMgdG8gaW5wdXQgYnVmZmVyCiAgICBfaW5wdXQucHV0Qnl0ZXMobXNnKTsKCiAgICAvLyBwcm9jZXNzIGJ5dGVzCiAgICBfdXBkYXRlKF9oLCBfdywgX2lucHV0KTsKCiAgICAvLyBjb21wYWN0IGlucHV0IGJ1ZmZlciBldmVyeSAySyBvciBpZiBlbXB0eQogICAgaWYoX2lucHV0LnJlYWQgPiAyMDQ4IHx8IF9pbnB1dC5sZW5ndGgoKSA9PT0gMCkgewogICAgICBfaW5wdXQuY29tcGFjdCgpOwogICAgfQoKICAgIHJldHVybiBtZDsKICB9OwoKICAvKioKICAgKiBQcm9kdWNlcyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiBhIGJ5dGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGRpZ2VzdCB2YWx1ZS4KICAgKi8KICBtZC5kaWdlc3QgPSBmdW5jdGlvbigpIHsKICAgIC8qIE5vdGU6IEhlcmUgd2UgY29weSB0aGUgcmVtYWluaW5nIGJ5dGVzIGluIHRoZSBpbnB1dCBidWZmZXIgYW5kCiAgICBhZGQgdGhlIGFwcHJvcHJpYXRlIFNIQS01MTIgcGFkZGluZy4gVGhlbiB3ZSBkbyB0aGUgZmluYWwgdXBkYXRlCiAgICBvbiBhIGNvcHkgb2YgdGhlIHN0YXRlIHNvIHRoYXQgaWYgdGhlIHVzZXIgd2FudHMgdG8gZ2V0CiAgICBpbnRlcm1lZGlhdGUgZGlnZXN0cyB0aGV5IGNhbiBkbyBzby4gKi8KCiAgICAvKiBEZXRlcm1pbmUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IG11c3QgYmUgYWRkZWQgdG8gdGhlIG1lc3NhZ2UKICAgIHRvIGVuc3VyZSBpdHMgbGVuZ3RoIGlzIGNvbmdydWVudCB0byA4OTYgbW9kIDEwMjQuIEluIG90aGVyIHdvcmRzLAogICAgdGhlIGRhdGEgdG8gYmUgZGlnZXN0ZWQgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDEwMjQgYml0cyAob3IgMTI4IGJ5dGVzKS4KICAgIFRoaXMgZGF0YSBpbmNsdWRlcyB0aGUgbWVzc2FnZSwgc29tZSBwYWRkaW5nLCBhbmQgdGhlIGxlbmd0aCBvZiB0aGUKICAgIG1lc3NhZ2UuIFNpbmNlIHRoZSBsZW5ndGggb2YgdGhlIG1lc3NhZ2Ugd2lsbCBiZSBlbmNvZGVkIGFzIDE2IGJ5dGVzICgxMjgKICAgIGJpdHMpLCB0aGF0IG1lYW5zIHRoYXQgdGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgZGF0YSBtdXN0IGhhdmUgMTEyIGJ5dGVzCiAgICAoODk2IGJpdHMpIG9mIG1lc3NhZ2UgYW5kIHBhZGRpbmcuIFRoZXJlZm9yZSwgdGhlIGxlbmd0aCBvZiB0aGUgbWVzc2FnZQogICAgcGx1cyB0aGUgcGFkZGluZyBtdXN0IGJlIGNvbmdydWVudCB0byA4OTYgbW9kIDEwMjQgYmVjYXVzZQogICAgMTAyNCAtIDEyOCA9IDg5Ni4KCiAgICBJbiBvcmRlciB0byBmaWxsIHVwIHRoZSBtZXNzYWdlIGxlbmd0aCBpdCBtdXN0IGJlIGZpbGxlZCB3aXRoCiAgICBwYWRkaW5nIHRoYXQgYmVnaW5zIHdpdGggMSBiaXQgZm9sbG93ZWQgYnkgYWxsIDAgYml0cy4gUGFkZGluZwogICAgbXVzdCAqYWx3YXlzKiBiZSBwcmVzZW50LCBzbyBpZiB0aGUgbWVzc2FnZSBsZW5ndGggaXMgYWxyZWFkeQogICAgY29uZ3J1ZW50IHRvIDg5NiBtb2QgMTAyNCwgdGhlbiAxMDI0IHBhZGRpbmcgYml0cyBtdXN0IGJlIGFkZGVkLiAqLwoKICAgIHZhciBmaW5hbEJsb2NrID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGZpbmFsQmxvY2sucHV0Qnl0ZXMoX2lucHV0LmJ5dGVzKCkpOwoKICAgIC8vIGNvbXB1dGUgcmVtYWluaW5nIHNpemUgdG8gYmUgZGlnZXN0ZWQgKGluY2x1ZGUgbWVzc2FnZSBsZW5ndGggc2l6ZSkKICAgIHZhciByZW1haW5pbmcgPSAoCiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW21kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aCAtIDFdICsKICAgICAgbWQubWVzc2FnZUxlbmd0aFNpemUpOwoKICAgIC8vIGFkZCBwYWRkaW5nIGZvciBvdmVyZmxvdyBibG9ja1NpemUgLSBvdmVyZmxvdwogICAgLy8gX3BhZGRpbmcgc3RhcnRzIHdpdGggMSBieXRlIHdpdGggZmlyc3QgYml0IGlzIHNldCAoYnl0ZSB2YWx1ZSAxMjgpLCB0aGVuCiAgICAvLyB0aGVyZSBtYXkgYmUgdXAgdG8gKGJsb2NrU2l6ZSAtIDEpIG90aGVyIHBhZCBieXRlcwogICAgdmFyIG92ZXJmbG93ID0gcmVtYWluaW5nICYgKG1kLmJsb2NrTGVuZ3RoIC0gMSk7CiAgICBmaW5hbEJsb2NrLnB1dEJ5dGVzKF9wYWRkaW5nLnN1YnN0cigwLCBtZC5ibG9ja0xlbmd0aCAtIG92ZXJmbG93KSk7CgogICAgLy8gc2VyaWFsaXplIG1lc3NhZ2UgbGVuZ3RoIGluIGJpdHMgaW4gYmlnLWVuZGlhbiBvcmRlcjsgc2luY2UgbGVuZ3RoCiAgICAvLyBpcyBzdG9yZWQgaW4gYnl0ZXMgd2UgbXVsdGlwbHkgYnkgOCBhbmQgYWRkIGNhcnJ5IGZyb20gbmV4dCBpbnQKICAgIHZhciBtZXNzYWdlTGVuZ3RoID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIHZhciBuZXh0LCBjYXJyeTsKICAgIHZhciBiaXRzID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbMF0gKiA4OwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aDsgKytpKSB7CiAgICAgIG5leHQgPSBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpICsgMV0gKiA4OwogICAgICBjYXJyeSA9IChuZXh0IC8gMHgxMDAwMDAwMDApID4+PiAwOwogICAgICBiaXRzICs9IGNhcnJ5OwogICAgICBmaW5hbEJsb2NrLnB1dEludDMyKGJpdHMgPj4+IDApOwogICAgICBiaXRzID0gbmV4dDsKICAgIH0KCiAgICB2YXIgaCA9IG5ldyBBcnJheShfaC5sZW5ndGgpOwogICAgZm9yKHZhciBpID0gMDsgaSA8IF9oLmxlbmd0aDsgKytpKSB7CiAgICAgIGhbaV0gPSBfaFtpXS5zbGljZSgwKTsKICAgIH0KICAgIF91cGRhdGUoaCwgX3csIGZpbmFsQmxvY2spOwogICAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgdmFyIGhsZW47CiAgICBpZihhbGdvcml0aG0gPT09ICdTSEEtNTEyJykgewogICAgICBobGVuID0gaC5sZW5ndGg7CiAgICB9IGVsc2UgaWYoYWxnb3JpdGhtID09PSAnU0hBLTM4NCcpIHsKICAgICAgaGxlbiA9IGgubGVuZ3RoIC0gMjsKICAgIH0gZWxzZSB7CiAgICAgIGhsZW4gPSBoLmxlbmd0aCAtIDQ7CiAgICB9CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgaGxlbjsgKytpKSB7CiAgICAgIHJ2YWwucHV0SW50MzIoaFtpXVswXSk7CiAgICAgIGlmKGkgIT09IGhsZW4gLSAxIHx8IGFsZ29yaXRobSAhPT0gJ1NIQS01MTIvMjI0JykgewogICAgICAgIHJ2YWwucHV0SW50MzIoaFtpXVsxXSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBydmFsOwogIH07CgogIHJldHVybiBtZDsKfTsKCi8vIHNoYS01MTIgcGFkZGluZyBieXRlcyBub3QgaW5pdGlhbGl6ZWQgeWV0CnZhciBfcGFkZGluZyA9IG51bGw7CnZhciBfaW5pdGlhbGl6ZWQgPSBmYWxzZTsKCi8vIHRhYmxlIG9mIGNvbnN0YW50cwp2YXIgX2sgPSBudWxsOwoKLy8gaW5pdGlhbCBoYXNoIHN0YXRlcwp2YXIgX3N0YXRlcyA9IG51bGw7CgovKioKICogSW5pdGlhbGl6ZXMgdGhlIGNvbnN0YW50IHRhYmxlcy4KICovCmZ1bmN0aW9uIF9pbml0KCkgewogIC8vIGNyZWF0ZSBwYWRkaW5nCiAgX3BhZGRpbmcgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDEyOCk7CiAgX3BhZGRpbmcgKz0gZm9yZ2UudXRpbC5maWxsU3RyaW5nKFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwMCksIDEyOCk7CgogIC8vIGNyZWF0ZSBLIHRhYmxlIGZvciBTSEEtNTEyCiAgX2sgPSBbCiAgICBbMHg0MjhhMmY5OCwgMHhkNzI4YWUyMl0sIFsweDcxMzc0NDkxLCAweDIzZWY2NWNkXSwKICAgIFsweGI1YzBmYmNmLCAweGVjNGQzYjJmXSwgWzB4ZTliNWRiYTUsIDB4ODE4OWRiYmNdLAogICAgWzB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzhdLCBbMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOV0sCiAgICBbMHg5MjNmODJhNCwgMHhhZjE5NGY5Yl0sIFsweGFiMWM1ZWQ1LCAweGRhNmQ4MTE4XSwKICAgIFsweGQ4MDdhYTk4LCAweGEzMDMwMjQyXSwgWzB4MTI4MzViMDEsIDB4NDU3MDZmYmVdLAogICAgWzB4MjQzMTg1YmUsIDB4NGVlNGIyOGNdLCBbMHg1NTBjN2RjMywgMHhkNWZmYjRlMl0sCiAgICBbMHg3MmJlNWQ3NCwgMHhmMjdiODk2Zl0sIFsweDgwZGViMWZlLCAweDNiMTY5NmIxXSwKICAgIFsweDliZGMwNmE3LCAweDI1YzcxMjM1XSwgWzB4YzE5YmYxNzQsIDB4Y2Y2OTI2OTRdLAogICAgWzB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDJdLCBbMHhlZmJlNDc4NiwgMHgzODRmMjVlM10sCiAgICBbMHgwZmMxOWRjNiwgMHg4YjhjZDViNV0sIFsweDI0MGNhMWNjLCAweDc3YWM5YzY1XSwKICAgIFsweDJkZTkyYzZmLCAweDU5MmIwMjc1XSwgWzB4NGE3NDg0YWEsIDB4NmVhNmU0ODNdLAogICAgWzB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDRdLCBbMHg3NmY5ODhkYSwgMHg4MzExNTNiNV0sCiAgICBbMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYl0sIFsweGE4MzFjNjZkLCAweDJkYjQzMjEwXSwKICAgIFsweGIwMDMyN2M4LCAweDk4ZmIyMTNmXSwgWzB4YmY1OTdmYzcsIDB4YmVlZjBlZTRdLAogICAgWzB4YzZlMDBiZjMsIDB4M2RhODhmYzJdLCBbMHhkNWE3OTE0NywgMHg5MzBhYTcyNV0sCiAgICBbMHgwNmNhNjM1MSwgMHhlMDAzODI2Zl0sIFsweDE0MjkyOTY3LCAweDBhMGU2ZTcwXSwKICAgIFsweDI3YjcwYTg1LCAweDQ2ZDIyZmZjXSwgWzB4MmUxYjIxMzgsIDB4NWMyNmM5MjZdLAogICAgWzB4NGQyYzZkZmMsIDB4NWFjNDJhZWRdLCBbMHg1MzM4MGQxMywgMHg5ZDk1YjNkZl0sCiAgICBbMHg2NTBhNzM1NCwgMHg4YmFmNjNkZV0sIFsweDc2NmEwYWJiLCAweDNjNzdiMmE4XSwKICAgIFsweDgxYzJjOTJlLCAweDQ3ZWRhZWU2XSwgWzB4OTI3MjJjODUsIDB4MTQ4MjM1M2JdLAogICAgWzB4YTJiZmU4YTEsIDB4NGNmMTAzNjRdLCBbMHhhODFhNjY0YiwgMHhiYzQyMzAwMV0sCiAgICBbMHhjMjRiOGI3MCwgMHhkMGY4OTc5MV0sIFsweGM3NmM1MWEzLCAweDA2NTRiZTMwXSwKICAgIFsweGQxOTJlODE5LCAweGQ2ZWY1MjE4XSwgWzB4ZDY5OTA2MjQsIDB4NTU2NWE5MTBdLAogICAgWzB4ZjQwZTM1ODUsIDB4NTc3MTIwMmFdLCBbMHgxMDZhYTA3MCwgMHgzMmJiZDFiOF0sCiAgICBbMHgxOWE0YzExNiwgMHhiOGQyZDBjOF0sIFsweDFlMzc2YzA4LCAweDUxNDFhYjUzXSwKICAgIFsweDI3NDg3NzRjLCAweGRmOGVlYjk5XSwgWzB4MzRiMGJjYjUsIDB4ZTE5YjQ4YThdLAogICAgWzB4MzkxYzBjYjMsIDB4YzVjOTVhNjNdLCBbMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYl0sCiAgICBbMHg1YjljY2E0ZiwgMHg3NzYzZTM3M10sIFsweDY4MmU2ZmYzLCAweGQ2YjJiOGEzXSwKICAgIFsweDc0OGY4MmVlLCAweDVkZWZiMmZjXSwgWzB4NzhhNTYzNmYsIDB4NDMxNzJmNjBdLAogICAgWzB4ODRjODc4MTQsIDB4YTFmMGFiNzJdLCBbMHg4Y2M3MDIwOCwgMHgxYTY0MzllY10sCiAgICBbMHg5MGJlZmZmYSwgMHgyMzYzMWUyOF0sIFsweGE0NTA2Y2ViLCAweGRlODJiZGU5XSwKICAgIFsweGJlZjlhM2Y3LCAweGIyYzY3OTE1XSwgWzB4YzY3MTc4ZjIsIDB4ZTM3MjUzMmJdLAogICAgWzB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWNdLCBbMHhkMTg2YjhjNywgMHgyMWMwYzIwN10sCiAgICBbMHhlYWRhN2RkNiwgMHhjZGUwZWIxZV0sIFsweGY1N2Q0ZjdmLCAweGVlNmVkMTc4XSwKICAgIFsweDA2ZjA2N2FhLCAweDcyMTc2ZmJhXSwgWzB4MGE2MzdkYzUsIDB4YTJjODk4YTZdLAogICAgWzB4MTEzZjk4MDQsIDB4YmVmOTBkYWVdLCBbMHgxYjcxMGIzNSwgMHgxMzFjNDcxYl0sCiAgICBbMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NF0sIFsweDMyY2FhYjdiLCAweDQwYzcyNDkzXSwKICAgIFsweDNjOWViZTBhLCAweDE1YzliZWJjXSwgWzB4NDMxZDY3YzQsIDB4OWMxMDBkNGNdLAogICAgWzB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjZdLCBbMHg1OTdmMjk5YywgMHhmYzY1N2UyYV0sCiAgICBbMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlY10sIFsweDZjNDQxOThjLCAweDRhNDc1ODE3XQogIF07CgogIC8vIGluaXRpYWwgaGFzaCBzdGF0ZXMKICBfc3RhdGVzID0ge307CiAgX3N0YXRlc1snU0hBLTUxMiddID0gWwogICAgWzB4NmEwOWU2NjcsIDB4ZjNiY2M5MDhdLAogICAgWzB4YmI2N2FlODUsIDB4ODRjYWE3M2JdLAogICAgWzB4M2M2ZWYzNzIsIDB4ZmU5NGY4MmJdLAogICAgWzB4YTU0ZmY1M2EsIDB4NWYxZDM2ZjFdLAogICAgWzB4NTEwZTUyN2YsIDB4YWRlNjgyZDFdLAogICAgWzB4OWIwNTY4OGMsIDB4MmIzZTZjMWZdLAogICAgWzB4MWY4M2Q5YWIsIDB4ZmI0MWJkNmJdLAogICAgWzB4NWJlMGNkMTksIDB4MTM3ZTIxNzldCiAgXTsKICBfc3RhdGVzWydTSEEtMzg0J10gPSBbCiAgICBbMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOF0sCiAgICBbMHg2MjlhMjkyYSwgMHgzNjdjZDUwN10sCiAgICBbMHg5MTU5MDE1YSwgMHgzMDcwZGQxN10sCiAgICBbMHgxNTJmZWNkOCwgMHhmNzBlNTkzOV0sCiAgICBbMHg2NzMzMjY2NywgMHhmZmMwMGIzMV0sCiAgICBbMHg4ZWI0NGE4NywgMHg2ODU4MTUxMV0sCiAgICBbMHhkYjBjMmUwZCwgMHg2NGY5OGZhN10sCiAgICBbMHg0N2I1NDgxZCwgMHhiZWZhNGZhNF0KICBdOwogIF9zdGF0ZXNbJ1NIQS01MTIvMjU2J10gPSBbCiAgICBbMHgyMjMxMjE5NCwgMHhGQzJCRjcyQ10sCiAgICBbMHg5RjU1NUZBMywgMHhDODRDNjRDMl0sCiAgICBbMHgyMzkzQjg2QiwgMHg2RjUzQjE1MV0sCiAgICBbMHg5NjM4NzcxOSwgMHg1OTQwRUFCRF0sCiAgICBbMHg5NjI4M0VFMiwgMHhBODhFRkZFM10sCiAgICBbMHhCRTVFMUUyNSwgMHg1Mzg2Mzk5Ml0sCiAgICBbMHgyQjAxOTlGQywgMHgyQzg1QjhBQV0sCiAgICBbMHgwRUI3MkREQywgMHg4MUM1MkNBMl0KICBdOwogIF9zdGF0ZXNbJ1NIQS01MTIvMjI0J10gPSBbCiAgICBbMHg4QzNEMzdDOCwgMHgxOTU0NERBMl0sCiAgICBbMHg3M0UxOTk2NiwgMHg4OURDRDRENl0sCiAgICBbMHgxREZBQjdBRSwgMHgzMkZGOUM4Ml0sCiAgICBbMHg2NzlERDUxNCwgMHg1ODJGOUZDRl0sCiAgICBbMHgwRjZEMkI2OSwgMHg3QkQ0NERBOF0sCiAgICBbMHg3N0UzNkY3MywgMHgwNEM0ODk0Ml0sCiAgICBbMHgzRjlEODVBOCwgMHg2QTFEMzZDOF0sCiAgICBbMHgxMTEyRTZBRCwgMHg5MUQ2OTJBMV0KICBdOwoKICAvLyBub3cgaW5pdGlhbGl6ZWQKICBfaW5pdGlhbGl6ZWQgPSB0cnVlOwp9CgovKioKICogVXBkYXRlcyBhIFNIQS01MTIgc3RhdGUgd2l0aCB0aGUgZ2l2ZW4gYnl0ZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBzIHRoZSBTSEEtNTEyIHN0YXRlIHRvIHVwZGF0ZS4KICogQHBhcmFtIHcgdGhlIGFycmF5IHRvIHVzZSB0byBzdG9yZSB3b3Jkcy4KICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlIGJ1ZmZlciB0byB1cGRhdGUgd2l0aC4KICovCmZ1bmN0aW9uIF91cGRhdGUocywgdywgYnl0ZXMpIHsKICAvLyBjb25zdW1lIDUxMiBiaXQgKDEyOCBieXRlKSBjaHVua3MKICB2YXIgdDFfaGksIHQxX2xvOwogIHZhciB0Ml9oaSwgdDJfbG87CiAgdmFyIHMwX2hpLCBzMF9sbzsKICB2YXIgczFfaGksIHMxX2xvOwogIHZhciBjaF9oaSwgY2hfbG87CiAgdmFyIG1hal9oaSwgbWFqX2xvOwogIHZhciBhX2hpLCBhX2xvOwogIHZhciBiX2hpLCBiX2xvOwogIHZhciBjX2hpLCBjX2xvOwogIHZhciBkX2hpLCBkX2xvOwogIHZhciBlX2hpLCBlX2xvOwogIHZhciBmX2hpLCBmX2xvOwogIHZhciBnX2hpLCBnX2xvOwogIHZhciBoX2hpLCBoX2xvOwogIHZhciBpLCBoaSwgbG8sIHcyLCB3NywgdzE1LCB3MTY7CiAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aCgpOwogIHdoaWxlKGxlbiA+PSAxMjgpIHsKICAgIC8vIHRoZSB3IGFycmF5IHdpbGwgYmUgcG9wdWxhdGVkIHdpdGggc2l4dGVlbiA2NC1iaXQgYmlnLWVuZGlhbiB3b3JkcwogICAgLy8gYW5kIHRoZW4gZXh0ZW5kZWQgaW50byA2NCA2NC1iaXQgd29yZHMgYWNjb3JkaW5nIHRvIFNIQS01MTIKICAgIGZvcihpID0gMDsgaSA8IDE2OyArK2kpIHsKICAgICAgd1tpXVswXSA9IGJ5dGVzLmdldEludDMyKCkgPj4+IDA7CiAgICAgIHdbaV1bMV0gPSBieXRlcy5nZXRJbnQzMigpID4+PiAwOwogICAgfQogICAgZm9yKDsgaSA8IDgwOyArK2kpIHsKICAgICAgLy8gZm9yIHdvcmQgMiB3b3JkcyBhZ286IFJPVFIgMTkoeCkgXiBST1RSIDYxKHgpIF4gU0hSIDYoeCkKICAgICAgdzIgPSB3W2kgLSAyXTsKICAgICAgaGkgPSB3MlswXTsKICAgICAgbG8gPSB3MlsxXTsKCiAgICAgIC8vIGhpZ2ggYml0cwogICAgICB0MV9oaSA9ICgKICAgICAgICAoKGhpID4+PiAxOSkgfCAobG8gPDwgMTMpKSBeIC8vIFJPVFIgMTkKICAgICAgICAoKGxvID4+PiAyOSkgfCAoaGkgPDwgMykpIF4gLy8gUk9UUiA2MS8oc3dhcCArIFJPVFIgMjkpCiAgICAgICAgKGhpID4+PiA2KSkgPj4+IDA7IC8vIFNIUiA2CiAgICAgIC8vIGxvdyBiaXRzCiAgICAgIHQxX2xvID0gKAogICAgICAgICgoaGkgPDwgMTMpIHwgKGxvID4+PiAxOSkpIF4gLy8gUk9UUiAxOQogICAgICAgICgobG8gPDwgMykgfCAoaGkgPj4+IDI5KSkgXiAvLyBST1RSIDYxLyhzd2FwICsgUk9UUiAyOSkKICAgICAgICAoKGhpIDw8IDI2KSB8IChsbyA+Pj4gNikpKSA+Pj4gMDsgLy8gU0hSIDYKCiAgICAgIC8vIGZvciB3b3JkIDE1IHdvcmRzIGFnbzogUk9UUiAxKHgpIF4gUk9UUiA4KHgpIF4gU0hSIDcoeCkKICAgICAgdzE1ID0gd1tpIC0gMTVdOwogICAgICBoaSA9IHcxNVswXTsKICAgICAgbG8gPSB3MTVbMV07CgogICAgICAvLyBoaWdoIGJpdHMKICAgICAgdDJfaGkgPSAoCiAgICAgICAgKChoaSA+Pj4gMSkgfCAobG8gPDwgMzEpKSBeIC8vIFJPVFIgMQogICAgICAgICgoaGkgPj4+IDgpIHwgKGxvIDw8IDI0KSkgXiAvLyBST1RSIDgKICAgICAgICAoaGkgPj4+IDcpKSA+Pj4gMDsgLy8gU0hSIDcKICAgICAgLy8gbG93IGJpdHMKICAgICAgdDJfbG8gPSAoCiAgICAgICAgKChoaSA8PCAzMSkgfCAobG8gPj4+IDEpKSBeIC8vIFJPVFIgMQogICAgICAgICgoaGkgPDwgMjQpIHwgKGxvID4+PiA4KSkgXiAvLyBST1RSIDgKICAgICAgICAoKGhpIDw8IDI1KSB8IChsbyA+Pj4gNykpKSA+Pj4gMDsgLy8gU0hSIDcKCiAgICAgIC8vIHN1bSh0MSwgd29yZCA3IGFnbywgdDIsIHdvcmQgMTYgYWdvKSBtb2R1bG8gMl42NCAoY2FycnkgbG8gb3ZlcmZsb3cpCiAgICAgIHc3ID0gd1tpIC0gN107CiAgICAgIHcxNiA9IHdbaSAtIDE2XTsKICAgICAgbG8gPSAodDFfbG8gKyB3N1sxXSArIHQyX2xvICsgdzE2WzFdKTsKICAgICAgd1tpXVswXSA9ICh0MV9oaSArIHc3WzBdICsgdDJfaGkgKyB3MTZbMF0gKwogICAgICAgICgobG8gLyAweDEwMDAwMDAwMCkgPj4+IDApKSA+Pj4gMDsKICAgICAgd1tpXVsxXSA9IGxvID4+PiAwOwogICAgfQoKICAgIC8vIGluaXRpYWxpemUgaGFzaCB2YWx1ZSBmb3IgdGhpcyBjaHVuawogICAgYV9oaSA9IHNbMF1bMF07CiAgICBhX2xvID0gc1swXVsxXTsKICAgIGJfaGkgPSBzWzFdWzBdOwogICAgYl9sbyA9IHNbMV1bMV07CiAgICBjX2hpID0gc1syXVswXTsKICAgIGNfbG8gPSBzWzJdWzFdOwogICAgZF9oaSA9IHNbM11bMF07CiAgICBkX2xvID0gc1szXVsxXTsKICAgIGVfaGkgPSBzWzRdWzBdOwogICAgZV9sbyA9IHNbNF1bMV07CiAgICBmX2hpID0gc1s1XVswXTsKICAgIGZfbG8gPSBzWzVdWzFdOwogICAgZ19oaSA9IHNbNl1bMF07CiAgICBnX2xvID0gc1s2XVsxXTsKICAgIGhfaGkgPSBzWzddWzBdOwogICAgaF9sbyA9IHNbN11bMV07CgogICAgLy8gcm91bmQgZnVuY3Rpb24KICAgIGZvcihpID0gMDsgaSA8IDgwOyArK2kpIHsKICAgICAgLy8gU3VtMShlKSA9IFJPVFIgMTQoZSkgXiBST1RSIDE4KGUpIF4gUk9UUiA0MShlKQogICAgICBzMV9oaSA9ICgKICAgICAgICAoKGVfaGkgPj4+IDE0KSB8IChlX2xvIDw8IDE4KSkgXiAvLyBST1RSIDE0CiAgICAgICAgKChlX2hpID4+PiAxOCkgfCAoZV9sbyA8PCAxNCkpIF4gLy8gUk9UUiAxOAogICAgICAgICgoZV9sbyA+Pj4gOSkgfCAoZV9oaSA8PCAyMykpKSA+Pj4gMDsgLy8gUk9UUiA0MS8oc3dhcCArIFJPVFIgOSkKICAgICAgczFfbG8gPSAoCiAgICAgICAgKChlX2hpIDw8IDE4KSB8IChlX2xvID4+PiAxNCkpIF4gLy8gUk9UUiAxNAogICAgICAgICgoZV9oaSA8PCAxNCkgfCAoZV9sbyA+Pj4gMTgpKSBeIC8vIFJPVFIgMTgKICAgICAgICAoKGVfbG8gPDwgMjMpIHwgKGVfaGkgPj4+IDkpKSkgPj4+IDA7IC8vIFJPVFIgNDEvKHN3YXAgKyBST1RSIDkpCgogICAgICAvLyBDaChlLCBmLCBnKSAob3B0aW1pemVkIHRoZSBzYW1lIHdheSBhcyBTSEEtMSkKICAgICAgY2hfaGkgPSAoZ19oaSBeIChlX2hpICYgKGZfaGkgXiBnX2hpKSkpID4+PiAwOwogICAgICBjaF9sbyA9IChnX2xvIF4gKGVfbG8gJiAoZl9sbyBeIGdfbG8pKSkgPj4+IDA7CgogICAgICAvLyBTdW0wKGEpID0gUk9UUiAyOChhKSBeIFJPVFIgMzQoYSkgXiBST1RSIDM5KGEpCiAgICAgIHMwX2hpID0gKAogICAgICAgICgoYV9oaSA+Pj4gMjgpIHwgKGFfbG8gPDwgNCkpIF4gLy8gUk9UUiAyOAogICAgICAgICgoYV9sbyA+Pj4gMikgfCAoYV9oaSA8PCAzMCkpIF4gLy8gUk9UUiAzNC8oc3dhcCArIFJPVFIgMikKICAgICAgICAoKGFfbG8gPj4+IDcpIHwgKGFfaGkgPDwgMjUpKSkgPj4+IDA7IC8vIFJPVFIgMzkvKHN3YXAgKyBST1RSIDcpCiAgICAgIHMwX2xvID0gKAogICAgICAgICgoYV9oaSA8PCA0KSB8IChhX2xvID4+PiAyOCkpIF4gLy8gUk9UUiAyOAogICAgICAgICgoYV9sbyA8PCAzMCkgfCAoYV9oaSA+Pj4gMikpIF4gLy8gUk9UUiAzNC8oc3dhcCArIFJPVFIgMikKICAgICAgICAoKGFfbG8gPDwgMjUpIHwgKGFfaGkgPj4+IDcpKSkgPj4+IDA7IC8vIFJPVFIgMzkvKHN3YXAgKyBST1RSIDcpCgogICAgICAvLyBNYWooYSwgYiwgYykgKG9wdGltaXplZCB0aGUgc2FtZSB3YXkgYXMgU0hBLTEpCiAgICAgIG1hal9oaSA9ICgoYV9oaSAmIGJfaGkpIHwgKGNfaGkgJiAoYV9oaSBeIGJfaGkpKSkgPj4+IDA7CiAgICAgIG1hal9sbyA9ICgoYV9sbyAmIGJfbG8pIHwgKGNfbG8gJiAoYV9sbyBeIGJfbG8pKSkgPj4+IDA7CgogICAgICAvLyBtYWluIGFsZ29yaXRobQogICAgICAvLyB0MSA9IChoICsgczEgKyBjaCArIF9rW2ldICsgX3dbaV0pIG1vZHVsbyAyXjY0IChjYXJyeSBsbyBvdmVyZmxvdykKICAgICAgbG8gPSAoaF9sbyArIHMxX2xvICsgY2hfbG8gKyBfa1tpXVsxXSArIHdbaV1bMV0pOwogICAgICB0MV9oaSA9IChoX2hpICsgczFfaGkgKyBjaF9oaSArIF9rW2ldWzBdICsgd1tpXVswXSArCiAgICAgICAgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgICB0MV9sbyA9IGxvID4+PiAwOwoKICAgICAgLy8gdDIgPSBzMCArIG1haiBtb2R1bG8gMl42NCAoY2FycnkgbG8gb3ZlcmZsb3cpCiAgICAgIGxvID0gczBfbG8gKyBtYWpfbG87CiAgICAgIHQyX2hpID0gKHMwX2hpICsgbWFqX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgICB0Ml9sbyA9IGxvID4+PiAwOwoKICAgICAgaF9oaSA9IGdfaGk7CiAgICAgIGhfbG8gPSBnX2xvOwoKICAgICAgZ19oaSA9IGZfaGk7CiAgICAgIGdfbG8gPSBmX2xvOwoKICAgICAgZl9oaSA9IGVfaGk7CiAgICAgIGZfbG8gPSBlX2xvOwoKICAgICAgLy8gZSA9IChkICsgdDEpIG1vZHVsbyAyXjY0IChjYXJyeSBsbyBvdmVyZmxvdykKICAgICAgbG8gPSBkX2xvICsgdDFfbG87CiAgICAgIGVfaGkgPSAoZF9oaSArIHQxX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgICBlX2xvID0gbG8gPj4+IDA7CgogICAgICBkX2hpID0gY19oaTsKICAgICAgZF9sbyA9IGNfbG87CgogICAgICBjX2hpID0gYl9oaTsKICAgICAgY19sbyA9IGJfbG87CgogICAgICBiX2hpID0gYV9oaTsKICAgICAgYl9sbyA9IGFfbG87CgogICAgICAvLyBhID0gKHQxICsgdDIpIG1vZHVsbyAyXjY0IChjYXJyeSBsbyBvdmVyZmxvdykKICAgICAgbG8gPSB0MV9sbyArIHQyX2xvOwogICAgICBhX2hpID0gKHQxX2hpICsgdDJfaGkgKyAoKGxvIC8gMHgxMDAwMDAwMDApID4+PiAwKSkgPj4+IDA7CiAgICAgIGFfbG8gPSBsbyA+Pj4gMDsKICAgIH0KCiAgICAvLyB1cGRhdGUgaGFzaCBzdGF0ZSAoYWRkaXRpb25hbCBtb2R1bG8gMl42NCkKICAgIGxvID0gc1swXVsxXSArIGFfbG87CiAgICBzWzBdWzBdID0gKHNbMF1bMF0gKyBhX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1swXVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1sxXVsxXSArIGJfbG87CiAgICBzWzFdWzBdID0gKHNbMV1bMF0gKyBiX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1sxXVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1syXVsxXSArIGNfbG87CiAgICBzWzJdWzBdID0gKHNbMl1bMF0gKyBjX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1syXVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1szXVsxXSArIGRfbG87CiAgICBzWzNdWzBdID0gKHNbM11bMF0gKyBkX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1szXVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1s0XVsxXSArIGVfbG87CiAgICBzWzRdWzBdID0gKHNbNF1bMF0gKyBlX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1s0XVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1s1XVsxXSArIGZfbG87CiAgICBzWzVdWzBdID0gKHNbNV1bMF0gKyBmX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1s1XVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1s2XVsxXSArIGdfbG87CiAgICBzWzZdWzBdID0gKHNbNl1bMF0gKyBnX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1s2XVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1s3XVsxXSArIGhfbG87CiAgICBzWzddWzBdID0gKHNbN11bMF0gKyBoX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1s3XVsxXSA9IGxvID4+PiAwOwoKICAgIGxlbiAtPSAxMjg7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdzaGE1MTInOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvc2hhNTEyJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBOb2RlLmpzIG1vZHVsZSBmb3IgRm9yZ2UgbWVzc2FnZSBkaWdlc3RzLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgMjAxMS0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UubWQgPSBmb3JnZS5tZCB8fCB7fTsKZm9yZ2UubWQuYWxnb3JpdGhtcyA9IHsKICBtZDU6IGZvcmdlLm1kNSwKICBzaGExOiBmb3JnZS5zaGExLAogIHNoYTI1NjogZm9yZ2Uuc2hhMjU2Cn07CmZvcmdlLm1kLm1kNSA9IGZvcmdlLm1kNTsKZm9yZ2UubWQuc2hhMSA9IGZvcmdlLnNoYTE7CmZvcmdlLm1kLnNoYTI1NiA9IGZvcmdlLnNoYTI1NjsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ21kJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoCiAgJ2pzL21kJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vbWQ1JywgJy4vc2hhMScsICcuL3NoYTI1NicsICcuL3NoYTUxMiddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBIYXNoLWJhc2VkIE1lc3NhZ2UgQXV0aGVudGljYXRpb24gQ29kZSBpbXBsZW1lbnRhdGlvbi4gUmVxdWlyZXMgYSBtZXNzYWdlCiAqIGRpZ2VzdCBvYmplY3QgdGhhdCBjYW4gYmUgb2J0YWluZWQsIGZvciBleGFtcGxlLCBmcm9tIGZvcmdlLm1kLnNoYTEgb3IKICogZm9yZ2UubWQubWQ1LgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxMiBEaWdpdGFsIEJhemFhciwgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8qIEhNQUMgQVBJICovCnZhciBobWFjID0gZm9yZ2UuaG1hYyA9IGZvcmdlLmhtYWMgfHwge307CgovKioKICogQ3JlYXRlcyBhbiBITUFDIG9iamVjdCB0aGF0IHVzZXMgdGhlIGdpdmVuIG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICoKICogQHJldHVybiBhbiBITUFDIG9iamVjdC4KICovCmhtYWMuY3JlYXRlID0gZnVuY3Rpb24oKSB7CiAgLy8gdGhlIGhtYWMga2V5IHRvIHVzZQogIHZhciBfa2V5ID0gbnVsbDsKCiAgLy8gdGhlIG1lc3NhZ2UgZGlnZXN0IHRvIHVzZQogIHZhciBfbWQgPSBudWxsOwoKICAvLyB0aGUgaW5uZXIgcGFkZGluZwogIHZhciBfaXBhZGRpbmcgPSBudWxsOwoKICAvLyB0aGUgb3V0ZXIgcGFkZGluZwogIHZhciBfb3BhZGRpbmcgPSBudWxsOwoKICAvLyBobWFjIGNvbnRleHQKICB2YXIgY3R4ID0ge307CgogIC8qKgogICAqIFN0YXJ0cyBvciByZXN0YXJ0cyB0aGUgSE1BQyB3aXRoIHRoZSBnaXZlbiBrZXkgYW5kIG1lc3NhZ2UgZGlnZXN0LgogICAqCiAgICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCB0byB1c2UsIG51bGwgdG8gcmV1c2UgdGhlIHByZXZpb3VzIG9uZSwKICAgKiAgICAgICAgICAgYSBzdHJpbmcgdG8gdXNlIGJ1aWx0aW4gJ3NoYTEnLCAnbWQ1JywgJ3NoYTI1NicuCiAgICogQHBhcmFtIGtleSB0aGUga2V5IHRvIHVzZSBhcyBhIHN0cmluZywgYXJyYXkgb2YgYnl0ZXMsIGJ5dGUgYnVmZmVyLAogICAqICAgICAgICAgICBvciBudWxsIHRvIHJldXNlIHRoZSBwcmV2aW91cyBrZXkuCiAgICovCiAgY3R4LnN0YXJ0ID0gZnVuY3Rpb24obWQsIGtleSkgewogICAgaWYobWQgIT09IG51bGwpIHsKICAgICAgaWYodHlwZW9mIG1kID09PSAnc3RyaW5nJykgewogICAgICAgIC8vIGNyZWF0ZSBidWlsdGluIG1lc3NhZ2UgZGlnZXN0CiAgICAgICAgbWQgPSBtZC50b0xvd2VyQ2FzZSgpOwogICAgICAgIGlmKG1kIGluIGZvcmdlLm1kLmFsZ29yaXRobXMpIHsKICAgICAgICAgIF9tZCA9IGZvcmdlLm1kLmFsZ29yaXRobXNbbWRdLmNyZWF0ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gaGFzaCBhbGdvcml0aG0gIicgKyBtZCArICciJyk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIC8vIHN0b3JlIG1lc3NhZ2UgZGlnZXN0CiAgICAgICAgX21kID0gbWQ7CiAgICAgIH0KICAgIH0KCiAgICBpZihrZXkgPT09IG51bGwpIHsKICAgICAgLy8gcmV1c2UgcHJldmlvdXMga2V5CiAgICAgIGtleSA9IF9rZXk7CiAgICB9IGVsc2UgewogICAgICBpZih0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykgewogICAgICAgIC8vIGNvbnZlcnQgc3RyaW5nIGludG8gYnl0ZSBidWZmZXIKICAgICAgICBrZXkgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihrZXkpOwogICAgICB9IGVsc2UgaWYoZm9yZ2UudXRpbC5pc0FycmF5KGtleSkpIHsKICAgICAgICAvLyBjb252ZXJ0IGJ5dGUgYXJyYXkgaW50byBieXRlIGJ1ZmZlcgogICAgICAgIHZhciB0bXAgPSBrZXk7CiAgICAgICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdG1wLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICBrZXkucHV0Qnl0ZSh0bXBbaV0pOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gaWYga2V5IGlzIGxvbmdlciB0aGFuIGJsb2Nrc2l6ZSwgaGFzaCBpdAogICAgICB2YXIga2V5bGVuID0ga2V5Lmxlbmd0aCgpOwogICAgICBpZihrZXlsZW4gPiBfbWQuYmxvY2tMZW5ndGgpIHsKICAgICAgICBfbWQuc3RhcnQoKTsKICAgICAgICBfbWQudXBkYXRlKGtleS5ieXRlcygpKTsKICAgICAgICBrZXkgPSBfbWQuZGlnZXN0KCk7CiAgICAgIH0KCiAgICAgIC8vIG1peCBrZXkgaW50byBpbm5lciBhbmQgb3V0ZXIgcGFkZGluZwogICAgICAvLyBpcGFkZGluZyA9IFsweDM2ICogYmxvY2tzaXplXSBeIGtleQogICAgICAvLyBvcGFkZGluZyA9IFsweDVDICogYmxvY2tzaXplXSBeIGtleQogICAgICBfaXBhZGRpbmcgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgICBfb3BhZGRpbmcgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgICBrZXlsZW4gPSBrZXkubGVuZ3RoKCk7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBrZXlsZW47ICsraSkgewogICAgICAgIHZhciB0bXAgPSBrZXkuYXQoaSk7CiAgICAgICAgX2lwYWRkaW5nLnB1dEJ5dGUoMHgzNiBeIHRtcCk7CiAgICAgICAgX29wYWRkaW5nLnB1dEJ5dGUoMHg1QyBeIHRtcCk7CiAgICAgIH0KCiAgICAgIC8vIGlmIGtleSBpcyBzaG9ydGVyIHRoYW4gYmxvY2tzaXplLCBhZGQgYWRkaXRpb25hbCBwYWRkaW5nCiAgICAgIGlmKGtleWxlbiA8IF9tZC5ibG9ja0xlbmd0aCkgewogICAgICAgIHZhciB0bXAgPSBfbWQuYmxvY2tMZW5ndGggLSBrZXlsZW47CiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHRtcDsgKytpKSB7CiAgICAgICAgICBfaXBhZGRpbmcucHV0Qnl0ZSgweDM2KTsKICAgICAgICAgIF9vcGFkZGluZy5wdXRCeXRlKDB4NUMpOwogICAgICAgIH0KICAgICAgfQogICAgICBfa2V5ID0ga2V5OwogICAgICBfaXBhZGRpbmcgPSBfaXBhZGRpbmcuYnl0ZXMoKTsKICAgICAgX29wYWRkaW5nID0gX29wYWRkaW5nLmJ5dGVzKCk7CiAgICB9CgogICAgLy8gZGlnZXN0IGlzIGRvbmUgbGlrZSBzbzogaGFzaChvcGFkZGluZyB8IGhhc2goaXBhZGRpbmcgfCBtZXNzYWdlKSkKCiAgICAvLyBwcmVwYXJlIHRvIGRvIGlubmVyIGhhc2gKICAgIC8vIGhhc2goaXBhZGRpbmcgfCBtZXNzYWdlKQogICAgX21kLnN0YXJ0KCk7CiAgICBfbWQudXBkYXRlKF9pcGFkZGluZyk7CiAgfTsKCiAgLyoqCiAgICogVXBkYXRlcyB0aGUgSE1BQyB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlIGJ5dGVzLgogICAqCiAgICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyB0byB1cGRhdGUgd2l0aC4KICAgKi8KICBjdHgudXBkYXRlID0gZnVuY3Rpb24oYnl0ZXMpIHsKICAgIF9tZC51cGRhdGUoYnl0ZXMpOwogIH07CgogIC8qKgogICAqIFByb2R1Y2VzIHRoZSBNZXNzYWdlIEF1dGhlbnRpY2F0aW9uIENvZGUgKE1BQykuCiAgICoKICAgKiBAcmV0dXJuIGEgYnl0ZSBidWZmZXIgY29udGFpbmluZyB0aGUgZGlnZXN0IHZhbHVlLgogICAqLwogIGN0eC5nZXRNYWMgPSBmdW5jdGlvbigpIHsKICAgIC8vIGRpZ2VzdCBpcyBkb25lIGxpa2Ugc286IGhhc2gob3BhZGRpbmcgfCBoYXNoKGlwYWRkaW5nIHwgbWVzc2FnZSkpCiAgICAvLyBoZXJlIHdlIGRvIHRoZSBvdXRlciBoYXNoaW5nCiAgICB2YXIgaW5uZXIgPSBfbWQuZGlnZXN0KCkuYnl0ZXMoKTsKICAgIF9tZC5zdGFydCgpOwogICAgX21kLnVwZGF0ZShfb3BhZGRpbmcpOwogICAgX21kLnVwZGF0ZShpbm5lcik7CiAgICByZXR1cm4gX21kLmRpZ2VzdCgpOwogIH07CiAgLy8gYWxpYXMgZm9yIGdldE1hYwogIGN0eC5kaWdlc3QgPSBjdHguZ2V0TWFjOwoKICByZXR1cm4gY3R4Owp9OwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAnaG1hYyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9obWFjJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vbWQnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgYmFzaWMgUEVNIChQcml2YWN5IEVuaGFuY2VkIE1haWwpIGFsZ29yaXRobXMuCiAqCiAqIFNlZTogUkZDIDE0MjEuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqCiAqIEEgRm9yZ2UgUEVNIG9iamVjdCBoYXMgdGhlIGZvbGxvd2luZyBmaWVsZHM6CiAqCiAqIHR5cGU6IGlkZW50aWZpZXMgdGhlIHR5cGUgb2YgbWVzc2FnZSAoZWc6ICJSU0EgUFJJVkFURSBLRVkiKS4KICoKICogcHJvY1R5cGU6IGlkZW50aWZpZXMgdGhlIHR5cGUgb2YgcHJvY2Vzc2luZyBwZXJmb3JtZWQgb24gdGhlIG1lc3NhZ2UsCiAqICAgaXQgaGFzIHR3byBzdWJmaWVsZHM6IHZlcnNpb24gYW5kIHR5cGUsIGVnOiA0LEVOQ1JZUFRFRC4KICoKICogY29udGVudERvbWFpbjogaWRlbnRpZmllcyB0aGUgdHlwZSBvZiBjb250ZW50IGluIHRoZSBtZXNzYWdlLCB0eXBpY2FsbHkKICogICBvbmx5IHVzZXMgdGhlIHZhbHVlOiAiUkZDODIyIi4KICoKICogZGVrSW5mbzogaWRlbnRpZmllcyB0aGUgbWVzc2FnZSBlbmNyeXB0aW9uIGFsZ29yaXRobSBhbmQgbW9kZSBhbmQgaW5jbHVkZXMKICogICBhbnkgcGFyYW1ldGVycyBmb3IgdGhlIGFsZ29yaXRobSwgaXQgaGFzIHR3byBzdWJmaWVsZHM6IGFsZ29yaXRobSBhbmQKICogICBwYXJhbWV0ZXJzLCBlZzogREVTLUNCQyxGODE0M0VERTU5NjBDNTk3LgogKgogKiBoZWFkZXJzOiBjb250YWlucyBhbGwgb3RoZXIgUEVNIGVuY2Fwc3VsYXRlZCBoZWFkZXJzIC0tIHdoZXJlIG9yZGVyIGlzCiAqICAgc2lnbmlmaWNhbnQgKGZvciBwYWlyaW5nIGRhdGEgbGlrZSByZWNpcGllbnQgSUQgKyBrZXkgaW5mbykuCiAqCiAqIGJvZHk6IHRoZSBiaW5hcnktZW5jb2RlZCBib2R5LgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIHNob3J0Y3V0IGZvciBwZW0gQVBJCnZhciBwZW0gPSBmb3JnZS5wZW0gPSBmb3JnZS5wZW0gfHwge307CgovKioKICogRW5jb2RlcyAoc2VyaWFsaXplcykgdGhlIGdpdmVuIFBFTSBvYmplY3QuCiAqCiAqIEBwYXJhbSBtc2cgdGhlIFBFTSBtZXNzYWdlIG9iamVjdCB0byBlbmNvZGUuCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgbWF4bGluZSB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lIGZvciB0aGUgYm9keSwgKGRlZmF1bHQ6IDY0KS4KICoKICogQHJldHVybiB0aGUgUEVNLWZvcm1hdHRlZCBzdHJpbmcuCiAqLwpwZW0uZW5jb2RlID0gZnVuY3Rpb24obXNnLCBvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdmFyIHJ2YWwgPSAnLS0tLS1CRUdJTiAnICsgbXNnLnR5cGUgKyAnLS0tLS1cclxuJzsKCiAgLy8gZW5jb2RlIHNwZWNpYWwgaGVhZGVycwogIHZhciBoZWFkZXI7CiAgaWYobXNnLnByb2NUeXBlKSB7CiAgICBoZWFkZXIgPSB7CiAgICAgIG5hbWU6ICdQcm9jLVR5cGUnLAogICAgICB2YWx1ZXM6IFtTdHJpbmcobXNnLnByb2NUeXBlLnZlcnNpb24pLCBtc2cucHJvY1R5cGUudHlwZV0KICAgIH07CiAgICBydmFsICs9IGZvbGRIZWFkZXIoaGVhZGVyKTsKICB9CiAgaWYobXNnLmNvbnRlbnREb21haW4pIHsKICAgIGhlYWRlciA9IHtuYW1lOiAnQ29udGVudC1Eb21haW4nLCB2YWx1ZXM6IFttc2cuY29udGVudERvbWFpbl19OwogICAgcnZhbCArPSBmb2xkSGVhZGVyKGhlYWRlcik7CiAgfQogIGlmKG1zZy5kZWtJbmZvKSB7CiAgICBoZWFkZXIgPSB7bmFtZTogJ0RFSy1JbmZvJywgdmFsdWVzOiBbbXNnLmRla0luZm8uYWxnb3JpdGhtXX07CiAgICBpZihtc2cuZGVrSW5mby5wYXJhbWV0ZXJzKSB7CiAgICAgIGhlYWRlci52YWx1ZXMucHVzaChtc2cuZGVrSW5mby5wYXJhbWV0ZXJzKTsKICAgIH0KICAgIHJ2YWwgKz0gZm9sZEhlYWRlcihoZWFkZXIpOwogIH0KCiAgaWYobXNnLmhlYWRlcnMpIHsKICAgIC8vIGVuY29kZSBhbGwgb3RoZXIgaGVhZGVycwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1zZy5oZWFkZXJzLmxlbmd0aDsgKytpKSB7CiAgICAgIHJ2YWwgKz0gZm9sZEhlYWRlcihtc2cuaGVhZGVyc1tpXSk7CiAgICB9CiAgfQoKICAvLyB0ZXJtaW5hdGUgaGVhZGVyCiAgaWYobXNnLnByb2NUeXBlKSB7CiAgICBydmFsICs9ICdcclxuJzsKICB9CgogIC8vIGFkZCBib2R5CiAgcnZhbCArPSBmb3JnZS51dGlsLmVuY29kZTY0KG1zZy5ib2R5LCBvcHRpb25zLm1heGxpbmUgfHwgNjQpICsgJ1xyXG4nOwoKICBydmFsICs9ICctLS0tLUVORCAnICsgbXNnLnR5cGUgKyAnLS0tLS1cclxuJzsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBEZWNvZGVzIChkZXNlcmlhbGl6ZXMpIGFsbCBQRU0gbWVzc2FnZXMgZm91bmQgaW4gdGhlIGdpdmVuIHN0cmluZy4KICoKICogQHBhcmFtIHN0ciB0aGUgUEVNLWZvcm1hdHRlZCBzdHJpbmcgdG8gZGVjb2RlLgogKgogKiBAcmV0dXJuIHRoZSBQRU0gbWVzc2FnZSBvYmplY3RzIGluIGFuIGFycmF5LgogKi8KcGVtLmRlY29kZSA9IGZ1bmN0aW9uKHN0cikgewogIHZhciBydmFsID0gW107CgogIC8vIHNwbGl0IHN0cmluZyBpbnRvIFBFTSBtZXNzYWdlcyAoYmUgbGVuaWVudCB3L0VPRiBvbiBCRUdJTiBsaW5lKQogIHZhciByTWVzc2FnZSA9IC9ccyotLS0tLUJFR0lOIChbQS1aMC05LSBdKyktLS0tLVxyP1xuPyhbXHgyMS1ceDdlXHNdKz8oPzpccj9cblxyP1xuKSk/KFs6QS1aYS16MC05K1wvPVxzXSs/KS0tLS0tRU5EIFwxLS0tLS0vZzsKICB2YXIgckhlYWRlciA9IC8oW1x4MjEtXHg3ZV0rKTpccyooW1x4MjEtXHg3ZVxzXjpdKykvOwogIHZhciByQ1JMRiA9IC9ccj9cbi87CiAgdmFyIG1hdGNoOwogIHdoaWxlKHRydWUpIHsKICAgIG1hdGNoID0gck1lc3NhZ2UuZXhlYyhzdHIpOwogICAgaWYoIW1hdGNoKSB7CiAgICAgIGJyZWFrOwogICAgfQoKICAgIHZhciBtc2cgPSB7CiAgICAgIHR5cGU6IG1hdGNoWzFdLAogICAgICBwcm9jVHlwZTogbnVsbCwKICAgICAgY29udGVudERvbWFpbjogbnVsbCwKICAgICAgZGVrSW5mbzogbnVsbCwKICAgICAgaGVhZGVyczogW10sCiAgICAgIGJvZHk6IGZvcmdlLnV0aWwuZGVjb2RlNjQobWF0Y2hbM10pCiAgICB9OwogICAgcnZhbC5wdXNoKG1zZyk7CgogICAgLy8gbm8gaGVhZGVycwogICAgaWYoIW1hdGNoWzJdKSB7CiAgICAgIGNvbnRpbnVlOwogICAgfQoKICAgIC8vIHBhcnNlIGhlYWRlcnMKICAgIHZhciBsaW5lcyA9IG1hdGNoWzJdLnNwbGl0KHJDUkxGKTsKICAgIHZhciBsaSA9IDA7CiAgICB3aGlsZShtYXRjaCAmJiBsaSA8IGxpbmVzLmxlbmd0aCkgewogICAgICAvLyBnZXQgbGluZSwgdHJpbSBhbnkgcmhzIHdoaXRlc3BhY2UKICAgICAgdmFyIGxpbmUgPSBsaW5lc1tsaV0ucmVwbGFjZSgvXHMrJC8sICcnKTsKCiAgICAgIC8vIFJGQzI4MjIgdW5mb2xkIGFueSBmb2xsb3dpbmcgZm9sZGVkIGxpbmVzCiAgICAgIGZvcih2YXIgbmwgPSBsaSArIDE7IG5sIDwgbGluZXMubGVuZ3RoOyArK25sKSB7CiAgICAgICAgdmFyIG5leHQgPSBsaW5lc1tubF07CiAgICAgICAgaWYoIS9ccy8udGVzdChuZXh0WzBdKSkgewogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGxpbmUgKz0gbmV4dDsKICAgICAgICBsaSA9IG5sOwogICAgICB9CgogICAgICAvLyBwYXJzZSBoZWFkZXIKICAgICAgbWF0Y2ggPSBsaW5lLm1hdGNoKHJIZWFkZXIpOwogICAgICBpZihtYXRjaCkgewogICAgICAgIHZhciBoZWFkZXIgPSB7bmFtZTogbWF0Y2hbMV0sIHZhbHVlczogW119OwogICAgICAgIHZhciB2YWx1ZXMgPSBtYXRjaFsyXS5zcGxpdCgnLCcpOwogICAgICAgIGZvcih2YXIgdmkgPSAwOyB2aSA8IHZhbHVlcy5sZW5ndGg7ICsrdmkpIHsKICAgICAgICAgIGhlYWRlci52YWx1ZXMucHVzaChsdHJpbSh2YWx1ZXNbdmldKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBQcm9jLVR5cGUgbXVzdCBiZSB0aGUgZmlyc3QgaGVhZGVyCiAgICAgICAgaWYoIW1zZy5wcm9jVHlwZSkgewogICAgICAgICAgaWYoaGVhZGVyLm5hbWUgIT09ICdQcm9jLVR5cGUnKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBQRU0gZm9ybWF0dGVkIG1lc3NhZ2UuIFRoZSBmaXJzdCAnICsKICAgICAgICAgICAgICAnZW5jYXBzdWxhdGVkIGhlYWRlciBtdXN0IGJlICJQcm9jLVR5cGUiLicpOwogICAgICAgICAgfSBlbHNlIGlmKGhlYWRlci52YWx1ZXMubGVuZ3RoICE9PSAyKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBQRU0gZm9ybWF0dGVkIG1lc3NhZ2UuIFRoZSAiUHJvYy1UeXBlIiAnICsKICAgICAgICAgICAgICAnaGVhZGVyIG11c3QgaGF2ZSB0d28gc3ViZmllbGRzLicpOwogICAgICAgICAgfQogICAgICAgICAgbXNnLnByb2NUeXBlID0ge3ZlcnNpb246IHZhbHVlc1swXSwgdHlwZTogdmFsdWVzWzFdfTsKICAgICAgICB9IGVsc2UgaWYoIW1zZy5jb250ZW50RG9tYWluICYmIGhlYWRlci5uYW1lID09PSAnQ29udGVudC1Eb21haW4nKSB7CiAgICAgICAgICAvLyBzcGVjaWFsLWNhc2UgQ29udGVudC1Eb21haW4KICAgICAgICAgIG1zZy5jb250ZW50RG9tYWluID0gdmFsdWVzWzBdIHx8ICcnOwogICAgICAgIH0gZWxzZSBpZighbXNnLmRla0luZm8gJiYgaGVhZGVyLm5hbWUgPT09ICdERUstSW5mbycpIHsKICAgICAgICAgIC8vIHNwZWNpYWwtY2FzZSBERUstSW5mbwogICAgICAgICAgaWYoaGVhZGVyLnZhbHVlcy5sZW5ndGggPT09IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFBFTSBmb3JtYXR0ZWQgbWVzc2FnZS4gVGhlICJERUstSW5mbyIgJyArCiAgICAgICAgICAgICAgJ2hlYWRlciBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIHN1YmZpZWxkLicpOwogICAgICAgICAgfQogICAgICAgICAgbXNnLmRla0luZm8gPSB7YWxnb3JpdGhtOiB2YWx1ZXNbMF0sIHBhcmFtZXRlcnM6IHZhbHVlc1sxXSB8fCBudWxsfTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbXNnLmhlYWRlcnMucHVzaChoZWFkZXIpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgKytsaTsKICAgIH0KCiAgICBpZihtc2cucHJvY1R5cGUgPT09ICdFTkNSWVBURUQnICYmICFtc2cuZGVrSW5mbykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUEVNIGZvcm1hdHRlZCBtZXNzYWdlLiBUaGUgIkRFSy1JbmZvIiAnICsKICAgICAgICAnaGVhZGVyIG11c3QgYmUgcHJlc2VudCBpZiAiUHJvYy1UeXBlIiBpcyAiRU5DUllQVEVEIi4nKTsKICAgIH0KICB9CgogIGlmKHJ2YWwubGVuZ3RoID09PSAwKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUEVNIGZvcm1hdHRlZCBtZXNzYWdlLicpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgpmdW5jdGlvbiBmb2xkSGVhZGVyKGhlYWRlcikgewogIHZhciBydmFsID0gaGVhZGVyLm5hbWUgKyAnOiAnOwoKICAvLyBlbnN1cmUgdmFsdWVzIHdpdGggQ1JMRiBhcmUgZm9sZGVkCiAgdmFyIHZhbHVlcyA9IFtdOwogIHZhciBpbnNlcnRTcGFjZSA9IGZ1bmN0aW9uKG1hdGNoLCAkMSkgewogICAgcmV0dXJuICcgJyArICQxOwogIH07CiAgZm9yKHZhciBpID0gMDsgaSA8IGhlYWRlci52YWx1ZXMubGVuZ3RoOyArK2kpIHsKICAgIHZhbHVlcy5wdXNoKGhlYWRlci52YWx1ZXNbaV0ucmVwbGFjZSgvXihcUytcclxuKS8sIGluc2VydFNwYWNlKSk7CiAgfQogIHJ2YWwgKz0gdmFsdWVzLmpvaW4oJywnKSArICdcclxuJzsKCiAgLy8gZG8gZm9sZGluZwogIHZhciBsZW5ndGggPSAwOwogIHZhciBjYW5kaWRhdGUgPSAtMTsKICBmb3IodmFyIGkgPSAwOyBpIDwgcnZhbC5sZW5ndGg7ICsraSwgKytsZW5ndGgpIHsKICAgIGlmKGxlbmd0aCA+IDY1ICYmIGNhbmRpZGF0ZSAhPT0gLTEpIHsKICAgICAgdmFyIGluc2VydCA9IHJ2YWxbY2FuZGlkYXRlXTsKICAgICAgaWYoaW5zZXJ0ID09PSAnLCcpIHsKICAgICAgICArK2NhbmRpZGF0ZTsKICAgICAgICBydmFsID0gcnZhbC5zdWJzdHIoMCwgY2FuZGlkYXRlKSArICdcclxuICcgKyBydmFsLnN1YnN0cihjYW5kaWRhdGUpOwogICAgICB9IGVsc2UgewogICAgICAgIHJ2YWwgPSBydmFsLnN1YnN0cigwLCBjYW5kaWRhdGUpICsKICAgICAgICAgICdcclxuJyArIGluc2VydCArIHJ2YWwuc3Vic3RyKGNhbmRpZGF0ZSArIDEpOwogICAgICB9CiAgICAgIGxlbmd0aCA9IChpIC0gY2FuZGlkYXRlIC0gMSk7CiAgICAgIGNhbmRpZGF0ZSA9IC0xOwogICAgICArK2k7CiAgICB9IGVsc2UgaWYocnZhbFtpXSA9PT0gJyAnIHx8IHJ2YWxbaV0gPT09ICdcdCcgfHwgcnZhbFtpXSA9PT0gJywnKSB7CiAgICAgIGNhbmRpZGF0ZSA9IGk7CiAgICB9CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKZnVuY3Rpb24gbHRyaW0oc3RyKSB7CiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXHMrLywgJycpOwp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdwZW0nOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvcGVtJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBERVMgKERhdGEgRW5jcnlwdGlvbiBTdGFuZGFyZCkgaW1wbGVtZW50YXRpb24uCiAqCiAqIFRoaXMgaW1wbGVtZW50YXRpb24gc3VwcG9ydHMgREVTIGFzIHdlbGwgYXMgM0RFUy1FREUgaW4gRUNCIGFuZCBDQkMgbW9kZS4KICogSXQgaXMgYmFzZWQgb24gdGhlIEJTRC1saWNlbnNlZCBpbXBsZW1lbnRhdGlvbiBieSBQYXVsIFRlcm86CiAqCiAqIFBhdWwgVGVybywgSnVseSAyMDAxCiAqIGh0dHA6Ly93d3cudGVyby5jby51ay9kZXMvCiAqCiAqIE9wdGltaXNlZCBmb3IgcGVyZm9ybWFuY2Ugd2l0aCBsYXJnZSBibG9ja3MgYnkgTWljaGFlbCBIYXl3b3J0aCwgTm92ZW1iZXIgMjAwMQogKiBodHRwOi8vd3d3Lm5ldGRlYWxpbmcuY29tCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiBBTkQKICogQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFCiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCiAqIEFSRSBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFCiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMCiAqIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTCiAqIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKQogKiBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVAogKiBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZCiAqIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKICogU1VDSCBEQU1BR0UuCiAqCiAqIEBhdXRob3IgU3RlZmFuIFNpZWdsCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMiBTdGVmYW4gU2llZ2wgPHN0ZXNpZUBicm9rZW5waXBlLmRlPgogKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8qIERFUyBBUEkgKi8KZm9yZ2UuZGVzID0gZm9yZ2UuZGVzIHx8IHt9OwoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogdmFyIGNpcGhlciA9IGZvcmdlLmNpcGhlci5jcmVhdGVDaXBoZXIoJ0RFUy08bW9kZT4nLCBrZXkpOwogKiBjaXBoZXIuc3RhcnQoe2l2OiBpdn0pOwogKgogKiBDcmVhdGVzIGFuIERFUyBjaXBoZXIgb2JqZWN0IHRvIGVuY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gc3ltbWV0cmljIGtleS4KICogVGhlIG91dHB1dCB3aWxsIGJlIHN0b3JlZCBpbiB0aGUgJ291dHB1dCcgbWVtYmVyIG9mIHRoZSByZXR1cm5lZCBjaXBoZXIuCiAqCiAqIFRoZSBrZXkgYW5kIGl2IG1heSBiZSBnaXZlbiBhcyBiaW5hcnktZW5jb2RlZCBzdHJpbmdzIG9mIGJ5dGVzIG9yCiAqIGJ5dGUgYnVmZmVycy4KICoKICogQHBhcmFtIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UgKDY0IG9yIDE5MiBiaXRzKS4KICogQHBhcmFtIGl2IHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IgdG8gdXNlLgogKiBAcGFyYW0gb3V0cHV0IHRoZSBidWZmZXIgdG8gd3JpdGUgdG8sIG51bGwgdG8gY3JlYXRlIG9uZS4KICogQHBhcmFtIG1vZGUgdGhlIGNpcGhlciBtb2RlIHRvIHVzZSAoZGVmYXVsdDogJ0NCQycgaWYgSVYgaXMKICogICAgICAgICAgZ2l2ZW4sICdFQ0InIGlmIG51bGwpLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwpmb3JnZS5kZXMuc3RhcnRFbmNyeXB0aW5nID0gZnVuY3Rpb24oa2V5LCBpdiwgb3V0cHV0LCBtb2RlKSB7CiAgdmFyIGNpcGhlciA9IF9jcmVhdGVDaXBoZXIoewogICAga2V5OiBrZXksCiAgICBvdXRwdXQ6IG91dHB1dCwKICAgIGRlY3J5cHQ6IGZhbHNlLAogICAgbW9kZTogbW9kZSB8fCAoaXYgPT09IG51bGwgPyAnRUNCJyA6ICdDQkMnKQogIH0pOwogIGNpcGhlci5zdGFydChpdik7CiAgcmV0dXJuIGNpcGhlcjsKfTsKCi8qKgogKiBEZXByZWNhdGVkLiBJbnN0ZWFkLCB1c2U6CiAqCiAqIHZhciBjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKCdERVMtPG1vZGU+Jywga2V5KTsKICoKICogQ3JlYXRlcyBhbiBERVMgY2lwaGVyIG9iamVjdCB0byBlbmNyeXB0IGRhdGEgdXNpbmcgdGhlIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqCiAqIFRoZSBrZXkgbWF5IGJlIGdpdmVuIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzIG9yIGEgYnl0ZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlICg2NCBvciAxOTIgYml0cykuCiAqIEBwYXJhbSBtb2RlIHRoZSBjaXBoZXIgbW9kZSB0byB1c2UgKGRlZmF1bHQ6ICdDQkMnKS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZm9yZ2UuZGVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXIgPSBmdW5jdGlvbihrZXksIG1vZGUpIHsKICByZXR1cm4gX2NyZWF0ZUNpcGhlcih7CiAgICBrZXk6IGtleSwKICAgIG91dHB1dDogbnVsbCwKICAgIGRlY3J5cHQ6IGZhbHNlLAogICAgbW9kZTogbW9kZQogIH0pOwp9OwoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogdmFyIGRlY2lwaGVyID0gZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKCdERVMtPG1vZGU+Jywga2V5KTsKICogZGVjaXBoZXIuc3RhcnQoe2l2OiBpdn0pOwogKgogKiBDcmVhdGVzIGFuIERFUyBjaXBoZXIgb2JqZWN0IHRvIGRlY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gc3ltbWV0cmljIGtleS4KICogVGhlIG91dHB1dCB3aWxsIGJlIHN0b3JlZCBpbiB0aGUgJ291dHB1dCcgbWVtYmVyIG9mIHRoZSByZXR1cm5lZCBjaXBoZXIuCiAqCiAqIFRoZSBrZXkgYW5kIGl2IG1heSBiZSBnaXZlbiBhcyBiaW5hcnktZW5jb2RlZCBzdHJpbmdzIG9mIGJ5dGVzIG9yCiAqIGJ5dGUgYnVmZmVycy4KICoKICogQHBhcmFtIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UgKDY0IG9yIDE5MiBiaXRzKS4KICogQHBhcmFtIGl2IHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IgdG8gdXNlLgogKiBAcGFyYW0gb3V0cHV0IHRoZSBidWZmZXIgdG8gd3JpdGUgdG8sIG51bGwgdG8gY3JlYXRlIG9uZS4KICogQHBhcmFtIG1vZGUgdGhlIGNpcGhlciBtb2RlIHRvIHVzZSAoZGVmYXVsdDogJ0NCQycgaWYgSVYgaXMKICogICAgICAgICAgZ2l2ZW4sICdFQ0InIGlmIG51bGwpLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwpmb3JnZS5kZXMuc3RhcnREZWNyeXB0aW5nID0gZnVuY3Rpb24oa2V5LCBpdiwgb3V0cHV0LCBtb2RlKSB7CiAgdmFyIGNpcGhlciA9IF9jcmVhdGVDaXBoZXIoewogICAga2V5OiBrZXksCiAgICBvdXRwdXQ6IG91dHB1dCwKICAgIGRlY3J5cHQ6IHRydWUsCiAgICBtb2RlOiBtb2RlIHx8IChpdiA9PT0gbnVsbCA/ICdFQ0InIDogJ0NCQycpCiAgfSk7CiAgY2lwaGVyLnN0YXJ0KGl2KTsKICByZXR1cm4gY2lwaGVyOwp9OwoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogdmFyIGRlY2lwaGVyID0gZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKCdERVMtPG1vZGU+Jywga2V5KTsKICoKICogQ3JlYXRlcyBhbiBERVMgY2lwaGVyIG9iamVjdCB0byBkZWNyeXB0IGRhdGEgdXNpbmcgdGhlIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqCiAqIFRoZSBrZXkgbWF5IGJlIGdpdmVuIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzIG9yIGEgYnl0ZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlICg2NCBvciAxOTIgYml0cykuCiAqIEBwYXJhbSBtb2RlIHRoZSBjaXBoZXIgbW9kZSB0byB1c2UgKGRlZmF1bHQ6ICdDQkMnKS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZm9yZ2UuZGVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXIgPSBmdW5jdGlvbihrZXksIG1vZGUpIHsKICByZXR1cm4gX2NyZWF0ZUNpcGhlcih7CiAgICBrZXk6IGtleSwKICAgIG91dHB1dDogbnVsbCwKICAgIGRlY3J5cHQ6IHRydWUsCiAgICBtb2RlOiBtb2RlCiAgfSk7Cn07CgovKioKICogQ3JlYXRlcyBhIG5ldyBERVMgY2lwaGVyIGFsZ29yaXRobSBvYmplY3QuCiAqCiAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0uCiAqIEBwYXJhbSBtb2RlIHRoZSBtb2RlIGZhY3RvcnkgZnVuY3Rpb24uCiAqCiAqIEByZXR1cm4gdGhlIERFUyBhbGdvcml0aG0gb2JqZWN0LgogKi8KZm9yZ2UuZGVzLkFsZ29yaXRobSA9IGZ1bmN0aW9uKG5hbWUsIG1vZGUpIHsKICB2YXIgc2VsZiA9IHRoaXM7CiAgc2VsZi5uYW1lID0gbmFtZTsKICBzZWxmLm1vZGUgPSBuZXcgbW9kZSh7CiAgICBibG9ja1NpemU6IDgsCiAgICBjaXBoZXI6IHsKICAgICAgZW5jcnlwdDogZnVuY3Rpb24oaW5CbG9jaywgb3V0QmxvY2spIHsKICAgICAgICByZXR1cm4gX3VwZGF0ZUJsb2NrKHNlbGYuX2tleXMsIGluQmxvY2ssIG91dEJsb2NrLCBmYWxzZSk7CiAgICAgIH0sCiAgICAgIGRlY3J5cHQ6IGZ1bmN0aW9uKGluQmxvY2ssIG91dEJsb2NrKSB7CiAgICAgICAgcmV0dXJuIF91cGRhdGVCbG9jayhzZWxmLl9rZXlzLCBpbkJsb2NrLCBvdXRCbG9jaywgdHJ1ZSk7CiAgICAgIH0KICAgIH0KICB9KTsKICBzZWxmLl9pbml0ID0gZmFsc2U7Cn07CgovKioKICogSW5pdGlhbGl6ZXMgdGhpcyBERVMgYWxnb3JpdGhtIGJ5IGV4cGFuZGluZyBpdHMga2V5LgogKgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIGtleSB0aGUga2V5IHRvIHVzZSB3aXRoIHRoaXMgYWxnb3JpdGhtLgogKiAgICAgICAgICBkZWNyeXB0IHRydWUgaWYgdGhlIGFsZ29yaXRobSBzaG91bGQgYmUgaW5pdGlhbGl6ZWQgZm9yIGRlY3J5cHRpb24sCiAqICAgICAgICAgICAgZmFsc2UgZm9yIGVuY3J5cHRpb24uCiAqLwpmb3JnZS5kZXMuQWxnb3JpdGhtLnByb3RvdHlwZS5pbml0aWFsaXplID0gZnVuY3Rpb24ob3B0aW9ucykgewogIGlmKHRoaXMuX2luaXQpIHsKICAgIHJldHVybjsKICB9CgogIHZhciBrZXkgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihvcHRpb25zLmtleSk7CiAgaWYodGhpcy5uYW1lLmluZGV4T2YoJzNERVMnKSA9PT0gMCkgewogICAgaWYoa2V5Lmxlbmd0aCgpICE9PSAyNCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgVHJpcGxlLURFUyBrZXkgc2l6ZTogJyArIGtleS5sZW5ndGgoKSAqIDgpOwogICAgfQogIH0KCiAgLy8gZG8ga2V5IGV4cGFuc2lvbiB0byAxNiBvciA0OCBzdWJrZXlzIChzaW5nbGUgb3IgdHJpcGxlIERFUykKICB0aGlzLl9rZXlzID0gX2NyZWF0ZUtleXMoa2V5KTsKICB0aGlzLl9pbml0ID0gdHJ1ZTsKfTsKCgovKiogUmVnaXN0ZXIgREVTIGFsZ29yaXRobXMgKiovCgpyZWdpc3RlckFsZ29yaXRobSgnREVTLUVDQicsIGZvcmdlLmNpcGhlci5tb2Rlcy5lY2IpOwpyZWdpc3RlckFsZ29yaXRobSgnREVTLUNCQycsIGZvcmdlLmNpcGhlci5tb2Rlcy5jYmMpOwpyZWdpc3RlckFsZ29yaXRobSgnREVTLUNGQicsIGZvcmdlLmNpcGhlci5tb2Rlcy5jZmIpOwpyZWdpc3RlckFsZ29yaXRobSgnREVTLU9GQicsIGZvcmdlLmNpcGhlci5tb2Rlcy5vZmIpOwpyZWdpc3RlckFsZ29yaXRobSgnREVTLUNUUicsIGZvcmdlLmNpcGhlci5tb2Rlcy5jdHIpOwoKcmVnaXN0ZXJBbGdvcml0aG0oJzNERVMtRUNCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmVjYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCczREVTLUNCQycsIGZvcmdlLmNpcGhlci5tb2Rlcy5jYmMpOwpyZWdpc3RlckFsZ29yaXRobSgnM0RFUy1DRkInLCBmb3JnZS5jaXBoZXIubW9kZXMuY2ZiKTsKcmVnaXN0ZXJBbGdvcml0aG0oJzNERVMtT0ZCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLm9mYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCczREVTLUNUUicsIGZvcmdlLmNpcGhlci5tb2Rlcy5jdHIpOwoKZnVuY3Rpb24gcmVnaXN0ZXJBbGdvcml0aG0obmFtZSwgbW9kZSkgewogIHZhciBmYWN0b3J5ID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gbmV3IGZvcmdlLmRlcy5BbGdvcml0aG0obmFtZSwgbW9kZSk7CiAgfTsKICBmb3JnZS5jaXBoZXIucmVnaXN0ZXJBbGdvcml0aG0obmFtZSwgZmFjdG9yeSk7Cn0KCgovKiogREVTIGltcGxlbWVudGF0aW9uICoqLwoKdmFyIHNwZnVuY3Rpb24xID0gWzB4MTAxMDQwMCwwLDB4MTAwMDAsMHgxMDEwNDA0LDB4MTAxMDAwNCwweDEwNDA0LDB4NCwweDEwMDAwLDB4NDAwLDB4MTAxMDQwMCwweDEwMTA0MDQsMHg0MDAsMHgxMDAwNDA0LDB4MTAxMDAwNCwweDEwMDAwMDAsMHg0LDB4NDA0LDB4MTAwMDQwMCwweDEwMDA0MDAsMHgxMDQwMCwweDEwNDAwLDB4MTAxMDAwMCwweDEwMTAwMDAsMHgxMDAwNDA0LDB4MTAwMDQsMHgxMDAwMDA0LDB4MTAwMDAwNCwweDEwMDA0LDAsMHg0MDQsMHgxMDQwNCwweDEwMDAwMDAsMHgxMDAwMCwweDEwMTA0MDQsMHg0LDB4MTAxMDAwMCwweDEwMTA0MDAsMHgxMDAwMDAwLDB4MTAwMDAwMCwweDQwMCwweDEwMTAwMDQsMHgxMDAwMCwweDEwNDAwLDB4MTAwMDAwNCwweDQwMCwweDQsMHgxMDAwNDA0LDB4MTA0MDQsMHgxMDEwNDA0LDB4MTAwMDQsMHgxMDEwMDAwLDB4MTAwMDQwNCwweDEwMDAwMDQsMHg0MDQsMHgxMDQwNCwweDEwMTA0MDAsMHg0MDQsMHgxMDAwNDAwLDB4MTAwMDQwMCwwLDB4MTAwMDQsMHgxMDQwMCwwLDB4MTAxMDAwNF07CnZhciBzcGZ1bmN0aW9uMiA9IFstMHg3ZmVmN2ZlMCwtMHg3ZmZmODAwMCwweDgwMDAsMHgxMDgwMjAsMHgxMDAwMDAsMHgyMCwtMHg3ZmVmZmZlMCwtMHg3ZmZmN2ZlMCwtMHg3ZmZmZmZlMCwtMHg3ZmVmN2ZlMCwtMHg3ZmVmODAwMCwtMHg4MDAwMDAwMCwtMHg3ZmZmODAwMCwweDEwMDAwMCwweDIwLC0weDdmZWZmZmUwLDB4MTA4MDAwLDB4MTAwMDIwLC0weDdmZmY3ZmUwLDAsLTB4ODAwMDAwMDAsMHg4MDAwLDB4MTA4MDIwLC0weDdmZjAwMDAwLDB4MTAwMDIwLC0weDdmZmZmZmUwLDAsMHgxMDgwMDAsMHg4MDIwLC0weDdmZWY4MDAwLC0weDdmZjAwMDAwLDB4ODAyMCwwLDB4MTA4MDIwLC0weDdmZWZmZmUwLDB4MTAwMDAwLC0weDdmZmY3ZmUwLC0weDdmZjAwMDAwLC0weDdmZWY4MDAwLDB4ODAwMCwtMHg3ZmYwMDAwMCwtMHg3ZmZmODAwMCwweDIwLC0weDdmZWY3ZmUwLDB4MTA4MDIwLDB4MjAsMHg4MDAwLC0weDgwMDAwMDAwLDB4ODAyMCwtMHg3ZmVmODAwMCwweDEwMDAwMCwtMHg3ZmZmZmZlMCwweDEwMDAyMCwtMHg3ZmZmN2ZlMCwtMHg3ZmZmZmZlMCwweDEwMDAyMCwweDEwODAwMCwwLC0weDdmZmY4MDAwLDB4ODAyMCwtMHg4MDAwMDAwMCwtMHg3ZmVmZmZlMCwtMHg3ZmVmN2ZlMCwweDEwODAwMF07CnZhciBzcGZ1bmN0aW9uMyA9IFsweDIwOCwweDgwMjAyMDAsMCwweDgwMjAwMDgsMHg4MDAwMjAwLDAsMHgyMDIwOCwweDgwMDAyMDAsMHgyMDAwOCwweDgwMDAwMDgsMHg4MDAwMDA4LDB4MjAwMDAsMHg4MDIwMjA4LDB4MjAwMDgsMHg4MDIwMDAwLDB4MjA4LDB4ODAwMDAwMCwweDgsMHg4MDIwMjAwLDB4MjAwLDB4MjAyMDAsMHg4MDIwMDAwLDB4ODAyMDAwOCwweDIwMjA4LDB4ODAwMDIwOCwweDIwMjAwLDB4MjAwMDAsMHg4MDAwMjA4LDB4OCwweDgwMjAyMDgsMHgyMDAsMHg4MDAwMDAwLDB4ODAyMDIwMCwweDgwMDAwMDAsMHgyMDAwOCwweDIwOCwweDIwMDAwLDB4ODAyMDIwMCwweDgwMDAyMDAsMCwweDIwMCwweDIwMDA4LDB4ODAyMDIwOCwweDgwMDAyMDAsMHg4MDAwMDA4LDB4MjAwLDAsMHg4MDIwMDA4LDB4ODAwMDIwOCwweDIwMDAwLDB4ODAwMDAwMCwweDgwMjAyMDgsMHg4LDB4MjAyMDgsMHgyMDIwMCwweDgwMDAwMDgsMHg4MDIwMDAwLDB4ODAwMDIwOCwweDIwOCwweDgwMjAwMDAsMHgyMDIwOCwweDgsMHg4MDIwMDA4LDB4MjAyMDBdOwp2YXIgc3BmdW5jdGlvbjQgPSBbMHg4MDIwMDEsMHgyMDgxLDB4MjA4MSwweDgwLDB4ODAyMDgwLDB4ODAwMDgxLDB4ODAwMDAxLDB4MjAwMSwwLDB4ODAyMDAwLDB4ODAyMDAwLDB4ODAyMDgxLDB4ODEsMCwweDgwMDA4MCwweDgwMDAwMSwweDEsMHgyMDAwLDB4ODAwMDAwLDB4ODAyMDAxLDB4ODAsMHg4MDAwMDAsMHgyMDAxLDB4MjA4MCwweDgwMDA4MSwweDEsMHgyMDgwLDB4ODAwMDgwLDB4MjAwMCwweDgwMjA4MCwweDgwMjA4MSwweDgxLDB4ODAwMDgwLDB4ODAwMDAxLDB4ODAyMDAwLDB4ODAyMDgxLDB4ODEsMCwwLDB4ODAyMDAwLDB4MjA4MCwweDgwMDA4MCwweDgwMDA4MSwweDEsMHg4MDIwMDEsMHgyMDgxLDB4MjA4MSwweDgwLDB4ODAyMDgxLDB4ODEsMHgxLDB4MjAwMCwweDgwMDAwMSwweDIwMDEsMHg4MDIwODAsMHg4MDAwODEsMHgyMDAxLDB4MjA4MCwweDgwMDAwMCwweDgwMjAwMSwweDgwLDB4ODAwMDAwLDB4MjAwMCwweDgwMjA4MF07CnZhciBzcGZ1bmN0aW9uNSA9IFsweDEwMCwweDIwODAxMDAsMHgyMDgwMDAwLDB4NDIwMDAxMDAsMHg4MDAwMCwweDEwMCwweDQwMDAwMDAwLDB4MjA4MDAwMCwweDQwMDgwMTAwLDB4ODAwMDAsMHgyMDAwMTAwLDB4NDAwODAxMDAsMHg0MjAwMDEwMCwweDQyMDgwMDAwLDB4ODAxMDAsMHg0MDAwMDAwMCwweDIwMDAwMDAsMHg0MDA4MDAwMCwweDQwMDgwMDAwLDAsMHg0MDAwMDEwMCwweDQyMDgwMTAwLDB4NDIwODAxMDAsMHgyMDAwMTAwLDB4NDIwODAwMDAsMHg0MDAwMDEwMCwwLDB4NDIwMDAwMDAsMHgyMDgwMTAwLDB4MjAwMDAwMCwweDQyMDAwMDAwLDB4ODAxMDAsMHg4MDAwMCwweDQyMDAwMTAwLDB4MTAwLDB4MjAwMDAwMCwweDQwMDAwMDAwLDB4MjA4MDAwMCwweDQyMDAwMTAwLDB4NDAwODAxMDAsMHgyMDAwMTAwLDB4NDAwMDAwMDAsMHg0MjA4MDAwMCwweDIwODAxMDAsMHg0MDA4MDEwMCwweDEwMCwweDIwMDAwMDAsMHg0MjA4MDAwMCwweDQyMDgwMTAwLDB4ODAxMDAsMHg0MjAwMDAwMCwweDQyMDgwMTAwLDB4MjA4MDAwMCwwLDB4NDAwODAwMDAsMHg0MjAwMDAwMCwweDgwMTAwLDB4MjAwMDEwMCwweDQwMDAwMTAwLDB4ODAwMDAsMCwweDQwMDgwMDAwLDB4MjA4MDEwMCwweDQwMDAwMTAwXTsKdmFyIHNwZnVuY3Rpb242ID0gWzB4MjAwMDAwMTAsMHgyMDQwMDAwMCwweDQwMDAsMHgyMDQwNDAxMCwweDIwNDAwMDAwLDB4MTAsMHgyMDQwNDAxMCwweDQwMDAwMCwweDIwMDA0MDAwLDB4NDA0MDEwLDB4NDAwMDAwLDB4MjAwMDAwMTAsMHg0MDAwMTAsMHgyMDAwNDAwMCwweDIwMDAwMDAwLDB4NDAxMCwwLDB4NDAwMDEwLDB4MjAwMDQwMTAsMHg0MDAwLDB4NDA0MDAwLDB4MjAwMDQwMTAsMHgxMCwweDIwNDAwMDEwLDB4MjA0MDAwMTAsMCwweDQwNDAxMCwweDIwNDA0MDAwLDB4NDAxMCwweDQwNDAwMCwweDIwNDA0MDAwLDB4MjAwMDAwMDAsMHgyMDAwNDAwMCwweDEwLDB4MjA0MDAwMTAsMHg0MDQwMDAsMHgyMDQwNDAxMCwweDQwMDAwMCwweDQwMTAsMHgyMDAwMDAxMCwweDQwMDAwMCwweDIwMDA0MDAwLDB4MjAwMDAwMDAsMHg0MDEwLDB4MjAwMDAwMTAsMHgyMDQwNDAxMCwweDQwNDAwMCwweDIwNDAwMDAwLDB4NDA0MDEwLDB4MjA0MDQwMDAsMCwweDIwNDAwMDEwLDB4MTAsMHg0MDAwLDB4MjA0MDAwMDAsMHg0MDQwMTAsMHg0MDAwLDB4NDAwMDEwLDB4MjAwMDQwMTAsMCwweDIwNDA0MDAwLDB4MjAwMDAwMDAsMHg0MDAwMTAsMHgyMDAwNDAxMF07CnZhciBzcGZ1bmN0aW9uNyA9IFsweDIwMDAwMCwweDQyMDAwMDIsMHg0MDAwODAyLDAsMHg4MDAsMHg0MDAwODAyLDB4MjAwODAyLDB4NDIwMDgwMCwweDQyMDA4MDIsMHgyMDAwMDAsMCwweDQwMDAwMDIsMHgyLDB4NDAwMDAwMCwweDQyMDAwMDIsMHg4MDIsMHg0MDAwODAwLDB4MjAwODAyLDB4MjAwMDAyLDB4NDAwMDgwMCwweDQwMDAwMDIsMHg0MjAwMDAwLDB4NDIwMDgwMCwweDIwMDAwMiwweDQyMDAwMDAsMHg4MDAsMHg4MDIsMHg0MjAwODAyLDB4MjAwODAwLDB4MiwweDQwMDAwMDAsMHgyMDA4MDAsMHg0MDAwMDAwLDB4MjAwODAwLDB4MjAwMDAwLDB4NDAwMDgwMiwweDQwMDA4MDIsMHg0MjAwMDAyLDB4NDIwMDAwMiwweDIsMHgyMDAwMDIsMHg0MDAwMDAwLDB4NDAwMDgwMCwweDIwMDAwMCwweDQyMDA4MDAsMHg4MDIsMHgyMDA4MDIsMHg0MjAwODAwLDB4ODAyLDB4NDAwMDAwMiwweDQyMDA4MDIsMHg0MjAwMDAwLDB4MjAwODAwLDAsMHgyLDB4NDIwMDgwMiwwLDB4MjAwODAyLDB4NDIwMDAwMCwweDgwMCwweDQwMDAwMDIsMHg0MDAwODAwLDB4ODAwLDB4MjAwMDAyXTsKdmFyIHNwZnVuY3Rpb244ID0gWzB4MTAwMDEwNDAsMHgxMDAwLDB4NDAwMDAsMHgxMDA0MTA0MCwweDEwMDAwMDAwLDB4MTAwMDEwNDAsMHg0MCwweDEwMDAwMDAwLDB4NDAwNDAsMHgxMDA0MDAwMCwweDEwMDQxMDQwLDB4NDEwMDAsMHgxMDA0MTAwMCwweDQxMDQwLDB4MTAwMCwweDQwLDB4MTAwNDAwMDAsMHgxMDAwMDA0MCwweDEwMDAxMDAwLDB4MTA0MCwweDQxMDAwLDB4NDAwNDAsMHgxMDA0MDA0MCwweDEwMDQxMDAwLDB4MTA0MCwwLDAsMHgxMDA0MDA0MCwweDEwMDAwMDQwLDB4MTAwMDEwMDAsMHg0MTA0MCwweDQwMDAwLDB4NDEwNDAsMHg0MDAwMCwweDEwMDQxMDAwLDB4MTAwMCwweDQwLDB4MTAwNDAwNDAsMHgxMDAwLDB4NDEwNDAsMHgxMDAwMTAwMCwweDQwLDB4MTAwMDAwNDAsMHgxMDA0MDAwMCwweDEwMDQwMDQwLDB4MTAwMDAwMDAsMHg0MDAwMCwweDEwMDAxMDQwLDAsMHgxMDA0MTA0MCwweDQwMDQwLDB4MTAwMDAwNDAsMHgxMDA0MDAwMCwweDEwMDAxMDAwLDB4MTAwMDEwNDAsMCwweDEwMDQxMDQwLDB4NDEwMDAsMHg0MTAwMCwweDEwNDAsMHgxMDQwLDB4NDAwNDAsMHgxMDAwMDAwMCwweDEwMDQxMDAwXTsKCi8qKgogKiBDcmVhdGUgbmVjZXNzYXJ5IHN1YiBrZXlzLgogKgogKiBAcGFyYW0ga2V5IHRoZSA2NC1iaXQgb3IgMTkyLWJpdCBrZXkuCiAqCiAqIEByZXR1cm4gdGhlIGV4cGFuZGVkIGtleXMuCiAqLwpmdW5jdGlvbiBfY3JlYXRlS2V5cyhrZXkpIHsKICB2YXIgcGMyYnl0ZXMwICA9IFswLDB4NCwweDIwMDAwMDAwLDB4MjAwMDAwMDQsMHgxMDAwMCwweDEwMDA0LDB4MjAwMTAwMDAsMHgyMDAxMDAwNCwweDIwMCwweDIwNCwweDIwMDAwMjAwLDB4MjAwMDAyMDQsMHgxMDIwMCwweDEwMjA0LDB4MjAwMTAyMDAsMHgyMDAxMDIwNF0sCiAgICAgIHBjMmJ5dGVzMSAgPSBbMCwweDEsMHgxMDAwMDAsMHgxMDAwMDEsMHg0MDAwMDAwLDB4NDAwMDAwMSwweDQxMDAwMDAsMHg0MTAwMDAxLDB4MTAwLDB4MTAxLDB4MTAwMTAwLDB4MTAwMTAxLDB4NDAwMDEwMCwweDQwMDAxMDEsMHg0MTAwMTAwLDB4NDEwMDEwMV0sCiAgICAgIHBjMmJ5dGVzMiAgPSBbMCwweDgsMHg4MDAsMHg4MDgsMHgxMDAwMDAwLDB4MTAwMDAwOCwweDEwMDA4MDAsMHgxMDAwODA4LDAsMHg4LDB4ODAwLDB4ODA4LDB4MTAwMDAwMCwweDEwMDAwMDgsMHgxMDAwODAwLDB4MTAwMDgwOF0sCiAgICAgIHBjMmJ5dGVzMyAgPSBbMCwweDIwMDAwMCwweDgwMDAwMDAsMHg4MjAwMDAwLDB4MjAwMCwweDIwMjAwMCwweDgwMDIwMDAsMHg4MjAyMDAwLDB4MjAwMDAsMHgyMjAwMDAsMHg4MDIwMDAwLDB4ODIyMDAwMCwweDIyMDAwLDB4MjIyMDAwLDB4ODAyMjAwMCwweDgyMjIwMDBdLAogICAgICBwYzJieXRlczQgID0gWzAsMHg0MDAwMCwweDEwLDB4NDAwMTAsMCwweDQwMDAwLDB4MTAsMHg0MDAxMCwweDEwMDAsMHg0MTAwMCwweDEwMTAsMHg0MTAxMCwweDEwMDAsMHg0MTAwMCwweDEwMTAsMHg0MTAxMF0sCiAgICAgIHBjMmJ5dGVzNSAgPSBbMCwweDQwMCwweDIwLDB4NDIwLDAsMHg0MDAsMHgyMCwweDQyMCwweDIwMDAwMDAsMHgyMDAwNDAwLDB4MjAwMDAyMCwweDIwMDA0MjAsMHgyMDAwMDAwLDB4MjAwMDQwMCwweDIwMDAwMjAsMHgyMDAwNDIwXSwKICAgICAgcGMyYnl0ZXM2ICA9IFswLDB4MTAwMDAwMDAsMHg4MDAwMCwweDEwMDgwMDAwLDB4MiwweDEwMDAwMDAyLDB4ODAwMDIsMHgxMDA4MDAwMiwwLDB4MTAwMDAwMDAsMHg4MDAwMCwweDEwMDgwMDAwLDB4MiwweDEwMDAwMDAyLDB4ODAwMDIsMHgxMDA4MDAwMl0sCiAgICAgIHBjMmJ5dGVzNyAgPSBbMCwweDEwMDAwLDB4ODAwLDB4MTA4MDAsMHgyMDAwMDAwMCwweDIwMDEwMDAwLDB4MjAwMDA4MDAsMHgyMDAxMDgwMCwweDIwMDAwLDB4MzAwMDAsMHgyMDgwMCwweDMwODAwLDB4MjAwMjAwMDAsMHgyMDAzMDAwMCwweDIwMDIwODAwLDB4MjAwMzA4MDBdLAogICAgICBwYzJieXRlczggID0gWzAsMHg0MDAwMCwwLDB4NDAwMDAsMHgyLDB4NDAwMDIsMHgyLDB4NDAwMDIsMHgyMDAwMDAwLDB4MjA0MDAwMCwweDIwMDAwMDAsMHgyMDQwMDAwLDB4MjAwMDAwMiwweDIwNDAwMDIsMHgyMDAwMDAyLDB4MjA0MDAwMl0sCiAgICAgIHBjMmJ5dGVzOSAgPSBbMCwweDEwMDAwMDAwLDB4OCwweDEwMDAwMDA4LDAsMHgxMDAwMDAwMCwweDgsMHgxMDAwMDAwOCwweDQwMCwweDEwMDAwNDAwLDB4NDA4LDB4MTAwMDA0MDgsMHg0MDAsMHgxMDAwMDQwMCwweDQwOCwweDEwMDAwNDA4XSwKICAgICAgcGMyYnl0ZXMxMCA9IFswLDB4MjAsMCwweDIwLDB4MTAwMDAwLDB4MTAwMDIwLDB4MTAwMDAwLDB4MTAwMDIwLDB4MjAwMCwweDIwMjAsMHgyMDAwLDB4MjAyMCwweDEwMjAwMCwweDEwMjAyMCwweDEwMjAwMCwweDEwMjAyMF0sCiAgICAgIHBjMmJ5dGVzMTEgPSBbMCwweDEwMDAwMDAsMHgyMDAsMHgxMDAwMjAwLDB4MjAwMDAwLDB4MTIwMDAwMCwweDIwMDIwMCwweDEyMDAyMDAsMHg0MDAwMDAwLDB4NTAwMDAwMCwweDQwMDAyMDAsMHg1MDAwMjAwLDB4NDIwMDAwMCwweDUyMDAwMDAsMHg0MjAwMjAwLDB4NTIwMDIwMF0sCiAgICAgIHBjMmJ5dGVzMTIgPSBbMCwweDEwMDAsMHg4MDAwMDAwLDB4ODAwMTAwMCwweDgwMDAwLDB4ODEwMDAsMHg4MDgwMDAwLDB4ODA4MTAwMCwweDEwLDB4MTAxMCwweDgwMDAwMTAsMHg4MDAxMDEwLDB4ODAwMTAsMHg4MTAxMCwweDgwODAwMTAsMHg4MDgxMDEwXSwKICAgICAgcGMyYnl0ZXMxMyA9IFswLDB4NCwweDEwMCwweDEwNCwwLDB4NCwweDEwMCwweDEwNCwweDEsMHg1LDB4MTAxLDB4MTA1LDB4MSwweDUsMHgxMDEsMHgxMDVdOwoKICAvLyBob3cgbWFueSBpdGVyYXRpb25zICgxIGZvciBkZXMsIDMgZm9yIHRyaXBsZSBkZXMpCiAgLy8gY2hhbmdlZCBieSBQYXVsIDE2LzYvMjAwNyB0byB1c2UgVHJpcGxlIERFUyBmb3IgOSsgYnl0ZSBrZXlzCiAgdmFyIGl0ZXJhdGlvbnMgPSBrZXkubGVuZ3RoKCkgPiA4ID8gMyA6IDE7CgogIC8vIHN0b3JlcyB0aGUgcmV0dXJuIGtleXMKICB2YXIga2V5cyA9IFtdOwoKICAvLyBub3cgZGVmaW5lIHRoZSBsZWZ0IHNoaWZ0cyB3aGljaCBuZWVkIHRvIGJlIGRvbmUKICB2YXIgc2hpZnRzID0gWzAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDBdOwoKICB2YXIgbiA9IDAsIHRtcDsKICBmb3IodmFyIGogPSAwOyBqIDwgaXRlcmF0aW9uczsgaiArKykgewogICAgdmFyIGxlZnQgPSBrZXkuZ2V0SW50MzIoKTsKICAgIHZhciByaWdodCA9IGtleS5nZXRJbnQzMigpOwoKICAgIHRtcCA9ICgobGVmdCA+Pj4gNCkgXiByaWdodCkgJiAweDBmMGYwZjBmOwogICAgcmlnaHQgXj0gdG1wOwogICAgbGVmdCBePSAodG1wIDw8IDQpOwoKICAgIHRtcCA9ICgocmlnaHQgPj4+IC0xNikgXiBsZWZ0KSAmIDB4MDAwMGZmZmY7CiAgICBsZWZ0IF49IHRtcDsKICAgIHJpZ2h0IF49ICh0bXAgPDwgLTE2KTsKCiAgICB0bXAgPSAoKGxlZnQgPj4+IDIpIF4gcmlnaHQpICYgMHgzMzMzMzMzMzsKICAgIHJpZ2h0IF49IHRtcDsKICAgIGxlZnQgXj0gKHRtcCA8PCAyKTsKCiAgICB0bXAgPSAoKHJpZ2h0ID4+PiAtMTYpIF4gbGVmdCkgJiAweDAwMDBmZmZmOwogICAgbGVmdCBePSB0bXA7CiAgICByaWdodCBePSAodG1wIDw8IC0xNik7CgogICAgdG1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7CiAgICByaWdodCBePSB0bXA7CiAgICBsZWZ0IF49ICh0bXAgPDwgMSk7CgogICAgdG1wID0gKChyaWdodCA+Pj4gOCkgXiBsZWZ0KSAmIDB4MDBmZjAwZmY7CiAgICBsZWZ0IF49IHRtcDsKICAgIHJpZ2h0IF49ICh0bXAgPDwgOCk7CgogICAgdG1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7CiAgICByaWdodCBePSB0bXA7CiAgICBsZWZ0IF49ICh0bXAgPDwgMSk7CgogICAgLy8gcmlnaHQgbmVlZHMgdG8gYmUgc2hpZnRlZCBhbmQgT1InZCB3aXRoIGxhc3QgZm91ciBiaXRzIG9mIGxlZnQKICAgIHRtcCA9IChsZWZ0IDw8IDgpIHwgKChyaWdodCA+Pj4gMjApICYgMHgwMDAwMDBmMCk7CgogICAgLy8gbGVmdCBuZWVkcyB0byBiZSBwdXQgdXBzaWRlIGRvd24KICAgIGxlZnQgPSAoKHJpZ2h0IDw8IDI0KSB8ICgocmlnaHQgPDwgOCkgJiAweGZmMDAwMCkgfAogICAgICAoKHJpZ2h0ID4+PiA4KSAmIDB4ZmYwMCkgfCAoKHJpZ2h0ID4+PiAyNCkgJiAweGYwKSk7CiAgICByaWdodCA9IHRtcDsKCiAgICAvLyBub3cgZ28gdGhyb3VnaCBhbmQgcGVyZm9ybSB0aGVzZSBzaGlmdHMgb24gdGhlIGxlZnQgYW5kIHJpZ2h0IGtleXMKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBzaGlmdHMubGVuZ3RoOyArK2kpIHsKICAgICAgLy9zaGlmdCB0aGUga2V5cyBlaXRoZXIgb25lIG9yIHR3byBiaXRzIHRvIHRoZSBsZWZ0CiAgICAgIGlmKHNoaWZ0c1tpXSkgewogICAgICAgIGxlZnQgPSAobGVmdCA8PCAyKSB8IChsZWZ0ID4+PiAyNik7CiAgICAgICAgcmlnaHQgPSAocmlnaHQgPDwgMikgfCAocmlnaHQgPj4+IDI2KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBsZWZ0ID0gKGxlZnQgPDwgMSkgfCAobGVmdCA+Pj4gMjcpOwogICAgICAgIHJpZ2h0ID0gKHJpZ2h0IDw8IDEpIHwgKHJpZ2h0ID4+PiAyNyk7CiAgICAgIH0KICAgICAgbGVmdCAmPSAtMHhmOwogICAgICByaWdodCAmPSAtMHhmOwoKICAgICAgLy8gbm93IGFwcGx5IFBDLTIsIGluIHN1Y2ggYSB3YXkgdGhhdCBFIGlzIGVhc2llciB3aGVuIGVuY3J5cHRpbmcgb3IKICAgICAgLy8gZGVjcnlwdGluZyB0aGlzIGNvbnZlcnNpb24gd2lsbCBsb29rIGxpa2UgUEMtMiBleGNlcHQgb25seSB0aGUgbGFzdCA2CiAgICAgIC8vIGJpdHMgb2YgZWFjaCBieXRlIGFyZSB1c2VkIHJhdGhlciB0aGFuIDQ4IGNvbnNlY3V0aXZlIGJpdHMgYW5kIHRoZQogICAgICAvLyBvcmRlciBvZiBsaW5lcyB3aWxsIGJlIGFjY29yZGluZyB0byBob3cgdGhlIFMgc2VsZWN0aW9uIGZ1bmN0aW9ucyB3aWxsCiAgICAgIC8vIGJlIGFwcGxpZWQ6IFMyLCBTNCwgUzYsIFM4LCBTMSwgUzMsIFM1LCBTNwogICAgICB2YXIgbGVmdHRtcCA9ICgKICAgICAgICBwYzJieXRlczBbbGVmdCA+Pj4gMjhdIHwgcGMyYnl0ZXMxWyhsZWZ0ID4+PiAyNCkgJiAweGZdIHwKICAgICAgICBwYzJieXRlczJbKGxlZnQgPj4+IDIwKSAmIDB4Zl0gfCBwYzJieXRlczNbKGxlZnQgPj4+IDE2KSAmIDB4Zl0gfAogICAgICAgIHBjMmJ5dGVzNFsobGVmdCA+Pj4gMTIpICYgMHhmXSB8IHBjMmJ5dGVzNVsobGVmdCA+Pj4gOCkgJiAweGZdIHwKICAgICAgICBwYzJieXRlczZbKGxlZnQgPj4+IDQpICYgMHhmXSk7CiAgICAgIHZhciByaWdodHRtcCA9ICgKICAgICAgICBwYzJieXRlczdbcmlnaHQgPj4+IDI4XSB8IHBjMmJ5dGVzOFsocmlnaHQgPj4+IDI0KSAmIDB4Zl0gfAogICAgICAgIHBjMmJ5dGVzOVsocmlnaHQgPj4+IDIwKSAmIDB4Zl0gfCBwYzJieXRlczEwWyhyaWdodCA+Pj4gMTYpICYgMHhmXSB8CiAgICAgICAgcGMyYnl0ZXMxMVsocmlnaHQgPj4+IDEyKSAmIDB4Zl0gfCBwYzJieXRlczEyWyhyaWdodCA+Pj4gOCkgJiAweGZdIHwKICAgICAgICBwYzJieXRlczEzWyhyaWdodCA+Pj4gNCkgJiAweGZdKTsKICAgICAgdG1wID0gKChyaWdodHRtcCA+Pj4gMTYpIF4gbGVmdHRtcCkgJiAweDAwMDBmZmZmOwogICAgICBrZXlzW24rK10gPSBsZWZ0dG1wIF4gdG1wOwogICAgICBrZXlzW24rK10gPSByaWdodHRtcCBeICh0bXAgPDwgMTYpOwogICAgfQogIH0KCiAgcmV0dXJuIGtleXM7Cn0KCi8qKgogKiBVcGRhdGVzIGEgc2luZ2xlIGJsb2NrICgxIGJ5dGUpIHVzaW5nIERFUy4gVGhlIHVwZGF0ZSB3aWxsIGVpdGhlcgogKiBlbmNyeXB0IG9yIGRlY3J5cHQgdGhlIGJsb2NrLgogKgogKiBAcGFyYW0ga2V5cyB0aGUgZXhwYW5kZWQga2V5cy4KICogQHBhcmFtIGlucHV0IHRoZSBpbnB1dCBibG9jayAoYW4gYXJyYXkgb2YgMzItYml0IHdvcmRzKS4KICogQHBhcmFtIG91dHB1dCB0aGUgdXBkYXRlZCBvdXRwdXQgYmxvY2suCiAqIEBwYXJhbSBkZWNyeXB0IHRydWUgdG8gZGVjcnlwdCB0aGUgYmxvY2ssIGZhbHNlIHRvIGVuY3J5cHQgaXQuCiAqLwpmdW5jdGlvbiBfdXBkYXRlQmxvY2soa2V5cywgaW5wdXQsIG91dHB1dCwgZGVjcnlwdCkgewogIC8vIHNldCB1cCBsb29wcyBmb3Igc2luZ2xlIG9yIHRyaXBsZSBERVMKICB2YXIgaXRlcmF0aW9ucyA9IGtleXMubGVuZ3RoID09PSAzMiA/IDMgOiA5OwogIHZhciBsb29waW5nOwogIGlmKGl0ZXJhdGlvbnMgPT09IDMpIHsKICAgIGxvb3BpbmcgPSBkZWNyeXB0ID8gWzMwLCAtMiwgLTJdIDogWzAsIDMyLCAyXTsKICB9IGVsc2UgewogICAgbG9vcGluZyA9IChkZWNyeXB0ID8KICAgICAgWzk0LCA2MiwgLTIsIDMyLCA2NCwgMiwgMzAsIC0yLCAtMl0gOgogICAgICBbMCwgMzIsIDIsIDYyLCAzMCwgLTIsIDY0LCA5NiwgMl0pOwogIH0KCiAgdmFyIHRtcDsKCiAgdmFyIGxlZnQgPSBpbnB1dFswXTsKICB2YXIgcmlnaHQgPSBpbnB1dFsxXTsKCiAgLy8gZmlyc3QgZWFjaCA2NCBiaXQgY2h1bmsgb2YgdGhlIG1lc3NhZ2UgbXVzdCBiZSBwZXJtdXRlZCBhY2NvcmRpbmcgdG8gSVAKICB0bXAgPSAoKGxlZnQgPj4+IDQpIF4gcmlnaHQpICYgMHgwZjBmMGYwZjsKICByaWdodCBePSB0bXA7CiAgbGVmdCBePSAodG1wIDw8IDQpOwoKICB0bXAgPSAoKGxlZnQgPj4+IDE2KSBeIHJpZ2h0KSAmIDB4MDAwMGZmZmY7CiAgcmlnaHQgXj0gdG1wOwogIGxlZnQgXj0gKHRtcCA8PCAxNik7CgogIHRtcCA9ICgocmlnaHQgPj4+IDIpIF4gbGVmdCkgJiAweDMzMzMzMzMzOwogIGxlZnQgXj0gdG1wOwogIHJpZ2h0IF49ICh0bXAgPDwgMik7CgogIHRtcCA9ICgocmlnaHQgPj4+IDgpIF4gbGVmdCkgJiAweDAwZmYwMGZmOwogIGxlZnQgXj0gdG1wOwogIHJpZ2h0IF49ICh0bXAgPDwgOCk7CgogIHRtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1OwogIHJpZ2h0IF49IHRtcDsKICBsZWZ0IF49ICh0bXAgPDwgMSk7CgogIC8vIHJvdGF0ZSBsZWZ0IDEgYml0CiAgbGVmdCA9ICgobGVmdCA8PCAxKSB8IChsZWZ0ID4+PiAzMSkpOwogIHJpZ2h0ID0gKChyaWdodCA8PCAxKSB8IChyaWdodCA+Pj4gMzEpKTsKCiAgZm9yKHZhciBqID0gMDsgaiA8IGl0ZXJhdGlvbnM7IGogKz0gMykgewogICAgdmFyIGVuZGxvb3AgPSBsb29waW5nW2ogKyAxXTsKICAgIHZhciBsb29waW5jID0gbG9vcGluZ1tqICsgMl07CgogICAgLy8gbm93IGdvIHRocm91Z2ggYW5kIHBlcmZvcm0gdGhlIGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbgogICAgZm9yKHZhciBpID0gbG9vcGluZ1tqXTsgaSAhPSBlbmRsb29wOyBpICs9IGxvb3BpbmMpIHsKICAgICAgdmFyIHJpZ2h0MSA9IHJpZ2h0IF4ga2V5c1tpXTsKICAgICAgdmFyIHJpZ2h0MiA9ICgocmlnaHQgPj4+IDQpIHwgKHJpZ2h0IDw8IDI4KSkgXiBrZXlzW2kgKyAxXTsKCiAgICAgIC8vIHBhc3NpbmcgdGhlc2UgYnl0ZXMgdGhyb3VnaCB0aGUgUyBzZWxlY3Rpb24gZnVuY3Rpb25zCiAgICAgIHRtcCA9IGxlZnQ7CiAgICAgIGxlZnQgPSByaWdodDsKICAgICAgcmlnaHQgPSB0bXAgXiAoCiAgICAgICAgc3BmdW5jdGlvbjJbKHJpZ2h0MSA+Pj4gMjQpICYgMHgzZl0gfAogICAgICAgIHNwZnVuY3Rpb240WyhyaWdodDEgPj4+IDE2KSAmIDB4M2ZdIHwKICAgICAgICBzcGZ1bmN0aW9uNlsocmlnaHQxID4+PiAgOCkgJiAweDNmXSB8CiAgICAgICAgc3BmdW5jdGlvbjhbcmlnaHQxICYgMHgzZl0gfAogICAgICAgIHNwZnVuY3Rpb24xWyhyaWdodDIgPj4+IDI0KSAmIDB4M2ZdIHwKICAgICAgICBzcGZ1bmN0aW9uM1socmlnaHQyID4+PiAxNikgJiAweDNmXSB8CiAgICAgICAgc3BmdW5jdGlvbjVbKHJpZ2h0MiA+Pj4gIDgpICYgMHgzZl0gfAogICAgICAgIHNwZnVuY3Rpb243W3JpZ2h0MiAmIDB4M2ZdKTsKICAgIH0KICAgIC8vIHVucmV2ZXJzZSBsZWZ0IGFuZCByaWdodAogICAgdG1wID0gbGVmdDsKICAgIGxlZnQgPSByaWdodDsKICAgIHJpZ2h0ID0gdG1wOwogIH0KCiAgLy8gcm90YXRlIHJpZ2h0IDEgYml0CiAgbGVmdCA9ICgobGVmdCA+Pj4gMSkgfCAobGVmdCA8PCAzMSkpOwogIHJpZ2h0ID0gKChyaWdodCA+Pj4gMSkgfCAocmlnaHQgPDwgMzEpKTsKCiAgLy8gbm93IHBlcmZvcm0gSVAtMSwgd2hpY2ggaXMgSVAgaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvbgogIHRtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1OwogIHJpZ2h0IF49IHRtcDsKICBsZWZ0IF49ICh0bXAgPDwgMSk7CgogIHRtcCA9ICgocmlnaHQgPj4+IDgpIF4gbGVmdCkgJiAweDAwZmYwMGZmOwogIGxlZnQgXj0gdG1wOwogIHJpZ2h0IF49ICh0bXAgPDwgOCk7CgogIHRtcCA9ICgocmlnaHQgPj4+IDIpIF4gbGVmdCkgJiAweDMzMzMzMzMzOwogIGxlZnQgXj0gdG1wOwogIHJpZ2h0IF49ICh0bXAgPDwgMik7CgogIHRtcCA9ICgobGVmdCA+Pj4gMTYpIF4gcmlnaHQpICYgMHgwMDAwZmZmZjsKICByaWdodCBePSB0bXA7CiAgbGVmdCBePSAodG1wIDw8IDE2KTsKCiAgdG1wID0gKChsZWZ0ID4+PiA0KSBeIHJpZ2h0KSAmIDB4MGYwZjBmMGY7CiAgcmlnaHQgXj0gdG1wOwogIGxlZnQgXj0gKHRtcCA8PCA0KTsKCiAgb3V0cHV0WzBdID0gbGVmdDsKICBvdXRwdXRbMV0gPSByaWdodDsKfQoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogZm9yZ2UuY2lwaGVyLmNyZWF0ZUNpcGhlcignREVTLTxtb2RlPicsIGtleSk7CiAqIGZvcmdlLmNpcGhlci5jcmVhdGVEZWNpcGhlcignREVTLTxtb2RlPicsIGtleSk7CiAqCiAqIENyZWF0ZXMgYSBkZXByZWNhdGVkIERFUyBjaXBoZXIgb2JqZWN0LiBUaGlzIG9iamVjdCdzIG1vZGUgd2lsbCBkZWZhdWx0IHRvCiAqIENCQyAoY2lwaGVyLWJsb2NrLWNoYWluaW5nKS4KICoKICogVGhlIGtleSBtYXkgYmUgZ2l2ZW4gYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMgb3IgYSBieXRlIGJ1ZmZlci4KICoKICogQHBhcmFtIG9wdGlvbnMgdGhlIG9wdGlvbnMgdG8gdXNlLgogKiAgICAgICAgICBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlICg2NCBvciAxOTIgYml0cykuCiAqICAgICAgICAgIG91dHB1dCB0aGUgYnVmZmVyIHRvIHdyaXRlIHRvLgogKiAgICAgICAgICBkZWNyeXB0IHRydWUgZm9yIGRlY3J5cHRpb24sIGZhbHNlIGZvciBlbmNyeXB0aW9uLgogKiAgICAgICAgICBtb2RlIHRoZSBjaXBoZXIgbW9kZSB0byB1c2UgKGRlZmF1bHQ6ICdDQkMnKS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZnVuY3Rpb24gX2NyZWF0ZUNpcGhlcihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdmFyIG1vZGUgPSAob3B0aW9ucy5tb2RlIHx8ICdDQkMnKS50b1VwcGVyQ2FzZSgpOwogIHZhciBhbGdvcml0aG0gPSAnREVTLScgKyBtb2RlOwoKICB2YXIgY2lwaGVyOwogIGlmKG9wdGlvbnMuZGVjcnlwdCkgewogICAgY2lwaGVyID0gZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKGFsZ29yaXRobSwgb3B0aW9ucy5rZXkpOwogIH0gZWxzZSB7CiAgICBjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKGFsZ29yaXRobSwgb3B0aW9ucy5rZXkpOwogIH0KCiAgLy8gYmFja3dhcmRzIGNvbXBhdGlibGUgc3RhcnQgQVBJCiAgdmFyIHN0YXJ0ID0gY2lwaGVyLnN0YXJ0OwogIGNpcGhlci5zdGFydCA9IGZ1bmN0aW9uKGl2LCBvcHRpb25zKSB7CiAgICAvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eTogc3VwcG9ydCBzZWNvbmQgYXJnIGFzIG91dHB1dCBidWZmZXIKICAgIHZhciBvdXRwdXQgPSBudWxsOwogICAgaWYob3B0aW9ucyBpbnN0YW5jZW9mIGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcikgewogICAgICBvdXRwdXQgPSBvcHRpb25zOwogICAgICBvcHRpb25zID0ge307CiAgICB9CiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICAgIG9wdGlvbnMub3V0cHV0ID0gb3V0cHV0OwogICAgb3B0aW9ucy5pdiA9IGl2OwogICAgc3RhcnQuY2FsbChjaXBoZXIsIG9wdGlvbnMpOwogIH07CgogIHJldHVybiBjaXBoZXI7Cn0KCgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdkZXMnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgKICAnanMvZGVzJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vY2lwaGVyJywgJy4vY2lwaGVyTW9kZXMnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFBhc3N3b3JkLUJhc2VkIEtleS1EZXJpdmF0aW9uIEZ1bmN0aW9uICMyIGltcGxlbWVudGF0aW9uLgogKgogKiBTZWUgUkZDIDI4OTggZm9yIGRldGFpbHMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEzIERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKdmFyIHBrY3M1ID0gZm9yZ2UucGtjczUgPSBmb3JnZS5wa2NzNSB8fCB7fTsKCnZhciBfbm9kZWpzID0gKAogIHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb25zICYmIHByb2Nlc3MudmVyc2lvbnMubm9kZSk7CnZhciBjcnlwdG87CmlmKF9ub2RlanMgJiYgIWZvcmdlLmRpc2FibGVOYXRpdmVDb2RlKSB7CiAgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7Cn0KCi8qKgogKiBEZXJpdmVzIGEga2V5IGZyb20gYSBwYXNzd29yZC4KICoKICogQHBhcmFtIHAgdGhlIHBhc3N3b3JkIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogKiBAcGFyYW0gcyB0aGUgc2FsdCBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBieXRlcy4KICogQHBhcmFtIGMgdGhlIGl0ZXJhdGlvbiBjb3VudCwgYSBwb3NpdGl2ZSBpbnRlZ2VyLgogKiBAcGFyYW0gZGtMZW4gdGhlIGludGVuZGVkIGxlbmd0aCwgaW4gYnl0ZXMsIG9mIHRoZSBkZXJpdmVkIGtleSwKICogICAgICAgICAgKG1heDogMl4zMiAtIDEpICogaGFzaCBsZW5ndGggb2YgdGhlIFBSRi4KICogQHBhcmFtIFttZF0gdGhlIG1lc3NhZ2UgZGlnZXN0IChvciBhbGdvcml0aG0gaWRlbnRpZmllciBhcyBhIHN0cmluZykgdG8gdXNlCiAqICAgICAgICAgIGluIHRoZSBQUkYsIGRlZmF1bHRzIHRvIFNIQS0xLgogKiBAcGFyYW0gW2NhbGxiYWNrKGVyciwga2V5KV0gcHJlc2VuY2UgdHJpZ2dlcnMgYXN5bmNocm9ub3VzIHZlcnNpb24sIGNhbGxlZAogKiAgICAgICAgICBvbmNlIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLgogKgogKiBAcmV0dXJuIHRoZSBkZXJpdmVkIGtleSwgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMsIGZvciB0aGUKICogICAgICAgICAgIHN5bmNocm9ub3VzIHZlcnNpb24gKGlmIG5vIGNhbGxiYWNrIGlzIHNwZWNpZmllZCkuCiAqLwpmb3JnZS5wYmtkZjIgPSBwa2NzNS5wYmtkZjIgPSBmdW5jdGlvbihwLCBzLCBjLCBka0xlbiwgbWQsIGNhbGxiYWNrKSB7CiAgaWYodHlwZW9mIG1kID09PSAnZnVuY3Rpb24nKSB7CiAgICBjYWxsYmFjayA9IG1kOwogICAgbWQgPSBudWxsOwogIH0KCiAgLy8gdXNlIG5hdGl2ZSBpbXBsZW1lbnRhdGlvbiBpZiBwb3NzaWJsZSBhbmQgbm90IGRpc2FibGVkLCBub3RlIHRoYXQKICAvLyBzb21lIG5vZGUgdmVyc2lvbnMgb25seSBzdXBwb3J0IFNIQS0xLCBvdGhlcnMgYWxsb3cgZGlnZXN0IHRvIGJlIGNoYW5nZWQKICBpZihfbm9kZWpzICYmICFmb3JnZS5kaXNhYmxlTmF0aXZlQ29kZSAmJiBjcnlwdG8ucGJrZGYyICYmCiAgICAobWQgPT09IG51bGwgfHwgdHlwZW9mIG1kICE9PSAnb2JqZWN0JykgJiYKICAgIChjcnlwdG8ucGJrZGYyU3luYy5sZW5ndGggPiA0IHx8ICghbWQgfHwgbWQgPT09ICdzaGExJykpKSB7CiAgICBpZih0eXBlb2YgbWQgIT09ICdzdHJpbmcnKSB7CiAgICAgIC8vIGRlZmF1bHQgcHJmIHRvIFNIQS0xCiAgICAgIG1kID0gJ3NoYTEnOwogICAgfQogICAgcyA9IG5ldyBCdWZmZXIocywgJ2JpbmFyeScpOwogICAgaWYoIWNhbGxiYWNrKSB7CiAgICAgIGlmKGNyeXB0by5wYmtkZjJTeW5jLmxlbmd0aCA9PT0gNCkgewogICAgICAgIHJldHVybiBjcnlwdG8ucGJrZGYyU3luYyhwLCBzLCBjLCBka0xlbikudG9TdHJpbmcoJ2JpbmFyeScpOwogICAgICB9CiAgICAgIHJldHVybiBjcnlwdG8ucGJrZGYyU3luYyhwLCBzLCBjLCBka0xlbiwgbWQpLnRvU3RyaW5nKCdiaW5hcnknKTsKICAgIH0KICAgIGlmKGNyeXB0by5wYmtkZjJTeW5jLmxlbmd0aCA9PT0gNCkgewogICAgICByZXR1cm4gY3J5cHRvLnBia2RmMihwLCBzLCBjLCBka0xlbiwgZnVuY3Rpb24oZXJyLCBrZXkpIHsKICAgICAgICBpZihlcnIpIHsKICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpOwogICAgICAgIH0KICAgICAgICBjYWxsYmFjayhudWxsLCBrZXkudG9TdHJpbmcoJ2JpbmFyeScpKTsKICAgICAgfSk7CiAgICB9CiAgICByZXR1cm4gY3J5cHRvLnBia2RmMihwLCBzLCBjLCBka0xlbiwgbWQsIGZ1bmN0aW9uKGVyciwga2V5KSB7CiAgICAgIGlmKGVycikgewogICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpOwogICAgICB9CiAgICAgIGNhbGxiYWNrKG51bGwsIGtleS50b1N0cmluZygnYmluYXJ5JykpOwogICAgfSk7CiAgfQoKICBpZih0eXBlb2YgbWQgPT09ICd1bmRlZmluZWQnIHx8IG1kID09PSBudWxsKSB7CiAgICAvLyBkZWZhdWx0IHByZiB0byBTSEEtMQogICAgbWQgPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogIH0KICBpZih0eXBlb2YgbWQgPT09ICdzdHJpbmcnKSB7CiAgICBpZighKG1kIGluIGZvcmdlLm1kLmFsZ29yaXRobXMpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBoYXNoIGFsZ29yaXRobTogJyArIG1kKTsKICAgIH0KICAgIG1kID0gZm9yZ2UubWRbbWRdLmNyZWF0ZSgpOwogIH0KCiAgdmFyIGhMZW4gPSBtZC5kaWdlc3RMZW5ndGg7CgogIC8qIDEuIElmIGRrTGVuID4gKDJeMzIgLSAxKSAqIGhMZW4sIG91dHB1dCAiZGVyaXZlZCBrZXkgdG9vIGxvbmciIGFuZAogICAgc3RvcC4gKi8KICBpZihka0xlbiA+ICgweEZGRkZGRkZGICogaExlbikpIHsKICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ0Rlcml2ZWQga2V5IGlzIHRvbyBsb25nLicpOwogICAgaWYoY2FsbGJhY2spIHsKICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7CiAgICB9CiAgICB0aHJvdyBlcnI7CiAgfQoKICAvKiAyLiBMZXQgbGVuIGJlIHRoZSBudW1iZXIgb2YgaExlbi1vY3RldCBibG9ja3MgaW4gdGhlIGRlcml2ZWQga2V5LAogICAgcm91bmRpbmcgdXAsIGFuZCBsZXQgciBiZSB0aGUgbnVtYmVyIG9mIG9jdGV0cyBpbiB0aGUgbGFzdAogICAgYmxvY2s6CgogICAgbGVuID0gQ0VJTChka0xlbiAvIGhMZW4pLAogICAgciA9IGRrTGVuIC0gKGxlbiAtIDEpICogaExlbi4gKi8KICB2YXIgbGVuID0gTWF0aC5jZWlsKGRrTGVuIC8gaExlbik7CiAgdmFyIHIgPSBka0xlbiAtIChsZW4gLSAxKSAqIGhMZW47CgogIC8qIDMuIEZvciBlYWNoIGJsb2NrIG9mIHRoZSBkZXJpdmVkIGtleSBhcHBseSB0aGUgZnVuY3Rpb24gRiBkZWZpbmVkCiAgICBiZWxvdyB0byB0aGUgcGFzc3dvcmQgUCwgdGhlIHNhbHQgUywgdGhlIGl0ZXJhdGlvbiBjb3VudCBjLCBhbmQKICAgIHRoZSBibG9jayBpbmRleCB0byBjb21wdXRlIHRoZSBibG9jazoKCiAgICBUXzEgPSBGKFAsIFMsIGMsIDEpLAogICAgVF8yID0gRihQLCBTLCBjLCAyKSwKICAgIC4uLgogICAgVF9sZW4gPSBGKFAsIFMsIGMsIGxlbiksCgogICAgd2hlcmUgdGhlIGZ1bmN0aW9uIEYgaXMgZGVmaW5lZCBhcyB0aGUgZXhjbHVzaXZlLW9yIHN1bSBvZiB0aGUKICAgIGZpcnN0IGMgaXRlcmF0ZXMgb2YgdGhlIHVuZGVybHlpbmcgcHNldWRvcmFuZG9tIGZ1bmN0aW9uIFBSRgogICAgYXBwbGllZCB0byB0aGUgcGFzc3dvcmQgUCBhbmQgdGhlIGNvbmNhdGVuYXRpb24gb2YgdGhlIHNhbHQgUwogICAgYW5kIHRoZSBibG9jayBpbmRleCBpOgoKICAgIEYoUCwgUywgYywgaSkgPSB1XzEgWE9SIHVfMiBYT1IgLi4uIFhPUiB1X2MKCiAgICB3aGVyZQoKICAgIHVfMSA9IFBSRihQLCBTIHx8IElOVChpKSksCiAgICB1XzIgPSBQUkYoUCwgdV8xKSwKICAgIC4uLgogICAgdV9jID0gUFJGKFAsIHVfe2MtMX0pLgoKICAgIEhlcmUsIElOVChpKSBpcyBhIGZvdXItb2N0ZXQgZW5jb2Rpbmcgb2YgdGhlIGludGVnZXIgaSwgbW9zdAogICAgc2lnbmlmaWNhbnQgb2N0ZXQgZmlyc3QuICovCiAgdmFyIHByZiA9IGZvcmdlLmhtYWMuY3JlYXRlKCk7CiAgcHJmLnN0YXJ0KG1kLCBwKTsKICB2YXIgZGsgPSAnJzsKICB2YXIgeG9yLCB1X2MsIHVfYzE7CgogIC8vIHN5bmMgdmVyc2lvbgogIGlmKCFjYWxsYmFjaykgewogICAgZm9yKHZhciBpID0gMTsgaSA8PSBsZW47ICsraSkgewogICAgICAvLyBQUkYoUCwgUyB8fCBJTlQoaSkpIChmaXJzdCBpdGVyYXRpb24pCiAgICAgIHByZi5zdGFydChudWxsLCBudWxsKTsKICAgICAgcHJmLnVwZGF0ZShzKTsKICAgICAgcHJmLnVwZGF0ZShmb3JnZS51dGlsLmludDMyVG9CeXRlcyhpKSk7CiAgICAgIHhvciA9IHVfYzEgPSBwcmYuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKCiAgICAgIC8vIFBSRihQLCB1X3tjLTF9KSAob3RoZXIgaXRlcmF0aW9ucykKICAgICAgZm9yKHZhciBqID0gMjsgaiA8PSBjOyArK2opIHsKICAgICAgICBwcmYuc3RhcnQobnVsbCwgbnVsbCk7CiAgICAgICAgcHJmLnVwZGF0ZSh1X2MxKTsKICAgICAgICB1X2MgPSBwcmYuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKICAgICAgICAvLyBGKHAsIHMsIGMsIGkpCiAgICAgICAgeG9yID0gZm9yZ2UudXRpbC54b3JCeXRlcyh4b3IsIHVfYywgaExlbik7CiAgICAgICAgdV9jMSA9IHVfYzsKICAgICAgfQoKICAgICAgLyogNC4gQ29uY2F0ZW5hdGUgdGhlIGJsb2NrcyBhbmQgZXh0cmFjdCB0aGUgZmlyc3QgZGtMZW4gb2N0ZXRzIHRvCiAgICAgICAgcHJvZHVjZSBhIGRlcml2ZWQga2V5IERLOgoKICAgICAgICBESyA9IFRfMSB8fCBUXzIgfHwgIC4uLiAgfHwgVF9sZW48MC4uci0xPiAqLwogICAgICBkayArPSAoaSA8IGxlbikgPyB4b3IgOiB4b3Iuc3Vic3RyKDAsIHIpOwogICAgfQogICAgLyogNS4gT3V0cHV0IHRoZSBkZXJpdmVkIGtleSBESy4gKi8KICAgIHJldHVybiBkazsKICB9CgogIC8vIGFzeW5jIHZlcnNpb24KICB2YXIgaSA9IDEsIGo7CiAgZnVuY3Rpb24gb3V0ZXIoKSB7CiAgICBpZihpID4gbGVuKSB7CiAgICAgIC8vIGRvbmUKICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGRrKTsKICAgIH0KCiAgICAvLyBQUkYoUCwgUyB8fCBJTlQoaSkpIChmaXJzdCBpdGVyYXRpb24pCiAgICBwcmYuc3RhcnQobnVsbCwgbnVsbCk7CiAgICBwcmYudXBkYXRlKHMpOwogICAgcHJmLnVwZGF0ZShmb3JnZS51dGlsLmludDMyVG9CeXRlcyhpKSk7CiAgICB4b3IgPSB1X2MxID0gcHJmLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CgogICAgLy8gUFJGKFAsIHVfe2MtMX0pIChvdGhlciBpdGVyYXRpb25zKQogICAgaiA9IDI7CiAgICBpbm5lcigpOwogIH0KCiAgZnVuY3Rpb24gaW5uZXIoKSB7CiAgICBpZihqIDw9IGMpIHsKICAgICAgcHJmLnN0YXJ0KG51bGwsIG51bGwpOwogICAgICBwcmYudXBkYXRlKHVfYzEpOwogICAgICB1X2MgPSBwcmYuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKICAgICAgLy8gRihwLCBzLCBjLCBpKQogICAgICB4b3IgPSBmb3JnZS51dGlsLnhvckJ5dGVzKHhvciwgdV9jLCBoTGVuKTsKICAgICAgdV9jMSA9IHVfYzsKICAgICAgKytqOwogICAgICByZXR1cm4gZm9yZ2UudXRpbC5zZXRJbW1lZGlhdGUoaW5uZXIpOwogICAgfQoKICAgIC8qIDQuIENvbmNhdGVuYXRlIHRoZSBibG9ja3MgYW5kIGV4dHJhY3QgdGhlIGZpcnN0IGRrTGVuIG9jdGV0cyB0bwogICAgICBwcm9kdWNlIGEgZGVyaXZlZCBrZXkgREs6CgogICAgICBESyA9IFRfMSB8fCBUXzIgfHwgIC4uLiAgfHwgVF9sZW48MC4uci0xPiAqLwogICAgZGsgKz0gKGkgPCBsZW4pID8geG9yIDogeG9yLnN1YnN0cigwLCByKTsKCiAgICArK2k7CiAgICBvdXRlcigpOwogIH0KCiAgb3V0ZXIoKTsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3Bia2RmMic7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9wYmtkZjInLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9obWFjJywgJy4vbWQnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEEgamF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBhIGNyeXB0b2dyYXBoaWNhbGx5LXNlY3VyZQogKiBQc2V1ZG8gUmFuZG9tIE51bWJlciBHZW5lcmF0b3IgKFBSTkcpLiBUaGUgRm9ydHVuYSBhbGdvcml0aG0gaXMgZm9sbG93ZWQKICogaGVyZSB0aG91Z2ggdGhlIHVzZSBvZiBTSEEtMjU2IGlzIG5vdCBlbmZvcmNlZDsgd2hlbiBnZW5lcmF0aW5nIGFuCiAqIGEgUFJORyBjb250ZXh0LCB0aGUgaGFzaGluZyBhbGdvcml0aG0gYW5kIGJsb2NrIGNpcGhlciB1c2VkIGZvcgogKiB0aGUgZ2VuZXJhdG9yIGFyZSBzcGVjaWZpZWQgdmlhIGEgcGx1Z2luLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCnZhciBfbm9kZWpzID0gKAogIHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb25zICYmIHByb2Nlc3MudmVyc2lvbnMubm9kZSk7CnZhciBfY3J5cHRvID0gbnVsbDsKaWYoIWZvcmdlLmRpc2FibGVOYXRpdmVDb2RlICYmIF9ub2RlanMgJiYgIXByb2Nlc3MudmVyc2lvbnNbJ25vZGUtd2Via2l0J10pIHsKICBfY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7Cn0KCi8qIFBSTkcgQVBJICovCnZhciBwcm5nID0gZm9yZ2UucHJuZyA9IGZvcmdlLnBybmcgfHwge307CgovKioKICogQ3JlYXRlcyBhIG5ldyBQUk5HIGNvbnRleHQuCiAqCiAqIEEgUFJORyBwbHVnaW4gbXVzdCBiZSBwYXNzZWQgaW4gdGhhdCB3aWxsIHByb3ZpZGU6CiAqCiAqIDEuIEEgZnVuY3Rpb24gdGhhdCBpbml0aWFsaXplcyB0aGUga2V5IGFuZCBzZWVkIG9mIGEgUFJORyBjb250ZXh0LiBJdAogKiAgIHdpbGwgYmUgZ2l2ZW4gYSAxNiBieXRlIGtleSBhbmQgYSAxNiBieXRlIHNlZWQuIEFueSBrZXkgZXhwYW5zaW9uCiAqICAgb3IgdHJhbnNmb3JtYXRpb24gb2YgdGhlIHNlZWQgZnJvbSBhIGJ5dGUgc3RyaW5nIGludG8gYW4gYXJyYXkgb2YKICogICBpbnRlZ2VycyAob3Igc2ltaWxhcikgc2hvdWxkIGJlIHBlcmZvcm1lZC4KICogMi4gVGhlIGNyeXB0b2dyYXBoaWMgZnVuY3Rpb24gdXNlZCBieSB0aGUgZ2VuZXJhdG9yLiBJdCB0YWtlcyBhIGtleSBhbmQKICogICBhIHNlZWQuCiAqIDMuIEEgc2VlZCBpbmNyZW1lbnQgZnVuY3Rpb24uIEl0IHRha2VzIHRoZSBzZWVkIGFuZCByZXR1cm5zIHNlZWQgKyAxLgogKiA0LiBBbiBhcGkgdG8gY3JlYXRlIGEgbWVzc2FnZSBkaWdlc3QuCiAqCiAqIEZvciBhbiBleGFtcGxlLCBzZWUgcmFuZG9tLmpzLgogKgogKiBAcGFyYW0gcGx1Z2luIHRoZSBQUk5HIHBsdWdpbiB0byB1c2UuCiAqLwpwcm5nLmNyZWF0ZSA9IGZ1bmN0aW9uKHBsdWdpbikgewogIHZhciBjdHggPSB7CiAgICBwbHVnaW46IHBsdWdpbiwKICAgIGtleTogbnVsbCwKICAgIHNlZWQ6IG51bGwsCiAgICB0aW1lOiBudWxsLAogICAgLy8gbnVtYmVyIG9mIHJlc2VlZHMgc28gZmFyCiAgICByZXNlZWRzOiAwLAogICAgLy8gYW1vdW50IG9mIGRhdGEgZ2VuZXJhdGVkIHNvIGZhcgogICAgZ2VuZXJhdGVkOiAwCiAgfTsKCiAgLy8gY3JlYXRlIDMyIGVudHJvcHkgcG9vbHMgKGVhY2ggaXMgYSBtZXNzYWdlIGRpZ2VzdCkKICB2YXIgbWQgPSBwbHVnaW4ubWQ7CiAgdmFyIHBvb2xzID0gbmV3IEFycmF5KDMyKTsKICBmb3IodmFyIGkgPSAwOyBpIDwgMzI7ICsraSkgewogICAgcG9vbHNbaV0gPSBtZC5jcmVhdGUoKTsKICB9CiAgY3R4LnBvb2xzID0gcG9vbHM7CgogIC8vIGVudHJvcHkgcG9vbHMgYXJlIHdyaXR0ZW4gdG8gY3ljbGljYWxseSwgc3RhcnRpbmcgYXQgaW5kZXggMAogIGN0eC5wb29sID0gMDsKCiAgLyoqCiAgICogR2VuZXJhdGVzIHJhbmRvbSBieXRlcy4gVGhlIGJ5dGVzIG1heSBiZSBnZW5lcmF0ZWQgc3luY2hyb25vdXNseSBvcgogICAqIGFzeW5jaHJvbm91c2x5LiBXZWIgd29ya2VycyBtdXN0IHVzZSB0aGUgYXN5bmNocm9ub3VzIGludGVyZmFjZSBvcgogICAqIGVsc2UgdGhlIGJlaGF2aW9yIGlzIHVuZGVmaW5lZC4KICAgKgogICAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIHJhbmRvbSBieXRlcyB0byBnZW5lcmF0ZS4KICAgKiBAcGFyYW0gW2NhbGxiYWNrKGVyciwgYnl0ZXMpXSBjYWxsZWQgb25jZSB0aGUgb3BlcmF0aW9uIGNvbXBsZXRlcy4KICAgKgogICAqIEByZXR1cm4gY291bnQgcmFuZG9tIGJ5dGVzIGFzIGEgc3RyaW5nLgogICAqLwogIGN0eC5nZW5lcmF0ZSA9IGZ1bmN0aW9uKGNvdW50LCBjYWxsYmFjaykgewogICAgLy8gZG8gc3luY2hyb25vdXNseQogICAgaWYoIWNhbGxiYWNrKSB7CiAgICAgIHJldHVybiBjdHguZ2VuZXJhdGVTeW5jKGNvdW50KTsKICAgIH0KCiAgICAvLyBzaW1wbGUgZ2VuZXJhdG9yIHVzaW5nIGNvdW50ZXItYmFzZWQgQ0JDCiAgICB2YXIgY2lwaGVyID0gY3R4LnBsdWdpbi5jaXBoZXI7CiAgICB2YXIgaW5jcmVtZW50ID0gY3R4LnBsdWdpbi5pbmNyZW1lbnQ7CiAgICB2YXIgZm9ybWF0S2V5ID0gY3R4LnBsdWdpbi5mb3JtYXRLZXk7CiAgICB2YXIgZm9ybWF0U2VlZCA9IGN0eC5wbHVnaW4uZm9ybWF0U2VlZDsKICAgIHZhciBiID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKCiAgICAvLyByZXNldCBrZXkgZm9yIGV2ZXJ5IHJlcXVlc3QKICAgIGN0eC5rZXkgPSBudWxsOwoKICAgIGdlbmVyYXRlKCk7CgogICAgZnVuY3Rpb24gZ2VuZXJhdGUoZXJyKSB7CiAgICAgIGlmKGVycikgewogICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpOwogICAgICB9CgogICAgICAvLyBzdWZmaWNpZW50IGJ5dGVzIGdlbmVyYXRlZAogICAgICBpZihiLmxlbmd0aCgpID49IGNvdW50KSB7CiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGIuZ2V0Qnl0ZXMoY291bnQpKTsKICAgICAgfQoKICAgICAgLy8gaWYgYW1vdW50IG9mIGRhdGEgZ2VuZXJhdGVkIGlzIGdyZWF0ZXIgdGhhbiAxIE1pQiwgdHJpZ2dlciByZXNlZWQKICAgICAgaWYoY3R4LmdlbmVyYXRlZCA+IDB4ZmZmZmYpIHsKICAgICAgICBjdHgua2V5ID0gbnVsbDsKICAgICAgfQoKICAgICAgaWYoY3R4LmtleSA9PT0gbnVsbCkgewogICAgICAgIC8vIHByZXZlbnQgc3RhY2sgb3ZlcmZsb3cKICAgICAgICByZXR1cm4gZm9yZ2UudXRpbC5uZXh0VGljayhmdW5jdGlvbigpIHsKICAgICAgICAgIF9yZXNlZWQoZ2VuZXJhdGUpOwogICAgICAgIH0pOwogICAgICB9CgogICAgICAvLyBnZW5lcmF0ZSB0aGUgcmFuZG9tIGJ5dGVzCiAgICAgIHZhciBieXRlcyA9IGNpcGhlcihjdHgua2V5LCBjdHguc2VlZCk7CiAgICAgIGN0eC5nZW5lcmF0ZWQgKz0gYnl0ZXMubGVuZ3RoOwogICAgICBiLnB1dEJ5dGVzKGJ5dGVzKTsKCiAgICAgIC8vIGdlbmVyYXRlIGJ5dGVzIGZvciBhIG5ldyBrZXkgYW5kIHNlZWQKICAgICAgY3R4LmtleSA9IGZvcm1hdEtleShjaXBoZXIoY3R4LmtleSwgaW5jcmVtZW50KGN0eC5zZWVkKSkpOwogICAgICBjdHguc2VlZCA9IGZvcm1hdFNlZWQoY2lwaGVyKGN0eC5rZXksIGN0eC5zZWVkKSk7CgogICAgICBmb3JnZS51dGlsLnNldEltbWVkaWF0ZShnZW5lcmF0ZSk7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogR2VuZXJhdGVzIHJhbmRvbSBieXRlcyBzeW5jaHJvbm91c2x5LgogICAqCiAgICogQHBhcmFtIGNvdW50IHRoZSBudW1iZXIgb2YgcmFuZG9tIGJ5dGVzIHRvIGdlbmVyYXRlLgogICAqCiAgICogQHJldHVybiBjb3VudCByYW5kb20gYnl0ZXMgYXMgYSBzdHJpbmcuCiAgICovCiAgY3R4LmdlbmVyYXRlU3luYyA9IGZ1bmN0aW9uKGNvdW50KSB7CiAgICAvLyBzaW1wbGUgZ2VuZXJhdG9yIHVzaW5nIGNvdW50ZXItYmFzZWQgQ0JDCiAgICB2YXIgY2lwaGVyID0gY3R4LnBsdWdpbi5jaXBoZXI7CiAgICB2YXIgaW5jcmVtZW50ID0gY3R4LnBsdWdpbi5pbmNyZW1lbnQ7CiAgICB2YXIgZm9ybWF0S2V5ID0gY3R4LnBsdWdpbi5mb3JtYXRLZXk7CiAgICB2YXIgZm9ybWF0U2VlZCA9IGN0eC5wbHVnaW4uZm9ybWF0U2VlZDsKCiAgICAvLyByZXNldCBrZXkgZm9yIGV2ZXJ5IHJlcXVlc3QKICAgIGN0eC5rZXkgPSBudWxsOwoKICAgIHZhciBiID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIHdoaWxlKGIubGVuZ3RoKCkgPCBjb3VudCkgewogICAgICAvLyBpZiBhbW91bnQgb2YgZGF0YSBnZW5lcmF0ZWQgaXMgZ3JlYXRlciB0aGFuIDEgTWlCLCB0cmlnZ2VyIHJlc2VlZAogICAgICBpZihjdHguZ2VuZXJhdGVkID4gMHhmZmZmZikgewogICAgICAgIGN0eC5rZXkgPSBudWxsOwogICAgICB9CgogICAgICBpZihjdHgua2V5ID09PSBudWxsKSB7CiAgICAgICAgX3Jlc2VlZFN5bmMoKTsKICAgICAgfQoKICAgICAgLy8gZ2VuZXJhdGUgdGhlIHJhbmRvbSBieXRlcwogICAgICB2YXIgYnl0ZXMgPSBjaXBoZXIoY3R4LmtleSwgY3R4LnNlZWQpOwogICAgICBjdHguZ2VuZXJhdGVkICs9IGJ5dGVzLmxlbmd0aDsKICAgICAgYi5wdXRCeXRlcyhieXRlcyk7CgogICAgICAvLyBnZW5lcmF0ZSBieXRlcyBmb3IgYSBuZXcga2V5IGFuZCBzZWVkCiAgICAgIGN0eC5rZXkgPSBmb3JtYXRLZXkoY2lwaGVyKGN0eC5rZXksIGluY3JlbWVudChjdHguc2VlZCkpKTsKICAgICAgY3R4LnNlZWQgPSBmb3JtYXRTZWVkKGNpcGhlcihjdHgua2V5LCBjdHguc2VlZCkpOwogICAgfQoKICAgIHJldHVybiBiLmdldEJ5dGVzKGNvdW50KTsKICB9OwoKICAvKioKICAgKiBQcml2YXRlIGZ1bmN0aW9uIHRoYXQgYXN5bmNocm9ub3VzbHkgcmVzZWVkcyBhIGdlbmVyYXRvci4KICAgKgogICAqIEBwYXJhbSBjYWxsYmFjayhlcnIpIGNhbGxlZCBvbmNlIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLgogICAqLwogIGZ1bmN0aW9uIF9yZXNlZWQoY2FsbGJhY2spIHsKICAgIGlmKGN0eC5wb29sc1swXS5tZXNzYWdlTGVuZ3RoID49IDMyKSB7CiAgICAgIF9zZWVkKCk7CiAgICAgIHJldHVybiBjYWxsYmFjaygpOwogICAgfQogICAgLy8gbm90IGVub3VnaCBzZWVkIGRhdGEuLi4KICAgIHZhciBuZWVkZWQgPSAoMzIgLSBjdHgucG9vbHNbMF0ubWVzc2FnZUxlbmd0aCkgPDwgNTsKICAgIGN0eC5zZWVkRmlsZShuZWVkZWQsIGZ1bmN0aW9uKGVyciwgYnl0ZXMpIHsKICAgICAgaWYoZXJyKSB7CiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7CiAgICAgIH0KICAgICAgY3R4LmNvbGxlY3QoYnl0ZXMpOwogICAgICBfc2VlZCgpOwogICAgICBjYWxsYmFjaygpOwogICAgfSk7CiAgfQoKICAvKioKICAgKiBQcml2YXRlIGZ1bmN0aW9uIHRoYXQgc3luY2hyb25vdXNseSByZXNlZWRzIGEgZ2VuZXJhdG9yLgogICAqLwogIGZ1bmN0aW9uIF9yZXNlZWRTeW5jKCkgewogICAgaWYoY3R4LnBvb2xzWzBdLm1lc3NhZ2VMZW5ndGggPj0gMzIpIHsKICAgICAgcmV0dXJuIF9zZWVkKCk7CiAgICB9CiAgICAvLyBub3QgZW5vdWdoIHNlZWQgZGF0YS4uLgogICAgdmFyIG5lZWRlZCA9ICgzMiAtIGN0eC5wb29sc1swXS5tZXNzYWdlTGVuZ3RoKSA8PCA1OwogICAgY3R4LmNvbGxlY3QoY3R4LnNlZWRGaWxlU3luYyhuZWVkZWQpKTsKICAgIF9zZWVkKCk7CiAgfQoKICAvKioKICAgKiBQcml2YXRlIGZ1bmN0aW9uIHRoYXQgc2VlZHMgYSBnZW5lcmF0b3Igb25jZSBlbm91Z2ggYnl0ZXMgYXJlIGF2YWlsYWJsZS4KICAgKi8KICBmdW5jdGlvbiBfc2VlZCgpIHsKICAgIC8vIGNyZWF0ZSBhIHBsdWdpbi1iYXNlZCBtZXNzYWdlIGRpZ2VzdAogICAgdmFyIG1kID0gY3R4LnBsdWdpbi5tZC5jcmVhdGUoKTsKCiAgICAvLyBkaWdlc3QgcG9vbCAwJ3MgZW50cm9weSBhbmQgcmVzdGFydCBpdAogICAgbWQudXBkYXRlKGN0eC5wb29sc1swXS5kaWdlc3QoKS5nZXRCeXRlcygpKTsKICAgIGN0eC5wb29sc1swXS5zdGFydCgpOwoKICAgIC8vIGRpZ2VzdCB0aGUgZW50cm9weSBvZiBvdGhlciBwb29scyB3aG9zZSBpbmRleCBrIG1lZXQgdGhlCiAgICAvLyBjb25kaXRpb24gJzJeayBtb2QgbiA9PSAwJyB3aGVyZSBuIGlzIHRoZSBudW1iZXIgb2YgcmVzZWVkcwogICAgdmFyIGsgPSAxOwogICAgZm9yKHZhciBpID0gMTsgaSA8IDMyOyArK2kpIHsKICAgICAgLy8gcHJldmVudCBzaWduZWQgbnVtYmVycyBmcm9tIGJlaW5nIHVzZWQKICAgICAgayA9IChrID09PSAzMSkgPyAweDgwMDAwMDAwIDogKGsgPDwgMik7CiAgICAgIGlmKGsgJSBjdHgucmVzZWVkcyA9PT0gMCkgewogICAgICAgIG1kLnVwZGF0ZShjdHgucG9vbHNbaV0uZGlnZXN0KCkuZ2V0Qnl0ZXMoKSk7CiAgICAgICAgY3R4LnBvb2xzW2ldLnN0YXJ0KCk7CiAgICAgIH0KICAgIH0KCiAgICAvLyBnZXQgZGlnZXN0IGZvciBrZXkgYnl0ZXMgYW5kIGl0ZXJhdGUgYWdhaW4gZm9yIHNlZWQgYnl0ZXMKICAgIHZhciBrZXlCeXRlcyA9IG1kLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CiAgICBtZC5zdGFydCgpOwogICAgbWQudXBkYXRlKGtleUJ5dGVzKTsKICAgIHZhciBzZWVkQnl0ZXMgPSBtZC5kaWdlc3QoKS5nZXRCeXRlcygpOwoKICAgIC8vIHVwZGF0ZQogICAgY3R4LmtleSA9IGN0eC5wbHVnaW4uZm9ybWF0S2V5KGtleUJ5dGVzKTsKICAgIGN0eC5zZWVkID0gY3R4LnBsdWdpbi5mb3JtYXRTZWVkKHNlZWRCeXRlcyk7CiAgICBjdHgucmVzZWVkcyA9IChjdHgucmVzZWVkcyA9PT0gMHhmZmZmZmZmZikgPyAwIDogY3R4LnJlc2VlZHMgKyAxOwogICAgY3R4LmdlbmVyYXRlZCA9IDA7CiAgfQoKICAvKioKICAgKiBUaGUgYnVpbHQtaW4gZGVmYXVsdCBzZWVkRmlsZS4gVGhpcyBzZWVkRmlsZSBpcyB1c2VkIHdoZW4gZW50cm9weQogICAqIGlzIG5lZWRlZCBpbW1lZGlhdGVseS4KICAgKgogICAqIEBwYXJhbSBuZWVkZWQgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IGFyZSBuZWVkZWQuCiAgICoKICAgKiBAcmV0dXJuIHRoZSByYW5kb20gYnl0ZXMuCiAgICovCiAgZnVuY3Rpb24gZGVmYXVsdFNlZWRGaWxlKG5lZWRlZCkgewogICAgLy8gdXNlIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzIHN0cm9uZyBzb3VyY2Ugb2YgZW50cm9weSBpZiBhdmFpbGFibGUKICAgIHZhciBnZXRSYW5kb21WYWx1ZXMgPSBudWxsOwogICAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgdmFyIF9jcnlwdG8gPSB3aW5kb3cuY3J5cHRvIHx8IHdpbmRvdy5tc0NyeXB0bzsKICAgICAgaWYoX2NyeXB0byAmJiBfY3J5cHRvLmdldFJhbmRvbVZhbHVlcykgewogICAgICAgIGdldFJhbmRvbVZhbHVlcyA9IGZ1bmN0aW9uKGFycikgewogICAgICAgICAgcmV0dXJuIF9jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGFycik7CiAgICAgICAgfTsKICAgICAgfQogICAgfQoKICAgIHZhciBiID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGlmKGdldFJhbmRvbVZhbHVlcykgewogICAgICB3aGlsZShiLmxlbmd0aCgpIDwgbmVlZGVkKSB7CiAgICAgICAgLy8gbWF4IGJ5dGUgbGVuZ3RoIGlzIDY1NTM2IGJlZm9yZSBRdW90YUV4Y2VlZGVkRXJyb3IgaXMgdGhyb3duCiAgICAgICAgLy8gaHR0cDovL3d3dy53My5vcmcvVFIvV2ViQ3J5cHRvQVBJLyNSYW5kb21Tb3VyY2UtbWV0aG9kLWdldFJhbmRvbVZhbHVlcwogICAgICAgIHZhciBjb3VudCA9IE1hdGgubWF4KDEsIE1hdGgubWluKG5lZWRlZCAtIGIubGVuZ3RoKCksIDY1NTM2KSAvIDQpOwogICAgICAgIHZhciBlbnRyb3B5ID0gbmV3IFVpbnQzMkFycmF5KE1hdGguZmxvb3IoY291bnQpKTsKICAgICAgICB0cnkgewogICAgICAgICAgZ2V0UmFuZG9tVmFsdWVzKGVudHJvcHkpOwogICAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGVudHJvcHkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgYi5wdXRJbnQzMihlbnRyb3B5W2ldKTsKICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgIC8qIG9ubHkgaWdub3JlIFF1b3RhRXhjZWVkZWRFcnJvciAqLwogICAgICAgICAgaWYoISh0eXBlb2YgUXVvdGFFeGNlZWRlZEVycm9yICE9PSAndW5kZWZpbmVkJyAmJgogICAgICAgICAgICBlIGluc3RhbmNlb2YgUXVvdGFFeGNlZWRlZEVycm9yKSkgewogICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIC8vIGJlIHNhZCBhbmQgYWRkIHNvbWUgd2VhayByYW5kb20gZGF0YQogICAgaWYoYi5sZW5ndGgoKSA8IG5lZWRlZCkgewogICAgICAvKiBEcmF3cyBmcm9tIFBhcmstTWlsbGVyICJtaW5pbWFsIHN0YW5kYXJkIiAzMSBiaXQgUFJORywKICAgICAgaW1wbGVtZW50ZWQgd2l0aCBEYXZpZCBHLiBDYXJ0YSdzIG9wdGltaXphdGlvbjogd2l0aCAzMiBiaXQgbWF0aAogICAgICBhbmQgd2l0aG91dCBkaXZpc2lvbiAoUHVibGljIERvbWFpbikuICovCiAgICAgIHZhciBoaSwgbG8sIG5leHQ7CiAgICAgIHZhciBzZWVkID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMHgwMTAwMDApOwogICAgICB3aGlsZShiLmxlbmd0aCgpIDwgbmVlZGVkKSB7CiAgICAgICAgbG8gPSAxNjgwNyAqIChzZWVkICYgMHhGRkZGKTsKICAgICAgICBoaSA9IDE2ODA3ICogKHNlZWQgPj4gMTYpOwogICAgICAgIGxvICs9IChoaSAmIDB4N0ZGRikgPDwgMTY7CiAgICAgICAgbG8gKz0gaGkgPj4gMTU7CiAgICAgICAgbG8gPSAobG8gJiAweDdGRkZGRkZGKSArIChsbyA+PiAzMSk7CiAgICAgICAgc2VlZCA9IGxvICYgMHhGRkZGRkZGRjsKCiAgICAgICAgLy8gY29uc3VtZSBsb3dlciAzIGJ5dGVzIG9mIHNlZWQKICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgMzsgKytpKSB7CiAgICAgICAgICAvLyB0aHJvdyBpbiBtb3JlIHBzZXVkbyByYW5kb20KICAgICAgICAgIG5leHQgPSBzZWVkID4+PiAoaSA8PCAzKTsKICAgICAgICAgIG5leHQgXj0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMHgwMTAwKTsKICAgICAgICAgIGIucHV0Qnl0ZShTdHJpbmcuZnJvbUNoYXJDb2RlKG5leHQgJiAweEZGKSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgcmV0dXJuIGIuZ2V0Qnl0ZXMobmVlZGVkKTsKICB9CiAgLy8gaW5pdGlhbGl6ZSBzZWVkIGZpbGUgQVBJcwogIGlmKF9jcnlwdG8pIHsKICAgIC8vIHVzZSBub2RlanMgYXN5bmMgQVBJCiAgICBjdHguc2VlZEZpbGUgPSBmdW5jdGlvbihuZWVkZWQsIGNhbGxiYWNrKSB7CiAgICAgIF9jcnlwdG8ucmFuZG9tQnl0ZXMobmVlZGVkLCBmdW5jdGlvbihlcnIsIGJ5dGVzKSB7CiAgICAgICAgaWYoZXJyKSB7CiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTsKICAgICAgICB9CiAgICAgICAgY2FsbGJhY2sobnVsbCwgYnl0ZXMudG9TdHJpbmcoKSk7CiAgICAgIH0pOwogICAgfTsKICAgIC8vIHVzZSBub2RlanMgc3luYyBBUEkKICAgIGN0eC5zZWVkRmlsZVN5bmMgPSBmdW5jdGlvbihuZWVkZWQpIHsKICAgICAgcmV0dXJuIF9jcnlwdG8ucmFuZG9tQnl0ZXMobmVlZGVkKS50b1N0cmluZygpOwogICAgfTsKICB9IGVsc2UgewogICAgY3R4LnNlZWRGaWxlID0gZnVuY3Rpb24obmVlZGVkLCBjYWxsYmFjaykgewogICAgICB0cnkgewogICAgICAgIGNhbGxiYWNrKG51bGwsIGRlZmF1bHRTZWVkRmlsZShuZWVkZWQpKTsKICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgY2FsbGJhY2soZSk7CiAgICAgIH0KICAgIH07CiAgICBjdHguc2VlZEZpbGVTeW5jID0gZGVmYXVsdFNlZWRGaWxlOwogIH0KCiAgLyoqCiAgICogQWRkcyBlbnRyb3B5IHRvIGEgcHJuZyBjdHgncyBhY2N1bXVsYXRvci4KICAgKgogICAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZXMgb2YgZW50cm9weSBhcyBhIHN0cmluZy4KICAgKi8KICBjdHguY29sbGVjdCA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgICAvLyBpdGVyYXRlIG92ZXIgcG9vbHMgZGlzdHJpYnV0aW5nIGVudHJvcHkgY3ljbGljYWxseQogICAgdmFyIGNvdW50ID0gYnl0ZXMubGVuZ3RoOwogICAgZm9yKHZhciBpID0gMDsgaSA8IGNvdW50OyArK2kpIHsKICAgICAgY3R4LnBvb2xzW2N0eC5wb29sXS51cGRhdGUoYnl0ZXMuc3Vic3RyKGksIDEpKTsKICAgICAgY3R4LnBvb2wgPSAoY3R4LnBvb2wgPT09IDMxKSA/IDAgOiBjdHgucG9vbCArIDE7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogQ29sbGVjdHMgYW4gaW50ZWdlciBvZiBuIGJpdHMuCiAgICoKICAgKiBAcGFyYW0gaSB0aGUgaW50ZWdlciBlbnRyb3B5LgogICAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICAgKi8KICBjdHguY29sbGVjdEludCA9IGZ1bmN0aW9uKGksIG4pIHsKICAgIHZhciBieXRlcyA9ICcnOwogICAgZm9yKHZhciB4ID0gMDsgeCA8IG47IHggKz0gOCkgewogICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChpID4+IHgpICYgMHhGRik7CiAgICB9CiAgICBjdHguY29sbGVjdChieXRlcyk7CiAgfTsKCiAgLyoqCiAgICogUmVnaXN0ZXJzIGEgV2ViIFdvcmtlciB0byByZWNlaXZlIGltbWVkaWF0ZSBlbnRyb3B5IGZyb20gdGhlIG1haW4gdGhyZWFkLgogICAqIFRoaXMgbWV0aG9kIGlzIHJlcXVpcmVkIHVudGlsIFdlYiBXb3JrZXJzIGNhbiBhY2Nlc3MgdGhlIG5hdGl2ZSBjcnlwdG8KICAgKiBBUEkuIFRoaXMgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgdHdpY2UgZm9yIGVhY2ggY3JlYXRlZCB3b3JrZXIsIG9uY2UgaW4KICAgKiB0aGUgbWFpbiB0aHJlYWQsIGFuZCBvbmNlIGluIHRoZSB3b3JrZXIgaXRzZWxmLgogICAqCiAgICogQHBhcmFtIHdvcmtlciB0aGUgd29ya2VyIHRvIHJlZ2lzdGVyLgogICAqLwogIGN0eC5yZWdpc3RlcldvcmtlciA9IGZ1bmN0aW9uKHdvcmtlcikgewogICAgLy8gd29ya2VyIHJlY2VpdmVzIHJhbmRvbSBieXRlcwogICAgaWYod29ya2VyID09PSBzZWxmKSB7CiAgICAgIGN0eC5zZWVkRmlsZSA9IGZ1bmN0aW9uKG5lZWRlZCwgY2FsbGJhY2spIHsKICAgICAgICBmdW5jdGlvbiBsaXN0ZW5lcihlKSB7CiAgICAgICAgICB2YXIgZGF0YSA9IGUuZGF0YTsKICAgICAgICAgIGlmKGRhdGEuZm9yZ2UgJiYgZGF0YS5mb3JnZS5wcm5nKSB7CiAgICAgICAgICAgIHNlbGYucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGxpc3RlbmVyKTsKICAgICAgICAgICAgY2FsbGJhY2soZGF0YS5mb3JnZS5wcm5nLmVyciwgZGF0YS5mb3JnZS5wcm5nLmJ5dGVzKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2VsZi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuZXIpOwogICAgICAgIHNlbGYucG9zdE1lc3NhZ2Uoe2ZvcmdlOiB7cHJuZzoge25lZWRlZDogbmVlZGVkfX19KTsKICAgICAgfTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIG1haW4gdGhyZWFkIHNlbmRzIHJhbmRvbSBieXRlcyB1cG9uIHJlcXVlc3QKICAgICAgdmFyIGxpc3RlbmVyID0gZnVuY3Rpb24oZSkgewogICAgICAgIHZhciBkYXRhID0gZS5kYXRhOwogICAgICAgIGlmKGRhdGEuZm9yZ2UgJiYgZGF0YS5mb3JnZS5wcm5nKSB7CiAgICAgICAgICBjdHguc2VlZEZpbGUoZGF0YS5mb3JnZS5wcm5nLm5lZWRlZCwgZnVuY3Rpb24oZXJyLCBieXRlcykgewogICAgICAgICAgICB3b3JrZXIucG9zdE1lc3NhZ2Uoe2ZvcmdlOiB7cHJuZzoge2VycjogZXJyLCBieXRlczogYnl0ZXN9fX0pOwogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9OwogICAgICAvLyBUT0RPOiBkbyB3ZSBuZWVkIHRvIHJlbW92ZSB0aGUgZXZlbnQgbGlzdGVuZXIgd2hlbiB0aGUgd29ya2VyIGRpZXM/CiAgICAgIHdvcmtlci5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuZXIpOwogICAgfQogIH07CgogIHJldHVybiBjdHg7Cn07Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdwcm5nJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3BybmcnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9tZCcsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cgp9KSgpOwoKLyoqCiAqIEFuIEFQSSBmb3IgZ2V0dGluZyBjcnlwdG9ncmFwaGljYWxseS1zZWN1cmUgcmFuZG9tIGJ5dGVzLiBUaGUgYnl0ZXMgYXJlCiAqIGdlbmVyYXRlZCB1c2luZyB0aGUgRm9ydHVuYSBhbGdvcml0aG0gZGV2aXNlZCBieSBCcnVjZSBTY2huZWllciBhbmQKICogTmllbHMgRmVyZ3Vzb24uCiAqCiAqIEdldHRpbmcgc3Ryb25nIHJhbmRvbSBieXRlcyBpcyBub3QgeWV0IGVhc3kgdG8gZG8gaW4gamF2YXNjcmlwdC4gVGhlIG9ubHkKICogdHJ1aXNoIHJhbmRvbSBlbnRyb3B5IHRoYXQgY2FuIGJlIGNvbGxlY3RlZCBpcyBmcm9tIHRoZSBtb3VzZSwga2V5Ym9hcmQsIG9yCiAqIGZyb20gdGltaW5nIHdpdGggcmVzcGVjdCB0byBwYWdlIGxvYWRzLCBldGMuIFRoaXMgZ2VuZXJhdG9yIG1ha2VzIGEgcG9vcgogKiBhdHRlbXB0IGF0IHByb3ZpZGluZyByYW5kb20gYnl0ZXMgd2hlbiB0aG9zZSBzb3VyY2VzIGhhdmVuJ3QgeWV0IHByb3ZpZGVkCiAqIGVub3VnaCBlbnRyb3B5IHRvIGluaXRpYWxseSBzZWVkIG9yIHRvIHJlc2VlZCB0aGUgUFJORy4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDA5LTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBmb3JnZS5yYW5kb20gYWxyZWFkeSBkZWZpbmVkCmlmKGZvcmdlLnJhbmRvbSAmJiBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMpIHsKICByZXR1cm47Cn0KCihmdW5jdGlvbihqUXVlcnkpIHsKCi8vIHRoZSBkZWZhdWx0IHBybmcgcGx1Z2luLCB1c2VzIEFFUy0xMjgKdmFyIHBybmdfYWVzID0ge307CnZhciBfcHJuZ19hZXNfb3V0cHV0ID0gbmV3IEFycmF5KDQpOwp2YXIgX3BybmdfYWVzX2J1ZmZlciA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CnBybmdfYWVzLmZvcm1hdEtleSA9IGZ1bmN0aW9uKGtleSkgewogIC8vIGNvbnZlcnQgdGhlIGtleSBpbnRvIDMyLWJpdCBpbnRlZ2VycwogIHZhciB0bXAgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihrZXkpOwogIGtleSA9IG5ldyBBcnJheSg0KTsKICBrZXlbMF0gPSB0bXAuZ2V0SW50MzIoKTsKICBrZXlbMV0gPSB0bXAuZ2V0SW50MzIoKTsKICBrZXlbMl0gPSB0bXAuZ2V0SW50MzIoKTsKICBrZXlbM10gPSB0bXAuZ2V0SW50MzIoKTsKCiAgLy8gcmV0dXJuIHRoZSBleHBhbmRlZCBrZXkKICByZXR1cm4gZm9yZ2UuYWVzLl9leHBhbmRLZXkoa2V5LCBmYWxzZSk7Cn07CnBybmdfYWVzLmZvcm1hdFNlZWQgPSBmdW5jdGlvbihzZWVkKSB7CiAgLy8gY29udmVydCBzZWVkIGludG8gMzItYml0IGludGVnZXJzCiAgdmFyIHRtcCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKHNlZWQpOwogIHNlZWQgPSBuZXcgQXJyYXkoNCk7CiAgc2VlZFswXSA9IHRtcC5nZXRJbnQzMigpOwogIHNlZWRbMV0gPSB0bXAuZ2V0SW50MzIoKTsKICBzZWVkWzJdID0gdG1wLmdldEludDMyKCk7CiAgc2VlZFszXSA9IHRtcC5nZXRJbnQzMigpOwogIHJldHVybiBzZWVkOwp9Owpwcm5nX2Flcy5jaXBoZXIgPSBmdW5jdGlvbihrZXksIHNlZWQpIHsKICBmb3JnZS5hZXMuX3VwZGF0ZUJsb2NrKGtleSwgc2VlZCwgX3BybmdfYWVzX291dHB1dCwgZmFsc2UpOwogIF9wcm5nX2Flc19idWZmZXIucHV0SW50MzIoX3BybmdfYWVzX291dHB1dFswXSk7CiAgX3BybmdfYWVzX2J1ZmZlci5wdXRJbnQzMihfcHJuZ19hZXNfb3V0cHV0WzFdKTsKICBfcHJuZ19hZXNfYnVmZmVyLnB1dEludDMyKF9wcm5nX2Flc19vdXRwdXRbMl0pOwogIF9wcm5nX2Flc19idWZmZXIucHV0SW50MzIoX3BybmdfYWVzX291dHB1dFszXSk7CiAgcmV0dXJuIF9wcm5nX2Flc19idWZmZXIuZ2V0Qnl0ZXMoKTsKfTsKcHJuZ19hZXMuaW5jcmVtZW50ID0gZnVuY3Rpb24oc2VlZCkgewogIC8vIEZJWE1FOiBkbyB3ZSBjYXJlIGFib3V0IGNhcnJ5IG9yIHNpZ25lZCBpc3N1ZXM/CiAgKytzZWVkWzNdOwogIHJldHVybiBzZWVkOwp9Owpwcm5nX2Flcy5tZCA9IGZvcmdlLm1kLnNoYTI1NjsKCi8qKgogKiBDcmVhdGVzIGEgbmV3IFBSTkcuCiAqLwpmdW5jdGlvbiBzcGF3blBybmcoKSB7CiAgdmFyIGN0eCA9IGZvcmdlLnBybmcuY3JlYXRlKHBybmdfYWVzKTsKCiAgLyoqCiAgICogR2V0cyByYW5kb20gYnl0ZXMuIElmIGEgbmF0aXZlIHNlY3VyZSBjcnlwdG8gQVBJIGlzIHVuYXZhaWxhYmxlLCB0aGlzCiAgICogbWV0aG9kIHRyaWVzIHRvIG1ha2UgdGhlIGJ5dGVzIG1vcmUgdW5wcmVkaWN0YWJsZSBieSBkcmF3aW5nIGZyb20gZGF0YSB0aGF0CiAgICogY2FuIGJlIGNvbGxlY3RlZCBmcm9tIHRoZSB1c2VyIG9mIHRoZSBicm93c2VyLCBlZzogbW91c2UgbW92ZW1lbnQuCiAgICoKICAgKiBJZiBhIGNhbGxiYWNrIGlzIGdpdmVuLCB0aGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBhc3luY2hyb25vdXNseS4KICAgKgogICAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIHJhbmRvbSBieXRlcyB0byBnZXQuCiAgICogQHBhcmFtIFtjYWxsYmFjayhlcnIsIGJ5dGVzKV0gY2FsbGVkIG9uY2UgdGhlIG9wZXJhdGlvbiBjb21wbGV0ZXMuCiAgICoKICAgKiBAcmV0dXJuIHRoZSByYW5kb20gYnl0ZXMgaW4gYSBzdHJpbmcuCiAgICovCiAgY3R4LmdldEJ5dGVzID0gZnVuY3Rpb24oY291bnQsIGNhbGxiYWNrKSB7CiAgICByZXR1cm4gY3R4LmdlbmVyYXRlKGNvdW50LCBjYWxsYmFjayk7CiAgfTsKCiAgLyoqCiAgICogR2V0cyByYW5kb20gYnl0ZXMgYXN5bmNocm9ub3VzbHkuIElmIGEgbmF0aXZlIHNlY3VyZSBjcnlwdG8gQVBJIGlzCiAgICogdW5hdmFpbGFibGUsIHRoaXMgbWV0aG9kIHRyaWVzIHRvIG1ha2UgdGhlIGJ5dGVzIG1vcmUgdW5wcmVkaWN0YWJsZSBieQogICAqIGRyYXdpbmcgZnJvbSBkYXRhIHRoYXQgY2FuIGJlIGNvbGxlY3RlZCBmcm9tIHRoZSB1c2VyIG9mIHRoZSBicm93c2VyLAogICAqIGVnOiBtb3VzZSBtb3ZlbWVudC4KICAgKgogICAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIHJhbmRvbSBieXRlcyB0byBnZXQuCiAgICoKICAgKiBAcmV0dXJuIHRoZSByYW5kb20gYnl0ZXMgaW4gYSBzdHJpbmcuCiAgICovCiAgY3R4LmdldEJ5dGVzU3luYyA9IGZ1bmN0aW9uKGNvdW50KSB7CiAgICByZXR1cm4gY3R4LmdlbmVyYXRlKGNvdW50KTsKICB9OwoKICByZXR1cm4gY3R4Owp9CgovLyBjcmVhdGUgZGVmYXVsdCBwcm5nIGNvbnRleHQKdmFyIF9jdHggPSBzcGF3blBybmcoKTsKCi8vIGFkZCBvdGhlciBzb3VyY2VzIG9mIGVudHJvcHkgb25seSBpZiB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyBpcyBub3QKLy8gYXZhaWxhYmxlIC0tIG90aGVyd2lzZSB0aGlzIHNvdXJjZSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgdXNlZCBieSB0aGUgcHJuZwp2YXIgX25vZGVqcyA9ICgKICB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvY2Vzcy52ZXJzaW9ucyAmJiBwcm9jZXNzLnZlcnNpb25zLm5vZGUpOwp2YXIgZ2V0UmFuZG9tVmFsdWVzID0gbnVsbDsKaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHsKICB2YXIgX2NyeXB0byA9IHdpbmRvdy5jcnlwdG8gfHwgd2luZG93Lm1zQ3J5cHRvOwogIGlmKF9jcnlwdG8gJiYgX2NyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHsKICAgIGdldFJhbmRvbVZhbHVlcyA9IGZ1bmN0aW9uKGFycikgewogICAgICByZXR1cm4gX2NyeXB0by5nZXRSYW5kb21WYWx1ZXMoYXJyKTsKICAgIH07CiAgfQp9CmlmKGZvcmdlLmRpc2FibGVOYXRpdmVDb2RlIHx8ICghX25vZGVqcyAmJiAhZ2V0UmFuZG9tVmFsdWVzKSkgewogIC8vIGlmIHRoaXMgaXMgYSB3ZWIgd29ya2VyLCBkbyBub3QgdXNlIHdlYWsgZW50cm9weSwgaW5zdGVhZCByZWdpc3RlciB0bwogIC8vIHJlY2VpdmUgc3Ryb25nIGVudHJvcHkgYXN5bmNocm9ub3VzbHkgZnJvbSB0aGUgbWFpbiB0aHJlYWQKICBpZih0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyB8fCB3aW5kb3cuZG9jdW1lbnQgPT09IHVuZGVmaW5lZCkgewogICAgLy8gRklYTUU6CiAgfQoKICAvLyBnZXQgbG9hZCB0aW1lIGVudHJvcHkKICBfY3R4LmNvbGxlY3RJbnQoK25ldyBEYXRlKCksIDMyKTsKCiAgLy8gYWRkIHNvbWUgZW50cm9weSBmcm9tIG5hdmlnYXRvciBvYmplY3QKICBpZih0eXBlb2YobmF2aWdhdG9yKSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgIHZhciBfbmF2Qnl0ZXMgPSAnJzsKICAgIGZvcih2YXIga2V5IGluIG5hdmlnYXRvcikgewogICAgICB0cnkgewogICAgICAgIGlmKHR5cGVvZihuYXZpZ2F0b3Jba2V5XSkgPT0gJ3N0cmluZycpIHsKICAgICAgICAgIF9uYXZCeXRlcyArPSBuYXZpZ2F0b3Jba2V5XTsKICAgICAgICB9CiAgICAgIH0gY2F0Y2goZSkgewogICAgICAgIC8qIFNvbWUgbmF2aWdhdG9yIGtleXMgbWlnaHQgbm90IGJlIGFjY2Vzc2libGUsIGUuZy4gdGhlIGdlb2xvY2F0aW9uCiAgICAgICAgICBhdHRyaWJ1dGUgdGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0b3VjaGVkIGluIE1vemlsbGEgY2hyb21lOi8vCiAgICAgICAgICBjb250ZXh0LgoKICAgICAgICAgIFNpbGVudGx5IGlnbm9yZSB0aGlzIGFuZCBqdXN0IGRvbid0IHVzZSB0aGlzIGFzIGEgc291cmNlIG9mCiAgICAgICAgICBlbnRyb3B5LiAqLwogICAgICB9CiAgICB9CiAgICBfY3R4LmNvbGxlY3QoX25hdkJ5dGVzKTsKICAgIF9uYXZCeXRlcyA9IG51bGw7CiAgfQoKICAvLyBhZGQgbW91c2UgYW5kIGtleWJvYXJkIGNvbGxlY3RvcnMgaWYganF1ZXJ5IGlzIGF2YWlsYWJsZQogIGlmKGpRdWVyeSkgewogICAgLy8gc2V0IHVwIG1vdXNlIGVudHJvcHkgY2FwdHVyZQogICAgalF1ZXJ5KCkubW91c2Vtb3ZlKGZ1bmN0aW9uKGUpIHsKICAgICAgLy8gYWRkIG1vdXNlIGNvb3JkcwogICAgICBfY3R4LmNvbGxlY3RJbnQoZS5jbGllbnRYLCAxNik7CiAgICAgIF9jdHguY29sbGVjdEludChlLmNsaWVudFksIDE2KTsKICAgIH0pOwoKICAgIC8vIHNldCB1cCBrZXlib2FyZCBlbnRyb3B5IGNhcHR1cmUKICAgIGpRdWVyeSgpLmtleXByZXNzKGZ1bmN0aW9uKGUpIHsKICAgICAgX2N0eC5jb2xsZWN0SW50KGUuY2hhckNvZGUsIDgpOwogICAgfSk7CiAgfQp9CgovKiBSYW5kb20gQVBJICovCmlmKCFmb3JnZS5yYW5kb20pIHsKICBmb3JnZS5yYW5kb20gPSBfY3R4Owp9IGVsc2UgewogIC8vIGV4dGVuZCBmb3JnZS5yYW5kb20gd2l0aCBfY3R4CiAgZm9yKHZhciBrZXkgaW4gX2N0eCkgewogICAgZm9yZ2UucmFuZG9tW2tleV0gPSBfY3R4W2tleV07CiAgfQp9CgovLyBleHBvc2Ugc3Bhd24gUFJORwpmb3JnZS5yYW5kb20uY3JlYXRlSW5zdGFuY2UgPSBzcGF3blBybmc7Cgp9KSh0eXBlb2YoalF1ZXJ5KSAhPT0gJ3VuZGVmaW5lZCcgPyBqUXVlcnkgOiBudWxsKTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3JhbmRvbSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9yYW5kb20nLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9hZXMnLCAnLi9tZCcsICcuL3BybmcnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFJDMiBpbXBsZW1lbnRhdGlvbi4KICoKICogQGF1dGhvciBTdGVmYW4gU2llZ2wKICoKICogQ29weXJpZ2h0IChjKSAyMDEyIFN0ZWZhbiBTaWVnbCA8c3Rlc2llQGJyb2tlbnBpcGUuZGU+CiAqCiAqIEluZm9ybWF0aW9uIG9uIHRoZSBSQzIgY2lwaGVyIGlzIGF2YWlsYWJsZSBmcm9tIFJGQyAjMjI2OCwKICogaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI2OC50eHQKICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7Cgp2YXIgcGlUYWJsZSA9IFsKICAweGQ5LCAweDc4LCAweGY5LCAweGM0LCAweDE5LCAweGRkLCAweGI1LCAweGVkLCAweDI4LCAweGU5LCAweGZkLCAweDc5LCAweDRhLCAweGEwLCAweGQ4LCAweDlkLAogIDB4YzYsIDB4N2UsIDB4MzcsIDB4ODMsIDB4MmIsIDB4NzYsIDB4NTMsIDB4OGUsIDB4NjIsIDB4NGMsIDB4NjQsIDB4ODgsIDB4NDQsIDB4OGIsIDB4ZmIsIDB4YTIsCiAgMHgxNywgMHg5YSwgMHg1OSwgMHhmNSwgMHg4NywgMHhiMywgMHg0ZiwgMHgxMywgMHg2MSwgMHg0NSwgMHg2ZCwgMHg4ZCwgMHgwOSwgMHg4MSwgMHg3ZCwgMHgzMiwKICAweGJkLCAweDhmLCAweDQwLCAweGViLCAweDg2LCAweGI3LCAweDdiLCAweDBiLCAweGYwLCAweDk1LCAweDIxLCAweDIyLCAweDVjLCAweDZiLCAweDRlLCAweDgyLAogIDB4NTQsIDB4ZDYsIDB4NjUsIDB4OTMsIDB4Y2UsIDB4NjAsIDB4YjIsIDB4MWMsIDB4NzMsIDB4NTYsIDB4YzAsIDB4MTQsIDB4YTcsIDB4OGMsIDB4ZjEsIDB4ZGMsCiAgMHgxMiwgMHg3NSwgMHhjYSwgMHgxZiwgMHgzYiwgMHhiZSwgMHhlNCwgMHhkMSwgMHg0MiwgMHgzZCwgMHhkNCwgMHgzMCwgMHhhMywgMHgzYywgMHhiNiwgMHgyNiwKICAweDZmLCAweGJmLCAweDBlLCAweGRhLCAweDQ2LCAweDY5LCAweDA3LCAweDU3LCAweDI3LCAweGYyLCAweDFkLCAweDliLCAweGJjLCAweDk0LCAweDQzLCAweDAzLAogIDB4ZjgsIDB4MTEsIDB4YzcsIDB4ZjYsIDB4OTAsIDB4ZWYsIDB4M2UsIDB4ZTcsIDB4MDYsIDB4YzMsIDB4ZDUsIDB4MmYsIDB4YzgsIDB4NjYsIDB4MWUsIDB4ZDcsCiAgMHgwOCwgMHhlOCwgMHhlYSwgMHhkZSwgMHg4MCwgMHg1MiwgMHhlZSwgMHhmNywgMHg4NCwgMHhhYSwgMHg3MiwgMHhhYywgMHgzNSwgMHg0ZCwgMHg2YSwgMHgyYSwKICAweDk2LCAweDFhLCAweGQyLCAweDcxLCAweDVhLCAweDE1LCAweDQ5LCAweDc0LCAweDRiLCAweDlmLCAweGQwLCAweDVlLCAweDA0LCAweDE4LCAweGE0LCAweGVjLAogIDB4YzIsIDB4ZTAsIDB4NDEsIDB4NmUsIDB4MGYsIDB4NTEsIDB4Y2IsIDB4Y2MsIDB4MjQsIDB4OTEsIDB4YWYsIDB4NTAsIDB4YTEsIDB4ZjQsIDB4NzAsIDB4MzksCiAgMHg5OSwgMHg3YywgMHgzYSwgMHg4NSwgMHgyMywgMHhiOCwgMHhiNCwgMHg3YSwgMHhmYywgMHgwMiwgMHgzNiwgMHg1YiwgMHgyNSwgMHg1NSwgMHg5NywgMHgzMSwKICAweDJkLCAweDVkLCAweGZhLCAweDk4LCAweGUzLCAweDhhLCAweDkyLCAweGFlLCAweDA1LCAweGRmLCAweDI5LCAweDEwLCAweDY3LCAweDZjLCAweGJhLCAweGM5LAogIDB4ZDMsIDB4MDAsIDB4ZTYsIDB4Y2YsIDB4ZTEsIDB4OWUsIDB4YTgsIDB4MmMsIDB4NjMsIDB4MTYsIDB4MDEsIDB4M2YsIDB4NTgsIDB4ZTIsIDB4ODksIDB4YTksCiAgMHgwZCwgMHgzOCwgMHgzNCwgMHgxYiwgMHhhYiwgMHgzMywgMHhmZiwgMHhiMCwgMHhiYiwgMHg0OCwgMHgwYywgMHg1ZiwgMHhiOSwgMHhiMSwgMHhjZCwgMHgyZSwKICAweGM1LCAweGYzLCAweGRiLCAweDQ3LCAweGU1LCAweGE1LCAweDljLCAweDc3LCAweDBhLCAweGE2LCAweDIwLCAweDY4LCAweGZlLCAweDdmLCAweGMxLCAweGFkCl07Cgp2YXIgcyA9IFsxLCAyLCAzLCA1XTsKCgovKioKICogUm90YXRlIGEgd29yZCBsZWZ0IGJ5IGdpdmVuIG51bWJlciBvZiBiaXRzLgogKgogKiBCaXRzIHRoYXQgYXJlIHNoaWZ0ZWQgb3V0IG9uIHRoZSBsZWZ0IGFyZSBwdXQgYmFjayBpbiBvbiB0aGUgcmlnaHQKICogaGFuZCBzaWRlLgogKgogKiBAcGFyYW0gd29yZCBUaGUgd29yZCB0byBzaGlmdCBsZWZ0LgogKiBAcGFyYW0gYml0cyBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnQgYnkuCiAqIEByZXR1cm4gVGhlIHJvdGF0ZWQgd29yZC4KICovCnZhciByb2wgPSBmdW5jdGlvbih3b3JkLCBiaXRzKSB7CiAgcmV0dXJuICgod29yZCA8PCBiaXRzKSAmIDB4ZmZmZikgfCAoKHdvcmQgJiAweGZmZmYpID4+ICgxNiAtIGJpdHMpKTsKfTsKCi8qKgogKiBSb3RhdGUgYSB3b3JkIHJpZ2h0IGJ5IGdpdmVuIG51bWJlciBvZiBiaXRzLgogKgogKiBCaXRzIHRoYXQgYXJlIHNoaWZ0ZWQgb3V0IG9uIHRoZSByaWdodCBhcmUgcHV0IGJhY2sgaW4gb24gdGhlIGxlZnQKICogaGFuZCBzaWRlLgogKgogKiBAcGFyYW0gd29yZCBUaGUgd29yZCB0byBzaGlmdCByaWdodC4KICogQHBhcmFtIGJpdHMgVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0IGJ5LgogKiBAcmV0dXJuIFRoZSByb3RhdGVkIHdvcmQuCiAqLwp2YXIgcm9yID0gZnVuY3Rpb24od29yZCwgYml0cykgewogIHJldHVybiAoKHdvcmQgJiAweGZmZmYpID4+IGJpdHMpIHwgKCh3b3JkIDw8ICgxNiAtIGJpdHMpKSAmIDB4ZmZmZik7Cn07CgoKLyogUkMyIEFQSSAqLwpmb3JnZS5yYzIgPSBmb3JnZS5yYzIgfHwge307CgovKioKICogUGVyZm9ybSBSQzIga2V5IGV4cGFuc2lvbiBhcyBwZXIgUkZDICMyMjY4LCBzZWN0aW9uIDIuCiAqCiAqIEBwYXJhbSBrZXkgdmFyaWFibGUtbGVuZ3RoIHVzZXIga2V5IChiZXR3ZWVuIDEgYW5kIDEyOCBieXRlcykKICogQHBhcmFtIGVmZktleUJpdHMgbnVtYmVyIG9mIGVmZmVjdGl2ZSBrZXkgYml0cyAoZGVmYXVsdDogMTI4KQogKiBAcmV0dXJuIHRoZSBleHBhbmRlZCBSQzIga2V5IChCeXRlQnVmZmVyIG9mIDEyOCBieXRlcykKICovCmZvcmdlLnJjMi5leHBhbmRLZXkgPSBmdW5jdGlvbihrZXksIGVmZktleUJpdHMpIHsKICBpZih0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykgewogICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoa2V5KTsKICB9CiAgZWZmS2V5Qml0cyA9IGVmZktleUJpdHMgfHwgMTI4OwoKICAvKiBpbnRyb2R1Y2UgdmFyaWFibGVzIHRoYXQgbWF0Y2ggdGhlIG5hbWVzIHVzZWQgaW4gUkZDICMyMjY4ICovCiAgdmFyIEwgPSBrZXk7CiAgdmFyIFQgPSBrZXkubGVuZ3RoKCk7CiAgdmFyIFQxID0gZWZmS2V5Qml0czsKICB2YXIgVDggPSBNYXRoLmNlaWwoVDEgLyA4KTsKICB2YXIgVE0gPSAweGZmID4+IChUMSAmIDB4MDcpOwogIHZhciBpOwoKICBmb3IoaSA9IFQ7IGkgPCAxMjg7IGkgKyspIHsKICAgIEwucHV0Qnl0ZShwaVRhYmxlWyhMLmF0KGkgLSAxKSArIEwuYXQoaSAtIFQpKSAmIDB4ZmZdKTsKICB9CgogIEwuc2V0QXQoMTI4IC0gVDgsIHBpVGFibGVbTC5hdCgxMjggLSBUOCkgJiBUTV0pOwoKICBmb3IoaSA9IDEyNyAtIFQ4OyBpID49IDA7IGkgLS0pIHsKICAgIEwuc2V0QXQoaSwgcGlUYWJsZVtMLmF0KGkgKyAxKSBeIEwuYXQoaSArIFQ4KV0pOwogIH0KCiAgcmV0dXJuIEw7Cn07CgoKLyoqCiAqIENyZWF0ZXMgYSBSQzIgY2lwaGVyIG9iamVjdC4KICoKICogQHBhcmFtIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UgKGFzIGJhc2UgZm9yIGtleSBnZW5lcmF0aW9uKS4KICogQHBhcmFtIGJpdHMgdGhlIG51bWJlciBvZiBlZmZlY3RpdmUga2V5IGJpdHMuCiAqIEBwYXJhbSBlbmNyeXB0IGZhbHNlIGZvciBkZWNyeXB0aW9uLCB0cnVlIGZvciBlbmNyeXB0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwp2YXIgY3JlYXRlQ2lwaGVyID0gZnVuY3Rpb24oa2V5LCBiaXRzLCBlbmNyeXB0KSB7CiAgdmFyIF9maW5pc2ggPSBmYWxzZSwgX2lucHV0ID0gbnVsbCwgX291dHB1dCA9IG51bGwsIF9pdiA9IG51bGw7CiAgdmFyIG1peFJvdW5kLCBtYXNoUm91bmQ7CiAgdmFyIGksIGosIEsgPSBbXTsKCiAgLyogRXhwYW5kIGtleSBhbmQgZmlsbCBpbnRvIEtbXSBBcnJheSAqLwogIGtleSA9IGZvcmdlLnJjMi5leHBhbmRLZXkoa2V5LCBiaXRzKTsKICBmb3IoaSA9IDA7IGkgPCA2NDsgaSArKykgewogICAgSy5wdXNoKGtleS5nZXRJbnQxNkxlKCkpOwogIH0KCiAgaWYoZW5jcnlwdCkgewogICAgLyoqCiAgICAgKiBQZXJmb3JtIG9uZSBtaXhpbmcgcm91bmQgImluIHBsYWNlIi4KICAgICAqCiAgICAgKiBAcGFyYW0gUiBBcnJheSBvZiBmb3VyIHdvcmRzIHRvIHBlcmZvcm0gbWl4aW5nIG9uLgogICAgICovCiAgICBtaXhSb3VuZCA9IGZ1bmN0aW9uKFIpIHsKICAgICAgZm9yKGkgPSAwOyBpIDwgNDsgaSsrKSB7CiAgICAgICAgUltpXSArPSBLW2pdICsgKFJbKGkgKyAzKSAlIDRdICYgUlsoaSArIDIpICUgNF0pICsKICAgICAgICAgICgoflJbKGkgKyAzKSAlIDRdKSAmIFJbKGkgKyAxKSAlIDRdKTsKICAgICAgICBSW2ldID0gcm9sKFJbaV0sIHNbaV0pOwogICAgICAgIGogKys7CiAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBQZXJmb3JtIG9uZSBtYXNoaW5nIHJvdW5kICJpbiBwbGFjZSIuCiAgICAgKgogICAgICogQHBhcmFtIFIgQXJyYXkgb2YgZm91ciB3b3JkcyB0byBwZXJmb3JtIG1hc2hpbmcgb24uCiAgICAgKi8KICAgIG1hc2hSb3VuZCA9IGZ1bmN0aW9uKFIpIHsKICAgICAgZm9yKGkgPSAwOyBpIDwgNDsgaSArKykgewogICAgICAgIFJbaV0gKz0gS1tSWyhpICsgMykgJSA0XSAmIDYzXTsKICAgICAgfQogICAgfTsKICB9IGVsc2UgewogICAgLyoqCiAgICAgKiBQZXJmb3JtIG9uZSByLW1peGluZyByb3VuZCAiaW4gcGxhY2UiLgogICAgICoKICAgICAqIEBwYXJhbSBSIEFycmF5IG9mIGZvdXIgd29yZHMgdG8gcGVyZm9ybSBtaXhpbmcgb24uCiAgICAgKi8KICAgIG1peFJvdW5kID0gZnVuY3Rpb24oUikgewogICAgICBmb3IoaSA9IDM7IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgUltpXSA9IHJvcihSW2ldLCBzW2ldKTsKICAgICAgICBSW2ldIC09IEtbal0gKyAoUlsoaSArIDMpICUgNF0gJiBSWyhpICsgMikgJSA0XSkgKwogICAgICAgICAgKCh+UlsoaSArIDMpICUgNF0pICYgUlsoaSArIDEpICUgNF0pOwogICAgICAgIGogLS07CiAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBQZXJmb3JtIG9uZSByLW1hc2hpbmcgcm91bmQgImluIHBsYWNlIi4KICAgICAqCiAgICAgKiBAcGFyYW0gUiBBcnJheSBvZiBmb3VyIHdvcmRzIHRvIHBlcmZvcm0gbWFzaGluZyBvbi4KICAgICAqLwogICAgbWFzaFJvdW5kID0gZnVuY3Rpb24oUikgewogICAgICBmb3IoaSA9IDM7IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgUltpXSAtPSBLW1JbKGkgKyAzKSAlIDRdICYgNjNdOwogICAgICB9CiAgICB9OwogIH0KCiAgLyoqCiAgICogUnVuIHRoZSBzcGVjaWZpZWQgY2lwaGVyIGV4ZWN1dGlvbiBwbGFuLgogICAqCiAgICogVGhpcyBmdW5jdGlvbiB0YWtlcyBmb3VyIHdvcmRzIGZyb20gdGhlIGlucHV0IGJ1ZmZlciwgYXBwbGllcyB0aGUgSVYgb24KICAgKiBpdCAoaWYgcmVxdWVzdGVkKSBhbmQgcnVucyB0aGUgcHJvdmlkZWQgZXhlY3V0aW9uIHBsYW4uCiAgICoKICAgKiBUaGUgcGxhbiBtdXN0IGJlIHB1dCB0b2dldGhlciBpbiBmb3JtIG9mIGEgYXJyYXkgb2YgYXJyYXlzLiAgV2hlcmUgdGhlCiAgICogb3V0ZXIgb25lIGlzIHNpbXBseSBhIGxpc3Qgb2Ygc3RlcHMgdG8gcGVyZm9ybSBhbmQgdGhlIGlubmVyIG9uZSBuZWVkcwogICAqIHRvIGhhdmUgdHdvIGVsZW1lbnRzOiB0aGUgZmlyc3Qgb25lIHRlbGxpbmcgaG93IG1hbnkgcm91bmRzIHRvIHBlcmZvcm0sCiAgICogdGhlIHNlY29uZCBvbmUgdGVsbGluZyB3aGF0IHRvIGRvIChpLmUuIHRoZSBmdW5jdGlvbiB0byBjYWxsKS4KICAgKgogICAqIEBwYXJhbSB7QXJyYXl9IHBsYW4gVGhlIHBsYW4gdG8gZXhlY3V0ZS4KICAgKi8KICB2YXIgcnVuUGxhbiA9IGZ1bmN0aW9uKHBsYW4pIHsKICAgIHZhciBSID0gW107CgogICAgLyogR2V0IGRhdGEgZnJvbSBpbnB1dCBidWZmZXIgYW5kIGZpbGwgdGhlIGZvdXIgd29yZHMgaW50byBSICovCiAgICBmb3IoaSA9IDA7IGkgPCA0OyBpICsrKSB7CiAgICAgIHZhciB2YWwgPSBfaW5wdXQuZ2V0SW50MTZMZSgpOwoKICAgICAgaWYoX2l2ICE9PSBudWxsKSB7CiAgICAgICAgaWYoZW5jcnlwdCkgewogICAgICAgICAgLyogV2UncmUgZW5jcnlwdGluZywgYXBwbHkgdGhlIElWIGZpcnN0LiAqLwogICAgICAgICAgdmFsIF49IF9pdi5nZXRJbnQxNkxlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8qIFdlJ3JlIGRlY3J5cHRpb24sIGtlZXAgY2lwaGVyIHRleHQgZm9yIG5leHQgYmxvY2suICovCiAgICAgICAgICBfaXYucHV0SW50MTZMZSh2YWwpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgUi5wdXNoKHZhbCAmIDB4ZmZmZik7CiAgICB9CgogICAgLyogUmVzZXQgZ2xvYmFsICJqIiB2YXJpYWJsZSBhcyBwZXIgc3BlYy4gKi8KICAgIGogPSBlbmNyeXB0ID8gMCA6IDYzOwoKICAgIC8qIFJ1biBleGVjdXRpb24gcGxhbi4gKi8KICAgIGZvcih2YXIgcHRyID0gMDsgcHRyIDwgcGxhbi5sZW5ndGg7IHB0ciArKykgewogICAgICBmb3IodmFyIGN0ciA9IDA7IGN0ciA8IHBsYW5bcHRyXVswXTsgY3RyICsrKSB7CiAgICAgICAgcGxhbltwdHJdWzFdKFIpOwogICAgICB9CiAgICB9CgogICAgLyogV3JpdGUgYmFjayByZXN1bHQgdG8gb3V0cHV0IGJ1ZmZlci4gKi8KICAgIGZvcihpID0gMDsgaSA8IDQ7IGkgKyspIHsKICAgICAgaWYoX2l2ICE9PSBudWxsKSB7CiAgICAgICAgaWYoZW5jcnlwdCkgewogICAgICAgICAgLyogV2UncmUgZW5jcnlwdGluZyBpbiBDQkMtbW9kZSwgZmVlZCBiYWNrIGVuY3J5cHRlZCBieXRlcyBpbnRvCiAgICAgICAgICAgICBJViBidWZmZXIgdG8gY2FycnkgaXQgZm9yd2FyZCB0byBuZXh0IGJsb2NrLiAqLwogICAgICAgICAgX2l2LnB1dEludDE2TGUoUltpXSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIFJbaV0gXj0gX2l2LmdldEludDE2TGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIF9vdXRwdXQucHV0SW50MTZMZShSW2ldKTsKICAgIH0KICB9OwoKCiAgLyogQ3JlYXRlIGNpcGhlciBvYmplY3QgKi8KICB2YXIgY2lwaGVyID0gbnVsbDsKICBjaXBoZXIgPSB7CiAgICAvKioKICAgICAqIFN0YXJ0cyBvciByZXN0YXJ0cyB0aGUgZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uIHByb2Nlc3MsIHdoaWNoZXZlcgogICAgICogd2FzIHByZXZpb3VzbHkgY29uZmlndXJlZC4KICAgICAqCiAgICAgKiBUbyB1c2UgdGhlIGNpcGhlciBpbiBDQkMgbW9kZSwgaXYgbWF5IGJlIGdpdmVuIGVpdGhlciBhcyBhIHN0cmluZwogICAgICogb2YgYnl0ZXMsIG9yIGFzIGEgYnl0ZSBidWZmZXIuICBGb3IgRUNCIG1vZGUsIGdpdmUgbnVsbCBhcyBpdi4KICAgICAqCiAgICAgKiBAcGFyYW0gaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UsIG51bGwgZm9yIEVDQiBtb2RlLgogICAgICogQHBhcmFtIG91dHB1dCB0aGUgb3V0cHV0IHRoZSBidWZmZXIgdG8gd3JpdGUgdG8sIG51bGwgdG8gY3JlYXRlIG9uZS4KICAgICAqLwogICAgc3RhcnQ6IGZ1bmN0aW9uKGl2LCBvdXRwdXQpIHsKICAgICAgaWYoaXYpIHsKICAgICAgICAvKiBDQkMgbW9kZSAqLwogICAgICAgIGlmKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgIGl2ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoaXYpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgX2ZpbmlzaCA9IGZhbHNlOwogICAgICBfaW5wdXQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgICBfb3V0cHV0ID0gb3V0cHV0IHx8IG5ldyBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgICBfaXYgPSBpdjsKCiAgICAgIGNpcGhlci5vdXRwdXQgPSBfb3V0cHV0OwogICAgfSwKCiAgICAvKioKICAgICAqIFVwZGF0ZXMgdGhlIG5leHQgYmxvY2suCiAgICAgKgogICAgICogQHBhcmFtIGlucHV0IHRoZSBidWZmZXIgdG8gcmVhZCBmcm9tLgogICAgICovCiAgICB1cGRhdGU6IGZ1bmN0aW9uKGlucHV0KSB7CiAgICAgIGlmKCFfZmluaXNoKSB7CiAgICAgICAgLy8gbm90IGZpbmlzaGluZywgc28gZmlsbCB0aGUgaW5wdXQgYnVmZmVyIHdpdGggbW9yZSBpbnB1dAogICAgICAgIF9pbnB1dC5wdXRCdWZmZXIoaW5wdXQpOwogICAgICB9CgogICAgICB3aGlsZShfaW5wdXQubGVuZ3RoKCkgPj0gOCkgewogICAgICAgIHJ1blBsYW4oWwogICAgICAgICAgICBbIDUsIG1peFJvdW5kIF0sCiAgICAgICAgICAgIFsgMSwgbWFzaFJvdW5kIF0sCiAgICAgICAgICAgIFsgNiwgbWl4Um91bmQgXSwKICAgICAgICAgICAgWyAxLCBtYXNoUm91bmQgXSwKICAgICAgICAgICAgWyA1LCBtaXhSb3VuZCBdCiAgICAgICAgICBdKTsKICAgICAgfQogICAgfSwKCiAgICAvKioKICAgICAqIEZpbmlzaGVzIGVuY3J5cHRpbmcgb3IgZGVjcnlwdGluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gcGFkIGEgcGFkZGluZyBmdW5jdGlvbiB0byB1c2UsIG51bGwgZm9yIFBLQ1MjNyBwYWRkaW5nLAogICAgICogICAgICAgICAgIHNpZ25hdHVyZShibG9ja1NpemUsIGJ1ZmZlciwgZGVjcnlwdCkuCiAgICAgKgogICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwsIGZhbHNlIG9uIGVycm9yLgogICAgICovCiAgICBmaW5pc2g6IGZ1bmN0aW9uKHBhZCkgewogICAgICB2YXIgcnZhbCA9IHRydWU7CgogICAgICBpZihlbmNyeXB0KSB7CiAgICAgICAgaWYocGFkKSB7CiAgICAgICAgICBydmFsID0gcGFkKDgsIF9pbnB1dCwgIWVuY3J5cHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBhZGQgUEtDUyM3IHBhZGRpbmcgdG8gYmxvY2sgKGVhY2ggcGFkIGJ5dGUgaXMgdGhlCiAgICAgICAgICAvLyB2YWx1ZSBvZiB0aGUgbnVtYmVyIG9mIHBhZCBieXRlcykKICAgICAgICAgIHZhciBwYWRkaW5nID0gKF9pbnB1dC5sZW5ndGgoKSA9PT0gOCkgPyA4IDogKDggLSBfaW5wdXQubGVuZ3RoKCkpOwogICAgICAgICAgX2lucHV0LmZpbGxXaXRoQnl0ZShwYWRkaW5nLCBwYWRkaW5nKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmKHJ2YWwpIHsKICAgICAgICAvLyBkbyBmaW5hbCB1cGRhdGUKICAgICAgICBfZmluaXNoID0gdHJ1ZTsKICAgICAgICBjaXBoZXIudXBkYXRlKCk7CiAgICAgIH0KCiAgICAgIGlmKCFlbmNyeXB0KSB7CiAgICAgICAgLy8gY2hlY2sgZm9yIGVycm9yOiBpbnB1dCBkYXRhIG5vdCBhIG11bHRpcGxlIG9mIGJsb2NrIHNpemUKICAgICAgICBydmFsID0gKF9pbnB1dC5sZW5ndGgoKSA9PT0gMCk7CiAgICAgICAgaWYocnZhbCkgewogICAgICAgICAgaWYocGFkKSB7CiAgICAgICAgICAgIHJ2YWwgPSBwYWQoOCwgX291dHB1dCwgIWVuY3J5cHQpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gZW5zdXJlIHBhZGRpbmcgYnl0ZSBjb3VudCBpcyB2YWxpZAogICAgICAgICAgICB2YXIgbGVuID0gX291dHB1dC5sZW5ndGgoKTsKICAgICAgICAgICAgdmFyIGNvdW50ID0gX291dHB1dC5hdChsZW4gLSAxKTsKCiAgICAgICAgICAgIGlmKGNvdW50ID4gbGVuKSB7CiAgICAgICAgICAgICAgcnZhbCA9IGZhbHNlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIC8vIHRyaW0gb2ZmIHBhZGRpbmcgYnl0ZXMKICAgICAgICAgICAgICBfb3V0cHV0LnRydW5jYXRlKGNvdW50KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgcmV0dXJuIHJ2YWw7CiAgICB9CiAgfTsKCiAgcmV0dXJuIGNpcGhlcjsKfTsKCgovKioKICogQ3JlYXRlcyBhbiBSQzIgY2lwaGVyIG9iamVjdCB0byBlbmNyeXB0IGRhdGEgaW4gRUNCIG9yIENCQyBtb2RlIHVzaW5nIHRoZQogKiBnaXZlbiBzeW1tZXRyaWMga2V5LiBUaGUgb3V0cHV0IHdpbGwgYmUgc3RvcmVkIGluIHRoZSAnb3V0cHV0JyBtZW1iZXIKICogb2YgdGhlIHJldHVybmVkIGNpcGhlci4KICoKICogVGhlIGtleSBhbmQgaXYgbWF5IGJlIGdpdmVuIGFzIGEgc3RyaW5nIG9mIGJ5dGVzIG9yIGEgYnl0ZSBidWZmZXIuCiAqIFRoZSBjaXBoZXIgaXMgaW5pdGlhbGl6ZWQgdG8gdXNlIDEyOCBlZmZlY3RpdmUga2V5IGJpdHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UuCiAqIEBwYXJhbSBvdXRwdXQgdGhlIGJ1ZmZlciB0byB3cml0ZSB0bywgbnVsbCB0byBjcmVhdGUgb25lLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwpmb3JnZS5yYzIuc3RhcnRFbmNyeXB0aW5nID0gZnVuY3Rpb24oa2V5LCBpdiwgb3V0cHV0KSB7CiAgdmFyIGNpcGhlciA9IGZvcmdlLnJjMi5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyKGtleSwgMTI4KTsKICBjaXBoZXIuc3RhcnQoaXYsIG91dHB1dCk7CiAgcmV0dXJuIGNpcGhlcjsKfTsKCi8qKgogKiBDcmVhdGVzIGFuIFJDMiBjaXBoZXIgb2JqZWN0IHRvIGVuY3J5cHQgZGF0YSBpbiBFQ0Igb3IgQ0JDIG1vZGUgdXNpbmcgdGhlCiAqIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqCiAqIFRoZSBrZXkgbWF5IGJlIGdpdmVuIGFzIGEgc3RyaW5nIG9mIGJ5dGVzIG9yIGEgYnl0ZSBidWZmZXIuCiAqCiAqIFRvIHN0YXJ0IGVuY3J5cHRpbmcgY2FsbCBzdGFydCgpIG9uIHRoZSBjaXBoZXIgd2l0aCBhbiBpdiBhbmQgb3B0aW9uYWwKICogb3V0cHV0IGJ1ZmZlci4KICoKICogQHBhcmFtIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLnJjMi5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyID0gZnVuY3Rpb24oa2V5LCBiaXRzKSB7CiAgcmV0dXJuIGNyZWF0ZUNpcGhlcihrZXksIGJpdHMsIHRydWUpOwp9OwoKLyoqCiAqIENyZWF0ZXMgYW4gUkMyIGNpcGhlciBvYmplY3QgdG8gZGVjcnlwdCBkYXRhIGluIEVDQiBvciBDQkMgbW9kZSB1c2luZyB0aGUKICogZ2l2ZW4gc3ltbWV0cmljIGtleS4gVGhlIG91dHB1dCB3aWxsIGJlIHN0b3JlZCBpbiB0aGUgJ291dHB1dCcgbWVtYmVyCiAqIG9mIHRoZSByZXR1cm5lZCBjaXBoZXIuCiAqCiAqIFRoZSBrZXkgYW5kIGl2IG1heSBiZSBnaXZlbiBhcyBhIHN0cmluZyBvZiBieXRlcyBvciBhIGJ5dGUgYnVmZmVyLgogKiBUaGUgY2lwaGVyIGlzIGluaXRpYWxpemVkIHRvIHVzZSAxMjggZWZmZWN0aXZlIGtleSBiaXRzLgogKgogKiBAcGFyYW0ga2V5IHRoZSBzeW1tZXRyaWMga2V5IHRvIHVzZS4KICogQHBhcmFtIGl2IHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IgdG8gdXNlLgogKiBAcGFyYW0gb3V0cHV0IHRoZSBidWZmZXIgdG8gd3JpdGUgdG8sIG51bGwgdG8gY3JlYXRlIG9uZS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZm9yZ2UucmMyLnN0YXJ0RGVjcnlwdGluZyA9IGZ1bmN0aW9uKGtleSwgaXYsIG91dHB1dCkgewogIHZhciBjaXBoZXIgPSBmb3JnZS5yYzIuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcihrZXksIDEyOCk7CiAgY2lwaGVyLnN0YXJ0KGl2LCBvdXRwdXQpOwogIHJldHVybiBjaXBoZXI7Cn07CgovKioKICogQ3JlYXRlcyBhbiBSQzIgY2lwaGVyIG9iamVjdCB0byBkZWNyeXB0IGRhdGEgaW4gRUNCIG9yIENCQyBtb2RlIHVzaW5nIHRoZQogKiBnaXZlbiBzeW1tZXRyaWMga2V5LgogKgogKiBUaGUga2V5IG1heSBiZSBnaXZlbiBhcyBhIHN0cmluZyBvZiBieXRlcyBvciBhIGJ5dGUgYnVmZmVyLgogKgogKiBUbyBzdGFydCBkZWNyeXB0aW5nIGNhbGwgc3RhcnQoKSBvbiB0aGUgY2lwaGVyIHdpdGggYW4gaXYgYW5kIG9wdGlvbmFsCiAqIG91dHB1dCBidWZmZXIuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwpmb3JnZS5yYzIuY3JlYXRlRGVjcnlwdGlvbkNpcGhlciA9IGZ1bmN0aW9uKGtleSwgYml0cykgewogIHJldHVybiBjcmVhdGVDaXBoZXIoa2V5LCBiaXRzLCBmYWxzZSk7Cn07Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdyYzInOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvcmMyJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8vIENvcHlyaWdodCAoYykgMjAwNSAgVG9tIFd1Ci8vIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi8vIFNlZSAiTElDRU5TRSIgZm9yIGRldGFpbHMuCgovLyBCYXNpYyBKYXZhU2NyaXB0IEJOIGxpYnJhcnkgLSBzdWJzZXQgdXNlZnVsIGZvciBSU0EgZW5jcnlwdGlvbi4KCi8qCkxpY2Vuc2luZyAoTElDRU5TRSkKLS0tLS0tLS0tLS0tLS0tLS0tLQoKVGhpcyBzb2Z0d2FyZSBpcyBjb3ZlcmVkIHVuZGVyIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0OgoqLwovKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMtMjAwNSAgVG9tIFd1CiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZwogKiBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUKICogIlNvZnR3YXJlIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZwogKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCiAqIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0bwogKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8KICogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZQogKiBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUy1JUyIgQU5EIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCiAqIEVYUFJFU1MsIElNUExJRUQgT1IgT1RIRVJXSVNFLCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OLCBBTlkKICogV0FSUkFOVFkgT0YgTUVSQ0hBTlRBQklMSVRZIE9SIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgogKgogKiBJTiBOTyBFVkVOVCBTSEFMTCBUT00gV1UgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5DSURFTlRBTCwKICogSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9GIEFOWSBLSU5ELCBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSCiAqIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgT1IgTk9UIEFEVklTRUQgT0YKICogVEhFIFBPU1NJQklMSVRZIE9GIERBTUFHRSwgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBBUklTSU5HIE9VVAogKiBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKgogKiBJbiBhZGRpdGlvbiwgdGhlIGZvbGxvd2luZyBjb25kaXRpb24gYXBwbGllczoKICoKICogQWxsIHJlZGlzdHJpYnV0aW9ucyBtdXN0IHJldGFpbiBhbiBpbnRhY3QgY29weSBvZiB0aGlzIGNvcHlyaWdodCBub3RpY2UKICogYW5kIGRpc2NsYWltZXIuCiAqLwovKgpBZGRyZXNzIGFsbCBxdWVzdGlvbnMgcmVnYXJkaW5nIHRoaXMgbGljZW5zZSB0bzoKCiAgVG9tIFd1CiAgdGp3QGNzLlN0YW5mb3JkLkVEVQoqLwoKKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIEJpdHMgcGVyIGRpZ2l0CnZhciBkYml0czsKCi8vIEphdmFTY3JpcHQgZW5naW5lIGFuYWx5c2lzCnZhciBjYW5hcnkgPSAweGRlYWRiZWVmY2FmZTsKdmFyIGpfbG0gPSAoKGNhbmFyeSYweGZmZmZmZik9PTB4ZWZjYWZlKTsKCi8vIChwdWJsaWMpIENvbnN0cnVjdG9yCmZ1bmN0aW9uIEJpZ0ludGVnZXIoYSxiLGMpIHsKICB0aGlzLmRhdGEgPSBbXTsKICBpZihhICE9IG51bGwpCiAgICBpZigibnVtYmVyIiA9PSB0eXBlb2YgYSkgdGhpcy5mcm9tTnVtYmVyKGEsYixjKTsKICAgIGVsc2UgaWYoYiA9PSBudWxsICYmICJzdHJpbmciICE9IHR5cGVvZiBhKSB0aGlzLmZyb21TdHJpbmcoYSwyNTYpOwogICAgZWxzZSB0aGlzLmZyb21TdHJpbmcoYSxiKTsKfQoKLy8gcmV0dXJuIG5ldywgdW5zZXQgQmlnSW50ZWdlcgpmdW5jdGlvbiBuYmkoKSB7IHJldHVybiBuZXcgQmlnSW50ZWdlcihudWxsKTsgfQoKLy8gYW06IENvbXB1dGUgd19qICs9ICh4KnRoaXNfaSksIHByb3BhZ2F0ZSBjYXJyaWVzLAovLyBjIGlzIGluaXRpYWwgY2FycnksIHJldHVybnMgZmluYWwgY2FycnkuCi8vIGMgPCAzKmR2YWx1ZSwgeCA8IDIqZHZhbHVlLCB0aGlzX2kgPCBkdmFsdWUKLy8gV2UgbmVlZCB0byBzZWxlY3QgdGhlIGZhc3Rlc3Qgb25lIHRoYXQgd29ya3MgaW4gdGhpcyBlbnZpcm9ubWVudC4KCi8vIGFtMTogdXNlIGEgc2luZ2xlIG11bHQgYW5kIGRpdmlkZSB0byBnZXQgdGhlIGhpZ2ggYml0cywKLy8gbWF4IGRpZ2l0IGJpdHMgc2hvdWxkIGJlIDI2IGJlY2F1c2UKLy8gbWF4IGludGVybmFsIHZhbHVlID0gMipkdmFsdWVeMi0yKmR2YWx1ZSAoPCAyXjUzKQpmdW5jdGlvbiBhbTEoaSx4LHcsaixjLG4pIHsKICB3aGlsZSgtLW4gPj0gMCkgewogICAgdmFyIHYgPSB4KnRoaXMuZGF0YVtpKytdK3cuZGF0YVtqXStjOwogICAgYyA9IE1hdGguZmxvb3Iodi8weDQwMDAwMDApOwogICAgdy5kYXRhW2orK10gPSB2JjB4M2ZmZmZmZjsKICB9CiAgcmV0dXJuIGM7Cn0KLy8gYW0yIGF2b2lkcyBhIGJpZyBtdWx0LWFuZC1leHRyYWN0IGNvbXBsZXRlbHkuCi8vIE1heCBkaWdpdCBiaXRzIHNob3VsZCBiZSA8PSAzMCBiZWNhdXNlIHdlIGRvIGJpdHdpc2Ugb3BzCi8vIG9uIHZhbHVlcyB1cCB0byAyKmhkdmFsdWVeMi1oZHZhbHVlLTEgKDwgMl4zMSkKZnVuY3Rpb24gYW0yKGkseCx3LGosYyxuKSB7CiAgdmFyIHhsID0geCYweDdmZmYsIHhoID0geD4+MTU7CiAgd2hpbGUoLS1uID49IDApIHsKICAgIHZhciBsID0gdGhpcy5kYXRhW2ldJjB4N2ZmZjsKICAgIHZhciBoID0gdGhpcy5kYXRhW2krK10+PjE1OwogICAgdmFyIG0gPSB4aCpsK2gqeGw7CiAgICBsID0geGwqbCsoKG0mMHg3ZmZmKTw8MTUpK3cuZGF0YVtqXSsoYyYweDNmZmZmZmZmKTsKICAgIGMgPSAobD4+PjMwKSsobT4+PjE1KSt4aCpoKyhjPj4+MzApOwogICAgdy5kYXRhW2orK10gPSBsJjB4M2ZmZmZmZmY7CiAgfQogIHJldHVybiBjOwp9Ci8vIEFsdGVybmF0ZWx5LCBzZXQgbWF4IGRpZ2l0IGJpdHMgdG8gMjggc2luY2Ugc29tZQovLyBicm93c2VycyBzbG93IGRvd24gd2hlbiBkZWFsaW5nIHdpdGggMzItYml0IG51bWJlcnMuCmZ1bmN0aW9uIGFtMyhpLHgsdyxqLGMsbikgewogIHZhciB4bCA9IHgmMHgzZmZmLCB4aCA9IHg+PjE0OwogIHdoaWxlKC0tbiA+PSAwKSB7CiAgICB2YXIgbCA9IHRoaXMuZGF0YVtpXSYweDNmZmY7CiAgICB2YXIgaCA9IHRoaXMuZGF0YVtpKytdPj4xNDsKICAgIHZhciBtID0geGgqbCtoKnhsOwogICAgbCA9IHhsKmwrKChtJjB4M2ZmZik8PDE0KSt3LmRhdGFbal0rYzsKICAgIGMgPSAobD4+MjgpKyhtPj4xNCkreGgqaDsKICAgIHcuZGF0YVtqKytdID0gbCYweGZmZmZmZmY7CiAgfQogIHJldHVybiBjOwp9CgovLyBub2RlLmpzIChubyBicm93c2VyKQppZih0eXBlb2YobmF2aWdhdG9yKSA9PT0gJ3VuZGVmaW5lZCcpCnsKICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYW0gPSBhbTM7CiAgIGRiaXRzID0gMjg7Cn0gZWxzZSBpZihqX2xtICYmIChuYXZpZ2F0b3IuYXBwTmFtZSA9PSAiTWljcm9zb2Z0IEludGVybmV0IEV4cGxvcmVyIikpIHsKICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMjsKICBkYml0cyA9IDMwOwp9IGVsc2UgaWYoal9sbSAmJiAobmF2aWdhdG9yLmFwcE5hbWUgIT0gIk5ldHNjYXBlIikpIHsKICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMTsKICBkYml0cyA9IDI2Owp9IGVsc2UgeyAvLyBNb3ppbGxhL05ldHNjYXBlIHNlZW1zIHRvIHByZWZlciBhbTMKICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMzsKICBkYml0cyA9IDI4Owp9CgpCaWdJbnRlZ2VyLnByb3RvdHlwZS5EQiA9IGRiaXRzOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5ETSA9ICgoMTw8ZGJpdHMpLTEpOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5EViA9ICgxPDxkYml0cyk7Cgp2YXIgQklfRlAgPSA1MjsKQmlnSW50ZWdlci5wcm90b3R5cGUuRlYgPSBNYXRoLnBvdygyLEJJX0ZQKTsKQmlnSW50ZWdlci5wcm90b3R5cGUuRjEgPSBCSV9GUC1kYml0czsKQmlnSW50ZWdlci5wcm90b3R5cGUuRjIgPSAyKmRiaXRzLUJJX0ZQOwoKLy8gRGlnaXQgY29udmVyc2lvbnMKdmFyIEJJX1JNID0gIjAxMjM0NTY3ODlhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiI7CnZhciBCSV9SQyA9IG5ldyBBcnJheSgpOwp2YXIgcnIsdnY7CnJyID0gIjAiLmNoYXJDb2RlQXQoMCk7CmZvcih2diA9IDA7IHZ2IDw9IDk7ICsrdnYpIEJJX1JDW3JyKytdID0gdnY7CnJyID0gImEiLmNoYXJDb2RlQXQoMCk7CmZvcih2diA9IDEwOyB2diA8IDM2OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2OwpyciA9ICJBIi5jaGFyQ29kZUF0KDApOwpmb3IodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2djsKCmZ1bmN0aW9uIGludDJjaGFyKG4pIHsgcmV0dXJuIEJJX1JNLmNoYXJBdChuKTsgfQpmdW5jdGlvbiBpbnRBdChzLGkpIHsKICB2YXIgYyA9IEJJX1JDW3MuY2hhckNvZGVBdChpKV07CiAgcmV0dXJuIChjPT1udWxsKT8tMTpjOwp9CgovLyAocHJvdGVjdGVkKSBjb3B5IHRoaXMgdG8gcgpmdW5jdGlvbiBibnBDb3B5VG8ocikgewogIGZvcih2YXIgaSA9IHRoaXMudC0xOyBpID49IDA7IC0taSkgci5kYXRhW2ldID0gdGhpcy5kYXRhW2ldOwogIHIudCA9IHRoaXMudDsKICByLnMgPSB0aGlzLnM7Cn0KCi8vIChwcm90ZWN0ZWQpIHNldCBmcm9tIGludGVnZXIgdmFsdWUgeCwgLURWIDw9IHggPCBEVgpmdW5jdGlvbiBibnBGcm9tSW50KHgpIHsKICB0aGlzLnQgPSAxOwogIHRoaXMucyA9ICh4PDApPy0xOjA7CiAgaWYoeCA+IDApIHRoaXMuZGF0YVswXSA9IHg7CiAgZWxzZSBpZih4IDwgLTEpIHRoaXMuZGF0YVswXSA9IHgrdGhpcy5EVjsKICBlbHNlIHRoaXMudCA9IDA7Cn0KCi8vIHJldHVybiBiaWdpbnQgaW5pdGlhbGl6ZWQgdG8gdmFsdWUKZnVuY3Rpb24gbmJ2KGkpIHsgdmFyIHIgPSBuYmkoKTsgci5mcm9tSW50KGkpOyByZXR1cm4gcjsgfQoKLy8gKHByb3RlY3RlZCkgc2V0IGZyb20gc3RyaW5nIGFuZCByYWRpeApmdW5jdGlvbiBibnBGcm9tU3RyaW5nKHMsYikgewogIHZhciBrOwogIGlmKGIgPT0gMTYpIGsgPSA0OwogIGVsc2UgaWYoYiA9PSA4KSBrID0gMzsKICBlbHNlIGlmKGIgPT0gMjU2KSBrID0gODsgLy8gYnl0ZSBhcnJheQogIGVsc2UgaWYoYiA9PSAyKSBrID0gMTsKICBlbHNlIGlmKGIgPT0gMzIpIGsgPSA1OwogIGVsc2UgaWYoYiA9PSA0KSBrID0gMjsKICBlbHNlIHsgdGhpcy5mcm9tUmFkaXgocyxiKTsgcmV0dXJuOyB9CiAgdGhpcy50ID0gMDsKICB0aGlzLnMgPSAwOwogIHZhciBpID0gcy5sZW5ndGgsIG1pID0gZmFsc2UsIHNoID0gMDsKICB3aGlsZSgtLWkgPj0gMCkgewogICAgdmFyIHggPSAoaz09OCk/c1tpXSYweGZmOmludEF0KHMsaSk7CiAgICBpZih4IDwgMCkgewogICAgICBpZihzLmNoYXJBdChpKSA9PSAiLSIpIG1pID0gdHJ1ZTsKICAgICAgY29udGludWU7CiAgICB9CiAgICBtaSA9IGZhbHNlOwogICAgaWYoc2ggPT0gMCkKICAgICAgdGhpcy5kYXRhW3RoaXMudCsrXSA9IHg7CiAgICBlbHNlIGlmKHNoK2sgPiB0aGlzLkRCKSB7CiAgICAgIHRoaXMuZGF0YVt0aGlzLnQtMV0gfD0gKHgmKCgxPDwodGhpcy5EQi1zaCkpLTEpKTw8c2g7CiAgICAgIHRoaXMuZGF0YVt0aGlzLnQrK10gPSAoeD4+KHRoaXMuREItc2gpKTsKICAgIH0gZWxzZQogICAgICB0aGlzLmRhdGFbdGhpcy50LTFdIHw9IHg8PHNoOwogICAgc2ggKz0gazsKICAgIGlmKHNoID49IHRoaXMuREIpIHNoIC09IHRoaXMuREI7CiAgfQogIGlmKGsgPT0gOCAmJiAoc1swXSYweDgwKSAhPSAwKSB7CiAgICB0aGlzLnMgPSAtMTsKICAgIGlmKHNoID4gMCkgdGhpcy5kYXRhW3RoaXMudC0xXSB8PSAoKDE8PCh0aGlzLkRCLXNoKSktMSk8PHNoOwogIH0KICB0aGlzLmNsYW1wKCk7CiAgaWYobWkpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLHRoaXMpOwp9CgovLyAocHJvdGVjdGVkKSBjbGFtcCBvZmYgZXhjZXNzIGhpZ2ggd29yZHMKZnVuY3Rpb24gYm5wQ2xhbXAoKSB7CiAgdmFyIGMgPSB0aGlzLnMmdGhpcy5ETTsKICB3aGlsZSh0aGlzLnQgPiAwICYmIHRoaXMuZGF0YVt0aGlzLnQtMV0gPT0gYykgLS10aGlzLnQ7Cn0KCi8vIChwdWJsaWMpIHJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24gaW4gZ2l2ZW4gcmFkaXgKZnVuY3Rpb24gYm5Ub1N0cmluZyhiKSB7CiAgaWYodGhpcy5zIDwgMCkgcmV0dXJuICItIit0aGlzLm5lZ2F0ZSgpLnRvU3RyaW5nKGIpOwogIHZhciBrOwogIGlmKGIgPT0gMTYpIGsgPSA0OwogIGVsc2UgaWYoYiA9PSA4KSBrID0gMzsKICBlbHNlIGlmKGIgPT0gMikgayA9IDE7CiAgZWxzZSBpZihiID09IDMyKSBrID0gNTsKICBlbHNlIGlmKGIgPT0gNCkgayA9IDI7CiAgZWxzZSByZXR1cm4gdGhpcy50b1JhZGl4KGIpOwogIHZhciBrbSA9ICgxPDxrKS0xLCBkLCBtID0gZmFsc2UsIHIgPSAiIiwgaSA9IHRoaXMudDsKICB2YXIgcCA9IHRoaXMuREItKGkqdGhpcy5EQiklazsKICBpZihpLS0gPiAwKSB7CiAgICBpZihwIDwgdGhpcy5EQiAmJiAoZCA9IHRoaXMuZGF0YVtpXT4+cCkgPiAwKSB7IG0gPSB0cnVlOyByID0gaW50MmNoYXIoZCk7IH0KICAgIHdoaWxlKGkgPj0gMCkgewogICAgICBpZihwIDwgaykgewogICAgICAgIGQgPSAodGhpcy5kYXRhW2ldJigoMTw8cCktMSkpPDwoay1wKTsKICAgICAgICBkIHw9IHRoaXMuZGF0YVstLWldPj4ocCs9dGhpcy5EQi1rKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkID0gKHRoaXMuZGF0YVtpXT4+KHAtPWspKSZrbTsKICAgICAgICBpZihwIDw9IDApIHsgcCArPSB0aGlzLkRCOyAtLWk7IH0KICAgICAgfQogICAgICBpZihkID4gMCkgbSA9IHRydWU7CiAgICAgIGlmKG0pIHIgKz0gaW50MmNoYXIoZCk7CiAgICB9CiAgfQogIHJldHVybiBtP3I6IjAiOwp9CgovLyAocHVibGljKSAtdGhpcwpmdW5jdGlvbiBibk5lZ2F0ZSgpIHsgdmFyIHIgPSBuYmkoKTsgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMscik7IHJldHVybiByOyB9CgovLyAocHVibGljKSB8dGhpc3wKZnVuY3Rpb24gYm5BYnMoKSB7IHJldHVybiAodGhpcy5zPDApP3RoaXMubmVnYXRlKCk6dGhpczsgfQoKLy8gKHB1YmxpYykgcmV0dXJuICsgaWYgdGhpcyA+IGEsIC0gaWYgdGhpcyA8IGEsIDAgaWYgZXF1YWwKZnVuY3Rpb24gYm5Db21wYXJlVG8oYSkgewogIHZhciByID0gdGhpcy5zLWEuczsKICBpZihyICE9IDApIHJldHVybiByOwogIHZhciBpID0gdGhpcy50OwogIHIgPSBpLWEudDsKICBpZihyICE9IDApIHJldHVybiAodGhpcy5zPDApPy1yOnI7CiAgd2hpbGUoLS1pID49IDApIGlmKChyPXRoaXMuZGF0YVtpXS1hLmRhdGFbaV0pICE9IDApIHJldHVybiByOwogIHJldHVybiAwOwp9CgovLyByZXR1cm5zIGJpdCBsZW5ndGggb2YgdGhlIGludGVnZXIgeApmdW5jdGlvbiBuYml0cyh4KSB7CiAgdmFyIHIgPSAxLCB0OwogIGlmKCh0PXg+Pj4xNikgIT0gMCkgeyB4ID0gdDsgciArPSAxNjsgfQogIGlmKCh0PXg+PjgpICE9IDApIHsgeCA9IHQ7IHIgKz0gODsgfQogIGlmKCh0PXg+PjQpICE9IDApIHsgeCA9IHQ7IHIgKz0gNDsgfQogIGlmKCh0PXg+PjIpICE9IDApIHsgeCA9IHQ7IHIgKz0gMjsgfQogIGlmKCh0PXg+PjEpICE9IDApIHsgeCA9IHQ7IHIgKz0gMTsgfQogIHJldHVybiByOwp9CgovLyAocHVibGljKSByZXR1cm4gdGhlIG51bWJlciBvZiBiaXRzIGluICJ0aGlzIgpmdW5jdGlvbiBibkJpdExlbmd0aCgpIHsKICBpZih0aGlzLnQgPD0gMCkgcmV0dXJuIDA7CiAgcmV0dXJuIHRoaXMuREIqKHRoaXMudC0xKStuYml0cyh0aGlzLmRhdGFbdGhpcy50LTFdXih0aGlzLnMmdGhpcy5ETSkpOwp9CgovLyAocHJvdGVjdGVkKSByID0gdGhpcyA8PCBuKkRCCmZ1bmN0aW9uIGJucERMU2hpZnRUbyhuLHIpIHsKICB2YXIgaTsKICBmb3IoaSA9IHRoaXMudC0xOyBpID49IDA7IC0taSkgci5kYXRhW2krbl0gPSB0aGlzLmRhdGFbaV07CiAgZm9yKGkgPSBuLTE7IGkgPj0gMDsgLS1pKSByLmRhdGFbaV0gPSAwOwogIHIudCA9IHRoaXMudCtuOwogIHIucyA9IHRoaXMuczsKfQoKLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPj4gbipEQgpmdW5jdGlvbiBibnBEUlNoaWZ0VG8obixyKSB7CiAgZm9yKHZhciBpID0gbjsgaSA8IHRoaXMudDsgKytpKSByLmRhdGFbaS1uXSA9IHRoaXMuZGF0YVtpXTsKICByLnQgPSBNYXRoLm1heCh0aGlzLnQtbiwwKTsKICByLnMgPSB0aGlzLnM7Cn0KCi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG4KZnVuY3Rpb24gYm5wTFNoaWZ0VG8obixyKSB7CiAgdmFyIGJzID0gbiV0aGlzLkRCOwogIHZhciBjYnMgPSB0aGlzLkRCLWJzOwogIHZhciBibSA9ICgxPDxjYnMpLTE7CiAgdmFyIGRzID0gTWF0aC5mbG9vcihuL3RoaXMuREIpLCBjID0gKHRoaXMuczw8YnMpJnRoaXMuRE0sIGk7CiAgZm9yKGkgPSB0aGlzLnQtMTsgaSA+PSAwOyAtLWkpIHsKICAgIHIuZGF0YVtpK2RzKzFdID0gKHRoaXMuZGF0YVtpXT4+Y2JzKXxjOwogICAgYyA9ICh0aGlzLmRhdGFbaV0mYm0pPDxiczsKICB9CiAgZm9yKGkgPSBkcy0xOyBpID49IDA7IC0taSkgci5kYXRhW2ldID0gMDsKICByLmRhdGFbZHNdID0gYzsKICByLnQgPSB0aGlzLnQrZHMrMTsKICByLnMgPSB0aGlzLnM7CiAgci5jbGFtcCgpOwp9CgovLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuCmZ1bmN0aW9uIGJucFJTaGlmdFRvKG4scikgewogIHIucyA9IHRoaXMuczsKICB2YXIgZHMgPSBNYXRoLmZsb29yKG4vdGhpcy5EQik7CiAgaWYoZHMgPj0gdGhpcy50KSB7IHIudCA9IDA7IHJldHVybjsgfQogIHZhciBicyA9IG4ldGhpcy5EQjsKICB2YXIgY2JzID0gdGhpcy5EQi1iczsKICB2YXIgYm0gPSAoMTw8YnMpLTE7CiAgci5kYXRhWzBdID0gdGhpcy5kYXRhW2RzXT4+YnM7CiAgZm9yKHZhciBpID0gZHMrMTsgaSA8IHRoaXMudDsgKytpKSB7CiAgICByLmRhdGFbaS1kcy0xXSB8PSAodGhpcy5kYXRhW2ldJmJtKTw8Y2JzOwogICAgci5kYXRhW2ktZHNdID0gdGhpcy5kYXRhW2ldPj5iczsKICB9CiAgaWYoYnMgPiAwKSByLmRhdGFbdGhpcy50LWRzLTFdIHw9ICh0aGlzLnMmYm0pPDxjYnM7CiAgci50ID0gdGhpcy50LWRzOwogIHIuY2xhbXAoKTsKfQoKLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgLSBhCmZ1bmN0aW9uIGJucFN1YlRvKGEscikgewogIHZhciBpID0gMCwgYyA9IDAsIG0gPSBNYXRoLm1pbihhLnQsdGhpcy50KTsKICB3aGlsZShpIDwgbSkgewogICAgYyArPSB0aGlzLmRhdGFbaV0tYS5kYXRhW2ldOwogICAgci5kYXRhW2krK10gPSBjJnRoaXMuRE07CiAgICBjID4+PSB0aGlzLkRCOwogIH0KICBpZihhLnQgPCB0aGlzLnQpIHsKICAgIGMgLT0gYS5zOwogICAgd2hpbGUoaSA8IHRoaXMudCkgewogICAgICBjICs9IHRoaXMuZGF0YVtpXTsKICAgICAgci5kYXRhW2krK10gPSBjJnRoaXMuRE07CiAgICAgIGMgPj49IHRoaXMuREI7CiAgICB9CiAgICBjICs9IHRoaXMuczsKICB9IGVsc2UgewogICAgYyArPSB0aGlzLnM7CiAgICB3aGlsZShpIDwgYS50KSB7CiAgICAgIGMgLT0gYS5kYXRhW2ldOwogICAgICByLmRhdGFbaSsrXSA9IGMmdGhpcy5ETTsKICAgICAgYyA+Pj0gdGhpcy5EQjsKICAgIH0KICAgIGMgLT0gYS5zOwogIH0KICByLnMgPSAoYzwwKT8tMTowOwogIGlmKGMgPCAtMSkgci5kYXRhW2krK10gPSB0aGlzLkRWK2M7CiAgZWxzZSBpZihjID4gMCkgci5kYXRhW2krK10gPSBjOwogIHIudCA9IGk7CiAgci5jbGFtcCgpOwp9CgovLyAocHJvdGVjdGVkKSByID0gdGhpcyAqIGEsIHIgIT0gdGhpcyxhIChIQUMgMTQuMTIpCi8vICJ0aGlzIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuCmZ1bmN0aW9uIGJucE11bHRpcGx5VG8oYSxyKSB7CiAgdmFyIHggPSB0aGlzLmFicygpLCB5ID0gYS5hYnMoKTsKICB2YXIgaSA9IHgudDsKICByLnQgPSBpK3kudDsKICB3aGlsZSgtLWkgPj0gMCkgci5kYXRhW2ldID0gMDsKICBmb3IoaSA9IDA7IGkgPCB5LnQ7ICsraSkgci5kYXRhW2kreC50XSA9IHguYW0oMCx5LmRhdGFbaV0scixpLDAseC50KTsKICByLnMgPSAwOwogIHIuY2xhbXAoKTsKICBpZih0aGlzLnMgIT0gYS5zKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ocixyKTsKfQoKLy8gKHByb3RlY3RlZCkgciA9IHRoaXNeMiwgciAhPSB0aGlzIChIQUMgMTQuMTYpCmZ1bmN0aW9uIGJucFNxdWFyZVRvKHIpIHsKICB2YXIgeCA9IHRoaXMuYWJzKCk7CiAgdmFyIGkgPSByLnQgPSAyKngudDsKICB3aGlsZSgtLWkgPj0gMCkgci5kYXRhW2ldID0gMDsKICBmb3IoaSA9IDA7IGkgPCB4LnQtMTsgKytpKSB7CiAgICB2YXIgYyA9IHguYW0oaSx4LmRhdGFbaV0sciwyKmksMCwxKTsKICAgIGlmKChyLmRhdGFbaSt4LnRdKz14LmFtKGkrMSwyKnguZGF0YVtpXSxyLDIqaSsxLGMseC50LWktMSkpID49IHguRFYpIHsKICAgICAgci5kYXRhW2kreC50XSAtPSB4LkRWOwogICAgICByLmRhdGFbaSt4LnQrMV0gPSAxOwogICAgfQogIH0KICBpZihyLnQgPiAwKSByLmRhdGFbci50LTFdICs9IHguYW0oaSx4LmRhdGFbaV0sciwyKmksMCwxKTsKICByLnMgPSAwOwogIHIuY2xhbXAoKTsKfQoKLy8gKHByb3RlY3RlZCkgZGl2aWRlIHRoaXMgYnkgbSwgcXVvdGllbnQgYW5kIHJlbWFpbmRlciB0byBxLCByIChIQUMgMTQuMjApCi8vIHIgIT0gcSwgdGhpcyAhPSBtLiAgcSBvciByIG1heSBiZSBudWxsLgpmdW5jdGlvbiBibnBEaXZSZW1UbyhtLHEscikgewogIHZhciBwbSA9IG0uYWJzKCk7CiAgaWYocG0udCA8PSAwKSByZXR1cm47CiAgdmFyIHB0ID0gdGhpcy5hYnMoKTsKICBpZihwdC50IDwgcG0udCkgewogICAgaWYocSAhPSBudWxsKSBxLmZyb21JbnQoMCk7CiAgICBpZihyICE9IG51bGwpIHRoaXMuY29weVRvKHIpOwogICAgcmV0dXJuOwogIH0KICBpZihyID09IG51bGwpIHIgPSBuYmkoKTsKICB2YXIgeSA9IG5iaSgpLCB0cyA9IHRoaXMucywgbXMgPSBtLnM7CiAgdmFyIG5zaCA9IHRoaXMuREItbmJpdHMocG0uZGF0YVtwbS50LTFdKTsJLy8gbm9ybWFsaXplIG1vZHVsdXMKICBpZihuc2ggPiAwKSB7IHBtLmxTaGlmdFRvKG5zaCx5KTsgcHQubFNoaWZ0VG8obnNoLHIpOyB9IGVsc2UgeyBwbS5jb3B5VG8oeSk7IHB0LmNvcHlUbyhyKTsgfQogIHZhciB5cyA9IHkudDsKICB2YXIgeTAgPSB5LmRhdGFbeXMtMV07CiAgaWYoeTAgPT0gMCkgcmV0dXJuOwogIHZhciB5dCA9IHkwKigxPDx0aGlzLkYxKSsoKHlzPjEpP3kuZGF0YVt5cy0yXT4+dGhpcy5GMjowKTsKICB2YXIgZDEgPSB0aGlzLkZWL3l0LCBkMiA9ICgxPDx0aGlzLkYxKS95dCwgZSA9IDE8PHRoaXMuRjI7CiAgdmFyIGkgPSByLnQsIGogPSBpLXlzLCB0ID0gKHE9PW51bGwpP25iaSgpOnE7CiAgeS5kbFNoaWZ0VG8oaix0KTsKICBpZihyLmNvbXBhcmVUbyh0KSA+PSAwKSB7CiAgICByLmRhdGFbci50KytdID0gMTsKICAgIHIuc3ViVG8odCxyKTsKICB9CiAgQmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKHlzLHQpOwogIHQuc3ViVG8oeSx5KTsJLy8gIm5lZ2F0aXZlIiB5IHNvIHdlIGNhbiByZXBsYWNlIHN1YiB3aXRoIGFtIGxhdGVyCiAgd2hpbGUoeS50IDwgeXMpIHkuZGF0YVt5LnQrK10gPSAwOwogIHdoaWxlKC0taiA+PSAwKSB7CiAgICAvLyBFc3RpbWF0ZSBxdW90aWVudCBkaWdpdAogICAgdmFyIHFkID0gKHIuZGF0YVstLWldPT15MCk/dGhpcy5ETTpNYXRoLmZsb29yKHIuZGF0YVtpXSpkMSsoci5kYXRhW2ktMV0rZSkqZDIpOwogICAgaWYoKHIuZGF0YVtpXSs9eS5hbSgwLHFkLHIsaiwwLHlzKSkgPCBxZCkgewkvLyBUcnkgaXQgb3V0CiAgICAgIHkuZGxTaGlmdFRvKGosdCk7CiAgICAgIHIuc3ViVG8odCxyKTsKICAgICAgd2hpbGUoci5kYXRhW2ldIDwgLS1xZCkgci5zdWJUbyh0LHIpOwogICAgfQogIH0KICBpZihxICE9IG51bGwpIHsKICAgIHIuZHJTaGlmdFRvKHlzLHEpOwogICAgaWYodHMgIT0gbXMpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhxLHEpOwogIH0KICByLnQgPSB5czsKICByLmNsYW1wKCk7CiAgaWYobnNoID4gMCkgci5yU2hpZnRUbyhuc2gscik7CS8vIERlbm9ybWFsaXplIHJlbWFpbmRlcgogIGlmKHRzIDwgMCkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIscik7Cn0KCi8vIChwdWJsaWMpIHRoaXMgbW9kIGEKZnVuY3Rpb24gYm5Nb2QoYSkgewogIHZhciByID0gbmJpKCk7CiAgdGhpcy5hYnMoKS5kaXZSZW1UbyhhLG51bGwscik7CiAgaWYodGhpcy5zIDwgMCAmJiByLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID4gMCkgYS5zdWJUbyhyLHIpOwogIHJldHVybiByOwp9CgovLyBNb2R1bGFyIHJlZHVjdGlvbiB1c2luZyAiY2xhc3NpYyIgYWxnb3JpdGhtCmZ1bmN0aW9uIENsYXNzaWMobSkgeyB0aGlzLm0gPSBtOyB9CmZ1bmN0aW9uIGNDb252ZXJ0KHgpIHsKICBpZih4LnMgPCAwIHx8IHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgcmV0dXJuIHgubW9kKHRoaXMubSk7CiAgZWxzZSByZXR1cm4geDsKfQpmdW5jdGlvbiBjUmV2ZXJ0KHgpIHsgcmV0dXJuIHg7IH0KZnVuY3Rpb24gY1JlZHVjZSh4KSB7IHguZGl2UmVtVG8odGhpcy5tLG51bGwseCk7IH0KZnVuY3Rpb24gY011bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB0aGlzLnJlZHVjZShyKTsgfQpmdW5jdGlvbiBjU3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IHRoaXMucmVkdWNlKHIpOyB9CgpDbGFzc2ljLnByb3RvdHlwZS5jb252ZXJ0ID0gY0NvbnZlcnQ7CkNsYXNzaWMucHJvdG90eXBlLnJldmVydCA9IGNSZXZlcnQ7CkNsYXNzaWMucHJvdG90eXBlLnJlZHVjZSA9IGNSZWR1Y2U7CkNsYXNzaWMucHJvdG90eXBlLm11bFRvID0gY011bFRvOwpDbGFzc2ljLnByb3RvdHlwZS5zcXJUbyA9IGNTcXJUbzsKCi8vIChwcm90ZWN0ZWQpIHJldHVybiAiLTEvdGhpcyAlIDJeREIiOyB1c2VmdWwgZm9yIE1vbnQuIHJlZHVjdGlvbgovLyBqdXN0aWZpY2F0aW9uOgovLyAgICAgICAgIHh5ID09IDEgKG1vZCBtKQovLyAgICAgICAgIHh5ID0gIDEra20KLy8gICB4eSgyLXh5KSA9ICgxK2ttKSgxLWttKQovLyB4W3koMi14eSldID0gMS1rXjJtXjIKLy8geFt5KDIteHkpXSA9PSAxIChtb2QgbV4yKQovLyBpZiB5IGlzIDEveCBtb2QgbSwgdGhlbiB5KDIteHkpIGlzIDEveCBtb2QgbV4yCi8vIHNob3VsZCByZWR1Y2UgeCBhbmQgeSgyLXh5KSBieSBtXjIgYXQgZWFjaCBzdGVwIHRvIGtlZXAgc2l6ZSBib3VuZGVkLgovLyBKUyBtdWx0aXBseSAib3ZlcmZsb3dzIiBkaWZmZXJlbnRseSBmcm9tIEMvQysrLCBzbyBjYXJlIGlzIG5lZWRlZCBoZXJlLgpmdW5jdGlvbiBibnBJbnZEaWdpdCgpIHsKICBpZih0aGlzLnQgPCAxKSByZXR1cm4gMDsKICB2YXIgeCA9IHRoaXMuZGF0YVswXTsKICBpZigoeCYxKSA9PSAwKSByZXR1cm4gMDsKICB2YXIgeSA9IHgmMzsJCS8vIHkgPT0gMS94IG1vZCAyXjIKICB5ID0gKHkqKDItKHgmMHhmKSp5KSkmMHhmOwkvLyB5ID09IDEveCBtb2QgMl40CiAgeSA9ICh5KigyLSh4JjB4ZmYpKnkpKSYweGZmOwkvLyB5ID09IDEveCBtb2QgMl44CiAgeSA9ICh5KigyLSgoKHgmMHhmZmZmKSp5KSYweGZmZmYpKSkmMHhmZmZmOwkvLyB5ID09IDEveCBtb2QgMl4xNgogIC8vIGxhc3Qgc3RlcCAtIGNhbGN1bGF0ZSBpbnZlcnNlIG1vZCBEViBkaXJlY3RseTsKICAvLyBhc3N1bWVzIDE2IDwgREIgPD0gMzIgYW5kIGFzc3VtZXMgYWJpbGl0eSB0byBoYW5kbGUgNDgtYml0IGludHMKICB5ID0gKHkqKDIteCp5JXRoaXMuRFYpKSV0aGlzLkRWOwkJLy8geSA9PSAxL3ggbW9kIDJeZGJpdHMKICAvLyB3ZSByZWFsbHkgd2FudCB0aGUgbmVnYXRpdmUgaW52ZXJzZSwgYW5kIC1EViA8IHkgPCBEVgogIHJldHVybiAoeT4wKT90aGlzLkRWLXk6LXk7Cn0KCi8vIE1vbnRnb21lcnkgcmVkdWN0aW9uCmZ1bmN0aW9uIE1vbnRnb21lcnkobSkgewogIHRoaXMubSA9IG07CiAgdGhpcy5tcCA9IG0uaW52RGlnaXQoKTsKICB0aGlzLm1wbCA9IHRoaXMubXAmMHg3ZmZmOwogIHRoaXMubXBoID0gdGhpcy5tcD4+MTU7CiAgdGhpcy51bSA9ICgxPDwobS5EQi0xNSkpLTE7CiAgdGhpcy5tdDIgPSAyKm0udDsKfQoKLy8geFIgbW9kIG0KZnVuY3Rpb24gbW9udENvbnZlcnQoeCkgewogIHZhciByID0gbmJpKCk7CiAgeC5hYnMoKS5kbFNoaWZ0VG8odGhpcy5tLnQscik7CiAgci5kaXZSZW1Ubyh0aGlzLm0sbnVsbCxyKTsKICBpZih4LnMgPCAwICYmIHIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPiAwKSB0aGlzLm0uc3ViVG8ocixyKTsKICByZXR1cm4gcjsKfQoKLy8geC9SIG1vZCBtCmZ1bmN0aW9uIG1vbnRSZXZlcnQoeCkgewogIHZhciByID0gbmJpKCk7CiAgeC5jb3B5VG8ocik7CiAgdGhpcy5yZWR1Y2Uocik7CiAgcmV0dXJuIHI7Cn0KCi8vIHggPSB4L1IgbW9kIG0gKEhBQyAxNC4zMikKZnVuY3Rpb24gbW9udFJlZHVjZSh4KSB7CiAgd2hpbGUoeC50IDw9IHRoaXMubXQyKQkvLyBwYWQgeCBzbyBhbSBoYXMgZW5vdWdoIHJvb20gbGF0ZXIKICAgIHguZGF0YVt4LnQrK10gPSAwOwogIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLm0udDsgKytpKSB7CiAgICAvLyBmYXN0ZXIgd2F5IG9mIGNhbGN1bGF0aW5nIHUwID0geC5kYXRhW2ldKm1wIG1vZCBEVgogICAgdmFyIGogPSB4LmRhdGFbaV0mMHg3ZmZmOwogICAgdmFyIHUwID0gKGoqdGhpcy5tcGwrKCgoaip0aGlzLm1waCsoeC5kYXRhW2ldPj4xNSkqdGhpcy5tcGwpJnRoaXMudW0pPDwxNSkpJnguRE07CiAgICAvLyB1c2UgYW0gdG8gY29tYmluZSB0aGUgbXVsdGlwbHktc2hpZnQtYWRkIGludG8gb25lIGNhbGwKICAgIGogPSBpK3RoaXMubS50OwogICAgeC5kYXRhW2pdICs9IHRoaXMubS5hbSgwLHUwLHgsaSwwLHRoaXMubS50KTsKICAgIC8vIHByb3BhZ2F0ZSBjYXJyeQogICAgd2hpbGUoeC5kYXRhW2pdID49IHguRFYpIHsgeC5kYXRhW2pdIC09IHguRFY7IHguZGF0YVsrK2pdKys7IH0KICB9CiAgeC5jbGFtcCgpOwogIHguZHJTaGlmdFRvKHRoaXMubS50LHgpOwogIGlmKHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgeC5zdWJUbyh0aGlzLm0seCk7Cn0KCi8vIHIgPSAieF4yL1IgbW9kIG0iOyB4ICE9IHIKZnVuY3Rpb24gbW9udFNxclRvKHgscikgeyB4LnNxdWFyZVRvKHIpOyB0aGlzLnJlZHVjZShyKTsgfQoKLy8gciA9ICJ4eS9SIG1vZCBtIjsgeCx5ICE9IHIKZnVuY3Rpb24gbW9udE11bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB0aGlzLnJlZHVjZShyKTsgfQoKTW9udGdvbWVyeS5wcm90b3R5cGUuY29udmVydCA9IG1vbnRDb252ZXJ0OwpNb250Z29tZXJ5LnByb3RvdHlwZS5yZXZlcnQgPSBtb250UmV2ZXJ0OwpNb250Z29tZXJ5LnByb3RvdHlwZS5yZWR1Y2UgPSBtb250UmVkdWNlOwpNb250Z29tZXJ5LnByb3RvdHlwZS5tdWxUbyA9IG1vbnRNdWxUbzsKTW9udGdvbWVyeS5wcm90b3R5cGUuc3FyVG8gPSBtb250U3FyVG87CgovLyAocHJvdGVjdGVkKSB0cnVlIGlmZiB0aGlzIGlzIGV2ZW4KZnVuY3Rpb24gYm5wSXNFdmVuKCkgeyByZXR1cm4gKCh0aGlzLnQ+MCk/KHRoaXMuZGF0YVswXSYxKTp0aGlzLnMpID09IDA7IH0KCi8vIChwcm90ZWN0ZWQpIHRoaXNeZSwgZSA8IDJeMzIsIGRvaW5nIHNxciBhbmQgbXVsIHdpdGggInIiIChIQUMgMTQuNzkpCmZ1bmN0aW9uIGJucEV4cChlLHopIHsKICBpZihlID4gMHhmZmZmZmZmZiB8fCBlIDwgMSkgcmV0dXJuIEJpZ0ludGVnZXIuT05FOwogIHZhciByID0gbmJpKCksIHIyID0gbmJpKCksIGcgPSB6LmNvbnZlcnQodGhpcyksIGkgPSBuYml0cyhlKS0xOwogIGcuY29weVRvKHIpOwogIHdoaWxlKC0taSA+PSAwKSB7CiAgICB6LnNxclRvKHIscjIpOwogICAgaWYoKGUmKDE8PGkpKSA+IDApIHoubXVsVG8ocjIsZyxyKTsKICAgIGVsc2UgeyB2YXIgdCA9IHI7IHIgPSByMjsgcjIgPSB0OyB9CiAgfQogIHJldHVybiB6LnJldmVydChyKTsKfQoKLy8gKHB1YmxpYykgdGhpc15lICUgbSwgMCA8PSBlIDwgMl4zMgpmdW5jdGlvbiBibk1vZFBvd0ludChlLG0pIHsKICB2YXIgejsKICBpZihlIDwgMjU2IHx8IG0uaXNFdmVuKCkpIHogPSBuZXcgQ2xhc3NpYyhtKTsgZWxzZSB6ID0gbmV3IE1vbnRnb21lcnkobSk7CiAgcmV0dXJuIHRoaXMuZXhwKGUseik7Cn0KCi8vIHByb3RlY3RlZApCaWdJbnRlZ2VyLnByb3RvdHlwZS5jb3B5VG8gPSBibnBDb3B5VG87CkJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21JbnQgPSBibnBGcm9tSW50OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tU3RyaW5nID0gYm5wRnJvbVN0cmluZzsKQmlnSW50ZWdlci5wcm90b3R5cGUuY2xhbXAgPSBibnBDbGFtcDsKQmlnSW50ZWdlci5wcm90b3R5cGUuZGxTaGlmdFRvID0gYm5wRExTaGlmdFRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kclNoaWZ0VG8gPSBibnBEUlNoaWZ0VG87CkJpZ0ludGVnZXIucHJvdG90eXBlLmxTaGlmdFRvID0gYm5wTFNoaWZ0VG87CkJpZ0ludGVnZXIucHJvdG90eXBlLnJTaGlmdFRvID0gYm5wUlNoaWZ0VG87CkJpZ0ludGVnZXIucHJvdG90eXBlLnN1YlRvID0gYm5wU3ViVG87CkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VG8gPSBibnBNdWx0aXBseVRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5zcXVhcmVUbyA9IGJucFNxdWFyZVRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZSZW1UbyA9IGJucERpdlJlbVRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5pbnZEaWdpdCA9IGJucEludkRpZ2l0OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5pc0V2ZW4gPSBibnBJc0V2ZW47CkJpZ0ludGVnZXIucHJvdG90eXBlLmV4cCA9IGJucEV4cDsKCi8vIHB1YmxpYwpCaWdJbnRlZ2VyLnByb3RvdHlwZS50b1N0cmluZyA9IGJuVG9TdHJpbmc7CkJpZ0ludGVnZXIucHJvdG90eXBlLm5lZ2F0ZSA9IGJuTmVnYXRlOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5hYnMgPSBibkFiczsKQmlnSW50ZWdlci5wcm90b3R5cGUuY29tcGFyZVRvID0gYm5Db21wYXJlVG87CkJpZ0ludGVnZXIucHJvdG90eXBlLmJpdExlbmd0aCA9IGJuQml0TGVuZ3RoOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2QgPSBibk1vZDsKQmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93SW50ID0gYm5Nb2RQb3dJbnQ7CgovLyAiY29uc3RhbnRzIgpCaWdJbnRlZ2VyLlpFUk8gPSBuYnYoMCk7CkJpZ0ludGVnZXIuT05FID0gbmJ2KDEpOwoKLy8ganNibjIgbGliCgovL0NvcHlyaWdodCAoYykgMjAwNS0yMDA5ICBUb20gV3UKLy9BbGwgUmlnaHRzIFJlc2VydmVkLgovL1NlZSAiTElDRU5TRSIgZm9yIGRldGFpbHMgKFNlZSBqc2JuLmpzIGZvciBMSUNFTlNFKS4KCi8vRXh0ZW5kZWQgSmF2YVNjcmlwdCBCTiBmdW5jdGlvbnMsIHJlcXVpcmVkIGZvciBSU0EgcHJpdmF0ZSBvcHMuCgovL1ZlcnNpb24gMS4xOiBuZXcgQmlnSW50ZWdlcigiMCIsIDEwKSByZXR1cm5zICJwcm9wZXIiIHplcm8KCi8vKHB1YmxpYykKZnVuY3Rpb24gYm5DbG9uZSgpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5jb3B5VG8ocik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIHJldHVybiB2YWx1ZSBhcyBpbnRlZ2VyCmZ1bmN0aW9uIGJuSW50VmFsdWUoKSB7CmlmKHRoaXMucyA8IDApIHsKIGlmKHRoaXMudCA9PSAxKSByZXR1cm4gdGhpcy5kYXRhWzBdLXRoaXMuRFY7CiBlbHNlIGlmKHRoaXMudCA9PSAwKSByZXR1cm4gLTE7Cn0gZWxzZSBpZih0aGlzLnQgPT0gMSkgcmV0dXJuIHRoaXMuZGF0YVswXTsKZWxzZSBpZih0aGlzLnQgPT0gMCkgcmV0dXJuIDA7Ci8vIGFzc3VtZXMgMTYgPCBEQiA8IDMyCnJldHVybiAoKHRoaXMuZGF0YVsxXSYoKDE8PCgzMi10aGlzLkRCKSktMSkpPDx0aGlzLkRCKXx0aGlzLmRhdGFbMF07Cn0KCi8vKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGJ5dGUKZnVuY3Rpb24gYm5CeXRlVmFsdWUoKSB7IHJldHVybiAodGhpcy50PT0wKT90aGlzLnM6KHRoaXMuZGF0YVswXTw8MjQpPj4yNDsgfQoKLy8ocHVibGljKSByZXR1cm4gdmFsdWUgYXMgc2hvcnQgKGFzc3VtZXMgREI+PTE2KQpmdW5jdGlvbiBiblNob3J0VmFsdWUoKSB7IHJldHVybiAodGhpcy50PT0wKT90aGlzLnM6KHRoaXMuZGF0YVswXTw8MTYpPj4xNjsgfQoKLy8ocHJvdGVjdGVkKSByZXR1cm4geCBzLnQuIHJeeCA8IERWCmZ1bmN0aW9uIGJucENodW5rU2l6ZShyKSB7IHJldHVybiBNYXRoLmZsb29yKE1hdGguTE4yKnRoaXMuREIvTWF0aC5sb2cocikpOyB9CgovLyhwdWJsaWMpIDAgaWYgdGhpcyA9PSAwLCAxIGlmIHRoaXMgPiAwCmZ1bmN0aW9uIGJuU2lnTnVtKCkgewppZih0aGlzLnMgPCAwKSByZXR1cm4gLTE7CmVsc2UgaWYodGhpcy50IDw9IDAgfHwgKHRoaXMudCA9PSAxICYmIHRoaXMuZGF0YVswXSA8PSAwKSkgcmV0dXJuIDA7CmVsc2UgcmV0dXJuIDE7Cn0KCi8vKHByb3RlY3RlZCkgY29udmVydCB0byByYWRpeCBzdHJpbmcKZnVuY3Rpb24gYm5wVG9SYWRpeChiKSB7CmlmKGIgPT0gbnVsbCkgYiA9IDEwOwppZih0aGlzLnNpZ251bSgpID09IDAgfHwgYiA8IDIgfHwgYiA+IDM2KSByZXR1cm4gIjAiOwp2YXIgY3MgPSB0aGlzLmNodW5rU2l6ZShiKTsKdmFyIGEgPSBNYXRoLnBvdyhiLGNzKTsKdmFyIGQgPSBuYnYoYSksIHkgPSBuYmkoKSwgeiA9IG5iaSgpLCByID0gIiI7CnRoaXMuZGl2UmVtVG8oZCx5LHopOwp3aGlsZSh5LnNpZ251bSgpID4gMCkgewogciA9IChhK3ouaW50VmFsdWUoKSkudG9TdHJpbmcoYikuc3Vic3RyKDEpICsgcjsKIHkuZGl2UmVtVG8oZCx5LHopOwp9CnJldHVybiB6LmludFZhbHVlKCkudG9TdHJpbmcoYikgKyByOwp9CgovLyhwcm90ZWN0ZWQpIGNvbnZlcnQgZnJvbSByYWRpeCBzdHJpbmcKZnVuY3Rpb24gYm5wRnJvbVJhZGl4KHMsYikgewp0aGlzLmZyb21JbnQoMCk7CmlmKGIgPT0gbnVsbCkgYiA9IDEwOwp2YXIgY3MgPSB0aGlzLmNodW5rU2l6ZShiKTsKdmFyIGQgPSBNYXRoLnBvdyhiLGNzKSwgbWkgPSBmYWxzZSwgaiA9IDAsIHcgPSAwOwpmb3IodmFyIGkgPSAwOyBpIDwgcy5sZW5ndGg7ICsraSkgewogdmFyIHggPSBpbnRBdChzLGkpOwogaWYoeCA8IDApIHsKICAgaWYocy5jaGFyQXQoaSkgPT0gIi0iICYmIHRoaXMuc2lnbnVtKCkgPT0gMCkgbWkgPSB0cnVlOwogICBjb250aW51ZTsKIH0KIHcgPSBiKncreDsKIGlmKCsraiA+PSBjcykgewogICB0aGlzLmRNdWx0aXBseShkKTsKICAgdGhpcy5kQWRkT2Zmc2V0KHcsMCk7CiAgIGogPSAwOwogICB3ID0gMDsKIH0KfQppZihqID4gMCkgewogdGhpcy5kTXVsdGlwbHkoTWF0aC5wb3coYixqKSk7CiB0aGlzLmRBZGRPZmZzZXQodywwKTsKfQppZihtaSkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsdGhpcyk7Cn0KCi8vKHByb3RlY3RlZCkgYWx0ZXJuYXRlIGNvbnN0cnVjdG9yCmZ1bmN0aW9uIGJucEZyb21OdW1iZXIoYSxiLGMpIHsKaWYoIm51bWJlciIgPT0gdHlwZW9mIGIpIHsKIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxpbnQsUk5HKQogaWYoYSA8IDIpIHRoaXMuZnJvbUludCgxKTsKIGVsc2UgewogICB0aGlzLmZyb21OdW1iZXIoYSxjKTsKICAgaWYoIXRoaXMudGVzdEJpdChhLTEpKSAgLy8gZm9yY2UgTVNCIHNldAogICAgIHRoaXMuYml0d2lzZVRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhLTEpLG9wX29yLHRoaXMpOwogICBpZih0aGlzLmlzRXZlbigpKSB0aGlzLmRBZGRPZmZzZXQoMSwwKTsgLy8gZm9yY2Ugb2RkCiAgIHdoaWxlKCF0aGlzLmlzUHJvYmFibGVQcmltZShiKSkgewogICAgIHRoaXMuZEFkZE9mZnNldCgyLDApOwogICAgIGlmKHRoaXMuYml0TGVuZ3RoKCkgPiBhKSB0aGlzLnN1YlRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhLTEpLHRoaXMpOwogICB9CiB9Cn0gZWxzZSB7CiAvLyBuZXcgQmlnSW50ZWdlcihpbnQsUk5HKQogdmFyIHggPSBuZXcgQXJyYXkoKSwgdCA9IGEmNzsKIHgubGVuZ3RoID0gKGE+PjMpKzE7CiBiLm5leHRCeXRlcyh4KTsKIGlmKHQgPiAwKSB4WzBdICY9ICgoMTw8dCktMSk7IGVsc2UgeFswXSA9IDA7CiB0aGlzLmZyb21TdHJpbmcoeCwyNTYpOwp9Cn0KCi8vKHB1YmxpYykgY29udmVydCB0byBiaWdlbmRpYW4gYnl0ZSBhcnJheQpmdW5jdGlvbiBiblRvQnl0ZUFycmF5KCkgewp2YXIgaSA9IHRoaXMudCwgciA9IG5ldyBBcnJheSgpOwpyWzBdID0gdGhpcy5zOwp2YXIgcCA9IHRoaXMuREItKGkqdGhpcy5EQiklOCwgZCwgayA9IDA7CmlmKGktLSA+IDApIHsKIGlmKHAgPCB0aGlzLkRCICYmIChkID0gdGhpcy5kYXRhW2ldPj5wKSAhPSAodGhpcy5zJnRoaXMuRE0pPj5wKQogICByW2srK10gPSBkfCh0aGlzLnM8PCh0aGlzLkRCLXApKTsKIHdoaWxlKGkgPj0gMCkgewogICBpZihwIDwgOCkgewogICAgIGQgPSAodGhpcy5kYXRhW2ldJigoMTw8cCktMSkpPDwoOC1wKTsKICAgICBkIHw9IHRoaXMuZGF0YVstLWldPj4ocCs9dGhpcy5EQi04KTsKICAgfSBlbHNlIHsKICAgICBkID0gKHRoaXMuZGF0YVtpXT4+KHAtPTgpKSYweGZmOwogICAgIGlmKHAgPD0gMCkgeyBwICs9IHRoaXMuREI7IC0taTsgfQogICB9CiAgIGlmKChkJjB4ODApICE9IDApIGQgfD0gLTI1NjsKICAgaWYoayA9PSAwICYmICh0aGlzLnMmMHg4MCkgIT0gKGQmMHg4MCkpICsrazsKICAgaWYoayA+IDAgfHwgZCAhPSB0aGlzLnMpIHJbaysrXSA9IGQ7CiB9Cn0KcmV0dXJuIHI7Cn0KCmZ1bmN0aW9uIGJuRXF1YWxzKGEpIHsgcmV0dXJuKHRoaXMuY29tcGFyZVRvKGEpPT0wKTsgfQpmdW5jdGlvbiBibk1pbihhKSB7IHJldHVybih0aGlzLmNvbXBhcmVUbyhhKTwwKT90aGlzOmE7IH0KZnVuY3Rpb24gYm5NYXgoYSkgeyByZXR1cm4odGhpcy5jb21wYXJlVG8oYSk+MCk/dGhpczphOyB9CgovLyhwcm90ZWN0ZWQpIHIgPSB0aGlzIG9wIGEgKGJpdHdpc2UpCmZ1bmN0aW9uIGJucEJpdHdpc2VUbyhhLG9wLHIpIHsKdmFyIGksIGYsIG0gPSBNYXRoLm1pbihhLnQsdGhpcy50KTsKZm9yKGkgPSAwOyBpIDwgbTsgKytpKSByLmRhdGFbaV0gPSBvcCh0aGlzLmRhdGFbaV0sYS5kYXRhW2ldKTsKaWYoYS50IDwgdGhpcy50KSB7CiBmID0gYS5zJnRoaXMuRE07CiBmb3IoaSA9IG07IGkgPCB0aGlzLnQ7ICsraSkgci5kYXRhW2ldID0gb3AodGhpcy5kYXRhW2ldLGYpOwogci50ID0gdGhpcy50Owp9IGVsc2UgewogZiA9IHRoaXMucyZ0aGlzLkRNOwogZm9yKGkgPSBtOyBpIDwgYS50OyArK2kpIHIuZGF0YVtpXSA9IG9wKGYsYS5kYXRhW2ldKTsKIHIudCA9IGEudDsKfQpyLnMgPSBvcCh0aGlzLnMsYS5zKTsKci5jbGFtcCgpOwp9CgovLyhwdWJsaWMpIHRoaXMgJiBhCmZ1bmN0aW9uIG9wX2FuZCh4LHkpIHsgcmV0dXJuIHgmeTsgfQpmdW5jdGlvbiBibkFuZChhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuYml0d2lzZVRvKGEsb3BfYW5kLHIpOyByZXR1cm4gcjsgfQoKLy8ocHVibGljKSB0aGlzIHwgYQpmdW5jdGlvbiBvcF9vcih4LHkpIHsgcmV0dXJuIHh8eTsgfQpmdW5jdGlvbiBibk9yKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF9vcixyKTsgcmV0dXJuIHI7IH0KCi8vKHB1YmxpYykgdGhpcyBeIGEKZnVuY3Rpb24gb3BfeG9yKHgseSkgeyByZXR1cm4geF55OyB9CmZ1bmN0aW9uIGJuWG9yKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF94b3Iscik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIHRoaXMgJiB+YQpmdW5jdGlvbiBvcF9hbmRub3QoeCx5KSB7IHJldHVybiB4Jn55OyB9CmZ1bmN0aW9uIGJuQW5kTm90KGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF9hbmRub3Qscik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIH50aGlzCmZ1bmN0aW9uIGJuTm90KCkgewp2YXIgciA9IG5iaSgpOwpmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHIuZGF0YVtpXSA9IHRoaXMuRE0mfnRoaXMuZGF0YVtpXTsKci50ID0gdGhpcy50OwpyLnMgPSB+dGhpcy5zOwpyZXR1cm4gcjsKfQoKLy8ocHVibGljKSB0aGlzIDw8IG4KZnVuY3Rpb24gYm5TaGlmdExlZnQobikgewp2YXIgciA9IG5iaSgpOwppZihuIDwgMCkgdGhpcy5yU2hpZnRUbygtbixyKTsgZWxzZSB0aGlzLmxTaGlmdFRvKG4scik7CnJldHVybiByOwp9CgovLyhwdWJsaWMpIHRoaXMgPj4gbgpmdW5jdGlvbiBiblNoaWZ0UmlnaHQobikgewp2YXIgciA9IG5iaSgpOwppZihuIDwgMCkgdGhpcy5sU2hpZnRUbygtbixyKTsgZWxzZSB0aGlzLnJTaGlmdFRvKG4scik7CnJldHVybiByOwp9CgovL3JldHVybiBpbmRleCBvZiBsb3dlc3QgMS1iaXQgaW4geCwgeCA8IDJeMzEKZnVuY3Rpb24gbGJpdCh4KSB7CmlmKHggPT0gMCkgcmV0dXJuIC0xOwp2YXIgciA9IDA7CmlmKCh4JjB4ZmZmZikgPT0gMCkgeyB4ID4+PSAxNjsgciArPSAxNjsgfQppZigoeCYweGZmKSA9PSAwKSB7IHggPj49IDg7IHIgKz0gODsgfQppZigoeCYweGYpID09IDApIHsgeCA+Pj0gNDsgciArPSA0OyB9CmlmKCh4JjMpID09IDApIHsgeCA+Pj0gMjsgciArPSAyOyB9CmlmKCh4JjEpID09IDApICsrcjsKcmV0dXJuIHI7Cn0KCi8vKHB1YmxpYykgcmV0dXJucyBpbmRleCBvZiBsb3dlc3QgMS1iaXQgKG9yIC0xIGlmIG5vbmUpCmZ1bmN0aW9uIGJuR2V0TG93ZXN0U2V0Qml0KCkgewpmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpCiBpZih0aGlzLmRhdGFbaV0gIT0gMCkgcmV0dXJuIGkqdGhpcy5EQitsYml0KHRoaXMuZGF0YVtpXSk7CmlmKHRoaXMucyA8IDApIHJldHVybiB0aGlzLnQqdGhpcy5EQjsKcmV0dXJuIC0xOwp9CgovL3JldHVybiBudW1iZXIgb2YgMSBiaXRzIGluIHgKZnVuY3Rpb24gY2JpdCh4KSB7CnZhciByID0gMDsKd2hpbGUoeCAhPSAwKSB7IHggJj0geC0xOyArK3I7IH0KcmV0dXJuIHI7Cn0KCi8vKHB1YmxpYykgcmV0dXJuIG51bWJlciBvZiBzZXQgYml0cwpmdW5jdGlvbiBibkJpdENvdW50KCkgewp2YXIgciA9IDAsIHggPSB0aGlzLnMmdGhpcy5ETTsKZm9yKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKSByICs9IGNiaXQodGhpcy5kYXRhW2ldXngpOwpyZXR1cm4gcjsKfQoKLy8ocHVibGljKSB0cnVlIGlmZiBudGggYml0IGlzIHNldApmdW5jdGlvbiBiblRlc3RCaXQobikgewp2YXIgaiA9IE1hdGguZmxvb3Iobi90aGlzLkRCKTsKaWYoaiA+PSB0aGlzLnQpIHJldHVybih0aGlzLnMhPTApOwpyZXR1cm4oKHRoaXMuZGF0YVtqXSYoMTw8KG4ldGhpcy5EQikpKSE9MCk7Cn0KCi8vKHByb3RlY3RlZCkgdGhpcyBvcCAoMTw8bikKZnVuY3Rpb24gYm5wQ2hhbmdlQml0KG4sb3ApIHsKdmFyIHIgPSBCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQobik7CnRoaXMuYml0d2lzZVRvKHIsb3Ascik7CnJldHVybiByOwp9CgovLyhwdWJsaWMpIHRoaXMgfCAoMTw8bikKZnVuY3Rpb24gYm5TZXRCaXQobikgeyByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobixvcF9vcik7IH0KCi8vKHB1YmxpYykgdGhpcyAmIH4oMTw8bikKZnVuY3Rpb24gYm5DbGVhckJpdChuKSB7IHJldHVybiB0aGlzLmNoYW5nZUJpdChuLG9wX2FuZG5vdCk7IH0KCi8vKHB1YmxpYykgdGhpcyBeICgxPDxuKQpmdW5jdGlvbiBibkZsaXBCaXQobikgeyByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobixvcF94b3IpOyB9CgovLyhwcm90ZWN0ZWQpIHIgPSB0aGlzICsgYQpmdW5jdGlvbiBibnBBZGRUbyhhLHIpIHsKdmFyIGkgPSAwLCBjID0gMCwgbSA9IE1hdGgubWluKGEudCx0aGlzLnQpOwp3aGlsZShpIDwgbSkgewogYyArPSB0aGlzLmRhdGFbaV0rYS5kYXRhW2ldOwogci5kYXRhW2krK10gPSBjJnRoaXMuRE07CiBjID4+PSB0aGlzLkRCOwp9CmlmKGEudCA8IHRoaXMudCkgewogYyArPSBhLnM7CiB3aGlsZShpIDwgdGhpcy50KSB7CiAgIGMgKz0gdGhpcy5kYXRhW2ldOwogICByLmRhdGFbaSsrXSA9IGMmdGhpcy5ETTsKICAgYyA+Pj0gdGhpcy5EQjsKIH0KIGMgKz0gdGhpcy5zOwp9IGVsc2UgewogYyArPSB0aGlzLnM7CiB3aGlsZShpIDwgYS50KSB7CiAgIGMgKz0gYS5kYXRhW2ldOwogICByLmRhdGFbaSsrXSA9IGMmdGhpcy5ETTsKICAgYyA+Pj0gdGhpcy5EQjsKIH0KIGMgKz0gYS5zOwp9CnIucyA9IChjPDApPy0xOjA7CmlmKGMgPiAwKSByLmRhdGFbaSsrXSA9IGM7CmVsc2UgaWYoYyA8IC0xKSByLmRhdGFbaSsrXSA9IHRoaXMuRFYrYzsKci50ID0gaTsKci5jbGFtcCgpOwp9CgovLyhwdWJsaWMpIHRoaXMgKyBhCmZ1bmN0aW9uIGJuQWRkKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5hZGRUbyhhLHIpOyByZXR1cm4gcjsgfQoKLy8ocHVibGljKSB0aGlzIC0gYQpmdW5jdGlvbiBiblN1YnRyYWN0KGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5zdWJUbyhhLHIpOyByZXR1cm4gcjsgfQoKLy8ocHVibGljKSB0aGlzICogYQpmdW5jdGlvbiBibk11bHRpcGx5KGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5tdWx0aXBseVRvKGEscik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIHRoaXMgLyBhCmZ1bmN0aW9uIGJuRGl2aWRlKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5kaXZSZW1UbyhhLHIsbnVsbCk7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIHRoaXMgJSBhCmZ1bmN0aW9uIGJuUmVtYWluZGVyKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5kaXZSZW1UbyhhLG51bGwscik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIFt0aGlzL2EsdGhpcyVhXQpmdW5jdGlvbiBibkRpdmlkZUFuZFJlbWFpbmRlcihhKSB7CnZhciBxID0gbmJpKCksIHIgPSBuYmkoKTsKdGhpcy5kaXZSZW1UbyhhLHEscik7CnJldHVybiBuZXcgQXJyYXkocSxyKTsKfQoKLy8ocHJvdGVjdGVkKSB0aGlzICo9IG4sIHRoaXMgPj0gMCwgMSA8IG4gPCBEVgpmdW5jdGlvbiBibnBETXVsdGlwbHkobikgewp0aGlzLmRhdGFbdGhpcy50XSA9IHRoaXMuYW0oMCxuLTEsdGhpcywwLDAsdGhpcy50KTsKKyt0aGlzLnQ7CnRoaXMuY2xhbXAoKTsKfQoKLy8ocHJvdGVjdGVkKSB0aGlzICs9IG4gPDwgdyB3b3JkcywgdGhpcyA+PSAwCmZ1bmN0aW9uIGJucERBZGRPZmZzZXQobix3KSB7CmlmKG4gPT0gMCkgcmV0dXJuOwp3aGlsZSh0aGlzLnQgPD0gdykgdGhpcy5kYXRhW3RoaXMudCsrXSA9IDA7CnRoaXMuZGF0YVt3XSArPSBuOwp3aGlsZSh0aGlzLmRhdGFbd10gPj0gdGhpcy5EVikgewogdGhpcy5kYXRhW3ddIC09IHRoaXMuRFY7CiBpZigrK3cgPj0gdGhpcy50KSB0aGlzLmRhdGFbdGhpcy50KytdID0gMDsKICsrdGhpcy5kYXRhW3ddOwp9Cn0KCi8vQSAibnVsbCIgcmVkdWNlcgpmdW5jdGlvbiBOdWxsRXhwKCkge30KZnVuY3Rpb24gbk5vcCh4KSB7IHJldHVybiB4OyB9CmZ1bmN0aW9uIG5NdWxUbyh4LHkscikgeyB4Lm11bHRpcGx5VG8oeSxyKTsgfQpmdW5jdGlvbiBuU3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IH0KCk51bGxFeHAucHJvdG90eXBlLmNvbnZlcnQgPSBuTm9wOwpOdWxsRXhwLnByb3RvdHlwZS5yZXZlcnQgPSBuTm9wOwpOdWxsRXhwLnByb3RvdHlwZS5tdWxUbyA9IG5NdWxUbzsKTnVsbEV4cC5wcm90b3R5cGUuc3FyVG8gPSBuU3FyVG87CgovLyhwdWJsaWMpIHRoaXNeZQpmdW5jdGlvbiBiblBvdyhlKSB7IHJldHVybiB0aGlzLmV4cChlLG5ldyBOdWxsRXhwKCkpOyB9CgovLyhwcm90ZWN0ZWQpIHIgPSBsb3dlciBuIHdvcmRzIG9mICJ0aGlzICogYSIsIGEudCA8PSBuCi8vInRoaXMiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS4KZnVuY3Rpb24gYm5wTXVsdGlwbHlMb3dlclRvKGEsbixyKSB7CnZhciBpID0gTWF0aC5taW4odGhpcy50K2EudCxuKTsKci5zID0gMDsgLy8gYXNzdW1lcyBhLHRoaXMgPj0gMApyLnQgPSBpOwp3aGlsZShpID4gMCkgci5kYXRhWy0taV0gPSAwOwp2YXIgajsKZm9yKGogPSByLnQtdGhpcy50OyBpIDwgajsgKytpKSByLmRhdGFbaSt0aGlzLnRdID0gdGhpcy5hbSgwLGEuZGF0YVtpXSxyLGksMCx0aGlzLnQpOwpmb3IoaiA9IE1hdGgubWluKGEudCxuKTsgaSA8IGo7ICsraSkgdGhpcy5hbSgwLGEuZGF0YVtpXSxyLGksMCxuLWkpOwpyLmNsYW1wKCk7Cn0KCi8vKHByb3RlY3RlZCkgciA9ICJ0aGlzICogYSIgd2l0aG91dCBsb3dlciBuIHdvcmRzLCBuID4gMAovLyJ0aGlzIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuCmZ1bmN0aW9uIGJucE11bHRpcGx5VXBwZXJUbyhhLG4scikgewotLW47CnZhciBpID0gci50ID0gdGhpcy50K2EudC1uOwpyLnMgPSAwOyAvLyBhc3N1bWVzIGEsdGhpcyA+PSAwCndoaWxlKC0taSA+PSAwKSByLmRhdGFbaV0gPSAwOwpmb3IoaSA9IE1hdGgubWF4KG4tdGhpcy50LDApOyBpIDwgYS50OyArK2kpCiByLmRhdGFbdGhpcy50K2ktbl0gPSB0aGlzLmFtKG4taSxhLmRhdGFbaV0sciwwLDAsdGhpcy50K2ktbik7CnIuY2xhbXAoKTsKci5kclNoaWZ0VG8oMSxyKTsKfQoKLy9CYXJyZXR0IG1vZHVsYXIgcmVkdWN0aW9uCmZ1bmN0aW9uIEJhcnJldHQobSkgewovLyBzZXR1cCBCYXJyZXR0CnRoaXMucjIgPSBuYmkoKTsKdGhpcy5xMyA9IG5iaSgpOwpCaWdJbnRlZ2VyLk9ORS5kbFNoaWZ0VG8oMiptLnQsdGhpcy5yMik7CnRoaXMubXUgPSB0aGlzLnIyLmRpdmlkZShtKTsKdGhpcy5tID0gbTsKfQoKZnVuY3Rpb24gYmFycmV0dENvbnZlcnQoeCkgewppZih4LnMgPCAwIHx8IHgudCA+IDIqdGhpcy5tLnQpIHJldHVybiB4Lm1vZCh0aGlzLm0pOwplbHNlIGlmKHguY29tcGFyZVRvKHRoaXMubSkgPCAwKSByZXR1cm4geDsKZWxzZSB7IHZhciByID0gbmJpKCk7IHguY29weVRvKHIpOyB0aGlzLnJlZHVjZShyKTsgcmV0dXJuIHI7IH0KfQoKZnVuY3Rpb24gYmFycmV0dFJldmVydCh4KSB7IHJldHVybiB4OyB9CgovL3ggPSB4IG1vZCBtIChIQUMgMTQuNDIpCmZ1bmN0aW9uIGJhcnJldHRSZWR1Y2UoeCkgewp4LmRyU2hpZnRUbyh0aGlzLm0udC0xLHRoaXMucjIpOwppZih4LnQgPiB0aGlzLm0udCsxKSB7IHgudCA9IHRoaXMubS50KzE7IHguY2xhbXAoKTsgfQp0aGlzLm11Lm11bHRpcGx5VXBwZXJUbyh0aGlzLnIyLHRoaXMubS50KzEsdGhpcy5xMyk7CnRoaXMubS5tdWx0aXBseUxvd2VyVG8odGhpcy5xMyx0aGlzLm0udCsxLHRoaXMucjIpOwp3aGlsZSh4LmNvbXBhcmVUbyh0aGlzLnIyKSA8IDApIHguZEFkZE9mZnNldCgxLHRoaXMubS50KzEpOwp4LnN1YlRvKHRoaXMucjIseCk7CndoaWxlKHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgeC5zdWJUbyh0aGlzLm0seCk7Cn0KCi8vciA9IHheMiBtb2QgbTsgeCAhPSByCmZ1bmN0aW9uIGJhcnJldHRTcXJUbyh4LHIpIHsgeC5zcXVhcmVUbyhyKTsgdGhpcy5yZWR1Y2Uocik7IH0KCi8vciA9IHgqeSBtb2QgbTsgeCx5ICE9IHIKZnVuY3Rpb24gYmFycmV0dE11bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB0aGlzLnJlZHVjZShyKTsgfQoKQmFycmV0dC5wcm90b3R5cGUuY29udmVydCA9IGJhcnJldHRDb252ZXJ0OwpCYXJyZXR0LnByb3RvdHlwZS5yZXZlcnQgPSBiYXJyZXR0UmV2ZXJ0OwpCYXJyZXR0LnByb3RvdHlwZS5yZWR1Y2UgPSBiYXJyZXR0UmVkdWNlOwpCYXJyZXR0LnByb3RvdHlwZS5tdWxUbyA9IGJhcnJldHRNdWxUbzsKQmFycmV0dC5wcm90b3R5cGUuc3FyVG8gPSBiYXJyZXR0U3FyVG87CgovLyhwdWJsaWMpIHRoaXNeZSAlIG0gKEhBQyAxNC44NSkKZnVuY3Rpb24gYm5Nb2RQb3coZSxtKSB7CnZhciBpID0gZS5iaXRMZW5ndGgoKSwgaywgciA9IG5idigxKSwgejsKaWYoaSA8PSAwKSByZXR1cm4gcjsKZWxzZSBpZihpIDwgMTgpIGsgPSAxOwplbHNlIGlmKGkgPCA0OCkgayA9IDM7CmVsc2UgaWYoaSA8IDE0NCkgayA9IDQ7CmVsc2UgaWYoaSA8IDc2OCkgayA9IDU7CmVsc2UgayA9IDY7CmlmKGkgPCA4KQogeiA9IG5ldyBDbGFzc2ljKG0pOwplbHNlIGlmKG0uaXNFdmVuKCkpCiB6ID0gbmV3IEJhcnJldHQobSk7CmVsc2UKIHogPSBuZXcgTW9udGdvbWVyeShtKTsKCi8vIHByZWNvbXB1dGF0aW9uCnZhciBnID0gbmV3IEFycmF5KCksIG4gPSAzLCBrMSA9IGstMSwga20gPSAoMTw8ayktMTsKZ1sxXSA9IHouY29udmVydCh0aGlzKTsKaWYoayA+IDEpIHsKIHZhciBnMiA9IG5iaSgpOwogei5zcXJUbyhnWzFdLGcyKTsKIHdoaWxlKG4gPD0ga20pIHsKICAgZ1tuXSA9IG5iaSgpOwogICB6Lm11bFRvKGcyLGdbbi0yXSxnW25dKTsKICAgbiArPSAyOwogfQp9Cgp2YXIgaiA9IGUudC0xLCB3LCBpczEgPSB0cnVlLCByMiA9IG5iaSgpLCB0OwppID0gbmJpdHMoZS5kYXRhW2pdKS0xOwp3aGlsZShqID49IDApIHsKIGlmKGkgPj0gazEpIHcgPSAoZS5kYXRhW2pdPj4oaS1rMSkpJmttOwogZWxzZSB7CiAgIHcgPSAoZS5kYXRhW2pdJigoMTw8KGkrMSkpLTEpKTw8KGsxLWkpOwogICBpZihqID4gMCkgdyB8PSBlLmRhdGFbai0xXT4+KHRoaXMuREIraS1rMSk7CiB9CgogbiA9IGs7CiB3aGlsZSgodyYxKSA9PSAwKSB7IHcgPj49IDE7IC0tbjsgfQogaWYoKGkgLT0gbikgPCAwKSB7IGkgKz0gdGhpcy5EQjsgLS1qOyB9CiBpZihpczEpIHsgIC8vIHJldCA9PSAxLCBkb24ndCBib3RoZXIgc3F1YXJpbmcgb3IgbXVsdGlwbHlpbmcgaXQKICAgZ1t3XS5jb3B5VG8ocik7CiAgIGlzMSA9IGZhbHNlOwogfSBlbHNlIHsKICAgd2hpbGUobiA+IDEpIHsgei5zcXJUbyhyLHIyKTsgei5zcXJUbyhyMixyKTsgbiAtPSAyOyB9CiAgIGlmKG4gPiAwKSB6LnNxclRvKHIscjIpOyBlbHNlIHsgdCA9IHI7IHIgPSByMjsgcjIgPSB0OyB9CiAgIHoubXVsVG8ocjIsZ1t3XSxyKTsKIH0KCiB3aGlsZShqID49IDAgJiYgKGUuZGF0YVtqXSYoMTw8aSkpID09IDApIHsKICAgei5zcXJUbyhyLHIyKTsgdCA9IHI7IHIgPSByMjsgcjIgPSB0OwogICBpZigtLWkgPCAwKSB7IGkgPSB0aGlzLkRCLTE7IC0tajsgfQogfQp9CnJldHVybiB6LnJldmVydChyKTsKfQoKLy8ocHVibGljKSBnY2QodGhpcyxhKSAoSEFDIDE0LjU0KQpmdW5jdGlvbiBibkdDRChhKSB7CnZhciB4ID0gKHRoaXMuczwwKT90aGlzLm5lZ2F0ZSgpOnRoaXMuY2xvbmUoKTsKdmFyIHkgPSAoYS5zPDApP2EubmVnYXRlKCk6YS5jbG9uZSgpOwppZih4LmNvbXBhcmVUbyh5KSA8IDApIHsgdmFyIHQgPSB4OyB4ID0geTsgeSA9IHQ7IH0KdmFyIGkgPSB4LmdldExvd2VzdFNldEJpdCgpLCBnID0geS5nZXRMb3dlc3RTZXRCaXQoKTsKaWYoZyA8IDApIHJldHVybiB4OwppZihpIDwgZykgZyA9IGk7CmlmKGcgPiAwKSB7CiB4LnJTaGlmdFRvKGcseCk7CiB5LnJTaGlmdFRvKGcseSk7Cn0Kd2hpbGUoeC5zaWdudW0oKSA+IDApIHsKIGlmKChpID0geC5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB4LnJTaGlmdFRvKGkseCk7CiBpZigoaSA9IHkuZ2V0TG93ZXN0U2V0Qml0KCkpID4gMCkgeS5yU2hpZnRUbyhpLHkpOwogaWYoeC5jb21wYXJlVG8oeSkgPj0gMCkgewogICB4LnN1YlRvKHkseCk7CiAgIHguclNoaWZ0VG8oMSx4KTsKIH0gZWxzZSB7CiAgIHkuc3ViVG8oeCx5KTsKICAgeS5yU2hpZnRUbygxLHkpOwogfQp9CmlmKGcgPiAwKSB5LmxTaGlmdFRvKGcseSk7CnJldHVybiB5Owp9CgovLyhwcm90ZWN0ZWQpIHRoaXMgJSBuLCBuIDwgMl4yNgpmdW5jdGlvbiBibnBNb2RJbnQobikgewppZihuIDw9IDApIHJldHVybiAwOwp2YXIgZCA9IHRoaXMuRFYlbiwgciA9ICh0aGlzLnM8MCk/bi0xOjA7CmlmKHRoaXMudCA+IDApCiBpZihkID09IDApIHIgPSB0aGlzLmRhdGFbMF0lbjsKIGVsc2UgZm9yKHZhciBpID0gdGhpcy50LTE7IGkgPj0gMDsgLS1pKSByID0gKGQqcit0aGlzLmRhdGFbaV0pJW47CnJldHVybiByOwp9CgovLyhwdWJsaWMpIDEvdGhpcyAlIG0gKEhBQyAxNC42MSkKZnVuY3Rpb24gYm5Nb2RJbnZlcnNlKG0pIHsKdmFyIGFjID0gbS5pc0V2ZW4oKTsKaWYoKHRoaXMuaXNFdmVuKCkgJiYgYWMpIHx8IG0uc2lnbnVtKCkgPT0gMCkgcmV0dXJuIEJpZ0ludGVnZXIuWkVSTzsKdmFyIHUgPSBtLmNsb25lKCksIHYgPSB0aGlzLmNsb25lKCk7CnZhciBhID0gbmJ2KDEpLCBiID0gbmJ2KDApLCBjID0gbmJ2KDApLCBkID0gbmJ2KDEpOwp3aGlsZSh1LnNpZ251bSgpICE9IDApIHsKIHdoaWxlKHUuaXNFdmVuKCkpIHsKICAgdS5yU2hpZnRUbygxLHUpOwogICBpZihhYykgewogICAgIGlmKCFhLmlzRXZlbigpIHx8ICFiLmlzRXZlbigpKSB7IGEuYWRkVG8odGhpcyxhKTsgYi5zdWJUbyhtLGIpOyB9CiAgICAgYS5yU2hpZnRUbygxLGEpOwogICB9IGVsc2UgaWYoIWIuaXNFdmVuKCkpIGIuc3ViVG8obSxiKTsKICAgYi5yU2hpZnRUbygxLGIpOwogfQogd2hpbGUodi5pc0V2ZW4oKSkgewogICB2LnJTaGlmdFRvKDEsdik7CiAgIGlmKGFjKSB7CiAgICAgaWYoIWMuaXNFdmVuKCkgfHwgIWQuaXNFdmVuKCkpIHsgYy5hZGRUbyh0aGlzLGMpOyBkLnN1YlRvKG0sZCk7IH0KICAgICBjLnJTaGlmdFRvKDEsYyk7CiAgIH0gZWxzZSBpZighZC5pc0V2ZW4oKSkgZC5zdWJUbyhtLGQpOwogICBkLnJTaGlmdFRvKDEsZCk7CiB9CiBpZih1LmNvbXBhcmVUbyh2KSA+PSAwKSB7CiAgIHUuc3ViVG8odix1KTsKICAgaWYoYWMpIGEuc3ViVG8oYyxhKTsKICAgYi5zdWJUbyhkLGIpOwogfSBlbHNlIHsKICAgdi5zdWJUbyh1LHYpOwogICBpZihhYykgYy5zdWJUbyhhLGMpOwogICBkLnN1YlRvKGIsZCk7CiB9Cn0KaWYodi5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDApIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87CmlmKGQuY29tcGFyZVRvKG0pID49IDApIHJldHVybiBkLnN1YnRyYWN0KG0pOwppZihkLnNpZ251bSgpIDwgMCkgZC5hZGRUbyhtLGQpOyBlbHNlIHJldHVybiBkOwppZihkLnNpZ251bSgpIDwgMCkgcmV0dXJuIGQuYWRkKG0pOyBlbHNlIHJldHVybiBkOwp9Cgp2YXIgbG93cHJpbWVzID0gWzIsMyw1LDcsMTEsMTMsMTcsMTksMjMsMjksMzEsMzcsNDEsNDMsNDcsNTMsNTksNjEsNjcsNzEsNzMsNzksODMsODksOTcsMTAxLDEwMywxMDcsMTA5LDExMywxMjcsMTMxLDEzNywxMzksMTQ5LDE1MSwxNTcsMTYzLDE2NywxNzMsMTc5LDE4MSwxOTEsMTkzLDE5NywxOTksMjExLDIyMywyMjcsMjI5LDIzMywyMzksMjQxLDI1MSwyNTcsMjYzLDI2OSwyNzEsMjc3LDI4MSwyODMsMjkzLDMwNywzMTEsMzEzLDMxNywzMzEsMzM3LDM0NywzNDksMzUzLDM1OSwzNjcsMzczLDM3OSwzODMsMzg5LDM5Nyw0MDEsNDA5LDQxOSw0MjEsNDMxLDQzMyw0MzksNDQzLDQ0OSw0NTcsNDYxLDQ2Myw0NjcsNDc5LDQ4Nyw0OTEsNDk5LDUwMyw1MDldOwp2YXIgbHBsaW0gPSAoMTw8MjYpL2xvd3ByaW1lc1tsb3dwcmltZXMubGVuZ3RoLTFdOwoKLy8ocHVibGljKSB0ZXN0IHByaW1hbGl0eSB3aXRoIGNlcnRhaW50eSA+PSAxLS41XnQKZnVuY3Rpb24gYm5Jc1Byb2JhYmxlUHJpbWUodCkgewp2YXIgaSwgeCA9IHRoaXMuYWJzKCk7CmlmKHgudCA9PSAxICYmIHguZGF0YVswXSA8PSBsb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aC0xXSkgewogZm9yKGkgPSAwOyBpIDwgbG93cHJpbWVzLmxlbmd0aDsgKytpKQogICBpZih4LmRhdGFbMF0gPT0gbG93cHJpbWVzW2ldKSByZXR1cm4gdHJ1ZTsKIHJldHVybiBmYWxzZTsKfQppZih4LmlzRXZlbigpKSByZXR1cm4gZmFsc2U7CmkgPSAxOwp3aGlsZShpIDwgbG93cHJpbWVzLmxlbmd0aCkgewogdmFyIG0gPSBsb3dwcmltZXNbaV0sIGogPSBpKzE7CiB3aGlsZShqIDwgbG93cHJpbWVzLmxlbmd0aCAmJiBtIDwgbHBsaW0pIG0gKj0gbG93cHJpbWVzW2orK107CiBtID0geC5tb2RJbnQobSk7CiB3aGlsZShpIDwgaikgaWYobSVsb3dwcmltZXNbaSsrXSA9PSAwKSByZXR1cm4gZmFsc2U7Cn0KcmV0dXJuIHgubWlsbGVyUmFiaW4odCk7Cn0KCi8vKHByb3RlY3RlZCkgdHJ1ZSBpZiBwcm9iYWJseSBwcmltZSAoSEFDIDQuMjQsIE1pbGxlci1SYWJpbikKZnVuY3Rpb24gYm5wTWlsbGVyUmFiaW4odCkgewp2YXIgbjEgPSB0aGlzLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTsKdmFyIGsgPSBuMS5nZXRMb3dlc3RTZXRCaXQoKTsKaWYoayA8PSAwKSByZXR1cm4gZmFsc2U7CnZhciByID0gbjEuc2hpZnRSaWdodChrKTsKdmFyIHBybmcgPSBibkdldFBybmcoKTsKdmFyIGE7CmZvcih2YXIgaSA9IDA7IGkgPCB0OyArK2kpIHsKIC8vIHNlbGVjdCB3aXRuZXNzICdhJyBhdCByYW5kb20gZnJvbSBiZXR3ZWVuIDEgYW5kIG4xCiBkbyB7CiAgIGEgPSBuZXcgQmlnSW50ZWdlcih0aGlzLmJpdExlbmd0aCgpLCBwcm5nKTsKIH0KIHdoaWxlKGEuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA8PSAwIHx8IGEuY29tcGFyZVRvKG4xKSA+PSAwKTsKIHZhciB5ID0gYS5tb2RQb3cocix0aGlzKTsKIGlmKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPSAwICYmIHkuY29tcGFyZVRvKG4xKSAhPSAwKSB7CiAgIHZhciBqID0gMTsKICAgd2hpbGUoaisrIDwgayAmJiB5LmNvbXBhcmVUbyhuMSkgIT0gMCkgewogICAgIHkgPSB5Lm1vZFBvd0ludCgyLHRoaXMpOwogICAgIGlmKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwKSByZXR1cm4gZmFsc2U7CiAgIH0KICAgaWYoeS5jb21wYXJlVG8objEpICE9IDApIHJldHVybiBmYWxzZTsKIH0KfQpyZXR1cm4gdHJ1ZTsKfQoKLy8gZ2V0IHBzZXVkbyByYW5kb20gbnVtYmVyIGdlbmVyYXRvcgpmdW5jdGlvbiBibkdldFBybmcoKSB7CiAgLy8gY3JlYXRlIHBybmcgd2l0aCBhcGkgdGhhdCBtYXRjaGVzIEJpZ0ludGVnZXIgc2VjdXJlIHJhbmRvbQogIHJldHVybiB7CiAgICAvLyB4IGlzIGFuIGFycmF5IHRvIGZpbGwgd2l0aCBieXRlcwogICAgbmV4dEJ5dGVzOiBmdW5jdGlvbih4KSB7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgeFtpXSA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDB4MDEwMCk7CiAgICAgIH0KICAgIH0KICB9Owp9CgovL3Byb3RlY3RlZApCaWdJbnRlZ2VyLnByb3RvdHlwZS5jaHVua1NpemUgPSBibnBDaHVua1NpemU7CkJpZ0ludGVnZXIucHJvdG90eXBlLnRvUmFkaXggPSBibnBUb1JhZGl4OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tUmFkaXggPSBibnBGcm9tUmFkaXg7CkJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21OdW1iZXIgPSBibnBGcm9tTnVtYmVyOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXR3aXNlVG8gPSBibnBCaXR3aXNlVG87CkJpZ0ludGVnZXIucHJvdG90eXBlLmNoYW5nZUJpdCA9IGJucENoYW5nZUJpdDsKQmlnSW50ZWdlci5wcm90b3R5cGUuYWRkVG8gPSBibnBBZGRUbzsKQmlnSW50ZWdlci5wcm90b3R5cGUuZE11bHRpcGx5ID0gYm5wRE11bHRpcGx5OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kQWRkT2Zmc2V0ID0gYm5wREFkZE9mZnNldDsKQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlMb3dlclRvID0gYm5wTXVsdGlwbHlMb3dlclRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseVVwcGVyVG8gPSBibnBNdWx0aXBseVVwcGVyVG87CkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludCA9IGJucE1vZEludDsKQmlnSW50ZWdlci5wcm90b3R5cGUubWlsbGVyUmFiaW4gPSBibnBNaWxsZXJSYWJpbjsKCi8vcHVibGljCkJpZ0ludGVnZXIucHJvdG90eXBlLmNsb25lID0gYm5DbG9uZTsKQmlnSW50ZWdlci5wcm90b3R5cGUuaW50VmFsdWUgPSBibkludFZhbHVlOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5ieXRlVmFsdWUgPSBibkJ5dGVWYWx1ZTsKQmlnSW50ZWdlci5wcm90b3R5cGUuc2hvcnRWYWx1ZSA9IGJuU2hvcnRWYWx1ZTsKQmlnSW50ZWdlci5wcm90b3R5cGUuc2lnbnVtID0gYm5TaWdOdW07CkJpZ0ludGVnZXIucHJvdG90eXBlLnRvQnl0ZUFycmF5ID0gYm5Ub0J5dGVBcnJheTsKQmlnSW50ZWdlci5wcm90b3R5cGUuZXF1YWxzID0gYm5FcXVhbHM7CkJpZ0ludGVnZXIucHJvdG90eXBlLm1pbiA9IGJuTWluOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5tYXggPSBibk1heDsKQmlnSW50ZWdlci5wcm90b3R5cGUuYW5kID0gYm5BbmQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLm9yID0gYm5PcjsKQmlnSW50ZWdlci5wcm90b3R5cGUueG9yID0gYm5Yb3I7CkJpZ0ludGVnZXIucHJvdG90eXBlLmFuZE5vdCA9IGJuQW5kTm90OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5ub3QgPSBibk5vdDsKQmlnSW50ZWdlci5wcm90b3R5cGUuc2hpZnRMZWZ0ID0gYm5TaGlmdExlZnQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLnNoaWZ0UmlnaHQgPSBiblNoaWZ0UmlnaHQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLmdldExvd2VzdFNldEJpdCA9IGJuR2V0TG93ZXN0U2V0Qml0OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXRDb3VudCA9IGJuQml0Q291bnQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLnRlc3RCaXQgPSBiblRlc3RCaXQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLnNldEJpdCA9IGJuU2V0Qml0OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5jbGVhckJpdCA9IGJuQ2xlYXJCaXQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLmZsaXBCaXQgPSBibkZsaXBCaXQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLmFkZCA9IGJuQWRkOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5zdWJ0cmFjdCA9IGJuU3VidHJhY3Q7CkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5ID0gYm5NdWx0aXBseTsKQmlnSW50ZWdlci5wcm90b3R5cGUuZGl2aWRlID0gYm5EaXZpZGU7CkJpZ0ludGVnZXIucHJvdG90eXBlLnJlbWFpbmRlciA9IGJuUmVtYWluZGVyOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZpZGVBbmRSZW1haW5kZXIgPSBibkRpdmlkZUFuZFJlbWFpbmRlcjsKQmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93ID0gYm5Nb2RQb3c7CkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludmVyc2UgPSBibk1vZEludmVyc2U7CkJpZ0ludGVnZXIucHJvdG90eXBlLnBvdyA9IGJuUG93OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5nY2QgPSBibkdDRDsKQmlnSW50ZWdlci5wcm90b3R5cGUuaXNQcm9iYWJsZVByaW1lID0gYm5Jc1Byb2JhYmxlUHJpbWU7CgovL0JpZ0ludGVnZXIgaW50ZXJmYWNlcyBub3QgaW1wbGVtZW50ZWQgaW4ganNibjoKCi8vQmlnSW50ZWdlcihpbnQgc2lnbnVtLCBieXRlW10gbWFnbml0dWRlKQovL2RvdWJsZSBkb3VibGVWYWx1ZSgpCi8vZmxvYXQgZmxvYXRWYWx1ZSgpCi8vaW50IGhhc2hDb2RlKCkKLy9sb25nIGxvbmdWYWx1ZSgpCi8vc3RhdGljIEJpZ0ludGVnZXIgdmFsdWVPZihsb25nIHZhbCkKCmZvcmdlLmpzYm4gPSBmb3JnZS5qc2JuIHx8IHt9Owpmb3JnZS5qc2JuLkJpZ0ludGVnZXIgPSBCaWdJbnRlZ2VyOwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAnanNibic7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9qc2JuJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFBhcnRpYWwgaW1wbGVtZW50YXRpb24gb2YgUEtDUyMxIHYyLjI6IFJTQS1PRUFQCiAqCiAqIE1vZGlmaWVkIGJ1dCBiYXNlZCBvbiB0aGUgZm9sbG93aW5nIE1JVCBhbmQgQlNEIGxpY2Vuc2VkIGNvZGU6CiAqCiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9ranVyL2pzandzL2Jsb2IvbWFzdGVyL3JzYS5qczoKICoKICogVGhlICdqc2p3cycoSlNPTiBXZWIgU2lnbmF0dXJlIEphdmFTY3JpcHQgTGlicmFyeSkgTGljZW5zZQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIgS2VuamkgVXJ1c2hpbWEKICoKICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQogKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAogKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKICogY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiAqCiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgogKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgogKiBUSEUgU09GVFdBUkUuCiAqCiAqIGh0dHA6Ly93ZWJyc2EuY3ZzLnNvdXJjZWZvcmdlLm5ldC92aWV3dmMvd2VicnNhL0NsaWVudC9SU0FFUy1PQUVQLmpzP2NvbnRlbnQtdHlwZT10ZXh0JTJGcGxhaW46CiAqCiAqIFJTQUVTLU9BRVAuanMKICogJElkOiBSU0FFUy1PQUVQLmpzLHYgMS4xLjEuMSAyMDAzLzAzLzE5IDE1OjM3OjIwIGVsbGlzcHJpdGNoYXJkIEV4cCAkCiAqIEphdmFTY3JpcHQgSW1wbGVtZW50YXRpb24gb2YgUEtDUyAjMSB2Mi4xIFJTQSBDUllQVE9HUkFQSFkgU1RBTkRBUkQgKFJTQSBMYWJvcmF0b3JpZXMsIEp1bmUgMTQsIDIwMDIpCiAqIENvcHlyaWdodCAoQykgRWxsaXMgUHJpdGNoYXJkLCBHdWFyZGlhbiBVbmxpbWl0ZWQgMjAwMy4KICogQ29udGFjdDogZWxsaXNAbnVraW5ldGljcy5jb20KICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlLgogKgogKiBPZmZpY2lhbCBkb2N1bWVudGF0aW9uOiBodHRwOi8vd3d3LnJzYS5jb20vcnNhbGFicy9ub2RlLmFzcD9pZD0yMTI1CiAqCiAqIEBhdXRob3IgRXZhbiBKb25lcyAoaHR0cDovL2V2YW5qb25lcy5jYS8pCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKLy8gc2hvcnRjdXQgZm9yIFBLQ1MjMSBBUEkKdmFyIHBrY3MxID0gZm9yZ2UucGtjczEgPSBmb3JnZS5wa2NzMSB8fCB7fTsKCi8qKgogKiBFbmNvZGUgdGhlIGdpdmVuIFJTQUVTLU9BRVAgbWVzc2FnZSAoTSkgdXNpbmcga2V5LCB3aXRoIG9wdGlvbmFsIGxhYmVsIChMKQogKiBhbmQgc2VlZC4KICoKICogVGhpcyBtZXRob2QgZG9lcyBub3QgcGVyZm9ybSBSU0EgZW5jcnlwdGlvbiwgaXQgb25seSBlbmNvZGVzIHRoZSBtZXNzYWdlCiAqIHVzaW5nIFJTQUVTLU9BRVAuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIFJTQSBrZXkgdG8gdXNlLgogKiBAcGFyYW0gbWVzc2FnZSB0aGUgbWVzc2FnZSB0byBlbmNvZGUuCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgbGFiZWwgYW4gb3B0aW9uYWwgbGFiZWwgdG8gdXNlLgogKiAgICAgICAgICBzZWVkIHRoZSBzZWVkIHRvIHVzZS4KICogICAgICAgICAgbWQgdGhlIG1lc3NhZ2UgZGlnZXN0IG9iamVjdCB0byB1c2UsIHVuZGVmaW5lZCBmb3IgU0hBLTEuCiAqICAgICAgICAgIG1nZjEgb3B0aW9uYWwgbWdmMSBwYXJhbWV0ZXJzOgogKiAgICAgICAgICAgIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlIGZvciBNR0YxLgogKgogKiBAcmV0dXJuIHRoZSBlbmNvZGVkIG1lc3NhZ2UgYnl0ZXMuCiAqLwpwa2NzMS5lbmNvZGVfcnNhX29hZXAgPSBmdW5jdGlvbihrZXksIG1lc3NhZ2UsIG9wdGlvbnMpIHsKICAvLyBwYXJzZSBhcmd1bWVudHMKICB2YXIgbGFiZWw7CiAgdmFyIHNlZWQ7CiAgdmFyIG1kOwogIHZhciBtZ2YxTWQ7CiAgLy8gbGVnYWN5IGFyZ3MgKGxhYmVsLCBzZWVkLCBtZCkKICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHsKICAgIGxhYmVsID0gb3B0aW9uczsKICAgIHNlZWQgPSBhcmd1bWVudHNbM10gfHwgdW5kZWZpbmVkOwogICAgbWQgPSBhcmd1bWVudHNbNF0gfHwgdW5kZWZpbmVkOwogIH0gZWxzZSBpZihvcHRpb25zKSB7CiAgICBsYWJlbCA9IG9wdGlvbnMubGFiZWwgfHwgdW5kZWZpbmVkOwogICAgc2VlZCA9IG9wdGlvbnMuc2VlZCB8fCB1bmRlZmluZWQ7CiAgICBtZCA9IG9wdGlvbnMubWQgfHwgdW5kZWZpbmVkOwogICAgaWYob3B0aW9ucy5tZ2YxICYmIG9wdGlvbnMubWdmMS5tZCkgewogICAgICBtZ2YxTWQgPSBvcHRpb25zLm1nZjEubWQ7CiAgICB9CiAgfQoKICAvLyBkZWZhdWx0IE9BRVAgdG8gU0hBLTEgbWVzc2FnZSBkaWdlc3QKICBpZighbWQpIHsKICAgIG1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICB9IGVsc2UgewogICAgbWQuc3RhcnQoKTsKICB9CgogIC8vIGRlZmF1bHQgTUdGLTEgdG8gc2FtZSBhcyBPQUVQCiAgaWYoIW1nZjFNZCkgewogICAgbWdmMU1kID0gbWQ7CiAgfQoKICAvLyBjb21wdXRlIGxlbmd0aCBpbiBieXRlcyBhbmQgY2hlY2sgb3V0cHV0CiAgdmFyIGtleUxlbmd0aCA9IE1hdGguY2VpbChrZXkubi5iaXRMZW5ndGgoKSAvIDgpOwogIHZhciBtYXhMZW5ndGggPSBrZXlMZW5ndGggLSAyICogbWQuZGlnZXN0TGVuZ3RoIC0gMjsKICBpZihtZXNzYWdlLmxlbmd0aCA+IG1heExlbmd0aCkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdSU0FFUy1PQUVQIGlucHV0IG1lc3NhZ2UgbGVuZ3RoIGlzIHRvbyBsb25nLicpOwogICAgZXJyb3IubGVuZ3RoID0gbWVzc2FnZS5sZW5ndGg7CiAgICBlcnJvci5tYXhMZW5ndGggPSBtYXhMZW5ndGg7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIGlmKCFsYWJlbCkgewogICAgbGFiZWwgPSAnJzsKICB9CiAgbWQudXBkYXRlKGxhYmVsLCAncmF3Jyk7CiAgdmFyIGxIYXNoID0gbWQuZGlnZXN0KCk7CgogIHZhciBQUyA9ICcnOwogIHZhciBQU19sZW5ndGggPSBtYXhMZW5ndGggLSBtZXNzYWdlLmxlbmd0aDsKICBmb3IgKHZhciBpID0gMDsgaSA8IFBTX2xlbmd0aDsgaSsrKSB7CiAgICBQUyArPSAnXHgwMCc7CiAgfQoKICB2YXIgREIgPSBsSGFzaC5nZXRCeXRlcygpICsgUFMgKyAnXHgwMScgKyBtZXNzYWdlOwoKICBpZighc2VlZCkgewogICAgc2VlZCA9IGZvcmdlLnJhbmRvbS5nZXRCeXRlcyhtZC5kaWdlc3RMZW5ndGgpOwogIH0gZWxzZSBpZihzZWVkLmxlbmd0aCAhPT0gbWQuZGlnZXN0TGVuZ3RoKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0ludmFsaWQgUlNBRVMtT0FFUCBzZWVkLiBUaGUgc2VlZCBsZW5ndGggbXVzdCAnICsKICAgICAgJ21hdGNoIHRoZSBkaWdlc3QgbGVuZ3RoLicpCiAgICBlcnJvci5zZWVkTGVuZ3RoID0gc2VlZC5sZW5ndGg7CiAgICBlcnJvci5kaWdlc3RMZW5ndGggPSBtZC5kaWdlc3RMZW5ndGg7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIHZhciBkYk1hc2sgPSByc2FfbWdmMShzZWVkLCBrZXlMZW5ndGggLSBtZC5kaWdlc3RMZW5ndGggLSAxLCBtZ2YxTWQpOwogIHZhciBtYXNrZWREQiA9IGZvcmdlLnV0aWwueG9yQnl0ZXMoREIsIGRiTWFzaywgREIubGVuZ3RoKTsKCiAgdmFyIHNlZWRNYXNrID0gcnNhX21nZjEobWFza2VkREIsIG1kLmRpZ2VzdExlbmd0aCwgbWdmMU1kKTsKICB2YXIgbWFza2VkU2VlZCA9IGZvcmdlLnV0aWwueG9yQnl0ZXMoc2VlZCwgc2VlZE1hc2ssIHNlZWQubGVuZ3RoKTsKCiAgLy8gcmV0dXJuIGVuY29kZWQgbWVzc2FnZQogIHJldHVybiAnXHgwMCcgKyBtYXNrZWRTZWVkICsgbWFza2VkREI7Cn07CgovKioKICogRGVjb2RlIHRoZSBnaXZlbiBSU0FFUy1PQUVQIGVuY29kZWQgbWVzc2FnZSAoRU0pIHVzaW5nIGtleSwgd2l0aCBvcHRpb25hbAogKiBsYWJlbCAoTCkuCiAqCiAqIFRoaXMgbWV0aG9kIGRvZXMgbm90IHBlcmZvcm0gUlNBIGRlY3J5cHRpb24sIGl0IG9ubHkgZGVjb2RlcyB0aGUgbWVzc2FnZQogKiB1c2luZyBSU0FFUy1PQUVQLgogKgogKiBAcGFyYW0ga2V5IHRoZSBSU0Ega2V5IHRvIHVzZS4KICogQHBhcmFtIGVtIHRoZSBlbmNvZGVkIG1lc3NhZ2UgdG8gZGVjb2RlLgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2U6CiAqICAgICAgICAgIGxhYmVsIGFuIG9wdGlvbmFsIGxhYmVsIHRvIHVzZS4KICogICAgICAgICAgbWQgdGhlIG1lc3NhZ2UgZGlnZXN0IG9iamVjdCB0byB1c2UgZm9yIE9BRVAsIHVuZGVmaW5lZCBmb3IgU0hBLTEuCiAqICAgICAgICAgIG1nZjEgb3B0aW9uYWwgbWdmMSBwYXJhbWV0ZXJzOgogKiAgICAgICAgICAgIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlIGZvciBNR0YxLgogKgogKiBAcmV0dXJuIHRoZSBkZWNvZGVkIG1lc3NhZ2UgYnl0ZXMuCiAqLwpwa2NzMS5kZWNvZGVfcnNhX29hZXAgPSBmdW5jdGlvbihrZXksIGVtLCBvcHRpb25zKSB7CiAgLy8gcGFyc2UgYXJncwogIHZhciBsYWJlbDsKICB2YXIgbWQ7CiAgdmFyIG1nZjFNZDsKICAvLyBsZWdhY3kgYXJncwogIGlmKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJykgewogICAgbGFiZWwgPSBvcHRpb25zOwogICAgbWQgPSBhcmd1bWVudHNbM10gfHwgdW5kZWZpbmVkOwogIH0gZWxzZSBpZihvcHRpb25zKSB7CiAgICBsYWJlbCA9IG9wdGlvbnMubGFiZWwgfHwgdW5kZWZpbmVkOwogICAgbWQgPSBvcHRpb25zLm1kIHx8IHVuZGVmaW5lZDsKICAgIGlmKG9wdGlvbnMubWdmMSAmJiBvcHRpb25zLm1nZjEubWQpIHsKICAgICAgbWdmMU1kID0gb3B0aW9ucy5tZ2YxLm1kOwogICAgfQogIH0KCiAgLy8gY29tcHV0ZSBsZW5ndGggaW4gYnl0ZXMKICB2YXIga2V5TGVuZ3RoID0gTWF0aC5jZWlsKGtleS5uLmJpdExlbmd0aCgpIC8gOCk7CgogIGlmKGVtLmxlbmd0aCAhPT0ga2V5TGVuZ3RoKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1JTQUVTLU9BRVAgZW5jb2RlZCBtZXNzYWdlIGxlbmd0aCBpcyBpbnZhbGlkLicpOwogICAgZXJyb3IubGVuZ3RoID0gZW0ubGVuZ3RoOwogICAgZXJyb3IuZXhwZWN0ZWRMZW5ndGggPSBrZXlMZW5ndGg7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIC8vIGRlZmF1bHQgT0FFUCB0byBTSEEtMSBtZXNzYWdlIGRpZ2VzdAogIGlmKG1kID09PSB1bmRlZmluZWQpIHsKICAgIG1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICB9IGVsc2UgewogICAgbWQuc3RhcnQoKTsKICB9CgogIC8vIGRlZmF1bHQgTUdGLTEgdG8gc2FtZSBhcyBPQUVQCiAgaWYoIW1nZjFNZCkgewogICAgbWdmMU1kID0gbWQ7CiAgfQoKICBpZihrZXlMZW5ndGggPCAyICogbWQuZGlnZXN0TGVuZ3RoICsgMikgewogICAgdGhyb3cgbmV3IEVycm9yKCdSU0FFUy1PQUVQIGtleSBpcyB0b28gc2hvcnQgZm9yIHRoZSBoYXNoIGZ1bmN0aW9uLicpOwogIH0KCiAgaWYoIWxhYmVsKSB7CiAgICBsYWJlbCA9ICcnOwogIH0KICBtZC51cGRhdGUobGFiZWwsICdyYXcnKTsKICB2YXIgbEhhc2ggPSBtZC5kaWdlc3QoKS5nZXRCeXRlcygpOwoKICAvLyBzcGxpdCB0aGUgbWVzc2FnZSBpbnRvIGl0cyBwYXJ0cwogIHZhciB5ID0gZW0uY2hhckF0KDApOwogIHZhciBtYXNrZWRTZWVkID0gZW0uc3Vic3RyaW5nKDEsIG1kLmRpZ2VzdExlbmd0aCArIDEpOwogIHZhciBtYXNrZWREQiA9IGVtLnN1YnN0cmluZygxICsgbWQuZGlnZXN0TGVuZ3RoKTsKCiAgdmFyIHNlZWRNYXNrID0gcnNhX21nZjEobWFza2VkREIsIG1kLmRpZ2VzdExlbmd0aCwgbWdmMU1kKTsKICB2YXIgc2VlZCA9IGZvcmdlLnV0aWwueG9yQnl0ZXMobWFza2VkU2VlZCwgc2VlZE1hc2ssIG1hc2tlZFNlZWQubGVuZ3RoKTsKCiAgdmFyIGRiTWFzayA9IHJzYV9tZ2YxKHNlZWQsIGtleUxlbmd0aCAtIG1kLmRpZ2VzdExlbmd0aCAtIDEsIG1nZjFNZCk7CiAgdmFyIGRiID0gZm9yZ2UudXRpbC54b3JCeXRlcyhtYXNrZWREQiwgZGJNYXNrLCBtYXNrZWREQi5sZW5ndGgpOwoKICB2YXIgbEhhc2hQcmltZSA9IGRiLnN1YnN0cmluZygwLCBtZC5kaWdlc3RMZW5ndGgpOwoKICAvLyBjb25zdGFudCB0aW1lIGNoZWNrIHRoYXQgYWxsIHZhbHVlcyBtYXRjaCB3aGF0IGlzIGV4cGVjdGVkCiAgdmFyIGVycm9yID0gKHkgIT09ICdceDAwJyk7CgogIC8vIGNvbnN0YW50IHRpbWUgY2hlY2sgbEhhc2ggdnMgbEhhc2hQcmltZQogIGZvcih2YXIgaSA9IDA7IGkgPCBtZC5kaWdlc3RMZW5ndGg7ICsraSkgewogICAgZXJyb3IgfD0gKGxIYXNoLmNoYXJBdChpKSAhPT0gbEhhc2hQcmltZS5jaGFyQXQoaSkpOwogIH0KCiAgLy8gImNvbnN0YW50IHRpbWUiIGZpbmQgdGhlIDB4MSBieXRlIHNlcGFyYXRpbmcgdGhlIHBhZGRpbmcgKHplcm9zKSBmcm9tIHRoZQogIC8vIG1lc3NhZ2UKICAvLyBUT0RPOiBJdCBtdXN0IGJlIHBvc3NpYmxlIHRvIGRvIHRoaXMgaW4gYSBiZXR0ZXIvc21hcnRlciB3YXk/CiAgdmFyIGluX3BzID0gMTsKICB2YXIgaW5kZXggPSBtZC5kaWdlc3RMZW5ndGg7CiAgZm9yKHZhciBqID0gbWQuZGlnZXN0TGVuZ3RoOyBqIDwgZGIubGVuZ3RoOyBqKyspIHsKICAgIHZhciBjb2RlID0gZGIuY2hhckNvZGVBdChqKTsKCiAgICB2YXIgaXNfMCA9IChjb2RlICYgMHgxKSBeIDB4MTsKCiAgICAvLyBub24temVybyBpZiBub3QgMCBvciAxIGluIHRoZSBwcyBzZWN0aW9uCiAgICB2YXIgZXJyb3JfbWFzayA9IGluX3BzID8gMHhmZmZlIDogMHgwMDAwOwogICAgZXJyb3IgfD0gKGNvZGUgJiBlcnJvcl9tYXNrKTsKCiAgICAvLyBsYXRjaCBpbl9wcyB0byB6ZXJvIGFmdGVyIHdlIGZpbmQgMHgxCiAgICBpbl9wcyA9IGluX3BzICYgaXNfMDsKICAgIGluZGV4ICs9IGluX3BzOwogIH0KCiAgaWYoZXJyb3IgfHwgZGIuY2hhckNvZGVBdChpbmRleCkgIT09IDB4MSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFJTQUVTLU9BRVAgcGFkZGluZy4nKTsKICB9CgogIHJldHVybiBkYi5zdWJzdHJpbmcoaW5kZXggKyAxKTsKfTsKCmZ1bmN0aW9uIHJzYV9tZ2YxKHNlZWQsIG1hc2tMZW5ndGgsIGhhc2gpIHsKICAvLyBkZWZhdWx0IHRvIFNIQS0xIG1lc3NhZ2UgZGlnZXN0CiAgaWYoIWhhc2gpIHsKICAgIGhhc2ggPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogIH0KICB2YXIgdCA9ICcnOwogIHZhciBjb3VudCA9IE1hdGguY2VpbChtYXNrTGVuZ3RoIC8gaGFzaC5kaWdlc3RMZW5ndGgpOwogIGZvcih2YXIgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CiAgICB2YXIgYyA9IFN0cmluZy5mcm9tQ2hhckNvZGUoCiAgICAgIChpID4+IDI0KSAmIDB4RkYsIChpID4+IDE2KSAmIDB4RkYsIChpID4+IDgpICYgMHhGRiwgaSAmIDB4RkYpOwogICAgaGFzaC5zdGFydCgpOwogICAgaGFzaC51cGRhdGUoc2VlZCArIGMpOwogICAgdCArPSBoYXNoLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CiAgfQogIHJldHVybiB0LnN1YnN0cmluZygwLCBtYXNrTGVuZ3RoKTsKfQoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncGtjczEnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvcGtjczEnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJywgJy4vcmFuZG9tJywgJy4vc2hhMSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBQcmltZSBudW1iZXIgZ2VuZXJhdGlvbiBBUEkuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIGZvcmdlLnByaW1lIGFscmVhZHkgZGVmaW5lZAppZihmb3JnZS5wcmltZSkgewogIHJldHVybjsKfQoKLyogUFJJTUUgQVBJICovCnZhciBwcmltZSA9IGZvcmdlLnByaW1lID0gZm9yZ2UucHJpbWUgfHwge307Cgp2YXIgQmlnSW50ZWdlciA9IGZvcmdlLmpzYm4uQmlnSW50ZWdlcjsKCi8vIHByaW1lcyBhcmUgMzBrK2kgZm9yIGkgPSAxLCA3LCAxMSwgMTMsIDE3LCAxOSwgMjMsIDI5CnZhciBHQ0RfMzBfREVMVEEgPSBbNiwgNCwgMiwgNCwgMiwgNCwgNiwgMl07CnZhciBUSElSVFkgPSBuZXcgQmlnSW50ZWdlcihudWxsKTsKVEhJUlRZLmZyb21JbnQoMzApOwp2YXIgb3Bfb3IgPSBmdW5jdGlvbih4LCB5KSB7cmV0dXJuIHh8eTt9OwoKLyoqCiAqIEdlbmVyYXRlcyBhIHJhbmRvbSBwcm9iYWJsZSBwcmltZSB3aXRoIHRoZSBnaXZlbiBudW1iZXIgb2YgYml0cy4KICoKICogQWx0ZXJuYXRpdmUgYWxnb3JpdGhtcyBjYW4gYmUgc3BlY2lmaWVkIGJ5IG5hbWUgYXMgYSBzdHJpbmcgb3IgYXMgYW4KICogb2JqZWN0IHdpdGggY3VzdG9tIG9wdGlvbnMgbGlrZSBzbzoKICoKICogewogKiAgIG5hbWU6ICdQUklNRUlOQycsCiAqICAgb3B0aW9uczogewogKiAgICAgbWF4QmxvY2tUaW1lOiA8dGhlIG1heGltdW0gYW1vdW50IG9mIHRpbWUgdG8gYmxvY2sgdGhlIG1haW4KICogICAgICAgdGhyZWFkIGJlZm9yZSBhbGxvd2luZyBJL08gb3RoZXIgSlMgdG8gcnVuPiwKICogICAgIG1pbGxlclJhYmluVGVzdHM6IDx0aGUgbnVtYmVyIG9mIG1pbGxlci1yYWJpbiB0ZXN0cyB0byBydW4+LAogKiAgICAgd29ya2VyU2NyaXB0OiA8dGhlIHdvcmtlciBzY3JpcHQgVVJMPiwKICogICAgIHdvcmtlcnM6IDx0aGUgbnVtYmVyIG9mIHdlYiB3b3JrZXJzIChpZiBzdXBwb3J0ZWQpIHRvIHVzZSwKICogICAgICAgLTEgdG8gdXNlIGVzdGltYXRlZCBjb3JlcyBtaW51cyBvbmU+LgogKiAgICAgd29ya0xvYWQ6IHRoZSBzaXplIG9mIHRoZSB3b3JrIGxvYWQsIGllOiBudW1iZXIgb2YgcG9zc2libGUgcHJpbWUKICogICAgICAgbnVtYmVycyBmb3IgZWFjaCB3ZWIgd29ya2VyIHRvIGNoZWNrIHBlciB3b3JrIGFzc2lnbm1lbnQsCiAqICAgICAgIChkZWZhdWx0OiAxMDApLgogKiAgIH0KICogfQogKgogKiBAcGFyYW0gYml0cyB0aGUgbnVtYmVyIG9mIGJpdHMgZm9yIHRoZSBwcmltZSBudW1iZXIuCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZS4KICogICAgICAgICAgW2FsZ29yaXRobV0gdGhlIGFsZ29yaXRobSB0byB1c2UgKGRlZmF1bHQ6ICdQUklNRUlOQycpLgogKiAgICAgICAgICBbcHJuZ10gYSBjdXN0b20gY3J5cHRvLXNlY3VyZSBwc2V1ZG8tcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdG8gdXNlLAogKiAgICAgICAgICAgIHRoYXQgbXVzdCBkZWZpbmUgImdldEJ5dGVzU3luYyIuCiAqCiAqIEByZXR1cm4gY2FsbGJhY2soZXJyLCBudW0pIGNhbGxlZCBvbmNlIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLgogKi8KcHJpbWUuZ2VuZXJhdGVQcm9iYWJsZVByaW1lID0gZnVuY3Rpb24oYml0cywgb3B0aW9ucywgY2FsbGJhY2spIHsKICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykgewogICAgY2FsbGJhY2sgPSBvcHRpb25zOwogICAgb3B0aW9ucyA9IHt9OwogIH0KICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKCiAgLy8gZGVmYXVsdCB0byBQUklNRUlOQyBhbGdvcml0aG0KICB2YXIgYWxnb3JpdGhtID0gb3B0aW9ucy5hbGdvcml0aG0gfHwgJ1BSSU1FSU5DJzsKICBpZih0eXBlb2YgYWxnb3JpdGhtID09PSAnc3RyaW5nJykgewogICAgYWxnb3JpdGhtID0ge25hbWU6IGFsZ29yaXRobX07CiAgfQogIGFsZ29yaXRobS5vcHRpb25zID0gYWxnb3JpdGhtLm9wdGlvbnMgfHwge307CgogIC8vIGNyZWF0ZSBwcm5nIHdpdGggYXBpIHRoYXQgbWF0Y2hlcyBCaWdJbnRlZ2VyIHNlY3VyZSByYW5kb20KICB2YXIgcHJuZyA9IG9wdGlvbnMucHJuZyB8fCBmb3JnZS5yYW5kb207CiAgdmFyIHJuZyA9IHsKICAgIC8vIHggaXMgYW4gYXJyYXkgdG8gZmlsbCB3aXRoIGJ5dGVzCiAgICBuZXh0Qnl0ZXM6IGZ1bmN0aW9uKHgpIHsKICAgICAgdmFyIGIgPSBwcm5nLmdldEJ5dGVzU3luYyh4Lmxlbmd0aCk7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgeFtpXSA9IGIuY2hhckNvZGVBdChpKTsKICAgICAgfQogICAgfQogIH07CgogIGlmKGFsZ29yaXRobS5uYW1lID09PSAnUFJJTUVJTkMnKSB7CiAgICByZXR1cm4gcHJpbWVpbmNGaW5kUHJpbWUoYml0cywgcm5nLCBhbGdvcml0aG0ub3B0aW9ucywgY2FsbGJhY2spOwogIH0KCiAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHByaW1lIGdlbmVyYXRpb24gYWxnb3JpdGhtOiAnICsgYWxnb3JpdGhtLm5hbWUpOwp9OwoKZnVuY3Rpb24gcHJpbWVpbmNGaW5kUHJpbWUoYml0cywgcm5nLCBvcHRpb25zLCBjYWxsYmFjaykgewogIGlmKCd3b3JrZXJzJyBpbiBvcHRpb25zKSB7CiAgICByZXR1cm4gcHJpbWVpbmNGaW5kUHJpbWVXaXRoV29ya2VycyhiaXRzLCBybmcsIG9wdGlvbnMsIGNhbGxiYWNrKTsKICB9CiAgcmV0dXJuIHByaW1laW5jRmluZFByaW1lV2l0aG91dFdvcmtlcnMoYml0cywgcm5nLCBvcHRpb25zLCBjYWxsYmFjayk7Cn0KCmZ1bmN0aW9uIHByaW1laW5jRmluZFByaW1lV2l0aG91dFdvcmtlcnMoYml0cywgcm5nLCBvcHRpb25zLCBjYWxsYmFjaykgewogIC8vIGluaXRpYWxpemUgcmFuZG9tIG51bWJlcgogIHZhciBudW0gPSBnZW5lcmF0ZVJhbmRvbShiaXRzLCBybmcpOwoKICAvKiBOb3RlOiBBbGwgcHJpbWVzIGFyZSBvZiB0aGUgZm9ybSAzMGsraSBmb3IgaSA8IDMwIGFuZCBnY2QoMzAsIGkpPTEuIFRoZQogIG51bWJlciB3ZSBhcmUgZ2l2ZW4gaXMgYWx3YXlzIGFsaWduZWQgYXQgMzBrICsgMS4gRWFjaCB0aW1lIHRoZSBudW1iZXIgaXMKICBkZXRlcm1pbmVkIG5vdCB0byBiZSBwcmltZSB3ZSBhZGQgdG8gZ2V0IHRvIHRoZSBuZXh0ICdpJywgZWc6IGlmIHRoZSBudW1iZXIKICB3YXMgYXQgMzBrICsgMSB3ZSBhZGQgNi4gKi8KICB2YXIgZGVsdGFJZHggPSAwOwoKICAvLyBnZXQgcmVxdWlyZWQgbnVtYmVyIG9mIE1SIHRlc3RzCiAgdmFyIG1yVGVzdHMgPSBnZXRNaWxsZXJSYWJpblRlc3RzKG51bS5iaXRMZW5ndGgoKSk7CiAgaWYoJ21pbGxlclJhYmluVGVzdHMnIGluIG9wdGlvbnMpIHsKICAgIG1yVGVzdHMgPSBvcHRpb25zLm1pbGxlclJhYmluVGVzdHM7CiAgfQoKICAvLyBmaW5kIHByaW1lIG5lYXJlc3QgdG8gJ251bScgZm9yIG1heEJsb2NrVGltZSBtcwogIC8vIDEwIG1zIGdpdmVzIDVtcyBvZiBsZWV3YXkgZm9yIG90aGVyIGNhbGN1bGF0aW9ucyBiZWZvcmUgZHJvcHBpbmcKICAvLyBiZWxvdyA2MGZwcyAoMTAwMC82MCA9PSAxNi42NyksIGJ1dCBpbiByZWFsaXR5LCB0aGUgbnVtYmVyIHdpbGwKICAvLyBsaWtlbHkgYmUgaGlnaGVyIGR1ZSB0byBhbiAnYXRvbWljJyBiaWcgaW50IG1vZFBvdwogIHZhciBtYXhCbG9ja1RpbWUgPSAxMDsKICBpZignbWF4QmxvY2tUaW1lJyBpbiBvcHRpb25zKSB7CiAgICBtYXhCbG9ja1RpbWUgPSBvcHRpb25zLm1heEJsb2NrVGltZTsKICB9CiAgdmFyIHN0YXJ0ID0gK25ldyBEYXRlKCk7CiAgZG8gewogICAgLy8gb3ZlcmZsb3csIHJlZ2VuZXJhdGUgcmFuZG9tIG51bWJlcgogICAgaWYobnVtLmJpdExlbmd0aCgpID4gYml0cykgewogICAgICBudW0gPSBnZW5lcmF0ZVJhbmRvbShiaXRzLCBybmcpOwogICAgfQogICAgLy8gZG8gcHJpbWFsaXR5IHRlc3QKICAgIGlmKG51bS5pc1Byb2JhYmxlUHJpbWUobXJUZXN0cykpIHsKICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIG51bSk7CiAgICB9CiAgICAvLyBnZXQgbmV4dCBwb3RlbnRpYWwgcHJpbWUKICAgIG51bS5kQWRkT2Zmc2V0KEdDRF8zMF9ERUxUQVtkZWx0YUlkeCsrICUgOF0sIDApOwogIH0gd2hpbGUobWF4QmxvY2tUaW1lIDwgMCB8fCAoK25ldyBEYXRlKCkgLSBzdGFydCA8IG1heEJsb2NrVGltZSkpOwoKICAvLyBrZWVwIHRyeWluZyAoc2V0SW1tZWRpYXRlIHdvdWxkIGJlIGJldHRlciBoZXJlKQogIGZvcmdlLnV0aWwuc2V0SW1tZWRpYXRlKGZ1bmN0aW9uKCkgewogICAgcHJpbWVpbmNGaW5kUHJpbWVXaXRob3V0V29ya2VycyhiaXRzLCBybmcsIG9wdGlvbnMsIGNhbGxiYWNrKTsKICB9KTsKfQoKZnVuY3Rpb24gcHJpbWVpbmNGaW5kUHJpbWVXaXRoV29ya2VycyhiaXRzLCBybmcsIG9wdGlvbnMsIGNhbGxiYWNrKSB7CiAgLy8gd2ViIHdvcmtlcnMgdW5hdmFpbGFibGUKICBpZih0eXBlb2YgV29ya2VyID09PSAndW5kZWZpbmVkJykgewogICAgcmV0dXJuIHByaW1laW5jRmluZFByaW1lV2l0aG91dFdvcmtlcnMoYml0cywgcm5nLCBvcHRpb25zLCBjYWxsYmFjayk7CiAgfQoKICAvLyBpbml0aWFsaXplIHJhbmRvbSBudW1iZXIKICB2YXIgbnVtID0gZ2VuZXJhdGVSYW5kb20oYml0cywgcm5nKTsKCiAgLy8gdXNlIHdlYiB3b3JrZXJzIHRvIGdlbmVyYXRlIGtleXMKICB2YXIgbnVtV29ya2VycyA9IG9wdGlvbnMud29ya2VyczsKICB2YXIgd29ya0xvYWQgPSBvcHRpb25zLndvcmtMb2FkIHx8IDEwMDsKICB2YXIgcmFuZ2UgPSB3b3JrTG9hZCAqIDMwIC8gODsKICB2YXIgd29ya2VyU2NyaXB0ID0gb3B0aW9ucy53b3JrZXJTY3JpcHQgfHwgJ2ZvcmdlL3ByaW1lLndvcmtlci5qcyc7CiAgaWYobnVtV29ya2VycyA9PT0gLTEpIHsKICAgIHJldHVybiBmb3JnZS51dGlsLmVzdGltYXRlQ29yZXMoZnVuY3Rpb24oZXJyLCBjb3JlcykgewogICAgICBpZihlcnIpIHsKICAgICAgICAvLyBkZWZhdWx0IHRvIDIKICAgICAgICBjb3JlcyA9IDI7CiAgICAgIH0KICAgICAgbnVtV29ya2VycyA9IGNvcmVzIC0gMTsKICAgICAgZ2VuZXJhdGUoKTsKICAgIH0pOwogIH0KICBnZW5lcmF0ZSgpOwoKICBmdW5jdGlvbiBnZW5lcmF0ZSgpIHsKICAgIC8vIHJlcXVpcmUgYXQgbGVhc3QgMSB3b3JrZXIKICAgIG51bVdvcmtlcnMgPSBNYXRoLm1heCgxLCBudW1Xb3JrZXJzKTsKCiAgICAvLyBUT0RPOiBjb25zaWRlciBvcHRpbWl6aW5nIGJ5IHN0YXJ0aW5nIHdvcmtlcnMgb3V0c2lkZSBnZXRQcmltZSgpIC4uLgogICAgLy8gbm90ZSB0aGF0IGluIG9yZGVyIHRvIGNsZWFuIHVwIHRoZXkgd2lsbCBoYXZlIHRvIGJlIG1hZGUgaW50ZXJuYWxseQogICAgLy8gYXN5bmNocm9ub3VzIHdoaWNoIG1heSBhY3R1YWxseSBiZSBzbG93ZXIKCiAgICAvLyBzdGFydCB3b3JrZXJzIGltbWVkaWF0ZWx5CiAgICB2YXIgd29ya2VycyA9IFtdOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG51bVdvcmtlcnM7ICsraSkgewogICAgICAvLyBGSVhNRTogZml4IHBhdGggb3IgdXNlIGJsb2IgVVJMcwogICAgICB3b3JrZXJzW2ldID0gbmV3IFdvcmtlcih3b3JrZXJTY3JpcHQpOwogICAgfQogICAgdmFyIHJ1bm5pbmcgPSBudW1Xb3JrZXJzOwoKICAgIC8vIGxpc3RlbiBmb3IgcmVxdWVzdHMgZnJvbSB3b3JrZXJzIGFuZCBhc3NpZ24gcmFuZ2VzIHRvIGZpbmQgcHJpbWUKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBudW1Xb3JrZXJzOyArK2kpIHsKICAgICAgd29ya2Vyc1tpXS5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgd29ya2VyTWVzc2FnZSk7CiAgICB9CgogICAgLyogTm90ZTogVGhlIGRpc3RyaWJ1dGlvbiBvZiByYW5kb20gbnVtYmVycyBpcyB1bmtub3duLiBUaGVyZWZvcmUsIGVhY2gKICAgIHdlYiB3b3JrZXIgaXMgY29udGludW91c2x5IGFsbG9jYXRlZCBhIHJhbmdlIG9mIG51bWJlcnMgdG8gY2hlY2sgZm9yIGEKICAgIHJhbmRvbSBudW1iZXIgdW50aWwgb25lIGlzIGZvdW5kLgoKICAgIEV2ZXJ5IDMwIG51bWJlcnMgd2lsbCBiZSBjaGVja2VkIGp1c3QgOCB0aW1lcywgYmVjYXVzZSBwcmltZSBudW1iZXJzCiAgICBoYXZlIHRoZSBmb3JtOgoKICAgIDMwaytpLCBmb3IgaSA8IDMwIGFuZCBnY2QoMzAsIGkpPTEgKHRoZXJlIGFyZSA4IHZhbHVlcyBvZiBpIGZvciB0aGlzKQoKICAgIFRoZXJlZm9yZSwgaWYgd2Ugd2FudCBhIHdlYiB3b3JrZXIgdG8gcnVuIE4gY2hlY2tzIGJlZm9yZSBhc2tpbmcgZm9yCiAgICBhIG5ldyByYW5nZSBvZiBudW1iZXJzLCBlYWNoIHJhbmdlIG11c3QgY29udGFpbiBOKjMwLzggbnVtYmVycy4KCiAgICBGb3IgMTAwIGNoZWNrcyAod29ya0xvYWQpLCB0aGlzIGlzIGEgcmFuZ2Ugb2YgMzc1LiAqLwoKICAgIHZhciBmb3VuZCA9IGZhbHNlOwogICAgZnVuY3Rpb24gd29ya2VyTWVzc2FnZShlKSB7CiAgICAgIC8vIGlnbm9yZSBtZXNzYWdlLCBwcmltZSBhbHJlYWR5IGZvdW5kCiAgICAgIGlmKGZvdW5kKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICAtLXJ1bm5pbmc7CiAgICAgIHZhciBkYXRhID0gZS5kYXRhOwogICAgICBpZihkYXRhLmZvdW5kKSB7CiAgICAgICAgLy8gdGVybWluYXRlIGFsbCB3b3JrZXJzCiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHdvcmtlcnMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgIHdvcmtlcnNbaV0udGVybWluYXRlKCk7CiAgICAgICAgfQogICAgICAgIGZvdW5kID0gdHJ1ZTsKICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgbmV3IEJpZ0ludGVnZXIoZGF0YS5wcmltZSwgMTYpKTsKICAgICAgfQoKICAgICAgLy8gb3ZlcmZsb3csIHJlZ2VuZXJhdGUgcmFuZG9tIG51bWJlcgogICAgICBpZihudW0uYml0TGVuZ3RoKCkgPiBiaXRzKSB7CiAgICAgICAgbnVtID0gZ2VuZXJhdGVSYW5kb20oYml0cywgcm5nKTsKICAgICAgfQoKICAgICAgLy8gYXNzaWduIG5ldyByYW5nZSB0byBjaGVjawogICAgICB2YXIgaGV4ID0gbnVtLnRvU3RyaW5nKDE2KTsKCiAgICAgIC8vIHN0YXJ0IHByaW1lIHNlYXJjaAogICAgICBlLnRhcmdldC5wb3N0TWVzc2FnZSh7CiAgICAgICAgaGV4OiBoZXgsCiAgICAgICAgd29ya0xvYWQ6IHdvcmtMb2FkCiAgICAgIH0pOwoKICAgICAgbnVtLmRBZGRPZmZzZXQocmFuZ2UsIDApOwogICAgfQogIH0KfQoKLyoqCiAqIEdlbmVyYXRlcyBhIHJhbmRvbSBudW1iZXIgdXNpbmcgdGhlIGdpdmVuIG51bWJlciBvZiBiaXRzIGFuZCBSTkcuCiAqCiAqIEBwYXJhbSBiaXRzIHRoZSBudW1iZXIgb2YgYml0cyBmb3IgdGhlIG51bWJlci4KICogQHBhcmFtIHJuZyB0aGUgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSByYW5kb20gbnVtYmVyLgogKi8KZnVuY3Rpb24gZ2VuZXJhdGVSYW5kb20oYml0cywgcm5nKSB7CiAgdmFyIG51bSA9IG5ldyBCaWdJbnRlZ2VyKGJpdHMsIHJuZyk7CiAgLy8gZm9yY2UgTVNCIHNldAogIHZhciBiaXRzMSA9IGJpdHMgLSAxOwogIGlmKCFudW0udGVzdEJpdChiaXRzMSkpIHsKICAgIG51bS5iaXR3aXNlVG8oQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGJpdHMxKSwgb3Bfb3IsIG51bSk7CiAgfQogIC8vIGFsaWduIG51bWJlciBvbiAzMGsrMSBib3VuZGFyeQogIG51bS5kQWRkT2Zmc2V0KDMxIC0gbnVtLm1vZChUSElSVFkpLmJ5dGVWYWx1ZSgpLCAwKTsKICByZXR1cm4gbnVtOwp9CgovKioKICogUmV0dXJucyB0aGUgcmVxdWlyZWQgbnVtYmVyIG9mIE1pbGxlci1SYWJpbiB0ZXN0cyB0byBnZW5lcmF0ZSBhCiAqIHByaW1lIHdpdGggYW4gZXJyb3IgcHJvYmFiaWxpdHkgb2YgKDEvMileODAuCiAqCiAqIFNlZSBIYW5kYm9vayBvZiBBcHBsaWVkIENyeXB0b2dyYXBoeSBDaGFwdGVyIDQsIFRhYmxlIDQuNC4KICoKICogQHBhcmFtIGJpdHMgdGhlIGJpdCBzaXplLgogKgogKiBAcmV0dXJuIHRoZSByZXF1aXJlZCBudW1iZXIgb2YgaXRlcmF0aW9ucy4KICovCmZ1bmN0aW9uIGdldE1pbGxlclJhYmluVGVzdHMoYml0cykgewogIGlmKGJpdHMgPD0gMTAwKSByZXR1cm4gMjc7CiAgaWYoYml0cyA8PSAxNTApIHJldHVybiAxODsKICBpZihiaXRzIDw9IDIwMCkgcmV0dXJuIDE1OwogIGlmKGJpdHMgPD0gMjUwKSByZXR1cm4gMTI7CiAgaWYoYml0cyA8PSAzMDApIHJldHVybiA5OwogIGlmKGJpdHMgPD0gMzUwKSByZXR1cm4gODsKICBpZihiaXRzIDw9IDQwMCkgcmV0dXJuIDc7CiAgaWYoYml0cyA8PSA1MDApIHJldHVybiA2OwogIGlmKGJpdHMgPD0gNjAwKSByZXR1cm4gNTsKICBpZihiaXRzIDw9IDgwMCkgcmV0dXJuIDQ7CiAgaWYoYml0cyA8PSAxMjUwKSByZXR1cm4gMzsKICByZXR1cm4gMjsKfQoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncHJpbWUnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvcHJpbWUnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJywgJy4vanNibicsICcuL3JhbmRvbSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKCn0pKCk7CgovKioKICogSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBiYXNpYyBSU0EgYWxnb3JpdGhtcy4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICoKICogVGhlIG9ubHkgYWxnb3JpdGhtIGN1cnJlbnRseSBzdXBwb3J0ZWQgZm9yIFBLSSBpcyBSU0EuCiAqCiAqIEFuIFJTQSBrZXkgaXMgb2Z0ZW4gc3RvcmVkIGluIEFTTi4xIERFUiBmb3JtYXQuIFRoZSBTdWJqZWN0UHVibGljS2V5SW5mbwogKiBBU04uMSBzdHJ1Y3R1cmUgaXMgY29tcG9zZWQgb2YgYW4gYWxnb3JpdGhtIG9mIHR5cGUgQWxnb3JpdGhtSWRlbnRpZmllcgogKiBhbmQgYSBzdWJqZWN0UHVibGljS2V5IG9mIHR5cGUgYml0IHN0cmluZy4KICoKICogVGhlIEFsZ29yaXRobUlkZW50aWZpZXIgY29udGFpbnMgYW4gT2JqZWN0IElkZW50aWZpZXIgKE9JRCkgYW5kIHBhcmFtZXRlcnMKICogZm9yIHRoZSBhbGdvcml0aG0sIGlmIGFueS4gSW4gdGhlIGNhc2Ugb2YgUlNBLCB0aGVyZSBhcmVuJ3QgYW55LgogKgogKiBTdWJqZWN0UHVibGljS2V5SW5mbyA6Oj0gU0VRVUVOQ0UgewogKiAgIGFsZ29yaXRobSBBbGdvcml0aG1JZGVudGlmaWVyLAogKiAgIHN1YmplY3RQdWJsaWNLZXkgQklUIFNUUklORwogKiB9CiAqCiAqIEFsZ29yaXRobUlkZW50aWZlciA6Oj0gU0VRVUVOQ0UgewogKiAgIGFsZ29yaXRobSBPQkpFQ1QgSURFTlRJRklFUiwKICogICBwYXJhbWV0ZXJzIEFOWSBERUZJTkVEIEJZIGFsZ29yaXRobSBPUFRJT05BTAogKiB9CiAqCiAqIEZvciBhbiBSU0EgcHVibGljIGtleSwgdGhlIHN1YmplY3RQdWJsaWNLZXkgaXM6CiAqCiAqIFJTQVB1YmxpY0tleSA6Oj0gU0VRVUVOQ0UgewogKiAgIG1vZHVsdXMgICAgICAgICAgICBJTlRFR0VSLCAgICAtLSBuCiAqICAgcHVibGljRXhwb25lbnQgICAgIElOVEVHRVIgICAgIC0tIGUKICogfQogKgogKiBQcml2YXRlS2V5SW5mbyA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gICAgICAgICAgICAgICAgICAgVmVyc2lvbiwKICogICBwcml2YXRlS2V5QWxnb3JpdGhtICAgICAgIFByaXZhdGVLZXlBbGdvcml0aG1JZGVudGlmaWVyLAogKiAgIHByaXZhdGVLZXkgICAgICAgICAgICAgICAgUHJpdmF0ZUtleSwKICogICBhdHRyaWJ1dGVzICAgICAgICAgICBbMF0gIElNUExJQ0lUIEF0dHJpYnV0ZXMgT1BUSU9OQUwKICogfQogKgogKiBWZXJzaW9uIDo6PSBJTlRFR0VSCiAqIFByaXZhdGVLZXlBbGdvcml0aG1JZGVudGlmaWVyIDo6PSBBbGdvcml0aG1JZGVudGlmaWVyCiAqIFByaXZhdGVLZXkgOjo9IE9DVEVUIFNUUklORwogKiBBdHRyaWJ1dGVzIDo6PSBTRVQgT0YgQXR0cmlidXRlCiAqCiAqIEFuIFJTQSBwcml2YXRlIGtleSBhcyB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZToKICoKICogUlNBUHJpdmF0ZUtleSA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gVmVyc2lvbiwKICogICBtb2R1bHVzIElOVEVHRVIsIC0tIG4KICogICBwdWJsaWNFeHBvbmVudCBJTlRFR0VSLCAtLSBlCiAqICAgcHJpdmF0ZUV4cG9uZW50IElOVEVHRVIsIC0tIGQKICogICBwcmltZTEgSU5URUdFUiwgLS0gcAogKiAgIHByaW1lMiBJTlRFR0VSLCAtLSBxCiAqICAgZXhwb25lbnQxIElOVEVHRVIsIC0tIGQgbW9kIChwLTEpCiAqICAgZXhwb25lbnQyIElOVEVHRVIsIC0tIGQgbW9kIChxLTEpCiAqICAgY29lZmZpY2llbnQgSU5URUdFUiAtLSAoaW52ZXJzZSBvZiBxKSBtb2QgcAogKiB9CiAqCiAqIFZlcnNpb24gOjo9IElOVEVHRVIKICoKICogVGhlIE9JRCBmb3IgdGhlIFJTQSBrZXkgYWxnb3JpdGhtIGlzOiAxLjIuODQwLjExMzU0OS4xLjEuMQogKi8KKGZ1bmN0aW9uKCkgewpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KCmlmKHR5cGVvZiBCaWdJbnRlZ2VyID09PSAndW5kZWZpbmVkJykgewogIHZhciBCaWdJbnRlZ2VyID0gZm9yZ2UuanNibi5CaWdJbnRlZ2VyOwp9CgovLyBzaG9ydGN1dCBmb3IgYXNuLjEgQVBJCnZhciBhc24xID0gZm9yZ2UuYXNuMTsKCi8qCiAqIFJTQSBlbmNyeXB0aW9uIGFuZCBkZWNyeXB0aW9uLCBzZWUgUkZDIDIzMTMuCiAqLwpmb3JnZS5wa2kgPSBmb3JnZS5wa2kgfHwge307CmZvcmdlLnBraS5yc2EgPSBmb3JnZS5yc2EgPSBmb3JnZS5yc2EgfHwge307CnZhciBwa2kgPSBmb3JnZS5wa2k7CgovLyBmb3IgZmluZGluZyBwcmltZXMsIHdoaWNoIGFyZSAzMGsraSBmb3IgaSA9IDEsIDcsIDExLCAxMywgMTcsIDE5LCAyMywgMjkKdmFyIEdDRF8zMF9ERUxUQSA9IFs2LCA0LCAyLCA0LCAyLCA0LCA2LCAyXTsKCi8vIHZhbGlkYXRvciBmb3IgYSBQcml2YXRlS2V5SW5mbyBzdHJ1Y3R1cmUKdmFyIHByaXZhdGVLZXlWYWxpZGF0b3IgPSB7CiAgLy8gUHJpdmF0ZUtleUluZm8KICBuYW1lOiAnUHJpdmF0ZUtleUluZm8nLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICAvLyBWZXJzaW9uIChJTlRFR0VSKQogICAgbmFtZTogJ1ByaXZhdGVLZXlJbmZvLnZlcnNpb24nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHJpdmF0ZUtleVZlcnNpb24nCiAgfSwgewogICAgLy8gcHJpdmF0ZUtleUFsZ29yaXRobQogICAgbmFtZTogJ1ByaXZhdGVLZXlJbmZvLnByaXZhdGVLZXlBbGdvcml0aG0nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICB2YWx1ZTogW3sKICAgICAgbmFtZTogJ0FsZ29yaXRobUlkZW50aWZpZXIuYWxnb3JpdGhtJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdwcml2YXRlS2V5T2lkJwogICAgfV0KICB9LCB7CiAgICAvLyBQcml2YXRlS2V5CiAgICBuYW1lOiAnUHJpdmF0ZUtleUluZm8nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ByaXZhdGVLZXknCiAgfV0KfTsKCi8vIHZhbGlkYXRvciBmb3IgYW4gUlNBIHByaXZhdGUga2V5CnZhciByc2FQcml2YXRlS2V5VmFsaWRhdG9yID0gewogIC8vIFJTQVByaXZhdGVLZXkKICBuYW1lOiAnUlNBUHJpdmF0ZUtleScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIC8vIFZlcnNpb24gKElOVEVHRVIpCiAgICBuYW1lOiAnUlNBUHJpdmF0ZUtleS52ZXJzaW9uJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ByaXZhdGVLZXlWZXJzaW9uJwogIH0sIHsKICAgIC8vIG1vZHVsdXMgKG4pCiAgICBuYW1lOiAnUlNBUHJpdmF0ZUtleS5tb2R1bHVzJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ByaXZhdGVLZXlNb2R1bHVzJwogIH0sIHsKICAgIC8vIHB1YmxpY0V4cG9uZW50IChlKQogICAgbmFtZTogJ1JTQVByaXZhdGVLZXkucHVibGljRXhwb25lbnQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHJpdmF0ZUtleVB1YmxpY0V4cG9uZW50JwogIH0sIHsKICAgIC8vIHByaXZhdGVFeHBvbmVudCAoZCkKICAgIG5hbWU6ICdSU0FQcml2YXRlS2V5LnByaXZhdGVFeHBvbmVudCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdwcml2YXRlS2V5UHJpdmF0ZUV4cG9uZW50JwogIH0sIHsKICAgIC8vIHByaW1lMSAocCkKICAgIG5hbWU6ICdSU0FQcml2YXRlS2V5LnByaW1lMScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdwcml2YXRlS2V5UHJpbWUxJwogIH0sIHsKICAgIC8vIHByaW1lMiAocSkKICAgIG5hbWU6ICdSU0FQcml2YXRlS2V5LnByaW1lMicsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdwcml2YXRlS2V5UHJpbWUyJwogIH0sIHsKICAgIC8vIGV4cG9uZW50MSAoZCBtb2QgKHAtMSkpCiAgICBuYW1lOiAnUlNBUHJpdmF0ZUtleS5leHBvbmVudDEnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHJpdmF0ZUtleUV4cG9uZW50MScKICB9LCB7CiAgICAvLyBleHBvbmVudDIgKGQgbW9kIChxLTEpKQogICAgbmFtZTogJ1JTQVByaXZhdGVLZXkuZXhwb25lbnQyJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ByaXZhdGVLZXlFeHBvbmVudDInCiAgfSwgewogICAgLy8gY29lZmZpY2llbnQgKChpbnZlcnNlIG9mIHEpIG1vZCBwKQogICAgbmFtZTogJ1JTQVByaXZhdGVLZXkuY29lZmZpY2llbnQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHJpdmF0ZUtleUNvZWZmaWNpZW50JwogIH1dCn07CgovLyB2YWxpZGF0b3IgZm9yIGFuIFJTQSBwdWJsaWMga2V5CnZhciByc2FQdWJsaWNLZXlWYWxpZGF0b3IgPSB7CiAgLy8gUlNBUHVibGljS2V5CiAgbmFtZTogJ1JTQVB1YmxpY0tleScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIC8vIG1vZHVsdXMgKG4pCiAgICBuYW1lOiAnUlNBUHVibGljS2V5Lm1vZHVsdXMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHVibGljS2V5TW9kdWx1cycKICB9LCB7CiAgICAvLyBwdWJsaWNFeHBvbmVudCAoZSkKICAgIG5hbWU6ICdSU0FQdWJsaWNLZXkuZXhwb25lbnQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHVibGljS2V5RXhwb25lbnQnCiAgfV0KfTsKCi8vIHZhbGlkYXRvciBmb3IgYW4gU3ViamVjdFB1YmxpY0tleUluZm8gc3RydWN0dXJlCi8vIE5vdGU6IEN1cnJlbnRseSBvbmx5IHdvcmtzIHdpdGggYW4gUlNBIHB1YmxpYyBrZXkKdmFyIHB1YmxpY0tleVZhbGlkYXRvciA9IGZvcmdlLnBraS5yc2EucHVibGljS2V5VmFsaWRhdG9yID0gewogIG5hbWU6ICdTdWJqZWN0UHVibGljS2V5SW5mbycsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICBjYXB0dXJlQXNuMTogJ3N1YmplY3RQdWJsaWNLZXlJbmZvJywKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdTdWJqZWN0UHVibGljS2V5SW5mby5BbGdvcml0aG1JZGVudGlmaWVyJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdBbGdvcml0aG1JZGVudGlmaWVyLmFsZ29yaXRobScsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlOiAncHVibGljS2V5T2lkJwogICAgfV0KICB9LCB7CiAgICAvLyBzdWJqZWN0UHVibGljS2V5CiAgICBuYW1lOiAnU3ViamVjdFB1YmxpY0tleUluZm8uc3ViamVjdFB1YmxpY0tleScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuQklUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgdmFsdWU6IFt7CiAgICAgIC8vIFJTQVB1YmxpY0tleQogICAgICBuYW1lOiAnU3ViamVjdFB1YmxpY0tleUluZm8uc3ViamVjdFB1YmxpY0tleS5SU0FQdWJsaWNLZXknLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ3JzYVB1YmxpY0tleScKICAgIH1dCiAgfV0KfTsKCi8qKgogKiBXcmFwIGRpZ2VzdCBpbiBEaWdlc3RJbmZvIG9iamVjdC4KICoKICogVGhpcyBmdW5jdGlvbiBpbXBsZW1lbnRzIEVNU0EtUEtDUzEtdjFfNS1FTkNPREUgYXMgcGVyIFJGQyAzNDQ3LgogKgogKiBEaWdlc3RJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgZGlnZXN0QWxnb3JpdGhtIERpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgZGlnZXN0IERpZ2VzdAogKiB9CiAqCiAqIERpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXIgOjo9IEFsZ29yaXRobUlkZW50aWZpZXIKICogRGlnZXN0IDo6PSBPQ1RFVCBTVFJJTkcKICoKICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3Qgd2l0aCB0aGUgaGFzaCB0byBzaWduLgogKgogKiBAcmV0dXJuIHRoZSBlbmNvZGVkIG1lc3NhZ2UgKHJlYWR5IGZvciBSU0EgZW5jcnl0aW9uKQogKi8KdmFyIGVtc2FQa2NzMXYxNWVuY29kZSA9IGZ1bmN0aW9uKG1kKSB7CiAgLy8gZ2V0IHRoZSBvaWQgZm9yIHRoZSBhbGdvcml0aG0KICB2YXIgb2lkOwogIGlmKG1kLmFsZ29yaXRobSBpbiBwa2kub2lkcykgewogICAgb2lkID0gcGtpLm9pZHNbbWQuYWxnb3JpdGhtXTsKICB9IGVsc2UgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdVbmtub3duIG1lc3NhZ2UgZGlnZXN0IGFsZ29yaXRobS4nKTsKICAgIGVycm9yLmFsZ29yaXRobSA9IG1kLmFsZ29yaXRobTsKICAgIHRocm93IGVycm9yOwogIH0KICB2YXIgb2lkQnl0ZXMgPSBhc24xLm9pZFRvRGVyKG9pZCkuZ2V0Qnl0ZXMoKTsKCiAgLy8gY3JlYXRlIHRoZSBkaWdlc3QgaW5mbwogIHZhciBkaWdlc3RJbmZvID0gYXNuMS5jcmVhdGUoCiAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbXSk7CiAgdmFyIGRpZ2VzdEFsZ29yaXRobSA9IGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgW10pOwogIGRpZ2VzdEFsZ29yaXRobS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLCBvaWRCeXRlcykpOwogIGRpZ2VzdEFsZ29yaXRobS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5OVUxMLCBmYWxzZSwgJycpKTsKICB2YXIgZGlnZXN0ID0gYXNuMS5jcmVhdGUoCiAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgZmFsc2UsIG1kLmRpZ2VzdCgpLmdldEJ5dGVzKCkpOwogIGRpZ2VzdEluZm8udmFsdWUucHVzaChkaWdlc3RBbGdvcml0aG0pOwogIGRpZ2VzdEluZm8udmFsdWUucHVzaChkaWdlc3QpOwoKICAvLyBlbmNvZGUgZGlnZXN0IGluZm8KICByZXR1cm4gYXNuMS50b0RlcihkaWdlc3RJbmZvKS5nZXRCeXRlcygpOwp9OwoKLyoqCiAqIFBlcmZvcm1zIHheYyBtb2QgbiAoUlNBIGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbiBvcGVyYXRpb24pLgogKgogKiBAcGFyYW0geCB0aGUgbnVtYmVyIHRvIHJhaXNlIGFuZCBtb2QuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSB0byB1c2UuCiAqIEBwYXJhbSBwdWIgdHJ1ZSBpZiB0aGUga2V5IGlzIHB1YmxpYywgZmFsc2UgaWYgcHJpdmF0ZS4KICoKICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHheYyBtb2Qgbi4KICovCnZhciBfbW9kUG93ID0gZnVuY3Rpb24oeCwga2V5LCBwdWIpIHsKICBpZihwdWIpIHsKICAgIHJldHVybiB4Lm1vZFBvdyhrZXkuZSwga2V5Lm4pOwogIH0KCiAgaWYoIWtleS5wIHx8ICFrZXkucSkgewogICAgLy8gYWxsb3cgY2FsY3VsYXRpb24gd2l0aG91dCBDUlQgcGFyYW1zIChzbG93KQogICAgcmV0dXJuIHgubW9kUG93KGtleS5kLCBrZXkubik7CiAgfQoKICAvLyBwcmUtY29tcHV0ZSBkUCwgZFEsIGFuZCBxSW52IGlmIG5lY2Vzc2FyeQogIGlmKCFrZXkuZFApIHsKICAgIGtleS5kUCA9IGtleS5kLm1vZChrZXkucC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkpOwogIH0KICBpZigha2V5LmRRKSB7CiAgICBrZXkuZFEgPSBrZXkuZC5tb2Qoa2V5LnEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKTsKICB9CiAgaWYoIWtleS5xSW52KSB7CiAgICBrZXkucUludiA9IGtleS5xLm1vZEludmVyc2Uoa2V5LnApOwogIH0KCiAgLyogQ2hpbmVzZSByZW1haW5kZXIgdGhlb3JlbSAoQ1JUKSBzdGF0ZXM6CgogICAgU3VwcG9zZSBuMSwgbjIsIC4uLiwgbmsgYXJlIHBvc2l0aXZlIGludGVnZXJzIHdoaWNoIGFyZSBwYWlyd2lzZQogICAgY29wcmltZSAobjEgYW5kIG4yIGhhdmUgbm8gY29tbW9uIGZhY3RvcnMgb3RoZXIgdGhhbiAxKS4gRm9yIGFueQogICAgaW50ZWdlcnMgeDEsIHgyLCAuLi4sIHhrIHRoZXJlIGV4aXN0cyBhbiBpbnRlZ2VyIHggc29sdmluZyB0aGUKICAgIHN5c3RlbSBvZiBzaW11bHRhbmVvdXMgY29uZ3J1ZW5jZXMgKHdoZXJlIH49IG1lYW5zIG1vZHVsYXJseQogICAgY29uZ3J1ZW50IHNvIGEgfj0gYiBtb2QgbiBtZWFucyBhIG1vZCBuID0gYiBtb2Qgbik6CgogICAgeCB+PSB4MSBtb2QgbjEKICAgIHggfj0geDIgbW9kIG4yCiAgICAuLi4KICAgIHggfj0geGsgbW9kIG5rCgogICAgVGhpcyBzeXN0ZW0gb2YgY29uZ3J1ZW5jZXMgaGFzIGEgc2luZ2xlIHNpbXVsdGFuZW91cyBzb2x1dGlvbiB4CiAgICBiZXR3ZWVuIDAgYW5kIG4gLSAxLiBGdXJ0aGVybW9yZSwgZWFjaCB4ayBzb2x1dGlvbiBhbmQgeCBpdHNlbGYKICAgIGlzIGNvbmdydWVudCBtb2R1bG8gdGhlIHByb2R1Y3QgbiA9IG4xKm4yKi4uLipuay4KICAgIFNvIHgxIG1vZCBuID0geDIgbW9kIG4gPSB4ayBtb2QgbiA9IHggbW9kIG4uCgogICAgVGhlIHNpbmdsZSBzaW11bHRhbmVvdXMgc29sdXRpb24geCBjYW4gYmUgc29sdmVkIHdpdGggdGhlIGZvbGxvd2luZwogICAgZXF1YXRpb246CgogICAgeCA9IHN1bSh4aSpyaSpzaSkgbW9kIG4gd2hlcmUgcmkgPSBuL25pIGFuZCBzaSA9IHJpXi0xIG1vZCBuaS4KCiAgICBXaGVyZSB4IGlzIGxlc3MgdGhhbiBuLCB4aSA9IHggbW9kIG5pLgoKICAgIEZvciBSU0Egd2UgYXJlIG9ubHkgY29uY2VybmVkIHdpdGggayA9IDIuIFRoZSBtb2R1bHVzIG4gPSBwcSwgd2hlcmUKICAgIHAgYW5kIHEgYXJlIGNvcHJpbWUuIFRoZSBSU0EgZGVjcnlwdGlvbiBhbGdvcml0aG0gaXM6CgogICAgeSA9IHheZCBtb2QgbgoKICAgIEdpdmVuIHRoZSBhYm92ZToKCiAgICB4MSA9IHheZCBtb2QgcAogICAgcjEgPSBuL3AgPSBxCiAgICBzMSA9IHFeLTEgbW9kIHAKICAgIHgyID0geF5kIG1vZCBxCiAgICByMiA9IG4vcSA9IHAKICAgIHMyID0gcF4tMSBtb2QgcQoKICAgIFNvIHkgPSAoeDFyMXMxICsgeDJyMnMyKSBtb2QgbgogICAgICAgICA9ICgoeF5kIG1vZCBwKXEocV4tMSBtb2QgcCkgKyAoeF5kIG1vZCBxKXAocF4tMSBtb2QgcSkpIG1vZCBuCgogICAgQWNjb3JkaW5nIHRvIEZlcm1hdCdzIExpdHRsZSBUaGVvcmVtLCBpZiB0aGUgbW9kdWx1cyBQIGlzIHByaW1lLAogICAgZm9yIGFueSBpbnRlZ2VyIEEgbm90IGV2ZW5seSBkaXZpc2libGUgYnkgUCwgQV4oUC0xKSB+PSAxIG1vZCBQLgogICAgU2luY2UgQSBpcyBub3QgZGl2aXNpYmxlIGJ5IFAgaXQgZm9sbG93cyB0aGF0IGlmOgogICAgTiB+PSBNIG1vZCAoUCAtIDEpLCB0aGVuIEFeTiBtb2QgUCA9IEFeTSBtb2QgUC4gVGhlcmVmb3JlOgoKICAgIEFeTiBtb2QgUCA9IEFeKE0gbW9kIChQIC0gMSkpIG1vZCBQLiAoVGhlIGxhdHRlciB0YWtlcyBsZXNzIGVmZm9ydAogICAgdG8gY2FsY3VsYXRlKS4gSW4gb3JkZXIgdG8gY2FsY3VsYXRlIHheZCBtb2QgcCBtb3JlIHF1aWNrbHkgdGhlCiAgICBleHBvbmVudCBkIG1vZCAocCAtIDEpIGlzIHN0b3JlZCBpbiB0aGUgUlNBIHByaXZhdGUga2V5ICh0aGUgc2FtZQogICAgaXMgZG9uZSBmb3IgeF5kIG1vZCBxKS4gVGhlc2UgdmFsdWVzIGFyZSByZWZlcnJlZCB0byBhcyBkUCBhbmQgZFEKICAgIHJlc3BlY3RpdmVseS4gVGhlcmVmb3JlIHdlIG5vdyBoYXZlOgoKICAgIHkgPSAoKHheZFAgbW9kIHApcShxXi0xIG1vZCBwKSArICh4XmRRIG1vZCBxKXAocF4tMSBtb2QgcSkpIG1vZCBuCgogICAgU2luY2Ugd2UnbGwgYmUgcmVkdWNpbmcgeF5kUCBieSBtb2R1bG8gcCAoc2FtZSBmb3IgcSkgd2UgY2FuIGFsc28KICAgIHJlZHVjZSB4IGJ5IHAgKGFuZCBxIHJlc3BlY3RpdmVseSkgYmVmb3JlIGhhbmQuIFRoZXJlZm9yZSwgbGV0CgogICAgeHAgPSAoKHggbW9kIHApXmRQIG1vZCBwKSwgYW5kCiAgICB4cSA9ICgoeCBtb2QgcSleZFEgbW9kIHEpLCB5aWVsZGluZzoKCiAgICB5ID0gKHhwKnEqKHFeLTEgbW9kIHApICsgeHEqcCoocF4tMSBtb2QgcSkpIG1vZCBuCgogICAgVGhpcyBjYW4gYmUgZnVydGhlciByZWR1Y2VkIHRvIGEgc2ltcGxlIGFsZ29yaXRobSB0aGF0IG9ubHkKICAgIHJlcXVpcmVzIDEgaW52ZXJzZSAodGhlIHEgaW52ZXJzZSBpcyB1c2VkKSB0byBiZSB1c2VkIGFuZCBzdG9yZWQuCiAgICBUaGUgYWxnb3JpdGhtIGlzIGNhbGxlZCBHYXJuZXIncyBhbGdvcml0aG0uIElmIHFJbnYgaXMgdGhlCiAgICBpbnZlcnNlIG9mIHEsIHdlIHNpbXBseSBjYWxjdWxhdGU6CgogICAgeSA9IChxSW52Kih4cCAtIHhxKSBtb2QgcCkgKiBxICsgeHEKCiAgICBIb3dldmVyLCB0aGVyZSBhcmUgdHdvIGZ1cnRoZXIgY29tcGxpY2F0aW9ucy4gRmlyc3QsIHdlIG5lZWQgdG8KICAgIGVuc3VyZSB0aGF0IHhwID4geHEgdG8gcHJldmVudCBzaWduZWQgQmlnSW50ZWdlcnMgZnJvbSBiZWluZyB1c2VkCiAgICBzbyB3ZSBhZGQgcCB1bnRpbCB0aGlzIGlzIHRydWUgKHNpbmNlIHdlIHdpbGwgYmUgbW9kJ2luZyB3aXRoCiAgICBwIGFueXdheSkuIFRoZW4sIHRoZXJlIGlzIGEga25vd24gdGltaW5nIGF0dGFjayBvbiBhbGdvcml0aG1zCiAgICB1c2luZyB0aGUgQ1JULiBUbyBtaXRpZ2F0ZSB0aGlzIHJpc2ssICJjcnlwdG9ncmFwaGljIGJsaW5kaW5nIgogICAgc2hvdWxkIGJlIHVzZWQuIFRoaXMgcmVxdWlyZXMgc2ltcGx5IGdlbmVyYXRpbmcgYSByYW5kb20gbnVtYmVyIHIKICAgIGJldHdlZW4gMCBhbmQgbi0xIGFuZCBpdHMgaW52ZXJzZSBhbmQgbXVsdGlwbHlpbmcgeCBieSByXmUgYmVmb3JlCiAgICBjYWxjdWxhdGluZyB5IGFuZCB0aGVuIG11bHRpcGx5aW5nIHkgYnkgcl4tMSBhZnRlcndhcmRzLiBOb3RlIHRoYXQKICAgIHIgbXVzdCBiZSBjb3ByaW1lIHdpdGggbiAoZ2NkKHIsIG4pID09PSAxKSBpbiBvcmRlciB0byBoYXZlIGFuCiAgICBpbnZlcnNlLgogICovCgogIC8vIGNyeXB0b2dyYXBoaWMgYmxpbmRpbmcKICB2YXIgcjsKICBkbyB7CiAgICByID0gbmV3IEJpZ0ludGVnZXIoCiAgICAgIGZvcmdlLnV0aWwuYnl0ZXNUb0hleChmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMoa2V5Lm4uYml0TGVuZ3RoKCkgLyA4KSksCiAgICAgIDE2KTsKICB9IHdoaWxlKHIuY29tcGFyZVRvKGtleS5uKSA+PSAwIHx8ICFyLmdjZChrZXkubikuZXF1YWxzKEJpZ0ludGVnZXIuT05FKSk7CiAgeCA9IHgubXVsdGlwbHkoci5tb2RQb3coa2V5LmUsIGtleS5uKSkubW9kKGtleS5uKTsKCiAgLy8gY2FsY3VsYXRlIHhwIGFuZCB4cQogIHZhciB4cCA9IHgubW9kKGtleS5wKS5tb2RQb3coa2V5LmRQLCBrZXkucCk7CiAgdmFyIHhxID0geC5tb2Qoa2V5LnEpLm1vZFBvdyhrZXkuZFEsIGtleS5xKTsKCiAgLy8geHAgbXVzdCBiZSBsYXJnZXIgdGhhbiB4cSB0byBhdm9pZCBzaWduZWQgYml0IHVzYWdlCiAgd2hpbGUoeHAuY29tcGFyZVRvKHhxKSA8IDApIHsKICAgIHhwID0geHAuYWRkKGtleS5wKTsKICB9CgogIC8vIGRvIGxhc3Qgc3RlcAogIHZhciB5ID0geHAuc3VidHJhY3QoeHEpCiAgICAubXVsdGlwbHkoa2V5LnFJbnYpLm1vZChrZXkucCkKICAgIC5tdWx0aXBseShrZXkucSkuYWRkKHhxKTsKCiAgLy8gcmVtb3ZlIGVmZmVjdCBvZiByYW5kb20gZm9yIGNyeXB0b2dyYXBoaWMgYmxpbmRpbmcKICB5ID0geS5tdWx0aXBseShyLm1vZEludmVyc2Uoa2V5Lm4pKS5tb2Qoa2V5Lm4pOwoKICByZXR1cm4geTsKfTsKCi8qKgogKiBOT1RFOiBUSElTIE1FVEhPRCBJUyBERVBSRUNBVEVELCB1c2UgJ3NpZ24nIG9uIGEgcHJpdmF0ZSBrZXkgb2JqZWN0IG9yCiAqICdlbmNyeXB0JyBvbiBhIHB1YmxpYyBrZXkgb2JqZWN0IGluc3RlYWQuCiAqCiAqIFBlcmZvcm1zIFJTQSBlbmNyeXB0aW9uLgogKgogKiBUaGUgcGFyYW1ldGVyIGJ0IGNvbnRyb2xzIHdoZXRoZXIgdG8gcHV0IHBhZGRpbmcgYnl0ZXMgYmVmb3JlIHRoZQogKiBtZXNzYWdlIHBhc3NlZCBpbi4gU2V0IGJ0IHRvIGVpdGhlciB0cnVlIG9yIGZhbHNlIHRvIGRpc2FibGUgcGFkZGluZwogKiBjb21wbGV0ZWx5IChpbiBvcmRlciB0byBoYW5kbGUgZS5nLiBFTVNBLVBTUyBlbmNvZGluZyBzZXBlcmF0ZWx5IGJlZm9yZSksCiAqIHNpZ25hbGluZyB3aGV0aGVyIHRoZSBlbmNyeXB0aW9uIG9wZXJhdGlvbiBpcyBhIHB1YmxpYyBrZXkgb3BlcmF0aW9uCiAqIChpLmUuIGVuY3J5cHRpbmcgZGF0YSkgb3Igbm90LCBpLmUuIHByaXZhdGUga2V5IG9wZXJhdGlvbiAoZGF0YSBzaWduaW5nKS4KICoKICogRm9yIFBLQ1MjMSB2MS41IHBhZGRpbmcgcGFzcyBpbiB0aGUgYmxvY2sgdHlwZSB0byB1c2UsIGkuZS4gZWl0aGVyIDB4MDEKICogKGZvciBzaWduaW5nKSBvciAweDAyIChmb3IgZW5jcnlwdGlvbikuIFRoZSBrZXkgb3BlcmF0aW9uIG1vZGUgKHByaXZhdGUKICogb3IgcHVibGljKSBpcyBkZXJpdmVkIGZyb20gdGhpcyBmbGFnIGluIHRoYXQgY2FzZSkuCiAqCiAqIEBwYXJhbSBtIHRoZSBtZXNzYWdlIHRvIGVuY3J5cHQgYXMgYSBieXRlIHN0cmluZy4KICogQHBhcmFtIGtleSB0aGUgUlNBIGtleSB0byB1c2UuCiAqIEBwYXJhbSBidCBmb3IgUEtDUyMxIHYxLjUgcGFkZGluZywgdGhlIGJsb2NrIHR5cGUgdG8gdXNlCiAqICAgKDB4MDEgZm9yIHByaXZhdGUga2V5LCAweDAyIGZvciBwdWJsaWMpLAogKiAgIHRvIGRpc2FibGUgcGFkZGluZzogdHJ1ZSA9IHB1YmxpYyBrZXksIGZhbHNlID0gcHJpdmF0ZSBrZXkuCiAqCiAqIEByZXR1cm4gdGhlIGVuY3J5cHRlZCBieXRlcyBhcyBhIHN0cmluZy4KICovCnBraS5yc2EuZW5jcnlwdCA9IGZ1bmN0aW9uKG0sIGtleSwgYnQpIHsKICB2YXIgcHViID0gYnQ7CiAgdmFyIGViOwoKICAvLyBnZXQgdGhlIGxlbmd0aCBvZiB0aGUgbW9kdWx1cyBpbiBieXRlcwogIHZhciBrID0gTWF0aC5jZWlsKGtleS5uLmJpdExlbmd0aCgpIC8gOCk7CgogIGlmKGJ0ICE9PSBmYWxzZSAmJiBidCAhPT0gdHJ1ZSkgewogICAgLy8gbGVnYWN5LCBkZWZhdWx0IHRvIFBLQ1MjMSB2MS41IHBhZGRpbmcKICAgIHB1YiA9IChidCA9PT0gMHgwMik7CiAgICBlYiA9IF9lbmNvZGVQa2NzMV92MV81KG0sIGtleSwgYnQpOwogIH0gZWxzZSB7CiAgICBlYiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBlYi5wdXRCeXRlcyhtKTsKICB9CgogIC8vIGxvYWQgZW5jcnlwdGlvbiBibG9jayBhcyBiaWcgaW50ZWdlciAneCcKICAvLyBGSVhNRTogaGV4IGNvbnZlcnNpb24gaW5lZmZpY2llbnQsIGdldCBCaWdJbnRlZ2VyIHcvYnl0ZSBzdHJpbmdzCiAgdmFyIHggPSBuZXcgQmlnSW50ZWdlcihlYi50b0hleCgpLCAxNik7CgogIC8vIGRvIFJTQSBlbmNyeXB0aW9uCiAgdmFyIHkgPSBfbW9kUG93KHgsIGtleSwgcHViKTsKCiAgLy8gY29udmVydCB5IGludG8gdGhlIGVuY3J5cHRlZCBkYXRhIGJ5dGUgc3RyaW5nLCBpZiB5IGlzIHNob3J0ZXIgaW4KICAvLyBieXRlcyB0aGFuIGssIHRoZW4gcHJlcGVuZCB6ZXJvIGJ5dGVzIHRvIGZpbGwgdXAgZWQKICAvLyBGSVhNRTogaGV4IGNvbnZlcnNpb24gaW5lZmZpY2llbnQsIGdldCBCaWdJbnRlZ2VyIHcvYnl0ZSBzdHJpbmdzCiAgdmFyIHloZXggPSB5LnRvU3RyaW5nKDE2KTsKICB2YXIgZWQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHZhciB6ZXJvcyA9IGsgLSBNYXRoLmNlaWwoeWhleC5sZW5ndGggLyAyKTsKICB3aGlsZSh6ZXJvcyA+IDApIHsKICAgIGVkLnB1dEJ5dGUoMHgwMCk7CiAgICAtLXplcm9zOwogIH0KICBlZC5wdXRCeXRlcyhmb3JnZS51dGlsLmhleFRvQnl0ZXMoeWhleCkpOwogIHJldHVybiBlZC5nZXRCeXRlcygpOwp9OwoKLyoqCiAqIE5PVEU6IFRISVMgTUVUSE9EIElTIERFUFJFQ0FURUQsIHVzZSAnZGVjcnlwdCcgb24gYSBwcml2YXRlIGtleSBvYmplY3Qgb3IKICogJ3ZlcmlmeScgb24gYSBwdWJsaWMga2V5IG9iamVjdCBpbnN0ZWFkLgogKgogKiBQZXJmb3JtcyBSU0EgZGVjcnlwdGlvbi4KICoKICogVGhlIHBhcmFtZXRlciBtbCBjb250cm9scyB3aGV0aGVyIHRvIGFwcGx5IFBLQ1MjMSB2MS41IHBhZGRpbmcKICogb3Igbm90LiAgU2V0IG1sID0gZmFsc2UgdG8gZGlzYWJsZSBwYWRkaW5nIHJlbW92YWwgY29tcGxldGVseQogKiAoaW4gb3JkZXIgdG8gaGFuZGxlIGUuZy4gRU1TQS1QU1MgbGF0ZXIgb24pIGFuZCBzaW1wbHkgcGFzcyBiYWNrCiAqIHRoZSBSU0EgZW5jcnlwdGlvbiBibG9jay4KICoKICogQHBhcmFtIGVkIHRoZSBlbmNyeXB0ZWQgZGF0YSB0byBkZWNyeXB0IGluIGFzIGEgYnl0ZSBzdHJpbmcuCiAqIEBwYXJhbSBrZXkgdGhlIFJTQSBrZXkgdG8gdXNlLgogKiBAcGFyYW0gcHViIHRydWUgZm9yIGEgcHVibGljIGtleSBvcGVyYXRpb24sIGZhbHNlIGZvciBwcml2YXRlLgogKiBAcGFyYW0gbWwgdGhlIG1lc3NhZ2UgbGVuZ3RoLCBpZiBrbm93biwgZmFsc2UgdG8gZGlzYWJsZSBwYWRkaW5nLgogKgogKiBAcmV0dXJuIHRoZSBkZWNyeXB0ZWQgbWVzc2FnZSBhcyBhIGJ5dGUgc3RyaW5nLgogKi8KcGtpLnJzYS5kZWNyeXB0ID0gZnVuY3Rpb24oZWQsIGtleSwgcHViLCBtbCkgewogIC8vIGdldCB0aGUgbGVuZ3RoIG9mIHRoZSBtb2R1bHVzIGluIGJ5dGVzCiAgdmFyIGsgPSBNYXRoLmNlaWwoa2V5Lm4uYml0TGVuZ3RoKCkgLyA4KTsKCiAgLy8gZXJyb3IgaWYgdGhlIGxlbmd0aCBvZiB0aGUgZW5jcnlwdGVkIGRhdGEgRUQgaXMgbm90IGsKICBpZihlZC5sZW5ndGggIT09IGspIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignRW5jcnlwdGVkIG1lc3NhZ2UgbGVuZ3RoIGlzIGludmFsaWQuJyk7CiAgICBlcnJvci5sZW5ndGggPSBlZC5sZW5ndGg7CiAgICBlcnJvci5leHBlY3RlZCA9IGs7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIC8vIGNvbnZlcnQgZW5jcnlwdGVkIGRhdGEgaW50byBhIGJpZyBpbnRlZ2VyCiAgLy8gRklYTUU6IGhleCBjb252ZXJzaW9uIGluZWZmaWNpZW50LCBnZXQgQmlnSW50ZWdlciB3L2J5dGUgc3RyaW5ncwogIHZhciB5ID0gbmV3IEJpZ0ludGVnZXIoZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoZWQpLnRvSGV4KCksIDE2KTsKCiAgLy8geSBtdXN0IGJlIGxlc3MgdGhhbiB0aGUgbW9kdWx1cyBvciBpdCB3YXNuJ3QgdGhlIHJlc3VsdCBvZgogIC8vIGEgcHJldmlvdXMgbW9kIG9wZXJhdGlvbiAoZW5jcnlwdGlvbikgdXNpbmcgdGhhdCBtb2R1bHVzCiAgaWYoeS5jb21wYXJlVG8oa2V5Lm4pID49IDApIHsKICAgIHRocm93IG5ldyBFcnJvcignRW5jcnlwdGVkIG1lc3NhZ2UgaXMgaW52YWxpZC4nKTsKICB9CgogIC8vIGRvIFJTQSBkZWNyeXB0aW9uCiAgdmFyIHggPSBfbW9kUG93KHksIGtleSwgcHViKTsKCiAgLy8gY3JlYXRlIHRoZSBlbmNyeXB0aW9uIGJsb2NrLCBpZiB4IGlzIHNob3J0ZXIgaW4gYnl0ZXMgdGhhbiBrLCB0aGVuCiAgLy8gcHJlcGVuZCB6ZXJvIGJ5dGVzIHRvIGZpbGwgdXAgZWIKICAvLyBGSVhNRTogaGV4IGNvbnZlcnNpb24gaW5lZmZpY2llbnQsIGdldCBCaWdJbnRlZ2VyIHcvYnl0ZSBzdHJpbmdzCiAgdmFyIHhoZXggPSB4LnRvU3RyaW5nKDE2KTsKICB2YXIgZWIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHZhciB6ZXJvcyA9IGsgLSBNYXRoLmNlaWwoeGhleC5sZW5ndGggLyAyKTsKICB3aGlsZSh6ZXJvcyA+IDApIHsKICAgIGViLnB1dEJ5dGUoMHgwMCk7CiAgICAtLXplcm9zOwogIH0KICBlYi5wdXRCeXRlcyhmb3JnZS51dGlsLmhleFRvQnl0ZXMoeGhleCkpOwoKICBpZihtbCAhPT0gZmFsc2UpIHsKICAgIC8vIGxlZ2FjeSwgZGVmYXVsdCB0byBQS0NTIzEgdjEuNSBwYWRkaW5nCiAgICByZXR1cm4gX2RlY29kZVBrY3MxX3YxXzUoZWIuZ2V0Qnl0ZXMoKSwga2V5LCBwdWIpOwogIH0KCiAgLy8gcmV0dXJuIG1lc3NhZ2UKICByZXR1cm4gZWIuZ2V0Qnl0ZXMoKTsKfTsKCi8qKgogKiBDcmVhdGVzIGFuIFJTQSBrZXktcGFpciBnZW5lcmF0aW9uIHN0YXRlIG9iamVjdC4gSXQgaXMgdXNlZCB0byBhbGxvdwogKiBrZXktZ2VuZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgaW4gc3RlcHMuIEl0IGFsc28gYWxsb3dzIGZvciBhIFVJIHRvCiAqIGRpc3BsYXkgcHJvZ3Jlc3MgdXBkYXRlcy4KICoKICogQHBhcmFtIGJpdHMgdGhlIHNpemUgZm9yIHRoZSBwcml2YXRlIGtleSBpbiBiaXRzLCBkZWZhdWx0cyB0byAyMDQ4LgogKiBAcGFyYW0gZSB0aGUgcHVibGljIGV4cG9uZW50IHRvIHVzZSwgZGVmYXVsdHMgdG8gNjU1MzcgKDB4MTAwMDEpLgogKiBAcGFyYW0gW29wdGlvbnNdIHRoZSBvcHRpb25zIHRvIHVzZS4KICogICAgICAgICAgcHJuZyBhIGN1c3RvbSBjcnlwdG8tc2VjdXJlIHBzZXVkby1yYW5kb20gbnVtYmVyIGdlbmVyYXRvciB0byB1c2UsCiAqICAgICAgICAgICAgdGhhdCBtdXN0IGRlZmluZSAiZ2V0Qnl0ZXNTeW5jIi4KICogICAgICAgICAgYWxnb3JpdGhtIHRoZSBhbGdvcml0aG0gdG8gdXNlIChkZWZhdWx0OiAnUFJJTUVJTkMnKS4KICoKICogQHJldHVybiB0aGUgc3RhdGUgb2JqZWN0IHRvIHVzZSB0byBnZW5lcmF0ZSB0aGUga2V5LXBhaXIuCiAqLwpwa2kucnNhLmNyZWF0ZUtleVBhaXJHZW5lcmF0aW9uU3RhdGUgPSBmdW5jdGlvbihiaXRzLCBlLCBvcHRpb25zKSB7CiAgLy8gVE9ETzogbWlncmF0ZSBzdGVwLWJhc2VkIHByaW1lIGdlbmVyYXRpb24gY29kZSB0byBmb3JnZS5wcmltZQoKICAvLyBzZXQgZGVmYXVsdCBiaXRzCiAgaWYodHlwZW9mKGJpdHMpID09PSAnc3RyaW5nJykgewogICAgYml0cyA9IHBhcnNlSW50KGJpdHMsIDEwKTsKICB9CiAgYml0cyA9IGJpdHMgfHwgMjA0ODsKCiAgLy8gY3JlYXRlIHBybmcgd2l0aCBhcGkgdGhhdCBtYXRjaGVzIEJpZ0ludGVnZXIgc2VjdXJlIHJhbmRvbQogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHZhciBwcm5nID0gb3B0aW9ucy5wcm5nIHx8IGZvcmdlLnJhbmRvbTsKICB2YXIgcm5nID0gewogICAgLy8geCBpcyBhbiBhcnJheSB0byBmaWxsIHdpdGggYnl0ZXMKICAgIG5leHRCeXRlczogZnVuY3Rpb24oeCkgewogICAgICB2YXIgYiA9IHBybmcuZ2V0Qnl0ZXNTeW5jKHgubGVuZ3RoKTsKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyArK2kpIHsKICAgICAgICB4W2ldID0gYi5jaGFyQ29kZUF0KGkpOwogICAgICB9CiAgICB9CiAgfTsKCiAgdmFyIGFsZ29yaXRobSA9IG9wdGlvbnMuYWxnb3JpdGhtIHx8ICdQUklNRUlOQyc7CgogIC8vIGNyZWF0ZSBQUklNRUlOQyBhbGdvcml0aG0gc3RhdGUKICB2YXIgcnZhbDsKICBpZihhbGdvcml0aG0gPT09ICdQUklNRUlOQycpIHsKICAgIHJ2YWwgPSB7CiAgICAgIGFsZ29yaXRobTogYWxnb3JpdGhtLAogICAgICBzdGF0ZTogMCwKICAgICAgYml0czogYml0cywKICAgICAgcm5nOiBybmcsCiAgICAgIGVJbnQ6IGUgfHwgNjU1MzcsCiAgICAgIGU6IG5ldyBCaWdJbnRlZ2VyKG51bGwpLAogICAgICBwOiBudWxsLAogICAgICBxOiBudWxsLAogICAgICBxQml0czogYml0cyA+PiAxLAogICAgICBwQml0czogYml0cyAtIChiaXRzID4+IDEpLAogICAgICBwcVN0YXRlOiAwLAogICAgICBudW06IG51bGwsCiAgICAgIGtleXM6IG51bGwKICAgIH07CiAgICBydmFsLmUuZnJvbUludChydmFsLmVJbnQpOwogIH0gZWxzZSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQga2V5IGdlbmVyYXRpb24gYWxnb3JpdGhtOiAnICsgYWxnb3JpdGhtKTsKICB9CgogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEF0dGVtcHRzIHRvIHJ1bnMgdGhlIGtleS1nZW5lcmF0aW9uIGFsZ29yaXRobSBmb3IgYXQgbW9zdCBuIHNlY29uZHMKICogKGFwcHJveGltYXRlbHkpIHVzaW5nIHRoZSBnaXZlbiBzdGF0ZS4gV2hlbiBrZXktZ2VuZXJhdGlvbiBoYXMgY29tcGxldGVkLAogKiB0aGUga2V5cyB3aWxsIGJlIHN0b3JlZCBpbiBzdGF0ZS5rZXlzLgogKgogKiBUbyB1c2UgdGhpcyBmdW5jdGlvbiB0byB1cGRhdGUgYSBVSSB3aGlsZSBnZW5lcmF0aW5nIGEga2V5IG9yIHRvIHByZXZlbnQKICogY2F1c2luZyBicm93c2VyIGxvY2t1cHMvd2FybmluZ3MsIHNldCAibiIgdG8gYSB2YWx1ZSBvdGhlciB0aGFuIDAuIEEKICogc2ltcGxlIHBhdHRlcm4gZm9yIGdlbmVyYXRpbmcgYSBrZXkgYW5kIHNob3dpbmcgYSBwcm9ncmVzcyBpbmRpY2F0b3IgaXM6CiAqCiAqIHZhciBzdGF0ZSA9IHBraS5yc2EuY3JlYXRlS2V5UGFpckdlbmVyYXRpb25TdGF0ZSgyMDQ4KTsKICogdmFyIHN0ZXAgPSBmdW5jdGlvbigpIHsKICogICAvLyBzdGVwIGtleS1nZW5lcmF0aW9uLCBydW4gYWxnb3JpdGhtIGZvciAxMDAgbXMsIHJlcGVhdAogKiAgIGlmKCFmb3JnZS5wa2kucnNhLnN0ZXBLZXlQYWlyR2VuZXJhdGlvblN0YXRlKHN0YXRlLCAxMDApKSB7CiAqICAgICBzZXRUaW1lb3V0KHN0ZXAsIDEpOwogKiAgIH0gZWxzZSB7CiAqICAgICAvLyBrZXktZ2VuZXJhdGlvbiBjb21wbGV0ZQogKiAgICAgLy8gVE9ETzogdHVybiBvZmYgcHJvZ3Jlc3MgaW5kaWNhdG9yIGhlcmUKICogICAgIC8vIFRPRE86IHVzZSB0aGUgZ2VuZXJhdGVkIGtleS1wYWlyIGluICJzdGF0ZS5rZXlzIgogKiAgIH0KICogfTsKICogLy8gVE9ETzogdHVybiBvbiBwcm9ncmVzcyBpbmRpY2F0b3IgaGVyZQogKiBzZXRUaW1lb3V0KHN0ZXAsIDApOwogKgogKiBAcGFyYW0gc3RhdGUgdGhlIHN0YXRlIHRvIHVzZS4KICogQHBhcmFtIG4gdGhlIG1heGltdW0gbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBydW4gdGhlIGFsZ29yaXRobSBmb3IsIDAKICogICAgICAgICAgdG8gcnVuIHRoZSBhbGdvcml0aG0gdG8gY29tcGxldGlvbi4KICoKICogQHJldHVybiB0cnVlIGlmIHRoZSBrZXktZ2VuZXJhdGlvbiBjb21wbGV0ZWQsIGZhbHNlIGlmIG5vdC4KICovCnBraS5yc2Euc3RlcEtleVBhaXJHZW5lcmF0aW9uU3RhdGUgPSBmdW5jdGlvbihzdGF0ZSwgbikgewogIC8vIHNldCBkZWZhdWx0IGFsZ29yaXRobSBpZiBub3Qgc2V0CiAgaWYoISgnYWxnb3JpdGhtJyBpbiBzdGF0ZSkpIHsKICAgIHN0YXRlLmFsZ29yaXRobSA9ICdQUklNRUlOQyc7CiAgfQoKICAvLyBUT0RPOiBtaWdyYXRlIHN0ZXAtYmFzZWQgcHJpbWUgZ2VuZXJhdGlvbiBjb2RlIHRvIGZvcmdlLnByaW1lCiAgLy8gVE9ETzogYWJzdHJhY3QgYXMgUFJJTUVJTkMgYWxnb3JpdGhtCgogIC8vIGRvIGtleSBnZW5lcmF0aW9uIChiYXNlZCBvbiBUb20gV3UncyByc2EuanMsIHNlZSBqc2JuLmpzIGxpY2Vuc2UpCiAgLy8gd2l0aCBzb21lIG1pbm9yIG9wdGltaXphdGlvbnMgYW5kIGRlc2lnbmVkIHRvIHJ1biBpbiBzdGVwcwoKICAvLyBsb2NhbCBzdGF0ZSB2YXJzCiAgdmFyIFRISVJUWSA9IG5ldyBCaWdJbnRlZ2VyKG51bGwpOwogIFRISVJUWS5mcm9tSW50KDMwKTsKICB2YXIgZGVsdGFJZHggPSAwOwogIHZhciBvcF9vciA9IGZ1bmN0aW9uKHgseSkgeyByZXR1cm4geHx5OyB9OwoKICAvLyBrZWVwIHN0ZXBwaW5nIHVudGlsIHRpbWUgbGltaXQgaXMgcmVhY2hlZCBvciBkb25lCiAgdmFyIHQxID0gK25ldyBEYXRlKCk7CiAgdmFyIHQyOwogIHZhciB0b3RhbCA9IDA7CiAgd2hpbGUoc3RhdGUua2V5cyA9PT0gbnVsbCAmJiAobiA8PSAwIHx8IHRvdGFsIDwgbikpIHsKICAgIC8vIGdlbmVyYXRlIHAgb3IgcQogICAgaWYoc3RhdGUuc3RhdGUgPT09IDApIHsKICAgICAgLyogTm90ZTogQWxsIHByaW1lcyBhcmUgb2YgdGhlIGZvcm06CgogICAgICAgIDMwaytpLCBmb3IgaSA8IDMwIGFuZCBnY2QoMzAsIGkpPTEsIHdoZXJlIHRoZXJlIGFyZSA4IHZhbHVlcyBmb3IgaQoKICAgICAgICBXaGVuIHdlIGdlbmVyYXRlIGEgcmFuZG9tIG51bWJlciwgd2UgYWx3YXlzIGFsaWduIGl0IGF0IDMwayArIDEuIEVhY2gKICAgICAgICB0aW1lIHRoZSBudW1iZXIgaXMgZGV0ZXJtaW5lZCBub3QgdG8gYmUgcHJpbWUgd2UgYWRkIHRvIGdldCB0byB0aGUKICAgICAgICBuZXh0ICdpJywgZWc6IGlmIHRoZSBudW1iZXIgd2FzIGF0IDMwayArIDEgd2UgYWRkIDYuICovCiAgICAgIHZhciBiaXRzID0gKHN0YXRlLnAgPT09IG51bGwpID8gc3RhdGUucEJpdHMgOiBzdGF0ZS5xQml0czsKICAgICAgdmFyIGJpdHMxID0gYml0cyAtIDE7CgogICAgICAvLyBnZXQgYSByYW5kb20gbnVtYmVyCiAgICAgIGlmKHN0YXRlLnBxU3RhdGUgPT09IDApIHsKICAgICAgICBzdGF0ZS5udW0gPSBuZXcgQmlnSW50ZWdlcihiaXRzLCBzdGF0ZS5ybmcpOwogICAgICAgIC8vIGZvcmNlIE1TQiBzZXQKICAgICAgICBpZighc3RhdGUubnVtLnRlc3RCaXQoYml0czEpKSB7CiAgICAgICAgICBzdGF0ZS5udW0uYml0d2lzZVRvKAogICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQoYml0czEpLCBvcF9vciwgc3RhdGUubnVtKTsKICAgICAgICB9CiAgICAgICAgLy8gYWxpZ24gbnVtYmVyIG9uIDMwaysxIGJvdW5kYXJ5CiAgICAgICAgc3RhdGUubnVtLmRBZGRPZmZzZXQoMzEgLSBzdGF0ZS5udW0ubW9kKFRISVJUWSkuYnl0ZVZhbHVlKCksIDApOwogICAgICAgIGRlbHRhSWR4ID0gMDsKCiAgICAgICAgKytzdGF0ZS5wcVN0YXRlOwogICAgICB9IGVsc2UgaWYoc3RhdGUucHFTdGF0ZSA9PT0gMSkgewogICAgICAgIC8vIHRyeSB0byBtYWtlIHRoZSBudW1iZXIgYSBwcmltZQogICAgICAgIGlmKHN0YXRlLm51bS5iaXRMZW5ndGgoKSA+IGJpdHMpIHsKICAgICAgICAgIC8vIG92ZXJmbG93LCB0cnkgYWdhaW4KICAgICAgICAgIHN0YXRlLnBxU3RhdGUgPSAwOwogICAgICAgICAgLy8gZG8gcHJpbWFsaXR5IHRlc3QKICAgICAgICB9IGVsc2UgaWYoc3RhdGUubnVtLmlzUHJvYmFibGVQcmltZSgKICAgICAgICAgIF9nZXRNaWxsZXJSYWJpblRlc3RzKHN0YXRlLm51bS5iaXRMZW5ndGgoKSkpKSB7CiAgICAgICAgICArK3N0YXRlLnBxU3RhdGU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8vIGdldCBuZXh0IHBvdGVudGlhbCBwcmltZQogICAgICAgICAgc3RhdGUubnVtLmRBZGRPZmZzZXQoR0NEXzMwX0RFTFRBW2RlbHRhSWR4KysgJSA4XSwgMCk7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYoc3RhdGUucHFTdGF0ZSA9PT0gMikgewogICAgICAgIC8vIGVuc3VyZSBudW1iZXIgaXMgY29wcmltZSB3aXRoIGUKICAgICAgICBzdGF0ZS5wcVN0YXRlID0KICAgICAgICAgIChzdGF0ZS5udW0uc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpLmdjZChzdGF0ZS5lKQogICAgICAgICAgLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT09IDApID8gMyA6IDA7CiAgICAgIH0gZWxzZSBpZihzdGF0ZS5wcVN0YXRlID09PSAzKSB7CiAgICAgICAgLy8gc3RvcmUgcCBvciBxCiAgICAgICAgc3RhdGUucHFTdGF0ZSA9IDA7CiAgICAgICAgaWYoc3RhdGUucCA9PT0gbnVsbCkgewogICAgICAgICAgc3RhdGUucCA9IHN0YXRlLm51bTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3RhdGUucSA9IHN0YXRlLm51bTsKICAgICAgICB9CgogICAgICAgIC8vIGFkdmFuY2Ugc3RhdGUgaWYgYm90aCBwIGFuZCBxIGFyZSByZWFkeQogICAgICAgIGlmKHN0YXRlLnAgIT09IG51bGwgJiYgc3RhdGUucSAhPT0gbnVsbCkgewogICAgICAgICAgKytzdGF0ZS5zdGF0ZTsKICAgICAgICB9CiAgICAgICAgc3RhdGUubnVtID0gbnVsbDsKICAgICAgfQogICAgfSBlbHNlIGlmKHN0YXRlLnN0YXRlID09PSAxKSB7CiAgICAgIC8vIGVuc3VyZSBwIGlzIGxhcmdlciB0aGFuIHEgKHN3YXAgdGhlbSBpZiBub3QpCiAgICAgIGlmKHN0YXRlLnAuY29tcGFyZVRvKHN0YXRlLnEpIDwgMCkgewogICAgICAgIHN0YXRlLm51bSA9IHN0YXRlLnA7CiAgICAgICAgc3RhdGUucCA9IHN0YXRlLnE7CiAgICAgICAgc3RhdGUucSA9IHN0YXRlLm51bTsKICAgICAgfQogICAgICArK3N0YXRlLnN0YXRlOwogICAgfSBlbHNlIGlmKHN0YXRlLnN0YXRlID09PSAyKSB7CiAgICAgIC8vIGNvbXB1dGUgcGhpOiAocCAtIDEpKHEgLSAxKSAoRXVsZXIncyB0b3RpZW50IGZ1bmN0aW9uKQogICAgICBzdGF0ZS5wMSA9IHN0YXRlLnAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpOwogICAgICBzdGF0ZS5xMSA9IHN0YXRlLnEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpOwogICAgICBzdGF0ZS5waGkgPSBzdGF0ZS5wMS5tdWx0aXBseShzdGF0ZS5xMSk7CiAgICAgICsrc3RhdGUuc3RhdGU7CiAgICB9IGVsc2UgaWYoc3RhdGUuc3RhdGUgPT09IDMpIHsKICAgICAgLy8gZW5zdXJlIGUgYW5kIHBoaSBhcmUgY29wcmltZQogICAgICBpZihzdGF0ZS5waGkuZ2NkKHN0YXRlLmUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT09IDApIHsKICAgICAgICAvLyBwaGkgYW5kIGUgYXJlIGNvcHJpbWUsIGFkdmFuY2UKICAgICAgICArK3N0YXRlLnN0YXRlOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIHBoaSBhbmQgZSBhcmVuJ3QgY29wcmltZSwgc28gZ2VuZXJhdGUgYSBuZXcgcCBhbmQgcQogICAgICAgIHN0YXRlLnAgPSBudWxsOwogICAgICAgIHN0YXRlLnEgPSBudWxsOwogICAgICAgIHN0YXRlLnN0YXRlID0gMDsKICAgICAgfQogICAgfSBlbHNlIGlmKHN0YXRlLnN0YXRlID09PSA0KSB7CiAgICAgIC8vIGNyZWF0ZSBuLCBlbnN1cmUgbiBpcyBoYXMgdGhlIHJpZ2h0IG51bWJlciBvZiBiaXRzCiAgICAgIHN0YXRlLm4gPSBzdGF0ZS5wLm11bHRpcGx5KHN0YXRlLnEpOwoKICAgICAgLy8gZW5zdXJlIG4gaXMgcmlnaHQgbnVtYmVyIG9mIGJpdHMKICAgICAgaWYoc3RhdGUubi5iaXRMZW5ndGgoKSA9PT0gc3RhdGUuYml0cykgewogICAgICAgIC8vIHN1Y2Nlc3MsIGFkdmFuY2UKICAgICAgICArK3N0YXRlLnN0YXRlOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIGZhaWxlZCwgZ2V0IG5ldyBxCiAgICAgICAgc3RhdGUucSA9IG51bGw7CiAgICAgICAgc3RhdGUuc3RhdGUgPSAwOwogICAgICB9CiAgICB9IGVsc2UgaWYoc3RhdGUuc3RhdGUgPT09IDUpIHsKICAgICAgLy8gc2V0IGtleXMKICAgICAgdmFyIGQgPSBzdGF0ZS5lLm1vZEludmVyc2Uoc3RhdGUucGhpKTsKICAgICAgc3RhdGUua2V5cyA9IHsKICAgICAgICBwcml2YXRlS2V5OiBwa2kucnNhLnNldFByaXZhdGVLZXkoCiAgICAgICAgICBzdGF0ZS5uLCBzdGF0ZS5lLCBkLCBzdGF0ZS5wLCBzdGF0ZS5xLAogICAgICAgICAgZC5tb2Qoc3RhdGUucDEpLCBkLm1vZChzdGF0ZS5xMSksCiAgICAgICAgICBzdGF0ZS5xLm1vZEludmVyc2Uoc3RhdGUucCkpLAogICAgICAgIHB1YmxpY0tleTogcGtpLnJzYS5zZXRQdWJsaWNLZXkoc3RhdGUubiwgc3RhdGUuZSkKICAgICAgfTsKICAgIH0KCiAgICAvLyB1cGRhdGUgdGltaW5nCiAgICB0MiA9ICtuZXcgRGF0ZSgpOwogICAgdG90YWwgKz0gdDIgLSB0MTsKICAgIHQxID0gdDI7CiAgfQoKICByZXR1cm4gc3RhdGUua2V5cyAhPT0gbnVsbDsKfTsKCi8qKgogKiBHZW5lcmF0ZXMgYW4gUlNBIHB1YmxpYy1wcml2YXRlIGtleSBwYWlyIGluIGEgc2luZ2xlIGNhbGwuCiAqCiAqIFRvIGdlbmVyYXRlIGEga2V5LXBhaXIgaW4gc3RlcHMgKHRvIGFsbG93IGZvciBwcm9ncmVzcyB1cGRhdGVzIGFuZCB0bwogKiBwcmV2ZW50IGJsb2NraW5nIG9yIHdhcm5pbmdzIGluIHNsb3cgYnJvd3NlcnMpIHRoZW4gdXNlIHRoZSBrZXktcGFpcgogKiBnZW5lcmF0aW9uIHN0YXRlIGZ1bmN0aW9ucy4KICoKICogVG8gZ2VuZXJhdGUgYSBrZXktcGFpciBhc3luY2hyb25vdXNseSAoZWl0aGVyIHRocm91Z2ggd2ViLXdvcmtlcnMsIGlmCiAqIGF2YWlsYWJsZSwgb3IgYnkgYnJlYWtpbmcgdXAgdGhlIHdvcmsgb24gdGhlIG1haW4gdGhyZWFkKSwgcGFzcyBhCiAqIGNhbGxiYWNrIGZ1bmN0aW9uLgogKgogKiBAcGFyYW0gW2JpdHNdIHRoZSBzaXplIGZvciB0aGUgcHJpdmF0ZSBrZXkgaW4gYml0cywgZGVmYXVsdHMgdG8gMjA0OC4KICogQHBhcmFtIFtlXSB0aGUgcHVibGljIGV4cG9uZW50IHRvIHVzZSwgZGVmYXVsdHMgdG8gNjU1MzcuCiAqIEBwYXJhbSBbb3B0aW9uc10gb3B0aW9ucyBmb3Iga2V5LXBhaXIgZ2VuZXJhdGlvbiwgaWYgZ2l2ZW4gdGhlbiAnYml0cycKICogICAgICAgICAgYW5kICdlJyBtdXN0ICpub3QqIGJlIGdpdmVuOgogKiAgICAgICAgICBiaXRzIHRoZSBzaXplIGZvciB0aGUgcHJpdmF0ZSBrZXkgaW4gYml0cywgKGRlZmF1bHQ6IDIwNDgpLgogKiAgICAgICAgICBlIHRoZSBwdWJsaWMgZXhwb25lbnQgdG8gdXNlLCAoZGVmYXVsdDogNjU1MzcgKDB4MTAwMDEpKS4KICogICAgICAgICAgd29ya2VyU2NyaXB0IHRoZSB3b3JrZXIgc2NyaXB0IFVSTC4KICogICAgICAgICAgd29ya2VycyB0aGUgbnVtYmVyIG9mIHdlYiB3b3JrZXJzIChpZiBzdXBwb3J0ZWQpIHRvIHVzZSwKICogICAgICAgICAgICAoZGVmYXVsdDogMikuCiAqICAgICAgICAgIHdvcmtMb2FkIHRoZSBzaXplIG9mIHRoZSB3b3JrIGxvYWQsIGllOiBudW1iZXIgb2YgcG9zc2libGUgcHJpbWUKICogICAgICAgICAgICBudW1iZXJzIGZvciBlYWNoIHdlYiB3b3JrZXIgdG8gY2hlY2sgcGVyIHdvcmsgYXNzaWdubWVudCwKICogICAgICAgICAgICAoZGVmYXVsdDogMTAwKS4KICogICAgICAgICAgZSB0aGUgcHVibGljIGV4cG9uZW50IHRvIHVzZSwgZGVmYXVsdHMgdG8gNjU1MzcuCiAqICAgICAgICAgIHBybmcgYSBjdXN0b20gY3J5cHRvLXNlY3VyZSBwc2V1ZG8tcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdG8gdXNlLAogKiAgICAgICAgICAgIHRoYXQgbXVzdCBkZWZpbmUgImdldEJ5dGVzU3luYyIuCiAqICAgICAgICAgIGFsZ29yaXRobSB0aGUgYWxnb3JpdGhtIHRvIHVzZSAoZGVmYXVsdDogJ1BSSU1FSU5DJykuCiAqIEBwYXJhbSBbY2FsbGJhY2soZXJyLCBrZXlwYWlyKV0gY2FsbGVkIG9uY2UgdGhlIG9wZXJhdGlvbiBjb21wbGV0ZXMuCiAqCiAqIEByZXR1cm4gYW4gb2JqZWN0IHdpdGggcHJpdmF0ZUtleSBhbmQgcHVibGljS2V5IHByb3BlcnRpZXMuCiAqLwpwa2kucnNhLmdlbmVyYXRlS2V5UGFpciA9IGZ1bmN0aW9uKGJpdHMsIGUsIG9wdGlvbnMsIGNhbGxiYWNrKSB7CiAgLy8gKGJpdHMpLCAob3B0aW9ucyksIChjYWxsYmFjaykKICBpZihhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7CiAgICBpZih0eXBlb2YgYml0cyA9PT0gJ29iamVjdCcpIHsKICAgICAgb3B0aW9ucyA9IGJpdHM7CiAgICAgIGJpdHMgPSB1bmRlZmluZWQ7CiAgICB9IGVsc2UgaWYodHlwZW9mIGJpdHMgPT09ICdmdW5jdGlvbicpIHsKICAgICAgY2FsbGJhY2sgPSBiaXRzOwogICAgICBiaXRzID0gdW5kZWZpbmVkOwogICAgfQogIH0gZWxzZSBpZihhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7CiAgICAvLyAoYml0cywgZSksIChiaXRzLCBvcHRpb25zKSwgKGJpdHMsIGNhbGxiYWNrKSwgKG9wdGlvbnMsIGNhbGxiYWNrKQogICAgaWYodHlwZW9mIGJpdHMgPT09ICdudW1iZXInKSB7CiAgICAgIGlmKHR5cGVvZiBlID09PSAnZnVuY3Rpb24nKSB7CiAgICAgICAgY2FsbGJhY2sgPSBlOwogICAgICAgIGUgPSB1bmRlZmluZWQ7CiAgICAgIH0gZWxzZSBpZih0eXBlb2YgZSAhPT0gJ251bWJlcicpIHsKICAgICAgICBvcHRpb25zID0gZTsKICAgICAgICBlID0gdW5kZWZpbmVkOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBvcHRpb25zID0gYml0czsKICAgICAgY2FsbGJhY2sgPSBlOwogICAgICBiaXRzID0gdW5kZWZpbmVkOwogICAgICBlID0gdW5kZWZpbmVkOwogICAgfQogIH0gZWxzZSBpZihhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7CiAgICAvLyAoYml0cywgZSwgb3B0aW9ucyksIChiaXRzLCBlLCBjYWxsYmFjayksIChiaXRzLCBvcHRpb25zLCBjYWxsYmFjaykKICAgIGlmKHR5cGVvZiBlID09PSAnbnVtYmVyJykgewogICAgICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgIGNhbGxiYWNrID0gb3B0aW9uczsKICAgICAgICBvcHRpb25zID0gdW5kZWZpbmVkOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBjYWxsYmFjayA9IG9wdGlvbnM7CiAgICAgIG9wdGlvbnMgPSBlOwogICAgICBlID0gdW5kZWZpbmVkOwogICAgfQogIH0KICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICBpZihiaXRzID09PSB1bmRlZmluZWQpIHsKICAgIGJpdHMgPSBvcHRpb25zLmJpdHMgfHwgMjA0ODsKICB9CiAgaWYoZSA9PT0gdW5kZWZpbmVkKSB7CiAgICBlID0gb3B0aW9ucy5lIHx8IDB4MTAwMDE7CiAgfQogIHZhciBzdGF0ZSA9IHBraS5yc2EuY3JlYXRlS2V5UGFpckdlbmVyYXRpb25TdGF0ZShiaXRzLCBlLCBvcHRpb25zKTsKICBpZighY2FsbGJhY2spIHsKICAgIHBraS5yc2Euc3RlcEtleVBhaXJHZW5lcmF0aW9uU3RhdGUoc3RhdGUsIDApOwogICAgcmV0dXJuIHN0YXRlLmtleXM7CiAgfQogIF9nZW5lcmF0ZUtleVBhaXIoc3RhdGUsIG9wdGlvbnMsIGNhbGxiYWNrKTsKfTsKCi8qKgogKiBTZXRzIGFuIFJTQSBwdWJsaWMga2V5IGZyb20gQmlnSW50ZWdlcnMgbW9kdWx1cyBhbmQgZXhwb25lbnQuCiAqCiAqIEBwYXJhbSBuIHRoZSBtb2R1bHVzLgogKiBAcGFyYW0gZSB0aGUgZXhwb25lbnQuCiAqCiAqIEByZXR1cm4gdGhlIHB1YmxpYyBrZXkuCiAqLwpwa2kuc2V0UnNhUHVibGljS2V5ID0gcGtpLnJzYS5zZXRQdWJsaWNLZXkgPSBmdW5jdGlvbihuLCBlKSB7CiAgdmFyIGtleSA9IHsKICAgIG46IG4sCiAgICBlOiBlCiAgfTsKCiAgLyoqCiAgICogRW5jcnlwdHMgdGhlIGdpdmVuIGRhdGEgd2l0aCB0aGlzIHB1YmxpYyBrZXkuIE5ld2VyIGFwcGxpY2F0aW9ucwogICAqIHNob3VsZCB1c2UgdGhlICdSU0EtT0FFUCcgZGVjcnlwdGlvbiBzY2hlbWUsICdSU0FFUy1QS0NTMS1WMV81JyBpcyBmb3IKICAgKiBsZWdhY3kgYXBwbGljYXRpb25zLgogICAqCiAgICogQHBhcmFtIGRhdGEgdGhlIGJ5dGUgc3RyaW5nIHRvIGVuY3J5cHQuCiAgICogQHBhcmFtIHNjaGVtZSB0aGUgZW5jcnlwdGlvbiBzY2hlbWUgdG8gdXNlOgogICAqICAgICAgICAgICdSU0FFUy1QS0NTMS1WMV81JyAoZGVmYXVsdCksCiAgICogICAgICAgICAgJ1JTQS1PQUVQJywKICAgKiAgICAgICAgICAnUkFXJywgJ05PTkUnLCBvciBudWxsIHRvIHBlcmZvcm0gcmF3IFJTQSBlbmNyeXB0aW9uLAogICAqICAgICAgICAgIGFuIG9iamVjdCB3aXRoIGFuICdlbmNvZGUnIHByb3BlcnR5IHNldCB0byBhIGZ1bmN0aW9uCiAgICogICAgICAgICAgd2l0aCB0aGUgc2lnbmF0dXJlICdmdW5jdGlvbihkYXRhLCBrZXkpJyB0aGF0IHJldHVybnMKICAgKiAgICAgICAgICBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGVuY29kZWQgZGF0YS4KICAgKiBAcGFyYW0gc2NoZW1lT3B0aW9ucyBhbnkgc2NoZW1lLXNwZWNpZmljIG9wdGlvbnMuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBlbmNyeXB0ZWQgYnl0ZSBzdHJpbmcuCiAgICovCiAga2V5LmVuY3J5cHQgPSBmdW5jdGlvbihkYXRhLCBzY2hlbWUsIHNjaGVtZU9wdGlvbnMpIHsKICAgIGlmKHR5cGVvZiBzY2hlbWUgPT09ICdzdHJpbmcnKSB7CiAgICAgIHNjaGVtZSA9IHNjaGVtZS50b1VwcGVyQ2FzZSgpOwogICAgfSBlbHNlIGlmKHNjaGVtZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIHNjaGVtZSA9ICdSU0FFUy1QS0NTMS1WMV81JzsKICAgIH0KCiAgICBpZihzY2hlbWUgPT09ICdSU0FFUy1QS0NTMS1WMV81JykgewogICAgICBzY2hlbWUgPSB7CiAgICAgICAgZW5jb2RlOiBmdW5jdGlvbihtLCBrZXksIHB1YikgewogICAgICAgICAgcmV0dXJuIF9lbmNvZGVQa2NzMV92MV81KG0sIGtleSwgMHgwMikuZ2V0Qnl0ZXMoKTsKICAgICAgICB9CiAgICAgIH07CiAgICB9IGVsc2UgaWYoc2NoZW1lID09PSAnUlNBLU9BRVAnIHx8IHNjaGVtZSA9PT0gJ1JTQUVTLU9BRVAnKSB7CiAgICAgIHNjaGVtZSA9IHsKICAgICAgICBlbmNvZGU6IGZ1bmN0aW9uKG0sIGtleSkgewogICAgICAgICAgcmV0dXJuIGZvcmdlLnBrY3MxLmVuY29kZV9yc2Ffb2FlcChrZXksIG0sIHNjaGVtZU9wdGlvbnMpOwogICAgICAgIH0KICAgICAgfTsKICAgIH0gZWxzZSBpZihbJ1JBVycsICdOT05FJywgJ05VTEwnLCBudWxsXS5pbmRleE9mKHNjaGVtZSkgIT09IC0xKSB7CiAgICAgIHNjaGVtZSA9IHsgZW5jb2RlOiBmdW5jdGlvbihlKSB7IHJldHVybiBlOyB9IH07CiAgICB9IGVsc2UgaWYodHlwZW9mIHNjaGVtZSA9PT0gJ3N0cmluZycpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBlbmNyeXB0aW9uIHNjaGVtZTogIicgKyBzY2hlbWUgKyAnIi4nKTsKICAgIH0KCiAgICAvLyBkbyBzY2hlbWUtYmFzZWQgZW5jb2RpbmcgdGhlbiByc2EgZW5jcnlwdGlvbgogICAgdmFyIGUgPSBzY2hlbWUuZW5jb2RlKGRhdGEsIGtleSwgdHJ1ZSk7CiAgICByZXR1cm4gcGtpLnJzYS5lbmNyeXB0KGUsIGtleSwgdHJ1ZSk7CiAgfTsKCiAgLyoqCiAgICogVmVyaWZpZXMgdGhlIGdpdmVuIHNpZ25hdHVyZSBhZ2FpbnN0IHRoZSBnaXZlbiBkaWdlc3QuCiAgICoKICAgKiBQS0NTIzEgc3VwcG9ydHMgbXVsdGlwbGUgKGN1cnJlbnRseSB0d28pIHNpZ25hdHVyZSBzY2hlbWVzOgogICAqIFJTQVNTQS1QS0NTMS1WMV81IGFuZCBSU0FTU0EtUFNTLgogICAqCiAgICogQnkgZGVmYXVsdCB0aGlzIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlICJvbGQgc2NoZW1lIiwgaS5lLgogICAqIFJTQVNTQS1QS0NTMS1WMV81LCBpbiB3aGljaCBjYXNlIG9uY2UgUlNBLWRlY3J5cHRlZCwgdGhlCiAgICogc2lnbmF0dXJlIGlzIGFuIE9DVEVUIFNUUklORyB0aGF0IGhvbGRzIGEgRGlnZXN0SW5mby4KICAgKgogICAqIERpZ2VzdEluZm8gOjo9IFNFUVVFTkNFIHsKICAgKiAgIGRpZ2VzdEFsZ29yaXRobSBEaWdlc3RBbGdvcml0aG1JZGVudGlmaWVyLAogICAqICAgZGlnZXN0IERpZ2VzdAogICAqIH0KICAgKiBEaWdlc3RBbGdvcml0aG1JZGVudGlmaWVyIDo6PSBBbGdvcml0aG1JZGVudGlmaWVyCiAgICogRGlnZXN0IDo6PSBPQ1RFVCBTVFJJTkcKICAgKgogICAqIFRvIHBlcmZvcm0gUFNTIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24sIHByb3ZpZGUgYW4gaW5zdGFuY2UKICAgKiBvZiBGb3JnZSBQU1Mgb2JqZWN0IGFzIHRoZSBzY2hlbWUgcGFyYW1ldGVyLgogICAqCiAgICogQHBhcmFtIGRpZ2VzdCB0aGUgbWVzc2FnZSBkaWdlc3QgaGFzaCB0byBjb21wYXJlIGFnYWluc3QgdGhlIHNpZ25hdHVyZSwKICAgKiAgICAgICAgICBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZy4KICAgKiBAcGFyYW0gc2lnbmF0dXJlIHRoZSBzaWduYXR1cmUgdG8gdmVyaWZ5LCBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZy4KICAgKiBAcGFyYW0gc2NoZW1lIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24gc2NoZW1lIHRvIHVzZToKICAgKiAgICAgICAgICAnUlNBU1NBLVBLQ1MxLVYxXzUnIG9yIHVuZGVmaW5lZCBmb3IgUlNBU1NBIFBLQ1MjMSB2MS41LAogICAqICAgICAgICAgIGEgRm9yZ2UgUFNTIG9iamVjdCBmb3IgUlNBU1NBLVBTUywKICAgKiAgICAgICAgICAnTk9ORScgb3IgbnVsbCBmb3Igbm9uZSwgRGlnZXN0SW5mbyB3aWxsIG5vdCBiZSBleHBlY3RlZCwgYnV0CiAgICogICAgICAgICAgICBQS0NTIzEgdjEuNSBwYWRkaW5nIHdpbGwgc3RpbGwgYmUgdXNlZC4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc2lnbmF0dXJlIHdhcyB2ZXJpZmllZCwgZmFsc2UgaWYgbm90LgogICAqLwogICBrZXkudmVyaWZ5ID0gZnVuY3Rpb24oZGlnZXN0LCBzaWduYXR1cmUsIHNjaGVtZSkgewogICAgIGlmKHR5cGVvZiBzY2hlbWUgPT09ICdzdHJpbmcnKSB7CiAgICAgICBzY2hlbWUgPSBzY2hlbWUudG9VcHBlckNhc2UoKTsKICAgICB9IGVsc2UgaWYoc2NoZW1lID09PSB1bmRlZmluZWQpIHsKICAgICAgIHNjaGVtZSA9ICdSU0FTU0EtUEtDUzEtVjFfNSc7CiAgICAgfQoKICAgICBpZihzY2hlbWUgPT09ICdSU0FTU0EtUEtDUzEtVjFfNScpIHsKICAgICAgIHNjaGVtZSA9IHsKICAgICAgICAgdmVyaWZ5OiBmdW5jdGlvbihkaWdlc3QsIGQpIHsKICAgICAgICAgICAvLyByZW1vdmUgcGFkZGluZwogICAgICAgICAgIGQgPSBfZGVjb2RlUGtjczFfdjFfNShkLCBrZXksIHRydWUpOwogICAgICAgICAgIC8vIGQgaXMgQVNOLjEgQkVSLWVuY29kZWQgRGlnZXN0SW5mbwogICAgICAgICAgIHZhciBvYmogPSBhc24xLmZyb21EZXIoZCk7CiAgICAgICAgICAgLy8gY29tcGFyZSB0aGUgZ2l2ZW4gZGlnZXN0IHRvIHRoZSBkZWNyeXB0ZWQgb25lCiAgICAgICAgICAgcmV0dXJuIGRpZ2VzdCA9PT0gb2JqLnZhbHVlWzFdLnZhbHVlOwogICAgICAgICB9CiAgICAgICB9OwogICAgIH0gZWxzZSBpZihzY2hlbWUgPT09ICdOT05FJyB8fCBzY2hlbWUgPT09ICdOVUxMJyB8fCBzY2hlbWUgPT09IG51bGwpIHsKICAgICAgIHNjaGVtZSA9IHsKICAgICAgICAgdmVyaWZ5OiBmdW5jdGlvbihkaWdlc3QsIGQpIHsKICAgICAgICAgICAvLyByZW1vdmUgcGFkZGluZwogICAgICAgICAgIGQgPSBfZGVjb2RlUGtjczFfdjFfNShkLCBrZXksIHRydWUpOwogICAgICAgICAgIHJldHVybiBkaWdlc3QgPT09IGQ7CiAgICAgICAgIH0KICAgICAgIH07CiAgICAgfQoKICAgICAvLyBkbyByc2EgZGVjcnlwdGlvbiB3L28gYW55IGRlY29kaW5nLCB0aGVuIHZlcmlmeSAtLSB3aGljaCBkb2VzIGRlY29kaW5nCiAgICAgdmFyIGQgPSBwa2kucnNhLmRlY3J5cHQoc2lnbmF0dXJlLCBrZXksIHRydWUsIGZhbHNlKTsKICAgICByZXR1cm4gc2NoZW1lLnZlcmlmeShkaWdlc3QsIGQsIGtleS5uLmJpdExlbmd0aCgpKTsKICB9OwoKICByZXR1cm4ga2V5Owp9OwoKLyoqCiAqIFNldHMgYW4gUlNBIHByaXZhdGUga2V5IGZyb20gQmlnSW50ZWdlcnMgbW9kdWx1cywgZXhwb25lbnQsIHByaW1lcywKICogcHJpbWUgZXhwb25lbnRzLCBhbmQgbW9kdWxhciBtdWx0aXBsaWNhdGl2ZSBpbnZlcnNlLgogKgogKiBAcGFyYW0gbiB0aGUgbW9kdWx1cy4KICogQHBhcmFtIGUgdGhlIHB1YmxpYyBleHBvbmVudC4KICogQHBhcmFtIGQgdGhlIHByaXZhdGUgZXhwb25lbnQgKChpbnZlcnNlIG9mIGUpIG1vZCBuKS4KICogQHBhcmFtIHAgdGhlIGZpcnN0IHByaW1lLgogKiBAcGFyYW0gcSB0aGUgc2Vjb25kIHByaW1lLgogKiBAcGFyYW0gZFAgZXhwb25lbnQxIChkIG1vZCAocC0xKSkuCiAqIEBwYXJhbSBkUSBleHBvbmVudDIgKGQgbW9kIChxLTEpKS4KICogQHBhcmFtIHFJbnYgKChpbnZlcnNlIG9mIHEpIG1vZCBwKQogKgogKiBAcmV0dXJuIHRoZSBwcml2YXRlIGtleS4KICovCnBraS5zZXRSc2FQcml2YXRlS2V5ID0gcGtpLnJzYS5zZXRQcml2YXRlS2V5ID0gZnVuY3Rpb24oCiAgbiwgZSwgZCwgcCwgcSwgZFAsIGRRLCBxSW52KSB7CiAgdmFyIGtleSA9IHsKICAgIG46IG4sCiAgICBlOiBlLAogICAgZDogZCwKICAgIHA6IHAsCiAgICBxOiBxLAogICAgZFA6IGRQLAogICAgZFE6IGRRLAogICAgcUludjogcUludgogIH07CgogIC8qKgogICAqIERlY3J5cHRzIHRoZSBnaXZlbiBkYXRhIHdpdGggdGhpcyBwcml2YXRlIGtleS4gVGhlIGRlY3J5cHRpb24gc2NoZW1lCiAgICogbXVzdCBtYXRjaCB0aGUgb25lIHVzZWQgdG8gZW5jcnlwdCB0aGUgZGF0YS4KICAgKgogICAqIEBwYXJhbSBkYXRhIHRoZSBieXRlIHN0cmluZyB0byBkZWNyeXB0LgogICAqIEBwYXJhbSBzY2hlbWUgdGhlIGRlY3J5cHRpb24gc2NoZW1lIHRvIHVzZToKICAgKiAgICAgICAgICAnUlNBRVMtUEtDUzEtVjFfNScgKGRlZmF1bHQpLAogICAqICAgICAgICAgICdSU0EtT0FFUCcsCiAgICogICAgICAgICAgJ1JBVycsICdOT05FJywgb3IgbnVsbCB0byBwZXJmb3JtIHJhdyBSU0EgZGVjcnlwdGlvbi4KICAgKiBAcGFyYW0gc2NoZW1lT3B0aW9ucyBhbnkgc2NoZW1lLXNwZWNpZmljIG9wdGlvbnMuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBkZWNyeXB0ZWQgYnl0ZSBzdHJpbmcuCiAgICovCiAga2V5LmRlY3J5cHQgPSBmdW5jdGlvbihkYXRhLCBzY2hlbWUsIHNjaGVtZU9wdGlvbnMpIHsKICAgIGlmKHR5cGVvZiBzY2hlbWUgPT09ICdzdHJpbmcnKSB7CiAgICAgIHNjaGVtZSA9IHNjaGVtZS50b1VwcGVyQ2FzZSgpOwogICAgfSBlbHNlIGlmKHNjaGVtZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIHNjaGVtZSA9ICdSU0FFUy1QS0NTMS1WMV81JzsKICAgIH0KCiAgICAvLyBkbyByc2EgZGVjcnlwdGlvbiB3L28gYW55IGRlY29kaW5nCiAgICB2YXIgZCA9IHBraS5yc2EuZGVjcnlwdChkYXRhLCBrZXksIGZhbHNlLCBmYWxzZSk7CgogICAgaWYoc2NoZW1lID09PSAnUlNBRVMtUEtDUzEtVjFfNScpIHsKICAgICAgc2NoZW1lID0geyBkZWNvZGU6IF9kZWNvZGVQa2NzMV92MV81IH07CiAgICB9IGVsc2UgaWYoc2NoZW1lID09PSAnUlNBLU9BRVAnIHx8IHNjaGVtZSA9PT0gJ1JTQUVTLU9BRVAnKSB7CiAgICAgIHNjaGVtZSA9IHsKICAgICAgICBkZWNvZGU6IGZ1bmN0aW9uKGQsIGtleSkgewogICAgICAgICAgcmV0dXJuIGZvcmdlLnBrY3MxLmRlY29kZV9yc2Ffb2FlcChrZXksIGQsIHNjaGVtZU9wdGlvbnMpOwogICAgICAgIH0KICAgICAgfTsKICAgIH0gZWxzZSBpZihbJ1JBVycsICdOT05FJywgJ05VTEwnLCBudWxsXS5pbmRleE9mKHNjaGVtZSkgIT09IC0xKSB7CiAgICAgIHNjaGVtZSA9IHsgZGVjb2RlOiBmdW5jdGlvbihkKSB7IHJldHVybiBkOyB9IH07CiAgICB9IGVsc2UgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGVuY3J5cHRpb24gc2NoZW1lOiAiJyArIHNjaGVtZSArICciLicpOwogICAgfQoKICAgIC8vIGRlY29kZSBhY2NvcmRpbmcgdG8gc2NoZW1lCiAgICByZXR1cm4gc2NoZW1lLmRlY29kZShkLCBrZXksIGZhbHNlKTsKICB9OwoKICAvKioKICAgKiBTaWducyB0aGUgZ2l2ZW4gZGlnZXN0LCBwcm9kdWNpbmcgYSBzaWduYXR1cmUuCiAgICoKICAgKiBQS0NTIzEgc3VwcG9ydHMgbXVsdGlwbGUgKGN1cnJlbnRseSB0d28pIHNpZ25hdHVyZSBzY2hlbWVzOgogICAqIFJTQVNTQS1QS0NTMS1WMV81IGFuZCBSU0FTU0EtUFNTLgogICAqCiAgICogQnkgZGVmYXVsdCB0aGlzIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlICJvbGQgc2NoZW1lIiwgaS5lLgogICAqIFJTQVNTQS1QS0NTMS1WMV81LiBJbiBvcmRlciB0byBnZW5lcmF0ZSBhIFBTUyBzaWduYXR1cmUsIHByb3ZpZGUKICAgKiBhbiBpbnN0YW5jZSBvZiBGb3JnZSBQU1Mgb2JqZWN0IGFzIHRoZSBzY2hlbWUgcGFyYW1ldGVyLgogICAqCiAgICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3Qgd2l0aCB0aGUgaGFzaCB0byBzaWduLgogICAqIEBwYXJhbSBzY2hlbWUgdGhlIHNpZ25hdHVyZSBzY2hlbWUgdG8gdXNlOgogICAqICAgICAgICAgICdSU0FTU0EtUEtDUzEtVjFfNScgb3IgdW5kZWZpbmVkIGZvciBSU0FTU0EgUEtDUyMxIHYxLjUsCiAgICogICAgICAgICAgYSBGb3JnZSBQU1Mgb2JqZWN0IGZvciBSU0FTU0EtUFNTLAogICAqICAgICAgICAgICdOT05FJyBvciBudWxsIGZvciBub25lLCBEaWdlc3RJbmZvIHdpbGwgbm90IGJlIHVzZWQgYnV0CiAgICogICAgICAgICAgICBQS0NTIzEgdjEuNSBwYWRkaW5nIHdpbGwgc3RpbGwgYmUgdXNlZC4KICAgKgogICAqIEByZXR1cm4gdGhlIHNpZ25hdHVyZSBhcyBhIGJ5dGUgc3RyaW5nLgogICAqLwogIGtleS5zaWduID0gZnVuY3Rpb24obWQsIHNjaGVtZSkgewogICAgLyogTm90ZTogVGhlIGludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIFJTQSBvcGVyYXRpb25zIGlzIGJlaW5nCiAgICAgIHRyYW5zaXRpb25lZCBhd2F5IGZyb20gYSBQS0NTIzEgdjEuNSBoYXJkLWNvZGVkIHNjaGVtZS4gU29tZSBsZWdhY3kKICAgICAgY29kZSBsaWtlIHRoZSB1c2Ugb2YgYW4gZW5jb2RpbmcgYmxvY2sgaWRlbnRpZmllciAnYnQnIHdpbGwgZXZlbnR1YWxseQogICAgICBiZSByZW1vdmVkLiAqLwoKICAgIC8vIHByaXZhdGUga2V5IG9wZXJhdGlvbgogICAgdmFyIGJ0ID0gZmFsc2U7CgogICAgaWYodHlwZW9mIHNjaGVtZSA9PT0gJ3N0cmluZycpIHsKICAgICAgc2NoZW1lID0gc2NoZW1lLnRvVXBwZXJDYXNlKCk7CiAgICB9CgogICAgaWYoc2NoZW1lID09PSB1bmRlZmluZWQgfHwgc2NoZW1lID09PSAnUlNBU1NBLVBLQ1MxLVYxXzUnKSB7CiAgICAgIHNjaGVtZSA9IHsgZW5jb2RlOiBlbXNhUGtjczF2MTVlbmNvZGUgfTsKICAgICAgYnQgPSAweDAxOwogICAgfSBlbHNlIGlmKHNjaGVtZSA9PT0gJ05PTkUnIHx8IHNjaGVtZSA9PT0gJ05VTEwnIHx8IHNjaGVtZSA9PT0gbnVsbCkgewogICAgICBzY2hlbWUgPSB7IGVuY29kZTogZnVuY3Rpb24oKSB7IHJldHVybiBtZDsgfSB9OwogICAgICBidCA9IDB4MDE7CiAgICB9CgogICAgLy8gZW5jb2RlIGFuZCB0aGVuIGVuY3J5cHQKICAgIHZhciBkID0gc2NoZW1lLmVuY29kZShtZCwga2V5Lm4uYml0TGVuZ3RoKCkpOwogICAgcmV0dXJuIHBraS5yc2EuZW5jcnlwdChkLCBrZXksIGJ0KTsKICB9OwoKICByZXR1cm4ga2V5Owp9OwoKLyoqCiAqIFdyYXBzIGFuIFJTQVByaXZhdGVLZXkgQVNOLjEgb2JqZWN0IGluIGFuIEFTTi4xIFByaXZhdGVLZXlJbmZvIG9iamVjdC4KICoKICogQHBhcmFtIHJzYUtleSB0aGUgQVNOLjEgUlNBUHJpdmF0ZUtleS4KICoKICogQHJldHVybiB0aGUgQVNOLjEgUHJpdmF0ZUtleUluZm8uCiAqLwpwa2kud3JhcFJzYVByaXZhdGVLZXkgPSBmdW5jdGlvbihyc2FLZXkpIHsKICAvLyBQcml2YXRlS2V5SW5mbwogIHJldHVybiBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyB2ZXJzaW9uICgwKQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIoMCkuZ2V0Qnl0ZXMoKSksCiAgICAvLyBwcml2YXRlS2V5QWxnb3JpdGhtCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIGFzbjEuY3JlYXRlKAogICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICBhc24xLm9pZFRvRGVyKHBraS5vaWRzLnJzYUVuY3J5cHRpb24pLmdldEJ5dGVzKCkpLAogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgIF0pLAogICAgLy8gUHJpdmF0ZUtleQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsCiAgICAgIGFzbjEudG9EZXIocnNhS2V5KS5nZXRCeXRlcygpKQogICAgXSk7Cn07CgovKioKICogQ29udmVydHMgYSBwcml2YXRlIGtleSBmcm9tIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiB0aGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgYSBQcml2YXRlS2V5SW5mbyBjb250YWluaW5nIGFuCiAqICAgICAgICAgIFJTQVByaXZhdGVLZXkgb3IgYW4gUlNBUHJpdmF0ZUtleS4KICoKICogQHJldHVybiB0aGUgcHJpdmF0ZSBrZXkuCiAqLwpwa2kucHJpdmF0ZUtleUZyb21Bc24xID0gZnVuY3Rpb24ob2JqKSB7CiAgLy8gZ2V0IFByaXZhdGVLZXlJbmZvCiAgdmFyIGNhcHR1cmUgPSB7fTsKICB2YXIgZXJyb3JzID0gW107CiAgaWYoYXNuMS52YWxpZGF0ZShvYmosIHByaXZhdGVLZXlWYWxpZGF0b3IsIGNhcHR1cmUsIGVycm9ycykpIHsKICAgIG9iaiA9IGFzbjEuZnJvbURlcihmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLnByaXZhdGVLZXkpKTsKICB9CgogIC8vIGdldCBSU0FQcml2YXRlS2V5CiAgY2FwdHVyZSA9IHt9OwogIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgcnNhUHJpdmF0ZUtleVZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBwcml2YXRlIGtleS4gJyArCiAgICAgICdBU04uMSBvYmplY3QgZG9lcyBub3QgY29udGFpbiBhbiBSU0FQcml2YXRlS2V5LicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3JzOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICAvLyBOb3RlOiBWZXJzaW9uIGlzIGN1cnJlbnRseSBpZ25vcmVkLgogIC8vIGNhcHR1cmUucHJpdmF0ZUtleVZlcnNpb24KICAvLyBGSVhNRTogaW5lZmZpY2llbnQsIGdldCBhIEJpZ0ludGVnZXIgdGhhdCB1c2VzIGJ5dGUgc3RyaW5ncwogIHZhciBuLCBlLCBkLCBwLCBxLCBkUCwgZFEsIHFJbnY7CiAgbiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHJpdmF0ZUtleU1vZHVsdXMpLnRvSGV4KCk7CiAgZSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHJpdmF0ZUtleVB1YmxpY0V4cG9uZW50KS50b0hleCgpOwogIGQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLnByaXZhdGVLZXlQcml2YXRlRXhwb25lbnQpLnRvSGV4KCk7CiAgcCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHJpdmF0ZUtleVByaW1lMSkudG9IZXgoKTsKICBxID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5wcml2YXRlS2V5UHJpbWUyKS50b0hleCgpOwogIGRQID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5wcml2YXRlS2V5RXhwb25lbnQxKS50b0hleCgpOwogIGRRID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5wcml2YXRlS2V5RXhwb25lbnQyKS50b0hleCgpOwogIHFJbnYgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLnByaXZhdGVLZXlDb2VmZmljaWVudCkudG9IZXgoKTsKCiAgLy8gc2V0IHByaXZhdGUga2V5CiAgcmV0dXJuIHBraS5zZXRSc2FQcml2YXRlS2V5KAogICAgbmV3IEJpZ0ludGVnZXIobiwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIoZSwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIoZCwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIocCwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIocSwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIoZFAsIDE2KSwKICAgIG5ldyBCaWdJbnRlZ2VyKGRRLCAxNiksCiAgICBuZXcgQmlnSW50ZWdlcihxSW52LCAxNikpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgcHJpdmF0ZSBrZXkgdG8gYW4gQVNOLjEgUlNBUHJpdmF0ZUtleS4KICoKICogQHBhcmFtIGtleSB0aGUgcHJpdmF0ZSBrZXkuCiAqCiAqIEByZXR1cm4gdGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIGFuIFJTQVByaXZhdGVLZXkuCiAqLwpwa2kucHJpdmF0ZUtleVRvQXNuMSA9IHBraS5wcml2YXRlS2V5VG9SU0FQcml2YXRlS2V5ID0gZnVuY3Rpb24oa2V5KSB7CiAgLy8gUlNBUHJpdmF0ZUtleQogIHJldHVybiBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyB2ZXJzaW9uICgwID0gb25seSAyIHByaW1lcywgMSBtdWx0aXBsZSBwcmltZXMpCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBhc24xLmludGVnZXJUb0RlcigwKS5nZXRCeXRlcygpKSwKICAgIC8vIG1vZHVsdXMgKG4pCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5uKSksCiAgICAvLyBwdWJsaWNFeHBvbmVudCAoZSkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIF9iblRvQnl0ZXMoa2V5LmUpKSwKICAgIC8vIHByaXZhdGVFeHBvbmVudCAoZCkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIF9iblRvQnl0ZXMoa2V5LmQpKSwKICAgIC8vIHByaXZhdGVLZXlQcmltZTEgKHApCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5wKSksCiAgICAvLyBwcml2YXRlS2V5UHJpbWUyIChxKQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgX2JuVG9CeXRlcyhrZXkucSkpLAogICAgLy8gcHJpdmF0ZUtleUV4cG9uZW50MSAoZFApCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5kUCkpLAogICAgLy8gcHJpdmF0ZUtleUV4cG9uZW50MiAoZFEpCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5kUSkpLAogICAgLy8gY29lZmZpY2llbnQgKHFJbnYpCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5xSW52KSkKICBdKTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIHB1YmxpYyBrZXkgZnJvbSBhbiBBU04uMSBTdWJqZWN0UHVibGljS2V5SW5mbyBvciBSU0FQdWJsaWNLZXkuCiAqCiAqIEBwYXJhbSBvYmogdGhlIGFzbjEgcmVwcmVzZW50YXRpb24gb2YgYSBTdWJqZWN0UHVibGljS2V5SW5mbyBvciBSU0FQdWJsaWNLZXkuCiAqCiAqIEByZXR1cm4gdGhlIHB1YmxpYyBrZXkuCiAqLwpwa2kucHVibGljS2V5RnJvbUFzbjEgPSBmdW5jdGlvbihvYmopIHsKICAvLyBnZXQgU3ViamVjdFB1YmxpY0tleUluZm8KICB2YXIgY2FwdHVyZSA9IHt9OwogIHZhciBlcnJvcnMgPSBbXTsKICBpZihhc24xLnZhbGlkYXRlKG9iaiwgcHVibGljS2V5VmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICAvLyBnZXQgb2lkCiAgICB2YXIgb2lkID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLnB1YmxpY0tleU9pZCk7CiAgICBpZihvaWQgIT09IHBraS5vaWRzLnJzYUVuY3J5cHRpb24pIHsKICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBwdWJsaWMga2V5LiBVbmtub3duIE9JRC4nKTsKICAgICAgZXJyb3Iub2lkID0gb2lkOwogICAgICB0aHJvdyBlcnJvcjsKICAgIH0KICAgIG9iaiA9IGNhcHR1cmUucnNhUHVibGljS2V5OwogIH0KCiAgLy8gZ2V0IFJTQSBwYXJhbXMKICBlcnJvcnMgPSBbXTsKICBpZighYXNuMS52YWxpZGF0ZShvYmosIHJzYVB1YmxpY0tleVZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBwdWJsaWMga2V5LiAnICsKICAgICAgJ0FTTi4xIG9iamVjdCBkb2VzIG5vdCBjb250YWluIGFuIFJTQVB1YmxpY0tleS4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gRklYTUU6IGluZWZmaWNpZW50LCBnZXQgYSBCaWdJbnRlZ2VyIHRoYXQgdXNlcyBieXRlIHN0cmluZ3MKICB2YXIgbiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHVibGljS2V5TW9kdWx1cykudG9IZXgoKTsKICB2YXIgZSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHVibGljS2V5RXhwb25lbnQpLnRvSGV4KCk7CgogIC8vIHNldCBwdWJsaWMga2V5CiAgcmV0dXJuIHBraS5zZXRSc2FQdWJsaWNLZXkoCiAgICBuZXcgQmlnSW50ZWdlcihuLCAxNiksCiAgICBuZXcgQmlnSW50ZWdlcihlLCAxNikpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgcHVibGljIGtleSB0byBhbiBBU04uMSBTdWJqZWN0UHVibGljS2V5SW5mby4KICoKICogQHBhcmFtIGtleSB0aGUgcHVibGljIGtleS4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIFN1YmplY3RQdWJsaWNLZXlJbmZvLgogKi8KcGtpLnB1YmxpY0tleVRvQXNuMSA9IHBraS5wdWJsaWNLZXlUb1N1YmplY3RQdWJsaWNLZXlJbmZvID0gZnVuY3Rpb24oa2V5KSB7CiAgLy8gU3ViamVjdFB1YmxpY0tleUluZm8KICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gQWxnb3JpdGhtSWRlbnRpZmllcgogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAvLyBhbGdvcml0aG0KICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgIGFzbjEub2lkVG9EZXIocGtpLm9pZHMucnNhRW5jcnlwdGlvbikuZ2V0Qnl0ZXMoKSksCiAgICAgIC8vIHBhcmFtZXRlcnMgKG51bGwpCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuTlVMTCwgZmFsc2UsICcnKQogICAgXSksCiAgICAvLyBzdWJqZWN0UHVibGljS2V5CiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLkJJVFNUUklORywgZmFsc2UsIFsKICAgICAgcGtpLnB1YmxpY0tleVRvUlNBUHVibGljS2V5KGtleSkKICAgIF0pCiAgXSk7Cn07CgovKioKICogQ29udmVydHMgYSBwdWJsaWMga2V5IHRvIGFuIEFTTi4xIFJTQVB1YmxpY0tleS4KICoKICogQHBhcmFtIGtleSB0aGUgcHVibGljIGtleS4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIFJTQVB1YmxpY0tleS4KICovCnBraS5wdWJsaWNLZXlUb1JTQVB1YmxpY0tleSA9IGZ1bmN0aW9uKGtleSkgewogIC8vIFJTQVB1YmxpY0tleQogIHJldHVybiBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyBtb2R1bHVzIChuKQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgX2JuVG9CeXRlcyhrZXkubikpLAogICAgLy8gcHVibGljRXhwb25lbnQgKGUpCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5lKSkKICBdKTsKfTsKCi8qKgogKiBFbmNvZGVzIGEgbWVzc2FnZSB1c2luZyBQS0NTIzEgdjEuNSBwYWRkaW5nLgogKgogKiBAcGFyYW0gbSB0aGUgbWVzc2FnZSB0byBlbmNvZGUuCiAqIEBwYXJhbSBrZXkgdGhlIFJTQSBrZXkgdG8gdXNlLgogKiBAcGFyYW0gYnQgdGhlIGJsb2NrIHR5cGUgdG8gdXNlLCBpLmUuIGVpdGhlciAweDAxIChmb3Igc2lnbmluZykgb3IgMHgwMgogKiAgICAgICAgICAoZm9yIGVuY3J5cHRpb24pLgogKgogKiBAcmV0dXJuIHRoZSBwYWRkZWQgYnl0ZSBidWZmZXIuCiAqLwpmdW5jdGlvbiBfZW5jb2RlUGtjczFfdjFfNShtLCBrZXksIGJ0KSB7CiAgdmFyIGViID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKCiAgLy8gZ2V0IHRoZSBsZW5ndGggb2YgdGhlIG1vZHVsdXMgaW4gYnl0ZXMKICB2YXIgayA9IE1hdGguY2VpbChrZXkubi5iaXRMZW5ndGgoKSAvIDgpOwoKICAvKiB1c2UgUEtDUyMxIHYxLjUgcGFkZGluZyAqLwogIGlmKG0ubGVuZ3RoID4gKGsgLSAxMSkpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignTWVzc2FnZSBpcyB0b28gbG9uZyBmb3IgUEtDUyMxIHYxLjUgcGFkZGluZy4nKTsKICAgIGVycm9yLmxlbmd0aCA9IG0ubGVuZ3RoOwogICAgZXJyb3IubWF4ID0gayAtIDExOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICAvKiBBIGJsb2NrIHR5cGUgQlQsIGEgcGFkZGluZyBzdHJpbmcgUFMsIGFuZCB0aGUgZGF0YSBEIHNoYWxsIGJlCiAgICBmb3JtYXR0ZWQgaW50byBhbiBvY3RldCBzdHJpbmcgRUIsIHRoZSBlbmNyeXB0aW9uIGJsb2NrOgoKICAgIEVCID0gMDAgfHwgQlQgfHwgUFMgfHwgMDAgfHwgRAoKICAgIFRoZSBibG9jayB0eXBlIEJUIHNoYWxsIGJlIGEgc2luZ2xlIG9jdGV0IGluZGljYXRpbmcgdGhlIHN0cnVjdHVyZSBvZgogICAgdGhlIGVuY3J5cHRpb24gYmxvY2suIEZvciB0aGlzIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50IGl0IHNoYWxsIGhhdmUKICAgIHZhbHVlIDAwLCAwMSwgb3IgMDIuIEZvciBhIHByaXZhdGUta2V5IG9wZXJhdGlvbiwgdGhlIGJsb2NrIHR5cGUKICAgIHNoYWxsIGJlIDAwIG9yIDAxLiBGb3IgYSBwdWJsaWMta2V5IG9wZXJhdGlvbiwgaXQgc2hhbGwgYmUgMDIuCgogICAgVGhlIHBhZGRpbmcgc3RyaW5nIFBTIHNoYWxsIGNvbnNpc3Qgb2Ygay0zLXx8RHx8IG9jdGV0cy4gRm9yIGJsb2NrCiAgICB0eXBlIDAwLCB0aGUgb2N0ZXRzIHNoYWxsIGhhdmUgdmFsdWUgMDA7IGZvciBibG9jayB0eXBlIDAxLCB0aGV5CiAgICBzaGFsbCBoYXZlIHZhbHVlIEZGOyBhbmQgZm9yIGJsb2NrIHR5cGUgMDIsIHRoZXkgc2hhbGwgYmUKICAgIHBzZXVkb3JhbmRvbWx5IGdlbmVyYXRlZCBhbmQgbm9uemVyby4gVGhpcyBtYWtlcyB0aGUgbGVuZ3RoIG9mIHRoZQogICAgZW5jcnlwdGlvbiBibG9jayBFQiBlcXVhbCB0byBrLiAqLwoKICAvLyBidWlsZCB0aGUgZW5jcnlwdGlvbiBibG9jawogIGViLnB1dEJ5dGUoMHgwMCk7CiAgZWIucHV0Qnl0ZShidCk7CgogIC8vIGNyZWF0ZSB0aGUgcGFkZGluZwogIHZhciBwYWROdW0gPSBrIC0gMyAtIG0ubGVuZ3RoOwogIHZhciBwYWRCeXRlOwogIC8vIHByaXZhdGUga2V5IG9wCiAgaWYoYnQgPT09IDB4MDAgfHwgYnQgPT09IDB4MDEpIHsKICAgIHBhZEJ5dGUgPSAoYnQgPT09IDB4MDApID8gMHgwMCA6IDB4RkY7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgcGFkTnVtOyArK2kpIHsKICAgICAgZWIucHV0Qnl0ZShwYWRCeXRlKTsKICAgIH0KICB9IGVsc2UgewogICAgLy8gcHVibGljIGtleSBvcAogICAgLy8gcGFkIHdpdGggcmFuZG9tIG5vbi16ZXJvIHZhbHVlcwogICAgd2hpbGUocGFkTnVtID4gMCkgewogICAgICB2YXIgbnVtWmVyb3MgPSAwOwogICAgICB2YXIgcGFkQnl0ZXMgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMocGFkTnVtKTsKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHBhZE51bTsgKytpKSB7CiAgICAgICAgcGFkQnl0ZSA9IHBhZEJ5dGVzLmNoYXJDb2RlQXQoaSk7CiAgICAgICAgaWYocGFkQnl0ZSA9PT0gMCkgewogICAgICAgICAgKytudW1aZXJvczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZWIucHV0Qnl0ZShwYWRCeXRlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcGFkTnVtID0gbnVtWmVyb3M7CiAgICB9CiAgfQoKICAvLyB6ZXJvIGZvbGxvd2VkIGJ5IG1lc3NhZ2UKICBlYi5wdXRCeXRlKDB4MDApOwogIGViLnB1dEJ5dGVzKG0pOwoKICByZXR1cm4gZWI7Cn0KCi8qKgogKiBEZWNvZGVzIGEgbWVzc2FnZSB1c2luZyBQS0NTIzEgdjEuNSBwYWRkaW5nLgogKgogKiBAcGFyYW0gZW0gdGhlIG1lc3NhZ2UgdG8gZGVjb2RlLgogKiBAcGFyYW0ga2V5IHRoZSBSU0Ega2V5IHRvIHVzZS4KICogQHBhcmFtIHB1YiB0cnVlIGlmIHRoZSBrZXkgaXMgYSBwdWJsaWMga2V5LCBmYWxzZSBpZiBpdCBpcyBwcml2YXRlLgogKiBAcGFyYW0gbWwgdGhlIG1lc3NhZ2UgbGVuZ3RoLCBpZiBzcGVjaWZpZWQuCiAqCiAqIEByZXR1cm4gdGhlIGRlY29kZWQgYnl0ZXMuCiAqLwpmdW5jdGlvbiBfZGVjb2RlUGtjczFfdjFfNShlbSwga2V5LCBwdWIsIG1sKSB7CiAgLy8gZ2V0IHRoZSBsZW5ndGggb2YgdGhlIG1vZHVsdXMgaW4gYnl0ZXMKICB2YXIgayA9IE1hdGguY2VpbChrZXkubi5iaXRMZW5ndGgoKSAvIDgpOwoKICAvKiBJdCBpcyBhbiBlcnJvciBpZiBhbnkgb2YgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIG9jY3VyczoKCiAgICAxLiBUaGUgZW5jcnlwdGlvbiBibG9jayBFQiBjYW5ub3QgYmUgcGFyc2VkIHVuYW1iaWd1b3VzbHkuCiAgICAyLiBUaGUgcGFkZGluZyBzdHJpbmcgUFMgY29uc2lzdHMgb2YgZmV3ZXIgdGhhbiBlaWdodCBvY3RldHMKICAgICAgb3IgaXMgaW5jb25zaXNlbnQgd2l0aCB0aGUgYmxvY2sgdHlwZSBCVC4KICAgIDMuIFRoZSBkZWNyeXB0aW9uIHByb2Nlc3MgaXMgYSBwdWJsaWMta2V5IG9wZXJhdGlvbiBhbmQgdGhlIGJsb2NrCiAgICAgIHR5cGUgQlQgaXMgbm90IDAwIG9yIDAxLCBvciB0aGUgZGVjcnlwdGlvbiBwcm9jZXNzIGlzIGEKICAgICAgcHJpdmF0ZS1rZXkgb3BlcmF0aW9uIGFuZCB0aGUgYmxvY2sgdHlwZSBpcyBub3QgMDIuCiAgICovCgogIC8vIHBhcnNlIHRoZSBlbmNyeXB0aW9uIGJsb2NrCiAgdmFyIGViID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoZW0pOwogIHZhciBmaXJzdCA9IGViLmdldEJ5dGUoKTsKICB2YXIgYnQgPSBlYi5nZXRCeXRlKCk7CiAgaWYoZmlyc3QgIT09IDB4MDAgfHwKICAgIChwdWIgJiYgYnQgIT09IDB4MDAgJiYgYnQgIT09IDB4MDEpIHx8CiAgICAoIXB1YiAmJiBidCAhPSAweDAyKSB8fAogICAgKHB1YiAmJiBidCA9PT0gMHgwMCAmJiB0eXBlb2YobWwpID09PSAndW5kZWZpbmVkJykpIHsKICAgIHRocm93IG5ldyBFcnJvcignRW5jcnlwdGlvbiBibG9jayBpcyBpbnZhbGlkLicpOwogIH0KCiAgdmFyIHBhZE51bSA9IDA7CiAgaWYoYnQgPT09IDB4MDApIHsKICAgIC8vIGNoZWNrIGFsbCBwYWRkaW5nIGJ5dGVzIGZvciAweDAwCiAgICBwYWROdW0gPSBrIC0gMyAtIG1sOwogICAgZm9yKHZhciBpID0gMDsgaSA8IHBhZE51bTsgKytpKSB7CiAgICAgIGlmKGViLmdldEJ5dGUoKSAhPT0gMHgwMCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcignRW5jcnlwdGlvbiBibG9jayBpcyBpbnZhbGlkLicpOwogICAgICB9CiAgICB9CiAgfSBlbHNlIGlmKGJ0ID09PSAweDAxKSB7CiAgICAvLyBmaW5kIHRoZSBmaXJzdCBieXRlIHRoYXQgaXNuJ3QgMHhGRiwgc2hvdWxkIGJlIGFmdGVyIGFsbCBwYWRkaW5nCiAgICBwYWROdW0gPSAwOwogICAgd2hpbGUoZWIubGVuZ3RoKCkgPiAxKSB7CiAgICAgIGlmKGViLmdldEJ5dGUoKSAhPT0gMHhGRikgewogICAgICAgIC0tZWIucmVhZDsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICArK3BhZE51bTsKICAgIH0KICB9IGVsc2UgaWYoYnQgPT09IDB4MDIpIHsKICAgIC8vIGxvb2sgZm9yIDB4MDAgYnl0ZQogICAgcGFkTnVtID0gMDsKICAgIHdoaWxlKGViLmxlbmd0aCgpID4gMSkgewogICAgICBpZihlYi5nZXRCeXRlKCkgPT09IDB4MDApIHsKICAgICAgICAtLWViLnJlYWQ7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgKytwYWROdW07CiAgICB9CiAgfQoKICAvLyB6ZXJvIG11c3QgYmUgMHgwMCBhbmQgcGFkTnVtIG11c3QgYmUgKGsgLSAzIC0gbWVzc2FnZSBsZW5ndGgpCiAgdmFyIHplcm8gPSBlYi5nZXRCeXRlKCk7CiAgaWYoemVybyAhPT0gMHgwMCB8fCBwYWROdW0gIT09IChrIC0gMyAtIGViLmxlbmd0aCgpKSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdFbmNyeXB0aW9uIGJsb2NrIGlzIGludmFsaWQuJyk7CiAgfQoKICByZXR1cm4gZWIuZ2V0Qnl0ZXMoKTsKfQoKLyoqCiAqIFJ1bnMgdGhlIGtleS1nZW5lcmF0aW9uIGFsZ29yaXRobSBhc3luY2hyb25vdXNseSwgZWl0aGVyIGluIHRoZSBiYWNrZ3JvdW5kCiAqIHZpYSBXZWIgV29ya2Vycywgb3IgdXNpbmcgdGhlIG1haW4gdGhyZWFkIGFuZCBzZXRJbW1lZGlhdGUuCiAqCiAqIEBwYXJhbSBzdGF0ZSB0aGUga2V5LXBhaXIgZ2VuZXJhdGlvbiBzdGF0ZS4KICogQHBhcmFtIFtvcHRpb25zXSBvcHRpb25zIGZvciBrZXktcGFpciBnZW5lcmF0aW9uOgogKiAgICAgICAgICB3b3JrZXJTY3JpcHQgdGhlIHdvcmtlciBzY3JpcHQgVVJMLgogKiAgICAgICAgICB3b3JrZXJzIHRoZSBudW1iZXIgb2Ygd2ViIHdvcmtlcnMgKGlmIHN1cHBvcnRlZCkgdG8gdXNlLAogKiAgICAgICAgICAgIChkZWZhdWx0OiAyLCAtMSB0byB1c2UgZXN0aW1hdGVkIGNvcmVzIG1pbnVzIG9uZSkuCiAqICAgICAgICAgIHdvcmtMb2FkIHRoZSBzaXplIG9mIHRoZSB3b3JrIGxvYWQsIGllOiBudW1iZXIgb2YgcG9zc2libGUgcHJpbWUKICogICAgICAgICAgICBudW1iZXJzIGZvciBlYWNoIHdlYiB3b3JrZXIgdG8gY2hlY2sgcGVyIHdvcmsgYXNzaWdubWVudCwKICogICAgICAgICAgICAoZGVmYXVsdDogMTAwKS4KICogQHBhcmFtIGNhbGxiYWNrKGVyciwga2V5cGFpcikgY2FsbGVkIG9uY2UgdGhlIG9wZXJhdGlvbiBjb21wbGV0ZXMuCiAqLwpmdW5jdGlvbiBfZ2VuZXJhdGVLZXlQYWlyKHN0YXRlLCBvcHRpb25zLCBjYWxsYmFjaykgewogIGlmKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nKSB7CiAgICBjYWxsYmFjayA9IG9wdGlvbnM7CiAgICBvcHRpb25zID0ge307CiAgfQogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwoKICB2YXIgb3B0cyA9IHsKICAgIGFsZ29yaXRobTogewogICAgICBuYW1lOiBvcHRpb25zLmFsZ29yaXRobSB8fCAnUFJJTUVJTkMnLAogICAgICBvcHRpb25zOiB7CiAgICAgICAgd29ya2Vyczogb3B0aW9ucy53b3JrZXJzIHx8IDIsCiAgICAgICAgd29ya0xvYWQ6IG9wdGlvbnMud29ya0xvYWQgfHwgMTAwLAogICAgICAgIHdvcmtlclNjcmlwdDogb3B0aW9ucy53b3JrZXJTY3JpcHQKICAgICAgfQogICAgfQogIH07CiAgaWYoJ3BybmcnIGluIG9wdGlvbnMpIHsKICAgIG9wdHMucHJuZyA9IG9wdGlvbnMucHJuZzsKICB9CgogIGdlbmVyYXRlKCk7CgogIGZ1bmN0aW9uIGdlbmVyYXRlKCkgewogICAgLy8gZmluZCBwIGFuZCB0aGVuIHEgKGRvbmUgaW4gc2VyaWVzIHRvIHNpbXBsaWZ5KQogICAgZ2V0UHJpbWUoc3RhdGUucEJpdHMsIGZ1bmN0aW9uKGVyciwgbnVtKSB7CiAgICAgIGlmKGVycikgewogICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpOwogICAgICB9CiAgICAgIHN0YXRlLnAgPSBudW07CiAgICAgIGlmKHN0YXRlLnEgIT09IG51bGwpIHsKICAgICAgICByZXR1cm4gZmluaXNoKGVyciwgc3RhdGUucSk7CiAgICAgIH0KICAgICAgZ2V0UHJpbWUoc3RhdGUucUJpdHMsIGZpbmlzaCk7CiAgICB9KTsKICB9CgogIGZ1bmN0aW9uIGdldFByaW1lKGJpdHMsIGNhbGxiYWNrKSB7CiAgICBmb3JnZS5wcmltZS5nZW5lcmF0ZVByb2JhYmxlUHJpbWUoYml0cywgb3B0cywgY2FsbGJhY2spOwogIH0KCiAgZnVuY3Rpb24gZmluaXNoKGVyciwgbnVtKSB7CiAgICBpZihlcnIpIHsKICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7CiAgICB9CgogICAgLy8gc2V0IHEKICAgIHN0YXRlLnEgPSBudW07CgogICAgLy8gZW5zdXJlIHAgaXMgbGFyZ2VyIHRoYW4gcSAoc3dhcCB0aGVtIGlmIG5vdCkKICAgIGlmKHN0YXRlLnAuY29tcGFyZVRvKHN0YXRlLnEpIDwgMCkgewogICAgICB2YXIgdG1wID0gc3RhdGUucDsKICAgICAgc3RhdGUucCA9IHN0YXRlLnE7CiAgICAgIHN0YXRlLnEgPSB0bXA7CiAgICB9CgogICAgLy8gZW5zdXJlIHAgaXMgY29wcmltZSB3aXRoIGUKICAgIGlmKHN0YXRlLnAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpLmdjZChzdGF0ZS5lKQogICAgICAuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPT0gMCkgewogICAgICBzdGF0ZS5wID0gbnVsbDsKICAgICAgZ2VuZXJhdGUoKTsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIGVuc3VyZSBxIGlzIGNvcHJpbWUgd2l0aCBlCiAgICBpZihzdGF0ZS5xLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKS5nY2Qoc3RhdGUuZSkKICAgICAgLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT09IDApIHsKICAgICAgc3RhdGUucSA9IG51bGw7CiAgICAgIGdldFByaW1lKHN0YXRlLnFCaXRzLCBmaW5pc2gpOwogICAgICByZXR1cm47CiAgICB9CgogICAgLy8gY29tcHV0ZSBwaGk6IChwIC0gMSkocSAtIDEpIChFdWxlcidzIHRvdGllbnQgZnVuY3Rpb24pCiAgICBzdGF0ZS5wMSA9IHN0YXRlLnAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpOwogICAgc3RhdGUucTEgPSBzdGF0ZS5xLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTsKICAgIHN0YXRlLnBoaSA9IHN0YXRlLnAxLm11bHRpcGx5KHN0YXRlLnExKTsKCiAgICAvLyBlbnN1cmUgZSBhbmQgcGhpIGFyZSBjb3ByaW1lCiAgICBpZihzdGF0ZS5waGkuZ2NkKHN0YXRlLmUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT09IDApIHsKICAgICAgLy8gcGhpIGFuZCBlIGFyZW4ndCBjb3ByaW1lLCBzbyBnZW5lcmF0ZSBhIG5ldyBwIGFuZCBxCiAgICAgIHN0YXRlLnAgPSBzdGF0ZS5xID0gbnVsbDsKICAgICAgZ2VuZXJhdGUoKTsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIGNyZWF0ZSBuLCBlbnN1cmUgbiBpcyBoYXMgdGhlIHJpZ2h0IG51bWJlciBvZiBiaXRzCiAgICBzdGF0ZS5uID0gc3RhdGUucC5tdWx0aXBseShzdGF0ZS5xKTsKICAgIGlmKHN0YXRlLm4uYml0TGVuZ3RoKCkgIT09IHN0YXRlLmJpdHMpIHsKICAgICAgLy8gZmFpbGVkLCBnZXQgbmV3IHEKICAgICAgc3RhdGUucSA9IG51bGw7CiAgICAgIGdldFByaW1lKHN0YXRlLnFCaXRzLCBmaW5pc2gpOwogICAgICByZXR1cm47CiAgICB9CgogICAgLy8gc2V0IGtleXMKICAgIHZhciBkID0gc3RhdGUuZS5tb2RJbnZlcnNlKHN0YXRlLnBoaSk7CiAgICBzdGF0ZS5rZXlzID0gewogICAgICBwcml2YXRlS2V5OiBwa2kucnNhLnNldFByaXZhdGVLZXkoCiAgICAgICAgc3RhdGUubiwgc3RhdGUuZSwgZCwgc3RhdGUucCwgc3RhdGUucSwKICAgICAgICBkLm1vZChzdGF0ZS5wMSksIGQubW9kKHN0YXRlLnExKSwKICAgICAgICBzdGF0ZS5xLm1vZEludmVyc2Uoc3RhdGUucCkpLAogICAgICBwdWJsaWNLZXk6IHBraS5yc2Euc2V0UHVibGljS2V5KHN0YXRlLm4sIHN0YXRlLmUpCiAgICB9OwoKICAgIGNhbGxiYWNrKG51bGwsIHN0YXRlLmtleXMpOwogIH0KfQoKLyoqCiAqIENvbnZlcnRzIGEgcG9zaXRpdmUgQmlnSW50ZWdlciBpbnRvIDIncy1jb21wbGVtZW50IGJpZy1lbmRpYW4gYnl0ZXMuCiAqCiAqIEBwYXJhbSBiIHRoZSBiaWcgaW50ZWdlciB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBieXRlcy4KICovCmZ1bmN0aW9uIF9iblRvQnl0ZXMoYikgewogIC8vIHByZXBlbmQgMHgwMCBpZiBmaXJzdCBieXRlID49IDB4ODAKICB2YXIgaGV4ID0gYi50b1N0cmluZygxNik7CiAgaWYoaGV4WzBdID49ICc4JykgewogICAgaGV4ID0gJzAwJyArIGhleDsKICB9CiAgcmV0dXJuIGZvcmdlLnV0aWwuaGV4VG9CeXRlcyhoZXgpOwp9CgovKioKICogUmV0dXJucyB0aGUgcmVxdWlyZWQgbnVtYmVyIG9mIE1pbGxlci1SYWJpbiB0ZXN0cyB0byBnZW5lcmF0ZSBhCiAqIHByaW1lIHdpdGggYW4gZXJyb3IgcHJvYmFiaWxpdHkgb2YgKDEvMileODAuCiAqCiAqIFNlZSBIYW5kYm9vayBvZiBBcHBsaWVkIENyeXB0b2dyYXBoeSBDaGFwdGVyIDQsIFRhYmxlIDQuNC4KICoKICogQHBhcmFtIGJpdHMgdGhlIGJpdCBzaXplLgogKgogKiBAcmV0dXJuIHRoZSByZXF1aXJlZCBudW1iZXIgb2YgaXRlcmF0aW9ucy4KICovCmZ1bmN0aW9uIF9nZXRNaWxsZXJSYWJpblRlc3RzKGJpdHMpIHsKICBpZihiaXRzIDw9IDEwMCkgcmV0dXJuIDI3OwogIGlmKGJpdHMgPD0gMTUwKSByZXR1cm4gMTg7CiAgaWYoYml0cyA8PSAyMDApIHJldHVybiAxNTsKICBpZihiaXRzIDw9IDI1MCkgcmV0dXJuIDEyOwogIGlmKGJpdHMgPD0gMzAwKSByZXR1cm4gOTsKICBpZihiaXRzIDw9IDM1MCkgcmV0dXJuIDg7CiAgaWYoYml0cyA8PSA0MDApIHJldHVybiA3OwogIGlmKGJpdHMgPD0gNTAwKSByZXR1cm4gNjsKICBpZihiaXRzIDw9IDYwMCkgcmV0dXJuIDU7CiAgaWYoYml0cyA8PSA4MDApIHJldHVybiA0OwogIGlmKGJpdHMgPD0gMTI1MCkgcmV0dXJuIDM7CiAgcmV0dXJuIDI7Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3JzYSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9yc2EnLFsKICAncmVxdWlyZScsCiAgJ21vZHVsZScsCiAgJy4vYXNuMScsCiAgJy4vanNibicsCiAgJy4vb2lkcycsCiAgJy4vcGtjczEnLAogICcuL3ByaW1lJywKICAnLi9yYW5kb20nLAogICcuL3V0aWwnCl0sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFBhc3N3b3JkLWJhc2VkIGVuY3J5cHRpb24gZnVuY3Rpb25zLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKiBAYXV0aG9yIFN0ZWZhbiBTaWVnbCA8c3Rlc2llQGJyb2tlbnBpcGUuZGU+CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEzIERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqIENvcHlyaWdodCAoYykgMjAxMiBTdGVmYW4gU2llZ2wgPHN0ZXNpZUBicm9rZW5waXBlLmRlPgogKgogKiBBbiBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbzoKICoKICogRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gOjo9IFNFUVVFTkNFIHsKICogICBlbmNyeXB0aW9uQWxnb3JpdGhtICBFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciwKICogICBlbmNyeXB0ZWREYXRhICAgICAgICBFbmNyeXB0ZWREYXRhIH0KICoKICogRW5jcnlwdGlvbkFsZ29yaXRobUlkZW50aWZpZXIgOjo9IEFsZ29yaXRobUlkZW50aWZpZXIKICoKICogRW5jcnlwdGVkRGF0YSA6Oj0gT0NURVQgU1RSSU5HCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKaWYodHlwZW9mIEJpZ0ludGVnZXIgPT09ICd1bmRlZmluZWQnKSB7CiAgdmFyIEJpZ0ludGVnZXIgPSBmb3JnZS5qc2JuLkJpZ0ludGVnZXI7Cn0KCi8vIHNob3J0Y3V0IGZvciBhc24uMSBBUEkKdmFyIGFzbjEgPSBmb3JnZS5hc24xOwoKLyogUGFzc3dvcmQtYmFzZWQgZW5jcnlwdGlvbiBpbXBsZW1lbnRhdGlvbi4gKi8KdmFyIHBraSA9IGZvcmdlLnBraSA9IGZvcmdlLnBraSB8fCB7fTsKcGtpLnBiZSA9IGZvcmdlLnBiZSA9IGZvcmdlLnBiZSB8fCB7fTsKdmFyIG9pZHMgPSBwa2kub2lkczsKCi8vIHZhbGlkYXRvciBmb3IgYW4gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gc3RydWN0dXJlCi8vIE5vdGU6IEN1cnJlbnRseSBvbmx5IHdvcmtzIHcvYWxnb3JpdGhtIHBhcmFtcwp2YXIgZW5jcnlwdGVkUHJpdmF0ZUtleVZhbGlkYXRvciA9IHsKICBuYW1lOiAnRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8nLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uZW5jcnlwdGlvbkFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnQWxnb3JpdGhtSWRlbnRpZmllci5hbGdvcml0aG0nLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2VuY3J5cHRpb25PaWQnCiAgICB9LCB7CiAgICAgIG5hbWU6ICdBbGdvcml0aG1JZGVudGlmaWVyLnBhcmFtZXRlcnMnLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIGNhcHR1cmVBc24xOiAnZW5jcnlwdGlvblBhcmFtcycKICAgIH1dCiAgfSwgewogICAgLy8gZW5jcnlwdGVkRGF0YQogICAgbmFtZTogJ0VuY3J5cHRlZFByaXZhdGVLZXlJbmZvLmVuY3J5cHRlZERhdGEnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2VuY3J5cHRlZERhdGEnCiAgfV0KfTsKCi8vIHZhbGlkYXRvciBmb3IgYSBQQkVTMkFsZ29yaXRobXMgc3RydWN0dXJlCi8vIE5vdGU6IEN1cnJlbnRseSBvbmx5IHdvcmtzIHcvUEJLREYyICsgQUVTIGVuY3J5cHRpb24gc2NoZW1lcwp2YXIgUEJFUzJBbGdvcml0aG1zVmFsaWRhdG9yID0gewogIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnUEJFUzJBbGdvcml0aG1zLmtleURlcml2YXRpb25GdW5jJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMua2V5RGVyaXZhdGlvbkZ1bmMub2lkJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdrZGZPaWQnCiAgICB9LCB7CiAgICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMucGFyYW1zJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAnUEJFUzJBbGdvcml0aG1zLnBhcmFtcy5zYWx0JywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBjYXB0dXJlOiAna2RmU2FsdCcKICAgICAgfSwgewogICAgICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMucGFyYW1zLml0ZXJhdGlvbkNvdW50JywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgICAgb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgICBjYXB0dXJlOiAna2RmSXRlcmF0aW9uQ291bnQnCiAgICAgIH1dCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMuZW5jcnlwdGlvblNjaGVtZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnUEJFUzJBbGdvcml0aG1zLmVuY3J5cHRpb25TY2hlbWUub2lkJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdlbmNPaWQnCiAgICB9LCB7CiAgICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMuZW5jcnlwdGlvblNjaGVtZS5pdicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdlbmNJdicKICAgIH1dCiAgfV0KfTsKCnZhciBwa2NzMTJQYmVQYXJhbXNWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ3BrY3MtMTJQYmVQYXJhbXMnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAncGtjcy0xMlBiZVBhcmFtcy5zYWx0JywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5PQ1RFVFNUUklORywKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdzYWx0JwogIH0sIHsKICAgIG5hbWU6ICdwa2NzLTEyUGJlUGFyYW1zLml0ZXJhdGlvbnMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAnaXRlcmF0aW9ucycKICB9XQp9OwoKLyoqCiAqIEVuY3J5cHRzIGEgQVNOLjEgUHJpdmF0ZUtleUluZm8gb2JqZWN0LCBwcm9kdWNpbmcgYW4gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uCiAqCiAqIFBCRVMyQWxnb3JpdGhtcyBBTEdPUklUSE0tSURFTlRJRklFUiA6Oj0KICogICB7IHtQQkVTMi1wYXJhbXMgSURFTlRJRklFRCBCWSBpZC1QQkVTMn0sIC4uLn0KICoKICogaWQtUEJFUzIgT0JKRUNUIElERU5USUZJRVIgOjo9IHtwa2NzLTUgMTN9CiAqCiAqIFBCRVMyLXBhcmFtcyA6Oj0gU0VRVUVOQ0UgewogKiAgIGtleURlcml2YXRpb25GdW5jIEFsZ29yaXRobUlkZW50aWZpZXIge3tQQkVTMi1LREZzfX0sCiAqICAgZW5jcnlwdGlvblNjaGVtZSBBbGdvcml0aG1JZGVudGlmaWVyIHt7UEJFUzItRW5jc319CiAqIH0KICoKICogUEJFUzItS0RGcyBBTEdPUklUSE0tSURFTlRJRklFUiA6Oj0KICogICB7IHtQQktERjItcGFyYW1zIElERU5USUZJRUQgQlkgaWQtUEJLREYyfSwgLi4uIH0KICoKICogUEJFUzItRW5jcyBBTEdPUklUSE0tSURFTlRJRklFUiA6Oj0geyAuLi4gfQogKgogKiBQQktERjItcGFyYW1zIDo6PSBTRVFVRU5DRSB7CiAqICAgc2FsdCBDSE9JQ0UgewogKiAgICAgc3BlY2lmaWVkIE9DVEVUIFNUUklORywKICogICAgIG90aGVyU291cmNlIEFsZ29yaXRobUlkZW50aWZpZXIge3tQQktERjItU2FsdFNvdXJjZXN9fQogKiAgIH0sCiAqICAgaXRlcmF0aW9uQ291bnQgSU5URUdFUiAoMS4uTUFYKSwKICogICBrZXlMZW5ndGggSU5URUdFUiAoMS4uTUFYKSBPUFRJT05BTCwKICogICBwcmYgQWxnb3JpdGhtSWRlbnRpZmllciB7e1BCS0RGMi1QUkZzfX0gREVGQVVMVCBhbGdpZC1obWFjV2l0aFNIQTEKICogfQogKgogKiBAcGFyYW0gb2JqIHRoZSBBU04uMSBQcml2YXRlS2V5SW5mbyBvYmplY3QuCiAqIEBwYXJhbSBwYXNzd29yZCB0aGUgcGFzc3dvcmQgdG8gZW5jcnlwdCB3aXRoLgogKiBAcGFyYW0gb3B0aW9uczoKICogICAgICAgICAgYWxnb3JpdGhtIHRoZSBlbmNyeXB0aW9uIGFsZ29yaXRobSB0byB1c2UKICogICAgICAgICAgICAoJ2FlczEyOCcsICdhZXMxOTInLCAnYWVzMjU2JywgJzNkZXMnKSwgZGVmYXVsdHMgdG8gJ2FlczEyOCcuCiAqICAgICAgICAgIGNvdW50IHRoZSBpdGVyYXRpb24gY291bnQgdG8gdXNlLgogKiAgICAgICAgICBzYWx0U2l6ZSB0aGUgc2FsdCBzaXplIHRvIHVzZS4KICoKICogQHJldHVybiB0aGUgQVNOLjEgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uCiAqLwpwa2kuZW5jcnlwdFByaXZhdGVLZXlJbmZvID0gZnVuY3Rpb24ob2JqLCBwYXNzd29yZCwgb3B0aW9ucykgewogIC8vIHNldCBkZWZhdWx0IG9wdGlvbnMKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICBvcHRpb25zLnNhbHRTaXplID0gb3B0aW9ucy5zYWx0U2l6ZSB8fCA4OwogIG9wdGlvbnMuY291bnQgPSBvcHRpb25zLmNvdW50IHx8IDIwNDg7CiAgb3B0aW9ucy5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobSB8fCAnYWVzMTI4JzsKCiAgLy8gZ2VuZXJhdGUgUEJFIHBhcmFtcwogIHZhciBzYWx0ID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzU3luYyhvcHRpb25zLnNhbHRTaXplKTsKICB2YXIgY291bnQgPSBvcHRpb25zLmNvdW50OwogIHZhciBjb3VudEJ5dGVzID0gYXNuMS5pbnRlZ2VyVG9EZXIoY291bnQpOwogIHZhciBka0xlbjsKICB2YXIgZW5jcnlwdGlvbkFsZ29yaXRobTsKICB2YXIgZW5jcnlwdGVkRGF0YTsKICBpZihvcHRpb25zLmFsZ29yaXRobS5pbmRleE9mKCdhZXMnKSA9PT0gMCB8fCBvcHRpb25zLmFsZ29yaXRobSA9PT0gJ2RlcycpIHsKICAgIC8vIERvIFBCRVMyCiAgICB2YXIgaXZMZW4sIGVuY09pZCwgY2lwaGVyRm47CiAgICBzd2l0Y2gob3B0aW9ucy5hbGdvcml0aG0pIHsKICAgIGNhc2UgJ2FlczEyOCc6CiAgICAgIGRrTGVuID0gMTY7CiAgICAgIGl2TGVuID0gMTY7CiAgICAgIGVuY09pZCA9IG9pZHNbJ2FlczEyOC1DQkMnXTsKICAgICAgY2lwaGVyRm4gPSBmb3JnZS5hZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgICAgYnJlYWs7CiAgICBjYXNlICdhZXMxOTInOgogICAgICBka0xlbiA9IDI0OwogICAgICBpdkxlbiA9IDE2OwogICAgICBlbmNPaWQgPSBvaWRzWydhZXMxOTItQ0JDJ107CiAgICAgIGNpcGhlckZuID0gZm9yZ2UuYWVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnYWVzMjU2JzoKICAgICAgZGtMZW4gPSAzMjsKICAgICAgaXZMZW4gPSAxNjsKICAgICAgZW5jT2lkID0gb2lkc1snYWVzMjU2LUNCQyddOwogICAgICBjaXBoZXJGbiA9IGZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyOwogICAgICBicmVhazsKICAgIGNhc2UgJ2Rlcyc6CiAgICAgIGRrTGVuID0gODsKICAgICAgaXZMZW4gPSA4OwogICAgICBlbmNPaWQgPSBvaWRzWydkZXNDQkMnXTsKICAgICAgY2lwaGVyRm4gPSBmb3JnZS5kZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCBlbmNyeXB0IHByaXZhdGUga2V5LiBVbmtub3duIGVuY3J5cHRpb24gYWxnb3JpdGhtLicpOwogICAgICBlcnJvci5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobTsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLy8gZW5jcnlwdCBwcml2YXRlIGtleSB1c2luZyBwYmUgU0hBLTEgYW5kIEFFUy9ERVMKICAgIHZhciBkayA9IGZvcmdlLnBrY3M1LnBia2RmMihwYXNzd29yZCwgc2FsdCwgY291bnQsIGRrTGVuKTsKICAgIHZhciBpdiA9IGZvcmdlLnJhbmRvbS5nZXRCeXRlc1N5bmMoaXZMZW4pOwogICAgdmFyIGNpcGhlciA9IGNpcGhlckZuKGRrKTsKICAgIGNpcGhlci5zdGFydChpdik7CiAgICBjaXBoZXIudXBkYXRlKGFzbjEudG9EZXIob2JqKSk7CiAgICBjaXBoZXIuZmluaXNoKCk7CiAgICBlbmNyeXB0ZWREYXRhID0gY2lwaGVyLm91dHB1dC5nZXRCeXRlcygpOwoKICAgIGVuY3J5cHRpb25BbGdvcml0aG0gPSBhc24xLmNyZWF0ZSgKICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0RlcihvaWRzWydwa2NzNVBCRVMyJ10pLmdldEJ5dGVzKCkpLAogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8ga2V5RGVyaXZhdGlvbkZ1bmMKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgICAgIGFzbjEub2lkVG9EZXIob2lkc1sncGtjczVQQktERjInXSkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgICAvLyBQQktERjItcGFyYW1zCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICAgIC8vIHNhbHQKICAgICAgICAgICAgYXNuMS5jcmVhdGUoCiAgICAgICAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIHNhbHQpLAogICAgICAgICAgICAvLyBpdGVyYXRpb24gY291bnQKICAgICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgICAgICAgICBjb3VudEJ5dGVzLmdldEJ5dGVzKCkpCiAgICAgICAgICBdKQogICAgICAgIF0pLAogICAgICAgIC8vIGVuY3J5cHRpb25TY2hlbWUKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgICAgIGFzbjEub2lkVG9EZXIoZW5jT2lkKS5nZXRCeXRlcygpKSwKICAgICAgICAgIC8vIGl2CiAgICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIGl2KQogICAgICAgIF0pCiAgICAgIF0pCiAgICBdKTsKICB9IGVsc2UgaWYob3B0aW9ucy5hbGdvcml0aG0gPT09ICczZGVzJykgewogICAgLy8gRG8gUEtDUzEyIFBCRQogICAgZGtMZW4gPSAyNDsKCiAgICB2YXIgc2FsdEJ5dGVzID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcihzYWx0KTsKICAgIHZhciBkayA9IHBraS5wYmUuZ2VuZXJhdGVQa2NzMTJLZXkocGFzc3dvcmQsIHNhbHRCeXRlcywgMSwgY291bnQsIGRrTGVuKTsKICAgIHZhciBpdiA9IHBraS5wYmUuZ2VuZXJhdGVQa2NzMTJLZXkocGFzc3dvcmQsIHNhbHRCeXRlcywgMiwgY291bnQsIGRrTGVuKTsKICAgIHZhciBjaXBoZXIgPSBmb3JnZS5kZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcihkayk7CiAgICBjaXBoZXIuc3RhcnQoaXYpOwogICAgY2lwaGVyLnVwZGF0ZShhc24xLnRvRGVyKG9iaikpOwogICAgY2lwaGVyLmZpbmlzaCgpOwogICAgZW5jcnlwdGVkRGF0YSA9IGNpcGhlci5vdXRwdXQuZ2V0Qnl0ZXMoKTsKCiAgICBlbmNyeXB0aW9uQWxnb3JpdGhtID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgIGFzbjEub2lkVG9EZXIob2lkc1sncGJlV2l0aFNIQUFuZDMtS2V5VHJpcGxlREVTLUNCQyddKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGtjcy0xMlBiZVBhcmFtcwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8gc2FsdAogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLCBzYWx0KSwKICAgICAgICAvLyBpdGVyYXRpb24gY291bnQKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICAgICAgY291bnRCeXRlcy5nZXRCeXRlcygpKQogICAgICBdKQogICAgXSk7CiAgfSBlbHNlIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IGVuY3J5cHQgcHJpdmF0ZSBrZXkuIFVua25vd24gZW5jcnlwdGlvbiBhbGdvcml0aG0uJyk7CiAgICBlcnJvci5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobTsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8KICB2YXIgcnZhbCA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgIC8vIGVuY3J5cHRpb25BbGdvcml0aG0KICAgIGVuY3J5cHRpb25BbGdvcml0aG0sCiAgICAvLyBlbmNyeXB0ZWREYXRhCiAgICBhc24xLmNyZWF0ZSgKICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIGVuY3J5cHRlZERhdGEpCiAgXSk7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogRGVjcnlwdHMgYSBBU04uMSBQcml2YXRlS2V5SW5mbyBvYmplY3QuCiAqCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIG9iamVjdC4KICogQHBhcmFtIHBhc3N3b3JkIHRoZSBwYXNzd29yZCB0byBkZWNyeXB0IHdpdGguCiAqCiAqIEByZXR1cm4gdGhlIEFTTi4xIFByaXZhdGVLZXlJbmZvIG9uIHN1Y2Nlc3MsIG51bGwgb24gZmFpbHVyZS4KICovCnBraS5kZWNyeXB0UHJpdmF0ZUtleUluZm8gPSBmdW5jdGlvbihvYmosIHBhc3N3b3JkKSB7CiAgdmFyIHJ2YWwgPSBudWxsOwoKICAvLyBnZXQgUEJFIHBhcmFtcwogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgZW5jcnlwdGVkUHJpdmF0ZUtleVZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBlbmNyeXB0ZWQgcHJpdmF0ZSBrZXkuICcgKwogICAgICAnQVNOLjEgb2JqZWN0IGlzIG5vdCBhIHN1cHBvcnRlZCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mby4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gZ2V0IGNpcGhlcgogIHZhciBvaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUuZW5jcnlwdGlvbk9pZCk7CiAgdmFyIGNpcGhlciA9IHBraS5wYmUuZ2V0Q2lwaGVyKG9pZCwgY2FwdHVyZS5lbmNyeXB0aW9uUGFyYW1zLCBwYXNzd29yZCk7CgogIC8vIGdldCBlbmNyeXB0ZWQgZGF0YQogIHZhciBlbmNyeXB0ZWQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLmVuY3J5cHRlZERhdGEpOwoKICBjaXBoZXIudXBkYXRlKGVuY3J5cHRlZCk7CiAgaWYoY2lwaGVyLmZpbmlzaCgpKSB7CiAgICBydmFsID0gYXNuMS5mcm9tRGVyKGNpcGhlci5vdXRwdXQpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ29udmVydHMgYSBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyB0byBQRU0gZm9ybWF0LgogKgogKiBAcGFyYW0gZXBraSB0aGUgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uCiAqIEBwYXJhbSBtYXhsaW5lIHRoZSBtYXhpbXVtIGNoYXJhY3RlcnMgcGVyIGxpbmUsIGRlZmF1bHRzIHRvIDY0LgogKgogKiBAcmV0dXJuIHRoZSBQRU0tZm9ybWF0dGVkIGVuY3J5cHRlZCBwcml2YXRlIGtleS4KICovCnBraS5lbmNyeXB0ZWRQcml2YXRlS2V5VG9QZW0gPSBmdW5jdGlvbihlcGtpLCBtYXhsaW5lKSB7CiAgLy8gY29udmVydCB0byBERVIsIHRoZW4gUEVNLWVuY29kZQogIHZhciBtc2cgPSB7CiAgICB0eXBlOiAnRU5DUllQVEVEIFBSSVZBVEUgS0VZJywKICAgIGJvZHk6IGFzbjEudG9EZXIoZXBraSkuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnLCB7bWF4bGluZTogbWF4bGluZX0pOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgUEVNLWVuY29kZWQgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gdG8gQVNOLjEgZm9ybWF0LiBEZWNyeXB0aW9uCiAqIGlzIG5vdCBwZXJmb3JtZWQuCiAqCiAqIEBwYXJhbSBwZW0gdGhlIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGluIFBFTS1mb3JtYXQuCiAqCiAqIEByZXR1cm4gdGhlIEFTTi4xIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvLgogKi8KcGtpLmVuY3J5cHRlZFByaXZhdGVLZXlGcm9tUGVtID0gZnVuY3Rpb24ocGVtKSB7CiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKCiAgaWYobXNnLnR5cGUgIT09ICdFTkNSWVBURUQgUFJJVkFURSBLRVknKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IGVuY3J5cHRlZCBwcml2YXRlIGtleSBmcm9tIFBFTTsgJyArCiAgICAgICdQRU0gaGVhZGVyIHR5cGUgaXMgIkVOQ1JZUFRFRCBQUklWQVRFIEtFWSIuJyk7CiAgICBlcnJvci5oZWFkZXJUeXBlID0gbXNnLnR5cGU7CiAgICB0aHJvdyBlcnJvcjsKICB9CiAgaWYobXNnLnByb2NUeXBlICYmIG1zZy5wcm9jVHlwZS50eXBlID09PSAnRU5DUllQVEVEJykgewogICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgY29udmVydCBlbmNyeXB0ZWQgcHJpdmF0ZSBrZXkgZnJvbSBQRU07ICcgKwogICAgICAnUEVNIGlzIGVuY3J5cHRlZC4nKTsKICB9CgogIC8vIGNvbnZlcnQgREVSIHRvIEFTTi4xIG9iamVjdAogIHJldHVybiBhc24xLmZyb21EZXIobXNnLmJvZHkpOwp9OwoKLyoqCiAqIEVuY3J5cHRzIGFuIFJTQSBwcml2YXRlIGtleS4gQnkgZGVmYXVsdCwgdGhlIGtleSB3aWxsIGJlIHdyYXBwZWQgaW4KICogYSBQcml2YXRlS2V5SW5mbyBhbmQgZW5jcnlwdGVkIHRvIHByb2R1Y2UgYSBQS0NTIzggRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uCiAqIFRoaXMgaXMgdGhlIHN0YW5kYXJkLCBwcmVmZXJyZWQgd2F5IHRvIGVuY3J5cHQgYSBwcml2YXRlIGtleS4KICoKICogVG8gcHJvZHVjZSBhIG5vbi1zdGFuZGFyZCBQRU0tZW5jcnlwdGVkIHByaXZhdGUga2V5IHRoYXQgdXNlcyBlbmNhcHN1bGF0ZWQKICogaGVhZGVycyB0byBpbmRpY2F0ZSB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0gKG9sZC1zdHlsZSBub24tUEtDUyM4IE9wZW5TU0wKICogcHJpdmF0ZSBrZXkgZW5jcnlwdGlvbiksIHNldCB0aGUgJ2xlZ2FjeScgb3B0aW9uIHRvIHRydWUuIE5vdGU6IFVzaW5nIHRoaXMKICogb3B0aW9uIHdpbGwgY2F1c2UgdGhlIGl0ZXJhdGlvbiBjb3VudCB0byBiZSBmb3JjZWQgdG8gMS4KICoKICogTm90ZTogVGhlICdkZXMnIGFsZ29yaXRobSBpcyBzdXBwb3J0ZWQsIGJ1dCBpdCBpcyBub3QgY29uc2lkZXJlZCB0byBiZQogKiBzZWN1cmUgYmVjYXVzZSBpdCBvbmx5IHVzZXMgYSBzaW5nbGUgNTYtYml0IGtleS4gSWYgcG9zc2libGUsIGl0IGlzIGhpZ2hseQogKiByZWNvbW1lbmRlZCB0aGF0IGEgZGlmZmVyZW50IGFsZ29yaXRobSBiZSB1c2VkLgogKgogKiBAcGFyYW0gcnNhS2V5IHRoZSBSU0Ega2V5IHRvIGVuY3J5cHQuCiAqIEBwYXJhbSBwYXNzd29yZCB0aGUgcGFzc3dvcmQgdG8gdXNlLgogKiBAcGFyYW0gb3B0aW9uczoKICogICAgICAgICAgYWxnb3JpdGhtOiB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0gdG8gdXNlCiAqICAgICAgICAgICAgKCdhZXMxMjgnLCAnYWVzMTkyJywgJ2FlczI1NicsICczZGVzJywgJ2RlcycpLgogKiAgICAgICAgICBjb3VudDogdGhlIGl0ZXJhdGlvbiBjb3VudCB0byB1c2UuCiAqICAgICAgICAgIHNhbHRTaXplOiB0aGUgc2FsdCBzaXplIHRvIHVzZS4KICogICAgICAgICAgbGVnYWN5OiBvdXRwdXQgYW4gb2xkIG5vbi1QS0NTIzggUEVNLWVuY3J5cHRlZCtlbmNhcHN1bGF0ZWQKICogICAgICAgICAgICBoZWFkZXJzIChERUstSW5mbykgcHJpdmF0ZSBrZXkuCiAqCiAqIEByZXR1cm4gdGhlIFBFTS1lbmNvZGVkIEFTTi4xIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvLgogKi8KcGtpLmVuY3J5cHRSc2FQcml2YXRlS2V5ID0gZnVuY3Rpb24ocnNhS2V5LCBwYXNzd29yZCwgb3B0aW9ucykgewogIC8vIHN0YW5kYXJkIFBLQ1MjOAogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIGlmKCFvcHRpb25zLmxlZ2FjeSkgewogICAgLy8gZW5jcnlwdCBQcml2YXRlS2V5SW5mbwogICAgdmFyIHJ2YWwgPSBwa2kud3JhcFJzYVByaXZhdGVLZXkocGtpLnByaXZhdGVLZXlUb0FzbjEocnNhS2V5KSk7CiAgICBydmFsID0gcGtpLmVuY3J5cHRQcml2YXRlS2V5SW5mbyhydmFsLCBwYXNzd29yZCwgb3B0aW9ucyk7CiAgICByZXR1cm4gcGtpLmVuY3J5cHRlZFByaXZhdGVLZXlUb1BlbShydmFsKTsKICB9CgogIC8vIGxlZ2FjeSBub24tUEtDUyM4CiAgdmFyIGFsZ29yaXRobTsKICB2YXIgaXY7CiAgdmFyIGRrTGVuOwogIHZhciBjaXBoZXJGbjsKICBzd2l0Y2gob3B0aW9ucy5hbGdvcml0aG0pIHsKICBjYXNlICdhZXMxMjgnOgogICAgYWxnb3JpdGhtID0gJ0FFUy0xMjgtQ0JDJzsKICAgIGRrTGVuID0gMTY7CiAgICBpdiA9IGZvcmdlLnJhbmRvbS5nZXRCeXRlc1N5bmMoMTYpOwogICAgY2lwaGVyRm4gPSBmb3JnZS5hZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgIGJyZWFrOwogIGNhc2UgJ2FlczE5Mic6CiAgICBhbGdvcml0aG0gPSAnQUVTLTE5Mi1DQkMnOwogICAgZGtMZW4gPSAyNDsKICAgIGl2ID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzU3luYygxNik7CiAgICBjaXBoZXJGbiA9IGZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyOwogICAgYnJlYWs7CiAgY2FzZSAnYWVzMjU2JzoKICAgIGFsZ29yaXRobSA9ICdBRVMtMjU2LUNCQyc7CiAgICBka0xlbiA9IDMyOwogICAgaXYgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXNTeW5jKDE2KTsKICAgIGNpcGhlckZuID0gZm9yZ2UuYWVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXI7CiAgICBicmVhazsKICBjYXNlICczZGVzJzoKICAgIGFsZ29yaXRobSA9ICdERVMtRURFMy1DQkMnOwogICAgZGtMZW4gPSAyNDsKICAgIGl2ID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzU3luYyg4KTsKICAgIGNpcGhlckZuID0gZm9yZ2UuZGVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXI7CiAgICBicmVhazsKICBjYXNlICdkZXMnOgogICAgYWxnb3JpdGhtID0gJ0RFUy1DQkMnOwogICAgZGtMZW4gPSA4OwogICAgaXYgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXNTeW5jKDgpOwogICAgY2lwaGVyRm4gPSBmb3JnZS5kZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBlbmNyeXB0IFJTQSBwcml2YXRlIGtleTsgdW5zdXBwb3J0ZWQgJyArCiAgICAgICdlbmNyeXB0aW9uIGFsZ29yaXRobSAiJyArIG9wdGlvbnMuYWxnb3JpdGhtICsgJyIuJyk7CiAgICBlcnJvci5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobTsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gZW5jcnlwdCBwcml2YXRlIGtleSB1c2luZyBPcGVuU1NMIGxlZ2FjeSBrZXkgZGVyaXZhdGlvbgogIHZhciBkayA9IGZvcmdlLnBiZS5vcGVuc3NsRGVyaXZlQnl0ZXMocGFzc3dvcmQsIGl2LnN1YnN0cigwLCA4KSwgZGtMZW4pOwogIHZhciBjaXBoZXIgPSBjaXBoZXJGbihkayk7CiAgY2lwaGVyLnN0YXJ0KGl2KTsKICBjaXBoZXIudXBkYXRlKGFzbjEudG9EZXIocGtpLnByaXZhdGVLZXlUb0FzbjEocnNhS2V5KSkpOwogIGNpcGhlci5maW5pc2goKTsKCiAgdmFyIG1zZyA9IHsKICAgIHR5cGU6ICdSU0EgUFJJVkFURSBLRVknLAogICAgcHJvY1R5cGU6IHsKICAgICAgdmVyc2lvbjogJzQnLAogICAgICB0eXBlOiAnRU5DUllQVEVEJwogICAgfSwKICAgIGRla0luZm86IHsKICAgICAgYWxnb3JpdGhtOiBhbGdvcml0aG0sCiAgICAgIHBhcmFtZXRlcnM6IGZvcmdlLnV0aWwuYnl0ZXNUb0hleChpdikudG9VcHBlckNhc2UoKQogICAgfSwKICAgIGJvZHk6IGNpcGhlci5vdXRwdXQuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnKTsKfTsKCi8qKgogKiBEZWNyeXB0cyBhbiBSU0EgcHJpdmF0ZSBrZXkuCiAqCiAqIEBwYXJhbSBwZW0gdGhlIFBFTS1mb3JtYXR0ZWQgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gdG8gZGVjcnlwdC4KICogQHBhcmFtIHBhc3N3b3JkIHRoZSBwYXNzd29yZCB0byB1c2UuCiAqCiAqIEByZXR1cm4gdGhlIFJTQSBrZXkgb24gc3VjY2VzcywgbnVsbCBvbiBmYWlsdXJlLgogKi8KcGtpLmRlY3J5cHRSc2FQcml2YXRlS2V5ID0gZnVuY3Rpb24ocGVtLCBwYXNzd29yZCkgewogIHZhciBydmFsID0gbnVsbDsKCiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKCiAgaWYobXNnLnR5cGUgIT09ICdFTkNSWVBURUQgUFJJVkFURSBLRVknICYmCiAgICBtc2cudHlwZSAhPT0gJ1BSSVZBVEUgS0VZJyAmJgogICAgbXNnLnR5cGUgIT09ICdSU0EgUFJJVkFURSBLRVknKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IHByaXZhdGUga2V5IGZyb20gUEVNOyBQRU0gaGVhZGVyIHR5cGUgJyArCiAgICAgICdpcyBub3QgIkVOQ1JZUFRFRCBQUklWQVRFIEtFWSIsICJQUklWQVRFIEtFWSIsIG9yICJSU0EgUFJJVkFURSBLRVkiLicpOwogICAgZXJyb3IuaGVhZGVyVHlwZSA9IGVycm9yOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB2YXIgZGtMZW47CiAgICB2YXIgY2lwaGVyRm47CiAgICBzd2l0Y2gobXNnLmRla0luZm8uYWxnb3JpdGhtKSB7CiAgICBjYXNlICdERVMtQ0JDJzoKICAgICAgZGtMZW4gPSA4OwogICAgICBjaXBoZXJGbiA9IGZvcmdlLmRlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyOwogICAgICBicmVhazsKICAgIGNhc2UgJ0RFUy1FREUzLUNCQyc6CiAgICAgIGRrTGVuID0gMjQ7CiAgICAgIGNpcGhlckZuID0gZm9yZ2UuZGVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnQUVTLTEyOC1DQkMnOgogICAgICBka0xlbiA9IDE2OwogICAgICBjaXBoZXJGbiA9IGZvcmdlLmFlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyOwogICAgICBicmVhazsKICAgIGNhc2UgJ0FFUy0xOTItQ0JDJzoKICAgICAgZGtMZW4gPSAyNDsKICAgICAgY2lwaGVyRm4gPSBmb3JnZS5hZXMuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcjsKICAgICAgYnJlYWs7CiAgICBjYXNlICdBRVMtMjU2LUNCQyc6CiAgICAgIGRrTGVuID0gMzI7CiAgICAgIGNpcGhlckZuID0gZm9yZ2UuYWVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnUkMyLTQwLUNCQyc6CiAgICAgIGRrTGVuID0gNTsKICAgICAgY2lwaGVyRm4gPSBmdW5jdGlvbihrZXkpIHsKICAgICAgICByZXR1cm4gZm9yZ2UucmMyLmNyZWF0ZURlY3J5cHRpb25DaXBoZXIoa2V5LCA0MCk7CiAgICAgIH07CiAgICAgIGJyZWFrOwogICAgY2FzZSAnUkMyLTY0LUNCQyc6CiAgICAgIGRrTGVuID0gODsKICAgICAgY2lwaGVyRm4gPSBmdW5jdGlvbihrZXkpIHsKICAgICAgICByZXR1cm4gZm9yZ2UucmMyLmNyZWF0ZURlY3J5cHRpb25DaXBoZXIoa2V5LCA2NCk7CiAgICAgIH07CiAgICAgIGJyZWFrOwogICAgY2FzZSAnUkMyLTEyOC1DQkMnOgogICAgICBka0xlbiA9IDE2OwogICAgICBjaXBoZXJGbiA9IGZ1bmN0aW9uKGtleSkgewogICAgICAgIHJldHVybiBmb3JnZS5yYzIuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcihrZXksIDEyOCk7CiAgICAgIH07CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDb3VsZCBub3QgZGVjcnlwdCBwcml2YXRlIGtleTsgdW5zdXBwb3J0ZWQgJyArCiAgICAgICAgJ2VuY3J5cHRpb24gYWxnb3JpdGhtICInICsgbXNnLmRla0luZm8uYWxnb3JpdGhtICsgJyIuJyk7CiAgICAgIGVycm9yLmFsZ29yaXRobSA9IG1zZy5kZWtJbmZvLmFsZ29yaXRobTsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLy8gdXNlIE9wZW5TU0wgbGVnYWN5IGtleSBkZXJpdmF0aW9uCiAgICB2YXIgaXYgPSBmb3JnZS51dGlsLmhleFRvQnl0ZXMobXNnLmRla0luZm8ucGFyYW1ldGVycyk7CiAgICB2YXIgZGsgPSBmb3JnZS5wYmUub3BlbnNzbERlcml2ZUJ5dGVzKHBhc3N3b3JkLCBpdi5zdWJzdHIoMCwgOCksIGRrTGVuKTsKICAgIHZhciBjaXBoZXIgPSBjaXBoZXJGbihkayk7CiAgICBjaXBoZXIuc3RhcnQoaXYpOwogICAgY2lwaGVyLnVwZGF0ZShmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihtc2cuYm9keSkpOwogICAgaWYoY2lwaGVyLmZpbmlzaCgpKSB7CiAgICAgIHJ2YWwgPSBjaXBoZXIub3V0cHV0LmdldEJ5dGVzKCk7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gcnZhbDsKICAgIH0KICB9IGVsc2UgewogICAgcnZhbCA9IG1zZy5ib2R5OwogIH0KCiAgaWYobXNnLnR5cGUgPT09ICdFTkNSWVBURUQgUFJJVkFURSBLRVknKSB7CiAgICBydmFsID0gcGtpLmRlY3J5cHRQcml2YXRlS2V5SW5mbyhhc24xLmZyb21EZXIocnZhbCksIHBhc3N3b3JkKTsKICB9IGVsc2UgewogICAgLy8gZGVjcnlwdGlvbiBhbHJlYWR5IHBlcmZvcm1lZCBhYm92ZQogICAgcnZhbCA9IGFzbjEuZnJvbURlcihydmFsKTsKICB9CgogIGlmKHJ2YWwgIT09IG51bGwpIHsKICAgIHJ2YWwgPSBwa2kucHJpdmF0ZUtleUZyb21Bc24xKHJ2YWwpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogRGVyaXZlcyBhIFBLQ1MjMTIga2V5LgogKgogKiBAcGFyYW0gcGFzc3dvcmQgdGhlIHBhc3N3b3JkIHRvIGRlcml2ZSB0aGUga2V5IG1hdGVyaWFsIGZyb20sIG51bGwgb3IKICogICAgICAgICAgdW5kZWZpbmVkIGZvciBub25lLgogKiBAcGFyYW0gc2FsdCB0aGUgc2FsdCwgYXMgYSBCeXRlQnVmZmVyLCB0byB1c2UuCiAqIEBwYXJhbSBpZCB0aGUgUEtDUyMxMiBJRCBieXRlICgxID0ga2V5IG1hdGVyaWFsLCAyID0gSVYsIDMgPSBNQUMpLgogKiBAcGFyYW0gaXRlciB0aGUgaXRlcmF0aW9uIGNvdW50LgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGRlcml2ZSBmcm9tIHRoZSBwYXNzd29yZC4KICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCB0byB1c2UsIGRlZmF1bHRzIHRvIFNIQS0xLgogKgogKiBAcmV0dXJuIGEgQnl0ZUJ1ZmZlciB3aXRoIHRoZSBieXRlcyBkZXJpdmVkIGZyb20gdGhlIHBhc3N3b3JkLgogKi8KcGtpLnBiZS5nZW5lcmF0ZVBrY3MxMktleSA9IGZ1bmN0aW9uKHBhc3N3b3JkLCBzYWx0LCBpZCwgaXRlciwgbiwgbWQpIHsKICB2YXIgaiwgbDsKCiAgaWYodHlwZW9mIG1kID09PSAndW5kZWZpbmVkJyB8fCBtZCA9PT0gbnVsbCkgewogICAgbWQgPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogIH0KCiAgdmFyIHUgPSBtZC5kaWdlc3RMZW5ndGg7CiAgdmFyIHYgPSBtZC5ibG9ja0xlbmd0aDsKICB2YXIgcmVzdWx0ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwoKICAvKiBDb252ZXJ0IHBhc3N3b3JkIHRvIFVuaWNvZGUgYnl0ZSBidWZmZXIgKyB0cmFpbGluZyAwLWJ5dGUuICovCiAgdmFyIHBhc3NCdWYgPSBuZXcgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKCk7CiAgaWYocGFzc3dvcmQgIT09IG51bGwgJiYgcGFzc3dvcmQgIT09IHVuZGVmaW5lZCkgewogICAgZm9yKGwgPSAwOyBsIDwgcGFzc3dvcmQubGVuZ3RoOyBsKyspIHsKICAgICAgcGFzc0J1Zi5wdXRJbnQxNihwYXNzd29yZC5jaGFyQ29kZUF0KGwpKTsKICAgIH0KICAgIHBhc3NCdWYucHV0SW50MTYoMCk7CiAgfQoKICAvKiBMZW5ndGggb2Ygc2FsdCBhbmQgcGFzc3dvcmQgaW4gQllURVMuICovCiAgdmFyIHAgPSBwYXNzQnVmLmxlbmd0aCgpOwogIHZhciBzID0gc2FsdC5sZW5ndGgoKTsKCiAgLyogMS4gQ29uc3RydWN0IGEgc3RyaW5nLCBEICh0aGUgImRpdmVyc2lmaWVyIiksIGJ5IGNvbmNhdGVuYXRpbmcKICAgICAgICB2IGNvcGllcyBvZiBJRC4gKi8KICB2YXIgRCA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICBELmZpbGxXaXRoQnl0ZShpZCwgdik7CgogIC8qIDIuIENvbmNhdGVuYXRlIGNvcGllcyBvZiB0aGUgc2FsdCB0b2dldGhlciB0byBjcmVhdGUgYSBzdHJpbmcgUyBvZiBsZW5ndGgKICAgICAgICB2ICogY2VpbChzIC8gdikgYnl0ZXMgKHRoZSBmaW5hbCBjb3B5IG9mIHRoZSBzYWx0IG1heSBiZSB0cnVuYWN0ZWQKICAgICAgICB0byBjcmVhdGUgUykuCiAgICAgICAgTm90ZSB0aGF0IGlmIHRoZSBzYWx0IGlzIHRoZSBlbXB0eSBzdHJpbmcsIHRoZW4gc28gaXMgUy4gKi8KICB2YXIgU2xlbiA9IHYgKiBNYXRoLmNlaWwocyAvIHYpOwogIHZhciBTID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogIGZvcihsID0gMDsgbCA8IFNsZW47IGwgKyspIHsKICAgIFMucHV0Qnl0ZShzYWx0LmF0KGwgJSBzKSk7CiAgfQoKICAvKiAzLiBDb25jYXRlbmF0ZSBjb3BpZXMgb2YgdGhlIHBhc3N3b3JkIHRvZ2V0aGVyIHRvIGNyZWF0ZSBhIHN0cmluZyBQIG9mCiAgICAgICAgbGVuZ3RoIHYgKiBjZWlsKHAgLyB2KSBieXRlcyAodGhlIGZpbmFsIGNvcHkgb2YgdGhlIHBhc3N3b3JkIG1heSBiZQogICAgICAgIHRydW5jYXRlZCB0byBjcmVhdGUgUCkuCiAgICAgICAgTm90ZSB0aGF0IGlmIHRoZSBwYXNzd29yZCBpcyB0aGUgZW1wdHkgc3RyaW5nLCB0aGVuIHNvIGlzIFAuICovCiAgdmFyIFBsZW4gPSB2ICogTWF0aC5jZWlsKHAgLyB2KTsKICB2YXIgUCA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICBmb3IobCA9IDA7IGwgPCBQbGVuOyBsICsrKSB7CiAgICBQLnB1dEJ5dGUocGFzc0J1Zi5hdChsICUgcCkpOwogIH0KCiAgLyogNC4gU2V0IEk9U3x8UCB0byBiZSB0aGUgY29uY2F0ZW5hdGlvbiBvZiBTIGFuZCBQLiAqLwogIHZhciBJID0gUzsKICBJLnB1dEJ1ZmZlcihQKTsKCiAgLyogNS4gU2V0IGM9Y2VpbChuIC8gdSkuICovCiAgdmFyIGMgPSBNYXRoLmNlaWwobiAvIHUpOwoKICAvKiA2LiBGb3IgaT0xLCAyLCAuLi4sIGMsIGRvIHRoZSBmb2xsb3dpbmc6ICovCiAgZm9yKHZhciBpID0gMTsgaSA8PSBjOyBpICsrKSB7CiAgICAvKiBhKSBTZXQgQWk9SF5yKER8fEkpLiAobC5lLiB0aGUgcnRoIGhhc2ggb2YgRHx8SSwgSChIKEgoLi4uSChEfHxJKSkpKSAqLwogICAgdmFyIGJ1ZiA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICAgIGJ1Zi5wdXRCeXRlcyhELmJ5dGVzKCkpOwogICAgYnVmLnB1dEJ5dGVzKEkuYnl0ZXMoKSk7CiAgICBmb3IodmFyIHJvdW5kID0gMDsgcm91bmQgPCBpdGVyOyByb3VuZCArKykgewogICAgICBtZC5zdGFydCgpOwogICAgICBtZC51cGRhdGUoYnVmLmdldEJ5dGVzKCkpOwogICAgICBidWYgPSBtZC5kaWdlc3QoKTsKICAgIH0KCiAgICAvKiBiKSBDb25jYXRlbmF0ZSBjb3BpZXMgb2YgQWkgdG8gY3JlYXRlIGEgc3RyaW5nIEIgb2YgbGVuZ3RoIHYgYnl0ZXMgKHRoZQogICAgICAgICAgZmluYWwgY29weSBvZiBBaSBtYXkgYmUgdHJ1bmNhdGVkIHRvIGNyZWF0ZSBCKS4gKi8KICAgIHZhciBCID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogICAgZm9yKGwgPSAwOyBsIDwgdjsgbCArKykgewogICAgICBCLnB1dEJ5dGUoYnVmLmF0KGwgJSB1KSk7CiAgICB9CgogICAgLyogYykgVHJlYXRpbmcgSSBhcyBhIGNvbmNhdGVuYXRpb24gSTAsIEkxLCAuLi4sIElrLTEgb2Ygdi1ieXRlIGJsb2NrcywKICAgICAgICAgIHdoZXJlIGs9Y2VpbChzIC8gdikgKyBjZWlsKHAgLyB2KSwgbW9kaWZ5IEkgYnkgc2V0dGluZwogICAgICAgICAgSWo9KElqK0IrMSkgbW9kIDJ2IGZvciBlYWNoIGouICAqLwogICAgdmFyIGsgPSBNYXRoLmNlaWwocyAvIHYpICsgTWF0aC5jZWlsKHAgLyB2KTsKICAgIHZhciBJbmV3ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogICAgZm9yKGogPSAwOyBqIDwgazsgaiArKykgewogICAgICB2YXIgY2h1bmsgPSBuZXcgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKEkuZ2V0Qnl0ZXModikpOwogICAgICB2YXIgeCA9IDB4MWZmOwogICAgICBmb3IobCA9IEIubGVuZ3RoKCkgLSAxOyBsID49IDA7IGwgLS0pIHsKICAgICAgICB4ID0geCA+PiA4OwogICAgICAgIHggKz0gQi5hdChsKSArIGNodW5rLmF0KGwpOwogICAgICAgIGNodW5rLnNldEF0KGwsIHggJiAweGZmKTsKICAgICAgfQogICAgICBJbmV3LnB1dEJ1ZmZlcihjaHVuayk7CiAgICB9CiAgICBJID0gSW5ldzsKCiAgICAvKiBBZGQgQWkgdG8gQS4gKi8KICAgIHJlc3VsdC5wdXRCdWZmZXIoYnVmKTsKICB9CgogIHJlc3VsdC50cnVuY2F0ZShyZXN1bHQubGVuZ3RoKCkgLSBuKTsKICByZXR1cm4gcmVzdWx0Owp9OwoKLyoqCiAqIEdldCBuZXcgRm9yZ2UgY2lwaGVyIG9iamVjdCBpbnN0YW5jZS4KICoKICogQHBhcmFtIG9pZCB0aGUgT0lEIChpbiBzdHJpbmcgbm90YXRpb24pLgogKiBAcGFyYW0gcGFyYW1zIHRoZSBBU04uMSBwYXJhbXMgb2JqZWN0LgogKiBAcGFyYW0gcGFzc3dvcmQgdGhlIHBhc3N3b3JkIHRvIGRlY3J5cHQgd2l0aC4KICoKICogQHJldHVybiBuZXcgY2lwaGVyIG9iamVjdCBpbnN0YW5jZS4KICovCnBraS5wYmUuZ2V0Q2lwaGVyID0gZnVuY3Rpb24ob2lkLCBwYXJhbXMsIHBhc3N3b3JkKSB7CiAgc3dpdGNoKG9pZCkgewogIGNhc2UgcGtpLm9pZHNbJ3BrY3M1UEJFUzInXToKICAgIHJldHVybiBwa2kucGJlLmdldENpcGhlckZvclBCRVMyKG9pZCwgcGFyYW1zLCBwYXNzd29yZCk7CgogIGNhc2UgcGtpLm9pZHNbJ3BiZVdpdGhTSEFBbmQzLUtleVRyaXBsZURFUy1DQkMnXToKICBjYXNlIHBraS5vaWRzWydwYmV3aXRoU0hBQW5kNDBCaXRSQzItQ0JDJ106CiAgICByZXR1cm4gcGtpLnBiZS5nZXRDaXBoZXJGb3JQS0NTMTJQQkUob2lkLCBwYXJhbXMsIHBhc3N3b3JkKTsKCiAgZGVmYXVsdDoKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgZW5jcnlwdGVkIFBCRSBkYXRhIGJsb2NrLiBVbnN1cHBvcnRlZCBPSUQuJyk7CiAgICBlcnJvci5vaWQgPSBvaWQ7CiAgICBlcnJvci5zdXBwb3J0ZWRPaWRzID0gWwogICAgICAncGtjczVQQkVTMicsCiAgICAgICdwYmVXaXRoU0hBQW5kMy1LZXlUcmlwbGVERVMtQ0JDJywKICAgICAgJ3BiZXdpdGhTSEFBbmQ0MEJpdFJDMi1DQkMnCiAgICBdOwogICAgdGhyb3cgZXJyb3I7CiAgfQp9OwoKLyoqCiAqIEdldCBuZXcgRm9yZ2UgY2lwaGVyIG9iamVjdCBpbnN0YW5jZSBhY2NvcmRpbmcgdG8gUEJFUzIgcGFyYW1zIGJsb2NrLgogKgogKiBUaGUgcmV0dXJuZWQgY2lwaGVyIGluc3RhbmNlIGlzIGFscmVhZHkgc3RhcnRlZCB1c2luZyB0aGUgSVYKICogZnJvbSBQQkVTMiBwYXJhbWV0ZXIgYmxvY2suCiAqCiAqIEBwYXJhbSBvaWQgdGhlIFBLQ1MjNSBQQktERjIgT0lEIChpbiBzdHJpbmcgbm90YXRpb24pLgogKiBAcGFyYW0gcGFyYW1zIHRoZSBBU04uMSBQQkVTMi1wYXJhbXMgb2JqZWN0LgogKiBAcGFyYW0gcGFzc3dvcmQgdGhlIHBhc3N3b3JkIHRvIGRlY3J5cHQgd2l0aC4KICoKICogQHJldHVybiBuZXcgY2lwaGVyIG9iamVjdCBpbnN0YW5jZS4KICovCnBraS5wYmUuZ2V0Q2lwaGVyRm9yUEJFUzIgPSBmdW5jdGlvbihvaWQsIHBhcmFtcywgcGFzc3dvcmQpIHsKICAvLyBnZXQgUEJFIHBhcmFtcwogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKHBhcmFtcywgUEJFUzJBbGdvcml0aG1zVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIHBhc3N3b3JkLWJhc2VkLWVuY3J5cHRpb24gYWxnb3JpdGhtICcgKwogICAgICAncGFyYW1ldGVycy4gQVNOLjEgb2JqZWN0IGlzIG5vdCBhIHN1cHBvcnRlZCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mby4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gY2hlY2sgb2lkcwogIG9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5rZGZPaWQpOwogIGlmKG9pZCAhPT0gcGtpLm9pZHNbJ3BrY3M1UEJLREYyJ10pIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgZW5jcnlwdGVkIHByaXZhdGUga2V5LiAnICsKICAgICAgJ1Vuc3VwcG9ydGVkIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uIE9JRC4nKTsKICAgIGVycm9yLm9pZCA9IG9pZDsKICAgIGVycm9yLnN1cHBvcnRlZE9pZHMgPSBbJ3BrY3M1UEJLREYyJ107CiAgICB0aHJvdyBlcnJvcjsKICB9CiAgb2lkID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLmVuY09pZCk7CiAgaWYob2lkICE9PSBwa2kub2lkc1snYWVzMTI4LUNCQyddICYmCiAgICBvaWQgIT09IHBraS5vaWRzWydhZXMxOTItQ0JDJ10gJiYKICAgIG9pZCAhPT0gcGtpLm9pZHNbJ2FlczI1Ni1DQkMnXSAmJgogICAgb2lkICE9PSBwa2kub2lkc1snZGVzLUVERTMtQ0JDJ10gJiYKICAgIG9pZCAhPT0gcGtpLm9pZHNbJ2Rlc0NCQyddKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIGVuY3J5cHRlZCBwcml2YXRlIGtleS4gJyArCiAgICAgICdVbnN1cHBvcnRlZCBlbmNyeXB0aW9uIHNjaGVtZSBPSUQuJyk7CiAgICBlcnJvci5vaWQgPSBvaWQ7CiAgICBlcnJvci5zdXBwb3J0ZWRPaWRzID0gWwogICAgICAnYWVzMTI4LUNCQycsICdhZXMxOTItQ0JDJywgJ2FlczI1Ni1DQkMnLCAnZGVzLUVERTMtQ0JDJywgJ2Rlc0NCQyddOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICAvLyBzZXQgUEJFIHBhcmFtcwogIHZhciBzYWx0ID0gY2FwdHVyZS5rZGZTYWx0OwogIHZhciBjb3VudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUua2RmSXRlcmF0aW9uQ291bnQpOwogIGNvdW50ID0gY291bnQuZ2V0SW50KGNvdW50Lmxlbmd0aCgpIDw8IDMpOwogIHZhciBka0xlbjsKICB2YXIgY2lwaGVyRm47CiAgc3dpdGNoKHBraS5vaWRzW29pZF0pIHsKICBjYXNlICdhZXMxMjgtQ0JDJzoKICAgIGRrTGVuID0gMTY7CiAgICBjaXBoZXJGbiA9IGZvcmdlLmFlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyOwogICAgYnJlYWs7CiAgY2FzZSAnYWVzMTkyLUNCQyc6CiAgICBka0xlbiA9IDI0OwogICAgY2lwaGVyRm4gPSBmb3JnZS5hZXMuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcjsKICAgIGJyZWFrOwogIGNhc2UgJ2FlczI1Ni1DQkMnOgogICAgZGtMZW4gPSAzMjsKICAgIGNpcGhlckZuID0gZm9yZ2UuYWVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXI7CiAgICBicmVhazsKICBjYXNlICdkZXMtRURFMy1DQkMnOgogICAgZGtMZW4gPSAyNDsKICAgIGNpcGhlckZuID0gZm9yZ2UuZGVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXI7CiAgICBicmVhazsKICBjYXNlICdkZXNDQkMnOgogICAgZGtMZW4gPSA4OwogICAgY2lwaGVyRm4gPSBmb3JnZS5kZXMuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcjsKICAgIGJyZWFrOwogIH0KCiAgLy8gZGVjcnlwdCBwcml2YXRlIGtleSB1c2luZyBwYmUgU0hBLTEgYW5kIEFFUy9ERVMKICB2YXIgZGsgPSBmb3JnZS5wa2NzNS5wYmtkZjIocGFzc3dvcmQsIHNhbHQsIGNvdW50LCBka0xlbik7CiAgdmFyIGl2ID0gY2FwdHVyZS5lbmNJdjsKICB2YXIgY2lwaGVyID0gY2lwaGVyRm4oZGspOwogIGNpcGhlci5zdGFydChpdik7CgogIHJldHVybiBjaXBoZXI7Cn07CgovKioKICogR2V0IG5ldyBGb3JnZSBjaXBoZXIgb2JqZWN0IGluc3RhbmNlIGZvciBQS0NTIzEyIFBCRS4KICoKICogVGhlIHJldHVybmVkIGNpcGhlciBpbnN0YW5jZSBpcyBhbHJlYWR5IHN0YXJ0ZWQgdXNpbmcgdGhlIGtleSAmIElWCiAqIGRlcml2ZWQgZnJvbSB0aGUgcHJvdmlkZWQgcGFzc3dvcmQgYW5kIFBLQ1MjMTIgUEJFIHNhbHQuCiAqCiAqIEBwYXJhbSBvaWQgVGhlIFBLQ1MjMTIgUEJFIE9JRCAoaW4gc3RyaW5nIG5vdGF0aW9uKS4KICogQHBhcmFtIHBhcmFtcyBUaGUgQVNOLjEgUEtDUyMxMiBQQkUtcGFyYW1zIG9iamVjdC4KICogQHBhcmFtIHBhc3N3b3JkIFRoZSBwYXNzd29yZCB0byBkZWNyeXB0IHdpdGguCiAqCiAqIEByZXR1cm4gdGhlIG5ldyBjaXBoZXIgb2JqZWN0IGluc3RhbmNlLgogKi8KcGtpLnBiZS5nZXRDaXBoZXJGb3JQS0NTMTJQQkUgPSBmdW5jdGlvbihvaWQsIHBhcmFtcywgcGFzc3dvcmQpIHsKICAvLyBnZXQgUEJFIHBhcmFtcwogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKHBhcmFtcywgcGtjczEyUGJlUGFyYW1zVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIHBhc3N3b3JkLWJhc2VkLWVuY3J5cHRpb24gYWxnb3JpdGhtICcgKwogICAgICAncGFyYW1ldGVycy4gQVNOLjEgb2JqZWN0IGlzIG5vdCBhIHN1cHBvcnRlZCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mby4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgdmFyIHNhbHQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLnNhbHQpOwogIHZhciBjb3VudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUuaXRlcmF0aW9ucyk7CiAgY291bnQgPSBjb3VudC5nZXRJbnQoY291bnQubGVuZ3RoKCkgPDwgMyk7CgogIHZhciBka0xlbiwgZEl2TGVuLCBjaXBoZXJGbjsKICBzd2l0Y2gob2lkKSB7CiAgICBjYXNlIHBraS5vaWRzWydwYmVXaXRoU0hBQW5kMy1LZXlUcmlwbGVERVMtQ0JDJ106CiAgICAgIGRrTGVuID0gMjQ7CiAgICAgIGRJdkxlbiA9IDg7CiAgICAgIGNpcGhlckZuID0gZm9yZ2UuZGVzLnN0YXJ0RGVjcnlwdGluZzsKICAgICAgYnJlYWs7CgogICAgY2FzZSBwa2kub2lkc1sncGJld2l0aFNIQUFuZDQwQml0UkMyLUNCQyddOgogICAgICBka0xlbiA9IDU7CiAgICAgIGRJdkxlbiA9IDg7CiAgICAgIGNpcGhlckZuID0gZnVuY3Rpb24oa2V5LCBpdikgewogICAgICAgIHZhciBjaXBoZXIgPSBmb3JnZS5yYzIuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcihrZXksIDQwKTsKICAgICAgICBjaXBoZXIuc3RhcnQoaXYsIG51bGwpOwogICAgICAgIHJldHVybiBjaXBoZXI7CiAgICAgIH07CiAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgUEtDUyAjMTIgUEJFIGRhdGEgYmxvY2suIFVuc3VwcG9ydGVkIE9JRC4nKTsKICAgICAgZXJyb3Iub2lkID0gb2lkOwogICAgICB0aHJvdyBlcnJvcjsKICB9CgogIHZhciBrZXkgPSBwa2kucGJlLmdlbmVyYXRlUGtjczEyS2V5KHBhc3N3b3JkLCBzYWx0LCAxLCBjb3VudCwgZGtMZW4pOwogIHZhciBpdiA9IHBraS5wYmUuZ2VuZXJhdGVQa2NzMTJLZXkocGFzc3dvcmQsIHNhbHQsIDIsIGNvdW50LCBkSXZMZW4pOwoKICByZXR1cm4gY2lwaGVyRm4oa2V5LCBpdik7Cn07CgovKioKICogT3BlblNTTCdzIGxlZ2FjeSBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbi4KICoKICogU2VlOiBodHRwOi8vd3d3Lm9wZW5zc2wub3JnL2RvY3MvY3J5cHRvL0VWUF9CeXRlc1RvS2V5Lmh0bWwKICoKICogQHBhcmFtIHBhc3N3b3JkIHRoZSBwYXNzd29yZCB0byBkZXJpdmUgdGhlIGtleSBmcm9tLgogKiBAcGFyYW0gc2FsdCB0aGUgc2FsdCB0byB1c2UsIG51bGwgZm9yIG5vbmUuCiAqIEBwYXJhbSBka0xlbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCBmb3IgdGhlIGRlcml2ZWQga2V5LgogKiBAcGFyYW0gW29wdGlvbnNdIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgW21kXSBhbiBvcHRpb25hbCBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlLgogKi8KcGtpLnBiZS5vcGVuc3NsRGVyaXZlQnl0ZXMgPSBmdW5jdGlvbihwYXNzd29yZCwgc2FsdCwgZGtMZW4sIG1kKSB7CiAgaWYodHlwZW9mIG1kID09PSAndW5kZWZpbmVkJyB8fCBtZCA9PT0gbnVsbCkgewogICAgbWQgPSBmb3JnZS5tZC5tZDUuY3JlYXRlKCk7CiAgfQogIGlmKHNhbHQgPT09IG51bGwpIHsKICAgIHNhbHQgPSAnJzsKICB9CiAgdmFyIGRpZ2VzdHMgPSBbaGFzaChtZCwgcGFzc3dvcmQgKyBzYWx0KV07CiAgZm9yKHZhciBsZW5ndGggPSAxNiwgaSA9IDE7IGxlbmd0aCA8IGRrTGVuOyArK2ksIGxlbmd0aCArPSAxNikgewogICAgZGlnZXN0cy5wdXNoKGhhc2gobWQsIGRpZ2VzdHNbaSAtIDFdICsgcGFzc3dvcmQgKyBzYWx0KSk7CiAgfQogIHJldHVybiBkaWdlc3RzLmpvaW4oJycpLnN1YnN0cigwLCBka0xlbik7Cn07CgpmdW5jdGlvbiBoYXNoKG1kLCBieXRlcykgewogIHJldHVybiBtZC5zdGFydCgpLnVwZGF0ZShieXRlcykuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKfQoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncGJlJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3BiZScsWwogICdyZXF1aXJlJywKICAnbW9kdWxlJywKICAnLi9hZXMnLAogICcuL2FzbjEnLAogICcuL2RlcycsCiAgJy4vbWQnLAogICcuL29pZHMnLAogICcuL3BlbScsCiAgJy4vcGJrZGYyJywKICAnLi9yYW5kb20nLAogICcuL3JjMicsCiAgJy4vcnNhJywKICAnLi91dGlsJwpdLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIEFTTi4xIHZhbGlkYXRvcnMgZm9yIFBLQ1MjNyB2MS41LgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKiBAYXV0aG9yIFN0ZWZhbiBTaWVnbAogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxNSBEaWdpdGFsIEJhemFhciwgSW5jLgogKiBDb3B5cmlnaHQgKGMpIDIwMTIgU3RlZmFuIFNpZWdsIDxzdGVzaWVAYnJva2VucGlwZS5kZT4KICoKICogVGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIFBLQ1MjNyBpcyBhcyBmb2xsb3dzCiAqIChzZWUgUkZDICMyMzE1IGZvciBkZXRhaWxzLCBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzE1LnR4dCk6CiAqCiAqIEEgUEtDUyM3IG1lc3NhZ2UgY29uc2lzdHMgb2YgYSBDb250ZW50SW5mbyBvbiByb290IGxldmVsLCB3aGljaCBtYXkKICogY29udGFpbiBhbnkgbnVtYmVyIG9mIGZ1cnRoZXIgQ29udGVudEluZm8gbmVzdGVkIGludG8gaXQuCiAqCiAqIENvbnRlbnRJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgY29udGVudFR5cGUgICAgICAgICAgICAgICAgQ29udGVudFR5cGUsCiAqICAgY29udGVudCAgICAgICAgICAgICAgIFswXSAgRVhQTElDSVQgQU5ZIERFRklORUQgQlkgY29udGVudFR5cGUgT1BUSU9OQUwKICogfQogKgogKiBDb250ZW50VHlwZSA6Oj0gT0JKRUNUIElERU5USUZJRVIKICoKICogRW52ZWxvcGVkRGF0YSA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gICAgICAgICAgICAgICAgICAgIFZlcnNpb24sCiAqICAgcmVjaXBpZW50SW5mb3MgICAgICAgICAgICAgUmVjaXBpZW50SW5mb3MsCiAqICAgZW5jcnlwdGVkQ29udGVudEluZm8gICAgICAgRW5jcnlwdGVkQ29udGVudEluZm8KICogfQogKgogKiBFbmNyeXB0ZWREYXRhIDo6PSBTRVFVRU5DRSB7CiAqICAgdmVyc2lvbiAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiwKICogICBlbmNyeXB0ZWRDb250ZW50SW5mbyAgICAgICBFbmNyeXB0ZWRDb250ZW50SW5mbwogKiB9CiAqCiAqIGlkLXNpZ25lZERhdGEgT0JKRUNUIElERU5USUZJRVIgOjo9IHsgaXNvKDEpIG1lbWJlci1ib2R5KDIpCiAqICAgdXMoODQwKSByc2Fkc2koMTEzNTQ5KSBwa2NzKDEpIHBrY3M3KDcpIDIgfQogKgogKiBTaWduZWREYXRhIDo6PSBTRVFVRU5DRSB7CiAqICAgdmVyc2lvbiAgICAgICAgICAgSU5URUdFUiwKICogICBkaWdlc3RBbGdvcml0aG1zICBEaWdlc3RBbGdvcml0aG1JZGVudGlmaWVycywKICogICBjb250ZW50SW5mbyAgICAgICBDb250ZW50SW5mbywKICogICBjZXJ0aWZpY2F0ZXMgICAgICBbMF0gSU1QTElDSVQgQ2VydGlmaWNhdGVzIE9QVElPTkFMLAogKiAgIGNybHMgICAgICAgICAgICAgIFsxXSBJTVBMSUNJVCBDZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0cyBPUFRJT05BTCwKICogICBzaWduZXJJbmZvcyAgICAgICBTaWduZXJJbmZvcwogKiB9CiAqCiAqIFNpZ25lckluZm9zIDo6PSBTRVQgT0YgU2lnbmVySW5mbwogKgogKiBTaWduZXJJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgdmVyc2lvbiAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiwKICogICBpc3N1ZXJBbmRTZXJpYWxOdW1iZXIgICAgICBJc3N1ZXJBbmRTZXJpYWxOdW1iZXIsCiAqICAgZGlnZXN0QWxnb3JpdGhtICAgICAgICAgICAgRGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllciwKICogICBhdXRoZW50aWNhdGVkQXR0cmlidXRlcyAgICBbMF0gSU1QTElDSVQgQXR0cmlidXRlcyBPUFRJT05BTCwKICogICBkaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtICBEaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciwKICogICBlbmNyeXB0ZWREaWdlc3QgICAgICAgICAgICBFbmNyeXB0ZWREaWdlc3QsCiAqICAgdW5hdXRoZW50aWNhdGVkQXR0cmlidXRlcyAgWzFdIElNUExJQ0lUIEF0dHJpYnV0ZXMgT1BUSU9OQUwKICogfQogKgogKiBFbmNyeXB0ZWREaWdlc3QgOjo9IE9DVEVUIFNUUklORwogKgogKiBBdHRyaWJ1dGVzIDo6PSBTRVQgT0YgQXR0cmlidXRlCiAqCiAqIEF0dHJpYnV0ZSA6Oj0gU0VRVUVOQ0UgewogKiAgIGF0dHJUeXBlICAgIE9CSkVDVCBJREVOVElGSUVSLAogKiAgIGF0dHJWYWx1ZXMgIFNFVCBPRiBBdHRyaWJ1dGVWYWx1ZQogKiB9CiAqCiAqIEF0dHJpYnV0ZVZhbHVlIDo6PSBBTlkKICoKICogVmVyc2lvbiA6Oj0gSU5URUdFUgogKgogKiBSZWNpcGllbnRJbmZvcyA6Oj0gU0VUIE9GIFJlY2lwaWVudEluZm8KICoKICogRW5jcnlwdGVkQ29udGVudEluZm8gOjo9IFNFUVVFTkNFIHsKICogICBjb250ZW50VHlwZSAgICAgICAgICAgICAgICAgQ29udGVudFR5cGUsCiAqICAgY29udGVudEVuY3J5cHRpb25BbGdvcml0aG0gIENvbnRlbnRFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciwKICogICBlbmNyeXB0ZWRDb250ZW50ICAgICAgIFswXSAgSU1QTElDSVQgRW5jcnlwdGVkQ29udGVudCBPUFRJT05BTAogKiB9CiAqCiAqIENvbnRlbnRFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciA6Oj0gQWxnb3JpdGhtSWRlbnRpZmllcgogKgogKiBUaGUgQWxnb3JpdGhtSWRlbnRpZmllciBjb250YWlucyBhbiBPYmplY3QgSWRlbnRpZmllciAoT0lEKSBhbmQgcGFyYW1ldGVycwogKiBmb3IgdGhlIGFsZ29yaXRobSwgaWYgYW55LiBJbiB0aGUgY2FzZSBvZiBBRVMgYW5kIERFUzMsIHRoZXJlIGlzIG9ubHkgb25lLAogKiB0aGUgSVYuCiAqCiAqIEFsZ29yaXRobUlkZW50aWZlciA6Oj0gU0VRVUVOQ0UgewogKiAgICBhbGdvcml0aG0gT0JKRUNUIElERU5USUZJRVIsCiAqICAgIHBhcmFtZXRlcnMgQU5ZIERFRklORUQgQlkgYWxnb3JpdGhtIE9QVElPTkFMCiAqIH0KICoKICogRW5jcnlwdGVkQ29udGVudCA6Oj0gT0NURVQgU1RSSU5HCiAqCiAqIFJlY2lwaWVudEluZm8gOjo9IFNFUVVFTkNFIHsKICogICB2ZXJzaW9uICAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiwKICogICBpc3N1ZXJBbmRTZXJpYWxOdW1iZXIgICAgICAgSXNzdWVyQW5kU2VyaWFsTnVtYmVyLAogKiAgIGtleUVuY3J5cHRpb25BbGdvcml0aG0gICAgICBLZXlFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciwKICogICBlbmNyeXB0ZWRLZXkgICAgICAgICAgICAgICAgRW5jcnlwdGVkS2V5CiAqIH0KICoKICogSXNzdWVyQW5kU2VyaWFsTnVtYmVyIDo6PSBTRVFVRU5DRSB7CiAqICAgaXNzdWVyICAgICAgICAgICAgICAgICAgICAgIE5hbWUsCiAqICAgc2VyaWFsTnVtYmVyICAgICAgICAgICAgICAgIENlcnRpZmljYXRlU2VyaWFsTnVtYmVyCiAqIH0KICoKICogQ2VydGlmaWNhdGVTZXJpYWxOdW1iZXIgOjo9IElOVEVHRVIKICoKICogS2V5RW5jcnlwdGlvbkFsZ29yaXRobUlkZW50aWZpZXIgOjo9IEFsZ29yaXRobUlkZW50aWZpZXIKICoKICogRW5jcnlwdGVkS2V5IDo6PSBPQ1RFVCBTVFJJTkcKICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBzaG9ydGN1dCBmb3IgQVNOLjEgQVBJCnZhciBhc24xID0gZm9yZ2UuYXNuMTsKCi8vIHNob3J0Y3V0IGZvciBQS0NTIzcgQVBJCnZhciBwN3YgPSBmb3JnZS5wa2NzN2FzbjEgPSBmb3JnZS5wa2NzN2FzbjEgfHwge307CmZvcmdlLnBrY3M3ID0gZm9yZ2UucGtjczcgfHwge307CmZvcmdlLnBrY3M3LmFzbjEgPSBwN3Y7Cgp2YXIgY29udGVudEluZm9WYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0NvbnRlbnRJbmZvJywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIHZhbHVlOiBbewogICAgbmFtZTogJ0NvbnRlbnRJbmZvLkNvbnRlbnRUeXBlJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAnY29udGVudFR5cGUnCiAgfSwgewogICAgbmFtZTogJ0NvbnRlbnRJbmZvLmNvbnRlbnQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgIHR5cGU6IDAsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgY2FwdHVyZUFzbjE6ICdjb250ZW50JwogIH1dCn07CnA3di5jb250ZW50SW5mb1ZhbGlkYXRvciA9IGNvbnRlbnRJbmZvVmFsaWRhdG9yOwoKdmFyIGVuY3J5cHRlZENvbnRlbnRJbmZvVmFsaWRhdG9yID0gewogIG5hbWU6ICdFbmNyeXB0ZWRDb250ZW50SW5mbycsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdFbmNyeXB0ZWRDb250ZW50SW5mby5jb250ZW50VHlwZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2NvbnRlbnRUeXBlJwogIH0sIHsKICAgIG5hbWU6ICdFbmNyeXB0ZWRDb250ZW50SW5mby5jb250ZW50RW5jcnlwdGlvbkFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnRW5jcnlwdGVkQ29udGVudEluZm8uY29udGVudEVuY3J5cHRpb25BbGdvcml0aG0uYWxnb3JpdGhtJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdlbmNBbGdvcml0aG0nCiAgICB9LCB7CiAgICAgIG5hbWU6ICdFbmNyeXB0ZWRDb250ZW50SW5mby5jb250ZW50RW5jcnlwdGlvbkFsZ29yaXRobS5wYXJhbWV0ZXInLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIGNhcHR1cmVBc24xOiAnZW5jUGFyYW1ldGVyJwogICAgfV0KICB9LCB7CiAgICBuYW1lOiAnRW5jcnlwdGVkQ29udGVudEluZm8uZW5jcnlwdGVkQ29udGVudCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLAogICAgdHlwZTogMCwKICAgIC8qIFRoZSBQS0NTIzcgc3RydWN0dXJlIG91dHB1dCBieSBPcGVuU1NMIHNvbWV3aGF0IGRpZmZlcnMgZnJvbSB3aGF0CiAgICAgKiBvdGhlciBpbXBsZW1lbnRhdGlvbnMgZG8gZ2VuZXJhdGUuCiAgICAgKgogICAgICogT3BlblNTTCBnZW5lcmF0ZXMgYSBzdHJ1Y3R1cmUgbGlrZSB0aGlzOgogICAgICogU0VRVUVOQ0UgewogICAgICogICAgLi4uCiAgICAgKiAgICBbMF0KICAgICAqICAgICAgIDI2IERBIDY3IEQyIDE3IDlDIDQ1IDNDIEIxIDJBIEE4IDU5IDJGIDI5IDMzIDM4CiAgICAgKiAgICAgICBDMyBDMyBERiA4NiA3MSA3NCA3QSAxOSA5RiA0MCBEMCAyOSBCRSA4NSA5MCA0NQogICAgICogICAgICAgLi4uCiAgICAgKiB9CiAgICAgKgogICAgICogV2hlcmVhcyBvdGhlciBpbXBsZW1lbnRhdGlvbnMgKGFuZCB0aGlzIFBLQ1MjNyBtb2R1bGUpIGdlbmVyYXRlOgogICAgICogU0VRVUVOQ0UgewogICAgICogICAgLi4uCiAgICAgKiAgICBbMF0gewogICAgICogICAgICAgT0NURVQgU1RSSU5HCiAgICAgKiAgICAgICAgICAyNiBEQSA2NyBEMiAxNyA5QyA0NSAzQyBCMSAyQSBBOCA1OSAyRiAyOSAzMyAzOAogICAgICogICAgICAgICAgQzMgQzMgREYgODYgNzEgNzQgN0EgMTkgOUYgNDAgRDAgMjkgQkUgODUgOTAgNDUKICAgICAqICAgICAgICAgIC4uLgogICAgICogICAgfQogICAgICogfQogICAgICoKICAgICAqIEluIG9yZGVyIHRvIHN1cHBvcnQgYm90aCwgd2UganVzdCBjYXB0dXJlIHRoZSBjb250ZXh0IHNwZWNpZmljCiAgICAgKiBmaWVsZCBoZXJlLiAgVGhlIE9DVEVUIFNUUklORyBiaXQgaXMgcmVtb3ZlZCBiZWxvdy4KICAgICAqLwogICAgY2FwdHVyZTogJ2VuY3J5cHRlZENvbnRlbnQnLAogICAgY2FwdHVyZUFzbjE6ICdlbmNyeXB0ZWRDb250ZW50QXNuMScKICB9XQp9OwoKcDd2LmVudmVsb3BlZERhdGFWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0VudmVsb3BlZERhdGEnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnRW52ZWxvcGVkRGF0YS5WZXJzaW9uJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ZlcnNpb24nCiAgfSwgewogICAgbmFtZTogJ0VudmVsb3BlZERhdGEuUmVjaXBpZW50SW5mb3MnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFVCwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgY2FwdHVyZUFzbjE6ICdyZWNpcGllbnRJbmZvcycKICB9XS5jb25jYXQoZW5jcnlwdGVkQ29udGVudEluZm9WYWxpZGF0b3IpCn07CgpwN3YuZW5jcnlwdGVkRGF0YVZhbGlkYXRvciA9IHsKICBuYW1lOiAnRW5jcnlwdGVkRGF0YScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdFbmNyeXB0ZWREYXRhLlZlcnNpb24nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAndmVyc2lvbicKICB9XS5jb25jYXQoZW5jcnlwdGVkQ29udGVudEluZm9WYWxpZGF0b3IpCn07Cgp2YXIgc2lnbmVyVmFsaWRhdG9yID0gewogIG5hbWU6ICdTaWduZXJJbmZvJywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIHZhbHVlOiBbewogICAgbmFtZTogJ1NpZ25lckluZm8udmVyc2lvbicsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZQogIH0sIHsKICAgIG5hbWU6ICdTaWduZXJJbmZvLmlzc3VlckFuZFNlcmlhbE51bWJlcicsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnU2lnbmVySW5mby5pc3N1ZXJBbmRTZXJpYWxOdW1iZXIuaXNzdWVyJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ2lzc3VlcicKICAgIH0sIHsKICAgICAgbmFtZTogJ1NpZ25lckluZm8uaXNzdWVyQW5kU2VyaWFsTnVtYmVyLnNlcmlhbE51bWJlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ3NlcmlhbCcKICAgIH1dCiAgfSwgewogICAgbmFtZTogJ1NpZ25lckluZm8uZGlnZXN0QWxnb3JpdGhtJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdTaWduZXJJbmZvLmRpZ2VzdEFsZ29yaXRobS5hbGdvcml0aG0nLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2RpZ2VzdEFsZ29yaXRobScKICAgIH0sIHsKICAgICAgbmFtZTogJ1NpZ25lckluZm8uZGlnZXN0QWxnb3JpdGhtLnBhcmFtZXRlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlQXNuMTogJ2RpZ2VzdFBhcmFtZXRlcicsCiAgICAgIG9wdGlvbmFsOiB0cnVlCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdTaWduZXJJbmZvLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICB0eXBlOiAwLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICBvcHRpb25hbDogdHJ1ZSwKICAgIGNhcHR1cmU6ICdhdXRoZW50aWNhdGVkQXR0cmlidXRlcycKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVySW5mby5kaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgY2FwdHVyZTogJ3NpZ25hdHVyZUFsZ29yaXRobScKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVySW5mby5lbmNyeXB0ZWREaWdlc3QnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3NpZ25hdHVyZScKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVySW5mby51bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICB0eXBlOiAxLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICBvcHRpb25hbDogdHJ1ZSwKICAgIGNhcHR1cmU6ICd1bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzJwogIH1dCn07CgpwN3Yuc2lnbmVkRGF0YVZhbGlkYXRvciA9IHsKICBuYW1lOiAnU2lnbmVkRGF0YScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdTaWduZWREYXRhLlZlcnNpb24nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAndmVyc2lvbicKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVkRGF0YS5EaWdlc3RBbGdvcml0aG1zJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVQsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAnZGlnZXN0QWxnb3JpdGhtcycKICB9LAogIGNvbnRlbnRJbmZvVmFsaWRhdG9yLAogIHsKICAgIG5hbWU6ICdTaWduZWREYXRhLkNlcnRpZmljYXRlcycsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLAogICAgdHlwZTogMCwKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgY2FwdHVyZUFzbjE6ICdjZXJ0aWZpY2F0ZXMnCiAgfSwgewogICAgbmFtZTogJ1NpZ25lZERhdGEuQ2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdHMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgIHR5cGU6IDEsCiAgICBvcHRpb25hbDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAnY3JscycKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVkRGF0YS5TaWduZXJJbmZvcycsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VULAogICAgY2FwdHVyZTogJ3NpZ25lckluZm9zJywKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgdmFsdWU6IFtzaWduZXJWYWxpZGF0b3JdCiAgfV0KfTsKCnA3di5yZWNpcGllbnRJbmZvVmFsaWRhdG9yID0gewogIG5hbWU6ICdSZWNpcGllbnRJbmZvJywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIHZhbHVlOiBbewogICAgbmFtZTogJ1JlY2lwaWVudEluZm8udmVyc2lvbicsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICd2ZXJzaW9uJwogIH0sIHsKICAgIG5hbWU6ICdSZWNpcGllbnRJbmZvLmlzc3VlckFuZFNlcmlhbCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnUmVjaXBpZW50SW5mby5pc3N1ZXJBbmRTZXJpYWwuaXNzdWVyJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ2lzc3VlcicKICAgIH0sIHsKICAgICAgbmFtZTogJ1JlY2lwaWVudEluZm8uaXNzdWVyQW5kU2VyaWFsLnNlcmlhbE51bWJlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ3NlcmlhbCcKICAgIH1dCiAgfSwgewogICAgbmFtZTogJ1JlY2lwaWVudEluZm8ua2V5RW5jcnlwdGlvbkFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnUmVjaXBpZW50SW5mby5rZXlFbmNyeXB0aW9uQWxnb3JpdGhtLmFsZ29yaXRobScsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlOiAnZW5jQWxnb3JpdGhtJwogICAgfSwgewogICAgICBuYW1lOiAnUmVjaXBpZW50SW5mby5rZXlFbmNyeXB0aW9uQWxnb3JpdGhtLnBhcmFtZXRlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlQXNuMTogJ2VuY1BhcmFtZXRlcicKICAgIH1dCiAgfSwgewogICAgbmFtZTogJ1JlY2lwaWVudEluZm8uZW5jcnlwdGVkS2V5JywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5PQ1RFVFNUUklORywKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdlbmNLZXknCiAgfV0KfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3BrY3M3YXNuMSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9wa2NzN2FzbjEnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9hc24xJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIG1hc2sgZ2VuZXJhdGlvbiBmdW5jdGlvbiBNR0YxLgogKgogKiBAYXV0aG9yIFN0ZWZhbiBTaWVnbAogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIgU3RlZmFuIFNpZWdsIDxzdGVzaWVAYnJva2VucGlwZS5kZT4KICogQ29weXJpZ2h0IChjKSAyMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UubWdmID0gZm9yZ2UubWdmIHx8IHt9Owp2YXIgbWdmMSA9IGZvcmdlLm1nZi5tZ2YxID0gZm9yZ2UubWdmMSA9IGZvcmdlLm1nZjEgfHwge307CgovKioKICogQ3JlYXRlcyBhIE1HRjEgbWFzayBnZW5lcmF0aW9uIGZ1bmN0aW9uIG9iamVjdC4KICoKICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBBUEkgdG8gdXNlIChlZzogZm9yZ2UubWQuc2hhMS5jcmVhdGUoKSkuCiAqCiAqIEByZXR1cm4gYSBtYXNrIGdlbmVyYXRpb24gZnVuY3Rpb24gb2JqZWN0LgogKi8KbWdmMS5jcmVhdGUgPSBmdW5jdGlvbihtZCkgewogIHZhciBtZ2YgPSB7CiAgICAvKioKICAgICAqIEdlbmVyYXRlIG1hc2sgb2Ygc3BlY2lmaWVkIGxlbmd0aC4KICAgICAqCiAgICAgKiBAcGFyYW0ge1N0cmluZ30gc2VlZCBUaGUgc2VlZCBmb3IgbWFzayBnZW5lcmF0aW9uLgogICAgICogQHBhcmFtIG1hc2tMZW4gTnVtYmVyIG9mIGJ5dGVzIHRvIGdlbmVyYXRlLgogICAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgZ2VuZXJhdGVkIG1hc2suCiAgICAgKi8KICAgIGdlbmVyYXRlOiBmdW5jdGlvbihzZWVkLCBtYXNrTGVuKSB7CiAgICAgIC8qIDIuIExldCBUIGJlIHRoZSBlbXB0eSBvY3RldCBzdHJpbmcuICovCiAgICAgIHZhciB0ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwoKICAgICAgLyogMy4gRm9yIGNvdW50ZXIgZnJvbSAwIHRvIGNlaWwobWFza0xlbiAvIGhMZW4pLCBkbyB0aGUgZm9sbG93aW5nOiAqLwogICAgICB2YXIgbGVuID0gTWF0aC5jZWlsKG1hc2tMZW4gLyBtZC5kaWdlc3RMZW5ndGgpOwogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgICAvKiBhLiBDb252ZXJ0IGNvdW50ZXIgdG8gYW4gb2N0ZXQgc3RyaW5nIEMgb2YgbGVuZ3RoIDQgb2N0ZXRzICovCiAgICAgICAgdmFyIGMgPSBuZXcgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKCk7CiAgICAgICAgYy5wdXRJbnQzMihpKTsKCiAgICAgICAgLyogYi4gQ29uY2F0ZW5hdGUgdGhlIGhhc2ggb2YgdGhlIHNlZWQgbWdmU2VlZCBhbmQgQyB0byB0aGUgb2N0ZXQKICAgICAgICAgKiBzdHJpbmcgVDogKi8KICAgICAgICBtZC5zdGFydCgpOwogICAgICAgIG1kLnVwZGF0ZShzZWVkICsgYy5nZXRCeXRlcygpKTsKICAgICAgICB0LnB1dEJ1ZmZlcihtZC5kaWdlc3QoKSk7CiAgICAgIH0KCiAgICAgIC8qIE91dHB1dCB0aGUgbGVhZGluZyBtYXNrTGVuIG9jdGV0cyBvZiBUIGFzIHRoZSBvY3RldCBzdHJpbmcgbWFzay4gKi8KICAgICAgdC50cnVuY2F0ZSh0Lmxlbmd0aCgpIC0gbWFza0xlbik7CiAgICAgIHJldHVybiB0LmdldEJ5dGVzKCk7CiAgICB9CiAgfTsKCiAgcmV0dXJuIG1nZjsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ21nZjEnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvbWdmMScsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogTm9kZS5qcyBtb2R1bGUgZm9yIEZvcmdlIG1hc2sgZ2VuZXJhdGlvbiBmdW5jdGlvbnMuCiAqCiAqIEBhdXRob3IgU3RlZmFuIFNpZWdsCiAqCiAqIENvcHlyaWdodCAyMDEyIFN0ZWZhbiBTaWVnbCA8c3Rlc2llQGJyb2tlbnBpcGUuZGU+CiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UubWdmID0gZm9yZ2UubWdmIHx8IHt9Owpmb3JnZS5tZ2YubWdmMSA9IGZvcmdlLm1nZjE7Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdtZ2YnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvbWdmJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vbWdmMSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIFBLQ1MjMSBQU1Mgc2lnbmF0dXJlIHBhZGRpbmcuCiAqCiAqIEBhdXRob3IgU3RlZmFuIFNpZWdsCiAqCiAqIENvcHlyaWdodCAoYykgMjAxMiBTdGVmYW4gU2llZ2wgPHN0ZXNpZUBicm9rZW5waXBlLmRlPgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIHNob3J0Y3V0IGZvciBQU1MgQVBJCnZhciBwc3MgPSBmb3JnZS5wc3MgPSBmb3JnZS5wc3MgfHwge307CgovKioKICogQ3JlYXRlcyBhIFBTUyBzaWduYXR1cmUgc2NoZW1lIG9iamVjdC4KICoKICogVGhlcmUgYXJlIHNldmVyYWwgd2F5cyB0byBwcm92aWRlIGEgc2FsdCBmb3IgZW5jb2Rpbmc6CiAqCiAqIDEuIFNwZWNpZnkgdGhlIHNhbHRMZW5ndGggb25seSBhbmQgdGhlIGJ1aWx0LWluIFBSTkcgd2lsbCBnZW5lcmF0ZSBpdC4KICogMi4gU3BlY2lmeSB0aGUgc2FsdExlbmd0aCBhbmQgYSBjdXN0b20gUFJORyB3aXRoICdnZXRCeXRlc1N5bmMnIGRlZmluZWQgdGhhdAogKiAgIHdpbGwgYmUgdXNlZC4KICogMy4gU3BlY2lmeSB0aGUgc2FsdCBpdHNlbGYgYXMgYSBmb3JnZS51dGlsLkJ5dGVCdWZmZXIuCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgbWQgdGhlIG1lc3NhZ2UgZGlnZXN0IG9iamVjdCB0byB1c2UsIGEgZm9yZ2UgbWQgaW5zdGFuY2UuCiAqICAgICAgICAgIG1nZiB0aGUgbWFzayBnZW5lcmF0aW9uIGZ1bmN0aW9uIHRvIHVzZSwgYSBmb3JnZSBtZ2YgaW5zdGFuY2UuCiAqICAgICAgICAgIFtzYWx0TGVuZ3RoXSB0aGUgbGVuZ3RoIG9mIHRoZSBzYWx0IGluIG9jdGV0cy4KICogICAgICAgICAgW3BybmddIHRoZSBwc2V1ZG8tcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdG8gdXNlIHRvIHByb2R1Y2UgYSBzYWx0LgogKiAgICAgICAgICBbc2FsdF0gdGhlIHNhbHQgdG8gdXNlIHdoZW4gZW5jb2RpbmcuCiAqCiAqIEByZXR1cm4gYSBzaWduYXR1cmUgc2NoZW1lIG9iamVjdC4KICovCnBzcy5jcmVhdGUgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgLy8gYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgdy9sZWdhY3kgYXJnczogaGFzaCwgbWdmLCBzTGVuCiAgaWYoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykgewogICAgb3B0aW9ucyA9IHsKICAgICAgbWQ6IGFyZ3VtZW50c1swXSwKICAgICAgbWdmOiBhcmd1bWVudHNbMV0sCiAgICAgIHNhbHRMZW5ndGg6IGFyZ3VtZW50c1syXQogICAgfTsKICB9CgogIHZhciBoYXNoID0gb3B0aW9ucy5tZDsKICB2YXIgbWdmID0gb3B0aW9ucy5tZ2Y7CiAgdmFyIGhMZW4gPSBoYXNoLmRpZ2VzdExlbmd0aDsKCiAgdmFyIHNhbHRfID0gb3B0aW9ucy5zYWx0IHx8IG51bGw7CiAgaWYodHlwZW9mIHNhbHRfID09PSAnc3RyaW5nJykgewogICAgLy8gYXNzdW1lIGJpbmFyeS1lbmNvZGVkIHN0cmluZwogICAgc2FsdF8gPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihzYWx0Xyk7CiAgfQoKICB2YXIgc0xlbjsKICBpZignc2FsdExlbmd0aCcgaW4gb3B0aW9ucykgewogICAgc0xlbiA9IG9wdGlvbnMuc2FsdExlbmd0aDsKICB9IGVsc2UgaWYoc2FsdF8gIT09IG51bGwpIHsKICAgIHNMZW4gPSBzYWx0Xy5sZW5ndGgoKTsKICB9IGVsc2UgewogICAgdGhyb3cgbmV3IEVycm9yKCdTYWx0IGxlbmd0aCBub3Qgc3BlY2lmaWVkIG9yIHNwZWNpZmljIHNhbHQgbm90IGdpdmVuLicpOwogIH0KCiAgaWYoc2FsdF8gIT09IG51bGwgJiYgc2FsdF8ubGVuZ3RoKCkgIT09IHNMZW4pIHsKICAgIHRocm93IG5ldyBFcnJvcignR2l2ZW4gc2FsdCBsZW5ndGggZG9lcyBub3QgbWF0Y2ggbGVuZ3RoIG9mIGdpdmVuIHNhbHQuJyk7CiAgfQoKICB2YXIgcHJuZyA9IG9wdGlvbnMucHJuZyB8fCBmb3JnZS5yYW5kb207CgogIHZhciBwc3NvYmogPSB7fTsKCiAgLyoqCiAgICogRW5jb2RlcyBhIFBTUyBzaWduYXR1cmUuCiAgICoKICAgKiBUaGlzIGZ1bmN0aW9uIGltcGxlbWVudHMgRU1TQS1QU1MtRU5DT0RFIGFzIHBlciBSRkMgMzQ0Nywgc2VjdGlvbiA5LjEuMS4KICAgKgogICAqIEBwYXJhbSBtZCB0aGUgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0IHdpdGggdGhlIGhhc2ggdG8gc2lnbi4KICAgKiBAcGFyYW0gbW9kc0JpdHMgdGhlIGxlbmd0aCBvZiB0aGUgUlNBIG1vZHVsdXMgaW4gYml0cy4KICAgKgogICAqIEByZXR1cm4gdGhlIGVuY29kZWQgbWVzc2FnZSBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBsZW5ndGgKICAgKiAgICAgICAgICAgY2VpbCgobW9kQml0cyAtIDEpIC8gOCkuCiAgICovCiAgcHNzb2JqLmVuY29kZSA9IGZ1bmN0aW9uKG1kLCBtb2RCaXRzKSB7CiAgICB2YXIgaTsKICAgIHZhciBlbUJpdHMgPSBtb2RCaXRzIC0gMTsKICAgIHZhciBlbUxlbiA9IE1hdGguY2VpbChlbUJpdHMgLyA4KTsKCiAgICAvKiAyLiBMZXQgbUhhc2ggPSBIYXNoKE0pLCBhbiBvY3RldCBzdHJpbmcgb2YgbGVuZ3RoIGhMZW4uICovCiAgICB2YXIgbUhhc2ggPSBtZC5kaWdlc3QoKS5nZXRCeXRlcygpOwoKICAgIC8qIDMuIElmIGVtTGVuIDwgaExlbiArIHNMZW4gKyAyLCBvdXRwdXQgImVuY29kaW5nIGVycm9yIiBhbmQgc3RvcC4gKi8KICAgIGlmKGVtTGVuIDwgaExlbiArIHNMZW4gKyAyKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignTWVzc2FnZSBpcyB0b28gbG9uZyB0byBlbmNyeXB0LicpOwogICAgfQoKICAgIC8qIDQuIEdlbmVyYXRlIGEgcmFuZG9tIG9jdGV0IHN0cmluZyBzYWx0IG9mIGxlbmd0aCBzTGVuOyBpZiBzTGVuID0gMCwKICAgICAqICAgIHRoZW4gc2FsdCBpcyB0aGUgZW1wdHkgc3RyaW5nLiAqLwogICAgdmFyIHNhbHQ7CiAgICBpZihzYWx0XyA9PT0gbnVsbCkgewogICAgICBzYWx0ID0gcHJuZy5nZXRCeXRlc1N5bmMoc0xlbik7CiAgICB9IGVsc2UgewogICAgICBzYWx0ID0gc2FsdF8uYnl0ZXMoKTsKICAgIH0KCiAgICAvKiA1LiBMZXQgTScgPSAoMHgpMDAgMDAgMDAgMDAgMDAgMDAgMDAgMDAgfHwgbUhhc2ggfHwgc2FsdDsgKi8KICAgIHZhciBtXyA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICAgIG1fLmZpbGxXaXRoQnl0ZSgwLCA4KTsKICAgIG1fLnB1dEJ5dGVzKG1IYXNoKTsKICAgIG1fLnB1dEJ5dGVzKHNhbHQpOwoKICAgIC8qIDYuIExldCBIID0gSGFzaChNJyksIGFuIG9jdGV0IHN0cmluZyBvZiBsZW5ndGggaExlbi4gKi8KICAgIGhhc2guc3RhcnQoKTsKICAgIGhhc2gudXBkYXRlKG1fLmdldEJ5dGVzKCkpOwogICAgdmFyIGggPSBoYXNoLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CgogICAgLyogNy4gR2VuZXJhdGUgYW4gb2N0ZXQgc3RyaW5nIFBTIGNvbnNpc3Rpbmcgb2YgZW1MZW4gLSBzTGVuIC0gaExlbiAtIDIKICAgICAqICAgIHplcm8gb2N0ZXRzLiAgVGhlIGxlbmd0aCBvZiBQUyBtYXkgYmUgMC4gKi8KICAgIHZhciBwcyA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICAgIHBzLmZpbGxXaXRoQnl0ZSgwLCBlbUxlbiAtIHNMZW4gLSBoTGVuIC0gMik7CgogICAgLyogOC4gTGV0IERCID0gUFMgfHwgMHgwMSB8fCBzYWx0OyBEQiBpcyBhbiBvY3RldCBzdHJpbmcgb2YgbGVuZ3RoCiAgICAgKiAgICBlbUxlbiAtIGhMZW4gLSAxLiAqLwogICAgcHMucHV0Qnl0ZSgweDAxKTsKICAgIHBzLnB1dEJ5dGVzKHNhbHQpOwogICAgdmFyIGRiID0gcHMuZ2V0Qnl0ZXMoKTsKCiAgICAvKiA5LiBMZXQgZGJNYXNrID0gTUdGKEgsIGVtTGVuIC0gaExlbiAtIDEpLiAqLwogICAgdmFyIG1hc2tMZW4gPSBlbUxlbiAtIGhMZW4gLSAxOwogICAgdmFyIGRiTWFzayA9IG1nZi5nZW5lcmF0ZShoLCBtYXNrTGVuKTsKCiAgICAvKiAxMC4gTGV0IG1hc2tlZERCID0gREIgXHhvciBkYk1hc2suICovCiAgICB2YXIgbWFza2VkREIgPSAnJzsKICAgIGZvcihpID0gMDsgaSA8IG1hc2tMZW47IGkgKyspIHsKICAgICAgbWFza2VkREIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShkYi5jaGFyQ29kZUF0KGkpIF4gZGJNYXNrLmNoYXJDb2RlQXQoaSkpOwogICAgfQoKICAgIC8qIDExLiBTZXQgdGhlIGxlZnRtb3N0IDhlbUxlbiAtIGVtQml0cyBiaXRzIG9mIHRoZSBsZWZ0bW9zdCBvY3RldCBpbgogICAgICogICAgIG1hc2tlZERCIHRvIHplcm8uICovCiAgICB2YXIgbWFzayA9ICgweEZGMDAgPj4gKDggKiBlbUxlbiAtIGVtQml0cykpICYgMHhGRjsKICAgIG1hc2tlZERCID0gU3RyaW5nLmZyb21DaGFyQ29kZShtYXNrZWREQi5jaGFyQ29kZUF0KDApICYgfm1hc2spICsKICAgICAgbWFza2VkREIuc3Vic3RyKDEpOwoKICAgIC8qIDEyLiBMZXQgRU0gPSBtYXNrZWREQiB8fCBIIHx8IDB4YmMuCiAgICAgKiAxMy4gT3V0cHV0IEVNLiAqLwogICAgcmV0dXJuIG1hc2tlZERCICsgaCArIFN0cmluZy5mcm9tQ2hhckNvZGUoMHhiYyk7CiAgfTsKCiAgLyoqCiAgICogVmVyaWZpZXMgYSBQU1Mgc2lnbmF0dXJlLgogICAqCiAgICogVGhpcyBmdW5jdGlvbiBpbXBsZW1lbnRzIEVNU0EtUFNTLVZFUklGWSBhcyBwZXIgUkZDIDM0NDcsIHNlY3Rpb24gOS4xLjIuCiAgICoKICAgKiBAcGFyYW0gbUhhc2ggdGhlIG1lc3NhZ2UgZGlnZXN0IGhhc2gsIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nLCB0bwogICAqICAgICAgICAgY29tcGFyZSBhZ2FpbnN0IHRoZSBzaWduYXR1cmUuCiAgICogQHBhcmFtIGVtIHRoZSBlbmNvZGVkIG1lc3NhZ2UsIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nCiAgICogICAgICAgICAgKFJTQSBkZWNyeXB0aW9uIHJlc3VsdCkuCiAgICogQHBhcmFtIG1vZHNCaXRzIHRoZSBsZW5ndGggb2YgdGhlIFJTQSBtb2R1bHVzIGluIGJpdHMuCiAgICoKICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHNpZ25hdHVyZSB3YXMgdmVyaWZpZWQsIGZhbHNlIGlmIG5vdC4KICAgKi8KICBwc3NvYmoudmVyaWZ5ID0gZnVuY3Rpb24obUhhc2gsIGVtLCBtb2RCaXRzKSB7CiAgICB2YXIgaTsKICAgIHZhciBlbUJpdHMgPSBtb2RCaXRzIC0gMTsKICAgIHZhciBlbUxlbiA9IE1hdGguY2VpbChlbUJpdHMgLyA4KTsKCiAgICAvKiBjLiBDb252ZXJ0IHRoZSBtZXNzYWdlIHJlcHJlc2VudGF0aXZlIG0gdG8gYW4gZW5jb2RlZCBtZXNzYWdlIEVNCiAgICAgKiAgICBvZiBsZW5ndGggZW1MZW4gPSBjZWlsKChtb2RCaXRzIC0gMSkgLyA4KSBvY3RldHMsIHdoZXJlIG1vZEJpdHMKICAgICAqICAgIGlzIHRoZSBsZW5ndGggaW4gYml0cyBvZiB0aGUgUlNBIG1vZHVsdXMgbiAqLwogICAgZW0gPSBlbS5zdWJzdHIoLWVtTGVuKTsKCiAgICAvKiAzLiBJZiBlbUxlbiA8IGhMZW4gKyBzTGVuICsgMiwgb3V0cHV0ICJpbmNvbnNpc3RlbnQiIGFuZCBzdG9wLiAqLwogICAgaWYoZW1MZW4gPCBoTGVuICsgc0xlbiArIDIpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbmNvbnNpc3RlbnQgcGFyYW1ldGVycyB0byBQU1Mgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbi4nKTsKICAgIH0KCiAgICAvKiA0LiBJZiB0aGUgcmlnaHRtb3N0IG9jdGV0IG9mIEVNIGRvZXMgbm90IGhhdmUgaGV4YWRlY2ltYWwgdmFsdWUKICAgICAqICAgIDB4YmMsIG91dHB1dCAiaW5jb25zaXN0ZW50IiBhbmQgc3RvcC4gKi8KICAgIGlmKGVtLmNoYXJDb2RlQXQoZW1MZW4gLSAxKSAhPT0gMHhiYykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VuY29kZWQgbWVzc2FnZSBkb2VzIG5vdCBlbmQgaW4gMHhCQy4nKTsKICAgIH0KCiAgICAvKiA1LiBMZXQgbWFza2VkREIgYmUgdGhlIGxlZnRtb3N0IGVtTGVuIC0gaExlbiAtIDEgb2N0ZXRzIG9mIEVNLCBhbmQKICAgICAqICAgIGxldCBIIGJlIHRoZSBuZXh0IGhMZW4gb2N0ZXRzLiAqLwogICAgdmFyIG1hc2tMZW4gPSBlbUxlbiAtIGhMZW4gLSAxOwogICAgdmFyIG1hc2tlZERCID0gZW0uc3Vic3RyKDAsIG1hc2tMZW4pOwogICAgdmFyIGggPSBlbS5zdWJzdHIobWFza0xlbiwgaExlbik7CgogICAgLyogNi4gSWYgdGhlIGxlZnRtb3N0IDhlbUxlbiAtIGVtQml0cyBiaXRzIG9mIHRoZSBsZWZ0bW9zdCBvY3RldCBpbgogICAgICogICAgbWFza2VkREIgYXJlIG5vdCBhbGwgZXF1YWwgdG8gemVybywgb3V0cHV0ICJpbmNvbnNpc3RlbnQiIGFuZCBzdG9wLiAqLwogICAgdmFyIG1hc2sgPSAoMHhGRjAwID4+ICg4ICogZW1MZW4gLSBlbUJpdHMpKSAmIDB4RkY7CiAgICBpZigobWFza2VkREIuY2hhckNvZGVBdCgwKSAmIG1hc2spICE9PSAwKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignQml0cyBiZXlvbmQga2V5c2l6ZSBub3QgemVybyBhcyBleHBlY3RlZC4nKTsKICAgIH0KCiAgICAvKiA3LiBMZXQgZGJNYXNrID0gTUdGKEgsIGVtTGVuIC0gaExlbiAtIDEpLiAqLwogICAgdmFyIGRiTWFzayA9IG1nZi5nZW5lcmF0ZShoLCBtYXNrTGVuKTsKCiAgICAvKiA4LiBMZXQgREIgPSBtYXNrZWREQiBceG9yIGRiTWFzay4gKi8KICAgIHZhciBkYiA9ICcnOwogICAgZm9yKGkgPSAwOyBpIDwgbWFza0xlbjsgaSArKykgewogICAgICBkYiArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKG1hc2tlZERCLmNoYXJDb2RlQXQoaSkgXiBkYk1hc2suY2hhckNvZGVBdChpKSk7CiAgICB9CgogICAgLyogOS4gU2V0IHRoZSBsZWZ0bW9zdCA4ZW1MZW4gLSBlbUJpdHMgYml0cyBvZiB0aGUgbGVmdG1vc3Qgb2N0ZXQKICAgICAqIGluIERCIHRvIHplcm8uICovCiAgICBkYiA9IFN0cmluZy5mcm9tQ2hhckNvZGUoZGIuY2hhckNvZGVBdCgwKSAmIH5tYXNrKSArIGRiLnN1YnN0cigxKTsKCiAgICAvKiAxMC4gSWYgdGhlIGVtTGVuIC0gaExlbiAtIHNMZW4gLSAyIGxlZnRtb3N0IG9jdGV0cyBvZiBEQiBhcmUgbm90IHplcm8KICAgICAqIG9yIGlmIHRoZSBvY3RldCBhdCBwb3NpdGlvbiBlbUxlbiAtIGhMZW4gLSBzTGVuIC0gMSAodGhlIGxlZnRtb3N0CiAgICAgKiBwb3NpdGlvbiBpcyAicG9zaXRpb24gMSIpIGRvZXMgbm90IGhhdmUgaGV4YWRlY2ltYWwgdmFsdWUgMHgwMSwKICAgICAqIG91dHB1dCAiaW5jb25zaXN0ZW50IiBhbmQgc3RvcC4gKi8KICAgIHZhciBjaGVja0xlbiA9IGVtTGVuIC0gaExlbiAtIHNMZW4gLSAyOwogICAgZm9yKGkgPSAwOyBpIDwgY2hlY2tMZW47IGkgKyspIHsKICAgICAgaWYoZGIuY2hhckNvZGVBdChpKSAhPT0gMHgwMCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcignTGVmdG1vc3Qgb2N0ZXRzIG5vdCB6ZXJvIGFzIGV4cGVjdGVkJyk7CiAgICAgIH0KICAgIH0KCiAgICBpZihkYi5jaGFyQ29kZUF0KGNoZWNrTGVuKSAhPT0gMHgwMSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ0luY29uc2lzdGVudCBQU1Mgc2lnbmF0dXJlLCAweDAxIG1hcmtlciBub3QgZm91bmQnKTsKICAgIH0KCiAgICAvKiAxMS4gTGV0IHNhbHQgYmUgdGhlIGxhc3Qgc0xlbiBvY3RldHMgb2YgREIuICovCiAgICB2YXIgc2FsdCA9IGRiLnN1YnN0cigtc0xlbik7CgogICAgLyogMTIuICBMZXQgTScgPSAoMHgpMDAgMDAgMDAgMDAgMDAgMDAgMDAgMDAgfHwgbUhhc2ggfHwgc2FsdCAqLwogICAgdmFyIG1fID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogICAgbV8uZmlsbFdpdGhCeXRlKDAsIDgpOwogICAgbV8ucHV0Qnl0ZXMobUhhc2gpOwogICAgbV8ucHV0Qnl0ZXMoc2FsdCk7CgogICAgLyogMTMuIExldCBIJyA9IEhhc2goTScpLCBhbiBvY3RldCBzdHJpbmcgb2YgbGVuZ3RoIGhMZW4uICovCiAgICBoYXNoLnN0YXJ0KCk7CiAgICBoYXNoLnVwZGF0ZShtXy5nZXRCeXRlcygpKTsKICAgIHZhciBoXyA9IGhhc2guZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKCiAgICAvKiAxNC4gSWYgSCA9IEgnLCBvdXRwdXQgImNvbnNpc3RlbnQuIiBPdGhlcndpc2UsIG91dHB1dCAiaW5jb25zaXN0ZW50LiIgKi8KICAgIHJldHVybiBoID09PSBoXzsKICB9OwoKICByZXR1cm4gcHNzb2JqOwp9OwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncHNzJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3BzcycsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL3JhbmRvbScsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBYLjUwOSBhbmQgcmVsYXRlZCBjb21wb25lbnRzIChzdWNoIGFzCiAqIENlcnRpZmljYXRpb24gU2lnbmluZyBSZXF1ZXN0cykgb2YgYSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKgogKiBUaGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgYW4gWC41MDl2MyBjZXJ0aWZpY2F0ZSBpcyBhcyBmb2xsb3dzCiAqIChzZWUgUkZDIDI0NTkpOgogKgogKiBDZXJ0aWZpY2F0ZSA6Oj0gU0VRVUVOQ0UgewogKiAgIHRic0NlcnRpZmljYXRlICAgICAgIFRCU0NlcnRpZmljYXRlLAogKiAgIHNpZ25hdHVyZUFsZ29yaXRobSAgIEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgc2lnbmF0dXJlVmFsdWUgICAgICAgQklUIFNUUklORwogKiB9CiAqCiAqIFRCU0NlcnRpZmljYXRlIDo6PSBTRVFVRU5DRSB7CiAqICAgdmVyc2lvbiAgICAgICAgIFswXSAgRVhQTElDSVQgVmVyc2lvbiBERUZBVUxUIHYxLAogKiAgIHNlcmlhbE51bWJlciAgICAgICAgIENlcnRpZmljYXRlU2VyaWFsTnVtYmVyLAogKiAgIHNpZ25hdHVyZSAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgaXNzdWVyICAgICAgICAgICAgICAgTmFtZSwKICogICB2YWxpZGl0eSAgICAgICAgICAgICBWYWxpZGl0eSwKICogICBzdWJqZWN0ICAgICAgICAgICAgICBOYW1lLAogKiAgIHN1YmplY3RQdWJsaWNLZXlJbmZvIFN1YmplY3RQdWJsaWNLZXlJbmZvLAogKiAgIGlzc3VlclVuaXF1ZUlEICBbMV0gIElNUExJQ0lUIFVuaXF1ZUlkZW50aWZpZXIgT1BUSU9OQUwsCiAqICAgICAgICAgICAgICAgICAgICAgICAgLS0gSWYgcHJlc2VudCwgdmVyc2lvbiBzaGFsbCBiZSB2MiBvciB2MwogKiAgIHN1YmplY3RVbmlxdWVJRCBbMl0gIElNUExJQ0lUIFVuaXF1ZUlkZW50aWZpZXIgT1BUSU9OQUwsCiAqICAgICAgICAgICAgICAgICAgICAgICAgLS0gSWYgcHJlc2VudCwgdmVyc2lvbiBzaGFsbCBiZSB2MiBvciB2MwogKiAgIGV4dGVuc2lvbnMgICAgICBbM10gIEVYUExJQ0lUIEV4dGVuc2lvbnMgT1BUSU9OQUwKICogICAgICAgICAgICAgICAgICAgICAgICAtLSBJZiBwcmVzZW50LCB2ZXJzaW9uIHNoYWxsIGJlIHYzCiAqIH0KICoKICogVmVyc2lvbiA6Oj0gSU5URUdFUiAgeyB2MSgwKSwgdjIoMSksIHYzKDIpIH0KICoKICogQ2VydGlmaWNhdGVTZXJpYWxOdW1iZXIgOjo9IElOVEVHRVIKICoKICogTmFtZSA6Oj0gQ0hPSUNFIHsKICogICAvLyBvbmx5IG9uZSBwb3NzaWJsZSBjaG9pY2UgZm9yIG5vdwogKiAgIFJETlNlcXVlbmNlCiAqIH0KICoKICogUkROU2VxdWVuY2UgOjo9IFNFUVVFTkNFIE9GIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUKICoKICogUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZSA6Oj0gU0VUIE9GIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZQogKgogKiBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgOjo9IFNFUVVFTkNFIHsKICogICB0eXBlICAgICBBdHRyaWJ1dGVUeXBlLAogKiAgIHZhbHVlICAgIEF0dHJpYnV0ZVZhbHVlCiAqIH0KICogQXR0cmlidXRlVHlwZSA6Oj0gT0JKRUNUIElERU5USUZJRVIKICogQXR0cmlidXRlVmFsdWUgOjo9IEFOWSBERUZJTkVEIEJZIEF0dHJpYnV0ZVR5cGUKICoKICogVmFsaWRpdHkgOjo9IFNFUVVFTkNFIHsKICogICBub3RCZWZvcmUgICAgICBUaW1lLAogKiAgIG5vdEFmdGVyICAgICAgIFRpbWUKICogfQogKgogKiBUaW1lIDo6PSBDSE9JQ0UgewogKiAgIHV0Y1RpbWUgICAgICAgIFVUQ1RpbWUsCiAqICAgZ2VuZXJhbFRpbWUgICAgR2VuZXJhbGl6ZWRUaW1lCiAqIH0KICoKICogVW5pcXVlSWRlbnRpZmllciA6Oj0gQklUIFNUUklORwogKgogKiBTdWJqZWN0UHVibGljS2V5SW5mbyA6Oj0gU0VRVUVOQ0UgewogKiAgIGFsZ29yaXRobSAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgc3ViamVjdFB1YmxpY0tleSAgICAgQklUIFNUUklORwogKiB9CiAqCiAqIEV4dGVuc2lvbnMgOjo9IFNFUVVFTkNFIFNJWkUgKDEuLk1BWCkgT0YgRXh0ZW5zaW9uCiAqCiAqIEV4dGVuc2lvbiA6Oj0gU0VRVUVOQ0UgewogKiAgIGV4dG5JRCAgICAgIE9CSkVDVCBJREVOVElGSUVSLAogKiAgIGNyaXRpY2FsICAgIEJPT0xFQU4gREVGQVVMVCBGQUxTRSwKICogICBleHRuVmFsdWUgICBPQ1RFVCBTVFJJTkcKICogfQogKgogKiBUaGUgb25seSBrZXkgYWxnb3JpdGhtIGN1cnJlbnRseSBzdXBwb3J0ZWQgZm9yIFBLSSBpcyBSU0EuCiAqCiAqIFJTQVNTQS1QU1Mgc2lnbmF0dXJlcyBhcmUgZGVzY3JpYmVkIGluIFJGQyAzNDQ3IGFuZCBSRkMgNDA1NS4KICoKICogUEtDUyMxMCB2MS43IGRlc2NyaWJlcyBjZXJ0aWZpY2F0ZSBzaWduaW5nIHJlcXVlc3RzOgogKgogKiBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm86CiAqCiAqIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gICAgICAgSU5URUdFUiB7IHYxKDApIH0gKHYxLC4uLiksCiAqICAgc3ViamVjdCAgICAgICBOYW1lLAogKiAgIHN1YmplY3RQS0luZm8gU3ViamVjdFB1YmxpY0tleUluZm97eyBQS0luZm9BbGdvcml0aG1zIH19LAogKiAgIGF0dHJpYnV0ZXMgICAgWzBdIEF0dHJpYnV0ZXN7eyBDUklBdHRyaWJ1dGVzIH19CiAqIH0KICoKICogQXR0cmlidXRlcyB7IEFUVFJJQlVURTpJT1NldCB9IDo6PSBTRVQgT0YgQXR0cmlidXRle3sgSU9TZXQgfX0KICoKICogQ1JJQXR0cmlidXRlcyAgQVRUUklCVVRFICA6Oj0gewogKiAgIC4uLiAtLSBhZGQgYW55IGxvY2FsbHkgZGVmaW5lZCBhdHRyaWJ1dGVzIGhlcmUgLS0gfQogKgogKiBBdHRyaWJ1dGUgeyBBVFRSSUJVVEU6SU9TZXQgfSA6Oj0gU0VRVUVOQ0UgewogKiAgIHR5cGUgICBBVFRSSUJVVEUuJmlkKHtJT1NldH0pLAogKiAgIHZhbHVlcyBTRVQgU0laRSgxLi5NQVgpIE9GIEFUVFJJQlVURS4mVHlwZSh7SU9TZXR9e0B0eXBlfSkKICogfQogKgogKiBDZXJ0aWZpY2F0aW9uUmVxdWVzdCA6Oj0gU0VRVUVOQ0UgewogKiAgIGNlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8sCiAqICAgc2lnbmF0dXJlQWxnb3JpdGhtIEFsZ29yaXRobUlkZW50aWZpZXJ7eyBTaWduYXR1cmVBbGdvcml0aG1zIH19LAogKiAgIHNpZ25hdHVyZSAgICAgICAgICBCSVQgU1RSSU5HCiAqIH0KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBzaG9ydGN1dCBmb3IgYXNuLjEgQVBJCnZhciBhc24xID0gZm9yZ2UuYXNuMTsKCi8qIFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUgKFBLSSkgaW1wbGVtZW50YXRpb24uICovCnZhciBwa2kgPSBmb3JnZS5wa2kgPSBmb3JnZS5wa2kgfHwge307CnZhciBvaWRzID0gcGtpLm9pZHM7CgovLyBzaG9ydCBuYW1lIE9JRCBtYXBwaW5ncwp2YXIgX3Nob3J0TmFtZXMgPSB7fTsKX3Nob3J0TmFtZXNbJ0NOJ10gPSBvaWRzWydjb21tb25OYW1lJ107Cl9zaG9ydE5hbWVzWydjb21tb25OYW1lJ10gPSAnQ04nOwpfc2hvcnROYW1lc1snQyddID0gb2lkc1snY291bnRyeU5hbWUnXTsKX3Nob3J0TmFtZXNbJ2NvdW50cnlOYW1lJ10gPSAnQyc7Cl9zaG9ydE5hbWVzWydMJ10gPSBvaWRzWydsb2NhbGl0eU5hbWUnXTsKX3Nob3J0TmFtZXNbJ2xvY2FsaXR5TmFtZSddID0gJ0wnOwpfc2hvcnROYW1lc1snU1QnXSA9IG9pZHNbJ3N0YXRlT3JQcm92aW5jZU5hbWUnXTsKX3Nob3J0TmFtZXNbJ3N0YXRlT3JQcm92aW5jZU5hbWUnXSA9ICdTVCc7Cl9zaG9ydE5hbWVzWydPJ10gPSBvaWRzWydvcmdhbml6YXRpb25OYW1lJ107Cl9zaG9ydE5hbWVzWydvcmdhbml6YXRpb25OYW1lJ10gPSAnTyc7Cl9zaG9ydE5hbWVzWydPVSddID0gb2lkc1snb3JnYW5pemF0aW9uYWxVbml0TmFtZSddOwpfc2hvcnROYW1lc1snb3JnYW5pemF0aW9uYWxVbml0TmFtZSddID0gJ09VJzsKX3Nob3J0TmFtZXNbJ0UnXSA9IG9pZHNbJ2VtYWlsQWRkcmVzcyddOwpfc2hvcnROYW1lc1snZW1haWxBZGRyZXNzJ10gPSAnRSc7CgovLyB2YWxpZGF0b3IgZm9yIGFuIFN1YmplY3RQdWJsaWNLZXlJbmZvIHN0cnVjdHVyZQovLyBOb3RlOiBDdXJyZW50bHkgb25seSB3b3JrcyB3aXRoIGFuIFJTQSBwdWJsaWMga2V5CnZhciBwdWJsaWNLZXlWYWxpZGF0b3IgPSBmb3JnZS5wa2kucnNhLnB1YmxpY0tleVZhbGlkYXRvcjsKCi8vIHZhbGlkYXRvciBmb3IgYW4gWC41MDl2MyBjZXJ0aWZpY2F0ZQp2YXIgeDUwOUNlcnRpZmljYXRlVmFsaWRhdG9yID0gewogIG5hbWU6ICdDZXJ0aWZpY2F0ZScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAndGJzQ2VydGlmaWNhdGUnLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS52ZXJzaW9uJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgICAgdHlwZTogMCwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUudmVyc2lvbi5pbnRlZ2VyJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICAgIGNhcHR1cmU6ICdjZXJ0VmVyc2lvbicKICAgICAgfV0KICAgIH0sIHsKICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnNlcmlhbE51bWJlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2NlcnRTZXJpYWxOdW1iZXInCiAgICB9LCB7CiAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS5zaWduYXR1cmUnLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIHZhbHVlOiBbewogICAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS5zaWduYXR1cmUuYWxnb3JpdGhtJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgICAgY2FwdHVyZTogJ2NlcnRpbmZvU2lnbmF0dXJlT2lkJwogICAgICB9LCB7CiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnNpZ25hdHVyZS5wYXJhbWV0ZXJzJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgICAgY2FwdHVyZUFzbjE6ICdjZXJ0aW5mb1NpZ25hdHVyZVBhcmFtcycKICAgICAgfV0KICAgIH0sIHsKICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLmlzc3VlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgY2FwdHVyZUFzbjE6ICdjZXJ0SXNzdWVyJwogICAgfSwgewogICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUudmFsaWRpdHknLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIC8vIE5vdGU6IFVUQyBhbmQgZ2VuZXJhbGl6ZWQgdGltZXMgbWF5IGJvdGggYXBwZWFyIHNvIHRoZSBjYXB0dXJlCiAgICAgIC8vIG5hbWVzIGFyZSBiYXNlZCBvbiB0aGVpciBkZXRlY3RlZCBvcmRlciwgdGhlIG5hbWVzIHVzZWQgYmVsb3cKICAgICAgLy8gYXJlIG9ubHkgZm9yIHRoZSBjb21tb24gY2FzZSwgd2hpY2ggdmFsaWRpdHkgdGltZSByZWFsbHkgbWVhbnMKICAgICAgLy8gIm5vdEJlZm9yZSIgYW5kIHdoaWNoIG1lYW5zICJub3RBZnRlciIgd2lsbCBiZSBkZXRlcm1pbmVkIGJ5IG9yZGVyCiAgICAgIHZhbHVlOiBbewogICAgICAgIC8vIG5vdEJlZm9yZSAoVGltZSkgKFVUQyB0aW1lIGNhc2UpCiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnZhbGlkaXR5Lm5vdEJlZm9yZSAodXRjKScsCiAgICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICAgIHR5cGU6IGFzbjEuVHlwZS5VVENUSU1FLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBvcHRpb25hbDogdHJ1ZSwKICAgICAgICBjYXB0dXJlOiAnY2VydFZhbGlkaXR5MVVUQ1RpbWUnCiAgICAgIH0sIHsKICAgICAgICAvLyBub3RCZWZvcmUgKFRpbWUpIChnZW5lcmFsaXplZCB0aW1lIGNhc2UpCiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnZhbGlkaXR5Lm5vdEJlZm9yZSAoZ2VuZXJhbGl6ZWQpJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLkdFTkVSQUxJWkVEVElNRSwKICAgICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgICAgY2FwdHVyZTogJ2NlcnRWYWxpZGl0eTJHZW5lcmFsaXplZFRpbWUnCiAgICAgIH0sIHsKICAgICAgICAvLyBub3RBZnRlciAoVGltZSkgKG9ubHkgVVRDIHRpbWUgaXMgc3VwcG9ydGVkKQogICAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS52YWxpZGl0eS5ub3RBZnRlciAodXRjKScsCiAgICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICAgIHR5cGU6IGFzbjEuVHlwZS5VVENUSU1FLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBvcHRpb25hbDogdHJ1ZSwKICAgICAgICBjYXB0dXJlOiAnY2VydFZhbGlkaXR5M1VUQ1RpbWUnCiAgICAgIH0sIHsKICAgICAgICAvLyBub3RBZnRlciAoVGltZSkgKG9ubHkgVVRDIHRpbWUgaXMgc3VwcG9ydGVkKQogICAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS52YWxpZGl0eS5ub3RBZnRlciAoZ2VuZXJhbGl6ZWQpJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLkdFTkVSQUxJWkVEVElNRSwKICAgICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgICAgY2FwdHVyZTogJ2NlcnRWYWxpZGl0eTRHZW5lcmFsaXplZFRpbWUnCiAgICAgIH1dCiAgICB9LCB7CiAgICAgIC8vIE5hbWUgKHN1YmplY3QpIChSRE5TZXF1ZW5jZSkKICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnN1YmplY3QnLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIGNhcHR1cmVBc24xOiAnY2VydFN1YmplY3QnCiAgICB9LAogICAgICAvLyBTdWJqZWN0UHVibGljS2V5SW5mbwogICAgICBwdWJsaWNLZXlWYWxpZGF0b3IsCiAgICB7CiAgICAgIC8vIGlzc3VlclVuaXF1ZUlEIChvcHRpb25hbCkKICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLmlzc3VlclVuaXF1ZUlEJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgICAgdHlwZTogMSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuaXNzdWVyVW5pcXVlSUQuaWQnLAogICAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgICB0eXBlOiBhc24xLlR5cGUuQklUU1RSSU5HLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBjYXB0dXJlOiAnY2VydElzc3VlclVuaXF1ZUlkJwogICAgICB9XQogICAgfSwgewogICAgICAvLyBzdWJqZWN0VW5pcXVlSUQgKG9wdGlvbmFsKQogICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuc3ViamVjdFVuaXF1ZUlEJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgICAgdHlwZTogMiwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuc3ViamVjdFVuaXF1ZUlELmlkJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLkJJVFNUUklORywKICAgICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgICAgY2FwdHVyZTogJ2NlcnRTdWJqZWN0VW5pcXVlSWQnCiAgICAgIH1dCiAgICB9LCB7CiAgICAgIC8vIEV4dGVuc2lvbnMgKG9wdGlvbmFsKQogICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuZXh0ZW5zaW9ucycsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICAgIHR5cGU6IDMsCiAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ2NlcnRFeHRlbnNpb25zJywKICAgICAgb3B0aW9uYWw6IHRydWUKICAgIH1dCiAgfSwgewogICAgLy8gQWxnb3JpdGhtSWRlbnRpZmllciAoc2lnbmF0dXJlIGFsZ29yaXRobSkKICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5zaWduYXR1cmVBbGdvcml0aG0nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICB2YWx1ZTogW3sKICAgICAgLy8gYWxnb3JpdGhtCiAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5zaWduYXR1cmVBbGdvcml0aG0uYWxnb3JpdGhtJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdjZXJ0U2lnbmF0dXJlT2lkJwogICAgfSwgewogICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuc2lnbmF0dXJlLnBhcmFtZXRlcnMnLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ2NlcnRTaWduYXR1cmVQYXJhbXMnCiAgICB9XQogIH0sIHsKICAgIC8vIFNpZ25hdHVyZVZhbHVlCiAgICBuYW1lOiAnQ2VydGlmaWNhdGUuc2lnbmF0dXJlVmFsdWUnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLkJJVFNUUklORywKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdjZXJ0U2lnbmF0dXJlJwogIH1dCn07Cgp2YXIgcnNhc3NhUHNzUGFyYW1ldGVyVmFsaWRhdG9yID0gewogIG5hbWU6ICdyc2Fwc3MnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAncnNhcHNzLmhhc2hBbGdvcml0aG0nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgIHR5cGU6IDAsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAncnNhcHNzLmhhc2hBbGdvcml0aG0uQWxnb3JpdGhtSWRlbnRpZmllcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5DbGFzcy5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAncnNhcHNzLmhhc2hBbGdvcml0aG0uQWxnb3JpdGhtSWRlbnRpZmllci5hbGdvcml0aG0nLAogICAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBjYXB0dXJlOiAnaGFzaE9pZCcKICAgICAgICAvKiBwYXJhbWV0ZXIgYmxvY2sgb21pdHRlZCwgZm9yIFNIQTEgTlVMTCBhbnlob3cuICovCiAgICAgIH1dCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdyc2Fwc3MubWFza0dlbkFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLAogICAgdHlwZTogMSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdyc2Fwc3MubWFza0dlbkFsZ29yaXRobS5BbGdvcml0aG1JZGVudGlmaWVyJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLkNsYXNzLlNFUVVFTkNFLAogICAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgIHZhbHVlOiBbewogICAgICAgIG5hbWU6ICdyc2Fwc3MubWFza0dlbkFsZ29yaXRobS5BbGdvcml0aG1JZGVudGlmaWVyLmFsZ29yaXRobScsCiAgICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICAgIGNhcHR1cmU6ICdtYXNrR2VuT2lkJwogICAgICB9LCB7CiAgICAgICAgbmFtZTogJ3JzYXBzcy5tYXNrR2VuQWxnb3JpdGhtLkFsZ29yaXRobUlkZW50aWZpZXIucGFyYW1zJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICAgIHZhbHVlOiBbewogICAgICAgICAgbmFtZTogJ3JzYXBzcy5tYXNrR2VuQWxnb3JpdGhtLkFsZ29yaXRobUlkZW50aWZpZXIucGFyYW1zLmFsZ29yaXRobScsCiAgICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICAgICAgY2FwdHVyZTogJ21hc2tHZW5IYXNoT2lkJwogICAgICAgICAgLyogcGFyYW1ldGVyIGJsb2NrIG9taXR0ZWQsIGZvciBTSEExIE5VTEwgYW55aG93LiAqLwogICAgICAgIH1dCiAgICAgIH1dCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdyc2Fwc3Muc2FsdExlbmd0aCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLAogICAgdHlwZTogMiwKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdyc2Fwc3Muc2FsdExlbmd0aC5zYWx0TGVuZ3RoJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLkNsYXNzLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ3NhbHRMZW5ndGgnCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdyc2Fwc3MudHJhaWxlckZpZWxkJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICB0eXBlOiAzLAogICAgb3B0aW9uYWw6IHRydWUsCiAgICB2YWx1ZTogW3sKICAgICAgbmFtZTogJ3JzYXBzcy50cmFpbGVyLnRyYWlsZXInLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuQ2xhc3MuSU5URUdFUiwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlOiAndHJhaWxlcicKICAgIH1dCiAgfV0KfTsKCi8vIHZhbGlkYXRvciBmb3IgYSBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8gc3RydWN0dXJlCnZhciBjZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm9WYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0SW5mbycsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICBjYXB0dXJlQXNuMTogJ2NlcnRpZmljYXRpb25SZXF1ZXN0SW5mbycsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLmludGVnZXInLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAnY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvVmVyc2lvbicKICB9LCB7CiAgICAvLyBOYW1lIChzdWJqZWN0KSAoUkROU2VxdWVuY2UpCiAgICBuYW1lOiAnQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLnN1YmplY3QnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICBjYXB0dXJlQXNuMTogJ2NlcnRpZmljYXRpb25SZXF1ZXN0SW5mb1N1YmplY3QnCiAgfSwKICAvLyBTdWJqZWN0UHVibGljS2V5SW5mbwogIHB1YmxpY0tleVZhbGlkYXRvciwKICB7CiAgICBuYW1lOiAnQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLmF0dHJpYnV0ZXMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgIHR5cGU6IDAsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgY2FwdHVyZTogJ2NlcnRpZmljYXRpb25SZXF1ZXN0SW5mb0F0dHJpYnV0ZXMnLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8uYXR0cmlidXRlcycsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgdmFsdWU6IFt7CiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0SW5mby5hdHRyaWJ1dGVzLnR5cGUnLAogICAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZQogICAgICB9LCB7CiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0SW5mby5hdHRyaWJ1dGVzLnZhbHVlJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLlNFVCwKICAgICAgICBjb25zdHJ1Y3RlZDogdHJ1ZQogICAgICB9XQogICAgfV0KICB9XQp9OwoKLy8gdmFsaWRhdG9yIGZvciBhIENlcnRpZmljYXRpb25SZXF1ZXN0IHN0cnVjdHVyZQp2YXIgY2VydGlmaWNhdGlvblJlcXVlc3RWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0JywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIGNhcHR1cmVBc24xOiAnY3NyJywKICB2YWx1ZTogWwogICAgY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvVmFsaWRhdG9yLCB7CiAgICAvLyBBbGdvcml0aG1JZGVudGlmaWVyIChzaWduYXR1cmUgYWxnb3JpdGhtKQogICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0LnNpZ25hdHVyZUFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICAvLyBhbGdvcml0aG0KICAgICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0LnNpZ25hdHVyZUFsZ29yaXRobS5hbGdvcml0aG0nLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2NzclNpZ25hdHVyZU9pZCcKICAgIH0sIHsKICAgICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0LnNpZ25hdHVyZUFsZ29yaXRobS5wYXJhbWV0ZXJzJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICBvcHRpb25hbDogdHJ1ZSwKICAgICAgY2FwdHVyZUFzbjE6ICdjc3JTaWduYXR1cmVQYXJhbXMnCiAgICB9XQogIH0sIHsKICAgIC8vIHNpZ25hdHVyZQogICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0LnNpZ25hdHVyZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuQklUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2NzclNpZ25hdHVyZScKICB9XQp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFJETlNlcXVlbmNlIG9mIEFTTi4xIERFUi1lbmNvZGVkIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUKICogc2V0cyBpbnRvIGFuIGFycmF5IHdpdGggb2JqZWN0cyB0aGF0IGhhdmUgdHlwZSBhbmQgdmFsdWUgcHJvcGVydGllcy4KICoKICogQHBhcmFtIHJkbiB0aGUgUkROU2VxdWVuY2UgdG8gY29udmVydC4KICogQHBhcmFtIG1kIGEgbWVzc2FnZSBkaWdlc3QgdG8gYXBwZW5kIHR5cGUgYW5kIHZhbHVlIHRvIGlmIHByb3ZpZGVkLgogKi8KcGtpLlJETkF0dHJpYnV0ZXNBc0FycmF5ID0gZnVuY3Rpb24ocmRuLCBtZCkgewogIHZhciBydmFsID0gW107CgogIC8vIGVhY2ggdmFsdWUgaW4gJ3JkbicgaW4gaXMgYSBTRVQgb2YgUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZQogIHZhciBzZXQsIGF0dHIsIG9iajsKICBmb3IodmFyIHNpID0gMDsgc2kgPCByZG4udmFsdWUubGVuZ3RoOyArK3NpKSB7CiAgICAvLyBnZXQgdGhlIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUgc2V0CiAgICBzZXQgPSByZG4udmFsdWVbc2ldOwoKICAgIC8vIGVhY2ggdmFsdWUgaW4gdGhlIFNFVCBpcyBhbiBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgc2VxdWVuY2UKICAgIC8vIGNvbnRhaW5pbmcgZmlyc3QgYSB0eXBlIChhbiBPSUQpIGFuZCBzZWNvbmQgYSB2YWx1ZSAoZGVmaW5lZCBieQogICAgLy8gdGhlIE9JRCkKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBzZXQudmFsdWUubGVuZ3RoOyArK2kpIHsKICAgICAgb2JqID0ge307CiAgICAgIGF0dHIgPSBzZXQudmFsdWVbaV07CiAgICAgIG9iai50eXBlID0gYXNuMS5kZXJUb09pZChhdHRyLnZhbHVlWzBdLnZhbHVlKTsKICAgICAgb2JqLnZhbHVlID0gYXR0ci52YWx1ZVsxXS52YWx1ZTsKICAgICAgb2JqLnZhbHVlVGFnQ2xhc3MgPSBhdHRyLnZhbHVlWzFdLnR5cGU7CiAgICAgIC8vIGlmIHRoZSBPSUQgaXMga25vd24sIGdldCBpdHMgbmFtZSBhbmQgc2hvcnQgbmFtZQogICAgICBpZihvYmoudHlwZSBpbiBvaWRzKSB7CiAgICAgICAgb2JqLm5hbWUgPSBvaWRzW29iai50eXBlXTsKICAgICAgICBpZihvYmoubmFtZSBpbiBfc2hvcnROYW1lcykgewogICAgICAgICAgb2JqLnNob3J0TmFtZSA9IF9zaG9ydE5hbWVzW29iai5uYW1lXTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYobWQpIHsKICAgICAgICBtZC51cGRhdGUob2JqLnR5cGUpOwogICAgICAgIG1kLnVwZGF0ZShvYmoudmFsdWUpOwogICAgICB9CiAgICAgIHJ2YWwucHVzaChvYmopOwogICAgfQogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ29udmVydHMgQVNOLjEgQ1JJQXR0cmlidXRlcyBpbnRvIGFuIGFycmF5IHdpdGggb2JqZWN0cyB0aGF0IGhhdmUgdHlwZSBhbmQKICogdmFsdWUgcHJvcGVydGllcy4KICoKICogQHBhcmFtIGF0dHJpYnV0ZXMgdGhlIENSSUF0dHJpYnV0ZXMgdG8gY29udmVydC4KICovCnBraS5DUklBdHRyaWJ1dGVzQXNBcnJheSA9IGZ1bmN0aW9uKGF0dHJpYnV0ZXMpIHsKICB2YXIgcnZhbCA9IFtdOwoKICAvLyBlYWNoIHZhbHVlIGluICdhdHRyaWJ1dGVzJyBpbiBpcyBhIFNFUVVFTkNFIHdpdGggYW4gT0lEIGFuZCBhIFNFVAogIGZvcih2YXIgc2kgPSAwOyBzaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyArK3NpKSB7CiAgICAvLyBnZXQgdGhlIGF0dHJpYnV0ZSBzZXF1ZW5jZQogICAgdmFyIHNlcSA9IGF0dHJpYnV0ZXNbc2ldOwoKICAgIC8vIGVhY2ggdmFsdWUgaW4gdGhlIFNFUVVFTkNFIGNvbnRhaW5pbmcgZmlyc3QgYSB0eXBlIChhbiBPSUQpIGFuZAogICAgLy8gc2Vjb25kIGEgc2V0IG9mIHZhbHVlcyAoZGVmaW5lZCBieSB0aGUgT0lEKQogICAgdmFyIHR5cGUgPSBhc24xLmRlclRvT2lkKHNlcS52YWx1ZVswXS52YWx1ZSk7CiAgICB2YXIgdmFsdWVzID0gc2VxLnZhbHVlWzFdLnZhbHVlOwogICAgZm9yKHZhciB2aSA9IDA7IHZpIDwgdmFsdWVzLmxlbmd0aDsgKyt2aSkgewogICAgICB2YXIgb2JqID0ge307CiAgICAgIG9iai50eXBlID0gdHlwZTsKICAgICAgb2JqLnZhbHVlID0gdmFsdWVzW3ZpXS52YWx1ZTsKICAgICAgb2JqLnZhbHVlVGFnQ2xhc3MgPSB2YWx1ZXNbdmldLnR5cGU7CiAgICAgIC8vIGlmIHRoZSBPSUQgaXMga25vd24sIGdldCBpdHMgbmFtZSBhbmQgc2hvcnQgbmFtZQogICAgICBpZihvYmoudHlwZSBpbiBvaWRzKSB7CiAgICAgICAgb2JqLm5hbWUgPSBvaWRzW29iai50eXBlXTsKICAgICAgICBpZihvYmoubmFtZSBpbiBfc2hvcnROYW1lcykgewogICAgICAgICAgb2JqLnNob3J0TmFtZSA9IF9zaG9ydE5hbWVzW29iai5uYW1lXTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLy8gcGFyc2UgZXh0ZW5zaW9ucwogICAgICBpZihvYmoudHlwZSA9PT0gb2lkcy5leHRlbnNpb25SZXF1ZXN0KSB7CiAgICAgICAgb2JqLmV4dGVuc2lvbnMgPSBbXTsKICAgICAgICBmb3IodmFyIGVpID0gMDsgZWkgPCBvYmoudmFsdWUubGVuZ3RoOyArK2VpKSB7CiAgICAgICAgICBvYmouZXh0ZW5zaW9ucy5wdXNoKHBraS5jZXJ0aWZpY2F0ZUV4dGVuc2lvbkZyb21Bc24xKG9iai52YWx1ZVtlaV0pKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcnZhbC5wdXNoKG9iaik7CiAgICB9CiAgfQoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGFuIGlzc3VlciBvciBzdWJqZWN0IGF0dHJpYnV0ZSBmcm9tIGl0cyBuYW1lLCB0eXBlLCBvciBzaG9ydCBuYW1lLgogKgogKiBAcGFyYW0gb2JqIHRoZSBpc3N1ZXIgb3Igc3ViamVjdCBvYmplY3QuCiAqIEBwYXJhbSBvcHRpb25zIGEgc2hvcnQgbmFtZSBzdHJpbmcgb3IgYW4gb2JqZWN0IHdpdGg6CiAqICAgICAgICAgIHNob3J0TmFtZSB0aGUgc2hvcnQgbmFtZSBmb3IgdGhlIGF0dHJpYnV0ZS4KICogICAgICAgICAgbmFtZSB0aGUgbmFtZSBmb3IgdGhlIGF0dHJpYnV0ZS4KICogICAgICAgICAgdHlwZSB0aGUgdHlwZSBmb3IgdGhlIGF0dHJpYnV0ZS4KICoKICogQHJldHVybiB0aGUgYXR0cmlidXRlLgogKi8KZnVuY3Rpb24gX2dldEF0dHJpYnV0ZShvYmosIG9wdGlvbnMpIHsKICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHsKICAgIG9wdGlvbnMgPSB7c2hvcnROYW1lOiBvcHRpb25zfTsKICB9CgogIHZhciBydmFsID0gbnVsbDsKICB2YXIgYXR0cjsKICBmb3IodmFyIGkgPSAwOyBydmFsID09PSBudWxsICYmIGkgPCBvYmouYXR0cmlidXRlcy5sZW5ndGg7ICsraSkgewogICAgYXR0ciA9IG9iai5hdHRyaWJ1dGVzW2ldOwogICAgaWYob3B0aW9ucy50eXBlICYmIG9wdGlvbnMudHlwZSA9PT0gYXR0ci50eXBlKSB7CiAgICAgIHJ2YWwgPSBhdHRyOwogICAgfSBlbHNlIGlmKG9wdGlvbnMubmFtZSAmJiBvcHRpb25zLm5hbWUgPT09IGF0dHIubmFtZSkgewogICAgICBydmFsID0gYXR0cjsKICAgIH0gZWxzZSBpZihvcHRpb25zLnNob3J0TmFtZSAmJiBvcHRpb25zLnNob3J0TmFtZSA9PT0gYXR0ci5zaG9ydE5hbWUpIHsKICAgICAgcnZhbCA9IGF0dHI7CiAgICB9CiAgfQogIHJldHVybiBydmFsOwp9CgovKioKICogQ29udmVydHMgc2lnbmF0dXJlIHBhcmFtZXRlcnMgZnJvbSBBU04uMSBzdHJ1Y3R1cmUuCiAqCiAqIEN1cnJlbnRseSBvbmx5IFJTQVNTQS1QU1Mgc3VwcG9ydGVkLiAgVGhlIFBLQ1MjMSB2MS41IHNpZ25hdHVyZSBzY2hlbWUgaGFkCiAqIG5vIHBhcmFtZXRlcnMuCiAqCiAqIFJTQVNTQS1QU1MtcGFyYW1zICA6Oj0gIFNFUVVFTkNFICB7CiAqICAgaGFzaEFsZ29yaXRobSAgICAgIFswXSBIYXNoQWxnb3JpdGhtIERFRkFVTFQKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYTFJZGVudGlmaWVyLAogKiAgIG1hc2tHZW5BbGdvcml0aG0gICBbMV0gTWFza0dlbkFsZ29yaXRobSBERUZBVUxUCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZ2YxU0hBMUlkZW50aWZpZXIsCiAqICAgc2FsdExlbmd0aCAgICAgICAgIFsyXSBJTlRFR0VSIERFRkFVTFQgMjAsCiAqICAgdHJhaWxlckZpZWxkICAgICAgIFszXSBJTlRFR0VSIERFRkFVTFQgMQogKiB9CiAqCiAqIEhhc2hBbGdvcml0aG0gIDo6PSAgQWxnb3JpdGhtSWRlbnRpZmllcgogKgogKiBNYXNrR2VuQWxnb3JpdGhtICA6Oj0gIEFsZ29yaXRobUlkZW50aWZpZXIKICoKICogQWxnb3JpdGhtSWRlbnRpZmVyIDo6PSBTRVFVRU5DRSB7CiAqICAgYWxnb3JpdGhtIE9CSkVDVCBJREVOVElGSUVSLAogKiAgIHBhcmFtZXRlcnMgQU5ZIERFRklORUQgQlkgYWxnb3JpdGhtIE9QVElPTkFMCiAqIH0KICoKICogQHBhcmFtIG9pZCBUaGUgT0lEIHNwZWNpZnlpbmcgdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0KICogQHBhcmFtIG9iaiBUaGUgQVNOLjEgc3RydWN0dXJlIGhvbGRpbmcgdGhlIHBhcmFtZXRlcnMKICogQHBhcmFtIGZpbGxEZWZhdWx0cyBXaGV0aGVyIHRvIHVzZSByZXR1cm4gZGVmYXVsdCB2YWx1ZXMgd2hlcmUgb21pdHRlZAogKiBAcmV0dXJuIHNpZ25hdHVyZSBwYXJhbWV0ZXIgb2JqZWN0CiAqLwp2YXIgX3JlYWRTaWduYXR1cmVQYXJhbWV0ZXJzID0gZnVuY3Rpb24ob2lkLCBvYmosIGZpbGxEZWZhdWx0cykgewogIHZhciBwYXJhbXMgPSB7fTsKCiAgaWYob2lkICE9PSBvaWRzWydSU0FTU0EtUFNTJ10pIHsKICAgIHJldHVybiBwYXJhbXM7CiAgfQoKICBpZihmaWxsRGVmYXVsdHMpIHsKICAgIHBhcmFtcyA9IHsKICAgICAgaGFzaDogewogICAgICAgIGFsZ29yaXRobU9pZDogb2lkc1snc2hhMSddCiAgICAgIH0sCiAgICAgIG1nZjogewogICAgICAgIGFsZ29yaXRobU9pZDogb2lkc1snbWdmMSddLAogICAgICAgIGhhc2g6IHsKICAgICAgICAgIGFsZ29yaXRobU9pZDogb2lkc1snc2hhMSddCiAgICAgICAgfQogICAgICB9LAogICAgICBzYWx0TGVuZ3RoOiAyMAogICAgfTsKICB9CgogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgcnNhc3NhUHNzUGFyYW1ldGVyVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFJTQVNTQS1QU1MgcGFyYW1ldGVyIGJsb2NrLicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3JzOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICBpZihjYXB0dXJlLmhhc2hPaWQgIT09IHVuZGVmaW5lZCkgewogICAgcGFyYW1zLmhhc2ggPSBwYXJhbXMuaGFzaCB8fCB7fTsKICAgIHBhcmFtcy5oYXNoLmFsZ29yaXRobU9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5oYXNoT2lkKTsKICB9CgogIGlmKGNhcHR1cmUubWFza0dlbk9pZCAhPT0gdW5kZWZpbmVkKSB7CiAgICBwYXJhbXMubWdmID0gcGFyYW1zLm1nZiB8fCB7fTsKICAgIHBhcmFtcy5tZ2YuYWxnb3JpdGhtT2lkID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLm1hc2tHZW5PaWQpOwogICAgcGFyYW1zLm1nZi5oYXNoID0gcGFyYW1zLm1nZi5oYXNoIHx8IHt9OwogICAgcGFyYW1zLm1nZi5oYXNoLmFsZ29yaXRobU9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5tYXNrR2VuSGFzaE9pZCk7CiAgfQoKICBpZihjYXB0dXJlLnNhbHRMZW5ndGggIT09IHVuZGVmaW5lZCkgewogICAgcGFyYW1zLnNhbHRMZW5ndGggPSBjYXB0dXJlLnNhbHRMZW5ndGguY2hhckNvZGVBdCgwKTsKICB9CgogIHJldHVybiBwYXJhbXM7Cn07CgovKioKICogQ29udmVydHMgYW4gWC41MDkgY2VydGlmaWNhdGUgZnJvbSBQRU0gZm9ybWF0LgogKgogKiBOb3RlOiBJZiB0aGUgY2VydGlmaWNhdGUgaXMgdG8gYmUgdmVyaWZpZWQgdGhlbiBjb21wdXRlIGhhc2ggc2hvdWxkCiAqIGJlIHNldCB0byB0cnVlLiBUaGlzIHdpbGwgc2NhbiB0aGUgVEJTQ2VydGlmaWNhdGUgcGFydCBvZiB0aGUgQVNOLjEKICogb2JqZWN0IHdoaWxlIGl0IGlzIGNvbnZlcnRlZCBzbyBpdCBkb2Vzbid0IG5lZWQgdG8gYmUgY29udmVydGVkIGJhY2sKICogdG8gQVNOLjEtREVSLWVuY29kaW5nIGxhdGVyLgogKgogKiBAcGFyYW0gcGVtIHRoZSBQRU0tZm9ybWF0dGVkIGNlcnRpZmljYXRlLgogKiBAcGFyYW0gY29tcHV0ZUhhc2ggdHJ1ZSB0byBjb21wdXRlIHRoZSBoYXNoIGZvciB2ZXJpZmljYXRpb24uCiAqIEBwYXJhbSBzdHJpY3QgdHJ1ZSB0byBiZSBzdHJpY3Qgd2hlbiBjaGVja2luZyBBU04uMSB2YWx1ZSBsZW5ndGhzLCBmYWxzZSB0bwogKiAgICAgICAgICBhbGxvdyB0cnVuY2F0ZWQgdmFsdWVzIChkZWZhdWx0OiB0cnVlKS4KICoKICogQHJldHVybiB0aGUgY2VydGlmaWNhdGUuCiAqLwpwa2kuY2VydGlmaWNhdGVGcm9tUGVtID0gZnVuY3Rpb24ocGVtLCBjb21wdXRlSGFzaCwgc3RyaWN0KSB7CiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKCiAgaWYobXNnLnR5cGUgIT09ICdDRVJUSUZJQ0FURScgJiYKICAgIG1zZy50eXBlICE9PSAnWDUwOSBDRVJUSUZJQ0FURScgJiYKICAgIG1zZy50eXBlICE9PSAnVFJVU1RFRCBDRVJUSUZJQ0FURScpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ291bGQgbm90IGNvbnZlcnQgY2VydGlmaWNhdGUgZnJvbSBQRU07IFBFTSBoZWFkZXIgdHlwZSAnICsKICAgICAgJ2lzIG5vdCAiQ0VSVElGSUNBVEUiLCAiWDUwOSBDRVJUSUZJQ0FURSIsIG9yICJUUlVTVEVEIENFUlRJRklDQVRFIi4nKTsKICAgIGVycm9yLmhlYWRlclR5cGUgPSBtc2cudHlwZTsKICAgIHRocm93IGVycm9yOwogIH0KICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IGNlcnRpZmljYXRlIGZyb20gUEVNOyBQRU0gaXMgZW5jcnlwdGVkLicpOwogIH0KCiAgLy8gY29udmVydCBERVIgdG8gQVNOLjEgb2JqZWN0CiAgdmFyIG9iaiA9IGFzbjEuZnJvbURlcihtc2cuYm9keSwgc3RyaWN0KTsKCiAgcmV0dXJuIHBraS5jZXJ0aWZpY2F0ZUZyb21Bc24xKG9iaiwgY29tcHV0ZUhhc2gpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFguNTA5IGNlcnRpZmljYXRlIHRvIFBFTSBmb3JtYXQuCiAqCiAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZS4KICogQHBhcmFtIG1heGxpbmUgdGhlIG1heGltdW0gY2hhcmFjdGVycyBwZXIgbGluZSwgZGVmYXVsdHMgdG8gNjQuCiAqCiAqIEByZXR1cm4gdGhlIFBFTS1mb3JtYXR0ZWQgY2VydGlmaWNhdGUuCiAqLwpwa2kuY2VydGlmaWNhdGVUb1BlbSA9IGZ1bmN0aW9uKGNlcnQsIG1heGxpbmUpIHsKICAvLyBjb252ZXJ0IHRvIEFTTi4xLCB0aGVuIERFUiwgdGhlbiBQRU0tZW5jb2RlCiAgdmFyIG1zZyA9IHsKICAgIHR5cGU6ICdDRVJUSUZJQ0FURScsCiAgICBib2R5OiBhc24xLnRvRGVyKHBraS5jZXJ0aWZpY2F0ZVRvQXNuMShjZXJ0KSkuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnLCB7bWF4bGluZTogbWF4bGluZX0pOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFJTQSBwdWJsaWMga2V5IGZyb20gUEVNIGZvcm1hdC4KICoKICogQHBhcmFtIHBlbSB0aGUgUEVNLWZvcm1hdHRlZCBwdWJsaWMga2V5LgogKgogKiBAcmV0dXJuIHRoZSBwdWJsaWMga2V5LgogKi8KcGtpLnB1YmxpY0tleUZyb21QZW0gPSBmdW5jdGlvbihwZW0pIHsKICB2YXIgbXNnID0gZm9yZ2UucGVtLmRlY29kZShwZW0pWzBdOwoKICBpZihtc2cudHlwZSAhPT0gJ1BVQkxJQyBLRVknICYmIG1zZy50eXBlICE9PSAnUlNBIFBVQkxJQyBLRVknKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IHB1YmxpYyBrZXkgZnJvbSBQRU07IFBFTSBoZWFkZXIgJyArCiAgICAgICd0eXBlIGlzIG5vdCAiUFVCTElDIEtFWSIgb3IgIlJTQSBQVUJMSUMgS0VZIi4nKTsKICAgIGVycm9yLmhlYWRlclR5cGUgPSBtc2cudHlwZTsKICAgIHRocm93IGVycm9yOwogIH0KICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IHB1YmxpYyBrZXkgZnJvbSBQRU07IFBFTSBpcyBlbmNyeXB0ZWQuJyk7CiAgfQoKICAvLyBjb252ZXJ0IERFUiB0byBBU04uMSBvYmplY3QKICB2YXIgb2JqID0gYXNuMS5mcm9tRGVyKG1zZy5ib2R5KTsKCiAgcmV0dXJuIHBraS5wdWJsaWNLZXlGcm9tQXNuMShvYmopOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFJTQSBwdWJsaWMga2V5IHRvIFBFTSBmb3JtYXQgKHVzaW5nIGEgU3ViamVjdFB1YmxpY0tleUluZm8pLgogKgogKiBAcGFyYW0ga2V5IHRoZSBwdWJsaWMga2V5LgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lLCBkZWZhdWx0cyB0byA2NC4KICoKICogQHJldHVybiB0aGUgUEVNLWZvcm1hdHRlZCBwdWJsaWMga2V5LgogKi8KcGtpLnB1YmxpY0tleVRvUGVtID0gZnVuY3Rpb24oa2V5LCBtYXhsaW5lKSB7CiAgLy8gY29udmVydCB0byBBU04uMSwgdGhlbiBERVIsIHRoZW4gUEVNLWVuY29kZQogIHZhciBtc2cgPSB7CiAgICB0eXBlOiAnUFVCTElDIEtFWScsCiAgICBib2R5OiBhc24xLnRvRGVyKHBraS5wdWJsaWNLZXlUb0FzbjEoa2V5KSkuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnLCB7bWF4bGluZTogbWF4bGluZX0pOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFJTQSBwdWJsaWMga2V5IHRvIFBFTSBmb3JtYXQgKHVzaW5nIGFuIFJTQVB1YmxpY0tleSkuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHB1YmxpYyBrZXkuCiAqIEBwYXJhbSBtYXhsaW5lIHRoZSBtYXhpbXVtIGNoYXJhY3RlcnMgcGVyIGxpbmUsIGRlZmF1bHRzIHRvIDY0LgogKgogKiBAcmV0dXJuIHRoZSBQRU0tZm9ybWF0dGVkIHB1YmxpYyBrZXkuCiAqLwpwa2kucHVibGljS2V5VG9SU0FQdWJsaWNLZXlQZW0gPSBmdW5jdGlvbihrZXksIG1heGxpbmUpIHsKICAvLyBjb252ZXJ0IHRvIEFTTi4xLCB0aGVuIERFUiwgdGhlbiBQRU0tZW5jb2RlCiAgdmFyIG1zZyA9IHsKICAgIHR5cGU6ICdSU0EgUFVCTElDIEtFWScsCiAgICBib2R5OiBhc24xLnRvRGVyKHBraS5wdWJsaWNLZXlUb1JTQVB1YmxpY0tleShrZXkpKS5nZXRCeXRlcygpCiAgfTsKICByZXR1cm4gZm9yZ2UucGVtLmVuY29kZShtc2csIHttYXhsaW5lOiBtYXhsaW5lfSk7Cn07CgovKioKICogR2V0cyBhIGZpbmdlcnByaW50IGZvciB0aGUgZ2l2ZW4gcHVibGljIGtleS4KICoKICogQHBhcmFtIG9wdGlvbnMgdGhlIG9wdGlvbnMgdG8gdXNlLgogKiAgICAgICAgICBbbWRdIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlIChkZWZhdWx0cyB0byBmb3JnZS5tZC5zaGExKS4KICogICAgICAgICAgW3R5cGVdIHRoZSB0eXBlIG9mIGZpbmdlcnByaW50LCBzdWNoIGFzICdSU0FQdWJsaWNLZXknLAogKiAgICAgICAgICAgICdTdWJqZWN0UHVibGljS2V5SW5mbycgKGRlZmF1bHRzIHRvICdSU0FQdWJsaWNLZXknKS4KICogICAgICAgICAgW2VuY29kaW5nXSBhbiBhbHRlcm5hdGl2ZSBvdXRwdXQgZW5jb2RpbmcsIHN1Y2ggYXMgJ2hleCcKICogICAgICAgICAgICAoZGVmYXVsdHMgdG8gbm9uZSwgb3V0cHV0cyBhIGJ5dGUgYnVmZmVyKS4KICogICAgICAgICAgW2RlbGltaXRlcl0gdGhlIGRlbGltaXRlciB0byB1c2UgYmV0d2VlbiBieXRlcyBmb3IgJ2hleCcgZW5jb2RlZAogKiAgICAgICAgICAgIG91dHB1dCwgZWc6ICc6JyAoZGVmYXVsdHMgdG8gbm9uZSkuCiAqCiAqIEByZXR1cm4gdGhlIGZpbmdlcnByaW50IGFzIGEgYnl0ZSBidWZmZXIgb3Igb3RoZXIgZW5jb2RpbmcgYmFzZWQgb24gb3B0aW9ucy4KICovCnBraS5nZXRQdWJsaWNLZXlGaW5nZXJwcmludCA9IGZ1bmN0aW9uKGtleSwgb3B0aW9ucykgewogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHZhciBtZCA9IG9wdGlvbnMubWQgfHwgZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICB2YXIgdHlwZSA9IG9wdGlvbnMudHlwZSB8fCAnUlNBUHVibGljS2V5JzsKCiAgdmFyIGJ5dGVzOwogIHN3aXRjaCh0eXBlKSB7CiAgY2FzZSAnUlNBUHVibGljS2V5JzoKICAgIGJ5dGVzID0gYXNuMS50b0Rlcihwa2kucHVibGljS2V5VG9SU0FQdWJsaWNLZXkoa2V5KSkuZ2V0Qnl0ZXMoKTsKICAgIGJyZWFrOwogIGNhc2UgJ1N1YmplY3RQdWJsaWNLZXlJbmZvJzoKICAgIGJ5dGVzID0gYXNuMS50b0Rlcihwa2kucHVibGljS2V5VG9Bc24xKGtleSkpLmdldEJ5dGVzKCk7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGZpbmdlcnByaW50IHR5cGUgIicgKyBvcHRpb25zLnR5cGUgKyAnIi4nKTsKICB9CgogIC8vIGhhc2ggcHVibGljIGtleSBieXRlcwogIG1kLnN0YXJ0KCk7CiAgbWQudXBkYXRlKGJ5dGVzKTsKICB2YXIgZGlnZXN0ID0gbWQuZGlnZXN0KCk7CiAgaWYob3B0aW9ucy5lbmNvZGluZyA9PT0gJ2hleCcpIHsKICAgIHZhciBoZXggPSBkaWdlc3QudG9IZXgoKTsKICAgIGlmKG9wdGlvbnMuZGVsaW1pdGVyKSB7CiAgICAgIHJldHVybiBoZXgubWF0Y2goLy57Mn0vZykuam9pbihvcHRpb25zLmRlbGltaXRlcik7CiAgICB9CiAgICByZXR1cm4gaGV4OwogIH0gZWxzZSBpZihvcHRpb25zLmVuY29kaW5nID09PSAnYmluYXJ5JykgewogICAgcmV0dXJuIGRpZ2VzdC5nZXRCeXRlcygpOwogIH0gZWxzZSBpZihvcHRpb25zLmVuY29kaW5nKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcgIicgKyBvcHRpb25zLmVuY29kaW5nICsgJyIuJyk7CiAgfQogIHJldHVybiBkaWdlc3Q7Cn07CgovKioKICogQ29udmVydHMgYSBQS0NTIzEwIGNlcnRpZmljYXRpb24gcmVxdWVzdCAoQ1NSKSBmcm9tIFBFTSBmb3JtYXQuCiAqCiAqIE5vdGU6IElmIHRoZSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QgaXMgdG8gYmUgdmVyaWZpZWQgdGhlbiBjb21wdXRlIGhhc2gKICogc2hvdWxkIGJlIHNldCB0byB0cnVlLiBUaGlzIHdpbGwgc2NhbiB0aGUgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIHBhcnQgb2YKICogdGhlIEFTTi4xIG9iamVjdCB3aGlsZSBpdCBpcyBjb252ZXJ0ZWQgc28gaXQgZG9lc24ndCBuZWVkIHRvIGJlIGNvbnZlcnRlZAogKiBiYWNrIHRvIEFTTi4xLURFUi1lbmNvZGluZyBsYXRlci4KICoKICogQHBhcmFtIHBlbSB0aGUgUEVNLWZvcm1hdHRlZCBjZXJ0aWZpY2F0ZS4KICogQHBhcmFtIGNvbXB1dGVIYXNoIHRydWUgdG8gY29tcHV0ZSB0aGUgaGFzaCBmb3IgdmVyaWZpY2F0aW9uLgogKiBAcGFyYW0gc3RyaWN0IHRydWUgdG8gYmUgc3RyaWN0IHdoZW4gY2hlY2tpbmcgQVNOLjEgdmFsdWUgbGVuZ3RocywgZmFsc2UgdG8KICogICAgICAgICAgYWxsb3cgdHJ1bmNhdGVkIHZhbHVlcyAoZGVmYXVsdDogdHJ1ZSkuCiAqCiAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRpb24gcmVxdWVzdCAoQ1NSKS4KICovCnBraS5jZXJ0aWZpY2F0aW9uUmVxdWVzdEZyb21QZW0gPSBmdW5jdGlvbihwZW0sIGNvbXB1dGVIYXNoLCBzdHJpY3QpIHsKICB2YXIgbXNnID0gZm9yZ2UucGVtLmRlY29kZShwZW0pWzBdOwoKICBpZihtc2cudHlwZSAhPT0gJ0NFUlRJRklDQVRFIFJFUVVFU1QnKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IGNlcnRpZmljYXRpb24gcmVxdWVzdCBmcm9tIFBFTTsgJyArCiAgICAgICdQRU0gaGVhZGVyIHR5cGUgaXMgbm90ICJDRVJUSUZJQ0FURSBSRVFVRVNUIi4nKTsKICAgIGVycm9yLmhlYWRlclR5cGUgPSBtc2cudHlwZTsKICAgIHRocm93IGVycm9yOwogIH0KICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IGNlcnRpZmljYXRpb24gcmVxdWVzdCBmcm9tIFBFTTsgJyArCiAgICAgICdQRU0gaXMgZW5jcnlwdGVkLicpOwogIH0KCiAgLy8gY29udmVydCBERVIgdG8gQVNOLjEgb2JqZWN0CiAgdmFyIG9iaiA9IGFzbjEuZnJvbURlcihtc2cuYm9keSwgc3RyaWN0KTsKCiAgcmV0dXJuIHBraS5jZXJ0aWZpY2F0aW9uUmVxdWVzdEZyb21Bc24xKG9iaiwgY29tcHV0ZUhhc2gpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgUEtDUyMxMCBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QgKENTUikgdG8gUEVNIGZvcm1hdC4KICoKICogQHBhcmFtIGNzciB0aGUgY2VydGlmaWNhdGlvbiByZXF1ZXN0LgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lLCBkZWZhdWx0cyB0byA2NC4KICoKICogQHJldHVybiB0aGUgUEVNLWZvcm1hdHRlZCBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QuCiAqLwpwa2kuY2VydGlmaWNhdGlvblJlcXVlc3RUb1BlbSA9IGZ1bmN0aW9uKGNzciwgbWF4bGluZSkgewogIC8vIGNvbnZlcnQgdG8gQVNOLjEsIHRoZW4gREVSLCB0aGVuIFBFTS1lbmNvZGUKICB2YXIgbXNnID0gewogICAgdHlwZTogJ0NFUlRJRklDQVRFIFJFUVVFU1QnLAogICAgYm9keTogYXNuMS50b0Rlcihwa2kuY2VydGlmaWNhdGlvblJlcXVlc3RUb0FzbjEoY3NyKSkuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnLCB7bWF4bGluZTogbWF4bGluZX0pOwp9OwoKLyoqCiAqIENyZWF0ZXMgYW4gZW1wdHkgWC41MDl2MyBSU0EgY2VydGlmaWNhdGUuCiAqCiAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRlLgogKi8KcGtpLmNyZWF0ZUNlcnRpZmljYXRlID0gZnVuY3Rpb24oKSB7CiAgdmFyIGNlcnQgPSB7fTsKICBjZXJ0LnZlcnNpb24gPSAweDAyOwogIGNlcnQuc2VyaWFsTnVtYmVyID0gJzAwJzsKICBjZXJ0LnNpZ25hdHVyZU9pZCA9IG51bGw7CiAgY2VydC5zaWduYXR1cmUgPSBudWxsOwogIGNlcnQuc2lnaW5mbyA9IHt9OwogIGNlcnQuc2lnaW5mby5hbGdvcml0aG1PaWQgPSBudWxsOwogIGNlcnQudmFsaWRpdHkgPSB7fTsKICBjZXJ0LnZhbGlkaXR5Lm5vdEJlZm9yZSA9IG5ldyBEYXRlKCk7CiAgY2VydC52YWxpZGl0eS5ub3RBZnRlciA9IG5ldyBEYXRlKCk7CgogIGNlcnQuaXNzdWVyID0ge307CiAgY2VydC5pc3N1ZXIuZ2V0RmllbGQgPSBmdW5jdGlvbihzbikgewogICAgcmV0dXJuIF9nZXRBdHRyaWJ1dGUoY2VydC5pc3N1ZXIsIHNuKTsKICB9OwogIGNlcnQuaXNzdWVyLmFkZEZpZWxkID0gZnVuY3Rpb24oYXR0cikgewogICAgX2ZpbGxNaXNzaW5nRmllbGRzKFthdHRyXSk7CiAgICBjZXJ0Lmlzc3Vlci5hdHRyaWJ1dGVzLnB1c2goYXR0cik7CiAgfTsKICBjZXJ0Lmlzc3Vlci5hdHRyaWJ1dGVzID0gW107CiAgY2VydC5pc3N1ZXIuaGFzaCA9IG51bGw7CgogIGNlcnQuc3ViamVjdCA9IHt9OwogIGNlcnQuc3ViamVjdC5nZXRGaWVsZCA9IGZ1bmN0aW9uKHNuKSB7CiAgICByZXR1cm4gX2dldEF0dHJpYnV0ZShjZXJ0LnN1YmplY3QsIHNuKTsKICB9OwogIGNlcnQuc3ViamVjdC5hZGRGaWVsZCA9IGZ1bmN0aW9uKGF0dHIpIHsKICAgIF9maWxsTWlzc2luZ0ZpZWxkcyhbYXR0cl0pOwogICAgY2VydC5zdWJqZWN0LmF0dHJpYnV0ZXMucHVzaChhdHRyKTsKICB9OwogIGNlcnQuc3ViamVjdC5hdHRyaWJ1dGVzID0gW107CiAgY2VydC5zdWJqZWN0Lmhhc2ggPSBudWxsOwoKICBjZXJ0LmV4dGVuc2lvbnMgPSBbXTsKICBjZXJ0LnB1YmxpY0tleSA9IG51bGw7CiAgY2VydC5tZCA9IG51bGw7CgogIC8qKgogICAqIFNldHMgdGhlIHN1YmplY3Qgb2YgdGhpcyBjZXJ0aWZpY2F0ZS4KICAgKgogICAqIEBwYXJhbSBhdHRycyB0aGUgYXJyYXkgb2Ygc3ViamVjdCBhdHRyaWJ1dGVzIHRvIHVzZS4KICAgKiBAcGFyYW0gdW5pcXVlSWQgYW4gb3B0aW9uYWwgYSB1bmlxdWUgSUQgdG8gdXNlLgogICAqLwogIGNlcnQuc2V0U3ViamVjdCA9IGZ1bmN0aW9uKGF0dHJzLCB1bmlxdWVJZCkgewogICAgLy8gc2V0IG5ldyBhdHRyaWJ1dGVzLCBjbGVhciBoYXNoCiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoYXR0cnMpOwogICAgY2VydC5zdWJqZWN0LmF0dHJpYnV0ZXMgPSBhdHRyczsKICAgIGRlbGV0ZSBjZXJ0LnN1YmplY3QudW5pcXVlSWQ7CiAgICBpZih1bmlxdWVJZCkgewogICAgICBjZXJ0LnN1YmplY3QudW5pcXVlSWQgPSB1bmlxdWVJZDsKICAgIH0KICAgIGNlcnQuc3ViamVjdC5oYXNoID0gbnVsbDsKICB9OwoKICAvKioKICAgKiBTZXRzIHRoZSBpc3N1ZXIgb2YgdGhpcyBjZXJ0aWZpY2F0ZS4KICAgKgogICAqIEBwYXJhbSBhdHRycyB0aGUgYXJyYXkgb2YgaXNzdWVyIGF0dHJpYnV0ZXMgdG8gdXNlLgogICAqIEBwYXJhbSB1bmlxdWVJZCBhbiBvcHRpb25hbCBhIHVuaXF1ZSBJRCB0byB1c2UuCiAgICovCiAgY2VydC5zZXRJc3N1ZXIgPSBmdW5jdGlvbihhdHRycywgdW5pcXVlSWQpIHsKICAgIC8vIHNldCBuZXcgYXR0cmlidXRlcywgY2xlYXIgaGFzaAogICAgX2ZpbGxNaXNzaW5nRmllbGRzKGF0dHJzKTsKICAgIGNlcnQuaXNzdWVyLmF0dHJpYnV0ZXMgPSBhdHRyczsKICAgIGRlbGV0ZSBjZXJ0Lmlzc3Vlci51bmlxdWVJZDsKICAgIGlmKHVuaXF1ZUlkKSB7CiAgICAgIGNlcnQuaXNzdWVyLnVuaXF1ZUlkID0gdW5pcXVlSWQ7CiAgICB9CiAgICBjZXJ0Lmlzc3Vlci5oYXNoID0gbnVsbDsKICB9OwoKICAvKioKICAgKiBTZXRzIHRoZSBleHRlbnNpb25zIG9mIHRoaXMgY2VydGlmaWNhdGUuCiAgICoKICAgKiBAcGFyYW0gZXh0cyB0aGUgYXJyYXkgb2YgZXh0ZW5zaW9ucyB0byB1c2UuCiAgICovCiAgY2VydC5zZXRFeHRlbnNpb25zID0gZnVuY3Rpb24oZXh0cykgewogICAgZm9yKHZhciBpID0gMDsgaSA8IGV4dHMubGVuZ3RoOyArK2kpIHsKICAgICAgX2ZpbGxNaXNzaW5nRXh0ZW5zaW9uRmllbGRzKGV4dHNbaV0sIHtjZXJ0OiBjZXJ0fSk7CiAgICB9CiAgICAvLyBzZXQgbmV3IGV4dGVuc2lvbnMKICAgIGNlcnQuZXh0ZW5zaW9ucyA9IGV4dHM7CiAgfTsKCiAgLyoqCiAgICogR2V0cyBhbiBleHRlbnNpb24gYnkgaXRzIG5hbWUgb3IgaWQuCiAgICoKICAgKiBAcGFyYW0gb3B0aW9ucyB0aGUgbmFtZSB0byB1c2Ugb3IgYW4gb2JqZWN0IHdpdGg6CiAgICogICAgICAgICAgbmFtZSB0aGUgbmFtZSB0byB1c2UuCiAgICogICAgICAgICAgaWQgdGhlIGlkIHRvIHVzZS4KICAgKgogICAqIEByZXR1cm4gdGhlIGV4dGVuc2lvbiBvciBudWxsIGlmIG5vdCBmb3VuZC4KICAgKi8KICBjZXJ0LmdldEV4dGVuc2lvbiA9IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgIGlmKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJykgewogICAgICBvcHRpb25zID0ge25hbWU6IG9wdGlvbnN9OwogICAgfQoKICAgIHZhciBydmFsID0gbnVsbDsKICAgIHZhciBleHQ7CiAgICBmb3IodmFyIGkgPSAwOyBydmFsID09PSBudWxsICYmIGkgPCBjZXJ0LmV4dGVuc2lvbnMubGVuZ3RoOyArK2kpIHsKICAgICAgZXh0ID0gY2VydC5leHRlbnNpb25zW2ldOwogICAgICBpZihvcHRpb25zLmlkICYmIGV4dC5pZCA9PT0gb3B0aW9ucy5pZCkgewogICAgICAgIHJ2YWwgPSBleHQ7CiAgICAgIH0gZWxzZSBpZihvcHRpb25zLm5hbWUgJiYgZXh0Lm5hbWUgPT09IG9wdGlvbnMubmFtZSkgewogICAgICAgIHJ2YWwgPSBleHQ7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBydmFsOwogIH07CgogIC8qKgogICAqIFNpZ25zIHRoaXMgY2VydGlmaWNhdGUgdXNpbmcgdGhlIGdpdmVuIHByaXZhdGUga2V5LgogICAqCiAgICogQHBhcmFtIGtleSB0aGUgcHJpdmF0ZSBrZXkgdG8gc2lnbiB3aXRoLgogICAqIEBwYXJhbSBtZCB0aGUgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0IHRvIHVzZSAoZGVmYXVsdHMgdG8gZm9yZ2UubWQuc2hhMSkuCiAgICovCiAgY2VydC5zaWduID0gZnVuY3Rpb24oa2V5LCBtZCkgewogICAgLy8gVE9ETzogZ2V0IHNpZ25hdHVyZSBPSUQgZnJvbSBwcml2YXRlIGtleQogICAgY2VydC5tZCA9IG1kIHx8IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICB2YXIgYWxnb3JpdGhtT2lkID0gb2lkc1tjZXJ0Lm1kLmFsZ29yaXRobSArICdXaXRoUlNBRW5jcnlwdGlvbiddOwogICAgaWYoIWFsZ29yaXRobU9pZCkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb21wdXRlIGNlcnRpZmljYXRlIGRpZ2VzdC4gJyArCiAgICAgICAgJ1Vua25vd24gbWVzc2FnZSBkaWdlc3QgYWxnb3JpdGhtIE9JRC4nKTsKICAgICAgZXJyb3IuYWxnb3JpdGhtID0gY2VydC5tZC5hbGdvcml0aG07CiAgICAgIHRocm93IGVycm9yOwogICAgfQogICAgY2VydC5zaWduYXR1cmVPaWQgPSBjZXJ0LnNpZ2luZm8uYWxnb3JpdGhtT2lkID0gYWxnb3JpdGhtT2lkOwoKICAgIC8vIGdldCBUQlNDZXJ0aWZpY2F0ZSwgY29udmVydCB0byBERVIKICAgIGNlcnQudGJzQ2VydGlmaWNhdGUgPSBwa2kuZ2V0VEJTQ2VydGlmaWNhdGUoY2VydCk7CiAgICB2YXIgYnl0ZXMgPSBhc24xLnRvRGVyKGNlcnQudGJzQ2VydGlmaWNhdGUpOwoKICAgIC8vIGRpZ2VzdCBhbmQgc2lnbgogICAgY2VydC5tZC51cGRhdGUoYnl0ZXMuZ2V0Qnl0ZXMoKSk7CiAgICBjZXJ0LnNpZ25hdHVyZSA9IGtleS5zaWduKGNlcnQubWQpOwogIH07CgogIC8qKgogICAqIEF0dGVtcHRzIHZlcmlmeSB0aGUgc2lnbmF0dXJlIG9uIHRoZSBwYXNzZWQgY2VydGlmaWNhdGUgdXNpbmcgdGhpcwogICAqIGNlcnRpZmljYXRlJ3MgcHVibGljIGtleS4KICAgKgogICAqIEBwYXJhbSBjaGlsZCB0aGUgY2VydGlmaWNhdGUgdG8gdmVyaWZ5LgogICAqCiAgICogQHJldHVybiB0cnVlIGlmIHZlcmlmaWVkLCBmYWxzZSBpZiBub3QuCiAgICovCiAgY2VydC52ZXJpZnkgPSBmdW5jdGlvbihjaGlsZCkgewogICAgdmFyIHJ2YWwgPSBmYWxzZTsKCiAgICBpZighY2VydC5pc3N1ZWQoY2hpbGQpKSB7CiAgICAgIHZhciBpc3N1ZXIgPSBjaGlsZC5pc3N1ZXI7CiAgICAgIHZhciBzdWJqZWN0ID0gY2VydC5zdWJqZWN0OwogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1RoZSBwYXJlbnQgY2VydGlmaWNhdGUgZGlkIG5vdCBpc3N1ZSB0aGUgZ2l2ZW4gY2hpbGQgJyArCiAgICAgICAgJ2NlcnRpZmljYXRlOyB0aGUgY2hpbGQgY2VydGlmaWNhdGVcJ3MgaXNzdWVyIGRvZXMgbm90IG1hdGNoIHRoZSAnICsKICAgICAgICAncGFyZW50XCdzIHN1YmplY3QuJyk7CiAgICAgIGVycm9yLmV4cGVjdGVkSXNzdWVyID0gaXNzdWVyLmF0dHJpYnV0ZXM7CiAgICAgIGVycm9yLmFjdHVhbElzc3VlciA9IHN1YmplY3QuYXR0cmlidXRlczsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgdmFyIG1kID0gY2hpbGQubWQ7CiAgICBpZihtZCA9PT0gbnVsbCkgewogICAgICAvLyBjaGVjayBzaWduYXR1cmUgT0lEIGZvciBzdXBwb3J0ZWQgc2lnbmF0dXJlIHR5cGVzCiAgICAgIGlmKGNoaWxkLnNpZ25hdHVyZU9pZCBpbiBvaWRzKSB7CiAgICAgICAgdmFyIG9pZCA9IG9pZHNbY2hpbGQuc2lnbmF0dXJlT2lkXTsKICAgICAgICBzd2l0Y2gob2lkKSB7CiAgICAgICAgY2FzZSAnc2hhMVdpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICAgIG1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ21kNVdpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICAgIG1kID0gZm9yZ2UubWQubWQ1LmNyZWF0ZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24nOgogICAgICAgICAgbWQgPSBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdzaGE1MTJXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgICBtZCA9IGZvcmdlLm1kLnNoYTUxMi5jcmVhdGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ1JTQVNTQS1QU1MnOgogICAgICAgICAgbWQgPSBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYobWQgPT09IG51bGwpIHsKICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb21wdXRlIGNlcnRpZmljYXRlIGRpZ2VzdC4gJyArCiAgICAgICAgICAnVW5rbm93biBzaWduYXR1cmUgT0lELicpOwogICAgICAgIGVycm9yLnNpZ25hdHVyZU9pZCA9IGNoaWxkLnNpZ25hdHVyZU9pZDsKICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgfQoKICAgICAgLy8gcHJvZHVjZSBERVIgZm9ybWF0dGVkIFRCU0NlcnRpZmljYXRlIGFuZCBkaWdlc3QgaXQKICAgICAgdmFyIHRic0NlcnRpZmljYXRlID0gY2hpbGQudGJzQ2VydGlmaWNhdGUgfHwgcGtpLmdldFRCU0NlcnRpZmljYXRlKGNoaWxkKTsKICAgICAgdmFyIGJ5dGVzID0gYXNuMS50b0Rlcih0YnNDZXJ0aWZpY2F0ZSk7CiAgICAgIG1kLnVwZGF0ZShieXRlcy5nZXRCeXRlcygpKTsKICAgIH0KCiAgICBpZihtZCAhPT0gbnVsbCkgewogICAgICB2YXIgc2NoZW1lOwoKICAgICAgc3dpdGNoKGNoaWxkLnNpZ25hdHVyZU9pZCkgewogICAgICBjYXNlIG9pZHMuc2hhMVdpdGhSU0FFbmNyeXB0aW9uOgogICAgICAgIHNjaGVtZSA9IHVuZGVmaW5lZDsgIC8qIHVzZSBQS0NTIzEgdjEuNSBwYWRkaW5nIHNjaGVtZSAqLwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIG9pZHNbJ1JTQVNTQS1QU1MnXToKICAgICAgICB2YXIgaGFzaCwgbWdmOwoKICAgICAgICAvKiBpbml0aWFsaXplIG1nZiAqLwogICAgICAgIGhhc2ggPSBvaWRzW2NoaWxkLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmhhc2guYWxnb3JpdGhtT2lkXTsKICAgICAgICBpZihoYXNoID09PSB1bmRlZmluZWQgfHwgZm9yZ2UubWRbaGFzaF0gPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBNR0YgaGFzaCBmdW5jdGlvbi4nKTsKICAgICAgICAgIGVycm9yLm9pZCA9IGNoaWxkLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmhhc2guYWxnb3JpdGhtT2lkOwogICAgICAgICAgZXJyb3IubmFtZSA9IGhhc2g7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CgogICAgICAgIG1nZiA9IG9pZHNbY2hpbGQuc2lnbmF0dXJlUGFyYW1ldGVycy5tZ2YuYWxnb3JpdGhtT2lkXTsKICAgICAgICBpZihtZ2YgPT09IHVuZGVmaW5lZCB8fCBmb3JnZS5tZ2ZbbWdmXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIE1HRiBmdW5jdGlvbi4nKTsKICAgICAgICAgIGVycm9yLm9pZCA9IGNoaWxkLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmFsZ29yaXRobU9pZDsKICAgICAgICAgIGVycm9yLm5hbWUgPSBtZ2Y7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CgogICAgICAgIG1nZiA9IGZvcmdlLm1nZlttZ2ZdLmNyZWF0ZShmb3JnZS5tZFtoYXNoXS5jcmVhdGUoKSk7CgogICAgICAgIC8qIGluaXRpYWxpemUgaGFzaCBmdW5jdGlvbiAqLwogICAgICAgIGhhc2ggPSBvaWRzW2NoaWxkLnNpZ25hdHVyZVBhcmFtZXRlcnMuaGFzaC5hbGdvcml0aG1PaWRdOwogICAgICAgIGlmKGhhc2ggPT09IHVuZGVmaW5lZCB8fCBmb3JnZS5tZFtoYXNoXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICB0aHJvdyB7CiAgICAgICAgICAgIG1lc3NhZ2U6ICdVbnN1cHBvcnRlZCBSU0FTU0EtUFNTIGhhc2ggZnVuY3Rpb24uJywKICAgICAgICAgICAgb2lkOiBjaGlsZC5zaWduYXR1cmVQYXJhbWV0ZXJzLmhhc2guYWxnb3JpdGhtT2lkLAogICAgICAgICAgICBuYW1lOiBoYXNoCiAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgc2NoZW1lID0gZm9yZ2UucHNzLmNyZWF0ZShmb3JnZS5tZFtoYXNoXS5jcmVhdGUoKSwgbWdmLAogICAgICAgICAgY2hpbGQuc2lnbmF0dXJlUGFyYW1ldGVycy5zYWx0TGVuZ3RoKTsKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgLy8gdmVyaWZ5IHNpZ25hdHVyZSBvbiBjZXJ0IHVzaW5nIHB1YmxpYyBrZXkKICAgICAgcnZhbCA9IGNlcnQucHVibGljS2V5LnZlcmlmeSgKICAgICAgICBtZC5kaWdlc3QoKS5nZXRCeXRlcygpLCBjaGlsZC5zaWduYXR1cmUsIHNjaGVtZSk7CiAgICB9CgogICAgcmV0dXJuIHJ2YWw7CiAgfTsKCiAgLyoqCiAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgY2VydGlmaWNhdGUncyBpc3N1ZXIgbWF0Y2hlcyB0aGUgcGFzc2VkCiAgICogY2VydGlmaWNhdGUncyBzdWJqZWN0LiBOb3RlIHRoYXQgbm8gc2lnbmF0dXJlIGNoZWNrIGlzIHBlcmZvcm1lZC4KICAgKgogICAqIEBwYXJhbSBwYXJlbnQgdGhlIGNlcnRpZmljYXRlIHRvIGNoZWNrLgogICAqCiAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgY2VydGlmaWNhdGUncyBpc3N1ZXIgbWF0Y2hlcyB0aGUgcGFzc2VkIGNlcnRpZmljYXRlJ3MKICAgKiAgICAgICAgIHN1YmplY3QuCiAgICovCiAgY2VydC5pc0lzc3VlciA9IGZ1bmN0aW9uKHBhcmVudCkgewogICAgdmFyIHJ2YWwgPSBmYWxzZTsKCiAgICB2YXIgaSA9IGNlcnQuaXNzdWVyOwogICAgdmFyIHMgPSBwYXJlbnQuc3ViamVjdDsKCiAgICAvLyBjb21wYXJlIGhhc2hlcyBpZiBwcmVzZW50CiAgICBpZihpLmhhc2ggJiYgcy5oYXNoKSB7CiAgICAgIHJ2YWwgPSAoaS5oYXNoID09PSBzLmhhc2gpOwogICAgfSBlbHNlIGlmKGkuYXR0cmlidXRlcy5sZW5ndGggPT09IHMuYXR0cmlidXRlcy5sZW5ndGgpIHsKICAgICAgLy8gYWxsIGF0dHJpYnV0ZXMgYXJlIHRoZSBzYW1lIHNvIGlzc3VlciBtYXRjaGVzIHN1YmplY3QKICAgICAgcnZhbCA9IHRydWU7CiAgICAgIHZhciBpYXR0ciwgc2F0dHI7CiAgICAgIGZvcih2YXIgbiA9IDA7IHJ2YWwgJiYgbiA8IGkuYXR0cmlidXRlcy5sZW5ndGg7ICsrbikgewogICAgICAgIGlhdHRyID0gaS5hdHRyaWJ1dGVzW25dOwogICAgICAgIHNhdHRyID0gcy5hdHRyaWJ1dGVzW25dOwogICAgICAgIGlmKGlhdHRyLnR5cGUgIT09IHNhdHRyLnR5cGUgfHwgaWF0dHIudmFsdWUgIT09IHNhdHRyLnZhbHVlKSB7CiAgICAgICAgICAvLyBhdHRyaWJ1dGUgbWlzbWF0Y2gKICAgICAgICAgIHJ2YWwgPSBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAvKioKICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBjZXJ0aWZpY2F0ZSdzIHN1YmplY3QgbWF0Y2hlcyB0aGUgaXNzdWVyIG9mIHRoZQogICAqIGdpdmVuIGNlcnRpZmljYXRlKS4gTm90ZSB0aGF0IG5vdCBzaWduYXR1cmUgY2hlY2sgaXMgcGVyZm9ybWVkLgogICAqCiAgICogQHBhcmFtIGNoaWxkIHRoZSBjZXJ0aWZpY2F0ZSB0byBjaGVjay4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGNlcnRpZmljYXRlJ3Mgc3ViamVjdCBtYXRjaGVzIHRoZSBwYXNzZWQKICAgKiAgICAgICAgIGNlcnRpZmljYXRlJ3MgaXNzdWVyLgogICAqLwogIGNlcnQuaXNzdWVkID0gZnVuY3Rpb24oY2hpbGQpIHsKICAgIHJldHVybiBjaGlsZC5pc0lzc3VlcihjZXJ0KTsKICB9OwoKICAvKioKICAgKiBHZW5lcmF0ZXMgdGhlIHN1YmplY3RLZXlJZGVudGlmaWVyIGZvciB0aGlzIGNlcnRpZmljYXRlIGFzIGJ5dGUgYnVmZmVyLgogICAqCiAgICogQHJldHVybiB0aGUgc3ViamVjdEtleUlkZW50aWZpZXIgZm9yIHRoaXMgY2VydGlmaWNhdGUgYXMgYnl0ZSBidWZmZXIuCiAgICovCiAgY2VydC5nZW5lcmF0ZVN1YmplY3RLZXlJZGVudGlmaWVyID0gZnVuY3Rpb24oKSB7CiAgICAvKiBTZWU6IDQuMi4xLjIgc2VjdGlvbiBvZiB0aGUgdGhlIFJGQzMyODAsIGtleUlkZW50aWZpZXIgaXMgZWl0aGVyOgoKICAgICAgKDEpIFRoZSBrZXlJZGVudGlmaWVyIGlzIGNvbXBvc2VkIG9mIHRoZSAxNjAtYml0IFNIQS0xIGhhc2ggb2YgdGhlCiAgICAgICAgdmFsdWUgb2YgdGhlIEJJVCBTVFJJTkcgc3ViamVjdFB1YmxpY0tleSAoZXhjbHVkaW5nIHRoZSB0YWcsCiAgICAgICAgbGVuZ3RoLCBhbmQgbnVtYmVyIG9mIHVudXNlZCBiaXRzKS4KCiAgICAgICgyKSBUaGUga2V5SWRlbnRpZmllciBpcyBjb21wb3NlZCBvZiBhIGZvdXIgYml0IHR5cGUgZmllbGQgd2l0aAogICAgICAgIHRoZSB2YWx1ZSAwMTAwIGZvbGxvd2VkIGJ5IHRoZSBsZWFzdCBzaWduaWZpY2FudCA2MCBiaXRzIG9mIHRoZQogICAgICAgIFNIQS0xIGhhc2ggb2YgdGhlIHZhbHVlIG9mIHRoZSBCSVQgU1RSSU5HIHN1YmplY3RQdWJsaWNLZXkKICAgICAgICAoZXhjbHVkaW5nIHRoZSB0YWcsIGxlbmd0aCwgYW5kIG51bWJlciBvZiB1bnVzZWQgYml0IHN0cmluZyBiaXRzKS4KICAgICovCgogICAgLy8gc2tpcHBpbmcgdGhlIHRhZywgbGVuZ3RoLCBhbmQgbnVtYmVyIG9mIHVudXNlZCBiaXRzIGlzIHRoZSBzYW1lCiAgICAvLyBhcyBqdXN0IHVzaW5nIHRoZSBSU0FQdWJsaWNLZXkgKGZvciBSU0Ega2V5cywgd2hpY2ggYXJlIHRoZQogICAgLy8gb25seSBvbmVzIHN1cHBvcnRlZCkKICAgIHJldHVybiBwa2kuZ2V0UHVibGljS2V5RmluZ2VycHJpbnQoY2VydC5wdWJsaWNLZXksIHt0eXBlOiAnUlNBUHVibGljS2V5J30pOwogIH07CgogIC8qKgogICAqIFZlcmlmaWVzIHRoZSBzdWJqZWN0S2V5SWRlbnRpZmllciBleHRlbnNpb24gdmFsdWUgZm9yIHRoaXMgY2VydGlmaWNhdGUKICAgKiBhZ2FpbnN0IGl0cyBwdWJsaWMga2V5LiBJZiBubyBleHRlbnNpb24gaXMgZm91bmQsIGZhbHNlIHdpbGwgYmUKICAgKiByZXR1cm5lZC4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB2ZXJpZmllZCwgZmFsc2UgaWYgbm90LgogICAqLwogIGNlcnQudmVyaWZ5U3ViamVjdEtleUlkZW50aWZpZXIgPSBmdW5jdGlvbigpIHsKICAgIHZhciBvaWQgPSBvaWRzWydzdWJqZWN0S2V5SWRlbnRpZmllciddOwogICAgZm9yKHZhciBpID0gMDsgaSA8IGNlcnQuZXh0ZW5zaW9ucy5sZW5ndGg7ICsraSkgewogICAgICB2YXIgZXh0ID0gY2VydC5leHRlbnNpb25zW2ldOwogICAgICBpZihleHQuaWQgPT09IG9pZCkgewogICAgICAgIHZhciBza2kgPSBjZXJ0LmdlbmVyYXRlU3ViamVjdEtleUlkZW50aWZpZXIoKS5nZXRCeXRlcygpOwogICAgICAgIHJldHVybiAoZm9yZ2UudXRpbC5oZXhUb0J5dGVzKGV4dC5zdWJqZWN0S2V5SWRlbnRpZmllcikgPT09IHNraSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBmYWxzZTsKICB9OwoKICByZXR1cm4gY2VydDsKfTsKCi8qKgogKiBDb252ZXJ0cyBhbiBYLjUwOXYzIFJTQSBjZXJ0aWZpY2F0ZSBmcm9tIGFuIEFTTi4xIG9iamVjdC4KICoKICogTm90ZTogSWYgdGhlIGNlcnRpZmljYXRlIGlzIHRvIGJlIHZlcmlmaWVkIHRoZW4gY29tcHV0ZSBoYXNoIHNob3VsZAogKiBiZSBzZXQgdG8gdHJ1ZS4gVGhlcmUgaXMgY3VycmVudGx5IG5vIGltcGxlbWVudGF0aW9uIGZvciBjb252ZXJ0aW5nCiAqIGEgY2VydGlmaWNhdGUgYmFjayB0byBBU04uMSBzbyB0aGUgVEJTQ2VydGlmaWNhdGUgcGFydCBvZiB0aGUgQVNOLjEKICogb2JqZWN0IG5lZWRzIHRvIGJlIHNjYW5uZWQgYmVmb3JlIHRoZSBjZXJ0IG9iamVjdCBpcyBjcmVhdGVkLgogKgogKiBAcGFyYW0gb2JqIHRoZSBhc24xIHJlcHJlc2VudGF0aW9uIG9mIGFuIFguNTA5djMgUlNBIGNlcnRpZmljYXRlLgogKiBAcGFyYW0gY29tcHV0ZUhhc2ggdHJ1ZSB0byBjb21wdXRlIHRoZSBoYXNoIGZvciB2ZXJpZmljYXRpb24uCiAqCiAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRlLgogKi8KcGtpLmNlcnRpZmljYXRlRnJvbUFzbjEgPSBmdW5jdGlvbihvYmosIGNvbXB1dGVIYXNoKSB7CiAgLy8gdmFsaWRhdGUgY2VydGlmaWNhdGUgYW5kIGNhcHR1cmUgZGF0YQogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgeDUwOUNlcnRpZmljYXRlVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFguNTA5IGNlcnRpZmljYXRlLiAnICsKICAgICAgJ0FTTi4xIG9iamVjdCBpcyBub3QgYW4gWDUwOXYzIENlcnRpZmljYXRlLicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3JzOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICAvLyBlbnN1cmUgc2lnbmF0dXJlIGlzIG5vdCBpbnRlcnByZXRlZCBhcyBhbiBlbWJlZGRlZCBBU04uMSBvYmplY3QKICBpZih0eXBlb2YgY2FwdHVyZS5jZXJ0U2lnbmF0dXJlICE9PSAnc3RyaW5nJykgewogICAgdmFyIGNlcnRTaWduYXR1cmUgPSAnXHgwMCc7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgY2FwdHVyZS5jZXJ0U2lnbmF0dXJlLmxlbmd0aDsgKytpKSB7CiAgICAgIGNlcnRTaWduYXR1cmUgKz0gYXNuMS50b0RlcihjYXB0dXJlLmNlcnRTaWduYXR1cmVbaV0pLmdldEJ5dGVzKCk7CiAgICB9CiAgICBjYXB0dXJlLmNlcnRTaWduYXR1cmUgPSBjZXJ0U2lnbmF0dXJlOwogIH0KCiAgLy8gZ2V0IG9pZAogIHZhciBvaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUucHVibGljS2V5T2lkKTsKICBpZihvaWQgIT09IHBraS5vaWRzWydyc2FFbmNyeXB0aW9uJ10pIHsKICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgcHVibGljIGtleS4gT0lEIGlzIG5vdCBSU0EuJyk7CiAgfQoKICAvLyBjcmVhdGUgY2VydGlmaWNhdGUKICB2YXIgY2VydCA9IHBraS5jcmVhdGVDZXJ0aWZpY2F0ZSgpOwogIGNlcnQudmVyc2lvbiA9IGNhcHR1cmUuY2VydFZlcnNpb24gPwogICAgY2FwdHVyZS5jZXJ0VmVyc2lvbi5jaGFyQ29kZUF0KDApIDogMDsKICB2YXIgc2VyaWFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5jZXJ0U2VyaWFsTnVtYmVyKTsKICBjZXJ0LnNlcmlhbE51bWJlciA9IHNlcmlhbC50b0hleCgpOwogIGNlcnQuc2lnbmF0dXJlT2lkID0gZm9yZ2UuYXNuMS5kZXJUb09pZChjYXB0dXJlLmNlcnRTaWduYXR1cmVPaWQpOwogIGNlcnQuc2lnbmF0dXJlUGFyYW1ldGVycyA9IF9yZWFkU2lnbmF0dXJlUGFyYW1ldGVycygKICAgIGNlcnQuc2lnbmF0dXJlT2lkLCBjYXB0dXJlLmNlcnRTaWduYXR1cmVQYXJhbXMsIHRydWUpOwogIGNlcnQuc2lnaW5mby5hbGdvcml0aG1PaWQgPSBmb3JnZS5hc24xLmRlclRvT2lkKGNhcHR1cmUuY2VydGluZm9TaWduYXR1cmVPaWQpOwogIGNlcnQuc2lnaW5mby5wYXJhbWV0ZXJzID0gX3JlYWRTaWduYXR1cmVQYXJhbWV0ZXJzKGNlcnQuc2lnaW5mby5hbGdvcml0aG1PaWQsCiAgICBjYXB0dXJlLmNlcnRpbmZvU2lnbmF0dXJlUGFyYW1zLCBmYWxzZSk7CiAgLy8gc2tpcCAidW51c2VkIGJpdHMiIGluIHNpZ25hdHVyZSB2YWx1ZSBCSVRTVFJJTkcKICB2YXIgc2lnbmF0dXJlID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5jZXJ0U2lnbmF0dXJlKTsKICArK3NpZ25hdHVyZS5yZWFkOwogIGNlcnQuc2lnbmF0dXJlID0gc2lnbmF0dXJlLmdldEJ5dGVzKCk7CgogIHZhciB2YWxpZGl0eSA9IFtdOwogIGlmKGNhcHR1cmUuY2VydFZhbGlkaXR5MVVUQ1RpbWUgIT09IHVuZGVmaW5lZCkgewogICAgdmFsaWRpdHkucHVzaChhc24xLnV0Y1RpbWVUb0RhdGUoY2FwdHVyZS5jZXJ0VmFsaWRpdHkxVVRDVGltZSkpOwogIH0KICBpZihjYXB0dXJlLmNlcnRWYWxpZGl0eTJHZW5lcmFsaXplZFRpbWUgIT09IHVuZGVmaW5lZCkgewogICAgdmFsaWRpdHkucHVzaChhc24xLmdlbmVyYWxpemVkVGltZVRvRGF0ZSgKICAgICAgY2FwdHVyZS5jZXJ0VmFsaWRpdHkyR2VuZXJhbGl6ZWRUaW1lKSk7CiAgfQogIGlmKGNhcHR1cmUuY2VydFZhbGlkaXR5M1VUQ1RpbWUgIT09IHVuZGVmaW5lZCkgewogICAgdmFsaWRpdHkucHVzaChhc24xLnV0Y1RpbWVUb0RhdGUoY2FwdHVyZS5jZXJ0VmFsaWRpdHkzVVRDVGltZSkpOwogIH0KICBpZihjYXB0dXJlLmNlcnRWYWxpZGl0eTRHZW5lcmFsaXplZFRpbWUgIT09IHVuZGVmaW5lZCkgewogICAgdmFsaWRpdHkucHVzaChhc24xLmdlbmVyYWxpemVkVGltZVRvRGF0ZSgKICAgICAgY2FwdHVyZS5jZXJ0VmFsaWRpdHk0R2VuZXJhbGl6ZWRUaW1lKSk7CiAgfQogIGlmKHZhbGlkaXR5Lmxlbmd0aCA+IDIpIHsKICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgbm90QmVmb3JlL25vdEFmdGVyIHZhbGlkaXR5IHRpbWVzOyBtb3JlICcgKwogICAgICAndGhhbiB0d28gdGltZXMgd2VyZSBwcm92aWRlZCBpbiB0aGUgY2VydGlmaWNhdGUuJyk7CiAgfQogIGlmKHZhbGlkaXR5Lmxlbmd0aCA8IDIpIHsKICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgbm90QmVmb3JlL25vdEFmdGVyIHZhbGlkaXR5IHRpbWVzOyB0aGV5ICcgKwogICAgICAnd2VyZSBub3QgcHJvdmlkZWQgYXMgZWl0aGVyIFVUQ1RpbWUgb3IgR2VuZXJhbGl6ZWRUaW1lLicpOwogIH0KICBjZXJ0LnZhbGlkaXR5Lm5vdEJlZm9yZSA9IHZhbGlkaXR5WzBdOwogIGNlcnQudmFsaWRpdHkubm90QWZ0ZXIgPSB2YWxpZGl0eVsxXTsKCiAgLy8ga2VlcCBUQlNDZXJ0aWZpY2F0ZSB0byBwcmVzZXJ2ZSBzaWduYXR1cmUgd2hlbiBleHBvcnRpbmcKICBjZXJ0LnRic0NlcnRpZmljYXRlID0gY2FwdHVyZS50YnNDZXJ0aWZpY2F0ZTsKCiAgaWYoY29tcHV0ZUhhc2gpIHsKICAgIC8vIGNoZWNrIHNpZ25hdHVyZSBPSUQgZm9yIHN1cHBvcnRlZCBzaWduYXR1cmUgdHlwZXMKICAgIGNlcnQubWQgPSBudWxsOwogICAgaWYoY2VydC5zaWduYXR1cmVPaWQgaW4gb2lkcykgewogICAgICB2YXIgb2lkID0gb2lkc1tjZXJ0LnNpZ25hdHVyZU9pZF07CiAgICAgIHN3aXRjaChvaWQpIHsKICAgICAgY2FzZSAnc2hhMVdpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICBjZXJ0Lm1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnbWQ1V2l0aFJTQUVuY3J5cHRpb24nOgogICAgICAgIGNlcnQubWQgPSBmb3JnZS5tZC5tZDUuY3JlYXRlKCk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgJ3NoYTI1NldpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICBjZXJ0Lm1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdzaGE1MTJXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgY2VydC5tZCA9IGZvcmdlLm1kLnNoYTUxMi5jcmVhdGUoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnUlNBU1NBLVBTUyc6CiAgICAgICAgY2VydC5tZCA9IGZvcmdlLm1kLnNoYTI1Ni5jcmVhdGUoKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogICAgaWYoY2VydC5tZCA9PT0gbnVsbCkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb21wdXRlIGNlcnRpZmljYXRlIGRpZ2VzdC4gJyArCiAgICAgICAgJ1Vua25vd24gc2lnbmF0dXJlIE9JRC4nKTsKICAgICAgZXJyb3Iuc2lnbmF0dXJlT2lkID0gY2VydC5zaWduYXR1cmVPaWQ7CiAgICAgIHRocm93IGVycm9yOwogICAgfQoKICAgIC8vIHByb2R1Y2UgREVSIGZvcm1hdHRlZCBUQlNDZXJ0aWZpY2F0ZSBhbmQgZGlnZXN0IGl0CiAgICB2YXIgYnl0ZXMgPSBhc24xLnRvRGVyKGNlcnQudGJzQ2VydGlmaWNhdGUpOwogICAgY2VydC5tZC51cGRhdGUoYnl0ZXMuZ2V0Qnl0ZXMoKSk7CiAgfQoKICAvLyBoYW5kbGUgaXNzdWVyLCBidWlsZCBpc3N1ZXIgbWVzc2FnZSBkaWdlc3QKICB2YXIgaW1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICBjZXJ0Lmlzc3Vlci5nZXRGaWVsZCA9IGZ1bmN0aW9uKHNuKSB7CiAgICByZXR1cm4gX2dldEF0dHJpYnV0ZShjZXJ0Lmlzc3Vlciwgc24pOwogIH07CiAgY2VydC5pc3N1ZXIuYWRkRmllbGQgPSBmdW5jdGlvbihhdHRyKSB7CiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoW2F0dHJdKTsKICAgIGNlcnQuaXNzdWVyLmF0dHJpYnV0ZXMucHVzaChhdHRyKTsKICB9OwogIGNlcnQuaXNzdWVyLmF0dHJpYnV0ZXMgPSBwa2kuUkROQXR0cmlidXRlc0FzQXJyYXkoY2FwdHVyZS5jZXJ0SXNzdWVyLCBpbWQpOwogIGlmKGNhcHR1cmUuY2VydElzc3VlclVuaXF1ZUlkKSB7CiAgICBjZXJ0Lmlzc3Vlci51bmlxdWVJZCA9IGNhcHR1cmUuY2VydElzc3VlclVuaXF1ZUlkOwogIH0KICBjZXJ0Lmlzc3Vlci5oYXNoID0gaW1kLmRpZ2VzdCgpLnRvSGV4KCk7CgogIC8vIGhhbmRsZSBzdWJqZWN0LCBidWlsZCBzdWJqZWN0IG1lc3NhZ2UgZGlnZXN0CiAgdmFyIHNtZCA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgY2VydC5zdWJqZWN0LmdldEZpZWxkID0gZnVuY3Rpb24oc24pIHsKICAgIHJldHVybiBfZ2V0QXR0cmlidXRlKGNlcnQuc3ViamVjdCwgc24pOwogIH07CiAgY2VydC5zdWJqZWN0LmFkZEZpZWxkID0gZnVuY3Rpb24oYXR0cikgewogICAgX2ZpbGxNaXNzaW5nRmllbGRzKFthdHRyXSk7CiAgICBjZXJ0LnN1YmplY3QuYXR0cmlidXRlcy5wdXNoKGF0dHIpOwogIH07CiAgY2VydC5zdWJqZWN0LmF0dHJpYnV0ZXMgPSBwa2kuUkROQXR0cmlidXRlc0FzQXJyYXkoY2FwdHVyZS5jZXJ0U3ViamVjdCwgc21kKTsKICBpZihjYXB0dXJlLmNlcnRTdWJqZWN0VW5pcXVlSWQpIHsKICAgIGNlcnQuc3ViamVjdC51bmlxdWVJZCA9IGNhcHR1cmUuY2VydFN1YmplY3RVbmlxdWVJZDsKICB9CiAgY2VydC5zdWJqZWN0Lmhhc2ggPSBzbWQuZGlnZXN0KCkudG9IZXgoKTsKCiAgLy8gaGFuZGxlIGV4dGVuc2lvbnMKICBpZihjYXB0dXJlLmNlcnRFeHRlbnNpb25zKSB7CiAgICBjZXJ0LmV4dGVuc2lvbnMgPSBwa2kuY2VydGlmaWNhdGVFeHRlbnNpb25zRnJvbUFzbjEoY2FwdHVyZS5jZXJ0RXh0ZW5zaW9ucyk7CiAgfSBlbHNlIHsKICAgIGNlcnQuZXh0ZW5zaW9ucyA9IFtdOwogIH0KCiAgLy8gY29udmVydCBSU0EgcHVibGljIGtleSBmcm9tIEFTTi4xCiAgY2VydC5wdWJsaWNLZXkgPSBwa2kucHVibGljS2V5RnJvbUFzbjEoY2FwdHVyZS5zdWJqZWN0UHVibGljS2V5SW5mbyk7CgogIHJldHVybiBjZXJ0Owp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIEFTTi4xIGV4dGVuc2lvbnMgb2JqZWN0ICh3aXRoIGV4dGVuc2lvbiBzZXF1ZW5jZXMgYXMgaXRzCiAqIHZhbHVlcykgaW50byBhbiBhcnJheSBvZiBleHRlbnNpb24gb2JqZWN0cyB3aXRoIHR5cGVzIGFuZCB2YWx1ZXMuCiAqCiAqIFN1cHBvcnRlZCBleHRlbnNpb25zOgogKgogKiBpZC1jZS1rZXlVc2FnZSBPQkpFQ1QgSURFTlRJRklFUiA6Oj0gIHsgaWQtY2UgMTUgfQogKiBLZXlVc2FnZSA6Oj0gQklUIFNUUklORyB7CiAqICAgZGlnaXRhbFNpZ25hdHVyZSAgICAgICAgKDApLAogKiAgIG5vblJlcHVkaWF0aW9uICAgICAgICAgICgxKSwKICogICBrZXlFbmNpcGhlcm1lbnQgICAgICAgICAoMiksCiAqICAgZGF0YUVuY2lwaGVybWVudCAgICAgICAgKDMpLAogKiAgIGtleUFncmVlbWVudCAgICAgICAgICAgICg0KSwKICogICBrZXlDZXJ0U2lnbiAgICAgICAgICAgICAoNSksCiAqICAgY1JMU2lnbiAgICAgICAgICAgICAgICAgKDYpLAogKiAgIGVuY2lwaGVyT25seSAgICAgICAgICAgICg3KSwKICogICBkZWNpcGhlck9ubHkgICAgICAgICAgICAoOCkKICogfQogKgogKiBpZC1jZS1iYXNpY0NvbnN0cmFpbnRzIE9CSkVDVCBJREVOVElGSUVSIDo6PSAgeyBpZC1jZSAxOSB9CiAqIEJhc2ljQ29uc3RyYWludHMgOjo9IFNFUVVFTkNFIHsKICogICBjQSAgICAgICAgICAgICAgICAgICAgICBCT09MRUFOIERFRkFVTFQgRkFMU0UsCiAqICAgcGF0aExlbkNvbnN0cmFpbnQgICAgICAgSU5URUdFUiAoMC4uTUFYKSBPUFRJT05BTAogKiB9CiAqCiAqIHN1YmplY3RBbHROYW1lIEVYVEVOU0lPTiA6Oj0gewogKiAgIFNZTlRBWCBHZW5lcmFsTmFtZXMKICogICBJREVOVElGSUVEIEJZIGlkLWNlLXN1YmplY3RBbHROYW1lCiAqIH0KICoKICogR2VuZXJhbE5hbWVzIDo6PSBTRVFVRU5DRSBTSVpFICgxLi5NQVgpIE9GIEdlbmVyYWxOYW1lCiAqCiAqIEdlbmVyYWxOYW1lIDo6PSBDSE9JQ0UgewogKiAgIG90aGVyTmFtZSAgICAgIFswXSBJTlNUQU5DRSBPRiBPVEhFUi1OQU1FLAogKiAgIHJmYzgyMk5hbWUgICAgIFsxXSBJQTVTdHJpbmcsCiAqICAgZE5TTmFtZSAgICAgICAgWzJdIElBNVN0cmluZywKICogICB4NDAwQWRkcmVzcyAgICBbM10gT1JBZGRyZXNzLAogKiAgIGRpcmVjdG9yeU5hbWUgIFs0XSBOYW1lLAogKiAgIGVkaVBhcnR5TmFtZSAgIFs1XSBFRElQYXJ0eU5hbWUsCiAqICAgdW5pZm9ybVJlc291cmNlSWRlbnRpZmllciBbNl0gSUE1U3RyaW5nLAogKiAgIElQQWRkcmVzcyAgICAgIFs3XSBPQ1RFVCBTVFJJTkcsCiAqICAgcmVnaXN0ZXJlZElEICAgWzhdIE9CSkVDVCBJREVOVElGSUVSCiAqIH0KICoKICogT1RIRVItTkFNRSA6Oj0gVFlQRS1JREVOVElGSUVSCiAqCiAqIEVESVBhcnR5TmFtZSA6Oj0gU0VRVUVOQ0UgewogKiAgIG5hbWVBc3NpZ25lciBbMF0gRGlyZWN0b3J5U3RyaW5nIHt1Yi1uYW1lfSBPUFRJT05BTCwKICogICBwYXJ0eU5hbWUgICAgWzFdIERpcmVjdG9yeVN0cmluZyB7dWItbmFtZX0KICogfQogKgogKiBAcGFyYW0gZXh0cyB0aGUgZXh0ZW5zaW9ucyBBU04uMSB3aXRoIGV4dGVuc2lvbiBzZXF1ZW5jZXMgdG8gcGFyc2UuCiAqCiAqIEByZXR1cm4gdGhlIGFycmF5LgogKi8KcGtpLmNlcnRpZmljYXRlRXh0ZW5zaW9uc0Zyb21Bc24xID0gZnVuY3Rpb24oZXh0cykgewogIHZhciBydmFsID0gW107CiAgZm9yKHZhciBpID0gMDsgaSA8IGV4dHMudmFsdWUubGVuZ3RoOyArK2kpIHsKICAgIC8vIGdldCBleHRlbnNpb24gc2VxdWVuY2UKICAgIHZhciBleHRzZXEgPSBleHRzLnZhbHVlW2ldOwogICAgZm9yKHZhciBlaSA9IDA7IGVpIDwgZXh0c2VxLnZhbHVlLmxlbmd0aDsgKytlaSkgewogICAgICBydmFsLnB1c2gocGtpLmNlcnRpZmljYXRlRXh0ZW5zaW9uRnJvbUFzbjEoZXh0c2VxLnZhbHVlW2VpXSkpOwogICAgfQogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogUGFyc2VzIGEgc2luZ2xlIGNlcnRpZmljYXRlIGV4dGVuc2lvbiBmcm9tIEFTTi4xLgogKgogKiBAcGFyYW0gZXh0IHRoZSBleHRlbnNpb24gaW4gQVNOLjEgZm9ybWF0LgogKgogKiBAcmV0dXJuIHRoZSBwYXJzZWQgZXh0ZW5zaW9uIGFzIGFuIG9iamVjdC4KICovCnBraS5jZXJ0aWZpY2F0ZUV4dGVuc2lvbkZyb21Bc24xID0gZnVuY3Rpb24oZXh0KSB7CiAgLy8gYW4gZXh0ZW5zaW9uIGhhczoKICAvLyBbMF0gZXh0bklEICAgICAgT0JKRUNUIElERU5USUZJRVIKICAvLyBbMV0gY3JpdGljYWwgICAgQk9PTEVBTiBERUZBVUxUIEZBTFNFCiAgLy8gWzJdIGV4dG5WYWx1ZSAgIE9DVEVUIFNUUklORwogIHZhciBlID0ge307CiAgZS5pZCA9IGFzbjEuZGVyVG9PaWQoZXh0LnZhbHVlWzBdLnZhbHVlKTsKICBlLmNyaXRpY2FsID0gZmFsc2U7CiAgaWYoZXh0LnZhbHVlWzFdLnR5cGUgPT09IGFzbjEuVHlwZS5CT09MRUFOKSB7CiAgICBlLmNyaXRpY2FsID0gKGV4dC52YWx1ZVsxXS52YWx1ZS5jaGFyQ29kZUF0KDApICE9PSAweDAwKTsKICAgIGUudmFsdWUgPSBleHQudmFsdWVbMl0udmFsdWU7CiAgfSBlbHNlIHsKICAgIGUudmFsdWUgPSBleHQudmFsdWVbMV0udmFsdWU7CiAgfQogIC8vIGlmIHRoZSBvaWQgaXMga25vd24sIGdldCBpdHMgbmFtZQogIGlmKGUuaWQgaW4gb2lkcykgewogICAgZS5uYW1lID0gb2lkc1tlLmlkXTsKCiAgICAvLyBoYW5kbGUga2V5IHVzYWdlCiAgICBpZihlLm5hbWUgPT09ICdrZXlVc2FnZScpIHsKICAgICAgLy8gZ2V0IHZhbHVlIGFzIEJJVCBTVFJJTkcKICAgICAgdmFyIGV2ID0gYXNuMS5mcm9tRGVyKGUudmFsdWUpOwogICAgICB2YXIgYjIgPSAweDAwOwogICAgICB2YXIgYjMgPSAweDAwOwogICAgICBpZihldi52YWx1ZS5sZW5ndGggPiAxKSB7CiAgICAgICAgLy8gc2tpcCBmaXJzdCBieXRlLCBqdXN0IGluZGljYXRlcyB1bnVzZWQgYml0cyB3aGljaAogICAgICAgIC8vIHdpbGwgYmUgcGFkZGVkIHdpdGggMHMgYW55d2F5CiAgICAgICAgLy8gZ2V0IGJ5dGVzIHdpdGggZmxhZyBiaXRzCiAgICAgICAgYjIgPSBldi52YWx1ZS5jaGFyQ29kZUF0KDEpOwogICAgICAgIGIzID0gZXYudmFsdWUubGVuZ3RoID4gMiA/IGV2LnZhbHVlLmNoYXJDb2RlQXQoMikgOiAwOwogICAgICB9CiAgICAgIC8vIHNldCBmbGFncwogICAgICBlLmRpZ2l0YWxTaWduYXR1cmUgPSAoYjIgJiAweDgwKSA9PT0gMHg4MDsKICAgICAgZS5ub25SZXB1ZGlhdGlvbiA9IChiMiAmIDB4NDApID09PSAweDQwOwogICAgICBlLmtleUVuY2lwaGVybWVudCA9IChiMiAmIDB4MjApID09PSAweDIwOwogICAgICBlLmRhdGFFbmNpcGhlcm1lbnQgPSAoYjIgJiAweDEwKSA9PT0gMHgxMDsKICAgICAgZS5rZXlBZ3JlZW1lbnQgPSAoYjIgJiAweDA4KSA9PT0gMHgwODsKICAgICAgZS5rZXlDZXJ0U2lnbiA9IChiMiAmIDB4MDQpID09PSAweDA0OwogICAgICBlLmNSTFNpZ24gPSAoYjIgJiAweDAyKSA9PT0gMHgwMjsKICAgICAgZS5lbmNpcGhlck9ubHkgPSAoYjIgJiAweDAxKSA9PT0gMHgwMTsKICAgICAgZS5kZWNpcGhlck9ubHkgPSAoYjMgJiAweDgwKSA9PT0gMHg4MDsKICAgIH0gZWxzZSBpZihlLm5hbWUgPT09ICdiYXNpY0NvbnN0cmFpbnRzJykgewogICAgICAvLyBoYW5kbGUgYmFzaWMgY29uc3RyYWludHMKICAgICAgLy8gZ2V0IHZhbHVlIGFzIFNFUVVFTkNFCiAgICAgIHZhciBldiA9IGFzbjEuZnJvbURlcihlLnZhbHVlKTsKICAgICAgLy8gZ2V0IGNBIEJPT0xFQU4gZmxhZyAoZGVmYXVsdHMgdG8gZmFsc2UpCiAgICAgIGlmKGV2LnZhbHVlLmxlbmd0aCA+IDAgJiYgZXYudmFsdWVbMF0udHlwZSA9PT0gYXNuMS5UeXBlLkJPT0xFQU4pIHsKICAgICAgICBlLmNBID0gKGV2LnZhbHVlWzBdLnZhbHVlLmNoYXJDb2RlQXQoMCkgIT09IDB4MDApOwogICAgICB9IGVsc2UgewogICAgICAgIGUuY0EgPSBmYWxzZTsKICAgICAgfQogICAgICAvLyBnZXQgcGF0aCBsZW5ndGggY29uc3RyYWludAogICAgICB2YXIgdmFsdWUgPSBudWxsOwogICAgICBpZihldi52YWx1ZS5sZW5ndGggPiAwICYmIGV2LnZhbHVlWzBdLnR5cGUgPT09IGFzbjEuVHlwZS5JTlRFR0VSKSB7CiAgICAgICAgdmFsdWUgPSBldi52YWx1ZVswXS52YWx1ZTsKICAgICAgfSBlbHNlIGlmKGV2LnZhbHVlLmxlbmd0aCA+IDEpIHsKICAgICAgICB2YWx1ZSA9IGV2LnZhbHVlWzFdLnZhbHVlOwogICAgICB9CiAgICAgIGlmKHZhbHVlICE9PSBudWxsKSB7CiAgICAgICAgZS5wYXRoTGVuQ29uc3RyYWludCA9IGFzbjEuZGVyVG9JbnRlZ2VyKHZhbHVlKTsKICAgICAgfQogICAgfSBlbHNlIGlmKGUubmFtZSA9PT0gJ2V4dEtleVVzYWdlJykgewogICAgICAvLyBoYW5kbGUgZXh0S2V5VXNhZ2UKICAgICAgLy8gdmFsdWUgaXMgYSBTRVFVRU5DRSBvZiBPSURzCiAgICAgIHZhciBldiA9IGFzbjEuZnJvbURlcihlLnZhbHVlKTsKICAgICAgZm9yKHZhciB2aSA9IDA7IHZpIDwgZXYudmFsdWUubGVuZ3RoOyArK3ZpKSB7CiAgICAgICAgdmFyIG9pZCA9IGFzbjEuZGVyVG9PaWQoZXYudmFsdWVbdmldLnZhbHVlKTsKICAgICAgICBpZihvaWQgaW4gb2lkcykgewogICAgICAgICAgZVtvaWRzW29pZF1dID0gdHJ1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZVtvaWRdID0gdHJ1ZTsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSBpZihlLm5hbWUgPT09ICduc0NlcnRUeXBlJykgewogICAgICAvLyBoYW5kbGUgbnNDZXJ0VHlwZQogICAgICAvLyBnZXQgdmFsdWUgYXMgQklUIFNUUklORwogICAgICB2YXIgZXYgPSBhc24xLmZyb21EZXIoZS52YWx1ZSk7CiAgICAgIHZhciBiMiA9IDB4MDA7CiAgICAgIGlmKGV2LnZhbHVlLmxlbmd0aCA+IDEpIHsKICAgICAgICAvLyBza2lwIGZpcnN0IGJ5dGUsIGp1c3QgaW5kaWNhdGVzIHVudXNlZCBiaXRzIHdoaWNoCiAgICAgICAgLy8gd2lsbCBiZSBwYWRkZWQgd2l0aCAwcyBhbnl3YXkKICAgICAgICAvLyBnZXQgYnl0ZXMgd2l0aCBmbGFnIGJpdHMKICAgICAgICBiMiA9IGV2LnZhbHVlLmNoYXJDb2RlQXQoMSk7CiAgICAgIH0KICAgICAgLy8gc2V0IGZsYWdzCiAgICAgIGUuY2xpZW50ID0gKGIyICYgMHg4MCkgPT09IDB4ODA7CiAgICAgIGUuc2VydmVyID0gKGIyICYgMHg0MCkgPT09IDB4NDA7CiAgICAgIGUuZW1haWwgPSAoYjIgJiAweDIwKSA9PT0gMHgyMDsKICAgICAgZS5vYmpzaWduID0gKGIyICYgMHgxMCkgPT09IDB4MTA7CiAgICAgIGUucmVzZXJ2ZWQgPSAoYjIgJiAweDA4KSA9PT0gMHgwODsKICAgICAgZS5zc2xDQSA9IChiMiAmIDB4MDQpID09PSAweDA0OwogICAgICBlLmVtYWlsQ0EgPSAoYjIgJiAweDAyKSA9PT0gMHgwMjsKICAgICAgZS5vYmpDQSA9IChiMiAmIDB4MDEpID09PSAweDAxOwogICAgfSBlbHNlIGlmKAogICAgICBlLm5hbWUgPT09ICdzdWJqZWN0QWx0TmFtZScgfHwKICAgICAgZS5uYW1lID09PSAnaXNzdWVyQWx0TmFtZScpIHsKICAgICAgLy8gaGFuZGxlIHN1YmplY3RBbHROYW1lL2lzc3VlckFsdE5hbWUKICAgICAgZS5hbHROYW1lcyA9IFtdOwoKICAgICAgLy8gZXYgaXMgYSBTWU5UQVggU0VRVUVOQ0UKICAgICAgdmFyIGduOwogICAgICB2YXIgZXYgPSBhc24xLmZyb21EZXIoZS52YWx1ZSk7CiAgICAgIGZvcih2YXIgbiA9IDA7IG4gPCBldi52YWx1ZS5sZW5ndGg7ICsrbikgewogICAgICAgIC8vIGdldCBHZW5lcmFsTmFtZQogICAgICAgIGduID0gZXYudmFsdWVbbl07CgogICAgICAgIHZhciBhbHROYW1lID0gewogICAgICAgICAgdHlwZTogZ24udHlwZSwKICAgICAgICAgIHZhbHVlOiBnbi52YWx1ZQogICAgICAgIH07CiAgICAgICAgZS5hbHROYW1lcy5wdXNoKGFsdE5hbWUpOwoKICAgICAgICAvLyBOb3RlOiBTdXBwb3J0IGZvciB0eXBlcyAxLDIsNiw3LDgKICAgICAgICBzd2l0Y2goZ24udHlwZSkgewogICAgICAgIC8vIHJmYzgyMk5hbWUKICAgICAgICBjYXNlIDE6CiAgICAgICAgLy8gZE5TTmFtZQogICAgICAgIGNhc2UgMjoKICAgICAgICAvLyB1bmlmb3JtUmVzb3VyY2VJZGVudGlmaWVyIChVUkkpCiAgICAgICAgY2FzZSA2OgogICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gSVBBZGRyZXNzCiAgICAgICAgY2FzZSA3OgogICAgICAgICAgLy8gY29udmVydCB0byBJUHY0L0lQdjYgc3RyaW5nIHJlcHJlc2VudGF0aW9uCiAgICAgICAgICBhbHROYW1lLmlwID0gZm9yZ2UudXRpbC5ieXRlc1RvSVAoZ24udmFsdWUpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gcmVnaXN0ZXJlZElECiAgICAgICAgY2FzZSA4OgogICAgICAgICAgYWx0TmFtZS5vaWQgPSBhc24xLmRlclRvT2lkKGduLnZhbHVlKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAvLyB1bnN1cHBvcnRlZAogICAgICAgIH0KICAgICAgfQogICAgfSBlbHNlIGlmKGUubmFtZSA9PT0gJ3N1YmplY3RLZXlJZGVudGlmaWVyJykgewogICAgICAvLyB2YWx1ZSBpcyBhbiBPQ1RFVFNUUklORyB3L3RoZSBoYXNoIG9mIHRoZSBrZXktdHlwZSBzcGVjaWZpYwogICAgICAvLyBwdWJsaWMga2V5IHN0cnVjdHVyZSAoZWc6IFJTQVB1YmxpY0tleSkKICAgICAgdmFyIGV2ID0gYXNuMS5mcm9tRGVyKGUudmFsdWUpOwogICAgICBlLnN1YmplY3RLZXlJZGVudGlmaWVyID0gZm9yZ2UudXRpbC5ieXRlc1RvSGV4KGV2LnZhbHVlKTsKICAgIH0KICB9CiAgcmV0dXJuIGU7Cn07CgovKioKICogQ29udmVydHMgYSBQS0NTIzEwIGNlcnRpZmljYXRpb24gcmVxdWVzdCAoQ1NSKSBmcm9tIGFuIEFTTi4xIG9iamVjdC4KICoKICogTm90ZTogSWYgdGhlIGNlcnRpZmljYXRpb24gcmVxdWVzdCBpcyB0byBiZSB2ZXJpZmllZCB0aGVuIGNvbXB1dGUgaGFzaAogKiBzaG91bGQgYmUgc2V0IHRvIHRydWUuIFRoZXJlIGlzIGN1cnJlbnRseSBubyBpbXBsZW1lbnRhdGlvbiBmb3IgY29udmVydGluZwogKiBhIGNlcnRpZmljYXRlIGJhY2sgdG8gQVNOLjEgc28gdGhlIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyBwYXJ0IG9mIHRoZQogKiBBU04uMSBvYmplY3QgbmVlZHMgdG8gYmUgc2Nhbm5lZCBiZWZvcmUgdGhlIGNzciBvYmplY3QgaXMgY3JlYXRlZC4KICoKICogQHBhcmFtIG9iaiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIFBLQ1MjMTAgY2VydGlmaWNhdGlvbiByZXF1ZXN0IChDU1IpLgogKiBAcGFyYW0gY29tcHV0ZUhhc2ggdHJ1ZSB0byBjb21wdXRlIHRoZSBoYXNoIGZvciB2ZXJpZmljYXRpb24uCiAqCiAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRpb24gcmVxdWVzdCAoQ1NSKS4KICovCnBraS5jZXJ0aWZpY2F0aW9uUmVxdWVzdEZyb21Bc24xID0gZnVuY3Rpb24ob2JqLCBjb21wdXRlSGFzaCkgewogIC8vIHZhbGlkYXRlIGNlcnRpZmljYXRpb24gcmVxdWVzdCBhbmQgY2FwdHVyZSBkYXRhCiAgdmFyIGNhcHR1cmUgPSB7fTsKICB2YXIgZXJyb3JzID0gW107CiAgaWYoIWFzbjEudmFsaWRhdGUob2JqLCBjZXJ0aWZpY2F0aW9uUmVxdWVzdFZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzEwIGNlcnRpZmljYXRlIHJlcXVlc3QuICcgKwogICAgICAnQVNOLjEgb2JqZWN0IGlzIG5vdCBhIFBLQ1MjMTAgQ2VydGlmaWNhdGlvblJlcXVlc3QuJyk7CiAgICBlcnJvci5lcnJvcnMgPSBlcnJvcnM7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIC8vIGVuc3VyZSBzaWduYXR1cmUgaXMgbm90IGludGVycHJldGVkIGFzIGFuIGVtYmVkZGVkIEFTTi4xIG9iamVjdAogIGlmKHR5cGVvZiBjYXB0dXJlLmNzclNpZ25hdHVyZSAhPT0gJ3N0cmluZycpIHsKICAgIHZhciBjc3JTaWduYXR1cmUgPSAnXHgwMCc7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgY2FwdHVyZS5jc3JTaWduYXR1cmUubGVuZ3RoOyArK2kpIHsKICAgICAgY3NyU2lnbmF0dXJlICs9IGFzbjEudG9EZXIoY2FwdHVyZS5jc3JTaWduYXR1cmVbaV0pLmdldEJ5dGVzKCk7CiAgICB9CiAgICBjYXB0dXJlLmNzclNpZ25hdHVyZSA9IGNzclNpZ25hdHVyZTsKICB9CgogIC8vIGdldCBvaWQKICB2YXIgb2lkID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLnB1YmxpY0tleU9pZCk7CiAgaWYob2lkICE9PSBwa2kub2lkcy5yc2FFbmNyeXB0aW9uKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIHB1YmxpYyBrZXkuIE9JRCBpcyBub3QgUlNBLicpOwogIH0KCiAgLy8gY3JlYXRlIGNlcnRpZmljYXRpb24gcmVxdWVzdAogIHZhciBjc3IgPSBwa2kuY3JlYXRlQ2VydGlmaWNhdGlvblJlcXVlc3QoKTsKICBjc3IudmVyc2lvbiA9IGNhcHR1cmUuY3NyVmVyc2lvbiA/IGNhcHR1cmUuY3NyVmVyc2lvbi5jaGFyQ29kZUF0KDApIDogMDsKICBjc3Iuc2lnbmF0dXJlT2lkID0gZm9yZ2UuYXNuMS5kZXJUb09pZChjYXB0dXJlLmNzclNpZ25hdHVyZU9pZCk7CiAgY3NyLnNpZ25hdHVyZVBhcmFtZXRlcnMgPSBfcmVhZFNpZ25hdHVyZVBhcmFtZXRlcnMoCiAgICBjc3Iuc2lnbmF0dXJlT2lkLCBjYXB0dXJlLmNzclNpZ25hdHVyZVBhcmFtcywgdHJ1ZSk7CiAgY3NyLnNpZ2luZm8uYWxnb3JpdGhtT2lkID0gZm9yZ2UuYXNuMS5kZXJUb09pZChjYXB0dXJlLmNzclNpZ25hdHVyZU9pZCk7CiAgY3NyLnNpZ2luZm8ucGFyYW1ldGVycyA9IF9yZWFkU2lnbmF0dXJlUGFyYW1ldGVycygKICAgIGNzci5zaWdpbmZvLmFsZ29yaXRobU9pZCwgY2FwdHVyZS5jc3JTaWduYXR1cmVQYXJhbXMsIGZhbHNlKTsKICAvLyBza2lwICJ1bnVzZWQgYml0cyIgaW4gc2lnbmF0dXJlIHZhbHVlIEJJVFNUUklORwogIHZhciBzaWduYXR1cmUgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLmNzclNpZ25hdHVyZSk7CiAgKytzaWduYXR1cmUucmVhZDsKICBjc3Iuc2lnbmF0dXJlID0gc2lnbmF0dXJlLmdldEJ5dGVzKCk7CgogIC8vIGtlZXAgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIHRvIHByZXNlcnZlIHNpZ25hdHVyZSB3aGVuIGV4cG9ydGluZwogIGNzci5jZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8gPSBjYXB0dXJlLmNlcnRpZmljYXRpb25SZXF1ZXN0SW5mbzsKCiAgaWYoY29tcHV0ZUhhc2gpIHsKICAgIC8vIGNoZWNrIHNpZ25hdHVyZSBPSUQgZm9yIHN1cHBvcnRlZCBzaWduYXR1cmUgdHlwZXMKICAgIGNzci5tZCA9IG51bGw7CiAgICBpZihjc3Iuc2lnbmF0dXJlT2lkIGluIG9pZHMpIHsKICAgICAgdmFyIG9pZCA9IG9pZHNbY3NyLnNpZ25hdHVyZU9pZF07CiAgICAgIHN3aXRjaChvaWQpIHsKICAgICAgY2FzZSAnc2hhMVdpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICBjc3IubWQgPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdtZDVXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgY3NyLm1kID0gZm9yZ2UubWQubWQ1LmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgY3NyLm1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdzaGE1MTJXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgY3NyLm1kID0gZm9yZ2UubWQuc2hhNTEyLmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdSU0FTU0EtUFNTJzoKICAgICAgICBjc3IubWQgPSBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIGlmKGNzci5tZCA9PT0gbnVsbCkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb21wdXRlIGNlcnRpZmljYXRpb24gcmVxdWVzdCBkaWdlc3QuICcgKwogICAgICAgICdVbmtub3duIHNpZ25hdHVyZSBPSUQuJyk7CiAgICAgIGVycm9yLnNpZ25hdHVyZU9pZCA9IGNzci5zaWduYXR1cmVPaWQ7CiAgICAgIHRocm93IGVycm9yOwogICAgfQoKICAgIC8vIHByb2R1Y2UgREVSIGZvcm1hdHRlZCBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8gYW5kIGRpZ2VzdCBpdAogICAgdmFyIGJ5dGVzID0gYXNuMS50b0Rlcihjc3IuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvKTsKICAgIGNzci5tZC51cGRhdGUoYnl0ZXMuZ2V0Qnl0ZXMoKSk7CiAgfQoKICAvLyBoYW5kbGUgc3ViamVjdCwgYnVpbGQgc3ViamVjdCBtZXNzYWdlIGRpZ2VzdAogIHZhciBzbWQgPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogIGNzci5zdWJqZWN0LmdldEZpZWxkID0gZnVuY3Rpb24oc24pIHsKICAgIHJldHVybiBfZ2V0QXR0cmlidXRlKGNzci5zdWJqZWN0LCBzbik7CiAgfTsKICBjc3Iuc3ViamVjdC5hZGRGaWVsZCA9IGZ1bmN0aW9uKGF0dHIpIHsKICAgIF9maWxsTWlzc2luZ0ZpZWxkcyhbYXR0cl0pOwogICAgY3NyLnN1YmplY3QuYXR0cmlidXRlcy5wdXNoKGF0dHIpOwogIH07CiAgY3NyLnN1YmplY3QuYXR0cmlidXRlcyA9IHBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheSgKICAgIGNhcHR1cmUuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvU3ViamVjdCwgc21kKTsKICBjc3Iuc3ViamVjdC5oYXNoID0gc21kLmRpZ2VzdCgpLnRvSGV4KCk7CgogIC8vIGNvbnZlcnQgUlNBIHB1YmxpYyBrZXkgZnJvbSBBU04uMQogIGNzci5wdWJsaWNLZXkgPSBwa2kucHVibGljS2V5RnJvbUFzbjEoY2FwdHVyZS5zdWJqZWN0UHVibGljS2V5SW5mbyk7CgogIC8vIGNvbnZlcnQgYXR0cmlidXRlcyBmcm9tIEFTTi4xCiAgY3NyLmdldEF0dHJpYnV0ZSA9IGZ1bmN0aW9uKHNuKSB7CiAgICByZXR1cm4gX2dldEF0dHJpYnV0ZShjc3IsIHNuKTsKICB9OwogIGNzci5hZGRBdHRyaWJ1dGUgPSBmdW5jdGlvbihhdHRyKSB7CiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoW2F0dHJdKTsKICAgIGNzci5hdHRyaWJ1dGVzLnB1c2goYXR0cik7CiAgfTsKICBjc3IuYXR0cmlidXRlcyA9IHBraS5DUklBdHRyaWJ1dGVzQXNBcnJheSgKICAgIGNhcHR1cmUuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvQXR0cmlidXRlcyB8fCBbXSk7CgogIHJldHVybiBjc3I7Cn07CgovKioKICogQ3JlYXRlcyBhbiBlbXB0eSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QgKGEgQ1NSIG9yIGNlcnRpZmljYXRlIHNpZ25pbmcKICogcmVxdWVzdCkuIE9uY2UgY3JlYXRlZCwgaXRzIHB1YmxpYyBrZXkgYW5kIGF0dHJpYnV0ZXMgY2FuIGJlIHNldCBhbmQgdGhlbgogKiBpdCBjYW4gYmUgc2lnbmVkLgogKgogKiBAcmV0dXJuIHRoZSBlbXB0eSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QuCiAqLwpwa2kuY3JlYXRlQ2VydGlmaWNhdGlvblJlcXVlc3QgPSBmdW5jdGlvbigpIHsKICB2YXIgY3NyID0ge307CiAgY3NyLnZlcnNpb24gPSAweDAwOwogIGNzci5zaWduYXR1cmVPaWQgPSBudWxsOwogIGNzci5zaWduYXR1cmUgPSBudWxsOwogIGNzci5zaWdpbmZvID0ge307CiAgY3NyLnNpZ2luZm8uYWxnb3JpdGhtT2lkID0gbnVsbDsKCiAgY3NyLnN1YmplY3QgPSB7fTsKICBjc3Iuc3ViamVjdC5nZXRGaWVsZCA9IGZ1bmN0aW9uKHNuKSB7CiAgICByZXR1cm4gX2dldEF0dHJpYnV0ZShjc3Iuc3ViamVjdCwgc24pOwogIH07CiAgY3NyLnN1YmplY3QuYWRkRmllbGQgPSBmdW5jdGlvbihhdHRyKSB7CiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoW2F0dHJdKTsKICAgIGNzci5zdWJqZWN0LmF0dHJpYnV0ZXMucHVzaChhdHRyKTsKICB9OwogIGNzci5zdWJqZWN0LmF0dHJpYnV0ZXMgPSBbXTsKICBjc3Iuc3ViamVjdC5oYXNoID0gbnVsbDsKCiAgY3NyLnB1YmxpY0tleSA9IG51bGw7CiAgY3NyLmF0dHJpYnV0ZXMgPSBbXTsKICBjc3IuZ2V0QXR0cmlidXRlID0gZnVuY3Rpb24oc24pIHsKICAgIHJldHVybiBfZ2V0QXR0cmlidXRlKGNzciwgc24pOwogIH07CiAgY3NyLmFkZEF0dHJpYnV0ZSA9IGZ1bmN0aW9uKGF0dHIpIHsKICAgIF9maWxsTWlzc2luZ0ZpZWxkcyhbYXR0cl0pOwogICAgY3NyLmF0dHJpYnV0ZXMucHVzaChhdHRyKTsKICB9OwogIGNzci5tZCA9IG51bGw7CgogIC8qKgogICAqIFNldHMgdGhlIHN1YmplY3Qgb2YgdGhpcyBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QuCiAgICoKICAgKiBAcGFyYW0gYXR0cnMgdGhlIGFycmF5IG9mIHN1YmplY3QgYXR0cmlidXRlcyB0byB1c2UuCiAgICovCiAgY3NyLnNldFN1YmplY3QgPSBmdW5jdGlvbihhdHRycykgewogICAgLy8gc2V0IG5ldyBhdHRyaWJ1dGVzCiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoYXR0cnMpOwogICAgY3NyLnN1YmplY3QuYXR0cmlidXRlcyA9IGF0dHJzOwogICAgY3NyLnN1YmplY3QuaGFzaCA9IG51bGw7CiAgfTsKCiAgLyoqCiAgICogU2V0cyB0aGUgYXR0cmlidXRlcyBvZiB0aGlzIGNlcnRpZmljYXRpb24gcmVxdWVzdC4KICAgKgogICAqIEBwYXJhbSBhdHRycyB0aGUgYXJyYXkgb2YgYXR0cmlidXRlcyB0byB1c2UuCiAgICovCiAgY3NyLnNldEF0dHJpYnV0ZXMgPSBmdW5jdGlvbihhdHRycykgewogICAgLy8gc2V0IG5ldyBhdHRyaWJ1dGVzCiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoYXR0cnMpOwogICAgY3NyLmF0dHJpYnV0ZXMgPSBhdHRyczsKICB9OwoKICAvKioKICAgKiBTaWducyB0aGlzIGNlcnRpZmljYXRpb24gcmVxdWVzdCB1c2luZyB0aGUgZ2l2ZW4gcHJpdmF0ZSBrZXkuCiAgICoKICAgKiBAcGFyYW0ga2V5IHRoZSBwcml2YXRlIGtleSB0byBzaWduIHdpdGguCiAgICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlIChkZWZhdWx0cyB0byBmb3JnZS5tZC5zaGExKS4KICAgKi8KICBjc3Iuc2lnbiA9IGZ1bmN0aW9uKGtleSwgbWQpIHsKICAgIC8vIFRPRE86IGdldCBzaWduYXR1cmUgT0lEIGZyb20gcHJpdmF0ZSBrZXkKICAgIGNzci5tZCA9IG1kIHx8IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICB2YXIgYWxnb3JpdGhtT2lkID0gb2lkc1tjc3IubWQuYWxnb3JpdGhtICsgJ1dpdGhSU0FFbmNyeXB0aW9uJ107CiAgICBpZighYWxnb3JpdGhtT2lkKSB7CiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ291bGQgbm90IGNvbXB1dGUgY2VydGlmaWNhdGlvbiByZXF1ZXN0IGRpZ2VzdC4gJyArCiAgICAgICAgJ1Vua25vd24gbWVzc2FnZSBkaWdlc3QgYWxnb3JpdGhtIE9JRC4nKTsKICAgICAgZXJyb3IuYWxnb3JpdGhtID0gY3NyLm1kLmFsZ29yaXRobTsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CiAgICBjc3Iuc2lnbmF0dXJlT2lkID0gY3NyLnNpZ2luZm8uYWxnb3JpdGhtT2lkID0gYWxnb3JpdGhtT2lkOwoKICAgIC8vIGdldCBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8sIGNvbnZlcnQgdG8gREVSCiAgICBjc3IuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvID0gcGtpLmdldENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyhjc3IpOwogICAgdmFyIGJ5dGVzID0gYXNuMS50b0Rlcihjc3IuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvKTsKCiAgICAvLyBkaWdlc3QgYW5kIHNpZ24KICAgIGNzci5tZC51cGRhdGUoYnl0ZXMuZ2V0Qnl0ZXMoKSk7CiAgICBjc3Iuc2lnbmF0dXJlID0ga2V5LnNpZ24oY3NyLm1kKTsKICB9OwoKICAvKioKICAgKiBBdHRlbXB0cyB2ZXJpZnkgdGhlIHNpZ25hdHVyZSBvbiB0aGUgcGFzc2VkIGNlcnRpZmljYXRpb24gcmVxdWVzdCB1c2luZwogICAqIGl0cyBwdWJsaWMga2V5LgogICAqCiAgICogQSBDU1IgdGhhdCBoYXMgYmVlbiBleHBvcnRlZCB0byBhIGZpbGUgaW4gUEVNIGZvcm1hdCBjYW4gYmUgdmVyaWZpZWQgdXNpbmcKICAgKiBPcGVuU1NMIHVzaW5nIHRoaXMgY29tbWFuZDoKICAgKgogICAqIG9wZW5zc2wgcmVxIC1pbiA8dGhlLWNzci1wZW0tZmlsZT4gLXZlcmlmeSAtbm9vdXQgLXRleHQKICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB2ZXJpZmllZCwgZmFsc2UgaWYgbm90LgogICAqLwogIGNzci52ZXJpZnkgPSBmdW5jdGlvbigpIHsKICAgIHZhciBydmFsID0gZmFsc2U7CgogICAgdmFyIG1kID0gY3NyLm1kOwogICAgaWYobWQgPT09IG51bGwpIHsKICAgICAgLy8gY2hlY2sgc2lnbmF0dXJlIE9JRCBmb3Igc3VwcG9ydGVkIHNpZ25hdHVyZSB0eXBlcwogICAgICBpZihjc3Iuc2lnbmF0dXJlT2lkIGluIG9pZHMpIHsKICAgICAgICAvLyBUT0RPOiBjcmVhdGUgRFJZIGBPSUQgdG8gbWRgIGZ1bmN0aW9uCiAgICAgICAgdmFyIG9pZCA9IG9pZHNbY3NyLnNpZ25hdHVyZU9pZF07CiAgICAgICAgc3dpdGNoKG9pZCkgewogICAgICAgIGNhc2UgJ3NoYTFXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgICBtZCA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdtZDVXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgICBtZCA9IGZvcmdlLm1kLm1kNS5jcmVhdGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ3NoYTI1NldpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICAgIG1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnc2hhNTEyV2l0aFJTQUVuY3J5cHRpb24nOgogICAgICAgICAgbWQgPSBmb3JnZS5tZC5zaGE1MTIuY3JlYXRlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdSU0FTU0EtUFNTJzoKICAgICAgICAgIG1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmKG1kID09PSBudWxsKSB7CiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDb3VsZCBub3QgY29tcHV0ZSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QgZGlnZXN0LiAnICsKICAgICAgICAgICdVbmtub3duIHNpZ25hdHVyZSBPSUQuJyk7CiAgICAgICAgZXJyb3Iuc2lnbmF0dXJlT2lkID0gY3NyLnNpZ25hdHVyZU9pZDsKICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgfQoKICAgICAgLy8gcHJvZHVjZSBERVIgZm9ybWF0dGVkIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyBhbmQgZGlnZXN0IGl0CiAgICAgIHZhciBjcmkgPSBjc3IuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIHx8CiAgICAgICAgcGtpLmdldENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyhjc3IpOwogICAgICB2YXIgYnl0ZXMgPSBhc24xLnRvRGVyKGNyaSk7CiAgICAgIG1kLnVwZGF0ZShieXRlcy5nZXRCeXRlcygpKTsKICAgIH0KCiAgICBpZihtZCAhPT0gbnVsbCkgewogICAgICB2YXIgc2NoZW1lOwoKICAgICAgc3dpdGNoKGNzci5zaWduYXR1cmVPaWQpIHsKICAgICAgY2FzZSBvaWRzLnNoYTFXaXRoUlNBRW5jcnlwdGlvbjoKICAgICAgICAvKiB1c2UgUEtDUyMxIHYxLjUgcGFkZGluZyBzY2hlbWUgKi8KICAgICAgICBicmVhazsKICAgICAgY2FzZSBvaWRzWydSU0FTU0EtUFNTJ106CiAgICAgICAgdmFyIGhhc2gsIG1nZjsKCiAgICAgICAgLyogaW5pdGlhbGl6ZSBtZ2YgKi8KICAgICAgICBoYXNoID0gb2lkc1tjc3Iuc2lnbmF0dXJlUGFyYW1ldGVycy5tZ2YuaGFzaC5hbGdvcml0aG1PaWRdOwogICAgICAgIGlmKGhhc2ggPT09IHVuZGVmaW5lZCB8fCBmb3JnZS5tZFtoYXNoXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIE1HRiBoYXNoIGZ1bmN0aW9uLicpOwogICAgICAgICAgZXJyb3Iub2lkID0gY3NyLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmhhc2guYWxnb3JpdGhtT2lkOwogICAgICAgICAgZXJyb3IubmFtZSA9IGhhc2g7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CgogICAgICAgIG1nZiA9IG9pZHNbY3NyLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmFsZ29yaXRobU9pZF07CiAgICAgICAgaWYobWdmID09PSB1bmRlZmluZWQgfHwgZm9yZ2UubWdmW21nZl0gPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBNR0YgZnVuY3Rpb24uJyk7CiAgICAgICAgICBlcnJvci5vaWQgPSBjc3Iuc2lnbmF0dXJlUGFyYW1ldGVycy5tZ2YuYWxnb3JpdGhtT2lkOwogICAgICAgICAgZXJyb3IubmFtZSA9IG1nZjsKICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgIH0KCiAgICAgICAgbWdmID0gZm9yZ2UubWdmW21nZl0uY3JlYXRlKGZvcmdlLm1kW2hhc2hdLmNyZWF0ZSgpKTsKCiAgICAgICAgLyogaW5pdGlhbGl6ZSBoYXNoIGZ1bmN0aW9uICovCiAgICAgICAgaGFzaCA9IG9pZHNbY3NyLnNpZ25hdHVyZVBhcmFtZXRlcnMuaGFzaC5hbGdvcml0aG1PaWRdOwogICAgICAgIGlmKGhhc2ggPT09IHVuZGVmaW5lZCB8fCBmb3JnZS5tZFtoYXNoXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIFJTQVNTQS1QU1MgaGFzaCBmdW5jdGlvbi4nKTsKICAgICAgICAgIGVycm9yLm9pZCA9IGNzci5zaWduYXR1cmVQYXJhbWV0ZXJzLmhhc2guYWxnb3JpdGhtT2lkOwogICAgICAgICAgZXJyb3IubmFtZSA9IGhhc2g7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CgogICAgICAgIHNjaGVtZSA9IGZvcmdlLnBzcy5jcmVhdGUoZm9yZ2UubWRbaGFzaF0uY3JlYXRlKCksIG1nZiwKICAgICAgICAgIGNzci5zaWduYXR1cmVQYXJhbWV0ZXJzLnNhbHRMZW5ndGgpOwogICAgICAgIGJyZWFrOwogICAgICB9CgogICAgICAvLyB2ZXJpZnkgc2lnbmF0dXJlIG9uIGNzciB1c2luZyBpdHMgcHVibGljIGtleQogICAgICBydmFsID0gY3NyLnB1YmxpY0tleS52ZXJpZnkoCiAgICAgICAgbWQuZGlnZXN0KCkuZ2V0Qnl0ZXMoKSwgY3NyLnNpZ25hdHVyZSwgc2NoZW1lKTsKICAgIH0KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICByZXR1cm4gY3NyOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFguNTA5IHN1YmplY3Qgb3IgaXNzdWVyIHRvIGFuIEFTTi4xIFJETlNlcXVlbmNlLgogKgogKiBAcGFyYW0gb2JqIHRoZSBzdWJqZWN0IG9yIGlzc3VlciAoZGlzdGluZ3Vpc2hlZCBuYW1lKS4KICoKICogQHJldHVybiB0aGUgQVNOLjEgUkROU2VxdWVuY2UuCiAqLwpmdW5jdGlvbiBfZG5Ub0FzbjEob2JqKSB7CiAgLy8gY3JlYXRlIGFuIGVtcHR5IFJETlNlcXVlbmNlCiAgdmFyIHJ2YWwgPSBhc24xLmNyZWF0ZSgKICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFtdKTsKCiAgLy8gaXRlcmF0ZSBvdmVyIGF0dHJpYnV0ZXMKICB2YXIgYXR0ciwgc2V0OwogIHZhciBhdHRycyA9IG9iai5hdHRyaWJ1dGVzOwogIGZvcih2YXIgaSA9IDA7IGkgPCBhdHRycy5sZW5ndGg7ICsraSkgewogICAgYXR0ciA9IGF0dHJzW2ldOwogICAgdmFyIHZhbHVlID0gYXR0ci52YWx1ZTsKCiAgICAvLyByZXVzZSB0YWcgY2xhc3MgZm9yIGF0dHJpYnV0ZSB2YWx1ZSBpZiBhdmFpbGFibGUKICAgIHZhciB2YWx1ZVRhZ0NsYXNzID0gYXNuMS5UeXBlLlBSSU5UQUJMRVNUUklORzsKICAgIGlmKCd2YWx1ZVRhZ0NsYXNzJyBpbiBhdHRyKSB7CiAgICAgIHZhbHVlVGFnQ2xhc3MgPSBhdHRyLnZhbHVlVGFnQ2xhc3M7CgogICAgICBpZih2YWx1ZVRhZ0NsYXNzID09PSBhc24xLlR5cGUuVVRGOCkgewogICAgICAgIHZhbHVlID0gZm9yZ2UudXRpbC5lbmNvZGVVdGY4KHZhbHVlKTsKICAgICAgfQogICAgICAvLyBGSVhNRTogaGFuZGxlIG1vcmUgZW5jb2RpbmdzCiAgICB9CgogICAgLy8gY3JlYXRlIGEgUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZSBzZXQKICAgIC8vIGVhY2ggdmFsdWUgaW4gdGhlIHNldCBpcyBhbiBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgZmlyc3QKICAgIC8vIGNvbnRhaW5pbmcgdGhlIHR5cGUgKGFuIE9JRCkgYW5kIHNlY29uZCB0aGUgdmFsdWUKICAgIHNldCA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VULCB0cnVlLCBbCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAvLyBBdHRyaWJ1dGVUeXBlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0RlcihhdHRyLnR5cGUpLmdldEJ5dGVzKCkpLAogICAgICAgIC8vIEF0dHJpYnV0ZVZhbHVlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIHZhbHVlVGFnQ2xhc3MsIGZhbHNlLCB2YWx1ZSkKICAgICAgXSkKICAgIF0pOwogICAgcnZhbC52YWx1ZS5wdXNoKHNldCk7CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIEdldHMgYWxsIHByaW50YWJsZSBhdHRyaWJ1dGVzICh0eXBpY2FsbHkgb2YgYW4gaXNzdWVyIG9yIHN1YmplY3QpIGluIGEKICogc2ltcGxpZmllZCBKU09OIGZvcm1hdCBmb3IgZGlzcGxheS4KICoKICogQHBhcmFtIGF0dHJzIHRoZSBhdHRyaWJ1dGVzLgogKgogKiBAcmV0dXJuIHRoZSBKU09OIGZvciBkaXNwbGF5LgogKi8KZnVuY3Rpb24gX2dldEF0dHJpYnV0ZXNBc0pzb24oYXR0cnMpIHsKICB2YXIgcnZhbCA9IHt9OwogIGZvcih2YXIgaSA9IDA7IGkgPCBhdHRycy5sZW5ndGg7ICsraSkgewogICAgdmFyIGF0dHIgPSBhdHRyc1tpXTsKICAgIGlmKGF0dHIuc2hvcnROYW1lICYmICgKICAgICAgYXR0ci52YWx1ZVRhZ0NsYXNzID09PSBhc24xLlR5cGUuVVRGOCB8fAogICAgICBhdHRyLnZhbHVlVGFnQ2xhc3MgPT09IGFzbjEuVHlwZS5QUklOVEFCTEVTVFJJTkcgfHwKICAgICAgYXR0ci52YWx1ZVRhZ0NsYXNzID09PSBhc24xLlR5cGUuSUE1U1RSSU5HKSkgewogICAgICB2YXIgdmFsdWUgPSBhdHRyLnZhbHVlOwogICAgICBpZihhdHRyLnZhbHVlVGFnQ2xhc3MgPT09IGFzbjEuVHlwZS5VVEY4KSB7CiAgICAgICAgdmFsdWUgPSBmb3JnZS51dGlsLmVuY29kZVV0ZjgoYXR0ci52YWx1ZSk7CiAgICAgIH0KICAgICAgaWYoIShhdHRyLnNob3J0TmFtZSBpbiBydmFsKSkgewogICAgICAgIHJ2YWxbYXR0ci5zaG9ydE5hbWVdID0gdmFsdWU7CiAgICAgIH0gZWxzZSBpZihmb3JnZS51dGlsLmlzQXJyYXkocnZhbFthdHRyLnNob3J0TmFtZV0pKSB7CiAgICAgICAgcnZhbFthdHRyLnNob3J0TmFtZV0ucHVzaCh2YWx1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcnZhbFthdHRyLnNob3J0TmFtZV0gPSBbcnZhbFthdHRyLnNob3J0TmFtZV0sIHZhbHVlXTsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIEZpbGxzIGluIG1pc3NpbmcgZmllbGRzIGluIGF0dHJpYnV0ZXMuCiAqCiAqIEBwYXJhbSBhdHRycyB0aGUgYXR0cmlidXRlcyB0byBmaWxsIG1pc3NpbmcgZmllbGRzIGluLgogKi8KZnVuY3Rpb24gX2ZpbGxNaXNzaW5nRmllbGRzKGF0dHJzKSB7CiAgdmFyIGF0dHI7CiAgZm9yKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgKytpKSB7CiAgICBhdHRyID0gYXR0cnNbaV07CgogICAgLy8gcG9wdWxhdGUgbWlzc2luZyBuYW1lCiAgICBpZih0eXBlb2YgYXR0ci5uYW1lID09PSAndW5kZWZpbmVkJykgewogICAgICBpZihhdHRyLnR5cGUgJiYgYXR0ci50eXBlIGluIHBraS5vaWRzKSB7CiAgICAgICAgYXR0ci5uYW1lID0gcGtpLm9pZHNbYXR0ci50eXBlXTsKICAgICAgfSBlbHNlIGlmKGF0dHIuc2hvcnROYW1lICYmIGF0dHIuc2hvcnROYW1lIGluIF9zaG9ydE5hbWVzKSB7CiAgICAgICAgYXR0ci5uYW1lID0gcGtpLm9pZHNbX3Nob3J0TmFtZXNbYXR0ci5zaG9ydE5hbWVdXTsKICAgICAgfQogICAgfQoKICAgIC8vIHBvcHVsYXRlIG1pc3NpbmcgdHlwZSAoT0lEKQogICAgaWYodHlwZW9mIGF0dHIudHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgaWYoYXR0ci5uYW1lICYmIGF0dHIubmFtZSBpbiBwa2kub2lkcykgewogICAgICAgIGF0dHIudHlwZSA9IHBraS5vaWRzW2F0dHIubmFtZV07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdBdHRyaWJ1dGUgdHlwZSBub3Qgc3BlY2lmaWVkLicpOwogICAgICAgIGVycm9yLmF0dHJpYnV0ZSA9IGF0dHI7CiAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgIH0KICAgIH0KCiAgICAvLyBwb3B1bGF0ZSBtaXNzaW5nIHNob3J0bmFtZQogICAgaWYodHlwZW9mIGF0dHIuc2hvcnROYW1lID09PSAndW5kZWZpbmVkJykgewogICAgICBpZihhdHRyLm5hbWUgJiYgYXR0ci5uYW1lIGluIF9zaG9ydE5hbWVzKSB7CiAgICAgICAgYXR0ci5zaG9ydE5hbWUgPSBfc2hvcnROYW1lc1thdHRyLm5hbWVdOwogICAgICB9CiAgICB9CgogICAgLy8gY29udmVydCBleHRlbnNpb25zIHRvIHZhbHVlCiAgICBpZihhdHRyLnR5cGUgPT09IG9pZHMuZXh0ZW5zaW9uUmVxdWVzdCkgewogICAgICBhdHRyLnZhbHVlQ29uc3RydWN0ZWQgPSB0cnVlOwogICAgICBhdHRyLnZhbHVlVGFnQ2xhc3MgPSBhc24xLlR5cGUuU0VRVUVOQ0U7CiAgICAgIGlmKCFhdHRyLnZhbHVlICYmIGF0dHIuZXh0ZW5zaW9ucykgewogICAgICAgIGF0dHIudmFsdWUgPSBbXTsKICAgICAgICBmb3IodmFyIGVpID0gMDsgZWkgPCBhdHRyLmV4dGVuc2lvbnMubGVuZ3RoOyArK2VpKSB7CiAgICAgICAgICBhdHRyLnZhbHVlLnB1c2gocGtpLmNlcnRpZmljYXRlRXh0ZW5zaW9uVG9Bc24xKAogICAgICAgICAgICBfZmlsbE1pc3NpbmdFeHRlbnNpb25GaWVsZHMoYXR0ci5leHRlbnNpb25zW2VpXSkpKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBpZih0eXBlb2YgYXR0ci52YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdBdHRyaWJ1dGUgdmFsdWUgbm90IHNwZWNpZmllZC4nKTsKICAgICAgZXJyb3IuYXR0cmlidXRlID0gYXR0cjsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CiAgfQp9CgovKioKICogRmlsbHMgaW4gbWlzc2luZyBmaWVsZHMgaW4gY2VydGlmaWNhdGUgZXh0ZW5zaW9ucy4KICoKICogQHBhcmFtIGUgdGhlIGV4dGVuc2lvbi4KICogQHBhcmFtIFtvcHRpb25zXSB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIFtjZXJ0XSB0aGUgY2VydGlmaWNhdGUgdGhlIGV4dGVuc2lvbnMgYXJlIGZvci4KICoKICogQHJldHVybiB0aGUgZXh0ZW5zaW9uLgogKi8KZnVuY3Rpb24gX2ZpbGxNaXNzaW5nRXh0ZW5zaW9uRmllbGRzKGUsIG9wdGlvbnMpIHsKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKCiAgLy8gcG9wdWxhdGUgbWlzc2luZyBuYW1lCiAgaWYodHlwZW9mIGUubmFtZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIGlmKGUuaWQgJiYgZS5pZCBpbiBwa2kub2lkcykgewogICAgICBlLm5hbWUgPSBwa2kub2lkc1tlLmlkXTsKICAgIH0KICB9CgogIC8vIHBvcHVsYXRlIG1pc3NpbmcgaWQKICBpZih0eXBlb2YgZS5pZCA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIGlmKGUubmFtZSAmJiBlLm5hbWUgaW4gcGtpLm9pZHMpIHsKICAgICAgZS5pZCA9IHBraS5vaWRzW2UubmFtZV07CiAgICB9IGVsc2UgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0V4dGVuc2lvbiBJRCBub3Qgc3BlY2lmaWVkLicpOwogICAgICBlcnJvci5leHRlbnNpb24gPSBlOwogICAgICB0aHJvdyBlcnJvcjsKICAgIH0KICB9CgogIGlmKHR5cGVvZiBlLnZhbHVlICE9PSAndW5kZWZpbmVkJykgewogICAgcmV0dXJuIGU7CiAgfQoKICAvLyBoYW5kbGUgbWlzc2luZyB2YWx1ZToKCiAgLy8gdmFsdWUgaXMgYSBCSVQgU1RSSU5HCiAgaWYoZS5uYW1lID09PSAna2V5VXNhZ2UnKSB7CiAgICAvLyBidWlsZCBmbGFncwogICAgdmFyIHVudXNlZCA9IDA7CiAgICB2YXIgYjIgPSAweDAwOwogICAgdmFyIGIzID0gMHgwMDsKICAgIGlmKGUuZGlnaXRhbFNpZ25hdHVyZSkgewogICAgICBiMiB8PSAweDgwOwogICAgICB1bnVzZWQgPSA3OwogICAgfQogICAgaWYoZS5ub25SZXB1ZGlhdGlvbikgewogICAgICBiMiB8PSAweDQwOwogICAgICB1bnVzZWQgPSA2OwogICAgfQogICAgaWYoZS5rZXlFbmNpcGhlcm1lbnQpIHsKICAgICAgYjIgfD0gMHgyMDsKICAgICAgdW51c2VkID0gNTsKICAgIH0KICAgIGlmKGUuZGF0YUVuY2lwaGVybWVudCkgewogICAgICBiMiB8PSAweDEwOwogICAgICB1bnVzZWQgPSA0OwogICAgfQogICAgaWYoZS5rZXlBZ3JlZW1lbnQpIHsKICAgICAgYjIgfD0gMHgwODsKICAgICAgdW51c2VkID0gMzsKICAgIH0KICAgIGlmKGUua2V5Q2VydFNpZ24pIHsKICAgICAgYjIgfD0gMHgwNDsKICAgICAgdW51c2VkID0gMjsKICAgIH0KICAgIGlmKGUuY1JMU2lnbikgewogICAgICBiMiB8PSAweDAyOwogICAgICB1bnVzZWQgPSAxOwogICAgfQogICAgaWYoZS5lbmNpcGhlck9ubHkpIHsKICAgICAgYjIgfD0gMHgwMTsKICAgICAgdW51c2VkID0gMDsKICAgIH0KICAgIGlmKGUuZGVjaXBoZXJPbmx5KSB7CiAgICAgIGIzIHw9IDB4ODA7CiAgICAgIHVudXNlZCA9IDc7CiAgICB9CgogICAgLy8gY3JlYXRlIGJpdCBzdHJpbmcKICAgIHZhciB2YWx1ZSA9IFN0cmluZy5mcm9tQ2hhckNvZGUodW51c2VkKTsKICAgIGlmKGIzICE9PSAwKSB7CiAgICAgIHZhbHVlICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYjIpICsgU3RyaW5nLmZyb21DaGFyQ29kZShiMyk7CiAgICB9IGVsc2UgaWYoYjIgIT09IDApIHsKICAgICAgdmFsdWUgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShiMik7CiAgICB9CiAgICBlLnZhbHVlID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuQklUU1RSSU5HLCBmYWxzZSwgdmFsdWUpOwogIH0gZWxzZSBpZihlLm5hbWUgPT09ICdiYXNpY0NvbnN0cmFpbnRzJykgewogICAgLy8gYmFzaWNDb25zdHJhaW50cyBpcyBhIFNFUVVFTkNFCiAgICBlLnZhbHVlID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFtdKTsKICAgIC8vIGNBIEJPT0xFQU4gZmxhZyBkZWZhdWx0cyB0byBmYWxzZQogICAgaWYoZS5jQSkgewogICAgICBlLnZhbHVlLnZhbHVlLnB1c2goYXNuMS5jcmVhdGUoCiAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CT09MRUFOLCBmYWxzZSwKICAgICAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkYpKSk7CiAgICB9CiAgICBpZigncGF0aExlbkNvbnN0cmFpbnQnIGluIGUpIHsKICAgICAgZS52YWx1ZS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIoZS5wYXRoTGVuQ29uc3RyYWludCkuZ2V0Qnl0ZXMoKSkpOwogICAgfQogIH0gZWxzZSBpZihlLm5hbWUgPT09ICdleHRLZXlVc2FnZScpIHsKICAgIC8vIGV4dEtleVVzYWdlIGlzIGEgU0VRVUVOQ0Ugb2YgT0lEcwogICAgZS52YWx1ZSA9IGFzbjEuY3JlYXRlKAogICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbXSk7CiAgICB2YXIgc2VxID0gZS52YWx1ZS52YWx1ZTsKICAgIGZvcih2YXIga2V5IGluIGUpIHsKICAgICAgaWYoZVtrZXldICE9PSB0cnVlKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgLy8ga2V5IGlzIG5hbWUgaW4gT0lEIG1hcAogICAgICBpZihrZXkgaW4gb2lkcykgewogICAgICAgIHNlcS5wdXNoKGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELAogICAgICAgICAgZmFsc2UsIGFzbjEub2lkVG9EZXIob2lkc1trZXldKS5nZXRCeXRlcygpKSk7CiAgICAgIH0gZWxzZSBpZihrZXkuaW5kZXhPZignLicpICE9PSAtMSkgewogICAgICAgIC8vIGFzc3VtZSBrZXkgaXMgYW4gT0lECiAgICAgICAgc2VxLnB1c2goYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsCiAgICAgICAgICBmYWxzZSwgYXNuMS5vaWRUb0RlcihrZXkpLmdldEJ5dGVzKCkpKTsKICAgICAgfQogICAgfQogIH0gZWxzZSBpZihlLm5hbWUgPT09ICduc0NlcnRUeXBlJykgewogICAgLy8gbnNDZXJ0VHlwZSBpcyBhIEJJVCBTVFJJTkcKICAgIC8vIGJ1aWxkIGZsYWdzCiAgICB2YXIgdW51c2VkID0gMDsKICAgIHZhciBiMiA9IDB4MDA7CgogICAgaWYoZS5jbGllbnQpIHsKICAgICAgYjIgfD0gMHg4MDsKICAgICAgdW51c2VkID0gNzsKICAgIH0KICAgIGlmKGUuc2VydmVyKSB7CiAgICAgIGIyIHw9IDB4NDA7CiAgICAgIHVudXNlZCA9IDY7CiAgICB9CiAgICBpZihlLmVtYWlsKSB7CiAgICAgIGIyIHw9IDB4MjA7CiAgICAgIHVudXNlZCA9IDU7CiAgICB9CiAgICBpZihlLm9ianNpZ24pIHsKICAgICAgYjIgfD0gMHgxMDsKICAgICAgdW51c2VkID0gNDsKICAgIH0KICAgIGlmKGUucmVzZXJ2ZWQpIHsKICAgICAgYjIgfD0gMHgwODsKICAgICAgdW51c2VkID0gMzsKICAgIH0KICAgIGlmKGUuc3NsQ0EpIHsKICAgICAgYjIgfD0gMHgwNDsKICAgICAgdW51c2VkID0gMjsKICAgIH0KICAgIGlmKGUuZW1haWxDQSkgewogICAgICBiMiB8PSAweDAyOwogICAgICB1bnVzZWQgPSAxOwogICAgfQogICAgaWYoZS5vYmpDQSkgewogICAgICBiMiB8PSAweDAxOwogICAgICB1bnVzZWQgPSAwOwogICAgfQoKICAgIC8vIGNyZWF0ZSBiaXQgc3RyaW5nCiAgICB2YXIgdmFsdWUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHVudXNlZCk7CiAgICBpZihiMiAhPT0gMCkgewogICAgICB2YWx1ZSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGIyKTsKICAgIH0KICAgIGUudmFsdWUgPSBhc24xLmNyZWF0ZSgKICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CSVRTVFJJTkcsIGZhbHNlLCB2YWx1ZSk7CiAgfSBlbHNlIGlmKGUubmFtZSA9PT0gJ3N1YmplY3RBbHROYW1lJyB8fCBlLm5hbWUgPT09ICdpc3N1ZXJBbHROYW1lJykgewogICAgLy8gU1lOVEFYIFNFUVVFTkNFCiAgICBlLnZhbHVlID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgW10pOwoKICAgIHZhciBhbHROYW1lOwogICAgZm9yKHZhciBuID0gMDsgbiA8IGUuYWx0TmFtZXMubGVuZ3RoOyArK24pIHsKICAgICAgYWx0TmFtZSA9IGUuYWx0TmFtZXNbbl07CiAgICAgIHZhciB2YWx1ZSA9IGFsdE5hbWUudmFsdWU7CiAgICAgIC8vIGhhbmRsZSBJUAogICAgICBpZihhbHROYW1lLnR5cGUgPT09IDcgJiYgYWx0TmFtZS5pcCkgewogICAgICAgIHZhbHVlID0gZm9yZ2UudXRpbC5ieXRlc0Zyb21JUChhbHROYW1lLmlwKTsKICAgICAgICBpZih2YWx1ZSA9PT0gbnVsbCkgewogICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKAogICAgICAgICAgICAnRXh0ZW5zaW9uICJpcCIgdmFsdWUgaXMgbm90IGEgdmFsaWQgSVB2NCBvciBJUHY2IGFkZHJlc3MuJyk7CiAgICAgICAgICBlcnJvci5leHRlbnNpb24gPSBlOwogICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYoYWx0TmFtZS50eXBlID09PSA4KSB7CiAgICAgICAgLy8gaGFuZGxlIE9JRAogICAgICAgIGlmKGFsdE5hbWUub2lkKSB7CiAgICAgICAgICB2YWx1ZSA9IGFzbjEub2lkVG9EZXIoYXNuMS5vaWRUb0RlcihhbHROYW1lLm9pZCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBkZXByZWNhdGVkIC4uLiBjb252ZXJ0IHZhbHVlIHRvIE9JRAogICAgICAgICAgdmFsdWUgPSBhc24xLm9pZFRvRGVyKHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZS52YWx1ZS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgICAgIGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgYWx0TmFtZS50eXBlLCBmYWxzZSwKICAgICAgICB2YWx1ZSkpOwogICAgfQogIH0gZWxzZSBpZihlLm5hbWUgPT09ICdzdWJqZWN0S2V5SWRlbnRpZmllcicgJiYgb3B0aW9ucy5jZXJ0KSB7CiAgICB2YXIgc2tpID0gb3B0aW9ucy5jZXJ0LmdlbmVyYXRlU3ViamVjdEtleUlkZW50aWZpZXIoKTsKICAgIGUuc3ViamVjdEtleUlkZW50aWZpZXIgPSBza2kudG9IZXgoKTsKICAgIC8vIE9DVEVUU1RSSU5HIHcvZGlnZXN0CiAgICBlLnZhbHVlID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLCBza2kuZ2V0Qnl0ZXMoKSk7CiAgfQoKICAvLyBlbnN1cmUgdmFsdWUgaGFzIGJlZW4gZGVmaW5lZCBieSBub3cKICBpZih0eXBlb2YgZS52YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignRXh0ZW5zaW9uIHZhbHVlIG5vdCBzcGVjaWZpZWQuJyk7CiAgICBlcnJvci5leHRlbnNpb24gPSBlOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICByZXR1cm4gZTsKfQoKLyoqCiAqIENvbnZlcnQgc2lnbmF0dXJlIHBhcmFtZXRlcnMgb2JqZWN0IHRvIEFTTi4xCiAqCiAqIEBwYXJhbSB7U3RyaW5nfSBvaWQgU2lnbmF0dXJlIGFsZ29yaXRobSBPSUQKICogQHBhcmFtIHBhcmFtcyBUaGUgc2lnbmF0dXJlIHBhcmFtZXRycyBvYmplY3QKICogQHJldHVybiBBU04uMSBvYmplY3QgcmVwcmVzZW50aW5nIHNpZ25hdHVyZSBwYXJhbWV0ZXJzCiAqLwpmdW5jdGlvbiBfc2lnbmF0dXJlUGFyYW1ldGVyc1RvQXNuMShvaWQsIHBhcmFtcykgewogIHN3aXRjaChvaWQpIHsKICBjYXNlIG9pZHNbJ1JTQVNTQS1QU1MnXToKICAgIHZhciBwYXJ0cyA9IFtdOwoKICAgIGlmKHBhcmFtcy5oYXNoLmFsZ29yaXRobU9pZCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgIHBhcnRzLnB1c2goYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgICBhc24xLm9pZFRvRGVyKHBhcmFtcy5oYXNoLmFsZ29yaXRobU9pZCkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgICAgICBdKQogICAgICBdKSk7CiAgICB9CgogICAgaWYocGFyYW1zLm1nZi5hbGdvcml0aG1PaWQgIT09IHVuZGVmaW5lZCkgewogICAgICBwYXJ0cy5wdXNoKGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMSwgdHJ1ZSwgWwogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgICAgYXNuMS5vaWRUb0RlcihwYXJhbXMubWdmLmFsZ29yaXRobU9pZCkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgICAgICBhc24xLm9pZFRvRGVyKHBhcmFtcy5tZ2YuaGFzaC5hbGdvcml0aG1PaWQpLmdldEJ5dGVzKCkpLAogICAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgICAgICAgIF0pCiAgICAgICAgXSkKICAgICAgXSkpOwogICAgfQoKICAgIGlmKHBhcmFtcy5zYWx0TGVuZ3RoICE9PSB1bmRlZmluZWQpIHsKICAgICAgcGFydHMucHVzaChhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDIsIHRydWUsIFsKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIocGFyYW1zLnNhbHRMZW5ndGgpLmdldEJ5dGVzKCkpCiAgICAgIF0pKTsKICAgIH0KCiAgICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgcGFydHMpOwoKICBkZWZhdWx0OgogICAgcmV0dXJuIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuTlVMTCwgZmFsc2UsICcnKTsKICB9Cn0KCi8qKgogKiBDb252ZXJ0cyBhIGNlcnRpZmljYXRpb24gcmVxdWVzdCdzIGF0dHJpYnV0ZXMgdG8gYW4gQVNOLjEgc2V0IG9mCiAqIENSSUF0dHJpYnV0ZXMuCiAqCiAqIEBwYXJhbSBjc3IgY2VydGlmaWNhdGlvbiByZXF1ZXN0LgogKgogKiBAcmV0dXJuIHRoZSBBU04uMSBzZXQgb2YgQ1JJQXR0cmlidXRlcy4KICovCmZ1bmN0aW9uIF9DUklBdHRyaWJ1dGVzVG9Bc24xKGNzcikgewogIC8vIGNyZWF0ZSBhbiBlbXB0eSBjb250ZXh0LXNwZWNpZmljIGNvbnRhaW5lcgogIHZhciBydmFsID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbXSk7CgogIC8vIG5vIGF0dHJpYnV0ZXMsIHJldHVybiBlbXB0eSBjb250YWluZXIKICBpZihjc3IuYXR0cmlidXRlcy5sZW5ndGggPT09IDApIHsKICAgIHJldHVybiBydmFsOwogIH0KCiAgLy8gZWFjaCBhdHRyaWJ1dGUgaGFzIGEgc2VxdWVuY2Ugd2l0aCBhIHR5cGUgYW5kIGEgc2V0IG9mIHZhbHVlcwogIHZhciBhdHRycyA9IGNzci5hdHRyaWJ1dGVzOwogIGZvcih2YXIgaSA9IDA7IGkgPCBhdHRycy5sZW5ndGg7ICsraSkgewogICAgdmFyIGF0dHIgPSBhdHRyc1tpXTsKICAgIHZhciB2YWx1ZSA9IGF0dHIudmFsdWU7CgogICAgLy8gcmV1c2UgdGFnIGNsYXNzIGZvciBhdHRyaWJ1dGUgdmFsdWUgaWYgYXZhaWxhYmxlCiAgICB2YXIgdmFsdWVUYWdDbGFzcyA9IGFzbjEuVHlwZS5VVEY4OwogICAgaWYoJ3ZhbHVlVGFnQ2xhc3MnIGluIGF0dHIpIHsKICAgICAgdmFsdWVUYWdDbGFzcyA9IGF0dHIudmFsdWVUYWdDbGFzczsKICAgIH0KICAgIGlmKHZhbHVlVGFnQ2xhc3MgPT09IGFzbjEuVHlwZS5VVEY4KSB7CiAgICAgIHZhbHVlID0gZm9yZ2UudXRpbC5lbmNvZGVVdGY4KHZhbHVlKTsKICAgIH0KICAgIHZhciB2YWx1ZUNvbnN0cnVjdGVkID0gZmFsc2U7CiAgICBpZigndmFsdWVDb25zdHJ1Y3RlZCcgaW4gYXR0cikgewogICAgICB2YWx1ZUNvbnN0cnVjdGVkID0gYXR0ci52YWx1ZUNvbnN0cnVjdGVkOwogICAgfQogICAgLy8gRklYTUU6IGhhbmRsZSBtb3JlIGVuY29kaW5ncwoKICAgIC8vIGNyZWF0ZSBhIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUgc2V0CiAgICAvLyBlYWNoIHZhbHVlIGluIHRoZSBzZXQgaXMgYW4gQXR0cmlidXRlVHlwZUFuZFZhbHVlIGZpcnN0CiAgICAvLyBjb250YWluaW5nIHRoZSB0eXBlIChhbiBPSUQpIGFuZCBzZWNvbmQgdGhlIHZhbHVlCiAgICB2YXIgc2VxID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAvLyBBdHRyaWJ1dGVUeXBlCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICBhc24xLm9pZFRvRGVyKGF0dHIudHlwZSkuZ2V0Qnl0ZXMoKSksCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VULCB0cnVlLCBbCiAgICAgICAgLy8gQXR0cmlidXRlVmFsdWUKICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCB2YWx1ZVRhZ0NsYXNzLCB2YWx1ZUNvbnN0cnVjdGVkLCB2YWx1ZSkKICAgICAgXSkKICAgIF0pOwogICAgcnZhbC52YWx1ZS5wdXNoKHNlcSk7CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIEdldHMgdGhlIEFTTi4xIFRCU0NlcnRpZmljYXRlIHBhcnQgb2YgYW4gWC41MDl2MyBjZXJ0aWZpY2F0ZS4KICoKICogQHBhcmFtIGNlcnQgdGhlIGNlcnRpZmljYXRlLgogKgogKiBAcmV0dXJuIHRoZSBhc24xIFRCU0NlcnRpZmljYXRlLgogKi8KcGtpLmdldFRCU0NlcnRpZmljYXRlID0gZnVuY3Rpb24oY2VydCkgewogIC8vIFRCU0NlcnRpZmljYXRlCiAgdmFyIHRicyA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgIC8vIHZlcnNpb24KICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgWwogICAgICAvLyBpbnRlZ2VyCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIoY2VydC52ZXJzaW9uKS5nZXRCeXRlcygpKQogICAgXSksCiAgICAvLyBzZXJpYWxOdW1iZXIKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIGZvcmdlLnV0aWwuaGV4VG9CeXRlcyhjZXJ0LnNlcmlhbE51bWJlcikpLAogICAgLy8gc2lnbmF0dXJlCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIGFsZ29yaXRobQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0RlcihjZXJ0LnNpZ2luZm8uYWxnb3JpdGhtT2lkKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGFyYW1ldGVycwogICAgICBfc2lnbmF0dXJlUGFyYW1ldGVyc1RvQXNuMSgKICAgICAgICBjZXJ0LnNpZ2luZm8uYWxnb3JpdGhtT2lkLCBjZXJ0LnNpZ2luZm8ucGFyYW1ldGVycykKICAgIF0pLAogICAgLy8gaXNzdWVyCiAgICBfZG5Ub0FzbjEoY2VydC5pc3N1ZXIpLAogICAgLy8gdmFsaWRpdHkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgLy8gbm90QmVmb3JlCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuVVRDVElNRSwgZmFsc2UsCiAgICAgICAgYXNuMS5kYXRlVG9VdGNUaW1lKGNlcnQudmFsaWRpdHkubm90QmVmb3JlKSksCiAgICAgIC8vIG5vdEFmdGVyCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuVVRDVElNRSwgZmFsc2UsCiAgICAgICAgYXNuMS5kYXRlVG9VdGNUaW1lKGNlcnQudmFsaWRpdHkubm90QWZ0ZXIpKQogICAgXSksCiAgICAvLyBzdWJqZWN0CiAgICBfZG5Ub0FzbjEoY2VydC5zdWJqZWN0KSwKICAgIC8vIFN1YmplY3RQdWJsaWNLZXlJbmZvCiAgICBwa2kucHVibGljS2V5VG9Bc24xKGNlcnQucHVibGljS2V5KQogIF0pOwoKICBpZihjZXJ0Lmlzc3Vlci51bmlxdWVJZCkgewogICAgLy8gaXNzdWVyVW5pcXVlSUQgKG9wdGlvbmFsKQogICAgdGJzLnZhbHVlLnB1c2goCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMSwgdHJ1ZSwgWwogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuQklUU1RSSU5HLCBmYWxzZSwKICAgICAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwMCkgKwogICAgICAgICAgY2VydC5pc3N1ZXIudW5pcXVlSWQKICAgICAgICApCiAgICAgIF0pCiAgICApOwogIH0KICBpZihjZXJ0LnN1YmplY3QudW5pcXVlSWQpIHsKICAgIC8vIHN1YmplY3RVbmlxdWVJRCAob3B0aW9uYWwpCiAgICB0YnMudmFsdWUucHVzaCgKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAyLCB0cnVlLCBbCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CSVRTVFJJTkcsIGZhbHNlLAogICAgICAgICAgU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKSArCiAgICAgICAgICBjZXJ0LnN1YmplY3QudW5pcXVlSWQKICAgICAgICApCiAgICAgIF0pCiAgICApOwogIH0KCiAgaWYoY2VydC5leHRlbnNpb25zLmxlbmd0aCA+IDApIHsKICAgIC8vIGV4dGVuc2lvbnMgKG9wdGlvbmFsKQogICAgdGJzLnZhbHVlLnB1c2gocGtpLmNlcnRpZmljYXRlRXh0ZW5zaW9uc1RvQXNuMShjZXJ0LmV4dGVuc2lvbnMpKTsKICB9CgogIHJldHVybiB0YnM7Cn07CgovKioKICogR2V0cyB0aGUgQVNOLjEgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIHBhcnQgb2YgYQogKiBQS0NTIzEwIENlcnRpZmljYXRpb25SZXF1ZXN0LgogKgogKiBAcGFyYW0gY3NyIHRoZSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QuCiAqCiAqIEByZXR1cm4gdGhlIGFzbjEgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLgogKi8KcGtpLmdldENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyA9IGZ1bmN0aW9uKGNzcikgewogIC8vIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbwogIHZhciBjcmkgPSBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyB2ZXJzaW9uCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBhc24xLmludGVnZXJUb0Rlcihjc3IudmVyc2lvbikuZ2V0Qnl0ZXMoKSksCiAgICAvLyBzdWJqZWN0CiAgICBfZG5Ub0FzbjEoY3NyLnN1YmplY3QpLAogICAgLy8gU3ViamVjdFB1YmxpY0tleUluZm8KICAgIHBraS5wdWJsaWNLZXlUb0FzbjEoY3NyLnB1YmxpY0tleSksCiAgICAvLyBhdHRyaWJ1dGVzCiAgICBfQ1JJQXR0cmlidXRlc1RvQXNuMShjc3IpCiAgXSk7CgogIHJldHVybiBjcmk7Cn07CgovKioKICogQ29udmVydHMgYSBEaXN0aW5ndWlzaGVkTmFtZSAoc3ViamVjdCBvciBpc3N1ZXIpIHRvIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIGRuIHRoZSBEaXN0aW5ndWlzaGVkTmFtZS4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIERpc3Rpbmd1aXNoZWROYW1lLgogKi8KcGtpLmRpc3Rpbmd1aXNoZWROYW1lVG9Bc24xID0gZnVuY3Rpb24oZG4pIHsKICByZXR1cm4gX2RuVG9Bc24xKGRuKTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhbiBYLjUwOXYzIFJTQSBjZXJ0aWZpY2F0ZSB0byBhbiBBU04uMSBvYmplY3QuCiAqCiAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZS4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhbiBYLjUwOXYzIFJTQSBjZXJ0aWZpY2F0ZS4KICovCnBraS5jZXJ0aWZpY2F0ZVRvQXNuMSA9IGZ1bmN0aW9uKGNlcnQpIHsKICAvLyBwcmVmZXIgY2FjaGVkIFRCU0NlcnRpZmljYXRlIG92ZXIgZ2VuZXJhdGluZyBvbmUKICB2YXIgdGJzQ2VydGlmaWNhdGUgPSBjZXJ0LnRic0NlcnRpZmljYXRlIHx8IHBraS5nZXRUQlNDZXJ0aWZpY2F0ZShjZXJ0KTsKCiAgLy8gQ2VydGlmaWNhdGUKICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gVEJTQ2VydGlmaWNhdGUKICAgIHRic0NlcnRpZmljYXRlLAogICAgLy8gQWxnb3JpdGhtSWRlbnRpZmllciAoc2lnbmF0dXJlIGFsZ29yaXRobSkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgLy8gYWxnb3JpdGhtCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICBhc24xLm9pZFRvRGVyKGNlcnQuc2lnbmF0dXJlT2lkKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGFyYW1ldGVycwogICAgICBfc2lnbmF0dXJlUGFyYW1ldGVyc1RvQXNuMShjZXJ0LnNpZ25hdHVyZU9pZCwgY2VydC5zaWduYXR1cmVQYXJhbWV0ZXJzKQogICAgXSksCiAgICAvLyBTaWduYXR1cmVWYWx1ZQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CSVRTVFJJTkcsIGZhbHNlLAogICAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDApICsgY2VydC5zaWduYXR1cmUpCiAgXSk7Cn07CgovKioKICogQ29udmVydHMgWC41MDl2MyBjZXJ0aWZpY2F0ZSBleHRlbnNpb25zIHRvIEFTTi4xLgogKgogKiBAcGFyYW0gZXh0cyB0aGUgZXh0ZW5zaW9ucyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBleHRlbnNpb25zIGluIEFTTi4xIGZvcm1hdC4KICovCnBraS5jZXJ0aWZpY2F0ZUV4dGVuc2lvbnNUb0FzbjEgPSBmdW5jdGlvbihleHRzKSB7CiAgLy8gY3JlYXRlIHRvcC1sZXZlbCBleHRlbnNpb24gY29udGFpbmVyCiAgdmFyIHJ2YWwgPSBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDMsIHRydWUsIFtdKTsKCiAgLy8gY3JlYXRlIGV4dGVuc2lvbiBzZXF1ZW5jZSAoc3RvcmVzIGEgc2VxdWVuY2UgZm9yIGVhY2ggZXh0ZW5zaW9uKQogIHZhciBzZXEgPSBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbXSk7CiAgcnZhbC52YWx1ZS5wdXNoKHNlcSk7CgogIGZvcih2YXIgaSA9IDA7IGkgPCBleHRzLmxlbmd0aDsgKytpKSB7CiAgICBzZXEudmFsdWUucHVzaChwa2kuY2VydGlmaWNhdGVFeHRlbnNpb25Ub0FzbjEoZXh0c1tpXSkpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ29udmVydHMgYSBzaW5nbGUgY2VydGlmaWNhdGUgZXh0ZW5zaW9uIHRvIEFTTi4xLgogKgogKiBAcGFyYW0gZXh0IHRoZSBleHRlbnNpb24gdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgZXh0ZW5zaW9uIGluIEFTTi4xIGZvcm1hdC4KICovCnBraS5jZXJ0aWZpY2F0ZUV4dGVuc2lvblRvQXNuMSA9IGZ1bmN0aW9uKGV4dCkgewogIC8vIGNyZWF0ZSBhIHNlcXVlbmNlIGZvciBlYWNoIGV4dGVuc2lvbgogIHZhciBleHRzZXEgPSBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbXSk7CgogIC8vIGV4dG5JRCAoT0lEKQogIGV4dHNlcS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgYXNuMS5vaWRUb0RlcihleHQuaWQpLmdldEJ5dGVzKCkpKTsKCiAgLy8gY3JpdGljYWwgZGVmYXVsdHMgdG8gZmFsc2UKICBpZihleHQuY3JpdGljYWwpIHsKICAgIC8vIGNyaXRpY2FsIEJPT0xFQU4gREVGQVVMVCBGQUxTRQogICAgZXh0c2VxLnZhbHVlLnB1c2goYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuQk9PTEVBTiwgZmFsc2UsCiAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoMHhGRikpKTsKICB9CgogIHZhciB2YWx1ZSA9IGV4dC52YWx1ZTsKICBpZih0eXBlb2YgZXh0LnZhbHVlICE9PSAnc3RyaW5nJykgewogICAgLy8gdmFsdWUgaXMgYXNuLjEKICAgIHZhbHVlID0gYXNuMS50b0Rlcih2YWx1ZSkuZ2V0Qnl0ZXMoKTsKICB9CgogIC8vIGV4dG5WYWx1ZSAoT0NURVQgU1RSSU5HKQogIGV4dHNlcS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIHZhbHVlKSk7CgogIHJldHVybiBleHRzZXE7Cn07CgovKioKICogQ29udmVydHMgYSBQS0NTIzEwIGNlcnRpZmljYXRpb24gcmVxdWVzdCB0byBhbiBBU04uMSBvYmplY3QuCiAqCiAqIEBwYXJhbSBjc3IgdGhlIGNlcnRpZmljYXRpb24gcmVxdWVzdC4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIGNlcnRpZmljYXRpb24gcmVxdWVzdC4KICovCnBraS5jZXJ0aWZpY2F0aW9uUmVxdWVzdFRvQXNuMSA9IGZ1bmN0aW9uKGNzcikgewogIC8vIHByZWZlciBjYWNoZWQgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIG92ZXIgZ2VuZXJhdGluZyBvbmUKICB2YXIgY3JpID0gY3NyLmNlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyB8fAogICAgcGtpLmdldENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyhjc3IpOwoKICAvLyBDZXJ0aWZpY2F0ZQogIHJldHVybiBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8KICAgIGNyaSwKICAgIC8vIEFsZ29yaXRobUlkZW50aWZpZXIgKHNpZ25hdHVyZSBhbGdvcml0aG0pCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIGFsZ29yaXRobQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0Rlcihjc3Iuc2lnbmF0dXJlT2lkKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGFyYW1ldGVycwogICAgICBfc2lnbmF0dXJlUGFyYW1ldGVyc1RvQXNuMShjc3Iuc2lnbmF0dXJlT2lkLCBjc3Iuc2lnbmF0dXJlUGFyYW1ldGVycykKICAgIF0pLAogICAgLy8gc2lnbmF0dXJlCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLkJJVFNUUklORywgZmFsc2UsCiAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwMCkgKyBjc3Iuc2lnbmF0dXJlKQogIF0pOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBDQSBzdG9yZS4KICoKICogQHBhcmFtIGNlcnRzIGFuIG9wdGlvbmFsIGFycmF5IG9mIGNlcnRpZmljYXRlIG9iamVjdHMgb3IgUEVNLWZvcm1hdHRlZAogKiAgICAgICAgICBjZXJ0aWZpY2F0ZSBzdHJpbmdzIHRvIGFkZCB0byB0aGUgQ0Egc3RvcmUuCiAqCiAqIEByZXR1cm4gdGhlIENBIHN0b3JlLgogKi8KcGtpLmNyZWF0ZUNhU3RvcmUgPSBmdW5jdGlvbihjZXJ0cykgewogIC8vIGNyZWF0ZSBDQSBzdG9yZQogIHZhciBjYVN0b3JlID0gewogICAgLy8gc3RvcmVkIGNlcnRpZmljYXRlcwogICAgY2VydHM6IHt9CiAgfTsKCiAgLyoqCiAgICogR2V0cyB0aGUgY2VydGlmaWNhdGUgdGhhdCBpc3N1ZWQgdGhlIHBhc3NlZCBjZXJ0aWZpY2F0ZSBvciBpdHMKICAgKiAncGFyZW50Jy4KICAgKgogICAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZSB0byBnZXQgdGhlIHBhcmVudCBmb3IuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBwYXJlbnQgY2VydGlmaWNhdGUgb3IgbnVsbCBpZiBub25lIHdhcyBmb3VuZC4KICAgKi8KICBjYVN0b3JlLmdldElzc3VlciA9IGZ1bmN0aW9uKGNlcnQpIHsKICAgIHZhciBydmFsID0gZ2V0QnlTdWJqZWN0KGNlcnQuaXNzdWVyKTsKCiAgICAvLyBzZWUgaWYgdGhlcmUgYXJlIG11bHRpcGxlIG1hdGNoZXMKICAgIC8qaWYoZm9yZ2UudXRpbC5pc0FycmF5KHJ2YWwpKSB7CiAgICAgIC8vIFRPRE86IHJlc29sdmUgbXVsdGlwbGUgbWF0Y2hlcyBieSBjaGVja2luZwogICAgICAvLyBhdXRob3JpdHlLZXkvc3ViamVjdEtleS9pc3N1ZXJVbmlxdWVJRC9vdGhlciBpZGVudGlmaWVycywgZXRjLgogICAgICAvLyBGSVhNRTogb3IgYWx0ZXJuYXRpdmVseSBkbyBhdXRob3JpdHkga2V5IG1hcHBpbmcKICAgICAgLy8gaWYgcG9zc2libGUgKFguNTA5djEgY2VydHMgY2FuJ3Qgd29yaz8pCiAgICAgIHRocm93IG5ldyBFcnJvcignUmVzb2x2aW5nIG11bHRpcGxlIGlzc3VlciBtYXRjaGVzIG5vdCBpbXBsZW1lbnRlZCB5ZXQuJyk7CiAgICB9Ki8KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAvKioKICAgKiBBZGRzIGEgdHJ1c3RlZCBjZXJ0aWZpY2F0ZSB0byB0aGUgc3RvcmUuCiAgICoKICAgKiBAcGFyYW0gY2VydCB0aGUgY2VydGlmaWNhdGUgdG8gYWRkIGFzIGEgdHJ1c3RlZCBjZXJ0aWZpY2F0ZSAoZWl0aGVyIGEKICAgKiAgICAgICAgICBwa2kuY2VydGlmaWNhdGUgb2JqZWN0IG9yIGEgUEVNLWZvcm1hdHRlZCBjZXJ0aWZpY2F0ZSkuCiAgICovCiAgY2FTdG9yZS5hZGRDZXJ0aWZpY2F0ZSA9IGZ1bmN0aW9uKGNlcnQpIHsKICAgIC8vIGNvbnZlcnQgZnJvbSBwZW0gaWYgbmVjZXNzYXJ5CiAgICBpZih0eXBlb2YgY2VydCA9PT0gJ3N0cmluZycpIHsKICAgICAgY2VydCA9IGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUZyb21QZW0oY2VydCk7CiAgICB9CgogICAgLy8gcHJvZHVjZSBzdWJqZWN0IGhhc2ggaWYgaXQgZG9lc24ndCBleGlzdAogICAgaWYoIWNlcnQuc3ViamVjdC5oYXNoKSB7CiAgICAgIHZhciBtZCA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICAgIGNlcnQuc3ViamVjdC5hdHRyaWJ1dGVzID0gIHBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheSgKICAgICAgICBfZG5Ub0FzbjEoY2VydC5zdWJqZWN0KSwgbWQpOwogICAgICBjZXJ0LnN1YmplY3QuaGFzaCA9IG1kLmRpZ2VzdCgpLnRvSGV4KCk7CiAgICB9CgogICAgaWYoY2VydC5zdWJqZWN0Lmhhc2ggaW4gY2FTdG9yZS5jZXJ0cykgewogICAgICAvLyBzdWJqZWN0IGhhc2ggYWxyZWFkeSBleGlzdHMsIGFwcGVuZCB0byBhcnJheQogICAgICB2YXIgdG1wID0gY2FTdG9yZS5jZXJ0c1tjZXJ0LnN1YmplY3QuaGFzaF07CiAgICAgIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkodG1wKSkgewogICAgICAgIHRtcCA9IFt0bXBdOwogICAgICB9CiAgICAgIHRtcC5wdXNoKGNlcnQpOwogICAgfSBlbHNlIHsKICAgICAgY2FTdG9yZS5jZXJ0c1tjZXJ0LnN1YmplY3QuaGFzaF0gPSBjZXJ0OwogICAgfQogIH07CgogIC8qKgogICAqIENoZWNrcyB0byBzZWUgaWYgdGhlIGdpdmVuIGNlcnRpZmljYXRlIGlzIGluIHRoZSBzdG9yZS4KICAgKgogICAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZSB0byBjaGVjay4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2VydGlmaWNhdGUgaXMgaW4gdGhlIHN0b3JlLCBmYWxzZSBpZiBub3QuCiAgICovCiAgY2FTdG9yZS5oYXNDZXJ0aWZpY2F0ZSA9IGZ1bmN0aW9uKGNlcnQpIHsKICAgIHZhciBtYXRjaCA9IGdldEJ5U3ViamVjdChjZXJ0LnN1YmplY3QpOwogICAgaWYoIW1hdGNoKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkobWF0Y2gpKSB7CiAgICAgIG1hdGNoID0gW21hdGNoXTsKICAgIH0KICAgIC8vIGNvbXBhcmUgREVSLWVuY29kaW5nIG9mIGNlcnRpZmljYXRlcwogICAgdmFyIGRlcjEgPSBhc24xLnRvRGVyKHBraS5jZXJ0aWZpY2F0ZVRvQXNuMShjZXJ0KSkuZ2V0Qnl0ZXMoKTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtYXRjaC5sZW5ndGg7ICsraSkgewogICAgICB2YXIgZGVyMiA9IGFzbjEudG9EZXIocGtpLmNlcnRpZmljYXRlVG9Bc24xKG1hdGNoW2ldKSkuZ2V0Qnl0ZXMoKTsKICAgICAgaWYoZGVyMSA9PT0gZGVyMikgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfTsKCiAgZnVuY3Rpb24gZ2V0QnlTdWJqZWN0KHN1YmplY3QpIHsKICAgIC8vIHByb2R1Y2Ugc3ViamVjdCBoYXNoIGlmIGl0IGRvZXNuJ3QgZXhpc3QKICAgIGlmKCFzdWJqZWN0Lmhhc2gpIHsKICAgICAgdmFyIG1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICAgICAgc3ViamVjdC5hdHRyaWJ1dGVzID0gIHBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheShfZG5Ub0FzbjEoc3ViamVjdCksIG1kKTsKICAgICAgc3ViamVjdC5oYXNoID0gbWQuZGlnZXN0KCkudG9IZXgoKTsKICAgIH0KICAgIHJldHVybiBjYVN0b3JlLmNlcnRzW3N1YmplY3QuaGFzaF0gfHwgbnVsbDsKICB9CgogIC8vIGF1dG8tYWRkIHBhc3NlZCBpbiBjZXJ0cwogIGlmKGNlcnRzKSB7CiAgICAvLyBwYXJzZSBQRU0tZm9ybWF0dGVkIGNlcnRpZmljYXRlcyBhcyBuZWNlc3NhcnkKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBjZXJ0cy5sZW5ndGg7ICsraSkgewogICAgICB2YXIgY2VydCA9IGNlcnRzW2ldOwogICAgICBjYVN0b3JlLmFkZENlcnRpZmljYXRlKGNlcnQpOwogICAgfQogIH0KCiAgcmV0dXJuIGNhU3RvcmU7Cn07CgovKioKICogQ2VydGlmaWNhdGUgdmVyaWZpY2F0aW9uIGVycm9ycywgYmFzZWQgb24gVExTLgogKi8KcGtpLmNlcnRpZmljYXRlRXJyb3IgPSB7CiAgYmFkX2NlcnRpZmljYXRlOiAnZm9yZ2UucGtpLkJhZENlcnRpZmljYXRlJywKICB1bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZTogJ2ZvcmdlLnBraS5VbnN1cHBvcnRlZENlcnRpZmljYXRlJywKICBjZXJ0aWZpY2F0ZV9yZXZva2VkOiAnZm9yZ2UucGtpLkNlcnRpZmljYXRlUmV2b2tlZCcsCiAgY2VydGlmaWNhdGVfZXhwaXJlZDogJ2ZvcmdlLnBraS5DZXJ0aWZpY2F0ZUV4cGlyZWQnLAogIGNlcnRpZmljYXRlX3Vua25vd246ICdmb3JnZS5wa2kuQ2VydGlmaWNhdGVVbmtub3duJywKICB1bmtub3duX2NhOiAnZm9yZ2UucGtpLlVua25vd25DZXJ0aWZpY2F0ZUF1dGhvcml0eScKfTsKCi8qKgogKiBWZXJpZmllcyBhIGNlcnRpZmljYXRlIGNoYWluIGFnYWluc3QgdGhlIGdpdmVuIENlcnRpZmljYXRlIEF1dGhvcml0eSBzdG9yZQogKiB3aXRoIGFuIG9wdGlvbmFsIGN1c3RvbSB2ZXJpZnkgY2FsbGJhY2suCiAqCiAqIEBwYXJhbSBjYVN0b3JlIGEgY2VydGlmaWNhdGUgc3RvcmUgdG8gdmVyaWZ5IGFnYWluc3QuCiAqIEBwYXJhbSBjaGFpbiB0aGUgY2VydGlmaWNhdGUgY2hhaW4gdG8gdmVyaWZ5LCB3aXRoIHRoZSByb290IG9yIGhpZ2hlc3QKICogICAgICAgICAgYXV0aG9yaXR5IGF0IHRoZSBlbmQgKGFuIGFycmF5IG9mIGNlcnRpZmljYXRlcykuCiAqIEBwYXJhbSB2ZXJpZnkgY2FsbGVkIGZvciBldmVyeSBjZXJ0aWZpY2F0ZSBpbiB0aGUgY2hhaW4uCiAqCiAqIFRoZSB2ZXJpZnkgY2FsbGJhY2sgaGFzIHRoZSBmb2xsb3dpbmcgc2lnbmF0dXJlOgogKgogKiB2ZXJpZmllZCAtIFNldCB0byB0cnVlIGlmIGNlcnRpZmljYXRlIHdhcyB2ZXJpZmllZCwgb3RoZXJ3aXNlIHRoZQogKiAgIHBraS5jZXJ0aWZpY2F0ZUVycm9yIGZvciB3aHkgdGhlIGNlcnRpZmljYXRlIGZhaWxlZC4KICogZGVwdGggLSBUaGUgY3VycmVudCBpbmRleCBpbiB0aGUgY2hhaW4sIHdoZXJlIDAgaXMgdGhlIGVuZCBwb2ludCdzIGNlcnQuCiAqIGNlcnRzIC0gVGhlIGNlcnRpZmljYXRlIGNoYWluLCAqTk9URSogYW4gZW1wdHkgY2hhaW4gaW5kaWNhdGVzIGFuIGFub255bW91cwogKiAgIGVuZCBwb2ludC4KICoKICogVGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzIGFuZCBvbiBmYWlsdXJlIGVpdGhlciB0aGUgYXBwcm9wcmlhdGUKICogcGtpLmNlcnRpZmljYXRlRXJyb3Igb3IgYW4gb2JqZWN0IHdpdGggJ2Vycm9yJyBzZXQgdG8gdGhlIGFwcHJvcHJpYXRlCiAqIHBraS5jZXJ0aWZpY2F0ZUVycm9yIGFuZCAnbWVzc2FnZScgc2V0IHRvIGEgY3VzdG9tIGVycm9yIG1lc3NhZ2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsLCBlcnJvciB0aHJvd24gaWYgbm90LgogKi8KcGtpLnZlcmlmeUNlcnRpZmljYXRlQ2hhaW4gPSBmdW5jdGlvbihjYVN0b3JlLCBjaGFpbiwgdmVyaWZ5KSB7CiAgLyogRnJvbTogUkZDMzI4MCAtIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUgQ2VydGlmaWNhdGUKICAgIFNlY3Rpb24gNjogQ2VydGlmaWNhdGlvbiBQYXRoIFZhbGlkYXRpb24KICAgIFNlZSBpbmxpbmUgcGFyZW50aGV0aWNhbHMgcmVsYXRlZCB0byB0aGlzIHBhcnRpY3VsYXIgaW1wbGVtZW50YXRpb24uCgogICAgVGhlIHByaW1hcnkgZ29hbCBvZiBwYXRoIHZhbGlkYXRpb24gaXMgdG8gdmVyaWZ5IHRoZSBiaW5kaW5nIGJldHdlZW4KICAgIGEgc3ViamVjdCBkaXN0aW5ndWlzaGVkIG5hbWUgb3IgYSBzdWJqZWN0IGFsdGVybmF0aXZlIG5hbWUgYW5kIHN1YmplY3QKICAgIHB1YmxpYyBrZXksIGFzIHJlcHJlc2VudGVkIGluIHRoZSBlbmQgZW50aXR5IGNlcnRpZmljYXRlLCBiYXNlZCBvbiB0aGUKICAgIHB1YmxpYyBrZXkgb2YgdGhlIHRydXN0IGFuY2hvci4gVGhpcyByZXF1aXJlcyBvYnRhaW5pbmcgYSBzZXF1ZW5jZSBvZgogICAgY2VydGlmaWNhdGVzIHRoYXQgc3VwcG9ydCB0aGF0IGJpbmRpbmcuIFRoYXQgc2VxdWVuY2Ugc2hvdWxkIGJlIHByb3ZpZGVkCiAgICBpbiB0aGUgcGFzc2VkICdjaGFpbicuIFRoZSB0cnVzdCBhbmNob3Igc2hvdWxkIGJlIGluIHRoZSBnaXZlbiBDQQogICAgc3RvcmUuIFRoZSAnZW5kIGVudGl0eScgY2VydGlmaWNhdGUgaXMgdGhlIGNlcnRpZmljYXRlIHByb3ZpZGVkIGJ5IHRoZQogICAgZW5kIHBvaW50ICh0eXBpY2FsbHkgYSBzZXJ2ZXIpIGFuZCBpcyB0aGUgZmlyc3QgaW4gdGhlIGNoYWluLgoKICAgIFRvIG1lZXQgdGhpcyBnb2FsLCB0aGUgcGF0aCB2YWxpZGF0aW9uIHByb2Nlc3MgdmVyaWZpZXMsIGFtb25nIG90aGVyCiAgICB0aGluZ3MsIHRoYXQgYSBwcm9zcGVjdGl2ZSBjZXJ0aWZpY2F0aW9uIHBhdGggKGEgc2VxdWVuY2Ugb2YgbgogICAgY2VydGlmaWNhdGVzIG9yIGEgJ2NoYWluJykgc2F0aXNmaWVzIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCiAgICAoYSkgZm9yIGFsbCB4IGluIHsxLCAuLi4sIG4tMX0sIHRoZSBzdWJqZWN0IG9mIGNlcnRpZmljYXRlIHggaXMKICAgICAgICAgIHRoZSBpc3N1ZXIgb2YgY2VydGlmaWNhdGUgeCsxOwoKICAgIChiKSBjZXJ0aWZpY2F0ZSAxIGlzIGlzc3VlZCBieSB0aGUgdHJ1c3QgYW5jaG9yOwoKICAgIChjKSBjZXJ0aWZpY2F0ZSBuIGlzIHRoZSBjZXJ0aWZpY2F0ZSB0byBiZSB2YWxpZGF0ZWQ7IGFuZAoKICAgIChkKSBmb3IgYWxsIHggaW4gezEsIC4uLiwgbn0sIHRoZSBjZXJ0aWZpY2F0ZSB3YXMgdmFsaWQgYXQgdGhlCiAgICAgICAgICB0aW1lIGluIHF1ZXN0aW9uLgoKICAgIE5vdGUgdGhhdCBoZXJlICduJyBpcyBpbmRleCAwIGluIHRoZSBjaGFpbiBhbmQgMSBpcyB0aGUgbGFzdCBjZXJ0aWZpY2F0ZQogICAgaW4gdGhlIGNoYWluIGFuZCBpdCBtdXN0IGJlIHNpZ25lZCBieSBhIGNlcnRpZmljYXRlIGluIHRoZSBjb25uZWN0aW9uJ3MKICAgIENBIHN0b3JlLgoKICAgIFRoZSBwYXRoIHZhbGlkYXRpb24gcHJvY2VzcyBhbHNvIGRldGVybWluZXMgdGhlIHNldCBvZiBjZXJ0aWZpY2F0ZQogICAgcG9saWNpZXMgdGhhdCBhcmUgdmFsaWQgZm9yIHRoaXMgcGF0aCwgYmFzZWQgb24gdGhlIGNlcnRpZmljYXRlIHBvbGljaWVzCiAgICBleHRlbnNpb24sIHBvbGljeSBtYXBwaW5nIGV4dGVuc2lvbiwgcG9saWN5IGNvbnN0cmFpbnRzIGV4dGVuc2lvbiwgYW5kCiAgICBpbmhpYml0IGFueS1wb2xpY3kgZXh0ZW5zaW9uLgoKICAgIE5vdGU6IFBvbGljeSBtYXBwaW5nIGV4dGVuc2lvbiBub3Qgc3VwcG9ydGVkIChOb3QgUmVxdWlyZWQpLgoKICAgIE5vdGU6IElmIHRoZSBjZXJ0aWZpY2F0ZSBoYXMgYW4gdW5zdXBwb3J0ZWQgY3JpdGljYWwgZXh0ZW5zaW9uLCB0aGVuIGl0CiAgICBtdXN0IGJlIHJlamVjdGVkLgoKICAgIE5vdGU6IEEgY2VydGlmaWNhdGUgaXMgc2VsZi1pc3N1ZWQgaWYgdGhlIEROcyB0aGF0IGFwcGVhciBpbiB0aGUgc3ViamVjdAogICAgYW5kIGlzc3VlciBmaWVsZHMgYXJlIGlkZW50aWNhbCBhbmQgYXJlIG5vdCBlbXB0eS4KCiAgICBUaGUgcGF0aCB2YWxpZGF0aW9uIGFsZ29yaXRobSBhc3N1bWVzIHRoZSBmb2xsb3dpbmcgc2V2ZW4gaW5wdXRzIGFyZQogICAgcHJvdmlkZWQgdG8gdGhlIHBhdGggcHJvY2Vzc2luZyBsb2dpYy4gV2hhdCB0aGlzIHNwZWNpZmljIGltcGxlbWVudGF0aW9uCiAgICB3aWxsIHVzZSBpcyBwcm92aWRlZCBwYXJlbnRoZXRpY2FsbHk6CgogICAgKGEpIGEgcHJvc3BlY3RpdmUgY2VydGlmaWNhdGlvbiBwYXRoIG9mIGxlbmd0aCBuICh0aGUgJ2NoYWluJykKICAgIChiKSB0aGUgY3VycmVudCBkYXRlL3RpbWU6ICgnbm93JykuCiAgICAoYykgdXNlci1pbml0aWFsLXBvbGljeS1zZXQ6IEEgc2V0IG9mIGNlcnRpZmljYXRlIHBvbGljeSBpZGVudGlmaWVycwogICAgICAgICAgbmFtaW5nIHRoZSBwb2xpY2llcyB0aGF0IGFyZSBhY2NlcHRhYmxlIHRvIHRoZSBjZXJ0aWZpY2F0ZSB1c2VyLgogICAgICAgICAgVGhlIHVzZXItaW5pdGlhbC1wb2xpY3ktc2V0IGNvbnRhaW5zIHRoZSBzcGVjaWFsIHZhbHVlIGFueS1wb2xpY3kKICAgICAgICAgIGlmIHRoZSB1c2VyIGlzIG5vdCBjb25jZXJuZWQgYWJvdXQgY2VydGlmaWNhdGUgcG9saWN5CiAgICAgICAgICAoTm90IGltcGxlbWVudGVkLiBBbnkgcG9saWN5IGlzIGFjY2VwdGVkKS4KICAgIChkKSB0cnVzdCBhbmNob3IgaW5mb3JtYXRpb24sIGRlc2NyaWJpbmcgYSBDQSB0aGF0IHNlcnZlcyBhcyBhIHRydXN0CiAgICAgICAgICBhbmNob3IgZm9yIHRoZSBjZXJ0aWZpY2F0aW9uIHBhdGguIFRoZSB0cnVzdCBhbmNob3IgaW5mb3JtYXRpb24KICAgICAgICAgIGluY2x1ZGVzOgoKICAgICAgKDEpICB0aGUgdHJ1c3RlZCBpc3N1ZXIgbmFtZSwKICAgICAgKDIpICB0aGUgdHJ1c3RlZCBwdWJsaWMga2V5IGFsZ29yaXRobSwKICAgICAgKDMpICB0aGUgdHJ1c3RlZCBwdWJsaWMga2V5LCBhbmQKICAgICAgKDQpICBvcHRpb25hbGx5LCB0aGUgdHJ1c3RlZCBwdWJsaWMga2V5IHBhcmFtZXRlcnMgYXNzb2NpYXRlZAogICAgICAgICAgICAgd2l0aCB0aGUgcHVibGljIGtleS4KCiAgICAgIChUcnVzdCBhbmNob3JzIGFyZSBwcm92aWRlZCB2aWEgY2VydGlmaWNhdGVzIGluIHRoZSBDQSBzdG9yZSkuCgogICAgICBUaGUgdHJ1c3QgYW5jaG9yIGluZm9ybWF0aW9uIG1heSBiZSBwcm92aWRlZCB0byB0aGUgcGF0aCBwcm9jZXNzaW5nCiAgICAgIHByb2NlZHVyZSBpbiB0aGUgZm9ybSBvZiBhIHNlbGYtc2lnbmVkIGNlcnRpZmljYXRlLiBUaGUgdHJ1c3RlZCBhbmNob3IKICAgICAgaW5mb3JtYXRpb24gaXMgdHJ1c3RlZCBiZWNhdXNlIGl0IHdhcyBkZWxpdmVyZWQgdG8gdGhlIHBhdGggcHJvY2Vzc2luZwogICAgICBwcm9jZWR1cmUgYnkgc29tZSB0cnVzdHdvcnRoeSBvdXQtb2YtYmFuZCBwcm9jZWR1cmUuIElmIHRoZSB0cnVzdGVkCiAgICAgIHB1YmxpYyBrZXkgYWxnb3JpdGhtIHJlcXVpcmVzIHBhcmFtZXRlcnMsIHRoZW4gdGhlIHBhcmFtZXRlcnMgYXJlCiAgICAgIHByb3ZpZGVkIGFsb25nIHdpdGggdGhlIHRydXN0ZWQgcHVibGljIGtleSAoTm8gcGFyYW1ldGVycyB1c2VkIGluIHRoaXMKICAgICAgaW1wbGVtZW50YXRpb24pLgoKICAgIChlKSBpbml0aWFsLXBvbGljeS1tYXBwaW5nLWluaGliaXQsIHdoaWNoIGluZGljYXRlcyBpZiBwb2xpY3kgbWFwcGluZyBpcwogICAgICAgICAgYWxsb3dlZCBpbiB0aGUgY2VydGlmaWNhdGlvbiBwYXRoLgogICAgICAgICAgKE5vdCBpbXBsZW1lbnRlZCwgbm8gcG9saWN5IGNoZWNraW5nKQoKICAgIChmKSBpbml0aWFsLWV4cGxpY2l0LXBvbGljeSwgd2hpY2ggaW5kaWNhdGVzIGlmIHRoZSBwYXRoIG11c3QgYmUgdmFsaWQKICAgICAgICAgIGZvciBhdCBsZWFzdCBvbmUgb2YgdGhlIGNlcnRpZmljYXRlIHBvbGljaWVzIGluIHRoZSB1c2VyLWluaXRpYWwtCiAgICAgICAgICBwb2xpY3ktc2V0LgogICAgICAgICAgKE5vdCBpbXBsZW1lbnRlZCwgbm8gcG9saWN5IGNoZWNraW5nKQoKICAgIChnKSBpbml0aWFsLWFueS1wb2xpY3ktaW5oaWJpdCwgd2hpY2ggaW5kaWNhdGVzIHdoZXRoZXIgdGhlCiAgICAgICAgICBhbnlQb2xpY3kgT0lEIHNob3VsZCBiZSBwcm9jZXNzZWQgaWYgaXQgaXMgaW5jbHVkZWQgaW4gYQogICAgICAgICAgY2VydGlmaWNhdGUuCiAgICAgICAgICAoTm90IGltcGxlbWVudGVkLCBzbyBhbnkgcG9saWN5IGlzIHZhbGlkIHByb3ZpZGVkIHRoYXQgaXQgaXMKICAgICAgICAgIG5vdCBtYXJrZWQgYXMgY3JpdGljYWwpICovCgogIC8qIEJhc2ljIFBhdGggUHJvY2Vzc2luZzoKCiAgICBGb3IgZWFjaCBjZXJ0aWZpY2F0ZSBpbiB0aGUgJ2NoYWluJywgdGhlIGZvbGxvd2luZyBpcyBjaGVja2VkOgoKICAgIDEuIFRoZSBjZXJ0aWZpY2F0ZSB2YWxpZGl0eSBwZXJpb2QgaW5jbHVkZXMgdGhlIGN1cnJlbnQgdGltZS4KICAgIDIuIFRoZSBjZXJ0aWZpY2F0ZSB3YXMgc2lnbmVkIGJ5IGl0cyBwYXJlbnQgKHdoZXJlIHRoZSBwYXJlbnQgaXMgZWl0aGVyCiAgICAgICB0aGUgbmV4dCBpbiB0aGUgY2hhaW4gb3IgZnJvbSB0aGUgQ0Egc3RvcmUpLiBBbGxvdyBwcm9jZXNzaW5nIHRvCiAgICAgICBjb250aW51ZSB0byB0aGUgbmV4dCBzdGVwIGlmIG5vIHBhcmVudCBpcyBmb3VuZCBidXQgdGhlIGNlcnRpZmljYXRlIGlzCiAgICAgICBpbiB0aGUgQ0Egc3RvcmUuCiAgICAzLiBUT0RPOiBUaGUgY2VydGlmaWNhdGUgaGFzIG5vdCBiZWVuIHJldm9rZWQuCiAgICA0LiBUaGUgY2VydGlmaWNhdGUgaXNzdWVyIG5hbWUgbWF0Y2hlcyB0aGUgcGFyZW50J3Mgc3ViamVjdCBuYW1lLgogICAgNS4gVE9ETzogSWYgdGhlIGNlcnRpZmljYXRlIGlzIHNlbGYtaXNzdWVkIGFuZCBub3QgdGhlIGZpbmFsIGNlcnRpZmljYXRlCiAgICAgICBpbiB0aGUgY2hhaW4sIHNraXAgdGhpcyBzdGVwLCBvdGhlcndpc2UgdmVyaWZ5IHRoYXQgdGhlIHN1YmplY3QgbmFtZQogICAgICAgaXMgd2l0aGluIG9uZSBvZiB0aGUgcGVybWl0dGVkIHN1YnRyZWVzIG9mIFguNTAwIGRpc3Rpbmd1aXNoZWQgbmFtZXMKICAgICAgIGFuZCB0aGF0IGVhY2ggb2YgdGhlIGFsdGVybmF0aXZlIG5hbWVzIGluIHRoZSBzdWJqZWN0QWx0TmFtZSBleHRlbnNpb24KICAgICAgIChjcml0aWNhbCBvciBub24tY3JpdGljYWwpIGlzIHdpdGhpbiBvbmUgb2YgdGhlIHBlcm1pdHRlZCBzdWJ0cmVlcyBmb3IKICAgICAgIHRoYXQgbmFtZSB0eXBlLgogICAgNi4gVE9ETzogSWYgdGhlIGNlcnRpZmljYXRlIGlzIHNlbGYtaXNzdWVkIGFuZCBub3QgdGhlIGZpbmFsIGNlcnRpZmljYXRlCiAgICAgICBpbiB0aGUgY2hhaW4sIHNraXAgdGhpcyBzdGVwLCBvdGhlcndpc2UgdmVyaWZ5IHRoYXQgdGhlIHN1YmplY3QgbmFtZQogICAgICAgaXMgbm90IHdpdGhpbiBvbmUgb2YgdGhlIGV4Y2x1ZGVkIHN1YnRyZWVzIGZvciBYLjUwMCBkaXN0aW5ndWlzaGVkCiAgICAgICBuYW1lcyBhbmQgbm9uZSBvZiB0aGUgc3ViamVjdEFsdE5hbWUgZXh0ZW5zaW9uIG5hbWVzIGFyZSBleGNsdWRlZCBmb3IKICAgICAgIHRoYXQgbmFtZSB0eXBlLgogICAgNy4gVGhlIG90aGVyIHN0ZXBzIGluIHRoZSBhbGdvcml0aG0gZm9yIGJhc2ljIHBhdGggcHJvY2Vzc2luZyBpbnZvbHZlCiAgICAgICBoYW5kbGluZyB0aGUgcG9saWN5IGV4dGVuc2lvbiB3aGljaCBpcyBub3QgcHJlc2VudGx5IHN1cHBvcnRlZCBpbiB0aGlzCiAgICAgICBpbXBsZW1lbnRhdGlvbi4gSW5zdGVhZCwgaWYgYSBjcml0aWNhbCBwb2xpY3kgZXh0ZW5zaW9uIGlzIGZvdW5kLCB0aGUKICAgICAgIGNlcnRpZmljYXRlIGlzIHJlamVjdGVkIGFzIG5vdCBzdXBwb3J0ZWQuCiAgICA4LiBJZiB0aGUgY2VydGlmaWNhdGUgaXMgbm90IHRoZSBmaXJzdCBvciBpZiBpdHMgdGhlIG9ubHkgY2VydGlmaWNhdGUgaW4KICAgICAgIHRoZSBjaGFpbiAoaGF2aW5nIG5vIHBhcmVudCBmcm9tIHRoZSBDQSBzdG9yZSBvciBpcyBzZWxmLXNpZ25lZCkgYW5kIGl0CiAgICAgICBoYXMgYSBjcml0aWNhbCBrZXkgdXNhZ2UgZXh0ZW5zaW9uLCB2ZXJpZnkgdGhhdCB0aGUga2V5Q2VydFNpZ24gYml0IGlzCiAgICAgICBzZXQuIElmIHRoZSBrZXkgdXNhZ2UgZXh0ZW5zaW9uIGV4aXN0cywgdmVyaWZ5IHRoYXQgdGhlIGJhc2ljCiAgICAgICBjb25zdHJhaW50cyBleHRlbnNpb24gZXhpc3RzLiBJZiB0aGUgYmFzaWMgY29uc3RyYWludHMgZXh0ZW5zaW9uIGV4aXN0cywKICAgICAgIHZlcmlmeSB0aGF0IHRoZSBjQSBmbGFnIGlzIHNldC4gSWYgcGF0aExlbkNvbnN0cmFpbnQgaXMgc2V0LCBlbnN1cmUgdGhhdAogICAgICAgdGhlIG51bWJlciBvZiBjZXJ0aWZpY2F0ZXMgdGhhdCBwcmVjZWRlIGluIHRoZSBjaGFpbiAoY29tZSBlYXJsaWVyCiAgICAgICBpbiB0aGUgY2hhaW4gYXMgaW1wbGVtZW50ZWQgYmVsb3cpLCBleGNsdWRpbmcgdGhlIHZlcnkgZmlyc3QgaW4gdGhlCiAgICAgICBjaGFpbiAodHlwaWNhbGx5IHRoZSBlbmQtZW50aXR5IG9uZSksIGlzbid0IGdyZWF0ZXIgdGhhbiB0aGUKICAgICAgIHBhdGhMZW5Db25zdHJhaW50LiBUaGlzIGNvbnN0cmFpbnQgbGltaXRzIHRoZSBudW1iZXIgb2YgaW50ZXJtZWRpYXRlCiAgICAgICBDQXMgdGhhdCBtYXkgYXBwZWFyIGJlbG93IGEgQ0EgYmVmb3JlIG9ubHkgZW5kLWVudGl0eSBjZXJ0aWZpY2F0ZXMKICAgICAgIG1heSBiZSBpc3N1ZWQuICovCgogIC8vIGNvcHkgY2VydCBjaGFpbiByZWZlcmVuY2VzIHRvIGFub3RoZXIgYXJyYXkgdG8gcHJvdGVjdCBhZ2FpbnN0IGNoYW5nZXMKICAvLyBpbiB2ZXJpZnkgY2FsbGJhY2sKICBjaGFpbiA9IGNoYWluLnNsaWNlKDApOwogIHZhciBjZXJ0cyA9IGNoYWluLnNsaWNlKDApOwoKICAvLyBnZXQgY3VycmVudCBkYXRlCiAgdmFyIG5vdyA9IG5ldyBEYXRlKCk7CgogIC8vIHZlcmlmeSBlYWNoIGNlcnQgaW4gdGhlIGNoYWluIHVzaW5nIGl0cyBwYXJlbnQsIHdoZXJlIHRoZSBwYXJlbnQKICAvLyBpcyBlaXRoZXIgdGhlIG5leHQgaW4gdGhlIGNoYWluIG9yIGZyb20gdGhlIENBIHN0b3JlCiAgdmFyIGZpcnN0ID0gdHJ1ZTsKICB2YXIgZXJyb3IgPSBudWxsOwogIHZhciBkZXB0aCA9IDA7CiAgZG8gewogICAgdmFyIGNlcnQgPSBjaGFpbi5zaGlmdCgpOwogICAgdmFyIHBhcmVudCA9IG51bGw7CiAgICB2YXIgc2VsZlNpZ25lZCA9IGZhbHNlOwoKICAgIC8vIDEuIGNoZWNrIHZhbGlkIHRpbWUKICAgIGlmKG5vdyA8IGNlcnQudmFsaWRpdHkubm90QmVmb3JlIHx8IG5vdyA+IGNlcnQudmFsaWRpdHkubm90QWZ0ZXIpIHsKICAgICAgZXJyb3IgPSB7CiAgICAgICAgbWVzc2FnZTogJ0NlcnRpZmljYXRlIGlzIG5vdCB2YWxpZCB5ZXQgb3IgaGFzIGV4cGlyZWQuJywKICAgICAgICBlcnJvcjogcGtpLmNlcnRpZmljYXRlRXJyb3IuY2VydGlmaWNhdGVfZXhwaXJlZCwKICAgICAgICBub3RCZWZvcmU6IGNlcnQudmFsaWRpdHkubm90QmVmb3JlLAogICAgICAgIG5vdEFmdGVyOiBjZXJ0LnZhbGlkaXR5Lm5vdEFmdGVyLAogICAgICAgIG5vdzogbm93CiAgICAgIH07CiAgICB9CgogICAgLy8gMi4gdmVyaWZ5IHdpdGggcGFyZW50IGZyb20gY2hhaW4gb3IgQ0Egc3RvcmUKICAgIGlmKGVycm9yID09PSBudWxsKSB7CiAgICAgIHBhcmVudCA9IGNoYWluWzBdIHx8IGNhU3RvcmUuZ2V0SXNzdWVyKGNlcnQpOwogICAgICBpZihwYXJlbnQgPT09IG51bGwpIHsKICAgICAgICAvLyBjaGVjayBmb3Igc2VsZi1zaWduZWQgY2VydAogICAgICAgIGlmKGNlcnQuaXNJc3N1ZXIoY2VydCkpIHsKICAgICAgICAgIHNlbGZTaWduZWQgPSB0cnVlOwogICAgICAgICAgcGFyZW50ID0gY2VydDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmKHBhcmVudCkgewogICAgICAgIC8vIEZJWE1FOiBjdXJyZW50IENBIHN0b3JlIGltcGxlbWVudGF0aW9uIG1pZ2h0IGhhdmUgbXVsdGlwbGUKICAgICAgICAvLyBjZXJ0aWZpY2F0ZXMgd2hlcmUgdGhlIGlzc3VlciBjYW4ndCBiZSBkZXRlcm1pbmVkIGZyb20gdGhlCiAgICAgICAgLy8gY2VydGlmaWNhdGUgKGhhcHBlbnMgcmFyZWx5IHdpdGgsIGVnOiBvbGQgY2VydGlmaWNhdGVzKSBzbyBub3JtYWxpemUKICAgICAgICAvLyBieSBhbHdheXMgcHV0dGluZyBwYXJlbnRzIGludG8gYW4gYXJyYXkKICAgICAgICAvLyBUT0RPOiB0aGVyZSdzIG1heSBiZSBhbiBleHRyZW1lIGRlZ2VuZXJhdGUgY2FzZSBjdXJyZW50bHkgdW5jb3ZlcmVkCiAgICAgICAgLy8gd2hlcmUgYW4gb2xkIGludGVybWVkaWF0ZSBjZXJ0aWZpY2F0ZSBzZWVtcyB0byBoYXZlIGEgbWF0Y2hpbmcgcGFyZW50CiAgICAgICAgLy8gYnV0IG5vbmUgb2YgdGhlIHBhcmVudHMgYWN0dWFsbHkgdmVyaWZ5IC4uLiBidXQgdGhlIGludGVybWVkaWF0ZQogICAgICAgIC8vIGlzIGluIHRoZSBDQSBhbmQgaXQgc2hvdWxkIHBhc3MgdGhpcyBjaGVjazsgbmVlZHMgaW52ZXN0aWdhdGlvbgogICAgICAgIHZhciBwYXJlbnRzID0gcGFyZW50OwogICAgICAgIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkocGFyZW50cykpIHsKICAgICAgICAgIHBhcmVudHMgPSBbcGFyZW50c107CiAgICAgICAgfQoKICAgICAgICAvLyB0cnkgdG8gdmVyaWZ5IHdpdGggZWFjaCBwb3NzaWJsZSBwYXJlbnQgKHR5cGljYWxseSBvbmx5IG9uZSkKICAgICAgICB2YXIgdmVyaWZpZWQgPSBmYWxzZTsKICAgICAgICB3aGlsZSghdmVyaWZpZWQgJiYgcGFyZW50cy5sZW5ndGggPiAwKSB7CiAgICAgICAgICBwYXJlbnQgPSBwYXJlbnRzLnNoaWZ0KCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICB2ZXJpZmllZCA9IHBhcmVudC52ZXJpZnkoY2VydCk7CiAgICAgICAgICB9IGNhdGNoKGV4KSB7CiAgICAgICAgICAgIC8vIGZhaWx1cmUgdG8gdmVyaWZ5LCBkb24ndCBjYXJlIHdoeSwgdHJ5IG5leHQgb25lCiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZighdmVyaWZpZWQpIHsKICAgICAgICAgIGVycm9yID0gewogICAgICAgICAgICBtZXNzYWdlOiAnQ2VydGlmaWNhdGUgc2lnbmF0dXJlIGlzIGludmFsaWQuJywKICAgICAgICAgICAgZXJyb3I6IHBraS5jZXJ0aWZpY2F0ZUVycm9yLmJhZF9jZXJ0aWZpY2F0ZQogICAgICAgICAgfTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmKGVycm9yID09PSBudWxsICYmICghcGFyZW50IHx8IHNlbGZTaWduZWQpICYmCiAgICAgICAgIWNhU3RvcmUuaGFzQ2VydGlmaWNhdGUoY2VydCkpIHsKICAgICAgICAvLyBubyBwYXJlbnQgaXNzdWVyIGFuZCBjZXJ0aWZpY2F0ZSBpdHNlbGYgaXMgbm90IHRydXN0ZWQKICAgICAgICBlcnJvciA9IHsKICAgICAgICAgIG1lc3NhZ2U6ICdDZXJ0aWZpY2F0ZSBpcyBub3QgdHJ1c3RlZC4nLAogICAgICAgICAgZXJyb3I6IHBraS5jZXJ0aWZpY2F0ZUVycm9yLnVua25vd25fY2EKICAgICAgICB9OwogICAgICB9CiAgICB9CgogICAgLy8gVE9ETzogMy4gY2hlY2sgcmV2b2tlZAoKICAgIC8vIDQuIGNoZWNrIGZvciBtYXRjaGluZyBpc3N1ZXIvc3ViamVjdAogICAgaWYoZXJyb3IgPT09IG51bGwgJiYgcGFyZW50ICYmICFjZXJ0LmlzSXNzdWVyKHBhcmVudCkpIHsKICAgICAgLy8gcGFyZW50IGlzIG5vdCBpc3N1ZXIKICAgICAgZXJyb3IgPSB7CiAgICAgICAgbWVzc2FnZTogJ0NlcnRpZmljYXRlIGlzc3VlciBpcyBpbnZhbGlkLicsCiAgICAgICAgZXJyb3I6IHBraS5jZXJ0aWZpY2F0ZUVycm9yLmJhZF9jZXJ0aWZpY2F0ZQogICAgICB9OwogICAgfQoKICAgIC8vIDUuIFRPRE86IGNoZWNrIG5hbWVzIHdpdGggcGVybWl0dGVkIG5hbWVzIHRyZWUKCiAgICAvLyA2LiBUT0RPOiBjaGVjayBuYW1lcyBhZ2FpbnN0IGV4Y2x1ZGVkIG5hbWVzIHRyZWUKCiAgICAvLyA3LiBjaGVjayBmb3IgdW5zdXBwb3J0ZWQgY3JpdGljYWwgZXh0ZW5zaW9ucwogICAgaWYoZXJyb3IgPT09IG51bGwpIHsKICAgICAgLy8gc3VwcG9ydGVkIGV4dGVuc2lvbnMKICAgICAgdmFyIHNlID0gewogICAgICAgIGtleVVzYWdlOiB0cnVlLAogICAgICAgIGJhc2ljQ29uc3RyYWludHM6IHRydWUKICAgICAgfTsKICAgICAgZm9yKHZhciBpID0gMDsgZXJyb3IgPT09IG51bGwgJiYgaSA8IGNlcnQuZXh0ZW5zaW9ucy5sZW5ndGg7ICsraSkgewogICAgICAgIHZhciBleHQgPSBjZXJ0LmV4dGVuc2lvbnNbaV07CiAgICAgICAgaWYoZXh0LmNyaXRpY2FsICYmICEoZXh0Lm5hbWUgaW4gc2UpKSB7CiAgICAgICAgICBlcnJvciA9IHsKICAgICAgICAgICAgbWVzc2FnZToKICAgICAgICAgICAgICAnQ2VydGlmaWNhdGUgaGFzIGFuIHVuc3VwcG9ydGVkIGNyaXRpY2FsIGV4dGVuc2lvbi4nLAogICAgICAgICAgICBlcnJvcjogcGtpLmNlcnRpZmljYXRlRXJyb3IudW5zdXBwb3J0ZWRfY2VydGlmaWNhdGUKICAgICAgICAgIH07CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgLy8gOC4gY2hlY2sgZm9yIENBIGlmIGNlcnQgaXMgbm90IGZpcnN0IG9yIGlzIHRoZSBvbmx5IGNlcnRpZmljYXRlCiAgICAvLyByZW1haW5pbmcgaW4gY2hhaW4gd2l0aCBubyBwYXJlbnQgb3IgaXMgc2VsZi1zaWduZWQKICAgIGlmKGVycm9yID09PSBudWxsICYmCiAgICAgICghZmlyc3QgfHwgKGNoYWluLmxlbmd0aCA9PT0gMCAmJiAoIXBhcmVudCB8fCBzZWxmU2lnbmVkKSkpKSB7CiAgICAgIC8vIGZpcnN0IGNoZWNrIGtleVVzYWdlIGV4dGVuc2lvbiBhbmQgdGhlbiBiYXNpYyBjb25zdHJhaW50cwogICAgICB2YXIgYmNFeHQgPSBjZXJ0LmdldEV4dGVuc2lvbignYmFzaWNDb25zdHJhaW50cycpOwogICAgICB2YXIga2V5VXNhZ2VFeHQgPSBjZXJ0LmdldEV4dGVuc2lvbigna2V5VXNhZ2UnKTsKICAgICAgaWYoa2V5VXNhZ2VFeHQgIT09IG51bGwpIHsKICAgICAgICAvLyBrZXlDZXJ0U2lnbiBtdXN0IGJlIHRydWUgYW5kIHRoZXJlIG11c3QgYmUgYSBiYXNpYwogICAgICAgIC8vIGNvbnN0cmFpbnRzIGV4dGVuc2lvbgogICAgICAgIGlmKCFrZXlVc2FnZUV4dC5rZXlDZXJ0U2lnbiB8fCBiY0V4dCA9PT0gbnVsbCkgewogICAgICAgICAgLy8gYmFkIGNlcnRpZmljYXRlCiAgICAgICAgICBlcnJvciA9IHsKICAgICAgICAgICAgbWVzc2FnZToKICAgICAgICAgICAgICAnQ2VydGlmaWNhdGUga2V5VXNhZ2Ugb3IgYmFzaWNDb25zdHJhaW50cyBjb25mbGljdCAnICsKICAgICAgICAgICAgICAnb3IgaW5kaWNhdGUgdGhhdCB0aGUgY2VydGlmaWNhdGUgaXMgbm90IGEgQ0EuICcgKwogICAgICAgICAgICAgICdJZiB0aGUgY2VydGlmaWNhdGUgaXMgdGhlIG9ubHkgb25lIGluIHRoZSBjaGFpbiBvciAnICsKICAgICAgICAgICAgICAnaXNuXCd0IHRoZSBmaXJzdCB0aGVuIHRoZSBjZXJ0aWZpY2F0ZSBtdXN0IGJlIGEgJyArCiAgICAgICAgICAgICAgJ3ZhbGlkIENBLicsCiAgICAgICAgICAgIGVycm9yOiBwa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGUKICAgICAgICAgIH07CiAgICAgICAgfQogICAgICB9CiAgICAgIC8vIGJhc2ljIGNvbnN0cmFpbnRzIGNBIGZsYWcgbXVzdCBiZSBzZXQKICAgICAgaWYoZXJyb3IgPT09IG51bGwgJiYgYmNFeHQgIT09IG51bGwgJiYgIWJjRXh0LmNBKSB7CiAgICAgICAgLy8gYmFkIGNlcnRpZmljYXRlCiAgICAgICAgZXJyb3IgPSB7CiAgICAgICAgICBtZXNzYWdlOgogICAgICAgICAgICAnQ2VydGlmaWNhdGUgYmFzaWNDb25zdHJhaW50cyBpbmRpY2F0ZXMgdGhlIGNlcnRpZmljYXRlICcgKwogICAgICAgICAgICAnaXMgbm90IGEgQ0EuJywKICAgICAgICAgIGVycm9yOiBwa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGUKICAgICAgICB9OwogICAgICB9CiAgICAgIC8vIGlmIGVycm9yIGlzIG5vdCBudWxsIGFuZCBrZXlVc2FnZSBpcyBhdmFpbGFibGUsIHRoZW4gd2Uga25vdyBpdAogICAgICAvLyBoYXMga2V5Q2VydFNpZ24gYW5kIHRoZXJlIGlzIGEgYmFzaWMgY29uc3RyYWludHMgZXh0ZW5zaW9uIHRvbywKICAgICAgLy8gd2hpY2ggbWVhbnMgd2UgY2FuIGNoZWNrIHBhdGhMZW5Db25zdHJhaW50IChpZiBpdCBleGlzdHMpCiAgICAgIGlmKGVycm9yID09PSBudWxsICYmIGtleVVzYWdlRXh0ICE9PSBudWxsICYmCiAgICAgICAgJ3BhdGhMZW5Db25zdHJhaW50JyBpbiBiY0V4dCkgewogICAgICAgIC8vIHBhdGhMZW4gaXMgdGhlIG1heGltdW0gIyBvZiBpbnRlcm1lZGlhdGUgQ0EgY2VydHMgdGhhdCBjYW4gYmUKICAgICAgICAvLyBmb3VuZCBiZXR3ZWVuIHRoZSBjdXJyZW50IGNlcnRpZmljYXRlIGFuZCB0aGUgZW5kLWVudGl0eSAoZGVwdGggMCkKICAgICAgICAvLyBjZXJ0aWZpY2F0ZTsgdGhpcyBudW1iZXIgZG9lcyBub3QgaW5jbHVkZSB0aGUgZW5kLWVudGl0eSAoZGVwdGggMCwKICAgICAgICAvLyBsYXN0IGluIHRoZSBjaGFpbikgZXZlbiBpZiBpdCBoYXBwZW5zIHRvIGJlIGEgQ0EgY2VydGlmaWNhdGUgaXRzZWxmCiAgICAgICAgdmFyIHBhdGhMZW4gPSBkZXB0aCAtIDE7CiAgICAgICAgaWYocGF0aExlbiA+IGJjRXh0LnBhdGhMZW5Db25zdHJhaW50KSB7CiAgICAgICAgICAvLyBwYXRoTGVuQ29uc3RyYWludCB2aW9sYXRlZCwgYmFkIGNlcnRpZmljYXRlCiAgICAgICAgICBlcnJvciA9IHsKICAgICAgICAgICAgbWVzc2FnZToKICAgICAgICAgICAgICAnQ2VydGlmaWNhdGUgYmFzaWNDb25zdHJhaW50cyBwYXRoTGVuQ29uc3RyYWludCB2aW9sYXRlZC4nLAogICAgICAgICAgICBlcnJvcjogcGtpLmNlcnRpZmljYXRlRXJyb3IuYmFkX2NlcnRpZmljYXRlCiAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIC8vIGNhbGwgYXBwbGljYXRpb24gY2FsbGJhY2sKICAgIHZhciB2ZmQgPSAoZXJyb3IgPT09IG51bGwpID8gdHJ1ZSA6IGVycm9yLmVycm9yOwogICAgdmFyIHJldCA9IHZlcmlmeSA/IHZlcmlmeSh2ZmQsIGRlcHRoLCBjZXJ0cykgOiB2ZmQ7CiAgICBpZihyZXQgPT09IHRydWUpIHsKICAgICAgLy8gY2xlYXIgYW55IHNldCBlcnJvcgogICAgICBlcnJvciA9IG51bGw7CiAgICB9IGVsc2UgewogICAgICAvLyBpZiBwYXNzZWQgYmFzaWMgdGVzdHMsIHNldCBkZWZhdWx0IG1lc3NhZ2UgYW5kIGFsZXJ0CiAgICAgIGlmKHZmZCA9PT0gdHJ1ZSkgewogICAgICAgIGVycm9yID0gewogICAgICAgICAgbWVzc2FnZTogJ1RoZSBhcHBsaWNhdGlvbiByZWplY3RlZCB0aGUgY2VydGlmaWNhdGUuJywKICAgICAgICAgIGVycm9yOiBwa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGUKICAgICAgICB9OwogICAgICB9CgogICAgICAvLyBjaGVjayBmb3IgY3VzdG9tIGVycm9yIGluZm8KICAgICAgaWYocmV0IHx8IHJldCA9PT0gMCkgewogICAgICAgIC8vIHNldCBjdXN0b20gbWVzc2FnZSBhbmQgZXJyb3IKICAgICAgICBpZih0eXBlb2YgcmV0ID09PSAnb2JqZWN0JyAmJiAhZm9yZ2UudXRpbC5pc0FycmF5KHJldCkpIHsKICAgICAgICAgIGlmKHJldC5tZXNzYWdlKSB7CiAgICAgICAgICAgICBlcnJvci5tZXNzYWdlID0gcmV0Lm1lc3NhZ2U7CiAgICAgICAgICB9CiAgICAgICAgICBpZihyZXQuZXJyb3IpIHsKICAgICAgICAgICAgZXJyb3IuZXJyb3IgPSByZXQuZXJyb3I7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmKHR5cGVvZiByZXQgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgICAvLyBzZXQgY3VzdG9tIGVycm9yCiAgICAgICAgICBlcnJvci5lcnJvciA9IHJldDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIHRocm93IGVycm9yCiAgICAgIHRocm93IGVycm9yOwogICAgfQoKICAgIC8vIG5vIGxvbmdlciBmaXJzdCBjZXJ0IGluIGNoYWluCiAgICBmaXJzdCA9IGZhbHNlOwogICAgKytkZXB0aDsKICB9IHdoaWxlKGNoYWluLmxlbmd0aCA+IDApOwoKICByZXR1cm4gdHJ1ZTsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3g1MDknOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZS5wa2k7CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3g1MDknLFsKICAncmVxdWlyZScsCiAgJ21vZHVsZScsCiAgJy4vYWVzJywKICAnLi9hc24xJywKICAnLi9kZXMnLAogICcuL21kJywKICAnLi9tZ2YnLAogICcuL29pZHMnLAogICcuL3BlbScsCiAgJy4vcHNzJywKICAnLi9yc2EnLAogICcuL3V0aWwnCl0sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgUEtDUyMxMi4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICogQGF1dGhvciBTdGVmYW4gU2llZ2wgPHN0ZXNpZUBicm9rZW5waXBlLmRlPgogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKiBDb3B5cmlnaHQgKGMpIDIwMTIgU3RlZmFuIFNpZWdsIDxzdGVzaWVAYnJva2VucGlwZS5kZT4KICoKICogVGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIFBLQ1MjMTIgaXMgYXMgZm9sbG93cwogKiAoc2VlIGZ0cDovL2Z0cC5yc2FzZWN1cml0eS5jb20vcHViL3BrY3MvcGtjcy0xMi9wa2NzLTEyLXRjMS5wZGYgZm9yIGRldGFpbHMpCiAqCiAqIFBGWCA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gIElOVEVHRVIge3YzKDMpfSh2MywuLi4pLAogKiAgIGF1dGhTYWZlIENvbnRlbnRJbmZvLAogKiAgIG1hY0RhdGEgIE1hY0RhdGEgT1BUSU9OQUwKICogfQogKgogKiBNYWNEYXRhIDo6PSBTRVFVRU5DRSB7CiAqICAgbWFjIERpZ2VzdEluZm8sCiAqICAgbWFjU2FsdCBPQ1RFVCBTVFJJTkcsCiAqICAgaXRlcmF0aW9ucyBJTlRFR0VSIERFRkFVTFQgMQogKiB9CiAqIE5vdGU6IFRoZSBpdGVyYXRpb25zIGRlZmF1bHQgaXMgZm9yIGhpc3RvcmljYWwgcmVhc29ucyBhbmQgaXRzIHVzZSBpcwogKiBkZXByZWNhdGVkLiBBIGhpZ2hlciB2YWx1ZSwgbGlrZSAxMDI0LCBpcyByZWNvbW1lbmRlZC4KICoKICogRGlnZXN0SW5mbyBpcyBkZWZpbmVkIGluIFBLQ1MjNyBhcyBmb2xsb3dzOgogKgogKiBEaWdlc3RJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgZGlnZXN0QWxnb3JpdGhtIERpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgZGlnZXN0IERpZ2VzdAogKiB9CiAqCiAqIERpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXIgOjo9IEFsZ29yaXRobUlkZW50aWZpZXIKICoKICogVGhlIEFsZ29yaXRobUlkZW50aWZpZXIgY29udGFpbnMgYW4gT2JqZWN0IElkZW50aWZpZXIgKE9JRCkgYW5kIHBhcmFtZXRlcnMKICogZm9yIHRoZSBhbGdvcml0aG0sIGlmIGFueS4gSW4gdGhlIGNhc2Ugb2YgU0hBMSB0aGVyZSBpcyBub25lLgogKgogKiBBbGdvcml0aG1JZGVudGlmZXIgOjo9IFNFUVVFTkNFIHsKICogICAgYWxnb3JpdGhtIE9CSkVDVCBJREVOVElGSUVSLAogKiAgICBwYXJhbWV0ZXJzIEFOWSBERUZJTkVEIEJZIGFsZ29yaXRobSBPUFRJT05BTAogKiB9CiAqCiAqIERpZ2VzdCA6Oj0gT0NURVQgU1RSSU5HCiAqCiAqCiAqIENvbnRlbnRJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgY29udGVudFR5cGUgQ29udGVudFR5cGUsCiAqICAgY29udGVudCAgICAgWzBdIEVYUExJQ0lUIEFOWSBERUZJTkVEIEJZIGNvbnRlbnRUeXBlIE9QVElPTkFMCiAqIH0KICoKICogQ29udGVudFR5cGUgOjo9IE9CSkVDVCBJREVOVElGSUVSCiAqCiAqIEF1dGhlbnRpY2F0ZWRTYWZlIDo6PSBTRVFVRU5DRSBPRiBDb250ZW50SW5mbwogKiAtLSBEYXRhIGlmIHVuZW5jcnlwdGVkCiAqIC0tIEVuY3J5cHRlZERhdGEgaWYgcGFzc3dvcmQtZW5jcnlwdGVkCiAqIC0tIEVudmVsb3BlZERhdGEgaWYgcHVibGljIGtleS1lbmNyeXB0ZWQKICoKICoKICogU2FmZUNvbnRlbnRzIDo6PSBTRVFVRU5DRSBPRiBTYWZlQmFnCiAqCiAqIFNhZmVCYWcgOjo9IFNFUVVFTkNFIHsKICogICBiYWdJZCAgICAgQkFHLVRZUEUuJmlkICh7UEtDUzEyQmFnU2V0fSkKICogICBiYWdWYWx1ZSAgWzBdIEVYUExJQ0lUIEJBRy1UWVBFLiZUeXBlKHtQS0NTMTJCYWdTZXR9e0BiYWdJZH0pLAogKiAgIGJhZ0F0dHJpYnV0ZXMgU0VUIE9GIFBLQ1MxMkF0dHJpYnV0ZSBPUFRJT05BTAogKiB9CiAqCiAqIFBLQ1MxMkF0dHJpYnV0ZSA6Oj0gU0VRVUVOQ0UgewogKiAgIGF0dHJJZCBBVFRSSUJVVEUuJmlkICh7UEtDUzEyQXR0clNldH0pLAogKiAgIGF0dHJWYWx1ZXMgU0VUIE9GIEFUVFJJQlVURS4mVHlwZSAoe1BLQ1MxMkF0dHJTZXR9e0BhdHRySWR9KQogKiB9IC0tIFRoaXMgdHlwZSBpcyBjb21wYXRpYmxlIHdpdGggdGhlIFguNTAwIHR5cGUg4oCZQXR0cmlidXRl4oCZCiAqCiAqIFBLQ1MxMkF0dHJTZXQgQVRUUklCVVRFIDo6PSB7CiAqICAgZnJpZW5kbHlOYW1lIHwgLS0gZnJvbSBQS0NTICM5CiAqICAgbG9jYWxLZXlJZCwgLS0gZnJvbSBQS0NTICM5CiAqICAgLi4uIC0tIE90aGVyIGF0dHJpYnV0ZXMgYXJlIGFsbG93ZWQKICogfQogKgogKiBDZXJ0QmFnIDo6PSBTRVFVRU5DRSB7CiAqICAgY2VydElkICAgIEJBRy1UWVBFLiZpZCAgICh7Q2VydFR5cGVzfSksCiAqICAgY2VydFZhbHVlIFswXSBFWFBMSUNJVCBCQUctVFlQRS4mVHlwZSAoe0NlcnRUeXBlc317QGNlcnRJZH0pCiAqIH0KICoKICogeDUwOUNlcnRpZmljYXRlIEJBRy1UWVBFIDo6PSB7T0NURVQgU1RSSU5HIElERU5USUZJRUQgQlkge2NlcnRUeXBlcyAxfX0KICogICAtLSBERVItZW5jb2RlZCBYLjUwOSBjZXJ0aWZpY2F0ZSBzdG9yZWQgaW4gT0NURVQgU1RSSU5HCiAqCiAqIHNkc2lDZXJ0aWZpY2F0ZSBCQUctVFlQRSA6Oj0ge0lBNVN0cmluZyBJREVOVElGSUVEIEJZIHtjZXJ0VHlwZXMgMn19CiAqIC0tIEJhc2U2NC1lbmNvZGVkIFNEU0kgY2VydGlmaWNhdGUgc3RvcmVkIGluIElBNVN0cmluZwogKgogKiBDZXJ0VHlwZXMgQkFHLVRZUEUgOjo9IHsKICogICB4NTA5Q2VydGlmaWNhdGUgfAogKiAgIHNkc2lDZXJ0aWZpY2F0ZSwKICogICAuLi4gLS0gRm9yIGZ1dHVyZSBleHRlbnNpb25zCiAqIH0KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBzaG9ydGN1dCBmb3IgYXNuLjEgJiBQS0kgQVBJCnZhciBhc24xID0gZm9yZ2UuYXNuMTsKdmFyIHBraSA9IGZvcmdlLnBraTsKCi8vIHNob3J0Y3V0IGZvciBQS0NTIzEyIEFQSQp2YXIgcDEyID0gZm9yZ2UucGtjczEyID0gZm9yZ2UucGtjczEyIHx8IHt9OwoKdmFyIGNvbnRlbnRJbmZvVmFsaWRhdG9yID0gewogIG5hbWU6ICdDb250ZW50SW5mbycsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwgIC8vIGEgQ29udGVudEluZm8KICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdDb250ZW50SW5mby5jb250ZW50VHlwZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2NvbnRlbnRUeXBlJwogIH0sIHsKICAgIG5hbWU6ICdDb250ZW50SW5mby5jb250ZW50JywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAnY29udGVudCcKICB9XQp9OwoKdmFyIHBmeFZhbGlkYXRvciA9IHsKICBuYW1lOiAnUEZYJywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIHZhbHVlOiBbewogICAgbmFtZTogJ1BGWC52ZXJzaW9uJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ZlcnNpb24nCiAgfSwKICBjb250ZW50SW5mb1ZhbGlkYXRvciwgewogICAgbmFtZTogJ1BGWC5tYWNEYXRhJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgb3B0aW9uYWw6IHRydWUsCiAgICBjYXB0dXJlQXNuMTogJ21hYycsCiAgICB2YWx1ZTogW3sKICAgICAgbmFtZTogJ1BGWC5tYWNEYXRhLm1hYycsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLCAgLy8gRGlnZXN0SW5mbwogICAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgdmFsdWU6IFt7CiAgICAgICAgbmFtZTogJ1BGWC5tYWNEYXRhLm1hYy5kaWdlc3RBbGdvcml0aG0nLAogICAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsICAvLyBEaWdlc3RBbGdvcml0aG1JZGVudGlmaWVyCiAgICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgICAgdmFsdWU6IFt7CiAgICAgICAgICBuYW1lOiAnUEZYLm1hY0RhdGEubWFjLmRpZ2VzdEFsZ29yaXRobS5hbGdvcml0aG0nLAogICAgICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICAgICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICAgIGNhcHR1cmU6ICdtYWNBbGdvcml0aG0nCiAgICAgICAgfSwgewogICAgICAgICAgbmFtZTogJ1BGWC5tYWNEYXRhLm1hYy5kaWdlc3RBbGdvcml0aG0ucGFyYW1ldGVycycsCiAgICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgICBjYXB0dXJlQXNuMTogJ21hY0FsZ29yaXRobVBhcmFtZXRlcnMnCiAgICAgICAgfV0KICAgICAgfSwgewogICAgICAgIG5hbWU6ICdQRlgubWFjRGF0YS5tYWMuZGlnZXN0JywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBjYXB0dXJlOiAnbWFjRGlnZXN0JwogICAgICB9XQogICAgfSwgewogICAgICBuYW1lOiAnUEZYLm1hY0RhdGEubWFjU2FsdCcsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdtYWNTYWx0JwogICAgfSwgewogICAgICBuYW1lOiAnUEZYLm1hY0RhdGEuaXRlcmF0aW9ucycsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgIGNhcHR1cmU6ICdtYWNJdGVyYXRpb25zJwogICAgfV0KICB9XQp9OwoKdmFyIHNhZmVCYWdWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ1NhZmVCYWcnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnU2FmZUJhZy5iYWdJZCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2JhZ0lkJwogIH0sIHsKICAgIG5hbWU6ICdTYWZlQmFnLmJhZ1ZhbHVlJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAnYmFnVmFsdWUnCiAgfSwgewogICAgbmFtZTogJ1NhZmVCYWcuYmFnQXR0cmlidXRlcycsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VULAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICBvcHRpb25hbDogdHJ1ZSwKICAgIGNhcHR1cmU6ICdiYWdBdHRyaWJ1dGVzJwogIH1dCn07Cgp2YXIgYXR0cmlidXRlVmFsaWRhdG9yID0gewogIG5hbWU6ICdBdHRyaWJ1dGUnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnQXR0cmlidXRlLmF0dHJJZCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ29pZCcKICB9LCB7CiAgICBuYW1lOiAnQXR0cmlidXRlLmF0dHJWYWx1ZXMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFVCwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgY2FwdHVyZTogJ3ZhbHVlcycKICB9XQp9OwoKdmFyIGNlcnRCYWdWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0NlcnRCYWcnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnQ2VydEJhZy5jZXJ0SWQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdjZXJ0SWQnCiAgfSwgewogICAgbmFtZTogJ0NlcnRCYWcuY2VydFZhbHVlJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIC8qIFNvIGZhciB3ZSBvbmx5IHN1cHBvcnQgWC41MDkgY2VydGlmaWNhdGVzICh3aGljaCBhcmUgd3JhcHBlZCBpbgogICAgICAgYW4gT0NURVQgU1RSSU5HLCBoZW5jZSBoYXJkIGNvZGUgdGhhdCBoZXJlKS4gKi8KICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnQ2VydEJhZy5jZXJ0VmFsdWVbMF0nLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuQ2xhc3MuT0NURVRTVFJJTkcsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2NlcnQnCiAgICB9XQogIH1dCn07CgovKioKICogU2VhcmNoIFNhZmVDb250ZW50cyBzdHJ1Y3R1cmUgZm9yIGJhZ3Mgd2l0aCBtYXRjaGluZyBhdHRyaWJ1dGVzLgogKgogKiBUaGUgc2VhcmNoIGNhbiBvcHRpb25hbGx5IGJlIG5hcnJvd2VkIGJ5IGEgY2VydGFpbiBiYWcgdHlwZS4KICoKICogQHBhcmFtIHNhZmVDb250ZW50cyB0aGUgU2FmZUNvbnRlbnRzIHN0cnVjdHVyZSB0byBzZWFyY2ggaW4uCiAqIEBwYXJhbSBhdHRyTmFtZSB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIGNvbXBhcmUgYWdhaW5zdC4KICogQHBhcmFtIGF0dHJWYWx1ZSB0aGUgYXR0cmlidXRlIHZhbHVlIHRvIHNlYXJjaCBmb3IuCiAqIEBwYXJhbSBbYmFnVHlwZV0gYmFnIHR5cGUgdG8gbmFycm93IHNlYXJjaCBieS4KICoKICogQHJldHVybiBhbiBhcnJheSBvZiBtYXRjaGluZyBiYWdzLgogKi8KZnVuY3Rpb24gX2dldEJhZ3NCeUF0dHJpYnV0ZShzYWZlQ29udGVudHMsIGF0dHJOYW1lLCBhdHRyVmFsdWUsIGJhZ1R5cGUpIHsKICB2YXIgcmVzdWx0ID0gW107CgogIGZvcih2YXIgaSA9IDA7IGkgPCBzYWZlQ29udGVudHMubGVuZ3RoOyBpICsrKSB7CiAgICBmb3IodmFyIGogPSAwOyBqIDwgc2FmZUNvbnRlbnRzW2ldLnNhZmVCYWdzLmxlbmd0aDsgaiArKykgewogICAgICB2YXIgYmFnID0gc2FmZUNvbnRlbnRzW2ldLnNhZmVCYWdzW2pdOwogICAgICBpZihiYWdUeXBlICE9PSB1bmRlZmluZWQgJiYgYmFnLnR5cGUgIT09IGJhZ1R5cGUpIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICAvLyBvbmx5IGZpbHRlciBieSBiYWcgdHlwZSwgbm8gYXR0cmlidXRlIHNwZWNpZmllZAogICAgICBpZihhdHRyTmFtZSA9PT0gbnVsbCkgewogICAgICAgIHJlc3VsdC5wdXNoKGJhZyk7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYoYmFnLmF0dHJpYnV0ZXNbYXR0ck5hbWVdICE9PSB1bmRlZmluZWQgJiYKICAgICAgICBiYWcuYXR0cmlidXRlc1thdHRyTmFtZV0uaW5kZXhPZihhdHRyVmFsdWUpID49IDApIHsKICAgICAgICByZXN1bHQucHVzaChiYWcpOwogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogQ29udmVydHMgYSBQS0NTIzEyIFBGWCBpbiBBU04uMSBub3RhdGlvbiBpbnRvIGEgUEZYIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiBUaGUgUEtDUyMxMiBQRlggaW4gQVNOLjEgbm90YXRpb24uCiAqIEBwYXJhbSBzdHJpY3QgdHJ1ZSB0byB1c2Ugc3RyaWN0IERFUiBkZWNvZGluZywgZmFsc2Ugbm90IHRvIChkZWZhdWx0OiB0cnVlKS4KICogQHBhcmFtIHtTdHJpbmd9IHBhc3N3b3JkIFBhc3N3b3JkIHRvIGRlY3J5cHQgd2l0aCAob3B0aW9uYWwpLgogKgogKiBAcmV0dXJuIFBLQ1MjMTIgUEZYIG9iamVjdC4KICovCnAxMi5wa2NzMTJGcm9tQXNuMSA9IGZ1bmN0aW9uKG9iaiwgc3RyaWN0LCBwYXNzd29yZCkgewogIC8vIGhhbmRsZSBhcmdzCiAgaWYodHlwZW9mIHN0cmljdCA9PT0gJ3N0cmluZycpIHsKICAgIHBhc3N3b3JkID0gc3RyaWN0OwogICAgc3RyaWN0ID0gdHJ1ZTsKICB9IGVsc2UgaWYoc3RyaWN0ID09PSB1bmRlZmluZWQpIHsKICAgIHN0cmljdCA9IHRydWU7CiAgfQoKICAvLyB2YWxpZGF0ZSBQRlggYW5kIGNhcHR1cmUgZGF0YQogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgcGZ4VmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFBLQ1MjMTIgUEZYLiAnICsKICAgICAgJ0FTTi4xIG9iamVjdCBpcyBub3QgYW4gUEtDUyMxMiBQRlguJyk7CiAgICBlcnJvci5lcnJvcnMgPSBlcnJvcjsKICAgIHRocm93IGVycm9yOwogIH0KCiAgdmFyIHBmeCA9IHsKICAgIHZlcnNpb246IGNhcHR1cmUudmVyc2lvbi5jaGFyQ29kZUF0KDApLAogICAgc2FmZUNvbnRlbnRzOiBbXSwKCiAgICAvKioKICAgICAqIEdldHMgYmFncyB3aXRoIG1hdGNoaW5nIGF0dHJpYnV0ZXMuCiAgICAgKgogICAgICogQHBhcmFtIGZpbHRlciB0aGUgYXR0cmlidXRlcyB0byBmaWx0ZXIgYnk6CiAgICAgKiAgICAgICAgICBbbG9jYWxLZXlJZF0gdGhlIGxvY2FsS2V5SWQgdG8gc2VhcmNoIGZvci4KICAgICAqICAgICAgICAgIFtsb2NhbEtleUlkSGV4XSB0aGUgbG9jYWxLZXlJZCBpbiBoZXggdG8gc2VhcmNoIGZvci4KICAgICAqICAgICAgICAgIFtmcmllbmRseU5hbWVdIHRoZSBmcmllbmRseSBuYW1lIHRvIHNlYXJjaCBmb3IuCiAgICAgKiAgICAgICAgICBbYmFnVHlwZV0gYmFnIHR5cGUgdG8gbmFycm93IGVhY2ggYXR0cmlidXRlIHNlYXJjaCBieS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGEgbWFwIG9mIGF0dHJpYnV0ZSB0eXBlIHRvIGFuIGFycmF5IG9mIG1hdGNoaW5nIGJhZ3Mgb3IsIGlmIG5vCiAgICAgKiAgICAgICAgICAgYXR0cmlidXRlIHdhcyBnaXZlbiBidXQgYSBiYWcgdHlwZSwgdGhlIG1hcCBrZXkgd2lsbCBiZSB0aGUKICAgICAqICAgICAgICAgICBiYWcgdHlwZS4KICAgICAqLwogICAgZ2V0QmFnczogZnVuY3Rpb24oZmlsdGVyKSB7CiAgICAgIHZhciBydmFsID0ge307CgogICAgICB2YXIgbG9jYWxLZXlJZDsKICAgICAgaWYoJ2xvY2FsS2V5SWQnIGluIGZpbHRlcikgewogICAgICAgIGxvY2FsS2V5SWQgPSBmaWx0ZXIubG9jYWxLZXlJZDsKICAgICAgfSBlbHNlIGlmKCdsb2NhbEtleUlkSGV4JyBpbiBmaWx0ZXIpIHsKICAgICAgICBsb2NhbEtleUlkID0gZm9yZ2UudXRpbC5oZXhUb0J5dGVzKGZpbHRlci5sb2NhbEtleUlkSGV4KTsKICAgICAgfQoKICAgICAgLy8gZmlsdGVyIG9uIGJhZ1R5cGUgb25seQogICAgICBpZihsb2NhbEtleUlkID09PSB1bmRlZmluZWQgJiYgISgnZnJpZW5kbHlOYW1lJyBpbiBmaWx0ZXIpICYmCiAgICAgICAgJ2JhZ1R5cGUnIGluIGZpbHRlcikgewogICAgICAgIHJ2YWxbZmlsdGVyLmJhZ1R5cGVdID0gX2dldEJhZ3NCeUF0dHJpYnV0ZSgKICAgICAgICAgIHBmeC5zYWZlQ29udGVudHMsIG51bGwsIG51bGwsIGZpbHRlci5iYWdUeXBlKTsKICAgICAgfQoKICAgICAgaWYobG9jYWxLZXlJZCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgcnZhbC5sb2NhbEtleUlkID0gX2dldEJhZ3NCeUF0dHJpYnV0ZSgKICAgICAgICAgIHBmeC5zYWZlQ29udGVudHMsICdsb2NhbEtleUlkJywKICAgICAgICAgIGxvY2FsS2V5SWQsIGZpbHRlci5iYWdUeXBlKTsKICAgICAgfQogICAgICBpZignZnJpZW5kbHlOYW1lJyBpbiBmaWx0ZXIpIHsKICAgICAgICBydmFsLmZyaWVuZGx5TmFtZSA9IF9nZXRCYWdzQnlBdHRyaWJ1dGUoCiAgICAgICAgICBwZnguc2FmZUNvbnRlbnRzLCAnZnJpZW5kbHlOYW1lJywKICAgICAgICAgIGZpbHRlci5mcmllbmRseU5hbWUsIGZpbHRlci5iYWdUeXBlKTsKICAgICAgfQoKICAgICAgcmV0dXJuIHJ2YWw7CiAgICB9LAoKICAgIC8qKgogICAgICogREVQUkVDQVRFRDogdXNlIGdldEJhZ3MoKSBpbnN0ZWFkLgogICAgICoKICAgICAqIEdldCBiYWdzIHdpdGggbWF0Y2hpbmcgZnJpZW5kbHlOYW1lIGF0dHJpYnV0ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZnJpZW5kbHlOYW1lIHRoZSBmcmllbmRseSBuYW1lIHRvIHNlYXJjaCBmb3IuCiAgICAgKiBAcGFyYW0gW2JhZ1R5cGVdIGJhZyB0eXBlIHRvIG5hcnJvdyBzZWFyY2ggYnkuCiAgICAgKgogICAgICogQHJldHVybiBhbiBhcnJheSBvZiBiYWdzIHdpdGggbWF0Y2hpbmcgZnJpZW5kbHlOYW1lIGF0dHJpYnV0ZS4KICAgICAqLwogICAgZ2V0QmFnc0J5RnJpZW5kbHlOYW1lOiBmdW5jdGlvbihmcmllbmRseU5hbWUsIGJhZ1R5cGUpIHsKICAgICAgcmV0dXJuIF9nZXRCYWdzQnlBdHRyaWJ1dGUoCiAgICAgICAgcGZ4LnNhZmVDb250ZW50cywgJ2ZyaWVuZGx5TmFtZScsIGZyaWVuZGx5TmFtZSwgYmFnVHlwZSk7CiAgICB9LAoKICAgIC8qKgogICAgICogREVQUkVDQVRFRDogdXNlIGdldEJhZ3MoKSBpbnN0ZWFkLgogICAgICoKICAgICAqIEdldCBiYWdzIHdpdGggbWF0Y2hpbmcgbG9jYWxLZXlJZCBhdHRyaWJ1dGUuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2FsS2V5SWQgdGhlIGxvY2FsS2V5SWQgdG8gc2VhcmNoIGZvci4KICAgICAqIEBwYXJhbSBbYmFnVHlwZV0gYmFnIHR5cGUgdG8gbmFycm93IHNlYXJjaCBieS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIGJhZ3Mgd2l0aCBtYXRjaGluZyBsb2NhbEtleUlkIGF0dHJpYnV0ZS4KICAgICAqLwogICAgZ2V0QmFnc0J5TG9jYWxLZXlJZDogZnVuY3Rpb24obG9jYWxLZXlJZCwgYmFnVHlwZSkgewogICAgICByZXR1cm4gX2dldEJhZ3NCeUF0dHJpYnV0ZSgKICAgICAgICBwZnguc2FmZUNvbnRlbnRzLCAnbG9jYWxLZXlJZCcsIGxvY2FsS2V5SWQsIGJhZ1R5cGUpOwogICAgfQogIH07CgogIGlmKGNhcHR1cmUudmVyc2lvbi5jaGFyQ29kZUF0KDApICE9PSAzKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1BLQ1MjMTIgUEZYIG9mIHZlcnNpb24gb3RoZXIgdGhhbiAzIG5vdCBzdXBwb3J0ZWQuJyk7CiAgICBlcnJvci52ZXJzaW9uID0gY2FwdHVyZS52ZXJzaW9uLmNoYXJDb2RlQXQoMCk7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIGlmKGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5jb250ZW50VHlwZSkgIT09IHBraS5vaWRzLmRhdGEpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignT25seSBQS0NTIzEyIFBGWCBpbiBwYXNzd29yZCBpbnRlZ3JpdHkgbW9kZSBzdXBwb3J0ZWQuJyk7CiAgICBlcnJvci5vaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUuY29udGVudFR5cGUpOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICB2YXIgZGF0YSA9IGNhcHR1cmUuY29udGVudC52YWx1ZVswXTsKICBpZihkYXRhLnRhZ0NsYXNzICE9PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fAogICAgIGRhdGEudHlwZSAhPT0gYXNuMS5UeXBlLk9DVEVUU1RSSU5HKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BLQ1MjMTIgYXV0aFNhZmUgY29udGVudCBkYXRhIGlzIG5vdCBhbiBPQ1RFVCBTVFJJTkcuJyk7CiAgfQogIGRhdGEgPSBfZGVjb2RlUGtjczdEYXRhKGRhdGEpOwoKICAvLyBjaGVjayBmb3IgTUFDCiAgaWYoY2FwdHVyZS5tYWMpIHsKICAgIHZhciBtZCA9IG51bGw7CiAgICB2YXIgbWFjS2V5Qnl0ZXMgPSAwOwogICAgdmFyIG1hY0FsZ29yaXRobSA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5tYWNBbGdvcml0aG0pOwogICAgc3dpdGNoKG1hY0FsZ29yaXRobSkgewogICAgY2FzZSBwa2kub2lkcy5zaGExOgogICAgICBtZCA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICAgIG1hY0tleUJ5dGVzID0gMjA7CiAgICAgIGJyZWFrOwogICAgY2FzZSBwa2kub2lkcy5zaGEyNTY6CiAgICAgIG1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICBtYWNLZXlCeXRlcyA9IDMyOwogICAgICBicmVhazsKICAgIGNhc2UgcGtpLm9pZHMuc2hhMzg0OgogICAgICBtZCA9IGZvcmdlLm1kLnNoYTM4NC5jcmVhdGUoKTsKICAgICAgbWFjS2V5Qnl0ZXMgPSA0ODsKICAgICAgYnJlYWs7CiAgICBjYXNlIHBraS5vaWRzLnNoYTUxMjoKICAgICAgbWQgPSBmb3JnZS5tZC5zaGE1MTIuY3JlYXRlKCk7CiAgICAgIG1hY0tleUJ5dGVzID0gNjQ7CiAgICAgIGJyZWFrOwogICAgY2FzZSBwa2kub2lkcy5tZDU6CiAgICAgIG1kID0gZm9yZ2UubWQubWQ1LmNyZWF0ZSgpOwogICAgICBtYWNLZXlCeXRlcyA9IDE2OwogICAgICBicmVhazsKICAgIH0KICAgIGlmKG1kID09PSBudWxsKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUyMxMiB1c2VzIHVuc3VwcG9ydGVkIE1BQyBhbGdvcml0aG06ICcgKyBtYWNBbGdvcml0aG0pOwogICAgfQoKICAgIC8vIHZlcmlmeSBNQUMgKGl0ZXJhdGlvbnMgZGVmYXVsdCB0byAxKQogICAgdmFyIG1hY1NhbHQgPSBuZXcgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKGNhcHR1cmUubWFjU2FsdCk7CiAgICB2YXIgbWFjSXRlcmF0aW9ucyA9ICgoJ21hY0l0ZXJhdGlvbnMnIGluIGNhcHR1cmUpID8KICAgICAgcGFyc2VJbnQoZm9yZ2UudXRpbC5ieXRlc1RvSGV4KGNhcHR1cmUubWFjSXRlcmF0aW9ucyksIDE2KSA6IDEpOwogICAgdmFyIG1hY0tleSA9IHAxMi5nZW5lcmF0ZUtleSgKICAgICAgcGFzc3dvcmQsIG1hY1NhbHQsIDMsIG1hY0l0ZXJhdGlvbnMsIG1hY0tleUJ5dGVzLCBtZCk7CiAgICB2YXIgbWFjID0gZm9yZ2UuaG1hYy5jcmVhdGUoKTsKICAgIG1hYy5zdGFydChtZCwgbWFjS2V5KTsKICAgIG1hYy51cGRhdGUoZGF0YS52YWx1ZSk7CiAgICB2YXIgbWFjVmFsdWUgPSBtYWMuZ2V0TWFjKCk7CiAgICBpZihtYWNWYWx1ZS5nZXRCeXRlcygpICE9PSBjYXB0dXJlLm1hY0RpZ2VzdCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BLQ1MjMTIgTUFDIGNvdWxkIG5vdCBiZSB2ZXJpZmllZC4gSW52YWxpZCBwYXNzd29yZD8nKTsKICAgIH0KICB9CgogIF9kZWNvZGVBdXRoZW50aWNhdGVkU2FmZShwZngsIGRhdGEudmFsdWUsIHN0cmljdCwgcGFzc3dvcmQpOwogIHJldHVybiBwZng7Cn07CgovKioKICogRGVjb2RlcyBQS0NTIzcgRGF0YS4gUEtDUyM3IChSRkMgMjMxNSkgZGVmaW5lcyAiRGF0YSIgYXMgYW4gT0NURVQgU1RSSU5HLAogKiBidXQgaXQgaXMgc29tZXRpbWVzIGFuIE9DVEVUIFNUUklORyB0aGF0IGlzIGNvbXBvc2VkL2NvbnN0cnVjdGVkIG9mIGNodW5rcywKICogZWFjaCBpdHMgb3duIE9DVEVUIFNUUklORy4gVGhpcyBpcyBCRVItZW5jb2RpbmcgdnMuIERFUi1lbmNvZGluZy4gVGhpcwogKiBmdW5jdGlvbiB0cmFuc2Zvcm1zIHRoaXMgY29ybmVyLWNhc2UgaW50byB0aGUgdXN1YWwgc2ltcGxlLAogKiBub24tY29tcG9zZWQvY29uc3RydWN0ZWQgT0NURVQgU1RSSU5HLgogKgogKiBUaGlzIGZ1bmN0aW9uIG1heSBiZSBtb3ZlZCB0byBBU04uMSBhdCBzb21lIHBvaW50IHRvIGJldHRlciBkZWFsIHdpdGgKICogbW9yZSBCRVItZW5jb2RpbmcgaXNzdWVzLCBzaG91bGQgdGhleSBhcmlzZS4KICoKICogQHBhcmFtIGRhdGEgdGhlIEFTTi4xIERhdGEgb2JqZWN0IHRvIHRyYW5zZm9ybS4KICovCmZ1bmN0aW9uIF9kZWNvZGVQa2NzN0RhdGEoZGF0YSkgewogIC8vIGhhbmRsZSBzcGVjaWFsIGNhc2Ugb2YgImNodW5rZWQiIGRhdGEgY29udGVudDogYW4gb2N0ZXQgc3RyaW5nIGNvbXBvc2VkCiAgLy8gb2Ygb3RoZXIgb2N0ZXQgc3RyaW5ncwogIGlmKGRhdGEuY29tcG9zZWQgfHwgZGF0YS5jb25zdHJ1Y3RlZCkgewogICAgdmFyIHZhbHVlID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBkYXRhLnZhbHVlLmxlbmd0aDsgKytpKSB7CiAgICAgIHZhbHVlLnB1dEJ5dGVzKGRhdGEudmFsdWVbaV0udmFsdWUpOwogICAgfQogICAgZGF0YS5jb21wb3NlZCA9IGRhdGEuY29uc3RydWN0ZWQgPSBmYWxzZTsKICAgIGRhdGEudmFsdWUgPSB2YWx1ZS5nZXRCeXRlcygpOwogIH0KICByZXR1cm4gZGF0YTsKfQoKLyoqCiAqIERlY29kZSBQS0NTIzEyIEF1dGhlbnRpY2F0ZWRTYWZlIChCRVIgZW5jb2RlZCkgaW50byBQRlggb2JqZWN0LgogKgogKiBUaGUgQXV0aGVudGljYXRlZFNhZmUgaXMgYSBCRVItZW5jb2RlZCBTRVFVRU5DRSBPRiBDb250ZW50SW5mby4KICoKICogQHBhcmFtIHBmeCBUaGUgUEtDUyMxMiBQRlggb2JqZWN0IHRvIGZpbGwuCiAqIEBwYXJhbSB7U3RyaW5nfSBhdXRoU2FmZSBCRVItZW5jb2RlZCBBdXRoZW50aWNhdGVkU2FmZS4KICogQHBhcmFtIHN0cmljdCB0cnVlIHRvIHVzZSBzdHJpY3QgREVSIGRlY29kaW5nLCBmYWxzZSBub3QgdG8uCiAqIEBwYXJhbSB7U3RyaW5nfSBwYXNzd29yZCBQYXNzd29yZCB0byBkZWNyeXB0IHdpdGggKG9wdGlvbmFsKS4KICovCmZ1bmN0aW9uIF9kZWNvZGVBdXRoZW50aWNhdGVkU2FmZShwZngsIGF1dGhTYWZlLCBzdHJpY3QsIHBhc3N3b3JkKSB7CiAgYXV0aFNhZmUgPSBhc24xLmZyb21EZXIoYXV0aFNhZmUsIHN0cmljdCk7ICAvKiBhY3R1YWxseSBpdCdzIEJFUiBlbmNvZGVkICovCgogIGlmKGF1dGhTYWZlLnRhZ0NsYXNzICE9PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fAogICAgIGF1dGhTYWZlLnR5cGUgIT09IGFzbjEuVHlwZS5TRVFVRU5DRSB8fAogICAgIGF1dGhTYWZlLmNvbnN0cnVjdGVkICE9PSB0cnVlKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BLQ1MjMTIgQXV0aGVudGljYXRlZFNhZmUgZXhwZWN0ZWQgdG8gYmUgYSAnICsKICAgICAgJ1NFUVVFTkNFIE9GIENvbnRlbnRJbmZvJyk7CiAgfQoKICBmb3IodmFyIGkgPSAwOyBpIDwgYXV0aFNhZmUudmFsdWUubGVuZ3RoOyBpICsrKSB7CiAgICB2YXIgY29udGVudEluZm8gPSBhdXRoU2FmZS52YWx1ZVtpXTsKCiAgICAvLyB2YWxpZGF0ZSBjb250ZW50SW5mbyBhbmQgY2FwdHVyZSBkYXRhCiAgICB2YXIgY2FwdHVyZSA9IHt9OwogICAgdmFyIGVycm9ycyA9IFtdOwogICAgaWYoIWFzbjEudmFsaWRhdGUoY29udGVudEluZm8sIGNvbnRlbnRJbmZvVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgQ29udGVudEluZm8uJyk7CiAgICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgdmFyIG9iaiA9IHsKICAgICAgZW5jcnlwdGVkOiBmYWxzZQogICAgfTsKICAgIHZhciBzYWZlQ29udGVudHMgPSBudWxsOwogICAgdmFyIGRhdGEgPSBjYXB0dXJlLmNvbnRlbnQudmFsdWVbMF07CiAgICBzd2l0Y2goYXNuMS5kZXJUb09pZChjYXB0dXJlLmNvbnRlbnRUeXBlKSkgewogICAgY2FzZSBwa2kub2lkcy5kYXRhOgogICAgICBpZihkYXRhLnRhZ0NsYXNzICE9PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fAogICAgICAgICBkYXRhLnR5cGUgIT09IGFzbjEuVHlwZS5PQ1RFVFNUUklORykgewogICAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUyMxMiBTYWZlQ29udGVudHMgRGF0YSBpcyBub3QgYW4gT0NURVQgU1RSSU5HLicpOwogICAgICB9CiAgICAgIHNhZmVDb250ZW50cyA9IF9kZWNvZGVQa2NzN0RhdGEoZGF0YSkudmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSBwa2kub2lkcy5lbmNyeXB0ZWREYXRhOgogICAgICBzYWZlQ29udGVudHMgPSBfZGVjcnlwdFNhZmVDb250ZW50cyhkYXRhLCBwYXNzd29yZCk7CiAgICAgIG9iai5lbmNyeXB0ZWQgPSB0cnVlOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgUEtDUyMxMiBjb250ZW50VHlwZS4nKTsKICAgICAgZXJyb3IuY29udGVudFR5cGUgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUuY29udGVudFR5cGUpOwogICAgICB0aHJvdyBlcnJvcjsKICAgIH0KCiAgICBvYmouc2FmZUJhZ3MgPSBfZGVjb2RlU2FmZUNvbnRlbnRzKHNhZmVDb250ZW50cywgc3RyaWN0LCBwYXNzd29yZCk7CiAgICBwZnguc2FmZUNvbnRlbnRzLnB1c2gob2JqKTsKICB9Cn0KCi8qKgogKiBEZWNyeXB0IFBLQ1MjNyBFbmNyeXB0ZWREYXRhIHN0cnVjdHVyZS4KICoKICogQHBhcmFtIGRhdGEgQVNOLjEgZW5jb2RlZCBFbmNyeXB0ZWRDb250ZW50SW5mbyBvYmplY3QuCiAqIEBwYXJhbSBwYXNzd29yZCBUaGUgdXNlci1wcm92aWRlZCBwYXNzd29yZC4KICoKICogQHJldHVybiBUaGUgZGVjcnlwdGVkIFNhZmVDb250ZW50cyAoQVNOLjEgb2JqZWN0KS4KICovCmZ1bmN0aW9uIF9kZWNyeXB0U2FmZUNvbnRlbnRzKGRhdGEsIHBhc3N3b3JkKSB7CiAgdmFyIGNhcHR1cmUgPSB7fTsKICB2YXIgZXJyb3JzID0gW107CiAgaWYoIWFzbjEudmFsaWRhdGUoCiAgICBkYXRhLCBmb3JnZS5wa2NzNy5hc24xLmVuY3J5cHRlZERhdGFWYWxpZGF0b3IsIGNhcHR1cmUsIGVycm9ycykpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgRW5jcnlwdGVkQ29udGVudEluZm8uJyk7CiAgICBlcnJvci5lcnJvcnMgPSBlcnJvcnM7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIHZhciBvaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUuY29udGVudFR5cGUpOwogIGlmKG9pZCAhPT0gcGtpLm9pZHMuZGF0YSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKAogICAgICAnUEtDUyMxMiBFbmNyeXB0ZWRDb250ZW50SW5mbyBDb250ZW50VHlwZSBpcyBub3QgRGF0YS4nKTsKICAgIGVycm9yLm9pZCA9IG9pZDsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gZ2V0IGNpcGhlcgogIG9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5lbmNBbGdvcml0aG0pOwogIHZhciBjaXBoZXIgPSBwa2kucGJlLmdldENpcGhlcihvaWQsIGNhcHR1cmUuZW5jUGFyYW1ldGVyLCBwYXNzd29yZCk7CgogIC8vIGdldCBlbmNyeXB0ZWQgZGF0YQogIHZhciBlbmNyeXB0ZWRDb250ZW50QXNuMSA9IF9kZWNvZGVQa2NzN0RhdGEoY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50QXNuMSk7CiAgdmFyIGVuY3J5cHRlZCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGVuY3J5cHRlZENvbnRlbnRBc24xLnZhbHVlKTsKCiAgY2lwaGVyLnVwZGF0ZShlbmNyeXB0ZWQpOwogIGlmKCFjaXBoZXIuZmluaXNoKCkpIHsKICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGRlY3J5cHQgUEtDUyMxMiBTYWZlQ29udGVudHMuJyk7CiAgfQoKICByZXR1cm4gY2lwaGVyLm91dHB1dC5nZXRCeXRlcygpOwp9CgovKioKICogRGVjb2RlIFBLQ1MjMTIgU2FmZUNvbnRlbnRzIChCRVItZW5jb2RlZCkgaW50byBhcnJheSBvZiBCYWcgb2JqZWN0cy4KICoKICogVGhlIHNhZmVDb250ZW50cyBpcyBhIEJFUi1lbmNvZGVkIFNFUVVFTkNFIE9GIFNhZmVCYWcuCiAqCiAqIEBwYXJhbSB7U3RyaW5nfSBzYWZlQ29udGVudHMgQkVSLWVuY29kZWQgc2FmZUNvbnRlbnRzLgogKiBAcGFyYW0gc3RyaWN0IHRydWUgdG8gdXNlIHN0cmljdCBERVIgZGVjb2RpbmcsIGZhbHNlIG5vdCB0by4KICogQHBhcmFtIHtTdHJpbmd9IHBhc3N3b3JkIFBhc3N3b3JkIHRvIGRlY3J5cHQgd2l0aCAob3B0aW9uYWwpLgogKgogKiBAcmV0dXJuIHtBcnJheX0gQXJyYXkgb2YgQmFnIG9iamVjdHMuCiAqLwpmdW5jdGlvbiBfZGVjb2RlU2FmZUNvbnRlbnRzKHNhZmVDb250ZW50cywgc3RyaWN0LCBwYXNzd29yZCkgewogIC8vIGlmIHN0cmljdCBhbmQgbm8gc2FmZSBjb250ZW50cywgcmV0dXJuIGVtcHR5IHNhZmVzCiAgaWYoIXN0cmljdCAmJiBzYWZlQ29udGVudHMubGVuZ3RoID09PSAwKSB7CiAgICByZXR1cm4gW107CiAgfQoKICAvLyBhY3R1YWxseSBpdCdzIEJFUi1lbmNvZGVkCiAgc2FmZUNvbnRlbnRzID0gYXNuMS5mcm9tRGVyKHNhZmVDb250ZW50cywgc3RyaWN0KTsKCiAgaWYoc2FmZUNvbnRlbnRzLnRhZ0NsYXNzICE9PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fAogICAgc2FmZUNvbnRlbnRzLnR5cGUgIT09IGFzbjEuVHlwZS5TRVFVRU5DRSB8fAogICAgc2FmZUNvbnRlbnRzLmNvbnN0cnVjdGVkICE9PSB0cnVlKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICdQS0NTIzEyIFNhZmVDb250ZW50cyBleHBlY3RlZCB0byBiZSBhIFNFUVVFTkNFIE9GIFNhZmVCYWcuJyk7CiAgfQoKICB2YXIgcmVzID0gW107CiAgZm9yKHZhciBpID0gMDsgaSA8IHNhZmVDb250ZW50cy52YWx1ZS5sZW5ndGg7IGkrKykgewogICAgdmFyIHNhZmVCYWcgPSBzYWZlQ29udGVudHMudmFsdWVbaV07CgogICAgLy8gdmFsaWRhdGUgU2FmZUJhZyBhbmQgY2FwdHVyZSBkYXRhCiAgICB2YXIgY2FwdHVyZSA9IHt9OwogICAgdmFyIGVycm9ycyA9IFtdOwogICAgaWYoIWFzbjEudmFsaWRhdGUoc2FmZUJhZywgc2FmZUJhZ1ZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFNhZmVCYWcuJyk7CiAgICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLyogQ3JlYXRlIGJhZyBvYmplY3QgYW5kIHB1c2ggdG8gcmVzdWx0IGFycmF5LiAqLwogICAgdmFyIGJhZyA9IHsKICAgICAgdHlwZTogYXNuMS5kZXJUb09pZChjYXB0dXJlLmJhZ0lkKSwKICAgICAgYXR0cmlidXRlczogX2RlY29kZUJhZ0F0dHJpYnV0ZXMoY2FwdHVyZS5iYWdBdHRyaWJ1dGVzKQogICAgfTsKICAgIHJlcy5wdXNoKGJhZyk7CgogICAgdmFyIHZhbGlkYXRvciwgZGVjb2RlcjsKICAgIHZhciBiYWdBc24xID0gY2FwdHVyZS5iYWdWYWx1ZS52YWx1ZVswXTsKICAgIHN3aXRjaChiYWcudHlwZSkgewogICAgICBjYXNlIHBraS5vaWRzLnBrY3M4U2hyb3VkZWRLZXlCYWc6CiAgICAgICAgLyogYmFnQXNuMSBoYXMgYSBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbywgd2hpY2ggd2UgbmVlZCB0byBkZWNyeXB0LgogICAgICAgICAgIEFmdGVyd2FyZHMgd2UgY2FuIGhhbmRsZSBpdCBsaWtlIGEga2V5QmFnLAogICAgICAgICAgIHdoaWNoIGlzIGEgUHJpdmF0ZUtleUluZm8uICovCiAgICAgICAgYmFnQXNuMSA9IHBraS5kZWNyeXB0UHJpdmF0ZUtleUluZm8oYmFnQXNuMSwgcGFzc3dvcmQpOwogICAgICAgIGlmKGJhZ0FzbjEgPT09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcigKICAgICAgICAgICAgJ1VuYWJsZSB0byBkZWNyeXB0IFBLQ1MjOCBTaHJvdWRlZEtleUJhZywgd3JvbmcgcGFzc3dvcmQ/Jyk7CiAgICAgICAgfQoKICAgICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgICAgY2FzZSBwa2kub2lkcy5rZXlCYWc6CiAgICAgICAgLyogQSBQS0NTIzEyIGtleUJhZyBpcyBhIHNpbXBsZSBQcml2YXRlS2V5SW5mbyBhcyB1bmRlcnN0b29kIGJ5IG91cgogICAgICAgICAgIFBLSSBtb2R1bGUsIGhlbmNlIHdlIGRvbid0IGhhdmUgdG8gZG8gdmFsaWRhdGlvbi9jYXB0dXJpbmcgaGVyZSwKICAgICAgICAgICBqdXN0IHBhc3Mgd2hhdCB3ZSBhbHJlYWR5IGdvdC4gKi8KICAgICAgICB0cnkgewogICAgICAgICAgYmFnLmtleSA9IHBraS5wcml2YXRlS2V5RnJvbUFzbjEoYmFnQXNuMSk7CiAgICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgICAvLyBpZ25vcmUgdW5rbm93biBrZXkgdHlwZSwgcGFzcyBhc24xIHZhbHVlCiAgICAgICAgICBiYWcua2V5ID0gbnVsbDsKICAgICAgICAgIGJhZy5hc24xID0gYmFnQXNuMTsKICAgICAgICB9CiAgICAgICAgY29udGludWU7ICAvKiBOb3RoaW5nIG1vcmUgdG8gZG8uICovCgogICAgICBjYXNlIHBraS5vaWRzLmNlcnRCYWc6CiAgICAgICAgLyogQSBQS0NTIzEyIGNlcnRCYWcgY2FuIHdyYXAgYm90aCBYLjUwOSBhbmQgc2RzaSBjZXJ0aWZpY2F0ZXMuCiAgICAgICAgICAgVGhlcmVmb3JlIHB1dCB0aGUgU2FmZUJhZyBjb250ZW50IHRocm91Z2ggYW5vdGhlciB2YWxpZGF0b3IgdG8KICAgICAgICAgICBjYXB0dXJlIHRoZSBmaWVsZHMuICBBZnRlcndhcmRzIGNoZWNrICYgc3RvcmUgdGhlIHJlc3VsdHMuICovCiAgICAgICAgdmFsaWRhdG9yID0gY2VydEJhZ1ZhbGlkYXRvcjsKICAgICAgICBkZWNvZGVyID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICBpZihhc24xLmRlclRvT2lkKGNhcHR1cmUuY2VydElkKSAhPT0gcGtpLm9pZHMueDUwOUNlcnRpZmljYXRlKSB7CiAgICAgICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcigKICAgICAgICAgICAgICAnVW5zdXBwb3J0ZWQgY2VydGlmaWNhdGUgdHlwZSwgb25seSBYLjUwOSBzdXBwb3J0ZWQuJyk7CiAgICAgICAgICAgIGVycm9yLm9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5jZXJ0SWQpOwogICAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyB0cnVlPXByb2R1Y2UgY2VydCBoYXNoCiAgICAgICAgICB2YXIgY2VydEFzbjEgPSBhc24xLmZyb21EZXIoY2FwdHVyZS5jZXJ0LCBzdHJpY3QpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYmFnLmNlcnQgPSBwa2kuY2VydGlmaWNhdGVGcm9tQXNuMShjZXJ0QXNuMSwgdHJ1ZSk7CiAgICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgICAgLy8gaWdub3JlIHVua25vd24gY2VydCB0eXBlLCBwYXNzIGFzbjEgdmFsdWUKICAgICAgICAgICAgYmFnLmNlcnQgPSBudWxsOwogICAgICAgICAgICBiYWcuYXNuMSA9IGNlcnRBc24xOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgUEtDUyMxMiBTYWZlQmFnIHR5cGUuJyk7CiAgICAgICAgZXJyb3Iub2lkID0gYmFnLnR5cGU7CiAgICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLyogVmFsaWRhdGUgU2FmZUJhZyB2YWx1ZSAoaS5lLiBDZXJ0QmFnLCBldGMuKSBhbmQgY2FwdHVyZSBkYXRhIGlmIG5lZWRlZC4gKi8KICAgIGlmKHZhbGlkYXRvciAhPT0gdW5kZWZpbmVkICYmCiAgICAgICAhYXNuMS52YWxpZGF0ZShiYWdBc24xLCB2YWxpZGF0b3IsIGNhcHR1cmUsIGVycm9ycykpIHsKICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzEyICcgKyB2YWxpZGF0b3IubmFtZSk7CiAgICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLyogQ2FsbCBkZWNvZGVyIGZ1bmN0aW9uIGZyb20gYWJvdmUgdG8gc3RvcmUgdGhlIHJlc3VsdHMuICovCiAgICBkZWNvZGVyKCk7CiAgfQoKICByZXR1cm4gcmVzOwp9CgovKioKICogRGVjb2RlIFBLQ1MjMTIgU0VUIE9GIFBLQ1MxMkF0dHJpYnV0ZSBpbnRvIEphdmFTY3JpcHQgb2JqZWN0LgogKgogKiBAcGFyYW0gYXR0cmlidXRlcyBTRVQgT0YgUEtDUzEyQXR0cmlidXRlIChBU04uMSBvYmplY3QpLgogKgogKiBAcmV0dXJuIHRoZSBkZWNvZGVkIGF0dHJpYnV0ZXMuCiAqLwpmdW5jdGlvbiBfZGVjb2RlQmFnQXR0cmlidXRlcyhhdHRyaWJ1dGVzKSB7CiAgdmFyIGRlY29kZWRBdHRycyA9IHt9OwoKICBpZihhdHRyaWJ1dGVzICE9PSB1bmRlZmluZWQpIHsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgKytpKSB7CiAgICAgIHZhciBjYXB0dXJlID0ge307CiAgICAgIHZhciBlcnJvcnMgPSBbXTsKICAgICAgaWYoIWFzbjEudmFsaWRhdGUoYXR0cmlidXRlc1tpXSwgYXR0cmlidXRlVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzEyIEJhZ0F0dHJpYnV0ZS4nKTsKICAgICAgICBlcnJvci5lcnJvcnMgPSBlcnJvcnM7CiAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgIH0KCiAgICAgIHZhciBvaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUub2lkKTsKICAgICAgaWYocGtpLm9pZHNbb2lkXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgLy8gdW5zdXBwb3J0ZWQgYXR0cmlidXRlIHR5cGUsIGlnbm9yZS4KICAgICAgICBjb250aW51ZTsKICAgICAgfQoKICAgICAgZGVjb2RlZEF0dHJzW3BraS5vaWRzW29pZF1dID0gW107CiAgICAgIGZvcih2YXIgaiA9IDA7IGogPCBjYXB0dXJlLnZhbHVlcy5sZW5ndGg7ICsraikgewogICAgICAgIGRlY29kZWRBdHRyc1twa2kub2lkc1tvaWRdXS5wdXNoKGNhcHR1cmUudmFsdWVzW2pdLnZhbHVlKTsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIGRlY29kZWRBdHRyczsKfQoKLyoqCiAqIFdyYXBzIGEgcHJpdmF0ZSBrZXkgYW5kIGNlcnRpZmljYXRlIGluIGEgUEtDUyMxMiBQRlggd3JhcHBlci4gSWYgYQogKiBwYXNzd29yZCBpcyBwcm92aWRlZCB0aGVuIHRoZSBwcml2YXRlIGtleSB3aWxsIGJlIGVuY3J5cHRlZC4KICoKICogQW4gZW50aXJlIGNlcnRpZmljYXRlIGNoYWluIG1heSBhbHNvIGJlIGluY2x1ZGVkLiBUbyBkbyB0aGlzLCBwYXNzCiAqIGFuIGFycmF5IGZvciB0aGUgImNlcnQiIHBhcmFtZXRlciB3aGVyZSB0aGUgZmlyc3QgY2VydGlmaWNhdGUgaXMKICogdGhlIG9uZSB0aGF0IGlzIHBhaXJlZCB3aXRoIHRoZSBwcml2YXRlIGtleSBhbmQgZWFjaCBzdWJzZXF1ZW50IG9uZQogKiB2ZXJpZmllcyB0aGUgcHJldmlvdXMgb25lLiBUaGUgY2VydGlmaWNhdGVzIG1heSBiZSBpbiBQRU0gZm9ybWF0IG9yCiAqIGhhdmUgYmVlbiBhbHJlYWR5IHBhcnNlZCBieSBGb3JnZS4KICoKICogQHRvZG8gaW1wbGVtZW50IHBhc3N3b3JkLWJhc2VkLWVuY3J5cHRpb24gZm9yIHRoZSB3aG9sZSBwYWNrYWdlCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHByaXZhdGUga2V5LgogKiBAcGFyYW0gY2VydCB0aGUgY2VydGlmaWNhdGUgKG1heSBiZSBhbiBhcnJheSBvZiBjZXJ0aWZpY2F0ZXMgaW4gb3JkZXIKICogICAgICAgICAgdG8gc3BlY2lmeSBhIGNlcnRpZmljYXRlIGNoYWluKS4KICogQHBhcmFtIHBhc3N3b3JkIHRoZSBwYXNzd29yZCB0byB1c2UsIG51bGwgZm9yIG5vbmUuCiAqIEBwYXJhbSBvcHRpb25zOgogKiAgICAgICAgICBhbGdvcml0aG0gdGhlIGVuY3J5cHRpb24gYWxnb3JpdGhtIHRvIHVzZQogKiAgICAgICAgICAgICgnYWVzMTI4JywgJ2FlczE5MicsICdhZXMyNTYnLCAnM2RlcycpLCBkZWZhdWx0cyB0byAnYWVzMTI4Jy4KICogICAgICAgICAgY291bnQgdGhlIGl0ZXJhdGlvbiBjb3VudCB0byB1c2UuCiAqICAgICAgICAgIHNhbHRTaXplIHRoZSBzYWx0IHNpemUgdG8gdXNlLgogKiAgICAgICAgICB1c2VNYWMgdHJ1ZSB0byBpbmNsdWRlIGEgTUFDLCBmYWxzZSBub3QgdG8sIGRlZmF1bHRzIHRvIHRydWUuCiAqICAgICAgICAgIGxvY2FsS2V5SWQgdGhlIGxvY2FsIGtleSBJRCB0byB1c2UsIGluIGhleC4KICogICAgICAgICAgZnJpZW5kbHlOYW1lIHRoZSBmcmllbmRseSBuYW1lIHRvIHVzZS4KICogICAgICAgICAgZ2VuZXJhdGVMb2NhbEtleUlkIHRydWUgdG8gZ2VuZXJhdGUgYSByYW5kb20gbG9jYWwga2V5IElELAogKiAgICAgICAgICAgIGZhbHNlIG5vdCB0bywgZGVmYXVsdHMgdG8gdHJ1ZS4KICoKICogQHJldHVybiB0aGUgUEtDUyMxMiBQRlggQVNOLjEgb2JqZWN0LgogKi8KcDEyLnRvUGtjczEyQXNuMSA9IGZ1bmN0aW9uKGtleSwgY2VydCwgcGFzc3dvcmQsIG9wdGlvbnMpIHsKICAvLyBzZXQgZGVmYXVsdCBvcHRpb25zCiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgb3B0aW9ucy5zYWx0U2l6ZSA9IG9wdGlvbnMuc2FsdFNpemUgfHwgODsKICBvcHRpb25zLmNvdW50ID0gb3B0aW9ucy5jb3VudCB8fCAyMDQ4OwogIG9wdGlvbnMuYWxnb3JpdGhtID0gb3B0aW9ucy5hbGdvcml0aG0gfHwgb3B0aW9ucy5lbmNBbGdvcml0aG0gfHwgJ2FlczEyOCc7CiAgaWYoISgndXNlTWFjJyBpbiBvcHRpb25zKSkgewogICAgb3B0aW9ucy51c2VNYWMgPSB0cnVlOwogIH0KICBpZighKCdsb2NhbEtleUlkJyBpbiBvcHRpb25zKSkgewogICAgb3B0aW9ucy5sb2NhbEtleUlkID0gbnVsbDsKICB9CiAgaWYoISgnZ2VuZXJhdGVMb2NhbEtleUlkJyBpbiBvcHRpb25zKSkgewogICAgb3B0aW9ucy5nZW5lcmF0ZUxvY2FsS2V5SWQgPSB0cnVlOwogIH0KCiAgdmFyIGxvY2FsS2V5SWQgPSBvcHRpb25zLmxvY2FsS2V5SWQ7CiAgdmFyIGJhZ0F0dHJzOwogIGlmKGxvY2FsS2V5SWQgIT09IG51bGwpIHsKICAgIGxvY2FsS2V5SWQgPSBmb3JnZS51dGlsLmhleFRvQnl0ZXMobG9jYWxLZXlJZCk7CiAgfSBlbHNlIGlmKG9wdGlvbnMuZ2VuZXJhdGVMb2NhbEtleUlkKSB7CiAgICAvLyB1c2UgU0hBLTEgb2YgcGFpcmVkIGNlcnQsIGlmIGF2YWlsYWJsZQogICAgaWYoY2VydCkgewogICAgICB2YXIgcGFpcmVkQ2VydCA9IGZvcmdlLnV0aWwuaXNBcnJheShjZXJ0KSA/IGNlcnRbMF0gOiBjZXJ0OwogICAgICBpZih0eXBlb2YgcGFpcmVkQ2VydCA9PT0gJ3N0cmluZycpIHsKICAgICAgICBwYWlyZWRDZXJ0ID0gcGtpLmNlcnRpZmljYXRlRnJvbVBlbShwYWlyZWRDZXJ0KTsKICAgICAgfQogICAgICB2YXIgc2hhMSA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICAgIHNoYTEudXBkYXRlKGFzbjEudG9EZXIocGtpLmNlcnRpZmljYXRlVG9Bc24xKHBhaXJlZENlcnQpKS5nZXRCeXRlcygpKTsKICAgICAgbG9jYWxLZXlJZCA9IHNoYTEuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIEZJWE1FOiBjb25zaWRlciB1c2luZyBTSEEtMSBvZiBwdWJsaWMga2V5ICh3aGljaCBjYW4gYmUgZ2VuZXJhdGVkCiAgICAgIC8vIGZyb20gcHJpdmF0ZSBrZXkgY29tcG9uZW50cyksIHNlZTogY2VydC5nZW5lcmF0ZVN1YmplY3RLZXlJZGVudGlmaWVyCiAgICAgIC8vIGdlbmVyYXRlIHJhbmRvbSBieXRlcwogICAgICBsb2NhbEtleUlkID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzKDIwKTsKICAgIH0KICB9CgogIHZhciBhdHRycyA9IFtdOwogIGlmKGxvY2FsS2V5SWQgIT09IG51bGwpIHsKICAgIGF0dHJzLnB1c2goCiAgICAgIC8vIGxvY2FsS2V5SUQKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIGF0dHJJZAogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgIGFzbjEub2lkVG9EZXIocGtpLm9pZHMubG9jYWxLZXlJZCkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgLy8gYXR0clZhbHVlcwogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VULCB0cnVlLCBbCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgICAgICAgbG9jYWxLZXlJZCkKICAgICAgICBdKQogICAgICBdKSk7CiAgfQogIGlmKCdmcmllbmRseU5hbWUnIGluIG9wdGlvbnMpIHsKICAgIGF0dHJzLnB1c2goCiAgICAgIC8vIGZyaWVuZGx5TmFtZQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8gYXR0cklkCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5mcmllbmRseU5hbWUpLmdldEJ5dGVzKCkpLAogICAgICAgIC8vIGF0dHJWYWx1ZXMKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFVCwgdHJ1ZSwgWwogICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CTVBTVFJJTkcsIGZhbHNlLAogICAgICAgICAgICBvcHRpb25zLmZyaWVuZGx5TmFtZSkKICAgICAgICBdKQogICAgICBdKSk7CiAgfQoKICBpZihhdHRycy5sZW5ndGggPiAwKSB7CiAgICBiYWdBdHRycyA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VULCB0cnVlLCBhdHRycyk7CiAgfQoKICAvLyBjb2xsZWN0IGNvbnRlbnRzIGZvciBBdXRoZW50aWNhdGVkU2FmZQogIHZhciBjb250ZW50cyA9IFtdOwoKICAvLyBjcmVhdGUgc2FmZSBiYWcocykgZm9yIGNlcnRpZmljYXRlIGNoYWluCiAgdmFyIGNoYWluID0gW107CiAgaWYoY2VydCAhPT0gbnVsbCkgewogICAgaWYoZm9yZ2UudXRpbC5pc0FycmF5KGNlcnQpKSB7CiAgICAgIGNoYWluID0gY2VydDsKICAgIH0gZWxzZSB7CiAgICAgIGNoYWluID0gW2NlcnRdOwogICAgfQogIH0KCiAgdmFyIGNlcnRTYWZlQmFncyA9IFtdOwogIGZvcih2YXIgaSA9IDA7IGkgPCBjaGFpbi5sZW5ndGg7ICsraSkgewogICAgLy8gY29udmVydCBjZXJ0IGZyb20gUEVNIGFzIG5lY2Vzc2FyeQogICAgY2VydCA9IGNoYWluW2ldOwogICAgaWYodHlwZW9mIGNlcnQgPT09ICdzdHJpbmcnKSB7CiAgICAgIGNlcnQgPSBwa2kuY2VydGlmaWNhdGVGcm9tUGVtKGNlcnQpOwogICAgfQoKICAgIC8vIFNhZmVCYWcKICAgIHZhciBjZXJ0QmFnQXR0cnMgPSAoaSA9PT0gMCkgPyBiYWdBdHRycyA6IHVuZGVmaW5lZDsKICAgIHZhciBjZXJ0QXNuMSA9IHBraS5jZXJ0aWZpY2F0ZVRvQXNuMShjZXJ0KTsKICAgIHZhciBjZXJ0U2FmZUJhZyA9CiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAvLyBiYWdJZAogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgIGFzbjEub2lkVG9EZXIocGtpLm9pZHMuY2VydEJhZykuZ2V0Qnl0ZXMoKSksCiAgICAgICAgLy8gYmFnVmFsdWUKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICAgIC8vIENlcnRCYWcKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAgICAgLy8gY2VydElkCiAgICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgICAgICBhc24xLm9pZFRvRGVyKHBraS5vaWRzLng1MDlDZXJ0aWZpY2F0ZSkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgICAgIC8vIGNlcnRWYWx1ZSAoeDUwOUNlcnRpZmljYXRlKQogICAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLAogICAgICAgICAgICAgICAgYXNuMS50b0RlcihjZXJ0QXNuMSkuZ2V0Qnl0ZXMoKSkKICAgICAgICAgICAgXSldKV0pLAogICAgICAgIC8vIGJhZ0F0dHJpYnV0ZXMgKE9QVElPTkFMKQogICAgICAgIGNlcnRCYWdBdHRycwogICAgICBdKTsKICAgIGNlcnRTYWZlQmFncy5wdXNoKGNlcnRTYWZlQmFnKTsKICB9CgogIGlmKGNlcnRTYWZlQmFncy5sZW5ndGggPiAwKSB7CiAgICAvLyBTYWZlQ29udGVudHMKICAgIHZhciBjZXJ0U2FmZUNvbnRlbnRzID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIGNlcnRTYWZlQmFncyk7CgogICAgLy8gQ29udGVudEluZm8KICAgIHZhciBjZXJ0Q0kgPQogICAgICAvLyBQS0NTIzcgQ29udGVudEluZm8KICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIGNvbnRlbnRUeXBlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgLy8gT0lEIGZvciB0aGUgY29udGVudCB0eXBlIGlzICdkYXRhJwogICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5kYXRhKS5nZXRCeXRlcygpKSwKICAgICAgICAvLyBjb250ZW50CiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbCiAgICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsCiAgICAgICAgICAgIGFzbjEudG9EZXIoY2VydFNhZmVDb250ZW50cykuZ2V0Qnl0ZXMoKSkKICAgICAgICBdKQogICAgICBdKTsKICAgIGNvbnRlbnRzLnB1c2goY2VydENJKTsKICB9CgogIC8vIGNyZWF0ZSBzYWZlIGNvbnRlbnRzIGZvciBwcml2YXRlIGtleQogIHZhciBrZXlCYWcgPSBudWxsOwogIGlmKGtleSAhPT0gbnVsbCkgewogICAgLy8gU2FmZUJhZwogICAgdmFyIHBrQXNuMSA9IHBraS53cmFwUnNhUHJpdmF0ZUtleShwa2kucHJpdmF0ZUtleVRvQXNuMShrZXkpKTsKICAgIGlmKHBhc3N3b3JkID09PSBudWxsKSB7CiAgICAgIC8vIG5vIGVuY3J5cHRpb24KICAgICAga2V5QmFnID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIGJhZ0lkCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5rZXlCYWcpLmdldEJ5dGVzKCkpLAogICAgICAgIC8vIGJhZ1ZhbHVlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbCiAgICAgICAgICAvLyBQcml2YXRlS2V5SW5mbwogICAgICAgICAgcGtBc24xCiAgICAgICAgXSksCiAgICAgICAgLy8gYmFnQXR0cmlidXRlcyAoT1BUSU9OQUwpCiAgICAgICAgYmFnQXR0cnMKICAgICAgXSk7CiAgICB9IGVsc2UgewogICAgICAvLyBlbmNyeXB0ZWQgUHJpdmF0ZUtleUluZm8KICAgICAga2V5QmFnID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIGJhZ0lkCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5wa2NzOFNocm91ZGVkS2V5QmFnKS5nZXRCeXRlcygpKSwKICAgICAgICAvLyBiYWdWYWx1ZQogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgWwogICAgICAgICAgLy8gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8KICAgICAgICAgIHBraS5lbmNyeXB0UHJpdmF0ZUtleUluZm8ocGtBc24xLCBwYXNzd29yZCwgb3B0aW9ucykKICAgICAgICBdKSwKICAgICAgICAvLyBiYWdBdHRyaWJ1dGVzIChPUFRJT05BTCkKICAgICAgICBiYWdBdHRycwogICAgICBdKTsKICAgIH0KCiAgICAvLyBTYWZlQ29udGVudHMKICAgIHZhciBrZXlTYWZlQ29udGVudHMgPQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBba2V5QmFnXSk7CgogICAgLy8gQ29udGVudEluZm8KICAgIHZhciBrZXlDSSA9CiAgICAgIC8vIFBLQ1MjNyBDb250ZW50SW5mbwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8gY29udGVudFR5cGUKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgICAvLyBPSUQgZm9yIHRoZSBjb250ZW50IHR5cGUgaXMgJ2RhdGEnCiAgICAgICAgICBhc24xLm9pZFRvRGVyKHBraS5vaWRzLmRhdGEpLmdldEJ5dGVzKCkpLAogICAgICAgIC8vIGNvbnRlbnQKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICAgIGFzbjEuY3JlYXRlKAogICAgICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgICAgICAgYXNuMS50b0RlcihrZXlTYWZlQ29udGVudHMpLmdldEJ5dGVzKCkpCiAgICAgICAgXSkKICAgICAgXSk7CiAgICBjb250ZW50cy5wdXNoKGtleUNJKTsKICB9CgogIC8vIGNyZWF0ZSBBdXRoZW50aWNhdGVkU2FmZSBieSBzdHJpbmdpbmcgdG9nZXRoZXIgdGhlIGNvbnRlbnRzCiAgdmFyIHNhZmUgPSBhc24xLmNyZWF0ZSgKICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIGNvbnRlbnRzKTsKCiAgdmFyIG1hY0RhdGE7CiAgaWYob3B0aW9ucy51c2VNYWMpIHsKICAgIC8vIE1hY0RhdGEKICAgIHZhciBzaGExID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICAgIHZhciBtYWNTYWx0ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigKICAgICAgZm9yZ2UucmFuZG9tLmdldEJ5dGVzKG9wdGlvbnMuc2FsdFNpemUpKTsKICAgIHZhciBjb3VudCA9IG9wdGlvbnMuY291bnQ7CiAgICAvLyAxNjAtYml0IGtleQogICAgdmFyIGtleSA9IHAxMi5nZW5lcmF0ZUtleShwYXNzd29yZCwgbWFjU2FsdCwgMywgY291bnQsIDIwKTsKICAgIHZhciBtYWMgPSBmb3JnZS5obWFjLmNyZWF0ZSgpOwogICAgbWFjLnN0YXJ0KHNoYTEsIGtleSk7CiAgICBtYWMudXBkYXRlKGFzbjEudG9EZXIoc2FmZSkuZ2V0Qnl0ZXMoKSk7CiAgICB2YXIgbWFjVmFsdWUgPSBtYWMuZ2V0TWFjKCk7CiAgICBtYWNEYXRhID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAvLyBtYWMgRGlnZXN0SW5mbwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8gZGlnZXN0QWxnb3JpdGhtCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgICAgLy8gYWxnb3JpdGhtID0gU0hBLTEKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5zaGExKS5nZXRCeXRlcygpKSwKICAgICAgICAgIC8vIHBhcmFtZXRlcnMgPSBOdWxsCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgICAgICBdKSwKICAgICAgICAvLyBkaWdlc3QKICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsCiAgICAgICAgICBmYWxzZSwgbWFjVmFsdWUuZ2V0Qnl0ZXMoKSkKICAgICAgXSksCiAgICAgIC8vIG1hY1NhbHQgT0NURVQgU1RSSU5HCiAgICAgIGFzbjEuY3JlYXRlKAogICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLCBtYWNTYWx0LmdldEJ5dGVzKCkpLAogICAgICAvLyBpdGVyYXRpb25zIElOVEVHRVIgKFhYWDogT25seSBzdXBwb3J0IGNvdW50IDwgNjU1MzYpCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIoY291bnQpLmdldEJ5dGVzKCkKICAgICAgKQogICAgXSk7CiAgfQoKICAvLyBQRlgKICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gdmVyc2lvbiAoMykKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIGFzbjEuaW50ZWdlclRvRGVyKDMpLmdldEJ5dGVzKCkpLAogICAgLy8gUEtDUyM3IENvbnRlbnRJbmZvCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIGNvbnRlbnRUeXBlCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAvLyBPSUQgZm9yIHRoZSBjb250ZW50IHR5cGUgaXMgJ2RhdGEnCiAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5kYXRhKS5nZXRCeXRlcygpKSwKICAgICAgLy8gY29udGVudAogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLAogICAgICAgICAgYXNuMS50b0RlcihzYWZlKS5nZXRCeXRlcygpKQogICAgICBdKQogICAgXSksCiAgICBtYWNEYXRhCiAgXSk7Cn07CgovKioKICogRGVyaXZlcyBhIFBLQ1MjMTIga2V5LgogKgogKiBAcGFyYW0gcGFzc3dvcmQgdGhlIHBhc3N3b3JkIHRvIGRlcml2ZSB0aGUga2V5IG1hdGVyaWFsIGZyb20sIG51bGwgb3IKICogICAgICAgICAgdW5kZWZpbmVkIGZvciBub25lLgogKiBAcGFyYW0gc2FsdCB0aGUgc2FsdCwgYXMgYSBCeXRlQnVmZmVyLCB0byB1c2UuCiAqIEBwYXJhbSBpZCB0aGUgUEtDUyMxMiBJRCBieXRlICgxID0ga2V5IG1hdGVyaWFsLCAyID0gSVYsIDMgPSBNQUMpLgogKiBAcGFyYW0gaXRlciB0aGUgaXRlcmF0aW9uIGNvdW50LgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGRlcml2ZSBmcm9tIHRoZSBwYXNzd29yZC4KICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCB0byB1c2UsIGRlZmF1bHRzIHRvIFNIQS0xLgogKgogKiBAcmV0dXJuIGEgQnl0ZUJ1ZmZlciB3aXRoIHRoZSBieXRlcyBkZXJpdmVkIGZyb20gdGhlIHBhc3N3b3JkLgogKi8KcDEyLmdlbmVyYXRlS2V5ID0gZm9yZ2UucGJlLmdlbmVyYXRlUGtjczEyS2V5OwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncGtjczEyJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3BrY3MxMicsWwogICdyZXF1aXJlJywKICAnbW9kdWxlJywKICAnLi9hc24xJywKICAnLi9obWFjJywKICAnLi9vaWRzJywKICAnLi9wa2NzN2FzbjEnLAogICcuL3BiZScsCiAgJy4vcmFuZG9tJywKICAnLi9yc2EnLAogICcuL3NoYTEnLAogICcuL3V0aWwnLAogICcuL3g1MDknCl0sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgYSBiYXNpYyBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLCBpbmNsdWRpbmcKICogc3VwcG9ydCBmb3IgUlNBIHB1YmxpYyBhbmQgcHJpdmF0ZSBrZXlzLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxMyBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIHNob3J0Y3V0IGZvciBhc24uMSBBUEkKdmFyIGFzbjEgPSBmb3JnZS5hc24xOwoKLyogUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZSAoUEtJKSBpbXBsZW1lbnRhdGlvbi4gKi8KdmFyIHBraSA9IGZvcmdlLnBraSA9IGZvcmdlLnBraSB8fCB7fTsKCi8qKgogKiBOT1RFOiBUSElTIE1FVEhPRCBJUyBERVBSRUNBVEVELiBVc2UgcGVtLmRlY29kZSgpIGluc3RlYWQuCiAqCiAqIENvbnZlcnRzIFBFTS1mb3JtYXR0ZWQgZGF0YSB0byBERVIuCiAqCiAqIEBwYXJhbSBwZW0gdGhlIFBFTS1mb3JtYXR0ZWQgZGF0YS4KICoKICogQHJldHVybiB0aGUgREVSLWZvcm1hdHRlZCBkYXRhLgogKi8KcGtpLnBlbVRvRGVyID0gZnVuY3Rpb24ocGVtKSB7CiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IFBFTSB0byBERVI7IFBFTSBpcyBlbmNyeXB0ZWQuJyk7CiAgfQogIHJldHVybiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihtc2cuYm9keSk7Cn07CgovKioKICogQ29udmVydHMgYW4gUlNBIHByaXZhdGUga2V5IGZyb20gUEVNIGZvcm1hdC4KICoKICogQHBhcmFtIHBlbSB0aGUgUEVNLWZvcm1hdHRlZCBwcml2YXRlIGtleS4KICoKICogQHJldHVybiB0aGUgcHJpdmF0ZSBrZXkuCiAqLwpwa2kucHJpdmF0ZUtleUZyb21QZW0gPSBmdW5jdGlvbihwZW0pIHsKICB2YXIgbXNnID0gZm9yZ2UucGVtLmRlY29kZShwZW0pWzBdOwoKICBpZihtc2cudHlwZSAhPT0gJ1BSSVZBVEUgS0VZJyAmJiBtc2cudHlwZSAhPT0gJ1JTQSBQUklWQVRFIEtFWScpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ291bGQgbm90IGNvbnZlcnQgcHJpdmF0ZSBrZXkgZnJvbSBQRU07IFBFTSAnICsKICAgICAgJ2hlYWRlciB0eXBlIGlzIG5vdCAiUFJJVkFURSBLRVkiIG9yICJSU0EgUFJJVkFURSBLRVkiLicpOwogICAgZXJyb3IuaGVhZGVyVHlwZSA9IG1zZy50eXBlOwogICAgdGhyb3cgZXJyb3I7CiAgfQogIGlmKG1zZy5wcm9jVHlwZSAmJiBtc2cucHJvY1R5cGUudHlwZSA9PT0gJ0VOQ1JZUFRFRCcpIHsKICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGNvbnZlcnQgcHJpdmF0ZSBrZXkgZnJvbSBQRU07IFBFTSBpcyBlbmNyeXB0ZWQuJyk7CiAgfQoKICAvLyBjb252ZXJ0IERFUiB0byBBU04uMSBvYmplY3QKICB2YXIgb2JqID0gYXNuMS5mcm9tRGVyKG1zZy5ib2R5KTsKCiAgcmV0dXJuIHBraS5wcml2YXRlS2V5RnJvbUFzbjEob2JqKTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhbiBSU0EgcHJpdmF0ZSBrZXkgdG8gUEVNIGZvcm1hdC4KICoKICogQHBhcmFtIGtleSB0aGUgcHJpdmF0ZSBrZXkuCiAqIEBwYXJhbSBtYXhsaW5lIHRoZSBtYXhpbXVtIGNoYXJhY3RlcnMgcGVyIGxpbmUsIGRlZmF1bHRzIHRvIDY0LgogKgogKiBAcmV0dXJuIHRoZSBQRU0tZm9ybWF0dGVkIHByaXZhdGUga2V5LgogKi8KcGtpLnByaXZhdGVLZXlUb1BlbSA9IGZ1bmN0aW9uKGtleSwgbWF4bGluZSkgewogIC8vIGNvbnZlcnQgdG8gQVNOLjEsIHRoZW4gREVSLCB0aGVuIFBFTS1lbmNvZGUKICB2YXIgbXNnID0gewogICAgdHlwZTogJ1JTQSBQUklWQVRFIEtFWScsCiAgICBib2R5OiBhc24xLnRvRGVyKHBraS5wcml2YXRlS2V5VG9Bc24xKGtleSkpLmdldEJ5dGVzKCkKICB9OwogIHJldHVybiBmb3JnZS5wZW0uZW5jb2RlKG1zZywge21heGxpbmU6IG1heGxpbmV9KTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIFByaXZhdGVLZXlJbmZvIHRvIFBFTSBmb3JtYXQuCiAqCiAqIEBwYXJhbSBwa2kgdGhlIFByaXZhdGVLZXlJbmZvLgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lLCBkZWZhdWx0cyB0byA2NC4KICoKICogQHJldHVybiB0aGUgUEVNLWZvcm1hdHRlZCBwcml2YXRlIGtleS4KICovCnBraS5wcml2YXRlS2V5SW5mb1RvUGVtID0gZnVuY3Rpb24ocGtpLCBtYXhsaW5lKSB7CiAgLy8gY29udmVydCB0byBERVIsIHRoZW4gUEVNLWVuY29kZQogIHZhciBtc2cgPSB7CiAgICB0eXBlOiAnUFJJVkFURSBLRVknLAogICAgYm9keTogYXNuMS50b0Rlcihwa2kpLmdldEJ5dGVzKCkKICB9OwogIHJldHVybiBmb3JnZS5wZW0uZW5jb2RlKG1zZywge21heGxpbmU6IG1heGxpbmV9KTsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3BraSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9wa2knLFsKICAncmVxdWlyZScsCiAgJ21vZHVsZScsCiAgJy4vYXNuMScsCiAgJy4vb2lkcycsCiAgJy4vcGJlJywKICAnLi9wZW0nLAogICcuL3Bia2RmMicsCiAgJy4vcGtjczEyJywKICAnLi9wc3MnLAogICcuL3JzYScsCiAgJy4vdXRpbCcsCiAgJy4veDUwOScKXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogQSBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIFRyYW5zcG9ydCBMYXllciBTZWN1cml0eSAoVExTKS4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDA5LTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICoKICogVGhlIFRMUyBIYW5kc2hha2UgUHJvdG9jb2wgaW52b2x2ZXMgdGhlIGZvbGxvd2luZyBzdGVwczoKICoKICogLSBFeGNoYW5nZSBoZWxsbyBtZXNzYWdlcyB0byBhZ3JlZSBvbiBhbGdvcml0aG1zLCBleGNoYW5nZSByYW5kb20gdmFsdWVzLAogKiBhbmQgY2hlY2sgZm9yIHNlc3Npb24gcmVzdW1wdGlvbi4KICoKICogLSBFeGNoYW5nZSB0aGUgbmVjZXNzYXJ5IGNyeXB0b2dyYXBoaWMgcGFyYW1ldGVycyB0byBhbGxvdyB0aGUgY2xpZW50IGFuZAogKiBzZXJ2ZXIgdG8gYWdyZWUgb24gYSBwcmVtYXN0ZXIgc2VjcmV0LgogKgogKiAtIEV4Y2hhbmdlIGNlcnRpZmljYXRlcyBhbmQgY3J5cHRvZ3JhcGhpYyBpbmZvcm1hdGlvbiB0byBhbGxvdyB0aGUgY2xpZW50CiAqIGFuZCBzZXJ2ZXIgdG8gYXV0aGVudGljYXRlIHRoZW1zZWx2ZXMuCiAqCiAqIC0gR2VuZXJhdGUgYSBtYXN0ZXIgc2VjcmV0IGZyb20gdGhlIHByZW1hc3RlciBzZWNyZXQgYW5kIGV4Y2hhbmdlZCByYW5kb20KICogdmFsdWVzLgogKgogKiAtIFByb3ZpZGUgc2VjdXJpdHkgcGFyYW1ldGVycyB0byB0aGUgcmVjb3JkIGxheWVyLgogKgogKiAtIEFsbG93IHRoZSBjbGllbnQgYW5kIHNlcnZlciB0byB2ZXJpZnkgdGhhdCB0aGVpciBwZWVyIGhhcyBjYWxjdWxhdGVkIHRoZQogKiBzYW1lIHNlY3VyaXR5IHBhcmFtZXRlcnMgYW5kIHRoYXQgdGhlIGhhbmRzaGFrZSBvY2N1cnJlZCB3aXRob3V0IHRhbXBlcmluZwogKiBieSBhbiBhdHRhY2tlci4KICoKICogVXAgdG8gNCBkaWZmZXJlbnQgbWVzc2FnZXMgbWF5IGJlIHNlbnQgZHVyaW5nIGEga2V5IGV4Y2hhbmdlLiBUaGUgc2VydmVyCiAqIGNlcnRpZmljYXRlLCB0aGUgc2VydmVyIGtleSBleGNoYW5nZSwgdGhlIGNsaWVudCBjZXJ0aWZpY2F0ZSwgYW5kIHRoZQogKiBjbGllbnQga2V5IGV4Y2hhbmdlLgogKgogKiBBIHR5cGljYWwgaGFuZHNoYWtlIChmcm9tIHRoZSBjbGllbnQncyBwZXJzcGVjdGl2ZSkuCiAqCiAqIDEuIENsaWVudCBzZW5kcyBDbGllbnRIZWxsby4KICogMi4gQ2xpZW50IHJlY2VpdmVzIFNlcnZlckhlbGxvLgogKiAzLiBDbGllbnQgcmVjZWl2ZXMgb3B0aW9uYWwgQ2VydGlmaWNhdGUuCiAqIDQuIENsaWVudCByZWNlaXZlcyBvcHRpb25hbCBTZXJ2ZXJLZXlFeGNoYW5nZS4KICogNS4gQ2xpZW50IHJlY2VpdmVzIFNlcnZlckhlbGxvRG9uZS4KICogNi4gQ2xpZW50IHNlbmRzIG9wdGlvbmFsIENlcnRpZmljYXRlLgogKiA3LiBDbGllbnQgc2VuZHMgQ2xpZW50S2V5RXhjaGFuZ2UuCiAqIDguIENsaWVudCBzZW5kcyBvcHRpb25hbCBDZXJ0aWZpY2F0ZVZlcmlmeS4KICogOS4gQ2xpZW50IHNlbmRzIENoYW5nZUNpcGhlclNwZWMuCiAqIDEwLiBDbGllbnQgc2VuZHMgRmluaXNoZWQuCiAqIDExLiBDbGllbnQgcmVjZWl2ZXMgQ2hhbmdlQ2lwaGVyU3BlYy4KICogMTIuIENsaWVudCByZWNlaXZlcyBGaW5pc2hlZC4KICogMTMuIENsaWVudCBzZW5kcy9yZWNlaXZlcyBhcHBsaWNhdGlvbiBkYXRhLgogKgogKiBUbyByZXVzZSBhbiBleGlzdGluZyBzZXNzaW9uOgogKgogKiAxLiBDbGllbnQgc2VuZHMgQ2xpZW50SGVsbG8gd2l0aCBzZXNzaW9uIElEIGZvciByZXVzZS4KICogMi4gQ2xpZW50IHJlY2VpdmVzIFNlcnZlckhlbGxvIHdpdGggc2FtZSBzZXNzaW9uIElEIGlmIHJldXNpbmcuCiAqIDMuIENsaWVudCByZWNlaXZlcyBDaGFuZ2VDaXBoZXJTcGVjIG1lc3NhZ2UgaWYgcmV1c2luZy4KICogNC4gQ2xpZW50IHJlY2VpdmVzIEZpbmlzaGVkLgogKiA1LiBDbGllbnQgc2VuZHMgQ2hhbmdlQ2lwaGVyU3BlYy4KICogNi4gQ2xpZW50IHNlbmRzIEZpbmlzaGVkLgogKgogKiBOb3RlOiBDbGllbnQgaWdub3JlcyBIZWxsb1JlcXVlc3QgaWYgaW4gdGhlIG1pZGRsZSBvZiBhIGhhbmRzaGFrZS4KICoKICogUmVjb3JkIExheWVyOgogKgogKiBUaGUgcmVjb3JkIGxheWVyIGZyYWdtZW50cyBpbmZvcm1hdGlvbiBibG9ja3MgaW50byBUTFNQbGFpbnRleHQgcmVjb3JkcwogKiBjYXJyeWluZyBkYXRhIGluIGNodW5rcyBvZiAyXjE0IGJ5dGVzIG9yIGxlc3MuIENsaWVudCBtZXNzYWdlIGJvdW5kYXJpZXMgYXJlCiAqIG5vdCBwcmVzZXJ2ZWQgaW4gdGhlIHJlY29yZCBsYXllciAoaS5lLiwgbXVsdGlwbGUgY2xpZW50IG1lc3NhZ2VzIG9mIHRoZQogKiBzYW1lIENvbnRlbnRUeXBlIE1BWSBiZSBjb2FsZXNjZWQgaW50byBhIHNpbmdsZSBUTFNQbGFpbnRleHQgcmVjb3JkLCBvciBhCiAqIHNpbmdsZSBtZXNzYWdlIE1BWSBiZSBmcmFnbWVudGVkIGFjcm9zcyBzZXZlcmFsIHJlY29yZHMpLgogKgogKiBzdHJ1Y3QgewogKiAgIHVpbnQ4IG1ham9yOwogKiAgIHVpbnQ4IG1pbm9yOwogKiB9IFByb3RvY29sVmVyc2lvbjsKICoKICogc3RydWN0IHsKICogICBDb250ZW50VHlwZSB0eXBlOwogKiAgIFByb3RvY29sVmVyc2lvbiB2ZXJzaW9uOwogKiAgIHVpbnQxNiBsZW5ndGg7CiAqICAgb3BhcXVlIGZyYWdtZW50W1RMU1BsYWludGV4dC5sZW5ndGhdOwogKiB9IFRMU1BsYWludGV4dDsKICoKICogdHlwZToKICogICBUaGUgaGlnaGVyLWxldmVsIHByb3RvY29sIHVzZWQgdG8gcHJvY2VzcyB0aGUgZW5jbG9zZWQgZnJhZ21lbnQuCiAqCiAqIHZlcnNpb246CiAqICAgVGhlIHZlcnNpb24gb2YgdGhlIHByb3RvY29sIGJlaW5nIGVtcGxveWVkLiBUTFMgVmVyc2lvbiAxLjIgdXNlcyB2ZXJzaW9uCiAqICAgezMsIDN9LiBUTFMgVmVyc2lvbiAxLjAgdXNlcyB2ZXJzaW9uIHszLCAxfS4gTm90ZSB0aGF0IGEgY2xpZW50IHRoYXQKICogICBzdXBwb3J0cyBtdWx0aXBsZSB2ZXJzaW9ucyBvZiBUTFMgbWF5IG5vdCBrbm93IHdoYXQgdmVyc2lvbiB3aWxsIGJlCiAqICAgZW1wbG95ZWQgYmVmb3JlIGl0IHJlY2VpdmVzIHRoZSBTZXJ2ZXJIZWxsby4KICoKICogbGVuZ3RoOgogKiAgIFRoZSBsZW5ndGggKGluIGJ5dGVzKSBvZiB0aGUgZm9sbG93aW5nIFRMU1BsYWludGV4dC5mcmFnbWVudC4gVGhlIGxlbmd0aAogKiAgIE1VU1QgTk9UIGV4Y2VlZCAyXjE0ID0gMTYzODQgYnl0ZXMuCiAqCiAqIGZyYWdtZW50OgogKiAgIFRoZSBhcHBsaWNhdGlvbiBkYXRhLiBUaGlzIGRhdGEgaXMgdHJhbnNwYXJlbnQgYW5kIHRyZWF0ZWQgYXMgYW4KICogICBpbmRlcGVuZGVudCBibG9jayB0byBiZSBkZWFsdCB3aXRoIGJ5IHRoZSBoaWdoZXItbGV2ZWwgcHJvdG9jb2wgc3BlY2lmaWVkCiAqICAgYnkgdGhlIHR5cGUgZmllbGQuCiAqCiAqIEltcGxlbWVudGF0aW9ucyBNVVNUIE5PVCBzZW5kIHplcm8tbGVuZ3RoIGZyYWdtZW50cyBvZiBIYW5kc2hha2UsIEFsZXJ0LCBvcgogKiBDaGFuZ2VDaXBoZXJTcGVjIGNvbnRlbnQgdHlwZXMuIFplcm8tbGVuZ3RoIGZyYWdtZW50cyBvZiBBcHBsaWNhdGlvbiBkYXRhCiAqIE1BWSBiZSBzZW50IGFzIHRoZXkgYXJlIHBvdGVudGlhbGx5IHVzZWZ1bCBhcyBhIHRyYWZmaWMgYW5hbHlzaXMKICogY291bnRlcm1lYXN1cmUuCiAqCiAqIE5vdGU6IERhdGEgb2YgZGlmZmVyZW50IFRMUyByZWNvcmQgbGF5ZXIgY29udGVudCB0eXBlcyBNQVkgYmUgaW50ZXJsZWF2ZWQuCiAqIEFwcGxpY2F0aW9uIGRhdGEgaXMgZ2VuZXJhbGx5IG9mIGxvd2VyIHByZWNlZGVuY2UgZm9yIHRyYW5zbWlzc2lvbiB0aGFuCiAqIG90aGVyIGNvbnRlbnQgdHlwZXMuIEhvd2V2ZXIsIHJlY29yZHMgTVVTVCBiZSBkZWxpdmVyZWQgdG8gdGhlIG5ldHdvcmsgaW4KICogdGhlIHNhbWUgb3JkZXIgYXMgdGhleSBhcmUgcHJvdGVjdGVkIGJ5IHRoZSByZWNvcmQgbGF5ZXIuIFJlY2lwaWVudHMgTVVTVAogKiByZWNlaXZlIGFuZCBwcm9jZXNzIGludGVybGVhdmVkIGFwcGxpY2F0aW9uIGxheWVyIHRyYWZmaWMgZHVyaW5nIGhhbmRzaGFrZXMKICogc3Vic2VxdWVudCB0byB0aGUgZmlyc3Qgb25lIG9uIGEgY29ubmVjdGlvbi4KICoKICogc3RydWN0IHsKICogICBDb250ZW50VHlwZSB0eXBlOyAgICAgICAvLyBzYW1lIGFzIFRMU1BsYWludGV4dC50eXBlCiAqICAgUHJvdG9jb2xWZXJzaW9uIHZlcnNpb247Ly8gc2FtZSBhcyBUTFNQbGFpbnRleHQudmVyc2lvbgogKiAgIHVpbnQxNiBsZW5ndGg7CiAqICAgb3BhcXVlIGZyYWdtZW50W1RMU0NvbXByZXNzZWQubGVuZ3RoXTsKICogfSBUTFNDb21wcmVzc2VkOwogKgogKiBsZW5ndGg6CiAqICAgVGhlIGxlbmd0aCAoaW4gYnl0ZXMpIG9mIHRoZSBmb2xsb3dpbmcgVExTQ29tcHJlc3NlZC5mcmFnbWVudC4KICogICBUaGUgbGVuZ3RoIE1VU1QgTk9UIGV4Y2VlZCAyXjE0ICsgMTAyNC4KICoKICogZnJhZ21lbnQ6CiAqICAgVGhlIGNvbXByZXNzZWQgZm9ybSBvZiBUTFNQbGFpbnRleHQuZnJhZ21lbnQuCiAqCiAqIE5vdGU6IEEgQ29tcHJlc3Npb25NZXRob2QubnVsbCBvcGVyYXRpb24gaXMgYW4gaWRlbnRpdHkgb3BlcmF0aW9uOyBubyBmaWVsZHMKICogYXJlIGFsdGVyZWQuIEluIHRoaXMgaW1wbGVtZW50YXRpb24sIHNpbmNlIG5vIGNvbXByZXNzaW9uIGlzIHN1cHBvcnRlZCwKICogdW5jb21wcmVzc2VkIHJlY29yZHMgYXJlIGFsd2F5cyB0aGUgc2FtZSBhcyBjb21wcmVzc2VkIHJlY29yZHMuCiAqCiAqIEVuY3J5cHRpb24gSW5mb3JtYXRpb246CiAqCiAqIFRoZSBlbmNyeXB0aW9uIGFuZCBNQUMgZnVuY3Rpb25zIHRyYW5zbGF0ZSBhIFRMU0NvbXByZXNzZWQgc3RydWN0dXJlIGludG8gYQogKiBUTFNDaXBoZXJ0ZXh0LiBUaGUgZGVjcnlwdGlvbiBmdW5jdGlvbnMgcmV2ZXJzZSB0aGUgcHJvY2Vzcy4gVGhlIE1BQyBvZiB0aGUKICogcmVjb3JkIGFsc28gaW5jbHVkZXMgYSBzZXF1ZW5jZSBudW1iZXIgc28gdGhhdCBtaXNzaW5nLCBleHRyYSwgb3IgcmVwZWF0ZWQKICogbWVzc2FnZXMgYXJlIGRldGVjdGFibGUuCiAqCiAqIHN0cnVjdCB7CiAqICAgQ29udGVudFR5cGUgdHlwZTsKICogICBQcm90b2NvbFZlcnNpb24gdmVyc2lvbjsKICogICB1aW50MTYgbGVuZ3RoOwogKiAgIHNlbGVjdCAoU2VjdXJpdHlQYXJhbWV0ZXJzLmNpcGhlcl90eXBlKSB7CiAqICAgICBjYXNlIHN0cmVhbTogR2VuZXJpY1N0cmVhbUNpcGhlcjsKICogICAgIGNhc2UgYmxvY2s6ICBHZW5lcmljQmxvY2tDaXBoZXI7CiAqICAgICBjYXNlIGFlYWQ6ICAgR2VuZXJpY0FFQURDaXBoZXI7CiAqICAgfSBmcmFnbWVudDsKICogfSBUTFNDaXBoZXJ0ZXh0OwogKgogKiB0eXBlOgogKiAgIFRoZSB0eXBlIGZpZWxkIGlzIGlkZW50aWNhbCB0byBUTFNDb21wcmVzc2VkLnR5cGUuCiAqCiAqIHZlcnNpb246CiAqICAgVGhlIHZlcnNpb24gZmllbGQgaXMgaWRlbnRpY2FsIHRvIFRMU0NvbXByZXNzZWQudmVyc2lvbi4KICoKICogbGVuZ3RoOgogKiAgIFRoZSBsZW5ndGggKGluIGJ5dGVzKSBvZiB0aGUgZm9sbG93aW5nIFRMU0NpcGhlcnRleHQuZnJhZ21lbnQuCiAqICAgVGhlIGxlbmd0aCBNVVNUIE5PVCBleGNlZWQgMl4xNCArIDIwNDguCiAqCiAqIGZyYWdtZW50OgogKiAgIFRoZSBlbmNyeXB0ZWQgZm9ybSBvZiBUTFNDb21wcmVzc2VkLmZyYWdtZW50LCB3aXRoIHRoZSBNQUMuCiAqCiAqIE5vdGU6IE9ubHkgQ0JDIEJsb2NrIENpcGhlcnMgYXJlIHN1cHBvcnRlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uLgogKgogKiBUaGUgVExTQ29tcHJlc3NlZC5mcmFnbWVudCBzdHJ1Y3R1cmVzIGFyZSBjb252ZXJ0ZWQgdG8vZnJvbSBibG9jawogKiBUTFNDaXBoZXJ0ZXh0LmZyYWdtZW50IHN0cnVjdHVyZXMuCiAqCiAqIHN0cnVjdCB7CiAqICAgb3BhcXVlIElWW1NlY3VyaXR5UGFyYW1ldGVycy5yZWNvcmRfaXZfbGVuZ3RoXTsKICogICBibG9jay1jaXBoZXJlZCBzdHJ1Y3QgewogKiAgICAgb3BhcXVlIGNvbnRlbnRbVExTQ29tcHJlc3NlZC5sZW5ndGhdOwogKiAgICAgb3BhcXVlIE1BQ1tTZWN1cml0eVBhcmFtZXRlcnMubWFjX2xlbmd0aF07CiAqICAgICB1aW50OCBwYWRkaW5nW0dlbmVyaWNCbG9ja0NpcGhlci5wYWRkaW5nX2xlbmd0aF07CiAqICAgICB1aW50OCBwYWRkaW5nX2xlbmd0aDsKICogICB9OwogKiB9IEdlbmVyaWNCbG9ja0NpcGhlcjsKICoKICogVGhlIE1BQyBpcyBnZW5lcmF0ZWQgYXMgZGVzY3JpYmVkIGluIFNlY3Rpb24gNi4yLjMuMS4KICoKICogSVY6CiAqICAgVGhlIEluaXRpYWxpemF0aW9uIFZlY3RvciAoSVYpIFNIT1VMRCBiZSBjaG9zZW4gYXQgcmFuZG9tLCBhbmQgTVVTVCBiZQogKiAgIHVucHJlZGljdGFibGUuIE5vdGUgdGhhdCBpbiB2ZXJzaW9ucyBvZiBUTFMgcHJpb3IgdG8gMS4xLCB0aGVyZSB3YXMgbm8KICogICBJViBmaWVsZCwgYW5kIHRoZSBsYXN0IGNpcGhlcnRleHQgYmxvY2sgb2YgdGhlIHByZXZpb3VzIHJlY29yZCAodGhlICJDQkMKICogICByZXNpZHVlIikgd2FzIHVzZWQgYXMgdGhlIElWLiBUaGlzIHdhcyBjaGFuZ2VkIHRvIHByZXZlbnQgdGhlIGF0dGFja3MKICogICBkZXNjcmliZWQgaW4gW0NCQ0FUVF0uIEZvciBibG9jayBjaXBoZXJzLCB0aGUgSVYgbGVuZ3RoIGlzIG9mIGxlbmd0aAogKiAgIFNlY3VyaXR5UGFyYW1ldGVycy5yZWNvcmRfaXZfbGVuZ3RoLCB3aGljaCBpcyBlcXVhbCB0byB0aGUKICogICBTZWN1cml0eVBhcmFtZXRlcnMuYmxvY2tfc2l6ZS4KICoKICogcGFkZGluZzoKICogICBQYWRkaW5nIHRoYXQgaXMgYWRkZWQgdG8gZm9yY2UgdGhlIGxlbmd0aCBvZiB0aGUgcGxhaW50ZXh0IHRvIGJlIGFuCiAqICAgaW50ZWdyYWwgbXVsdGlwbGUgb2YgdGhlIGJsb2NrIGNpcGhlcidzIGJsb2NrIGxlbmd0aC4gVGhlIHBhZGRpbmcgTUFZIGJlCiAqICAgYW55IGxlbmd0aCB1cCB0byAyNTUgYnl0ZXMsIGFzIGxvbmcgYXMgaXQgcmVzdWx0cyBpbiB0aGUKICogICBUTFNDaXBoZXJ0ZXh0Lmxlbmd0aCBiZWluZyBhbiBpbnRlZ3JhbCBtdWx0aXBsZSBvZiB0aGUgYmxvY2sgbGVuZ3RoLgogKiAgIExlbmd0aHMgbG9uZ2VyIHRoYW4gbmVjZXNzYXJ5IG1pZ2h0IGJlIGRlc2lyYWJsZSB0byBmcnVzdHJhdGUgYXR0YWNrcyBvbgogKiAgIGEgcHJvdG9jb2wgdGhhdCBhcmUgYmFzZWQgb24gYW5hbHlzaXMgb2YgdGhlIGxlbmd0aHMgb2YgZXhjaGFuZ2VkCiAqICAgbWVzc2FnZXMuIEVhY2ggdWludDggaW4gdGhlIHBhZGRpbmcgZGF0YSB2ZWN0b3IgTVVTVCBiZSBmaWxsZWQgd2l0aCB0aGUKICogICBwYWRkaW5nIGxlbmd0aCB2YWx1ZS4gVGhlIHJlY2VpdmVyIE1VU1QgY2hlY2sgdGhpcyBwYWRkaW5nIGFuZCBNVVNUIHVzZQogKiAgIHRoZSBiYWRfcmVjb3JkX21hYyBhbGVydCB0byBpbmRpY2F0ZSBwYWRkaW5nIGVycm9ycy4KICoKICogcGFkZGluZ19sZW5ndGg6CiAqICAgVGhlIHBhZGRpbmcgbGVuZ3RoIE1VU1QgYmUgc3VjaCB0aGF0IHRoZSB0b3RhbCBzaXplIG9mIHRoZQogKiAgIEdlbmVyaWNCbG9ja0NpcGhlciBzdHJ1Y3R1cmUgaXMgYSBtdWx0aXBsZSBvZiB0aGUgY2lwaGVyJ3MgYmxvY2sgbGVuZ3RoLgogKiAgIExlZ2FsIHZhbHVlcyByYW5nZSBmcm9tIHplcm8gdG8gMjU1LCBpbmNsdXNpdmUuIFRoaXMgbGVuZ3RoIHNwZWNpZmllcyB0aGUKICogICBsZW5ndGggb2YgdGhlIHBhZGRpbmcgZmllbGQgZXhjbHVzaXZlIG9mIHRoZSBwYWRkaW5nX2xlbmd0aCBmaWVsZCBpdHNlbGYuCiAqCiAqIFRoZSBlbmNyeXB0ZWQgZGF0YSBsZW5ndGggKFRMU0NpcGhlcnRleHQubGVuZ3RoKSBpcyBvbmUgbW9yZSB0aGFuIHRoZSBzdW0gb2YKICogU2VjdXJpdHlQYXJhbWV0ZXJzLmJsb2NrX2xlbmd0aCwgVExTQ29tcHJlc3NlZC5sZW5ndGgsCiAqIFNlY3VyaXR5UGFyYW1ldGVycy5tYWNfbGVuZ3RoLCBhbmQgcGFkZGluZ19sZW5ndGguCiAqCiAqIEV4YW1wbGU6IElmIHRoZSBibG9jayBsZW5ndGggaXMgOCBieXRlcywgdGhlIGNvbnRlbnQgbGVuZ3RoCiAqIChUTFNDb21wcmVzc2VkLmxlbmd0aCkgaXMgNjEgYnl0ZXMsIGFuZCB0aGUgTUFDIGxlbmd0aCBpcyAyMCBieXRlcywgdGhlbiB0aGUKICogbGVuZ3RoIGJlZm9yZSBwYWRkaW5nIGlzIDgyIGJ5dGVzICh0aGlzIGRvZXMgbm90IGluY2x1ZGUgdGhlIElWLiBUaHVzLCB0aGUKICogcGFkZGluZyBsZW5ndGggbW9kdWxvIDggbXVzdCBiZSBlcXVhbCB0byA2IGluIG9yZGVyIHRvIG1ha2UgdGhlIHRvdGFsIGxlbmd0aAogKiBhbiBldmVuIG11bHRpcGxlIG9mIDggYnl0ZXMgKHRoZSBibG9jayBsZW5ndGgpLiBUaGUgcGFkZGluZyBsZW5ndGggY2FuIGJlCiAqIDYsIDE0LCAyMiwgYW5kIHNvIG9uLCB0aHJvdWdoIDI1NC4gSWYgdGhlIHBhZGRpbmcgbGVuZ3RoIHdlcmUgdGhlIG1pbmltdW0KICogbmVjZXNzYXJ5LCA2LCB0aGUgcGFkZGluZyB3b3VsZCBiZSA2IGJ5dGVzLCBlYWNoIGNvbnRhaW5pbmcgdGhlIHZhbHVlIDYuCiAqIFRodXMsIHRoZSBsYXN0IDggb2N0ZXRzIG9mIHRoZSBHZW5lcmljQmxvY2tDaXBoZXIgYmVmb3JlIGJsb2NrIGVuY3J5cHRpb24KICogd291bGQgYmUgeHggMDYgMDYgMDYgMDYgMDYgMDYgMDYsIHdoZXJlIHh4IGlzIHRoZSBsYXN0IG9jdGV0IG9mIHRoZSBNQUMuCiAqCiAqIE5vdGU6IFdpdGggYmxvY2sgY2lwaGVycyBpbiBDQkMgbW9kZSAoQ2lwaGVyIEJsb2NrIENoYWluaW5nKSwgaXQgaXMgY3JpdGljYWwKICogdGhhdCB0aGUgZW50aXJlIHBsYWludGV4dCBvZiB0aGUgcmVjb3JkIGJlIGtub3duIGJlZm9yZSBhbnkgY2lwaGVydGV4dCBpcwogKiB0cmFuc21pdHRlZC4gT3RoZXJ3aXNlLCBpdCBpcyBwb3NzaWJsZSBmb3IgdGhlIGF0dGFja2VyIHRvIG1vdW50IHRoZSBhdHRhY2sKICogZGVzY3JpYmVkIGluIFtDQkNBVFRdLgogKgogKiBJbXBsZW1lbnRhdGlvbiBub3RlOiBDYW52ZWwgZXQgYWwuIFtDQkNUSU1FXSBoYXZlIGRlbW9uc3RyYXRlZCBhIHRpbWluZwogKiBhdHRhY2sgb24gQ0JDIHBhZGRpbmcgYmFzZWQgb24gdGhlIHRpbWUgcmVxdWlyZWQgdG8gY29tcHV0ZSB0aGUgTUFDLiBJbgogKiBvcmRlciB0byBkZWZlbmQgYWdhaW5zdCB0aGlzIGF0dGFjaywgaW1wbGVtZW50YXRpb25zIE1VU1QgZW5zdXJlIHRoYXQKICogcmVjb3JkIHByb2Nlc3NpbmcgdGltZSBpcyBlc3NlbnRpYWxseSB0aGUgc2FtZSB3aGV0aGVyIG9yIG5vdCB0aGUgcGFkZGluZwogKiBpcyBjb3JyZWN0LiBJbiBnZW5lcmFsLCB0aGUgYmVzdCB3YXkgdG8gZG8gdGhpcyBpcyB0byBjb21wdXRlIHRoZSBNQUMgZXZlbgogKiBpZiB0aGUgcGFkZGluZyBpcyBpbmNvcnJlY3QsIGFuZCBvbmx5IHRoZW4gcmVqZWN0IHRoZSBwYWNrZXQuIEZvciBpbnN0YW5jZSwKICogaWYgdGhlIHBhZCBhcHBlYXJzIHRvIGJlIGluY29ycmVjdCwgdGhlIGltcGxlbWVudGF0aW9uIG1pZ2h0IGFzc3VtZSBhCiAqIHplcm8tbGVuZ3RoIHBhZCBhbmQgdGhlbiBjb21wdXRlIHRoZSBNQUMuIFRoaXMgbGVhdmVzIGEgc21hbGwgdGltaW5nCiAqIGNoYW5uZWwsIHNpbmNlIE1BQyBwZXJmb3JtYW5jZSBkZXBlbmRzLCB0byBzb21lIGV4dGVudCwgb24gdGhlIHNpemUgb2YgdGhlCiAqIGRhdGEgZnJhZ21lbnQsIGJ1dCBpdCBpcyBub3QgYmVsaWV2ZWQgdG8gYmUgbGFyZ2UgZW5vdWdoIHRvIGJlIGV4cGxvaXRhYmxlLAogKiBkdWUgdG8gdGhlIGxhcmdlIGJsb2NrIHNpemUgb2YgZXhpc3RpbmcgTUFDcyBhbmQgdGhlIHNtYWxsIHNpemUgb2YgdGhlCiAqIHRpbWluZyBzaWduYWwuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKLyoqCiAqIEdlbmVyYXRlcyBwc2V1ZG8gcmFuZG9tIGJ5dGVzIGJ5IG1peGluZyB0aGUgcmVzdWx0IG9mIHR3byBoYXNoIGZ1bmN0aW9ucywKICogTUQ1IGFuZCBTSEEtMS4KICoKICogcHJmX1RMUzEoc2VjcmV0LCBsYWJlbCwgc2VlZCkgPQogKiAgIFBfTUQ1KFMxLCBsYWJlbCArIHNlZWQpIFhPUiBQX1NIQS0xKFMyLCBsYWJlbCArIHNlZWQpOwogKgogKiBFYWNoIFBfaGFzaCBmdW5jdGlvbiBmdW5jdGlvbnMgYXMgZm9sbG93czoKICoKICogUF9oYXNoKHNlY3JldCwgc2VlZCkgPSBITUFDX2hhc2goc2VjcmV0LCBBKDEpICsgc2VlZCkgKwogKiAgICAgICAgICAgICAgICAgICAgICAgIEhNQUNfaGFzaChzZWNyZXQsIEEoMikgKyBzZWVkKSArCiAqICAgICAgICAgICAgICAgICAgICAgICAgSE1BQ19oYXNoKHNlY3JldCwgQSgzKSArIHNlZWQpICsgLi4uCiAqIEEoKSBpcyBkZWZpbmVkIGFzOgogKiAgIEEoMCkgPSBzZWVkCiAqICAgQShpKSA9IEhNQUNfaGFzaChzZWNyZXQsIEEoaS0xKSkKICoKICogVGhlICcrJyBvcGVyYXRvciBkZW5vdGVzIGNvbmNhdGVuYXRpb24uCiAqCiAqIEFzIG1hbnkgaXRlcmF0aW9ucyBBKE4pIGFzIGFyZSBuZWVkZWQgYXJlIHBlcmZvcm1lZCB0byBnZW5lcmF0ZSBlbm91Z2gKICogcHNldWRvIHJhbmRvbSBieXRlIG91dHB1dC4gSWYgYW4gaXRlcmF0aW9uIGNyZWF0ZXMgbW9yZSBkYXRhIHRoYW4gaXMKICogbmVjZXNzYXJ5LCB0aGVuIGl0IGlzIHRydW5jYXRlZC4KICoKICogVGhlcmVmb3JlOgogKiBBKDEpID0gSE1BQ19oYXNoKHNlY3JldCwgQSgwKSkKICogICAgICA9IEhNQUNfaGFzaChzZWNyZXQsIHNlZWQpCiAqIEEoMikgPSBITUFDX2hhc2goc2VjcmV0LCBBKDEpKQogKiAgICAgID0gSE1BQ19oYXNoKHNlY3JldCwgSE1BQ19oYXNoKHNlY3JldCwgc2VlZCkpCiAqCiAqIFRoZXJlZm9yZToKICogUF9oYXNoKHNlY3JldCwgc2VlZCkgPQogKiAgIEhNQUNfaGFzaChzZWNyZXQsIEhNQUNfaGFzaChzZWNyZXQsIEEoMCkpICsgc2VlZCkgKwogKiAgIEhNQUNfaGFzaChzZWNyZXQsIEhNQUNfaGFzaChzZWNyZXQsIEEoMSkpICsgc2VlZCkgKwogKiAgIC4uLgogKgogKiBUaGVyZWZvcmU6CiAqIFBfaGFzaChzZWNyZXQsIHNlZWQpID0KICogICBITUFDX2hhc2goc2VjcmV0LCBITUFDX2hhc2goc2VjcmV0LCBzZWVkKSArIHNlZWQpICsKICogICBITUFDX2hhc2goc2VjcmV0LCBITUFDX2hhc2goc2VjcmV0LCBITUFDX2hhc2goc2VjcmV0LCBzZWVkKSkgKyBzZWVkKSArCiAqICAgLi4uCiAqCiAqIEBwYXJhbSBzZWNyZXQgdGhlIHNlY3JldCB0byB1c2UuCiAqIEBwYXJhbSBsYWJlbCB0aGUgbGFiZWwgdG8gdXNlLgogKiBAcGFyYW0gc2VlZCB0aGUgc2VlZCB2YWx1ZSB0byB1c2UuCiAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyB0byBnZW5lcmF0ZS4KICoKICogQHJldHVybiB0aGUgcHNldWRvIHJhbmRvbSBieXRlcyBpbiBhIGJ5dGUgYnVmZmVyLgogKi8KdmFyIHByZl9UTFMxID0gZnVuY3Rpb24oc2VjcmV0LCBsYWJlbCwgc2VlZCwgbGVuZ3RoKSB7CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwoKICAvKiBGb3IgVExTIDEuMCwgdGhlIHNlY3JldCBpcyBzcGxpdCBpbiBoYWxmLCBpbnRvIHR3byBzZWNyZXRzIG9mIGVxdWFsCiAgICBsZW5ndGguIElmIHRoZSBzZWNyZXQgaGFzIGFuIG9kZCBsZW5ndGggdGhlbiB0aGUgbGFzdCBieXRlIG9mIHRoZSBmaXJzdAogICAgaGFsZiB3aWxsIGJlIHRoZSBzYW1lIGFzIHRoZSBmaXJzdCBieXRlIG9mIHRoZSBzZWNvbmQuIFRoZSBsZW5ndGggb2YgdGhlCiAgICB0d28gc2VjcmV0cyBpcyBoYWxmIG9mIHRoZSBzZWNyZXQgcm91bmRlZCB1cC4gKi8KICB2YXIgaWR4ID0gKHNlY3JldC5sZW5ndGggPj4gMSk7CiAgdmFyIHNsZW4gPSBpZHggKyAoc2VjcmV0Lmxlbmd0aCAmIDEpOwogIHZhciBzMSA9IHNlY3JldC5zdWJzdHIoMCwgc2xlbik7CiAgdmFyIHMyID0gc2VjcmV0LnN1YnN0cihpZHgsIHNsZW4pOwogIHZhciBhaSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdmFyIGhtYWMgPSBmb3JnZS5obWFjLmNyZWF0ZSgpOwogIHNlZWQgPSBsYWJlbCArIHNlZWQ7CgogIC8vIGRldGVybWluZSB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgdGhhdCBtdXN0IGJlIHBlcmZvcm1lZCB0byBnZW5lcmF0ZQogIC8vIGVub3VnaCBvdXRwdXQgYnl0ZXMsIG1kNSBjcmVhdGVzIDE2IGJ5dGUgaGFzaGVzLCBzaGExIGNyZWF0ZXMgMjAKICB2YXIgbWQ1aXRyID0gTWF0aC5jZWlsKGxlbmd0aCAvIDE2KTsKICB2YXIgc2hhMWl0ciA9IE1hdGguY2VpbChsZW5ndGggLyAyMCk7CgogIC8vIGRvIG1kNSBpdGVyYXRpb25zCiAgaG1hYy5zdGFydCgnTUQ1JywgczEpOwogIHZhciBtZDVieXRlcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgYWkucHV0Qnl0ZXMoc2VlZCk7CiAgZm9yKHZhciBpID0gMDsgaSA8IG1kNWl0cjsgKytpKSB7CiAgICAvLyBITUFDX2hhc2goc2VjcmV0LCBBKGktMSkpCiAgICBobWFjLnN0YXJ0KG51bGwsIG51bGwpOwogICAgaG1hYy51cGRhdGUoYWkuZ2V0Qnl0ZXMoKSk7CiAgICBhaS5wdXRCdWZmZXIoaG1hYy5kaWdlc3QoKSk7CgogICAgLy8gSE1BQ19oYXNoKHNlY3JldCwgQShpKSArIHNlZWQpCiAgICBobWFjLnN0YXJ0KG51bGwsIG51bGwpOwogICAgaG1hYy51cGRhdGUoYWkuYnl0ZXMoKSArIHNlZWQpOwogICAgbWQ1Ynl0ZXMucHV0QnVmZmVyKGhtYWMuZGlnZXN0KCkpOwogIH0KCiAgLy8gZG8gc2hhMSBpdGVyYXRpb25zCiAgaG1hYy5zdGFydCgnU0hBMScsIHMyKTsKICB2YXIgc2hhMWJ5dGVzID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBhaS5jbGVhcigpOwogIGFpLnB1dEJ5dGVzKHNlZWQpOwogIGZvcih2YXIgaSA9IDA7IGkgPCBzaGExaXRyOyArK2kpIHsKICAgIC8vIEhNQUNfaGFzaChzZWNyZXQsIEEoaS0xKSkKICAgIGhtYWMuc3RhcnQobnVsbCwgbnVsbCk7CiAgICBobWFjLnVwZGF0ZShhaS5nZXRCeXRlcygpKTsKICAgIGFpLnB1dEJ1ZmZlcihobWFjLmRpZ2VzdCgpKTsKCiAgICAvLyBITUFDX2hhc2goc2VjcmV0LCBBKGkpICsgc2VlZCkKICAgIGhtYWMuc3RhcnQobnVsbCwgbnVsbCk7CiAgICBobWFjLnVwZGF0ZShhaS5ieXRlcygpICsgc2VlZCk7CiAgICBzaGExYnl0ZXMucHV0QnVmZmVyKGhtYWMuZGlnZXN0KCkpOwogIH0KCiAgLy8gWE9SIHRoZSBtZDUgYnl0ZXMgd2l0aCB0aGUgc2hhMSBieXRlcwogIHJ2YWwucHV0Qnl0ZXMoZm9yZ2UudXRpbC54b3JCeXRlcygKICAgIG1kNWJ5dGVzLmdldEJ5dGVzKCksIHNoYTFieXRlcy5nZXRCeXRlcygpLCBsZW5ndGgpKTsKCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2VuZXJhdGVzIHBzZXVkbyByYW5kb20gYnl0ZXMgdXNpbmcgYSBTSEEyNTYgYWxnb3JpdGhtLiBGb3IgVExTIDEuMi4KICoKICogQHBhcmFtIHNlY3JldCB0aGUgc2VjcmV0IHRvIHVzZS4KICogQHBhcmFtIGxhYmVsIHRoZSBsYWJlbCB0byB1c2UuCiAqIEBwYXJhbSBzZWVkIHRoZSBzZWVkIHZhbHVlIHRvIHVzZS4KICogQHBhcmFtIGxlbmd0aCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGdlbmVyYXRlLgogKgogKiBAcmV0dXJuIHRoZSBwc2V1ZG8gcmFuZG9tIGJ5dGVzIGluIGEgYnl0ZSBidWZmZXIuCiAqLwp2YXIgcHJmX3NoYTI1NiA9IGZ1bmN0aW9uKHNlY3JldCwgbGFiZWwsIHNlZWQsIGxlbmd0aCkgewogICAvLyBGSVhNRTogaW1wbGVtZW50IG1lIGZvciBUTFMgMS4yCn07CgovKioKICogR2V0cyBhIE1BQyBmb3IgYSByZWNvcmQgdXNpbmcgdGhlIFNIQS0xIGhhc2ggYWxnb3JpdGhtLgogKgogKiBAcGFyYW0ga2V5IHRoZSBtYWMga2V5LgogKiBAcGFyYW0gc3RhdGUgdGhlIHNlcXVlbmNlIG51bWJlciAoYXJyYXkgb2YgdHdvIDMyLWJpdCBpbnRlZ2VycykuCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICoKICogQHJldHVybiB0aGUgc2hhLTEgaGFzaCAoMjAgYnl0ZXMpIGZvciB0aGUgZ2l2ZW4gcmVjb3JkLgogKi8KdmFyIGhtYWNfc2hhMSA9IGZ1bmN0aW9uKGtleSwgc2VxTnVtLCByZWNvcmQpIHsKICAvKiBNQUMgaXMgY29tcHV0ZWQgbGlrZSBzbzoKICBITUFDX2hhc2goCiAgICBrZXksIHNlcU51bSArCiAgICAgIFRMU0NvbXByZXNzZWQudHlwZSArCiAgICAgIFRMU0NvbXByZXNzZWQudmVyc2lvbiArCiAgICAgIFRMU0NvbXByZXNzZWQubGVuZ3RoICsKICAgICAgVExTQ29tcHJlc3NlZC5mcmFnbWVudCkKICAqLwogIHZhciBobWFjID0gZm9yZ2UuaG1hYy5jcmVhdGUoKTsKICBobWFjLnN0YXJ0KCdTSEExJywga2V5KTsKICB2YXIgYiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgYi5wdXRJbnQzMihzZXFOdW1bMF0pOwogIGIucHV0SW50MzIoc2VxTnVtWzFdKTsKICBiLnB1dEJ5dGUocmVjb3JkLnR5cGUpOwogIGIucHV0Qnl0ZShyZWNvcmQudmVyc2lvbi5tYWpvcik7CiAgYi5wdXRCeXRlKHJlY29yZC52ZXJzaW9uLm1pbm9yKTsKICBiLnB1dEludDE2KHJlY29yZC5sZW5ndGgpOwogIGIucHV0Qnl0ZXMocmVjb3JkLmZyYWdtZW50LmJ5dGVzKCkpOwogIGhtYWMudXBkYXRlKGIuZ2V0Qnl0ZXMoKSk7CiAgcmV0dXJuIGhtYWMuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKfTsKCi8qKgogKiBDb21wcmVzc2VzIHRoZSBUTFNQbGFpbnRleHQgcmVjb3JkIGludG8gYSBUTFNDb21wcmVzc2VkIHJlY29yZCB1c2luZyB0aGUKICogZGVmbGF0ZSBhbGdvcml0aG0uCiAqCiAqIEBwYXJhbSBjIHRoZSBUTFMgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgVExTUGxhaW50ZXh0IHJlY29yZCB0byBjb21wcmVzcy4KICogQHBhcmFtIHMgdGhlIENvbm5lY3Rpb25TdGF0ZSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KdmFyIGRlZmxhdGUgPSBmdW5jdGlvbihjLCByZWNvcmQsIHMpIHsKICB2YXIgcnZhbCA9IGZhbHNlOwoKICB0cnkgewogICAgdmFyIGJ5dGVzID0gYy5kZWZsYXRlKHJlY29yZC5mcmFnbWVudC5nZXRCeXRlcygpKTsKICAgIHJlY29yZC5mcmFnbWVudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGJ5dGVzKTsKICAgIHJlY29yZC5sZW5ndGggPSBieXRlcy5sZW5ndGg7CiAgICBydmFsID0gdHJ1ZTsKICB9IGNhdGNoKGV4KSB7CiAgICAvLyBkZWZsYXRlIGVycm9yLCBmYWlsIG91dAogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogRGVjb21wcmVzc2VzIHRoZSBUTFNDb21wcmVzc2VkIHJlY29yZCBpbnRvIGEgVExTUGxhaW50ZXh0IHJlY29yZCB1c2luZyB0aGUKICogZGVmbGF0ZSBhbGdvcml0aG0uCiAqCiAqIEBwYXJhbSBjIHRoZSBUTFMgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgVExTQ29tcHJlc3NlZCByZWNvcmQgdG8gZGVjb21wcmVzcy4KICogQHBhcmFtIHMgdGhlIENvbm5lY3Rpb25TdGF0ZSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KdmFyIGluZmxhdGUgPSBmdW5jdGlvbihjLCByZWNvcmQsIHMpIHsKICB2YXIgcnZhbCA9IGZhbHNlOwoKICB0cnkgewogICAgdmFyIGJ5dGVzID0gYy5pbmZsYXRlKHJlY29yZC5mcmFnbWVudC5nZXRCeXRlcygpKTsKICAgIHJlY29yZC5mcmFnbWVudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGJ5dGVzKTsKICAgIHJlY29yZC5sZW5ndGggPSBieXRlcy5sZW5ndGg7CiAgICBydmFsID0gdHJ1ZTsKICB9IGNhdGNoKGV4KSB7CiAgICAvLyBpbmZsYXRlIGVycm9yLCBmYWlsIG91dAogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogUmVhZHMgYSBUTFMgdmFyaWFibGUtbGVuZ3RoIHZlY3RvciBmcm9tIGEgYnl0ZSBidWZmZXIuCiAqCiAqIFZhcmlhYmxlLWxlbmd0aCB2ZWN0b3JzIGFyZSBkZWZpbmVkIGJ5IHNwZWNpZnlpbmcgYSBzdWJyYW5nZSBvZiBsZWdhbAogKiBsZW5ndGhzLCBpbmNsdXNpdmVseSwgdXNpbmcgdGhlIG5vdGF0aW9uIDxmbG9vci4uY2VpbGluZz4uIFdoZW4gdGhlc2UgYXJlCiAqIGVuY29kZWQsIHRoZSBhY3R1YWwgbGVuZ3RoIHByZWNlZGVzIHRoZSB2ZWN0b3IncyBjb250ZW50cyBpbiB0aGUgYnl0ZQogKiBzdHJlYW0uIFRoZSBsZW5ndGggd2lsbCBiZSBpbiB0aGUgZm9ybSBvZiBhIG51bWJlciBjb25zdW1pbmcgYXMgbWFueSBieXRlcwogKiBhcyByZXF1aXJlZCB0byBob2xkIHRoZSB2ZWN0b3IncyBzcGVjaWZpZWQgbWF4aW11bSAoY2VpbGluZykgbGVuZ3RoLiBBCiAqIHZhcmlhYmxlLWxlbmd0aCB2ZWN0b3Igd2l0aCBhbiBhY3R1YWwgbGVuZ3RoIGZpZWxkIG9mIHplcm8gaXMgcmVmZXJyZWQgdG8KICogYXMgYW4gZW1wdHkgdmVjdG9yLgogKgogKiBAcGFyYW0gYiB0aGUgYnl0ZSBidWZmZXIuCiAqIEBwYXJhbSBsZW5CeXRlcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIHN0b3JlIHRoZSBsZW5ndGguCiAqCiAqIEByZXR1cm4gdGhlIHJlc3VsdGluZyBieXRlIGJ1ZmZlci4KICovCnZhciByZWFkVmVjdG9yID0gZnVuY3Rpb24oYiwgbGVuQnl0ZXMpIHsKICB2YXIgbGVuID0gMDsKICBzd2l0Y2gobGVuQnl0ZXMpIHsKICBjYXNlIDE6CiAgICBsZW4gPSBiLmdldEJ5dGUoKTsKICAgIGJyZWFrOwogIGNhc2UgMjoKICAgIGxlbiA9IGIuZ2V0SW50MTYoKTsKICAgIGJyZWFrOwogIGNhc2UgMzoKICAgIGxlbiA9IGIuZ2V0SW50MjQoKTsKICAgIGJyZWFrOwogIGNhc2UgNDoKICAgIGxlbiA9IGIuZ2V0SW50MzIoKTsKICAgIGJyZWFrOwogIH0KCiAgLy8gcmVhZCB2ZWN0b3IgYnl0ZXMgaW50byBhIG5ldyBidWZmZXIKICByZXR1cm4gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoYi5nZXRCeXRlcyhsZW4pKTsKfTsKCi8qKgogKiBXcml0ZXMgYSBUTFMgdmFyaWFibGUtbGVuZ3RoIHZlY3RvciB0byBhIGJ5dGUgYnVmZmVyLgogKgogKiBAcGFyYW0gYiB0aGUgYnl0ZSBidWZmZXIuCiAqIEBwYXJhbSBsZW5CeXRlcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIHN0b3JlIHRoZSBsZW5ndGguCiAqIEBwYXJhbSB2IHRoZSBieXRlIGJ1ZmZlciB2ZWN0b3IuCiAqLwp2YXIgd3JpdGVWZWN0b3IgPSBmdW5jdGlvbihiLCBsZW5CeXRlcywgdikgewogIC8vIGVuY29kZSBsZW5ndGggYXQgdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3IsIHdoZXJlIHRoZSBudW1iZXIgb2YgYnl0ZXMgZm9yCiAgLy8gdGhlIGxlbmd0aCBpcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgaXQgd291bGQgdGFrZSB0byBlbmNvZGUgdGhlCiAgLy8gdmVjdG9yJ3MgY2VpbGluZwogIGIucHV0SW50KHYubGVuZ3RoKCksIGxlbkJ5dGVzIDw8IDMpOwogIGIucHV0QnVmZmVyKHYpOwp9OwoKLyoqCiAqIFRoZSB0bHMgaW1wbGVtZW50YXRpb24uCiAqLwp2YXIgdGxzID0ge307CgovKioKICogVmVyc2lvbjogVExTIDEuMiA9IDMuMywgVExTIDEuMSA9IDMuMiwgVExTIDEuMCA9IDMuMS4gQm90aCBUTFMgMS4xIGFuZAogKiBUTFMgMS4yIHdlcmUgc3RpbGwgdG9vIG5ldyAoaWU6IG9wZW5TU0wgZGlkbid0IGltcGxlbWVudCB0aGVtKSBhdCB0aGUgdGltZQogKiBvZiB0aGlzIGltcGxlbWVudGF0aW9uIHNvIFRMUyAxLjAgd2FzIGltcGxlbWVudGVkIGluc3RlYWQuCiAqLwp0bHMuVmVyc2lvbnMgPSB7CiAgVExTXzFfMDoge21ham9yOiAzLCBtaW5vcjogMX0sCiAgVExTXzFfMToge21ham9yOiAzLCBtaW5vcjogMn0sCiAgVExTXzFfMjoge21ham9yOiAzLCBtaW5vcjogM30KfTsKdGxzLlN1cHBvcnRlZFZlcnNpb25zID0gWwogIHRscy5WZXJzaW9ucy5UTFNfMV8xLAogIHRscy5WZXJzaW9ucy5UTFNfMV8wCl07CnRscy5WZXJzaW9uID0gdGxzLlN1cHBvcnRlZFZlcnNpb25zWzBdOwoKLyoqCiAqIE1heGltdW0gZnJhZ21lbnQgc2l6ZS4gVHJ1ZSBtYXhpbXVtIGlzIDE2Mzg0LCBidXQgd2UgZnJhZ21lbnQgYmVmb3JlIHRoYXQKICogdG8gYWxsb3cgZm9yIHVudXN1YWwgc21hbGwgaW5jcmVhc2VzIGR1cmluZyBjb21wcmVzc2lvbi4KICovCnRscy5NYXhGcmFnbWVudCA9IDE2Mzg0IC0gMTAyNDsKCi8qKgogKiBXaGV0aGVyIHRoaXMgZW50aXR5IGlzIGNvbnNpZGVyZWQgdGhlICJjbGllbnQiIG9yICJzZXJ2ZXIiLgogKiBlbnVtIHsgc2VydmVyLCBjbGllbnQgfSBDb25uZWN0aW9uRW5kOwogKi8KdGxzLkNvbm5lY3Rpb25FbmQgPSB7CiAgc2VydmVyOiAwLAogIGNsaWVudDogMQp9OwoKLyoqCiAqIFBzZXVkby1yYW5kb20gZnVuY3Rpb24gYWxnb3JpdGhtIHVzZWQgdG8gZ2VuZXJhdGUga2V5cyBmcm9tIHRoZSBtYXN0ZXIKICogc2VjcmV0LgogKiBlbnVtIHsgdGxzX3ByZl9zaGEyNTYgfSBQUkZBbGdvcml0aG07CiAqLwp0bHMuUFJGQWxnb3JpdGhtID0gewogIHRsc19wcmZfc2hhMjU2OiAwCn07CgovKioKICogQnVsayBlbmNyeXB0aW9uIGFsZ29yaXRobXMuCiAqIGVudW0geyBudWxsLCByYzQsIGRlczMsIGFlcyB9IEJ1bGtDaXBoZXJBbGdvcml0aG07CiAqLwp0bHMuQnVsa0NpcGhlckFsZ29yaXRobSA9IHsKICBub25lOiBudWxsLAogIHJjNDogMCwKICBkZXMzOiAxLAogIGFlczogMgp9OwoKLyoqCiAqIENpcGhlciB0eXBlcy4KICogZW51bSB7IHN0cmVhbSwgYmxvY2ssIGFlYWQgfSBDaXBoZXJUeXBlOwogKi8KdGxzLkNpcGhlclR5cGUgPSB7CiAgc3RyZWFtOiAwLAogIGJsb2NrOiAxLAogIGFlYWQ6IDIKfTsKCi8qKgogKiBNQUMgKE1lc3NhZ2UgQXV0aGVudGljYXRpb24gQ29kZSkgYWxnb3JpdGhtcy4KICogZW51bSB7IG51bGwsIGhtYWNfbWQ1LCBobWFjX3NoYTEsIGhtYWNfc2hhMjU2LAogKiAgIGhtYWNfc2hhMzg0LCBobWFjX3NoYTUxMn0gTUFDQWxnb3JpdGhtOwogKi8KdGxzLk1BQ0FsZ29yaXRobSA9IHsKICBub25lOiBudWxsLAogIGhtYWNfbWQ1OiAwLAogIGhtYWNfc2hhMTogMSwKICBobWFjX3NoYTI1NjogMiwKICBobWFjX3NoYTM4NDogMywKICBobWFjX3NoYTUxMjogNAp9OwoKLyoqCiAqIENvbXByZXNzaW9uIGFsZ29yaXRobXMuCiAqIGVudW0geyBudWxsKDApLCBkZWZsYXRlKDEpLCAoMjU1KSB9IENvbXByZXNzaW9uTWV0aG9kOwogKi8KdGxzLkNvbXByZXNzaW9uTWV0aG9kID0gewogIG5vbmU6IDAsCiAgZGVmbGF0ZTogMQp9OwoKLyoqCiAqIFRMUyByZWNvcmQgY29udGVudCB0eXBlcy4KICogZW51bSB7CiAqICAgY2hhbmdlX2NpcGhlcl9zcGVjKDIwKSwgYWxlcnQoMjEpLCBoYW5kc2hha2UoMjIpLAogKiAgIGFwcGxpY2F0aW9uX2RhdGEoMjMpLCAoMjU1KQogKiB9IENvbnRlbnRUeXBlOwogKi8KdGxzLkNvbnRlbnRUeXBlID0gewogIGNoYW5nZV9jaXBoZXJfc3BlYzogMjAsCiAgYWxlcnQ6IDIxLAogIGhhbmRzaGFrZTogMjIsCiAgYXBwbGljYXRpb25fZGF0YTogMjMsCiAgaGVhcnRiZWF0OiAyNAp9OwoKLyoqCiAqIFRMUyBoYW5kc2hha2UgdHlwZXMuCiAqIGVudW0gewogKiAgIGhlbGxvX3JlcXVlc3QoMCksIGNsaWVudF9oZWxsbygxKSwgc2VydmVyX2hlbGxvKDIpLAogKiAgIGNlcnRpZmljYXRlKDExKSwgc2VydmVyX2tleV9leGNoYW5nZSAoMTIpLAogKiAgIGNlcnRpZmljYXRlX3JlcXVlc3QoMTMpLCBzZXJ2ZXJfaGVsbG9fZG9uZSgxNCksCiAqICAgY2VydGlmaWNhdGVfdmVyaWZ5KDE1KSwgY2xpZW50X2tleV9leGNoYW5nZSgxNiksCiAqICAgZmluaXNoZWQoMjApLCAoMjU1KQogKiB9IEhhbmRzaGFrZVR5cGU7CiAqLwp0bHMuSGFuZHNoYWtlVHlwZSA9IHsKICBoZWxsb19yZXF1ZXN0OiAwLAogIGNsaWVudF9oZWxsbzogMSwKICBzZXJ2ZXJfaGVsbG86IDIsCiAgY2VydGlmaWNhdGU6IDExLAogIHNlcnZlcl9rZXlfZXhjaGFuZ2U6IDEyLAogIGNlcnRpZmljYXRlX3JlcXVlc3Q6IDEzLAogIHNlcnZlcl9oZWxsb19kb25lOiAxNCwKICBjZXJ0aWZpY2F0ZV92ZXJpZnk6IDE1LAogIGNsaWVudF9rZXlfZXhjaGFuZ2U6IDE2LAogIGZpbmlzaGVkOiAyMAp9OwoKLyoqCiAqIFRMUyBBbGVydCBQcm90b2NvbC4KICoKICogZW51bSB7IHdhcm5pbmcoMSksIGZhdGFsKDIpLCAoMjU1KSB9IEFsZXJ0TGV2ZWw7CiAqCiAqIGVudW0gewogKiAgIGNsb3NlX25vdGlmeSgwKSwKICogICB1bmV4cGVjdGVkX21lc3NhZ2UoMTApLAogKiAgIGJhZF9yZWNvcmRfbWFjKDIwKSwKICogICBkZWNyeXB0aW9uX2ZhaWxlZCgyMSksCiAqICAgcmVjb3JkX292ZXJmbG93KDIyKSwKICogICBkZWNvbXByZXNzaW9uX2ZhaWx1cmUoMzApLAogKiAgIGhhbmRzaGFrZV9mYWlsdXJlKDQwKSwKICogICBiYWRfY2VydGlmaWNhdGUoNDIpLAogKiAgIHVuc3VwcG9ydGVkX2NlcnRpZmljYXRlKDQzKSwKICogICBjZXJ0aWZpY2F0ZV9yZXZva2VkKDQ0KSwKICogICBjZXJ0aWZpY2F0ZV9leHBpcmVkKDQ1KSwKICogICBjZXJ0aWZpY2F0ZV91bmtub3duKDQ2KSwKICogICBpbGxlZ2FsX3BhcmFtZXRlcig0NyksCiAqICAgdW5rbm93bl9jYSg0OCksCiAqICAgYWNjZXNzX2RlbmllZCg0OSksCiAqICAgZGVjb2RlX2Vycm9yKDUwKSwKICogICBkZWNyeXB0X2Vycm9yKDUxKSwKICogICBleHBvcnRfcmVzdHJpY3Rpb24oNjApLAogKiAgIHByb3RvY29sX3ZlcnNpb24oNzApLAogKiAgIGluc3VmZmljaWVudF9zZWN1cml0eSg3MSksCiAqICAgaW50ZXJuYWxfZXJyb3IoODApLAogKiAgIHVzZXJfY2FuY2VsZWQoOTApLAogKiAgIG5vX3JlbmVnb3RpYXRpb24oMTAwKSwKICogICAoMjU1KQogKiB9IEFsZXJ0RGVzY3JpcHRpb247CiAqCiAqIHN0cnVjdCB7CiAqICAgQWxlcnRMZXZlbCBsZXZlbDsKICogICBBbGVydERlc2NyaXB0aW9uIGRlc2NyaXB0aW9uOwogKiB9IEFsZXJ0OwogKi8KdGxzLkFsZXJ0ID0ge307CnRscy5BbGVydC5MZXZlbCA9IHsKICB3YXJuaW5nOiAxLAogIGZhdGFsOiAyCn07CnRscy5BbGVydC5EZXNjcmlwdGlvbiA9IHsKICBjbG9zZV9ub3RpZnk6IDAsCiAgdW5leHBlY3RlZF9tZXNzYWdlOiAxMCwKICBiYWRfcmVjb3JkX21hYzogMjAsCiAgZGVjcnlwdGlvbl9mYWlsZWQ6IDIxLAogIHJlY29yZF9vdmVyZmxvdzogMjIsCiAgZGVjb21wcmVzc2lvbl9mYWlsdXJlOiAzMCwKICBoYW5kc2hha2VfZmFpbHVyZTogNDAsCiAgYmFkX2NlcnRpZmljYXRlOiA0MiwKICB1bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZTogNDMsCiAgY2VydGlmaWNhdGVfcmV2b2tlZDogNDQsCiAgY2VydGlmaWNhdGVfZXhwaXJlZDogNDUsCiAgY2VydGlmaWNhdGVfdW5rbm93bjogNDYsCiAgaWxsZWdhbF9wYXJhbWV0ZXI6IDQ3LAogIHVua25vd25fY2E6IDQ4LAogIGFjY2Vzc19kZW5pZWQ6IDQ5LAogIGRlY29kZV9lcnJvcjogNTAsCiAgZGVjcnlwdF9lcnJvcjogNTEsCiAgZXhwb3J0X3Jlc3RyaWN0aW9uOiA2MCwKICBwcm90b2NvbF92ZXJzaW9uOiA3MCwKICBpbnN1ZmZpY2llbnRfc2VjdXJpdHk6IDcxLAogIGludGVybmFsX2Vycm9yOiA4MCwKICB1c2VyX2NhbmNlbGVkOiA5MCwKICBub19yZW5lZ290aWF0aW9uOiAxMDAKfTsKCi8qKgogKiBUTFMgSGVhcnRiZWF0IE1lc3NhZ2UgdHlwZXMuCiAqIGVudW0gewogKiAgIGhlYXJ0YmVhdF9yZXF1ZXN0KDEpLAogKiAgIGhlYXJ0YmVhdF9yZXNwb25zZSgyKSwKICogICAoMjU1KQogKiB9IEhlYXJ0YmVhdE1lc3NhZ2VUeXBlOwogKi8KdGxzLkhlYXJ0YmVhdE1lc3NhZ2VUeXBlID0gewogIGhlYXJ0YmVhdF9yZXF1ZXN0OiAxLAogIGhlYXJ0YmVhdF9yZXNwb25zZTogMgp9OwoKLyoqCiAqIFN1cHBvcnRlZCBjaXBoZXIgc3VpdGVzLgogKi8KdGxzLkNpcGhlclN1aXRlcyA9IHt9OwoKLyoqCiAqIEdldHMgYSBzdXBwb3J0ZWQgY2lwaGVyIHN1aXRlIGZyb20gaXRzIDIgYnl0ZSBJRC4KICoKICogQHBhcmFtIHR3b0J5dGVzIHR3byBieXRlcyBpbiBhIHN0cmluZy4KICoKICogQHJldHVybiB0aGUgbWF0Y2hpbmcgc3VwcG9ydGVkIGNpcGhlciBzdWl0ZSBvciBudWxsLgogKi8KdGxzLmdldENpcGhlclN1aXRlID0gZnVuY3Rpb24odHdvQnl0ZXMpIHsKICB2YXIgcnZhbCA9IG51bGw7CiAgZm9yKHZhciBrZXkgaW4gdGxzLkNpcGhlclN1aXRlcykgewogICAgdmFyIGNzID0gdGxzLkNpcGhlclN1aXRlc1trZXldOwogICAgaWYoY3MuaWRbMF0gPT09IHR3b0J5dGVzLmNoYXJDb2RlQXQoMCkgJiYKICAgICAgY3MuaWRbMV0gPT09IHR3b0J5dGVzLmNoYXJDb2RlQXQoMSkpIHsKICAgICAgcnZhbCA9IGNzOwogICAgICBicmVhazsKICAgIH0KICB9CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ2FsbGVkIHdoZW4gYW4gdW5leHBlY3RlZCByZWNvcmQgaXMgZW5jb3VudGVyZWQuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqLwp0bHMuaGFuZGxlVW5leHBlY3RlZCA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogIC8vIGlmIGNvbm5lY3Rpb24gaXMgY2xpZW50IGFuZCBjbG9zZWQsIGlnbm9yZSB1bmV4cGVjdGVkIG1lc3NhZ2VzCiAgdmFyIGlnbm9yZSA9ICghYy5vcGVuICYmIGMuZW50aXR5ID09PSB0bHMuQ29ubmVjdGlvbkVuZC5jbGllbnQpOwogIGlmKCFpZ25vcmUpIHsKICAgIGMuZXJyb3IoYywgewogICAgICBtZXNzYWdlOiAnVW5leHBlY3RlZCBtZXNzYWdlLiBSZWNlaXZlZCBUTFMgcmVjb3JkIG91dCBvZiBvcmRlci4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi51bmV4cGVjdGVkX21lc3NhZ2UKICAgICAgfQogICAgfSk7CiAgfQp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgY2xpZW50IHJlY2VpdmVzIGEgSGVsbG9SZXF1ZXN0IHJlY29yZC4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVIZWxsb1JlcXVlc3QgPSBmdW5jdGlvbihjLCByZWNvcmQsIGxlbmd0aCkgewogIC8vIGlnbm9yZSByZW5lZ290aWF0aW9uIHJlcXVlc3RzIGZyb20gdGhlIHNlcnZlciBkdXJpbmcgYSBoYW5kc2hha2UsIGJ1dAogIC8vIGlmIGhhbmRzaGFraW5nLCBzZW5kIGEgd2FybmluZyBhbGVydCB0aGF0IHJlbmVnb3RhdGlvbiBpcyBkZW5pZWQKICBpZighYy5oYW5kc2hha2luZyAmJiBjLmhhbmRzaGFrZXMgPiAwKSB7CiAgICAvLyBzZW5kIGFsZXJ0IHdhcm5pbmcKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlQWxlcnQoYywgewogICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC53YXJuaW5nLAogICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5ub19yZW5lZ290aWF0aW9uCiAgICB9KSk7CiAgICB0bHMuZmx1c2goYyk7CiAgfQoKICAvLyBjb250aW51ZQogIGMucHJvY2VzcygpOwp9OwoKLyoqCiAqIFBhcnNlcyBhIGhlbGxvIG1lc3NhZ2UgZnJvbSBhIENsaWVudEhlbGxvIG9yIFNlcnZlckhlbGxvIHJlY29yZC4KICoKICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkIHRvIHBhcnNlLgogKgogKiBAcmV0dXJuIHRoZSBwYXJzZWQgbWVzc2FnZS4KICovCnRscy5wYXJzZUhlbGxvTWVzc2FnZSA9IGZ1bmN0aW9uKGMsIHJlY29yZCwgbGVuZ3RoKSB7CiAgdmFyIG1zZyA9IG51bGw7CgogIHZhciBjbGllbnQgPSAoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCk7CgogIC8vIG1pbmltdW0gb2YgMzggYnl0ZXMgaW4gbWVzc2FnZQogIGlmKGxlbmd0aCA8IDM4KSB7CiAgICBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogY2xpZW50ID8KICAgICAgICAnSW52YWxpZCBTZXJ2ZXJIZWxsbyBtZXNzYWdlLiBNZXNzYWdlIHRvbyBzaG9ydC4nIDoKICAgICAgICAnSW52YWxpZCBDbGllbnRIZWxsbyBtZXNzYWdlLiBNZXNzYWdlIHRvbyBzaG9ydC4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5pbGxlZ2FsX3BhcmFtZXRlcgogICAgICB9CiAgICB9KTsKICB9IGVsc2UgewogICAgLy8gdXNlICdyZW1haW5pbmcnIHRvIGNhbGN1bGF0ZSAjIG9mIHJlbWFpbmluZyBieXRlcyBpbiB0aGUgbWVzc2FnZQogICAgdmFyIGIgPSByZWNvcmQuZnJhZ21lbnQ7CiAgICB2YXIgcmVtYWluaW5nID0gYi5sZW5ndGgoKTsKICAgIG1zZyA9IHsKICAgICAgdmVyc2lvbjogewogICAgICAgIG1ham9yOiBiLmdldEJ5dGUoKSwKICAgICAgICBtaW5vcjogYi5nZXRCeXRlKCkKICAgICAgfSwKICAgICAgcmFuZG9tOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihiLmdldEJ5dGVzKDMyKSksCiAgICAgIHNlc3Npb25faWQ6IHJlYWRWZWN0b3IoYiwgMSksCiAgICAgIGV4dGVuc2lvbnM6IFtdCiAgICB9OwogICAgaWYoY2xpZW50KSB7CiAgICAgIG1zZy5jaXBoZXJfc3VpdGUgPSBiLmdldEJ5dGVzKDIpOwogICAgICBtc2cuY29tcHJlc3Npb25fbWV0aG9kID0gYi5nZXRCeXRlKCk7CiAgICB9IGVsc2UgewogICAgICBtc2cuY2lwaGVyX3N1aXRlcyA9IHJlYWRWZWN0b3IoYiwgMik7CiAgICAgIG1zZy5jb21wcmVzc2lvbl9tZXRob2RzID0gcmVhZFZlY3RvcihiLCAxKTsKICAgIH0KCiAgICAvLyByZWFkIGV4dGVuc2lvbnMgaWYgdGhlcmUgYXJlIGFueSBieXRlcyBsZWZ0IGluIHRoZSBtZXNzYWdlCiAgICByZW1haW5pbmcgPSBsZW5ndGggLSAocmVtYWluaW5nIC0gYi5sZW5ndGgoKSk7CiAgICBpZihyZW1haW5pbmcgPiAwKSB7CiAgICAgIC8vIHBhcnNlIGV4dGVuc2lvbnMKICAgICAgdmFyIGV4dHMgPSByZWFkVmVjdG9yKGIsIDIpOwogICAgICB3aGlsZShleHRzLmxlbmd0aCgpID4gMCkgewogICAgICAgIG1zZy5leHRlbnNpb25zLnB1c2goewogICAgICAgICAgdHlwZTogW2V4dHMuZ2V0Qnl0ZSgpLCBleHRzLmdldEJ5dGUoKV0sCiAgICAgICAgICBkYXRhOiByZWFkVmVjdG9yKGV4dHMsIDIpCiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgIC8vIFRPRE86IG1ha2UgZXh0ZW5zaW9uIHN1cHBvcnQgbW9kdWxhcgogICAgICBpZighY2xpZW50KSB7CiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IG1zZy5leHRlbnNpb25zLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICB2YXIgZXh0ID0gbXNnLmV4dGVuc2lvbnNbaV07CgogICAgICAgICAgLy8gc3VwcG9ydCBTTkkgZXh0ZW5zaW9uCiAgICAgICAgICBpZihleHQudHlwZVswXSA9PT0gMHgwMCAmJiBleHQudHlwZVsxXSA9PT0gMHgwMCkgewogICAgICAgICAgICAvLyBnZXQgc2VydmVyIG5hbWUgbGlzdAogICAgICAgICAgICB2YXIgc25sID0gcmVhZFZlY3RvcihleHQuZGF0YSwgMik7CiAgICAgICAgICAgIHdoaWxlKHNubC5sZW5ndGgoKSA+IDApIHsKICAgICAgICAgICAgICAvLyByZWFkIHNlcnZlciBuYW1lIHR5cGUKICAgICAgICAgICAgICB2YXIgc25UeXBlID0gc25sLmdldEJ5dGUoKTsKCiAgICAgICAgICAgICAgLy8gb25seSBIb3N0TmFtZSB0eXBlICgweDAwKSBpcyBrbm93biwgYnJlYWsgb3V0IGlmCiAgICAgICAgICAgICAgLy8gYW5vdGhlciB0eXBlIGlzIGRldGVjdGVkCiAgICAgICAgICAgICAgaWYoc25UeXBlICE9PSAweDAwKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIGFkZCBob3N0IG5hbWUgdG8gc2VydmVyIG5hbWUgbGlzdAogICAgICAgICAgICAgIGMuc2Vzc2lvbi5leHRlbnNpb25zLnNlcnZlcl9uYW1lLnNlcnZlck5hbWVMaXN0LnB1c2goCiAgICAgICAgICAgICAgICByZWFkVmVjdG9yKHNubCwgMikuZ2V0Qnl0ZXMoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICAvLyB2ZXJzaW9uIGFscmVhZHkgc2V0LCBkbyBub3QgYWxsb3cgdmVyc2lvbiBjaGFuZ2UKICAgIGlmKGMuc2Vzc2lvbi52ZXJzaW9uKSB7CiAgICAgIGlmKG1zZy52ZXJzaW9uLm1ham9yICE9PSBjLnNlc3Npb24udmVyc2lvbi5tYWpvciB8fAogICAgICAgIG1zZy52ZXJzaW9uLm1pbm9yICE9PSBjLnNlc3Npb24udmVyc2lvbi5taW5vcikgewogICAgICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgICAgIG1lc3NhZ2U6ICdUTFMgdmVyc2lvbiBjaGFuZ2UgaXMgZGlzYWxsb3dlZCBkdXJpbmcgcmVuZWdvdGlhdGlvbi4nLAogICAgICAgICAgc2VuZDogdHJ1ZSwKICAgICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24ucHJvdG9jb2xfdmVyc2lvbgogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICB9CiAgICB9CgogICAgLy8gZ2V0IHRoZSBjaG9zZW4gKFNlcnZlckhlbGxvKSBjaXBoZXIgc3VpdGUKICAgIGlmKGNsaWVudCkgewogICAgICAvLyBGSVhNRTogc2hvdWxkIGJlIGNoZWNraW5nIGNvbmZpZ3VyZWQgYWNjZXB0YWJsZSBjaXBoZXIgc3VpdGVzCiAgICAgIGMuc2Vzc2lvbi5jaXBoZXJTdWl0ZSA9IHRscy5nZXRDaXBoZXJTdWl0ZShtc2cuY2lwaGVyX3N1aXRlKTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIGdldCBhIHN1cHBvcnRlZCBwcmVmZXJyZWQgKENsaWVudEhlbGxvKSBjaXBoZXIgc3VpdGUKICAgICAgLy8gY2hvb3NlIHRoZSBmaXJzdCBzdXBwb3J0ZWQgY2lwaGVyIHN1aXRlCiAgICAgIHZhciB0bXAgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihtc2cuY2lwaGVyX3N1aXRlcy5ieXRlcygpKTsKICAgICAgd2hpbGUodG1wLmxlbmd0aCgpID4gMCkgewogICAgICAgIC8vIEZJWE1FOiBzaG91bGQgYmUgY2hlY2tpbmcgY29uZmlndXJlZCBhY2NlcHRhYmxlIHN1aXRlcwogICAgICAgIC8vIGNpcGhlciBzdWl0ZXMgdGFrZSB1cCAyIGJ5dGVzCiAgICAgICAgYy5zZXNzaW9uLmNpcGhlclN1aXRlID0gdGxzLmdldENpcGhlclN1aXRlKHRtcC5nZXRCeXRlcygyKSk7CiAgICAgICAgaWYoYy5zZXNzaW9uLmNpcGhlclN1aXRlICE9PSBudWxsKSB7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICAvLyBjaXBoZXIgc3VpdGUgbm90IHN1cHBvcnRlZAogICAgaWYoYy5zZXNzaW9uLmNpcGhlclN1aXRlID09PSBudWxsKSB7CiAgICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgICBtZXNzYWdlOiAnTm8gY2lwaGVyIHN1aXRlcyBpbiBjb21tb24uJywKICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5oYW5kc2hha2VfZmFpbHVyZQogICAgICAgIH0sCiAgICAgICAgY2lwaGVyU3VpdGU6IGZvcmdlLnV0aWwuYnl0ZXNUb0hleChtc2cuY2lwaGVyX3N1aXRlKQogICAgICB9KTsKICAgIH0KCiAgICAvLyBUT0RPOiBoYW5kbGUgY29tcHJlc3Npb24gbWV0aG9kcwogICAgaWYoY2xpZW50KSB7CiAgICAgIGMuc2Vzc2lvbi5jb21wcmVzc2lvbk1ldGhvZCA9IG1zZy5jb21wcmVzc2lvbl9tZXRob2Q7CiAgICB9IGVsc2UgewogICAgICAvLyBubyBjb21wcmVzc2lvbgogICAgICBjLnNlc3Npb24uY29tcHJlc3Npb25NZXRob2QgPSB0bHMuQ29tcHJlc3Npb25NZXRob2Qubm9uZTsKICAgIH0KICB9CgogIHJldHVybiBtc2c7Cn07CgovKioKICogQ3JlYXRlcyBzZWN1cml0eSBwYXJhbWV0ZXJzIGZvciB0aGUgZ2l2ZW4gY29ubmVjdGlvbiBiYXNlZCBvbiB0aGUgZ2l2ZW4KICogaGVsbG8gbWVzc2FnZS4KICoKICogQHBhcmFtIGMgdGhlIFRMUyBjb25uZWN0aW9uLgogKiBAcGFyYW0gbXNnIHRoZSBoZWxsbyBtZXNzYWdlLgogKi8KdGxzLmNyZWF0ZVNlY3VyaXR5UGFyYW1ldGVycyA9IGZ1bmN0aW9uKGMsIG1zZykgewogIC8qIE5vdGU6IHNlY3VyaXR5IHBhcmFtcyBhcmUgZnJvbSBUTFMgMS4yLCBzb21lIHZhbHVlcyBsaWtlIHByZl9hbGdvcml0aG0KICBhcmUgaWdub3JlZCBmb3IgVExTIDEuMC8xLjEgYW5kIHRoZSBidWlsdGluIGFzIHNwZWNpZmllZCBpbiB0aGUgc3BlYyBpcwogIHVzZWQuICovCgogIC8vIFRPRE86IGhhbmRsZSBvdGhlciBvcHRpb25zIGZyb20gc2VydmVyIHdoZW4gbW9yZSBzdXBwb3J0ZWQKCiAgLy8gZ2V0IGNsaWVudCBhbmQgc2VydmVyIHJhbmRvbXMKICB2YXIgY2xpZW50ID0gKGMuZW50aXR5ID09PSB0bHMuQ29ubmVjdGlvbkVuZC5jbGllbnQpOwogIHZhciBtc2dSYW5kb20gPSBtc2cucmFuZG9tLmJ5dGVzKCk7CiAgdmFyIGNSYW5kb20gPSBjbGllbnQgPyBjLnNlc3Npb24uc3AuY2xpZW50X3JhbmRvbSA6IG1zZ1JhbmRvbTsKICB2YXIgc1JhbmRvbSA9IGNsaWVudCA/IG1zZ1JhbmRvbSA6IHRscy5jcmVhdGVSYW5kb20oKS5nZXRCeXRlcygpOwoKICAvLyBjcmVhdGUgbmV3IHNlY3VyaXR5IHBhcmFtZXRlcnMKICBjLnNlc3Npb24uc3AgPSB7CiAgICBlbnRpdHk6IGMuZW50aXR5LAogICAgcHJmX2FsZ29yaXRobTogdGxzLlBSRkFsZ29yaXRobS50bHNfcHJmX3NoYTI1NiwKICAgIGJ1bGtfY2lwaGVyX2FsZ29yaXRobTogbnVsbCwKICAgIGNpcGhlcl90eXBlOiBudWxsLAogICAgZW5jX2tleV9sZW5ndGg6IG51bGwsCiAgICBibG9ja19sZW5ndGg6IG51bGwsCiAgICBmaXhlZF9pdl9sZW5ndGg6IG51bGwsCiAgICByZWNvcmRfaXZfbGVuZ3RoOiBudWxsLAogICAgbWFjX2FsZ29yaXRobTogbnVsbCwKICAgIG1hY19sZW5ndGg6IG51bGwsCiAgICBtYWNfa2V5X2xlbmd0aDogbnVsbCwKICAgIGNvbXByZXNzaW9uX2FsZ29yaXRobTogYy5zZXNzaW9uLmNvbXByZXNzaW9uTWV0aG9kLAogICAgcHJlX21hc3Rlcl9zZWNyZXQ6IG51bGwsCiAgICBtYXN0ZXJfc2VjcmV0OiBudWxsLAogICAgY2xpZW50X3JhbmRvbTogY1JhbmRvbSwKICAgIHNlcnZlcl9yYW5kb206IHNSYW5kb20KICB9Owp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgY2xpZW50IHJlY2VpdmVzIGEgU2VydmVySGVsbG8gcmVjb3JkLgogKgogKiBXaGVuIGEgU2VydmVySGVsbG8gbWVzc2FnZSB3aWxsIGJlIHNlbnQ6CiAqICAgVGhlIHNlcnZlciB3aWxsIHNlbmQgdGhpcyBtZXNzYWdlIGluIHJlc3BvbnNlIHRvIGEgY2xpZW50IGhlbGxvIG1lc3NhZ2UKICogICB3aGVuIGl0IHdhcyBhYmxlIHRvIGZpbmQgYW4gYWNjZXB0YWJsZSBzZXQgb2YgYWxnb3JpdGhtcy4gSWYgaXQgY2Fubm90CiAqICAgZmluZCBzdWNoIGEgbWF0Y2gsIGl0IHdpbGwgcmVzcG9uZCB3aXRoIGEgaGFuZHNoYWtlIGZhaWx1cmUgYWxlcnQuCiAqCiAqIHVpbnQyNCBsZW5ndGg7CiAqIHN0cnVjdCB7CiAqICAgUHJvdG9jb2xWZXJzaW9uIHNlcnZlcl92ZXJzaW9uOwogKiAgIFJhbmRvbSByYW5kb207CiAqICAgU2Vzc2lvbklEIHNlc3Npb25faWQ7CiAqICAgQ2lwaGVyU3VpdGUgY2lwaGVyX3N1aXRlOwogKiAgIENvbXByZXNzaW9uTWV0aG9kIGNvbXByZXNzaW9uX21ldGhvZDsKICogICBzZWxlY3QoZXh0ZW5zaW9uc19wcmVzZW50KSB7CiAqICAgICBjYXNlIGZhbHNlOgogKiAgICAgICBzdHJ1Y3Qge307CiAqICAgICBjYXNlIHRydWU6CiAqICAgICAgIEV4dGVuc2lvbiBleHRlbnNpb25zPDAuLjJeMTYtMT47CiAqICAgfTsKICogfSBTZXJ2ZXJIZWxsbzsKICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVTZXJ2ZXJIZWxsbyA9IGZ1bmN0aW9uKGMsIHJlY29yZCwgbGVuZ3RoKSB7CiAgdmFyIG1zZyA9IHRscy5wYXJzZUhlbGxvTWVzc2FnZShjLCByZWNvcmQsIGxlbmd0aCk7CiAgaWYoYy5mYWlsKSB7CiAgICByZXR1cm47CiAgfQoKICAvLyBlbnN1cmUgc2VydmVyIHZlcnNpb24gaXMgY29tcGF0aWJsZQogIGlmKG1zZy52ZXJzaW9uLm1pbm9yIDw9IGMudmVyc2lvbi5taW5vcikgewogICAgYy52ZXJzaW9uLm1pbm9yID0gbXNnLnZlcnNpb24ubWlub3I7CiAgfSBlbHNlIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0luY29tcGF0aWJsZSBUTFMgdmVyc2lvbi4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5wcm90b2NvbF92ZXJzaW9uCiAgICAgIH0KICAgIH0pOwogIH0KCiAgLy8gaW5kaWNhdGUgc2Vzc2lvbiB2ZXJzaW9uIGhhcyBiZWVuIHNldAogIGMuc2Vzc2lvbi52ZXJzaW9uID0gYy52ZXJzaW9uOwoKICAvLyBnZXQgdGhlIHNlc3Npb24gSUQgZnJvbSB0aGUgbWVzc2FnZQogIHZhciBzZXNzaW9uSWQgPSBtc2cuc2Vzc2lvbl9pZC5ieXRlcygpOwoKICAvLyBpZiB0aGUgc2Vzc2lvbiBJRCBpcyBub3QgYmxhbmsgYW5kIG1hdGNoZXMgdGhlIGNhY2hlZCBvbmUsIHJlc3VtZQogIC8vIHRoZSBzZXNzaW9uCiAgaWYoc2Vzc2lvbklkLmxlbmd0aCA+IDAgJiYgc2Vzc2lvbklkID09PSBjLnNlc3Npb24uaWQpIHsKICAgIC8vIHJlc3VtaW5nIHNlc3Npb24sIGV4cGVjdCBhIENoYW5nZUNpcGhlclNwZWMgbmV4dAogICAgYy5leHBlY3QgPSBTQ0M7CiAgICBjLnNlc3Npb24ucmVzdW1pbmcgPSB0cnVlOwoKICAgIC8vIGdldCBuZXcgc2VydmVyIHJhbmRvbQogICAgYy5zZXNzaW9uLnNwLnNlcnZlcl9yYW5kb20gPSBtc2cucmFuZG9tLmJ5dGVzKCk7CiAgfSBlbHNlIHsKICAgIC8vIG5vdCByZXN1bWluZywgZXhwZWN0IGEgc2VydmVyIENlcnRpZmljYXRlIG1lc3NhZ2UgbmV4dAogICAgYy5leHBlY3QgPSBTQ0U7CiAgICBjLnNlc3Npb24ucmVzdW1pbmcgPSBmYWxzZTsKCiAgICAvLyBjcmVhdGUgbmV3IHNlY3VyaXR5IHBhcmFtZXRlcnMKICAgIHRscy5jcmVhdGVTZWN1cml0eVBhcmFtZXRlcnMoYywgbXNnKTsKICB9CgogIC8vIHNldCBuZXcgc2Vzc2lvbiBJRAogIGMuc2Vzc2lvbi5pZCA9IHNlc3Npb25JZDsKCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIHNlcnZlciByZWNlaXZlcyBhIENsaWVudEhlbGxvIHJlY29yZC4KICoKICogV2hlbiBhIENsaWVudEhlbGxvIG1lc3NhZ2Ugd2lsbCBiZSBzZW50OgogKiAgIFdoZW4gYSBjbGllbnQgZmlyc3QgY29ubmVjdHMgdG8gYSBzZXJ2ZXIgaXQgaXMgcmVxdWlyZWQgdG8gc2VuZCB0aGUKICogICBjbGllbnQgaGVsbG8gYXMgaXRzIGZpcnN0IG1lc3NhZ2UuIFRoZSBjbGllbnQgY2FuIGFsc28gc2VuZCBhIGNsaWVudAogKiAgIGhlbGxvIGluIHJlc3BvbnNlIHRvIGEgaGVsbG8gcmVxdWVzdCBvciBvbiBpdHMgb3duIGluaXRpYXRpdmUgaW4gb3JkZXIKICogICB0byByZW5lZ290aWF0ZSB0aGUgc2VjdXJpdHkgcGFyYW1ldGVycyBpbiBhbiBleGlzdGluZyBjb25uZWN0aW9uLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlLgogKi8KdGxzLmhhbmRsZUNsaWVudEhlbGxvID0gZnVuY3Rpb24oYywgcmVjb3JkLCBsZW5ndGgpIHsKICB2YXIgbXNnID0gdGxzLnBhcnNlSGVsbG9NZXNzYWdlKGMsIHJlY29yZCwgbGVuZ3RoKTsKICBpZihjLmZhaWwpIHsKICAgIHJldHVybjsKICB9CgogIC8vIGdldCB0aGUgc2Vzc2lvbiBJRCBmcm9tIHRoZSBtZXNzYWdlCiAgdmFyIHNlc3Npb25JZCA9IG1zZy5zZXNzaW9uX2lkLmJ5dGVzKCk7CgogIC8vIHNlZSBpZiB0aGUgZ2l2ZW4gc2Vzc2lvbiBJRCBpcyBpbiB0aGUgY2FjaGUKICB2YXIgc2Vzc2lvbiA9IG51bGw7CiAgaWYoYy5zZXNzaW9uQ2FjaGUpIHsKICAgIHNlc3Npb24gPSBjLnNlc3Npb25DYWNoZS5nZXRTZXNzaW9uKHNlc3Npb25JZCk7CiAgICBpZihzZXNzaW9uID09PSBudWxsKSB7CiAgICAgIC8vIHNlc3Npb24gSUQgbm90IGZvdW5kCiAgICAgIHNlc3Npb25JZCA9ICcnOwogICAgfSBlbHNlIGlmKHNlc3Npb24udmVyc2lvbi5tYWpvciAhPT0gbXNnLnZlcnNpb24ubWFqb3IgfHwKICAgICAgc2Vzc2lvbi52ZXJzaW9uLm1pbm9yID4gbXNnLnZlcnNpb24ubWlub3IpIHsKICAgICAgLy8gaWYgc2Vzc2lvbiB2ZXJzaW9uIGlzIGluY29tcGF0aWJsZSB3aXRoIGNsaWVudCB2ZXJzaW9uLCBkbyBub3QgcmVzdW1lCiAgICAgIHNlc3Npb24gPSBudWxsOwogICAgICBzZXNzaW9uSWQgPSAnJzsKICAgIH0KICB9CgogIC8vIG5vIHNlc3Npb24gZm91bmQgdG8gcmVzdW1lLCBnZW5lcmF0ZSBhIG5ldyBzZXNzaW9uIElECiAgaWYoc2Vzc2lvbklkLmxlbmd0aCA9PT0gMCkgewogICAgc2Vzc2lvbklkID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzKDMyKTsKICB9CgogIC8vIHVwZGF0ZSBzZXNzaW9uCiAgYy5zZXNzaW9uLmlkID0gc2Vzc2lvbklkOwogIGMuc2Vzc2lvbi5jbGllbnRIZWxsb1ZlcnNpb24gPSBtc2cudmVyc2lvbjsKICBjLnNlc3Npb24uc3AgPSB7fTsKICBpZihzZXNzaW9uKSB7CiAgICAvLyB1c2UgdmVyc2lvbiBhbmQgc2VjdXJpdHkgcGFyYW1ldGVycyBmcm9tIHJlc3VtZWQgc2Vzc2lvbgogICAgYy52ZXJzaW9uID0gYy5zZXNzaW9uLnZlcnNpb24gPSBzZXNzaW9uLnZlcnNpb247CiAgICBjLnNlc3Npb24uc3AgPSBzZXNzaW9uLnNwOwogIH0gZWxzZSB7CiAgICAvLyB1c2UgaGlnaGVzdCBjb21wYXRpYmxlIG1pbm9yIHZlcnNpb24KICAgIHZhciB2ZXJzaW9uOwogICAgZm9yKHZhciBpID0gMTsgaSA8IHRscy5TdXBwb3J0ZWRWZXJzaW9ucy5sZW5ndGg7ICsraSkgewogICAgICB2ZXJzaW9uID0gdGxzLlN1cHBvcnRlZFZlcnNpb25zW2ldOwogICAgICBpZih2ZXJzaW9uLm1pbm9yIDw9IG1zZy52ZXJzaW9uLm1pbm9yKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIGMudmVyc2lvbiA9IHttYWpvcjogdmVyc2lvbi5tYWpvciwgbWlub3I6IHZlcnNpb24ubWlub3J9OwogICAgYy5zZXNzaW9uLnZlcnNpb24gPSBjLnZlcnNpb247CiAgfQoKICAvLyBpZiBhIHNlc3Npb24gaXMgc2V0LCByZXN1bWUgaXQKICBpZihzZXNzaW9uICE9PSBudWxsKSB7CiAgICAvLyByZXN1bWluZyBzZXNzaW9uLCBleHBlY3QgYSBDaGFuZ2VDaXBoZXJTcGVjIG5leHQKICAgIGMuZXhwZWN0ID0gQ0NDOwogICAgYy5zZXNzaW9uLnJlc3VtaW5nID0gdHJ1ZTsKCiAgICAvLyBnZXQgbmV3IGNsaWVudCByYW5kb20KICAgIGMuc2Vzc2lvbi5zcC5jbGllbnRfcmFuZG9tID0gbXNnLnJhbmRvbS5ieXRlcygpOwogIH0gZWxzZSB7CiAgICAvLyBub3QgcmVzdW1pbmcsIGV4cGVjdCBhIENlcnRpZmljYXRlIG9yIENsaWVudEtleUV4Y2hhbmdlCiAgICBjLmV4cGVjdCA9IChjLnZlcmlmeUNsaWVudCAhPT0gZmFsc2UpID8gQ0NFIDogQ0tFOwogICAgYy5zZXNzaW9uLnJlc3VtaW5nID0gZmFsc2U7CgogICAgLy8gY3JlYXRlIG5ldyBzZWN1cml0eSBwYXJhbWV0ZXJzCiAgICB0bHMuY3JlYXRlU2VjdXJpdHlQYXJhbWV0ZXJzKGMsIG1zZyk7CiAgfQoKICAvLyBjb25uZWN0aW9uIG5vdyBvcGVuCiAgYy5vcGVuID0gdHJ1ZTsKCiAgLy8gcXVldWUgc2VydmVyIGhlbGxvCiAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVSZWNvcmQoYywgewogICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgIGRhdGE6IHRscy5jcmVhdGVTZXJ2ZXJIZWxsbyhjKQogIH0pKTsKCiAgaWYoYy5zZXNzaW9uLnJlc3VtaW5nKSB7CiAgICAvLyBxdWV1ZSBjaGFuZ2UgY2lwaGVyIHNwZWMgbWVzc2FnZQogICAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVSZWNvcmQoYywgewogICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuY2hhbmdlX2NpcGhlcl9zcGVjLAogICAgICBkYXRhOiB0bHMuY3JlYXRlQ2hhbmdlQ2lwaGVyU3BlYygpCiAgICB9KSk7CgogICAgLy8gY3JlYXRlIHBlbmRpbmcgc3RhdGUKICAgIGMuc3RhdGUucGVuZGluZyA9IHRscy5jcmVhdGVDb25uZWN0aW9uU3RhdGUoYyk7CgogICAgLy8gY2hhbmdlIGN1cnJlbnQgd3JpdGUgc3RhdGUgdG8gcGVuZGluZyB3cml0ZSBzdGF0ZQogICAgYy5zdGF0ZS5jdXJyZW50LndyaXRlID0gYy5zdGF0ZS5wZW5kaW5nLndyaXRlOwoKICAgIC8vIHF1ZXVlIGZpbmlzaGVkCiAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgIHR5cGU6IHRscy5Db250ZW50VHlwZS5oYW5kc2hha2UsCiAgICAgIGRhdGE6IHRscy5jcmVhdGVGaW5pc2hlZChjKQogICAgfSkpOwogIH0gZWxzZSB7CiAgICAvLyBxdWV1ZSBzZXJ2ZXIgY2VydGlmaWNhdGUKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgICAgZGF0YTogdGxzLmNyZWF0ZUNlcnRpZmljYXRlKGMpCiAgICB9KSk7CgogICAgaWYoIWMuZmFpbCkgewogICAgICAvLyBxdWV1ZSBzZXJ2ZXIga2V5IGV4Y2hhbmdlCiAgICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlLAogICAgICAgIGRhdGE6IHRscy5jcmVhdGVTZXJ2ZXJLZXlFeGNoYW5nZShjKQogICAgICB9KSk7CgogICAgICAvLyByZXF1ZXN0IGNsaWVudCBjZXJ0aWZpY2F0ZSBpZiBzZXQKICAgICAgaWYoYy52ZXJpZnlDbGllbnQgIT09IGZhbHNlKSB7CiAgICAgICAgLy8gcXVldWUgY2VydGlmaWNhdGUgcmVxdWVzdAogICAgICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICAgIHR5cGU6IHRscy5Db250ZW50VHlwZS5oYW5kc2hha2UsCiAgICAgICAgICBkYXRhOiB0bHMuY3JlYXRlQ2VydGlmaWNhdGVSZXF1ZXN0KGMpCiAgICAgICAgfSkpOwogICAgICB9CgogICAgICAvLyBxdWV1ZSBzZXJ2ZXIgaGVsbG8gZG9uZQogICAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgICAgICBkYXRhOiB0bHMuY3JlYXRlU2VydmVySGVsbG9Eb25lKGMpCiAgICAgIH0pKTsKICAgIH0KICB9CgogIC8vIHNlbmQgcmVjb3JkcwogIHRscy5mbHVzaChjKTsKCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIGNsaWVudCByZWNlaXZlcyBhIENlcnRpZmljYXRlIHJlY29yZC4KICoKICogV2hlbiB0aGlzIG1lc3NhZ2Ugd2lsbCBiZSBzZW50OgogKiAgIFRoZSBzZXJ2ZXIgbXVzdCBzZW5kIGEgY2VydGlmaWNhdGUgd2hlbmV2ZXIgdGhlIGFncmVlZC11cG9uIGtleSBleGNoYW5nZQogKiAgIG1ldGhvZCBpcyBub3QgYW4gYW5vbnltb3VzIG9uZS4gVGhpcyBtZXNzYWdlIHdpbGwgYWx3YXlzIGltbWVkaWF0ZWx5CiAqICAgZm9sbG93IHRoZSBzZXJ2ZXIgaGVsbG8gbWVzc2FnZS4KICoKICogTWVhbmluZyBvZiB0aGlzIG1lc3NhZ2U6CiAqICAgVGhlIGNlcnRpZmljYXRlIHR5cGUgbXVzdCBiZSBhcHByb3ByaWF0ZSBmb3IgdGhlIHNlbGVjdGVkIGNpcGhlciBzdWl0ZSdzCiAqICAga2V5IGV4Y2hhbmdlIGFsZ29yaXRobSwgYW5kIGlzIGdlbmVyYWxseSBhbiBYLjUwOXYzIGNlcnRpZmljYXRlLiBJdCBtdXN0CiAqICAgY29udGFpbiBhIGtleSB3aGljaCBtYXRjaGVzIHRoZSBrZXkgZXhjaGFuZ2UgbWV0aG9kLCBhcyBmb2xsb3dzLiBVbmxlc3MKICogICBvdGhlcndpc2Ugc3BlY2lmaWVkLCB0aGUgc2lnbmluZyBhbGdvcml0aG0gZm9yIHRoZSBjZXJ0aWZpY2F0ZSBtdXN0IGJlCiAqICAgdGhlIHNhbWUgYXMgdGhlIGFsZ29yaXRobSBmb3IgdGhlIGNlcnRpZmljYXRlIGtleS4gVW5sZXNzIG90aGVyd2lzZQogKiAgIHNwZWNpZmllZCwgdGhlIHB1YmxpYyBrZXkgbWF5IGJlIG9mIGFueSBsZW5ndGguCiAqCiAqIG9wYXF1ZSBBU04uMUNlcnQ8MS4uMl4yNC0xPjsKICogc3RydWN0IHsKICogICBBU04uMUNlcnQgY2VydGlmaWNhdGVfbGlzdDwxLi4yXjI0LTE+OwogKiB9IENlcnRpZmljYXRlOwogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlLgogKi8KdGxzLmhhbmRsZUNlcnRpZmljYXRlID0gZnVuY3Rpb24oYywgcmVjb3JkLCBsZW5ndGgpIHsKICAvLyBtaW5pbXVtIG9mIDMgYnl0ZXMgaW4gbWVzc2FnZQogIGlmKGxlbmd0aCA8IDMpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0ludmFsaWQgQ2VydGlmaWNhdGUgbWVzc2FnZS4gTWVzc2FnZSB0b28gc2hvcnQuJywKICAgICAgc2VuZDogdHJ1ZSwKICAgICAgYWxlcnQ6IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uaWxsZWdhbF9wYXJhbWV0ZXIKICAgICAgfQogICAgfSk7CiAgfQoKICB2YXIgYiA9IHJlY29yZC5mcmFnbWVudDsKICB2YXIgbXNnID0gewogICAgY2VydGlmaWNhdGVfbGlzdDogcmVhZFZlY3RvcihiLCAzKQogIH07CgogIC8qIFRoZSBzZW5kZXIncyBjZXJ0aWZpY2F0ZSB3aWxsIGJlIGZpcnN0IGluIHRoZSBsaXN0IChjaGFpbiksIGVhY2gKICAgIHN1YnNlcXVlbnQgb25lIHRoYXQgZm9sbG93cyB3aWxsIGNlcnRpZnkgdGhlIHByZXZpb3VzIG9uZSwgYnV0IHJvb3QKICAgIGNlcnRpZmljYXRlcyAoc2VsZi1zaWduZWQpIHRoYXQgc3BlY2lmeSB0aGUgY2VydGlmaWNhdGUgYXV0aG9yaXR5IG1heQogICAgYmUgb21pdHRlZCB1bmRlciB0aGUgYXNzdW1wdGlvbiB0aGF0IGNsaWVudHMgbXVzdCBhbHJlYWR5IHBvc3Nlc3MgaXQuICovCiAgdmFyIGNlcnQsIGFzbjE7CiAgdmFyIGNlcnRzID0gW107CiAgdHJ5IHsKICAgIHdoaWxlKG1zZy5jZXJ0aWZpY2F0ZV9saXN0Lmxlbmd0aCgpID4gMCkgewogICAgICAvLyBlYWNoIGVudHJ5IGluIG1zZy5jZXJ0aWZpY2F0ZV9saXN0IGlzIGEgdmVjdG9yIHdpdGggMyBsZW4gYnl0ZXMKICAgICAgY2VydCA9IHJlYWRWZWN0b3IobXNnLmNlcnRpZmljYXRlX2xpc3QsIDMpOwogICAgICBhc24xID0gZm9yZ2UuYXNuMS5mcm9tRGVyKGNlcnQpOwogICAgICBjZXJ0ID0gZm9yZ2UucGtpLmNlcnRpZmljYXRlRnJvbUFzbjEoYXNuMSwgdHJ1ZSk7CiAgICAgIGNlcnRzLnB1c2goY2VydCk7CiAgICB9CiAgfSBjYXRjaChleCkgewogICAgcmV0dXJuIGMuZXJyb3IoYywgewogICAgICBtZXNzYWdlOiAnQ291bGQgbm90IHBhcnNlIGNlcnRpZmljYXRlIGxpc3QuJywKICAgICAgY2F1c2U6IGV4LAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5iYWRfY2VydGlmaWNhdGUKICAgICAgfQogICAgfSk7CiAgfQoKICAvLyBlbnN1cmUgYXQgbGVhc3QgMSBjZXJ0aWZpY2F0ZSB3YXMgcHJvdmlkZWQgaWYgaW4gY2xpZW50LW1vZGUKICAvLyBvciBpZiB2ZXJpZnlDbGllbnQgd2FzIHNldCB0byB0cnVlIHRvIHJlcXVpcmUgYSBjZXJ0aWZpY2F0ZQogIC8vIChhcyBvcHBvc2VkIHRvICdvcHRpb25hbCcpCiAgdmFyIGNsaWVudCA9IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KTsKICBpZigoY2xpZW50IHx8IGMudmVyaWZ5Q2xpZW50ID09PSB0cnVlKSAmJiBjZXJ0cy5sZW5ndGggPT09IDApIHsKICAgIC8vIGVycm9yLCBubyBjZXJ0aWZpY2F0ZQogICAgYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6IGNsaWVudCA/CiAgICAgICAgJ05vIHNlcnZlciBjZXJ0aWZpY2F0ZSBwcm92aWRlZC4nIDoKICAgICAgICAnTm8gY2xpZW50IGNlcnRpZmljYXRlIHByb3ZpZGVkLicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmlsbGVnYWxfcGFyYW1ldGVyCiAgICAgIH0KICAgIH0pOwogIH0gZWxzZSBpZihjZXJ0cy5sZW5ndGggPT09IDApIHsKICAgIC8vIG5vIGNlcnRzIHRvIHZlcmlmeQogICAgLy8gZXhwZWN0IGEgU2VydmVyS2V5RXhjaGFuZ2Ugb3IgQ2xpZW50S2V5RXhjaGFuZ2UgbWVzc2FnZSBuZXh0CiAgICBjLmV4cGVjdCA9IGNsaWVudCA/IFNLRSA6IENLRTsKICB9IGVsc2UgewogICAgLy8gc2F2ZSBjZXJ0aWZpY2F0ZSBpbiBzZXNzaW9uCiAgICBpZihjbGllbnQpIHsKICAgICAgYy5zZXNzaW9uLnNlcnZlckNlcnRpZmljYXRlID0gY2VydHNbMF07CiAgICB9IGVsc2UgewogICAgICBjLnNlc3Npb24uY2xpZW50Q2VydGlmaWNhdGUgPSBjZXJ0c1swXTsKICAgIH0KCiAgICBpZih0bHMudmVyaWZ5Q2VydGlmaWNhdGVDaGFpbihjLCBjZXJ0cykpIHsKICAgICAgLy8gZXhwZWN0IGEgU2VydmVyS2V5RXhjaGFuZ2Ugb3IgQ2xpZW50S2V5RXhjaGFuZ2UgbWVzc2FnZSBuZXh0CiAgICAgIGMuZXhwZWN0ID0gY2xpZW50ID8gU0tFIDogQ0tFOwogICAgfQogIH0KCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIGNsaWVudCByZWNlaXZlcyBhIFNlcnZlcktleUV4Y2hhbmdlIHJlY29yZC4KICoKICogV2hlbiB0aGlzIG1lc3NhZ2Ugd2lsbCBiZSBzZW50OgogKiAgIFRoaXMgbWVzc2FnZSB3aWxsIGJlIHNlbnQgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIHNlcnZlciBjZXJ0aWZpY2F0ZQogKiAgIG1lc3NhZ2UgKG9yIHRoZSBzZXJ2ZXIgaGVsbG8gbWVzc2FnZSwgaWYgdGhpcyBpcyBhbiBhbm9ueW1vdXMKICogICBuZWdvdGlhdGlvbikuCiAqCiAqICAgVGhlIHNlcnZlciBrZXkgZXhjaGFuZ2UgbWVzc2FnZSBpcyBzZW50IGJ5IHRoZSBzZXJ2ZXIgb25seSB3aGVuIHRoZQogKiAgIHNlcnZlciBjZXJ0aWZpY2F0ZSBtZXNzYWdlIChpZiBzZW50KSBkb2VzIG5vdCBjb250YWluIGVub3VnaCBkYXRhIHRvCiAqICAgYWxsb3cgdGhlIGNsaWVudCB0byBleGNoYW5nZSBhIHByZW1hc3RlciBzZWNyZXQuCiAqCiAqIE1lYW5pbmcgb2YgdGhpcyBtZXNzYWdlOgogKiAgIFRoaXMgbWVzc2FnZSBjb252ZXlzIGNyeXB0b2dyYXBoaWMgaW5mb3JtYXRpb24gdG8gYWxsb3cgdGhlIGNsaWVudCB0bwogKiAgIGNvbW11bmljYXRlIHRoZSBwcmVtYXN0ZXIgc2VjcmV0OiBlaXRoZXIgYW4gUlNBIHB1YmxpYyBrZXkgdG8gZW5jcnlwdAogKiAgIHRoZSBwcmVtYXN0ZXIgc2VjcmV0IHdpdGgsIG9yIGEgRGlmZmllLUhlbGxtYW4gcHVibGljIGtleSB3aXRoIHdoaWNoIHRoZQogKiAgIGNsaWVudCBjYW4gY29tcGxldGUgYSBrZXkgZXhjaGFuZ2UgKHdpdGggdGhlIHJlc3VsdCBiZWluZyB0aGUgcHJlbWFzdGVyCiAqICAgc2VjcmV0LikKICoKICogZW51bSB7CiAqICAgZGhlX2RzcywgZGhlX3JzYSwgZGhfYW5vbiwgcnNhLCBkaF9kc3MsIGRoX3JzYQogKiB9IEtleUV4Y2hhbmdlQWxnb3JpdGhtOwogKgogKiBzdHJ1Y3QgewogKiAgIG9wYXF1ZSBkaF9wPDEuLjJeMTYtMT47CiAqICAgb3BhcXVlIGRoX2c8MS4uMl4xNi0xPjsKICogICBvcGFxdWUgZGhfWXM8MS4uMl4xNi0xPjsKICogfSBTZXJ2ZXJESFBhcmFtczsKICoKICogc3RydWN0IHsKICogICBzZWxlY3QoS2V5RXhjaGFuZ2VBbGdvcml0aG0pIHsKICogICAgIGNhc2UgZGhfYW5vbjoKICogICAgICAgU2VydmVyREhQYXJhbXMgcGFyYW1zOwogKiAgICAgY2FzZSBkaGVfZHNzOgogKiAgICAgY2FzZSBkaGVfcnNhOgogKiAgICAgICBTZXJ2ZXJESFBhcmFtcyBwYXJhbXM7CiAqICAgICAgIGRpZ2l0YWxseS1zaWduZWQgc3RydWN0IHsKICogICAgICAgICBvcGFxdWUgY2xpZW50X3JhbmRvbVszMl07CiAqICAgICAgICAgb3BhcXVlIHNlcnZlcl9yYW5kb21bMzJdOwogKiAgICAgICAgIFNlcnZlckRIUGFyYW1zIHBhcmFtczsKICogICAgICAgfSBzaWduZWRfcGFyYW1zOwogKiAgICAgY2FzZSByc2E6CiAqICAgICBjYXNlIGRoX2RzczoKICogICAgIGNhc2UgZGhfcnNhOgogKiAgICAgICBzdHJ1Y3Qge307CiAqICAgfTsKICogfSBTZXJ2ZXJLZXlFeGNoYW5nZTsKICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVTZXJ2ZXJLZXlFeGNoYW5nZSA9IGZ1bmN0aW9uKGMsIHJlY29yZCwgbGVuZ3RoKSB7CiAgLy8gdGhpcyBpbXBsZW1lbnRhdGlvbiBvbmx5IHN1cHBvcnRzIFJTQSwgbm8gRGlmZmllLUhlbGxtYW4gc3VwcG9ydAogIC8vIHNvIGFueSBsZW5ndGggPiAwIGlzIGludmFsaWQKICBpZihsZW5ndGggPiAwKSB7CiAgICByZXR1cm4gYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIGtleSBwYXJhbWV0ZXJzLiBPbmx5IFJTQSBpcyBzdXBwb3J0ZWQuJywKICAgICAgc2VuZDogdHJ1ZSwKICAgICAgYWxlcnQ6IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24udW5zdXBwb3J0ZWRfY2VydGlmaWNhdGUKICAgICAgfQogICAgfSk7CiAgfQoKICAvLyBleHBlY3QgYW4gb3B0aW9uYWwgQ2VydGlmaWNhdGVSZXF1ZXN0IG1lc3NhZ2UgbmV4dAogIGMuZXhwZWN0ID0gU0NSOwoKICAvLyBjb250aW51ZQogIGMucHJvY2VzcygpOwp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgY2xpZW50IHJlY2VpdmVzIGEgQ2xpZW50S2V5RXhjaGFuZ2UgcmVjb3JkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlLgogKi8KdGxzLmhhbmRsZUNsaWVudEtleUV4Y2hhbmdlID0gZnVuY3Rpb24oYywgcmVjb3JkLCBsZW5ndGgpIHsKICAvLyB0aGlzIGltcGxlbWVudGF0aW9uIG9ubHkgc3VwcG9ydHMgUlNBLCBubyBEaWZmaWUtSGVsbG1hbiBzdXBwb3J0CiAgLy8gc28gYW55IGxlbmd0aCA8IDQ4IGlzIGludmFsaWQKICBpZihsZW5ndGggPCA0OCkgewogICAgcmV0dXJuIGMuZXJyb3IoYywgewogICAgICBtZXNzYWdlOiAnSW52YWxpZCBrZXkgcGFyYW1ldGVycy4gT25seSBSU0EgaXMgc3VwcG9ydGVkLicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLnVuc3VwcG9ydGVkX2NlcnRpZmljYXRlCiAgICAgIH0KICAgIH0pOwogIH0KCiAgdmFyIGIgPSByZWNvcmQuZnJhZ21lbnQ7CiAgdmFyIG1zZyA9IHsKICAgIGVuY19wcmVfbWFzdGVyX3NlY3JldDogcmVhZFZlY3RvcihiLCAyKS5nZXRCeXRlcygpCiAgfTsKCiAgLy8gZG8gcnNhIGRlY3J5cHRpb24KICB2YXIgcHJpdmF0ZUtleSA9IG51bGw7CiAgaWYoYy5nZXRQcml2YXRlS2V5KSB7CiAgICB0cnkgewogICAgICBwcml2YXRlS2V5ID0gYy5nZXRQcml2YXRlS2V5KGMsIGMuc2Vzc2lvbi5zZXJ2ZXJDZXJ0aWZpY2F0ZSk7CiAgICAgIHByaXZhdGVLZXkgPSBmb3JnZS5wa2kucHJpdmF0ZUtleUZyb21QZW0ocHJpdmF0ZUtleSk7CiAgICB9IGNhdGNoKGV4KSB7CiAgICAgIGMuZXJyb3IoYywgewogICAgICAgIG1lc3NhZ2U6ICdDb3VsZCBub3QgZ2V0IHByaXZhdGUga2V5LicsCiAgICAgICAgY2F1c2U6IGV4LAogICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgfQogICAgICB9KTsKICAgIH0KICB9CgogIGlmKHByaXZhdGVLZXkgPT09IG51bGwpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ05vIHByaXZhdGUga2V5IHNldC4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5pbnRlcm5hbF9lcnJvcgogICAgICB9CiAgICB9KTsKICB9CgogIHRyeSB7CiAgICAvLyBkZWNyeXB0IDQ4LWJ5dGUgcHJlLW1hc3RlciBzZWNyZXQKICAgIHZhciBzcCA9IGMuc2Vzc2lvbi5zcDsKICAgIHNwLnByZV9tYXN0ZXJfc2VjcmV0ID0gcHJpdmF0ZUtleS5kZWNyeXB0KG1zZy5lbmNfcHJlX21hc3Rlcl9zZWNyZXQpOwoKICAgIC8vIGVuc3VyZSBjbGllbnQgaGVsbG8gdmVyc2lvbiBtYXRjaGVzIGZpcnN0IDIgYnl0ZXMKICAgIHZhciB2ZXJzaW9uID0gYy5zZXNzaW9uLmNsaWVudEhlbGxvVmVyc2lvbjsKICAgIGlmKHZlcnNpb24ubWFqb3IgIT09IHNwLnByZV9tYXN0ZXJfc2VjcmV0LmNoYXJDb2RlQXQoMCkgfHwKICAgICAgdmVyc2lvbi5taW5vciAhPT0gc3AucHJlX21hc3Rlcl9zZWNyZXQuY2hhckNvZGVBdCgxKSkgewogICAgICAvLyBlcnJvciwgZG8gbm90IHNlbmQgYWxlcnQgKHNlZSBCTEVJIGF0dGFjayBiZWxvdykKICAgICAgdGhyb3cgbmV3IEVycm9yKCdUTFMgdmVyc2lvbiByb2xsYmFjayBhdHRhY2sgZGV0ZWN0ZWQuJyk7CiAgICB9CiAgfSBjYXRjaChleCkgewogICAgLyogTm90ZTogRGFuaWVsIEJsZWljaGVuYmFjaGVyIFtCTEVJXSBjYW4gYmUgdXNlZCB0byBhdHRhY2sgYQogICAgICBUTFMgc2VydmVyIHdoaWNoIGlzIHVzaW5nIFBLQ1MjMSBlbmNvZGVkIFJTQSwgc28gaW5zdGVhZCBvZgogICAgICBmYWlsaW5nIGhlcmUsIHdlIGdlbmVyYXRlIDQ4IHJhbmRvbSBieXRlcyBhbmQgdXNlIHRoYXQgYXMKICAgICAgdGhlIHByZS1tYXN0ZXIgc2VjcmV0LiAqLwogICAgc3AucHJlX21hc3Rlcl9zZWNyZXQgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMoNDgpOwogIH0KCiAgLy8gZXhwZWN0IGEgQ2VydGlmaWNhdGVWZXJpZnkgbWVzc2FnZSBpZiBhIENlcnRpZmljYXRlIHdhcyByZWNlaXZlZCB0aGF0CiAgLy8gZG9lcyBub3QgaGF2ZSBmaXhlZCBEaWZmaWUtSGVsbG1hbiBwYXJhbXMsIG90aGVyd2lzZSBleHBlY3QKICAvLyBDaGFuZ2VDaXBoZXJTcGVjCiAgYy5leHBlY3QgPSBDQ0M7CiAgaWYoYy5zZXNzaW9uLmNsaWVudENlcnRpZmljYXRlICE9PSBudWxsKSB7CiAgICAvLyBvbmx5IFJTQSBzdXBwb3J0LCBzbyBleHBlY3QgQ2VydGlmaWNhdGVWZXJpZnkKICAgIC8vIFRPRE86IHN1cHBvcnQgRGlmZmllLUhlbGxtYW4KICAgIGMuZXhwZWN0ID0gQ0NWOwogIH0KCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIGNsaWVudCByZWNlaXZlcyBhIENlcnRpZmljYXRlUmVxdWVzdCByZWNvcmQuCiAqCiAqIFdoZW4gdGhpcyBtZXNzYWdlIHdpbGwgYmUgc2VudDoKICogICBBIG5vbi1hbm9ueW1vdXMgc2VydmVyIGNhbiBvcHRpb25hbGx5IHJlcXVlc3QgYSBjZXJ0aWZpY2F0ZSBmcm9tIHRoZQogKiAgIGNsaWVudCwgaWYgYXBwcm9wcmlhdGUgZm9yIHRoZSBzZWxlY3RlZCBjaXBoZXIgc3VpdGUuIFRoaXMgbWVzc2FnZSwgaWYKICogICBzZW50LCB3aWxsIGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgU2VydmVyIEtleSBFeGNoYW5nZSBtZXNzYWdlIChpZiBpdCBpcwogKiAgIHNlbnQ7IG90aGVyd2lzZSwgdGhlIFNlcnZlciBDZXJ0aWZpY2F0ZSBtZXNzYWdlKS4KICoKICogZW51bSB7CiAqICAgcnNhX3NpZ24oMSksIGRzc19zaWduKDIpLCByc2FfZml4ZWRfZGgoMyksIGRzc19maXhlZF9kaCg0KSwKICogICByc2FfZXBoZW1lcmFsX2RoX1JFU0VSVkVEKDUpLCBkc3NfZXBoZW1lcmFsX2RoX1JFU0VSVkVEKDYpLAogKiAgIGZvcnRlenphX2Rtc19SRVNFUlZFRCgyMCksICgyNTUpCiAqIH0gQ2xpZW50Q2VydGlmaWNhdGVUeXBlOwogKgogKiBvcGFxdWUgRGlzdGluZ3Vpc2hlZE5hbWU8MS4uMl4xNi0xPjsKICoKICogc3RydWN0IHsKICogICBDbGllbnRDZXJ0aWZpY2F0ZVR5cGUgY2VydGlmaWNhdGVfdHlwZXM8MS4uMl44LTE+OwogKiAgIFNpZ25hdHVyZUFuZEhhc2hBbGdvcml0aG0gc3VwcG9ydGVkX3NpZ25hdHVyZV9hbGdvcml0aG1zPDJeMTYtMT47CiAqICAgRGlzdGluZ3Vpc2hlZE5hbWUgY2VydGlmaWNhdGVfYXV0aG9yaXRpZXM8MC4uMl4xNi0xPjsKICogfSBDZXJ0aWZpY2F0ZVJlcXVlc3Q7CiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqIEBwYXJhbSBsZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgaGFuZHNoYWtlIG1lc3NhZ2UuCiAqLwp0bHMuaGFuZGxlQ2VydGlmaWNhdGVSZXF1ZXN0ID0gZnVuY3Rpb24oYywgcmVjb3JkLCBsZW5ndGgpIHsKICAvLyBtaW5pbXVtIG9mIDMgYnl0ZXMgaW4gbWVzc2FnZQogIGlmKGxlbmd0aCA8IDMpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0ludmFsaWQgQ2VydGlmaWNhdGVSZXF1ZXN0LiBNZXNzYWdlIHRvbyBzaG9ydC4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5pbGxlZ2FsX3BhcmFtZXRlcgogICAgICB9CiAgICB9KTsKICB9CgogIC8vIFRPRE86IFRMUyAxLjIrIGhhcyBkaWZmZXJlbnQgZm9ybWF0IGluY2x1ZGluZwogIC8vIFNpZ25hdHVyZUFuZEhhc2hBbGdvcml0aG0gYWZ0ZXIgY2VydCB0eXBlcwogIHZhciBiID0gcmVjb3JkLmZyYWdtZW50OwogIHZhciBtc2cgPSB7CiAgICBjZXJ0aWZpY2F0ZV90eXBlczogcmVhZFZlY3RvcihiLCAxKSwKICAgIGNlcnRpZmljYXRlX2F1dGhvcml0aWVzOiByZWFkVmVjdG9yKGIsIDIpCiAgfTsKCiAgLy8gc2F2ZSBjZXJ0aWZpY2F0ZSByZXF1ZXN0IGluIHNlc3Npb24KICBjLnNlc3Npb24uY2VydGlmaWNhdGVSZXF1ZXN0ID0gbXNnOwoKICAvLyBleHBlY3QgYSBTZXJ2ZXJIZWxsb0RvbmUgbWVzc2FnZSBuZXh0CiAgYy5leHBlY3QgPSBTSEQ7CgogIC8vIGNvbnRpbnVlCiAgYy5wcm9jZXNzKCk7Cn07CgovKioKICogQ2FsbGVkIHdoZW4gYSBzZXJ2ZXIgcmVjZWl2ZXMgYSBDZXJ0aWZpY2F0ZVZlcmlmeSByZWNvcmQuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqIEBwYXJhbSBsZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgaGFuZHNoYWtlIG1lc3NhZ2UuCiAqLwp0bHMuaGFuZGxlQ2VydGlmaWNhdGVWZXJpZnkgPSBmdW5jdGlvbihjLCByZWNvcmQsIGxlbmd0aCkgewogIGlmKGxlbmd0aCA8IDIpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0ludmFsaWQgQ2VydGlmaWNhdGVWZXJpZnkuIE1lc3NhZ2UgdG9vIHNob3J0LicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmlsbGVnYWxfcGFyYW1ldGVyCiAgICAgIH0KICAgIH0pOwogIH0KCiAgLy8gcmV3aW5kIHRvIGdldCBmdWxsIGJ5dGVzIGZvciBtZXNzYWdlIHNvIGl0IGNhbiBiZSBtYW51YWxseQogIC8vIGRpZ2VzdGVkIGJlbG93IChzcGVjaWFsIGNhc2UgZm9yIENlcnRpZmljYXRlVmVyaWZ5IG1lc3NhZ2VzIGJlY2F1c2UKICAvLyB0aGV5IG11c3QgYmUgZGlnZXN0ZWQgKmFmdGVyKiBoYW5kbGluZyBhcyBvcHBvc2VkIHRvIGFsbCBvdGhlcnMpCiAgdmFyIGIgPSByZWNvcmQuZnJhZ21lbnQ7CiAgYi5yZWFkIC09IDQ7CiAgdmFyIG1zZ0J5dGVzID0gYi5ieXRlcygpOwogIGIucmVhZCArPSA0OwoKICB2YXIgbXNnID0gewogICAgc2lnbmF0dXJlOiByZWFkVmVjdG9yKGIsIDIpLmdldEJ5dGVzKCkKICB9OwoKICAvLyBUT0RPOiBhZGQgc3VwcG9ydCBmb3IgRFNBCgogIC8vIGdlbmVyYXRlIGRhdGEgdG8gdmVyaWZ5CiAgdmFyIHZlcmlmeSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdmVyaWZ5LnB1dEJ1ZmZlcihjLnNlc3Npb24ubWQ1LmRpZ2VzdCgpKTsKICB2ZXJpZnkucHV0QnVmZmVyKGMuc2Vzc2lvbi5zaGExLmRpZ2VzdCgpKTsKICB2ZXJpZnkgPSB2ZXJpZnkuZ2V0Qnl0ZXMoKTsKCiAgdHJ5IHsKICAgIHZhciBjZXJ0ID0gYy5zZXNzaW9uLmNsaWVudENlcnRpZmljYXRlOwogICAgLypiID0gZm9yZ2UucGtpLnJzYS5kZWNyeXB0KAogICAgICBtc2cuc2lnbmF0dXJlLCBjZXJ0LnB1YmxpY0tleSwgdHJ1ZSwgdmVyaWZ5Lmxlbmd0aCk7CiAgICBpZihiICE9PSB2ZXJpZnkpIHsqLwogICAgaWYoIWNlcnQucHVibGljS2V5LnZlcmlmeSh2ZXJpZnksIG1zZy5zaWduYXR1cmUsICdOT05FJykpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKCdDZXJ0aWZpY2F0ZVZlcmlmeSBzaWduYXR1cmUgZG9lcyBub3QgbWF0Y2guJyk7CiAgICB9CgogICAgLy8gZGlnZXN0IG1lc3NhZ2Ugbm93IHRoYXQgaXQgaGFzIGJlZW4gaGFuZGxlZAogICAgYy5zZXNzaW9uLm1kNS51cGRhdGUobXNnQnl0ZXMpOwogICAgYy5zZXNzaW9uLnNoYTEudXBkYXRlKG1zZ0J5dGVzKTsKICB9IGNhdGNoKGV4KSB7CiAgICByZXR1cm4gYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6ICdCYWQgc2lnbmF0dXJlIGluIENlcnRpZmljYXRlVmVyaWZ5LicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmhhbmRzaGFrZV9mYWlsdXJlCiAgICAgIH0KICAgIH0pOwogIH0KCiAgLy8gZXhwZWN0IENoYW5nZUNpcGhlclNwZWMKICBjLmV4cGVjdCA9IENDQzsKCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIGNsaWVudCByZWNlaXZlcyBhIFNlcnZlckhlbGxvRG9uZSByZWNvcmQuCiAqCiAqIFdoZW4gdGhpcyBtZXNzYWdlIHdpbGwgYmUgc2VudDoKICogICBUaGUgc2VydmVyIGhlbGxvIGRvbmUgbWVzc2FnZSBpcyBzZW50IGJ5IHRoZSBzZXJ2ZXIgdG8gaW5kaWNhdGUgdGhlIGVuZAogKiAgIG9mIHRoZSBzZXJ2ZXIgaGVsbG8gYW5kIGFzc29jaWF0ZWQgbWVzc2FnZXMuIEFmdGVyIHNlbmRpbmcgdGhpcyBtZXNzYWdlCiAqICAgdGhlIHNlcnZlciB3aWxsIHdhaXQgZm9yIGEgY2xpZW50IHJlc3BvbnNlLgogKgogKiBNZWFuaW5nIG9mIHRoaXMgbWVzc2FnZToKICogICBUaGlzIG1lc3NhZ2UgbWVhbnMgdGhhdCB0aGUgc2VydmVyIGlzIGRvbmUgc2VuZGluZyBtZXNzYWdlcyB0byBzdXBwb3J0CiAqICAgdGhlIGtleSBleGNoYW5nZSwgYW5kIHRoZSBjbGllbnQgY2FuIHByb2NlZWQgd2l0aCBpdHMgcGhhc2Ugb2YgdGhlIGtleQogKiAgIGV4Y2hhbmdlLgogKgogKiAgIFVwb24gcmVjZWlwdCBvZiB0aGUgc2VydmVyIGhlbGxvIGRvbmUgbWVzc2FnZSB0aGUgY2xpZW50IHNob3VsZCB2ZXJpZnkKICogICB0aGF0IHRoZSBzZXJ2ZXIgcHJvdmlkZWQgYSB2YWxpZCBjZXJ0aWZpY2F0ZSBpZiByZXF1aXJlZCBhbmQgY2hlY2sgdGhhdAogKiAgIHRoZSBzZXJ2ZXIgaGVsbG8gcGFyYW1ldGVycyBhcmUgYWNjZXB0YWJsZS4KICoKICogc3RydWN0IHt9IFNlcnZlckhlbGxvRG9uZTsKICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVTZXJ2ZXJIZWxsb0RvbmUgPSBmdW5jdGlvbihjLCByZWNvcmQsIGxlbmd0aCkgewogIC8vIGxlbiBtdXN0IGJlIDAgYnl0ZXMKICBpZihsZW5ndGggPiAwKSB7CiAgICByZXR1cm4gYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIFNlcnZlckhlbGxvRG9uZSBtZXNzYWdlLiBJbnZhbGlkIGxlbmd0aC4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5yZWNvcmRfb3ZlcmZsb3cKICAgICAgfQogICAgfSk7CiAgfQoKICBpZihjLnNlcnZlckNlcnRpZmljYXRlID09PSBudWxsKSB7CiAgICAvLyBubyBzZXJ2ZXIgY2VydGlmaWNhdGUgd2FzIHByb3ZpZGVkCiAgICB2YXIgZXJyb3IgPSB7CiAgICAgIG1lc3NhZ2U6ICdObyBzZXJ2ZXIgY2VydGlmaWNhdGUgcHJvdmlkZWQuIE5vdCBlbm91Z2ggc2VjdXJpdHkuJywKICAgICAgc2VuZDogdHJ1ZSwKICAgICAgYWxlcnQ6IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uaW5zdWZmaWNpZW50X3NlY3VyaXR5CiAgICAgIH0KICAgIH07CgogICAgLy8gY2FsbCBhcHBsaWNhdGlvbiBjYWxsYmFjawogICAgdmFyIGRlcHRoID0gMDsKICAgIHZhciByZXQgPSBjLnZlcmlmeShjLCBlcnJvci5hbGVydC5kZXNjcmlwdGlvbiwgZGVwdGgsIFtdKTsKICAgIGlmKHJldCAhPT0gdHJ1ZSkgewogICAgICAvLyBjaGVjayBmb3IgY3VzdG9tIGFsZXJ0IGluZm8KICAgICAgaWYocmV0IHx8IHJldCA9PT0gMCkgewogICAgICAgIC8vIHNldCBjdXN0b20gbWVzc2FnZSBhbmQgYWxlcnQgZGVzY3JpcHRpb24KICAgICAgICBpZih0eXBlb2YgcmV0ID09PSAnb2JqZWN0JyAmJiAhZm9yZ2UudXRpbC5pc0FycmF5KHJldCkpIHsKICAgICAgICAgIGlmKHJldC5tZXNzYWdlKSB7CiAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgPSByZXQubWVzc2FnZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmKHJldC5hbGVydCkgewogICAgICAgICAgICBlcnJvci5hbGVydC5kZXNjcmlwdGlvbiA9IHJldC5hbGVydDsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYodHlwZW9mIHJldCA9PT0gJ251bWJlcicpIHsKICAgICAgICAgIC8vIHNldCBjdXN0b20gYWxlcnQgZGVzY3JpcHRpb24KICAgICAgICAgIGVycm9yLmFsZXJ0LmRlc2NyaXB0aW9uID0gcmV0OwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gc2VuZCBlcnJvcgogICAgICByZXR1cm4gYy5lcnJvcihjLCBlcnJvcik7CiAgICB9CiAgfQoKICAvLyBjcmVhdGUgY2xpZW50IGNlcnRpZmljYXRlIG1lc3NhZ2UgaWYgcmVxdWVzdGVkCiAgaWYoYy5zZXNzaW9uLmNlcnRpZmljYXRlUmVxdWVzdCAhPT0gbnVsbCkgewogICAgcmVjb3JkID0gdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgIHR5cGU6IHRscy5Db250ZW50VHlwZS5oYW5kc2hha2UsCiAgICAgIGRhdGE6IHRscy5jcmVhdGVDZXJ0aWZpY2F0ZShjKQogICAgfSk7CiAgICB0bHMucXVldWUoYywgcmVjb3JkKTsKICB9CgogIC8vIGNyZWF0ZSBjbGllbnQga2V5IGV4Y2hhbmdlIG1lc3NhZ2UKICByZWNvcmQgPSB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlLAogICAgIGRhdGE6IHRscy5jcmVhdGVDbGllbnRLZXlFeGNoYW5nZShjKQogIH0pOwogIHRscy5xdWV1ZShjLCByZWNvcmQpOwoKICAvLyBleHBlY3Qgbm8gbWVzc2FnZXMgdW50aWwgdGhlIGZvbGxvd2luZyBjYWxsYmFjayBoYXMgYmVlbiBjYWxsZWQKICBjLmV4cGVjdCA9IFNFUjsKCiAgLy8gY3JlYXRlIGNhbGxiYWNrIHRvIGhhbmRsZSBjbGllbnQgc2lnbmF0dXJlIChmb3IgY2xpZW50LWNlcnRzKQogIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uKGMsIHNpZ25hdHVyZSkgewogICAgaWYoYy5zZXNzaW9uLmNlcnRpZmljYXRlUmVxdWVzdCAhPT0gbnVsbCAmJgogICAgICBjLnNlc3Npb24uY2xpZW50Q2VydGlmaWNhdGUgIT09IG51bGwpIHsKICAgICAgLy8gY3JlYXRlIGNlcnRpZmljYXRlIHZlcmlmeSBtZXNzYWdlCiAgICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlLAogICAgICAgIGRhdGE6IHRscy5jcmVhdGVDZXJ0aWZpY2F0ZVZlcmlmeShjLCBzaWduYXR1cmUpCiAgICAgIH0pKTsKICAgIH0KCiAgICAvLyBjcmVhdGUgY2hhbmdlIGNpcGhlciBzcGVjIG1lc3NhZ2UKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmNoYW5nZV9jaXBoZXJfc3BlYywKICAgICAgZGF0YTogdGxzLmNyZWF0ZUNoYW5nZUNpcGhlclNwZWMoKQogICAgfSkpOwoKICAgIC8vIGNyZWF0ZSBwZW5kaW5nIHN0YXRlCiAgICBjLnN0YXRlLnBlbmRpbmcgPSB0bHMuY3JlYXRlQ29ubmVjdGlvblN0YXRlKGMpOwoKICAgIC8vIGNoYW5nZSBjdXJyZW50IHdyaXRlIHN0YXRlIHRvIHBlbmRpbmcgd3JpdGUgc3RhdGUKICAgIGMuc3RhdGUuY3VycmVudC53cml0ZSA9IGMuc3RhdGUucGVuZGluZy53cml0ZTsKCiAgICAvLyBjcmVhdGUgZmluaXNoZWQgbWVzc2FnZQogICAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVSZWNvcmQoYywgewogICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlLAogICAgICBkYXRhOiB0bHMuY3JlYXRlRmluaXNoZWQoYykKICAgIH0pKTsKCiAgICAvLyBleHBlY3QgYSBzZXJ2ZXIgQ2hhbmdlQ2lwaGVyU3BlYyBtZXNzYWdlIG5leHQKICAgIGMuZXhwZWN0ID0gU0NDOwoKICAgIC8vIHNlbmQgcmVjb3JkcwogICAgdGxzLmZsdXNoKGMpOwoKICAgIC8vIGNvbnRpbnVlCiAgICBjLnByb2Nlc3MoKTsKICB9OwoKICAvLyBpZiB0aGVyZSBpcyBubyBjZXJ0aWZpY2F0ZSByZXF1ZXN0IG9yIG5vIGNsaWVudCBjZXJ0aWZpY2F0ZSwgZG8KICAvLyBjYWxsYmFjayBpbW1lZGlhdGVseQogIGlmKGMuc2Vzc2lvbi5jZXJ0aWZpY2F0ZVJlcXVlc3QgPT09IG51bGwgfHwKICAgIGMuc2Vzc2lvbi5jbGllbnRDZXJ0aWZpY2F0ZSA9PT0gbnVsbCkgewogICAgcmV0dXJuIGNhbGxiYWNrKGMsIG51bGwpOwogIH0KCiAgLy8gb3RoZXJ3aXNlIGdldCB0aGUgY2xpZW50IHNpZ25hdHVyZQogIHRscy5nZXRDbGllbnRTaWduYXR1cmUoYywgY2FsbGJhY2spOwp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgQ2hhbmdlQ2lwaGVyU3BlYyByZWNvcmQgaXMgcmVjZWl2ZWQuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqLwp0bHMuaGFuZGxlQ2hhbmdlQ2lwaGVyU3BlYyA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogIGlmKHJlY29yZC5mcmFnbWVudC5nZXRCeXRlKCkgIT09IDB4MDEpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0ludmFsaWQgQ2hhbmdlQ2lwaGVyU3BlYyBtZXNzYWdlIHJlY2VpdmVkLicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmlsbGVnYWxfcGFyYW1ldGVyCiAgICAgIH0KICAgIH0pOwogIH0KCiAgLy8gY3JlYXRlIHBlbmRpbmcgc3RhdGUgaWY6CiAgLy8gMS4gUmVzdW1pbmcgc2Vzc2lvbiBpbiBjbGllbnQgbW9kZSBPUgogIC8vIDIuIE5PVCByZXN1bWluZyBzZXNzaW9uIGluIHNlcnZlciBtb2RlCiAgdmFyIGNsaWVudCA9IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KTsKICBpZigoYy5zZXNzaW9uLnJlc3VtaW5nICYmIGNsaWVudCkgfHwgKCFjLnNlc3Npb24ucmVzdW1pbmcgJiYgIWNsaWVudCkpIHsKICAgIGMuc3RhdGUucGVuZGluZyA9IHRscy5jcmVhdGVDb25uZWN0aW9uU3RhdGUoYyk7CiAgfQoKICAvLyBjaGFuZ2UgY3VycmVudCByZWFkIHN0YXRlIHRvIHBlbmRpbmcgcmVhZCBzdGF0ZQogIGMuc3RhdGUuY3VycmVudC5yZWFkID0gYy5zdGF0ZS5wZW5kaW5nLnJlYWQ7CgogIC8vIGNsZWFyIHBlbmRpbmcgc3RhdGUgaWY6CiAgLy8gMS4gTk9UIHJlc3VtaW5nIHNlc3Npb24gaW4gY2xpZW50IG1vZGUgT1IKICAvLyAyLiByZXN1bWluZyBhIHNlc3Npb24gaW4gc2VydmVyIG1vZGUKICBpZigoIWMuc2Vzc2lvbi5yZXN1bWluZyAmJiBjbGllbnQpIHx8IChjLnNlc3Npb24ucmVzdW1pbmcgJiYgIWNsaWVudCkpIHsKICAgIGMuc3RhdGUucGVuZGluZyA9IG51bGw7CiAgfQoKICAvLyBleHBlY3QgYSBGaW5pc2hlZCByZWNvcmQgbmV4dAogIGMuZXhwZWN0ID0gY2xpZW50ID8gU0ZJIDogQ0ZJOwoKICAvLyBjb250aW51ZQogIGMucHJvY2VzcygpOwp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgRmluaXNoZWQgcmVjb3JkIGlzIHJlY2VpdmVkLgogKgogKiBXaGVuIHRoaXMgbWVzc2FnZSB3aWxsIGJlIHNlbnQ6CiAqICAgQSBmaW5pc2hlZCBtZXNzYWdlIGlzIGFsd2F5cyBzZW50IGltbWVkaWF0ZWx5IGFmdGVyIGEgY2hhbmdlCiAqICAgY2lwaGVyIHNwZWMgbWVzc2FnZSB0byB2ZXJpZnkgdGhhdCB0aGUga2V5IGV4Y2hhbmdlIGFuZAogKiAgIGF1dGhlbnRpY2F0aW9uIHByb2Nlc3NlcyB3ZXJlIHN1Y2Nlc3NmdWwuIEl0IGlzIGVzc2VudGlhbCB0aGF0IGEKICogICBjaGFuZ2UgY2lwaGVyIHNwZWMgbWVzc2FnZSBiZSByZWNlaXZlZCBiZXR3ZWVuIHRoZSBvdGhlcgogKiAgIGhhbmRzaGFrZSBtZXNzYWdlcyBhbmQgdGhlIEZpbmlzaGVkIG1lc3NhZ2UuCiAqCiAqIE1lYW5pbmcgb2YgdGhpcyBtZXNzYWdlOgogKiAgIFRoZSBmaW5pc2hlZCBtZXNzYWdlIGlzIHRoZSBmaXJzdCBwcm90ZWN0ZWQgd2l0aCB0aGUganVzdC0KICogICBuZWdvdGlhdGVkIGFsZ29yaXRobXMsIGtleXMsIGFuZCBzZWNyZXRzLiBSZWNpcGllbnRzIG9mIGZpbmlzaGVkCiAqICAgbWVzc2FnZXMgbXVzdCB2ZXJpZnkgdGhhdCB0aGUgY29udGVudHMgYXJlIGNvcnJlY3QuICBPbmNlIGEgc2lkZQogKiAgIGhhcyBzZW50IGl0cyBGaW5pc2hlZCBtZXNzYWdlIGFuZCByZWNlaXZlZCBhbmQgdmFsaWRhdGVkIHRoZQogKiAgIEZpbmlzaGVkIG1lc3NhZ2UgZnJvbSBpdHMgcGVlciwgaXQgbWF5IGJlZ2luIHRvIHNlbmQgYW5kIHJlY2VpdmUKICogICBhcHBsaWNhdGlvbiBkYXRhIG92ZXIgdGhlIGNvbm5lY3Rpb24uCiAqCiAqIHN0cnVjdCB7CiAqICAgb3BhcXVlIHZlcmlmeV9kYXRhW3ZlcmlmeV9kYXRhX2xlbmd0aF07CiAqIH0gRmluaXNoZWQ7CiAqCiAqIHZlcmlmeV9kYXRhCiAqICAgUFJGKG1hc3Rlcl9zZWNyZXQsIGZpbmlzaGVkX2xhYmVsLCBIYXNoKGhhbmRzaGFrZV9tZXNzYWdlcykpCiAqICAgICBbMC4udmVyaWZ5X2RhdGFfbGVuZ3RoLTFdOwogKgogKiBmaW5pc2hlZF9sYWJlbAogKiAgIEZvciBGaW5pc2hlZCBtZXNzYWdlcyBzZW50IGJ5IHRoZSBjbGllbnQsIHRoZSBzdHJpbmcKICogICAiY2xpZW50IGZpbmlzaGVkIi4gRm9yIEZpbmlzaGVkIG1lc3NhZ2VzIHNlbnQgYnkgdGhlIHNlcnZlciwgdGhlCiAqICAgc3RyaW5nICJzZXJ2ZXIgZmluaXNoZWQiLgogKgogKiB2ZXJpZnlfZGF0YV9sZW5ndGggZGVwZW5kcyBvbiB0aGUgY2lwaGVyIHN1aXRlLiBJZiBpdCBpcyBub3Qgc3BlY2lmaWVkCiAqIGJ5IHRoZSBjaXBoZXIgc3VpdGUsIHRoZW4gaXQgaXMgMTIuIFZlcnNpb25zIG9mIFRMUyA8IDEuMiBhbHdheXMgdXNlZAogKiAxMiBieXRlcy4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVGaW5pc2hlZCA9IGZ1bmN0aW9uKGMsIHJlY29yZCwgbGVuZ3RoKSB7CiAgLy8gcmV3aW5kIHRvIGdldCBmdWxsIGJ5dGVzIGZvciBtZXNzYWdlIHNvIGl0IGNhbiBiZSBtYW51YWxseQogIC8vIGRpZ2VzdGVkIGJlbG93IChzcGVjaWFsIGNhc2UgZm9yIEZpbmlzaGVkIG1lc3NhZ2VzIGJlY2F1c2UgdGhleQogIC8vIG11c3QgYmUgZGlnZXN0ZWQgKmFmdGVyKiBoYW5kbGluZyBhcyBvcHBvc2VkIHRvIGFsbCBvdGhlcnMpCiAgdmFyIGIgPSByZWNvcmQuZnJhZ21lbnQ7CiAgYi5yZWFkIC09IDQ7CiAgdmFyIG1zZ0J5dGVzID0gYi5ieXRlcygpOwogIGIucmVhZCArPSA0OwoKICAvLyBtZXNzYWdlIGNvbnRhaW5zIG9ubHkgdmVyaWZ5X2RhdGEKICB2YXIgdmQgPSByZWNvcmQuZnJhZ21lbnQuZ2V0Qnl0ZXMoKTsKCiAgLy8gZW5zdXJlIHZlcmlmeSBkYXRhIGlzIGNvcnJlY3QKICBiID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBiLnB1dEJ1ZmZlcihjLnNlc3Npb24ubWQ1LmRpZ2VzdCgpKTsKICBiLnB1dEJ1ZmZlcihjLnNlc3Npb24uc2hhMS5kaWdlc3QoKSk7CgogIC8vIHNldCBsYWJlbCBiYXNlZCBvbiBlbnRpdHkgdHlwZQogIHZhciBjbGllbnQgPSAoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCk7CiAgdmFyIGxhYmVsID0gY2xpZW50ID8gJ3NlcnZlciBmaW5pc2hlZCcgOiAnY2xpZW50IGZpbmlzaGVkJzsKCiAgLy8gVE9ETzogZGV0ZXJtaW5lIHByZiBmdW5jdGlvbiBhbmQgdmVyaWZ5IGxlbmd0aCBmb3IgVExTIDEuMgogIHZhciBzcCA9IGMuc2Vzc2lvbi5zcDsKICB2YXIgdmRsID0gMTI7CiAgdmFyIHByZiA9IHByZl9UTFMxOwogIGIgPSBwcmYoc3AubWFzdGVyX3NlY3JldCwgbGFiZWwsIGIuZ2V0Qnl0ZXMoKSwgdmRsKTsKICBpZihiLmdldEJ5dGVzKCkgIT09IHZkKSB7CiAgICByZXR1cm4gYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIHZlcmlmeV9kYXRhIGluIEZpbmlzaGVkIG1lc3NhZ2UuJywKICAgICAgc2VuZDogdHJ1ZSwKICAgICAgYWxlcnQ6IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uZGVjcnlwdF9lcnJvcgogICAgICB9CiAgICB9KTsKICB9CgogIC8vIGRpZ2VzdCBmaW5pc2hlZCBtZXNzYWdlIG5vdyB0aGF0IGl0IGhhcyBiZWVuIGhhbmRsZWQKICBjLnNlc3Npb24ubWQ1LnVwZGF0ZShtc2dCeXRlcyk7CiAgYy5zZXNzaW9uLnNoYTEudXBkYXRlKG1zZ0J5dGVzKTsKCiAgLy8gcmVzdW1pbmcgc2Vzc2lvbiBhcyBjbGllbnQgb3IgTk9UIHJlc3VtaW5nIHNlc3Npb24gYXMgc2VydmVyCiAgaWYoKGMuc2Vzc2lvbi5yZXN1bWluZyAmJiBjbGllbnQpIHx8ICghYy5zZXNzaW9uLnJlc3VtaW5nICYmICFjbGllbnQpKSB7CiAgICAvLyBjcmVhdGUgY2hhbmdlIGNpcGhlciBzcGVjIG1lc3NhZ2UKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmNoYW5nZV9jaXBoZXJfc3BlYywKICAgICAgZGF0YTogdGxzLmNyZWF0ZUNoYW5nZUNpcGhlclNwZWMoKQogICAgfSkpOwoKICAgIC8vIGNoYW5nZSBjdXJyZW50IHdyaXRlIHN0YXRlIHRvIHBlbmRpbmcgd3JpdGUgc3RhdGUsIGNsZWFyIHBlbmRpbmcKICAgIGMuc3RhdGUuY3VycmVudC53cml0ZSA9IGMuc3RhdGUucGVuZGluZy53cml0ZTsKICAgIGMuc3RhdGUucGVuZGluZyA9IG51bGw7CgogICAgLy8gY3JlYXRlIGZpbmlzaGVkIG1lc3NhZ2UKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgICAgZGF0YTogdGxzLmNyZWF0ZUZpbmlzaGVkKGMpCiAgICB9KSk7CiAgfQoKICAvLyBleHBlY3QgYXBwbGljYXRpb24gZGF0YSBuZXh0CiAgYy5leHBlY3QgPSBjbGllbnQgPyBTQUQgOiBDQUQ7CgogIC8vIGhhbmRzaGFrZSBjb21wbGV0ZQogIGMuaGFuZHNoYWtpbmcgPSBmYWxzZTsKICArK2MuaGFuZHNoYWtlczsKCiAgLy8gc2F2ZSBhY2Nlc3MgdG8gcGVlciBjZXJ0aWZpY2F0ZQogIGMucGVlckNlcnRpZmljYXRlID0gY2xpZW50ID8KICAgIGMuc2Vzc2lvbi5zZXJ2ZXJDZXJ0aWZpY2F0ZSA6IGMuc2Vzc2lvbi5jbGllbnRDZXJ0aWZpY2F0ZTsKCiAgLy8gc2VuZCByZWNvcmRzCiAgdGxzLmZsdXNoKGMpOwoKICAvLyBub3cgY29ubmVjdGVkCiAgYy5pc0Nvbm5lY3RlZCA9IHRydWU7CiAgYy5jb25uZWN0ZWQoYyk7CgogIC8vIGNvbnRpbnVlCiAgYy5wcm9jZXNzKCk7Cn07CgovKioKICogQ2FsbGVkIHdoZW4gYW4gQWxlcnQgcmVjb3JkIGlzIHJlY2VpdmVkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKi8KdGxzLmhhbmRsZUFsZXJ0ID0gZnVuY3Rpb24oYywgcmVjb3JkKSB7CiAgLy8gcmVhZCBhbGVydAogIHZhciBiID0gcmVjb3JkLmZyYWdtZW50OwogIHZhciBhbGVydCA9IHsKICAgIGxldmVsOiBiLmdldEJ5dGUoKSwKICAgIGRlc2NyaXB0aW9uOiBiLmdldEJ5dGUoKQogIH07CgogIC8vIFRPRE86IGNvbnNpZGVyIHVzaW5nIGEgdGFibGU/CiAgLy8gZ2V0IGFwcHJvcHJpYXRlIG1lc3NhZ2UKICB2YXIgbXNnOwogIHN3aXRjaChhbGVydC5kZXNjcmlwdGlvbikgewogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNsb3NlX25vdGlmeToKICAgIG1zZyA9ICdDb25uZWN0aW9uIGNsb3NlZC4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24udW5leHBlY3RlZF9tZXNzYWdlOgogICAgbXNnID0gJ1VuZXhwZWN0ZWQgbWVzc2FnZS4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uYmFkX3JlY29yZF9tYWM6CiAgICBtc2cgPSAnQmFkIHJlY29yZCBNQUMuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmRlY3J5cHRpb25fZmFpbGVkOgogICAgbXNnID0gJ0RlY3J5cHRpb24gZmFpbGVkLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5yZWNvcmRfb3ZlcmZsb3c6CiAgICBtc2cgPSAnUmVjb3JkIG92ZXJmbG93Lic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5kZWNvbXByZXNzaW9uX2ZhaWx1cmU6CiAgICBtc2cgPSAnRGVjb21wcmVzc2lvbiBmYWlsZWQuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmhhbmRzaGFrZV9mYWlsdXJlOgogICAgbXNnID0gJ0hhbmRzaGFrZSBmYWlsdXJlLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5iYWRfY2VydGlmaWNhdGU6CiAgICBtc2cgPSAnQmFkIGNlcnRpZmljYXRlLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi51bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZToKICAgIG1zZyA9ICdVbnN1cHBvcnRlZCBjZXJ0aWZpY2F0ZS4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uY2VydGlmaWNhdGVfcmV2b2tlZDoKICAgIG1zZyA9ICdDZXJ0aWZpY2F0ZSByZXZva2VkLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5jZXJ0aWZpY2F0ZV9leHBpcmVkOgogICAgbXNnID0gJ0NlcnRpZmljYXRlIGV4cGlyZWQuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNlcnRpZmljYXRlX3Vua25vd246CiAgICBtc2cgPSAnQ2VydGlmaWNhdGUgdW5rbm93bi4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uaWxsZWdhbF9wYXJhbWV0ZXI6CiAgICBtc2cgPSAnSWxsZWdhbCBwYXJhbWV0ZXIuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLnVua25vd25fY2E6CiAgICBtc2cgPSAnVW5rbm93biBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmFjY2Vzc19kZW5pZWQ6CiAgICBtc2cgPSAnQWNjZXNzIGRlbmllZC4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uZGVjb2RlX2Vycm9yOgogICAgbXNnID0gJ0RlY29kZSBlcnJvci4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uZGVjcnlwdF9lcnJvcjoKICAgIG1zZyA9ICdEZWNyeXB0IGVycm9yLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5leHBvcnRfcmVzdHJpY3Rpb246CiAgICBtc2cgPSAnRXhwb3J0IHJlc3RyaWN0aW9uLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5wcm90b2NvbF92ZXJzaW9uOgogICAgbXNnID0gJ1Vuc3VwcG9ydGVkIHByb3RvY29sIHZlcnNpb24uJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmluc3VmZmljaWVudF9zZWN1cml0eToKICAgIG1zZyA9ICdJbnN1ZmZpY2llbnQgc2VjdXJpdHkuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yOgogICAgbXNnID0gJ0ludGVybmFsIGVycm9yLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi51c2VyX2NhbmNlbGVkOgogICAgbXNnID0gJ1VzZXIgY2FuY2VsZWQuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLm5vX3JlbmVnb3RpYXRpb246CiAgICBtc2cgPSAnUmVuZWdvdGlhdGlvbiBub3Qgc3VwcG9ydGVkLic7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgbXNnID0gJ1Vua25vd24gZXJyb3IuJzsKICAgIGJyZWFrOwogIH0KCiAgLy8gY2xvc2UgY29ubmVjdGlvbiBvbiBjbG9zZV9ub3RpZnksIG5vdCBhbiBlcnJvcgogIGlmKGFsZXJ0LmRlc2NyaXB0aW9uID09PSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uY2xvc2Vfbm90aWZ5KSB7CiAgICByZXR1cm4gYy5jbG9zZSgpOwogIH0KCiAgLy8gY2FsbCBlcnJvciBoYW5kbGVyCiAgYy5lcnJvcihjLCB7CiAgICBtZXNzYWdlOiBtc2csCiAgICBzZW5kOiBmYWxzZSwKICAgIC8vIG9yaWdpbiBpcyB0aGUgb3Bwb3NpdGUgZW5kCiAgICBvcmlnaW46IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KSA/ICdzZXJ2ZXInIDogJ2NsaWVudCcsCiAgICBhbGVydDogYWxlcnQKICB9KTsKCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIEhhbmRzaGFrZSByZWNvcmQgaXMgcmVjZWl2ZWQuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqLwp0bHMuaGFuZGxlSGFuZHNoYWtlID0gZnVuY3Rpb24oYywgcmVjb3JkKSB7CiAgLy8gZ2V0IHRoZSBoYW5kc2hha2UgdHlwZSBhbmQgbWVzc2FnZSBsZW5ndGgKICB2YXIgYiA9IHJlY29yZC5mcmFnbWVudDsKICB2YXIgdHlwZSA9IGIuZ2V0Qnl0ZSgpOwogIHZhciBsZW5ndGggPSBiLmdldEludDI0KCk7CgogIC8vIHNlZSBpZiB0aGUgcmVjb3JkIGZyYWdtZW50IGRvZXNuJ3QgeWV0IGNvbnRhaW4gdGhlIGZ1bGwgbWVzc2FnZQogIGlmKGxlbmd0aCA+IGIubGVuZ3RoKCkpIHsKICAgIC8vIGNhY2hlIHRoZSByZWNvcmQsIGNsZWFyIGl0cyBmcmFnbWVudCwgYW5kIHJlc2V0IHRoZSBidWZmZXIgcmVhZAogICAgLy8gcG9pbnRlciBiZWZvcmUgdGhlIHR5cGUgYW5kIGxlbmd0aCB3ZXJlIHJlYWQKICAgIGMuZnJhZ21lbnRlZCA9IHJlY29yZDsKICAgIHJlY29yZC5mcmFnbWVudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBiLnJlYWQgLT0gNDsKCiAgICAvLyBjb250aW51ZQogICAgcmV0dXJuIGMucHJvY2VzcygpOwogIH0KCiAgLy8gZnVsbCBtZXNzYWdlIG5vdyBhdmFpbGFibGUsIGNsZWFyIGNhY2hlLCByZXNldCByZWFkIHBvaW50ZXIgdG8KICAvLyBiZWZvcmUgdHlwZSBhbmQgbGVuZ3RoCiAgYy5mcmFnbWVudGVkID0gbnVsbDsKICBiLnJlYWQgLT0gNDsKCiAgLy8gc2F2ZSB0aGUgaGFuZHNoYWtlIGJ5dGVzIGZvciBkaWdlc3Rpb24gYWZ0ZXIgaGFuZGxlciBpcyBmb3VuZAogIC8vIChpbmNsdWRlIHR5cGUgYW5kIGxlbmd0aCBvZiBoYW5kc2hha2UgbXNnKQogIHZhciBieXRlcyA9IGIuYnl0ZXMobGVuZ3RoICsgNCk7CgogIC8vIHJlc3RvcmUgcmVhZCBwb2ludGVyCiAgYi5yZWFkICs9IDQ7CgogIC8vIGhhbmRsZSBleHBlY3RlZCBtZXNzYWdlCiAgaWYodHlwZSBpbiBoc1RhYmxlW2MuZW50aXR5XVtjLmV4cGVjdF0pIHsKICAgIC8vIGluaXRpYWxpemUgc2VydmVyIHNlc3Npb24KICAgIGlmKGMuZW50aXR5ID09PSB0bHMuQ29ubmVjdGlvbkVuZC5zZXJ2ZXIgJiYgIWMub3BlbiAmJiAhYy5mYWlsKSB7CiAgICAgIGMuaGFuZHNoYWtpbmcgPSB0cnVlOwogICAgICBjLnNlc3Npb24gPSB7CiAgICAgICAgdmVyc2lvbjogbnVsbCwKICAgICAgICBleHRlbnNpb25zOiB7CiAgICAgICAgICBzZXJ2ZXJfbmFtZTogewogICAgICAgICAgICBzZXJ2ZXJOYW1lTGlzdDogW10KICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGNpcGhlclN1aXRlOiBudWxsLAogICAgICAgIGNvbXByZXNzaW9uTWV0aG9kOiBudWxsLAogICAgICAgIHNlcnZlckNlcnRpZmljYXRlOiBudWxsLAogICAgICAgIGNsaWVudENlcnRpZmljYXRlOiBudWxsLAogICAgICAgIG1kNTogZm9yZ2UubWQubWQ1LmNyZWF0ZSgpLAogICAgICAgIHNoYTE6IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCkKICAgICAgfTsKICAgIH0KCiAgICAvKiBVcGRhdGUgaGFuZHNoYWtlIG1lc3NhZ2VzIGRpZ2VzdC4gRmluaXNoZWQgYW5kIENlcnRpZmljYXRlVmVyaWZ5CiAgICAgIG1lc3NhZ2VzIGFyZSBub3QgZGlnZXN0ZWQgaGVyZS4gVGhleSBjYW4ndCBiZSBkaWdlc3RlZCBhcyBwYXJ0IG9mCiAgICAgIHRoZSB2ZXJpZnlfZGF0YSB0aGF0IHRoZXkgY29udGFpbi4gVGhlc2UgbWVzc2FnZXMgYXJlIG1hbnVhbGx5CiAgICAgIGRpZ2VzdGVkIGluIHRoZWlyIGhhbmRsZXJzLiBIZWxsb1JlcXVlc3QgbWVzc2FnZXMgYXJlIHNpbXBseSBuZXZlcgogICAgICBpbmNsdWRlZCBpbiB0aGUgaGFuZHNoYWtlIG1lc3NhZ2UgZGlnZXN0IGFjY29yZGluZyB0byBzcGVjLiAqLwogICAgaWYodHlwZSAhPT0gdGxzLkhhbmRzaGFrZVR5cGUuaGVsbG9fcmVxdWVzdCAmJgogICAgICB0eXBlICE9PSB0bHMuSGFuZHNoYWtlVHlwZS5jZXJ0aWZpY2F0ZV92ZXJpZnkgJiYKICAgICAgdHlwZSAhPT0gdGxzLkhhbmRzaGFrZVR5cGUuZmluaXNoZWQpIHsKICAgICAgYy5zZXNzaW9uLm1kNS51cGRhdGUoYnl0ZXMpOwogICAgICBjLnNlc3Npb24uc2hhMS51cGRhdGUoYnl0ZXMpOwogICAgfQoKICAgIC8vIGhhbmRsZSBzcGVjaWZpYyBoYW5kc2hha2UgdHlwZSByZWNvcmQKICAgIGhzVGFibGVbYy5lbnRpdHldW2MuZXhwZWN0XVt0eXBlXShjLCByZWNvcmQsIGxlbmd0aCk7CiAgfSBlbHNlIHsKICAgIC8vIHVuZXhwZWN0ZWQgcmVjb3JkCiAgICB0bHMuaGFuZGxlVW5leHBlY3RlZChjLCByZWNvcmQpOwogIH0KfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhbiBBcHBsaWNhdGlvbkRhdGEgcmVjb3JkIGlzIHJlY2VpdmVkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKi8KdGxzLmhhbmRsZUFwcGxpY2F0aW9uRGF0YSA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogIC8vIGJ1ZmZlciBkYXRhLCBub3RpZnkgdGhhdCBpdHMgcmVhZHkKICBjLmRhdGEucHV0QnVmZmVyKHJlY29yZC5mcmFnbWVudCk7CiAgYy5kYXRhUmVhZHkoYyk7CgogIC8vIGNvbnRpbnVlCiAgYy5wcm9jZXNzKCk7Cn07CgovKioKICogQ2FsbGVkIHdoZW4gYSBIZWFydGJlYXQgcmVjb3JkIGlzIHJlY2VpdmVkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKi8KdGxzLmhhbmRsZUhlYXJ0YmVhdCA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogIC8vIGdldCB0aGUgaGVhcnRiZWF0IHR5cGUgYW5kIHBheWxvYWQKICB2YXIgYiA9IHJlY29yZC5mcmFnbWVudDsKICB2YXIgdHlwZSA9IGIuZ2V0Qnl0ZSgpOwogIHZhciBsZW5ndGggPSBiLmdldEludDE2KCk7CiAgdmFyIHBheWxvYWQgPSBiLmdldEJ5dGVzKGxlbmd0aCk7CgogIGlmKHR5cGUgPT09IHRscy5IZWFydGJlYXRNZXNzYWdlVHlwZS5oZWFydGJlYXRfcmVxdWVzdCkgewogICAgLy8gZGlzY2FyZCByZXF1ZXN0IGR1cmluZyBoYW5kc2hha2Ugb3IgaWYgbGVuZ3RoIGlzIHRvbyBsYXJnZQogICAgaWYoYy5oYW5kc2hha2luZyB8fCBsZW5ndGggPiBwYXlsb2FkLmxlbmd0aCkgewogICAgICAvLyBjb250aW51ZQogICAgICByZXR1cm4gYy5wcm9jZXNzKCk7CiAgICB9CiAgICAvLyByZXRyYW5zbWl0IHBheWxvYWQKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhlYXJ0YmVhdCwKICAgICAgZGF0YTogdGxzLmNyZWF0ZUhlYXJ0YmVhdCgKICAgICAgICB0bHMuSGVhcnRiZWF0TWVzc2FnZVR5cGUuaGVhcnRiZWF0X3Jlc3BvbnNlLCBwYXlsb2FkKQogICAgfSkpOwogICAgdGxzLmZsdXNoKGMpOwogIH0gZWxzZSBpZih0eXBlID09PSB0bHMuSGVhcnRiZWF0TWVzc2FnZVR5cGUuaGVhcnRiZWF0X3Jlc3BvbnNlKSB7CiAgICAvLyBjaGVjayBwYXlsb2FkIGFnYWluc3QgZXhwZWN0ZWQgcGF5bG9hZCwgZGlzY2FyZCBoZWFydGJlYXQgaWYgbm8gbWF0Y2gKICAgIGlmKHBheWxvYWQgIT09IGMuZXhwZWN0ZWRIZWFydGJlYXRQYXlsb2FkKSB7CiAgICAgIC8vIGNvbnRpbnVlCiAgICAgIHJldHVybiBjLnByb2Nlc3MoKTsKICAgIH0KCiAgICAvLyBub3RpZnkgdGhhdCBhIHZhbGlkIGhlYXJ0YmVhdCB3YXMgcmVjZWl2ZWQKICAgIGlmKGMuaGVhcnRiZWF0UmVjZWl2ZWQpIHsKICAgICAgYy5oZWFydGJlYXRSZWNlaXZlZChjLCBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihwYXlsb2FkKSk7CiAgICB9CiAgfQoKICAvLyBjb250aW51ZQogIGMucHJvY2VzcygpOwp9OwoKLyoqCiAqIFRoZSB0cmFuc2lzdGlvbmFsIHN0YXRlIHRhYmxlcyBmb3IgcmVjZWl2aW5nIFRMUyByZWNvcmRzLiBJdCBtYXBzIHRoZQogKiBjdXJyZW50IFRMUyBlbmdpbmUgc3RhdGUgYW5kIGEgcmVjZWl2ZWQgcmVjb3JkIHRvIGEgZnVuY3Rpb24gdG8gaGFuZGxlIHRoZQogKiByZWNvcmQgYW5kIHVwZGF0ZSB0aGUgc3RhdGUuCiAqCiAqIEZvciBpbnN0YW5jZSwgaWYgdGhlIGN1cnJlbnQgc3RhdGUgaXMgU0hFLCB0aGVuIHRoZSBUTFMgZW5naW5lIGlzIGV4cGVjdGluZwogKiBhIFNlcnZlckhlbGxvIHJlY29yZC4gT25jZSBhIHJlY29yZCBpcyByZWNlaXZlZCwgdGhlIGhhbmRsZXIgZnVuY3Rpb24gaXMKICogbG9va2VkIHVwIHVzaW5nIHRoZSBzdGF0ZSBTSEUgYW5kIHRoZSByZWNvcmQncyBjb250ZW50IHR5cGUuCiAqCiAqIFRoZSByZXN1bHRpbmcgZnVuY3Rpb24gd2lsbCBlaXRoZXIgYmUgYW4gZXJyb3IgaGFuZGxlciBvciBhIHJlY29yZCBoYW5kbGVyLgogKiBUaGUgZnVuY3Rpb24gd2lsbCB0YWtlIHdoYXRldmVyIGFjdGlvbiBpcyBhcHByb3ByaWF0ZSBhbmQgdXBkYXRlIHRoZSBzdGF0ZQogKiBmb3IgdGhlIG5leHQgcmVjb3JkLgogKgogKiBUaGUgc3RhdGVzIGFyZSBhbGwgYmFzZWQgb24gcG9zc2libGUgc2VydmVyIHJlY29yZCB0eXBlcy4gTm90ZSB0aGF0IHRoZQogKiBjbGllbnQgd2lsbCBuZXZlciBzcGVjaWZpY2FsbHkgZXhwZWN0IHRvIHJlY2VpdmUgYSBIZWxsb1JlcXVlc3Qgb3IgYW4gYWxlcnQKICogZnJvbSB0aGUgc2VydmVyIHNvIHRoZXJlIGlzIG5vIHN0YXRlIHRoYXQgcmVmbGVjdHMgdGhpcy4gVGhlc2UgbWVzc2FnZXMgbWF5CiAqIG9jY3VyIGF0IGFueSB0aW1lLgogKgogKiBUaGVyZSBhcmUgdHdvIHRhYmxlcyBmb3IgbWFwcGluZyBzdGF0ZXMgYmVjYXVzZSB0aGVyZSBpcyBhIHNlY29uZCB0aWVyIG9mCiAqIHR5cGVzIGZvciBoYW5kc2hha2UgbWVzc2FnZXMuIE9uY2UgYSByZWNvcmQgd2l0aCBhIGNvbnRlbnQgdHlwZSBvZiBoYW5kc2hha2UKICogaXMgcmVjZWl2ZWQsIHRoZSBoYW5kc2hha2UgcmVjb3JkIGhhbmRsZXIgd2lsbCBsb29rIHVwIHRoZSBoYW5kc2hha2UgdHlwZSBpbgogKiB0aGUgc2Vjb25kYXJ5IG1hcCB0byBnZXQgaXRzIGFwcHJvcHJpYXRlIGhhbmRsZXIuCiAqCiAqIFZhbGlkIG1lc3NhZ2Ugb3JkZXJzIGFyZSBhcyBmb2xsb3dzOgogKgogKiA9PT09PT09PT09PT09PT09PT09PT09PUZVTEwgSEFORFNIQUtFPT09PT09PT09PT09PT09PT09PT09PQogKiBDbGllbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlcnZlcgogKgogKiBDbGllbnRIZWxsbyAgICAgICAgICAgICAgICAgIC0tLS0tLS0tPgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXJ2ZXJIZWxsbwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENlcnRpZmljYXRlKgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlcnZlcktleUV4Y2hhbmdlKgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVSZXF1ZXN0KgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwtLS0tLS0tLSAgICAgIFNlcnZlckhlbGxvRG9uZQogKiBDZXJ0aWZpY2F0ZSoKICogQ2xpZW50S2V5RXhjaGFuZ2UKICogQ2VydGlmaWNhdGVWZXJpZnkqCiAqIFtDaGFuZ2VDaXBoZXJTcGVjXQogKiBGaW5pc2hlZCAgICAgICAgICAgICAgICAgICAgIC0tLS0tLS0tPgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtDaGFuZ2VDaXBoZXJTcGVjXQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwtLS0tLS0tLSAgICAgICAgICAgICBGaW5pc2hlZAogKiBBcHBsaWNhdGlvbiBEYXRhICAgICAgICAgICAgIDwtLS0tLS0tPiAgICAgQXBwbGljYXRpb24gRGF0YQogKgogKiA9PT09PT09PT09PT09PT09PT09PT1TRVNTSU9OIFJFU1VNUFRJT049PT09PT09PT09PT09PT09PT09PT0KICogQ2xpZW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VydmVyCiAqCiAqIENsaWVudEhlbGxvICAgICAgICAgICAgICAgICAgIC0tLS0tLS0tPgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VydmVySGVsbG8KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW0NoYW5nZUNpcGhlclNwZWNdCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwtLS0tLS0tLSAgICAgICAgICAgICBGaW5pc2hlZAogKiBbQ2hhbmdlQ2lwaGVyU3BlY10KICogRmluaXNoZWQgICAgICAgICAgICAgICAgICAgICAgLS0tLS0tLS0+CiAqIEFwcGxpY2F0aW9uIERhdGEgICAgICAgICAgICAgIDwtLS0tLS0tPiAgICAgQXBwbGljYXRpb24gRGF0YQogKi8KLy8gY2xpZW50IGV4cGVjdCBzdGF0ZXMgKGluZGljYXRlIHdoaWNoIHJlY29yZHMgYXJlIGV4cGVjdGVkIHRvIGJlIHJlY2VpdmVkKQp2YXIgU0hFID0gMDsgLy8gcmN2IHNlcnZlciBoZWxsbwp2YXIgU0NFID0gMTsgLy8gcmN2IHNlcnZlciBjZXJ0aWZpY2F0ZQp2YXIgU0tFID0gMjsgLy8gcmN2IHNlcnZlciBrZXkgZXhjaGFuZ2UKdmFyIFNDUiA9IDM7IC8vIHJjdiBjZXJ0aWZpY2F0ZSByZXF1ZXN0CnZhciBTSEQgPSA0OyAvLyByY3Ygc2VydmVyIGhlbGxvIGRvbmUKdmFyIFNDQyA9IDU7IC8vIHJjdiBjaGFuZ2UgY2lwaGVyIHNwZWMKdmFyIFNGSSA9IDY7IC8vIHJjdiBmaW5pc2hlZAp2YXIgU0FEID0gNzsgLy8gcmN2IGFwcGxpY2F0aW9uIGRhdGEKdmFyIFNFUiA9IDg7IC8vIG5vdCBleHBlY3RpbmcgYW55IG1lc3NhZ2VzIGF0IHRoaXMgcG9pbnQKCi8vIHNlcnZlciBleHBlY3Qgc3RhdGVzCnZhciBDSEUgPSAwOyAvLyByY3YgY2xpZW50IGhlbGxvCnZhciBDQ0UgPSAxOyAvLyByY3YgY2xpZW50IGNlcnRpZmljYXRlCnZhciBDS0UgPSAyOyAvLyByY3YgY2xpZW50IGtleSBleGNoYW5nZQp2YXIgQ0NWID0gMzsgLy8gcmN2IGNlcnRpZmljYXRlIHZlcmlmeQp2YXIgQ0NDID0gNDsgLy8gcmN2IGNoYW5nZSBjaXBoZXIgc3BlYwp2YXIgQ0ZJID0gNTsgLy8gcmN2IGZpbmlzaGVkCnZhciBDQUQgPSA2OyAvLyByY3YgYXBwbGljYXRpb24gZGF0YQp2YXIgQ0VSID0gNzsgLy8gbm90IGV4cGVjdGluZyBhbnkgbWVzc2FnZXMgYXQgdGhpcyBwb2ludAoKLy8gbWFwIGNsaWVudCBjdXJyZW50IGV4cGVjdCBzdGF0ZSBhbmQgY29udGVudCB0eXBlIHRvIGZ1bmN0aW9uCnZhciBfXyA9IHRscy5oYW5kbGVVbmV4cGVjdGVkOwp2YXIgUjAgPSB0bHMuaGFuZGxlQ2hhbmdlQ2lwaGVyU3BlYzsKdmFyIFIxID0gdGxzLmhhbmRsZUFsZXJ0Owp2YXIgUjIgPSB0bHMuaGFuZGxlSGFuZHNoYWtlOwp2YXIgUjMgPSB0bHMuaGFuZGxlQXBwbGljYXRpb25EYXRhOwp2YXIgUjQgPSB0bHMuaGFuZGxlSGVhcnRiZWF0Owp2YXIgY3RUYWJsZSA9IFtdOwpjdFRhYmxlW3Rscy5Db25uZWN0aW9uRW5kLmNsaWVudF0gPSBbCi8vICAgICAgQ0MsQUwsSFMsQUQsSEIKLypTSEUqL1tfXyxSMSxSMixfXyxSNF0sCi8qU0NFKi9bX18sUjEsUjIsX18sUjRdLAovKlNLRSovW19fLFIxLFIyLF9fLFI0XSwKLypTQ1IqL1tfXyxSMSxSMixfXyxSNF0sCi8qU0hEKi9bX18sUjEsUjIsX18sUjRdLAovKlNDQyovW1IwLFIxLF9fLF9fLFI0XSwKLypTRkkqL1tfXyxSMSxSMixfXyxSNF0sCi8qU0FEKi9bX18sUjEsUjIsUjMsUjRdLAovKlNFUiovW19fLFIxLFIyLF9fLFI0XQpdOwoKLy8gbWFwIHNlcnZlciBjdXJyZW50IGV4cGVjdCBzdGF0ZSBhbmQgY29udGVudCB0eXBlIHRvIGZ1bmN0aW9uCmN0VGFibGVbdGxzLkNvbm5lY3Rpb25FbmQuc2VydmVyXSA9IFsKLy8gICAgICBDQyxBTCxIUyxBRAovKkNIRSovW19fLFIxLFIyLF9fLFI0XSwKLypDQ0UqL1tfXyxSMSxSMixfXyxSNF0sCi8qQ0tFKi9bX18sUjEsUjIsX18sUjRdLAovKkNDViovW19fLFIxLFIyLF9fLFI0XSwKLypDQ0MqL1tSMCxSMSxfXyxfXyxSNF0sCi8qQ0ZJKi9bX18sUjEsUjIsX18sUjRdLAovKkNBRCovW19fLFIxLFIyLFIzLFI0XSwKLypDRVIqL1tfXyxSMSxSMixfXyxSNF0KXTsKCi8vIG1hcCBjbGllbnQgY3VycmVudCBleHBlY3Qgc3RhdGUgYW5kIGhhbmRzaGFrZSB0eXBlIHRvIGZ1bmN0aW9uCnZhciBIMCA9IHRscy5oYW5kbGVIZWxsb1JlcXVlc3Q7CnZhciBIMSA9IHRscy5oYW5kbGVTZXJ2ZXJIZWxsbzsKdmFyIEgyID0gdGxzLmhhbmRsZUNlcnRpZmljYXRlOwp2YXIgSDMgPSB0bHMuaGFuZGxlU2VydmVyS2V5RXhjaGFuZ2U7CnZhciBINCA9IHRscy5oYW5kbGVDZXJ0aWZpY2F0ZVJlcXVlc3Q7CnZhciBINSA9IHRscy5oYW5kbGVTZXJ2ZXJIZWxsb0RvbmU7CnZhciBINiA9IHRscy5oYW5kbGVGaW5pc2hlZDsKdmFyIGhzVGFibGUgPSBbXTsKaHNUYWJsZVt0bHMuQ29ubmVjdGlvbkVuZC5jbGllbnRdID0gWwovLyAgICAgIEhSLDAxLFNILDAzLDA0LDA1LDA2LDA3LDA4LDA5LDEwLFNDLFNLLENSLEhELDE1LENLLDE3LDE4LDE5LEZJCi8qU0hFKi9bX18sX18sSDEsX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX19dLAovKlNDRSovW0gwLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLEgyLEgzLEg0LEg1LF9fLF9fLF9fLF9fLF9fLF9fXSwKLypTS0UqL1tIMCxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxIMyxINCxINSxfXyxfXyxfXyxfXyxfXyxfX10sCi8qU0NSKi9bSDAsX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sSDQsSDUsX18sX18sX18sX18sX18sX19dLAovKlNIRCovW0gwLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLEg1LF9fLF9fLF9fLF9fLF9fLF9fXSwKLypTQ0MqL1tIMCxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfX10sCi8qU0ZJKi9bSDAsX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sSDZdLAovKlNBRCovW0gwLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fXSwKLypTRVIqL1tIMCxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfX10KXTsKCi8vIG1hcCBzZXJ2ZXIgY3VycmVudCBleHBlY3Qgc3RhdGUgYW5kIGhhbmRzaGFrZSB0eXBlIHRvIGZ1bmN0aW9uCi8vIE5vdGU6IENBRFtDSF0gZG9lcyBub3QgbWFwIHRvIEZCIGJlY2F1c2UgcmVuZWdvdGF0aW9uIGlzIHByb2hpYml0ZWQKdmFyIEg3ID0gdGxzLmhhbmRsZUNsaWVudEhlbGxvOwp2YXIgSDggPSB0bHMuaGFuZGxlQ2xpZW50S2V5RXhjaGFuZ2U7CnZhciBIOSA9IHRscy5oYW5kbGVDZXJ0aWZpY2F0ZVZlcmlmeTsKaHNUYWJsZVt0bHMuQ29ubmVjdGlvbkVuZC5zZXJ2ZXJdID0gWwovLyAgICAgIDAxLENILDAyLDAzLDA0LDA1LDA2LDA3LDA4LDA5LDEwLENDLDEyLDEzLDE0LENWLENLLDE3LDE4LDE5LEZJCi8qQ0hFKi9bX18sSDcsX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX19dLAovKkNDRSovW19fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLEgyLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fXSwKLypDS0UqL1tfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxIOCxfXyxfXyxfXyxfX10sCi8qQ0NWKi9bX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sSDksX18sX18sX18sX18sX19dLAovKkNDQyovW19fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fXSwKLypDRkkqL1tfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxINl0sCi8qQ0FEKi9bX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX19dLAovKkNFUiovW19fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fXQpdOwoKLyoqCiAqIEdlbmVyYXRlcyB0aGUgbWFzdGVyX3NlY3JldCBhbmQga2V5cyB1c2luZyB0aGUgZ2l2ZW4gc2VjdXJpdHkgcGFyYW1ldGVycy4KICoKICogVGhlIHNlY3VyaXR5IHBhcmFtZXRlcnMgZm9yIGEgVExTIGNvbm5lY3Rpb24gc3RhdGUgYXJlIGRlZmluZWQgYXMgc3VjaDoKICoKICogc3RydWN0IHsKICogICBDb25uZWN0aW9uRW5kICAgICAgICAgIGVudGl0eTsKICogICBQUkZBbGdvcml0aG0gICAgICAgICAgIHByZl9hbGdvcml0aG07CiAqICAgQnVsa0NpcGhlckFsZ29yaXRobSAgICBidWxrX2NpcGhlcl9hbGdvcml0aG07CiAqICAgQ2lwaGVyVHlwZSAgICAgICAgICAgICBjaXBoZXJfdHlwZTsKICogICB1aW50OCAgICAgICAgICAgICAgICAgIGVuY19rZXlfbGVuZ3RoOwogKiAgIHVpbnQ4ICAgICAgICAgICAgICAgICAgYmxvY2tfbGVuZ3RoOwogKiAgIHVpbnQ4ICAgICAgICAgICAgICAgICAgZml4ZWRfaXZfbGVuZ3RoOwogKiAgIHVpbnQ4ICAgICAgICAgICAgICAgICAgcmVjb3JkX2l2X2xlbmd0aDsKICogICBNQUNBbGdvcml0aG0gICAgICAgICAgIG1hY19hbGdvcml0aG07CiAqICAgdWludDggICAgICAgICAgICAgICAgICBtYWNfbGVuZ3RoOwogKiAgIHVpbnQ4ICAgICAgICAgICAgICAgICAgbWFjX2tleV9sZW5ndGg7CiAqICAgQ29tcHJlc3Npb25NZXRob2QgICAgICBjb21wcmVzc2lvbl9hbGdvcml0aG07CiAqICAgb3BhcXVlICAgICAgICAgICAgICAgICBtYXN0ZXJfc2VjcmV0WzQ4XTsKICogICBvcGFxdWUgICAgICAgICAgICAgICAgIGNsaWVudF9yYW5kb21bMzJdOwogKiAgIG9wYXF1ZSAgICAgICAgICAgICAgICAgc2VydmVyX3JhbmRvbVszMl07CiAqIH0gU2VjdXJpdHlQYXJhbWV0ZXJzOwogKgogKiBOb3RlIHRoYXQgdGhpcyBkZWZpbml0aW9uIGlzIGZyb20gVExTIDEuMi4gSW4gVExTIDEuMCBzb21lIG9mIHRoZXNlCiAqIHBhcmFtZXRlcnMgYXJlIGlnbm9yZWQgYmVjYXVzZSwgZm9yIGluc3RhbmNlLCB0aGUgUFJGQWxnb3JpdGhtIGlzIGEKICogYnVpbHRpbi1maXhlZCBhbGdvcml0aG0gY29tYmluaW5nIGl0ZXJhdGlvbnMgb2YgTUQ1IGFuZCBTSEEtMSBpbiBUTFMgMS4wLgogKgogKiBUaGUgUmVjb3JkIFByb3RvY29sIHJlcXVpcmVzIGFuIGFsZ29yaXRobSB0byBnZW5lcmF0ZSBrZXlzIHJlcXVpcmVkIGJ5IHRoZQogKiBjdXJyZW50IGNvbm5lY3Rpb24gc3RhdGUuCiAqCiAqIFRoZSBtYXN0ZXIgc2VjcmV0IGlzIGV4cGFuZGVkIGludG8gYSBzZXF1ZW5jZSBvZiBzZWN1cmUgYnl0ZXMsIHdoaWNoIGlzIHRoZW4KICogc3BsaXQgdG8gYSBjbGllbnQgd3JpdGUgTUFDIGtleSwgYSBzZXJ2ZXIgd3JpdGUgTUFDIGtleSwgYSBjbGllbnQgd3JpdGUKICogZW5jcnlwdGlvbiBrZXksIGFuZCBhIHNlcnZlciB3cml0ZSBlbmNyeXB0aW9uIGtleS4gSW4gVExTIDEuMCBhIGNsaWVudCB3cml0ZQogKiBJViBhbmQgc2VydmVyIHdyaXRlIElWIGFyZSBhbHNvIGdlbmVyYXRlZC4gRWFjaCBvZiB0aGVzZSBpcyBnZW5lcmF0ZWQgZnJvbQogKiB0aGUgYnl0ZSBzZXF1ZW5jZSBpbiB0aGF0IG9yZGVyLiBVbnVzZWQgdmFsdWVzIGFyZSBlbXB0eS4gSW4gVExTIDEuMiwgc29tZQogKiBBRUFEIGNpcGhlcnMgbWF5IGFkZGl0aW9uYWxseSByZXF1aXJlIGEgY2xpZW50IHdyaXRlIElWIGFuZCBhIHNlcnZlciB3cml0ZQogKiBJViAoc2VlIFNlY3Rpb24gNi4yLjMuMykuCiAqCiAqIFdoZW4ga2V5cywgTUFDIGtleXMsIGFuZCBJVnMgYXJlIGdlbmVyYXRlZCwgdGhlIG1hc3RlciBzZWNyZXQgaXMgdXNlZCBhcyBhbgogKiBlbnRyb3B5IHNvdXJjZS4KICoKICogVG8gZ2VuZXJhdGUgdGhlIGtleSBtYXRlcmlhbCwgY29tcHV0ZToKICoKICogbWFzdGVyX3NlY3JldCA9IFBSRihwcmVfbWFzdGVyX3NlY3JldCwgIm1hc3RlciBzZWNyZXQiLAogKiAgICAgICAgICAgICAgICAgICAgIENsaWVudEhlbGxvLnJhbmRvbSArIFNlcnZlckhlbGxvLnJhbmRvbSkKICoKICoga2V5X2Jsb2NrID0gUFJGKFNlY3VyaXR5UGFyYW1ldGVycy5tYXN0ZXJfc2VjcmV0LAogKiAgICAgICAgICAgICAgICAgImtleSBleHBhbnNpb24iLAogKiAgICAgICAgICAgICAgICAgU2VjdXJpdHlQYXJhbWV0ZXJzLnNlcnZlcl9yYW5kb20gKwogKiAgICAgICAgICAgICAgICAgU2VjdXJpdHlQYXJhbWV0ZXJzLmNsaWVudF9yYW5kb20pOwogKgogKiB1bnRpbCBlbm91Z2ggb3V0cHV0IGhhcyBiZWVuIGdlbmVyYXRlZC4gVGhlbiwgdGhlIGtleV9ibG9jayBpcwogKiBwYXJ0aXRpb25lZCBhcyBmb2xsb3dzOgogKgogKiBjbGllbnRfd3JpdGVfTUFDX2tleVtTZWN1cml0eVBhcmFtZXRlcnMubWFjX2tleV9sZW5ndGhdCiAqIHNlcnZlcl93cml0ZV9NQUNfa2V5W1NlY3VyaXR5UGFyYW1ldGVycy5tYWNfa2V5X2xlbmd0aF0KICogY2xpZW50X3dyaXRlX2tleVtTZWN1cml0eVBhcmFtZXRlcnMuZW5jX2tleV9sZW5ndGhdCiAqIHNlcnZlcl93cml0ZV9rZXlbU2VjdXJpdHlQYXJhbWV0ZXJzLmVuY19rZXlfbGVuZ3RoXQogKiBjbGllbnRfd3JpdGVfSVZbU2VjdXJpdHlQYXJhbWV0ZXJzLmZpeGVkX2l2X2xlbmd0aF0KICogc2VydmVyX3dyaXRlX0lWW1NlY3VyaXR5UGFyYW1ldGVycy5maXhlZF9pdl9sZW5ndGhdCiAqCiAqIEluIFRMUyAxLjIsIHRoZSBjbGllbnRfd3JpdGVfSVYgYW5kIHNlcnZlcl93cml0ZV9JViBhcmUgb25seSBnZW5lcmF0ZWQgZm9yCiAqIGltcGxpY2l0IG5vbmNlIHRlY2huaXF1ZXMgYXMgZGVzY3JpYmVkIGluIFNlY3Rpb24gMy4yLjEgb2YgW0FFQURdLiBUaGlzCiAqIGltcGxlbWVudGF0aW9uIHVzZXMgVExTIDEuMCBzbyBJVnMgYXJlIGdlbmVyYXRlZC4KICoKICogSW1wbGVtZW50YXRpb24gbm90ZTogVGhlIGN1cnJlbnRseSBkZWZpbmVkIGNpcGhlciBzdWl0ZSB3aGljaCByZXF1aXJlcyB0aGUKICogbW9zdCBtYXRlcmlhbCBpcyBBRVNfMjU2X0NCQ19TSEEyNTYuIEl0IHJlcXVpcmVzIDIgeCAzMiBieXRlIGtleXMgYW5kIDIgeCAzMgogKiBieXRlIE1BQyBrZXlzLCBmb3IgYSB0b3RhbCAxMjggYnl0ZXMgb2Yga2V5IG1hdGVyaWFsLiBJbiBUTFMgMS4wIGl0IGFsc28KICogcmVxdWlyZXMgMiB4IDE2IGJ5dGUgSVZzLCBzbyBpdCBhY3R1YWxseSB0YWtlcyAxNjAgYnl0ZXMgb2Yga2V5IG1hdGVyaWFsLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHNwIHRoZSBzZWN1cml0eSBwYXJhbWV0ZXJzIHRvIHVzZS4KICoKICogQHJldHVybiB0aGUgc2VjdXJpdHkga2V5cy4KICovCnRscy5nZW5lcmF0ZUtleXMgPSBmdW5jdGlvbihjLCBzcCkgewogIC8vIFRMU19SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEgKHJlcXVpcmVkIHRvIGJlIGNvbXBsaWFudCB3aXRoIFRMUyAxLjIpICYKICAvLyBUTFNfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBIGFyZSB0aGUgb25seSBjaXBoZXIgc3VpdGVzIGltcGxlbWVudGVkCiAgLy8gYXQgcHJlc2VudAoKICAvLyBUTFNfREhFX0RTU19XSVRIXzNERVNfRURFX0NCQ19TSEEgaXMgcmVxdWlyZWQgdG8gYmUgY29tcGxpYW50IHdpdGgKICAvLyBUTFMgMS4wIGJ1dCB3ZSBkb24ndCBjYXJlIHJpZ2h0IG5vdyBiZWNhdXNlIEFFUyBpcyBiZXR0ZXIgYW5kIHdlIGhhdmUKICAvLyBhbiBpbXBsZW1lbnRhdGlvbiBmb3IgaXQKCiAgLy8gVE9ETzogVExTIDEuMiBpbXBsZW1lbnRhdGlvbgogIC8qCiAgLy8gZGV0ZXJtaW5lIHRoZSBQUkYKICB2YXIgcHJmOwogIHN3aXRjaChzcC5wcmZfYWxnb3JpdGhtKSB7CiAgY2FzZSB0bHMuUFJGQWxnb3JpdGhtLnRsc19wcmZfc2hhMjU2OgogICAgcHJmID0gcHJmX3NoYTI1NjsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUFJGJyk7CiAgfQogICovCgogIC8vIFRMUyAxLjAvMS4xIGltcGxlbWVudGF0aW9uCiAgdmFyIHByZiA9IHByZl9UTFMxOwoKICAvLyBjb25jYXRlbmF0ZSBzZXJ2ZXIgYW5kIGNsaWVudCByYW5kb20KICB2YXIgcmFuZG9tID0gc3AuY2xpZW50X3JhbmRvbSArIHNwLnNlcnZlcl9yYW5kb207CgogIC8vIG9ubHkgY3JlYXRlIG1hc3RlciBzZWNyZXQgaWYgc2Vzc2lvbiBpcyBuZXcKICBpZighYy5zZXNzaW9uLnJlc3VtaW5nKSB7CiAgICAvLyBjcmVhdGUgbWFzdGVyIHNlY3JldCwgY2xlYW4gdXAgcHJlLW1hc3RlciBzZWNyZXQKICAgIHNwLm1hc3Rlcl9zZWNyZXQgPSBwcmYoCiAgICAgIHNwLnByZV9tYXN0ZXJfc2VjcmV0LCAnbWFzdGVyIHNlY3JldCcsIHJhbmRvbSwgNDgpLmJ5dGVzKCk7CiAgICBzcC5wcmVfbWFzdGVyX3NlY3JldCA9IG51bGw7CiAgfQoKICAvLyBnZW5lcmF0ZSB0aGUgYW1vdW50IG9mIGtleSBtYXRlcmlhbCBuZWVkZWQKICByYW5kb20gPSBzcC5zZXJ2ZXJfcmFuZG9tICsgc3AuY2xpZW50X3JhbmRvbTsKICB2YXIgbGVuZ3RoID0gMiAqIHNwLm1hY19rZXlfbGVuZ3RoICsgMiAqIHNwLmVuY19rZXlfbGVuZ3RoOwoKICAvLyBpbmNsdWRlIElWIGZvciBUTFMvMS4wCiAgdmFyIHRsczEwID0gKGMudmVyc2lvbi5tYWpvciA9PT0gdGxzLlZlcnNpb25zLlRMU18xXzAubWFqb3IgJiYKICAgIGMudmVyc2lvbi5taW5vciA9PT0gdGxzLlZlcnNpb25zLlRMU18xXzAubWlub3IpOwogIGlmKHRsczEwKSB7CiAgICBsZW5ndGggKz0gMiAqIHNwLmZpeGVkX2l2X2xlbmd0aDsKICB9CiAgdmFyIGttID0gcHJmKHNwLm1hc3Rlcl9zZWNyZXQsICdrZXkgZXhwYW5zaW9uJywgcmFuZG9tLCBsZW5ndGgpOwoKICAvLyBzcGxpdCB0aGUga2V5IG1hdGVyaWFsIGludG8gdGhlIE1BQyBhbmQgZW5jcnlwdGlvbiBrZXlzCiAgdmFyIHJ2YWwgPSB7CiAgICBjbGllbnRfd3JpdGVfTUFDX2tleToga20uZ2V0Qnl0ZXMoc3AubWFjX2tleV9sZW5ndGgpLAogICAgc2VydmVyX3dyaXRlX01BQ19rZXk6IGttLmdldEJ5dGVzKHNwLm1hY19rZXlfbGVuZ3RoKSwKICAgIGNsaWVudF93cml0ZV9rZXk6IGttLmdldEJ5dGVzKHNwLmVuY19rZXlfbGVuZ3RoKSwKICAgIHNlcnZlcl93cml0ZV9rZXk6IGttLmdldEJ5dGVzKHNwLmVuY19rZXlfbGVuZ3RoKQogIH07CgogIC8vIGluY2x1ZGUgVExTIDEuMCBJVnMKICBpZih0bHMxMCkgewogICAgcnZhbC5jbGllbnRfd3JpdGVfSVYgPSBrbS5nZXRCeXRlcyhzcC5maXhlZF9pdl9sZW5ndGgpOwogICAgcnZhbC5zZXJ2ZXJfd3JpdGVfSVYgPSBrbS5nZXRCeXRlcyhzcC5maXhlZF9pdl9sZW5ndGgpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ3JlYXRlcyBhIG5ldyBpbml0aWFsaXplZCBUTFMgY29ubmVjdGlvbiBzdGF0ZS4gQSBjb25uZWN0aW9uIHN0YXRlIGhhcwogKiBhIHJlYWQgbW9kZSBhbmQgYSB3cml0ZSBtb2RlLgogKgogKiBjb21wcmVzc2lvbiBzdGF0ZToKICogICBUaGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgY29tcHJlc3Npb24gYWxnb3JpdGhtLgogKgogKiBjaXBoZXIgc3RhdGU6CiAqICAgVGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGVuY3J5cHRpb24gYWxnb3JpdGhtLiBUaGlzIHdpbGwgY29uc2lzdCBvZiB0aGUKICogICBzY2hlZHVsZWQga2V5IGZvciB0aGF0IGNvbm5lY3Rpb24uIEZvciBzdHJlYW0gY2lwaGVycywgdGhpcyB3aWxsIGFsc28KICogICBjb250YWluIHdoYXRldmVyIHN0YXRlIGluZm9ybWF0aW9uIGlzIG5lY2Vzc2FyeSB0byBhbGxvdyB0aGUgc3RyZWFtIHRvCiAqICAgY29udGludWUgdG8gZW5jcnlwdCBvciBkZWNyeXB0IGRhdGEuCiAqCiAqIE1BQyBrZXk6CiAqICAgVGhlIE1BQyBrZXkgZm9yIHRoZSBjb25uZWN0aW9uLgogKgogKiBzZXF1ZW5jZSBudW1iZXI6CiAqICAgRWFjaCBjb25uZWN0aW9uIHN0YXRlIGNvbnRhaW5zIGEgc2VxdWVuY2UgbnVtYmVyLCB3aGljaCBpcyBtYWludGFpbmVkCiAqICAgc2VwYXJhdGVseSBmb3IgcmVhZCBhbmQgd3JpdGUgc3RhdGVzLiBUaGUgc2VxdWVuY2UgbnVtYmVyIE1VU1QgYmUgc2V0IHRvCiAqICAgemVybyB3aGVuZXZlciBhIGNvbm5lY3Rpb24gc3RhdGUgaXMgbWFkZSB0aGUgYWN0aXZlIHN0YXRlLiBTZXF1ZW5jZQogKiAgIG51bWJlcnMgYXJlIG9mIHR5cGUgdWludDY0IGFuZCBtYXkgbm90IGV4Y2VlZCAyXjY0LTEuIFNlcXVlbmNlIG51bWJlcnMgZG8KICogICBub3Qgd3JhcC4gSWYgYSBUTFMgaW1wbGVtZW50YXRpb24gd291bGQgbmVlZCB0byB3cmFwIGEgc2VxdWVuY2UgbnVtYmVyLAogKiAgIGl0IG11c3QgcmVuZWdvdGlhdGUgaW5zdGVhZC4gQSBzZXF1ZW5jZSBudW1iZXIgaXMgaW5jcmVtZW50ZWQgYWZ0ZXIgZWFjaAogKiAgIHJlY29yZDogc3BlY2lmaWNhbGx5LCB0aGUgZmlyc3QgcmVjb3JkIHRyYW5zbWl0dGVkIHVuZGVyIGEgcGFydGljdWxhcgogKiAgIGNvbm5lY3Rpb24gc3RhdGUgTVVTVCB1c2Ugc2VxdWVuY2UgbnVtYmVyIDAuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBuZXcgaW5pdGlhbGl6ZWQgVExTIGNvbm5lY3Rpb24gc3RhdGUuCiAqLwp0bHMuY3JlYXRlQ29ubmVjdGlvblN0YXRlID0gZnVuY3Rpb24oYykgewogIHZhciBjbGllbnQgPSAoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCk7CgogIHZhciBjcmVhdGVNb2RlID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgbW9kZSA9IHsKICAgICAgLy8gdHdvIDMyLWJpdCBudW1iZXJzLCBmaXJzdCBpcyBtb3N0IHNpZ25pZmljYW50CiAgICAgIHNlcXVlbmNlTnVtYmVyOiBbMCwgMF0sCiAgICAgIG1hY0tleTogbnVsbCwKICAgICAgbWFjTGVuZ3RoOiAwLAogICAgICBtYWNGdW5jdGlvbjogbnVsbCwKICAgICAgY2lwaGVyU3RhdGU6IG51bGwsCiAgICAgIGNpcGhlckZ1bmN0aW9uOiBmdW5jdGlvbihyZWNvcmQpIHtyZXR1cm4gdHJ1ZTt9LAogICAgICBjb21wcmVzc2lvblN0YXRlOiBudWxsLAogICAgICBjb21wcmVzc0Z1bmN0aW9uOiBmdW5jdGlvbihyZWNvcmQpIHtyZXR1cm4gdHJ1ZTt9LAogICAgICB1cGRhdGVTZXF1ZW5jZU51bWJlcjogZnVuY3Rpb24oKSB7CiAgICAgICAgaWYobW9kZS5zZXF1ZW5jZU51bWJlclsxXSA9PT0gMHhGRkZGRkZGRikgewogICAgICAgICAgbW9kZS5zZXF1ZW5jZU51bWJlclsxXSA9IDA7CiAgICAgICAgICArK21vZGUuc2VxdWVuY2VOdW1iZXJbMF07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICsrbW9kZS5zZXF1ZW5jZU51bWJlclsxXTsKICAgICAgICB9CiAgICAgIH0KICAgIH07CiAgICByZXR1cm4gbW9kZTsKICB9OwogIHZhciBzdGF0ZSA9IHsKICAgIHJlYWQ6IGNyZWF0ZU1vZGUoKSwKICAgIHdyaXRlOiBjcmVhdGVNb2RlKCkKICB9OwoKICAvLyB1cGRhdGUgZnVuY3Rpb24gaW4gcmVhZCBtb2RlIHdpbGwgZGVjcnlwdCB0aGVuIGRlY29tcHJlc3MgYSByZWNvcmQKICBzdGF0ZS5yZWFkLnVwZGF0ZSA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogICAgaWYoIXN0YXRlLnJlYWQuY2lwaGVyRnVuY3Rpb24ocmVjb3JkLCBzdGF0ZS5yZWFkKSkgewogICAgICBjLmVycm9yKGMsIHsKICAgICAgICBtZXNzYWdlOiAnQ291bGQgbm90IGRlY3J5cHQgcmVjb3JkIG9yIGJhZCBNQUMuJywKICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgLy8gZG9lc24ndCBtYXR0ZXIgaWYgZGVjcnlwdGlvbiBmYWlsZWQgb3IgTUFDIHdhcwogICAgICAgICAgLy8gaW52YWxpZCwgcmV0dXJuIHRoZSBzYW1lIGVycm9yIHNvIGFzIG5vdCB0byByZXZlYWwKICAgICAgICAgIC8vIHdoaWNoIG9uZSBvY2N1cnJlZAogICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5iYWRfcmVjb3JkX21hYwogICAgICAgIH0KICAgICAgfSk7CiAgICB9IGVsc2UgaWYoIXN0YXRlLnJlYWQuY29tcHJlc3NGdW5jdGlvbihjLCByZWNvcmQsIHN0YXRlLnJlYWQpKSB7CiAgICAgIGMuZXJyb3IoYywgewogICAgICAgIG1lc3NhZ2U6ICdDb3VsZCBub3QgZGVjb21wcmVzcyByZWNvcmQuJywKICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5kZWNvbXByZXNzaW9uX2ZhaWx1cmUKICAgICAgICB9CiAgICAgIH0pOwogICAgfQogICAgcmV0dXJuICFjLmZhaWw7CiAgfTsKCiAgLy8gdXBkYXRlIGZ1bmN0aW9uIGluIHdyaXRlIG1vZGUgd2lsbCBjb21wcmVzcyB0aGVuIGVuY3J5cHQgYSByZWNvcmQKICBzdGF0ZS53cml0ZS51cGRhdGUgPSBmdW5jdGlvbihjLCByZWNvcmQpIHsKICAgIGlmKCFzdGF0ZS53cml0ZS5jb21wcmVzc0Z1bmN0aW9uKGMsIHJlY29yZCwgc3RhdGUud3JpdGUpKSB7CiAgICAgIC8vIGVycm9yLCBidXQgZG8gbm90IHNlbmQgYWxlcnQgc2luY2UgaXQgd291bGQgcmVxdWlyZQogICAgICAvLyBjb21wcmVzc2lvbiBhcyB3ZWxsCiAgICAgIGMuZXJyb3IoYywgewogICAgICAgIG1lc3NhZ2U6ICdDb3VsZCBub3QgY29tcHJlc3MgcmVjb3JkLicsCiAgICAgICAgc2VuZDogZmFsc2UsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgfQogICAgICB9KTsKICAgIH0gZWxzZSBpZighc3RhdGUud3JpdGUuY2lwaGVyRnVuY3Rpb24ocmVjb3JkLCBzdGF0ZS53cml0ZSkpIHsKICAgICAgLy8gZXJyb3IsIGJ1dCBkbyBub3Qgc2VuZCBhbGVydCBzaW5jZSBpdCB3b3VsZCByZXF1aXJlCiAgICAgIC8vIGVuY3J5cHRpb24gYXMgd2VsbAogICAgICBjLmVycm9yKGMsIHsKICAgICAgICBtZXNzYWdlOiAnQ291bGQgbm90IGVuY3J5cHQgcmVjb3JkLicsCiAgICAgICAgc2VuZDogZmFsc2UsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgfQogICAgICB9KTsKICAgIH0KICAgIHJldHVybiAhYy5mYWlsOwogIH07CgogIC8vIGhhbmRsZSBzZWN1cml0eSBwYXJhbWV0ZXJzCiAgaWYoYy5zZXNzaW9uKSB7CiAgICB2YXIgc3AgPSBjLnNlc3Npb24uc3A7CiAgICBjLnNlc3Npb24uY2lwaGVyU3VpdGUuaW5pdFNlY3VyaXR5UGFyYW1ldGVycyhzcCk7CgogICAgLy8gZ2VuZXJhdGUga2V5cwogICAgc3Aua2V5cyA9IHRscy5nZW5lcmF0ZUtleXMoYywgc3ApOwogICAgc3RhdGUucmVhZC5tYWNLZXkgPSBjbGllbnQgPwogICAgICBzcC5rZXlzLnNlcnZlcl93cml0ZV9NQUNfa2V5IDogc3Aua2V5cy5jbGllbnRfd3JpdGVfTUFDX2tleTsKICAgIHN0YXRlLndyaXRlLm1hY0tleSA9IGNsaWVudCA/CiAgICAgIHNwLmtleXMuY2xpZW50X3dyaXRlX01BQ19rZXkgOiBzcC5rZXlzLnNlcnZlcl93cml0ZV9NQUNfa2V5OwoKICAgIC8vIGNpcGhlciBzdWl0ZSBzZXR1cAogICAgYy5zZXNzaW9uLmNpcGhlclN1aXRlLmluaXRDb25uZWN0aW9uU3RhdGUoc3RhdGUsIGMsIHNwKTsKCiAgICAvLyBjb21wcmVzc2lvbiBzZXR1cAogICAgc3dpdGNoKHNwLmNvbXByZXNzaW9uX2FsZ29yaXRobSkgewogICAgY2FzZSB0bHMuQ29tcHJlc3Npb25NZXRob2Qubm9uZToKICAgICAgYnJlYWs7CiAgICBjYXNlIHRscy5Db21wcmVzc2lvbk1ldGhvZC5kZWZsYXRlOgogICAgICBzdGF0ZS5yZWFkLmNvbXByZXNzRnVuY3Rpb24gPSBpbmZsYXRlOwogICAgICBzdGF0ZS53cml0ZS5jb21wcmVzc0Z1bmN0aW9uID0gZGVmbGF0ZTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGNvbXByZXNzaW9uIGFsZ29yaXRobS4nKTsKICAgIH0KICB9CgogIHJldHVybiBzdGF0ZTsKfTsKCi8qKgogKiBDcmVhdGVzIGEgUmFuZG9tIHN0cnVjdHVyZS4KICoKICogc3RydWN0IHsKICogICB1aW50MzIgZ210X3VuaXhfdGltZTsKICogICBvcGFxdWUgcmFuZG9tX2J5dGVzWzI4XTsKICogfSBSYW5kb207CiAqCiAqIGdtdF91bml4X3RpbWU6CiAqICAgVGhlIGN1cnJlbnQgdGltZSBhbmQgZGF0ZSBpbiBzdGFuZGFyZCBVTklYIDMyLWJpdCBmb3JtYXQgKHNlY29uZHMgc2luY2UKICogICB0aGUgbWlkbmlnaHQgc3RhcnRpbmcgSmFuIDEsIDE5NzAsIFVUQywgaWdub3JpbmcgbGVhcCBzZWNvbmRzKSBhY2NvcmRpbmcKICogICB0byB0aGUgc2VuZGVyJ3MgaW50ZXJuYWwgY2xvY2suIENsb2NrcyBhcmUgbm90IHJlcXVpcmVkIHRvIGJlIHNldAogKiAgIGNvcnJlY3RseSBieSB0aGUgYmFzaWMgVExTIHByb3RvY29sOyBoaWdoZXItbGV2ZWwgb3IgYXBwbGljYXRpb24KICogICBwcm90b2NvbHMgbWF5IGRlZmluZSBhZGRpdGlvbmFsIHJlcXVpcmVtZW50cy4gTm90ZSB0aGF0LCBmb3IgaGlzdG9yaWNhbAogKiAgIHJlYXNvbnMsIHRoZSBkYXRhIGVsZW1lbnQgaXMgbmFtZWQgdXNpbmcgR01ULCB0aGUgcHJlZGVjZXNzb3Igb2YgdGhlCiAqICAgY3VycmVudCB3b3JsZHdpZGUgdGltZSBiYXNlLCBVVEMuCiAqIHJhbmRvbV9ieXRlczoKICogICAyOCBieXRlcyBnZW5lcmF0ZWQgYnkgYSBzZWN1cmUgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IuCiAqCiAqIEByZXR1cm4gdGhlIFJhbmRvbSBzdHJ1Y3R1cmUgYXMgYSBieXRlIGFycmF5LgogKi8KdGxzLmNyZWF0ZVJhbmRvbSA9IGZ1bmN0aW9uKCkgewogIC8vIGdldCBVVEMgbWlsbGlzZWNvbmRzCiAgdmFyIGQgPSBuZXcgRGF0ZSgpOwogIHZhciB1dGMgPSArZCArIGQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwMDAwOwogIHZhciBydmFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBydmFsLnB1dEludDMyKHV0Yyk7CiAgcnZhbC5wdXRCeXRlcyhmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMoMjgpKTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDcmVhdGVzIGEgVExTIHJlY29yZCB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZCBkYXRhLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIG9wdGlvbnM6CiAqICAgdHlwZTogdGhlIHJlY29yZCB0eXBlLgogKiAgIGRhdGE6IHRoZSBwbGFpbiB0ZXh0IGRhdGEgaW4gYSBieXRlIGJ1ZmZlci4KICoKICogQHJldHVybiB0aGUgY3JlYXRlZCByZWNvcmQuCiAqLwp0bHMuY3JlYXRlUmVjb3JkID0gZnVuY3Rpb24oYywgb3B0aW9ucykgewogIGlmKCFvcHRpb25zLmRhdGEpIHsKICAgIHJldHVybiBudWxsOwogIH0KICB2YXIgcmVjb3JkID0gewogICAgdHlwZTogb3B0aW9ucy50eXBlLAogICAgdmVyc2lvbjogewogICAgICBtYWpvcjogYy52ZXJzaW9uLm1ham9yLAogICAgICBtaW5vcjogYy52ZXJzaW9uLm1pbm9yCiAgICB9LAogICAgbGVuZ3RoOiBvcHRpb25zLmRhdGEubGVuZ3RoKCksCiAgICBmcmFnbWVudDogb3B0aW9ucy5kYXRhCiAgfTsKICByZXR1cm4gcmVjb3JkOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBUTFMgYWxlcnQgcmVjb3JkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIGFsZXJ0OgogKiAgIGxldmVsOiB0aGUgVExTIGFsZXJ0IGxldmVsLgogKiAgIGRlc2NyaXB0aW9uOiB0aGUgVExTIGFsZXJ0IGRlc2NyaXB0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBjcmVhdGVkIGFsZXJ0IHJlY29yZC4KICovCnRscy5jcmVhdGVBbGVydCA9IGZ1bmN0aW9uKGMsIGFsZXJ0KSB7CiAgdmFyIGIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIGIucHV0Qnl0ZShhbGVydC5sZXZlbCk7CiAgYi5wdXRCeXRlKGFsZXJ0LmRlc2NyaXB0aW9uKTsKICByZXR1cm4gdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuYWxlcnQsCiAgICBkYXRhOiBiCiAgfSk7Cn07CgovKiBUaGUgc3RydWN0dXJlIG9mIGEgVExTIGhhbmRzaGFrZSBtZXNzYWdlLgogKgogKiBzdHJ1Y3QgewogKiAgICBIYW5kc2hha2VUeXBlIG1zZ190eXBlOyAgICAvLyBoYW5kc2hha2UgdHlwZQogKiAgICB1aW50MjQgbGVuZ3RoOyAgICAgICAgICAgICAvLyBieXRlcyBpbiBtZXNzYWdlCiAqICAgIHNlbGVjdChIYW5kc2hha2VUeXBlKSB7CiAqICAgICAgIGNhc2UgaGVsbG9fcmVxdWVzdDogICAgICAgSGVsbG9SZXF1ZXN0OwogKiAgICAgICBjYXNlIGNsaWVudF9oZWxsbzogICAgICAgIENsaWVudEhlbGxvOwogKiAgICAgICBjYXNlIHNlcnZlcl9oZWxsbzogICAgICAgIFNlcnZlckhlbGxvOwogKiAgICAgICBjYXNlIGNlcnRpZmljYXRlOiAgICAgICAgIENlcnRpZmljYXRlOwogKiAgICAgICBjYXNlIHNlcnZlcl9rZXlfZXhjaGFuZ2U6IFNlcnZlcktleUV4Y2hhbmdlOwogKiAgICAgICBjYXNlIGNlcnRpZmljYXRlX3JlcXVlc3Q6IENlcnRpZmljYXRlUmVxdWVzdDsKICogICAgICAgY2FzZSBzZXJ2ZXJfaGVsbG9fZG9uZTogICBTZXJ2ZXJIZWxsb0RvbmU7CiAqICAgICAgIGNhc2UgY2VydGlmaWNhdGVfdmVyaWZ5OiAgQ2VydGlmaWNhdGVWZXJpZnk7CiAqICAgICAgIGNhc2UgY2xpZW50X2tleV9leGNoYW5nZTogQ2xpZW50S2V5RXhjaGFuZ2U7CiAqICAgICAgIGNhc2UgZmluaXNoZWQ6ICAgICAgICAgICAgRmluaXNoZWQ7CiAqICAgIH0gYm9keTsKICogfSBIYW5kc2hha2U7CiAqLwoKLyoqCiAqIENyZWF0ZXMgYSBDbGllbnRIZWxsbyBtZXNzYWdlLgogKgogKiBvcGFxdWUgU2Vzc2lvbklEPDAuLjMyPjsKICogZW51bSB7IG51bGwoMCksIGRlZmxhdGUoMSksICgyNTUpIH0gQ29tcHJlc3Npb25NZXRob2Q7CiAqIHVpbnQ4IENpcGhlclN1aXRlWzJdOwogKgogKiBzdHJ1Y3QgewogKiAgIFByb3RvY29sVmVyc2lvbiBjbGllbnRfdmVyc2lvbjsKICogICBSYW5kb20gcmFuZG9tOwogKiAgIFNlc3Npb25JRCBzZXNzaW9uX2lkOwogKiAgIENpcGhlclN1aXRlIGNpcGhlcl9zdWl0ZXM8Mi4uMl4xNi0yPjsKICogICBDb21wcmVzc2lvbk1ldGhvZCBjb21wcmVzc2lvbl9tZXRob2RzPDEuLjJeOC0xPjsKICogICBzZWxlY3QoZXh0ZW5zaW9uc19wcmVzZW50KSB7CiAqICAgICBjYXNlIGZhbHNlOgogKiAgICAgICBzdHJ1Y3Qge307CiAqICAgICBjYXNlIHRydWU6CiAqICAgICAgIEV4dGVuc2lvbiBleHRlbnNpb25zPDAuLjJeMTYtMT47CiAqICAgfTsKICogfSBDbGllbnRIZWxsbzsKICoKICogVGhlIGV4dGVuc2lvbiBmb3JtYXQgZm9yIGV4dGVuZGVkIGNsaWVudCBoZWxsb3MgYW5kIHNlcnZlciBoZWxsb3MgaXM6CiAqCiAqIHN0cnVjdCB7CiAqICAgRXh0ZW5zaW9uVHlwZSBleHRlbnNpb25fdHlwZTsKICogICBvcGFxdWUgZXh0ZW5zaW9uX2RhdGE8MC4uMl4xNi0xPjsKICogfSBFeHRlbnNpb247CiAqCiAqIEhlcmU6CiAqCiAqIC0gImV4dGVuc2lvbl90eXBlIiBpZGVudGlmaWVzIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiB0eXBlLgogKiAtICJleHRlbnNpb25fZGF0YSIgY29udGFpbnMgaW5mb3JtYXRpb24gc3BlY2lmaWMgdG8gdGhlIHBhcnRpY3VsYXIKICogZXh0ZW5zaW9uIHR5cGUuCiAqCiAqIFRoZSBleHRlbnNpb24gdHlwZXMgZGVmaW5lZCBpbiB0aGlzIGRvY3VtZW50IGFyZToKICoKICogZW51bSB7CiAqICAgc2VydmVyX25hbWUoMCksIG1heF9mcmFnbWVudF9sZW5ndGgoMSksCiAqICAgY2xpZW50X2NlcnRpZmljYXRlX3VybCgyKSwgdHJ1c3RlZF9jYV9rZXlzKDMpLAogKiAgIHRydW5jYXRlZF9obWFjKDQpLCBzdGF0dXNfcmVxdWVzdCg1KSwgKDY1NTM1KQogKiB9IEV4dGVuc2lvblR5cGU7CiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBDbGllbnRIZWxsbyBieXRlIGJ1ZmZlci4KICovCnRscy5jcmVhdGVDbGllbnRIZWxsbyA9IGZ1bmN0aW9uKGMpIHsKICAvLyBzYXZlIGhlbGxvIHZlcnNpb24KICBjLnNlc3Npb24uY2xpZW50SGVsbG9WZXJzaW9uID0gewogICAgbWFqb3I6IGMudmVyc2lvbi5tYWpvciwKICAgIG1pbm9yOiBjLnZlcnNpb24ubWlub3IKICB9OwoKICAvLyBjcmVhdGUgc3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMKICB2YXIgY2lwaGVyU3VpdGVzID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBmb3IodmFyIGkgPSAwOyBpIDwgYy5jaXBoZXJTdWl0ZXMubGVuZ3RoOyArK2kpIHsKICAgIHZhciBjcyA9IGMuY2lwaGVyU3VpdGVzW2ldOwogICAgY2lwaGVyU3VpdGVzLnB1dEJ5dGUoY3MuaWRbMF0pOwogICAgY2lwaGVyU3VpdGVzLnB1dEJ5dGUoY3MuaWRbMV0pOwogIH0KICB2YXIgY1N1aXRlcyA9IGNpcGhlclN1aXRlcy5sZW5ndGgoKTsKCiAgLy8gY3JlYXRlIHN1cHBvcnRlZCBjb21wcmVzc2lvbiBtZXRob2RzLCBudWxsIGFsd2F5cyBzdXBwb3J0ZWQsIGJ1dAogIC8vIGFsc28gc3VwcG9ydCBkZWZsYXRlIGlmIGNvbm5lY3Rpb24gaGFzIGluZmxhdGUgYW5kIGRlZmxhdGUgbWV0aG9kcwogIHZhciBjb21wcmVzc2lvbk1ldGhvZHMgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIGNvbXByZXNzaW9uTWV0aG9kcy5wdXRCeXRlKHRscy5Db21wcmVzc2lvbk1ldGhvZC5ub25lKTsKICAvLyBGSVhNRTogZGVmbGF0ZSBzdXBwb3J0IGRpc2FibGVkIHVudGlsIGlzc3VlcyB3aXRoIHJhdyBkZWZsYXRlIGRhdGEKICAvLyB3aXRob3V0IHpsaWIgaGVhZGVycyBhcmUgcmVzb2x2ZWQKICAvKgogIGlmKGMuaW5mbGF0ZSAhPT0gbnVsbCAmJiBjLmRlZmxhdGUgIT09IG51bGwpIHsKICAgIGNvbXByZXNzaW9uTWV0aG9kcy5wdXRCeXRlKHRscy5Db21wcmVzc2lvbk1ldGhvZC5kZWZsYXRlKTsKICB9CiAgKi8KICB2YXIgY01ldGhvZHMgPSBjb21wcmVzc2lvbk1ldGhvZHMubGVuZ3RoKCk7CgogIC8vIGNyZWF0ZSBUTFMgU05JIChzZXJ2ZXIgbmFtZSBpbmRpY2F0aW9uKSBleHRlbnNpb24gaWYgdmlydHVhbCBob3N0CiAgLy8gaGFzIGJlZW4gc3BlY2lmaWVkLCBzZWUgUkZDIDM1NDYKICB2YXIgZXh0ZW5zaW9ucyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgaWYoYy52aXJ0dWFsSG9zdCkgewogICAgLy8gY3JlYXRlIGV4dGVuc2lvbiBzdHJ1Y3QKICAgIHZhciBleHQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgZXh0LnB1dEJ5dGUoMHgwMCk7IC8vIHR5cGUgc2VydmVyX25hbWUgKEV4dGVuc2lvblR5cGUgaXMgMiBieXRlcykKICAgIGV4dC5wdXRCeXRlKDB4MDApOwoKICAgIC8qIEluIG9yZGVyIHRvIHByb3ZpZGUgdGhlIHNlcnZlciBuYW1lLCBjbGllbnRzIE1BWSBpbmNsdWRlIGFuCiAgICAgKiBleHRlbnNpb24gb2YgdHlwZSAic2VydmVyX25hbWUiIGluIHRoZSAoZXh0ZW5kZWQpIGNsaWVudCBoZWxsby4KICAgICAqIFRoZSAiZXh0ZW5zaW9uX2RhdGEiIGZpZWxkIG9mIHRoaXMgZXh0ZW5zaW9uIFNIQUxMIGNvbnRhaW4KICAgICAqICJTZXJ2ZXJOYW1lTGlzdCIgd2hlcmU6CiAgICAgKgogICAgICogc3RydWN0IHsKICAgICAqICAgTmFtZVR5cGUgbmFtZV90eXBlOwogICAgICogICBzZWxlY3QobmFtZV90eXBlKSB7CiAgICAgKiAgICAgY2FzZSBob3N0X25hbWU6IEhvc3ROYW1lOwogICAgICogICB9IG5hbWU7CiAgICAgKiB9IFNlcnZlck5hbWU7CiAgICAgKgogICAgICogZW51bSB7CiAgICAgKiAgIGhvc3RfbmFtZSgwKSwgKDI1NSkKICAgICAqIH0gTmFtZVR5cGU7CiAgICAgKgogICAgICogb3BhcXVlIEhvc3ROYW1lPDEuLjJeMTYtMT47CiAgICAgKgogICAgICogc3RydWN0IHsKICAgICAqICAgU2VydmVyTmFtZSBzZXJ2ZXJfbmFtZV9saXN0PDEuLjJeMTYtMT4KICAgICAqIH0gU2VydmVyTmFtZUxpc3Q7CiAgICAgKi8KICAgIHZhciBzZXJ2ZXJOYW1lID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIHNlcnZlck5hbWUucHV0Qnl0ZSgweDAwKTsgLy8gdHlwZSBob3N0X25hbWUKICAgIHdyaXRlVmVjdG9yKHNlcnZlck5hbWUsIDIsIGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGMudmlydHVhbEhvc3QpKTsKCiAgICAvLyBTZXJ2ZXJOYW1lTGlzdCBpcyBpbiBleHRlbnNpb25fZGF0YQogICAgdmFyIHNuTGlzdCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICB3cml0ZVZlY3Rvcihzbkxpc3QsIDIsIHNlcnZlck5hbWUpOwogICAgd3JpdGVWZWN0b3IoZXh0LCAyLCBzbkxpc3QpOwogICAgZXh0ZW5zaW9ucy5wdXRCdWZmZXIoZXh0KTsKICB9CiAgdmFyIGV4dExlbmd0aCA9IGV4dGVuc2lvbnMubGVuZ3RoKCk7CiAgaWYoZXh0TGVuZ3RoID4gMCkgewogICAgLy8gYWRkIGV4dGVuc2lvbiB2ZWN0b3IgbGVuZ3RoCiAgICBleHRMZW5ndGggKz0gMjsKICB9CgogIC8vIGRldGVybWluZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlCiAgLy8gY2lwaGVyIHN1aXRlcyBhbmQgY29tcHJlc3Npb24gbWV0aG9kcyBzaXplIHdpbGwgbmVlZCB0byBiZQogIC8vIHVwZGF0ZWQgaWYgbW9yZSBnZXQgYWRkZWQgdG8gdGhlIGxpc3QKICB2YXIgc2Vzc2lvbklkID0gYy5zZXNzaW9uLmlkOwogIHZhciBsZW5ndGggPQogICAgc2Vzc2lvbklkLmxlbmd0aCArIDEgKyAvLyBzZXNzaW9uIElEIHZlY3RvcgogICAgMiArICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIChtYWpvciArIG1pbm9yKQogICAgNCArIDI4ICsgICAgICAgICAgICAgICAvLyByYW5kb20gdGltZSBhbmQgcmFuZG9tIGJ5dGVzCiAgICAyICsgY1N1aXRlcyArICAgICAgICAgIC8vIGNpcGhlciBzdWl0ZXMgdmVjdG9yCiAgICAxICsgY01ldGhvZHMgKyAgICAgICAgIC8vIGNvbXByZXNzaW9uIG1ldGhvZHMgdmVjdG9yCiAgICBleHRMZW5ndGg7ICAgICAgICAgICAgIC8vIGV4dGVuc2lvbnMgdmVjdG9yCgogIC8vIGJ1aWxkIHJlY29yZCBmcmFnbWVudAogIHZhciBydmFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBydmFsLnB1dEJ5dGUodGxzLkhhbmRzaGFrZVR5cGUuY2xpZW50X2hlbGxvKTsKICBydmFsLnB1dEludDI0KGxlbmd0aCk7ICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZHNoYWtlIGxlbmd0aAogIHJ2YWwucHV0Qnl0ZShjLnZlcnNpb24ubWFqb3IpOyAgICAgICAgICAgICAvLyBtYWpvciB2ZXJzaW9uCiAgcnZhbC5wdXRCeXRlKGMudmVyc2lvbi5taW5vcik7ICAgICAgICAgICAgIC8vIG1pbm9yIHZlcnNpb24KICBydmFsLnB1dEJ5dGVzKGMuc2Vzc2lvbi5zcC5jbGllbnRfcmFuZG9tKTsgLy8gcmFuZG9tIHRpbWUgKyBieXRlcwogIHdyaXRlVmVjdG9yKHJ2YWwsIDEsIGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKHNlc3Npb25JZCkpOwogIHdyaXRlVmVjdG9yKHJ2YWwsIDIsIGNpcGhlclN1aXRlcyk7CiAgd3JpdGVWZWN0b3IocnZhbCwgMSwgY29tcHJlc3Npb25NZXRob2RzKTsKICBpZihleHRMZW5ndGggPiAwKSB7CiAgICB3cml0ZVZlY3RvcihydmFsLCAyLCBleHRlbnNpb25zKTsKICB9CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ3JlYXRlcyBhIFNlcnZlckhlbGxvIG1lc3NhZ2UuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBTZXJ2ZXJIZWxsbyBieXRlIGJ1ZmZlci4KICovCnRscy5jcmVhdGVTZXJ2ZXJIZWxsbyA9IGZ1bmN0aW9uKGMpIHsKICAvLyBkZXRlcm1pbmUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZQogIHZhciBzZXNzaW9uSWQgPSBjLnNlc3Npb24uaWQ7CiAgdmFyIGxlbmd0aCA9CiAgICBzZXNzaW9uSWQubGVuZ3RoICsgMSArIC8vIHNlc3Npb24gSUQgdmVjdG9yCiAgICAyICsgICAgICAgICAgICAgICAgICAgIC8vIHZlcnNpb24gKG1ham9yICsgbWlub3IpCiAgICA0ICsgMjggKyAgICAgICAgICAgICAgIC8vIHJhbmRvbSB0aW1lIGFuZCByYW5kb20gYnl0ZXMKICAgIDIgKyAgICAgICAgICAgICAgICAgICAgLy8gY2hvc2VuIGNpcGhlciBzdWl0ZQogICAgMTsgICAgICAgICAgICAgICAgICAgICAvLyBjaG9zZW4gY29tcHJlc3Npb24gbWV0aG9kCgogIC8vIGJ1aWxkIHJlY29yZCBmcmFnbWVudAogIHZhciBydmFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBydmFsLnB1dEJ5dGUodGxzLkhhbmRzaGFrZVR5cGUuc2VydmVyX2hlbGxvKTsKICBydmFsLnB1dEludDI0KGxlbmd0aCk7ICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZHNoYWtlIGxlbmd0aAogIHJ2YWwucHV0Qnl0ZShjLnZlcnNpb24ubWFqb3IpOyAgICAgICAgICAgICAvLyBtYWpvciB2ZXJzaW9uCiAgcnZhbC5wdXRCeXRlKGMudmVyc2lvbi5taW5vcik7ICAgICAgICAgICAgIC8vIG1pbm9yIHZlcnNpb24KICBydmFsLnB1dEJ5dGVzKGMuc2Vzc2lvbi5zcC5zZXJ2ZXJfcmFuZG9tKTsgLy8gcmFuZG9tIHRpbWUgKyBieXRlcwogIHdyaXRlVmVjdG9yKHJ2YWwsIDEsIGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKHNlc3Npb25JZCkpOwogIHJ2YWwucHV0Qnl0ZShjLnNlc3Npb24uY2lwaGVyU3VpdGUuaWRbMF0pOwogIHJ2YWwucHV0Qnl0ZShjLnNlc3Npb24uY2lwaGVyU3VpdGUuaWRbMV0pOwogIHJ2YWwucHV0Qnl0ZShjLnNlc3Npb24uY29tcHJlc3Npb25NZXRob2QpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBDZXJ0aWZpY2F0ZSBtZXNzYWdlLgogKgogKiBXaGVuIHRoaXMgbWVzc2FnZSB3aWxsIGJlIHNlbnQ6CiAqICAgVGhpcyBpcyB0aGUgZmlyc3QgbWVzc2FnZSB0aGUgY2xpZW50IGNhbiBzZW5kIGFmdGVyIHJlY2VpdmluZyBhIHNlcnZlcgogKiAgIGhlbGxvIGRvbmUgbWVzc2FnZSBhbmQgdGhlIGZpcnN0IG1lc3NhZ2UgdGhlIHNlcnZlciBjYW4gc2VuZCBhZnRlcgogKiAgIHNlbmRpbmcgYSBTZXJ2ZXJIZWxsby4gVGhpcyBjbGllbnQgbWVzc2FnZSBpcyBvbmx5IHNlbnQgaWYgdGhlIHNlcnZlcgogKiAgIHJlcXVlc3RzIGEgY2VydGlmaWNhdGUuIElmIG5vIHN1aXRhYmxlIGNlcnRpZmljYXRlIGlzIGF2YWlsYWJsZSwgdGhlCiAqICAgY2xpZW50IHNob3VsZCBzZW5kIGEgY2VydGlmaWNhdGUgbWVzc2FnZSBjb250YWluaW5nIG5vIGNlcnRpZmljYXRlcy4gSWYKICogICBjbGllbnQgYXV0aGVudGljYXRpb24gaXMgcmVxdWlyZWQgYnkgdGhlIHNlcnZlciBmb3IgdGhlIGhhbmRzaGFrZSB0bwogKiAgIGNvbnRpbnVlLCBpdCBtYXkgcmVzcG9uZCB3aXRoIGEgZmF0YWwgaGFuZHNoYWtlIGZhaWx1cmUgYWxlcnQuCiAqCiAqIG9wYXF1ZSBBU04uMUNlcnQ8MS4uMl4yNC0xPjsKICoKICogc3RydWN0IHsKICogICBBU04uMUNlcnQgY2VydGlmaWNhdGVfbGlzdDwwLi4yXjI0LTE+OwogKiB9IENlcnRpZmljYXRlOwogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgQ2VydGlmaWNhdGUgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlQ2VydGlmaWNhdGUgPSBmdW5jdGlvbihjKSB7CiAgLy8gVE9ETzogY2hlY2sgY2VydGlmaWNhdGUgcmVxdWVzdCB0byBlbnN1cmUgdHlwZXMgYXJlIHN1cHBvcnRlZAoKICAvLyBnZXQgYSBjZXJ0aWZpY2F0ZSAoYSBjZXJ0aWZpY2F0ZSBhcyBhIFBFTSBzdHJpbmcpCiAgdmFyIGNsaWVudCA9IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KTsKICB2YXIgY2VydCA9IG51bGw7CiAgaWYoYy5nZXRDZXJ0aWZpY2F0ZSkgewogICAgdmFyIGhpbnQ7CiAgICBpZihjbGllbnQpIHsKICAgICAgaGludCA9IGMuc2Vzc2lvbi5jZXJ0aWZpY2F0ZVJlcXVlc3Q7CiAgICB9IGVsc2UgewogICAgICBoaW50ID0gYy5zZXNzaW9uLmV4dGVuc2lvbnMuc2VydmVyX25hbWUuc2VydmVyTmFtZUxpc3Q7CiAgICB9CiAgICBjZXJ0ID0gYy5nZXRDZXJ0aWZpY2F0ZShjLCBoaW50KTsKICB9CgogIC8vIGJ1ZmZlciB0byBob2xkIGNlcnRpZmljYXRlIGxpc3QKICB2YXIgY2VydExpc3QgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIGlmKGNlcnQgIT09IG51bGwpIHsKICAgIHRyeSB7CiAgICAgIC8vIG5vcm1hbGl6ZSBjZXJ0IHRvIGEgY2hhaW4gb2YgY2VydGlmaWNhdGVzCiAgICAgIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkoY2VydCkpIHsKICAgICAgICBjZXJ0ID0gW2NlcnRdOwogICAgICB9CiAgICAgIHZhciBhc24xID0gbnVsbDsKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGNlcnQubGVuZ3RoOyArK2kpIHsKICAgICAgICB2YXIgbXNnID0gZm9yZ2UucGVtLmRlY29kZShjZXJ0W2ldKVswXTsKICAgICAgICBpZihtc2cudHlwZSAhPT0gJ0NFUlRJRklDQVRFJyAmJgogICAgICAgICAgbXNnLnR5cGUgIT09ICdYNTA5IENFUlRJRklDQVRFJyAmJgogICAgICAgICAgbXNnLnR5cGUgIT09ICdUUlVTVEVEIENFUlRJRklDQVRFJykgewogICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDb3VsZCBub3QgY29udmVydCBjZXJ0aWZpY2F0ZSBmcm9tIFBFTTsgUEVNICcgKwogICAgICAgICAgICAnaGVhZGVyIHR5cGUgaXMgbm90ICJDRVJUSUZJQ0FURSIsICJYNTA5IENFUlRJRklDQVRFIiwgb3IgJyArCiAgICAgICAgICAgICciVFJVU1RFRCBDRVJUSUZJQ0FURSIuJyk7CiAgICAgICAgICBlcnJvci5oZWFkZXJUeXBlID0gbXNnLnR5cGU7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CiAgICAgICAgaWYobXNnLnByb2NUeXBlICYmIG1zZy5wcm9jVHlwZS50eXBlID09PSAnRU5DUllQVEVEJykgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgY29udmVydCBjZXJ0aWZpY2F0ZSBmcm9tIFBFTTsgUEVNIGlzIGVuY3J5cHRlZC4nKTsKICAgICAgICB9CgogICAgICAgIHZhciBkZXIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihtc2cuYm9keSk7CiAgICAgICAgaWYoYXNuMSA9PT0gbnVsbCkgewogICAgICAgICAgYXNuMSA9IGZvcmdlLmFzbjEuZnJvbURlcihkZXIuYnl0ZXMoKSwgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgLy8gY2VydGlmaWNhdGUgZW50cnkgaXMgaXRzZWxmIGEgdmVjdG9yIHdpdGggMyBsZW5ndGggYnl0ZXMKICAgICAgICB2YXIgY2VydEJ1ZmZlciA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICAgICAgd3JpdGVWZWN0b3IoY2VydEJ1ZmZlciwgMywgZGVyKTsKCiAgICAgICAgLy8gYWRkIGNlcnQgdmVjdG9yIHRvIGNlcnQgbGlzdCB2ZWN0b3IKICAgICAgICBjZXJ0TGlzdC5wdXRCdWZmZXIoY2VydEJ1ZmZlcik7CiAgICAgIH0KCiAgICAgIC8vIHNhdmUgY2VydGlmaWNhdGUKICAgICAgY2VydCA9IGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUZyb21Bc24xKGFzbjEpOwogICAgICBpZihjbGllbnQpIHsKICAgICAgICBjLnNlc3Npb24uY2xpZW50Q2VydGlmaWNhdGUgPSBjZXJ0OwogICAgICB9IGVsc2UgewogICAgICAgIGMuc2Vzc2lvbi5zZXJ2ZXJDZXJ0aWZpY2F0ZSA9IGNlcnQ7CiAgICAgIH0KICAgIH0gY2F0Y2goZXgpIHsKICAgICAgcmV0dXJuIGMuZXJyb3IoYywgewogICAgICAgIG1lc3NhZ2U6ICdDb3VsZCBub3Qgc2VuZCBjZXJ0aWZpY2F0ZSBsaXN0LicsCiAgICAgICAgY2F1c2U6IGV4LAogICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmJhZF9jZXJ0aWZpY2F0ZQogICAgICAgIH0KICAgICAgfSk7CiAgICB9CiAgfQoKICAvLyBkZXRlcm1pbmUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZQogIHZhciBsZW5ndGggPSAzICsgY2VydExpc3QubGVuZ3RoKCk7IC8vIGNlcnQgbGlzdCB2ZWN0b3IKCiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5jZXJ0aWZpY2F0ZSk7CiAgcnZhbC5wdXRJbnQyNChsZW5ndGgpOwogIHdyaXRlVmVjdG9yKHJ2YWwsIDMsIGNlcnRMaXN0KTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDcmVhdGVzIGEgQ2xpZW50S2V5RXhjaGFuZ2UgbWVzc2FnZS4KICoKICogV2hlbiB0aGlzIG1lc3NhZ2Ugd2lsbCBiZSBzZW50OgogKiAgIFRoaXMgbWVzc2FnZSBpcyBhbHdheXMgc2VudCBieSB0aGUgY2xpZW50LiBJdCB3aWxsIGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUKICogICBjbGllbnQgY2VydGlmaWNhdGUgbWVzc2FnZSwgaWYgaXQgaXMgc2VudC4gT3RoZXJ3aXNlIGl0IHdpbGwgYmUgdGhlIGZpcnN0CiAqICAgbWVzc2FnZSBzZW50IGJ5IHRoZSBjbGllbnQgYWZ0ZXIgaXQgcmVjZWl2ZXMgdGhlIHNlcnZlciBoZWxsbyBkb25lCiAqICAgbWVzc2FnZS4KICoKICogTWVhbmluZyBvZiB0aGlzIG1lc3NhZ2U6CiAqICAgV2l0aCB0aGlzIG1lc3NhZ2UsIHRoZSBwcmVtYXN0ZXIgc2VjcmV0IGlzIHNldCwgZWl0aGVyIHRob3VnaCBkaXJlY3QKICogICB0cmFuc21pc3Npb24gb2YgdGhlIFJTQS1lbmNyeXB0ZWQgc2VjcmV0LCBvciBieSB0aGUgdHJhbnNtaXNzaW9uIG9mCiAqICAgRGlmZmllLUhlbGxtYW4gcGFyYW1ldGVycyB3aGljaCB3aWxsIGFsbG93IGVhY2ggc2lkZSB0byBhZ3JlZSB1cG9uIHRoZQogKiAgIHNhbWUgcHJlbWFzdGVyIHNlY3JldC4gV2hlbiB0aGUga2V5IGV4Y2hhbmdlIG1ldGhvZCBpcyBESF9SU0Egb3IgREhfRFNTLAogKiAgIGNsaWVudCBjZXJ0aWZpY2F0aW9uIGhhcyBiZWVuIHJlcXVlc3RlZCwgYW5kIHRoZSBjbGllbnQgd2FzIGFibGUgdG8KICogICByZXNwb25kIHdpdGggYSBjZXJ0aWZpY2F0ZSB3aGljaCBjb250YWluZWQgYSBEaWZmaWUtSGVsbG1hbiBwdWJsaWMga2V5CiAqICAgd2hvc2UgcGFyYW1ldGVycyAoZ3JvdXAgYW5kIGdlbmVyYXRvcikgbWF0Y2hlZCB0aG9zZSBzcGVjaWZpZWQgYnkgdGhlCiAqICAgc2VydmVyIGluIGl0cyBjZXJ0aWZpY2F0ZSwgdGhpcyBtZXNzYWdlIHdpbGwgbm90IGNvbnRhaW4gYW55IGRhdGEuCiAqCiAqIE1lYW5pbmcgb2YgdGhpcyBtZXNzYWdlOgogKiAgIElmIFJTQSBpcyBiZWluZyB1c2VkIGZvciBrZXkgYWdyZWVtZW50IGFuZCBhdXRoZW50aWNhdGlvbiwgdGhlIGNsaWVudAogKiAgIGdlbmVyYXRlcyBhIDQ4LWJ5dGUgcHJlbWFzdGVyIHNlY3JldCwgZW5jcnlwdHMgaXQgdXNpbmcgdGhlIHB1YmxpYyBrZXkKICogICBmcm9tIHRoZSBzZXJ2ZXIncyBjZXJ0aWZpY2F0ZSBvciB0aGUgdGVtcG9yYXJ5IFJTQSBrZXkgcHJvdmlkZWQgaW4gYQogKiAgIHNlcnZlciBrZXkgZXhjaGFuZ2UgbWVzc2FnZSwgYW5kIHNlbmRzIHRoZSByZXN1bHQgaW4gYW4gZW5jcnlwdGVkCiAqICAgcHJlbWFzdGVyIHNlY3JldCBtZXNzYWdlLiBUaGlzIHN0cnVjdHVyZSBpcyBhIHZhcmlhbnQgb2YgdGhlIGNsaWVudAogKiAgIGtleSBleGNoYW5nZSBtZXNzYWdlLCBub3QgYSBtZXNzYWdlIGluIGl0c2VsZi4KICoKICogc3RydWN0IHsKICogICBzZWxlY3QoS2V5RXhjaGFuZ2VBbGdvcml0aG0pIHsKICogICAgIGNhc2UgcnNhOiBFbmNyeXB0ZWRQcmVNYXN0ZXJTZWNyZXQ7CiAqICAgICBjYXNlIGRpZmZpZV9oZWxsbWFuOiBDbGllbnREaWZmaWVIZWxsbWFuUHVibGljOwogKiAgIH0gZXhjaGFuZ2Vfa2V5czsKICogfSBDbGllbnRLZXlFeGNoYW5nZTsKICoKICogc3RydWN0IHsKICogICBQcm90b2NvbFZlcnNpb24gY2xpZW50X3ZlcnNpb247CiAqICAgb3BhcXVlIHJhbmRvbVs0Nl07CiAqIH0gUHJlTWFzdGVyU2VjcmV0OwogKgogKiBzdHJ1Y3QgewogKiAgIHB1YmxpYy1rZXktZW5jcnlwdGVkIFByZU1hc3RlclNlY3JldCBwcmVfbWFzdGVyX3NlY3JldDsKICogfSBFbmNyeXB0ZWRQcmVNYXN0ZXJTZWNyZXQ7CiAqCiAqIEEgcHVibGljLWtleS1lbmNyeXB0ZWQgZWxlbWVudCBpcyBlbmNvZGVkIGFzIGEgdmVjdG9yIDwwLi4yXjE2LTE+LgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgQ2xpZW50S2V5RXhjaGFuZ2UgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlQ2xpZW50S2V5RXhjaGFuZ2UgPSBmdW5jdGlvbihjKSB7CiAgLy8gY3JlYXRlIGJ1ZmZlciB0byBlbmNyeXB0CiAgdmFyIGIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwoKICAvLyBhZGQgaGlnaGVzdCBjbGllbnQtc3VwcG9ydGVkIHByb3RvY29sIHRvIGhlbHAgc2VydmVyIGF2b2lkIHZlcnNpb24KICAvLyByb2xsYmFjayBhdHRhY2tzCiAgYi5wdXRCeXRlKGMuc2Vzc2lvbi5jbGllbnRIZWxsb1ZlcnNpb24ubWFqb3IpOwogIGIucHV0Qnl0ZShjLnNlc3Npb24uY2xpZW50SGVsbG9WZXJzaW9uLm1pbm9yKTsKCiAgLy8gZ2VuZXJhdGUgYW5kIGFkZCA0NiByYW5kb20gYnl0ZXMKICBiLnB1dEJ5dGVzKGZvcmdlLnJhbmRvbS5nZXRCeXRlcyg0NikpOwoKICAvLyBzYXZlIHByZS1tYXN0ZXIgc2VjcmV0CiAgdmFyIHNwID0gYy5zZXNzaW9uLnNwOwogIHNwLnByZV9tYXN0ZXJfc2VjcmV0ID0gYi5nZXRCeXRlcygpOwoKICAvLyBSU0EtZW5jcnlwdCB0aGUgcHJlLW1hc3RlciBzZWNyZXQKICB2YXIga2V5ID0gYy5zZXNzaW9uLnNlcnZlckNlcnRpZmljYXRlLnB1YmxpY0tleTsKICBiID0ga2V5LmVuY3J5cHQoc3AucHJlX21hc3Rlcl9zZWNyZXQpOwoKICAvKiBOb3RlOiBUaGUgZW5jcnlwdGVkIHByZS1tYXN0ZXIgc2VjcmV0IHdpbGwgYmUgc3RvcmVkIGluIGEKICAgIHB1YmxpYy1rZXktZW5jcnlwdGVkIG9wYXF1ZSB2ZWN0b3IgdGhhdCBoYXMgdGhlIGxlbmd0aCBwcmVmaXhlZCB1c2luZwogICAgMiBieXRlcywgc28gaW5jbHVkZSB0aG9zZSAyIGJ5dGVzIGluIHRoZSBoYW5kc2hha2UgbWVzc2FnZSBsZW5ndGguIFRoaXMKICAgIGlzIGRvbmUgYXMgYSBtaW5vciBvcHRpbWl6YXRpb24gaW5zdGVhZCBvZiBjYWxsaW5nIHdyaXRlVmVjdG9yKCkuICovCgogIC8vIGRldGVybWluZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlCiAgdmFyIGxlbmd0aCA9IGIubGVuZ3RoICsgMjsKCiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5jbGllbnRfa2V5X2V4Y2hhbmdlKTsKICBydmFsLnB1dEludDI0KGxlbmd0aCk7CiAgLy8gYWRkIHZlY3RvciBsZW5ndGggYnl0ZXMKICBydmFsLnB1dEludDE2KGIubGVuZ3RoKTsKICBydmFsLnB1dEJ5dGVzKGIpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBTZXJ2ZXJLZXlFeGNoYW5nZSBtZXNzYWdlLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgU2VydmVyS2V5RXhjaGFuZ2UgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlU2VydmVyS2V5RXhjaGFuZ2UgPSBmdW5jdGlvbihjKSB7CiAgLy8gdGhpcyBpbXBsZW1lbnRhdGlvbiBvbmx5IHN1cHBvcnRzIFJTQSwgbm8gRGlmZmllLUhlbGxtYW4gc3VwcG9ydCwKICAvLyBzbyB0aGlzIHJlY29yZCBpcyBlbXB0eQoKICAvLyBkZXRlcm1pbmUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZQogIHZhciBsZW5ndGggPSAwOwoKICAvLyBidWlsZCByZWNvcmQgZnJhZ21lbnQKICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgaWYobGVuZ3RoID4gMCkgewogICAgcnZhbC5wdXRCeXRlKHRscy5IYW5kc2hha2VUeXBlLnNlcnZlcl9rZXlfZXhjaGFuZ2UpOwogICAgcnZhbC5wdXRJbnQyNChsZW5ndGgpOwogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIHRoZSBzaWduZWQgZGF0YSB1c2VkIHRvIHZlcmlmeSBhIGNsaWVudC1zaWRlIGNlcnRpZmljYXRlLiBTZWUKICogdGxzLmNyZWF0ZUNlcnRpZmljYXRlVmVyaWZ5KCkgZm9yIGRldGFpbHMuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gY2FsbGJhY2sgdGhlIGNhbGxiYWNrIHRvIGNhbGwgb25jZSB0aGUgc2lnbmVkIGRhdGEgaXMgcmVhZHkuCiAqLwp0bHMuZ2V0Q2xpZW50U2lnbmF0dXJlID0gZnVuY3Rpb24oYywgY2FsbGJhY2spIHsKICAvLyBnZW5lcmF0ZSBkYXRhIHRvIFJTQSBlbmNyeXB0CiAgdmFyIGIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIGIucHV0QnVmZmVyKGMuc2Vzc2lvbi5tZDUuZGlnZXN0KCkpOwogIGIucHV0QnVmZmVyKGMuc2Vzc2lvbi5zaGExLmRpZ2VzdCgpKTsKICBiID0gYi5nZXRCeXRlcygpOwoKICAvLyBjcmVhdGUgZGVmYXVsdCBzaWduaW5nIGZ1bmN0aW9uIGFzIG5lY2Vzc2FyeQogIGMuZ2V0U2lnbmF0dXJlID0gYy5nZXRTaWduYXR1cmUgfHwgZnVuY3Rpb24oYywgYiwgY2FsbGJhY2spIHsKICAgIC8vIGRvIHJzYSBlbmNyeXB0aW9uLCBjYWxsIGNhbGxiYWNrCiAgICB2YXIgcHJpdmF0ZUtleSA9IG51bGw7CiAgICBpZihjLmdldFByaXZhdGVLZXkpIHsKICAgICAgdHJ5IHsKICAgICAgICBwcml2YXRlS2V5ID0gYy5nZXRQcml2YXRlS2V5KGMsIGMuc2Vzc2lvbi5jbGllbnRDZXJ0aWZpY2F0ZSk7CiAgICAgICAgcHJpdmF0ZUtleSA9IGZvcmdlLnBraS5wcml2YXRlS2V5RnJvbVBlbShwcml2YXRlS2V5KTsKICAgICAgfSBjYXRjaChleCkgewogICAgICAgIGMuZXJyb3IoYywgewogICAgICAgICAgbWVzc2FnZTogJ0NvdWxkIG5vdCBnZXQgcHJpdmF0ZSBrZXkuJywKICAgICAgICAgIGNhdXNlOiBleCwKICAgICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgICBhbGVydDogewogICAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KICAgIGlmKHByaXZhdGVLZXkgPT09IG51bGwpIHsKICAgICAgYy5lcnJvcihjLCB7CiAgICAgICAgbWVzc2FnZTogJ05vIHByaXZhdGUga2V5IHNldC4nLAogICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgfQogICAgICB9KTsKICAgIH0gZWxzZSB7CiAgICAgIGIgPSBwcml2YXRlS2V5LnNpZ24oYiwgbnVsbCk7CiAgICB9CiAgICBjYWxsYmFjayhjLCBiKTsKICB9OwoKICAvLyBnZXQgY2xpZW50IHNpZ25hdHVyZQogIGMuZ2V0U2lnbmF0dXJlKGMsIGIsIGNhbGxiYWNrKTsKfTsKCi8qKgogKiBDcmVhdGVzIGEgQ2VydGlmaWNhdGVWZXJpZnkgbWVzc2FnZS4KICoKICogTWVhbmluZyBvZiB0aGlzIG1lc3NhZ2U6CiAqICAgVGhpcyBzdHJ1Y3R1cmUgY29udmV5cyB0aGUgY2xpZW50J3MgRGlmZmllLUhlbGxtYW4gcHVibGljIHZhbHVlCiAqICAgKFljKSBpZiBpdCB3YXMgbm90IGFscmVhZHkgaW5jbHVkZWQgaW4gdGhlIGNsaWVudCdzIGNlcnRpZmljYXRlLgogKiAgIFRoZSBlbmNvZGluZyB1c2VkIGZvciBZYyBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBlbnVtZXJhdGVkCiAqICAgUHVibGljVmFsdWVFbmNvZGluZy4gVGhpcyBzdHJ1Y3R1cmUgaXMgYSB2YXJpYW50IG9mIHRoZSBjbGllbnQKICogICBrZXkgZXhjaGFuZ2UgbWVzc2FnZSwgbm90IGEgbWVzc2FnZSBpbiBpdHNlbGYuCiAqCiAqIFdoZW4gdGhpcyBtZXNzYWdlIHdpbGwgYmUgc2VudDoKICogICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBwcm92aWRlIGV4cGxpY2l0IHZlcmlmaWNhdGlvbiBvZiBhIGNsaWVudAogKiAgIGNlcnRpZmljYXRlLiBUaGlzIG1lc3NhZ2UgaXMgb25seSBzZW50IGZvbGxvd2luZyBhIGNsaWVudAogKiAgIGNlcnRpZmljYXRlIHRoYXQgaGFzIHNpZ25pbmcgY2FwYWJpbGl0eSAoaS5lLiBhbGwgY2VydGlmaWNhdGVzCiAqICAgZXhjZXB0IHRob3NlIGNvbnRhaW5pbmcgZml4ZWQgRGlmZmllLUhlbGxtYW4gcGFyYW1ldGVycykuIFdoZW4KICogICBzZW50LCBpdCB3aWxsIGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgY2xpZW50IGtleSBleGNoYW5nZSBtZXNzYWdlLgogKgogKiBzdHJ1Y3QgewogKiAgIFNpZ25hdHVyZSBzaWduYXR1cmU7CiAqIH0gQ2VydGlmaWNhdGVWZXJpZnk7CiAqCiAqIENlcnRpZmljYXRlVmVyaWZ5LnNpZ25hdHVyZS5tZDVfaGFzaAogKiAgIE1ENShoYW5kc2hha2VfbWVzc2FnZXMpOwogKgogKiBDZXJ0aWZpY2F0ZS5zaWduYXR1cmUuc2hhX2hhc2gKICogICBTSEEoaGFuZHNoYWtlX21lc3NhZ2VzKTsKICoKICogSGVyZSBoYW5kc2hha2VfbWVzc2FnZXMgcmVmZXJzIHRvIGFsbCBoYW5kc2hha2UgbWVzc2FnZXMgc2VudCBvcgogKiByZWNlaXZlZCBzdGFydGluZyBhdCBjbGllbnQgaGVsbG8gdXAgdG8gYnV0IG5vdCBpbmNsdWRpbmcgdGhpcwogKiBtZXNzYWdlLCBpbmNsdWRpbmcgdGhlIHR5cGUgYW5kIGxlbmd0aCBmaWVsZHMgb2YgdGhlIGhhbmRzaGFrZQogKiBtZXNzYWdlcy4KICoKICogc2VsZWN0KFNpZ25hdHVyZUFsZ29yaXRobSkgewogKiAgIGNhc2UgYW5vbnltb3VzOiBzdHJ1Y3QgeyB9OwogKiAgIGNhc2UgcnNhOgogKiAgICAgZGlnaXRhbGx5LXNpZ25lZCBzdHJ1Y3QgewogKiAgICAgICBvcGFxdWUgbWQ1X2hhc2hbMTZdOwogKiAgICAgICBvcGFxdWUgc2hhX2hhc2hbMjBdOwogKiAgICAgfTsKICogICBjYXNlIGRzYToKICogICAgIGRpZ2l0YWxseS1zaWduZWQgc3RydWN0IHsKICogICAgICAgb3BhcXVlIHNoYV9oYXNoWzIwXTsKICogICAgIH07CiAqIH0gU2lnbmF0dXJlOwogKgogKiBJbiBkaWdpdGFsIHNpZ25pbmcsIG9uZS13YXkgaGFzaCBmdW5jdGlvbnMgYXJlIHVzZWQgYXMgaW5wdXQgZm9yIGEKICogc2lnbmluZyBhbGdvcml0aG0uIEEgZGlnaXRhbGx5LXNpZ25lZCBlbGVtZW50IGlzIGVuY29kZWQgYXMgYW4gb3BhcXVlCiAqIHZlY3RvciA8MC4uMl4xNi0xPiwgd2hlcmUgdGhlIGxlbmd0aCBpcyBzcGVjaWZpZWQgYnkgdGhlIHNpZ25pbmcKICogYWxnb3JpdGhtIGFuZCBrZXkuCiAqCiAqIEluIFJTQSBzaWduaW5nLCBhIDM2LWJ5dGUgc3RydWN0dXJlIG9mIHR3byBoYXNoZXMgKG9uZSBTSEEgYW5kIG9uZQogKiBNRDUpIGlzIHNpZ25lZCAoZW5jcnlwdGVkIHdpdGggdGhlIHByaXZhdGUga2V5KS4gSXQgaXMgZW5jb2RlZCB3aXRoCiAqIFBLQ1MgIzEgYmxvY2sgdHlwZSAwIG9yIHR5cGUgMSBhcyBkZXNjcmliZWQgaW4gW1BLQ1MxXS4KICoKICogSW4gRFNTLCB0aGUgMjAgYnl0ZXMgb2YgdGhlIFNIQSBoYXNoIGFyZSBydW4gZGlyZWN0bHkgdGhyb3VnaCB0aGUKICogRGlnaXRhbCBTaWduaW5nIEFsZ29yaXRobSB3aXRoIG5vIGFkZGl0aW9uYWwgaGFzaGluZy4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSBzaWduYXR1cmUgdGhlIHNpZ25hdHVyZSB0byBpbmNsdWRlIGluIHRoZSBtZXNzYWdlLgogKgogKiBAcmV0dXJuIHRoZSBDZXJ0aWZpY2F0ZVZlcmlmeSBieXRlIGJ1ZmZlci4KICovCnRscy5jcmVhdGVDZXJ0aWZpY2F0ZVZlcmlmeSA9IGZ1bmN0aW9uKGMsIHNpZ25hdHVyZSkgewogIC8qIE5vdGU6IFRoZSBzaWduYXR1cmUgd2lsbCBiZSBzdG9yZWQgaW4gYSAiZGlnaXRhbGx5LXNpZ25lZCIgb3BhcXVlCiAgICB2ZWN0b3IgdGhhdCBoYXMgdGhlIGxlbmd0aCBwcmVmaXhlZCB1c2luZyAyIGJ5dGVzLCBzbyBpbmNsdWRlIHRob3NlCiAgICAyIGJ5dGVzIGluIHRoZSBoYW5kc2hha2UgbWVzc2FnZSBsZW5ndGguIFRoaXMgaXMgZG9uZSBhcyBhIG1pbm9yCiAgICBvcHRpbWl6YXRpb24gaW5zdGVhZCBvZiBjYWxsaW5nIHdyaXRlVmVjdG9yKCkuICovCgogIC8vIGRldGVybWluZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlCiAgdmFyIGxlbmd0aCA9IHNpZ25hdHVyZS5sZW5ndGggKyAyOwoKICAvLyBidWlsZCByZWNvcmQgZnJhZ21lbnQKICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgcnZhbC5wdXRCeXRlKHRscy5IYW5kc2hha2VUeXBlLmNlcnRpZmljYXRlX3ZlcmlmeSk7CiAgcnZhbC5wdXRJbnQyNChsZW5ndGgpOwogIC8vIGFkZCB2ZWN0b3IgbGVuZ3RoIGJ5dGVzCiAgcnZhbC5wdXRJbnQxNihzaWduYXR1cmUubGVuZ3RoKTsKICBydmFsLnB1dEJ5dGVzKHNpZ25hdHVyZSk7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ3JlYXRlcyBhIENlcnRpZmljYXRlUmVxdWVzdCBtZXNzYWdlLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgQ2VydGlmaWNhdGVSZXF1ZXN0IGJ5dGUgYnVmZmVyLgogKi8KdGxzLmNyZWF0ZUNlcnRpZmljYXRlUmVxdWVzdCA9IGZ1bmN0aW9uKGMpIHsKICAvLyBUT0RPOiBzdXBwb3J0IG90aGVyIGNlcnRpZmljYXRlIHR5cGVzCiAgdmFyIGNlcnRUeXBlcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIGNvbW1vbiBSU0EgY2VydGlmaWNhdGUgdHlwZQogIGNlcnRUeXBlcy5wdXRCeXRlKDB4MDEpOwoKICAvLyBUT0RPOiB2ZXJpZnkgdGhhdCB0aGlzIGRhdGEgZm9ybWF0IGlzIGNvcnJlY3QKICAvLyBhZGQgZGlzdGluZ3Vpc2hlZCBuYW1lcyBmcm9tIENBIHN0b3JlCiAgdmFyIGNBcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgZm9yKHZhciBrZXkgaW4gYy5jYVN0b3JlLmNlcnRzKSB7CiAgICB2YXIgY2VydCA9IGMuY2FTdG9yZS5jZXJ0c1trZXldOwogICAgdmFyIGRuID0gZm9yZ2UucGtpLmRpc3Rpbmd1aXNoZWROYW1lVG9Bc24xKGNlcnQuc3ViamVjdCk7CiAgICBjQXMucHV0QnVmZmVyKGZvcmdlLmFzbjEudG9EZXIoZG4pKTsKICB9CgogIC8vIFRPRE86IFRMUyAxLjIrIGhhcyBhIGRpZmZlcmVudCBmb3JtYXQKCiAgLy8gZGV0ZXJtaW5lIGxlbmd0aCBvZiB0aGUgaGFuZHNoYWtlIG1lc3NhZ2UKICB2YXIgbGVuZ3RoID0KICAgIDEgKyBjZXJ0VHlwZXMubGVuZ3RoKCkgKwogICAgMiArIGNBcy5sZW5ndGgoKTsKCiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5jZXJ0aWZpY2F0ZV9yZXF1ZXN0KTsKICBydmFsLnB1dEludDI0KGxlbmd0aCk7CiAgd3JpdGVWZWN0b3IocnZhbCwgMSwgY2VydFR5cGVzKTsKICB3cml0ZVZlY3RvcihydmFsLCAyLCBjQXMpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBTZXJ2ZXJIZWxsb0RvbmUgbWVzc2FnZS4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqCiAqIEByZXR1cm4gdGhlIFNlcnZlckhlbGxvRG9uZSBieXRlIGJ1ZmZlci4KICovCnRscy5jcmVhdGVTZXJ2ZXJIZWxsb0RvbmUgPSBmdW5jdGlvbihjKSB7CiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5zZXJ2ZXJfaGVsbG9fZG9uZSk7CiAgcnZhbC5wdXRJbnQyNCgwKTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDcmVhdGVzIGEgQ2hhbmdlQ2lwaGVyU3BlYyBtZXNzYWdlLgogKgogKiBUaGUgY2hhbmdlIGNpcGhlciBzcGVjIHByb3RvY29sIGV4aXN0cyB0byBzaWduYWwgdHJhbnNpdGlvbnMgaW4KICogY2lwaGVyaW5nIHN0cmF0ZWdpZXMuIFRoZSBwcm90b2NvbCBjb25zaXN0cyBvZiBhIHNpbmdsZSBtZXNzYWdlLAogKiB3aGljaCBpcyBlbmNyeXB0ZWQgYW5kIGNvbXByZXNzZWQgdW5kZXIgdGhlIGN1cnJlbnQgKG5vdCB0aGUgcGVuZGluZykKICogY29ubmVjdGlvbiBzdGF0ZS4gVGhlIG1lc3NhZ2UgY29uc2lzdHMgb2YgYSBzaW5nbGUgYnl0ZSBvZiB2YWx1ZSAxLgogKgogKiBzdHJ1Y3QgewogKiAgIGVudW0geyBjaGFuZ2VfY2lwaGVyX3NwZWMoMSksICgyNTUpIH0gdHlwZTsKICogfSBDaGFuZ2VDaXBoZXJTcGVjOwogKgogKiBAcmV0dXJuIHRoZSBDaGFuZ2VDaXBoZXJTcGVjIGJ5dGUgYnVmZmVyLgogKi8KdGxzLmNyZWF0ZUNoYW5nZUNpcGhlclNwZWMgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgcnZhbC5wdXRCeXRlKDB4MDEpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBGaW5pc2hlZCBtZXNzYWdlLgogKgogKiBzdHJ1Y3QgewogKiAgIG9wYXF1ZSB2ZXJpZnlfZGF0YVsxMl07CiAqIH0gRmluaXNoZWQ7CiAqCiAqIHZlcmlmeV9kYXRhCiAqICAgUFJGKG1hc3Rlcl9zZWNyZXQsIGZpbmlzaGVkX2xhYmVsLCBNRDUoaGFuZHNoYWtlX21lc3NhZ2VzKSArCiAqICAgU0hBLTEoaGFuZHNoYWtlX21lc3NhZ2VzKSkgWzAuLjExXTsKICoKICogZmluaXNoZWRfbGFiZWwKICogICBGb3IgRmluaXNoZWQgbWVzc2FnZXMgc2VudCBieSB0aGUgY2xpZW50LCB0aGUgc3RyaW5nICJjbGllbnQKICogICBmaW5pc2hlZCIuIEZvciBGaW5pc2hlZCBtZXNzYWdlcyBzZW50IGJ5IHRoZSBzZXJ2ZXIsIHRoZQogKiAgIHN0cmluZyAic2VydmVyIGZpbmlzaGVkIi4KICoKICogaGFuZHNoYWtlX21lc3NhZ2VzCiAqICAgQWxsIG9mIHRoZSBkYXRhIGZyb20gYWxsIGhhbmRzaGFrZSBtZXNzYWdlcyB1cCB0byBidXQgbm90CiAqICAgaW5jbHVkaW5nIHRoaXMgbWVzc2FnZS4gVGhpcyBpcyBvbmx5IGRhdGEgdmlzaWJsZSBhdCB0aGUKICogICBoYW5kc2hha2UgbGF5ZXIgYW5kIGRvZXMgbm90IGluY2x1ZGUgcmVjb3JkIGxheWVyIGhlYWRlcnMuCiAqICAgVGhpcyBpcyB0aGUgY29uY2F0ZW5hdGlvbiBvZiBhbGwgdGhlIEhhbmRzaGFrZSBzdHJ1Y3R1cmVzIGFzCiAqICAgZGVmaW5lZCBpbiA3LjQgZXhjaGFuZ2VkIHRodXMgZmFyLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgRmluaXNoZWQgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlRmluaXNoZWQgPSBmdW5jdGlvbihjKSB7CiAgLy8gZ2VuZXJhdGUgdmVyaWZ5X2RhdGEKICB2YXIgYiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgYi5wdXRCdWZmZXIoYy5zZXNzaW9uLm1kNS5kaWdlc3QoKSk7CiAgYi5wdXRCdWZmZXIoYy5zZXNzaW9uLnNoYTEuZGlnZXN0KCkpOwoKICAvLyBUT0RPOiBkZXRlcm1pbmUgcHJmIGZ1bmN0aW9uIGFuZCB2ZXJpZnkgbGVuZ3RoIGZvciBUTFMgMS4yCiAgdmFyIGNsaWVudCA9IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KTsKICB2YXIgc3AgPSBjLnNlc3Npb24uc3A7CiAgdmFyIHZkbCA9IDEyOwogIHZhciBwcmYgPSBwcmZfVExTMTsKICB2YXIgbGFiZWwgPSBjbGllbnQgPyAnY2xpZW50IGZpbmlzaGVkJyA6ICdzZXJ2ZXIgZmluaXNoZWQnOwogIGIgPSBwcmYoc3AubWFzdGVyX3NlY3JldCwgbGFiZWwsIGIuZ2V0Qnl0ZXMoKSwgdmRsKTsKCiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5maW5pc2hlZCk7CiAgcnZhbC5wdXRJbnQyNChiLmxlbmd0aCgpKTsKICBydmFsLnB1dEJ1ZmZlcihiKTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDcmVhdGVzIGEgSGVhcnRiZWF0TWVzc2FnZSAoU2VlIFJGQyA2NTIwKS4KICoKICogc3RydWN0IHsKICogICBIZWFydGJlYXRNZXNzYWdlVHlwZSB0eXBlOwogKiAgIHVpbnQxNiBwYXlsb2FkX2xlbmd0aDsKICogICBvcGFxdWUgcGF5bG9hZFtIZWFydGJlYXRNZXNzYWdlLnBheWxvYWRfbGVuZ3RoXTsKICogICBvcGFxdWUgcGFkZGluZ1twYWRkaW5nX2xlbmd0aF07CiAqIH0gSGVhcnRiZWF0TWVzc2FnZTsKICoKICogVGhlIHRvdGFsIGxlbmd0aCBvZiBhIEhlYXJ0YmVhdE1lc3NhZ2UgTVVTVCBOT1QgZXhjZWVkIDJeMTQgb3IKICogbWF4X2ZyYWdtZW50X2xlbmd0aCB3aGVuIG5lZ290aWF0ZWQgYXMgZGVmaW5lZCBpbiBbUkZDNjA2Nl0uCiAqCiAqIHR5cGU6IFRoZSBtZXNzYWdlIHR5cGUsIGVpdGhlciBoZWFydGJlYXRfcmVxdWVzdCBvciBoZWFydGJlYXRfcmVzcG9uc2UuCiAqCiAqIHBheWxvYWRfbGVuZ3RoOiBUaGUgbGVuZ3RoIG9mIHRoZSBwYXlsb2FkLgogKgogKiBwYXlsb2FkOiBUaGUgcGF5bG9hZCBjb25zaXN0cyBvZiBhcmJpdHJhcnkgY29udGVudC4KICoKICogcGFkZGluZzogVGhlIHBhZGRpbmcgaXMgcmFuZG9tIGNvbnRlbnQgdGhhdCBNVVNUIGJlIGlnbm9yZWQgYnkgdGhlCiAqICAgcmVjZWl2ZXIuIFRoZSBsZW5ndGggb2YgYSBIZWFydGJlYXRNZXNzYWdlIGlzIFRMU1BsYWludGV4dC5sZW5ndGgKICogICBmb3IgVExTIGFuZCBEVExTUGxhaW50ZXh0Lmxlbmd0aCBmb3IgRFRMUy4gRnVydGhlcm1vcmUsIHRoZQogKiAgIGxlbmd0aCBvZiB0aGUgdHlwZSBmaWVsZCBpcyAxIGJ5dGUsIGFuZCB0aGUgbGVuZ3RoIG9mIHRoZQogKiAgIHBheWxvYWRfbGVuZ3RoIGlzIDIuIFRoZXJlZm9yZSwgdGhlIHBhZGRpbmdfbGVuZ3RoIGlzCiAqICAgVExTUGxhaW50ZXh0Lmxlbmd0aCAtIHBheWxvYWRfbGVuZ3RoIC0gMyBmb3IgVExTIGFuZAogKiAgIERUTFNQbGFpbnRleHQubGVuZ3RoIC0gcGF5bG9hZF9sZW5ndGggLSAzIGZvciBEVExTLiBUaGUKICogICBwYWRkaW5nX2xlbmd0aCBNVVNUIGJlIGF0IGxlYXN0IDE2LgogKgogKiBUaGUgc2VuZGVyIG9mIGEgSGVhcnRiZWF0TWVzc2FnZSBNVVNUIHVzZSBhIHJhbmRvbSBwYWRkaW5nIG9mIGF0CiAqIGxlYXN0IDE2IGJ5dGVzLiBUaGUgcGFkZGluZyBvZiBhIHJlY2VpdmVkIEhlYXJ0YmVhdE1lc3NhZ2UgbWVzc2FnZQogKiBNVVNUIGJlIGlnbm9yZWQuCiAqCiAqIElmIHRoZSBwYXlsb2FkX2xlbmd0aCBvZiBhIHJlY2VpdmVkIEhlYXJ0YmVhdE1lc3NhZ2UgaXMgdG9vIGxhcmdlLAogKiB0aGUgcmVjZWl2ZWQgSGVhcnRiZWF0TWVzc2FnZSBNVVNUIGJlIGRpc2NhcmRlZCBzaWxlbnRseS4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSB0eXBlIHRoZSB0bHMuSGVhcnRiZWF0TWVzc2FnZVR5cGUuCiAqIEBwYXJhbSBwYXlsb2FkIHRoZSBoZWFydGJlYXQgZGF0YSB0byBzZW5kIGFzIHRoZSBwYXlsb2FkLgogKiBAcGFyYW0gW3BheWxvYWRMZW5ndGhdIHRoZSBwYXlsb2FkIGxlbmd0aCB0byB1c2UsIGRlZmF1bHRzIHRvIHRoZQogKiAgICAgICAgICBhY3R1YWwgcGF5bG9hZCBsZW5ndGguCiAqCiAqIEByZXR1cm4gdGhlIEhlYXJ0YmVhdFJlcXVlc3QgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlSGVhcnRiZWF0ID0gZnVuY3Rpb24odHlwZSwgcGF5bG9hZCwgcGF5bG9hZExlbmd0aCkgewogIGlmKHR5cGVvZiBwYXlsb2FkTGVuZ3RoID09PSAndW5kZWZpbmVkJykgewogICAgcGF5bG9hZExlbmd0aCA9IHBheWxvYWQubGVuZ3RoOwogIH0KICAvLyBidWlsZCByZWNvcmQgZnJhZ21lbnQKICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgcnZhbC5wdXRCeXRlKHR5cGUpOyAgICAgICAgICAgICAgIC8vIGhlYXJ0YmVhdCBtZXNzYWdlIHR5cGUKICBydmFsLnB1dEludDE2KHBheWxvYWRMZW5ndGgpOyAgICAgLy8gcGF5bG9hZCBsZW5ndGgKICBydmFsLnB1dEJ5dGVzKHBheWxvYWQpOyAgICAgICAgICAgLy8gcGF5bG9hZAogIC8vIHBhZGRpbmcKICB2YXIgcGxhaW50ZXh0TGVuZ3RoID0gcnZhbC5sZW5ndGgoKTsKICB2YXIgcGFkZGluZ0xlbmd0aCA9IE1hdGgubWF4KDE2LCBwbGFpbnRleHRMZW5ndGggLSBwYXlsb2FkTGVuZ3RoIC0gMyk7CiAgcnZhbC5wdXRCeXRlcyhmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMocGFkZGluZ0xlbmd0aCkpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEZyYWdtZW50cywgY29tcHJlc3NlcywgZW5jcnlwdHMsIGFuZCBxdWV1ZXMgYSByZWNvcmQgZm9yIGRlbGl2ZXJ5LgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkIHRvIHF1ZXVlLgogKi8KdGxzLnF1ZXVlID0gZnVuY3Rpb24oYywgcmVjb3JkKSB7CiAgLy8gZXJyb3IgZHVyaW5nIHJlY29yZCBjcmVhdGlvbgogIGlmKCFyZWNvcmQpIHsKICAgIHJldHVybjsKICB9CgogIC8vIGlmIHRoZSByZWNvcmQgaXMgYSBoYW5kc2hha2UgcmVjb3JkLCB1cGRhdGUgaGFuZHNoYWtlIGhhc2hlcwogIGlmKHJlY29yZC50eXBlID09PSB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlKSB7CiAgICB2YXIgYnl0ZXMgPSByZWNvcmQuZnJhZ21lbnQuYnl0ZXMoKTsKICAgIGMuc2Vzc2lvbi5tZDUudXBkYXRlKGJ5dGVzKTsKICAgIGMuc2Vzc2lvbi5zaGExLnVwZGF0ZShieXRlcyk7CiAgICBieXRlcyA9IG51bGw7CiAgfQoKICAvLyBoYW5kbGUgcmVjb3JkIGZyYWdtZW50YXRpb24KICB2YXIgcmVjb3JkczsKICBpZihyZWNvcmQuZnJhZ21lbnQubGVuZ3RoKCkgPD0gdGxzLk1heEZyYWdtZW50KSB7CiAgICByZWNvcmRzID0gW3JlY29yZF07CiAgfSBlbHNlIHsKICAgIC8vIGZyYWdtZW50IGRhdGEgYXMgbG9uZyBhcyBpdCBpcyB0b28gbG9uZwogICAgcmVjb3JkcyA9IFtdOwogICAgdmFyIGRhdGEgPSByZWNvcmQuZnJhZ21lbnQuYnl0ZXMoKTsKICAgIHdoaWxlKGRhdGEubGVuZ3RoID4gdGxzLk1heEZyYWdtZW50KSB7CiAgICAgIHJlY29yZHMucHVzaCh0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICB0eXBlOiByZWNvcmQudHlwZSwKICAgICAgICBkYXRhOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihkYXRhLnNsaWNlKDAsIHRscy5NYXhGcmFnbWVudCkpCiAgICAgIH0pKTsKICAgICAgZGF0YSA9IGRhdGEuc2xpY2UodGxzLk1heEZyYWdtZW50KTsKICAgIH0KICAgIC8vIGFkZCBsYXN0IHJlY29yZAogICAgaWYoZGF0YS5sZW5ndGggPiAwKSB7CiAgICAgIHJlY29yZHMucHVzaCh0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICB0eXBlOiByZWNvcmQudHlwZSwKICAgICAgICBkYXRhOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihkYXRhKQogICAgICB9KSk7CiAgICB9CiAgfQoKICAvLyBjb21wcmVzcyBhbmQgZW5jcnlwdCBhbGwgZnJhZ21lbnRlZCByZWNvcmRzCiAgZm9yKHZhciBpID0gMDsgaSA8IHJlY29yZHMubGVuZ3RoICYmICFjLmZhaWw7ICsraSkgewogICAgLy8gdXBkYXRlIHRoZSByZWNvcmQgdXNpbmcgY3VycmVudCB3cml0ZSBzdGF0ZQogICAgdmFyIHJlYyA9IHJlY29yZHNbaV07CiAgICB2YXIgcyA9IGMuc3RhdGUuY3VycmVudC53cml0ZTsKICAgIGlmKHMudXBkYXRlKGMsIHJlYykpIHsKICAgICAgLy8gc3RvcmUgcmVjb3JkCiAgICAgIGMucmVjb3Jkcy5wdXNoKHJlYyk7CiAgICB9CiAgfQp9OwoKLyoqCiAqIEZsdXNoZXMgYWxsIHF1ZXVlZCByZWNvcmRzIHRvIHRoZSBvdXRwdXQgYnVmZmVyIGFuZCBjYWxscyB0aGUKICogdGxzRGF0YVJlYWR5KCkgaGFuZGxlciBvbiB0aGUgZ2l2ZW4gY29ubmVjdGlvbi4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KdGxzLmZsdXNoID0gZnVuY3Rpb24oYykgewogIGZvcih2YXIgaSA9IDA7IGkgPCBjLnJlY29yZHMubGVuZ3RoOyArK2kpIHsKICAgIHZhciByZWNvcmQgPSBjLnJlY29yZHNbaV07CgogICAgLy8gYWRkIHJlY29yZCBoZWFkZXIgYW5kIGZyYWdtZW50CiAgICBjLnRsc0RhdGEucHV0Qnl0ZShyZWNvcmQudHlwZSk7CiAgICBjLnRsc0RhdGEucHV0Qnl0ZShyZWNvcmQudmVyc2lvbi5tYWpvcik7CiAgICBjLnRsc0RhdGEucHV0Qnl0ZShyZWNvcmQudmVyc2lvbi5taW5vcik7CiAgICBjLnRsc0RhdGEucHV0SW50MTYocmVjb3JkLmZyYWdtZW50Lmxlbmd0aCgpKTsKICAgIGMudGxzRGF0YS5wdXRCdWZmZXIoYy5yZWNvcmRzW2ldLmZyYWdtZW50KTsKICB9CiAgYy5yZWNvcmRzID0gW107CiAgcmV0dXJuIGMudGxzRGF0YVJlYWR5KGMpOwp9OwoKLyoqCiAqIE1hcHMgYSBwa2kuY2VydGlmaWNhdGVFcnJvciB0byBhIHRscy5BbGVydC5EZXNjcmlwdGlvbi4KICoKICogQHBhcmFtIGVycm9yIHRoZSBlcnJvciB0byBtYXAuCiAqCiAqIEByZXR1cm4gdGhlIGFsZXJ0IGRlc2NyaXB0aW9uLgogKi8KdmFyIF9jZXJ0RXJyb3JUb0FsZXJ0RGVzYyA9IGZ1bmN0aW9uKGVycm9yKSB7CiAgc3dpdGNoKGVycm9yKSB7CiAgY2FzZSB0cnVlOgogICAgcmV0dXJuIHRydWU7CiAgY2FzZSBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGU6CiAgICByZXR1cm4gdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmJhZF9jZXJ0aWZpY2F0ZTsKICBjYXNlIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLnVuc3VwcG9ydGVkX2NlcnRpZmljYXRlOgogICAgcmV0dXJuIHRscy5BbGVydC5EZXNjcmlwdGlvbi51bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZTsKICBjYXNlIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLmNlcnRpZmljYXRlX3Jldm9rZWQ6CiAgICByZXR1cm4gdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNlcnRpZmljYXRlX3Jldm9rZWQ7CiAgY2FzZSBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci5jZXJ0aWZpY2F0ZV9leHBpcmVkOgogICAgcmV0dXJuIHRscy5BbGVydC5EZXNjcmlwdGlvbi5jZXJ0aWZpY2F0ZV9leHBpcmVkOwogIGNhc2UgZm9yZ2UucGtpLmNlcnRpZmljYXRlRXJyb3IuY2VydGlmaWNhdGVfdW5rbm93bjoKICAgIHJldHVybiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uY2VydGlmaWNhdGVfdW5rbm93bjsKICBjYXNlIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLnVua25vd25fY2E6CiAgICByZXR1cm4gdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLnVua25vd25fY2E7CiAgZGVmYXVsdDoKICAgIHJldHVybiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uYmFkX2NlcnRpZmljYXRlOwogIH0KfTsKCi8qKgogKiBNYXBzIGEgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uIHRvIGEgcGtpLmNlcnRpZmljYXRlRXJyb3IuCiAqCiAqIEBwYXJhbSBkZXNjIHRoZSBhbGVydCBkZXNjcmlwdGlvbi4KICoKICogQHJldHVybiB0aGUgY2VydGlmaWNhdGUgZXJyb3IuCiAqLwp2YXIgX2FsZXJ0RGVzY1RvQ2VydEVycm9yID0gZnVuY3Rpb24oZGVzYykgewogIHN3aXRjaChkZXNjKSB7CiAgY2FzZSB0cnVlOgogICAgcmV0dXJuIHRydWU7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uYmFkX2NlcnRpZmljYXRlOgogICAgcmV0dXJuIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLmJhZF9jZXJ0aWZpY2F0ZTsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi51bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZToKICAgIHJldHVybiBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci51bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZTsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5jZXJ0aWZpY2F0ZV9yZXZva2VkOgogICAgcmV0dXJuIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLmNlcnRpZmljYXRlX3Jldm9rZWQ7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uY2VydGlmaWNhdGVfZXhwaXJlZDoKICAgIHJldHVybiBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci5jZXJ0aWZpY2F0ZV9leHBpcmVkOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNlcnRpZmljYXRlX3Vua25vd246CiAgICByZXR1cm4gZm9yZ2UucGtpLmNlcnRpZmljYXRlRXJyb3IuY2VydGlmaWNhdGVfdW5rbm93bjsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi51bmtub3duX2NhOgogICAgcmV0dXJuIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLnVua25vd25fY2E7CiAgZGVmYXVsdDoKICAgIHJldHVybiBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGU7CiAgfQp9OwoKLyoqCiAqIFZlcmlmaWVzIGEgY2VydGlmaWNhdGUgY2hhaW4gYWdhaW5zdCB0aGUgZ2l2ZW4gY29ubmVjdGlvbidzCiAqIENlcnRpZmljYXRlIEF1dGhvcml0eSBzdG9yZS4KICoKICogQHBhcmFtIGMgdGhlIFRMUyBjb25uZWN0aW9uLgogKiBAcGFyYW0gY2hhaW4gdGhlIGNlcnRpZmljYXRlIGNoYWluIHRvIHZlcmlmeSwgd2l0aCB0aGUgcm9vdCBvciBoaWdoZXN0CiAqICAgICAgICAgIGF1dGhvcml0eSBhdCB0aGUgZW5kLgogKgogKiBAcmV0dXJuIHRydWUgaWYgc3VjY2Vzc2Z1bCwgZmFsc2UgaWYgbm90LgogKi8KdGxzLnZlcmlmeUNlcnRpZmljYXRlQ2hhaW4gPSBmdW5jdGlvbihjLCBjaGFpbikgewogIHRyeSB7CiAgICAvLyB2ZXJpZnkgY2hhaW4KICAgIGZvcmdlLnBraS52ZXJpZnlDZXJ0aWZpY2F0ZUNoYWluKGMuY2FTdG9yZSwgY2hhaW4sCiAgICAgIGZ1bmN0aW9uIHZlcmlmeSh2ZmQsIGRlcHRoLCBjaGFpbikgewogICAgICAgIC8vIGNvbnZlcnQgcGtpLmNlcnRpZmljYXRlRXJyb3IgdG8gdGxzIGFsZXJ0IGRlc2NyaXB0aW9uCiAgICAgICAgdmFyIGRlc2MgPSBfY2VydEVycm9yVG9BbGVydERlc2ModmZkKTsKCiAgICAgICAgLy8gY2FsbCBhcHBsaWNhdGlvbiBjYWxsYmFjawogICAgICAgIHZhciByZXQgPSBjLnZlcmlmeShjLCB2ZmQsIGRlcHRoLCBjaGFpbik7CiAgICAgICAgaWYocmV0ICE9PSB0cnVlKSB7CiAgICAgICAgICBpZih0eXBlb2YgcmV0ID09PSAnb2JqZWN0JyAmJiAhZm9yZ2UudXRpbC5pc0FycmF5KHJldCkpIHsKICAgICAgICAgICAgLy8gdGhyb3cgY3VzdG9tIGVycm9yCiAgICAgICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignVGhlIGFwcGxpY2F0aW9uIHJlamVjdGVkIHRoZSBjZXJ0aWZpY2F0ZS4nKTsKICAgICAgICAgICAgZXJyb3Iuc2VuZCA9IHRydWU7CiAgICAgICAgICAgIGVycm9yLmFsZXJ0ID0gewogICAgICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5iYWRfY2VydGlmaWNhdGUKICAgICAgICAgICAgfTsKICAgICAgICAgICAgaWYocmV0Lm1lc3NhZ2UpIHsKICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlID0gcmV0Lm1lc3NhZ2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYocmV0LmFsZXJ0KSB7CiAgICAgICAgICAgICAgZXJyb3IuYWxlcnQuZGVzY3JpcHRpb24gPSByZXQuYWxlcnQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgICB9CgogICAgICAgICAgLy8gY29udmVydCB0bHMgYWxlcnQgZGVzY3JpcHRpb24gdG8gcGtpLmNlcnRpZmljYXRlRXJyb3IKICAgICAgICAgIGlmKHJldCAhPT0gdmZkKSB7CiAgICAgICAgICAgIHJldCA9IF9hbGVydERlc2NUb0NlcnRFcnJvcihyZXQpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSk7CiAgfSBjYXRjaChleCkgewogICAgLy8gYnVpbGQgdGxzIGVycm9yIGlmIG5vdCBhbHJlYWR5IGN1c3RvbWl6ZWQKICAgIHZhciBlcnIgPSBleDsKICAgIGlmKHR5cGVvZiBlcnIgIT09ICdvYmplY3QnIHx8IGZvcmdlLnV0aWwuaXNBcnJheShlcnIpKSB7CiAgICAgIGVyciA9IHsKICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgZGVzY3JpcHRpb246IF9jZXJ0RXJyb3JUb0FsZXJ0RGVzYyhleCkKICAgICAgICB9CiAgICAgIH07CiAgICB9CiAgICBpZighKCdzZW5kJyBpbiBlcnIpKSB7CiAgICAgIGVyci5zZW5kID0gdHJ1ZTsKICAgIH0KICAgIGlmKCEoJ2FsZXJ0JyBpbiBlcnIpKSB7CiAgICAgIGVyci5hbGVydCA9IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiBfY2VydEVycm9yVG9BbGVydERlc2MoZXJyLmVycm9yKQogICAgICB9OwogICAgfQoKICAgIC8vIHNlbmQgZXJyb3IKICAgIGMuZXJyb3IoYywgZXJyKTsKICB9CgogIHJldHVybiAhYy5mYWlsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgVExTIHNlc3Npb24gY2FjaGUuCiAqCiAqIEBwYXJhbSBjYWNoZSBvcHRpb25hbCBtYXAgb2Ygc2Vzc2lvbiBJRCB0byBjYWNoZWQgc2Vzc2lvbi4KICogQHBhcmFtIGNhcGFjaXR5IHRoZSBtYXhpbXVtIHNpemUgZm9yIHRoZSBjYWNoZSAoZGVmYXVsdDogMTAwKS4KICoKICogQHJldHVybiB0aGUgbmV3IFRMUyBzZXNzaW9uIGNhY2hlLgogKi8KdGxzLmNyZWF0ZVNlc3Npb25DYWNoZSA9IGZ1bmN0aW9uKGNhY2hlLCBjYXBhY2l0eSkgewogIHZhciBydmFsID0gbnVsbDsKCiAgLy8gYXNzdW1lIGlucHV0IGlzIGFscmVhZHkgYSBzZXNzaW9uIGNhY2hlIG9iamVjdAogIGlmKGNhY2hlICYmIGNhY2hlLmdldFNlc3Npb24gJiYgY2FjaGUuc2V0U2Vzc2lvbiAmJiBjYWNoZS5vcmRlcikgewogICAgcnZhbCA9IGNhY2hlOwogIH0gZWxzZSB7CiAgICAvLyBjcmVhdGUgY2FjaGUKICAgIHJ2YWwgPSB7fTsKICAgIHJ2YWwuY2FjaGUgPSBjYWNoZSB8fCB7fTsKICAgIHJ2YWwuY2FwYWNpdHkgPSBNYXRoLm1heChjYXBhY2l0eSB8fCAxMDAsIDEpOwogICAgcnZhbC5vcmRlciA9IFtdOwoKICAgIC8vIHN0b3JlIG9yZGVyIGZvciBzZXNzaW9ucywgZGVsZXRlIHNlc3Npb24gb3ZlcmZsb3cKICAgIGZvcih2YXIga2V5IGluIGNhY2hlKSB7CiAgICAgIGlmKHJ2YWwub3JkZXIubGVuZ3RoIDw9IGNhcGFjaXR5KSB7CiAgICAgICAgcnZhbC5vcmRlci5wdXNoKGtleSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVsZXRlIGNhY2hlW2tleV07CiAgICAgIH0KICAgIH0KCiAgICAvLyBnZXQgYSBzZXNzaW9uIGZyb20gYSBzZXNzaW9uIElEIChvciBnZXQgYW55IHNlc3Npb24pCiAgICBydmFsLmdldFNlc3Npb24gPSBmdW5jdGlvbihzZXNzaW9uSWQpIHsKICAgICAgdmFyIHNlc3Npb24gPSBudWxsOwogICAgICB2YXIga2V5ID0gbnVsbDsKCiAgICAgIC8vIGlmIHNlc3Npb24gSUQgcHJvdmlkZWQsIHVzZSBpdAogICAgICBpZihzZXNzaW9uSWQpIHsKICAgICAgICBrZXkgPSBmb3JnZS51dGlsLmJ5dGVzVG9IZXgoc2Vzc2lvbklkKTsKICAgICAgfSBlbHNlIGlmKHJ2YWwub3JkZXIubGVuZ3RoID4gMCkgewogICAgICAgIC8vIGdldCBmaXJzdCBzZXNzaW9uIGZyb20gY2FjaGUKICAgICAgICBrZXkgPSBydmFsLm9yZGVyWzBdOwogICAgICB9CgogICAgICBpZihrZXkgIT09IG51bGwgJiYga2V5IGluIHJ2YWwuY2FjaGUpIHsKICAgICAgICAvLyBnZXQgY2FjaGVkIHNlc3Npb24gYW5kIHJlbW92ZSBmcm9tIGNhY2hlCiAgICAgICAgc2Vzc2lvbiA9IHJ2YWwuY2FjaGVba2V5XTsKICAgICAgICBkZWxldGUgcnZhbC5jYWNoZVtrZXldOwogICAgICAgIGZvcih2YXIgaSBpbiBydmFsLm9yZGVyKSB7CiAgICAgICAgICBpZihydmFsLm9yZGVyW2ldID09PSBrZXkpIHsKICAgICAgICAgICAgcnZhbC5vcmRlci5zcGxpY2UoaSwgMSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgcmV0dXJuIHNlc3Npb247CiAgICB9OwoKICAgIC8vIHNldCBhIHNlc3Npb24gaW4gdGhlIGNhY2hlCiAgICBydmFsLnNldFNlc3Npb24gPSBmdW5jdGlvbihzZXNzaW9uSWQsIHNlc3Npb24pIHsKICAgICAgLy8gcmVtb3ZlIHNlc3Npb24gZnJvbSBjYWNoZSBpZiBhdCBjYXBhY2l0eQogICAgICBpZihydmFsLm9yZGVyLmxlbmd0aCA9PT0gcnZhbC5jYXBhY2l0eSkgewogICAgICAgIHZhciBrZXkgPSBydmFsLm9yZGVyLnNoaWZ0KCk7CiAgICAgICAgZGVsZXRlIHJ2YWwuY2FjaGVba2V5XTsKICAgICAgfQogICAgICAvLyBhZGQgc2Vzc2lvbiB0byBjYWNoZQogICAgICB2YXIga2V5ID0gZm9yZ2UudXRpbC5ieXRlc1RvSGV4KHNlc3Npb25JZCk7CiAgICAgIHJ2YWwub3JkZXIucHVzaChrZXkpOwogICAgICBydmFsLmNhY2hlW2tleV0gPSBzZXNzaW9uOwogICAgfTsKICB9CgogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgVExTIGNvbm5lY3Rpb24uCiAqCiAqIFNlZSBwdWJsaWMgY3JlYXRlQ29ubmVjdGlvbigpIGRvY3MgZm9yIG1vcmUgZGV0YWlscy4KICoKICogQHBhcmFtIG9wdGlvbnMgdGhlIG9wdGlvbnMgZm9yIHRoaXMgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgbmV3IFRMUyBjb25uZWN0aW9uLgogKi8KdGxzLmNyZWF0ZUNvbm5lY3Rpb24gPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgdmFyIGNhU3RvcmUgPSBudWxsOwogIGlmKG9wdGlvbnMuY2FTdG9yZSkgewogICAgLy8gaWYgQ0Egc3RvcmUgaXMgYW4gYXJyYXksIGNvbnZlcnQgaXQgdG8gYSBDQSBzdG9yZSBvYmplY3QKICAgIGlmKGZvcmdlLnV0aWwuaXNBcnJheShvcHRpb25zLmNhU3RvcmUpKSB7CiAgICAgIGNhU3RvcmUgPSBmb3JnZS5wa2kuY3JlYXRlQ2FTdG9yZShvcHRpb25zLmNhU3RvcmUpOwogICAgfSBlbHNlIHsKICAgICAgY2FTdG9yZSA9IG9wdGlvbnMuY2FTdG9yZTsKICAgIH0KICB9IGVsc2UgewogICAgLy8gY3JlYXRlIGVtcHR5IENBIHN0b3JlCiAgICBjYVN0b3JlID0gZm9yZ2UucGtpLmNyZWF0ZUNhU3RvcmUoKTsKICB9CgogIC8vIHNldHVwIGRlZmF1bHQgY2lwaGVyIHN1aXRlcwogIHZhciBjaXBoZXJTdWl0ZXMgPSBvcHRpb25zLmNpcGhlclN1aXRlcyB8fCBudWxsOwogIGlmKGNpcGhlclN1aXRlcyA9PT0gbnVsbCkgewogICAgY2lwaGVyU3VpdGVzID0gW107CiAgICBmb3IodmFyIGtleSBpbiB0bHMuQ2lwaGVyU3VpdGVzKSB7CiAgICAgIGNpcGhlclN1aXRlcy5wdXNoKHRscy5DaXBoZXJTdWl0ZXNba2V5XSk7CiAgICB9CiAgfQoKICAvLyBzZXQgZGVmYXVsdCBlbnRpdHkKICB2YXIgZW50aXR5ID0gKG9wdGlvbnMuc2VydmVyIHx8IGZhbHNlKSA/CiAgICB0bHMuQ29ubmVjdGlvbkVuZC5zZXJ2ZXIgOiB0bHMuQ29ubmVjdGlvbkVuZC5jbGllbnQ7CgogIC8vIGNyZWF0ZSBzZXNzaW9uIGNhY2hlIGlmIHJlcXVlc3RlZAogIHZhciBzZXNzaW9uQ2FjaGUgPSBvcHRpb25zLnNlc3Npb25DYWNoZSA/CiAgICB0bHMuY3JlYXRlU2Vzc2lvbkNhY2hlKG9wdGlvbnMuc2Vzc2lvbkNhY2hlKSA6IG51bGw7CgogIC8vIGNyZWF0ZSBUTFMgY29ubmVjdGlvbgogIHZhciBjID0gewogICAgdmVyc2lvbjoge21ham9yOiB0bHMuVmVyc2lvbi5tYWpvciwgbWlub3I6IHRscy5WZXJzaW9uLm1pbm9yfSwKICAgIGVudGl0eTogZW50aXR5LAogICAgc2Vzc2lvbklkOiBvcHRpb25zLnNlc3Npb25JZCwKICAgIGNhU3RvcmU6IGNhU3RvcmUsCiAgICBzZXNzaW9uQ2FjaGU6IHNlc3Npb25DYWNoZSwKICAgIGNpcGhlclN1aXRlczogY2lwaGVyU3VpdGVzLAogICAgY29ubmVjdGVkOiBvcHRpb25zLmNvbm5lY3RlZCwKICAgIHZpcnR1YWxIb3N0OiBvcHRpb25zLnZpcnR1YWxIb3N0IHx8IG51bGwsCiAgICB2ZXJpZnlDbGllbnQ6IG9wdGlvbnMudmVyaWZ5Q2xpZW50IHx8IGZhbHNlLAogICAgdmVyaWZ5OiBvcHRpb25zLnZlcmlmeSB8fCBmdW5jdGlvbihjbiwgdmZkLCBkcHRoLCBjdHMpIHtyZXR1cm4gdmZkO30sCiAgICBnZXRDZXJ0aWZpY2F0ZTogb3B0aW9ucy5nZXRDZXJ0aWZpY2F0ZSB8fCBudWxsLAogICAgZ2V0UHJpdmF0ZUtleTogb3B0aW9ucy5nZXRQcml2YXRlS2V5IHx8IG51bGwsCiAgICBnZXRTaWduYXR1cmU6IG9wdGlvbnMuZ2V0U2lnbmF0dXJlIHx8IG51bGwsCiAgICBpbnB1dDogZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKSwKICAgIHRsc0RhdGE6IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCksCiAgICBkYXRhOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpLAogICAgdGxzRGF0YVJlYWR5OiBvcHRpb25zLnRsc0RhdGFSZWFkeSwKICAgIGRhdGFSZWFkeTogb3B0aW9ucy5kYXRhUmVhZHksCiAgICBoZWFydGJlYXRSZWNlaXZlZDogb3B0aW9ucy5oZWFydGJlYXRSZWNlaXZlZCwKICAgIGNsb3NlZDogb3B0aW9ucy5jbG9zZWQsCiAgICBlcnJvcjogZnVuY3Rpb24oYywgZXgpIHsKICAgICAgLy8gc2V0IG9yaWdpbiBpZiBub3Qgc2V0CiAgICAgIGV4Lm9yaWdpbiA9IGV4Lm9yaWdpbiB8fAogICAgICAgICgoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCkgPyAnY2xpZW50JyA6ICdzZXJ2ZXInKTsKCiAgICAgIC8vIHNlbmQgVExTIGFsZXJ0CiAgICAgIGlmKGV4LnNlbmQpIHsKICAgICAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZUFsZXJ0KGMsIGV4LmFsZXJ0KSk7CiAgICAgICAgdGxzLmZsdXNoKGMpOwogICAgICB9CgogICAgICAvLyBlcnJvciBpcyBmYXRhbCBieSBkZWZhdWx0CiAgICAgIHZhciBmYXRhbCA9IChleC5mYXRhbCAhPT0gZmFsc2UpOwogICAgICBpZihmYXRhbCkgewogICAgICAgIC8vIHNldCBmYWlsIGZsYWcKICAgICAgICBjLmZhaWwgPSB0cnVlOwogICAgICB9CgogICAgICAvLyBjYWxsIGVycm9yIGhhbmRsZXIgZmlyc3QKICAgICAgb3B0aW9ucy5lcnJvcihjLCBleCk7CgogICAgICBpZihmYXRhbCkgewogICAgICAgIC8vIGZhdGFsIGVycm9yLCBjbG9zZSBjb25uZWN0aW9uLCBkbyBub3QgY2xlYXIgZmFpbAogICAgICAgIGMuY2xvc2UoZmFsc2UpOwogICAgICB9CiAgICB9LAogICAgZGVmbGF0ZTogb3B0aW9ucy5kZWZsYXRlIHx8IG51bGwsCiAgICBpbmZsYXRlOiBvcHRpb25zLmluZmxhdGUgfHwgbnVsbAogIH07CgogIC8qKgogICAqIFJlc2V0cyBhIGNsb3NlZCBUTFMgY29ubmVjdGlvbiBmb3IgcmV1c2UuIENhbGxlZCBpbiBjLmNsb3NlKCkuCiAgICoKICAgKiBAcGFyYW0gY2xlYXJGYWlsIHRydWUgdG8gY2xlYXIgdGhlIGZhaWwgZmxhZyAoZGVmYXVsdDogdHJ1ZSkuCiAgICovCiAgYy5yZXNldCA9IGZ1bmN0aW9uKGNsZWFyRmFpbCkgewogICAgYy52ZXJzaW9uID0ge21ham9yOiB0bHMuVmVyc2lvbi5tYWpvciwgbWlub3I6IHRscy5WZXJzaW9uLm1pbm9yfTsKICAgIGMucmVjb3JkID0gbnVsbDsKICAgIGMuc2Vzc2lvbiA9IG51bGw7CiAgICBjLnBlZXJDZXJ0aWZpY2F0ZSA9IG51bGw7CiAgICBjLnN0YXRlID0gewogICAgICBwZW5kaW5nOiBudWxsLAogICAgICBjdXJyZW50OiBudWxsCiAgICB9OwogICAgYy5leHBlY3QgPSAoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCkgPyBTSEUgOiBDSEU7CiAgICBjLmZyYWdtZW50ZWQgPSBudWxsOwogICAgYy5yZWNvcmRzID0gW107CiAgICBjLm9wZW4gPSBmYWxzZTsKICAgIGMuaGFuZHNoYWtlcyA9IDA7CiAgICBjLmhhbmRzaGFraW5nID0gZmFsc2U7CiAgICBjLmlzQ29ubmVjdGVkID0gZmFsc2U7CiAgICBjLmZhaWwgPSAhKGNsZWFyRmFpbCB8fCB0eXBlb2YoY2xlYXJGYWlsKSA9PT0gJ3VuZGVmaW5lZCcpOwogICAgYy5pbnB1dC5jbGVhcigpOwogICAgYy50bHNEYXRhLmNsZWFyKCk7CiAgICBjLmRhdGEuY2xlYXIoKTsKICAgIGMuc3RhdGUuY3VycmVudCA9IHRscy5jcmVhdGVDb25uZWN0aW9uU3RhdGUoYyk7CiAgfTsKCiAgLy8gZG8gaW5pdGlhbCByZXNldCBvZiBjb25uZWN0aW9uCiAgYy5yZXNldCgpOwoKICAvKioKICAgKiBVcGRhdGVzIHRoZSBjdXJyZW50IFRMUyBlbmdpbmUgc3RhdGUgYmFzZWQgb24gdGhlIGdpdmVuIHJlY29yZC4KICAgKgogICAqIEBwYXJhbSBjIHRoZSBUTFMgY29ubmVjdGlvbi4KICAgKiBAcGFyYW0gcmVjb3JkIHRoZSBUTFMgcmVjb3JkIHRvIGFjdCBvbi4KICAgKi8KICB2YXIgX3VwZGF0ZSA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogICAgLy8gZ2V0IHJlY29yZCBoYW5kbGVyIChhbGlnbiB0eXBlIGluIHRhYmxlIGJ5IHN1YnRyYWN0aW5nIGxvd2VzdCkKICAgIHZhciBhbGlnbmVkID0gcmVjb3JkLnR5cGUgLSB0bHMuQ29udGVudFR5cGUuY2hhbmdlX2NpcGhlcl9zcGVjOwogICAgdmFyIGhhbmRsZXJzID0gY3RUYWJsZVtjLmVudGl0eV1bYy5leHBlY3RdOwogICAgaWYoYWxpZ25lZCBpbiBoYW5kbGVycykgewogICAgICBoYW5kbGVyc1thbGlnbmVkXShjLCByZWNvcmQpOwogICAgfSBlbHNlIHsKICAgICAgLy8gdW5leHBlY3RlZCByZWNvcmQKICAgICAgdGxzLmhhbmRsZVVuZXhwZWN0ZWQoYywgcmVjb3JkKTsKICAgIH0KICB9OwoKICAvKioKICAgKiBSZWFkcyB0aGUgcmVjb3JkIGhlYWRlciBhbmQgaW5pdGlhbGl6ZXMgdGhlIG5leHQgcmVjb3JkIG9uIHRoZSBnaXZlbgogICAqIGNvbm5lY3Rpb24uCiAgICoKICAgKiBAcGFyYW0gYyB0aGUgVExTIGNvbm5lY3Rpb24gd2l0aCB0aGUgbmV4dCByZWNvcmQuCiAgICoKICAgKiBAcmV0dXJuIDAgaWYgdGhlIGlucHV0IGRhdGEgY291bGQgYmUgcHJvY2Vzc2VkLCBvdGhlcndpc2UgdGhlCiAgICogICAgICAgICBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgZm9yIGRhdGEgdG8gYmUgcHJvY2Vzc2VkLgogICAqLwogIHZhciBfcmVhZFJlY29yZEhlYWRlciA9IGZ1bmN0aW9uKGMpIHsKICAgIHZhciBydmFsID0gMDsKCiAgICAvLyBnZXQgaW5wdXQgYnVmZmVyIGFuZCBpdHMgbGVuZ3RoCiAgICB2YXIgYiA9IGMuaW5wdXQ7CiAgICB2YXIgbGVuID0gYi5sZW5ndGgoKTsKCiAgICAvLyBuZWVkIGF0IGxlYXN0IDUgYnl0ZXMgdG8gaW5pdGlhbGl6ZSBhIHJlY29yZAogICAgaWYobGVuIDwgNSkgewogICAgICBydmFsID0gNSAtIGxlbjsKICAgIH0gZWxzZSB7CiAgICAgIC8vIGVub3VnaCBieXRlcyBmb3IgaGVhZGVyCiAgICAgIC8vIGluaXRpYWxpemUgcmVjb3JkCiAgICAgIGMucmVjb3JkID0gewogICAgICAgIHR5cGU6IGIuZ2V0Qnl0ZSgpLAogICAgICAgIHZlcnNpb246IHsKICAgICAgICAgIG1ham9yOiBiLmdldEJ5dGUoKSwKICAgICAgICAgIG1pbm9yOiBiLmdldEJ5dGUoKQogICAgICAgIH0sCiAgICAgICAgbGVuZ3RoOiBiLmdldEludDE2KCksCiAgICAgICAgZnJhZ21lbnQ6IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCksCiAgICAgICAgcmVhZHk6IGZhbHNlCiAgICAgIH07CgogICAgICAvLyBjaGVjayByZWNvcmQgdmVyc2lvbgogICAgICB2YXIgY29tcGF0aWJsZVZlcnNpb24gPSAoYy5yZWNvcmQudmVyc2lvbi5tYWpvciA9PT0gYy52ZXJzaW9uLm1ham9yKTsKICAgICAgaWYoY29tcGF0aWJsZVZlcnNpb24gJiYgYy5zZXNzaW9uICYmIGMuc2Vzc2lvbi52ZXJzaW9uKSB7CiAgICAgICAgLy8gc2Vzc2lvbiB2ZXJzaW9uIGFscmVhZHkgc2V0LCByZXF1aXJlIHNhbWUgbWlub3IgdmVyc2lvbgogICAgICAgIGNvbXBhdGlibGVWZXJzaW9uID0gKGMucmVjb3JkLnZlcnNpb24ubWlub3IgPT09IGMudmVyc2lvbi5taW5vcik7CiAgICAgIH0KICAgICAgaWYoIWNvbXBhdGlibGVWZXJzaW9uKSB7CiAgICAgICAgYy5lcnJvcihjLCB7CiAgICAgICAgICBtZXNzYWdlOiAnSW5jb21wYXRpYmxlIFRMUyB2ZXJzaW9uLicsCiAgICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5wcm90b2NvbF92ZXJzaW9uCiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAvKioKICAgKiBSZWFkcyB0aGUgbmV4dCByZWNvcmQncyBjb250ZW50cyBhbmQgYXBwZW5kcyBpdHMgbWVzc2FnZSB0byBhbnkKICAgKiBwcmV2aW91c2x5IGZyYWdtZW50ZWQgbWVzc2FnZS4KICAgKgogICAqIEBwYXJhbSBjIHRoZSBUTFMgY29ubmVjdGlvbiB3aXRoIHRoZSBuZXh0IHJlY29yZC4KICAgKgogICAqIEByZXR1cm4gMCBpZiB0aGUgaW5wdXQgZGF0YSBjb3VsZCBiZSBwcm9jZXNzZWQsIG90aGVyd2lzZSB0aGUKICAgKiAgICAgICAgIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCBmb3IgZGF0YSB0byBiZSBwcm9jZXNzZWQuCiAgICovCiAgdmFyIF9yZWFkUmVjb3JkID0gZnVuY3Rpb24oYykgewogICAgdmFyIHJ2YWwgPSAwOwoKICAgIC8vIGVuc3VyZSB0aGVyZSBpcyBlbm91Z2ggaW5wdXQgZGF0YSB0byBnZXQgdGhlIGVudGlyZSByZWNvcmQKICAgIHZhciBiID0gYy5pbnB1dDsKICAgIHZhciBsZW4gPSBiLmxlbmd0aCgpOwogICAgaWYobGVuIDwgYy5yZWNvcmQubGVuZ3RoKSB7CiAgICAgIC8vIG5vdCBlbm91Z2ggZGF0YSB5ZXQsIHJldHVybiBob3cgbXVjaCBpcyByZXF1aXJlZAogICAgICBydmFsID0gYy5yZWNvcmQubGVuZ3RoIC0gbGVuOwogICAgfSBlbHNlIHsKICAgICAgLy8gdGhlcmUgaXMgZW5vdWdoIGRhdGEgdG8gcGFyc2UgdGhlIHBlbmRpbmcgcmVjb3JkCiAgICAgIC8vIGZpbGwgcmVjb3JkIGZyYWdtZW50IGFuZCBjb21wYWN0IGlucHV0IGJ1ZmZlcgogICAgICBjLnJlY29yZC5mcmFnbWVudC5wdXRCeXRlcyhiLmdldEJ5dGVzKGMucmVjb3JkLmxlbmd0aCkpOwogICAgICBiLmNvbXBhY3QoKTsKCiAgICAgIC8vIHVwZGF0ZSByZWNvcmQgdXNpbmcgY3VycmVudCByZWFkIHN0YXRlCiAgICAgIHZhciBzID0gYy5zdGF0ZS5jdXJyZW50LnJlYWQ7CiAgICAgIGlmKHMudXBkYXRlKGMsIGMucmVjb3JkKSkgewogICAgICAgIC8vIHNlZSBpZiB0aGVyZSBpcyBhIHByZXZpb3VzbHkgZnJhZ21lbnRlZCBtZXNzYWdlIHRoYXQgdGhlCiAgICAgICAgLy8gbmV3IHJlY29yZCdzIG1lc3NhZ2UgZnJhZ21lbnQgc2hvdWxkIGJlIGFwcGVuZGVkIHRvCiAgICAgICAgaWYoYy5mcmFnbWVudGVkICE9PSBudWxsKSB7CiAgICAgICAgICAvLyBpZiB0aGUgcmVjb3JkIHR5cGUgbWF0Y2hlcyBhIHByZXZpb3VzbHkgZnJhZ21lbnRlZAogICAgICAgICAgLy8gcmVjb3JkLCBhcHBlbmQgdGhlIHJlY29yZCBmcmFnbWVudCB0byBpdAogICAgICAgICAgaWYoYy5mcmFnbWVudGVkLnR5cGUgPT09IGMucmVjb3JkLnR5cGUpIHsKICAgICAgICAgICAgLy8gY29uY2F0ZW5hdGUgcmVjb3JkIGZyYWdtZW50cwogICAgICAgICAgICBjLmZyYWdtZW50ZWQuZnJhZ21lbnQucHV0QnVmZmVyKGMucmVjb3JkLmZyYWdtZW50KTsKICAgICAgICAgICAgYy5yZWNvcmQgPSBjLmZyYWdtZW50ZWQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBlcnJvciwgaW52YWxpZCBmcmFnbWVudGVkIHJlY29yZAogICAgICAgICAgICBjLmVycm9yKGMsIHsKICAgICAgICAgICAgICBtZXNzYWdlOiAnSW52YWxpZCBmcmFnbWVudGVkIHJlY29yZC4nLAogICAgICAgICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjoKICAgICAgICAgICAgICAgICAgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLnVuZXhwZWN0ZWRfbWVzc2FnZQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyByZWNvcmQgaXMgbm93IHJlYWR5CiAgICAgICAgYy5yZWNvcmQucmVhZHkgPSB0cnVlOwogICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJ2YWw7CiAgfTsKCiAgLyoqCiAgICogUGVyZm9ybXMgYSBoYW5kc2hha2UgdXNpbmcgdGhlIFRMUyBIYW5kc2hha2UgUHJvdG9jb2wsIGFzIGEgY2xpZW50LgogICAqCiAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGlmIHRoZSBjb25uZWN0aW9uIGlzIGluIGNsaWVudCBtb2RlLgogICAqCiAgICogQHBhcmFtIHNlc3Npb25JZCB0aGUgc2Vzc2lvbiBJRCB0byB1c2UsIG51bGwgdG8gc3RhcnQgYSBuZXcgb25lLgogICAqLwogIGMuaGFuZHNoYWtlID0gZnVuY3Rpb24oc2Vzc2lvbklkKSB7CiAgICAvLyBlcnJvciB0byBjYWxsIHRoaXMgaW4gbm9uLWNsaWVudCBtb2RlCiAgICBpZihjLmVudGl0eSAhPT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KSB7CiAgICAgIC8vIG5vdCBmYXRhbCBlcnJvcgogICAgICBjLmVycm9yKGMsIHsKICAgICAgICBtZXNzYWdlOiAnQ2Fubm90IGluaXRpYXRlIGhhbmRzaGFrZSBhcyBhIHNlcnZlci4nLAogICAgICAgIGZhdGFsOiBmYWxzZQogICAgICB9KTsKICAgIH0gZWxzZSBpZihjLmhhbmRzaGFraW5nKSB7CiAgICAgIC8vIGhhbmRzaGFrZSBpcyBhbHJlYWR5IGluIHByb2dyZXNzLCBmYWlsIGJ1dCBub3QgZmF0YWwgZXJyb3IKICAgICAgYy5lcnJvcihjLCB7CiAgICAgICAgbWVzc2FnZTogJ0hhbmRzaGFrZSBhbHJlYWR5IGluIHByb2dyZXNzLicsCiAgICAgICAgZmF0YWw6IGZhbHNlCiAgICAgIH0pOwogICAgfSBlbHNlIHsKICAgICAgLy8gY2xlYXIgZmFpbCBmbGFnIG9uIHJldXNlCiAgICAgIGlmKGMuZmFpbCAmJiAhYy5vcGVuICYmIGMuaGFuZHNoYWtlcyA9PT0gMCkgewogICAgICAgIGMuZmFpbCA9IGZhbHNlOwogICAgICB9CgogICAgICAvLyBub3cgaGFuZHNoYWtpbmcKICAgICAgYy5oYW5kc2hha2luZyA9IHRydWU7CgogICAgICAvLyBkZWZhdWx0IHRvIGJsYW5rIChuZXcgc2Vzc2lvbikKICAgICAgc2Vzc2lvbklkID0gc2Vzc2lvbklkIHx8ICcnOwoKICAgICAgLy8gaWYgYSBzZXNzaW9uIElEIHdhcyBzcGVjaWZpZWQsIHRyeSB0byBmaW5kIGl0IGluIHRoZSBjYWNoZQogICAgICB2YXIgc2Vzc2lvbiA9IG51bGw7CiAgICAgIGlmKHNlc3Npb25JZC5sZW5ndGggPiAwKSB7CiAgICAgICAgaWYoYy5zZXNzaW9uQ2FjaGUpIHsKICAgICAgICAgIHNlc3Npb24gPSBjLnNlc3Npb25DYWNoZS5nZXRTZXNzaW9uKHNlc3Npb25JZCk7CiAgICAgICAgfQoKICAgICAgICAvLyBtYXRjaGluZyBzZXNzaW9uIG5vdCBmb3VuZCBpbiBjYWNoZSwgY2xlYXIgc2Vzc2lvbiBJRAogICAgICAgIGlmKHNlc3Npb24gPT09IG51bGwpIHsKICAgICAgICAgIHNlc3Npb25JZCA9ICcnOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gbm8gc2Vzc2lvbiBnaXZlbiwgZ3JhYiBhIHNlc3Npb24gZnJvbSB0aGUgY2FjaGUsIGlmIGF2YWlsYWJsZQogICAgICBpZihzZXNzaW9uSWQubGVuZ3RoID09PSAwICYmIGMuc2Vzc2lvbkNhY2hlKSB7CiAgICAgICAgc2Vzc2lvbiA9IGMuc2Vzc2lvbkNhY2hlLmdldFNlc3Npb24oKTsKICAgICAgICBpZihzZXNzaW9uICE9PSBudWxsKSB7CiAgICAgICAgICBzZXNzaW9uSWQgPSBzZXNzaW9uLmlkOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gc2V0IHVwIHNlc3Npb24KICAgICAgYy5zZXNzaW9uID0gewogICAgICAgIGlkOiBzZXNzaW9uSWQsCiAgICAgICAgdmVyc2lvbjogbnVsbCwKICAgICAgICBjaXBoZXJTdWl0ZTogbnVsbCwKICAgICAgICBjb21wcmVzc2lvbk1ldGhvZDogbnVsbCwKICAgICAgICBzZXJ2ZXJDZXJ0aWZpY2F0ZTogbnVsbCwKICAgICAgICBjZXJ0aWZpY2F0ZVJlcXVlc3Q6IG51bGwsCiAgICAgICAgY2xpZW50Q2VydGlmaWNhdGU6IG51bGwsCiAgICAgICAgc3A6IHt9LAogICAgICAgIG1kNTogZm9yZ2UubWQubWQ1LmNyZWF0ZSgpLAogICAgICAgIHNoYTE6IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCkKICAgICAgfTsKCiAgICAgIC8vIHVzZSBleGlzdGluZyBzZXNzaW9uIGluZm9ybWF0aW9uCiAgICAgIGlmKHNlc3Npb24pIHsKICAgICAgICAvLyBvbmx5IHVwZGF0ZSB2ZXJzaW9uIG9uIGNvbm5lY3Rpb24sIHNlc3Npb24gdmVyc2lvbiBub3QgeWV0IHNldAogICAgICAgIGMudmVyc2lvbiA9IHNlc3Npb24udmVyc2lvbjsKICAgICAgICBjLnNlc3Npb24uc3AgPSBzZXNzaW9uLnNwOwogICAgICB9CgogICAgICAvLyBnZW5lcmF0ZSBuZXcgY2xpZW50IHJhbmRvbQogICAgICBjLnNlc3Npb24uc3AuY2xpZW50X3JhbmRvbSA9IHRscy5jcmVhdGVSYW5kb20oKS5nZXRCeXRlcygpOwoKICAgICAgLy8gY29ubmVjdGlvbiBub3cgb3BlbgogICAgICBjLm9wZW4gPSB0cnVlOwoKICAgICAgLy8gc2VuZCBoZWxsbwogICAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgICAgICBkYXRhOiB0bHMuY3JlYXRlQ2xpZW50SGVsbG8oYykKICAgICAgfSkpOwogICAgICB0bHMuZmx1c2goYyk7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogQ2FsbGVkIHdoZW4gVExTIHByb3RvY29sIGRhdGEgaGFzIGJlZW4gcmVjZWl2ZWQgZnJvbSBzb21ld2hlcmUgYW5kIHNob3VsZAogICAqIGJlIHByb2Nlc3NlZCBieSB0aGUgVExTIGVuZ2luZS4KICAgKgogICAqIEBwYXJhbSBkYXRhIHRoZSBUTFMgcHJvdG9jb2wgZGF0YSwgYXMgYSBzdHJpbmcsIHRvIHByb2Nlc3MuCiAgICoKICAgKiBAcmV0dXJuIDAgaWYgdGhlIGRhdGEgY291bGQgYmUgcHJvY2Vzc2VkLCBvdGhlcndpc2UgdGhlIG51bWJlciBvZiBieXRlcwogICAqICAgICAgICAgcmVxdWlyZWQgZm9yIGRhdGEgdG8gYmUgcHJvY2Vzc2VkLgogICAqLwogIGMucHJvY2VzcyA9IGZ1bmN0aW9uKGRhdGEpIHsKICAgIHZhciBydmFsID0gMDsKCiAgICAvLyBidWZmZXIgaW5wdXQgZGF0YQogICAgaWYoZGF0YSkgewogICAgICBjLmlucHV0LnB1dEJ5dGVzKGRhdGEpOwogICAgfQoKICAgIC8vIHByb2Nlc3MgbmV4dCByZWNvcmQgaWYgbm8gZmFpbHVyZSwgcHJvY2VzcyB3aWxsIGJlIGNhbGxlZCBhZnRlcgogICAgLy8gZWFjaCByZWNvcmQgaXMgaGFuZGxlZCAoc2luY2UgaGFuZGxpbmcgY2FuIGJlIGFzeW5jaHJvbm91cykKICAgIGlmKCFjLmZhaWwpIHsKICAgICAgLy8gcmVzZXQgcmVjb3JkIGlmIHJlYWR5IGFuZCBub3cgZW1wdHkKICAgICAgaWYoYy5yZWNvcmQgIT09IG51bGwgJiYKICAgICAgICBjLnJlY29yZC5yZWFkeSAmJiBjLnJlY29yZC5mcmFnbWVudC5pc0VtcHR5KCkpIHsKICAgICAgICBjLnJlY29yZCA9IG51bGw7CiAgICAgIH0KCiAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIHBlbmRpbmcgcmVjb3JkLCB0cnkgdG8gcmVhZCByZWNvcmQgaGVhZGVyCiAgICAgIGlmKGMucmVjb3JkID09PSBudWxsKSB7CiAgICAgICAgcnZhbCA9IF9yZWFkUmVjb3JkSGVhZGVyKGMpOwogICAgICB9CgogICAgICAvLyByZWFkIHRoZSBuZXh0IHJlY29yZCAoaWYgcmVjb3JkIG5vdCB5ZXQgcmVhZHkpCiAgICAgIGlmKCFjLmZhaWwgJiYgYy5yZWNvcmQgIT09IG51bGwgJiYgIWMucmVjb3JkLnJlYWR5KSB7CiAgICAgICAgcnZhbCA9IF9yZWFkUmVjb3JkKGMpOwogICAgICB9CgogICAgICAvLyByZWNvcmQgcmVhZHkgdG8gYmUgaGFuZGxlZCwgdXBkYXRlIGVuZ2luZSBzdGF0ZQogICAgICBpZighYy5mYWlsICYmIGMucmVjb3JkICE9PSBudWxsICYmIGMucmVjb3JkLnJlYWR5KSB7CiAgICAgICAgX3VwZGF0ZShjLCBjLnJlY29yZCk7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAvKioKICAgKiBSZXF1ZXN0cyB0aGF0IGFwcGxpY2F0aW9uIGRhdGEgYmUgcGFja2FnZWQgaW50byBhIFRMUyByZWNvcmQuIFRoZQogICAqIHRsc0RhdGFSZWFkeSBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkIHdoZW4gdGhlIFRMUyByZWNvcmQocykgaGF2ZSBiZWVuCiAgICogcHJlcGFyZWQuCiAgICoKICAgKiBAcGFyYW0gZGF0YSB0aGUgYXBwbGljYXRpb24gZGF0YSwgYXMgYSByYXcgJ2JpbmFyeScgZW5jb2RlZCBzdHJpbmcsIHRvCiAgICogICAgICAgICAgYmUgc2VudDsgdG8gc2VuZCB1dGYtMTYvdXRmLTggc3RyaW5nIGRhdGEsIHVzZSB0aGUgcmV0dXJuIHZhbHVlCiAgICogICAgICAgICAgb2YgdXRpbC5lbmNvZGVVdGY4KHN0cikuCiAgICoKICAgKiBAcmV0dXJuIHRydWUgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZS4KICAgKi8KICBjLnByZXBhcmUgPSBmdW5jdGlvbihkYXRhKSB7CiAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgIHR5cGU6IHRscy5Db250ZW50VHlwZS5hcHBsaWNhdGlvbl9kYXRhLAogICAgICBkYXRhOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihkYXRhKQogICAgfSkpOwogICAgcmV0dXJuIHRscy5mbHVzaChjKTsKICB9OwoKICAvKioKICAgKiBSZXF1ZXN0cyB0aGF0IGEgaGVhcnRiZWF0IHJlcXVlc3QgYmUgcGFja2FnZWQgaW50byBhIFRMUyByZWNvcmQgZm9yCiAgICogdHJhbnNtaXNzaW9uLiBUaGUgdGxzRGF0YVJlYWR5IGhhbmRsZXIgd2lsbCBiZSBjYWxsZWQgd2hlbiBUTFMgcmVjb3JkKHMpCiAgICogaGF2ZSBiZWVuIHByZXBhcmVkLgogICAqCiAgICogV2hlbiBhIGhlYXJ0YmVhdCByZXNwb25zZSBoYXMgYmVlbiByZWNlaXZlZCwgdGhlIGhlYXJ0YmVhdFJlY2VpdmVkCiAgICogaGFuZGxlciB3aWxsIGJlIGNhbGxlZCB3aXRoIHRoZSBtYXRjaGluZyBwYXlsb2FkLiBUaGlzIGhhbmRsZXIgY2FuCiAgICogYmUgdXNlZCB0byBjbGVhciBhIHJldHJhbnNtaXNzaW9uIHRpbWVyLCBldGMuCiAgICoKICAgKiBAcGFyYW0gcGF5bG9hZCB0aGUgaGVhcnRiZWF0IGRhdGEgdG8gc2VuZCBhcyB0aGUgcGF5bG9hZCBpbiB0aGUgbWVzc2FnZS4KICAgKiBAcGFyYW0gW3BheWxvYWRMZW5ndGhdIHRoZSBwYXlsb2FkIGxlbmd0aCB0byB1c2UsIGRlZmF1bHRzIHRvIHRoZQogICAqICAgICAgICAgIGFjdHVhbCBwYXlsb2FkIGxlbmd0aC4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogICAqLwogIGMucHJlcGFyZUhlYXJ0YmVhdFJlcXVlc3QgPSBmdW5jdGlvbihwYXlsb2FkLCBwYXlsb2FkTGVuZ3RoKSB7CiAgICBpZihwYXlsb2FkIGluc3RhbmNlb2YgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKSB7CiAgICAgIHBheWxvYWQgPSBwYXlsb2FkLmJ5dGVzKCk7CiAgICB9CiAgICBpZih0eXBlb2YgcGF5bG9hZExlbmd0aCA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgcGF5bG9hZExlbmd0aCA9IHBheWxvYWQubGVuZ3RoOwogICAgfQogICAgYy5leHBlY3RlZEhlYXJ0YmVhdFBheWxvYWQgPSBwYXlsb2FkOwogICAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVSZWNvcmQoYywgewogICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGVhcnRiZWF0LAogICAgICBkYXRhOiB0bHMuY3JlYXRlSGVhcnRiZWF0KAogICAgICAgIHRscy5IZWFydGJlYXRNZXNzYWdlVHlwZS5oZWFydGJlYXRfcmVxdWVzdCwgcGF5bG9hZCwgcGF5bG9hZExlbmd0aCkKICAgIH0pKTsKICAgIHJldHVybiB0bHMuZmx1c2goYyk7CiAgfTsKCiAgLyoqCiAgICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uIChzZW5kcyBhIGNsb3NlX25vdGlmeSBhbGVydCkuCiAgICoKICAgKiBAcGFyYW0gY2xlYXJGYWlsIHRydWUgdG8gY2xlYXIgdGhlIGZhaWwgZmxhZyAoZGVmYXVsdDogdHJ1ZSkuCiAgICovCiAgYy5jbG9zZSA9IGZ1bmN0aW9uKGNsZWFyRmFpbCkgewogICAgLy8gc2F2ZSBzZXNzaW9uIGlmIGNvbm5lY3Rpb24gZGlkbid0IGZhaWwKICAgIGlmKCFjLmZhaWwgJiYgYy5zZXNzaW9uQ2FjaGUgJiYgYy5zZXNzaW9uKSB7CiAgICAgIC8vIG9ubHkgbmVlZCB0byBwcmVzZXJ2ZSBzZXNzaW9uIElELCB2ZXJzaW9uLCBhbmQgc2VjdXJpdHkgcGFyYW1zCiAgICAgIHZhciBzZXNzaW9uID0gewogICAgICAgIGlkOiBjLnNlc3Npb24uaWQsCiAgICAgICAgdmVyc2lvbjogYy5zZXNzaW9uLnZlcnNpb24sCiAgICAgICAgc3A6IGMuc2Vzc2lvbi5zcAogICAgICB9OwogICAgICBzZXNzaW9uLnNwLmtleXMgPSBudWxsOwogICAgICBjLnNlc3Npb25DYWNoZS5zZXRTZXNzaW9uKHNlc3Npb24uaWQsIHNlc3Npb24pOwogICAgfQoKICAgIGlmKGMub3BlbikgewogICAgICAvLyBjb25uZWN0aW9uIG5vIGxvbmdlciBvcGVuLCBjbGVhciBpbnB1dAogICAgICBjLm9wZW4gPSBmYWxzZTsKICAgICAgYy5pbnB1dC5jbGVhcigpOwoKICAgICAgLy8gaWYgY29ubmVjdGVkIG9yIGhhbmRzaGFraW5nLCBzZW5kIGFuIGFsZXJ0CiAgICAgIGlmKGMuaXNDb25uZWN0ZWQgfHwgYy5oYW5kc2hha2luZykgewogICAgICAgIGMuaXNDb25uZWN0ZWQgPSBjLmhhbmRzaGFraW5nID0gZmFsc2U7CgogICAgICAgIC8vIHNlbmQgY2xvc2Vfbm90aWZ5IGFsZXJ0CiAgICAgICAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVBbGVydChjLCB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLndhcm5pbmcsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNsb3NlX25vdGlmeQogICAgICAgIH0pKTsKICAgICAgICB0bHMuZmx1c2goYyk7CiAgICAgIH0KCiAgICAgIC8vIGNhbGwgaGFuZGxlcgogICAgICBjLmNsb3NlZChjKTsKICAgIH0KCiAgICAvLyByZXNldCBUTFMgY29ubmVjdGlvbiwgZG8gbm90IGNsZWFyIGZhaWwgZmxhZwogICAgYy5yZXNldChjbGVhckZhaWwpOwogIH07CgogIHJldHVybiBjOwp9OwoKLyogVExTIEFQSSAqLwpmb3JnZS50bHMgPSBmb3JnZS50bHMgfHwge307CgovLyBleHBvc2Ugbm9uLWZ1bmN0aW9ucwpmb3IodmFyIGtleSBpbiB0bHMpIHsKICBpZih0eXBlb2YgdGxzW2tleV0gIT09ICdmdW5jdGlvbicpIHsKICAgIGZvcmdlLnRsc1trZXldID0gdGxzW2tleV07CiAgfQp9CgovLyBleHBvc2UgcHJmX3RsczEgZm9yIHRlc3RpbmcKZm9yZ2UudGxzLnByZl90bHMxID0gcHJmX1RMUzE7CgovLyBleHBvc2Ugc2hhMSBobWFjIG1ldGhvZApmb3JnZS50bHMuaG1hY19zaGExID0gaG1hY19zaGExOwoKLy8gZXhwb3NlIHNlc3Npb24gY2FjaGUgY3JlYXRpb24KZm9yZ2UudGxzLmNyZWF0ZVNlc3Npb25DYWNoZSA9IHRscy5jcmVhdGVTZXNzaW9uQ2FjaGU7CgovKioKICogQ3JlYXRlcyBhIG5ldyBUTFMgY29ubmVjdGlvbi4gVGhpcyBkb2VzIG5vdCBtYWtlIGFueSBhc3N1bXB0aW9ucyBhYm91dCB0aGUKICogdHJhbnNwb3J0IGxheWVyIHRoYXQgVExTIGlzIHdvcmtpbmcgb24gdG9wIG9mLCBpZTogaXQgZG9lcyBub3QgYXNzdW1lIHRoZXJlCiAqIGlzIGEgVENQL0lQIGNvbm5lY3Rpb24gb3IgZXN0YWJsaXNoIG9uZS4gQSBUTFMgY29ubmVjdGlvbiBpcyB0b3RhbGx5CiAqIGFic3RyYWN0ZWQgYXdheSBmcm9tIHRoZSBsYXllciBpcyBydW5zIG9uIHRvcCBvZiwgaXQgbWVyZWx5IGVzdGFibGlzaGVzIGEKICogc2VjdXJlIGNoYW5uZWwgYmV0d2VlbiBhIGNsaWVudCIgYW5kIGEgInNlcnZlciIuCiAqCiAqIEEgVExTIGNvbm5lY3Rpb24gY29udGFpbnMgNCBjb25uZWN0aW9uIHN0YXRlczogcGVuZGluZyByZWFkIGFuZCB3cml0ZSwgYW5kCiAqIGN1cnJlbnQgcmVhZCBhbmQgd3JpdGUuCiAqCiAqIEF0IGluaXRpYWxpemF0aW9uLCB0aGUgY3VycmVudCByZWFkIGFuZCB3cml0ZSBzdGF0ZXMgd2lsbCBiZSBudWxsLiBPbmx5IG9uY2UKICogdGhlIHNlY3VyaXR5IHBhcmFtZXRlcnMgaGF2ZSBiZWVuIHNldCBhbmQgdGhlIGtleXMgaGF2ZSBiZWVuIGdlbmVyYXRlZCBjYW4KICogdGhlIHBlbmRpbmcgc3RhdGVzIGJlIGNvbnZlcnRlZCBpbnRvIGN1cnJlbnQgc3RhdGVzLiBDdXJyZW50IHN0YXRlcyB3aWxsIGJlCiAqIHVwZGF0ZWQgZm9yIGVhY2ggcmVjb3JkIHByb2Nlc3NlZC4KICoKICogQSBjdXN0b20gY2VydGlmaWNhdGUgdmVyaWZ5IGNhbGxiYWNrIG1heSBiZSBwcm92aWRlZCB0byBjaGVjayBpbmZvcm1hdGlvbgogKiBsaWtlIHRoZSBjb21tb24gbmFtZSBvbiB0aGUgc2VydmVyJ3MgY2VydGlmaWNhdGUuIEl0IHdpbGwgYmUgY2FsbGVkIGZvcgogKiBldmVyeSBjZXJ0aWZpY2F0ZSBpbiB0aGUgY2hhaW4uIEl0IGhhcyB0aGUgZm9sbG93aW5nIHNpZ25hdHVyZToKICoKICogdmFyaWFibGUgZnVuYyhjLCBjZXJ0cywgaW5kZXgsIHByZVZlcmlmeSkKICogV2hlcmU6CiAqIGMgICAgICAgICBUaGUgVExTIGNvbm5lY3Rpb24KICogdmVyaWZpZWQgIFNldCB0byB0cnVlIGlmIGNlcnRpZmljYXRlIHdhcyB2ZXJpZmllZCwgb3RoZXJ3aXNlIHRoZSBhbGVydAogKiAgICAgICAgICAgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uIGZvciB3aHkgdGhlIGNlcnRpZmljYXRlIGZhaWxlZC4KICogZGVwdGggICAgIFRoZSBjdXJyZW50IGluZGV4IGluIHRoZSBjaGFpbiwgd2hlcmUgMCBpcyB0aGUgc2VydmVyJ3MgY2VydC4KICogY2VydHMgICAgIFRoZSBjZXJ0aWZpY2F0ZSBjaGFpbiwgKk5PVEUqIGlmIHRoZSBzZXJ2ZXIgd2FzIGFub255bW91cyB0aGVuCiAqICAgICAgICAgICB0aGUgY2hhaW4gd2lsbCBiZSBlbXB0eS4KICoKICogVGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzIGFuZCBvbiBmYWlsdXJlIGVpdGhlciB0aGUgYXBwcm9wcmlhdGUKICogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uIG9yIGFuIG9iamVjdCB3aXRoICdhbGVydCcgc2V0IHRvIHRoZSBhcHByb3ByaWF0ZQogKiB0bHMuQWxlcnQuRGVzY3JpcHRpb24gYW5kICdtZXNzYWdlJyBzZXQgdG8gYSBjdXN0b20gZXJyb3IgbWVzc2FnZS4gSWYgdHJ1ZQogKiBpcyBub3QgcmV0dXJuZWQgdGhlbiB0aGUgY29ubmVjdGlvbiB3aWxsIGFib3J0IHVzaW5nLCBpbiBvcmRlciBvZgogKiBhdmFpbGFiaWxpdHksIGZpcnN0IHRoZSByZXR1cm5lZCBhbGVydCBkZXNjcmlwdGlvbiwgc2Vjb25kIHRoZSBwcmVWZXJpZnkKICogYWxlcnQgZGVzY3JpcHRpb24sIGFuZCBsYXN0bHkgdGhlIGRlZmF1bHQgJ2JhZF9jZXJ0aWZpY2F0ZScuCiAqCiAqIFRoZXJlIGFyZSB0aHJlZSBjYWxsYmFja3MgdGhhdCBjYW4gYmUgdXNlZCB0byBtYWtlIHVzZSBvZiBjbGllbnQtc2lkZQogKiBjZXJ0aWZpY2F0ZXMgd2hlcmUgZWFjaCB0YWtlcyB0aGUgVExTIGNvbm5lY3Rpb24gYXMgdGhlIGZpcnN0IHBhcmFtZXRlcjoKICoKICogZ2V0Q2VydGlmaWNhdGUoY29ubiwgaGludCkKICogICBUaGUgc2Vjb25kIHBhcmFtZXRlciBpcyBhIGhpbnQgYXMgdG8gd2hpY2ggY2VydGlmaWNhdGUgc2hvdWxkIGJlCiAqICAgcmV0dXJuZWQuIElmIHRoZSBjb25uZWN0aW9uIGVudGl0eSBpcyBhIGNsaWVudCwgdGhlbiB0aGUgaGludCB3aWxsIGJlCiAqICAgdGhlIENlcnRpZmljYXRlUmVxdWVzdCBtZXNzYWdlIGZyb20gdGhlIHNlcnZlciB0aGF0IGlzIHBhcnQgb2YgdGhlCiAqICAgVExTIHByb3RvY29sLiBJZiB0aGUgY29ubmVjdGlvbiBlbnRpdHkgaXMgYSBzZXJ2ZXIsIHRoZW4gaXQgd2lsbCBiZQogKiAgIHRoZSBzZXJ2ZXJuYW1lIGxpc3QgcHJvdmlkZWQgdmlhIGFuIFNOSSBleHRlbnNpb24gdGhlIENsaWVudEhlbGxvLCBpZgogKiAgIG9uZSB3YXMgcHJvdmlkZWQgKGVtcHR5IGFycmF5IGlmIG5vdCkuIFRoZSBoaW50IGNhbiBiZSBleGFtaW5lZCB0bwogKiAgIGRldGVybWluZSB3aGljaCBjZXJ0aWZpY2F0ZSB0byB1c2UgKGFkdmFuY2VkKS4gTW9zdCBpbXBsZW1lbnRhdGlvbnMKICogICB3aWxsIGp1c3QgcmV0dXJuIGEgY2VydGlmaWNhdGUuIFRoZSByZXR1cm4gdmFsdWUgbXVzdCBiZSBhCiAqICAgUEVNLWZvcm1hdHRlZCBjZXJ0aWZpY2F0ZSBvciBhbiBhcnJheSBvZiBQRU0tZm9ybWF0dGVkIGNlcnRpZmljYXRlcwogKiAgIHRoYXQgY29uc3RpdHV0ZSBhIGNlcnRpZmljYXRlIGNoYWluLCB3aXRoIHRoZSBmaXJzdCBpbiB0aGUgYXJyYXkvY2hhaW4KICogICBiZWluZyB0aGUgY2xpZW50J3MgY2VydGlmaWNhdGUuCiAqIGdldFByaXZhdGVLZXkoY29ubiwgY2VydGlmaWNhdGUpCiAqICAgVGhlIHNlY29uZCBwYXJhbWV0ZXIgaXMgYW4gZm9yZ2UucGtpIFguNTA5IGNlcnRpZmljYXRlIG9iamVjdCB0aGF0CiAqICAgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSByZXF1ZXN0ZWQgcHJpdmF0ZSBrZXkuIFRoZSByZXR1cm4gdmFsdWUgbXVzdAogKiAgIGJlIGEgUEVNLWZvcm1hdHRlZCBwcml2YXRlIGtleS4KICogZ2V0U2lnbmF0dXJlKGNvbm4sIGJ5dGVzLCBjYWxsYmFjaykKICogICBUaGlzIGNhbGxiYWNrIGNhbiBiZSB1c2VkIGluc3RlYWQgb2YgZ2V0UHJpdmF0ZUtleSBpZiB0aGUgcHJpdmF0ZSBrZXkKICogICBpcyBub3QgZGlyZWN0bHkgYWNjZXNzaWJsZSBpbiBqYXZhc2NyaXB0IG9yIHNob3VsZCBub3QgYmUuIEZvcgogKiAgIGluc3RhbmNlLCBhIHNlY3VyZSBleHRlcm5hbCB3ZWIgc2VydmljZSBjb3VsZCBwcm92aWRlIHRoZSBzaWduYXR1cmUKICogICBpbiBleGNoYW5nZSBmb3IgYXBwcm9wcmlhdGUgY3JlZGVudGlhbHMuIFRoZSBzZWNvbmQgcGFyYW1ldGVyIGlzIGEKICogICBzdHJpbmcgb2YgYnl0ZXMgdG8gYmUgc2lnbmVkIHRoYXQgYXJlIHBhcnQgb2YgdGhlIFRMUyBwcm90b2NvbC4gVGhlc2UKICogICBieXRlcyBhcmUgdXNlZCB0byB2ZXJpZnkgdGhhdCB0aGUgcHJpdmF0ZSBrZXkgZm9yIHRoZSBwcmV2aW91c2x5CiAqICAgcHJvdmlkZWQgY2xpZW50LXNpZGUgY2VydGlmaWNhdGUgaXMgYWNjZXNzaWJsZSB0byB0aGUgY2xpZW50LiBUaGUKICogICBjYWxsYmFjayBpcyBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgMiBwYXJhbWV0ZXJzLCB0aGUgVExTIGNvbm5lY3Rpb24KICogICBhbmQgdGhlIFJTQSBlbmNyeXB0ZWQgKHNpZ25lZCkgYnl0ZXMgYXMgYSBzdHJpbmcuIFRoaXMgY2FsbGJhY2sgbXVzdAogKiAgIGJlIGNhbGxlZCBvbmNlIHRoZSBzaWduYXR1cmUgaXMgcmVhZHkuCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIGZvciB0aGlzIGNvbm5lY3Rpb246CiAqICAgc2VydmVyOiB0cnVlIGlmIHRoZSBjb25uZWN0aW9uIGlzIHNlcnZlci1zaWRlLCBmYWxzZSBmb3IgY2xpZW50LgogKiAgIHNlc3Npb25JZDogYSBzZXNzaW9uIElEIHRvIHJldXNlLCBudWxsIGZvciBhIG5ldyBjb25uZWN0aW9uLgogKiAgIGNhU3RvcmU6IGFuIGFycmF5IG9mIGNlcnRpZmljYXRlcyB0byB0cnVzdC4KICogICBzZXNzaW9uQ2FjaGU6IGEgc2Vzc2lvbiBjYWNoZSB0byB1c2UuCiAqICAgY2lwaGVyU3VpdGVzOiBhbiBvcHRpb25hbCBhcnJheSBvZiBjaXBoZXIgc3VpdGVzIHRvIHVzZSwKICogICAgIHNlZSB0bHMuQ2lwaGVyU3VpdGVzLgogKiAgIGNvbm5lY3RlZDogZnVuY3Rpb24oY29ubikgY2FsbGVkIHdoZW4gdGhlIGZpcnN0IGhhbmRzaGFrZSBjb21wbGV0ZXMuCiAqICAgdmlydHVhbEhvc3Q6IHRoZSB2aXJ0dWFsIHNlcnZlciBuYW1lIHRvIHVzZSBpbiBhIFRMUyBTTkkgZXh0ZW5zaW9uLgogKiAgIHZlcmlmeUNsaWVudDogdHJ1ZSB0byByZXF1aXJlIGEgY2xpZW50IGNlcnRpZmljYXRlIGluIHNlcnZlciBtb2RlLAogKiAgICAgJ29wdGlvbmFsJyB0byByZXF1ZXN0IG9uZSwgZmFsc2Ugbm90IHRvIChkZWZhdWx0OiBmYWxzZSkuCiAqICAgdmVyaWZ5OiBhIGhhbmRsZXIgdXNlZCB0byBjdXN0b20gdmVyaWZ5IGNlcnRpZmljYXRlcyBpbiB0aGUgY2hhaW4uCiAqICAgZ2V0Q2VydGlmaWNhdGU6IGFuIG9wdGlvbmFsIGNhbGxiYWNrIHVzZWQgdG8gZ2V0IGEgY2VydGlmaWNhdGUgb3IKICogICAgIGEgY2hhaW4gb2YgY2VydGlmaWNhdGVzIChhcyBhbiBhcnJheSkuCiAqICAgZ2V0UHJpdmF0ZUtleTogYW4gb3B0aW9uYWwgY2FsbGJhY2sgdXNlZCB0byBnZXQgYSBwcml2YXRlIGtleS4KICogICBnZXRTaWduYXR1cmU6IGFuIG9wdGlvbmFsIGNhbGxiYWNrIHVzZWQgdG8gZ2V0IGEgc2lnbmF0dXJlLgogKiAgIHRsc0RhdGFSZWFkeTogZnVuY3Rpb24oY29ubikgY2FsbGVkIHdoZW4gVExTIHByb3RvY29sIGRhdGEgaGFzIGJlZW4KICogICAgIHByZXBhcmVkIGFuZCBpcyByZWFkeSB0byBiZSB1c2VkICh0eXBpY2FsbHkgc2VudCBvdmVyIGEgc29ja2V0CiAqICAgICBjb25uZWN0aW9uIHRvIGl0cyBkZXN0aW5hdGlvbiksIHJlYWQgZnJvbSBjb25uLnRsc0RhdGEgYnVmZmVyLgogKiAgIGRhdGFSZWFkeTogZnVuY3Rpb24oY29ubikgY2FsbGVkIHdoZW4gYXBwbGljYXRpb24gZGF0YSBoYXMKICogICAgIGJlZW4gcGFyc2VkIGZyb20gYSBUTFMgcmVjb3JkIGFuZCBzaG91bGQgYmUgY29uc3VtZWQgYnkgdGhlCiAqICAgICBhcHBsaWNhdGlvbiwgcmVhZCBmcm9tIGNvbm4uZGF0YSBidWZmZXIuCiAqICAgY2xvc2VkOiBmdW5jdGlvbihjb25uKSBjYWxsZWQgd2hlbiB0aGUgY29ubmVjdGlvbiBoYXMgYmVlbiBjbG9zZWQuCiAqICAgZXJyb3I6IGZ1bmN0aW9uKGNvbm4sIGVycm9yKSBjYWxsZWQgd2hlbiB0aGVyZSB3YXMgYW4gZXJyb3IuCiAqICAgZGVmbGF0ZTogZnVuY3Rpb24oaW5CeXRlcykgaWYgcHJvdmlkZWQsIHdpbGwgZGVmbGF0ZSBUTFMgcmVjb3JkcyB1c2luZwogKiAgICAgdGhlIGRlZmxhdGUgYWxnb3JpdGhtIGlmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgaXQuCiAqICAgaW5mbGF0ZTogZnVuY3Rpb24oaW5CeXRlcykgaWYgcHJvdmlkZWQsIHdpbGwgaW5mbGF0ZSBUTFMgcmVjb3JkcyB1c2luZwogKiAgICAgdGhlIGRlZmxhdGUgYWxnb3JpdGhtIGlmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgaXQuCiAqCiAqIEByZXR1cm4gdGhlIG5ldyBUTFMgY29ubmVjdGlvbi4KICovCmZvcmdlLnRscy5jcmVhdGVDb25uZWN0aW9uID0gdGxzLmNyZWF0ZUNvbm5lY3Rpb247Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICd0bHMnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvdGxzJyxbCiAgJ3JlcXVpcmUnLAogICdtb2R1bGUnLAogICcuL2FzbjEnLAogICcuL2htYWMnLAogICcuL21kJywKICAnLi9wZW0nLAogICcuL3BraScsCiAgJy4vcmFuZG9tJywKICAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEEgSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBBRVMgQ2lwaGVyIFN1aXRlcyBmb3IgVExTLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDktMjAxNSBEaWdpdGFsIEJhemFhciwgSW5jLgogKgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCnZhciB0bHMgPSBmb3JnZS50bHM7CgovKioKICogU3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMuCiAqLwp0bHMuQ2lwaGVyU3VpdGVzWydUTFNfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBJ10gPSB7CiAgaWQ6IFsweDAwLDB4MmZdLAogIG5hbWU6ICdUTFNfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBJywKICBpbml0U2VjdXJpdHlQYXJhbWV0ZXJzOiBmdW5jdGlvbihzcCkgewogICAgc3AuYnVsa19jaXBoZXJfYWxnb3JpdGhtID0gdGxzLkJ1bGtDaXBoZXJBbGdvcml0aG0uYWVzOwogICAgc3AuY2lwaGVyX3R5cGUgPSB0bHMuQ2lwaGVyVHlwZS5ibG9jazsKICAgIHNwLmVuY19rZXlfbGVuZ3RoID0gMTY7CiAgICBzcC5ibG9ja19sZW5ndGggPSAxNjsKICAgIHNwLmZpeGVkX2l2X2xlbmd0aCA9IDE2OwogICAgc3AucmVjb3JkX2l2X2xlbmd0aCA9IDE2OwogICAgc3AubWFjX2FsZ29yaXRobSA9IHRscy5NQUNBbGdvcml0aG0uaG1hY19zaGExOwogICAgc3AubWFjX2xlbmd0aCA9IDIwOwogICAgc3AubWFjX2tleV9sZW5ndGggPSAyMDsKICB9LAogIGluaXRDb25uZWN0aW9uU3RhdGU6IGluaXRDb25uZWN0aW9uU3RhdGUKfTsKdGxzLkNpcGhlclN1aXRlc1snVExTX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSddID0gewogIGlkOiBbMHgwMCwweDM1XSwKICBuYW1lOiAnVExTX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQScsCiAgaW5pdFNlY3VyaXR5UGFyYW1ldGVyczogZnVuY3Rpb24oc3ApIHsKICAgIHNwLmJ1bGtfY2lwaGVyX2FsZ29yaXRobSA9IHRscy5CdWxrQ2lwaGVyQWxnb3JpdGhtLmFlczsKICAgIHNwLmNpcGhlcl90eXBlID0gdGxzLkNpcGhlclR5cGUuYmxvY2s7CiAgICBzcC5lbmNfa2V5X2xlbmd0aCA9IDMyOwogICAgc3AuYmxvY2tfbGVuZ3RoID0gMTY7CiAgICBzcC5maXhlZF9pdl9sZW5ndGggPSAxNjsKICAgIHNwLnJlY29yZF9pdl9sZW5ndGggPSAxNjsKICAgIHNwLm1hY19hbGdvcml0aG0gPSB0bHMuTUFDQWxnb3JpdGhtLmhtYWNfc2hhMTsKICAgIHNwLm1hY19sZW5ndGggPSAyMDsKICAgIHNwLm1hY19rZXlfbGVuZ3RoID0gMjA7CiAgfSwKICBpbml0Q29ubmVjdGlvblN0YXRlOiBpbml0Q29ubmVjdGlvblN0YXRlCn07CgpmdW5jdGlvbiBpbml0Q29ubmVjdGlvblN0YXRlKHN0YXRlLCBjLCBzcCkgewogIHZhciBjbGllbnQgPSAoYy5lbnRpdHkgPT09IGZvcmdlLnRscy5Db25uZWN0aW9uRW5kLmNsaWVudCk7CgogIC8vIGNpcGhlciBzZXR1cAogIHN0YXRlLnJlYWQuY2lwaGVyU3RhdGUgPSB7CiAgICBpbml0OiBmYWxzZSwKICAgIGNpcGhlcjogZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKCdBRVMtQ0JDJywgY2xpZW50ID8KICAgICAgc3Aua2V5cy5zZXJ2ZXJfd3JpdGVfa2V5IDogc3Aua2V5cy5jbGllbnRfd3JpdGVfa2V5KSwKICAgIGl2OiBjbGllbnQgPyBzcC5rZXlzLnNlcnZlcl93cml0ZV9JViA6IHNwLmtleXMuY2xpZW50X3dyaXRlX0lWCiAgfTsKICBzdGF0ZS53cml0ZS5jaXBoZXJTdGF0ZSA9IHsKICAgIGluaXQ6IGZhbHNlLAogICAgY2lwaGVyOiBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKCdBRVMtQ0JDJywgY2xpZW50ID8KICAgICAgc3Aua2V5cy5jbGllbnRfd3JpdGVfa2V5IDogc3Aua2V5cy5zZXJ2ZXJfd3JpdGVfa2V5KSwKICAgIGl2OiBjbGllbnQgPyBzcC5rZXlzLmNsaWVudF93cml0ZV9JViA6IHNwLmtleXMuc2VydmVyX3dyaXRlX0lWCiAgfTsKICBzdGF0ZS5yZWFkLmNpcGhlckZ1bmN0aW9uID0gZGVjcnlwdF9hZXNfY2JjX3NoYTE7CiAgc3RhdGUud3JpdGUuY2lwaGVyRnVuY3Rpb24gPSBlbmNyeXB0X2Flc19jYmNfc2hhMTsKCiAgLy8gTUFDIHNldHVwCiAgc3RhdGUucmVhZC5tYWNMZW5ndGggPSBzdGF0ZS53cml0ZS5tYWNMZW5ndGggPSBzcC5tYWNfbGVuZ3RoOwogIHN0YXRlLnJlYWQubWFjRnVuY3Rpb24gPSBzdGF0ZS53cml0ZS5tYWNGdW5jdGlvbiA9IHRscy5obWFjX3NoYTE7Cn0KCi8qKgogKiBFbmNyeXB0cyB0aGUgVExTQ29tcHJlc3NlZCByZWNvcmQgaW50byBhIFRMU0NpcGhlclRleHQgcmVjb3JkIHVzaW5nIEFFUwogKiBpbiBDQkMgbW9kZS4KICoKICogQHBhcmFtIHJlY29yZCB0aGUgVExTQ29tcHJlc3NlZCByZWNvcmQgdG8gZW5jcnlwdC4KICogQHBhcmFtIHMgdGhlIENvbm5lY3Rpb25TdGF0ZSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KZnVuY3Rpb24gZW5jcnlwdF9hZXNfY2JjX3NoYTEocmVjb3JkLCBzKSB7CiAgdmFyIHJ2YWwgPSBmYWxzZTsKCiAgLy8gYXBwZW5kIE1BQyB0byBmcmFnbWVudCwgdXBkYXRlIHNlcXVlbmNlIG51bWJlcgogIHZhciBtYWMgPSBzLm1hY0Z1bmN0aW9uKHMubWFjS2V5LCBzLnNlcXVlbmNlTnVtYmVyLCByZWNvcmQpOwogIHJlY29yZC5mcmFnbWVudC5wdXRCeXRlcyhtYWMpOwogIHMudXBkYXRlU2VxdWVuY2VOdW1iZXIoKTsKCiAgLy8gVExTIDEuMSsgdXNlIGFuIGV4cGxpY2l0IElWIGV2ZXJ5IHRpbWUgdG8gcHJvdGVjdCBhZ2FpbnN0IENCQyBhdHRhY2tzCiAgdmFyIGl2OwogIGlmKHJlY29yZC52ZXJzaW9uLm1pbm9yID09PSB0bHMuVmVyc2lvbnMuVExTXzFfMC5taW5vcikgewogICAgLy8gdXNlIHRoZSBwcmUtZ2VuZXJhdGVkIElWIHdoZW4gaW5pdGlhbGl6aW5nIGZvciBUTFMgMS4wLCBvdGhlcndpc2UgdXNlCiAgICAvLyB0aGUgcmVzaWR1ZSBmcm9tIHRoZSBwcmV2aW91cyBlbmNyeXB0aW9uCiAgICBpdiA9IHMuY2lwaGVyU3RhdGUuaW5pdCA/IG51bGwgOiBzLmNpcGhlclN0YXRlLml2OwogIH0gZWxzZSB7CiAgICBpdiA9IGZvcmdlLnJhbmRvbS5nZXRCeXRlc1N5bmMoMTYpOwogIH0KCiAgcy5jaXBoZXJTdGF0ZS5pbml0ID0gdHJ1ZTsKCiAgLy8gc3RhcnQgY2lwaGVyCiAgdmFyIGNpcGhlciA9IHMuY2lwaGVyU3RhdGUuY2lwaGVyOwogIGNpcGhlci5zdGFydCh7aXY6IGl2fSk7CgogIC8vIFRMUyAxLjErIHdyaXRlIElWIGludG8gb3V0cHV0CiAgaWYocmVjb3JkLnZlcnNpb24ubWlub3IgPj0gdGxzLlZlcnNpb25zLlRMU18xXzEubWlub3IpIHsKICAgIGNpcGhlci5vdXRwdXQucHV0Qnl0ZXMoaXYpOwogIH0KCiAgLy8gZG8gZW5jcnlwdGlvbiAoZGVmYXVsdCBwYWRkaW5nIGlzIGFwcHJvcHJpYXRlKQogIGNpcGhlci51cGRhdGUocmVjb3JkLmZyYWdtZW50KTsKICBpZihjaXBoZXIuZmluaXNoKGVuY3J5cHRfYWVzX2NiY19zaGExX3BhZGRpbmcpKSB7CiAgICAvLyBzZXQgcmVjb3JkIGZyYWdtZW50IHRvIGVuY3J5cHRlZCBvdXRwdXQKICAgIHJlY29yZC5mcmFnbWVudCA9IGNpcGhlci5vdXRwdXQ7CiAgICByZWNvcmQubGVuZ3RoID0gcmVjb3JkLmZyYWdtZW50Lmxlbmd0aCgpOwogICAgcnZhbCA9IHRydWU7CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIEhhbmRsZXMgcGFkZGluZyBmb3IgYWVzX2NiY19zaGExIGluIGVuY3J5cHQgbW9kZS4KICoKICogQHBhcmFtIGJsb2NrU2l6ZSB0aGUgYmxvY2sgc2l6ZS4KICogQHBhcmFtIGlucHV0IHRoZSBpbnB1dCBidWZmZXIuCiAqIEBwYXJhbSBkZWNyeXB0IHRydWUgaW4gZGVjcnlwdCBtb2RlLCBmYWxzZSBpbiBlbmNyeXB0IG1vZGUuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KZnVuY3Rpb24gZW5jcnlwdF9hZXNfY2JjX3NoYTFfcGFkZGluZyhibG9ja1NpemUsIGlucHV0LCBkZWNyeXB0KSB7CiAgLyogVGhlIGVuY3J5cHRlZCBkYXRhIGxlbmd0aCAoVExTQ2lwaGVydGV4dC5sZW5ndGgpIGlzIG9uZSBtb3JlIHRoYW4gdGhlIHN1bQogICBvZiBTZWN1cml0eVBhcmFtZXRlcnMuYmxvY2tfbGVuZ3RoLCBUTFNDb21wcmVzc2VkLmxlbmd0aCwKICAgU2VjdXJpdHlQYXJhbWV0ZXJzLm1hY19sZW5ndGgsIGFuZCBwYWRkaW5nX2xlbmd0aC4KCiAgIFRoZSBwYWRkaW5nIG1heSBiZSBhbnkgbGVuZ3RoIHVwIHRvIDI1NSBieXRlcyBsb25nLCBhcyBsb25nIGFzIGl0IHJlc3VsdHMgaW4KICAgdGhlIFRMU0NpcGhlcnRleHQubGVuZ3RoIGJlaW5nIGFuIGludGVncmFsIG11bHRpcGxlIG9mIHRoZSBibG9jayBsZW5ndGguCiAgIExlbmd0aHMgbG9uZ2VyIHRoYW4gbmVjZXNzYXJ5IG1pZ2h0IGJlIGRlc2lyYWJsZSB0byBmcnVzdHJhdGUgYXR0YWNrcyBvbiBhCiAgIHByb3RvY29sIGJhc2VkIG9uIGFuYWx5c2lzIG9mIHRoZSBsZW5ndGhzIG9mIGV4Y2hhbmdlZCBtZXNzYWdlcy4gRWFjaCB1aW50OAogICBpbiB0aGUgcGFkZGluZyBkYXRhIHZlY3RvciBtdXN0IGJlIGZpbGxlZCB3aXRoIHRoZSBwYWRkaW5nIGxlbmd0aCB2YWx1ZS4KCiAgIFRoZSBwYWRkaW5nIGxlbmd0aCBzaG91bGQgYmUgc3VjaCB0aGF0IHRoZSB0b3RhbCBzaXplIG9mIHRoZQogICBHZW5lcmljQmxvY2tDaXBoZXIgc3RydWN0dXJlIGlzIGEgbXVsdGlwbGUgb2YgdGhlIGNpcGhlcidzIGJsb2NrIGxlbmd0aC4KICAgTGVnYWwgdmFsdWVzIHJhbmdlIGZyb20gemVybyB0byAyNTUsIGluY2x1c2l2ZS4gVGhpcyBsZW5ndGggc3BlY2lmaWVzIHRoZQogICBsZW5ndGggb2YgdGhlIHBhZGRpbmcgZmllbGQgZXhjbHVzaXZlIG9mIHRoZSBwYWRkaW5nX2xlbmd0aCBmaWVsZCBpdHNlbGYuCgogICBUaGlzIGlzIHNsaWdodGx5IGRpZmZlcmVudCBmcm9tIFBLQ1MjNyBiZWNhdXNlIHRoZSBwYWRkaW5nIHZhbHVlIGlzIDEKICAgbGVzcyB0aGFuIHRoZSBhY3R1YWwgbnVtYmVyIG9mIHBhZGRpbmcgYnl0ZXMgaWYgeW91IGluY2x1ZGUgdGhlCiAgIHBhZGRpbmdfbGVuZ3RoIHVpbnQ4IGl0c2VsZiBhcyBhIHBhZGRpbmcgYnl0ZS4gKi8KICBpZighZGVjcnlwdCkgewogICAgLy8gZ2V0IHRoZSBudW1iZXIgb2YgcGFkZGluZyBieXRlcyByZXF1aXJlZCB0byByZWFjaCB0aGUgYmxvY2tTaXplIGFuZAogICAgLy8gc3VidHJhY3QgMSBmb3IgdGhlIHBhZGRpbmcgdmFsdWUgKHRvIG1ha2Ugcm9vbSBmb3IgdGhlIHBhZGRpbmdfbGVuZ3RoCiAgICAvLyB1aW50OCkKICAgIHZhciBwYWRkaW5nID0gYmxvY2tTaXplIC0gKGlucHV0Lmxlbmd0aCgpICUgYmxvY2tTaXplKTsKICAgIGlucHV0LmZpbGxXaXRoQnl0ZShwYWRkaW5nIC0gMSwgcGFkZGluZyk7CiAgfQogIHJldHVybiB0cnVlOwp9CgovKioKICogSGFuZGxlcyBwYWRkaW5nIGZvciBhZXNfY2JjX3NoYTEgaW4gZGVjcnlwdCBtb2RlLgogKgogKiBAcGFyYW0gYmxvY2tTaXplIHRoZSBibG9jayBzaXplLgogKiBAcGFyYW0gb3V0cHV0IHRoZSBvdXRwdXQgYnVmZmVyLgogKiBAcGFyYW0gZGVjcnlwdCB0cnVlIGluIGRlY3J5cHQgbW9kZSwgZmFsc2UgaW4gZW5jcnlwdCBtb2RlLgogKgogKiBAcmV0dXJuIHRydWUgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZS4KICovCmZ1bmN0aW9uIGRlY3J5cHRfYWVzX2NiY19zaGExX3BhZGRpbmcoYmxvY2tTaXplLCBvdXRwdXQsIGRlY3J5cHQpIHsKICB2YXIgcnZhbCA9IHRydWU7CiAgaWYoZGVjcnlwdCkgewogICAgLyogVGhlIGxhc3QgYnl0ZSBpbiB0aGUgb3V0cHV0IHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIHBhZGRpbmcgYnl0ZXMgbm90CiAgICAgIGluY2x1ZGluZyBpdHNlbGYuIEVhY2ggb2YgdGhlIHBhZGRpbmcgYnl0ZXMgaGFzIHRoZSBzYW1lIHZhbHVlIGFzIHRoYXQKICAgICAgbGFzdCBieXRlIChrbm93biBhcyB0aGUgcGFkZGluZ19sZW5ndGgpLiBIZXJlIHdlIGNoZWNrIGFsbCBwYWRkaW5nCiAgICAgIGJ5dGVzIHRvIGVuc3VyZSB0aGV5IGhhdmUgdGhlIHZhbHVlIG9mIHBhZGRpbmdfbGVuZ3RoIGV2ZW4gaWYgb25lIG9mCiAgICAgIHRoZW0gaXMgYmFkIGluIG9yZGVyIHRvIHdhcmQtb2ZmIHRpbWluZyBhdHRhY2tzLiAqLwogICAgdmFyIGxlbiA9IG91dHB1dC5sZW5ndGgoKTsKICAgIHZhciBwYWRkaW5nTGVuZ3RoID0gb3V0cHV0Lmxhc3QoKTsKICAgIGZvcih2YXIgaSA9IGxlbiAtIDEgLSBwYWRkaW5nTGVuZ3RoOyBpIDwgbGVuIC0gMTsgKytpKSB7CiAgICAgIHJ2YWwgPSBydmFsICYmIChvdXRwdXQuYXQoaSkgPT0gcGFkZGluZ0xlbmd0aCk7CiAgICB9CiAgICBpZihydmFsKSB7CiAgICAgIC8vIHRyaW0gb2ZmIHBhZGRpbmcgYnl0ZXMgYW5kIGxhc3QgcGFkZGluZyBsZW5ndGggYnl0ZQogICAgICBvdXRwdXQudHJ1bmNhdGUocGFkZGluZ0xlbmd0aCArIDEpOwogICAgfQogIH0KICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIERlY3J5cHRzIGEgVExTQ2lwaGVyVGV4dCByZWNvcmQgaW50byBhIFRMU0NvbXByZXNzZWQgcmVjb3JkIHVzaW5nCiAqIEFFUyBpbiBDQkMgbW9kZS4KICoKICogQHBhcmFtIHJlY29yZCB0aGUgVExTQ2lwaGVyVGV4dCByZWNvcmQgdG8gZGVjcnlwdC4KICogQHBhcmFtIHMgdGhlIENvbm5lY3Rpb25TdGF0ZSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KdmFyIGNvdW50ID0gMDsKZnVuY3Rpb24gZGVjcnlwdF9hZXNfY2JjX3NoYTEocmVjb3JkLCBzKSB7CiAgdmFyIHJ2YWwgPSBmYWxzZTsKICArK2NvdW50OwoKICB2YXIgaXY7CiAgaWYocmVjb3JkLnZlcnNpb24ubWlub3IgPT09IHRscy5WZXJzaW9ucy5UTFNfMV8wLm1pbm9yKSB7CiAgICAvLyB1c2UgcHJlLWdlbmVyYXRlZCBJViB3aGVuIGluaXRpYWxpemluZyBmb3IgVExTIDEuMCwgb3RoZXJ3aXNlIHVzZSB0aGUKICAgIC8vIHJlc2lkdWUgZnJvbSB0aGUgcHJldmlvdXMgZGVjcnlwdGlvbgogICAgaXYgPSBzLmNpcGhlclN0YXRlLmluaXQgPyBudWxsIDogcy5jaXBoZXJTdGF0ZS5pdjsKICB9IGVsc2UgewogICAgLy8gVExTIDEuMSsgdXNlIGFuIGV4cGxpY2l0IElWIGV2ZXJ5IHRpbWUgdG8gcHJvdGVjdCBhZ2FpbnN0IENCQyBhdHRhY2tzCiAgICAvLyB0aGF0IGlzIGFwcGVuZGVkIHRvIHRoZSByZWNvcmQgZnJhZ21lbnQKICAgIGl2ID0gcmVjb3JkLmZyYWdtZW50LmdldEJ5dGVzKDE2KTsKICB9CgogIHMuY2lwaGVyU3RhdGUuaW5pdCA9IHRydWU7CgogIC8vIHN0YXJ0IGNpcGhlcgogIHZhciBjaXBoZXIgPSBzLmNpcGhlclN0YXRlLmNpcGhlcjsKICBjaXBoZXIuc3RhcnQoe2l2OiBpdn0pOwoKICAvLyBkbyBkZWNyeXB0aW9uCiAgY2lwaGVyLnVwZGF0ZShyZWNvcmQuZnJhZ21lbnQpOwogIHJ2YWwgPSBjaXBoZXIuZmluaXNoKGRlY3J5cHRfYWVzX2NiY19zaGExX3BhZGRpbmcpOwoKICAvLyBldmVuIGlmIGRlY3J5cHRpb24gZmFpbHMsIGtlZXAgZ29pbmcgdG8gbWluaW1pemUgdGltaW5nIGF0dGFja3MKCiAgLy8gZGVjcnlwdGVkIGRhdGE6CiAgLy8gZmlyc3QgKGxlbiAtIDIwKSBieXRlcyA9IGFwcGxpY2F0aW9uIGRhdGEKICAvLyBsYXN0IDIwIGJ5dGVzICAgICAgICAgID0gTUFDCiAgdmFyIG1hY0xlbiA9IHMubWFjTGVuZ3RoOwoKICAvLyBjcmVhdGUgYSByYW5kb20gTUFDIHRvIGNoZWNrIGFnYWluc3Qgc2hvdWxkIHRoZSBtYWMgbGVuZ3RoIGNoZWNrIGZhaWwKICAvLyBOb3RlOiBkbyB0aGlzIHJlZ2FyZGxlc3Mgb2YgdGhlIGZhaWx1cmUgdG8ga2VlcCB0aW1pbmcgY29uc2lzdGVudAogIHZhciBtYWMgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXNTeW5jKG1hY0xlbik7CgogIC8vIGdldCBmcmFnbWVudCBhbmQgbWFjCiAgdmFyIGxlbiA9IGNpcGhlci5vdXRwdXQubGVuZ3RoKCk7CiAgaWYobGVuID49IG1hY0xlbikgewogICAgcmVjb3JkLmZyYWdtZW50ID0gY2lwaGVyLm91dHB1dC5nZXRCeXRlcyhsZW4gLSBtYWNMZW4pOwogICAgbWFjID0gY2lwaGVyLm91dHB1dC5nZXRCeXRlcyhtYWNMZW4pOwogIH0gZWxzZSB7CiAgICAvLyBiYWQgZGF0YSwgYnV0IGdldCBieXRlcyBhbnl3YXkgdG8gdHJ5IHRvIGtlZXAgdGltaW5nIGNvbnNpc3RlbnQKICAgIHJlY29yZC5mcmFnbWVudCA9IGNpcGhlci5vdXRwdXQuZ2V0Qnl0ZXMoKTsKICB9CiAgcmVjb3JkLmZyYWdtZW50ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIocmVjb3JkLmZyYWdtZW50KTsKICByZWNvcmQubGVuZ3RoID0gcmVjb3JkLmZyYWdtZW50Lmxlbmd0aCgpOwoKICAvLyBzZWUgaWYgZGF0YSBpbnRlZ3JpdHkgY2hlY2tzIG91dCwgdXBkYXRlIHNlcXVlbmNlIG51bWJlcgogIHZhciBtYWMyID0gcy5tYWNGdW5jdGlvbihzLm1hY0tleSwgcy5zZXF1ZW5jZU51bWJlciwgcmVjb3JkKTsKICBzLnVwZGF0ZVNlcXVlbmNlTnVtYmVyKCk7CiAgcnZhbCA9IGNvbXBhcmVNYWNzKHMubWFjS2V5LCBtYWMsIG1hYzIpICYmIHJ2YWw7CiAgcmV0dXJuIHJ2YWw7Cn0KCi8qKgogKiBTYWZlbHkgY29tcGFyZSB0d28gTUFDcy4gVGhpcyBmdW5jdGlvbiB3aWxsIGNvbXBhcmUgdHdvIE1BQ3MgaW4gYSB3YXkKICogdGhhdCBwcm90ZWN0cyBhZ2FpbnN0IHRpbWluZyBhdHRhY2tzLgogKgogKiBUT0RPOiBFeHBvc2UgZWxzZXdoZXJlIGFzIGEgdXRpbGl0eSBBUEkuCiAqCiAqIFNlZTogaHR0cHM6Ly93d3cubmNjZ3JvdXAudHJ1c3QvdXMvYWJvdXQtdXMvbmV3c3Jvb20tYW5kLWV2ZW50cy9ibG9nLzIwMTEvZmVicnVhcnkvZG91YmxlLWhtYWMtdmVyaWZpY2F0aW9uLwogKgogKiBAcGFyYW0ga2V5IHRoZSBNQUMga2V5IHRvIHVzZS4KICogQHBhcmFtIG1hYzEgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMuCiAqIEBwYXJhbSBtYWMyIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogKgogKiBAcmV0dXJuIHRydWUgaWYgdGhlIE1BQ3MgYXJlIHRoZSBzYW1lLCBmYWxzZSBpZiBub3QuCiAqLwpmdW5jdGlvbiBjb21wYXJlTWFjcyhrZXksIG1hYzEsIG1hYzIpIHsKICB2YXIgaG1hYyA9IGZvcmdlLmhtYWMuY3JlYXRlKCk7CgogIGhtYWMuc3RhcnQoJ1NIQTEnLCBrZXkpOwogIGhtYWMudXBkYXRlKG1hYzEpOwogIG1hYzEgPSBobWFjLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CgogIGhtYWMuc3RhcnQobnVsbCwgbnVsbCk7CiAgaG1hYy51cGRhdGUobWFjMik7CiAgbWFjMiA9IGhtYWMuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKCiAgcmV0dXJuIG1hYzEgPT09IG1hYzI7Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ2Flc0NpcGhlclN1aXRlcyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9hZXNDaXBoZXJTdWl0ZXMnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9hZXMnLCAnLi90bHMnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogRGVidWdnaW5nIHN1cHBvcnQgZm9yIHdlYiBhcHBsaWNhdGlvbnMuCiAqCiAqIEBhdXRob3IgRGF2aWQgSS4gTGVobiA8ZGxlaG5AZGlnaXRhbGJhemFhci5jb20+CiAqCiAqIENvcHlyaWdodCAyMDA4LTIwMTMgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovKiBERUJVRyBBUEkgKi8KZm9yZ2UuZGVidWcgPSBmb3JnZS5kZWJ1ZyB8fCB7fTsKCi8vIFByaXZhdGUgc3RvcmFnZSBmb3IgZGVidWdnaW5nLgovLyBVc2VmdWwgdG8gZXhwb3NlIGRhdGEgdGhhdCBpcyBvdGhlcndpc2UgdW52aWV3YWJsZSBiZWhpbmQgY2xvc3VyZXMuCi8vIE5PVEU6IHJlbWVtYmVyIHRoYXQgdGhpcyBjYW4gaG9sZCByZWZlcmVuY2VzIHRvIGRhdGEgYW5kIGNhdXNlIGxlYWtzIQovLyBmb3JtYXQgaXMgImZvcmdlLl9kZWJ1Zy48bW9kdWxlbmFtZT4uPGRhdGFuYW1lPiA9IGRhdGEiCi8vIEV4YW1wbGU6Ci8vIChmdW5jdGlvbigpIHsKLy8gICB2YXIgY2F0ID0gJ2ZvcmdlLnRlc3QuVGVzdCc7IC8vIGRlYnVnZ2luZyBjYXRlZ29yeQovLyAgIHZhciBzU3RhdGUgPSB7Li4ufTsgLy8gbG9jYWwgc3RhdGUKLy8gICBmb3JnZS5kZWJ1Zy5zZXQoY2F0LCAnc1N0YXRlJywgc1N0YXRlKTsKLy8gfSkoKTsKZm9yZ2UuZGVidWcuc3RvcmFnZSA9IHt9OwoKLyoqCiAqIEdldHMgZGVidWcgZGF0YS4gT21pdCBuYW1lIGZvciBhbGwgY2F0IGRhdGEgIE9taXQgbmFtZSBhbmQgY2F0IGZvcgogKiBhbGwgZGF0YS4KICoKICogQHBhcmFtIGNhdCBuYW1lIG9mIGRlYnVnZ2luZyBjYXRlZ29yeS4KICogQHBhcmFtIG5hbWUgbmFtZSBvZiBkYXRhIHRvIGdldCAob3B0aW9uYWwpLgogKiBAcmV0dXJuIG9iamVjdCB3aXRoIHJlcXVlc3RlZCBkZWJ1ZyBkYXRhIG9yIHVuZGVmaW5lZC4KICovCmZvcmdlLmRlYnVnLmdldCA9IGZ1bmN0aW9uKGNhdCwgbmFtZSkgewogIHZhciBydmFsOwogIGlmKHR5cGVvZihjYXQpID09PSAndW5kZWZpbmVkJykgewogICAgcnZhbCA9IGZvcmdlLmRlYnVnLnN0b3JhZ2U7CiAgfSBlbHNlIGlmKGNhdCBpbiBmb3JnZS5kZWJ1Zy5zdG9yYWdlKSB7CiAgICBpZih0eXBlb2YobmFtZSkgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIHJ2YWwgPSBmb3JnZS5kZWJ1Zy5zdG9yYWdlW2NhdF07CiAgICB9IGVsc2UgewogICAgICBydmFsID0gZm9yZ2UuZGVidWcuc3RvcmFnZVtjYXRdW25hbWVdOwogICAgfQogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBTZXRzIGRlYnVnIGRhdGEuCiAqCiAqIEBwYXJhbSBjYXQgbmFtZSBvZiBkZWJ1Z2dpbmcgY2F0ZWdvcnkuCiAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgZGF0YSB0byBzZXQuCiAqIEBwYXJhbSBkYXRhIGRhdGEgdG8gc2V0LgogKi8KZm9yZ2UuZGVidWcuc2V0ID0gZnVuY3Rpb24oY2F0LCBuYW1lLCBkYXRhKSB7CiAgaWYoIShjYXQgaW4gZm9yZ2UuZGVidWcuc3RvcmFnZSkpIHsKICAgIGZvcmdlLmRlYnVnLnN0b3JhZ2VbY2F0XSA9IHt9OwogIH0KICBmb3JnZS5kZWJ1Zy5zdG9yYWdlW2NhdF1bbmFtZV0gPSBkYXRhOwp9OwoKLyoqCiAqIENsZWFycyBkZWJ1ZyBkYXRhLiBPbWl0IG5hbWUgZm9yIGFsbCBjYXQgZGF0YS4gT21pdCBuYW1lIGFuZCBjYXQgZm9yCiAqIGFsbCBkYXRhLgogKgogKiBAcGFyYW0gY2F0IG5hbWUgb2YgZGVidWdnaW5nIGNhdGVnb3J5LgogKiBAcGFyYW0gbmFtZSBuYW1lIG9mIGRhdGEgdG8gY2xlYXIgb3Igb21pdCB0byBjbGVhciBlbnRpcmUgY2F0ZWdvcnkuCiAqLwpmb3JnZS5kZWJ1Zy5jbGVhciA9IGZ1bmN0aW9uKGNhdCwgbmFtZSkgewogIGlmKHR5cGVvZihjYXQpID09PSAndW5kZWZpbmVkJykgewogICAgZm9yZ2UuZGVidWcuc3RvcmFnZSA9IHt9OwogIH0gZWxzZSBpZihjYXQgaW4gZm9yZ2UuZGVidWcuc3RvcmFnZSkgewogICAgaWYodHlwZW9mKG5hbWUpID09PSAndW5kZWZpbmVkJykgewogICAgICBkZWxldGUgZm9yZ2UuZGVidWcuc3RvcmFnZVtjYXRdOwogICAgfSBlbHNlIHsKICAgICAgZGVsZXRlIGZvcmdlLmRlYnVnLnN0b3JhZ2VbY2F0XVtuYW1lXTsKICAgIH0KICB9Cn07Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdkZWJ1Zyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9kZWJ1ZycsWydyZXF1aXJlJywgJ21vZHVsZSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIFJTQS1LRU0uCiAqCiAqIEBhdXRob3IgTGF1dGFybyBDb3p6YW5pIFJvZHJpZ3VlegogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQgTGF1dGFybyBDb3p6YW5pIDxsYXV0YXJvLmNvenphbmlAc2N5dGwuY29tPgogKiBDb3B5cmlnaHQgKGMpIDIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7Cgpmb3JnZS5rZW0gPSBmb3JnZS5rZW0gfHwge307Cgp2YXIgQmlnSW50ZWdlciA9IGZvcmdlLmpzYm4uQmlnSW50ZWdlcjsKCi8qKgogKiBUaGUgQVBJIGZvciB0aGUgUlNBIEtleSBFbmNhcHN1bGF0aW9uIE1lY2hhbmlzbSAoUlNBLUtFTSkgZnJvbSBJU08gMTgwMzMtMi4KICovCmZvcmdlLmtlbS5yc2EgPSB7fTsKCi8qKgogKiBDcmVhdGVzIGFuIFJTQSBLRU0gQVBJIG9iamVjdCBmb3IgZ2VuZXJhdGluZyBhIHNlY3JldCBhc3ltbWV0cmljIGtleS4KICoKICogVGhlIHN5bW1ldHJpYyBrZXkgbWF5IGJlIGdlbmVyYXRlZCB2aWEgYSBjYWxsIHRvICdlbmNyeXB0Jywgd2hpY2ggd2lsbAogKiBwcm9kdWNlIGEgY2lwaGVydGV4dCB0byBiZSB0cmFuc21pdHRlZCB0byB0aGUgcmVjaXBpZW50IGFuZCBhIGtleSB0byBiZQogKiBrZXB0IHNlY3JldC4gVGhlIGNpcGhlcnRleHQgaXMgYSBwYXJhbWV0ZXIgdG8gYmUgcGFzc2VkIHRvICdkZWNyeXB0JyB3aGljaAogKiB3aWxsIHByb2R1Y2UgdGhlIHNhbWUgc2VjcmV0IGtleSBmb3IgdGhlIHJlY2lwaWVudCB0byB1c2UgdG8gZGVjcnlwdCBhCiAqIG1lc3NhZ2UgdGhhdCB3YXMgZW5jcnlwdGVkIHdpdGggdGhlIHNlY3JldCBrZXkuCiAqCiAqIEBwYXJhbSBrZGYgdGhlIEtERiBBUEkgdG8gdXNlIChlZzogbmV3IGZvcmdlLmtlbS5rZGYxKCkpLgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIFtwcm5nXSBhIGN1c3RvbSBjcnlwdG8tc2VjdXJlIHBzZXVkby1yYW5kb20gbnVtYmVyIGdlbmVyYXRvciB0byB1c2UsCiAqICAgICAgICAgICAgdGhhdCBtdXN0IGRlZmluZSAiZ2V0Qnl0ZXNTeW5jIi4KICovCmZvcmdlLmtlbS5yc2EuY3JlYXRlID0gZnVuY3Rpb24oa2RmLCBvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdmFyIHBybmcgPSBvcHRpb25zLnBybmcgfHwgZm9yZ2UucmFuZG9tOwoKICB2YXIga2VtID0ge307CgogIC8qKgogICAqIEdlbmVyYXRlcyBhIHNlY3JldCBrZXkgYW5kIGl0cyBlbmNhcHN1bGF0aW9uLgogICAqCiAgICogQHBhcmFtIHB1YmxpY0tleSB0aGUgUlNBIHB1YmxpYyBrZXkgdG8gZW5jcnlwdCB3aXRoLgogICAqIEBwYXJhbSBrZXlMZW5ndGggdGhlIGxlbmd0aCwgaW4gYnl0ZXMsIG9mIHRoZSBzZWNyZXQga2V5IHRvIGdlbmVyYXRlLgogICAqCiAgICogQHJldHVybiBhbiBvYmplY3Qgd2l0aDoKICAgKiAgIGVuY2Fwc3VsYXRpb246IHRoZSBjaXBoZXJ0ZXh0IGZvciBnZW5lcmF0aW5nIHRoZSBzZWNyZXQga2V5LCBhcyBhCiAgICogICAgIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBieXRlcy4KICAgKiAgIGtleTogdGhlIHNlY3JldCBrZXkgdG8gdXNlIGZvciBlbmNyeXB0aW5nIGEgbWVzc2FnZS4KICAgKi8KICBrZW0uZW5jcnlwdCA9IGZ1bmN0aW9uKHB1YmxpY0tleSwga2V5TGVuZ3RoKSB7CiAgICAvLyBnZW5lcmF0ZSBhIHJhbmRvbSByIHdoZXJlIDEgPiByID4gbgogICAgdmFyIGJ5dGVMZW5ndGggPSBNYXRoLmNlaWwocHVibGljS2V5Lm4uYml0TGVuZ3RoKCkgLyA4KTsKICAgIHZhciByOwogICAgZG8gewogICAgICByID0gbmV3IEJpZ0ludGVnZXIoCiAgICAgICAgZm9yZ2UudXRpbC5ieXRlc1RvSGV4KHBybmcuZ2V0Qnl0ZXNTeW5jKGJ5dGVMZW5ndGgpKSwKICAgICAgICAxNikubW9kKHB1YmxpY0tleS5uKTsKICAgIH0gd2hpbGUoci5lcXVhbHMoQmlnSW50ZWdlci5aRVJPKSk7CgogICAgLy8gcHJlcGVuZCByIHdpdGggemVyb3MKICAgIHIgPSBmb3JnZS51dGlsLmhleFRvQnl0ZXMoci50b1N0cmluZygxNikpOwogICAgdmFyIHplcm9zID0gYnl0ZUxlbmd0aCAtIHIubGVuZ3RoOwogICAgaWYoemVyb3MgPiAwKSB7CiAgICAgIHIgPSBmb3JnZS51dGlsLmZpbGxTdHJpbmcoU3RyaW5nLmZyb21DaGFyQ29kZSgwKSwgemVyb3MpICsgcjsKICAgIH0KCiAgICAvLyBlbmNyeXB0IHRoZSByYW5kb20KICAgIHZhciBlbmNhcHN1bGF0aW9uID0gcHVibGljS2V5LmVuY3J5cHQociwgJ05PTkUnKTsKCiAgICAvLyBnZW5lcmF0ZSB0aGUgc2VjcmV0IGtleQogICAgdmFyIGtleSA9IGtkZi5nZW5lcmF0ZShyLCBrZXlMZW5ndGgpOwoKICAgIHJldHVybiB7ZW5jYXBzdWxhdGlvbjogZW5jYXBzdWxhdGlvbiwga2V5OiBrZXl9OwogIH07CgogIC8qKgogICAqIERlY3J5cHRzIGFuIGVuY2Fwc3VsYXRlZCBzZWNyZXQga2V5LgogICAqCiAgICogQHBhcmFtIHByaXZhdGVLZXkgdGhlIFJTQSBwcml2YXRlIGtleSB0byBkZWNyeXB0IHdpdGguCiAgICogQHBhcmFtIGVuY2Fwc3VsYXRpb24gdGhlIGNpcGhlcnRleHQgZm9yIGdlbmVyYXRpbmcgdGhlIHNlY3JldCBrZXksIGFzCiAgICogICAgICAgICAgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMuCiAgICogQHBhcmFtIGtleUxlbmd0aCB0aGUgbGVuZ3RoLCBpbiBieXRlcywgb2YgdGhlIHNlY3JldCBrZXkgdG8gZ2VuZXJhdGUuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBzZWNyZXQga2V5IGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogICAqLwogIGtlbS5kZWNyeXB0ID0gZnVuY3Rpb24ocHJpdmF0ZUtleSwgZW5jYXBzdWxhdGlvbiwga2V5TGVuZ3RoKSB7CiAgICAvLyBkZWNyeXB0IHRoZSBlbmNhcHN1bGF0aW9uIGFuZCBnZW5lcmF0ZSB0aGUgc2VjcmV0IGtleQogICAgdmFyIHIgPSBwcml2YXRlS2V5LmRlY3J5cHQoZW5jYXBzdWxhdGlvbiwgJ05PTkUnKTsKICAgIHJldHVybiBrZGYuZ2VuZXJhdGUociwga2V5TGVuZ3RoKTsKICB9OwoKICByZXR1cm4ga2VtOwp9OwoKLy8gVE9ETzogYWRkIGZvcmdlLmtlbS5rZGYuY3JlYXRlKCdLREYxJywge21kOiAuLi4sIC4uLn0pIEFQST8KCi8qKgogKiBDcmVhdGVzIGEga2V5IGRlcml2YXRpb24gQVBJIG9iamVjdCB0aGF0IGltcGxlbWVudHMgS0RGMSBwZXIgSVNPIDE4MDMzLTIuCiAqCiAqIEBwYXJhbSBtZCB0aGUgaGFzaCBBUEkgdG8gdXNlLgogKiBAcGFyYW0gW2RpZ2VzdExlbmd0aF0gYW4gb3B0aW9uYWwgZGlnZXN0IGxlbmd0aCB0aGF0IG11c3QgYmUgcG9zaXRpdmUgYW5kCiAqICAgICAgICAgIGxlc3MgdGhhbiBvciBlcXVhbCB0byBtZC5kaWdlc3RMZW5ndGguCiAqCiAqIEByZXR1cm4gYSBLREYxIEFQSSBvYmplY3QuCiAqLwpmb3JnZS5rZW0ua2RmMSA9IGZ1bmN0aW9uKG1kLCBkaWdlc3RMZW5ndGgpIHsKICBfY3JlYXRlS0RGKHRoaXMsIG1kLCAwLCBkaWdlc3RMZW5ndGggfHwgbWQuZGlnZXN0TGVuZ3RoKTsKfTsKCi8qKgogKiBDcmVhdGVzIGEga2V5IGRlcml2YXRpb24gQVBJIG9iamVjdCB0aGF0IGltcGxlbWVudHMgS0RGMiBwZXIgSVNPIDE4MDMzLTIuCiAqCiAqIEBwYXJhbSBtZCB0aGUgaGFzaCBBUEkgdG8gdXNlLgogKiBAcGFyYW0gW2RpZ2VzdExlbmd0aF0gYW4gb3B0aW9uYWwgZGlnZXN0IGxlbmd0aCB0aGF0IG11c3QgYmUgcG9zaXRpdmUgYW5kCiAqICAgICAgICAgIGxlc3MgdGhhbiBvciBlcXVhbCB0byBtZC5kaWdlc3RMZW5ndGguCiAqCiAqIEByZXR1cm4gYSBLREYyIEFQSSBvYmplY3QuCiAqLwpmb3JnZS5rZW0ua2RmMiA9IGZ1bmN0aW9uKG1kLCBkaWdlc3RMZW5ndGgpIHsKICBfY3JlYXRlS0RGKHRoaXMsIG1kLCAxLCBkaWdlc3RMZW5ndGggfHwgbWQuZGlnZXN0TGVuZ3RoKTsKfTsKCi8qKgogKiBDcmVhdGVzIGEgS0RGMSBvciBLREYyIEFQSSBvYmplY3QuCiAqCiAqIEBwYXJhbSBtZCB0aGUgaGFzaCBBUEkgdG8gdXNlLgogKiBAcGFyYW0gY291bnRlclN0YXJ0IHRoZSBzdGFydGluZyBpbmRleCBmb3IgdGhlIGNvdW50ZXIuCiAqIEBwYXJhbSBkaWdlc3RMZW5ndGggdGhlIGRpZ2VzdCBsZW5ndGggdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSBLREYgQVBJIG9iamVjdC4KICovCmZ1bmN0aW9uIF9jcmVhdGVLREYoa2RmLCBtZCwgY291bnRlclN0YXJ0LCBkaWdlc3RMZW5ndGgpIHsKICAvKioKICAgKiBHZW5lcmF0ZSBhIGtleSBvZiB0aGUgc3BlY2lmaWVkIGxlbmd0aC4KICAgKgogICAqIEBwYXJhbSB4IHRoZSBiaW5hcnktZW5jb2RlZCBieXRlIHN0cmluZyB0byBnZW5lcmF0ZSBhIGtleSBmcm9tLgogICAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyB0byBnZW5lcmF0ZSAodGhlIHNpemUgb2YgdGhlIGtleSkuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBrZXkgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcuCiAgICovCiAga2RmLmdlbmVyYXRlID0gZnVuY3Rpb24oeCwgbGVuZ3RoKSB7CiAgICB2YXIga2V5ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwoKICAgIC8vIHJ1biBjb3VudGVyIGZyb20gY291bnRlclN0YXJ0IHRvIGNlaWwobGVuZ3RoIC8gSGFzaC5sZW4pCiAgICB2YXIgayA9IE1hdGguY2VpbChsZW5ndGggLyBkaWdlc3RMZW5ndGgpICsgY291bnRlclN0YXJ0OwoKICAgIHZhciBjID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogICAgZm9yKHZhciBpID0gY291bnRlclN0YXJ0OyBpIDwgazsgKytpKSB7CiAgICAgIC8vIEkyT1NQKGksIDQpOiBjb252ZXJ0IGNvdW50ZXIgdG8gYW4gb2N0ZXQgc3RyaW5nIG9mIDQgb2N0ZXRzCiAgICAgIGMucHV0SW50MzIoaSk7CgogICAgICAvLyBkaWdlc3QgJ3gnIGFuZCB0aGUgY291bnRlciBhbmQgYWRkIHRoZSByZXN1bHQgdG8gdGhlIGtleQogICAgICBtZC5zdGFydCgpOwogICAgICBtZC51cGRhdGUoeCArIGMuZ2V0Qnl0ZXMoKSk7CiAgICAgIHZhciBoYXNoID0gbWQuZGlnZXN0KCk7CiAgICAgIGtleS5wdXRCeXRlcyhoYXNoLmdldEJ5dGVzKGRpZ2VzdExlbmd0aCkpOwogICAgfQoKICAgIC8vIHRydW5jYXRlIHRvIHRoZSBjb3JyZWN0IGtleSBsZW5ndGgKICAgIGtleS50cnVuY2F0ZShrZXkubGVuZ3RoKCkgLSBsZW5ndGgpOwogICAgcmV0dXJuIGtleS5nZXRCeXRlcygpOwogIH07Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ2tlbSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9rZW0nLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJywnLi9yYW5kb20nLCcuL2pzYm4nXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogQ3Jvc3MtYnJvd3NlciBzdXBwb3J0IGZvciBsb2dnaW5nIGluIGEgd2ViIGFwcGxpY2F0aW9uLgogKgogKiBAYXV0aG9yIERhdmlkIEkuIExlaG4gPGRsZWhuQGRpZ2l0YWxiYXphYXIuY29tPgogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDgtMjAxMyBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8qIExPRyBBUEkgKi8KZm9yZ2UubG9nID0gZm9yZ2UubG9nIHx8IHt9OwoKLyoqCiAqIEFwcGxpY2F0aW9uIGxvZ2dpbmcgc3lzdGVtLgogKgogKiBFYWNoIGxvZ2dlciBsZXZlbCBhdmFpbGFibGUgYXMgaXQncyBvd24gZnVuY3Rpb24gb2YgdGhlIGZvcm06CiAqICAgZm9yZ2UubG9nLmxldmVsKGNhdGVnb3J5LCBhcmdzLi4uKQogKiBUaGUgY2F0ZWdvcnkgaXMgYW4gYXJiaXRyYXJ5IHN0cmluZywgYW5kIHRoZSBhcmdzIGFyZSB0aGUgc2FtZSBhcwogKiBGaXJlYnVnJ3MgY29uc29sZS5sb2cgQVBJLiBCeSBkZWZhdWx0IHRoZSBjYWxsIHdpbGwgYmUgb3V0cHV0IGFzOgogKiAgICdMRVZFTCBbY2F0ZWdvcnldIDxhcmdzWzBdPiwgYXJnc1sxXSwgLi4uJwogKiBUaGlzIGVuYWJsZXMgcHJvcGVyICUgZm9ybWF0dGluZyB2aWEgdGhlIGZpcnN0IGFyZ3VtZW50LgogKiBFYWNoIGNhdGVnb3J5IGlzIGVuYWJsZWQgYnkgZGVmYXVsdCBidXQgY2FuIGJlIGVuYWJsZWQgb3IgZGlzYWJsZWQgd2l0aAogKiB0aGUgc2V0Q2F0ZWdvcnlFbmFibGVkKCkgZnVuY3Rpb24uCiAqLwovLyBsaXN0IG9mIGtub3duIGxldmVscwpmb3JnZS5sb2cubGV2ZWxzID0gWwogICdub25lJywgJ2Vycm9yJywgJ3dhcm5pbmcnLCAnaW5mbycsICdkZWJ1ZycsICd2ZXJib3NlJywgJ21heCddOwovLyBpbmZvIG9uIHRoZSBsZXZlbHMgaW5kZXhlZCBieSBuYW1lOgovLyAgIGluZGV4OiBsZXZlbCBpbmRleAovLyAgIG5hbWU6IHVwcGVyY2FzZWQgZGlzcGxheSBuYW1lCnZhciBzTGV2ZWxJbmZvID0ge307Ci8vIGxpc3Qgb2YgbG9nZ2Vycwp2YXIgc0xvZ2dlcnMgPSBbXTsKLyoqCiAqIFN0YW5kYXJkIGNvbnNvbGUgbG9nZ2VyLiBJZiBubyBjb25zb2xlIHN1cHBvcnQgaXMgZW5hYmxlZCB0aGlzIHdpbGwKICogcmVtYWluIG51bGwuIENoZWNrIGJlZm9yZSB1c2luZy4KICovCnZhciBzQ29uc29sZUxvZ2dlciA9IG51bGw7CgovLyBsb2dnZXIgZmxhZ3MKLyoqCiAqIExvY2sgdGhlIGxldmVsIGF0IHRoZSBjdXJyZW50IHZhbHVlLiBVc2VkIGluIGNhc2VzIHdoZXJlIHVzZXIgY29uZmlnIG1heQogKiBzZXQgdGhlIGxldmVsIHN1Y2ggdGhhdCBvbmx5IGNyaXRpY2FsIG1lc3NhZ2VzIGFyZSBzZWVuIGJ1dCBtb3JlIHZlcmJvc2UKICogbWVzc2FnZXMgYXJlIG5lZWRlZCBmb3IgZGVidWdnaW5nIG9yIG90aGVyIHB1cnBvc2VzLgogKi8KZm9yZ2UubG9nLkxFVkVMX0xPQ0tFRCA9ICgxIDw8IDEpOwovKioKICogQWx3YXlzIGNhbGwgbG9nIGZ1bmN0aW9uLiBCeSBkZWZhdWx0LCB0aGUgbG9nZ2luZyBzeXN0ZW0gd2lsbCBjaGVjayB0aGUKICogbWVzc2FnZSBsZXZlbCBhZ2FpbnN0IGxvZ2dlci5sZXZlbCBiZWZvcmUgY2FsbGluZyB0aGUgbG9nIGZ1bmN0aW9uLiBUaGlzCiAqIGZsYWcgYWxsb3dzIHRoZSBmdW5jdGlvbiB0byBkbyBpdHMgb3duIGNoZWNrLgogKi8KZm9yZ2UubG9nLk5PX0xFVkVMX0NIRUNLID0gKDEgPDwgMik7Ci8qKgogKiBQZXJmb3JtIG1lc3NhZ2UgaW50ZXJwb2xhdGlvbiB3aXRoIHRoZSBwYXNzZWQgYXJndW1lbnRzLiAiJSIgc3R5bGUKICogZmllbGRzIGluIGxvZyBtZXNzYWdlcyB3aWxsIGJlIHJlcGxhY2VkIGJ5IGFyZ3VtZW50cyBhcyBuZWVkZWQuIFNvbWUKICogbG9nZ2Vycywgc3VjaCBhcyBGaXJlYnVnLCBtYXkgZG8gdGhpcyBhdXRvbWF0aWNhbGx5LiBUaGUgb3JpZ2luYWwgbG9nCiAqIG1lc3NhZ2Ugd2lsbCBiZSBhdmFpbGFibGUgYXMgJ21lc3NhZ2UnIGFuZCB0aGUgaW50ZXJwb2xhdGVkIHZlcnNpb24gd2lsbAogKiBiZSBhdmFpbGFibGUgYXMgJ2Z1bGxNZXNzYWdlJy4KICovCmZvcmdlLmxvZy5JTlRFUlBPTEFURSA9ICgxIDw8IDMpOwoKLy8gc2V0dXAgZWFjaCBsb2cgbGV2ZWwKZm9yKHZhciBpID0gMDsgaSA8IGZvcmdlLmxvZy5sZXZlbHMubGVuZ3RoOyArK2kpIHsKICB2YXIgbGV2ZWwgPSBmb3JnZS5sb2cubGV2ZWxzW2ldOwogIHNMZXZlbEluZm9bbGV2ZWxdID0gewogICAgaW5kZXg6IGksCiAgICBuYW1lOiBsZXZlbC50b1VwcGVyQ2FzZSgpCiAgfTsKfQoKLyoqCiAqIE1lc3NhZ2UgbG9nZ2VyLiBXaWxsIGRpc3BhdGNoIGEgbWVzc2FnZSB0byByZWdpc3RlcmVkIGxvZ2dlcnMgYXMgbmVlZGVkLgogKgogKiBAcGFyYW0gbWVzc2FnZSBtZXNzYWdlIG9iamVjdAogKi8KZm9yZ2UubG9nLmxvZ01lc3NhZ2UgPSBmdW5jdGlvbihtZXNzYWdlKSB7CiAgdmFyIG1lc3NhZ2VMZXZlbEluZGV4ID0gc0xldmVsSW5mb1ttZXNzYWdlLmxldmVsXS5pbmRleDsKICBmb3IodmFyIGkgPSAwOyBpIDwgc0xvZ2dlcnMubGVuZ3RoOyArK2kpIHsKICAgIHZhciBsb2dnZXIgPSBzTG9nZ2Vyc1tpXTsKICAgIGlmKGxvZ2dlci5mbGFncyAmIGZvcmdlLmxvZy5OT19MRVZFTF9DSEVDSykgewogICAgICBsb2dnZXIuZihtZXNzYWdlKTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIGdldCBsb2dnZXIgbGV2ZWwKICAgICAgdmFyIGxvZ2dlckxldmVsSW5kZXggPSBzTGV2ZWxJbmZvW2xvZ2dlci5sZXZlbF0uaW5kZXg7CiAgICAgIC8vIGNoZWNrIGxldmVsCiAgICAgIGlmKG1lc3NhZ2VMZXZlbEluZGV4IDw9IGxvZ2dlckxldmVsSW5kZXgpIHsKICAgICAgICAvLyBtZXNzYWdlIGNyaXRpY2FsIGVub3VnaCwgY2FsbCBsb2dnZXIKICAgICAgICBsb2dnZXIuZihsb2dnZXIsIG1lc3NhZ2UpOwogICAgICB9CiAgICB9CiAgfQp9OwoKLyoqCiAqIFNldHMgdGhlICdzdGFuZGFyZCcga2V5IG9uIGEgbWVzc2FnZSBvYmplY3QgdG86CiAqICJMRVZFTCBbY2F0ZWdvcnldICIgKyBtZXNzYWdlCiAqCiAqIEBwYXJhbSBtZXNzYWdlIGEgbWVzc2FnZSBsb2cgb2JqZWN0CiAqLwpmb3JnZS5sb2cucHJlcGFyZVN0YW5kYXJkID0gZnVuY3Rpb24obWVzc2FnZSkgewogIGlmKCEoJ3N0YW5kYXJkJyBpbiBtZXNzYWdlKSkgewogICAgbWVzc2FnZS5zdGFuZGFyZCA9CiAgICAgIHNMZXZlbEluZm9bbWVzc2FnZS5sZXZlbF0ubmFtZSArCiAgICAgIC8vJyAnICsgK21lc3NhZ2UudGltZXN0YW1wICsKICAgICAgJyBbJyArIG1lc3NhZ2UuY2F0ZWdvcnkgKyAnXSAnICsKICAgICAgbWVzc2FnZS5tZXNzYWdlOwogIH0KfTsKCi8qKgogKiBTZXRzIHRoZSAnZnVsbCcga2V5IG9uIGEgbWVzc2FnZSBvYmplY3QgdG8gdGhlIG9yaWdpbmFsIG1lc3NhZ2UKICogaW50ZXJwb2xhdGVkIHZpYSAlIGZvcm1hdHRpbmcgd2l0aCB0aGUgbWVzc2FnZSBhcmd1bWVudHMuCiAqCiAqIEBwYXJhbSBtZXNzYWdlIGEgbWVzc2FnZSBsb2cgb2JqZWN0LgogKi8KZm9yZ2UubG9nLnByZXBhcmVGdWxsID0gZnVuY3Rpb24obWVzc2FnZSkgewogIGlmKCEoJ2Z1bGwnIGluIG1lc3NhZ2UpKSB7CiAgICAvLyBjb3B5IGFyZ3MgYW5kIGluc2VydCBtZXNzYWdlIGF0IHRoZSBmcm9udAogICAgdmFyIGFyZ3MgPSBbbWVzc2FnZS5tZXNzYWdlXTsKICAgIGFyZ3MgPSBhcmdzLmNvbmNhdChbXSB8fCBtZXNzYWdlWydhcmd1bWVudHMnXSk7CiAgICAvLyBmb3JtYXQgdGhlIG1lc3NhZ2UKICAgIG1lc3NhZ2UuZnVsbCA9IGZvcmdlLnV0aWwuZm9ybWF0LmFwcGx5KHRoaXMsIGFyZ3MpOwogIH0KfTsKCi8qKgogKiBBcHBsaWVzIGJvdGggcHJlcGFyc2VTdGFuZGFyZCgpIGFuZCBwcmVwYXJlRnVsbCgpIHRvIGEgbWVzc2FnZSBvYmplY3QgYW5kCiAqIHN0b3JlIHJlc3VsdCBpbiAnc3RhbmRhcmRGdWxsJy4KICoKICogQHBhcmFtIG1lc3NhZ2UgYSBtZXNzYWdlIGxvZyBvYmplY3QuCiAqLwpmb3JnZS5sb2cucHJlcGFyZVN0YW5kYXJkRnVsbCA9IGZ1bmN0aW9uKG1lc3NhZ2UpIHsKICBpZighKCdzdGFuZGFyZEZ1bGwnIGluIG1lc3NhZ2UpKSB7CiAgICAvLyBGSVhNRSBpbXBsZW1lbnQgJ3N0YW5kYXJkRnVsbCcgbG9nZ2luZwogICAgZm9yZ2UubG9nLnByZXBhcmVTdGFuZGFyZChtZXNzYWdlKTsKICAgIG1lc3NhZ2Uuc3RhbmRhcmRGdWxsID0gbWVzc2FnZS5zdGFuZGFyZDsKICB9Cn07CgovLyBjcmVhdGUgbG9nIGxldmVsIGZ1bmN0aW9ucwppZih0cnVlKSB7CiAgLy8gbGV2ZWxzIGZvciB3aGljaCB3ZSB3YW50IGZ1bmN0aW9ucwogIHZhciBsZXZlbHMgPSBbJ2Vycm9yJywgJ3dhcm5pbmcnLCAnaW5mbycsICdkZWJ1ZycsICd2ZXJib3NlJ107CiAgZm9yKHZhciBpID0gMDsgaSA8IGxldmVscy5sZW5ndGg7ICsraSkgewogICAgLy8gd3JhcCBpbiBhIGZ1bmN0aW9uIHRvIGVuc3VyZSBwcm9wZXIgbGV2ZWwgdmFyIGlzIHBhc3NlZAogICAgKGZ1bmN0aW9uKGxldmVsKSB7CiAgICAgIC8vIGNyZWF0ZSBmdW5jdGlvbiBmb3IgdGhpcyBsZXZlbAogICAgICBmb3JnZS5sb2dbbGV2ZWxdID0gZnVuY3Rpb24oY2F0ZWdvcnksIG1lc3NhZ2UvKiwgYXJncy4uLiovKSB7CiAgICAgICAgLy8gY29udmVydCBhcmd1bWVudHMgdG8gcmVhbCBhcnJheSwgcmVtb3ZlIGNhdGVnb3J5IGFuZCBtZXNzYWdlCiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLnNsaWNlKDIpOwogICAgICAgIC8vIGNyZWF0ZSBtZXNzYWdlIG9iamVjdAogICAgICAgIC8vIE5vdGU6IGludGVycG9sYXRpb24gYW5kIHN0YW5kYXJkIGZvcm1hdHRpbmcgaXMgZG9uZSBsYXppbHkKICAgICAgICB2YXIgbXNnID0gewogICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLAogICAgICAgICAgbGV2ZWw6IGxldmVsLAogICAgICAgICAgY2F0ZWdvcnk6IGNhdGVnb3J5LAogICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwKICAgICAgICAgICdhcmd1bWVudHMnOiBhcmdzCiAgICAgICAgICAvKnN0YW5kYXJkKi8KICAgICAgICAgIC8qZnVsbCovCiAgICAgICAgICAvKmZ1bGxNZXNzYWdlKi8KICAgICAgICB9OwogICAgICAgIC8vIHByb2Nlc3MgdGhpcyBtZXNzYWdlCiAgICAgICAgZm9yZ2UubG9nLmxvZ01lc3NhZ2UobXNnKTsKICAgICAgfTsKICAgIH0pKGxldmVsc1tpXSk7CiAgfQp9CgovKioKICogQ3JlYXRlcyBhIG5ldyBsb2dnZXIgd2l0aCBzcGVjaWZpZWQgY3VzdG9tIGxvZ2dpbmcgZnVuY3Rpb24uCiAqCiAqIFRoZSBsb2dnaW5nIGZ1bmN0aW9uIGhhcyBhIHNpZ25hdHVyZSBvZjoKICogICBmdW5jdGlvbihsb2dnZXIsIG1lc3NhZ2UpCiAqIGxvZ2dlcjogY3VycmVudCBsb2dnZXIKICogbWVzc2FnZTogb2JqZWN0OgogKiAgIGxldmVsOiBsZXZlbCBpZAogKiAgIGNhdGVnb3J5OiBjYXRlZ29yeQogKiAgIG1lc3NhZ2U6IHN0cmluZyBtZXNzYWdlCiAqICAgYXJndW1lbnRzOiBBcnJheSBvZiBleHRyYSBhcmd1bWVudHMKICogICBmdWxsTWVzc2FnZTogaW50ZXJwb2xhdGVkIG1lc3NhZ2UgYW5kIGFyZ3VtZW50cyBpZiBJTlRFUlBPTEFURSBmbGFnIHNldAogKgogKiBAcGFyYW0gbG9nRnVuY3Rpb24gYSBsb2dnaW5nIGZ1bmN0aW9uIHdoaWNoIHRha2VzIGEgbG9nIG1lc3NhZ2Ugb2JqZWN0CiAqICAgICAgICAgIGFzIGEgcGFyYW1ldGVyLgogKgogKiBAcmV0dXJuIGEgbG9nZ2VyIG9iamVjdC4KICovCmZvcmdlLmxvZy5tYWtlTG9nZ2VyID0gZnVuY3Rpb24obG9nRnVuY3Rpb24pIHsKICB2YXIgbG9nZ2VyID0gewogICAgZmxhZ3M6IDAsCiAgICBmOiBsb2dGdW5jdGlvbgogIH07CiAgZm9yZ2UubG9nLnNldExldmVsKGxvZ2dlciwgJ25vbmUnKTsKICByZXR1cm4gbG9nZ2VyOwp9OwoKLyoqCiAqIFNldHMgdGhlIGN1cnJlbnQgbG9nIGxldmVsIG9uIGEgbG9nZ2VyLgogKgogKiBAcGFyYW0gbG9nZ2VyIHRoZSB0YXJnZXQgbG9nZ2VyLgogKiBAcGFyYW0gbGV2ZWwgdGhlIG5ldyBtYXhpbXVtIGxvZyBsZXZlbCBhcyBhIHN0cmluZy4KICoKICogQHJldHVybiB0cnVlIGlmIHNldCwgZmFsc2UgaWYgbm90LgogKi8KZm9yZ2UubG9nLnNldExldmVsID0gZnVuY3Rpb24obG9nZ2VyLCBsZXZlbCkgewogIHZhciBydmFsID0gZmFsc2U7CiAgaWYobG9nZ2VyICYmICEobG9nZ2VyLmZsYWdzICYgZm9yZ2UubG9nLkxFVkVMX0xPQ0tFRCkpIHsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBmb3JnZS5sb2cubGV2ZWxzLmxlbmd0aDsgKytpKSB7CiAgICAgIHZhciBhVmFsaWRMZXZlbCA9IGZvcmdlLmxvZy5sZXZlbHNbaV07CiAgICAgIGlmKGxldmVsID09IGFWYWxpZExldmVsKSB7CiAgICAgICAgLy8gc2V0IGxldmVsCiAgICAgICAgbG9nZ2VyLmxldmVsID0gbGV2ZWw7CiAgICAgICAgcnZhbCA9IHRydWU7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIExvY2tzIHRoZSBsb2cgbGV2ZWwgYXQgaXRzIGN1cnJlbnQgdmFsdWUuCiAqCiAqIEBwYXJhbSBsb2dnZXIgdGhlIHRhcmdldCBsb2dnZXIuCiAqIEBwYXJhbSBsb2NrIGJvb2xlYW4gbG9jayB2YWx1ZSwgZGVmYXVsdCB0byB0cnVlLgogKi8KZm9yZ2UubG9nLmxvY2sgPSBmdW5jdGlvbihsb2dnZXIsIGxvY2spIHsKICBpZih0eXBlb2YgbG9jayA9PT0gJ3VuZGVmaW5lZCcgfHwgbG9jaykgewogICAgbG9nZ2VyLmZsYWdzIHw9IGZvcmdlLmxvZy5MRVZFTF9MT0NLRUQ7CiAgfSBlbHNlIHsKICAgIGxvZ2dlci5mbGFncyAmPSB+Zm9yZ2UubG9nLkxFVkVMX0xPQ0tFRDsKICB9Cn07CgovKioKICogQWRkcyBhIGxvZ2dlci4KICoKICogQHBhcmFtIGxvZ2dlciB0aGUgbG9nZ2VyIG9iamVjdC4KICovCmZvcmdlLmxvZy5hZGRMb2dnZXIgPSBmdW5jdGlvbihsb2dnZXIpIHsKICBzTG9nZ2Vycy5wdXNoKGxvZ2dlcik7Cn07CgovLyBzZXR1cCB0aGUgY29uc29sZSBsb2dnZXIgaWYgcG9zc2libGUsIGVsc2UgY3JlYXRlIGZha2UgY29uc29sZS5sb2cKaWYodHlwZW9mKGNvbnNvbGUpICE9PSAndW5kZWZpbmVkJyAmJiAnbG9nJyBpbiBjb25zb2xlKSB7CiAgdmFyIGxvZ2dlcjsKICBpZihjb25zb2xlLmVycm9yICYmIGNvbnNvbGUud2FybiAmJiBjb25zb2xlLmluZm8gJiYgY29uc29sZS5kZWJ1ZykgewogICAgLy8gbG9va3MgbGlrZSBGaXJlYnVnLXN0eWxlIGxvZ2dpbmcgaXMgYXZhaWxhYmxlCiAgICAvLyBsZXZlbCBoYW5kbGVycyBtYXAKICAgIHZhciBsZXZlbEhhbmRsZXJzID0gewogICAgICBlcnJvcjogY29uc29sZS5lcnJvciwKICAgICAgd2FybmluZzogY29uc29sZS53YXJuLAogICAgICBpbmZvOiBjb25zb2xlLmluZm8sCiAgICAgIGRlYnVnOiBjb25zb2xlLmRlYnVnLAogICAgICB2ZXJib3NlOiBjb25zb2xlLmRlYnVnCiAgICB9OwogICAgdmFyIGYgPSBmdW5jdGlvbihsb2dnZXIsIG1lc3NhZ2UpIHsKICAgICAgZm9yZ2UubG9nLnByZXBhcmVTdGFuZGFyZChtZXNzYWdlKTsKICAgICAgdmFyIGhhbmRsZXIgPSBsZXZlbEhhbmRsZXJzW21lc3NhZ2UubGV2ZWxdOwogICAgICAvLyBwcmVwZW5kIHN0YW5kYXJkIG1lc3NhZ2UgYW5kIGNvbmNhdCBhcmdzCiAgICAgIHZhciBhcmdzID0gW21lc3NhZ2Uuc3RhbmRhcmRdOwogICAgICBhcmdzID0gYXJncy5jb25jYXQobWVzc2FnZVsnYXJndW1lbnRzJ10uc2xpY2UoKSk7CiAgICAgIC8vIGFwcGx5IHRvIGxvdy1sZXZlbCBjb25zb2xlIGZ1bmN0aW9uCiAgICAgIGhhbmRsZXIuYXBwbHkoY29uc29sZSwgYXJncyk7CiAgICB9OwogICAgbG9nZ2VyID0gZm9yZ2UubG9nLm1ha2VMb2dnZXIoZik7CiAgfSBlbHNlIHsKICAgIC8vIG9ubHkgYXBwZWFyIHRvIGhhdmUgYmFzaWMgY29uc29sZS5sb2cKICAgIHZhciBmID0gZnVuY3Rpb24obG9nZ2VyLCBtZXNzYWdlKSB7CiAgICAgIGZvcmdlLmxvZy5wcmVwYXJlU3RhbmRhcmRGdWxsKG1lc3NhZ2UpOwogICAgICBjb25zb2xlLmxvZyhtZXNzYWdlLnN0YW5kYXJkRnVsbCk7CiAgICB9OwogICAgbG9nZ2VyID0gZm9yZ2UubG9nLm1ha2VMb2dnZXIoZik7CiAgfQogIGZvcmdlLmxvZy5zZXRMZXZlbChsb2dnZXIsICdkZWJ1ZycpOwogIGZvcmdlLmxvZy5hZGRMb2dnZXIobG9nZ2VyKTsKICBzQ29uc29sZUxvZ2dlciA9IGxvZ2dlcjsKfSBlbHNlIHsKICAvLyBkZWZpbmUgZmFrZSBjb25zb2xlLmxvZyB0byBhdm9pZCBwb3RlbnRpYWwgc2NyaXB0IGVycm9ycyBvbgogIC8vIGJyb3dzZXJzIHRoYXQgZG8gbm90IGhhdmUgY29uc29sZSBsb2dnaW5nCiAgY29uc29sZSA9IHsKICAgIGxvZzogZnVuY3Rpb24oKSB7fQogIH07Cn0KCi8qCiAqIENoZWNrIGZvciBsb2dnaW5nIGNvbnRyb2wgcXVlcnkgdmFycy4KICoKICogY29uc29sZS5sZXZlbD08bGV2ZWwtbmFtZT4KICogU2V0J3MgdGhlIGNvbnNvbGUgbG9nIGxldmVsIGJ5IG5hbWUuICBVc2VmdWwgdG8gb3ZlcnJpZGUgZGVmYXVsdHMgYW5kCiAqIGFsbG93IG1vcmUgdmVyYm9zZSBsb2dnaW5nIGJlZm9yZSBhIHVzZXIgY29uZmlnIGlzIGxvYWRlZC4KICoKICogY29uc29sZS5sb2NrPTx0cnVlfGZhbHNlPgogKiBMb2NrIHRoZSBjb25zb2xlIGxvZyBsZXZlbCBhdCB3aGF0ZXZlciBsZXZlbCBpdCBpcyBzZXQgYXQuICBUaGlzIGlzIHJ1bgogKiBhZnRlciBjb25zb2xlLmxldmVsIGlzIHByb2Nlc3NlZC4gIFVzZWZ1bCB0byBmb3JjZSBhIGxldmVsIG9mIHZlcmJvc2l0eQogKiB0aGF0IGNvdWxkIG90aGVyd2lzZSBiZSBsaW1pdGVkIGJ5IGEgdXNlciBjb25maWcuCiAqLwppZihzQ29uc29sZUxvZ2dlciAhPT0gbnVsbCkgewogIHZhciBxdWVyeSA9IGZvcmdlLnV0aWwuZ2V0UXVlcnlWYXJpYWJsZXMoKTsKICBpZignY29uc29sZS5sZXZlbCcgaW4gcXVlcnkpIHsKICAgIC8vIHNldCB3aXRoIGxhc3QgdmFsdWUKICAgIGZvcmdlLmxvZy5zZXRMZXZlbCgKICAgICAgc0NvbnNvbGVMb2dnZXIsIHF1ZXJ5Wydjb25zb2xlLmxldmVsJ10uc2xpY2UoLTEpWzBdKTsKICB9CiAgaWYoJ2NvbnNvbGUubG9jaycgaW4gcXVlcnkpIHsKICAgIC8vIHNldCB3aXRoIGxhc3QgdmFsdWUKICAgIHZhciBsb2NrID0gcXVlcnlbJ2NvbnNvbGUubG9jayddLnNsaWNlKC0xKVswXTsKICAgIGlmKGxvY2sgPT0gJ3RydWUnKSB7CiAgICAgIGZvcmdlLmxvZy5sb2NrKHNDb25zb2xlTG9nZ2VyKTsKICAgIH0KICB9Cn0KCi8vIHByb3ZpZGUgcHVibGljIGFjY2VzcyB0byBjb25zb2xlIGxvZ2dlcgpmb3JnZS5sb2cuY29uc29sZUxvZ2dlciA9IHNDb25zb2xlTG9nZ2VyOwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAnbG9nJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL2xvZycsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBQS0NTIzcgdjEuNS4KICoKICogQGF1dGhvciBTdGVmYW4gU2llZ2wKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDEyIFN0ZWZhbiBTaWVnbCA8c3Rlc2llQGJyb2tlbnBpcGUuZGU+CiAqIENvcHlyaWdodCAoYykgMjAxMi0yMDE1IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqCiAqIEN1cnJlbnRseSB0aGlzIGltcGxlbWVudGF0aW9uIG9ubHkgc3VwcG9ydHMgQ29udGVudFR5cGUgb2YgRW52ZWxvcGVkRGF0YSwKICogRW5jcnlwdGVkRGF0YSwgb3IgU2lnbmVkRGF0YSBhdCB0aGUgcm9vdCBsZXZlbC4gVGhlIHRvcCBsZXZlbCBlbGVtZW50cyBtYXkKICogY29udGFpbiBvbmx5IGEgQ29udGVudEluZm8gb2YgQ29udGVudFR5cGUgRGF0YSwgaS5lLiBwbGFpbiBkYXRhLiBGdXJ0aGVyCiAqIG5lc3RpbmcgaXMgbm90ICh5ZXQpIHN1cHBvcnRlZC4KICoKICogVGhlIEZvcmdlIHZhbGlkYXRvcnMgZm9yIFBLQ1MgIzcncyBBU04uMSBzdHJ1Y3R1cmVzIGFyZSBhdmFpbGFibGUgZnJvbQogKiBhIHNlcGFyYXRlIGZpbGUgcGtjczdhc24xLmpzLCBzaW5jZSB0aG9zZSBhcmUgcmVmZXJlbmNlZCBmcm9tIG90aGVyCiAqIFBLQ1Mgc3RhbmRhcmRzIGxpa2UgUEtDUyAjMTIuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKLy8gc2hvcnRjdXQgZm9yIEFTTi4xIEFQSQp2YXIgYXNuMSA9IGZvcmdlLmFzbjE7CgovLyBzaG9ydGN1dCBmb3IgUEtDUyM3IEFQSQp2YXIgcDcgPSBmb3JnZS5wa2NzNyA9IGZvcmdlLnBrY3M3IHx8IHt9OwoKLyoqCiAqIENvbnZlcnRzIGEgUEtDUyM3IG1lc3NhZ2UgZnJvbSBQRU0gZm9ybWF0LgogKgogKiBAcGFyYW0gcGVtIHRoZSBQRU0tZm9ybWF0dGVkIFBLQ1MjNyBtZXNzYWdlLgogKgogKiBAcmV0dXJuIHRoZSBQS0NTIzcgbWVzc2FnZS4KICovCnA3Lm1lc3NhZ2VGcm9tUGVtID0gZnVuY3Rpb24ocGVtKSB7CiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKCiAgaWYobXNnLnR5cGUgIT09ICdQS0NTNycpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ291bGQgbm90IGNvbnZlcnQgUEtDUyM3IG1lc3NhZ2UgZnJvbSBQRU07IFBFTSAnICsKICAgICAgJ2hlYWRlciB0eXBlIGlzIG5vdCAiUEtDUyM3Ii4nKTsKICAgIGVycm9yLmhlYWRlclR5cGUgPSBtc2cudHlwZTsKICAgIHRocm93IGVycm9yOwogIH0KICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IFBLQ1MjNyBtZXNzYWdlIGZyb20gUEVNOyBQRU0gaXMgZW5jcnlwdGVkLicpOwogIH0KCiAgLy8gY29udmVydCBERVIgdG8gQVNOLjEgb2JqZWN0CiAgdmFyIG9iaiA9IGFzbjEuZnJvbURlcihtc2cuYm9keSk7CgogIHJldHVybiBwNy5tZXNzYWdlRnJvbUFzbjEob2JqKTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIFBLQ1MjNyBtZXNzYWdlIHRvIFBFTSBmb3JtYXQuCiAqCiAqIEBwYXJhbSBtc2cgVGhlIFBLQ1MjNyBtZXNzYWdlIG9iamVjdAogKiBAcGFyYW0gbWF4bGluZSBUaGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lLCBkZWZhdWx0cyB0byA2NC4KICoKICogQHJldHVybiBUaGUgUEVNLWZvcm1hdHRlZCBQS0NTIzcgbWVzc2FnZS4KICovCnA3Lm1lc3NhZ2VUb1BlbSA9IGZ1bmN0aW9uKG1zZywgbWF4bGluZSkgewogIC8vIGNvbnZlcnQgdG8gQVNOLjEsIHRoZW4gREVSLCB0aGVuIFBFTS1lbmNvZGUKICB2YXIgcGVtT2JqID0gewogICAgdHlwZTogJ1BLQ1M3JywKICAgIGJvZHk6IGFzbjEudG9EZXIobXNnLnRvQXNuMSgpKS5nZXRCeXRlcygpCiAgfTsKICByZXR1cm4gZm9yZ2UucGVtLmVuY29kZShwZW1PYmosIHttYXhsaW5lOiBtYXhsaW5lfSk7Cn07CgovKioKICogQ29udmVydHMgYSBQS0NTIzcgbWVzc2FnZSBmcm9tIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiB0aGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgYSBDb250ZW50SW5mby4KICoKICogQHJldHVybiB0aGUgUEtDUyM3IG1lc3NhZ2UuCiAqLwpwNy5tZXNzYWdlRnJvbUFzbjEgPSBmdW5jdGlvbihvYmopIHsKICAvLyB2YWxpZGF0ZSByb290IGxldmVsIENvbnRlbnRJbmZvIGFuZCBjYXB0dXJlIGRhdGEKICB2YXIgY2FwdHVyZSA9IHt9OwogIHZhciBlcnJvcnMgPSBbXTsKICBpZighYXNuMS52YWxpZGF0ZShvYmosIHA3LmFzbjEuY29udGVudEluZm9WYWxpZGF0b3IsIGNhcHR1cmUsIGVycm9ycykpCiAgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzcgbWVzc2FnZS4gJyArCiAgICAgICdBU04uMSBvYmplY3QgaXMgbm90IGFuIFBLQ1MjNyBDb250ZW50SW5mby4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgdmFyIGNvbnRlbnRUeXBlID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLmNvbnRlbnRUeXBlKTsKICB2YXIgbXNnOwoKICBzd2l0Y2goY29udGVudFR5cGUpIHsKICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMuZW52ZWxvcGVkRGF0YToKICAgICAgbXNnID0gcDcuY3JlYXRlRW52ZWxvcGVkRGF0YSgpOwogICAgICBicmVhazsKCiAgICBjYXNlIGZvcmdlLnBraS5vaWRzLmVuY3J5cHRlZERhdGE6CiAgICAgIG1zZyA9IHA3LmNyZWF0ZUVuY3J5cHRlZERhdGEoKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSBmb3JnZS5wa2kub2lkcy5zaWduZWREYXRhOgogICAgICBtc2cgPSBwNy5jcmVhdGVTaWduZWREYXRhKCk7CiAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgUEtDUyM3IG1lc3NhZ2UuIENvbnRlbnRUeXBlIHdpdGggT0lEICcgKwogICAgICAgIGNvbnRlbnRUeXBlICsgJyBpcyBub3QgKHlldCkgc3VwcG9ydGVkLicpOwogIH0KCiAgbXNnLmZyb21Bc24xKGNhcHR1cmUuY29udGVudC52YWx1ZVswXSk7CiAgcmV0dXJuIG1zZzsKfTsKCnA3LmNyZWF0ZVNpZ25lZERhdGEgPSBmdW5jdGlvbigpIHsKICB2YXIgbXNnID0gbnVsbDsKICBtc2cgPSB7CiAgICB0eXBlOiBmb3JnZS5wa2kub2lkcy5zaWduZWREYXRhLAogICAgdmVyc2lvbjogMSwKICAgIGNlcnRpZmljYXRlczogW10sCiAgICBjcmxzOiBbXSwKICAgIC8vIFRPRE86IGFkZCBqc29uLWZvcm1hdHRlZCBzaWduZXIgc3R1ZmYgaGVyZT8KICAgIHNpZ25lcnM6IFtdLAogICAgLy8gcG9wdWxhdGVkIGR1cmluZyBzaWduKCkKICAgIGRpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXJzOiBbXSwKICAgIGNvbnRlbnRJbmZvOiBudWxsLAogICAgc2lnbmVySW5mb3M6IFtdLAoKICAgIGZyb21Bc24xOiBmdW5jdGlvbihvYmopIHsKICAgICAgLy8gdmFsaWRhdGUgU2lnbmVkRGF0YSBjb250ZW50IGJsb2NrIGFuZCBjYXB0dXJlIGRhdGEuCiAgICAgIF9mcm9tQXNuMShtc2csIG9iaiwgcDcuYXNuMS5zaWduZWREYXRhVmFsaWRhdG9yKTsKICAgICAgbXNnLmNlcnRpZmljYXRlcyA9IFtdOwogICAgICBtc2cuY3JscyA9IFtdOwogICAgICBtc2cuZGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllcnMgPSBbXTsKICAgICAgbXNnLmNvbnRlbnRJbmZvID0gbnVsbDsKICAgICAgbXNnLnNpZ25lckluZm9zID0gW107CgogICAgICB2YXIgY2VydHMgPSBtc2cucmF3Q2FwdHVyZS5jZXJ0aWZpY2F0ZXMudmFsdWU7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBjZXJ0cy5sZW5ndGg7ICsraSkgewogICAgICAgIG1zZy5jZXJ0aWZpY2F0ZXMucHVzaChmb3JnZS5wa2kuY2VydGlmaWNhdGVGcm9tQXNuMShjZXJ0c1tpXSkpOwogICAgICB9CgogICAgICAvLyBUT0RPOiBwYXJzZSBjcmxzCiAgICB9LAoKICAgIHRvQXNuMTogZnVuY3Rpb24oKSB7CiAgICAgIC8vIGRlZ2VuZXJhdGUgY2FzZSB3aXRoIG5vIGNvbnRlbnQKICAgICAgaWYoIW1zZy5jb250ZW50SW5mbykgewogICAgICAgIG1zZy5zaWduKCk7CiAgICAgIH0KCiAgICAgIHZhciBjZXJ0cyA9IFtdOwogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgbXNnLmNlcnRpZmljYXRlcy5sZW5ndGg7ICsraSkgewogICAgICAgIGNlcnRzLnB1c2goZm9yZ2UucGtpLmNlcnRpZmljYXRlVG9Bc24xKG1zZy5jZXJ0aWZpY2F0ZXNbaV0pKTsKICAgICAgfQoKICAgICAgdmFyIGNybHMgPSBbXTsKICAgICAgLy8gVE9ETzogaW1wbGVtZW50IENSTHMKCiAgICAgIC8vIFswXSBTaWduZWREYXRhCiAgICAgIHZhciBzaWduZWREYXRhID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgICAgLy8gVmVyc2lvbgogICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIobXNnLnZlcnNpb24pLmdldEJ5dGVzKCkpLAogICAgICAgICAgLy8gRGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllcnMKICAgICAgICAgIGFzbjEuY3JlYXRlKAogICAgICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFVCwgdHJ1ZSwKICAgICAgICAgICAgbXNnLmRpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXJzKSwKICAgICAgICAgIC8vIENvbnRlbnRJbmZvCiAgICAgICAgICBtc2cuY29udGVudEluZm8KICAgICAgICBdKQogICAgICBdKTsKICAgICAgaWYoY2VydHMubGVuZ3RoID4gMCkgewogICAgICAgIC8vIFswXSBJTVBMSUNJVCBFeHRlbmRlZENlcnRpZmljYXRlc0FuZENlcnRpZmljYXRlcyBPUFRJT05BTAogICAgICAgIHNpZ25lZERhdGEudmFsdWVbMF0udmFsdWUucHVzaCgKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgY2VydHMpKTsKICAgICAgfQogICAgICBpZihjcmxzLmxlbmd0aCA+IDApIHsKICAgICAgICAvLyBbMV0gSU1QTElDSVQgQ2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdHMgT1BUSU9OQUwKICAgICAgICBzaWduZWREYXRhLnZhbHVlWzBdLnZhbHVlLnB1c2goCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDEsIHRydWUsIGNybHMpKTsKICAgICAgfQogICAgICAvLyBTaWduZXJJbmZvcwogICAgICBzaWduZWREYXRhLnZhbHVlWzBdLnZhbHVlLnB1c2goCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVQsIHRydWUsCiAgICAgICAgICBtc2cuc2lnbmVySW5mb3MpKTsKCiAgICAgIC8vIENvbnRlbnRJbmZvCiAgICAgIHJldHVybiBhc24xLmNyZWF0ZSgKICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICAvLyBDb250ZW50VHlwZQogICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgICBhc24xLm9pZFRvRGVyKG1zZy50eXBlKS5nZXRCeXRlcygpKSwKICAgICAgICAgIC8vIFswXSBTaWduZWREYXRhCiAgICAgICAgICBzaWduZWREYXRhCiAgICAgICAgXSk7CiAgICB9LAoKICAgIC8qKgogICAgICogQWRkIChhbm90aGVyKSBlbnRpdHkgdG8gbGlzdCBvZiBzaWduZXJzLgogICAgICoKICAgICAqIE5vdGU6IElmIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIGFyZSBwcm92aWRlZCwgdGhlbiwgcGVyIFJGQyAyMzE1LAogICAgICogdGhleSBtdXN0IGluY2x1ZGUgYXQgbGVhc3QgdHdvIGF0dHJpYnV0ZXM6IGNvbnRlbnQgdHlwZSBhbmQKICAgICAqIG1lc3NhZ2UgZGlnZXN0LiBUaGUgbWVzc2FnZSBkaWdlc3QgYXR0cmlidXRlIHZhbHVlIHdpbGwgYmUKICAgICAqIGF1dG8tY2FsY3VsYXRlZCBkdXJpbmcgc2lnbmluZyBhbmQgd2lsbCBiZSBpZ25vcmVkIGlmIHByb3ZpZGVkLgogICAgICoKICAgICAqIEhlcmUncyBhbiBleGFtcGxlIG9mIHByb3ZpZGluZyB0aGVzZSB0d28gYXR0cmlidXRlczoKICAgICAqCiAgICAgKiBmb3JnZS5wa2NzNy5jcmVhdGVTaWduZWREYXRhKCk7CiAgICAgKiBwNy5hZGRTaWduZXIoewogICAgICogICBpc3N1ZXI6IGNlcnQuaXNzdWVyLmF0dHJpYnV0ZXMsCiAgICAgKiAgIHNlcmlhbE51bWJlcjogY2VydC5zZXJpYWxOdW1iZXIsCiAgICAgKiAgIGtleTogcHJpdmF0ZUtleSwKICAgICAqICAgZGlnZXN0QWxnb3JpdGhtOiBmb3JnZS5wa2kub2lkcy5zaGExLAogICAgICogICBhdXRoZW50aWNhdGVkQXR0cmlidXRlczogW3sKICAgICAqICAgICB0eXBlOiBmb3JnZS5wa2kub2lkcy5jb250ZW50VHlwZSwKICAgICAqICAgICB2YWx1ZTogZm9yZ2UucGtpLm9pZHMuZGF0YQogICAgICogICB9LCB7CiAgICAgKiAgICAgdHlwZTogZm9yZ2UucGtpLm9pZHMubWVzc2FnZURpZ2VzdAogICAgICogICB9XQogICAgICogfSk7CiAgICAgKgogICAgICogVE9ETzogU3VwcG9ydCBbc3ViamVjdEtleUlkZW50aWZpZXJdIGFzIHNpZ25lcidzIElELgogICAgICoKICAgICAqIEBwYXJhbSBzaWduZXIgdGhlIHNpZ25lciBpbmZvcm1hdGlvbjoKICAgICAqICAgICAgICAgIGtleSB0aGUgc2lnbmVyJ3MgcHJpdmF0ZSBrZXkuCiAgICAgKiAgICAgICAgICBbY2VydGlmaWNhdGVdIGEgY2VydGlmaWNhdGUgY29udGFpbmluZyB0aGUgcHVibGljIGtleQogICAgICogICAgICAgICAgICBhc3NvY2lhdGVkIHdpdGggdGhlIHNpZ25lcidzIHByaXZhdGUga2V5OyB1c2UgdGhpcyBvcHRpb24gYXMKICAgICAqICAgICAgICAgICAgYW4gYWx0ZXJuYXRpdmUgdG8gc3BlY2lmeWluZyBzaWduZXIuaXNzdWVyIGFuZAogICAgICogICAgICAgICAgICBzaWduZXIuc2VyaWFsTnVtYmVyLgogICAgICogICAgICAgICAgW2lzc3Vlcl0gdGhlIGlzc3VlciBhdHRyaWJ1dGVzIChlZzogY2VydC5pc3N1ZXIuYXR0cmlidXRlcykuCiAgICAgKiAgICAgICAgICBbc2VyaWFsTnVtYmVyXSB0aGUgc2lnbmVyJ3MgY2VydGlmaWNhdGUncyBzZXJpYWwgbnVtYmVyIGluCiAgICAgKiAgICAgICAgICAgaGV4YWRlY2ltYWwgKGVnOiBjZXJ0LnNlcmlhbE51bWJlcikuCiAgICAgKiAgICAgICAgICBbZGlnZXN0QWxnb3JpdGhtXSB0aGUgbWVzc2FnZSBkaWdlc3QgT0lELCBhcyBhIHN0cmluZywgdG8gdXNlCiAgICAgKiAgICAgICAgICAgIChlZzogZm9yZ2UucGtpLm9pZHMuc2hhMSkuCiAgICAgKiAgICAgICAgICBbYXV0aGVudGljYXRlZEF0dHJpYnV0ZXNdIGFuIG9wdGlvbmFsIGFycmF5IG9mIGF0dHJpYnV0ZXMKICAgICAqICAgICAgICAgICAgdG8gYWxzbyBzaWduIGFsb25nIHdpdGggdGhlIGNvbnRlbnQuCiAgICAgKi8KICAgIGFkZFNpZ25lcjogZnVuY3Rpb24oc2lnbmVyKSB7CiAgICAgIHZhciBpc3N1ZXIgPSBzaWduZXIuaXNzdWVyOwogICAgICB2YXIgc2VyaWFsTnVtYmVyID0gc2lnbmVyLnNlcmlhbE51bWJlcjsKICAgICAgaWYoc2lnbmVyLmNlcnRpZmljYXRlKSB7CiAgICAgICAgdmFyIGNlcnQgPSBzaWduZXIuY2VydGlmaWNhdGU7CiAgICAgICAgaWYodHlwZW9mIGNlcnQgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgICBjZXJ0ID0gZm9yZ2UucGtpLmNlcnRpZmljYXRlRnJvbVBlbShjZXJ0KTsKICAgICAgICB9CiAgICAgICAgaXNzdWVyID0gY2VydC5pc3N1ZXIuYXR0cmlidXRlczsKICAgICAgICBzZXJpYWxOdW1iZXIgPSBjZXJ0LnNlcmlhbE51bWJlcjsKICAgICAgfQogICAgICB2YXIga2V5ID0gc2lnbmVyLmtleTsKICAgICAgaWYoIWtleSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigKICAgICAgICAgICdDb3VsZCBub3QgYWRkIFBLQ1MjNyBzaWduZXI7IG5vIHByaXZhdGUga2V5IHNwZWNpZmllZC4nKTsKICAgICAgfQogICAgICBpZih0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykgewogICAgICAgIGtleSA9IGZvcmdlLnBraS5wcml2YXRlS2V5RnJvbVBlbShrZXkpOwogICAgICB9CgogICAgICAvLyBlbnN1cmUgT0lEIGtub3duIGZvciBkaWdlc3QgYWxnb3JpdGhtCiAgICAgIHZhciBkaWdlc3RBbGdvcml0aG0gPSBzaWduZXIuZGlnZXN0QWxnb3JpdGhtIHx8IGZvcmdlLnBraS5vaWRzLnNoYTE7CiAgICAgIHN3aXRjaChkaWdlc3RBbGdvcml0aG0pIHsKICAgICAgY2FzZSBmb3JnZS5wa2kub2lkcy5zaGExOgogICAgICBjYXNlIGZvcmdlLnBraS5vaWRzLnNoYTI1NjoKICAgICAgY2FzZSBmb3JnZS5wa2kub2lkcy5zaGEzODQ6CiAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMuc2hhNTEyOgogICAgICBjYXNlIGZvcmdlLnBraS5vaWRzLm1kNToKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICAgICAnQ291bGQgbm90IGFkZCBQS0NTIzcgc2lnbmVyOyB1bmtub3duIG1lc3NhZ2UgZGlnZXN0IGFsZ29yaXRobTogJyArCiAgICAgICAgICBkaWdlc3RBbGdvcml0aG0pOwogICAgICB9CgogICAgICAvLyBpZiBhdXRoZW50aWNhdGVkQXR0cmlidXRlcyBpcyBwcmVzZW50LCB0aGVuIHRoZSBhdHRyaWJ1dGVzCiAgICAgIC8vIG11c3QgY29udGFpbiBhdCBsZWFzdCBQS0NTICM5IGNvbnRlbnQtdHlwZSBhbmQgbWVzc2FnZS1kaWdlc3QKICAgICAgdmFyIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzID0gc2lnbmVyLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIHx8IFtdOwogICAgICBpZihhdXRoZW50aWNhdGVkQXR0cmlidXRlcy5sZW5ndGggPiAwKSB7CiAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gZmFsc2U7CiAgICAgICAgdmFyIG1lc3NhZ2VEaWdlc3QgPSBmYWxzZTsKICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgIHZhciBhdHRyID0gYXV0aGVudGljYXRlZEF0dHJpYnV0ZXNbaV07CiAgICAgICAgICBpZighY29udGVudFR5cGUgJiYgYXR0ci50eXBlID09PSBmb3JnZS5wa2kub2lkcy5jb250ZW50VHlwZSkgewogICAgICAgICAgICBjb250ZW50VHlwZSA9IHRydWU7CiAgICAgICAgICAgIGlmKG1lc3NhZ2VEaWdlc3QpIHsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmKCFtZXNzYWdlRGlnZXN0ICYmIGF0dHIudHlwZSA9PT0gZm9yZ2UucGtpLm9pZHMubWVzc2FnZURpZ2VzdCkgewogICAgICAgICAgICBtZXNzYWdlRGlnZXN0ID0gdHJ1ZTsKICAgICAgICAgICAgaWYoY29udGVudFR5cGUpIHsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmKCFjb250ZW50VHlwZSB8fCAhbWVzc2FnZURpZ2VzdCkgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNpZ25lci5hdXRoZW50aWNhdGVkQXR0cmlidXRlcy4gSWYgJyArCiAgICAgICAgICAgICdzaWduZXIuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgaXMgc3BlY2lmaWVkLCB0aGVuIGl0IG11c3QgJyArCiAgICAgICAgICAgICdjb250YWluIGF0IGxlYXN0IHR3byBhdHRyaWJ1dGVzLCBQS0NTICM5IGNvbnRlbnQtdHlwZSBhbmQgJyArCiAgICAgICAgICAgICdQS0NTICM5IG1lc3NhZ2UtZGlnZXN0LicpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgbXNnLnNpZ25lcnMucHVzaCh7CiAgICAgICAga2V5OiBrZXksCiAgICAgICAgdmVyc2lvbjogMSwKICAgICAgICBpc3N1ZXI6IGlzc3VlciwKICAgICAgICBzZXJpYWxOdW1iZXI6IHNlcmlhbE51bWJlciwKICAgICAgICBkaWdlc3RBbGdvcml0aG06IGRpZ2VzdEFsZ29yaXRobSwKICAgICAgICBzaWduYXR1cmVBbGdvcml0aG06IGZvcmdlLnBraS5vaWRzLnJzYUVuY3J5cHRpb24sCiAgICAgICAgc2lnbmF0dXJlOiBudWxsLAogICAgICAgIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzOiBhdXRoZW50aWNhdGVkQXR0cmlidXRlcywKICAgICAgICB1bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzOiBbXQogICAgICB9KTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBTaWducyB0aGUgY29udGVudC4KICAgICAqLwogICAgc2lnbjogZnVuY3Rpb24oKSB7CiAgICAgIC8vIGF1dG8tZ2VuZXJhdGUgY29udGVudCBpbmZvCiAgICAgIGlmKHR5cGVvZiBtc2cuY29udGVudCAhPT0gJ29iamVjdCcgfHwgbXNnLmNvbnRlbnRJbmZvID09PSBudWxsKSB7CiAgICAgICAgLy8gdXNlIERhdGEgQ29udGVudEluZm8KICAgICAgICBtc2cuY29udGVudEluZm8gPSBhc24xLmNyZWF0ZSgKICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAgICAgLy8gQ29udGVudFR5cGUKICAgICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgICAgIGFzbjEub2lkVG9EZXIoZm9yZ2UucGtpLm9pZHMuZGF0YSkuZ2V0Qnl0ZXMoKSkKICAgICAgICAgIF0pOwoKICAgICAgICAvLyBhZGQgYWN0dWFsIGNvbnRlbnQsIGlmIHByZXNlbnQKICAgICAgICBpZignY29udGVudCcgaW4gbXNnKSB7CiAgICAgICAgICB2YXIgY29udGVudDsKICAgICAgICAgIGlmKG1zZy5jb250ZW50IGluc3RhbmNlb2YgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKSB7CiAgICAgICAgICAgIGNvbnRlbnQgPSBtc2cuY29udGVudC5ieXRlcygpOwogICAgICAgICAgfSBlbHNlIGlmKHR5cGVvZiBtc2cuY29udGVudCA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgY29udGVudCA9IGZvcmdlLnV0aWwuZW5jb2RlVXRmOChtc2cuY29udGVudCk7CiAgICAgICAgICB9CgogICAgICAgICAgbXNnLmNvbnRlbnRJbmZvLnZhbHVlLnB1c2goCiAgICAgICAgICAgIC8vIFswXSBFWFBMSUNJVCBjb250ZW50CiAgICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgWwogICAgICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLAogICAgICAgICAgICAgICAgY29udGVudCkKICAgICAgICAgICAgXSkpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gbm8gc2lnbmVycywgcmV0dXJuIGVhcmx5IChkZWdlbmVyYXRlIGNhc2UgZm9yIGNlcnRpZmljYXRlIGNvbnRhaW5lcikKICAgICAgaWYobXNnLnNpZ25lcnMubGVuZ3RoID09PSAwKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICAvLyBnZW5lcmF0ZSBkaWdlc3QgYWxnb3JpdGhtIGlkZW50aWZpZXJzCiAgICAgIHZhciBtZHMgPSBhZGREaWdlc3RBbGdvcml0aG1JZHMoKTsKCiAgICAgIC8vIGdlbmVyYXRlIHNpZ25lckluZm9zCiAgICAgIGFkZFNpZ25lckluZm9zKG1kcyk7CiAgICB9LAoKICAgIHZlcmlmeTogZnVuY3Rpb24oKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUyM3IHNpZ25hdHVyZSB2ZXJpZmljYXRpb24gbm90IHlldCBpbXBsZW1lbnRlZC4nKTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBBZGQgYSBjZXJ0aWZpY2F0ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gY2VydCB0aGUgY2VydGlmaWNhdGUgdG8gYWRkLgogICAgICovCiAgICBhZGRDZXJ0aWZpY2F0ZTogZnVuY3Rpb24oY2VydCkgewogICAgICAvLyBjb252ZXJ0IGZyb20gUEVNCiAgICAgIGlmKHR5cGVvZiBjZXJ0ID09PSAnc3RyaW5nJykgewogICAgICAgIGNlcnQgPSBmb3JnZS5wa2kuY2VydGlmaWNhdGVGcm9tUGVtKGNlcnQpOwogICAgICB9CiAgICAgIG1zZy5jZXJ0aWZpY2F0ZXMucHVzaChjZXJ0KTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBBZGQgYSBjZXJ0aWZpY2F0ZSByZXZva2F0aW9uIGxpc3QuCiAgICAgKgogICAgICogQHBhcmFtIGNybCB0aGUgY2VydGlmaWNhdGUgcmV2b2thdGlvbiBsaXN0IHRvIGFkZC4KICAgICAqLwogICAgYWRkQ2VydGlmaWNhdGVSZXZva2F0aW9uTGlzdDogZnVuY3Rpb24oY3JsKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUyM3IENSTCBzdXBwb3J0IG5vdCB5ZXQgaW1wbGVtZW50ZWQuJyk7CiAgICB9CiAgfTsKICByZXR1cm4gbXNnOwoKICBmdW5jdGlvbiBhZGREaWdlc3RBbGdvcml0aG1JZHMoKSB7CiAgICB2YXIgbWRzID0ge307CgogICAgZm9yKHZhciBpID0gMDsgaSA8IG1zZy5zaWduZXJzLmxlbmd0aDsgKytpKSB7CiAgICAgIHZhciBzaWduZXIgPSBtc2cuc2lnbmVyc1tpXTsKICAgICAgdmFyIG9pZCA9IHNpZ25lci5kaWdlc3RBbGdvcml0aG07CiAgICAgIGlmKCEob2lkIGluIG1kcykpIHsKICAgICAgICAvLyBjb250ZW50IGRpZ2VzdAogICAgICAgIG1kc1tvaWRdID0gZm9yZ2UubWRbZm9yZ2UucGtpLm9pZHNbb2lkXV0uY3JlYXRlKCk7CiAgICAgIH0KICAgICAgaWYoc2lnbmVyLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzLmxlbmd0aCA9PT0gMCkgewogICAgICAgIC8vIG5vIGN1c3RvbSBhdHRyaWJ1dGVzIHRvIGRpZ2VzdDsgdXNlIGNvbnRlbnQgbWVzc2FnZSBkaWdlc3QKICAgICAgICBzaWduZXIubWQgPSBtZHNbb2lkXTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBjdXN0b20gYXR0cmlidXRlcyB0byBiZSBkaWdlc3RlZDsgdXNlIG93biBtZXNzYWdlIGRpZ2VzdAogICAgICAgIC8vIFRPRE86IG9wdGltaXplIHRvIGp1c3QgY29weSBtZXNzYWdlIGRpZ2VzdCBzdGF0ZSBpZiB0aGF0CiAgICAgICAgLy8gZmVhdHVyZSBpcyBldmVyIHN1cHBvcnRlZCB3aXRoIG1lc3NhZ2UgZGlnZXN0cwogICAgICAgIHNpZ25lci5tZCA9IGZvcmdlLm1kW2ZvcmdlLnBraS5vaWRzW29pZF1dLmNyZWF0ZSgpOwogICAgICB9CiAgICB9CgogICAgLy8gYWRkIHVuaXF1ZSBkaWdlc3QgYWxnb3JpdGhtIGlkZW50aWZpZXJzCiAgICBtc2cuZGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllcnMgPSBbXTsKICAgIGZvcih2YXIgb2lkIGluIG1kcykgewogICAgICBtc2cuZGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllcnMucHVzaCgKICAgICAgICAvLyBBbGdvcml0aG1JZGVudGlmaWVyCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgICAgLy8gYWxnb3JpdGhtCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgICAgIGFzbjEub2lkVG9EZXIob2lkKS5nZXRCeXRlcygpKSwKICAgICAgICAgIC8vIHBhcmFtZXRlcnMgKG51bGwpCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgICAgICBdKSk7CiAgICB9CgogICAgcmV0dXJuIG1kczsKICB9CgogIGZ1bmN0aW9uIGFkZFNpZ25lckluZm9zKG1kcykgewogICAgLy8gTm90ZTogQ29udGVudEluZm8gaXMgYSBTRVFVRU5DRSB3aXRoIDIgdmFsdWVzLCBzZWNvbmQgdmFsdWUgaXMKICAgIC8vIHRoZSBjb250ZW50IGZpZWxkIGFuZCBpcyBvcHRpb25hbCBmb3IgYSBDb250ZW50SW5mbyBidXQgcmVxdWlyZWQgaGVyZQogICAgLy8gc2luY2Ugc2lnbmVycyBhcmUgcHJlc2VudAogICAgaWYobXNnLmNvbnRlbnRJbmZvLnZhbHVlLmxlbmd0aCA8IDIpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKAogICAgICAgICdDb3VsZCBub3Qgc2lnbiBQS0NTIzcgbWVzc2FnZTsgdGhlcmUgaXMgbm8gY29udGVudCB0byBzaWduLicpOwogICAgfQoKICAgIC8vIGdldCBDb250ZW50SW5mbyBjb250ZW50IHR5cGUKICAgIHZhciBjb250ZW50VHlwZSA9IGFzbjEuZGVyVG9PaWQobXNnLmNvbnRlbnRJbmZvLnZhbHVlWzBdLnZhbHVlKTsKCiAgICAvLyBnZXQgQ29udGVudEluZm8gY29udGVudAogICAgdmFyIGNvbnRlbnQgPSBtc2cuY29udGVudEluZm8udmFsdWVbMV07CiAgICAvLyBza2lwIFswXSBFWFBMSUNJVCBjb250ZW50IHdyYXBwZXIKICAgIGNvbnRlbnQgPSBjb250ZW50LnZhbHVlWzBdOwoKICAgIC8vIHNlcmlhbGl6ZSBjb250ZW50CiAgICB2YXIgYnl0ZXMgPSBhc24xLnRvRGVyKGNvbnRlbnQpOwoKICAgIC8vIHNraXAgaWRlbnRpZmllciBhbmQgbGVuZ3RoIHBlciBSRkMgMjMxNSA5LjMKICAgIC8vIHNraXAgaWRlbnRpZmllciAoMSBieXRlKQogICAgYnl0ZXMuZ2V0Qnl0ZSgpOwogICAgLy8gcmVhZCBhbmQgZGlzY2FyZCBsZW5ndGggYnl0ZXMKICAgIGFzbjEuZ2V0QmVyVmFsdWVMZW5ndGgoYnl0ZXMpOwogICAgYnl0ZXMgPSBieXRlcy5nZXRCeXRlcygpOwoKICAgIC8vIGRpZ2VzdCBjb250ZW50IERFUiB2YWx1ZSBieXRlcwogICAgZm9yKHZhciBvaWQgaW4gbWRzKSB7CiAgICAgIG1kc1tvaWRdLnN0YXJ0KCkudXBkYXRlKGJ5dGVzKTsKICAgIH0KCiAgICAvLyBzaWduIGNvbnRlbnQKICAgIHZhciBzaWduaW5nVGltZSA9IG5ldyBEYXRlKCk7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbXNnLnNpZ25lcnMubGVuZ3RoOyArK2kpIHsKICAgICAgdmFyIHNpZ25lciA9IG1zZy5zaWduZXJzW2ldOwoKICAgICAgaWYoc2lnbmVyLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzLmxlbmd0aCA9PT0gMCkgewogICAgICAgIC8vIGlmIENvbnRlbnRJbmZvIGNvbnRlbnQgdHlwZSBpcyBub3QgIkRhdGEiLCB0aGVuCiAgICAgICAgLy8gYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgbXVzdCBiZSBwcmVzZW50IHBlciBSRkMgMjMxNQogICAgICAgIGlmKGNvbnRlbnRUeXBlICE9PSBmb3JnZS5wa2kub2lkcy5kYXRhKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICAgICAgICdJbnZhbGlkIHNpZ25lcjsgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgbXVzdCBiZSBwcmVzZW50ICcgKwogICAgICAgICAgICAnd2hlbiB0aGUgQ29udGVudEluZm8gY29udGVudCB0eXBlIGlzIG5vdCBQS0NTIzcgRGF0YS4nKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gcHJvY2VzcyBhdXRoZW50aWNhdGVkIGF0dHJpYnV0ZXMKICAgICAgICAvLyBbMF0gSU1QTElDSVQKICAgICAgICBzaWduZXIuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXNBc24xID0gYXNuMS5jcmVhdGUoCiAgICAgICAgICBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFtdKTsKCiAgICAgICAgLy8gcGVyIFJGQyAyMzE1LCBhdHRyaWJ1dGVzIGFyZSB0byBiZSBkaWdlc3RlZCB1c2luZyBhIFNFVCBjb250YWluZXIKICAgICAgICAvLyBub3QgdGhlIGFib3ZlIFswXSBJTVBMSUNJVCBjb250YWluZXIKICAgICAgICB2YXIgYXR0cnNBc24xID0gYXNuMS5jcmVhdGUoCiAgICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFVCwgdHJ1ZSwgW10pOwoKICAgICAgICBmb3IodmFyIGFpID0gMDsgYWkgPCBzaWduZXIuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMubGVuZ3RoOyArK2FpKSB7CiAgICAgICAgICB2YXIgYXR0ciA9IHNpZ25lci5hdXRoZW50aWNhdGVkQXR0cmlidXRlc1thaV07CiAgICAgICAgICBpZihhdHRyLnR5cGUgPT09IGZvcmdlLnBraS5vaWRzLm1lc3NhZ2VEaWdlc3QpIHsKICAgICAgICAgICAgLy8gdXNlIGNvbnRlbnQgbWVzc2FnZSBkaWdlc3QgYXMgdmFsdWUKICAgICAgICAgICAgYXR0ci52YWx1ZSA9IG1kc1tzaWduZXIuZGlnZXN0QWxnb3JpdGhtXS5kaWdlc3QoKTsKICAgICAgICAgIH0gZWxzZSBpZihhdHRyLnR5cGUgPT09IGZvcmdlLnBraS5vaWRzLnNpZ25pbmdUaW1lKSB7CiAgICAgICAgICAgIC8vIGF1dG8tcG9wdWxhdGUgc2lnbmluZyB0aW1lIGlmIG5vdCBhbHJlYWR5IHNldAogICAgICAgICAgICBpZighYXR0ci52YWx1ZSkgewogICAgICAgICAgICAgIGF0dHIudmFsdWUgPSBzaWduaW5nVGltZTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIC8vIGNvbnZlcnQgdG8gQVNOLjEgYW5kIHB1c2ggb250byBBdHRyaWJ1dGVzIFNFVCAoZm9yIHNpZ25pbmcpIGFuZAogICAgICAgICAgLy8gb250byBhdXRoZW50aWNhdGVkQXR0cmlidXRlc0FzbjEgdG8gY29tcGxldGUgU2lnbmVkRGF0YSBBU04uMQogICAgICAgICAgLy8gVE9ETzogb3B0aW1pemUgYXdheSBkdXBsaWNhdGlvbgogICAgICAgICAgYXR0cnNBc24xLnZhbHVlLnB1c2goX2F0dHJpYnV0ZVRvQXNuMShhdHRyKSk7CiAgICAgICAgICBzaWduZXIuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXNBc24xLnZhbHVlLnB1c2goX2F0dHJpYnV0ZVRvQXNuMShhdHRyKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBERVItc2VyaWFsaXplIGFuZCBkaWdlc3QgU0VUIE9GIGF0dHJpYnV0ZXMgb25seQogICAgICAgIGJ5dGVzID0gYXNuMS50b0RlcihhdHRyc0FzbjEpLmdldEJ5dGVzKCk7CiAgICAgICAgc2lnbmVyLm1kLnN0YXJ0KCkudXBkYXRlKGJ5dGVzKTsKICAgICAgfQoKICAgICAgLy8gc2lnbiBkaWdlc3QKICAgICAgc2lnbmVyLnNpZ25hdHVyZSA9IHNpZ25lci5rZXkuc2lnbihzaWduZXIubWQsICdSU0FTU0EtUEtDUzEtVjFfNScpOwogICAgfQoKICAgIC8vIGFkZCBzaWduZXIgaW5mbwogICAgbXNnLnNpZ25lckluZm9zID0gX3NpZ25lcnNUb0FzbjEobXNnLnNpZ25lcnMpOwogIH0KfTsKCi8qKgogKiBDcmVhdGVzIGFuIGVtcHR5IFBLQ1MjNyBtZXNzYWdlIG9mIHR5cGUgRW5jcnlwdGVkRGF0YS4KICoKICogQHJldHVybiB0aGUgbWVzc2FnZS4KICovCnA3LmNyZWF0ZUVuY3J5cHRlZERhdGEgPSBmdW5jdGlvbigpIHsKICB2YXIgbXNnID0gbnVsbDsKICBtc2cgPSB7CiAgICB0eXBlOiBmb3JnZS5wa2kub2lkcy5lbmNyeXB0ZWREYXRhLAogICAgdmVyc2lvbjogMCwKICAgIGVuY3J5cHRlZENvbnRlbnQ6IHsKICAgICAgYWxnb3JpdGhtOiBmb3JnZS5wa2kub2lkc1snYWVzMjU2LUNCQyddCiAgICB9LAoKICAgIC8qKgogICAgICogUmVhZHMgYW4gRW5jcnlwdGVkRGF0YSBjb250ZW50IGJsb2NrIChpbiBBU04uMSBmb3JtYXQpCiAgICAgKgogICAgICogQHBhcmFtIG9iaiBUaGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgdGhlIEVuY3J5cHRlZERhdGEgY29udGVudCBibG9jawogICAgICovCiAgICBmcm9tQXNuMTogZnVuY3Rpb24ob2JqKSB7CiAgICAgIC8vIFZhbGlkYXRlIEVuY3J5cHRlZERhdGEgY29udGVudCBibG9jayBhbmQgY2FwdHVyZSBkYXRhLgogICAgICBfZnJvbUFzbjEobXNnLCBvYmosIHA3LmFzbjEuZW5jcnlwdGVkRGF0YVZhbGlkYXRvcik7CiAgICB9LAoKICAgIC8qKgogICAgICogRGVjcnlwdCBlbmNyeXB0ZWQgY29udGVudAogICAgICoKICAgICAqIEBwYXJhbSBrZXkgVGhlIChzeW1tZXRyaWMpIGtleSBhcyBhIGJ5dGUgYnVmZmVyCiAgICAgKi8KICAgIGRlY3J5cHQ6IGZ1bmN0aW9uKGtleSkgewogICAgICBpZihrZXkgIT09IHVuZGVmaW5lZCkgewogICAgICAgIG1zZy5lbmNyeXB0ZWRDb250ZW50LmtleSA9IGtleTsKICAgICAgfQogICAgICBfZGVjcnlwdENvbnRlbnQobXNnKTsKICAgIH0KICB9OwogIHJldHVybiBtc2c7Cn07CgovKioKICogQ3JlYXRlcyBhbiBlbXB0eSBQS0NTIzcgbWVzc2FnZSBvZiB0eXBlIEVudmVsb3BlZERhdGEuCiAqCiAqIEByZXR1cm4gdGhlIG1lc3NhZ2UuCiAqLwpwNy5jcmVhdGVFbnZlbG9wZWREYXRhID0gZnVuY3Rpb24oKSB7CiAgdmFyIG1zZyA9IG51bGw7CiAgbXNnID0gewogICAgdHlwZTogZm9yZ2UucGtpLm9pZHMuZW52ZWxvcGVkRGF0YSwKICAgIHZlcnNpb246IDAsCiAgICByZWNpcGllbnRzOiBbXSwKICAgIGVuY3J5cHRlZENvbnRlbnQ6IHsKICAgICAgYWxnb3JpdGhtOiBmb3JnZS5wa2kub2lkc1snYWVzMjU2LUNCQyddCiAgICB9LAoKICAgIC8qKgogICAgICogUmVhZHMgYW4gRW52ZWxvcGVkRGF0YSBjb250ZW50IGJsb2NrIChpbiBBU04uMSBmb3JtYXQpCiAgICAgKgogICAgICogQHBhcmFtIG9iaiB0aGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgdGhlIEVudmVsb3BlZERhdGEgY29udGVudCBibG9jay4KICAgICAqLwogICAgZnJvbUFzbjE6IGZ1bmN0aW9uKG9iaikgewogICAgICAvLyB2YWxpZGF0ZSBFbnZlbG9wZWREYXRhIGNvbnRlbnQgYmxvY2sgYW5kIGNhcHR1cmUgZGF0YQogICAgICB2YXIgY2FwdHVyZSA9IF9mcm9tQXNuMShtc2csIG9iaiwgcDcuYXNuMS5lbnZlbG9wZWREYXRhVmFsaWRhdG9yKTsKICAgICAgbXNnLnJlY2lwaWVudHMgPSBfcmVjaXBpZW50c0Zyb21Bc24xKGNhcHR1cmUucmVjaXBpZW50SW5mb3MudmFsdWUpOwogICAgfSwKCiAgICB0b0FzbjE6IGZ1bmN0aW9uKCkgewogICAgICAvLyBDb250ZW50SW5mbwogICAgICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIENvbnRlbnRUeXBlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0Rlcihtc2cudHlwZSkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgLy8gWzBdIEVudmVsb3BlZERhdGEKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAgICAgLy8gVmVyc2lvbgogICAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICAgICAgICAgIGFzbjEuaW50ZWdlclRvRGVyKG1zZy52ZXJzaW9uKS5nZXRCeXRlcygpKSwKICAgICAgICAgICAgLy8gUmVjaXBpZW50SW5mb3MKICAgICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVQsIHRydWUsCiAgICAgICAgICAgICAgX3JlY2lwaWVudHNUb0FzbjEobXNnLnJlY2lwaWVudHMpKSwKICAgICAgICAgICAgLy8gRW5jcnlwdGVkQ29udGVudEluZm8KICAgICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwKICAgICAgICAgICAgICBfZW5jcnlwdGVkQ29udGVudFRvQXNuMShtc2cuZW5jcnlwdGVkQ29udGVudCkpCiAgICAgICAgICBdKQogICAgICAgIF0pCiAgICAgIF0pOwogICAgfSwKCiAgICAvKioKICAgICAqIEZpbmQgcmVjaXBpZW50IGJ5IFguNTA5IGNlcnRpZmljYXRlJ3MgaXNzdWVyLgogICAgICoKICAgICAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZSB3aXRoIHRoZSBpc3N1ZXIgdG8gbG9vayBmb3IuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgcmVjaXBpZW50IG9iamVjdC4KICAgICAqLwogICAgZmluZFJlY2lwaWVudDogZnVuY3Rpb24oY2VydCkgewogICAgICB2YXIgc0F0dHIgPSBjZXJ0Lmlzc3Vlci5hdHRyaWJ1dGVzOwoKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IG1zZy5yZWNpcGllbnRzLmxlbmd0aDsgKytpKSB7CiAgICAgICAgdmFyIHIgPSBtc2cucmVjaXBpZW50c1tpXTsKICAgICAgICB2YXIgckF0dHIgPSByLmlzc3VlcjsKCiAgICAgICAgaWYoci5zZXJpYWxOdW1iZXIgIT09IGNlcnQuc2VyaWFsTnVtYmVyKSB7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGlmKHJBdHRyLmxlbmd0aCAhPT0gc0F0dHIubGVuZ3RoKSB7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIHZhciBtYXRjaCA9IHRydWU7CiAgICAgICAgZm9yKHZhciBqID0gMDsgaiA8IHNBdHRyLmxlbmd0aDsgKytqKSB7CiAgICAgICAgICBpZihyQXR0cltqXS50eXBlICE9PSBzQXR0cltqXS50eXBlIHx8CiAgICAgICAgICAgIHJBdHRyW2pdLnZhbHVlICE9PSBzQXR0cltqXS52YWx1ZSkgewogICAgICAgICAgICBtYXRjaCA9IGZhbHNlOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmKG1hdGNoKSB7CiAgICAgICAgICByZXR1cm4gcjsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHJldHVybiBudWxsOwogICAgfSwKCiAgICAvKioKICAgICAqIERlY3J5cHQgZW52ZWxvcGVkIGNvbnRlbnQKICAgICAqCiAgICAgKiBAcGFyYW0gcmVjaXBpZW50IFRoZSByZWNpcGllbnQgb2JqZWN0IHJlbGF0ZWQgdG8gdGhlIHByaXZhdGUga2V5CiAgICAgKiBAcGFyYW0gcHJpdktleSBUaGUgKFJTQSkgcHJpdmF0ZSBrZXkgb2JqZWN0CiAgICAgKi8KICAgIGRlY3J5cHQ6IGZ1bmN0aW9uKHJlY2lwaWVudCwgcHJpdktleSkgewogICAgICBpZihtc2cuZW5jcnlwdGVkQ29udGVudC5rZXkgPT09IHVuZGVmaW5lZCAmJiByZWNpcGllbnQgIT09IHVuZGVmaW5lZCAmJgogICAgICAgIHByaXZLZXkgIT09IHVuZGVmaW5lZCkgewogICAgICAgIHN3aXRjaChyZWNpcGllbnQuZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pIHsKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMucnNhRW5jcnlwdGlvbjoKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMuZGVzQ0JDOgogICAgICAgICAgICB2YXIga2V5ID0gcHJpdktleS5kZWNyeXB0KHJlY2lwaWVudC5lbmNyeXB0ZWRDb250ZW50LmNvbnRlbnQpOwogICAgICAgICAgICBtc2cuZW5jcnlwdGVkQ29udGVudC5rZXkgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihrZXkpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGFzeW1tZXRyaWMgY2lwaGVyLCAnICsKICAgICAgICAgICAgICAnT0lEICcgKyByZWNpcGllbnQuZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pOwogICAgICAgIH0KICAgICAgfQoKICAgICAgX2RlY3J5cHRDb250ZW50KG1zZyk7CiAgICB9LAoKICAgIC8qKgogICAgICogQWRkIChhbm90aGVyKSBlbnRpdHkgdG8gbGlzdCBvZiByZWNpcGllbnRzLgogICAgICoKICAgICAqIEBwYXJhbSBjZXJ0IFRoZSBjZXJ0aWZpY2F0ZSBvZiB0aGUgZW50aXR5IHRvIGFkZC4KICAgICAqLwogICAgYWRkUmVjaXBpZW50OiBmdW5jdGlvbihjZXJ0KSB7CiAgICAgIG1zZy5yZWNpcGllbnRzLnB1c2goewogICAgICAgIHZlcnNpb246IDAsCiAgICAgICAgaXNzdWVyOiBjZXJ0Lmlzc3Vlci5hdHRyaWJ1dGVzLAogICAgICAgIHNlcmlhbE51bWJlcjogY2VydC5zZXJpYWxOdW1iZXIsCiAgICAgICAgZW5jcnlwdGVkQ29udGVudDogewogICAgICAgICAgLy8gV2Ugc2ltcGx5IGFzc3VtZSByc2FFbmNyeXB0aW9uIGhlcmUsIHNpbmNlIGZvcmdlLnBraSBvbmx5CiAgICAgICAgICAvLyBzdXBwb3J0cyBSU0Egc28gZmFyLiAgSWYgdGhlIFBLSSBtb2R1bGUgc3VwcG9ydHMgb3RoZXIKICAgICAgICAgIC8vIGNpcGhlcnMgb25lIGRheSwgd2UgbmVlZCB0byBtb2RpZnkgdGhpcyBvbmUgYXMgd2VsbC4KICAgICAgICAgIGFsZ29yaXRobTogZm9yZ2UucGtpLm9pZHMucnNhRW5jcnlwdGlvbiwKICAgICAgICAgIGtleTogY2VydC5wdWJsaWNLZXkKICAgICAgICB9CiAgICAgIH0pOwogICAgfSwKCiAgICAvKioKICAgICAqIEVuY3J5cHQgZW52ZWxvcGVkIGNvbnRlbnQuCiAgICAgKgogICAgICogVGhpcyBmdW5jdGlvbiBzdXBwb3J0cyB0d28gb3B0aW9uYWwgYXJndW1lbnRzLCBjaXBoZXIgYW5kIGtleSwgd2hpY2gKICAgICAqIGNhbiBiZSB1c2VkIHRvIGluZmx1ZW5jZSBzeW1tZXRyaWMgZW5jcnlwdGlvbi4gIFVubGVzcyBjaXBoZXIgaXMKICAgICAqIHByb3ZpZGVkLCB0aGUgY2lwaGVyIHNwZWNpZmllZCBpbiBlbmNyeXB0ZWRDb250ZW50LmFsZ29yaXRobSBpcyB1c2VkCiAgICAgKiAoZGVmYXVsdHMgdG8gQUVTLTI1Ni1DQkMpLiAgSWYgbm8ga2V5IGlzIHByb3ZpZGVkLCBlbmNyeXB0ZWRDb250ZW50LmtleQogICAgICogaXMgKHJlLSl1c2VkLiAgSWYgdGhhdCBvbmUncyBub3Qgc2V0LCBhIHJhbmRvbSBrZXkgd2lsbCBiZSBnZW5lcmF0ZWQKICAgICAqIGF1dG9tYXRpY2FsbHkuCiAgICAgKgogICAgICogQHBhcmFtIFtrZXldIFRoZSBrZXkgdG8gYmUgdXNlZCBmb3Igc3ltbWV0cmljIGVuY3J5cHRpb24uCiAgICAgKiBAcGFyYW0gW2NpcGhlcl0gVGhlIE9JRCBvZiB0aGUgc3ltbWV0cmljIGNpcGhlciB0byB1c2UuCiAgICAgKi8KICAgIGVuY3J5cHQ6IGZ1bmN0aW9uKGtleSwgY2lwaGVyKSB7CiAgICAgIC8vIFBhcnQgMTogU3ltbWV0cmljIGVuY3J5cHRpb24KICAgICAgaWYobXNnLmVuY3J5cHRlZENvbnRlbnQuY29udGVudCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgY2lwaGVyID0gY2lwaGVyIHx8IG1zZy5lbmNyeXB0ZWRDb250ZW50LmFsZ29yaXRobTsKICAgICAgICBrZXkgPSBrZXkgfHwgbXNnLmVuY3J5cHRlZENvbnRlbnQua2V5OwoKICAgICAgICB2YXIga2V5TGVuLCBpdkxlbiwgY2lwaEZuOwogICAgICAgIHN3aXRjaChjaXBoZXIpIHsKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHNbJ2FlczEyOC1DQkMnXToKICAgICAgICAgICAga2V5TGVuID0gMTY7CiAgICAgICAgICAgIGl2TGVuID0gMTY7CiAgICAgICAgICAgIGNpcGhGbiA9IGZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICBjYXNlIGZvcmdlLnBraS5vaWRzWydhZXMxOTItQ0JDJ106CiAgICAgICAgICAgIGtleUxlbiA9IDI0OwogICAgICAgICAgICBpdkxlbiA9IDE2OwogICAgICAgICAgICBjaXBoRm4gPSBmb3JnZS5hZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgY2FzZSBmb3JnZS5wa2kub2lkc1snYWVzMjU2LUNCQyddOgogICAgICAgICAgICBrZXlMZW4gPSAzMjsKICAgICAgICAgICAgaXZMZW4gPSAxNjsKICAgICAgICAgICAgY2lwaEZuID0gZm9yZ2UuYWVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXI7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHNbJ2Rlcy1FREUzLUNCQyddOgogICAgICAgICAgICBrZXlMZW4gPSAyNDsKICAgICAgICAgICAgaXZMZW4gPSA4OwogICAgICAgICAgICBjaXBoRm4gPSBmb3JnZS5kZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBzeW1tZXRyaWMgY2lwaGVyLCBPSUQgJyArIGNpcGhlcik7CiAgICAgICAgfQoKICAgICAgICBpZihrZXkgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoZm9yZ2UucmFuZG9tLmdldEJ5dGVzKGtleUxlbikpOwogICAgICAgIH0gZWxzZSBpZihrZXkubGVuZ3RoKCkgIT0ga2V5TGVuKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N5bW1ldHJpYyBrZXkgaGFzIHdyb25nIGxlbmd0aDsgJyArCiAgICAgICAgICAgICdnb3QgJyArIGtleS5sZW5ndGgoKSArICcgYnl0ZXMsIGV4cGVjdGVkICcgKyBrZXlMZW4gKyAnLicpOwogICAgICAgIH0KCiAgICAgICAgLy8gS2VlcCBhIGNvcHkgb2YgdGhlIGtleSAmIElWIGluIHRoZSBvYmplY3QsIHNvIHRoZSBjYWxsZXIgY2FuCiAgICAgICAgLy8gdXNlIGl0IGZvciB3aGF0ZXZlciByZWFzb24uCiAgICAgICAgbXNnLmVuY3J5cHRlZENvbnRlbnQuYWxnb3JpdGhtID0gY2lwaGVyOwogICAgICAgIG1zZy5lbmNyeXB0ZWRDb250ZW50LmtleSA9IGtleTsKICAgICAgICBtc2cuZW5jcnlwdGVkQ29udGVudC5wYXJhbWV0ZXIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigKICAgICAgICAgIGZvcmdlLnJhbmRvbS5nZXRCeXRlcyhpdkxlbikpOwoKICAgICAgICB2YXIgY2lwaCA9IGNpcGhGbihrZXkpOwogICAgICAgIGNpcGguc3RhcnQobXNnLmVuY3J5cHRlZENvbnRlbnQucGFyYW1ldGVyLmNvcHkoKSk7CiAgICAgICAgY2lwaC51cGRhdGUobXNnLmNvbnRlbnQpOwoKICAgICAgICAvLyBUaGUgZmluaXNoIGZ1bmN0aW9uIGRvZXMgUEtDUyM3IHBhZGRpbmcgYnkgZGVmYXVsdCwgdGhlcmVmb3JlCiAgICAgICAgLy8gbm8gYWN0aW9uIHJlcXVpcmVkIGJ5IHVzLgogICAgICAgIGlmKCFjaXBoLmZpbmlzaCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N5bW1ldHJpYyBlbmNyeXB0aW9uIGZhaWxlZC4nKTsKICAgICAgICB9CgogICAgICAgIG1zZy5lbmNyeXB0ZWRDb250ZW50LmNvbnRlbnQgPSBjaXBoLm91dHB1dDsKICAgICAgfQoKICAgICAgLy8gUGFydCAyOiBhc3ltbWV0cmljIGVuY3J5cHRpb24gZm9yIGVhY2ggcmVjaXBpZW50CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtc2cucmVjaXBpZW50cy5sZW5ndGg7ICsraSkgewogICAgICAgIHZhciByZWNpcGllbnQgPSBtc2cucmVjaXBpZW50c1tpXTsKCiAgICAgICAgLy8gTm90aGluZyB0byBkbywgZW5jcnlwdGlvbiBhbHJlYWR5IGRvbmUuCiAgICAgICAgaWYocmVjaXBpZW50LmVuY3J5cHRlZENvbnRlbnQuY29udGVudCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIHN3aXRjaChyZWNpcGllbnQuZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pIHsKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMucnNhRW5jcnlwdGlvbjoKICAgICAgICAgICAgcmVjaXBpZW50LmVuY3J5cHRlZENvbnRlbnQuY29udGVudCA9CiAgICAgICAgICAgICAgcmVjaXBpZW50LmVuY3J5cHRlZENvbnRlbnQua2V5LmVuY3J5cHQoCiAgICAgICAgICAgICAgICBtc2cuZW5jcnlwdGVkQ29udGVudC5rZXkuZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgYXN5bW1ldHJpYyBjaXBoZXIsIE9JRCAnICsKICAgICAgICAgICAgICByZWNpcGllbnQuZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH07CiAgcmV0dXJuIG1zZzsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIHNpbmdsZSByZWNpcGllbnQgZnJvbSBhbiBBU04uMSBvYmplY3QuCiAqCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIFJlY2lwaWVudEluZm8uCiAqCiAqIEByZXR1cm4gdGhlIHJlY2lwaWVudCBvYmplY3QuCiAqLwpmdW5jdGlvbiBfcmVjaXBpZW50RnJvbUFzbjEob2JqKSB7CiAgLy8gdmFsaWRhdGUgRW52ZWxvcGVkRGF0YSBjb250ZW50IGJsb2NrIGFuZCBjYXB0dXJlIGRhdGEKICB2YXIgY2FwdHVyZSA9IHt9OwogIHZhciBlcnJvcnMgPSBbXTsKICBpZighYXNuMS52YWxpZGF0ZShvYmosIHA3LmFzbjEucmVjaXBpZW50SW5mb1ZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzcgUmVjaXBpZW50SW5mby4gJyArCiAgICAgICdBU04uMSBvYmplY3QgaXMgbm90IGFuIFBLQ1MjNyBSZWNpcGllbnRJbmZvLicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3JzOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICByZXR1cm4gewogICAgdmVyc2lvbjogY2FwdHVyZS52ZXJzaW9uLmNoYXJDb2RlQXQoMCksCiAgICBpc3N1ZXI6IGZvcmdlLnBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheShjYXB0dXJlLmlzc3VlciksCiAgICBzZXJpYWxOdW1iZXI6IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUuc2VyaWFsKS50b0hleCgpLAogICAgZW5jcnlwdGVkQ29udGVudDogewogICAgICBhbGdvcml0aG06IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5lbmNBbGdvcml0aG0pLAogICAgICBwYXJhbWV0ZXI6IGNhcHR1cmUuZW5jUGFyYW1ldGVyLnZhbHVlLAogICAgICBjb250ZW50OiBjYXB0dXJlLmVuY0tleQogICAgfQogIH07Cn0KCi8qKgogKiBDb252ZXJ0cyBhIHNpbmdsZSByZWNpcGllbnQgb2JqZWN0IHRvIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiB0aGUgcmVjaXBpZW50IG9iamVjdC4KICoKICogQHJldHVybiB0aGUgQVNOLjEgUmVjaXBpZW50SW5mby4KICovCmZ1bmN0aW9uIF9yZWNpcGllbnRUb0FzbjEob2JqKSB7CiAgcmV0dXJuIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgIC8vIFZlcnNpb24KICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIGFzbjEuaW50ZWdlclRvRGVyKG9iai52ZXJzaW9uKS5nZXRCeXRlcygpKSwKICAgIC8vIElzc3VlckFuZFNlcmlhbE51bWJlcgogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAvLyBOYW1lCiAgICAgIGZvcmdlLnBraS5kaXN0aW5ndWlzaGVkTmFtZVRvQXNuMSh7YXR0cmlidXRlczogb2JqLmlzc3Vlcn0pLAogICAgICAvLyBTZXJpYWwKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgICBmb3JnZS51dGlsLmhleFRvQnl0ZXMob2JqLnNlcmlhbE51bWJlcikpCiAgICBdKSwKICAgIC8vIEtleUVuY3J5cHRpb25BbGdvcml0aG1JZGVudGlmaWVyCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIEFsZ29yaXRobQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0RlcihvYmouZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pLmdldEJ5dGVzKCkpLAogICAgICAvLyBQYXJhbWV0ZXIsIGZvcmNlIE5VTEwsIG9ubHkgUlNBIHN1cHBvcnRlZCBmb3Igbm93LgogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgIF0pLAogICAgLy8gRW5jcnlwdGVkS2V5CiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgb2JqLmVuY3J5cHRlZENvbnRlbnQuY29udGVudCkKICBdKTsKfQoKLyoqCiAqIE1hcCBhIHNldCBvZiBSZWNpcGllbnRJbmZvIEFTTi4xIG9iamVjdHMgdG8gcmVjaXBpZW50IG9iamVjdHMuCiAqCiAqIEBwYXJhbSBpbmZvcyBhbiBhcnJheSBvZiBBU04uMSByZXByZXNlbnRhdGlvbnMgUmVjaXBpZW50SW5mbyAoaS5lLiBTRVQgT0YpLgogKgogKiBAcmV0dXJuIGFuIGFycmF5IG9mIHJlY2lwaWVudCBvYmplY3RzLgogKi8KZnVuY3Rpb24gX3JlY2lwaWVudHNGcm9tQXNuMShpbmZvcykgewogIHZhciByZXQgPSBbXTsKICBmb3IodmFyIGkgPSAwOyBpIDwgaW5mb3MubGVuZ3RoOyArK2kpIHsKICAgIHJldC5wdXNoKF9yZWNpcGllbnRGcm9tQXNuMShpbmZvc1tpXSkpOwogIH0KICByZXR1cm4gcmV0Owp9CgovKioKICogTWFwIGFuIGFycmF5IG9mIHJlY2lwaWVudCBvYmplY3RzIHRvIEFTTi4xIFJlY2lwaWVudEluZm8gb2JqZWN0cy4KICoKICogQHBhcmFtIHJlY2lwaWVudHMgYW4gYXJyYXkgb2YgcmVjaXBpZW50SW5mbyBvYmplY3RzLgogKgogKiBAcmV0dXJuIGFuIGFycmF5IG9mIEFTTi4xIFJlY2lwaWVudEluZm9zLgogKi8KZnVuY3Rpb24gX3JlY2lwaWVudHNUb0FzbjEocmVjaXBpZW50cykgewogIHZhciByZXQgPSBbXTsKICBmb3IodmFyIGkgPSAwOyBpIDwgcmVjaXBpZW50cy5sZW5ndGg7ICsraSkgewogICAgcmV0LnB1c2goX3JlY2lwaWVudFRvQXNuMShyZWNpcGllbnRzW2ldKSk7CiAgfQogIHJldHVybiByZXQ7Cn0KCi8qKgogKiBDb252ZXJ0cyBhIHNpbmdsZSBzaWduZXIgZnJvbSBhbiBBU04uMSBvYmplY3QuCiAqCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIGEgU2lnbmVySW5mby4KICoKICogQHJldHVybiB0aGUgc2lnbmVyIG9iamVjdC4KICovCmZ1bmN0aW9uIF9zaWduZXJGcm9tQXNuMShvYmopIHsKICAvLyB2YWxpZGF0ZSBFbnZlbG9wZWREYXRhIGNvbnRlbnQgYmxvY2sgYW5kIGNhcHR1cmUgZGF0YQogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgcDcuYXNuMS5zaWduZXJJbmZvVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFBLQ1MjNyBTaWduZXJJbmZvLiAnICsKICAgICAgJ0FTTi4xIG9iamVjdCBpcyBub3QgYW4gUEtDUyM3IFNpZ25lckluZm8uJyk7CiAgICBlcnJvci5lcnJvcnMgPSBlcnJvcnM7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIHZhciBydmFsID0gewogICAgdmVyc2lvbjogY2FwdHVyZS52ZXJzaW9uLmNoYXJDb2RlQXQoMCksCiAgICBpc3N1ZXI6IGZvcmdlLnBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheShjYXB0dXJlLmlzc3VlciksCiAgICBzZXJpYWxOdW1iZXI6IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUuc2VyaWFsKS50b0hleCgpLAogICAgZGlnZXN0QWxnb3JpdGhtOiBhc24xLmRlclRvT2lkKGNhcHR1cmUuZGlnZXN0QWxnb3JpdGhtKSwKICAgIHNpZ25hdHVyZUFsZ29yaXRobTogYXNuMS5kZXJUb09pZChjYXB0dXJlLnNpZ25hdHVyZUFsZ29yaXRobSksCiAgICBzaWduYXR1cmU6IGNhcHR1cmUuc2lnbmF0dXJlLAogICAgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXM6IFtdLAogICAgdW5hdXRoZW50aWNhdGVkQXR0cmlidXRlczogW10KICB9OwoKICAvLyBUT0RPOiBjb252ZXJ0IGF0dHJpYnV0ZXMKICB2YXIgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgPSBjYXB0dXJlLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIHx8IFtdOwogIHZhciB1bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzID0gY2FwdHVyZS51bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIHx8IFtdOwoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIENvbnZlcnRzIGEgc2luZ2xlIHNpZ25lckluZm8gb2JqZWN0IHRvIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiB0aGUgc2lnbmVySW5mbyBvYmplY3QuCiAqCiAqIEByZXR1cm4gdGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIGEgU2lnbmVySW5mby4KICovCmZ1bmN0aW9uIF9zaWduZXJUb0FzbjEob2JqKSB7CiAgLy8gU2lnbmVySW5mbwogIHZhciBydmFsID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gdmVyc2lvbgogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIob2JqLnZlcnNpb24pLmdldEJ5dGVzKCkpLAogICAgLy8gaXNzdWVyQW5kU2VyaWFsTnVtYmVyCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIG5hbWUKICAgICAgZm9yZ2UucGtpLmRpc3Rpbmd1aXNoZWROYW1lVG9Bc24xKHthdHRyaWJ1dGVzOiBvYmouaXNzdWVyfSksCiAgICAgIC8vIHNlcmlhbAogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICAgIGZvcmdlLnV0aWwuaGV4VG9CeXRlcyhvYmouc2VyaWFsTnVtYmVyKSkKICAgIF0pLAogICAgLy8gZGlnZXN0QWxnb3JpdGhtCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIGFsZ29yaXRobQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0RlcihvYmouZGlnZXN0QWxnb3JpdGhtKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGFyYW1ldGVycyAobnVsbCkKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5OVUxMLCBmYWxzZSwgJycpCiAgICBdKQogIF0pOwoKICAvLyBhdXRoZW50aWNhdGVkQXR0cmlidXRlcyAoT1BUSU9OQUwpCiAgaWYob2JqLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzQXNuMSkgewogICAgLy8gYWRkIEFTTi4xIHByZXZpb3VzbHkgZ2VuZXJhdGVkIGR1cmluZyBzaWduaW5nCiAgICBydmFsLnZhbHVlLnB1c2gob2JqLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzQXNuMSk7CiAgfQoKICAvLyBkaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtCiAgcnZhbC52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgIC8vIGFsZ29yaXRobQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICBhc24xLm9pZFRvRGVyKG9iai5zaWduYXR1cmVBbGdvcml0aG0pLmdldEJ5dGVzKCkpLAogICAgLy8gcGFyYW1ldGVycyAobnVsbCkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuTlVMTCwgZmFsc2UsICcnKQogIF0pKTsKCiAgLy8gZW5jcnlwdGVkRGlnZXN0CiAgcnZhbC52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIG9iai5zaWduYXR1cmUpKTsKCiAgLy8gdW5hdXRoZW50aWNhdGVkQXR0cmlidXRlcyAoT1BUSU9OQUwpCiAgaWYob2JqLnVuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMubGVuZ3RoID4gMCkgewogICAgLy8gWzFdIElNUExJQ0lUCiAgICB2YXIgYXR0cnNBc24xID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAxLCB0cnVlLCBbXSk7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgb2JqLnVuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMubGVuZ3RoOyArK2kpIHsKICAgICAgdmFyIGF0dHIgPSBvYmoudW5hdXRoZW50aWNhdGVkQXR0cmlidXRlc1tpXTsKICAgICAgYXR0cnNBc24xLnZhbHVlcy5wdXNoKF9hdHRyaWJ1dGVUb0FzbjEoYXR0cikpOwogICAgfQogICAgcnZhbC52YWx1ZS5wdXNoKGF0dHJzQXNuMSk7CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIE1hcCBhIHNldCBvZiBTaWduZXJJbmZvIEFTTi4xIG9iamVjdHMgdG8gYW4gYXJyYXkgb2Ygc2lnbmVyIG9iamVjdHMuCiAqCiAqIEBwYXJhbSBzaWduZXJJbmZvQXNuMXMgYW4gYXJyYXkgb2YgQVNOLjEgU2lnbmVySW5mb3MgKGkuZS4gU0VUIE9GKS4KICoKICogQHJldHVybiBhbiBhcnJheSBvZiBzaWduZXJzIG9iamVjdHMuCiAqLwpmdW5jdGlvbiBfc2lnbmVyc0Zyb21Bc24xKHNpZ25lckluZm9Bc24xcykgewogIHZhciByZXQgPSBbXTsKICBmb3IodmFyIGkgPSAwOyBpIDwgc2lnbmVySW5mb0FzbjFzLmxlbmd0aDsgKytpKSB7CiAgICByZXQucHVzaChfc2lnbmVyRnJvbUFzbjEoc2lnbmVySW5mb0FzbjFzW2ldKSk7CiAgfQogIHJldHVybiByZXQ7Cn0KCi8qKgogKiBNYXAgYW4gYXJyYXkgb2Ygc2lnbmVyIG9iamVjdHMgdG8gQVNOLjEgb2JqZWN0cy4KICoKICogQHBhcmFtIHNpZ25lcnMgYW4gYXJyYXkgb2Ygc2lnbmVyIG9iamVjdHMuCiAqCiAqIEByZXR1cm4gYW4gYXJyYXkgb2YgQVNOLjEgU2lnbmVySW5mb3MuCiAqLwpmdW5jdGlvbiBfc2lnbmVyc1RvQXNuMShzaWduZXJzKSB7CiAgdmFyIHJldCA9IFtdOwogIGZvcih2YXIgaSA9IDA7IGkgPCBzaWduZXJzLmxlbmd0aDsgKytpKSB7CiAgICByZXQucHVzaChfc2lnbmVyVG9Bc24xKHNpZ25lcnNbaV0pKTsKICB9CiAgcmV0dXJuIHJldDsKfQoKLyoqCiAqIENvbnZlcnQgYW4gYXR0cmlidXRlIG9iamVjdCB0byBhbiBBU04uMSBBdHRyaWJ1dGUuCiAqCiAqIEBwYXJhbSBhdHRyIHRoZSBhdHRyaWJ1dGUgb2JqZWN0LgogKgogKiBAcmV0dXJuIHRoZSBBU04uMSBBdHRyaWJ1dGUuCiAqLwpmdW5jdGlvbiBfYXR0cmlidXRlVG9Bc24xKGF0dHIpIHsKICB2YXIgdmFsdWU7CgogIC8vIFRPRE86IGdlbmVyYWxpemUgdG8gc3VwcG9ydCBtb3JlIGF0dHJpYnV0ZXMKICBpZihhdHRyLnR5cGUgPT09IGZvcmdlLnBraS5vaWRzLmNvbnRlbnRUeXBlKSB7CiAgICB2YWx1ZSA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgYXNuMS5vaWRUb0RlcihhdHRyLnZhbHVlKS5nZXRCeXRlcygpKTsKICB9IGVsc2UgaWYoYXR0ci50eXBlID09PSBmb3JnZS5wa2kub2lkcy5tZXNzYWdlRGlnZXN0KSB7CiAgICB2YWx1ZSA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLAogICAgICBhdHRyLnZhbHVlLmJ5dGVzKCkpOwogIH0gZWxzZSBpZihhdHRyLnR5cGUgPT09IGZvcmdlLnBraS5vaWRzLnNpZ25pbmdUaW1lKSB7CiAgICAvKiBOb3RlIHBlciBSRkMgMjk4NTogRGF0ZXMgYmV0d2VlbiAxIEphbnVhcnkgMTk1MCBhbmQgMzEgRGVjZW1iZXIgMjA0OQogICAgICAoaW5jbHVzaXZlKSBNVVNUIGJlIGVuY29kZWQgYXMgVVRDVGltZS4gQW55IGRhdGVzIHdpdGggeWVhciB2YWx1ZXMKICAgICAgYmVmb3JlIDE5NTAgb3IgYWZ0ZXIgMjA0OSBNVVNUIGJlIGVuY29kZWQgYXMgR2VuZXJhbGl6ZWRUaW1lLiBbRnVydGhlcixdCiAgICAgIFVUQ1RpbWUgdmFsdWVzIE1VU1QgYmUgZXhwcmVzc2VkIGluIEdyZWVud2ljaCBNZWFuIFRpbWUgKFp1bHUpIGFuZCBNVVNUCiAgICAgIGluY2x1ZGUgc2Vjb25kcyAoaS5lLiwgdGltZXMgYXJlIFlZTU1EREhITU1TU1opLCBldmVuIHdoZXJlIHRoZQogICAgICBudW1iZXIgb2Ygc2Vjb25kcyBpcyB6ZXJvLiAgTWlkbmlnaHQgKEdNVCkgbXVzdCBiZSByZXByZXNlbnRlZCBhcwogICAgICAiWVlNTUREMDAwMDAwWiIuICovCiAgICAvLyBUT0RPOiBtYWtlIHRoZXNlIG1vZHVsZS1sZXZlbCBjb25zdGFudHMKICAgIHZhciBqYW5fMV8xOTUwID0gbmV3IERhdGUoJ0phbiAxLCAxOTUwIDAwOjAwOjAwWicpOwogICAgdmFyIGphbl8xXzIwNTAgPSBuZXcgRGF0ZSgnSmFuIDEsIDIwNTAgMDA6MDA6MDBaJyk7CiAgICB2YXIgZGF0ZSA9IGF0dHIudmFsdWU7CiAgICBpZih0eXBlb2YgZGF0ZSA9PT0gJ3N0cmluZycpIHsKICAgICAgLy8gdHJ5IHRvIHBhcnNlIGRhdGUKICAgICAgdmFyIHRpbWVzdGFtcCA9IERhdGUucGFyc2UoZGF0ZSk7CiAgICAgIGlmKCFpc05hTih0aW1lc3RhbXApKSB7CiAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKHRpbWVzdGFtcCk7CiAgICAgIH0gZWxzZSBpZihkYXRlLmxlbmd0aCA9PT0gMTMpIHsKICAgICAgICAvLyBZWU1NRERISE1NU1NaICgxMyBjaGFycyBmb3IgVVRDVGltZSkKICAgICAgICBkYXRlID0gYXNuMS51dGNUaW1lVG9EYXRlKGRhdGUpOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIGFzc3VtZSBnZW5lcmFsaXplZCB0aW1lCiAgICAgICAgZGF0ZSA9IGFzbjEuZ2VuZXJhbGl6ZWRUaW1lVG9EYXRlKGRhdGUpOwogICAgICB9CiAgICB9CgogICAgaWYoZGF0ZSA+PSBqYW5fMV8xOTUwICYmIGRhdGUgPCBqYW5fMV8yMDUwKSB7CiAgICAgIHZhbHVlID0gYXNuMS5jcmVhdGUoCiAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5VVENUSU1FLCBmYWxzZSwKICAgICAgICBhc24xLmRhdGVUb1V0Y1RpbWUoZGF0ZSkpOwogICAgfSBlbHNlIHsKICAgICAgdmFsdWUgPSBhc24xLmNyZWF0ZSgKICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLkdFTkVSQUxJWkVEVElNRSwgZmFsc2UsCiAgICAgICAgYXNuMS5kYXRlVG9HZW5lcmFsaXplZFRpbWUoZGF0ZSkpOwogICAgfQogIH0KCiAgLy8gVE9ETzogZXhwb3NlIGFzIGNvbW1vbiBBUEkgY2FsbAogIC8vIGNyZWF0ZSBhIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUgc2V0CiAgLy8gZWFjaCB2YWx1ZSBpbiB0aGUgc2V0IGlzIGFuIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZSBmaXJzdAogIC8vIGNvbnRhaW5pbmcgdGhlIHR5cGUgKGFuIE9JRCkgYW5kIHNlY29uZCB0aGUgdmFsdWUKICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gQXR0cmlidXRlVHlwZQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICBhc24xLm9pZFRvRGVyKGF0dHIudHlwZSkuZ2V0Qnl0ZXMoKSksCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFVCwgdHJ1ZSwgWwogICAgICAvLyBBdHRyaWJ1dGVWYWx1ZQogICAgICB2YWx1ZQogICAgXSkKICBdKTsKfQoKLyoqCiAqIE1hcCBtZXNzYWdlcyBlbmNyeXB0ZWQgY29udGVudCB0byBBU04uMSBvYmplY3RzLgogKgogKiBAcGFyYW0gZWMgVGhlIGVuY3J5cHRlZENvbnRlbnQgb2JqZWN0IG9mIHRoZSBtZXNzYWdlLgogKgogKiBAcmV0dXJuIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbmNyeXB0ZWRDb250ZW50IG9iamVjdCAoU0VRVUVOQ0UpLgogKi8KZnVuY3Rpb24gX2VuY3J5cHRlZENvbnRlbnRUb0FzbjEoZWMpIHsKICByZXR1cm4gWwogICAgLy8gQ29udGVudFR5cGUsIGFsd2F5cyBEYXRhIGZvciB0aGUgbW9tZW50CiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgIGFzbjEub2lkVG9EZXIoZm9yZ2UucGtpLm9pZHMuZGF0YSkuZ2V0Qnl0ZXMoKSksCiAgICAvLyBDb250ZW50RW5jcnlwdGlvbkFsZ29yaXRobUlkZW50aWZpZXIKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgLy8gQWxnb3JpdGhtCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICBhc24xLm9pZFRvRGVyKGVjLmFsZ29yaXRobSkuZ2V0Qnl0ZXMoKSksCiAgICAgIC8vIFBhcmFtZXRlcnMgKElWKQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgICBlYy5wYXJhbWV0ZXIuZ2V0Qnl0ZXMoKSkKICAgIF0pLAogICAgLy8gWzBdIEVuY3J5cHRlZENvbnRlbnQKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgWwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgICBlYy5jb250ZW50LmdldEJ5dGVzKCkpCiAgICBdKQogIF07Cn0KCi8qKgogKiBSZWFkcyB0aGUgImNvbW1vbiBwYXJ0IiBvZiBhbiBQS0NTIzcgY29udGVudCBibG9jayAoaW4gQVNOLjEgZm9ybWF0KQogKgogKiBUaGlzIGZ1bmN0aW9uIHJlYWRzIHRoZSAiY29tbW9uIHBhcnQiIG9mIHRoZSBQS0NTIzcgY29udGVudCBibG9ja3MKICogRW5jcnlwdGVkRGF0YSBhbmQgRW52ZWxvcGVkRGF0YSwgaS5lLiB2ZXJzaW9uIG51bWJlciBhbmQgc3ltbWV0cmljYWxseQogKiBlbmNyeXB0ZWQgY29udGVudCBibG9jay4KICoKICogVGhlIHJlc3VsdCBvZiB0aGUgQVNOLjEgdmFsaWRhdGUgYW5kIGNhcHR1cmUgcHJvY2VzcyBpcyByZXR1cm5lZAogKiB0byBhbGxvdyB0aGUgY2FsbGVyIHRvIGV4dHJhY3QgZnVydGhlciBkYXRhLCBlLmcuIHRoZSBsaXN0IG9mIHJlY2lwaWVudHMKICogaW4gY2FzZSBvZiBhIEVudmVsb3BlZERhdGEgb2JqZWN0LgogKgogKiBAcGFyYW0gbXNnIHRoZSBQS0NTIzcgb2JqZWN0IHRvIHJlYWQgdGhlIGRhdGEgdG8uCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb250ZW50IGJsb2NrLgogKiBAcGFyYW0gdmFsaWRhdG9yIHRoZSBBU04uMSBzdHJ1Y3R1cmUgdmFsaWRhdG9yIG9iamVjdCB0byB1c2UuCiAqCiAqIEByZXR1cm4gdGhlIHZhbHVlIG1hcCBjYXB0dXJlZCBieSB2YWxpZGF0b3Igb2JqZWN0LgogKi8KZnVuY3Rpb24gX2Zyb21Bc24xKG1zZywgb2JqLCB2YWxpZGF0b3IpIHsKICB2YXIgY2FwdHVyZSA9IHt9OwogIHZhciBlcnJvcnMgPSBbXTsKICBpZighYXNuMS52YWxpZGF0ZShvYmosIHZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzcgbWVzc2FnZS4gJyArCiAgICAgICdBU04uMSBvYmplY3QgaXMgbm90IGEgc3VwcG9ydGVkIFBLQ1MjNyBtZXNzYWdlLicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3I7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIC8vIENoZWNrIGNvbnRlbnRUeXBlLCBzbyBmYXIgd2Ugb25seSBzdXBwb3J0IChyYXcpIERhdGEuCiAgdmFyIGNvbnRlbnRUeXBlID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLmNvbnRlbnRUeXBlKTsKICBpZihjb250ZW50VHlwZSAhPT0gZm9yZ2UucGtpLm9pZHMuZGF0YSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBQS0NTIzcgbWVzc2FnZS4gJyArCiAgICAgICdPbmx5IHdyYXBwZWQgQ29udGVudFR5cGUgRGF0YSBzdXBwb3J0ZWQuJyk7CiAgfQoKICBpZihjYXB0dXJlLmVuY3J5cHRlZENvbnRlbnQpIHsKICAgIHZhciBjb250ZW50ID0gJyc7CiAgICBpZihmb3JnZS51dGlsLmlzQXJyYXkoY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50KSkgewogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgaWYoY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50W2ldLnR5cGUgIT09IGFzbjEuVHlwZS5PQ1RFVFNUUklORykgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNYWxmb3JtZWQgUEtDUyM3IG1lc3NhZ2UsIGV4cGVjdGluZyBlbmNyeXB0ZWQgJyArCiAgICAgICAgICAgICdjb250ZW50IGNvbnN0cnVjdGVkIG9mIG9ubHkgT0NURVQgU1RSSU5HIG9iamVjdHMuJyk7CiAgICAgICAgfQogICAgICAgIGNvbnRlbnQgKz0gY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50W2ldLnZhbHVlOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBjb250ZW50ID0gY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50OwogICAgfQogICAgbXNnLmVuY3J5cHRlZENvbnRlbnQgPSB7CiAgICAgIGFsZ29yaXRobTogYXNuMS5kZXJUb09pZChjYXB0dXJlLmVuY0FsZ29yaXRobSksCiAgICAgIHBhcmFtZXRlcjogZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5lbmNQYXJhbWV0ZXIudmFsdWUpLAogICAgICBjb250ZW50OiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjb250ZW50KQogICAgfTsKICB9CgogIGlmKGNhcHR1cmUuY29udGVudCkgewogICAgdmFyIGNvbnRlbnQgPSAnJzsKICAgIGlmKGZvcmdlLnV0aWwuaXNBcnJheShjYXB0dXJlLmNvbnRlbnQpKSB7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBjYXB0dXJlLmNvbnRlbnQubGVuZ3RoOyArK2kpIHsKICAgICAgICBpZihjYXB0dXJlLmNvbnRlbnRbaV0udHlwZSAhPT0gYXNuMS5UeXBlLk9DVEVUU1RSSU5HKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01hbGZvcm1lZCBQS0NTIzcgbWVzc2FnZSwgZXhwZWN0aW5nICcgKwogICAgICAgICAgICAnY29udGVudCBjb25zdHJ1Y3RlZCBvZiBvbmx5IE9DVEVUIFNUUklORyBvYmplY3RzLicpOwogICAgICAgIH0KICAgICAgICBjb250ZW50ICs9IGNhcHR1cmUuY29udGVudFtpXS52YWx1ZTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgY29udGVudCA9IGNhcHR1cmUuY29udGVudDsKICAgIH0KICAgIG1zZy5jb250ZW50ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY29udGVudCk7CiAgfQoKICBtc2cudmVyc2lvbiA9IGNhcHR1cmUudmVyc2lvbi5jaGFyQ29kZUF0KDApOwogIG1zZy5yYXdDYXB0dXJlID0gY2FwdHVyZTsKCiAgcmV0dXJuIGNhcHR1cmU7Cn0KCi8qKgogKiBEZWNyeXB0IHRoZSBzeW1tZXRyaWNhbGx5IGVuY3J5cHRlZCBjb250ZW50IGJsb2NrIG9mIHRoZSBQS0NTIzcgbWVzc2FnZS4KICoKICogRGVjcnlwdGlvbiBpcyBza2lwcGVkIGluIGNhc2UgdGhlIFBLQ1MjNyBtZXNzYWdlIG9iamVjdCBhbHJlYWR5IGhhcyBhCiAqIChkZWNyeXB0ZWQpIGNvbnRlbnQgYXR0cmlidXRlLiAgVGhlIGFsZ29yaXRobSwga2V5IGFuZCBjaXBoZXIgcGFyYW1ldGVycwogKiAocHJvYmFibHkgdGhlIGl2KSBhcmUgdGFrZW4gZnJvbSB0aGUgZW5jcnlwdGVkQ29udGVudCBhdHRyaWJ1dGUgb2YgdGhlCiAqIG1lc3NhZ2Ugb2JqZWN0LgogKgogKiBAcGFyYW0gVGhlIFBLQ1MjNyBtZXNzYWdlIG9iamVjdC4KICovCmZ1bmN0aW9uIF9kZWNyeXB0Q29udGVudChtc2cpIHsKICBpZihtc2cuZW5jcnlwdGVkQ29udGVudC5rZXkgPT09IHVuZGVmaW5lZCkgewogICAgdGhyb3cgbmV3IEVycm9yKCdTeW1tZXRyaWMga2V5IG5vdCBhdmFpbGFibGUuJyk7CiAgfQoKICBpZihtc2cuY29udGVudCA9PT0gdW5kZWZpbmVkKSB7CiAgICB2YXIgY2lwaDsKCiAgICBzd2l0Y2gobXNnLmVuY3J5cHRlZENvbnRlbnQuYWxnb3JpdGhtKSB7CiAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHNbJ2FlczEyOC1DQkMnXToKICAgICAgY2FzZSBmb3JnZS5wa2kub2lkc1snYWVzMTkyLUNCQyddOgogICAgICBjYXNlIGZvcmdlLnBraS5vaWRzWydhZXMyNTYtQ0JDJ106CiAgICAgICAgY2lwaCA9IGZvcmdlLmFlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyKG1zZy5lbmNyeXB0ZWRDb250ZW50LmtleSk7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIGZvcmdlLnBraS5vaWRzWydkZXNDQkMnXToKICAgICAgY2FzZSBmb3JnZS5wa2kub2lkc1snZGVzLUVERTMtQ0JDJ106CiAgICAgICAgY2lwaCA9IGZvcmdlLmRlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyKG1zZy5lbmNyeXB0ZWRDb250ZW50LmtleSk7CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgc3ltbWV0cmljIGNpcGhlciwgT0lEICcgKwogICAgICAgICAgbXNnLmVuY3J5cHRlZENvbnRlbnQuYWxnb3JpdGhtKTsKICAgIH0KICAgIGNpcGguc3RhcnQobXNnLmVuY3J5cHRlZENvbnRlbnQucGFyYW1ldGVyKTsKICAgIGNpcGgudXBkYXRlKG1zZy5lbmNyeXB0ZWRDb250ZW50LmNvbnRlbnQpOwoKICAgIGlmKCFjaXBoLmZpbmlzaCgpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignU3ltbWV0cmljIGRlY3J5cHRpb24gZmFpbGVkLicpOwogICAgfQoKICAgIG1zZy5jb250ZW50ID0gY2lwaC5vdXRwdXQ7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdwa2NzNyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9wa2NzNycsWwogICdyZXF1aXJlJywKICAnbW9kdWxlJywKICAnLi9hZXMnLAogICcuL2FzbjEnLAogICcuL2RlcycsCiAgJy4vb2lkcycsCiAgJy4vcGVtJywKICAnLi9wa2NzN2FzbjEnLAogICcuL3JhbmRvbScsCiAgJy4vdXRpbCcsCiAgJy4veDUwOScKXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogRnVuY3Rpb25zIHRvIG91dHB1dCBrZXlzIGluIFNTSC1mcmllbmRseSBmb3JtYXRzLgogKgogKiBUaGlzIGlzIHBhcnQgb2YgdGhlIEZvcmdlIHByb2plY3Qgd2hpY2ggbWF5IGJlIHVzZWQgdW5kZXIgdGhlIHRlcm1zIG9mCiAqIGVpdGhlciB0aGUgQlNEIExpY2Vuc2Ugb3IgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIChHUEwpIFZlcnNpb24gMi4KICoKICogU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZGlnaXRhbGJhemFhci9mb3JnZS9ibG9iL2NiZWJjYTM3ODA2NTg3MDNkOTI1YjYxYjJjYWZmYjFkMjYzYTZjMWQvTElDRU5TRQogKgogKiBAYXV0aG9yIGh0dHBzOi8vZ2l0aHViLmNvbS9zaGVsbGFjCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKdmFyIHNzaCA9IGZvcmdlLnNzaCA9IGZvcmdlLnNzaCB8fCB7fTsKCi8qKgogKiBFbmNvZGVzIChhbmQgb3B0aW9uYWxseSBlbmNyeXB0cykgYSBwcml2YXRlIFJTQSBrZXkgYXMgYSBQdXR0eSBQUEsgZmlsZS4KICoKICogQHBhcmFtIHByaXZhdGVLZXkgdGhlIGtleS4KICogQHBhcmFtIHBhc3NwaHJhc2UgYSBwYXNzcGhyYXNlIHRvIHByb3RlY3QgdGhlIGtleSAoZmFsc3kgZm9yIG5vIGVuY3J5cHRpb24pLgogKiBAcGFyYW0gY29tbWVudCBhIGNvbW1lbnQgdG8gaW5jbHVkZSBpbiB0aGUga2V5IGZpbGUuCiAqCiAqIEByZXR1cm4gdGhlIFBQSyBmaWxlIGFzIGEgc3RyaW5nLgogKi8Kc3NoLnByaXZhdGVLZXlUb1B1dHR5ID0gZnVuY3Rpb24ocHJpdmF0ZUtleSwgcGFzc3BocmFzZSwgY29tbWVudCkgewogIGNvbW1lbnQgPSBjb21tZW50IHx8ICcnOwogIHBhc3NwaHJhc2UgPSBwYXNzcGhyYXNlIHx8ICcnOwogIHZhciBhbGdvcml0aG0gPSAnc3NoLXJzYSc7CiAgdmFyIGVuY3J5cHRpb25BbGdvcml0aG0gPSAocGFzc3BocmFzZSA9PT0gJycpID8gJ25vbmUnIDogJ2FlczI1Ni1jYmMnOwoKICB2YXIgcHBrID0gJ1B1VFRZLVVzZXItS2V5LUZpbGUtMjogJyArIGFsZ29yaXRobSArICdcclxuJzsKICBwcGsgKz0gJ0VuY3J5cHRpb246ICcgKyBlbmNyeXB0aW9uQWxnb3JpdGhtICsgJ1xyXG4nOwogIHBwayArPSAnQ29tbWVudDogJyArIGNvbW1lbnQgKyAnXHJcbic7CgogIC8vIHB1YmxpYyBrZXkgaW50byBidWZmZXIgZm9yIHBwawogIHZhciBwdWJidWZmZXIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIF9hZGRTdHJpbmdUb0J1ZmZlcihwdWJidWZmZXIsIGFsZ29yaXRobSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihwdWJidWZmZXIsIHByaXZhdGVLZXkuZSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihwdWJidWZmZXIsIHByaXZhdGVLZXkubik7CgogIC8vIHdyaXRlIHB1YmxpYyBrZXkKICB2YXIgcHViID0gZm9yZ2UudXRpbC5lbmNvZGU2NChwdWJidWZmZXIuYnl0ZXMoKSwgNjQpOwogIHZhciBsZW5ndGggPSBNYXRoLmZsb29yKHB1Yi5sZW5ndGggLyA2NikgKyAxOyAvLyA2NiA9IDY0ICsgXHJcbgogIHBwayArPSAnUHVibGljLUxpbmVzOiAnICsgbGVuZ3RoICsgJ1xyXG4nOwogIHBwayArPSBwdWI7CgogIC8vIHByaXZhdGUga2V5IGludG8gYSBidWZmZXIKICB2YXIgcHJpdmJ1ZmZlciA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihwcml2YnVmZmVyLCBwcml2YXRlS2V5LmQpOwogIF9hZGRCaWdJbnRlZ2VyVG9CdWZmZXIocHJpdmJ1ZmZlciwgcHJpdmF0ZUtleS5wKTsKICBfYWRkQmlnSW50ZWdlclRvQnVmZmVyKHByaXZidWZmZXIsIHByaXZhdGVLZXkucSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihwcml2YnVmZmVyLCBwcml2YXRlS2V5LnFJbnYpOwoKICAvLyBvcHRpb25hbGx5IGVuY3J5cHQgdGhlIHByaXZhdGUga2V5CiAgdmFyIHByaXY7CiAgaWYoIXBhc3NwaHJhc2UpIHsKICAgIC8vIHVzZSB0aGUgdW5lbmNyeXB0ZWQgYnVmZmVyCiAgICBwcml2ID0gZm9yZ2UudXRpbC5lbmNvZGU2NChwcml2YnVmZmVyLmJ5dGVzKCksIDY0KTsKICB9IGVsc2UgewogICAgLy8gZW5jcnlwdCBSU0Ega2V5IHVzaW5nIHBhc3NwaHJhc2UKICAgIHZhciBlbmNMZW4gPSBwcml2YnVmZmVyLmxlbmd0aCgpICsgMTYgLSAxOwogICAgZW5jTGVuIC09IGVuY0xlbiAlIDE2OwoKICAgIC8vIHBhZCBwcml2YXRlIGtleSB3aXRoIHNoYTEtZCBkYXRhIC0tIG5lZWRzIHRvIGJlIGEgbXVsdGlwbGUgb2YgMTYKICAgIHZhciBwYWRkaW5nID0gX3NoYTEocHJpdmJ1ZmZlci5ieXRlcygpKTsKCiAgICBwYWRkaW5nLnRydW5jYXRlKHBhZGRpbmcubGVuZ3RoKCkgLSBlbmNMZW4gKyBwcml2YnVmZmVyLmxlbmd0aCgpKTsKICAgIHByaXZidWZmZXIucHV0QnVmZmVyKHBhZGRpbmcpOwoKICAgIHZhciBhZXNrZXkgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgYWVza2V5LnB1dEJ1ZmZlcihfc2hhMSgnXHgwMFx4MDBceDAwXHgwMCcsIHBhc3NwaHJhc2UpKTsKICAgIGFlc2tleS5wdXRCdWZmZXIoX3NoYTEoJ1x4MDBceDAwXHgwMFx4MDEnLCBwYXNzcGhyYXNlKSk7CgogICAgLy8gZW5jcnlwdCBzb21lIGJ5dGVzIHVzaW5nIENCQyBtb2RlCiAgICAvLyBrZXkgaXMgNDAgYnl0ZXMsIHNvIHRydW5jYXRlICpieSogOCBieXRlcwogICAgdmFyIGNpcGhlciA9IGZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyKGFlc2tleS50cnVuY2F0ZSg4KSwgJ0NCQycpOwogICAgY2lwaGVyLnN0YXJ0KGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCkuZmlsbFdpdGhCeXRlKDAsIDE2KSk7CiAgICBjaXBoZXIudXBkYXRlKHByaXZidWZmZXIuY29weSgpKTsKICAgIGNpcGhlci5maW5pc2goKTsKICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIub3V0cHV0OwoKICAgIC8vIE5vdGU6IHRoaXMgYXBwZWFycyB0byBkaWZmZXIgZnJvbSBQdXR0eSAtLSBpcyBmb3JnZSB3cm9uZywgb3IgcHV0dHk/CiAgICAvLyBkdWUgdG8gcGFkZGluZyB3ZSBmaW5pc2ggYXMgYW4gZXhhY3QgbXVsdGlwbGUgb2YgMTYKICAgIGVuY3J5cHRlZC50cnVuY2F0ZSgxNik7IC8vIGFsbCBwYWRkaW5nCgogICAgcHJpdiA9IGZvcmdlLnV0aWwuZW5jb2RlNjQoZW5jcnlwdGVkLmJ5dGVzKCksIDY0KTsKICB9CgogIC8vIG91dHB1dCBwcml2YXRlIGtleQogIGxlbmd0aCA9IE1hdGguZmxvb3IocHJpdi5sZW5ndGggLyA2NikgKyAxOyAvLyA2NCArIFxyXG4KICBwcGsgKz0gJ1xyXG5Qcml2YXRlLUxpbmVzOiAnICsgbGVuZ3RoICsgJ1xyXG4nOwogIHBwayArPSBwcml2OwoKICAvLyBNQUMKICB2YXIgbWFja2V5ID0gX3NoYTEoJ3B1dHR5LXByaXZhdGUta2V5LWZpbGUtbWFjLWtleScsIHBhc3NwaHJhc2UpOwoKICB2YXIgbWFjYnVmZmVyID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBfYWRkU3RyaW5nVG9CdWZmZXIobWFjYnVmZmVyLCBhbGdvcml0aG0pOwogIF9hZGRTdHJpbmdUb0J1ZmZlcihtYWNidWZmZXIsIGVuY3J5cHRpb25BbGdvcml0aG0pOwogIF9hZGRTdHJpbmdUb0J1ZmZlcihtYWNidWZmZXIsIGNvbW1lbnQpOwogIG1hY2J1ZmZlci5wdXRJbnQzMihwdWJidWZmZXIubGVuZ3RoKCkpOwogIG1hY2J1ZmZlci5wdXRCdWZmZXIocHViYnVmZmVyKTsKICBtYWNidWZmZXIucHV0SW50MzIocHJpdmJ1ZmZlci5sZW5ndGgoKSk7CiAgbWFjYnVmZmVyLnB1dEJ1ZmZlcihwcml2YnVmZmVyKTsKCiAgdmFyIGhtYWMgPSBmb3JnZS5obWFjLmNyZWF0ZSgpOwogIGhtYWMuc3RhcnQoJ3NoYTEnLCBtYWNrZXkpOwogIGhtYWMudXBkYXRlKG1hY2J1ZmZlci5ieXRlcygpKTsKCiAgcHBrICs9ICdcclxuUHJpdmF0ZS1NQUM6ICcgKyBobWFjLmRpZ2VzdCgpLnRvSGV4KCkgKyAnXHJcbic7CgogIHJldHVybiBwcGs7Cn07CgovKioKICogRW5jb2RlcyBhIHB1YmxpYyBSU0Ega2V5IGFzIGFuIE9wZW5TU0ggZmlsZS4KICoKICogQHBhcmFtIGtleSB0aGUga2V5LgogKiBAcGFyYW0gY29tbWVudCBhIGNvbW1lbnQuCiAqCiAqIEByZXR1cm4gdGhlIHB1YmxpYyBrZXkgaW4gT3BlblNTSCBmb3JtYXQuCiAqLwpzc2gucHVibGljS2V5VG9PcGVuU1NIID0gZnVuY3Rpb24oa2V5LCBjb21tZW50KSB7CiAgdmFyIHR5cGUgPSAnc3NoLXJzYSc7CiAgY29tbWVudCA9IGNvbW1lbnQgfHwgJyc7CgogIHZhciBidWZmZXIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIF9hZGRTdHJpbmdUb0J1ZmZlcihidWZmZXIsIHR5cGUpOwogIF9hZGRCaWdJbnRlZ2VyVG9CdWZmZXIoYnVmZmVyLCBrZXkuZSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihidWZmZXIsIGtleS5uKTsKCiAgcmV0dXJuIHR5cGUgKyAnICcgKyBmb3JnZS51dGlsLmVuY29kZTY0KGJ1ZmZlci5ieXRlcygpKSArICcgJyArIGNvbW1lbnQ7Cn07CgovKioKICogRW5jb2RlcyBhIHByaXZhdGUgUlNBIGtleSBhcyBhbiBPcGVuU1NIIGZpbGUuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIGtleS4KICogQHBhcmFtIHBhc3NwaHJhc2UgYSBwYXNzcGhyYXNlIHRvIHByb3RlY3QgdGhlIGtleSAoZmFsc3kgZm9yIG5vIGVuY3J5cHRpb24pLgogKgogKiBAcmV0dXJuIHRoZSBwdWJsaWMga2V5IGluIE9wZW5TU0ggZm9ybWF0LgogKi8Kc3NoLnByaXZhdGVLZXlUb09wZW5TU0ggPSBmdW5jdGlvbihwcml2YXRlS2V5LCBwYXNzcGhyYXNlKSB7CiAgaWYoIXBhc3NwaHJhc2UpIHsKICAgIHJldHVybiBmb3JnZS5wa2kucHJpdmF0ZUtleVRvUGVtKHByaXZhdGVLZXkpOwogIH0KICAvLyBPcGVuU1NIIHByaXZhdGUga2V5IGlzIGp1c3QgYSBsZWdhY3kgZm9ybWF0LCBpdCBzZWVtcwogIHJldHVybiBmb3JnZS5wa2kuZW5jcnlwdFJzYVByaXZhdGVLZXkocHJpdmF0ZUtleSwgcGFzc3BocmFzZSwKICAgIHtsZWdhY3k6IHRydWUsIGFsZ29yaXRobTogJ2FlczEyOCd9KTsKfTsKCi8qKgogKiBHZXRzIHRoZSBTU0ggZmluZ2VycHJpbnQgZm9yIHRoZSBnaXZlbiBwdWJsaWMga2V5LgogKgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIFttZF0gdGhlIG1lc3NhZ2UgZGlnZXN0IG9iamVjdCB0byB1c2UgKGRlZmF1bHRzIHRvIGZvcmdlLm1kLm1kNSkuCiAqICAgICAgICAgIFtlbmNvZGluZ10gYW4gYWx0ZXJuYXRpdmUgb3V0cHV0IGVuY29kaW5nLCBzdWNoIGFzICdoZXgnCiAqICAgICAgICAgICAgKGRlZmF1bHRzIHRvIG5vbmUsIG91dHB1dHMgYSBieXRlIGJ1ZmZlcikuCiAqICAgICAgICAgIFtkZWxpbWl0ZXJdIHRoZSBkZWxpbWl0ZXIgdG8gdXNlIGJldHdlZW4gYnl0ZXMgZm9yICdoZXgnIGVuY29kZWQKICogICAgICAgICAgICBvdXRwdXQsIGVnOiAnOicgKGRlZmF1bHRzIHRvIG5vbmUpLgogKgogKiBAcmV0dXJuIHRoZSBmaW5nZXJwcmludCBhcyBhIGJ5dGUgYnVmZmVyIG9yIG90aGVyIGVuY29kaW5nIGJhc2VkIG9uIG9wdGlvbnMuCiAqLwpzc2guZ2V0UHVibGljS2V5RmluZ2VycHJpbnQgPSBmdW5jdGlvbihrZXksIG9wdGlvbnMpIHsKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICB2YXIgbWQgPSBvcHRpb25zLm1kIHx8IGZvcmdlLm1kLm1kNS5jcmVhdGUoKTsKCiAgdmFyIHR5cGUgPSAnc3NoLXJzYSc7CiAgdmFyIGJ1ZmZlciA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgX2FkZFN0cmluZ1RvQnVmZmVyKGJ1ZmZlciwgdHlwZSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihidWZmZXIsIGtleS5lKTsKICBfYWRkQmlnSW50ZWdlclRvQnVmZmVyKGJ1ZmZlciwga2V5Lm4pOwoKICAvLyBoYXNoIHB1YmxpYyBrZXkgYnl0ZXMKICBtZC5zdGFydCgpOwogIG1kLnVwZGF0ZShidWZmZXIuZ2V0Qnl0ZXMoKSk7CiAgdmFyIGRpZ2VzdCA9IG1kLmRpZ2VzdCgpOwogIGlmKG9wdGlvbnMuZW5jb2RpbmcgPT09ICdoZXgnKSB7CiAgICB2YXIgaGV4ID0gZGlnZXN0LnRvSGV4KCk7CiAgICBpZihvcHRpb25zLmRlbGltaXRlcikgewogICAgICByZXR1cm4gaGV4Lm1hdGNoKC8uezJ9L2cpLmpvaW4ob3B0aW9ucy5kZWxpbWl0ZXIpOwogICAgfQogICAgcmV0dXJuIGhleDsKICB9IGVsc2UgaWYob3B0aW9ucy5lbmNvZGluZyA9PT0gJ2JpbmFyeScpIHsKICAgIHJldHVybiBkaWdlc3QuZ2V0Qnl0ZXMoKTsKICB9IGVsc2UgaWYob3B0aW9ucy5lbmNvZGluZykgewogICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nICInICsgb3B0aW9ucy5lbmNvZGluZyArICciLicpOwogIH0KICByZXR1cm4gZGlnZXN0Owp9OwoKLyoqCiAqIEFkZHMgbGVuKHZhbCkgdGhlbiB2YWwgdG8gYSBidWZmZXIuCiAqCiAqIEBwYXJhbSBidWZmZXIgdGhlIGJ1ZmZlciB0byBhZGQgdG8uCiAqIEBwYXJhbSB2YWwgYSBiaWcgaW50ZWdlci4KICovCmZ1bmN0aW9uIF9hZGRCaWdJbnRlZ2VyVG9CdWZmZXIoYnVmZmVyLCB2YWwpIHsKICB2YXIgaGV4VmFsID0gdmFsLnRvU3RyaW5nKDE2KTsKICAvLyBlbnN1cmUgMnMgY29tcGxlbWVudCArdmUKICBpZihoZXhWYWxbMF0gPj0gJzgnKSB7CiAgICBoZXhWYWwgPSAnMDAnICsgaGV4VmFsOwogIH0KICB2YXIgYnl0ZXMgPSBmb3JnZS51dGlsLmhleFRvQnl0ZXMoaGV4VmFsKTsKICBidWZmZXIucHV0SW50MzIoYnl0ZXMubGVuZ3RoKTsKICBidWZmZXIucHV0Qnl0ZXMoYnl0ZXMpOwp9CgovKioKICogQWRkcyBsZW4odmFsKSB0aGVuIHZhbCB0byBhIGJ1ZmZlci4KICoKICogQHBhcmFtIGJ1ZmZlciB0aGUgYnVmZmVyIHRvIGFkZCB0by4KICogQHBhcmFtIHZhbCBhIHN0cmluZy4KICovCmZ1bmN0aW9uIF9hZGRTdHJpbmdUb0J1ZmZlcihidWZmZXIsIHZhbCkgewogIGJ1ZmZlci5wdXRJbnQzMih2YWwubGVuZ3RoKTsKICBidWZmZXIucHV0U3RyaW5nKHZhbCk7Cn0KCi8qKgogKiBIYXNoZXMgdGhlIGFyZ3VtZW50cyBpbnRvIG9uZSB2YWx1ZSB1c2luZyBTSEEtMS4KICoKICogQHJldHVybiB0aGUgc2hhMSBoYXNoIG9mIHRoZSBwcm92aWRlZCBhcmd1bWVudHMuCiAqLwpmdW5jdGlvbiBfc2hhMSgpIHsKICB2YXIgc2hhID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICB2YXIgbnVtID0gYXJndW1lbnRzLmxlbmd0aDsKICBmb3IgKHZhciBpID0gMDsgaSA8IG51bTsgKytpKSB7CiAgICBzaGEudXBkYXRlKGFyZ3VtZW50c1tpXSk7CiAgfQogIHJldHVybiBzaGEuZGlnZXN0KCk7Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3NzaCc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9zc2gnLFsKICAncmVxdWlyZScsCiAgJ21vZHVsZScsCiAgJy4vYWVzJywKICAnLi9obWFjJywKICAnLi9tZDUnLAogICcuL3NoYTEnLAogICcuL3V0aWwnCl0sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFN1cHBvcnQgZm9yIGNvbmN1cnJlbnQgdGFzayBtYW5hZ2VtZW50IGFuZCBzeW5jaHJvbml6YXRpb24gaW4gd2ViCiAqIGFwcGxpY2F0aW9ucy4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICogQGF1dGhvciBEYXZpZCBJLiBMZWhuIDxkbGVobkBkaWdpdGFsYmF6YWFyLmNvbT4KICoKICogQ29weXJpZ2h0IChjKSAyMDA5LTIwMTMgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBsb2dnaW5nIGNhdGVnb3J5CnZhciBjYXQgPSAnZm9yZ2UudGFzayc7CgovLyB2ZXJib3NlIGxldmVsCi8vIDA6IG9mZiwgMTogYSBsaXR0bGUsIDI6IGEgd2hvbGUgbG90Ci8vIFZlcmJvc2UgZGVidWcgbG9nZ2luZyBpcyBzdXJyb3VuZGVkIGJ5IGEgbGV2ZWwgY2hlY2sgdG8gYXZvaWQgdGhlCi8vIHBlcmZvcm1hbmNlIGlzc3VlcyB3aXRoIGV2ZW4gY2FsbGluZyB0aGUgbG9nZ2luZyBjb2RlIHJlZ2FyZGxlc3MgaWYgaXQKLy8gaXMgYWN0dWFsbHkgbG9nZ2VkLiAgRm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMgdGhpcyBzaG91bGQgbm90IGJlIHNldCB0byAyCi8vIGZvciBwcm9kdWN0aW9uIHVzZS4KLy8gZXg6IGlmKHNWTCA+PSAyKSBmb3JnZS5sb2cudmVyYm9zZSguLi4uKQp2YXIgc1ZMID0gMDsKCi8vIHRyYWNrIHRhc2tzIGZvciBkZWJ1Z2dpbmcKdmFyIHNUYXNrcyA9IHt9Owp2YXIgc05leHRUYXNrSWQgPSAwOwovLyBkZWJ1ZyBhY2Nlc3MKZm9yZ2UuZGVidWcuc2V0KGNhdCwgJ3Rhc2tzJywgc1Rhc2tzKTsKCi8vIGEgbWFwIG9mIHRhc2sgdHlwZSB0byB0YXNrIHF1ZXVlCnZhciBzVGFza1F1ZXVlcyA9IHt9OwovLyBkZWJ1ZyBhY2Nlc3MKZm9yZ2UuZGVidWcuc2V0KGNhdCwgJ3F1ZXVlcycsIHNUYXNrUXVldWVzKTsKCi8vIG5hbWUgZm9yIHVubmFtZWQgdGFza3MKdmFyIHNOb1Rhc2tOYW1lID0gJz8nOwoKLy8gbWF4aW11bSBudW1iZXIgb2YgZG9OZXh0KCkgcmVjdXJzaW9ucyBiZWZvcmUgYSBjb250ZXh0IHN3YXAgb2NjdXJzCi8vIEZJWE1FOiBtaWdodCBuZWVkIHRvIHR3ZWFrIHRoaXMgYmFzZWQgb24gdGhlIGJyb3dzZXIKdmFyIHNNYXhSZWN1cnNpb25zID0gMzA7CgovLyB0aW1lIHNsaWNlIGZvciBkb2luZyB0YXNrcyBiZWZvcmUgYSBjb250ZXh0IHN3YXAgb2NjdXJzCi8vIEZJWE1FOiBtaWdodCBuZWVkIHRvIHR3ZWFrIHRoaXMgYmFzZWQgb24gdGhlIGJyb3dzZXIKdmFyIHNUaW1lU2xpY2UgPSAyMDsKCi8qKgogKiBUYXNrIHN0YXRlcy4KICoKICogUkVBRFk6IHJlYWR5IHRvIHN0YXJ0IHByb2Nlc3NpbmcKICogUlVOTklORzogdGFzayBvciBhIHN1YnRhc2sgaXMgcnVubmluZwogKiBCTE9DS0VEOiB0YXNrIGlzIHdhaXRpbmcgdG8gYWNxdWlyZSBOIHBlcm1pdHMgdG8gY29udGludWUKICogU0xFRVBJTkc6IHRhc2sgaXMgc2xlZXBpbmcgZm9yIGEgcGVyaW9kIG9mIHRpbWUKICogRE9ORTogdGFzayBpcyBkb25lCiAqIEVSUk9SOiB0YXNrIGhhcyBhbiBlcnJvcgogKi8KdmFyIFJFQURZID0gJ3JlYWR5JzsKdmFyIFJVTk5JTkcgPSAncnVubmluZyc7CnZhciBCTE9DS0VEID0gJ2Jsb2NrZWQnOwp2YXIgU0xFRVBJTkcgPSAnc2xlZXBpbmcnOwp2YXIgRE9ORSA9ICdkb25lJzsKdmFyIEVSUk9SID0gJ2Vycm9yJzsKCi8qKgogKiBUYXNrIGFjdGlvbnMuICBVc2VkIHRvIGNvbnRyb2wgc3RhdGUgdHJhbnNpdGlvbnMuCiAqCiAqIFNUT1A6IHN0b3AgcHJvY2Vzc2luZwogKiBTVEFSVDogc3RhcnQgcHJvY2Vzc2luZyB0YXNrcwogKiBCTE9DSzogYmxvY2sgdGFzayBmcm9tIGNvbnRpbnVpbmcgdW50aWwgMSBvciBtb3JlIHBlcm1pdHMgYXJlIHJlbGVhc2VkCiAqIFVOQkxPQ0s6IHJlbGVhc2Ugb25lIG9yIG1vcmUgcGVybWl0cwogKiBTTEVFUDogc2xlZXAgZm9yIGEgcGVyaW9kIG9mIHRpbWUKICogV0FLRVVQOiB3YWtldXAgZWFybHkgZnJvbSBTTEVFUElORyBzdGF0ZQogKiBDQU5DRUw6IGNhbmNlbCBmdXJ0aGVyIHRhc2tzCiAqIEZBSUw6IGEgZmFpbHVyZSBvY2N1cmVkCiAqLwp2YXIgU1RPUCA9ICdzdG9wJzsKdmFyIFNUQVJUID0gJ3N0YXJ0JzsKdmFyIEJMT0NLID0gJ2Jsb2NrJzsKdmFyIFVOQkxPQ0sgPSAndW5ibG9jayc7CnZhciBTTEVFUCA9ICdzbGVlcCc7CnZhciBXQUtFVVAgPSAnd2FrZXVwJzsKdmFyIENBTkNFTCA9ICdjYW5jZWwnOwp2YXIgRkFJTCA9ICdmYWlsJzsKCi8qKgogKiBTdGF0ZSB0cmFuc2l0aW9uIHRhYmxlLgogKgogKiBuZXh0U3RhdGUgPSBzU3RhdGVUYWJsZVtjdXJyZW50U3RhdGVdW2FjdGlvbl0KICovCnZhciBzU3RhdGVUYWJsZSA9IHt9OwoKc1N0YXRlVGFibGVbUkVBRFldID0ge307CnNTdGF0ZVRhYmxlW1JFQURZXVtTVE9QXSA9IFJFQURZOwpzU3RhdGVUYWJsZVtSRUFEWV1bU1RBUlRdID0gUlVOTklORzsKc1N0YXRlVGFibGVbUkVBRFldW0NBTkNFTF0gPSBET05FOwpzU3RhdGVUYWJsZVtSRUFEWV1bRkFJTF0gPSBFUlJPUjsKCnNTdGF0ZVRhYmxlW1JVTk5JTkddID0ge307CnNTdGF0ZVRhYmxlW1JVTk5JTkddW1NUT1BdID0gUkVBRFk7CnNTdGF0ZVRhYmxlW1JVTk5JTkddW1NUQVJUXSA9IFJVTk5JTkc7CnNTdGF0ZVRhYmxlW1JVTk5JTkddW0JMT0NLXSA9IEJMT0NLRUQ7CnNTdGF0ZVRhYmxlW1JVTk5JTkddW1VOQkxPQ0tdID0gUlVOTklORzsKc1N0YXRlVGFibGVbUlVOTklOR11bU0xFRVBdID0gU0xFRVBJTkc7CnNTdGF0ZVRhYmxlW1JVTk5JTkddW1dBS0VVUF0gPSBSVU5OSU5HOwpzU3RhdGVUYWJsZVtSVU5OSU5HXVtDQU5DRUxdID0gRE9ORTsKc1N0YXRlVGFibGVbUlVOTklOR11bRkFJTF0gPSBFUlJPUjsKCnNTdGF0ZVRhYmxlW0JMT0NLRURdID0ge307CnNTdGF0ZVRhYmxlW0JMT0NLRURdW1NUT1BdID0gQkxPQ0tFRDsKc1N0YXRlVGFibGVbQkxPQ0tFRF1bU1RBUlRdID0gQkxPQ0tFRDsKc1N0YXRlVGFibGVbQkxPQ0tFRF1bQkxPQ0tdID0gQkxPQ0tFRDsKc1N0YXRlVGFibGVbQkxPQ0tFRF1bVU5CTE9DS10gPSBCTE9DS0VEOwpzU3RhdGVUYWJsZVtCTE9DS0VEXVtTTEVFUF0gPSBCTE9DS0VEOwpzU3RhdGVUYWJsZVtCTE9DS0VEXVtXQUtFVVBdID0gQkxPQ0tFRDsKc1N0YXRlVGFibGVbQkxPQ0tFRF1bQ0FOQ0VMXSA9IERPTkU7CnNTdGF0ZVRhYmxlW0JMT0NLRURdW0ZBSUxdID0gRVJST1I7CgpzU3RhdGVUYWJsZVtTTEVFUElOR10gPSB7fTsKc1N0YXRlVGFibGVbU0xFRVBJTkddW1NUT1BdID0gU0xFRVBJTkc7CnNTdGF0ZVRhYmxlW1NMRUVQSU5HXVtTVEFSVF0gPSBTTEVFUElORzsKc1N0YXRlVGFibGVbU0xFRVBJTkddW0JMT0NLXSA9IFNMRUVQSU5HOwpzU3RhdGVUYWJsZVtTTEVFUElOR11bVU5CTE9DS10gPSBTTEVFUElORzsKc1N0YXRlVGFibGVbU0xFRVBJTkddW1NMRUVQXSA9IFNMRUVQSU5HOwpzU3RhdGVUYWJsZVtTTEVFUElOR11bV0FLRVVQXSA9IFNMRUVQSU5HOwpzU3RhdGVUYWJsZVtTTEVFUElOR11bQ0FOQ0VMXSA9IERPTkU7CnNTdGF0ZVRhYmxlW1NMRUVQSU5HXVtGQUlMXSA9IEVSUk9SOwoKc1N0YXRlVGFibGVbRE9ORV0gPSB7fTsKc1N0YXRlVGFibGVbRE9ORV1bU1RPUF0gPSBET05FOwpzU3RhdGVUYWJsZVtET05FXVtTVEFSVF0gPSBET05FOwpzU3RhdGVUYWJsZVtET05FXVtCTE9DS10gPSBET05FOwpzU3RhdGVUYWJsZVtET05FXVtVTkJMT0NLXSA9IERPTkU7CnNTdGF0ZVRhYmxlW0RPTkVdW1NMRUVQXSA9IERPTkU7CnNTdGF0ZVRhYmxlW0RPTkVdW1dBS0VVUF0gPSBET05FOwpzU3RhdGVUYWJsZVtET05FXVtDQU5DRUxdID0gRE9ORTsKc1N0YXRlVGFibGVbRE9ORV1bRkFJTF0gPSBFUlJPUjsKCnNTdGF0ZVRhYmxlW0VSUk9SXSA9IHt9OwpzU3RhdGVUYWJsZVtFUlJPUl1bU1RPUF0gPSBFUlJPUjsKc1N0YXRlVGFibGVbRVJST1JdW1NUQVJUXSA9IEVSUk9SOwpzU3RhdGVUYWJsZVtFUlJPUl1bQkxPQ0tdID0gRVJST1I7CnNTdGF0ZVRhYmxlW0VSUk9SXVtVTkJMT0NLXSA9IEVSUk9SOwpzU3RhdGVUYWJsZVtFUlJPUl1bU0xFRVBdID0gRVJST1I7CnNTdGF0ZVRhYmxlW0VSUk9SXVtXQUtFVVBdID0gRVJST1I7CnNTdGF0ZVRhYmxlW0VSUk9SXVtDQU5DRUxdID0gRVJST1I7CnNTdGF0ZVRhYmxlW0VSUk9SXVtGQUlMXSA9IEVSUk9SOwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgdGFzay4KICoKICogQHBhcmFtIG9wdGlvbnMgb3B0aW9ucyBmb3IgdGhpcyB0YXNrCiAqICAgcnVuOiB0aGUgcnVuIGZ1bmN0aW9uIGZvciB0aGUgdGFzayAocmVxdWlyZWQpCiAqICAgbmFtZTogdGhlIHJ1biBmdW5jdGlvbiBmb3IgdGhlIHRhc2sgKG9wdGlvbmFsKQogKiAgIHBhcmVudDogcGFyZW50IG9mIHRoaXMgdGFzayAob3B0aW9uYWwpCiAqCiAqIEByZXR1cm4gdGhlIGVtcHR5IHRhc2suCiAqLwp2YXIgVGFzayA9IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAvLyB0YXNrIGlkCiAgdGhpcy5pZCA9IC0xOwoKICAvLyB0YXNrIG5hbWUKICB0aGlzLm5hbWUgPSBvcHRpb25zLm5hbWUgfHwgc05vVGFza05hbWU7CgogIC8vIHRhc2sgaGFzIG5vIHBhcmVudAogIHRoaXMucGFyZW50ID0gb3B0aW9ucy5wYXJlbnQgfHwgbnVsbDsKCiAgLy8gc2F2ZSBydW4gZnVuY3Rpb24KICB0aGlzLnJ1biA9IG9wdGlvbnMucnVuOwoKICAvLyBjcmVhdGUgYSBxdWV1ZSBvZiBzdWJ0YXNrcyB0byBydW4KICB0aGlzLnN1YnRhc2tzID0gW107CgogIC8vIGVycm9yIGZsYWcKICB0aGlzLmVycm9yID0gZmFsc2U7CgogIC8vIHN0YXRlIG9mIHRoZSB0YXNrCiAgdGhpcy5zdGF0ZSA9IFJFQURZOwoKICAvLyBudW1iZXIgb2YgdGltZXMgdGhlIHRhc2sgaGFzIGJlZW4gYmxvY2tlZCAoYWxzbyB0aGUgbnVtYmVyCiAgLy8gb2YgcGVybWl0cyBuZWVkZWQgdG8gYmUgcmVsZWFzZWQgdG8gY29udGludWUgcnVubmluZykKICB0aGlzLmJsb2NrcyA9IDA7CgogIC8vIHRpbWVvdXQgaWQgd2hlbiBzbGVlcGluZwogIHRoaXMudGltZW91dElkID0gbnVsbDsKCiAgLy8gbm8gc3dhcCB0aW1lIHlldAogIHRoaXMuc3dhcFRpbWUgPSBudWxsOwoKICAvLyBubyB1c2VyIGRhdGEKICB0aGlzLnVzZXJEYXRhID0gbnVsbDsKCiAgLy8gaW5pdGlhbGl6ZSB0YXNrCiAgLy8gRklYTUU6IGRlYWwgd2l0aCBvdmVyZmxvdwogIHRoaXMuaWQgPSBzTmV4dFRhc2tJZCsrOwogIHNUYXNrc1t0aGlzLmlkXSA9IHRoaXM7CiAgaWYoc1ZMID49IDEpIHsKICAgIGZvcmdlLmxvZy52ZXJib3NlKGNhdCwgJ1slc11bJXNdIGluaXQnLCB0aGlzLmlkLCB0aGlzLm5hbWUsIHRoaXMpOwogIH0KfTsKCi8qKgogKiBMb2dzIGRlYnVnIGluZm9ybWF0aW9uIG9uIHRoaXMgdGFzayBhbmQgdGhlIHN5c3RlbSBzdGF0ZS4KICovClRhc2sucHJvdG90eXBlLmRlYnVnID0gZnVuY3Rpb24obXNnKSB7CiAgbXNnID0gbXNnIHx8ICcnOwogIGZvcmdlLmxvZy5kZWJ1ZyhjYXQsIG1zZywKICAgICdbJXNdWyVzXSB0YXNrOicsIHRoaXMuaWQsIHRoaXMubmFtZSwgdGhpcywKICAgICdzdWJ0YXNrczonLCB0aGlzLnN1YnRhc2tzLmxlbmd0aCwKICAgICdxdWV1ZTonLCBzVGFza1F1ZXVlcyk7Cn07CgovKioKICogQWRkcyBhIHN1YnRhc2sgdG8gcnVuIGFmdGVyIHRhc2suZG9OZXh0KCkgb3IgdGFzay5mYWlsKCkgaXMgY2FsbGVkLgogKgogKiBAcGFyYW0gbmFtZSBodW1hbiByZWFkYWJsZSBuYW1lIGZvciB0aGlzIHRhc2sgKG9wdGlvbmFsKS4KICogQHBhcmFtIHN1YnJ1biBhIGZ1bmN0aW9uIHRvIHJ1biB0aGF0IHRha2VzIHRoZSBjdXJyZW50IHRhc2sgYXMKICogICAgICAgICAgaXRzIGZpcnN0IHBhcmFtZXRlci4KICoKICogQHJldHVybiB0aGUgY3VycmVudCB0YXNrICh1c2VmdWwgZm9yIGNoYWluaW5nIG5leHQoKSBjYWxscykuCiAqLwpUYXNrLnByb3RvdHlwZS5uZXh0ID0gZnVuY3Rpb24obmFtZSwgc3VicnVuKSB7CiAgLy8ganVnZ2xlIHBhcmFtZXRlcnMgaWYgaXQgbG9va3MgbGlrZSBubyBuYW1lIGlzIGdpdmVuCiAgaWYodHlwZW9mKG5hbWUpID09PSAnZnVuY3Rpb24nKSB7CiAgICBzdWJydW4gPSBuYW1lOwoKICAgIC8vIGluaGVyaXQgcGFyZW50J3MgbmFtZQogICAgbmFtZSA9IHRoaXMubmFtZTsKICB9CiAgLy8gY3JlYXRlIHN1YnRhc2ssIHNldCBwYXJlbnQgdG8gdGhpcyB0YXNrLCBwcm9wYWdhdGUgY2FsbGJhY2tzCiAgdmFyIHN1YnRhc2sgPSBuZXcgVGFzayh7CiAgICBydW46IHN1YnJ1biwKICAgIG5hbWU6IG5hbWUsCiAgICBwYXJlbnQ6IHRoaXMKICB9KTsKICAvLyBzdGFydCBzdWJ0YXNrcyBydW5uaW5nCiAgc3VidGFzay5zdGF0ZSA9IFJVTk5JTkc7CiAgc3VidGFzay50eXBlID0gdGhpcy50eXBlOwogIHN1YnRhc2suc3VjY2Vzc0NhbGxiYWNrID0gdGhpcy5zdWNjZXNzQ2FsbGJhY2sgfHwgbnVsbDsKICBzdWJ0YXNrLmZhaWx1cmVDYWxsYmFjayA9IHRoaXMuZmFpbHVyZUNhbGxiYWNrIHx8IG51bGw7CgogIC8vIHF1ZXVlIGEgbmV3IHN1YnRhc2sKICB0aGlzLnN1YnRhc2tzLnB1c2goc3VidGFzayk7CgogIHJldHVybiB0aGlzOwp9OwoKLyoqCiAqIEFkZHMgc3VidGFza3MgdG8gcnVuIGluIHBhcmFsbGVsIGFmdGVyIHRhc2suZG9OZXh0KCkgb3IgdGFzay5mYWlsKCkKICogaXMgY2FsbGVkLgogKgogKiBAcGFyYW0gbmFtZSBodW1hbiByZWFkYWJsZSBuYW1lIGZvciB0aGlzIHRhc2sgKG9wdGlvbmFsKS4KICogQHBhcmFtIHN1YnJ1biBmdW5jdGlvbnMgdG8gcnVuIHRoYXQgdGFrZSB0aGUgY3VycmVudCB0YXNrIGFzCiAqICAgICAgICAgIHRoZWlyIGZpcnN0IHBhcmFtZXRlci4KICoKICogQHJldHVybiB0aGUgY3VycmVudCB0YXNrICh1c2VmdWwgZm9yIGNoYWluaW5nIG5leHQoKSBjYWxscykuCiAqLwpUYXNrLnByb3RvdHlwZS5wYXJhbGxlbCA9IGZ1bmN0aW9uKG5hbWUsIHN1YnJ1bikgewogIC8vIGp1Z2dsZSBwYXJhbWV0ZXJzIGlmIGl0IGxvb2tzIGxpa2Ugbm8gbmFtZSBpcyBnaXZlbgogIGlmKGZvcmdlLnV0aWwuaXNBcnJheShuYW1lKSkgewogICAgc3VicnVuID0gbmFtZTsKCiAgICAvLyBpbmhlcml0IHBhcmVudCdzIG5hbWUKICAgIG5hbWUgPSB0aGlzLm5hbWU7CiAgfQogIC8vIFdyYXAgcGFyYWxsZWwgdGFza3MgaW4gYSByZWd1bGFyIHRhc2sgc28gdGhleSBhcmUgc3RhcnRlZCBhdCB0aGUKICAvLyBwcm9wZXIgdGltZS4KICByZXR1cm4gdGhpcy5uZXh0KG5hbWUsIGZ1bmN0aW9uKHRhc2spIHsKICAgIC8vIGJsb2NrIHdhaXRpbmcgZm9yIHN1YnRhc2tzCiAgICB2YXIgcHRhc2sgPSB0YXNrOwogICAgcHRhc2suYmxvY2soc3VicnVuLmxlbmd0aCk7CgogICAgLy8gd2UgcGFzcyB0aGUgaXRlcmF0b3IgZnJvbSB0aGUgbG9vcCBiZWxvdyBhcyBhIHBhcmFtZXRlcgogICAgLy8gdG8gYSBmdW5jdGlvbiBiZWNhdXNlIGl0IGlzIG90aGVyd2lzZSBpbmNsdWRlZCBpbiB0aGUKICAgIC8vIGNsb3N1cmUgYW5kIGNoYW5nZXMgYXMgdGhlIGxvb3AgY2hhbmdlcyAtLSBjYXVzaW5nIGkKICAgIC8vIHRvIGFsd2F5cyBiZSBzZXQgdG8gaXRzIGhpZ2hlc3QgdmFsdWUKICAgIHZhciBzdGFydFBhcmFsbGVsVGFzayA9IGZ1bmN0aW9uKHBuYW1lLCBwaSkgewogICAgICBmb3JnZS50YXNrLnN0YXJ0KHsKICAgICAgICB0eXBlOiBwbmFtZSwKICAgICAgICBydW46IGZ1bmN0aW9uKHRhc2spIHsKICAgICAgICAgICBzdWJydW5bcGldKHRhc2spOwogICAgICAgIH0sCiAgICAgICAgc3VjY2VzczogZnVuY3Rpb24odGFzaykgewogICAgICAgICAgIHB0YXNrLnVuYmxvY2soKTsKICAgICAgICB9LAogICAgICAgIGZhaWx1cmU6IGZ1bmN0aW9uKHRhc2spIHsKICAgICAgICAgICBwdGFzay51bmJsb2NrKCk7CiAgICAgICAgfQogICAgICB9KTsKICAgIH07CgogICAgZm9yKHZhciBpID0gMDsgaSA8IHN1YnJ1bi5sZW5ndGg7IGkrKykgewogICAgICAvLyBUeXBlIG11c3QgYmUgdW5pcXVlIHNvIHRhc2sgc3RhcnRzIGluIHBhcmFsbGVsOgogICAgICAvLyAgICBuYW1lICsgcHJpdmF0ZSBzdHJpbmcgKyB0YXNrIGlkICsgc3ViLXRhc2sgaW5kZXgKICAgICAgLy8gc3RhcnQgdGFza3MgaW4gcGFyYWxsZWwgYW5kIHVuYmxvY2sgd2hlbiB0aGUgZmluaXNoCiAgICAgIHZhciBwbmFtZSA9IG5hbWUgKyAnX19wYXJhbGxlbC0nICsgdGFzay5pZCArICctJyArIGk7CiAgICAgIHZhciBwaSA9IGk7CiAgICAgIHN0YXJ0UGFyYWxsZWxUYXNrKHBuYW1lLCBwaSk7CiAgICB9CiAgfSk7Cn07CgovKioKICogU3RvcHMgYSBydW5uaW5nIHRhc2suCiAqLwpUYXNrLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5zdGF0ZSA9IHNTdGF0ZVRhYmxlW3RoaXMuc3RhdGVdW1NUT1BdOwp9OwoKLyoqCiAqIFN0YXJ0cyBydW5uaW5nIGEgdGFzay4KICovClRhc2sucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5lcnJvciA9IGZhbHNlOwogIHRoaXMuc3RhdGUgPSBzU3RhdGVUYWJsZVt0aGlzLnN0YXRlXVtTVEFSVF07CgogIC8vIHRyeSB0byByZXN0YXJ0CiAgaWYodGhpcy5zdGF0ZSA9PT0gUlVOTklORykgewogICAgdGhpcy5zdGFydCA9IG5ldyBEYXRlKCk7CiAgICB0aGlzLnJ1bih0aGlzKTsKICAgIHJ1bk5leHQodGhpcywgMCk7CiAgfQp9OwoKLyoqCiAqIEJsb2NrcyBhIHRhc2sgdW50aWwgaXQgb25lIG9yIG1vcmUgcGVybWl0cyBoYXZlIGJlZW4gcmVsZWFzZWQuIFRoZQogKiB0YXNrIHdpbGwgbm90IHJlc3VtZSB1bnRpbCB0aGUgcmVxdWVzdGVkIG51bWJlciBvZiBwZXJtaXRzIGhhdmUKICogYmVlbiByZWxlYXNlZCB3aXRoIGNhbGwocykgdG8gdW5ibG9jaygpLgogKgogKiBAcGFyYW0gbiBudW1iZXIgb2YgcGVybWl0cyB0byB3YWl0IGZvcihkZWZhdWx0OiAxKS4KICovClRhc2sucHJvdG90eXBlLmJsb2NrID0gZnVuY3Rpb24obikgewogIG4gPSB0eXBlb2YobikgPT09ICd1bmRlZmluZWQnID8gMSA6IG47CiAgdGhpcy5ibG9ja3MgKz0gbjsKICBpZih0aGlzLmJsb2NrcyA+IDApIHsKICAgIHRoaXMuc3RhdGUgPSBzU3RhdGVUYWJsZVt0aGlzLnN0YXRlXVtCTE9DS107CiAgfQp9OwoKLyoqCiAqIFJlbGVhc2VzIGEgcGVybWl0IHRvIHVuYmxvY2sgYSB0YXNrLiBJZiBhIHRhc2sgd2FzIGJsb2NrZWQgYnkKICogcmVxdWVzdGluZyBOIHBlcm1pdHMgdmlhIGJsb2NrKCksIHRoZW4gaXQgd2lsbCBvbmx5IGNvbnRpbnVlCiAqIHJ1bm5pbmcgb25jZSBlbm91Z2ggcGVybWl0cyBoYXZlIGJlZW4gcmVsZWFzZWQgdmlhIHVuYmxvY2soKSBjYWxscy4KICoKICogSWYgbXVsdGlwbGUgcHJvY2Vzc2VzIG5lZWQgdG8gc3luY2hyb25pemUgd2l0aCBhIHNpbmdsZSB0YXNrIHRoZW4KICogdXNlIGEgY29uZGl0aW9uIHZhcmlhYmxlIChzZWUgZm9yZ2UudGFzay5jcmVhdGVDb25kaXRpb24pLiBJdCBpcwogKiBhbiBlcnJvciB0byB1bmJsb2NrIGEgdGFzayBtb3JlIHRpbWVzIHRoYW4gaXQgaGFzIGJlZW4gYmxvY2tlZC4KICoKICogQHBhcmFtIG4gbnVtYmVyIG9mIHBlcm1pdHMgdG8gcmVsZWFzZSAoZGVmYXVsdDogMSkuCiAqCiAqIEByZXR1cm4gdGhlIGN1cnJlbnQgYmxvY2sgY291bnQgKHRhc2sgaXMgdW5ibG9ja2VkIHdoZW4gY291bnQgaXMgMCkKICovClRhc2sucHJvdG90eXBlLnVuYmxvY2sgPSBmdW5jdGlvbihuKSB7CiAgbiA9IHR5cGVvZihuKSA9PT0gJ3VuZGVmaW5lZCcgPyAxIDogbjsKICB0aGlzLmJsb2NrcyAtPSBuOwogIGlmKHRoaXMuYmxvY2tzID09PSAwICYmIHRoaXMuc3RhdGUgIT09IERPTkUpIHsKICAgIHRoaXMuc3RhdGUgPSBSVU5OSU5HOwogICAgcnVuTmV4dCh0aGlzLCAwKTsKICB9CiAgcmV0dXJuIHRoaXMuYmxvY2tzOwp9OwoKLyoqCiAqIFNsZWVwIGZvciBhIHBlcmlvZCBvZiB0aW1lIGJlZm9yZSByZXN1bWluZyB0YXNrcy4KICoKICogQHBhcmFtIG4gbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBzbGVlcCAoZGVmYXVsdDogMCkuCiAqLwpUYXNrLnByb3RvdHlwZS5zbGVlcCA9IGZ1bmN0aW9uKG4pIHsKICBuID0gdHlwZW9mKG4pID09PSAndW5kZWZpbmVkJyA/IDAgOiBuOwogIHRoaXMuc3RhdGUgPSBzU3RhdGVUYWJsZVt0aGlzLnN0YXRlXVtTTEVFUF07CiAgdmFyIHNlbGYgPSB0aGlzOwogIHRoaXMudGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbigpIHsKICAgIHNlbGYudGltZW91dElkID0gbnVsbDsKICAgIHNlbGYuc3RhdGUgPSBSVU5OSU5HOwogICAgcnVuTmV4dChzZWxmLCAwKTsKICB9LCBuKTsKfTsKCi8qKgogKiBXYWl0cyBvbiBhIGNvbmRpdGlvbiB2YXJpYWJsZSB1bnRpbCBub3RpZmllZC4gVGhlIG5leHQgdGFzayB3aWxsCiAqIG5vdCBiZSBzY2hlZHVsZWQgdW50aWwgbm90aWZpY2F0aW9uLiBBIGNvbmRpdGlvbiB2YXJpYWJsZSBjYW4gYmUKICogY3JlYXRlZCB3aXRoIGZvcmdlLnRhc2suY3JlYXRlQ29uZGl0aW9uKCkuCiAqCiAqIE9uY2UgY29uZC5ub3RpZnkoKSBpcyBjYWxsZWQsIHRoZSB0YXNrIHdpbGwgY29udGludWUuCiAqCiAqIEBwYXJhbSBjb25kIHRoZSBjb25kaXRpb24gdmFyaWFibGUgdG8gd2FpdCBvbi4KICovClRhc2sucHJvdG90eXBlLndhaXQgPSBmdW5jdGlvbihjb25kKSB7CiAgY29uZC53YWl0KHRoaXMpOwp9OwoKLyoqCiAqIElmIHNsZWVwaW5nLCB3YWtldXAgYW5kIGNvbnRpbnVlIHJ1bm5pbmcgdGFza3MuCiAqLwpUYXNrLnByb3RvdHlwZS53YWtldXAgPSBmdW5jdGlvbigpIHsKICBpZih0aGlzLnN0YXRlID09PSBTTEVFUElORykgewogICAgY2FuY2VsVGltZW91dCh0aGlzLnRpbWVvdXRJZCk7CiAgICB0aGlzLnRpbWVvdXRJZCA9IG51bGw7CiAgICB0aGlzLnN0YXRlID0gUlVOTklORzsKICAgIHJ1bk5leHQodGhpcywgMCk7CiAgfQp9OwoKLyoqCiAqIENhbmNlbCBhbGwgcmVtYWluaW5nIHN1YnRhc2tzIG9mIHRoaXMgdGFzay4KICovClRhc2sucHJvdG90eXBlLmNhbmNlbCA9IGZ1bmN0aW9uKCkgewogIHRoaXMuc3RhdGUgPSBzU3RhdGVUYWJsZVt0aGlzLnN0YXRlXVtDQU5DRUxdOwogIC8vIHJlbW92ZSBwZXJtaXRzIG5lZWRlZAogIHRoaXMucGVybWl0c05lZWRlZCA9IDA7CiAgLy8gY2FuY2VsIHRpbWVvdXRzCiAgaWYodGhpcy50aW1lb3V0SWQgIT09IG51bGwpIHsKICAgIGNhbmNlbFRpbWVvdXQodGhpcy50aW1lb3V0SWQpOwogICAgdGhpcy50aW1lb3V0SWQgPSBudWxsOwogIH0KICAvLyByZW1vdmUgc3VidGFza3MKICB0aGlzLnN1YnRhc2tzID0gW107Cn07CgovKioKICogRmluaXNoZXMgdGhpcyB0YXNrIHdpdGggZmFpbHVyZSBhbmQgc2V0cyBlcnJvciBmbGFnLiBUaGUgZW50aXJlCiAqIHRhc2sgd2lsbCBiZSBhYm9ydGVkIHVubGVzcyB0aGUgbmV4dCB0YXNrIHRoYXQgc2hvdWxkIGV4ZWN1dGUKICogaXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyLiBUaGlzIGFsbG93cyBsZXZlbHMgb2Ygc3VidGFza3MgdG8gYmUKICogc2tpcHBlZC4gRm9yIGluc3RhbmNlLCB0byBhYm9ydCBvbmx5IHRoaXMgdGFza3MncyBzdWJ0YXNrcywgdGhlbgogKiBjYWxsIGZhaWwodGFzay5wYXJlbnQpLiBUbyBhYm9ydCB0aGlzIHRhc2sncyBzdWJ0YXNrcyBhbmQgaXRzCiAqIHBhcmVudCdzIHN1YnRhc2tzLCBjYWxsIGZhaWwodGFzay5wYXJlbnQucGFyZW50KS4gVG8gYWJvcnQKICogYWxsIHRhc2tzIGFuZCBzaW1wbHkgY2FsbCB0aGUgdGFzayBjYWxsYmFjaywgY2FsbCBmYWlsKCkgb3IKICogZmFpbChudWxsKS4KICoKICogVGhlIHRhc2sgY2FsbGJhY2sgKHN1Y2Nlc3Mgb3IgZmFpbHVyZSkgd2lsbCBhbHdheXMsIGV2ZW50dWFsbHksIGJlCiAqIGNhbGxlZC4KICoKICogQHBhcmFtIG5leHQgdGhlIHRhc2sgdG8gY29udGludWUgYXQsIG9yIG51bGwgdG8gYWJvcnQgZW50aXJlbHkuCiAqLwpUYXNrLnByb3RvdHlwZS5mYWlsID0gZnVuY3Rpb24obmV4dCkgewogIC8vIHNldCBlcnJvciBmbGFnCiAgdGhpcy5lcnJvciA9IHRydWU7CgogIC8vIGZpbmlzaCB0YXNrCiAgZmluaXNoKHRoaXMsIHRydWUpOwoKICBpZihuZXh0KSB7CiAgICAvLyBwcm9wYWdhdGUgdGFzayBpbmZvCiAgICBuZXh0LmVycm9yID0gdGhpcy5lcnJvcjsKICAgIG5leHQuc3dhcFRpbWUgPSB0aGlzLnN3YXBUaW1lOwogICAgbmV4dC51c2VyRGF0YSA9IHRoaXMudXNlckRhdGE7CgogICAgLy8gZG8gbmV4dCB0YXNrIGFzIHNwZWNpZmllZAogICAgcnVuTmV4dChuZXh0LCAwKTsKICB9IGVsc2UgewogICAgaWYodGhpcy5wYXJlbnQgIT09IG51bGwpIHsKICAgICAgLy8gZmluaXNoIHJvb3QgdGFzayAoZW5zdXJlcyBpdCBpcyByZW1vdmVkIGZyb20gdGFzayBxdWV1ZSkKICAgICAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50OwogICAgICB3aGlsZShwYXJlbnQucGFyZW50ICE9PSBudWxsKSB7CiAgICAgICAgLy8gcHJvcGFnYXRlIHRhc2sgaW5mbwogICAgICAgIHBhcmVudC5lcnJvciA9IHRoaXMuZXJyb3I7CiAgICAgICAgcGFyZW50LnN3YXBUaW1lID0gdGhpcy5zd2FwVGltZTsKICAgICAgICBwYXJlbnQudXNlckRhdGEgPSB0aGlzLnVzZXJEYXRhOwogICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnQ7CiAgICAgIH0KICAgICAgZmluaXNoKHBhcmVudCwgdHJ1ZSk7CiAgICB9CgogICAgLy8gY2FsbCBmYWlsdXJlIGNhbGxiYWNrIGlmIG9uZSBleGlzdHMKICAgIGlmKHRoaXMuZmFpbHVyZUNhbGxiYWNrKSB7CiAgICAgIHRoaXMuZmFpbHVyZUNhbGxiYWNrKHRoaXMpOwogICAgfQogIH0KfTsKCi8qKgogKiBBc3luY2hyb25vdXNseSBzdGFydCBhIHRhc2suCiAqCiAqIEBwYXJhbSB0YXNrIHRoZSB0YXNrIHRvIHN0YXJ0LgogKi8KdmFyIHN0YXJ0ID0gZnVuY3Rpb24odGFzaykgewogIHRhc2suZXJyb3IgPSBmYWxzZTsKICB0YXNrLnN0YXRlID0gc1N0YXRlVGFibGVbdGFzay5zdGF0ZV1bU1RBUlRdOwogIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7CiAgICBpZih0YXNrLnN0YXRlID09PSBSVU5OSU5HKSB7CiAgICAgIHRhc2suc3dhcFRpbWUgPSArbmV3IERhdGUoKTsKICAgICAgdGFzay5ydW4odGFzayk7CiAgICAgIHJ1bk5leHQodGFzaywgMCk7CiAgICB9CiAgfSwgMCk7Cn07CgovKioKICogUnVuIHRoZSBuZXh0IHN1YnRhc2sgb3IgZmluaXNoIHRoaXMgdGFzay4KICoKICogQHBhcmFtIHRhc2sgdGhlIHRhc2sgdG8gcHJvY2Vzcy4KICogQHBhcmFtIHJlY3Vyc2UgdGhlIHJlY3Vyc2lvbiBjb3VudC4KICovCnZhciBydW5OZXh0ID0gZnVuY3Rpb24odGFzaywgcmVjdXJzZSkgewogIC8vIGdldCB0aW1lIHNpbmNlIGxhc3QgY29udGV4dCBzd2FwIChtcyksIGlmIGVub3VnaCB0aW1lIGhhcyBwYXNzZWQgc2V0CiAgLy8gc3dhcCB0byB0cnVlIHRvIGluZGljYXRlIHRoYXQgZG9OZXh0IHdhcyBwZXJmb3JtZWQgYXN5bmNocm9ub3VzbHkKICAvLyBhbHNvLCBpZiByZWN1cnNlIGlzIHRvbyBoaWdoIGRvIGFzeW5jaHJvbm91c2x5CiAgdmFyIHN3YXAgPQogICAgKHJlY3Vyc2UgPiBzTWF4UmVjdXJzaW9ucykgfHwKICAgICgrbmV3IERhdGUoKSAtIHRhc2suc3dhcFRpbWUpID4gc1RpbWVTbGljZTsKCiAgdmFyIGRvTmV4dCA9IGZ1bmN0aW9uKHJlY3Vyc2UpIHsKICAgIHJlY3Vyc2UrKzsKICAgIGlmKHRhc2suc3RhdGUgPT09IFJVTk5JTkcpIHsKICAgICAgaWYoc3dhcCkgewogICAgICAgIC8vIHVwZGF0ZSBzd2FwIHRpbWUKICAgICAgICB0YXNrLnN3YXBUaW1lID0gK25ldyBEYXRlKCk7CiAgICAgIH0KCiAgICAgIGlmKHRhc2suc3VidGFza3MubGVuZ3RoID4gMCkgewogICAgICAgIC8vIHJ1biBuZXh0IHN1YnRhc2sKICAgICAgICB2YXIgc3VidGFzayA9IHRhc2suc3VidGFza3Muc2hpZnQoKTsKICAgICAgICBzdWJ0YXNrLmVycm9yID0gdGFzay5lcnJvcjsKICAgICAgICBzdWJ0YXNrLnN3YXBUaW1lID0gdGFzay5zd2FwVGltZTsKICAgICAgICBzdWJ0YXNrLnVzZXJEYXRhID0gdGFzay51c2VyRGF0YTsKICAgICAgICBzdWJ0YXNrLnJ1bihzdWJ0YXNrKTsKICAgICAgICBpZighc3VidGFzay5lcnJvcikgewogICAgICAgICAgIHJ1bk5leHQoc3VidGFzaywgcmVjdXJzZSk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGZpbmlzaCh0YXNrKTsKCiAgICAgICAgaWYoIXRhc2suZXJyb3IpIHsKICAgICAgICAgIC8vIGNoYWluIGJhY2sgdXAgYW5kIHJ1biBwYXJlbnQKICAgICAgICAgIGlmKHRhc2sucGFyZW50ICE9PSBudWxsKSB7CiAgICAgICAgICAgIC8vIHByb3BhZ2F0ZSB0YXNrIGluZm8KICAgICAgICAgICAgdGFzay5wYXJlbnQuZXJyb3IgPSB0YXNrLmVycm9yOwogICAgICAgICAgICB0YXNrLnBhcmVudC5zd2FwVGltZSA9IHRhc2suc3dhcFRpbWU7CiAgICAgICAgICAgIHRhc2sucGFyZW50LnVzZXJEYXRhID0gdGFzay51c2VyRGF0YTsKCiAgICAgICAgICAgIC8vIG5vIHN1YnRhc2tzIGxlZnQsIGNhbGwgcnVuIG5leHQgc3VidGFzayBvbiBwYXJlbnQKICAgICAgICAgICAgcnVuTmV4dCh0YXNrLnBhcmVudCwgcmVjdXJzZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKCiAgaWYoc3dhcCkgewogICAgLy8gd2UncmUgc3dhcHBpbmcsIHNvIHJ1biBhc3luY2hyb25vdXNseQogICAgc2V0VGltZW91dChkb05leHQsIDApOwogIH0gZWxzZSB7CiAgICAvLyBub3Qgc3dhcHBpbmcsIHNvIHJ1biBzeW5jaHJvbm91c2x5CiAgICBkb05leHQocmVjdXJzZSk7CiAgfQp9OwoKLyoqCiAqIEZpbmlzaGVzIGEgdGFzayBhbmQgbG9va3MgZm9yIHRoZSBuZXh0IHRhc2sgaW4gdGhlIHF1ZXVlIHRvIHN0YXJ0LgogKgogKiBAcGFyYW0gdGFzayB0aGUgdGFzayB0byBmaW5pc2guCiAqIEBwYXJhbSBzdXBwcmVzc0NhbGxiYWNrcyB0cnVlIHRvIHN1cHByZXNzIGNhbGxiYWNrcy4KICovCnZhciBmaW5pc2ggPSBmdW5jdGlvbih0YXNrLCBzdXBwcmVzc0NhbGxiYWNrcykgewogIC8vIHN1YnRhc2sgaXMgbm93IGRvbmUKICB0YXNrLnN0YXRlID0gRE9ORTsKCiAgZGVsZXRlIHNUYXNrc1t0YXNrLmlkXTsKICBpZihzVkwgPj0gMSkgewogICAgZm9yZ2UubG9nLnZlcmJvc2UoY2F0LCAnWyVzXVslc10gZmluaXNoJywKICAgICAgdGFzay5pZCwgdGFzay5uYW1lLCB0YXNrKTsKICB9CgogIC8vIG9ubHkgZG8gcXVldWUgcHJvY2Vzc2luZyBmb3Igcm9vdCB0YXNrcwogIGlmKHRhc2sucGFyZW50ID09PSBudWxsKSB7CiAgICAvLyByZXBvcnQgZXJyb3IgaWYgcXVldWUgaXMgbWlzc2luZwogICAgaWYoISh0YXNrLnR5cGUgaW4gc1Rhc2tRdWV1ZXMpKSB7CiAgICAgIGZvcmdlLmxvZy5lcnJvcihjYXQsCiAgICAgICAgJ1slc11bJXNdIHRhc2sgcXVldWUgbWlzc2luZyBbJXNdJywKICAgICAgICB0YXNrLmlkLCB0YXNrLm5hbWUsIHRhc2sudHlwZSk7CiAgICB9IGVsc2UgaWYoc1Rhc2tRdWV1ZXNbdGFzay50eXBlXS5sZW5ndGggPT09IDApIHsKICAgICAgLy8gcmVwb3J0IGVycm9yIGlmIHF1ZXVlIGlzIGVtcHR5CiAgICAgIGZvcmdlLmxvZy5lcnJvcihjYXQsCiAgICAgICAgJ1slc11bJXNdIHRhc2sgcXVldWUgZW1wdHkgWyVzXScsCiAgICAgICAgdGFzay5pZCwgdGFzay5uYW1lLCB0YXNrLnR5cGUpOwogICAgfSBlbHNlIGlmKHNUYXNrUXVldWVzW3Rhc2sudHlwZV1bMF0gIT09IHRhc2spIHsKICAgICAgLy8gcmVwb3J0IGVycm9yIGlmIHRoaXMgdGFzayBpc24ndCB0aGUgZmlyc3QgaW4gdGhlIHF1ZXVlCiAgICAgIGZvcmdlLmxvZy5lcnJvcihjYXQsCiAgICAgICAgJ1slc11bJXNdIHRhc2sgbm90IGZpcnN0IGluIHF1ZXVlIFslc10nLAogICAgICAgIHRhc2suaWQsIHRhc2submFtZSwgdGFzay50eXBlKTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIHJlbW92ZSBvdXJzZWx2ZXMgZnJvbSB0aGUgcXVldWUKICAgICAgc1Rhc2tRdWV1ZXNbdGFzay50eXBlXS5zaGlmdCgpOwogICAgICAvLyBjbGVhbiB1cCBxdWV1ZSBpZiBpdCBpcyBlbXB0eQogICAgICBpZihzVGFza1F1ZXVlc1t0YXNrLnR5cGVdLmxlbmd0aCA9PT0gMCkgewogICAgICAgIGlmKHNWTCA+PSAxKSB7CiAgICAgICAgICBmb3JnZS5sb2cudmVyYm9zZShjYXQsICdbJXNdWyVzXSBkZWxldGUgcXVldWUgWyVzXScsCiAgICAgICAgICAgIHRhc2suaWQsIHRhc2submFtZSwgdGFzay50eXBlKTsKICAgICAgICB9CiAgICAgICAgLyogTm90ZTogT25seSBhIHRhc2sgY2FuIGRlbGV0ZSBhIHF1ZXVlIG9mIGl0cyBvd24gdHlwZS4gVGhpcwogICAgICAgICBpcyB1c2VkIGFzIGEgd2F5IHRvIHN5bmNocm9uaXplIHRhc2tzLiBJZiBhIHF1ZXVlIGZvciBhIGNlcnRhaW4KICAgICAgICAgdGFzayB0eXBlIGV4aXN0cywgdGhlbiBhIHRhc2sgb2YgdGhhdCB0eXBlIGlzIHJ1bm5pbmcuCiAgICAgICAgICovCiAgICAgICAgZGVsZXRlIHNUYXNrUXVldWVzW3Rhc2sudHlwZV07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gZGVxdWV1ZSB0aGUgbmV4dCB0YXNrIGFuZCBzdGFydCBpdAogICAgICAgIGlmKHNWTCA+PSAxKSB7CiAgICAgICAgICBmb3JnZS5sb2cudmVyYm9zZShjYXQsCiAgICAgICAgICAgICdbJXNdWyVzXSBxdWV1ZSBzdGFydCBuZXh0IFslc10gcmVtYWluOiVzJywKICAgICAgICAgICAgdGFzay5pZCwgdGFzay5uYW1lLCB0YXNrLnR5cGUsCiAgICAgICAgICAgIHNUYXNrUXVldWVzW3Rhc2sudHlwZV0ubGVuZ3RoKTsKICAgICAgICB9CiAgICAgICAgc1Rhc2tRdWV1ZXNbdGFzay50eXBlXVswXS5zdGFydCgpOwogICAgICB9CiAgICB9CgogICAgaWYoIXN1cHByZXNzQ2FsbGJhY2tzKSB7CiAgICAgIC8vIGNhbGwgZmluYWwgY2FsbGJhY2sgaWYgb25lIGV4aXN0cwogICAgICBpZih0YXNrLmVycm9yICYmIHRhc2suZmFpbHVyZUNhbGxiYWNrKSB7CiAgICAgICAgdGFzay5mYWlsdXJlQ2FsbGJhY2sodGFzayk7CiAgICAgIH0gZWxzZSBpZighdGFzay5lcnJvciAmJiB0YXNrLnN1Y2Nlc3NDYWxsYmFjaykgewogICAgICAgIHRhc2suc3VjY2Vzc0NhbGxiYWNrKHRhc2spOwogICAgICB9CiAgICB9CiAgfQp9OwoKLyogVGFza3MgQVBJICovCmZvcmdlLnRhc2sgPSBmb3JnZS50YXNrIHx8IHt9OwoKLyoqCiAqIFN0YXJ0cyBhIG5ldyB0YXNrIHRoYXQgd2lsbCBydW4gdGhlIHBhc3NlZCBmdW5jdGlvbiBhc3luY2hyb25vdXNseS4KICoKICogSW4gb3JkZXIgdG8gZmluaXNoIHRoZSB0YXNrLCBlaXRoZXIgdGFzay5kb05leHQoKSBvciB0YXNrLmZhaWwoKQogKiAqbXVzdCogYmUgY2FsbGVkLgogKgogKiBUaGUgdGFzayBtdXN0IGhhdmUgYSB0eXBlIChhIHN0cmluZyBpZGVudGlmaWVyKSB0aGF0IGNhbiBiZSB1c2VkIHRvCiAqIHN5bmNocm9uaXplIGl0IHdpdGggb3RoZXIgdGFza3Mgb2YgdGhlIHNhbWUgdHlwZS4gVGhhdCB0eXBlIGNhbiBhbHNvCiAqIGJlIHVzZWQgdG8gY2FuY2VsIHRhc2tzIHRoYXQgaGF2ZW4ndCBzdGFydGVkIHlldC4KICoKICogVG8gc3RhcnQgYSB0YXNrLCB0aGUgZm9sbG93aW5nIG9iamVjdCBtdXN0IGJlIHByb3ZpZGVkIGFzIGEgcGFyYW1ldGVyCiAqIChlYWNoIGZ1bmN0aW9uIHRha2VzIGEgdGFzayBvYmplY3QgYXMgaXRzIGZpcnN0IHBhcmFtZXRlcik6CiAqCiAqIHsKICogICB0eXBlOiB0aGUgdHlwZSBvZiB0YXNrLgogKiAgIHJ1bjogdGhlIGZ1bmN0aW9uIHRvIHJ1biB0byBleGVjdXRlIHRoZSB0YXNrLgogKiAgIHN1Y2Nlc3M6IGEgY2FsbGJhY2sgdG8gY2FsbCB3aGVuIHRoZSB0YXNrIHN1Y2NlZWRzIChvcHRpb25hbCkuCiAqICAgZmFpbHVyZTogYSBjYWxsYmFjayB0byBjYWxsIHdoZW4gdGhlIHRhc2sgZmFpbHMgKG9wdGlvbmFsKS4KICogfQogKgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb2JqZWN0IGFzIGRlc2NyaWJlZCBhYm92ZS4KICovCmZvcmdlLnRhc2suc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgLy8gY3JlYXRlIGEgbmV3IHRhc2sKICB2YXIgdGFzayA9IG5ldyBUYXNrKHsKICAgIHJ1bjogb3B0aW9ucy5ydW4sCiAgICBuYW1lOiBvcHRpb25zLm5hbWUgfHwgc05vVGFza05hbWUKICB9KTsKICB0YXNrLnR5cGUgPSBvcHRpb25zLnR5cGU7CiAgdGFzay5zdWNjZXNzQ2FsbGJhY2sgPSBvcHRpb25zLnN1Y2Nlc3MgfHwgbnVsbDsKICB0YXNrLmZhaWx1cmVDYWxsYmFjayA9IG9wdGlvbnMuZmFpbHVyZSB8fCBudWxsOwoKICAvLyBhcHBlbmQgdGhlIHRhc2sgb250byB0aGUgYXBwcm9wcmlhdGUgcXVldWUKICBpZighKHRhc2sudHlwZSBpbiBzVGFza1F1ZXVlcykpIHsKICAgIGlmKHNWTCA+PSAxKSB7CiAgICAgIGZvcmdlLmxvZy52ZXJib3NlKGNhdCwgJ1slc11bJXNdIGNyZWF0ZSBxdWV1ZSBbJXNdJywKICAgICAgICB0YXNrLmlkLCB0YXNrLm5hbWUsIHRhc2sudHlwZSk7CiAgICB9CiAgICAvLyBjcmVhdGUgdGhlIHF1ZXVlIHdpdGggdGhlIG5ldyB0YXNrCiAgICBzVGFza1F1ZXVlc1t0YXNrLnR5cGVdID0gW3Rhc2tdOwogICAgc3RhcnQodGFzayk7CiAgfSBlbHNlIHsKICAgIC8vIHB1c2ggdGhlIHRhc2sgb250byB0aGUgcXVldWUsIGl0IHdpbGwgYmUgcnVuIGFmdGVyIGEgdGFzawogICAgLy8gd2l0aCB0aGUgc2FtZSB0eXBlIGNvbXBsZXRlcwogICAgc1Rhc2tRdWV1ZXNbb3B0aW9ucy50eXBlXS5wdXNoKHRhc2spOwogIH0KfTsKCi8qKgogKiBDYW5jZWxzIGFsbCB0YXNrcyBvZiB0aGUgZ2l2ZW4gdHlwZSB0aGF0IGhhdmVuJ3Qgc3RhcnRlZCB5ZXQuCiAqCiAqIEBwYXJhbSB0eXBlIHRoZSB0eXBlIG9mIHRhc2sgdG8gY2FuY2VsLgogKi8KZm9yZ2UudGFzay5jYW5jZWwgPSBmdW5jdGlvbih0eXBlKSB7CiAgLy8gZmluZCB0aGUgdGFzayBxdWV1ZQogIGlmKHR5cGUgaW4gc1Rhc2tRdWV1ZXMpIHsKICAgIC8vIGVtcHR5IGFsbCBidXQgdGhlIGN1cnJlbnQgdGFzayBmcm9tIHRoZSBxdWV1ZQogICAgc1Rhc2tRdWV1ZXNbdHlwZV0gPSBbc1Rhc2tRdWV1ZXNbdHlwZV1bMF1dOwogIH0KfTsKCi8qKgogKiBDcmVhdGVzIGEgY29uZGl0aW9uIHZhcmlhYmxlIHRvIHN5bmNocm9uaXplIHRhc2tzLiBUbyBtYWtlIGEgdGFzayB3YWl0CiAqIG9uIHRoZSBjb25kaXRpb24gdmFyaWFibGUsIGNhbGwgdGFzay53YWl0KGNvbmRpdGlvbikuIFRvIG5vdGlmeSBhbGwKICogdGFza3MgdGhhdCBhcmUgd2FpdGluZywgY2FsbCBjb25kaXRpb24ubm90aWZ5KCkuCiAqCiAqIEByZXR1cm4gdGhlIGNvbmRpdGlvbiB2YXJpYWJsZS4KICovCmZvcmdlLnRhc2suY3JlYXRlQ29uZGl0aW9uID0gZnVuY3Rpb24oKSB7CiAgdmFyIGNvbmQgPSB7CiAgICAvLyBhbGwgdGFza3MgdGhhdCBhcmUgYmxvY2tlZAogICAgdGFza3M6IHt9CiAgfTsKCiAgLyoqCiAgICogQ2F1c2VzIHRoZSBnaXZlbiB0YXNrIHRvIGJsb2NrIHVudGlsIG5vdGlmeSBpcyBjYWxsZWQuIElmIHRoZSB0YXNrCiAgICogaXMgYWxyZWFkeSB3YWl0aW5nIG9uIHRoaXMgY29uZGl0aW9uIHRoZW4gdGhpcyBpcyBhIG5vLW9wLgogICAqCiAgICogQHBhcmFtIHRhc2sgdGhlIHRhc2sgdG8gY2F1c2UgdG8gd2FpdC4KICAgKi8KICBjb25kLndhaXQgPSBmdW5jdGlvbih0YXNrKSB7CiAgICAvLyBvbmx5IGJsb2NrIG9uY2UKICAgIGlmKCEodGFzay5pZCBpbiBjb25kLnRhc2tzKSkgewogICAgICAgdGFzay5ibG9jaygpOwogICAgICAgY29uZC50YXNrc1t0YXNrLmlkXSA9IHRhc2s7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogTm90aWZpZXMgYWxsIHdhaXRpbmcgdGFza3MgdG8gd2FrZSB1cC4KICAgKi8KICBjb25kLm5vdGlmeSA9IGZ1bmN0aW9uKCkgewogICAgLy8gc2luY2UgdW5ibG9jaygpIHdpbGwgcnVuIHRoZSBuZXh0IHRhc2sgZnJvbSBoZXJlLCBtYWtlIHN1cmUgdG8KICAgIC8vIGNsZWFyIHRoZSBjb25kaXRpb24ncyBibG9ja2VkIHRhc2sgbGlzdCBiZWZvcmUgdW5ibG9ja2luZwogICAgdmFyIHRtcCA9IGNvbmQudGFza3M7CiAgICBjb25kLnRhc2tzID0ge307CiAgICBmb3IodmFyIGlkIGluIHRtcCkgewogICAgICB0bXBbaWRdLnVuYmxvY2soKTsKICAgIH0KICB9OwoKICByZXR1cm4gY29uZDsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3Rhc2snOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvdGFzaycsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL2RlYnVnJywgJy4vbG9nJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBOb2RlLmpzIG1vZHVsZSBmb3IgRm9yZ2UuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAyMDExLTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKdmFyIG5hbWUgPSAnZm9yZ2UnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICAvLyBzZXQgdG8gdHJ1ZSB0byBkaXNhYmxlIG5hdGl2ZSBjb2RlIGlmIGV2ZW4gaXQncyBhdmFpbGFibGUKICAgICAgZm9yZ2UgPSB7ZGlzYWJsZU5hdGl2ZUNvZGU6IGZhbHNlfTsKICAgIH0KICAgIHJldHVybjsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZTsKICB9OwogIC8vIHNldCB0byB0cnVlIHRvIGRpc2FibGUgbmF0aXZlIGNvZGUgaWYgZXZlbiBpdCdzIGF2YWlsYWJsZQogIG1vZHVsZS5leHBvcnRzLmRpc2FibGVOYXRpdmVDb2RlID0gdHJ1ZTsKICBtb2R1bGUuZXhwb3J0cyhtb2R1bGUuZXhwb3J0cyk7Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9mb3JnZScsWwogICdyZXF1aXJlJywKICAnbW9kdWxlJywKICAnLi9hZXMnLAogICcuL2Flc0NpcGhlclN1aXRlcycsCiAgJy4vYXNuMScsCiAgJy4vY2lwaGVyJywKICAnLi9jaXBoZXJNb2RlcycsCiAgJy4vZGVidWcnLAogICcuL2RlcycsCiAgJy4vaG1hYycsCiAgJy4va2VtJywKICAnLi9sb2cnLAogICcuL21kJywKICAnLi9tZ2YxJywKICAnLi9wYmtkZjInLAogICcuL3BlbScsCiAgJy4vcGtjczcnLAogICcuL3BrY3MxJywKICAnLi9wa2NzMTInLAogICcuL3BraScsCiAgJy4vcHJpbWUnLAogICcuL3BybmcnLAogICcuL3BzcycsCiAgJy4vcmFuZG9tJywKICAnLi9yYzInLAogICcuL3NzaCcsCiAgJy4vdGFzaycsCiAgJy4vdGxzJywKICAnLi91dGlsJwpdLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCgpyZXR1cm4gcmVxdWlyZSgnanMvZm9yZ2UnKTsKCn0pOwovKioNCiogQGZpbGVvdmVydmlldyBJbnRlbChyKSBBTVQgQ2VydGlmaWNhdGUgZnVuY3Rpb25zDQoqIEBhdXRob3IgWWxpYW4gU2FpbnQtSGlsYWlyZQ0KKiBAdmVyc2lvbiB2MC4yLjBiDQoqLw0KDQovLyBDaGVjayB3aGljaCBrZXkgcGFpciBtYXRjaGVzIHRoZSBwdWJsaWMga2V5IGluIHRoZSBjZXJ0aWZpY2F0ZQ0KZnVuY3Rpb24gYW10Y2VydF9saW5rQ2VydFByaXZhdGVLZXkoY2VydHMsIGtleXMpIHsNCiAgICBmb3IgKHZhciBpIGluIGNlcnRzKSB7DQogICAgICAgIHZhciBjZXJ0ID0gY2VydHNbaV07DQogICAgICAgIHRyeSB7DQogICAgICAgICAgICBpZiAoeHhDZXJ0UHJpdmF0ZUtleXMubGVuZ3RoID09IDApIHJldHVybjsNCiAgICAgICAgICAgIHZhciBwdWJsaWNLZXlQRU0gPSBmb3JnZS5wa2kucHVibGljS2V5VG9QZW0oZm9yZ2UucGtpLmNlcnRpZmljYXRlRnJvbUFzbjEoZm9yZ2UuYXNuMS5mcm9tRGVyKGNlcnQuWDUwOUNlcnRpZmljYXRlKSkucHVibGljS2V5KS5zdWJzdHJpbmcoMjggKyAzMikucmVwbGFjZSgvKFxyXG58XG58XHIpL2dtLCAiIik7DQogICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGtleXMubGVuZ3RoOyBqKyspIHsNCiAgICAgICAgICAgICAgICBpZiAocHVibGljS2V5UEVNID09PSAoa2V5c1tqXVsnREVSS2V5J10gKyAnLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tJykpIHsNCiAgICAgICAgICAgICAgICAgICAga2V5c1tqXS5YQ2VydCA9IGNlcnQ7IC8vIExpbmsgdGhlIGtleSBwYWlyIHRvIHRoZSBjZXJ0aWZpY2F0ZQ0KICAgICAgICAgICAgICAgICAgICBjZXJ0LlhQcml2YXRlS2V5ID0ga2V5c1tqXTsgLy8gTGluayB0aGUgY2VydGlmaWNhdGUgdG8gdGhlIGtleSBwYWlyDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9IGNhdGNoIChlKSB7IGNvbnNvbGUubG9nKGUpOyB9DQogICAgfQ0KfQ0KDQovLyBMb2FkIGEgUDEyIGZpbGUsIGRlY29kZXMgaXQgdXNpbmcgdGhlIHBhc3N3b3JkIGFuZCByZXR1cm5zIHRoZSBwcml2YXRlIGtleSBoYW5kbGUNCmZ1bmN0aW9uIGFtdGNlcnRfbG9hZFAxMkZpbGUoZmlsZSwgcGFzc3dvcmQsIGZ1bmMpIHsNCiAgICB0cnkgew0KICAgICAgICAvLyBFbmNvZGUgaW4gQmFzZTY0IHNvIEZvcmdlIEFQSSBjYW4gcGFyc2UgaXQuDQogICAgICAgIHZhciBwMTJEZXIgPSB3aW5kb3cuZm9yZ2UudXRpbC5kZWNvZGU2NChidG9hKGZpbGUpKTsNCiAgICAgICAgdmFyIHAxMkFzbjEgPSB3aW5kb3cuZm9yZ2UuYXNuMS5mcm9tRGVyKHAxMkRlcik7DQogICAgICAgIHZhciBwMTIgPSB3aW5kb3cuZm9yZ2UucGtjczEyLnBrY3MxMkZyb21Bc24xKHAxMkFzbjEsIHBhc3N3b3JkKTsNCg0KICAgICAgICAvLyBQcml2YXRlIGtleSBpcyBzdG9yZWQgaW4gYSBzaHJvdWRlZCBrZXkgYmFnDQogICAgICAgIHZhciBiYWdzID0gcDEyLmdldEJhZ3MoeyBiYWdUeXBlOiB3aW5kb3cuZm9yZ2UucGtpLm9pZHMucGtjczhTaHJvdWRlZEtleUJhZyB9KTsNCiAgICAgICAgY29uc29sZS5hc3NlcnQoYmFnc1t3aW5kb3cuZm9yZ2UucGtpLm9pZHMucGtjczhTaHJvdWRlZEtleUJhZ10gJiYgYmFnc1t3aW5kb3cuZm9yZ2UucGtpLm9pZHMucGtjczhTaHJvdWRlZEtleUJhZ10ubGVuZ3RoID4gMCk7DQogICAgICAgIA0KICAgICAgICAvLyBJbXBvcnQgdGhlIEZvcmdlIHByaXZhdGUga2V5IHN0cnVjdHVyZSBpbnRvIFdlYiBDcnlwdG8NCiAgICAgICAgdmFyIHByaXZhdGVLZXkgPSBiYWdzW3dpbmRvdy5mb3JnZS5wa2kub2lkcy5wa2NzOFNocm91ZGVkS2V5QmFnXVswXS5rZXk7DQogICAgICAgIHZhciByc2FQcml2YXRlS2V5ID0gd2luZG93LmZvcmdlLnBraS5wcml2YXRlS2V5VG9Bc24xKHByaXZhdGVLZXkpOw0KICAgICAgICB2YXIgcHJpdmF0ZUtleUluZm8gPSB3aW5kb3cuZm9yZ2UucGtpLndyYXBSc2FQcml2YXRlS2V5KHJzYVByaXZhdGVLZXkpOw0KICAgICAgICB2YXIgcGtjczggPSB3aW5kb3cuZm9yZ2UuYXNuMS50b0Rlcihwcml2YXRlS2V5SW5mbykuZ2V0Qnl0ZXMoKTsNCiAgICAgICAgDQogICAgICAgIC8vIEdldCB0aGUgaXNzdWVyIGF0dHJpYnV0ZXMNCiAgICAgICAgdmFyIGNlcnRCYWdzID0gcDEyLmdldEJhZ3MoeyBiYWdUeXBlOiB3aW5kb3cuZm9yZ2UucGtpLm9pZHMuY2VydEJhZyB9KTsNCiAgICAgICAgdmFyIGlzc3VlckF0dHJpYnV0ZXMgPSBjZXJ0QmFnc1t3aW5kb3cuZm9yZ2UucGtpLm9pZHMuY2VydEJhZ11bMF0uY2VydC5zdWJqZWN0LmF0dHJpYnV0ZXM7DQoNCiAgICAgICAgdmFyIGJhZ3MxID0gcDEyLmdldEJhZ3MoeyBiYWdUeXBlOiBmb3JnZS5wa2kub2lkcy5jZXJ0QmFnIH0pOw0KICAgICAgICB2YXIgY2VydCA9IGJhZ3MxW2ZvcmdlLnBraS5vaWRzLmNlcnRCYWddWzBdLmNlcnQ7DQoNCiAgICAgICAgZnVuYyhwcml2YXRlS2V5LCBpc3N1ZXJBdHRyaWJ1dGVzLCBjZXJ0KTsNCiAgICAgICAgcmV0dXJuIHRydWU7DQogICAgfSBjYXRjaCAoZXgpIHsgfQ0KICAgIHJldHVybiBmYWxzZTsNCn0NCg0KZnVuY3Rpb24gYW10Y2VydF9zaWduV2l0aENhS2V5KERFUktleSwgY2FQcml2YXRlS2V5LCBjZXJ0QXR0cmlidXRlcywgaXNzdWVyQXR0cmlidXRlcywgZXh0S2V5VXNhZ2UpIHsNCiAgICBpZiAoIWNhUHJpdmF0ZUtleSB8fCBjYVByaXZhdGVLZXkgPT0gbnVsbCkgew0KICAgICAgICB2YXIgY2VydEFuZEtleSA9IGFtdGNlcnRfY3JlYXRlQ2VydGlmaWNhdGUoaXNzdWVyQXR0cmlidXRlcyk7DQogICAgICAgIGNhUHJpdmF0ZUtleSA9IGNlcnRBbmRLZXkua2V5Ow0KICAgIH0NCiAgICByZXR1cm4gYW10Y2VydF9jcmVhdGVDZXJ0aWZpY2F0ZShjZXJ0QXR0cmlidXRlcywgY2FQcml2YXRlS2V5LCBERVJLZXksIGlzc3VlckF0dHJpYnV0ZXMsIGV4dEtleVVzYWdlKTsNCn0NCg0KLy8gLS0tIEV4dGVuZGVkIEtleSBVc2FnZSBPSUQncyAtLS0NCi8vIDEuMy42LjEuNS41LjcuMy4xICAgICAgICAgICAgPSBUTFMgU2VydmVyIGNlcnRpZmljYXRlDQovLyAxLjMuNi4xLjUuNS43LjMuMiAgICAgICAgICAgID0gVExTIENsaWVudCBjZXJ0aWZpY2F0ZQ0KLy8gMi4xNi44NDAuMS4xMTM3NDEuMS4yLjEgICAgICA9IEludGVsIEFNVCBSZW1vdGUgQ29uc29sZQ0KLy8gMi4xNi44NDAuMS4xMTM3NDEuMS4yLjIgICAgICA9IEludGVsIEFNVCBMb2NhbCBDb25zb2xlDQovLyAyLjE2Ljg0MC4xLjExMzc0MS4xLjIuMyAgICAgID0gSW50ZWwgQU1UIENsaWVudCBTZXR1cCBDZXJ0aWZpY2F0ZSAoWmVyby1Ub3VjaCkNCg0KLy8gR2VuZXJhdGUgYSBjZXJ0aWZpY2F0ZSB3aXRoIGEgc2V0IG9mIGF0dHJpYnV0ZXMgc2lnbmVkIGJ5IGEgcm9vdENlcnQuIElmIHRoZSByb290Q2VydCBpcyBvYm1pdHRlZCwgdGhlIGdlbmVyYXRlZCBjZXJ0aWZpY2F0ZSBpcyBzZWxmLXNpZ25lZC4NCmZ1bmN0aW9uIGFtdGNlcnRfY3JlYXRlQ2VydGlmaWNhdGUoY2VydEF0dHJpYnV0ZXMsIGNhUHJpdmF0ZUtleSwgREVSS2V5LCBpc3N1ZXJBdHRyaWJ1dGVzLCBleHRLZXlVc2FnZSkgew0KICAgIC8vIEdlbmVyYXRlIGEga2V5cGFpciBhbmQgY3JlYXRlIGFuIFguNTA5djMgY2VydGlmaWNhdGUNCiAgICB2YXIga2V5cywgY2VydCA9IGZvcmdlLnBraS5jcmVhdGVDZXJ0aWZpY2F0ZSgpOw0KICAgIGlmICghREVSS2V5KSB7DQogICAgICAgIGtleXMgPSBmb3JnZS5wa2kucnNhLmdlbmVyYXRlS2V5UGFpcigyMDQ4KTsNCiAgICAgICAgY2VydC5wdWJsaWNLZXkgPSBrZXlzLnB1YmxpY0tleTsNCiAgICB9IGVsc2Ugew0KICAgICAgICBjZXJ0LnB1YmxpY0tleSA9IGZvcmdlLnBraS5wdWJsaWNLZXlGcm9tUGVtKCctLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLScgKyBERVJLZXkgKyAnLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tJyk7DQogICAgfQ0KICAgIGNlcnQuc2VyaWFsTnVtYmVyID0gJycgKyBNYXRoLmZsb29yKChNYXRoLnJhbmRvbSgpICogMTAwMDAwKSArIDEpOw0KICAgIGNlcnQudmFsaWRpdHkubm90QmVmb3JlID0gbmV3IERhdGUoKTsNCiAgICBjZXJ0LnZhbGlkaXR5Lm5vdEJlZm9yZS5zZXRGdWxsWWVhcihjZXJ0LnZhbGlkaXR5Lm5vdEJlZm9yZS5nZXRGdWxsWWVhcigpIC0gMSk7IC8vIENyZWF0ZSBhIGNlcnRpZmljYXRlIHRoYXQgaXMgdmFsaWQgb25lIHllYXIgYmVmb3JlLCB0byBtYWtlIHN1cmUgb3V0LW9mLXN5bmMgY2xvY2tzIGRvbid0IHJlamVjdCB0aGlzIGNlcnQuDQogICAgY2VydC52YWxpZGl0eS5ub3RBZnRlciA9IG5ldyBEYXRlKCk7DQogICAgY2VydC52YWxpZGl0eS5ub3RBZnRlci5zZXRGdWxsWWVhcihjZXJ0LnZhbGlkaXR5Lm5vdEFmdGVyLmdldEZ1bGxZZWFyKCkgKyAzMCk7DQogICAgdmFyIGF0dHJzID0gW107DQogICAgaWYgKGNlcnRBdHRyaWJ1dGVzWydDTiddKSBhdHRycy5wdXNoKHsgbmFtZTogJ2NvbW1vbk5hbWUnLCB2YWx1ZTogY2VydEF0dHJpYnV0ZXNbJ0NOJ10gfSk7DQogICAgaWYgKGNlcnRBdHRyaWJ1dGVzWydDJ10pIGF0dHJzLnB1c2goeyBuYW1lOiAnY291bnRyeU5hbWUnLCB2YWx1ZTogY2VydEF0dHJpYnV0ZXNbJ0MnXSB9KTsNCiAgICBpZiAoY2VydEF0dHJpYnV0ZXNbJ1NUJ10pIGF0dHJzLnB1c2goeyBzaG9ydE5hbWU6ICdTVCcsIHZhbHVlOiBjZXJ0QXR0cmlidXRlc1snU1QnXSB9KTsNCiAgICBpZiAoY2VydEF0dHJpYnV0ZXNbJ08nXSkgYXR0cnMucHVzaCh7IG5hbWU6ICdvcmdhbml6YXRpb25OYW1lJywgdmFsdWU6IGNlcnRBdHRyaWJ1dGVzWydPJ10gfSk7DQogICAgY2VydC5zZXRTdWJqZWN0KGF0dHJzKTsNCg0KICAgIGlmIChjYVByaXZhdGVLZXkpIHsNCiAgICAgICAgLy8gVXNlIHJvb3QgYXR0cmlidXRlcw0KICAgICAgICB2YXIgcm9vdGF0dHJzID0gW107DQogICAgICAgIGlmIChpc3N1ZXJBdHRyaWJ1dGVzWydDTiddKSByb290YXR0cnMucHVzaCh7IG5hbWU6ICdjb21tb25OYW1lJywgdmFsdWU6IGlzc3VlckF0dHJpYnV0ZXNbJ0NOJ10gfSk7DQogICAgICAgIGlmIChpc3N1ZXJBdHRyaWJ1dGVzWydDJ10pIHJvb3RhdHRycy5wdXNoKHsgbmFtZTogJ2NvdW50cnlOYW1lJywgdmFsdWU6IGlzc3VlckF0dHJpYnV0ZXNbJ0MnXSB9KTsNCiAgICAgICAgaWYgKGlzc3VlckF0dHJpYnV0ZXNbJ1NUJ10pIHJvb3RhdHRycy5wdXNoKHsgc2hvcnROYW1lOiAnU1QnLCB2YWx1ZTogaXNzdWVyQXR0cmlidXRlc1snU1QnXSB9KTsNCiAgICAgICAgaWYgKGlzc3VlckF0dHJpYnV0ZXNbJ08nXSkgcm9vdGF0dHJzLnB1c2goeyBuYW1lOiAnb3JnYW5pemF0aW9uTmFtZScsIHZhbHVlOiBpc3N1ZXJBdHRyaWJ1dGVzWydPJ10gfSk7DQogICAgICAgIGNlcnQuc2V0SXNzdWVyKHJvb3RhdHRycyk7DQogICAgfSBlbHNlIHsNCiAgICAgICAgLy8gVXNlIG91ciBvd24gYXR0cmlidXRlcw0KICAgICAgICBjZXJ0LnNldElzc3VlcihhdHRycyk7DQogICAgfQ0KDQogICAgaWYgKGNhUHJpdmF0ZUtleSA9PSB1bmRlZmluZWQpIHsNCiAgICAgICAgLy8gQ3JlYXRlIGEgcm9vdCBjZXJ0aWZpY2F0ZQ0KICAgICAgICBjZXJ0LnNldEV4dGVuc2lvbnMoW3sNCiAgICAgICAgICAgIG5hbWU6ICdiYXNpY0NvbnN0cmFpbnRzJywNCiAgICAgICAgICAgIGNBOiB0cnVlDQogICAgICAgIH0sIHsNCiAgICAgICAgICAgIG5hbWU6ICduc0NlcnRUeXBlJywNCiAgICAgICAgICAgIHNzbENBOiB0cnVlLA0KICAgICAgICAgICAgZW1haWxDQTogdHJ1ZSwNCiAgICAgICAgICAgIG9iakNBOiB0cnVlDQogICAgICAgIH0sIHsNCiAgICAgICAgICAgIG5hbWU6ICdzdWJqZWN0S2V5SWRlbnRpZmllcicNCiAgICAgICAgfV0pOw0KICAgIH0gZWxzZSB7DQogICAgICAgIGlmIChleHRLZXlVc2FnZSA9PSBudWxsKSB7IGV4dEtleVVzYWdlID0geyBuYW1lOiAnZXh0S2V5VXNhZ2UnLCBzZXJ2ZXJBdXRoOiB0cnVlLCB9IH0gZWxzZSB7IGV4dEtleVVzYWdlLm5hbWUgPSAnZXh0S2V5VXNhZ2UnOyB9DQoNCiAgICAgICAgLyoNCiAgICAgICAgew0KICAgICAgICAgICAgbmFtZTogJ2V4dEtleVVzYWdlJywNCiAgICAgICAgICAgIHNlcnZlckF1dGg6IHRydWUsDQogICAgICAgICAgICBjbGllbnRBdXRoOiB0cnVlLA0KICAgICAgICAgICAgY29kZVNpZ25pbmc6IHRydWUsDQogICAgICAgICAgICBlbWFpbFByb3RlY3Rpb246IHRydWUsDQogICAgICAgICAgICB0aW1lU3RhbXBpbmc6IHRydWUsDQogICAgICAgICAgICAnMi4xNi44NDAuMS4xMTM3NDEuMS4yLjEnOiB0cnVlDQogICAgICAgIH0NCiAgICAgICAgKi8NCg0KICAgICAgICAvLyBDcmVhdGUgYSBsZWFmIGNlcnRpZmljYXRlDQogICAgICAgIGNlcnQuc2V0RXh0ZW5zaW9ucyhbew0KICAgICAgICAgICAgbmFtZTogJ2Jhc2ljQ29uc3RyYWludHMnDQogICAgICAgIH0sIHsNCiAgICAgICAgICAgIG5hbWU6ICdrZXlVc2FnZScsDQogICAgICAgICAgICBrZXlDZXJ0U2lnbjogdHJ1ZSwNCiAgICAgICAgICAgIGRpZ2l0YWxTaWduYXR1cmU6IHRydWUsDQogICAgICAgICAgICBub25SZXB1ZGlhdGlvbjogdHJ1ZSwNCiAgICAgICAgICAgIGtleUVuY2lwaGVybWVudDogdHJ1ZSwNCiAgICAgICAgICAgIGRhdGFFbmNpcGhlcm1lbnQ6IHRydWUNCiAgICAgICAgfSwgZXh0S2V5VXNhZ2UsIHsNCiAgICAgICAgICAgIG5hbWU6ICduc0NlcnRUeXBlJywNCiAgICAgICAgICAgIGNsaWVudDogdHJ1ZSwNCiAgICAgICAgICAgIHNlcnZlcjogdHJ1ZSwNCiAgICAgICAgICAgIGVtYWlsOiB0cnVlLA0KICAgICAgICAgICAgb2Jqc2lnbjogdHJ1ZSwNCiAgICAgICAgfSwgew0KICAgICAgICAgICAgbmFtZTogJ3N1YmplY3RLZXlJZGVudGlmaWVyJw0KICAgICAgICB9XSk7DQogICAgfQ0KDQogICAgLy8gU2VsZi1zaWduIGNlcnRpZmljYXRlDQogICAgaWYgKGNhUHJpdmF0ZUtleSkgew0KICAgICAgICBjZXJ0LnNpZ24oY2FQcml2YXRlS2V5LCBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCkpOw0KICAgIH0gZWxzZSB7DQogICAgICAgIGNlcnQuc2lnbihrZXlzLnByaXZhdGVLZXksIGZvcmdlLm1kLnNoYTI1Ni5jcmVhdGUoKSk7DQogICAgfQ0KDQogICAgaWYgKERFUktleSkgew0KICAgICAgICByZXR1cm4gY2VydDsNCiAgICB9IGVsc2Ugew0KICAgICAgICByZXR1cm4geyAnY2VydCc6IGNlcnQsICdrZXknOiBrZXlzLnByaXZhdGVLZXkgfTsNCiAgICB9DQp9DQoNCmZ1bmN0aW9uIF9zdHJpbmdUb0FycmF5QnVmZmVyKHN0cikgew0KICAgIHZhciBidWYgPSBuZXcgQXJyYXlCdWZmZXIoc3RyLmxlbmd0aCk7DQogICAgdmFyIGJ1ZlZpZXcgPSBuZXcgVWludDhBcnJheShidWYpOw0KICAgIGZvciAodmFyIGkgPSAwLCBzdHJMZW4gPSBzdHIubGVuZ3RoOyBpIDwgc3RyTGVuOyBpKyspIHsgYnVmVmlld1tpXSA9IHN0ci5jaGFyQ29kZUF0KGkpOyB9DQogICAgcmV0dXJuIGJ1ZjsNCn0NCg0KZnVuY3Rpb24gX2FycmF5QnVmZmVyVG9TdHJpbmcoYnVmZmVyKSB7DQogICAgdmFyIGJpbmFyeSA9ICcnOw0KICAgIHZhciBieXRlcyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7DQogICAgdmFyIGxlbiA9IGJ5dGVzLmJ5dGVMZW5ndGg7DQogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykgeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7IH0NCiAgICByZXR1cm4gYmluYXJ5Ow0KfQ0KLyoqDQoqIEBmaWxlb3ZlcnZpZXcgU2NyaXB0IENvbXBpbGVyIC8gRGVjb21waWxlciAvIFJ1bm5lcg0KKiBAYXV0aG9yIFlsaWFuIFNhaW50LUhpbGFpcmUNCiogQHZlcnNpb24gdjAuMS4wZQ0KKi8NCg0KLy8gQ29yZSBmdW5jdGlvbnMNCnNjcmlwdF9mdW5jdGlvblRhYmxlMSA9IFsnbm9wJywgJ2p1bXAnLCAnc2V0JywgJ3ByaW50JywgJ2RpYWxvZycsICdnZXRpdGVtJywgJ3N1YnN0cicsICdpbmRleG9mJywgJ3NwbGl0JywgJ2pvaW4nLCAnbGVuZ3RoJywgJ2pzb25wYXJzZScsICdqc29uc3RyJywgJ2FkZCcsICdzdWJzdHJhY3QnLCAncGFyc2VpbnQnLCAnd3NiYXRjaGVudW0nLCAnd3NwdXQnLCAnd3NjcmVhdGUnLCAnd3NkZWxldGUnLCAnd3NleGVjJywgJ3NjcmlwdHNwZWVkJywgJ3dzc3Vic2NyaWJlJywgJ3dzdW5zdWJzY3JpYmUnLCAncmVhZGNoYXInLCAnc2lnbndpdGhkdW1teWNhJ107DQoNCi8vIGZ1bmN0aW9ucyBvZiB0eXBlIEFSRzEgPSBmdW5jKEFSRzIsIEFSRzMsIEFSRzQsIEFSRzUsIEFSRzYpDQpzY3JpcHRfZnVuY3Rpb25UYWJsZTIgPSBbJ2VuY29kZXVyaScsICdkZWNvZGV1cmknLCAncGFzc3dvcmRjaGVjaycsICdhdG9iJywgJ2J0b2EnLCAnaGV4MnN0cicsICdzdHIyaGV4JywgJ3JhbmRvbScsICdtZDUnLCAnbWFrZXRvYXJyYXknLCAncmVhZHNob3J0JywgJ3JlYWRzaG9ydHgnLCAncmVhZGludCcsICdyZWFkc2ludCcsICdyZWFkaW50eCcsICdzaG9ydHRvc3RyJywgJ3Nob3J0dG9zdHJ4JywgJ2ludHRvc3RyJywgJ2ludHRvc3RyeCddOw0KDQovLyBmdW5jdGlvbnMgb2YgdHlwZSBBUkcxID0gZnVuYyhBUkcyLCBBUkczLCBBUkc0LCBBUkc1LCBBUkc2KQ0Kc2NyaXB0X2Z1bmN0aW9uVGFibGVYMiA9IFtlbmNvZGVVUkksIGRlY29kZVVSSSwgcGFzc3dvcmRjaGVjaywgd2luZG93LmF0b2IuYmluZCh3aW5kb3cpLCB3aW5kb3cuYnRvYS5iaW5kKHdpbmRvdyksIGhleDJyc3RyLCByc3RyMmhleCwgcmFuZG9tLCByc3RyX21kNSwgTWFrZVRvQXJyYXksIFJlYWRTaG9ydCwgUmVhZFNob3J0WCwgUmVhZEludCwgUmVhZFNJbnQsIFJlYWRJbnRYLCBTaG9ydFRvU3RyLCBTaG9ydFRvU3RyWCwgSW50VG9TdHIsIEludFRvU3RyWF07DQoNCi8vIE9wdGlvbmFsIGZ1bmN0aW9ucyBvZiB0eXBlIEFSRzEgPSBmdW5jKEFSRzIsIEFSRzMsIEFSRzQsIEFSRzUsIEFSRzYpDQpzY3JpcHRfZnVuY3Rpb25UYWJsZTMgPSBbJ3B1bGxzeXN0ZW1zdGF0dXMnLCAncHVsbGV2ZW50bG9nJywgJ3B1bGxhdWRpdGxvZycsICdwdWxsY2VydGlmaWNhdGVzJywgJ3B1bGx3YXRjaGRvZycsICdwdWxsc3lzdGVtZGVmZW5zZScsICdwdWxsaGFyZHdhcmUnLCAncHVsbHVzZXJpbmZvJywgJ3B1bGxyZW1vdGVhY2Nlc3MnLCAnaGlnaGxpZ2h0YmxvY2snLCAnZGlzY29ubmVjdCcsICdnZXRzaWRzdHJpbmcnLCAnZ2V0c2lkYnl0ZWFycmF5JywgJ3B1bGxldmVudHN1YnNjcmlwdGlvbnMnXTsNCg0KLy8gT3B0aW9uYWwgZnVuY3Rpb25zIG9mIHR5cGUgQVJHMSA9IGZ1bmMoQVJHMiwgQVJHMywgQVJHNCwgQVJHNSwgQVJHNikNCnNjcmlwdF9mdW5jdGlvblRhYmxlWDMgPSBbDQogICAgUHVsbFN5c3RlbVN0YXR1cw0KICAgICwNCiAgICANCiAgICBQdWxsRXZlbnRMb2cNCiAgICAgICAgLA0KICAgIA0KICAgIFB1bGxBdWRpdExvZw0KICAgICAgICAsDQogICAgDQogICAgUHVsbENlcnRpZmljYXRlcw0KICAgICAgICAsDQogICAgDQogICAgUHVsbFdhdGNoZG9nDQogICAgICAgICwNCiAgICANCiAgICBQdWxsU3lzdGVtRGVmZW5zZQ0KICAgICAgICAsDQogICAgDQogICAgUHVsbEhhcmR3YXJlDQogICAgICAgICwNCiAgICBQdWxsVXNlckluZm8NCiAgICAsDQogICAgDQogICAgUHVsbFJlbW90ZUFjY2Vzcw0KICAgICAgICAsDQogICAgDQogICAgc2NyaXB0X0hpZ2hsaWdodEJsb2NrDQogICAgICAgICwNCiAgICAgICAgLA0KICAgIGZ1bmN0aW9uIChydW5uZXIsIHgpIHsgcmV0dXJuIEdldFNpZFN0cmluZyh4KTsgfQ0KICAgICwNCiAgICBmdW5jdGlvbiAocnVubmVyLCB4KSB7IHJldHVybiBHZXRTaWRCeXRlQXJyYXkoeCk7IH0NCiAgICAsDQogICAgXTsNCg0KLy8gU2V0dXAgdGhlIHNjcmlwdCBzdGF0ZQ0KZnVuY3Rpb24gc2NyaXB0X3NldHVwKGJpbmFyeSwgc3RhcnR2YXJzKSB7DQogICAgdmFyIG9iaiA9IHsgc3RhcnR2YXJzOnN0YXJ0dmFycyB9Ow0KICAgIGlmIChiaW5hcnkubGVuZ3RoIDwgNikgeyBjb25zb2xlLmVycm9yKCdJbnZhbGlkIHNjcmlwdCBsZW5ndGgnKTsgcmV0dXJuIG51bGw7IH0gLy8gU2NyaXB0IG11c3QgaGF2ZSBhdCBsZWFzdCA2IGJ5dGUgaGVhZGVyDQogICAgaWYgKFJlYWRJbnQoYmluYXJ5LCAwKSAhPSAweDI0N0QyOTQ1KSB7IGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgYmluYXJ5IHNjcmlwdCcpOyByZXR1cm4gbnVsbDsgfSAvLyBDaGVjayB0aGUgc2NyaXB0IG1hZ2ljIGhlYWRlcg0KICAgIGlmIChSZWFkU2hvcnQoYmluYXJ5LCA0KSA+IDEpIHsgY29uc29sZS5lcnJvcignVW5zdXBwb3J0ZWQgc2NyaXB0IHZlcnNpb24nKTsgcmV0dXJuIG51bGw7IH0gLy8gQ2hlY2sgdGhlIHNjcmlwdCB2ZXJzaW9uDQogICAgb2JqLnNjcmlwdCA9IGJpbmFyeS5zdWJzdHJpbmcoNik7DQogICAgLy8gb2JqLm9uU3RlcDsNCiAgICAvLyBvYmoub25Db25zb2xlOw0KDQogICAgLy8gUmVzZXQgdGhlIHNjcmlwdCB0byB0aGUgc3RhcnQNCiAgICBvYmoucmVzZXQgPSBmdW5jdGlvbiAoc3RlcHNwZWVkKSB7DQogICAgICAgIG9iai5zdG9wKCk7DQogICAgICAgIG9iai5pcCA9IDA7DQogICAgICAgIG9iai52YXJpYWJsZXMgPSBzdGFydHZhcnM7DQogICAgICAgIG9iai5zdGF0ZSA9IDE7DQogICAgfQ0KDQogICAgLy8gU3RhcnQgdGhlIHNjcmlwdA0KICAgIG9iai5zdGFydCA9IGZ1bmN0aW9uIChzdGVwc3BlZWQpIHsNCiAgICAgICAgb2JqLnN0b3AoKTsNCiAgICAgICAgb2JqLnN0ZXBzcGVlZCA9IHN0ZXBzcGVlZDsNCiAgICAgICAgaWYgKHN0ZXBzcGVlZCA+IDApIHsgb2JqLnRpbWVyID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkgeyBvYmouc3RlcCgpIH0sIHN0ZXBzcGVlZCk7IH0NCiAgICB9DQoNCiAgICAvLyBTdG9wIHRoZSBzY3JpcHQNCiAgICBvYmouc3RvcCA9IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgaWYgKG9iai50aW1lciAhPSBudWxsKSB7IGNsZWFySW50ZXJ2YWwob2JqLnRpbWVyKTsgfQ0KICAgICAgICBvYmoudGltZXIgPSBudWxsOw0KICAgICAgICBvYmouc3RlcHNwZWVkID0gMDsNCiAgICB9DQoNCiAgICAvLyBmdW5jdGlvbiB1c2VkIHRvIGxvYWQgYW5kIHN0b3JlIHZhcmlhYmxlIHZhbHVlcw0KICAgIG9iai5nZXRWYXIgPSBmdW5jdGlvbiAobmFtZSkgeyBpZiAobmFtZSA9PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7IHJldHVybiBvYmouZ2V0VmFyRXgobmFtZS5zcGxpdCgnLicpLCBvYmoudmFyaWFibGVzKTsgfQ0KICAgIG9iai5nZXRWYXJFeCA9IGZ1bmN0aW9uIChuYW1lLCB2YWwpIHsgdHJ5IHsgaWYgKG5hbWUgPT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkOyBpZiAobmFtZS5sZW5ndGggPT0gMCkgcmV0dXJuIHZhbDsgcmV0dXJuIG9iai5nZXRWYXJFeChuYW1lLnNsaWNlKDEpLCB2YWxbbmFtZVswXV0pOyB9IGNhdGNoIChlKSB7IHJldHVybiBudWxsOyB9IH0NCiAgICBvYmouc2V0VmFyID0gZnVuY3Rpb24gKG5hbWUsIHZhbCkgeyBvYmouc2V0VmFyRXgobmFtZS5zcGxpdCgnLicpLCBvYmoudmFyaWFibGVzLCB2YWwpOyB9DQogICAgb2JqLnNldFZhckV4ID0gZnVuY3Rpb24gKG5hbWUsIHZhcnMsIHZhbCkgeyBpZiAobmFtZS5sZW5ndGggPT0gMSkgeyB2YXJzW25hbWVbMF1dID0gdmFsOyB9IGVsc2UgeyBvYmouc2V0VmFyRXgobmFtZS5zbGljZSgxKSwgdmFyc1tuYW1lWzBdXSwgdmFsKTsgfSB9DQoNCiAgICAvLyBSdW4gdGhlIHNjcmlwdCBvbmUgc3RlcCBmb3J3YXJkDQogICAgb2JqLnN0ZXAgPSBmdW5jdGlvbiAoKSB7DQogICAgICAgIGlmIChvYmouc3RhdGUgIT0gMSkgcmV0dXJuOw0KICAgICAgICBpZiAob2JqLmlwIDwgb2JqLnNjcmlwdC5sZW5ndGgpIHsNCiAgICAgICAgICAgIHZhciBjbWRpZCA9IFJlYWRTaG9ydChvYmouc2NyaXB0LCBvYmouaXApOw0KICAgICAgICAgICAgdmFyIGNtZGxlbiA9IFJlYWRTaG9ydChvYmouc2NyaXB0LCBvYmouaXAgKyAyKTsNCiAgICAgICAgICAgIHZhciBhcmdjb3VudCA9IFJlYWRTaG9ydChvYmouc2NyaXB0LCBvYmouaXAgKyA0KTsNCiAgICAgICAgICAgIHZhciBhcmdwdHIgPSBvYmouaXAgKyA2Ow0KICAgICAgICAgICAgdmFyIGFyZ3MgPSBbXTsNCg0KICAgICAgICAgICAgLy8gQ2xlYXIgYWxsIHRlbXAgdmFyaWFibGVzIChUaGlzIGlzIG9wdGlvbmFsKQ0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBvYmoudmFyaWFibGVzKSB7IGlmIChpLnN0YXJ0c1dpdGgoJ19fJykpIHsgZGVsZXRlIG9iai52YXJpYWJsZXNbaV07IH0gfQ0KDQogICAgICAgICAgICAvLyBMb29wIG9uIGVhY2ggYXJndW1lbnQsIG1vdmluZyBmb3J3YXJkIGJ5IHRoZSBhcmd1bWVudCBsZW5ndGggZWFjaCB0aW1lDQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ2NvdW50OyBpKyspIHsNCiAgICAgICAgICAgICAgICB2YXIgYXJnbGVuID0gUmVhZFNob3J0KG9iai5zY3JpcHQsIGFyZ3B0cik7DQogICAgICAgICAgICAgICAgdmFyIGFyZ3ZhbCA9IG9iai5zY3JpcHQuc3Vic3RyaW5nKGFyZ3B0ciArIDIsIGFyZ3B0ciArIDIgKyBhcmdsZW4pOw0KICAgICAgICAgICAgICAgIHZhciBhcmd0eXAgPSBhcmd2YWwuY2hhckNvZGVBdCgwKTsNCiAgICAgICAgICAgICAgICBhcmd2YWwgPSBhcmd2YWwuc3Vic3RyaW5nKDEpOw0KICAgICAgICAgICAgICAgIGlmIChhcmd0eXAgPCAyKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgdmFsdWUgYW5kIHJlcGxhY2UgYWxsIHt2YXJ9IHdpdGggdmFyaWFibGUgdmFsdWVzDQogICAgICAgICAgICAgICAgICAgIHdoaWxlIChhcmd2YWwuc3BsaXQoInsiKS5sZW5ndGggPiAxKSB7IHZhciB0ID0gYXJndmFsLnNwbGl0KCJ7IikucG9wKCkuc3BsaXQoIn0iKS5zaGlmdCgpOyBhcmd2YWwgPSBhcmd2YWwucmVwbGFjZSgneycgKyB0ICsgJ30nLCBvYmouZ2V0VmFyKHQpKTsgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoYXJndHlwID09IDEpIHsgb2JqLnZhcmlhYmxlc1snX18nICsgaV0gPSBkZWNvZGVVUkkoYXJndmFsKTsgYXJndmFsID0gJ19fJyArIGk7IH0gLy8gSWYgYXJndHlwIGlzIDEsIHRoaXMgaXMgYSBsaXRlcmFsLiBTdG9yZSBpbiB0ZW1wIHZhcmlhYmxlLg0KICAgICAgICAgICAgICAgICAgICBhcmdzLnB1c2goYXJndmFsKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKGFyZ3R5cCA9PSAyIHx8IGFyZ3R5cCA9PSAzKSB7DQogICAgICAgICAgICAgICAgICAgIG9iai52YXJpYWJsZXNbJ19fJyArIGldID0gUmVhZFNJbnQoYXJndmFsLCAwKTsNCiAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKCdfXycgKyBpKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgYXJncHRyICs9ICgyICsgYXJnbGVuKTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gTW92ZSBpbnN0cnVjdGlvbiBwb2ludGVyIGZvcndhcmQgYnkgY29tbWFuZCBzaXplDQogICAgICAgICAgICBvYmouaXAgKz0gY21kbGVuOw0KDQogICAgICAgICAgICAvLyBHZXQgYWxsIHZhcmlhYmxlIHZhbHVlcw0KICAgICAgICAgICAgdmFyIGFyZ3N2YWwgPSBbXTsNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTA7IGkrKykgeyBhcmdzdmFsLnB1c2gob2JqLmdldFZhcihhcmdzW2ldKSk7IH0NCiAgICAgICAgICAgIHZhciBzdG9yZUluQXJnMDsNCg0KICAgICAgICAgICAgdHJ5IHsNCiAgICAgICAgICAgICAgICBpZiAoY21kaWQgPCAxMDAwMCkgew0KICAgICAgICAgICAgICAgICAgICAvLyBMZXRzIHJ1biB0aGUgYWN0dWFsIGNvbW1hbmQNCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjbWRpZCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOiAvLyBub3ANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTogLy8ganVtcChsYWJlbCkgb3IganVtcChsYWJlbCwgYSwgY29tcGFyZSwgYikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJnc3ZhbFsyXSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXJnc3ZhbFsyXSA9PSAnPCcgJiYgYXJnc3ZhbFsxXSA8IGFyZ3N2YWxbM10pIHx8DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXJnc3ZhbFsyXSA9PSAnPD0nICYmIGFyZ3N2YWxbMV0gPD0gYXJnc3ZhbFszXSkgfHwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcmdzdmFsWzJdID09ICchPScgJiYgYXJnc3ZhbFsxXSAhPSBhcmdzdmFsWzNdKSB8fA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFyZ3N2YWxbMl0gPT0gJz0nICYmIGFyZ3N2YWxbMV0gPT0gYXJnc3ZhbFszXSkgfHwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcmdzdmFsWzJdID09ICc+PScgJiYgYXJnc3ZhbFsxXSA+PSBhcmdzdmFsWzNdKSB8fA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFyZ3N2YWxbMl0gPT0gJz4nICYmIGFyZ3N2YWxbMV0gPiBhcmdzdmFsWzNdKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHsgb2JqLmlwID0gYXJnc3ZhbFswXTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5pcCA9IGFyZ3N2YWxbMF07IC8vIFNldCB0aGUgaW5zdHJ1Y3Rpb24gcG9pbnRlciB0byB0aGUgbmV3IGxvY2F0aW9uIGluIHRoZSBzY3JpcHQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IC8vIHNldCh2YXJpYWJsZSwgdmFsdWUpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3NbMV0gPT0gdW5kZWZpbmVkKSBkZWxldGUgb2JqLnZhcmlhYmxlc1thcmdzWzBdXTsgZWxzZSBvYmouc2V0VmFyKGFyZ3NbMF0sIGFyZ3N2YWxbMV0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOiAvLyBwcmludChtZXNzYWdlKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvYmoub25Db25zb2xlKSB7IG9iai5vbkNvbnNvbGUob2JqLnRvU3RyaW5nKGFyZ3N2YWxbMF0pLCBvYmopOyB9IGVsc2UgeyBjb25zb2xlLmxvZyhvYmoudG9TdHJpbmcoYXJnc3ZhbFswXSkpOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIFEob2JqLmNvbnNvbGVpZCkudmFsdWUgKz0gKCkgKyAnXG4nKTsgUShvYmouY29uc29sZSkuc2Nyb2xsVG9wID0gUShvYmouY29uc29sZSkuc2Nyb2xsSGVpZ2h0Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiAvLyBkaWFsb2codGl0bGUsIGNvbnRlbnQsIGJ1dHRvbnMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouZGlhbG9nID0gdHJ1ZTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCBhcmdzdmFsWzBdLCBhcmdzdmFsWzJdLCBvYmoueHhTdGVwRGlhbG9nT2ssIGFyZ3N2YWxbMV0sIG9iaik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDU6IC8vIGdldGl0ZW0oYSwgYiwgYykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIGFyZ3N2YWxbMV0pIHsgaWYgKGFyZ3N2YWxbMV1baV1bYXJnc3ZhbFsyXV0gPT0gYXJnc3ZhbFszXSkgeyBzdG9yZUluQXJnMCA9IGk7IH0gfTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNjogLy8gc3Vic3RyKHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYywgaW5kZXgsIGxlbikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IGFyZ3N2YWxbMV0uc3Vic3RyKGFyZ3N2YWxbMl0sIGFyZ3N2YWxbM10pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA3OiAvLyBpbmRleE9mKHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYywgaW5kZXgsIGxlbikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IGFyZ3N2YWxbMV0uaW5kZXhPZihhcmdzdmFsWzJdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgODogLy8gc3BsaXQodmFyaWFibGVfZGVzdCwgdmFyaWFibGVfc3JjLCBzZXBhcmF0b3IpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVJbkFyZzAgPSBhcmdzdmFsWzFdLnNwbGl0KGFyZ3N2YWxbMl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA5OiAvLyBqb2luKHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYywgc2VwYXJhdG9yKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlSW5BcmcwID0gYXJnc3ZhbFsxXS5qb2luKGFyZ3N2YWxbMl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMDogLy8gbGVuZ3RoKHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IGFyZ3N2YWxbMV0ubGVuZ3RoOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMTogLy8ganNvbnBhcnNlKHZhcmlhYmxlX2Rlc3QsIGpzb24pDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVJbkFyZzAgPSBKU09OLnBhcnNlKGFyZ3N2YWxbMV0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMjogLy8ganNvbnN0cih2YXJpYWJsZV9kZXN0LCB2YXJpYWJsZV9zcmMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVJbkFyZzAgPSBKU09OLnN0cmluZ2lmeShhcmdzdmFsWzFdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTM6IC8vIGFkZCh2YXJpYWJsZV9kZXN0LCB2YXJpYWJsZV9zcmMsIHZhbHVlKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlSW5BcmcwID0gKGFyZ3N2YWxbMV0gKyBhcmdzdmFsWzJdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTQ6IC8vIHN1YnN0cmFjdCh2YXJpYWJsZV9kZXN0LCB2YXJpYWJsZV9zcmMsIHZhbHVlKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlSW5BcmcwID0gKGFyZ3N2YWxbMV0gLSBhcmdzdmFsWzJdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTU6IC8vIHBhcnNlSW50KHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IHBhcnNlSW50KGFyZ3N2YWxbMV0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNjogLy8gd3NiYXRjaGVudW0obmFtZSwgb2JqZWN0TGlzdCkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouc3RhdGUgPSAyOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5hbXRzdGFjay5CYXRjaEVudW0oYXJnc3ZhbFswXSwgYXJnc3ZhbFsxXSwgb2JqLnh4V3NtYW5SZXR1cm4sIG9iaik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE3OiAvLyB3c3B1dChuYW1lLCBhcmdzKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5zdGF0ZSA9IDI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmFtdHN0YWNrLlB1dChhcmdzdmFsWzBdLCBhcmdzdmFsWzFdLCBvYmoueHhXc21hblJldHVybiwgb2JqKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTg6IC8vIHdzY3JlYXRlKG5hbWUsIGFyZ3MpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouYW10c3RhY2suQ3JlYXRlKGFyZ3N2YWxbMF0sIGFyZ3N2YWxbMV0sIG9iai54eFdzbWFuUmV0dXJuLCBvYmopOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOTogLy8gd3NkZWxldGUobmFtZSwgYXJncykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouc3RhdGUgPSAyOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5hbXRzdGFjay5EZWxldGUoYXJnc3ZhbFswXSwgYXJnc3ZhbFsxXSwgb2JqLnh4V3NtYW5SZXR1cm4sIG9iaik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIwOiAvLyB3c2V4ZWMobmFtZSwgbWV0aG9kLCBhcmdzLCBzZWxlY3RvcnMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouYW10c3RhY2suRXhlYyhhcmdzdmFsWzBdLCBhcmdzdmFsWzFdLCBhcmdzdmFsWzJdLCBvYmoueHhXc21hblJldHVybiwgb2JqLCAwLCBhcmdzdmFsWzNdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjE6IC8vIFNjcmlwdCBTcGVlZA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5zdGVwc3BlZWQgPSBhcmdzdmFsWzBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvYmoudGltZXIgIT0gbnVsbCkgeyBjbGVhckludGVydmFsKG9iai50aW1lcik7IG9iai50aW1lciA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHsgb2JqLnN0ZXAoKSB9LCBvYmouc3RlcHNwZWVkKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMjogLy8gd3NzdWJzY3JpYmUobmFtZSwgZGVsaXZlcnksIHVybCwgc2VsZWN0b3JzLCBvcGFxdWUsIHVzZXIsIHBhc3MpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouYW10c3RhY2suU3Vic2NyaWJlKGFyZ3N2YWxbMF0sIGFyZ3N2YWxbMV0sIGFyZ3N2YWxbMl0sIG9iai54eFdzbWFuUmV0dXJuLCBvYmosIDAsIGFyZ3N2YWxbM10sIGFyZ3N2YWxbNF0sIGFyZ3N2YWxbNV0sIGFyZ3N2YWxbNl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMzogLy8gd3N1bnN1YnNjcmliZShuYW1lLCBzZWxlY3RvcnMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouYW10c3RhY2suVW5TdWJzY3JpYmUoYXJnc3ZhbFswXSwgb2JqLnh4V3NtYW5SZXR1cm4sIG9iaiwgMCwgYXJnc3ZhbFsxXSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI0OiAvLyByZWFkY2hhcihzdHIsIHBvcykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhhcmdzdmFsWzFdLCBhcmdzdmFsWzJdLCBhcmdzdmFsWzFdLmNoYXJDb2RlQXQoYXJnc3ZhbFsyXSkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlSW5BcmcwID0gYXJnc3ZhbFsxXS5jaGFyQ29kZUF0KGFyZ3N2YWxbMl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyNTogLy8gc2lnbldpdGhEdW1teUNhDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBERVJLZXksIHh4Q2FQcml2YXRlS2V5LCBjZXJ0YXR0cmlidXRlcywgaXNzdWVyYXR0cmlidXRlcw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFtdGNlcnRfc2lnbldpdGhDYUtleShhcmdzdmFsWzBdLCBudWxsLCBhcmdzdmFsWzFdLCB7ICdDTic6ICdVbnRydXN0ZWQgUm9vdCBDZXJ0aWZpY2F0ZScgfSwgb2JqLnh4U2lnbldpdGhEdW1teUNhUmV0dXJuKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gOTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCJTY3JpcHQgRXJyb3IsIHVua25vd24gY29tbWFuZDogIiArIGNtZGlkKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChjbWRpZCA8IDIwMDAwKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAvLyBmdW5jdGlvbnMgb2YgdHlwZSBBUkcxID0gZnVuYyhBUkcyLCBBUkczLCBBUkc0LCBBUkc1LCBBUkc2KQ0KICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVJbkFyZzAgPSBzY3JpcHRfZnVuY3Rpb25UYWJsZVgyW2NtZGlkIC0gMTAwMDBdKGFyZ3N2YWxbMV0sIGFyZ3N2YWxbMl0sIGFyZ3N2YWxbM10sIGFyZ3N2YWxbNF0sIGFyZ3N2YWxbNV0sIGFyZ3N2YWxbNl0pOw0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3B0aW9uYWwgZnVuY3Rpb25zIG9mIHR5cGUgQVJHMSA9IGZ1bmMoQVJHMiwgQVJHMywgQVJHNCwgQVJHNSwgQVJHNikNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzY3JpcHRfZnVuY3Rpb25UYWJsZVgzICYmIHNjcmlwdF9mdW5jdGlvblRhYmxlWDNbY21kaWQgLSAyMDAwMF0pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IHNjcmlwdF9mdW5jdGlvblRhYmxlWDNbY21kaWQgLSAyMDAwMF0ob2JqLCBhcmdzdmFsWzFdLCBhcmdzdmFsWzJdLCBhcmdzdmFsWzNdLCBhcmdzdmFsWzRdLCBhcmdzdmFsWzVdLCBhcmdzdmFsWzZdKTsgLy8gTm90ZSB0aGF0IG9wdGlvbmFsIGNhbGxzIHN0YXJ0IHdpdGggIm9iaiIgYXMgZmlyc3QgYXJndW1lbnQuDQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBpZiAoc3RvcmVJbkFyZzAgIT0gdW5kZWZpbmVkKSBvYmouc2V0VmFyKGFyZ3NbMF0sIHN0b3JlSW5BcmcwKTsNCiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsNCiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGUgPT0gJ29iamVjdCcpIHsgZSA9IGUubWVzc2FnZTsgfQ0KICAgICAgICAgICAgICAgIG9iai5zZXRWYXIoJ19leGNlcHRpb24nLCBlKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGlmIChvYmouc3RhdGUgPT0gMSAmJiBvYmouaXAgPj0gb2JqLnNjcmlwdC5sZW5ndGgpIHsgb2JqLnN0YXRlID0gMDsgb2JqLnN0b3AoKTsgfQ0KICAgICAgICBpZiAob2JqLm9uU3RlcCkgb2JqLm9uU3RlcChvYmopOw0KICAgICAgICByZXR1cm4gb2JqOw0KICAgIH0NCg0KICAgIG9iai54eFN0ZXBEaWFsb2dPayA9IGZ1bmN0aW9uIChidXR0b24pIHsNCiAgICAgICAgb2JqLnZhcmlhYmxlc1snRGlhbG9nU2VsZWN0J10gPSBidXR0b247DQogICAgICAgIG9iai5zdGF0ZSA9IDE7DQogICAgICAgIG9iai5kaWFsb2cgPSBmYWxzZTsNCiAgICAgICAgaWYgKG9iai5vblN0ZXApIG9iai5vblN0ZXAob2JqKTsNCiAgICB9DQoNCiAgICANCiAgICBvYmoueHhXc21hblJldHVybiA9IGZ1bmN0aW9uIChzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICBvYmouc2V0VmFyKG5hbWUsIHJlc3BvbnNlcyk7DQogICAgICAgIG9iai5zZXRWYXIoJ3dzbWFuX3Jlc3VsdCcsIHN0YXR1cyk7DQogICAgICAgIG9iai5zZXRWYXIoJ3dzbWFuX3Jlc3VsdF9zdHInLCAoKGh0dHBFcnJvclRhYmxlW3N0YXR1c10pID8gKGh0dHBFcnJvclRhYmxlW3N0YXR1c10pIDogKCdFcnJvciAjJyArIHN0YXR1cykpKTsNCiAgICAgICAgb2JqLnN0YXRlID0gMTsNCiAgICAgICAgaWYgKG9iai5vblN0ZXApIG9iai5vblN0ZXAob2JqKTsNCiAgICB9DQoNCiAgICANCiAgICBvYmoueHhTaWduV2l0aER1bW15Q2FSZXR1cm4gPSBmdW5jdGlvbiAoY2VydCkgew0KICAgICAgICBvYmouc2V0VmFyKCdzaWduZWRfY2VydCcsIGJ0b2EoX2FycmF5QnVmZmVyVG9TdHJpbmcoY2VydCkpKTsNCiAgICAgICAgb2JqLnN0YXRlID0gMTsNCiAgICAgICAgaWYgKG9iai5vblN0ZXApIG9iai5vblN0ZXAob2JqKTsNCiAgICB9DQogICAgDQogICAgb2JqLnRvU3RyaW5nID0gZnVuY3Rpb24gKHgpIHsgaWYgKHR5cGVvZiB4ID09ICdvYmplY3QnKSByZXR1cm4gSlNPTi5zdHJpbmdpZnkoeCk7IHJldHVybiB4OyB9DQoNCiAgICBvYmoucmVzZXQoKTsNCiAgICByZXR1cm4gb2JqOw0KfQ0KDQovLyBBcmd1bWVudCB0eXBlczogMCA9IFZhcmlhYmxlLCAxID0gU3RyaW5nLCAyID0gSW50ZWdlciwgMyA9IExhYmVsDQpmdW5jdGlvbiBzY3JpcHRfY29tcGlsZShzY3JpcHQsIG9ubXNnKSB7DQogICAgdmFyIHIgPSAnJywgc2NyaXB0bGluZXMgPSBzY3JpcHQuc3BsaXQoJ1xuJyksIGxhYmVscyA9IHt9LCBsYWJlbHN3YXAgPSBbXSwgc3dhcHMgPSBbXTsNCiAgICAvLyBHbyB0aHJ1IGVhY2ggc2NyaXB0IGxpbmUgYW5kIGVuY29kZSBpdA0KICAgIGZvciAodmFyIGkgaW4gc2NyaXB0bGluZXMpIHsNCiAgICAgICAgdmFyIHNjcmlwdGxpbmUgPSBzY3JpcHRsaW5lc1tpXTsNCiAgICAgICAgaWYgKHNjcmlwdGxpbmUuc3RhcnRzV2l0aCgnIyNTV0FQICcpKSB7IHZhciB4ID0gc2NyaXB0bGluZS5zcGxpdCgnICcpOyBpZiAoeC5sZW5ndGggPT0gMykgeyBzd2Fwc1t4WzFdXSA9IHhbMl07IH0gfSAvLyBBZGQgYSBzd2FwIGluc3RhbmNlDQogICAgICAgIGlmIChzY3JpcHRsaW5lWzBdID09ICcjJyB8fCBzY3JpcHRsaW5lLmxlbmd0aCA9PSAwKSBjb250aW51ZTsgLy8gU2tpcCBjb21tZW50cyAmIGJsYW5rIGxpbmVzDQogICAgICAgIGZvciAodmFyIHggaW4gc3dhcHMpIHsgc2NyaXB0bGluZSA9IHNjcmlwdGxpbmUuc3BsaXQoeCkuam9pbihzd2Fwc1t4XSk7IH0gLy8gQXBwbHkgYWxsIHN3YXBzDQogICAgICAgIHZhciBrZXl3b3JkcyA9IHNjcmlwdGxpbmUubWF0Y2goLyJbXiJdKiJ8W15ccyJdKy9nKTsNCiAgICAgICAgaWYgKGtleXdvcmRzLmxlbmd0aCA9PSAwKSBjb250aW51ZTsgLy8gU2tpcCBibGFuayBsaW5lcw0KICAgICAgICBpZiAoc2NyaXB0bGluZVswXSA9PSAnOicpIHsgbGFiZWxzW2tleXdvcmRzWzBdLnRvVXBwZXJDYXNlKCldID0gci5sZW5ndGg7IGNvbnRpbnVlOyB9IC8vIE1hcmsgYSBsYWJlbCBwb3NpdGlvbg0KICAgICAgICB2YXIgZnVuY0luZGV4ID0gc2NyaXB0X2Z1bmN0aW9uVGFibGUxLmluZGV4T2Yoa2V5d29yZHNbMF0udG9Mb3dlckNhc2UoKSk7DQogICAgICAgIGlmIChmdW5jSW5kZXggPT0gLTEpIHsgZnVuY0luZGV4ID0gc2NyaXB0X2Z1bmN0aW9uVGFibGUyLmluZGV4T2Yoa2V5d29yZHNbMF0udG9Mb3dlckNhc2UoKSk7IGlmIChmdW5jSW5kZXggPj0gMCkgZnVuY0luZGV4ICs9IDEwMDAwOyB9DQogICAgICAgIGlmIChmdW5jSW5kZXggPT0gLTEpIHsgZnVuY0luZGV4ID0gc2NyaXB0X2Z1bmN0aW9uVGFibGUzLmluZGV4T2Yoa2V5d29yZHNbMF0udG9Mb3dlckNhc2UoKSk7IGlmIChmdW5jSW5kZXggPj0gMCkgZnVuY0luZGV4ICs9IDIwMDAwOyB9IC8vIE9wdGlvbmFsIG1ldGhvZHMNCiAgICAgICAgaWYgKGZ1bmNJbmRleCA9PSAtMSkgeyBpZiAob25tc2cpIHsgb25tc2coIlVuYWJsZWQgdG8gY29tcGlsZSwgdW5rbm93biBjb21tYW5kOiAiICsga2V5d29yZHNbMF0pOyB9IHJldHVybiAnJzsgfQ0KICAgICAgICAvLyBFbmNvZGUgQ29tbWFuZElkLCBDbWRTaXplLCBBcmdDb3VudCwgQXJnMUxlbiwgQXJnMSwgQXJnMkxlbiwgQXJnMi4uLg0KICAgICAgICB2YXIgY21kID0gU2hvcnRUb1N0cihrZXl3b3Jkcy5sZW5ndGggLSAxKTsNCiAgICAgICAgZm9yICh2YXIgaiBpbiBrZXl3b3Jkcykgew0KICAgICAgICAgICAgaWYgKGogPT0gMCkgY29udGludWU7DQogICAgICAgICAgICBpZiAoa2V5d29yZHNbal1bMF0gPT0gJzonKSB7DQogICAgICAgICAgICAgICAgbGFiZWxzd2FwLnB1c2goW2tleXdvcmRzW2pdLCByLmxlbmd0aCArIGNtZC5sZW5ndGggKyA3XSk7IC8vIEFkZCBhIGxhYmVsIHN3YXANCiAgICAgICAgICAgICAgICBjbWQgKz0gU2hvcnRUb1N0cig1KSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMykgKyBJbnRUb1N0cigweEZGRkZGRkZGKTsgLy8gUHV0IGFuIGVtcHR5IGxhYmVsDQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHZhciBhcmdpbnQgPSBwYXJzZUludChrZXl3b3Jkc1tqXSk7DQogICAgICAgICAgICAgICAgaWYgKGFyZ2ludCA9PSBrZXl3b3Jkc1tqXSkgew0KICAgICAgICAgICAgICAgICAgICBjbWQgKz0gU2hvcnRUb1N0cig1KSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMikgKyBJbnRUb1N0cihhcmdpbnQpOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChrZXl3b3Jkc1tqXVswXSA9PSAnIicgJiYga2V5d29yZHNbal1ba2V5d29yZHNbal0ubGVuZ3RoIC0gMV0gPT0gJyInKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBjbWQgKz0gU2hvcnRUb1N0cihrZXl3b3Jkc1tqXS5sZW5ndGggLSAxKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMSkgKyBrZXl3b3Jkc1tqXS5zdWJzdHJpbmcoMSwga2V5d29yZHNbal0ubGVuZ3RoIC0gMSk7DQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICBjbWQgKz0gU2hvcnRUb1N0cihrZXl3b3Jkc1tqXS5sZW5ndGggKyAxKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMCkgKyBrZXl3b3Jkc1tqXTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBjbWQgPSBTaG9ydFRvU3RyKGZ1bmNJbmRleCkgKyBTaG9ydFRvU3RyKGNtZC5sZW5ndGggKyA0KSArIGNtZDsNCiAgICAgICAgciArPSBjbWQ7DQogICAgfQ0KICAgIC8vIFBlcmZvcm0gYWxsIHRoZSBuZWVkZWQgbGFiZWwgc3dhcHMNCiAgICBmb3IgKGkgaW4gbGFiZWxzd2FwKSB7DQogICAgICAgIHZhciBsYWJlbCA9IGxhYmVsc3dhcFtpXVswXS50b1VwcGVyQ2FzZSgpLCBwb3NpdGlvbiA9IGxhYmVsc3dhcFtpXVsxXSwgdGFyZ2V0ID0gbGFiZWxzW2xhYmVsXTsNCiAgICAgICAgaWYgKHRhcmdldCA9PSB1bmRlZmluZWQpIHsgaWYgKG9ubXNnKSB7IG9ubXNnKCJVbmFibGVkIHRvIGNvbXBpbGUsIHVua25vd24gbGFiZWw6ICIgKyBsYWJlbCk7IH0gcmV0dXJuICcnOyB9DQogICAgICAgIHIgPSByLnN1YnN0cigwLCBwb3NpdGlvbikgKyBJbnRUb1N0cih0YXJnZXQpICsgci5zdWJzdHIocG9zaXRpb24gKyA0KTsNCiAgICB9DQogICAgcmV0dXJuIEludFRvU3RyKDB4MjQ3RDI5NDUpICsgU2hvcnRUb1N0cigxKSArIHI7DQp9DQoNCi8vIERlY29tcGlsZSB0aGUgc2NyaXB0LCBpbnRlbmRlZCBmb3IgZGVidWdnaW5nIG9ubHkNCmZ1bmN0aW9uIHNjcmlwdF9kZWNvbXBpbGUoYmluYXJ5LCBvbmVjbWQpIHsNCiAgICB2YXIgciA9ICcnLCBwdHIgPSA2LCBsYWJlbGNvdW50ID0gMCwgbGFiZWxzID0ge307DQogICAgaWYgKG9uZWNtZCA+PSAwKSB7DQogICAgICAgIHB0ciA9IG9uZWNtZDsgLy8gSWYgd2UgYXJlIGRlY29tcGlsaW5nIGp1c3Qgb25lIGNvbW1hbmQsIHNldCB0aGUgcHRyIHRvIHRoYXQgY29tbWFuZC4NCiAgICB9IGVsc2Ugew0KICAgICAgICBpZiAoYmluYXJ5Lmxlbmd0aCA8IDYpIHsgcmV0dXJuICcjIEludmFsaWQgc2NyaXB0IGxlbmd0aCc7IH0NCiAgICAgICAgdmFyIG1hZ2ljID0gUmVhZEludChiaW5hcnksIDApOw0KICAgICAgICB2YXIgdmVyc2lvbiA9IFJlYWRTaG9ydChiaW5hcnksIDQpOw0KICAgICAgICBpZiAobWFnaWMgIT0gMHgyNDdEMjk0NSkgeyByZXR1cm4gJyMgSW52YWxpZCBiaW5hcnkgc2NyaXB0OiAnICsgbWFnaWM7IH0NCiAgICAgICAgaWYgKHZlcnNpb24gIT0gMSkgeyByZXR1cm4gJyMgSW52YWxpZCBzY3JpcHQgdmVyc2lvbic7IH0NCiAgICB9DQogICAgLy8gTG9vcCBvbiBlYWNoIGNvbW1hbmQsIG1vdmluZyBmb3J3YXJkIGJ5IHRoZSBjb21tYW5kIGxlbmd0aCBlYWNoIHRpbWUuDQogICAgd2hpbGUgKHB0ciA8IGJpbmFyeS5sZW5ndGgpIHsNCiAgICAgICAgdmFyIGNtZGlkID0gUmVhZFNob3J0KGJpbmFyeSwgcHRyKTsNCiAgICAgICAgdmFyIGNtZGxlbiA9IFJlYWRTaG9ydChiaW5hcnksIHB0ciArIDIpOw0KICAgICAgICB2YXIgYXJnY291bnQgPSBSZWFkU2hvcnQoYmluYXJ5LCBwdHIgKyA0KTsNCiAgICAgICAgdmFyIGFyZ3B0ciA9IHB0ciArIDY7DQogICAgICAgIHZhciBhcmdzdHIgPSAnJzsNCiAgICAgICAgaWYgKCEob25lY21kID49IDApKSByICs9ICI6bGFiZWwiICsgKHB0ciAtIDYpICsgIlxuIjsNCiAgICAgICAgLy8gTG9vcCBvbiBlYWNoIGFyZ3VtZW50LCBtb3ZpbmcgZm9yd2FyZCBieSB0aGUgYXJndW1lbnQgbGVuZ3RoIGVhY2ggdGltZQ0KICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ2NvdW50OyBpKyspIHsNCiAgICAgICAgICAgIHZhciBhcmdsZW4gPSBSZWFkU2hvcnQoYmluYXJ5LCBhcmdwdHIpOw0KICAgICAgICAgICAgdmFyIGFyZ3ZhbCA9IGJpbmFyeS5zdWJzdHJpbmcoYXJncHRyICsgMiwgYXJncHRyICsgMiArIGFyZ2xlbik7DQogICAgICAgICAgICB2YXIgYXJndHlwID0gYXJndmFsLmNoYXJDb2RlQXQoMCk7DQogICAgICAgICAgICBpZiAoYXJndHlwID09IDApIHsgYXJnc3RyICs9ICcgJyArIGFyZ3ZhbC5zdWJzdHJpbmcoMSk7IH0gLy8gVmFyaWFibGUNCiAgICAgICAgICAgIGVsc2UgaWYgKGFyZ3R5cCA9PSAxKSB7IGFyZ3N0ciArPSAnIFwiJyArIGFyZ3ZhbC5zdWJzdHJpbmcoMSkgKyAnXCInOyB9IC8vIFN0cmluZw0KICAgICAgICAgICAgZWxzZSBpZiAoYXJndHlwID09IDIpIHsgYXJnc3RyICs9ICcgJyArIFJlYWRJbnQoYXJndmFsLCAxKTsgfSAvLyBJbnRlZ2VyDQogICAgICAgICAgICBlbHNlIGlmIChhcmd0eXAgPT0gMykgeyAvLyBMYWJlbA0KICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSBSZWFkSW50KGFyZ3ZhbCwgMSk7DQogICAgICAgICAgICAgICAgdmFyIGxhYmVsID0gbGFiZWxzW3RhcmdldF07DQogICAgICAgICAgICAgICAgaWYgKCFsYWJlbCkgeyBsYWJlbCA9ICI6bGFiZWwiICsgdGFyZ2V0OyBsYWJlbHNbbGFiZWxdID0gdGFyZ2V0OyB9DQogICAgICAgICAgICAgICAgYXJnc3RyICs9ICcgJyArIGxhYmVsOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgYXJncHRyICs9ICgyICsgYXJnbGVuKTsNCiAgICAgICAgfQ0KICAgICAgICAvLyBHbyBpbiB0aGUgc2NyaXB0IGZ1bmN0aW9uIHRhYmxlIHRvIGRlY29kZSB0aGUgZnVuY3Rpb24NCiAgICAgICAgaWYgKGNtZGlkIDwgMTAwMDApIHsNCiAgICAgICAgICAgIHIgKz0gc2NyaXB0X2Z1bmN0aW9uVGFibGUxW2NtZGlkXSArIGFyZ3N0ciArICJcbiI7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBpZiAoY21kaWQgPj0gMjAwMDApIHsNCiAgICAgICAgICAgICAgICByICs9IHNjcmlwdF9mdW5jdGlvblRhYmxlM1tjbWRpZCAtIDIwMDAwXSArIGFyZ3N0ciArICJcbiI7IC8vIE9wdGlvbmFsIG1ldGhvZHMNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgciArPSBzY3JpcHRfZnVuY3Rpb25UYWJsZTJbY21kaWQgLSAxMDAwMF0gKyBhcmdzdHIgKyAiXG4iOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIHB0ciArPSBjbWRsZW47DQogICAgICAgIGlmIChvbmVjbWQgPj0gMCkgcmV0dXJuIHI7IC8vIElmIHdlIGFyZSBkZWNvbXBpbGluZyBqdXN0IG9uZSBjb21tYW5kLCBleGl0IG5vdw0KICAgIH0NCiAgICAvLyBSZW1vdmUgYWxsIHVudXNlZCBsYWJlbHMNCiAgICB2YXIgc2NyaXB0bGluZXMgPSByLnNwbGl0KCdcbicpOw0KICAgIHIgPSAnJzsNCiAgICBmb3IgKHZhciBpIGluIHNjcmlwdGxpbmVzKSB7DQogICAgICAgIHZhciBsaW5lID0gc2NyaXB0bGluZXNbaV07DQogICAgICAgIGlmIChsaW5lWzBdICE9ICc6JykgeyByICs9IGxpbmUgKyAnXG4nOyB9IGVsc2UgeyBpZiAobGFiZWxzW2xpbmVdKSB7IHIgKz0gbGluZSArICdcbic7IH0gfQ0KICAgIH0NCiAgICByZXR1cm4gcjsNCn0NCi8qKiANCiogQGRlc2NyaXB0aW9uIEludGVsKFIpIEFNVCBTZXR1cC5iaW4gUGFyc2VyDQoqIEBhdXRob3IgWWxpYW4gU2FpbnQtSGlsYWlyZQ0KKiBAdmVyc2lvbiB2MC4xLjANCiovDQoNCi8vIEludGVsKFIpIEFNVCBTZXR1cC5iaW4gR1VJRCdzDQp2YXIgQW10U2V0dXBCaW5TZXR1cEd1aWRzID0gWw0KICAgICJceGI1XHgxNlx4ZmJceDcxXHg4N1x4Y2JceGY5XHg0YVx4YjRceDQxXHhjYVx4N2JceDM4XHgzNVx4NzhceGY5IiwgLy8gVmVyc2lvbiAxDQogICAgIlx4OTZceGIyXHg4MVx4NThceGNmXHg2Ylx4NzJceDRjXHg4Ylx4OTFceGExXHg1ZVx4NTFceDJlXHg5OVx4YzQiLCAvLyBWZXJzaW9uIDINCiAgICAiXHhhN1x4ZjdceGY2XHhjNlx4ODlceGM0XHhmNlx4NDdceDkzXHhlZFx4ZTJceGU1XHgwMlx4MGRceGE1XHgxZCIsIC8vIFZlcnNpb24gMw0KICAgICJceGFhXHhhOVx4MzRceDUyXHhlMVx4MjlceGE5XHg0NFx4OGRceDRkXHgwOFx4MWNceDA3XHhiOVx4NjNceDUzIiAgLy8gVmVyc2lvbiA0DQpdOw0KDQovLyBOb3RlcyBhYm91dCB2ZXJzaW9uIDIgb2Ygc2V0dXAuYmluOg0KLy8gICAtIERlZmF1bHQgImFkbWluIiBtdXN0IGJlIGZvbGxvd2VkIGJ5IGEgbmV3IE1FQnggcGFzc3dvcmQNCi8vICAgLSBNRV9WQVJJQUJMRV9JREVOVElGSUVSX01BTkFHRUFCSUxJVFlfRkVBVFVSRV9TRUxFQ1RJT04gbWF5IG5vdCBhcHBlYXIgYWZ0ZXIgYW55IENNIHNldHRpbmdzDQovLyAgIC0gQ01fVkFSSUFCTEVfSURFTlRJRklFUl9VU0VSX0RFRklORURfQ0VSVF9BREQgbXVzdCBiZSBwcmVjZWRlZCBieSBzZXR0aW5nIENNX1ZBUklBQkxFX0lERU5USUZJRVJfVVNFUl9ERUZJTkVEX0NFUlRTX0NPTkZJRyB0byAoVE9ETyEpDQoNCi8vIEdlbmVyYWwgbm90ZXM6DQovLyAgIC0gU2V0dXAuYmluIHNob3VsZCBhbHdheXMgc3RhcnQgd2l0aCAiQ3VycmVudE1FQnggUHdkIiwgIm5ld01lYnggUHdkIiwgIm1hbmFnZWFiaWxpdHkgc2VsZWN0aW9uIiAoaWYgcHJlc2VudCkuDQoNCi8vIEludGVsKFIpIEFNVCB2YXJpYWJsZSBpZGVudGlmaWVycw0KLy8gVHlwZTogMCA9IEJpbmFyIFN0cmluZ3ksIDEgPSBDaGFyLCAyID0gU2hvcnQsIDMgPSBJbnQNCnZhciBBbXRTZXR1cEJpblZhcklkcyA9DQp7DQogICAgMTogew0KICAgICAgICAxOiAgWzAsICJDdXJyZW50IE1FQnggUGFzc3dvcmQiXSwNCiAgICAgICAgMjogIFswLCAiTmV3IE1FQnggUGFzc3dvcmQiXSwNCiAgICAgICAgMzogIFsxLCAiTWFuYWdlYWJpbGl0eSBGZWF0dXJlIFNlbGVjdGlvbiJdLA0KICAgICAgICA0OiAgWzEsICJGaXJtd2FyZSBMb2NhbCBVcGRhdGUiLCAgICAgICAgICAgICAgICAgICAvLyAwID0gRGlzYWJsZWQsIDEgPSBFbmFibGVkLCAyID0gUGFzc3dvcmQgUHJvdGVjdGVkDQogICAgICAgICAgICB7IDA6ICJEaXNhYmxlZCIsIDE6ICJFbmFibGVkIiwgMjogIlBhc3N3b3JkIFByb3RlY3RlZCIgfV0sDQogICAgICAgIDU6ICBbMSwgIkZpcm13YXJlIFVwZGF0ZSBRdWFsaWZpZXIiLCAgICAgICAgICAgICAgIC8vIDAgPSBBbHdheXMsIDEgPSBOZXZlciwgMiA9IFJlc3RyaWN0ZWQNCiAgICAgICAgICAgIHsgMDogIkFsd2F5cyIsIDE6ICJOZXZlciIsIDI6ICJSZXN0cmljdGVkIiB9XSwNCiAgICAgICAgNjogIFs0LCAiUG93ZXIgUGFja2FnZSJdICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR1VJRCBMZW5ndGggKDE2IGJ5dGVzKSwgSW50ZWwgQU1UIHZlcnNpb24gMi4xLCAzIGFuZCA0DQogICAgfSwNCiAgICAyOiB7DQogICAgICAgIDE6ICBbMCwgIlByb3Zpc2lvbmluZyBQcmVzaGFyZWQgS2V5IElEIChQSUQpIl0sDQogICAgICAgIDI6ICBbMCwgIlByb3Zpc2lvbmluZyBQcmVzaGFyZWQgS2V5IChQUFMpIl0sDQogICAgICAgIDM6ICBbMCwgIlBLSSBETlMgU3VmZml4Il0sICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDI1NSBieXRlcyBtYXggbGVuZ3RoDQogICAgICAgIDQ6ICBbMCwgIkNvbmZpZ3VyYXRpb24gU2VydmVyIEZRRE4iXSwgICAgICAgICAgICAgIC8vIDI1NSBieXRlcyBtYXggbGVuZ3RoDQogICAgICAgIDU6ICBbMSwgIlJlbW90ZSBDb25maWd1cmF0aW9uIEVuYWJsZWQgKFJDRkcpIiwgICAgIC8vIDAgPSBPZmYsIDEgPSBPbg0KICAgICAgICAgICAgeyAwOiAiT2ZmIiwgMTogIk9uIiB9XSwNCiAgICAgICAgNjogIFsxLCAiUHJlLUluc3RhbGxlZCBDZXJ0aWZpY2F0ZXMgRW5hYmxlZCIsICAgICAgLy8gMCA9IE9mZiwgMSA9IE9uDQogICAgICAgICAgICB7IDA6ICJPZmYiLCAxOiAiT24iIH1dLA0KICAgICAgICA3OiAgWzEsICJVc2VyIERlZmluZWQgQ2VydGlmaWNhdGUgQ29uZmlndXJhdGlvbiIsICAvLyAwID0gRGlzYWJsZWQsIDEgPSBFbmFibGVkLCAyID0gRGVsZXRlDQogICAgICAgICAgICB7IDA6ICJEaXNhYmxlZCIsIDE6ICJFbmFibGVkIiwgMjogIkRlbGV0ZSIgfV0sDQogICAgICAgIDg6ICBbMCwgIlVzZXIgRGVmaW5lZCBDZXJ0aWZpY2F0ZSBBZGRpdGlvbiJdLCAgICAgIC8vIDEgYnl0ZSBoYXNoIGFsZ28sIDIwIHRvIDQ4IGJ5dGVzIGhhc2gsIDEgYnl0ZSBuYW1lIGxlbmd0aCwgdXAgdG8gMzIgYnl0ZXMgZnJpZW5kbHkgbmFtZSwgMSA9IFNIQTEgKDIwIGJ5dGVzKSwgMiA9IFNIQTI1NiAoMzIgYnl0ZXMpLCAzID0gU0hBMzg0ICg0OCBieXRlcykuIEFsZ28gMiAmIDMgYXJlIGZvciB2ZXJzaW9uIDMgYW5kIHVwLg0KICAgICAgICAxMDogWzEsICJTT0wvSURFUiBSZWRpcmVjdGlvbiBDb25maWd1cmF0aW9uIl0sDQogICAgICAgIDExOiBbMCwgIkhvc3RuYW1lIl0sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDYzIGJ5dGVzIG1heCBsZW5ndGgNCiAgICAgICAgMTI6IFswLCAiRG9tYWluIE5hbWUiXSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gMjU1IGJ5dGVzIG1heCBsZW5ndGgNCiAgICAgICAgMTM6IFsxLCAiREhDUCIsIHsgMTogIkRpc2FibGVkIiwgMjogIkVuYWJsZWQiIH1dLA0KICAgICAgICAxNDogWzEsICJTZWN1cmUgRmlybXdhcmUgVXBkYXRlIChTRldVKSIsICAgICAgICAgICAvLyAwID0gRGlzYWJsZWQsIDEgPSBFbmFibGVkDQogICAgICAgICAgICB7IDA6ICJEaXNhYmxlZCIsIDE6ICJFbmFibGVkIiB9XSwNCiAgICAgICAgMTU6IFswLCAiSVRPIl0sDQogICAgICAgIDE2OiBbMSwgIlByb3Zpc2lvbmluZyBNb2RlIChQTSkiLCAgICAgICAgICAgICAgICAgIC8vIDEgPSBFbnRlcnByaXNlLCAyID0gU21hbGwgQnVpc25lc3MgKFNNQikNCiAgICAgICAgICAgIHsgMDogIkVudGVycHJpc2UiLCAxOiAiU21hbGwgQnVpc25lc3MifV0sDQogICAgICAgIDE3OiBbMCwgIlByb3Zpc2lvbmluZyBTZXJ2ZXIgQWRkcmVzcyJdLA0KICAgICAgICAxODogWzIsICJQcm92aXNpb24gU2VydmVyIFBvcnQgTnVtYmVyIChQU1BPKSJdLA0KICAgICAgICAxOTogWzAsICJTdGF0aWMgUFY0IFBhcmFtZXRlcnMiXSwNCiAgICAgICAgMjA6IFswLCAiVkxBTiJdLA0KICAgICAgICAyMTogWzAsICJQQVNTIFBvbGljeSBGbGFnIl0sDQogICAgICAgIDIyOiBbMCwgIklQdjYiXSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIExlbmd0aCBpcyAyMDQgYnl0ZXMgb2xkIGZvcm1hdCwgODQgYnl0ZXMgbmV3IGZvcm1hdCwgVmVyc2lvbiAzKyBvbmx5DQogICAgICAgIDIzOiBbMSwgIlNoYXJlZC9EZWRpY2F0ZWQgRlFETiIsICAgICAgICAgICAgICAgICAgIC8vIDAgPSBEZWRpY2F0ZWQsIDEgPSBTaGFyZWQuIFRoaXMgb3B0aW9uIGlzIHZhbGlkIG9ubHkgaWYgY29uZmlndXJpbmcgdGhlIGhvc3RuYW1lIGFzIHdlbGwNCiAgICAgICAgICAgIHsgMDogIkRlZGljYXRlZCIsIDE6ICJTaGFyZWQiIH1dLA0KICAgICAgICAyNDogWzEsICJEeW5hbWljIEROUyBVcGRhdGUiLCAgICAgICAgICAgICAgICAgICAgICAvLyAwID0gRGlzYWJsZWQsIDEgPSBFbmFibGVkDQogICAgICAgICAgICB7IDA6ICJEaXNhYmxlZCIsIDE6ICJFbmFibGVkIiB9XSwNCiAgICAgICAgMjU6IFsxLCAiUmVtb3RlIERlc2t0b3AgKEtWTSkgU3RhdGUiLCAgICAgICAgICAgICAgLy8gMCA9IERpc2FibGVkLCAxID0gRW5hYmxlZA0KICAgICAgICAgICAgeyAwOiAiRGlzYWJsZWQiLCAxOiAiRW5hYmxlZCIgfV0sDQogICAgICAgIDI2OiBbMSwgIk9wdC1pbiBVc2VyIENvbnNlbnQgT3B0aW9uIiwgICAgICAgICAgICAgIC8vIDAgPSBEaXNhYmxlZCwgMSA9IEtWTSwgMHhGRiA9IEFMTA0KICAgICAgICAgICAgeyAwIDogIkRpc2FibGVkIiwgMSA6ICJLVk0iLCAyNTUgOiAiQWxsIiB9XSwNCiAgICAgICAgMjc6IFsxLCAiT3B0LWluIFJlbW90ZSBJVCBDb25zZW50IFBvbGljeSIsICAgICAgICAgLy8gMCA9IERpc2FibGVkLCAxID0gRW5hYmxlZC4gQWxsb3dzIHVzZXIgY29uc2VudCB0byBiZSBjb25maWd1cmVkIHJlbW90ZWx5Lg0KICAgICAgICAgICAgeyAwIDogIkRpc2FibGVkIiwgMSA6ICJFbmFibGVkIn0gXSwNCiAgICAgICAgMjg6IFsxLCAiTUUgUHJvdmlzaW9uIEhhbHQgQWN0aXZlIiwgICAgICAgICAgICAgICAgLy8gMCA9IFN0b3AsIDEgPSBTdGFydC4gVGhlICJNRSBwcm92aXNpb25pbmcgSGFsdC9BY3RpdmF0ZSIgY29tbWFuZCBtdXN0IGFwcGVhciBpbiB0aGUgZmlsZSBvbmx5IGFmdGVyICJQS0lETlNTdWZmaXgiLCAiQ29uZmlnU2VydmVyRlFETiIgYW5kICJQcm92aXNpb25pbmcgU2VydmVyIEFkZHJlc3MiDQogICAgICAgICAgICB7IDAgOiAiU3RvcCIsIDEgOiAiU3RhcnQifV0sDQogICAgICAgIDI5OiBbMSwgIk1hbnVhbCBTZXR1cCBhbmQgQ29uZmlndXJhdGlvbiIsICAgICAgICAgIC8vIDAgPSBBdXRvbWF0ZWQsIDEgPSBNYW51YWwNCiAgICAgICAgICAgIHsgMCA6ICJBdXRvbWF0ZWQiLCAxIDogIk1hbnVhbCJ9XSwNCiAgICAgICAgMzA6IFszLCAiU3VwcG9ydCBDaGFubmVsIElkZW50aWZpZXIiXSwgICAgICAgICAgICAgLy8gNCBieXRlcyBsZW5ndGguIFN1cHBvcnQgY2hhbm5lbCBpZGVudGlmaWVyICh2YWxpZCB2YWx1ZXM6IDEtNjU1MzUpDQogICAgICAgIDMxOiBbMCwgIlN1cHBvcnQgQ2hhbm5lbCBEZXNjcmlwdGlvbiJdLCAgICAgICAgICAgIC8vIDYwIGJ5dGVzIG1heC4gRnJpZW5kbHkgbmFtZSB1c2VkIHRvIGRlc2NyaWJlIHRoZSBwYXJ0eSByZXByZXNlbnRlZGJ5IHRoZSBzdXBwb3J0IGNoYW5uZWwgaWRlbnRpZmllci4NCiAgICAgICAgMzI6IFswLCAiU2VydmljZSBBY2NvdW50IE51bWJlciJdLCAgICAgICAgICAgICAgICAgLy8gMzIgYnl0ZXMgbWF4LiBVbmlxdWUgc3RyaW5nIGlkZW50aWZpZXIgZ2l2ZW4gdG8gdGhlIGVuZCB1c2VyIGJ5IHRoZSBzZXJ2aWNlIHByb3ZpZGVyLg0KICAgICAgICAzMzogWzAsICJFbnJvbGxlbWVudCBQYXNzY29kZSJdLCAgICAgICAgICAgICAgICAgICAvLyAzMiBieXRlcyBtYXgNCiAgICAgICAgMzQ6IFszLCAiU2VydmljZSBUeXBlIl0sICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gNCBieXRlcyBsZW5ndGguIDEgPSBSZWFjdGl2ZSwgMiA9IFByb2FjdGl2ZSwgNCA9IE9uZSBUaW1lIFNlc3Npb24NCiAgICAgICAgMzU6IFswLCAiU2VydmljZSBQcm92aWRlciBJZGVudGlmaWVyIl0gICAgICAgICAgICAgLy8gR1VJRCBMZW5ndGggKDE2IGJ5dGVzKQ0KICAgIH0NCn0NCg0KDQovLyBQYXJzZSB0aGUgU2V0dXAuYmluIGZpbGUNCnZhciBBbXRTZXR1cEJpbkNyZWF0ZSA9IGZ1bmN0aW9uICh2ZXJzaW9uLCBmbGFncykgew0KICAgIHZhciBvYmogPSB7fTsNCiAgICBvYmouZmlsZVR5cGUgPSB2ZXJzaW9uOw0KICAgIG9iai5yZWNvcmRDaHVua0NvdW50ID0gMDsNCiAgICBvYmoucmVjb3JkSGVhZGVyQnl0ZUNvdW50ID0gMDsNCiAgICBvYmoucmVjb3JkTnVtYmVyID0gMDsNCiAgICBvYmoubWFqb3JWZXJzaW9uID0gdmVyc2lvbjsNCiAgICBvYmoubWlub3JWZXJzaW9uID0gMDsNCiAgICBvYmouZmxhZ3MgPSBmbGFnczsNCiAgICBvYmouZGF0YVJlY29yZHNDb25zdW1lZCA9IDA7DQogICAgb2JqLmRhdGFSZWNvcmRDaHVua0NvdW50ID0gMDsNCiAgICBvYmoucmVjb3JkcyA9IFtdOw0KICAgIHJldHVybiBvYmo7DQp9DQoNCg0KLy8gUGFyc2UgdGhlIFNldHVwLmJpbiBmaWxlDQp2YXIgQW10U2V0dXBCaW5EZWNvZGUgPSBmdW5jdGlvbiAoZmlsZSkgew0KDQogICAgLy8gRm9ybWF0IG9mIHRoZSBzZXR1cCBmaWxlIGhlYWRlcjoNCiAgICAvLyBGaWxlVHlwZVVVSUQoMTYpICAgICAgICAgLSB1bmlxdWVseSBpZGVudGlmaWVzIHRoZSBmaWxlIHR5cGUuIFRoaXMgaWRlbnRpZmllciB3aWxsIHJlbWFpbiB2YWxpZCBhbmQgY29uc3RhbnQgYWNyb3NzIGFsbCB2ZXJzaW9ucyBvZiB0aGUgZmlsZSB0eXBlLg0KICAgIC8vIFJlY29yZENodW5rQ291bnQoMikgICAgICAtIGluZGljYXRlcyB0aGUgbnVtYmVyIG9mIDUxMi1ieXRlIGNodW5rcyBvY2N1cGllZCBieSB0aGlzIHJlY29yZCwgaW5jbHVkaW5nIGFsbCBoZWFkZXIsIGJvZHksIGFuZCByZXNlcnZlZCBmaWVsZHMuDQogICAgLy8gUmVjb3JkSGVhZGVyQnl0ZXMoMikgICAgIC0gaW5kaWNhdGVzIHRoZSBsZW5ndGggb2YgdGhlIHJlY29yZCBoZWFkZXIgaW4gYnl0ZXMuDQogICAgLy8gUmVjb3JkTnVtYmVyKDQpICAgICAgICAgIC0gdW5pcXVlbHkgaWRlbnRpZmllcyB0aGUgcmVjb3JkIGFtb25nIGFsbCByZWNvcmRzIGluIHRoZSBmaWxlLiBUaGUgZmllbGQgY29udGFpbnMgYSBub24tbmVnYXRpdmUgb3JkaW5hbCB2YWx1ZS4gVGhlIHZhbHVlIG9mIHRoaXMgZmllbGQgaXMgYWx3YXlzIHplcm8gaW4gdGhlIExvY2FsIFByb3Zpc2lvbmluZyBGaWxlIEhlYWRlciBSZWNvcmQuDQogICAgLy8gTWFqb3JWZXJzaW9uKDEpICAgICAgICAgIC0gaWRlbnRpZmllcyB0aGUgbWFqb3IgdmVyc2lvbiBvZiB0aGUgZmlsZSBmb3JtYXQgc3BlY2lmaWNhdGlvbi4gVGhpcyBpcyBhIHBvc2l0aXZlIGludGVnZXIgdGhhdCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMS4gVGhlIE1ham9yIFZlcnNpb24gbnVtYmVyIGlzIGluY3JlbWVudGVkIHRvIGluZGljYXRlIHRoYXQgY2hhbmdlcyBoYXZlIGJlZW4gaW50cm9kdWNlZCB0aGF0IHdpbGwgY2F1c2UgY29kZSB3cml0dGVuIGFnYWluc3QgYSBsb3dlciBNYWpvciBWZXJzaW9uIG51bWJlciB0byBmYWlsLg0KICAgIC8vIE1pbm9yVmVyc2lvbigxKSAgICAgICAgICAtIGlkZW50aWZpZXMgdGhlIG1pbm9yIHZlcnNpb24gb2YgdGhlIGZpbGUgZm9ybWF0IHNwZWNpZmljYXRpb24uIFRoaXMgaXMgYW4gaW50ZWdlciB0aGF0IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwLiBUaGUgTWlub3IgVmVyc2lvbiBudW1iZXIgaXMgaW5jcmVtZW50ZWQgdG8gaW5kaWNhdGUgdGhhdCBjaGFuZ2VzIGhhdmUgYmVlbiBpbnRyb2R1Y2VkIHRoYXQgd2lsbCBub3QgY2F1c2UgY29kZSB3cml0dGVuIGFnYWluc3QgdGhlIHNhbWUgTWFqb3IgVmVyc2lvbiBhbmQgYSBsb3dlciBNaW5vciBWZXJzaW9uIG51bWJlciB0byBmYWlsLiBUaGUgcHVycG9zZSBvZiB0aGlzIGJlaGF2aW9yIGlzIHRvIGFsbG93IGEgc2luZ2xlIGxvY2FsIHByb3Zpc2lvbmluZyBmaWxlIHRvIGJlIHVzZWQgZm9yIG11bHRpcGxlIGdlbmVyYXRpb25zIG9mIEludGVs77+9IEFNVCBwbGF0Zm9ybS4NCiAgICAvLyBEYXRhUmVjb3JkQ291bnQoNCkgICAgICAgLSBpbmRpY2F0ZXMgdGhlIHRvdGFsIG51bWJlciBvZiBkYXRhIHJlY29yZHMgd3JpdHRlbiBpbiB0aGUgZmlsZSB3aGVuIGl0IHdhcyBjcmVhdGVkLg0KICAgIC8vIERhdGFSZWNvcmRzQ29uc3VtZWQoNCkgICAtIGlzIGEgY291bnRlciB2YWx1ZSB0aGF0IGJlZ2lucyBhdCAwIGFuZCBpcyBpbmNyZW1lbnRlZCBieSAxIGJ5IGVhY2ggcGxhdGZvcm0gQklPUyB3aGVuIGl0IGNvbnN1bWVzIGEgZGF0YSByZWNvcmQgZnJvbSB0aGUgZmlsZS4gVGhpcyB2YWx1ZSBpcyB1c2VkIHRvIGRldGVybWluZSB0aGUgb2Zmc2V0IG9mIHRoZSBuZXh0IGRhdGEgcmVjb3JkIGluIHRoZSBmaWxlLg0KICAgIC8vIERhdGFSZWNvcmRDaHVua0NvdW50KDIpICAtIGNvbnRhaW5zIHRoZSBudW1iZXIgb2YgNTEyLWJ5dGUgY2h1bmtzIGluIGVhY2ggZGF0YSByZWNvcmQuIEFsbCBkYXRhIHJlY29yZHMgYXJlIHRoZSBzYW1lIGxlbmd0aC4NCiAgICAvLyBNb2R1bGVMaXN0ICAgICAgICAgICAgICAgLSBjb250YWlucyBhIGxpc3Qgb2YgbW9kdWxlIGlkZW50aWZpZXJzLiBBIG1vZHVsZe+/vXMgaWRlbnRpZmllciBhcHBlYXJzIGluIHRoZSBsaXN0IGlmIGFuZCBvbmx5IGlmIHRoZSBkYXRhIHJlY29yZHMgY29udGFpbiBlbnRyaWVzIGZvciB0aGF0IG1vZHVsZS4gRWFjaCBtb2R1bGUgaWRlbnRpZmllciBpcyB0d28gYnl0ZXMgaW4gbGVuZ3RoLiBUaGUgbGlzdCBpcyB0ZXJtaW5hdGVkIGJ5IGFuIGlkZW50aWZpZXIgdmFsdWUgb2YgMC4gDQoNCiAgICB2YXIgb2JqID0ge30sIFVVSUQgPSBmaWxlLnN1YnN0cmluZygwLCAxNik7DQogICAgb2JqLmZpbGVUeXBlID0gMDsNCiAgICBmb3IgKHZhciBpIGluIEFtdFNldHVwQmluU2V0dXBHdWlkcykgeyBpZiAoVVVJRCA9PSBBbXRTZXR1cEJpblNldHVwR3VpZHNbaV0pIG9iai5maWxlVHlwZSA9ICgraSArIDEpOyB9DQogICAgaWYgKG9iai5maWxlVHlwZSA9PSAwKSByZXR1cm47IC8vIEJhZCBoZWFkZXINCiAgICBvYmoucmVjb3JkQ2h1bmtDb3VudCA9IFJlYWRTaG9ydFgoZmlsZSwgMTYpOw0KICAgIG9iai5yZWNvcmRIZWFkZXJCeXRlQ291bnQgPSBSZWFkU2hvcnRYKGZpbGUsIDE4KTsNCiAgICBvYmoucmVjb3JkTnVtYmVyID0gUmVhZEludFgoZmlsZSwgMjApOw0KICAgIG9iai5tYWpvclZlcnNpb24gPSBmaWxlLmNoYXJDb2RlQXQoMjQpOw0KICAgIG9iai5taW5vclZlcnNpb24gPSBmaWxlLmNoYXJDb2RlQXQoMjUpOw0KICAgIG9iai5mbGFncyA9IFJlYWRTaG9ydFgoZmlsZSwgMjYpOyAgICAgICAgICAgICAgICAgICAvLyBGbGFnczogMSA9IERvIG5vdCBjb25zdW1lIHJlY29yZHMNCiAgICB2YXIgZGF0YVJlY29yZENvdW50ID0gUmVhZEludFgoZmlsZSwgMjgpOw0KICAgIG9iai5kYXRhUmVjb3Jkc0NvbnN1bWVkID0gUmVhZEludFgoZmlsZSwgMzIpOw0KICAgIG9iai5kYXRhUmVjb3JkQ2h1bmtDb3VudCA9IFJlYWRTaG9ydFgoZmlsZSwgMzYpOw0KICAgIG9iai5yZWNvcmRzID0gW107DQoNCiAgICB2YXIgcHRyID0gNTEyOw0KICAgIHdoaWxlIChwdHIgKyA1MTIgPD0gZmlsZS5sZW5ndGgpIHsNCg0KICAgICAgICAvLyBGb3JtYXQgb2YgYSBkYXRhIHJlY29yZCBoZWFkZXI6DQogICAgICAgIC8vIFJlY29yZFR5cGVJZGVudGlmaWVyKDQpICAgICAgICAgICAtIGlkZW50aWZpZXMgdGhlIHR5cGUgb2YgcmVjb3JkIChpbiB0aGlzIGNhc2UgYSBkYXRhIHJlY29yZCkuIFJlY29yZCBJZGVudGlmaWVyczogSW52YWxpZCAtIDAsIERhdGEgUmVjb3JkIC0gMQ0KICAgICAgICAvLyBSZWNvcmRGbGFncyg0KSAgICAgICAgICAgICAgICAgICAgLSBjb250YWlucyBhIHNldCBvZiBiaXQgZmxhZ3MgdGhhdCBjaGFyYWN0ZXJpemUgdGhlIHJlY29yZC4NCiAgICAgICAgLy8gUmVjb3JkQ2h1bmtDb3VudCgyKSAgICAgICAgICAgICAgIC0gY29udGFpbnMgdGhlIG51bWJlciBvZiA1MTItYnl0ZSBjaHVua3Mgb2NjdXBpZWQgYnkgdGhlIHJlY29yZCBpbmNsdWRpbmcgYWxsIGhlYWRlciwgYm9keSwgYW5kIHJlc2VydmVkIGZpZWxkcy4NCiAgICAgICAgLy8gUmVjb3JkSGVhZGVyQnl0ZUNvdW50KDIpICAgICAgICAgIC0gaW5kaWNhdGVzIHRoZSBsZW5ndGggb2YgdGhlIHJlY29yZCBoZWFkZXIgaW4gYnl0ZXMuDQogICAgICAgIC8vIFJlY29yZE51bWJlcig0KSAgICAgICAgICAgICAgICAgICAtIHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhlIHJlY29yZCBhbW9uZyBhbGwgcmVjb3JkcyBpbiB0aGUgZmlsZSwgaW5jbHVkaW5nIGludmFsaWQgYXMgd2VsbCBhcyB2YWxpZCByZWNvcmRzLiBUaGUgaWRlbnRpZmllciBpcyBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLg0KDQogICAgICAgIHZhciByID0ge307DQogICAgICAgIHIudHlwZUlkZW50aWZpZXIgPSBSZWFkSW50WChmaWxlLCBwdHIpOw0KICAgICAgICByLmZsYWdzID0gUmVhZEludFgoZmlsZSwgcHRyICsgNCk7ICAgICAgICAgICAgICAvLyBGbGFnczogMSA9IFZhbGlkLCAyID0gU2NyYW1ibGVkDQogICAgICAgIHIuY2h1bmtDb3VudCA9IFJlYWRTaG9ydFgoZmlsZSwgcHRyICsgOCk7DQogICAgICAgIHIuaGVhZGVyQnl0ZUNvdW50ID0gUmVhZFNob3J0WChmaWxlLCBwdHIgKyAxMCk7DQogICAgICAgIHIubnVtYmVyID0gUmVhZEludFgoZmlsZSwgcHRyICsgMTIpOw0KICAgICAgICByLnZhcmlhYmxlcyA9IFtdOw0KDQogICAgICAgIHZhciBwdHIyID0gMCwgcmVjYmluID0gZmlsZS5zdWJzdHJpbmcocHRyICsgMjQsIHB0ciArIDUxMik7DQogICAgICAgIGlmICgoci5mbGFncyAmIDIpICE9IDApIHsgcmVjYmluID0gQW10U2V0dXBCaW5EZXNjcmFtYmxlUmVjb3JkRGF0YShyZWNiaW4pOyB9IC8vIERlLVNjcmFtYmxlIHRoZSByZWNvcmQNCiAgICAgICAgd2hpbGUgKDEpIHsNCg0KICAgICAgICAgICAgLy8gRm9ybWF0IG9mIGEgZGF0YSByZWNvcmQgZW50cnk6DQogICAgICAgICAgICAvLyBNb2R1bGVJZGVudGlmaWVyKDIpICAgICAgICAgICAtIGlkZW50aWZpZXMgdGhlIHRhcmdldCBNRSBtb2R1bGUgZm9yIHRoZSBlbnRyeS4NCiAgICAgICAgICAgIC8vIFZhcmlhYmxlSWRlbnRpZmllcigyKSAgICAgICAgIC0gYW4gZW51bWVyYXRpb24gdmFsdWUgdGhhdCBpZGVudGlmaWVzIHRoZSB2YXJpYWJsZS4gVmFyaWFibGUgaWRlbnRpZmllcnMgYXJlIHVuaXF1ZSB0byBlYWNoIE1vZHVsZUlkZW50aWZpZXIuDQogICAgICAgICAgICAvLyBWYXJpYWJsZUxlbmd0aCgyKSAgICAgICAgICAgICAtIGlzIHRoZSBsZW5ndGggb2YgdGhlIHZhcmlhYmxlIHZhbHVlIGluIGJ5dGVzLg0KICAgICAgICAgICAgLy8gVmFyaWFibGVWYWx1ZSAgICAgICAgICAgICAgICAgLSBpcyB0aGUgdmFsdWUgdG8gYmUgYXNzaWduZWQgdG8gdGhlIHZhcmlhYmxlLg0KDQogICAgICAgICAgICB2YXIgdiA9IHt9Ow0KICAgICAgICAgICAgdi5tb2R1bGVpZCA9IFJlYWRTaG9ydFgocmVjYmluLCBwdHIyKTsNCiAgICAgICAgICAgIHYudmFyaWQgPSBSZWFkU2hvcnRYKHJlY2JpbiwgcHRyMiArIDIpOw0KICAgICAgICAgICAgaWYgKHYubW9kdWxlaWQgPT0gMCB8fCB2LnZhcmlkID09IDApIGJyZWFrOw0KICAgICAgICAgICAgaWYgKEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdKSB7DQogICAgICAgICAgICAgICAgdi5sZW5ndGggPSBSZWFkU2hvcnRYKHJlY2JpbiwgcHRyMiArIDQpOw0KICAgICAgICAgICAgICAgIHYudHlwZSA9IEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdWzBdOw0KICAgICAgICAgICAgICAgIHYuZGVzYyA9IEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdWzFdOw0KICAgICAgICAgICAgICAgIHYudmFsdWUgPSByZWNiaW4uc3Vic3RyaW5nKHB0cjIgKyA4LCBwdHIyICsgOCArIHYubGVuZ3RoKTsNCiAgICAgICAgICAgICAgICBpZiAodi50eXBlID09IDEgJiYgdi5sZW5ndGggPT0gMSkgdi52YWx1ZSA9IHYudmFsdWUuY2hhckNvZGVBdCgwKTsgLy8gMSBieXRlIG51bWJlcg0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHYudHlwZSA9PSAyICYmIHYubGVuZ3RoID09IDIpIHYudmFsdWUgPSBSZWFkU2hvcnRYKHYudmFsdWUsIDApOyAvLyAyIGJ5dGUgbnVtYmVyDQogICAgICAgICAgICAgICAgZWxzZSBpZiAodi50eXBlID09IDMgJiYgdi5sZW5ndGggPT0gNCkgdi52YWx1ZSA9IFJlYWRJbnRYKHYudmFsdWUsIDApOyAvLyA0IGJ5dGUgbnVtYmVyDQogICAgICAgICAgICAgICAgZWxzZSBpZiAodi50eXBlID09IDQpIHYudmFsdWUgPSBndWlkVG9TdHIocnN0cjJoZXgodi52YWx1ZSkpOyAvLyBHVUlEDQogICAgICAgICAgICAgICAgci52YXJpYWJsZXMucHVzaCh2KTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHB0cjIgKz0gKDggKyAoTWF0aC5mbG9vcigodi5sZW5ndGggKyAzKSAvIDQpICogNCkpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gU29ydCB0aGUgdmFyaWFibGVzDQogICAgICAgIHIudmFyaWFibGVzLnNvcnQoQW10U2V0dXBCaW5WYXJpYWJsZUNvbXBhcmUpOw0KDQogICAgICAgIG9iai5yZWNvcmRzLnB1c2gocik7DQogICAgICAgIHB0ciArPSA1MTI7DQogICAgfQ0KDQogICAgaWYgKGRhdGFSZWNvcmRDb3VudCAhPSBvYmoucmVjb3Jkcy5sZW5ndGgpIHJldHVybjsgLy8gTWlzbWF0Y2ggcmVjb3JkIGNvdW50DQogICAgcmV0dXJuIG9iajsNCn0NCg0KLy8gQ29uc3RydWN0IGEgU2V0dXAuYmluIGZpbGUNCnZhciBBbXRTZXR1cEJpbkVuY29kZSA9IGZ1bmN0aW9uIChvYmopIHsNCiAgICBpZiAob2JqLmZpbGVUeXBlIDwgMSAmJiBvYmouZmlsZVR5cGUgPiBBbXRTZXR1cEJpblNldHVwR3VpZHMubGVuZ3RoKSByZXR1cm4gbnVsbDsNCiAgICB2YXIgb3V0ID0gW10sIHIgPSBBbXRTZXR1cEJpblNldHVwR3VpZHNbb2JqLmZpbGVUeXBlIC0gMV0sIHJlY2NvdW50ID0gMDsNCiAgICByICs9IFNob3J0VG9TdHJYKG9iai5yZWNvcmRDaHVua0NvdW50KTsNCiAgICByICs9IFNob3J0VG9TdHJYKG9iai5yZWNvcmRIZWFkZXJCeXRlQ291bnQpOw0KICAgIHIgKz0gSW50VG9TdHJYKG9iai5yZWNvcmROdW1iZXIpOw0KICAgIHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShvYmoubWFqb3JWZXJzaW9uLCBvYmoubWlub3JWZXJzaW9uKTsNCiAgICByICs9IFNob3J0VG9TdHJYKG9iai5mbGFncyk7IC8vIEZsYWdzOiAxID0gRG8gbm90IGNvbnN1bWUgcmVjb3Jkcw0KICAgIHIgKz0gSW50VG9TdHJYKG9iai5yZWNvcmRzLmxlbmd0aCk7DQogICAgciArPSBJbnRUb1N0clgob2JqLmRhdGFSZWNvcmRzQ29uc3VtZWQpOw0KICAgIHIgKz0gU2hvcnRUb1N0clgob2JqLmRhdGFSZWNvcmRDaHVua0NvdW50KTsNCiAgICB3aGlsZSAoci5sZW5ndGggPCA1MTIpIHsgciArPSAiXDAiOyB9IC8vIFBhZCB0aGUgaGVhZGVyDQogICAgb3V0LnB1c2gocik7DQoNCiAgICAvLyBXcml0ZSBlYWNoIHJlY29yZA0KICAgIGZvciAodmFyIGkgaW4gb2JqLnJlY29yZHMpIHsNCiAgICAgICAgdmFyIHIyID0gIiIsIHJlYyA9IG9iai5yZWNvcmRzW2ldOw0KICAgICAgICByMiArPSBJbnRUb1N0clgocmVjLnR5cGVJZGVudGlmaWVyKTsNCiAgICAgICAgcjIgKz0gSW50VG9TdHJYKHJlYy5mbGFncyk7DQogICAgICAgIHIyICs9IEludFRvU3RyWCgwKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVzZXJ2ZWQNCiAgICAgICAgcjIgKz0gSW50VG9TdHJYKDApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXNlcnZlZA0KICAgICAgICByMiArPSBTaG9ydFRvU3RyWCgxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlYy5jaHVua0NvdW50DQogICAgICAgIHIyICs9IFNob3J0VG9TdHJYKDI0KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVjLmhlYWRlckJ5dGVDb3VudA0KICAgICAgICByMiArPSBJbnRUb1N0clgoKytyZWNjb3VudCk7DQoNCiAgICAgICAgLy8gU29ydCB0aGUgdmFyaWFibGVzDQogICAgICAgIHJlYy52YXJpYWJsZXMuc29ydChBbXRTZXR1cEJpblZhcmlhYmxlQ29tcGFyZSk7DQoNCiAgICAgICAgLyoNCiAgICAgICAgLy8gQ2hhbmdlIHZhcmlhYmxlIHByaW9yaXR5DQogICAgICAgIEFtdFNldHVwQmluTW92ZVRvVG9wKHIudmFyaWFibGVzLCAxLCAzKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFuYWdlYWJpbGl0eSBGZWF0dXJlIFNlbGVjdGlvbg0KICAgICAgICBBbXRTZXR1cEJpbk1vdmVUb1RvcChyLnZhcmlhYmxlcywgMSwgMik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5ldyBNRUJ4IHBhc3N3b3JkDQogICAgICAgIEFtdFNldHVwQmluTW92ZVRvVG9wKHIudmFyaWFibGVzLCAxLCAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ3VycmVudCBNRUJ4IHBhc3N3b3JkDQogICAgICAgICovDQoNCiAgICAgICAgLy8gV3JpdGUgZWFjaCB2YXJpYWJsZQ0KICAgICAgICBmb3IgKHZhciBqIGluIHJlYy52YXJpYWJsZXMpIHsNCiAgICAgICAgICAgIHZhciByMyA9ICIiLCB2ID0gcmVjLnZhcmlhYmxlc1tqXSwgZGF0YSA9IHYudmFsdWU7DQogICAgICAgICAgICB2LnR5cGUgPSBBbXRTZXR1cEJpblZhcklkc1t2Lm1vZHVsZWlkXVt2LnZhcmlkXVswXTsgICAgICAgICAgICAgLy8gU2V0IHRoZSBjb3JyZWN0IHR5cGUgaWYgbm90IGFscmVheSBjb25uZWN0DQogICAgICAgICAgICBpZiAoKHYudHlwZSA+IDApICYmICh2LnR5cGUgPCA0KSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhIG51bWVyaWMgdmFsdWUsIGVuY29kZSBpdCBjb3JyZWN0bHkNCiAgICAgICAgICAgICAgICBkYXRhID0gcGFyc2VJbnQoZGF0YSk7DQogICAgICAgICAgICAgICAgaWYgKHYudHlwZSA9PSAxKSBkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZShkYXRhKTsNCiAgICAgICAgICAgICAgICBpZiAodi50eXBlID09IDIpIGRhdGEgPSBTaG9ydFRvU3RyWChkYXRhKTsNCiAgICAgICAgICAgICAgICBpZiAodi50eXBlID09IDMpIGRhdGEgPSBJbnRUb1N0clgoZGF0YSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAodi50eXBlID09IDQpIHsgZGF0YSA9IGhleDJyc3RyKGd1aWRUb1N0cihkYXRhLnNwbGl0KCctJykuam9pbignJykpLnNwbGl0KCctJykuam9pbignJykpOyB9DQogICAgICAgICAgICByMyArPSBTaG9ydFRvU3RyWCh2Lm1vZHVsZWlkKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9kdWxlIElkZW50aWZpZXINCiAgICAgICAgICAgIHIzICs9IFNob3J0VG9TdHJYKHYudmFyaWQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWYXJpYWJsZSBJZGVudGlmaWVyDQogICAgICAgICAgICByMyArPSBTaG9ydFRvU3RyWChkYXRhLmxlbmd0aCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmFyaWFibGUgTGVuZ3RoDQogICAgICAgICAgICByMyArPSBTaG9ydFRvU3RyWCgwKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVzZXJ2ZWQNCiAgICAgICAgICAgIHIzICs9IGRhdGE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWYXJpYWJsZSBEYXRhDQogICAgICAgICAgICB3aGlsZSAocjMubGVuZ3RoICUgNCAhPSAwKSB7IHIzICs9ICJcMCI7IH0gICAgICAgICAgICAgICAgICAgICAgLy8gUGFkIHRoZSB2YXJpYWJsZQ0KICAgICAgICAgICAgcjIgKz0gcjM7DQogICAgICAgIH0NCg0KICAgICAgICB3aGlsZSAocjIubGVuZ3RoIDwgNTEyKSB7IHIyICs9ICJcMCI7IH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBhZCB0aGUgcmVjb3JkDQogICAgICAgIGlmICgocmVjLmZsYWdzICYgMikgIT0gMCkgeyByMiA9IHIyLnN1YnN0cmluZygwLCAyNCkgKyBBbXRTZXR1cEJpblNjcmFtYmxlUmVjb3JkRGF0YShyMi5zdWJzdHJpbmcoMjQpKTsgfSAvLyBTY3JhbWJsZSB0aGUgcmVjb3JkIHN0YXJ0aW5nIGF0IGJ5dGUgMjQsIGFmdGVyIHRoZSBoZWFkZXINCiAgICAgICAgb3V0LnB1c2gocjIpOw0KICAgIH0NCiAgICByZXR1cm4gb3V0LmpvaW4oJycpOw0KfQ0KDQovLyBVc2VkIHRvIHNvcnQgdmFyaWFibGVzDQpmdW5jdGlvbiBBbXRTZXR1cEJpblZhcmlhYmxlQ29tcGFyZShhLCBiKSB7DQogICAgaWYgKGEubW9kdWxlaWQgPiBiLm1vZHVsZWlkKSByZXR1cm4gMTsNCiAgICBpZiAoYS5tb2R1bGVpZCA8IGIubW9kdWxlaWQpIHJldHVybiAtMTsNCiAgICBpZiAoYS52YXJpZCA+IGIudmFyaWQpIHJldHVybiAxOw0KICAgIGlmIChhLnZhcmlkIDwgYi52YXJpZCkgcmV0dXJuIC0xOw0KICAgIHJldHVybiAwOw0KfQ0KDQovLyBTY3JhbWJsZSBhbmQgdW4tc2NyYW1ibGUgcmVjb3Jkcw0KZnVuY3Rpb24gQW10U2V0dXBCaW5TY3JhbWJsZVJlY29yZERhdGEoZGF0YSkgeyB2YXIgb3V0ID0gIiI7IGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykgeyBvdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoZGF0YS5jaGFyQ29kZUF0KGkpICsgMTcpICYgMHhGRik7IH0gcmV0dXJuIG91dDsgfQ0KZnVuY3Rpb24gQW10U2V0dXBCaW5EZXNjcmFtYmxlUmVjb3JkRGF0YShkYXRhKSB7IHZhciBvdXQgPSAiIjsgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7IG91dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChkYXRhLmNoYXJDb2RlQXQoaSkgKyAweEVGKSAmIDB4RkYpOyB9IHJldHVybiBvdXQ7IH0NCg0KLy8gRmluZCBhIG1vZHVsZWlkL3ZhcmlkIGluIHRoZSB2YXJpYWJsZSBsaXN0LCBpZiBmb3VuZCwgbW92ZSBpdCB0byB0aGUgdG9wDQovL2Z1bmN0aW9uIEFtdFNldHVwQmluTW92ZVRvVG9wKHZhcmlhYmxlcywgbW9kdWxlaWQsIHZhcmlkKSB7IHZhciBpID0gLTE7IGZvciAodmFyIGogaW4gdmFyaWFibGVzKSB7IGlmICgodmFyaWFibGVzW2pdLm1vZHVsZWlkID09IG1vZHVsZWlkKSAmJiAodmFyaWFibGVzW2pdLnZhcmlkID09IHZhcmlkKSkgeyBpID0gajsgfSB9IGlmIChpID4gMSkgeyBBcnJheUVsZW1lbnRNb3ZlKHZhcmlhYmxlcywgaSwgMCk7IH0gfQ0KLyogRmlsZVNhdmVyLmpzDQogKiBBIHNhdmVBcygpIEZpbGVTYXZlciBpbXBsZW1lbnRhdGlvbi4NCiAqIDEuMS4yMDE1MTAwMw0KICoNCiAqIEJ5IEVsaSBHcmV5LCBodHRwOi8vZWxpZ3JleS5jb20NCiAqIExpY2Vuc2U6IE1JVA0KICogICBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2VsaWdyZXkvRmlsZVNhdmVyLmpzL2Jsb2IvbWFzdGVyL0xJQ0VOU0UubWQNCiAqLw0KDQovKmdsb2JhbCBzZWxmICovDQovKmpzbGludCBiaXR3aXNlOiB0cnVlLCBpbmRlbnQ6IDQsIGxheGJyZWFrOiB0cnVlLCBsYXhjb21tYTogdHJ1ZSwgc21hcnR0YWJzOiB0cnVlLCBwbHVzcGx1czogdHJ1ZSAqLw0KDQovKiEgQHNvdXJjZSBodHRwOi8vcHVybC5lbGlncmV5LmNvbS9naXRodWIvRmlsZVNhdmVyLmpzL2Jsb2IvbWFzdGVyL0ZpbGVTYXZlci5qcyAqLw0KDQp2YXIgc2F2ZUFzID0gc2F2ZUFzIHx8IChmdW5jdGlvbiAodmlldykgew0KICAgICJ1c2Ugc3RyaWN0IjsNCiAgICAvLyBJRSA8MTAgaXMgZXhwbGljaXRseSB1bnN1cHBvcnRlZA0KICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSAidW5kZWZpbmVkIiAmJiAvTVNJRSBbMS05XVwuLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7DQogICAgICAgIHJldHVybjsNCiAgICB9DQogICAgdmFyDQoJCSAgZG9jID0gdmlldy5kb2N1bWVudA0KCQkgIC8vIG9ubHkgZ2V0IFVSTCB3aGVuIG5lY2Vzc2FyeSBpbiBjYXNlIEJsb2IuanMgaGFzbid0IG92ZXJyaWRkZW4gaXQgeWV0DQoJCSwgZ2V0X1VSTCA9IGZ1bmN0aW9uICgpIHsNCgkJICAgIHJldHVybiB2aWV3LlVSTCB8fCB2aWV3LndlYmtpdFVSTCB8fCB2aWV3Ow0KCQl9DQoJCSwgc2F2ZV9saW5rID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIsICJhIikNCgkJLCBjYW5fdXNlX3NhdmVfbGluayA9ICJkb3dubG9hZCIgaW4gc2F2ZV9saW5rDQoJCSwgY2xpY2sgPSBmdW5jdGlvbiAobm9kZSkgew0KCQkgICAgdmFyIGV2ZW50ID0gbmV3IE1vdXNlRXZlbnQoImNsaWNrIik7DQoJCSAgICBub2RlLmRpc3BhdGNoRXZlbnQoZXZlbnQpOw0KCQl9DQoJCSwgaXNfc2FmYXJpID0gL1ZlcnNpb25cL1tcZFwuXSsuKlNhZmFyaS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KQ0KCQksIHdlYmtpdF9yZXFfZnMgPSB2aWV3LndlYmtpdFJlcXVlc3RGaWxlU3lzdGVtDQoJCSwgcmVxX2ZzID0gdmlldy5yZXF1ZXN0RmlsZVN5c3RlbSB8fCB3ZWJraXRfcmVxX2ZzIHx8IHZpZXcubW96UmVxdWVzdEZpbGVTeXN0ZW0NCgkJLCB0aHJvd19vdXRzaWRlID0gZnVuY3Rpb24gKGV4KSB7DQoJCSAgICAodmlldy5zZXRJbW1lZGlhdGUgfHwgdmlldy5zZXRUaW1lb3V0KShmdW5jdGlvbiAoKSB7DQoJCSAgICAgICAgdGhyb3cgZXg7DQoJCSAgICB9LCAwKTsNCgkJfQ0KCQksIGZvcmNlX3NhdmVhYmxlX3R5cGUgPSAiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIg0KCQksIGZzX21pbl9zaXplID0gMA0KCQkvLyBTZWUgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTM3NTI5NyNjNyBhbmQNCgkJLy8gaHR0cHM6Ly9naXRodWIuY29tL2VsaWdyZXkvRmlsZVNhdmVyLmpzL2NvbW1pdC80ODU5MzBhI2NvbW1pdGNvbW1lbnQtODc2ODA0Nw0KCQkvLyBmb3IgdGhlIHJlYXNvbmluZyBiZWhpbmQgdGhlIHRpbWVvdXQgYW5kIHJldm9jYXRpb24gZmxvdw0KCQksIGFyYml0cmFyeV9yZXZva2VfdGltZW91dCA9IDUwMCAvLyBpbiBtcw0KCQksIHJldm9rZSA9IGZ1bmN0aW9uIChmaWxlKSB7DQoJCSAgICB2YXIgcmV2b2tlciA9IGZ1bmN0aW9uICgpIHsNCgkJICAgICAgICBpZiAodHlwZW9mIGZpbGUgPT09ICJzdHJpbmciKSB7IC8vIGZpbGUgaXMgYW4gb2JqZWN0IFVSTA0KCQkgICAgICAgICAgICBnZXRfVVJMKCkucmV2b2tlT2JqZWN0VVJMKGZpbGUpOw0KCQkgICAgICAgIH0gZWxzZSB7IC8vIGZpbGUgaXMgYSBGaWxlDQoJCSAgICAgICAgICAgIGZpbGUucmVtb3ZlKCk7DQoJCSAgICAgICAgfQ0KCQkgICAgfTsNCgkJICAgIGlmICh2aWV3LmNocm9tZSkgew0KCQkgICAgICAgIHJldm9rZXIoKTsNCgkJICAgIH0gZWxzZSB7DQoJCSAgICAgICAgc2V0VGltZW91dChyZXZva2VyLCBhcmJpdHJhcnlfcmV2b2tlX3RpbWVvdXQpOw0KCQkgICAgfQ0KCQl9DQoJCSwgZGlzcGF0Y2ggPSBmdW5jdGlvbiAoZmlsZXNhdmVyLCBldmVudF90eXBlcywgZXZlbnQpIHsNCgkJICAgIGV2ZW50X3R5cGVzID0gW10uY29uY2F0KGV2ZW50X3R5cGVzKTsNCgkJICAgIHZhciBpID0gZXZlbnRfdHlwZXMubGVuZ3RoOw0KCQkgICAgd2hpbGUgKGktLSkgew0KCQkgICAgICAgIHZhciBsaXN0ZW5lciA9IGZpbGVzYXZlclsib24iICsgZXZlbnRfdHlwZXNbaV1dOw0KCQkgICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICJmdW5jdGlvbiIpIHsNCgkJICAgICAgICAgICAgdHJ5IHsNCgkJICAgICAgICAgICAgICAgIGxpc3RlbmVyLmNhbGwoZmlsZXNhdmVyLCBldmVudCB8fCBmaWxlc2F2ZXIpOw0KCQkgICAgICAgICAgICB9IGNhdGNoIChleCkgew0KCQkgICAgICAgICAgICAgICAgdGhyb3dfb3V0c2lkZShleCk7DQoJCSAgICAgICAgICAgIH0NCgkJICAgICAgICB9DQoJCSAgICB9DQoJCX0NCgkJLCBhdXRvX2JvbSA9IGZ1bmN0aW9uIChibG9iKSB7DQoJCSAgICAvLyBwcmVwZW5kIEJPTSBmb3IgVVRGLTggWE1MIGFuZCB0ZXh0IHR5cGVzIChpbmNsdWRpbmcgSFRNTCkNCgkJICAgIGlmICgvXlxzKig/OnRleHRcL1xTKnxhcHBsaWNhdGlvblwveG1sfFxTKlwvXFMqXCt4bWwpXHMqOy4qY2hhcnNldFxzKj1ccyp1dGYtOC9pLnRlc3QoYmxvYi50eXBlKSkgew0KCQkgICAgICAgIHJldHVybiBuZXcgQmxvYihbIlx1ZmVmZiIsIGJsb2JdLCB7IHR5cGU6IGJsb2IudHlwZSB9KTsNCgkJICAgIH0NCgkJICAgIHJldHVybiBibG9iOw0KCQl9DQoJCSwgRmlsZVNhdmVyID0gZnVuY3Rpb24gKGJsb2IsIG5hbWUsIG5vX2F1dG9fYm9tKSB7DQoJCSAgICBpZiAoIW5vX2F1dG9fYm9tKSB7DQoJCSAgICAgICAgYmxvYiA9IGF1dG9fYm9tKGJsb2IpOw0KCQkgICAgfQ0KCQkgICAgLy8gRmlyc3QgdHJ5IGEuZG93bmxvYWQsIHRoZW4gd2ViIGZpbGVzeXN0ZW0sIHRoZW4gb2JqZWN0IFVSTHMNCgkJICAgIHZhcg0KCQkJCSAgZmlsZXNhdmVyID0gdGhpcw0KCQkJCSwgdHlwZSA9IGJsb2IudHlwZQ0KCQkJCSwgYmxvYl9jaGFuZ2VkID0gZmFsc2UNCgkJCQksIG9iamVjdF91cmwNCgkJCQksIHRhcmdldF92aWV3DQoJCQkJLCBkaXNwYXRjaF9hbGwgPSBmdW5jdGlvbiAoKSB7DQoJCQkJICAgIGRpc3BhdGNoKGZpbGVzYXZlciwgIndyaXRlc3RhcnQgcHJvZ3Jlc3Mgd3JpdGUgd3JpdGVlbmQiLnNwbGl0KCIgIikpOw0KCQkJCX0NCgkJCQkvLyBvbiBhbnkgZmlsZXN5cyBlcnJvcnMgcmV2ZXJ0IHRvIHNhdmluZyB3aXRoIG9iamVjdCBVUkxzDQoJCQkJLCBmc19lcnJvciA9IGZ1bmN0aW9uICgpIHsNCgkJCQkgICAgaWYgKHRhcmdldF92aWV3ICYmIGlzX3NhZmFyaSAmJiB0eXBlb2YgRmlsZVJlYWRlciAhPT0gInVuZGVmaW5lZCIpIHsNCgkJCQkgICAgICAgIC8vIFNhZmFyaSBkb2Vzbid0IGFsbG93IGRvd25sb2FkaW5nIG9mIGJsb2IgdXJscw0KCQkJCSAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQoJCQkJICAgICAgICByZWFkZXIub25sb2FkZW5kID0gZnVuY3Rpb24gKCkgew0KCQkJCSAgICAgICAgICAgIHZhciBiYXNlNjREYXRhID0gcmVhZGVyLnJlc3VsdDsNCgkJCQkgICAgICAgICAgICB0YXJnZXRfdmlldy5sb2NhdGlvbi5ocmVmID0gImRhdGE6YXR0YWNobWVudC9maWxlIiArIGJhc2U2NERhdGEuc2xpY2UoYmFzZTY0RGF0YS5zZWFyY2goL1ssO10vKSk7DQoJCQkJICAgICAgICAgICAgZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTsNCgkJCQkgICAgICAgICAgICBkaXNwYXRjaF9hbGwoKTsNCgkJCQkgICAgICAgIH07DQoJCQkJICAgICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChibG9iKTsNCgkJCQkgICAgICAgIGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLklOSVQ7DQoJCQkJICAgICAgICByZXR1cm47DQoJCQkJICAgIH0NCgkJCQkgICAgLy8gZG9uJ3QgY3JlYXRlIG1vcmUgb2JqZWN0IFVSTHMgdGhhbiBuZWVkZWQNCgkJCQkgICAgaWYgKGJsb2JfY2hhbmdlZCB8fCAhb2JqZWN0X3VybCkgew0KCQkJCSAgICAgICAgb2JqZWN0X3VybCA9IGdldF9VUkwoKS5jcmVhdGVPYmplY3RVUkwoYmxvYik7DQoJCQkJICAgIH0NCgkJCQkgICAgaWYgKHRhcmdldF92aWV3KSB7DQoJCQkJICAgICAgICB0YXJnZXRfdmlldy5sb2NhdGlvbi5ocmVmID0gb2JqZWN0X3VybDsNCgkJCQkgICAgfSBlbHNlIHsNCgkJCQkgICAgICAgIHZhciBuZXdfdGFiID0gdmlldy5vcGVuKG9iamVjdF91cmwsICJfYmxhbmsiKTsNCgkJCQkgICAgICAgIGlmIChuZXdfdGFiID09IHVuZGVmaW5lZCAmJiBpc19zYWZhcmkpIHsNCgkJCQkgICAgICAgICAgICAvL0FwcGxlIGRvIG5vdCBhbGxvdyB3aW5kb3cub3Blbiwgc2VlIGh0dHA6Ly9iaXQubHkvMWtaZmZSSQ0KCQkJCSAgICAgICAgICAgIHZpZXcubG9jYXRpb24uaHJlZiA9IG9iamVjdF91cmwNCgkJCQkgICAgICAgIH0NCgkJCQkgICAgfQ0KCQkJCSAgICBmaWxlc2F2ZXIucmVhZHlTdGF0ZSA9IGZpbGVzYXZlci5ET05FOw0KCQkJCSAgICBkaXNwYXRjaF9hbGwoKTsNCgkJCQkgICAgcmV2b2tlKG9iamVjdF91cmwpOw0KCQkJCX0NCgkJCQksIGFib3J0YWJsZSA9IGZ1bmN0aW9uIChmdW5jKSB7DQoJCQkJICAgIHJldHVybiBmdW5jdGlvbiAoKSB7DQoJCQkJICAgICAgICBpZiAoZmlsZXNhdmVyLnJlYWR5U3RhdGUgIT09IGZpbGVzYXZlci5ET05FKSB7DQoJCQkJICAgICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsNCgkJCQkgICAgICAgIH0NCgkJCQkgICAgfTsNCgkJCQl9DQoJCQkJLCBjcmVhdGVfaWZfbm90X2ZvdW5kID0geyBjcmVhdGU6IHRydWUsIGV4Y2x1c2l2ZTogZmFsc2UgfQ0KCQkJCSwgc2xpY2UNCgkJICAgIDsNCgkJICAgIGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLklOSVQ7DQoJCSAgICBpZiAoIW5hbWUpIHsNCgkJICAgICAgICBuYW1lID0gImRvd25sb2FkIjsNCgkJICAgIH0NCgkJICAgIGlmIChjYW5fdXNlX3NhdmVfbGluaykgew0KCQkgICAgICAgIG9iamVjdF91cmwgPSBnZXRfVVJMKCkuY3JlYXRlT2JqZWN0VVJMKGJsb2IpOw0KCQkgICAgICAgIHNhdmVfbGluay5ocmVmID0gb2JqZWN0X3VybDsNCgkJICAgICAgICBzYXZlX2xpbmsuZG93bmxvYWQgPSBuYW1lOw0KCQkgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgew0KCQkgICAgICAgICAgICBjbGljayhzYXZlX2xpbmspOw0KCQkgICAgICAgICAgICBkaXNwYXRjaF9hbGwoKTsNCgkJICAgICAgICAgICAgcmV2b2tlKG9iamVjdF91cmwpOw0KCQkgICAgICAgICAgICBmaWxlc2F2ZXIucmVhZHlTdGF0ZSA9IGZpbGVzYXZlci5ET05FOw0KCQkgICAgICAgIH0pOw0KCQkgICAgICAgIHJldHVybjsNCgkJICAgIH0NCgkJICAgIC8vIE9iamVjdCBhbmQgd2ViIGZpbGVzeXN0ZW0gVVJMcyBoYXZlIGEgcHJvYmxlbSBzYXZpbmcgaW4gR29vZ2xlIENocm9tZSB3aGVuDQoJCSAgICAvLyB2aWV3ZWQgaW4gYSB0YWIsIHNvIEkgZm9yY2Ugc2F2ZSB3aXRoIGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbQ0KCQkgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9OTExNTgNCgkJICAgIC8vIFVwZGF0ZTogR29vZ2xlIGVycmFudGx5IGNsb3NlZCA5MTE1OCwgSSBzdWJtaXR0ZWQgaXQgYWdhaW46DQoJCSAgICAvLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9Mzg5NjQyDQoJCSAgICBpZiAodmlldy5jaHJvbWUgJiYgdHlwZSAmJiB0eXBlICE9PSBmb3JjZV9zYXZlYWJsZV90eXBlKSB7DQoJCSAgICAgICAgc2xpY2UgPSBibG9iLnNsaWNlIHx8IGJsb2Iud2Via2l0U2xpY2U7DQoJCSAgICAgICAgYmxvYiA9IHNsaWNlLmNhbGwoYmxvYiwgMCwgYmxvYi5zaXplLCBmb3JjZV9zYXZlYWJsZV90eXBlKTsNCgkJICAgICAgICBibG9iX2NoYW5nZWQgPSB0cnVlOw0KCQkgICAgfQ0KCQkgICAgLy8gU2luY2UgSSBjYW4ndCBiZSBzdXJlIHRoYXQgdGhlIGd1ZXNzZWQgbWVkaWEgdHlwZSB3aWxsIHRyaWdnZXIgYSBkb3dubG9hZA0KCQkgICAgLy8gaW4gV2ViS2l0LCBJIGFwcGVuZCAuZG93bmxvYWQgdG8gdGhlIGZpbGVuYW1lLg0KCQkgICAgLy8gaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTY1NDQwDQoJCSAgICBpZiAod2Via2l0X3JlcV9mcyAmJiBuYW1lICE9PSAiZG93bmxvYWQiKSB7DQoJCSAgICAgICAgbmFtZSArPSAiLmRvd25sb2FkIjsNCgkJICAgIH0NCgkJICAgIGlmICh0eXBlID09PSBmb3JjZV9zYXZlYWJsZV90eXBlIHx8IHdlYmtpdF9yZXFfZnMpIHsNCgkJICAgICAgICB0YXJnZXRfdmlldyA9IHZpZXc7DQoJCSAgICB9DQoJCSAgICBpZiAoIXJlcV9mcykgew0KCQkgICAgICAgIGZzX2Vycm9yKCk7DQoJCSAgICAgICAgcmV0dXJuOw0KCQkgICAgfQ0KCQkgICAgZnNfbWluX3NpemUgKz0gYmxvYi5zaXplOw0KCQkgICAgcmVxX2ZzKHZpZXcuVEVNUE9SQVJZLCBmc19taW5fc2l6ZSwgYWJvcnRhYmxlKGZ1bmN0aW9uIChmcykgew0KCQkgICAgICAgIGZzLnJvb3QuZ2V0RGlyZWN0b3J5KCJzYXZlZCIsIGNyZWF0ZV9pZl9ub3RfZm91bmQsIGFib3J0YWJsZShmdW5jdGlvbiAoZGlyKSB7DQoJCSAgICAgICAgICAgIHZhciBzYXZlID0gZnVuY3Rpb24gKCkgew0KCQkgICAgICAgICAgICAgICAgZGlyLmdldEZpbGUobmFtZSwgY3JlYXRlX2lmX25vdF9mb3VuZCwgYWJvcnRhYmxlKGZ1bmN0aW9uIChmaWxlKSB7DQoJCSAgICAgICAgICAgICAgICAgICAgZmlsZS5jcmVhdGVXcml0ZXIoYWJvcnRhYmxlKGZ1bmN0aW9uICh3cml0ZXIpIHsNCgkJICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLm9ud3JpdGVlbmQgPSBmdW5jdGlvbiAoZXZlbnQpIHsNCgkJICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldF92aWV3LmxvY2F0aW9uLmhyZWYgPSBmaWxlLnRvVVJMKCk7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc2F2ZXIucmVhZHlTdGF0ZSA9IGZpbGVzYXZlci5ET05FOw0KCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2goZmlsZXNhdmVyLCAid3JpdGVlbmQiLCBldmVudCk7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXZva2UoZmlsZSk7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIH07DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci5vbmVycm9yID0gZnVuY3Rpb24gKCkgew0KCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gd3JpdGVyLmVycm9yOw0KCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgIT09IGVycm9yLkFCT1JUX0VSUikgew0KCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZzX2Vycm9yKCk7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIH07DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICJ3cml0ZXN0YXJ0IHByb2dyZXNzIHdyaXRlIGFib3J0Ii5zcGxpdCgiICIpLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXJbIm9uIiArIGV2ZW50XSA9IGZpbGVzYXZlclsib24iICsgZXZlbnRdOw0KCQkgICAgICAgICAgICAgICAgICAgICAgICB9KTsNCgkJICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGJsb2IpOw0KCQkgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc2F2ZXIuYWJvcnQgPSBmdW5jdGlvbiAoKSB7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIuYWJvcnQoKTsNCgkJICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLkRPTkU7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIH07DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLldSSVRJTkc7DQoJCSAgICAgICAgICAgICAgICAgICAgfSksIGZzX2Vycm9yKTsNCgkJICAgICAgICAgICAgICAgIH0pLCBmc19lcnJvcik7DQoJCSAgICAgICAgICAgIH07DQoJCSAgICAgICAgICAgIGRpci5nZXRGaWxlKG5hbWUsIHsgY3JlYXRlOiBmYWxzZSB9LCBhYm9ydGFibGUoZnVuY3Rpb24gKGZpbGUpIHsNCgkJICAgICAgICAgICAgICAgIC8vIGRlbGV0ZSBmaWxlIGlmIGl0IGFscmVhZHkgZXhpc3RzDQoJCSAgICAgICAgICAgICAgICBmaWxlLnJlbW92ZSgpOw0KCQkgICAgICAgICAgICAgICAgc2F2ZSgpOw0KCQkgICAgICAgICAgICB9KSwgYWJvcnRhYmxlKGZ1bmN0aW9uIChleCkgew0KCQkgICAgICAgICAgICAgICAgaWYgKGV4LmNvZGUgPT09IGV4Lk5PVF9GT1VORF9FUlIpIHsNCgkJICAgICAgICAgICAgICAgICAgICBzYXZlKCk7DQoJCSAgICAgICAgICAgICAgICB9IGVsc2Ugew0KCQkgICAgICAgICAgICAgICAgICAgIGZzX2Vycm9yKCk7DQoJCSAgICAgICAgICAgICAgICB9DQoJCSAgICAgICAgICAgIH0pKTsNCgkJICAgICAgICB9KSwgZnNfZXJyb3IpOw0KCQkgICAgfSksIGZzX2Vycm9yKTsNCgkJfQ0KCQksIEZTX3Byb3RvID0gRmlsZVNhdmVyLnByb3RvdHlwZQ0KCQksIHNhdmVBcyA9IGZ1bmN0aW9uIChibG9iLCBuYW1lLCBub19hdXRvX2JvbSkgew0KCQkgICAgcmV0dXJuIG5ldyBGaWxlU2F2ZXIoYmxvYiwgbmFtZSwgbm9fYXV0b19ib20pOw0KCQl9DQogICAgOw0KICAgIC8vIElFIDEwKyAobmF0aXZlIHNhdmVBcykNCiAgICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gInVuZGVmaW5lZCIgJiYgbmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IpIHsNCiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChibG9iLCBuYW1lLCBub19hdXRvX2JvbSkgew0KICAgICAgICAgICAgaWYgKCFub19hdXRvX2JvbSkgew0KICAgICAgICAgICAgICAgIGJsb2IgPSBhdXRvX2JvbShibG9iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHJldHVybiBuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYihibG9iLCBuYW1lIHx8ICJkb3dubG9hZCIpOw0KICAgICAgICB9Ow0KICAgIH0NCg0KICAgIEZTX3Byb3RvLmFib3J0ID0gZnVuY3Rpb24gKCkgew0KICAgICAgICB2YXIgZmlsZXNhdmVyID0gdGhpczsNCiAgICAgICAgZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTsNCiAgICAgICAgZGlzcGF0Y2goZmlsZXNhdmVyLCAiYWJvcnQiKTsNCiAgICB9Ow0KICAgIEZTX3Byb3RvLnJlYWR5U3RhdGUgPSBGU19wcm90by5JTklUID0gMDsNCiAgICBGU19wcm90by5XUklUSU5HID0gMTsNCiAgICBGU19wcm90by5ET05FID0gMjsNCg0KICAgIEZTX3Byb3RvLmVycm9yID0NCglGU19wcm90by5vbndyaXRlc3RhcnQgPQ0KCUZTX3Byb3RvLm9ucHJvZ3Jlc3MgPQ0KCUZTX3Byb3RvLm9ud3JpdGUgPQ0KCUZTX3Byb3RvLm9uYWJvcnQgPQ0KCUZTX3Byb3RvLm9uZXJyb3IgPQ0KCUZTX3Byb3RvLm9ud3JpdGVlbmQgPQ0KCQludWxsOw0KDQogICAgcmV0dXJuIHNhdmVBczsNCn0oDQoJICAgdHlwZW9mIHNlbGYgIT09ICJ1bmRlZmluZWQiICYmIHNlbGYNCgl8fCB0eXBlb2Ygd2luZG93ICE9PSAidW5kZWZpbmVkIiAmJiB3aW5kb3cNCgl8fCB0aGlzLmNvbnRlbnQNCikpOw0KLy8gYHNlbGZgIGlzIHVuZGVmaW5lZCBpbiBGaXJlZm94IGZvciBBbmRyb2lkIGNvbnRlbnQgc2NyaXB0IGNvbnRleHQNCi8vIHdoaWxlIGB0aGlzYCBpcyBuc0lDb250ZW50RnJhbWVNZXNzYWdlTWFuYWdlcg0KLy8gd2l0aCBhbiBhdHRyaWJ1dGUgYGNvbnRlbnRgIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHdpbmRvdw0KDQppZiAodHlwZW9mIG1vZHVsZSAhPT0gInVuZGVmaW5lZCIgJiYgbW9kdWxlLmV4cG9ydHMpIHsNCiAgICBtb2R1bGUuZXhwb3J0cy5zYXZlQXMgPSBzYXZlQXM7DQp9IGVsc2UgaWYgKCh0eXBlb2YgZGVmaW5lICE9PSAidW5kZWZpbmVkIiAmJiBkZWZpbmUgIT09IG51bGwpICYmIChkZWZpbmUuYW1kICE9IG51bGwpKSB7DQogICAgZGVmaW5lKFtdLCBmdW5jdGlvbiAoKSB7DQogICAgICAgIHJldHVybiBzYXZlQXM7DQogICAgfSk7DQp9DQoNCiAgICAgICAgdmFyIHZlcnNpb24gPSAnMC43LjUnOw0KICAgICAgICB2YXIgdXJsdmFycyA9IHt9Ow0KICAgICAgICB2YXIgYW10c3RhY2s7DQogICAgICAgIHZhciB3c3N0YWNrID0gbnVsbDsNCiAgICAgICAgdmFyIEFsbFdzbWFuID0gIkFNVF84MDIxeENyZWRlbnRpYWxDb250ZXh0LEFNVF84MDIxWFByb2ZpbGUsQU1UX0FjdGl2ZUZpbHRlclN0YXRpc3RpY3MsQU1UX0FnZW50UHJlc2VuY2VDYXBhYmlsaXRpZXMsQU1UX0FnZW50UHJlc2VuY2VJbnRlcmZhY2VQb2xpY3ksQU1UX0FnZW50UHJlc2VuY2VTZXJ2aWNlLEFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2csQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ0FjdGlvbixBTVRfQWxhcm1DbG9ja1NlcnZpY2UsSVBTX0FsYXJtQ2xvY2tPY2N1cnJlbmNlLEFNVF9Bc3NldFRhYmxlLEFNVF9Bc3NldFRhYmxlU2VydmljZSxBTVRfQXVkaXRMb2csQU1UX0F1ZGl0UG9saWN5UnVsZSxBTVRfQXV0aG9yaXphdGlvblNlcnZpY2UsQU1UX0Jvb3RDYXBhYmlsaXRpZXMsQU1UX0Jvb3RTZXR0aW5nRGF0YSxBTVRfQ29tcGxleEZpbHRlckVudHJ5QmFzZSxBTVRfQ1JMLEFNVF9DcnlwdG9ncmFwaGljQ2FwYWJpbGl0aWVzLEFNVF9FQUNDcmVkZW50aWFsQ29udGV4dCxBTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZSxBTVRfRW52aXJvbm1lbnREZXRlY3Rpb25JbnRlcmZhY2VQb2xpY3ksQU1UX0Vudmlyb25tZW50RGV0ZWN0aW9uU2V0dGluZ0RhdGEsQU1UX0V0aGVybmV0UG9ydFNldHRpbmdzLEFNVF9FdmVudExvZ0VudHJ5LEFNVF9FdmVudE1hbmFnZXJTZXJ2aWNlLEFNVF9FdmVudFN1YnNjcmliZXIsQU1UX0ZpbHRlckVudHJ5QmFzZSxBTVRfRmlsdGVySW5TeXN0ZW1EZWZlbnNlUG9saWN5LEFNVF9HZW5lcmFsU2V0dGluZ3MsQU1UX0dlbmVyYWxTeXN0ZW1EZWZlbnNlQ2FwYWJpbGl0aWVzLEFNVF9IZHI4MDIxRmlsdGVyLEFNVF9IZXVyaXN0aWNQYWNrZXRGaWx0ZXJJbnRlcmZhY2VQb2xpY3ksQU1UX0hldXJpc3RpY1BhY2tldEZpbHRlclNldHRpbmdzLEFNVF9IZXVyaXN0aWNQYWNrZXRGaWx0ZXJTdGF0aXN0aWNzLEFNVF9JbnRlcmZhY2VQb2xpY3ksQU1UX0lQSGVhZGVyc0ZpbHRlcixBTVRfS2VyYmVyb3NTZXR0aW5nRGF0YSxBTVRfTWFuYWdlbWVudFByZXNlbmNlUmVtb3RlU0FQLEFNVF9NZXNzYWdlTG9nLEFNVF9NUFNVc2VybmFtZVBhc3N3b3JkLEFNVF9OZXR3b3JrRmlsdGVyLEFNVF9OZXR3b3JrUG9ydERlZmF1bHRTeXN0ZW1EZWZlbnNlUG9saWN5LEFNVF9OZXR3b3JrUG9ydFN5c3RlbURlZmVuc2VDYXBhYmlsaXRpZXMsQU1UX05ldHdvcmtQb3J0U3lzdGVtRGVmZW5zZVBvbGljeSxBTVRfUENJRGV2aWNlLEFNVF9QRVRDYXBhYmlsaXRpZXMsQU1UX1BFVEZpbHRlckZvclRhcmdldCxBTVRfUEVURmlsdGVyU2V0dGluZyxBTVRfUHJvdmlzaW9uaW5nQ2VydGlmaWNhdGVIYXNoLEFNVF9QdWJsaWNLZXlDZXJ0aWZpY2F0ZSxBTVRfUHVibGljS2V5TWFuYWdlbWVudENhcGFiaWxpdGllcyxBTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2UsQU1UX1B1YmxpY1ByaXZhdGVLZXlQYWlyLEFNVF9SZWRpcmVjdGlvblNlcnZpY2UsQU1UX1JlbW90ZUFjY2Vzc0NhcGFiaWxpdGllcyxBTVRfUmVtb3RlQWNjZXNzQ3JlZGVudGlhbENvbnRleHQsQU1UX1JlbW90ZUFjY2Vzc1BvbGljeUFwcGxpZXNUb01QUyxBTVRfUmVtb3RlQWNjZXNzUG9saWN5UnVsZSxBTVRfUmVtb3RlQWNjZXNzU2VydmljZSxBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSxBTVRfU05NUEV2ZW50U3Vic2NyaWJlcixBTVRfU3RhdGVUcmFuc2l0aW9uQ29uZGl0aW9uLEFNVF9TeXN0ZW1EZWZlbnNlUG9saWN5LEFNVF9TeXN0ZW1EZWZlbnNlUG9saWN5SW5TZXJ2aWNlLEFNVF9TeXN0ZW1EZWZlbnNlU2VydmljZSxBTVRfU3lzdGVtUG93ZXJTY2hlbWUsQU1UX1RoaXJkUGFydHlEYXRhU3RvcmFnZUFkbWluaXN0cmF0aW9uU2VydmljZSxBTVRfVGhpcmRQYXJ0eURhdGFTdG9yYWdlU2VydmljZSxBTVRfVGltZVN5bmNocm9uaXphdGlvblNlcnZpY2UsQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0LEFNVF9UTFNQcm90b2NvbEVuZHBvaW50LEFNVF9UTFNQcm90b2NvbEVuZHBvaW50Q29sbGVjdGlvbixBTVRfVExTU2V0dGluZ0RhdGEsQU1UX1RyYXBUYXJnZXRGb3JTZXJ2aWNlLEFNVF9Vc2VySW5pdGlhdGVkQ29ubmVjdGlvblNlcnZpY2UsQU1UX1dlYlVJU2VydmljZSxBTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZSxDSU1fQWJzdHJhY3RJbmRpY2F0aW9uU3Vic2NyaXB0aW9uLENJTV9BY2NvdW50LENJTV9BY2NvdW50TWFuYWdlbWVudENhcGFiaWxpdGllcyxDSU1fQWNjb3VudE1hbmFnZW1lbnRTZXJ2aWNlLENJTV9BY2NvdW50T25TeXN0ZW0sQ0lNX0FkbWluRG9tYWluLENJTV9BbGVydEluZGljYXRpb24sQ0lNX0Fzc2lnbmVkSWRlbnRpdHksQ0lNX0Fzc29jaWF0ZWRQb3dlck1hbmFnZW1lbnRTZXJ2aWNlLENJTV9BdXRoZW50aWNhdGlvblNlcnZpY2UsQ0lNX0F1dGhvcml6YXRpb25TZXJ2aWNlLENJTV9CSU9TRWxlbWVudCxDSU1fQklPU0ZlYXR1cmUsQ0lNX0JJT1NGZWF0dXJlQklPU0VsZW1lbnRzLENJTV9Cb290Q29uZmlnU2V0dGluZyxDSU1fQm9vdFNlcnZpY2UsQ0lNX0Jvb3RTZXR0aW5nRGF0YSxDSU1fQm9vdFNvdXJjZVNldHRpbmcsQ0lNX0NhcGFiaWxpdGllcyxDSU1fQ2FyZCxDSU1fQ2hhc3NpcyxDSU1fQ2hpcCxDSU1fQ29sbGVjdGlvbixDSU1fQ29tcG9uZW50LENJTV9Db21wdXRlclN5c3RlbSxDSU1fQ29tcHV0ZXJTeXN0ZW1QYWNrYWdlLENJTV9Db25jcmV0ZUNvbXBvbmVudCxDSU1fQ29uY3JldGVEZXBlbmRlbmN5LENJTV9Db250cm9sbGVyLENJTV9Db29saW5nRGV2aWNlLENJTV9DcmVkZW50aWFsLENJTV9DcmVkZW50aWFsQ29udGV4dCxDSU1fQ3JlZGVudGlhbE1hbmFnZW1lbnRTZXJ2aWNlLENJTV9EZXBlbmRlbmN5LENJTV9EZXZpY2VTQVBJbXBsZW1lbnRhdGlvbixDSU1fRWxlbWVudENhcGFiaWxpdGllcyxDSU1fRWxlbWVudENvbmZvcm1zVG9Qcm9maWxlLENJTV9FbGVtZW50TG9jYXRpb24sQ0lNX0VsZW1lbnRTZXR0aW5nRGF0YSxDSU1fRWxlbWVudFNvZnR3YXJlSWRlbnRpdHksQ0lNX0VsZW1lbnRTdGF0aXN0aWNhbERhdGEsQ0lNX0VuYWJsZWRMb2dpY2FsRWxlbWVudCxDSU1fRW5hYmxlZExvZ2ljYWxFbGVtZW50Q2FwYWJpbGl0aWVzLENJTV9FdGhlcm5ldFBvcnQsQ0lNX0ZhbixDSU1fRmlsdGVyQ29sbGVjdGlvbixDSU1fRmlsdGVyQ29sbGVjdGlvblN1YnNjcmlwdGlvbixDSU1fSG9zdGVkQWNjZXNzUG9pbnQsQ0lNX0hvc3RlZERlcGVuZGVuY3ksQ0lNX0hvc3RlZFNlcnZpY2UsQ0lNX0lkZW50aXR5LENJTV9JRUVFODAyMXhDYXBhYmlsaXRpZXMsQ0lNX0lFRUU4MDIxeFNldHRpbmdzLENJTV9JbmRpY2F0aW9uLENJTV9JbmRpY2F0aW9uU2VydmljZSxDSU1fSW5zdGFsbGVkU29mdHdhcmVJZGVudGl0eSxDSU1fS1ZNUmVkaXJlY3Rpb25TQVAsQ0lNX0xBTkVuZHBvaW50LENJTV9MaXN0ZW5lckRlc3RpbmF0aW9uLENJTV9MaXN0ZW5lckRlc3RpbmF0aW9uV1NNYW5hZ2VtZW50LENJTV9Mb2NhdGlvbixDSU1fTG9nLENJTV9Mb2dFbnRyeSxDSU1fTG9naWNhbERldmljZSxDSU1fTG9naWNhbEVsZW1lbnQsQ0lNX0xvZ2ljYWxQb3J0LENJTV9Mb2dpY2FsUG9ydENhcGFiaWxpdGllcyxDSU1fTG9nTWFuYWdlc1JlY29yZCxDSU1fTWFuYWdlZENyZWRlbnRpYWwsQ0lNX01hbmFnZWRFbGVtZW50LENJTV9NYW5hZ2VkU3lzdGVtRWxlbWVudCxDSU1fTWVkaWFBY2Nlc3NEZXZpY2UsQ0lNX01lbWJlck9mQ29sbGVjdGlvbixDSU1fTWVtb3J5LENJTV9NZXNzYWdlTG9nLENJTV9OZXR3b3JrUG9ydCxDSU1fTmV0d29ya1BvcnRDYXBhYmlsaXRpZXMsQ0lNX05ldHdvcmtQb3J0Q29uZmlndXJhdGlvblNlcnZpY2UsQ0lNX09yZGVyZWRDb21wb25lbnQsQ0lNX093bmluZ0NvbGxlY3Rpb25FbGVtZW50LENJTV9Pd25pbmdKb2JFbGVtZW50LENJTV9QQ0lDb250cm9sbGVyLENJTV9QaHlzaWNhbENvbXBvbmVudCxDSU1fUGh5c2ljYWxFbGVtZW50LENJTV9QaHlzaWNhbEVsZW1lbnRMb2NhdGlvbixDSU1fUGh5c2ljYWxGcmFtZSxDSU1fUGh5c2ljYWxNZW1vcnksQ0lNX1BoeXNpY2FsUGFja2FnZSxDSU1fUG9saWN5LENJTV9Qb2xpY3lBY3Rpb24sQ0lNX1BvbGljeUNvbmRpdGlvbixDSU1fUG9saWN5SW5TeXN0ZW0sQ0lNX1BvbGljeVJ1bGUsQ0lNX1BvbGljeVJ1bGVJblN5c3RlbSxDSU1fUG9saWN5U2V0LENJTV9Qb2xpY3lTZXRBcHBsaWVzVG9FbGVtZW50LENJTV9Qb2xpY3lTZXRJblN5c3RlbSxDSU1fUG93ZXJNYW5hZ2VtZW50Q2FwYWJpbGl0aWVzLENJTV9Qb3dlck1hbmFnZW1lbnRTZXJ2aWNlLENJTV9Qb3dlclN1cHBseSxDSU1fUHJpdmlsZWdlLENJTV9Qcml2aWxlZ2VNYW5hZ2VtZW50Q2FwYWJpbGl0aWVzLENJTV9Qcml2aWxlZ2VNYW5hZ2VtZW50U2VydmljZSxDSU1fUHJvY2Vzc0luZGljYXRpb24sQ0lNX1Byb2Nlc3NvcixDSU1fUHJvdG9jb2xFbmRwb2ludCxDSU1fUHJvdmlkZXNTZXJ2aWNlVG9FbGVtZW50LENJTV9SZWFsaXplcyxDSU1fUmVjb3JkRm9yTG9nLENJTV9SZWNvcmRMb2csQ0lNX1JlZGlyZWN0aW9uU2VydmljZSxDSU1fUmVmZXJlbmNlZFByb2ZpbGUsQ0lNX1JlZ2lzdGVyZWRQcm9maWxlLENJTV9SZW1vdGVBY2Nlc3NBdmFpbGFibGVUb0VsZW1lbnQsQ0lNX1JlbW90ZUlkZW50aXR5LENJTV9SZW1vdGVQb3J0LENJTV9SZW1vdGVTZXJ2aWNlQWNjZXNzUG9pbnQsQ0lNX1JvbGUsQ0lNX1JvbGVCYXNlZEF1dGhvcml6YXRpb25TZXJ2aWNlLENJTV9Sb2xlQmFzZWRNYW5hZ2VtZW50Q2FwYWJpbGl0aWVzLENJTV9Sb2xlTGltaXRlZFRvVGFyZ2V0LENJTV9TQVBBdmFpbGFibGVGb3JFbGVtZW50LENJTV9TZWN1cml0eVNlcnZpY2UsQ0lNX1NlbnNvcixDSU1fU2VydmljZSxDSU1fU2VydmljZUFjY2Vzc0J5U0FQLENJTV9TZXJ2aWNlQWNjZXNzUG9pbnQsQ0lNX1NlcnZpY2VBZmZlY3RzRWxlbWVudCxDSU1fU2VydmljZUF2YWlsYWJsZVRvRWxlbWVudCxDSU1fU2VydmljZVNBUERlcGVuZGVuY3ksQ0lNX1NlcnZpY2VTZXJ2aWNlRGVwZW5kZW5jeSxDSU1fU2V0dGluZ0RhdGEsQ0lNX1NoYXJlZENyZWRlbnRpYWwsQ0lNX1NvZnR3YXJlRWxlbWVudCxDSU1fU29mdHdhcmVGZWF0dXJlLENJTV9Tb2Z0d2FyZUZlYXR1cmVTb2Z0d2FyZUVsZW1lbnRzLENJTV9Tb2Z0d2FyZUlkZW50aXR5LENJTV9TdGF0aXN0aWNhbERhdGEsQ0lNX1N0b3JhZ2VFeHRlbnQsQ0lNX1N5c3RlbSxDSU1fU3lzdGVtQklPUyxDSU1fU3lzdGVtQ29tcG9uZW50LENJTV9TeXN0ZW1EZXZpY2UsQ0lNX1N5c3RlbVBhY2thZ2luZyxDSU1fVXNlT2ZMb2csQ0lNX1dhdGNoZG9nLENJTV9XaUZpRW5kcG9pbnQsQ0lNX1dpRmlFbmRwb2ludENhcGFiaWxpdGllcyxDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MsQ0lNX1dpRmlQb3J0LENJTV9XaUZpUG9ydENhcGFiaWxpdGllcyxJUFNfQWRtaW5Qcm92aXNpb25pbmdSZWNvcmQsSVBTX0NsaWVudFByb3Zpc2lvbmluZ1JlY29yZCxJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlLElQU19Ib3N0SVBTZXR0aW5ncyxJUFNfSFRUUFByb3h5U2VydmljZSxJUFNfSFRUUFByb3h5QWNjZXNzUG9pbnQsSVBTX0lkZXJTZXNzaW9uVXNpbmdQb3J0LElQU19JUHY2UG9ydFNldHRpbmdzLElQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhLElQU19Ldm1TZXNzaW9uVXNpbmdQb3J0LElQU19NYW51YWxQcm92aXNpb25pbmdSZWNvcmQsSVBTX09wdEluU2VydmljZSxJUFNfUHJvdmlzaW9uaW5nQXVkaXRSZWNvcmQsSVBTX1Byb3Zpc2lvbmluZ1JlY29yZExvZyxJUFNfUmFzU2Vzc2lvblVzaW5nUG9ydCxJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UsSVBTX1NjcmVlblNldHRpbmdEYXRhLElQU19TZWNJT1NlcnZpY2UsSVBTX1Nlc3Npb25Vc2luZ1BvcnQsSVBTX1NvbFNlc3Npb25Vc2luZ1BvcnQsSVBTX1RMU1Byb3Zpc2lvbmluZ1JlY29yZCxJUFNfV2F0Y2hEb2dBY3Rpb24iLnNwbGl0KCcsJyk7DQogICAgICAgIHZhciBkaXNjb25uZWN0dXJsID0gbnVsbDsNCiAgICAgICAgdmFyIGN1cnJlbnRWaWV3ID0gMDsNCiAgICAgICAgdmFyIExvYWRpbmdIdG1sID0gIjxkaXYgc3R5bGU9dGV4dC1hbGlnbjpjZW50ZXI7cGFkZGluZy10b3A6MjBweD5Mb2FkaW5nLi4uPGRpdj4iOw0KICAgICAgICB2YXIgYW10dmVyc2lvbiA9IDA7DQogICAgICAgIHZhciBhbXR2ZXJzaW9ubWluID0gMDsNCiAgICAgICAgdmFyIGFtdEZpcnN0UHVsbCA9IDA7IC8vIEJpdG1hc2ssIFNldCB0aGlzIHdoZW4gdGhlIGZpcnN0IHB1bGwgcmVxdWVzdCBpcyBtYWRlIG9uIGEgZGV2aWNlOiAxID0gSGFyZHdhcmVJbmZvLCAyID0gV2lyZWxlc3NJbmZvLCA0ID0gU3lzdGVtRGVmZW5zZSwgOCA9IFN0b3JhZ2UsIDE2ID0gRXZlbnRMb2csIDMyID0gQXVkaXRMb2cNCg0KICAgICAgICB2YXIgYW10d2lyZWxlc3NpZiA9IC0xOyAvLyBTZXQgdG8gdGhlIGludGVyZmFjZSBpbmRleCBmb3IgdGhlIHdpcmVsZXNzIGludGVyZmFjZSwgLTEgaWYgbm8gd2lyZWxlc3MuDQogICAgICAgIHZhciB3ZWJjb21waWxlcmZlYXR1cmVzID0gWydBZ2VudFByZXNlbmNlJywnQWxhcm1zJywnQXVkaXRMb2cnLCdDZXJ0aWZpY2F0ZXMnLCdDb21wdXRlclNlbGVjdG9yVG9vbGJhcicsJ0Rlc2t0b3AtU2V0dGluZ3MnLCdFdmVudExvZycsJ0ZpbGVTYXZlcicsJ0hhcmR3YXJlSW5mbycsJ0xvb2stQ29tbWFuZGVyJywnTW9kZS1MTVMnLCdOZXR3b3JrU2V0dGluZ3MnLCdSZW1vdGVBY2Nlc3MnLCdTY3JpcHRpbmcnLCdTY3JpcHRpbmctRWRpdG9yJywnU3RvcmFnZScsJ1N5c3RlbURlZmVuc2UnLCdVU0JTZXR1cCcsJ1dpcmVsZXNzJ107DQogICAgICAgIHZhciBTdGF0dXNTdHJzID0gWydEaXNjb25uZWN0ZWQnLCAnQ29ubmVjdGluZy4uLicsICdTZXR1cC4uLicsICdDb25uZWN0ZWQnXTsNCg0KICAgICAgICB2YXIgc2NyaXB0c3RhdGU7DQoNCiAgICAgICAgdmFyIHNldHVwYmluOw0KICAgICAgICB2YXIgc2VsZWN0ZWRSZWNvcmQgPSAwOw0KICAgICAgICB2YXIgc2VsZWN0ZWRWYXJpYWJsZSA9IDA7DQoNCiAgICAgICAgdmFyIGFtdFBvd2VyUG9sbFRpbWVyID0gbnVsbDsNCg0KICAgICAgICB2YXIgbG1zID0gbnVsbDsNCiAgICAgICAgdmFyIHQsIHQyLCByc2VwYXNzID0gbnVsbDsgLy8gR2xvYmFsIHRlbXBvcmFyeSB2YXJpYWJsZQ0KDQogICAgICAgIGZ1bmN0aW9uIHN0YXJ0dXAoKSB7DQogICAgICAgICAgICAvLyBUaGlzIGlzIGEgYml0IGZyZWVreSwgYnV0IGFsbCBIVE1MIGlucHV0IGVsZW1lbnRzIGFyZSBqdXN0IGdvaW5nIHRvIGJlIGFjY2Vzc2libGUgZGlyZWN0bHkuDQogICAgICAgICAgICB2YXIgYWxsZWxlbWVudHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaW5wdXQnKTsNCiAgICAgICAgICAgIGZvciAodCA9IDA7IHQgPCBhbGxlbGVtZW50cy5sZW5ndGg7IHQrKykgeyBpZiAoYWxsZWxlbWVudHNbdF0uaWQpIHsgd2luZG93W2FsbGVsZW1lbnRzW3RdLmlkXSA9IGFsbGVsZW1lbnRzW3RdOyB9IH0NCg0KDQogICAgICAgICAgICB1cmx2YXJzID0gZ2V0VXJsVmFycygpOw0KDQoNCg0KICAgICAgICAgICAgLy8gU2V0dXAgTE1TDQogICAgICAgICAgICBsbXMgPSBDcmVhdGVMbXNDb250cm9sKCk7DQogICAgICAgICAgICBsbXMub25TdGF0ZUNoYW5nZWQgPSBsbXNDaGFuZ2VkU3RhdGU7DQogICAgICAgICAgICBsbXMub25EYXRhID0gbG1zT25EYXRhOw0KICAgICAgICAgICAgbG1zLlN0YXJ0KCk7DQogICAgICAgICAgICBRSCgnaWRfbG1zRGF0YScsIExvYWRpbmdIdG1sKTsNCiAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhJywgJycpOw0KICAgICAgICAgICAgUUgoJ2lkX2NvbXB1dGVybmFtZScsICdDb25maWd1cmF0aW9uIENvbnNvbGUgdicgKyB2ZXJzaW9uKTsNCiAgICAgICAgICAgIGdvKDEwMSk7DQogICAgICAgICAgICBsbXNSZWZyZXNoKCk7DQoNCg0KDQoNCiAgICAgICAgICAgIC8vIE1hc3RlciBkcmFnICYgZHJvcA0KICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ292ZXInLCBoYWx0RXZlbnQsIGZhbHNlKTsNCiAgICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdsZWF2ZScsIGhhbHRFdmVudCwgZmFsc2UpOw0KICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignZHJvcCcsIGRvY3VtZW50RmlsZVNlbGVjdEhhbmRsZXIsIGZhbHNlKTsNCg0KDQogICAgICAgICAgICAvLyBTZXR1cCBUZXJtaW5hbCBkcmFnICYgZHJvcA0KICAgICAgICAgICAgUSgncDE2JykuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ292ZXInLCBoYWx0RXZlbnQsIGZhbHNlKTsNCiAgICAgICAgICAgIFEoJ3AxNicpLmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdsZWF2ZScsIGhhbHRFdmVudCwgZmFsc2UpOw0KICAgICAgICAgICAgUSgncDE2JykuYWRkRXZlbnRMaXN0ZW5lcignZHJvcCcsIGNlcnRfRmlsZVNlbGVjdEhhbmRsZXIsIGZhbHNlKTsNCg0KDQoNCg0KDQoNCg0KDQogICAgICAgICAgICB1c2JfZGlzcGxheVNldHVwQmluKCk7DQoNCiAgICAgICAgICAgIC8vIEFkZCBhbGwgcG9zc2libGUgdmFyaWFibGUgdHlwZXMgdG8gZGlhbG9nIDE2DQogICAgICAgICAgICB2YXIgb3B0aW9ucyA9ICcnOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBBbXRTZXR1cEJpblZhcklkcykgeyBmb3IgKHZhciBqIGluIEFtdFNldHVwQmluVmFySWRzW2ldKSB7IG9wdGlvbnMgKz0gJzxvcHRpb24gdmFsdWU9IicgKyBpICsgIi0iICsgaiArICciPicgKyBBbXRTZXR1cEJpblZhcklkc1tpXVtqXVsxXSB9IH0NCiAgICAgICAgICAgIFFIKCdkMTZ0eXBlJywgb3B0aW9ucyk7DQoNCiAgICAgICAgICAgIGRvY3VtZW50Lm9ua2V5dXAgPSBoYW5kbGVLZXlVcDsNCiAgICAgICAgICAgIGRvY3VtZW50Lm9ua2V5ZG93biA9IGhhbmRsZUtleURvd247DQogICAgICAgICAgICBkb2N1bWVudC5vbmtleXByZXNzID0gaGFuZGxlS2V5UHJlc3M7DQogICAgICAgICAgICB3aW5kb3cub25yZXNpemUgPSBjZW50ZXI7DQogICAgICAgICAgICBjZW50ZXIoKTsNCg0KDQoNCg0KICAgICAgICAgICAgc2NyaXB0TG9hZFN0YXJ0aW5nQmxvY2tzKCk7DQoNCg0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZG9jdW1lbnRGaWxlU2VsZWN0SGFuZGxlcihlKSB7DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQogICAgICAgICAgICBpZiAoZS5kYXRhVHJhbnNmZXIgPT0gbnVsbCB8fCBlLmRhdGFUcmFuc2Zlci5maWxlcy5sZW5ndGggIT0gMSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIGYgPSBudWxsLCBmaWxlbmFtZSA9IGUuZGF0YVRyYW5zZmVyLmZpbGVzWzBdLm5hbWUudG9Mb3dlckNhc2UoKTsNCg0KICAgICAgICAgICAgaWYgKGN1cnJlbnRWaWV3ID09IDIxKSB7IFVwbG9hZFRvU3RvcmFnZShlLmRhdGFUcmFuc2Zlci5maWxlc1swXSwgZmlsZW5hbWUpOyByZXR1cm47IH0NCg0KICAgICAgICAgICAgaWYgKGN1cnJlbnRWaWV3ID09IDEwMiAmJiBmaWxlbmFtZS5lbmRzV2l0aCgnLmJpbicpKSB7IGYgPSB1c2Jfb25TZXR1cEJpblJlYWQ7IH0NCg0KICAgICAgICAgICAgaWYgKHdzc3RhY2sgIT0gbnVsbCAmJiAoZmlsZW5hbWUuZW5kc1dpdGgoJy5tZXNjcmlwdCcpIHx8IGZpbGVuYW1lLmVuZHNXaXRoKCcubWVibG9ja3MnKSkpIHsgZiA9IHNjcmlwdF9vblNjcmlwdFJlYWQ7IH0NCiAgICAgICAgICAgIGlmIChmICE9IG51bGwpIHsgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7IHJlYWRlci5vbmxvYWQgPSBmOyByZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKGUuZGF0YVRyYW5zZmVyLmZpbGVzWzBdKTsgfQ0KICAgICAgICB9DQoNCg0KDQoNCiAgICAgICAgLy8gQ2FsbGVkIHdoZW4gdGhlIExNUyBjb250cm9sIGNoYW5uZWwgY2hhbmdlcyBzdGF0ZQ0KICAgICAgICBmdW5jdGlvbiBsbXNDaGFuZ2VkU3RhdGUoc2VuZGVyLCBzdGF0ZSkNCiAgICAgICAgew0KICAgICAgICAgICAgLy9jb25zb2xlLmxvZygiTE1TIENvbnRyb2wgQ2hhbm5lbCBTdGF0ZTogIiArIHN0YXRlKTsNCiAgICAgICAgICAgIGlmIChzdGF0ZSA9PSAwKSB7IA0KICAgICAgICAgICAgICAgIHNldERpYWxvZ01vZGUoKTsNCiAgICAgICAgICAgICAgICBRVignaWRfbG1zVG9vbEJhckNvbnRlbnQnLCBmYWxzZSk7DQogICAgICAgICAgICAgICAgUUgoJ2lkX2xtc0RhdGEnLCAnPGRpdiBzdHlsZT10ZXh0LWFsaWduOmNlbnRlcjtwYWRkaW5nLXRvcDoyMHB4Pk1pY3JvTE1TIGRpc2Nvbm5lY3RlZC48ZGl2PicpOw0KICAgICAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhMicsICcnKTsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT0gMikgeyBRVignaWRfbG1zVG9vbEJhckNvbnRlbnQnLCB0cnVlKTsgbG1zUmVmcmVzaCgpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBsbXNMb2dpbigpIHsgd2luZG93LmxvY2F0aW9uLmhyZWYgPSAnL2F1dGhpbmRleC5odG1sJzsgfQ0KDQogICAgICAgIHZhciBsbXNQcm92aXNpb25pbmdTdGF0ZXMgPSBbJ1ByZS1Qcm92aXNpb25pbmcnLCAnSW4tUHJvdmlzaW9uaW5nJywgJ1Bvc3QtUHJvdmlzaW9uaW5nJ107DQogICAgICAgIHZhciBsbXNQcm92aXNpb25pbmdNb2RlcyA9IFsnTm9uZScsICdFbnRlcnByaXNlIE1vZGUnLCAnU21hbGwgQnVpc25lc3MgTW9kZScsICdSZW1vdGUgQXNzaXN0YW5jZSBNb2RlJ107DQogICAgICAgIHZhciBsbXNNZUluZm8gPSBudWxsOw0KICAgICAgICB2YXIgbG1zVGVtcCA9IG51bGw7DQogICAgICAgIHZhciBsbXNOb3RpZmljYXRpb25zID0gbnVsbDsNCg0KICAgICAgICAvLyBDYWxsZWQgd2hlbiBkYXRhIGlzIHJlY2VpdmVkIG9uIHRoZSBMTVMgY29udHJvbCBjaGFubmVsDQogICAgICAgIGZ1bmN0aW9uIGxtc09uRGF0YShzZW5kZXIsIGRhdGEpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBjbWRpZCA9IFJlYWRTaG9ydFgoZGF0YSwgMCk7DQogICAgICAgICAgICAvL2NvbnNvbGUubG9nKCJMTVMgQ29udHJvbCBDaGFubmVsIERhdGE6ICIgKyBkYXRhICsgIiwgY21kaWQ6IiArIGNtZGlkKTsNCg0KICAgICAgICAgICAgc3dpdGNoICgrY21kaWQpIHsNCiAgICAgICAgICAgICAgICBjYXNlIDE6IHsgLy8gTUUgSW5mb3JtYXRpb24NCiAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhkYXRhLnN1YnN0cmluZygyKSk7DQogICAgICAgICAgICAgICAgICAgIHZhciBtZWluZm8gPSBKU09OLnBhcnNlKGRhdGEuc3Vic3RyaW5nKDIpKTsNCiAgICAgICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0xvZ2luQnV0dG9uJywgbWVpbmZvWydMb2dpbk1vZGUnXSA9PSAxKTsNCg0KICAgICAgICAgICAgICAgICAgICAvLyBJZiBJbnRlbCBBTVQgaXMgaW4tYmV0d2VlbiBzdGF0ZXMsIHJlbG9hZCBkYXRhIGluIGEgZmV3IHNlY29uZHMuDQogICAgICAgICAgICAgICAgICAgIGlmICgobWVpbmZvWydUcnVzdGVkSGFzaGVzJ10gIT0gbnVsbCkgJiYgKG1laW5mb1snUHJvdmlzaW9uaW5nTW9kZSddID09IC04NTg5OTM0NjApKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBRVignaWRfbG1zQ29uZmlndXJlQnV0dG9uJywgZmFsc2UpOw0KICAgICAgICAgICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0FjdGl2YXRlQnV0dG9uJywgZmFsc2UpOw0KICAgICAgICAgICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0RlYWN0aXZhdGVCdXR0b24nLCBmYWxzZSk7DQogICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGxtc1JlZnJlc2gsIDEwMDApOw0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAgICAgbG1zTWVJbmZvID0gbWVpbmZvOw0KICAgICAgICAgICAgICAgICAgICBpZiAobWVpbmZvWydQcm92aXNpb25pbmdTdGF0ZSddID09IG51bGwpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhJywgJzxkaXYgc3R5bGU9dGV4dC1hbGlnbjpjZW50ZXI7cGFkZGluZy10b3A6MjBweD5JbnRlbCZyZWc7IEFNVCBub3QgZm91bmQ8ZGl2PicpOw0KICAgICAgICAgICAgICAgICAgICAgICAgUUgoJ2lkX2xtc0RhdGEyJywgJycpOw0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgbWVpbmZvWydGbGFncyddID0gK21laW5mb1snRmxhZ3MnXTsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHggPSAnPGgyPkN1cnJlbnQgU3RhdHVzPC9oMj4nOw0KICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZVN0YXJ0KCk7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAobWVpbmZvWydQcm92aXNpb25pbmdTdGF0ZSddICE9IDIpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkFjdGl2YXRpb24gc3RhdGUiLCBsbXNQcm92aXNpb25pbmdTdGF0ZXNbbWVpbmZvWydQcm92aXNpb25pbmdTdGF0ZSddXSk7DQogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtZWluZm9bJ0ZsYWdzJ10gJiAyKSB7IHggKz0gVGFibGVFbnRyeSgnQWN0aXZhdGlvbiBzdGF0ZScsICdBY3RpdmF0ZWQgaW4gQ2xpZW50IENvbnRyb2wgTW9kZScpOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobWVpbmZvWydGbGFncyddICYgNCkgeyB4ICs9IFRhYmxlRW50cnkoJ0FjdGl2YXRpb24gc3RhdGUnLCAnQWN0aXZhdGVkIGluIEFkbWluIENvbnRyb2wgTW9kZScpOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7IHggKz0gVGFibGVFbnRyeSgnQWN0aXZhdGlvbiBzdGF0ZScsICdBY3RpdmF0ZWQsICcgKyBsbXNQcm92aXNpb25pbmdNb2Rlc1ttZWluZm9bJ1Byb3Zpc2lvbmluZ01vZGUnXV0pOyB9DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoJ0ludGVsJnJlZzsgQU1UIHZlcnNpb24nLCBhZGRMaW5rKG1laW5mb1snVmVyc2lvbnMnXVsnQU1UJ10sICdsbXNTaG93VmVyc2lvbnNEbGcoKScpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtZWluZm9bJ01laVZlcnNpb24nXSAhPSBudWxsKSB7IHggKz0gVGFibGVFbnRyeSgnSW50ZWwmcmVnOyBNRUkgZHJpdmVyIHZlcnNpb24nLCBtZWluZm9bJ01laVZlcnNpb24nXSk7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbmQoKTsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1laW5mb1snUHJvdmlzaW9uaW5nU3RhdGUnXSAhPSAyKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSAnPGgyPkFjdGl2YXRpb24gSW5mb3JtYXRpb248L2gyPic7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZVN0YXJ0KCk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1laW5mb1snRG5zU3VmZml4J10pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCdUcnVzdGVkIEROUyBzdWZmaXgnLCBtZWluZm9bJ0Ruc1N1ZmZpeCddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoJ1RydXN0ZWQgRE5TIHN1ZmZpeCcsICc8aT5Ob3QgU2V0PC9pPicpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWVpbmZvWydUcnVzdGVkSGFzaGVzJ10gIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWVpbmZvWydUcnVzdGVkSGFzaGVzJ10ubGVuZ3RoID09IDEpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgnVHJ1c3RlZCBoYXNoZXMnLCBhZGRMaW5rKG1laW5mb1snVHJ1c3RlZEhhc2hlcyddLmxlbmd0aCArICcgaGFzaCcsICdsbXNTaG93VHJ1c3RlZEhhc2hlc0RsZygpJykpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCdUcnVzdGVkIGhhc2hlcycsIGFkZExpbmsobWVpbmZvWydUcnVzdGVkSGFzaGVzJ10ubGVuZ3RoICsgJyBoYXNoZXMnLCAnbG1zU2hvd1RydXN0ZWRIYXNoZXNEbGcoKScpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW5kKCk7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhJywgeCk7DQogICAgICAgICAgICAgICAgICAgICAgICBRVignaWRfbG1zRGF0YTInLCB0cnVlKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGxtc05vdGlmaWNhdGlvbnMgPSBtZWluZm9bJ05vdGlmaWNhdGlvbnMnXS5yZXZlcnNlKCk7DQogICAgICAgICAgICAgICAgICAgICAgICBsbXNSZWZyZXNoTm90aWZpY2F0aW9ucygpOw0KICAgICAgICAgICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0NvbmZpZ3VyZUJ1dHRvbicsIChtZWluZm9bJ1Byb3Zpc2lvbmluZ1N0YXRlJ10gPT0gMikpOyAvLyBPbmx5IGRpc3BsYXkgdGhlICJMb2dpbi4uLiIgYnV0dG9uIGlmIEludGVsIEFNVCBpcyBpbiBwb3N0LXByb3Zpc2lvbmluZyBzdGF0ZS4NCiAgICAgICAgICAgICAgICAgICAgICAgIFFWKCdpZF9sbXNBY3RpdmF0ZUJ1dHRvbicsIChtZWluZm9bJ1Byb3Zpc2lvbmluZ1N0YXRlJ10gPT0gMCkgJiYgKG1laW5mb1snTG9naW5Nb2RlJ10gPj0gMikpOyAvLyBPbmx5IGRpc3BsYXkgdGhlICJBY3RpdmF0ZS4uLiIgYnV0dG9uIGlmIEludGVsIEFNVCBpcyBpbiBwcmUtcHJvdmlzaW9uaW5nIHN0YXRlIGFuZCB3ZSBhcmUgYWRybWluaXN0cmF0b3IuDQogICAgICAgICAgICAgICAgICAgICAgICBRVignaWRfbG1zRGVhY3RpdmF0ZUJ1dHRvbicsIChtZWluZm9bJ1Byb3Zpc2lvbmluZ1N0YXRlJ10gPT0gMikgJiYgKG1laW5mb1snRmxhZ3MnXSAmIDIpICYmIChtZWluZm9bJ0xvZ2luTW9kZSddID49IDIpKTsgLy8gT25seSBkaXNwbGF5IHRoZSAiRGVhY3RpdmF0ZS4uLiIgYnV0dG9uIGlmIEludGVsIEFNVCBpcyBpbiBwb3J0LXByb3Zpc2lvbmluZyBzdGF0ZSAmIGluIGNsaWVudCBjb250cm9sIG1vZGUgJiB3ZSBhcmUgYWRybWluaXN0cmF0b3IuDQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGNhc2UgMjogeyAvLyBJbnRlbCBNRSBVbi1Qcm92aXNpb25pbmcNCiAgICAgICAgICAgICAgICAgICAgbG1zRGVhY3RpdmF0ZVgyKFJlYWRJbnRYKGRhdGEsIDIpKTsNCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGNhc2UgMzogeyAvLyBJbnRlbCBNRSBTeXN0ZW0gQWNjb3VudCBJbmZvcm1hdGlvbg0KICAgICAgICAgICAgICAgICAgICB2YXIgc3RhdHVzID0gUmVhZEludFgoZGF0YSwgMik7DQogICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnSW50ZWwmcmVnOyBBTVQgQWN0aXZhdGlvbicsICdGYWlsZWQgdG8gZ2V0IGFjY291bnQgaW5mb3JtYXRpb24sIHN0YXR1cyAnICsgc3RhdHVzKTsNCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtZXVzZXIgPSBkYXRhLnN1YnN0cmluZyg2LCBkYXRhLmluZGV4T2YoJ1wwJywgNikpOw0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1lcGFzcyA9IGRhdGEuc3Vic3RyaW5nKDM5LCBkYXRhLmluZGV4T2YoJ1wwJywgMzkpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIFFIKCdpZF9kaWFsb2dNZXNzYWdlJywgJ0ZldGNoaW5nIGFjdGl2YXRpb24gc3RhdHVzLi4uJyk7DQogICAgICAgICAgICAgICAgICAgICAgICB3c3N0YWNrID0gV3NtYW5TdGFja0NyZWF0ZVNlcnZpY2UoImxvY2FsaG9zdCIsIDE2OTkyLCBtZXVzZXIsIG1lcGFzcywgZmFsc2UpOw0KICAgICAgICAgICAgICAgICAgICAgICAgYW10c3RhY2sgPSBBbXRTdGFja0NyZWF0ZVNlcnZpY2Uod3NzdGFjayk7DQogICAgICAgICAgICAgICAgICAgICAgICBhbXRzdGFjay5vblByb2Nlc3NDaGFuZ2VkID0gb25Qcm9jZXNzQ2hhbmdlZDsNCiAgICAgICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLkJhdGNoRW51bShudWxsLCBbJypBTVRfR2VuZXJhbFNldHRpbmdzJywgJypJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlJ10sIGxtc0FjdGl2YXRpb25YMSk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGNhc2UgOTogeyAvLyBOZXcgbm90aWZpY2F0aW9uDQogICAgICAgICAgICAgICAgICAgIHZhciBub3RpZmljYXRpb24gPSBKU09OLnBhcnNlKGRhdGEuc3Vic3RyaW5nKDIpKTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGxtc05vdGlmaWNhdGlvbnMgPT0gbnVsbCkgeyBsbXNOb3RpZmljYXRpb25zID0gW107IH0NCiAgICAgICAgICAgICAgICAgICAgbG1zTm90aWZpY2F0aW9ucy51bnNoaWZ0KG5vdGlmaWNhdGlvbik7DQogICAgICAgICAgICAgICAgICAgIGxtc1JlZnJlc2hOb3RpZmljYXRpb25zKCk7DQogICAgICAgICAgICAgICAgICAgIGlmICgobm90aWZpY2F0aW9uLmNvZGUgPT0gJ2lBTVQwMDU1LTAnKSB8fCAobm90aWZpY2F0aW9uLmNvZGUgPT0gJ2lBTVQwMDU1LTEnKSB8fCAobm90aWZpY2F0aW9uLmNvZGUgPT0gJ2lBTVQwMDU1LTInKSkgeyBzZXREaWFsb2dNb2RlKCk7IGxtc1JlZnJlc2goKTsgfQ0KICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBsbXNSZWZyZXNoTm90aWZpY2F0aW9ucygpIHsNCiAgICAgICAgICAgIHZhciB4ID0gJzxoMj5Ob3RpZmljYXRpb25zPC9oMj4nICsgVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgaWYgKGxtc05vdGlmaWNhdGlvbnMgJiYgbG1zTm90aWZpY2F0aW9ucy5sZW5ndGggPiAwKSB7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBsbXNOb3RpZmljYXRpb25zKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBuID0gbG1zTm90aWZpY2F0aW9uc1tpXSwgdiA9IG4uc3RyOw0KICAgICAgICAgICAgICAgICAgICBpZiAobi5jb2RlICE9ICdpQU1UMDA1MC0zMicpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2LmluZGV4T2YoJ1VzZXIgTm90aWZpY2F0aW9uIEFsZXJ0IC0gJykgPT0gMCkgeyB2ID0gdi5zdWJzdHJpbmcoMjYpOyB9DQogICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkobmV3IERhdGUobi5kYXRlKS50b0xvY2FsZVN0cmluZygpLCB2KTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgeCArPSAiPHRyPjx0ZCBzdHlsZT1wYWRkaW5nOjhweD48aT5ObyBub3RpZmljYXRpb25zIGZvdW5kLjwvaT48dGQ+IjsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoKTsNCiAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhMicsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gbG1zQWN0aXZhdGlvblgxKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdJbnRlbCZyZWc7IEFNVCBBY3RpdmF0aW9uJywgJ0ZhaWxlZCB0byBmZXRjaCBhY3RpdmF0aW9uIHN0YXR1cywgc3RhdHVzICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZXNbJ0lQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2UnXS5yZXNwb25zZVsnQWxsb3dlZENvbnRyb2xNb2RlcyddLmxlbmd0aCAhPSAyKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnSW50ZWwmcmVnOyBBTVQgQWN0aXZhdGlvbicsICdDbGllbnQgY29udHJvbCBtb2RlIGFjdGl2YXRpb24gbm90IGFsbG93ZWQnKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgbG1zVGVtcCA9IHJlc3BvbnNlc1snQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlOw0KICAgICAgICAgICAgICAgIGFtdHN0YWNrLklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2VfU2V0dXAoMiwgcnN0cjJoZXgocnN0cl9tZDUoJ2FkbWluOicgKyByZXNwb25zZXNbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZVsnRGlnZXN0UmVhbG0nXSArICc6JyArIGQ0cGFzc3dvcmQudmFsdWUpKSwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbG1zQWN0aXZhdGlvblgyKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGxtc0FjdGl2YXRpb25YMihzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDAgfHwgcmVzcG9uc2UuQm9keVsnUmV0dXJuVmFsdWUnXSAhPSAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnSW50ZWwmcmVnOyBBTVQgQWN0aXZhdGlvbicsICdGYWlsZWQgYWN0aXZhdGlvbiwgc3RhdHVzICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBzZXREaWFsb2dNb2RlKCk7DQogICAgICAgICAgICAgICAgbG1zUmVmcmVzaCgpOw0KICAgICAgICAgICAgICAgIGxtc1RlbXBbJ0hvc3ROYW1lJ10gPSBsbXNNZUluZm9bJ09zSG9zdG5hbWUnXTsgLy8gU2V0IHRoZSBPUyBob3N0bmFtZQ0KICAgICAgICAgICAgICAgIC8vIFRPRE86IEFsc28gc2V0IHRoZSBsb2NhbCBGUUROIGlmIHdlIGNhbiBnZXQgaXQgZnJvbSBMTVMNCiAgICAgICAgICAgICAgICB3c3N0YWNrID0gV3NtYW5TdGFja0NyZWF0ZVNlcnZpY2UoJ2xvY2FsaG9zdCcsIDE2OTkyLCAnYWRtaW4nLCBkNHBhc3N3b3JkLnZhbHVlLCBmYWxzZSk7DQogICAgICAgICAgICAgICAgYW10c3RhY2sgPSBBbXRTdGFja0NyZWF0ZVNlcnZpY2Uod3NzdGFjayk7DQogICAgICAgICAgICAgICAgYW10c3RhY2sub25Qcm9jZXNzQ2hhbmdlZCA9IG9uUHJvY2Vzc0NoYW5nZWQ7DQogICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfR2VuZXJhbFNldHRpbmdzJywgbG1zVGVtcCwgZnVuY3Rpb24oKSB7IH0sIDAsIDEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gbG1zRGVhY3RpdmF0ZSgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgbG1zLlN0YXRlICE9IDIpIHJldHVybjsNCiAgICAgICAgICAgIFFIKCdpZF9kaWFsb2dNZXNzYWdlJywgJ0NvbmZpcm0gSW50ZWwmcmVnOyBBTVQgZGVhY3RpdmF0aW9uPycpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxLCAiSW50ZWwmcmVnOyBBTVQgRGVhY3RpdmF0aW9uIiwgMywgbG1zRGVhY3RpdmF0ZVgxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGxtc0RlYWN0aXZhdGVYMSgpIHsNCiAgICAgICAgICAgIHN0YXR1c2JveCgnSW50ZWwmcmVnOyBBTVQgRGVhY3RpdmF0aW9uJywgJ0RlYWN0aXZhdGluZyBJbnRlbCZyZWc7IEFNVC4uLicpDQogICAgICAgICAgICBsbXMuU2VuZENtZCgyLCBJbnRUb1N0clgoMSkpOyAvLyBTZW5kIHJlcXVlc3QgZm9yIGRlYWN0aXZhdGlvbg0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gbG1zRGVhY3RpdmF0ZVgyKHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnSW50ZWwmcmVnOyBBTVQgRGVhY3RpdmF0aW9uJywgJ0ZhaWxlZCBkZWFjdGl2YXRpb24sIHN0YXR1cyAnICsgc3RhdHVzKQ0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBRSCgnaWRfbG1zRGF0YScsICdQbGVhc2Ugd2FpdCBmb3IgZGVhY3RpdmF0aW9uLi4uJyk7DQogICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0RhdGEyJywgZmFsc2UpOw0KICAgICAgICAgICAgICAgIHNldERpYWxvZ01vZGUoKTsNCiAgICAgICAgICAgICAgICBsbXNSZWZyZXNoKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAvLyBSZWZyZXNoIGJ1dHRvbiBvbiB0aGUgVUkNCiAgICAgICAgZnVuY3Rpb24gbG1zUmVmcmVzaCgpIHsNCiAgICAgICAgICAgIGlmIChsbXMuU3RhdGUgIT0gMikgcmV0dXJuOw0KICAgICAgICAgICAgbG1zLlNlbmRDbWQoMSwgIiIpOyAvLyBTZW5kIHRoZSByZXF1ZXN0IGJhc2ljIGluZm9ybWF0aW9uIGNvbW1hbmQNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENvbmZpZ3VyZSBidXR0b24gb24gdGhlIFVJDQogICAgICAgIGZ1bmN0aW9uIGxtc0NvbmZpZ3VyZSgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoNCwgJ0ludGVsJnJlZzsgQU1UIExvZ2luJywgMywgZnVuY3Rpb24gKCkgeyBsbXNDb25maWd1cmVMb2dpbigpOyB9KTsNCiAgICAgICAgICAgIC8vZDR1c2VybmFtZS5yZWFkT25seSA9IGZhbHNlOw0KICAgICAgICAgICAgZDR1c2VybmFtZS5kaXNhYmxlZCA9IGZhbHNlOw0KICAgICAgICAgICAgaWYgKGQ0dXNlcm5hbWUudmFsdWUgPT0gJ2FkbWluJykgZDR1c2VybmFtZS52YWx1ZSA9ICcnOw0KICAgICAgICAgICAgaW5wdXRCb3hGb2N1cygnZDR1c2VybmFtZScpOw0KICAgICAgICAgICAgbG1zVXBkYXRlTG9naW5EaWFsb2coKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENhbGxlZCB3aGVuIHRoZSB1c2VyIGhpdHMgT0sgb24gdGhlIGxvZ2luIGRpYWxvZw0KICAgICAgICBmdW5jdGlvbiBsbXNDb25maWd1cmVMb2dpbigpIHsNCiAgICAgICAgICAgIHZhciB1c2VyID0gZDR1c2VybmFtZS52YWx1ZTsNCiAgICAgICAgICAgIGlmICh1c2VyID09ICcnKSB1c2VyID0gJ2FkbWluJzsNCiAgICAgICAgICAgIGNvbm5lY3QoJ2xvY2FsaG9zdCcsIDE2OTkyLCB1c2VyLCBkNHBhc3N3b3JkLnZhbHVlLCAwKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIEFjdGl2YXRlIGJ1dHRvbiBvbiB0aGUgVUkNCiAgICAgICAgZnVuY3Rpb24gbG1zQWN0aXZhdGUoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlfHwgbG1zLlN0YXRlICE9IDIpIHJldHVybjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoNCwgJ0ludGVsJnJlZzsgQU1UIEFjdGl2YXRpb24nLCAzLCBmdW5jdGlvbiAoKSB7IGxtc0FjdGl2YXRlRXgoKTsgfSk7DQogICAgICAgICAgICAvL2Q0dXNlcm5hbWUucmVhZE9ubHkgPSB0cnVlOw0KICAgICAgICAgICAgZDR1c2VybmFtZS5kaXNhYmxlZCA9IHRydWU7DQogICAgICAgICAgICBkNHVzZXJuYW1lLnZhbHVlID0gJ2FkbWluJzsNCiAgICAgICAgICAgIGlucHV0Qm94Rm9jdXMoJ2Q0cGFzc3dvcmQnKTsNCiAgICAgICAgICAgIGxtc1VwZGF0ZUxvZ2luRGlhbG9nKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBHbyBoZWFkIHdpdGggSW50ZWwgQU1UIGNsaWVudCBjb250cm9sIG1vZGUgYWN0aXZhdGlvbg0KICAgICAgICBmdW5jdGlvbiBsbXNBY3RpdmF0ZUV4KCkNCiAgICAgICAgew0KICAgICAgICAgICAgbG1zLlNlbmRDbWQoMyk7IC8vIFNlbmQgcmVxdWVzdCBmb3IgYWNjb3VudCBpbmZvcm1hdGlvbg0KICAgICAgICAgICAgc3RhdHVzYm94KCdJbnRlbCZyZWc7IEFNVCBBY3RpdmF0aW9uJywgJ0ZldGNoaW5nIEFjY291bnQgSW5mb3JtYXRpb24uLi4nKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENhbGxlZCBlYWNoIHRpbWUgc29tZXRoaW5nIGNoYW5nZXMgaW4gdGhlIGxvZ2luIGRpYWxvZw0KICAgICAgICBmdW5jdGlvbiBsbXNVcGRhdGVMb2dpbkRpYWxvZyhlLCBkKSB7DQogICAgICAgICAgICB2YXIgb2sgPSBwYXNzd29yZGNoZWNrKGQ0cGFzc3dvcmQudmFsdWUpOw0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgICAgIGlmIChlICE9IG51bGwgJiYgZS5rZXlDb2RlID09IDEzICYmIGQgPT0gMSkgaW5wdXRCb3hGb2N1cygnZDRwYXNzd29yZCcpOw0KICAgICAgICAgICAgaWYgKG9rID09IHRydWUgJiYgZSAhPSBudWxsICYmIGUua2V5Q29kZSA9PSAxMyAmJiBkID09IDIpIGRpYWxvZ2Nsb3NlKDEpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGxtc0hhc2hBcmdTdHJpbmdzID0gWyJNRDUiLCAiU0hBMSIsICJTSEEyNTYiLCAiU0hBNTEyIl07DQogICAgICAgIGZ1bmN0aW9uIGxtc1Nob3dUcnVzdGVkSGFzaGVzRGxnKCkgew0KICAgICAgICAgICAgLy8ge1wiQUNcIjolZCxcIkRGXCI6JWQsXCJBTFwiOiVkLFwiTkFcIjpcIiVzXCIsXCJIQVwiOlwiJXNcIn0iDQoNCiAgICAgICAgICAgIHZhciB4ID0gIjxkaXYgc3R5bGU9bWF4LWhlaWdodDoyNDBweDtvdmVyZmxvdy15OnNjcm9sbD4iICsgVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBsbXNNZUluZm9bJ1RydXN0ZWRIYXNoZXMnXSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAvL3ggKz0gIjxiPiIgKyBsbXNNZUluZm9bJ1RydXN0ZWRIYXNoZXMnXVtpXVsnTmFtZSddICsgIjwvYj48YnI+PHNwYW4gc3R5bGU9Zm9udC1zaXplOjEwcHg+IiArIGxtc0hhc2hBcmdTdHJpbmdzW2xtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydIYXNoQWxnb3JpdGhtJ11dICsgKGxtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydBY3RpdmUnXSA9PSAxPyIsIEFjdGl2ZSI6IiIpICsgKGxtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydEZWZhdWx0J10gPT0gMT8iLCBEZWZhdWx0IjoiIikgKyAiPC9zcGFuPjxicj48c3BhbiBzdHlsZT1mb250LXNpemU6MTBweD4iICsgbG1zTWVJbmZvWydUcnVzdGVkSGFzaGVzJ11baV1bJ0hhc2gnXSArICI8L3NwYW4+PGJyPjxicj4iOw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiPGI+IiArIGxtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydOYW1lJ10gKyAiPC9iPjxicj48c3BhbiBzdHlsZT1mb250LXNpemU6MTBweD4iICsgbG1zSGFzaEFyZ1N0cmluZ3NbbG1zTWVJbmZvWydUcnVzdGVkSGFzaGVzJ11baV1bJ0hhc2hBbGdvcml0aG0nXV0gKyAobG1zTWVJbmZvWydUcnVzdGVkSGFzaGVzJ11baV1bJ0FjdGl2ZSddID09IDE/IiwgQWN0aXZlIjoiIikgKyAobG1zTWVJbmZvWydUcnVzdGVkSGFzaGVzJ11baV1bJ0RlZmF1bHQnXSA9PSAxPyIsIERlZmF1bHQiOiIiKSArICI8L3NwYW4+PGJyPjxzcGFuIHN0eWxlPWZvbnQtc2l6ZTo4cHg+IiArIGxtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydIYXNoJ10gKyAiPC9zcGFuPiIsICIiKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoKSArICI8L2Rpdj4iOw0KICAgICAgICAgICAgbWVzc2FnZWJveCgiSW50ZWwmcmVnOyBBTVQgVHJ1c3RlZCBIYXNoZXMiLCB4KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGxtc1Nob3dWZXJzaW9uc0RsZygpIHsNCiAgICAgICAgICAgIHZhciB4ID0gVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJJbnRlbCZyZWc7IEFNVCIsIGxtc01lSW5mb1snVmVyc2lvbnMnXVsnQU1UJ10pOw0KICAgICAgICAgICAgaWYgKGxtc01lSW5mb1snTWVpVmVyc2lvbiddICE9IG51bGwpIHsgeCArPSBUYWJsZUVudHJ5KCJJbnRlbCZyZWc7IE1FSSBkcml2ZXIiLCBsbXNNZUluZm9bJ01laVZlcnNpb24nXSk7IH0NCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gbG1zTWVJbmZvWydWZXJzaW9ucyddKSB7IGlmIChpICE9ICdBTVQnKSB4ICs9IFRhYmxlRW50cnkoaSwgbG1zTWVJbmZvWydWZXJzaW9ucyddW2ldKTsgfQ0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgbWVzc2FnZWJveCgiSW50ZWwmcmVnOyBBTVQgVmVyc2lvbnMiLCB4KTsNCiAgICAgICAgfQ0KDQoNCg0KICAgICAgICBmdW5jdGlvbiBjbGVhbnVwKCkgew0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gaGFuZGxlS2V5VXAoZSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gaGFuZGxlS2V5RG93bihlKSB7DQogICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdoYW5kbGVLZXlEb3duJywgZSk7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBoYW5kbGVLZXlQcmVzcyhlKSB7DQogICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdoYW5kbGVLZXlQcmVzcycsIGUpOw0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGNvbm5lY3RGdW5jID0gbnVsbDsNCiAgICAgICAgdmFyIGNvbm5lY3RGdW5jVGFnID0gbnVsbDsNCiAgICAgICAgZnVuY3Rpb24gY29ubmVjdChob3N0LCBwb3J0LCB1c2VyLCBwYXNzLCB0bHMsIGZ1bmMsIGZ1bmN0YWcpIHsNCiAgICAgICAgICAgIGdvKDApOw0KICAgICAgICAgICAgZnVsbHNjcmVlbm9ubHkgPSBmYWxzZTsNCiAgICAgICAgICAgIGNvbm5lY3RGdW5jID0gZnVuYzsNCiAgICAgICAgICAgIGNvbm5lY3RGdW5jVGFnID0gZnVuY3RhZzsNCg0KDQoNCiAgICAgICAgICAgIHdzc3RhY2sgPSBXc21hblN0YWNrQ3JlYXRlU2VydmljZShob3N0LCBwb3J0LCB1c2VyLCBwYXNzLCB0bHMpOw0KICAgICAgICAgICAgYW10c3RhY2sgPSBBbXRTdGFja0NyZWF0ZVNlcnZpY2Uod3NzdGFjayk7DQogICAgICAgICAgICBhbXRzdGFjay5vblByb2Nlc3NDaGFuZ2VkID0gb25Qcm9jZXNzQ2hhbmdlZDsNCg0KICAgICAgICAgICAgLy8gU2V0dXAgVExTIGNoZWNraW5nDQoNCiAgICAgICAgICAgIC8vIEhpZGUgVExTIGluZGljYXRvcg0KDQogICAgICAgICAgICAvLyBIaWRlIG1vc3Qgb2YgdGhlIGxlZnQgbWVudSBvcHRpb25zLCB3ZSB3aWxsIHNlZSB0aGVtIGFzIHdlIGxvYWQgZGF0YQ0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDI7IGkgPCAyNTsgaSsrKSB7IFFWKCdnbycgKyBpLCBmYWxzZSk7IH0NCiAgICAgICAgICAgIFFWKCdnbzgnLCB0cnVlKTsgLy8gTmV0d29yayBTZXR0aW5ncw0KICAgICAgICAgICAgLy9RVignZ28xNScsIGZhbHNlKTsgLy8gQXVkaXQgTG9nDQoNCiAgICAgICAgICAgIC8vUVYoJ2dvMTYnLCBmYWxzZSk7IC8vIFNlY3VyaXR5IFNldHRpbmdzDQoNCiAgICAgICAgICAgIC8vUVYoJ2dvMTcnLCBmYWxzZSk7IC8vIFJlbW90ZSBBY2Nlc3MNCg0KICAgICAgICAgICAgUVYoJ2dvMjAnLCB0cnVlKTsgLy8gU2NyaXB0aW5nIEVkaXRvcg0KDQoNCg0KICAgICAgICAgICAgLy8gQ2xlYXIgdGhlIGRpc3BsYXllZCBwb3dlciBzdGF0ZQ0KDQogICAgICAgICAgICAvLyBDbGVhciBldmVyeXRoaW5nLCBtYWtlIHN1cmUgYWxsIGNvbm5lY3Rpb24gc3RhdGUgaXMgcmVzZXQuDQogICAgICAgICAgICBhbXR2ZXJzaW9uID0gYW10dmVyc2lvbm1pbiA9IGFtdEZpcnN0UHVsbCA9IDA7DQogICAgICAgICAgICBhbXRzeXNzdGF0ZSA9IGFtdGRlbHRhdGltZSA9IGFtdGxvZ2ljYWxlbGVtZW50cyA9IEhhcmR3YXJlSW52ZW50b3J5ID0gdW5kZWZpbmVkOw0KICAgICAgICAgICAgYW10UG93ZXJCb290Q2FwYWJpbGl0aWVzID0gbnVsbDsNCiAgICAgICAgICAgIHh4QWNjb3VudEZldGNoID0gOTk5Ow0KDQogICAgICAgICAgICAvLyBTaG93IGxvYWRpbmcgb24gYWxsIHBhbmVscw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlU3lzU3RhdHVzJywgTG9hZGluZ0h0bWwpOw0KDQogICAgICAgICAgICBRSCgnaWRfVGFibGVOZXR3b3JrU2V0dGluZ3NTcGFuJywgTG9hZGluZ0h0bWwpOw0KICAgICAgICAgICAgYW10d2lyZWxlc3NpZiA9IC0xOw0KDQogICAgICAgICAgICB4eFdpcmVsZXNzID0gdW5kZWZpbmVkOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlV2lmaTInLCAnJyk7DQoNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVN5c0luZm8nLCBMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIHh4QWNjb3VudEFkbWluTmFtZSA9IG51bGw7DQogICAgICAgICAgICB4eEFjY291bnRSZWFsbUluZm8gPSB7fTsNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVVzZXJBY2NvdW50cycsIExvYWRpbmdIdG1sKTsNCg0KICAgICAgICAgICAgZXZlbnRtZXNzYWdlcyA9IG51bGw7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVFdmVudExvZycsJycpOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlRXZlbnRMb2cyJyxMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIGF1ZGl0TG9nID0gbnVsbDsNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZUF1ZGl0TG9nMScsICcnKTsNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZUF1ZGl0TG9nMicsIExvYWRpbmdIdG1sKTsNCg0KICAgICAgICAgICAgeHhDZXJ0aWZpY2F0ZXMgPSBudWxsOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlQ2VydHMnLCBMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIHh4UmVtb3RlQWNjZXNzID0gbnVsbDsNCiAgICAgICAgICAgIHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uID0gbnVsbDsNCiAgICAgICAgICAgIHh4Q2lyYVNlcnZlcnMgPSBudWxsOw0KICAgICAgICAgICAgeHhVc2VySW5pdGlhdGVkQ2lyYSA9IG51bGw7DQogICAgICAgICAgICB4eFJlbW90ZUFjY2Vzc0NyZWRlbnRpYUxpbmtzID0gbnVsbDsNCiAgICAgICAgICAgIHh4TVBTVXNlclBhc3MgPSBudWxsOw0KICAgICAgICAgICAgeHhQb2xpY2llcyA9IG51bGw7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVSZW1vdGVBY2Nlc3MnLCBMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVN5c3RlbUFnZW50UHJlc2VuY2UnLCBMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIHh4U3lzdGVtRGVmZW5zZSA9IG51bGw7DQogICAgICAgICAgICB4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3kgPSB7fTsNCiAgICAgICAgICAgIHh4VXBkYXRpbmdEZWZlbnNlU3RhdHMgPSBmYWxzZTsNCiAgICAgICAgICAgIHh4RmlsdGVyU3RhdGlzdGljcyA9IFt7fSwge31dOyAvLyBXaXJlZCBhbmQgd2lyZWxlc3MgaW50ZXJmYWNlIHN0YXRzDQogICAgICAgICAgICB4eEZpbHRlclN0YXRpc3RpY3NUaW1lciA9IG51bGw7DQogICAgICAgICAgICB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9IGZhbHNlOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlU3lzdGVtRGVmZW5zZScsIExvYWRpbmdIdG1sKTsNCg0KDQogICAgICAgICAgICAvLyBTdGFydCBwdWxsaW5nIEludGVsIEFNVCBpbmZvcm1hdGlvbg0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKCIiLCBbIkNJTV9Tb2Z0d2FyZUlkZW50aXR5IiwgIipBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSJdLCBwcm9jZXNzU3lzdGVtVmVyc2lvbik7IC8vIEdldCBJbnRlbCBBTVQgdmVyc2lvbiBpbmZvcm1hdGlvbiBhbmQgcGxlbnR5IG1vcmUNCiAgICAgICAgICAgIC8vYW10c3RhY2suRW51bSgiQ0lNX0xvZ2ljYWxFbGVtZW50IiwgcHJvY2Vzc1N5c3RlbVZlcnNpb24pOyAvLyBHZXQgSW50ZWwgQU1UIHZlcnNpb24gaW5mb3JtYXRpb24gYW5kIHBsZW50eSBtb3JlDQoNCg0KDQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBkaXNjb25uZWN0KCkgew0KDQoNCg0KDQoNCg0KICAgICAgICAgICAgU3RvcERlZmVuc2VTdGF0c1RpbWVyKCk7DQoNCg0KICAgICAgICAgICAgc2NyaXB0X1N0b3AoKTsNCg0KICAgICAgICAgICAgYnJlYWtTY3JpcHRCdXR0b24oKTsNCg0KICAgICAgICAgICAgZGlhbG9nY2xvc2UoMCk7DQoNCiAgICAgICAgICAgIFFIKCdpZF9jb21wdXRlcm5hbWUnLCAnJyk7DQogICAgICAgICAgICBpZiAoYW10c3RhY2spIHsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5vblByb2Nlc3NDaGFuZ2VkID0gbnVsbDsgLy8gVW4taG9vayBwcm9ncmVzcyBpbmRpY2F0b3INCiAgICAgICAgICAgICAgICBhbXRzdGFjay5DYW5jZWxBbGxRdWVyaWVzKDk5OSk7IC8vIEZhaWwgYWxsIHBlbmRpbmcgV1NNQU4gY2FsbHMuIFNldCB0byA5OTkgdG8gaW5kaWNhdGUgbm90IHRvIGNhbGwgYmFjayBhbnkgb2YgdGhlIHBlbmRpbmcgY2FsbHMgd2l0aCBlcnJvcnMuDQogICAgICAgICAgICAgICAgYW10c3RhY2sgPSBudWxsOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY2xlYW51cCgpOw0KICAgICAgICAgICAgd3NzdGFjayA9IG51bGw7DQogICAgICAgICAgICBkZWxldGUgYW10c3RhY2s7DQogICAgICAgICAgICBvblByb2Nlc3NDaGFuZ2VkKDAsIDEpOw0KICAgICAgICAgICAgZ28oMTAxKTsNCg0KDQoNCiAgICAgICAgICAgIFFIKCdpZF9jb21wdXRlcm5hbWUnLCAnUmVtb3RlIE1hbmFnZW1lbnQgQ29uc29sZSB2JyArIHZlcnNpb24pOw0KICAgICAgICAgICAgDQoNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIG9uUHJvY2Vzc0NoYW5nZWQoYSwgYikgew0KICAgICAgICAgICAgUVMoJ2lkX3Byb2dyZXNzYmFyJykud2lkdGggPSAoKGEgKiAxMDApIC8gYikgKyAiJSI7DQogICAgICAgICAgICBpZiAoYSA9PSAwKSByZWZyZXNoQnV0dG9ucyh0cnVlKTsgLy8gSWYgbm90aGluZyBpcyBiZWluZyBkb25lLCByZS1lbmFibGUgcmVmcmVzaCBidXR0b25zDQoNCg0KICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm90aGluZyBiZWluZyBkb25lIG5vdywgc2VlIGlmIHdlIGNhbiBwdWxsIG1vcmUgaW5mb3JtYXRpb24NCiAgICAgICAgICAgIGlmIChhICE9IDAgfHwgIWFtdHN0YWNrKSByZXR1cm47DQogICAgICAgICAgICBpZiAoKGFtdHZlcnNpb24gPiAwKSAmJiAoKGFtdEZpcnN0UHVsbCAmIDY0KSA9PSAwKSkgew0KICAgICAgICAgICAgICAgIGFtdEZpcnN0UHVsbCB8PSA2NDsNCiAgICAgICAgICAgICAgICBQdWxsUG93ZXJQb2xpY3koKTsNCg0KICAgICAgICAgICAgICAgIFB1bGxXYXRjaGRvZygpOw0KDQoNCiAgICAgICAgICAgICAgICBzY3JpcHRWaWV3QnV0dG9uKHNjcmlwdF9CdWlsZGluZ0Jsb2Nrcz8xOjApOw0KDQogICAgICAgICAgICAgICAgaWYgKGFtdHZlcnNpb24gPiA1KSB7DQoNCiAgICAgICAgICAgICAgICAgICAgUHVsbENlcnRpZmljYXRlcygpOw0KDQogICAgICAgICAgICAgICAgICAgIFB1bGxSZW1vdGVBY2Nlc3MoKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAoKGFtdEZpcnN0UHVsbCAmIDEpID09IDApIHsgUHVsbEhhcmR3YXJlKCk7IHJldHVybjsgfQ0KDQogICAgICAgICAgICBpZiAoKGFtdEZpcnN0UHVsbCAmIDE2KSA9PSAwKSB7IFB1bGxFdmVudExvZygpOyByZXR1cm47IH0NCg0KICAgICAgICAgICAgaWYgKChhbXRGaXJzdFB1bGwgJiAzMikgPT0gMCkgeyBQdWxsQXVkaXRMb2coKTsgcmV0dXJuOyB9DQogICAgICAgIH0NCg0KDQogICAgICAgIGZ1bmN0aW9uIHRvb2xtZW51Y2xpY2soeCkgew0KICAgICAgICAgICAgUVYoJ2lkX21lbnVpdGVtMScsIGN1cnJlbnRWaWV3ID09IDEwMSk7DQoNCiAgICAgICAgICAgIFFWKCdpZF9tZW51aXRlbTInLCBjdXJyZW50VmlldyA9PSAxMDIpOw0KDQogICAgICAgICAgICB2YXIgZCA9IChRUygnaWRfY29tcHV0ZXJTZWxlY3Rvck1lbnUnKS5kaXNwbGF5ID09ICdub25lJyk7DQogICAgICAgICAgICBpZiAoZCA9PSB0cnVlICYmIHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgeHhkaWFsb2dNb2RlID0gKGQgPT0gdHJ1ZSk/OTk5OnVuZGVmaW5lZDsNCiAgICAgICAgICAgIFFWKCdpZF9jb21wdXRlclNlbGVjdG9yTWVudScsIGQpOw0KICAgICAgICAgICAgaWYgKHggPT0gMCkgcmV0dXJuOw0KICAgICAgICAgICAgZ28oeCk7DQogICAgICAgIH0NCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gQk9UVE9NIElORk9STUFUSU9OIFNUUklORw0KICAgICAgICAvLw0KDQoNCiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1N5c3RlbVZlcnNpb24oc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCB8fCBzdGF0dXMgPT0gNDAwKSB7DQogICAgICAgICAgICAgICAgdmFyIHY7DQogICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsNCiAgICAgICAgICAgICAgICAgICAgLy9hbXRsb2dpY2FsZWxlbWVudHMgPSByZXNwb25zZXM7DQogICAgICAgICAgICAgICAgICAgIGFtdGxvZ2ljYWxlbGVtZW50cyA9IFtdOw0KICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2VzICE9IG51bGwpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZXNbIkNJTV9Tb2Z0d2FyZUlkZW50aXR5Il0gIT0gbnVsbCAmJiByZXNwb25zZXNbIkNJTV9Tb2Z0d2FyZUlkZW50aXR5Il0ucmVzcG9uc2VzICE9IG51bGwpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbXRsb2dpY2FsZWxlbWVudHMgPSByZXNwb25zZXNbIkNJTV9Tb2Z0d2FyZUlkZW50aXR5Il0ucmVzcG9uc2VzOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZXNbIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIl0gIT0gbnVsbCAmJiByZXNwb25zZXNbIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIl0ucmVzcG9uc2UgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbXRsb2dpY2FsZWxlbWVudHMucHVzaChyZXNwb25zZXNbIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIl0ucmVzcG9uc2UpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoYW10bG9naWNhbGVsZW1lbnRzLmxlbmd0aCA9PSAwKSB7IGNvbnNvbGUuZXJyb3IoJ0VSUk9SOiBDb3VsZCBub3QgZ2V0IEludGVsIEFNVCB2ZXJzaW9uLicpOyBkaXNjb25uZWN0KCk7IHJldHVybjsgfSAvLyBDb3VsZCBub3QgZ2V0IEludGVsIEFNVCB2ZXJzaW9uLCBkaXNjb25uZWN0KCk7DQogICAgICAgICAgICAgICAgICAgIHYgPSBnZXRJbnN0YW5jZShhbXRsb2dpY2FsZWxlbWVudHMsICJBTVQiKVsiVmVyc2lvblN0cmluZyJdOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIHYgPSBzdGFjay53c21hbi5jb21tLmFtdFZlcnNpb247DQogICAgICAgICAgICAgICAgICAgIGlmICghdikgeyBlcnJjaGVjayg0MDAsIHN0YWNrKTsgcmV0dXJuOyB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGFtdHZlcnNpb24gPSBwYXJzZUludCh2LnNwbGl0KCcuJylbMF0pOw0KICAgICAgICAgICAgICAgIGFtdHZlcnNpb25taW4gPSBwYXJzZUludCh2LnNwbGl0KCcuJylbMV0pOw0KDQoNCiAgICAgICAgICAgICAgICAvL2lmIChhbXR2ZXJzaW9uID4gMTApIHsgd3NzdGFjay5jb21tLk1heEFjdGl2ZUFqYXhDb3VudCA9IDQ7IGFtdHN0YWNrLk1heEFjdGl2ZUVudW1zQ291bnQgPSAxOyBjb25zb2xlLmxvZygnSFRUUCBQaXBlbGluaW5nIGFjdGl2YXRlZCcpOyB9IC8vIFdpdGggSW50ZWwgQU1UIDExIGFuZCBoaWdoZXIsIHVzZSBIVFRQIHBpcGVsaW5pbmcuDQoNCiAgICAgICAgICAgICAgICBQdWxsU3lzdGVtU3RhdHVzKCk7DQogICAgICAgICAgICAgICAgdXBkYXRlU3lzdGVtU3RhdHVzKCk7DQoNCiAgICAgICAgICAgICAgICAvLyBQZXJmb3JtIGxvYWRzIG1vcmUgV1NNQU4gb25seSBpZiBuZWVkZWQNCiAgICAgICAgICAgICAgICBpZiAoKHVybHZhcnNbJ2t2bW9ubHknXSAhPSAxKSAmJiAoZnVsbHNjcmVlbm9ubHkgPT0gZmFsc2UpKSB7DQogICAgICAgICAgICAgICAgICAgIFB1bGxVc2VySW5mbygpOw0KDQoNCiAgICAgICAgICAgICAgICAgICAgaWYgKGFtdHZlcnNpb24gPj0gOCkgUHVsbEFsYXJtcygpOw0KICAgICAgICAgICAgICAgIH0NCg0KDQogICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBjYWxsYmFjaw0KICAgICAgICAgICAgICAgIGlmIChjb25uZWN0RnVuYykgeyBjb25uZWN0RnVuYyhjb25uZWN0RnVuY1RhZyk7IGNvbm5lY3RGdW5jID0gbnVsbDsgY29ubmVjdEZ1bmNUYWcgPSBudWxsOyB9DQoNCg0KDQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIGVycmNoZWNrKHN0YXR1cywgc3RhY2spOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ29udHJvbCB0aGUgc3RhdGUgb2YgYWxsIHJlZnJlc2ggYnV0dG9ucw0KICAgICAgICB2YXIgcmVmcmVzaEJ1dHRvbnNTdGF0ZSA9IHRydWU7DQogICAgICAgIGZ1bmN0aW9uIHJlZnJlc2hCdXR0b25zKHgpIHsNCiAgICAgICAgICAgIGlmIChyZWZyZXNoQnV0dG9uc1N0YXRlID09IHgpIHJldHVybjsNCiAgICAgICAgICAgIHJlZnJlc2hCdXR0b25zU3RhdGUgPSB4Ow0KICAgICAgICAgICAgdmFyIGkgPSAwLCBlID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0Jyk7DQogICAgICAgICAgICBmb3IgKDsgaSA8IGUubGVuZ3RoOyBpKyspIHsgaWYgKGVbaV0ubmFtZSA9PSAncmVmcmVzaGJ0bicpIHsgZVtpXS5kaXNhYmxlZCA9ICF4OyB9IH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIERpc3BsYXkgVExTIGNlcnRpZmljYXRlDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gU1lTVEVNIFNUQVRVUyBQQU5FTA0KICAgICAgICAvLw0KDQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFN5c3RlbVN0YXR1cyh4KSB7DQogICAgICAgICAgICByZWZyZXNoQnV0dG9ucyhmYWxzZSk7DQogICAgICAgICAgICBhbXRzdGFjay5BTVRfVGltZVN5bmNocm9uaXphdGlvblNlcnZpY2VfR2V0TG93QWNjdXJhY3lUaW1lU3luY2gocHJvY2Vzc1N5c3RlbVRpbWUpOw0KDQogICAgICAgICAgICB2YXIgcXVlcnkgPSBbIkNJTV9TZXJ2aWNlQXZhaWxhYmxlVG9FbGVtZW50IiwgIipBTVRfR2VuZXJhbFNldHRpbmdzIiwgIkFNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyIsICIqQU1UX1JlZGlyZWN0aW9uU2VydmljZSIsICJDSU1fRWxlbWVudFNldHRpbmdEYXRhIl07DQogICAgICAgICAgICBpZiAoYW10dmVyc2lvbiA+IDUpIHF1ZXJ5LnB1c2goIklQU19JUHY2UG9ydFNldHRpbmdzIiwgIipDSU1fS1ZNUmVkaXJlY3Rpb25TQVAiLCAiKklQU19PcHRJblNlcnZpY2UiLCIqSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEiKTsNCiAgICAgICAgICAgIGlmIChhbXR2ZXJzaW9uID4gOSkgcXVlcnkucHVzaCgiKklQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSIpOw0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKCIiLCBxdWVyeSwgcHJvY2Vzc1N5c3RlbVN0YXR1cywgdHJ1ZSk7DQoNCiAgICAgICAgICAgIGlmICh4ID09IDEpIFB1bGxXaXJlbGVzcygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1N5c3RlbVRpbWUoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoZXJyY2hlY2soc3RhdHVzLCBzdGFjaykpIHJldHVybjsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSB7DQogICAgICAgICAgICAgICAgLy8gQ29udmVydCBtcyB0byB0aW1lIGFuZCBhZGp1c3QgZm9yIHRoZSB0aW1lem9uZQ0KICAgICAgICAgICAgICAgIHZhciB0ID0gbmV3IERhdGUoKSwgdDIgPSBuZXcgRGF0ZSgpOw0KICAgICAgICAgICAgICAgIHQuc2V0VGltZShyZXNwb25zZXMuQm9keVsiVGEwIl0gKiAxMDAwICsgKHQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwICogMTAwMCkpOw0KICAgICAgICAgICAgICAgIGFtdGRlbHRhdGltZSA9IHQgLSB0MjsNCiAgICAgICAgICAgICAgICB1cGRhdGVTeXN0ZW1TdGF0dXMoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIHZhciBhbXRkZWx0YXRpbWU7DQogICAgICAgIHZhciBhbXRzeXNzdGF0ZTsNCiAgICAgICAgdmFyIGFtdGxvZ2ljYWxlbGVtZW50czsgLy8gcHJvY2Vzc1N5c3RlbVZlcnNpb24NCiAgICAgICAgdmFyIGFtdGZlYXR1cmVzID0ge307DQogICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NTeXN0ZW1TdGF0dXMoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICAvLyBJZiB0aGlzIGNvbXB1dGVyIGhhcyBubyBLVk0sIGlnbm9yZSBhbmQgY29udGludWUgKFN0YW5kYXJkIE1hbmFnZWFiaWxpdHkpDQogICAgICAgICAgICBpZiAoKHJlc3BvbnNlc1snSVBTX1NjcmVlbkNvbmZpZ3VyYXRpb25TZXJ2aWNlJ10gPT0gdW5kZWZpbmVkKSB8fCAocmVzcG9uc2VzWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXS5zdGF0dXMgPT0gNDAwKSkgeyByZXNwb25zZXNbJ0lQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSddID0gbnVsbDsgfQ0KICAgICAgICAgICAgaWYgKChyZXNwb25zZXNbJ0lQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhJ10gPT0gdW5kZWZpbmVkKSB8fCAocmVzcG9uc2VzWydJUFNfS1ZNUmVkaXJlY3Rpb25TZXR0aW5nRGF0YSddLnN0YXR1cyA9PSA0MDApKSB7IHJlc3BvbnNlc1snSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnXSA9IG51bGw7IH0NCiAgICAgICAgICAgIGlmICgocmVzcG9uc2VzWydDSU1fS1ZNUmVkaXJlY3Rpb25TQVAnXSA9PSB1bmRlZmluZWQpIHx8IChyZXNwb25zZXNbJ0NJTV9LVk1SZWRpcmVjdGlvblNBUCddLnN0YXR1cyA9PSA0MDApKSB7IHJlc3BvbnNlc1snQ0lNX0tWTVJlZGlyZWN0aW9uU0FQJ10gPSBudWxsOyB9DQogICAgICAgICAgICBpZiAoKHJlc3BvbnNlc1snSVBTX09wdEluU2VydmljZSddID09IHVuZGVmaW5lZCkgfHwgKHJlc3BvbnNlc1snSVBTX09wdEluU2VydmljZSddLnN0YXR1cyA9PSA0MDApKSB7IHJlc3BvbnNlc1snSVBTX09wdEluU2VydmljZSddID0gbnVsbDsgfQ0KICAgICAgICAgICAgaWYgKChyZXNwb25zZXNbJ0FNVF9SZWRpcmVjdGlvblNlcnZpY2UnXSAhPSB1bmRlZmluZWQpICYmIChyZXNwb25zZXNbJ0FNVF9SZWRpcmVjdGlvblNlcnZpY2UnXS5zdGF0dXMgPT0gMjAwKSkgeyBRVignZ28xMycsIHRydWUpOyB9IC8vIFNob3cgdGhlIHRlcm1pbmFsDQoNCiAgICAgICAgICAgIC8vIFJlc2V0IHRoZSBzdGF0dXMgYWZ0ZXIgcG9zc2libGUgS1ZNIHJlbW92YWwNCiAgICAgICAgICAgIHN0YXR1cyA9IDA7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHJlc3BvbnNlcykgeyBpZiAoKHJlc3BvbnNlc1tpXSAhPSBudWxsKSAmJiAocmVzcG9uc2VzW2ldLnN0YXR1cyA+IHN0YXR1cykpIHsgc3RhdHVzID0gcmVzcG9uc2VzW2ldLnN0YXR1czsgfSB9DQoNCiAgICAgICAgICAgIGlmICgoc3RhdHVzICE9IDQwMCkgJiYgZXJyY2hlY2soc3RhdHVzLCBzdGFjaykpIHJldHVybjsNCiAgICAgICAgICAgIGFtdHN5c3N0YXRlID0gcmVzcG9uc2VzOw0KICAgICAgICAgICAgdXBkYXRlU3lzdGVtU3RhdHVzKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1cGRhdGVTeXN0ZW1TdGF0dXMoKSB7DQogICAgICAgICAgICBpZiAoKCFhbXRzeXNzdGF0ZSkgfHwgKGN1cnJlbnRWaWV3ID4gOTkpKSByZXR1cm47DQogICAgICAgICAgIA0KICAgICAgICAgICAgLy8gU3lzdGVtIFN0YXR1cyBUYWJsZQ0KICAgICAgICAgICAgdmFyIHN5c3RlbWRlZmVuc2UgPSAwLCBob3N0LCB5LCB4ID0gVGFibGVTdGFydCgpLCBmZWF0dXJlcyA9ICcnLCBncyA9IGFtdHN5c3N0YXRlWydBTVRfR2VuZXJhbFNldHRpbmdzJ10ucmVzcG9uc2U7DQoNCiAgICAgICAgICAgIGhvc3QgPSBnc1siSG9zdE5hbWUiXTsNCiAgICAgICAgICAgIHkgPSBnc1siRG9tYWluTmFtZSJdOw0KICAgICAgICAgICAgaWYgKHkgIT0gbnVsbCAmJiB5Lmxlbmd0aCA+IDApIGhvc3QgKz0gIi4iICsgeTsNCiAgICAgICAgICAgIGlmIChob3N0Lmxlbmd0aCA9PSAwKSB7IGhvc3QgPSAiPGk+Tm9uZTwvaT4iOyB9IGVsc2UgeyBob3N0ID0gRXNjYXBlSHRtbChob3N0KTsgfQ0KICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJOYW1lICYgRG9tYWluIiwgYWRkTGlua0NvbmRpdGlvbmFsKGhvc3QsICdzaG93RWRpdE5hbWVEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgaWYgKEhhcmR3YXJlSW52ZW50b3J5KSB4ICs9IFRhYmxlRW50cnkoIlN5c3RlbSBJRCIsIGd1aWRUb1N0cihIYXJkd2FyZUludmVudG9yeVsnQ0lNX0NvbXB1dGVyU3lzdGVtUGFja2FnZSddLnJlc3BvbnNlWyJQbGF0Zm9ybUdVSUQiXS50b0xvd2VyQ2FzZSgpKSk7DQogICAgICAgICAgICBpZiAoYW10bG9naWNhbGVsZW1lbnRzKSB7DQogICAgICAgICAgICAgICAgdmFyIG1vZGUgPSAnJywgc2NzID0gZ2V0SXRlbShhbXRsb2dpY2FsZWxlbWVudHMsICJDcmVhdGlvbkNsYXNzTmFtZSIsICJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIpOw0KDQogICAgICAgICAgICAgICAgaWYgKChzY3NbIlByb3Zpc2lvbmluZ1N0YXRlIl0gPT0gMikgJiYgKGFtdHZlcnNpb24gPiA1KSkgew0KICAgICAgICAgICAgICAgICAgICBtb2RlID0gJyBhY3RpdmF0ZWQgaW4gQWRtaW4gQ29udHJvbCBNb2RlIChBQ00pJzsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHNjc1siUHJvdmlzaW9uaW5nTW9kZSJdID09IDQpIHsgbW9kZSA9ICcgYWN0aXZhdGVkIGluIENsaWVudCBDb250cm9sIE1vZGUgKENDTSknOyBzeXN0ZW1kZWZlbnNlID0gOTsgfQ0KICAgICAgICAgICAgICAgIH0NCg0KDQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJJbnRlbCZyZWc7IE1FIiwgInYiICsgZ2V0SXRlbShhbXRsb2dpY2FsZWxlbWVudHMsICJJbnN0YW5jZUlEIiwgIkFNVCIpWyJWZXJzaW9uU3RyaW5nIl0gKyBtb2RlKTsNCg0KICAgICAgICAgICAgfQ0KDQoNCg0KDQogICAgICAgICAgICBRSCgnaWRfY29tcHV0ZXJuYW1lJywgJ0NvbXB1dGVyOiAnICsgKChnc1siSG9zdE5hbWUiXSA9PSAnJykgPyAiPGk+Tm9uZTwvaT4iIDogZ3NbIkhvc3ROYW1lIl0pKTsNCg0KDQoNCg0KICAgICAgICAgICAgLy8gSW50ZWwgQU1UIEZlYXR1cmVzDQogICAgICAgICAgICBpZiAoYW10c3lzc3RhdGVbJ0FNVF9SZWRpcmVjdGlvblNlcnZpY2UnXS5zdGF0dXMgPT0gMjAwKSB7DQogICAgICAgICAgICAgICAgdmFyIHJlZGlyID0gYW10ZmVhdHVyZXNbMF0gPSAoYW10c3lzc3RhdGVbJ0FNVF9SZWRpcmVjdGlvblNlcnZpY2UnXS5yZXNwb25zZVsiTGlzdGVuZXJFbmFibGVkIl0gPT0gdHJ1ZSk7DQogICAgICAgICAgICAgICAgdmFyIHNvbCA9IGFtdGZlYXR1cmVzWzFdID0gKChhbXRzeXNzdGF0ZVsnQU1UX1JlZGlyZWN0aW9uU2VydmljZSddLnJlc3BvbnNlWyJFbmFibGVkU3RhdGUiXSAmIDIpICE9IDApOw0KICAgICAgICAgICAgICAgIHZhciBpZGVyID0gYW10ZmVhdHVyZXNbMl0gPSAoKGFtdHN5c3N0YXRlWydBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlJ10ucmVzcG9uc2VbIkVuYWJsZWRTdGF0ZSJdICYgMSkgIT0gMCk7DQogICAgICAgICAgICAgICAgdmFyIGt2bSA9IGFtdGZlYXR1cmVzWzNdID0gdW5kZWZpbmVkOw0KICAgICAgICAgICAgICAgIGlmICgoYW10dmVyc2lvbiA+IDUpICYmIChhbXRzeXNzdGF0ZVsnQ0lNX0tWTVJlZGlyZWN0aW9uU0FQJ10gIT0gbnVsbCkpIHsNCiAgICAgICAgICAgICAgICAgICAga3ZtID0gYW10ZmVhdHVyZXNbM10gPSAoKGFtdHN5c3N0YXRlWydDSU1fS1ZNUmVkaXJlY3Rpb25TQVAnXS5yZXNwb25zZVsiRW5hYmxlZFN0YXRlIl0gPT0gNiAmJiBhbXRzeXNzdGF0ZVsnQ0lNX0tWTVJlZGlyZWN0aW9uU0FQJ10ucmVzcG9uc2VbIlJlcXVlc3RlZFN0YXRlIl0gPT0gMikgfHwgYW10c3lzc3RhdGVbJ0NJTV9LVk1SZWRpcmVjdGlvblNBUCddLnJlc3BvbnNlWyJFbmFibGVkU3RhdGUiXSA9PSAyIHx8IGFtdHN5c3N0YXRlWydDSU1fS1ZNUmVkaXJlY3Rpb25TQVAnXS5yZXNwb25zZVsiRW5hYmxlZFN0YXRlIl0gPT0gNik7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmIChyZWRpcikgZmVhdHVyZXMgKz0gIiwgUmVkaXJlY3Rpb24gUG9ydCI7DQogICAgICAgICAgICAgICAgaWYgKHNvbCkgZmVhdHVyZXMgKz0gIiwgU2VyaWFsLW92ZXItTEFOIjsNCiAgICAgICAgICAgICAgICBpZiAoaWRlcikgZmVhdHVyZXMgKz0gIiwgSURFLVJlZGlyZWN0IjsNCiAgICAgICAgICAgICAgICBpZiAoa3ZtKSBmZWF0dXJlcyArPSAiLCBLVk0iOw0KICAgICAgICAgICAgICAgIGlmIChmZWF0dXJlcyA9PSAnJykgZmVhdHVyZXMgPSAiICBOb25lIjsNCiAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkFjdGl2ZSBGZWF0dXJlcyIsIGFkZExpbmtDb25kaXRpb25hbChmZWF0dXJlcy5zdWJzdHJpbmcoMiksICdzaG93RmVhdHVyZXNEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAoKGFtdHN5c3N0YXRlWydJUFNfS1ZNUmVkaXJlY3Rpb25TZXR0aW5nRGF0YSddICE9IG51bGwpICYmIChhbXRzeXNzdGF0ZVsnSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnXS5yZXNwb25zZSkpIHsNCiAgICAgICAgICAgICAgICB2YXIgZGVza3RvcFNldHRpbmdzID0gYW10c3lzc3RhdGVbJ0lQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhJ10ucmVzcG9uc2U7DQogICAgICAgICAgICAgICAgdmFyIHNjcmVlbm5hbWUgPSAnUHJpbWFyeSBkaXNwbGF5JzsNCiAgICAgICAgICAgICAgICBpZiAoKGFtdHZlcnNpb24gPiA3KSAmJiAoZGVza3RvcFNldHRpbmdzWydEZWZhdWx0U2NyZWVuJ10gIT09IHVuZGVmaW5lZCkgJiYgKGRlc2t0b3BTZXR0aW5nc1snRGVmYXVsdFNjcmVlbiddIDwgMjU1KSkgeyBzY3JlZW5uYW1lID0gWydQcmltYXJ5IGRpc3BsYXknLCAnU2Vjb25kYXJ5IGRpc3BsYXknLCAnM3JkIGRpc3BsYXknXVtkZXNrdG9wU2V0dGluZ3NbJ0RlZmF1bHRTY3JlZW4nXV07IH0NCiAgICAgICAgICAgICAgICBmZWF0dXJlcyA9ICc8c3BhbiB0aXRsZT0iVGhlIGRlZmF1bHQgcmVtb3RlIGRpc3BsYXkgaXMgdGhlICcgKyBzY3JlZW5uYW1lLnRvTG93ZXJDYXNlKCkgKyAnIj4nICsgc2NyZWVubmFtZSArICI8L3NwYW4+IjsNCiAgICAgICAgICAgICAgICBpZiAoZGVza3RvcFNldHRpbmdzWydJczU5MDBQb3J0RW5hYmxlZCddID09IHRydWUpIHsgZmVhdHVyZXMgKz0gIiwgUG9ydCA1OTAwIGVuYWJsZWQiOyB9DQogICAgICAgICAgICAgICAgaWYgKGRlc2t0b3BTZXR0aW5nc1snT3B0SW5Qb2xpY3knXSA9PSB0cnVlKSB7IGZlYXR1cmVzICs9ICIsICIgKyBkZXNrdG9wU2V0dGluZ3NbJ09wdEluUG9saWN5VGltZW91dCddICsgIiBzZWNvbmQiICsgKChkZXNrdG9wU2V0dGluZ3NbJ09wdEluUG9saWN5VGltZW91dCddID4gMCk/J3MnOicnKSArICIgb3B0LWluIjsgfQ0KICAgICAgICAgICAgICAgIGZlYXR1cmVzICs9ICIsICIgKyBkZXNrdG9wU2V0dGluZ3NbJ1Nlc3Npb25UaW1lb3V0J10gKyAiIG1pbnV0ZSIgKyAoKGRlc2t0b3BTZXR0aW5nc1snU2Vzc2lvblRpbWVvdXQnXSA+IDApID8gJ3MnIDogJycpICsgIiBzZXNzaW9uIHRpbWVvdXQiOw0KDQogICAgICAgICAgICAgICAgLy8gU2NyZWVuIGJsYW5raW5nIG9uIEFNVCAxMCBhbmQgaGlnaGVyDQogICAgICAgICAgICAgICAgaWYgKChhbXR2ZXJzaW9uID4gOSkgJiYgKGFtdHN5c3N0YXRlWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXSAhPSBudWxsKSkgew0KICAgICAgICAgICAgICAgICAgICB2YXIgc2NyZWVuQmxhbmtpbmcgPSAoKGFtdHN5c3N0YXRlWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXS5yZXNwb25zZVsiRW5hYmxlZFN0YXRlIl0gJiAxKSAhPSAwKTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHNjcmVlbkJsYW5raW5nKSBmZWF0dXJlcyArPSAiLCBCbGFua2luZyBBbGxvd2VkIjsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIH0NCg0KDQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJSZW1vdGUgRGVza3RvcCIsIGFkZExpbmtDb25kaXRpb25hbChmZWF0dXJlcywgJ3Nob3dEZXNrdG9wU2V0dGluZ3NEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBJbnRlbCBBTVQgdXNlciBDb25zZW50DQogICAgICAgICAgICBpZiAoKGFtdHZlcnNpb24gPiA1KSAmJiAoYW10c3lzc3RhdGVbJ0lQU19PcHRJblNlcnZpY2UnXSAhPSBudWxsKSAmJiAoYW10c3lzc3RhdGVbJ0lQU19PcHRJblNlcnZpY2UnXS5yZXNwb25zZSAhPSB1bmRlZmluZWQpKSB7DQogICAgICAgICAgICAgICAgZmVhdHVyZXMgPSAiVW5rbm93biBzdGF0ZSI7DQogICAgICAgICAgICAgICAgdmFyIG9wdGlucmVxdWlyZWQgPSBhbXRzeXNzdGF0ZVsnSVBTX09wdEluU2VydmljZSddLnJlc3BvbnNlWyJPcHRJblJlcXVpcmVkIl07DQogICAgICAgICAgICAgICAgaWYgKG9wdGlucmVxdWlyZWQgPT0gMCkgeyBmZWF0dXJlcyA9ICJOb3QgUmVxdWlyZWQiOyB9DQogICAgICAgICAgICAgICAgaWYgKG9wdGlucmVxdWlyZWQgPT0gMSkgeyBmZWF0dXJlcyA9ICJSZXF1aXJlZCBmb3IgS1ZNIG9ubHkiOyB9DQogICAgICAgICAgICAgICAgaWYgKG9wdGlucmVxdWlyZWQgPT0gMHhGRkZGRkZGRikgeyBmZWF0dXJlcyA9ICJBbHdheXMgUmVxdWlyZWQiOyB9DQogICAgICAgICAgICAgICAgaWYgKGFtdHN5c3N0YXRlWydJUFNfT3B0SW5TZXJ2aWNlJ10ucmVzcG9uc2VbIkNhbk1vZGlmeU9wdEluUG9saWN5Il0gPT0gdHJ1ZSkgZmVhdHVyZXMgPSBhZGRMaW5rQ29uZGl0aW9uYWwoZmVhdHVyZXMsICdzaG93Q29uc2VudERsZygpJywgeHhBY2NvdW50QWRtaW5OYW1lKTsgLy8gSWYgd2UgY2FuIG1vZGlmeSB1c2VyIGNvbnNlbnQgc2V0dGluZ3MsIGFkZCB0aGUgbGluayB0byBkbyBpdC4NCiAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIlVzZXIgQ29uc2VudCIsIGZlYXR1cmVzKTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gSW50ZWwgQU1UIFBvd2VyIHBvbGljeQ0KICAgICAgICAgICAgaWYgKEFtdFN5c3RlbVBvd2VyU2NoZW1lcyAhPSBudWxsKSB7DQogICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRTZXR0aW5ncyA9IGFtdHN5c3N0YXRlWydDSU1fRWxlbWVudFNldHRpbmdEYXRhJ10ucmVzcG9uc2VzOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxlbWVudFNldHRpbmdzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50U2V0dGluZ3NbaV1bJ1NldHRpbmdEYXRhJ10gJiYgZWxlbWVudFNldHRpbmdzW2ldWydJc0N1cnJlbnQnXSA9PSAxICYmIGVsZW1lbnRTZXR0aW5nc1tpXVsnU2V0dGluZ0RhdGEnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydSZXNvdXJjZVVSSSddID09ICdodHRwOi8vaW50ZWwuY29tL3diZW0vd3NjaW0vMS9hbXQtc2NoZW1hLzEvQU1UX1N5c3RlbVBvd2VyU2NoZW1lJykgew0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm91bmQgdGhlIGFjdGl2ZSBJbnRlbCBBTVQgcG93ZXIgc2NoZW1lDQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcG93ZXJndWlkID0gZWxlbWVudFNldHRpbmdzW2ldWydTZXR0aW5nRGF0YSddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ11bMV1bJ1ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3cgZmluZCB0aGUgbmFtZSBvZiB0aGUgcG93ZXIgc2NoZW1hIGluIHRoZSBBTVRfU3lzdGVtUG93ZXJTY2hlbWUgdGFibGUNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgQW10U3lzdGVtUG93ZXJTY2hlbWVzLmxlbmd0aDsgaisrKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEFtdFN5c3RlbVBvd2VyU2NoZW1lc1tqXVsnU2NoZW1lR1VJRCddID09IHBvd2VyZ3VpZCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3VuZCB0aGUgcG93ZXIgc2NoZW1lIG5hbWUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJQb3dlciBQb2xpY3kiLCBhZGRMaW5rQ29uZGl0aW9uYWwoQW10U3lzdGVtUG93ZXJTY2hlbWVzW2pdWydEZXNjcmlwdGlvbiddLnNwbGl0KCc6JyApWzFdLCAic2hvd1Bvd2VyUG9saWN5RGxnKFwiIiArIHBvd2VyZ3VpZCArICJcIikiLCB4eEFjY291bnRBZG1pbk5hbWUpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIGlmIChhbXRkZWx0YXRpbWUpIHsgeCArPSBUYWJsZUVudHJ5KCJEYXRlICYgVGltZSIsIG5ldyBEYXRlKG5ldyBEYXRlKCkuZ2V0VGltZSgpICsgYW10ZGVsdGF0aW1lKS50b0xvY2FsZVN0cmluZygpKTsgfQ0KICAgICAgICAgICAgdmFyIGJ1dHRvbnMgPSBBZGRSZWZyZXNoQnV0dG9uKCJQdWxsU3lzdGVtU3RhdHVzKCkiKSArICIgIjsNCg0KICAgICAgICAgICAgYnV0dG9ucyArPSBBZGRCdXR0b24oIlNhdmUgU3RhdGUuLi4iLCAic2F2ZUVudGlyZUFtdFN0YXRlKCkiKSArICIgIjsNCg0KICAgICAgICAgICAgYnV0dG9ucyArPSBBZGRCdXR0b24oIlJ1biBTY3JpcHQuLi4iLCAic2NyaXB0X3J1blNjcmlwdERsZygpIikgKyAiICI7DQogICAgICAgICAgICB4ICs9IFRhYmxlRW5kKGJ1dHRvbnMpOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlU3lzU3RhdHVzJywgeCk7DQoNCg0KICAgICAgICAgICAgdmFyIHggPSAiPHRhYmxlIGNsYXNzPWxvZzEgY2VsbHBhZGRpbmc9MCBjZWxsc3BhY2luZz0wIHN0eWxlPXdpZHRoOjEwMCU7Ym9yZGVyLXJhZGl1czo4cHg+IjsNCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoIjxkaXY+Jm5ic3A7IiArIEFkZFJlZnJlc2hCdXR0b24oIlB1bGxTeXN0ZW1TdGF0dXMoMSkiKQ0KDQogICAgICAgICAgICAgICAgKyAnIENoYW5naW5nIG5ldHdvcmsgc2V0dGluZ3MgbWF5IGNhdXNlIHRoaXMgcGFnZSB0byBiZSB1bmF2YWlsYWJsZSBmb3IgYSBmZXcgc2Vjb25kcy4nDQogICAgICAgICAgICApOw0KDQogICAgICAgICAgICAvLyBHZW5lcmFsIHNldHRpbmdzDQogICAgICAgICAgICB4ICs9ICI8YnI+PGgyPkdlbmVyYWwgU2V0dGluZ3M8L2gyPiI7DQogICAgICAgICAgICB4ICs9IFRhYmxlU3RhcnQoKTsNCg0KICAgICAgICAgICAgLy8gTmV0d29yayBzdGF0ZQ0KICAgICAgICAgICAgLy8gaWYgKGdzWyJBTVROZXR3b3JrRW5hYmxlZCJdKSB7IHggKz0gVGFibGVFbnRyeSgiTmV0d29yayBzdGF0ZSIsIChnc1siQU1UTmV0d29ya0VuYWJsZWQiXT09MSk/IkVuYWJsZWQiOiJEaXNhYmxlZCIpOyB9DQoNCiAgICAgICAgICAgIC8vIFNoYXJlZCBGUURODQogICAgICAgICAgICB2YXIgZnFkbnNoYXJlID0gJyc7DQogICAgICAgICAgICBpZiAoaG9zdCAhPSAiPGk+Tm9uZTwvaT4iKSB7DQogICAgICAgICAgICAgICAgaWYgKGdzWyJTaGFyZWRGUUROIl0gPT0gdHJ1ZSkgZnFkbnNoYXJlID0gJywgc2hhcmVkIHdpdGggT1MnOw0KICAgICAgICAgICAgICAgIGlmIChnc1siU2hhcmVkRlFETiJdID09IGZhbHNlKSBmcWRuc2hhcmUgPSAnLCBkaWZmZXJlbnQgZnJvbSBPUyc7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIk5hbWUgJiBEb21haW4iLCBhZGRMaW5rQ29uZGl0aW9uYWwoaG9zdCArIGZxZG5zaGFyZSwgJ3Nob3dFZGl0TmFtZURsZygxKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KDQogICAgICAgICAgICAvLyBEeW5hbWljIEROUw0KICAgICAgICAgICAgdmFyIGRkbnMgPSAnRGlzYWJsZWQnOw0KICAgICAgICAgICAgaWYgKGdzWyJERE5TVXBkYXRlRW5hYmxlZCJdID09IHRydWUpIHsNCiAgICAgICAgICAgICAgICBkZG5zID0gIkVuYWJsZWQgZWFjaCAiICsgZ3NbIkRETlNQZXJpb2RpY1VwZGF0ZUludGVydmFsIl0gKyAiIG1pbnV0ZXMsIFRUTCBpcyAiICsgZ3NbIkRETlNUVEwiXSArICIgbWludXRlcyI7DQogICAgICAgICAgICB9IGVsc2UgaWYgKGdzWyJERE5TVXBkYXRlQnlESENQU2VydmVyRW5hYmxlZCJdID09IHRydWUpIHsNCiAgICAgICAgICAgICAgICBkZG5zID0gIlVwZGF0ZSBieSBESENQIHNlcnZlciI7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkR5bmFtaWMgRE5TIiwgYWRkTGlua0NvbmRpdGlvbmFsKGRkbnMsICdzaG93RWRpdERuc0RsZygpJywgeHhBY2NvdW50QWRtaW5OYW1lKSk7DQogICAgICAgICAgICB4ICs9IFRhYmxlRW5kKCk7DQoNCiAgICAgICAgICAgIGZvciAodmFyIHkgaW4gYW10c3lzc3RhdGVbJ0FNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyddLnJlc3BvbnNlcykgew0KICAgICAgICAgICAgICAgIHZhciB6ID0gYW10c3lzc3RhdGVbJ0FNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyddLnJlc3BvbnNlc1t5XTsNCiAgICAgICAgICAgICAgICBpZiAoelsnV0xBTkxpbmtQcm90ZWN0aW9uTGV2ZWwnXSB8fCAoeSA9PSAxKSkgeyBhbXR3aXJlbGVzc2lmID0geTsgfSAvLyBTZXQgdGhlIHdpcmVsZXNzIGludGVyZmFjZSwgdGhpcyBzZWVtcyB0byBjb3ZlciBuZXcgd2lyZWxlc3Mgb25seSBjb21wdXRlcnMgYW5kIG9sZGVyIGNvbXB1dGVycyB3aXRoIGR1YWwgaW50ZXJmYWNlcy4NCiAgICAgICAgICAgICAgICBpZiAoKHkgPT0gMCkgJiYgKGFtdHdpcmVsZXNzaWYgIT0geSkgJiYgKHpbIk1BQ0FkZHJlc3MiXSA9PSAiMDAtMDAtMDAtMDAtMDAtMDAiKSkgeyBjb250aW51ZTsgfSAvLyBPbiBjb21wdXRlcnMgd2l0aCBvbmx5IHdpcmVsZXNzLCB0aGUgd2lyZWQgaW50ZXJmYWNlIHdpbGwgaGF2ZSBhIG51bGwgTUFDLCBza2lwIGl0Lg0KICAgICAgICAgICAgICAgIGlmICh5ID09IDApIHN5c3RlbWRlZmVuc2UrKzsNCiAgICAgICAgICAgICAgICB4ICs9ICI8YnI+PGgyPiIgKyAoKGFtdHdpcmVsZXNzaWYgPT0geSk/J1dpcmVsZXNzJzonV2lyZWQnKSArICIgSW50ZXJmYWNlPC9oMj4iOw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVTdGFydCgpOw0KDQogICAgICAgICAgICAgICAgLyoNCiAgICAgICAgICAgICAgICB2YXIgbHAgPSBbXSwgbGlua3BvbGljeSA9IE1ha2VUb0FycmF5KHpbIkxpbmtQb2xpY3kiXSk7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBsaW5rcG9saWN5KSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBhcCA9IGxpbmtwb2xpY3lbcF07DQogICAgICAgICAgICAgICAgICAgIGlmIChhcCA9PSAxKSBscC5wdXNoKCJTMC9BQyIpOw0KICAgICAgICAgICAgICAgICAgICBpZiAoYXAgPT0gMTQpIGxwLnB1c2goIlN4L0FDIik7DQogICAgICAgICAgICAgICAgICAgIGlmIChhcCA9PSAxNikgbHAucHVzaCgiUzAvREMiKTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGFwID09IDIyNCkgbHAucHVzaCgiU3gvREMiKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJMaW5rIHN0YXRlIiwgKHpbIkxpbmtJc1VwIl0gPT0gdHJ1ZT8nTGluayBpcyB1cCc6J0xpbmsgaXMgZG93bicpICsgIiwgYXZhaWxhYmxlIGluICIgKyBscC5qb2luKCcsICcpKTsNCiAgICAgICAgICAgICAgICAqLw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiTGluayBzdGF0ZSIsICh6WyJMaW5rSXNVcCJdID09IHRydWU/J0xpbmsgaXMgdXAnOidMaW5rIGlzIGRvd24nKSk7DQogICAgICAgICAgICAgICAgaWYgKHpbIk1BQ0FkZHJlc3MiXSAhPSAiMDAtMDAtMDAtMDAtMDAtMDAiKSB7IHggKz0gVGFibGVFbnRyeSgiTUFDIGFkZHJlc3MiLCB6WyJNQUNBZGRyZXNzIl0pOyB9DQoNCg0KICAgICAgICAgICAgICAgIGlmICgoYW10d2lyZWxlc3NpZiA9PSB5KSAmJiB4eFdpcmVsZXNzICYmIHh4V2lyZWxlc3NbJ0NJTV9XaUZpUG9ydENhcGFiaWxpdGllcyddLnJlc3BvbnNlKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIFN0YXJ0IGFuZCBzdGF0ZQ0KICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIlN0YXRlIiwgYWRkTGlua0NvbmRpdGlvbmFsKHh4V2lmaVN0YXRlW3h4V2lyZWxlc3NbJ0NJTV9XaUZpUG9ydCddLnJlc3BvbnNlWyJFbmFibGVkU3RhdGUiXV0sICdzaG93V2lmaVN0YXRlRGxnKCknLCB4eEFjY291bnRBZG1pbk5hbWUpKTsNCiAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIC8qIFRoaXMgaXMgbm90IHRoYXQgdXNlZnVsDQogICAgICAgICAgICAgICAgICAgIC8vIENhcGFiaWxpdGllcw0KICAgICAgICAgICAgICAgICAgICB2YXIgcyA9ICcnLCBzYyA9IHh4V2lyZWxlc3NbJ0NJTV9XaUZpUG9ydENhcGFiaWxpdGllcyddLnJlc3BvbnNlLCBzdXBwb3J0ZWRUeXBlcyA9IHNjWyJTdXBwb3J0ZWRQb3J0VHlwZXMiXTsNCiAgICAgICAgICAgICAgICAgICAgZm9yIChpIGluIHN1cHBvcnRlZFR5cGVzKSB7IHMgKz0gIiwgODAyLjExIiArICJhYmduIltzdXBwb3J0ZWRUeXBlc1tpXSAtIDcwXTsgfQ0KICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkNhcGFiaWxpdGVzIiwgcy5zdWJzdHJpbmcoMikpOw0KICAgICAgICAgICAgICAgICAgICAqLw0KDQogICAgICAgICAgICAgICAgICAgIC8vIEN1cnJlbnQgcmFkaW8gc3RhdGUNCiAgICAgICAgICAgICAgICAgICAgcyA9IHh4V2lyZWxlc3NbJ0NJTV9XaUZpRW5kcG9pbnQnXS5yZXNwb25zZVsnTEFOSUQnXTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJSYWRpbyBTdGF0ZSIsIHh4UmFkaW9TdGF0ZVt4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50J10ucmVzcG9uc2VbJ0VuYWJsZWRTdGF0ZSddXSArICIsIFNTSUQ6ICIgKyAocz9zOiI8aT5Ob25lPC9pPiIpKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBpZiAoYW10d2lyZWxlc3NpZiAhPSB5KSB7DQogICAgICAgICAgICAgICAgICAgIC8vIFRoaW5ncyB0aGF0IGFyZSBzcGVjaWZpYyB0byB0aGUgd2lyZWQgaW50ZXJmYWNlDQogICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiUmVzcG9uZCB0byBwaW5nIiwgYWRkTGlua0NvbmRpdGlvbmFsKFsiRGlzYWJsZWQiLCJJQ01QIHJlc3BvbnNlIiwiUk1DUCByZXNwb25zZSIsIklDTVAgJiBSTUNQIHJlc3BvbnNlIl1bZ3NbIlBpbmdSZXNwb25zZUVuYWJsZWQiXSArIChnc1siUm1jcFBpbmdSZXNwb25zZUVuYWJsZWQiXSA8PCAxKV0sICJzaG93UGluZ0FjdGlvbkRsZygpIiwgeHhBY2NvdW50QWRtaW5OYW1lKSk7DQogICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NCBzdGF0ZSIsIGFkZExpbmtDb25kaXRpb25hbCh6WyJESENQRW5hYmxlZCJdID09IHRydWU/IkF1dG9tYXRpYyB1c2luZyBESENQIHNlcnZlciI6IlN0YXRpYyBJUCBhZGRyZXNzIiwgInNob3dJUFNldHVwRGxnKCkiLCB4eEFjY291bnRBZG1pbk5hbWUpKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAvLyBEaXNwbGF5IElQdjQgY3VycmVudCBzZXR0aW5ncw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NCBhZGRyZXNzIiwgaXNJcEFkZHJlc3MoelsiSVBBZGRyZXNzIl0sIk5vbmUiKSk7DQogICAgICAgICAgICAgICAgaWYgKGlzSXBBZGRyZXNzKHpbIkRlZmF1bHRHYXRld2F5Il0pKSB7IHggKz0gVGFibGVFbnRyeSgiSVB2NCBnYXRld2F5IC8gTWFzayIsIHpbIkRlZmF1bHRHYXRld2F5Il0gKyAiIC8gIiArIGlzSXBBZGRyZXNzKHpbIlN1Ym5ldE1hc2siXSwiTm9uZSIpKTsgfQ0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIHZhciBkbnMgPSB6WyJQcmltYXJ5RE5TIl07DQogICAgICAgICAgICAgICAgaWYgKGlzSXBBZGRyZXNzKGRucykpIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHpbIlNlY29uZGFyeUROUyJdKSBkbnMgKz0gIiAvICIgKyB6WyJTZWNvbmRhcnlETlMiXTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJJUHY0IGRvbWFpbiBuYW1lIHNlcnZlciIsIGRucyk7DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgaWYgKChhbXRzeXNzdGF0ZVsnSVBTX0lQdjZQb3J0U2V0dGluZ3MnXS5zdGF0dXMgPT0gMjAwKSAmJiAoYW10dmVyc2lvbiA+IDUpKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIElQdjYgaXMgZW5hYmxlZCBmb3IgdGhpcyBpbnRlcmZhY2UNCiAgICAgICAgICAgICAgICAgICAgdmFyIHp6ID0gYW10c3lzc3RhdGVbJ0lQU19JUHY2UG9ydFNldHRpbmdzJ10ucmVzcG9uc2VzW3ldOw0KICAgICAgICAgICAgICAgICAgICB2YXIgaXB2NnN0YXRlID0gJ0Rpc2FibGVkJywgaXB2NiwgaXB2Nm1hbnVhbCwgZWxlbWVudFNldHRpbmdzID0gYW10c3lzc3RhdGVbJ0NJTV9FbGVtZW50U2V0dGluZ0RhdGEnXS5yZXNwb25zZXM7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxlbWVudFNldHRpbmdzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudFNldHRpbmdzW2ldWydTZXR0aW5nRGF0YSddICYmIGVsZW1lbnRTZXR0aW5nc1tpXVsnU2V0dGluZ0RhdGEnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWydWYWx1ZSddID09ICdJbnRlbChyKSBJUFMgSVB2NiBTZXR0aW5ncyAnICsgeSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlwdjYgPSAoZWxlbWVudFNldHRpbmdzW2ldWydJc0N1cnJlbnQnXSA9PSAxKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIG1hbnVhbCBhZGRyZXNzZXMgaGF2ZSBiZWVuIGFkZGVkDQogICAgICAgICAgICAgICAgICAgIGlmIChpcHY2ID09IHRydWUpIHsgDQogICAgICAgICAgICAgICAgICAgICAgICBpcHY2bWFudWFsID0gaXNJcEFkZHJlc3MoenpbIklQdjZBZGRyZXNzIl0pIHx8IGlzSXBBZGRyZXNzKHp6WyJEZWZhdWx0Um91dGVyIl0pIHx8IGlzSXBBZGRyZXNzKHp6WyJQcmltYXJ5RE5TIl0pIHx8IGlzSXBBZGRyZXNzKHp6WyJTZWNvbmRhcnlETlMiXSk7DQogICAgICAgICAgICAgICAgICAgICAgICBpcHY2c3RhdGUgPSAnRW5hYmxlZCwgQXV0b21hdGljICcgKyAoaXB2Nm1hbnVhbD8iJiBtYW51YWwiOiIiKSArICIgYWRkcmVzc2VzIjsNCiAgICAgICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgICAgIC8vIERpc3BsYXkgSVB2NiBjdXJyZW50IHNldHRpbmdzDQogICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NiBzdGF0ZSIsIGFkZExpbmtDb25kaXRpb25hbChpcHY2c3RhdGUsICJzaG93SVB2NlN0YXRlRGxnKCIgKyB5ICsgIiwiICsgaXB2NiArICIpIiwgeHhBY2NvdW50QWRtaW5OYW1lKSk7DQogICAgICAgICAgICAgICAgICAgIGlmIChpcHY2ID09IHRydWUpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh6elsiQ3VycmVudEFkZHJlc3NJbmZvIl0gJiYgenpbIkN1cnJlbnRBZGRyZXNzSW5mbyJdLmxlbmd0aCA+IDApIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB6elsiQ3VycmVudEFkZHJlc3NJbmZvIl0gPSBNYWtlVG9BcnJheSh6elsiQ3VycmVudEFkZHJlc3NJbmZvIl0pOyAvLyBCZWNhdXNlIG91ciBXU01BTiBzdGFjayBkb2VzIG5vdCBrbm93IGlmIHRoaXMgaXMgYSBhcnJheSwgd2UgbmVlZCB0byBtYWtlIGl0IGFuIGFycmF5IGlmIGl0IGNvbnRhaW5zIDEgZWxlbWVudC4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcHY2YWRkciA9ICcnOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgenpbIkN1cnJlbnRBZGRyZXNzSW5mbyJdLmxlbmd0aDsgaSsrKSB7IGlmIChpcHY2YWRkci5sZW5ndGggPiAwKSBpcHY2YWRkciArPSAiLCAiOyBpcHY2YWRkciArPSB6elsiQ3VycmVudEFkZHJlc3NJbmZvIl1baV0uc3BsaXQoJywnKVswXTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NiBhZGRyZXNzIiwgYWRkTGluayhpcHY2YWRkciwgInNob3dJUHY2QWRkckRsZygiICsgeSArICIsXCIiICsgenpbIkN1cnJlbnRBZGRyZXNzSW5mbyJdICsgIlwiKSIpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJJUHY2IGFkZHJlc3MiLCAnTm9uZScpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzSXBBZGRyZXNzKHp6WyJDdXJyZW50RGVmYXVsdFJvdXRlciJdKSkgeyB4ICs9IFRhYmxlRW50cnkoIklQdjYgZGVmYXVsdCByb3V0ZXIiLCB6elsiQ3VycmVudERlZmF1bHRSb3V0ZXIiXSk7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0lwQWRkcmVzcyh6elsiQ3VycmVudFByaW1hcnlETlMiXSkpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZG5zID0genpbIkN1cnJlbnRQcmltYXJ5RE5TIl07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzSXBBZGRyZXNzKHp6WyJDdXJyZW50U2Vjb25kYXJ5RE5TIl0pKSBkbnMgKz0gIiAvICIgKyB6elsiQ3VycmVudFNlY29uZGFyeUROUyJdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NiBkb21haW4gbmFtZSBzZXJ2ZXIiLCBkbnMpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBPbmx5IGRvIG1vcmUgV1NNQU4gaWYgd2UgbmVlZCBpdA0KICAgICAgICAgICAgaWYgKCh1cmx2YXJzWydrdm1vbmx5J10gIT0gMSkgJiYgKGZ1bGxzY3JlZW5vbmx5ID09IGZhbHNlKSkgew0KDQogICAgICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgYSB3aXJlbGVzcyBpbnRlcmZhY2UsIGdldCB0aGUgZGF0YSBmb3IgaXQuIElmIG5vdCwgc2hvdyB0aGF0IHRoZXJlIGlzIG5vdC4NCiAgICAgICAgICAgICAgICBpZiAoYW10d2lyZWxlc3NpZiAhPSAtMSkgeyBpZiAoKGFtdEZpcnN0UHVsbCAmIDIpID09IDApIFB1bGxXaXJlbGVzcygpOyB9DQogICAgICAgICAgICAgICAgUUgoJ2lkX1RhYmxlTmV0d29ya1NldHRpbmdzU3BhbicsIHgpOw0KDQoNCiAgICAgICAgICAgICAgICAvLyBJZiBpbiBBQ00gbW9kZSBhbmQgd2UgaGF2ZSBhIHdpcmVkIGludGVyZmFjZSwgcHVsbCBTeXN0ZW0gRGVmZW5zZSBpbmZvcm1hdGlvbg0KICAgICAgICAgICAgICAgIGlmICgoc3lzdGVtZGVmZW5zZSA9PSAxKSAmJiAoKGFtdEZpcnN0UHVsbCAmIDQpID09IDApKSBQdWxsU3lzdGVtRGVmZW5zZSgpOw0KDQoNCiAgICAgICAgICAgICAgICBpZiAoKChhbXRGaXJzdFB1bGwgJiA4KSA9PSAwKSAmJiAoYW10dmVyc2lvbiA+IDExIHx8IChhbXR2ZXJzaW9uID09IDExICYmIGFtdHZlcnNpb25taW4gPiA1KSkpIHsgUHVsbFN0b3JhZ2UoKTsgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAoY3VycmVudFZpZXcgPT0gMCkgZ28oMSwgMSk7IC8vIElmIHdlIGFyZSBhdCB0aGUgbG9hZGluZyBzY3JlZW4sIG1vc3QgdG8gU3lzdGVtIFN0YXR1cyBzY3JlZW4NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGlzSXBBZGRyZXNzKHQsIHgpIHsgcmV0dXJuICh0ICYmIHQgIT0gbnVsbCAmJiB0Lmxlbmd0aCA+IDAgJiYgdCAhPSAnOjonICYmIHQgIT0gJzo6MCcpP3Q6eDsgfQ0KDQoNCiAgICAgICAgdmFyIEludGVsQW10RW50aXJlU3RhdGU7DQogICAgICAgIHZhciBJbnRlbEFtdEVudGlyZVN0YXRlQ2FsbHM7DQogICAgICAgIGZ1bmN0aW9uIHNhdmVFbnRpcmVBbXRTdGF0ZSgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBuID0gJycsIGQgPSBuZXcgRGF0ZSgpOw0KICAgICAgICAgICAgaWYgKGFtdHN5c3N0YXRlKSB7IG4gPSAiLSIgKyBhbXRzeXNzdGF0ZVsnQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlWydIb3N0TmFtZSddOyB9DQogICAgICAgICAgICBuICs9ICctJyArIGQuZ2V0RnVsbFllYXIoKSArICItIiArICgiMCIrKGQuZ2V0TW9udGgoKSsxKSkuc2xpY2UoLTIpICsgIi0iICsgKCIwIiArIGQuZ2V0RGF0ZSgpKS5zbGljZSgtMikgKyAiLSIgKyAoIjAiICsgZC5nZXRIb3VycygpKS5zbGljZSgtMikgKyAiLSIgKyAoIjAiICsgZC5nZXRNaW51dGVzKCkpLnNsaWNlKC0yKTs7DQogICAgICAgICAgICBpZHhfZDE5c2F2ZXN0YXRlZmlsZW5hbWUudmFsdWUgPSAnYW10c3RhdGUnICsgbiArICcuanNvbic7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDE5LCAiU2F2ZSBFbnRpcmUgSW50ZWwmcmVnOyBBTVQgU3RhdGUiLCAzLCBzYXZlRW50aXJlQW10U3RhdGVPayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzYXZlRW50aXJlQW10U3RhdGVPaygpIHsNCiAgICAgICAgICAgIEludGVsQW10RW50aXJlU3RhdGUgPSB7ICd3ZWJhcHB2ZXJzaW9uJzp2ZXJzaW9uLCdsb2NhbHRpbWUnOkRhdGUoKSwndXRjdGltZSc6bmV3IERhdGUoKS50b1VUQ1N0cmluZygpLCdpc290aW1lJzpuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkgfTsNCiAgICAgICAgICAgIFFIKCdpZF9kaWFsb2dNZXNzYWdlJywgJ0ZldGNoaW5nIGVudGlyZSBzdGF0ZSwgcGxlYXNlIHdhaXQuLi4nKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMSwgIlNhdmUgRW50aXJlIEludGVsJnJlZzsgQU1UIFN0YXRlIiwgMCwgbnVsbCk7DQoNCiAgICAgICAgICAgIC8vIEZldGNoIGV2ZXJ5dGhpbmchDQogICAgICAgICAgICBJbnRlbEFtdEVudGlyZVN0YXRlQ2FsbHMgPSAzOw0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKG51bGwsIEFsbFdzbWFuLCBzYXZlRW50aXJlQW10U3RhdGVPazIsIG51bGwsIHRydWUpOw0KICAgICAgICAgICAgYW10c3RhY2suR2V0QXVkaXRMb2coc2F2ZUVudGlyZUFtdFN0YXRlT2szKTsNCiAgICAgICAgICAgIGFtdHN0YWNrLkdldE1lc3NhZ2VMb2coc2F2ZUVudGlyZUFtdFN0YXRlT2s0KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNhdmVFbnRpcmVBbXRTdGF0ZU9rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsgSW50ZWxBbXRFbnRpcmVTdGF0ZVsnd3NtYW5lbnVtcyddID0gcmVzcG9uc2VzOyBzYXZlRW50aXJlQW10U3RhdGVEb25lKCk7IH0NCiAgICAgICAgZnVuY3Rpb24gc2F2ZUVudGlyZUFtdFN0YXRlT2szKHN0YWNrLCBtZXNzYWdlcykgeyBJbnRlbEFtdEVudGlyZVN0YXRlWydhdWRpdGxvZyddID0gbWVzc2FnZXM7IHNhdmVFbnRpcmVBbXRTdGF0ZURvbmUoKTsgfQ0KICAgICAgICBmdW5jdGlvbiBzYXZlRW50aXJlQW10U3RhdGVPazQoc3RhY2ssIG1lc3NhZ2VzKSB7IEludGVsQW10RW50aXJlU3RhdGVbJ2V2ZW50bG9nJ10gPSBtZXNzYWdlczsgc2F2ZUVudGlyZUFtdFN0YXRlRG9uZSgpOyB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2F2ZUVudGlyZUFtdFN0YXRlRG9uZSgpIHsNCiAgICAgICAgICAgIGlmICgtLUludGVsQW10RW50aXJlU3RhdGVDYWxscyAhPSAwKSByZXR1cm47DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKCk7DQoNCiAgICAgICAgICAgIHNhdmVBcyhkYXRhMmJsb2IoSlNPTi5zdHJpbmdpZnkoSW50ZWxBbXRFbnRpcmVTdGF0ZSwgbnVsbCwgJyAgJykucmVwbGFjZSgvXG4vZywgJ1xyXG4nKSksIGlkeF9kMTlzYXZlc3RhdGVmaWxlbmFtZS52YWx1ZSk7DQogICAgICAgIH0NCg0KDQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0Rlc2t0b3BTZXR0aW5nc0RsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBkZXNrdG9wU2V0dGluZ3MgPSBhbXRzeXNzdGF0ZVsnSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnXS5yZXNwb25zZTsNCiAgICAgICAgICAgIHZhciB4ID0gJzxkaXYgc3R5bGU9dGV4dC1hbGlnbjpsZWZ0Pic7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9c3ViZGRpc3BsYXkgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHg+PG9wdGlvbiB2YWx1ZT0wPlByaW1hcnkgZGlzcGxheTwvb3B0aW9uPjxvcHRpb24gdmFsdWU9MT5TZWNvbmRhcnkgZGlzcGxheTwvb3B0aW9uPiI7DQogICAgICAgICAgICBpZiAoYW10dmVyc2lvbiA+IDkpIHsgeCArPSAiPG9wdGlvbiB2YWx1ZT0yPjNyZCBkaXNwbGF5PC9vcHRpb24+IjsgfQ0KICAgICAgICAgICAgeCArPSAiPC9zZWxlY3Q+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+RGVmYXVsdCBkaXNwbGF5PC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPXN1YnNlc3Npb250aW1lb3V0IHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IG1heGxlbmd0aD01IG9ua2V5cHJlc3M9J3JldHVybiBudW1iZXJzT25seShldmVudCknPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PlNlc3Npb24gdGltZW91dCAoTWludXRlcyk8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgaWYgKGRlc2t0b3BTZXR0aW5nc1snT3B0SW5Qb2xpY3knXSA9PSB0cnVlKSB7IHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPXN1Ym9wdGludGltZW91dCBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBtYXhsZW5ndGg9NSBvbmtleXByZXNzPSdyZXR1cm4gbnVtYmVyc09ubHkoZXZlbnQpJz48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5PcHQtaW4gdGltZW91dCAoU2Vjb25kcyk8L2Rpdj48L2Rpdj4iOyB9DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9c3ViZGxlZ2FjeSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBvbmNoYW5nZT1zaG93RGVza3RvcFNldHRpbmdzRGxnVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0wPkRpc2FibGVkLCBSZWNvbW1lbmRlZDwvb3B0aW9uPjxvcHRpb24gdmFsdWU9MT5FbmFibGVkLCBMZWdhY3kgS1ZNIHZpZXdlcnM8L29wdGlvbj48L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5Qb3J0IDU5MDA8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweCBpZD1zdWJzcGFzc3g+PGlucHV0IGlkPXN1YnNwYXNzIHR5cGU9cGFzc3dvcmQgYXV0b2NvbXBsZXRlPW9mZiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBtYXhsZW5ndGg9OCBvbmtleXVwPXNob3dEZXNrdG9wU2V0dGluZ3NEbGdVcGRhdGUoKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD41OTAwIHBhc3N3b3JkICg4IGNoYXJzKTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICBpZiAoKGFtdHZlcnNpb24gPiA5KSAmJiAoYW10c3lzc3RhdGVbJ0lQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSddICE9IG51bGwpKSB7IHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PHNlbGVjdCBpZD1zdWJzYiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBvbmNoYW5nZT1zaG93RGVza3RvcFNldHRpbmdzRGxnVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0wPkRpc2FibGVkPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT0xPkVuYWJsZWQ8L29wdGlvbj48L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweCB0aXRsZT0nVGhpcyBmZWF0dXJlIGlzIG5vdCBvZnRlbiBzdXBwb3J0ZWQnPlNjcmVlbiBCbGFua2luZzwvZGl2PjwvZGl2PiI7IH0NCiAgICAgICAgICAgIHggKz0gIjwvZGl2PiI7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiUmVtb3RlIERlc2t0b3AgU2V0dGluZ3MiLCAzLCBzaG93RGVza3RvcFNldHRpbmdzRGxnT2ssIHgpOw0KICAgICAgICAgICAgUSgnc3ViZGRpc3BsYXknKS52YWx1ZSA9IGRlc2t0b3BTZXR0aW5nc1snRGVmYXVsdFNjcmVlbiddOw0KICAgICAgICAgICAgUSgnc3Vic2Vzc2lvbnRpbWVvdXQnKS52YWx1ZSA9IGRlc2t0b3BTZXR0aW5nc1snU2Vzc2lvblRpbWVvdXQnXTsNCiAgICAgICAgICAgIGlmIChkZXNrdG9wU2V0dGluZ3NbJ09wdEluUG9saWN5J10gPT0gdHJ1ZSkgeyBRKCdzdWJvcHRpbnRpbWVvdXQnKS52YWx1ZSA9IGRlc2t0b3BTZXR0aW5nc1snT3B0SW5Qb2xpY3lUaW1lb3V0J107IH0NCiAgICAgICAgICAgIFEoJ3N1YmRsZWdhY3knKS52YWx1ZSA9ICgoZGVza3RvcFNldHRpbmdzWydJczU5MDBQb3J0RW5hYmxlZCddID09IHRydWUpID8gMSA6IDApOw0KICAgICAgICAgICAgaWYgKChhbXR2ZXJzaW9uID4gOSkgJiYgKGFtdHN5c3N0YXRlWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXSAhPSBudWxsKSkgeyBRKCdzdWJzYicpLnZhbHVlID0gYW10c3lzc3RhdGVbJ0lQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSddLnJlc3BvbnNlWyJFbmFibGVkU3RhdGUiXTsgfQ0KICAgICAgICAgICAgc2hvd0Rlc2t0b3BTZXR0aW5nc0RsZ1VwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0Rlc2t0b3BTZXR0aW5nc0RsZ1VwZGF0ZSgpIHsNCiAgICAgICAgICAgIFFWKCdzdWJzcGFzc3gnLCAoUSgnc3ViZGxlZ2FjeScpLnZhbHVlID09IDEpKTsNCiAgICAgICAgICAgIHZhciBvayA9ICgoUSgnc3ViZGxlZ2FjeScpLnZhbHVlID09IDApIHx8IChRKCdzdWJzcGFzcycpLnZhbHVlLmxlbmd0aCA9PSA4KSB8fCAoUSgnc3Vic3Bhc3MnKS52YWx1ZS5sZW5ndGggPT0gMCkpICYmIChRKCdzdWJzZXNzaW9udGltZW91dCcpLnZhbHVlLmxlbmd0aCA+IDApOw0KICAgICAgICAgICAgaWYgKChhbXRzeXNzdGF0ZVsnSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnXS5yZXNwb25zZVsnT3B0SW5Qb2xpY3knXSA9PSB0cnVlKSAmJiAoUSgnc3Vib3B0aW50aW1lb3V0JykudmFsdWUubGVuZ3RoID09IDApKSB7IG9rID0gZmFsc2U7IH0NCiAgICAgICAgICAgIFFFKCdpZHhfZGxnT2tCdXR0b24nLCBvayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93RGVza3RvcFNldHRpbmdzRGxnT2soKSB7DQogICAgICAgICAgICB2YXIgeCA9IENsb25lKGFtdHN5c3N0YXRlWydJUFNfS1ZNUmVkaXJlY3Rpb25TZXR0aW5nRGF0YSddLnJlc3BvbnNlKTsNCiAgICAgICAgICAgIHhbJ0RlZmF1bHRTY3JlZW4nXSA9IFEoJ3N1YmRkaXNwbGF5JykudmFsdWUNCiAgICAgICAgICAgIHhbJ1Nlc3Npb25UaW1lb3V0J10gPSBRKCdzdWJzZXNzaW9udGltZW91dCcpLnZhbHVlOw0KICAgICAgICAgICAgeFsnSXM1OTAwUG9ydEVuYWJsZWQnXSA9IChRKCdzdWJkbGVnYWN5JykudmFsdWUgPT0gMSk7DQogICAgICAgICAgICBpZiAoeFsnT3B0SW5Qb2xpY3knXSA9PSB0cnVlKSB7IHhbJ09wdEluUG9saWN5VGltZW91dCddID0gUSgnc3Vib3B0aW50aW1lb3V0JykudmFsdWU7IH0NCiAgICAgICAgICAgIGlmICh4WydJczU5MDBQb3J0RW5hYmxlZCddID09IHRydWUpIHsgeFsnUkZCUGFzc3dvcmQnXSA9IFEoJ3N1YnNwYXNzJykudmFsdWU7IH0NCiAgICAgICAgICAgIGFtdHN0YWNrLlB1dCgnSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnLCB4LCBzaG93RGVza3RvcFNldHRpbmdzRGxnT2syKTsNCg0KICAgICAgICAgICAgLy8gU2NyZWVuIGJsYW5raW5nDQogICAgICAgICAgICB2YXIgeSA9IENsb25lKGFtdHN5c3N0YXRlWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXS5yZXNwb25zZSk7DQogICAgICAgICAgICB5WydFbmFibGVkU3RhdGUnXSA9IHBhcnNlSW50KFEoJ3N1YnNiJykudmFsdWUpOw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnLCB5LCBzaG93RGVza3RvcFNldHRpbmdzRGxnT2szKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dEZXNrdG9wU2V0dGluZ3NEbGdPazIoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgUHVsbFN5c3RlbVN0YXR1cygpOyBlbHNlIG1lc3NhZ2Vib3goIlJlbW90ZSBEZXNrdG9wIFNldHRpbmdzIiwgIkVycm9yICIgKyBzdGF0dXMgKyAiLCB1bmFibGUgdG8gc2V0IHZhbHVlcy4iKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dEZXNrdG9wU2V0dGluZ3NEbGdPazMoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goIkVycm9yIiwgIlNjcmVlbiBCbGFua2luZyBjb3VsZCBub3QgYmUgc2V0LCBibGFua2luZyBtYXkgbm90IGJlIHN1cHBvcnRlZCBvbiB0aGlzIHN5c3RlbSAoIiArIHN0YXR1cyArICIpLiIpOyByZXR1cm47IH0NCiAgICAgICAgICAgIGFtdHN0YWNrLkdldCgiSVBTX1NjcmVlbkNvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgZnVuY3Rpb24gKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgYW10c3lzc3RhdGVbJ0lQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSddLnJlc3BvbnNlID0gcmVzcG9uc2UuQm9keTsgdXBkYXRlU3lzdGVtU3RhdHVzKCk7IH0NCiAgICAgICAgICAgIH0sIDAsIDEpOw0KICAgICAgICB9DQoNCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gRVZFTlQgTE9HIFBBTkVMDQogICAgICAgIC8vDQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbEV2ZW50TG9nKGJ1dHRvbikgew0KICAgICAgICAgICAgaWYgKGJ1dHRvbiA9PSAxICYmIHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgYW10Rmlyc3RQdWxsIHw9IDE2Ow0KICAgICAgICAgICAgYW10c3RhY2suRW51bSgiQU1UX01lc3NhZ2VMb2ciLCBwcm9jZXNzTWVzc2FnZUxvZzApOw0KICAgICAgICAgICAgYW10c3RhY2suR2V0TWVzc2FnZUxvZyhwcm9jZXNzTWVzc2FnZUxvZzEpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIHByb2Nlc3NNZXNzYWdlTG9nMHJlc3BvbnNlcyA9IG51bGw7DQogICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NNZXNzYWdlTG9nMChzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSByZXR1cm47DQogICAgICAgICAgICBpZiAoc3RhdHVzKSBRVignZ282JywgdHJ1ZSk7IC8vIFNob3cgZXZlbnQgbG9nIGxlZnQgcGFuZWwgb3B0aW9uDQogICAgICAgICAgICBpZiAocmVzcG9uc2VzKSBwcm9jZXNzTWVzc2FnZUxvZzByZXNwb25zZXMgPSByZXNwb25zZXM7DQogICAgICAgICAgICB2YXIgZnIgPSAnJywgeCA9ICI8dGFibGUgY2xhc3M9bG9nMSBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjhweD4iOw0KICAgICAgICAgICAgaWYgKHByb2Nlc3NNZXNzYWdlTG9nMHJlc3BvbnNlcyAhPSBudWxsKSB7IGZyID0gKChwcm9jZXNzTWVzc2FnZUxvZzByZXNwb25zZXNbMF1bIklzRnJvemVuIl0gPT0gdHJ1ZSkgPyBBZGRCdXR0b24oIlVuLWZyZWV6ZSBMb2ciLCAiRnJlZXplTG9nKDApIikgOiBBZGRCdXR0b24oIkZyZWV6ZSBMb2ciLCAiRnJlZXplTG9nKDEpIikpOyB9DQoNCg0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgiPGRpdiBzdHlsZT1mbG9hdDpyaWdodD48aW5wdXQgaWQ9ZXZlbnRGaWx0ZXIgcGxhY2Vob2xkZXI9RmlsdGVyIHN0eWxlPW1hcmdpbjo0cHggb25rZXl1cD1ldmVudEZpbHRlcigpPiZuYnNwOzwvZGl2PjxkaXY+Jm5ic3A7IiArIEFkZFJlZnJlc2hCdXR0b24oIlB1bGxFdmVudExvZygxKSIpICsgQWRkQnV0dG9uKCJDbGVhciBMb2ciLCAiQ2xlYXJMb2coKSIpICsgQWRkQnV0dG9uKCJTYXZlLi4uIiwgIlNhdmVFdmVudExvZygpIikgKyBmcik7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVFdmVudExvZycsIHggKyAnPGJyPicpOw0KICAgICAgICB9DQoNCg0KICAgICAgICBmdW5jdGlvbiBTYXZlRXZlbnRMb2coKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8IGV2ZW50bWVzc2FnZXMgPT0gbnVsbCkgcmV0dXJuOw0KICAgICAgICAgICAgU2F2ZUpzb25GaWxlKCdJbnRlbEFtdEV2ZW50bG9nJywgJ2V2ZW50cycsICdJbnRlbCBBTVQgRXZlbnQgTG9nJywgZXZlbnRtZXNzYWdlcyk7DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgZXZlbnRtZXNzYWdlcyA9IG51bGw7DQogICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NNZXNzYWdlTG9nMShzdGFjaywgbWVzc2FnZXMpIHsNCiAgICAgICAgICAgIGV2ZW50bWVzc2FnZXMgPSBtZXNzYWdlczsNCiAgICAgICAgICAgIHZhciBpLCB5ID0gMCwgeCA9ICI8dGFibGUgY2xhc3M9bG9nMSBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjhweD48dHI+PHRkIHdpZHRoPTgwcHg+PHA+PHRkPjx0ZD48dGQ+IjsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6OTBweD48Yj4mbmJzcDsmbmJzcDtFdmVudDwvYj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6MTEwcHg+PGI+VGltZTwvYj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6MTYwcHg+PGI+U291cmNlPC9iPjx0ZCBjbGFzcz1yMT48Yj5EZXNjcmlwdGlvbjwvYj4iOw0KICAgICAgICAgICAgZm9yIChpIGluIG1lc3NhZ2VzKSB7DQogICAgICAgICAgICAgICAgeSsrOw0KICAgICAgICAgICAgICAgIHZhciBpY29uID0gMSwgbSA9IG1lc3NhZ2VzW2ldOw0KICAgICAgICAgICAgICAgIGlmIChtWydFdmVudFNldmVyaXR5J10gPj0gOCkgeyBpY29uID0gMjsgfSBpZiAobVsnRXZlbnRTZXZlcml0eSddID49IDE2KSB7IGljb24gPSAzOyB9DQogICAgICAgICAgICAgICAgeCArPSAiPHRyIGlkPXhhbXRldmVudCIgKyBpICsgIiBjbGFzcz1yMyBvbmNsaWNrPXNob3dFdmVudERldGFpbHMoIiArIGkgKyAiKT48dGQgY2xhc3M9cjE+PHA+PGRpdiBjbGFzcz1pY29uIiArIGljb24gKyAiIHN0eWxlPWRpc3BsYXk6YmxvY2s7ZmxvYXQ6bGVmdDttYXJnaW4tbGVmdDo1cHg7bWFyZ2luLXJpZ2h0OjVweD48L2Rpdj4iICsgKHBhcnNlSW50KGkpICsgMSkgKyAiPHRkIGNsYXNzPXIxIHRpdGxlPSciICsgbVsnVGltZSddLnRvTG9jYWxlU3RyaW5nKCkgKyAiJz4iICsgbVsnVGltZSddLnRvTG9jYWxlRGF0ZVN0cmluZygnZW4nLCB7IHllYXI6ICJudW1lcmljIiwgbW9udGg6ICIyLWRpZ2l0IiwgZGF5OiAibnVtZXJpYyIgfSkgKyAiPGJyPiIgKyBtWydUaW1lJ10udG9Mb2NhbGVUaW1lU3RyaW5nKCdlbicsIHsgaG91cjoiMi1kaWdpdCIsIG1pbnV0ZToiMi1kaWdpdCIsIHNlY29uZDoiMi1kaWdpdCIgfSkgKyAiPHRkIGNsYXNzPXIxPiIgKyBtWydFbnRpdHlTdHInXS5yZXBsYWNlKCIocikiLCAiJnJlZzsiKSArICI8dGQgY2xhc3M9cjE+IiArIG1bJ0Rlc2MnXTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoeSA9PSAwID8gIiZuYnNwOyIgOiAiIik7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVFdmVudExvZzInLCB4ICsgJzxicj4nKTsNCiAgICAgICAgICAgIHByb2Nlc3NNZXNzYWdlTG9nMCgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gRnJlZXplTG9nKHgpIHsgaWYgKCF4eGRpYWxvZ01vZGUpIHsgYW10c3RhY2suQU1UX01lc3NhZ2VMb2dfRnJlZXplTG9nKHgsIGZ1bmN0aW9uICgpIHsgYW10c3RhY2suRW51bSgiQU1UX01lc3NhZ2VMb2ciLCBwcm9jZXNzTWVzc2FnZUxvZzApOyB9KSB9IH0NCiAgICAgICAgZnVuY3Rpb24gQ2xlYXJMb2coeCkgeyBpZiAoIXh4ZGlhbG9nTW9kZSkgeyBRSCgnaWRfZGlhbG9nTWVzc2FnZScsICdDbGVhciBldmVudCBsb2c/Jyk7IHNldERpYWxvZ01vZGUoMSwgIkV2ZW50IExvZyIsIDMsIENsZWFyTG9nRXgpOyB9IH0NCiAgICAgICAgZnVuY3Rpb24gQ2xlYXJMb2dFeCgpIHsgYW10c3RhY2suQU1UX01lc3NhZ2VMb2dfQ2xlYXJMb2coZnVuY3Rpb24gKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgeyBpZiAoc3RhdHVzICE9IDIwMCkgbWVzc2FnZWJveCgiRXZlbnQgTG9nIiwgIlVuYWJsZSB0byBjbGVhciwgRXJyb3I6ICIgKyBzdGF0dXMpOyBlbHNlIFB1bGxFdmVudExvZygpOyB9KSB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0V2ZW50RGV0YWlscyhoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgbSA9IGV2ZW50bWVzc2FnZXNbaF07DQogICAgICAgICAgICB2YXIgeCA9ICc8ZGl2IHN0eWxlPXRleHQtYWxpZ246bGVmdD4nOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlRpbWUiLCBtWydUaW1lJ10udG9Mb2NhbGVTdHJpbmcoKSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU291cmNlIiwgbVsnRW50aXR5U3RyJ10ucmVwbGFjZSgiKHIpIiwgIiZyZWc7IikpOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkRlc2NyaXB0aW9uIiwgbVsnRGVzYyddKTsNCiAgICAgICAgICAgIHggKz0gTW9yZVN0YXJ0KCk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiRGV2aWNlIEFkZHJlc3MiLCBtWydEZXZpY2VBZGRyZXNzJ10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkVudGl0eSIsIG1bJ0VudGl0eSddKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJFbnRpdHkgSW5zdGFuY2UiLCBtWydFbnRpdHlJbnN0YW5jZSddKTsNCiAgICAgICAgICAgIHZhciBlID0gJyc7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIG1bJ0V2ZW50RGF0YSddKSB7IGlmIChlLmxlbmd0aCA+IDApIGUgKz0nLCc7IGUgKz0gbVsnRXZlbnREYXRhJ11baV07IH0NCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJEYXRhIiwgZSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiT2Zmc2V0IiwgbVsnRXZlbnRPZmZzZXQnXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU2Vuc29yIFR5cGUiLCBtWydFdmVudFNlbnNvclR5cGUnXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU2V2ZXJpdHkiLCBtWydFdmVudFNldmVyaXR5J10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlNvdXJjZSBUeXBlIiwgbVsnRXZlbnRTb3VyY2VUeXBlJ10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlR5cGUiLCBtWydFdmVudFR5cGUnXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU2Vuc29yIE51bWJlciIsIG1bJ1NlbnNvck51bWJlciddKTsNCiAgICAgICAgICAgIHggKz0gTW9yZUVuZCgpOw0KICAgICAgICAgICAgeCArPSAiPC9kaXY+IjsNCiAgICAgICAgICAgIG1lc3NhZ2Vib3goIkV2ZW50ICMiICsgKGggKyAxKSArICIgRGV0YWlscyIsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZXZlbnRGaWx0ZXIoKSB7DQogICAgICAgICAgICB2YXIgZmlsdGVyID0gUSgnZXZlbnRGaWx0ZXInKS52YWx1ZS50b0xvd2VyQ2FzZSgpOw0KICAgICAgICAgICAgZm9yICh2YXIgdyBpbiBldmVudG1lc3NhZ2VzKSB7IFFWKCd4YW10ZXZlbnQnICsgdywgZmlsdGVyID09ICcnIHx8IGV2ZW50bWVzc2FnZXNbd11bJ0Rlc2MnXS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoZmlsdGVyKSA+PSAwIHx8IGV2ZW50bWVzc2FnZXNbd11bJ0VudGl0eVN0ciddLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihmaWx0ZXIpID49IDApOyB9DQogICAgICAgIH0NCg0KDQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEFVRElUIExPRyBQQU5FTA0KICAgICAgICAvLw0KDQogICAgICAgIGZ1bmN0aW9uIFB1bGxBdWRpdExvZyhidXR0b24pIHsNCiAgICAgICAgICAgIGlmIChidXR0b24gPT0gMSAmJiB4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIGFtdEZpcnN0UHVsbCB8PSAzMjsNCiAgICAgICAgICAgIGFtdHN0YWNrLkVudW0oIkFNVF9BdWRpdExvZyIsIHByb2Nlc3NBdWRpdExvZzApOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGF1ZGl0TG9nID0gbnVsbDsNCiAgICAgICAgdmFyIGF1ZGl0TG9nRW5hYmxlZFN0YXRlcyA9IFsiVW5rbm93biIsICJPdGhlciIsICJFbmFibGVkIiwgIkRpc2FibGVkIiwgIlNodXR0aW5nIERvd24iLCAiTm90IEFwcGxpY2FibGUiLCAiRW5hYmxlZCBidXQgT2ZmbGluZSIsICJJbiBUZXN0IiwgIkRlZmVycmVkIiwgIlF1aWVzY2UiLCAiU3RhcnRpbmciXTsNCg0KICAgICAgICBmdW5jdGlvbiBwcm9jZXNzQXVkaXRMb2cwKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsNCiAgICAgICAgICAgICAgICBRVignZ28xNScsIHRydWUpOyAvLyBTaG93IGF1ZGl0IGxvZyBsZWZ0IHBhbmVsIG9wdGlvbg0KDQogICAgICAgICAgICAgICAgdmFyIHIgPSByZXNwb25zZXNbMF1bIkF1ZGl0U3RhdGUiXTsNCiAgICAgICAgICAgICAgICB2YXIgYXVkaXRzdGF0ZSA9IChyICYgMHgwMSkgPyAnRGlzYWJsZWQnIDogJ0VuYWJsZWQnOw0KICAgICAgICAgICAgICAgIGlmIChyICYgMHgwMikgYXVkaXRzdGF0ZSArPSAiLCBMb2NrZWQiOw0KICAgICAgICAgICAgICAgIGlmIChyICYgMHgwNCkgYXVkaXRzdGF0ZSArPSAiLCBBbG1vc3QgRnVsbCI7DQogICAgICAgICAgICAgICAgaWYgKHIgJiAweDA4KSBhdWRpdHN0YXRlICs9ICIsIEZ1bGwiOw0KICAgICAgICAgICAgICAgIGlmIChyICYgMHgxMCkgYXVkaXRzdGF0ZSArPSAiLCBOb0tleSI7DQoNCiAgICAgICAgICAgICAgICB2YXIgeCA9ICI8aDE+QXVkaXQgTG9nIFNldHRpbmdzPC9oMT4iICsgVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiU3RhdGUiLCBhdWRpdHN0YXRlKTsNCiAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIlN0b3JhZ2UiLCByZXNwb25zZXNbMF1bIkN1cnJlbnROdW1iZXJPZlJlY29yZHMiXSArICIgcmVjb3JkKHMpLCAiICsgcmVzcG9uc2VzWzBdWyJQZXJjZW50YWdlRnJlZSJdICsgIiUgZnJlZSIpOw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiT3ZlcndyaXRlIHBvbGljeSIsICgocmVzcG9uc2VzWzBdWyJPdmVyd3JpdGVQb2xpY3kiXSA9PSAyKSA/ICJXcmFwcyB3aGVuIGZ1bGwiIDogIk5ldmVyIG92ZXJ3cml0ZXMiKSk7DQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgICAgIFFIKCdpZF9UYWJsZUF1ZGl0TG9nMScsIHgpOw0KDQogICAgICAgICAgICAgICAgYW10c3RhY2suR2V0QXVkaXRMb2cocHJvY2Vzc0F1ZGl0TG9nMSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBwcm9jZXNzQXVkaXRMb2cxKHN0YWNrLCBtZXNzYWdlcykgew0KICAgICAgICAgICAgYXVkaXRMb2cgPSBtZXNzYWdlczsNCiAgICAgICAgICAgIHZhciBpLCB4ID0gIjx0YWJsZSBjbGFzcz1sb2cxIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6OHB4PiI7DQoNCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoIjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ+PGlucHV0IGlkPWF1ZGl0RmlsdGVyIHBsYWNlaG9sZGVyPUZpbHRlciBzdHlsZT1tYXJnaW46NHB4IG9ua2V5dXA9YXVkaXRGaWx0ZXIoKT4mbmJzcDs8L2Rpdj48ZGl2PiAiICsgQWRkUmVmcmVzaEJ1dHRvbigiUHVsbEF1ZGl0TG9nKDEpIikgKyBBZGRCdXR0b24oIlNhdmUuLi4iLCAiU2F2ZUF1ZGl0TG9nKCkiKSArIEFkZEJ1dHRvbigiQ2xlYXIgTG9nIiwgIkNsZWFyQXVkaXRMb2coKSIpIC8qICsgQWRkQnV0dG9uKCJTZXR0aW5ncy4uLiIsICJTaG93QXVkaXRMb2dTZXR0aW5ncygpIikqLykgKyAiPGJyPiI7DQogICAgICAgICAgICBpZiAobWVzc2FnZXMubGVuZ3RoID09IDApIHsNCiAgICAgICAgICAgICAgICB4ID0gIk5vIGF1ZGl0IGxvZyBldmVudHMgZm91bmQuIjsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgdmFyIHkgPSAwOw0KICAgICAgICAgICAgICAgIHggKz0gIjx0YWJsZSBjbGFzcz1sb2cxIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6OHB4Pjx0cj48dGQgd2lkdGg9ODBweD48cD48dGQ+PHRkPjx0ZD4iOw0KICAgICAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6MTEwcHg+Jm5ic3A7Jm5ic3A7PGI+VGltZTwvYj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6MjYwcHg+PGI+SW5pdGlhdG9yPC9iPjx0ZCBjbGFzcz1yMT48Yj5BY3Rpb248L2I+IjsNCiAgICAgICAgICAgICAgICBmb3IgKGkgaW4gbWVzc2FnZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIG0gPSBtZXNzYWdlc1tpXSwgZGVzY3JpcHRpb24gPSBtWydBdWRpdEFwcCddLCBpbml0aWF0b3IgPSBtWydJbml0aWF0b3InXTsNCiAgICAgICAgICAgICAgICAgICAgeSsrOw0KICAgICAgICAgICAgICAgICAgICB2YXIgYWRkciA9ICcnOw0KICAgICAgICAgICAgICAgICAgICBpZiAobVsnTmV0QWRkcmVzcyddLmxlbmd0aCA+IDApIGFkZHIgPSBtWydOZXRBZGRyZXNzJ10ucmVwbGFjZSgnMDAwMDowMDAwOjAwMDA6MDAwMDowMDAwOjAwMDA6MDAwMDowMDAxJywnOjoxJyk7DQogICAgICAgICAgICAgICAgICAgIGlmIChtWydFdmVudCddKSBkZXNjcmlwdGlvbiArPSAiLCAiICsgbVsnRXZlbnQnXTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKG1bJ0V4U3RyJ10gIT0gbnVsbCkgZGVzY3JpcHRpb24gKz0gIiwgIiArIG1bJ0V4U3RyJ107DQogICAgICAgICAgICAgICAgICAgIGlmIChpbml0aWF0b3IgIT0gJycgJiYgYWRkciAhPSAnJykgaW5pdGlhdG9yICs9ICIsICI7DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjx0ciBpZD14YW10YXVkaXQiICsgaSArICIgY2xhc3M9cjMgb25jbGljaz1zaG93QXVkaXREZXRhaWxzKCIgKyBpICsgIik+PHRkIGNsYXNzPXIxIHRpdGxlPSciICsgbVsnVGltZSddLnRvTG9jYWxlU3RyaW5nKCkgKyAiJz4mbmJzcDsmbmJzcDsiICsgbVsnVGltZSddLnRvTG9jYWxlRGF0ZVN0cmluZygnZW4nLCB7IHllYXI6ICJudW1lcmljIiwgbW9udGg6ICIyLWRpZ2l0IiwgZGF5OiAibnVtZXJpYyIgfSkgKyAiPGJyPiZuYnNwOyZuYnNwOyIgKyBtWydUaW1lJ10udG9Mb2NhbGVUaW1lU3RyaW5nKCdlbicsIHsgaG91cjoiMi1kaWdpdCIsIG1pbnV0ZToiMi1kaWdpdCIsIHNlY29uZDoiMi1kaWdpdCIgfSkgKyAiPHRkIGNsYXNzPXIxPiIgKyBpbml0aWF0b3IgKyBhZGRyICsgIjx0ZCBjbGFzcz1yMT4iICsgZGVzY3JpcHRpb247DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbmQoeSA9PSAwID8gIiZuYnNwOyIgOiAiIikgKyAiPGJyPiI7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBRSCgnaWRfVGFibGVBdWRpdExvZzInLCB4KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGF1ZGl0RmlsdGVyKCkgew0KICAgICAgICAgICAgdmFyIGZpbHRlciA9IFEoJ2F1ZGl0RmlsdGVyJykudmFsdWUudG9Mb3dlckNhc2UoKTsNCiAgICAgICAgICAgIGZvciAodmFyIHcgaW4gYXVkaXRMb2cpIHsgUVYoJ3hhbXRhdWRpdCcgKyB3LCBmaWx0ZXIgPT0gJycgfHwgSlNPTi5zdHJpbmdpZnkoYXVkaXRMb2dbd10pLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihmaWx0ZXIpID49IDApOyB9DQogICAgICAgIH0NCg0KDQogICAgICAgIGZ1bmN0aW9uIFNhdmVBdWRpdExvZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgYXVkaXRMb2cgPT0gbnVsbCkgcmV0dXJuOw0KICAgICAgICAgICAgU2F2ZUpzb25GaWxlKCdJbnRlbEFtdEF1ZGl0bG9nJywgJ2F1ZGl0ZXZlbnRzJywgJ0ludGVsIEFNVCBBdWRpdCBMb2cnLCBhdWRpdExvZyk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBDbGVhckF1ZGl0TG9nKHgpIHsgUUgoJ2lkX2RpYWxvZ01lc3NhZ2UnLCAnQ2xlYXIgYXVkaXQgbG9nPycpOyBzZXREaWFsb2dNb2RlKDEsICJBdWRpdCBMb2ciLCAzLCBDbGVhckF1ZGl0TG9nRXgpOyB9DQogICAgICAgIGZ1bmN0aW9uIENsZWFyQXVkaXRMb2dFeCgpIHsNCiAgICAgICAgICAgIC8vYW10c3RhY2suQU1UX0F1ZGl0TG9nX0NsZWFyTG9nKGZ1bmN0aW9uICgpIHsgUHVsbEF1ZGl0TG9nKCk7IH0pDQogICAgICAgICAgICB2YXIgaGFuZGxlID0gYW10c3RhY2suQU1UX0F1ZGl0TG9nX1NldEF1ZGl0TG9jaygxLDAsIGhhbmRsZSwgZnVuY3Rpb24oKSB7IGFtdHN0YWNrLkFNVF9BdWRpdExvZ19DbGVhckxvZyhmdW5jdGlvbiAoKSB7IGFtdHN0YWNrLkFNVF9BdWRpdExvZ19TZXRBdWRpdExvY2soMCwgMiwgaGFuZGxlLCBmdW5jdGlvbiAoKSB7IHNldFRpbWVvdXQoUHVsbEF1ZGl0TG9nLDEwMDApO30pOyB9KTsgfSk7ICAgICAgICAgDQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBTaG93QXVkaXRMb2dTZXR0aW5ncygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9BdWRpdExvZ19SZXF1ZXN0U3RhdGVDaGFuZ2UoMiwgMCwgQXVkaXRMb2dTZXR0aW5nc0NvbXBsZXRlZCk7IC8vIEVuYWJsZQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQXVkaXRMb2dTZXR0aW5nc0NvbXBsZXRlZChzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSBQdWxsQXVkaXRMb2coKTsgZWxzZSBtZXNzYWdlYm94KCJBdWRpdCBMb2ciLCAiRXJyb3I6ICIgKyBzdGF0dXMpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0F1ZGl0RGV0YWlscyhoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgaSwgbSA9IGF1ZGl0TG9nW2hdLCB4ID0gJzxkaXYgc3R5bGU9dGV4dC1hbGlnbjpsZWZ0Pic7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiVGltZSIsIG1bJ1RpbWUnXS50b0xvY2FsZVN0cmluZygpKTsNCiAgICAgICAgICAgIGlmIChtWydJbml0aWF0b3InXSAhPSAnJykgeCArPSBhZGRIdG1sVmFsdWUoIkluaXRpYXRvciIsIG1bJ0luaXRpYXRvciddKTsNCiAgICAgICAgICAgIGlmIChtWydOZXRBZGRyZXNzJ10gIT0gJycpIHggKz0gYWRkSHRtbFZhbHVlKCJBZGRyZXNzIiwgbVsnTmV0QWRkcmVzcyddKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJBcHBsaWNhdGlvbiIsIG1bJ0F1ZGl0QXBwJ10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkV2ZW50IiwgbVsnRXZlbnQnXSk7DQogICAgICAgICAgICBpZiAobVsnRXhTdHInXSAhPSBudWxsKSB7DQogICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkV4dGVuZGVkIERhdGEiLCBtWydFeFN0ciddKTsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAobVsnRXgnXS5sZW5ndGggPiAwKSB7DQogICAgICAgICAgICAgICAgdmFyIGUgPSAnJzsNCiAgICAgICAgICAgICAgICBmb3IgKGkgaW4gbVsnRXgnXSkgeyBpZiAoZS5sZW5ndGggPiAwKSBlICs9ICcsJzsgZSArPSBtWydFeCddLmNoYXJDb2RlQXQoaSk7IH0NCiAgICAgICAgICAgICAgICBpZiAoZSAhPSAnJykgeCArPSBhZGRIdG1sVmFsdWUoIkRhdGEgVmFsdWVzIiwgZSk7DQogICAgICAgICAgICAgICAgaWYgKG1bJ0V4J10ubGVuZ3RoID4gMiAmJiBSZWFkU2hvcnQobVsnRXgnXSwgMCkgPT0gKG1bJ0V4J10ubGVuZ3RoIC0gMikpIHggKz0gYWRkSHRtbFZhbHVlKCJEYXRhIFN0cmluZyIsIG1bJ0V4J10uc3Vic3RyaW5nKDIpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gIjwvZGl2PiI7DQogICAgICAgICAgICBtZXNzYWdlYm94KCJBdWRpdCBFdmVudCAjIiArIChoICsgMSkgKyAiIERldGFpbHMiLCB4KTsNCiAgICAgICAgfQ0KDQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIENlcnRpZmljYXRlcw0KICAgICAgICAvLw0KDQogICAgICAgIHZhciB4eENlcnRpZmljYXRlcyA9IG51bGw7DQogICAgICAgIHZhciB4eENlcnRQcml2YXRlS2V5cyA9IG51bGw7DQogICAgICAgIHZhciB4eFRsc1NldHRpbmdzID0gbnVsbDsNCiAgICAgICAgdmFyIHh4VGxzQ3VycmVudENlcnQgPSBudWxsOw0KICAgICAgICB2YXIgeHhUTFNDcmVkZW50aWFsQ29udGV4dCA9IG51bGw7DQogICAgICAgIHZhciB4eENhUHJpdmF0ZUtleSA9IG51bGw7DQogICAgICAgIHZhciB4eENhU3ViamVjdEF0dHJpYnV0ZXMgPSBudWxsOw0KDQogICAgICAgIGZ1bmN0aW9uIFB1bGxDZXJ0aWZpY2F0ZXMoKSB7DQogICAgICAgICAgICAvLyBXZSBvbmx5IGRlYWwgd2l0aCBjZXJ0aWZpY2F0ZXMgc3RhcnRpbmcgd2l0aCBJbnRlbCBBTVQgNiBhbmQgYmV5b25kDQogICAgICAgICAgICBhbXRzdGFjay5CYXRjaEVudW0obnVsbCwgWyJBTVRfUHVibGljS2V5Q2VydGlmaWNhdGUiLCAiQU1UX1B1YmxpY1ByaXZhdGVLZXlQYWlyIiwgIkFNVF9UTFNTZXR0aW5nRGF0YSIsICJBTVRfVExTQ3JlZGVudGlhbENvbnRleHQiXSwgcHJvY2Vzc0NlcnRzMSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBwcm9jZXNzQ2VydHMxKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKChzdGF0dXMgPT0gNDAwKSB8fCBlcnJjaGVjayhzdGF0dXMsIHN0YWNrKSkgcmV0dXJuOw0KICAgICAgICAgICAgUVYoJ2dvMTYnLCB0cnVlKTsgLy8gU2VjdXJpdHkgU2V0dGluZ3MNCiAgICAgICAgICAgIHh4Q2VydGlmaWNhdGVzID0gcmVzcG9uc2VzWyJBTVRfUHVibGljS2V5Q2VydGlmaWNhdGUiXS5yZXNwb25zZXM7DQogICAgICAgICAgICB4eENlcnRQcml2YXRlS2V5cyA9IHJlc3BvbnNlc1siQU1UX1B1YmxpY1ByaXZhdGVLZXlQYWlyIl0ucmVzcG9uc2VzOw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5ncyA9IHJlc3BvbnNlc1siQU1UX1RMU1NldHRpbmdEYXRhIl0ucmVzcG9uc2VzOw0KICAgICAgICAgICAgeHhUTFNDcmVkZW50aWFsQ29udGV4dCA9IHJlc3BvbnNlc1siQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0Il0ucmVzcG9uc2VzOw0KDQogICAgICAgICAgICAvLyBTZWxlY3QgdGhlIGN1cnJlbnQgVExTIGNlcnRpZmljYXRlIGluIHRoZSBkcm9wIGRvd24gYm94DQogICAgICAgICAgICB4eFRsc0N1cnJlbnRDZXJ0ID0gbnVsbDsNCiAgICAgICAgICAgIGlmICh4eFRMU0NyZWRlbnRpYWxDb250ZXh0Lmxlbmd0aCA+IDApIHsNCiAgICAgICAgICAgICAgICB2YXIgY2VydEluc3RhbmNlSWQgPSB4eFRMU0NyZWRlbnRpYWxDb250ZXh0WzBdWydFbGVtZW50SW5Db250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVsnVmFsdWUnXTsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4Q2VydGlmaWNhdGVzKSB7IGlmICh4eENlcnRpZmljYXRlc1tpXVsnSW5zdGFuY2VJRCddID09IGNlcnRJbnN0YW5jZUlkKSB7IHh4VGxzQ3VycmVudENlcnQgPSBpOyB9IH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gU2V0dXAgdGhlIGNlcnRpZmljYXRlcw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eENlcnRpZmljYXRlcykgew0KICAgICAgICAgICAgICAgIHh4Q2VydGlmaWNhdGVzW2ldLlRydXN0ZWRSb290Q2VydGZpY2F0ZSA9ICh4eENlcnRpZmljYXRlc1tpXVsiVHJ1c3RlZFJvb3RDZXJ0ZmljYXRlIl0gPT0gdHJ1ZSk7DQogICAgICAgICAgICAgICAgeHhDZXJ0aWZpY2F0ZXNbaV0uWDUwOUNlcnRpZmljYXRlID0gd2luZG93LmF0b2IoeHhDZXJ0aWZpY2F0ZXNbaV1bIlg1MDlDZXJ0aWZpY2F0ZSJdKTsNCiAgICAgICAgICAgICAgICB4eENlcnRpZmljYXRlc1tpXS5YSXNzdWVyID0gcGFyc2VDZXJ0TmFtZSh4eENlcnRpZmljYXRlc1tpXVsiSXNzdWVyIl0pOw0KICAgICAgICAgICAgICAgIHh4Q2VydGlmaWNhdGVzW2ldLlhTdWJqZWN0ID0gcGFyc2VDZXJ0TmFtZSh4eENlcnRpZmljYXRlc1tpXVsiU3ViamVjdCJdKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGFtdGNlcnRfbGlua0NlcnRQcml2YXRlS2V5KHh4Q2VydGlmaWNhdGVzLCB4eENlcnRQcml2YXRlS2V5cyk7IC8vIFRoaXMgbGlua3MgYWxsIGNlcnRpZmljYXRlcyBhbmQgcHJpdmF0ZSBrZXlzDQoNCiAgICAgICAgICAgIHVwZGF0ZUNlcnRpZmljYXRlcygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcGFyc2VDZXJ0TmFtZSh4KSB7DQogICAgICAgICAgICB2YXIgaiwgciA9IHt9LCB4eCA9IHguc3BsaXQoJywnKTsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHgpIHsgaiA9IHh4W2ldLmluZGV4T2YoJz0nKTsgclt4eFtpXS5zdWJzdHJpbmcoMCwgaildID0geHhbaV0uc3Vic3RyaW5nKGogKyAxKTsgfQ0KICAgICAgICAgICAgcmV0dXJuIHI7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBnZXRUbHNTZWN1cml0eVN0YXRlKHgpIHsNCiAgICAgICAgICAgIGlmICh4eFRsc1NldHRpbmdzW3hdWydFbmFibGVkJ10gPT0gZmFsc2UpIHJldHVybiAiRGlzYWJsZWQiOw0KICAgICAgICAgICAgdmFyIHIgPSAoKHh4VGxzU2V0dGluZ3NbeF1bJ011dHVhbEF1dGhlbnRpY2F0aW9uJ10gPT0gdHJ1ZSkgPyAnTXV0dWFsLWF1dGggVExTJyA6ICdTZXJ2ZXItYXV0aCBUTFMnKSArICgoeHhUbHNTZXR0aW5nc1t4XVsnQWNjZXB0Tm9uU2VjdXJlQ29ubmVjdGlvbnMnXSA9PSB0cnVlKSA/ICIgYW5kIG5vbi1UTFMiIDogIiIpOw0KICAgICAgICAgICAgaWYgKCh4eFRsc1NldHRpbmdzW3hdWydNdXR1YWxBdXRoZW50aWNhdGlvbiddID09IHRydWUpICYmICh4eFRsc1NldHRpbmdzW3hdWydUcnVzdGVkQ04nXSkpIHsNCiAgICAgICAgICAgICAgICB2YXIgdHJ1c3RlZENuID0gTWFrZVRvQXJyYXkoeHhUbHNTZXR0aW5nc1t4XVsnVHJ1c3RlZENOJ10pOw0KICAgICAgICAgICAgICAgIGlmICh0cnVzdGVkQ24ubGVuZ3RoID4gMCkgeyByICs9ICIsIFRydXN0ZWQgbmFtZSIgKyAoKHRydXN0ZWRDbi5sZW5ndGggPiAxKT8ncyc6JycpICsgIjogIiArIHRydXN0ZWRDbi5qb2luKCcsICcpICsgIi4iOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gcjsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVwZGF0ZUNlcnRpZmljYXRlcygpIHsNCiAgICAgICAgICAgIGlmICh4eENlcnRpZmljYXRlcyA9PSBudWxsKSByZXR1cm47DQoNCiAgICAgICAgICAgIC8vIEZpZ3VyZSBvdXQgd2hhdCBpbmRleCBpcyBsb2NhbCAmIHJlbW90ZQ0KICAgICAgICAgICAgdmFyIGxvY2FsTmR4ID0gKCh4eFRsc1NldHRpbmdzWzBdWydJbnN0YW5jZUlEJ10gPT0gJ0ludGVsKHIpIEFNVCBMTVMgVExTIFNldHRpbmdzJykpID8gMCA6IDEsIHJlbW90ZU5keCA9ICgxIC0gbG9jYWxOZHgpOw0KDQogICAgICAgICAgICAvLyBHZW5lcmFsIHNldHRpbmdzDQogICAgICAgICAgICB2YXIgeCA9IFRhYmxlU3RhcnQoKTsNCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiUmVtb3RlIFRMUyBzZWN1cml0eSIsIGFkZExpbmtDb25kaXRpb25hbChnZXRUbHNTZWN1cml0eVN0YXRlKHJlbW90ZU5keCksICdzaG93U2V0VGxzU2VjdXJpdHlEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJMb2NhbCBUTFMgc2VjdXJpdHkiLCBhZGRMaW5rQ29uZGl0aW9uYWwoZ2V0VGxzU2VjdXJpdHlTdGF0ZShsb2NhbE5keCksICdzaG93U2V0VGxzU2VjdXJpdHlEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgeCArPSAiPGJyPiIgKyBUYWJsZVN0YXJ0MigpICsgIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCBjZXJ0aWZpY2F0ZXMgZm9yIHRoaXMgY29tcHV0ZXIuPGJyPjxicj4iOw0KICAgICAgICAgICAgaWYgKHh4Q2VydGlmaWNhdGVzLmxlbmd0aCA9PSAwICYmIHh4Q2VydFByaXZhdGVLZXlzLmxlbmd0aCA9PSAwKSB7DQogICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD48YnI+PGk+Tm8gY2VydGlmaWNhdGVzIGZvdW5kLjwvaT48L2Rpdj48YnI+IjsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eENlcnRpZmljYXRlcykgew0KICAgICAgICAgICAgICAgICAgICB2YXIgZGVzYyA9ICcnOw0KICAgICAgICAgICAgICAgICAgICBpZiAoeHhDZXJ0aWZpY2F0ZXNbaV0uVHJ1c3RlZFJvb3RDZXJ0ZmljYXRlKSBkZXNjID0gJywgVHJ1c3RlZCBSb290JzsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHh4Q2VydGlmaWNhdGVzW2ldLlhQcml2YXRlS2V5KSBkZXNjID0gJywgUHJpdmF0ZSBLZXknOw0KICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSB4eFRsc0N1cnJlbnRDZXJ0KSBkZXNjICs9ICcsIFRMUyBjZXJ0JzsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIG9uY2xpY2s9c2hvd0NlcnREZXRhaWxzKCIgKyBpICsgIik+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDozcHg+PGI+IiArIEVzY2FwZUh0bWwoeHhDZXJ0aWZpY2F0ZXNbaV0uWFN1YmplY3RbIkNOIl0pICsgIjwvYj48aT4iICsgZGVzYyArICI8L2k+PC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eENlcnRQcml2YXRlS2V5cykgew0KICAgICAgICAgICAgICAgICAgICBpZiAoIXh4Q2VydFByaXZhdGVLZXlzW2ldLlhDZXJ0KSB7DQogICAgICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93S2V5UGFpckRldGFpbHMoIiArIGkgKyAiKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48aT5VbmFzc2lnbmVkIFByaXZhdGUgS2V5IFBhaXIgIyIgKyBpICsgIjwvaT48L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgdmFyIGJ1dHRvbnMgPSBBZGRSZWZyZXNoQnV0dG9uKCJQdWxsQ2VydGlmaWNhdGVzKCkiKTsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHsgYnV0dG9ucyArPSAoQWRkQnV0dG9uKCJBZGQgQ2VydGlmaWNhdGUuLi4iLCAiYWRkQ2VydEJ1dHRvbigpIikgKyBBZGRCdXR0b24oIklzc3VlIENlcnRpZmljYXRlLi4uIiwgImlzc3VlQ2VydEJ1dHRvbigpIikpOyB9DQogICAgICAgICAgICB4ICs9ICI8YnI+PHRkIGNsYXNzPXIxPiIgKyBUYWJsZUVuZChidXR0b25zKTsNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZUNlcnRzJywgeCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93S2V5UGFpckRldGFpbHMoaCkgew0KICAgICAgICAgICAgdmFyIHggPSAiVGhpcyBpcyBhIHB1YmxpYy9wcml2YXRlIGNlcnRpZmljYXRlIGtleSBwYWlyIHRoYXQgZG9lcyBub3QgYmVsb25nIHRvIGFueSBjZXJ0aWZpY2F0ZXMuIFRoaXMgZW50cnkgc2hvdWxkIGJlIHRlbXBvcmFyeS4iOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIktleSBQYWlyICMiICsgaCwgNSwgZnVuY3Rpb24gKGIpIHsgaWYgKGIgPT0gMikgeyBhbXRzdGFjay5EZWxldGUoJ0FNVF9QdWJsaWNQcml2YXRlS2V5UGFpcicsIHsgJ0luc3RhbmNlSUQnOiB4eENlcnRQcml2YXRlS2V5c1toXVsnSW5zdGFuY2VJRCddIH0sIFB1bGxDZXJ0aWZpY2F0ZXMsIDAsIDEpOyB9IH0sIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIHh4Q2VydFN1YmplY3ROYW1lcyA9IHsgJ0NOJzogJ0NvbW1vbiBOYW1lJywgJ08nOiAnT3JnYW5pemF0aW9uJywgJ09VJzogJ09yZyBVbml0JywgJ1MnOiAnU3RhdGUvUHJvdmluY2UnLCAnU1QnOiAnU3RhdGUvUHJvdmluY2UnLCAnTCc6ICdMb2NhbGl0eScsICdDJzogJ0NvdW50cnknLCAnU04nOiAnU3VybmFtZScsICdHTic6ICdHaXZlbiBuYW1lJyB9Ow0KICAgICAgICBmdW5jdGlvbiBzaG93Q2VydERldGFpbHMoaCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIGMgPSB4eENlcnRpZmljYXRlc1toXSwgeCA9ICc8YnI+JzsNCg0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkNlcnRpZmljYXRlIiwgYy5YNTA5Q2VydGlmaWNhdGUubGVuZ3RoICsgIiBieXRlcywgPGEgc3R5bGU9Y3Vyc29yOnBvaW50ZXI7Y29sb3I6Ymx1ZSBvbmNsaWNrPWRvd25sb2FkQ2VydCgiICsgaCArICIpPkRvd25sb2FkPC9hPiIpOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlRydXN0ZWQgcm9vdCIsIGMuVHJ1c3RlZFJvb3RDZXJ0ZmljYXRlID8gIlllcyIgOiAiTm8iKTsNCiAgICAgICAgICAgIGlmIChjLlRydXN0ZWRSb290Q2VydGZpY2F0ZSA9PSBmYWxzZSAmJiBjLlhQcml2YXRlS2V5KSB7IHggKz0gYWRkSHRtbFZhbHVlKCdQcml2YXRlIGtleScsICdQcmVzZW50Jyk7IH0NCg0KICAgICAgICAgICAgLy8gU2hvdyBjZXJ0aWZpY2F0ZSB1c2FnZXMNCiAgICAgICAgICAgIC8qDQogICAgICAgICAgICB5ID0gW107DQogICAgICAgICAgICBpZiAoZXh0S2V5VXNhZ2UgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgIGlmIChleHRLZXlVc2FnZS5jbGllbnRBdXRoID09IHRydWUpIHsgeS5wdXNoKCJUTFMmbmJzcDtDbGllbnQiKTsgfQ0KICAgICAgICAgICAgICAgIGlmIChleHRLZXlVc2FnZS5jb2RlU2lnbmluZyA9PSB0cnVlKSB7IHkucHVzaCgiQ29kZSZuYnNwO1NpZ25pbmciKTsgfQ0KICAgICAgICAgICAgICAgIGlmIChleHRLZXlVc2FnZS5lbWFpbFByb3RlY3Rpb24gPT0gdHJ1ZSkgeyB5LnB1c2goIkVNYWlsIik7IH0NCiAgICAgICAgICAgICAgICBpZiAoZXh0S2V5VXNhZ2Uuc2VydmVyQXV0aCA9PSB0cnVlKSB7IHkucHVzaCgiVExTJm5ic3A7U2VydmVyIik7IH0NCiAgICAgICAgICAgICAgICBpZiAoZXh0S2V5VXNhZ2VbIjIuMTYuODQwLjEuMTEzNzQxLjEuMi4xIl0gPT0gdHJ1ZSkgeyB5LnB1c2goIkludGVsJnJlZzsmbmJzcDtBTVQgQ29uc29sZSIpOyB9DQogICAgICAgICAgICAgICAgaWYgKGV4dEtleVVzYWdlWyIyLjE2Ljg0MC4xLjExMzc0MS4xLjIuMiJdID09IHRydWUpIHsgeS5wdXNoKCJJbnRlbCZyZWc7Jm5ic3A7QU1UIEFnZW50Iik7IH0NCiAgICAgICAgICAgICAgICBpZiAoZXh0S2V5VXNhZ2VbIjIuMTYuODQwLjEuMTEzNzQxLjEuMi4zIl0gPT0gdHJ1ZSkgeyB5LnB1c2goIkludGVsJnJlZzsmbmJzcDtBTVQgQWN0aXZhdGlvbiIpOyB9DQogICAgICAgICAgICAgICAgaWYgKGV4dEtleVVzYWdlLnRpbWVTdGFtcGluZyA9PSB0cnVlKSB7IHkucHVzaCgiVGltZSZuYnNwO1N0YW1waW5nIik7IH0NCiAgICAgICAgICAgICAgICBpZiAoeS5sZW5ndGggPiAwKSB7IHggKz0gYWRkSHRtbFZhbHVlTm9UaXRsZSgiQ2VydGlmaWNhdGUgVXNhZ2UiLCB5LmpvaW4oJywgJykgKyAnLicpICsgJzxiciBjbGVhcj1hbGwgLz4nOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICAqLw0KDQogICAgICAgICAgICB4ICs9ICc8YnI+PGRpdiBzdHlsZT0iYm9yZGVyLWJvdHRvbToxcHggc29saWQgZ3JheSI+PGk+Q2VydGlmaWNhdGUgU3ViamVjdDwvaT48L2Rpdj48YnI+JzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYy5YU3ViamVjdCkgeyBpZiAoYy5YU3ViamVjdFtpXSkgeyB4ICs9IGFkZEh0bWxWYWx1ZSh4eENlcnRTdWJqZWN0TmFtZXNbaV0gPyB4eENlcnRTdWJqZWN0TmFtZXNbaV0gOiBpLCBFc2NhcGVIdG1sKGMuWFN1YmplY3RbaV0pKTsgfSB9DQogICAgICAgICAgICAvLyB4ICs9IGFkZEh0bWxWYWx1ZU5vVGl0bGUoJ0ZpbmdlcnByaW50JywgYy5maW5nZXJwcmludC5zdWJzdHJpbmcoMCwyOSkgKyAnPGJyIC8+JyArIGMuZmluZ2VycHJpbnQuc3Vic3RyaW5nKDMwKSk7IC8vIFRPRE86IFBhcnNlIHRoZSBjZXJ0aWZpY2F0ZSB1c2luZyBGb3JnZSBhbmQgZ2V0IHRoZSBmaW5nZXJwcmludA0KICAgICAgICAgICAgeCArPSAnPGJyPjxkaXYgc3R5bGU9ImJvcmRlci1ib3R0b206MXB4IHNvbGlkIGdyYXkiPjxpPklzc3VlciBDZXJ0aWZpY2F0ZTwvaT48L2Rpdj48YnI+JzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYy5YSXNzdWVyKSB7IGlmIChjLlhJc3N1ZXJbaV0pIHsgeCArPSBhZGRIdG1sVmFsdWUoeHhDZXJ0U3ViamVjdE5hbWVzW2ldID8geHhDZXJ0U3ViamVjdE5hbWVzW2ldIDogaSwgRXNjYXBlSHRtbChjLlhJc3N1ZXJbaV0pKTsgfSB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiQ2VydGlmaWNhdGUgLSAiICsgRXNjYXBlSHRtbChjLlhTdWJqZWN0WyJDTiJdKSwgNSwgZnVuY3Rpb24gKGIpIHsNCiAgICAgICAgICAgICAgICBpZiAoYiA9PSAyKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIGEgcHJpdmF0ZSBrZXksIGRlbGV0ZSBpdC4NCiAgICAgICAgICAgICAgICAgICAgaWYgKHh4Q2VydGlmaWNhdGVzW2hdLlhQcml2YXRlS2V5KSBhbXRzdGFjay5EZWxldGUoJ0FNVF9QdWJsaWNQcml2YXRlS2V5UGFpcicsIHsgJ0luc3RhbmNlSUQnOiB4eENlcnRpZmljYXRlc1toXS5YUHJpdmF0ZUtleVsnSW5zdGFuY2VJRCddIH0sIGZ1bmN0aW9uICgpIHsgfSwgMCwgMSk7DQogICAgICAgICAgICAgICAgICAgIC8vIERlbGV0ZSB0aGUgY2VydGlmaWNhdGUNCiAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suRGVsZXRlKCdBTVRfUHVibGljS2V5Q2VydGlmaWNhdGUnLCB4eENlcnRpZmljYXRlc1toXSwgY2VydGlmaWNhdGVSZW1vdmVkLCAwLCAxKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LCB4KTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgZnVuY3Rpb24gZG93bmxvYWRDZXJ0KGgpIHsgDQoNCiAgICAgICAgICAgIHNhdmVBcyhkYXRhMmJsb2IoeHhDZXJ0aWZpY2F0ZXNbaF0uWDUwOUNlcnRpZmljYXRlKSwgeHhDZXJ0aWZpY2F0ZXNbaF0uWFN1YmplY3RbJ0NOJ10gKyAiLmNlciIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2VydF9GaWxlU2VsZWN0SGFuZGxlcihlKSB7DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQogICAgICAgICAgICBpZiAoZS5kYXRhVHJhbnNmZXIuZmlsZXMubGVuZ3RoID09IDEpIHsNCiAgICAgICAgICAgICAgICBpZiAoZS5kYXRhVHJhbnNmZXIuZmlsZXNbMF0ubmFtZS50b0xvd2VyQ2FzZSgpLmVuZHNXaXRoKCcucDEyJykpIHsNCiAgICAgICAgICAgICAgICAgICAgaXNzdWVDZXJ0QnV0dG9uKGUuZGF0YVRyYW5zZmVyLmZpbGVzKTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBhZGRDZXJ0QnV0dG9uKGUuZGF0YVRyYW5zZmVyLmZpbGVzKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgeHhEcmFnRHJvcENlcnRGaWxlcyA9IG51bGw7DQogICAgICAgIGZ1bmN0aW9uIGFkZENlcnRCdXR0b24oZmlsZXMpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgIXh4QWNjb3VudEFkbWluTmFtZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MTBweD48L2Rpdj4nOw0KICAgICAgICAgICAgeHhEcmFnRHJvcENlcnRGaWxlcyA9IGZpbGVzOw0KDQogICAgICAgICAgICB2YXIgaW5wdXQgPSAiPGlucHV0IGlkPWNlcnRvcGVuIG9uY2hhbmdlPWFkZENlcnRCdXR0b25VcGRhdGUoKSB0eXBlPWZpbGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHggYWNjZXB0PScuY2VyLC5wZW0nPiI7DQogICAgICAgICAgICBpZiAoeHhEcmFnRHJvcENlcnRGaWxlcykgeyBpbnB1dCA9ICc8aW5wdXQgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHggcmVhZG9ubHkgZGlzYWJsZWQgdmFsdWU9IicgKyB4eERyYWdEcm9wQ2VydEZpbGVzWzBdLm5hbWUgKyAnIj4nOyB9DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PiIgKyBpbnB1dCArICI8ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5DZXJ0aWZpY2F0ZSBmaWxlPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PHNlbGVjdCBpZD1jZXJ0dHlwZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjBweD48b3B0aW9uIHZhbHVlPTA+Q2hhaW4gQ2VydGlmaWNhdGU8L29wdGlvbj48b3B0aW9uIHZhbHVlPTE+VHJ1c3RlZCBSb290IENlcnRpZmljYXRlPC9vcHRpb24+PC9zZWxlY3Q+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q2VydGlmaWNhdGUgdHlwZTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiQWRkIENlcnRpZmljYXRlIiwgMywgYWRkQ2VydEJ1dHRvbk9rLCB4KTsNCiAgICAgICAgICAgIGFkZENlcnRCdXR0b25VcGRhdGUoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZENlcnRCdXR0b25VcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgY2VydG9wZW4gPSBnZXRJbnB1dEVsZW1lbnQoJ2NlcnRvcGVuJyk7DQogICAgICAgICAgICBRRSgnaWR4X2RsZ09rQnV0dG9uJywgIWNlcnRvcGVuIHx8IGNlcnRvcGVuLmZpbGVzLmxlbmd0aCA9PSAxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZENlcnRCdXR0b25PaygpIHsNCg0KICAgICAgICAgICAgdmFyIGNlcnRvcGVuID0gZ2V0SW5wdXRFbGVtZW50KCdjZXJ0b3BlbicpOw0KICAgICAgICAgICAgdmFyIGZpbGVzID0geHhEcmFnRHJvcENlcnRGaWxlczsNCiAgICAgICAgICAgIGlmIChjZXJ0b3BlbikgZmlsZXMgPSBjZXJ0b3Blbi5maWxlczsNCiAgICAgICAgICAgIGlmIChmaWxlcyAmJiBmaWxlcy5sZW5ndGggPT0gMSkgew0KICAgICAgICAgICAgICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpOw0KICAgICAgICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSBhZGRDZXJ0QnV0dG9uT2syOw0KICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkQXNCaW5hcnlTdHJpbmcoZmlsZXNbMF0pOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIA0KICAgICAgICBmdW5jdGlvbiBhZGRDZXJ0QnV0dG9uT2syKGZpbGUpIHsNCiAgICAgICAgICAgIHZhciBkYXRhID0gZmlsZS50YXJnZXQucmVzdWx0Ow0KICAgICAgICAgICAgdmFyIGkgPSBkYXRhLmluZGV4T2YoJy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLScpOw0KICAgICAgICAgICAgaWYgKGkgPiAwKSB7DQogICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBhIC5QRU0gZmlsZSwga2VlcCBldmVyeXRoaW5nIGJldHdlZW4gQkVHSU4vRU5ELCBjbGVhbiBpdCB1cCBhbmQgdXNlIGFzLWlzLiBJdCdzIGFscmVhZHkgQmFzZTY0Lg0KICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLnN1YnN0cmluZyhpICsgMjcpOw0KICAgICAgICAgICAgICAgIGkgPSBkYXRhLmluZGV4T2YoJy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0nKTsNCiAgICAgICAgICAgICAgICBpZiAoaSA+IDApIGRhdGEgPSBkYXRhLnN1YnN0cmluZygwLCBpKQ0KICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLnJlcGxhY2UoL1xyXG4vZywgJycpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgLkNFUiBmaWxlLCBqdXN0IGJhc2U2NCBlbmNvZGUgaXQgYW5kIHdlIHNob3VsZCBiZSBvay4NCiAgICAgICAgICAgICAgICBkYXRhID0gYnRvYShkYXRhKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChnZXRTZWxlY3RFbGVtZW50KCdjZXJ0dHlwZScpLnZhbHVlID09IDEpIHsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfQWRkVHJ1c3RlZFJvb3RDZXJ0aWZpY2F0ZShkYXRhLCBjZXJ0aWZpY2F0ZUFkZGVkKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgYW10c3RhY2suQU1UX1B1YmxpY0tleU1hbmFnZW1lbnRTZXJ2aWNlX0FkZENlcnRpZmljYXRlKGRhdGEsIGNlcnRpZmljYXRlQWRkZWQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gaXNzdWVDZXJ0QnV0dG9uKGZpbGVzKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8ICF4eEFjY291bnRBZG1pbk5hbWUpIHJldHVybjsNCiAgICAgICAgICAgIHh4RHJhZ0Ryb3BDZXJ0RmlsZXMgPSBmaWxlczsNCg0KDQoNCiAgICAgICAgICAgIHZhciB4ID0gJycsIGlucHV0ID0gIjxpbnB1dCBpZD1jZXJ0b3BlbiB0eXBlPWZpbGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjMwcHggb25jaGFuZ2U9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgYWNjZXB0PScucDEyJz4iOw0KICAgICAgICAgICAgaWYgKHh4RHJhZ0Ryb3BDZXJ0RmlsZXMpIHsgaW5wdXQgPSAnPGlucHV0IHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4IHJlYWRvbmx5IGRpc2FibGVkIHZhbHVlPSInICsgeHhEcmFnRHJvcENlcnRGaWxlc1swXS5uYW1lICsgJyI+JzsgfQ0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZWhlaWdodDoyNnB4O21hcmdpbi10b3A6MTRweD4iICsgaW5wdXQgKyAiPGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q2VydGlmaWNhdGUgZmlsZTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxpbnB1dCBvbmtleXVwPWlzc3VlQ2VydEJ1dHRvblVwZGF0ZSgpIGlkPWNlcnRvcGVucGFzcyB0eXBlPXBhc3N3b3JkIGF1dG9jb21wbGV0ZT1vZmYgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjMwcHg+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q2VydGlmaWNhdGUgcGFzc3dvcmQ8L2Rpdj48L2Rpdj4iOw0KDQogICAgICAgICAgICB4ICs9ICc8YnI+PGRpdiBzdHlsZT0iYm9yZGVyLWJvdHRvbToxcHggc29saWQgZ3JheSI+PGk+SW50ZWwmcmVnOyBBTVQgQ2VydGlmaWNhdGU8L2k+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IG9ua2V5dXA9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgaWQ9Y2VydGNuIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PkNvbW1vbiBOYW1lPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IG9ua2V5dXA9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgaWQ9Y2VydG8gc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjMwcHg+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+T3JnYW5pemF0aW9uPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IG9ua2V5dXA9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgaWQ9Y2VydHN0IHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PlN0YXRlL1Byb3ZpbmNlPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IG9ua2V5dXA9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgaWQ9Y2VydGMgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjMwcHg+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q291bnRyeTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICc8ZGl2PkNlcnRpZmljYXRlIFVzYWdlczwvZGl2Pjx1bCBzdHlsZT0ibGlzdC1zdHlsZS10eXBlOm5vbmU7aGVpZ2h0OjEwMHB4O292ZXJmbG93OmF1dG87d2lkdGg6MTAwJTtib3JkZXI6IDFweCBzb2xpZCAjMDAwO2JhY2tncm91bmQtY29sb3I6d2hpdGU7b3ZlcmZsb3cteDpoaWRkZW47bWFyZ2luOjA7cGFkZGluZzowIj4nOw0KICAgICAgICAgICAgLy94ICs9ICc8bGk+PGxhYmVsPjxpbnB1dCB0eXBlPWNoZWNrYm94IGlkPWQxMV9jdTE+SW50ZWwmcmVnOyBBTVQgQ29uc29sZTwvbGFiZWw+PC9saT4nOw0KICAgICAgICAgICAgLy94ICs9ICc8bGk+PGxhYmVsPjxpbnB1dCB0eXBlPWNoZWNrYm94IGlkPWQxMV9jdTI+SW50ZWwmcmVnOyBBTVQgQWdlbnQ8L2xhYmVsPjwvbGk+JzsNCiAgICAgICAgICAgIC8veCArPSAnPGxpPjxsYWJlbD48aW5wdXQgdHlwZT1jaGVja2JveCBpZD1kMTFfY3UzPkludGVsJnJlZzsgQU1UIEFjdGl2YXRpb248L2xhYmVsPjwvbGk+JzsNCiAgICAgICAgICAgIHggKz0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggaWQ9ZDExX2N1NCBjaGVja2VkPlRMUyBTZXJ2ZXIgKEhUVFBTKTwvbGFiZWw+PC9saT4nOw0KICAgICAgICAgICAgeCArPSAnPGxpPjxsYWJlbD48aW5wdXQgdHlwZT1jaGVja2JveCBpZD1kMTFfY3U1PlRMUyBDbGllbnQgKEhUVFBTKTwvbGFiZWw+PC9saT4nOw0KICAgICAgICAgICAgeCArPSAnPGxpPjxsYWJlbD48aW5wdXQgdHlwZT1jaGVja2JveCBpZD1kMTFfY3U2PkVtYWlsIFByb3RlY3Rpb248L2xhYmVsPjwvbGk+JzsNCiAgICAgICAgICAgIHggKz0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggaWQ9ZDExX2N1Nz5Db2RlIFNpZ25pbmc8L2xhYmVsPjwvbGk+JzsNCiAgICAgICAgICAgIHggKz0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggaWQ9ZDExX2N1OD5UaW1lIFN0YW1wPC9sYWJlbD48L2xpPic7DQogICAgICAgICAgICB4ICs9ICc8L3VsPic7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiSXNzdWUgQ2VydGlmaWNhdGUiLCAzLCBpc3N1ZUNlcnRCdXR0b25PaywgeCk7DQogICAgICAgICAgICBpc3N1ZUNlcnRCdXR0b25VcGRhdGUoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGlzc3VlQ2VydEJ1dHRvblVwZGF0ZSgpIHsNCiAgICAgICAgICAgIHZhciBjZXJ0b3BlbiA9IGdldElucHV0RWxlbWVudCgnY2VydG9wZW4nKTsNCiAgICAgICAgICAgIFFFKCdjZXJ0b3BlbnBhc3MnLCAhY2VydG9wZW4gfHwgKGNlcnRvcGVuICYmIGNlcnRvcGVuLmZpbGVzLmxlbmd0aCA9PSAxKSk7DQogICAgICAgICAgICB2YXIgeCA9ICghY2VydG9wZW4gfHwgY2VydG9wZW4uZmlsZXMubGVuZ3RoIDwgMik7DQogICAgICAgICAgICBpZiAoKCFjZXJ0b3BlbiB8fCAoY2VydG9wZW4gJiYgY2VydG9wZW4uZmlsZXMubGVuZ3RoKSkgPT0gMSAmJiBRKCdjZXJ0b3BlbnBhc3MnKS52YWx1ZSA9PSAnJykgeCA9IGZhbHNlOw0KICAgICAgICAgICAgaWYgKGdldElucHV0RWxlbWVudCgnY2VydGNuJykudmFsdWUgPT0gJycgfHwgZ2V0SW5wdXRFbGVtZW50KCdjZXJ0bycpLnZhbHVlID09ICcnIHx8IGdldElucHV0RWxlbWVudCgnY2VydHN0JykudmFsdWUgPT0gJycgfHwgZ2V0SW5wdXRFbGVtZW50KCdjZXJ0YycpLnZhbHVlID09ICcnKSB7IHggPSBmYWxzZTsgfQ0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gaXNzdWVDZXJ0QnV0dG9uT2soKSB7DQoNCiAgICAgICAgICAgIHZhciBjZXJ0b3BlbiA9IGdldElucHV0RWxlbWVudCgnY2VydG9wZW4nKTsNCiAgICAgICAgICAgIHZhciBmaWxlcyA9IHh4RHJhZ0Ryb3BDZXJ0RmlsZXM7DQogICAgICAgICAgICBpZiAoY2VydG9wZW4pIGZpbGVzID0gY2VydG9wZW4uZmlsZXM7DQogICAgICAgICAgICBpZiAoZmlsZXMgJiYgZmlsZXMubGVuZ3RoID09IDEpIHsNCiAgICAgICAgICAgICAgICAvLyBJc3N1ZSBhIGNlcnRpZmljYXRlIHVzaW5nIHRoaXMgZmlsZQ0KICAgICAgICAgICAgICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpOw0KICAgICAgICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSBpc3N1ZUNlcnRCdXR0b25PazI7DQogICAgICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyhmaWxlc1swXSk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIC8vIElzc3VlIGEgY2VydGlmaWNhdGUgdXNpbmcgYSBkdW1teSBDQQ0KICAgICAgICAgICAgICAgIGlzc3VlQ2VydEJ1dHRvbk9rMyhudWxsKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGlzc3VlQ2VydEJ1dHRvbk9rMihmaWxlKSB7DQogICAgICAgICAgICAvLyBMb2FkIHRoZSBDQSBjZXJ0aWZpY2F0ZSBhbmQgcHJpdmF0ZSBrZXkNCiAgICAgICAgICAgIHZhciByID0gYW10Y2VydF9sb2FkUDEyRmlsZShmaWxlLnRhcmdldC5yZXN1bHQsIFEoJ2NlcnRvcGVucGFzcycpLnZhbHVlLCBpc3N1ZUNlcnRCdXR0b25PazMpOw0KICAgICAgICAgICAgaWYgKHIgPT0gZmFsc2UpIHsgbWVzc2FnZWJveCgiSXNzdWUgQ2VydGlmaWNhdGUiLCAiVW5hYmxlIHRvIGRlY3J5cHQvZGVjb2RlIGNlcnRpZmljYXRlLiIpOyByZXR1cm47IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGlzc3VlQ2VydEJ1dHRvbk9rMyhwcml2YXRlS2V5LCBzdWJqZWN0QXR0cmlidXRlcywgY2VydCkgew0KICAgICAgICAgICAgLy8gQXNrIEludGVsIEFNVCB0byBnZW5lcmF0ZSBhIGtleSBwYWlyDQogICAgICAgICAgICB4eENhUHJpdmF0ZUtleSA9IHByaXZhdGVLZXk7DQogICAgICAgICAgICB4eENhU3ViamVjdEF0dHJpYnV0ZXMgPSBzdWJqZWN0QXR0cmlidXRlczsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZV9HZW5lcmF0ZUtleVBhaXIoMCwgMjA0OCwgR2VuZXJhdGVLZXlQYWlyUmVzcG9uc2UpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gR2VuZXJhdGVLZXlQYWlyUmVzcG9uc2Uoc3RhY2ssIHNlcnZpY2VOYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCdJc3N1ZSBDZXJ0aWZpY2F0ZScsICdGYWlsZWQgdG8gZ2VuZXJhdGUga2V5IHBhaXIuIFN0YXR1czogJyArIHN0YXR1cyk7IHJldHVybjsgfQ0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlLkJvZHlbJ1JldHVyblZhbHVlJ10gIT0gMCkgeyBtZXNzYWdlYm94KCdJc3N1ZSBDZXJ0aWZpY2F0ZScsICdGYWlsZWQgdG8gZ2VuZXJhdGUga2V5IHBhaXIsICcgKyByZXNwb25zZS5Cb2R5WydSZXR1cm5WYWx1ZVN0ciddKTsgcmV0dXJuOyB9DQoNCiAgICAgICAgICAgIC8vIEdldCB0aGUgbmV3IGtleSBwYWlyDQogICAgICAgICAgICBhbXRzdGFjay5FbnVtKCJBTVRfUHVibGljUHJpdmF0ZUtleVBhaXIiLCBHZW5lcmF0ZUtleVBhaXJSZXNwb25zZTIsIHJlc3BvbnNlLkJvZHlbJ0tleVBhaXInXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWydWYWx1ZSddKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEdlbmVyYXRlS2V5UGFpclJlc3BvbnNlMihzdGFjaywgc2VydmljZU5hbWUsIHJlc3BvbnNlLCBzdGF0dXMsIHRhZykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsgbWVzc2FnZWJveCgnSXNzdWUgQ2VydGlmaWNhdGUnLCAnRmFpbGVkIHRvIGdlbmVyYXRlIGtleSBwYWlyLiBTdGF0dXM6ICcgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgIHZhciBERVJLZXkgPSBudWxsOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiByZXNwb25zZSkgeyBpZiAocmVzcG9uc2VbaV1bJ0luc3RhbmNlSUQnXSA9PSB0YWcpIERFUktleSA9IHJlc3BvbnNlW2ldWydERVJLZXknXTsgfQ0KDQogICAgICAgICAgICAvLyBHZXQgY2VydGlmaWNhdGUgdmFsdWVzDQogICAgICAgICAgICB2YXIgY2VydGF0dHJpYnV0ZXMgPSB7ICdDTic6IGdldElucHV0RWxlbWVudCgnY2VydGNuJykudmFsdWUsICdPJzogZ2V0SW5wdXRFbGVtZW50KCdjZXJ0bycpLnZhbHVlLCAnU1QnOiBnZXRJbnB1dEVsZW1lbnQoJ2NlcnRzdCcpLnZhbHVlLCAnQyc6IGdldElucHV0RWxlbWVudCgnY2VydGMnKS52YWx1ZSB9Ow0KICAgICAgICAgICAgdmFyIGlzc3VlcmF0dHJpYnV0ZXMgPSB7ICdDTic6ICdVbnRydXN0ZWQgUm9vdCBDZXJ0aWZpY2F0ZScgfTsNCiAgICAgICAgICAgIGlmICh4eENhUHJpdmF0ZUtleSAhPSBudWxsICYmIHh4Q2FTdWJqZWN0QXR0cmlidXRlcykgew0KICAgICAgICAgICAgICAgIGlzc3VlcmF0dHJpYnV0ZXMgPSB7fTsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4Q2FTdWJqZWN0QXR0cmlidXRlcykgew0KICAgICAgICAgICAgICAgICAgICBpc3N1ZXJhdHRyaWJ1dGVzW3h4Q2FTdWJqZWN0QXR0cmlidXRlc1tpXS5zaG9ydE5hbWVdID0geHhDYVN1YmplY3RBdHRyaWJ1dGVzW2ldLnZhbHVlOyAvLyBUaGUgaXNzdWluZyBDQSdzIHN1YmplY3QgYXR0cmlidXRlcyANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9IA0KDQogICAgICAgICAgICAvLyBGaWd1cmUgb3V0IHRoZSBleHRlbmRlZCBrZXkgdXNhZ2VzDQogICAgICAgICAgICB2YXIgZXh0S2V5VXNhZ2UgPSB7IG5hbWU6ICdleHRLZXlVc2FnZScgfQ0KICAgICAgICAgICAgLy9pZiAoUSgnZDExX2N1MScpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2VbJzIuMTYuODQwLjEuMTEzNzQxLjEuMi4xJ10gPSB0cnVlOyBleHRLZXlVc2FnZS5jbGllbnRBdXRoID0gdHJ1ZTsgfQ0KICAgICAgICAgICAgLy9pZiAoUSgnZDExX2N1MicpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2VbJzIuMTYuODQwLjEuMTEzNzQxLjEuMi4yJ10gPSB0cnVlOyBleHRLZXlVc2FnZS5jbGllbnRBdXRoID0gdHJ1ZTsgfQ0KICAgICAgICAgICAgLy9pZiAoUSgnZDExX2N1MycpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2VbJzIuMTYuODQwLjEuMTEzNzQxLjEuMi4zJ10gPSB0cnVlOyBleHRLZXlVc2FnZS5jbGllbnRBdXRoID0gdHJ1ZTsgfQ0KICAgICAgICAgICAgaWYgKFEoJ2QxMV9jdTQnKS5jaGVja2VkKSB7IGV4dEtleVVzYWdlLnNlcnZlckF1dGggPSB0cnVlOyB9DQogICAgICAgICAgICBpZiAoUSgnZDExX2N1NScpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2UuY2xpZW50QXV0aCA9IHRydWU7IH0NCiAgICAgICAgICAgIGlmIChRKCdkMTFfY3U2JykuY2hlY2tlZCkgeyBleHRLZXlVc2FnZS5lbWFpbFByb3RlY3Rpb24gPSB0cnVlOyB9DQogICAgICAgICAgICBpZiAoUSgnZDExX2N1NycpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2UuY29kZVNpZ25pbmcgPSB0cnVlOyB9DQogICAgICAgICAgICBpZiAoUSgnZDExX2N1OCcpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2UudGltZVN0YW1waW5nID0gdHJ1ZTsgfQ0KDQogICAgICAgICAgICAvLyBTaWduIHRoZSBrZXkgcGFpciB1c2luZyB0aGUgQ0EgY2VydGlmaWF0ZQ0KICAgICAgICAgICAgdmFyIGNlcnQgPSBhbXRjZXJ0X3NpZ25XaXRoQ2FLZXkoREVSS2V5LCB4eENhUHJpdmF0ZUtleSwgY2VydGF0dHJpYnV0ZXMsIGlzc3VlcmF0dHJpYnV0ZXMsIGV4dEtleVVzYWdlKTsNCiAgICAgICAgICAgIGlmIChjZXJ0ID09IG51bGwpIHsgbWVzc2FnZWJveCgnSXNzdWUgQ2VydGlmaWNhdGUnLCAnVW5hYmxlIHRvIHNpZ24gY2VydGlmaWNhdGUuJyk7IHJldHVybjsgfQ0KDQogICAgICAgICAgICAvLyBQbGFjZSB0aGUgcmVzdWx0aW5nIHNpZ25lZCBjZXJ0aWZpY2F0ZSBiYWNrIGludG8gQU1UDQogICAgICAgICAgICB2YXIgcGVtID0gZm9yZ2UucGtpLmNlcnRpZmljYXRlVG9QZW0oY2VydCkucmVwbGFjZSgvKFxyXG58XG58XHIpL2dtLCAiIik7DQogICAgICAgICAgICBhbXRzdGFjay5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfQWRkQ2VydGlmaWNhdGUocGVtLnN1YnN0cmluZygyNywgcGVtLmxlbmd0aCAtIDI1KSwgR2VuZXJhdGVLZXlQYWlyUmVzcG9uc2U0KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEdlbmVyYXRlS2V5UGFpclJlc3BvbnNlNChzdGFjaywgc2VydmljZU5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goJ0lzc3VlIENlcnRpZmljYXRlJywgJ0ZhaWxlZCB0byBnZW5lcmF0ZSBrZXkgcGFpci4gU3RhdHVzOiAnICsgc3RhdHVzKTsgcmV0dXJuOyB9DQogICAgICAgICAgICBQdWxsQ2VydGlmaWNhdGVzKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBjZXJ0aWZpY2F0ZUFkZGVkKHN0YWNrLCBzZXJ2aWNlTmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgeyBpZiAoc3RhdHVzICE9IDIwMCB8fCByZXNwb25zZS5Cb2R5WydSZXR1cm5WYWx1ZSddICE9IDApIHsgbWVzc2FnZWJveCgnQWRkIENlcnRpZmljYXRlJywgJ1VuYWJsZSB0byBhZGQgY2VydGlmaWNhdGUsIGVycm9yICcgKyAoc3RhdHVzICE9IDIwMCA/IHN0YXR1cyA6IHJlc3BvbnNlLkJvZHlbJ1JldHVyblZhbHVlU3RyJ10pKTsgfSBlbHNlIFB1bGxDZXJ0aWZpY2F0ZXMoKTsgfQ0KICAgICAgICBmdW5jdGlvbiBjZXJ0aWZpY2F0ZVJlbW92ZWQoc3RhY2ssIHNlcnZpY2VOYW1lLCBoZWFkZXIsIHN0YXR1cykgeyBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCdSZW1vdmUgQ2VydGlmaWNhdGUnLCAnVW5hYmxlIHRvIHJlbW92ZSBjZXJ0aWZpY2F0ZSwgZXJyb3IgJyArIHN0YXR1cyk7IH0gZWxzZSBQdWxsQ2VydGlmaWNhdGVzKCk7IH0NCg0KICAgICAgICBmdW5jdGlvbiBnZXRJbnB1dEVsZW1lbnQoaWQpIHsgdmFyIGFsbGVsZW1lbnRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0Jyk7IGZvciAodCA9IDA7IHQgPCBhbGxlbGVtZW50cy5sZW5ndGg7IHQrKykgeyBpZiAoYWxsZWxlbWVudHNbdF0uaWQgPT0gaWQpIHJldHVybiBhbGxlbGVtZW50c1t0XTsgfSB9DQogICAgICAgIGZ1bmN0aW9uIGdldFNlbGVjdEVsZW1lbnQoaWQpIHsgdmFyIGFsbGVsZW1lbnRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NlbGVjdCcpOyBmb3IgKHQgPSAwOyB0IDwgYWxsZWxlbWVudHMubGVuZ3RoOyB0KyspIHsgaWYgKGFsbGVsZW1lbnRzW3RdLmlkID09IGlkKSByZXR1cm4gYWxsZWxlbWVudHNbdF07IH0gfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dTZXRUbHNTZWN1cml0eURsZyh4KSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9ICcnOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48c2VsZWN0IG9uY2hhbmdlPXNob3dTZXRUbHNTZWN1cml0eURsZ1VwZGF0ZSgpIGlkPXRsc2NlcnQgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHg+PG9wdGlvbiB2YWx1ZT0tMT5ObyBDZXJ0aWZpY2F0ZSwgVExTIERpc2FibGVkPC9vcHRpb24+IjsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhDZXJ0aWZpY2F0ZXMpIHsgaWYgKHh4Q2VydGlmaWNhdGVzW2ldLlRydXN0ZWRSb290Q2VydGZpY2F0ZSA9PSBmYWxzZSAmJiB4eENlcnRpZmljYXRlc1tpXS5YUHJpdmF0ZUtleSAmJiAoeHhUbHNDdXJyZW50Q2VydCA9PSBudWxsIHx8IHh4VGxzQ3VycmVudENlcnQgPT0gaSkpIHsgeCArPSAiPG9wdGlvbiB2YWx1ZT0iICsgaSArICI+IiArIHh4Q2VydGlmaWNhdGVzW2ldLlhTdWJqZWN0WyJDTiJdICsgIjwvb3B0aW9uPiI7IH0gfQ0KICAgICAgICAgICAgeCArPSAiPC9zZWxlY3Q+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q2VydGlmaWNhdGU8L2Rpdj48L2Rpdj4iOw0KDQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9dGxzcmVtb3RlIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG9uY2hhbmdlPXNob3dTZXRUbHNTZWN1cml0eURsZ1VwZGF0ZSgpPjxvcHRpb24gdmFsdWU9MD5TZXJ2ZXItYXV0aCBUTFMgb25seTwvb3B0aW9uPjxvcHRpb24gdmFsdWU9MT5TZXJ2ZXItYXV0aCwgbm9uLVRMUyBhbGxvd2VkPC9vcHRpb24+IjsNCiAgICAgICAgICAgIGlmIChhbXR2ZXJzaW9uIDwgOCkgeyB4ICs9ICI8b3B0aW9uIHZhbHVlPTI+TXV0dWFsLWF1dGggVExTIG9ubHk8L29wdGlvbj48b3B0aW9uIHZhbHVlPTM+TXV0dWFsLWF1dGgsIG5vbi1UTFMgYWxsb3dlZDwvb3B0aW9uPiI7IH0gLy8gU3VwcG9ydCBmb3IgbXV0dWFsLWF1dGggVExTIHNlZW1zIHRvIGhhdmUgYmVlbiByZW1vdmVkIG9uIEFNVDggYW5kIGFmdGVyDQogICAgICAgICAgICB4ICs9ICI8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5TZWN1cml0eTwvZGl2PjwvZGl2PjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHggaWQ9ZDExcmNuIHRpdGxlPSdDb21tYSBzZXBlcmF0ZWQgbGlzdCBvZiBjZXJ0aWZpY2F0ZSBjb21tb24gbmFtZXMgdGhhdCB3aWxsIGJlIGFsbG93ZWQgdG8gY29ubmVjdCByZW1vdGVseS4nPjxpbnB1dCBpZD1kMTFfcmNuIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG9ua2V5dXA9c2hvd1NldFRsc1NlY3VyaXR5RGxnVXBkYXRlKCkgcGxhY2Vob2xkZXI9J25hbWUxLCBuYW1lMic+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+UmVtb3RlIENOJ3M8L2Rpdj48L2Rpdj4iOw0KDQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiVExTIFNldHRpbmdzIiwgMywgc2hvd1NldFRsc1NlY3VyaXR5RGxnT2ssIHgpOw0KDQogICAgICAgICAgICAvLyBTZWxlY3QgdGhlIGN1cnJlbnQgVExTIGNlcnRpZmljYXRlIGluIHRoZSBkcm9wIGRvd24gYm94DQogICAgICAgICAgICBpZiAoKHh4VExTQ3JlZGVudGlhbENvbnRleHQubGVuZ3RoID09IDApIHx8ICh4eFRsc1NldHRpbmdzWzBdWydFbmFibGVkJ10gPT0gZmFsc2UpIHx8ICh4eFRsc1NldHRpbmdzWzFdWydFbmFibGVkJ10gPT0gZmFsc2UpKSB7DQogICAgICAgICAgICAgICAgZ2V0U2VsZWN0RWxlbWVudCgndGxzY2VydCcpLnZhbHVlID0gLTE7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHZhciBjZXJ0SW5zdGFuY2VJZCA9IHh4VExTQ3JlZGVudGlhbENvbnRleHRbMF1bJ0VsZW1lbnRJbkNvbnRleHQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWydWYWx1ZSddOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhDZXJ0aWZpY2F0ZXMpIHsgaWYgKHh4Q2VydGlmaWNhdGVzW2ldWydJbnN0YW5jZUlEJ10gPT0gY2VydEluc3RhbmNlSWQpIHsgZ2V0U2VsZWN0RWxlbWVudCgndGxzY2VydCcpLnZhbHVlID0gaTsgfSB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIEZpZ3VyZSBvdXQgd2hhdCBpbmRleCBpcyBsb2NhbCAmIHJlbW90ZQ0KICAgICAgICAgICAgdmFyIGxvY2FsTmR4ID0gKCh4eFRsc1NldHRpbmdzWzBdWydJbnN0YW5jZUlEJ10gPT0gJ0ludGVsKHIpIEFNVCBMTVMgVExTIFNldHRpbmdzJykpID8gMCA6IDEsIHJlbW90ZU5keCA9ICgxIC0gbG9jYWxOZHgpOw0KDQogICAgICAgICAgICAvLyBTZWxlY3QgY29ycmVjdCBUTFMgb3B0aW9ucyBpbiB0aGUgZHJvcCBkb3duIGJveGVzDQogICAgICAgICAgICBnZXRTZWxlY3RFbGVtZW50KCd0bHNyZW1vdGUnKS52YWx1ZSA9ICgoeHhUbHNTZXR0aW5nc1tyZW1vdGVOZHhdWydNdXR1YWxBdXRoZW50aWNhdGlvbiddID09IHRydWUpID8gMiA6IDApICsgKCh4eFRsc1NldHRpbmdzW3JlbW90ZU5keF1bJ0FjY2VwdE5vblNlY3VyZUNvbm5lY3Rpb25zJ10gPT0gdHJ1ZSkgPyAxIDogMCk7DQogICAgICAgICAgICBpZiAoeHhUbHNTZXR0aW5nc1tyZW1vdGVOZHhdWydUcnVzdGVkQ04nXSkgeyBRKCdkMTFfcmNuJykudmFsdWUgPSBNYWtlVG9BcnJheSh4eFRsc1NldHRpbmdzW3JlbW90ZU5keF1bJ1RydXN0ZWRDTiddKS5qb2luKCcsICcpOyB9DQoNCiAgICAgICAgICAgIHNob3dTZXRUbHNTZWN1cml0eURsZ1VwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1NldFRsc1NlY3VyaXR5RGxnVXBkYXRlKCkgew0KICAgICAgICAgICAgdmFyIGggPSBnZXRTZWxlY3RFbGVtZW50KCd0bHNjZXJ0JykudmFsdWU7DQogICAgICAgICAgICBRRSgndGxzcmVtb3RlJywgaCAhPSAtMSk7DQogICAgICAgICAgICBRVignZDExcmNuJywgKGggIT0gLTEpICYmIChnZXRTZWxlY3RFbGVtZW50KCd0bHNyZW1vdGUnKS52YWx1ZSA+IDEpKTsNCiAgICAgICAgICAgIHZhciBvayA9IHRydWU7DQogICAgICAgICAgICBpZiAoKGdldFNlbGVjdEVsZW1lbnQoJ3Rsc3JlbW90ZScpLnZhbHVlID4gMSkgJiYgKCFzcGxpdERvbWFpbnMoUSgnZDExX3JjbicpLnZhbHVlKSkpIHsgb2sgPSBmYWxzZTsgfQ0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIHZhciBzZXRUbHNTZWN1cml0eVBlbmRpbmdDYWxsczsNCiAgICAgICAgdmFyIHNldFRsc1NlY3VyaXR5RGVsZXRlQ3JlZGVudGlhbENvbnRleHQ7DQogICAgICAgIGZ1bmN0aW9uIHNob3dTZXRUbHNTZWN1cml0eURsZ09rKCkgew0KICAgICAgICAgICAgdmFyIGggPSBnZXRTZWxlY3RFbGVtZW50KCd0bHNjZXJ0JykudmFsdWU7DQogICAgICAgICAgICB2YXIgciA9IGdldFNlbGVjdEVsZW1lbnQoJ3Rsc3JlbW90ZScpLnZhbHVlOw0KICAgICAgICAgICAgdmFyIHh4VGxzU2V0dGluZ3MyID0gQ2xvbmUoeHhUbHNTZXR0aW5ncyk7DQogICAgICAgICAgICBzZXRUbHNTZWN1cml0eVBlbmRpbmdDYWxscyA9IDA7DQogICAgICAgICAgICBzZXRUbHNTZWN1cml0eURlbGV0ZUNyZWRlbnRpYWxDb250ZXh0ID0gbnVsbDsNCg0KICAgICAgICAgICAgaWYgKGggIT0gLTEpIHsNCiAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIFRMUyBjZXJ0aWZpY2F0ZQ0KICAgICAgICAgICAgICAgIGlmICh4eFRMU0NyZWRlbnRpYWxDb250ZXh0Lmxlbmd0aCA+IDApIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gTW9kaWZ5IHRoZSBjdXJyZW50IGNvbnRleHQNCiAgICAgICAgICAgICAgICAgICAgdmFyIG5ld1RMU0NyZWRlbnRpYWxDb250ZXh0ID0gQ2xvbmUoeHhUTFNDcmVkZW50aWFsQ29udGV4dFswXSk7DQogICAgICAgICAgICAgICAgICAgIG5ld1RMU0NyZWRlbnRpYWxDb250ZXh0WydFbGVtZW50SW5Db250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVsnVmFsdWUnXSA9IHh4Q2VydGlmaWNhdGVzW2hdWydJbnN0YW5jZUlEJ107DQogICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLlB1dCgnQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0JywgbmV3VExTQ3JlZGVudGlhbENvbnRleHQsIHNldFRsc1NlY3VyaXR5UmVzcG9uc2UsIDAsIDEpOw0KICAgICAgICAgICAgICAgICAgICBzZXRUbHNTZWN1cml0eVBlbmRpbmdDYWxscysrOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIC8vIEFkZCBhIG5ldyBzZWN1cml0eSBjb250ZXh0DQogICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLkNyZWF0ZSgnQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0Jywgew0KICAgICAgICAgICAgICAgICAgICAgICAgJ0VsZW1lbnRJbkNvbnRleHQnOic8YTpBZGRyZXNzPi93c21hbjwvYTpBZGRyZXNzPjxhOlJlZmVyZW5jZVBhcmFtZXRlcnM+PHc6UmVzb3VyY2VVUkk+JyArIGFtdHN0YWNrLkNvbXBsZXRlTmFtZSgnQU1UX1B1YmxpY0tleUNlcnRpZmljYXRlJykgKyAnPC93OlJlc291cmNlVVJJPjx3OlNlbGVjdG9yU2V0Pjx3OlNlbGVjdG9yIE5hbWU9Ikluc3RhbmNlSUQiPicgKyB4eENlcnRpZmljYXRlc1toXVsnSW5zdGFuY2VJRCddICsgJzwvdzpTZWxlY3Rvcj48L3c6U2VsZWN0b3JTZXQ+PC9hOlJlZmVyZW5jZVBhcmFtZXRlcnM+JywNCiAgICAgICAgICAgICAgICAgICAgICAgICdFbGVtZW50UHJvdmlkaW5nQ29udGV4dCc6JzxhOkFkZHJlc3M+L3dzbWFuPC9hOkFkZHJlc3M+PGE6UmVmZXJlbmNlUGFyYW1ldGVycz48dzpSZXNvdXJjZVVSST4nICsgYW10c3RhY2suQ29tcGxldGVOYW1lKCdBTVRfVExTUHJvdG9jb2xFbmRwb2ludENvbGxlY3Rpb24nKSArICc8L3c6UmVzb3VyY2VVUkk+PHc6U2VsZWN0b3JTZXQ+PHc6U2VsZWN0b3IgTmFtZT0iRWxlbWVudE5hbWUiPlRMU1Byb3RvY29sRW5kcG9pbnRJbnN0YW5jZXMgQ29sbGVjdGlvbjwvdzpTZWxlY3Rvcj48L3c6U2VsZWN0b3JTZXQ+PC9hOlJlZmVyZW5jZVBhcmFtZXRlcnM+JyB9LCBzZXRUbHNTZWN1cml0eVJlc3BvbnNlKTsNCiAgICAgICAgICAgICAgICAgICAgc2V0VGxzU2VjdXJpdHlQZW5kaW5nQ2FsbHMrKzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIC8vIENsZWFyIHRoZSBUTFMgY2VydGlmaWNhdGUgYXNzb2NpYXRpb24gKE1PVkUgVEhJUykNCiAgICAgICAgICAgICAgICBpZiAoeHhUTFNDcmVkZW50aWFsQ29udGV4dC5sZW5ndGggPiAwKSB7IHNldFRsc1NlY3VyaXR5RGVsZXRlQ3JlZGVudGlhbENvbnRleHQgPSBDbG9uZSh4eFRMU0NyZWRlbnRpYWxDb250ZXh0WzBdKTsgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBGaWd1cmUgb3V0IHdoYXQgaW5kZXggaXMgbG9jYWwgJiByZW1vdGUNCiAgICAgICAgICAgIHZhciBsb2NhbE5keCA9ICgoeHhUbHNTZXR0aW5nc1swXVsnSW5zdGFuY2VJRCddID09ICdJbnRlbChyKSBBTVQgTE1TIFRMUyBTZXR0aW5ncycpKSA/IDAgOiAxLCByZW1vdGVOZHggPSAoMSAtIGxvY2FsTmR4KTsNCg0KICAgICAgICAgICAgLy8gUmVtb3RlIFRMUyBzZXR0aW5ncw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5nczJbcmVtb3RlTmR4XVsnRW5hYmxlZCddID0gKGggIT0gLTEpOw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5nczJbcmVtb3RlTmR4XVsnTXV0dWFsQXV0aGVudGljYXRpb24nXSA9IChyID49IDIpOw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5nczJbcmVtb3RlTmR4XVsnQWNjZXB0Tm9uU2VjdXJlQ29ubmVjdGlvbnMnXSA9ICgociAlIDIpID09IDEpOw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5nczJbcmVtb3RlTmR4XVsnVHJ1c3RlZENOJ10gPSBzcGxpdERvbWFpbnMoUSgnZDExX3JjbicpLnZhbHVlKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgLy8gTG9jYWwgVExTIHNldHRpbmdzDQogICAgICAgICAgICB4eFRsc1NldHRpbmdzMltsb2NhbE5keF1bJ0VuYWJsZWQnXSA9IChoICE9IC0xKTsNCg0KICAgICAgICAgICAgLy8gVXBkYXRlIFRMUyBzZXR0aW5ncw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfVExTU2V0dGluZ0RhdGEnLCB4eFRsc1NldHRpbmdzMlswXSwgc2V0VGxzU2VjdXJpdHlSZXNwb25zZSwgMCwgMSwgeHhUbHNTZXR0aW5nczJbMF0pOw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfVExTU2V0dGluZ0RhdGEnLCB4eFRsc1NldHRpbmdzMlsxXSwgc2V0VGxzU2VjdXJpdHlSZXNwb25zZSwgMCwgMSwgeHhUbHNTZXR0aW5nczJbMV0pOw0KICAgICAgICAgICAgc2V0VGxzU2VjdXJpdHlQZW5kaW5nQ2FsbHMgKz0gMjsNCg0KICAgICAgICAgICAgc3RhdHVzYm94KCJUTFMgU2V0dGluZ3MiLCAiQXBwbHlpbmcgbmV3IHNlY3VyaXR5IHNldHRpbmdzLi4uIik7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBTcGxpdCBhIHN0cmluZyBpbnRvIGEgYXJyYXkgb2YgZG9tYWlucy4gUmV0dXJuIG51bGwgaWYgbm90IGEgdmFsaWQgbGlzdC4NCiAgICAgICAgZnVuY3Rpb24gc3BsaXREb21haW5zKHN0cikgew0KICAgICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCcsJyk7DQogICAgICAgICAgICBpZiAoc3RyLmxlbmd0aCA9PSAwKSByZXR1cm47DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHN0cikgeyBzdHJbaV0gPSBzdHJbaV0udHJpbSgpOyBpZiAoKHN0cltpXS5pbmRleE9mKCcgJykgPj0gMCkgfHwgKHN0cltpXS5sZW5ndGggPT0gMCkpIHJldHVybjsgfQ0KICAgICAgICAgICAgaWYgKHN0ci5sZW5ndGggPiA0KSByZXR1cm47DQogICAgICAgICAgICByZXR1cm4gc3RyOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2V0VGxzU2VjdXJpdHlSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCIiLCAiRmFpbGVkIHRvIHNldCBUTFMgc2VjdXJpdHksIHN0YXR1cyA9ICIgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgIGlmIChyZXNwb25zZS5Cb2R5WydSZXR1cm5WYWx1ZVN0ciddICYmICFtZXRob2RjaGVjayhyZXNwb25zZSkpIHJldHVybjsNCg0KICAgICAgICAgICAgLy8gQ2hlY2sgaWYgYWxsIHRoZSBjYWxscyBhcmUgZG9uZQ0KICAgICAgICAgICAgaWYgKCgtLXNldFRsc1NlY3VyaXR5UGVuZGluZ0NhbGxzKSA9PSAwKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIC8vIFBlcmZvcm0gYSBjb21taXQNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9Db21taXRDaGFuZ2VzKG51bGwsIHNldFRsc1NlY3VyaXR5UmVzcG9uc2UyKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNldFRsc1NlY3VyaXR5UmVzcG9uc2UyKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCIiLCAiRmFpbGVkIHRvIHNldCBUTFMgc2VjdXJpdHksIHN0YXR1cyA9ICIgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgIC8vIGlmIChyZXNwb25zZS5Cb2R5WydSZXR1cm5WYWx1ZVN0ciddICYmICFtZXRob2RjaGVjayhyZXNwb25zZSkpIHJldHVybjsNCiAgICAgICAgICAgIHNldFRpbWVvdXQoc2V0VGxzU2VjdXJpdHlSZXNwb25zZTMsIDIwMDApOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2V0VGxzU2VjdXJpdHlSZXNwb25zZTMoKSB7DQogICAgICAgICAgICBpZiAoc2V0VGxzU2VjdXJpdHlEZWxldGVDcmVkZW50aWFsQ29udGV4dCAhPSBudWxsKSB7IGFtdHN0YWNrLkRlbGV0ZSgnQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0Jywgc2V0VGxzU2VjdXJpdHlEZWxldGVDcmVkZW50aWFsQ29udGV4dCwgZnVuY3Rpb24gKCkgeyB9KTsgfQ0KICAgICAgICAgICAgUHVsbENlcnRpZmljYXRlcygpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgpOw0KICAgICAgICB9DQoNCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gQUdFTlQgUFJFU0VOQ0UNCiAgICAgICAgLy8NCg0KICAgICAgICB2YXIgeHhXYXRjaGRvZyA9IG51bGw7DQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFdhdGNoZG9nKCkgew0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKG51bGwsIFsiKkFNVF9BZ2VudFByZXNlbmNlQ2FwYWJpbGl0aWVzIiwgIkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2ciLCAiQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ0FjdGlvbiIsICJBTVRfU3RhdGVUcmFuc2l0aW9uQ29uZGl0aW9uIiwgIkNJTV9Db25jcmV0ZURlcGVuZGVuY3kiXSwgUHVsbFdhdGNoZG9nUmVzcG9uc2UpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFdhdGNoZG9nUmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoKHN0YXR1cyA9PSAyMDApICYmIChyZXNwb25zZXNbJ0FNVF9BZ2VudFByZXNlbmNlQ2FwYWJpbGl0aWVzJ10uc3RhdHVzID09IDIwMCkpIHsNCiAgICAgICAgICAgICAgICB4eFdhdGNoZG9nID0gcmVzcG9uc2VzOw0KICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8gUGxhY2UgdGhlIGFjdGlvbnMgaW50byB0aGUgd2F0Y2hkb2dzIGZvciBlYXN5IG5hdmlnYXRpb24uDQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFdhdGNoZG9nWydDSU1fQ29uY3JldGVEZXBlbmRlbmN5J10ucmVzcG9uc2VzKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBsaW5rID0geHhXYXRjaGRvZ1snQ0lNX0NvbmNyZXRlRGVwZW5kZW5jeSddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHgxID0gZ2V0SXRlbShsaW5rWydBbnRlY2VkZW50J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXSwgJ0BOYW1lJywgJ0NyZWF0aW9uQ2xhc3NOYW1lJyk7DQogICAgICAgICAgICAgICAgICAgIGlmICh4MSAmJiB4MVsnVmFsdWUnXSA9PSAnQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZycpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZXZpY2VpZCA9IGdldEl0ZW0obGlua1snQW50ZWNlZGVudCddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10sICdATmFtZScsICdEZXZpY2VJRCcpWydWYWx1ZSddOw0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvbGljeUNvbmRpdGlvbk5hbWUgPSBnZXRJdGVtKGxpbmtbJ0RlcGVuZGVudCddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10sICdATmFtZScsICdQb2xpY3lDb25kaXRpb25OYW1lJylbJ1ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2F0Y2hkb2cgPSBnZXRJdGVtKHh4V2F0Y2hkb2dbJ0FNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2cnXS5yZXNwb25zZXMsICdEZXZpY2VJRCcsIGRldmljZWlkKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0cmFuc2l0aW9uUG9saWN5ID0gZ2V0SXRlbSh4eFdhdGNoZG9nWydBTVRfU3RhdGVUcmFuc2l0aW9uQ29uZGl0aW9uJ10ucmVzcG9uc2VzLCAnUG9saWN5Q29uZGl0aW9uTmFtZScsIHBvbGljeUNvbmRpdGlvbk5hbWUpOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF3YXRjaGRvZy50cmFuc2l0aW9ucykgd2F0Y2hkb2cudHJhbnNpdGlvbnMgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHdhdGNoZG9nLnRyYW5zaXRpb25zLnB1c2godHJhbnNpdGlvblBvbGljeSk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKHgxICYmIHgxWydWYWx1ZSddID09ICdBTVRfU3RhdGVUcmFuc2l0aW9uQ29uZGl0aW9uJykgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvbGljeUNvbmRpdGlvbk5hbWUgPSBnZXRJdGVtKGxpbmtbJ0FudGVjZWRlbnQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddLCAnQE5hbWUnLCAnUG9saWN5Q29uZGl0aW9uTmFtZScpWydWYWx1ZSddOw0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvbGljeUFjdGlvbk5hbWUgPSBnZXRJdGVtKGxpbmtbJ0RlcGVuZGVudCddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10sICdATmFtZScsICdQb2xpY3lBY3Rpb25OYW1lJylbJ1ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhbnNpdGlvblBvbGljeSA9IGdldEl0ZW0oeHhXYXRjaGRvZ1snQU1UX1N0YXRlVHJhbnNpdGlvbkNvbmRpdGlvbiddLnJlc3BvbnNlcywgJ1BvbGljeUNvbmRpdGlvbk5hbWUnLCBwb2xpY3lDb25kaXRpb25OYW1lKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3YXRjaGRvZ0FjdGlvbiA9IGdldEl0ZW0oeHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ0FjdGlvbiddLnJlc3BvbnNlcywgJ1BvbGljeUFjdGlvbk5hbWUnLCBwb2xpY3lBY3Rpb25OYW1lKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdHJhbnNpdGlvblBvbGljeS5hY3Rpb25zKSB0cmFuc2l0aW9uUG9saWN5LmFjdGlvbnMgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zaXRpb25Qb2xpY3kuYWN0aW9ucy5wdXNoKHdhdGNoZG9nQWN0aW9uKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIHVwZGF0ZVdhdGNoZG9nKCk7DQogICAgICAgICAgICAgICAgUVYoJ2dvMTknLCB0cnVlKTsgLy8gU2hvdyBBZ2VudCBQcmVzZW5jZSBwYW5lbA0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIHdhdGNoZG9nRW5hYmxlZFN0YXRlcyA9IFsgJ1Vua25vd24nLCAnT3RoZXInLCAnRW5hYmxlZCcsICdEaXNhYmxlZCcsICdTaHV0dGluZyBEb3duJywgJ05vdCBBcHBsaWNhYmxlJywgJ0VuYWJsZWQgYnV0IE9mZmxpbmUnLCAnSW4gVGVzdCcsICdEZWZlcnJlZCcsICdRdWllc2NlJywgJ1N0YXJ0aW5nJyBdOw0KICAgICAgICB2YXIgd2F0Y2hkb2dNb25pdG9yZWRFbnRpdHkgPSBbICdVbmtub3duJywgJ090aGVyJywgJ09wZXJhdGluZyBTeXN0ZW0nLCAnT3BlcmF0aW5nIFN5c3RlbSBCb290IFByb2Nlc3MnLCAnT3BlcmF0aW5nIFN5c3RlbSBTaHV0ZG93biBQcm9jZXNzJywgJ0Zpcm13YXJlIEJvb3QgUHJvY2VzcycsICdCSU9TIEJvb3QgUHJvY2VzcycsICdBcHBsaWNhdGlvbicsICdTZXJ2aWNlIFByb2Nlc3NvcicgXTsNCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlV2F0Y2hkb2coKSB7DQogICAgICAgICAgICBpZiAoeHhXYXRjaGRvZyA9PSBudWxsKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9ICcnOw0KDQogICAgICAgICAgICAvLyBHbG9iYWwgQWdlbnQgUHJlc2Vuc2UgVmFsdWVzDQogICAgICAgICAgICB4ICs9IFRhYmxlU3RhcnQoKTsNCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiTWF4aW11bSBXYXRjaGRvZ3MiLCB4eFdhdGNoZG9nWydBTVRfQWdlbnRQcmVzZW5jZUNhcGFiaWxpdGllcyddLnJlc3BvbnNlWydNYXhUb3RhbEFnZW50cyddICsgIiB3YXRjaGRvZ3MiKTsNCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiTWF4aW11bSBUb3RhbCBBY3Rpb25zIiwgeHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VDYXBhYmlsaXRpZXMnXS5yZXNwb25zZVsnTWF4VG90YWxBY3Rpb25zJ10gKyAiIGFjdGlvbnMiKTsNCiAgICAgICAgICAgIC8vIHggKz0gVGFibGVFbnRyeSgiTWF4aW11bSBFQUMgV2F0Y2hkb2dzIiwgeHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VDYXBhYmlsaXRpZXMnXS5yZXNwb25zZVsnTWF4RWFjQWdlbnRzJ10gKyAiIHdhdGNoZG9ncyIpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpICsgIjxicj4iOw0KDQogICAgICAgICAgICAvLyBXYXRjaGRvZ3MNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCBhZ2VudCBwcmVzZW5jZSB3YXRjaGRvZ3MuPGJyPjxicj4iOw0KICAgICAgICAgICAgaWYgKCh4eFdhdGNoZG9nWydBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nJ10ucmVzcG9uc2VzID09IG51bGwpIHx8ICh4eFdhdGNoZG9nWydBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nJ10ucmVzcG9uc2VzLmxlbmd0aCA9PSAwKSkgew0KICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGk+Tm8gYWdlbnQgcHJlc2VuY2Ugd2F0Y2hkb2cgZm91bmQuPC9pPjwvZGl2Pjxicj4iOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4V2F0Y2hkb2dbJ0FNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2cnXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHcgPSB4eFdhdGNoZG9nWydBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nJ10ucmVzcG9uc2VzW2ldOw0KICAgICAgICAgICAgICAgICAgICB2YXIgbiA9IGd1aWRUb1N0cihyc3RyMmhleChhdG9iKHdbJ0RldmljZUlEJ10pKSk7DQogICAgICAgICAgICAgICAgICAgIGlmICh3WydNb25pdG9yZWRFbnRpdHlEZXNjcmlwdGlvbiddICYmIHdbJ01vbml0b3JlZEVudGl0eURlc2NyaXB0aW9uJ10gIT0gJycpIG4gPSBFc2NhcGVIdG1sKHdbJ01vbml0b3JlZEVudGl0eURlc2NyaXB0aW9uJ10pOw0KICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93V2F0Y2hkb2dEZXRhaWxzKCIgKyBpICsgIik+PGlucHV0IHR5cGU9YnV0dG9uIHN0eWxlPWZsb2F0OnJpZ2h0IHZhbHVlPSdBZGQgQWN0aW9uLi4uJyBvbmNsaWNrPWFkZFdhdGNoZG9nQWN0aW9uKGV2ZW50LCIgKyBpICsgIik+IjsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHcudHJhbnNpdGlvbnMpIHsgeCArPSAiPGlucHV0IHR5cGU9YnV0dG9uIHN0eWxlPWZsb2F0OnJpZ2h0IHZhbHVlPSdEZWxldGUgQWN0aW9ucy4uLicgb25jbGljaz1kZWxldGVXYXRjaGRvZ0FjdGlvbnMoZXZlbnQsIiArIGkgKyAiKT4iOyB9DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyBuICsgIjwvYj4sICIgKyBhbXRzdGFjay5XYXRjaGRvZ0N1cnJlbnRTdGF0ZXNbd1snQ3VycmVudFN0YXRlJ11dICsgIjwvZGl2PiI7DQogICAgICAgICAgICAgICAgICAgIHZhciB4eCA9ICcnOw0KICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqIGluIHcudHJhbnNpdGlvbnMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0ID0gdy50cmFuc2l0aW9uc1tqXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4eCAhPSAnJykgeHggKz0gIjxicj4iOw0KICAgICAgICAgICAgICAgICAgICAgICAgeHggKz0gZ2V0V2F0Y2hkb2dUcmFuc2l0aW9uU3RyKHRbJ09sZFN0YXRlJ10pICsgIiAmcmFycjsgIiArIGdldFdhdGNoZG9nVHJhbnNpdGlvblN0cih0WydOZXdTdGF0ZSddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0LmFjdGlvbnMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWN0aW9uID0gdC5hY3Rpb25zWzBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhY3Rpb25bJ0V2ZW50T25UcmFuc2l0aW9uJ10gPT0gdHJ1ZSkgeyB4eCArPSAiIDogRXZlbnQgdG8gbG9nIjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGlmICh4eCAhPSAnJykgeyB4ICs9ICI8ZGl2IHN0eWxlPXBhZGRpbmc6MTJweD4iICsgeHggKyAiPC9kaXY+IjsgfQ0KICAgICAgICAgICAgICAgICAgICB4ICs9ICI8L2Rpdj4iOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZChBZGRSZWZyZXNoQnV0dG9uKCJQdWxsV2F0Y2hkb2coKSIpICsgQWRkQnV0dG9uKCJBZGQgV2F0Y2hkb2cuLi4iLCAiQWRkV2F0Y2hkb2coKSIpKTsNCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KDQogICAgICAgICAgICBRSCgnaWRfVGFibGVTeXN0ZW1BZ2VudFByZXNlbmNlJywgeCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBnZXRXYXRjaGRvZ1RyYW5zaXRpb25TdHIocykgew0KICAgICAgICAgICAgaWYgKHMgPT0gMzEpIHJldHVybiAiQW55IFN0YXRlIjsNCiAgICAgICAgICAgIHZhciB4ID0gJyc7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGFtdHN0YWNrLldhdGNoZG9nQ3VycmVudFN0YXRlcykgeyBpZiAoKHMgJiBpKSAhPSAwKSB7IHggKz0gJywgJyArIGFtdHN0YWNrLldhdGNoZG9nQ3VycmVudFN0YXRlc1tpXTsgfSB9DQogICAgICAgICAgICByZXR1cm4geC5zdWJzdHJpbmcoMik7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93V2F0Y2hkb2dEZXRhaWxzKGkpIHsNCiAgICAgICAgICAgIHZhciB3ID0geHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZyddLnJlc3BvbnNlc1tpXTsNCg0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIC8veCArPSBhZGRIdG1sVmFsdWUoJ0RldmljZUlEJywgZ3VpZFRvU3RyKHJzdHIyaGV4KGF0b2Iod1snRGV2aWNlSUQnXSkpKSk7DQogICAgICAgICAgICBpZiAod1snTW9uaXRvcmVkRW50aXR5RGVzY3JpcHRpb24nXSAmJiB3WydNb25pdG9yZWRFbnRpdHlEZXNjcmlwdGlvbiddICE9ICcnKSB4ICs9IGFkZEh0bWxWYWx1ZSgnRGVzY3JpcHRpb24nLCBFc2NhcGVIdG1sKHdbJ01vbml0b3JlZEVudGl0eURlc2NyaXB0aW9uJ10pKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdNb25pdG9yZWQgRW50aXR5Jywgd2F0Y2hkb2dNb25pdG9yZWRFbnRpdHlbd1snTW9uaXRvcmVkRW50aXR5J11dKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdDdXJyZW50IFN0YXRlJywgYW10c3RhY2suV2F0Y2hkb2dDdXJyZW50U3RhdGVzW3dbJ0N1cnJlbnRTdGF0ZSddXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnRW5hYmxlZCBTdGF0ZScsIHdhdGNoZG9nRW5hYmxlZFN0YXRlc1t3WydFbmFibGVkU3RhdGUnXV0pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ1N0YXJ0dXAgSW50ZXJ2YWwnLCB3WydTdGFydHVwSW50ZXJ2YWwnXSArICcgc2Vjb25kKHMpJyk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnVGltZW91dCBJbnRlcnZhbCcsIHdbJ1RpbWVvdXRJbnRlcnZhbCddICsgJyBzZWNvbmQocyknKTsNCg0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ1dhdGNoZG9nICcgKyBndWlkVG9TdHIocnN0cjJoZXgoYXRvYih3WydEZXZpY2VJRCddKSkpLCA1LCBzaG93V2F0Y2hkb2dEZXRhaWxzT2ssIHgsIHcpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1dhdGNoZG9nRGV0YWlsc09rKHgsIHcpIHsNCiAgICAgICAgICAgIGlmICh4ID09IDIpIHsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5EZWxldGUoJ0FNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2cnLCB7ICdEZXZpY2VJRCc6IHdbJ0RldmljZUlEJ10gfSwgUHVsbFdhdGNoZG9nKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZFdhdGNoZG9nKCkgew0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPXdnbmFtZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweCBtYXhsZW5ndGg9MTYgb25rZXl1cD1BZGRXYXRjaGRvZ1VwZGF0ZSgpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4Pk5hbWU8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48aW5wdXQgaWQ9d2dndWlkIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI0MHB4IG1heGxlbmd0aD0zNiBvbmtleXVwPUFkZFdhdGNoZG9nVXBkYXRlKCk+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHggdGl0bGU9J0dlbmVyYXRlIHJhbmRvbSBEZXZpY2VJRCc+IiArIGFkZExpbmsoIkRldmljZUlEIiwgIkdlbmVyYXRlV2F0Y2hkb2dHdWlkKCkiKSArICI8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48aW5wdXQgaWQ9d2dzdGFydCBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweCBtYXhsZW5ndGg9OCBwbGFjZWhvbGRlcj0zNjAwIG9ua2V5dXA9QWRkV2F0Y2hkb2dVcGRhdGUoKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5TdGFydHVwIChzZWNvbmRzKTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxpbnB1dCBpZD13Z3RpbWVvdXQgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjQwcHggbWF4bGVuZ3RoPTggcGxhY2Vob2xkZXI9NjAgb25rZXl1cD1BZGRXYXRjaGRvZ1VwZGF0ZSgpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PlRpbWVvdXQgKHNlY29uZHMpPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdBZGQgV2F0Y2hkb2cnLCAzLCBBZGRXYXRjaGRvZ09rLCB4KTsNCiAgICAgICAgICAgIEFkZFdhdGNoZG9nVXBkYXRlKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBHZW5lcmF0ZVdhdGNoZG9nR3VpZCgpIHsNCiAgICAgICAgICAgIHZhciBpLCBndWlkID0gJyc7DQogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgeyBndWlkICs9IFN0cmluZy5mcm9tQ2hhckNvZGUocmFuZG9tKDI1NSkpOyB9DQogICAgICAgICAgICBRKCd3Z2d1aWQnKS52YWx1ZSA9IGd1aWRUb1N0cihyc3RyMmhleChndWlkKSk7DQogICAgICAgICAgICBBZGRXYXRjaGRvZ1VwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkV2F0Y2hkb2dVcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgb2sgPSAoUSgnd2dzdGFydCcpLnZhbHVlID09ICcnIHx8IHBhcnNlSW50KFEoJ3dnc3RhcnQnKS52YWx1ZSkgPiAwKSAmJiAoUSgnd2d0aW1lb3V0JykudmFsdWUgPT0gJycgfHwgcGFyc2VJbnQoUSgnd2d0aW1lb3V0JykudmFsdWUpID4gMCk7DQogICAgICAgICAgICB2YXIgZ2MgPSAwLCBnID0gUSgnd2dndWlkJykudmFsdWUudG9Mb3dlckNhc2UoKTsNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZy5sZW5ndGg7IGkrKykgew0KICAgICAgICAgICAgICAgIHZhciBjID0gZy5jaGFyQ29kZUF0KGkpOw0KICAgICAgICAgICAgICAgIGlmIChjID09IDQ1KSBjb250aW51ZTsNCiAgICAgICAgICAgICAgICBpZiAoKGMgPj0gNDggJiYgYyA8PSA1NykgfHwgKGMgPj0gOTcgJiYgYyA8PSAxMDIpKSB7IGdjKys7IH0gZWxzZSB7IG9rID0gZmFsc2U7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChnYyAhPSAzMikgb2sgPSBmYWxzZTsNCiAgICAgICAgICAgIFFFKCdkbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZFdhdGNoZG9nT2soKSB7DQogICAgICAgICAgICB2YXIgdGltZW91dCA9IFEoJ3dndGltZW91dCcpLnZhbHVlLCBzdGFydHVwID0gUSgnd2dzdGFydCcpLnZhbHVlOw0KICAgICAgICAgICAgaWYgKHRpbWVvdXQgPT0gJycpIHRpbWVvdXQgPSA2MDsNCiAgICAgICAgICAgIGlmIChzdGFydHVwID09ICcnKSBzdGFydHVwID0gMzYwMDsNCiAgICAgICAgICAgIHZhciBndWlkID0gYnRvYShoZXgycnN0cihndWlkVG9TdHIoUSgnd2dndWlkJykudmFsdWUucmVwbGFjZSgvLS9nLCAnJykpLnJlcGxhY2UoLy0vZywgJycpKSk7DQogICAgICAgICAgICB2YXIgd2RvZyA9IHsgJ0NyZWF0aW9uQ2xhc3NOYW1lJzogMCwgJ0RldmljZUlEJzogZ3VpZCwgJ1N0YXJ0dXBJbnRlcnZhbCc6IHN0YXJ0dXAsICdTeXN0ZW1DcmVhdGlvbkNsYXNzTmFtZSc6IDAsICdTeXN0ZW1OYW1lJzogMCwgJ1RpbWVvdXRJbnRlcnZhbCc6IHRpbWVvdXQsICdNb25pdG9yZWRFbnRpdHlEZXNjcmlwdGlvbic6IFEoJ3dnbmFtZScpLnZhbHVlIH07DQogICAgICAgICAgICBhbXRzdGFjay5DcmVhdGUoJ0FNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2cnLCB3ZG9nLCBBZGRXYXRjaGRvZ09rMik7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRXYXRjaGRvZ09rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnV2F0Y2hkb2cnLCAiVW5hYmxlIHRvIGFkZCB3YXRjaGRvZywgZXJyb3IgIyIgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsV2F0Y2hkb2coKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZFdhdGNoZG9nQWN0aW9uKGUsIGkpIHsNCiAgICAgICAgICAgIHZhciB3ID0geHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZyddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgIHZhciB4ID0gJzx0YWJsZT4nOw0KICAgICAgICAgICAgeCArPSAnPHRkIHN0eWxlPXdpZHRoOjE4MHB4PkZyb208YnI+Jw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBhbXRzdGFjay5XYXRjaGRvZ0N1cnJlbnRTdGF0ZXMpIHsNCiAgICAgICAgICAgICAgICB4ICs9ICc8aW5wdXQgaWQ9d2dzYScgKyBpICsgJyB0eXBlPWNoZWNrYm94IG9uY2xpY2s9YWRkV2F0Y2hkb2dBY3Rpb25VcGRhdGUoKT4gJyArIGFtdHN0YWNrLldhdGNoZG9nQ3VycmVudFN0YXRlc1tpXSArICc8YnIgLz4nOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSAnPHRkPlRvPGJyPicNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYW10c3RhY2suV2F0Y2hkb2dDdXJyZW50U3RhdGVzKSB7DQogICAgICAgICAgICAgICAgeCArPSAnPGlucHV0IGlkPXdnc2InICsgaSArICcgdHlwZT1jaGVja2JveCBvbmNsaWNrPWFkZFdhdGNoZG9nQWN0aW9uVXBkYXRlKCk+ICcgKyBhbXRzdGFjay5XYXRjaGRvZ0N1cnJlbnRTdGF0ZXNbaV0gKyAnPGJyIC8+JzsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gJzwvdGFibGU+PGJyPlBlcmZvcm0gQWN0aW9uPGJyPjxpbnB1dCBpZD13Z3NldmVudCB0eXBlPWNoZWNrYm94IGNoZWNrZWQgb25jbGljaz1hZGRXYXRjaGRvZ0FjdGlvblVwZGF0ZSgpPldyaXRlIHRvIGV2ZW50IGxvZzxiciAvPic7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnQWRkIFdhdGNoZG9nIEFjdGlvbicsIDMsIGFkZFdhdGNoZG9nQWN0aW9uT2ssIHgsIHcpOw0KICAgICAgICAgICAgYWRkV2F0Y2hkb2dBY3Rpb25VcGRhdGUoKTsNCiAgICAgICAgICAgIGhhbHRFdmVudChlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZFdhdGNoZG9nQWN0aW9uVXBkYXRlKCkgew0KICAgICAgICAgICAgdmFyIHRmcm9tID0gMCwgdHRvID0gMDsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYW10c3RhY2suV2F0Y2hkb2dDdXJyZW50U3RhdGVzKSB7DQogICAgICAgICAgICAgICAgaWYgKFEoJ3dnc2EnICsgaSkuY2hlY2tlZCA9PSB0cnVlKSB0ZnJvbSArPSBwYXJzZUludChpKTsNCiAgICAgICAgICAgICAgICBpZiAoUSgnd2dzYicgKyBpKS5jaGVja2VkID09IHRydWUpIHR0byArPSBwYXJzZUludChpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIFFFKCdkbGdPa0J1dHRvbicsIHRmcm9tID4gMCAmJiB0dG8gPiAwICYmIFEoJ3dnc2V2ZW50JykuY2hlY2tlZCA9PSB0cnVlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZFdhdGNoZG9nQWN0aW9uT2soYiwgdykgew0KICAgICAgICAgICAgdmFyIHRmcm9tID0gMCwgdHRvID0gMDsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYW10c3RhY2suV2F0Y2hkb2dDdXJyZW50U3RhdGVzKSB7DQogICAgICAgICAgICAgICAgaWYgKFEoJ3dnc2EnICsgaSkuY2hlY2tlZCA9PSB0cnVlKSB0ZnJvbSArPSBwYXJzZUludChpKTsNCiAgICAgICAgICAgICAgICBpZiAoUSgnd2dzYicgKyBpKS5jaGVja2VkID09IHRydWUpIHR0byArPSBwYXJzZUludChpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2dfQWRkQWN0aW9uKHRmcm9tLCB0dG8sIFEoJ3dnc2V2ZW50JykuY2hlY2tlZCwgbnVsbCwgbnVsbCwgQWRkV2F0Y2hkb2dBY3Rpb25SZXNwb25zZSwgbnVsbCwgMCwgeyAnRGV2aWNlSUQnOiB3WydEZXZpY2VJRCddIH0pOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkV2F0Y2hkb2dBY3Rpb25SZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnV2F0Y2hkb2cgQWN0aW9uJywgIlVuYWJsZSB0byBhZGQgd2F0Y2hkb2cgYWN0aW9uLCBlcnJvciAjIiArIHN0YXR1cyk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFB1bGxXYXRjaGRvZygpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGVsZXRlV2F0Y2hkb2dBY3Rpb25zKGUsIGkpIHsNCiAgICAgICAgICAgIHZhciB3ID0geHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZyddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdEZWxldGUgV2F0Y2hkb2cgQWN0aW9ucycsIDMsIGRlbGV0ZVdhdGNoZG9nQWN0aW9uc09rLCAiRGVsZXRlIGFsbCBhY3Rpb25zIGZvciB0aGlzIHdhdGNoZG9nPyIsIHcpOw0KICAgICAgICAgICAgaGFsdEV2ZW50KGUpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGVsZXRlV2F0Y2hkb2dBY3Rpb25zT2soYiwgdykgew0KICAgICAgICAgICAgYW10c3RhY2suQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ19EZWxldGVBbGxBY3Rpb25zKGRlbGV0ZVdhdGNoZG9nQWN0aW9uUmVzcG9uc2UsIG51bGwsIDAsIHsgJ0RldmljZUlEJzogd1snRGV2aWNlSUQnXSB9KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGRlbGV0ZVdhdGNoZG9nQWN0aW9uUmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goJ1dhdGNoZG9nIEFjdGlvbicsICJVbmFibGUgdG8gcmVtb3ZlIHdhdGNoZG9nIGFjdGlvbnMsIGVycm9yICMiICsgc3RhdHVzKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgUHVsbFdhdGNoZG9nKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICANCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIFNZU1RFTSBERUZFTlNFIFBBTkVMDQogICAgICAgIC8vDQoNCiAgICAgICAgdmFyIHh4U3lzdGVtRGVmZW5zZSA9IG51bGw7DQogICAgICAgIHZhciB4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3kgPSB7fTsNCiAgICAgICAgdmFyIHh4VXBkYXRpbmdEZWZlbnNlU3RhdHMgPSBmYWxzZTsNCiAgICAgICAgdmFyIHh4RmlsdGVyU3RhdGlzdGljcyA9IFt7fSwge31dOyAvLyBXaXJlZCBhbmQgd2lyZWxlc3MgaW50ZXJmYWNlIHN0YXRzDQogICAgICAgIHZhciB4eEZpbHRlclN0YXRpc3RpY3NUaW1lciA9IG51bGw7DQogICAgICAgIHZhciB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9IGZhbHNlOw0KDQogICAgICAgIHZhciB4eFN5c3RlbURlZmVuY2VGaWx0ZXJFdGhlcm5ldFR5cGVzID0geyAyMDQ4OiAnQWxsIElQIFBhY2tldHMnLCAyMDU0OiAnQWxsIEFSUCBQYWNrZXRzJyB9Ow0KICAgICAgICB2YXIgeHhTeXN0ZW1EZWZlbmNlRmlsdGVySVBUeXBlcyA9IHsgNDogJ0lQdjQnLCA2OiAnSVB2NicgfTsNCiAgICAgICAgdmFyIHh4U3lzdGVtRGVmZW5jZUZpbHRlckRlc2MgPSB7IDA6ICdBbGxvdywgQ291bnQnLCAxOiAnRHJvcCwgQ291bnQnLCAyOiAnUmF0ZSBsaW1pdCcsIDM6ICdBbGxvdycsIDQ6ICdEcm9wJyB9Ow0KICAgICAgICB2YXIgeHhTeXN0ZW1EZWZlbmNlRmlsdGVycyA9IHsgJ0hkclByb3RvY29sSUQnOiAxLCAnSGRyRGVzdEFkZHJlc3MnOiAyLCAnSGRyRGVzdE1hc2snOiAyLCAnSGRyU3JjQWRkcmVzcyc6IDIsICdIZHJTcmNNYXNrJzogMiwgJ0hkclNyY1BvcnRTdGFydCc6IDEsICdIZHJTcmNQb3J0RW5kJzogMSwgJ0hkckRlc3RQb3J0U3RhcnQnOiAxLCAnSGRyRGVzdFBvcnRFbmQnOiAxLCAnSGRyU3JjQWRkcmVzc0VuZE9mUmFuZ2UnOiAyLCAnSGRyRGVzdEFkZHJlc3NFbmRPZlJhbmdlICc6IDIsICdUQ1BGbGFnc09uJzogMywgJ1RDUEZsYWdzT2ZmJzogMyB9Ow0KDQogICAgICAgIGZ1bmN0aW9uIFB1bGxTeXN0ZW1EZWZlbnNlKCkgew0KICAgICAgICAgICAgYW10Rmlyc3RQdWxsIHw9IDQ7DQogICAgICAgICAgICBhbXRzdGFjay5CYXRjaEVudW0obnVsbCwgWyJBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSIsICJBTVRfTmV0d29ya1BvcnRTeXN0ZW1EZWZlbnNlUG9saWN5IiwgIkFNVF9IZHI4MDIxRmlsdGVyIiwgIkFNVF9JUEhlYWRlcnNGaWx0ZXIiLCAiQU1UX05ldHdvcmtGaWx0ZXIiXSwgUHVsbFN5c3RlbURlZmVuc2VSZXNwb25zZSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBQdWxsU3lzdGVtRGVmZW5zZVJlc3BvbnNlKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsNCiAgICAgICAgICAgICAgICB4eFN5c3RlbURlZmVuc2UgPSByZXNwb25zZXM7DQogICAgICAgICAgICAgICAgdXBkYXRlU3lzdGVtRGVmZW5zZSgpOw0KICAgICAgICAgICAgICAgIFFWKCdnbzE4JywgdHJ1ZSk7IC8vIFNob3cgU3lzdGVtIERlZmVuc2UgUGFuZWwNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVN5c3RlbURlZmVuc2UoKSB7DQogICAgICAgICAgICBpZiAoeHhTeXN0ZW1EZWZlbnNlID09IG51bGwpIHJldHVybjsNCiAgICAgICAgICAgIHZhciB4ID0gJyc7DQoNCiAgICAgICAgICAgIC8vIEdldCBhY3RpdmUgcG9saWNpZXMNCiAgICAgICAgICAgIHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeSA9IHt9Ow0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFN5c3RlbURlZmVuc2VbJ0FNVF9OZXR3b3JrUG9ydFN5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICB2YXIgbGluayA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX05ldHdvcmtQb3J0U3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICB2YXIgYSA9ICtnZXRJdGVtKGxpbmtbJ0FudGVjZWRlbnQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddLCAnQE5hbWUnLCAnRGV2aWNlSUQnKVsnVmFsdWUnXS5zdWJzdHJpbmcoMjcpOw0KICAgICAgICAgICAgICAgIHZhciBiID0gbGlua1snRGVwZW5kZW50J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVsnVmFsdWUnXTsNCiAgICAgICAgICAgICAgICB2YXIgcCA9IGdldEl0ZW0oeHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlcywgJ0luc3RhbmNlSUQnLCBiKTsNCiAgICAgICAgICAgICAgICB4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3lbYV0gPSBwOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBHbG9iYWwgU3lzdGVtIERlZmVuc2Ugc2V0dGluZ3MNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgdmFyIHBvbGljeW5hbWUgPSAnPGk+Tm9uZTwvaT4nOw0KICAgICAgICAgICAgaWYgKHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeVswXSkgeyBwb2xpY3luYW1lID0geHhTeXN0ZW1EZWZlbmNlTGlua2VkUG9saWN5WzBdWydQb2xpY3lOYW1lJ107IH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiRGVmYXVsdCBXaXJlZCBQb2xpY3kiLCBhZGRMaW5rKHBvbGljeW5hbWUsICdjaGFuZ2VEZWZhdWx0UG9saWN5KDApJykpOw0KICAgICAgICAgICAgLyoNCiAgICAgICAgICAgIHBvbGljeW5hbWUgPSAnPGk+Tm9uZTwvaT4nOw0KICAgICAgICAgICAgaWYgKHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeVsxXSkgeyBwb2xpY3luYW1lID0geHhTeXN0ZW1EZWZlbmNlTGlua2VkUG9saWN5WzFdWydQb2xpY3lOYW1lJ107IH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiRGVmYXVsdCBXaXJlbGVzcyBQb2xpY3kiLCBhZGRMaW5rKHBvbGljeW5hbWUsICdjaGFuZ2VEZWZhdWx0UG9saWN5KDEpJykpOw0KICAgICAgICAgICAgKi8NCg0KICAgICAgICAgICAgLy8gRmlsdGVyIFN0YXRpc3RpY3MNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjsgaSsrKSB7DQogICAgICAgICAgICAgICAgdmFyIGYgPSB4eEZpbHRlclN0YXRpc3RpY3NbaV07DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaiBpbiBmKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBjID0gZltqXTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT0gMSkgYyArPSAnIHBhY2tldCc7IGVsc2UgYyArPSAnIHBhY2tldHMnOw0KICAgICAgICAgICAgICAgICAgICB2YXIgam4gPSAoKGk9PTApPydXaXJlZCAnOidXaXJlbGVzcyAnKSArIGo7DQogICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeShqbiwgYyk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgeCArPSAiPGJyPiI7DQoNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg7Ym9yZGVyOjA+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCBzeXN0ZW0gZGVmZW5zZSBwb2xpY2llcy48YnI+PGJyPiI7DQogICAgICAgICAgICBpZiAoeHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlcy5sZW5ndGggPT0gMCkgew0KICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGk+Tm8gc3lzdGVtIGRlZmVuc2UgcG9saWNpZXMgZm91bmQuPC9pPjwvZGl2Pjxicj4iOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4U3lzdGVtRGVmZW5zZVsnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHBvbGljeSA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgICAgIHZhciBkZXNjID0gJyc7DQogICAgICAgICAgICAgICAgICAgIGlmIChwb2xpY3lbJ0ZpbHRlckNyZWF0aW9uSGFuZGxlcyddKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBwb2xpY3lbJ0ZpbHRlckNyZWF0aW9uSGFuZGxlcyddID0gTWFrZVRvQXJyYXkocG9saWN5WydGaWx0ZXJDcmVhdGlvbkhhbmRsZXMnXSk7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IHBvbGljeVsnRmlsdGVyQ3JlYXRpb25IYW5kbGVzJ10ubGVuZ3RoOw0KICAgICAgICAgICAgICAgICAgICAgICAgZGVzYyA9ICcsICcgKyBjICsgJyBmaWx0ZXInICsgKGMgPiAxPydzJzonJyk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIG9uY2xpY2s9c2hvd1BvbGljeURldGFpbHMoIiArIGkgKyAiKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48Yj4iICsgRXNjYXBlSHRtbChwb2xpY3lbJ1BvbGljeU5hbWUnXSkgKyAiPC9iPiIgKyBkZXNjICsgIjwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICB4ICs9ICI8dHI+PHRkIGNsYXNzPXIxIHN0eWxlPXBhZGRpbmctbGVmdDoxNXB4Pjxicj5NYW5hZ2UgSW50ZWwmcmVnOyBBTVQgc3lzdGVtIGRlZmVuc2UgZmlsdGVycy48YnI+PGJyPiI7DQogICAgICAgICAgICBpZiAoeHhTeXN0ZW1EZWZlbnNlWydBTVRfSGRyODAyMUZpbHRlciddLnJlc3BvbnNlcy5sZW5ndGggPT0gMCAmJiB4eFN5c3RlbURlZmVuc2VbJ0FNVF9JUEhlYWRlcnNGaWx0ZXInXS5yZXNwb25zZXMubGVuZ3RoID09IDApIHsNCiAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPXBhZGRpbmctbGVmdDoxNXB4PjxpPk5vIHN5c3RlbSBkZWZlbnNlIGZpbHRlcnMgZm91bmQuPC9pPjwvZGl2Pjxicj4iOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4U3lzdGVtRGVmZW5zZVsnQU1UX0hkcjgwMjFGaWx0ZXInXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0hkcjgwMjFGaWx0ZXInXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgICAgIHZhciBkZXNjID0geHhTeXN0ZW1EZWZlbmNlRmlsdGVyRXRoZXJuZXRUeXBlc1tmaWx0ZXJbJ0hkclByb3RvY29sSUQ4MDIxJ11dOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIWRlc2MpIGRlc2MgPSAnQWxsIEV0aGVybmV0IFByb3RvY29sICcgKyBmaWx0ZXJbJ0hkclByb3RvY29sSUQ4MDIxJ107DQogICAgICAgICAgICAgICAgICAgIGRlc2MgKz0gJywgJyArIHh4U3lzdGVtRGVmZW5jZUZpbHRlckRlc2NbZmlsdGVyWydGaWx0ZXJQcm9maWxlJ11dOw0KICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyWydGaWx0ZXJQcm9maWxlJ10gPT0gMikgeyBkZXNjICs9ICIgYXQgIiArIGZpbHRlclsnRmlsdGVyUHJvZmlsZURhdGEnXSArICIgcGFja2V0IC8gc2VjIjsgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyWydBY3Rpb25FdmVudE9uTWF0Y2gnXSA9PSB0cnVlKSBkZXNjICs9ICcsIEV2ZW50IG9uIG1hdGNoJzsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIG9uY2xpY2s9c2hvd0ZpbHRlckRldGFpbHMoMCwiICsgaSArICIpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyAoZmlsdGVyWydGaWx0ZXJEaXJlY3Rpb24nXSA9PSAwID8gJyYjODU5MjsgJyA6ICcmIzg1OTQ7ICcpICsgRXNjYXBlSHRtbChmaWx0ZXJbIk5hbWUiXSkgKyAiPC9iPiwgIiArIGRlc2MgKyAiPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFN5c3RlbURlZmVuc2VbJ0FNVF9JUEhlYWRlcnNGaWx0ZXInXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0lQSGVhZGVyc0ZpbHRlciddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGRlc2MgPSB4eFN5c3RlbURlZmVuY2VGaWx0ZXJJUFR5cGVzW2ZpbHRlclsnSGRySVBWZXJzaW9uJ11dOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIWRlc2MpIGRlc2MgPSAnQWxsIEV0aGVybmV0IFByb3RvY29sICcgKyBmaWx0ZXJbJ0hkcklQVmVyc2lvbiddOw0KICAgICAgICAgICAgICAgICAgICBkZXNjICs9ICcsICcgKyB4eFN5c3RlbURlZmVuY2VGaWx0ZXJEZXNjW2ZpbHRlclsnRmlsdGVyUHJvZmlsZSddXTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlclsnRmlsdGVyUHJvZmlsZSddID09IDIpIHsgZGVzYyArPSAiIGF0ICIgKyBmaWx0ZXJbJ0ZpbHRlclByb2ZpbGVEYXRhJ10gKyAiIHBhY2tldCAvIHNlYyI7IH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlclsnQWN0aW9uRXZlbnRPbk1hdGNoJ10gPT0gdHJ1ZSkgZGVzYyArPSAnLCBFdmVudCBvbiBtYXRjaCc7DQogICAgICAgICAgICAgICAgICAgIHZhciBmaWx0ZXJjb3VudCA9IDA7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4geHhTeXN0ZW1EZWZlbmNlRmlsdGVycykgeyBpZiAoZmlsdGVyW2pdKSBmaWx0ZXJjb3VudCsrOyB9DQogICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJjb3VudCA+IDApIGRlc2MgKz0gJywgJyArIGZpbHRlcmNvdW50ICsgJyBmaWx0ZXInICsgKGZpbHRlcmNvdW50PjE/J3MnOicnKTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIG9uY2xpY2s9c2hvd0ZpbHRlckRldGFpbHMoMSwiICsgaSArICIpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyAoZmlsdGVyWydGaWx0ZXJEaXJlY3Rpb24nXSA9PSAwID8gJyYjODU5MjsgJyA6ICcmIzg1OTQ7ICcpICsgRXNjYXBlSHRtbChmaWx0ZXJbIk5hbWUiXSkgKyAiPC9iPiwgIiArIGRlc2MgKyAiPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICB4ICs9ICI8YnI+PHRkIGNsYXNzPXIxPiIgKyBUYWJsZUVuZChBZGRSZWZyZXNoQnV0dG9uKCJQdWxsU3lzdGVtRGVmZW5zZSgpIikgKyAvKkFkZEJ1dHRvbigiVXBkYXRlIFN0YXRzIiwgIlVwZGF0ZURlZmVuc2VTdGF0cygpIikgKyovIEFkZEJ1dHRvbigiQWRkIEZpbHRlci4uLiIsICJBZGREZWZlbnNlRmlsdGVyKCkiKSArIEFkZEJ1dHRvbigiQWRkIFBvbGljeS4uLiIsICJBZGREZWZlbnNlUG9saWN5KCkiKSk7DQoNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVN5c3RlbURlZmVuc2UnLCB4KTsNCg0KICAgICAgICAgICAgaWYgKHh4RmlsdGVyU3RhdGlzdGljc1RpbWVyID09IG51bGwpIHsNCiAgICAgICAgICAgICAgICBVcGRhdGVEZWZlbnNlU3RhdHMoKTsNCiAgICAgICAgICAgICAgICB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9IGZhbHNlOw0KICAgICAgICAgICAgICAgIGlmICghdXJsdmFyc1snbm9yZWZyZXNoJ10pIHsgeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXIgPSBzZXRJbnRlcnZhbChVcGRhdGVEZWZlbnNlU3RhdHMsIDUwMDApOyB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBTdG9wRGVmZW5zZVN0YXRzVGltZXIoKSB7DQogICAgICAgICAgICBpZiAoeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXIgIT0gbnVsbCkgeyBjbGVhckludGVydmFsKHh4RmlsdGVyU3RhdGlzdGljc1RpbWVyKTsgeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXIgPSBudWxsOyB9DQogICAgICAgICAgICB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9IGZhbHNlOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gVXBkYXRlRGVmZW5zZVN0YXRzKG4pIHsNCiAgICAgICAgICAgIGlmICghbiAmJiB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9PSB0cnVlKSB7IHJldHVybjsgfQ0KICAgICAgICAgICAgeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXJBY3RpdmUgPSB0cnVlOw0KICAgICAgICAgICAgdmFyIG5ldHdvcmsgPSBuP246MDsNCiAgICAgICAgICAgIGlmICh4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3lbbmV0d29ya10pIHsNCiAgICAgICAgICAgICAgICB2YXIgZXJlZiA9ICc8YTpBZGRyZXNzPjwvYTpBZGRyZXNzPjxhOlJlZmVyZW5jZVBhcmFtZXRlcnM+PHc6UmVzb3VyY2VVUkk+aHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NpbS1zY2hlbWEvMi9DSU1fRXRoZXJuZXRQb3J0PC93OlJlc291cmNlVVJJPjx3OlNlbGVjdG9yU2V0Pjx3OlNlbGVjdG9yIE5hbWU9IkRldmljZUlEIj5JbnRlbChyKSBBTVQgRXRoZXJuZXQgUG9ydCAnICsgbmV0d29yayArICc8L3c6U2VsZWN0b3I+PC93OlNlbGVjdG9yU2V0PjwvYTpSZWZlcmVuY2VQYXJhbWV0ZXJzPic7DQogICAgICAgICAgICAgICAgYW10c3RhY2suQU1UX1N5c3RlbURlZmVuc2VQb2xpY3lfVXBkYXRlU3RhdGlzdGljcyhlcmVmLCBmYWxzZSwgVXBkYXRlRGVmZW5zZVN0YXRzMiwgbmV0d29yaywgMCwgeyAnSW5zdGFuY2VJRCc6IHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeVtuZXR3b3JrXVsnSW5zdGFuY2VJRCddIH0pOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAvLyBObyBhY3RpdmUgcG9saWN5LCBzdG9wIHRoZSB0aW1lcg0KICAgICAgICAgICAgICAgIHh4RmlsdGVyU3RhdGlzdGljc1tuZXR3b3JrXSA9IHt9Ow0KICAgICAgICAgICAgICAgIHVwZGF0ZVN5c3RlbURlZmVuc2UoKTsNCiAgICAgICAgICAgICAgICBTdG9wRGVmZW5zZVN0YXRzVGltZXIoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIFVwZGF0ZURlZmVuc2VTdGF0czIoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzLCBuZXR3b3JrKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgew0KICAgICAgICAgICAgICAgIGFtdHN0YWNrLkVudW0oJ0FNVF9BY3RpdmVGaWx0ZXJTdGF0aXN0aWNzJywgVXBkYXRlRGVmZW5zZVN0YXRzMywgbmV0d29yayk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFN0b3BEZWZlbnNlU3RhdHNUaW1lcigpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gVXBkYXRlRGVmZW5zZVN0YXRzMyhzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMsIG5ldHdvcmspIHsNCiAgICAgICAgICAgIHZhciBjb3VudCA9IDA7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgew0KICAgICAgICAgICAgICAgIHh4RmlsdGVyU3RhdGlzdGljc1tuZXR3b3JrXSA9IHt9Ow0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gcmVzcG9uc2VzKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciByZWFkY291bnQgPSByZXNwb25zZXNbaV1bJ1JlYWRDb3VudCddOw0KICAgICAgICAgICAgICAgICAgICAvLyB2YXIgbWF0Y2hlZCA9IHJlc3BvbnNlc1tpXVsnRmlsdGVyTWF0Y2hlZCddOw0KICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IGdldEl0ZW0ocmVzcG9uc2VzW2ldWydEZXBlbmRlbnQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWzFdWydWYWx1ZSddWydFbmRwb2ludFJlZmVyZW5jZSddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10sICdATmFtZScsICdOYW1lJylbJ1ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgIHh4RmlsdGVyU3RhdGlzdGljc1tuZXR3b3JrXVtuYW1lXSA9IHJlYWRjb3VudDsNCiAgICAgICAgICAgICAgICAgICAgY291bnQrKzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgdXBkYXRlU3lzdGVtRGVmZW5zZSgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXJBY3RpdmUgPSBmYWxzZTsNCiAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIHN0YXRpc3RpY3MsIHN0b3AgdGhlIHRpbWVyDQogICAgICAgICAgICBpZiAoY291bnQgPT0gMCkgeyBTdG9wRGVmZW5zZVN0YXRzVGltZXIoKTsgfSAvLyBUT0RPOiBDaGFuZ2UgdGhpcyB0byBhbGxvdyBmb3Igd2lyZWxlc3MNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGNoYW5nZURlZmF1bHRQb2xpY3kobmV0d29yaykgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PHNlbGVjdCBpZD1wb2xpY3lTZWxlY3Rpb24gc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjY2cHg+PG9wdGlvbiB2YWx1ZT0tMT5Ob25lIjsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlcykgeyB4ICs9ICI8b3B0aW9uIHZhbHVlPSIgKyBpICsgKCh4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3lbbmV0d29ya10gJiYgeHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlc1tpXVsnSW5zdGFuY2VJRCddID09IHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeVtuZXR3b3JrXVsnSW5zdGFuY2VJRCddKSA/ICcgc2VsZWN0ZWQnIDogJycpICsgIj4iICsgeHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlc1tpXVsnUG9saWN5TmFtZSddOyB9DQogICAgICAgICAgICB4ICs9ICI8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5EZWZhdWx0IFBvbGljeTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnRGVmYXVsdCBTeXN0ZW0gRGVmZW5zZSBQb2xpY3knLCAzLCBjaGFuZ2VEZWZhdWx0UG9saWN5T2ssIHgsIG5ldHdvcmspOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2hhbmdlRGVmYXVsdFBvbGljeU9rKGJ1dHRvbiwgbmV0d29yaykgew0KICAgICAgICAgICAgdmFyIGkgPSBRKCdwb2xpY3lTZWxlY3Rpb24nKS52YWx1ZTsNCiAgICAgICAgICAgIHZhciBvbGRwb2xpY3kgPSB4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3lbbmV0d29ya107DQogICAgICAgICAgICBpZiAob2xkcG9saWN5KSB7IGFtdHN0YWNrLkRlbGV0ZSgnQU1UX05ldHdvcmtQb3J0U3lzdGVtRGVmZW5zZVBvbGljeScsICc8dzpTZWxlY3RvclNldD48dzpTZWxlY3RvciBOYW1lPSJBbnRlY2VkZW50Ij48YTpFbmRwb2ludFJlZmVyZW5jZSB4bWxuczpiPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciIHhtbG5zOmM9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiPjxhOkFkZHJlc3M+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL3JvbGUvYW5vbnltb3VzPC9hOkFkZHJlc3M+PGE6UmVmZXJlbmNlUGFyYW1ldGVycz48dzpSZXNvdXJjZVVSST5odHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9FdGhlcm5ldFBvcnQ8L3c6UmVzb3VyY2VVUkk+PHc6U2VsZWN0b3JTZXQ+PHc6U2VsZWN0b3IgTmFtZT0iQ3JlYXRpb25DbGFzc05hbWUiPkNJTV9FdGhlcm5ldFBvcnQ8L3c6U2VsZWN0b3I+PHc6U2VsZWN0b3IgTmFtZT0iRGV2aWNlSUQiPkludGVsKHIpIEFNVCBFdGhlcm5ldCBQb3J0ICcgKyBuZXR3b3JrICsgJzwvdzpTZWxlY3Rvcj48L3c6U2VsZWN0b3JTZXQ+PC9hOlJlZmVyZW5jZVBhcmFtZXRlcnM+PC9hOkVuZHBvaW50UmVmZXJlbmNlPjwvdzpTZWxlY3Rvcj48dzpTZWxlY3RvciBOYW1lPSJEZXBlbmRlbnQiPjxhOkVuZHBvaW50UmVmZXJlbmNlIHhtbG5zOmI9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyIgeG1sbnM6Yz0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZCI+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48YTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjx3OlJlc291cmNlVVJJPmh0dHA6Ly9pbnRlbC5jb20vd2JlbS93c2NpbS8xL2FtdC1zY2hlbWEvMS9BTVRfU3lzdGVtRGVmZW5zZVBvbGljeTwvdzpSZXNvdXJjZVVSST48dzpTZWxlY3RvclNldD48dzpTZWxlY3RvciBOYW1lPSJJbnN0YW5jZUlEIj4nICsgb2xkcG9saWN5WydJbnN0YW5jZUlEJ10gKyAnPC93OlNlbGVjdG9yPjwvdzpTZWxlY3RvclNldD48L2E6UmVmZXJlbmNlUGFyYW1ldGVycz48L2E6RW5kcG9pbnRSZWZlcmVuY2U+PC93OlNlbGVjdG9yPjwvdzpTZWxlY3RvclNldD4nLCAoKGkgPT0gLTEpID8gUHVsbFN5c3RlbURlZmVuc2UgOiBmdW5jdGlvbiAoKSB7IH0pKTsgfQ0KDQogICAgICAgICAgICBpZiAoaSA+PSAwKSB7DQogICAgICAgICAgICAgICAgdmFyIHBvbGljeSA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgdmFyIGVyZWYgPSAnPEFkZHJlc3MgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyI+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nPC9BZGRyZXNzPjxSZWZlcmVuY2VQYXJhbWV0ZXJzIHhtbG5zPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciPjxSZXNvdXJjZVVSSSB4bWxucz0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZCI+aHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NpbS1zY2hlbWEvMi9DSU1fRXRoZXJuZXRQb3J0PC9SZXNvdXJjZVVSST48U2VsZWN0b3JTZXQgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiPjxTZWxlY3RvciBOYW1lPSJEZXZpY2VJRCI+SW50ZWwocikgQU1UIEV0aGVybmV0IFBvcnQgJyArIG5ldHdvcmsgKyAnPC9TZWxlY3Rvcj48L1NlbGVjdG9yU2V0PjwvUmVmZXJlbmNlUGFyYW1ldGVycz4nOw0KICAgICAgICAgICAgICAgIHZhciBwcmVmID0gJzxBZGRyZXNzIHhtbG5zPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciPmh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZzwvQWRkcmVzcz48UmVmZXJlbmNlUGFyYW1ldGVycyB4bWxucz0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nIj48UmVzb3VyY2VVUkkgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiPmh0dHA6Ly9pbnRlbC5jb20vd2JlbS93c2NpbS8xL2FtdC1zY2hlbWEvMS9BTVRfU3lzdGVtRGVmZW5zZVBvbGljeTwvUmVzb3VyY2VVUkk+PFNlbGVjdG9yU2V0IHhtbG5zPSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIj48U2VsZWN0b3IgTmFtZT0iSW5zdGFuY2VJRCI+JyArIHBvbGljeVsnSW5zdGFuY2VJRCddICsgJzwvU2VsZWN0b3I+PC9TZWxlY3RvclNldD48L1JlZmVyZW5jZVBhcmFtZXRlcnM+JzsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5DcmVhdGUoJ0FNVF9OZXR3b3JrUG9ydFN5c3RlbURlZmVuc2VQb2xpY3knLCB7ICdBbnRlY2VkZW50JzogZXJlZiwgJ0RlcGVuZGVudCc6IHByZWYgfSwgY2hhbmdlRGVmYXVsdFBvbGljeU9rMik7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBjaGFuZ2VEZWZhdWx0UG9saWN5T2syKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdEZWZhdWx0IFN5c3RlbSBEZWZlbnNlIFBvbGljeScsICJVbmFibGUgdG8gc2V0IHBvbGljeSwgZXJyb3IgIiArIHN0YXR1cyk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFB1bGxTeXN0ZW1EZWZlbnNlKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGREZWZlbnNlRmlsdGVyKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPWZpbHRlcm5hbWUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHggbWF4bGVuZ3RoPTE2IG9ua2V5dXA9QWRkRGVmZW5zZUZpbHRlclVwZGF0ZSgpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4Pk5hbWU8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48c2VsZWN0IGlkPWZpbHRlcnR5cGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjY2cHggb25jaGFuZ2U9QWRkRGVmZW5zZUZpbHRlclVwZGF0ZSgpPjxvcHRpb24gdmFsdWU9MD5FdGhlcm5ldCBJUCBQYWNrZXQgRmlsdGVyPG9wdGlvbiB2YWx1ZT0xPkV0aGVybmV0IEFSUCBQYWNrZXQgRmlsdGVyPG9wdGlvbiB2YWx1ZT0yPklQdjQgUGFja2V0IEZpbHRlcjxvcHRpb24gdmFsdWU9Mz5JUHY2IFBhY2tldCBGaWx0ZXI8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5UeXBlPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHggaWQ9aXBmaWx0ZXJkaXY+PGlucHV0IGlkPWlwZmlsdGVyIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IHBsYWNlaG9sZGVyPVwiT3B0aW9uYWwgUnVsZXNcIiBvbmtleXVwPUFkZERlZmVuc2VGaWx0ZXJVcGRhdGUoKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5NYXRjaGluZyBSdWxlczwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9ZmlsdGVyZGlyIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2NnB4IG9uY2hhbmdlPUFkZERlZmVuc2VGaWx0ZXJVcGRhdGUoKT48b3B0aW9uIHZhbHVlPTA+T3V0Ym91bmQgLyBUcmFuc21pdDxvcHRpb24gdmFsdWU9MT5JbmJvdW5kIC8gUmVjZWl2ZTwvc2VsZWN0PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PkRpcmVjdGlvbjwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9ZmlsdGVycHJvZmlsZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjZweCBvbmNoYW5nZT1BZGREZWZlbnNlRmlsdGVyVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0wPkFsbG93LCBDb3VudDxvcHRpb24gdmFsdWU9MT5Ecm9wLCBDb3VudDxvcHRpb24gdmFsdWU9Mj5SYXRlIExpbWl0PG9wdGlvbiB2YWx1ZT0zPkFsbG93PG9wdGlvbiB2YWx1ZT00PkRyb3A8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5BY3Rpb248L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweCBpZD1maWx0ZXJkYXRhZGl2PjxpbnB1dCBpZD1maWx0ZXJkYXRhIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG1heGxlbmd0aD04IG9ua2V5dXA9QWRkRGVmZW5zZUZpbHRlclVwZGF0ZSgpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PlBhY2tldHMgLyBzZWNvbmQ8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48c2VsZWN0IGlkPWZpbHRlcmFjdGlvbiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjZweCBvbmNoYW5nZT1BZGREZWZlbnNlRmlsdGVyVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT1mYWxzZT5EbyBOb3RoaW5nPG9wdGlvbiB2YWx1ZT0xPkV2ZW50IG9uIG1hdGNoPC9zZWxlY3Q+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+RXZlbnQgTG9nPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdBZGQgU3lzdGVtIERlZmVuc2UgRmlsdGVyJywgMywgQWRkRGVmZW5zZUZpbHRlck9rLCB4KTsNCiAgICAgICAgICAgIEFkZERlZmVuc2VGaWx0ZXJVcGRhdGUoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZERlZmVuc2VGaWx0ZXJPaygpIHsNCiAgICAgICAgICAgIGlmIChRKCdmaWx0ZXJ0eXBlJykudmFsdWUgPD0gMSkgew0KICAgICAgICAgICAgICAgIC8vIEFkZCBFdGhlcm5ldCBJUCBvciBBUlAgZmlsdGVyDQogICAgICAgICAgICAgICAgdmFyIHByb3RvY29sID0gKFEoJ2ZpbHRlcnR5cGUnKS52YWx1ZSA9PSAwKSA/IDIwNDggOiAyMDU0OyAvLyBJUCA6IEFSUA0KICAgICAgICAgICAgICAgIHZhciBmaWx0ZXIgPSB7ICdJbnN0YW5jZUlEICc6IDAsICdOYW1lJzogUSgnZmlsdGVybmFtZScpLnZhbHVlLCAnQ3JlYXRpb25DbGFzc05hbWUnOiAwLCAnU3lzdGVtTmFtZSc6IDAsICdTeXN0ZW1DcmVhdGlvbkNsYXNzTmFtZSc6IDAsICdIZHJQcm90b2NvbElEODAyMSc6IHByb3RvY29sLCAnRmlsdGVyUHJvZmlsZSc6IFEoJ2ZpbHRlcnByb2ZpbGUnKS52YWx1ZSwgJ0ZpbHRlckRpcmVjdGlvbic6IFEoJ2ZpbHRlcmRpcicpLnZhbHVlLCAnQWN0aW9uRXZlbnRPbk1hdGNoJzogUSgnZmlsdGVyYWN0aW9uJykudmFsdWUgfTsNCiAgICAgICAgICAgICAgICBpZiAoUSgnZmlsdGVycHJvZmlsZScpLnZhbHVlID09IDIpIGZpbHRlclsnRmlsdGVyUHJvZmlsZURhdGEnXSA9IFEoJ2ZpbHRlcmRhdGEnKS52YWx1ZTsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5DcmVhdGUoJ0FNVF9IZHI4MDIxRmlsdGVyJywgZmlsdGVyLCBBZGREZWZlbnNlRmlsdGVyT2syKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gQWRkIElQdjQgb3IgSVB2NiBGaWx0ZXINCiAgICAgICAgICAgICAgICB2YXIgcHJvdG9jb2wgPSAoUSgnZmlsdGVydHlwZScpLnZhbHVlID09IDIpID8gNCA6IDY7IC8vIElQdjQgOiBJUHY2DQogICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHsgJ0luc3RhbmNlSUQgJzogMCwgJ05hbWUnOiBRKCdmaWx0ZXJuYW1lJykudmFsdWUsICdDcmVhdGlvbkNsYXNzTmFtZSc6IDAsICdTeXN0ZW1OYW1lJzogMCwgJ1N5c3RlbUNyZWF0aW9uQ2xhc3NOYW1lJzogMCwgJ0hkcklQVmVyc2lvbic6IHByb3RvY29sLCAnRmlsdGVyUHJvZmlsZSc6IFEoJ2ZpbHRlcnByb2ZpbGUnKS52YWx1ZSwgJ0ZpbHRlckRpcmVjdGlvbic6IFEoJ2ZpbHRlcmRpcicpLnZhbHVlLCAnQWN0aW9uRXZlbnRPbk1hdGNoJzogUSgnZmlsdGVyYWN0aW9uJykudmFsdWUgfTsNCg0KICAgICAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBmaWx0ZXIgc3RyaW5nDQogICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9zb2Z0d2FyZS5pbnRlbC5jb20vc2l0ZXMvbWFuYWdlYWJpbGl0eS9BTVRfSW1wbGVtZW50YXRpb25fYW5kX1JlZmVyZW5jZV9HdWlkZS9kZWZhdWx0Lmh0bT90dXJsPUhUTUxEb2N1bWVudHMlMkZXUy1NYW5hZ2VtZW50X0NsYXNzX1JlZmVyZW5jZSUyRkFNVF9IZHI4MDIxRmlsdGVyLmh0bQ0KICAgICAgICAgICAgICAgIHZhciBmaWx0ZXJzdHJzID0gUSgnaXBmaWx0ZXInKS52YWx1ZS5zcGxpdCgnLCcpOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gZmlsdGVyc3Rycykgew0KICAgICAgICAgICAgICAgICAgICB2YXIgeHggPSBmaWx0ZXJzdHJzW2ldLmluZGV4T2YoJz0nKTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIG4gPSBmaWx0ZXJzdHJzW2ldLnN1YnN0cmluZygwLCB4eCk7DQogICAgICAgICAgICAgICAgICAgIHZhciB2ID0gZmlsdGVyc3Ryc1tpXS5zdWJzdHJpbmcoeHggKyAxKTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHQgPSB4eFN5c3RlbURlZmVuY2VGaWx0ZXJzW25dOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIXQpIHsgbiA9ICJIZHIiICsgbjsgdCA9IHh4U3lzdGVtRGVmZW5jZUZpbHRlcnNbbl07IH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKHQpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IFBhcnNlIHYgKHRoZSB2YWx1ZSkgYmFzZWQgb24gdGhlIHR5cGUgdC4NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ID09IDIgJiYgcHJvdG9jb2wgPT0gNCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElQdjQgYWRkcmVzcw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpcHNwbGl0ID0gdi5zcGxpdCgnLicpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpcHNwbGl0Lmxlbmd0aCA9PSA0KSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmlsdGVyW25dID0gYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KGlwc3BsaXRbMF0pLCBwYXJzZUludChpcHNwbGl0WzFdKSwgcGFyc2VJbnQoaXBzcGxpdFsyXSksIHBhcnNlSW50KGlwc3BsaXRbM10pKSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmlsdGVyW25dID0gWyBwYXJzZUludChpcHNwbGl0WzBdKSwgcGFyc2VJbnQoaXBzcGxpdFsxXSksIHBhcnNlSW50KGlwc3BsaXRbMl0pLCBwYXJzZUludChpcHNwbGl0WzNdKSBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJbbl0gPSByc3RyMmhleChTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KGlwc3BsaXRbMF0pLCBwYXJzZUludChpcHNwbGl0WzFdKSwgcGFyc2VJbnQoaXBzcGxpdFsyXSksIHBhcnNlSW50KGlwc3BsaXRbM10pKSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlciB2YWx1ZXMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJbbl0gPSB2Ow0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgaWYgKFEoJ2ZpbHRlcnByb2ZpbGUnKS52YWx1ZSA9PSAyKSBmaWx0ZXJbJ0ZpbHRlclByb2ZpbGVEYXRhJ10gPSBRKCdmaWx0ZXJkYXRhJykudmFsdWU7DQogICAgICAgICAgICAgICAgYW10c3RhY2suQ3JlYXRlKCdBTVRfSVBIZWFkZXJzRmlsdGVyJywgZmlsdGVyLCBBZGREZWZlbnNlRmlsdGVyT2syKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZERlZmVuc2VGaWx0ZXJVcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgb2sgPSBRKCdmaWx0ZXJuYW1lJykudmFsdWUubGVuZ3RoID4gMDsNCiAgICAgICAgICAgIGlmIChvayAmJiBRKCdmaWx0ZXJwcm9maWxlJykudmFsdWUgPT0gMikgeyB2YXIgaSA9IHBhcnNlSW50KFEoJ2ZpbHRlcmRhdGEnKS52YWx1ZSk7IG9rID0gKGkgPiAwICYmIGkgPCAweEZGRkZGRkZGKTsgfQ0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgICAgIFFWKCdmaWx0ZXJkYXRhZGl2JywgUSgnZmlsdGVycHJvZmlsZScpLnZhbHVlID09IDIpOw0KICAgICAgICAgICAgUVYoJ2lwZmlsdGVyZGl2JywgUSgnZmlsdGVydHlwZScpLnZhbHVlID49IDIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkRGVmZW5zZUZpbHRlck9rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnQWRkIFN5c3RlbSBEZWZlbnNlIEZpbHRlcicsICJVbmFibGUgdG8gYWRkIGZpbHRlciwgZXJyb3IgIyIgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsU3lzdGVtRGVmZW5zZSgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0ZpbHRlckRldGFpbHModCwgaSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIGRlc2MsIGZpbHRlciwgdHlwZSwgdG47DQogICAgICAgICAgICBpZiAodCA9PSAwKSB7DQogICAgICAgICAgICAgICAgdG4gPSAnQU1UX0hkcjgwMjFGaWx0ZXInOw0KICAgICAgICAgICAgICAgIHR5cGUgPSAnRXRoZXJuZXQgVHJhZmZpYyc7DQogICAgICAgICAgICAgICAgZmlsdGVyID0geHhTeXN0ZW1EZWZlbnNlW3RuXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgZGVzYyA9IHh4U3lzdGVtRGVmZW5jZUZpbHRlckV0aGVybmV0VHlwZXNbZmlsdGVyWydIZHJQcm90b2NvbElEODAyMSddXTsNCiAgICAgICAgICAgICAgICBpZiAoIWRlc2MpIGRlc2MgPSAnQWxsIEV0aGVybmV0IFByb3RvY29sICcgKyBmaWx0ZXJbJ0hkclByb3RvY29sSUQ4MDIxJ107DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHRuID0gJ0FNVF9JUEhlYWRlcnNGaWx0ZXInOw0KICAgICAgICAgICAgICAgIHR5cGUgPSAnSVAgVHJhZmZpYyc7DQogICAgICAgICAgICAgICAgZmlsdGVyID0geHhTeXN0ZW1EZWZlbnNlW3RuXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgZGVzYyA9IHh4U3lzdGVtRGVmZW5jZUZpbHRlcklQVHlwZXNbZmlsdGVyWydIZHJJUFZlcnNpb24nXV07DQogICAgICAgICAgICAgICAgaWYgKCFkZXNjKSBkZXNjID0gJ0FsbCBJUCBQcm90b2NvbCAnICsgZmlsdGVyWydIZHJJUFZlcnNpb24nXTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHZhciB4ID0gJyc7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnTmFtZScsIEVzY2FwZUh0bWwoZmlsdGVyWyJOYW1lIl0pKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdUeXBlJywgdHlwZSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnTWF0Y2hpbmcgVHJhZmZpYycsIGRlc2MpOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ0RpcmVjdGlvbicsIGZpbHRlclsnRmlsdGVyRGlyZWN0aW9uJ10gPT0gMCA/ICdPdXRib3VuZCAvIFRyYW5zbWl0JyA6ICdJbmJvdW5kIC8gUmVjZWl2ZScpOw0KICAgICAgICAgICAgaWYgKHQgPT0gMSkgew0KICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4geHhTeXN0ZW1EZWZlbmNlRmlsdGVycykgew0KICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyW2pdKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbiA9IGosIHYgPSBmaWx0ZXJbal0sIHQgPSB4eFN5c3RlbURlZmVuY2VGaWx0ZXJzW2pdOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHQgPT0gMiAmJiB2Lmxlbmd0aCA9PSA0KSB7IHYgPSBoZXgycnN0cih2KTsgdiA9IHYuY2hhckNvZGVBdCgwKSArICcuJyArIHYuY2hhckNvZGVBdCgxKSArICcuJyArIHYuY2hhckNvZGVBdCgyKSArICcuJyArIHYuY2hhckNvZGVBdCgzKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG4uc3RhcnRzV2l0aCgnSGRyJykpIG4gPSBuLnN1YnN0cmluZygzKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdGaWx0ZXIgJyArIG4sIHYpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ0V2ZW50IG9uIG1hdGNoJywgKGZpbHRlclsnQWN0aW9uRXZlbnRPbk1hdGNoJ10gPT0gdHJ1ZSkgPyAnWWVzJyA6ICdObycpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ0V0aGVybmV0IEZpbHRlciAjJyArIGZpbHRlclsnSW5zdGFuY2VJRCddLCA1LCBzaG93RmlsdGVyRGV0YWlsc09rLCB4LCBbdG4sIGZpbHRlcl0pOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0ZpbHRlckRldGFpbHNPayhiLCB0YWcpIHsNCiAgICAgICAgICAgIGlmIChiID09IDIpIHsgYW10c3RhY2suRGVsZXRlKHRhZ1swXSwgdGFnWzFdLCBkZWxldGVEZWZlbnNlRmlsdGVyKTsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGVsZXRlRGVmZW5zZUZpbHRlcihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnUmVtb3ZlIEZpbHRlcicsICJVbmFibGUgdG8gcmVtb3ZlIGZpbHRlciwgbWFrZSBzdXJlIGl0J3Mgbm90IGluIHVzZS4iKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgUHVsbFN5c3RlbURlZmVuc2UoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIHZhciB4eEFkZERlZmVuc2VQb2xpY3lGaWx0ZXJzOw0KICAgICAgICBmdW5jdGlvbiBBZGREZWZlbnNlUG9saWN5KCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgeHhBZGREZWZlbnNlUG9saWN5RmlsdGVycyA9IFtdOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPXBvbGljeW5hbWUgdGl0bGU9Jzxwb2xpY3kgbmFtZT46PHBvbGljeSBwcmVjZWRlbmNlIG51bWJlcj4nIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG1heGxlbmd0aD0xNiBvbmtleXVwPUFkZERlZmVuc2VQb2xpY3lVcGRhdGUoKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5OYW1lPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PHNlbGVjdCBpZD1wb2xpY3l0eCB0aXRsZT0nRGVmYXVsdCBhY3Rpb24gdG8gdGFrZSBmb3Igb3V0Ym91bmQgdHJhZmZpYycgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MTMzcHg+PG9wdGlvbiB2YWx1ZT0wPkFsbG93PG9wdGlvbiB2YWx1ZT0xPkRyb3A8b3B0aW9uIHZhbHVlPTI+QWxsb3csQ291bnQ8b3B0aW9uIHZhbHVlPTM+RHJvcCxDb3VudDxvcHRpb24gdmFsdWU9ND5BbGxvdyxDb3VudCxFdmVudDxvcHRpb24gdmFsdWU9NT5Ecm9wLENvdW50LEV2ZW50PC9zZWxlY3Q+PHNlbGVjdCBpZD1wb2xpY3lyeCBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoxMzNweCB0aXRsZT0nRGVmYXVsdCBhY3Rpb24gdG8gdGFrZSBmb3IgaW5ib3VuZCB0cmFmZmljJz48b3B0aW9uIHZhbHVlPTA+QWxsb3c8b3B0aW9uIHZhbHVlPTE+RHJvcDxvcHRpb24gdmFsdWU9Mj5BbGxvdyxDb3VudDxvcHRpb24gdmFsdWU9Mz5Ecm9wLENvdW50PG9wdGlvbiB2YWx1ZT00PkFsbG93LENvdW50LEV2ZW50PG9wdGlvbiB2YWx1ZT01PkRyb3AsQ291bnQsRXZlbnQ8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5EZWZhdWx0IFRYIC8gUlg8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBpZD1wb2xpY3lGaWx0ZXJzPjwvZGl2PiI7DQogICAgICAgICAgICBpZiAoeHhTeXN0ZW1EZWZlbnNlWydBTVRfSGRyODAyMUZpbHRlciddLnJlc3BvbnNlcy5sZW5ndGggPiAwIHx8IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0lQSGVhZGVyc0ZpbHRlciddLnJlc3BvbnNlcy5sZW5ndGggPiAwKSB7DQogICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48ZGl2IHN0eWxlPWZsb2F0OnJpZ2h0PjxzZWxlY3QgaWQ9eGZpbHRlciBzdHlsZT13aWR0aDoxODZweD4iOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhTeXN0ZW1EZWZlbnNlWydBTVRfSGRyODAyMUZpbHRlciddLnJlc3BvbnNlcykgew0KICAgICAgICAgICAgICAgICAgICB2YXIgZmlsdGVyID0geHhTeXN0ZW1EZWZlbnNlWydBTVRfSGRyODAyMUZpbHRlciddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPG9wdGlvbiB2YWx1ZT0iICsgZmlsdGVyWyJJbnN0YW5jZUlEIl0gKyAiPiIgKyBmaWx0ZXJbIk5hbWUiXTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFN5c3RlbURlZmVuc2VbJ0FNVF9JUEhlYWRlcnNGaWx0ZXInXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0lQSGVhZGVyc0ZpbHRlciddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPG9wdGlvbiB2YWx1ZT0iICsgZmlsdGVyWyJJbnN0YW5jZUlEIl0gKyAiPiIgKyBmaWx0ZXJbIk5hbWUiXTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgeCArPSAiPC9zZWxlY3Q+PGlucHV0IGlkPWFkZEZpbHRlckJ1dHRvbiB0eXBlPWJ1dHRvbiB2YWx1ZT1BZGQgc3R5bGU9d2lkdGg6ODBweCBvbmNsaWNrPWFkZEZpbHRlckJ1dHRvbigpPjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PkFkZCBGaWx0ZXI8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ0FkZCBTeXN0ZW0gRGVmZW5zZSBQb2xpY3knLCAzLCBBZGREZWZlbnNlUG9saWN5T2ssIHgpOw0KICAgICAgICAgICAgQWRkRGVmZW5zZVBvbGljeVVwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gYWRkRmlsdGVyQnV0dG9uKCkgew0KICAgICAgICAgICAgaWYgKHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMuaW5kZXhPZihRKCd4ZmlsdGVyJykudmFsdWUpID49IDApIHJldHVybjsNCiAgICAgICAgICAgIHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMucHVzaChRKCd4ZmlsdGVyJykudmFsdWUpOw0KICAgICAgICAgICAgQWRkRGVmZW5zZVBvbGljeVVwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcmVtb3ZlRmlsdGVyQnV0dG9uKGgpIHsNCiAgICAgICAgICAgIHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMuc3BsaWNlKGgsIDEpOw0KICAgICAgICAgICAgQWRkRGVmZW5zZVBvbGljeVVwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkRGVmZW5zZVBvbGljeVVwZGF0ZSgpIHsNCiAgICAgICAgICAgIHZhciBvayA9IFEoJ3BvbGljeW5hbWUnKS52YWx1ZS5zcGxpdCgnOicpWzBdLmxlbmd0aCA+IDA7DQogICAgICAgICAgICBRRSgnaWR4X2RsZ09rQnV0dG9uJywgb2spOw0KICAgICAgICAgICAgaWYgKHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMubGVuZ3RoID09IDApIHsNCiAgICAgICAgICAgICAgICBRSCgncG9saWN5RmlsdGVycycsICc8YnI+PGk+VGhpcyBwb2xpY3kgY29udGFpbnMgbm8gZmlsdGVycy48L2k+PGJyPjxicj4nKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMpIHsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIHN0eWxlPW1hcmdpbi1yaWdodDowPjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ+IiArIEFkZEJ1dHRvbjIoIlJlbW92ZSIsICJyZW1vdmVGaWx0ZXJCdXR0b24oIiArIGkgKyAiKSIpICsgIjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4O21heC13aWR0aDoyNjBweDtvdmVyZmxvdzpoaWRkZW4+PGI+IiArIEdldEZpbHRlckJ5SWQoeHhBZGREZWZlbnNlUG9saWN5RmlsdGVyc1tpXSlbJ05hbWUnXSArICI8L2I+PC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgUUgoJ3BvbGljeUZpbHRlcnMnLCB4KTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIFRPRE86IE9uY2UgbG9hZGVkLCB3ZSBjb3VsZCBtYWtlIGEgdGFibGUgb2YgImhhbmRsZSAtPiBmaWx0ZXIiIHdoZXJlIGJvdGggZmlsdGVyIHR5cGVzIGFyZSBtaXhlZC1pbi4gQ291bGQgbWFrZSB0aGluZ3Mgc2ltcGxlci9zbWFsbGVyPw0KICAgICAgICAvLyBXZSB3b3VsZCBvbmx5IGhhdmUgb25lIHRhYmxlIHRvIGxvb3AgaW5zdGVhZCBvZiB0d28gYXQgYSBmZXcgcGxhY2VzLiBUaGlzIGZ1bmN0aW9uIHdvdWxkIGJlIHJlbW92ZWQgY29tcGxldGVseS4NCiAgICAgICAgZnVuY3Rpb24gR2V0RmlsdGVyQnlJZChoKSB7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4U3lzdGVtRGVmZW5zZVsnQU1UX0hkcjgwMjFGaWx0ZXInXS5yZXNwb25zZXMpIHsgdmFyIGZpbHRlciA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0hkcjgwMjFGaWx0ZXInXS5yZXNwb25zZXNbaV07IGlmIChmaWx0ZXJbIkluc3RhbmNlSUQiXSA9PSBoKSByZXR1cm4gZmlsdGVyOyB9DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4U3lzdGVtRGVmZW5zZVsnQU1UX0lQSGVhZGVyc0ZpbHRlciddLnJlc3BvbnNlcykgeyB2YXIgZmlsdGVyID0geHhTeXN0ZW1EZWZlbnNlWydBTVRfSVBIZWFkZXJzRmlsdGVyJ10ucmVzcG9uc2VzW2ldOyBpZiAoZmlsdGVyWyJJbnN0YW5jZUlEIl0gPT0gaCkgcmV0dXJuIGZpbHRlcjsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkRGVmZW5zZVBvbGljeU9rKCkgew0KICAgICAgICAgICAgdmFyIHR4ID0gUSgncG9saWN5dHgnKS52YWx1ZTsNCiAgICAgICAgICAgIHZhciByeCA9IFEoJ3BvbGljeXJ4JykudmFsdWU7DQogICAgICAgICAgICB2YXIgcHJpID0gMDsNCiAgICAgICAgICAgIHZhciBuID0gUSgncG9saWN5bmFtZScpLnZhbHVlLnNwbGl0KCc6Jyk7DQogICAgICAgICAgICBpZiAobi5sZW5ndGggPT0gMikgcHJpID0gcGFyc2VJbnQoblsxXSk7DQogICAgICAgICAgICB2YXIgZmlsdGVyID0geyAnSW5zdGFuY2VJRCAnOiAwLCAnUG9saWN5TmFtZSc6IG5bMF0sICdQb2xpY3lQcmVjZWRlbmNlJzogcHJpLCAnVHhEZWZhdWx0Q291bnQnOiAodHggPiAxKSwgJ1R4RGVmYXVsdERyb3AnOiAodHggJSAyID09IDEpLCAnVHhEZWZhdWx0TWF0Y2hFdmVudCc6ICh0eCA+IDMpLCAnUnhEZWZhdWx0Q291bnQnOiAocnggPiAxKSwgJ1J4RGVmYXVsdERyb3AnOiAocnggJSAyID09IDEpLCAnUnhEZWZhdWx0TWF0Y2hFdmVudCc6IChyeCA+IDMpIH07DQogICAgICAgICAgICBpZiAoeHhBZGREZWZlbnNlUG9saWN5RmlsdGVycy5sZW5ndGggPiAwKSBmaWx0ZXJbJ0ZpbHRlckNyZWF0aW9uSGFuZGxlcyddID0geHhBZGREZWZlbnNlUG9saWN5RmlsdGVyczsNCiAgICAgICAgICAgIGFtdHN0YWNrLkNyZWF0ZSgnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knLCBmaWx0ZXIsIEFkZERlZmVuc2VQb2xpY3lPazIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkRGVmZW5zZVBvbGljeU9rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnQWRkIFN5c3RlbSBEZWZlbnNlIFBvbGljeScsICJVbmFibGUgdG8gYWRkIHBvbGljeSwgZXJyb3IgIyIgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsU3lzdGVtRGVmZW5zZSgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1BvbGljeURldGFpbHMoaSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHBvbGljeSA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICB2YXIgeCA9ICcnOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ05hbWUnLCBFc2NhcGVIdG1sKHBvbGljeVsiUG9saWN5TmFtZSJdKSk7DQogICAgICAgICAgICBpZiAocG9saWN5WyJQb2xpY3lQcmVjZWRlbmNlIl0gIT0gMCkgeCArPSBhZGRIdG1sVmFsdWUoJ1ByZWNlZGVuY2UnLCBwb2xpY3lbIlBvbGljeVByZWNlZGVuY2UiXSk7DQoNCiAgICAgICAgICAgIHZhciBhY3Rpb24gPSAocG9saWN5WyJUeERlZmF1bHREcm9wIl0gPT0gdHJ1ZSkgPyAnRHJvcCcgOiAnQWxsb3cnOw0KICAgICAgICAgICAgaWYgKHBvbGljeVsiVHhEZWZhdWx0Q291bnQiXSA9PSB0cnVlKSBhY3Rpb24gKz0gJywgQ291bnQnOw0KICAgICAgICAgICAgaWYgKHBvbGljeVsiVHhEZWZhdWx0TWF0Y2hFdmVudCJdID09IHRydWUpIGFjdGlvbiArPSAnLCBFdmVudCc7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnRGVmYXVsdCBUWCBBY3Rpb24nLCBhY3Rpb24pOw0KDQogICAgICAgICAgICBhY3Rpb24gPSAocG9saWN5WyJSeERlZmF1bHREcm9wIl0gPT0gdHJ1ZSkgPyAnRHJvcCcgOiAnQWxsb3cnOw0KICAgICAgICAgICAgaWYgKHBvbGljeVsiUnhEZWZhdWx0Q291bnQiXSA9PSB0cnVlKSBhY3Rpb24gKz0gJywgQ291bnQnOw0KICAgICAgICAgICAgaWYgKHBvbGljeVsiUnhEZWZhdWx0TWF0Y2hFdmVudCJdID09IHRydWUpIGFjdGlvbiArPSAnLCBFdmVudCc7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnRGVmYXVsdCBSWCBBY3Rpb24nLCBhY3Rpb24pOw0KDQogICAgICAgICAgICBpZiAocG9saWN5WydGaWx0ZXJDcmVhdGlvbkhhbmRsZXMnXSkgeyBmb3IgKHZhciBpIGluIHBvbGljeVsnRmlsdGVyQ3JlYXRpb25IYW5kbGVzJ10pIHsgeCArPSBhZGRIdG1sVmFsdWUoJ0ZpbHRlciAjJyArICgraSArIDEpLCBHZXRGaWx0ZXJCeUlkKHBvbGljeVsnRmlsdGVyQ3JlYXRpb25IYW5kbGVzJ11baV0pWydOYW1lJ10pOyB9IH0NCg0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ1BvbGljeSAjJyArIHBvbGljeVsnSW5zdGFuY2VJRCddLnN1YnN0cmluZygyMCksIDUsIHNob3dQb2xpY3lEZXRhaWxzT2ssIHgsIHBvbGljeSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93UG9saWN5RGV0YWlsc09rKGIsIHRhZykgew0KICAgICAgICAgICAgaWYgKGIgPT0gMikgeyBhbXRzdGFjay5EZWxldGUoJ0FNVF9TeXN0ZW1EZWZlbnNlUG9saWN5JywgdGFnLCBkZWxldGVEZWZlbnNlUG9saWN5KTsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGVsZXRlRGVmZW5zZVBvbGljeShzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnUmVtb3ZlIFBvbGljeScsICJVbmFibGUgdG8gcmVtb3ZlIHBvbGljeSwgbWFrZSBzdXJlIGl0J3Mgbm90IGluIHVzZS4iKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgUHVsbFN5c3RlbURlZmVuc2UoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQoNCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gV0lSRUxFU1MgU0VUVElOR1MgUEFORUwNCiAgICAgICAgLy8NCg0KICAgICAgICB2YXIgeHhXaXJlbGVzczsNCiAgICAgICAgZnVuY3Rpb24gUHVsbFdpcmVsZXNzKCkgew0KICAgICAgICAgICAgYW10Rmlyc3RQdWxsIHw9IDI7DQogICAgICAgICAgICB0cnkgeyBpZiAoYW10d2lyZWxlc3NpZiA9PSAtMSkgcmV0dXJuOyB9IGNhdGNoIChlKSB7fSAvLyBJZiB0aGUgd2lyZWxlc3MgYWRhcHRlciBoYXMgbm8gTUFDLCBkb24ndCBzaG93IHRoaXMuDQogICAgICAgICAgICBhbXRzdGFjay5CYXRjaEVudW0oIiIsIFsiKkNJTV9XaUZpUG9ydENhcGFiaWxpdGllcyIsICIqQ0lNX1dpRmlQb3J0IiwgIipDSU1fV2lGaUVuZHBvaW50IiwgIkNJTV9XaUZpRW5kcG9pbnRTZXR0aW5ncyJdLCBwcm9jZXNzV2lyZWxlc3MpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gd2lmaVJlZnJlc2goKSB7IGlmICgheHhkaWFsb2dNb2RlKSBQdWxsV2lyZWxlc3MoKTsgfQ0KDQogICAgICAgIHZhciB4eFdpZmlTdGF0ZSA9IHsgMzogJ0Rpc2FibGVkJywgMzI3Njg6ICdFbmFibGVkIGluIFMwJywgMzI3Njk6ICdFbmFibGVkIGluIFMwLCBTeC9BQycgfTsNCiAgICAgICAgdmFyIHh4UmFkaW9TdGF0ZSA9IAl7IDI6ICdPbiwgQ29ubmVjdGVkJywgMzogJ09mZicsIDY6ICdPbiwgRGlzY29ubmVjdGVkJyB9Ow0KICAgICAgICB2YXIgeHhXaWZpQXV0aGVudGljYXRpb25NZXRob2Q9IHsgMTogJ090aGVyJywgMjogJ09wZW4nLCAzOiAnU2hhcmVkIEtleScsIDQ6ICdXUEEgUFNLJywgNTogJ1dQQSBJRUVFIDgwMi4xeCcsIDY6ICdXUEEyIFBTSycsIDc6ICdXUEEyIElFRUUgODAyLjF4JyB9Ow0KICAgICAgICB2YXIgeHhXaWZpRW5jcnlwdGlvbk1ldGhvZCA9IHsgMTogJ090aGVyJywgMjogJ1dFUCcsIDM6ICdUS0lQLVJDNCcsIDQ6ICdDQ01QLUFFUycsIDU6ICdOb25lJyB9OyAvLyBGb3IgMiAmIDUsIEF1dGhlbnRpY2F0aW9uTWV0aG9kIG11c3QgYmUgMiBvciAzLiBGb3IgMyAmIDQgQXV0aGVudGljYXRpb25NZXRob2QgbXVzdCBiZSA0LDUsNiBvciA3DQoNCiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1dpcmVsZXNzKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgeHhXaXJlbGVzcyA9IHJlc3BvbnNlczsgfSBlbHNlIHsgeHhXaXJlbGVzcyA9IHVuZGVmaW5lZDsgfQ0KICAgICAgICAgICAgdXBkYXRlU3lzdGVtU3RhdHVzKCk7DQogICAgICAgICAgICBzaG93V2lyZWxlc3NJbmZvKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93V2lyZWxlc3NJbmZvKCkgew0KICAgICAgICAgICAgaWYgKCF4eFdpcmVsZXNzKSByZXR1cm47DQogICAgICAgICAgICB2YXIgaSwgaiwgcyA9ICIiLCBzYywgeCA9ICI8YnI+PGgyPldpcmVsZXNzIFByb2ZpbGVzPC9oMj4iOw0KICAgICAgICAgICAgaWYgKCEoeHhXaXJlbGVzc1snQ0lNX1dpRmlQb3J0Q2FwYWJpbGl0aWVzJ10ucmVzcG9uc2UpKSByZXR1cm47DQoNCiAgICAgICAgICAgIC8vIFNob3cgV0lGSSBwcm9maWxlcyBzb3J0ZWQgYnkgcHJpb3JpdHkNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjIgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPldpcmVsZXNzIHByb2ZpbGVzIHRoYXQgSW50ZWwmcmVnOyBBTVQgd2lsbCB1c2UgZm9yIG5ldHdvcmsgY29ubmVjdGl2aXR5Ljxicj48YnI+IjsNCiAgICAgICAgICAgIHMgPSAwOw0KICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsNCiAgICAgICAgICAgICAgICBmb3IgKGogaW4geHhXaXJlbGVzc1snQ0lNX1dpRmlFbmRwb2ludFNldHRpbmdzJ10ucmVzcG9uc2VzKSB7DQogICAgICAgICAgICAgICAgICAgIHNjID0geHhXaXJlbGVzc1snQ0lNX1dpRmlFbmRwb2ludFNldHRpbmdzJ10ucmVzcG9uc2VzW2pdOw0KICAgICAgICAgICAgICAgICAgICBpZiAoc2NbJ0F1dGhlbnRpY2F0aW9uTWV0aG9kJ10gPT0gMSkgY29udGludWU7IC8vIFNraXAgIkVuZHBvaW50IFVzZXIgU2V0dGluZ3MiDQogICAgICAgICAgICAgICAgICAgIGlmIChzY1snUHJpb3JpdHknXSA9PSBpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93V2lmaURldGFpbHMoIiArIGogKyAiKT48ZGl2IHN0eWxlPWZsb2F0OnJpZ2h0PiIgKyBFc2NhcGVIdG1sKHNjWydTU0lEJ10pICsgIiwgIiArIHh4V2lmaUF1dGhlbnRpY2F0aW9uTWV0aG9kW3NjWydBdXRoZW50aWNhdGlvbk1ldGhvZCddXSArICIsICIgKyB4eFdpZmlFbmNyeXB0aW9uTWV0aG9kW3NjWydFbmNyeXB0aW9uTWV0aG9kJ11dICsgIiAmbmJzcDsgIjsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHggKz0gQWRkQnV0dG9uMigiUmVtb3ZlIiwgIndpZmlSZW1vdmVCdXR0b24oXCIiICsgaiArICJcIikiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gIjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyBFc2NhcGVIdG1sKHNjWydFbGVtZW50TmFtZSddKSArICI8L2I+PC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICAgICAgICAgIHMrKzsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChzID09IDApIHggKz0gJzxpPk5vIFdpcmVsZXNzIFByb2ZpbGVzIFByZXNlbnQ8L2k+PGJyPic7DQoNCiAgICAgICAgICAgIC8vIEVuZCBvZiB0YWJsZQ0KICAgICAgICAgICAgeCArPSAiPGJyPjx0ZCBjbGFzcz1yMj4iOw0KICAgICAgICAgICAgaWYgKHh4QWNjb3VudEFkbWluTmFtZSkgeCArPSBUYWJsZUVuZChBZGRCdXR0b24oIk5ldyBQcm9maWxlIiwgInNob3dXaWZpTmV3UHJvZmlsZSgpIikpOyBlbHNlIHggKz0gVGFibGVFbmQoJycpOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlV2lmaTInLCB4ICsgIjxicj4iKTsNCiAgICAgICAgfQ0KICAgICAgICANCiAgICAgICAgZnVuY3Rpb24gc2hvd1dpZmlTdGF0ZURsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBzID0gIiI7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4V2lmaVN0YXRlKSB7IHMgKz0gJzxpbnB1dCB0eXBlPXJhZGlvIG5hbWU9ZDExIGlkPXdsJyArIGkgKyAnIHZhbHVlPScgKyBpICsgJyAnICsgKCh4eFdpcmVsZXNzWydDSU1fV2lGaVBvcnQnXS5yZXNwb25zZVsiRW5hYmxlZFN0YXRlIl0gPT0gaSk/ImNoZWNrZWQiOiIiKSArICc+JyArIHh4V2lmaVN0YXRlW2ldICsgJzxicj4nOyB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnV2lyZWxlc3MgU3RhdGUnLCAzLCB3aWZpU3RhdGVEbGcsIHMpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gd2lmaVN0YXRlRGxnKCkgeyBhbXRzdGFjay5DSU1fV2lGaVBvcnRfUmVxdWVzdFN0YXRlQ2hhbmdlKCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPWQxMV06Y2hlY2tlZCcpLnZhbHVlLCBudWxsLCBmdW5jdGlvbigpIHsgYW10c3RhY2suR2V0KCJDSU1fV2lGaVBvcnQiLCBmdW5jdGlvbihzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgeyBpZiAoc3RhdHVzID09IDIwMCkgeyB4eFdpcmVsZXNzWydDSU1fV2lGaVBvcnQnXS5yZXNwb25zZSA9IHJlc3BvbnNlLkJvZHk7IHNob3dXaXJlbGVzc0luZm8oKTsgfSB9ICk7IH0gKTsgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dXaWZpRGV0YWlscyhoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgaSwgc2MgPSB4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXNbaF0sIHggPSAnPGRpdiBzdHlsZT10ZXh0LWFsaWduOmxlZnQ+JzsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJQcm9maWxlIE5hbWUiLCBFc2NhcGVIdG1sKHNjWydFbGVtZW50TmFtZSddKSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU1NJRCIsIHNjWydTU0lEJ10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkF1dGhlbnRpY2F0aW9uIiwgeHhXaWZpQXV0aGVudGljYXRpb25NZXRob2Rbc2NbJ0F1dGhlbnRpY2F0aW9uTWV0aG9kJ11dKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJFbmNyeXB0aW9uIiwgeHhXaWZpRW5jcnlwdGlvbk1ldGhvZFtzY1snRW5jcnlwdGlvbk1ldGhvZCddXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiUHJpb3JpdHkiLCBzY1snUHJpb3JpdHknXSk7DQogICAgICAgICAgICB4ICs9ICI8L2Rpdj4iOw0KICAgICAgICAgICAgbWVzc2FnZWJveCgiV2lyZWxlc3MgUHJvZmlsZSIsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gd2lmaVJlbW92ZUJ1dHRvbihoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgc2MgPSB4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXNbaF07DQogICAgICAgICAgICBRSCgnaWRfZGlhbG9nTWVzc2FnZScsICdSZW1vdmUgd2lyZWxlc3MgcHJvZmlsZSBcIicgKyBzY1siRWxlbWVudE5hbWUiXSArICdcIj8nKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMSwgIldpcmVsZXNzIFByb2ZpbGUiLCAzLCBmdW5jdGlvbiAoKSB7IHJlbW92ZVdpZmlCdXR0b25FeChoKSB9KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHJlbW92ZVdpZmlCdXR0b25FeChoKSB7DQogICAgICAgICAgICB2YXIgc2MgPSB4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXNbaF07DQogICAgICAgICAgICBhbXRzdGFjay5EZWxldGUoJ0NJTV9XaUZpRW5kcG9pbnRTZXR0aW5ncycsIHsgSW5zdGFuY2VJRDogc2NbJ0luc3RhbmNlSUQnXSB9LCByZW1vdmVXaWZpRW50cnlSZXNwb25zZSwgMCwgMSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiByZW1vdmVXaWZpRW50cnlSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICBpZiAobWV0aG9kY2hlY2socmVzcG9uc2UpKSByZXR1cm47DQogICAgICAgICAgICBhbXRzdGFjay5FbnVtKCJDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MiLCBmdW5jdGlvbihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsgaWYgKHN0YXR1cyA9PSAyMDApIHsgeHhXaXJlbGVzc1snQ0lNX1dpRmlFbmRwb2ludFNldHRpbmdzJ10ucmVzcG9uc2VzID0gcmVzcG9uc2VzOyBzaG93V2lyZWxlc3NJbmZvKCk7IH0gfSApOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1dpZmlOZXdQcm9maWxlKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIGZvciAoaSA9IDE7IGkgPCAyNTY7IGkrKykgew0KICAgICAgICAgICAgICAgIHZhciB0ID0gMTsNCiAgICAgICAgICAgICAgICBmb3IgKGogaW4geHhXaXJlbGVzc1snQ0lNX1dpRmlFbmRwb2ludFNldHRpbmdzJ10ucmVzcG9uc2VzKSB7IGlmICh4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXNbal1bJ1ByaW9yaXR5J10gPT0gaSkgdCA9IDA7IH0NCiAgICAgICAgICAgICAgICBpZiAodCkgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPScrIGkgKyc+JysgaTsgfSAvLyBPcHRpb24gaXMgYSB0YWcgdGhhdCBpcyBzZWxmIGNsb3NpbmcuDQogICAgICAgICAgICB9DQogICAgICAgICAgICBRSCgnaWR4X2QxMnByaScsIHgpOw0KDQogICAgICAgICAgICBpZHhfZDEyYXV0aC52YWx1ZSA9IDY7DQogICAgICAgICAgICBpZHhfZDEyZW5jLnZhbHVlID0gNDsNCg0KICAgICAgICAgICAgaWR4X2QxMm5hbWUudmFsdWUgPSBpZHhfZDEyc3NpZC52YWx1ZSA9IGlkeF9kMTJwYXNzd29yZDEudmFsdWUgPSBpZHhfZDEycGFzc3dvcmQyLnZhbHVlID0gJyc7DQoNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTIsICJBZGQgV2lyZWxlc3MgUHJvZmlsZSIsIDMsIGZ1bmN0aW9uICgpIHsgYWRkV2lmaVByb2ZpbGUoKSB9KTsNCiAgICAgICAgICAgIHVwZGF0ZVdpZmlEaWFsb2coKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZFdpZmlQcm9maWxlKCkgew0KICAgICAgICAgICAgYW10c3RhY2suQU1UX1dpRmlQb3J0Q29uZmlndXJhdGlvblNlcnZpY2VfQWRkV2lGaVNldHRpbmdzKA0KCQkJCXsNCgkJCQkgICAgJ19fcGFyYW1ldGVyVHlwZSc6ICdyZWZlcmVuY2UnLA0KCQkJCSAgICAnX19yZXNvdXJjZVVyaSc6IGFtdHN0YWNrLkNvbXBsZXRlTmFtZSgnQ0lNX1dpRmlFbmRwb2ludCcpLA0KCQkJCSAgICAnTmFtZSc6ICdXaUZpIEVuZHBvaW50IDAnDQoJCQkJfSwgew0KCQkJCSAgICAnX19wYXJhbWV0ZXJUeXBlJzogJ2luc3RhbmNlJywNCgkJCQkgICAgJ19fbmFtZXNwYWNlJzogYW10c3RhY2suQ29tcGxldGVOYW1lKCdDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnKSwNCgkJCQkgICAgJ0VsZW1lbnROYW1lJzogaWR4X2QxMm5hbWUudmFsdWUsDQoJCQkJICAgICdJbnN0YW5jZUlEJzogJ0ludGVsKHIpIEFNVDpXaUZpIEVuZHBvaW50IFNldHRpbmdzICcgKyBpZHhfZDEybmFtZS52YWx1ZSwNCgkJCQkgICAgJ0F1dGhlbnRpY2F0aW9uTWV0aG9kJzogaWR4X2QxMmF1dGgudmFsdWUsDQoJCQkJICAgICdFbmNyeXB0aW9uTWV0aG9kJzogaWR4X2QxMmVuYy52YWx1ZSwNCgkJCQkgICAgJ1NTSUQnOiBpZHhfZDEyc3NpZC52YWx1ZSwNCgkJCQkgICAgJ1ByaW9yaXR5JzogaWR4X2QxMnByaS52YWx1ZSwNCgkJCQkgICAgJ1BTS1Bhc3NQaHJhc2UnOiBpZHhfZDEycGFzc3dvcmQxLnZhbHVlDQoJCQkJfSwNCgkJCQludWxsLCBudWxsLCBudWxsLCByZW1vdmVXaWZpRW50cnlSZXNwb25zZQ0KCQkJKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVdpZmlEaWFsb2coKSB7DQogICAgICAgICAgICB2YXIgciA9IHRydWU7DQogICAgICAgICAgICB2YXIgYSA9IGlkeF9kMTJhdXRoLnZhbHVlOw0KICAgICAgICAgICAgdmFyIGUgPSBpZHhfZDEyZW5jLnZhbHVlOw0KICAgICAgICAgICAgUVYoJ2lkX2QxMmUyJywgYSA8IDQpOw0KICAgICAgICAgICAgUVYoJ2lkX2QxMmUzJywgYSA+IDMpOw0KICAgICAgICAgICAgUVYoJ2lkX2QxMmU0JywgYSA+IDMpOw0KICAgICAgICAgICAgUVYoJ2lkX2QxMmU1JywgYSA8IDQpOw0KICAgICAgICAgICAgaWYgKGEgPCA0ICYmIChlID09IDMgfHwgZSA9PSA0KSkgeyBpZHhfZDEyZW5jLnZhbHVlID0gMjsgfQ0KICAgICAgICAgICAgaWYgKGEgPiAzICYmIChlID09IDIgfHwgZSA9PSA1KSkgeyBpZHhfZDEyZW5jLnZhbHVlID0gMzsgfQ0KDQogICAgICAgICAgICAvLyBDaGVjayBpZiB0aGVyZSBpcyBhbHJlYWR5IGEgcHJvZmlsZSB3aXRoIHRoaXMgbmFtZQ0KICAgICAgICAgICAgZm9yICh2YXIgaiBpbiB4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXMpIHsgaWYgKHh4V2lyZWxlc3NbJ0NJTV9XaUZpRW5kcG9pbnRTZXR0aW5ncyddLnJlc3BvbnNlc1tqXVsnRWxlbWVudE5hbWUnXSA9PSBpZHhfZDEybmFtZS52YWx1ZSkgeyByID0gZmFsc2U7IH0gfQ0KDQogICAgICAgICAgICBRRSgnaWR4X2RsZ09rQnV0dG9uJywgciA9PSB0cnVlICYmIChpZHhfZDEybmFtZS52YWx1ZS5sZW5ndGggPiAwKSAmJiAoaWR4X2QxMnNzaWQudmFsdWUubGVuZ3RoID4gMCkgJiYgKGlkeF9kMTJwYXNzd29yZDEudmFsdWUubGVuZ3RoID4gNykgJiYgKGlkeF9kMTJwYXNzd29yZDEudmFsdWUgPT0gaWR4X2QxMnBhc3N3b3JkMi52YWx1ZSkpOw0KICAgICAgICB9DQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEhBUkRXQVJFIElORk9STUFUSU9OIFBBTkVMDQogICAgICAgIC8vDQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbEhhcmR3YXJlKCkgew0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKCIiLCBbIipDSU1fQ29tcHV0ZXJTeXN0ZW1QYWNrYWdlIiwgIkNJTV9TeXN0ZW1QYWNrYWdpbmciLCAiKkNJTV9DaGFzc2lzIiwgIkNJTV9DaGlwIiwgIipDSU1fQ2FyZCIsICIqQ0lNX0JJT1NFbGVtZW50IiwgIkNJTV9Qcm9jZXNzb3IiLCAiQ0lNX1BoeXNpY2FsTWVtb3J5IiwgIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJDSU1fUGh5c2ljYWxQYWNrYWdlIl0sIHByb2Nlc3NIYXJkd2FyZSk7DQogICAgICAgICAgICBhbXRGaXJzdFB1bGwgfD0gMTsgLy8gU2V0IHRoZSBoYXJkd2FyZSBpbmZvIGJpdCBvbiwgaW5kaWNhdGVzIHdlIGFyZSBwdWxsaW5nIHRoaXMgaW5mb3JtYXRpb24uDQogICAgICAgIH0NCg0KICAgICAgICAvLyBodHRwOi8vd3d3LmRtdGYub3JnL3NpdGVzL2RlZmF1bHQvZmlsZXMvc3RhbmRhcmRzL2RvY3VtZW50cy9EU1AwMTM0XzIuNy4xLnBkZg0KICAgICAgICB2YXIgRE1URkNQVVN0YXR1cyA9IFsiVW5rbm93biIsICJFbmFibGVkIiwgIkRpc2FibGVkIGJ5IFVzZXIiLCAiRGlzYWJsZWQgQnkgQklPUyAoUE9TVCBFcnJvcikiLCAiSWRsZSIsICJPdGhlciJdOw0KICAgICAgICB2YXIgRE1URk1lbVR5cGUgPSBbIlVua25vd24iLCAiT3RoZXIiLCAiRFJBTSIsICJTeW5jaHJvbm91cyBEUkFNIiwgIkNhY2hlIERSQU0iLCAiRURPIiwgIkVEUkFNIiwgIlZSQU0iLCAiU1JBTSIsICJSQU0iLCAiUk9NIiwgIkZsYXNoIiwgIkVFUFJPTSIsICJGRVBST00iLCAiRVBST00iLCAiQ0RSQU0iLCAiM0RSQU0iLCAiU0RSQU0iLCAiU0dSQU0iLCAiUkRSQU0iLCAiRERSIiwgIkREUi0yIiwgIkJSQU0iLCAiRkItRElNTSIsICJERFIzIiwgIkZCRDIiLCAiRERSNCIsICJMUEREUiIsICJMUEREUjIiLCAiTFBERFIzIiwgIkxQRERSNCJdOw0KICAgICAgICB2YXIgRE1URk1lbUZvcm1GYWN0b3IgPSBbJycsICdPdGhlcicsJ1Vua25vd24nLCdTSU1NJywnU0lQJywnQ2hpcCcsJ0RJUCcsJ1pJUCcsJ1Byb3ByaWV0YXJ5IENhcmQnLCdESU1NJywnVFNPUCcsJ1JvdyBvZiBjaGlwcycsJ1JJTU0nLCdTT0RJTU0nLCdTUklNTScsJ0ZCLURJTSddOw0KICAgICAgICB2YXIgRE1URlByb2NGYW1pbGx5ID0geyAvLyBQYWdlIDQ2IG9mIERNVEYgZG9jdW1lbnQNCiAgICAgICAgICAgIDE5MTogJ0ludGVsJnJlZzsgQ29yZSZ0cmFkZTsgMiBEdW8gUHJvY2Vzc29yJywNCiAgICAgICAgICAgIDE5MjogJ0ludGVsJnJlZzsgQ29yZSZ0cmFkZTsgMiBTb2xvIHByb2Nlc3NvcicsDQogICAgICAgICAgICAxOTM6ICdJbnRlbCZyZWc7IENvcmUmdHJhZGU7IDIgRXh0cmVtZSBwcm9jZXNzb3InLA0KICAgICAgICAgICAgMTk0OiAnSW50ZWwmcmVnOyBDb3JlJnRyYWRlOyAyIFF1YWQgcHJvY2Vzc29yJywNCiAgICAgICAgICAgIDE5NTogJ0ludGVsJnJlZzsgQ29yZSZ0cmFkZTsgMiBFeHRyZW1lIG1vYmlsZSBwcm9jZXNzb3InLA0KICAgICAgICAgICAgMTk2OiAnSW50ZWwmcmVnOyBDb3JlJnRyYWRlOyAyIER1byBtb2JpbGUgcHJvY2Vzc29yJywNCiAgICAgICAgICAgIDE5NzogJ0ludGVsJnJlZzsgQ29yZSZ0cmFkZTsgMiBTb2xvIG1vYmlsZSBwcm9jZXNzb3InLA0KICAgICAgICAgICAgMTk4OiAnSW50ZWwmcmVnOyBDb3JlJnRyYWRlOyBpNyBwcm9jZXNzb3InLA0KICAgICAgICAgICAgMTk5OiAnRHVhbC1Db3JlIEludGVsJnJlZzsgQ2VsZXJvbiZyZWc7IHByb2Nlc3NvcicgfTsNCg0KICAgICAgICB2YXIgSGFyZHdhcmVJbnZlbnRvcnk7DQogICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NIYXJkd2FyZShzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSByZXR1cm47DQoNCiAgICAgICAgICAgIHZhciBpLCB4ID0gIjx0YWJsZSBjbGFzcz1sb2cxIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6OHB4PiI7DQogICAgICAgICAgICBIYXJkd2FyZUludmVudG9yeSA9IHJlc3BvbnNlczsNCiAgICAgICAgICAgIFFWKCdnbzInLCB0cnVlKTsgLy8gU2hvdyAiSGFyZHdhcmUgSW5mb3JtYXRpb24iIG9uIGxlZnQgcGFuZWwNCg0KDQogICAgICAgICAgICB4ICs9IFRhYmxlRW5kKCI8ZGl2PiZuYnNwOyIgKyBBZGRSZWZyZXNoQnV0dG9uKCJQdWxsSGFyZHdhcmUoMSkiKSArIEFkZEJ1dHRvbigiU2F2ZS4uLiIsICJTYXZlSGFyZHdhcmVMb2coKSIpICsgJyBIYXJkd2FyZSBpbmZvcm1hdGlvbiBpcyBnYXRoZXJlZCBhdCBzeXN0ZW0gYm9vdCB0aW1lLicpOw0KDQogICAgICAgICAgICB2YXIgYmEgPSByZXNwb25zZXNbJ0NJTV9DaGFzc2lzJ10ucmVzcG9uc2U7DQogICAgICAgICAgICB2YXIgYmIgPSByZXNwb25zZXNbJ0NJTV9DYXJkJ10ucmVzcG9uc2U7DQogICAgICAgICAgICB2YXIgdiA9IHJlc3BvbnNlc1snQ0lNX0JJT1NFbGVtZW50J10ucmVzcG9uc2VbIlNvZnR3YXJlRWxlbWVudElEIl07DQogICAgICAgICAgICANCiAgICAgICAgICAgIHggKz0gIjxicj48aDI+UGxhdGZvcm08L2gyPiI7DQogICAgICAgICAgICB4ICs9IEZ1bGxUYWJsZSh7IkNvbXB1dGVyIG1vZGVsIjpiYVsiTW9kZWwiXSwgIk1hbnVmYWN0dXJlciI6YmFbIk1hbnVmYWN0dXJlciJdLCAiVmVyc2lvbiI6YmFbIlZlcnNpb24iXSwgIlNlcmlhbCBudW1iZXIiOmJhWyJTZXJpYWxOdW1iZXIiXSwgIlN5c3RlbSBJRCI6Z3VpZFRvU3RyKHJlc3BvbnNlc1snQ0lNX1N5c3RlbVBhY2thZ2luZyddLnJlc3BvbnNlc1swXVsiUGxhdGZvcm1HVUlEIl0pLnRvTG93ZXJDYXNlKCl9LCAnJyk7DQoNCiAgICAgICAgICAgIHggKz0gIjxicj48aDI+QmFzZWJvYXJkPC9oMj4iOw0KICAgICAgICAgICAgeCArPSBGdWxsVGFibGUoeyAiTWFudWZhY3R1cmVyIjpiYlsiTWFudWZhY3R1cmVyIl0sICJQcm9kdWN0IG5hbWUiOmJiWyJNb2RlbCJdLCAiVmVyc2lvbiI6YmJbIlZlcnNpb24iXSwgIlNlcmlhbCBudW1iZXIiOmJiWyJTZXJpYWxOdW1iZXIiXSwgIkFzc2V0IHRhZyI6YmJbIlRhZyJdLCAiUmVwbGFjZWFibGU/IjooYmJbIkNhbkJlRlJVZWQiXT09dHJ1ZSk/J1llcyc6J05vJyB9LCcnKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgeCArPSAiPGJyPjxoMj5CSU9TPC9oMj4iOw0KICAgICAgICAgICAgeCArPSBGdWxsVGFibGUoeyJWZW5kb3IiOnJlc3BvbnNlc1snQ0lNX0JJT1NFbGVtZW50J10ucmVzcG9uc2VbIk1hbnVmYWN0dXJlciJdLCAiVmVyc2lvbiI6diwgIlJlbGVhc2UgZGF0ZSI6bmV3IERhdGUocmVzcG9uc2VzWydDSU1fQklPU0VsZW1lbnQnXS5yZXNwb25zZVsiUmVsZWFzZURhdGUiXVsnRGF0ZXRpbWUnXSkudG9Mb2NhbGVEYXRlU3RyaW5nKCdlbicsIHt0aW1lWm9uZTonVVRDJ30pfSwnJyk7DQogICAgICAgICAgICANCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KICAgICAgICAgICAgZm9yIChpIGluIHJlc3BvbnNlc1snQ0lNX1Byb2Nlc3NvciddLnJlc3BvbnNlcykgew0KICAgICAgICAgICAgICAgIHZhciBwID0gcmVzcG9uc2VzWydDSU1fUHJvY2Vzc29yJ10ucmVzcG9uc2VzW2ldOw0KICAgICAgICAgICAgICAgIHZhciBxID0gcmVzcG9uc2VzWydDSU1fQ2hpcCddLnJlc3BvbnNlc1tpXTsgLy8gVGhpcyBpcyBhIHNob3J0Y3V0LCB3ZSBhc3N1bWUgdGhhdCB0aGUgZmlyc3QgZW50cmllcyBpbiBDSU1fQ2hpcCBhcmUgdGhlIHByb2Nlc3NvcnMsIGluIHRoZSBzYW1lIG9yZGVyLg0KICAgICAgICAgICAgICAgIHggKz0gIjxoMj5Qcm9jZXNzb3IgIiArIChwYXJzZUludChpKSArIDEpICsgIjwvaDI+IjsNCiAgICAgICAgICAgICAgICB4ICs9IEZ1bGxUYWJsZSh7Ik1hbnVmYWN0dXJlciI6dHJhZGVtYXJrcyhxWyJNYW51ZmFjdHVyZXIiXSksICJGYW1pbHkiOkRNVEZQcm9jRmFtaWxseVtwWyJGYW1pbHkiXV0sICJWZXJzaW9uIjp0cmFkZW1hcmtzKHFbIlZlcnNpb24iXSksICJNYXhpbXVtIHNvY2tldCBzcGVlZCI6cFsiTWF4Q2xvY2tTcGVlZCJdICsgIiBNSHoiLCAiU3RhdHVzIjpETVRGQ1BVU3RhdHVzW3BbIkNQVVN0YXR1cyJdXX0sJycpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSAiPGJyPiI7DQoNCiAgICAgICAgICAgIGZvciAoaSBpbiByZXNwb25zZXNbJ0NJTV9QaHlzaWNhbE1lbW9yeSddLnJlc3BvbnNlcykgew0KICAgICAgICAgICAgICAgIHZhciBtID0gcmVzcG9uc2VzWydDSU1fUGh5c2ljYWxNZW1vcnknXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgeCArPSAiPGgyPk1lbW9yeSBNb2R1bGUgIiArICgraSArIDEpICsgIjwvaDI+IjsNCiAgICAgICAgICAgICAgICB4ICs9IEZ1bGxUYWJsZSh7IkJhbmsgTGFiZWwiOm1bIkJhbmtMYWJlbCJdLCAiTWFudWZhY3R1cmVyIjptWyJNYW51ZmFjdHVyZXIiXSwgIlNlcmlhbCBOdW1iZXIiOm1bIlNlcmlhbE51bWJlciJdLCAiU2l6ZSI6cGFyc2VJbnQobVsiQ2FwYWNpdHkiXSAvIDB4MTAwMDAwKSArICIgTUIiLCAiRm9ybSBmYWN0b3IiOkRNVEZNZW1Gb3JtRmFjdG9yW21bIkZvcm1GYWN0b3IiXV0sICJUeXBlIjpETVRGTWVtVHlwZVttWyJNZW1vcnlUeXBlIl1dLCAiQXNzZXQgdGFnIjptWyJUYWciXSwgIlBhcnQgbnVtYmVyIjptWyJQYXJ0TnVtYmVyIl19LCcnKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KDQogICAgICAgICAgICBmb3IgKGkgaW4gcmVzcG9uc2VzWydDSU1fTWVkaWFBY2Nlc3NEZXZpY2UnXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICB2YXIgbSA9IHJlc3BvbnNlc1snQ0lNX01lZGlhQWNjZXNzRGV2aWNlJ10ucmVzcG9uc2VzW2ldOw0KICAgICAgICAgICAgICAgIHZhciBuID0gcmVzcG9uc2VzWydDSU1fUGh5c2ljYWxQYWNrYWdlJ10ucmVzcG9uc2VzWytpICsgMV07IC8vIFRoaXMgaXMgYSBzaG9ydGN1dCwgd2UgYXNzdW1lIENJTV9QaHlzaWNhbFBhY2thZ2UgaXMgdGhlIHNhbWUgYXMgQ0lNX01lZGlhQWNjZXNzRGV2aWNlIGV4Y2VwdCBmb3IgdGhlIGZpcnN0IGVudHJ5Lg0KICAgICAgICAgICAgICAgIHggKz0gIjxoMj5TdG9yYWdlIE1lZGlhICIgKyAocGFyc2VJbnQoaSkgKyAxKSArICI8L2gyPiI7DQogICAgICAgICAgICAgICAgeCArPSBGdWxsVGFibGUoeyJNb2RlbCI6blsnTW9kZWwnXSwiU2VyaWFsIG51bWJlciI6KG5bJ1NlcmlhbE51bWJlciddPT0nJz8nVW5rbm93bic6blsnU2VyaWFsTnVtYmVyJ10pLCAiU2l6ZSI6cGFyc2VJbnQoTWF0aC5yb3VuZChtWyJNYXhNZWRpYVNpemUiXSAqIDEwMDAgLyAweDEwMDAwMCkpICsgIiBNQiJ9LCcnKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KDQogICAgICAgICAgICBRSCgnaWRfVGFibGVTeXNJbmZvJywgeCk7DQogICAgICAgICAgICB1cGRhdGVTeXN0ZW1TdGF0dXMoKTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgZnVuY3Rpb24gU2F2ZUhhcmR3YXJlTG9nKCkgew0KICAgICAgICAgICAgaWYgKCF4eGRpYWxvZ01vZGUgJiYgSGFyZHdhcmVJbnZlbnRvcnkpIFNhdmVKc29uRmlsZSgnSW50ZWxBbXRIYXJkd2FyZScsICdoYXJkd2FyZScsICdJbnRlbCBBTVQgSGFyZHdhcmUgSW5mb3JtYXRpb24nLCBIYXJkd2FyZUludmVudG9yeSk7DQogICAgICAgIH0NCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIFBPV0VSIFBPTElDWQ0KICAgICAgICAvLw0KDQogICAgICAgIHZhciBBbXRTeXN0ZW1Qb3dlclNjaGVtZXMgPSBudWxsOw0KICAgICAgICBmdW5jdGlvbiBQdWxsUG93ZXJQb2xpY3koKSB7IGFtdHN0YWNrLkVudW0oIkFNVF9TeXN0ZW1Qb3dlclNjaGVtZSIsIHBvd2VyUG9saWN5UmVzcG9uc2UpOyB9DQogICAgICAgIGZ1bmN0aW9uIHBvd2VyUG9saWN5UmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsgQW10U3lzdGVtUG93ZXJTY2hlbWVzID0gcmVzcG9uc2U7IHVwZGF0ZVN5c3RlbVN0YXR1cygpOyB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1Bvd2VyUG9saWN5RGxnKGN1cnJlbnRndWlkKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgcyA9ICIiOw0KDQogICAgICAgICAgICAvLyBOb3cgZmluZCB0aGUgbmFtZSBvZiB0aGUgcG93ZXIgc2NoZW1hIGluIHRoZSBBTVRfU3lzdGVtUG93ZXJTY2hlbWUgdGFibGUNCiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgQW10U3lzdGVtUG93ZXJTY2hlbWVzLmxlbmd0aDsgaisrKSB7DQogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkID0gKChBbXRTeXN0ZW1Qb3dlclNjaGVtZXNbal1bJ1NjaGVtZUdVSUQnXSA9PSBjdXJyZW50Z3VpZCk/JyBjaGVja2VkJzonJyk7DQogICAgICAgICAgICAgICAgcyArPSAnPGlucHV0IHR5cGU9cmFkaW8gbmFtZT1wb3dlcnBvbGljeSB2YWx1ZT1cIicgKyBBbXRTeXN0ZW1Qb3dlclNjaGVtZXNbal1bJ0luc3RhbmNlSUQnXSArICJcIiAiICsgc2VsZWN0ZWQgKyAnPicgKyBBbXRTeXN0ZW1Qb3dlclNjaGVtZXNbal1bJ0Rlc2NyaXB0aW9uJ10gKyAnPGJyPic7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdJbnRlbCZyZWc7IEFNVCBQb3dlciBQb2xpY3knLCAzLCBzaG93UG93ZXJQb2xpY3lEbGdPaywgcyk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93UG93ZXJQb2xpY3lEbGdPaygpIHsNCiAgICAgICAgICAgIHZhciBpZCA9IG51bGwsIGkgPSAwLCBlID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0Jyk7DQogICAgICAgICAgICBmb3IgKDsgaSA8IGUubGVuZ3RoOyBpKyspIHsgaWYgKGVbaV0ubmFtZSA9PSAncG93ZXJwb2xpY3knICYmIGVbaV0uY2hlY2tlZCkgeyBpZCA9IGVbaV0udmFsdWU7IH0gfQ0KICAgICAgICAgICAgYW10c3RhY2suQU1UX1N5c3RlbVBvd2VyU2NoZW1lX1NldFBvd2VyU2NoZW1lKHNob3dQb3dlclBvbGljeURsZ09rRG9uZSwgaWQpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1Bvd2VyUG9saWN5RGxnT2tEb25lKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7IGlmIChzdGF0dXMgPT0gMjAwKSBQdWxsU3lzdGVtU3RhdHVzKCk7IH0NCg0KICAgICAgICAvLw0KICAgICAgICAvLyBVU0VSIElORk9STUFUSU9OIFBBTkVMDQogICAgICAgIC8vDQoNCiAgICAgICAgdmFyIHh4QWNjb3VudEFkbWluTmFtZSwgeHhBY2NvdW50UmVhbG1JbmZvLCB4eEFjY291bnRFbmFibGVkSW5mbyA9IHt9LCB4eEFjY291bnRGZXRjaCwgc2hvd0hpZGRlbkFjY291bnRzID0gZmFsc2U7DQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFVzZXJJbmZvKCkgew0KICAgICAgICAgICAgeHhBY2NvdW50RmV0Y2ggPSAxOw0KICAgICAgICAgICAgZGVsZXRlIHh4QWNjb3VudEFkbWluTmFtZTsNCiAgICAgICAgICAgIHh4QWNjb3VudFJlYWxtSW5mbyA9IHt9Ow0KICAgICAgICAgICAgYW10c3RhY2suQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX0dldEFkbWluQWNsRW50cnkoZ2V0QWRtaW5BY2xFbnRyeVJlc3BvbnNlKTsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9FbnVtZXJhdGVVc2VyQWNsRW50cmllcygxLCBlbnVtZXJhdGVVc2VyQWNsRW50cmllc1Jlc3BvbnNlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGdldEFkbWluQWNsRW50cnlSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHJldHVybjsNCiAgICAgICAgICAgIHh4QWNjb3VudFJlYWxtSW5mb1stMV0gPSB7ICdBY2Nlc3NQZXJtaXNzaW9uJzogOTk5LCAnRGlnZXN0VXNlcm5hbWUnOiByZXNwb25zZS5Cb2R5WyJVc2VybmFtZSJdLCAnUmVhbG1zJzpudWxsIH07DQogICAgICAgICAgICB4eEFjY291bnRBZG1pbk5hbWUgPSByZXNwb25zZS5Cb2R5WyJVc2VybmFtZSJdOw0KICAgICAgICAgICAgdXBkYXRlQWNjb3VudHMoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVudW1lcmF0ZVVzZXJBY2xFbnRyaWVzUmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSByZXR1cm47DQogICAgICAgICAgICAvL2lmIChlcnJjaGVjayhzdGF0dXMsIHN0YWNrKSkgcmV0dXJuOw0KICAgICAgICAgICAgbWV0aG9kY2hlY2socmVzcG9uc2UpOw0KICAgICAgICAgICAgUVYoJ2dvMTEnLCB0cnVlKTsgLy8gU2hvdyAiVXNlciBBY2NvdW50cyIgb24gbGVmdCBwYW5lbA0KICAgICAgICAgICAgeHhBY2NvdW50RmV0Y2ggPSByZXNwb25zZS5Cb2R5WyJIYW5kbGVzIl0ubGVuZ3RoOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiByZXNwb25zZS5Cb2R5WyJIYW5kbGVzIl0pIHsNCiAgICAgICAgICAgICAgICB2YXIgaCA9IHJlc3BvbnNlLkJvZHlbIkhhbmRsZXMiXVtpXTsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfR2V0QWNsRW5hYmxlZFN0YXRlKGgsIGdldEFjbEVuYWJsZWRTdGF0ZVJlc3BvbnNlLCBoKTsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfR2V0VXNlckFjbEVudHJ5RXgoaCwgZ2V0VXNlckFjbEVudHJ5RXhSZXNwb25zZSwgaCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB1cGRhdGVBY2NvdW50cygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZ2V0VXNlckFjbEVudHJ5RXhSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICB4eEFjY291bnRGZXRjaC0tOw0KICAgICAgICAgICAgLy9pZiAoZXJyY2hlY2soc3RhdHVzLCBzdGFjaykpIHJldHVybjsNCiAgICAgICAgICAgIC8vbWV0aG9kY2hlY2socmVzcG9uc2UpOw0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgLy8gU29tZXRpbWVzIEludGVsIEFNVCB3aWxsIGp1c3QgZnJlYWsgb3V0IG9uIHRoaXMgY2FsbCwgaWYgaXQncyB0aGUgY2FzZSwganVzdCBjYXJyeSBvbi4NCiAgICAgICAgICAgICAgICByZXNwb25zZS5Cb2R5WyJIYW5kbGUiXSA9IHRhZzsNCiAgICAgICAgICAgICAgICBpZiAoIXJlc3BvbnNlLkJvZHlbIlJlYWxtcyJdKSByZXNwb25zZS5Cb2R5WyJSZWFsbXMiXSA9IFtdOw0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFBcnJheS5pc0FycmF5KHJlc3BvbnNlLkJvZHlbIlJlYWxtcyJdKSkgcmVzcG9uc2UuQm9keVsiUmVhbG1zIl0gPSBbcmVzcG9uc2UuQm9keVsiUmVhbG1zIl1dOyAvLyBJZiAiUmVhbG1zIiBpcyBub3QgYW4gYXJyYXksIGl0J3MgYmVjYXVzZSBpdCdzIGp1c3Qgb25lIHJlYWxtLiBGaXggaXMgc28gaXQncyBhbiBhcnJheSBvZiBvbmUuDQogICAgICAgICAgICAgICAgeHhBY2NvdW50UmVhbG1JbmZvW3RhZ10gPSByZXNwb25zZS5Cb2R5Ow0KICAgICAgICAgICAgICAgIHVwZGF0ZUFjY291bnRzKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBnZXRBY2xFbmFibGVkU3RhdGVSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICAvL2lmIChlcnJjaGVjayhzdGF0dXMsIHN0YWNrKSkgcmV0dXJuOw0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgLy8gU29tZXRpbWVzIEludGVsIEFNVCB3aWxsIGp1c3QgZnJlYWsgb3V0IG9uIHRoaXMgY2FsbCwgaWYgaXQncyB0aGUgY2FzZSwganVzdCBjYXJyeSBvbi4NCiAgICAgICAgICAgICAgICB4eEFjY291bnRFbmFibGVkSW5mb1t0YWddID0gcmVzcG9uc2UuQm9keTsNCiAgICAgICAgICAgICAgICB1cGRhdGVBY2NvdW50cygpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2V0QWNsRW5hYmxlZFN0YXRlUmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMsIHRhZykgew0KICAgICAgICAgICAgaWYgKGVycmNoZWNrKHN0YXR1cywgc3RhY2spKSByZXR1cm47DQogICAgICAgICAgICBtZXRob2RjaGVjayhyZXNwb25zZSk7DQogICAgICAgICAgICBhbXRzdGFjay5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfR2V0QWNsRW5hYmxlZFN0YXRlKHRhZywgZ2V0QWNsRW5hYmxlZFN0YXRlUmVzcG9uc2UsIHRhZyk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1cGRhdGVBY2NvdW50cygpIHsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRGZXRjaCA+IDApIHJldHVybjsNCiAgICAgICAgICAgIHZhciB4ID0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSB0aGUgSW50ZWwmcmVnOyBBTVQgdXNlciBhY2NvdW50cyBmb3IgdGhpcyBjb21wdXRlci48YnI+PGJyPiI7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4QWNjb3VudFJlYWxtSW5mbykgew0KICAgICAgICAgICAgICAgIHZhciByID0geHhBY2NvdW50UmVhbG1JbmZvW2ldLCBuYW1lLCBoaWRkZW4gPSBmYWxzZSwgc3RhdGUgPSAwOw0KICAgICAgICAgICAgICAgIGlmIChyWyJEaWdlc3RVc2VybmFtZSJdKSB7IG5hbWUgPSByWyJEaWdlc3RVc2VybmFtZSJdOyBoaWRkZW4gPSAobmFtZVswXSA9PSAnJCcgJiYgbmFtZVsxXSA9PSAnJCcpOyB9IGVsc2UgeyBuYW1lID0gR2V0U2lkU3RyaW5nKGF0b2IoclsiS2VyYmVyb3NVc2VyU2lkIl0pKTsgfQ0KICAgICAgICAgICAgICAgIGlmICh4eEFjY291bnRFbmFibGVkSW5mb1tpXSAmJiBuYW1lICE9ICckJE9zQWRtaW4nKSB7IHN0YXRlID0gKHh4QWNjb3VudEVuYWJsZWRJbmZvW2ldWydFbmFibGVkJ10gPT0gdHJ1ZSk/MToyOyB9DQogICAgICAgICAgICAgICAgaWYgKHNob3dIaWRkZW5BY2NvdW50cyB8fCAhaGlkZGVuKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciByYiA9ICIiOw0KICAgICAgICAgICAgICAgICAgICBpZiAoclsiQWNjZXNzUGVybWlzc2lvbiJdICE9IDk5OSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXRlID09IDIpIHsgcmIgKz0gIkRpc2FibGVkLCAiOyB9DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmMgPSAwOw0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpIGluIHJbIlJlYWxtcyJdKSB7IGlmIChhbXRzdGFjay5SZWFsbU5hbWVzW3JbIlJlYWxtcyJdW2ldXSAhPSAnJykgeyByYysrOyB9IH0gLy8gQ291bnQgb25seSByZWFsbXMgdGhhdCBoYXZlIGEgbmFtZSwgcmVtb3ZpbmcgcmVzZXJ2ZWQgcmVhbG1zLg0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJbIlJlYWxtcyJdLmluZGV4T2YoMjApID49IDApIHJiICs9ICJBdWRpdG9yLCAiOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJbIlJlYWxtcyJdLmluZGV4T2YoMykgPj0gMCkgeyByYiArPSAiQWRtaW5pc3RyYXRvciI7IH0gZWxzZSB7IGlmIChyYyA9PSAxKSB7IHJiICs9ICIxIHJlYWxtIjsgfSBlbHNlIHsgcmIgKz0gcmMgKyAiIHJlYWxtcyI7IH0gfQ0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgcmIgKz0gIkFkbWluaXN0cmF0b3IiOw0KICAgICAgICAgICAgICAgICAgICAgICAgclsiSGFuZGxlIl0gPSAtMTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93VXNlckRldGFpbHMoIiArIHJbIkhhbmRsZSJdICsgIik+PGRpdiBzdHlsZT1mbG9hdDpyaWdodD4iOw0KICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGUgPiAwICYmIHh4QWNjb3VudEFkbWluTmFtZSkgeCArPSAiICIgKyBBZGRCdXR0b24yKChzdGF0ZSA9PSAxPydEaXNhYmxlJzonRW5hYmxlJyksICJjaGFuZ2VBY2NvdW50U3RhdGVCdXR0b24oZXZlbnQsIiArIHJbIkhhbmRsZSJdICsgIiwiICsgc3RhdGUgKyAiKSIpOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIWhpZGRlbiAmJiB4eEFjY291bnRBZG1pbk5hbWUpIHggKz0gIiAiICsgQWRkQnV0dG9uMigiRWRpdC4uLiIsICJjaGFuZ2VBY2NvdW50QnV0dG9uKGV2ZW50LCIgKyByWyJIYW5kbGUiXSArICIpIik7DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4O3dpZHRoOjMzMHB4O2Zsb2F0OmxlZnQ7b3ZlcmZsb3cteDpoaWRkZW4gdGl0bGU9JyIgKyBuYW1lICsgIic+PGI+IiArIG5hbWUgKyAiPC9iPjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PiIgKyByYiArICI8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHZhciB5ID0gIjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ7bWFyZ2luLXJpZ2h0OjhweD48YSB0aXRsZT0nVG9nZ2xlIGhpZGRlbiBhY2NvdW50cycgc3R5bGU9Y29sb3I6Z3JheTtjdXJzb3I6cG9pbnRlciBvbmNsaWNrPXRvZ2dsZUFjY291bnRCdXR0b24oKT4iICsgKHNob3dIaWRkZW5BY2NvdW50cz8nJiN4MjVCMjsnOicmI3gyNUJDOycpICsgIjwvYT48L2Rpdj48ZGl2PiZuYnNwOyIgKyBBZGRSZWZyZXNoQnV0dG9uKCJ4eEFjY291bnRGZXRjaD05OTk7UHVsbFVzZXJJbmZvKCkiKTsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHkgKz0gQWRkQnV0dG9uKCJOZXcgQWNjb3VudCIsICJuZXdBY2NvdW50QnV0dG9uKCkiKTsNCiAgICAgICAgICAgIHggKz0gIjxicj48dGQgY2xhc3M9cjE+IiArIFRhYmxlRW5kKHkgKyAiPC9kaXY+Iik7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVVc2VyQWNjb3VudHMnLCB4KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHRvZ2dsZUFjY291bnRCdXR0b24oKSB7DQogICAgICAgICAgICBzaG93SGlkZGVuQWNjb3VudHMgPSAhc2hvd0hpZGRlbkFjY291bnRzOw0KICAgICAgICAgICAgdXBkYXRlQWNjb3VudHMoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHJlbW92ZVVzZXJBY2xFbnRyeVJlc3BvbnNlKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzLCB0YWcpIHsNCiAgICAgICAgICAgIGlmIChtZXRob2RjaGVjayhyZXNwb25zZSkpIHJldHVybjsNCiAgICAgICAgICAgIFB1bGxVc2VySW5mbygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2hhbmdlQWNjb3VudFN0YXRlQnV0dG9uKGUsIGgsIHMpIHsNCiAgICAgICAgICAgIGhhbHRFdmVudChlKTsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9TZXRBY2xFbmFibGVkU3RhdGUoaCwgKHM9PTE/ZmFsc2U6dHJ1ZSksIHNldEFjbEVuYWJsZWRTdGF0ZVJlc3BvbnNlLCBoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGNoYW5nZUFjY291bnRCdXR0b24oZSwgaCkgew0KICAgICAgICAgICAgaGFsdEV2ZW50KGUpOw0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdXBkYXRlUmVhbG1zKHh4QWNjb3VudFJlYWxtSW5mb1toXVsiUmVhbG1zIl0pOw0KICAgICAgICAgICAgZDJ1c2VybmFtZS52YWx1ZSA9IHh4QWNjb3VudFJlYWxtSW5mb1toXVsiRGlnZXN0VXNlcm5hbWUiXSA/IHh4QWNjb3VudFJlYWxtSW5mb1toXVsiRGlnZXN0VXNlcm5hbWUiXSA6IEdldFNpZFN0cmluZyhhdG9iKHh4QWNjb3VudFJlYWxtSW5mb1toXVsiS2VyYmVyb3NVc2VyU2lkIl0pKTsNCiAgICAgICAgICAgIGQycGFzc3dvcmQxLnZhbHVlID0gZDJwYXNzd29yZDIudmFsdWUgPSAnJzsNCiAgICAgICAgICAgIGQycGVybWlzc2lvbi52YWx1ZSA9IHh4QWNjb3VudFJlYWxtSW5mb1toXVsiQWNjZXNzUGVybWlzc2lvbiJdOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgyLCAiRWRpdCBBY2NvdW50IiwgKChoPT0tMSk/Mzo3KSwgZnVuY3Rpb24gKGJ1dHRvbikgeyBjaGFuZ2VBY2NvdW50QnV0dG9uRXgoaCwgYnV0dG9uKTsgfSk7IC8vIElmIGhhbmRsZSBpcyAtMSwgb25seSBkaXNwbGF5IE9LL0NhbmNlbCBidXR0b25zLCBpZiBub3QsIGFsc28gZGlzcGxheSBkZWxldGUgYnV0dG9uLg0KICAgICAgICAgICAgdXBkYXRlQWNjb3VudERpYWxvZygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gbmV3QWNjb3VudEJ1dHRvbigpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHVwZGF0ZVJlYWxtcyhbXSk7DQogICAgICAgICAgICBkMnVzZXJuYW1lLnZhbHVlID0gZDJwYXNzd29yZDEudmFsdWUgPSBkMnBhc3N3b3JkMi52YWx1ZSA9ICcnOw0KICAgICAgICAgICAgZDJwZXJtaXNzaW9uLnZhbHVlID0gMjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMiwgIk5ldyBBY2NvdW50IiwgMywgZnVuY3Rpb24gKCkgeyBjaGFuZ2VBY2NvdW50QnV0dG9uRXgobnVsbCwgMSk7IH0pOw0KICAgICAgICAgICAgdXBkYXRlQWNjb3VudERpYWxvZygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2hhbmdlQWNjb3VudEJ1dHRvbkV4KGgsIGJ1dHRvbikgew0KICAgICAgICAgICAgaWYgKGJ1dHRvbiA9PSAxKSB7IC8vIE9LIEJ1dHRvbg0KICAgICAgICAgICAgICAgIHZhciByZWFsbXMgPSBbXSwgdXNlcm5hbWUgPSBkMnVzZXJuYW1lLnZhbHVlLCBwZXJtaXNzaW9uID0gZDJwZXJtaXNzaW9uLnZhbHVlLCBwYXNzd29yZCA9IGQycGFzc3dvcmQxLnZhbHVlLCBzaWQgPSBHZXRTaWRCeXRlQXJyYXkoUSgnZDJ1c2VybmFtZScpLnZhbHVlKSwgZCA9IG51bGw7DQogICAgICAgICAgICAgICAgaWYgKHVzZXJuYW1lLmxlbmd0aCA9PSAwIHx8IHBhc3N3b3JkICE9IGQycGFzc3dvcmQyLnZhbHVlKSB7IG1lc3NhZ2Vib3goIkFjY291bnQgRXJyb3IiLCAiSW52YWxpZCBQYXJhbWV0ZXJzIik7IHJldHVybjsgfQ0KICAgICAgICAgICAgICAgIGlmIChzaWQgPT0gbnVsbCkgeyBkID0gd2luZG93LmJ0b2EocnN0cl9tZDUodXNlcm5hbWUgKyAiOiIgKyBhbXRzeXNzdGF0ZVsnQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlWyJEaWdlc3RSZWFsbSJdICsgIjoiICsgcGFzc3dvcmQpKTsgfSBlbHNlIHsgdXNlcm5hbWUgPSBudWxsOyBzaWQgPSBidG9hKHNpZCk7IH0NCiAgICAgICAgICAgICAgICBpZiAoaCAhPSAtMSkgeyBmb3IgKHZhciB5IGluIGFtdHN0YWNrLlJlYWxtTmFtZXMpIHsgaWYgKCgoYW10c3RhY2suUmVhbG1OYW1lc1t5XSkgfHwgKHkgPT0gMykpICYmIFEoJ3J4JyArIHkpLmNoZWNrZWQpIHsgcmVhbG1zLnB1c2goeSk7IH0gfSB9DQogICAgICAgICAgICAgICAgaWYgKGggPT0gbnVsbCkgeyBhbXRzdGFjay5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfQWRkVXNlckFjbEVudHJ5RXgodXNlcm5hbWUsIGQsIHNpZCwgcGVybWlzc2lvbiwgcmVhbG1zLCB1c2VyQWNsRW50cnlFeFJlc3BvbnNlKTsgfQ0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGggPT0gLTEpIHsgYW10c3RhY2suQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX1NldEFkbWluQWNsRW50cnlFeCh1c2VybmFtZSwgZCwgdXNlckFjbEVudHJ5RXhSZXNwb25zZSk7IH0NCiAgICAgICAgICAgICAgICBlbHNlIHsgYW10c3RhY2suQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX1VwZGF0ZVVzZXJBY2xFbnRyeUV4KGgsIHVzZXJuYW1lLCBkLCBzaWQsIHBlcm1pc3Npb24sIHJlYWxtcywgdXNlckFjbEVudHJ5RXhSZXNwb25zZSk7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChidXR0b24gPT0gMikgeyAvLyBEZWxldGUgQnV0dG9uDQogICAgICAgICAgICAgICAgYW10c3RhY2suQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX1JlbW92ZVVzZXJBY2xFbnRyeShoLCByZW1vdmVVc2VyQWNsRW50cnlSZXNwb25zZSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2VyQWNsRW50cnlFeFJlc3BvbnNlKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzLCB0YWcpIHsgaWYgKG1ldGhvZGNoZWNrKHJlc3BvbnNlKSkgcmV0dXJuOyBQdWxsVXNlckluZm8oKTsgfQ0KICAgICAgICBmdW5jdGlvbiB1cGRhdGVSZWFsbXMocikgew0KICAgICAgICAgICAgUVYoJ2lkX2QycGVybWlzc2lvbnMnLCByICE9IG51bGwpOw0KICAgICAgICAgICAgaWYgKHIgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgIHZhciB4ID0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggb25jaGFuZ2U9dXBkYXRlQWNjb3VudERpYWxvZygpIGlkPXJ4MycgKyAoKHIuaW5kZXhPZigzKSA+PSAwKT8nIGNoZWNrZWQnOicnKSArICc+QWRtaW5pc3RyYXRvcjwvbGFiZWw+PC9saT48aHIgLz4nOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIHkgaW4gYW10c3RhY2suUmVhbG1OYW1lcykgeyB2YXIgYyA9ICcnOyBpZiAoci5pbmRleE9mKHBhcnNlSW50KHkpKSA+PSAwKSBjID0gJyBjaGVja2VkJzsgaWYgKGFtdHN0YWNrLlJlYWxtTmFtZXNbeV0pIHggKz0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggb25jaGFuZ2U9dXBkYXRlQWNjb3VudERpYWxvZygpIGlkPXJ4JyArIHkgKyBjICsgJz4nICsgYW10c3RhY2suUmVhbG1OYW1lc1t5XSArICc8L2xhYmVsPjwvbGk+JzsgfQ0KICAgICAgICAgICAgICAgIFFIKCdpZF9kMnJlYWxtcycsIHgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlQWNjb3VudERpYWxvZygpIHsNCiAgICAgICAgICAgIHZhciBvayA9IGZhbHNlOw0KICAgICAgICAgICAgZm9yICh2YXIgeSBpbiBhbXRzdGFjay5SZWFsbU5hbWVzKSB7IGlmICgoKGFtdHN0YWNrLlJlYWxtTmFtZXNbeV0pIHx8ICh5ID09IDMpKSAmJiBRKCdyeCcgKyB5KS5jaGVja2VkKSB7IG9rID0gdHJ1ZTsgfSB9DQogICAgICAgICAgICBvayAmPSAoZDJ1c2VybmFtZS52YWx1ZS5sZW5ndGggPiAwICYmIHBhc3N3b3JkY2hlY2soZDJwYXNzd29yZDEudmFsdWUpICYmIGQycGFzc3dvcmQxLnZhbHVlID09IGQycGFzc3dvcmQyLnZhbHVlKTsNCiAgICAgICAgICAgIFFFKCdpZHhfZGxnT2tCdXR0b24nLCBvayk7DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgeHhVc2VyUGVybWlzc2lvbnMgPSBbJ0xvY2FsIG9ubHknICwgJ05ldHdvcmsgb25seScsICdBbGwgKExvY2FsICYgTmV0d29yayknXTsNCiAgICAgICAgZnVuY3Rpb24gc2hvd1VzZXJEZXRhaWxzKGgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBhID0geHhBY2NvdW50UmVhbG1JbmZvW2hdLCB4ID0gJzxkaXYgc3R5bGU9dGV4dC1hbGlnbjpsZWZ0Pic7DQogICAgICAgICAgICB2YXIgaSwgbiA9IGFbIkRpZ2VzdFVzZXJuYW1lIl07DQogICAgICAgICAgICBpZiAoIW4pIG4gPSBHZXRTaWRTdHJpbmcoYXRvYihhWyJLZXJiZXJvc1VzZXJTaWQiXSkpOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIk5hbWUiLCBuKTsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRFbmFibGVkSW5mb1toXSkgeyB4ICs9IGFkZEh0bWxWYWx1ZSgiU3RhdGUiLCAoKHh4QWNjb3VudEVuYWJsZWRJbmZvW2hdWydFbmFibGVkJ10gPT0gdHJ1ZSk/J0VuYWJsZWQnOidEaXNhYmxlZCcpKTsgfQ0KICAgICAgICAgICAgaWYgKG4gPT0geHhBY2NvdW50QWRtaW5OYW1lKSB7DQogICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlBlcm1pc3Npb24iLCAiQWRtaW5pc3RyYXRvciIpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiUGVybWlzc2lvbiIsIHh4VXNlclBlcm1pc3Npb25zW2FbIkFjY2Vzc1Blcm1pc3Npb24iXV0pOw0KICAgICAgICAgICAgICAgIHZhciB5ID0gJyc7DQogICAgICAgICAgICAgICAgaWYgKGFbIlJlYWxtcyJdLmluZGV4T2YoMykgPj0gMCkgew0KICAgICAgICAgICAgICAgICAgICB5ID0gJ0FkbWluaXN0cmF0b3InOw0KICAgICAgICAgICAgICAgICAgICBpZiAoYVsiUmVhbG1zIl0uaW5kZXhPZigyMCkgPj0gMCkgeSArPSAiLCBBdWRpdG9yIjsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBmb3IgKGkgaW4geHhBY2NvdW50UmVhbG1JbmZvW2hdWyJSZWFsbXMiXSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFtdHN0YWNrLlJlYWxtTmFtZXNbYVsiUmVhbG1zIl1baV1dICE9ICcnKSB7IC8vIFJlbW92ZSBibGFuayByZXNlcnZlZCByZWFsbXMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoeS5sZW5ndGggPiAwKSB5ICs9ICIsICI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeSArPSBhbXRzdGFjay5SZWFsbU5hbWVzW2FbIlJlYWxtcyJdW2ldXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAoeS5sZW5ndGggPT0gMCkgeSA9ICdOb25lJzsNCiAgICAgICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiUmVhbG1zIiwgIiIpICsgIjxiPiIgKyB5ICsgIjwvYj4iOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSAiPC9kaXY+IjsNCiAgICAgICAgICAgIG1lc3NhZ2Vib3goIkFjY291bnQgIiArIG4sIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gV1NNQU4gQlJPV1NFUiBQQU5FTA0KICAgICAgICAvLw0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gUmVtb3RlIFRlcm1pbmFsDQogICAgICAgIC8vDQoNCg0KICAgICAgICAvLw0KICAgICAgICAvLyBSZW1vdGUgRGVza3RvcA0KICAgICAgICAvLw0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gUmVtb3RlIElERVINCiAgICAgICAgLy8NCg0KDQoNCg0KICAgICAgICAvLw0KICAgICAgICAvLyBSZW1vdGUgQWNjZXNzDQogICAgICAgIC8vDQoNCiAgICAgICAgdmFyIHh4UmVtb3RlQWNjZXNzID0gbnVsbDsNCiAgICAgICAgdmFyIHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uID0gbnVsbDsNCiAgICAgICAgdmFyIHh4Q2lyYVNlcnZlcnMgPSBudWxsOw0KICAgICAgICB2YXIgeHhVc2VySW5pdGlhdGVkQ2lyYSA9IG51bGw7DQogICAgICAgIHZhciB4eFVzZXJJbml0aWF0ZWRFbmFibGVkU3RhdGUgPSB7IDMyNzY4OiAnRGlzYWJsZWQnLCAzMjc2OTogJ0JJT1MgZW5hYmxlZCcsIDMyNzcwOiAnT1MgZW5hYmxlJywgMzI3NzE6ICdCSU9TICYgT1MgZW5hYmxlZCcgfTsNCiAgICAgICAgdmFyIHh4UmVtb3RlQWNjZXNzQ3JlZGVudGlhTGlua3MgPSBudWxsOw0KICAgICAgICB2YXIgeHhNUFNVc2VyUGFzcyA9IG51bGw7DQogICAgICAgIHZhciB4eFBvbGljaWVzID0gbnVsbDsNCg0KICAgICAgICBmdW5jdGlvbiBQdWxsUmVtb3RlQWNjZXNzKCkgew0KICAgICAgICAgICAgLy8gV2Ugb25seSBkZWFsIHdpdGggcmVtb3RlIGFjY2VzcyBzdGFydGluZyB3aXRoIEludGVsIEFNVCA2IGFuZCBiZXlvbmQNCg0KICAgICAgICAgICAgdmFyIHJlcXVlc3RzID0gWyIqQU1UX0Vudmlyb25tZW50RGV0ZWN0aW9uU2V0dGluZ0RhdGEiLCAiQU1UX01hbmFnZW1lbnRQcmVzZW5jZVJlbW90ZVNBUCIsICJBTVRfUmVtb3RlQWNjZXNzQ3JlZGVudGlhbENvbnRleHQiLCAiQU1UX1JlbW90ZUFjY2Vzc1BvbGljeUFwcGxpZXNUb01QUyIsICJBTVRfUmVtb3RlQWNjZXNzUG9saWN5UnVsZSIsICIqQU1UX1VzZXJJbml0aWF0ZWRDb25uZWN0aW9uU2VydmljZSIsICJBTVRfTVBTVXNlcm5hbWVQYXNzd29yZCJdOw0KICAgICAgICAgICAgaWYgKGFtdHZlcnNpb24gPiAxMSkgeyByZXF1ZXN0cy5wdXNoKCIqSVBTX0hUVFBQcm94eVNlcnZpY2UiLCAiSVBTX0hUVFBQcm94eUFjY2Vzc1BvaW50Iik7IH0NCiAgICAgICAgICAgIGFtdHN0YWNrLkJhdGNoRW51bShudWxsLCByZXF1ZXN0cywgcHJvY2Vzc1JlbW90ZTEpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1JlbW90ZTEoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDQwMCkgcmV0dXJuOw0KICAgICAgICAgICAgaWYgKChlcnJjaGVjayhzdGF0dXMsIHN0YWNrKSkgfHwgKHJlc3BvbnNlc1siQU1UX1VzZXJJbml0aWF0ZWRDb25uZWN0aW9uU2VydmljZSJdID09IHVuZGVmaW5lZCB8fCByZXNwb25zZXNbIkFNVF9Vc2VySW5pdGlhdGVkQ29ubmVjdGlvblNlcnZpY2UiXS5yZXNwb25zZSA9PSB1bmRlZmluZWQpKSByZXR1cm47DQogICAgICAgICAgICBRVignZ28xNycsIHRydWUpOyAvLyBSZW1vdGUgQWNjZXNzDQogICAgICAgICAgICB4eFJlbW90ZUFjY2VzcyA9IHJlc3BvbnNlczsNCiAgICAgICAgICAgIHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uID0gcmVzcG9uc2VzWyJBTVRfRW52aXJvbm1lbnREZXRlY3Rpb25TZXR0aW5nRGF0YSJdLnJlc3BvbnNlOw0KICAgICAgICAgICAgeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXSA9IE1ha2VUb0FycmF5KHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uWydEZXRlY3Rpb25TdHJpbmdzJ10pOw0KICAgICAgICAgICAgeHhDaXJhU2VydmVycyA9IHJlc3BvbnNlc1siQU1UX01hbmFnZW1lbnRQcmVzZW5jZVJlbW90ZVNBUCJdLnJlc3BvbnNlczsNCiAgICAgICAgICAgIHh4VXNlckluaXRpYXRlZENpcmEgPSByZXNwb25zZXNbIkFNVF9Vc2VySW5pdGlhdGVkQ29ubmVjdGlvblNlcnZpY2UiXS5yZXNwb25zZTsNCiAgICAgICAgICAgIHh4UmVtb3RlQWNjZXNzQ3JlZGVudGlhTGlua3MgPSByZXNwb25zZXNbIkFNVF9SZW1vdGVBY2Nlc3NDcmVkZW50aWFsQ29udGV4dCJdLnJlc3BvbnNlczsNCiAgICAgICAgICAgIHh4TVBTVXNlclBhc3MgPSByZXNwb25zZXNbIkFNVF9NUFNVc2VybmFtZVBhc3N3b3JkIl0ucmVzcG9uc2VzOw0KDQogICAgICAgICAgICAvLyBGaWd1cmUgb3V0IHBvbGljaWVzIGF0dGFjaGVkIHRvIHNlcnZlcnMuIENyZWF0ZSBhIHBvbGljeSB0eXBlIHRvIHNlcnZlciB0YWJsZS4NCiAgICAgICAgICAgIHh4UG9saWNpZXMgPSB7ICdVc2VyJzogW10sICdBbGVydCc6IFtdLCAnUGVyaW9kaWMnOiBbXSB9Ow0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiByZXNwb25zZXNbIkFNVF9SZW1vdGVBY2Nlc3NQb2xpY3lBcHBsaWVzVG9NUFMiXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICB2YXIgcG9saWN5ID0gcmVzcG9uc2VzWyJBTVRfUmVtb3RlQWNjZXNzUG9saWN5QXBwbGllc1RvTVBTIl0ucmVzcG9uc2VzW2ldOw0KICAgICAgICAgICAgICAgIHZhciBzZXJ2ZXIgPSBDbG9uZShnZXRJdGVtKHh4Q2lyYVNlcnZlcnMsICJOYW1lIiwgZ2V0SXRlbShwb2xpY3lbJ01hbmFnZWRFbGVtZW50J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXSwgIkBOYW1lIiwgIk5hbWUiKVsnVmFsdWUnXSkpOw0KICAgICAgICAgICAgICAgIHNlcnZlci5NcHNUeXBlID0gcG9saWN5WydNcHNUeXBlJ107IC8vIE1wc1R5cGUgd2FzIGFkZGVkIGluIEludGVsIEFNVCAxMS42DQogICAgICAgICAgICAgICAgdmFyIHB0eXBlID0gKGdldEl0ZW0ocG9saWN5WydQb2xpY3lTZXQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddLCAiQE5hbWUiLCAiUG9saWN5UnVsZU5hbWUiKVsnVmFsdWUnXSkuc3BsaXQoJyAnKVswXTsNCiAgICAgICAgICAgICAgICB4eFBvbGljaWVzW3B0eXBlXS5wdXNoKHNlcnZlcik7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHVwZGF0ZVJlbW90ZUFjY2VzcygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlUmVtb3RlQWNjZXNzKCkgew0KICAgICAgICAgICAgaWYgKHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uID09IG51bGwpIHJldHVybjsNCiAgICAgICAgICAgIHZhciB4ID0gJycsIGUgPSAnRGlzYWJsZWQnLCBjaXJhUHJveHlTdXBwb3J0ID0gKHh4UmVtb3RlQWNjZXNzWyJJUFNfSFRUUFByb3h5U2VydmljZSJdICYmIHh4UmVtb3RlQWNjZXNzWyJJUFNfSFRUUFByb3h5QWNjZXNzUG9pbnQiXSk7DQogICAgICAgICAgICBpZiAoeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXSAmJiB4eEVudmlyb25lbWVudERldGVjdGlvblsnRGV0ZWN0aW9uU3RyaW5ncyddLmxlbmd0aCA+IDApIHsgZSA9ICdFbmFibGVkLCAnICsgeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXS5sZW5ndGggKyAnIGRvbWFpbicgKyAoeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXS5sZW5ndGggPiAxPydzJzonJyk7IH0NCg0KICAgICAgICAgICAgLy8gR2VuZXJhbCBzZXR0aW5ncw0KICAgICAgICAgICAgeCArPSBUYWJsZVN0YXJ0KCk7DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkVudmlyb25tZW50IGRldGVjdGlvbiIsIGFkZExpbmsoZSwgJ2VkaXRFbnZpcm9ubWVudERldGVjdGlvbigpJykpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJVc2VyIGluaXRpYXRpb24gb3B0aW9ucyIsIGFkZExpbmtDb25kaXRpb25hbCh4eFVzZXJJbml0aWF0ZWRFbmFibGVkU3RhdGVbeHhVc2VySW5pdGlhdGVkQ2lyYVsnRW5hYmxlZFN0YXRlJ11dLCAnZWRpdFVzZXJJbml0aWF0ZWRDaXJhKCknLCB4eEFjY291bnRBZG1pbk5hbWUpKTsNCiAgICAgICAgICAgIHZhciB5ID0gJzxpPk5vbmU8L2k+JzsNCiAgICAgICAgICAgIGlmICh4eFBvbGljaWVzWydVc2VyJ10ubGVuZ3RoID4gMCkgeyB5ID0gJyc7IGZvciAodmFyIGkgaW4geHhQb2xpY2llc1snVXNlciddKSB7IGlmICh5Lmxlbmd0aCA+IDApIHkgKz0gJywgJzsgeSArPSB4eFBvbGljaWVzWydVc2VyJ11baV1bJ0FjY2Vzc0luZm8nXTsgaWYgKHh4UG9saWNpZXNbJ1VzZXInXVtpXS5NcHNUeXBlID09IDEpIHsgeSArPSAnIChDSUxBKSc7IH0gfSB9DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIlVzZXIgaW5pdGlhdGVkIGNvbm5lY3Rpb24iLCBhZGRMaW5rQ29uZGl0aW9uYWwoeSwgJ2VkaXRNcHNQb2xpY3koIlVzZXIiKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgdmFyIHkgPSAnPGk+Tm9uZTwvaT4nOw0KICAgICAgICAgICAgaWYgKHh4UG9saWNpZXNbJ0FsZXJ0J10ubGVuZ3RoID4gMCkgeyB5ID0gJyc7IGZvciAodmFyIGkgaW4geHhQb2xpY2llc1snQWxlcnQnXSkgeyBpZiAoeS5sZW5ndGggPiAwKSB5ICs9ICcsICc7IHkgKz0geHhQb2xpY2llc1snQWxlcnQnXVtpXVsnQWNjZXNzSW5mbyddOyBpZiAoeHhQb2xpY2llc1snQWxlcnQnXVtpXS5NcHNUeXBlID09IDEpIHsgeSArPSAnIChDSUxBKSc7IH0gfSB9DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkFsZXJ0IGluaXRpYXRlZCBjb25uZWN0aW9uIiwgYWRkTGlua0NvbmRpdGlvbmFsKHksICdlZGl0TXBzUG9saWN5KCJBbGVydCIpJywgeHhBY2NvdW50QWRtaW5OYW1lKSk7DQogICAgICAgICAgICB2YXIgeSA9ICc8aT5Ob25lPC9pPic7DQogICAgICAgICAgICBpZiAoeHhQb2xpY2llc1snUGVyaW9kaWMnXS5sZW5ndGggPiAwKSB7IHkgPSAnJzsgZm9yICh2YXIgaSBpbiB4eFBvbGljaWVzWydQZXJpb2RpYyddKSB7IGlmICh5Lmxlbmd0aCA+IDApIHkgKz0gJywgJzsgeSArPSB4eFBvbGljaWVzWydQZXJpb2RpYyddW2ldWydBY2Nlc3NJbmZvJ107IGlmICh4eFBvbGljaWVzWydQZXJpb2RpYyddW2ldLk1wc1R5cGUgPT0gMSkgeyB5ICs9ICcgKENJTEEpJzsgfSB9IH0NCiAgICAgICAgICAgIHZhciBwZXJpb2RpY1BvbGljeSA9IGdldEl0ZW0oeHhSZW1vdGVBY2Nlc3NbIkFNVF9SZW1vdGVBY2Nlc3NQb2xpY3lSdWxlIl0ucmVzcG9uc2VzLCAiUG9saWN5UnVsZU5hbWUiLCAiUGVyaW9kaWMiKTsNCiAgICAgICAgICAgIGlmIChwZXJpb2RpY1BvbGljeSkgew0KICAgICAgICAgICAgICAgIHZhciBleGRhdGEgPSBhdG9iKHBlcmlvZGljUG9saWN5WydFeHRlbmRlZERhdGEnXSk7DQogICAgICAgICAgICAgICAgaWYgKFJlYWRJbnQoZXhkYXRhLCAwKSA9PSAwKSB7IHkgKz0gJywgZWFjaCAnICsgUmVhZEludChleGRhdGEsIDQpICsgJyBzZWNvbmRzJzsgfQ0KICAgICAgICAgICAgICAgIGlmIChSZWFkSW50KGV4ZGF0YSwgMCkgPT0gMSkgeyB2YXIgaG91cnMgPSBSZWFkSW50KGV4ZGF0YSwgNCk7IHZhciBtaW51dGVzID0gUmVhZEludChleGRhdGEsIDgpOyBpZiAobWludXRlcyA8IDEwKSBtaW51dGVzID0gJzAnICsgbWludXRlczsgeSArPSAnLCBhdCAnICsgaG91cnMgKyAiOiIgKyBtaW51dGVzICsgJyBkYWlseSc7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiUGVyaW9kaWMgY29ubmVjdGlvbiIsIGFkZExpbmtDb25kaXRpb25hbCh5LCAnZWRpdE1wc1BvbGljeSgiUGVyaW9kaWMiKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KDQogICAgICAgICAgICAvLyBTaG93IE1QUyBzZXJ2ZXJzDQogICAgICAgICAgICB4ICs9ICI8YnI+IjsNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCByZW1vdGUgbWFuYWdlbWVudCBzZXJ2ZXJzLjxicj48YnI+IjsNCiAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzLmxlbmd0aCA9PSAwKSB7DQogICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD48YnI+PGk+Tm8gcmVtb3RlIHNlcnZlcnMgZm91bmQuPC9pPjwvZGl2Pjxicj4iOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4Q2lyYVNlcnZlcnMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGRlc2MgPSAnOicgKyB4eENpcmFTZXJ2ZXJzW2ldWydQb3J0J107DQogICAgICAgICAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzW2ldWydDTiddKSBkZXNjICs9ICcsICcgKyB4eENpcmFTZXJ2ZXJzW2ldWydDTiddOw0KICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93U2VydmVyRGV0YWlscygiICsgaSArICIpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyB4eENpcmFTZXJ2ZXJzW2ldWyJBY2Nlc3NJbmZvIl0gKyAiPC9iPiIgKyBFc2NhcGVIdG1sKGRlc2MpICsgIjwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBTaG93IE1QUyBwcm94aWVzIGlmIHN1cHBvcnRlZA0KICAgICAgICAgICAgaWYgKGNpcmFQcm94eVN1cHBvcnQpIHsNCiAgICAgICAgICAgICAgICB4ICs9ICI8YnI+TWFuYWdlIEhUVFAgcHJveGllcyB1c2VkIGZvciBtYW5hZ2VtZW50IGNvbm5lY3Rpb25zLjxicj48YnI+IjsNCiAgICAgICAgICAgICAgICB2YXIgcHJveHlTZXJ2aWNlID0geHhSZW1vdGVBY2Nlc3NbIklQU19IVFRQUHJveHlTZXJ2aWNlIl0ucmVzcG9uc2U7DQogICAgICAgICAgICAgICAgdmFyIHByb3hpZXMgPSB4eFJlbW90ZUFjY2Vzc1siSVBTX0hUVFBQcm94eUFjY2Vzc1BvaW50Il0ucmVzcG9uc2VzOw0KICAgICAgICAgICAgICAgIGlmIChwcm94aWVzLmxlbmd0aCA9PSAwKSB7DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPjxpPk5vIHByb3hpZXMgY29uZmlndXJlZC48L2k+PC9kaXY+PGJyPiI7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBwcm94aWVzKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAvL3ggKz0gIjxkaXYgY2xhc3M9aXRlbUJhciBvbmNsaWNrPXNob3dQcm94eURldGFpbHMoIiArIGkgKyAiKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48Yj4iICsgRXNjYXBlSHRtbChwcm94aWVzW2ldWydBY2Nlc3NJbmZvJ10pICsgIjoiICsgcHJveGllc1tpXVsnUHJveHlQb3J0J10gKyAiPC9iPiAvICIgKyBFc2NhcGVIdG1sKHByb3hpZXNbaV1bJ05ldHdvcmtEbnNTdWZmaXgnXSkgKyAiPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgY2xhc3M9aXRlbUJhciBvbmNsaWNrPXNob3dQcm94eURldGFpbHMoIiArIGkgKyAiKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48Yj4iICsgRXNjYXBlSHRtbChwcm94aWVzW2ldWydBY2Nlc3NJbmZvJ10pICsgIjoiICsgcHJveGllc1tpXVsnUG9ydCddICsgIjwvYj4gLyAiICsgRXNjYXBlSHRtbChwcm94aWVzW2ldWydOZXR3b3JrRG5zU3VmZml4J10pICsgIjwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHZhciBhZGRzZXJ2ZXJidXR0b24gPSAnJzsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHsNCiAgICAgICAgICAgICAgICBhZGRzZXJ2ZXJidXR0b24gPSBBZGRCdXR0b24oIkFkZCBTZXJ2ZXIuLi4iLCAiQWRkUmVtb3RlQWNjZXNzU2VydmVyKCkiKTsNCiAgICAgICAgICAgICAgICBpZiAoY2lyYVByb3h5U3VwcG9ydCkgeyBhZGRzZXJ2ZXJidXR0b24gKz0gQWRkQnV0dG9uKCJBZGQgUHJveHkuLi4iLCAiQWRkUmVtb3RlQWNjZXNzUHJveHkoKSIpOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICB4ICs9ICI8YnI+PHRkIGNsYXNzPXIxPiIgKyBUYWJsZUVuZChBZGRSZWZyZXNoQnV0dG9uKCJQdWxsUmVtb3RlQWNjZXNzKCkiKSArIGFkZHNlcnZlcmJ1dHRvbik7DQoNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVJlbW90ZUFjY2VzcycsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIHh4RWRpdE1wc1BvbGljeVR5cGU7DQogICAgICAgIGZ1bmN0aW9uIGVkaXRNcHNQb2xpY3kodHlwZSkgew0KICAgICAgICAgICAgdmFyIHggPSAnJywgY2lsYVN1cHBvcnQgPSAoKGFtdHZlcnNpb24gPiAxMSkgfHwgKChhbXR2ZXJzaW9uID09IDExKSAmJiAoYW10dmVyc2lvbiA+PSA2KSkpOw0KICAgICAgICAgICAgeHhFZGl0TXBzUG9saWN5VHlwZSA9IHR5cGU7DQogICAgICAgICAgICB2YXIgbmFtZSA9IHh4RWRpdE1wc1BvbGljeVR5cGU7DQogICAgICAgICAgICBpZiAobmFtZSA9PSAnVXNlcicpIG5hbWUgPSAnVXNlciBJbml0aWF0ZWQnOw0KICAgICAgICAgICAgdmFyIHBvbGljeSA9IGdldEl0ZW0oeHhSZW1vdGVBY2Nlc3NbIkFNVF9SZW1vdGVBY2Nlc3NQb2xpY3lSdWxlIl0ucmVzcG9uc2VzLCAiUG9saWN5UnVsZU5hbWUiLCBuYW1lKTsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PHNlbGVjdCBpZD1kMnNlcnZlcjEgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjA2cHggb25jaGFuZ2U9ZWRpdE1wc1BvbGljeVVwZGF0ZSgpPic7DQogICAgICAgICAgICB4ICs9ICc8b3B0aW9uIHZhbHVlPS0xPihOb25lKScNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhDaXJhU2VydmVycykgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPScgKyBpICsgJycgKyAoKHh4UG9saWNpZXNbdHlwZV1bMF0gJiYgeHhQb2xpY2llc1t0eXBlXVswXVsnTmFtZSddID09IHh4Q2lyYVNlcnZlcnNbaV1bJ05hbWUnXSkgPyAnIHNlbGVjdGVkJyA6ICcnKSArICc+JyArIHh4Q2lyYVNlcnZlcnNbaV1bJ0FjY2Vzc0luZm8nXSB9DQogICAgICAgICAgICB4ICs9ICc8L3NlbGVjdD48ZGl2PlByaW1hcnkgc2VydmVyPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIGlmIChjaWxhU3VwcG9ydCkgeyB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9ZDJzZXJ2ZXIxY2lyYSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDZweCBvbmNoYW5nZT1lZGl0TXBzUG9saWN5VXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0wPkNJUkEgLSBFeHRlcm5hbDxvcHRpb24gdmFsdWU9MScgKyAoKCh4eFBvbGljaWVzW3R5cGVdWzBdKSAmJiAoeHhQb2xpY2llc1t0eXBlXVswXS5NcHNUeXBlID09IDEpKT8nIHNlbGVjdGVkJzonJykgKyAnPkNJTEEgLSBJbnRlcm5hbDwvc2VsZWN0PjxkaXY+UHJpbWFyeSBNUFMgVHlwZTwvZGl2PjwvZGl2Pic7IH0NCiAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzLmxlbmd0aCA+IDEpIHsNCiAgICAgICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9ZDJzZXJ2ZXIyIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwNnB4IG9uY2hhbmdlPWVkaXRNcHNQb2xpY3lVcGRhdGUoKT4nOw0KICAgICAgICAgICAgICAgIHggKz0gJzxvcHRpb24gdmFsdWU9LTE+KE5vbmUpJw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhDaXJhU2VydmVycykgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPScgKyBpICsgJycgKyAoKHh4UG9saWNpZXNbdHlwZV1bMV0gJiYgeHhQb2xpY2llc1t0eXBlXVsxXVsnTmFtZSddID09IHh4Q2lyYVNlcnZlcnNbaV1bJ05hbWUnXSkgPyAnIHNlbGVjdGVkJyA6ICcnKSArICc+JyArIHh4Q2lyYVNlcnZlcnNbaV1bJ0FjY2Vzc0luZm8nXSB9DQogICAgICAgICAgICAgICAgeCArPSAnPC9zZWxlY3Q+PGRpdj5TZWNvbmRhcnkgc2VydmVyPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgICAgICBpZiAoY2lsYVN1cHBvcnQpIHsgeCArPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48c2VsZWN0IGlkPWQyc2VydmVyMmNpcmEgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjA2cHggb25jaGFuZ2U9ZWRpdE1wc1BvbGljeVVwZGF0ZSgpPjxvcHRpb24gdmFsdWU9MD5DSVJBIC0gRXh0ZXJuYWw8b3B0aW9uIHZhbHVlPTEnICsgKCgoeHhQb2xpY2llc1t0eXBlXVsxXSkgJiYgKHh4UG9saWNpZXNbdHlwZV1bMV0uTXBzVHlwZSA9PSAxKSkgPyAnIHNlbGVjdGVkJyA6ICcnKSArICc+Q0lMQSAtIEludGVybmFsPC9zZWxlY3Q+PGRpdj5TZWNvbmRhcnkgTVBTIFR5cGU8L2Rpdj48L2Rpdj4nOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICB2YXIgdCwgdiA9IDA7DQogICAgICAgICAgICBpZiAocG9saWN5KSB7IHYgPSBwb2xpY3lbJ1R1bm5lbExpZmVUaW1lJ107IH0NCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWQybGlmZXRpbWUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggb25jaGFuZ2U9ZWRpdE1wc1BvbGljeVVwZGF0ZSgpIHZhbHVlPScgKyB2ICsgJz4nOw0KICAgICAgICAgICAgeCArPSAnPGRpdj5UdW5uZWwgbGlmZXRpbWUgKFNlY29uZHMpPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIGlmICh0eXBlID09ICdQZXJpb2RpYycpIHsNCiAgICAgICAgICAgICAgICB0ID0gMDsNCiAgICAgICAgICAgICAgICB2ID0gMzYwMDsNCiAgICAgICAgICAgICAgICBpZiAocG9saWN5KSB7DQogICAgICAgICAgICAgICAgICAgIHZhciB4eCA9IGF0b2IocG9saWN5WydFeHRlbmRlZERhdGEnXSk7DQogICAgICAgICAgICAgICAgICAgIHQgPSBSZWFkSW50KHh4LCAwKTsNCiAgICAgICAgICAgICAgICAgICAgdiA9IFJlYWRJbnQoeHgsIDQpOw0KICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSAxKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbW0gPSBSZWFkSW50KHh4LCA4KTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtbSA8IDEwKSBtbSA9ICcwJyArIG1tOw0KICAgICAgICAgICAgICAgICAgICAgICAgdiArPSAnOicgKyBtbTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9ZDJ0dHlwZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDZweCBvbmNoYW5nZT1lZGl0TXBzUG9saWN5VXBkYXRlKCk+JzsNCiAgICAgICAgICAgICAgICB4ICs9ICc8b3B0aW9uIHZhbHVlPTAnICsgKHQgPT0gMCA/ICcgc2VsZWN0ZWQnIDogJycpICsgJz5QZXJpb2RpYywgdGltZSBpbnRlcnZhbDxvcHRpb24gdmFsdWU9MScgKyAodCA9PSAxID8gJyBzZWxlY3RlZCcgOiAnJykgKyAnPlRpbWUgb2YgZGF5LCBvbmNlIGEgZGF5Jw0KICAgICAgICAgICAgICAgIHggKz0gJzwvc2VsZWN0PjxkaXY+VHJpZ2dlciB0eXBlPC9kaXY+PC9kaXY+PGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48aW5wdXQgaWQ9ZDJ0aW1lciBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBvbmtleXVwPWVkaXRNcHNQb2xpY3lVcGRhdGUoKSB2YWx1ZT0nICsgdiArICc+PGRpdiBpZD10dHlwZWxhYmVsPjwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCB0eXBlICsgIiBDb25uZWN0aW9uIiwgMywgZWRpdE1wc1BvbGljeU9rLCB4KTsNCiAgICAgICAgICAgIGVkaXRNcHNQb2xpY3lVcGRhdGUoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVkaXRNcHNQb2xpY3lVcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgY2lsYVN1cHBvcnQgPSAoKGFtdHZlcnNpb24gPiAxMSkgfHwgKChhbXR2ZXJzaW9uID09IDExKSAmJiAoYW10dmVyc2lvbiA+PSA2KSkpOw0KICAgICAgICAgICAgdmFyIG9rID0gKHh4Q2lyYVNlcnZlcnMubGVuZ3RoIDw9IDEgfHwgKChRKCdkMnNlcnZlcjEnKS52YWx1ZSA9PSAtMSkgfHwgKFEoJ2Qyc2VydmVyMScpLnZhbHVlICE9IFEoJ2Qyc2VydmVyMicpLnZhbHVlKSkpOw0KICAgICAgICAgICAgaWYgKG9rID09IHRydWUgJiYgeHhFZGl0TXBzUG9saWN5VHlwZSA9PSAnUGVyaW9kaWMnICYmIFEoJ2QydHR5cGUnKS52YWx1ZSA9PSAxKSB7IHZhciBoaG1tID0gUSgnZDJ0aW1lcicpLnZhbHVlLnNwbGl0KCc6Jyk7IGlmIChoaG1tLmxlbmd0aCAhPSAyKSBvayA9IGZhbHNlOyBlbHNlIHsgdmFyIGhoID0gcGFyc2VJbnQoaGhtbVswXSk7IHZhciBtbSA9IHBhcnNlSW50KGhobW1bMV0pOyBpZiAoaGggPCAwIHx8IGhoID4gMjMgfHwgbW0gPCAwIHx8IG1tID4gNTkpIG9rID0gZmFsc2U7IH0gfQ0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzLmxlbmd0aCA+IDEpIFFFKCdkMnNlcnZlcjInLCBRKCdkMnNlcnZlcjEnKS52YWx1ZSAhPSAtMSk7DQogICAgICAgICAgICBpZiAoeHhFZGl0TXBzUG9saWN5VHlwZSA9PSAnUGVyaW9kaWMnKSB7DQogICAgICAgICAgICAgICAgUUUoJ2QydGltZXInLCBRKCdkMnNlcnZlcjEnKS52YWx1ZSAhPSAtMSk7DQogICAgICAgICAgICAgICAgUUgoJ3R0eXBlbGFiZWwnLCBRKCdkMnR0eXBlJykudmFsdWUgPT0gMCA/ICdUcmlnZ2VyIGludGVydmFsIChTZWNvbmRzKScgOiAnVGltZSBvZiBkYXkgKEhIOk1NKScpOw0KICAgICAgICAgICAgICAgIFFFKCdkMnR0eXBlJywgUSgnZDJzZXJ2ZXIxJykudmFsdWUgIT0gLTEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgUUUoJ2QybGlmZXRpbWUnLCBRKCdkMnNlcnZlcjEnKS52YWx1ZSAhPSAtMSk7DQoNCiAgICAgICAgICAgIC8vIElmIHdlIGFyZSBvbiBJbnRlbCBBTVQgMTEuNiBvciBoaWdoZXIsIGVuYWJsZSB0aGUgQ0lSQS9DSUxBIHNlbGVjdG9yIHdoZW4gbmVlZGVkLg0KICAgICAgICAgICAgaWYgKGNpbGFTdXBwb3J0KSB7DQogICAgICAgICAgICAgICAgUUUoJ2Qyc2VydmVyMWNpcmEnLCBRKCdkMnNlcnZlcjEnKS52YWx1ZSA+IC0xKQ0KICAgICAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzLmxlbmd0aCA+IDEpIHsgUUUoJ2Qyc2VydmVyMmNpcmEnLCAoUSgnZDJzZXJ2ZXIxJykudmFsdWUgPiAtMSkgJiYgKFEoJ2Qyc2VydmVyMicpLnZhbHVlID4gLTEpKTsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdE1wc1BvbGljeU9rKCkgew0KICAgICAgICAgICAgdmFyIG5hbWUgPSB4eEVkaXRNcHNQb2xpY3lUeXBlOw0KICAgICAgICAgICAgaWYgKG5hbWUgPT0gJ1VzZXInKSB7IG5hbWUgPSAnVXNlciBJbml0aWF0ZWQnOyB9DQoNCiAgICAgICAgICAgIGlmIChnZXRJdGVtKHh4UmVtb3RlQWNjZXNzWyJBTVRfUmVtb3RlQWNjZXNzUG9saWN5UnVsZSJdLnJlc3BvbnNlcywgIlBvbGljeVJ1bGVOYW1lIiwgbmFtZSkpIHsNCiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgb2xkIHBvbGljeQ0KICAgICAgICAgICAgICAgIGFtdHN0YWNrLkRlbGV0ZSgnQU1UX1JlbW90ZUFjY2Vzc1BvbGljeVJ1bGUnLCB7ICdQb2xpY3lSdWxlTmFtZSc6IG5hbWUgfSwgZWRpdE1wc1BvbGljeU9rMik7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIC8vIE5vIG9sZCBwb2xpY3kgdG8gcmVtb3ZlLCBza2lwIHRoaXMuDQogICAgICAgICAgICAgICAgZWRpdE1wc1BvbGljeU9rMigpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdE1wc1BvbGljeU9rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIHZhciBjaWxhU3VwcG9ydCA9ICgoYW10dmVyc2lvbiA+IDExKSB8fCAoKGFtdHZlcnNpb24gPT0gMTEpICYmIChhbXR2ZXJzaW9uID49IDYpKSk7DQogICAgICAgICAgICBpZiAoUSgnZDJzZXJ2ZXIxJykudmFsdWUgPT0gLTEpIHsgUHVsbFJlbW90ZUFjY2VzcygpOyByZXR1cm47IH0NCg0KICAgICAgICAgICAgdmFyIHRyaWdnZXIgPSAwOw0KICAgICAgICAgICAgaWYgKHh4RWRpdE1wc1BvbGljeVR5cGUgPT0gJ0FsZXJ0JykgdHJpZ2dlciA9IDE7DQogICAgICAgICAgICBpZiAoeHhFZGl0TXBzUG9saWN5VHlwZSA9PSAnUGVyaW9kaWMnKSB0cmlnZ2VyID0gMjsNCg0KICAgICAgICAgICAgLy8gU2V0dXAgZXh0ZW5kZWQgZGF0YQ0KICAgICAgICAgICAgdmFyIGV4dGVuZGVkRGF0YSA9IG51bGw7DQogICAgICAgICAgICBpZiAodHJpZ2dlciA9PSAyKSB7DQogICAgICAgICAgICAgICAgdmFyIHRpbWVydHlwZSA9IFEoJ2QydHR5cGUnKS52YWx1ZTsNCiAgICAgICAgICAgICAgICB2YXIgZXhkYXRhID0gSW50VG9TdHIoUSgnZDJ0aW1lcicpLnZhbHVlKTsgLy8gSW50ZXJ2YWwgdHJpZ2dlcg0KICAgICAgICAgICAgICAgIGlmICh0aW1lcnR5cGUgPT0gMSkgeyB2YXIgaGhtbSA9IFEoJ2QydGltZXInKS52YWx1ZS5zcGxpdCgnOicpOyBleGRhdGEgPSBJbnRUb1N0cihwYXJzZUludChoaG1tWzBdKSkgKyBJbnRUb1N0cihwYXJzZUludChoaG1tWzFdKSk7IH0gLy8gVGltZSBvZiBkYXkgdHJpZ2dlcg0KICAgICAgICAgICAgICAgIGV4dGVuZGVkRGF0YSA9IGJ0b2EoSW50VG9TdHIodGltZXJ0eXBlKSArIGV4ZGF0YSk7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgTVBTIHNlcnZlciByZWZlcmVuY2VzDQogICAgICAgICAgICB2YXIgc2VydmVyMSwgc2VydmVyMjsNCiAgICAgICAgICAgIGlmIChRKCdkMnNlcnZlcjEnKS52YWx1ZSA+PSAwKSB7IHNlcnZlcjEgPSAnPEFkZHJlc3MgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyI+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL3JvbGUvYW5vbnltb3VzPC9BZGRyZXNzPjxSZWZlcmVuY2VQYXJhbWV0ZXJzIHhtbG5zPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciPjxSZXNvdXJjZVVSSSB4bWxucz0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZCI+aHR0cDovL2ludGVsLmNvbS93YmVtL3dzY2ltLzEvYW10LXNjaGVtYS8xL0FNVF9NYW5hZ2VtZW50UHJlc2VuY2VSZW1vdGVTQVA8L1Jlc291cmNlVVJJPjxTZWxlY3RvclNldCB4bWxucz0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZCI+PFNlbGVjdG9yIE5hbWU9Ik5hbWUiPicgKyB4eENpcmFTZXJ2ZXJzW1EoJ2Qyc2VydmVyMScpLnZhbHVlXVsnTmFtZSddICsgJzwvU2VsZWN0b3I+PC9TZWxlY3RvclNldD48L1JlZmVyZW5jZVBhcmFtZXRlcnM+JzsgfQ0KICAgICAgICAgICAgaWYgKFEoJ2Qyc2VydmVyMScpLnZhbHVlID49IDAgJiYgeHhDaXJhU2VydmVycy5sZW5ndGggPiAxICYmIFEoJ2Qyc2VydmVyMicpLnZhbHVlID49IDApIHsgc2VydmVyMiA9ICc8QWRkcmVzcyB4bWxucz0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nIj5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L0FkZHJlc3M+PFJlZmVyZW5jZVBhcmFtZXRlcnMgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyI+PFJlc291cmNlVVJJIHhtbG5zPSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIj5odHRwOi8vaW50ZWwuY29tL3diZW0vd3NjaW0vMS9hbXQtc2NoZW1hLzEvQU1UX01hbmFnZW1lbnRQcmVzZW5jZVJlbW90ZVNBUDwvUmVzb3VyY2VVUkk+PFNlbGVjdG9yU2V0IHhtbG5zPSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIj48U2VsZWN0b3IgTmFtZT0iTmFtZSI+JyArIHh4Q2lyYVNlcnZlcnNbUSgnZDJzZXJ2ZXIyJykudmFsdWVdWydOYW1lJ10gKyAnPC9TZWxlY3Rvcj48L1NlbGVjdG9yU2V0PjwvUmVmZXJlbmNlUGFyYW1ldGVycz4nOyB9DQoNCiAgICAgICAgICAgIC8vIFB1dCB0aGUgQ0lSQS9DSUxBIHNlcnZlcnMgaW4gdGhlIHJpZ2h0IGJpbnMuDQogICAgICAgICAgICB2YXIgY2lyYVNlcnZlcnMgPSBbXTsNCiAgICAgICAgICAgIHZhciBjaWxhU2VydmVycyA9IFtdOw0KICAgICAgICAgICAgaWYgKGNpbGFTdXBwb3J0KSB7DQogICAgICAgICAgICAgICAgLy8gT25seSBJbnRlbCBBTVQgMTEuNiBzdXBwb3J0cyB0aGlzDQogICAgICAgICAgICAgICAgaWYgKHNlcnZlcjEpIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKFEoJ2Qyc2VydmVyMWNpcmEnKS52YWx1ZSA9PSAwKSB7IGNpcmFTZXJ2ZXJzLnB1c2goc2VydmVyMSk7IH0gZWxzZSB7IGNpbGFTZXJ2ZXJzLnB1c2goc2VydmVyMSk7IH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKHNlcnZlcjIpIHsgaWYgKFEoJ2Qyc2VydmVyMmNpcmEnKS52YWx1ZSA9PSAwKSB7IGNpcmFTZXJ2ZXJzLnB1c2goc2VydmVyMik7IH0gZWxzZSB7IGNpbGFTZXJ2ZXJzLnB1c2goc2VydmVyMik7IH0gfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gSWYgb2xkZXIgdGhhbiBJbnRlbCBBTVQgMTEuNiwgcHV0IGFsbCBzZXJ2ZXJzIGluIHRoZSBDSVJBIGJ1Y2tldC4NCiAgICAgICAgICAgICAgICBpZiAoc2VydmVyMSkgeyBjaXJhU2VydmVycy5wdXNoKHNlcnZlcjEpOyBpZiAoc2VydmVyMikgeyBjaXJhU2VydmVycy5wdXNoKHNlcnZlcjIpOyB9IH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gR28gYWhlYWQgYW5kIGNyZWF0ZSB0aGUgbmV3IENJUkEvQ0lMQSBwb2xpY3kuDQogICAgICAgICAgICBhbXRzdGFjay5BTVRfUmVtb3RlQWNjZXNzU2VydmljZV9BZGRSZW1vdGVBY2Nlc3NQb2xpY3lSdWxlKHRyaWdnZXIsIFEoJ2QybGlmZXRpbWUnKS52YWx1ZSwgZXh0ZW5kZWREYXRhLCBjaXJhU2VydmVycywgY2lsYVNlcnZlcnMsIFB1bGxSZW1vdGVBY2Nlc3MpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcDsNCiAgICAgICAgZnVuY3Rpb24gZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uKGEpIHsNCiAgICAgICAgICAgIGlmIChhICE9IDEpIHsgZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wID0gKHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uWydEZXRlY3Rpb25TdHJpbmdzJ10pID8gQ2xvbmUoeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXSkgOiBbXTsgfQ0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHggKz0gJ0VudGVyIHVwIHRvIDQgaW50cmFuZXQgZG9tYWluIHN1ZmZpeC4gSWYgdGhlIGNvbXB1dGVyIGlzIG91dHNpZGUgdGhlc2UgZG9tYWlucywgSW50ZWwmcmVnOyBBTVQgbG9jYWwgcG9ydHMgd2lsbCBiZSBjbG9zZWQgYW5kIHJlbW90ZSBzZXJ2ZXIgY29ubmVjdGlvbnMgd2lsbCBiZSBhY3RpdmUuPGJyPjxicj4nOw0KICAgICAgICAgICAgaWYgKGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcC5sZW5ndGggPT0gMCkgeyB4ICs9ICI8aT5ObyBpbnRyYW5ldCBkb21haW5zLCBFbnZpcm9uZW1udCBkZXRlY3Rpb24gZGlzYWJsZWQuPC9pPjxicj4iOyB9DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcCkgeyB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgc3R5bGU9bWFyZ2luLXJpZ2h0OjA+PGRpdiBzdHlsZT1mbG9hdDpyaWdodD4iICsgQWRkQnV0dG9uMigiUmVtb3ZlIiwgImVkaXRFbnZpcm9ubWVudERldGVjdGlvblJlbW92ZSgiICsgaSArICIpIikgKyAiPC9kaXY+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDozcHg7bWF4LXdpZHRoOjI2MHB4O292ZXJmbG93OmhpZGRlbiB0aXRsZT0nIiArIGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcFtpXSArICInPjxiPiIgKyBlZGl0RW52aXJvbm1lbnREZXRlY3Rpb25UbXBbaV0gKyAiPC9iPjwvZGl2PjwvZGl2PiI7IH0NCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUgJiYgZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wLmxlbmd0aCA8IDQpIHsgeCArPSAiPGJyPjxpbnB1dCBpZD1lZElucHV0IHBsYWNlaG9sZGVyPWludHJhbmV0Lm9yZyBzdHlsZT13aWR0aDoyNzZweCBvbmtleXVwPWVkSW5wdXRDaGcoKSBtYXhsZW5ndGg9NjM+PGlucHV0IHR5cGU9YnV0dG9uIGlkPWVkQWRkIHZhbHVlPUFkZCBzdHlsZT13aWR0aDo4MHB4O21hcmdpbi1sZWZ0OjVweCBvbmNsaWNrPWVkaXRFbnZpcm9ubWVudERldGVjdGlvbkFkZCgpPiI7IH0NCiAgICAgICAgICAgIGlmIChhID09IDEpIFFIKCdpZF9kaWFsb2dPcHRpb25zJywgeCk7IGVsc2Ugc2V0RGlhbG9nTW9kZSgxMSwgJ0Vudmlyb25tZW50IERldGVjdGlvbicsIHh4QWNjb3VudEFkbWluTmFtZT8zOjEsIGVkaXRFbnZpcm9ubWVudERldGVjdGlvbkRsZywgeCk7DQogICAgICAgICAgICBlZElucHV0Q2hnKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBlZGl0RW52aXJvbm1lbnREZXRlY3Rpb25EbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhBY2NvdW50QWRtaW5OYW1lKSB7DQogICAgICAgICAgICAgICAgdmFyIHQgPSBDbG9uZSh4eEVudmlyb25lbWVudERldGVjdGlvbik7DQogICAgICAgICAgICAgICAgdFsnRGV0ZWN0aW9uU3RyaW5ncyddID0gZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wOw0KICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coJ0FNVF9FbnZpcm9ubWVudERldGVjdGlvblNldHRpbmdEYXRhJywgdCk7DQogICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfRW52aXJvbm1lbnREZXRlY3Rpb25TZXR0aW5nRGF0YScsIHQsIGVkaXRFbnZpcm9ubWVudERldGVjdGlvbkRsZzIsIDAsIDEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uRGxnMihzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsgbWVzc2FnZWJveCgnRW52aXJvbm1lbnQgRGV0ZWN0aW9uJywgJ0ZhaWxlZCB0byBhZGQgc2VydmVyLCBzdGF0dXMgJyArIHN0YXR1cyk7IH0NCiAgICAgICAgICAgIGVsc2UgaWYgKChyZXNwb25zZS5Cb2R5WyJSZXR1cm5WYWx1ZSJdKSAmJiAocmVzcG9uc2UuQm9keVsiUmV0dXJuVmFsdWUiXSAhPSAwKSkgeyBtZXNzYWdlYm94KCdFbnZpcm9ubWVudCBEZXRlY3Rpb24nLCByZXNwb25zZS5Cb2R5LlJldHVyblZhbHVlU3RyLnJlcGxhY2UoL18vZywgJyAnKSk7IH0NCiAgICAgICAgICAgIGVsc2UgeyBQdWxsUmVtb3RlQWNjZXNzKCk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVkSW5wdXRDaGcoKSB7DQogICAgICAgICAgICBpZiAoZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wLmxlbmd0aCA8IDQpIFFFKCdlZEFkZCcsIFEoJ2VkSW5wdXQnKS52YWx1ZS5sZW5ndGggPiAwKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVkaXRFbnZpcm9ubWVudERldGVjdGlvbkFkZCgpIHsNCiAgICAgICAgICAgIGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcC5wdXNoKFEoJ2VkSW5wdXQnKS52YWx1ZSk7DQogICAgICAgICAgICBlZGl0RW52aXJvbm1lbnREZXRlY3Rpb24oMSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBlZGl0RW52aXJvbm1lbnREZXRlY3Rpb25SZW1vdmUoaCkgew0KICAgICAgICAgICAgZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wLnNwbGljZShoLCAxKTsNCiAgICAgICAgICAgIGVkaXRFbnZpcm9ubWVudERldGVjdGlvbigxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVkaXRVc2VySW5pdGlhdGVkQ2lyYSgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBzID0gIiI7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4VXNlckluaXRpYXRlZEVuYWJsZWRTdGF0ZSkgeyBzICs9ICc8aW5wdXQgdHlwZT1yYWRpbyBuYW1lPWQxMSBpZD13bCcgKyBpICsgJyB2YWx1ZT0nICsgaSArICcgJyArICgoeHhVc2VySW5pdGlhdGVkQ2lyYVsnRW5hYmxlZFN0YXRlJ10gPT0gaSkgPyAiY2hlY2tlZCIgOiAiIikgKyAnPicgKyB4eFVzZXJJbml0aWF0ZWRFbmFibGVkU3RhdGVbaV0gKyAnPGJyPic7IH0NCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdVc2VyIEluaXRpYXRlZCBUdW5uZWwnLCAzLCBlZGl0VXNlckluaXRpYXRlZENpcmFEbGcsIHMpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdFVzZXJJbml0aWF0ZWRDaXJhRGxnKCkgeyBhbXRzdGFjay5BTVRfVXNlckluaXRpYXRlZENvbm5lY3Rpb25TZXJ2aWNlX1JlcXVlc3RTdGF0ZUNoYW5nZShkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPWQxMV06Y2hlY2tlZCcpLnZhbHVlLCBudWxsLCBlZGl0VXNlckluaXRpYXRlZENpcmFEbGcyKTsgfQ0KICAgICAgICBmdW5jdGlvbiBlZGl0VXNlckluaXRpYXRlZENpcmFEbGcyKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7IGlmIChzdGF0dXMgPT0gMjAwKSB7IGFtdHN0YWNrLkdldCgnQU1UX1VzZXJJbml0aWF0ZWRDb25uZWN0aW9uU2VydmljZScsIGVkaXRVc2VySW5pdGlhdGVkQ2lyYURsZzMsIDAsIDEpOyB9IH0NCiAgICAgICAgZnVuY3Rpb24gZWRpdFVzZXJJbml0aWF0ZWRDaXJhRGxnMyhzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgeyBpZiAoc3RhdHVzID09IDIwMCkgeyB4eFVzZXJJbml0aWF0ZWRDaXJhID0gcmVzcG9uc2UuQm9keTsgdXBkYXRlUmVtb3RlQWNjZXNzKCk7IH0gfQ0KDQogICAgICAgIHZhciB4eFNob3dTZXJ2ZXJEZXRhaWxzSGFuZGxlOw0KICAgICAgICBmdW5jdGlvbiBzaG93U2VydmVyRGV0YWlscyhoKSB7DQogICAgICAgICAgICB4eFNob3dTZXJ2ZXJEZXRhaWxzSGFuZGxlID0gaDsNCiAgICAgICAgICAgIHZhciBzZXJ2ZXIgPSB4eENpcmFTZXJ2ZXJzW2hdOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJBY2Nlc3MgTmFtZSIsIHNlcnZlclsiQWNjZXNzSW5mbyJdKTsNCiAgICAgICAgICAgIGlmIChzZXJ2ZXJbIlBvcnQiXSkgeCArPSBhZGRIdG1sVmFsdWUoIlBvcnQiLCBzZXJ2ZXJbIlBvcnQiXSk7DQogICAgICAgICAgICBpZiAoc2VydmVyWyJDTiJdKSB4ICs9IGFkZEh0bWxWYWx1ZSgiQ29tbW9uIE5hbWUiLCBzZXJ2ZXJbIkNOIl0pOw0KDQogICAgICAgICAgICB2YXIgY3JlZGVudGlhbGxpbmsgPSBnZXRFbGVtZW50V2l0aENvbnRleHRTZWxlY3RvclZhbHVlKHh4UmVtb3RlQWNjZXNzQ3JlZGVudGlhTGlua3MsIHNlcnZlclsnTmFtZSddKTsNCiAgICAgICAgICAgIGlmIChjcmVkZW50aWFsbGluaykgew0KICAgICAgICAgICAgICAgIHZhciBjcmVkZW50aWFsc2VsZWN0b3J2YWx1ZSA9IGNyZWRlbnRpYWxsaW5rWydFbGVtZW50SW5Db250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVsnVmFsdWUnXTsNCiAgICAgICAgICAgICAgICBpZiAoY3JlZGVudGlhbHNlbGVjdG9ydmFsdWUuaW5kZXhPZignVXNlcm5hbWUnKSA+IDApIHsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ0F1dGhlbnRpY2F0aW9uIFR5cGUnLCAnVXNlciAmIFBhc3MgLyBTZXJ2ZXItQXV0aCBUTFMnKTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ1JlbW90ZSBJRCcsIGdldEluc3RhbmNlKHh4TVBTVXNlclBhc3MsIGNyZWRlbnRpYWxzZWxlY3RvcnZhbHVlKVsnUmVtb3RlSUQnXSk7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ0F1dGhlbnRpY2F0aW9uIFR5cGUnLCAnQ2VydGlmaWNhdGUgLyBNdXR1YWwtQXV0aCBUTFMnKTsNCg0KICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IGdldEluc3RhbmNlKHh4Q2VydGlmaWNhdGVzLCBjcmVkZW50aWFsc2VsZWN0b3J2YWx1ZSk7DQogICAgICAgICAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdDZXJ0aWZpY2F0ZSBOYW1lJywgcGFyc2VDZXJ0TmFtZShjWydTdWJqZWN0J10pWydDTiddKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHZhciBidXR0b25zID0gMTsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIGJ1dHRvbnMgPSA1Ow0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIlJlbW90ZSBTZXJ2ZXIgIyIgKyAoaCArIDEpLCBidXR0b25zLCBzaG93U2VydmVyRGV0YWlsc09rLCB4KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGdldEVsZW1lbnRXaXRoQ29udGV4dFNlbGVjdG9yVmFsdWUoZWxlbWVudHMsIHZhbHVlKSB7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGVsZW1lbnRzKSB7DQogICAgICAgICAgICAgICAgZWxlbWVudHNbaV1bJ0VsZW1lbnRQcm92aWRpbmdDb250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXSA9IE1ha2VUb0FycmF5KGVsZW1lbnRzW2ldWydFbGVtZW50UHJvdmlkaW5nQ29udGV4dCddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10pOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gZWxlbWVudHNbaV1bJ0VsZW1lbnRQcm92aWRpbmdDb250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXSkgeyBpZiAoZWxlbWVudHNbaV1bJ0VsZW1lbnRQcm92aWRpbmdDb250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVtqXVsnVmFsdWUnXSA9PSB2YWx1ZSkgcmV0dXJuIGVsZW1lbnRzW2ldOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gbnVsbDsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dTZXJ2ZXJEZXRhaWxzT2socikgew0KICAgICAgICAgICAgLy8gRGVsZXRlIHRoZSBzZWxlY3RlZCBDSVJBIHNlcnZlciANCiAgICAgICAgICAgIGlmIChyID09IDIpIHsgYW10c3RhY2suRGVsZXRlKCdBTVRfTWFuYWdlbWVudFByZXNlbmNlUmVtb3RlU0FQJywgeyAnTmFtZSc6IHh4Q2lyYVNlcnZlcnNbeHhTaG93U2VydmVyRGV0YWlsc0hhbmRsZV1bJ05hbWUnXSB9LCBzaG93U2VydmVyRGV0YWlsc09rMik7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dTZXJ2ZXJEZXRhaWxzT2syKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSA0MDgpIHsgbWVzc2FnZWJveCgnUmVtb3RlIFNlcnZlciBSZW1vdmFsJywgJ1VuYWJsZSB0byByZW1vdmUgc2VydmVyLCBhY2Nlc3MgZGVuaWVkLicpOyB9IGVsc2UgeyBQdWxsUmVtb3RlQWNjZXNzKCk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHBhcnNlQ2VydE5hbWUoeCkgew0KICAgICAgICAgICAgdmFyIGosIHIgPSB7fSwgeHggPSB4LnNwbGl0KCcsJyk7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4KSB7IGogPSB4eFtpXS5pbmRleE9mKCc9Jyk7IHJbeHhbaV0uc3Vic3RyaW5nKDAsIGopXSA9IHh4W2ldLnN1YnN0cmluZyhqICsgMSk7IH0NCiAgICAgICAgICAgIHJldHVybiByOw0KICAgICAgICB9DQogICAgICAgIA0KICAgICAgICBmdW5jdGlvbiBzaG93UHJveHlEZXRhaWxzKGgpIHsNCiAgICAgICAgICAgIHZhciBwcm94eSA9IHh4UmVtb3RlQWNjZXNzWyJJUFNfSFRUUFByb3h5QWNjZXNzUG9pbnQiXS5yZXNwb25zZXNbaF07DQoNCiAgICAgICAgICAgIHZhciB4ID0gYWRkSHRtbFZhbHVlKCJBY2Nlc3MgbmFtZSIsIHByb3h5WyJBY2Nlc3NJbmZvIl0gKyAnOicgKyBwcm94eVsiUHJveHlQb3J0Il0pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkROUyBzdWZmZXgiLCBwcm94eVsiTmV0d29ya0Ruc1N1ZmZpeCJdKTsNCiAgICAgICAgICAgIC8veCArPSBhZGRIdG1sVmFsdWUoIlByb3h5IHR5cGUiLCBbJ0FkbWluaXN0cmF0b3InLCAnT3BlcmF0aW5nIHN5c3RlbSddW3Byb3h5WyJQcm94eVR5cGUiXV0pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlByb3h5IHR5cGUiLCBbJ0FkbWluaXN0cmF0b3InLCAnT3BlcmF0aW5nIHN5c3RlbSddW3Byb3h5WyJUeXBlIl1dKTsNCiAgICAgICAgICAgIC8veCArPSBhZGRIdG1sVmFsdWUoIkxhc3QgdGltZSB1c2VkIiwgcHJveHlbIkxhc3RUaW1lVXNlZCJdKTsNCg0KICAgICAgICAgICAgdmFyIGJ1dHRvbnMgPSAxOw0KICAgICAgICAgICAgaWYgKHh4QWNjb3VudEFkbWluTmFtZSkgeyBidXR0b25zID0gNTsgfQ0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIkhUVFAgUHJveHkgIyIgKyAoaCArIDEpLCBidXR0b25zLCBzaG93UHJveHlEZXRhaWxzT2ssIHgsIGgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1Byb3h5RGV0YWlsc09rKHIsIGgpIHsNCiAgICAgICAgICAgIC8vIERlbGV0ZSB0aGUgc2VsZWN0ZWQgcHJveHkgc2VydmVyDQogICAgICAgICAgICB2YXIgcHJveHkgPSB4eFJlbW90ZUFjY2Vzc1siSVBTX0hUVFBQcm94eUFjY2Vzc1BvaW50Il0ucmVzcG9uc2VzW2hdOw0KICAgICAgICAgICAgaWYgKHIgPT0gMikgeyBhbXRzdGFjay5EZWxldGUoJ0lQU19IVFRQUHJveHlBY2Nlc3NQb2ludCcsIHsgJ05hbWUnOiBwcm94eVsnTmFtZSddIH0sIHNob3dQcm94eURldGFpbHNPazIpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93UHJveHlEZXRhaWxzT2syKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSA0MDgpIHsgbWVzc2FnZWJveCgnSFRUUCBQcm94eSBSZW1vdmFsJywgJ1VuYWJsZSB0byByZW1vdmUgSFRUUCBwcm94eSwgYWNjZXNzIGRlbmllZC4nKTsgfSBlbHNlIHsgUHVsbFJlbW90ZUFjY2VzcygpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NQcm94eSgpIHsNCiAgICAgICAgICAgIC8vIEFkZFJlbW90ZUFjY2Vzc1Byb3h5IEhvc3QgbmFtZSA9IDIsIElwdjQgPSAzLCBJcHY2ID0gNA0KICAgICAgICAgICAgdmFyIHggPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48c2VsZWN0IGlkPWQydHlwZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDZweCBvbmNoYW5nZT1BZGRSZW1vdGVBY2Nlc3NQcm94eVVwZGF0ZSgpPjxvcHRpb24gdmFsdWU9Mj5Ib3N0bmFtZSBGUUROPG9wdGlvbiB2YWx1ZT0zPklQdjQgYWRkcmVzczxvcHRpb24gdmFsdWU9ND5JUHY2IGFkZHJlc3M8L3NlbGVjdD48ZGl2PkNvbm5lY3Rpb24gdHlwZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMmhvc3Qgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggbWF4bGVuZ3RoPTI1NSBvbmtleXVwPUFkZFJlbW90ZUFjY2Vzc1Byb3h5VXBkYXRlKCk+PGRpdiBpZD1kMnR5cGVzcGFuPjwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMnBvcnQgb25rZXlwcmVzcz0icmV0dXJuIChldmVudC5jaGFyQ29kZSA9PSAwIHx8IChldmVudC5jaGFyQ29kZSA+PSA0OCAmJiBldmVudC5jaGFyQ29kZSA8PSA1NykpIiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBvbmtleXVwPUFkZFJlbW90ZUFjY2Vzc1Byb3h5VXBkYXRlKCk+PGRpdj5Qb3J0PC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWQyZG9tYWluIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IG1heGxlbmd0aD0xOTEgb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NQcm94eVVwZGF0ZSgpPjxkaXY+RE5TIHN1ZmZpeDwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiQWRkIEhUVFAgUHJveHkiLCAzLCBBZGRSZW1vdGVBY2Nlc3NQcm94eU9rLCB4KTsNCiAgICAgICAgICAgIEFkZFJlbW90ZUFjY2Vzc1Byb3h5VXBkYXRlKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NQcm94eVVwZGF0ZSgpIHsNCiAgICAgICAgICAgIHZhciBvayA9IChRKCdkMmhvc3QnKS52YWx1ZS5sZW5ndGggIT0gMCkgJiYgKFEoJ2QyZG9tYWluJykudmFsdWUubGVuZ3RoICE9IDApOw0KICAgICAgICAgICAgaWYgKChRKCdkMnBvcnQnKS52YWx1ZS5sZW5ndGggPT0gMCkgfHwgKHBhcnNlSW50KFEoJ2QycG9ydCcpLnZhbHVlKSA+IDY1NTM1KSkgeyBvayA9IGZhbHNlOyB9DQogICAgICAgICAgICBRRSgnaWR4X2RsZ09rQnV0dG9uJywgb2spOw0KICAgICAgICAgICAgUUgoJ2QydHlwZXNwYW4nLCBbJycsICcnLCAnRlFETiAvIGhvc3RuYW1lJywgJ0lQdjQgYWRkcmVzcycsICdJUHY2IGFkZHJlc3MnXVtRKCdkMnR5cGUnKS52YWx1ZV0pOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkUmVtb3RlQWNjZXNzUHJveHlPaygpIHsNCiAgICAgICAgICAgIGFtdHN0YWNrLklQU19IVFRQUHJveHlTZXJ2aWNlX0FkZFByb3h5QWNjZXNzUG9pbnQoUSgnZDJob3N0JykudmFsdWUsIFEoJ2QydHlwZScpLnZhbHVlLCBwYXJzZUludChRKCdkMnBvcnQnKS52YWx1ZSksIFEoJ2QyZG9tYWluJykudmFsdWUsIEFkZFJlbW90ZUFjY2Vzc1Byb3h5T2syKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZFJlbW90ZUFjY2Vzc1Byb3h5T2syKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goJ0FkZCBQcm94eSBTZXJ2ZXInLCAnRmFpbGVkIHRvIGFkZCBwcm94eSwgc3RhdHVzICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5Cb2R5WyJSZXR1cm5WYWx1ZSJdICE9IDApIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdBZGQgUHJveHkgU2VydmVyJywgcmVzcG9uc2UuQm9keS5SZXR1cm5WYWx1ZVN0ci5yZXBsYWNlKC9fL2csICcgJykpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsUmVtb3RlQWNjZXNzKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NTZXJ2ZXIoKSB7DQoNCiAgICAgICAgICAgIHZhciBjZXJ0cyA9IFtdOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eENlcnRpZmljYXRlcykgeyBpZiAoeHhDZXJ0aWZpY2F0ZXNbaV0uWFByaXZhdGVLZXkpIHsgY2VydHMucHVzaCh4eENlcnRpZmljYXRlc1tpXSk7IH0gfQ0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PHNlbGVjdCBpZD1kMnR5cGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjA2cHggb25jaGFuZ2U9QWRkUmVtb3RlQWNjZXNzU2VydmVyVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0yMDE+SG9zdG5hbWUgRlFETjxvcHRpb24gdmFsdWU9Mz5JUHY0IGFkZHJlc3M8L3NlbGVjdD48ZGl2PkNvbm5lY3Rpb24gdHlwZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMm5hbWUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKT48ZGl2IGlkPWQybG5hbWU+PC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWQycG9ydCBvbmtleXByZXNzPSJyZXR1cm4gKGV2ZW50LmNoYXJDb2RlID09IDAgfHwgKGV2ZW50LmNoYXJDb2RlID49IDQ4ICYmIGV2ZW50LmNoYXJDb2RlIDw9IDU3KSkiIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IHZhbHVlPTQ0MzMgb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKT48ZGl2PlNlcnZlciBwb3J0PC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHggaWQ9ZDJ1Y24+PGlucHV0IGlkPWQyY24gc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKT48ZGl2PlNlcnZlciBDb21tb24gTmFtZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9ZDJhdXRoIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwNnB4IG9uY2hhbmdlPUFkZFJlbW90ZUFjY2Vzc1NlcnZlclVwZGF0ZSgpPic7DQogICAgICAgICAgICBpZiAoY2VydHMubGVuZ3RoID4gMCkgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPTE+Q2VydGlmaWNhdGUnOyB9DQogICAgICAgICAgICB4ICs9ICc8b3B0aW9uIHZhbHVlPTI+VXNlcm5hbWUvUGFzc3dvcmQ8L3NlbGVjdD48ZGl2PkF1dGhlbnRpY2F0aW9uIHR5cGU8L2Rpdj48L2Rpdj4nOw0KICAgICAgICAgICAgeCArPSAnPHNwYW4gaWQ9ZDJ1dHlwZT4nOw0KICAgICAgICAgICAgeCArPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48aW5wdXQgaWQ9ZDJ1c2VyIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IG9ua2V5dXA9QWRkUmVtb3RlQWNjZXNzU2VydmVyVXBkYXRlKCk+PGRpdj5Vc2VybmFtZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMnBhc3Mgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKT48ZGl2PlN0cm9uZyBQYXNzd29yZDwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8L3NwYW4+JzsNCiAgICAgICAgICAgIHggKz0gJzxzcGFuIGlkPWQyY3R5cGU+JzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PHNlbGVjdCBpZD1kMmNlcnQgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjA2cHggb25jaGFuZ2U9QWRkUmVtb3RlQWNjZXNzU2VydmVyVXBkYXRlKCk+JzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gY2VydHMpIHsgeCArPSAnPG9wdGlvbiB2YWx1ZT0nICsgY2VydHNbaV1bJ0luc3RhbmNlSUQnXS5zdWJzdHJpbmcoMzQpICsgJz4nICsgcGFyc2VDZXJ0TmFtZShjZXJ0c1tpXVsnU3ViamVjdCddKVsnQ04nXTsgfQ0KICAgICAgICAgICAgeCArPSAnPC9zZWxlY3Q+PGRpdj5DZXJ0aWZpY2F0ZTwvZGl2PjwvZGl2Pjwvc3Bhbj4nOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIkFkZCBSZW1vdGUgU2VydmVyIiwgMywgQWRkUmVtb3RlQWNjZXNzU2VydmVyT2ssIHgpOw0KICAgICAgICAgICAgQWRkUmVtb3RlQWNjZXNzU2VydmVyVXBkYXRlKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJPaygpIHsNCiAgICAgICAgICAgIHZhciBjcmVmLCB1c2VyLCBwYXNzLCBjbjsNCiAgICAgICAgICAgIGlmIChRKCdkMmF1dGgnKS52YWx1ZSA9PSAxKSB7DQogICAgICAgICAgICAgICAgY3JlZiA9ICc8QWRkcmVzcyB4bWxucz0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nIj5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmc8L0FkZHJlc3M+PFJlZmVyZW5jZVBhcmFtZXRlcnMgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyI+PFJlc291cmNlVVJJIHhtbG5zPSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIj5odHRwOi8vaW50ZWwuY29tL3diZW0vd3NjaW0vMS9hbXQtc2NoZW1hLzEvQU1UX1B1YmxpY0tleUNlcnRpZmljYXRlPC9SZXNvdXJjZVVSST48U2VsZWN0b3JTZXQgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiPjxTZWxlY3RvciBOYW1lPSJJbnN0YW5jZUlEIj5JbnRlbChyKSBBTVQgQ2VydGlmaWNhdGU6IEhhbmRsZTogJyArIFEoJ2QyY2VydCcpLnZhbHVlICsgJzwvU2VsZWN0b3I+PC9TZWxlY3RvclNldD48L1JlZmVyZW5jZVBhcmFtZXRlcnM+JzsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgdXNlciA9IFEoJ2QydXNlcicpLnZhbHVlOw0KICAgICAgICAgICAgICAgIHBhc3MgPSBRKCdkMnBhc3MnKS52YWx1ZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChRKCdkMmNuJykudmFsdWUubGVuZ3RoID4gMCkgY24gPSBRKCdkMmNuJykudmFsdWU7DQogICAgICAgICAgICBhbXRzdGFjay5BTVRfUmVtb3RlQWNjZXNzU2VydmljZV9BZGRNcFNlcnZlcihRKCdkMm5hbWUnKS52YWx1ZSwgUSgnZDJ0eXBlJykudmFsdWUsIFEoJ2QycG9ydCcpLnZhbHVlLCBRKCdkMmF1dGgnKS52YWx1ZSwgY3JlZiwgdXNlciwgcGFzcywgY24sIEFkZFJlbW90ZUFjY2Vzc1NlcnZlck9rMik7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJPazIoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnQWRkIEludGVybmV0IFNlcnZlcicsICdGYWlsZWQgdG8gYWRkIHNlcnZlciwgc3RhdHVzICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5Cb2R5WyJSZXR1cm5WYWx1ZSJdICE9IDApIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdBZGQgSW50ZXJuZXQgU2VydmVyJywgcmVzcG9uc2UuQm9keS5SZXR1cm5WYWx1ZVN0ci5yZXBsYWNlKC9fL2csICcgJykpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsUmVtb3RlQWNjZXNzKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgb2sgPSAoUSgnZDJuYW1lJykudmFsdWUubGVuZ3RoICE9IDApOw0KICAgICAgICAgICAgaWYgKFEoJ2QydHlwZScpLnZhbHVlID09IDMgJiYgb2sgPT0gdHJ1ZSkgIHsgb2sgPSAoUSgnZDJjbicpLnZhbHVlLmxlbmd0aCAhPSAwKTsgfQ0KICAgICAgICAgICAgaWYgKFEoJ2QyYXV0aCcpLnZhbHVlID09IDIgJiYgb2sgPT0gdHJ1ZSkgeyBvayA9ICgoUSgnZDJ1c2VyJykudmFsdWUubGVuZ3RoICE9IDApICYmIChwYXNzd29yZGNoZWNrKFEoJ2QycGFzcycpLnZhbHVlKSkpOyB9DQogICAgICAgICAgICBpZiAoKFEoJ2QycG9ydCcpLnZhbHVlLmxlbmd0aCA9PSAwKSB8fCAocGFyc2VJbnQoUSgnZDJwb3J0JykudmFsdWUpID4gNjU1MzUpKSB7IG9rID0gZmFsc2U7IH0NCiAgICAgICAgICAgIGlmICgoUSgnZDJuYW1lJykudmFsdWUuaW5kZXhPZignOicpICE9IC0xKSB8fCAoKFEoJ2QydHlwZScpLnZhbHVlID09IDMpICYmIChRKCdkMmNuJykudmFsdWUuaW5kZXhPZignOicpICE9IC0xKSkpIHsgb2sgPSBmYWxzZTsgfQ0KICAgICAgICAgICAgUUgoJ2QybG5hbWUnLCAoUSgnZDJ0eXBlJykudmFsdWUgPT0gMjAxKSA/ICdIb3N0bmFtZScgOiAnSVB2NCBBZGRyZXNzJyk7DQogICAgICAgICAgICBRVignZDJ1dHlwZScsIFEoJ2QyYXV0aCcpLnZhbHVlID09IDIpOw0KICAgICAgICAgICAgUVYoJ2QydWNuJywgUSgnZDJ0eXBlJykudmFsdWUgPT0gMyk7DQogICAgICAgICAgICBRVignZDJjdHlwZScsIFEoJ2QyYXV0aCcpLnZhbHVlID09IDEpOw0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gRWRpdCBDb21wdXRlciBOYW1lICYgRE5TIGZlYXR1cmUNCiAgICAgICAgLy8NCg0KICAgICAgICBmdW5jdGlvbiBzaG93RWRpdE5hbWVEbGcoeCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHQgPSBhbXRzeXNzdGF0ZVsnQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlWyJIb3N0TmFtZSJdLCB5ID0gYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZVsiRG9tYWluTmFtZSJdOw0KICAgICAgICAgICAgaWYgKHkgIT0gbnVsbCAmJiB5Lmxlbmd0aCA+IDApIHQgKz0gIi4iICsgeTsNCiAgICAgICAgICAgIHZhciByID0gJzxicj48ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMTFuYW1lIHZhbHVlPSInICsgdCArICciIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4PjxkaXY+TmFtZSAmIERvbWFpbjwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICBpZiAoeCA9PSAxKSB7DQogICAgICAgICAgICAgICAgdmFyIHMgPSAoYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZVsiU2hhcmVkRlFETiJdID09IHRydWUpOw0KICAgICAgICAgICAgICAgIHIgKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PHNlbGVjdCBpZD1kMTFmcWRuIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4PjxvcHRpb24gdmFsdWU9dHJ1ZSAnICsgKHM/J3NlbGVjdGVkJzonJykgKyAnPlNoYXJlZCwgc2FtZSBhcyBPUzxvcHRpb24gdmFsdWU9ImZhbHNlIiAnICsgKHM/Jyc6J3NlbGVjdGVkJykgKyAnPkRlZGljYXRlZCwgZGlmZmVyZW50IGZyb20gT1M8L3NlbGVjdD48ZGl2Pk5hbWUgU2hhcmluZzwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnQ29tcHV0ZXIgTmFtZScsIDMsIGVkaXROYW1lRGxnT2ssIHIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdE5hbWVEbGdPaygpIHsNCiAgICAgICAgICAgIHZhciBpID0gUSgnZDExbmFtZScpLnZhbHVlLCBqID0gaS5pbmRleE9mKCcuJyksIGsgPSAnJzsNCiAgICAgICAgICAgIGlmIChqID49IDApIHsgayA9IGkuc3Vic3RyaW5nKGogKyAxKTsgaSA9IGkuc3Vic3RyaW5nKDAsIGopOyB9DQogICAgICAgICAgICB2YXIgY2xvbmUgPSBDbG9uZShhbXRzeXNzdGF0ZVsnQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlKTsNCiAgICAgICAgICAgIGNsb25lWyJIb3N0TmFtZSJdID0gaTsNCiAgICAgICAgICAgIGNsb25lWyJEb21haW5OYW1lIl0gPSBrOw0KICAgICAgICAgICAgaWYgKFEoJ2QxMWZxZG4nKSkgeyBjbG9uZVsiU2hhcmVkRlFETiJdID0gZDExZnFkbi52YWx1ZTsgfQ0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfR2VuZXJhbFNldHRpbmdzJywgY2xvbmUsIGZ1bmN0aW9uKCkgeyBhbXRzdGFjay5HZXQoJ0FNVF9HZW5lcmFsU2V0dGluZ3MnLCBjb21wdXRlck5hbWVHZXQsIDAsIDEpOyB9LCAwLCAxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGNvbXB1dGVyTmFtZUdldChzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZSA9IHJlc3BvbnNlLkJvZHk7IHVwZGF0ZVN5c3RlbVN0YXR1cygpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93RWRpdERuc0RsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBnID0gYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZTsNCiAgICAgICAgICAgIHZhciB2ID0gMDsNCiAgICAgICAgICAgIGlmIChnWyJERE5TVXBkYXRlQnlESENQU2VydmVyRW5hYmxlZCJdID09IHRydWUpIHYgPSAxOw0KICAgICAgICAgICAgaWYgKGdbIkRETlNVcGRhdGVFbmFibGVkIl0gPT0gdHJ1ZSkgdiA9IDI7DQogICAgICAgICAgICBpZHhfZDIzZGRucy52YWx1ZSA9IHY7DQogICAgICAgICAgICBpZHhfZDIzaW50ZXJ2YWwudmFsdWUgPSBnWydERE5TUGVyaW9kaWNVcGRhdGVJbnRlcnZhbCddOw0KICAgICAgICAgICAgaWR4X2QyM3R0bC52YWx1ZSA9IGdbJ0RETlNUVEwnXTsNCiAgICAgICAgICAgIHNob3dFZGl0RG5zRGxnQ2hhbmdlKCk7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDIzLCAnRHluYW1pYyBETlMgY2xpZW50JywgMywgc2hvd0VkaXREbnNEbGdPayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93RWRpdERuc0RsZ09rKCkgew0KICAgICAgICAgICAgdmFyIGNsb25lID0gQ2xvbmUoYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZSk7DQogICAgICAgICAgICBjbG9uZVsiREROU1VwZGF0ZUVuYWJsZWQiXSA9ICgoaWR4X2QyM2RkbnMudmFsdWUgPT0gMik/dHJ1ZTpmYWxzZSk7DQogICAgICAgICAgICBjbG9uZVsiREROU1VwZGF0ZUJ5REhDUFNlcnZlckVuYWJsZWQiXSA9ICgoaWR4X2QyM2RkbnMudmFsdWUgPT0gMSk/dHJ1ZTpmYWxzZSk7DQogICAgICAgICAgICBpZiAoaWR4X2QyM2RkbnMudmFsdWUgPT0gMikgew0KICAgICAgICAgICAgICAgIGNsb25lWyJERE5TUGVyaW9kaWNVcGRhdGVJbnRlcnZhbCJdID0gaWR4X2QyM2ludGVydmFsLnZhbHVlOw0KICAgICAgICAgICAgICAgIGNsb25lWyJERE5TVFRMIl0gPSBpZHhfZDIzdHRsLnZhbHVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfR2VuZXJhbFNldHRpbmdzJywgY2xvbmUsIGZ1bmN0aW9uKCkgeyBhbXRzdGFjay5HZXQoJ0FNVF9HZW5lcmFsU2V0dGluZ3MnLCBjb21wdXRlck5hbWVHZXQsIDAsIDEpOyB9LCAwLCAxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dFZGl0RG5zRGxnQ2hhbmdlKCkgew0KICAgICAgICAgICAgUUUoJ2lkeF9kMjNpbnRlcnZhbCcsIGlkeF9kMjNkZG5zLnZhbHVlID09IDIpOw0KICAgICAgICAgICAgUUUoJ2lkeF9kMjN0dGwnLCBpZHhfZDIzZGRucy52YWx1ZSA9PSAyKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEludGVsIEFNVCBGZWF0dXJlcw0KICAgICAgICAvLw0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dGZWF0dXJlc0RsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgIXh4QWNjb3VudEFkbWluTmFtZSkgcmV0dXJuOw0KICAgICAgICAgICAgaWR4X2Q5cmVkaXIuY2hlY2tlZCA9IGFtdGZlYXR1cmVzWzBdLCBpZHhfZDlrdm0uY2hlY2tlZCA9IGFtdGZlYXR1cmVzWzNdLCBpZHhfZDlpZGVyLmNoZWNrZWQgPSBhbXRmZWF0dXJlc1syXSwgaWR4X2Q5c29sLmNoZWNrZWQgPSBhbXRmZWF0dXJlc1sxXTsNCiAgICAgICAgICAgIFFWKCdpZHhfZDlrdm1fZGl2JywgYW10ZmVhdHVyZXNbM10gIT0gdW5kZWZpbmVkKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoOSwgJ0ludGVsJnJlZzsgQU1UIEZlYXR1cmVzJywgMywgZmVhdHVyZXNEbGdPaykNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGZlYXR1cmVzRGxnT2soKSB7DQogICAgICAgICAgICB2YXIgciA9IGFtdHN5c3N0YXRlWydBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlJ10ucmVzcG9uc2U7DQogICAgICAgICAgICByWyJMaXN0ZW5lckVuYWJsZWQiXSA9IGlkeF9kOXJlZGlyLmNoZWNrZWQ7DQogICAgICAgICAgICByWyJFbmFibGVkU3RhdGUiXSA9IDMyNzY4ICsgKChpZHhfZDlpZGVyLmNoZWNrZWQ/MTowKSArIChpZHhfZDlzb2wuY2hlY2tlZD8yOjApKTsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9SZWRpcmVjdGlvblNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlKHJbIkVuYWJsZWRTdGF0ZSJdLA0KICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goIkVycm9yIiwgIlJlZGlyZWN0aW9uU2VydmljZSwgUmVxdWVzdFN0YXRlQ2hhbmdlIEVycm9yICIgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suQ0lNX0tWTVJlZGlyZWN0aW9uU0FQX1JlcXVlc3RTdGF0ZUNoYW5nZSgoaWR4X2Q5a3ZtLmNoZWNrZWQpPzI6MywgMCwNCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goIkVycm9yIiwgIktWTVJlZGlyZWN0aW9uU0FQLCBSZXF1ZXN0U3RhdGVDaGFuZ2UgRXJyb3IgIiArIHN0YXR1cyk7IHJldHVybjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCJBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlIiwgciwgZnVuY3Rpb24oc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCJFcnJvciIsICJSZWRpcmVjdGlvblNlcnZpY2UgUFVUIEVycm9yICIgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbXRzdGFjay5HZXQoIkFNVF9SZWRpcmVjdGlvblNlcnZpY2UiLCBmZWF0dXJlc0RsZ0dldDEsIDAsIDEpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLkdldCgiQ0lNX0tWTVJlZGlyZWN0aW9uU0FQIiwgZmVhdHVyZXNEbGdHZXQyLCAwLCAxKSB9LCAwLCAxKQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgKTt9DQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZmVhdHVyZXNEbGdHZXQxKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgeyBhbXRzeXNzdGF0ZVsnQU1UX1JlZGlyZWN0aW9uU2VydmljZSddLnJlc3BvbnNlID0gcmVzcG9uc2UuQm9keTsgdXBkYXRlU3lzdGVtU3RhdHVzKCk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGZlYXR1cmVzRGxnR2V0MihzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgYW10c3lzc3RhdGVbJ0NJTV9LVk1SZWRpcmVjdGlvblNBUCddLnJlc3BvbnNlID0gcmVzcG9uc2UuQm9keTsgdXBkYXRlU3lzdGVtU3RhdHVzKCk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEludGVsIEFNVCBVc2VyIENvbnNlbnQNCiAgICAgICAgLy8NCg0KICAgICAgICBmdW5jdGlvbiBzaG93Q29uc2VudERsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBvcHRpbnJlcXVpcmVkID0gYW10c3lzc3RhdGVbJ0lQU19PcHRJblNlcnZpY2UnXS5yZXNwb25zZVsiT3B0SW5SZXF1aXJlZCJdOw0KICAgICAgICAgICAgaWR4X2QxMG5vbmUuY2hlY2tlZCA9IChvcHRpbnJlcXVpcmVkID09IDApOw0KICAgICAgICAgICAgaWR4X2QxMGt2bS5jaGVja2VkID0gKG9wdGlucmVxdWlyZWQgPT0gMSk7DQogICAgICAgICAgICBpZHhfZDEwYWxsLmNoZWNrZWQgPSAob3B0aW5yZXF1aXJlZCA9PSAweEZGRkZGRkZGKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTAsICdVc2VyIENvbnNlbnQnLCAzLCBjb25zZW50RGxnT2spDQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBjb25zZW50RGxnT2soKSB7DQogICAgICAgICAgICBhbXRzeXNzdGF0ZVsnSVBTX09wdEluU2VydmljZSddLnJlc3BvbnNlWyJPcHRJblJlcXVpcmVkIl0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPWQxMF06Y2hlY2tlZCcpLnZhbHVlOw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCJJUFNfT3B0SW5TZXJ2aWNlIiwgYW10c3lzc3RhdGVbJ0lQU19PcHRJblNlcnZpY2UnXS5yZXNwb25zZSwgZnVuY3Rpb24oKSB7IGFtdHN0YWNrLkdldCgiSVBTX09wdEluU2VydmljZSIsIGNvbnNlbnRHZXQsIDAsIDEpOyB9LCAwLCAxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGNvbnNlbnRHZXQoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSB7IFB1bGxTeXN0ZW1TdGF0dXMoKTsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gTkVUV09SSyBTRVRUSU5HUw0KICAgICAgICAvLw0KDQoNCg0KICAgICAgICAvKg0KICAgICAgICBJUHY2ICVBZGRyVHlwZSU6DQogICAgICAgICAgICAwIC0gQWRkcmVzcyBnZW5lcmF0ZWQgZnJvbTogZmU4MDo6LzY0ICsgSW50ZXJmYWNlIElELA0KICAgICAgICAgICAgMSAtIEFkZHJlc3MgZ2VuZXJhdGVkIGZyb206IFtSb3V0ZXIgYWR2ZXJ0aXNlZCBwcmVmaXhdICsgW0ludGVyZmFjZSBJRF0sDQogICAgICAgICAgICAyIC0gR2xvYmFsIElQdjYgYWRkcmVzcyBvYnRhaW5lZCBmcm9tIERIQ1B2NiBTZXJ2ZXIsDQogICAgICAgICAgICAzIC0gSVB2NiB1bmljYXN0IGFkZHJlc3MgY29uZmlndXJlZCBieSB0aGUgdXNlciwNCiAgICAgICAgICAgIDQgLSBSZXR1cm5lZCBieSBGVyBmb3IgSVB2NiBhZGRyZXNzZXMgdGhhdCBhcmUgbm90IG93bmVkIGJ5IEZXIChzdWNoIGFzIElQdjYgcm91dGVyIGFkZHJlc3MsIGNvbmZpZ3VyYXRpb24gc2VydmVyIGFkZHJlc3MgZXRjLikNCg0KICAgICAgICBJUHY2ICVBZGRyU3RhdGUlOg0KICAgICAgICAgICAgMCAtIERBRCBpcyBzdGlsbCBpbiBwcm9jZXNzIGZvciB0aGlzIGFkZHJlc3MsDQogICAgICAgICAgICAxIC0gQWRkcmVzcyBpcyB2YWxpZCBhbmQgbWF5IGJlIHVzZWQgZm9yIG5ldyBjb21tdW5pY2F0aW9uLA0KICAgICAgICAgICAgMiAtIEFkZHJlc3MgaXMgZGVwcmVjYXRlZCBhbmQgc2hvdWxkIG5vdCBiZSB1c2VkIGZvciBuZXcgY29tbXVuaWNhdGlvbiwNCiAgICAgICAgICAgIDMgLSBDb3ZlcnMgYm90aCB0aGUgcHJlZmVycmVkIGFuZCBkZXByZWNhdGVkIHN0YXRlcywNCiAgICAgICAgICAgIDQgLSBUaGUgdmFsaWQgbGlmZXRpbWUgb2YgdGhlIGFkZHJlc3MgaGFzIGV4cGlyZWQsDQogICAgICAgICAgICA1IC0gQW4gaW50ZXJmYWNlIElEIGNvbGxpc2lvbiBoYXMgYmVlbiBkZXRlY3RlZCBmb3IgdGhpcyBhZGRyZXNzIHdoZW4gcGVyZm9ybWluZyBEQUQsDQogICAgICAgICAgICA2IC0gUmV0dXJuZWQgYnkgRlcgZm9yIElQdjYgYWRkcmVzc2VzIHRoYXQgYXJlIG5vdCBvd25lZCBieSBGVyAoc3VjaCBhcyBJUHY2IHJvdXRlciBhZGRyZXNzLCBjb25maWd1cmF0aW9uIHNlcnZlciBhZGRyZXNzIGV0Yy4NCiAgICAgICAgKi8NCiAgICAgICAgLy8gaXB2NmFkZHJ0eXBlIGFyZSBlbGVtZW50IDAgdG8gNCwgaXB2NmFkZHJzdGF0ZSBhcmUgNSBhbmQgYWZ0ZXIuIE1lcmdlZCBib3RoIGFycmF5cyB0byBjdXQgZG93biBzaXplDQogICAgICAgIHZhciBpcHY2YWRkcnR5cGUgPSBbIkxpbmsgbG9jYWwgYWRkcmVzcyIsICJOZXR3b3JrIGxvY2FsIGFkZHJlc3MiLCAiR2xvYmFsIGFkZHJlc3MiLCAiVXNlciBjb25maWd1cmVkIiwgIk5vdCBhbGxvd2VkIiwgIkRBRCBpbiBwcm9ncmVzcyIsICJ2YWxpZCIsICJkZXByZWNhdGVkIiwgInByZWZlcnJlZC9kZXByZWNhdGVkIiwgImV4cGlyZWQiLCAiY29sbGlzaW9uIiwgIm5vdCBhbGxvd2VkIl07DQogICAgICAgIGZ1bmN0aW9uIHNob3dJUHY2QWRkckRsZyhuZXRpZmlkLCBhZGRyc3RyKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9IFRhYmxlU3RhcnQoKTsNCiAgICAgICAgICAgIHQgPSBhZGRyc3RyLnNwbGl0KCcsJyk7DQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHQubGVuZ3RoOyBpICs9IDMpIHsNCiAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIjxiPiIgKyB0W2ldICsgIjwvYj48YnI+PHNwYW4gc3R5bGU9Zm9udC1zaXplOjEwcHg+IiArIGlwdjZhZGRydHlwZVt0W2kgKyAxXV0gKyAiLCAiICsgaXB2NmFkZHJ0eXBlWyt0W2kgKyAyXSArIDVdICsgIjwvc3Bhbj4iLCAiIik7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnSVB2NiBhZGRyZXNzZXMgZm9yICcgKyAobmV0aWZpZD09MD8nd2lyZWQnOid3aXJlbGVzcycpICsgJyBpbnRlcmZhY2UnLCAxLCBudWxsLCB4ICsgVGFibGVFbmQoKSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93SVB2NlN0YXRlRGxnKG5ldGlmaWQsIHN0YXRlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8ICFhbXRzeXNzdGF0ZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHp6ID0gYW10c3lzc3RhdGVbJ0lQU19JUHY2UG9ydFNldHRpbmdzJ10ucmVzcG9uc2VzW25ldGlmaWRdOw0KICAgICAgICAgICAgaXB2Nm1hbnVhbCA9IChuZXRpZmlkID09IDAgJiYgKGlzSXBBZGRyZXNzKHp6WyJJUHY2QWRkcmVzcyJdKSB8fCBpc0lwQWRkcmVzcyh6elsiRGVmYXVsdFJvdXRlciJdKSB8fCBpc0lwQWRkcmVzcyh6elsiUHJpbWFyeUROUyJdKSB8fCBpc0lwQWRkcmVzcyh6elsiU2Vjb25kYXJ5RE5TIl0pKSk7DQoNCiAgICAgICAgICAgIFFWKCdpZF9kMjFtYW51YWxkaXYnLCBuZXRpZmlkID09IDApOw0KICAgICAgICAgICAgUVYoJ2lkX2QyMXN1Ym5ldGRpdicsIGZhbHNlKTsNCiAgICAgICAgICAgIFFWKCdkMjFvMCcsIHRydWUpOw0KICAgICAgICAgICAgUVYoJ2QyMWwwJywgdHJ1ZSk7DQogICAgICAgICAgICBRSCgnZDIxbDAnLCAnSVB2NiBkaXNhYmxlZCcpOw0KICAgICAgICAgICAgUUgoJ2QyMWwxJywgJ0lQdjYgZW5hYmxlZCwgYXV0b21hdGljJyk7DQogICAgICAgICAgICBRSCgnZDIxbDInLCAnSVB2NiBlbmFibGVkLCBhdXRvbWF0aWMgKyBtYW51YWwgYWRkcmVzc2UnKTsNCiAgICAgICAgICAgIGQyMW8wLmNoZWNrZWQgPSAhc3RhdGU7DQogICAgICAgICAgICBkMjFvMS5jaGVja2VkID0gc3RhdGUgJiYgIWlwdjZtYW51YWw7DQogICAgICAgICAgICBkMjFvMi5jaGVja2VkID0gc3RhdGUgJiYgaXB2Nm1hbnVhbDsNCiAgICAgICAgICAgIGlkeF9kMjFhZGRyZXNzLnZhbHVlID0gaXNJcEFkZHJlc3MoenpbIklQdjZBZGRyZXNzIl0sJycpOw0KICAgICAgICAgICAgaWR4X2QyMWdhdGV3YXkudmFsdWUgPSBpc0lwQWRkcmVzcyh6elsiRGVmYXVsdFJvdXRlciJdLCcnKTsNCiAgICAgICAgICAgIGlkeF9kMjFkbnMxLnZhbHVlID0gaXNJcEFkZHJlc3MoenpbIlByaW1hcnlETlMiXSwnJyk7DQogICAgICAgICAgICBpZHhfZDIxZG5zMi52YWx1ZSA9IGlzSXBBZGRyZXNzKHp6WyJTZWNvbmRhcnlETlMiXSwnJyk7DQogICAgICAgICAgICB1cGRhdGVJUFNldHVwRGxnKCk7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDIxLCAnSVB2NiBzdXBwb3J0IGZvciAnICsgKG5ldGlmaWQ9PTA/J3dpcmVkJzond2lyZWxlc3MnKSArICcgaW50ZXJmYWNlJywgMywgZnVuY3Rpb24oKSB7IHNob3dJUHY2U3RhdGVEbGdPayhuZXRpZmlkKSB9KQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0lQdjZTdGF0ZURsZ09rKG5ldGlmaWQpIHsNCiAgICAgICAgICAgIHZhciB6eiA9IGFtdHN5c3N0YXRlWydJUFNfSVB2NlBvcnRTZXR0aW5ncyddLnJlc3BvbnNlc1tuZXRpZmlkXTsNCiAgICAgICAgICAgIGlmIChuZXRpZmlkID09IDApIHsgLy8gV2UgY2FuIG9ubHkgc2V0IElQdjYgbWFudWFsIGFkZHJlc3MgZm9yIHdpcmVkIGludGVyZmFjZQ0KICAgICAgICAgICAgICAgIGlmIChkMjFvMS5jaGVja2VkKSB7IC8vIEZ1bGx5IGF1dG9tYXRpYywgY2xlYXIgYWxsIGFkZHJlc3Nlcw0KICAgICAgICAgICAgICAgICAgICB6elsiSVB2NkFkZHJlc3MiXSA9IHp6WyJEZWZhdWx0Um91dGVyIl0gPSB6elsiUHJpbWFyeUROUyJdID0genpbIlNlY29uZGFyeUROUyJdID0gIjo6IjsNCiAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCJJUFNfSVB2NlBvcnRTZXR0aW5ncyIsIHp6LCBzaG93SVB2NlN0YXRlRGxnRG9uZSk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmIChkMjFvMi5jaGVja2VkKSB7IC8vIE1hbnVhbCwgc2V0IGFkZHJlc3Nlcw0KICAgICAgICAgICAgICAgICAgICB6elsiSVB2NkFkZHJlc3MiXSA9IGlkeF9kMjFhZGRyZXNzLnZhbHVlOw0KICAgICAgICAgICAgICAgICAgICB6elsiRGVmYXVsdFJvdXRlciJdID0gaWR4X2QyMWdhdGV3YXkudmFsdWU7DQogICAgICAgICAgICAgICAgICAgIHp6WyJQcmltYXJ5RE5TIl0gPSBpZHhfZDIxZG5zMS52YWx1ZTsNCiAgICAgICAgICAgICAgICAgICAgenpbIlNlY29uZGFyeUROUyJdID0gaWR4X2QyMWRuczIudmFsdWU7DQogICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLlB1dCgiSVBTX0lQdjZQb3J0U2V0dGluZ3MiLCB6eiwgc2hvd0lQdjZTdGF0ZURsZ0RvbmUpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIC8vIFRoaXMgY29kZSBlbmFibGVzL2Rpc2FibGVzIElQdjYgZm9yIGEgZ2l2ZW4gaW50ZXJmYWNlLg0KICAgICAgICAgICAgdmFyIGVsZW1lbnRTZXR0aW5ncyA9IGFtdHN5c3N0YXRlWydDSU1fRWxlbWVudFNldHRpbmdEYXRhJ10ucmVzcG9uc2VzOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50U2V0dGluZ3MubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudFNldHRpbmdzW2ldWydTZXR0aW5nRGF0YSddICYmIGVsZW1lbnRTZXR0aW5nc1tpXVsnU2V0dGluZ0RhdGEnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWydWYWx1ZSddID09ICgnSW50ZWwocikgSVBTIElQdjYgU2V0dGluZ3MgJyArIG5ldGlmaWQpKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBjbG9uZSA9IENsb25lKGVsZW1lbnRTZXR0aW5nc1tpXSk7DQogICAgICAgICAgICAgICAgICAgIGNsb25lWydJc0N1cnJlbnQnXSA9ICgoZDIxbzAuY2hlY2tlZCk/MjoxKTsNCiAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCJDSU1fRWxlbWVudFNldHRpbmdEYXRhIiwgY2xvbmUsIHNob3dJUHY2U3RhdGVEbGdEb25lKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93SVB2NlN0YXRlRGxnRG9uZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsNCiAgICAgICAgICAgICAgICBhbXRzeXNzdGF0ZSA9IHVuZGVmaW5lZDsNCiAgICAgICAgICAgICAgICBQdWxsU3lzdGVtU3RhdHVzKCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goJ0lQdjYgc3VwcG9ydCcsICdVbmFibGUgdG8gc2V0IElQdjYgc3RhdGUsIGVycm9yICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1BpbmdBY3Rpb25EbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgZyA9IGFtdHN5c3N0YXRlWydBTVRfR2VuZXJhbFNldHRpbmdzJ10ucmVzcG9uc2U7DQogICAgICAgICAgICB2YXIgdiA9IChnWyJQaW5nUmVzcG9uc2VFbmFibGVkIl0gPT0gdHJ1ZSkgKyAoKGdbIlJtY3BQaW5nUmVzcG9uc2VFbmFibGVkIl0gPT0gdHJ1ZSkgPDwgMSk7DQogICAgICAgICAgICBkMjBhLmNoZWNrZWQgPSAodiA9PSAwKTsNCiAgICAgICAgICAgIGQyMGIuY2hlY2tlZCA9ICh2ID09IDEpOw0KICAgICAgICAgICAgZDIwYy5jaGVja2VkID0gKHYgPT0gMik7DQogICAgICAgICAgICBkMjBkLmNoZWNrZWQgPSAodiA9PSAzKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMjAsICdJbnRlbCZyZWc7IEFNVCBQaW5nIFJlc3BvbnNlJywgMywgc2hvd1BpbmdBY3Rpb25EbGdPayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93UGluZ0FjdGlvbkRsZ09rKCkgew0KICAgICAgICAgICAgdmFyIGNsb25lID0gQ2xvbmUoYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZSk7DQogICAgICAgICAgICB2YXIgdiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W25hbWU9ZDIwXTpjaGVja2VkJykudmFsdWU7DQogICAgICAgICAgICBjbG9uZVsiUGluZ1Jlc3BvbnNlRW5hYmxlZCJdID0gKCh2ICYgMSkgIT0gMCk7DQogICAgICAgICAgICBjbG9uZVsiUm1jcFBpbmdSZXNwb25zZUVuYWJsZWQiXSA9ICgodiAmIDIpICE9IDApOw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCJBTVRfR2VuZXJhbFNldHRpbmdzIiwgY2xvbmUsIFB1bGxTeXN0ZW1TdGF0dXMsIDAsIDEpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0lQU2V0dXBEbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9IGFtdHN5c3N0YXRlWydBTVRfRXRoZXJuZXRQb3J0U2V0dGluZ3MnXS5yZXNwb25zZXNbMF07DQogICAgICAgICAgICBRVignaWRfZDIxbWFudWFsZGl2JywgdHJ1ZSk7DQogICAgICAgICAgICBRVignaWRfZDIxc3VibmV0ZGl2JywgdHJ1ZSk7DQogICAgICAgICAgICBRVignZDIxbzAnLCBmYWxzZSk7DQogICAgICAgICAgICBRVignZDIxbDAnLCBmYWxzZSk7DQogICAgICAgICAgICBRSCgnZDIxbDEnLCAnQXV0b21hdGljIGNvbmZpZ3VyYXRpb24gdXNpbmcgREhDUCBzZXJ2ZXInKTsNCiAgICAgICAgICAgIFFIKCdkMjFsMicsICdTdGF0aWMgY29uZmlndXJhdGlvbiB1c2luZyBJUHY0IHNldHRpbmdzIGJlbG93Jyk7DQogICAgICAgICAgICBkMjFvMS5jaGVja2VkID0gKHhbJ0RIQ1BFbmFibGVkJ10gPT0gdHJ1ZSk7DQogICAgICAgICAgICBkMjFvMi5jaGVja2VkID0gIWQyMW8xLmNoZWNrZWQ7DQogICAgICAgICAgICBpZHhfZDIxYWRkcmVzcy52YWx1ZSA9IGlzSXBBZGRyZXNzKHhbIklQQWRkcmVzcyJdLCcnKTsNCiAgICAgICAgICAgIGlkeF9kMjFzdWJuZXQudmFsdWUgPSBpc0lwQWRkcmVzcyh4WyJTdWJuZXRNYXNrIl0sJycpOw0KICAgICAgICAgICAgaWR4X2QyMWdhdGV3YXkudmFsdWUgPSBpc0lwQWRkcmVzcyh4WyJEZWZhdWx0R2F0ZXdheSJdLCcnKTsNCiAgICAgICAgICAgIGlkeF9kMjFkbnMxLnZhbHVlID0gaXNJcEFkZHJlc3MoeFsiUHJpbWFyeUROUyJdLCcnKTsNCiAgICAgICAgICAgIGlkeF9kMjFkbnMyLnZhbHVlID0gaXNJcEFkZHJlc3MoeFsiU2Vjb25kYXJ5RE5TIl0sJycpOw0KICAgICAgICAgICAgdXBkYXRlSVBTZXR1cERsZygpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgyMSwgJ0lQdjQgU2V0dGluZ3MnLCAzLCBzaG93SVBTZXR1cERsZ09rKQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlSVBTZXR1cERsZygpIHsNCiAgICAgICAgICAgIGlkeF9kMjFhZGRyZXNzLmRpc2FibGVkID0gaWR4X2QyMXN1Ym5ldC5kaXNhYmxlZCA9IGlkeF9kMjFnYXRld2F5LmRpc2FibGVkID0gaWR4X2QyMWRuczEuZGlzYWJsZWQgPSBpZHhfZDIxZG5zMi5kaXNhYmxlZCA9ICFkMjFvMi5jaGVja2VkOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0lQU2V0dXBEbGdPaygpIHsNCiAgICAgICAgICAgIHZhciB4ID0gQ2xvbmUoYW10c3lzc3RhdGVbJ0FNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyddLnJlc3BvbnNlc1swXSk7DQogICAgICAgICAgICB4WydESENQRW5hYmxlZCddID0gZDIxbzEuY2hlY2tlZDsNCiAgICAgICAgICAgIGRlbGV0ZSB4WyJJUEFkZHJlc3MiXTsNCiAgICAgICAgICAgIGRlbGV0ZSB4WyJTdWJuZXRNYXNrIl07DQogICAgICAgICAgICBkZWxldGUgeFsiRGVmYXVsdEdhdGV3YXkiXTsNCiAgICAgICAgICAgIGRlbGV0ZSB4WyJQcmltYXJ5RE5TIl07DQogICAgICAgICAgICBkZWxldGUgeFsiU2Vjb25kYXJ5RE5TIl07DQogICAgICAgICAgICBpZiAoZDIxbzEuY2hlY2tlZCA9PSBmYWxzZSkgew0KICAgICAgICAgICAgICAgIHhbIklQQWRkcmVzcyJdID0gaWR4X2QyMWFkZHJlc3MudmFsdWU7DQogICAgICAgICAgICAgICAgeFsiU3VibmV0TWFzayJdID0gaWR4X2QyMXN1Ym5ldC52YWx1ZTsNCiAgICAgICAgICAgICAgICB4WyJEZWZhdWx0R2F0ZXdheSJdID0gaWR4X2QyMWdhdGV3YXkudmFsdWU7DQogICAgICAgICAgICAgICAgaWYgKGlkeF9kMjFkbnMxLnZhbHVlICE9ICcnKSB4WyJQcmltYXJ5RE5TIl0gPSBpZHhfZDIxZG5zMS52YWx1ZTsNCiAgICAgICAgICAgICAgICBpZiAoaWR4X2QyMWRuczIudmFsdWUgIT0gJycpIHhbIlNlY29uZGFyeUROUyJdID0gaWR4X2QyMWRuczIudmFsdWU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBhbXRzdGFjay5QdXQoIkFNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyIsIHgsIHNob3dJUFNldHVwRGxnRG9uZSwgMCwgMSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93SVBTZXR1cERsZ0RvbmUoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSB7DQogICAgICAgICAgICAgICAgYW10c3lzc3RhdGUgPSB1bmRlZmluZWQ7DQogICAgICAgICAgICAgICAgUHVsbFN5c3RlbVN0YXR1cygpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdJUHY0IFNldHRpbmdzJywgJ1VuYWJsZSB0byBzZXQgbmV0d29yayBwYXJhbWV0ZXJzLCBlcnJvciAnICsgc3RhdHVzKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQoNCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gU3RvcmFnZQ0KICAgICAgICAvLw0KDQogICAgICAgIHZhciB4eFN0b3JhZ2UgPSBudWxsOw0KICAgICAgICB2YXIgeHhTdG9yYWdlVmVuZG9ycyA9IFtdOw0KICAgICAgICB2YXIgeHhTdG9yYWdlQXBwbGljYXRpb25zID0gW107DQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFN0b3JhZ2UoKSB7DQogICAgICAgICAgICBhbXRGaXJzdFB1bGwgfD0gODsNCiAgICAgICAgICAgIHdzc3RhY2suY29tbS5QZXJmb3JtQWpheCgiIiwgUHVsbFN0b3JhZ2VSZXNwb25zZSwgbnVsbCwgMCwgIi9hbXQtc3RvcmFnZS8iLCAiR0VUIik7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBQdWxsU3RvcmFnZVJlc3BvbnNlKGRhdGEsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICBpZiAoYW10c3RhY2suUGVuZGluZ0JhdGNoT3BlcmF0aW9ucyA9PSAwKSByZWZyZXNoQnV0dG9ucyh0cnVlKTsgLy8gSWYgbm90aGluZyBpcyBiZWluZyBkb25lLCByZS1lbmFibGUgcmVmcmVzaCBidXR0b25zDQogICAgICAgICAgICANCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSB7DQogICAgICAgICAgICAgICAgUVYoJ2dvMjEnLCB0cnVlKTsgLy8gU2hvdyBTdG9yYWdlIFBhbmVsDQoNCiAgICAgICAgICAgICAgICB2YXIgbGVuOyAvLyBSZW1vdmUgYWxsIGNoYXJzIHRoYXQgYXJlIGJlbG93IDMyLCB0aGlzIHdpbGwgYWxsb3cgcGFyc2luZyBldmVuIHRoZSB0aGUgZmlybXdhcmUgZ2l2ZXMgdXMgZ2FyYmFnZS4NCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpKyspIHsgZG8geyBsZW4gPSBkYXRhLmxlbmd0aDsgZGF0YSA9IGRhdGEucmVwbGFjZShTdHJpbmcuZnJvbUNoYXJDb2RlKGkpLCAnJyk7IH0gd2hpbGUgKGxlbiA+IGRhdGEubGVuZ3RoKTsgfQ0KICAgICAgICAgICAgICAgIC8vZGF0YSA9ICd7ImluZm9ybWF0aW9uIjogeyJ2ZXJzaW9uIjogMS4xLCJyZWFsbXMiOiA3NzY1NzU5LCJ1c2VyIjogImFkbWluIn0sImNvbnRlbnQiOiBbeyJuYW1lIjogImluZGV4Lmh0bSIsInNpemUiOiAzODg2NH0seyJ2ZW5kb3IiOiAiVXNlciIsImFwcCI6ICJTREsiLCJuYW1lIjogIlNhbXBsZS5odG1sIiwic2l6ZSI6IDI2NzYwLCJsaW5rIjogIlNESyBTYW1wbGUifSx7InZlbmRvciI6ICJVc2VyIiwiYXBwIjogIlNESyIsIm5hbWUiOiAid3MuanMiLCJzaXplIjogNDI1NzUsImxpbmsiOiAiU0RLIFNhbXBsZSJ9LHsidmVuZG9yIjogIlVzZXIiLCJhcHAiOiAiU0RLIiwibmFtZSI6ICJidHAubWluLmNzcyIsInNpemUiOiAxMjEyNjUsImxpbmsiOiAiU0RLIFNhbXBsZSJ9LHsidmVuZG9yIjogIlVzZXIiLCJhcHAiOiAiU0RLIiwibmFtZSI6ICJsb2dvLnBuZyIsInNpemUiOiAyODAzLCJsaW5rIjogIlNESyBTYW1wbGUifV19JzsNCiAgICAgICAgICAgICAgICB0cnkgeyB4eFN0b3JhZ2UgPSBKU09OLnBhcnNlKGRhdGEpOyB9IGNhdGNoIChlKSB7IHJldHVybjsgfQ0KICAgICAgICAgICAgICAgIHh4U3RvcmFnZVZlbmRvcnMgPSBbXTsNCiAgICAgICAgICAgICAgICB4eFN0b3JhZ2VBcHBsaWNhdGlvbnMgPSBbXTsNCiAgICAgICAgICAgICAgICB2YXIgY29udGVudCA9IHh4U3RvcmFnZVsnY29udGVudCddOw0KDQogICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29udGVudCkpIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gTmV3IGZsYXQgZm9ybWF0LCBjb252ZXJ0IHRvIHRyZWUgZm9ybWF0Lg0KICAgICAgICAgICAgICAgICAgICB2YXIgbmV3Y29udGVudCA9IHt9Ow0KICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIGNvbnRlbnQpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2ZW5kb3IgPSBjb250ZW50W2ldWyJ2ZW5kb3IiXSA/IGNvbnRlbnRbaV1bInZlbmRvciJdIDogJyc7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5ld2NvbnRlbnRbdmVuZG9yXSkgeyBuZXdjb250ZW50W3ZlbmRvcl0gPSB7fTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFwcCA9IGNvbnRlbnRbaV1bImFwcCJdID8gY29udGVudFtpXVsiYXBwIl0gOiAnJzsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbmV3Y29udGVudFt2ZW5kb3JdW2FwcF0pIHsgbmV3Y29udGVudFt2ZW5kb3JdW2FwcF0gPSB7fTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRbaV1bIm5hbWUiXSkgeyBuZXdjb250ZW50W3ZlbmRvcl1bYXBwXVtjb250ZW50W2ldWyJuYW1lIl1dID0gY29udGVudFtpXTsgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIHh4U3RvcmFnZVsnY29udGVudCddID0gY29udGVudCA9IG5ld2NvbnRlbnQ7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gVHJlZSBmb3JtYXQsIG1vdmUgaW5kZXguaHRtIGFuZCBsb2dvbi5odG0NCiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRbJ2luZGV4Lmh0bSddIHx8IGNvbnRlbnRbJ2xvZ29uLmh0bSddKSB7IGNvbnRlbnRbJyddID0geyAnJzoge30gfTsgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoY29udGVudFsnaW5kZXguaHRtJ10pIHsgY29udGVudFsnJ11bJyddWydpbmRleC5odG0nXSA9IGNvbnRlbnRbJ2luZGV4Lmh0bSddOyBkZWxldGUgY29udGVudFsnaW5kZXguaHRtJ107IH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRbJ2xvZ29uLmh0bSddKSB7IGNvbnRlbnRbJyddWycnXVsnbG9nb24uaHRtJ10gPSBjb250ZW50Wydsb2dvbi5odG0nXTsgZGVsZXRlIGNvbnRlbnRbJ2xvZ29uLmh0bSddOyB9DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgLy8gRGlzcGxheSBhbGwgc3RvcmFnZSBmaWxlcw0KICAgICAgICAgICAgICAgIHZhciBjb3VudCA9IDAsIHggPSBUYWJsZVN0YXJ0MigpICsgIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCBzdG9yYWdlIGZvciB0aGlzIGNvbXB1dGVyLjxicj48YnI+IjsNCiAgICAgICAgICAgICAgICB2YXIgaWksIGpqLCB4eCA9ICIiLCBsaW5rcyA9ICIiLCBsaW5raWQgPSAzMDsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIGNvbnRlbnQpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGpjb3VudCA9IDA7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gY29udGVudFtpXSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgamNvdW50Kys7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIga2NvdW50ID0gMDsNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGsgaW4gY29udGVudFtpXVtqXSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtjb3VudCsrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpICE9IGlpIHx8IGogIT0gamopIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHh4ICE9ICIiKSB7IHggKz0geHg7IHh4ID0gIjxicj4iOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlpID0gaTsgamogPSBqOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSAhPSAnJykgeyB4eCArPSBFc2NhcGVIdG1sKGkgKyAiIC8gIiArIGopOyB9IGVsc2UgeyB4eCArPSAiUm9vdCIgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3ZhciBoYW5kbGUgPSAiXCIiICsgaSArICJcIixcIiIgKyBqICsgIlwiLFwiIiArIGsgKyAiXCIiOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGUgPSAiXCIiICsgaSArICgoaSAhPSAnJykgPyAnLycgOiAnJykgKyBqICsgKChqICE9ICcnKSA/ICcvJyA6ICcnKSArIGsgKyAiXCIiOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHh4ICs9ICc8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93U3RvcmFnZURldGFpbHMoIicgKyBpICsgJyIsIicgKyBqICsgJyIsIicgKyBrICsgJyIsJyArIGhhbmRsZSArICcpPjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ+JzsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHh4ICs9ICIgIiArIEFkZEJ1dHRvbjIoIk9wZW4iLCAiT3BlbkZyb21TdG9yYWdlKCIgKyBoYW5kbGUgKyAiLGV2ZW50KSIpOw0KDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeHggKz0gIiAiICsgQWRkQnV0dG9uMigiRG93bmxvYWQiLCAiRG93bmxvYWRGcm9tU3RvcmFnZSgiICsgaGFuZGxlICsgIixcIiIgKyBrICsgIlwiLGV2ZW50KSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHh4ICs9ICI8L2Rpdj48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48Yj4iICsgRXNjYXBlSHRtbChrKSArICI8L2I+LCA8aT4iICsgY29udGVudFtpXVtqXVtrXVsnc2l6ZSddICsgIiBieXRlczwvaT48L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50Kys7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHh4U3RvcmFnZVZlbmRvcnMuaW5kZXhPZihpKSA9PSAtMSkgeHhTdG9yYWdlVmVuZG9ycy5wdXNoKGkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4eFN0b3JhZ2VBcHBsaWNhdGlvbnMuaW5kZXhPZihqKSA9PSAtMSkgeHhTdG9yYWdlQXBwbGljYXRpb25zLnB1c2goaik7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2NvdW50ID09IDApIHsgIC8vIENsZWFyIGVtcHR5IGFwcGxpY2F0aW9uICYgdmVuZG9yDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBmdW5jdGlvbiAoKSB7IH0sIG51bGwsIDAsICIvYW10LXN0b3JhZ2UvIiArIGkgKyAiLyIgKyBqLCAiREVMRVRFIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBmdW5jdGlvbiAoKSB7IH0sIG51bGwsIDAsICIvYW10LXN0b3JhZ2UvIiArIGksICJERUxFVEUiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoamNvdW50ID09IDApIHsgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBmdW5jdGlvbiAoKSB7IH0sIG51bGwsIDAsICIvYW10LXN0b3JhZ2UvIiArIGksICJERUxFVEUiKTsgfSAvLyBDbGVhciBlbXB0eSB2ZW5kb3INCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKHh4ICE9ICIiKSB4ICs9IHh4Ow0KICAgICAgICAgICAgICAgIGlmIChjb3VudCA9PSAwKSB7IHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPjxpPk5vIGZpbGVzIGZvdW5kLjwvaT48L2Rpdj48YnI+IjsgfQ0KICAgICAgICAgICAgICAgIHggKz0gIjxicj48dGQgY2xhc3M9cjE+IiArIFRhYmxlRW5kKEFkZFJlZnJlc2hCdXR0b24oIlB1bGxTdG9yYWdlKCkiKSArIEFkZEJ1dHRvbigiVXBsb2FkLi4uIiwgIlVwbG9hZFRvU3RvcmFnZSgpIikNCiAgICAgICAgICAgICAgICApOw0KICAgICAgICAgICAgICAgIFFIKCdpZF9UYWJsZVN5c3RlbVN0b3JhZ2UnLCB4KTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgUUgoJ2lkX1RhYmxlU3lzdGVtU3RvcmFnZScsICdVbmFibGUgdG8gbG9hZCBzdG9yYWdlIGRhdGEuLi48YnIvPicgKyBBZGRCdXR0b24oIlJlZnJlc2giLCAiUHVsbFN0b3JhZ2UoKSIpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dTdG9yYWdlRGV0YWlscyhpLCBqLCBrLCBoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9ICcnLCBpdGVtID0geHhTdG9yYWdlWydjb250ZW50J11baV1bal1ba107DQogICAgICAgICAgICBpZiAoaSAhPSAnJykgeCArPSBhZGRIdG1sVmFsdWUoIlZlbmRvciIsIGkpOw0KICAgICAgICAgICAgaWYgKGogIT0gJycpIHggKz0gYWRkSHRtbFZhbHVlKCJBcHBsaWNhdGlvbiIsIGopOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIk5hbWUiLCBrKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJTaXplIiwgaXRlbVsnc2l6ZSddICsgJyBieXRlcycpOw0KICAgICAgICAgICAgaWYgKGl0ZW1bJ2xpbmsnXSkgeyB4ICs9IGFkZEh0bWxWYWx1ZSgiTGluayIsIGl0ZW1bJ2xpbmsnXSk7IH0NCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdTdG9yYWdlIEl0ZW0nLCA1LCBzaG93U3RvcmFnZURldGFpbHNFeCwgeCwgaCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93U3RvcmFnZURldGFpbHNFeChidXR0b25zLCBoYW5kbGUpIHsNCiAgICAgICAgICAgIGlmIChidXR0b25zID09IDIpIHsgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBzdG9yYWdlRGVsZXRlUmVzcG9uc2UsIG51bGwsIDAsICcvYW10LXN0b3JhZ2UvJyArIGhhbmRsZSwgIkRFTEVURSIpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzdG9yYWdlRGVsZXRlUmVzcG9uc2UoZGF0YSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goIlN0b3JhZ2UiLCAiVW5hYmxlIHRvIGRlbGV0ZSBmaWxlIChFUlIiICsgc3RhdHVzICsgIiksIGNoZWNrIHRoYXQgdGhlIGNvbXB1dGVyIGlzIHBvd2VyZWQgb24uIik7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFB1bGxTdG9yYWdlKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KDQogICAgICAgIGZ1bmN0aW9uIERvd25sb2FkRnJvbVN0b3JhZ2UoaGFuZGxlLCBmaWxlbmFtZSwgZSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgaGFsdEV2ZW50KGUpOw0KICAgICAgICAgICAgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBEb3dubG9hZEZyb21TdG9yYWdlRXgsIGZpbGVuYW1lLCAwLCAnL2FtdC1zdG9yYWdlLycgKyBoYW5kbGUsICJHRVQiKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIERvd25sb2FkRnJvbVN0b3JhZ2VFeChkYXRhLCBzdGF0dXMsIHRhZykgew0KICAgICAgICAgICAgaWYgKChzdGF0dXMgIT0gMjAwKSB8fCAoZGF0YSA9PSBudWxsKSkgeyBjb25zb2xlLmxvZyhzdGF0dXMsICdEYXRhID0gbnVsbCcpOyByZXR1cm47IH0NCiAgICAgICAgICAgIHNhdmVBcyhkYXRhMmJsb2IoZGF0YSksIHRhZyk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBPcGVuRnJvbVN0b3JhZ2UoaGFuZGxlLCBlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQoNCiAgICAgICAgICAgIHZhciBuZXdXaW5kb3cgPSB3aW5kb3cub3BlbignaHR0cDovLycgKyB3c3N0YWNrLmNvbW0uaG9zdCArICc6JyArIHdzc3RhY2suY29tbS5wb3J0ICsgJy9hbXQtc3RvcmFnZS8nICsgaGFuZGxlLCAnX2JsYW5rJyk7DQogICAgICAgICAgICBuZXdXaW5kb3cub3BlbmVyID0gbnVsbDsNCiAgICAgICAgICAgIG5ld1dpbmRvdy5mb2N1cygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gUHVzaFRvU3RvcmFnZSh2ZW5kb3JBcHBuYW1lRmlsZW5hbWUsIGRhdGEsIGFwcGVuZCkgew0KICAgICAgICAgICAgdmFyIHRhZyA9IG51bGw7DQogICAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggPiA3MDAwKSB7IHRhZyA9IFt2ZW5kb3JBcHBuYW1lRmlsZW5hbWUsIGRhdGEuc3Vic3RyaW5nKDcwMDApXTsgZGF0YSA9IGRhdGEuc3Vic3RyaW5nKDAsIDcwMDApOyB9DQogICAgICAgICAgICB3c3N0YWNrLmNvbW0uUGVyZm9ybUFqYXgoZGF0YSwgUHVzaFRvU3RvcmFnZVJlc3BvbnNlLCB0YWcsIDAsICIvYW10LXN0b3JhZ2UvIiArIHZlbmRvckFwcG5hbWVGaWxlbmFtZSArIChhcHBlbmQgPT0gdHJ1ZSA/ICI/YXBwZW5kPSIgOiAiIiksICJQVVQiKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIFB1c2hUb1N0b3JhZ2VSZXNwb25zZShkYXRhLCBzdGF0dXMsIHRhZykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsgbWVzc2FnZWJveCgiU3RvcmFnZSIsICJVbmFibGUgdG8gcHVzaCBmaWxlIChFUlIiICsgc3RhdHVzICsgIiksIGNoZWNrIHRoYXQgdGhlIGNvbXB1dGVyIGlzIHBvd2VyZWQgb24uIik7IH0gZWxzZSB7DQogICAgICAgICAgICAgICAgaWYgKHRhZyAhPSBudWxsKSB7IFB1c2hUb1N0b3JhZ2UodGFnWzBdLCB0YWdbMV0sIHRydWUpOyB9IGVsc2UgeyBQdWxsU3RvcmFnZSgpOyB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBVcGxvYWRUb1N0b3JhZ2UoZmlsZSwgZmlsZW5hbWUpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIGlmICghZmlsZW5hbWUpIHsgZmlsZW5hbWUgPSAnJzsgfQ0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gJzxicj5TZWxlY3QgYSBzbWFsbCBmaWxlIHRvIHVwbG9hZCB0byBzdG9yYWdlIGFuZCBlbnRlciBhIHZlbmRvciwgYXBwbGljYXRpb24gYW5kIGZpbGVuYW1lLjxicj4nOw0KICAgICAgICAgICAgaWYgKCFmaWxlKSB7DQogICAgICAgICAgICAgICAgeCArPSAnPGJyPjxkaXYgc3R5bGU9aGVpZ2h0OjIwcHg+PGlucHV0IHR5cGU9ZmlsZSBpZD1tc3RvcmFnZWZpbGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjQwcHggb25jaGFuZ2U9U2V0U3RvcmFnZU5hbWUoKT48ZGl2PlVwbG9hZCBmaWxlPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgeCArPSAnPGJyPjxkaXYgc3R5bGU9aGVpZ2h0OjIwcHg+PGlucHV0IGlkPW1zdG9yYWdlZmlsZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweCByZWFkb25seSBkaXNhYmxlZD1kaXNhYmxlZCB2YWx1ZT0iJyArIGZpbGVuYW1lICsgJyIgPjxkaXY+VXBsb2FkIGZpbGU8L2Rpdj48L2Rpdj4nOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSAnPGJyPjxkaXYgc3R5bGU9aGVpZ2h0OjE2cHg+PGlucHV0IGlkPW1zdG9yYWdldmVuZG9yIHBsYWNlaG9sZGVyPVZlbmRvciBsaXN0PW1zdG9yYWdldmVuZG9ybGlzdCBtYXhsZW5ndGg9MTEgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjQwcHg+PGRpdj5WZW5kb3IgbmFtZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8YnI+PGRpdiBzdHlsZT1oZWlnaHQ6MTZweD48aW5wdXQgaWQ9bXN0b3JhZ2VhcHBsaWNhdGlvbiBwbGFjZWhvbGRlcj1BcHAgbGlzdD1tc3RvcmFnZWFwcGxpY2F0aW9ubGlzdCBtYXhsZW5ndGg9MTEgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjQwcHg+PGRpdj5BcHBsaWNhdGlvbiBuYW1lPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxicj48ZGl2IHN0eWxlPWhlaWdodDoxNnB4PjxpbnB1dCBpZD1tc3RvcmFnZWZpbGVuYW1lIHBsYWNlaG9sZGVyPUZpbGVuYW1lIG1heGxlbmd0aD0xMSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweD48ZGl2PkZpbGVuYW1lPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxicj48ZGl2IHN0eWxlPWhlaWdodDoxNnB4PjxpbnB1dCBpZD1tc3RvcmFnZXR5cGUgcGxhY2Vob2xkZXI9YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIGxpc3Q9bXN0b3JhZ2V0eXBlbGlzdCBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweD48ZGl2Pk1JTUUgVHlwZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8YnI+PGRpdiBzdHlsZT1oZWlnaHQ6MTZweD48aW5wdXQgaWQ9bXN0b3JhZ2VsaW5rIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI0MHB4PjxkaXYgdGl0bGU9IklmIHNldCwgY3JlYXRlcyBhIGxpbmsgdG8gdGhpcyBjb250ZW50IGZyb20gdGhlIG1haW4gd2ViIHBhZ2UiPkxpbms8L2Rpdj48L2Rpdj48YnI+JzsNCiAgICAgICAgICAgIHggKz0gJzxkYXRhbGlzdCBpZD1tc3RvcmFnZXZlbmRvcmxpc3Q+JzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhTdG9yYWdlVmVuZG9ycykgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPSInICsgeHhTdG9yYWdlVmVuZG9yc1tpXSArICciPic7IH0NCiAgICAgICAgICAgIHggKz0gJzwvZGF0YWxpc3Q+JzsNCiAgICAgICAgICAgIHggKz0gJzxkYXRhbGlzdCBpZD1tc3RvcmFnZWFwcGxpY2F0aW9ubGlzdD4nOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFN0b3JhZ2VBcHBsaWNhdGlvbnMpIHsgeCArPSAnPG9wdGlvbiB2YWx1ZT0iJyArIHh4U3RvcmFnZUFwcGxpY2F0aW9uc1tpXSArICciPic7IH0NCiAgICAgICAgICAgIHggKz0gJzwvZGF0YWxpc3Q+PGRhdGFsaXN0IGlkPW1zdG9yYWdldHlwZWxpc3Q+PG9wdGlvbiB2YWx1ZT0iYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIj48b3B0aW9uIHZhbHVlPSJpbWFnZS9qcGVnIj48b3B0aW9uIHZhbHVlPSJ0ZXh0L2h0bWwiPjxvcHRpb24gdmFsdWU9InRleHQvcGxhaW4iPjwvZGF0YWxpc3Q+JzsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdTdG9yYWdlIFVwbG9hZCcsIDMsIFVwbG9hZFRvU3RvcmFnZUV4LCB4LCBmaWxlKTsNCiAgICAgICAgICAgIGlmIChmaWxlKSB7IFNldFN0b3JhZ2VOYW1lKGZpbGVuYW1lKTsgfQ0KICAgICAgICB9DQoNCg0KICAgICAgICBmdW5jdGlvbiBVcGxvYWRUb1N0b3JhZ2VFeChidXR0b24sIHRhZykgew0KICAgICAgICAgICAgaWYgKCF0YWcpIHsNCiAgICAgICAgICAgICAgICB2YXIgeCA9IFEoJ21zdG9yYWdlZmlsZScpOw0KICAgICAgICAgICAgICAgIGlmICh4LmZpbGVzLmxlbmd0aCAhPSAxKSByZXR1cm47DQogICAgICAgICAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQogICAgICAgICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IFVwbG9hZFRvU3RvcmFnZUV4MjsNCiAgICAgICAgICAgICAgICByZWFkZXIuZmlsZW5hbWUgPSB4LmZpbGVzWzBdLm5hbWU7DQogICAgICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyh4LmZpbGVzWzBdKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQogICAgICAgICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IFVwbG9hZFRvU3RvcmFnZUV4MjsNCiAgICAgICAgICAgICAgICByZWFkZXIuZmlsZW5hbWUgPSBRKCdtc3RvcmFnZWZpbGUnKS52YWx1ZTsNCiAgICAgICAgICAgICAgICByZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKHRhZyk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBTZXRTdG9yYWdlTmFtZShmaWxlbmFtZSkgew0KICAgICAgICAgICAgaWYgKCFmaWxlbmFtZSkgew0KICAgICAgICAgICAgICAgIHZhciB4ID0gUSgnbXN0b3JhZ2VmaWxlJyk7DQogICAgICAgICAgICAgICAgaWYgKHguZmlsZXMubGVuZ3RoID09IDEpIHsgZmlsZW5hbWUgPSB4LmZpbGVzWzBdLm5hbWU7IH0gZWxzZSB7IGZpbGVuYW1lID0gJyc7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGZpbGVuYW1lID0gZmlsZW5hbWUuc3BsaXQoJyAnKS5qb2luKCcnKTsNCiAgICAgICAgICAgIHZhciBmaWxlbmFtZVNwbGl0ID0gZmlsZW5hbWUuc3BsaXQoJy0nKTsNCiAgICAgICAgICAgIGlmIChmaWxlbmFtZVNwbGl0Lmxlbmd0aCA9PSAzICYmIGZpbGVuYW1lU3BsaXRbMF0ubGVuZ3RoIDwgMTIgJiYgZmlsZW5hbWVTcGxpdFsxXS5sZW5ndGggPCAxMikgew0KICAgICAgICAgICAgICAgIFEoJ21zdG9yYWdldmVuZG9yJykudmFsdWUgPSBmaWxlbmFtZVNwbGl0WzBdOw0KICAgICAgICAgICAgICAgIFEoJ21zdG9yYWdlYXBwbGljYXRpb24nKS52YWx1ZSA9IGZpbGVuYW1lU3BsaXRbMV07DQogICAgICAgICAgICAgICAgZmlsZW5hbWUgPSBmaWxlbmFtZVNwbGl0WzJdOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZmlsZW5hbWUgPSBmaWxlbmFtZS5zcGxpdCgnLScpLmpvaW4oJycpOw0KICAgICAgICAgICAgaWYgKGZpbGVuYW1lLmVuZHNXaXRoKCcuZ3onKSkgZmlsZW5hbWUgPSBmaWxlbmFtZS5zdWJzdHJpbmcoMCwgZmlsZW5hbWUubGVuZ3RoIC0gMyk7DQogICAgICAgICAgICBpZiAoZmlsZW5hbWUuZW5kc1dpdGgoJy5odG0nKSB8fCBmaWxlbmFtZS5lbmRzV2l0aCgnLmh0bWwnKSkgUSgnbXN0b3JhZ2V0eXBlJykudmFsdWUgPSAidGV4dC9odG1sIjsNCiAgICAgICAgICAgIGVsc2UgaWYgKGZpbGVuYW1lLmVuZHNXaXRoKCcudHh0JykpIFEoJ21zdG9yYWdldHlwZScpLnZhbHVlID0gInRleHQvcGxhaW4iOw0KICAgICAgICAgICAgaWYgKGZpbGVuYW1lLmxlbmd0aCA+IDExKSBmaWxlbmFtZSA9IGZpbGVuYW1lLnN1YnN0cmluZygwLCAxMSk7DQogICAgICAgICAgICBRKCdtc3RvcmFnZWZpbGVuYW1lJykudmFsdWUgPSBmaWxlbmFtZTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIFVwbG9hZFRvU3RvcmFnZUV4MihmaWxlKSB7DQogICAgICAgICAgICB2YXIgdmFmLCB2ZW5kb3IgPSBRKCdtc3RvcmFnZXZlbmRvcicpLnZhbHVlOw0KICAgICAgICAgICAgdmFyIGFwcCA9IFEoJ21zdG9yYWdlYXBwbGljYXRpb24nKS52YWx1ZTsNCiAgICAgICAgICAgIHZhciBmaWxlbmFtZSA9IFEoJ21zdG9yYWdlZmlsZW5hbWUnKS52YWx1ZTsNCiAgICAgICAgICAgIGlmIChmaWxlbmFtZSA9PSAnJykgZmlsZW5hbWUgPSAnRmlsZW5hbWUnOw0KICAgICAgICAgICAgdmFyIG1pbWV0eXBlID0gUSgnbXN0b3JhZ2V0eXBlJykudmFsdWU7DQogICAgICAgICAgICBpZiAobWltZXR5cGUgPT0gJycpIG1pbWV0eXBlID0gJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSc7DQogICAgICAgICAgICB2YXIgbGluayA9IFEoJ21zdG9yYWdlbGluaycpLnZhbHVlOw0KICAgICAgICAgICAgaWYgKHZlbmRvciA9PSAnJyAmJiBhcHAgPT0gJycgJiYgKGZpbGVuYW1lLnRvTG93ZXJDYXNlKCkgPT0gJ2xvZ29uLmh0bScgfHwgZmlsZW5hbWUudG9Mb3dlckNhc2UoKSA9PSAnaW5kZXguaHRtJykpIHsNCiAgICAgICAgICAgICAgICB2YWYgPSBmaWxlbmFtZS50b0xvd2VyQ2FzZSgpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBpZiAodmVuZG9yID09ICcnKSB2ZW5kb3IgPSAnVmVuZG9yJzsNCiAgICAgICAgICAgICAgICBpZiAoYXBwID09ICcnKSBhcHAgPSAnQXBwJzsNCiAgICAgICAgICAgICAgICB2YWYgPSB2ZW5kb3IgKyAiLyIgKyBhcHAgKyAiLyIgKyBmaWxlbmFtZTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgdmFyIGRhdGEgPSAiPG1ldGFkYXRhPjxoZWFkZXJzPiI7DQogICAgICAgICAgICB2YXIgZmlsZW5hbWUgPSBmaWxlLnRhcmdldC5maWxlbmFtZTsNCiAgICAgICAgICAgIGlmICghZmlsZW5hbWUpIHsgZmlsZW5hbWUgPSBRKCdtc3RvcmFnZWZpbGUnKS5maWxlc1swXS5uYW1lOyB9DQogICAgICAgICAgICBpZiAoZmlsZW5hbWUuZW5kc1dpdGgoJy5neicpKSB7IGRhdGEgKz0gIjxoPkNvbnRlbnQtRW5jb2Rpbmc6IGd6aXA8L2g+IjsgfQ0KICAgICAgICAgICAgZGF0YSArPSAiPGg+Q29udGVudC1UeXBlOiAiICsgbWltZXR5cGUgKyAiPC9oPjwvaGVhZGVycz4iOyAvLyA8aD5YLVVBLUNvbXBhdGlibGU6IElFPUVkZ2U8L2g+DQogICAgICAgICAgICBpZiAobGluayAhPSAnJykgZGF0YSArPSAiPGxpbms+IiArIGxpbmsgKyAiPC9saW5rPiI7DQogICAgICAgICAgICBkYXRhICs9ICI8L21ldGFkYXRhPiIgKyBmaWxlLnRhcmdldC5yZXN1bHQ7DQoNCiAgICAgICAgICAgIFB1c2hUb1N0b3JhZ2UodmFmLCBkYXRhKTsNCiAgICAgICAgfQ0KDQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEFsYXJtIFBhbmVsDQogICAgICAgIC8vDQoNCiAgICAgICAgZnVuY3Rpb24gX2ZtdGRhdGV0aW1lKHN0cikgew0KICAgICAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKCJUIiwiICIpLnJlcGxhY2UoIloiLCIiKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIF9mbXRpbnRlcnZhbChzdHIpIHsNCiAgICAgICAgICAgIHZhciBjbCA9IHN0ci5yZXBsYWNlKCJUIiwgIiIpLnN1YnN0cmluZyhzdHIuaW5kZXhPZignUCcpICsgMSk7DQogICAgICAgICAgICBjbCA9ICcgJyArIGNsLnJlcGxhY2UoIkQiLCAiIGRheXMgIikucmVwbGFjZSgiSCIsICIgaG91cnMgIikucmVwbGFjZSgiTSIsIiBtaW51dGVzICIpOw0KICAgICAgICAgICAgY2wgPSBjbC5yZXBsYWNlKCIgMSBkYXlzICIsICIgMSBkYXkgIikucmVwbGFjZSgiIDEgaG91cnMgIiwgIiAxIGhvdXIgIikucmVwbGFjZSgiIDEgbWludXRlcyAiLCIgMSBtaW51dGUgIik7DQogICAgICAgICAgICByZXR1cm4gY2wuc3Vic3RyaW5nKDAsIGNsLmxlbmd0aCAtIDEpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gX2ZtdHRpbWVwYWQoc3RyKSB7DQogICAgICAgICAgICBzdHIgPSAnJyArIHN0cjsNCiAgICAgICAgICAgIHdoaWxlIChzdHIubGVuZ3RoIDwgMikgeyBzdHIgPSAnMCcgKyBzdHI7IH0NCiAgICAgICAgICAgIHJldHVybiBzdHI7DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgeHhBbGFybXMgPSBudWxsOw0KDQogICAgICAgIGZ1bmN0aW9uIFB1bGxBbGFybXMoKSB7DQogICAgICAgICAgICB2YXIgeCA9IFRhYmxlU3RhcnQyKCkgKyAiPHRyPjx0ZCBjbGFzcz1yMSBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD48YnI+TWFuYWdlIHdha2UgYWxhcm1zLjxicj48YnI+Ig0KICAgICAgICAgICAgYW10c3RhY2suRW51bSgiSVBTX0FsYXJtQ2xvY2tPY2N1cnJlbmNlIiwgZnVuY3Rpb24oc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgew0KICAgICAgICAgICAgICAgICAgICBRVigiZ28yMyIsIHRydWUpOw0KICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UubGVuZ3RoID4gMCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgeHhBbGFybXMgPSByZXNwb25zZTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzcG9uc2UubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2FrZXRpbWUgPSBuZXcgRGF0ZShyZXNwb25zZVtpXVsiU3RhcnRUaW1lIl1bIkRhdGV0aW1lIl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZXRhaWxzID0gJzxiPicgKyByZXNwb25zZVtpXVsiRWxlbWVudE5hbWUiXSArICc8L2I+LCB3YWtlIG9uICcgKyB3YWtldGltZS50b0xvY2FsZVN0cmluZygpLnJlcGxhY2UoJywgJywgJyBhdCAnKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2VbaV1bIkludGVydmFsIl0gIT0gdW5kZWZpbmVkKSB7IGRldGFpbHMgKz0gJyBhbmQgZWFjaCcgKyBfZm10aW50ZXJ2YWwocmVzcG9uc2VbaV1bIkludGVydmFsIl1bIkludGVydmFsIl0pOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlW2ldWyJEZWxldGVPbkNvbXBsZXRpb24iXSA9PSB0cnVlKSB7IGRldGFpbHMgKz0gJywgZGVsZXRlIHdoZW4gZG9uZSc7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93QWxlcnREZXRhaWxzKCIgKyBpICsgIik+PGRpdiBzdHlsZT1mbG9hdDpyaWdodD4iOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHggKz0gIiAiICsgQWRkQnV0dG9uMigiRWRpdC4uLiIsICJzaG93QWRkQWxhcm0oIiArIGkgKyAiKSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gIjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4O3dpZHRoOmF1dG87ZmxvYXQ6bGVmdDtvdmVyZmxvdy14OmhpZGRlbj4iICsgZGV0YWlscyArICI8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgeHhBbGFybXMgPSBudWxsOw0KICAgICAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD48YnI+PGk+Tm8gd2FrZSBhbGFybXMgcmVnaXN0ZXJlZC48L2k+PC9kaXY+PGJyPiI7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgdmFyIHkgPSAiPGRpdj4mbmJzcDsiICsgQWRkUmVmcmVzaEJ1dHRvbigiUHVsbEFsYXJtcygpIik7DQogICAgICAgICAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHsgeSArPSBBZGRCdXR0b24oIlJlbW92ZSBhbGwgYWxhcm1zIiwgIlJlbW92ZUFsbEFsYXJtcygpIikgKyBBZGRCdXR0b24oIkFkZCIsICJzaG93QWRkQWxhcm0oKSIpOyB9DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjxicj48dGQgY2xhc3M9cjE+IiArIFRhYmxlRW5kKHkgKyAiPC9kaXY+Iik7DQogICAgICAgICAgICAgICAgICAgIFFIKCdpZF9UYWJsZUFsYXJtJywgeCk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwgbnVsbCwgdHJ1ZSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBwcmVwYXJlQWxhcm1PY2N1cmVuY2VUZW1wbGF0ZShpZCwgbm0sIHN0YXJ0LCBpbnRlcnZhbCwgZGVsKSB7DQogICAgICAgICAgICByZXR1cm4gIjxkOkFsYXJtVGVtcGxhdGUgeG1sbnM6ZD1cImh0dHA6Ly9pbnRlbC5jb20vd2JlbS93c2NpbS8xL2FtdC1zY2hlbWEvMS9BTVRfQWxhcm1DbG9ja1NlcnZpY2VcIiB4bWxuczpzPVwiaHR0cDovL2ludGVsLmNvbS93YmVtL3dzY2ltLzEvaXBzLXNjaGVtYS8xL0lQU19BbGFybUNsb2NrT2NjdXJyZW5jZVwiPjxzOkluc3RhbmNlSUQ+IiArIGlkICsgIjwvczpJbnN0YW5jZUlEPjxzOlN0YXJ0VGltZT48cDpEYXRldGltZSB4bWxuczpwPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NvbW1vblwiPiIgKyBzdGFydCArICI8L3A6RGF0ZXRpbWU+PC9zOlN0YXJ0VGltZT48czpJbnRlcnZhbD48cDpJbnRlcnZhbCB4bWxuczpwPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NvbW1vblwiPiIgKyBpbnRlcnZhbCArICI8L3A6SW50ZXJ2YWw+PC9zOkludGVydmFsPjxzOkRlbGV0ZU9uQ29tcGxldGlvbj4iICsgZGVsICsgIjwvczpEZWxldGVPbkNvbXBsZXRpb24+PC9kOkFsYXJtVGVtcGxhdGU+IjsNCiAgICAgICAgfQ0KICAgICAgICANCiAgICAgICAgZnVuY3Rpb24gUmVtb3ZlQWxsQWxhcm1zKCl7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDEsICJSZW1vdmUgYWxsIHdha2UgYWxhcm1zIiwgMywgUmVtb3ZlQWxsQWxhcm1zRXgsICJDb25maXJtIHJlbW92YWwgb2YgYWxsIHdha2UgYWxhcm1zPyIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gUmVtb3ZlQWxsQWxhcm1zRXgoKSB7DQogICAgICAgICAgICB2YXIgZGVsZXRlQ291bnQgPSB4eEFsYXJtcy5sZW5ndGg7DQogICAgICAgICAgICBmb3IgKHZhciBhIGluIHh4QWxhcm1zKSB7IGFtdHN0YWNrLkRlbGV0ZSgiSVBTX0FsYXJtQ2xvY2tPY2N1cnJlbmNlIiwgeHhBbGFybXNbYV0sIGZ1bmN0aW9uKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7IGlmICgtLWRlbGV0ZUNvdW50ID09IDApIHsgUHVsbEFsYXJtcygpOyB9fSk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dBZGRBbGFybShhbHJtKXsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIFFFKCdkMjVhbGFybV9uYW1lJywgIWFscm0pOw0KICAgICAgICAgICAgaWYgKGFscm0gIT0gdW5kZWZpbmVkKSB7DQogICAgICAgICAgICAgICAgdmFyIGFsYXJtID0geHhBbGFybXNbYWxybV0sIHdha2V0aW1lID0gbmV3IERhdGUoYWxhcm1bIlN0YXJ0VGltZSJdWyJEYXRldGltZSJdKTsNCiAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9uYW1lJykudmFsdWUgPSBhbGFybVsiRWxlbWVudE5hbWUiXTsNCiAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9zZGF0ZScpLnZhbHVlID0gd2FrZXRpbWUuZ2V0RnVsbFllYXIoKSArICctJyArIF9mbXR0aW1lcGFkKHdha2V0aW1lLmdldE1vbnRoKCkgKyAxKSArICctJyArIF9mbXR0aW1lcGFkKHdha2V0aW1lLmdldERhdGUoKSk7DQogICAgICAgICAgICAgICAgUSgnZDI1YWxhcm1fc3RpbWUnKS52YWx1ZSA9IHdha2V0aW1lLmdldEhvdXJzKCkgKyAnOicgKyBfZm10dGltZXBhZCh3YWtldGltZS5nZXRNaW51dGVzKCkpICsgJzonICsgX2ZtdHRpbWVwYWQod2FrZXRpbWUuZ2V0U2Vjb25kcygpKTsNCiAgICAgICAgICAgICAgICBpZiAoYWxhcm1bIkludGVydmFsIl0pIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGogPSBhbGFybVsiSW50ZXJ2YWwiXVsiSW50ZXJ2YWwiXS5yZXBsYWNlKCdQJywnJykucmVwbGFjZSgnVCcsJycpLnJlcGxhY2UoJ0QnLCdELCcpLnJlcGxhY2UoJ0gnLCdILCcpLnJlcGxhY2UoJ00nLCdNLCcpLnNwbGl0KCcsJyksIGsgPSBbMCwgMCwgMF07DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gaikgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGpsID0galtpXS5sZW5ndGggLSAxOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGpbaV1bamxdID09ICdEJykgeyBrWzBdID0gcGFyc2VJbnQoaltpXS5zdWJzdHJpbmcoMCwgamwpKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGpbaV1bamxdID09ICdIJykgeyBrWzFdID0gcGFyc2VJbnQoaltpXS5zdWJzdHJpbmcoMCwgamwpKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGpbaV1bamxdID09ICdNJykgeyBrWzJdID0gcGFyc2VJbnQoaltpXS5zdWJzdHJpbmcoMCwgamwpKTsgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIFEoJ2QyNWFsYXJtX2ludGVydmFsJykudmFsdWUgPSBrLmpvaW4oJy0nKTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9pbnRlcnZhbCcpLnZhbHVlID0gJyc7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIFEoJ2QyNWFsYXJtX2RvYycpLnZhbHVlID0gKGFsYXJtWyJEZWxldGVPbkNvbXBsZXRpb24iXSA9PSB0cnVlKT8xOjA7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHZhciBjdXJyZW50VGltZSA9IG5ldyBEYXRlKCk7DQogICAgICAgICAgICAgICAgY3VycmVudFRpbWUuc2V0RGF0ZShuZXcgRGF0ZSgpLmdldERhdGUoKSArIDEpOw0KICAgICAgICAgICAgICAgIFEoJ2QyNWFsYXJtX25hbWUnKS52YWx1ZSA9ICcnOw0KICAgICAgICAgICAgICAgIFEoJ2QyNWFsYXJtX3NkYXRlJykudmFsdWUgPSBjdXJyZW50VGltZS5nZXRGdWxsWWVhcigpICsgJy0nICsgX2ZtdHRpbWVwYWQoY3VycmVudFRpbWUuZ2V0TW9udGgoKSArIDEpICsgJy0nICsgX2ZtdHRpbWVwYWQoY3VycmVudFRpbWUuZ2V0RGF0ZSgpKTsNCiAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9zdGltZScpLnZhbHVlID0gY3VycmVudFRpbWUuZ2V0SG91cnMoKSArICc6JyArIF9mbXR0aW1lcGFkKGN1cnJlbnRUaW1lLmdldE1pbnV0ZXMoKSkgKyAnOjAwJzsNCiAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9pbnRlcnZhbCcpLnZhbHVlID0gJyc7DQogICAgICAgICAgICAgICAgUSgnZDI1YWxhcm1fZG9jJykudmFsdWUgPSAwOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgyNSwgIkFkZCBuZXcgYWxhcm0iLCAoYWxybSAhPSB1bmRlZmluZWQpPzc6Mywgc2hvd0FkZEFsYXJtT2ssICcnLCBhbHJtKTsNCiAgICAgICAgICAgIGFsZXJ0RGlhbG9nVXBkYXRlKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBhbGVydERpYWxvZ1VwZGF0ZSgpIHsNCiAgICAgICAgICAgIHZhciBpbCA9IFEoJ2QyNWFsYXJtX2ludGVydmFsJykudmFsdWUuc3BsaXQoJy0nKS5sZW5ndGg7DQogICAgICAgICAgICB2YXIgb2sgPSAoUSgnZDI1YWxhcm1fbmFtZScpLnZhbHVlLmxlbmd0aCA+IDApICYmIChRKCdkMjVhbGFybV9zZGF0ZScpLnZhbHVlLnNwbGl0KCctJykubGVuZ3RoID09IDMpICYmIChRKCdkMjVhbGFybV9zdGltZScpLnZhbHVlLnNwbGl0KCc6JykubGVuZ3RoID09IDMpICYmICgoaWwgPT0gMSkgfHwgKGlsID09IDMpKTsNCiAgICAgICAgICAgIFFFKCdpZHhfZGxnT2tCdXR0b24nLCBvayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93QWRkQWxhcm1PayhidXR0b24sIGFscm0pIHsNCiAgICAgICAgICAgIGlmIChidXR0b24gPT0gMikgeyBzaG93QWxlcnREZXRhaWxzRGVsZXRlKGJ1dHRvbiwgYWxybSk7IHJldHVybjsgfQ0KICAgICAgICAgICAgdmFyIGFsYXJtX25hbWUgPSBRKCdkMjVhbGFybV9uYW1lJykudmFsdWU7DQogICAgICAgICAgICB2YXIgeDEgPSBRKCdkMjVhbGFybV9zZGF0ZScpLnZhbHVlLnNwbGl0KCctJyk7DQogICAgICAgICAgICB2YXIgeDIgPSBRKCdkMjVhbGFybV9zdGltZScpLnZhbHVlLnNwbGl0KCc6Jyk7DQogICAgICAgICAgICB2YXIgdCA9IG5ldyBEYXRlKHgxWzBdLCB4MVsxXSAtIDEsIHgxWzJdLCB4MlswXSwgeDJbMV0sIHgyWzJdLCAwKTsgLy8gTm90IHN1cmUgd2h5LCBidXQgbW9udGggaXMgMCA9IEpBTiwgMTEgPSBERUMNCiAgICAgICAgICAgIHZhciBhbGFybV9zdGFydHRpbWUgPSBfZm10dGltZXBhZCh0LmdldFVUQ0Z1bGxZZWFyKCkpICsgJy0nICsgX2ZtdHRpbWVwYWQodC5nZXRVVENNb250aCgpICsgMSkgKyAnLScgKyBfZm10dGltZXBhZCh0LmdldFVUQ0RhdGUoKSkgKyAnVCcgKyBfZm10dGltZXBhZCh0LmdldFVUQ0hvdXJzKCkpICsgJzonICsgX2ZtdHRpbWVwYWQodC5nZXRVVENNaW51dGVzKCkpICsgJzonICsgX2ZtdHRpbWVwYWQodC5nZXRVVENTZWNvbmRzKCkpICsgJ1onOw0KICAgICAgICAgICAgdmFyIHggPSBRKCdkMjVhbGFybV9pbnRlcnZhbCcpLnZhbHVlLnNwbGl0KCctJyk7DQogICAgICAgICAgICBpZiAoeC5sZW5ndGggIT0gMykgeyB4ID0gWzAsIDAsIDBdOyB9DQogICAgICAgICAgICB2YXIgYWxhcm1faW50ZXJ2YWwgPSAnUCcgKyB4WzBdICsgJ0RUJyArIHhbMV0gKyAnSCcgKyB4WzJdICsgJ00nOw0KICAgICAgICAgICAgdmFyIGFsYXJtX2RvYyA9IChRKCdkMjVhbGFybV9kb2MnKS52YWx1ZSA9PSAxKTsNCiAgICAgICAgICAgIHZhciB0cGwgPSBwcmVwYXJlQWxhcm1PY2N1cmVuY2VUZW1wbGF0ZShhbGFybV9uYW1lLCBhbGFybV9uYW1lLCBhbGFybV9zdGFydHRpbWUsIGFsYXJtX2ludGVydmFsLCBhbGFybV9kb2MpOw0KICAgICAgICAgICAgaWYgKGFscm0gPT0gdW5kZWZpbmVkKSB7DQogICAgICAgICAgICAgICAgd3NzdGFjay5FeGVjTWV0aG9kWG1sKGFtdHN0YWNrLkNvbXBsZXRlTmFtZSgiQU1UX0FsYXJtQ2xvY2tTZXJ2aWNlIiksICJBZGRBbGFybSIsIHRwbCwNCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goJ0FkZCBhbGFybScsICdGYWlsZWQgdG8gYWRkIGFsYXJtLiBTdGF0dXM6ICcgKyBzdGF0dXMgKyAnLjxici8+VmVyaWZ5IHRoZSBhbGFybSBpcyBmb3IgYSBmdXR1cmUgdGltZS4nKTsgcmV0dXJuOyB9DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UuQm9keVsnUmV0dXJuVmFsdWUnXSAhPSAwKSB7IG1lc3NhZ2Vib3goJ0FkZCBhbGFybScsICdGYWlsZWQgdG8gYWRkIGFsYXJtLCAnICsgcmVzcG9uc2UuQm9keVsnUmV0dXJuVmFsdWVTdHInXSArICcuPGJyLz5WZXJpZnkgdGhlIGFsYXJtIGlzIGZvciBhIGZ1dHVyZSB0aW1lLicpOyByZXR1cm47IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIFB1bGxBbGFybXMoKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHZhciBhbGFybXggPSBDbG9uZSh4eEFsYXJtc1thbHJtXSk7DQogICAgICAgICAgICAgICAgYWxhcm14WyJTdGFydFRpbWUiXSA9ICI8cDpEYXRldGltZSB4bWxuczpwPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NvbW1vblwiPiIgKyBhbGFybV9zdGFydHRpbWUgKyAiPC9wOkRhdGV0aW1lPiI7DQogICAgICAgICAgICAgICAgYWxhcm14WyJJbnRlcnZhbCJdID0gIjxwOkludGVydmFsIHhtbG5zOnA9XCJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY29tbW9uXCI+IiArIGFsYXJtX2ludGVydmFsICsgIjwvcDpJbnRlcnZhbD4iOw0KICAgICAgICAgICAgICAgIGFsYXJteFsiRGVsZXRlT25Db21wbGV0aW9uIl0gPSBhbGFybV9kb2M7DQogICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCJJUFNfQWxhcm1DbG9ja09jY3VycmVuY2UiLCBhbGFybXgsIGZ1bmN0aW9uICh3cywgcmVzdXJpLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goJ0VkaXQgYWxhcm0nLCAnRmFpbGVkIHRvIGNoYW5nZSBhbGFybS4gU3RhdHVzOiAnICsgc3RhdHVzICsgJy48YnIvPlZlcmlmeSB0aGUgYWxhcm0gZm9yIGF0IGEgZnV0dXJlIHRpbWUuJyk7IHJldHVybjsgfQ0KICAgICAgICAgICAgICAgICAgICBQdWxsQWxhcm1zKCk7DQogICAgICAgICAgICAgICAgfSwgbnVsbCwgbnVsbCwgeyAiSW5zdGFuY2VJRCIgOiBhbGFybXhbIkluc3RhbmNlSUQiXX0pOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0FsZXJ0RGV0YWlscyhpKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgYWxhcm0gPSB4eEFsYXJtc1tpXSwgd2FrZXRpbWUgPSBuZXcgRGF0ZShhbGFybVsiU3RhcnRUaW1lIl1bIkRhdGV0aW1lIl0pOw0KICAgICAgICAgICAgdmFyIHggPSAnPGRpdiBzdHlsZT10ZXh0LWFsaWduOmxlZnQ+JyArIGFkZEh0bWxWYWx1ZSgiTmFtZSIsIGFsYXJtWyJFbGVtZW50TmFtZSJdKSArIGFkZEh0bWxWYWx1ZSgiV2FrZSB0aW1lIiwgd2FrZXRpbWUudG9Mb2NhbGVTdHJpbmcoKS5yZXBsYWNlKCcsICcsICcgYXQgJykpOw0KICAgICAgICAgICAgaWYgKGFsYXJtWyJJbnRlcnZhbCJdICE9IHVuZGVmaW5lZCkgeyB4ICs9IGFkZEh0bWxWYWx1ZSgiSW50ZXJuYWwiLCBfZm10aW50ZXJ2YWwoYWxhcm1bIkludGVydmFsIl1bIkludGVydmFsIl0pKTsgfQ0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkFmdGVyIHdha2UiLCAoYWxhcm1bIkRlbGV0ZU9uQ29tcGxldGlvbiJdID09IHRydWUpPyJEZWxldGUgQWxhcm0iOiJLZWVwIEFsYXJtIikgKyAiPC9kaXY+IjsNCiAgICAgICAgICAgIG1lc3NhZ2Vib3goIkFsYXJtICIgKyBhbGFybVsiRWxlbWVudE5hbWUiXSwgeCk7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiQWxhcm0gIiArIGFsYXJtWyJFbGVtZW50TmFtZSJdLCA1LCBzaG93QWxlcnREZXRhaWxzRGVsZXRlLCB4LCBpKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dBbGVydERldGFpbHNEZWxldGUoYnV0dG9uLCB0YWcpIHsNCiAgICAgICAgICAgIGlmIChidXR0b24gPT0gMikgeyBhbXRzdGFjay5EZWxldGUoIklQU19BbGFybUNsb2NrT2NjdXJyZW5jZSIsIHh4QWxhcm1zW3RhZ10sIGZ1bmN0aW9uKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7IFB1bGxBbGFybXMoKTsgfSk7IH0NCiAgICAgICAgfQ0KDQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIFNjcmlwdGluZw0KICAgICAgICAvLw0KDQogICAgICAgIC8vIENhbGxlZCBieSB0aGUgIlJ1biBTY3JpcHQuLi4iIGJ1dHRvbi4gRGlzcGxheSBhIGRpYWxvZyBib3ggdG8gYXNrIGZvciB0aGUgc2NyaXB0IGZpbGUuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9ydW5TY3JpcHREbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8IHNjcmlwdHN0YXRlKSByZXR1cm47DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiUnVuIFNjcmlwdCIsIDMsIHNjcmlwdF9ydW5TY3JpcHREbGdPaywgIjxicj48aW5wdXQgaWQ9c2NyaXB0b3BlbiB0eXBlPWZpbGUgc3R5bGU9d2lkdGg6MTAwJSBhY2NlcHQ9Lm1lc2NyaXB0PiIpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gT25jZSB0aGUgc2NyaXB0IGZpbGUgaXMgc2VsZWN0ZWQsIGRlY29kZSB0aGUgc2NyaXB0IGhlcmUuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9ydW5TY3JpcHREbGdPayhyKSB7DQogICAgICAgICAgICBpZiAociAhPSAxKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9IFEoJ3NjcmlwdG9wZW4nKTsNCiAgICAgICAgICAgIGlmICh4LmZpbGVzLmxlbmd0aCAhPSAxKSByZXR1cm47DQogICAgICAgICAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsNCiAgICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSBzY3JpcHRfb25TY3JpcHRSZWFkOw0KICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyh4LmZpbGVzWzBdKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENhbGxlZCBvbmNlIHRoZSBzY3JpcHQgaXMgZGVjb2RlZCwgZ2V0IHRoZSBzY3JpcHQgc2V0dXAgYW5kIHN0YXJ0IHJ1bm5pbmcgaXQuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9vblNjcmlwdFJlYWQoZmlsZSkgew0KICAgICAgICAgICAgdmFyIHg7DQogICAgICAgICAgICB0cnkgeyB4ID0gSlNPTi5wYXJzZShmaWxlLnRhcmdldC5yZXN1bHQpOyB9IGNhdGNoIChlKSB7fQ0KDQogICAgICAgICAgICBpZiAoY3VycmVudFZpZXcgPT0gMjApIHsNCiAgICAgICAgICAgICAgICAvLyBMb2FkIHNjcmlwdCBpbnRvIGVkaXRvcg0KICAgICAgICAgICAgICAgIGlmICh4WydzY3JpcHRUZXh0J10pIFEoJ3NjcmlwdGFyZWEnKS52YWx1ZSA9IHhbJ3NjcmlwdFRleHQnXTsNCiAgICAgICAgICAgICAgICBpZiAoeFsnbWVzY3JpcHQnXSkgUSgnY29tcGlsZWRhcmVhJykudmFsdWUgPSByc3RyMmhleChhdG9iKHhbJ21lc2NyaXB0J10pKTsNCiAgICAgICAgICAgICAgICBpZiAoeFsnYmxvY2tzJ10pIHsgc2NyaXB0X3NldEJ1aWxkQmxvY2tzKHhbJ2Jsb2NrcyddKTsgc2NyaXB0Vmlld0J1dHRvbigxKTsgfSBlbHNlIHsgc2NyaXB0X3NldEJ1aWxkQmxvY2tzKCk7IHNjcmlwdFZpZXdCdXR0b24oMCk7IH0NCiAgICAgICAgICAgICAgICBpZiAoeFsnc2NyaXB0QmxvY2tzJ10pIHsgc2NyaXB0X0Jsb2NrU2NyaXB0ID0geFsnc2NyaXB0QmxvY2tzJ107IH0gZWxzZSB7IGlmICghc2NyaXB0X0J1aWxkaW5nQmxvY2tzKSB7IHNjcmlwdF9CbG9ja1NjcmlwdCA9IFtdOyB9IH0NCg0KICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgc2NyaXB0QmxvY2tzIHRvIHRoZSBsYXRlc3QgYmxvY2tzLiBUaGlzIGlzIGRvZXMgYmVjYXVzZSB3ZSBtYXkgdXBkYXRlIGFuIGV4aXN0aW5nIHNjcmlwdCB0byBuZXcgYmxvY2tzLg0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gc2NyaXB0X0Jsb2NrU2NyaXB0KSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBibG9jayA9IHNjcmlwdF9CbG9ja1NjcmlwdFtpXTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHhibG9jayA9IHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1tibG9ja1sneG5hbWUnXV07DQogICAgICAgICAgICAgICAgICAgIGlmICh4YmxvY2spIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBiID0gQ2xvbmUoeGJsb2NrKTsgLy8gQ2xvbmUgYSBuZXcgYmxvY2ssIHRoZW4gc2V0IGFsbCB0aGUgdmFyaWFibGVzLg0KICAgICAgICAgICAgICAgICAgICAgICAgYlsnaWQnXSA9IGJsb2NrWydpZCddOw0KICAgICAgICAgICAgICAgICAgICAgICAgYlsneG5hbWUnXSA9IGJsb2NrWyd4bmFtZSddOw0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiBpbiBiLnZhcnMpIHsgaWYgKGJsb2NrLnZhcnNbal0pIHsgYi52YXJzW2pdWyd2YWx1ZSddID0gYmxvY2sudmFyc1tqXVsndmFsdWUnXTsgfSB9DQogICAgICAgICAgICAgICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRbaV0gPSBiOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgLy8gUmVzZXQgdGhlIHNjcmlwdCBzdGF0ZQ0KICAgICAgICAgICAgICAgIGZ1cGRhdGVzY3JpcHQoKTsNCiAgICAgICAgICAgICAgICBkZWxldGUgc2NyaXB0c3RhdGU7DQogICAgICAgICAgICAgICAgcmVzZXRTY3JpcHRCdXR0b24oKTsNCiAgICAgICAgICAgICAgICByZXR1cm47DQogICAgICAgICAgICB9DQogICAgICAgICAgICB2YXIgc3RhcnR2YXJzID0geyAnX2ludGVyYWN0aXZlJzoxIH07DQoNCiAgICAgICAgICAgIHN0YXJ0dmFyc1snX2NlcnRpZmljYXRlcyddID0gMTsNCg0KICAgICAgICAgICAgc3RhcnR2YXJzWydfbW9kZSddID0gJ0Zpcm13YXJlJzsNCg0KICAgICAgICAgICAgc3RhcnR2YXJzWydfbW9kZSddID0gJ01lc2hDZW50cmFsMic7DQoNCiAgICAgICAgICAgIHN0YXJ0dmFyc1snX21vZGUnXSA9ICdMTVMnOw0KICAgICAgICAgICAgaWYgKHggJiYgeFsnbWVzY3JpcHQnXSkgc2NyaXB0c3RhdGUgPSBzY3JpcHRfc2V0dXAoYXRvYih4WydtZXNjcmlwdCddKSwgc3RhcnR2YXJzKTsNCiAgICAgICAgICAgIGlmIChzY3JpcHRzdGF0ZSkgew0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLndzc3RhY2sgPSB3c3N0YWNrOw0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLmFtdHN0YWNrID0gYW10c3RhY2s7DQogICAgICAgICAgICAgICAgc2NyaXB0c3RhdGUub25TdGVwID0gc2NyaXB0X3VwZGF0ZVNjcmlwdFN0YXRlOw0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLm9uQ29uc29sZSA9IHNjcmlwdF9jb25zb2xlOw0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLnN0YXJ0KDEwMCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goIlJ1biBTY3JpcHQiLCAiSW52YWxpZCBzY3JpcHQgZmlsZS4iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENhbGxlZCB3aGVuIHRoZSBzY3JpcHQgY2hhbmdlcyBzdGF0ZSwgZGlzcGxheXMgdGhlIGdyZWVuIHN0YXR1cyBiYXIgYXQgdGhlIHRvcCBvZiB0aGUgd2ViIHBhZ2UuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF91cGRhdGVTY3JpcHRTdGF0ZSgpIHsNCiAgICAgICAgICAgIGlmIChzY3JpcHRzdGF0ZSkgew0KICAgICAgICAgICAgICAgIFFWKCdpZF9zY3JpcHRzdGF0dXMnLCBzY3JpcHRzdGF0ZS5zdGF0ZSA+IDApOyBjZW50ZXIoKTsNCiAgICAgICAgICAgICAgICBpZiAoc2NyaXB0c3RhdGUuc3RhdGUgPT0gMCkgew0KICAgICAgICAgICAgICAgICAgICBzY3JpcHRzdGF0ZSA9IHVuZGVmaW5lZDsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgYnkgYSBydW5uaW5nIHNjcmlwdCB0byB1cGRhdGUgdGhlIGNvbnNvbGUuIFRoZSBsYXN0IG1lc3NhZ2UgaW4gdGhlIGNvbnNvbGUgaXMgZGlzcGxheWVkIGluIHRoZSB0b3AgZ3JlZW4gYmFyLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfY29uc29sZShtc2cpIHsNCiAgICAgICAgICAgIGlmIChtc2cuaW5kZXhPZigiSU5GTzogIikgPT0gMCkgeyBtc2cgPSBtc2cuc3Vic3RyaW5nKDYpOyB9DQogICAgICAgICAgICBpZiAobXNnLmluZGV4T2YoIlNVQ0NFU1M6ICIpID09IDApIHsgbXNnID0gbXNnLnN1YnN0cmluZyg5KTsgfQ0KICAgICAgICAgICAgaWYgKG1zZy5pbmRleE9mKCJFUlJPUjogIikgPT0gMCkgeyBtc2cgPSBtc2cuc3Vic3RyaW5nKDcpOyB9DQogICAgICAgICAgICBRSCgnaWRfc2NyaXB0c3RhdHVzc3RyJywgJywgJyArIG1zZyk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgYnkgdGhlICJTdG9wIiBidXR0b24gb24gdGhlIHNjcmlwdCBzdGF0dXMgYmFyLiBDYXVzZXMgdGhlIHNjcmlwdCB0byBzdG9wLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfU3RvcCgpIHsNCiAgICAgICAgICAgIGlmIChzY3JpcHRzdGF0ZSkgew0KICAgICAgICAgICAgICAgIGlmIChzY3JpcHRzdGF0ZS5kaWFsb2cgPT0gdHJ1ZSkgeyBzZXREaWFsb2dNb2RlKDApOyB9DQogICAgICAgICAgICAgICAgc2NyaXB0c3RhdGUuc3RvcCgpOw0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLnN0YXRlID0gMDsNCiAgICAgICAgICAgICAgICBzY3JpcHRfdXBkYXRlU2NyaXB0U3RhdGUoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQoNCg0KICAgICAgICANCiAgICAgICAgdmFyIHNjcmlwdF9CdWlsZGluZ0Jsb2NrczsgLy8gTGlzdCBvZiBibG9jayB0aGF0IGNhbiBiZSB1c2VkIHRvIGJ1aWxkIGEgc2NyaXB0LiBUaGlzIGlzIHNob3duIG9uIHRoZSBsaXN0IHNpZGUuDQogICAgICAgIHZhciBzY3JpcHRfU3RhcnRpbmdCdWlsZGluZ0Jsb2NrczsgLy8gTGlzdCBvZiBibG9jayB0aGF0IGNhbiBiZSB1c2VkIHRvIGJ1aWxkIGEgc2NyaXB0IHdoZW4geW91IGdldCBzdGFydGVkLg0KICAgICAgICB2YXIgc2NyaXB0X0Jsb2NrU2NyaXB0ID0gW107IC8vIExpc3Qgb2YgYmxvY2tzIHRoYXQgYXJlIHBhcnQgb2YgdGhlIGN1cnJlbnQgc2NyaXB0Lg0KICAgICAgICB2YXIgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IG51bGw7IC8vIFRoZSBpZGVudGlmaWVyIG9mIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgYmxvY2suDQogICAgICAgIHZhciBzY3JpcHRfQnVpbGRlclZpZXcgPSAwOyAvLyAwID0gRWRpdG9yIFZpZXcsIDEgPSBCdWlsZGVyIFZpZXcNCiAgICAgICAgdmFyIGVkaXRzY3JpcHRzdGF0ZTsgLy8gVGhpcyBpcyB0aGUgaW5zdGFuY2Ugb2YgdGhlIHNjcmlwdCBydW5uZXIgdXNlZCBieSB0aGUgZWRpdG9yLiBUaGlzIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBydW5uZXIgdXNlZCBieSB0aGUgd2ViIHBhZ2UuDQoNCg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRMb2FkU3RhcnRpbmdCbG9ja3MoKSB7DQoNCiAgICAgICAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7DQogICAgICAgICAgICByZXF1ZXN0Lm9ubG9hZCA9IGZ1bmN0aW9uKCkgew0KICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0LnN0YXR1cyA+PSAyMDAgJiYgcmVxdWVzdC5zdGF0dXMgPCA0MDApIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gU3VjY2Vzcw0KICAgICAgICAgICAgICAgICAgICB2YXIgeDsNCiAgICAgICAgICAgICAgICAgICAgdHJ5IHsgeCA9IEpTT04ucGFyc2UocmVxdWVzdC5yZXNwb25zZVRleHQpOyB9IGNhdGNoIChlKSB7fQ0KICAgICAgICAgICAgICAgICAgICBpZiAoKHgpICYmICh4WydibG9ja3MnXSkpIHsgc2NyaXB0X1N0YXJ0aW5nQnVpbGRpbmdCbG9ja3MgPSB4WydibG9ja3MnXTsgc2NyaXB0X3NldEJ1aWxkQmxvY2tzKHNjcmlwdF9TdGFydGluZ0J1aWxkaW5nQmxvY2tzKTsgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH07DQogICAgICAgICAgICByZXF1ZXN0Lm9uZXJyb3IgPSBmdW5jdGlvbigpIHsgY29uc29sZS5sb2coJ0ZhaWxlZCB0byBnZXQgc2NyaXB0IGJsb2NrcycpOyB9Ow0KICAgICAgICAgICAgcmVxdWVzdC5vcGVuKCdHRVQnLCAnc2NyaXB0YmxvY2tzLnR4dCcsIHRydWUpOw0KICAgICAgICAgICAgcmVxdWVzdC5zZW5kKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgYnkgdGhlICJWaWV3IEVkaXRvciIgb3IgIlZpZXcgQnVpbGRlciIgYnV0dG9uIHRvIHRvZ2dsZSBiZXR3ZWVuIHRoZSB2aWV3IG1vZGVzLg0KICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBjb25zdHJ1Y3Rpb24gYmxvY2tzLCBkaXNwbGF5IHRoZSBzY3JpcHQgZWRpdG9yIG9ubHkuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdFZpZXdCdXR0b24oeCkgew0KICAgICAgICAgICAgc2NyaXB0X0J1aWxkZXJWaWV3ID0geDsNCiAgICAgICAgICAgIFFWKCdzY3JpcHRlZGl0b3InLCB4ID09IDApOw0KICAgICAgICAgICAgUVYoJ3NjcmlwdGJ1aWxkZXInLCB4ID09IDEpOw0KICAgICAgICAgICAgUVYoJ3ZpZXdFZGl0b3JCdXR0b24nLCBzY3JpcHRfQnVpbGRpbmdCbG9ja3MgJiYgKHggPT0gMSkpOw0KICAgICAgICAgICAgUVYoJ3ZpZXdCdWlsZGVyQnV0dG9uJywgc2NyaXB0X0J1aWxkaW5nQmxvY2tzICYmICh4ID09IDApKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIERpc3BsYXkgdGhlIGxpc3Qgb2YgY29uc3RydWN0aW9uIHNjcmlwdCBibG9jayBvbiB0aGUgbGVmdCBzaWRlLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfc2V0QnVpbGRCbG9ja3MoYmxvY2tzKSB7DQogICAgICAgICAgICBzY3JpcHRfQnVpbGRpbmdCbG9ja3MgPSBibG9ja3M7DQogICAgICAgICAgICB2YXIgeCA9ICcnOw0KICAgICAgICAgICAgaWYgKGJsb2Nrcykgew0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYmxvY2tzKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChpLmNoYXJDb2RlQXQoMCkgIT0gOTUpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gJzxkaXYgaWQ9c2Jsb2NrXycgKyBpICsgJyBzdHlsZT1jdXJzb3I6cG9pbnRlcjtiYWNrZ3JvdW5kLWNvbG9yOiNjY2M7d2lkdGg6YXV0bztwYWRkaW5nOjVweDttYXJnaW46MnB4IG9uZGJsY2xpY2s9c2NyaXB0X2ZhZGRibG9jaygiJyArIGkgKyAnIikgZHJhZ2dhYmxlPXRydWUgb25kcmFnc3RhcnQ9c2NyaXB0X2ZvbmRyYWdzdGFydChldmVudCx0aGlzKSBvbmRyYWdlbmQ9c2NyaXB0X2ZvbmRyYWdlbmQoZXZlbnQsdGhpcykgdGl0bGU9IicgKyBibG9ja3NbaV1bJ2Rlc2MnXSArICciJzsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gJz4nICsgYmxvY2tzW2ldWyduYW1lJ10gKyAnPC9kaXY+JzsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIFFIKCdibG9ja3MnLCB4KTsNCiAgICAgICAgICAgIHNjcmlwdF9mb25maWx0ZXJjaGFuZ2VkKCk7DQogICAgICAgICAgICBzY3JpcHRWaWV3QnV0dG9uKHNjcmlwdF9CdWlsZGluZ0Jsb2Nrcz8xOjApOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQWRkIGEgbmV3IGJsb2NrIHRvIHRoZSBlbmQgb2YgdGhlIGJsb2NrIHNjcmlwdC4gVGhpcyBpcyBjYWxsZWQgd2hlbiB5b3UgcmlnaHQgY2xpY2sgb24gYSBibG9jayBhbmQgaGl0ICJBZGQiIGluIHRoZSBjb250ZXh0IG1lbnUuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mYWRkYmxvY2soaCkgew0KICAgICAgICAgICAgdmFyIGIgPSBDbG9uZShzY3JpcHRfQnVpbGRpbmdCbG9ja3NbaF0pOyAvLyBUbyBhZGQgYSBuZXcgYmxvY2sgdG8gdGhlIHNjcmlwdCwgY2xvbmUgdGhlIGJsb2NrLCBhc3NpZ24gaXQgYSByYW5kb20gaWQgYW5kIHNldCB0aGUgeG5hbWUgdG8gdGhlIG5hbWUgb2YgdGhlIGJsb2NrLg0KICAgICAgICAgICAgYlsnaWQnXSA9IE1hdGgucmFuZG9tKCk7DQogICAgICAgICAgICBiWyd4bmFtZSddID0gaDsNCiAgICAgICAgICAgIHNjcmlwdF9CbG9ja1NjcmlwdC5wdXNoKGIpOyAvLyBOb3cgdGhhdCBhIGJsb2NrIGlzIGNyZWF0ZWQsIGFkZCBpdCBhdCB0aGUgZW5kIG9mIHRoZSBzY3JpcHQgYW5kIHNldCBpdCBhcyB0aGUgc2VsZWN0ZWQgYmxvY2suDQogICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID0gc2NyaXB0X0Jsb2NrU2NyaXB0Lmxlbmd0aCAtIDE7DQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7IC8vIFJlLWRpc3BsYXkgdGhlIGxpc3Qgb2Ygc2NyaXB0IGJsb2Nrcy4gVGhlIHNlbGVjdGVkIGJsb2NrIHdpbGwgYWxzbyBiZSBoaWdobGlnaHRlZC4NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIEVkaXQgYSBzY3JpcHQgYmxvY2sNCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZlZGl0YmxvY2soaCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ0VkaXQgJyArIHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1toXVsnbmFtZSddLCAzLCBzY3JpcHRfZmVkaXRibG9ja0V4LCAnRWRpdCB0aGlzIGJsb2NrPyBUaGlzIG9wZXJhdGlvbiB3aWxsIHJlc2V0IHRoZSBibG9jayBlZGl0b3IgYW5kIGxvYWQgdGhlIGJsb2NrIGNvZGUgaW50byB0aGUgY29kZSBlZGl0b3IuJywgaCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgd2hlbiB0aGUgc2NyaXB0IGJsb2NrIGVkaXQgZGlhbG9nIGlzIGNsb3NlZC4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZlZGl0YmxvY2tFeChidXR0b24sIGgpIHsNCiAgICAgICAgICAgIHNjcmlwdF9uZXdTY3JpcHREbGdPaygpOw0KICAgICAgICAgICAgc2NyaXB0Vmlld0J1dHRvbigwKTsNCiAgICAgICAgICAgIHZhciB4ID0gJycsIGIgPSBzY3JpcHRfQnVpbGRpbmdCbG9ja3NbaF07DQogICAgICAgICAgICB4ICs9ICcjIyFCTE9DSyEjI1xyXG4jaWQ9JyArIGggKyAnXHJcbiNuYW1lPScgKyBiWyduYW1lJ10gKyAnXHJcbiNkZXNjPScgKyBiWydkZXNjJ10gKyAnXHJcbiMjIUJMT0NLISMjXHJcbic7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGJbJ3ZhcnMnXSkgew0KICAgICAgICAgICAgICAgIHZhciB2ID0gYlsndmFycyddW2ldOw0KICAgICAgICAgICAgICAgIHggKz0gJyMjIVZBUiEjI1xyXG4jaWQ9JyArIGkgKyAnXHJcbiNuYW1lPScgKyB2WyduYW1lJ10gKyAnXHJcbiNkZXNjPScgKyB2WydkZXNjJ10gKyAnXHJcbiN0eXBlPScgKyB2Wyd0eXBlJ10gKyAnXHJcbic7DQogICAgICAgICAgICAgICAgaWYgKHZbJ21heGxlbmd0aCddKSB7IHggKz0gJyNtYXhsZW5ndGg9JyArIHZbJ21heGxlbmd0aCddICsgJ1xyXG4nOyB9DQogICAgICAgICAgICAgICAgaWYgKHZbJ3ZhbHVlcyddKSB7IGZvciAodmFyIGogaW4gdlsndmFsdWVzJ10pIHsgeCArPSAnI3ZhbHVlcy0nICsgaiArJz0nICsgdlsndmFsdWVzJ11bal0gKyAnXHJcbic7IH0gfQ0KICAgICAgICAgICAgICAgIHggKz0gJyN2YWx1ZT0nICsgdlsndmFsdWUnXSArICdcclxuIyNTV0FQICUlJScgKyBpICsgJyUlJSAnICsgdlsndmFsdWUnXSArICdcclxuJzsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gJyMjIVZBUiEjI1xyXG4jI1NXQVAgJSUlfiUlJSAwXHJcblxyXG4jIyFCTE9DSyEjI1xyXG4nICsgYlsnY29kZSddICsgJ1xyXG4jIyFCTE9DSyEjI1xyXG4nOw0KICAgICAgICAgICAgUSgnc2NyaXB0YXJlYScpLnZhbHVlID0geDsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mQ29udmVydFNjcmlwdFRvSnNvbkJsb2NrKHNjcmlwdCkgew0KICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHt9LCBzY3JpcHRwYXJ0cyA9IHNjcmlwdC5zcGxpdCgnIyMhQkxPQ0shIyNcbicpLCBzY3JpcHRsaW5lcyA9IHNjcmlwdHBhcnRzWzFdLnNwbGl0KCdcbicpOw0KDQogICAgICAgICAgICAvLyBQYXJzZSBpbmZvcm1hdGlvbiBwYXJ0DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHNjcmlwdGxpbmVzKSB7DQogICAgICAgICAgICAgICAgdmFyIHMgPSBzY3JpcHRsaW5lc1tpXS5zcGxpdCgnPScpOw0KICAgICAgICAgICAgICAgIGlmIChzLmxlbmd0aCA9PSAyKSB7IHJlc3VsdFtzWzBdLnN1YnN0cmluZygxKV0gPSBzWzFdOyB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIFBhcnNlIHZhcmlhYmxlcyBwYXJ0DQogICAgICAgICAgICByZXN1bHRbJ3ZhcnMnXSA9IHt9Ow0KICAgICAgICAgICAgc2NyaXB0dmFyaWFibGVzID0gc2NyaXB0cGFydHNbMl0uc3BsaXQoJyMjIVZBUiEjI1xuJyk7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHNjcmlwdHZhcmlhYmxlcykgew0KICAgICAgICAgICAgICAgIHNjcmlwdGxpbmVzID0gc2NyaXB0dmFyaWFibGVzW2ldLnNwbGl0KCdcbicpOw0KICAgICAgICAgICAgICAgIHZhciB2ID0ge30sIHZhbHVlcyA9IHt9LCB2YWx1ZXNsZW4gPSAwOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gc2NyaXB0bGluZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHMgPSBzY3JpcHRsaW5lc1tqXS5zcGxpdCgnPScpOw0KICAgICAgICAgICAgICAgICAgICBpZiAoKHMubGVuZ3RoID09IDIpICYmIChzWzFdKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChzWzBdKSAmJiAoc1swXS5sZW5ndGggPiAwKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzWzBdLnN1YnN0cmluZygwLCA4KSA9PSAnI3ZhbHVlcy0nKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlc1tzWzBdLnN1YnN0cmluZyg4KV0gPSBzWzFdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXNsZW4rKzsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2W3NbMF0uc3Vic3RyaW5nKDEpXSA9IHNbMV07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmICh2LmlkKSB7DQogICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZXNsZW4gPiAwKSB7IHZbJ3ZhbHVlcyddID0gdmFsdWVzOyB9DQogICAgICAgICAgICAgICAgICAgIHZhciBpZCA9IHYuaWQ7DQogICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB2LmlkOw0KICAgICAgICAgICAgICAgICAgICByZXN1bHRbJ3ZhcnMnXVtpZF0gPSB2Ow0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gUGFyc2UgY29kZSBwYXJ0DQogICAgICAgICAgICByZXN1bHRbJ2NvZGUnXSA9IHNjcmlwdHBhcnRzWzNdOw0KDQogICAgICAgICAgICAvLyBQYWNrYWdlIHRoZSByZXN1bHQNCiAgICAgICAgICAgIHZhciBpZCA9IHJlc3VsdC5pZDsNCiAgICAgICAgICAgIGRlbGV0ZSByZXN1bHQuaWQ7DQogICAgICAgICAgICB2YXIgciA9IHt9Ow0KICAgICAgICAgICAgcltpZF0gPSByZXN1bHQ7DQogICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkociwgbnVsbCwgJyAgJyk7DQogICAgICAgIH0NCg0KICAgICAgICAvKg0KICAgICAgICAvLyBJZiB0aGUgZGVsZXRlIGtleSBpcyBwcmVzc2VkLCBkZWxldGUgdGhlIGJsb2NrDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25rZXlwcmVzcyhlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBpZiAoZS5rZXkgPT0gJ0RlbGV0ZScgJiYgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCAhPSBudWxsKSB7DQogICAgICAgICAgICAgICAgLy9kZWxldGUgc2NyaXB0X0Jsb2NrU2NyaXB0W3NjcmlwdF9CbG9ja1NjcmlwdFNlbGVjdGVkSWRdOw0KICAgICAgICAgICAgICAgIHNjcmlwdF9CbG9ja1NjcmlwdC5zcGxpY2Uoc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCwgMSk7DQogICAgICAgICAgICAgICAgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IG51bGw7DQogICAgICAgICAgICAgICAgZnVwZGF0ZXNjcmlwdCgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgICovDQoNCiAgICAgICAgLy8gRmlsZXIgdGhlIGxpc3Qgb2YgYmxvY2tzIG9uIHRoZSBsZWZ0IHNpZGUgbGlzdC4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmZpbHRlcmNoYW5nZWQoKSB7DQogICAgICAgICAgICB2YXIgZmlsdGVyID0gUSgnYmxvY2tmaWx0ZXInKS52YWx1ZS50b0xvd2VyQ2FzZSgpOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBzY3JpcHRfQnVpbGRpbmdCbG9ja3MpIHsNCiAgICAgICAgICAgICAgICAvLyBTY3JpcHQgYmxvY2tzIHRoYXQgc3RhcnQgd2l0aCAiXyIgYXJlIGhpZGRlbiBibG9ja3MgYW5kIHNob3VsZCBuZXZlciBiZSBzaG93bi4NCiAgICAgICAgICAgICAgICBpZiAoaS5jaGFyQ29kZUF0KDApICE9IDk1KSB7IFFWKCdzYmxvY2tfJyArIGksIChzY3JpcHRfQnVpbGRpbmdCbG9ja3NbaV1bJ25hbWUnXS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoZmlsdGVyKSA+PSAwIHx8IHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1tpXVsnZGVzYyddLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihmaWx0ZXIpID49IDApKTsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ2FsbGVkIHdoZW4geW91IGNsaWNrIG9uIGEgYmxvY2suIElmIHlvdSBkb3VibGUgY2xpY2ssIG9uIGEgYmxvY2ssIGRvIGxpa2UgcHJlc3Npbmcgb24gdGhlICJFZGl0Li4uIiBidXR0b24uDQogICAgICAgIHZhciBzY3JpcHRfZm9uY2xpY2tEYmxDbGlja0RldGVjdEluZGV4ID0gbnVsbDsNCiAgICAgICAgdmFyIHNjcmlwdF9mb25jbGlja0RibENsaWNrRGV0ZWN0VGltZSA9IG51bGw7DQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25jbGljayhlLCB0KSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID0gbnVsbDsNCiAgICAgICAgICAgIGlmICh0KSB7IHQgPSBmZ2V0UGFyZW50V2l0aElkKHQpOyBpZiAodC5pZC5zdGFydHNXaXRoKCd4YmxvY2tfJykpIHsgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IHQuaWQuc3Vic3RyaW5nKDcpOyB9IH0gLy8gRmlndXJlIG91dCB3aGF0IGJsb2NrIHdhcyBjbGlja2VkIG9uDQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7IC8vIFRoaXMgd2lsbCBzaG93IHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgYmxvY2sgaW4gYSBkaWZmZXJlbnQgY29sb3IuDQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQoNCiAgICAgICAgICAgIC8vIEZpZ3VyZSBvdXQgaWYgdGhpcyBpcyBhIGRvdWJsZSBjbGljay4gV2UgbmVlZCB0d28gY2xpY2tzIG9uIHRoZSBzYW1lIG9iamVjdCB3aXRoaW4gMjUwbXMuDQogICAgICAgICAgICBpZiAoc2NyaXB0X2ZvbmNsaWNrRGJsQ2xpY2tEZXRlY3RJbmRleCA9PSBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkICYmIChuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHNjcmlwdF9mb25jbGlja0RibENsaWNrRGV0ZWN0VGltZSkgPCAyNTApIHsgcmV0dXJuIHNjcmlwdF9mb25lZGl0Y2xpY2soc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCk7IH0NCiAgICAgICAgICAgIHNjcmlwdF9mb25jbGlja0RibENsaWNrRGV0ZWN0SW5kZXggPSBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkOw0KICAgICAgICAgICAgc2NyaXB0X2ZvbmNsaWNrRGJsQ2xpY2tEZXRlY3RUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBTY3JpcHQgYmxvY2sgZHJhZyAmIGRyb3AgZnVuY3Rpb25zLCBhbGxvdyB0aGUgdXNlciB0byBjcmVhdGUgYW5kIG1vdmUgc2NyaXB0IGJsb2Nrcy4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmRyYWdzdGFydChlLCB0KSB7IGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsgdCA9IGZnZXRQYXJlbnRXaXRoSWQodCk7IHQuc3R5bGUub3BhY2l0eSA9ICcwLjQnOyBlLmRhdGFUcmFuc2Zlci5lZmZlY3RBbGxvd2VkID0gJ21vdmUnOyBlLmRhdGFUcmFuc2Zlci5zZXREYXRhKCdzY3JpcHRidWlsZGVyL2Jsb2NrJywgdC5pZCk7IH0NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmRyYWdlbmQoZSwgdCkgICB7IGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsgdCA9IGZnZXRQYXJlbnRXaXRoSWQodCk7IHQuc3R5bGUub3BhY2l0eSA9ICcxLjAnOyB9DQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25kcmFnZW50ZXIoZSwgdCkgeyBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47IGZnZXRQYXJlbnRXaXRoSWQodCkuc3R5bGVbJ2JvcmRlci10b3AnXSA9ICdzb2xpZCAycHggYmxhY2snOyB9DQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25kcmFnbGVhdmUoZSwgdCkgeyBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47IGUgPSBlLm9yaWdpbmFsRXZlbnQgfHwgZTsgdmFyIGN1cnJlbnRFbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnBhZ2VYLCBlLnBhZ2VZKTsgaWYgKCF0LmNvbnRhaW5zKGN1cnJlbnRFbGVtZW50KSkgeyBmZ2V0UGFyZW50V2l0aElkKHQpLnN0eWxlWydib3JkZXItdG9wJ10gPSAnbm9uZSc7IH0gfQ0KDQogICAgICAgIC8vIENhbGxlZCB3aGVuIHlvdSBkcm9wIGEgYmxvY2sgb24gdGhlIGJsb2NrIHNjcmlwdCBhcmVhLiBUaGlzIGNvZGUgd2lsbCBhZGQgb3IgbW92ZSBhIGJsb2NrIGludG8gaXQncyBuZXcgcGxhY2UuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25kcm9wKGUsIHQpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHQgPSBmZ2V0UGFyZW50V2l0aElkKHQpOw0KICAgICAgICAgICAgdmFyIGIsIHggPSBlLmRhdGFUcmFuc2Zlci5nZXREYXRhKCdzY3JpcHRidWlsZGVyL2Jsb2NrJyksIGRwID0gcGFyc2VJbnQodC5pZC5zdWJzdHJpbmcoNykpOw0KICAgICAgICAgICAgaWYgKHggPT0gJycpIHsgZG9jdW1lbnRGaWxlU2VsZWN0SGFuZGxlcihlKTsgcmV0dXJuOyB9DQogICAgICAgICAgICBpZiAoeC5zdGFydHNXaXRoKCJzYmxvY2tfIikpIHsNCiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgc2NyaXB0IGJsb2NrDQogICAgICAgICAgICAgICAgYiA9IENsb25lKHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1t4LnN1YnN0cmluZyg3KV0pOw0KICAgICAgICAgICAgICAgIGJbJ2lkJ10gPSBNYXRoLnJhbmRvbSgpOw0KICAgICAgICAgICAgICAgIGJbJ3huYW1lJ10gPSB4LnN1YnN0cmluZyg3KTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gUHVsbCBhbiBleGlzdGluZyBzY3JpcHQgYmxvY2sgZnJvbSB0aGUgbGlzdA0KICAgICAgICAgICAgICAgIHZhciBpID0gcGFyc2VJbnQoeC5zdWJzdHJpbmcoNykpOw0KICAgICAgICAgICAgICAgIGIgPSBzY3JpcHRfQmxvY2tTY3JpcHRbaV07DQogICAgICAgICAgICAgICAgc2NyaXB0X0Jsb2NrU2NyaXB0LnNwbGljZShpLCAxKTsNCiAgICAgICAgICAgICAgICBpZiAoZHAgPiBpKSBkcC0tOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKHQuaWQgPT0gJ3NjcmlwdGJsb2NrcycpIHsNCiAgICAgICAgICAgICAgICAvLyBQdXQgdGhlIGJsb2NrIGF0IHRoZSBlbmQgb2YgdGhlIGxpc3QNCiAgICAgICAgICAgICAgICBpZiAoYikgc2NyaXB0X0Jsb2NrU2NyaXB0LnB1c2goYik7DQogICAgICAgICAgICAgICAgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IHNjcmlwdF9CbG9ja1NjcmlwdC5sZW5ndGggLSAxOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAvLyBJbnNlcnQgdGhlIGJsb2NrIHdpdGhpbiB0aGUgbGlzdCwgYWJvdmUgdGhlIGRyb3AgcG9pbnQNCiAgICAgICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHQuc3BsaWNlKGRwLCAwLCBiKTsNCiAgICAgICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID0gZHA7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgd2hlbiB5b3UgaGl0ICJFZGl0Li4uIiBvbiBhIGJsb2NrLCBkaXNwbGF5cyBhIGRpYWxvZyBib3ggd2l0aCBhbGwgYmxvY2sgYXR0cmlidXRlcy4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmVkaXRjbGljayhoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgYmxvY2sgPSBzY3JpcHRfQmxvY2tTY3JpcHRbaF07DQogICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID0gaDsNCiAgICAgICAgICAgIGZ1cGRhdGVzY3JpcHQoKTsNCg0KICAgICAgICAgICAgaWYgKGJsb2NrICE9IG51bGwpIHsNCiAgICAgICAgICAgICAgICB2YXIgYiA9IGJsb2NrWyd2YXJzJ10gPyA3IDogNTsNCiAgICAgICAgICAgICAgICB2YXIgYyA9IGJsb2NrWydkZXNjJ10gKyAiPGJyPjxicj4iOw0KICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIEZvciBlYWNoIHZhcmlhYmxlIGluIGEgYmxvY2ssIGFkZCB0aGUgcHJvcGVyIGlucHV0IGNvbnRyb2wgZm9yIHRoaXMgdmFyaWFibGUgYW5kIHNldCB0aGUgY29udHJvbCB0byB0aGUgY3VycmVudCB2YWx1ZS4NCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBibG9ja1sndmFycyddKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZCA9IGJsb2NrWyd2YXJzJ11baV1bJ3ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9ICcnOw0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gQmxvY2sgdmFsdWVzIGNhbiBiZSBvbiB0eXBlIDE6VGV4dCwyOk51bWJlciwzOkRyb3BEb3duTGlzdCw0OnBhc3N3b3JkLDU6TXVsdGlTZWxlY3QNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWydtYXhsZW5ndGgnXSkgYXR0cmlidXRlcyArPSAoIiBtYXhsZW5ndGg9IiArIGJsb2NrWyd2YXJzJ11baV1bJ21heGxlbmd0aCddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gMikgeyBhdHRyaWJ1dGVzICs9ICIgb25rZXlwcmVzcz0ncmV0dXJuIG51bWJlcnNPbmx5KGV2ZW50KSciIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gMSB8fCBibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gMikgeyBkID0gIjxpbnB1dCB0aXRsZT0nIiArIGJsb2NrWyd2YXJzJ11baV1bJ2Rlc2MnXSArICInIGlkPXNjcmlwdFh2YWx1ZV8iICsgaSArICIgdmFsdWU9JyIgKyBibG9ja1sndmFycyddW2ldWyd2YWx1ZSddICsgIicgIiArIGF0dHJpYnV0ZXMgKyAiIHN0eWxlPXdpZHRoOjEwMCU+PC9pbnB1dD4iOyB9DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbJ3ZhcnMnXVtpXVsndHlwZSddID09IDMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkID0gIjxzZWxlY3QgdGl0bGU9JyIgKyBibG9ja1sndmFycyddW2ldWydkZXNjJ10gKyAiJyBpZD1zY3JpcHRYdmFsdWVfIiArIGkgKyAiIHN0eWxlPXdpZHRoOjEwMCU7cGFkZGluZzowO21hcmdpbjowPiI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiBpbiBibG9ja1sndmFycyddW2ldWyd2YWx1ZXMnXSkgeyBkICs9ICI8b3B0aW9uIHZhbHVlPSIgKyBqICsgKGogPT0gYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWUnXSA/ICIgc2VsZWN0ZWQiIDogIiIpICsgIj4iICsgYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWVzJ11bal0gKyAiPC9vcHRpb24+IjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQgKz0gIjwvc2VsZWN0PiI7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbJ3ZhcnMnXVtpXVsndHlwZSddID09IDQpIHsgZCA9ICI8aW5wdXQgdHlwZT1wYXNzd29yZCBhdXRvY29tcGxldGU9b2ZmIHRpdGxlPSciICsgYmxvY2tbJ3ZhcnMnXVtpXVsnZGVzYyddICsgIicgaWQ9c2NyaXB0WHZhbHVlXyIgKyBpICsgIiB2YWx1ZT0nIiArIGJsb2NrWyd2YXJzJ11baV1bJ3ZhbHVlJ10gKyAiJyAiICsgYXR0cmlidXRlcyArICIgc3R5bGU9d2lkdGg6MTAwJT48L2lucHV0PiI7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gNSkgeyBkID0gJyc7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gNikgeyBkID0gIjxpbnB1dCB0eXBlPWZpbGUgdGl0bGU9JyIgKyBibG9ja1sndmFycyddW2ldWydkZXNjJ10gKyAiJyBpZD1zY3JpcHRYdmFsdWVfIiArIGkgKyAiICIgKyBhdHRyaWJ1dGVzICsgIiBzdHlsZT13aWR0aDoxMDAlPjwvaW5wdXQ+IjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgYyArPSAnPHRhYmxlIHN0eWxlPXdpZHRoOjEwMCUgdGl0bGU9IicgKyBibG9ja1sndmFycyddW2ldWydkZXNjJ10gKyAnIj48dGQgc3R5bGU9d2lkdGg6MTIwcHg+JyArIGJsb2NrWyd2YXJzJ11baV1bJ25hbWUnXSArICc8dGQ+PGI+JyArIGQgKyAnPC9iPjwvdGFibGU+JzsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gNSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4ID0gJyc7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyArPSAnPHVsIGlkPXNjcmlwdFh2YWx1ZV8nICsgaSArICcgc3R5bGU9Imxpc3Qtc3R5bGUtdHlwZTpub25lO2hlaWdodDoxMDBweDtvdmVyZmxvdzphdXRvO3dpZHRoOjEwMCU7Ym9yZGVyOjFweCBzb2xpZCAjMDAwO2JhY2tncm91bmQtY29sb3I6d2hpdGU7b3ZlcmZsb3cteDpoaWRkZW47bWFyZ2luOjA7cGFkZGluZzowIj4nOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIHkgaW4gYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWVzJ10pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHhjID0gJyc7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd2YWx1ZSddLmluZGV4T2YoeSkgPj0gMCkgeGMgPSAnIGNoZWNrZWQnOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjICs9ICc8bGk+PGxhYmVsPjxpbnB1dCB0eXBlPWNoZWNrYm94IGlkPXNjcmlwdFh2YWx1ZXhfJyArIGkgKyAnLScgKyB5ICsgJycgKyB4YyArICc+JyArIGJsb2NrWyd2YXJzJ11baV1bJ3ZhbHVlcyddW3ldICsgJzwvbGFiZWw+PC9saT4nOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjICs9ICc8L3VsPic7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIFBhcmFtZXRlcnM6IERpYWxvZyBNb2RlICgwID0gbm9uZSksIERpYWxvZyBUaXRsZSwgQnV0dG9ucyAoMSA9IE9LLCAyID0gQ2FuY2VsLCAzID0gT0sgJiBDYW5jZWwpLCBDYWxsIGJhY2sgZnVuY3Rpb24oMCA9IENhbmNlbCwgMSA9IE9LKSwgRGlhbG9nIENvbnRlbnQgKE1vZGUgMTEgb25seSkNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsIGJsb2NrLm5hbWUsIGIsIHNjcmlwdF9mb25lZGl0Y2xpY2tFeCwgYywgaCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgd2hlbiB0aGUgc2NyaXB0IGJsb2NrIGVkaXQgZGlhbG9nIGlzIGNsb3NlZC4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmVkaXRjbGlja0V4KGJ1dHRvbiwgdGFnKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBpZiAoYnV0dG9uID09IDIpIHsNCiAgICAgICAgICAgICAgICAvLyBEZWxldGUgdGhpcyBibG9jaw0KICAgICAgICAgICAgICAgIHNjcmlwdF9CbG9ja1NjcmlwdC5zcGxpY2UodGFnLCAxKTsNCiAgICAgICAgICAgICAgICBpZiAoc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9PSB0YWcpIHsgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IG51bGw7IH0NCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gQ2hhbmdlIHRoaXMgYmxvY2sgd2l0aCBuZXcgYXJndW1lbnRzDQogICAgICAgICAgICAgICAgdmFyIGJsb2NrID0gc2NyaXB0X0Jsb2NrU2NyaXB0W3RhZ107DQogICAgICAgICAgICAgICAgaWYgKGJsb2NrWyd2YXJzJ10pIHsNCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBibG9ja1sndmFycyddKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbJ3ZhcnMnXVtpXVsndHlwZSddID09IDUpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBibG9ja1sndmFycyddW2ldWyd2YWx1ZSddID0gW107DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgeSBpbiBibG9ja1sndmFycyddW2ldWyd2YWx1ZXMnXSkgeyBpZiAoUSgnc2NyaXB0WHZhbHVleF8nICsgaSArICctJyArIHkpLmNoZWNrZWQpIGJsb2NrWyd2YXJzJ11baV1bJ3ZhbHVlJ10ucHVzaCh5KTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gNikgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4ID0gUSgnc2NyaXB0WHZhbHVlXycgKyBpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoeC5maWxlcy5sZW5ndGggPT0gMSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKGZpbGUpIHsgYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWUnXSA9IGJ0b2EoZmlsZS50YXJnZXQucmVzdWx0KTsgZnVwZGF0ZXNjcmlwdCgpOyB9Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKHguZmlsZXNbMF0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWUnXSA9IFEoJ3NjcmlwdFh2YWx1ZV8nICsgaSkudmFsdWU7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBTdGFydGluZyB3aXRoIGEgY2hpbGQgZWxlbWVudCwgZ28gdXAgb25lIHBhcmVudCBhdCBhIHRpbWUgdW50aWwgd2UgZmluZCBhbiBlbGVtZW50IHdpdGggYW4gSUQuDQogICAgICAgIGZ1bmN0aW9uIGZnZXRQYXJlbnRXaXRoSWQoeCkgeyB3aGlsZSAoIXguaWQpIHsgeCA9IHgucGFyZW50RWxlbWVudDsgfSByZXR1cm4geDsgfQ0KDQogICAgICAgIC8vIERpc3BsYXlzIHRoZSBsaXN0IG9mIHNjcmlwdCBibG9ja3MgdG8gdGhlIEhUTUwgcGFnZS4gRWFjaCBibG9jayBpcyBkaXNwbGF5ZWQgd2l0aCBpdCdzIG5hbWUsIGF0dHJpYnV0ZXMgYW5kIGFuIGVkaXQgYnV0dG9uLg0KICAgICAgICBmdW5jdGlvbiBmdXBkYXRlc2NyaXB0KCkgew0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gc2NyaXB0X0Jsb2NrU2NyaXB0KSB7DQogICAgICAgICAgICAgICAgeCArPSAnPGRpdiBpZD14YmxvY2tfJyArIGkgKyAnIHN0eWxlPWN1cnNvcjpwb2ludGVyO21pbi1oZWlnaHQ6MjRweDtiYWNrZ3JvdW5kLWNvbG9yOiMnICsgKChzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID09IGkpID8gJ2FhYScgOiAnY2NjJykgKyAnO3dpZHRoOmF1dG87cGFkZGluZzo1cHg7bWFyZ2luOjJweCBkcmFnZ2FibGU9dHJ1ZSBvbmNsaWNrPXNjcmlwdF9mb25jbGljayhldmVudCx0aGlzKSBvbmRyYWdlbnRlcj1zY3JpcHRfZm9uZHJhZ2VudGVyKGV2ZW50LHRoaXMpIG9uZHJhZ2xlYXZlPXNjcmlwdF9mb25kcmFnbGVhdmUoZXZlbnQsdGhpcykgb25kcmFnc3RhcnQ9c2NyaXB0X2ZvbmRyYWdzdGFydChldmVudCx0aGlzKSBvbmRyYWdlbmQ9c2NyaXB0X2ZvbmRyYWdlbmQoZXZlbnQsdGhpcykgb25kcm9wPXNjcmlwdF9mb25kcm9wKGV2ZW50LHRoaXMpIHRpdGxlPSInICsgc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWydkZXNjJ10gKyAnIic7DQogICAgICAgICAgICAgICAgeCArPSAnPjxpbnB1dCBzdHlsZT1mbG9hdDpyaWdodCB0eXBlPWJ1dHRvbiB2YWx1ZT1FZGl0Li4uIG9uY2xpY2s9c2NyaXB0X2ZvbmVkaXRjbGljaygnICsgaSArICcpPjxkaXYgc3R5bGU9Zm9udC1zaXplOjE2cHg+PGI+JyArIHNjcmlwdF9CbG9ja1NjcmlwdFtpXS5uYW1lICsgJzwvYj4nOw0KICAgICAgICAgICAgICAgIGlmIChzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ3ZhcnMnXSkgew0KICAgICAgICAgICAgICAgICAgICB2YXIgciA9IDA7DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjx0YWJsZSBjbGFzcz0nc2NyaXB0QmxvY2tWYXIgdXMnIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6NXB4O21hcmdpbi10b3A6OHB4PiI7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ10pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2ID0gc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ3ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ3R5cGUnXSA9PSA0ICYmIHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsndmFycyddW2pdWyd2YWx1ZSddLmxlbmd0aCA+IDApIHYgPSAiKioqKioiOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsndmFycyddW2pdWyd0eXBlJ10gPT0gMykgdiA9IHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsndmFycyddW2pdWyd2YWx1ZXMnXVtzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ3ZhcnMnXVtqXVsndmFsdWUnXV07DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ3R5cGUnXSA9PSA2KSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsndmFycyddW2pdWyd2YWx1ZSddKSB7IHYgPSAiQmluYXJ5IGZpbGUsICIgKyBzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ3ZhcnMnXVtqXVsndmFsdWUnXS5sZW5ndGggKyAiIGJ5dGVzIjsgfSBlbHNlIHsgdiA9ICJOb3Qgc2V0IjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgeCArPSAiPHRyIHRpdGxlPSciICsgc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ2Rlc2MnXSArICInPjx0ZCB3aWR0aD0yMDBweCBzdHlsZT0nIiArIChyID4gMCA/ICJib3JkZXItdG9wOjFweCBzb2xpZCAjYTgxMGE4IiA6ICIiKSArICInPjxwPiIgKyBzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ3ZhcnMnXVtqXVsnbmFtZSddICsgIjx0ZCBzdHlsZT0nIiArIChyID4gMCA/ICJib3JkZXItdG9wOjFweCBzb2xpZCAjYTgxMGE4IiA6ICIiKSArICInPiIgKyB2Ow0KICAgICAgICAgICAgICAgICAgICAgICAgcisrOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjx0cj48dGQgc3R5bGU9aGVpZ2h0OjNweD48L3RhYmxlPiI7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHggKz0gJzwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoeCA9PSAnJykgeyB4ID0gJzxkaXYgc3R5bGU9InBhZGRpbmc6MTVweDtjb2xvcjpncmF5Ij5TdGFydCB5b3VyIHNjcmlwdCBieSBkcmFnICYgZHJvcHBpbmcgYmxvY2tzIGZyb20gdGhlIGxlZnQgc2lkZSBpbnRvIHRoaXMgc2NyaXB0aW5nIGJveC48ZGl2Pic7IH0NCiAgICAgICAgICAgIFFIKCdzY3JpcHRibG9ja3MnLCB4ICsgIjxkaXYgc3R5bGU9aGVpZ2h0OjgwcHg+PC9kaXY+Iik7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHNjcmlwdF9CbG9ja1NjcmlwdCkgeyBRUygneGJsb2NrXycgKyBpKS5ib3JkZXJMZWZ0ID0gKHNjcmlwdF9DdXJyZW50SGlnaGxpZ2h0QmxvY2sgPT0gaSkgPyAiM3B4IHNvbGlkIGJsYWNrIiA6ICIiOyB9DQogICAgICAgICAgICBzY3JpcHRfYmxvY2tzVG9TY3JpcHQoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENvbnZlcnQgdGhlIGxpc3Qgb2YgYmxvY2tzIGludG8gYSBzY3JpcHQgdGhhdCBjYW4gYmUgY29tcGlsZWQNCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2Jsb2Nrc1RvU2NyaXB0KCkgew0KICAgICAgICAgICAgdmFyIHNjcmlwdCA9ICcnOw0KICAgICAgICAgICAgaWYgKHNjcmlwdF9CdWlsZGluZ0Jsb2Nrcykgew0KICAgICAgICAgICAgICAgIGlmIChzY3JpcHRfQnVpbGRpbmdCbG9ja3NbJ19zdGFydCddKSB7IHNjcmlwdCArPSAnIyMjIyMgU3RhcnRpbmcgQmxvY2sgIyMjIyNcclxuJyArIHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1snX3N0YXJ0J11bJ2NvZGUnXSArICdcclxuXHJcbic7IH0NCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHNjcmlwdF9CbG9ja1NjcmlwdCkgew0KICAgICAgICAgICAgICAgICAgICB2YXIgY29kZSA9IHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsnY29kZSddOw0KICAgICAgICAgICAgICAgICAgICBjb2RlID0gY29kZS5zcGxpdCgiJSUlfiUlJSIpLmpvaW4oaSk7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ10pIHsgY29kZSA9IGNvZGUuc3BsaXQoIiUlJSIgKyBqICsgIiUlJSIpLmpvaW4oc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ3ZhbHVlJ10pOyB9DQogICAgICAgICAgICAgICAgICAgIHNjcmlwdCArPSAnIyMjIyMgQmxvY2s6ICcgKyBzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ25hbWUnXSArICcgIyMjIyNcclxuSGlnaGxpZ2h0QmxvY2sgX190ICcgKyBpICsgJ1xyXG4nICsgY29kZSArICdcclxuXHJcbic7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmIChzY3JpcHRfQnVpbGRpbmdCbG9ja3NbJ19lbmQnXSkgeyBzY3JpcHQgKz0gJyMjIyMjIEVuZGluZyBCbG9jayAjIyMjI1xyXG4nICsgc2NyaXB0X0J1aWxkaW5nQmxvY2tzWydfZW5kJ11bJ2NvZGUnXSArICdcclxuSGlnaGxpZ2h0QmxvY2tcclxuJzsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgUSgnc2NyaXB0YXJlYScpLnZhbHVlID0gc2NyaXB0Ow0KICAgICAgICB9DQoNCiAgICAgICAgLy8gSGlnaGxpZ2h0IGEgc2NyaXB0IGJsb2NrLiBUaGlzIGlzIHVzZWZ1bCB0byBrbm93IHdoYXQgYmxvY2sgdGhlIHNjcmlwdCBpcyBjdXJyZW50bHkgcnVubmluZw0KICAgICAgICB2YXIgc2NyaXB0X0N1cnJlbnRIaWdobGlnaHRCbG9jazsNCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X0hpZ2hsaWdodEJsb2NrKHJ1bm5lciwgeCkgew0KICAgICAgICAgICAgaWYgKHJ1bm5lciA9PSBlZGl0c2NyaXB0c3RhdGUpIHsgLy8gT25seSBoaWdobGlnaHQgYmxvY2tzIGlmIHRoZSBzY3JwdCBlZGl0b3IgaXMgcnVubmluZyB0aGUgc2NyaXB0LiBJZiBydW5uaW5nIGEgc2NyaXB0IG9uIHRoZSBwYWdlLCBkb24ndCBoaWdobGlnaHQgYmxvY2tzIGluIHRoZSBlZGl0b3IuDQogICAgICAgICAgICAgICAgc2NyaXB0X0N1cnJlbnRIaWdobGlnaHRCbG9jayA9IHg7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBzY3JpcHRfQmxvY2tTY3JpcHQpIHsgUVMoJ3hibG9ja18nICsgaSkuYm9yZGVyTGVmdCA9IChzY3JpcHRfQ3VycmVudEhpZ2hsaWdodEJsb2NrID09IGkpID8gIjNweCBzb2xpZCBibGFjayIgOiAiIjsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ2FsbGVkIGJ5IHRoZSAiTmV3Li4uIiBidXR0b24gdG8gcmVzZXQgdGhlIHNjcmlwdCBlZGl0b3IgdG8gdGhlIHN0YXJ0DQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9uZXdTY3JpcHREbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiTmV3IFNjcmlwdCIsIDMsIHNjcmlwdF9uZXdTY3JpcHREbGdPaywgIjxicj5SZXNldCAmIGNsZWFyIHRoZSBzY3JpcHQgZWRpdG9yPyIpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ2xlYXIgdGhlIHNjcmlwdCBlZGl0b3INCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X25ld1NjcmlwdERsZ09rKCkgew0KICAgICAgICAgICAgc2NyaXB0X3NldEJ1aWxkQmxvY2tzKHNjcmlwdF9TdGFydGluZ0J1aWxkaW5nQmxvY2tzKTsNCiAgICAgICAgICAgIHNjcmlwdF9CbG9ja1NjcmlwdCA9IFtdOw0KICAgICAgICAgICAgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IG51bGw7DQogICAgICAgICAgICBkZWxldGUgZWRpdHNjcmlwdHN0YXRlOw0KICAgICAgICAgICAgc2NyaXB0Vmlld0J1dHRvbihzY3JpcHRfQnVpbGRpbmdCbG9ja3M/MTowKTsNCiAgICAgICAgICAgIFFIKCd2YXJpYWJsZXMnLCAnJyk7DQogICAgICAgICAgICBRKCdzY3JpcHRhcmVhJykudmFsdWUgPSAnJzsNCiAgICAgICAgICAgIHJlc2V0U2NyaXB0QnV0dG9uKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDb21waWxlIGFuZCByZXNldCBhIHNjcmlwdCB0byB0aGUgc3RhcnRpbmcgcG9zaXRpb24NCiAgICAgICAgZnVuY3Rpb24gcmVzZXRTY3JpcHRCdXR0b24oKSB7DQogICAgICAgICAgICAvLyBDb21waWxlIHRoZSBzY3JpcHQNCiAgICAgICAgICAgIGJyZWFrU2NyaXB0QnV0dG9uKCk7DQogICAgICAgICAgICBRKCdjb21waWxlZGFyZWEnKS52YWx1ZSA9IHJzdHIyaGV4KHNjcmlwdF9jb21waWxlKFEoJ3NjcmlwdGFyZWEnKS52YWx1ZSwgZnVuY3Rpb24obSkgeyBtZXNzYWdlYm94KCJTY3JpcHQgQ29tcGlsZSBFcnJvciIsIG0pOyB9KSk7DQogICAgICAgICAgICBkZWxldGUgZWRpdHNjcmlwdHN0YXRlOw0KDQogICAgICAgICAgICAvLyBSZXNldCB0aGUgc2NyaXB0IGVudmlyb25tZW50DQogICAgICAgICAgICBRKCdjb25zb2xlJykudmFsdWUgPSAnJzsNCiAgICAgICAgICAgIFFIKCd2YXJpYWJsZXMnLCAnJyk7DQogICAgICAgICAgICBRSCgnRWRpdFNjcmlwdFN0YXR1cycsICdTdG9wcGVkJyk7DQogICAgICAgICAgICBpZiAoc2NyaXB0X0J1aWxkZXJWaWV3ID09IDEpIHsgZnVwZGF0ZXNjcmlwdCgpOyB9DQogICAgICAgICAgICBpZiAoUSgnY29tcGlsZWRhcmVhJykudmFsdWUubGVuZ3RoID09IDApIHJldHVybjsNCg0KICAgICAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IHNjcmlwdCBydW50aW1lIG9iamVjdA0KICAgICAgICAgICAgdmFyIHN0YXJ0dmFycyA9IHsgJ19pbnRlcmFjdGl2ZSc6MSB9Ow0KDQogICAgICAgICAgICBzdGFydHZhcnNbJ19jZXJ0aWZpY2F0ZXMnXSA9IDE7DQoNCiAgICAgICAgICAgIHN0YXJ0dmFyc1snX21vZGUnXSA9ICdGaXJtd2FyZSc7DQoNCiAgICAgICAgICAgIHN0YXJ0dmFyc1snX21vZGUnXSA9ICdNZXNoQ2VudHJhbDInOw0KDQogICAgICAgICAgICBzdGFydHZhcnNbJ19tb2RlJ10gPSAnTE1TJzsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRzdGF0ZSA9IHNjcmlwdF9zZXR1cChoZXgycnN0cihRKCdjb21waWxlZGFyZWEnKS52YWx1ZSksIHN0YXJ0dmFycyk7DQogICAgICAgICAgICBlZGl0c2NyaXB0c3RhdGUud3NzdGFjayA9IHdzc3RhY2s7DQogICAgICAgICAgICBlZGl0c2NyaXB0c3RhdGUuYW10c3RhY2sgPSBhbXRzdGFjazsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRzdGF0ZS5vblN0ZXAgPSBlZGl0c2NyaXB0X3VwZGF0ZVNjcmlwdFN0YXRlOw0KICAgICAgICAgICAgZWRpdHNjcmlwdHN0YXRlLm9uQ29uc29sZSA9IGVkaXRzY3JpcHRfY29uc29sZTsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRfdXBkYXRlU2NyaXB0U3RhdGUoZWRpdHNjcmlwdHN0YXRlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIFN0YXJ0IHJ1bm5pbmcgdGhlIHNjcmlwdA0KICAgICAgICBmdW5jdGlvbiBydW5TY3JpcHRCdXR0b24oKSB7DQogICAgICAgICAgICBpZiAoZWRpdHNjcmlwdHN0YXRlID09IG51bGwpIHJlc2V0U2NyaXB0QnV0dG9uKCk7DQogICAgICAgICAgICBpZiAoZWRpdHNjcmlwdHN0YXRlID09IG51bGwpIHJldHVybjsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRzdGF0ZS5zdGFydCgxMDApOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gU3RvcC9QYXVzZSB0aGUgc2NyaXB0DQogICAgICAgIGZ1bmN0aW9uIGJyZWFrU2NyaXB0QnV0dG9uKCkgew0KICAgICAgICAgICAgaWYgKGVkaXRzY3JpcHRzdGF0ZSA9PSBudWxsKSByZXR1cm47DQogICAgICAgICAgICBlZGl0c2NyaXB0c3RhdGUuc3RvcCgpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gUnVuIG9uZSBzdGVwIG9mIHRoZSBzY3JpcHQNCiAgICAgICAgZnVuY3Rpb24gc3RlcFNjcmlwdEJ1dHRvbigpIHsNCiAgICAgICAgICAgIGlmIChlZGl0c2NyaXB0c3RhdGUgPT0gbnVsbCkgcmVzZXRTY3JpcHRCdXR0b24oKTsNCiAgICAgICAgICAgIGlmIChlZGl0c2NyaXB0c3RhdGUgPT0gbnVsbCkgcmV0dXJuOw0KICAgICAgICAgICAgYnJlYWtTY3JpcHRCdXR0b24oKTsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRzdGF0ZS5zdGVwKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBEaXNwbGF5IGEgbmV3IGxpbmUgaW50byB0aGUgc2NyaXB0IGNvbnNvbGUNCiAgICAgICAgZnVuY3Rpb24gZWRpdHNjcmlwdF9jb25zb2xlKG1zZykgew0KICAgICAgICAgICAgUSgnY29uc29sZScpLnZhbHVlICs9IChtc2cgKyAnXG4nKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIFVwZGF0ZSB0aGUgc2NyaXB0IHN0YXRlIGluZm9ybWF0aW9uIGFuZCBkaXNwbGF5ZWQgdmFyaWFibGVzDQogICAgICAgIHZhciBzY3JpcHRfc3RhdGVzID0gWydTdG9wcGVkJywgJ1J1bm5pbmcnLCAnUGF1c2VkJ107DQogICAgICAgIGZ1bmN0aW9uIGVkaXRzY3JpcHRfdXBkYXRlU2NyaXB0U3RhdGUocnVuc3RhdGUpIHsNCiAgICAgICAgICAgIC8vIFVwZGF0ZSB2YXJpYWJsZXMNCiAgICAgICAgICAgIHZhciByID0gJyc7DQogICAgICAgICAgICBpZiAocnVuc3RhdGUgJiYgcnVuc3RhdGUgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgIHZhciB2cyA9IFtdOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gcnVuc3RhdGUudmFyaWFibGVzKSB7IGlmICghaS5zdGFydHNXaXRoKCdfXycpKSB2cy5wdXNoKGkpOyB9DQogICAgICAgICAgICAgICAgdnMuc29ydCgpOw0KICAgICAgICAgICAgICAgIC8vZm9yICh2YXIgaSBpbiB2cykgeyByICs9IHZzW2ldICsgIiA9ICIgKyBzY3JpcHRfdG9TdHJpbmcocnVuc3RhdGUudmFyaWFibGVzW3ZzW2ldXSkgKyAiXG4iOyB9DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB2cykgew0KICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJ1bnN0YXRlLnZhcmlhYmxlc1t2c1tpXV0gPT0gJ29iamVjdCcpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHIgKz0gIjxiPiIgKyB2c1tpXSArICI8L2I+ID0gIiArIE9iamVjdFRvU3RyaW5nRXgocnVuc3RhdGUudmFyaWFibGVzW3ZzW2ldXSwgMikgKyAiPGJyPiI7DQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICByICs9ICI8Yj4iICsgdnNbaV0gKyAiPC9iPiA9ICIgKyBFc2NhcGVIdG1sKHNjcmlwdF90b1N0cmluZyhydW5zdGF0ZS52YXJpYWJsZXNbdnNbaV1dKSkgKyAiPGJyPiI7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBRSCgndmFyaWFibGVzJywgcik7DQoNCiAgICAgICAgICAgIC8vIFVwZGF0ZSBzdGF0ZQ0KICAgICAgICAgICAgciA9ICdTdG9wcGVkLCBObyBTY3JpcHQnOw0KICAgICAgICAgICAgaWYgKHJ1bnN0YXRlICYmIHJ1bnN0YXRlICE9IG51bGwpIHsgciA9IHNjcmlwdF9zdGF0ZXNbcnVuc3RhdGUuc3RhdGVdOyBpZiAocnVuc3RhdGUuc3RhdGUgPiAwKSByICs9ICIsICIgKyBydW5zdGF0ZS5pcCArICIgOiAiICsgc2NyaXB0X2RlY29tcGlsZShydW5zdGF0ZS5zY3JpcHQsIHJ1bnN0YXRlLmlwKTsgfQ0KICAgICAgICAgICAgaWYgKHIubGVuZ3RoID4gNTApIHsgciA9IHIuc3Vic3RyaW5nKDAsIDUwKSArICIuLi4iOyB9DQogICAgICAgICAgICBRSCgnRWRpdFNjcmlwdFN0YXR1cycsIHIpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gUmV0dXJuIGEgc3RyaW5nIGZyb20gYW55IGlucHV0LCBpZiB0aGUgaW5wdXQgaXMgYW4gb2JqZWN0LCBzdHJpbmdpZnkgaXQuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF90b1N0cmluZyh4KSB7IGlmICh0eXBlb2YgeCA9PSAnb2JqZWN0JykgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHgpOyByZXR1cm4geDsgfQ0KDQoNCiAgICAgICAgLy8gU2F2ZSBhIHNjcmlwdCB0byBkaXNrLCBzdGFydCBieSBzaG93aW5nIGEgZGlhbG9nIGJveCB0byBwcm9tcHQgdG8gdGhlIGZpbGVuYW1lLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfc2F2ZVNjcmlwdChlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8IHNjcmlwdHN0YXRlKSByZXR1cm47DQogICAgICAgICAgICBpZiAoZSAmJiAoZS5zaGlmdEtleSA9PSB0cnVlKSkgew0KICAgICAgICAgICAgICAgIC8vIFNhdmUgYXMgc2NyaXB0IGJsb2NrDQogICAgICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIlNjcmlwdCBCbG9jayIsIDEsIG51bGwsICI8YnI+PHRleHRhcmVhIGlkPXNjcmlwdFNhdmVTY3JpcHRKc29uQmxvY2sgc3R5bGU9d2lkdGg6MTAwJTtoZWlnaHQ6MjAwcHg7cmVzaXplOnZlcnRpY2FsIC8+Iik7DQogICAgICAgICAgICAgICAgUUgoJ3NjcmlwdFNhdmVTY3JpcHRKc29uQmxvY2snLCBzY3JpcHRfZkNvbnZlcnRTY3JpcHRUb0pzb25CbG9jayhRKCdzY3JpcHRhcmVhJykudmFsdWUpKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gU2F2ZSBhcyAubWVzY3JpcHQgZmlsZQ0KDQogICAgICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIlNhdmUgU2NyaXB0IiwgMywgc2NyaXB0X3NhdmVTY3JpcHRPaywgIjxicj48aW5wdXQgaWQ9c2NyaXB0c2F2ZW5hbWUgc3R5bGU9d2lkdGg6MTAwJSB2YWx1ZT10ZXN0Lm1lc2NyaXB0ID4iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIE9uY2UgdGhlIGZpbGVuYW1lIGlzIHNlbGVjdGVkLCBzYXZlIHRoZSBmaWxlLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfc2F2ZVNjcmlwdE9rKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSBKU09OLnN0cmluZ2lmeSh7DQogICAgICAgICAgICAgICAgInNjcmlwdFRleHQiOiBRKCdzY3JpcHRhcmVhJykudmFsdWUsDQogICAgICAgICAgICAgICAgIm1lc2NyaXB0IjogYnRvYShzY3JpcHRfY29tcGlsZShRKCdzY3JpcHRhcmVhJykudmFsdWUpKSwNCiAgICAgICAgICAgICAgICAiYmxvY2tzIjogc2NyaXB0X1N0YXJ0aW5nQnVpbGRpbmdCbG9ja3MsDQogICAgICAgICAgICAgICAgInNjcmlwdEJsb2NrcyI6IHNjcmlwdF9CbG9ja1NjcmlwdA0KICAgICAgICAgICAgfSwgbnVsbCwgJyAgJyk7DQogICAgICAgICAgICBzYXZlQXMoZGF0YTJibG9iKHgpLCBRKCdzY3JpcHRzYXZlbmFtZScpLnZhbHVlKTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgDQoNCg0KICAgICAgICAvLw0KICAgICAgICAvLyBVU0IgU0VUVVAuQklODQogICAgICAgIC8vDQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX25ld1NldHVwQmluKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgaWR4X2QxNHZlcnNpb24udmFsdWUgPSA0Ow0KICAgICAgICAgICAgaWR4X2QxNGNvbnN1bWUudmFsdWUgPSAxOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxNCwgIkNyZWF0ZSBuZXcgU2V0dXAuYmluIGZpbGUiLCAzLCB1c2JfbmV3U2V0dXBCaW5Payk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2JfbmV3U2V0dXBCaW5PayhyKSB7DQogICAgICAgICAgICBpZiAociA9PSAxKSB7IHNldHVwYmluID0gQW10U2V0dXBCaW5DcmVhdGUoaWR4X2QxNHZlcnNpb24udmFsdWUsIGlkeF9kMTRjb25zdW1lLnZhbHVlKTsgfSAvLyBPSyBCdXR0b24NCiAgICAgICAgICAgIHVzYl9kaXNwbGF5U2V0dXBCaW4oKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9vcGVuU2V0dXBCaW4oKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQoNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTUsICJPcGVuIFNldHVwLmJpbiBmaWxlIiwgMywgdXNiX29wZW5TZXR1cEJpbk9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9vcGVuU2V0dXBCaW5PaygpIHsNCiAgICAgICAgICAgIHZhciB4ID0gUSgnZDE1c2V0dXBiaW5maWxlJyk7DQogICAgICAgICAgICBpZiAoeC5maWxlcy5sZW5ndGggIT0gMSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQogICAgICAgICAgICByZWFkZXIub25sb2FkID0gdXNiX29uU2V0dXBCaW5SZWFkOw0KICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyh4LmZpbGVzWzBdKTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX3NhdmVTZXR1cEJpbigpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgIXNldHVwYmluKSByZXR1cm47DQoNCiAgICAgICAgICAgIHNhdmVBcyhkYXRhMmJsb2IoQW10U2V0dXBCaW5FbmNvZGUoc2V0dXBiaW4pKSwgInNldHVwLmJpbiIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX29uU2V0dXBCaW5SZWFkKGZpbGUpIHsNCiAgICAgICAgICAgIHNldHVwYmluID0gQW10U2V0dXBCaW5EZWNvZGUoZmlsZS50YXJnZXQucmVzdWx0KTsNCiAgICAgICAgICAgIGlmICghc2V0dXBiaW4pIHsgbWVzc2FnZWJveCgiT3BlbiBGaWxlIiwgIkludmFsaWQgb3IgY29ycnVwdCBzZXR1cC5iaW4gZmlsZS4gVW5hYmxlIHRvIG9wZW4uIik7IH0gZWxzZSB7IHVzYl9kaXNwbGF5U2V0dXBCaW4oKTsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2Rpc3BsYXlTZXR1cEJpbigpIHsNCiAgICAgICAgICAgIFFWKCdpZF9TdGFydHVwU2NyZWVuJywgIXNldHVwYmluKTsNCg0KICAgICAgICAgICAgUVYoJ2lkX3NhdmVTZXR1cEJpbicsIHNldHVwYmluKTsNCiAgICAgICAgICAgIGlmICghc2V0dXBiaW4pIHsgcmV0dXJuIFFIKCdpZF9TZXR1cEJpbkFyZWEnLCAnJyk7IH0NCiAgICAgICAgICAgIA0KICAgICAgICAgICAgLy8gVXBkYXRlIHJlY29yZCBjb3VudA0KICAgICAgICAgICAgdmFyIGNvbnN1bWVkID0gMDsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gc2V0dXBiaW4ucmVjb3JkcykgeyBpZiAoKHNldHVwYmluLnJlY29yZHNbaV0uZmxhZ3MgJiAxKSA9PSAwKSB7IGNvbnN1bWVkKys7IH0gfQ0KICAgICAgICAgICAgc2V0dXBiaW4uZGF0YVJlY29yZHNDb25zdW1lZCA9IGNvbnN1bWVkOw0KDQogICAgICAgICAgICAvLyBNYWluIEhlYWRlciAgICAgICAgICAgIA0KICAgICAgICAgICAgdmFyIHggPSAiPHRhYmxlIG9uY2xpY2s9dXNiX2VkaXRoZWFkZXIoZXZlbnQpIGNsYXNzPSdsb2cxIHVzJyBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjhweDtjdXJzb3I6cG9pbnRlcj48dHI+PHRkPjxwPjx0ZD4iOw0KICAgICAgICAgICAgeCArPSAiPHRyPjx0ZCBjbGFzcz1yMiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1mbG9hdDpyaWdodDttYXJnaW4tcmlnaHQ6MTJweCBvbmNsaWNrPXVzYl9hZGRSZWNvcmRTZXR1cEJpbigpPjxhPjx1IHRpdGxlPSdBZGQgYSBuZXcgcmVjb3JkJz5BZGQgUmVjb3JkPC91PjwvYT48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdj48c3Ryb25nPkludGVsJnJlZzsgQU1UIFNldHVwLmJpbiBmaWxlIHZlcnNpb24gIiArIHNldHVwYmluLm1ham9yVmVyc2lvbiArICIuIiArIHNldHVwYmluLm1pbm9yVmVyc2lvbiArICI8L3N0cm9uZz4uPC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gKCgoc2V0dXBiaW4uZmxhZ3MgJiAxKSA9PSAwKSA/ICJSZWNvcmRzIHdpbGwgYmUgY29uc3VtZWQuIiA6ICJSZWNvcmRzIHdpbGwgbm90IGJlIGNvbnN1bWVkLiIpOw0KICAgICAgICAgICAgeCArPSAiPGJyPlJlY29yZHM6ICIgKyBzZXR1cGJpbi5yZWNvcmRzLmxlbmd0aCArICIsIENvbnN1bWVkOiAiICsgc2V0dXBiaW4uZGF0YVJlY29yZHNDb25zdW1lZCArICI8YnI+IjsNCiAgICAgICAgICAgIHggKz0gIjx0ciBzdHlsZT1oZWlnaHQ6NHB4PjwvdGFibGU+IjsNCg0KICAgICAgICAgICAgLy8gRGlzcGxheSBlYWNoIHJlY29yZA0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBzZXR1cGJpbi5yZWNvcmRzKSB7DQogICAgICAgICAgICAgICAgdmFyIHJlYyA9IHNldHVwYmluLnJlY29yZHNbaV07DQogICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6NHB4PjwvZGl2Pjx0YWJsZSBjbGFzcz0nbG9nMSB1cycgY2VsbHBhZGRpbmc9MCBjZWxsc3BhY2luZz0wIHN0eWxlPXdpZHRoOjEwMCU7Ym9yZGVyLXJhZGl1czo4cHg+PHRyPjx0ZD48cD48dGQ+PHRyPjx0ZCBjbGFzcz1yMiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweDtjdXJzb3I6cG9pbnRlcj4iOw0KICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ7bWFyZ2luLXJpZ2h0OjEycHggb25jbGljaz0ndXNiX2FkZHZhcmlhYmxlKGV2ZW50LCIgKyBpICsgIiknPjxhPjx1IHRpdGxlPSdBZGQgYSBuZXcgdmFyaWFibGUnPkFkZCBWYXJpYWJsZTwvdT48L2E+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IG9uY2xpY2s9J3VzYl9lZGl0cmVjb3JkKGV2ZW50LCAiICsgaSArICIpJz5SZWNvcmQgIzxzdHJvbmc+IiArICgraSArIDEpICsgIjwvc3Ryb25nPi4gVGhpcyByZWNvcmQgaXM6IDxzdHJvbmc+IiArICgocmVjLmZsYWdzICYgMSkgPyAiVmFsaWQiIDogIkNvbnN1bWVkIikgKyAoKHJlYy5mbGFncyAmIDIpID8gIiwgU2NyYW1ibGVkIiA6ICIiKSArICI8L3N0cm9uZz48L2Rpdj4iOw0KDQogICAgICAgICAgICAgICAgLy8gRGlzcGxheSBlYWNoIHZhcmlhYmxlDQogICAgICAgICAgICAgICAgZm9yICh2YXIgaiBpbiByZWMudmFyaWFibGVzKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciB2ID0gcmVjLnZhcmlhYmxlc1tqXSwgdmFsID0gdi52YWx1ZTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdWzJdICYmIEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdWzJdW3ZhbF0pIHsgdmFsID0gQW10U2V0dXBCaW5WYXJJZHNbdi5tb2R1bGVpZF1bdi52YXJpZF1bMl1bdmFsXTsgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAodi5tb2R1bGVpZCA9PSAyICYmIHYudmFyaWQgPT0gOCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2h0eXBlID0gdmFsLmNoYXJDb2RlQXQoMCk7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzaHR5cGUgPj0gMCAmJiBoYXNodHlwZSA8PSAzKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2hzaXplID0gWzIwLCAzMiwgNDhdW2hhc2h0eXBlIC0gMV07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2ggPSByc3RyMmhleCh2YWwuc3Vic3RyaW5nKDEsIGhhc2hzaXplICsgMSkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYXNobmFtZXNpemUgPSB2YWwuY2hhckNvZGVBdCgxICsgaGFzaHNpemUpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYXNobmFtZSA9IHZhbC5zdWJzdHJpbmcoMiArIGhhc2hzaXplLCAyICsgaGFzaHNpemUgKyBoYXNobmFtZXNpemUpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsID0gWydTSEExJywgJ1NIQTI1NicsICdTSEEzODQnXVtoYXNodHlwZSAtIDFdICsgJywgJyArIGhhc2huYW1lICsgJywgJyArIGhhc2g7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1tYXJnaW4tcmlnaHQ6MTJweD48dGFibGUgb25jbGljaz0ndXNiX2VkaXR2YXJpYWJsZShldmVudCwgIiArIGkgKyAiLCIgKyBqICsgIiknIGNsYXNzPSdpdGVtQmFyIHVzJyBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjRweDttYXJnaW4tdG9wOjJweDttYXJnaW4tYm90dG9tOjJweDtwYWRkaW5nOjA+PHRyPjx0ZD48cCBzdHlsZT1mbG9hdDpyaWdodDttYXJnaW4tcmlnaHQ6OHB4PjxiPiIgKyB2YWwgKyAiPC9iPjxwPiIgKyB2WydkZXNjJ10gKyAiPHRyIHN0eWxlPWhlaWdodDo0cHg+PC90YWJsZT48L2Rpdj4iOw0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIHggKz0gIjx0ciBzdHlsZT1oZWlnaHQ6NHB4PjwvdGFibGU+IjsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgUUgoJ2lkX1NldHVwQmluQXJlYScsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2FkZFJlY29yZFNldHVwQmluKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgZDEzdmFsaWQuY2hlY2tlZCA9IDE7DQogICAgICAgICAgICBkMTNzY3JhbWJsZS5jaGVja2VkID0gMDsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTMsICJOZXcgUmVjb3JkICMiLCAzLCB1c2JfYWRkUmVjb3JkU2V0dXBCaW5Payk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2JfYWRkUmVjb3JkU2V0dXBCaW5PaygpIHsNCiAgICAgICAgICAgIHZhciByID0ge307DQogICAgICAgICAgICByLnR5cGVJZGVudGlmaWVyID0gMTsNCiAgICAgICAgICAgIHIuZmxhZ3MgPSAoZDEzdmFsaWQuY2hlY2tlZCA/IDEgOiAwKSArIChkMTNzY3JhbWJsZS5jaGVja2VkID8gMiA6IDApOw0KICAgICAgICAgICAgci5jaHVua0NvdW50ID0gMDsNCiAgICAgICAgICAgIHIuaGVhZGVyQnl0ZUNvdW50ID0gMDsNCiAgICAgICAgICAgIHIubnVtYmVyID0gMDsNCiAgICAgICAgICAgIHIudmFyaWFibGVzID0gW107DQogICAgICAgICAgICBzZXR1cGJpbi5yZWNvcmRzLnB1c2gocik7DQogICAgICAgICAgICB1c2JfZGlzcGxheVNldHVwQmluKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2JfZWRpdGhlYWRlcihlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQogICAgICAgICAgICBpZHhfZDE0dmVyc2lvbi52YWx1ZSA9IHNldHVwYmluLm1ham9yVmVyc2lvbjsNCiAgICAgICAgICAgIGlkeF9kMTRjb25zdW1lLnZhbHVlID0gKHNldHVwYmluLmZsYWdzICYgMSk7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDE0LCAiRWRpdCBIZWFkZXIiLCA3LCB1c2JfZWRpdGhlYWRlcm9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9lZGl0aGVhZGVyb2socikgew0KICAgICAgICAgICAgaWYgKHIgPT0gMikgew0KICAgICAgICAgICAgICAgIGRlbGV0ZSBzZXR1cGJpbjsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgc2V0dXBiaW4ubWFqb3JWZXJzaW9uID0gaWR4X2QxNHZlcnNpb24udmFsdWU7DQogICAgICAgICAgICAgICAgc2V0dXBiaW4uZmxhZ3MgPSBpZHhfZDE0Y29uc3VtZS52YWx1ZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHVzYl9kaXNwbGF5U2V0dXBCaW4oKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9lZGl0cmVjb3JkKGUsIGkpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHNlbGVjdGVkUmVjb3JkID0gaTsNCiAgICAgICAgICAgIHNlbGVjdGVkVmFyaWFibGUgPSAtMTsNCiAgICAgICAgICAgIGhhbHRFdmVudChlKTsNCiAgICAgICAgICAgIGQxM3ZhbGlkLmNoZWNrZWQgPSAoc2V0dXBiaW4ucmVjb3Jkc1tzZWxlY3RlZFJlY29yZF0uZmxhZ3MgJiAxKTsNCiAgICAgICAgICAgIGQxM3NjcmFtYmxlLmNoZWNrZWQgPSAoc2V0dXBiaW4ucmVjb3Jkc1tzZWxlY3RlZFJlY29yZF0uZmxhZ3MgJiAyKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTMsICJFZGl0IFJlY29yZCAjIiArIChpICsgMSksIDcsIHVzYl9lZGl0cmVjb3Jkb2spOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2VkaXRyZWNvcmRvayhyKSB7DQogICAgICAgICAgICBpZiAociA9PSAxKSB7IHNldHVwYmluLnJlY29yZHNbc2VsZWN0ZWRSZWNvcmRdLmZsYWdzID0gKGQxM3ZhbGlkLmNoZWNrZWQgPyAxIDogMCkgKyAoZDEzc2NyYW1ibGUuY2hlY2tlZCA/IDIgOiAwKTsgfSAvLyBFZGl0IFJlY29yZA0KICAgICAgICAgICAgaWYgKHIgPT0gMikgeyBzZXR1cGJpbi5yZWNvcmRzLnNwbGljZShzZWxlY3RlZFJlY29yZCwgMSk7IH0gLy8gRGVsZXRlIFJlY29yZA0KICAgICAgICAgICAgdXNiX2Rpc3BsYXlTZXR1cEJpbigpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2VkaXR2YXJpYWJsZShlLCBpLCBqKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBzZWxlY3RlZFJlY29yZCA9IGk7DQogICAgICAgICAgICBzZWxlY3RlZFZhcmlhYmxlID0gajsNCiAgICAgICAgICAgIHZhciBtb2RpZCA9IHNldHVwYmluLnJlY29yZHNbaV0udmFyaWFibGVzW2pdLm1vZHVsZWlkOw0KICAgICAgICAgICAgdmFyIHZhcmlkID0gc2V0dXBiaW4ucmVjb3Jkc1tpXS52YXJpYWJsZXNbal0udmFyaWQ7DQogICAgICAgICAgICBkMTZ0eXBlLnZhbHVlID0gbW9kaWQgKyAiLSIgKyB2YXJpZDsNCiAgICAgICAgICAgIGQxNnR5cGUuZGlzYWJsZWQgPSB0cnVlOw0KICAgICAgICAgICAgdXNiX29uZDE2dHlwZWNoYW5nZSgpOw0KICAgICAgICAgICAgUVYoJ2QxNmdlbmVyaWN2YWx1ZScsIGZhbHNlKTsNCiAgICAgICAgICAgIFFWKCdkMTZjdXN0b212YWx1ZScsIGZhbHNlKTsNCiAgICAgICAgICAgIGlmIChtb2RpZCA9PSAyICYmIHZhcmlkID09IDgpIHsNCiAgICAgICAgICAgICAgICB2YXIgeCA9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9aWR4X2QxNnZhbGMxIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG9uY2hhbmdlPXVzYl9vbmQxNmNoZWNraGFzaCgpPjxvcHRpb24gdmFsdWU9MT5TSEExPC9vcHRpb24+JzsNCiAgICAgICAgICAgICAgICBpZiAoc2V0dXBiaW4ubWFqb3JWZXJzaW9uID49IDMpIHsgeCArPSAnPG9wdGlvbiB2YWx1ZT0yPlNIQTI1Njwvb3B0aW9uPjxvcHRpb24gdmFsdWU9Mz5TSEEzODQ8L29wdGlvbj4nOyB9DQogICAgICAgICAgICAgICAgeCArPSAnPC9zZWxlY3Q+PGRpdj5IYXNoIFR5cGU8L2Rpdj48L2Rpdj4nOw0KICAgICAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWlkeF9kMTZ2YWxjMiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjBweCBvbmtleXVwPXVzYl9vbmQxNmNoZWNraGFzaCgpPjxkaXY+SGFzaCAoSEVYKTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICAgICAgeCArPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48aW5wdXQgaWQ9aWR4X2QxNnZhbGMzIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG9ua2V5dXA9dXNiX29uZDE2Y2hlY2toYXNoKCkgbWF4bGVuZ3RoPTMxPjxkaXY+SGFzaCBOYW1lPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgICAgICBRSCgnZDE2Y3VzdG9tdmFsdWUnLCB4KTsNCiAgICAgICAgICAgICAgICBRVignZDE2Y3VzdG9tdmFsdWUnLCB0cnVlKTsNCiAgICAgICAgICAgICAgICB2YXIgdmFsID0gc2V0dXBiaW4ucmVjb3Jkc1tpXS52YXJpYWJsZXNbal0udmFsdWU7DQogICAgICAgICAgICAgICAgdmFyIGhhc2h0eXBlID0gdmFsLmNoYXJDb2RlQXQoMCk7DQogICAgICAgICAgICAgICAgaWYgKGhhc2h0eXBlID49IDAgJiYgaGFzaHR5cGUgPD0gMykgew0KICAgICAgICAgICAgICAgICAgICB2YXIgaGFzaHNpemUgPSBbMjAsIDMyLCA0OF1baGFzaHR5cGUgLSAxXTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2ggPSByc3RyMmhleCh2YWwuc3Vic3RyaW5nKDEsIGhhc2hzaXplICsgMSkpOw0KICAgICAgICAgICAgICAgICAgICB2YXIgaGFzaG5hbWVzaXplID0gdmFsLmNoYXJDb2RlQXQoMSArIGhhc2hzaXplKTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2huYW1lID0gdmFsLnN1YnN0cmluZygyICsgaGFzaHNpemUsIDIgKyBoYXNoc2l6ZSArIGhhc2huYW1lc2l6ZSkNCiAgICAgICAgICAgICAgICAgICAgdmFsID0gWydTSEExJywgJ1NIQTI1NicsICdTSEEzODQnXVtoYXNodHlwZSAtIDFdICsgJywgJyArIGhhc2huYW1lICsgJywgJyArIGhhc2g7DQogICAgICAgICAgICAgICAgICAgIFEoJ2lkeF9kMTZ2YWxjMScpLnZhbHVlID0gaGFzaHR5cGU7DQogICAgICAgICAgICAgICAgICAgIFEoJ2lkeF9kMTZ2YWxjMicpLnZhbHVlID0gaGFzaDsNCiAgICAgICAgICAgICAgICAgICAgUSgnaWR4X2QxNnZhbGMzJykudmFsdWUgPSBoYXNobmFtZTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgdXNiX29uZDE2Y2hlY2toYXNoKCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFFWKCdkMTZnZW5lcmljdmFsdWUnLCB0cnVlKTsNCiAgICAgICAgICAgICAgICBpZHhfZDE2dmFsdWUxLnZhbHVlID0gaWR4X2QxNnZhbHVlMi52YWx1ZSA9IHNldHVwYmluLnJlY29yZHNbaV0udmFyaWFibGVzW2pdLnZhbHVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaGFsdEV2ZW50KGUpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxNiwgIkVkaXQgUmVjb3JkICMiICsgKGkgKyAxKSArICIsIFZhcmlhYmxlICMiICsgKGogKyAxKSwgNywgdXNiX2VkaXR2YXJpYWJsZW9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9lZGl0dmFyaWFibGVvayhyKSB7DQogICAgICAgICAgICBpZiAociA9PSAxKSB7IC8vIE9LDQogICAgICAgICAgICAgICAgdmFyIGlkcyA9IGQxNnR5cGUudmFsdWUuc3BsaXQoJy0nKTsNCiAgICAgICAgICAgICAgICB2YXIgbW9kaWQgPSAraWRzWzBdOw0KICAgICAgICAgICAgICAgIHZhciB2YXJpZCA9ICtpZHNbMV07DQogICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gIiI7DQogICAgICAgICAgICAgICAgdmFyIHZhcmRlc2NyaXB0aW9uID0gQW10U2V0dXBCaW5WYXJJZHNbbW9kaWRdW3ZhcmlkXTsNCiAgICAgICAgICAgICAgICBpZiAobW9kaWQgPT0gMiAmJiB2YXJpZCA9PSA4KSB7DQogICAgICAgICAgICAgICAgICAgIHZhbHVlID0gU3RyaW5nLmZyb21DaGFyQ29kZShRKCdpZHhfZDE2dmFsYzEnKS52YWx1ZSkgKyBoZXgycnN0cihRKCdpZHhfZDE2dmFsYzInKS52YWx1ZSkgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKFEoJ2lkeF9kMTZ2YWxjMycpLnZhbHVlLmxlbmd0aCkgKyBRKCdpZHhfZDE2dmFsYzMnKS52YWx1ZTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBpZiAodmFyZGVzY3JpcHRpb25bMl0pIHsgdmFsdWUgPSBpZHhfZDE2dmFsdWUxLnZhbHVlOyB9IGVsc2UgeyB2YWx1ZSA9IGlkeF9kMTZ2YWx1ZTIudmFsdWU7IH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgc2V0dXBiaW4ucmVjb3Jkc1tzZWxlY3RlZFJlY29yZF0udmFyaWFibGVzW3NlbGVjdGVkVmFyaWFibGVdLnZhbHVlID0gdmFsdWU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAociA9PSAyKSB7IHNldHVwYmluLnJlY29yZHNbc2VsZWN0ZWRSZWNvcmRdLnZhcmlhYmxlcy5zcGxpY2Uoc2VsZWN0ZWRWYXJpYWJsZSwgMSk7IH0gLy8gRGVsZXRlDQogICAgICAgICAgICB1c2JfZGlzcGxheVNldHVwQmluKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2JfYWRkdmFyaWFibGUoZSwgaSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgc2VsZWN0ZWRSZWNvcmQgPSBpOw0KICAgICAgICAgICAgZDE2dHlwZS52YWx1ZSA9ICIxLTEiOw0KICAgICAgICAgICAgZDE2dHlwZS5kaXNhYmxlZCA9IGZhbHNlOw0KICAgICAgICAgICAgaWR4X2QxNnZhbHVlMS52YWx1ZSA9IGlkeF9kMTZ2YWx1ZTIudmFsdWUgPSAiIjsNCiAgICAgICAgICAgIHVzYl9vbmQxNnR5cGVjaGFuZ2UoKTsNCiAgICAgICAgICAgIGhhbHRFdmVudChlKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTYsICJBZGQgVmFyaWFibGUgdG8gUmVjb3JkICMiICsgKGkgKyAxKSwgMywgdXNiX2FkZHZhcmlhYmxlb2spOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2FkZHZhcmlhYmxlb2soKSB7DQogICAgICAgICAgICB2YXIgaWRzID0gZDE2dHlwZS52YWx1ZS5zcGxpdCgnLScpOw0KICAgICAgICAgICAgdmFyIG1vZGlkID0gK2lkc1swXTsNCiAgICAgICAgICAgIHZhciB2YXJpZCA9ICtpZHNbMV07DQogICAgICAgICAgICB2YXIgdmFsdWUgPSAiIjsNCiAgICAgICAgICAgIHZhciB2YXJkZXNjcmlwdGlvbiA9IEFtdFNldHVwQmluVmFySWRzW21vZGlkXVt2YXJpZF07DQogICAgICAgICAgICBpZiAobW9kaWQgPT0gMiAmJiB2YXJpZCA9PSA4KSB7DQogICAgICAgICAgICAgICAgdmFsdWUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKFEoJ2lkeF9kMTZ2YWxjMScpLnZhbHVlKSArIGhleDJyc3RyKFEoJ2lkeF9kMTZ2YWxjMicpLnZhbHVlKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoUSgnaWR4X2QxNnZhbGMzJykudmFsdWUubGVuZ3RoKSArIFEoJ2lkeF9kMTZ2YWxjMycpLnZhbHVlOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBpZiAodmFyZGVzY3JpcHRpb25bMl0pIHsgdmFsdWUgPSBpZHhfZDE2dmFsdWUxLnZhbHVlOyB9IGVsc2UgeyB2YWx1ZSA9IGlkeF9kMTZ2YWx1ZTIudmFsdWU7IH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IHZhcmlhYmxlDQogICAgICAgICAgICB2YXIgdiA9IHt9Ow0KICAgICAgICAgICAgdi5tb2R1bGVpZCA9IG1vZGlkOw0KICAgICAgICAgICAgdi52YXJpZCA9IHZhcmlkOw0KICAgICAgICAgICAgdi5sZW5ndGggPSAtMTsNCiAgICAgICAgICAgIHYudHlwZSA9IEFtdFNldHVwQmluVmFySWRzW21vZGlkXVt2YXJpZF1bMF07DQogICAgICAgICAgICB2LmRlc2MgPSBBbXRTZXR1cEJpblZhcklkc1ttb2RpZF1bdmFyaWRdWzFdOw0KICAgICAgICAgICAgdi52YWx1ZSA9IHZhbHVlOw0KICAgICAgICAgICAgc2V0dXBiaW4ucmVjb3Jkc1tzZWxlY3RlZFJlY29yZF0udmFyaWFibGVzLnB1c2godik7DQoNCiAgICAgICAgICAgIHNldHVwYmluLnJlY29yZHNbc2VsZWN0ZWRSZWNvcmRdLnZhcmlhYmxlcy5zb3J0KEFtdFNldHVwQmluVmFyaWFibGVDb21wYXJlKTsgLy8gU29ydCB0aGUgdmFyaWFibGVzDQogICAgICAgICAgICB1c2JfZGlzcGxheVNldHVwQmluKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2Jfb25kMTZ0eXBlY2hhbmdlKCkgew0KICAgICAgICAgICAgdmFyIGlkcyA9IGQxNnR5cGUudmFsdWUuc3BsaXQoJy0nKTsNCiAgICAgICAgICAgIHZhciBtb2RpZCA9ICtpZHNbMF07DQogICAgICAgICAgICB2YXIgdmFyaWQgPSAraWRzWzFdOw0KICAgICAgICAgICAgdmFyIHZhcmRlc2NyaXB0aW9uID0gQW10U2V0dXBCaW5WYXJJZHNbbW9kaWRdW3ZhcmlkXTsNCiAgICAgICAgICAgIFFWKCdkMTZnZW5lcmljdmFsdWUnLCBmYWxzZSk7DQogICAgICAgICAgICBRVignZDE2Y3VzdG9tdmFsdWUnLCBmYWxzZSk7DQogICAgICAgICAgICBpZiAobW9kaWQgPT0gMiAmJiB2YXJpZCA9PSA4KSB7DQogICAgICAgICAgICAgICAgdmFyIHggPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48c2VsZWN0IGlkPWlkeF9kMTZ2YWxjMSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjBweCBvbmNoYW5nZT11c2Jfb25kMTZjaGVja2hhc2goKT48b3B0aW9uIHZhbHVlPTE+U0hBMTwvb3B0aW9uPic7DQogICAgICAgICAgICAgICAgaWYgKHNldHVwYmluLm1ham9yVmVyc2lvbiA+PSAzKSB7IHggKz0gJzxvcHRpb24gdmFsdWU9Mj5TSEEyNTY8L29wdGlvbj48b3B0aW9uIHZhbHVlPTM+U0hBMzg0PC9vcHRpb24+JzsgfQ0KICAgICAgICAgICAgICAgIHggKz0gJzwvc2VsZWN0PjxkaXY+SGFzaCBUeXBlPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1pZHhfZDE2dmFsYzIgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHggb25rZXl1cD11c2Jfb25kMTZjaGVja2hhc2goKT48ZGl2Pkhhc2ggKEhFWCk8L2Rpdj48L2Rpdj4nOw0KICAgICAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWlkeF9kMTZ2YWxjMyBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjBweCBvbmtleXVwPXVzYl9vbmQxNmNoZWNraGFzaCgpIG1heGxlbmd0aD0zMT48ZGl2Pkhhc2ggTmFtZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICAgICAgUVYoJ2QxNmN1c3RvbXZhbHVlJywgdHJ1ZSk7DQogICAgICAgICAgICAgICAgUUgoJ2QxNmN1c3RvbXZhbHVlJywgeCk7DQogICAgICAgICAgICAgICAgdXNiX29uZDE2Y2hlY2toYXNoKCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFFWKCdkMTZnZW5lcmljdmFsdWUnLCB0cnVlKTsNCiAgICAgICAgICAgICAgICBpZiAodmFyZGVzY3JpcHRpb25bMl0pIHsNCiAgICAgICAgICAgICAgICAgICAgUVYoJ2lkeF9kMTZ2YWx1ZTEnLCB0cnVlKTsNCiAgICAgICAgICAgICAgICAgICAgUVYoJ2lkeF9kMTZ2YWx1ZTInLCBmYWxzZSk7DQogICAgICAgICAgICAgICAgICAgIHZhciBvcHRpb25zID0gIiI7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gdmFyZGVzY3JpcHRpb25bMl0pIHsgb3B0aW9ucyArPSAnPG9wdGlvbiB2YWx1ZT0iJyArIGkgKyAnIj4nICsgdmFyZGVzY3JpcHRpb25bMl1baV0gfQ0KICAgICAgICAgICAgICAgICAgICBRSCgnaWR4X2QxNnZhbHVlMScsIG9wdGlvbnMpOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIFFWKCdpZHhfZDE2dmFsdWUxJywgZmFsc2UpOw0KICAgICAgICAgICAgICAgICAgICBRVignaWR4X2QxNnZhbHVlMicsIHRydWUpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9vbmQxNmNoZWNraGFzaCgpIHsNCiAgICAgICAgICAgIHZhciBoYXNodHlwZSA9IFEoJ2lkeF9kMTZ2YWxjMScpLnZhbHVlOw0KICAgICAgICAgICAgdmFyIGhhc2hsZW4gPSBoZXgycnN0cihRKCdpZHhfZDE2dmFsYzInKS52YWx1ZSkubGVuZ3RoOw0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIChRKCdpZHhfZDE2dmFsYzMnKS52YWx1ZS5sZW5ndGggPiAwKSAmJiAoKGhhc2h0eXBlID09IDEpICYmIChoYXNobGVuID09IDIwKSkgfHwgKChoYXNodHlwZSA9PSAyKSAmJiAoaGFzaGxlbiA9PSAzMikpIHx8ICgoaGFzaHR5cGUgPT0gMykgJiYgKGhhc2hsZW4gPT0gNDgpKSk7DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgdXNiX2FscGhhYmV0ID0gIjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiI7DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2NvbXB1dGVDaGVja3N1bShzKSB7DQogICAgICAgICAgICB2YXIgQSA9IDA7DQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHMubGVuZ3RoOyBpKyspIEEgKz0gcy5jaGFyQ29kZUF0KGkpOw0KICAgICAgICAgICAgcmV0dXJuIHVzYl9hbHBoYWJldFtBICUgMzZdOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2dlbmVyYXRlUmFuZG9tUGlkKCkgew0KICAgICAgICAgICAgdmFyIHBpZCA9ICIiOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA3OyBpKyspIHsgcGlkICs9IHVzYl9hbHBoYWJldFtyYW5kb20oMzYpXTsgfQ0KICAgICAgICAgICAgcmV0dXJuIHBpZCArIHVzYl9jb21wdXRlQ2hlY2tzdW0ocGlkKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9nZW5lcmF0ZVJhbmRvbVBwcygpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBwcHMgPSAiIiwgczsNCiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgODsgaisrKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHMgPSAiIjsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDM7IGkrKykgcyArPSB1c2JfYWxwaGFiZXRbcmFuZG9tKDM2KV07DQogICAgICAgICAgICAgICAgcHBzICs9IHMgKyB1c2JfY29tcHV0ZUNoZWNrc3VtKHMpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIHBwczsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gUE9QVVAgRElBTE9HDQogICAgICAgIC8vDQoNCiAgICAgICAgLy8gdW5kZWZpbmVkID0gSGlkZGVuLCAxID0gR2VuZXJpYyBNZXNzYWdlDQogICAgICAgIHZhciB4eGRpYWxvZ01vZGU7DQogICAgICAgIHZhciB4eGRpYWxvZ0Z1bmM7DQogICAgICAgIHZhciB4eGRpYWxvZ0J1dHRvbnM7DQogICAgICAgIHZhciB4eGRpYWxvZ1RhZzsNCg0KICAgICAgICAvLyBEaXNwbGF5IGEgZGlhbG9nIGJveA0KICAgICAgICAvLyBQYXJhbWV0ZXJzOiBEaWFsb2cgTW9kZSAoMCA9IG5vbmUpLCBEaWFsb2cgVGl0bGUsIEJ1dHRvbnMgKDEgPSBPSywgMiA9IENhbmNlbCwgMyA9IE9LICYgQ2FuY2VsKSwgQ2FsbCBiYWNrIGZ1bmN0aW9uKDAgPSBDYW5jZWwsIDEgPSBPSyksIERpYWxvZyBDb250ZW50IChNb2RlIDExIG9ubHkpDQogICAgICAgIGZ1bmN0aW9uIHNldERpYWxvZ01vZGUoeCwgeSwgYiwgZiwgYywgdGFnKSB7DQogICAgICAgICAgICB4eGRpYWxvZ01vZGUgPSB4Ow0KICAgICAgICAgICAgeHhkaWFsb2dGdW5jID0gZjsNCiAgICAgICAgICAgIHh4ZGlhbG9nQnV0dG9ucyA9IGI7DQogICAgICAgICAgICB4eGRpYWxvZ1RhZyA9IHRhZzsNCiAgICAgICAgICAgIFFFKCdpZHhfZGxnT2tCdXR0b24nLCB0cnVlKTsNCiAgICAgICAgICAgIFFWKCdpZHhfZGxnT2tCdXR0b24nLCBiICYgMSk7DQogICAgICAgICAgICBRVignaWR4X2RsZ0NhbmNlbEJ1dHRvbicsIGIgJiAyKTsNCiAgICAgICAgICAgIFFWKCdpZF9kaWFsb2djbG9zZScsIGIgJiAyKTsNCiAgICAgICAgICAgIFFWKCdpZHhfZGxnRGVsZXRlQnV0dG9uJywgYiAmIDQpOw0KICAgICAgICAgICAgaWYgKHkpIFFIKCdpZF9kaWFsb2d0aXRsZScsIHkpOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCAyNjsgaSsrKSB7IFFWKCdkaWFsb2cnICsgaSwgaSA9PSB4KTsgfSAvLyBFZGl0IHRoaXMgbGluZSB3aGVuIG1vcmUgZGlhbG9ncyBhcmUgYWRkZWQNCiAgICAgICAgICAgIFFWKCdkaWFsb2cnLCB4KTsNCiAgICAgICAgICAgIGlmIChjKSB7IGlmICh4ID09IDExKSB7IFFIKCdpZF9kaWFsb2dPcHRpb25zJywgYyk7IH0gZWxzZSB7IFFIKCdpZF9kaWFsb2dNZXNzYWdlJywgYyk7IH0gfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGlhbG9nY2xvc2UoeCkgew0KICAgICAgICAgICAgdmFyIGYgPSB4eGRpYWxvZ0Z1bmMsIGIgPSB4eGRpYWxvZ0J1dHRvbnMsIHQgPSB4eGRpYWxvZ1RhZzsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoKTsNCiAgICAgICAgICAgIGlmICgoKGIgJiA4KSB8fCB4KSAmJiBmKSBmKHgsIHQpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2VudGVyKCkgew0KICAgICAgICAgICAgUVMoJ2RpYWxvZycpLmxlZnQgPSAoKCgoZ2V0RG9jV2lkdGgoKSAtIDQwMCkgLyAyKSkgKyAicHgiKTsNCg0KICAgICAgICAgICAgLy9RUygnaWRfbWFpbmFyZWFfZnJhbWUnKS5oZWlnaHQgPSBRKCdpZF9tYWluYXJlYScpLm9mZnNldEhlaWdodDsNCiAgICAgICAgfQ0KICAgICAgICBmdW5jdGlvbiBtZXNzYWdlYm94KHQsIG0pIHsgUUgoJ2lkX2RpYWxvZ01lc3NhZ2UnLCBtKTsgc2V0RGlhbG9nTW9kZSgxLCB0LCAxKTsgfQ0KICAgICAgICBmdW5jdGlvbiBzdGF0dXNib3godCwgbSkgeyBRSCgnaWRfZGlhbG9nTWVzc2FnZScsIG0pOyBzZXREaWFsb2dNb2RlKDEsIHQpOyB9DQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gR0VORVJJQyBNRVRIT0RTDQogICAgICAgIC8vDQoNCg0KICAgICAgICBmdW5jdGlvbiBTYXZlSnNvbkZpbGUobmFtZSwgbmFtZTIsIGRlc2MsIGRhdGEpIHsNCiAgICAgICAgICAgIHZhciBuID0gJycsIHIgPSB7fSwgZCA9IG5ldyBEYXRlKCk7DQogICAgICAgICAgICBpZiAoYW10c3lzc3RhdGUpIHsNCiAgICAgICAgICAgICAgICBuID0gIi0iICsgYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZVsnSG9zdE5hbWUnXTsNCiAgICAgICAgICAgICAgICByID0geyd3ZWJhcHB2ZXJzaW9uJzp2ZXJzaW9uLCdkZXNjcmlwdGlvbic6ZGVzYywnaG9zdG5hbWUnOmFtdHN5c3N0YXRlWydBTVRfR2VuZXJhbFNldHRpbmdzJ10ucmVzcG9uc2VbJ0hvc3ROYW1lJ10sJ2xvY2FsdGltZSc6RGF0ZSgpLCd1dGN0aW1lJzpuZXcgRGF0ZSgpLnRvVVRDU3RyaW5nKCksJ2lzb3RpbWUnOm5ldyBEYXRlKCkudG9JU09TdHJpbmcoKX07DQogICAgICAgICAgICAgICAgaWYgKEhhcmR3YXJlSW52ZW50b3J5KSByWydzeXN0ZW1pZCddID0gZ3VpZFRvU3RyKEhhcmR3YXJlSW52ZW50b3J5WydDSU1fQ29tcHV0ZXJTeXN0ZW1QYWNrYWdlJ10ucmVzcG9uc2VbIlBsYXRmb3JtR1VJRCJdLnRvTG93ZXJDYXNlKCkpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgbiArPSAnLScgKyBkLmdldEZ1bGxZZWFyKCkgKyAiLSIgKyAoIjAiKyhkLmdldE1vbnRoKCkrMSkpLnNsaWNlKC0yKSArICItIiArICgiMCIgKyBkLmdldERhdGUoKSkuc2xpY2UoLTIpICsgIi0iICsgKCIwIiArIGQuZ2V0SG91cnMoKSkuc2xpY2UoLTIpICsgIi0iICsgKCIwIiArIGQuZ2V0TWludXRlcygpKS5zbGljZSgtMik7Ow0KICAgICAgICAgICAgcltuYW1lMl0gPSBkYXRhOw0KDQogICAgICAgICAgICBzYXZlQXMoZGF0YTJibG9iKEpTT04uc3RyaW5naWZ5KHIsIG51bGwsICcgICcpLnJlcGxhY2UoL1xuL2csICdcclxuJykpLCBuYW1lICsgbiArICcuanNvbicpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGh0dHBFcnJvclRhYmxlID0gew0KICAgICAgICAgICAgMjAwOiAnT0snLA0KICAgICAgICAgICAgNDAxOiAnQXV0aGVudGljYXRpb24gRXJyb3InLA0KICAgICAgICAgICAgNDA4OiAnVGltZW91dCBFcnJvcicsDQogICAgICAgICAgICA2MDE6ICdXU01BTiBQYXJzaW5nIEVycm9yJywNCiAgICAgICAgICAgIDYwMjogJ1VuYWJsZSB0byBwYXJzZSBIVFRQIHJlc3BvbnNlIGhlYWRlcicsDQogICAgICAgICAgICA2MDM6ICdVbmV4cGVjdGVkIEhUVFAgZW51bSByZXNwb25zZScsDQogICAgICAgICAgICA2MDQ6ICdVbmV4cGVjdGVkIEhUVFAgcHVsbCByZXNwb25zZScsDQogICAgICAgIH0NCiAgICAgICAgZnVuY3Rpb24gZXJyY2hlY2socywgc3RhY2spIHsNCiAgICAgICAgICAgIGlmICh3c3N0YWNrID09IG51bGwgfHwgYW10c3RhY2sgIT0gc3RhY2spIHJldHVybiB0cnVlOw0KICAgICAgICAgICAgaWYgKHMgIT0gMjAwICYmIHMgIT0gOSkgew0KICAgICAgICAgICAgICAgIHNldERpYWxvZ01vZGUoKTsNCiAgICAgICAgICAgICAgICB3c3N0YWNrLmNvbW0uRmFpbEFsbEVycm9yID0gOTk5OyAvLyBDYXVzZSBhbGwgbmV3IHJlc3BvbnNlcyB0byBiZSBzaWxlbnQNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5DYW5jZWxBbGxRdWVyaWVzKDk5OSk7DQogICAgICAgICAgICAgICAgUUgoJ2lkX21lc3NhZ2V2aWV3c3RyJywgKChodHRwRXJyb3JUYWJsZVtzXSk/KGh0dHBFcnJvclRhYmxlW3NdKTooJ0Vycm9yICMnICsgcykpKTsNCiAgICAgICAgICAgICAgICBnbygxMDApOw0KICAgICAgICAgICAgICAgIFFTKCdpZF9wcm9ncmVzc2JhcicpLndpZHRoID0gMDsNCg0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIChzICE9IDIwMCk7DQogICAgICAgIH0NCg0KDQogICAgICAgIGZ1bmN0aW9uIGdvaUZyYW1lKGUseCx5KSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBnbyh4KTsNCiAgICAgICAgICAgIGlmICgoZS5zaGlmdEtleSA9PSB0cnVlKSB8fCAoUSgnaWRfU3RvcmFnZUlGcmFtZScpLnNyYy5lbmRzV2l0aCh5KSA9PSBmYWxzZSkpIFEoJ2lkX1N0b3JhZ2VJRnJhbWUnKS5zcmMgPSB5Ow0KICAgICAgICAgICAgUVYoJ2lkX21haW5hcmVhX3BhZCcsIGZhbHNlKTsNCiAgICAgICAgICAgIFFWKCdpZF9tYWluYXJlYV9mcmFtZScsIHRydWUpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZ28oeCwgZm9yY2UpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgJiYgZm9yY2UgIT0gMSkgcmV0dXJuOw0KDQogICAgICAgICAgICBRVignaWRfbWFpbmFyZWFfZnJhbWUnLCBmYWxzZSk7DQogICAgICAgICAgICBRVignaWRfbWFpbmFyZWFfcGFkJywgdHJ1ZSk7DQoNCiAgICAgICAgICAgIFFWKCdpZF9sbXNNYWluUGFuZWwnLCB4ID09IDEwMSk7DQoNCiAgICAgICAgICAgIFFWKCdpZF91c2JTZXR1cFBhbmVsJywgeCA9PSAxMDIpOw0KICAgICAgICAgICAgUVYoJ2lkX21lc3NhZ2V2aWV3JywgeCA9PSAxMDApOw0KICAgICAgICAgICAgUVYoJ2lkX21haW52aWV3JywgeCA8IDEwMCk7DQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDgwOyBpKyspIHsgLy8gRWRpdCB0aGlzIGxpbmUgd2hlbiBhZGRpbmcgYSBuZXcgc2NyZWVuDQogICAgICAgICAgICAgICAgUVYoJ3AnICsgaSwgaSA9PSB4KTsNCiAgICAgICAgICAgICAgICB2YXIgcSA9IFFTKCdnbycgKyBpKTsNCi8vICMjI0JFR0lOIyMje0xvb2stSW50ZWx9DQogICAgICAgICAgICAgICAgaWYgKHEpIHsgcVsnYmFja2dyb3VuZC1jb2xvciddID0gKChpID09IHgpPyIjYWJjYWUxIjoiIik7IH0gLy8gI2U4ZWVmZQ0KLy8gIyMjRU5EIyMje0xvb2stSW50ZWx9DQoNCiAgICAgICAgICAgICAgICBpZiAocSkgeyBxWydiYWNrZ3JvdW5kLWNvbG9yJ10gPSAoKGkgPT0geCk/ImdyYXkiOiIiKTsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY3VycmVudFZpZXcgPSB4Ow0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcG9ydHNGcm9tSG9zdChob3N0LCB0bHMpIHsgdmFyIHggPSBkZWNvZGVVUklDb21wb25lbnQoaG9zdCkuc3BsaXQoJzonKSwgaHAgPSAoKHRscyA9PSAwKSA/IDE2OTkyIDogMTY5OTMpLCBycCA9ICgodGxzID09IDApID8gMTY5OTQgOiAxNjk5NSk7IGlmICh4Lmxlbmd0aCA+IDEpIHsgaHAgPSBwYXJzZUludCh4WzFdKTsgfSBpZiAoeC5sZW5ndGggPiAyKSB7IHJwID0gcGFyc2VJbnQoeFsyXSk7IH0gcmV0dXJuIHsgaG9zdDogeFswXSwgaHR0cDogaHAsIHJlZGlyOiBycCB9IH0NCiAgICAgICAgZnVuY3Rpb24gYWRkTGluayh4LCBmKSB7IHJldHVybiAiPGEgc3R5bGU9Y3Vyc29yOnBvaW50ZXI7Y29sb3I6Ymx1ZSBvbmNsaWNrPSciICsgZiArICInPiZkaWFtczsgIiArIHggKyAiPC9hPiI7IH0NCiAgICAgICAgZnVuY3Rpb24gYWRkTGlua0NvbmRpdGlvbmFsKHgsIGYsIGMpIHsgaWYgKGMpIHJldHVybiBhZGRMaW5rKHgsIGYpOyByZXR1cm4geDsgfQ0KICAgICAgICBmdW5jdGlvbiBoYWx0RXZlbnQoZSkgeyBpZiAoZS5wcmV2ZW50RGVmYXVsdCkgZS5wcmV2ZW50RGVmYXVsdCgpOyBpZiAoZS5zdG9wUHJvcGFnYXRpb24pIGUuc3RvcFByb3BhZ2F0aW9uKCk7IHJldHVybiBmYWxzZTsgfQ0KICAgICAgICBmdW5jdGlvbiBhZGRPcHRpb24ocSwgdCwgaSkgeyB2YXIgb3B0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgib3B0aW9uIik7IG9wdGlvbi50ZXh0ID0gdDsgb3B0aW9uLnZhbHVlID0gaTsgUShxKS5hZGQob3B0aW9uKTsgfQ0KICAgICAgICBmdW5jdGlvbiBhZGREaXNhYmxlZE9wdGlvbihxLCB0LCBpKSB7IHZhciBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJvcHRpb24iKTsgb3B0aW9uLnRleHQgPSB0OyBvcHRpb24udmFsdWUgPSBpOyBvcHRpb24uZGlzYWJsZWQgPSAxOyBRKHEpLmFkZChvcHRpb24pOyB9DQogICAgICAgIGZ1bmN0aW9uIHBhc3N3b3JkY2hlY2socCkgeyBpZiAocC5sZW5ndGggPCA4KSByZXR1cm4gZmFsc2U7IHZhciB1cHBlciA9IDAsIGxvd2VyID0gMCwgbnVtYmVyID0gMCwgbm9uYWxwaGEgPSAwOyBmb3IgKHZhciBpIGluIHApIHsgdmFyIGMgPSBwLmNoYXJDb2RlQXQoaSk7IGlmICgoYyA+IDY0KSAmJiAoYyA8IDkxKSkgeyB1cHBlciA9IDE7IH0gZWxzZSBpZiAoKGMgPiA5NikgJiYgKGMgPCAxMjMpKSB7IGxvd2VyID0gMTsgfSBlbHNlIGlmICgoYyA+IDQ3KSAmJiAoYyA8IDU4KSkgeyBudW1iZXIgPSAxOyB9IGVsc2UgeyBub25hbHBoYSA9IDE7IH0gfSByZXR1cm4gKCh1cHBlciArIGxvd2VyICsgbnVtYmVyICsgbm9uYWxwaGEpID09IDQpOyB9DQogICAgICAgIGZ1bmN0aW9uIG1ldGhvZGNoZWNrKHIpIHsgaWYgKHIgJiYgciAhPSBudWxsICYmIHIuQm9keSAmJiByLkJvZHlbJ1JldHVyblZhbHVlJ10gIT0gMCkgeyBtZXNzYWdlYm94KCJDYWxsIEVycm9yIiwgci5IZWFkZXJbJ01ldGhvZCddICsgIjogIiArIChyLkJvZHkuUmV0dXJuVmFsdWVTdHIgKyAnJykucmVwbGFjZSgiXyIsICIgIikpOyByZXR1cm4gdHJ1ZTsgfSByZXR1cm4gZmFsc2U7IH0NCiAgICAgICAgZnVuY3Rpb24gVGFibGVTdGFydCgpIHsgcmV0dXJuICI8dGFibGUgY2xhc3M9J2xvZzEgdXMnIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6OHB4Pjx0cj48dGQgd2lkdGg9MjAwcHg+PHA+PHRkPiI7IH0NCiAgICAgICAgZnVuY3Rpb24gVGFibGVTdGFydDIoKSB7IHJldHVybiAiPHRhYmxlIGNsYXNzPSdsb2cxIHVzJyBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjhweD48dHI+PHRkPjxwPjx0ZD4iOyB9DQogICAgICAgIGZ1bmN0aW9uIFRhYmxlRW50cnkobiwgdikgeyByZXR1cm4gIjx0cj48dGQgY2xhc3M9cjE+PHA+IiArIG4gKyAiPHRkIGNsYXNzPXIxPiIgKyB2OyB9DQogICAgICAgIGZ1bmN0aW9uIEZ1bGxUYWJsZSh4LCBlKSB7IHZhciByID0gVGFibGVTdGFydCgpOyBmb3IgKGkgaW4geCkgeyBpZiAoaSAmJiB4W2ldKSByICs9IFRhYmxlRW50cnkoaSwgeFtpXSk7IH0gcmV0dXJuIHIgKyBUYWJsZUVuZChlKTsgfQ0KICAgICAgICBmdW5jdGlvbiBUYWJsZUVuZChuKSB7IHJldHVybiAiPHRyPjx0ZCBjb2xzcGFuPTI+PHA+IiArIChuP246JycpICsgIjwvdGFibGU+IjsgfQ0KICAgICAgICBmdW5jdGlvbiBBZGRCdXR0b24odiwgZikgeyByZXR1cm4gIjxpbnB1dCB0eXBlPWJ1dHRvbiB2YWx1ZT0nIiArIHYgKyAiJyBvbmNsaWNrPSciICsgZiArICInIHN0eWxlPW1hcmdpbjo0cHg+IjsgfQ0KICAgICAgICBmdW5jdGlvbiBBZGRCdXR0b24yKHYsIGYsIHMpIHsgcmV0dXJuICI8aW5wdXQgdHlwZT1idXR0b24gdmFsdWU9JyIgKyB2ICsgIicgb25jbGljaz0nIiArIGYgKyAiJyAiICsgcyArICI+IjsgfQ0KICAgICAgICBmdW5jdGlvbiBBZGRSZWZyZXNoQnV0dG9uKGYpIHsgcmV0dXJuICI8aW5wdXQgdHlwZT1idXR0b24gbmFtZT1yZWZyZXNoYnRuIHZhbHVlPVJlZnJlc2ggb25jbGljaz0ncmVmcmVzaEJ1dHRvbnMoZmFsc2UpOyIgKyBmICsgIicgc3R5bGU9bWFyZ2luOjRweCAiICsgKHJlZnJlc2hCdXR0b25zU3RhdGU9PWZhbHNlPyJkaXNhYmxlZCI6IiIpICsgIj4iOyB9DQogICAgICAgIGZ1bmN0aW9uIE1vcmVTdGFydCgpIHsgcmV0dXJuICI8YSBzdHlsZT1jdXJzb3I6cG9pbnRlcjtjb2xvcjpibHVlIGlkPW1vcmV4eHgxIG9uY2xpY2s9UVYoXCJtb3JleHh4MVwiLGZhbHNlKTtRVihcIm1vcmV4eHgyXCIsdHJ1ZSk+JiN4MjVCQzsgTW9yZTwvYT48ZGl2IGlkPW1vcmV4eHgyIHN0eWxlPWRpc3BsYXk6bm9uZT48YnI+PGhyPiI7IH07DQogICAgICAgIGZ1bmN0aW9uIE1vcmVFbmQoKSB7IHJldHVybiAiPGEgc3R5bGU9Y3Vyc29yOnBvaW50ZXI7Y29sb3I6Ymx1ZSBvbmNsaWNrPVFWKFwibW9yZXh4eDJcIixmYWxzZSk7UVYoXCJtb3JleHh4MVwiLHRydWUpPiYjeDI1QjI7IExlc3M8L2E+PC9kaXY+IjsgfTsNCiAgICAgICAgZnVuY3Rpb24gZ2V0U2VsZWN0ZWRPcHRpb25zKHNlbCkgeyB2YXIgb3B0cyA9IFtdLCBvcHQ7IGZvciAodmFyIGkgPSAwLCBsZW4gPSBzZWwub3B0aW9ucy5sZW5ndGg7IGkgPCBsZW47IGkrKykgeyBvcHQgPSBzZWwub3B0aW9uc1tpXTsgaWYgKG9wdC5zZWxlY3RlZCkgeyBvcHRzLnB1c2gob3B0LnZhbHVlKTsgfSB9IHJldHVybiBvcHRzOyB9DQogICAgICAgIGZ1bmN0aW9uIGdldEluc3RhbmNlKHgsIHkpIHsgZm9yICh2YXIgaSBpbiB4KSB7IGlmICh4W2ldWyJJbnN0YW5jZUlEIl0gPT0geSkgcmV0dXJuIHhbaV07IH0gcmV0dXJuIG51bGw7IH0NCiAgICAgICAgZnVuY3Rpb24gZ2V0SXRlbSh4LCB5LCB6KSB7IGZvciAodmFyIGkgaW4geCkgeyBpZiAoeFtpXVt5XSA9PSB6KSByZXR1cm4geFtpXTsgfSByZXR1cm4gbnVsbDsgfQ0KICAgICAgICBmdW5jdGlvbiBndWlkVG9TdHIoZykgeyByZXR1cm4gZy5zdWJzdHJpbmcoNiwgOCkgKyBnLnN1YnN0cmluZyg0LCA2KSArIGcuc3Vic3RyaW5nKDIsIDQpICsgZy5zdWJzdHJpbmcoMCwgMikgKyAiLSIgKyBnLnN1YnN0cmluZygxMCwgMTIpICsgZy5zdWJzdHJpbmcoOCwgMTApICsgIi0iICsgZy5zdWJzdHJpbmcoMTQsIDE2KSArIGcuc3Vic3RyaW5nKDEyLCAxNCkgKyAiLSIgKyBnLnN1YnN0cmluZygxNiwgMjApICsgIi0iICsgZy5zdWJzdHJpbmcoMjApOyB9DQogICAgICAgIGZ1bmN0aW9uIGdldFVybFZhcnMoKSB7IHZhciBqLCBoYXNoLCB2YXJzID0gW10sIGhhc2hlcyA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNsaWNlKHdpbmRvdy5sb2NhdGlvbi5ocmVmLmluZGV4T2YoJz8nKSArIDEpLnNwbGl0KCcmJyk7IGZvciAodmFyIGkgPSAwOyBpIDwgaGFzaGVzLmxlbmd0aDsgaSsrKSB7IGogPSBoYXNoZXNbaV0uaW5kZXhPZignPScpOyBpZiAoaiA+IDApIHsgdmFyc1toYXNoZXNbaV0uc3Vic3RyaW5nKDAsIGopXSA9IGhhc2hlc1tpXS5zdWJzdHJpbmcoaiArIDEsIGhhc2hlc1tpXS5sZW5ndGgpOyB9IH0gcmV0dXJuIHZhcnM7IH0NCiAgICAgICAgZnVuY3Rpb24gZ2V0RG9jV2lkdGgoKSB7IGlmICh3aW5kb3cuaW5uZXJXaWR0aCkgcmV0dXJuIHdpbmRvdy5pbm5lcldpZHRoOyBpZiAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aCAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGggIT0gMCkgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aDsgcmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdib2R5JylbMF0uY2xpZW50V2lkdGg7IH0NCiAgICAgICAgZnVuY3Rpb24gZ2V0RG9jSGVpZ2h0KCkgeyBpZiAod2luZG93LmlubmVySGVpZ2h0KSByZXR1cm4gd2luZG93LmlubmVySGVpZ2h0OyBpZiAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCAhPSAwKSByZXR1cm4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodDsgcmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdib2R5JylbMF0uY2xpZW50SGVpZ2h0OyB9DQogICAgICAgIGZ1bmN0aW9uIGFkZEh0bWxWYWx1ZSh0LCB2KSB7IHJldHVybiAnPGRpdiBzdHlsZT1oZWlnaHQ6MjBweD48ZGl2IHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIyMHB4O292ZXJmbG93OmhpZGRlbj48YiB0aXRsZT0iJyArIHYgKyAnIj4nICsgdiArICc8L2I+PC9kaXY+PGRpdj4nICsgdCArICc8L2Rpdj48L2Rpdj4nOyB9DQogICAgICAgIGZ1bmN0aW9uIGFkZEh0bWxWYWx1ZU5vVGl0bGUodCwgdikgeyByZXR1cm4gJzxkaXYgc3R5bGU9aGVpZ2h0OjIwcHg+PGRpdiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMjBweDtvdmVyZmxvdzpoaWRkZW4+JyArIHYgKyAnPC9iPjwvZGl2PjxkaXY+JyArIHQgKyAnPC9kaXY+PC9kaXY+JzsgfQ0KICAgICAgICBmdW5jdGlvbiBudW1iZXJzT25seShlLCB4KSB7IHJldHVybiAoZXZlbnQuY2hhckNvZGUgPT0gMCkgfHwgKGV2ZW50LmNoYXJDb2RlID09IHgpIHx8IChldmVudC5jaGFyQ29kZSA+PSA0OCAmJiBldmVudC5jaGFyQ29kZSA8PSA1Nyk7IH0NCg0KDQogICAgICAgIC8vIEdldCB0aGluZ3Mgc3RhcnRlZA0KICAgICAgICBzdGFydHVwKCk7DQogICAgPC9zY3JpcHQ+";amtLms.meshCommander=http.createServer();amtLms.meshCommander.listen(16994);amtLms.meshCommander.on("upgrade",function(f,g,c){switch(f.url.split("?")[0]){case"/lms.ashx":g.ws=g.upgradeWebSocket();g.ws.on("data",processLmsControlData);g.ws.on("end",function(){if(lmsControlSockets[this.id]){delete lmsControlSockets[this.id]}});var d=lmsControlSocketsNextId++;lmsControlSockets[d]=g.ws;g.ws.id=d;break;case"/webrelay.ashx":g.ws=g.upgradeWebSocket();if(amtLms.connected==true){amtLms.bindDuplexStream(g.ws,"IPv4",16992)}else{var e=require("net");g.relay=e.connect({host:"127.0.0.1",port:16992});g.relay.on("connect",function(){g.ws.on("data",function(h){g.relay.write(h)});g.ws.on("end",function(){g.relay.end()})});g.relay.on("data",function(h){g.ws.write(h)});g.relay.on("close",function(){g.ws.end()})}break;default:g.end();break}});amtLms.meshCommander.on("request",function(f,g){switch(f.url.split("?")[0]){case"/":var d=null;try{d=fs.readFileSync("lmscommander.htm")}catch(c){}if(d!=null){g.writeHead(200,"OK",{Server:"JSLMS","Cache-Control":"max-age=0, no-cache","X-Frame-Options":"DENY","Content-Type":"text/html","Transfer-Encoding":"chunked"});g.end(d)}else{g.writeHead(200,"OK",{Server:"JSLMS","Cache-Control":"max-age=0, no-cache","X-Frame-Options":"DENY","Content-Type":"text/html","Content-Encoding":"gzip","Transfer-Encoding":"chunked",ETag:b});g.end(Buffer.from(a,"base64"))}break;default:g.statusCode=404;g.statusMessage="Not Found";g.end();break}})}function setupMeiOsAdmin(a,b){if(amtMei==null){if(a){a(b)}}else{amtMei.getLocalSystemAccount(function(f){var d=require("amt-wsman-duk");var e=require("amt-wsman");var c=require("amt");oswsstack=new e(d,"127.0.0.1",16992,f.user,f.pass,false);osamtstack=new c(oswsstack);if(a){a(b)}amtMei.getVersion(function(k){var g=null;try{for(var j in k.Versions){if(k.Versions[j].Description=="AMT"){g=parseInt(k.Versions[j].Version.split(".")[0])}}}catch(h){}if((g!=null)&&(g>=12)){kvmGetData("skip");tempTimer=setInterval(function(){kvmGetData()},2000);kvmSetData(JSON.stringify({action:"restart",ver:1}))}})})}}function kvmGetData(a){osamtstack.IPS_KVMRedirectionSettingData_DataChannelRead(kvmDataGetResponse,a)}function kvmDataGetResponse(d,b,c,f,g){if((g!="skip")&&(f==200)&&(c.Body.ReturnValue==0)){var h=null;try{h=Buffer.from(c.Body.DataMessage,"base64").toString()}catch(a){return}if(h!=null){kvmProcessData(c.Body.RealmsBitmap,c.Body.MessageId,h)}}}var webRtcDesktop=null;function kvmProcessData(d,c,g){var a=null;try{a=JSON.parse(g)}catch(b){}if((a!=null)&&(a.action)){if(a.action=="present"){kvmSetData(JSON.stringify({action:"present",ver:1,platform:process.platform}))}if(a.action=="offer"){webRtcDesktop={};var f=require("ILibWebRTC");webRtcDesktop.webrtc=f.createConnection();webRtcDesktop.webrtc.on("connected",function(){});webRtcDesktop.webrtc.on("disconnected",function(){webRtcCleanUp()});webRtcDesktop.webrtc.on("dataChannel",function(h){webRtcDesktop.rtcchannel=h;var e=require("meshDesktop");webRtcDesktop.kvm=e.getRemoteDesktopStream();webRtcDesktop.kvm.pipe(webRtcDesktop.rtcchannel,{dataTypeSkip:1,end:false});webRtcDesktop.rtcchannel.on("end",function(){webRtcCleanUp()});webRtcDesktop.rtcchannel.on("data",function(j){kvmCtrlData(this,j)});webRtcDesktop.rtcchannel.pipe(webRtcDesktop.kvm,{dataTypeSkip:1,end:false})});kvmSetData(JSON.stringify({action:"answer",ver:1,sdp:webRtcDesktop.webrtc.setOffer(a.sdp)}))}}}var path={join:function(){var c=[];for(var a in arguments){var b=arguments[a];if(b!=null){while(b.endsWith("/")||b.endsWith("\\")){b=b.substring(0,b.length-1)}if(a!=0){while(b.startsWith("/")||b.startsWith("\\")){b=b.substring(1)}}c.push(b)}}if(c.length==0){return"/"}return c.join("/")}};function getDirectoryInfo(f){var g={path:f,dir:[]};if(((f==undefined)||(f==""))&&(process.platform=="win32")){var h=null;try{h=fs.readDrivesSync()}catch(b){}if(h!=null){for(var c=0;c0&&c.charCodeAt(0)!=123){if(this.fileupload!=null){c=Buffer.from(c,"base64");var k=c.readUInt32BE(0);if((k==16777216)||(k==16777217)){fs.writeSync(this.fileupload.fp,c.slice(4));b.write({action:"upload",sub:"ack",reqid:this.fileupload.reqid});if(k==16777217){fs.closeSync(this.fileupload.fp);this.fileupload=null}}}return}try{c=JSON.parse(c)}catch(g){console.error("Invalid JSON: "+c);return}if((c.path!=null)&&(process.platform!="win32")&&(c.path[0]!="/")){c.path="/"+c.path}switch(c.action){case"ping":b.write({action:"pong"});break;case"ls":var p=getDirectoryInfo(c.path);if(c.reqid!=undefined){p.reqid=c.reqid}b.write(p);break;case"mkdir":fs.mkdirSync(c.path);break;case"rm":for(var l in c.delfiles){var j=path.join(c.path,c.delfiles[l]);try{fs.unlinkSync(j)}catch(f){console.log(f)}}break;case"rename":var o=path.join(c.path,c.oldname);var n=path.join(c.path,c.newname);try{fs.renameSync(o,n)}catch(f){console.log(f)}break;case"download":var r=0;if(c.sub=="start"){if(this.filedownload!=null){b.write({action:"download",sub:"cancel",id:this.filedownload.id});delete this.filedownload}this.filedownload={id:c.id,path:c.path,ptr:0};try{this.filedownload.f=fs.openSync(this.filedownload.path,"rbN")}catch(f){b.write({action:"download",sub:"cancel",id:this.filedownload.id});delete this.filedownload}if(this.filedownload){b.write({action:"download",sub:"start",id:c.id})}}else{if((this.filedownload!=null)&&(c.id==this.filedownload.id)){if(c.sub=="startack"){r=8}else{if(c.sub=="stop"){delete this.filedownload}else{if(c.sub=="ack"){r=1}}}}}while(r>0){r--;var a=Buffer.alloc(4096);var m=fs.readSync(this.filedownload.f,a,4,4092,null);this.filedownload.ptr+=m;if(m<4092){a.writeInt32BE(16777217,0);fs.closeSync(this.filedownload.f);delete this.filedownload;r=0}else{a.writeInt32BE(16777216,0)}b.write(a.slice(0,m+4).toString("base64"))}break;case"upload":if(c.sub=="start"){if(this.fileupload!=null){fs.closeSync(this.fileupload.fp)}if(!c.path||!c.name){break}this.fileupload={reqid:c.reqid};var h=path.join(c.path,c.name);try{this.fileupload.fp=fs.openSync(h,"wbN")}catch(f){}if(this.fileupload.fp){b.write({action:"upload",sub:"start",reqid:this.fileupload.reqid})}else{this.fileupload=null;b.write({action:"upload",sub:"error",reqid:this.fileupload.reqid})}}else{if(c.sub=="cancel"){if(this.fileupload!=null){fs.closeSync(this.fileupload.fp);this.fileupload=null}}}break;case"copy":for(var l in c.names){var q=path.join(c.scpath,c.names[l]),d=path.join(c.dspath,c.names[l]);if(q!=d){try{fs.copyFileSync(q,d)}catch(f){}}}break;case"move":for(var l in c.names){var q=path.join(c.scpath,c.names[l]),d=path.join(c.dspath,c.names[l]);if(q!=d){try{fs.copyFileSync(q,d);fs.unlinkSync(q)}catch(f){}}}break;default:break}}function webRtcCleanUp(){if(webRtcDesktop==null){return}if(webRtcDesktop.rtcchannel){try{webRtcDesktop.rtcchannel.close()}catch(a){}try{webRtcDesktop.rtcchannel.removeAllListeners("data")}catch(a){}try{webRtcDesktop.rtcchannel.removeAllListeners("end")}catch(a){}delete webRtcDesktop.rtcchannel}if(webRtcDesktop.webrtc){try{webRtcDesktop.webrtc.close()}catch(a){}try{webRtcDesktop.webrtc.removeAllListeners("connected")}catch(a){}try{webRtcDesktop.webrtc.removeAllListeners("disconnected")}catch(a){}try{webRtcDesktop.webrtc.removeAllListeners("dataChannel")}catch(a){}delete webRtcDesktop.webrtc}if(webRtcDesktop.kvm){try{webRtcDesktop.kvm.end()}catch(a){}delete webRtcDesktop.kvm}webRtcDesktop=null}function kvmSetData(a){osamtstack.IPS_KVMRedirectionSettingData_DataChannelWrite(Buffer.from(a).toString("base64"),function(){})}function startLmsWsmanResponse(d,b,c,e){if(e==600){console.log("ERROR: Unable to connect to Intel(R) AMT.")}else{if(e!=200){console.log("ERROR: Unable to get object from Intel(R) AMT, status = "+e+".")}else{var a=c.CIM_SoftwareIdentity.responses;if(a.length>0){var f=getInstance(a,"AMT")["VersionString"];amtversion=parseInt(f.split(".")[0]);amtversionmin=parseInt(f.split(".")[1])}}}}function processLmsControlData(b){if(b.length<2){return}var a=b.readUInt16LE(0);switch(a){case 1:getAmtInfo(function(c,d){c.LoginMode=2;d.write(Buffer.concat([Buffer.from("0100","hex"),Buffer.from(JSON.stringify(c))]))},this);break;case 2:if(b.length<6){break}amtMei.unprovision(b.readUInt32LE(2),function(e,d){var c=Buffer.alloc(6);c.writeUInt16LE(2,0);c.writeUInt32LE(e,2);d.write(c)},this);break;case 3:amtMei.getLocalSystemAccount(function(c,d){d.write(Buffer.concat([Buffer.from("030000000000","hex"),c.raw]))},this);break;case 4:amtMei.startConfiguration(function(e,d){var c=Buffer.alloc(6);c.writeUInt16LE(7,0);c.writeUInt32LE(e,2);d.write(c)},this);break;case 5:amtMei.stopConfiguration(function(e,d){var c=Buffer.alloc(6);c.writeUInt16LE(7,0);c.writeUInt32LE(e,2);d.write(c)},this);break;case 6:amtMei.openUserInitiatedConnection(function(e,d){var c=Buffer.alloc(6);c.writeUInt16LE(7,0);c.writeUInt32LE(e,2);d.write(c)},this);break;case 7:amtMei.closeUserInitiatedConnection(function(e,d){var c=Buffer.alloc(6);c.writeUInt16LE(7,0);c.writeUInt32LE(e,2);d.write(c)},this);break;case 8:amtMei.getRemoteAccessConnectionStatus(function(e,d){var c=Buffer.alloc(6);c.writeUInt16LE(8,0);c.writeUInt32LE(e.status,2);d.write(Buffer.concat([c,e.raw]))},this);break;default:break}}function startRouter(){tcpserver=net.createServer(OnTcpClientConnected);tcpserver.on("error",function(a){console.log("ERROR: "+JSON.stringify(a));exit(0);return});tcpserver.listen(settings.localport,function(){if(settings.remotename==null){console.log("Redirecting local port "+settings.localport+" to remote port "+settings.remoteport+".")}else{console.log("Redirecting local port "+settings.localport+" to "+settings.remotename+":"+settings.remoteport+".")}console.log("Press ctrl-c to exit.")})}function OnTcpClientConnected(a){try{debug(1,"Client connected");a.on("end",function(){disconnectTunnel(this,this.websocket,"Client closed")});a.pause();try{options=http.parseUri(settings.serverurl+"?user="+settings.username+"&pass="+settings.password+"&nodeid="+settings.remotenodeid+"&tcpport="+settings.remoteport)}catch(b){console.log('Unable to parse "serverUrl".');process.exit(1);return}options.checkServerIdentity=onVerifyServer;options.rejectUnauthorized=false;a.websocket=http.request(options);a.websocket.tcp=a;a.websocket.tunneling=false;a.websocket.upgrade=OnWebSocket;a.websocket.on("error",function(c){console.log("ERROR: "+JSON.stringify(c))});a.websocket.end()}catch(b){debug(2,b)}}function disconnectTunnel(c,d,b){if(d!=null){try{d.end()}catch(a){debug(2,a)}}if(c!=null){try{c.end()}catch(a){debug(2,a)}}debug(1,"Tunnel disconnected: "+b)}function OnWebSocket(b,c,a){debug(1,"Websocket connected");c.on("data",function(d){if(this.parent.tunneling==false){d=d.toString();if(d=="c"){this.parent.tunneling=true;this.pipe(this.parent.tcp);this.parent.tcp.pipe(this);debug(1,"Tunnel active")}else{if((d.length>6)&&(d.substring(0,6)=="error:")){console.log(d.substring(6));disconnectTunnel(this.tcp,this,d.substring(6))}}}});c.on("error",function(d){disconnectTunnel(this.tcp,this,"Websocket error")});c.on("close",function(d){disconnectTunnel(this.tcp,this,"Websocket closed")});c.parent=this}function discoverMeshServer(){console.log("Looking for server...");discoveryInterval=setInterval(discoverMeshServerOnce,5000);discoverMeshServerOnce()}function discoverMeshServerOnce(){var f=os.networkInterfaces();for(var a in f){if(f.hasOwnProperty(a)){for(var d=0;dm){g+="}";m++}f=JSON.parse(g)}catch(j){console.log("Error: Unable to parse Intel AMT response: "+g,j);a(null)}if(a!=null){a(d.statusCode,f)}})});c.on("error",function(d){console.log("Error occured: "+JSON.stringify(d));if(b==true){if(a!=null){a(null)}}else{getAmtStorage(a,true)}});c.end()}function pushToStorage(f,e,b,c,g){if(g==null){g=0}var h=digest.request({protocol:settings.protocol,method:"PUT",host:settings.hostname,path:("/amt-storage/"+f+((g!=0)?"?append=":"")),port:settings.localport});h.on("error",function(j){console.log("Error occured: "+JSON.stringify(j));if(c!=null){c(null)}});h.on("response",function(j){debug(1,"Chunk Done",b.length,g);if((j.statusCode==200)&&(g0)?"":"Content-Encoding:gzipContent-Type:text/html"+((e!=null)?(""+e+""):"")+"";var a=((b.length-g)>(7000-d.length))?(7000-d.length):(b.length-g);h.write(Buffer.concat([new Buffer(d),b.slice(g,g+a)]));g+=a;h.end()}function verifyStorage(c,a,b){var d=digest.request({protocol:settings.protocol,method:"GET",host:settings.hostname,path:("/amt-storage/"+c),port:settings.localport});d.on("error",function(f){console.log("Verify error occured: "+JSON.stringify(f));if(b!=null){b(null)}});d.on("response",function(e){e.ptr=0;e.ok=true;e.on("data",function(f){if(f.toString("hex")!=a.slice(e.ptr,e.ptr+f.length).toString("hex")){e.ok=false;console.log("Verifiy failed ("+e.ptr+", "+f.length+").")}e.ptr+=f.length});e.on("end",function(){if(b!=null){b(e.ok)}})});d.end()}function deleteStorage(b,a,c){var d=digest.request({protocol:settings.protocol,method:"DELETE",host:settings.hostname,path:"/amt-storage/"+b,port:settings.localport});d.on("error",function(f){if((f=="Error: Socket was unexpectedly closed")&&(c!=true)){deleteStorage(b,a,true)}else{if(a!=null){if(f.statusCode){a(f.statusCode)}else{a(null)}}}});d.on("response",function(e){if(a!=null){a(e.statusCode)}});d.end()}function parseUrlArguments(d){var c={},e=d.split("?");if(e.length<2){return c}e=e[1].split("&");for(var a in e){var b=e[a].indexOf("=");if(b>0){c[e[a].substring(0,b).toLowerCase()]=e[a].substring(b+1)}}return c}function removeItemFromArray(a,b){var c=a.indexOf(b);if(c!==-1){a.splice(c,1)}}var serviceName=null;var serviceOpSpecified=0;var serviceInstall=0;for(var i in process.argv){if(process.argv[i].toLowerCase()=="install"){serviceInstall=1}else{if(process.argv[i].toLowerCase()=="uninstall"){serviceInstall=-1}}if((process.argv[i].toLowerCase()=="microlms")||(process.argv[i].toLowerCase()=="amtlms")||(process.argv[i].toLowerCase()=="lms")){serviceName="MicroLMS";break}if((process.argv[i].toLowerCase()=="meshcommander")||(process.argv[i].toLowerCase()=="commander")){serviceName="MeshCommander";break}}if(serviceName==null){for(var i in process.argv){if((process.argv[i].toLowerCase()=="install")||(process.argv[i].toLowerCase()=="uninstall")){console.log("In order to install/uninstall, a service type must be specified.");process.exit()}}if(process.execPath.includes("MicroLMS")){serviceName="MicroLMS"}else{if(process.execPath.includes("MeshCommander")){serviceName="MeshCommander"}else{serviceName="not_a_service"}}}if(serviceInstall==0){run(process.argv)}else{var serviceHost=require("service-host");var meshcmdService=new serviceHost({name:serviceName,startType:"AUTO_START"});meshcmdService.on("serviceStart",function onStart(){console.setDestination(console.Destinations.DISABLED);if(process.execPath.includes("MicroLMS")){run([process.execPath,"microlms"])}else{if(process.execPath.includes("MeshCommander")){run([process.execPath,"meshcommander"])}else{console.log("Aborting Service Start, because unknown binary: "+process.execPath);process.exit(1)}}});meshcmdService.on("serviceStop",function onStop(){console.log("Stopping service");process.exit()});meshcmdService.on("normalStart",function onNormalStart(){try{run(process.argv)}catch(a){console.log("ERROR: "+a)}});meshcmdService.run()}; \ No newline at end of file +var fs=require("fs");var os=require("os");var net=require("net");var http=require("http");var dgram=require("dgram");var httpHeaders=require("http-headers");var tcpserver=null;var broadcastSockets={};var multicastSockets={};var discoveryInterval=null;var membershipIPv4="239.255.255.235";var membershipIPv6="FF02:0:0:0:0:0:0:FE";var settings=null;var meshCmdVersion="***Mesh*Cmd*Version***";var amtLms=null,amtMei=null,amtMeiState=null;var wsstack=null,amtstack=null;var oswsstack=null,osamtstack=null;var amtMeiTmpState=null;var SMBiosTables=null;var globalDebugFlags=0;var Large_IntelAmtWebApp="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";var Medium_IntelAmtWebApp="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";var Small_IntelAmtWebApp="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";function onVerifyServer(b,a){if(a==null){a=b}try{for(var d in a){if(a[d].fingerprint.replace(/:/g,"")==settings.serverhttpshash){return}}}catch(c){}if(serverhash!=null){console.log("Error: Failed to verify server certificate.");throw"Invalid server certificate"}}function debug(a,b){if((settings.debuglevel!=null)&&(settings.debuglevel>=a)){console.log(b)}}function exit(b){if(b==null){b=0}try{process.exit(b)}catch(a){}}function getInstance(b,c){for(var a in b){if(b[a]["InstanceID"]==c){return b[a]}}return null}function md5hex(a){return require("MD5Stream").create().syncHash(a).toString("hex")}function guidToStr(a){return a.substring(6,8)+a.substring(4,6)+a.substring(2,4)+a.substring(0,2)+"-"+a.substring(10,12)+a.substring(8,10)+"-"+a.substring(14,16)+a.substring(12,14)+"-"+a.substring(16,20)+"-"+a.substring(20)}function parceArguments(a){var d={};for(var b in a){b=parseInt(b);if(a[b].startsWith("--")==true){var c=a[b].substring(2).toLowerCase(),e=true;if(((b+1)8){return"[...]"}if(e==undefined){return"[undefined]"}if(typeof e=="string"){if(b==0){return e}return'"'+(e.split("\0")[0])+'"'}if(typeof e=="buffer"){return"[buffer]"}if(typeof e!="object"){return e}var c="{"+(d?"\r\n":" ");for(var a in e){if(a!="_ObjectID"){c+=(addPad(b+2,d)+a+": "+objToString(e[a],b+2,d)+(d?"\r\n":" "))}}return c+addPad(b,d)+"}"}function addPad(b,d){var c="";for(var a=0;a=2){settings={action:j[1]}}}if(settings==null){settings={}}var p={};for(var m in settings){p[m.toLowerCase()]=settings[m]}settings=p;if((typeof h.action)=="string"){settings.action=h.action}if((typeof h.localport)=="string"){settings.localport=parseInt(h.localport)}if((typeof h.remotenodeid)=="string"){settings.remotenodeid=h.remotenodeid}if((typeof h.username)=="string"){settings.username=h.username}if((typeof h.password)=="string"){settings.password=h.password}if((typeof h.wss)=="string"){settings.wss=h.wss}if((typeof h.type)=="string"){settings.type=h.type}if((typeof h.user)=="string"){settings.username=h.user}if((typeof h.pass)=="string"){settings.password=h.pass}if((typeof h.host)=="string"){settings.hostname=h.host}if((typeof h.hostname)=="string"){settings.hostname=h.hostname}if((typeof h.serverid)=="string"){settings.serverid=h.serverid}if((typeof h.serverhttpshash)=="string"){settings.serverhttpshash=h.serverhttpshash}if((typeof h.remoteport)=="string"){settings.remoteport=parseInt(h.remoteport)}if((typeof h.out)=="string"){settings.output=h.out}if((typeof h.output)=="string"){settings.output=h.output}if((typeof h.debug)=="string"){settings.debuglevel=parseInt(h.debug)}if((typeof h.debugflags)=="string"){globalDebugFlags=parseInt(h.debugflags)}if((typeof h.script)=="string"){settings.script=h.script}if((typeof h.agent)=="string"){settings.agent=h.agent}if((typeof h.proxy)=="string"){settings.proxy=h.proxy}if(h.debug){try{waitForDebugger()}catch(k){}}if(h.noconsole){settings.noconsole=true}if(h.nocommander){settings.noconsole=true}if(h.lmsdebug){settings.lmsdebug=true}if(h.tls){settings.tls=true}if((j.length>1)&&(d.indexOf(j[1].toUpperCase())>=0)){settings.action=j[1]}if(settings.action==null){console.log("MeshCentral Command (MeshCmd) "+meshCmdVersion);console.log("No action specified, use MeshCmd like this:\r\n");console.log(" meshcmd [action] [arguments...]\r\n");console.log("Valid MeshCentral actions:");console.log(" Route - Map a local TCP port to a remote computer.");console.log("\r\nValid local actions:");console.log(" SMBios - Display System Management BIOS tables for this computer.");console.log(" RawSMBios - Display RAW System Management BIOS tables for this computer.");console.log(" MicroLMS - Run MicroLMS, allowing local access to Intel AMT.");console.log(" AmtInfo - Show Intel AMT version and activation state.");console.log(" AmtVersions - Show all Intel ME version information.");console.log(" AmtHashes - Show all Intel AMT trusted activation hashes.");console.log(" AmtCCM - Activate Intel AMT into Client Control Mode.");console.log(" AmtACM - Activate Intel AMT into Admin Control Mode.");console.log(" AmtDeactivate - Deactivate Intel AMT if activated in Client Control mode.");console.log(" AmtAcmDeactivate - Deactivate Intel AMT if activated in Admin Control mode.");console.log("\r\nValid local or remote actions:");console.log(" MeshCommander - Launch a local MeshCommander web server.");console.log(" AmtUUID - Show Intel AMT unique identifier.");console.log(" AmtAuditLog - Show the Intel AMT audit log.");console.log(" AmtLoadWebApp - Load MeshCommander in Intel AMT 11.6+ firmware.");console.log(" AmtClearWebApp - Clear everything from Intel AMT web storage.");console.log(" AmtStorageState - Show contents of the Intel AMT web storage.");console.log(" AmtSaveState - Save all Intel AMT WSMAN object to file.");console.log(" AmtPresence - Heartbeat a local Intel AMT watchdog agent.");console.log(" AmtScript - Run .mescript on Intel AMT.");console.log("\r\nHelp on a specific action using:\r\n");console.log(" meshcmd help [action]");exit(1);return}if(settings.action=="help"){if(j.length<=2){d.shift();console.log("Help usage:\r\n\r\n MeshCmd help [action]\r\n\r\nValid actions are: "+d.join(", ")+".");exit(1);return}var a=j[2].toLowerCase();if(a=="route"){console.log("The route action is used along with a MeshCentral account to map a local TCP port to a remote port on any computer on your MeshCentral account. This action requires many arguments, to avoid specifying them all it's best to download the meshaction.txt file from the web site and place it in the current folder. Example usage:\r\n\r\n (Place meshaction.txt file in current folder)\r\n meshcmd route --pass myAccountPassword")}else{if(a=="smbios"){console.log("SMBios action will display this computer's system management BIOS information. Example usage:\r\n\r\n meshcmd smbios --out smbios.txt\r\n");console.log("\rOptional arguments:\r\n");console.log(" --output [filename] Optional filename to write the results to.")}else{if(a=="rawsmbios"){console.log("RawSMBios action will display this computer's system management BIOS information in raw hexdecimal form. Example usage:\r\n\r\n meshcmd rawsmbios --out smbios.txt\r\n");console.log("\rOptional arguments:\r\n");console.log(" --output [filename] Optional filename to write the results to.")}else{if(a=="amtinfo"){console.log("AmtInfo action will get the version and activation state of Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Example usage:\r\n\r\n meshcmd amtinfo")}else{if((a=="amtversion")||(a=="amtversions")){console.log("AmtVersions will display all version information about Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Example usage:\r\n\r\n meshcmd amtversions")}else{if(a=="amthashes"){console.log("Amthashes will display all trusted activations hashes for Intel AMT on this computer. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd amthashes")}else{if((a=="microlms")||(a=="lms")||(a=="amtlms")){console.log("Starts MicroLMS on this computer, allowing local access to Intel AMT on TCP ports 16992 and 16993 when applicable. The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. These certificates hashes are used by Intel AMT when performing activation into ACM mode. Example usage:\r\n\r\n meshcmd microlms");console.log("\r\nPossible arguments:\r\n");console.log(" --noconsole MeshCommander for LMS will no be available on port 16994.");console.log("\r\nRun as a background service:\r\n");console.log(" microlms install/uninstall/start/stop.")}else{if(a=="amtccm"){console.log('AmtCCM will attempt to activate Intel AMT on this computer into client control mode (CCM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be in "pre-provisioning" state for this command to work and a administrator password must be provided. Example usage:\r\n\r\n meshcmd amtccm --pass mypassword')}else{if(a=="amtacm"){console.log('AmtACM will attempt to activate Intel AMT on this computer into admin control mode (ACM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be in "pre-provisioning" state for this command to work and a administrator password and provisioning certificate must be provided. Example usage:\r\n\r\n meshcmd amtacm --wss servername:port');console.log("\r\nPossible arguments:\r\n");console.log(" --wss [server:port] The address of the AMT remote configuration server.")}else{if(a=="amtdeactivate"){console.log("AmtDeactivate will attempt to deactivate Intel AMT on this computer when in client control mode (CCM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be activated in client control mode for this command to work. Example usage:\r\n\r\n meshcmd amtdeactivate")}else{if(a=="amtacmdeactivate"){console.log("AmtACMDeactivate will attempt to deactivate Intel AMT on this computer when in admin control mode (ACM). The command must be run on a computer with Intel AMT, must run as administrator and the Intel management driver must be installed. Intel AMT must be activated in admin control mode for this command to work. Example usage:\r\n\r\n meshcmd amtacmdeactivate");console.log("\r\nPossible arguments:\r\n");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --type [partial/full] Specifies to perform partial or full unprovision.")}else{if(a=="amtuuid"){console.log("AmtUUID action will get the unique identifier of the local or remote Intel AMT computer. By default, the local UUID is obtained unless a host is specified. Intel AMT must be activated for this command to work. Example usage:\r\n\r\n meshcmd amtuuid --host 1.2.3.4 --user admin --pass mypassword --tls");console.log("\r\nPossible arguments:\r\n");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{if((a=="amtloadwebapp")||(a=="amtloadsmallwebapp")||(a=="amtloadlargewebapp")||(a=="amtclearwebapp")||(a=="amtstoragestate")){console.log('AmtLoadWebApp action will load MeshCommander into Intel AMT 11.6 or higher. If the computer is in ACM mode, MeshCommander will replace the default index.htm on HTTP/16992 or HTTPS/16993. If Intel AMT is in CCM mode, MeshCommander will be installed alongside the default web page and will be accessible in the "Web Applications" section. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtloadwebapp --host 1.2.3.4 --user admin --pass mypassword --tls');console.log("\r\nPossible arguments:\r\n");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{if(a=="amtclearwebstorage"){console.log("AmtClearWebStorage will clear the web storage of Intel AMT, removing any loaded firmware version of MeshCommander. This command can clear the local or a remote Intel AMT computer. By default, the local computer storage is cleared unless a host is specified. Intel AMT must be activated for this command to work. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtclearwebstorage --host 1.2.3.4 --user admin --pass mypassword --tls");console.log("\r\nPossible arguments:\r\n");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{if(a=="amtstoragestate"){console.log("AmtStorageState will display the content of the web storage of Intel AMT including any loaded firmware version of MeshCommander. This command can read the storage state of a local or remote Intel AMT computer. By default, the local computer storage state is displayed unless a host is specified. Intel AMT must be activated for this command to work. This action works on Intel AMT 11.6 and higher only. Example usage:\r\n\r\n meshcmd amtstoragestate --host 1.2.3.4 --user admin --pass mypassword --tls");console.log("\r\nPossible arguments:\r\n");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{if(a=="amtsavestate"){console.log("AmtSaveState action will fetch all the entire state of Intel AMT and save it as a JSON file. This action will take multiple minutes to perform. The command will fetch the local computer state unless host is specified. Intel AMT must be ativated for this command to work. Example usage:\r\n\r\n meshcmd amtsavestate --host 1.2.3.4 --user admin --pass mypassword --tls --output state.json");console.log("\r\nPossible arguments:\r\n");console.log(" --output [filename] The output file for the Intel AMT state in JSON format.");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{if(a=="amtpresence"){console.log("AmtPresence will heartbeat a local Intel AMT watchdog agent. Example usage:\r\n\r\n meshcmd amtpresence --agent B4B6A24C-255E-A75C-F5E8-B00B4D946AA7");console.log("\r\nPossible arguments:\r\n");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --agent [uuid] The unique identifier of the watchdog agent.")}else{if(a=="amtscript"){console.log("AmtScript will run a .mescript file on the local or remote Intel AMT. Script files can be built using the MeshCommander script editor and be used to setup or perform actions on Intel AMT. Example usage:\r\n\r\n meshcmd amtscript --script myscript.mescript --host 1.2.3.4 --user admin --pass mypassword --tls");console.log("\r\nPossible arguments:\r\n");console.log(" --script [filename] The script file to run on Intel AMT.");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{if(a=="meshcommander"){console.log("This action launched a local web server that hosts MeshCommander, a Intel AMT management console.");console.log("\r\nPossible arguments:\r\n");console.log(" --localport [port] Local port used for the web server, 3000 is default.");console.log("\r\nRun as a background service:\r\n");console.log(" meshcommander install/uninstall/start/stop.")}else{if(a=="amtauditlog"){console.log("AmtAuditLog action will fetch the local or remote audit log. If used localy, no username/password is required. Example usage:\r\n\r\n meshcmd amtauditlog --host 1.2.3.4 --user admin --pass mypassword --tls --output audit.json");console.log("\r\nPossible arguments:\r\n");console.log(" --output [filename] The output file for the Intel AMT state in JSON format.");console.log(" --host [hostname] The IP address or DNS name of Intel AMT, 127.0.0.1 is default.");console.log(" --user [username] The Intel AMT login username, admin is default.");console.log(" --pass [password] The Intel AMT login password.");console.log(" --tls Specifies that TLS must be used.")}else{d.shift();console.log("Invalid action, usage:\r\n\r\n meshcmd help [action]\r\n\r\nValid actions are: "+d.join(", ")+".")}}}}}}}}}}}}}}}}}}}}exit(1);return}settings.action=settings.action.toLowerCase();debug(1,"Settings: "+JSON.stringify(settings));if((typeof settings.proxy)=="string"){var n=settings.proxy.split(":"),o=(n.length==2)?parseInt(n[1]):0;if((n.length!=2)||(n[0].length<1)||(o<1)||(o>65535)){console.log('Invalid "proxy" specified, use --proxy [hostname]:[port].');exit(1);return}try{require("global-tunnel").initialize({host:n[0],port:o})}catch(l){console.log(l);exit(1);return}console.log("Proxy set to "+n[0]+":"+o)}if(settings.action=="smbios"){SMBiosTables=require("smbios");SMBiosTables.get(function(e){var t=SMBiosTables.parse(e);var s=objToString(t,0,"\r\n");if(settings.output==null){console.log(s)}else{var q=fs.openSync(settings.output,"w");fs.writeSync(q,Buffer.from(s,"utf8"));fs.closeSync(q)}exit(1)})}else{if(settings.action=="rawsmbios"){SMBiosTables=require("smbios");SMBiosTables.get(function(e){var u="";for(var s in e){var r=false;for(var t in e[s]){if(e[s][t].length>0){if(r==false){u+=("Table type #"+s+((SMBiosTables.smTableTypes[s]==null)?"":(", "+SMBiosTables.smTableTypes[s])))+"\r\n";r=true}u+=(" "+e[s][t].toString("hex"))+"\r\n"}}}if(settings.output==null){console.log(u)}else{var q=fs.openSync(settings.output,"w");fs.writeSync(q,Buffer.from(u,"utf8"));fs.closeSync(q)}exit(1)})}else{if(settings.action=="route"){if((settings.localport==null)||(typeof settings.localport!="number")||(settings.localport<0)||(settings.localport>65535)){console.log('No or invalid "localPort" specified, use --localport [localport].');exit(1);return}if((settings.remotenodeid==null)||(typeof settings.remotenodeid!="string")){console.log('No or invalid "remoteNodeId" specified.');exit(1);return}if((settings.username==null)||(typeof settings.username!="string")||(settings.username=="")){console.log('No or invalid "username" specified, use --username [username].');exit(1);return}if((settings.password==null)||(typeof settings.password!="string")||(settings.password=="")){console.log('No or invalid "password" specified, use --password [password].');exit(1);return}if((settings.serverid==null)||(typeof settings.serverid!="string")||(settings.serverid.length!=96)){console.log('No or invalid "serverId" specified.');exit(1);return}if((settings.serverhttpshash==null)||(typeof settings.serverhttpshash!="string")||(settings.serverhttpshash.length!=96)){console.log('No or invalid "serverHttpsHash" specified.');exit(1);return}if((settings.remoteport==null)||(typeof settings.remoteport!="number")||(settings.remoteport<0)||(settings.remoteport>65535)){console.log('No or invalid "remotePort" specified, use --remoteport [remoteport].');exit(1);return}if(settings.serverurl!=null){startRouter()}else{discoverMeshServer()}}else{if((settings.action=="amtloadwebapp")||(settings.action=="amtloadsmallwebapp")||(settings.action=="amtloadlargewebapp")||(settings.action=="amtclearwebapp")||(settings.action=="amtstoragestate")){if((settings.password==null)||(typeof settings.password!="string")||(settings.password=="")){console.log('No or invalid "password" specified, use --password [password].');exit(1);return}if((settings.hostname==null)||(typeof settings.hostname!="string")||(settings.hostname=="")){settings.hostname="127.0.0.1"}if((settings.username==null)||(typeof settings.username!="string")||(settings.username=="")){settings.username="admin"}settings.protocol="http:";settings.localport=16992;debug(1,"Settings: "+JSON.stringify(settings));digest=require("http-digest").create(settings.username,settings.password);digest.http=require("http");if(settings.action=="amtstoragestate"){getAmtStorage(function(q,e){if(q==200){console.log("Storage State: "+JSON.stringify(e,null,2));exit();return}else{console.log("Unable to read storage state.");exit();return}})}else{if(settings.action=="amtloadwebapp"){settings.webapp=Medium_IntelAmtWebApp}else{if(settings.action=="amtloadsmallwebapp"){settings.webapp=Small_IntelAmtWebApp}else{if(settings.action=="amtloadlargewebapp"){settings.webapp=Large_IntelAmtWebApp}else{if(settings.action=="amtclearwebapp"){settings.webapp=null}}}}nextStepStorageUpload()}}else{if((settings.action=="amtversion")||(settings.action=="amtversions")||(settings.action=="amtver")){var g,f;try{g=require("amt-mei");f=new g()}catch(l){console.log(l);exit(1);return}f.on("error",function(q){console.log("ERROR: "+q);exit(1);return});f.getVersion(function(e){console.log("MEI Version = "+e.BiosVersion.toString());for(var q in e.Versions){console.log(e.Versions[q].Description+" = "+e.Versions[q].Version)}exit(1);return})}else{if(settings.action=="amthashes"){var g,f;try{g=require("amt-mei");f=new g()}catch(l){console.log(l);exit(1);return}f.on("error",function(q){console.log("ERROR: "+q);exit(1);return});f.getHashHandles(function(e){exitOnCount=e.length;for(var q=0;q100){lmsNotifications.shift()}var l=Buffer.concat([Buffer.from("0900","hex"),Buffer.from(JSON.stringify(k))]);for(var j in lmsControlSockets){lmsControlSockets[j].write(l)}}}});amtLms.on("bind",function(g){if(g[16992]){this.removeAllListeners("bind")}else{return}amtLms.connected=true;this.promise._res();if(settings.noconsole!==true){startMeshCommanderLms();tempTimer=setTimeout(function(){delete tempTimer;setupMeiOsAdmin(b,2)},100)}else{tempTimer=setTimeout(function(){delete tempTimer;setupMeiOsAdmin(b,1)},100)}});return(f)}function startMeshCommanderLms(){var b="C2ZfnIbUEl7w4c1S1Xbd";var a="77u/PCFET0NUWVBFIGh0bWw+DQo8aHRtbCBzdHlsZT0iaGVpZ2h0OjEwMCUiPg0KPGhlYWQ+DQogICAgPG1ldGEgaHR0cC1lcXVpdj0iWC1VQS1Db21wYXRpYmxlIiBjb250ZW50PSJJRT1lZGdlIj4gDQogICAgPG1ldGEgY29udGVudD0idGV4dC9odG1sO2NoYXJzZXQ9dXRmLTgiIGh0dHAtZXF1aXY9IkNvbnRlbnQtVHlwZSI+DQogICAgPG1ldGEgbmFtZT0iZm9ybWF0LWRldGVjdGlvbiIgY29udGVudD0idGVsZXBob25lPW5vIj4NCiAgICA8bGluayByZWw9Imljb24iIHR5cGU9ImltYWdlL3BuZyIgaHJlZj0iZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvPSI+IDwhLS0gU3RvcCBmYXZpY29uLmljbyBmcm9tIGxvYWRpbmcgLS0+DQogICAgPHN0eWxlPmJvZHkgew0KICAgIGhlaWdodDogMTAwJTsNCiAgICBtYXgtaGVpZ2h0OiAxMDAlOw0KICAgIG92ZXJmbG93OiBoaWRkZW47DQogICAgZm9udC1mYW1pbHk6IGFyaWFsLCBoZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQogICAgZm9udC1zaXplOiA5cHQ7DQogICAgY29sb3I6IGJsYWNrOw0KICAgIGJhY2tncm91bmQ6IHdoaXRlOw0KICAgIG1hcmdpbi10b3A6IDA7DQogICAgbWFyZ2luLWxlZnQ6IDA7DQogICAgbWFyZ2luLXJpZ2h0OiAwOw0KICAgIC13ZWJraXQtdG91Y2gtY2FsbG91dDogbm9uZTsNCiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lOw0KICAgIC1raHRtbC11c2VyLXNlbGVjdDogbm9uZTsNCiAgICAtbW96LXVzZXItc2VsZWN0OiBub25lOw0KICAgIC1tcy11c2VyLXNlbGVjdDogbm9uZTsNCiAgICB1c2VyLXNlbGVjdDogbm9uZTsNCn0NCg0KbGkgew0KICAgIG1hcmdpbjogMDsNCiAgICBwYWRkaW5nOiAwOw0KfQ0KDQpsYWJlbCB7DQogICAgZGlzcGxheTogYmxvY2s7DQogICAgY29sb3I6IHdpbmRvd3RleHQ7DQogICAgYmFja2dyb3VuZC1jb2xvcjogd2luZG93Ow0KICAgIG1hcmdpbjogMDsNCiAgICBwYWRkaW5nOiAwOw0KICAgIHdpZHRoOiAxMDAlOw0KfQ0KDQogICAgbGFiZWw6aG92ZXIgew0KICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiBoaWdobGlnaHQ7DQogICAgICAgIGNvbG9yOiBoaWdobGlnaHR0ZXh0Ow0KICAgIH0NCg0KYTp2aXNpdGVkIHsNCiAgICB0ZXh0LWRlY29yYXRpb246IG5vbmU7DQogICAgY29sb3I6ICMwNGY7DQp9DQoNCmE6bGluayB7DQogICAgdGV4dC1kZWNvcmF0aW9uOiBub25lOw0KICAgIGNvbG9yOiAjMDRmOw0KfQ0KDQphOmhvdmVyIHsNCiAgICBjb2xvcjogIzU1NTsNCn0NCg0KaDEgew0KICAgIGZvbnQtc2l6ZTogMTFwdDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBjb2xvcjogYmxhY2s7DQogICAgbWFyZ2luLWxlZnQ6IDVweDsNCiAgICBtYXJnaW4tdG9wOiAxMHB4Ow0KICAgIG1hcmdpbi1ib3R0b206IDZweDsNCn0NCg0KaDIgew0KICAgIGZvbnQtc2l6ZTogOXB0Ow0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGNvbG9yOiBibGFjazsNCiAgICBtYXJnaW4tbGVmdDogNnB4Ow0KICAgIG1hcmdpbi10b3A6IDZweDsNCiAgICBtYXJnaW4tYm90dG9tOiAwOw0KfQ0KDQpwIHsNCiAgICBtYXJnaW4tbGVmdDogNnB4Ow0KICAgIG1hcmdpbi10b3A6IDRweDsNCiAgICBtYXJnaW4tYm90dG9tOiAwOw0KICAgIG1hcmdpbi1yaWdodDogMnB4Ow0KfQ0KDQp0ZCB7DQogICAgZm9udC1zaXplOiA5cHQ7DQp9DQoNCnRoIHsNCiAgICBmb250LXNpemU6IDlwdDsNCn0NCg0KICAgIHRoOmhvdmVyIHsNCiAgICAgICAgY3Vyc29yOiBwb2ludGVyOw0KICAgICAgICBiYWNrZ3JvdW5kOiAjYWFhOw0KICAgIH0NCg0KLmhlYWRlciB7DQogICAgcG9zaXRpb246IGZpeGVkOw0KICAgIHRvcDogMDsNCiAgICBsZWZ0OiAwOw0KICAgIHJpZ2h0OiAwOw0KICAgIGhlaWdodDogNjdweDsNCiAgICBiYWNrZ3JvdW5kOiAjMDM2Ow0KICAgIC8qIGJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICM2YTY5NjAgMCUsIzQyNDEzYyAxMDAlKTsgKi8NCn0NCg0KLnByb2dyZXNzYmFyIHsNCiAgICBwb3NpdGlvbjogZml4ZWQ7DQogICAgdG9wOiA2N3B4Ow0KICAgIGxlZnQ6IDA7DQogICAgcmlnaHQ6IDA7DQogICAgaGVpZ2h0OiAycHg7DQogICAgYmFja2dyb3VuZDogIzAzNjsNCn0NCg0KLmluIHsNCiAgICBtYXJnaW4tbGVmdDogNDBweDsNCn0NCg0KLmxvZyB7DQogICAgYmFja2dyb3VuZDogI2JiYmFiNTsNCn0NCg0KLmxvZzEgew0KICAgIGJhY2tncm91bmQ6ICNiYmJhYjU7DQp9DQoNCi5sb2cgdGJvZHkgdHI6bnRoLWNoaWxkKG9kZCkgew0KICAgIGJhY2tncm91bmQ6ICNlOGVlZmU7DQp9DQoNCi5mdWxsY2VsbCB7DQogICAgcG9zaXRpb246IGZpeGVkOw0KICAgIHRvcDogNjlweDsNCiAgICByaWdodDogMDsNCiAgICBib3R0b206IDA7DQogICAgbGVmdDogMHB4Ow0KICAgIG92ZXJmbG93OiBoaWRkZW47DQp9DQoNCi5tYWluY2VsbCB7DQogICAgcG9zaXRpb246IGZpeGVkOw0KICAgIHRvcDogNjlweDsNCiAgICByaWdodDogMDsNCiAgICBib3R0b206IDA7DQogICAgbGVmdDogMTU2cHg7DQogICAgb3ZlcmZsb3c6IGhpZGRlbjsNCiAgICBwYWRkaW5nLWxlZnQ6IDJweDsNCiAgICB2ZXJ0aWNhbC1hbGlnbjogdG9wOw0KfQ0KDQoubmF2YmFyIHsNCiAgICBwb3NpdGlvbjogZml4ZWQ7DQogICAgdG9wOiA2OXB4Ow0KICAgIGxlZnQ6IDA7DQogICAgYm90dG9tOiAwOw0KICAgIHdpZHRoOiAxNTZweDsNCiAgICBib3JkZXItcmlnaHQ6IDJweCBzb2xpZCAjQjBDNkZDOw0KICAgIHZlcnRpY2FsLWFsaWduOiB0b3A7DQogICAgYmFja2dyb3VuZDogIzAzNjsNCiAgICBiYWNrZ3JvdW5kOiBsaW5lYXItZ3JhZGllbnQodG8gYm90dG9tLCAjYmZkMWZjIDAlLCNlOGVlZmUgMTAwJSk7DQp9DQoNCi5uYXYxIHsNCiAgICBwYWRkaW5nOiAxcHggMHB4IDFweCA4cHg7DQogICAgbWFyZ2luOiAwcHg7DQogICAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogICAgY29sb3I6IGJsYWNrOw0KICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KfQ0KDQoubmF2MiB7DQogICAgbWFyZ2luLWxlZnQ6IDMycHg7DQogICAgbWFyZ2luLXRvcDogMDsNCiAgICBjb2xvcjogYmxhY2s7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KfQ0KDQouciB7DQogICAgZm9udC1zaXplOiAxMXB0Ow0KfQ0KDQoucjAgew0KICAgIGJhY2tncm91bmQ6IHdoaXRlOw0KfQ0KDQoucjEgew0KICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCBncmF5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCi5yMiB7DQogICAgdGV4dC1hbGlnbjogbGVmdDsNCn0NCg0KLnIzIHsNCiAgICBib3JkZXItYm90dG9tOiAxcHggc29saWQgZ3JheTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQogICAgLnIzOmhvdmVyIHsNCiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogIzgzODI3YjsNCiAgICAgICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIH0NCg0KLnNwcmVhZCB7DQogICAgaGVpZ2h0OiAxMDAlOw0KICAgIHdpZHRoOiAxMDAlOw0KICAgIGJhY2tncm91bmQtY29sb3I6IHdoaXRlOw0KfQ0KDQoudGltZXIgew0KICAgIGJvcmRlcjogMXB4IHNvbGlkICNhYmNhZTE7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI2FiY2FlMTsNCn0NCg0KLnRtIHsNCiAgICBmb250LXNpemU6IDdwdDsNCn0NCg0KLnRvcDEgew0KICAgIGZvbnQtc2l6ZTogMjBwdDsNCiAgICBmb250LXdlaWdodDogYm9sZDsNCiAgICBjb2xvcjogI0M4QzhDODsNCiAgICBtYXJnaW4tdG9wOiA2cHg7DQogICAgbWFyZ2luLWxlZnQ6IDEwcHg7DQp9DQoNCi50b3AyIHsNCiAgICBjb2xvcjogI0M4QzhDODsNCiAgICBtYXJnaW4tbGVmdDogMTBweDsNCn0NCg0KLndhcm4gew0KICAgIGZvbnQtd2VpZ2h0OiBib2xkOw0KICAgIGNvbG9yOiAjYzAwMDAwOw0KfQ0KDQouaWNvbjEgew0KICAgIHdpZHRoOiAxNHB4Ow0KICAgIGhlaWdodDogMTVweDsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybCgiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoRUFBUUFMTVBBTEMyeXg5RHIwbHkyV3VSOEZkdXVoUXlsb09XenpkZ3ltNkd5WnVxMS92NytxQ2hwY2pKMEplWG03ZTV2di8vL3lINUJBRUFBQThBTEFBQUFBQVFBQkFBQUFSeThNbEpxMTJPTWJlc2JFQXlqRU1DTkJWb2pJb3lDTWhKQVlZZ0RPMXd3TUMwSkxhZzRFQThHRG9QQnlLWWFCRUNVSUpEd2hnT0V3d0ZvZ0FOTUtqRFF3Q3JNSENoM3lSQ1BNNXVvOVBId3RBbEU4N0hDZUE1ZG5JSlBSTWdUekY3QlFRSktCUXFmQVFHTWg0WUdod2VsUllSQURzPSIpOw0KfQ0KDQouaWNvbjIgew0KICAgIHdpZHRoOiAxNHB4Ow0KICAgIGhlaWdodDogMTVweDsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybCgiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoRUFBUUFKRURBUERWTWFtTUR3QUFBUC8vL3lINUJBRUFBQU1BTEFBQUFBQVFBQkFBQUFJeW5JK3BCckFhV25pb05XcWluYlFKY1QzYUp6MFdHU1lhZ0FKY3RhME9JbHNiZklMMlViZWxEUXhLQXNTaXNUakRJQW9BT3c9PSIpOw0KfQ0KDQouaWNvbjMgew0KICAgIHdpZHRoOiAxNHB4Ow0KICAgIGhlaWdodDogMTVweDsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogbm8tcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6IHVybCgiZGF0YTppbWFnZS9naWY7YmFzZTY0LFIwbEdPRGxoRUFBUUFLSUhBTEVjSGVYdDdhQ2hwY2pKMEplWG03ZTV2di8vLy8vLy95SDVCQUVBQUFjQUxBQUFBQUFRQUJBQUFBTmFlTHJjTG1XTUlwd2lwWkJOSUdsWUI0ekFwakZhWUJBallRVFk0aFhHU3FoQ1dSM2FTTCtCbkU4eElBRUVnYUJ4UURRaUE0V2xvZ2VnU1FMRjRVSEFzbzRHaG1KbkVTVmtSN0FxUTJRa2NVSFUxc2tDa1ZBc2VFY0NBRHM9Iik7DQp9DQoNCi5pdGVtQmFyIHsNCiAgICBwYWRkaW5nOiA3cHg7DQogICAgbWluLWhlaWdodDogMjBweDsNCiAgICBtYXJnaW4tdG9wOiA0cHg7DQogICAgbWFyZ2luLXJpZ2h0OiA4cHg7DQogICAgd2lkdGg6IGF1dG87DQogICAgYm9yZGVyLXJhZGl1czogOHB4Ow0KICAgIGJhY2tncm91bmQtY29sb3I6ICM4YzhiODE7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KfQ0KDQouY29tcHV0ZXJpdGVtY2lyIHsNCiAgICB3aWR0aDogMTJweDsNCiAgICBoZWlnaHQ6IDEycHg7DQogICAgYm9yZGVyLXJhZGl1czogNHB4Ow0KICAgIGJhY2tncm91bmQ6IGdyYXk7DQogICAgbWFyZ2luLXJpZ2h0OjRweDsNCn0NCg0KLmNvbXB1dGVyaXRlbSB7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIHdpZHRoOiBhdXRvOw0KICAgIC8qDQogICAgYm9yZGVyLXJhZGl1czogNXB4Ow0KICAgIGJhY2tncm91bmQtY29sb3I6ICNhNmE1YTA7DQogICAgKi8NCiAgICBoZWlnaHQ6IDI4cHg7DQogICAgbWFyZ2luOiA0cHg7DQogICAgcGFkZGluZzogMnB4Ow0KfQ0KDQogICAgLmNvbXB1dGVyaXRlbTpob3ZlciB7DQogICAgICAgIGJhY2tncm91bmQtY29sb3I6ICM4MzgyN2I7DQogICAgfQ0KDQoudXMgew0KICAgIC13ZWJraXQtdG91Y2gtY2FsbG91dDogaW5pdGlhbDsNCiAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBhdXRvOw0KICAgIC1raHRtbC11c2VyLXNlbGVjdDogdGV4dDsNCiAgICAtbW96LXVzZXItc2VsZWN0OiB0ZXh0Ow0KICAgIC1tcy11c2VyLXNlbGVjdDogdGV4dDsNCiAgICB1c2VyLXNlbGVjdDogdGV4dDsNCn0NCg0KDQovKiBTdHlsZXMgYmVsb3cgYXJlIG9ubHkgdXNlZCBpbiBOb2RlSlMsIFdlYlNpdGUgY29tcGlsZXIgc2hvdWxkIHJlbW92ZSB0aGVzZSBpbiB0aGUgZnV0dXJlICovDQoNCi50b3BDZWxsIHsNCiAgICBiYWNrZ3JvdW5kLWltYWdlOnVybCgnaW1hZ2VzLWNvbW1hbmRlci9sb2dvYmFjay5wbmcnKTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpuby1yZXBlYXQ7DQp9DQoNCi5pMSB7DQogICAgYmFja2dyb3VuZDogdXJsKGltYWdlcy1jb21tYW5kZXIvaWNvbnM1MC5wbmcpIDBweCAwcHg7DQogICAgaGVpZ2h0OiA1MHB4Ow0KICAgIHdpZHRoOiA1MHB4Ow0KICAgIGN1cnNvcjogcG9pbnRlcjsNCiAgICBib3JkZXI6IG5vbmU7DQp9DQoNCi5pMiB7DQogICAgYmFja2dyb3VuZDogdXJsKGltYWdlcy1jb21tYW5kZXIvaWNvbnM1MC5wbmcpIC01MHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmkzIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczUwLnBuZykgLTEwMHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmk0IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczUwLnBuZykgLTE1MHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmk1IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczUwLnBuZykgLTIwMHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmk2IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczUwLnBuZykgLTI1MHB4IDBweDsNCiAgICBoZWlnaHQ6IDUwcHg7DQogICAgd2lkdGg6IDUwcHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmoxIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczI2LnBuZykgMHB4IDBweDsNCiAgICBoZWlnaHQ6IDI2cHg7DQogICAgd2lkdGg6IDI2cHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmoyIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczI2LnBuZykgLTI2cHggMHB4Ow0KICAgIGhlaWdodDogMjZweDsNCiAgICB3aWR0aDogMjZweDsNCiAgICBjdXJzb3I6IHBvaW50ZXI7DQogICAgYm9yZGVyOiBub25lOw0KfQ0KDQouajMgew0KICAgIGJhY2tncm91bmQ6IHVybChpbWFnZXMtY29tbWFuZGVyL2ljb25zMjYucG5nKSAtNTJweCAwcHg7DQogICAgaGVpZ2h0OiAyNnB4Ow0KICAgIHdpZHRoOiAyNnB4Ow0KICAgIGN1cnNvcjogcG9pbnRlcjsNCiAgICBib3JkZXI6IG5vbmU7DQp9DQoNCi5qNCB7DQogICAgYmFja2dyb3VuZDogdXJsKGltYWdlcy1jb21tYW5kZXIvaWNvbnMyNi5wbmcpIC03OHB4IDBweDsNCiAgICBoZWlnaHQ6IDI2cHg7DQogICAgd2lkdGg6IDI2cHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmo1IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczI2LnBuZykgLTEwNHB4IDBweDsNCiAgICBoZWlnaHQ6IDI2cHg7DQogICAgd2lkdGg6IDI2cHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmo2IHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9pY29uczI2LnBuZykgLTEzMHB4IDBweDsNCiAgICBoZWlnaHQ6IDI2cHg7DQogICAgd2lkdGg6IDI2cHg7DQogICAgY3Vyc29yOiBwb2ludGVyOw0KICAgIGJvcmRlcjogbm9uZTsNCn0NCg0KLmdyYXkgew0KICAgIC8qZmlsdGVyOiB1cmwoImRhdGE6aW1hZ2Uvc3ZnK3htbDt1dGY4LCZsdDtzdmcgeG1sbnM9XCdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wnJmd0OyZsdDtmaWx0ZXIgaWQ9XCdncmF5c2NhbGVcJyZndDsmbHQ7ZmVDb2xvck1hdHJpeCB0eXBlPVwnbWF0cml4XCcgdmFsdWVzPVwnMC4zMzMzIDAuMzMzMyAwLjMzMzMgMCAwIDAuMzMzMyAwLjMzMzMgMC4zMzMzIDAgMCAwLjMzMzMgMC4zMzMzIDAuMzMzMyAwIDAgMCAwIDAgMSAwXCcvJmd0OyZsdDsvZmlsdGVyJmd0OyZsdDsvc3ZnJmd0OyNncmF5c2NhbGUiKTsqLyAvKiBGaXJlZm94IDEwKywgRmlyZWZveCBvbiBBbmRyb2lkICovDQogICAgZmlsdGVyOiBncmF5OyAvKiBJRTYtOSAqLw0KICAgIC13ZWJraXQtZmlsdGVyOiBncmF5c2NhbGUoMTAwJSkgb3BhY2l0eSg2MCUpOyAvKiBDaHJvbWUgMTkrLCBTYWZhcmkgNissIFNhZmFyaSA2KyBpT1MgKi8NCn0NCg0KLmcxIHsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwJSAwJTsNCiAgICB3aWR0aDogMTRweDsNCiAgICBoZWlnaHQ6IDEwMCU7DQogICAgZmxvYXQ6IGxlZnQ7DQogICAgLyogZmFsbGJhY2sgKE9wZXJhKSAqLw0KICAgIC8qIE1vemlsbGE6ICovDQogICAgLyogQ2hyb21lLCBTYWZhcmk6Ki8NCiAgICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsICNmZmZmZmYgMCUsICNjOWM5YzkgMTAwJSk7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI2M5YzljOTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtYXR0YWNobWVudDogc2Nyb2xsOw0KfQ0KDQouZzIgew0KICAgIGJhY2tncm91bmQtcG9zaXRpb246IDAlIDAlOw0KICAgIHdpZHRoOiAxNHB4Ow0KICAgIGhlaWdodDogMTAwJTsNCiAgICBmbG9hdDogcmlnaHQ7DQogICAgLyogZmFsbGJhY2sgKE9wZXJhKSAqLw0KICAgIC8qIE1vemlsbGE6ICovDQogICAgLyogQ2hyb21lLCBTYWZhcmk6Ki8NCiAgICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsICNjOWM5YzkgMCUsICNmZmZmZmYgMTAwJSk7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI2M5YzljOTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtYXR0YWNobWVudDogc2Nyb2xsOw0KfQ0KDQouZzFzIHsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwJSAwJTsNCiAgICB3aWR0aDogMTRweDsNCiAgICBoZWlnaHQ6IDEwMCU7DQogICAgZmxvYXQ6IGxlZnQ7DQogICAgLyogZmFsbGJhY2sgKE9wZXJhKSAqLw0KICAgIC8qIE1vemlsbGE6ICovDQogICAgLyogQ2hyb21lLCBTYWZhcmk6Ki8NCiAgICBiYWNrZ3JvdW5kLWltYWdlOiBsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsICNmZmZmZmYgMCUsICNhMGEwYTAgMTAwJSk7DQogICAgYmFja2dyb3VuZC1jb2xvcjogI2EwYTBhMDsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDogcmVwZWF0Ow0KICAgIGJhY2tncm91bmQtYXR0YWNobWVudDogc2Nyb2xsOw0KfQ0KDQouZzJzIHsNCiAgICBiYWNrZ3JvdW5kLXBvc2l0aW9uOiAwJSAwJTsNCiAgICB3aWR0aDogMTRweDsNCiAgICBoZWlnaHQ6IDEwMCU7DQogICAgZmxvYXQ6IHJpZ2h0Ow0KICAgIC8qIGZhbGxiYWNrIChPcGVyYSkgKi8NCiAgICAvKiBNb3ppbGxhOiAqLw0KICAgIC8qIENocm9tZSwgU2FmYXJpOiovDQogICAgYmFja2dyb3VuZC1pbWFnZTogbGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCAjYTBhMGEwIDAlLCAjZmZmZmZmIDEwMCUpOw0KICAgIGJhY2tncm91bmQtY29sb3I6ICNhMGEwYTA7DQogICAgYmFja2dyb3VuZC1yZXBlYXQ6IHJlcGVhdDsNCiAgICBiYWNrZ3JvdW5kLWF0dGFjaG1lbnQ6IHNjcm9sbDsNCn0NCg0KDQoubGJidXR0b24gew0KICAgIHdpZHRoOjQ0cHg7DQogICAgaGVpZ2h0OjQ0cHg7DQogICAgYm9yZGVyLXJhZGl1czo1cHg7DQogICAgYmFja2dyb3VuZC1jb2xvcjp3aGl0ZTsNCiAgICBtYXJnaW4tbGVmdDo0cHg7DQogICAgbWFyZ2luLXRvcDo0cHg7DQogICAgcG9zaXRpb246cmVsYXRpdmU7DQogICAgY3Vyc29yOnBvaW50ZXI7DQogICAgb3BhY2l0eTowLjU7DQp9DQoNCi5sYmJ1dHRvbjpob3ZlciB7DQogICAgb3BhY2l0eToxOw0KfQ0KDQoubGJidXR0b25zZWwgew0KICAgIG9wYWNpdHk6MC45Ow0KfQ0KDQoubGJidXR0b25zZWwyIHsNCiAgICB3aWR0aDo4MnB4Ow0KICAgIGJvcmRlci1yYWRpdXM6NXB4IDBweCAwcHggNXB4Ow0KICAgIG9wYWNpdHk6MTsNCn0NCg0KLmxiMSB7DQogICAgYmFja2dyb3VuZDogdXJsKGltYWdlcy1jb21tYW5kZXIvbGVmdGJhci0zMi5wbmcpIC0wcHggMHB4Ow0KICAgIGhlaWdodDogMzJweDsNCiAgICB3aWR0aDogMzJweDsNCiAgICBjdXJzb3I6IHBvaW50ZXI7DQogICAgYm9yZGVyOiBub25lOw0KfQ0KDQoubGIyIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9sZWZ0YmFyLTMyLnBuZykgLTMycHggMHB4Ow0KICAgIGhlaWdodDogMzJweDsNCiAgICB3aWR0aDogMzJweDsNCiAgICBjdXJzb3I6IHBvaW50ZXI7DQogICAgYm9yZGVyOiBub25lOw0KfQ0KDQoubGIzIHsNCiAgICBiYWNrZ3JvdW5kOiB1cmwoaW1hZ2VzLWNvbW1hbmRlci9sZWZ0YmFyLTMyLnBuZykgLTY0cHggMHB4Ow0KICAgIGhlaWdodDogMzJweDsNCiAgICB3aWR0aDogMzJweDsNCiAgICBjdXJzb3I6IHBvaW50ZXI7DQogICAgYm9yZGVyOiBub25lOw0KfTwvc3R5bGU+DQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgDQogICAgPHN0eWxlPg0KICAgICAgICAubWVudWl0ZW0geyBjdXJzb3I6IHBvaW50ZXI7IGJvcmRlcjogbm9uZTsgcGFkZGluZzo1cHg7IH0NCiAgICAgICAgLm1lbnVpdGVtOmhvdmVyIHsgYmFja2dyb3VuZC1jb2xvcjogIzZiOWRjNzsgfQ0KICAgIDwvc3R5bGU+DQogICAgICAgICAgICAgICAgPHRpdGxlPkxNUyBNZXNoQ29tbWFuZGVyPC90aXRsZT4NCiAgICAgICAgICAgIDwvaGVhZD4NCjxib2R5IG9udW5sb2FkPSJjbGVhbnVwKCkiPg0KICAgIDxkaXYgaWQ9ImlkX3RvcGhlYWRlciIgY2xhc3M9ImhlYWRlciI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzcz0idG9wQ2VsbCIgc3R5bGU9IndpZHRoOjEwMCU7aGVpZ2h0OjU1cHgiPg0KICAgICAgICAgICAgPHRyPg0KICAgICAgICAgICAgICAgIDx0ZCB2YWxpZ249InRvcCIgbm93cmFwPSJub3dyYXAiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJ0b3AxIj5MTVMgTWVzaENvbW1hbmRlcjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGNsYXNzPSJ0b3AyIiBpZD0iaWRfY29tcHV0ZXJuYW1lIj4NCiAgICAgICAgICAgICAgICA8L3RkPg0KICAgICAgICAgICAgICAgIDx0ZCB2YWxpZ249InRvcCI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+DQogICAgICAgICAgICA8L3RyPg0KICAgICAgICA8L3RhYmxlPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9InByb2dyZXNzYmFyIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImlkX3Byb2dyZXNzYmFyIiBzdHlsZT0iaGVpZ2h0OjJweDt3aWR0aDowJTtiYWNrZ3JvdW5kLWNvbG9yOnJlZCI+PC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgIDwvZGl2Pg0KICAgIDxkaXYgaWQ9ImlkX21lc3NhZ2V2aWV3IiBjbGFzcz0iZnVsbGNlbGwiIHN0eWxlPSJ0ZXh0LWFsaWduOmNlbnRlcjtwYWRkaW5nLXRvcDoxMDBweDtmb250LXNpemU6MjBweCI+DQogICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfbWVzc2FnZXZpZXdzdHIiPkxvYWRpbmcuLi48L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxicj48YnI+PGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkNsb3NlIiBvbmNsaWNrPSJkaXNjb25uZWN0KCkiPg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgIDxkaXYgaWQ9ImlkX2xtc01haW5QYW5lbCIgY2xhc3M9ImZ1bGxjZWxsIiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgPGRpdiBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjpsaWdodGdyYXk7aGVpZ2h0OjI0cHg7bWFyZ2luLWJvdHRvbTo2cHg7cGFkZGluZy10b3A6MnB4Ij4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImlkX2xtc1Rvb2xCYXJDb250ZW50IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZmxvYXQ6bGVmdDtoZWlnaHQ6MjZweDt3aWR0aDoyNnB4O2N1cnNvcjpwb2ludGVyIiBvbmNsaWNrPSJ0b29sbWVudWNsaWNrKDApIj4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gc3R5bGU9ImZvbnQtc2l6ZToxNnB4Ij4mbmJzcDsmIzk3NzY7PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iUmVmcmVzaCIgb25jbGljaz0ibG1zUmVmcmVzaCgpIj4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJpZF9sbXNBY3RpdmF0ZUJ1dHRvbiIgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iQWN0aXZhdGUuLi4iIHN0eWxlPSJkaXNwbGF5Om5vbmUiIG9uY2xpY2s9Imxtc0FjdGl2YXRlKCkiPg0KICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9ImlkX2xtc0RlYWN0aXZhdGVCdXR0b24iIHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkRlYWN0aXZhdGUuLi4iIHN0eWxlPSJkaXNwbGF5Om5vbmUiIG9uY2xpY2s9Imxtc0RlYWN0aXZhdGUoKSI+DQogICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iaWRfbG1zTG9naW5CdXR0b24iIHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkxvZ2luLi4uIiBzdHlsZT0iZGlzcGxheTpub25lIiBvbmNsaWNrPSJsbXNMb2dpbigpIj4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJpZF9sbXNDb25maWd1cmVCdXR0b24iIHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkludGVsJnJlZzsgQU1UIExvZ2luLi4uIiBzdHlsZT0iZGlzcGxheTpub25lIiBvbmNsaWNrPSJsbXNDb25maWd1cmUoKSI+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgPC9kaXY+DQogICAgICAgIDxkaXYgaWQ9ImlkX2xtc0RhdGEiIHN0eWxlPSJtYXJnaW46MTBweCI+PC9kaXY+DQogICAgICAgIDxkaXYgaWQ9ImlkX2xtc0RhdGEyIiBzdHlsZT0ibWFyZ2luOjEwcHgiPjwvZGl2Pg0KICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9jb21wdXRlclNlbGVjdG9yTWVudSIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6I0VFRUVFRTtkaXNwbGF5Om5vbmU7cG9zaXRpb246YWJzb2x1dGU7bGVmdDowO3RvcDo5NHB4O3dpZHRoOjIwMHB4O3BhZGRpbmc6M3B4O3otaW5kZXg6MTAwMDtib3gtc2hhZG93OjVweCA1cHggNXB4ICM4ODg4ODg7Ym9yZGVyOjFweCBzb2xpZCBncmF5Ij4NCiAgICAgICAgPGRpdiBjbGFzcz0ibWVudWl0ZW0iIG9uY2xpY2s9InRvb2xtZW51Y2xpY2soMTAxKSI+PHNwYW4gaWQ9ImlkX21lbnVpdGVtMSI+JmJ1bGw7IDwvc3Bhbj5Db21wdXRlciBDb25maWd1cmF0aW9uPC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0ibWVudWl0ZW0iIG9uY2xpY2s9InRvb2xtZW51Y2xpY2soMTAyKSI+PHNwYW4gaWQ9ImlkX21lbnVpdGVtMiIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+JmJ1bGw7IDwvc3Bhbj5VU0IgU2V0dXAuYmluIEVkaXRvcjwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJpZF91c2JTZXR1cFBhbmVsIiBjbGFzcz0iZnVsbGNlbGwiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgIDx0YWJsZSBzdHlsZT0iYmFja2dyb3VuZC1jb2xvcjojODA4MDgwO3dpZHRoOjEwMCUiPg0KICAgICAgICAgICAgPHRyPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgc3R5bGU9IndpZHRoOjI2cHg7Y3Vyc29yOnBvaW50ZXIiIG9uY2xpY2s9InRvb2xtZW51Y2xpY2soMCkiPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBzdHlsZT0iZm9udC1zaXplOjE2cHgiPiZuYnNwOyYjOTc3Njs8L3NwYW4+DQogICAgICAgICAgICAgICAgPC90ZD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRkPg0KICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iTmV3Li4uIiBvbmNsaWNrPSJ1c2JfbmV3U2V0dXBCaW4oKSI+DQogICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJPcGVuLi4uIiBvbmNsaWNrPSJ1c2Jfb3BlblNldHVwQmluKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iaWRfc2F2ZVNldHVwQmluIiB0eXBlPSJidXR0b24iIHZhbHVlPSJTYXZlLi4uIiBvbmNsaWNrPSJ1c2Jfc2F2ZVNldHVwQmluKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD4NCiAgICAgICAgICAgIDwvdHI+DQogICAgICAgIDwvdGFibGU+DQogICAgICAgIDxkaXYgaWQ9ImlkX3VzYlNldHVwUGFuZWwyIiBzdHlsZT0icG9zaXRpb246Zml4ZWQ7b3ZlcmZsb3cteTpzY3JvbGw7bGVmdDowO3JpZ2h0OjA7Ym90dG9tOjA7dG9wOjk2cHgiPg0KICAgICAgICAgICAgPGRpdiBpZD0iaWRfU3RhcnR1cFNjcmVlbiIgc3R5bGU9IndpZHRoOjEwMCU7dGV4dC1hbGlnbjpjZW50ZXI7Y29sb3I6Z3JheTttYXJnaW4tdG9wOjM2cHgiPg0KICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPSJmb250LXNpemU6MjBweCI+SW50ZWw8c3VwIHN0eWxlPSJmb250LXNpemU6MTBweCI+JnJlZzs8L3N1cD4gQU1UIFVTQiBTZXR1cC5iaW4gTWFuYWdlcjwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJtYXJnaW46NHB4Ij5HZXQgc3RhcnRlZCBieSA8YSBvbmNsaWNrPSJ1c2JfbmV3U2V0dXBCaW4oKSIgc3R5bGU9ImN1cnNvcjpwb2ludGVyIj48dT5jcmVhdGluZzwvdT48L2E+IGEgbmV3IGZpbGUsIDxhIG9uY2xpY2s9InVzYl9vcGVuU2V0dXBCaW4oKSIgc3R5bGU9ImN1cnNvcjpwb2ludGVyIj48dT5vcGVuaW5nPC91PjwvYT4gYW4gZXhpc3Rpbmcgb25lPGJyPm9yIGRyYWcgJiBkcm9wcGluZyBhIHNldHVwLmJpbiBmaWxlIGluIHRoaXMgd2luZG93LjwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJpZF9TZXR1cEJpbkFyZWEiIHN0eWxlPSJtYXJnaW46MTBweCI+PC9kaXY+DQogICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImlkX21haW52aWV3IiBzdHlsZT0iaGVpZ2h0OjEwMCU7ZGlzcGxheTpub25lIj4NCiAgICAgICAgPGRpdiBpZD0iaWRfbGVmdGJhciIgY2xhc3M9Im5hdmJhciI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdwYWRkaW5nOjhweCc+DQogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgaWQ9ImRpc2Nvbm5lY3RCdXR0b24iIHZhbHVlPSJEaXNjb25uZWN0IiBvbmtleXByZXNzPSJyZXR1cm4gZmFsc2UiIG9ua2V5ZG93bj0icmV0dXJuIGZhbHNlIiBvbmNsaWNrPSJkaXNjb25uZWN0KCkiIHN0eWxlPSJ3aWR0aDoxMzhweCI+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzEiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbygxKSI+PGE+U3lzdGVtIFN0YXR1czwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBpZD0iZ28yIiBjbGFzcz0ibmF2MSIgb25jbGljaz0iZ28oMikiPjxhPkhhcmR3YXJlIEluZm9ybWF0aW9uPC9hPjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzYiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbyg2KSI+PGE+RXZlbnQgTG9nPC9hPjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzE1IiBjbGFzcz0ibmF2MSIgb25jbGljaz0iZ28oMTUpIj48YT5BdWRpdCBMb2c8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgaWQ9ImdvMjEiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbygyMSkiPjxhPlN0b3JhZ2U8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgaWQ9ImdvOCIgY2xhc3M9Im5hdjEiIG9uY2xpY2s9ImdvKDgpIj48YT5OZXR3b3JrIFNldHRpbmdzPC9hPjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzE3IiBjbGFzcz0ibmF2MSIgb25jbGljaz0iZ28oMTcpIj48YT5JbnRlcm5ldCBTZXR0aW5nczwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBpZD0iZ28xNiIgY2xhc3M9Im5hdjEiIG9uY2xpY2s9ImdvKDE2KSI+PGE+U2VjdXJpdHkgU2V0dGluZ3M8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgaWQ9ImdvMTkiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbygxOSkiPjxhPkFnZW50IFByZXNlbmNlPC9hPjwvcD4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwIGlkPSJnbzE4IiBjbGFzcz0ibmF2MSIgb25jbGljaz0iZ28oMTgpIj48YT5TeXN0ZW0gRGVmZW5zZTwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgICAgICA8cCBpZD0iZ28xMSIgY2xhc3M9Im5hdjEiIG9uY2xpY2s9ImdvKDExKSI+PGE+VXNlciBBY2NvdW50czwvYT48L3A+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cCBpZD0iZ28yMyIgY2xhc3M9Im5hdjEiIG9uY2xpY2s9ImdvKDIzKSI+PGE+V2FrZSBBbGFybXM8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHAgaWQ9ImdvMjAiIGNsYXNzPSJuYXYxIiBvbmNsaWNrPSJnbygyMCkiPjxhPlNjcmlwdCBFZGl0b3I8L2E+PC9wPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgPGRpdiBpZD0iaWRfbWFpbmFyZWEiIGNsYXNzPSJtYWluY2VsbCI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9zY3JpcHRzdGF0dXMiIHN0eWxlPSJoZWlnaHQ6MjFweDtiYWNrZ3JvdW5kOiM4ZmFjOGQ7cGFkZGluZzo1cHg7bWFyZ2luLWJvdHRvbToxcHg7ZGlzcGxheTpub25lO292ZXJmbG93OmhpZGRlbiI+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZmxvYXQ6cmlnaHQiPjxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJTdG9wIFNjcmlwdCIgb25jbGljaz0ic2NyaXB0X1N0b3AoKSI+PC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZm9udC1zaXplOjE2cHg7cGFkZGluZy10b3A6MnB4O292ZXJmbG93OmhpZGRlbiI+Jm5ic3A7PGI+UnVubmluZyBTY3JpcHQ8L2I+PHNwYW4gc3R5bGU9Im92ZXJmbG93OmhpZGRlbiIgaWQ9ImlkX3NjcmlwdHN0YXR1c3N0ciI+PC9zcGFuPjwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9tYWluYXJlYV9mcmFtZSIgc3R5bGU9IndpZHRoOjEwMCU7aGVpZ2h0OjEwMCUiPg0KICAgICAgICAgICAgICAgIDxpZnJhbWUgaWQ9ImlkX1N0b3JhZ2VJRnJhbWUiIHN0eWxlPSJ3aWR0aDoxMDAlO2hlaWdodDoxMDAlO2JvcmRlcjowIj48L2lmcmFtZT4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iaWRfbWFpbmFyZWFfcGFkIiBzdHlsZT0icGFkZGluZzo4cHg7b3ZlcmZsb3cteDpoaWRkZW4iPg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAwIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPkxvYWRpbmcuLi48L2gxPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAxIiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPlN5c3RlbSBTdGF0dXM8L2gxPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVTeXNTdGF0dXMiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDIiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgICAgICA8aDEgc3R5bGU9Im1hcmdpbi1ib3R0b206MTZweCI+SGFyZHdhcmUgSW5mb3JtYXRpb248L2gxPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVTeXNJbmZvIj48L3NwYW4+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJwNiIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+DQogICAgICAgICAgICAgICAgICAgIDxoMT5FdmVudCBMb2c8L2gxPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVFdmVudExvZyI+PC9zcGFuPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVFdmVudExvZzIiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InA4IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPk5ldHdvcmsgU2V0dGluZ3M8L2gxPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVOZXR3b3JrU2V0dGluZ3NTcGFuIj48L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlV2lmaTIiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJwMTEiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgICAgICA8aDE+VXNlciBBY2NvdW50czwvaDE+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIGlkPSJpZF9UYWJsZVVzZXJBY2NvdW50cyI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJwMTUiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgICAgICA8c3BhbiBpZD0iaWRfVGFibGVBdWRpdExvZzEiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPkF1ZGl0IExvZzwvaDE+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIGlkPSJpZF9UYWJsZUF1ZGl0TG9nMiI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDE2IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPlNlY3VyaXR5IFNldHRpbmdzPC9oMT4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlQ2VydHMiPjwvc3Bhbj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAxNyIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+DQogICAgICAgICAgICAgICAgICAgIDxoMT5JbnRlcm5ldCBTZXR0aW5nczwvaDE+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIGlkPSJpZF9UYWJsZVJlbW90ZUFjY2VzcyI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDE4IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPlN5c3RlbSBEZWZlbnNlPC9oMT4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlU3lzdGVtRGVmZW5zZSI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDE5IiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPkFnZW50IFByZXNlbmNlPC9oMT4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlU3lzdGVtQWdlbnRQcmVzZW5jZSI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0icDIwIiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGgxPlNjcmlwdCBFZGl0b3I8L2gxPg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJsb2cxIiBzdHlsZT0icGFkZGluZzo1cHg7Ym9yZGVyLXJhZGl1czo1cHgiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0nRWRpdFNjcmlwdFN0YXR1cycgc3R5bGU9ImZsb2F0OnJpZ2h0O2ZvbnQtd2VpZ2h0OmJvbGQ7cGFkZGluZzo1cHgiPlN0b3BwZWQ8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IlZpZXcgRWRpdG9yIiB0aXRsZT0iU3dpdGNoIHRvIHNjcmlwdCBsaW5lIGVkaXRvciB2aWV3IiBpZD0idmlld0VkaXRvckJ1dHRvbiIgb25jbGljaz0ic2NyaXB0Vmlld0J1dHRvbigwKSI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IlZpZXcgQnVpbGRlciIgdGl0bGU9IlN3aXRjaCB0byBibG9jayBlZGl0b3IgdmlldyIgaWQ9InZpZXdCdWlsZGVyQnV0dG9uIiBvbmNsaWNrPSJzY3JpcHRWaWV3QnV0dG9uKDEpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iTmV3Li4uIiB0aXRsZT0iQ2xlYXIgdGhlIHNjcmlwdCBlZGl0b3IiIG9uY2xpY2s9InNjcmlwdF9uZXdTY3JpcHREbGcoKSI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkxvYWQuLi4iIHRpdGxlPSJMb2FkIGEgc2NyaXB0IGZyb20gZmlsZSIgb25jbGljaz0ic2NyaXB0X3J1blNjcmlwdERsZygpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IlNhdmUuLi4iIHRpdGxlPSJTYXZlIGEgc2NyaXB0IHRvIGZpbGUiIG9uY2xpY2s9InNjcmlwdF9zYXZlU2NyaXB0KGV2ZW50KSI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJSZXN0YXJ0IiB0aXRsZT0iQ29tcGlsZSB0aGUgc2NyaXB0IGFuZCBnZXQgcmVhZHkgdG8gcnVuIGl0IGZyb20gdGhlIHN0YXJ0IiBvbmNsaWNrPSJyZXNldFNjcmlwdEJ1dHRvbigpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iQ29udGludWUiIHRpdGxlPSJSdW4gdGhlIHNjcmlwdCBmcm9tIHRoZSBjdXJyZW50IGV4ZWN1dGlvbiBwb2ludCIgb25jbGljaz0icnVuU2NyaXB0QnV0dG9uKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJidXR0b24iIHZhbHVlPSJCcmVhayIgdGl0bGU9IlBhdXNlIHRoZSBleGVjdXRpb24gb2YgdGhlIHNjcmlwdCIgb25jbGljaz0iYnJlYWtTY3JpcHRCdXR0b24oKSI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9ImJ1dHRvbiIgdmFsdWU9IlN0ZXAiIHRpdGxlPSJFeGVjdXRlIG9uZSBzdGVwIG9mIHRoZSBzY3JpcHQiIG9uY2xpY2s9InN0ZXBTY3JpcHRCdXR0b24oKSI+DQogICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InNjcmlwdGJ1aWxkZXIiIHN0eWxlPSJkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPGgyPlNjcmlwdCBCdWlsZGVyPC9oMj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9InBhZGRpbmc6MDttYXJnaW46MCI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0id2lkdGg6MjUwcHg7aGVpZ2h0OjQwMHB4O2Zsb2F0OmxlZnQ7cGFkZGluZzowO21hcmdpbjowO3BhZGRpbmctcmlnaHQ6M3B4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJibG9ja2ZpbHRlciIgc3R5bGU9IndpZHRoOmluaGVyaXQ7aGVpZ2h0OjI0cHg7cGFkZGluZzowO21hcmdpbjowO2JvcmRlcjoxcHggc29saWQgZ3JheTttYXJnaW4tYm90dG9tOjFweCIgcGxhY2Vob2xkZXI9IkZpbHRlciBibG9ja3MuLi4iIG9ua2V5dXA9InNjcmlwdF9mb25maWx0ZXJjaGFuZ2VkKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJibG9ja3MiIHN0eWxlPSJ3aWR0aDppbmhlcml0O2hlaWdodDozNzNweDtib3JkZXI6MXB4IHNvbGlkIGdyYXk7b3ZlcmZsb3cteTpzY3JvbGw7cGFkZGluZzowO21hcmdpbjowIj48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJzY3JpcHRibG9ja3MiIHN0eWxlPSJ3aWR0aDphdXRvO2hlaWdodDo0MDBweDtwYWRkaW5nOjA7bWFyZ2luOjA7Ym9yZGVyOjFweCBzb2xpZCBncmF5O292ZXJmbG93LXk6c2Nyb2xsIiBvbmRyb3A9InNjcmlwdF9mb25kcm9wKGV2ZW50LCB0aGlzKSIgb25jbGljaz0ic2NyaXB0X2ZvbmNsaWNrKGV2ZW50KSI+PC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InNjcmlwdGVkaXRvciI+DQogICAgICAgICAgICAgICAgICAgICAgICA8aDI+U2NyaXB0PC9oMj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZXh0YXJlYSBpZD0ic2NyaXB0YXJlYSIgc3R5bGU9IndpZHRoOjEwMCU7aGVpZ2h0OjE3NnB4O3Jlc2l6ZTp2ZXJ0aWNhbDttYXJnaW46MDtwYWRkaW5nOjA7Zm9udC1mYW1pbHk6QXJpYWwsSGVsdmV0aWNhLHNhbnMtc2VyaWYiIHNwZWxsY2hlY2s9ImZhbHNlIj48L3RleHRhcmVhPg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnI+PGgyPkNvbXBpbGVkIFNjcmlwdDwvaDI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIGlkPSJjb21waWxlZGFyZWEiIHN0eWxlPSJ3aWR0aDoxMDAlO2hlaWdodDoxNnB4O3Jlc2l6ZTp2ZXJ0aWNhbDttYXJnaW46MDtwYWRkaW5nOjAiIHNwZWxsY2hlY2s9ImZhbHNlIj48L3RleHRhcmVhPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxicj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGgyPlZhcmlhYmxlczwvaDI+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJ2YXJpYWJsZXMiIHN0eWxlPSJ3aWR0aDoxMDAlO2hlaWdodDoyMDBweDtyZXNpemU6dmVydGljYWw7Ym9yZGVyOjFweCBzb2xpZCBncmF5O292ZXJmbG93OnNjcm9sbDttYXJnaW46MDtwYWRkaW5nOjA7dXNlci1zZWxlY3Q6dGV4dDstd2Via2l0LXVzZXItc2VsZWN0OnRleHQ7LWtodG1sLXVzZXItc2VsZWN0OnRleHQ7LW1vei11c2VyLXNlbGVjdDp0ZXh0Oy1tcy11c2VyLXNlbGVjdDp0ZXh0Ij48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxoMj5Db25zb2xlPC9oMj4NCiAgICAgICAgICAgICAgICAgICAgPHRleHRhcmVhIGlkPSJjb25zb2xlIiBzdHlsZT0id2lkdGg6MTAwJTtoZWlnaHQ6ODBweDtyZXNpemU6dmVydGljYWw7bWFyZ2luOjA7cGFkZGluZzowO3VzZXItc2VsZWN0OnRleHQ7LXdlYmtpdC11c2VyLXNlbGVjdDp0ZXh0Oy1raHRtbC11c2VyLXNlbGVjdDp0ZXh0Oy1tb3otdXNlci1zZWxlY3Q6dGV4dDstbXMtdXNlci1zZWxlY3Q6dGV4dCIgcmVhZG9ubHk9IiI+PC90ZXh0YXJlYT4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAyMSIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+DQogICAgICAgICAgICAgICAgICAgIDxoMT5TdG9yYWdlPC9oMT4NCiAgICAgICAgICAgICAgICAgICAgPHNwYW4gaWQ9ImlkX1RhYmxlU3lzdGVtU3RvcmFnZSI+PC9zcGFuPg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9InAyMyIgc3R5bGU9ImRpc3BsYXk6bm9uZSI+DQogICAgICAgICAgICAgICAgICAgIDxoMT5XYWtlIEFsYXJtczwvaDE+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIGlkPSJpZF9UYWJsZUFsYXJtIj48L3NwYW4+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICA8L2Rpdj4NCiAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZyIgc3R5bGU9InotaW5kZXg6MTAwMDtiYWNrZ3JvdW5kLWNvbG9yOiNFRUU7Ym94LXNoYWRvdzowcHggMHB4IDE1cHggIzY2Njtmb250LWZhbWlseTpBcmlhbCwgSGVsdmV0aWNhLCBzYW5zLXNlcmlmO2JvcmRlci1yYWRpdXM6NXB4O3Bvc2l0aW9uOmZpeGVkO3RvcDoxNjBweDt3aWR0aDo0MDBweDtkaXNwbGF5Om5vbmUiPg0KICAgICAgICAgICAgPGRpdiBzdHlsZT0id2lkdGg6MTAwJTtiYWNrZ3JvdW5kLWNvbG9yOiMwMDMzNjY7Y29sb3I6I0ZGRjtib3JkZXItcmFkaXVzOjVweCA1cHggMCAwIj4NCiAgICAgICAgICAgIDxkaXYgaWQ9J2lkX2RpYWxvZ2Nsb3NlJyBzdHlsZT0iZmxvYXQ6cmlnaHQ7cGFkZGluZzoxcHg7bWFyZ2luLXJpZ2h0OjVweDtjdXJzb3I6cG9pbnRlcjtmb250LXNpemU6MTVweCIgb25jbGljaz0ic2V0RGlhbG9nTW9kZSgpIj4mI3gyNzE2OzwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0naWRfZGlhbG9ndGl0bGUnIHN0eWxlPSJwYWRkaW5nOjVweCI+PC9kaXY+DQogICAgICAgICAgICA8ZGl2IHN0eWxlPSJ3aWR0aDoxMDAlO21hcmdpbjo2cHgiPjwvZGl2Pg0KICAgICAgICA8L2Rpdj4NCiAgICAgICAgPGRpdiBzdHlsZT0ibWFyZ2luLXJpZ2h0OjE2cHg7bWFyZ2luLWxlZnQ6OHB4Ij4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzEiIHN0eWxlPSJtYXJnaW46YXV0bzt0ZXh0LWFsaWduOmNlbnRlcjttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9kaWFsb2dNZXNzYWdlIiBzdHlsZT0icGFkZGluZzoxMHB4Ij48L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMiIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxicj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+PGlucHV0IGlkPSJkMnVzZXJuYW1lIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiIG9ua2V5dXA9InVwZGF0ZUFjY291bnREaWFsb2coKSI+PGRpdj5Vc2VybmFtZTwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImQycGFzc3dvcmQxIiB0eXBlPSJwYXNzd29yZCIgYXV0b2NvbXBsZXRlPSJvZmYiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25rZXl1cD0idXBkYXRlQWNjb3VudERpYWxvZygpIj48ZGl2PlBhc3N3b3JkKjwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImQycGFzc3dvcmQyIiB0eXBlPSJwYXNzd29yZCIgYXV0b2NvbXBsZXRlPSJvZmYiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25rZXl1cD0idXBkYXRlQWNjb3VudERpYWxvZygpIj48ZGl2PkNvbmZpcm0gUGFzc3dvcmQ8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IGlkPSJpZF9kMnBlcm1pc3Npb25zIj4NCiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0naGVpZ2h0OjI2cHgnPjxzZWxlY3QgaWQ9ImQycGVybWlzc2lvbiIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4Ij48b3B0aW9uIHZhbHVlPSIwIj5Mb2NhbDxvcHRpb24gdmFsdWU9IjEiPk5ldHdvcms8b3B0aW9uIHZhbHVlPSIyIj5Bbnk8L3NlbGVjdD48ZGl2PlBlcm1pc3Npb248L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPGRpdj5HcmFudGVkIFBlcm1pc3Npb25zPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDx1bCBpZD0iaWRfZDJyZWFsbXMiIHN0eWxlPSJsaXN0LXN0eWxlLXR5cGU6bm9uZTtoZWlnaHQ6MTAwcHg7b3ZlcmZsb3c6YXV0bzt3aWR0aDoxMDAlO2JvcmRlcjogMXB4IHNvbGlkICMwMDA7YmFja2dyb3VuZC1jb2xvcjp3aGl0ZTtvdmVyZmxvdy14OmhpZGRlbjttYXJnaW46MDtwYWRkaW5nOjAiPjwvdWw+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iZm9udC1zaXplOjEwcHgiPjxicj4qTWluaW11bSA4IGNoYXJhY3RlcnMgd2l0aCB1cHBlciwgbG93ZXJjYXNlLCAwLTksIGFuZCBvbmUgb2YgIUAjJCVeJmFtcDsqKCkrLTwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2c0IiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImQ0dXNlcm5hbWUiIHBsYWNlaG9sZGVyPSJhZG1pbiIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IiBvbmtleXVwPSJsbXNVcGRhdGVMb2dpbkRpYWxvZyhldmVudCwgMSkiPjxkaXY+VXNlcm5hbWU8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+PGlucHV0IGlkPSJkNHBhc3N3b3JkIiB0eXBlPSJwYXNzd29yZCIgYXV0b2NvbXBsZXRlPSJvZmYiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25rZXl1cD0ibG1zVXBkYXRlTG9naW5EaWFsb2coZXZlbnQsIDIpIj48ZGl2PlBhc3N3b3JkKjwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImZvbnQtc2l6ZToxMHB4Ij48YnI+Kk1pbmltdW0gOCBjaGFyYWN0ZXJzIHdpdGggdXBwZXIsIGxvd2VyY2FzZSwgMC05LCBhbmQgb25lIG9mICFAIyQlXiZhbXA7KigpKy08L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nNSIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxicj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+DQogICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgaWQ9ImQ1YWN0aW9uU2VsZWN0IiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiPjwvc2VsZWN0Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2PlBvd2VyIEFjdGlvbjwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXY+DQogICAgICAgICAgICAgICAgICAgIDxzcGFuIHN0eWxlPSJjb2xvcjpyZWQiPldhcm5pbmc6PC9zcGFuPiBTb21lIHBvd2VyIGFjdGlvbnMgbWF5IHJlc3VsdCBpbiBkYXRhIGxvc3MgYW5kIG1heSBkaXNjb25uZWN0IHRoZSBkZXNrdG9wLCB0ZXJtaW5hbCBvciBkaXNrIHJlZGlyZWN0aW9uIHNlc3Npb25zLg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2c2IiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImQ2Q29uc2VudFRleHQiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgbWF4bGVuZ3RoPSI2IiBvbmtleXVwPSJjb25zZW50Q2hhbmdlZCgpIiBvbmtleXByZXNzPSJyZXR1cm4gbnVtYmVyc09ubHkoZXZlbnQpIj48ZGl2PkNvbnNlbnQgQ29kZTwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48c2VsZWN0IGlkPSJkNkRpc3BsYXkiIG9uY2hhbmdlPSJjaGFuZ2VDb25zZW50RGlzcGxheSgpIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiPjxvcHRpb24gdmFsdWU9IjAiPlByaW1hcnkgZGlzcGxheTxvcHRpb24gdmFsdWU9IjEiPlNlY29uZGFyeSBkaXNwbGF5PG9wdGlvbiBpZD0iZDZUaGlyZERpc3BsYXkiIHZhbHVlPSIyIiBzdHlsZT0iZGlzcGxheTpub25lIj5UaGlyZCBkaXNwbGF5PC9zZWxlY3Q+PGRpdj5Db25zZW50IERpc3BsYXk8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nOCIgc3R5bGU9ImRpc3BsYXk6dGFibGU7bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0ibWFyZ2luOjNweCAwIDNweCAwO3BhZGRpbmctdG9wOjVweCI+DQogICAgICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iaWR4X2Q4dXNlcm5hbWUiIHZhbHVlPSJhZG1pbiIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIyMHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iaGVpZ2h0OjIwcHgiPlVzZXJuYW1lPC9kaXY+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0ibWFyZ2luOjNweCAwIDNweCAwIj4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJpZHhfZDhwYXNzd29yZCIgdHlwZT0icGFzc3dvcmQiIGF1dG9jb21wbGV0ZT0ib2ZmIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjIwcHgiPg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJoZWlnaHQ6MjBweCI+UGFzc3dvcmQ8L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nOSIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9J2lkeF9kOXJlZGlyJz5SZWRpcmVjdGlvbiBQb3J0PGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImlkeF9kOWt2bV9kaXYiPjxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9J2lkeF9kOWt2bSc+S1ZNIFJlbW90ZSBEZXNrdG9wPGJyPjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9J2lkeF9kOWlkZXInPklERS1SZWRpcmVjdGlvbjxicj4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSdpZHhfZDlzb2wnPlNlcmlhbC1vdmVyLUxBTjxicj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMTAiIHN0eWxlPSJtYXJnaW46YXV0bzttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0icmFkaW8iIG5hbWU9ImQxMCIgaWQ9J2lkeF9kMTBub25lJyB2YWx1ZT0iMCI+Tm90IFJlcXVpcmVkPGJyPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJyYWRpbyIgbmFtZT0iZDEwIiBpZD0naWR4X2QxMGt2bScgdmFsdWU9IjEiPlJlcXVpcmVkIGZvciBLVk0gb25seTxicj4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0icmFkaW8iIG5hbWU9ImQxMCIgaWQ9J2lkeF9kMTBhbGwnIHZhbHVlPSI0Mjk0OTY3Mjk1Ij5BbHdheXMgUmVxdWlyZWQ8YnI+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzExIiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGRpdiBpZD0iaWRfZGlhbG9nT3B0aW9ucyI+PC9kaXY+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzEyIiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImlkeF9kMTJuYW1lIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiIG1heGxlbmd0aD0iMzIiIG9ua2V5dXA9InVwZGF0ZVdpZmlEaWFsb2coKSIgdGl0bGU9Ik1heGltdW0gMzIgY2hhcmFjdGVycyI+PGRpdiB0aXRsZT0iTWF4aW11bSAzMiBjaGFyYWN0ZXJzIj5Qcm9maWxlIE5hbWU8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+PGlucHV0IGlkPSJpZHhfZDEyc3NpZCIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IiBtYXhsZW5ndGg9IjMyIiBvbmtleXVwPSJ1cGRhdGVXaWZpRGlhbG9nKCkiIHRpdGxlPSJNYXhpbXVtIDMyIGNoYXJhY3RlcnMiPjxkaXYgdGl0bGU9Ik1heGltdW0gMzIgY2hhcmFjdGVycyI+U1NJRDwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz4NCiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBpZD0iaWR4X2QxMnByaSIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IiBvbmNsaWNrPSJ1cGRhdGVXaWZpRGlhbG9nKCkiPjwvc2VsZWN0Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2PlByaW9yaXR5PC9kaXY+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0naGVpZ2h0OjI2cHgnPg0KICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGlkPSJpZHhfZDEyYXV0aCIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IiBvbmNsaWNrPSJ1cGRhdGVXaWZpRGlhbG9nKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPCEtLTxvcHRpb24gdmFsdWU9IjciPldQQTIgSUVFRSA4MDIuMXg8L29wdGlvbj4tLT4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjYiPldQQTIgUFNLDQogICAgICAgICAgICAgICAgICAgICAgICA8IS0tPG9wdGlvbiB2YWx1ZT0iNSI+V1BBIElFRUUgODAyLjF4PC9vcHRpb24+LS0+DQogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSI0Ij5XUEEgUFNLDQogICAgICAgICAgICAgICAgICAgICAgICA8IS0tPG9wdGlvbiB2YWx1ZT0iMyI+U2hhcmVkIEtleTwvb3B0aW9uPi0tPg0KICAgICAgICAgICAgICAgICAgICAgICAgPCEtLTxvcHRpb24gdmFsdWU9IjIiPk9wZW48L29wdGlvbj4tLT4NCiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgIDxkaXY+QXV0aGVudGljYXRpb248L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+DQogICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgaWQ9ImlkeF9kMTJlbmMiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25jbGljaz0idXBkYXRlV2lmaURpYWxvZygpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gaWQ9ImlkX2QxMmU0IiB2YWx1ZT0iNCI+Q0NNUC1BRVMNCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gaWQ9ImlkX2QxMmUzIiB2YWx1ZT0iMyI+VEtJUC1SQzQNCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gaWQ9ImlkX2QxMmUyIiB2YWx1ZT0iMiI+V0VQDQogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIGlkPSJpZF9kMTJlNSIgdmFsdWU9IjUiPk5vbmUNCiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgIDxkaXY+RW5jcnlwdGlvbjwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImlkeF9kMTJwYXNzd29yZDEiIHR5cGU9InBhc3N3b3JkIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiIG1heGxlbmd0aD0iNjMiIG9ua2V5dXA9InVwZGF0ZVdpZmlEaWFsb2coKSIgdGl0bGU9Ikxlbmd0aCBiZXR3ZWVuIDggYW5kIDYzIGNoYXJhY3RlcnMiPjxkaXYgdGl0bGU9Ikxlbmd0aCBiZXR3ZWVuIDggYW5kIDYzIGNoYXJhY3RlcnMiPlBhc3N3b3JkKjwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz48aW5wdXQgaWQ9ImlkeF9kMTJwYXNzd29yZDIiIHR5cGU9InBhc3N3b3JkIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiIG1heGxlbmd0aD0iNjMiIG9ua2V5dXA9InVwZGF0ZVdpZmlEaWFsb2coKSIgdGl0bGU9Ikxlbmd0aCBiZXR3ZWVuIDggYW5kIDYzIGNoYXJhY3RlcnMiPjxkaXYgdGl0bGU9Ikxlbmd0aCBiZXR3ZWVuIDggYW5kIDYzIGNoYXJhY3RlcnMiPkNvbmZpcm0gUGFzc3dvcmQ8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMTMiIHN0eWxlPSJtYXJnaW46YXV0bzttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iY2hlY2tib3giIGlkPSdkMTN2YWxpZCc+VmFsaWQgUmVjb3JkPGJyPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgaWQ9J2QxM3NjcmFtYmxlJz5TY3JhbWJsZWQgUmVjb3JkPGJyPg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2cxNCIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz4NCiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBpZD0iaWR4X2QxNHZlcnNpb24iIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCI+DQogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSIxIj5WZXJzaW9uIDENCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjIiPlZlcnNpb24gMg0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMyI+VmVyc2lvbiAzDQogICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSI0Ij5WZXJzaW9uIDQNCiAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgIDxkaXY+U2V0dXAuYmluIHZlcnNpb248L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+DQogICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgaWQ9ImlkeF9kMTRjb25zdW1lIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHgiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMSI+UmVjb3JkcyB3aWxsIG5vdCBiZSBjb25zdW1lZA0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMCI+UmVjb3JkcyB3aWxsIGJlIGNvbnN1bWVkDQogICAgICAgICAgICAgICAgICAgIDwvc2VsZWN0Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2PlJlY29yZCBjb25zdW1wdGlvbjwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2cxNSIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iZDE1c2V0dXBiaW5maWxlIiB0eXBlPSJmaWxlIiBzdHlsZT0id2lkdGg6MTAwJSIgYWNjZXB0PSIuYmluIj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMTYiIHN0eWxlPSJtYXJnaW46YXV0bzttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+DQogICAgICAgICAgICAgICAgICAgIDxzZWxlY3QgaWQ9ImQxNnR5cGUiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyNjBweCIgb25jaGFuZ2U9InVzYl9vbmQxNnR5cGVjaGFuZ2UoKSIgb25jbGljaz0idXNiX29uZDE2dHlwZWNoYW5nZSgpIiBvbnNjcm9sbD0idXNiX29uZDE2dHlwZWNoYW5nZSgpIiBvbmtleWRvd249InVzYl9vbmQxNnR5cGVjaGFuZ2UoKSI+PC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgIDxkaXY+VmFyaWFibGUgVHlwZTwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImQxNmdlbmVyaWN2YWx1ZSIgc3R5bGU9J2hlaWdodDoyNnB4Jz4NCiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBpZD0iaWR4X2QxNnZhbHVlMSIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4Ij48L3NlbGVjdD4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJpZHhfZDE2dmFsdWUyIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHg7ZGlzcGxheTpub25lIj4NCiAgICAgICAgICAgICAgICAgICAgPGRpdj5WYXJpYWJsZSBWYWx1ZTwvZGl2Pg0KICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgIDxkaXYgaWQ9ImQxNmN1c3RvbXZhbHVlIj48L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBpZD0iZGlhbG9nMTkiIHN0eWxlPSJtYXJnaW46YXV0bzttYXJnaW46M3B4Ij4NCiAgICAgICAgICAgICAgICBUaGlzIHdpbGwgc2F2ZSB0aGUgZW50aXJlIHN0YXRlIG9mIEludGVsJnJlZzsgQU1UIGZvciB0aGlzIG1hY2hpbmUgaW50byBmaWxlLiBQYXNzd29yZHMgd2lsbCBub3QgYmUgc2F2ZWQsIGJ1dCBzb21lIHNlbnNpdGl2ZSBkYXRhIG1heSBiZSBpbmNsdWRlZC48YnI+PGJyPg0KICAgICAgICAgICAgICAgIDxpbnB1dCBpZD0iaWR4X2QxOXNhdmVzdGF0ZWZpbGVuYW1lIiBzdHlsZT0id2lkdGg6MTAwJSIgdmFsdWU9ImFtdHN0YXRlLmpzb24iPg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2cyMCIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJyYWRpbyIgbmFtZT0iZDIwIiBpZD0iZDIwYSIgdmFsdWU9IjAiPkRpc2FibGVkPGJyPg0KICAgICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJyYWRpbyIgbmFtZT0iZDIwIiBpZD0iZDIwYiIgdmFsdWU9IjEiPklDTVAgcmVzcG9uc2U8YnI+DQogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJkMjAiIGlkPSJkMjBjIiB2YWx1ZT0iMiI+Uk1DUCByZXNwb25zZTxicj4NCiAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0icmFkaW8iIG5hbWU9ImQyMCIgaWQ9ImQyMGQiIHZhbHVlPSIzIj5JQ01QICYgUk1DUCByZXNwb25zZTxicj48YnI+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzIxIiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJkMjEiIGlkPSJkMjFvMCIgb25jbGljaz0idXBkYXRlSVBTZXR1cERsZygpIj48c3BhbiBpZD0iZDIxbDAiPjwvc3Bhbj48YnI+DQogICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJkMjEiIGlkPSJkMjFvMSIgb25jbGljaz0idXBkYXRlSVBTZXR1cERsZygpIj48c3BhbiBpZD0iZDIxbDEiPjwvc3Bhbj48YnI+DQogICAgICAgICAgICAgICAgPGRpdiBpZD0iaWRfZDIxbWFudWFsZGl2Ij4NCiAgICAgICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InJhZGlvIiBuYW1lPSJkMjEiIGlkPSdkMjFvMicgb25jbGljaz0idXBkYXRlSVBTZXR1cERsZygpIj48c3BhbiBpZD0iZDIxbDIiPjwvc3Bhbj48YnI+PGJyPg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJtYXJnaW4tbGVmdDoyMHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4Ij48aW5wdXQgaWQ9ImlkeF9kMjFhZGRyZXNzIiBvbmtleXVwPSJ1cGRhdGVJUFNldHVwRGxnKCkiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMzBweCI+PGRpdj5JUCBhZGRyZXNzPC9kaXY+PC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJoZWlnaHQ6MjZweCIgaWQ9ImlkX2QyMXN1Ym5ldGRpdiI+PGlucHV0IGlkPSJpZHhfZDIxc3VibmV0IiBvbmtleXVwPSJ1cGRhdGVJUFNldHVwRGxnKCkiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMzBweCI+PGRpdj5TdWJuZXQgbWFyazwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iaGVpZ2h0OjI2cHgiPjxpbnB1dCBpZD0iaWR4X2QyMWdhdGV3YXkiIG9ua2V5dXA9InVwZGF0ZUlQU2V0dXBEbGcoKSIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4Ij48ZGl2PkdhdGV3YXk8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4Ij48aW5wdXQgaWQ9ImlkeF9kMjFkbnMxIiBvbmtleXVwPSJ1cGRhdGVJUFNldHVwRGxnKCkiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMzBweCI+PGRpdj5QcmltYXJ5IEROUzwvZGl2PjwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0iaGVpZ2h0OjI2cHgiPjxpbnB1dCBpZD0iaWR4X2QyMWRuczIiIG9ua2V5dXA9InVwZGF0ZUlQU2V0dXBEbGcoKSIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4Ij48ZGl2PkFsdGVybmF0ZSBETlM8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDxkaXYgaWQ9ImRpYWxvZzIzIiBzdHlsZT0ibWFyZ2luOmF1dG87bWFyZ2luOjNweCI+DQogICAgICAgICAgICAgICAgPGJyPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9J2hlaWdodDoyNnB4Jz4NCiAgICAgICAgICAgICAgICAgICAgPHNlbGVjdCBpZD0iaWR4X2QyM2RkbnMiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCIgb25jaGFuZ2U9InNob3dFZGl0RG5zRGxnQ2hhbmdlKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMCI+RGlzYWJsZWQNCiAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjEiPkRpc2FibGVkLCBESENQIHVwZGF0ZQ0KICAgICAgICAgICAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT0iMiI+RW5hYmxlZA0KICAgICAgICAgICAgICAgICAgICA8L3NlbGVjdD4NCiAgICAgICAgICAgICAgICAgICAgPGRpdj5EeW5hbWljIEROUyBjbGllbnQ8L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSdoZWlnaHQ6MjZweCc+PGlucHV0IGlkPSJpZHhfZDIzaW50ZXJ2YWwiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoyMDBweCI+PGRpdj5VcGRhdGUgSW50ZXJ2YWwgKG1pbnV0ZXMpPC9kaXY+PC9kaXY+DQogICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0naGVpZ2h0OjI2cHgnPjxpbnB1dCBpZD0iaWR4X2QyM3R0bCIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4Ij48ZGl2PlRUTCAoc2Vjb25kcyk8L2Rpdj48L2Rpdj4NCiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJmb250LXNpemU6MTBweCI+PGJyPkRlZmF1dCBJbnRlcnZhbCBpcyAxNDQwIG1pbnV0ZXMsIERlZmF1bHQgVFRMIGlzIDkwMCBzZWNvbmRzLjwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGlkPSJkaWFsb2cyNSIgc3R5bGU9Im1hcmdpbjphdXRvO21hcmdpbjozcHgiPg0KICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9InRleHQtYWxpZ246bGVmdCI+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4Ij48aW5wdXQgaWQ9ImQyNWFsYXJtX25hbWUiIHN0eWxlPSJmbG9hdDpyaWdodDt3aWR0aDoxODBweCIgbWF4bGVuZ3RoPSIzMiIgb25rZXl1cD0iYWxlcnREaWFsb2dVcGRhdGUoKSI+PGRpdiBzdHlsZT0icGFkZGluZy10b3A6NHB4Ij5BbGFybSBuYW1lPC9kaXY+PC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9ImQyNWFsYXJtX3NkYXRlIiBzdHlsZT0id2lkdGg6MTgwcHgiIG1heGxlbmd0aD0iMTAiIG9ua2V5dXA9ImFsZXJ0RGlhbG9nVXBkYXRlKCkiIG9ua2V5cHJlc3M9InJldHVybiBudW1iZXJzT25seShldmVudCw0NSkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJwYWRkaW5nLXRvcDo0cHgiPldha2UgZGF0ZSAoeWVhci1tb250aC1kYXkpPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJoZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweCI+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJmbG9hdDpyaWdodCI+DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IGlkPSJkMjVhbGFybV9zdGltZSIgc3R5bGU9IndpZHRoOjE4MHB4IiBtYXhsZW5ndGg9IjEwIiBvbmtleXVwPSJhbGVydERpYWxvZ1VwZGF0ZSgpIiBvbmtleXByZXNzPSJyZXR1cm4gbnVtYmVyc09ubHkoZXZlbnQsNTgpIj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBzdHlsZT0icGFkZGluZy10b3A6NHB4Ij5XYWtlIHRpbWUgKGhvdXI6bWluOnNlYyk8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgaWQ9ImQyNWFsYXJtX2ludGVydmFsIiBzdHlsZT0id2lkdGg6MTgwcHgiIG1heGxlbmd0aD0iMTAiIG9ua2V5dXA9ImFsZXJ0RGlhbG9nVXBkYXRlKCkiIG9ua2V5cHJlc3M9InJldHVybiBudW1iZXJzT25seShldmVudCw0NSkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPSJwYWRkaW5nLXRvcDo0cHgiPkludGVydmFsIChkYXlzLWhvdXJzLW1pbik8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjE4MHB4Ij4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c2VsZWN0IGlkPSJkMjVhbGFybV9kb2MiIHN0eWxlPSJ3aWR0aDoxMDAlIiBvbmNoYW5nZT0ic2hvd0FkdlBvd2VyRGxnQ2hhbmdlKCkiPg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPSIwIj5LZWVwIGFsYXJtDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9IjEiPkRlbGV0ZSBvbiBjb21wbGV0aW9uDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zZWxlY3Q+DQogICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgc3R5bGU9InBhZGRpbmctdG9wOjRweCI+QWZ0ZXIgd2FrZTwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICA8L2Rpdj4NCiAgICAgICAgPGRpdiBzdHlsZT0icGFkZGluZzoxMHB4O21hcmdpbi1ib3R0b206NHB4Ij4NCiAgICAgICAgICAgIDxpbnB1dCBpZD0iaWR4X2RsZ0NhbmNlbEJ1dHRvbiIgdHlwZT0iYnV0dG9uIiB2YWx1ZT0iQ2FuY2VsIiBzdHlsZT0iZmxvYXQ6cmlnaHQ7d2lkdGg6ODBweDttYXJnaW4tbGVmdDo1cHgiIG9uY2xpY2s9ImRpYWxvZ2Nsb3NlKDApIj4NCiAgICAgICAgICAgIDxpbnB1dCBpZD0iaWR4X2RsZ09rQnV0dG9uIiB0eXBlPSJidXR0b24iIHZhbHVlPSJPSyIgc3R5bGU9ImZsb2F0OnJpZ2h0O3dpZHRoOjgwcHgiIG9uY2xpY2s9ImRpYWxvZ2Nsb3NlKDEpIj4NCiAgICAgICAgICAgIDxkaXYgc3R5bGU9ImhlaWdodDoyNXB4Ij48aW5wdXQgaWQ9ImlkeF9kbGdEZWxldGVCdXR0b24iIHR5cGU9ImJ1dHRvbiIgdmFsdWU9IkRlbGV0ZSIgc3R5bGU9IndpZHRoOjgwcHg7ZGlzcGxheTpub25lIiBvbmNsaWNrPSJkaWFsb2djbG9zZSgyKSI+PC9kaXY+DQogICAgICAgIDwvZGl2Pg0KICAgIDwvZGl2Pg0KICAgICAgICAgICAgICAgICAgICANCjwvYm9keT4NCjwvaHRtbD4NCjxzY3JpcHQ+LyoqIA0KKiBAZGVzY3JpcHRpb24gU2V0IG9mIHNob3J0IGNvbW1vbmx5IHVzZWQgbWV0aG9kcyBmb3IgaGFuZGxpbmcgSFRNTCBlbGVtZW50cw0KKiBAYXV0aG9yIFlsaWFuIFNhaW50LUhpbGFpcmUNCiogQHZlcnNpb24gdjAuMC4xYg0KKi8NCg0KLy8gQWRkIHN0YXJ0c1dpdGggZm9yIElFIGJyb3dzZXINCmlmICghU3RyaW5nLnByb3RvdHlwZS5zdGFydHNXaXRoKSB7IFN0cmluZy5wcm90b3R5cGUuc3RhcnRzV2l0aCA9IGZ1bmN0aW9uIChzdHIpIHsgcmV0dXJuIHRoaXMubGFzdEluZGV4T2Yoc3RyLCAwKSA9PT0gMDsgfTsgfQ0KaWYgKCFTdHJpbmcucHJvdG90eXBlLmVuZHNXaXRoKSB7IFN0cmluZy5wcm90b3R5cGUuZW5kc1dpdGggPSBmdW5jdGlvbiAoc3RyKSB7IHJldHVybiB0aGlzLmluZGV4T2Yoc3RyLCB0aGlzLmxlbmd0aCAtIHN0ci5sZW5ndGgpICE9PSAtMTsgfTsgfQ0KDQovLyBRdWljayBVSSBmdW5jdGlvbnMsIGEgYml0IG9mIGEgcmVwbGFjZW1lbnQgZm9yIGpRdWVyeQ0KLy9mdW5jdGlvbiBRKHgpIHsgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHgpID09IG51bGwpIHsgY29uc29sZS5sb2coJ0ludmFsaWQgZWxlbWVudDogJyArIHgpOyB9IHJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh4KTsgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyAiUSINCmZ1bmN0aW9uIFEoeCkgeyByZXR1cm4gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoeCk7IH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIlEiDQpmdW5jdGlvbiBRUyh4KSB7IHRyeSB7IHJldHVybiBRKHgpLnN0eWxlOyB9IGNhdGNoICh4KSB7IH0gfSAgICAgICAgICAgICAgICAgICAgIC8vICJRIiBzdHlsZQ0KZnVuY3Rpb24gUUUoeCwgeSkgeyB0cnkgeyBRKHgpLmRpc2FibGVkID0gIXk7IH0gY2F0Y2ggKHgpIHsgfSB9ICAgICAgICAgICAgICAgICAvLyAiUSIgZW5hYmxlDQpmdW5jdGlvbiBRVih4LCB5KSB7IHRyeSB7IFFTKHgpLmRpc3BsYXkgPSAoeSA/ICcnIDogJ25vbmUnKTsgfSBjYXRjaCAoeCkgeyB9IH0gIC8vICJRIiB2aXNpYmxlDQpmdW5jdGlvbiBRQSh4LCB5KSB7IFEoeCkuaW5uZXJIVE1MICs9IHk7IH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vICJRIiBhcHBlbmQNCmZ1bmN0aW9uIFFIKHgsIHkpIHsgUSh4KS5pbm5lckhUTUwgPSB5OyB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIlEiIGh0bWwNCg0KLy8gTW92ZSBjdXJzb3IgdG8gZW5kIG9mIGlucHV0IGJveA0KZnVuY3Rpb24gaW5wdXRCb3hGb2N1cyh4KSB7IFEoeCkuZm9jdXMoKTsgdmFyIHYgPSBRKHgpLnZhbHVlOyBRKHgpLnZhbHVlID0gJyc7IFEoeCkudmFsdWUgPSB2OyB9DQoNCi8vIEJpbmFyeSBlbmNvZGluZyBhbmQgZGVjb2RpbmcgZnVuY3Rpb25zDQpmdW5jdGlvbiBSZWFkU2hvcnQodiwgcCkgeyByZXR1cm4gKHYuY2hhckNvZGVBdChwKSA8PCA4KSArIHYuY2hhckNvZGVBdChwICsgMSk7IH0NCmZ1bmN0aW9uIFJlYWRTaG9ydFgodiwgcCkgeyByZXR1cm4gKHYuY2hhckNvZGVBdChwICsgMSkgPDwgOCkgKyB2LmNoYXJDb2RlQXQocCk7IH0NCmZ1bmN0aW9uIFJlYWRJbnQodiwgcCkgeyByZXR1cm4gKHYuY2hhckNvZGVBdChwKSAqIDB4MTAwMDAwMCkgKyAodi5jaGFyQ29kZUF0KHAgKyAxKSA8PCAxNikgKyAodi5jaGFyQ29kZUF0KHAgKyAyKSA8PCA4KSArIHYuY2hhckNvZGVBdChwICsgMyk7IH0gLy8gV2UgdXNlICIqMHgxMDAwMDAwIiBpbnN0ZWFkIG9mICI8PDI0IiBiZWNhdXNlIHRoZSBzaGlmdCBjb252ZXJ0cyB0aGUgbnVtYmVyIHRvIHNpZ25lZCBpbnQzMi4NCmZ1bmN0aW9uIFJlYWRTSW50KHYsIHApIHsgcmV0dXJuICh2LmNoYXJDb2RlQXQocCkgPDwgMjQpICsgKHYuY2hhckNvZGVBdChwICsgMSkgPDwgMTYpICsgKHYuY2hhckNvZGVBdChwICsgMikgPDwgOCkgKyB2LmNoYXJDb2RlQXQocCArIDMpOyB9DQpmdW5jdGlvbiBSZWFkSW50WCh2LCBwKSB7IHJldHVybiAodi5jaGFyQ29kZUF0KHAgKyAzKSAqIDB4MTAwMDAwMCkgKyAodi5jaGFyQ29kZUF0KHAgKyAyKSA8PCAxNikgKyAodi5jaGFyQ29kZUF0KHAgKyAxKSA8PCA4KSArIHYuY2hhckNvZGVBdChwKTsgfQ0KZnVuY3Rpb24gU2hvcnRUb1N0cih2KSB7IHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKCh2ID4+IDgpICYgMHhGRiwgdiAmIDB4RkYpOyB9DQpmdW5jdGlvbiBTaG9ydFRvU3RyWCh2KSB7IHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKHYgJiAweEZGLCAodiA+PiA4KSAmIDB4RkYpOyB9DQpmdW5jdGlvbiBJbnRUb1N0cih2KSB7IHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKCh2ID4+IDI0KSAmIDB4RkYsICh2ID4+IDE2KSAmIDB4RkYsICh2ID4+IDgpICYgMHhGRiwgdiAmIDB4RkYpOyB9DQpmdW5jdGlvbiBJbnRUb1N0clgodikgeyByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSh2ICYgMHhGRiwgKHYgPj4gOCkgJiAweEZGLCAodiA+PiAxNikgJiAweEZGLCAodiA+PiAyNCkgJiAweEZGKTsgfQ0KZnVuY3Rpb24gTWFrZVRvQXJyYXkodikgeyBpZiAoIXYgfHwgdiA9PSBudWxsIHx8IHR5cGVvZiB2ID09ICdvYmplY3QnKSByZXR1cm4gdjsgcmV0dXJuIFt2XTsgfQ0KZnVuY3Rpb24gU3BsaXRBcnJheSh2KSB7IHJldHVybiB2LnNwbGl0KCcsJyk7IH0NCmZ1bmN0aW9uIENsb25lKHYpIHsgcmV0dXJuIEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodikpOyB9DQpmdW5jdGlvbiBFc2NhcGVIdG1sKHgpIHsgaWYgKHR5cGVvZiB4ID09ICJzdHJpbmciKSByZXR1cm4geC5yZXBsYWNlKC8mL2csICcmYW1wOycpLnJlcGxhY2UoLz4vZywgJyZndDsnKS5yZXBsYWNlKC88L2csICcmbHQ7JykucmVwbGFjZSgvIi9nLCAnJnF1b3Q7JykucmVwbGFjZSgvJy9nLCAnJmFwb3M7Jyk7IGlmICh0eXBlb2YgeCA9PSAiYm9vbGVhbiIpIHJldHVybiB4OyBpZiAodHlwZW9mIHggPT0gIm51bWJlciIpIHJldHVybiB4OyB9DQoNCi8vIE1vdmUgYW4gZWxlbWVudCBmcm9tIG9uZSBwb3NpdGlvbiBpbiBhbiBhcnJheSB0byBhIG5ldyBwb3NpdGlvbg0KZnVuY3Rpb24gQXJyYXlFbGVtZW50TW92ZShhcnIsIGZyb20sIHRvKSB7IGFyci5zcGxpY2UodG8sIDAsIGFyci5zcGxpY2UoZnJvbSwgMSlbMF0pOyB9Ow0KDQovLyBQcmludCBvYmplY3QgZm9yIEhUTUwNCmZ1bmN0aW9uIE9iamVjdFRvU3RyaW5nRXgoeCwgYykgew0KICAgIHZhciByID0gIiI7DQogICAgaWYgKHggIT0gMCAmJiAoIXggfHwgeCA9PSBudWxsKSkgcmV0dXJuICIoTnVsbCkiOw0KICAgIGlmICh4IGluc3RhbmNlb2YgQXJyYXkpIHsgZm9yICh2YXIgaSBpbiB4KSB7IHIgKz0gJzxiciAvPicgKyBnYXAoYykgKyAiSXRlbSAjIiArIGkgKyAiOiAiICsgT2JqZWN0VG9TdHJpbmdFeCh4W2ldLCBjICsgMSk7IH0gfQ0KICAgIGVsc2UgaWYgKHggaW5zdGFuY2VvZiBPYmplY3QpIHsgZm9yICh2YXIgaSBpbiB4KSB7IHIgKz0gJzxiciAvPicgKyBnYXAoYykgKyBpICsgIiA9ICIgKyBPYmplY3RUb1N0cmluZ0V4KHhbaV0sIGMgKyAxKTsgfSB9DQogICAgZWxzZSB7IHIgKz0gRXNjYXBlSHRtbCh4KTsgfQ0KICAgIHJldHVybiByOw0KfQ0KDQovLyBQcmludCBvYmplY3QgZm9yIGNvbnNvbGUNCmZ1bmN0aW9uIE9iamVjdFRvU3RyaW5nRXgyKHgsIGMpIHsNCiAgICB2YXIgciA9ICIiOw0KICAgIGlmICh4ICE9IDAgJiYgKCF4IHx8IHggPT0gbnVsbCkpIHJldHVybiAiKE51bGwpIjsNCiAgICBpZiAoeCBpbnN0YW5jZW9mIEFycmF5KSB7IGZvciAodmFyIGkgaW4geCkgeyByICs9ICdcclxuJyArIGdhcDIoYykgKyAiSXRlbSAjIiArIGkgKyAiOiAiICsgT2JqZWN0VG9TdHJpbmdFeDIoeFtpXSwgYyArIDEpOyB9IH0NCiAgICBlbHNlIGlmICh4IGluc3RhbmNlb2YgT2JqZWN0KSB7IGZvciAodmFyIGkgaW4geCkgeyByICs9ICdcclxuJyArIGdhcDIoYykgKyBpICsgIiA9ICIgKyBPYmplY3RUb1N0cmluZ0V4Mih4W2ldLCBjICsgMSk7IH0gfQ0KICAgIGVsc2UgeyByICs9IEVzY2FwZUh0bWwoeCk7IH0NCiAgICByZXR1cm4gcjsNCn0NCg0KLy8gQ3JlYXRlIGFuIGlkZW50IGdhcA0KZnVuY3Rpb24gZ2FwKGMpIHsgdmFyIHggPSAnJzsgZm9yICh2YXIgaSA9IDA7IGkgPCAoYyAqIDQpIDsgaSsrKSB7IHggKz0gJyZuYnNwOyc7IH0gcmV0dXJuIHg7IH0NCmZ1bmN0aW9uIGdhcDIoYykgeyB2YXIgeCA9ICcnOyBmb3IgKHZhciBpID0gMDsgaSA8IChjICogNCkgOyBpKyspIHsgeCArPSAnICc7IH0gcmV0dXJuIHg7IH0NCg0KLy8gUHJpbnQgYW4gb2JqZWN0IGluIGh0bWwNCmZ1bmN0aW9uIE9iamVjdFRvU3RyaW5nKHgpIHsgcmV0dXJuIE9iamVjdFRvU3RyaW5nRXgoeCwgMCk7IH0NCmZ1bmN0aW9uIE9iamVjdFRvU3RyaW5nMih4KSB7IHJldHVybiBPYmplY3RUb1N0cmluZ0V4Mih4LCAwKTsgfQ0KDQovLyBDb252ZXJ0IGEgaGV4IHN0cmluZyB0byBhIHJhdyBzdHJpbmcNCmZ1bmN0aW9uIGhleDJyc3RyKGQpIHsNCiAgICBpZiAodHlwZW9mIGQgIT0gInN0cmluZyIgfHwgZC5sZW5ndGggPT0gMCkgcmV0dXJuICcnOw0KICAgIHZhciByID0gJycsIG0gPSAoJycgKyBkKS5tYXRjaCgvLi4vZyksIHQ7DQogICAgd2hpbGUgKHQgPSBtLnNoaWZ0KCkpIHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgnMHgnICsgdCk7DQogICAgcmV0dXJuIHINCn0NCg0KLy8gQ29udmVydCBkZWNpbWFsIHRvIGhleA0KZnVuY3Rpb24gY2hhcjJoZXgoaSkgeyByZXR1cm4gKGkgKyAweDEwMCkudG9TdHJpbmcoMTYpLnN1YnN0cigtMikudG9VcHBlckNhc2UoKTsgfQ0KDQovLyBDb252ZXJ0IGEgcmF3IHN0cmluZyB0byBhIGhleCBzdHJpbmcNCmZ1bmN0aW9uIHJzdHIyaGV4KGlucHV0KSB7DQogICAgdmFyIHIgPSAnJywgaTsNCiAgICBmb3IgKGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHsgciArPSBjaGFyMmhleChpbnB1dC5jaGFyQ29kZUF0KGkpKTsgfQ0KICAgIHJldHVybiByOw0KfQ0KDQovLyBVVEYtOCBlbmNvZGluZyAmIGRlY29kaW5nIGZ1bmN0aW9ucw0KZnVuY3Rpb24gZW5jb2RlX3V0ZjgocykgeyByZXR1cm4gdW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KHMpKTsgfQ0KZnVuY3Rpb24gZGVjb2RlX3V0ZjgocykgeyByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZShzKSk7IH0NCg0KLy8gQ29udmVydCBhIHN0cmluZyBpbnRvIGEgYmxvYg0KZnVuY3Rpb24gZGF0YTJibG9iKGRhdGEpIHsNCiAgICB2YXIgYnl0ZXMgPSBuZXcgQXJyYXkoZGF0YS5sZW5ndGgpOw0KICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykgYnl0ZXNbaV0gPSBkYXRhLmNoYXJDb2RlQXQoaSk7DQogICAgdmFyIGJsb2IgPSBuZXcgQmxvYihbbmV3IFVpbnQ4QXJyYXkoYnl0ZXMpXSk7DQogICAgcmV0dXJuIGJsb2I7DQp9DQoNCi8vIEdlbmVyYXRlIHJhbmRvbSBudW1iZXJzDQpmdW5jdGlvbiByYW5kb20obWF4KSB7IHJldHVybiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBtYXgpOyB9DQoNCi8vIFRyYWRlbWFya3MNCmZ1bmN0aW9uIHRyYWRlbWFya3MoeCkgeyByZXR1cm4geC5yZXBsYWNlKC9cKFJcKS9nLCAnJnJlZzsnKS5yZXBsYWNlKC9cKFRNXCkvZywgJyZ0cmFkZTsnKTsgfQ0KDQoNCi8qKiANCiogQGRlc2NyaXB0aW9uIEludGVsIEFNVCBMTVMgY29udHJvbCBtb2R1bGUgLSB1c2luZyB3ZWJzb2NrZXQNCiogQGF1dGhvciBZbGlhbiBTYWludC1IaWxhaXJlDQoqIEB2ZXJzaW9uIHYwLjAuMQ0KKi8NCg0KLy8gQ29uc3RydWN0IGEgTE1TIGNvbnRyb2wgb2JqZWN0DQp2YXIgQ3JlYXRlTG1zQ29udHJvbCA9IGZ1bmN0aW9uICgpIHsNCiAgICB2YXIgb2JqID0ge307DQogICAgdmFyIHNvY2tldCA9IG51bGw7DQogICAgb2JqLlN0YXRlID0gMDsNCiAgICBvYmoub25TdGF0ZUNoYW5nZWQgPSBudWxsOw0KICAgIG9iai5vbkRhdGEgPSBudWxsOw0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBvYmouU3RhcnQgPSBmdW5jdGlvbiAoKSB7DQogICAgICAgIHNvY2tldCA9IG5ldyBXZWJTb2NrZXQod2luZG93LmxvY2F0aW9uLnByb3RvY29sLnJlcGxhY2UoImh0dHAiLCAid3MiKSArICIvLyIgKyB3aW5kb3cubG9jYXRpb24uaG9zdCArICIvbG1zLmFzaHgiKTsNCiAgICAgICAgc29ja2V0Lm9ub3BlbiA9IF9PblNvY2tldENvbm5lY3RlZDsNCiAgICAgICAgc29ja2V0Lm9ubWVzc2FnZSA9IF9Pbk1lc3NhZ2U7DQogICAgICAgIHNvY2tldC5vbmNsb3NlID0gb2JqLlN0b3A7DQogICAgICAgIF9TdGF0ZUNoYW5nZSgxKTsNCiAgICB9DQoNCiAgICBmdW5jdGlvbiBfT25Tb2NrZXRDb25uZWN0ZWQoKSB7DQogICAgICAgIF9TdGF0ZUNoYW5nZSgyKTsNCiAgICB9DQoNCiAgICAvLyBTZXR1cCB0aGUgZmlsZSByZWFkZXINCiAgICB2YXIgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQogICAgdmFyIGZpbGVSZWFkZXJJbnVzZSA9IGZhbHNlLCBmaWxlUmVhZGVyQWNjID0gW107DQogICAgaWYgKGZpbGVSZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKSB7DQogICAgICAgIC8vIENocm9tZSAmIEZpcmVmb3ggKERyYWZ0KQ0KICAgICAgICBmaWxlUmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uIChlKSB7IF9PblNvY2tldERhdGEoZS50YXJnZXQucmVzdWx0KTsgaWYgKGZpbGVSZWFkZXJBY2MubGVuZ3RoID09IDApIHsgZmlsZVJlYWRlckludXNlID0gZmFsc2U7IH0gZWxzZSB7IGZpbGVSZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKG5ldyBCbG9iKFtmaWxlUmVhZGVyQWNjLnNoaWZ0KCldKSk7IH0gfQ0KICAgIH0gZWxzZSBpZiAoZmlsZVJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcikgew0KICAgICAgICAvLyBDaHJvbWUgJiBGaXJlZm94IChTcGVjKQ0KICAgICAgICBmaWxlUmVhZGVyLm9ubG9hZGVuZCA9IGZ1bmN0aW9uIChlKSB7IF9PblNvY2tldERhdGEoZS50YXJnZXQucmVzdWx0KTsgaWYgKGZpbGVSZWFkZXJBY2MubGVuZ3RoID09IDApIHsgZmlsZVJlYWRlckludXNlID0gZmFsc2U7IH0gZWxzZSB7IGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZmlsZVJlYWRlckFjYy5zaGlmdCgpKTsgfSB9DQogICAgfQ0KDQogICAgZnVuY3Rpb24gX09uTWVzc2FnZShlKSB7DQogICAgICAgIGlmICh0eXBlb2YgZS5kYXRhID09ICdvYmplY3QnKSB7DQogICAgICAgICAgICBpZiAoZmlsZVJlYWRlckludXNlID09IHRydWUpIHsgZmlsZVJlYWRlckFjYy5wdXNoKGUuZGF0YSk7IHJldHVybjsgfQ0KICAgICAgICAgICAgaWYgKGZpbGVSZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKSB7DQogICAgICAgICAgICAgICAgLy8gQ2hyb21lICYgRmlyZWZveCAoRHJhZnQpDQogICAgICAgICAgICAgICAgZmlsZVJlYWRlckludXNlID0gdHJ1ZTsNCiAgICAgICAgICAgICAgICBmaWxlUmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyhuZXcgQmxvYihbZS5kYXRhXSkpOw0KICAgICAgICAgICAgfSBlbHNlIGlmIChmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKSB7DQogICAgICAgICAgICAgICAgLy8gQ2hyb21lICYgRmlyZWZveCAoU3BlYykNCiAgICAgICAgICAgICAgICBmaWxlUmVhZGVySW51c2UgPSB0cnVlOw0KICAgICAgICAgICAgICAgIGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZS5kYXRhKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gSUUxMCwgcmVhZEFzQmluYXJ5U3RyaW5nIGRvZXMgbm90IGV4aXN0LCB1c2UgYW4gYWx0ZXJuYXRpdmUuDQogICAgICAgICAgICAgICAgdmFyIGJpbmFyeSA9ICIiLCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGUuZGF0YSksIGxlbmd0aCA9IGJ5dGVzLmJ5dGVMZW5ndGg7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7IH0NCiAgICAgICAgICAgICAgICBfT25Tb2NrZXREYXRhKGJpbmFyeSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBfT25Tb2NrZXREYXRhKGUuZGF0YSk7DQogICAgICAgIH0NCiAgICB9Ow0KICAgDQogICAgZnVuY3Rpb24gX09uU29ja2V0RGF0YShkYXRhKSB7DQogICAgICAgIGlmICghZGF0YSkgcmV0dXJuOw0KDQogICAgICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcpIHsNCiAgICAgICAgICAgIC8vIFRoaXMgaXMgYW4gQXJyYXlCdWZmZXIsIGNvbnZlcnQgaXQgdG8gYSBzdHJpbmcgYXJyYXkgKHVzZWQgaW4gSUUpDQogICAgICAgICAgICB2YXIgYmluYXJ5ID0gIiI7DQogICAgICAgICAgICB2YXIgYnl0ZXMgPSBuZXcgVWludDhBcnJheShkYXRhKTsNCiAgICAgICAgICAgIHZhciBsZW5ndGggPSBieXRlcy5ieXRlTGVuZ3RoOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7IH0NCiAgICAgICAgICAgIGRhdGEgPSBiaW5hcnk7DQogICAgICAgIH0NCiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRhdGEgIT09ICdzdHJpbmcnKSB7IHJldHVybjsgfQ0KDQogICAgICAgIC8vIFNlbmQgdGhlIGRhdGEgdXANCiAgICAgICAgaWYgKG9iai5vbkRhdGEgIT0gbnVsbCkgb2JqLm9uRGF0YShvYmosIGRhdGEpOw0KICAgIH0NCiAgICANCiAgICBmdW5jdGlvbiBfU2VuZCh4KSB7DQogICAgICAgIGlmIChzb2NrZXQgIT0gbnVsbCAmJiBzb2NrZXQucmVhZHlTdGF0ZSA9PSBXZWJTb2NrZXQuT1BFTikgew0KICAgICAgICAgICAgdmFyIGIgPSBuZXcgVWludDhBcnJheSh4Lmxlbmd0aCk7DQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyArK2kpIHsgYltpXSA9IHguY2hhckNvZGVBdChpKTsgfQ0KICAgICAgICAgICAgc29ja2V0LnNlbmQoYi5idWZmZXIpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgb2JqLlNlbmRDbWQgPSBmdW5jdGlvbiAoY21kaWQsIGRhdGEpIHsNCiAgICAgICAgaWYgKHNvY2tldCA9PSBudWxsIHx8IG9iai5TdGF0ZSAhPSAyKSByZXR1cm47DQogICAgICAgIGlmICghZGF0YSB8fCBkYXRhID09IG51bGwpIGRhdGEgPSAiIjsNCiAgICAgICAgX1NlbmQoU2hvcnRUb1N0clgoY21kaWQpICsgZGF0YSk7DQogICAgfQ0KDQogICAgZnVuY3Rpb24gX1N0YXRlQ2hhbmdlKG5ld3N0YXRlKSB7DQogICAgICAgIGlmIChvYmouU3RhdGUgPT0gbmV3c3RhdGUpIHJldHVybjsNCiAgICAgICAgb2JqLlN0YXRlID0gbmV3c3RhdGU7DQogICAgICAgIGlmIChvYmoub25TdGF0ZUNoYW5nZWQgIT0gbnVsbCkgb2JqLm9uU3RhdGVDaGFuZ2VkKG9iaiwgb2JqLlN0YXRlKTsNCiAgICB9DQoNCiAgICBvYmouU3RvcCA9IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgX1N0YXRlQ2hhbmdlKDApOw0KICAgICAgICBpZiAoc29ja2V0ICE9IG51bGwpIHsgc29ja2V0LmNsb3NlKCk7IHNvY2tldCA9IG51bGw7IH0NCiAgICB9DQoNCiAgICByZXR1cm4gb2JqOw0KfS8qKiANCiogQGRlc2NyaXB0aW9uIFdTTUFOIGNvbW11bmljYXRpb24gdXNpbmcgd2Vic29ja2V0DQoqIEBhdXRob3IgWWxpYW4gU2FpbnQtSGlsYWlyZQ0KKiBAdmVyc2lvbiB2MC4yLjBjDQoqLw0KDQovLyBDb25zdHJ1Y3QgYSBXU01BTiBjb21tdW5pY2F0aW9uIG9iamVjdA0KdmFyIENyZWF0ZVdzbWFuQ29tbSA9IGZ1bmN0aW9uIChob3N0LCBwb3J0LCB1c2VyLCBwYXNzLCB0bHMpIHsNCiAgICB2YXIgb2JqID0ge307DQogICAgb2JqLlBlbmRpbmdBamF4ID0gW107ICAgICAgICAgICAgICAgLy8gTGlzdCBvZiBwZW5kaW5nIEFKQVggY2FsbHMuIFdoZW4gb25lIGZyZWVzIHVwLCBhbm90aGVyIHdpbGwgc3RhcnQuDQogICAgb2JqLkFjdGl2ZUFqYXhDb3VudCA9IDA7ICAgICAgICAgICAgLy8gTnVtYmVyIG9mIGN1cnJlbnRseSBhY3RpdmUgQUpBWCBjYWxscw0KICAgIG9iai5NYXhBY3RpdmVBamF4Q291bnQgPSAxOyAgICAgICAgIC8vIE1heGltdW0gbnVtYmVyIG9mIGFjdGl2YXRlIEFKQVggY2FsbHMgYXQgdGhlIHNhbWUgdGltZS4NCiAgICBvYmouRmFpbEFsbEVycm9yID0gMDsgICAgICAgICAgICAgICAvLyBTZXQgdGhpcyB0byBub24temVybyB0byBmYWlsIGFsbCBBSkFYIGNhbGxzIHdpdGggdGhhdCBlcnJvciBzdGF0dXMsIDk5OSBjYXVzZXMgcmVzcG9uc2VzIHRvIGJlIHNpbGVudC4NCiAgICBvYmouY2hhbGxlbmdlUGFyYW1zID0gbnVsbDsNCiAgICBvYmoubm9uY2Vjb3VudGVyID0gMTsNCiAgICBvYmouYXV0aGNvdW50ZXIgPSAwOw0KICAgIG9iai5zb2NrZXQgPSBudWxsOw0KICAgIG9iai5zb2NrZXRTdGF0ZSA9IDA7DQogICAgb2JqLmhvc3QgPSBob3N0Ow0KICAgIG9iai5wb3J0ID0gcG9ydDsNCiAgICBvYmoudXNlciA9IHVzZXI7DQogICAgb2JqLnBhc3MgPSBwYXNzOw0KICAgIG9iai50bHMgPSB0bHM7DQogICAgb2JqLnRsc3Yxb25seSA9IDA7DQogICAgb2JqLmNub25jZSA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZyg3KTsgLy8gR2VuZXJhdGUgYSByYW5kb20gY2xpZW50IG5vbmNlDQogICAgb2JqLmluRGF0YUNvdW50ID0gMDsNCiAgICBvYmouYW10VmVyc2lvbiA9IG51bGw7DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIC8vb2JqLkRlYnVnID0gZnVuY3Rpb24gKG1zZykgeyBjb25zb2xlLmxvZyhtc2cpOyB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIC8vICAgcHJpID0gcHJpb3JpdHksIGlmIHNldCB0byAxLCB0aGUgY2FsbCBpcyBoaWdoIHByaW9yaXR5IGFuZCBwdXQgb24gdG9wIG9mIHRoZSBzdGFjay4NCiAgICBvYmouUGVyZm9ybUFqYXggPSBmdW5jdGlvbiAocG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHByaSwgdXJsLCBhY3Rpb24pIHsNCiAgICAgICAgaWYgKG9iai5BY3RpdmVBamF4Q291bnQgPCBvYmouTWF4QWN0aXZlQWpheENvdW50ICYmIG9iai5QZW5kaW5nQWpheC5sZW5ndGggPT0gMCkgew0KICAgICAgICAgICAgLy8gVGhlcmUgYXJlIG5vIHBlbmRpbmcgQUpBWCBjYWxscywgcGVyZm9ybSB0aGUgY2FsbCBub3cuDQogICAgICAgICAgICBvYmouUGVyZm9ybUFqYXhFeChwb3N0ZGF0YSwgY2FsbGJhY2ssIHRhZywgdXJsLCBhY3Rpb24pOw0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhIGhpZ2ggcHJpb3JpdHkgY2FsbCwgcHV0IHRoaXMgY2FsbCBpbiBmcm9udCBvZiB0aGUgYXJyYXksIG90aGVyd2lzZSBwdXQgaXQgaW4gdGhlIGJhY2suDQogICAgICAgICAgICBpZiAocHJpID09IDEpIHsgb2JqLlBlbmRpbmdBamF4LnVuc2hpZnQoW3Bvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCB1cmwsIGFjdGlvbl0pOyB9IGVsc2UgeyBvYmouUGVuZGluZ0FqYXgucHVzaChbcG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHVybCwgYWN0aW9uXSk7IH0NCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIC8vIFByaXZhdGUgbWV0aG9kDQogICAgb2JqLlBlcmZvcm1OZXh0QWpheCA9IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgaWYgKG9iai5BY3RpdmVBamF4Q291bnQgPj0gb2JqLk1heEFjdGl2ZUFqYXhDb3VudCB8fCBvYmouUGVuZGluZ0FqYXgubGVuZ3RoID09IDApIHJldHVybjsNCiAgICAgICAgdmFyIHggPSBvYmouUGVuZGluZ0FqYXguc2hpZnQoKTsNCiAgICAgICAgb2JqLlBlcmZvcm1BamF4RXgoeFswXSwgeFsxXSwgeFsyXSwgeFszXSwgeFs0XSk7DQogICAgICAgIG9iai5QZXJmb3JtTmV4dEFqYXgoKTsNCiAgICB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIG9iai5QZXJmb3JtQWpheEV4ID0gZnVuY3Rpb24gKHBvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCB1cmwsIGFjdGlvbikgew0KICAgICAgICBpZiAob2JqLkZhaWxBbGxFcnJvciAhPSAwKSB7IG9iai5nb3ROZXh0TWVzc2FnZXNFcnJvcih7IHN0YXR1czogb2JqLkZhaWxBbGxFcnJvciB9LCAnZXJyb3InLCBudWxsLCBbcG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHVybCwgYWN0aW9uXSk7IHJldHVybjsgfQ0KICAgICAgICBpZiAoIXBvc3RkYXRhKSBwb3N0ZGF0YSA9ICIiOw0KICAgICAgICAvL2NvbnNvbGUubG9nKCJTRU5EOiAiICsgcG9zdGRhdGEpOyAvLyBERUJVRw0KDQogICAgICAgIC8vIFdlIGFyZSBpbiBhIHdlYnNvY2tldCByZWxheSBlbnZpcm9ubWVudCANCiAgICAgICAgb2JqLkFjdGl2ZUFqYXhDb3VudCsrOw0KICAgICAgICByZXR1cm4gb2JqLlBlcmZvcm1BamF4RXhOb2RlSlMocG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHVybCwgYWN0aW9uKTsNCiAgICB9DQoNCiAgICAvLyBXZWJzb2NrZXQgcmVsYXkgc3BlY2lmaWMgcHJpdmF0ZSBtZXRob2QNCiAgICBvYmoucGVuZGluZ0FqYXhDYWxsID0gW107DQoNCiAgICAvLyBXZWJzb2NrZXQgcmVsYXkgc3BlY2lmaWMgcHJpdmF0ZSBtZXRob2QNCiAgICBvYmouUGVyZm9ybUFqYXhFeE5vZGVKUyA9IGZ1bmN0aW9uIChwb3N0ZGF0YSwgY2FsbGJhY2ssIHRhZywgdXJsLCBhY3Rpb24pIHsgb2JqLlBlcmZvcm1BamF4RXhOb2RlSlMyKHBvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCB1cmwsIGFjdGlvbiwgMyk7IH0NCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZA0KICAgIG9iai5QZXJmb3JtQWpheEV4Tm9kZUpTMiA9IGZ1bmN0aW9uIChwb3N0ZGF0YSwgY2FsbGJhY2ssIHRhZywgdXJsLCBhY3Rpb24sIHJldHJ5KSB7DQogICAgICAgIGlmIChyZXRyeSA8PSAwIHx8IG9iai5GYWlsQWxsRXJyb3IgIT0gMCkgew0KICAgICAgICAgICAgLy8gVG9vIG1hbnkgcmV0cnksIGZhaWwgaGVyZS4NCiAgICAgICAgICAgIG9iai5BY3RpdmVBamF4Q291bnQtLTsNCiAgICAgICAgICAgIGlmIChvYmouRmFpbEFsbEVycm9yICE9IDk5OSkgb2JqLmdvdE5leHRNZXNzYWdlcyhudWxsLCAnZXJyb3InLCB7IHN0YXR1czogKChvYmouRmFpbEFsbEVycm9yID09IDApID8gNDA4IDogb2JqLkZhaWxBbGxFcnJvcikgfSwgW3Bvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCB1cmwsIGFjdGlvbl0pOyAvLyA0MDggaXMgdGltZW91dCBlcnJvcg0KICAgICAgICAgICAgb2JqLlBlcmZvcm1OZXh0QWpheCgpOw0KICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICB9DQogICAgICAgIG9iai5wZW5kaW5nQWpheENhbGwucHVzaChbcG9zdGRhdGEsIGNhbGxiYWNrLCB0YWcsIHVybCwgYWN0aW9uLCByZXRyeV0pOw0KICAgICAgICBpZiAob2JqLnNvY2tldFN0YXRlID09IDApIHsgb2JqLnh4Q29ubmVjdEh0dHBTb2NrZXQoKTsgfQ0KICAgICAgICBlbHNlIGlmIChvYmouc29ja2V0U3RhdGUgPT0gMikgeyBvYmouc2VuZFJlcXVlc3QocG9zdGRhdGEsIHVybCwgYWN0aW9uKTsgfQ0KICAgIH0NCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZCAoQ29udGVudCBMZW5ndGggRW5jb2RpbmcpDQogICAgb2JqLnNlbmRSZXF1ZXN0ID0gZnVuY3Rpb24gKHBvc3RkYXRhLCB1cmwsIGFjdGlvbikgew0KICAgICAgICB1cmwgPSB1cmwgPyB1cmwgOiAiL3dzbWFuIjsNCiAgICAgICAgYWN0aW9uID0gYWN0aW9uID8gYWN0aW9uIDogIlBPU1QiOw0KICAgICAgICB2YXIgaCA9IGFjdGlvbiArICIgIiArIHVybCArICIgSFRUUC8xLjFcclxuIjsNCiAgICAgICAgaWYgKG9iai5jaGFsbGVuZ2VQYXJhbXMgIT0gbnVsbCkgew0KICAgICAgICAgICAgdmFyIHJlc3BvbnNlID0gaGV4X21kNShoZXhfbWQ1KG9iai51c2VyICsgJzonICsgb2JqLmNoYWxsZW5nZVBhcmFtc1sicmVhbG0iXSArICc6JyArIG9iai5wYXNzKSArICc6JyArIG9iai5jaGFsbGVuZ2VQYXJhbXNbIm5vbmNlIl0gKyAnOicgKyBvYmoubm9uY2Vjb3VudGVyICsgJzonICsgb2JqLmNub25jZSArICc6JyArIG9iai5jaGFsbGVuZ2VQYXJhbXNbInFvcCJdICsgJzonICsgaGV4X21kNShhY3Rpb24gKyAnOicgKyB1cmwpKTsNCiAgICAgICAgICAgIGggKz0gJ0F1dGhvcml6YXRpb246ICcgKyBvYmoucmVuZGVyRGlnZXN0KHsgInVzZXJuYW1lIjogb2JqLnVzZXIsICJyZWFsbSI6IG9iai5jaGFsbGVuZ2VQYXJhbXNbInJlYWxtIl0sICJub25jZSI6IG9iai5jaGFsbGVuZ2VQYXJhbXNbIm5vbmNlIl0sICJ1cmkiOiB1cmwsICJxb3AiOiBvYmouY2hhbGxlbmdlUGFyYW1zWyJxb3AiXSwgInJlc3BvbnNlIjogcmVzcG9uc2UsICJuYyI6IG9iai5ub25jZWNvdW50ZXIrKywgImNub25jZSI6IG9iai5jbm9uY2UgfSkgKyAnXHJcbic7DQogICAgICAgIH0NCiAgICAgICAgaCArPSAnSG9zdDogJyArIG9iai5ob3N0ICsgJzonICsgb2JqLnBvcnQgKyAnXHJcbkNvbnRlbnQtTGVuZ3RoOiAnICsgcG9zdGRhdGEubGVuZ3RoICsgJ1xyXG5cclxuJyArIHBvc3RkYXRhOyAvLyBVc2UgQ29udGVudC1MZW5ndGgNCiAgICAgICAgLy9oICs9ICdIb3N0OiAnICsgb2JqLmhvc3QgKyAnOicgKyBvYmoucG9ydCArICdcclxuVHJhbnNmZXItRW5jb2Rpbmc6IGNodW5rZWRcclxuXHJcbicgKyBwb3N0ZGF0YS5sZW5ndGgudG9TdHJpbmcoMTYpLnRvVXBwZXJDYXNlKCkgKyAnXHJcbicgKyBwb3N0ZGF0YSArICdcclxuMFxyXG5cclxuJzsgLy8gVXNlIENodW5rZWQtRW5jb2RpbmcNCiAgICAgICAgX1NlbmQoaCk7DQogICAgfQ0KDQogICAgLy8gV2Vic29ja2V0IHJlbGF5IHNwZWNpZmljIHByaXZhdGUgbWV0aG9kDQogICAgb2JqLnBhcnNlRGlnZXN0ID0gZnVuY3Rpb24gKGhlYWRlcikgew0KICAgICAgICB2YXIgdCA9IGhlYWRlci5zdWJzdHJpbmcoNykuc3BsaXQoJywnKTsNCiAgICAgICAgZm9yIChpIGluIHQpIHRbaV0gPSB0W2ldLnRyaW0oKTsNCiAgICAgICAgcmV0dXJuIHQucmVkdWNlKGZ1bmN0aW9uIChvYmosIHMpIHsgdmFyIHBhcnRzID0gcy5zcGxpdCgnPScpOyBvYmpbcGFydHNbMF1dID0gcGFydHNbMV0ucmVwbGFjZSgvIi9nLCAnJyk7IHJldHVybiBvYmo7IH0sIHt9KQ0KICAgIH0NCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZA0KICAgIG9iai5yZW5kZXJEaWdlc3QgPSBmdW5jdGlvbiAocGFyYW1zKSB7DQogICAgICAgIHZhciBwYXJhbXNuYW1lcyA9IFtdOw0KICAgICAgICBmb3IgKGkgaW4gcGFyYW1zKSB7IHBhcmFtc25hbWVzLnB1c2goaSk7IH0NCiAgICAgICAgcmV0dXJuICdEaWdlc3QgJyArIHBhcmFtc25hbWVzLnJlZHVjZShmdW5jdGlvbiAoczEsIGlpKSB7IHJldHVybiBzMSArICcsJyArIGlpICsgJz0iJyArIHBhcmFtc1tpaV0gKyAnIicgfSwgJycpLnN1YnN0cmluZygxKTsNCiAgICB9DQoNCiAgICAvLyBXZWJzb2NrZXQgcmVsYXkgc3BlY2lmaWMgcHJpdmF0ZSBtZXRob2QNCiAgICBvYmoueHhDb25uZWN0SHR0cFNvY2tldCA9IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgLy9vYmouRGVidWcoInh4Q29ubmVjdEh0dHBTb2NrZXQiKTsNCiAgICAgICAgb2JqLmluRGF0YUNvdW50ID0gMDsNCiAgICAgICAgb2JqLnNvY2tldFN0YXRlID0gMTsNCiAgICAgICAgb2JqLnNvY2tldCA9IG5ldyBXZWJTb2NrZXQod2luZG93LmxvY2F0aW9uLnByb3RvY29sLnJlcGxhY2UoImh0dHAiLCAid3MiKSArICIvLyIgKyB3aW5kb3cubG9jYXRpb24uaG9zdCArIHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZS5zdWJzdHJpbmcoMCwgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLmxhc3RJbmRleE9mKCcvJykpICsgIi93ZWJyZWxheS5hc2h4P3A9MSZob3N0PSIgKyBvYmouaG9zdCArICImcG9ydD0iICsgb2JqLnBvcnQgKyAiJnRscz0iICsgb2JqLnRscyArICImdGxzMW9ubHk9IiArIG9iai50bHN2MW9ubHkgKyAoKHVzZXIgPT0gJyonKSA/ICImc2VydmVyYXV0aD0xIiA6ICIiKSArICgodHlwZW9mIHBhc3MgPT09ICJ1bmRlZmluZWQiKSA/ICgiJnNlcnZlcmF1dGg9MSZ1c2VyPSIgKyB1c2VyKSA6ICIiKSk7IC8vIFRoZSAicD0xIiBpbmRpY2F0ZXMgdG8gdGhlIHJlbGF5IHRoYXQgdGhpcyBpcyBhIFdTTUFOIHNlc3Npb24NCiAgICAgICAgb2JqLnNvY2tldC5vbm9wZW4gPSBfT25Tb2NrZXRDb25uZWN0ZWQ7DQogICAgICAgIG9iai5zb2NrZXQub25tZXNzYWdlID0gX09uTWVzc2FnZTsNCiAgICAgICAgb2JqLnNvY2tldC5vbmNsb3NlID0gX09uU29ja2V0Q2xvc2VkOw0KICAgIH0NCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZA0KICAgIGZ1bmN0aW9uIF9PblNvY2tldENvbm5lY3RlZCgpIHsNCiAgICAgICAgb2JqLnNvY2tldFN0YXRlID0gMjsNCiAgICAgICAgb2JqLnNvY2tldFBhcnNlU3RhdGUgPSAwOw0KICAgICAgICBvYmouc29ja2V0QWNjdW11bGF0b3IgPSAnJzsNCiAgICAgICAgb2JqLnNvY2tldEhlYWRlciA9IG51bGw7DQogICAgICAgIG9iai5zb2NrZXREYXRhID0gJyc7DQogICAgICAgIC8vY29uc29sZS5sb2coInh4T25Tb2NrZXRDb25uZWN0ZWQiKTsNCiAgICAgICAgZm9yIChpIGluIG9iai5wZW5kaW5nQWpheENhbGwpIHsgb2JqLnNlbmRSZXF1ZXN0KG9iai5wZW5kaW5nQWpheENhbGxbaV1bMF0sIG9iai5wZW5kaW5nQWpheENhbGxbaV1bM10sIG9iai5wZW5kaW5nQWpheENhbGxbaV1bNF0pOyB9DQogICAgfQ0KDQogICAgLy8gU2V0dXAgdGhlIGZpbGUgcmVhZGVyDQogICAgdmFyIGZpbGVSZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpOw0KICAgIHZhciBmaWxlUmVhZGVySW51c2UgPSBmYWxzZSwgZmlsZVJlYWRlckFjYyA9IFtdOw0KICAgIGlmIChmaWxlUmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZykgew0KICAgICAgICAvLyBDaHJvbWUgJiBGaXJlZm94IChEcmFmdCkNCiAgICAgICAgZmlsZVJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoZSkgeyBfT25Tb2NrZXREYXRhKGUudGFyZ2V0LnJlc3VsdCk7IGlmIChmaWxlUmVhZGVyQWNjLmxlbmd0aCA9PSAwKSB7IGZpbGVSZWFkZXJJbnVzZSA9IGZhbHNlOyB9IGVsc2UgeyBmaWxlUmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyhuZXcgQmxvYihbZmlsZVJlYWRlckFjYy5zaGlmdCgpXSkpOyB9IH0NCiAgICB9IGVsc2UgaWYgKGZpbGVSZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIpIHsNCiAgICAgICAgLy8gQ2hyb21lICYgRmlyZWZveCAoU3BlYykNCiAgICAgICAgZmlsZVJlYWRlci5vbmxvYWRlbmQgPSBmdW5jdGlvbiAoZSkgeyBfT25Tb2NrZXREYXRhKGUudGFyZ2V0LnJlc3VsdCk7IGlmIChmaWxlUmVhZGVyQWNjLmxlbmd0aCA9PSAwKSB7IGZpbGVSZWFkZXJJbnVzZSA9IGZhbHNlOyB9IGVsc2UgeyBmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGZpbGVSZWFkZXJBY2Muc2hpZnQoKSk7IH0gfQ0KICAgIH0NCg0KICAgIGZ1bmN0aW9uIF9Pbk1lc3NhZ2UoZSkgew0KICAgICAgICBpZiAodHlwZW9mIGUuZGF0YSA9PSAnb2JqZWN0Jykgew0KICAgICAgICAgICAgaWYgKGZpbGVSZWFkZXJJbnVzZSA9PSB0cnVlKSB7IGZpbGVSZWFkZXJBY2MucHVzaChlLmRhdGEpOyByZXR1cm47IH0NCiAgICAgICAgICAgIGlmIChmaWxlUmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZykgew0KICAgICAgICAgICAgICAgIC8vIENocm9tZSAmIEZpcmVmb3ggKERyYWZ0KQ0KICAgICAgICAgICAgICAgIGZpbGVSZWFkZXJJbnVzZSA9IHRydWU7DQogICAgICAgICAgICAgICAgZmlsZVJlYWRlci5yZWFkQXNCaW5hcnlTdHJpbmcobmV3IEJsb2IoW2UuZGF0YV0pKTsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAoZmlsZVJlYWRlci5yZWFkQXNBcnJheUJ1ZmZlcikgew0KICAgICAgICAgICAgICAgIC8vIENocm9tZSAmIEZpcmVmb3ggKFNwZWMpDQogICAgICAgICAgICAgICAgZmlsZVJlYWRlckludXNlID0gdHJ1ZTsNCiAgICAgICAgICAgICAgICBmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKGUuZGF0YSk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIC8vIElFMTAsIHJlYWRBc0JpbmFyeVN0cmluZyBkb2VzIG5vdCBleGlzdCwgdXNlIGFuIGFsdGVybmF0aXZlLg0KICAgICAgICAgICAgICAgIHZhciBiaW5hcnkgPSAiIiwgYnl0ZXMgPSBuZXcgVWludDhBcnJheShlLmRhdGEpLCBsZW5ndGggPSBieXRlcy5ieXRlTGVuZ3RoOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsgYmluYXJ5ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXNbaV0pOyB9DQogICAgICAgICAgICAgICAgX09uU29ja2V0RGF0YShiaW5hcnkpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgX09uU29ja2V0RGF0YShlLmRhdGEpOw0KICAgICAgICB9DQogICAgfTsNCg0KICAgIC8vIFdlYnNvY2tldCByZWxheSBzcGVjaWZpYyBwcml2YXRlIG1ldGhvZA0KICAgIGZ1bmN0aW9uIF9PblNvY2tldERhdGEoZGF0YSkgew0KICAgICAgICAvL29iai5EZWJ1ZygiX09uU29ja2V0RGF0YSAoIiArIGRhdGEubGVuZ3RoICsgIik6ICIgKyBkYXRhKTsNCg0KICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT09ICdvYmplY3QnKSB7DQogICAgICAgICAgICAvLyBUaGlzIGlzIGFuIEFycmF5QnVmZmVyLCBjb252ZXJ0IGl0IHRvIGEgc3RyaW5nIGFycmF5ICh1c2VkIGluIElFKQ0KICAgICAgICAgICAgdmFyIGJpbmFyeSA9ICIiLCBieXRlcyA9IG5ldyBVaW50OEFycmF5KGRhdGEpLCBsZW5ndGggPSBieXRlcy5ieXRlTGVuZ3RoOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykgeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7IH0NCiAgICAgICAgICAgIGRhdGEgPSBiaW5hcnk7DQogICAgICAgIH0NCiAgICAgICAgZWxzZSBpZiAodHlwZW9mIGRhdGEgIT09ICdzdHJpbmcnKSByZXR1cm47DQoNCiAgICAgICAgLy9jb25zb2xlLmxvZygiUkVDVigiICsgb2JqLnNvY2tldFBhcnNlU3RhdGUgKyAiKTogIiArIGRhdGEpOyAvLyBERUJVRw0KDQogICAgICAgIG9iai5zb2NrZXRBY2N1bXVsYXRvciArPSBkYXRhOw0KICAgICAgICB3aGlsZSAodHJ1ZSkgew0KICAgICAgICAgICAgaWYgKG9iai5zb2NrZXRQYXJzZVN0YXRlID09IDApIHsNCiAgICAgICAgICAgICAgICB2YXIgaGVhZGVyc2l6ZSA9IG9iai5zb2NrZXRBY2N1bXVsYXRvci5pbmRleE9mKCJcclxuXHJcbiIpOw0KICAgICAgICAgICAgICAgIGlmIChoZWFkZXJzaXplIDwgMCkgcmV0dXJuOw0KICAgICAgICAgICAgICAgIC8vb2JqLkRlYnVnKG9iai5zb2NrZXRBY2N1bXVsYXRvci5zdWJzdHJpbmcoMCwgaGVhZGVyc2l6ZSkpOyAvLyBEaXNwbGF5IHJlY2VpdmVkIEhUVFAgaGVhZGVyDQogICAgICAgICAgICAgICAgb2JqLnNvY2tldEhlYWRlciA9IG9iai5zb2NrZXRBY2N1bXVsYXRvci5zdWJzdHJpbmcoMCwgaGVhZGVyc2l6ZSkuc3BsaXQoIlxyXG4iKTsNCiAgICAgICAgICAgICAgICBpZiAob2JqLmFtdFZlcnNpb24gPT0gbnVsbCkgeyBmb3IgKHZhciBpIGluIG9iai5zb2NrZXRIZWFkZXIpIHsgaWYgKG9iai5zb2NrZXRIZWFkZXJbaV0uaW5kZXhPZignU2VydmVyOiBJbnRlbChSKSBBY3RpdmUgTWFuYWdlbWVudCBUZWNobm9sb2d5ICcpID09IDApIHsgb2JqLmFtdFZlcnNpb24gPSBvYmouc29ja2V0SGVhZGVyW2ldLnN1YnN0cmluZyg0Nik7IH0gfSB9DQogICAgICAgICAgICAgICAgb2JqLnNvY2tldEFjY3VtdWxhdG9yID0gb2JqLnNvY2tldEFjY3VtdWxhdG9yLnN1YnN0cmluZyhoZWFkZXJzaXplICsgNCk7DQogICAgICAgICAgICAgICAgb2JqLnNvY2tldFBhcnNlU3RhdGUgPSAxOw0KICAgICAgICAgICAgICAgIG9iai5zb2NrZXREYXRhID0gJyc7DQogICAgICAgICAgICAgICAgb2JqLnNvY2tldFhIZWFkZXIgPSB7IERpcmVjdGl2ZTogb2JqLnNvY2tldEhlYWRlclswXS5zcGxpdCgnICcpIH07DQogICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZygiSGVhZGVyIiwgb2JqLnNvY2tldFhIZWFkZXIpOw0KICAgICAgICAgICAgICAgIGZvciAoaSBpbiBvYmouc29ja2V0SGVhZGVyKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChpICE9IDApIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4MiA9IG9iai5zb2NrZXRIZWFkZXJbaV0uaW5kZXhPZignOicpOw0KICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnNvY2tldFhIZWFkZXJbb2JqLnNvY2tldEhlYWRlcltpXS5zdWJzdHJpbmcoMCwgeDIpLnRvTG93ZXJDYXNlKCldID0gb2JqLnNvY2tldEhlYWRlcltpXS5zdWJzdHJpbmcoeDIgKyAyKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChvYmouc29ja2V0UGFyc2VTdGF0ZSA9PSAxKSB7DQogICAgICAgICAgICAgICAgdmFyIGNzaXplID0gLTE7DQogICAgICAgICAgICAgICAgaWYgKChvYmouc29ja2V0WEhlYWRlclsiY29ubmVjdGlvbiJdICE9IHVuZGVmaW5lZCkgJiYgKG9iai5zb2NrZXRYSGVhZGVyWyJjb25uZWN0aW9uIl0udG9Mb3dlckNhc2UoKSA9PSAnY2xvc2UnKSAmJiAoKG9iai5zb2NrZXRYSGVhZGVyWyJ0cmFuc2Zlci1lbmNvZGluZyJdID09IHVuZGVmaW5lZCkgfHwgKG9iai5zb2NrZXRYSGVhZGVyWyJ0cmFuc2Zlci1lbmNvZGluZyJdLnRvTG93ZXJDYXNlKCkgIT0gJ2NodW5rZWQnKSkpIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGJvZHkgZW5kcyB3aXRoIGEgY2xvc2UsIGluIHRoaXMgY2FzZSwgd2Ugd2lsbCBvbmx5IHByb2Nlc3MgdGhlIGhlYWRlcg0KICAgICAgICAgICAgICAgICAgICBjc2l6ZSA9IDA7DQogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvYmouc29ja2V0WEhlYWRlclsiY29udGVudC1sZW5ndGgiXSAhPSB1bmRlZmluZWQpIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGJvZHkgbGVuZ3RoIGlzIHNwZWNpZmllZCBieSB0aGUgY29udGVudC1sZW5ndGgNCiAgICAgICAgICAgICAgICAgICAgY3NpemUgPSBwYXJzZUludChvYmouc29ja2V0WEhlYWRlclsiY29udGVudC1sZW5ndGgiXSk7DQogICAgICAgICAgICAgICAgICAgIGlmIChvYmouc29ja2V0QWNjdW11bGF0b3IubGVuZ3RoIDwgY3NpemUpIHJldHVybjsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGRhdGEgPSBvYmouc29ja2V0QWNjdW11bGF0b3Iuc3Vic3RyaW5nKDAsIGNzaXplKTsNCiAgICAgICAgICAgICAgICAgICAgb2JqLnNvY2tldEFjY3VtdWxhdG9yID0gb2JqLnNvY2tldEFjY3VtdWxhdG9yLnN1YnN0cmluZyhjc2l6ZSk7DQogICAgICAgICAgICAgICAgICAgIG9iai5zb2NrZXREYXRhID0gZGF0YTsNCiAgICAgICAgICAgICAgICAgICAgY3NpemUgPSAwOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIC8vIFRoZSBib2R5IGlzIGNodW5rZWQNCiAgICAgICAgICAgICAgICAgICAgdmFyIGNsZW4gPSBvYmouc29ja2V0QWNjdW11bGF0b3IuaW5kZXhPZigiXHJcbiIpOw0KICAgICAgICAgICAgICAgICAgICBpZiAoY2xlbiA8IDApIHJldHVybjsgLy8gQ2h1bmsgbGVuZ3RoIG5vdCBmb3VuZCwgZXhpdCBub3cgYW5kIGdldCBtb3JlIGRhdGEuDQogICAgICAgICAgICAgICAgICAgIC8vIENodW5rIGxlbmd0aCBpZiBmb3VuZCwgbGV0cyBzZWUgaWYgd2UgY2FuIGdldCB0aGUgZGF0YS4NCiAgICAgICAgICAgICAgICAgICAgY3NpemUgPSBwYXJzZUludChvYmouc29ja2V0QWNjdW11bGF0b3Iuc3Vic3RyaW5nKDAsIGNsZW4pLCAxNik7DQogICAgICAgICAgICAgICAgICAgIGlmIChpc05hTihjc2l6ZSkpIHsgaWYgKG9iai53ZWJzb2NrZXQpIHsgb2JqLndlYnNvY2tldC5jbG9zZSgpOyB9IHJldHVybjsgfSAvLyBDcml0aWNhbCBlcnJvciwgY2xvc2UgdGhlIHNvY2tldCBhbmQgZXhpdC4NCiAgICAgICAgICAgICAgICAgICAgaWYgKG9iai5zb2NrZXRBY2N1bXVsYXRvci5sZW5ndGggPCBjbGVuICsgMiArIGNzaXplICsgMikgcmV0dXJuOw0KICAgICAgICAgICAgICAgICAgICAvLyBXZSBnb3QgYSBjaHVuayB3aXRoIGFsbCBvZiB0aGUgZGF0YSwgaGFuZGxlIHRoZSBjaHVuY2sgbm93Lg0KICAgICAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IG9iai5zb2NrZXRBY2N1bXVsYXRvci5zdWJzdHJpbmcoY2xlbiArIDIsIGNsZW4gKyAyICsgY3NpemUpOw0KICAgICAgICAgICAgICAgICAgICBvYmouc29ja2V0QWNjdW11bGF0b3IgPSBvYmouc29ja2V0QWNjdW11bGF0b3Iuc3Vic3RyaW5nKGNsZW4gKyAyICsgY3NpemUgKyAyKTsNCiAgICAgICAgICAgICAgICAgICAgb2JqLnNvY2tldERhdGEgKz0gZGF0YTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKGNzaXplID09IDApIHsNCiAgICAgICAgICAgICAgICAgICAgLy9vYmouRGVidWcoIl9PblNvY2tldERhdGEgRE9ORTogKCIgKyBvYmouc29ja2V0RGF0YS5sZW5ndGggKyAiKTogIiArIG9iai5zb2NrZXREYXRhKTsNCiAgICAgICAgICAgICAgICAgICAgX1Byb2Nlc3NIdHRwUmVzcG9uc2Uob2JqLnNvY2tldFhIZWFkZXIsIG9iai5zb2NrZXREYXRhKTsNCiAgICAgICAgICAgICAgICAgICAgb2JqLnNvY2tldFBhcnNlU3RhdGUgPSAwOw0KICAgICAgICAgICAgICAgICAgICBvYmouc29ja2V0SGVhZGVyID0gbnVsbDsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICB9DQoNCiAgICAvLyBXZWJzb2NrZXQgcmVsYXkgc3BlY2lmaWMgcHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfUHJvY2Vzc0h0dHBSZXNwb25zZShoZWFkZXIsIGRhdGEpIHsNCiAgICAgICAgLy9vYmouRGVidWcoIl9Qcm9jZXNzSHR0cFJlc3BvbnNlOiAiICsgaGVhZGVyLkRpcmVjdGl2ZVsxXSk7DQoNCiAgICAgICAgdmFyIHMgPSBwYXJzZUludChoZWFkZXIuRGlyZWN0aXZlWzFdKTsNCiAgICAgICAgaWYgKGlzTmFOKHMpKSB7DQogICAgICAgICAgICBzID0gNjAyOw0KICAgICAgICB9DQogICAgICAgIGlmIChzID09IDQwMSAmJiArKyhvYmouYXV0aGNvdW50ZXIpIDwgMykgew0KICAgICAgICAgICAgb2JqLmNoYWxsZW5nZVBhcmFtcyA9IG9iai5wYXJzZURpZ2VzdChoZWFkZXJbJ3d3dy1hdXRoZW50aWNhdGUnXSk7IC8vIFNldCB0aGUgZGlnZXN0IHBhcmFtZXRlcnMsIGFmdGVyIHRoaXMsIHRoZSBzb2NrZXQgd2lsbCBjbG9zZSBhbmQgd2Ugd2lsbCBhdXRvLXJldHJ5DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICB2YXIgciA9IG9iai5wZW5kaW5nQWpheENhbGwuc2hpZnQoKTsNCiAgICAgICAgICAgIC8vIGlmIChzICE9IDIwMCkgeyBvYmouRGVidWcoIkVycm9yLCBzdGF0dXM9IiArIHMgKyAiXHJcblxyXG5yZXE9IiArIHJbMF0gKyAiXHJcblxyXG5yZXNwPSIgKyBkYXRhKTsgfSAvLyBEZWJ1ZzogRGlzcGxheSB0aGUgcmVxdWVzdCAmIHJlc3BvbnNlIGlmIHNvbWV0aGluZyBkaWQgbm90IHdvcmsuDQogICAgICAgICAgICBvYmouYXV0aGNvdW50ZXIgPSAwOw0KICAgICAgICAgICAgb2JqLkFjdGl2ZUFqYXhDb3VudC0tOw0KICAgICAgICAgICAgb2JqLmdvdE5leHRNZXNzYWdlcyhkYXRhLCAnc3VjY2VzcycsIHsgc3RhdHVzOiBzIH0sIHIpOw0KICAgICAgICAgICAgb2JqLlBlcmZvcm1OZXh0QWpheCgpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8gV2Vic29ja2V0IHJlbGF5IHNwZWNpZmljIHByaXZhdGUgbWV0aG9kDQogICAgZnVuY3Rpb24gX09uU29ja2V0Q2xvc2VkKGRhdGEpIHsNCiAgICAgICAgLy9jb25zb2xlLmxvZygiX09uU29ja2V0Q2xvc2VkIik7DQogICAgICAgIGlmIChvYmouaW5EYXRhQ291bnQgPT0gMCkgeyBvYmoudGxzdjFvbmx5ID0gKDEgLSBvYmoudGxzdjFvbmx5KTsgfQ0KICAgICAgICBvYmouc29ja2V0U3RhdGUgPSAwOw0KICAgICAgICBpZiAob2JqLnNvY2tldCAhPSBudWxsKSB7IG9iai5zb2NrZXQuY2xvc2UoKTsgb2JqLnNvY2tldCA9IG51bGw7IH0NCiAgICAgICAgaWYgKG9iai5wZW5kaW5nQWpheENhbGwubGVuZ3RoID4gMCkgew0KICAgICAgICAgICAgdmFyIHIgPSBvYmoucGVuZGluZ0FqYXhDYWxsLnNoaWZ0KCk7DQogICAgICAgICAgICB2YXIgcmV0cnkgPSByWzVdOw0KICAgICAgICAgICAgb2JqLlBlcmZvcm1BamF4RXhOb2RlSlMyKHJbMF0sIHJbMV0sIHJbMl0sIHJbM10sIHJbNF0sIC0tcmV0cnkpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8gV2Vic29ja2V0IHJlbGF5IHNwZWNpZmljIHByaXZhdGUgbWV0aG9kDQogICAgZnVuY3Rpb24gX1NlbmQoeCkgew0KICAgICAgICAvL2NvbnNvbGUubG9nKCJTRU5EOiAiICsgeCk7IC8vIERFQlVHDQogICAgICAgIGlmIChvYmouc29ja2V0U3RhdGUgPT0gMiAmJiBvYmouc29ja2V0ICE9IG51bGwgJiYgb2JqLnNvY2tldC5yZWFkeVN0YXRlID09IFdlYlNvY2tldC5PUEVOKSB7DQogICAgICAgICAgICB2YXIgYiA9IG5ldyBVaW50OEFycmF5KHgubGVuZ3RoKTsNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeC5sZW5ndGg7ICsraSkgeyBiW2ldID0geC5jaGFyQ29kZUF0KGkpOyB9DQogICAgICAgICAgICB0cnkgeyBvYmouc29ja2V0LnNlbmQoYi5idWZmZXIpOyB9IGNhdGNoIChlKSB7IH0NCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIC8vIFByaXZhdGUgbWV0aG9kDQogICAgb2JqLmdvdE5leHRNZXNzYWdlcyA9IGZ1bmN0aW9uIChkYXRhLCBzdGF0dXMsIHJlcXVlc3QsIGNhbGxBcmdzKSB7DQogICAgICAgIGlmIChvYmouRmFpbEFsbEVycm9yID09IDk5OSkgcmV0dXJuOw0KICAgICAgICBpZiAob2JqLkZhaWxBbGxFcnJvciAhPSAwKSB7IGNhbGxBcmdzWzFdKG51bGwsIG9iai5GYWlsQWxsRXJyb3IsIGNhbGxBcmdzWzJdKTsgcmV0dXJuOyB9DQogICAgICAgIGlmIChyZXF1ZXN0LnN0YXR1cyAhPSAyMDApIHsgY2FsbEFyZ3NbMV0obnVsbCwgcmVxdWVzdC5zdGF0dXMsIGNhbGxBcmdzWzJdKTsgcmV0dXJuOyB9DQogICAgICAgIGNhbGxBcmdzWzFdKGRhdGEsIDIwMCwgY2FsbEFyZ3NbMl0pOw0KICAgIH0NCg0KICAgIC8vIFByaXZhdGUgbWV0aG9kDQogICAgb2JqLmdvdE5leHRNZXNzYWdlc0Vycm9yID0gZnVuY3Rpb24gKHJlcXVlc3QsIHN0YXR1cywgZXJyb3JUaHJvd24sIGNhbGxBcmdzKSB7DQogICAgICAgIGlmIChvYmouRmFpbEFsbEVycm9yID09IDk5OSkgcmV0dXJuOw0KICAgICAgICBpZiAob2JqLkZhaWxBbGxFcnJvciAhPSAwKSB7IGNhbGxBcmdzWzFdKG51bGwsIG9iai5GYWlsQWxsRXJyb3IsIGNhbGxBcmdzWzJdKTsgcmV0dXJuOyB9DQogICAgICAgIGNhbGxBcmdzWzFdKG9iaiwgbnVsbCwgeyBIZWFkZXI6IHsgSHR0cEVycm9yOiByZXF1ZXN0LnN0YXR1cyB9IH0sIHJlcXVlc3Quc3RhdHVzLCBjYWxsQXJnc1syXSk7DQogICAgfQ0KDQogICAgLy8gQ2FuY2VsIGFsbCBwZW5kaW5nIHF1ZXJpZXMgd2l0aCBnaXZlbiBzdGF0dXMNCiAgICBvYmouQ2FuY2VsQWxsUXVlcmllcyA9IGZ1bmN0aW9uIChzKSB7DQogICAgICAgIHdoaWxlIChvYmouUGVuZGluZ0FqYXgubGVuZ3RoID4gMCkgeyB2YXIgeCA9IG9iai5QZW5kaW5nQWpheC5zaGlmdCgpOyB4WzFdKG51bGwsIHMsIHhbMl0pOyB9DQogICAgICAgIGlmIChvYmoud2Vic29ja2V0ICE9IG51bGwpIHsgb2JqLndlYnNvY2tldC5jbG9zZSgpOyBvYmoud2Vic29ja2V0ID0gbnVsbDsgb2JqLnNvY2tldFN0YXRlID0gMDsgfQ0KICAgIH0NCg0KICAgIHJldHVybiBvYmo7DQp9DQoNCi8qKiANCiogQGRlc2NyaXB0aW9uIEludGVsKHIpIEFNVCBXU01BTiBTdGFjaw0KKiBAYXV0aG9yIFlsaWFuIFNhaW50LUhpbGFpcmUNCiogQHZlcnNpb24gdjAuMi4wDQoqLw0KDQovLyBDb25zdHJ1Y3QgYSBNZXNoU2VydmVyIG9iamVjdA0KdmFyIFdzbWFuU3RhY2tDcmVhdGVTZXJ2aWNlID0gZnVuY3Rpb24gKGhvc3QsIHBvcnQsIHVzZXIsIHBhc3MsIHRscywgZXh0cmEpIHsNCiAgICB2YXIgb2JqID0ge307DQogICAgLy9vYmoub25EZWJ1Z01lc3NhZ2UgPSBudWxsOyAgICAgICAgICAvLyBTZXQgdG8gYSBmdW5jdGlvbiBpZiB5b3Ugd2FudCB0byBnZXQgZGVidWcgbWVzc2FnZXMuDQogICAgb2JqLk5leHRNZXNzYWdlSWQgPSAxOyAgICAgICAgICAgICAgLy8gTmV4dCBtZXNzYWdlIG51bWJlciwgdXNlZCB0byBsYWJlbCBXU01BTiBjYWxscy4NCiAgICBvYmouQWRkcmVzcyA9ICcvd3NtYW4nOw0KICAgIG9iai5jb21tID0gQ3JlYXRlV3NtYW5Db21tKGhvc3QsIHBvcnQsIHVzZXIsIHBhc3MsIHRscywgZXh0cmEpOw0KDQogICAgb2JqLlBlcmZvcm1BamF4ID0gZnVuY3Rpb24gKHBvc3RkYXRhLCBjYWxsYmFjaywgdGFnLCBwcmksIG5hbWVzcGFjZXMpIHsNCiAgICAgICAgaWYgKG5hbWVzcGFjZXMgPT0gbnVsbCkgbmFtZXNwYWNlcyA9ICcnOw0KICAgICAgICBvYmouY29tbS5QZXJmb3JtQWpheCgnPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwidXRmLThcIj8+PEVudmVsb3BlIHhtbG5zOnhzaT1cImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlXCIgeG1sbnM6eHNkPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWFcIiB4bWxuczphPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciIHhtbG5zOnc9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMy8wNS9zb2FwLWVudmVsb3BlXCIgJyArIG5hbWVzcGFjZXMgKyAnPjxIZWFkZXI+PGE6QWN0aW9uPicgKyBwb3N0ZGF0YSwgZnVuY3Rpb24gKGRhdGEsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBjYWxsYmFjayhvYmosIG51bGwsIHsgSGVhZGVyOiB7IEh0dHBFcnJvcjogc3RhdHVzIH0gfSwgc3RhdHVzLCB0YWcpOyByZXR1cm47IH0NCiAgICAgICAgICAgIHZhciB3c3Jlc3BvbnNlID0gb2JqLlBhcnNlV3NtYW4oZGF0YSk7DQogICAgICAgICAgICBpZiAoIXdzcmVzcG9uc2UgfHwgd3NyZXNwb25zZSA9PSBudWxsKSB7IGNhbGxiYWNrKG9iaiwgbnVsbCwgeyBIZWFkZXI6IHsgSHR0cEVycm9yOiBzdGF0dXMgfSB9LCA2MDEsIHRhZyk7IH0gZWxzZSB7IGNhbGxiYWNrKG9iaiwgd3NyZXNwb25zZS5IZWFkZXJbIlJlc291cmNlVVJJIl0sIHdzcmVzcG9uc2UsIDIwMCwgdGFnKTsgfQ0KICAgICAgICB9LCB0YWcsIHByaSk7DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICAvL29iai5EZWJ1ZyA9IGZ1bmN0aW9uIChtc2cpIHsgLypjb25zb2xlLmxvZyhtc2cpOyovIH0NCg0KICAgIC8vIENhbmNlbCBhbGwgcGVuZGluZyBxdWVyaWVzIHdpdGggZ2l2ZW4gc3RhdHVzDQogICAgb2JqLkNhbmNlbEFsbFF1ZXJpZXMgPSBmdW5jdGlvbiAocykgeyBvYmouY29tbS5DYW5jZWxBbGxRdWVyaWVzKHMpOyB9DQoNCiAgICAvLyBHZXQgdGhlIGxhc3QgZWxlbWVudCBvZiBhIFVSSSBzdHJpbmcNCiAgICBvYmouR2V0TmFtZUZyb21VcmwgPSBmdW5jdGlvbiAocmVzdXJpKSB7DQogICAgICAgIHZhciB4ID0gcmVzdXJpLmxhc3RJbmRleE9mKCIvIik7DQogICAgICAgIHJldHVybiAoeCA9PSAtMSk/cmVzdXJpOnJlc3VyaS5zdWJzdHJpbmcoeCArIDEpOw0KICAgIH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiBTdWJzY3JpYmUgb3BlcmF0aW9uDQogICAgb2JqLkV4ZWNTdWJzY3JpYmUgPSBmdW5jdGlvbiAocmVzdXJpLCBkZWxpdmVyeSwgdXJsLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycywgb3BhcXVlLCB1c2VyLCBwYXNzKSB7DQogICAgICAgIHZhciBkaWdlc3QgPSAiIiwgZGlnZXN0MiA9ICIiLCBvcGFxdWUgPSAiIjsNCiAgICAgICAgaWYgKHVzZXIgIT0gbnVsbCAmJiBwYXNzICE9IG51bGwpIHsgZGlnZXN0ID0gJzx0Oklzc3VlZFRva2VucyB4bWxuczp0PSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzAyL3RydXN0IiB4bWxuczpzZT0iaHR0cDovL2RvY3Mub2FzaXMtb3Blbi5vcmcvd3NzLzIwMDQvMDEvb2FzaXMtMjAwNDAxLXdzcy13c3NlY3VyaXR5LXNlY2V4dC0xLjAueHNkIj48dDpSZXF1ZXN0U2VjdXJpdHlUb2tlblJlc3BvbnNlPjx0OlRva2VuVHlwZT5odHRwOi8vZG9jcy5vYXNpcy1vcGVuLm9yZy93c3MvMjAwNC8wMS9vYXNpcy0yMDA0MDEtd3NzLXVzZXJuYW1lLXRva2VuLXByb2ZpbGUtMS4wI1VzZXJuYW1lVG9rZW48L3Q6VG9rZW5UeXBlPjx0OlJlcXVlc3RlZFNlY3VyaXR5VG9rZW4+PHNlOlVzZXJuYW1lVG9rZW4+PHNlOlVzZXJuYW1lPicgKyB1c2VyICsgJzwvc2U6VXNlcm5hbWU+PHNlOlBhc3N3b3JkIFR5cGU9Imh0dHA6Ly9kb2NzLm9hc2lzLW9wZW4ub3JnL3dzcy8yMDA0LzAxL29hc2lzLTIwMDQwMS13c3Mtd3NzZWN1cml0eS1zZWNleHQtMS4wLnhzZCNQYXNzd29yZFRleHQiPicgKyBwYXNzICsgJzwvc2U6UGFzc3dvcmQ+PC9zZTpVc2VybmFtZVRva2VuPjwvdDpSZXF1ZXN0ZWRTZWN1cml0eVRva2VuPjwvdDpSZXF1ZXN0U2VjdXJpdHlUb2tlblJlc3BvbnNlPjwvdDpJc3N1ZWRUb2tlbnM+JzsgZGlnZXN0MiA9ICc8dzpBdXRoIFByb2ZpbGU9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi9zZWNwcm9maWxlL2h0dHAvZGlnZXN0Ii8+JzsgfQ0KICAgICAgICBpZiAob3BhcXVlICE9IG51bGwpIHsgb3BhcXVlID0gJzxhOlJlZmVyZW5jZVBhcmFtZXRlcnM+PG06YXJnPicgKyBvcGFxdWUgKyAnPC9tOmFyZz48L2E6UmVmZXJlbmNlUGFyYW1ldGVycz4nOyB9DQogICAgICAgIGlmIChkZWxpdmVyeSA9PSAnUHVzaFdpdGhBY2snKSB7IGRlbGl2ZXJ5ID0gJ2RtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi9QdXNoV2l0aEFjayc7IH0gZWxzZSBpZiAoZGVsaXZlcnkgPT0gJ1B1c2gnKSB7IGRlbGl2ZXJ5ID0gJ3htbHNvYXAub3JnL3dzLzIwMDQvMDgvZXZlbnRpbmcvRGVsaXZlcnlNb2Rlcy9QdXNoJzsgfQ0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2V2ZW50aW5nL1N1YnNjcmliZTwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz4iICsgX1B1dE9ialRvU2VsZWN0b3JzWG1sKHNlbGVjdG9ycykgKyBkaWdlc3QgKyAnPC9IZWFkZXI+PEJvZHk+PGU6U3Vic2NyaWJlPjxlOkRlbGl2ZXJ5IE1vZGU9Imh0dHA6Ly9zY2hlbWFzLicgKyBkZWxpdmVyeSArICciPjxlOk5vdGlmeVRvPjxhOkFkZHJlc3M+JyArIHVybCArICc8L2E6QWRkcmVzcz4nICsgb3BhcXVlICsgJzwvZTpOb3RpZnlUbz4nICsgZGlnZXN0MiArICc8L2U6RGVsaXZlcnk+PC9lOlN1YnNjcmliZT4nOw0KICAgICAgICBvYmouUGVyZm9ybUFqYXgoZGF0YSArICI8L0JvZHk+PC9FbnZlbG9wZT4iLCBjYWxsYmFjaywgdGFnLCBwcmksICd4bWxuczplPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2V2ZW50aW5nIiB4bWxuczptPSJodHRwOi8veC5jb20iJyk7DQogICAgfQ0KDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOIFVuU3Vic2NyaWJlIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjVW5TdWJzY3JpYmUgPSBmdW5jdGlvbiAocmVzdXJpLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycykgew0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2V2ZW50aW5nL1Vuc3Vic2NyaWJlPC9hOkFjdGlvbj48YTpUbz4iICsgb2JqLkFkZHJlc3MgKyAiPC9hOlRvPjx3OlJlc291cmNlVVJJPiIgKyByZXN1cmkgKyAiPC93OlJlc291cmNlVVJJPjxhOk1lc3NhZ2VJRD4iICsgKG9iai5OZXh0TWVzc2FnZUlkKyspICsgIjwvYTpNZXNzYWdlSUQ+PGE6UmVwbHlUbz48YTpBZGRyZXNzPmh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZy9yb2xlL2Fub255bW91czwvYTpBZGRyZXNzPjwvYTpSZXBseVRvPiIgKyBfUHV0T2JqVG9TZWxlY3RvcnNYbWwoc2VsZWN0b3JzKSArICc8L0hlYWRlcj48Qm9keT48ZTpVbnN1YnNjcmliZS8+JzsNCiAgICAgICAgb2JqLlBlcmZvcm1BamF4KGRhdGEgKyAiPC9Cb2R5PjwvRW52ZWxvcGU+IiwgY2FsbGJhY2ssIHRhZywgcHJpLCAneG1sbnM6ZT0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9ldmVudGluZyInKTsNCiAgICB9DQoNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gUFVUIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjUHV0ID0gZnVuY3Rpb24gKHJlc3VyaSwgcHV0b2JqLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycykgew0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L3RyYW5zZmVyL1B1dDwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjAuMDAwUzwvdzpPcGVyYXRpb25UaW1lb3V0PiIgKyBfUHV0T2JqVG9TZWxlY3RvcnNYbWwoc2VsZWN0b3JzKSArICc8L0hlYWRlcj48Qm9keT4nICsgX1B1dE9ialRvQm9keVhtbChyZXN1cmksIHB1dG9iaik7DQogICAgICAgIG9iai5QZXJmb3JtQWpheChkYXRhICsgIjwvQm9keT48L0VudmVsb3BlPiIsIGNhbGxiYWNrLCB0YWcsIHByaSk7DQogICAgfQ0KCQkNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gQ1JFQVRFIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjQ3JlYXRlID0gZnVuY3Rpb24gKHJlc3VyaSwgcHV0b2JqLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycykgew0KICAgICAgICB2YXIgb2JqbmFtZSA9IG9iai5HZXROYW1lRnJvbVVybChyZXN1cmkpOw0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L3RyYW5zZmVyL0NyZWF0ZTwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+IiArIF9QdXRPYmpUb1NlbGVjdG9yc1htbChzZWxlY3RvcnMpICsgIjwvSGVhZGVyPjxCb2R5PjxnOiIgKyBvYmpuYW1lICsgIiB4bWxuczpnPVwiIiArIHJlc3VyaSArICJcIj4iOw0KICAgICAgICBmb3IgKHZhciBuIGluIHB1dG9iaikgeyBkYXRhICs9ICI8ZzoiICsgbiArICI+IiArIHB1dG9ialtuXSArICI8L2c6IiArIG4gKyAiPiIgfSANCiAgICAgICAgb2JqLlBlcmZvcm1BamF4KGRhdGEgKyAiPC9nOiIgKyBvYmpuYW1lICsgIj48L0JvZHk+PC9FbnZlbG9wZT4iLCBjYWxsYmFjaywgdGFnLCBwcmkpOw0KICAgIH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiBERUxFVEUgb3BlcmF0aW9uDQogICAgb2JqLkV4ZWNEZWxldGUgPSBmdW5jdGlvbiAocmVzdXJpLCBwdXRvYmosIGNhbGxiYWNrLCB0YWcsIHByaSkgew0KICAgICAgICB2YXIgZGF0YSA9ICJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L3RyYW5zZmVyL0RlbGV0ZTwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+IiArIF9QdXRPYmpUb1NlbGVjdG9yc1htbChwdXRvYmopICsgIjwvSGVhZGVyPjxCb2R5IC8+PC9FbnZlbG9wZT4iOw0KICAgICAgICBvYmouUGVyZm9ybUFqYXgoZGF0YSwgY2FsbGJhY2ssIHRhZywgcHJpKTsNCiAgICB9DQoNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gR0VUIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjR2V0ID0gZnVuY3Rpb24gKHJlc3VyaSwgY2FsbGJhY2ssIHRhZywgcHJpKSB7DQogICAgICAgIG9iai5QZXJmb3JtQWpheCgiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOS90cmFuc2Zlci9HZXQ8L2E6QWN0aW9uPjxhOlRvPiIgKyBvYmouQWRkcmVzcyArICI8L2E6VG8+PHc6UmVzb3VyY2VVUkk+IiArIHJlc3VyaSArICI8L3c6UmVzb3VyY2VVUkk+PGE6TWVzc2FnZUlEPiIgKyAob2JqLk5leHRNZXNzYWdlSWQrKykgKyAiPC9hOk1lc3NhZ2VJRD48YTpSZXBseVRvPjxhOkFkZHJlc3M+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL3JvbGUvYW5vbnltb3VzPC9hOkFkZHJlc3M+PC9hOlJlcGx5VG8+PHc6T3BlcmF0aW9uVGltZW91dD5QVDYwUzwvdzpPcGVyYXRpb25UaW1lb3V0PjwvSGVhZGVyPjxCb2R5IC8+PC9FbnZlbG9wZT4iLCBjYWxsYmFjaywgdGFnLCBwcmkpOw0KICAgIH0NCg0KCS8vIFBlcmZvcm0gYSBXU01BTiBtZXRob2QgY2FsbCBvcGVyYXRpb24NCiAgICBvYmouRXhlY01ldGhvZCA9IGZ1bmN0aW9uIChyZXN1cmksIG1ldGhvZCwgYXJncywgY2FsbGJhY2ssIHRhZywgcHJpLCBzZWxlY3RvcnMpIHsNCiAgICAgICAgdmFyIGFyZ3N4bWwgPSAiIjsNCiAgICAgICAgZm9yICh2YXIgaSBpbiBhcmdzKSB7IGlmIChhcmdzW2ldICE9IG51bGwpIHsgaWYgKEFycmF5LmlzQXJyYXkoYXJnc1tpXSkpIHsgZm9yICh2YXIgeCBpbiBhcmdzW2ldKSB7IGFyZ3N4bWwgKz0gIjxyOiIgKyBpICsgIj4iICsgYXJnc1tpXVt4XSArICI8L3I6IiArIGkgKyAiPiI7IH0gfSBlbHNlIHsgYXJnc3htbCArPSAiPHI6IiArIGkgKyAiPiIgKyBhcmdzW2ldICsgIjwvcjoiICsgaSArICI+IjsgfSB9IH0NCiAgICAgICAgb2JqLkV4ZWNNZXRob2RYbWwocmVzdXJpLCBtZXRob2QsIGFyZ3N4bWwsIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKTsNCiAgICB9DQoJDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOIG1ldGhvZCBjYWxsIG9wZXJhdGlvbi4gVGhlIGFyZ3VtZW50cyBhcmUgYWxyZWFkeSBmb3JtYXR0ZWQgaW4gWE1MLg0KICAgIG9iai5FeGVjTWV0aG9kWG1sID0gZnVuY3Rpb24gKHJlc3VyaSwgbWV0aG9kLCBhcmdzeG1sLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycykgew0KICAgICAgICBvYmouUGVyZm9ybUFqYXgocmVzdXJpICsgIi8iICsgbWV0aG9kICsgIjwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+IiArIF9QdXRPYmpUb1NlbGVjdG9yc1htbChzZWxlY3RvcnMpICsgIjwvSGVhZGVyPjxCb2R5PjxyOiIgKyBtZXRob2QgKyAnX0lOUFVUJyArICIgeG1sbnM6cj1cIiIgKyByZXN1cmkgKyAiXCI+IiArIGFyZ3N4bWwgKyAiPC9yOiIgKyBtZXRob2QgKyAiX0lOUFVUPjwvQm9keT48L0VudmVsb3BlPiIsIGNhbGxiYWNrLCB0YWcsIHByaSk7DQogICAgfQ0KDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOIEVOVU0gb3BlcmF0aW9uDQogICAgb2JqLkV4ZWNFbnVtID0gZnVuY3Rpb24gKHJlc3VyaSwgY2FsbGJhY2ssIHRhZywgcHJpKSB7DQogICAgICAgIG9iai5QZXJmb3JtQWpheCgiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOS9lbnVtZXJhdGlvbi9FbnVtZXJhdGU8L2E6QWN0aW9uPjxhOlRvPiIgKyBvYmouQWRkcmVzcyArICI8L2E6VG8+PHc6UmVzb3VyY2VVUkk+IiArIHJlc3VyaSArICI8L3c6UmVzb3VyY2VVUkk+PGE6TWVzc2FnZUlEPiIgKyAob2JqLk5leHRNZXNzYWdlSWQrKykgKyAiPC9hOk1lc3NhZ2VJRD48YTpSZXBseVRvPjxhOkFkZHJlc3M+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL3JvbGUvYW5vbnltb3VzPC9hOkFkZHJlc3M+PC9hOlJlcGx5VG8+PHc6T3BlcmF0aW9uVGltZW91dD5QVDYwUzwvdzpPcGVyYXRpb25UaW1lb3V0PjwvSGVhZGVyPjxCb2R5PjxFbnVtZXJhdGUgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L2VudW1lcmF0aW9uXCIgLz48L0JvZHk+PC9FbnZlbG9wZT4iLCBjYWxsYmFjaywgdGFnLCBwcmkpOw0KICAgIH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiBQVUxMIG9wZXJhdGlvbg0KICAgIG9iai5FeGVjUHVsbCA9IGZ1bmN0aW9uIChyZXN1cmksIGVudW1jdHgsIGNhbGxiYWNrLCB0YWcsIHByaSkgew0KICAgICAgICBvYmouUGVyZm9ybUFqYXgoImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDkvZW51bWVyYXRpb24vUHVsbDwvYTpBY3Rpb24+PGE6VG8+IiArIG9iai5BZGRyZXNzICsgIjwvYTpUbz48dzpSZXNvdXJjZVVSST4iICsgcmVzdXJpICsgIjwvdzpSZXNvdXJjZVVSST48YTpNZXNzYWdlSUQ+IiArIChvYmouTmV4dE1lc3NhZ2VJZCsrKSArICI8L2E6TWVzc2FnZUlEPjxhOlJlcGx5VG8+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48L2E6UmVwbHlUbz48dzpPcGVyYXRpb25UaW1lb3V0PlBUNjBTPC93Ok9wZXJhdGlvblRpbWVvdXQ+PC9IZWFkZXI+PEJvZHk+PFB1bGwgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA5L2VudW1lcmF0aW9uXCI+PEVudW1lcmF0aW9uQ29udGV4dD4iICsgZW51bWN0eCArICI8L0VudW1lcmF0aW9uQ29udGV4dD48L1B1bGw+PC9Cb2R5PjwvRW52ZWxvcGU+IiwgY2FsbGJhY2ssIHRhZywgcHJpKTsgLy8gPC9FbnVtZXJhdGlvbkNvbnRleHQ+LS08TWF4RWxlbWVudHM+OTk5PC9NYXhFbGVtZW50cz48TWF4Q2hhcmFjdGVycz45OTk5OTwvTWF4Q2hhcmFjdGVycz4tLTwvUHVsbD4NCiAgICB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIG9iai5QYXJzZVdzbWFuID0gZnVuY3Rpb24gKHhtbCkgew0KICAgICAgICB0cnkgew0KICAgICAgICAgICAgaWYgKCF4bWwuY2hpbGROb2RlcykgeG1sID0gX3R1cm5Ub1htbCh4bWwpOw0KICAgICAgICAgICAgdmFyIHIgPSB7IEhlYWRlcjp7fSB9LCBoZWFkZXIgPSB4bWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIkhlYWRlciIpWzBdLCB0Ow0KICAgICAgICAgICAgaWYgKCFoZWFkZXIpIGhlYWRlciA9IHhtbC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiYTpIZWFkZXIiKVswXTsNCiAgICAgICAgICAgIGlmICghaGVhZGVyKSByZXR1cm4gbnVsbDsNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGVhZGVyLmNoaWxkTm9kZXMubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgICAgICB2YXIgY2hpbGQgPSBoZWFkZXIuY2hpbGROb2Rlc1tpXTsNCiAgICAgICAgICAgICAgICByLkhlYWRlcltjaGlsZC5sb2NhbE5hbWVdID0gY2hpbGQudGV4dENvbnRlbnQ7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB2YXIgYm9keSA9IHhtbC5nZXRFbGVtZW50c0J5VGFnTmFtZSgiQm9keSIpWzBdOw0KICAgICAgICAgICAgaWYgKCFib2R5KSBib2R5ID0geG1sLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJhOkJvZHkiKVswXTsNCiAgICAgICAgICAgIGlmICghYm9keSkgcmV0dXJuIG51bGw7DQogICAgICAgICAgICBpZiAoYm9keS5jaGlsZE5vZGVzLmxlbmd0aCA+IDApIHsNCiAgICAgICAgICAgICAgICB0ID0gYm9keS5jaGlsZE5vZGVzWzBdLmxvY2FsTmFtZTsNCiAgICAgICAgICAgICAgICBpZiAodC5pbmRleE9mKCJfT1VUUFVUIikgPT0gdC5sZW5ndGggLSA3KSB7IHQgPSB0LnN1YnN0cmluZygwLCB0Lmxlbmd0aCAtIDcpOyB9DQogICAgICAgICAgICAgICAgci5IZWFkZXJbJ01ldGhvZCddID0gdDsNCiAgICAgICAgICAgICAgICByLkJvZHkgPSBfUGFyc2VXc21hblJlYyhib2R5LmNoaWxkTm9kZXNbMF0pOw0KCQkgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIHI7DQogICAgICAgIH0gY2F0Y2ggKGUpIHsNCiAgICAgICAgICAgIGNvbnNvbGUubG9nKCJVbmFibGUgdG8gcGFyc2UgWE1MOiAiICsgeG1sKTsNCiAgICAgICAgICAgIHJldHVybiBudWxsOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfUGFyc2VXc21hblJlYyhub2RlKSB7DQogICAgICAgIHZhciBkYXRhLCByID0ge307DQogICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZS5jaGlsZE5vZGVzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICB2YXIgY2hpbGQgPSBub2RlLmNoaWxkTm9kZXNbaV07DQogICAgICAgICAgICBpZiAoKGNoaWxkLmNoaWxkRWxlbWVudENvdW50ID09IG51bGwpIHx8IChjaGlsZC5jaGlsZEVsZW1lbnRDb3VudCA9PSAwKSkgeyBkYXRhID0gY2hpbGQudGV4dENvbnRlbnQ7IH0gZWxzZSB7IGRhdGEgPSBfUGFyc2VXc21hblJlYyhjaGlsZCk7IH0NCiAgICAgICAgICAgIGlmIChkYXRhID09ICd0cnVlJykgZGF0YSA9IHRydWU7IC8vIENvbnZlcnQgJ3RydWUnIGludG8gdHJ1ZQ0KICAgICAgICAgICAgaWYgKGRhdGEgPT0gJ2ZhbHNlJykgZGF0YSA9IGZhbHNlOyAvLyBDb252ZXJ0ICdmYWxzZScgaW50byBmYWxzZQ0KICAgICAgICAgICAgaWYgKChwYXJzZUludChkYXRhKSArICcnKSA9PT0gZGF0YSkgZGF0YSA9IHBhcnNlSW50KGRhdGEpOyAvLyBDb252ZXJ0IGludGVnZXJzDQoNCiAgICAgICAgICAgIHZhciBjaGlsZE9iaiA9IGRhdGE7DQogICAgICAgICAgICBpZiAoKGNoaWxkLmF0dHJpYnV0ZXMgIT0gbnVsbCkgJiYgKGNoaWxkLmF0dHJpYnV0ZXMubGVuZ3RoID4gMCkpIHsNCgkJCQljaGlsZE9iaiA9IHsgJ1ZhbHVlJzogZGF0YSB9Ow0KCQkJCWZvcih2YXIgaiA9IDA7IGogPCBjaGlsZC5hdHRyaWJ1dGVzLmxlbmd0aDsgaisrKSB7DQoJCQkJCWNoaWxkT2JqWydAJyArIGNoaWxkLmF0dHJpYnV0ZXNbal0ubmFtZV0gPSBjaGlsZC5hdHRyaWJ1dGVzW2pdLnZhbHVlOw0KCQkJCX0NCgkJCX0NCgkJCQ0KICAgICAgICAgICAgaWYgKHJbY2hpbGQubG9jYWxOYW1lXSBpbnN0YW5jZW9mIEFycmF5KSB7IHJbY2hpbGQubG9jYWxOYW1lXS5wdXNoKGNoaWxkT2JqKTsgfQ0KICAgICAgICAgICAgZWxzZSBpZiAocltjaGlsZC5sb2NhbE5hbWVdID09IG51bGwpIHsgcltjaGlsZC5sb2NhbE5hbWVdID0gY2hpbGRPYmo7IH0NCiAgICAgICAgICAgIGVsc2UgeyByW2NoaWxkLmxvY2FsTmFtZV0gPSBbcltjaGlsZC5sb2NhbE5hbWVdLCBjaGlsZE9ial07IH0NCiAgICAgICAgfQ0KICAgICAgICByZXR1cm4gcjsNCiAgICB9DQoNCiAgICBmdW5jdGlvbiBfUHV0T2JqVG9Cb2R5WG1sKHJlc3VyaSwgcHV0T2JqKSB7DQogICAgICAgIGlmICghcmVzdXJpIHx8IHB1dE9iaiA9PSBudWxsKSByZXR1cm4gJyc7DQoJCXZhciBvYmpuYW1lID0gb2JqLkdldE5hbWVGcm9tVXJsKHJlc3VyaSk7DQoJCXZhciByZXN1bHQgPSAnPHI6JyArIG9iam5hbWUgKyAnIHhtbG5zOnI9IicgKyByZXN1cmkgKyAnIj4nOw0KDQoJCWZvciAodmFyIHByb3AgaW4gcHV0T2JqKSB7DQoJCQlpZiAoIXB1dE9iai5oYXNPd25Qcm9wZXJ0eShwcm9wKSB8fCBwcm9wLmluZGV4T2YoJ19fJykgPT09IDAgfHwgcHJvcC5pbmRleE9mKCdAJykgPT09IDApIGNvbnRpbnVlOw0KCQkJaWYgKHB1dE9ialtwcm9wXSA9PSBudWxsIHx8IHR5cGVvZiBwdXRPYmpbcHJvcF0gPT09ICdmdW5jdGlvbicpIGNvbnRpbnVlOw0KCQkJaWYgKHR5cGVvZiBwdXRPYmpbcHJvcF0gPT09ICdvYmplY3QnICYmIHB1dE9ialtwcm9wXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddKSB7DQoJCQkJcmVzdWx0ICs9ICc8cjonICsgcHJvcCArICc+PGE6QWRkcmVzcz4nICsgcHV0T2JqW3Byb3BdLkFkZHJlc3MgKyAnPC9hOkFkZHJlc3M+PGE6UmVmZXJlbmNlUGFyYW1ldGVycz48dzpSZXNvdXJjZVVSST4nICsgcHV0T2JqW3Byb3BdWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bIlJlc291cmNlVVJJIl0gKyAnPC93OlJlc291cmNlVVJJPjx3OlNlbGVjdG9yU2V0Pic7DQoJCQkJdmFyIHNlbGVjdG9yQXJyYXkgPSBwdXRPYmpbcHJvcF1bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXTsNCgkJCQlpZiAoQXJyYXkuaXNBcnJheShzZWxlY3RvckFycmF5KSkgew0KCQkJCQlmb3IgKHZhciBpPTA7IGk8IHNlbGVjdG9yQXJyYXkubGVuZ3RoOyBpKyspIHsNCgkJCQkJCXJlc3VsdCArPSAnPHc6U2VsZWN0b3InICsgX09iamVjdFRvWG1sQXR0cmlidXRlcyhzZWxlY3RvckFycmF5W2ldKSArICc+JyArIHNlbGVjdG9yQXJyYXlbaV1bJ1ZhbHVlJ10gKyAnPC93OlNlbGVjdG9yPic7DQoJCQkJCX0NCgkJCQl9DQoJCQkJZWxzZSB7DQoJCQkJCXJlc3VsdCArPSAnPHc6U2VsZWN0b3InICsgX09iamVjdFRvWG1sQXR0cmlidXRlcyhzZWxlY3RvckFycmF5KSArICc+JyArIHNlbGVjdG9yQXJyYXlbJ1ZhbHVlJ10gKyAnPC93OlNlbGVjdG9yPic7DQoJCQkJfQ0KCQkJCXJlc3VsdCArPSAnPC93OlNlbGVjdG9yU2V0PjwvYTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjwvcjonICsgcHJvcCArICc+JzsNCgkJCX0NCgkJCWVsc2Ugew0KCQkJICAgIGlmIChBcnJheS5pc0FycmF5KHB1dE9ialtwcm9wXSkpIHsNCgkJCSAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwdXRPYmpbcHJvcF0ubGVuZ3RoOyBpKyspIHsNCgkJCSAgICAgICAgICAgIHJlc3VsdCArPSAnPHI6JyArIHByb3AgKyAnPicgKyBwdXRPYmpbcHJvcF1baV0udG9TdHJpbmcoKSArICc8L3I6JyArIHByb3AgKyAnPic7DQoJCQkgICAgICAgIH0NCgkJCSAgICB9IGVsc2Ugew0KCQkJICAgICAgICByZXN1bHQgKz0gJzxyOicgKyBwcm9wICsgJz4nICsgcHV0T2JqW3Byb3BdLnRvU3RyaW5nKCkgKyAnPC9yOicgKyBwcm9wICsgJz4nOw0KCQkJICAgIH0NCgkJCX0NCgkJfQ0KDQoJCXJlc3VsdCArPSAnPC9yOicgKyBvYmpuYW1lICsgJz4nOw0KCQlyZXR1cm4gcmVzdWx0Ow0KCX0NCg0KCS8qIA0KCWNvbnZlcnQgDQoJCXsgQE5hbWU6ICdJbnN0YW5jZUlEJywgQEF0dHJOYW1lOiAnQXR0cmlidXRlIFZhbHVlJ30NCglpbnRvDQoJCScgTmFtZT0iSW5zdGFuY2VJRCIgQXR0ck5hbWU9IkF0dHJpYnV0ZSBWYWx1ZSIgJw0KCSovDQogICAgZnVuY3Rpb24gX09iamVjdFRvWG1sQXR0cmlidXRlcyhvYmpXaXRoQXR0cmlidXRlcykgew0KCQlpZighb2JqV2l0aEF0dHJpYnV0ZXMpIHJldHVybiAnJzsNCgkJdmFyIHJlc3VsdCA9ICcnOw0KCQlmb3IgKHZhciBwcm9wTmFtZSBpbiBvYmpXaXRoQXR0cmlidXRlcykgew0KCQkJaWYgKCFvYmpXaXRoQXR0cmlidXRlcy5oYXNPd25Qcm9wZXJ0eShwcm9wTmFtZSkgfHwgcHJvcE5hbWUuaW5kZXhPZignQCcpICE9PSAwKSBjb250aW51ZTsNCgkJCXJlc3VsdCArPSAnICcgKyBwcm9wTmFtZS5zdWJzdHJpbmcoMSkgKyAnPSInICsgb2JqV2l0aEF0dHJpYnV0ZXNbcHJvcE5hbWVdICsgJyInOw0KCQl9DQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KDQogICAgZnVuY3Rpb24gX1B1dE9ialRvU2VsZWN0b3JzWG1sKHNlbGVjdG9yU2V0KSB7DQogICAgICAgIGlmICghc2VsZWN0b3JTZXQpIHJldHVybiAnJzsNCiAgICAgICAgaWYgKHR5cGVvZiBzZWxlY3RvclNldCA9PSAnc3RyaW5nJykgcmV0dXJuIHNlbGVjdG9yU2V0Ow0KICAgICAgICBpZiAoc2VsZWN0b3JTZXRbJ0luc3RhbmNlSUQnXSkgcmV0dXJuICI8dzpTZWxlY3RvclNldD48dzpTZWxlY3RvciBOYW1lPVwiSW5zdGFuY2VJRFwiPiIgKyBzZWxlY3RvclNldFsnSW5zdGFuY2VJRCddICsgIjwvdzpTZWxlY3Rvcj48L3c6U2VsZWN0b3JTZXQ+IjsNCgkJdmFyIHJlc3VsdCA9ICc8dzpTZWxlY3RvclNldD4nOw0KCQlmb3IodmFyIHByb3BOYW1lIGluIHNlbGVjdG9yU2V0KSB7DQoJCSAgICBpZiAoIXNlbGVjdG9yU2V0Lmhhc093blByb3BlcnR5KHByb3BOYW1lKSkgY29udGludWU7DQoJCSAgICByZXN1bHQgKz0gJzx3OlNlbGVjdG9yIE5hbWU9IicgKyBwcm9wTmFtZSArICciPic7DQoJCSAgICBpZiAoc2VsZWN0b3JTZXRbcHJvcE5hbWVdWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ10pIHsNCgkJICAgICAgICByZXN1bHQgKz0gJzxhOkVuZHBvaW50UmVmZXJlbmNlPic7DQoJCSAgICAgICAgcmVzdWx0ICs9ICc8YTpBZGRyZXNzPicgKyBzZWxlY3RvclNldFtwcm9wTmFtZV1bJ0FkZHJlc3MnXSArICc8L2E6QWRkcmVzcz48YTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjx3OlJlc291cmNlVVJJPicgKyBzZWxlY3RvclNldFtwcm9wTmFtZV1bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnUmVzb3VyY2VVUkknXSArICc8L3c6UmVzb3VyY2VVUkk+PHc6U2VsZWN0b3JTZXQ+JzsNCgkJICAgICAgICB2YXIgc2VsZWN0b3JBcnJheSA9IHNlbGVjdG9yU2V0W3Byb3BOYW1lXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddOw0KCQkgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHNlbGVjdG9yQXJyYXkpKSB7DQoJCSAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VsZWN0b3JBcnJheS5sZW5ndGg7IGkrKykgew0KCQkgICAgICAgICAgICAgICAgcmVzdWx0ICs9ICc8dzpTZWxlY3RvcicgKyBfT2JqZWN0VG9YbWxBdHRyaWJ1dGVzKHNlbGVjdG9yQXJyYXlbaV0pICsgJz4nICsgc2VsZWN0b3JBcnJheVtpXVsnVmFsdWUnXSArICc8L3c6U2VsZWN0b3I+JzsNCgkJICAgICAgICAgICAgfQ0KCQkgICAgICAgIH0NCgkJICAgICAgICBlbHNlIHsNCgkJICAgICAgICAgICAgcmVzdWx0ICs9ICc8dzpTZWxlY3RvcicgKyBfT2JqZWN0VG9YbWxBdHRyaWJ1dGVzKHNlbGVjdG9yQXJyYXkpICsgJz4nICsgc2VsZWN0b3JBcnJheVsnVmFsdWUnXSArICc8L3c6U2VsZWN0b3I+JzsNCgkJICAgICAgICB9DQoJCSAgICAgICAgcmVzdWx0ICs9ICc8L3c6U2VsZWN0b3JTZXQ+PC9hOlJlZmVyZW5jZVBhcmFtZXRlcnM+PC9hOkVuZHBvaW50UmVmZXJlbmNlPic7DQoJCSAgICB9IGVsc2Ugew0KCQkgICAgICAgIHJlc3VsdCArPSBzZWxlY3RvclNldFtwcm9wTmFtZV07DQoJCSAgICB9DQoJCQlyZXN1bHQgKz0gJzwvdzpTZWxlY3Rvcj4nOw0KCQl9DQoJCXJlc3VsdCArPSAnPC93OlNlbGVjdG9yU2V0Pic7DQoJCXJldHVybiByZXN1bHQ7DQoJfQ0KDQogICAgZnVuY3Rpb24gX3R1cm5Ub1htbCh0ZXh0KSB7DQogICAgICAgIA0KICAgICAgICAvLyBOb2RlSlMgZGV0ZWN0aW9uDQogICAgICAgIHZhciBpc05vZGUgPSBuZXcgRnVuY3Rpb24oInRyeSB7cmV0dXJuIHRoaXM9PT1nbG9iYWw7fWNhdGNoKGUpe3JldHVybiBmYWxzZTt9Iik7DQogICAgICAgIGlmIChpc05vZGUoKSkgew0KICAgICAgICAgICAgdmFyIFhET01QYXJzZXIgPSByZXF1aXJlKCd4bWxkb20nKS5ET01QYXJzZXI7DQogICAgICAgICAgICByZXR1cm4gbmV3IFhET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcodGV4dCwgInRleHQveG1sIik7DQogICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAod2luZG93LkRPTVBhcnNlcikgew0KICAgICAgICAgICAgcmV0dXJuIG5ldyBET01QYXJzZXIoKS5wYXJzZUZyb21TdHJpbmcodGV4dCwgInRleHQveG1sIik7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAvLyBJbnRlcm5ldCBFeHBsb3Jlcg0KICAgICAgICAgICAgdmFyIHhtbERvYyA9IG5ldyBBY3RpdmVYT2JqZWN0KCJNaWNyb3NvZnQuWE1MRE9NIik7DQogICAgICAgICAgICB4bWxEb2MuYXN5bmMgPSBmYWxzZTsNCiAgICAgICAgICAgIHhtbERvYy5sb2FkWE1MKHRleHQpOw0KICAgICAgICAgICAgcmV0dXJuIHhtbERvYzsNCiAgICAgICAgfQ0KICAgIH0NCg0KICAgIC8qDQogICAgLy8gVGhpcyBpcyBhIGRyb3AtaW4gcmVwbGFjZW1lbnQgdG8gX3R1cm5Ub1htbCgpIHRoYXQgd29ya3Mgd2l0aG91dCB4bWwgcGFyc2VyIGRlcGVuZGVuY3kuDQogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFycmF5LnByb3RvdHlwZSwgInBlZWsiLCB7IHZhbHVlOiBmdW5jdGlvbiAoKSB7IHJldHVybiAodGhpcy5sZW5ndGggPiAwID8gdGhpc1t0aGlzLmxlbmd0aCAtIDFdIDogbnVsbCk7IH0gfSk7CiAgICBmdW5jdGlvbiBfdHJlZUJ1aWxkZXIoKSB7DQogICAgICAgIHRoaXMudHJlZSA9IFtdOwogICAgICAgIHRoaXMucHVzaCA9IGZ1bmN0aW9uIChlbGVtZW50KSB7IHRoaXMudHJlZS5wdXNoKGVsZW1lbnQpOyB9OwogICAgICAgIHRoaXMucG9wID0gZnVuY3Rpb24gKCkgeyB2YXIgZWxlbWVudCA9IHRoaXMudHJlZS5wb3AoKTsgaWYgKHRoaXMudHJlZS5sZW5ndGggPiAwKSB7IHZhciB4ID0gdGhpcy50cmVlLnBlZWsoKTsgeC5jaGlsZE5vZGVzLnB1c2goZWxlbWVudCk7IHguY2hpbGRFbGVtZW50Q291bnQgPSB4LmNoaWxkTm9kZXMubGVuZ3RoOyB9IHJldHVybiAoZWxlbWVudCk7IH07CiAgICAgICAgdGhpcy5wZWVrID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gKHRoaXMudHJlZS5wZWVrKCkpOyB9CiAgICAgICAgdGhpcy5hZGROYW1lc3BhY2UgPSBmdW5jdGlvbiAocHJlZml4LCBuYW1lc3BhY2UpIHsgdGhpcy50cmVlLnBlZWsoKS5uc1RhYmxlW3ByZWZpeF0gPSBuYW1lc3BhY2U7IGlmICh0aGlzLnRyZWUucGVlaygpLmF0dHJpYnV0ZXMubGVuZ3RoID4gMCkgeyBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMudHJlZS5wZWVrKCkuYXR0cmlidXRlczsgKytpKSB7IHZhciBhID0gdGhpcy50cmVlLnBlZWsoKS5hdHRyaWJ1dGVzW2ldOyBpZiAocHJlZml4ID09ICcqJyAmJiBhLm5hbWUgPT0gYS5sb2NhbE5hbWUpIHsgYS5uYW1lc3BhY2UgPSBuYW1lc3BhY2U7IH0gZWxzZSBpZiAocHJlZml4ICE9ICcqJyAmJiBhLm5hbWUgIT0gYS5sb2NhbE5hbWUpIHsgdmFyIHBmeCA9IGEubmFtZS5zcGxpdCgnOicpWzBdOyBpZiAocGZ4ID09IHByZWZpeCkgeyBhLm5hbWVzcGFjZSA9IG5hbWVzcGFjZTsgfSB9IH0gfSB9CiAgICAgICAgdGhpcy5nZXROYW1lc3BhY2UgPSBmdW5jdGlvbiAocHJlZml4KSB7IGZvciAodmFyIGkgPSB0aGlzLnRyZWUubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHsgaWYgKHRoaXMudHJlZVtpXS5uc1RhYmxlW3ByZWZpeF0gIT0gbnVsbCkgeyByZXR1cm4gKHRoaXMudHJlZVtpXS5uc1RhYmxlW3ByZWZpeF0pOyB9IH0gcmV0dXJuIG51bGw7IH0NCiAgICB9CiAgICBmdW5jdGlvbiBfdHVyblRvWG1sKHRleHQpIHsgaWYgKHRleHQgPT0gbnVsbCkgcmV0dXJuIG51bGw7IHJldHVybiAoeyBjaGlsZE5vZGVzOiBbX3R1cm5Ub1htbFJlYyh0ZXh0KV0sIGdldEVsZW1lbnRzQnlUYWdOYW1lOiBfZ2V0RWxlbWVudHNCeVRhZ05hbWUsIGdldENoaWxkRWxlbWVudHNCeVRhZ05hbWU6IF9nZXRDaGlsZEVsZW1lbnRzQnlUYWdOYW1lLCBnZXRFbGVtZW50c0J5VGFnTmFtZU5TOiBfZ2V0RWxlbWVudHNCeVRhZ05hbWVOUyB9KTsgfQogICAgZnVuY3Rpb24gX2dldEVsZW1lbnRzQnlUYWdOYW1lTlMobnMsIG5hbWUpIHsgdmFyIHJldCA9IFtdOyBfeG1sVHJhdmVyc2VBbGxSZWModGhpcy5jaGlsZE5vZGVzLCBmdW5jdGlvbiAobm9kZSkgeyBpZiAobm9kZS5sb2NhbE5hbWUgPT0gbmFtZSAmJiAobm9kZS5uYW1lc3BhY2UgPT0gbnMgfHwgbnMgPT0gJyonKSkgeyByZXQucHVzaChub2RlKTsgfSB9KTsgcmV0dXJuIHJldDsgfQogICAgZnVuY3Rpb24gX2dldEVsZW1lbnRzQnlUYWdOYW1lKG5hbWUpIHsgdmFyIHJldCA9IFtdOyBfeG1sVHJhdmVyc2VBbGxSZWModGhpcy5jaGlsZE5vZGVzLCBmdW5jdGlvbiAobm9kZSkgeyBpZiAobm9kZS5sb2NhbE5hbWUgPT0gbmFtZSkgeyByZXQucHVzaChub2RlKTsgfSB9KTsgcmV0dXJuIHJldDsgfQogICAgZnVuY3Rpb24gX2dldENoaWxkRWxlbWVudHNCeVRhZ05hbWUobmFtZSkgeyB2YXIgcmV0ID0gW107IGlmICh0aGlzLmNoaWxkTm9kZXMgIT0gbnVsbCkgeyBmb3IgKHZhciBub2RlIGluIHRoaXMuY2hpbGROb2RlcykgeyBpZiAodGhpcy5jaGlsZE5vZGVzW25vZGVdLmxvY2FsTmFtZSA9PSBuYW1lKSB7IHJldC5wdXNoKHRoaXMuY2hpbGROb2Rlc1tub2RlXSk7IH0gfSB9IHJldHVybiAocmV0KTsgfQogICAgZnVuY3Rpb24gX2dldENoaWxkRWxlbWVudHNCeVRhZ05hbWVOUyhucywgbmFtZSkgeyB2YXIgcmV0ID0gW107IGlmICh0aGlzLmNoaWxkTm9kZXMgIT0gbnVsbCkgeyBmb3IgKHZhciBub2RlIGluIHRoaXMuY2hpbGROb2RlcykgeyBpZiAodGhpcy5jaGlsZE5vZGVzW25vZGVdLmxvY2FsTmFtZSA9PSBuYW1lICYmIChucyA9PSAnKicgfHwgdGhpcy5jaGlsZE5vZGVzW25vZGVdLm5hbWVzcGFjZSA9PSBucykpIHsgcmV0LnB1c2godGhpcy5jaGlsZE5vZGVzW25vZGVdKTsgfSB9IH0gcmV0dXJuIChyZXQpOyB9CiAgICBmdW5jdGlvbiBfeG1sVHJhdmVyc2VBbGxSZWMobm9kZXMsIGZ1bmMpIHsgZm9yICh2YXIgaSBpbiBub2RlcykgeyBmdW5jKG5vZGVzW2ldKTsgaWYgKG5vZGVzW2ldLmNoaWxkTm9kZXMpIHsgX3htbFRyYXZlcnNlQWxsUmVjKG5vZGVzW2ldLmNoaWxkTm9kZXMsIGZ1bmMpOyB9IH0gfQogICAgZnVuY3Rpb24gX3R1cm5Ub1htbFJlYyh0ZXh0KSB7DQogICAgICAgIHZhciBlbGVtZW50U3RhY2sgPSBuZXcgX3RyZWVCdWlsZGVyKCksIGxhc3RFbGVtZW50ID0gbnVsbCwgeDEgPSB0ZXh0LnNwbGl0KCc8JyksIHJldCA9IFtdLCBlbGVtZW50ID0gbnVsbCwgY3VycmVudEVsZW1lbnROYW1lID0gbnVsbDsKICAgICAgICBmb3IgKHZhciBpIGluIHgxKSB7DQogICAgICAgICAgICB2YXIgeDIgPSB4MVtpXS5zcGxpdCgnPicpLCB4MyA9IHgyWzBdLnNwbGl0KCcgJyksIGVsZW1lbnROYW1lID0geDNbMF07CiAgICAgICAgICAgIGlmICgoZWxlbWVudE5hbWUubGVuZ3RoID4gMCkgJiYgKGVsZW1lbnROYW1lWzBdICE9ICc/JykpIHsNCiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudE5hbWVbMF0gIT0gJy8nKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBhdHRyaWJ1dGVzID0gW10sIGxvY2FsTmFtZSwgbG9jYWxuYW1lMiA9IGVsZW1lbnROYW1lLnNwbGl0KCcgJylbMF0uc3BsaXQoJzonKSwgbG9jYWxOYW1lID0gKGxvY2FsbmFtZTIubGVuZ3RoID4gMSkgPyBsb2NhbG5hbWUyWzFdIDogbG9jYWxuYW1lMlswXTsKICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoYXR0cmlidXRlcywgImdldCIsCiAgICAgICAgICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAxKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGEgaW4gdGhpcykgeyBpZiAodGhpc1thXS5uYW1lID09IGFyZ3VtZW50c1swXSkgeyByZXR1cm4gKHRoaXNbYV0pOyB9IH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChhcmd1bWVudHMubGVuZ3RoID09IDIpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgYSBpbiB0aGlzKSB7IGlmICh0aGlzW2FdLm5hbWUgPT0gYXJndW1lbnRzWzFdICYmIChhcmd1bWVudHNbMF0gPT0gJyonIHx8IHRoaXNbYV0ubmFtZXNwYWNlID09IGFyZ3VtZW50c1swXSkpIHsgcmV0dXJuICh0aGlzW2FdKTsgfSB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93ICgnYXR0cmlidXRlcy5nZXQoKTogSW52YWxpZCBudW1iZXIgb2YgcGFyYW1ldGVycycpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgZWxlbWVudFN0YWNrLnB1c2goeyBuYW1lOiBlbGVtZW50TmFtZSwgbG9jYWxOYW1lOiBsb2NhbE5hbWUsIGdldENoaWxkRWxlbWVudHNCeVRhZ05hbWU6IF9nZXRDaGlsZEVsZW1lbnRzQnlUYWdOYW1lLCBnZXRFbGVtZW50c0J5VGFnTmFtZU5TOiBfZ2V0RWxlbWVudHNCeVRhZ05hbWVOUywgZ2V0Q2hpbGRFbGVtZW50c0J5VGFnTmFtZU5TOiBfZ2V0Q2hpbGRFbGVtZW50c0J5VGFnTmFtZU5TLCBhdHRyaWJ1dGVzOiBhdHRyaWJ1dGVzLCBjaGlsZE5vZGVzOiBbXSwgbnNUYWJsZToge30gfSk7CiAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgQXR0cmlidXRlcwogICAgICAgICAgICAgICAgICAgIGlmICh4My5sZW5ndGggPiAwKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgc2tpcCA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqIGluIHgzKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHgzW2pdID09ICcvJykgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgYW4gZW1wdHkgRWxlbWVudAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdGFjay5wZWVrKCkubmFtZXNwYWNlID0gZWxlbWVudFN0YWNrLnBlZWsoKS5uYW1lID09IGVsZW1lbnRTdGFjay5wZWVrKCkubG9jYWxOYW1lID8gZWxlbWVudFN0YWNrLmdldE5hbWVzcGFjZSgnKicpIDogZWxlbWVudFN0YWNrLmdldE5hbWVzcGFjZShlbGVtZW50U3RhY2sucGVlaygpLm5hbWUuc3Vic3RyaW5nKDAsIGVsZW1lbnRTdGFjay5wZWVrKCkubmFtZS5pbmRleE9mKCc6JykpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3RhY2sucGVlaygpLnRleHRDb250ZW50ID0gJyc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFzdEVsZW1lbnQgPSBlbGVtZW50U3RhY2sucG9wKCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2tpcCA9IHRydWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGsgPSB4M1tqXS5pbmRleE9mKCc9Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoayA+IDApIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGF0dHJOYW1lID0geDNbal0uc3Vic3RyaW5nKDAsIGspOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRyVmFsdWUgPSB4M1tqXS5zdWJzdHJpbmcoayArIDIsIHgzW2pdLmxlbmd0aCAtIDEpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBhdHRyTlMgPSBlbGVtZW50U3RhY2suZ2V0TmFtZXNwYWNlKCcqJyk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRyTmFtZSA9PSAneG1sbnMnKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3RhY2suYWRkTmFtZXNwYWNlKCcqJywgYXR0clZhbHVlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0ck5TID0gYXR0clZhbHVlOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGF0dHJOYW1lLnN0YXJ0c1dpdGgoJ3htbG5zOicpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50U3RhY2suYWRkTmFtZXNwYWNlKGF0dHJOYW1lLnN1YnN0cmluZyg2KSwgYXR0clZhbHVlKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBheCA9IGF0dHJOYW1lLnNwbGl0KCc6Jyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChheC5sZW5ndGggPT0gMikgeyBhdHRyTmFtZSA9IGF4WzFdOyBhdHRyTlMgPSBlbGVtZW50U3RhY2suZ2V0TmFtZXNwYWNlKGF4WzBdKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHggPSB7IG5hbWU6IGF0dHJOYW1lLCB2YWx1ZTogYXR0clZhbHVlIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXR0ck5TICE9IG51bGwpIHgubmFtZXNwYWNlID0gYXR0ck5TOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdGFjay5wZWVrKCkuYXR0cmlidXRlcy5wdXNoKHgpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNraXApIHsgY29udGludWU7IH0NCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsZW1lbnRTdGFjay5wZWVrKCkubmFtZXNwYWNlID0gZWxlbWVudFN0YWNrLnBlZWsoKS5uYW1lID09IGVsZW1lbnRTdGFjay5wZWVrKCkubG9jYWxOYW1lID8gZWxlbWVudFN0YWNrLmdldE5hbWVzcGFjZSgnKicpIDogZWxlbWVudFN0YWNrLmdldE5hbWVzcGFjZShlbGVtZW50U3RhY2sucGVlaygpLm5hbWUuc3Vic3RyaW5nKDAsIGVsZW1lbnRTdGFjay5wZWVrKCkubmFtZS5pbmRleE9mKCc6JykpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoeDJbMV0pIHsgZWxlbWVudFN0YWNrLnBlZWsoKS50ZXh0Q29udGVudCA9IHgyWzFdOyB9DQogICAgICAgICAgICAgICAgfSBlbHNlIHsgbGFzdEVsZW1lbnQgPSBlbGVtZW50U3RhY2sucG9wKCk7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQogICAgICAgIHJldHVybiBsYXN0RWxlbWVudDsNCiAgICB9DQogICAgKi8NCg0KICAgIHJldHVybiBvYmo7DQp9DQovKioNCiogQGZpbGVvdmVydmlldyBJbnRlbChyKSBBTVQgQ29tbXVuaWNhdGlvbiBTdGFja1hYDQoqIEBhdXRob3IgWWxpYW4gU2FpbnQtSGlsYWlyZQ0KKiBAdmVyc2lvbiB2MC4yLjBiDQoqLw0KDQovKioNCiAqIENvbnN0cnVjdCBhIEFtdFN0YWNrQ3JlYXRlU2VydmljZSBvYmplY3QsIHRoaXMgaWEgdGhlIG1haW4gSW50ZWwgQU1UIGNvbW11bmljYXRpb24gc3RhY2suDQogKiBAY29uc3RydWN0b3INCiAqLw0KZnVuY3Rpb24gQW10U3RhY2tDcmVhdGVTZXJ2aWNlKHdzbWFuU3RhY2spIHsNCiAgICB2YXIgb2JqID0gbmV3IE9iamVjdCgpOw0KICAgIG9iai53c21hbiA9IHdzbWFuU3RhY2s7DQogICAgb2JqLnBmeCA9IFsiaHR0cDovL2ludGVsLmNvbS93YmVtL3dzY2ltLzEvYW10LXNjaGVtYS8xLyIsICJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yLyIsICJodHRwOi8vaW50ZWwuY29tL3diZW0vd3NjaW0vMS9pcHMtc2NoZW1hLzEvIl07DQogICAgb2JqLlBlbmRpbmdFbnVtcyA9IFtdOw0KICAgIG9iai5QZW5kaW5nQmF0Y2hPcGVyYXRpb25zID0gMDsNCiAgICBvYmouQWN0aXZlRW51bXNDb3VudCA9IDA7DQogICAgb2JqLk1heEFjdGl2ZUVudW1zQ291bnQgPSAxOyAvLyBNYXhpbXVtIG51bWJlciBvZiBlbnVtZXJhdGlvbnMgdGhhdCBjYW4gYmUgZG9uZSBhdCB0aGUgc2FtZSB0aW1lLg0KICAgIG9iai5vblByb2Nlc3NDaGFuZ2VkID0gbnVsbDsNCiAgICB2YXIgX01heFByb2Nlc3MgPSAwOw0KICAgIHZhciBfTGFzdFByb2Nlc3MgPSAwOw0KDQogICAgLy8gUmV0dXJuIHRoZSBudW1iZXIgb2YgcGVuZGluZyBhY3Rpb25zDQogICAgb2JqLkdldFBlbmRpbmdBY3Rpb25zID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gKG9iai5QZW5kaW5nRW51bXMubGVuZ3RoICogMikgKyAob2JqLkFjdGl2ZUVudW1zQ291bnQpICsgb2JqLndzbWFuLmNvbW0uUGVuZGluZ0FqYXgubGVuZ3RoICsgb2JqLndzbWFuLmNvbW0uQWN0aXZlQWpheENvdW50ICsgb2JqLlBlbmRpbmdCYXRjaE9wZXJhdGlvbnM7IH0NCg0KICAgIC8vIFByaXZhdGUgTWV0aG9kLCBVcGRhdGUgdGhlIGN1cnJlbnQgcHJvY2Vzc2luZyBzdGF0dXMsIHRoaXMgZ2l2ZXMgdGhlIGFwcGxpY2F0aW9uIGFuIGlkZWEgb2Ygd2hhdCBwcm9ncmVzcyBpcyBiZWluZyBkb25lIGJ5IHRoZSBXU01BTiBzdGFjaw0KICAgIGZ1bmN0aW9uIF91cCgpIHsNCiAgICAgICAgdmFyIHggPSBvYmouR2V0UGVuZGluZ0FjdGlvbnMoKTsNCiAgICAgICAgaWYgKF9NYXhQcm9jZXNzIDwgeCkgX01heFByb2Nlc3MgPSB4Ow0KICAgICAgICBpZiAob2JqLm9uUHJvY2Vzc0NoYW5nZWQgIT0gbnVsbCAmJiBfTGFzdFByb2Nlc3MgIT0geCkgew0KICAgICAgICAgICAgLy9jb25zb2xlLmxvZygiUHJvY2VzcyBPbGQ9IiArIF9MYXN0UHJvY2VzcyArICIsIE5ldz0iICsgeCArICIsIFBFbnVtcz0iICsgb2JqLlBlbmRpbmdFbnVtcy5sZW5ndGggKyAiLCBBRW51bXM9IiArIG9iai5BY3RpdmVFbnVtc0NvdW50ICsgIiwgUEFqYXg9IiArIG9iai53c21hbi5jb21tLlBlbmRpbmdBamF4Lmxlbmd0aCArICIsIEFBamF4PSIgKyBvYmoud3NtYW4uY29tbS5BY3RpdmVBamF4Q291bnQgKyAiLCBQQmF0Y2g9IiArIG9iai5QZW5kaW5nQmF0Y2hPcGVyYXRpb25zKTsNCiAgICAgICAgICAgIF9MYXN0UHJvY2VzcyA9IHg7DQogICAgICAgICAgICBvYmoub25Qcm9jZXNzQ2hhbmdlZCh4LCBfTWF4UHJvY2Vzcyk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKHggPT0gMCkgX01heFByb2Nlc3MgPSAwOw0KICAgIH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiAiU1VCU0NSSUJFIiBvcGVyYXRpb24uDQogICAgb2JqLlN1YnNjcmliZSA9IGZ1bmN0aW9uIChuYW1lLCBkZWxpdmVyeSwgdXJsLCBjYWxsYmFjaywgdGFnLCBwcmksIHNlbGVjdG9ycywgb3BhcXVlLCB1c2VyLCBwYXNzKSB7IG9iai53c21hbi5FeGVjU3Vic2NyaWJlKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIGRlbGl2ZXJ5LCB1cmwsIGZ1bmN0aW9uICh3cywgcmVzdXJpLCByZXNwb25zZSwgeHN0YXR1cykgeyBfdXAoKTsgY2FsbGJhY2sob2JqLCBuYW1lLCByZXNwb25zZSwgeHN0YXR1cywgdGFnKTsgfSwgMCwgcHJpLCBzZWxlY3RvcnMsIG9wYXF1ZSwgdXNlciwgcGFzcyk7IF91cCgpOyB9DQoNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gIlVOU1VCU0NSSUJFIiBvcGVyYXRpb24uDQogICAgb2JqLlVuU3Vic2NyaWJlID0gZnVuY3Rpb24gKG5hbWUsIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai53c21hbi5FeGVjVW5TdWJzY3JpYmUob2JqLkNvbXBsZXRlTmFtZShuYW1lKSwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcpOyB9LCAwLCBwcmksIHNlbGVjdG9ycyk7IF91cCgpOyB9DQoNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gIkdFVCIgb3BlcmF0aW9uLg0KICAgIG9iai5HZXQgPSBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2ssIHRhZywgcHJpKSB7IG9iai53c21hbi5FeGVjR2V0KG9iai5Db21wbGV0ZU5hbWUobmFtZSksIGZ1bmN0aW9uICh3cywgcmVzdXJpLCByZXNwb25zZSwgeHN0YXR1cykgeyBfdXAoKTsgY2FsbGJhY2sob2JqLCBuYW1lLCByZXNwb25zZSwgeHN0YXR1cywgdGFnKTsgfSwgMCwgcHJpKTsgX3VwKCk7IH0NCg0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiAiUFVUIiBvcGVyYXRpb24uDQogICAgb2JqLlB1dCA9IGZ1bmN0aW9uIChuYW1lLCBwdXRvYmosIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai53c21hbi5FeGVjUHV0KG9iai5Db21wbGV0ZU5hbWUobmFtZSksIHB1dG9iaiwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcpOyB9LCAwLCBwcmksIHNlbGVjdG9ycyk7IF91cCgpOyB9DQoJDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOICJDUkVBVEUiIG9wZXJhdGlvbi4NCiAgICBvYmouQ3JlYXRlID0gZnVuY3Rpb24gKG5hbWUsIHB1dG9iaiwgY2FsbGJhY2ssIHRhZywgcHJpKSB7IG9iai53c21hbi5FeGVjQ3JlYXRlKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIHB1dG9iaiwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcpOyB9LCAwLCBwcmkpOyBfdXAoKTsgfQ0KDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOICJERUxFVEUiIG9wZXJhdGlvbi4NCiAgICBvYmouRGVsZXRlID0gZnVuY3Rpb24gKG5hbWUsIHB1dG9iaiwgY2FsbGJhY2ssIHRhZywgcHJpKSB7IG9iai53c21hbi5FeGVjRGVsZXRlKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIHB1dG9iaiwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcpOyB9LCAwLCBwcmkpOyBfdXAoKTsgfQ0KDQogICAgLy8gUGVyZm9ybSBhIFdTTUFOIG1ldGhvZCBjYWxsIG9wZXJhdGlvbi4NCiAgICBvYmouRXhlYyA9IGZ1bmN0aW9uIChuYW1lLCBtZXRob2QsIGFyZ3MsIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai53c21hbi5FeGVjTWV0aG9kKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIG1ldGhvZCwgYXJncywgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF91cCgpOyBjYWxsYmFjayhvYmosIG5hbWUsIG9iai5Db21wbGV0ZUV4ZWNSZXNwb25zZShyZXNwb25zZSksIHhzdGF0dXMsIHRhZyk7IH0sIDAsIHByaSwgc2VsZWN0b3JzKTsgX3VwKCk7IH0NCgkNCiAgICAvLyBQZXJmb3JtIGEgV1NNQU4gbWV0aG9kIGNhbGwgb3BlcmF0aW9uLg0KICAgIG9iai5FeGVjV2l0aFhtbCA9IGZ1bmN0aW9uIChuYW1lLCBtZXRob2QsIGFyZ3MsIGNhbGxiYWNrLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai53c21hbi5FeGVjTWV0aG9kWG1sKG9iai5Db21wbGV0ZU5hbWUobmFtZSksIG1ldGhvZCwgZXhlY0FyZ3VtZW50c1RvWG1sKGFyZ3MpLCBmdW5jdGlvbiAod3MsIHJlc3VyaSwgcmVzcG9uc2UsIHhzdGF0dXMpIHsgX3VwKCk7IGNhbGxiYWNrKG9iaiwgbmFtZSwgb2JqLkNvbXBsZXRlRXhlY1Jlc3BvbnNlKHJlc3BvbnNlKSwgeHN0YXR1cywgdGFnKTsgfSwgMCwgcHJpLCBzZWxlY3RvcnMpOyBfdXAoKTsgfQ0KCQ0KICAgIC8vIFBlcmZvcm0gYSBXU01BTiAiRU5VTUVSQVRFIiBvcGVyYXRpb24uDQogICAgb2JqLkVudW0gPSBmdW5jdGlvbiAobmFtZSwgY2FsbGJhY2ssIHRhZywgcHJpKSB7DQogICAgICAgIGlmIChvYmouQWN0aXZlRW51bXNDb3VudCA8IG9iai5NYXhBY3RpdmVFbnVtc0NvdW50KSB7DQogICAgICAgICAgICBvYmouQWN0aXZlRW51bXNDb3VudCsrOyBvYmoud3NtYW4uRXhlY0VudW0ob2JqLkNvbXBsZXRlTmFtZShuYW1lKSwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzLCB0YWcwKSB7IF91cCgpOyBfRW51bVN0YXJ0U2luayhuYW1lLCByZXNwb25zZSwgY2FsbGJhY2ssIHJlc3VyaSwgeHN0YXR1cywgdGFnMCk7IH0sIHRhZywgcHJpKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIG9iai5QZW5kaW5nRW51bXMucHVzaChbbmFtZSwgY2FsbGJhY2ssIHRhZywgcHJpXSk7DQogICAgICAgIH0NCiAgICAgICAgX3VwKCk7DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfRW51bVN0YXJ0U2luayhuYW1lLCByZXNwb25zZSwgY2FsbGJhY2ssIHJlc3VyaSwgc3RhdHVzLCB0YWcsIHByaSkgew0KICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBjYWxsYmFjayhvYmosIG5hbWUsIG51bGwsIHN0YXR1cywgdGFnKTsgX0VudW1Eb05leHQoMSk7IHJldHVybjsgfQ0KICAgICAgICBpZiAocmVzcG9uc2UgPT0gbnVsbCB8fCByZXNwb25zZS5IZWFkZXJbIk1ldGhvZCJdICE9ICJFbnVtZXJhdGVSZXNwb25zZSIgfHwgIXJlc3BvbnNlLkJvZHlbIkVudW1lcmF0aW9uQ29udGV4dCJdKSB7IGNhbGxiYWNrKG9iaiwgbmFtZSwgbnVsbCwgNjAzLCB0YWcpOyBfRW51bURvTmV4dCgxKTsgcmV0dXJuOyB9DQogICAgICAgIHZhciBlbnVtY3R4ID0gcmVzcG9uc2UuQm9keVsiRW51bWVyYXRpb25Db250ZXh0Il07DQogICAgICAgIG9iai53c21hbi5FeGVjUHVsbChyZXN1cmksIGVudW1jdHgsIGZ1bmN0aW9uICh3cywgcmVzdXJpLCByZXNwb25zZSwgeHN0YXR1cykgeyBfRW51bUNvbnRpbnVlU2luayhuYW1lLCByZXNwb25zZSwgY2FsbGJhY2ssIHJlc3VyaSwgW10sIHhzdGF0dXMsIHRhZywgcHJpKTsgfSk7DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfRW51bUNvbnRpbnVlU2luayhuYW1lLCByZXNwb25zZSwgY2FsbGJhY2ssIHJlc3VyaSwgaXRlbXMsIHN0YXR1cywgdGFnLCBwcmkpIHsNCiAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsgY2FsbGJhY2sob2JqLCBuYW1lLCBudWxsLCBzdGF0dXMsIHRhZyk7IF9FbnVtRG9OZXh0KDEpOyByZXR1cm47IH0NCiAgICAgICAgaWYgKHJlc3BvbnNlID09IG51bGwgfHwgcmVzcG9uc2UuSGVhZGVyWyJNZXRob2QiXSAhPSAiUHVsbFJlc3BvbnNlIikgeyBjYWxsYmFjayhvYmosIG5hbWUsIG51bGwsIDYwNCwgdGFnKTsgX0VudW1Eb05leHQoMSk7IHJldHVybjsgfQ0KICAgICAgICBmb3IgKHZhciBpIGluIHJlc3BvbnNlLkJvZHlbIkl0ZW1zIl0pIHsNCiAgICAgICAgICAgIGlmIChyZXNwb25zZS5Cb2R5WyJJdGVtcyJdW2ldIGluc3RhbmNlb2YgQXJyYXkpIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBqIGluIHJlc3BvbnNlLkJvZHlbIkl0ZW1zIl1baV0pIHsgaWYgKHR5cGVvZiByZXNwb25zZS5Cb2R5WyJJdGVtcyJdW2ldW2pdICE9ICdmdW5jdGlvbicpIHsgaXRlbXMucHVzaChyZXNwb25zZS5Cb2R5WyJJdGVtcyJdW2ldW2pdKTsgfSB9DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzcG9uc2UuQm9keVsiSXRlbXMiXVtpXSAhPSAnZnVuY3Rpb24nKSB7IGl0ZW1zLnB1c2gocmVzcG9uc2UuQm9keVsiSXRlbXMiXVtpXSk7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBpZiAocmVzcG9uc2UuQm9keVsiRW51bWVyYXRpb25Db250ZXh0Il0pIHsNCiAgICAgICAgICAgIHZhciBlbnVtY3R4ID0gcmVzcG9uc2UuQm9keVsiRW51bWVyYXRpb25Db250ZXh0Il07DQogICAgICAgICAgICBvYmoud3NtYW4uRXhlY1B1bGwocmVzdXJpLCBlbnVtY3R4LCBmdW5jdGlvbiAod3MsIHJlc3VyaSwgcmVzcG9uc2UsIHhzdGF0dXMpIHsgX0VudW1Db250aW51ZVNpbmsobmFtZSwgcmVzcG9uc2UsIGNhbGxiYWNrLCByZXN1cmksIGl0ZW1zLCB4c3RhdHVzLCB0YWcsIDEpOyB9KTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIF9FbnVtRG9OZXh0KDEpOw0KICAgICAgICAgICAgY2FsbGJhY2sob2JqLCBuYW1lLCBpdGVtcywgc3RhdHVzLCB0YWcpOw0KICAgICAgICAgICAgX3VwKCk7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIGZ1bmN0aW9uIF9FbnVtRG9OZXh0KGRlYykgew0KICAgICAgICBvYmouQWN0aXZlRW51bXNDb3VudCAtPSBkZWM7DQogICAgICAgIGlmIChvYmouQWN0aXZlRW51bXNDb3VudCA+PSBvYmouTWF4QWN0aXZlRW51bXNDb3VudCB8fCBvYmouUGVuZGluZ0VudW1zLmxlbmd0aCA9PSAwKSB7IF91cCgpOyByZXR1cm47IH0NCiAgICAgICAgdmFyIHggPSBvYmouUGVuZGluZ0VudW1zLnNoaWZ0KCk7DQogICAgICAgIG9iai5FbnVtKHhbMF0sIHhbMV0sIHhbMl0pOw0KICAgICAgICBfRW51bURvTmV4dCgwKTsNCiAgICB9DQoNCiAgICAvLyBQZXJmb3JtIGEgYmF0Y2ggb2YgV1NNQU4gIkVOVU0iIG9wZXJhdGlvbnMuDQogICAgb2JqLkJhdGNoRW51bSA9IGZ1bmN0aW9uIChiYXRjaG5hbWUsIG5hbWVzLCBjYWxsYmFjaywgdGFnLCBjb250aW51ZU9uRXJyb3IsIHByaSkgew0KICAgICAgICBvYmouUGVuZGluZ0JhdGNoT3BlcmF0aW9ucyArPSAobmFtZXMubGVuZ3RoICogMik7DQogICAgICAgIF9CYXRjaE5leHRFbnVtKGJhdGNobmFtZSwgQ2xvbmUobmFtZXMpLCBjYWxsYmFjaywgdGFnLCB7fSwgY29udGludWVPbkVycm9yLCBwcmkpOyBfdXAoKTsNCiAgICB9DQoNCiAgICAvLyBSZXF1ZXN0IGVhY2ggZW51bSBpbiB0aGUgYmF0Y2gsIHN0b3BwaW5nIGlmIHNvbWV0aGluZyBkb2VzIG5vdCByZXR1cm4gc3RhdHVzIDIwMA0KICAgIGZ1bmN0aW9uIF9CYXRjaE5leHRFbnVtKGJhdGNobmFtZSwgbmFtZXMsIGNhbGxiYWNrLCB0YWcsIHJlc3VsdHMsIGNvbnRpbnVlT25FcnJvciwgcHJpKSB7DQogICAgICAgIG9iai5QZW5kaW5nQmF0Y2hPcGVyYXRpb25zIC09IDI7DQogICAgICAgIHZhciBuID0gbmFtZXMuc2hpZnQoKSwgZiA9IG9iai5FbnVtOw0KICAgICAgICBpZiAoblswXSA9PSAnKicpIHsgZiA9IG9iai5HZXQ7IG4gPSBuLnN1YnN0cmluZygxKTsgfSAvLyBJZiB0aGUgbmFtZSBzdGFydHMgd2l0aCBhIHN0YXIsIGRvIGEgR0VUIGluc3RlYWQgb2YgYW4gRU5VTS4gVGhpcyB3aWxsIHJlZHVjZSByb3VuZCB0cmlwcy4NCiAgICAgICAgLy9jb25zb2xlLmxvZygoZiA9PSBvYmouR2V0PydHZXQgJzonRW51bSAnKSArIG4pOw0KICAgICAgICAvLyBQZXJmb3JtIGEgR0VUL0VOVU0gYWN0aW9uDQogICAgICAgIGYobiwgZnVuY3Rpb24gKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cywgdGFnMCkgew0KICAgICAgICAgICAgdGFnMFsyXVtuYW1lXSA9IHsgcmVzcG9uc2U6IChyZXNwb25zZXM9PW51bGw/bnVsbDpyZXNwb25zZXMuQm9keSksIHJlc3BvbnNlczogcmVzcG9uc2VzLCBzdGF0dXM6IHN0YXR1cyB9Ow0KICAgICAgICAgICAgaWYgKHRhZzBbMV0ubGVuZ3RoID09IDAgfHwgc3RhdHVzID09IDQwMSB8fCAoY29udGludWVPbkVycm9yICE9IHRydWUgJiYgc3RhdHVzICE9IDIwMCAmJiBzdGF0dXMgIT0gNDAwKSkgeyBvYmouUGVuZGluZ0JhdGNoT3BlcmF0aW9ucyAtPSAobmFtZXMubGVuZ3RoICogMik7IF91cCgpOyBjYWxsYmFjayhvYmosIGJhdGNobmFtZSwgdGFnMFsyXSwgc3RhdHVzLCB0YWcpOyB9DQogICAgICAgICAgICBlbHNlIHsgX3VwKCk7IF9CYXRjaE5leHRFbnVtKGJhdGNobmFtZSwgbmFtZXMsIGNhbGxiYWNrLCB0YWcsIHRhZzBbMl0sIHByaSk7IH0NCiAgICAgICAgfSwgW2JhdGNobmFtZSwgbmFtZXMsIHJlc3VsdHNdLCBwcmkpOw0KICAgICAgICBfdXAoKTsNCiAgICB9DQoNCiAgICAvLyBQZXJmb3JtIGEgYmF0Y2ggb2YgV1NNQU4gIkdFVCIgb3BlcmF0aW9ucy4NCiAgICBvYmouQmF0Y2hHZXQgPSBmdW5jdGlvbiAoYmF0Y2huYW1lLCBuYW1lcywgY2FsbGJhY2ssIHRhZywgcHJpKSB7DQogICAgICAgIF9GZXRjaE5leHQoeyBuYW1lOiBiYXRjaG5hbWUsIG5hbWVzOiBuYW1lcywgY2FsbGJhY2s6IGNhbGxiYWNrLCBjdXJyZW50OiAwLCByZXNwb25zZXM6IHt9LCB0YWc6IHRhZywgcHJpOiBwcmkgfSk7IF91cCgpOw0KICAgIH0NCg0KICAgIC8vIFByaXZhdGUgbWV0aG9kDQogICAgZnVuY3Rpb24gX0ZldGNoTmV4dChiYXRjaCkgew0KICAgICAgICBpZiAoYmF0Y2gubmFtZXMubGVuZ3RoIDw9IGJhdGNoLmN1cnJlbnQpIHsNCiAgICAgICAgICAgIGJhdGNoLmNhbGxiYWNrKG9iaiwgYmF0Y2gubmFtZSwgYmF0Y2gucmVzcG9uc2VzLCAyMDAsIGJhdGNoLnRhZyk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBvYmoud3NtYW4uRXhlY0dldChvYmouQ29tcGxldGVOYW1lKGJhdGNoLm5hbWVzW2JhdGNoLmN1cnJlbnRdKSwgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCB4c3RhdHVzKSB7IF9GZXRjaGVkKGJhdGNoLCByZXNwb25zZSwgeHN0YXR1cyk7IH0sIGJhdGNoLnByaSk7DQogICAgICAgICAgICBiYXRjaC5jdXJyZW50Kys7DQogICAgICAgIH0NCiAgICAgICAgX3VwKCk7DQogICAgfQ0KDQogICAgLy8gUHJpdmF0ZSBtZXRob2QNCiAgICBmdW5jdGlvbiBfRmV0Y2hlZChiYXRjaCwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICBpZiAocmVzcG9uc2UgPT0gbnVsbCB8fCBzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICBiYXRjaC5jYWxsYmFjayhvYmosIGJhdGNoLm5hbWUsIG51bGwsIHN0YXR1cywgYmF0Y2gudGFnKTsNCiAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgIGJhdGNoLnJlc3BvbnNlc1tyZXNwb25zZS5IZWFkZXJbIk1ldGhvZCJdXSA9IHJlc3BvbnNlOw0KICAgICAgICAgICAgX0ZldGNoTmV4dChiYXRjaCk7DQogICAgICAgIH0NCiAgICB9DQoNCiAgICAvLyBQcml2YXRlIG1ldGhvZA0KICAgIG9iai5Db21wbGV0ZU5hbWUgPSBmdW5jdGlvbihuYW1lKSB7DQogICAgICAgIGlmIChuYW1lLmluZGV4T2YoIkFNVF8iKSA9PSAwKSByZXR1cm4gb2JqLnBmeFswXSArIG5hbWU7DQogICAgICAgIGlmIChuYW1lLmluZGV4T2YoIkNJTV8iKSA9PSAwKSByZXR1cm4gb2JqLnBmeFsxXSArIG5hbWU7DQogICAgICAgIGlmIChuYW1lLmluZGV4T2YoIklQU18iKSA9PSAwKSByZXR1cm4gb2JqLnBmeFsyXSArIG5hbWU7DQogICAgfQ0KDQogICAgb2JqLkNvbXBsZXRlRXhlY1Jlc3BvbnNlID0gZnVuY3Rpb24gKHJlc3ApIHsNCiAgICAgICAgaWYgKHJlc3AgJiYgcmVzcCAhPSBudWxsICYmIHJlc3AuQm9keSAmJiAocmVzcC5Cb2R5WyJSZXR1cm5WYWx1ZSJdICE9IHVuZGVmaW5lZCkpIHsgcmVzcC5Cb2R5LlJldHVyblZhbHVlU3RyID0gb2JqLkFtdFN0YXR1c1RvU3RyKHJlc3AuQm9keVsiUmV0dXJuVmFsdWUiXSk7IH0NCiAgICAgICAgcmV0dXJuIHJlc3A7DQogICAgfQ0KDQogICAgb2JqLlJlcXVlc3RQb3dlclN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFBvd2VyU3RhdGUsIGNhbGxiYWNrX2Z1bmMpIHsNCiAgICAgICAgb2JqLkNJTV9Qb3dlck1hbmFnZW1lbnRTZXJ2aWNlX1JlcXVlc3RQb3dlclN0YXRlQ2hhbmdlKFBvd2VyU3RhdGUsICI8QWRkcmVzcyB4bWxucz1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZ1wiPmh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZzwvQWRkcmVzcz48UmVmZXJlbmNlUGFyYW1ldGVycyB4bWxucz1cImh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZ1wiPjxSZXNvdXJjZVVSSSB4bWxucz1cImh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2RcIj5odHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9Db21wdXRlclN5c3RlbTwvUmVzb3VyY2VVUkk+PFNlbGVjdG9yU2V0IHhtbG5zPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZFwiPjxTZWxlY3RvciBOYW1lPVwiQ3JlYXRpb25DbGFzc05hbWVcIj5DSU1fQ29tcHV0ZXJTeXN0ZW08L1NlbGVjdG9yPjxTZWxlY3RvciBOYW1lPVwiTmFtZVwiPk1hbmFnZWRTeXN0ZW08L1NlbGVjdG9yPjwvU2VsZWN0b3JTZXQ+PC9SZWZlcmVuY2VQYXJhbWV0ZXJzPiIsIG51bGwsIG51bGwsIGNhbGxiYWNrX2Z1bmMpOw0KICAgIH0NCg0KICAgIG9iai5TZXRCb290Q29uZmlnUm9sZSA9IGZ1bmN0aW9uIChSb2xlLCBjYWxsYmFja19mdW5jKSB7DQogICAgICAgIG9iai5DSU1fQm9vdFNlcnZpY2VfU2V0Qm9vdENvbmZpZ1JvbGUoIjxBZGRyZXNzIHhtbG5zPVwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nXCI+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nPC9BZGRyZXNzPjxSZWZlcmVuY2VQYXJhbWV0ZXJzIHhtbG5zPVwiaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nXCI+PFJlc291cmNlVVJJIHhtbG5zPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZFwiPmh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NjaW0vMS9jaW0tc2NoZW1hLzIvQ0lNX0Jvb3RDb25maWdTZXR0aW5nPC9SZXNvdXJjZVVSST48U2VsZWN0b3JTZXQgeG1sbnM9XCJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkXCI+PFNlbGVjdG9yIE5hbWU9XCJJbnN0YW5jZUlEXCI+SW50ZWwocikgQU1UOiBCb290IENvbmZpZ3VyYXRpb24gMDwvU2VsZWN0b3I+PC9TZWxlY3RvclNldD48L1JlZmVyZW5jZVBhcmFtZXRlcnM+IiwgUm9sZSwgY2FsbGJhY2tfZnVuYyk7DQogICAgfQ0KDQogICAgLy8gQ2FuY2VsIGFsbCBwZW5kaW5nIHF1ZXJpZXMgd2l0aCBnaXZlbiBzdGF0dXMNCiAgICBvYmouQ2FuY2VsQWxsUXVlcmllcyA9IGZ1bmN0aW9uIChzKSB7DQogICAgICAgIG9iai53c21hbi5DYW5jZWxBbGxRdWVyaWVzKHMpOw0KICAgIH0NCg0KICAgIC8vIEF1dG8gZ2VuZXJhdGVkIG1ldGhvZHMNCiAgICBvYmouQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ19SZWdpc3RlckFnZW50ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2ciLCAiUmVnaXN0ZXJBZ2VudCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nX0Fzc2VydFByZXNlbmNlID0gZnVuY3Rpb24gKFNlcXVlbmNlTnVtYmVyLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nIiwgIkFzc2VydFByZXNlbmNlIiwgeyAiU2VxdWVuY2VOdW1iZXIiOiBTZXF1ZW5jZU51bWJlciB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nX0Fzc2VydFNodXRkb3duID0gZnVuY3Rpb24gKFNlcXVlbmNlTnVtYmVyLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nIiwgIkFzc2VydFNodXRkb3duIiwgeyAiU2VxdWVuY2VOdW1iZXIiOiBTZXF1ZW5jZU51bWJlciB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nX0FkZEFjdGlvbiA9IGZ1bmN0aW9uIChPbGRTdGF0ZSwgTmV3U3RhdGUsIEV2ZW50T25UcmFuc2l0aW9uLCBBY3Rpb25TZCwgQWN0aW9uRWFjLCBjYWxsYmFja19mdW5jLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nIiwgIkFkZEFjdGlvbiIsIHsgIk9sZFN0YXRlIjogT2xkU3RhdGUsICJOZXdTdGF0ZSI6IE5ld1N0YXRlLCAiRXZlbnRPblRyYW5zaXRpb24iOiBFdmVudE9uVHJhbnNpdGlvbiwgIkFjdGlvblNkIjogQWN0aW9uU2QsICJBY3Rpb25FYWMiOiBBY3Rpb25FYWMgfSwgY2FsbGJhY2tfZnVuYywgdGFnLCBwcmksIHNlbGVjdG9ycyk7IH0NCiAgICBvYmouQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ19EZWxldGVBbGxBY3Rpb25zID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMsIHRhZywgcHJpLCBzZWxlY3RvcnMpIHsgb2JqLkV4ZWMoIkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2ciLCAiRGVsZXRlQWxsQWN0aW9ucyIsIHt9LCBjYWxsYmFja19mdW5jLCB0YWcsIHByaSwgc2VsZWN0b3JzKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nQWN0aW9uX0dldEFjdGlvbkVhYyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nQWN0aW9uIiwgIkdldEFjdGlvbkVhYyIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nVkFfUmVnaXN0ZXJBZ2VudCA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nVkEiLCAiUmVnaXN0ZXJBZ2VudCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nVkFfQXNzZXJ0UHJlc2VuY2UgPSBmdW5jdGlvbiAoU2VxdWVuY2VOdW1iZXIsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2dWQSIsICJBc3NlcnRQcmVzZW5jZSIsIHsgIlNlcXVlbmNlTnVtYmVyIjogU2VxdWVuY2VOdW1iZXIgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ1ZBX0Fzc2VydFNodXRkb3duID0gZnVuY3Rpb24gKFNlcXVlbmNlTnVtYmVyLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nVkEiLCAiQXNzZXJ0U2h1dGRvd24iLCB7ICJTZXF1ZW5jZU51bWJlciI6IFNlcXVlbmNlTnVtYmVyIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2dWQV9BZGRBY3Rpb24gPSBmdW5jdGlvbiAoT2xkU3RhdGUsIE5ld1N0YXRlLCBFdmVudE9uVHJhbnNpdGlvbiwgQWN0aW9uU2QsIEFjdGlvbkVhYywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ1ZBIiwgIkFkZEFjdGlvbiIsIHsgIk9sZFN0YXRlIjogT2xkU3RhdGUsICJOZXdTdGF0ZSI6IE5ld1N0YXRlLCAiRXZlbnRPblRyYW5zaXRpb24iOiBFdmVudE9uVHJhbnNpdGlvbiwgIkFjdGlvblNkIjogQWN0aW9uU2QsICJBY3Rpb25FYWMiOiBBY3Rpb25FYWMgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ1ZBX0RlbGV0ZUFsbEFjdGlvbnMgPSBmdW5jdGlvbiAoX21ldGhvZF9kdW1teSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ1ZBIiwgIkRlbGV0ZUFsbEFjdGlvbnMiLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQXVkaXRMb2dfQ2xlYXJMb2cgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0F1ZGl0TG9nIiwgIkNsZWFyTG9nIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdWRpdExvZ19SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdExvZyIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0F1ZGl0TG9nX1JlYWRSZWNvcmRzID0gZnVuY3Rpb24gKFN0YXJ0SW5kZXgsIGNhbGxiYWNrX2Z1bmMsIHRhZykgeyBvYmouRXhlYygiQU1UX0F1ZGl0TG9nIiwgIlJlYWRSZWNvcmRzIiwgeyAiU3RhcnRJbmRleCI6IFN0YXJ0SW5kZXggfSwgY2FsbGJhY2tfZnVuYywgdGFnKTsgfQ0KICAgIG9iai5BTVRfQXVkaXRMb2dfU2V0QXVkaXRMb2NrID0gZnVuY3Rpb24gKExvY2tUaW1lb3V0SW5TZWNvbmRzLCBGbGFnLCBIYW5kbGUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdExvZyIsICJTZXRBdWRpdExvY2siLCB7ICJMb2NrVGltZW91dEluU2Vjb25kcyI6IExvY2tUaW1lb3V0SW5TZWNvbmRzLCAiRmxhZyI6IEZsYWcsICJIYW5kbGUiOiBIYW5kbGUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0F1ZGl0TG9nX0V4cG9ydEF1ZGl0TG9nU2lnbmF0dXJlID0gZnVuY3Rpb24gKFNpZ25pbmdNZWNoYW5pc20sIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdExvZyIsICJFeHBvcnRBdWRpdExvZ1NpZ25hdHVyZSIsIHsgIlNpZ25pbmdNZWNoYW5pc20iOiBTaWduaW5nTWVjaGFuaXNtIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdWRpdExvZ19TZXRTaWduaW5nS2V5TWF0ZXJpYWwgPSBmdW5jdGlvbiAoU2lnbmluZ01lY2hhbmlzbVR5cGUsIFNpZ25pbmdLZXksIExlbmd0aE9mQ2VydGlmaWNhdGVzLCBDZXJ0aWZpY2F0ZXMsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdExvZyIsICJTZXRTaWduaW5nS2V5TWF0ZXJpYWwiLCB7ICJTaWduaW5nTWVjaGFuaXNtVHlwZSI6IFNpZ25pbmdNZWNoYW5pc21UeXBlLCAiU2lnbmluZ0tleSI6IFNpZ25pbmdLZXksICJMZW5ndGhPZkNlcnRpZmljYXRlcyI6IExlbmd0aE9mQ2VydGlmaWNhdGVzLCAiQ2VydGlmaWNhdGVzIjogQ2VydGlmaWNhdGVzIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdWRpdFBvbGljeVJ1bGVfU2V0QXVkaXRQb2xpY3kgPSBmdW5jdGlvbiAoRW5hYmxlLCBBdWRpdGVkQXBwSUQsIEV2ZW50SUQsIFBvbGljeVR5cGUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdWRpdFBvbGljeVJ1bGUiLCAiU2V0QXVkaXRQb2xpY3kiLCB7ICJFbmFibGUiOiBFbmFibGUsICJBdWRpdGVkQXBwSUQiOiBBdWRpdGVkQXBwSUQsICJFdmVudElEIjogRXZlbnRJRCwgIlBvbGljeVR5cGUiOiBQb2xpY3lUeXBlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdWRpdFBvbGljeVJ1bGVfU2V0QXVkaXRQb2xpY3lCdWxrID0gZnVuY3Rpb24gKEVuYWJsZSwgQXVkaXRlZEFwcElELCBFdmVudElELCBQb2xpY3lUeXBlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfQXVkaXRQb2xpY3lSdWxlIiwgIlNldEF1ZGl0UG9saWN5QnVsayIsIHsgIkVuYWJsZSI6IEVuYWJsZSwgIkF1ZGl0ZWRBcHBJRCI6IEF1ZGl0ZWRBcHBJRCwgIkV2ZW50SUQiOiBFdmVudElELCAiUG9saWN5VHlwZSI6IFBvbGljeVR5cGUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX0FkZFVzZXJBY2xFbnRyeUV4ID0gZnVuY3Rpb24gKERpZ2VzdFVzZXJuYW1lLCBEaWdlc3RQYXNzd29yZCwgS2VyYmVyb3NVc2VyU2lkLCBBY2Nlc3NQZXJtaXNzaW9uLCBSZWFsbXMsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJBZGRVc2VyQWNsRW50cnlFeCIsIHsgIkRpZ2VzdFVzZXJuYW1lIjogRGlnZXN0VXNlcm5hbWUsICJEaWdlc3RQYXNzd29yZCI6IERpZ2VzdFBhc3N3b3JkLCAiS2VyYmVyb3NVc2VyU2lkIjogS2VyYmVyb3NVc2VyU2lkLCAiQWNjZXNzUGVybWlzc2lvbiI6IEFjY2Vzc1Blcm1pc3Npb24sICJSZWFsbXMiOiBSZWFsbXMgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX0VudW1lcmF0ZVVzZXJBY2xFbnRyaWVzID0gZnVuY3Rpb24gKFN0YXJ0SW5kZXgsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJFbnVtZXJhdGVVc2VyQWNsRW50cmllcyIsIHsgIlN0YXJ0SW5kZXgiOiBTdGFydEluZGV4IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRVc2VyQWNsRW50cnlFeCA9IGZ1bmN0aW9uIChIYW5kbGUsIGNhbGxiYWNrX2Z1bmMsIHRhZykgeyBvYmouRXhlYygiQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlIiwgIkdldFVzZXJBY2xFbnRyeUV4IiwgeyAiSGFuZGxlIjogSGFuZGxlIH0sIGNhbGxiYWNrX2Z1bmMsIHRhZyk7IH0NCiAgICBvYmouQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX1VwZGF0ZVVzZXJBY2xFbnRyeUV4ID0gZnVuY3Rpb24gKEhhbmRsZSwgRGlnZXN0VXNlcm5hbWUsIERpZ2VzdFBhc3N3b3JkLCBLZXJiZXJvc1VzZXJTaWQsIEFjY2Vzc1Blcm1pc3Npb24sIFJlYWxtcywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlIiwgIlVwZGF0ZVVzZXJBY2xFbnRyeUV4IiwgeyAiSGFuZGxlIjogSGFuZGxlLCAiRGlnZXN0VXNlcm5hbWUiOiBEaWdlc3RVc2VybmFtZSwgIkRpZ2VzdFBhc3N3b3JkIjogRGlnZXN0UGFzc3dvcmQsICJLZXJiZXJvc1VzZXJTaWQiOiBLZXJiZXJvc1VzZXJTaWQsICJBY2Nlc3NQZXJtaXNzaW9uIjogQWNjZXNzUGVybWlzc2lvbiwgIlJlYWxtcyI6IFJlYWxtcyB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfUmVtb3ZlVXNlckFjbEVudHJ5ID0gZnVuY3Rpb24gKEhhbmRsZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlIiwgIlJlbW92ZVVzZXJBY2xFbnRyeSIsIHsgIkhhbmRsZSI6IEhhbmRsZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfU2V0QWRtaW5BY2xFbnRyeUV4ID0gZnVuY3Rpb24gKFVzZXJuYW1lLCBEaWdlc3RQYXNzd29yZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlIiwgIlNldEFkbWluQWNsRW50cnlFeCIsIHsgIlVzZXJuYW1lIjogVXNlcm5hbWUsICJEaWdlc3RQYXNzd29yZCI6IERpZ2VzdFBhc3N3b3JkIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRBZG1pbkFjbEVudHJ5ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJHZXRBZG1pbkFjbEVudHJ5Iiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRBZG1pbkFjbEVudHJ5U3RhdHVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJHZXRBZG1pbkFjbEVudHJ5U3RhdHVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRBZG1pbk5ldEFjbEVudHJ5U3RhdHVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJHZXRBZG1pbk5ldEFjbEVudHJ5U3RhdHVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9TZXRBY2xFbmFibGVkU3RhdGUgPSBmdW5jdGlvbiAoSGFuZGxlLCBFbmFibGVkLCBjYWxsYmFja19mdW5jLCB0YWcpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJTZXRBY2xFbmFibGVkU3RhdGUiLCB7ICJIYW5kbGUiOiBIYW5kbGUsICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jLCB0YWcpOyB9DQogICAgb2JqLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9HZXRBY2xFbmFibGVkU3RhdGUgPSBmdW5jdGlvbiAoSGFuZGxlLCBjYWxsYmFja19mdW5jLCB0YWcpIHsgb2JqLkV4ZWMoIkFNVF9BdXRob3JpemF0aW9uU2VydmljZSIsICJHZXRBY2xFbmFibGVkU3RhdGUiLCB7ICJIYW5kbGUiOiBIYW5kbGUgfSwgY2FsbGJhY2tfZnVuYywgdGFnKTsgfQ0KICAgIG9iai5BTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZV9SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9FbmRwb2ludEFjY2Vzc0NvbnRyb2xTZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZV9HZXRQb3N0dXJlID0gZnVuY3Rpb24gKFBvc3R1cmVUeXBlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZSIsICJHZXRQb3N0dXJlIiwgeyAiUG9zdHVyZVR5cGUiOiBQb3N0dXJlVHlwZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZV9HZXRQb3N0dXJlSGFzaCA9IGZ1bmN0aW9uIChQb3N0dXJlVHlwZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0VuZHBvaW50QWNjZXNzQ29udHJvbFNlcnZpY2UiLCAiR2V0UG9zdHVyZUhhc2giLCB7ICJQb3N0dXJlVHlwZSI6IFBvc3R1cmVUeXBlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9FbmRwb2ludEFjY2Vzc0NvbnRyb2xTZXJ2aWNlX1VwZGF0ZVBvc3R1cmVTdGF0ZSA9IGZ1bmN0aW9uIChVcGRhdGVUeXBlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZSIsICJVcGRhdGVQb3N0dXJlU3RhdGUiLCB7ICJVcGRhdGVUeXBlIjogVXBkYXRlVHlwZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZV9HZXRFYWNPcHRpb25zID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9FbmRwb2ludEFjY2Vzc0NvbnRyb2xTZXJ2aWNlIiwgIkdldEVhY09wdGlvbnMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0VuZHBvaW50QWNjZXNzQ29udHJvbFNlcnZpY2VfU2V0RWFjT3B0aW9ucyA9IGZ1bmN0aW9uIChFYWNWZW5kb3JzLCBQb3N0dXJlSGFzaEFsZ29yaXRobSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0VuZHBvaW50QWNjZXNzQ29udHJvbFNlcnZpY2UiLCAiU2V0RWFjT3B0aW9ucyIsIHsgIkVhY1ZlbmRvcnMiOiBFYWNWZW5kb3JzLCAiUG9zdHVyZUhhc2hBbGdvcml0aG0iOiBQb3N0dXJlSGFzaEFsZ29yaXRobSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW52aXJvbm1lbnREZXRlY3Rpb25TZXR0aW5nRGF0YV9TZXRTeXN0ZW1EZWZlbnNlUG9saWN5ID0gZnVuY3Rpb24gKFBvbGljeSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0Vudmlyb25tZW50RGV0ZWN0aW9uU2V0dGluZ0RhdGEiLCAiU2V0U3lzdGVtRGVmZW5zZVBvbGljeSIsIHsgIlBvbGljeSI6IFBvbGljeSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRW52aXJvbm1lbnREZXRlY3Rpb25TZXR0aW5nRGF0YV9FbmFibGVWcG5Sb3V0aW5nID0gZnVuY3Rpb24gKEVuYWJsZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0Vudmlyb25tZW50RGV0ZWN0aW9uU2V0dGluZ0RhdGEiLCAiRW5hYmxlVnBuUm91dGluZyIsIHsgIkVuYWJsZSI6IEVuYWJsZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfRXRoZXJuZXRQb3J0U2V0dGluZ3NfU2V0TGlua1ByZWZlcmVuY2UgPSBmdW5jdGlvbiAoTGlua1ByZWZlcmVuY2UsIFRpbWVvdXQsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyIsICJTZXRMaW5rUHJlZmVyZW5jZSIsIHsgIkxpbmtQcmVmZXJlbmNlIjogTGlua1ByZWZlcmVuY2UsICJUaW1lb3V0IjogVGltZW91dCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfSGV1cmlzdGljUGFja2V0RmlsdGVyU3RhdGlzdGljc19SZXNldFNlbGVjdGVkU3RhdHMgPSBmdW5jdGlvbiAoU2VsZWN0ZWRTdGF0aXN0aWNzLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfSGV1cmlzdGljUGFja2V0RmlsdGVyU3RhdGlzdGljcyIsICJSZXNldFNlbGVjdGVkU3RhdHMiLCB7ICJTZWxlY3RlZFN0YXRpc3RpY3MiOiBTZWxlY3RlZFN0YXRpc3RpY3MgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0tlcmJlcm9zU2V0dGluZ0RhdGFfR2V0Q3JlZGVudGlhbENhY2hlU3RhdGUgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX0tlcmJlcm9zU2V0dGluZ0RhdGEiLCAiR2V0Q3JlZGVudGlhbENhY2hlU3RhdGUiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX0tlcmJlcm9zU2V0dGluZ0RhdGFfU2V0Q3JlZGVudGlhbENhY2hlU3RhdGUgPSBmdW5jdGlvbiAoRW5hYmxlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfS2VyYmVyb3NTZXR0aW5nRGF0YSIsICJTZXRDcmVkZW50aWFsQ2FjaGVTdGF0ZSIsIHsgIkVuYWJsZSI6IEVuYWJsZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfTWVzc2FnZUxvZ19DYW5jZWxJdGVyYXRpb24gPSBmdW5jdGlvbiAoSXRlcmF0aW9uSWRlbnRpZmllciwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX01lc3NhZ2VMb2ciLCAiQ2FuY2VsSXRlcmF0aW9uIiwgeyAiSXRlcmF0aW9uSWRlbnRpZmllciI6IEl0ZXJhdGlvbklkZW50aWZpZXIgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX01lc3NhZ2VMb2dfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfTWVzc2FnZUxvZyIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX01lc3NhZ2VMb2dfQ2xlYXJMb2cgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX01lc3NhZ2VMb2ciLCAiQ2xlYXJMb2ciLCB7IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9NZXNzYWdlTG9nX0dldFJlY29yZHMgPSBmdW5jdGlvbiAoSXRlcmF0aW9uSWRlbnRpZmllciwgTWF4UmVhZFJlY29yZHMsIGNhbGxiYWNrX2Z1bmMsIHRhZykgeyBvYmouRXhlYygiQU1UX01lc3NhZ2VMb2ciLCAiR2V0UmVjb3JkcyIsIHsgIkl0ZXJhdGlvbklkZW50aWZpZXIiOiBJdGVyYXRpb25JZGVudGlmaWVyLCAiTWF4UmVhZFJlY29yZHMiOiBNYXhSZWFkUmVjb3JkcyB9LCBjYWxsYmFja19mdW5jLCB0YWcpOyB9DQogICAgb2JqLkFNVF9NZXNzYWdlTG9nX0dldFJlY29yZCA9IGZ1bmN0aW9uIChJdGVyYXRpb25JZGVudGlmaWVyLCBQb3NpdGlvblRvTmV4dCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX01lc3NhZ2VMb2ciLCAiR2V0UmVjb3JkIiwgeyAiSXRlcmF0aW9uSWRlbnRpZmllciI6IEl0ZXJhdGlvbklkZW50aWZpZXIsICJQb3NpdGlvblRvTmV4dCI6IFBvc2l0aW9uVG9OZXh0IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9NZXNzYWdlTG9nX1Bvc2l0aW9uQXRSZWNvcmQgPSBmdW5jdGlvbiAoSXRlcmF0aW9uSWRlbnRpZmllciwgTW92ZUFic29sdXRlLCBSZWNvcmROdW1iZXIsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9NZXNzYWdlTG9nIiwgIlBvc2l0aW9uQXRSZWNvcmQiLCB7ICJJdGVyYXRpb25JZGVudGlmaWVyIjogSXRlcmF0aW9uSWRlbnRpZmllciwgIk1vdmVBYnNvbHV0ZSI6IE1vdmVBYnNvbHV0ZSwgIlJlY29yZE51bWJlciI6IFJlY29yZE51bWJlciB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfTWVzc2FnZUxvZ19Qb3NpdGlvblRvRmlyc3RSZWNvcmQgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYywgdGFnKSB7IG9iai5FeGVjKCJBTVRfTWVzc2FnZUxvZyIsICJQb3NpdGlvblRvRmlyc3RSZWNvcmQiLCB7fSwgY2FsbGJhY2tfZnVuYywgdGFnKTsgfQ0KICAgIG9iai5BTVRfTWVzc2FnZUxvZ19GcmVlemVMb2cgPSBmdW5jdGlvbiAoRnJlZXplLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfTWVzc2FnZUxvZyIsICJGcmVlemVMb2ciLCB7ICJGcmVlemUiOiBGcmVlemUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1B1YmxpY0tleU1hbmFnZW1lbnRTZXJ2aWNlX0FkZENSTCA9IGZ1bmN0aW9uIChVcmwsIFNlcmlhbE51bWJlcnMsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJBZGRDUkwiLCB7ICJVcmwiOiBVcmwsICJTZXJpYWxOdW1iZXJzIjogU2VyaWFsTnVtYmVycyB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfUmVzZXRDUkxMaXN0ID0gZnVuY3Rpb24gKF9tZXRob2RfZHVtbXksIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJSZXNldENSTExpc3QiLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfQWRkQ2VydGlmaWNhdGUgPSBmdW5jdGlvbiAoQ2VydGlmaWNhdGVCbG9iLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2UiLCAiQWRkQ2VydGlmaWNhdGUiLCB7ICJDZXJ0aWZpY2F0ZUJsb2IiOiBDZXJ0aWZpY2F0ZUJsb2IgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1B1YmxpY0tleU1hbmFnZW1lbnRTZXJ2aWNlX0FkZFRydXN0ZWRSb290Q2VydGlmaWNhdGUgPSBmdW5jdGlvbiAoQ2VydGlmaWNhdGVCbG9iLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2UiLCAiQWRkVHJ1c3RlZFJvb3RDZXJ0aWZpY2F0ZSIsIHsgIkNlcnRpZmljYXRlQmxvYiI6IENlcnRpZmljYXRlQmxvYiB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfQWRkS2V5ID0gZnVuY3Rpb24gKEtleUJsb2IsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJBZGRLZXkiLCB7ICJLZXlCbG9iIjogS2V5QmxvYiB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfR2VuZXJhdGVQS0NTMTBSZXF1ZXN0ID0gZnVuY3Rpb24gKEtleVBhaXIsIEROTmFtZSwgVXNhZ2UsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJHZW5lcmF0ZVBLQ1MxMFJlcXVlc3QiLCB7ICJLZXlQYWlyIjogS2V5UGFpciwgIkROTmFtZSI6IEROTmFtZSwgIlVzYWdlIjogVXNhZ2UgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1B1YmxpY0tleU1hbmFnZW1lbnRTZXJ2aWNlX0dlbmVyYXRlUEtDUzEwUmVxdWVzdEV4ID0gZnVuY3Rpb24gKEtleVBhaXIsIFNpZ25pbmdBbGdvcml0aG0sIE51bGxTaWduZWRDZXJ0aWZpY2F0ZVJlcXVlc3QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZSIsICJHZW5lcmF0ZVBLQ1MxMFJlcXVlc3RFeCIsIHsgIktleVBhaXIiOiBLZXlQYWlyLCAiU2lnbmluZ0FsZ29yaXRobSI6IFNpZ25pbmdBbGdvcml0aG0sICJOdWxsU2lnbmVkQ2VydGlmaWNhdGVSZXF1ZXN0IjogTnVsbFNpZ25lZENlcnRpZmljYXRlUmVxdWVzdCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfR2VuZXJhdGVLZXlQYWlyID0gZnVuY3Rpb24gKEtleUFsZ29yaXRobSwgS2V5TGVuZ3RoLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2UiLCAiR2VuZXJhdGVLZXlQYWlyIiwgeyAiS2V5QWxnb3JpdGhtIjogS2V5QWxnb3JpdGhtLCAiS2V5TGVuZ3RoIjogS2V5TGVuZ3RoIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9SZWRpcmVjdGlvblNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1JlZGlyZWN0aW9uU2VydmljZV9UZXJtaW5hdGVTZXNzaW9uID0gZnVuY3Rpb24gKFNlc3Npb25UeXBlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlIiwgIlRlcm1pbmF0ZVNlc3Npb24iLCB7ICJTZXNzaW9uVHlwZSI6IFNlc3Npb25UeXBlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9SZW1vdGVBY2Nlc3NTZXJ2aWNlX0FkZE1wU2VydmVyID0gZnVuY3Rpb24gKEFjY2Vzc0luZm8sIEluZm9Gb3JtYXQsIFBvcnQsIEF1dGhNZXRob2QsIENlcnRpZmljYXRlLCBVc2VybmFtZSwgUGFzc3dvcmQsIENOLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVtb3RlQWNjZXNzU2VydmljZSIsICJBZGRNcFNlcnZlciIsIHsgIkFjY2Vzc0luZm8iOiBBY2Nlc3NJbmZvLCAiSW5mb0Zvcm1hdCI6IEluZm9Gb3JtYXQsICJQb3J0IjogUG9ydCwgIkF1dGhNZXRob2QiOiBBdXRoTWV0aG9kLCAiQ2VydGlmaWNhdGUiOiBDZXJ0aWZpY2F0ZSwgIlVzZXJuYW1lIjogVXNlcm5hbWUsICJQYXNzd29yZCI6IFBhc3N3b3JkLCAiQ04iOiBDTiB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfUmVtb3RlQWNjZXNzU2VydmljZV9BZGRSZW1vdGVBY2Nlc3NQb2xpY3lSdWxlID0gZnVuY3Rpb24gKFRyaWdnZXIsIFR1bm5lbExpZmVUaW1lLCBFeHRlbmRlZERhdGEsIE1wU2VydmVyLCBJbnRlcm5hbE1wU2VydmVyLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVtb3RlQWNjZXNzU2VydmljZSIsICJBZGRSZW1vdGVBY2Nlc3NQb2xpY3lSdWxlIiwgeyAiVHJpZ2dlciI6IFRyaWdnZXIsICJUdW5uZWxMaWZlVGltZSI6IFR1bm5lbExpZmVUaW1lLCAiRXh0ZW5kZWREYXRhIjogRXh0ZW5kZWREYXRhLCAiTXBTZXJ2ZXIiOiBNcFNlcnZlciwgIkludGVybmFsTXBTZXJ2ZXIiOiBJbnRlcm5hbE1wU2VydmVyIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9SZW1vdGVBY2Nlc3NTZXJ2aWNlX0Nsb3NlUmVtb3RlQWNjZXNzQ29ubmVjdGlvbiA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfUmVtb3RlQWNjZXNzU2VydmljZSIsICJDbG9zZVJlbW90ZUFjY2Vzc0Nvbm5lY3Rpb24iLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9Db21taXRDaGFuZ2VzID0gZnVuY3Rpb24gKF9tZXRob2RfZHVtbXksIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgIkNvbW1pdENoYW5nZXMiLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9VbnByb3Zpc2lvbiA9IGZ1bmN0aW9uIChQcm92aXNpb25pbmdNb2RlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJVbnByb3Zpc2lvbiIsIHsgIlByb3Zpc2lvbmluZ01vZGUiOiBQcm92aXNpb25pbmdNb2RlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlX1BhcnRpYWxVbnByb3Zpc2lvbiA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJQYXJ0aWFsVW5wcm92aXNpb24iLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9SZXNldEZsYXNoV2Vhck91dFByb3RlY3Rpb24gPSBmdW5jdGlvbiAoX21ldGhvZF9kdW1teSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2UiLCAiUmVzZXRGbGFzaFdlYXJPdXRQcm90ZWN0aW9uIiwgeyAiX21ldGhvZF9kdW1teSI6IF9tZXRob2RfZHVtbXkgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2VfRXh0ZW5kUHJvdmlzaW9uaW5nUGVyaW9kID0gZnVuY3Rpb24gKER1cmF0aW9uLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJFeHRlbmRQcm92aXNpb25pbmdQZXJpb2QiLCB7ICJEdXJhdGlvbiI6IER1cmF0aW9uIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlX1NldE1FQnhQYXNzd29yZCA9IGZ1bmN0aW9uIChQYXNzd29yZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2UiLCAiU2V0TUVCeFBhc3N3b3JkIiwgeyAiUGFzc3dvcmQiOiBQYXNzd29yZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9TZXRUTFNQU0sgPSBmdW5jdGlvbiAoUElELCBQUFMsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgIlNldFRMU1BTSyIsIHsgIlBJRCI6IFBJRCwgIlBQUyI6IFBQUyB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9HZXRQcm92aXNpb25pbmdBdWRpdFJlY29yZCA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJHZXRQcm92aXNpb25pbmdBdWRpdFJlY29yZCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9HZXRVdWlkID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgIkdldFV1aWQiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2VfR2V0VW5wcm92aXNpb25CbG9ja2luZ0NvbXBvbmVudHMgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2UiLCAiR2V0VW5wcm92aXNpb25CbG9ja2luZ0NvbXBvbmVudHMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1NldHVwQW5kQ29uZmlndXJhdGlvblNlcnZpY2VfR2V0UHJvdmlzaW9uaW5nQXVkaXRSZWNvcmRWMiA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIsICJHZXRQcm92aXNpb25pbmdBdWRpdFJlY29yZFYyIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9TeXN0ZW1EZWZlbnNlUG9saWN5X0dldFRpbWVvdXQgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1N5c3RlbURlZmVuc2VQb2xpY3kiLCAiR2V0VGltZW91dCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU3lzdGVtRGVmZW5zZVBvbGljeV9TZXRUaW1lb3V0ID0gZnVuY3Rpb24gKFRpbWVvdXQsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9TeXN0ZW1EZWZlbnNlUG9saWN5IiwgIlNldFRpbWVvdXQiLCB7ICJUaW1lb3V0IjogVGltZW91dCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfU3lzdGVtRGVmZW5zZVBvbGljeV9VcGRhdGVTdGF0aXN0aWNzID0gZnVuY3Rpb24gKE5ldHdvcmtJbnRlcmZhY2UsIFJlc2V0T25SZWFkLCBjYWxsYmFja19mdW5jLCB0YWcsIHByaSwgc2VsZWN0b3JzKSB7IG9iai5FeGVjKCJBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSIsICJVcGRhdGVTdGF0aXN0aWNzIiwgeyAiTmV0d29ya0ludGVyZmFjZSI6IE5ldHdvcmtJbnRlcmZhY2UsICJSZXNldE9uUmVhZCI6IFJlc2V0T25SZWFkIH0sIGNhbGxiYWNrX2Z1bmMsIHRhZywgcHJpLCBzZWxlY3RvcnMpOyB9DQogICAgb2JqLkFNVF9TeXN0ZW1Qb3dlclNjaGVtZV9TZXRQb3dlclNjaGVtZSA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jLCBzY2hlbWVJbnN0YW5jZUlkLCB0YWcpIHsgb2JqLkV4ZWMoIkFNVF9TeXN0ZW1Qb3dlclNjaGVtZSIsICJTZXRQb3dlclNjaGVtZSIsIHt9LCBjYWxsYmFja19mdW5jLCB0YWcsIDAsIHsgIkluc3RhbmNlSUQiOiBzY2hlbWVJbnN0YW5jZUlkIH0pOyB9DQogICAgb2JqLkFNVF9UaW1lU3luY2hyb25pemF0aW9uU2VydmljZV9HZXRMb3dBY2N1cmFjeVRpbWVTeW5jaCA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jLCB0YWcpIHsgb2JqLkV4ZWMoIkFNVF9UaW1lU3luY2hyb25pemF0aW9uU2VydmljZSIsICJHZXRMb3dBY2N1cmFjeVRpbWVTeW5jaCIsIHt9LCBjYWxsYmFja19mdW5jLCB0YWcpOyB9DQogICAgb2JqLkFNVF9UaW1lU3luY2hyb25pemF0aW9uU2VydmljZV9TZXRIaWdoQWNjdXJhY3lUaW1lU3luY2ggPSBmdW5jdGlvbiAoVGEwLCBUbTEsIFRtMiwgY2FsbGJhY2tfZnVuYywgdGFnKSB7IG9iai5FeGVjKCJBTVRfVGltZVN5bmNocm9uaXphdGlvblNlcnZpY2UiLCAiU2V0SGlnaEFjY3VyYWN5VGltZVN5bmNoIiwgeyAiVGEwIjogVGEwLCAiVG0xIjogVG0xLCAiVG0yIjogVG0yIH0sIGNhbGxiYWNrX2Z1bmMsIHRhZyk7IH0NCiAgICBvYmouQU1UX1VzZXJJbml0aWF0ZWRDb25uZWN0aW9uU2VydmljZV9SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkFNVF9Vc2VySW5pdGlhdGVkQ29ubmVjdGlvblNlcnZpY2UiLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZSwgIlRpbWVvdXRQZXJpb2QiOiBUaW1lb3V0UGVyaW9kIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9XZWJVSVNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfV2ViVUlTZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5BTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZV9BZGRXaUZpU2V0dGluZ3MgPSBmdW5jdGlvbiAoV2lGaUVuZHBvaW50LCBXaUZpRW5kcG9pbnRTZXR0aW5nc0lucHV0LCBJRUVFODAyMXhTZXR0aW5nc0lucHV0LCBDbGllbnRDcmVkZW50aWFsLCBDQUNyZWRlbnRpYWwsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWNXaXRoWG1sKCJBTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZSIsICJBZGRXaUZpU2V0dGluZ3MiLCB7ICJXaUZpRW5kcG9pbnQiOiBXaUZpRW5kcG9pbnQsICJXaUZpRW5kcG9pbnRTZXR0aW5nc0lucHV0IjogV2lGaUVuZHBvaW50U2V0dGluZ3NJbnB1dCwgIklFRUU4MDIxeFNldHRpbmdzSW5wdXQiOiBJRUVFODAyMXhTZXR0aW5nc0lucHV0LCAiQ2xpZW50Q3JlZGVudGlhbCI6IENsaWVudENyZWRlbnRpYWwsICJDQUNyZWRlbnRpYWwiOiBDQUNyZWRlbnRpYWwgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQU1UX1dpRmlQb3J0Q29uZmlndXJhdGlvblNlcnZpY2VfVXBkYXRlV2lGaVNldHRpbmdzID0gZnVuY3Rpb24gKFdpRmlFbmRwb2ludFNldHRpbmdzLCBXaUZpRW5kcG9pbnRTZXR0aW5nc0lucHV0LCBJRUVFODAyMXhTZXR0aW5nc0lucHV0LCBDbGllbnRDcmVkZW50aWFsLCBDQUNyZWRlbnRpYWwsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWNXaXRoWG1sKCJBTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZSIsICJVcGRhdGVXaUZpU2V0dGluZ3MiLCB7ICJXaUZpRW5kcG9pbnRTZXR0aW5ncyI6IFdpRmlFbmRwb2ludFNldHRpbmdzLCAiV2lGaUVuZHBvaW50U2V0dGluZ3NJbnB1dCI6IFdpRmlFbmRwb2ludFNldHRpbmdzSW5wdXQsICJJRUVFODAyMXhTZXR0aW5nc0lucHV0IjogSUVFRTgwMjF4U2V0dGluZ3NJbnB1dCwgIkNsaWVudENyZWRlbnRpYWwiOiBDbGllbnRDcmVkZW50aWFsLCAiQ0FDcmVkZW50aWFsIjogQ0FDcmVkZW50aWFsIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9XaUZpUG9ydENvbmZpZ3VyYXRpb25TZXJ2aWNlX0RlbGV0ZUFsbElUUHJvZmlsZXMgPSBmdW5jdGlvbiAoX21ldGhvZF9kdW1teSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQU1UX1dpRmlQb3J0Q29uZmlndXJhdGlvblNlcnZpY2UiLCAiRGVsZXRlQWxsSVRQcm9maWxlcyIsIHsgIl9tZXRob2RfZHVtbXkiOiBfbWV0aG9kX2R1bW15IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkFNVF9XaUZpUG9ydENvbmZpZ3VyYXRpb25TZXJ2aWNlX0RlbGV0ZUFsbFVzZXJQcm9maWxlcyA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJBTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZSIsICJEZWxldGVBbGxVc2VyUHJvZmlsZXMiLCB7ICJfbWV0aG9kX2R1bW15IjogX21ldGhvZF9kdW1teSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fQWNjb3VudF9SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9BY2NvdW50IiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fQWNjb3VudE1hbmFnZW1lbnRTZXJ2aWNlX0NyZWF0ZUFjY291bnQgPSBmdW5jdGlvbiAoU3lzdGVtLCBBY2NvdW50VGVtcGxhdGUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9BY2NvdW50TWFuYWdlbWVudFNlcnZpY2UiLCAiQ3JlYXRlQWNjb3VudCIsIHsgIlN5c3RlbSI6IFN5c3RlbSwgIkFjY291bnRUZW1wbGF0ZSI6IEFjY291bnRUZW1wbGF0ZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fQm9vdENvbmZpZ1NldHRpbmdfQ2hhbmdlQm9vdE9yZGVyID0gZnVuY3Rpb24gKFNvdXJjZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX0Jvb3RDb25maWdTZXR0aW5nIiwgIkNoYW5nZUJvb3RPcmRlciIsIHsgIlNvdXJjZSI6IFNvdXJjZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fQm9vdFNlcnZpY2VfU2V0Qm9vdENvbmZpZ1JvbGUgPSBmdW5jdGlvbiAoQm9vdENvbmZpZ1NldHRpbmcsIFJvbGUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Cb290U2VydmljZSIsICJTZXRCb290Q29uZmlnUm9sZSIsIHsgIkJvb3RDb25maWdTZXR0aW5nIjogQm9vdENvbmZpZ1NldHRpbmcsICJSb2xlIjogUm9sZSB9LCBjYWxsYmFja19mdW5jLCAwLCAxKTsgfQ0KICAgIG9iai5DSU1fQ2FyZF9Db25uZWN0b3JQb3dlciA9IGZ1bmN0aW9uIChDb25uZWN0b3IsIFBvd2VyZWRPbiwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX0NhcmQiLCAiQ29ubmVjdG9yUG93ZXIiLCB7ICJDb25uZWN0b3IiOiBDb25uZWN0b3IsICJQb3dlcmVkT24iOiBQb3dlcmVkT24gfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX0NhcmRfSXNDb21wYXRpYmxlID0gZnVuY3Rpb24gKEVsZW1lbnRUb0NoZWNrLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fQ2FyZCIsICJJc0NvbXBhdGlibGUiLCB7ICJFbGVtZW50VG9DaGVjayI6IEVsZW1lbnRUb0NoZWNrIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9DaGFzc2lzX0lzQ29tcGF0aWJsZSA9IGZ1bmN0aW9uIChFbGVtZW50VG9DaGVjaywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX0NoYXNzaXMiLCAiSXNDb21wYXRpYmxlIiwgeyAiRWxlbWVudFRvQ2hlY2siOiBFbGVtZW50VG9DaGVjayB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fRmFuX1NldFNwZWVkID0gZnVuY3Rpb24gKERlc2lyZWRTcGVlZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX0ZhbiIsICJTZXRTcGVlZCIsIHsgIkRlc2lyZWRTcGVlZCI6IERlc2lyZWRTcGVlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fS1ZNUmVkaXJlY3Rpb25TQVBfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fS1ZNUmVkaXJlY3Rpb25TQVAiLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZS8qLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgKi99LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfTG9ja01lZGlhID0gZnVuY3Rpb24gKExvY2ssIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJMb2NrTWVkaWEiLCB7ICJMb2NrIjogTG9jayB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfU2V0UG93ZXJTdGF0ZSA9IGZ1bmN0aW9uIChQb3dlclN0YXRlLCBUaW1lLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fTWVkaWFBY2Nlc3NEZXZpY2UiLCAiU2V0UG93ZXJTdGF0ZSIsIHsgIlBvd2VyU3RhdGUiOiBQb3dlclN0YXRlLCAiVGltZSI6IFRpbWUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX01lZGlhQWNjZXNzRGV2aWNlX1Jlc2V0ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJSZXNldCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfRW5hYmxlRGV2aWNlID0gZnVuY3Rpb24gKEVuYWJsZWQsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJFbmFibGVEZXZpY2UiLCB7ICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfT25saW5lRGV2aWNlID0gZnVuY3Rpb24gKE9ubGluZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX01lZGlhQWNjZXNzRGV2aWNlIiwgIk9ubGluZURldmljZSIsIHsgIk9ubGluZSI6IE9ubGluZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfUXVpZXNjZURldmljZSA9IGZ1bmN0aW9uIChRdWllc2NlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fTWVkaWFBY2Nlc3NEZXZpY2UiLCAiUXVpZXNjZURldmljZSIsIHsgIlF1aWVzY2UiOiBRdWllc2NlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9NZWRpYUFjY2Vzc0RldmljZV9TYXZlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fTWVkaWFBY2Nlc3NEZXZpY2UiLCAiU2F2ZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX01lZGlhQWNjZXNzRGV2aWNlX1Jlc3RvcmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJSZXN0b3JlUHJvcGVydGllcyIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fTWVkaWFBY2Nlc3NEZXZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fTWVkaWFBY2Nlc3NEZXZpY2UiLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZSwgIlRpbWVvdXRQZXJpb2QiOiBUaW1lb3V0UGVyaW9kIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9QaHlzaWNhbEZyYW1lX0lzQ29tcGF0aWJsZSA9IGZ1bmN0aW9uIChFbGVtZW50VG9DaGVjaywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1BoeXNpY2FsRnJhbWUiLCAiSXNDb21wYXRpYmxlIiwgeyAiRWxlbWVudFRvQ2hlY2siOiBFbGVtZW50VG9DaGVjayB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUGh5c2ljYWxQYWNrYWdlX0lzQ29tcGF0aWJsZSA9IGZ1bmN0aW9uIChFbGVtZW50VG9DaGVjaywgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1BoeXNpY2FsUGFja2FnZSIsICJJc0NvbXBhdGlibGUiLCB7ICJFbGVtZW50VG9DaGVjayI6IEVsZW1lbnRUb0NoZWNrIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qb3dlck1hbmFnZW1lbnRTZXJ2aWNlX1JlcXVlc3RQb3dlclN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFBvd2VyU3RhdGUsIE1hbmFnZWRFbGVtZW50LCBUaW1lLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUG93ZXJNYW5hZ2VtZW50U2VydmljZSIsICJSZXF1ZXN0UG93ZXJTdGF0ZUNoYW5nZSIsIHsgIlBvd2VyU3RhdGUiOiBQb3dlclN0YXRlLCAiTWFuYWdlZEVsZW1lbnQiOiBNYW5hZ2VkRWxlbWVudCwgIlRpbWUiOiBUaW1lLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYywgMCwgMSk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X1NldFBvd2VyU3RhdGUgPSBmdW5jdGlvbiAoUG93ZXJTdGF0ZSwgVGltZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Bvd2VyU3VwcGx5IiwgIlNldFBvd2VyU3RhdGUiLCB7ICJQb3dlclN0YXRlIjogUG93ZXJTdGF0ZSwgIlRpbWUiOiBUaW1lIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qb3dlclN1cHBseV9SZXNldCA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUG93ZXJTdXBwbHkiLCAiUmVzZXQiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X0VuYWJsZURldmljZSA9IGZ1bmN0aW9uIChFbmFibGVkLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUG93ZXJTdXBwbHkiLCAiRW5hYmxlRGV2aWNlIiwgeyAiRW5hYmxlZCI6IEVuYWJsZWQgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X09ubGluZURldmljZSA9IGZ1bmN0aW9uIChPbmxpbmUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Qb3dlclN1cHBseSIsICJPbmxpbmVEZXZpY2UiLCB7ICJPbmxpbmUiOiBPbmxpbmUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X1F1aWVzY2VEZXZpY2UgPSBmdW5jdGlvbiAoUXVpZXNjZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Bvd2VyU3VwcGx5IiwgIlF1aWVzY2VEZXZpY2UiLCB7ICJRdWllc2NlIjogUXVpZXNjZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUG93ZXJTdXBwbHlfU2F2ZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Bvd2VyU3VwcGx5IiwgIlNhdmVQcm9wZXJ0aWVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qb3dlclN1cHBseV9SZXN0b3JlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUG93ZXJTdXBwbHkiLCAiUmVzdG9yZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Bvd2VyU3VwcGx5X1JlcXVlc3RTdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uIChSZXF1ZXN0ZWRTdGF0ZSwgVGltZW91dFBlcmlvZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Bvd2VyU3VwcGx5IiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUHJvY2Vzc29yX1NldFBvd2VyU3RhdGUgPSBmdW5jdGlvbiAoUG93ZXJTdGF0ZSwgVGltZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Byb2Nlc3NvciIsICJTZXRQb3dlclN0YXRlIiwgeyAiUG93ZXJTdGF0ZSI6IFBvd2VyU3RhdGUsICJUaW1lIjogVGltZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUHJvY2Vzc29yX1Jlc2V0ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Qcm9jZXNzb3IiLCAiUmVzZXQiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Byb2Nlc3Nvcl9FbmFibGVEZXZpY2UgPSBmdW5jdGlvbiAoRW5hYmxlZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1Byb2Nlc3NvciIsICJFbmFibGVEZXZpY2UiLCB7ICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUHJvY2Vzc29yX09ubGluZURldmljZSA9IGZ1bmN0aW9uIChPbmxpbmUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Qcm9jZXNzb3IiLCAiT25saW5lRGV2aWNlIiwgeyAiT25saW5lIjogT25saW5lIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qcm9jZXNzb3JfUXVpZXNjZURldmljZSA9IGZ1bmN0aW9uIChRdWllc2NlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUHJvY2Vzc29yIiwgIlF1aWVzY2VEZXZpY2UiLCB7ICJRdWllc2NlIjogUXVpZXNjZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUHJvY2Vzc29yX1NhdmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9Qcm9jZXNzb3IiLCAiU2F2ZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1Byb2Nlc3Nvcl9SZXN0b3JlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUHJvY2Vzc29yIiwgIlJlc3RvcmVQcm9wZXJ0aWVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9Qcm9jZXNzb3JfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUHJvY2Vzc29yIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fUmVjb3JkTG9nX0NsZWFyTG9nID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9SZWNvcmRMb2ciLCAiQ2xlYXJMb2ciLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1JlY29yZExvZ19SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9SZWNvcmRMb2ciLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZSwgIlRpbWVvdXRQZXJpb2QiOiBUaW1lb3V0UGVyaW9kIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9SZWRpcmVjdGlvblNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fUmVkaXJlY3Rpb25TZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU2Vuc29yX1NldFBvd2VyU3RhdGUgPSBmdW5jdGlvbiAoUG93ZXJTdGF0ZSwgVGltZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1NlbnNvciIsICJTZXRQb3dlclN0YXRlIiwgeyAiUG93ZXJTdGF0ZSI6IFBvd2VyU3RhdGUsICJUaW1lIjogVGltZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU2Vuc29yX1Jlc2V0ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9TZW5zb3IiLCAiUmVzZXQiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1NlbnNvcl9FbmFibGVEZXZpY2UgPSBmdW5jdGlvbiAoRW5hYmxlZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1NlbnNvciIsICJFbmFibGVEZXZpY2UiLCB7ICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU2Vuc29yX09ubGluZURldmljZSA9IGZ1bmN0aW9uIChPbmxpbmUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9TZW5zb3IiLCAiT25saW5lRGV2aWNlIiwgeyAiT25saW5lIjogT25saW5lIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9TZW5zb3JfUXVpZXNjZURldmljZSA9IGZ1bmN0aW9uIChRdWllc2NlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fU2Vuc29yIiwgIlF1aWVzY2VEZXZpY2UiLCB7ICJRdWllc2NlIjogUXVpZXNjZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU2Vuc29yX1NhdmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9TZW5zb3IiLCAiU2F2ZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1NlbnNvcl9SZXN0b3JlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fU2Vuc29yIiwgIlJlc3RvcmVQcm9wZXJ0aWVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9TZW5zb3JfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fU2Vuc29yIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fU3RhdGlzdGljYWxEYXRhX1Jlc2V0U2VsZWN0ZWRTdGF0cyA9IGZ1bmN0aW9uIChTZWxlY3RlZFN0YXRpc3RpY3MsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9TdGF0aXN0aWNhbERhdGEiLCAiUmVzZXRTZWxlY3RlZFN0YXRzIiwgeyAiU2VsZWN0ZWRTdGF0aXN0aWNzIjogU2VsZWN0ZWRTdGF0aXN0aWNzIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XYXRjaGRvZ19LZWVwQWxpdmUgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dhdGNoZG9nIiwgIktlZXBBbGl2ZSIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfU2V0UG93ZXJTdGF0ZSA9IGZ1bmN0aW9uIChQb3dlclN0YXRlLCBUaW1lLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2F0Y2hkb2ciLCAiU2V0UG93ZXJTdGF0ZSIsIHsgIlBvd2VyU3RhdGUiOiBQb3dlclN0YXRlLCAiVGltZSI6IFRpbWUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1dhdGNoZG9nX1Jlc2V0ID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XYXRjaGRvZyIsICJSZXNldCIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfRW5hYmxlRGV2aWNlID0gZnVuY3Rpb24gKEVuYWJsZWQsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XYXRjaGRvZyIsICJFbmFibGVEZXZpY2UiLCB7ICJFbmFibGVkIjogRW5hYmxlZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfT25saW5lRGV2aWNlID0gZnVuY3Rpb24gKE9ubGluZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dhdGNoZG9nIiwgIk9ubGluZURldmljZSIsIHsgIk9ubGluZSI6IE9ubGluZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfUXVpZXNjZURldmljZSA9IGZ1bmN0aW9uIChRdWllc2NlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2F0Y2hkb2ciLCAiUXVpZXNjZURldmljZSIsIHsgIlF1aWVzY2UiOiBRdWllc2NlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XYXRjaGRvZ19TYXZlUHJvcGVydGllcyA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2F0Y2hkb2ciLCAiU2F2ZVByb3BlcnRpZXMiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1dhdGNoZG9nX1Jlc3RvcmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XYXRjaGRvZyIsICJSZXN0b3JlUHJvcGVydGllcyIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2F0Y2hkb2dfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2F0Y2hkb2ciLCAiUmVxdWVzdFN0YXRlQ2hhbmdlIiwgeyAiUmVxdWVzdGVkU3RhdGUiOiBSZXF1ZXN0ZWRTdGF0ZSwgIlRpbWVvdXRQZXJpb2QiOiBUaW1lb3V0UGVyaW9kIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9TZXRQb3dlclN0YXRlID0gZnVuY3Rpb24gKFBvd2VyU3RhdGUsIFRpbWUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XaUZpUG9ydCIsICJTZXRQb3dlclN0YXRlIiwgeyAiUG93ZXJTdGF0ZSI6IFBvd2VyU3RhdGUsICJUaW1lIjogVGltZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2lGaVBvcnRfUmVzZXQgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dpRmlQb3J0IiwgIlJlc2V0Iiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9FbmFibGVEZXZpY2UgPSBmdW5jdGlvbiAoRW5hYmxlZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dpRmlQb3J0IiwgIkVuYWJsZURldmljZSIsIHsgIkVuYWJsZWQiOiBFbmFibGVkIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9PbmxpbmVEZXZpY2UgPSBmdW5jdGlvbiAoT25saW5lLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJDSU1fV2lGaVBvcnQiLCAiT25saW5lRGV2aWNlIiwgeyAiT25saW5lIjogT25saW5lIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9RdWllc2NlRGV2aWNlID0gZnVuY3Rpb24gKFF1aWVzY2UsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XaUZpUG9ydCIsICJRdWllc2NlRGV2aWNlIiwgeyAiUXVpZXNjZSI6IFF1aWVzY2UgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouQ0lNX1dpRmlQb3J0X1NhdmVQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XaUZpUG9ydCIsICJTYXZlUHJvcGVydGllcyIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5DSU1fV2lGaVBvcnRfUmVzdG9yZVByb3BlcnRpZXMgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiQ0lNX1dpRmlQb3J0IiwgIlJlc3RvcmVQcm9wZXJ0aWVzIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLkNJTV9XaUZpUG9ydF9SZXF1ZXN0U3RhdGVDaGFuZ2UgPSBmdW5jdGlvbiAoUmVxdWVzdGVkU3RhdGUsIFRpbWVvdXRQZXJpb2QsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIkNJTV9XaUZpUG9ydCIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX0hvc3RCYXNlZFNldHVwU2VydmljZV9TZXR1cCA9IGZ1bmN0aW9uIChOZXRBZG1pblBhc3NFbmNyeXB0aW9uVHlwZSwgTmV0d29ya0FkbWluUGFzc3dvcmQsIE1jTm9uY2UsIENlcnRpZmljYXRlLCBTaWduaW5nQWxnb3JpdGhtLCBEaWdpdGFsU2lnbmF0dXJlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlIiwgIlNldHVwIiwgeyAiTmV0QWRtaW5QYXNzRW5jcnlwdGlvblR5cGUiOiBOZXRBZG1pblBhc3NFbmNyeXB0aW9uVHlwZSwgIk5ldHdvcmtBZG1pblBhc3N3b3JkIjogTmV0d29ya0FkbWluUGFzc3dvcmQsICJNY05vbmNlIjogTWNOb25jZSwgIkNlcnRpZmljYXRlIjogQ2VydGlmaWNhdGUsICJTaWduaW5nQWxnb3JpdGhtIjogU2lnbmluZ0FsZ29yaXRobSwgIkRpZ2l0YWxTaWduYXR1cmUiOiBEaWdpdGFsU2lnbmF0dXJlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2VfQWRkTmV4dENlcnRJbkNoYWluID0gZnVuY3Rpb24gKE5leHRDZXJ0aWZpY2F0ZSwgSXNMZWFmQ2VydGlmaWNhdGUsIElzUm9vdENlcnRpZmljYXRlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlIiwgIkFkZE5leHRDZXJ0SW5DaGFpbiIsIHsgIk5leHRDZXJ0aWZpY2F0ZSI6IE5leHRDZXJ0aWZpY2F0ZSwgIklzTGVhZkNlcnRpZmljYXRlIjogSXNMZWFmQ2VydGlmaWNhdGUsICJJc1Jvb3RDZXJ0aWZpY2F0ZSI6IElzUm9vdENlcnRpZmljYXRlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2VfQWRtaW5TZXR1cCA9IGZ1bmN0aW9uIChOZXRBZG1pblBhc3NFbmNyeXB0aW9uVHlwZSwgTmV0d29ya0FkbWluUGFzc3dvcmQsIE1jTm9uY2UsIFNpZ25pbmdBbGdvcml0aG0sIERpZ2l0YWxTaWduYXR1cmUsIGNhbGxiYWNrX2Z1bmMpIHsgb2JqLkV4ZWMoIklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2UiLCAiQWRtaW5TZXR1cCIsIHsgIk5ldEFkbWluUGFzc0VuY3J5cHRpb25UeXBlIjogTmV0QWRtaW5QYXNzRW5jcnlwdGlvblR5cGUsICJOZXR3b3JrQWRtaW5QYXNzd29yZCI6IE5ldHdvcmtBZG1pblBhc3N3b3JkLCAiTWNOb25jZSI6IE1jTm9uY2UsICJTaWduaW5nQWxnb3JpdGhtIjogU2lnbmluZ0FsZ29yaXRobSwgIkRpZ2l0YWxTaWduYXR1cmUiOiBEaWdpdGFsU2lnbmF0dXJlIH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2VfVXBncmFkZUNsaWVudFRvQWRtaW4gPSBmdW5jdGlvbiAoTWNOb25jZSwgU2lnbmluZ0FsZ29yaXRobSwgRGlnaXRhbFNpZ25hdHVyZSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX0hvc3RCYXNlZFNldHVwU2VydmljZSIsICJVcGdyYWRlQ2xpZW50VG9BZG1pbiIsIHsgIk1jTm9uY2UiOiBNY05vbmNlLCAiU2lnbmluZ0FsZ29yaXRobSI6IFNpZ25pbmdBbGdvcml0aG0sICJEaWdpdGFsU2lnbmF0dXJlIjogRGlnaXRhbFNpZ25hdHVyZSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlX0Rpc2FibGVDbGllbnRDb250cm9sTW9kZSA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlIiwgIkRpc2FibGVDbGllbnRDb250cm9sTW9kZSIsIHsgIl9tZXRob2RfZHVtbXkiOiBfbWV0aG9kX2R1bW15IH0sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhX1Rlcm1pbmF0ZVNlc3Npb24gPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEiLCAiVGVybWluYXRlU2Vzc2lvbiIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfS1ZNUmVkaXJlY3Rpb25TZXR0aW5nRGF0YV9EYXRhQ2hhbm5lbFJlYWQgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEiLCAiRGF0YUNoYW5uZWxSZWFkIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhX0RhdGFDaGFubmVsV3JpdGUgPSBmdW5jdGlvbiAoRGF0YSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEiLCAiRGF0YUNoYW5uZWxXcml0ZSIsIHsgIkRhdGFNZXNzYWdlIjogRGF0YSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfT3B0SW5TZXJ2aWNlX1N0YXJ0T3B0SW4gPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX09wdEluU2VydmljZSIsICJTdGFydE9wdEluIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19PcHRJblNlcnZpY2VfQ2FuY2VsT3B0SW4gPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX09wdEluU2VydmljZSIsICJDYW5jZWxPcHRJbiIsIHt9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfT3B0SW5TZXJ2aWNlX1NlbmRPcHRJbkNvZGUgPSBmdW5jdGlvbiAoT3B0SW5Db2RlLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfT3B0SW5TZXJ2aWNlIiwgIlNlbmRPcHRJbkNvZGUiLCB7ICJPcHRJbkNvZGUiOiBPcHRJbkNvZGUgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX09wdEluU2VydmljZV9TdGFydFNlcnZpY2UgPSBmdW5jdGlvbiAoY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX09wdEluU2VydmljZSIsICJTdGFydFNlcnZpY2UiLCB7fSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX09wdEluU2VydmljZV9TdG9wU2VydmljZSA9IGZ1bmN0aW9uIChjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfT3B0SW5TZXJ2aWNlIiwgIlN0b3BTZXJ2aWNlIiwge30sIGNhbGxiYWNrX2Z1bmMpOyB9DQogICAgb2JqLklQU19PcHRJblNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlID0gZnVuY3Rpb24gKFJlcXVlc3RlZFN0YXRlLCBUaW1lb3V0UGVyaW9kLCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfT3B0SW5TZXJ2aWNlIiwgIlJlcXVlc3RTdGF0ZUNoYW5nZSIsIHsgIlJlcXVlc3RlZFN0YXRlIjogUmVxdWVzdGVkU3RhdGUsICJUaW1lb3V0UGVyaW9kIjogVGltZW91dFBlcmlvZCB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfUHJvdmlzaW9uaW5nUmVjb3JkTG9nX1JlcXVlc3RTdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uIChSZXF1ZXN0ZWRTdGF0ZSwgVGltZW91dFBlcmlvZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX1Byb3Zpc2lvbmluZ1JlY29yZExvZyIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX1Byb3Zpc2lvbmluZ1JlY29yZExvZ19DbGVhckxvZyA9IGZ1bmN0aW9uIChfbWV0aG9kX2R1bW15LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfUHJvdmlzaW9uaW5nUmVjb3JkTG9nIiwgIkNsZWFyTG9nIiwgeyAiX21ldGhvZF9kdW1teSI6IF9tZXRob2RfZHVtbXkgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX1NjcmVlbkNvbmZpZ3VyYXRpb25TZXJ2aWNlX1NldFNlc3Npb25TdGF0ZSA9IGZ1bmN0aW9uIChTZXNzaW9uU3RhdGUsIENvbnNlY3V0aXZlUmVib290c051bSwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX1NjcmVlbkNvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgIlNldFNlc3Npb25TdGF0ZSIsIHsgIlNlc3Npb25TdGF0ZSI6IFNlc3Npb25TdGF0ZSwgIkNvbnNlY3V0aXZlUmVib290c051bSI6IENvbnNlY3V0aXZlUmVib290c051bSB9LCBjYWxsYmFja19mdW5jKTsgfQ0KICAgIG9iai5JUFNfU2VjSU9TZXJ2aWNlX1JlcXVlc3RTdGF0ZUNoYW5nZSA9IGZ1bmN0aW9uIChSZXF1ZXN0ZWRTdGF0ZSwgVGltZW91dFBlcmlvZCwgY2FsbGJhY2tfZnVuYykgeyBvYmouRXhlYygiSVBTX1NlY0lPU2VydmljZSIsICJSZXF1ZXN0U3RhdGVDaGFuZ2UiLCB7ICJSZXF1ZXN0ZWRTdGF0ZSI6IFJlcXVlc3RlZFN0YXRlLCAiVGltZW91dFBlcmlvZCI6IFRpbWVvdXRQZXJpb2QgfSwgY2FsbGJhY2tfZnVuYyk7IH0NCiAgICBvYmouSVBTX0hUVFBQcm94eVNlcnZpY2VfQWRkUHJveHlBY2Nlc3NQb2ludCA9IGZ1bmN0aW9uIChBY2Nlc3NJbmZvLCBJbmZvRm9ybWF0LCBQb3J0LCBOZXR3b3JrRG5zU3VmZml4LCBjYWxsYmFja19mdW5jKSB7IG9iai5FeGVjKCJJUFNfSFRUUFByb3h5U2VydmljZSIsICJBZGRQcm94eUFjY2Vzc1BvaW50IiwgeyAiQWNjZXNzSW5mbyI6IEFjY2Vzc0luZm8sICJJbmZvRm9ybWF0IjogSW5mb0Zvcm1hdCwgIlBvcnQiOiBQb3J0LCAiTmV0d29ya0Ruc1N1ZmZpeCI6IE5ldHdvcmtEbnNTdWZmaXggfSwgY2FsbGJhY2tfZnVuYyk7IH0NCg0KICAgIG9iai5BbXRTdGF0dXNUb1N0ciA9IGZ1bmN0aW9uIChjb2RlKSB7IGlmIChvYmouQW10U3RhdHVzQ29kZXNbY29kZV0pIHJldHVybiBvYmouQW10U3RhdHVzQ29kZXNbY29kZV07IGVsc2UgcmV0dXJuICJVTktOT1dOX0VSUk9SIiB9DQogICAgb2JqLkFtdFN0YXR1c0NvZGVzID0gew0KICAgICAgICAweDAwMDA6ICJTVUNDRVNTIiwNCiAgICAgICAgMHgwMDAxOiAiSU5URVJOQUxfRVJST1IiLA0KICAgICAgICAweDAwMDI6ICJOT1RfUkVBRFkiLA0KICAgICAgICAweDAwMDM6ICJJTlZBTElEX1BUX01PREUiLA0KICAgICAgICAweDAwMDQ6ICJJTlZBTElEX01FU1NBR0VfTEVOR1RIIiwNCiAgICAgICAgMHgwMDA1OiAiVEFCTEVfRklOR0VSUFJJTlRfTk9UX0FWQUlMQUJMRSIsDQogICAgICAgIDB4MDAwNjogIklOVEVHUklUWV9DSEVDS19GQUlMRUQiLA0KICAgICAgICAweDAwMDc6ICJVTlNVUFBPUlRFRF9JU1ZTX1ZFUlNJT04iLA0KICAgICAgICAweDAwMDg6ICJBUFBMSUNBVElPTl9OT1RfUkVHSVNURVJFRCIsDQogICAgICAgIDB4MDAwOTogIklOVkFMSURfUkVHSVNUUkFUSU9OX0RBVEEiLA0KICAgICAgICAweDAwMEE6ICJBUFBMSUNBVElPTl9ET0VTX05PVF9FWElTVCIsDQogICAgICAgIDB4MDAwQjogIk5PVF9FTk9VR0hfU1RPUkFHRSIsDQogICAgICAgIDB4MDAwQzogIklOVkFMSURfTkFNRSIsDQogICAgICAgIDB4MDAwRDogIkJMT0NLX0RPRVNfTk9UX0VYSVNUIiwNCiAgICAgICAgMHgwMDBFOiAiSU5WQUxJRF9CWVRFX09GRlNFVCIsDQogICAgICAgIDB4MDAwRjogIklOVkFMSURfQllURV9DT1VOVCIsDQogICAgICAgIDB4MDAxMDogIk5PVF9QRVJNSVRURUQiLA0KICAgICAgICAweDAwMTE6ICJOT1RfT1dORVIiLA0KICAgICAgICAweDAwMTI6ICJCTE9DS19MT0NLRURfQllfT1RIRVIiLA0KICAgICAgICAweDAwMTM6ICJCTE9DS19OT1RfTE9DS0VEIiwNCiAgICAgICAgMHgwMDE0OiAiSU5WQUxJRF9HUk9VUF9QRVJNSVNTSU9OUyIsDQogICAgICAgIDB4MDAxNTogIkdST1VQX0RPRVNfTk9UX0VYSVNUIiwNCiAgICAgICAgMHgwMDE2OiAiSU5WQUxJRF9NRU1CRVJfQ09VTlQiLA0KICAgICAgICAweDAwMTc6ICJNQVhfTElNSVRfUkVBQ0hFRCIsDQogICAgICAgIDB4MDAxODogIklOVkFMSURfQVVUSF9UWVBFIiwNCiAgICAgICAgMHgwMDE5OiAiQVVUSEVOVElDQVRJT05fRkFJTEVEIiwNCiAgICAgICAgMHgwMDFBOiAiSU5WQUxJRF9ESENQX01PREUiLA0KICAgICAgICAweDAwMUI6ICJJTlZBTElEX0lQX0FERFJFU1MiLA0KICAgICAgICAweDAwMUM6ICJJTlZBTElEX0RPTUFJTl9OQU1FIiwNCiAgICAgICAgMHgwMDFEOiAiVU5TVVBQT1JURURfVkVSU0lPTiIsDQogICAgICAgIDB4MDAxRTogIlJFUVVFU1RfVU5FWFBFQ1RFRCIsDQogICAgICAgIDB4MDAxRjogIklOVkFMSURfVEFCTEVfVFlQRSIsDQogICAgICAgIDB4MDAyMDogIklOVkFMSURfUFJPVklTSU9OSU5HX1NUQVRFIiwNCiAgICAgICAgMHgwMDIxOiAiVU5TVVBQT1JURURfT0JKRUNUIiwNCiAgICAgICAgMHgwMDIyOiAiSU5WQUxJRF9USU1FIiwNCiAgICAgICAgMHgwMDIzOiAiSU5WQUxJRF9JTkRFWCIsDQogICAgICAgIDB4MDAyNDogIklOVkFMSURfUEFSQU1FVEVSIiwNCiAgICAgICAgMHgwMDI1OiAiSU5WQUxJRF9ORVRNQVNLIiwNCiAgICAgICAgMHgwMDI2OiAiRkxBU0hfV1JJVEVfTElNSVRfRVhDRUVERUQiLA0KICAgICAgICAweDAwMjc6ICJJTlZBTElEX0lNQUdFX0xFTkdUSCIsDQogICAgICAgIDB4MDAyODogIklOVkFMSURfSU1BR0VfU0lHTkFUVVJFIiwNCiAgICAgICAgMHgwMDI5OiAiUFJPUE9TRV9BTk9USEVSX1ZFUlNJT04iLA0KICAgICAgICAweDAwMkE6ICJJTlZBTElEX1BJRF9GT1JNQVQiLA0KICAgICAgICAweDAwMkI6ICJJTlZBTElEX1BQU19GT1JNQVQiLA0KICAgICAgICAweDAwMkM6ICJCSVNUX0NPTU1BTkRfQkxPQ0tFRCIsDQogICAgICAgIDB4MDAyRDogIkNPTk5FQ1RJT05fRkFJTEVEIiwNCiAgICAgICAgMHgwMDJFOiAiQ09OTkVDVElPTl9UT09fTUFOWSIsDQogICAgICAgIDB4MDAyRjogIlJOR19HRU5FUkFUSU9OX0lOX1BST0dSRVNTIiwNCiAgICAgICAgMHgwMDMwOiAiUk5HX05PVF9SRUFEWSIsDQogICAgICAgIDB4MDAzMTogIkNFUlRJRklDQVRFX05PVF9SRUFEWSIsDQogICAgICAgIDB4MDQwMDogIkRJU0FCTEVEX0JZX1BPTElDWSIsDQogICAgICAgIDB4MDgwMDogIk5FVFdPUktfSUZfRVJST1JfQkFTRSIsDQogICAgICAgIDB4MDgwMTogIlVOU1VQUE9SVEVEX09FTV9OVU1CRVIiLA0KICAgICAgICAweDA4MDI6ICJVTlNVUFBPUlRFRF9CT09UX09QVElPTiIsDQogICAgICAgIDB4MDgwMzogIklOVkFMSURfQ09NTUFORCIsDQogICAgICAgIDB4MDgwNDogIklOVkFMSURfU1BFQ0lBTF9DT01NQU5EIiwNCiAgICAgICAgMHgwODA1OiAiSU5WQUxJRF9IQU5ETEUiLA0KICAgICAgICAweDA4MDY6ICJJTlZBTElEX1BBU1NXT1JEIiwNCiAgICAgICAgMHgwODA3OiAiSU5WQUxJRF9SRUFMTSIsDQogICAgICAgIDB4MDgwODogIlNUT1JBR0VfQUNMX0VOVFJZX0lOX1VTRSIsDQogICAgICAgIDB4MDgwOTogIkRBVEFfTUlTU0lORyIsDQogICAgICAgIDB4MDgwQTogIkRVUExJQ0FURSIsDQogICAgICAgIDB4MDgwQjogIkVWRU5UTE9HX0ZST1pFTiIsDQogICAgICAgIDB4MDgwQzogIlBLSV9NSVNTSU5HX0tFWVMiLA0KICAgICAgICAweDA4MEQ6ICJQS0lfR0VORVJBVElOR19LRVlTIiwNCiAgICAgICAgMHgwODBFOiAiSU5WQUxJRF9LRVkiLA0KICAgICAgICAweDA4MEY6ICJJTlZBTElEX0NFUlQiLA0KICAgICAgICAweDA4MTA6ICJDRVJUX0tFWV9OT1RfTUFUQ0giLA0KICAgICAgICAweDA4MTE6ICJNQVhfS0VSQl9ET01BSU5fUkVBQ0hFRCIsDQogICAgICAgIDB4MDgxMjogIlVOU1VQUE9SVEVEIiwNCiAgICAgICAgMHgwODEzOiAiSU5WQUxJRF9QUklPUklUWSIsDQogICAgICAgIDB4MDgxNDogIk5PVF9GT1VORCIsDQogICAgICAgIDB4MDgxNTogIklOVkFMSURfQ1JFREVOVElBTFMiLA0KICAgICAgICAweDA4MTY6ICJJTlZBTElEX1BBU1NQSFJBU0UiLA0KICAgICAgICAweDA4MTg6ICJOT19BU1NPQ0lBVElPTiIsDQogICAgICAgIDB4MDgxQjogIkFVRElUX0ZBSUwiLA0KICAgICAgICAweDA4MUM6ICJCTE9DS0lOR19DT01QT05FTlQiLA0KICAgICAgICAweDA4MjE6ICJVU0VSX0NPTlNFTlRfUkVRVUlSRUQiLA0KICAgICAgICAweDEwMDA6ICJBUFBfSU5URVJOQUxfRVJST1IiLA0KICAgICAgICAweDEwMDE6ICJOT1RfSU5JVElBTElaRUQiLA0KICAgICAgICAweDEwMDI6ICJMSUJfVkVSU0lPTl9VTlNVUFBPUlRFRCIsDQogICAgICAgIDB4MTAwMzogIklOVkFMSURfUEFSQU0iLA0KICAgICAgICAweDEwMDQ6ICJSRVNPVVJDRVMiLA0KICAgICAgICAweDEwMDU6ICJIQVJEV0FSRV9BQ0NFU1NfRVJST1IiLA0KICAgICAgICAweDEwMDY6ICJSRVFVRVNUT1JfTk9UX1JFR0lTVEVSRUQiLA0KICAgICAgICAweDEwMDc6ICJORVRXT1JLX0VSUk9SIiwNCiAgICAgICAgMHgxMDA4OiAiUEFSQU1fQlVGRkVSX1RPT19TSE9SVCIsDQogICAgICAgIDB4MTAwOTogIkNPTV9OT1RfSU5JVElBTElaRURfSU5fVEhSRUFEIiwNCiAgICAgICAgMHgxMDBBOiAiVVJMX1JFUVVJUkVEIg0KICAgIH0NCg0KICAgIC8vDQogICAgLy8gTWV0aG9kcyB1c2VkIGZvciBnZXR0aW5nIHRoZSBldmVudCBsb2cNCiAgICAvLw0KDQogICAgb2JqLkdldE1lc3NhZ2VMb2cgPSBmdW5jdGlvbiAoZnVuYywgdGFnKSB7DQogICAgICAgIG9iai5BTVRfTWVzc2FnZUxvZ19Qb3NpdGlvblRvRmlyc3RSZWNvcmQoX0dldE1lc3NhZ2VMb2cwLCBbZnVuYywgdGFnLCBbXV0pOw0KICAgIH0NCiAgICBmdW5jdGlvbiBfR2V0TWVzc2FnZUxvZzAoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzLCB0YWcpIHsNCiAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDAgfHwgcmVzcG9uc2VzLkJvZHlbIlJldHVyblZhbHVlIl0gIT0gJzAnKSB7IHRhZ1swXShvYmosIG51bGwsIHRhZ1syXSk7IHJldHVybjsgfQ0KICAgICAgICBvYmouQU1UX01lc3NhZ2VMb2dfR2V0UmVjb3JkcyhyZXNwb25zZXMuQm9keVsiSXRlcmF0aW9uSWRlbnRpZmllciJdLCAzOTAsIF9HZXRNZXNzYWdlTG9nMSwgdGFnKTsNCiAgICB9DQogICAgZnVuY3Rpb24gX0dldE1lc3NhZ2VMb2cxKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cywgdGFnKSB7DQogICAgICAgIGlmIChzdGF0dXMgIT0gMjAwIHx8IHJlc3BvbnNlcy5Cb2R5WyJSZXR1cm5WYWx1ZSJdICE9ICcwJykgeyB0YWdbMF0ob2JqLCBudWxsLCB0YWdbMl0pOyByZXR1cm47IH0NCiAgICAgICAgdmFyIGksIGosIHgsIGUsIEFtdE1lc3NhZ2VzID0gdGFnWzJdLCB0ID0gbmV3IERhdGUoKSwgVGltZVN0YW1wLCByYSA9IHJlc3BvbnNlcy5Cb2R5WyJSZWNvcmRBcnJheSJdOw0KICAgICAgICBpZiAodHlwZW9mIHJhID09PSAnc3RyaW5nJykgeyByZXNwb25zZXMuQm9keVsiUmVjb3JkQXJyYXkiXSA9IFtyZXNwb25zZXMuQm9keVsiUmVjb3JkQXJyYXkiXV07IH0NCg0KICAgICAgICBmb3IgKGkgaW4gcmEpIHsNCiAgICAgICAgICAgIGUgPSBudWxsOw0KICAgICAgICAgICAgdHJ5IHsNCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAvLyBOb2RlSlMgZGV0ZWN0aW9uDQogICAgICAgICAgICAgICAgdmFyIGlzTm9kZSA9IG5ldyBGdW5jdGlvbigidHJ5IHtyZXR1cm4gdGhpcz09PWdsb2JhbDt9Y2F0Y2goZSl7cmV0dXJuIGZhbHNlO30iKTsNCiAgICAgICAgICAgICAgICBpZiAoaXNOb2RlKCkpIHsgZSA9IHJlcXVpcmUoJ2F0b2InKShyYVtpXSk7IH0gZWxzZSB7IGUgPSB3aW5kb3cuYXRvYihyYVtpXSk7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXgpIHsgfQ0KICAgICAgICAgICAgaWYgKGUgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgIFRpbWVTdGFtcCA9IFJlYWRJbnRYKGUsIDApOw0KICAgICAgICAgICAgICAgIGlmICgoVGltZVN0YW1wID4gMCkgJiYgKFRpbWVTdGFtcCA8IDB4RkZGRkZGRkYpKSB7DQogICAgICAgICAgICAgICAgICAgIHggPSB7ICdEZXZpY2VBZGRyZXNzJzogZS5jaGFyQ29kZUF0KDQpLCAnRXZlbnRTZW5zb3JUeXBlJzogZS5jaGFyQ29kZUF0KDUpLCAnRXZlbnRUeXBlJzogZS5jaGFyQ29kZUF0KDYpLCAnRXZlbnRPZmZzZXQnOiBlLmNoYXJDb2RlQXQoNyksICdFdmVudFNvdXJjZVR5cGUnOiBlLmNoYXJDb2RlQXQoOCksICdFdmVudFNldmVyaXR5JzogZS5jaGFyQ29kZUF0KDkpLCAnU2Vuc29yTnVtYmVyJzogZS5jaGFyQ29kZUF0KDEwKSwgJ0VudGl0eSc6IGUuY2hhckNvZGVBdCgxMSksICdFbnRpdHlJbnN0YW5jZSc6IGUuY2hhckNvZGVBdCgxMiksICdFdmVudERhdGEnOiBbXSwgJ1RpbWUnOiBuZXcgRGF0ZSgoVGltZVN0YW1wICsgKHQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwKSkgKiAxMDAwKSB9Ow0KICAgICAgICAgICAgICAgICAgICBmb3IgKGogPSAxMzsgaiA8IDIxOyBqKyspIHsgeFsnRXZlbnREYXRhJ10ucHVzaChlLmNoYXJDb2RlQXQoaikpOyB9DQogICAgICAgICAgICAgICAgICAgIHhbJ0VudGl0eVN0ciddID0gX1N5c3RlbUVudGl0eVR5cGVzW3hbJ0VudGl0eSddXTsNCiAgICAgICAgICAgICAgICAgICAgeFsnRGVzYyddID0gX0dldEV2ZW50RGV0YWlsU3RyKHhbJ0V2ZW50U2Vuc29yVHlwZSddLCB4WydFdmVudE9mZnNldCddLCB4WydFdmVudERhdGEnXSwgeFsnRW50aXR5J10pOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIXhbJ0VudGl0eVN0ciddKSB4WydFbnRpdHlTdHInXSA9ICJVbmtub3duIjsNCiAgICAgICAgICAgICAgICAgICAgQW10TWVzc2FnZXMucHVzaCh4KTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBpZiAocmVzcG9uc2VzLkJvZHlbIk5vTW9yZVJlY29yZHMiXSAhPSB0cnVlKSB7IG9iai5BTVRfTWVzc2FnZUxvZ19HZXRSZWNvcmRzKHJlc3BvbnNlcy5Cb2R5WyJJdGVyYXRpb25JZGVudGlmaWVyIl0sIDM5MCwgX0dldE1lc3NhZ2VMb2cxLCBbdGFnWzBdLCBBbXRNZXNzYWdlcywgdGFnWzJdXSk7IH0gZWxzZSB7IHRhZ1swXShvYmosIEFtdE1lc3NhZ2VzLCB0YWdbMl0pOyB9DQogICAgfQ0KDQogICAgdmFyIF9FdmVudFRyYXBTb3VyY2VUeXBlcyA9ICJQbGF0Zm9ybSBmaXJtd2FyZSAoZS5nLiBCSU9TKXxTTUkgaGFuZGxlcnxJU1Ygc3lzdGVtIG1hbmFnZW1lbnQgc29mdHdhcmV8QWxlcnQgQVNJQ3xJUE1JfEJJT1MgdmVuZG9yfFN5c3RlbSBib2FyZCBzZXQgdmVuZG9yfFN5c3RlbSBpbnRlZ3JhdG9yfFRoaXJkIHBhcnR5IGFkZC1pbnxPU1Z8TklDfFN5c3RlbSBtYW5hZ2VtZW50IGNhcmQiLnNwbGl0KCd8Jyk7DQogICAgdmFyIF9TeXN0ZW1GaXJtd2FyZUVycm9yID0gIlVuc3BlY2lmaWVkLnxObyBzeXN0ZW0gbWVtb3J5IGlzIHBoeXNpY2FsbHkgaW5zdGFsbGVkIGluIHRoZSBzeXN0ZW0ufE5vIHVzYWJsZSBzeXN0ZW0gbWVtb3J5LCBhbGwgaW5zdGFsbGVkIG1lbW9yeSBoYXMgZXhwZXJpZW5jZWQgYW4gdW5yZWNvdmVyYWJsZSBmYWlsdXJlLnxVbnJlY292ZXJhYmxlIGhhcmQtZGlzay9BVEFQSS9JREUgZGV2aWNlIGZhaWx1cmUufFVucmVjb3ZlcmFibGUgc3lzdGVtLWJvYXJkIGZhaWx1cmUufFVucmVjb3ZlcmFibGUgZGlza2V0dGUgc3Vic3lzdGVtIGZhaWx1cmUufFVucmVjb3ZlcmFibGUgaGFyZC1kaXNrIGNvbnRyb2xsZXIgZmFpbHVyZS58VW5yZWNvdmVyYWJsZSBQUy8yIG9yIFVTQiBrZXlib2FyZCBmYWlsdXJlLnxSZW1vdmFibGUgYm9vdCBtZWRpYSBub3QgZm91bmQufFVucmVjb3ZlcmFibGUgdmlkZW8gY29udHJvbGxlciBmYWlsdXJlLnxObyB2aWRlbyBkZXZpY2UgZGV0ZWN0ZWQufEZpcm13YXJlIChCSU9TKSBST00gY29ycnVwdGlvbiBkZXRlY3RlZC58Q1BVIHZvbHRhZ2UgbWlzbWF0Y2ggKHByb2Nlc3NvcnMgdGhhdCBzaGFyZSBzYW1lIHN1cHBseSBoYXZlIG1pc21hdGNoZWQgdm9sdGFnZSByZXF1aXJlbWVudHMpfENQVSBzcGVlZCBtYXRjaGluZyBmYWlsdXJlIi5zcGxpdCgnfCcpOw0KICAgIHZhciBfU3lzdGVtRmlybXdhcmVQcm9ncmVzcyA9ICJVbnNwZWNpZmllZC58TWVtb3J5IGluaXRpYWxpemF0aW9uLnxTdGFydGluZyBoYXJkLWRpc2sgaW5pdGlhbGl6YXRpb24gYW5kIHRlc3R8U2Vjb25kYXJ5IHByb2Nlc3NvcihzKSBpbml0aWFsaXphdGlvbnxVc2VyIGF1dGhlbnRpY2F0aW9ufFVzZXItaW5pdGlhdGVkIHN5c3RlbSBzZXR1cHxVU0IgcmVzb3VyY2UgY29uZmlndXJhdGlvbnxQQ0kgcmVzb3VyY2UgY29uZmlndXJhdGlvbnxPcHRpb24gUk9NIGluaXRpYWxpemF0aW9ufFZpZGVvIGluaXRpYWxpemF0aW9ufENhY2hlIGluaXRpYWxpemF0aW9ufFNNIEJ1cyBpbml0aWFsaXphdGlvbnxLZXlib2FyZCBjb250cm9sbGVyIGluaXRpYWxpemF0aW9ufEVtYmVkZGVkIGNvbnRyb2xsZXIvbWFuYWdlbWVudCBjb250cm9sbGVyIGluaXRpYWxpemF0aW9ufERvY2tpbmcgc3RhdGlvbiBhdHRhY2htZW50fEVuYWJsaW5nIGRvY2tpbmcgc3RhdGlvbnxEb2NraW5nIHN0YXRpb24gZWplY3Rpb258RGlzYWJsaW5nIGRvY2tpbmcgc3RhdGlvbnxDYWxsaW5nIG9wZXJhdGluZyBzeXN0ZW0gd2FrZS11cCB2ZWN0b3J8U3RhcnRpbmcgb3BlcmF0aW5nIHN5c3RlbSBib290IHByb2Nlc3N8QmFzZWJvYXJkIG9yIG1vdGhlcmJvYXJkIGluaXRpYWxpemF0aW9ufHJlc2VydmVkfEZsb3BweSBpbml0aWFsaXphdGlvbnxLZXlib2FyZCB0ZXN0fFBvaW50aW5nIGRldmljZSB0ZXN0fFByaW1hcnkgcHJvY2Vzc29yIGluaXRpYWxpemF0aW9uIi5zcGxpdCgnfCcpOw0KICAgIHZhciBfU3lzdGVtRW50aXR5VHlwZXMgPSAiVW5zcGVjaWZpZWR8T3RoZXJ8VW5rbm93bnxQcm9jZXNzb3J8RGlza3xQZXJpcGhlcmFsfFN5c3RlbSBtYW5hZ2VtZW50IG1vZHVsZXxTeXN0ZW0gYm9hcmR8TWVtb3J5IG1vZHVsZXxQcm9jZXNzb3IgbW9kdWxlfFBvd2VyIHN1cHBseXxBZGQgaW4gY2FyZHxGcm9udCBwYW5lbCBib2FyZHxCYWNrIHBhbmVsIGJvYXJkfFBvd2VyIHN5c3RlbSBib2FyZHxEcml2ZSBiYWNrcGxhbmV8U3lzdGVtIGludGVybmFsIGV4cGFuc2lvbiBib2FyZHxPdGhlciBzeXN0ZW0gYm9hcmR8UHJvY2Vzc29yIGJvYXJkfFBvd2VyIHVuaXR8UG93ZXIgbW9kdWxlfFBvd2VyIG1hbmFnZW1lbnQgYm9hcmR8Q2hhc3NpcyBiYWNrIHBhbmVsIGJvYXJkfFN5c3RlbSBjaGFzc2lzfFN1YiBjaGFzc2lzfE90aGVyIGNoYXNzaXMgYm9hcmR8RGlzayBkcml2ZSBiYXl8UGVyaXBoZXJhbCBiYXl8RGV2aWNlIGJheXxGYW4gY29vbGluZ3xDb29saW5nIHVuaXR8Q2FibGUgaW50ZXJjb25uZWN0fE1lbW9yeSBkZXZpY2V8U3lzdGVtIG1hbmFnZW1lbnQgc29mdHdhcmV8QklPU3xJbnRlbChyKSBNRXxTeXN0ZW0gYnVzfEdyb3VwfEludGVsKHIpIE1FfEV4dGVybmFsIGVudmlyb25tZW50fEJhdHRlcnl8UHJvY2Vzc2luZyBibGFkZXxDb25uZWN0aXZpdHkgc3dpdGNofFByb2Nlc3Nvci9tZW1vcnkgbW9kdWxlfEkvTyBtb2R1bGV8UHJvY2Vzc29yIEkvTyBtb2R1bGV8TWFuYWdlbWVudCBjb250cm9sbGVyIGZpcm13YXJlfElQTUkgY2hhbm5lbHxQQ0kgYnVzfFBDSSBleHByZXNzIGJ1c3xTQ1NJIGJ1c3xTQVRBL1NBUyBidXN8UHJvY2Vzc29yIGZyb250IHNpZGUgYnVzIi5zcGxpdCgnfCcpOw0KICAgIG9iai5SZWFsbU5hbWVzID0gInx8UmVkaXJlY3Rpb258fEhhcmR3YXJlIEFzc2V0fFJlbW90ZSBDb250cm9sfFN0b3JhZ2V8RXZlbnQgTWFuYWdlcnxTdG9yYWdlIEFkbWlufEFnZW50IFByZXNlbmNlIExvY2FsfEFnZW50IFByZXNlbmNlIFJlbW90ZXxDaXJjdWl0IEJyZWFrZXJ8TmV0d29yayBUaW1lfEdlbmVyYWwgSW5mb3JtYXRpb258RmlybXdhcmUgVXBkYXRlfEVJVHxMb2NhbFVOfEVuZHBvaW50IEFjY2VzcyBDb250cm9sfEVuZHBvaW50IEFjY2VzcyBDb250cm9sIEFkbWlufEV2ZW50IExvZyBSZWFkZXJ8QXVkaXQgTG9nfEFDTCBSZWFsbXx8fExvY2FsIFN5c3RlbSIuc3BsaXQoJ3wnKTsNCiAgICBvYmouV2F0Y2hkb2dDdXJyZW50U3RhdGVzID0geyAxOiAnTm90IFN0YXJ0ZWQnLCAyOiAnU3RvcHBlZCcsIDQ6ICdSdW5uaW5nJywgODogJ0V4cGlyZWQnLCAxNjogJ1N1c3BlbmRlZCcgfTsNCg0KICAgIGZ1bmN0aW9uIF9HZXRFdmVudERldGFpbFN0cihldmVudFNlbnNvclR5cGUsIGV2ZW50T2Zmc2V0LCBldmVudERhdGFGaWVsZCwgZW50aXR5KSB7DQoNCiAgICAgICAgaWYgKGV2ZW50U2Vuc29yVHlwZSA9PSAxNSkgew0KICAgICAgICAgICAgaWYgKGV2ZW50RGF0YUZpZWxkWzBdID09IDIzNSkgcmV0dXJuICJJbnZhbGlkIERhdGEiOw0KICAgICAgICAgICAgaWYgKGV2ZW50T2Zmc2V0ID09IDApIHJldHVybiBfU3lzdGVtRmlybXdhcmVFcnJvcltldmVudERhdGFGaWVsZFsxXV07DQogICAgICAgICAgICByZXR1cm4gX1N5c3RlbUZpcm13YXJlUHJvZ3Jlc3NbZXZlbnREYXRhRmllbGRbMV1dOw0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKChldmVudFNlbnNvclR5cGUgPT0gMTgpICYmIChldmVudERhdGFGaWVsZFswXSA9PSAxNzApKSB7IC8vIFN5c3RlbSB3YXRjaGRvZyBldmVudA0KICAgICAgICAgICAgcmV0dXJuICJBZ2VudCB3YXRjaGRvZyAiICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbNF0pICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbM10pICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbMl0pICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbMV0pICsgIi0iICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbNl0pICsgY2hhcjJoZXgoZXZlbnREYXRhRmllbGRbNV0pICsgIi0uLi4gY2hhbmdlZCB0byAiICsgb2JqLldhdGNoZG9nQ3VycmVudFN0YXRlc1tldmVudERhdGFGaWVsZFs3XV07DQogICAgICAgIH0NCg0KICAgICAgICBpZiAoKGV2ZW50U2Vuc29yVHlwZSA9PSA1KSAmJiAoZXZlbnRPZmZzZXQgPT0gMCkpIHsgLy8gU3lzdGVtIGNoYXNzaXMNCiAgICAgICAgICAgIHJldHVybiAiQ2FzZSBpbnRydXNpb24iOw0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKChldmVudFNlbnNvclR5cGUgPT0gMTkyKSAmJiAoZXZlbnRPZmZzZXQgPT0gMCkgJiYgKGV2ZW50RGF0YUZpZWxkWzBdID09IDE3MCkgJiYgKGV2ZW50RGF0YUZpZWxkWzFdID09IDQ4KSkNCiAgICAgICAgew0KICAgICAgICAgICAgaWYgKGV2ZW50RGF0YUZpZWxkWzJdID09IDApIHJldHVybiAiQSByZW1vdGUgU2VyaWFsIE92ZXIgTEFOIHNlc3Npb24gd2FzIGVzdGFibGlzaGVkLiI7DQogICAgICAgICAgICBpZiAoZXZlbnREYXRhRmllbGRbMl0gPT0gMSkgcmV0dXJuICJSZW1vdGUgU2VyaWFsIE92ZXIgTEFOIHNlc3Npb24gZmluaXNoZWQuIFVzZXIgY29udHJvbCB3YXMgcmVzdG9yZWQuIjsNCiAgICAgICAgICAgIGlmIChldmVudERhdGFGaWVsZFsyXSA9PSAyKSByZXR1cm4gIkEgcmVtb3RlIElERS1SZWRpcmVjdGlvbiBzZXNzaW9uIHdhcyBlc3RhYmxpc2hlZC4iOw0KICAgICAgICAgICAgaWYgKGV2ZW50RGF0YUZpZWxkWzJdID09IDMpIHJldHVybiAiUmVtb3RlIElERS1SZWRpcmVjdGlvbiBzZXNzaW9uIGZpbmlzaGVkLiBVc2VyIGNvbnRyb2wgd2FzIHJlc3RvcmVkLiI7DQogICAgICAgIH0NCg0KICAgICAgICBpZiAoZXZlbnRTZW5zb3JUeXBlID09IDM2KSB7DQogICAgICAgICAgICB2YXIgaGFuZGxlID0gKGV2ZW50RGF0YUZpZWxkWzFdIDw8IDI0KSArIChldmVudERhdGFGaWVsZFsyXSA8PCAxNikgKyAoZXZlbnREYXRhRmllbGRbM10gPDwgOCkgKyBldmVudERhdGFGaWVsZFs0XTsNCiAgICAgICAgICAgIHZhciBuaWMgPSAiIyIgKyBldmVudERhdGFGaWVsZFswXTsNCiAgICAgICAgICAgIGlmIChldmVudERhdGFGaWVsZFswXSA9PSAweEFBKSBuaWMgPSAid2lyZWQiOyAvLyBUT0RPOiBBZGQgd2lyZWxlc3MgKioqKioNCiAgICAgICAgICAgIC8vaWYgKGV2ZW50RGF0YUZpZWxkWzBdID09IDB4QUEpIG5pYyA9ICJ3aXJlbGVzcyI7DQoNCiAgICAgICAgICAgIGlmIChoYW5kbGUgPT0gNDI5NDk2NzI5MykgeyByZXR1cm4gIkFsbCByZWNlaXZlZCBwYWNrZXQgZmlsdGVyIHdhcyBtYXRjaGVkIG9uICIgKyBuaWMgKyAiIGludGVyZmFjZS4iOyB9DQogICAgICAgICAgICBpZiAoaGFuZGxlID09IDQyOTQ5NjcyOTIpIHsgcmV0dXJuICJBbGwgb3V0Ym91bmQgcGFja2V0IGZpbHRlciB3YXMgbWF0Y2hlZCBvbiAiICsgbmljICsgIiBpbnRlcmZhY2UuIjsgfQ0KICAgICAgICAgICAgaWYgKGhhbmRsZSA9PSA0Mjk0OTY3MjkwKSB7IHJldHVybiAiU3Bvb2ZlZCBwYWNrZXQgZmlsdGVyIHdhcyBtYXRjaGVkIG9uICIgKyBuaWMgKyAiIGludGVyZmFjZS4iOyB9DQogICAgICAgICAgICByZXR1cm4gIkZpbHRlciAiICsgaGFuZGxlICsgIiB3YXMgbWF0Y2hlZCBvbiAiICsgbmljICsgIiBpbnRlcmZhY2UuIjsNCiAgICAgICAgfQ0KDQogICAgICAgIGlmIChldmVudFNlbnNvclR5cGUgPT0gMTkyKSB7DQogICAgICAgICAgICBpZiAoZXZlbnREYXRhRmllbGRbMl0gPT0gMCkgcmV0dXJuICJTZWN1cml0eSBwb2xpY3kgaW52b2tlZC4gU29tZSBvciBhbGwgbmV0d29yayB0cmFmZmljIChUWCkgd2FzIHN0b3BwZWQuIjsNCiAgICAgICAgICAgIGlmIChldmVudERhdGFGaWVsZFsyXSA9PSAyKSByZXR1cm4gIlNlY3VyaXR5IHBvbGljeSBpbnZva2VkLiBTb21lIG9yIGFsbCBuZXR3b3JrIHRyYWZmaWMgKFJYKSB3YXMgc3RvcHBlZC4iOw0KICAgICAgICAgICAgcmV0dXJuICJTZWN1cml0eSBwb2xpY3kgaW52b2tlZC4iOw0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKGV2ZW50U2Vuc29yVHlwZSA9PSAxOTMpIHsNCiAgICAgICAgICAgIGlmICgoZXZlbnREYXRhRmllbGRbMF0gPT0gMHhBQSkgJiYgKGV2ZW50RGF0YUZpZWxkWzFdID09IDB4MzApICYmIChldmVudERhdGFGaWVsZFsyXSA9PSAweDAwKSAmJiAoZXZlbnREYXRhRmllbGRbM10gPT0gMHgwMCkpIHsgcmV0dXJuICJVc2VyIHJlcXVlc3QgZm9yIHJlbW90ZSBjb25uZWN0aW9uLiI7IH0NCiAgICAgICAgICAgIGlmICgoZXZlbnREYXRhRmllbGRbMF0gPT0gMHhBQSkgJiYgKGV2ZW50RGF0YUZpZWxkWzFdID09IDB4MjApICYmIChldmVudERhdGFGaWVsZFsyXSA9PSAweDAzKSAmJiAoZXZlbnREYXRhRmllbGRbM10gPT0gMHgwMSkpIHsgcmV0dXJuICJFQUMgZXJyb3I6IGF0dGVtcHQgdG8gZ2V0IHBvc3R1cmUgd2hpbGUgTkFDIGluIEludGVs77+9IEFNVCBpcyBkaXNhYmxlZC4iOyB9IC8vIGV2ZW50RGF0YUZpZWxkID0gMHhBQTIwMDMwMTAwMDAwMDAwDQogICAgICAgICAgICBpZiAoKGV2ZW50RGF0YUZpZWxkWzBdID09IDB4QUEpICYmIChldmVudERhdGFGaWVsZFsxXSA9PSAweDIwKSAmJiAoZXZlbnREYXRhRmllbGRbMl0gPT0gMHgwNCkgJiYgKGV2ZW50RGF0YUZpZWxkWzNdID09IDB4MDApKSB7IHJldHVybiAiQ2VydGlmaWNhdGUgcmV2b2tlZC4gIjsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKGV2ZW50U2Vuc29yVHlwZSA9PSA2KSByZXR1cm4gIkF1dGhlbnRpY2F0aW9uIGZhaWxlZCAiICsgKGV2ZW50RGF0YUZpZWxkWzFdICsgKGV2ZW50RGF0YUZpZWxkWzJdIDw8IDgpKSArICIgdGltZXMuIFRoZSBzeXN0ZW0gbWF5IGJlIHVuZGVyIGF0dGFjay4iOw0KICAgICAgICBpZiAoZXZlbnRTZW5zb3JUeXBlID09IDMwKSByZXR1cm4gIk5vIGJvb3RhYmxlIG1lZGlhIjsNCiAgICAgICAgaWYgKGV2ZW50U2Vuc29yVHlwZSA9PSAzMikgcmV0dXJuICJPcGVyYXRpbmcgc3lzdGVtIGxvY2t1cCBvciBwb3dlciBpbnRlcnJ1cHQiOw0KICAgICAgICBpZiAoZXZlbnRTZW5zb3JUeXBlID09IDM1KSByZXR1cm4gIlN5c3RlbSBib290IGZhaWx1cmUiOw0KICAgICAgICBpZiAoZXZlbnRTZW5zb3JUeXBlID09IDM3KSByZXR1cm4gIlN5c3RlbSBmaXJtd2FyZSBzdGFydGVkIChhdCBsZWFzdCBvbmUgQ1BVIGlzIHByb3Blcmx5IGV4ZWN1dGluZykuIjsNCiAgICAgICAgcmV0dXJuICJVbmtub3duIFNlbnNvciBUeXBlICMiICsgZXZlbnRTZW5zb3JUeXBlOw0KICAgIH0NCg0KDQoNCiAgICAvLyBVc2VmdWwgbGluazogaHR0cHM6Ly9zb2Z0d2FyZS5pbnRlbC5jb20vc2l0ZXMvbWFuYWdlYWJpbGl0eS9BTVRfSW1wbGVtZW50YXRpb25fYW5kX1JlZmVyZW5jZV9HdWlkZS9kZWZhdWx0Lmh0bT90dXJsPVdvcmREb2N1bWVudHMlMkZzZWN1cml0eWFkbWluZXZlbnRzLmh0bQ0KDQogICAgdmFyIF9BbXRBdWRpdFN0cmluZ1RhYmxlID0NCiAgICB7DQogICAgICAgIDE2OiAnU2VjdXJpdHkgQWRtaW4nLA0KICAgICAgICAxNzogJ1JDTycsDQogICAgICAgIDE4OiAnUmVkaXJlY3Rpb24gTWFuYWdlcicsDQogICAgICAgIDE5OiAnRmlybXdhcmUgVXBkYXRlIE1hbmFnZXInLA0KICAgICAgICAyMDogJ1NlY3VyaXR5IEF1ZGl0IExvZycsDQogICAgICAgIDIxOiAnTmV0d29yayBUaW1lJywNCiAgICAgICAgMjI6ICdOZXR3b3JrIEFkbWluaXN0cmF0aW9uJywNCiAgICAgICAgMjM6ICdTdG9yYWdlIEFkbWluaXN0cmF0aW9uJywNCiAgICAgICAgMjQ6ICdFdmVudCBNYW5hZ2VyJywNCiAgICAgICAgMjU6ICdDaXJjdWl0IEJyZWFrZXIgTWFuYWdlcicsDQogICAgICAgIDI2OiAnQWdlbnQgUHJlc2VuY2UgTWFuYWdlcicsDQogICAgICAgIDI3OiAnV2lyZWxlc3MgQ29uZmlndXJhdGlvbicsDQogICAgICAgIDI4OiAnRUFDJywNCiAgICAgICAgMjk6ICdLVk0nLA0KICAgICAgICAzMDogJ1VzZXIgT3B0LUluIEV2ZW50cycsDQogICAgICAgIDMyOiAnU2NyZWVuIEJsYW5raW5nJywNCiAgICAgICAgMzM6ICdXYXRjaGRvZyBFdmVudHMnLA0KICAgICAgICAxNjAwOiAnUHJvdmlzaW9uaW5nIFN0YXJ0ZWQnLA0KICAgICAgICAxNjAxOiAnUHJvdmlzaW9uaW5nIENvbXBsZXRlZCcsDQogICAgICAgIDE2MDI6ICdBQ0wgRW50cnkgQWRkZWQnLA0KICAgICAgICAxNjAzOiAnQUNMIEVudHJ5IE1vZGlmaWVkJywNCiAgICAgICAgMTYwNDogJ0FDTCBFbnRyeSBSZW1vdmVkJywNCiAgICAgICAgMTYwNTogJ0FDTCBBY2Nlc3Mgd2l0aCBJbnZhbGlkIENyZWRlbnRpYWxzJywNCiAgICAgICAgMTYwNjogJ0FDTCBFbnRyeSBTdGF0ZScsDQogICAgICAgIDE2MDc6ICdUTFMgU3RhdGUgQ2hhbmdlZCcsDQogICAgICAgIDE2MDg6ICdUTFMgU2VydmVyIENlcnRpZmljYXRlIFNldCcsDQogICAgICAgIDE2MDk6ICdUTFMgU2VydmVyIENlcnRpZmljYXRlIFJlbW92ZScsDQogICAgICAgIDE2MTA6ICdUTFMgVHJ1c3RlZCBSb290IENlcnRpZmljYXRlIEFkZGVkJywNCiAgICAgICAgMTYxMTogJ1RMUyBUcnVzdGVkIFJvb3QgQ2VydGlmaWNhdGUgUmVtb3ZlZCcsDQogICAgICAgIDE2MTI6ICdUTFMgUHJlc2hhcmVkIEtleSBTZXQnLA0KICAgICAgICAxNjEzOiAnS2VyYmVyb3MgU2V0dGluZ3MgTW9kaWZpZWQnLA0KICAgICAgICAxNjE0OiAnS2VyYmVyb3MgTWFzdGVyIEtleSBNb2RpZmllZCcsDQogICAgICAgIDE2MTU6ICdGbGFzaCBXZWFyIG91dCBDb3VudGVycyBSZXNldCcsDQogICAgICAgIDE2MTY6ICdQb3dlciBQYWNrYWdlIE1vZGlmaWVkJywNCiAgICAgICAgMTYxNzogJ1NldCBSZWFsbSBBdXRoZW50aWNhdGlvbiBNb2RlJywNCiAgICAgICAgMTYxODogJ1VwZ3JhZGUgQ2xpZW50IHRvIEFkbWluIENvbnRyb2wgTW9kZScsDQogICAgICAgIDE2MTk6ICdVbnByb3Zpc2lvbmluZyBTdGFydGVkJywNCiAgICAgICAgMTcwMDogJ1BlcmZvcm1lZCBQb3dlciBVcCcsDQogICAgICAgIDE3MDE6ICdQZXJmb3JtZWQgUG93ZXIgRG93bicsDQogICAgICAgIDE3MDI6ICdQZXJmb3JtZWQgUG93ZXIgQ3ljbGUnLA0KICAgICAgICAxNzAzOiAnUGVyZm9ybWVkIFJlc2V0JywNCiAgICAgICAgMTcwNDogJ1NldCBCb290IE9wdGlvbnMnLA0KICAgICAgICAxODAwOiAnSURFUiBTZXNzaW9uIE9wZW5lZCcsDQogICAgICAgIDE4MDE6ICdJREVSIFNlc3Npb24gQ2xvc2VkJywNCiAgICAgICAgMTgwMjogJ0lERVIgRW5hYmxlZCcsDQogICAgICAgIDE4MDM6ICdJREVSIERpc2FibGVkJywNCiAgICAgICAgMTgwNDogJ1NvTCBTZXNzaW9uIE9wZW5lZCcsDQogICAgICAgIDE4MDU6ICdTb0wgU2Vzc2lvbiBDbG9zZWQnLA0KICAgICAgICAxODA2OiAnU29MIEVuYWJsZWQnLA0KICAgICAgICAxODA3OiAnU29MIERpc2FibGVkJywNCiAgICAgICAgMTgwODogJ0tWTSBTZXNzaW9uIFN0YXJ0ZWQnLA0KICAgICAgICAxODA5OiAnS1ZNIFNlc3Npb24gRW5kZWQnLA0KICAgICAgICAxODEwOiAnS1ZNIEVuYWJsZWQnLA0KICAgICAgICAxODExOiAnS1ZNIERpc2FibGVkJywNCiAgICAgICAgMTgxMjogJ1ZOQyBQYXNzd29yZCBGYWlsZWQgMyBUaW1lcycsDQogICAgICAgIDE5MDA6ICdGaXJtd2FyZSBVcGRhdGVkJywNCiAgICAgICAgMTkwMTogJ0Zpcm13YXJlIFVwZGF0ZSBGYWlsZWQnLA0KICAgICAgICAyMDAwOiAnU2VjdXJpdHkgQXVkaXQgTG9nIENsZWFyZWQnLA0KICAgICAgICAyMDAxOiAnU2VjdXJpdHkgQXVkaXQgUG9saWN5IE1vZGlmaWVkJywNCiAgICAgICAgMjAwMjogJ1NlY3VyaXR5IEF1ZGl0IExvZyBEaXNhYmxlZCcsDQogICAgICAgIDIwMDM6ICdTZWN1cml0eSBBdWRpdCBMb2cgRW5hYmxlZCcsDQogICAgICAgIDIwMDQ6ICdTZWN1cml0eSBBdWRpdCBMb2cgRXhwb3J0ZWQnLA0KICAgICAgICAyMDA1OiAnU2VjdXJpdHkgQXVkaXQgTG9nIFJlY292ZXJlZCcsDQogICAgICAgIDIxMDA6ICdJbnRlbCZyZWc7IE1FIFRpbWUgU2V0JywNCiAgICAgICAgMjIwMDogJ1RDUElQIFBhcmFtZXRlcnMgU2V0JywNCiAgICAgICAgMjIwMTogJ0hvc3QgTmFtZSBTZXQnLA0KICAgICAgICAyMjAyOiAnRG9tYWluIE5hbWUgU2V0JywNCiAgICAgICAgMjIwMzogJ1ZMQU4gUGFyYW1ldGVycyBTZXQnLA0KICAgICAgICAyMjA0OiAnTGluayBQb2xpY3kgU2V0JywNCiAgICAgICAgMjIwNTogJ0lQdjYgUGFyYW1ldGVycyBTZXQnLA0KICAgICAgICAyMzAwOiAnR2xvYmFsIFN0b3JhZ2UgQXR0cmlidXRlcyBTZXQnLA0KICAgICAgICAyMzAxOiAnU3RvcmFnZSBFQUNMIE1vZGlmaWVkJywNCiAgICAgICAgMjMwMjogJ1N0b3JhZ2UgRlBBQ0wgTW9kaWZpZWQnLA0KICAgICAgICAyMzAzOiAnU3RvcmFnZSBXcml0ZSBPcGVyYXRpb24nLA0KICAgICAgICAyNDAwOiAnQWxlcnQgU3Vic2NyaWJlZCcsDQogICAgICAgIDI0MDE6ICdBbGVydCBVbnN1YnNjcmliZWQnLA0KICAgICAgICAyNDAyOiAnRXZlbnQgTG9nIENsZWFyZWQnLA0KICAgICAgICAyNDAzOiAnRXZlbnQgTG9nIEZyb3plbicsDQogICAgICAgIDI1MDA6ICdDQiBGaWx0ZXIgQWRkZWQnLA0KICAgICAgICAyNTAxOiAnQ0IgRmlsdGVyIFJlbW92ZWQnLA0KICAgICAgICAyNTAyOiAnQ0IgUG9saWN5IEFkZGVkJywNCiAgICAgICAgMjUwMzogJ0NCIFBvbGljeSBSZW1vdmVkJywNCiAgICAgICAgMjUwNDogJ0NCIERlZmF1bHQgUG9saWN5IFNldCcsDQogICAgICAgIDI1MDU6ICdDQiBIZXVyaXN0aWNzIE9wdGlvbiBTZXQnLA0KICAgICAgICAyNTA2OiAnQ0IgSGV1cmlzdGljcyBTdGF0ZSBDbGVhcmVkJywNCiAgICAgICAgMjYwMDogJ0FnZW50IFdhdGNoZG9nIEFkZGVkJywNCiAgICAgICAgMjYwMTogJ0FnZW50IFdhdGNoZG9nIFJlbW92ZWQnLA0KICAgICAgICAyNjAyOiAnQWdlbnQgV2F0Y2hkb2cgQWN0aW9uIFNldCcsDQogICAgICAgIDI3MDA6ICdXaXJlbGVzcyBQcm9maWxlIEFkZGVkJywNCiAgICAgICAgMjcwMTogJ1dpcmVsZXNzIFByb2ZpbGUgUmVtb3ZlZCcsDQogICAgICAgIDI3MDI6ICdXaXJlbGVzcyBQcm9maWxlIFVwZGF0ZWQnLA0KICAgICAgICAyODAwOiAnRUFDIFBvc3R1cmUgU2lnbmVyIFNFVCcsDQogICAgICAgIDI4MDE6ICdFQUMgRW5hYmxlZCcsDQogICAgICAgIDI4MDI6ICdFQUMgRGlzYWJsZWQnLA0KICAgICAgICAyODAzOiAnRUFDIFBvc3R1cmUgU3RhdGUnLA0KICAgICAgICAyODA0OiAnRUFDIFNldCBPcHRpb25zJywNCiAgICAgICAgMjkwMDogJ0tWTSBPcHQtaW4gRW5hYmxlZCcsDQogICAgICAgIDI5MDE6ICdLVk0gT3B0LWluIERpc2FibGVkJywNCiAgICAgICAgMjkwMjogJ0tWTSBQYXNzd29yZCBDaGFuZ2VkJywNCiAgICAgICAgMjkwMzogJ0tWTSBDb25zZW50IFN1Y2NlZWRlZCcsDQogICAgICAgIDI5MDQ6ICdLVk0gQ29uc2VudCBGYWlsZWQnLA0KICAgICAgICAzMDAwOiAnT3B0LUluIFBvbGljeSBDaGFuZ2UnLA0KICAgICAgICAzMDAxOiAnU2VuZCBDb25zZW50IENvZGUgRXZlbnQnLA0KICAgICAgICAzMDAyOiAnU3RhcnQgT3B0LUluIEJsb2NrZWQgRXZlbnQnDQogICAgfQ0KDQogICAgLy8gUmV0dXJuIGh1bWFuIHJlYWRhYmxlIGV4dGVuZGVkIGF1ZGl0IGxvZyBkYXRhDQogICAgLy8gVE9ETzogSnVzdCBwdXQgc29tZSBvZiB0aGVtIGhlcmUsIGJ1dCBtYW55IG1vcmUgc3RpbGwgbmVlZCB0byBiZSBhZGRlZCwgaGVscGZ1bCBsaW5rIGhlcmU6DQogICAgLy8gaHR0cHM6Ly9zb2Z0d2FyZS5pbnRlbC5jb20vc2l0ZXMvbWFuYWdlYWJpbGl0eS9BTVRfSW1wbGVtZW50YXRpb25fYW5kX1JlZmVyZW5jZV9HdWlkZS9kZWZhdWx0Lmh0bT90dXJsPVdvcmREb2N1bWVudHMlMkZzZWN1cml0eWFkbWluZXZlbnRzLmh0bQ0KICAgIG9iai5HZXRBdWRpdExvZ0V4dGVuZGVkRGF0YVN0ciA9IGZ1bmN0aW9uIChpZCwgZGF0YSkgew0KICAgICAgICBpZiAoKGlkID09IDE2MDIgfHwgaWQgPT0gMTYwNCkgJiYgZGF0YS5jaGFyQ29kZUF0KDApID09IDApIHsgcmV0dXJuIGRhdGEuc3Vic3RyaW5nKDIsIDIgKyBkYXRhLmNoYXJDb2RlQXQoMSkpOyB9IC8vIEFDTCBFbnRyeSBBZGRlZC9SZW1vdmVkIChEaWdlc3QpDQogICAgICAgIGlmIChpZCA9PSAxNjAzKSB7IGlmIChkYXRhLmNoYXJDb2RlQXQoMSkgPT0gMCkgeyByZXR1cm4gZGF0YS5zdWJzdHJpbmcoMyk7IH0gcmV0dXJuIG51bGw7IH0gLy8gQUNMIEVudHJ5IE1vZGlmaWVkDQogICAgICAgIGlmIChpZCA9PSAxNjA1KSB7IHJldHVybiBbIkludmFsaWQgTUUgYWNjZXNzIiwgIkludmFsaWQgTUVCeCBhY2Nlc3MiXVtkYXRhLmNoYXJDb2RlQXQoMCldOyB9IC8vIEFDTCBBY2Nlc3Mgd2l0aCBJbnZhbGlkIENyZWRlbnRpYWxzDQogICAgICAgIGlmIChpZCA9PSAxNjA2KSB7IHZhciByID0gWyJEaXNhYmxlZCIsICJFbmFibGVkIl1bZGF0YS5jaGFyQ29kZUF0KDApXTsgaWYgKGRhdGEuY2hhckNvZGVBdCgxKSA9PSAwKSB7IHIgKz0gIiwgIiArIGRhdGEuc3Vic3RyaW5nKDMpOyB9IHJldHVybiByO30gLy8gQUNMIEVudHJ5IFN0YXRlDQogICAgICAgIGlmIChpZCA9PSAxNjA3KSB7IHJldHVybiAiUmVtb3RlICIgKyBbIk5vQXV0aCIsICJTZXJ2ZXJBdXRoIiwgIk11dHVhbEF1dGgiXVtkYXRhLmNoYXJDb2RlQXQoMCldICsgIiwgTG9jYWwgIiArIFsiTm9BdXRoIiwgIlNlcnZlckF1dGgiLCAiTXV0dWFsQXV0aCJdW2RhdGEuY2hhckNvZGVBdCgxKV07IH0gLy8gVExTIFN0YXRlIENoYW5nZWQNCiAgICAgICAgaWYgKGlkID09IDE2MTcpIHsgcmV0dXJuIG9iai5SZWFsbU5hbWVzW1JlYWRJbnQoZGF0YSwgMCldICsgIiwgIiArIFsiTm9BdXRoIiwgIkF1dGgiLCAiRGlzYWJsZWQiXVtkYXRhLmNoYXJDb2RlQXQoNCldOyB9IC8vIFNldCBSZWFsbSBBdXRoZW50aWNhdGlvbiBNb2RlDQogICAgICAgIGlmIChpZCA9PSAxNjE5KSB7IHJldHVybiBbIkJJT1MiLCAiTUVCeCIsICJMb2NhbCBNRUkiLCAiTG9jYWwgV1NNQU4iLCAiUmVtb3RlIFdTQU1OIl1bZGF0YS5jaGFyQ29kZUF0KDApXTsgfSAvLyBJbnRlbCBBTVQgVW5wcm92aXNpb25pbmcgU3RhcnRlZA0KICAgICAgICBpZiAoaWQgPT0gMTkwMCkgeyByZXR1cm4gIkZyb20gIiArIFJlYWRTaG9ydChkYXRhLCAwKSArICIuIiArIFJlYWRTaG9ydChkYXRhLCAyKSArICIuIiArIFJlYWRTaG9ydChkYXRhLCA0KSArICIuIiArIFJlYWRTaG9ydChkYXRhLCA2KSArICIgdG8gIiArIFJlYWRTaG9ydChkYXRhLCA4KSArICIuIiArIFJlYWRTaG9ydChkYXRhLCAxMCkgKyAiLiIgKyBSZWFkU2hvcnQoZGF0YSwgMTIpICsgIi4iICsgUmVhZFNob3J0KGRhdGEsIDE0KTsgfSAvLyBGaXJtd2FyZSBVcGRhdGVkDQogICAgICAgIGlmIChpZCA9PSAyMTAwKSB7IHZhciB0NCA9IG5ldyBEYXRlKCk7IHQ0LnNldFRpbWUoUmVhZEludChkYXRhLCAwKSAqIDEwMDAgKyAobmV3IERhdGUoKS5nZXRUaW1lem9uZU9mZnNldCgpICogNjAwMDApKTsgcmV0dXJuIHQ0LnRvTG9jYWxlU3RyaW5nKCk7IH0gLy8gSW50ZWwgQU1UIFRpbWUgU2V0DQogICAgICAgIGlmIChpZCA9PSAzMDAwKSB7IHJldHVybiAiRnJvbSAiICsgWyJOb25lIiwgIktWTSIsICJBbGwiXVtkYXRhLmNoYXJDb2RlQXQoMCldICsgIiB0byAiICsgWyJOb25lIiwgIktWTSIsICJBbGwiXVtkYXRhLmNoYXJDb2RlQXQoMSldOyB9IC8vIE9wdC1JbiBQb2xpY3kgQ2hhbmdlDQogICAgICAgIGlmIChpZCA9PSAzMDAxKSB7IHJldHVybiBbIlN1Y2Nlc3MiLCAiRmFpbGVkIDMgdGltZXMiXVtkYXRhLmNoYXJDb2RlQXQoMCldOyB9IC8vIFNlbmQgQ29uc2VudCBDb2RlIEV2ZW50DQogICAgICAgIHJldHVybiBudWxsOw0KICAgIH0NCg0KICAgIG9iai5HZXRBdWRpdExvZyA9IGZ1bmN0aW9uIChmdW5jKSB7DQogICAgICAgIG9iai5BTVRfQXVkaXRMb2dfUmVhZFJlY29yZHMoMSwgX0dldEF1ZGl0TG9nMCwgW2Z1bmMsIFtdXSk7DQogICAgfQ0KDQogICAgZnVuY3Rpb24gX0dldEF1ZGl0TG9nMChzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMsIHRhZykgew0KICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyB0YWdbMF0ob2JqLCBbXSwgc3RhdHVzKTsgcmV0dXJuOyB9DQogICAgICAgIHZhciBwdHIsIGksIGUsIHgsIHIgPSB0YWdbMV0sIHQgPSBuZXcgRGF0ZSgpLCBUaW1lU3RhbXA7DQoNCiAgICAgICAgaWYgKHJlc3BvbnNlcy5Cb2R5WydSZWNvcmRzUmV0dXJuZWQnXSA+IDApIHsNCiAgICAgICAgICAgIHJlc3BvbnNlcy5Cb2R5WydFdmVudFJlY29yZHMnXSA9IE1ha2VUb0FycmF5KHJlc3BvbnNlcy5Cb2R5WydFdmVudFJlY29yZHMnXSk7DQoNCiAgICAgICAgICAgIGZvciAoaSBpbiByZXNwb25zZXMuQm9keVsnRXZlbnRSZWNvcmRzJ10pIHsNCiAgICAgICAgICAgICAgICBlID0gbnVsbDsNCiAgICAgICAgICAgICAgICB0cnkgew0KICAgICAgICAgICAgICAgICAgICBlID0gd2luZG93LmF0b2IocmVzcG9uc2VzLkJvZHlbJ0V2ZW50UmVjb3JkcyddW2ldKTsNCiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7DQogICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGUgKyAiICIgKyByZXNwb25zZXMuQm9keVsnRXZlbnRSZWNvcmRzJ11baV0pDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHggPSB7ICdBdWRpdEFwcElEJzogUmVhZFNob3J0KGUsIDApLCAnRXZlbnRJRCc6IFJlYWRTaG9ydChlLCAyKSwgJ0luaXRpYXRvclR5cGUnOiBlLmNoYXJDb2RlQXQoNCkgfTsNCiAgICAgICAgICAgICAgICB4WydBdWRpdEFwcCddID0gX0FtdEF1ZGl0U3RyaW5nVGFibGVbeFsnQXVkaXRBcHBJRCddXTsNCiAgICAgICAgICAgICAgICB4WydFdmVudCddID0gX0FtdEF1ZGl0U3RyaW5nVGFibGVbKHhbJ0F1ZGl0QXBwSUQnXSAqIDEwMCkgKyB4WydFdmVudElEJ11dOw0KICAgICAgICAgICAgICAgIGlmICgheFsnRXZlbnQnXSkgeFsnRXZlbnQnXSA9ICcjJyArIHhbJ0V2ZW50SUQnXTsNCg0KICAgICAgICAgICAgICAgIC8vIFJlYWQgYW5kIHByb2Nlc3MgdGhlIGluaXRpYXRvcg0KICAgICAgICAgICAgICAgIGlmICh4WydJbml0aWF0b3JUeXBlJ10gPT0gMCkgew0KICAgICAgICAgICAgICAgICAgICAvLyBIVFRQIGRpZ2VzdA0KICAgICAgICAgICAgICAgICAgICB2YXIgdXNlcmxlbiA9IGUuY2hhckNvZGVBdCg1KTsNCiAgICAgICAgICAgICAgICAgICAgeFsnSW5pdGlhdG9yJ10gPSBlLnN1YnN0cmluZyg2LCA2ICsgdXNlcmxlbik7DQogICAgICAgICAgICAgICAgICAgIHB0ciA9IDYgKyB1c2VybGVuOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAoeFsnSW5pdGlhdG9yVHlwZSddID09IDEpIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gS2VyYmVyb3MNCiAgICAgICAgICAgICAgICAgICAgeFsnS2VyYmVyb3NVc2VySW5Eb21haW4nXSA9IFJlYWRJbnQoZSwgNSk7DQogICAgICAgICAgICAgICAgICAgIHZhciB1c2VybGVuID0gZS5jaGFyQ29kZUF0KDkpOw0KICAgICAgICAgICAgICAgICAgICB4WydJbml0aWF0b3InXSA9IEdldFNpZFN0cmluZyhlLnN1YnN0cmluZygxMCwgMTAgKyB1c2VybGVuKSk7DQogICAgICAgICAgICAgICAgICAgIHB0ciA9IDEwICsgdXNlcmxlbjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKHhbJ0luaXRpYXRvclR5cGUnXSA9PSAyKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIExvY2FsDQogICAgICAgICAgICAgICAgICAgIHhbJ0luaXRpYXRvciddID0gJzxpPkxvY2FsPC9pPic7DQogICAgICAgICAgICAgICAgICAgIHB0ciA9IDU7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmICh4WydJbml0aWF0b3JUeXBlJ10gPT0gMykgew0KICAgICAgICAgICAgICAgICAgICAvLyBLVk0gRGVmYXVsdCBQb3J0DQogICAgICAgICAgICAgICAgICAgIHhbJ0luaXRpYXRvciddID0gJzxpPktWTSBEZWZhdWx0IFBvcnQ8L2k+JzsNCiAgICAgICAgICAgICAgICAgICAgcHRyID0gNTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAvLyBSZWFkIHRpbWVzdGFtcA0KICAgICAgICAgICAgICAgIFRpbWVTdGFtcCA9IFJlYWRJbnQoZSwgcHRyKTsNCiAgICAgICAgICAgICAgICB4WydUaW1lJ10gPSBuZXcgRGF0ZSgoVGltZVN0YW1wICsgKHQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwKSkgKiAxMDAwKTsNCiAgICAgICAgICAgICAgICBwdHIgKz0gNDsNCg0KICAgICAgICAgICAgICAgIC8vIFJlYWQgbmV0d29yayBhY2Nlc3MNCiAgICAgICAgICAgICAgICB4WydNQ0xvY2F0aW9uVHlwZSddID0gZS5jaGFyQ29kZUF0KHB0cisrKTsNCiAgICAgICAgICAgICAgICB2YXIgbmV0bGVuID0gZS5jaGFyQ29kZUF0KHB0cisrKTsNCiAgICAgICAgICAgICAgICB4WydOZXRBZGRyZXNzJ10gPSBlLnN1YnN0cmluZyhwdHIsIHB0ciArIG5ldGxlbik7DQoNCiAgICAgICAgICAgICAgICAvLyBSZWFkIGV4dGVuZGVkIGRhdGENCiAgICAgICAgICAgICAgICBwdHIgKz0gbmV0bGVuOw0KICAgICAgICAgICAgICAgIHZhciBleGxlbiA9IGUuY2hhckNvZGVBdChwdHIrKyk7DQogICAgICAgICAgICAgICAgeFsnRXgnXSA9IGUuc3Vic3RyaW5nKHB0ciwgcHRyICsgZXhsZW4pOw0KICAgICAgICAgICAgICAgIHhbJ0V4U3RyJ10gPSBvYmouR2V0QXVkaXRMb2dFeHRlbmRlZERhdGFTdHIoKHhbJ0F1ZGl0QXBwSUQnXSAqIDEwMCkgKyB4WydFdmVudElEJ10sIHhbJ0V4J10pOw0KDQogICAgICAgICAgICAgICAgci5wdXNoKHgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIGlmIChyZXNwb25zZXMuQm9keVsnVG90YWxSZWNvcmRDb3VudCddID4gci5sZW5ndGgpIHsNCiAgICAgICAgICAgIG9iai5BTVRfQXVkaXRMb2dfUmVhZFJlY29yZHMoci5sZW5ndGggKyAxLCBfR2V0QXVkaXRMb2cwLCBbdGFnWzBdLCByXSk7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICB0YWdbMF0ob2JqLCByLCBzdGF0dXMpOw0KICAgICAgICB9DQogICAgfQ0KDQogICAgDQogICAgcmV0dXJuIG9iajsNCn0NCg0KDQoNCg0KLy8gRm9yZ2UgTUQ1DQpmdW5jdGlvbiBoZXhfbWQ1KHN0cikgeyByZXR1cm4gZm9yZ2UubWQubWQ1LmNyZWF0ZSgpLnVwZGF0ZShzdHIpLmRpZ2VzdCgpLnRvSGV4KCk7IH0NCg0KDQoNCi8vIFBlcmZvcm0gTUQ1IG9uIHJhdyBzdHJpbmcgYW5kIHJldHVybiByYXcgc3RyaW5nIHJlc3VsdA0KZnVuY3Rpb24gcnN0cl9tZDUoc3RyKSB7IHJldHVybiBoZXgycnN0cihoZXhfbWQ1KHN0cikpOyB9DQoNCi8qDQpDb252ZXJ0IGFyZ3VtZW50cyBpbnRvIHNlbGVjdG9yIHNldCBhbmQgYm9keSBYTUwuIFVzZWQgYnkgQU1UX1dpRmlQb3J0Q29uZmlndXJhdGlvblNlcnZpY2VfVXBkYXRlV2lGaVNldHRpbmdzLg0KYXJncyA9IHsgDQoJIldpRmlFbmRwb2ludCI6IHsNCgkJX19wYXJhbWV0ZXJUeXBlOiAncmVmZXJlbmNlJywNCgkJX19yZXNvdXJjZVVyaTogJ2h0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NjaW0vMS9jaW0tc2NoZW1hLzIvQ0lNX1dpRmlFbmRwb2ludCcsDQoJCU5hbWU6ICdXaUZpIEVuZHBvaW50IDAnDQoJfSwgDQoJIldpRmlFbmRwb2ludFNldHRpbmdzSW5wdXQiOiANCgl7DQoJCV9fcGFyYW1ldGVyVHlwZTogJ2luc3RhbmNlJywNCgkJX19uYW1lc3BhY2U6ICdodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9XaUZpRW5kcG9pbnRTZXR0aW5ncycsDQoJCUVsZW1lbnROYW1lOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZWRpdFByb2ZpbGUtcHJvZmlsZU5hbWUnKS52YWx1ZSwNCgkJSW5zdGFuY2VJRDogJ0ludGVsKHIpIEFNVDpXaUZpIEVuZHBvaW50IFNldHRpbmdzICcgKyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZWRpdFByb2ZpbGUtcHJvZmlsZU5hbWUnKS52YWx1ZSwNCgkJQXV0aGVudGljYXRpb25NZXRob2Q6IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJyNlZGl0UHJvZmlsZS1uZXR3b3JrQXV0aGVudGljYXRpb24nKS52YWx1ZSwNCgkJLy9CU1NUeXBlOiAzLCAvLyBJbnRlbChyKSBBTVQgc3VwcG9ydHMgb25seSBpbmZyYXN0cnVjdHVyZSBuZXR3b3Jrcw0KCQlFbmNyeXB0aW9uTWV0aG9kOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZWRpdFByb2ZpbGUtZW5jcnlwdGlvbicpLnZhbHVlLA0KCQlTU0lEOiBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcjZWRpdFByb2ZpbGUtbmV0d29ya05hbWUnKS52YWx1ZSwNCgkJUHJpb3JpdHk6IDEwMCwNCgkJUFNLUGFzc1BocmFzZTogZG9jdW1lbnQucXVlcnlTZWxlY3RvcignI2VkaXRQcm9maWxlLXBhc3NQaHJhc2UnKS52YWx1ZQ0KCX0sIA0KCSJJRUVFODAyMXhTZXR0aW5nc0lucHV0IjogbnVsbCwgDQoJIkNsaWVudENyZWRlbnRpYWwiOiBudWxsLCANCgkiQ0FDcmVkZW50aWFsIjogbnVsbCANCn0sIA0KKi8NCmZ1bmN0aW9uIGV4ZWNBcmd1bWVudHNUb1htbChhcmdzKSB7DQoJaWYoYXJncyA9PT0gdW5kZWZpbmVkIHx8IGFyZ3MgPT09IG51bGwpIHJldHVybiBudWxsOw0KCQ0KCXZhciByZXN1bHQgPSAnJzsNCglmb3IodmFyIGFyZ05hbWUgaW4gYXJncykgew0KCQl2YXIgYXJnID0gYXJnc1thcmdOYW1lXTsNCgkJaWYoIWFyZykgY29udGludWU7DQoJCWlmKGFyZ1snX19wYXJhbWV0ZXJUeXBlJ10gPT09ICdyZWZlcmVuY2UnKSByZXN1bHQgKz0gcmVmZXJlbmNlVG9YbWwoYXJnTmFtZSwgYXJnKTsNCgkJZWxzZSByZXN1bHQgKz0gaW5zdGFuY2VUb1htbChhcmdOYW1lLCBhcmcpOw0KCQkvL2lmKGFyZ1snX19pc0luc3RhbmNlJ10pIHJlc3VsdCArPSBpbnN0YW5jZVRvWG1sKGFyZ05hbWUsIGFyZyk7DQoJfQ0KCXJldHVybiByZXN1bHQ7DQp9DQoNCi8qKg0KICogQ29udmVydCBKYXZhU2NyaXB0IG9iamVjdCBpbnRvIFhNTA0KIA0KCTxyOldpRmlFbmRwb2ludFNldHRpbmdzSW5wdXQgeG1sbnM6cT0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NpbS1zY2hlbWEvMi9DSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MiPg0KCQk8cTpFbGVtZW50TmFtZT5XaXJlbGVzcy1Qcm9maWxlLUFkbWluPC9xOkVsZW1lbnROYW1lPg0KCQk8cTpJbnN0YW5jZUlEPkludGVsKHIpIEFNVDpXaUZpIEVuZHBvaW50IFNldHRpbmdzIFdpcmVsZXNzLVByb2ZpbGUtQWRtaW48L3E6SW5zdGFuY2VJRD4NCgkJPHE6QXV0aGVudGljYXRpb25NZXRob2Q+NjwvcTpBdXRoZW50aWNhdGlvbk1ldGhvZD4NCgkJPHE6RW5jcnlwdGlvbk1ldGhvZD40PC9xOkVuY3J5cHRpb25NZXRob2Q+DQoJCTxxOlByaW9yaXR5PjEwMDwvcTpQcmlvcml0eT4NCgkJPHE6UFNLUGFzc1BocmFzZT54eHh4eHh4eDwvcTpQU0tQYXNzUGhyYXNlPg0KCTwvcjpXaUZpRW5kcG9pbnRTZXR0aW5nc0lucHV0Pg0KICovDQpmdW5jdGlvbiBpbnN0YW5jZVRvWG1sKGluc3RhbmNlTmFtZSwgaW5JbnN0YW5jZSkgew0KCWlmKGluSW5zdGFuY2UgPT09IHVuZGVmaW5lZCB8fCBpbkluc3RhbmNlID09PSBudWxsKSByZXR1cm4gbnVsbDsNCgkNCgl2YXIgaGFzTmFtZXNwYWNlID0gISFpbkluc3RhbmNlWydfX25hbWVzcGFjZSddOw0KCXZhciBzdGFydFRhZyA9IGhhc05hbWVzcGFjZSA/ICc8cTonIDogJzwnOw0KCXZhciBlbmRUYWcgPSBoYXNOYW1lc3BhY2UgPyAnPC9xOicgOiAnPC8nOw0KCXZhciBuYW1lc3BhY2VEZWYgPSBoYXNOYW1lc3BhY2UgPyAoJyB4bWxuczpxPSInICsgaW5JbnN0YW5jZVsnX19uYW1lc3BhY2UnXSArICciJyApOiAnJzsNCgl2YXIgcmVzdWx0ID0gJzxyOicgKyBpbnN0YW5jZU5hbWUgKyBuYW1lc3BhY2VEZWYgKyAnPic7DQoJZm9yKHZhciBwcm9wIGluIGluSW5zdGFuY2UpIHsNCgkJaWYgKCFpbkluc3RhbmNlLmhhc093blByb3BlcnR5KHByb3ApIHx8IHByb3AuaW5kZXhPZignX18nKSA9PT0gMCkgY29udGludWU7DQoJCQ0KCQlpZiAodHlwZW9mIGluSW5zdGFuY2VbcHJvcF0gPT09ICdmdW5jdGlvbicgfHwgQXJyYXkuaXNBcnJheShpbkluc3RhbmNlW3Byb3BdKSApIGNvbnRpbnVlOw0KCQkNCgkJaWYgKHR5cGVvZiBpbkluc3RhbmNlW3Byb3BdID09PSAnb2JqZWN0Jykgew0KCQkJLy9yZXN1bHQgKz0gc3RhcnRUYWcgKyBwcm9wICsnPicgKyBpbnN0YW5jZVRvWG1sKCdwcm9wJywgaW5JbnN0YW5jZVtwcm9wXSkgKyBlbmRUYWcgKyBwcm9wICsnPic7DQoJCQljb25zb2xlLmVycm9yKCdvbmx5IGNvbnZlcnQgb25lIGxldmVsIGRvd24uLi4nKTsNCgkJfQ0KCQllbHNlIHsNCgkJCXJlc3VsdCArPSBzdGFydFRhZyArIHByb3AgKyc+JyArIGluSW5zdGFuY2VbcHJvcF0udG9TdHJpbmcoKSArIGVuZFRhZyArIHByb3AgKyc+JzsNCgkJfQ0KCX0NCglyZXN1bHQgKz0gJzwvcjonICsgaW5zdGFuY2VOYW1lICsgJz4nOw0KCXJldHVybiByZXN1bHQ7DQp9DQoNCg0KLyoqDQogKiBDb252ZXJ0IGEgc2VsZWN0b3Igc2V0IGludG8gWE1MLiBFeHBlY3Qgbm8gbmVzdGluZy4NCiAqIHsNCiAqIAlzZWxlY3Rvck5hbWUgOiBzZWxlY3RvclZhbHVlLA0KICogCXNlbGVjdG9yTmFtZSA6IHNlbGVjdG9yVmFsdWUsDQogKgkuLi4gLi4uDQogKiB9DQogDQoJPHI6V2lGaUVuZHBvaW50Pg0KCQk8YTpBZGRyZXNzPmh0dHA6Ly8xOTIuMTY4LjEuMTAzOjE2OTkyL3dzbWFuPC9hOkFkZHJlc3M+DQoJCTxhOlJlZmVyZW5jZVBhcmFtZXRlcnM+DQoJCQk8dzpSZXNvdXJjZVVSST5odHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9XaUZpRW5kcG9pbnQ8L3c6UmVzb3VyY2VVUkk+DQoJCQk8dzpTZWxlY3RvclNldD4NCgkJCQk8dzpTZWxlY3RvciBOYW1lPSJOYW1lIj5XaUZpIEVuZHBvaW50IDA8L3c6U2VsZWN0b3I+DQoJCQk8L3c6U2VsZWN0b3JTZXQ+DQoJCTwvYTpSZWZlcmVuY2VQYXJhbWV0ZXJzPg0KCTwvcjpXaUZpRW5kcG9pbnQ+DQoJCQkNCiAqLw0KZnVuY3Rpb24gcmVmZXJlbmNlVG9YbWwocmVmZXJlbmNlTmFtZSwgaW5SZWZlcmVuY2UpIHsNCglpZihpblJlZmVyZW5jZSA9PT0gdW5kZWZpbmVkIHx8IGluUmVmZXJlbmNlID09PSBudWxsICkgcmV0dXJuIG51bGw7DQoJDQoJdmFyIHJlc3VsdCA9ICc8cjonICsgcmVmZXJlbmNlTmFtZSArICc+PGE6QWRkcmVzcz4vd3NtYW48L2E6QWRkcmVzcz48YTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjx3OlJlc291cmNlVVJJPicrIGluUmVmZXJlbmNlWydfX3Jlc291cmNlVXJpJ10rJzwvdzpSZXNvdXJjZVVSST48dzpTZWxlY3RvclNldD4nOw0KCWZvcih2YXIgc2VsZWN0b3JOYW1lIGluIGluUmVmZXJlbmNlKSB7DQoJCWlmICghaW5SZWZlcmVuY2UuaGFzT3duUHJvcGVydHkoc2VsZWN0b3JOYW1lKSB8fCBzZWxlY3Rvck5hbWUuaW5kZXhPZignX18nKSA9PT0gMCkgY29udGludWU7DQoJCQ0KCQlpZiAodHlwZW9mIGluUmVmZXJlbmNlW3NlbGVjdG9yTmFtZV0gPT09ICdmdW5jdGlvbicgfHwgDQoJCQl0eXBlb2YgaW5SZWZlcmVuY2Vbc2VsZWN0b3JOYW1lXSA9PT0gJ29iamVjdCcgfHwNCgkJCUFycmF5LmlzQXJyYXkoaW5SZWZlcmVuY2Vbc2VsZWN0b3JOYW1lXSkgKQ0KCQkJY29udGludWU7DQoJCQ0KCQlyZXN1bHQgKz0gJzx3OlNlbGVjdG9yIE5hbWU9IicgKyBzZWxlY3Rvck5hbWUgKyciPicgKyBpblJlZmVyZW5jZVtzZWxlY3Rvck5hbWVdLnRvU3RyaW5nKCkgKyAnPC93OlNlbGVjdG9yPic7DQoJfQ0KCQ0KCXJlc3VsdCArPSAnPC93OlNlbGVjdG9yU2V0PjwvYTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjwvcjonICsgcmVmZXJlbmNlTmFtZSArICc+JzsNCglyZXR1cm4gcmVzdWx0Ow0KfQ0KDQovLyBDb252ZXJ0IGEgYnl0ZSBhcnJheSBvZiBTSUQgaW50byBzdHJpbmcNCmZ1bmN0aW9uIEdldFNpZFN0cmluZyhzaWQpIHsNCiAgICB2YXIgciA9ICJTLSIgKyBzaWQuY2hhckNvZGVBdCgwKSArICItIiArIHNpZC5jaGFyQ29kZUF0KDcpOw0KICAgIGZvciAodmFyIGkgPSAyOyBpIDwgKHNpZC5sZW5ndGggLyA0KSA7IGkrKykgciArPSAiLSIgKyBSZWFkSW50WChzaWQsIGkgKiA0KTsNCiAgICByZXR1cm4gcjsNCn0NCg0KLy8gQ29udmVydCBhIFNJRCByZWFkYWJsZSBzdHJpbmcgaW50byBieXRlcw0KZnVuY3Rpb24gR2V0U2lkQnl0ZUFycmF5KHNpZFN0cmluZykgew0KICAgIGlmICghc2lkU3RyaW5nIHx8IHNpZFN0cmluZyA9PSBudWxsKSByZXR1cm4gbnVsbDsNCiAgICB2YXIgc2lkUGFydHMgPSBzaWRTdHJpbmcuc3BsaXQoJy0nKTsNCg0KICAgIC8vIE1ha2Ugc3VyZSB0aGUgU0lEIGhhcyBhdCBsZWFzdCA0IHBhcnRzIGFuZCBzdGFydHMgd2l0aCAnUycNCiAgICBpZiAoc2lkUGFydHMubGVuZ3RoIDwgNCB8fCAoc2lkUGFydHNbMF0gIT0gJ3MnICYmIHNpZFBhcnRzWzBdICE9ICdTJykpIHJldHVybiBudWxsOw0KDQogICAgLy8gQ2hlY2sgdGhhdCBlYWNoIHBhcnQgb2YgdGhlIFNJRCBpcyByZWFsbHkgYW4gaW50ZWdlcg0KICAgIGZvciAodmFyIGkgPSAxOyBpIDwgc2lkUGFydHMubGVuZ3RoOyBpKyspIHsgdmFyIHkgPSBwYXJzZUludChzaWRQYXJ0c1tpXSk7IGlmICh5ICE9IHNpZFBhcnRzW2ldKSByZXR1cm4gbnVsbDsgc2lkUGFydHNbaV0gPSB5OyB9DQoNCiAgICAvLyBWZXJzaW9uICg4IGJpdCkgKyBJZCBjb3VudCAoOCBiaXQpICsgNDggYml0IGluIGJpZyBlbmRpYW4gLS0gRE8gTk9UIHVzZSBiaXR3aXNlIHJpZ2h0IHNoaWZ0IG9wZXJhdG9yLiBKYXZhU2NyaXB0IGNvbnZlcnRzIHRoZSBudW1iZXIgaW50byBhIDMyIGJpdCBpbnRlZ2VyIGJlZm9yZSBzaGlmdGluZy4gSW4gcmVhbCB3b3JsZCwgaXQncyBoaWdobHkgbGlrZWx5IHRoaXMgcGFydCBpcyBhbHdheXMgMC4NCiAgICB2YXIgciA9IFN0cmluZy5mcm9tQ2hhckNvZGUoc2lkUGFydHNbMV0pICsgU3RyaW5nLmZyb21DaGFyQ29kZShzaWRQYXJ0cy5sZW5ndGggLSAzKSArIFNob3J0VG9TdHIoTWF0aC5mbG9vcihzaWRQYXJ0c1syXSAvIE1hdGgucG93KDIsIDMyKSkpICsgSW50VG9TdHIoKHNpZFBhcnRzWzJdKSAmIDB4RkZGRik7DQoNCiAgICAvLyB0aGUgcmVzdCBhcmUgaW4gMzIgYml0IGluIGxpdHRsZSBlbmRpYW4NCiAgICBmb3IgKHZhciBpID0gMzsgaSA8IHNpZFBhcnRzLmxlbmd0aDsgaSsrKSByICs9IEludFRvU3RyWChzaWRQYXJ0c1tpXSk7DQogICAgcmV0dXJuIHI7DQp9DQooZnVuY3Rpb24ocm9vdCwgZmFjdG9yeSkgewogIGlmKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkgewogICAgZGVmaW5lKFtdLCBmYWN0b3J5KTsKICB9IGVsc2UgewogICAgcm9vdC5mb3JnZSA9IGZhY3RvcnkoKTsKICB9Cn0pKHRoaXMsIGZ1bmN0aW9uKCkgewovKioKICogbGljZW5zZSBhbG1vbmQgMC4yLjkgQ29weXJpZ2h0IChjKSAyMDExLTIwMTQsIFRoZSBEb2pvIEZvdW5kYXRpb24gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KICogQXZhaWxhYmxlIHZpYSB0aGUgTUlUIG9yIG5ldyBCU0QgbGljZW5zZS4KICogc2VlOiBodHRwOi8vZ2l0aHViLmNvbS9qcmJ1cmtlL2FsbW9uZCBmb3IgZGV0YWlscwogKi8KLy9Hb2luZyBzbG9wcHkgdG8gYXZvaWQgJ3VzZSBzdHJpY3QnIHN0cmluZyBjb3N0LCBidXQgc3RyaWN0IHByYWN0aWNlcyBzaG91bGQKLy9iZSBmb2xsb3dlZC4KLypqc2xpbnQgc2xvcHB5OiB0cnVlICovCi8qZ2xvYmFsIHNldFRpbWVvdXQ6IGZhbHNlICovCgp2YXIgcmVxdWlyZWpzLCByZXF1aXJlLCBkZWZpbmU7CihmdW5jdGlvbiAodW5kZWYpIHsKICAgIHZhciBtYWluLCByZXEsIG1ha2VNYXAsIGhhbmRsZXJzLAogICAgICAgIGRlZmluZWQgPSB7fSwKICAgICAgICB3YWl0aW5nID0ge30sCiAgICAgICAgY29uZmlnID0ge30sCiAgICAgICAgZGVmaW5pbmcgPSB7fSwKICAgICAgICBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LAogICAgICAgIGFwcyA9IFtdLnNsaWNlLAogICAgICAgIGpzU3VmZml4UmVnRXhwID0gL1wuanMkLzsKCiAgICBmdW5jdGlvbiBoYXNQcm9wKG9iaiwgcHJvcCkgewogICAgICAgIHJldHVybiBoYXNPd24uY2FsbChvYmosIHByb3ApOwogICAgfQoKICAgIC8qKgogICAgICogR2l2ZW4gYSByZWxhdGl2ZSBtb2R1bGUgbmFtZSwgbGlrZSAuL3NvbWV0aGluZywgbm9ybWFsaXplIGl0IHRvCiAgICAgKiBhIHJlYWwgbmFtZSB0aGF0IGNhbiBiZSBtYXBwZWQgdG8gYSBwYXRoLgogICAgICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgdGhlIHJlbGF0aXZlIG5hbWUKICAgICAqIEBwYXJhbSB7U3RyaW5nfSBiYXNlTmFtZSBhIHJlYWwgbmFtZSB0aGF0IHRoZSBuYW1lIGFyZyBpcyByZWxhdGl2ZQogICAgICogdG8uCiAgICAgKiBAcmV0dXJucyB7U3RyaW5nfSBub3JtYWxpemVkIG5hbWUKICAgICAqLwogICAgZnVuY3Rpb24gbm9ybWFsaXplKG5hbWUsIGJhc2VOYW1lKSB7CiAgICAgICAgdmFyIG5hbWVQYXJ0cywgbmFtZVNlZ21lbnQsIG1hcFZhbHVlLCBmb3VuZE1hcCwgbGFzdEluZGV4LAogICAgICAgICAgICBmb3VuZEksIGZvdW5kU3Rhck1hcCwgc3RhckksIGksIGosIHBhcnQsCiAgICAgICAgICAgIGJhc2VQYXJ0cyA9IGJhc2VOYW1lICYmIGJhc2VOYW1lLnNwbGl0KCIvIiksCiAgICAgICAgICAgIG1hcCA9IGNvbmZpZy5tYXAsCiAgICAgICAgICAgIHN0YXJNYXAgPSAobWFwICYmIG1hcFsnKiddKSB8fCB7fTsKCiAgICAgICAgLy9BZGp1c3QgYW55IHJlbGF0aXZlIHBhdGhzLgogICAgICAgIGlmIChuYW1lICYmIG5hbWUuY2hhckF0KDApID09PSAiLiIpIHsKICAgICAgICAgICAgLy9JZiBoYXZlIGEgYmFzZSBuYW1lLCB0cnkgdG8gbm9ybWFsaXplIGFnYWluc3QgaXQsCiAgICAgICAgICAgIC8vb3RoZXJ3aXNlLCBhc3N1bWUgaXQgaXMgYSB0b3AtbGV2ZWwgcmVxdWlyZSB0aGF0IHdpbGwKICAgICAgICAgICAgLy9iZSByZWxhdGl2ZSB0byBiYXNlVXJsIGluIHRoZSBlbmQuCiAgICAgICAgICAgIGlmIChiYXNlTmFtZSkgewogICAgICAgICAgICAgICAgLy9Db252ZXJ0IGJhc2VOYW1lIHRvIGFycmF5LCBhbmQgbG9wIG9mZiB0aGUgbGFzdCBwYXJ0LAogICAgICAgICAgICAgICAgLy9zbyB0aGF0IC4gbWF0Y2hlcyB0aGF0ICJkaXJlY3RvcnkiIGFuZCBub3QgbmFtZSBvZiB0aGUgYmFzZU5hbWUncwogICAgICAgICAgICAgICAgLy9tb2R1bGUuIEZvciBpbnN0YW5jZSwgYmFzZU5hbWUgb2YgIm9uZS90d28vdGhyZWUiLCBtYXBzIHRvCiAgICAgICAgICAgICAgICAvLyJvbmUvdHdvL3RocmVlLmpzIiwgYnV0IHdlIHdhbnQgdGhlIGRpcmVjdG9yeSwgIm9uZS90d28iIGZvcgogICAgICAgICAgICAgICAgLy90aGlzIG5vcm1hbGl6YXRpb24uCiAgICAgICAgICAgICAgICBiYXNlUGFydHMgPSBiYXNlUGFydHMuc2xpY2UoMCwgYmFzZVBhcnRzLmxlbmd0aCAtIDEpOwogICAgICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3BsaXQoJy8nKTsKICAgICAgICAgICAgICAgIGxhc3RJbmRleCA9IG5hbWUubGVuZ3RoIC0gMTsKCiAgICAgICAgICAgICAgICAvLyBOb2RlIC5qcyBhbGxvd2FuY2U6CiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLm5vZGVJZENvbXBhdCAmJiBqc1N1ZmZpeFJlZ0V4cC50ZXN0KG5hbWVbbGFzdEluZGV4XSkpIHsKICAgICAgICAgICAgICAgICAgICBuYW1lW2xhc3RJbmRleF0gPSBuYW1lW2xhc3RJbmRleF0ucmVwbGFjZShqc1N1ZmZpeFJlZ0V4cCwgJycpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIG5hbWUgPSBiYXNlUGFydHMuY29uY2F0KG5hbWUpOwoKICAgICAgICAgICAgICAgIC8vc3RhcnQgdHJpbURvdHMKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuYW1lLmxlbmd0aDsgaSArPSAxKSB7CiAgICAgICAgICAgICAgICAgICAgcGFydCA9IG5hbWVbaV07CiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnQgPT09ICIuIikgewogICAgICAgICAgICAgICAgICAgICAgICBuYW1lLnNwbGljZShpLCAxKTsKICAgICAgICAgICAgICAgICAgICAgICAgaSAtPSAxOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocGFydCA9PT0gIi4uIikgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PT0gMSAmJiAobmFtZVsyXSA9PT0gJy4uJyB8fCBuYW1lWzBdID09PSAnLi4nKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9FbmQgb2YgdGhlIGxpbmUuIEtlZXAgYXQgbGVhc3Qgb25lIG5vbi1kb3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vcGF0aCBzZWdtZW50IGF0IHRoZSBmcm9udCBzbyBpdCBjYW4gYmUgbWFwcGVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2NvcnJlY3RseSB0byBkaXNrLiBPdGhlcndpc2UsIHRoZXJlIGlzIGxpa2VseQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy9ubyBwYXRoIG1hcHBpbmcgZm9yIGEgcGF0aCBzdGFydGluZyB3aXRoICcuLicuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1RoaXMgY2FuIHN0aWxsIGZhaWwsIGJ1dCBjYXRjaGVzIHRoZSBtb3N0IHJlYXNvbmFibGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vdXNlcyBvZiAuLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA+IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUuc3BsaWNlKGkgLSAxLCAyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgLT0gMjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vZW5kIHRyaW1Eb3RzCgogICAgICAgICAgICAgICAgbmFtZSA9IG5hbWUuam9pbigiLyIpOwogICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWUuaW5kZXhPZignLi8nKSA9PT0gMCkgewogICAgICAgICAgICAgICAgLy8gTm8gYmFzZU5hbWUsIHNvIHRoaXMgaXMgSUQgaXMgcmVzb2x2ZWQgcmVsYXRpdmUKICAgICAgICAgICAgICAgIC8vIHRvIGJhc2VVcmwsIHB1bGwgb2ZmIHRoZSBsZWFkaW5nIGRvdC4KICAgICAgICAgICAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cmluZygyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLy9BcHBseSBtYXAgY29uZmlnIGlmIGF2YWlsYWJsZS4KICAgICAgICBpZiAoKGJhc2VQYXJ0cyB8fCBzdGFyTWFwKSAmJiBtYXApIHsKICAgICAgICAgICAgbmFtZVBhcnRzID0gbmFtZS5zcGxpdCgnLycpOwoKICAgICAgICAgICAgZm9yIChpID0gbmFtZVBhcnRzLmxlbmd0aDsgaSA+IDA7IGkgLT0gMSkgewogICAgICAgICAgICAgICAgbmFtZVNlZ21lbnQgPSBuYW1lUGFydHMuc2xpY2UoMCwgaSkuam9pbigiLyIpOwoKICAgICAgICAgICAgICAgIGlmIChiYXNlUGFydHMpIHsKICAgICAgICAgICAgICAgICAgICAvL0ZpbmQgdGhlIGxvbmdlc3QgYmFzZU5hbWUgc2VnbWVudCBtYXRjaCBpbiB0aGUgY29uZmlnLgogICAgICAgICAgICAgICAgICAgIC8vU28sIGRvIGpvaW5zIG9uIHRoZSBiaWdnZXN0IHRvIHNtYWxsZXN0IGxlbmd0aHMgb2YgYmFzZVBhcnRzLgogICAgICAgICAgICAgICAgICAgIGZvciAoaiA9IGJhc2VQYXJ0cy5sZW5ndGg7IGogPiAwOyBqIC09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbWFwVmFsdWUgPSBtYXBbYmFzZVBhcnRzLnNsaWNlKDAsIGopLmpvaW4oJy8nKV07CgogICAgICAgICAgICAgICAgICAgICAgICAvL2Jhc2VOYW1lIHNlZ21lbnQgaGFzICBjb25maWcsIGZpbmQgaWYgaXQgaGFzIG9uZSBmb3IKICAgICAgICAgICAgICAgICAgICAgICAgLy90aGlzIG5hbWUuCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtYXBWYWx1ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwVmFsdWUgPSBtYXBWYWx1ZVtuYW1lU2VnbWVudF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWFwVmFsdWUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL01hdGNoLCB1cGRhdGUgbmFtZSB0byB0aGUgbmV3IHZhbHVlLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvdW5kTWFwID0gbWFwVmFsdWU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm91bmRJID0gaTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoZm91bmRNYXApIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvL0NoZWNrIGZvciBhIHN0YXIgbWFwIG1hdGNoLCBidXQganVzdCBob2xkIG9uIHRvIGl0LAogICAgICAgICAgICAgICAgLy9pZiB0aGVyZSBpcyBhIHNob3J0ZXIgc2VnbWVudCBtYXRjaCBsYXRlciBpbiBhIG1hdGNoaW5nCiAgICAgICAgICAgICAgICAvL2NvbmZpZywgdGhlbiBmYXZvciBvdmVyIHRoaXMgc3RhciBtYXAuCiAgICAgICAgICAgICAgICBpZiAoIWZvdW5kU3Rhck1hcCAmJiBzdGFyTWFwICYmIHN0YXJNYXBbbmFtZVNlZ21lbnRdKSB7CiAgICAgICAgICAgICAgICAgICAgZm91bmRTdGFyTWFwID0gc3Rhck1hcFtuYW1lU2VnbWVudF07CiAgICAgICAgICAgICAgICAgICAgc3RhckkgPSBpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoIWZvdW5kTWFwICYmIGZvdW5kU3Rhck1hcCkgewogICAgICAgICAgICAgICAgZm91bmRNYXAgPSBmb3VuZFN0YXJNYXA7CiAgICAgICAgICAgICAgICBmb3VuZEkgPSBzdGFySTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGZvdW5kTWFwKSB7CiAgICAgICAgICAgICAgICBuYW1lUGFydHMuc3BsaWNlKDAsIGZvdW5kSSwgZm91bmRNYXApOwogICAgICAgICAgICAgICAgbmFtZSA9IG5hbWVQYXJ0cy5qb2luKCcvJyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldHVybiBuYW1lOwogICAgfQoKICAgIGZ1bmN0aW9uIG1ha2VSZXF1aXJlKHJlbE5hbWUsIGZvcmNlU3luYykgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vQSB2ZXJzaW9uIG9mIGEgcmVxdWlyZSBmdW5jdGlvbiB0aGF0IHBhc3NlcyBhIG1vZHVsZU5hbWUKICAgICAgICAgICAgLy92YWx1ZSBmb3IgaXRlbXMgdGhhdCBtYXkgbmVlZCB0bwogICAgICAgICAgICAvL2xvb2sgdXAgcGF0aHMgcmVsYXRpdmUgdG8gdGhlIG1vZHVsZU5hbWUKICAgICAgICAgICAgcmV0dXJuIHJlcS5hcHBseSh1bmRlZiwgYXBzLmNhbGwoYXJndW1lbnRzLCAwKS5jb25jYXQoW3JlbE5hbWUsIGZvcmNlU3luY10pKTsKICAgICAgICB9OwogICAgfQoKICAgIGZ1bmN0aW9uIG1ha2VOb3JtYWxpemUocmVsTmFtZSkgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAobmFtZSkgewogICAgICAgICAgICByZXR1cm4gbm9ybWFsaXplKG5hbWUsIHJlbE5hbWUpOwogICAgICAgIH07CiAgICB9CgogICAgZnVuY3Rpb24gbWFrZUxvYWQoZGVwTmFtZSkgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAodmFsdWUpIHsKICAgICAgICAgICAgZGVmaW5lZFtkZXBOYW1lXSA9IHZhbHVlOwogICAgICAgIH07CiAgICB9CgogICAgZnVuY3Rpb24gY2FsbERlcChuYW1lKSB7CiAgICAgICAgaWYgKGhhc1Byb3Aod2FpdGluZywgbmFtZSkpIHsKICAgICAgICAgICAgdmFyIGFyZ3MgPSB3YWl0aW5nW25hbWVdOwogICAgICAgICAgICBkZWxldGUgd2FpdGluZ1tuYW1lXTsKICAgICAgICAgICAgZGVmaW5pbmdbbmFtZV0gPSB0cnVlOwogICAgICAgICAgICBtYWluLmFwcGx5KHVuZGVmLCBhcmdzKTsKICAgICAgICB9CgogICAgICAgIGlmICghaGFzUHJvcChkZWZpbmVkLCBuYW1lKSAmJiAhaGFzUHJvcChkZWZpbmluZywgbmFtZSkpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyAnICsgbmFtZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBkZWZpbmVkW25hbWVdOwogICAgfQoKICAgIC8vVHVybnMgYSBwbHVnaW4hcmVzb3VyY2UgdG8gW3BsdWdpbiwgcmVzb3VyY2VdCiAgICAvL3dpdGggdGhlIHBsdWdpbiBiZWluZyB1bmRlZmluZWQgaWYgdGhlIG5hbWUKICAgIC8vZGlkIG5vdCBoYXZlIGEgcGx1Z2luIHByZWZpeC4KICAgIGZ1bmN0aW9uIHNwbGl0UHJlZml4KG5hbWUpIHsKICAgICAgICB2YXIgcHJlZml4LAogICAgICAgICAgICBpbmRleCA9IG5hbWUgPyBuYW1lLmluZGV4T2YoJyEnKSA6IC0xOwogICAgICAgIGlmIChpbmRleCA+IC0xKSB7CiAgICAgICAgICAgIHByZWZpeCA9IG5hbWUuc3Vic3RyaW5nKDAsIGluZGV4KTsKICAgICAgICAgICAgbmFtZSA9IG5hbWUuc3Vic3RyaW5nKGluZGV4ICsgMSwgbmFtZS5sZW5ndGgpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gW3ByZWZpeCwgbmFtZV07CiAgICB9CgogICAgLyoqCiAgICAgKiBNYWtlcyBhIG5hbWUgbWFwLCBub3JtYWxpemluZyB0aGUgbmFtZSwgYW5kIHVzaW5nIGEgcGx1Z2luCiAgICAgKiBmb3Igbm9ybWFsaXphdGlvbiBpZiBuZWNlc3NhcnkuIEdyYWJzIGEgcmVmIHRvIHBsdWdpbgogICAgICogdG9vLCBhcyBhbiBvcHRpbWl6YXRpb24uCiAgICAgKi8KICAgIG1ha2VNYXAgPSBmdW5jdGlvbiAobmFtZSwgcmVsTmFtZSkgewogICAgICAgIHZhciBwbHVnaW4sCiAgICAgICAgICAgIHBhcnRzID0gc3BsaXRQcmVmaXgobmFtZSksCiAgICAgICAgICAgIHByZWZpeCA9IHBhcnRzWzBdOwoKICAgICAgICBuYW1lID0gcGFydHNbMV07CgogICAgICAgIGlmIChwcmVmaXgpIHsKICAgICAgICAgICAgcHJlZml4ID0gbm9ybWFsaXplKHByZWZpeCwgcmVsTmFtZSk7CiAgICAgICAgICAgIHBsdWdpbiA9IGNhbGxEZXAocHJlZml4KTsKICAgICAgICB9CgogICAgICAgIC8vTm9ybWFsaXplIGFjY29yZGluZwogICAgICAgIGlmIChwcmVmaXgpIHsKICAgICAgICAgICAgaWYgKHBsdWdpbiAmJiBwbHVnaW4ubm9ybWFsaXplKSB7CiAgICAgICAgICAgICAgICBuYW1lID0gcGx1Z2luLm5vcm1hbGl6ZShuYW1lLCBtYWtlTm9ybWFsaXplKHJlbE5hbWUpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG5hbWUgPSBub3JtYWxpemUobmFtZSwgcmVsTmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBuYW1lID0gbm9ybWFsaXplKG5hbWUsIHJlbE5hbWUpOwogICAgICAgICAgICBwYXJ0cyA9IHNwbGl0UHJlZml4KG5hbWUpOwogICAgICAgICAgICBwcmVmaXggPSBwYXJ0c1swXTsKICAgICAgICAgICAgbmFtZSA9IHBhcnRzWzFdOwogICAgICAgICAgICBpZiAocHJlZml4KSB7CiAgICAgICAgICAgICAgICBwbHVnaW4gPSBjYWxsRGVwKHByZWZpeCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vVXNpbmcgcmlkaWN1bG91cyBwcm9wZXJ0eSBuYW1lcyBmb3Igc3BhY2UgcmVhc29ucwogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIGY6IHByZWZpeCA/IHByZWZpeCArICchJyArIG5hbWUgOiBuYW1lLCAvL2Z1bGxOYW1lCiAgICAgICAgICAgIG46IG5hbWUsCiAgICAgICAgICAgIHByOiBwcmVmaXgsCiAgICAgICAgICAgIHA6IHBsdWdpbgogICAgICAgIH07CiAgICB9OwoKICAgIGZ1bmN0aW9uIG1ha2VDb25maWcobmFtZSkgewogICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIHJldHVybiAoY29uZmlnICYmIGNvbmZpZy5jb25maWcgJiYgY29uZmlnLmNvbmZpZ1tuYW1lXSkgfHwge307CiAgICAgICAgfTsKICAgIH0KCiAgICBoYW5kbGVycyA9IHsKICAgICAgICByZXF1aXJlOiBmdW5jdGlvbiAobmFtZSkgewogICAgICAgICAgICByZXR1cm4gbWFrZVJlcXVpcmUobmFtZSk7CiAgICAgICAgfSwKICAgICAgICBleHBvcnRzOiBmdW5jdGlvbiAobmFtZSkgewogICAgICAgICAgICB2YXIgZSA9IGRlZmluZWRbbmFtZV07CiAgICAgICAgICAgIGlmICh0eXBlb2YgZSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICAgICAgICAgIHJldHVybiBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmV0dXJuIChkZWZpbmVkW25hbWVdID0ge30pOwogICAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBtb2R1bGU6IGZ1bmN0aW9uIChuYW1lKSB7CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICBpZDogbmFtZSwKICAgICAgICAgICAgICAgIHVyaTogJycsCiAgICAgICAgICAgICAgICBleHBvcnRzOiBkZWZpbmVkW25hbWVdLAogICAgICAgICAgICAgICAgY29uZmlnOiBtYWtlQ29uZmlnKG5hbWUpCiAgICAgICAgICAgIH07CiAgICAgICAgfQogICAgfTsKCiAgICBtYWluID0gZnVuY3Rpb24gKG5hbWUsIGRlcHMsIGNhbGxiYWNrLCByZWxOYW1lKSB7CiAgICAgICAgdmFyIGNqc01vZHVsZSwgZGVwTmFtZSwgcmV0LCBtYXAsIGksCiAgICAgICAgICAgIGFyZ3MgPSBbXSwKICAgICAgICAgICAgY2FsbGJhY2tUeXBlID0gdHlwZW9mIGNhbGxiYWNrLAogICAgICAgICAgICB1c2luZ0V4cG9ydHM7CgogICAgICAgIC8vVXNlIG5hbWUgaWYgbm8gcmVsTmFtZQogICAgICAgIHJlbE5hbWUgPSByZWxOYW1lIHx8IG5hbWU7CgogICAgICAgIC8vQ2FsbCB0aGUgY2FsbGJhY2sgdG8gZGVmaW5lIHRoZSBtb2R1bGUsIGlmIG5lY2Vzc2FyeS4KICAgICAgICBpZiAoY2FsbGJhY2tUeXBlID09PSAndW5kZWZpbmVkJyB8fCBjYWxsYmFja1R5cGUgPT09ICdmdW5jdGlvbicpIHsKICAgICAgICAgICAgLy9QdWxsIG91dCB0aGUgZGVmaW5lZCBkZXBlbmRlbmNpZXMgYW5kIHBhc3MgdGhlIG9yZGVyZWQKICAgICAgICAgICAgLy92YWx1ZXMgdG8gdGhlIGNhbGxiYWNrLgogICAgICAgICAgICAvL0RlZmF1bHQgdG8gW3JlcXVpcmUsIGV4cG9ydHMsIG1vZHVsZV0gaWYgbm8gZGVwcwogICAgICAgICAgICBkZXBzID0gIWRlcHMubGVuZ3RoICYmIGNhbGxiYWNrLmxlbmd0aCA/IFsncmVxdWlyZScsICdleHBvcnRzJywgJ21vZHVsZSddIDogZGVwczsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGRlcHMubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgICAgICAgICAgIG1hcCA9IG1ha2VNYXAoZGVwc1tpXSwgcmVsTmFtZSk7CiAgICAgICAgICAgICAgICBkZXBOYW1lID0gbWFwLmY7CgogICAgICAgICAgICAgICAgLy9GYXN0IHBhdGggQ29tbW9uSlMgc3RhbmRhcmQgZGVwZW5kZW5jaWVzLgogICAgICAgICAgICAgICAgaWYgKGRlcE5hbWUgPT09ICJyZXF1aXJlIikgewogICAgICAgICAgICAgICAgICAgIGFyZ3NbaV0gPSBoYW5kbGVycy5yZXF1aXJlKG5hbWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChkZXBOYW1lID09PSAiZXhwb3J0cyIpIHsKICAgICAgICAgICAgICAgICAgICAvL0NvbW1vbkpTIG1vZHVsZSBzcGVjIDEuMQogICAgICAgICAgICAgICAgICAgIGFyZ3NbaV0gPSBoYW5kbGVycy5leHBvcnRzKG5hbWUpOwogICAgICAgICAgICAgICAgICAgIHVzaW5nRXhwb3J0cyA9IHRydWU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRlcE5hbWUgPT09ICJtb2R1bGUiKSB7CiAgICAgICAgICAgICAgICAgICAgLy9Db21tb25KUyBtb2R1bGUgc3BlYyAxLjEKICAgICAgICAgICAgICAgICAgICBjanNNb2R1bGUgPSBhcmdzW2ldID0gaGFuZGxlcnMubW9kdWxlKG5hbWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChoYXNQcm9wKGRlZmluZWQsIGRlcE5hbWUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc1Byb3Aod2FpdGluZywgZGVwTmFtZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzUHJvcChkZWZpbmluZywgZGVwTmFtZSkpIHsKICAgICAgICAgICAgICAgICAgICBhcmdzW2ldID0gY2FsbERlcChkZXBOYW1lKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAobWFwLnApIHsKICAgICAgICAgICAgICAgICAgICBtYXAucC5sb2FkKG1hcC5uLCBtYWtlUmVxdWlyZShyZWxOYW1lLCB0cnVlKSwgbWFrZUxvYWQoZGVwTmFtZSksIHt9KTsKICAgICAgICAgICAgICAgICAgICBhcmdzW2ldID0gZGVmaW5lZFtkZXBOYW1lXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKG5hbWUgKyAnIG1pc3NpbmcgJyArIGRlcE5hbWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICByZXQgPSBjYWxsYmFjayA/IGNhbGxiYWNrLmFwcGx5KGRlZmluZWRbbmFtZV0sIGFyZ3MpIDogdW5kZWZpbmVkOwoKICAgICAgICAgICAgaWYgKG5hbWUpIHsKICAgICAgICAgICAgICAgIC8vSWYgc2V0dGluZyBleHBvcnRzIHZpYSAibW9kdWxlIiBpcyBpbiBwbGF5LAogICAgICAgICAgICAgICAgLy9mYXZvciB0aGF0IG92ZXIgcmV0dXJuIHZhbHVlIGFuZCBleHBvcnRzLiBBZnRlciB0aGF0LAogICAgICAgICAgICAgICAgLy9mYXZvciBhIG5vbi11bmRlZmluZWQgcmV0dXJuIHZhbHVlIG92ZXIgZXhwb3J0cyB1c2UuCiAgICAgICAgICAgICAgICBpZiAoY2pzTW9kdWxlICYmIGNqc01vZHVsZS5leHBvcnRzICE9PSB1bmRlZiAmJgogICAgICAgICAgICAgICAgICAgICAgICBjanNNb2R1bGUuZXhwb3J0cyAhPT0gZGVmaW5lZFtuYW1lXSkgewogICAgICAgICAgICAgICAgICAgIGRlZmluZWRbbmFtZV0gPSBjanNNb2R1bGUuZXhwb3J0czsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAocmV0ICE9PSB1bmRlZiB8fCAhdXNpbmdFeHBvcnRzKSB7CiAgICAgICAgICAgICAgICAgICAgLy9Vc2UgdGhlIHJldHVybiB2YWx1ZSBmcm9tIHRoZSBmdW5jdGlvbi4KICAgICAgICAgICAgICAgICAgICBkZWZpbmVkW25hbWVdID0gcmV0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChuYW1lKSB7CiAgICAgICAgICAgIC8vTWF5IGp1c3QgYmUgYW4gb2JqZWN0IGRlZmluaXRpb24gZm9yIHRoZSBtb2R1bGUuIE9ubHkKICAgICAgICAgICAgLy93b3JyeSBhYm91dCBkZWZpbmluZyBpZiBoYXZlIGEgbW9kdWxlIG5hbWUuCiAgICAgICAgICAgIGRlZmluZWRbbmFtZV0gPSBjYWxsYmFjazsKICAgICAgICB9CiAgICB9OwoKICAgIHJlcXVpcmVqcyA9IHJlcXVpcmUgPSByZXEgPSBmdW5jdGlvbiAoZGVwcywgY2FsbGJhY2ssIHJlbE5hbWUsIGZvcmNlU3luYywgYWx0KSB7CiAgICAgICAgaWYgKHR5cGVvZiBkZXBzID09PSAic3RyaW5nIikgewogICAgICAgICAgICBpZiAoaGFuZGxlcnNbZGVwc10pIHsKICAgICAgICAgICAgICAgIC8vY2FsbGJhY2sgaW4gdGhpcyBjYXNlIGlzIHJlYWxseSByZWxOYW1lCiAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlcnNbZGVwc10oY2FsbGJhY2spOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8vSnVzdCByZXR1cm4gdGhlIG1vZHVsZSB3YW50ZWQuIEluIHRoaXMgc2NlbmFyaW8sIHRoZQogICAgICAgICAgICAvL2RlcHMgYXJnIGlzIHRoZSBtb2R1bGUgbmFtZSwgYW5kIHNlY29uZCBhcmcgKGlmIHBhc3NlZCkKICAgICAgICAgICAgLy9pcyBqdXN0IHRoZSByZWxOYW1lLgogICAgICAgICAgICAvL05vcm1hbGl6ZSBtb2R1bGUgbmFtZSwgaWYgaXQgY29udGFpbnMgLiBvciAuLgogICAgICAgICAgICByZXR1cm4gY2FsbERlcChtYWtlTWFwKGRlcHMsIGNhbGxiYWNrKS5mKTsKICAgICAgICB9IGVsc2UgaWYgKCFkZXBzLnNwbGljZSkgewogICAgICAgICAgICAvL2RlcHMgaXMgYSBjb25maWcgb2JqZWN0LCBub3QgYW4gYXJyYXkuCiAgICAgICAgICAgIGNvbmZpZyA9IGRlcHM7CiAgICAgICAgICAgIGlmIChjb25maWcuZGVwcykgewogICAgICAgICAgICAgICAgcmVxKGNvbmZpZy5kZXBzLCBjb25maWcuY2FsbGJhY2spOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghY2FsbGJhY2spIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNhbGxiYWNrLnNwbGljZSkgewogICAgICAgICAgICAgICAgLy9jYWxsYmFjayBpcyBhbiBhcnJheSwgd2hpY2ggbWVhbnMgaXQgaXMgYSBkZXBlbmRlbmN5IGxpc3QuCiAgICAgICAgICAgICAgICAvL0FkanVzdCBhcmdzIGlmIHRoZXJlIGFyZSBkZXBlbmRlbmNpZXMKICAgICAgICAgICAgICAgIGRlcHMgPSBjYWxsYmFjazsKICAgICAgICAgICAgICAgIGNhbGxiYWNrID0gcmVsTmFtZTsKICAgICAgICAgICAgICAgIHJlbE5hbWUgPSBudWxsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZGVwcyA9IHVuZGVmOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvL1N1cHBvcnQgcmVxdWlyZShbJ2EnXSkKICAgICAgICBjYWxsYmFjayA9IGNhbGxiYWNrIHx8IGZ1bmN0aW9uICgpIHt9OwoKICAgICAgICAvL0lmIHJlbE5hbWUgaXMgYSBmdW5jdGlvbiwgaXQgaXMgYW4gZXJyYmFjayBoYW5kbGVyLAogICAgICAgIC8vc28gcmVtb3ZlIGl0LgogICAgICAgIGlmICh0eXBlb2YgcmVsTmFtZSA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICByZWxOYW1lID0gZm9yY2VTeW5jOwogICAgICAgICAgICBmb3JjZVN5bmMgPSBhbHQ7CiAgICAgICAgfQoKICAgICAgICAvL1NpbXVsYXRlIGFzeW5jIGNhbGxiYWNrOwogICAgICAgIGlmIChmb3JjZVN5bmMpIHsKICAgICAgICAgICAgbWFpbih1bmRlZiwgZGVwcywgY2FsbGJhY2ssIHJlbE5hbWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vVXNpbmcgYSBub24temVybyB2YWx1ZSBiZWNhdXNlIG9mIGNvbmNlcm4gZm9yIHdoYXQgb2xkIGJyb3dzZXJzCiAgICAgICAgICAgIC8vZG8sIGFuZCBsYXRlc3QgYnJvd3NlcnMgInVwZ3JhZGUiIHRvIDQgaWYgbG93ZXIgdmFsdWUgaXMgdXNlZDoKICAgICAgICAgICAgLy9odHRwOi8vd3d3LndoYXR3Zy5vcmcvc3BlY3Mvd2ViLWFwcHMvY3VycmVudC13b3JrL211bHRpcGFnZS90aW1lcnMuaHRtbCNkb20td2luZG93dGltZXJzLXNldHRpbWVvdXQ6CiAgICAgICAgICAgIC8vSWYgd2FudCBhIHZhbHVlIGltbWVkaWF0ZWx5LCB1c2UgcmVxdWlyZSgnaWQnKSBpbnN0ZWFkIC0tIHNvbWV0aGluZwogICAgICAgICAgICAvL3RoYXQgd29ya3MgaW4gYWxtb25kIG9uIHRoZSBnbG9iYWwgbGV2ZWwsIGJ1dCBub3QgZ3VhcmFudGVlZCBhbmQKICAgICAgICAgICAgLy91bmxpa2VseSB0byB3b3JrIGluIG90aGVyIEFNRCBpbXBsZW1lbnRhdGlvbnMuCiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAgbWFpbih1bmRlZiwgZGVwcywgY2FsbGJhY2ssIHJlbE5hbWUpOwogICAgICAgICAgICB9LCA0KTsKICAgICAgICB9CgogICAgICAgIHJldHVybiByZXE7CiAgICB9OwoKICAgIC8qKgogICAgICogSnVzdCBkcm9wcyB0aGUgY29uZmlnIG9uIHRoZSBmbG9vciwgYnV0IHJldHVybnMgcmVxIGluIGNhc2UKICAgICAqIHRoZSBjb25maWcgcmV0dXJuIHZhbHVlIGlzIHVzZWQuCiAgICAgKi8KICAgIHJlcS5jb25maWcgPSBmdW5jdGlvbiAoY2ZnKSB7CiAgICAgICAgcmV0dXJuIHJlcShjZmcpOwogICAgfTsKCiAgICAvKioKICAgICAqIEV4cG9zZSBtb2R1bGUgcmVnaXN0cnkgZm9yIGRlYnVnZ2luZyBhbmQgdG9vbGluZwogICAgICovCiAgICByZXF1aXJlanMuX2RlZmluZWQgPSBkZWZpbmVkOwoKICAgIGRlZmluZSA9IGZ1bmN0aW9uIChuYW1lLCBkZXBzLCBjYWxsYmFjaykgewoKICAgICAgICAvL1RoaXMgbW9kdWxlIG1heSBub3QgaGF2ZSBkZXBlbmRlbmNpZXMKICAgICAgICBpZiAoIWRlcHMuc3BsaWNlKSB7CiAgICAgICAgICAgIC8vZGVwcyBpcyBub3QgYW4gYXJyYXksIHNvIHByb2JhYmx5IG1lYW5zCiAgICAgICAgICAgIC8vYW4gb2JqZWN0IGxpdGVyYWwgb3IgZmFjdG9yeSBmdW5jdGlvbiBmb3IKICAgICAgICAgICAgLy90aGUgdmFsdWUuIEFkanVzdCBhcmdzLgogICAgICAgICAgICBjYWxsYmFjayA9IGRlcHM7CiAgICAgICAgICAgIGRlcHMgPSBbXTsKICAgICAgICB9CgogICAgICAgIGlmICghaGFzUHJvcChkZWZpbmVkLCBuYW1lKSAmJiAhaGFzUHJvcCh3YWl0aW5nLCBuYW1lKSkgewogICAgICAgICAgICB3YWl0aW5nW25hbWVdID0gW25hbWUsIGRlcHMsIGNhbGxiYWNrXTsKICAgICAgICB9CiAgICB9OwoKICAgIGRlZmluZS5hbWQgPSB7CiAgICAgICAgalF1ZXJ5OiB0cnVlCiAgICB9Owp9KCkpOwoKZGVmaW5lKCJub2RlX21vZHVsZXMvYWxtb25kL2FsbW9uZCIsIGZ1bmN0aW9uKCl7fSk7CgovKioKICogVXRpbGl0eSBmdW5jdGlvbnMgZm9yIHdlYiBhcHBsaWNhdGlvbnMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKLyogVXRpbGl0aWVzIEFQSSAqLwp2YXIgdXRpbCA9IGZvcmdlLnV0aWwgPSBmb3JnZS51dGlsIHx8IHt9OwoKLy8gZGVmaW5lIHNldEltbWVkaWF0ZSBhbmQgbmV4dFRpY2sKKGZ1bmN0aW9uKCkgewogIC8vIHVzZSBuYXRpdmUgbmV4dFRpY2sKICBpZih0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvY2Vzcy5uZXh0VGljaykgewogICAgdXRpbC5uZXh0VGljayA9IHByb2Nlc3MubmV4dFRpY2s7CiAgICBpZih0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSAnZnVuY3Rpb24nKSB7CiAgICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gc2V0SW1tZWRpYXRlOwogICAgfSBlbHNlIHsKICAgICAgLy8gcG9seWZpbGwgc2V0SW1tZWRpYXRlIHdpdGggbmV4dFRpY2ssIG9sZGVyIHZlcnNpb25zIG9mIG5vZGUKICAgICAgLy8gKHRob3NlIHcvbyBzZXRJbW1lZGlhdGUpIHdvbid0IHRvdGFsbHkgc3RhcnZlIElPCiAgICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gdXRpbC5uZXh0VGljazsKICAgIH0KICAgIHJldHVybjsKICB9CgogIC8vIHBvbHlmaWxsIG5leHRUaWNrIHdpdGggbmF0aXZlIHNldEltbWVkaWF0ZQogIGlmKHR5cGVvZiBzZXRJbW1lZGlhdGUgPT09ICdmdW5jdGlvbicpIHsKICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gc2V0SW1tZWRpYXRlOwogICAgdXRpbC5uZXh0VGljayA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7CiAgICAgIHJldHVybiBzZXRJbW1lZGlhdGUoY2FsbGJhY2spOwogICAgfTsKICAgIHJldHVybjsKICB9CgogIC8qIE5vdGU6IEEgcG9seWZpbGwgdXBncmFkZSBwYXR0ZXJuIGlzIHVzZWQgaGVyZSB0byBhbGxvdyBjb21iaW5pbmcKICBwb2x5ZmlsbHMuIEZvciBleGFtcGxlLCBNdXRhdGlvbk9ic2VydmVyIGlzIGZhc3QsIGJ1dCBibG9ja3MgVUkgdXBkYXRlcywKICBzbyBpdCBuZWVkcyB0byBhbGxvdyBVSSB1cGRhdGVzIHBlcmlvZGljYWxseSwgc28gaXQgZmFsbHMgYmFjayBvbgogIHBvc3RNZXNzYWdlIG9yIHNldFRpbWVvdXQuICovCgogIC8vIHBvbHlmaWxsIHdpdGggc2V0VGltZW91dAogIHV0aWwuc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgIHNldFRpbWVvdXQoY2FsbGJhY2ssIDApOwogIH07CgogIC8vIHVwZ3JhZGUgcG9seWZpbGwgdG8gdXNlIHBvc3RNZXNzYWdlCiAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYKICAgIHR5cGVvZiB3aW5kb3cucG9zdE1lc3NhZ2UgPT09ICdmdW5jdGlvbicpIHsKICAgIHZhciBtc2cgPSAnZm9yZ2Uuc2V0SW1tZWRpYXRlJzsKICAgIHZhciBjYWxsYmFja3MgPSBbXTsKICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgICAgY2FsbGJhY2tzLnB1c2goY2FsbGJhY2spOwogICAgICAvLyBvbmx5IHNlbmQgbWVzc2FnZSB3aGVuIG9uZSBoYXNuJ3QgYmVlbiBzZW50IGluCiAgICAgIC8vIHRoZSBjdXJyZW50IHR1cm4gb2YgdGhlIGV2ZW50IGxvb3AKICAgICAgaWYoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMSkgewogICAgICAgIHdpbmRvdy5wb3N0TWVzc2FnZShtc2csICcqJyk7CiAgICAgIH0KICAgIH07CiAgICBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50KSB7CiAgICAgIGlmKGV2ZW50LnNvdXJjZSA9PT0gd2luZG93ICYmIGV2ZW50LmRhdGEgPT09IG1zZykgewogICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgICAgIHZhciBjb3B5ID0gY2FsbGJhY2tzLnNsaWNlKCk7CiAgICAgICAgY2FsbGJhY2tzLmxlbmd0aCA9IDA7CiAgICAgICAgY29weS5mb3JFYWNoKGZ1bmN0aW9uKGNhbGxiYWNrKSB7CiAgICAgICAgICBjYWxsYmFjaygpOwogICAgICAgIH0pOwogICAgICB9CiAgICB9CiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGhhbmRsZXIsIHRydWUpOwogIH0KCiAgLy8gdXBncmFkZSBwb2x5ZmlsbCB0byB1c2UgTXV0YXRpb25PYnNlcnZlcgogIGlmKHR5cGVvZiBNdXRhdGlvbk9ic2VydmVyICE9PSAndW5kZWZpbmVkJykgewogICAgLy8gcG9seWZpbGwgd2l0aCBNdXRhdGlvbk9ic2VydmVyCiAgICB2YXIgbm93ID0gRGF0ZS5ub3coKTsKICAgIHZhciBhdHRyID0gdHJ1ZTsKICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICAgIHZhciBjYWxsYmFja3MgPSBbXTsKICAgIG5ldyBNdXRhdGlvbk9ic2VydmVyKGZ1bmN0aW9uKCkgewogICAgICB2YXIgY29weSA9IGNhbGxiYWNrcy5zbGljZSgpOwogICAgICBjYWxsYmFja3MubGVuZ3RoID0gMDsKICAgICAgY29weS5mb3JFYWNoKGZ1bmN0aW9uKGNhbGxiYWNrKSB7CiAgICAgICAgY2FsbGJhY2soKTsKICAgICAgfSk7CiAgICB9KS5vYnNlcnZlKGRpdiwge2F0dHJpYnV0ZXM6IHRydWV9KTsKICAgIHZhciBvbGRTZXRJbW1lZGlhdGUgPSB1dGlsLnNldEltbWVkaWF0ZTsKICAgIHV0aWwuc2V0SW1tZWRpYXRlID0gZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgICAgaWYoRGF0ZS5ub3coKSAtIG5vdyA+IDE1KSB7CiAgICAgICAgbm93ID0gRGF0ZS5ub3coKTsKICAgICAgICBvbGRTZXRJbW1lZGlhdGUoY2FsbGJhY2spOwogICAgICB9IGVsc2UgewogICAgICAgIGNhbGxiYWNrcy5wdXNoKGNhbGxiYWNrKTsKICAgICAgICAvLyBvbmx5IHRyaWdnZXIgb2JzZXJ2ZXIgd2hlbiBpdCBoYXNuJ3QgYmVlbiB0cmlnZ2VyZWQgaW4KICAgICAgICAvLyB0aGUgY3VycmVudCB0dXJuIG9mIHRoZSBldmVudCBsb29wCiAgICAgICAgaWYoY2FsbGJhY2tzLmxlbmd0aCA9PT0gMSkgewogICAgICAgICAgZGl2LnNldEF0dHJpYnV0ZSgnYScsIGF0dHIgPSAhYXR0cik7CiAgICAgICAgfQogICAgICB9CiAgICB9OwogIH0KCiAgdXRpbC5uZXh0VGljayA9IHV0aWwuc2V0SW1tZWRpYXRlOwp9KSgpOwoKLy8gZGVmaW5lIGlzQXJyYXkKdXRpbC5pc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbih4KSB7CiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh4KSA9PT0gJ1tvYmplY3QgQXJyYXldJzsKfTsKCi8vIGRlZmluZSBpc0FycmF5QnVmZmVyCnV0aWwuaXNBcnJheUJ1ZmZlciA9IGZ1bmN0aW9uKHgpIHsKICByZXR1cm4gdHlwZW9mIEFycmF5QnVmZmVyICE9PSAndW5kZWZpbmVkJyAmJiB4IGluc3RhbmNlb2YgQXJyYXlCdWZmZXI7Cn07CgovLyBkZWZpbmUgaXNBcnJheUJ1ZmZlclZpZXcKdXRpbC5pc0FycmF5QnVmZmVyVmlldyA9IGZ1bmN0aW9uKHgpIHsKICByZXR1cm4geCAmJiB1dGlsLmlzQXJyYXlCdWZmZXIoeC5idWZmZXIpICYmIHguYnl0ZUxlbmd0aCAhPT0gdW5kZWZpbmVkOwp9OwoKLy8gVE9ETzogc2V0IEJ5dGVCdWZmZXIgdG8gYmVzdCBhdmFpbGFibGUgYmFja2luZwp1dGlsLkJ5dGVCdWZmZXIgPSBCeXRlU3RyaW5nQnVmZmVyOwoKLyoqIEJ1ZmZlciB3L0JpbmFyeVN0cmluZyBiYWNraW5nICovCgovKioKICogQ29uc3RydWN0b3IgZm9yIGEgYmluYXJ5IHN0cmluZyBiYWNrZWQgYnl0ZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBbYl0gdGhlIGJ5dGVzIHRvIHdyYXAgKGVpdGhlciBlbmNvZGVkIGFzIHN0cmluZywgb25lIGJ5dGUgcGVyCiAqICAgICAgICAgIGNoYXJhY3Rlciwgb3IgYXMgYW4gQXJyYXlCdWZmZXIgb3IgVHlwZWQgQXJyYXkpLgogKi8KZnVuY3Rpb24gQnl0ZVN0cmluZ0J1ZmZlcihiKSB7CiAgLy8gVE9ETzogdXBkYXRlIHRvIG1hdGNoIERhdGFCdWZmZXIgQVBJCgogIC8vIHRoZSBkYXRhIGluIHRoaXMgYnVmZmVyCiAgdGhpcy5kYXRhID0gJyc7CiAgLy8gdGhlIHBvaW50ZXIgZm9yIHJlYWRpbmcgZnJvbSB0aGlzIGJ1ZmZlcgogIHRoaXMucmVhZCA9IDA7CgogIGlmKHR5cGVvZiBiID09PSAnc3RyaW5nJykgewogICAgdGhpcy5kYXRhID0gYjsKICB9IGVsc2UgaWYodXRpbC5pc0FycmF5QnVmZmVyKGIpIHx8IHV0aWwuaXNBcnJheUJ1ZmZlclZpZXcoYikpIHsKICAgIC8vIGNvbnZlcnQgbmF0aXZlIGJ1ZmZlciB0byBmb3JnZSBidWZmZXIKICAgIC8vIEZJWE1FOiBzdXBwb3J0IG5hdGl2ZSBidWZmZXJzIGludGVybmFsbHkgaW5zdGVhZAogICAgdmFyIGFyciA9IG5ldyBVaW50OEFycmF5KGIpOwogICAgdHJ5IHsKICAgICAgdGhpcy5kYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBhcnIpOwogICAgfSBjYXRjaChlKSB7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyArK2kpIHsKICAgICAgICB0aGlzLnB1dEJ5dGUoYXJyW2ldKTsKICAgICAgfQogICAgfQogIH0gZWxzZSBpZihiIGluc3RhbmNlb2YgQnl0ZVN0cmluZ0J1ZmZlciB8fAogICAgKHR5cGVvZiBiID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgYi5kYXRhID09PSAnc3RyaW5nJyAmJgogICAgdHlwZW9mIGIucmVhZCA9PT0gJ251bWJlcicpKSB7CiAgICAvLyBjb3B5IGV4aXN0aW5nIGJ1ZmZlcgogICAgdGhpcy5kYXRhID0gYi5kYXRhOwogICAgdGhpcy5yZWFkID0gYi5yZWFkOwogIH0KCiAgLy8gdXNlZCBmb3Igdjggb3B0aW1pemF0aW9uCiAgdGhpcy5fY29uc3RydWN0ZWRTdHJpbmdMZW5ndGggPSAwOwp9CnV0aWwuQnl0ZVN0cmluZ0J1ZmZlciA9IEJ5dGVTdHJpbmdCdWZmZXI7CgovKiBOb3RlOiBUaGlzIGlzIGFuIG9wdGltaXphdGlvbiBmb3IgVjgtYmFzZWQgYnJvd3NlcnMuIFdoZW4gVjggY29uY2F0ZW5hdGVzCiAgYSBzdHJpbmcsIHRoZSBzdHJpbmdzIGFyZSBvbmx5IGpvaW5lZCBsb2dpY2FsbHkgdXNpbmcgYSAiY29ucyBzdHJpbmciIG9yCiAgImNvbnN0cnVjdGVkL2NvbmNhdGVuYXRlZCBzdHJpbmciLiBUaGVzZSBjb250YWluZXJzIGtlZXAgcmVmZXJlbmNlcyB0byBvbmUKICBhbm90aGVyIGFuZCBjYW4gcmVzdWx0IGluIHZlcnkgbGFyZ2UgbWVtb3J5IHVzYWdlLiBGb3IgZXhhbXBsZSwgaWYgYSAyTUIKICBzdHJpbmcgaXMgY29uc3RydWN0ZWQgYnkgY29uY2F0ZW5hdGluZyA0IGJ5dGVzIHRvZ2V0aGVyIGF0IGEgdGltZSwgdGhlCiAgbWVtb3J5IHVzYWdlIHdpbGwgYmUgfjQ0TUI7IHNvIH4yMnggaW5jcmVhc2UuIFRoZSBzdHJpbmdzIGFyZSBvbmx5IGpvaW5lZAogIHRvZ2V0aGVyIHdoZW4gYW4gb3BlcmF0aW9uIHJlcXVpcmluZyB0aGVpciBqb2luaW5nIHRha2VzIHBsYWNlLCBzdWNoIGFzCiAgc3Vic3RyKCkuIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW4gYWRkaW5nIGRhdGEgdG8gdGhpcyBidWZmZXIgdG8gZW5zdXJlCiAgdGhlc2UgdHlwZXMgb2Ygc3RyaW5ncyBhcmUgcGVyaW9kaWNhbGx5IGpvaW5lZCB0byByZWR1Y2UgdGhlIG1lbW9yeQogIGZvb3RwcmludC4gKi8KdmFyIF9NQVhfQ09OU1RSVUNURURfU1RSSU5HX0xFTkdUSCA9IDQwOTY7CnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUuX29wdGltaXplQ29uc3RydWN0ZWRTdHJpbmcgPSBmdW5jdGlvbih4KSB7CiAgdGhpcy5fY29uc3RydWN0ZWRTdHJpbmdMZW5ndGggKz0geDsKICBpZih0aGlzLl9jb25zdHJ1Y3RlZFN0cmluZ0xlbmd0aCA+IF9NQVhfQ09OU1RSVUNURURfU1RSSU5HX0xFTkdUSCkgewogICAgLy8gdGhpcyBzdWJzdHIoKSBzaG91bGQgY2F1c2UgdGhlIGNvbnN0cnVjdGVkIHN0cmluZyB0byBqb2luCiAgICB0aGlzLmRhdGEuc3Vic3RyKDAsIDEpOwogICAgdGhpcy5fY29uc3RydWN0ZWRTdHJpbmdMZW5ndGggPSAwOwogIH0KfTsKCi8qKgogKiBHZXRzIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUubGVuZ3RoID0gZnVuY3Rpb24oKSB7CiAgcmV0dXJuIHRoaXMuZGF0YS5sZW5ndGggLSB0aGlzLnJlYWQ7Cn07CgovKioKICogR2V0cyB3aGV0aGVyIG9yIG5vdCB0aGlzIGJ1ZmZlciBpcyBlbXB0eS4KICoKICogQHJldHVybiB0cnVlIGlmIHRoaXMgYnVmZmVyIGlzIGVtcHR5LCBmYWxzZSBpZiBub3QuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmlzRW1wdHkgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gdGhpcy5sZW5ndGgoKSA8PSAwOwp9OwoKLyoqCiAqIFB1dHMgYSBieXRlIGluIHRoaXMgYnVmZmVyLgogKgogKiBAcGFyYW0gYiB0aGUgYnl0ZSB0byBwdXQuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dEJ5dGUgPSBmdW5jdGlvbihiKSB7CiAgcmV0dXJuIHRoaXMucHV0Qnl0ZXMoU3RyaW5nLmZyb21DaGFyQ29kZShiKSk7Cn07CgovKioKICogUHV0cyBhIGJ5dGUgaW4gdGhpcyBidWZmZXIgTiB0aW1lcy4KICoKICogQHBhcmFtIGIgdGhlIGJ5dGUgdG8gcHV0LgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIG9mIHZhbHVlIGIgdG8gcHV0LgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5maWxsV2l0aEJ5dGUgPSBmdW5jdGlvbihiLCBuKSB7CiAgYiA9IFN0cmluZy5mcm9tQ2hhckNvZGUoYik7CiAgdmFyIGQgPSB0aGlzLmRhdGE7CiAgd2hpbGUobiA+IDApIHsKICAgIGlmKG4gJiAxKSB7CiAgICAgIGQgKz0gYjsKICAgIH0KICAgIG4gPj4+PSAxOwogICAgaWYobiA+IDApIHsKICAgICAgYiArPSBiOwogICAgfQogIH0KICB0aGlzLmRhdGEgPSBkOwogIHRoaXMuX29wdGltaXplQ29uc3RydWN0ZWRTdHJpbmcobik7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBieXRlcyBpbiB0aGlzIGJ1ZmZlci4KICoKICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyAoYXMgYSBVVEYtOCBlbmNvZGVkIHN0cmluZykgdG8gcHV0LgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5wdXRCeXRlcyA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgdGhpcy5kYXRhICs9IGJ5dGVzOwogIHRoaXMuX29wdGltaXplQ29uc3RydWN0ZWRTdHJpbmcoYnl0ZXMubGVuZ3RoKTsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBQdXRzIGEgVVRGLTE2IGVuY29kZWQgc3RyaW5nIGludG8gdGhpcyBidWZmZXIuCiAqCiAqIEBwYXJhbSBzdHIgdGhlIHN0cmluZyB0byBwdXQuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dFN0cmluZyA9IGZ1bmN0aW9uKHN0cikgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKHV0aWwuZW5jb2RlVXRmOChzdHIpKTsKfTsKCi8qKgogKiBQdXRzIGEgMTYtYml0IGludGVnZXIgaW4gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlci4KICoKICogQHBhcmFtIGkgdGhlIDE2LWJpdCBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5wdXRJbnQxNiA9IGZ1bmN0aW9uKGkpIHsKICByZXR1cm4gdGhpcy5wdXRCeXRlcygKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiA4ICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpICYgMHhGRikpOwp9OwoKLyoqCiAqIFB1dHMgYSAyNC1iaXQgaW50ZWdlciBpbiB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyLgogKgogKiBAcGFyYW0gaSB0aGUgMjQtYml0IGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dEludDI0ID0gZnVuY3Rpb24oaSkgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKAogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpID4+IDE2ICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpID4+IDggJiAweEZGKSArCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgJiAweEZGKSk7Cn07CgovKioKICogUHV0cyBhIDMyLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAzMi1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUucHV0SW50MzIgPSBmdW5jdGlvbihpKSB7CiAgcmV0dXJuIHRoaXMucHV0Qnl0ZXMoCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgPj4gMjQgJiAweEZGKSArCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgPj4gMTYgJiAweEZGKSArCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgPj4gOCAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSAmIDB4RkYpKTsKfTsKCi8qKgogKiBQdXRzIGEgMTYtYml0IGludGVnZXIgaW4gdGhpcyBidWZmZXIgaW4gbGl0dGxlLWVuZGlhbiBvcmRlci4KICoKICogQHBhcmFtIGkgdGhlIDE2LWJpdCBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5wdXRJbnQxNkxlID0gZnVuY3Rpb24oaSkgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKAogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpID4+IDggJiAweEZGKSk7Cn07CgovKioKICogUHV0cyBhIDI0LWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAyNC1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUucHV0SW50MjRMZSA9IGZ1bmN0aW9uKGkpIHsKICByZXR1cm4gdGhpcy5wdXRCeXRlcygKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiA4ICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpID4+IDE2ICYgMHhGRikpOwp9OwoKLyoqCiAqIFB1dHMgYSAzMi1iaXQgaW50ZWdlciBpbiB0aGlzIGJ1ZmZlciBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyLgogKgogKiBAcGFyYW0gaSB0aGUgMzItYml0IGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dEludDMyTGUgPSBmdW5jdGlvbihpKSB7CiAgcmV0dXJuIHRoaXMucHV0Qnl0ZXMoCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgJiAweEZGKSArCiAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKGkgPj4gOCAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiAxNiAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiAyNCAmIDB4RkYpKTsKfTsKCi8qKgogKiBQdXRzIGFuIG4tYml0IGludGVnZXIgaW4gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlci4KICoKICogQHBhcmFtIGkgdGhlIG4tYml0IGludGVnZXIuCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUucHV0SW50ID0gZnVuY3Rpb24oaSwgbikgewogIHZhciBieXRlcyA9ICcnOwogIGRvIHsKICAgIG4gLT0gODsKICAgIGJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKGkgPj4gbikgJiAweEZGKTsKICB9IHdoaWxlKG4gPiAwKTsKICByZXR1cm4gdGhpcy5wdXRCeXRlcyhieXRlcyk7Cn07CgovKioKICogUHV0cyBhIHNpZ25lZCBuLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuIFR3bydzCiAqIGNvbXBsZW1lbnQgcmVwcmVzZW50YXRpb24gaXMgdXNlZC4KICoKICogQHBhcmFtIGkgdGhlIG4tYml0IGludGVnZXIuCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUucHV0U2lnbmVkSW50ID0gZnVuY3Rpb24oaSwgbikgewogIGlmKGkgPCAwKSB7CiAgICBpICs9IDIgPDwgKG4gLSAxKTsKICB9CiAgcmV0dXJuIHRoaXMucHV0SW50KGksIG4pOwp9OwoKLyoqCiAqIFB1dHMgdGhlIGdpdmVuIGJ1ZmZlciBpbnRvIHRoaXMgYnVmZmVyLgogKgogKiBAcGFyYW0gYnVmZmVyIHRoZSBidWZmZXIgdG8gcHV0IGludG8gdGhpcyBvbmUuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnB1dEJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKGJ1ZmZlci5nZXRCeXRlcygpKTsKfTsKCi8qKgogKiBHZXRzIGEgYnl0ZSBmcm9tIHRoaXMgYnVmZmVyIGFuZCBhZHZhbmNlcyB0aGUgcmVhZCBwb2ludGVyIGJ5IDEuCiAqCiAqIEByZXR1cm4gdGhlIGJ5dGUuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldEJ5dGUgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkKyspOwp9OwoKLyoqCiAqIEdldHMgYSB1aW50MTYgZnJvbSB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyIGFuZCBhZHZhbmNlcyB0aGUgcmVhZAogKiBwb2ludGVyIGJ5IDIuCiAqCiAqIEByZXR1cm4gdGhlIHVpbnQxNi4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUuZ2V0SW50MTYgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9ICgKICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCkgPDwgOCBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAxKSk7CiAgdGhpcy5yZWFkICs9IDI7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQyNCBmcm9tIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMy4KICoKICogQHJldHVybiB0aGUgdWludDI0LgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQyNCA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gKAogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkKSA8PCAxNiBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAxKSA8PCA4IF4KICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCArIDIpKTsKICB0aGlzLnJlYWQgKz0gMzsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGEgdWludDMyIGZyb20gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlciBhbmQgYWR2YW5jZXMgdGhlIHJlYWQKICogcG9pbnRlciBieSA0LgogKgogKiBAcmV0dXJuIHRoZSB3b3JkLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQzMiA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gKAogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkKSA8PCAyNCBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAxKSA8PCAxNiBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAyKSA8PCA4IF4KICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCArIDMpKTsKICB0aGlzLnJlYWQgKz0gNDsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGEgdWludDE2IGZyb20gdGhpcyBidWZmZXIgaW4gbGl0dGxlLWVuZGlhbiBvcmRlciBhbmQgYWR2YW5jZXMgdGhlIHJlYWQKICogcG9pbnRlciBieSAyLgogKgogKiBAcmV0dXJuIHRoZSB1aW50MTYuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldEludDE2TGUgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9ICgKICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCkgXgogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkICsgMSkgPDwgOCk7CiAgdGhpcy5yZWFkICs9IDI7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQyNCBmcm9tIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMy4KICoKICogQHJldHVybiB0aGUgdWludDI0LgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQyNExlID0gZnVuY3Rpb24oKSB7CiAgdmFyIHJ2YWwgPSAoCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQpIF4KICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCArIDEpIDw8IDggXgogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkICsgMikgPDwgMTYpOwogIHRoaXMucmVhZCArPSAzOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEdldHMgYSB1aW50MzIgZnJvbSB0aGlzIGJ1ZmZlciBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyIGFuZCBhZHZhbmNlcyB0aGUgcmVhZAogKiBwb2ludGVyIGJ5IDQuCiAqCiAqIEByZXR1cm4gdGhlIHdvcmQuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldEludDMyTGUgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9ICgKICAgIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCkgXgogICAgdGhpcy5kYXRhLmNoYXJDb2RlQXQodGhpcy5yZWFkICsgMSkgPDwgOCBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAyKSA8PCAxNiBeCiAgICB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQgKyAzKSA8PCAyNCk7CiAgdGhpcy5yZWFkICs9IDQ7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhbiBuLWJpdCBpbnRlZ2VyIGZyb20gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlciBhbmQgYWR2YW5jZXMgdGhlCiAqIHJlYWQgcG9pbnRlciBieSBuLzguCiAqCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGUgaW50ZWdlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUuZ2V0SW50ID0gZnVuY3Rpb24obikgewogIHZhciBydmFsID0gMDsKICBkbyB7CiAgICBydmFsID0gKHJ2YWwgPDwgOCkgKyB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLnJlYWQrKyk7CiAgICBuIC09IDg7CiAgfSB3aGlsZShuID4gMCk7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHNpZ25lZCBuLWJpdCBpbnRlZ2VyIGZyb20gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlciwgdXNpbmcKICogdHdvJ3MgY29tcGxlbWVudCwgYW5kIGFkdmFuY2VzIHRoZSByZWFkIHBvaW50ZXIgYnkgbi84LgogKgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhlIGludGVnZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldFNpZ25lZEludCA9IGZ1bmN0aW9uKG4pIHsKICB2YXIgeCA9IHRoaXMuZ2V0SW50KG4pOwogIHZhciBtYXggPSAyIDw8IChuIC0gMik7CiAgaWYoeCA+PSBtYXgpIHsKICAgIHggLT0gbWF4IDw8IDE7CiAgfQogIHJldHVybiB4Owp9OwoKLyoqCiAqIFJlYWRzIGJ5dGVzIG91dCBpbnRvIGEgVVRGLTggc3RyaW5nIGFuZCBjbGVhcnMgdGhlbSBmcm9tIHRoZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIHJlYWQsIHVuZGVmaW5lZCBvciBudWxsIGZvciBhbGwuCiAqCiAqIEByZXR1cm4gYSBVVEYtOCBzdHJpbmcgb2YgYnl0ZXMuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmdldEJ5dGVzID0gZnVuY3Rpb24oY291bnQpIHsKICB2YXIgcnZhbDsKICBpZihjb3VudCkgewogICAgLy8gcmVhZCBjb3VudCBieXRlcwogICAgY291bnQgPSBNYXRoLm1pbih0aGlzLmxlbmd0aCgpLCBjb3VudCk7CiAgICBydmFsID0gdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCwgdGhpcy5yZWFkICsgY291bnQpOwogICAgdGhpcy5yZWFkICs9IGNvdW50OwogIH0gZWxzZSBpZihjb3VudCA9PT0gMCkgewogICAgcnZhbCA9ICcnOwogIH0gZWxzZSB7CiAgICAvLyByZWFkIGFsbCBieXRlcywgb3B0aW1pemUgdG8gb25seSBjb3B5IHdoZW4gbmVlZGVkCiAgICBydmFsID0gKHRoaXMucmVhZCA9PT0gMCkgPyB0aGlzLmRhdGEgOiB0aGlzLmRhdGEuc2xpY2UodGhpcy5yZWFkKTsKICAgIHRoaXMuY2xlYXIoKTsKICB9CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIFVURi04IGVuY29kZWQgc3RyaW5nIG9mIHRoZSBieXRlcyBmcm9tIHRoaXMgYnVmZmVyIHdpdGhvdXQgbW9kaWZ5aW5nCiAqIHRoZSByZWFkIHBvaW50ZXIuCiAqCiAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGdldCwgb21pdCB0byBnZXQgYWxsLgogKgogKiBAcmV0dXJuIGEgc3RyaW5nIGZ1bGwgb2YgVVRGLTggZW5jb2RlZCBjaGFyYWN0ZXJzLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5ieXRlcyA9IGZ1bmN0aW9uKGNvdW50KSB7CiAgcmV0dXJuICh0eXBlb2YoY291bnQpID09PSAndW5kZWZpbmVkJyA/CiAgICB0aGlzLmRhdGEuc2xpY2UodGhpcy5yZWFkKSA6CiAgICB0aGlzLmRhdGEuc2xpY2UodGhpcy5yZWFkLCB0aGlzLnJlYWQgKyBjb3VudCkpOwp9OwoKLyoqCiAqIEdldHMgYSBieXRlIGF0IHRoZSBnaXZlbiBpbmRleCB3aXRob3V0IG1vZGlmeWluZyB0aGUgcmVhZCBwb2ludGVyLgogKgogKiBAcGFyYW0gaSB0aGUgYnl0ZSBpbmRleC4KICoKICogQHJldHVybiB0aGUgYnl0ZS4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUuYXQgPSBmdW5jdGlvbihpKSB7CiAgcmV0dXJuIHRoaXMuZGF0YS5jaGFyQ29kZUF0KHRoaXMucmVhZCArIGkpOwp9OwoKLyoqCiAqIFB1dHMgYSBieXRlIGF0IHRoZSBnaXZlbiBpbmRleCB3aXRob3V0IG1vZGlmeWluZyB0aGUgcmVhZCBwb2ludGVyLgogKgogKiBAcGFyYW0gaSB0aGUgYnl0ZSBpbmRleC4KICogQHBhcmFtIGIgdGhlIGJ5dGUgdG8gcHV0LgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5zZXRBdCA9IGZ1bmN0aW9uKGksIGIpIHsKICB0aGlzLmRhdGEgPSB0aGlzLmRhdGEuc3Vic3RyKDAsIHRoaXMucmVhZCArIGkpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoYikgKwogICAgdGhpcy5kYXRhLnN1YnN0cih0aGlzLnJlYWQgKyBpICsgMSk7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogR2V0cyB0aGUgbGFzdCBieXRlIHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSByZWFkIHBvaW50ZXIuCiAqCiAqIEByZXR1cm4gdGhlIGxhc3QgYnl0ZS4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUubGFzdCA9IGZ1bmN0aW9uKCkgewogIHJldHVybiB0aGlzLmRhdGEuY2hhckNvZGVBdCh0aGlzLmRhdGEubGVuZ3RoIC0gMSk7Cn07CgovKioKICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIGNvcHkuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbigpIHsKICB2YXIgYyA9IHV0aWwuY3JlYXRlQnVmZmVyKHRoaXMuZGF0YSk7CiAgYy5yZWFkID0gdGhpcy5yZWFkOwogIHJldHVybiBjOwp9OwoKLyoqCiAqIENvbXBhY3RzIHRoaXMgYnVmZmVyLgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5CeXRlU3RyaW5nQnVmZmVyLnByb3RvdHlwZS5jb21wYWN0ID0gZnVuY3Rpb24oKSB7CiAgaWYodGhpcy5yZWFkID4gMCkgewogICAgdGhpcy5kYXRhID0gdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCk7CiAgICB0aGlzLnJlYWQgPSAwOwogIH0KICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBDbGVhcnMgdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5kYXRhID0gJyc7CiAgdGhpcy5yZWFkID0gMDsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBTaG9ydGVucyB0aGlzIGJ1ZmZlciBieSB0cmltaW5nIGJ5dGVzIG9mZiBvZiB0aGUgZW5kIG9mIHRoaXMgYnVmZmVyLgogKgogKiBAcGFyYW0gY291bnQgdGhlIG51bWJlciBvZiBieXRlcyB0byB0cmltIG9mZi4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuQnl0ZVN0cmluZ0J1ZmZlci5wcm90b3R5cGUudHJ1bmNhdGUgPSBmdW5jdGlvbihjb3VudCkgewogIHZhciBsZW4gPSBNYXRoLm1heCgwLCB0aGlzLmxlbmd0aCgpIC0gY291bnQpOwogIHRoaXMuZGF0YSA9IHRoaXMuZGF0YS5zdWJzdHIodGhpcy5yZWFkLCBsZW4pOwogIHRoaXMucmVhZCA9IDA7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogQ29udmVydHMgdGhpcyBidWZmZXIgdG8gYSBoZXhhZGVjaW1hbCBzdHJpbmcuCiAqCiAqIEByZXR1cm4gYSBoZXhhZGVjaW1hbCBzdHJpbmcuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnRvSGV4ID0gZnVuY3Rpb24oKSB7CiAgdmFyIHJ2YWwgPSAnJzsKICBmb3IodmFyIGkgPSB0aGlzLnJlYWQ7IGkgPCB0aGlzLmRhdGEubGVuZ3RoOyArK2kpIHsKICAgIHZhciBiID0gdGhpcy5kYXRhLmNoYXJDb2RlQXQoaSk7CiAgICBpZihiIDwgMTYpIHsKICAgICAgcnZhbCArPSAnMCc7CiAgICB9CiAgICBydmFsICs9IGIudG9TdHJpbmcoMTYpOwogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDb252ZXJ0cyB0aGlzIGJ1ZmZlciB0byBhIFVURi0xNiBzdHJpbmcgKHN0YW5kYXJkIEphdmFTY3JpcHQgc3RyaW5nKS4KICoKICogQHJldHVybiBhIFVURi0xNiBzdHJpbmcuCiAqLwp1dGlsLkJ5dGVTdHJpbmdCdWZmZXIucHJvdG90eXBlLnRvU3RyaW5nID0gZnVuY3Rpb24oKSB7CiAgcmV0dXJuIHV0aWwuZGVjb2RlVXRmOCh0aGlzLmJ5dGVzKCkpOwp9OwoKLyoqIEVuZCBCdWZmZXIgdy9CaW5hcnlTdHJpbmcgYmFja2luZyAqLwoKCi8qKiBCdWZmZXIgdy9VSW50OEFycmF5IGJhY2tpbmcgKi8KCi8qKgogKiBGSVhNRTogRXhwZXJpbWVudGFsLiBEbyBub3QgdXNlIHlldC4KICoKICogQ29uc3RydWN0b3IgZm9yIGFuIEFycmF5QnVmZmVyLWJhY2tlZCBieXRlIGJ1ZmZlci4KICoKICogVGhlIGJ1ZmZlciBtYXkgYmUgY29uc3RydWN0ZWQgZnJvbSBhIHN0cmluZywgYW4gQXJyYXlCdWZmZXIsIERhdGFWaWV3LCBvciBhCiAqIFR5cGVkQXJyYXkuCiAqCiAqIElmIGEgc3RyaW5nIGlzIGdpdmVuLCBpdHMgZW5jb2Rpbmcgc2hvdWxkIGJlIHByb3ZpZGVkIGFzIGFuIG9wdGlvbiwKICogb3RoZXJ3aXNlIGl0IHdpbGwgZGVmYXVsdCB0byAnYmluYXJ5Jy4gQSAnYmluYXJ5JyBzdHJpbmcgaXMgZW5jb2RlZCBzdWNoCiAqIHRoYXQgZWFjaCBjaGFyYWN0ZXIgaXMgb25lIGJ5dGUgaW4gbGVuZ3RoIGFuZCBzaXplLgogKgogKiBJZiBhbiBBcnJheUJ1ZmZlciwgRGF0YVZpZXcsIG9yIFR5cGVkQXJyYXkgaXMgZ2l2ZW4sIGl0IHdpbGwgYmUgdXNlZAogKiAqZGlyZWN0bHkqIHdpdGhvdXQgYW55IGNvcHlpbmcuIE5vdGUgdGhhdCwgaWYgYSB3cml0ZSB0byB0aGUgYnVmZmVyIHJlcXVpcmVzCiAqIG1vcmUgc3BhY2UsIHRoZSBidWZmZXIgd2lsbCBhbGxvY2F0ZSBhIG5ldyBiYWNraW5nIEFycmF5QnVmZmVyIHRvCiAqIGFjY29tbW9kYXRlLiBUaGUgc3RhcnRpbmcgcmVhZCBhbmQgd3JpdGUgb2Zmc2V0cyBmb3IgdGhlIGJ1ZmZlciBtYXkgYmUKICogZ2l2ZW4gYXMgb3B0aW9ucy4KICoKICogQHBhcmFtIFtiXSB0aGUgaW5pdGlhbCBieXRlcyBmb3IgdGhpcyBidWZmZXIuCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgW3JlYWRPZmZzZXRdIHRoZSBzdGFydGluZyByZWFkIG9mZnNldCB0byB1c2UgKGRlZmF1bHQ6IDApLgogKiAgICAgICAgICBbd3JpdGVPZmZzZXRdIHRoZSBzdGFydGluZyB3cml0ZSBvZmZzZXQgdG8gdXNlIChkZWZhdWx0OiB0aGUKICogICAgICAgICAgICBsZW5ndGggb2YgdGhlIGZpcnN0IHBhcmFtZXRlcikuCiAqICAgICAgICAgIFtncm93U2l6ZV0gdGhlIG1pbmltdW0gYW1vdW50LCBpbiBieXRlcywgdG8gZ3JvdyB0aGUgYnVmZmVyIGJ5IHRvCiAqICAgICAgICAgICAgYWNjb21tb2RhdGUgd3JpdGVzIChkZWZhdWx0OiAxMDI0KS4KICogICAgICAgICAgW2VuY29kaW5nXSB0aGUgZW5jb2RpbmcgKCdiaW5hcnknLCAndXRmOCcsICd1dGYxNicsICdoZXgnKSBmb3IgdGhlCiAqICAgICAgICAgICAgZmlyc3QgcGFyYW1ldGVyLCBpZiBpdCBpcyBhIHN0cmluZyAoZGVmYXVsdDogJ2JpbmFyeScpLgogKi8KZnVuY3Rpb24gRGF0YUJ1ZmZlcihiLCBvcHRpb25zKSB7CiAgLy8gZGVmYXVsdCBvcHRpb25zCiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CgogIC8vIHBvaW50ZXJzIGZvciByZWFkIGZyb20vd3JpdGUgdG8gYnVmZmVyCiAgdGhpcy5yZWFkID0gb3B0aW9ucy5yZWFkT2Zmc2V0IHx8IDA7CiAgdGhpcy5ncm93U2l6ZSA9IG9wdGlvbnMuZ3Jvd1NpemUgfHwgMTAyNDsKCiAgdmFyIGlzQXJyYXlCdWZmZXIgPSB1dGlsLmlzQXJyYXlCdWZmZXIoYik7CiAgdmFyIGlzQXJyYXlCdWZmZXJWaWV3ID0gdXRpbC5pc0FycmF5QnVmZmVyVmlldyhiKTsKICBpZihpc0FycmF5QnVmZmVyIHx8IGlzQXJyYXlCdWZmZXJWaWV3KSB7CiAgICAvLyB1c2UgQXJyYXlCdWZmZXIgZGlyZWN0bHkKICAgIGlmKGlzQXJyYXlCdWZmZXIpIHsKICAgICAgdGhpcy5kYXRhID0gbmV3IERhdGFWaWV3KGIpOwogICAgfSBlbHNlIHsKICAgICAgLy8gVE9ETzogYWRqdXN0IHJlYWQvd3JpdGUgb2Zmc2V0IGJhc2VkIG9uIHRoZSB0eXBlIG9mIHZpZXcKICAgICAgLy8gb3Igc3BlY2lmeSB0aGF0IHRoaXMgbXVzdCBiZSBkb25lIGluIHRoZSBvcHRpb25zIC4uLiB0aGF0IHRoZQogICAgICAvLyBvZmZzZXRzIGFyZSBieXRlLWJhc2VkCiAgICAgIHRoaXMuZGF0YSA9IG5ldyBEYXRhVmlldyhiLmJ1ZmZlciwgYi5ieXRlT2Zmc2V0LCBiLmJ5dGVMZW5ndGgpOwogICAgfQogICAgdGhpcy53cml0ZSA9ICgnd3JpdGVPZmZzZXQnIGluIG9wdGlvbnMgPwogICAgICBvcHRpb25zLndyaXRlT2Zmc2V0IDogdGhpcy5kYXRhLmJ5dGVMZW5ndGgpOwogICAgcmV0dXJuOwogIH0KCiAgLy8gaW5pdGlhbGl6ZSB0byBlbXB0eSBhcnJheSBidWZmZXIgYW5kIGFkZCBhbnkgZ2l2ZW4gYnl0ZXMgdXNpbmcgcHV0Qnl0ZXMKICB0aGlzLmRhdGEgPSBuZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDApKTsKICB0aGlzLndyaXRlID0gMDsKCiAgaWYoYiAhPT0gbnVsbCAmJiBiICE9PSB1bmRlZmluZWQpIHsKICAgIHRoaXMucHV0Qnl0ZXMoYik7CiAgfQoKICBpZignd3JpdGVPZmZzZXQnIGluIG9wdGlvbnMpIHsKICAgIHRoaXMud3JpdGUgPSBvcHRpb25zLndyaXRlT2Zmc2V0OwogIH0KfQp1dGlsLkRhdGFCdWZmZXIgPSBEYXRhQnVmZmVyOwoKLyoqCiAqIEdldHMgdGhlIG51bWJlciBvZiBieXRlcyBpbiB0aGlzIGJ1ZmZlci4KICoKICogQHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbigpIHsKICByZXR1cm4gdGhpcy53cml0ZSAtIHRoaXMucmVhZDsKfTsKCi8qKgogKiBHZXRzIHdoZXRoZXIgb3Igbm90IHRoaXMgYnVmZmVyIGlzIGVtcHR5LgogKgogKiBAcmV0dXJuIHRydWUgaWYgdGhpcyBidWZmZXIgaXMgZW1wdHksIGZhbHNlIGlmIG5vdC4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uKCkgewogIHJldHVybiB0aGlzLmxlbmd0aCgpIDw9IDA7Cn07CgovKioKICogRW5zdXJlcyB0aGlzIGJ1ZmZlciBoYXMgZW5vdWdoIGVtcHR5IHNwYWNlIHRvIGFjY29tbW9kYXRlIHRoZSBnaXZlbiBudW1iZXIKICogb2YgYnl0ZXMuIEFuIG9wdGlvbmFsIHBhcmFtZXRlciBtYXkgYmUgZ2l2ZW4gdGhhdCBpbmRpY2F0ZXMgYSBtaW5pbXVtCiAqIGFtb3VudCB0byBncm93IHRoZSBidWZmZXIgaWYgbmVjZXNzYXJ5LiBJZiB0aGUgcGFyYW1ldGVyIGlzIG5vdCBnaXZlbiwKICogdGhlIGJ1ZmZlciB3aWxsIGJlIGdyb3duIGJ5IHNvbWUgcHJldmlvdXNseS1zcGVjaWZpZWQgZGVmYXVsdCBhbW91bnQKICogb3IgaGV1cmlzdGljLgogKgogKiBAcGFyYW0gYW1vdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gYWNjb21tb2RhdGUuCiAqIEBwYXJhbSBbZ3Jvd1NpemVdIHRoZSBtaW5pbXVtIGFtb3VudCwgaW4gYnl0ZXMsIHRvIGdyb3cgdGhlIGJ1ZmZlciBieSBpZgogKiAgICAgICAgICBuZWNlc3NhcnkuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLmFjY29tbW9kYXRlID0gZnVuY3Rpb24oYW1vdW50LCBncm93U2l6ZSkgewogIGlmKHRoaXMubGVuZ3RoKCkgPj0gYW1vdW50KSB7CiAgICByZXR1cm4gdGhpczsKICB9CiAgZ3Jvd1NpemUgPSBNYXRoLm1heChncm93U2l6ZSB8fCB0aGlzLmdyb3dTaXplLCBhbW91bnQpOwoKICAvLyBncm93IGJ1ZmZlcgogIHZhciBzcmMgPSBuZXcgVWludDhBcnJheSgKICAgIHRoaXMuZGF0YS5idWZmZXIsIHRoaXMuZGF0YS5ieXRlT2Zmc2V0LCB0aGlzLmRhdGEuYnl0ZUxlbmd0aCk7CiAgdmFyIGRzdCA9IG5ldyBVaW50OEFycmF5KHRoaXMubGVuZ3RoKCkgKyBncm93U2l6ZSk7CiAgZHN0LnNldChzcmMpOwogIHRoaXMuZGF0YSA9IG5ldyBEYXRhVmlldyhkc3QuYnVmZmVyKTsKCiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIGJ5dGUgaW4gdGhpcyBidWZmZXIuCiAqCiAqIEBwYXJhbSBiIHRoZSBieXRlIHRvIHB1dC4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0Qnl0ZSA9IGZ1bmN0aW9uKGIpIHsKICB0aGlzLmFjY29tbW9kYXRlKDEpOwogIHRoaXMuZGF0YS5zZXRVaW50OCh0aGlzLndyaXRlKyssIGIpOwogIHJldHVybiB0aGlzOwp9OwoKLyoqCiAqIFB1dHMgYSBieXRlIGluIHRoaXMgYnVmZmVyIE4gdGltZXMuCiAqCiAqIEBwYXJhbSBiIHRoZSBieXRlIHRvIHB1dC4KICogQHBhcmFtIG4gdGhlIG51bWJlciBvZiBieXRlcyBvZiB2YWx1ZSBiIHRvIHB1dC4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZmlsbFdpdGhCeXRlID0gZnVuY3Rpb24oYiwgbikgewogIHRoaXMuYWNjb21tb2RhdGUobik7CiAgZm9yKHZhciBpID0gMDsgaSA8IG47ICsraSkgewogICAgdGhpcy5kYXRhLnNldFVpbnQ4KGIpOwogIH0KICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBQdXRzIGJ5dGVzIGluIHRoaXMgYnVmZmVyLiBUaGUgYnl0ZXMgbWF5IGJlIGdpdmVuIGFzIGEgc3RyaW5nLCBhbgogKiBBcnJheUJ1ZmZlciwgYSBEYXRhVmlldywgb3IgYSBUeXBlZEFycmF5LgogKgogKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGVzIHRvIHB1dC4KICogQHBhcmFtIFtlbmNvZGluZ10gdGhlIGVuY29kaW5nIGZvciB0aGUgZmlyc3QgcGFyYW1ldGVyICgnYmluYXJ5JywgJ3V0ZjgnLAogKiAgICAgICAgICAndXRmMTYnLCAnaGV4JyksIGlmIGl0IGlzIGEgc3RyaW5nIChkZWZhdWx0OiAnYmluYXJ5JykuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dEJ5dGVzID0gZnVuY3Rpb24oYnl0ZXMsIGVuY29kaW5nKSB7CiAgaWYodXRpbC5pc0FycmF5QnVmZmVyVmlldyhieXRlcykpIHsKICAgIHZhciBzcmMgPSBuZXcgVWludDhBcnJheShieXRlcy5idWZmZXIsIGJ5dGVzLmJ5dGVPZmZzZXQsIGJ5dGVzLmJ5dGVMZW5ndGgpOwogICAgdmFyIGxlbiA9IHNyYy5ieXRlTGVuZ3RoIC0gc3JjLmJ5dGVPZmZzZXQ7CiAgICB0aGlzLmFjY29tbW9kYXRlKGxlbik7CiAgICB2YXIgZHN0ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5kYXRhLmJ1ZmZlciwgdGhpcy53cml0ZSk7CiAgICBkc3Quc2V0KHNyYyk7CiAgICB0aGlzLndyaXRlICs9IGxlbjsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgaWYodXRpbC5pc0FycmF5QnVmZmVyKGJ5dGVzKSkgewogICAgdmFyIHNyYyA9IG5ldyBVaW50OEFycmF5KGJ5dGVzKTsKICAgIHRoaXMuYWNjb21tb2RhdGUoc3JjLmJ5dGVMZW5ndGgpOwogICAgdmFyIGRzdCA9IG5ldyBVaW50OEFycmF5KHRoaXMuZGF0YS5idWZmZXIpOwogICAgZHN0LnNldChzcmMsIHRoaXMud3JpdGUpOwogICAgdGhpcy53cml0ZSArPSBzcmMuYnl0ZUxlbmd0aDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgLy8gYnl0ZXMgaXMgYSB1dGlsLkRhdGFCdWZmZXIgb3IgZXF1aXZhbGVudAogIGlmKGJ5dGVzIGluc3RhbmNlb2YgdXRpbC5EYXRhQnVmZmVyIHx8CiAgICAodHlwZW9mIGJ5dGVzID09PSAnb2JqZWN0JyAmJgogICAgdHlwZW9mIGJ5dGVzLnJlYWQgPT09ICdudW1iZXInICYmIHR5cGVvZiBieXRlcy53cml0ZSA9PT0gJ251bWJlcicgJiYKICAgIHV0aWwuaXNBcnJheUJ1ZmZlclZpZXcoYnl0ZXMuZGF0YSkpKSB7CiAgICB2YXIgc3JjID0gbmV3IFVpbnQ4QXJyYXkoYnl0ZXMuZGF0YS5ieXRlTGVuZ3RoLCBieXRlcy5yZWFkLCBieXRlcy5sZW5ndGgoKSk7CiAgICB0aGlzLmFjY29tbW9kYXRlKHNyYy5ieXRlTGVuZ3RoKTsKICAgIHZhciBkc3QgPSBuZXcgVWludDhBcnJheShieXRlcy5kYXRhLmJ5dGVMZW5ndGgsIHRoaXMud3JpdGUpOwogICAgZHN0LnNldChzcmMpOwogICAgdGhpcy53cml0ZSArPSBzcmMuYnl0ZUxlbmd0aDsKICAgIHJldHVybiB0aGlzOwogIH0KCiAgaWYoYnl0ZXMgaW5zdGFuY2VvZiB1dGlsLkJ5dGVTdHJpbmdCdWZmZXIpIHsKICAgIC8vIGNvcHkgYmluYXJ5IHN0cmluZyBhbmQgcHJvY2VzcyBhcyB0aGUgc2FtZSBhcyBhIHN0cmluZyBwYXJhbWV0ZXIgYmVsb3cKICAgIGJ5dGVzID0gYnl0ZXMuZGF0YTsKICAgIGVuY29kaW5nID0gJ2JpbmFyeSc7CiAgfQoKICAvLyBzdHJpbmcgY29udmVyc2lvbgogIGVuY29kaW5nID0gZW5jb2RpbmcgfHwgJ2JpbmFyeSc7CiAgaWYodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykgewogICAgdmFyIHZpZXc7CgogICAgLy8gZGVjb2RlIGZyb20gc3RyaW5nCiAgICBpZihlbmNvZGluZyA9PT0gJ2hleCcpIHsKICAgICAgdGhpcy5hY2NvbW1vZGF0ZShNYXRoLmNlaWwoYnl0ZXMubGVuZ3RoIC8gMikpOwogICAgICB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5kYXRhLmJ1ZmZlciwgdGhpcy53cml0ZSk7CiAgICAgIHRoaXMud3JpdGUgKz0gdXRpbC5iaW5hcnkuaGV4LmRlY29kZShieXRlcywgdmlldywgdGhpcy53cml0ZSk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfQogICAgaWYoZW5jb2RpbmcgPT09ICdiYXNlNjQnKSB7CiAgICAgIHRoaXMuYWNjb21tb2RhdGUoTWF0aC5jZWlsKGJ5dGVzLmxlbmd0aCAvIDQpICogMyk7CiAgICAgIHZpZXcgPSBuZXcgVWludDhBcnJheSh0aGlzLmRhdGEuYnVmZmVyLCB0aGlzLndyaXRlKTsKICAgICAgdGhpcy53cml0ZSArPSB1dGlsLmJpbmFyeS5iYXNlNjQuZGVjb2RlKGJ5dGVzLCB2aWV3LCB0aGlzLndyaXRlKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgLy8gZW5jb2RlIHRleHQgYXMgVVRGLTggYnl0ZXMKICAgIGlmKGVuY29kaW5nID09PSAndXRmOCcpIHsKICAgICAgLy8gZW5jb2RlIGFzIFVURi04IHRoZW4gZGVjb2RlIHN0cmluZyBhcyByYXcgYmluYXJ5CiAgICAgIGJ5dGVzID0gdXRpbC5lbmNvZGVVdGY4KGJ5dGVzKTsKICAgICAgZW5jb2RpbmcgPSAnYmluYXJ5JzsKICAgIH0KCiAgICAvLyBkZWNvZGUgc3RyaW5nIGFzIHJhdyBiaW5hcnkKICAgIGlmKGVuY29kaW5nID09PSAnYmluYXJ5JyB8fCBlbmNvZGluZyA9PT0gJ3JhdycpIHsKICAgICAgLy8gb25lIGJ5dGUgcGVyIGNoYXJhY3RlcgogICAgICB0aGlzLmFjY29tbW9kYXRlKGJ5dGVzLmxlbmd0aCk7CiAgICAgIHZpZXcgPSBuZXcgVWludDhBcnJheSh0aGlzLmRhdGEuYnVmZmVyLCB0aGlzLndyaXRlKTsKICAgICAgdGhpcy53cml0ZSArPSB1dGlsLmJpbmFyeS5yYXcuZGVjb2RlKHZpZXcpOwogICAgICByZXR1cm4gdGhpczsKICAgIH0KCiAgICAvLyBlbmNvZGUgdGV4dCBhcyBVVEYtMTYgYnl0ZXMKICAgIGlmKGVuY29kaW5nID09PSAndXRmMTYnKSB7CiAgICAgIC8vIHR3byBieXRlcyBwZXIgY2hhcmFjdGVyCiAgICAgIHRoaXMuYWNjb21tb2RhdGUoYnl0ZXMubGVuZ3RoICogMik7CiAgICAgIHZpZXcgPSBuZXcgVWludDE2QXJyYXkodGhpcy5kYXRhLmJ1ZmZlciwgdGhpcy53cml0ZSk7CiAgICAgIHRoaXMud3JpdGUgKz0gdXRpbC50ZXh0LnV0ZjE2LmVuY29kZSh2aWV3KTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGVuY29kaW5nOiAnICsgZW5jb2RpbmcpOwogIH0KCiAgdGhyb3cgRXJyb3IoJ0ludmFsaWQgcGFyYW1ldGVyOiAnICsgYnl0ZXMpOwp9OwoKLyoqCiAqIFB1dHMgdGhlIGdpdmVuIGJ1ZmZlciBpbnRvIHRoaXMgYnVmZmVyLgogKgogKiBAcGFyYW0gYnVmZmVyIHRoZSBidWZmZXIgdG8gcHV0IGludG8gdGhpcyBvbmUuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dEJ1ZmZlciA9IGZ1bmN0aW9uKGJ1ZmZlcikgewogIHRoaXMucHV0Qnl0ZXMoYnVmZmVyKTsKICBidWZmZXIuY2xlYXIoKTsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBQdXRzIGEgc3RyaW5nIGludG8gdGhpcyBidWZmZXIuCiAqCiAqIEBwYXJhbSBzdHIgdGhlIHN0cmluZyB0byBwdXQuCiAqIEBwYXJhbSBbZW5jb2RpbmddIHRoZSBlbmNvZGluZyBmb3IgdGhlIHN0cmluZyAoZGVmYXVsdDogJ3V0ZjE2JykuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dFN0cmluZyA9IGZ1bmN0aW9uKHN0cikgewogIHJldHVybiB0aGlzLnB1dEJ5dGVzKHN0ciwgJ3V0ZjE2Jyk7Cn07CgovKioKICogUHV0cyBhIDE2LWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAxNi1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0SW50MTYgPSBmdW5jdGlvbihpKSB7CiAgdGhpcy5hY2NvbW1vZGF0ZSgyKTsKICB0aGlzLmRhdGEuc2V0SW50MTYodGhpcy53cml0ZSwgaSk7CiAgdGhpcy53cml0ZSArPSAyOwogIHJldHVybiB0aGlzOwp9OwoKLyoqCiAqIFB1dHMgYSAyNC1iaXQgaW50ZWdlciBpbiB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyLgogKgogKiBAcGFyYW0gaSB0aGUgMjQtYml0IGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dEludDI0ID0gZnVuY3Rpb24oaSkgewogIHRoaXMuYWNjb21tb2RhdGUoMyk7CiAgdGhpcy5kYXRhLnNldEludDE2KHRoaXMud3JpdGUsIGkgPj4gOCAmIDB4RkZGRik7CiAgdGhpcy5kYXRhLnNldEludDgodGhpcy53cml0ZSwgaSA+PiAxNiAmIDB4RkYpOwogIHRoaXMud3JpdGUgKz0gMzsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBQdXRzIGEgMzItYml0IGludGVnZXIgaW4gdGhpcyBidWZmZXIgaW4gYmlnLWVuZGlhbiBvcmRlci4KICoKICogQHBhcmFtIGkgdGhlIDMyLWJpdCBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoaXMgYnVmZmVyLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5wdXRJbnQzMiA9IGZ1bmN0aW9uKGkpIHsKICB0aGlzLmFjY29tbW9kYXRlKDQpOwogIHRoaXMuZGF0YS5zZXRJbnQzMih0aGlzLndyaXRlLCBpKTsKICB0aGlzLndyaXRlICs9IDQ7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIDE2LWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAxNi1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0SW50MTZMZSA9IGZ1bmN0aW9uKGkpIHsKICB0aGlzLmFjY29tbW9kYXRlKDIpOwogIHRoaXMuZGF0YS5zZXRJbnQxNih0aGlzLndyaXRlLCBpLCB0cnVlKTsKICB0aGlzLndyaXRlICs9IDI7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIDI0LWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAyNC1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0SW50MjRMZSA9IGZ1bmN0aW9uKGkpIHsKICB0aGlzLmFjY29tbW9kYXRlKDMpOwogIHRoaXMuZGF0YS5zZXRJbnQ4KHRoaXMud3JpdGUsIGkgPj4gMTYgJiAweEZGKTsKICB0aGlzLmRhdGEuc2V0SW50MTYodGhpcy53cml0ZSwgaSA+PiA4ICYgMHhGRkZGLCB0cnVlKTsKICB0aGlzLndyaXRlICs9IDM7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIDMyLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSAzMi1iaXQgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0SW50MzJMZSA9IGZ1bmN0aW9uKGkpIHsKICB0aGlzLmFjY29tbW9kYXRlKDQpOwogIHRoaXMuZGF0YS5zZXRJbnQzMih0aGlzLndyaXRlLCBpLCB0cnVlKTsKICB0aGlzLndyaXRlICs9IDQ7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhbiBuLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSBuLWJpdCBpbnRlZ2VyLgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnB1dEludCA9IGZ1bmN0aW9uKGksIG4pIHsKICB0aGlzLmFjY29tbW9kYXRlKG4gLyA4KTsKICBkbyB7CiAgICBuIC09IDg7CiAgICB0aGlzLmRhdGEuc2V0SW50OCh0aGlzLndyaXRlKyssIChpID4+IG4pICYgMHhGRik7CiAgfSB3aGlsZShuID4gMCk7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogUHV0cyBhIHNpZ25lZCBuLWJpdCBpbnRlZ2VyIGluIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIuIFR3bydzCiAqIGNvbXBsZW1lbnQgcmVwcmVzZW50YXRpb24gaXMgdXNlZC4KICoKICogQHBhcmFtIGkgdGhlIG4tYml0IGludGVnZXIuCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUucHV0U2lnbmVkSW50ID0gZnVuY3Rpb24oaSwgbikgewogIHRoaXMuYWNjb21tb2RhdGUobiAvIDgpOwogIGlmKGkgPCAwKSB7CiAgICBpICs9IDIgPDwgKG4gLSAxKTsKICB9CiAgcmV0dXJuIHRoaXMucHV0SW50KGksIG4pOwp9OwoKLyoqCiAqIEdldHMgYSBieXRlIGZyb20gdGhpcyBidWZmZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkIHBvaW50ZXIgYnkgMS4KICoKICogQHJldHVybiB0aGUgYnl0ZS4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0Qnl0ZSA9IGZ1bmN0aW9uKCkgewogIHJldHVybiB0aGlzLmRhdGEuZ2V0SW50OCh0aGlzLnJlYWQrKyk7Cn07CgovKioKICogR2V0cyBhIHVpbnQxNiBmcm9tIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMi4KICoKICogQHJldHVybiB0aGUgdWludDE2LgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQxNiA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gdGhpcy5kYXRhLmdldEludDE2KHRoaXMucmVhZCk7CiAgdGhpcy5yZWFkICs9IDI7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQyNCBmcm9tIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMy4KICoKICogQHJldHVybiB0aGUgdWludDI0LgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQyNCA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gKAogICAgdGhpcy5kYXRhLmdldEludDE2KHRoaXMucmVhZCkgPDwgOCBeCiAgICB0aGlzLmRhdGEuZ2V0SW50OCh0aGlzLnJlYWQgKyAyKSk7CiAgdGhpcy5yZWFkICs9IDM7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQzMiBmcm9tIHRoaXMgYnVmZmVyIGluIGJpZy1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgNC4KICoKICogQHJldHVybiB0aGUgd29yZC4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0SW50MzIgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9IHRoaXMuZGF0YS5nZXRJbnQzMih0aGlzLnJlYWQpOwogIHRoaXMucmVhZCArPSA0OwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEdldHMgYSB1aW50MTYgZnJvbSB0aGlzIGJ1ZmZlciBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyIGFuZCBhZHZhbmNlcyB0aGUgcmVhZAogKiBwb2ludGVyIGJ5IDIuCiAqCiAqIEByZXR1cm4gdGhlIHVpbnQxNi4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0SW50MTZMZSA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gdGhpcy5kYXRhLmdldEludDE2KHRoaXMucmVhZCwgdHJ1ZSk7CiAgdGhpcy5yZWFkICs9IDI7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2V0cyBhIHVpbnQyNCBmcm9tIHRoaXMgYnVmZmVyIGluIGxpdHRsZS1lbmRpYW4gb3JkZXIgYW5kIGFkdmFuY2VzIHRoZSByZWFkCiAqIHBvaW50ZXIgYnkgMy4KICoKICogQHJldHVybiB0aGUgdWludDI0LgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQyNExlID0gZnVuY3Rpb24oKSB7CiAgdmFyIHJ2YWwgPSAoCiAgICB0aGlzLmRhdGEuZ2V0SW50OCh0aGlzLnJlYWQpIF4KICAgIHRoaXMuZGF0YS5nZXRJbnQxNih0aGlzLnJlYWQgKyAxLCB0cnVlKSA8PCA4KTsKICB0aGlzLnJlYWQgKz0gMzsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGEgdWludDMyIGZyb20gdGhpcyBidWZmZXIgaW4gbGl0dGxlLWVuZGlhbiBvcmRlciBhbmQgYWR2YW5jZXMgdGhlIHJlYWQKICogcG9pbnRlciBieSA0LgogKgogKiBAcmV0dXJuIHRoZSB3b3JkLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQzMkxlID0gZnVuY3Rpb24oKSB7CiAgdmFyIHJ2YWwgPSB0aGlzLmRhdGEuZ2V0SW50MzIodGhpcy5yZWFkLCB0cnVlKTsKICB0aGlzLnJlYWQgKz0gNDsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGFuIG4tYml0IGludGVnZXIgZnJvbSB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyIGFuZCBhZHZhbmNlcyB0aGUKICogcmVhZCBwb2ludGVyIGJ5IG4vOC4KICoKICogQHBhcmFtIG4gdGhlIG51bWJlciBvZiBiaXRzIGluIHRoZSBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoZSBpbnRlZ2VyLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5nZXRJbnQgPSBmdW5jdGlvbihuKSB7CiAgdmFyIHJ2YWwgPSAwOwogIGRvIHsKICAgIHJ2YWwgPSAocnZhbCA8PCA4KSArIHRoaXMuZGF0YS5nZXRJbnQ4KHRoaXMucmVhZCsrKTsKICAgIG4gLT0gODsKICB9IHdoaWxlKG4gPiAwKTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGEgc2lnbmVkIG4tYml0IGludGVnZXIgZnJvbSB0aGlzIGJ1ZmZlciBpbiBiaWctZW5kaWFuIG9yZGVyLCB1c2luZwogKiB0d28ncyBjb21wbGVtZW50LCBhbmQgYWR2YW5jZXMgdGhlIHJlYWQgcG9pbnRlciBieSBuLzguCiAqCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICoKICogQHJldHVybiB0aGUgaW50ZWdlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0U2lnbmVkSW50ID0gZnVuY3Rpb24obikgewogIHZhciB4ID0gdGhpcy5nZXRJbnQobik7CiAgdmFyIG1heCA9IDIgPDwgKG4gLSAyKTsKICBpZih4ID49IG1heCkgewogICAgeCAtPSBtYXggPDwgMTsKICB9CiAgcmV0dXJuIHg7Cn07CgovKioKICogUmVhZHMgYnl0ZXMgb3V0IGludG8gYSBVVEYtOCBzdHJpbmcgYW5kIGNsZWFycyB0aGVtIGZyb20gdGhlIGJ1ZmZlci4KICoKICogQHBhcmFtIGNvdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gcmVhZCwgdW5kZWZpbmVkIG9yIG51bGwgZm9yIGFsbC4KICoKICogQHJldHVybiBhIFVURi04IHN0cmluZyBvZiBieXRlcy4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuZ2V0Qnl0ZXMgPSBmdW5jdGlvbihjb3VudCkgewogIC8vIFRPRE86IGRlcHJlY2F0ZSB0aGlzIG1ldGhvZCwgaXQgaXMgcG9vcmx5IG5hbWVkIGFuZAogIC8vIHRoaXMudG9TdHJpbmcoJ2JpbmFyeScpIHJlcGxhY2VzIGl0CiAgLy8gYWRkIGEgdG9UeXBlZEFycmF5KCkvdG9BcnJheUJ1ZmZlcigpIGZ1bmN0aW9uCiAgdmFyIHJ2YWw7CiAgaWYoY291bnQpIHsKICAgIC8vIHJlYWQgY291bnQgYnl0ZXMKICAgIGNvdW50ID0gTWF0aC5taW4odGhpcy5sZW5ndGgoKSwgY291bnQpOwogICAgcnZhbCA9IHRoaXMuZGF0YS5zbGljZSh0aGlzLnJlYWQsIHRoaXMucmVhZCArIGNvdW50KTsKICAgIHRoaXMucmVhZCArPSBjb3VudDsKICB9IGVsc2UgaWYoY291bnQgPT09IDApIHsKICAgIHJ2YWwgPSAnJzsKICB9IGVsc2UgewogICAgLy8gcmVhZCBhbGwgYnl0ZXMsIG9wdGltaXplIHRvIG9ubHkgY29weSB3aGVuIG5lZWRlZAogICAgcnZhbCA9ICh0aGlzLnJlYWQgPT09IDApID8gdGhpcy5kYXRhIDogdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCk7CiAgICB0aGlzLmNsZWFyKCk7CiAgfQogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEdldHMgYSBVVEYtOCBlbmNvZGVkIHN0cmluZyBvZiB0aGUgYnl0ZXMgZnJvbSB0aGlzIGJ1ZmZlciB3aXRob3V0IG1vZGlmeWluZwogKiB0aGUgcmVhZCBwb2ludGVyLgogKgogKiBAcGFyYW0gY291bnQgdGhlIG51bWJlciBvZiBieXRlcyB0byBnZXQsIG9taXQgdG8gZ2V0IGFsbC4KICoKICogQHJldHVybiBhIHN0cmluZyBmdWxsIG9mIFVURi04IGVuY29kZWQgY2hhcmFjdGVycy4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuYnl0ZXMgPSBmdW5jdGlvbihjb3VudCkgewogIC8vIFRPRE86IGRlcHJlY2F0ZSB0aGlzIG1ldGhvZCwgaXQgaXMgcG9vcmx5IG5hbWVkLCBhZGQgImdldFN0cmluZygpIgogIHJldHVybiAodHlwZW9mKGNvdW50KSA9PT0gJ3VuZGVmaW5lZCcgPwogICAgdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCkgOgogICAgdGhpcy5kYXRhLnNsaWNlKHRoaXMucmVhZCwgdGhpcy5yZWFkICsgY291bnQpKTsKfTsKCi8qKgogKiBHZXRzIGEgYnl0ZSBhdCB0aGUgZ2l2ZW4gaW5kZXggd2l0aG91dCBtb2RpZnlpbmcgdGhlIHJlYWQgcG9pbnRlci4KICoKICogQHBhcmFtIGkgdGhlIGJ5dGUgaW5kZXguCiAqCiAqIEByZXR1cm4gdGhlIGJ5dGUuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLmF0ID0gZnVuY3Rpb24oaSkgewogIHJldHVybiB0aGlzLmRhdGEuZ2V0VWludDgodGhpcy5yZWFkICsgaSk7Cn07CgovKioKICogUHV0cyBhIGJ5dGUgYXQgdGhlIGdpdmVuIGluZGV4IHdpdGhvdXQgbW9kaWZ5aW5nIHRoZSByZWFkIHBvaW50ZXIuCiAqCiAqIEBwYXJhbSBpIHRoZSBieXRlIGluZGV4LgogKiBAcGFyYW0gYiB0aGUgYnl0ZSB0byBwdXQuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnNldEF0ID0gZnVuY3Rpb24oaSwgYikgewogIHRoaXMuZGF0YS5zZXRVaW50OChpLCBiKTsKICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBHZXRzIHRoZSBsYXN0IGJ5dGUgd2l0aG91dCBtb2RpZnlpbmcgdGhlIHJlYWQgcG9pbnRlci4KICoKICogQHJldHVybiB0aGUgbGFzdCBieXRlLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS5sYXN0ID0gZnVuY3Rpb24oKSB7CiAgcmV0dXJuIHRoaXMuZGF0YS5nZXRVaW50OCh0aGlzLndyaXRlIC0gMSk7Cn07CgovKioKICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIGNvcHkuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gbmV3IHV0aWwuRGF0YUJ1ZmZlcih0aGlzKTsKfTsKCi8qKgogKiBDb21wYWN0cyB0aGlzIGJ1ZmZlci4KICoKICogQHJldHVybiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUuY29tcGFjdCA9IGZ1bmN0aW9uKCkgewogIGlmKHRoaXMucmVhZCA+IDApIHsKICAgIHZhciBzcmMgPSBuZXcgVWludDhBcnJheSh0aGlzLmRhdGEuYnVmZmVyLCB0aGlzLnJlYWQpOwogICAgdmFyIGRzdCA9IG5ldyBVaW50OEFycmF5KHNyYy5ieXRlTGVuZ3RoKTsKICAgIGRzdC5zZXQoc3JjKTsKICAgIHRoaXMuZGF0YSA9IG5ldyBEYXRhVmlldyhkc3QpOwogICAgdGhpcy53cml0ZSAtPSB0aGlzLnJlYWQ7CiAgICB0aGlzLnJlYWQgPSAwOwogIH0KICByZXR1cm4gdGhpczsKfTsKCi8qKgogKiBDbGVhcnMgdGhpcyBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5kYXRhID0gbmV3IERhdGFWaWV3KG5ldyBBcnJheUJ1ZmZlcigwKSk7CiAgdGhpcy5yZWFkID0gdGhpcy53cml0ZSA9IDA7CiAgcmV0dXJuIHRoaXM7Cn07CgovKioKICogU2hvcnRlbnMgdGhpcyBidWZmZXIgYnkgdHJpbWluZyBieXRlcyBvZmYgb2YgdGhlIGVuZCBvZiB0aGlzIGJ1ZmZlci4KICoKICogQHBhcmFtIGNvdW50IHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gdHJpbSBvZmYuCiAqCiAqIEByZXR1cm4gdGhpcyBidWZmZXIuCiAqLwp1dGlsLkRhdGFCdWZmZXIucHJvdG90eXBlLnRydW5jYXRlID0gZnVuY3Rpb24oY291bnQpIHsKICB0aGlzLndyaXRlID0gTWF0aC5tYXgoMCwgdGhpcy5sZW5ndGgoKSAtIGNvdW50KTsKICB0aGlzLnJlYWQgPSBNYXRoLm1pbih0aGlzLnJlYWQsIHRoaXMud3JpdGUpOwogIHJldHVybiB0aGlzOwp9OwoKLyoqCiAqIENvbnZlcnRzIHRoaXMgYnVmZmVyIHRvIGEgaGV4YWRlY2ltYWwgc3RyaW5nLgogKgogKiBAcmV0dXJuIGEgaGV4YWRlY2ltYWwgc3RyaW5nLgogKi8KdXRpbC5EYXRhQnVmZmVyLnByb3RvdHlwZS50b0hleCA9IGZ1bmN0aW9uKCkgewogIHZhciBydmFsID0gJyc7CiAgZm9yKHZhciBpID0gdGhpcy5yZWFkOyBpIDwgdGhpcy5kYXRhLmJ5dGVMZW5ndGg7ICsraSkgewogICAgdmFyIGIgPSB0aGlzLmRhdGEuZ2V0VWludDgoaSk7CiAgICBpZihiIDwgMTYpIHsKICAgICAgcnZhbCArPSAnMCc7CiAgICB9CiAgICBydmFsICs9IGIudG9TdHJpbmcoMTYpOwogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDb252ZXJ0cyB0aGlzIGJ1ZmZlciB0byBhIHN0cmluZywgdXNpbmcgdGhlIGdpdmVuIGVuY29kaW5nLiBJZiBubwogKiBlbmNvZGluZyBpcyBnaXZlbiwgJ3V0ZjgnIChVVEYtOCkgaXMgdXNlZC4KICoKICogQHBhcmFtIFtlbmNvZGluZ10gdGhlIGVuY29kaW5nIHRvIHVzZTogJ2JpbmFyeScsICd1dGY4JywgJ3V0ZjE2JywgJ2hleCcsCiAqICAgICAgICAgICdiYXNlNjQnIChkZWZhdWx0OiAndXRmOCcpLgogKgogKiBAcmV0dXJuIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBieXRlcyBpbiB0aGlzIGJ1ZmZlci4KICovCnV0aWwuRGF0YUJ1ZmZlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbihlbmNvZGluZykgewogIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5kYXRhLCB0aGlzLnJlYWQsIHRoaXMubGVuZ3RoKCkpOwogIGVuY29kaW5nID0gZW5jb2RpbmcgfHwgJ3V0ZjgnOwoKICAvLyBlbmNvZGUgdG8gc3RyaW5nCiAgaWYoZW5jb2RpbmcgPT09ICdiaW5hcnknIHx8IGVuY29kaW5nID09PSAncmF3JykgewogICAgcmV0dXJuIHV0aWwuYmluYXJ5LnJhdy5lbmNvZGUodmlldyk7CiAgfQogIGlmKGVuY29kaW5nID09PSAnaGV4JykgewogICAgcmV0dXJuIHV0aWwuYmluYXJ5LmhleC5lbmNvZGUodmlldyk7CiAgfQogIGlmKGVuY29kaW5nID09PSAnYmFzZTY0JykgewogICAgcmV0dXJuIHV0aWwuYmluYXJ5LmJhc2U2NC5lbmNvZGUodmlldyk7CiAgfQoKICAvLyBkZWNvZGUgdG8gdGV4dAogIGlmKGVuY29kaW5nID09PSAndXRmOCcpIHsKICAgIHJldHVybiB1dGlsLnRleHQudXRmOC5kZWNvZGUodmlldyk7CiAgfQogIGlmKGVuY29kaW5nID09PSAndXRmMTYnKSB7CiAgICByZXR1cm4gdXRpbC50ZXh0LnV0ZjE2LmRlY29kZSh2aWV3KTsKICB9CgogIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBlbmNvZGluZzogJyArIGVuY29kaW5nKTsKfTsKCi8qKiBFbmQgQnVmZmVyIHcvVUludDhBcnJheSBiYWNraW5nICovCgoKLyoqCiAqIENyZWF0ZXMgYSBidWZmZXIgdGhhdCBzdG9yZXMgYnl0ZXMuIEEgdmFsdWUgbWF5IGJlIGdpdmVuIHRvIHB1dCBpbnRvIHRoZQogKiBidWZmZXIgdGhhdCBpcyBlaXRoZXIgYSBzdHJpbmcgb2YgYnl0ZXMgb3IgYSBVVEYtMTYgc3RyaW5nIHRoYXQgd2lsbAogKiBiZSBlbmNvZGVkIHVzaW5nIFVURi04ICh0byBkbyB0aGUgbGF0dGVyLCBzcGVjaWZ5ICd1dGY4JyBhcyB0aGUgZW5jb2RpbmcpLgogKgogKiBAcGFyYW0gW2lucHV0XSB0aGUgYnl0ZXMgdG8gd3JhcCAoYXMgYSBzdHJpbmcpIG9yIGEgVVRGLTE2IHN0cmluZyB0byBlbmNvZGUKICogICAgICAgICAgYXMgVVRGLTguCiAqIEBwYXJhbSBbZW5jb2RpbmddIChkZWZhdWx0OiAncmF3Jywgb3RoZXI6ICd1dGY4JykuCiAqLwp1dGlsLmNyZWF0ZUJ1ZmZlciA9IGZ1bmN0aW9uKGlucHV0LCBlbmNvZGluZykgewogIC8vIFRPRE86IGRlcHJlY2F0ZSwgdXNlIG5ldyBCeXRlQnVmZmVyKCkgaW5zdGVhZAogIGVuY29kaW5nID0gZW5jb2RpbmcgfHwgJ3Jhdyc7CiAgaWYoaW5wdXQgIT09IHVuZGVmaW5lZCAmJiBlbmNvZGluZyA9PT0gJ3V0ZjgnKSB7CiAgICBpbnB1dCA9IHV0aWwuZW5jb2RlVXRmOChpbnB1dCk7CiAgfQogIHJldHVybiBuZXcgdXRpbC5CeXRlQnVmZmVyKGlucHV0KTsKfTsKCi8qKgogKiBGaWxscyBhIHN0cmluZyB3aXRoIGEgcGFydGljdWxhciB2YWx1ZS4gSWYgeW91IHdhbnQgdGhlIHN0cmluZyB0byBiZSBhIGJ5dGUKICogc3RyaW5nLCBwYXNzIGluIFN0cmluZy5mcm9tQ2hhckNvZGUodGhlQnl0ZSkuCiAqCiAqIEBwYXJhbSBjIHRoZSBjaGFyYWN0ZXIgdG8gZmlsbCB0aGUgc3RyaW5nIHdpdGgsIHVzZSBTdHJpbmcuZnJvbUNoYXJDb2RlCiAqICAgICAgICAgIHRvIGZpbGwgdGhlIHN0cmluZyB3aXRoIGEgYnl0ZSB2YWx1ZS4KICogQHBhcmFtIG4gdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIG9mIHZhbHVlIGMgdG8gZmlsbCB3aXRoLgogKgogKiBAcmV0dXJuIHRoZSBmaWxsZWQgc3RyaW5nLgogKi8KdXRpbC5maWxsU3RyaW5nID0gZnVuY3Rpb24oYywgbikgewogIHZhciBzID0gJyc7CiAgd2hpbGUobiA+IDApIHsKICAgIGlmKG4gJiAxKSB7CiAgICAgIHMgKz0gYzsKICAgIH0KICAgIG4gPj4+PSAxOwogICAgaWYobiA+IDApIHsKICAgICAgYyArPSBjOwogICAgfQogIH0KICByZXR1cm4gczsKfTsKCi8qKgogKiBQZXJmb3JtcyBhIHBlciBieXRlIFhPUiBiZXR3ZWVuIHR3byBieXRlIHN0cmluZ3MgYW5kIHJldHVybnMgdGhlIHJlc3VsdCBhcyBhCiAqIHN0cmluZyBvZiBieXRlcy4KICoKICogQHBhcmFtIHMxIGZpcnN0IHN0cmluZyBvZiBieXRlcy4KICogQHBhcmFtIHMyIHNlY29uZCBzdHJpbmcgb2YgYnl0ZXMuCiAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYnl0ZXMgdG8gWE9SLgogKgogKiBAcmV0dXJuIHRoZSBYT1InZCByZXN1bHQuCiAqLwp1dGlsLnhvckJ5dGVzID0gZnVuY3Rpb24oczEsIHMyLCBuKSB7CiAgdmFyIHMzID0gJyc7CiAgdmFyIGIgPSAnJzsKICB2YXIgdCA9ICcnOwogIHZhciBpID0gMDsKICB2YXIgYyA9IDA7CiAgZm9yKDsgbiA+IDA7IC0tbiwgKytpKSB7CiAgICBiID0gczEuY2hhckNvZGVBdChpKSBeIHMyLmNoYXJDb2RlQXQoaSk7CiAgICBpZihjID49IDEwKSB7CiAgICAgIHMzICs9IHQ7CiAgICAgIHQgPSAnJzsKICAgICAgYyA9IDA7CiAgICB9CiAgICB0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYik7CiAgICArK2M7CiAgfQogIHMzICs9IHQ7CiAgcmV0dXJuIHMzOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgaGV4IHN0cmluZyBpbnRvIGEgJ2JpbmFyeScgZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMuCiAqCiAqIEBwYXJhbSBoZXggdGhlIGhleGFkZWNpbWFsIHN0cmluZyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMuCiAqLwp1dGlsLmhleFRvQnl0ZXMgPSBmdW5jdGlvbihoZXgpIHsKICAvLyBUT0RPOiBkZXByZWNhdGU6ICJEZXByZWNhdGVkLiBVc2UgdXRpbC5iaW5hcnkuaGV4LmRlY29kZSBpbnN0ZWFkLiIKICB2YXIgcnZhbCA9ICcnOwogIHZhciBpID0gMDsKICBpZihoZXgubGVuZ3RoICYgMSA9PSAxKSB7CiAgICAvLyBvZGQgbnVtYmVyIG9mIGNoYXJhY3RlcnMsIGNvbnZlcnQgZmlyc3QgY2hhcmFjdGVyIGFsb25lCiAgICBpID0gMTsKICAgIHJ2YWwgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChoZXhbMF0sIDE2KSk7CiAgfQogIC8vIGNvbnZlcnQgMiBjaGFyYWN0ZXJzICgxIGJ5dGUpIGF0IGEgdGltZQogIGZvcig7IGkgPCBoZXgubGVuZ3RoOyBpICs9IDIpIHsKICAgIHJ2YWwgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShwYXJzZUludChoZXguc3Vic3RyKGksIDIpLCAxNikpOwogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDb252ZXJ0cyBhICdiaW5hcnknIGVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzIHRvIGhleC4KICoKICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlIHN0cmluZyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBzdHJpbmcgb2YgaGV4YWRlY2ltYWwgY2hhcmFjdGVycy4KICovCnV0aWwuYnl0ZXNUb0hleCA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgLy8gVE9ETzogZGVwcmVjYXRlOiAiRGVwcmVjYXRlZC4gVXNlIHV0aWwuYmluYXJ5LmhleC5lbmNvZGUgaW5zdGVhZC4iCiAgcmV0dXJuIHV0aWwuY3JlYXRlQnVmZmVyKGJ5dGVzKS50b0hleCgpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIDMyLWJpdCBpbnRlZ2VyIHRvIDQtYmlnLWVuZGlhbiBieXRlIHN0cmluZy4KICoKICogQHBhcmFtIGkgdGhlIGludGVnZXIuCiAqCiAqIEByZXR1cm4gdGhlIGJ5dGUgc3RyaW5nLgogKi8KdXRpbC5pbnQzMlRvQnl0ZXMgPSBmdW5jdGlvbihpKSB7CiAgcmV0dXJuICgKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiAyNCAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiAxNiAmIDB4RkYpICsKICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoaSA+PiA4ICYgMHhGRikgKwogICAgU3RyaW5nLmZyb21DaGFyQ29kZShpICYgMHhGRikpOwp9OwoKLy8gYmFzZTY0IGNoYXJhY3RlcnMsIHJldmVyc2UgbWFwcGluZwp2YXIgX2Jhc2U2NCA9CiAgJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky89JzsKdmFyIF9iYXNlNjRJZHggPSBbCi8qNDMgLTQzID0gMCovCi8qJysnLCAgMSwgIDIsICAzLCcvJyAqLwogICA2MiwgLTEsIC0xLCAtMSwgNjMsCgovKicwJywnMScsJzInLCczJywnNCcsJzUnLCc2JywnNycsJzgnLCc5JyAqLwogICA1MiwgNTMsIDU0LCA1NSwgNTYsIDU3LCA1OCwgNTksIDYwLCA2MSwKCi8qMTUsIDE2LCAxNywnPScsIDE5LCAyMCwgMjEgKi8KICAtMSwgLTEsIC0xLCA2NCwgLTEsIC0xLCAtMSwKCi8qNjUgLSA0MyA9IDIyKi8KLyonQScsJ0InLCdDJywnRCcsJ0UnLCdGJywnRycsJ0gnLCdJJywnSicsJ0snLCdMJywnTScsICovCiAgIDAsICAxLCAgMiwgIDMsICA0LCAgNSwgIDYsICA3LCAgOCwgIDksIDEwLCAxMSwgMTIsCgovKidOJywnTycsJ1AnLCdRJywnUicsJ1MnLCdUJywnVScsJ1YnLCdXJywnWCcsJ1knLCdaJyAqLwogICAxMywgMTQsIDE1LCAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwKCi8qOTEgLSA0MyA9IDQ4ICovCi8qNDgsIDQ5LCA1MCwgNTEsIDUyLCA1MyAqLwogIC0xLCAtMSwgLTEsIC0xLCAtMSwgLTEsCgovKjk3IC0gNDMgPSA1NCovCi8qJ2EnLCdiJywnYycsJ2QnLCdlJywnZicsJ2cnLCdoJywnaScsJ2onLCdrJywnbCcsJ20nICovCiAgIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsIDMyLCAzMywgMzQsIDM1LCAzNiwgMzcsIDM4LAoKLyonbicsJ28nLCdwJywncScsJ3InLCdzJywndCcsJ3UnLCd2JywndycsJ3gnLCd5JywneicgKi8KICAgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywgNDgsIDQ5LCA1MCwgNTEKXTsKCi8qKgogKiBCYXNlNjQgZW5jb2RlcyBhICdiaW5hcnknIGVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogKgogKiBAcGFyYW0gaW5wdXQgdGhlIGJpbmFyeSBlbmNvZGVkIHN0cmluZyBvZiBieXRlcyB0byBiYXNlNjQtZW5jb2RlLgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBudW1iZXIgb2YgZW5jb2RlZCBjaGFyYWN0ZXJzIHBlciBsaW5lIHRvIHVzZSwKICogICAgICAgICAgZGVmYXVsdHMgdG8gbm9uZS4KICoKICogQHJldHVybiB0aGUgYmFzZTY0LWVuY29kZWQgb3V0cHV0LgogKi8KdXRpbC5lbmNvZGU2NCA9IGZ1bmN0aW9uKGlucHV0LCBtYXhsaW5lKSB7CiAgLy8gVE9ETzogZGVwcmVjYXRlOiAiRGVwcmVjYXRlZC4gVXNlIHV0aWwuYmluYXJ5LmJhc2U2NC5lbmNvZGUgaW5zdGVhZC4iCiAgdmFyIGxpbmUgPSAnJzsKICB2YXIgb3V0cHV0ID0gJyc7CiAgdmFyIGNocjEsIGNocjIsIGNocjM7CiAgdmFyIGkgPSAwOwogIHdoaWxlKGkgPCBpbnB1dC5sZW5ndGgpIHsKICAgIGNocjEgPSBpbnB1dC5jaGFyQ29kZUF0KGkrKyk7CiAgICBjaHIyID0gaW5wdXQuY2hhckNvZGVBdChpKyspOwogICAgY2hyMyA9IGlucHV0LmNoYXJDb2RlQXQoaSsrKTsKCiAgICAvLyBlbmNvZGUgNCBjaGFyYWN0ZXIgZ3JvdXAKICAgIGxpbmUgKz0gX2Jhc2U2NC5jaGFyQXQoY2hyMSA+PiAyKTsKICAgIGxpbmUgKz0gX2Jhc2U2NC5jaGFyQXQoKChjaHIxICYgMykgPDwgNCkgfCAoY2hyMiA+PiA0KSk7CiAgICBpZihpc05hTihjaHIyKSkgewogICAgICBsaW5lICs9ICc9PSc7CiAgICB9IGVsc2UgewogICAgICBsaW5lICs9IF9iYXNlNjQuY2hhckF0KCgoY2hyMiAmIDE1KSA8PCAyKSB8IChjaHIzID4+IDYpKTsKICAgICAgbGluZSArPSBpc05hTihjaHIzKSA/ICc9JyA6IF9iYXNlNjQuY2hhckF0KGNocjMgJiA2Myk7CiAgICB9CgogICAgaWYobWF4bGluZSAmJiBsaW5lLmxlbmd0aCA+IG1heGxpbmUpIHsKICAgICAgb3V0cHV0ICs9IGxpbmUuc3Vic3RyKDAsIG1heGxpbmUpICsgJ1xyXG4nOwogICAgICBsaW5lID0gbGluZS5zdWJzdHIobWF4bGluZSk7CiAgICB9CiAgfQogIG91dHB1dCArPSBsaW5lOwogIHJldHVybiBvdXRwdXQ7Cn07CgovKioKICogQmFzZTY0IGRlY29kZXMgYSBzdHJpbmcgaW50byBhICdiaW5hcnknIGVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogKgogKiBAcGFyYW0gaW5wdXQgdGhlIGJhc2U2NC1lbmNvZGVkIGlucHV0LgogKgogKiBAcmV0dXJuIHRoZSBiaW5hcnkgZW5jb2RlZCBzdHJpbmcuCiAqLwp1dGlsLmRlY29kZTY0ID0gZnVuY3Rpb24oaW5wdXQpIHsKICAvLyBUT0RPOiBkZXByZWNhdGU6ICJEZXByZWNhdGVkLiBVc2UgdXRpbC5iaW5hcnkuYmFzZTY0LmRlY29kZSBpbnN0ZWFkLiIKCiAgLy8gcmVtb3ZlIGFsbCBub24tYmFzZTY0IGNoYXJhY3RlcnMKICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1teQS1aYS16MC05XCtcL1w9XS9nLCAnJyk7CgogIHZhciBvdXRwdXQgPSAnJzsKICB2YXIgZW5jMSwgZW5jMiwgZW5jMywgZW5jNDsKICB2YXIgaSA9IDA7CgogIHdoaWxlKGkgPCBpbnB1dC5sZW5ndGgpIHsKICAgIGVuYzEgPSBfYmFzZTY0SWR4W2lucHV0LmNoYXJDb2RlQXQoaSsrKSAtIDQzXTsKICAgIGVuYzIgPSBfYmFzZTY0SWR4W2lucHV0LmNoYXJDb2RlQXQoaSsrKSAtIDQzXTsKICAgIGVuYzMgPSBfYmFzZTY0SWR4W2lucHV0LmNoYXJDb2RlQXQoaSsrKSAtIDQzXTsKICAgIGVuYzQgPSBfYmFzZTY0SWR4W2lucHV0LmNoYXJDb2RlQXQoaSsrKSAtIDQzXTsKCiAgICBvdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoZW5jMSA8PCAyKSB8IChlbmMyID4+IDQpKTsKICAgIGlmKGVuYzMgIT09IDY0KSB7CiAgICAgIC8vIGRlY29kZWQgYXQgbGVhc3QgMiBieXRlcwogICAgICBvdXRwdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoKGVuYzIgJiAxNSkgPDwgNCkgfCAoZW5jMyA+PiAyKSk7CiAgICAgIGlmKGVuYzQgIT09IDY0KSB7CiAgICAgICAgLy8gZGVjb2RlZCAzIGJ5dGVzCiAgICAgICAgb3V0cHV0ICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoKChlbmMzICYgMykgPDwgNikgfCBlbmM0KTsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIG91dHB1dDsKfTsKCi8qKgogKiBVVEYtOCBlbmNvZGVzIHRoZSBnaXZlbiBVVEYtMTYgZW5jb2RlZCBzdHJpbmcgKGEgc3RhbmRhcmQgSmF2YVNjcmlwdAogKiBzdHJpbmcpLiBOb24tQVNDSUkgY2hhcmFjdGVycyB3aWxsIGJlIGVuY29kZWQgYXMgbXVsdGlwbGUgYnl0ZXMgYWNjb3JkaW5nCiAqIHRvIFVURi04LgogKgogKiBAcGFyYW0gc3RyIHRoZSBzdHJpbmcgdG8gZW5jb2RlLgogKgogKiBAcmV0dXJuIHRoZSBVVEYtOCBlbmNvZGVkIHN0cmluZy4KICovCnV0aWwuZW5jb2RlVXRmOCA9IGZ1bmN0aW9uKHN0cikgewogIHJldHVybiB1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQoc3RyKSk7Cn07CgovKioKICogRGVjb2RlcyBhIFVURi04IGVuY29kZWQgc3RyaW5nIGludG8gYSBVVEYtMTYgc3RyaW5nLgogKgogKiBAcGFyYW0gc3RyIHRoZSBzdHJpbmcgdG8gZGVjb2RlLgogKgogKiBAcmV0dXJuIHRoZSBVVEYtMTYgZW5jb2RlZCBzdHJpbmcgKHN0YW5kYXJkIEphdmFTY3JpcHQgc3RyaW5nKS4KICovCnV0aWwuZGVjb2RlVXRmOCA9IGZ1bmN0aW9uKHN0cikgewogIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKHN0cikpOwp9OwoKLy8gYmluYXJ5IGVuY29kaW5nL2RlY29kaW5nIHRvb2xzCi8vIEZJWE1FOiBFeHBlcmltZW50YWwuIERvIG5vdCB1c2UgeWV0Lgp1dGlsLmJpbmFyeSA9IHsKICByYXc6IHt9LAogIGhleDoge30sCiAgYmFzZTY0OiB7fQp9OwoKLyoqCiAqIEVuY29kZXMgYSBVaW50OEFycmF5IGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nLiBUaGlzIGVuY29kaW5nIHVzZXMKICogYSB2YWx1ZSBiZXR3ZWVuIDAgYW5kIDI1NSBmb3IgZWFjaCBjaGFyYWN0ZXIuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgVWludDhBcnJheSB0byBlbmNvZGUuCiAqCiAqIEByZXR1cm4gdGhlIGJpbmFyeS1lbmNvZGVkIHN0cmluZy4KICovCnV0aWwuYmluYXJ5LnJhdy5lbmNvZGUgPSBmdW5jdGlvbihieXRlcykgewogIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsIGJ5dGVzKTsKfTsKCi8qKgogKiBEZWNvZGVzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIHRvIGEgVWludDhBcnJheS4gVGhpcyBlbmNvZGluZyB1c2VzCiAqIGEgdmFsdWUgYmV0d2VlbiAwIGFuZCAyNTUgZm9yIGVhY2ggY2hhcmFjdGVyLgogKgogKiBAcGFyYW0gc3RyIHRoZSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgdG8gZGVjb2RlLgogKiBAcGFyYW0gW291dHB1dF0gYW4gb3B0aW9uYWwgVWludDhBcnJheSB0byB3cml0ZSB0aGUgb3V0cHV0IHRvOyBpZiBpdAogKiAgICAgICAgICBpcyB0b28gc21hbGwsIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4KICogQHBhcmFtIFtvZmZzZXRdIHRoZSBzdGFydCBvZmZzZXQgZm9yIHdyaXRpbmcgdG8gdGhlIG91dHB1dCAoZGVmYXVsdDogMCkuCiAqCiAqIEByZXR1cm4gdGhlIFVpbnQ4QXJyYXkgb3IgdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIGlmIG91dHB1dCB3YXMgZ2l2ZW4uCiAqLwp1dGlsLmJpbmFyeS5yYXcuZGVjb2RlID0gZnVuY3Rpb24oc3RyLCBvdXRwdXQsIG9mZnNldCkgewogIHZhciBvdXQgPSBvdXRwdXQ7CiAgaWYoIW91dCkgewogICAgb3V0ID0gbmV3IFVpbnQ4QXJyYXkoc3RyLmxlbmd0aCk7CiAgfQogIG9mZnNldCA9IG9mZnNldCB8fCAwOwogIHZhciBqID0gb2Zmc2V0OwogIGZvcih2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHsKICAgIG91dFtqKytdID0gc3RyLmNoYXJDb2RlQXQoaSk7CiAgfQogIHJldHVybiBvdXRwdXQgPyAoaiAtIG9mZnNldCkgOiBvdXQ7Cn07CgovKioKICogRW5jb2RlcyBhICdiaW5hcnknIHN0cmluZywgQXJyYXlCdWZmZXIsIERhdGFWaWV3LCBUeXBlZEFycmF5LCBvcgogKiBCeXRlQnVmZmVyIGFzIGEgc3RyaW5nIG9mIGhleGFkZWNpbWFsIGNoYXJhY3RlcnMuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZXMgdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgc3RyaW5nIG9mIGhleGFkZWNpbWFsIGNoYXJhY3RlcnMuCiAqLwp1dGlsLmJpbmFyeS5oZXguZW5jb2RlID0gdXRpbC5ieXRlc1RvSGV4OwoKLyoqCiAqIERlY29kZXMgYSBoZXgtZW5jb2RlZCBzdHJpbmcgdG8gYSBVaW50OEFycmF5LgogKgogKiBAcGFyYW0gaGV4IHRoZSBoZXhhZGVjaW1hbCBzdHJpbmcgdG8gY29udmVydC4KICogQHBhcmFtIFtvdXRwdXRdIGFuIG9wdGlvbmFsIFVpbnQ4QXJyYXkgdG8gd3JpdGUgdGhlIG91dHB1dCB0bzsgaWYgaXQKICogICAgICAgICAgaXMgdG9vIHNtYWxsLCBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCiAqIEBwYXJhbSBbb2Zmc2V0XSB0aGUgc3RhcnQgb2Zmc2V0IGZvciB3cml0aW5nIHRvIHRoZSBvdXRwdXQgKGRlZmF1bHQ6IDApLgogKgogKiBAcmV0dXJuIHRoZSBVaW50OEFycmF5IG9yIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiBpZiBvdXRwdXQgd2FzIGdpdmVuLgogKi8KdXRpbC5iaW5hcnkuaGV4LmRlY29kZSA9IGZ1bmN0aW9uKGhleCwgb3V0cHV0LCBvZmZzZXQpIHsKICB2YXIgb3V0ID0gb3V0cHV0OwogIGlmKCFvdXQpIHsKICAgIG91dCA9IG5ldyBVaW50OEFycmF5KE1hdGguY2VpbChoZXgubGVuZ3RoIC8gMikpOwogIH0KICBvZmZzZXQgPSBvZmZzZXQgfHwgMDsKICB2YXIgaSA9IDAsIGogPSBvZmZzZXQ7CiAgaWYoaGV4Lmxlbmd0aCAmIDEpIHsKICAgIC8vIG9kZCBudW1iZXIgb2YgY2hhcmFjdGVycywgY29udmVydCBmaXJzdCBjaGFyYWN0ZXIgYWxvbmUKICAgIGkgPSAxOwogICAgb3V0W2orK10gPSBwYXJzZUludChoZXhbMF0sIDE2KTsKICB9CiAgLy8gY29udmVydCAyIGNoYXJhY3RlcnMgKDEgYnl0ZSkgYXQgYSB0aW1lCiAgZm9yKDsgaSA8IGhleC5sZW5ndGg7IGkgKz0gMikgewogICAgb3V0W2orK10gPSBwYXJzZUludChoZXguc3Vic3RyKGksIDIpLCAxNik7CiAgfQogIHJldHVybiBvdXRwdXQgPyAoaiAtIG9mZnNldCkgOiBvdXQ7Cn07CgovKioKICogQmFzZTY0LWVuY29kZXMgYSBVaW50OEFycmF5LgogKgogKiBAcGFyYW0gaW5wdXQgdGhlIFVpbnQ4QXJyYXkgdG8gZW5jb2RlLgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBudW1iZXIgb2YgZW5jb2RlZCBjaGFyYWN0ZXJzIHBlciBsaW5lIHRvIHVzZSwKICogICAgICAgICAgZGVmYXVsdHMgdG8gbm9uZS4KICoKICogQHJldHVybiB0aGUgYmFzZTY0LWVuY29kZWQgb3V0cHV0IHN0cmluZy4KICovCnV0aWwuYmluYXJ5LmJhc2U2NC5lbmNvZGUgPSBmdW5jdGlvbihpbnB1dCwgbWF4bGluZSkgewogIHZhciBsaW5lID0gJyc7CiAgdmFyIG91dHB1dCA9ICcnOwogIHZhciBjaHIxLCBjaHIyLCBjaHIzOwogIHZhciBpID0gMDsKICB3aGlsZShpIDwgaW5wdXQuYnl0ZUxlbmd0aCkgewogICAgY2hyMSA9IGlucHV0W2krK107CiAgICBjaHIyID0gaW5wdXRbaSsrXTsKICAgIGNocjMgPSBpbnB1dFtpKytdOwoKICAgIC8vIGVuY29kZSA0IGNoYXJhY3RlciBncm91cAogICAgbGluZSArPSBfYmFzZTY0LmNoYXJBdChjaHIxID4+IDIpOwogICAgbGluZSArPSBfYmFzZTY0LmNoYXJBdCgoKGNocjEgJiAzKSA8PCA0KSB8IChjaHIyID4+IDQpKTsKICAgIGlmKGlzTmFOKGNocjIpKSB7CiAgICAgIGxpbmUgKz0gJz09JzsKICAgIH0gZWxzZSB7CiAgICAgIGxpbmUgKz0gX2Jhc2U2NC5jaGFyQXQoKChjaHIyICYgMTUpIDw8IDIpIHwgKGNocjMgPj4gNikpOwogICAgICBsaW5lICs9IGlzTmFOKGNocjMpID8gJz0nIDogX2Jhc2U2NC5jaGFyQXQoY2hyMyAmIDYzKTsKICAgIH0KCiAgICBpZihtYXhsaW5lICYmIGxpbmUubGVuZ3RoID4gbWF4bGluZSkgewogICAgICBvdXRwdXQgKz0gbGluZS5zdWJzdHIoMCwgbWF4bGluZSkgKyAnXHJcbic7CiAgICAgIGxpbmUgPSBsaW5lLnN1YnN0cihtYXhsaW5lKTsKICAgIH0KICB9CiAgb3V0cHV0ICs9IGxpbmU7CiAgcmV0dXJuIG91dHB1dDsKfTsKCi8qKgogKiBEZWNvZGVzIGEgYmFzZTY0LWVuY29kZWQgc3RyaW5nIHRvIGEgVWludDhBcnJheS4KICoKICogQHBhcmFtIGlucHV0IHRoZSBiYXNlNjQtZW5jb2RlZCBpbnB1dCBzdHJpbmcuCiAqIEBwYXJhbSBbb3V0cHV0XSBhbiBvcHRpb25hbCBVaW50OEFycmF5IHRvIHdyaXRlIHRoZSBvdXRwdXQgdG87IGlmIGl0CiAqICAgICAgICAgIGlzIHRvbyBzbWFsbCwgYW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLgogKiBAcGFyYW0gW29mZnNldF0gdGhlIHN0YXJ0IG9mZnNldCBmb3Igd3JpdGluZyB0byB0aGUgb3V0cHV0IChkZWZhdWx0OiAwKS4KICoKICogQHJldHVybiB0aGUgVWludDhBcnJheSBvciB0aGUgbnVtYmVyIG9mIGJ5dGVzIHdyaXR0ZW4gaWYgb3V0cHV0IHdhcyBnaXZlbi4KICovCnV0aWwuYmluYXJ5LmJhc2U2NC5kZWNvZGUgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBvZmZzZXQpIHsKICB2YXIgb3V0ID0gb3V0cHV0OwogIGlmKCFvdXQpIHsKICAgIG91dCA9IG5ldyBVaW50OEFycmF5KE1hdGguY2VpbChpbnB1dC5sZW5ndGggLyA0KSAqIDMpOwogIH0KCiAgLy8gcmVtb3ZlIGFsbCBub24tYmFzZTY0IGNoYXJhY3RlcnMKICBpbnB1dCA9IGlucHV0LnJlcGxhY2UoL1teQS1aYS16MC05XCtcL1w9XS9nLCAnJyk7CgogIG9mZnNldCA9IG9mZnNldCB8fCAwOwogIHZhciBlbmMxLCBlbmMyLCBlbmMzLCBlbmM0OwogIHZhciBpID0gMCwgaiA9IG9mZnNldDsKCiAgd2hpbGUoaSA8IGlucHV0Lmxlbmd0aCkgewogICAgZW5jMSA9IF9iYXNlNjRJZHhbaW5wdXQuY2hhckNvZGVBdChpKyspIC0gNDNdOwogICAgZW5jMiA9IF9iYXNlNjRJZHhbaW5wdXQuY2hhckNvZGVBdChpKyspIC0gNDNdOwogICAgZW5jMyA9IF9iYXNlNjRJZHhbaW5wdXQuY2hhckNvZGVBdChpKyspIC0gNDNdOwogICAgZW5jNCA9IF9iYXNlNjRJZHhbaW5wdXQuY2hhckNvZGVBdChpKyspIC0gNDNdOwoKICAgIG91dFtqKytdID0gKGVuYzEgPDwgMikgfCAoZW5jMiA+PiA0KTsKICAgIGlmKGVuYzMgIT09IDY0KSB7CiAgICAgIC8vIGRlY29kZWQgYXQgbGVhc3QgMiBieXRlcwogICAgICBvdXRbaisrXSA9ICgoZW5jMiAmIDE1KSA8PCA0KSB8IChlbmMzID4+IDIpOwogICAgICBpZihlbmM0ICE9PSA2NCkgewogICAgICAgIC8vIGRlY29kZWQgMyBieXRlcwogICAgICAgIG91dFtqKytdID0gKChlbmMzICYgMykgPDwgNikgfCBlbmM0OwogICAgICB9CiAgICB9CiAgfQoKICAvLyBtYWtlIHN1cmUgcmVzdWx0IGlzIHRoZSBleGFjdCBkZWNvZGVkIGxlbmd0aAogIHJldHVybiBvdXRwdXQgPwogICAgICAgICAoaiAtIG9mZnNldCkgOgogICAgICAgICBvdXQuc3ViYXJyYXkoMCwgaik7Cn07CgovLyB0ZXh0IGVuY29kaW5nL2RlY29kaW5nIHRvb2xzCi8vIEZJWE1FOiBFeHBlcmltZW50YWwuIERvIG5vdCB1c2UgeWV0Lgp1dGlsLnRleHQgPSB7CiAgdXRmODoge30sCiAgdXRmMTY6IHt9Cn07CgovKioKICogRW5jb2RlcyB0aGUgZ2l2ZW4gc3RyaW5nIGFzIFVURi04IGluIGEgVWludDhBcnJheS4KICoKICogQHBhcmFtIHN0ciB0aGUgc3RyaW5nIHRvIGVuY29kZS4KICogQHBhcmFtIFtvdXRwdXRdIGFuIG9wdGlvbmFsIFVpbnQ4QXJyYXkgdG8gd3JpdGUgdGhlIG91dHB1dCB0bzsgaWYgaXQKICogICAgICAgICAgaXMgdG9vIHNtYWxsLCBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uCiAqIEBwYXJhbSBbb2Zmc2V0XSB0aGUgc3RhcnQgb2Zmc2V0IGZvciB3cml0aW5nIHRvIHRoZSBvdXRwdXQgKGRlZmF1bHQ6IDApLgogKgogKiBAcmV0dXJuIHRoZSBVaW50OEFycmF5IG9yIHRoZSBudW1iZXIgb2YgYnl0ZXMgd3JpdHRlbiBpZiBvdXRwdXQgd2FzIGdpdmVuLgogKi8KdXRpbC50ZXh0LnV0ZjguZW5jb2RlID0gZnVuY3Rpb24oc3RyLCBvdXRwdXQsIG9mZnNldCkgewogIHN0ciA9IHV0aWwuZW5jb2RlVXRmOChzdHIpOwogIHZhciBvdXQgPSBvdXRwdXQ7CiAgaWYoIW91dCkgewogICAgb3V0ID0gbmV3IFVpbnQ4QXJyYXkoc3RyLmxlbmd0aCk7CiAgfQogIG9mZnNldCA9IG9mZnNldCB8fCAwOwogIHZhciBqID0gb2Zmc2V0OwogIGZvcih2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyArK2kpIHsKICAgIG91dFtqKytdID0gc3RyLmNoYXJDb2RlQXQoaSk7CiAgfQogIHJldHVybiBvdXRwdXQgPyAoaiAtIG9mZnNldCkgOiBvdXQ7Cn07CgovKioKICogRGVjb2RlcyB0aGUgVVRGLTggY29udGVudHMgZnJvbSBhIFVpbnQ4QXJyYXkuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgVWludDhBcnJheSB0byBkZWNvZGUuCiAqCiAqIEByZXR1cm4gdGhlIHJlc3VsdGluZyBzdHJpbmcuCiAqLwp1dGlsLnRleHQudXRmOC5kZWNvZGUgPSBmdW5jdGlvbihieXRlcykgewogIHJldHVybiB1dGlsLmRlY29kZVV0ZjgoU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBieXRlcykpOwp9OwoKLyoqCiAqIEVuY29kZXMgdGhlIGdpdmVuIHN0cmluZyBhcyBVVEYtMTYgaW4gYSBVaW50OEFycmF5LgogKgogKiBAcGFyYW0gc3RyIHRoZSBzdHJpbmcgdG8gZW5jb2RlLgogKiBAcGFyYW0gW291dHB1dF0gYW4gb3B0aW9uYWwgVWludDhBcnJheSB0byB3cml0ZSB0aGUgb3V0cHV0IHRvOyBpZiBpdAogKiAgICAgICAgICBpcyB0b28gc21hbGwsIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4KICogQHBhcmFtIFtvZmZzZXRdIHRoZSBzdGFydCBvZmZzZXQgZm9yIHdyaXRpbmcgdG8gdGhlIG91dHB1dCAoZGVmYXVsdDogMCkuCiAqCiAqIEByZXR1cm4gdGhlIFVpbnQ4QXJyYXkgb3IgdGhlIG51bWJlciBvZiBieXRlcyB3cml0dGVuIGlmIG91dHB1dCB3YXMgZ2l2ZW4uCiAqLwp1dGlsLnRleHQudXRmMTYuZW5jb2RlID0gZnVuY3Rpb24oc3RyLCBvdXRwdXQsIG9mZnNldCkgewogIHZhciBvdXQgPSBvdXRwdXQ7CiAgaWYoIW91dCkgewogICAgb3V0ID0gbmV3IFVpbnQ4QXJyYXkoc3RyLmxlbmd0aCAqIDIpOwogIH0KICB2YXIgdmlldyA9IG5ldyBVaW50MTZBcnJheShvdXQuYnVmZmVyKTsKICBvZmZzZXQgPSBvZmZzZXQgfHwgMDsKICB2YXIgaiA9IG9mZnNldDsKICB2YXIgayA9IG9mZnNldDsKICBmb3IodmFyIGkgPSAwOyBpIDwgc3RyLmxlbmd0aDsgKytpKSB7CiAgICB2aWV3W2srK10gPSBzdHIuY2hhckNvZGVBdChpKTsKICAgIGogKz0gMjsKICB9CiAgcmV0dXJuIG91dHB1dCA/IChqIC0gb2Zmc2V0KSA6IG91dDsKfTsKCi8qKgogKiBEZWNvZGVzIHRoZSBVVEYtMTYgY29udGVudHMgZnJvbSBhIFVpbnQ4QXJyYXkuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgVWludDhBcnJheSB0byBkZWNvZGUuCiAqCiAqIEByZXR1cm4gdGhlIHJlc3VsdGluZyBzdHJpbmcuCiAqLwp1dGlsLnRleHQudXRmMTYuZGVjb2RlID0gZnVuY3Rpb24oYnl0ZXMpIHsKICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDE2QXJyYXkoYnl0ZXMuYnVmZmVyKSk7Cn07CgovKioKICogRGVmbGF0ZXMgdGhlIGdpdmVuIGRhdGEgdXNpbmcgYSBmbGFzaCBpbnRlcmZhY2UuCiAqCiAqIEBwYXJhbSBhcGkgdGhlIGZsYXNoIGludGVyZmFjZS4KICogQHBhcmFtIGJ5dGVzIHRoZSBkYXRhLgogKiBAcGFyYW0gcmF3IHRydWUgdG8gcmV0dXJuIG9ubHkgcmF3IGRlZmxhdGUgZGF0YSwgZmFsc2UgdG8gaW5jbHVkZSB6bGliCiAqICAgICAgICAgIGhlYWRlciBhbmQgdHJhaWxlci4KICoKICogQHJldHVybiB0aGUgZGVmbGF0ZWQgZGF0YSBhcyBhIHN0cmluZy4KICovCnV0aWwuZGVmbGF0ZSA9IGZ1bmN0aW9uKGFwaSwgYnl0ZXMsIHJhdykgewogIGJ5dGVzID0gdXRpbC5kZWNvZGU2NChhcGkuZGVmbGF0ZSh1dGlsLmVuY29kZTY0KGJ5dGVzKSkucnZhbCk7CgogIC8vIHN0cmlwIHpsaWIgaGVhZGVyIGFuZCB0cmFpbGVyIGlmIG5lY2Vzc2FyeQogIGlmKHJhdykgewogICAgLy8gemxpYiBoZWFkZXIgaXMgMiBieXRlcyAoQ01GLEZMRykgd2hlcmUgRkxHIGluZGljYXRlcyB0aGF0CiAgICAvLyB0aGVyZSBpcyBhIDQtYnl0ZSBESUNUIChhbGRlci0zMikgYmxvY2sgYmVmb3JlIHRoZSBkYXRhIGlmCiAgICAvLyBpdHMgNXRoIGJpdCBpcyBzZXQKICAgIHZhciBzdGFydCA9IDI7CiAgICB2YXIgZmxnID0gYnl0ZXMuY2hhckNvZGVBdCgxKTsKICAgIGlmKGZsZyAmIDB4MjApIHsKICAgICAgc3RhcnQgPSA2OwogICAgfQogICAgLy8gemxpYiB0cmFpbGVyIGlzIDQgYnl0ZXMgb2YgYWRsZXItMzIKICAgIGJ5dGVzID0gYnl0ZXMuc3Vic3RyaW5nKHN0YXJ0LCBieXRlcy5sZW5ndGggLSA0KTsKICB9CgogIHJldHVybiBieXRlczsKfTsKCi8qKgogKiBJbmZsYXRlcyB0aGUgZ2l2ZW4gZGF0YSB1c2luZyBhIGZsYXNoIGludGVyZmFjZS4KICoKICogQHBhcmFtIGFwaSB0aGUgZmxhc2ggaW50ZXJmYWNlLgogKiBAcGFyYW0gYnl0ZXMgdGhlIGRhdGEuCiAqIEBwYXJhbSByYXcgdHJ1ZSBpZiB0aGUgaW5jb21pbmcgZGF0YSBoYXMgbm8gemxpYiBoZWFkZXIgb3IgdHJhaWxlciBhbmQgaXMKICogICAgICAgICAgcmF3IERFRkxBVEUgZGF0YS4KICoKICogQHJldHVybiB0aGUgaW5mbGF0ZWQgZGF0YSBhcyBhIHN0cmluZywgbnVsbCBvbiBlcnJvci4KICovCnV0aWwuaW5mbGF0ZSA9IGZ1bmN0aW9uKGFwaSwgYnl0ZXMsIHJhdykgewogIC8vIFRPRE86IGFkZCB6bGliIGhlYWRlciBhbmQgdHJhaWxlciBpZiBuZWNlc3NhcnkvcG9zc2libGUKICB2YXIgcnZhbCA9IGFwaS5pbmZsYXRlKHV0aWwuZW5jb2RlNjQoYnl0ZXMpKS5ydmFsOwogIHJldHVybiAocnZhbCA9PT0gbnVsbCkgPyBudWxsIDogdXRpbC5kZWNvZGU2NChydmFsKTsKfTsKCi8qKgogKiBTZXRzIGEgc3RvcmFnZSBvYmplY3QuCiAqCiAqIEBwYXJhbSBhcGkgdGhlIHN0b3JhZ2UgaW50ZXJmYWNlLgogKiBAcGFyYW0gaWQgdGhlIHN0b3JhZ2UgSUQgdG8gdXNlLgogKiBAcGFyYW0gb2JqIHRoZSBzdG9yYWdlIG9iamVjdCwgbnVsbCB0byByZW1vdmUuCiAqLwp2YXIgX3NldFN0b3JhZ2VPYmplY3QgPSBmdW5jdGlvbihhcGksIGlkLCBvYmopIHsKICBpZighYXBpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYlN0b3JhZ2Ugbm90IGF2YWlsYWJsZS4nKTsKICB9CgogIHZhciBydmFsOwogIGlmKG9iaiA9PT0gbnVsbCkgewogICAgcnZhbCA9IGFwaS5yZW1vdmVJdGVtKGlkKTsKICB9IGVsc2UgewogICAgLy8ganNvbi1lbmNvZGUgYW5kIGJhc2U2NC1lbmNvZGUgb2JqZWN0CiAgICBvYmogPSB1dGlsLmVuY29kZTY0KEpTT04uc3RyaW5naWZ5KG9iaikpOwogICAgcnZhbCA9IGFwaS5zZXRJdGVtKGlkLCBvYmopOwogIH0KCiAgLy8gaGFuZGxlIHBvdGVudGlhbCBmbGFzaCBlcnJvcgogIGlmKHR5cGVvZihydmFsKSAhPT0gJ3VuZGVmaW5lZCcgJiYgcnZhbC5ydmFsICE9PSB0cnVlKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IocnZhbC5lcnJvci5tZXNzYWdlKTsKICAgIGVycm9yLmlkID0gcnZhbC5lcnJvci5pZDsKICAgIGVycm9yLm5hbWUgPSBydmFsLmVycm9yLm5hbWU7CiAgICB0aHJvdyBlcnJvcjsKICB9Cn07CgovKioKICogR2V0cyBhIHN0b3JhZ2Ugb2JqZWN0LgogKgogKiBAcGFyYW0gYXBpIHRoZSBzdG9yYWdlIGludGVyZmFjZS4KICogQHBhcmFtIGlkIHRoZSBzdG9yYWdlIElEIHRvIHVzZS4KICoKICogQHJldHVybiB0aGUgc3RvcmFnZSBvYmplY3QgZW50cnkgb3IgbnVsbCBpZiBub25lIGV4aXN0cy4KICovCnZhciBfZ2V0U3RvcmFnZU9iamVjdCA9IGZ1bmN0aW9uKGFwaSwgaWQpIHsKICBpZighYXBpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1dlYlN0b3JhZ2Ugbm90IGF2YWlsYWJsZS4nKTsKICB9CgogIC8vIGdldCB0aGUgZXhpc3RpbmcgZW50cnkKICB2YXIgcnZhbCA9IGFwaS5nZXRJdGVtKGlkKTsKCiAgLyogTm90ZTogV2UgY2hlY2sgYXBpLmluaXQgYmVjYXVzZSB3ZSBjYW4ndCBkbyAoYXBpID09IGxvY2FsU3RvcmFnZSkKICAgIG9uIElFIGJlY2F1c2Ugb2YgIkNsYXNzIGRvZXNuJ3Qgc3VwcG9ydCBBdXRvbWF0aW9uIiBleGNlcHRpb24uIE9ubHkKICAgIHRoZSBmbGFzaCBhcGkgaGFzIGFuIGluaXQgbWV0aG9kIHNvIHRoaXMgd29ya3MgdG9vLCBidXQgd2UgbmVlZCBhCiAgICBiZXR0ZXIgc29sdXRpb24gaW4gdGhlIGZ1dHVyZS4gKi8KCiAgLy8gZmxhc2ggcmV0dXJucyBpdGVtIHdyYXBwZWQgaW4gYW4gb2JqZWN0LCBoYW5kbGUgc3BlY2lhbCBjYXNlCiAgaWYoYXBpLmluaXQpIHsKICAgIGlmKHJ2YWwucnZhbCA9PT0gbnVsbCkgewogICAgICBpZihydmFsLmVycm9yKSB7CiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKHJ2YWwuZXJyb3IubWVzc2FnZSk7CiAgICAgICAgZXJyb3IuaWQgPSBydmFsLmVycm9yLmlkOwogICAgICAgIGVycm9yLm5hbWUgPSBydmFsLmVycm9yLm5hbWU7CiAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgIH0KICAgICAgLy8gbm8gZXJyb3IsIGJ1dCBhbHNvIG5vIGl0ZW0KICAgICAgcnZhbCA9IG51bGw7CiAgICB9IGVsc2UgewogICAgICBydmFsID0gcnZhbC5ydmFsOwogICAgfQogIH0KCiAgLy8gaGFuZGxlIGRlY29kaW5nCiAgaWYocnZhbCAhPT0gbnVsbCkgewogICAgLy8gYmFzZTY0LWRlY29kZSBhbmQganNvbi1kZWNvZGUgZGF0YQogICAgcnZhbCA9IEpTT04ucGFyc2UodXRpbC5kZWNvZGU2NChydmFsKSk7CiAgfQoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBTdG9yZXMgYW4gaXRlbSBpbiBsb2NhbCBzdG9yYWdlLgogKgogKiBAcGFyYW0gYXBpIHRoZSBzdG9yYWdlIGludGVyZmFjZS4KICogQHBhcmFtIGlkIHRoZSBzdG9yYWdlIElEIHRvIHVzZS4KICogQHBhcmFtIGtleSB0aGUga2V5IGZvciB0aGUgaXRlbS4KICogQHBhcmFtIGRhdGEgdGhlIGRhdGEgZm9yIHRoZSBpdGVtIChhbnkgamF2YXNjcmlwdCBvYmplY3QvcHJpbWl0aXZlKS4KICovCnZhciBfc2V0SXRlbSA9IGZ1bmN0aW9uKGFwaSwgaWQsIGtleSwgZGF0YSkgewogIC8vIGdldCBzdG9yYWdlIG9iamVjdAogIHZhciBvYmogPSBfZ2V0U3RvcmFnZU9iamVjdChhcGksIGlkKTsKICBpZihvYmogPT09IG51bGwpIHsKICAgIC8vIGNyZWF0ZSBhIG5ldyBzdG9yYWdlIG9iamVjdAogICAgb2JqID0ge307CiAgfQogIC8vIHVwZGF0ZSBrZXkKICBvYmpba2V5XSA9IGRhdGE7CgogIC8vIHNldCBzdG9yYWdlIG9iamVjdAogIF9zZXRTdG9yYWdlT2JqZWN0KGFwaSwgaWQsIG9iaik7Cn07CgovKioKICogR2V0cyBhbiBpdGVtIGZyb20gbG9jYWwgc3RvcmFnZS4KICoKICogQHBhcmFtIGFwaSB0aGUgc3RvcmFnZSBpbnRlcmZhY2UuCiAqIEBwYXJhbSBpZCB0aGUgc3RvcmFnZSBJRCB0byB1c2UuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSBmb3IgdGhlIGl0ZW0uCiAqCiAqIEByZXR1cm4gdGhlIGl0ZW0uCiAqLwp2YXIgX2dldEl0ZW0gPSBmdW5jdGlvbihhcGksIGlkLCBrZXkpIHsKICAvLyBnZXQgc3RvcmFnZSBvYmplY3QKICB2YXIgcnZhbCA9IF9nZXRTdG9yYWdlT2JqZWN0KGFwaSwgaWQpOwogIGlmKHJ2YWwgIT09IG51bGwpIHsKICAgIC8vIHJldHVybiBkYXRhIGF0IGtleQogICAgcnZhbCA9IChrZXkgaW4gcnZhbCkgPyBydmFsW2tleV0gOiBudWxsOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogUmVtb3ZlcyBhbiBpdGVtIGZyb20gbG9jYWwgc3RvcmFnZS4KICoKICogQHBhcmFtIGFwaSB0aGUgc3RvcmFnZSBpbnRlcmZhY2UuCiAqIEBwYXJhbSBpZCB0aGUgc3RvcmFnZSBJRCB0byB1c2UuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSBmb3IgdGhlIGl0ZW0uCiAqLwp2YXIgX3JlbW92ZUl0ZW0gPSBmdW5jdGlvbihhcGksIGlkLCBrZXkpIHsKICAvLyBnZXQgc3RvcmFnZSBvYmplY3QKICB2YXIgb2JqID0gX2dldFN0b3JhZ2VPYmplY3QoYXBpLCBpZCk7CiAgaWYob2JqICE9PSBudWxsICYmIGtleSBpbiBvYmopIHsKICAgIC8vIHJlbW92ZSBrZXkKICAgIGRlbGV0ZSBvYmpba2V5XTsKCiAgICAvLyBzZWUgaWYgZW50cnkgaGFzIG5vIGtleXMgcmVtYWluaW5nCiAgICB2YXIgZW1wdHkgPSB0cnVlOwogICAgZm9yKHZhciBwcm9wIGluIG9iaikgewogICAgICBlbXB0eSA9IGZhbHNlOwogICAgICBicmVhazsKICAgIH0KICAgIGlmKGVtcHR5KSB7CiAgICAgIC8vIHJlbW92ZSBlbnRyeSBlbnRpcmVseSBpZiBubyBrZXlzIGFyZSBsZWZ0CiAgICAgIG9iaiA9IG51bGw7CiAgICB9CgogICAgLy8gc2V0IHN0b3JhZ2Ugb2JqZWN0CiAgICBfc2V0U3RvcmFnZU9iamVjdChhcGksIGlkLCBvYmopOwogIH0KfTsKCi8qKgogKiBDbGVhcnMgdGhlIGxvY2FsIGRpc2sgc3RvcmFnZSBpZGVudGlmaWVkIGJ5IHRoZSBnaXZlbiBJRC4KICoKICogQHBhcmFtIGFwaSB0aGUgc3RvcmFnZSBpbnRlcmZhY2UuCiAqIEBwYXJhbSBpZCB0aGUgc3RvcmFnZSBJRCB0byB1c2UuCiAqLwp2YXIgX2NsZWFySXRlbXMgPSBmdW5jdGlvbihhcGksIGlkKSB7CiAgX3NldFN0b3JhZ2VPYmplY3QoYXBpLCBpZCwgbnVsbCk7Cn07CgovKioKICogQ2FsbHMgYSBzdG9yYWdlIGZ1bmN0aW9uLgogKgogKiBAcGFyYW0gZnVuYyB0aGUgZnVuY3Rpb24gdG8gY2FsbC4KICogQHBhcmFtIGFyZ3MgdGhlIGFyZ3VtZW50cyBmb3IgdGhlIGZ1bmN0aW9uLgogKiBAcGFyYW0gbG9jYXRpb24gdGhlIGxvY2F0aW9uIGFyZ3VtZW50LgogKgogKiBAcmV0dXJuIHRoZSByZXR1cm4gdmFsdWUgZnJvbSB0aGUgZnVuY3Rpb24uCiAqLwp2YXIgX2NhbGxTdG9yYWdlRnVuY3Rpb24gPSBmdW5jdGlvbihmdW5jLCBhcmdzLCBsb2NhdGlvbikgewogIHZhciBydmFsID0gbnVsbDsKCiAgLy8gZGVmYXVsdCBzdG9yYWdlIHR5cGVzCiAgaWYodHlwZW9mKGxvY2F0aW9uKSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIGxvY2F0aW9uID0gWyd3ZWInLCAnZmxhc2gnXTsKICB9CgogIC8vIGFwcGx5IHN0b3JhZ2UgdHlwZXMgaW4gb3JkZXIgb2YgcHJlZmVyZW5jZQogIHZhciB0eXBlOwogIHZhciBkb25lID0gZmFsc2U7CiAgdmFyIGV4Y2VwdGlvbiA9IG51bGw7CiAgZm9yKHZhciBpZHggaW4gbG9jYXRpb24pIHsKICAgIHR5cGUgPSBsb2NhdGlvbltpZHhdOwogICAgdHJ5IHsKICAgICAgaWYodHlwZSA9PT0gJ2ZsYXNoJyB8fCB0eXBlID09PSAnYm90aCcpIHsKICAgICAgICBpZihhcmdzWzBdID09PSBudWxsKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ZsYXNoIGxvY2FsIHN0b3JhZ2Ugbm90IGF2YWlsYWJsZS4nKTsKICAgICAgICB9CiAgICAgICAgcnZhbCA9IGZ1bmMuYXBwbHkodGhpcywgYXJncyk7CiAgICAgICAgZG9uZSA9ICh0eXBlID09PSAnZmxhc2gnKTsKICAgICAgfQogICAgICBpZih0eXBlID09PSAnd2ViJyB8fCB0eXBlID09PSAnYm90aCcpIHsKICAgICAgICBhcmdzWzBdID0gbG9jYWxTdG9yYWdlOwogICAgICAgIHJ2YWwgPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpOwogICAgICAgIGRvbmUgPSB0cnVlOwogICAgICB9CiAgICB9IGNhdGNoKGV4KSB7CiAgICAgIGV4Y2VwdGlvbiA9IGV4OwogICAgfQogICAgaWYoZG9uZSkgewogICAgICBicmVhazsKICAgIH0KICB9CgogIGlmKCFkb25lKSB7CiAgICB0aHJvdyBleGNlcHRpb247CiAgfQoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBTdG9yZXMgYW4gaXRlbSBvbiBsb2NhbCBkaXNrLgogKgogKiBUaGUgYXZhaWxhYmxlIHR5cGVzIG9mIGxvY2FsIHN0b3JhZ2UgaW5jbHVkZSAnZmxhc2gnLCAnd2ViJywgYW5kICdib3RoJy4KICoKICogVGhlIHR5cGUgJ2ZsYXNoJyByZWZlcnMgdG8gZmxhc2ggbG9jYWwgc3RvcmFnZSAoU2hhcmVkT2JqZWN0KS4gSW4gb3JkZXIKICogdG8gdXNlIGZsYXNoIGxvY2FsIHN0b3JhZ2UsIHRoZSAnYXBpJyBwYXJhbWV0ZXIgbXVzdCBiZSB2YWxpZC4gVGhlIHR5cGUKICogJ3dlYicgcmVmZXJzIHRvIFdlYlN0b3JhZ2UsIGlmIHN1cHBvcnRlZCBieSB0aGUgYnJvd3Nlci4gVGhlIHR5cGUgJ2JvdGgnCiAqIHJlZmVycyB0byBzdG9yaW5nIHVzaW5nIGJvdGggJ2ZsYXNoJyBhbmQgJ3dlYicsIG5vdCBqdXN0IG9uZSBvciB0aGUKICogb3RoZXIuCiAqCiAqIFRoZSBsb2NhdGlvbiBhcnJheSBzaG91bGQgbGlzdCB0aGUgc3RvcmFnZSB0eXBlcyB0byB1c2UgaW4gb3JkZXIgb2YKICogcHJlZmVyZW5jZToKICoKICogWydmbGFzaCddOiBmbGFzaCBvbmx5IHN0b3JhZ2UKICogWyd3ZWInXTogd2ViIG9ubHkgc3RvcmFnZQogKiBbJ2JvdGgnXTogdHJ5IHRvIHN0b3JlIGluIGJvdGgKICogWydmbGFzaCcsJ3dlYiddOiBzdG9yZSBpbiBmbGFzaCBmaXJzdCwgYnV0IGlmIG5vdCBhdmFpbGFibGUsICd3ZWInCiAqIFsnd2ViJywnZmxhc2gnXTogc3RvcmUgaW4gd2ViIGZpcnN0LCBidXQgaWYgbm90IGF2YWlsYWJsZSwgJ2ZsYXNoJwogKgogKiBUaGUgbG9jYXRpb24gYXJyYXkgZGVmYXVsdHMgdG86IFsnd2ViJywgJ2ZsYXNoJ10KICoKICogQHBhcmFtIGFwaSB0aGUgZmxhc2ggaW50ZXJmYWNlLCBudWxsIHRvIHVzZSBvbmx5IFdlYlN0b3JhZ2UuCiAqIEBwYXJhbSBpZCB0aGUgc3RvcmFnZSBJRCB0byB1c2UuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSBmb3IgdGhlIGl0ZW0uCiAqIEBwYXJhbSBkYXRhIHRoZSBkYXRhIGZvciB0aGUgaXRlbSAoYW55IGphdmFzY3JpcHQgb2JqZWN0L3ByaW1pdGl2ZSkuCiAqIEBwYXJhbSBsb2NhdGlvbiBhbiBhcnJheSB3aXRoIHRoZSBwcmVmZXJyZWQgdHlwZXMgb2Ygc3RvcmFnZSB0byB1c2UuCiAqLwp1dGlsLnNldEl0ZW0gPSBmdW5jdGlvbihhcGksIGlkLCBrZXksIGRhdGEsIGxvY2F0aW9uKSB7CiAgX2NhbGxTdG9yYWdlRnVuY3Rpb24oX3NldEl0ZW0sIGFyZ3VtZW50cywgbG9jYXRpb24pOwp9OwoKLyoqCiAqIEdldHMgYW4gaXRlbSBvbiBsb2NhbCBkaXNrLgogKgogKiBTZXQgc2V0SXRlbSgpIGZvciBkZXRhaWxzIG9uIHN0b3JhZ2UgdHlwZXMuCiAqCiAqIEBwYXJhbSBhcGkgdGhlIGZsYXNoIGludGVyZmFjZSwgbnVsbCB0byB1c2Ugb25seSBXZWJTdG9yYWdlLgogKiBAcGFyYW0gaWQgdGhlIHN0b3JhZ2UgSUQgdG8gdXNlLgogKiBAcGFyYW0ga2V5IHRoZSBrZXkgZm9yIHRoZSBpdGVtLgogKiBAcGFyYW0gbG9jYXRpb24gYW4gYXJyYXkgd2l0aCB0aGUgcHJlZmVycmVkIHR5cGVzIG9mIHN0b3JhZ2UgdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSBpdGVtLgogKi8KdXRpbC5nZXRJdGVtID0gZnVuY3Rpb24oYXBpLCBpZCwga2V5LCBsb2NhdGlvbikgewogIHJldHVybiBfY2FsbFN0b3JhZ2VGdW5jdGlvbihfZ2V0SXRlbSwgYXJndW1lbnRzLCBsb2NhdGlvbik7Cn07CgovKioKICogUmVtb3ZlcyBhbiBpdGVtIG9uIGxvY2FsIGRpc2suCiAqCiAqIFNldCBzZXRJdGVtKCkgZm9yIGRldGFpbHMgb24gc3RvcmFnZSB0eXBlcy4KICoKICogQHBhcmFtIGFwaSB0aGUgZmxhc2ggaW50ZXJmYWNlLgogKiBAcGFyYW0gaWQgdGhlIHN0b3JhZ2UgSUQgdG8gdXNlLgogKiBAcGFyYW0ga2V5IHRoZSBrZXkgZm9yIHRoZSBpdGVtLgogKiBAcGFyYW0gbG9jYXRpb24gYW4gYXJyYXkgd2l0aCB0aGUgcHJlZmVycmVkIHR5cGVzIG9mIHN0b3JhZ2UgdG8gdXNlLgogKi8KdXRpbC5yZW1vdmVJdGVtID0gZnVuY3Rpb24oYXBpLCBpZCwga2V5LCBsb2NhdGlvbikgewogIF9jYWxsU3RvcmFnZUZ1bmN0aW9uKF9yZW1vdmVJdGVtLCBhcmd1bWVudHMsIGxvY2F0aW9uKTsKfTsKCi8qKgogKiBDbGVhcnMgdGhlIGxvY2FsIGRpc2sgc3RvcmFnZSBpZGVudGlmaWVkIGJ5IHRoZSBnaXZlbiBJRC4KICoKICogU2V0IHNldEl0ZW0oKSBmb3IgZGV0YWlscyBvbiBzdG9yYWdlIHR5cGVzLgogKgogKiBAcGFyYW0gYXBpIHRoZSBmbGFzaCBpbnRlcmZhY2UgaWYgZmxhc2ggaXMgYXZhaWxhYmxlLgogKiBAcGFyYW0gaWQgdGhlIHN0b3JhZ2UgSUQgdG8gdXNlLgogKiBAcGFyYW0gbG9jYXRpb24gYW4gYXJyYXkgd2l0aCB0aGUgcHJlZmVycmVkIHR5cGVzIG9mIHN0b3JhZ2UgdG8gdXNlLgogKi8KdXRpbC5jbGVhckl0ZW1zID0gZnVuY3Rpb24oYXBpLCBpZCwgbG9jYXRpb24pIHsKICBfY2FsbFN0b3JhZ2VGdW5jdGlvbihfY2xlYXJJdGVtcywgYXJndW1lbnRzLCBsb2NhdGlvbik7Cn07CgovKioKICogUGFyc2VzIHRoZSBzY2hlbWUsIGhvc3QsIGFuZCBwb3J0IGZyb20gYW4gaHR0cChzKSB1cmwuCiAqCiAqIEBwYXJhbSBzdHIgdGhlIHVybCBzdHJpbmcuCiAqCiAqIEByZXR1cm4gdGhlIHBhcnNlZCB1cmwgb2JqZWN0IG9yIG51bGwgaWYgdGhlIHVybCBpcyBpbnZhbGlkLgogKi8KdXRpbC5wYXJzZVVybCA9IGZ1bmN0aW9uKHN0cikgewogIC8vIEZJWE1FOiB0aGlzIHJlZ2V4IGxvb2tzIGEgYml0IGJyb2tlbgogIHZhciByZWdleCA9IC9eKGh0dHBzPyk6XC9cLyhbXjomXlwvXSopOj8oXGQqKSguKikkL2c7CiAgcmVnZXgubGFzdEluZGV4ID0gMDsKICB2YXIgbSA9IHJlZ2V4LmV4ZWMoc3RyKTsKICB2YXIgdXJsID0gKG0gPT09IG51bGwpID8gbnVsbCA6IHsKICAgIGZ1bGw6IHN0ciwKICAgIHNjaGVtZTogbVsxXSwKICAgIGhvc3Q6IG1bMl0sCiAgICBwb3J0OiBtWzNdLAogICAgcGF0aDogbVs0XQogIH07CiAgaWYodXJsKSB7CiAgICB1cmwuZnVsbEhvc3QgPSB1cmwuaG9zdDsKICAgIGlmKHVybC5wb3J0KSB7CiAgICAgIGlmKHVybC5wb3J0ICE9PSA4MCAmJiB1cmwuc2NoZW1lID09PSAnaHR0cCcpIHsKICAgICAgICB1cmwuZnVsbEhvc3QgKz0gJzonICsgdXJsLnBvcnQ7CiAgICAgIH0gZWxzZSBpZih1cmwucG9ydCAhPT0gNDQzICYmIHVybC5zY2hlbWUgPT09ICdodHRwcycpIHsKICAgICAgICB1cmwuZnVsbEhvc3QgKz0gJzonICsgdXJsLnBvcnQ7CiAgICAgIH0KICAgIH0gZWxzZSBpZih1cmwuc2NoZW1lID09PSAnaHR0cCcpIHsKICAgICAgdXJsLnBvcnQgPSA4MDsKICAgIH0gZWxzZSBpZih1cmwuc2NoZW1lID09PSAnaHR0cHMnKSB7CiAgICAgIHVybC5wb3J0ID0gNDQzOwogICAgfQogICAgdXJsLmZ1bGwgPSB1cmwuc2NoZW1lICsgJzovLycgKyB1cmwuZnVsbEhvc3Q7CiAgfQogIHJldHVybiB1cmw7Cn07CgovKiBTdG9yYWdlIGZvciBxdWVyeSB2YXJpYWJsZXMgKi8KdmFyIF9xdWVyeVZhcmlhYmxlcyA9IG51bGw7CgovKioKICogUmV0dXJucyB0aGUgd2luZG93IGxvY2F0aW9uIHF1ZXJ5IHZhcmlhYmxlcy4gUXVlcnkgaXMgcGFyc2VkIG9uIHRoZSBmaXJzdAogKiBjYWxsIGFuZCB0aGUgc2FtZSBvYmplY3QgaXMgcmV0dXJuZWQgb24gc3Vic2VxdWVudCBjYWxscy4gVGhlIG1hcHBpbmcKICogaXMgZnJvbSBrZXlzIHRvIGFuIGFycmF5IG9mIHZhbHVlcy4gUGFyYW1ldGVycyB3aXRob3V0IHZhbHVlcyB3aWxsIGhhdmUKICogYW4gb2JqZWN0IGtleSBzZXQgYnV0IG5vIHZhbHVlIGFkZGVkIHRvIHRoZSB2YWx1ZSBhcnJheS4gVmFsdWVzIGFyZQogKiB1bmVzY2FwZWQuCiAqCiAqIC4uLj9rMT12MSZrMj12MjoKICogewogKiAgICJrMSI6IFsidjEiXSwKICogICAiazIiOiBbInYyIl0KICogfQogKgogKiAuLi4/azE9djEmazE9djI6CiAqIHsKICogICAiazEiOiBbInYxIiwgInYyIl0KICogfQogKgogKiAuLi4/azE9djEmazI6CiAqIHsKICogICAiazEiOiBbInYxIl0sCiAqICAgImsyIjogW10KICogfQogKgogKiAuLi4/azE9djEmazE6CiAqIHsKICogICAiazEiOiBbInYxIl0KICogfQogKgogKiAuLi4/azEmazE6CiAqIHsKICogICAiazEiOiBbXQogKiB9CiAqCiAqIEBwYXJhbSBxdWVyeSB0aGUgcXVlcnkgc3RyaW5nIHRvIHBhcnNlIChvcHRpb25hbCwgZGVmYXVsdCB0byBjYWNoZWQKICogICAgICAgICAgcmVzdWx0cyBmcm9tIHBhcnNpbmcgd2luZG93IGxvY2F0aW9uIHNlYXJjaCBxdWVyeSkuCiAqCiAqIEByZXR1cm4gb2JqZWN0IG1hcHBpbmcga2V5cyB0byB2YXJpYWJsZXMuCiAqLwp1dGlsLmdldFF1ZXJ5VmFyaWFibGVzID0gZnVuY3Rpb24ocXVlcnkpIHsKICB2YXIgcGFyc2UgPSBmdW5jdGlvbihxKSB7CiAgICB2YXIgcnZhbCA9IHt9OwogICAgdmFyIGt2cGFpcnMgPSBxLnNwbGl0KCcmJyk7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwga3ZwYWlycy5sZW5ndGg7IGkrKykgewogICAgICB2YXIgcG9zID0ga3ZwYWlyc1tpXS5pbmRleE9mKCc9Jyk7CiAgICAgIHZhciBrZXk7CiAgICAgIHZhciB2YWw7CiAgICAgIGlmKHBvcyA+IDApIHsKICAgICAgICBrZXkgPSBrdnBhaXJzW2ldLnN1YnN0cmluZygwLCBwb3MpOwogICAgICAgIHZhbCA9IGt2cGFpcnNbaV0uc3Vic3RyaW5nKHBvcyArIDEpOwogICAgICB9IGVsc2UgewogICAgICAgIGtleSA9IGt2cGFpcnNbaV07CiAgICAgICAgdmFsID0gbnVsbDsKICAgICAgfQogICAgICBpZighKGtleSBpbiBydmFsKSkgewogICAgICAgIHJ2YWxba2V5XSA9IFtdOwogICAgICB9CiAgICAgIC8vIGRpc2FsbG93IG92ZXJyaWRpbmcgb2JqZWN0IHByb3RvdHlwZSBrZXlzCiAgICAgIGlmKCEoa2V5IGluIE9iamVjdC5wcm90b3R5cGUpICYmIHZhbCAhPT0gbnVsbCkgewogICAgICAgIHJ2YWxba2V5XS5wdXNoKHVuZXNjYXBlKHZhbCkpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAgdmFyIHJ2YWw7CiAgIGlmKHR5cGVvZihxdWVyeSkgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgLy8gc2V0IGNhY2hlZCB2YXJpYWJsZXMgaWYgbmVlZGVkCiAgICAgaWYoX3F1ZXJ5VmFyaWFibGVzID09PSBudWxsKSB7CiAgICAgICBpZih0eXBlb2Yod2luZG93KSAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LmxvY2F0aW9uICYmIHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpIHsKICAgICAgICAgIC8vIHBhcnNlIHdpbmRvdyBzZWFyY2ggcXVlcnkKICAgICAgICAgIF9xdWVyeVZhcmlhYmxlcyA9IHBhcnNlKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guc3Vic3RyaW5nKDEpKTsKICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBubyBxdWVyeSB2YXJpYWJsZXMgYXZhaWxhYmxlCiAgICAgICAgICBfcXVlcnlWYXJpYWJsZXMgPSB7fTsKICAgICAgIH0KICAgICB9CiAgICAgcnZhbCA9IF9xdWVyeVZhcmlhYmxlczsKICAgfSBlbHNlIHsKICAgICAvLyBwYXJzZSBnaXZlbiBxdWVyeQogICAgIHJ2YWwgPSBwYXJzZShxdWVyeSk7CiAgIH0KICAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogUGFyc2VzIGEgZnJhZ21lbnQgaW50byBhIHBhdGggYW5kIHF1ZXJ5LiBUaGlzIG1ldGhvZCB3aWxsIHRha2UgYSBVUkkKICogZnJhZ21lbnQgYW5kIGJyZWFrIGl0IHVwIGFzIGlmIGl0IHdlcmUgdGhlIG1haW4gVVJJLiBGb3IgZXhhbXBsZToKICogICAgL2Jhci9iYXo/YT0xJmI9MgogKiByZXN1bHRzIGluOgogKiAgICB7CiAqICAgICAgIHBhdGg6IFsiYmFyIiwgImJheiJdLAogKiAgICAgICBxdWVyeTogeyJrMSI6IFsidjEiXSwgImsyIjogWyJ2MiJdfQogKiAgICB9CiAqCiAqIEByZXR1cm4gb2JqZWN0IHdpdGggYSBwYXRoIGFycmF5IGFuZCBxdWVyeSBvYmplY3QuCiAqLwp1dGlsLnBhcnNlRnJhZ21lbnQgPSBmdW5jdGlvbihmcmFnbWVudCkgewogIC8vIGRlZmF1bHQgdG8gd2hvbGUgZnJhZ21lbnQKICB2YXIgZnAgPSBmcmFnbWVudDsKICB2YXIgZnEgPSAnJzsKICAvLyBzcGxpdCBpbnRvIHBhdGggYW5kIHF1ZXJ5IGlmIHBvc3NpYmxlIGF0IHRoZSBmaXJzdCAnPycKICB2YXIgcG9zID0gZnJhZ21lbnQuaW5kZXhPZignPycpOwogIGlmKHBvcyA+IDApIHsKICAgIGZwID0gZnJhZ21lbnQuc3Vic3RyaW5nKDAsIHBvcyk7CiAgICBmcSA9IGZyYWdtZW50LnN1YnN0cmluZyhwb3MgKyAxKTsKICB9CiAgLy8gc3BsaXQgcGF0aCBiYXNlZCBvbiAnLycgYW5kIGlnbm9yZSBmaXJzdCBlbGVtZW50IGlmIGVtcHR5CiAgdmFyIHBhdGggPSBmcC5zcGxpdCgnLycpOwogIGlmKHBhdGgubGVuZ3RoID4gMCAmJiBwYXRoWzBdID09PSAnJykgewogICAgcGF0aC5zaGlmdCgpOwogIH0KICAvLyBjb252ZXJ0IHF1ZXJ5IGludG8gb2JqZWN0CiAgdmFyIHF1ZXJ5ID0gKGZxID09PSAnJykgPyB7fSA6IHV0aWwuZ2V0UXVlcnlWYXJpYWJsZXMoZnEpOwoKICByZXR1cm4gewogICAgcGF0aFN0cmluZzogZnAsCiAgICBxdWVyeVN0cmluZzogZnEsCiAgICBwYXRoOiBwYXRoLAogICAgcXVlcnk6IHF1ZXJ5CiAgfTsKfTsKCi8qKgogKiBNYWtlcyBhIHJlcXVlc3Qgb3V0IG9mIGEgVVJJLWxpa2UgcmVxdWVzdCBzdHJpbmcuIFRoaXMgaXMgaW50ZW5kZWQgdG8KICogYmUgdXNlZCB3aGVyZSBhIGZyYWdtZW50IGlkIChhZnRlciBhIFVSSSAnIycpIGlzIHBhcnNlZCBhcyBhIFVSSSB3aXRoCiAqIHBhdGggYW5kIHF1ZXJ5IHBhcnRzLiBUaGUgc3RyaW5nIHNob3VsZCBoYXZlIGEgcGF0aCBiZWdpbm5pbmcgYW5kCiAqIGRlbGltaXRlZCBieSAnLycgYW5kIG9wdGlvbmFsIHF1ZXJ5IHBhcmFtZXRlcnMgZm9sbG93aW5nIGEgJz8nLiBUaGUKICogcXVlcnkgc2hvdWxkIGJlIGEgc3RhbmRhcmQgVVJMIHNldCBvZiBrZXkgdmFsdWUgcGFpcnMgZGVsaW1pdGVkIGJ5CiAqICcmJy4gRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHRoZSBpbml0aWFsICcvJyBvbiB0aGUgcGF0aCBpcyBub3QKICogcmVxdWlyZWQuIFRoZSByZXF1ZXN0IG9iamVjdCBoYXMgdGhlIGZvbGxvd2luZyBBUEksIChmdWxseSBkZXNjcmliZWQKICogaW4gdGhlIG1ldGhvZCBjb2RlKToKICogICAgewogKiAgICAgICBwYXRoOiA8dGhlIHBhdGggc3RyaW5nIHBhcnQ+LgogKiAgICAgICBxdWVyeTogPHRoZSBxdWVyeSBzdHJpbmcgcGFydD4sCiAqICAgICAgIGdldFBhdGgoaSk6IGdldCBwYXJ0IG9yIGFsbCBvZiB0aGUgc3BsaXQgcGF0aCBhcnJheSwKICogICAgICAgZ2V0UXVlcnkoaywgaSk6IGdldCBwYXJ0IG9yIGFsbCBvZiBhIHF1ZXJ5IGtleSBhcnJheSwKICogICAgICAgZ2V0UXVlcnlMYXN0KGssIF9kZWZhdWx0KTogZ2V0IGxhc3QgZWxlbWVudCBvZiBhIHF1ZXJ5IGtleSBhcnJheS4KICogICAgfQogKgogKiBAcmV0dXJuIG9iamVjdCB3aXRoIHJlcXVlc3QgcGFyYW1ldGVycy4KICovCnV0aWwubWFrZVJlcXVlc3QgPSBmdW5jdGlvbihyZXFTdHJpbmcpIHsKICB2YXIgZnJhZyA9IHV0aWwucGFyc2VGcmFnbWVudChyZXFTdHJpbmcpOwogIHZhciByZXEgPSB7CiAgICAvLyBmdWxsIHBhdGggc3RyaW5nCiAgICBwYXRoOiBmcmFnLnBhdGhTdHJpbmcsCiAgICAvLyBmdWxsIHF1ZXJ5IHN0cmluZwogICAgcXVlcnk6IGZyYWcucXVlcnlTdHJpbmcsCiAgICAvKioKICAgICAqIEdldCBwYXRoIG9yIGVsZW1lbnQgaW4gcGF0aC4KICAgICAqCiAgICAgKiBAcGFyYW0gaSBvcHRpb25hbCBwYXRoIGluZGV4LgogICAgICoKICAgICAqIEByZXR1cm4gcGF0aCBvciBwYXJ0IG9mIHBhdGggaWYgaSBwcm92aWRlZC4KICAgICAqLwogICAgZ2V0UGF0aDogZnVuY3Rpb24oaSkgewogICAgICByZXR1cm4gKHR5cGVvZihpKSA9PT0gJ3VuZGVmaW5lZCcpID8gZnJhZy5wYXRoIDogZnJhZy5wYXRoW2ldOwogICAgfSwKICAgIC8qKgogICAgICogR2V0IHF1ZXJ5LCB2YWx1ZXMgZm9yIGEga2V5LCBvciB2YWx1ZSBmb3IgYSBrZXkgaW5kZXguCiAgICAgKgogICAgICogQHBhcmFtIGsgb3B0aW9uYWwgcXVlcnkga2V5LgogICAgICogQHBhcmFtIGkgb3B0aW9uYWwgcXVlcnkga2V5IGluZGV4LgogICAgICoKICAgICAqIEByZXR1cm4gcXVlcnksIHZhbHVlcyBmb3IgYSBrZXksIG9yIHZhbHVlIGZvciBhIGtleSBpbmRleC4KICAgICAqLwogICAgZ2V0UXVlcnk6IGZ1bmN0aW9uKGssIGkpIHsKICAgICAgdmFyIHJ2YWw7CiAgICAgIGlmKHR5cGVvZihrKSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICBydmFsID0gZnJhZy5xdWVyeTsKICAgICAgfSBlbHNlIHsKICAgICAgICBydmFsID0gZnJhZy5xdWVyeVtrXTsKICAgICAgICBpZihydmFsICYmIHR5cGVvZihpKSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgICAgICBydmFsID0gcnZhbFtpXTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIHJ2YWw7CiAgICB9LAogICAgZ2V0UXVlcnlMYXN0OiBmdW5jdGlvbihrLCBfZGVmYXVsdCkgewogICAgICB2YXIgcnZhbDsKICAgICAgdmFyIHZhbHMgPSByZXEuZ2V0UXVlcnkoayk7CiAgICAgIGlmKHZhbHMpIHsKICAgICAgICBydmFsID0gdmFsc1t2YWxzLmxlbmd0aCAtIDFdOwogICAgICB9IGVsc2UgewogICAgICAgIHJ2YWwgPSBfZGVmYXVsdDsKICAgICAgfQogICAgICByZXR1cm4gcnZhbDsKICAgIH0KICB9OwogIHJldHVybiByZXE7Cn07CgovKioKICogTWFrZXMgYSBVUkkgb3V0IG9mIGEgcGF0aCwgYW4gb2JqZWN0IHdpdGggcXVlcnkgcGFyYW1ldGVycywgYW5kIGEKICogZnJhZ21lbnQuIFVzZXMgalF1ZXJ5LnBhcmFtKCkgaW50ZXJuYWxseSBmb3IgcXVlcnkgc3RyaW5nIGNyZWF0aW9uLgogKiBJZiB0aGUgcGF0aCBpcyBhbiBhcnJheSwgaXQgd2lsbCBiZSBqb2luZWQgd2l0aCAnLycuCiAqCiAqIEBwYXJhbSBwYXRoIHN0cmluZyBwYXRoIG9yIGFycmF5IG9mIHN0cmluZ3MuCiAqIEBwYXJhbSBxdWVyeSBvYmplY3Qgd2l0aCBxdWVyeSBwYXJhbWV0ZXJzLiAob3B0aW9uYWwpCiAqIEBwYXJhbSBmcmFnbWVudCBmcmFnbWVudCBzdHJpbmcuIChvcHRpb25hbCkKICoKICogQHJldHVybiBzdHJpbmcgb2JqZWN0IHdpdGggcmVxdWVzdCBwYXJhbWV0ZXJzLgogKi8KdXRpbC5tYWtlTGluayA9IGZ1bmN0aW9uKHBhdGgsIHF1ZXJ5LCBmcmFnbWVudCkgewogIC8vIGpvaW4gcGF0aCBwYXJ0cyBpZiBuZWVkZWQKICBwYXRoID0galF1ZXJ5LmlzQXJyYXkocGF0aCkgPyBwYXRoLmpvaW4oJy8nKSA6IHBhdGg7CgogIHZhciBxc3RyID0galF1ZXJ5LnBhcmFtKHF1ZXJ5IHx8IHt9KTsKICBmcmFnbWVudCA9IGZyYWdtZW50IHx8ICcnOwogIHJldHVybiBwYXRoICsKICAgICgocXN0ci5sZW5ndGggPiAwKSA/ICgnPycgKyBxc3RyKSA6ICcnKSArCiAgICAoKGZyYWdtZW50Lmxlbmd0aCA+IDApID8gKCcjJyArIGZyYWdtZW50KSA6ICcnKTsKfTsKCi8qKgogKiBGb2xsb3dzIGEgcGF0aCBvZiBrZXlzIGRlZXAgaW50byBhbiBvYmplY3QgaGllcmFyY2h5IGFuZCBzZXQgYSB2YWx1ZS4KICogSWYgYSBrZXkgZG9lcyBub3QgZXhpc3Qgb3IgaXQncyB2YWx1ZSBpcyBub3QgYW4gb2JqZWN0LCBjcmVhdGUgYW4KICogb2JqZWN0IGluIGl0J3MgcGxhY2UuIFRoaXMgY2FuIGJlIGRlc3RydWN0aXZlIHRvIGEgb2JqZWN0IHRyZWUgaWYKICogbGVhZiBub2RlcyBhcmUgZ2l2ZW4gYXMgbm9uLWZpbmFsIHBhdGgga2V5cy4KICogVXNlZCB0byBhdm9pZCBleGNlcHRpb25zIGZyb20gbWlzc2luZyBwYXJ0cyBvZiB0aGUgcGF0aC4KICoKICogQHBhcmFtIG9iamVjdCB0aGUgc3RhcnRpbmcgb2JqZWN0LgogKiBAcGFyYW0ga2V5cyBhbiBhcnJheSBvZiBzdHJpbmcga2V5cy4KICogQHBhcmFtIHZhbHVlIHRoZSB2YWx1ZSB0byBzZXQuCiAqLwp1dGlsLnNldFBhdGggPSBmdW5jdGlvbihvYmplY3QsIGtleXMsIHZhbHVlKSB7CiAgLy8gbmVlZCB0byBzdGFydCBhdCBhbiBvYmplY3QKICBpZih0eXBlb2Yob2JqZWN0KSA9PT0gJ29iamVjdCcgJiYgb2JqZWN0ICE9PSBudWxsKSB7CiAgICB2YXIgaSA9IDA7CiAgICB2YXIgbGVuID0ga2V5cy5sZW5ndGg7CiAgICB3aGlsZShpIDwgbGVuKSB7CiAgICAgIHZhciBuZXh0ID0ga2V5c1tpKytdOwogICAgICBpZihpID09IGxlbikgewogICAgICAgIC8vIGxhc3QKICAgICAgICBvYmplY3RbbmV4dF0gPSB2YWx1ZTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBtb3JlCiAgICAgICAgdmFyIGhhc05leHQgPSAobmV4dCBpbiBvYmplY3QpOwogICAgICAgIGlmKCFoYXNOZXh0IHx8CiAgICAgICAgICAoaGFzTmV4dCAmJiB0eXBlb2Yob2JqZWN0W25leHRdKSAhPT0gJ29iamVjdCcpIHx8CiAgICAgICAgICAoaGFzTmV4dCAmJiBvYmplY3RbbmV4dF0gPT09IG51bGwpKSB7CiAgICAgICAgICBvYmplY3RbbmV4dF0gPSB7fTsKICAgICAgICB9CiAgICAgICAgb2JqZWN0ID0gb2JqZWN0W25leHRdOwogICAgICB9CiAgICB9CiAgfQp9OwoKLyoqCiAqIEZvbGxvd3MgYSBwYXRoIG9mIGtleXMgZGVlcCBpbnRvIGFuIG9iamVjdCBoaWVyYXJjaHkgYW5kIHJldHVybiBhIHZhbHVlLgogKiBJZiBhIGtleSBkb2VzIG5vdCBleGlzdCwgY3JlYXRlIGFuIG9iamVjdCBpbiBpdCdzIHBsYWNlLgogKiBVc2VkIHRvIGF2b2lkIGV4Y2VwdGlvbnMgZnJvbSBtaXNzaW5nIHBhcnRzIG9mIHRoZSBwYXRoLgogKgogKiBAcGFyYW0gb2JqZWN0IHRoZSBzdGFydGluZyBvYmplY3QuCiAqIEBwYXJhbSBrZXlzIGFuIGFycmF5IG9mIHN0cmluZyBrZXlzLgogKiBAcGFyYW0gX2RlZmF1bHQgdmFsdWUgdG8gcmV0dXJuIGlmIHBhdGggbm90IGZvdW5kLgogKgogKiBAcmV0dXJuIHRoZSB2YWx1ZSBhdCB0aGUgcGF0aCBpZiBmb3VuZCwgZWxzZSBkZWZhdWx0IGlmIGdpdmVuLCBlbHNlCiAqICAgICAgICAgdW5kZWZpbmVkLgogKi8KdXRpbC5nZXRQYXRoID0gZnVuY3Rpb24ob2JqZWN0LCBrZXlzLCBfZGVmYXVsdCkgewogIHZhciBpID0gMDsKICB2YXIgbGVuID0ga2V5cy5sZW5ndGg7CiAgdmFyIGhhc05leHQgPSB0cnVlOwogIHdoaWxlKGhhc05leHQgJiYgaSA8IGxlbiAmJgogICAgdHlwZW9mKG9iamVjdCkgPT09ICdvYmplY3QnICYmIG9iamVjdCAhPT0gbnVsbCkgewogICAgdmFyIG5leHQgPSBrZXlzW2krK107CiAgICBoYXNOZXh0ID0gbmV4dCBpbiBvYmplY3Q7CiAgICBpZihoYXNOZXh0KSB7CiAgICAgIG9iamVjdCA9IG9iamVjdFtuZXh0XTsKICAgIH0KICB9CiAgcmV0dXJuIChoYXNOZXh0ID8gb2JqZWN0IDogX2RlZmF1bHQpOwp9OwoKLyoqCiAqIEZvbGxvdyBhIHBhdGggb2Yga2V5cyBkZWVwIGludG8gYW4gb2JqZWN0IGhpZXJhcmNoeSBhbmQgZGVsZXRlIHRoZQogKiBsYXN0IG9uZS4gSWYgYSBrZXkgZG9lcyBub3QgZXhpc3QsIGRvIG5vdGhpbmcuCiAqIFVzZWQgdG8gYXZvaWQgZXhjZXB0aW9ucyBmcm9tIG1pc3NpbmcgcGFydHMgb2YgdGhlIHBhdGguCiAqCiAqIEBwYXJhbSBvYmplY3QgdGhlIHN0YXJ0aW5nIG9iamVjdC4KICogQHBhcmFtIGtleXMgYW4gYXJyYXkgb2Ygc3RyaW5nIGtleXMuCiAqLwp1dGlsLmRlbGV0ZVBhdGggPSBmdW5jdGlvbihvYmplY3QsIGtleXMpIHsKICAvLyBuZWVkIHRvIHN0YXJ0IGF0IGFuIG9iamVjdAogIGlmKHR5cGVvZihvYmplY3QpID09PSAnb2JqZWN0JyAmJiBvYmplY3QgIT09IG51bGwpIHsKICAgIHZhciBpID0gMDsKICAgIHZhciBsZW4gPSBrZXlzLmxlbmd0aDsKICAgIHdoaWxlKGkgPCBsZW4pIHsKICAgICAgdmFyIG5leHQgPSBrZXlzW2krK107CiAgICAgIGlmKGkgPT0gbGVuKSB7CiAgICAgICAgLy8gbGFzdAogICAgICAgIGRlbGV0ZSBvYmplY3RbbmV4dF07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gbW9yZQogICAgICAgIGlmKCEobmV4dCBpbiBvYmplY3QpIHx8CiAgICAgICAgICAodHlwZW9mKG9iamVjdFtuZXh0XSkgIT09ICdvYmplY3QnKSB8fAogICAgICAgICAgKG9iamVjdFtuZXh0XSA9PT0gbnVsbCkpIHsKICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgb2JqZWN0ID0gb2JqZWN0W25leHRdOwogICAgICB9CiAgICB9CiAgfQp9OwoKLyoqCiAqIENoZWNrIGlmIGFuIG9iamVjdCBpcyBlbXB0eS4KICoKICogVGFrZW4gZnJvbToKICogaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy82Nzk5MTUvaG93LWRvLWktdGVzdC1mb3ItYW4tZW1wdHktamF2YXNjcmlwdC1vYmplY3QtZnJvbS1qc29uLzY3OTkzNyM2Nzk5MzcKICoKICogQHBhcmFtIG9iamVjdCB0aGUgb2JqZWN0IHRvIGNoZWNrLgogKi8KdXRpbC5pc0VtcHR5ID0gZnVuY3Rpb24ob2JqKSB7CiAgZm9yKHZhciBwcm9wIGluIG9iaikgewogICAgaWYob2JqLmhhc093blByb3BlcnR5KHByb3ApKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CiAgcmV0dXJuIHRydWU7Cn07CgovKioKICogRm9ybWF0IHdpdGggc2ltcGxlIHByaW50Zi1zdHlsZSBpbnRlcnBvbGF0aW9uLgogKgogKiAlJTogbGl0ZXJhbCAnJScKICogJXMsJW86IGNvbnZlcnQgbmV4dCBhcmd1bWVudCBpbnRvIGEgc3RyaW5nLgogKgogKiBAcGFyYW0gZm9ybWF0IHRoZSBzdHJpbmcgdG8gZm9ybWF0LgogKiBAcGFyYW0gLi4uIGFyZ3VtZW50cyB0byBpbnRlcnBvbGF0ZSBpbnRvIHRoZSBmb3JtYXQgc3RyaW5nLgogKi8KdXRpbC5mb3JtYXQgPSBmdW5jdGlvbihmb3JtYXQpIHsKICB2YXIgcmUgPSAvJS4vZzsKICAvLyBjdXJyZW50IG1hdGNoCiAgdmFyIG1hdGNoOwogIC8vIGN1cnJlbnQgcGFydAogIHZhciBwYXJ0OwogIC8vIGN1cnJlbnQgYXJnIGluZGV4CiAgdmFyIGFyZ2kgPSAwOwogIC8vIGNvbGxlY3RlZCBwYXJ0cyB0byByZWNvbWJpbmUgbGF0ZXIKICB2YXIgcGFydHMgPSBbXTsKICAvLyBsYXN0IGluZGV4IGZvdW5kCiAgdmFyIGxhc3QgPSAwOwogIC8vIGxvb3Agd2hpbGUgbWF0Y2hlcyByZW1haW4KICB3aGlsZSgobWF0Y2ggPSByZS5leGVjKGZvcm1hdCkpKSB7CiAgICBwYXJ0ID0gZm9ybWF0LnN1YnN0cmluZyhsYXN0LCByZS5sYXN0SW5kZXggLSAyKTsKICAgIC8vIGRvbid0IGFkZCBlbXB0eSBzdHJpbmdzIChpZSwgcGFydHMgYmV0d2VlbiAlcyVzKQogICAgaWYocGFydC5sZW5ndGggPiAwKSB7CiAgICAgIHBhcnRzLnB1c2gocGFydCk7CiAgICB9CiAgICBsYXN0ID0gcmUubGFzdEluZGV4OwogICAgLy8gc3dpdGNoIG9uICUgY29kZQogICAgdmFyIGNvZGUgPSBtYXRjaFswXVsxXTsKICAgIHN3aXRjaChjb2RlKSB7CiAgICBjYXNlICdzJzoKICAgIGNhc2UgJ28nOgogICAgICAvLyBjaGVjayBpZiBlbm91Z2ggYXJndW1lbnRzIHdlcmUgZ2l2ZW4KICAgICAgaWYoYXJnaSA8IGFyZ3VtZW50cy5sZW5ndGgpIHsKICAgICAgICBwYXJ0cy5wdXNoKGFyZ3VtZW50c1thcmdpKysgKyAxXSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcGFydHMucHVzaCgnPD8+Jyk7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICAvLyBGSVhNRTogZG8gcHJvcGVyIGZvcm1hdGluZyBmb3IgbnVtYmVycywgZXRjCiAgICAvL2Nhc2UgJ2YnOgogICAgLy9jYXNlICdkJzoKICAgIGNhc2UgJyUnOgogICAgICBwYXJ0cy5wdXNoKCclJyk7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgLy9wYXJ0cy5wdXNoKCc8JyArICclJyArIGNvZGUgKyAnPz4nKTsKICAgICAgcGFydHMucHVzaCgnPFx1MDAyMycgKyBjb2RlICsgJz8+Jyk7IC8vIE5lZWQgdG8gZXNjYXBlIHRoaXMgbGluZSBmb3IgQVNQLm5ldAogICAgfQogIH0KICAvLyBhZGQgdHJhaWxpbmcgcGFydCBvZiBmb3JtYXQgc3RyaW5nCiAgcGFydHMucHVzaChmb3JtYXQuc3Vic3RyaW5nKGxhc3QpKTsKICByZXR1cm4gcGFydHMuam9pbignJyk7Cn07CgovKioKICogRm9ybWF0cyBhIG51bWJlci4KICoKICogaHR0cDovL3NuaXBwbHIuY29tL3ZpZXcvNTk0NS9qYXZhc2NyaXB0LW51bWJlcmZvcm1hdC0tcG9ydGVkLWZyb20tcGhwLwogKi8KdXRpbC5mb3JtYXROdW1iZXIgPSBmdW5jdGlvbihudW1iZXIsIGRlY2ltYWxzLCBkZWNfcG9pbnQsIHRob3VzYW5kc19zZXApIHsKICAvLyBodHRwOi8va2V2aW4udmFuem9ubmV2ZWxkLm5ldAogIC8vICsgICBvcmlnaW5hbCBieTogSm9uYXMgUmFvbmkgU29hcmVzIFNpbHZhIChodHRwOi8vd3d3LmpzZnJvbWhlbGwuY29tKQogIC8vICsgICBpbXByb3ZlZCBieTogS2V2aW4gdmFuIFpvbm5ldmVsZCAoaHR0cDovL2tldmluLnZhbnpvbm5ldmVsZC5uZXQpCiAgLy8gKyAgICAgYnVnZml4IGJ5OiBNaWNoYWVsIFdoaXRlIChodHRwOi8vY3Jlc3RpZGcuY29tKQogIC8vICsgICAgIGJ1Z2ZpeCBieTogQmVuamFtaW4gTHVwdG9uCiAgLy8gKyAgICAgYnVnZml4IGJ5OiBBbGxhbiBKZW5zZW4gKGh0dHA6Ly93d3cud2ludGVybmV0Lm5vKQogIC8vICsgICAgcmV2aXNlZCBieTogSm9uYXMgUmFvbmkgU29hcmVzIFNpbHZhIChodHRwOi8vd3d3LmpzZnJvbWhlbGwuY29tKQogIC8vICogICAgIGV4YW1wbGUgMTogbnVtYmVyX2Zvcm1hdCgxMjM0LjU2NzgsIDIsICcuJywgJycpOwogIC8vICogICAgIHJldHVybnMgMTogMTIzNC41NwoKICB2YXIgbiA9IG51bWJlciwgYyA9IGlzTmFOKGRlY2ltYWxzID0gTWF0aC5hYnMoZGVjaW1hbHMpKSA/IDIgOiBkZWNpbWFsczsKICB2YXIgZCA9IGRlY19wb2ludCA9PT0gdW5kZWZpbmVkID8gJywnIDogZGVjX3BvaW50OwogIHZhciB0ID0gdGhvdXNhbmRzX3NlcCA9PT0gdW5kZWZpbmVkID8KICAgJy4nIDogdGhvdXNhbmRzX3NlcCwgcyA9IG4gPCAwID8gJy0nIDogJyc7CiAgdmFyIGkgPSBwYXJzZUludCgobiA9IE1hdGguYWJzKCtuIHx8IDApLnRvRml4ZWQoYykpLCAxMCkgKyAnJzsKICB2YXIgaiA9IChpLmxlbmd0aCA+IDMpID8gaS5sZW5ndGggJSAzIDogMDsKICByZXR1cm4gcyArIChqID8gaS5zdWJzdHIoMCwgaikgKyB0IDogJycpICsKICAgIGkuc3Vic3RyKGopLnJlcGxhY2UoLyhcZHszfSkoPz1cZCkvZywgJyQxJyArIHQpICsKICAgIChjID8gZCArIE1hdGguYWJzKG4gLSBpKS50b0ZpeGVkKGMpLnNsaWNlKDIpIDogJycpOwp9OwoKLyoqCiAqIEZvcm1hdHMgYSBieXRlIHNpemUuCiAqCiAqIGh0dHA6Ly9zbmlwcGxyLmNvbS92aWV3LzU5NDkvZm9ybWF0LWh1bWFuaXplLWZpbGUtYnl0ZS1zaXplLXByZXNlbnRhdGlvbi1pbi1qYXZhc2NyaXB0LwogKi8KdXRpbC5mb3JtYXRTaXplID0gZnVuY3Rpb24oc2l6ZSkgewogIGlmKHNpemUgPj0gMTA3Mzc0MTgyNCkgewogICAgc2l6ZSA9IHV0aWwuZm9ybWF0TnVtYmVyKHNpemUgLyAxMDczNzQxODI0LCAyLCAnLicsICcnKSArICcgR2lCJzsKICB9IGVsc2UgaWYoc2l6ZSA+PSAxMDQ4NTc2KSB7CiAgICBzaXplID0gdXRpbC5mb3JtYXROdW1iZXIoc2l6ZSAvIDEwNDg1NzYsIDIsICcuJywgJycpICsgJyBNaUInOwogIH0gZWxzZSBpZihzaXplID49IDEwMjQpIHsKICAgIHNpemUgPSB1dGlsLmZvcm1hdE51bWJlcihzaXplIC8gMTAyNCwgMCkgKyAnIEtpQic7CiAgfSBlbHNlIHsKICAgIHNpemUgPSB1dGlsLmZvcm1hdE51bWJlcihzaXplLCAwKSArICcgYnl0ZXMnOwogIH0KICByZXR1cm4gc2l6ZTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhbiBJUHY0IG9yIElQdjYgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGludG8gYnl0ZXMgKGluIG5ldHdvcmsgb3JkZXIpLgogKgogKiBAcGFyYW0gaXAgdGhlIElQdjQgb3IgSVB2NiBhZGRyZXNzIHRvIGNvbnZlcnQuCiAqCiAqIEByZXR1cm4gdGhlIDQtYnl0ZSBJUHY2IG9yIDE2LWJ5dGUgSVB2NiBhZGRyZXNzIG9yIG51bGwgaWYgdGhlIGFkZHJlc3MgY2FuJ3QKICogICAgICAgICBiZSBwYXJzZWQuCiAqLwp1dGlsLmJ5dGVzRnJvbUlQID0gZnVuY3Rpb24oaXApIHsKICBpZihpcC5pbmRleE9mKCcuJykgIT09IC0xKSB7CiAgICByZXR1cm4gdXRpbC5ieXRlc0Zyb21JUHY0KGlwKTsKICB9CiAgaWYoaXAuaW5kZXhPZignOicpICE9PSAtMSkgewogICAgcmV0dXJuIHV0aWwuYnl0ZXNGcm9tSVB2NihpcCk7CiAgfQogIHJldHVybiBudWxsOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIElQdjQgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGludG8gYnl0ZXMgKGluIG5ldHdvcmsgb3JkZXIpLgogKgogKiBAcGFyYW0gaXAgdGhlIElQdjQgYWRkcmVzcyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSA0LWJ5dGUgYWRkcmVzcyBvciBudWxsIGlmIHRoZSBhZGRyZXNzIGNhbid0IGJlIHBhcnNlZC4KICovCnV0aWwuYnl0ZXNGcm9tSVB2NCA9IGZ1bmN0aW9uKGlwKSB7CiAgaXAgPSBpcC5zcGxpdCgnLicpOwogIGlmKGlwLmxlbmd0aCAhPT0gNCkgewogICAgcmV0dXJuIG51bGw7CiAgfQogIHZhciBiID0gdXRpbC5jcmVhdGVCdWZmZXIoKTsKICBmb3IodmFyIGkgPSAwOyBpIDwgaXAubGVuZ3RoOyArK2kpIHsKICAgIHZhciBudW0gPSBwYXJzZUludChpcFtpXSwgMTApOwogICAgaWYoaXNOYU4obnVtKSkgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIGIucHV0Qnl0ZShudW0pOwogIH0KICByZXR1cm4gYi5nZXRCeXRlcygpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIElQdjYgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGludG8gYnl0ZXMgKGluIG5ldHdvcmsgb3JkZXIpLgogKgogKiBAcGFyYW0gaXAgdGhlIElQdjYgYWRkcmVzcyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSAxNi1ieXRlIGFkZHJlc3Mgb3IgbnVsbCBpZiB0aGUgYWRkcmVzcyBjYW4ndCBiZSBwYXJzZWQuCiAqLwp1dGlsLmJ5dGVzRnJvbUlQdjYgPSBmdW5jdGlvbihpcCkgewogIHZhciBibGFua3MgPSAwOwogIGlwID0gaXAuc3BsaXQoJzonKS5maWx0ZXIoZnVuY3Rpb24oZSkgewogICAgaWYoZS5sZW5ndGggPT09IDApICsrYmxhbmtzOwogICAgcmV0dXJuIHRydWU7CiAgfSk7CiAgdmFyIHplcm9zID0gKDggLSBpcC5sZW5ndGggKyBibGFua3MpICogMjsKICB2YXIgYiA9IHV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgZm9yKHZhciBpID0gMDsgaSA8IDg7ICsraSkgewogICAgaWYoIWlwW2ldIHx8IGlwW2ldLmxlbmd0aCA9PT0gMCkgewogICAgICBiLmZpbGxXaXRoQnl0ZSgwLCB6ZXJvcyk7CiAgICAgIHplcm9zID0gMDsKICAgICAgY29udGludWU7CiAgICB9CiAgICB2YXIgYnl0ZXMgPSB1dGlsLmhleFRvQnl0ZXMoaXBbaV0pOwogICAgaWYoYnl0ZXMubGVuZ3RoIDwgMikgewogICAgICBiLnB1dEJ5dGUoMCk7CiAgICB9CiAgICBiLnB1dEJ5dGVzKGJ5dGVzKTsKICB9CiAgcmV0dXJuIGIuZ2V0Qnl0ZXMoKTsKfTsKCi8qKgogKiBDb252ZXJ0cyA0LWJ5dGVzIGludG8gYW4gSVB2NCBzdHJpbmcgcmVwcmVzZW50YXRpb24gb3IgMTYtYnl0ZXMgaW50bwogKiBhbiBJUHY2IHN0cmluZyByZXByZXNlbnRhdGlvbi4gVGhlIGJ5dGVzIG11c3QgYmUgaW4gbmV0d29yayBvcmRlci4KICoKICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBJUHY0IG9yIElQdjYgc3RyaW5nIHJlcHJlc2VudGF0aW9uIGlmIDQgb3IgMTYgYnl0ZXMsCiAqICAgICAgICAgcmVzcGVjdGl2ZWx5LCBhcmUgZ2l2ZW4sIG90aGVyd2lzZSBudWxsLgogKi8KdXRpbC5ieXRlc1RvSVAgPSBmdW5jdGlvbihieXRlcykgewogIGlmKGJ5dGVzLmxlbmd0aCA9PT0gNCkgewogICAgcmV0dXJuIHV0aWwuYnl0ZXNUb0lQdjQoYnl0ZXMpOwogIH0KICBpZihieXRlcy5sZW5ndGggPT09IDE2KSB7CiAgICByZXR1cm4gdXRpbC5ieXRlc1RvSVB2NihieXRlcyk7CiAgfQogIHJldHVybiBudWxsOwp9OwoKLyoqCiAqIENvbnZlcnRzIDQtYnl0ZXMgaW50byBhbiBJUHY0IHN0cmluZyByZXByZXNlbnRhdGlvbi4gVGhlIGJ5dGVzIG11c3QgYmUKICogaW4gbmV0d29yayBvcmRlci4KICoKICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBJUHY0IHN0cmluZyByZXByZXNlbnRhdGlvbiBvciBudWxsIGZvciBhbiBpbnZhbGlkICMgb2YgYnl0ZXMuCiAqLwp1dGlsLmJ5dGVzVG9JUHY0ID0gZnVuY3Rpb24oYnl0ZXMpIHsKICBpZihieXRlcy5sZW5ndGggIT09IDQpIHsKICAgIHJldHVybiBudWxsOwogIH0KICB2YXIgaXAgPSBbXTsKICBmb3IodmFyIGkgPSAwOyBpIDwgYnl0ZXMubGVuZ3RoOyArK2kpIHsKICAgIGlwLnB1c2goYnl0ZXMuY2hhckNvZGVBdChpKSk7CiAgfQogIHJldHVybiBpcC5qb2luKCcuJyk7Cn07CgovKioKICogQ29udmVydHMgMTYtYnl0ZXMgaW50byBhbiBJUHYxNiBzdHJpbmcgcmVwcmVzZW50YXRpb24uIFRoZSBieXRlcyBtdXN0IGJlCiAqIGluIG5ldHdvcmsgb3JkZXIuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZXMgdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgSVB2MTYgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9yIG51bGwgZm9yIGFuIGludmFsaWQgIyBvZiBieXRlcy4KICovCnV0aWwuYnl0ZXNUb0lQdjYgPSBmdW5jdGlvbihieXRlcykgewogIGlmKGJ5dGVzLmxlbmd0aCAhPT0gMTYpIHsKICAgIHJldHVybiBudWxsOwogIH0KICB2YXIgaXAgPSBbXTsKICB2YXIgemVyb0dyb3VwcyA9IFtdOwogIHZhciB6ZXJvTWF4R3JvdXAgPSAwOwogIGZvcih2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikgewogICAgdmFyIGhleCA9IHV0aWwuYnl0ZXNUb0hleChieXRlc1tpXSArIGJ5dGVzW2kgKyAxXSk7CiAgICAvLyBjYW5vbmljYWxpemUgemVybyByZXByZXNlbnRhdGlvbgogICAgd2hpbGUoaGV4WzBdID09PSAnMCcgJiYgaGV4ICE9PSAnMCcpIHsKICAgICAgaGV4ID0gaGV4LnN1YnN0cigxKTsKICAgIH0KICAgIGlmKGhleCA9PT0gJzAnKSB7CiAgICAgIHZhciBsYXN0ID0gemVyb0dyb3Vwc1t6ZXJvR3JvdXBzLmxlbmd0aCAtIDFdOwogICAgICB2YXIgaWR4ID0gaXAubGVuZ3RoOwogICAgICBpZighbGFzdCB8fCBpZHggIT09IGxhc3QuZW5kICsgMSkgewogICAgICAgIHplcm9Hcm91cHMucHVzaCh7c3RhcnQ6IGlkeCwgZW5kOiBpZHh9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBsYXN0LmVuZCA9IGlkeDsKICAgICAgICBpZigobGFzdC5lbmQgLSBsYXN0LnN0YXJ0KSA+CiAgICAgICAgICAoemVyb0dyb3Vwc1t6ZXJvTWF4R3JvdXBdLmVuZCAtIHplcm9Hcm91cHNbemVyb01heEdyb3VwXS5zdGFydCkpIHsKICAgICAgICAgIHplcm9NYXhHcm91cCA9IHplcm9Hcm91cHMubGVuZ3RoIC0gMTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGlwLnB1c2goaGV4KTsKICB9CiAgaWYoemVyb0dyb3Vwcy5sZW5ndGggPiAwKSB7CiAgICB2YXIgZ3JvdXAgPSB6ZXJvR3JvdXBzW3plcm9NYXhHcm91cF07CiAgICAvLyBvbmx5IHNob3J0ZW4gZ3JvdXAgb2YgbGVuZ3RoID4gMAogICAgaWYoZ3JvdXAuZW5kIC0gZ3JvdXAuc3RhcnQgPiAwKSB7CiAgICAgIGlwLnNwbGljZShncm91cC5zdGFydCwgZ3JvdXAuZW5kIC0gZ3JvdXAuc3RhcnQgKyAxLCAnJyk7CiAgICAgIGlmKGdyb3VwLnN0YXJ0ID09PSAwKSB7CiAgICAgICAgaXAudW5zaGlmdCgnJyk7CiAgICAgIH0KICAgICAgaWYoZ3JvdXAuZW5kID09PSA3KSB7CiAgICAgICAgaXAucHVzaCgnJyk7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIGlwLmpvaW4oJzonKTsKfTsKCi8qKgogKiBFc3RpbWF0ZXMgdGhlIG51bWJlciBvZiBwcm9jZXNzZXMgdGhhdCBjYW4gYmUgcnVuIGNvbmN1cnJlbnRseS4gSWYKICogY3JlYXRpbmcgV2ViIFdvcmtlcnMsIGtlZXAgaW4gbWluZCB0aGF0IHRoZSBtYWluIEphdmFTY3JpcHQgcHJvY2VzcyBuZWVkcwogKiBpdHMgb3duIGNvcmUuCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgdXBkYXRlIHRydWUgdG8gZm9yY2UgYW4gdXBkYXRlIChub3QgdXNlIHRoZSBjYWNoZWQgdmFsdWUpLgogKiBAcGFyYW0gY2FsbGJhY2soZXJyLCBtYXgpIGNhbGxlZCBvbmNlIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLgogKi8KdXRpbC5lc3RpbWF0ZUNvcmVzID0gZnVuY3Rpb24ob3B0aW9ucywgY2FsbGJhY2spIHsKICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykgewogICAgY2FsbGJhY2sgPSBvcHRpb25zOwogICAgb3B0aW9ucyA9IHt9OwogIH0KICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICBpZignY29yZXMnIGluIHV0aWwgJiYgIW9wdGlvbnMudXBkYXRlKSB7CiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgdXRpbC5jb3Jlcyk7CiAgfQogIGlmKHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmCiAgICAnaGFyZHdhcmVDb25jdXJyZW5jeScgaW4gbmF2aWdhdG9yICYmCiAgICBuYXZpZ2F0b3IuaGFyZHdhcmVDb25jdXJyZW5jeSA+IDApIHsKICAgIHV0aWwuY29yZXMgPSBuYXZpZ2F0b3IuaGFyZHdhcmVDb25jdXJyZW5jeTsKICAgIHJldHVybiBjYWxsYmFjayhudWxsLCB1dGlsLmNvcmVzKTsKICB9CiAgaWYodHlwZW9mIFdvcmtlciA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIC8vIHdvcmtlcnMgbm90IGF2YWlsYWJsZQogICAgdXRpbC5jb3JlcyA9IDE7CiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgdXRpbC5jb3Jlcyk7CiAgfQogIGlmKHR5cGVvZiBCbG9iID09PSAndW5kZWZpbmVkJykgewogICAgLy8gY2FuJ3QgZXN0aW1hdGUsIGRlZmF1bHQgdG8gMgogICAgdXRpbC5jb3JlcyA9IDI7CiAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgdXRpbC5jb3Jlcyk7CiAgfQoKICAvLyBjcmVhdGUgd29ya2VyIGNvbmN1cnJlbmN5IGVzdGltYXRpb24gY29kZSBhcyBibG9iCiAgdmFyIGJsb2JVcmwgPSBVUkwuY3JlYXRlT2JqZWN0VVJMKG5ldyBCbG9iKFsnKCcsCiAgICBmdW5jdGlvbigpIHsKICAgICAgc2VsZi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24oZSkgewogICAgICAgIC8vIHJ1biB3b3JrZXIgZm9yIDQgbXMKICAgICAgICB2YXIgc3QgPSBEYXRlLm5vdygpOwogICAgICAgIHZhciBldCA9IHN0ICsgNDsKICAgICAgICB3aGlsZShEYXRlLm5vdygpIDwgZXQpOwogICAgICAgIHNlbGYucG9zdE1lc3NhZ2Uoe3N0OiBzdCwgZXQ6IGV0fSk7CiAgICAgIH0pOwogICAgfS50b1N0cmluZygpLAogICcpKCknXSwge3R5cGU6ICdhcHBsaWNhdGlvbi9qYXZhc2NyaXB0J30pKTsKCiAgLy8gdGFrZSA1IHNhbXBsZXMgdXNpbmcgMTYgd29ya2VycwogIHNhbXBsZShbXSwgNSwgMTYpOwoKICBmdW5jdGlvbiBzYW1wbGUobWF4LCBzYW1wbGVzLCBudW1Xb3JrZXJzKSB7CiAgICBpZihzYW1wbGVzID09PSAwKSB7CiAgICAgIC8vIGdldCBvdmVybGFwIGF2ZXJhZ2UKICAgICAgdmFyIGF2ZyA9IE1hdGguZmxvb3IobWF4LnJlZHVjZShmdW5jdGlvbihhdmcsIHgpIHsKICAgICAgICByZXR1cm4gYXZnICsgeDsKICAgICAgfSwgMCkgLyBtYXgubGVuZ3RoKTsKICAgICAgdXRpbC5jb3JlcyA9IE1hdGgubWF4KDEsIGF2Zyk7CiAgICAgIFVSTC5yZXZva2VPYmplY3RVUkwoYmxvYlVybCk7CiAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCB1dGlsLmNvcmVzKTsKICAgIH0KICAgIG1hcChudW1Xb3JrZXJzLCBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHsKICAgICAgbWF4LnB1c2gocmVkdWNlKG51bVdvcmtlcnMsIHJlc3VsdHMpKTsKICAgICAgc2FtcGxlKG1heCwgc2FtcGxlcyAtIDEsIG51bVdvcmtlcnMpOwogICAgfSk7CiAgfQoKICBmdW5jdGlvbiBtYXAobnVtV29ya2VycywgY2FsbGJhY2spIHsKICAgIHZhciB3b3JrZXJzID0gW107CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG51bVdvcmtlcnM7ICsraSkgewogICAgICB2YXIgd29ya2VyID0gbmV3IFdvcmtlcihibG9iVXJsKTsKICAgICAgd29ya2VyLmFkZEV2ZW50TGlzdGVuZXIoJ21lc3NhZ2UnLCBmdW5jdGlvbihlKSB7CiAgICAgICAgcmVzdWx0cy5wdXNoKGUuZGF0YSk7CiAgICAgICAgaWYocmVzdWx0cy5sZW5ndGggPT09IG51bVdvcmtlcnMpIHsKICAgICAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBudW1Xb3JrZXJzOyArK2kpIHsKICAgICAgICAgICAgd29ya2Vyc1tpXS50ZXJtaW5hdGUoKTsKICAgICAgICAgIH0KICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHJlc3VsdHMpOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIHdvcmtlcnMucHVzaCh3b3JrZXIpOwogICAgfQogICAgZm9yKHZhciBpID0gMDsgaSA8IG51bVdvcmtlcnM7ICsraSkgewogICAgICB3b3JrZXJzW2ldLnBvc3RNZXNzYWdlKGkpOwogICAgfQogIH0KCiAgZnVuY3Rpb24gcmVkdWNlKG51bVdvcmtlcnMsIHJlc3VsdHMpIHsKICAgIC8vIGZpbmQgb3ZlcmxhcHBpbmcgdGltZSB3aW5kb3dzCiAgICB2YXIgb3ZlcmxhcHMgPSBbXTsKICAgIGZvcih2YXIgbiA9IDA7IG4gPCBudW1Xb3JrZXJzOyArK24pIHsKICAgICAgdmFyIHIxID0gcmVzdWx0c1tuXTsKICAgICAgdmFyIG92ZXJsYXAgPSBvdmVybGFwc1tuXSA9IFtdOwogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgbnVtV29ya2VyczsgKytpKSB7CiAgICAgICAgaWYobiA9PT0gaSkgewogICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIHZhciByMiA9IHJlc3VsdHNbaV07CiAgICAgICAgaWYoKHIxLnN0ID4gcjIuc3QgJiYgcjEuc3QgPCByMi5ldCkgfHwKICAgICAgICAgIChyMi5zdCA+IHIxLnN0ICYmIHIyLnN0IDwgcjEuZXQpKSB7CiAgICAgICAgICBvdmVybGFwLnB1c2goaSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICAvLyBnZXQgbWF4aW11bSBvdmVybGFwcyAuLi4gZG9uJ3QgaW5jbHVkZSBvdmVybGFwcGluZyB3b3JrZXIgaXRzZWxmCiAgICAvLyBhcyB0aGUgbWFpbiBKUyBwcm9jZXNzIHdhcyBhbHNvIGJlaW5nIHNjaGVkdWxlZCBkdXJpbmcgdGhlIHdvcmsgYW5kCiAgICAvLyB3b3VsZCBoYXZlIHRvIGJlIHN1YnRyYWN0ZWQgZnJvbSB0aGUgZXN0aW1hdGUgYW55d2F5CiAgICByZXR1cm4gb3ZlcmxhcHMucmVkdWNlKGZ1bmN0aW9uKG1heCwgb3ZlcmxhcCkgewogICAgICByZXR1cm4gTWF0aC5tYXgobWF4LCBvdmVybGFwLmxlbmd0aCk7CiAgICB9LCAwKTsKICB9Cn07Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICd1dGlsJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3V0aWwnLFsncmVxdWlyZScsICdtb2R1bGUnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogQ2lwaGVyIGJhc2UgQVBJLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCmZvcmdlLmNpcGhlciA9IGZvcmdlLmNpcGhlciB8fCB7fTsKCi8vIHJlZ2lzdGVyZWQgYWxnb3JpdGhtcwpmb3JnZS5jaXBoZXIuYWxnb3JpdGhtcyA9IGZvcmdlLmNpcGhlci5hbGdvcml0aG1zIHx8IHt9OwoKLyoqCiAqIENyZWF0ZXMgYSBjaXBoZXIgb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8gZW5jcnlwdCBkYXRhIHVzaW5nIHRoZSBnaXZlbgogKiBhbGdvcml0aG0gYW5kIGtleS4gVGhlIGFsZ29yaXRobSBtYXkgYmUgcHJvdmlkZWQgYXMgYSBzdHJpbmcgdmFsdWUgZm9yIGEKICogcHJldmlvdXNseSByZWdpc3RlcmVkIGFsZ29yaXRobSBvciBpdCBtYXkgYmUgZ2l2ZW4gYXMgYSBjaXBoZXIgYWxnb3JpdGhtCiAqIEFQSSBvYmplY3QuCiAqCiAqIEBwYXJhbSBhbGdvcml0aG0gdGhlIGFsZ29yaXRobSB0byB1c2UsIGVpdGhlciBhIHN0cmluZyBvciBhbiBhbGdvcml0aG0gQVBJCiAqICAgICAgICAgIG9iamVjdC4KICogQHBhcmFtIGtleSB0aGUga2V5IHRvIHVzZSwgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMgb3IgYQogKiAgICAgICAgICBieXRlIGJ1ZmZlci4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZm9yZ2UuY2lwaGVyLmNyZWF0ZUNpcGhlciA9IGZ1bmN0aW9uKGFsZ29yaXRobSwga2V5KSB7CiAgdmFyIGFwaSA9IGFsZ29yaXRobTsKICBpZih0eXBlb2YgYXBpID09PSAnc3RyaW5nJykgewogICAgYXBpID0gZm9yZ2UuY2lwaGVyLmdldEFsZ29yaXRobShhcGkpOwogICAgaWYoYXBpKSB7CiAgICAgIGFwaSA9IGFwaSgpOwogICAgfQogIH0KICBpZighYXBpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGFsZ29yaXRobTogJyArIGFsZ29yaXRobSk7CiAgfQoKICAvLyBhc3N1bWUgYmxvY2sgY2lwaGVyCiAgcmV0dXJuIG5ldyBmb3JnZS5jaXBoZXIuQmxvY2tDaXBoZXIoewogICAgYWxnb3JpdGhtOiBhcGksCiAgICBrZXk6IGtleSwKICAgIGRlY3J5cHQ6IGZhbHNlCiAgfSk7Cn07CgovKioKICogQ3JlYXRlcyBhIGRlY2lwaGVyIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIGRlY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4KICogYWxnb3JpdGhtIGFuZCBrZXkuIFRoZSBhbGdvcml0aG0gbWF5IGJlIHByb3ZpZGVkIGFzIGEgc3RyaW5nIHZhbHVlIGZvciBhCiAqIHByZXZpb3VzbHkgcmVnaXN0ZXJlZCBhbGdvcml0aG0gb3IgaXQgbWF5IGJlIGdpdmVuIGFzIGEgY2lwaGVyIGFsZ29yaXRobQogKiBBUEkgb2JqZWN0LgogKgogKiBAcGFyYW0gYWxnb3JpdGhtIHRoZSBhbGdvcml0aG0gdG8gdXNlLCBlaXRoZXIgYSBzdHJpbmcgb3IgYW4gYWxnb3JpdGhtIEFQSQogKiAgICAgICAgICBvYmplY3QuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSB0byB1c2UsIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzIG9yIGEKICogICAgICAgICAgYnl0ZSBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmNpcGhlci5jcmVhdGVEZWNpcGhlciA9IGZ1bmN0aW9uKGFsZ29yaXRobSwga2V5KSB7CiAgdmFyIGFwaSA9IGFsZ29yaXRobTsKICBpZih0eXBlb2YgYXBpID09PSAnc3RyaW5nJykgewogICAgYXBpID0gZm9yZ2UuY2lwaGVyLmdldEFsZ29yaXRobShhcGkpOwogICAgaWYoYXBpKSB7CiAgICAgIGFwaSA9IGFwaSgpOwogICAgfQogIH0KICBpZighYXBpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGFsZ29yaXRobTogJyArIGFsZ29yaXRobSk7CiAgfQoKICAvLyBhc3N1bWUgYmxvY2sgY2lwaGVyCiAgcmV0dXJuIG5ldyBmb3JnZS5jaXBoZXIuQmxvY2tDaXBoZXIoewogICAgYWxnb3JpdGhtOiBhcGksCiAgICBrZXk6IGtleSwKICAgIGRlY3J5cHQ6IHRydWUKICB9KTsKfTsKCi8qKgogKiBSZWdpc3RlcnMgYW4gYWxnb3JpdGhtIGJ5IG5hbWUuIElmIHRoZSBuYW1lIHdhcyBhbHJlYWR5IHJlZ2lzdGVyZWQsIHRoZQogKiBhbGdvcml0aG0gQVBJIG9iamVjdCB3aWxsIGJlIG92ZXJ3cml0dGVuLgogKgogKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLgogKiBAcGFyYW0gYWxnb3JpdGhtIHRoZSBhbGdvcml0aG0gQVBJIG9iamVjdC4KICovCmZvcmdlLmNpcGhlci5yZWdpc3RlckFsZ29yaXRobSA9IGZ1bmN0aW9uKG5hbWUsIGFsZ29yaXRobSkgewogIG5hbWUgPSBuYW1lLnRvVXBwZXJDYXNlKCk7CiAgZm9yZ2UuY2lwaGVyLmFsZ29yaXRobXNbbmFtZV0gPSBhbGdvcml0aG07Cn07CgovKioKICogR2V0cyBhIHJlZ2lzdGVyZWQgYWxnb3JpdGhtIGJ5IG5hbWUuCiAqCiAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0uCiAqCiAqIEByZXR1cm4gdGhlIGFsZ29yaXRobSwgaWYgZm91bmQsIG51bGwgaWYgbm90LgogKi8KZm9yZ2UuY2lwaGVyLmdldEFsZ29yaXRobSA9IGZ1bmN0aW9uKG5hbWUpIHsKICBuYW1lID0gbmFtZS50b1VwcGVyQ2FzZSgpOwogIGlmKG5hbWUgaW4gZm9yZ2UuY2lwaGVyLmFsZ29yaXRobXMpIHsKICAgIHJldHVybiBmb3JnZS5jaXBoZXIuYWxnb3JpdGhtc1tuYW1lXTsKICB9CiAgcmV0dXJuIG51bGw7Cn07Cgp2YXIgQmxvY2tDaXBoZXIgPSBmb3JnZS5jaXBoZXIuQmxvY2tDaXBoZXIgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgdGhpcy5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobTsKICB0aGlzLm1vZGUgPSB0aGlzLmFsZ29yaXRobS5tb2RlOwogIHRoaXMuYmxvY2tTaXplID0gdGhpcy5tb2RlLmJsb2NrU2l6ZTsKICB0aGlzLl9maW5pc2ggPSBmYWxzZTsKICB0aGlzLl9pbnB1dCA9IG51bGw7CiAgdGhpcy5vdXRwdXQgPSBudWxsOwogIHRoaXMuX29wID0gb3B0aW9ucy5kZWNyeXB0ID8gdGhpcy5tb2RlLmRlY3J5cHQgOiB0aGlzLm1vZGUuZW5jcnlwdDsKICB0aGlzLl9kZWNyeXB0ID0gb3B0aW9ucy5kZWNyeXB0OwogIHRoaXMuYWxnb3JpdGhtLmluaXRpYWxpemUob3B0aW9ucyk7Cn07CgovKioKICogU3RhcnRzIG9yIHJlc3RhcnRzIHRoZSBlbmNyeXB0aW9uIG9yIGRlY3J5cHRpb24gcHJvY2Vzcywgd2hpY2hldmVyCiAqIHdhcyBwcmV2aW91c2x5IGNvbmZpZ3VyZWQuCiAqCiAqIEZvciBub24tR0NNIG1vZGUsIHRoZSBJViBtYXkgYmUgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5CiAqIG9mIGJ5dGVzLCBhIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgaW50ZWdlcnMuIElmIHRoZSBJViBpcyBpbgogKiBieXRlcywgdGhlbiBpdCBtdXN0IGJlIE5iICgxNikgYnl0ZXMgaW4gbGVuZ3RoLiBJZiB0aGUgSVYgaXMgZ2l2ZW4gaW4gYXMKICogMzItYml0IGludGVnZXJzLCB0aGVuIGl0IG11c3QgYmUgNCBpbnRlZ2VycyBsb25nLgogKgogKiBOb3RlOiBhbiBJViBpcyBub3QgcmVxdWlyZWQgb3IgdXNlZCBpbiBFQ0IgbW9kZS4KICoKICogRm9yIEdDTS1tb2RlLCB0aGUgSVYgbXVzdCBiZSBnaXZlbiBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBieXRlcyBvcgogKiBhIGJ5dGUgYnVmZmVyLiBUaGUgbnVtYmVyIG9mIGJ5dGVzIHNob3VsZCBiZSAxMiAoOTYgYml0cykgYXMgcmVjb21tZW5kZWQKICogYnkgTklTVCBTUC04MDAtMzhEIGJ1dCBhbm90aGVyIGxlbmd0aCBtYXkgYmUgZ2l2ZW4uCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YKICogICAgICAgICAgICBieXRlcywgbnVsbCB0byByZXVzZSB0aGUgbGFzdCBjaXBoZXJlZCBibG9jayBmcm9tIGEgcHJldmlvdXMKICogICAgICAgICAgICB1cGRhdGUoKSAodGhpcyAicmVzaWR1ZSIgbWV0aG9kIGlzIGZvciBsZWdhY3kgc3VwcG9ydCBvbmx5KS4KICogICAgICAgICAgYWRkaXRpb25hbERhdGEgYWRkaXRpb25hbCBhdXRoZW50aWNhdGlvbiBkYXRhIGFzIGEgYmluYXJ5LWVuY29kZWQKICogICAgICAgICAgICBzdHJpbmcgb2YgYnl0ZXMsIGZvciAnR0NNJyBtb2RlLCAoZGVmYXVsdDogbm9uZSkuCiAqICAgICAgICAgIHRhZ0xlbmd0aCBkZXNpcmVkIGxlbmd0aCBvZiBhdXRoZW50aWNhdGlvbiB0YWcsIGluIGJpdHMsIGZvcgogKiAgICAgICAgICAgICdHQ00nIG1vZGUgKDAtMTI4LCBkZWZhdWx0OiAxMjgpLgogKiAgICAgICAgICB0YWcgdGhlIGF1dGhlbnRpY2F0aW9uIHRhZyB0byBjaGVjayBpZiBkZWNyeXB0aW5nLCBhcyBhCiAqICAgICAgICAgICAgIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBieXRlcy4KICogICAgICAgICAgb3V0cHV0IHRoZSBvdXRwdXQgdGhlIGJ1ZmZlciB0byB3cml0ZSB0bywgbnVsbCB0byBjcmVhdGUgb25lLgogKi8KQmxvY2tDaXBoZXIucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24ob3B0aW9ucykgewogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHZhciBvcHRzID0ge307CiAgZm9yKHZhciBrZXkgaW4gb3B0aW9ucykgewogICAgb3B0c1trZXldID0gb3B0aW9uc1trZXldOwogIH0KICBvcHRzLmRlY3J5cHQgPSB0aGlzLl9kZWNyeXB0OwogIHRoaXMuX2ZpbmlzaCA9IGZhbHNlOwogIHRoaXMuX2lucHV0ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICB0aGlzLm91dHB1dCA9IG9wdGlvbnMub3V0cHV0IHx8IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdGhpcy5tb2RlLnN0YXJ0KG9wdHMpOwp9OwoKLyoqCiAqIFVwZGF0ZXMgdGhlIG5leHQgYmxvY2sgYWNjb3JkaW5nIHRvIHRoZSBjaXBoZXIgbW9kZS4KICoKICogQHBhcmFtIGlucHV0IHRoZSBidWZmZXIgdG8gcmVhZCBmcm9tLgogKi8KQmxvY2tDaXBoZXIucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKGlucHV0KSB7CiAgaWYoaW5wdXQpIHsKICAgIC8vIGlucHV0IGdpdmVuLCBzbyBlbXB0eSBpdCBpbnRvIHRoZSBpbnB1dCBidWZmZXIKICAgIHRoaXMuX2lucHV0LnB1dEJ1ZmZlcihpbnB1dCk7CiAgfQoKICAvLyBkbyBjaXBoZXIgb3BlcmF0aW9uIHVudGlsIGl0IG5lZWRzIG1vcmUgaW5wdXQgYW5kIG5vdCBmaW5pc2hlZAogIHdoaWxlKCF0aGlzLl9vcC5jYWxsKHRoaXMubW9kZSwgdGhpcy5faW5wdXQsIHRoaXMub3V0cHV0LCB0aGlzLl9maW5pc2gpICYmCiAgICAhdGhpcy5fZmluaXNoKSB7fQoKICAvLyBmcmVlIGNvbnN1bWVkIG1lbW9yeSBmcm9tIGlucHV0IGJ1ZmZlcgogIHRoaXMuX2lucHV0LmNvbXBhY3QoKTsKfTsKCi8qKgogKiBGaW5pc2hlcyBlbmNyeXB0aW5nIG9yIGRlY3J5cHRpbmcuCiAqCiAqIEBwYXJhbSBwYWQgYSBwYWRkaW5nIGZ1bmN0aW9uIHRvIHVzZSBpbiBDQkMgbW9kZSwgbnVsbCBmb3IgZGVmYXVsdCwKICogICAgICAgICAgc2lnbmF0dXJlKGJsb2NrU2l6ZSwgYnVmZmVyLCBkZWNyeXB0KS4KICoKICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwsIGZhbHNlIG9uIGVycm9yLgogKi8KQmxvY2tDaXBoZXIucHJvdG90eXBlLmZpbmlzaCA9IGZ1bmN0aW9uKHBhZCkgewogIC8vIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5IHcvZGVwcmVjYXRlZCBwYWRkaW5nIEFQSQogIC8vIE5vdGU6IHdpbGwgb3ZlcndyaXRlIHBhZGRpbmcgZnVuY3Rpb25zIGV2ZW4gYWZ0ZXIgYW5vdGhlciBzdGFydCgpIGNhbGwKICBpZihwYWQgJiYgKHRoaXMubW9kZS5uYW1lID09PSAnRUNCJyB8fCB0aGlzLm1vZGUubmFtZSA9PT0gJ0NCQycpKSB7CiAgICB0aGlzLm1vZGUucGFkID0gZnVuY3Rpb24oaW5wdXQpIHsKICAgICAgcmV0dXJuIHBhZCh0aGlzLmJsb2NrU2l6ZSwgaW5wdXQsIGZhbHNlKTsKICAgIH07CiAgICB0aGlzLm1vZGUudW5wYWQgPSBmdW5jdGlvbihvdXRwdXQpIHsKICAgICAgcmV0dXJuIHBhZCh0aGlzLmJsb2NrU2l6ZSwgb3V0cHV0LCB0cnVlKTsKICAgIH07CiAgfQoKICAvLyBidWlsZCBvcHRpb25zIGZvciBwYWRkaW5nIGFuZCBhZnRlckZpbmlzaCBmdW5jdGlvbnMKICB2YXIgb3B0aW9ucyA9IHt9OwogIG9wdGlvbnMuZGVjcnlwdCA9IHRoaXMuX2RlY3J5cHQ7CgogIC8vIGdldCAjIG9mIGJ5dGVzIHRoYXQgd29uJ3QgZmlsbCBhIGJsb2NrCiAgb3B0aW9ucy5vdmVyZmxvdyA9IHRoaXMuX2lucHV0Lmxlbmd0aCgpICUgdGhpcy5ibG9ja1NpemU7CgogIGlmKCF0aGlzLl9kZWNyeXB0ICYmIHRoaXMubW9kZS5wYWQpIHsKICAgIGlmKCF0aGlzLm1vZGUucGFkKHRoaXMuX2lucHV0LCBvcHRpb25zKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQoKICAvLyBkbyBmaW5hbCB1cGRhdGUKICB0aGlzLl9maW5pc2ggPSB0cnVlOwogIHRoaXMudXBkYXRlKCk7CgogIGlmKHRoaXMuX2RlY3J5cHQgJiYgdGhpcy5tb2RlLnVucGFkKSB7CiAgICBpZighdGhpcy5tb2RlLnVucGFkKHRoaXMub3V0cHV0LCBvcHRpb25zKSkgewogICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgfQoKICBpZih0aGlzLm1vZGUuYWZ0ZXJGaW5pc2gpIHsKICAgIGlmKCF0aGlzLm1vZGUuYWZ0ZXJGaW5pc2godGhpcy5vdXRwdXQsIG9wdGlvbnMpKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICB9CgogIHJldHVybiB0cnVlOwp9OwoKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ2NpcGhlcic7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9jaXBoZXInLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFN1cHBvcnRlZCBjaXBoZXIgbW9kZXMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UuY2lwaGVyID0gZm9yZ2UuY2lwaGVyIHx8IHt9OwoKLy8gc3VwcG9ydGVkIGNpcGhlciBtb2Rlcwp2YXIgbW9kZXMgPSBmb3JnZS5jaXBoZXIubW9kZXMgPSBmb3JnZS5jaXBoZXIubW9kZXMgfHwge307CgoKLyoqIEVsZWN0cm9uaWMgY29kZWJvb2sgKEVDQikgKERvbid0IHVzZSB0aGlzOyBpdCdzIG5vdCBzZWN1cmUpICoqLwoKbW9kZXMuZWNiID0gZnVuY3Rpb24ob3B0aW9ucykgewogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHRoaXMubmFtZSA9ICdFQ0InOwogIHRoaXMuY2lwaGVyID0gb3B0aW9ucy5jaXBoZXI7CiAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLmJsb2NrU2l6ZSB8fCAxNjsKICB0aGlzLl9pbnRzID0gdGhpcy5ibG9ja1NpemUgLyA0OwogIHRoaXMuX2luQmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fb3V0QmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7Cn07Cgptb2Rlcy5lY2IucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24ob3B0aW9ucykge307Cgptb2Rlcy5lY2IucHJvdG90eXBlLmVuY3J5cHQgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBmaW5pc2gpIHsKICAvLyBub3QgZW5vdWdoIGlucHV0IHRvIGVuY3J5cHQKICBpZihpbnB1dC5sZW5ndGgoKSA8IHRoaXMuYmxvY2tTaXplICYmICEoZmluaXNoICYmIGlucHV0Lmxlbmd0aCgpID4gMCkpIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZ2V0IG5leHQgYmxvY2sKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICB0aGlzLl9pbkJsb2NrW2ldID0gaW5wdXQuZ2V0SW50MzIoKTsKICB9CgogIC8vIGVuY3J5cHQgYmxvY2sKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gd3JpdGUgb3V0cHV0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX291dEJsb2NrW2ldKTsKICB9Cn07Cgptb2Rlcy5lY2IucHJvdG90eXBlLmRlY3J5cHQgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBmaW5pc2gpIHsKICAvLyBub3QgZW5vdWdoIGlucHV0IHRvIGRlY3J5cHQKICBpZihpbnB1dC5sZW5ndGgoKSA8IHRoaXMuYmxvY2tTaXplICYmICEoZmluaXNoICYmIGlucHV0Lmxlbmd0aCgpID4gMCkpIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZ2V0IG5leHQgYmxvY2sKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICB0aGlzLl9pbkJsb2NrW2ldID0gaW5wdXQuZ2V0SW50MzIoKTsKICB9CgogIC8vIGRlY3J5cHQgYmxvY2sKICB0aGlzLmNpcGhlci5kZWNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gd3JpdGUgb3V0cHV0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX291dEJsb2NrW2ldKTsKICB9Cn07Cgptb2Rlcy5lY2IucHJvdG90eXBlLnBhZCA9IGZ1bmN0aW9uKGlucHV0LCBvcHRpb25zKSB7CiAgLy8gYWRkIFBLQ1MjNyBwYWRkaW5nIHRvIGJsb2NrIChlYWNoIHBhZCBieXRlIGlzIHRoZQogIC8vIHZhbHVlIG9mIHRoZSBudW1iZXIgb2YgcGFkIGJ5dGVzKQogIHZhciBwYWRkaW5nID0gKGlucHV0Lmxlbmd0aCgpID09PSB0aGlzLmJsb2NrU2l6ZSA/CiAgICB0aGlzLmJsb2NrU2l6ZSA6ICh0aGlzLmJsb2NrU2l6ZSAtIGlucHV0Lmxlbmd0aCgpKSk7CiAgaW5wdXQuZmlsbFdpdGhCeXRlKHBhZGRpbmcsIHBhZGRpbmcpOwogIHJldHVybiB0cnVlOwp9OwoKbW9kZXMuZWNiLnByb3RvdHlwZS51bnBhZCA9IGZ1bmN0aW9uKG91dHB1dCwgb3B0aW9ucykgewogIC8vIGNoZWNrIGZvciBlcnJvcjogaW5wdXQgZGF0YSBub3QgYSBtdWx0aXBsZSBvZiBibG9ja1NpemUKICBpZihvcHRpb25zLm92ZXJmbG93ID4gMCkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgLy8gZW5zdXJlIHBhZGRpbmcgYnl0ZSBjb3VudCBpcyB2YWxpZAogIHZhciBsZW4gPSBvdXRwdXQubGVuZ3RoKCk7CiAgdmFyIGNvdW50ID0gb3V0cHV0LmF0KGxlbiAtIDEpOwogIGlmKGNvdW50ID4gKHRoaXMuYmxvY2tTaXplIDw8IDIpKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICAvLyB0cmltIG9mZiBwYWRkaW5nIGJ5dGVzCiAgb3V0cHV0LnRydW5jYXRlKGNvdW50KTsKICByZXR1cm4gdHJ1ZTsKfTsKCgovKiogQ2lwaGVyLWJsb2NrIENoYWluaW5nIChDQkMpICoqLwoKbW9kZXMuY2JjID0gZnVuY3Rpb24ob3B0aW9ucykgewogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHRoaXMubmFtZSA9ICdDQkMnOwogIHRoaXMuY2lwaGVyID0gb3B0aW9ucy5jaXBoZXI7CiAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLmJsb2NrU2l6ZSB8fCAxNjsKICB0aGlzLl9pbnRzID0gdGhpcy5ibG9ja1NpemUgLyA0OwogIHRoaXMuX2luQmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fb3V0QmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7Cn07Cgptb2Rlcy5jYmMucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24ob3B0aW9ucykgewogIC8vIE5vdGU6IGxlZ2FjeSBzdXBwb3J0IGZvciB1c2luZyBJViByZXNpZHVlIChoYXMgc2VjdXJpdHkgZmxhd3MpCiAgLy8gaWYgSVYgaXMgbnVsbCwgcmV1c2UgYmxvY2sgZnJvbSBwcmV2aW91cyBwcm9jZXNzaW5nCiAgaWYob3B0aW9ucy5pdiA9PT0gbnVsbCkgewogICAgLy8gbXVzdCBoYXZlIGEgcHJldmlvdXMgYmxvY2sKICAgIGlmKCF0aGlzLl9wcmV2KSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBJViBwYXJhbWV0ZXIuJyk7CiAgICB9CiAgICB0aGlzLl9pdiA9IHRoaXMuX3ByZXYuc2xpY2UoMCk7CiAgfSBlbHNlIGlmKCEoJ2l2JyBpbiBvcHRpb25zKSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIElWIHBhcmFtZXRlci4nKTsKICB9IGVsc2UgewogICAgLy8gc2F2ZSBJViBhcyAicHJldmlvdXMiIGJsb2NrCiAgICB0aGlzLl9pdiA9IHRyYW5zZm9ybUlWKG9wdGlvbnMuaXYpOwogICAgdGhpcy5fcHJldiA9IHRoaXMuX2l2LnNsaWNlKDApOwogIH0KfTsKCm1vZGVzLmNiYy5wcm90b3R5cGUuZW5jcnlwdCA9IGZ1bmN0aW9uKGlucHV0LCBvdXRwdXQsIGZpbmlzaCkgewogIC8vIG5vdCBlbm91Z2ggaW5wdXQgdG8gZW5jcnlwdAogIGlmKGlucHV0Lmxlbmd0aCgpIDwgdGhpcy5ibG9ja1NpemUgJiYgIShmaW5pc2ggJiYgaW5wdXQubGVuZ3RoKCkgPiAwKSkgewogICAgcmV0dXJuIHRydWU7CiAgfQoKICAvLyBnZXQgbmV4dCBibG9jawogIC8vIENCQyBYT1IncyBJViAob3IgcHJldmlvdXMgYmxvY2spIHdpdGggcGxhaW50ZXh0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgdGhpcy5faW5CbG9ja1tpXSA9IHRoaXMuX3ByZXZbaV0gXiBpbnB1dC5nZXRJbnQzMigpOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jawogIHRoaXMuY2lwaGVyLmVuY3J5cHQodGhpcy5faW5CbG9jaywgdGhpcy5fb3V0QmxvY2spOwoKICAvLyB3cml0ZSBvdXRwdXQsIHNhdmUgcHJldmlvdXMgYmxvY2sKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICBvdXRwdXQucHV0SW50MzIodGhpcy5fb3V0QmxvY2tbaV0pOwogIH0KICB0aGlzLl9wcmV2ID0gdGhpcy5fb3V0QmxvY2s7Cn07Cgptb2Rlcy5jYmMucHJvdG90eXBlLmRlY3J5cHQgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBmaW5pc2gpIHsKICAvLyBub3QgZW5vdWdoIGlucHV0IHRvIGRlY3J5cHQKICBpZihpbnB1dC5sZW5ndGgoKSA8IHRoaXMuYmxvY2tTaXplICYmICEoZmluaXNoICYmIGlucHV0Lmxlbmd0aCgpID4gMCkpIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZ2V0IG5leHQgYmxvY2sKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICB0aGlzLl9pbkJsb2NrW2ldID0gaW5wdXQuZ2V0SW50MzIoKTsKICB9CgogIC8vIGRlY3J5cHQgYmxvY2sKICB0aGlzLmNpcGhlci5kZWNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gd3JpdGUgb3V0cHV0LCBzYXZlIHByZXZpb3VzIGNpcGhlcmVkIGJsb2NrCiAgLy8gQ0JDIFhPUidzIElWIChvciBwcmV2aW91cyBibG9jaykgd2l0aCBjaXBoZXJ0ZXh0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX3ByZXZbaV0gXiB0aGlzLl9vdXRCbG9ja1tpXSk7CiAgfQogIHRoaXMuX3ByZXYgPSB0aGlzLl9pbkJsb2NrLnNsaWNlKDApOwp9OwoKbW9kZXMuY2JjLnByb3RvdHlwZS5wYWQgPSBmdW5jdGlvbihpbnB1dCwgb3B0aW9ucykgewogIC8vIGFkZCBQS0NTIzcgcGFkZGluZyB0byBibG9jayAoZWFjaCBwYWQgYnl0ZSBpcyB0aGUKICAvLyB2YWx1ZSBvZiB0aGUgbnVtYmVyIG9mIHBhZCBieXRlcykKICB2YXIgcGFkZGluZyA9IChpbnB1dC5sZW5ndGgoKSA9PT0gdGhpcy5ibG9ja1NpemUgPwogICAgdGhpcy5ibG9ja1NpemUgOiAodGhpcy5ibG9ja1NpemUgLSBpbnB1dC5sZW5ndGgoKSkpOwogIGlucHV0LmZpbGxXaXRoQnl0ZShwYWRkaW5nLCBwYWRkaW5nKTsKICByZXR1cm4gdHJ1ZTsKfTsKCm1vZGVzLmNiYy5wcm90b3R5cGUudW5wYWQgPSBmdW5jdGlvbihvdXRwdXQsIG9wdGlvbnMpIHsKICAvLyBjaGVjayBmb3IgZXJyb3I6IGlucHV0IGRhdGEgbm90IGEgbXVsdGlwbGUgb2YgYmxvY2tTaXplCiAgaWYob3B0aW9ucy5vdmVyZmxvdyA+IDApIHsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIC8vIGVuc3VyZSBwYWRkaW5nIGJ5dGUgY291bnQgaXMgdmFsaWQKICB2YXIgbGVuID0gb3V0cHV0Lmxlbmd0aCgpOwogIHZhciBjb3VudCA9IG91dHB1dC5hdChsZW4gLSAxKTsKICBpZihjb3VudCA+ICh0aGlzLmJsb2NrU2l6ZSA8PCAyKSkgewogICAgcmV0dXJuIGZhbHNlOwogIH0KCiAgLy8gdHJpbSBvZmYgcGFkZGluZyBieXRlcwogIG91dHB1dC50cnVuY2F0ZShjb3VudCk7CiAgcmV0dXJuIHRydWU7Cn07CgoKLyoqIENpcGhlciBmZWVkYmFjayAoQ0ZCKSAqKi8KCm1vZGVzLmNmYiA9IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICB0aGlzLm5hbWUgPSAnQ0ZCJzsKICB0aGlzLmNpcGhlciA9IG9wdGlvbnMuY2lwaGVyOwogIHRoaXMuYmxvY2tTaXplID0gb3B0aW9ucy5ibG9ja1NpemUgfHwgMTY7CiAgdGhpcy5faW50cyA9IHRoaXMuYmxvY2tTaXplIC8gNDsKICB0aGlzLl9pbkJsb2NrID0gbnVsbDsKICB0aGlzLl9vdXRCbG9jayA9IG5ldyBBcnJheSh0aGlzLl9pbnRzKTsKICB0aGlzLl9wYXJ0aWFsQmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fcGFydGlhbE91dHB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKfTsKCm1vZGVzLmNmYi5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYoISgnaXYnIGluIG9wdGlvbnMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSVYgcGFyYW1ldGVyLicpOwogIH0KICAvLyB1c2UgSVYgYXMgZmlyc3QgaW5wdXQKICB0aGlzLl9pdiA9IHRyYW5zZm9ybUlWKG9wdGlvbnMuaXYpOwogIHRoaXMuX2luQmxvY2sgPSB0aGlzLl9pdi5zbGljZSgwKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwp9OwoKbW9kZXMuY2ZiLnByb3RvdHlwZS5lbmNyeXB0ID0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCwgZmluaXNoKSB7CiAgLy8gbm90IGVub3VnaCBpbnB1dCB0byBlbmNyeXB0CiAgdmFyIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoKCk7CiAgaWYoaW5wdXRMZW5ndGggPT09IDApIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jawogIHRoaXMuY2lwaGVyLmVuY3J5cHQodGhpcy5faW5CbG9jaywgdGhpcy5fb3V0QmxvY2spOwoKICAvLyBoYW5kbGUgZnVsbCBibG9jawogIGlmKHRoaXMuX3BhcnRpYWxCeXRlcyA9PT0gMCAmJiBpbnB1dExlbmd0aCA+PSB0aGlzLmJsb2NrU2l6ZSkgewogICAgLy8gWE9SIGlucHV0IHdpdGggb3V0cHV0LCB3cml0ZSBpbnB1dCBhcyBvdXRwdXQKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgICAgdGhpcy5faW5CbG9ja1tpXSA9IGlucHV0LmdldEludDMyKCkgXiB0aGlzLl9vdXRCbG9ja1tpXTsKICAgICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX2luQmxvY2tbaV0pOwogICAgfQogICAgcmV0dXJuOwogIH0KCiAgLy8gaGFuZGxlIHBhcnRpYWwgYmxvY2sKICB2YXIgcGFydGlhbEJ5dGVzID0gKHRoaXMuYmxvY2tTaXplIC0gaW5wdXRMZW5ndGgpICUgdGhpcy5ibG9ja1NpemU7CiAgaWYocGFydGlhbEJ5dGVzID4gMCkgewogICAgcGFydGlhbEJ5dGVzID0gdGhpcy5ibG9ja1NpemUgLSBwYXJ0aWFsQnl0ZXM7CiAgfQoKICAvLyBYT1IgaW5wdXQgd2l0aCBvdXRwdXQsIHdyaXRlIGlucHV0IGFzIHBhcnRpYWwgb3V0cHV0CiAgdGhpcy5fcGFydGlhbE91dHB1dC5jbGVhcigpOwogIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgIHRoaXMuX3BhcnRpYWxCbG9ja1tpXSA9IGlucHV0LmdldEludDMyKCkgXiB0aGlzLl9vdXRCbG9ja1tpXTsKICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQucHV0SW50MzIodGhpcy5fcGFydGlhbEJsb2NrW2ldKTsKICB9CgogIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgIC8vIGJsb2NrIHN0aWxsIGluY29tcGxldGUsIHJlc3RvcmUgaW5wdXQgYnVmZmVyCiAgICBpbnB1dC5yZWFkIC09IHRoaXMuYmxvY2tTaXplOwogIH0gZWxzZSB7CiAgICAvLyBibG9jayBjb21wbGV0ZSwgdXBkYXRlIGlucHV0IGJsb2NrCiAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgIHRoaXMuX2luQmxvY2tbaV0gPSB0aGlzLl9wYXJ0aWFsQmxvY2tbaV07CiAgICB9CiAgfQoKICAvLyBza2lwIGFueSBwcmV2aW91cyBwYXJ0aWFsIGJ5dGVzCiAgaWYodGhpcy5fcGFydGlhbEJ5dGVzID4gMCkgewogICAgdGhpcy5fcGFydGlhbE91dHB1dC5nZXRCeXRlcyh0aGlzLl9wYXJ0aWFsQnl0ZXMpOwogIH0KCiAgaWYocGFydGlhbEJ5dGVzID4gMCAmJiAhZmluaXNoKSB7CiAgICBvdXRwdXQucHV0Qnl0ZXModGhpcy5fcGFydGlhbE91dHB1dC5nZXRCeXRlcygKICAgICAgcGFydGlhbEJ5dGVzIC0gdGhpcy5fcGFydGlhbEJ5dGVzKSk7CiAgICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSBwYXJ0aWFsQnl0ZXM7CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgaW5wdXRMZW5ndGggLSB0aGlzLl9wYXJ0aWFsQnl0ZXMpKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwp9OwoKbW9kZXMuY2ZiLnByb3RvdHlwZS5kZWNyeXB0ID0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCwgZmluaXNoKSB7CiAgLy8gbm90IGVub3VnaCBpbnB1dCB0byBkZWNyeXB0CiAgdmFyIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoKCk7CiAgaWYoaW5wdXRMZW5ndGggPT09IDApIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jayAoQ0ZCIGFsd2F5cyB1c2VzIGVuY3J5cHRpb24gbW9kZSkKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gaGFuZGxlIGZ1bGwgYmxvY2sKICBpZih0aGlzLl9wYXJ0aWFsQnl0ZXMgPT09IDAgJiYgaW5wdXRMZW5ndGggPj0gdGhpcy5ibG9ja1NpemUpIHsKICAgIC8vIFhPUiBpbnB1dCB3aXRoIG91dHB1dCwgd3JpdGUgaW5wdXQgYXMgb3V0cHV0CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgIHRoaXMuX2luQmxvY2tbaV0gPSBpbnB1dC5nZXRJbnQzMigpOwogICAgICBvdXRwdXQucHV0SW50MzIodGhpcy5faW5CbG9ja1tpXSBeIHRoaXMuX291dEJsb2NrW2ldKTsKICAgIH0KICAgIHJldHVybjsKICB9CgogIC8vIGhhbmRsZSBwYXJ0aWFsIGJsb2NrCiAgdmFyIHBhcnRpYWxCeXRlcyA9ICh0aGlzLmJsb2NrU2l6ZSAtIGlucHV0TGVuZ3RoKSAlIHRoaXMuYmxvY2tTaXplOwogIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgIHBhcnRpYWxCeXRlcyA9IHRoaXMuYmxvY2tTaXplIC0gcGFydGlhbEJ5dGVzOwogIH0KCiAgLy8gWE9SIGlucHV0IHdpdGggb3V0cHV0LCB3cml0ZSBpbnB1dCBhcyBwYXJ0aWFsIG91dHB1dAogIHRoaXMuX3BhcnRpYWxPdXRwdXQuY2xlYXIoKTsKICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICB0aGlzLl9wYXJ0aWFsQmxvY2tbaV0gPSBpbnB1dC5nZXRJbnQzMigpOwogICAgdGhpcy5fcGFydGlhbE91dHB1dC5wdXRJbnQzMih0aGlzLl9wYXJ0aWFsQmxvY2tbaV0gXiB0aGlzLl9vdXRCbG9ja1tpXSk7CiAgfQoKICBpZihwYXJ0aWFsQnl0ZXMgPiAwKSB7CiAgICAvLyBibG9jayBzdGlsbCBpbmNvbXBsZXRlLCByZXN0b3JlIGlucHV0IGJ1ZmZlcgogICAgaW5wdXQucmVhZCAtPSB0aGlzLmJsb2NrU2l6ZTsKICB9IGVsc2UgewogICAgLy8gYmxvY2sgY29tcGxldGUsIHVwZGF0ZSBpbnB1dCBibG9jawogICAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgICB0aGlzLl9pbkJsb2NrW2ldID0gdGhpcy5fcGFydGlhbEJsb2NrW2ldOwogICAgfQogIH0KCiAgLy8gc2tpcCBhbnkgcHJldmlvdXMgcGFydGlhbCBieXRlcwogIGlmKHRoaXMuX3BhcnRpYWxCeXRlcyA+IDApIHsKICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQuZ2V0Qnl0ZXModGhpcy5fcGFydGlhbEJ5dGVzKTsKICB9CgogIGlmKHBhcnRpYWxCeXRlcyA+IDAgJiYgIWZpbmlzaCkgewogICAgb3V0cHV0LnB1dEJ5dGVzKHRoaXMuX3BhcnRpYWxPdXRwdXQuZ2V0Qnl0ZXMoCiAgICAgIHBhcnRpYWxCeXRlcyAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgdGhpcy5fcGFydGlhbEJ5dGVzID0gcGFydGlhbEJ5dGVzOwogICAgcmV0dXJuIHRydWU7CiAgfQoKICBvdXRwdXQucHV0Qnl0ZXModGhpcy5fcGFydGlhbE91dHB1dC5nZXRCeXRlcygKICAgIGlucHV0TGVuZ3RoIC0gdGhpcy5fcGFydGlhbEJ5dGVzKSk7CiAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKfTsKCi8qKiBPdXRwdXQgZmVlZGJhY2sgKE9GQikgKiovCgptb2Rlcy5vZmIgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdGhpcy5uYW1lID0gJ09GQic7CiAgdGhpcy5jaXBoZXIgPSBvcHRpb25zLmNpcGhlcjsKICB0aGlzLmJsb2NrU2l6ZSA9IG9wdGlvbnMuYmxvY2tTaXplIHx8IDE2OwogIHRoaXMuX2ludHMgPSB0aGlzLmJsb2NrU2l6ZSAvIDQ7CiAgdGhpcy5faW5CbG9jayA9IG51bGw7CiAgdGhpcy5fb3V0QmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fcGFydGlhbE91dHB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKfTsKCm1vZGVzLm9mYi5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYoISgnaXYnIGluIG9wdGlvbnMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSVYgcGFyYW1ldGVyLicpOwogIH0KICAvLyB1c2UgSVYgYXMgZmlyc3QgaW5wdXQKICB0aGlzLl9pdiA9IHRyYW5zZm9ybUlWKG9wdGlvbnMuaXYpOwogIHRoaXMuX2luQmxvY2sgPSB0aGlzLl9pdi5zbGljZSgwKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwp9OwoKbW9kZXMub2ZiLnByb3RvdHlwZS5lbmNyeXB0ID0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCwgZmluaXNoKSB7CiAgLy8gbm90IGVub3VnaCBpbnB1dCB0byBlbmNyeXB0CiAgdmFyIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoKCk7CiAgaWYoaW5wdXQubGVuZ3RoKCkgPT09IDApIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jayAoT0ZCIGFsd2F5cyB1c2VzIGVuY3J5cHRpb24gbW9kZSkKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gaGFuZGxlIGZ1bGwgYmxvY2sKICBpZih0aGlzLl9wYXJ0aWFsQnl0ZXMgPT09IDAgJiYgaW5wdXRMZW5ndGggPj0gdGhpcy5ibG9ja1NpemUpIHsKICAgIC8vIFhPUiBpbnB1dCB3aXRoIG91dHB1dCBhbmQgdXBkYXRlIG5leHQgaW5wdXQKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgICAgb3V0cHV0LnB1dEludDMyKGlucHV0LmdldEludDMyKCkgXiB0aGlzLl9vdXRCbG9ja1tpXSk7CiAgICAgIHRoaXMuX2luQmxvY2tbaV0gPSB0aGlzLl9vdXRCbG9ja1tpXTsKICAgIH0KICAgIHJldHVybjsKICB9CgogIC8vIGhhbmRsZSBwYXJ0aWFsIGJsb2NrCiAgdmFyIHBhcnRpYWxCeXRlcyA9ICh0aGlzLmJsb2NrU2l6ZSAtIGlucHV0TGVuZ3RoKSAlIHRoaXMuYmxvY2tTaXplOwogIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgIHBhcnRpYWxCeXRlcyA9IHRoaXMuYmxvY2tTaXplIC0gcGFydGlhbEJ5dGVzOwogIH0KCiAgLy8gWE9SIGlucHV0IHdpdGggb3V0cHV0CiAgdGhpcy5fcGFydGlhbE91dHB1dC5jbGVhcigpOwogIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQucHV0SW50MzIoaW5wdXQuZ2V0SW50MzIoKSBeIHRoaXMuX291dEJsb2NrW2ldKTsKICB9CgogIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgIC8vIGJsb2NrIHN0aWxsIGluY29tcGxldGUsIHJlc3RvcmUgaW5wdXQgYnVmZmVyCiAgICBpbnB1dC5yZWFkIC09IHRoaXMuYmxvY2tTaXplOwogIH0gZWxzZSB7CiAgICAvLyBibG9jayBjb21wbGV0ZSwgdXBkYXRlIGlucHV0IGJsb2NrCiAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgIHRoaXMuX2luQmxvY2tbaV0gPSB0aGlzLl9vdXRCbG9ja1tpXTsKICAgIH0KICB9CgogIC8vIHNraXAgYW55IHByZXZpb3VzIHBhcnRpYWwgYnl0ZXMKICBpZih0aGlzLl9wYXJ0aWFsQnl0ZXMgPiAwKSB7CiAgICB0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKHRoaXMuX3BhcnRpYWxCeXRlcyk7CiAgfQoKICBpZihwYXJ0aWFsQnl0ZXMgPiAwICYmICFmaW5pc2gpIHsKICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICBwYXJ0aWFsQnl0ZXMgLSB0aGlzLl9wYXJ0aWFsQnl0ZXMpKTsKICAgIHRoaXMuX3BhcnRpYWxCeXRlcyA9IHBhcnRpYWxCeXRlczsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgb3V0cHV0LnB1dEJ5dGVzKHRoaXMuX3BhcnRpYWxPdXRwdXQuZ2V0Qnl0ZXMoCiAgICBpbnB1dExlbmd0aCAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogIHRoaXMuX3BhcnRpYWxCeXRlcyA9IDA7Cn07Cgptb2Rlcy5vZmIucHJvdG90eXBlLmRlY3J5cHQgPSBtb2Rlcy5vZmIucHJvdG90eXBlLmVuY3J5cHQ7CgoKLyoqIENvdW50ZXIgKENUUikgKiovCgptb2Rlcy5jdHIgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdGhpcy5uYW1lID0gJ0NUUic7CiAgdGhpcy5jaXBoZXIgPSBvcHRpb25zLmNpcGhlcjsKICB0aGlzLmJsb2NrU2l6ZSA9IG9wdGlvbnMuYmxvY2tTaXplIHx8IDE2OwogIHRoaXMuX2ludHMgPSB0aGlzLmJsb2NrU2l6ZSAvIDQ7CiAgdGhpcy5faW5CbG9jayA9IG51bGw7CiAgdGhpcy5fb3V0QmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5fcGFydGlhbE91dHB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKfTsKCm1vZGVzLmN0ci5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYoISgnaXYnIGluIG9wdGlvbnMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSVYgcGFyYW1ldGVyLicpOwogIH0KICAvLyB1c2UgSVYgYXMgZmlyc3QgaW5wdXQKICB0aGlzLl9pdiA9IHRyYW5zZm9ybUlWKG9wdGlvbnMuaXYpOwogIHRoaXMuX2luQmxvY2sgPSB0aGlzLl9pdi5zbGljZSgwKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwp9OwoKbW9kZXMuY3RyLnByb3RvdHlwZS5lbmNyeXB0ID0gZnVuY3Rpb24oaW5wdXQsIG91dHB1dCwgZmluaXNoKSB7CiAgLy8gbm90IGVub3VnaCBpbnB1dCB0byBlbmNyeXB0CiAgdmFyIGlucHV0TGVuZ3RoID0gaW5wdXQubGVuZ3RoKCk7CiAgaWYoaW5wdXRMZW5ndGggPT09IDApIHsKICAgIHJldHVybiB0cnVlOwogIH0KCiAgLy8gZW5jcnlwdCBibG9jayAoQ1RSIGFsd2F5cyB1c2VzIGVuY3J5cHRpb24gbW9kZSkKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2luQmxvY2ssIHRoaXMuX291dEJsb2NrKTsKCiAgLy8gaGFuZGxlIGZ1bGwgYmxvY2sKICBpZih0aGlzLl9wYXJ0aWFsQnl0ZXMgPT09IDAgJiYgaW5wdXRMZW5ndGggPj0gdGhpcy5ibG9ja1NpemUpIHsKICAgIC8vIFhPUiBpbnB1dCB3aXRoIG91dHB1dAogICAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgICBvdXRwdXQucHV0SW50MzIoaW5wdXQuZ2V0SW50MzIoKSBeIHRoaXMuX291dEJsb2NrW2ldKTsKICAgIH0KICB9IGVsc2UgewogICAgLy8gaGFuZGxlIHBhcnRpYWwgYmxvY2sKICAgIHZhciBwYXJ0aWFsQnl0ZXMgPSAodGhpcy5ibG9ja1NpemUgLSBpbnB1dExlbmd0aCkgJSB0aGlzLmJsb2NrU2l6ZTsKICAgIGlmKHBhcnRpYWxCeXRlcyA+IDApIHsKICAgICAgcGFydGlhbEJ5dGVzID0gdGhpcy5ibG9ja1NpemUgLSBwYXJ0aWFsQnl0ZXM7CiAgICB9CgogICAgLy8gWE9SIGlucHV0IHdpdGggb3V0cHV0CiAgICB0aGlzLl9wYXJ0aWFsT3V0cHV0LmNsZWFyKCk7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQucHV0SW50MzIoaW5wdXQuZ2V0SW50MzIoKSBeIHRoaXMuX291dEJsb2NrW2ldKTsKICAgIH0KCiAgICBpZihwYXJ0aWFsQnl0ZXMgPiAwKSB7CiAgICAgIC8vIGJsb2NrIHN0aWxsIGluY29tcGxldGUsIHJlc3RvcmUgaW5wdXQgYnVmZmVyCiAgICAgIGlucHV0LnJlYWQgLT0gdGhpcy5ibG9ja1NpemU7CiAgICB9CgogICAgLy8gc2tpcCBhbnkgcHJldmlvdXMgcGFydGlhbCBieXRlcwogICAgaWYodGhpcy5fcGFydGlhbEJ5dGVzID4gMCkgewogICAgICB0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKHRoaXMuX3BhcnRpYWxCeXRlcyk7CiAgICB9CgogICAgaWYocGFydGlhbEJ5dGVzID4gMCAmJiAhZmluaXNoKSB7CiAgICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICAgIHBhcnRpYWxCeXRlcyAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSBwYXJ0aWFsQnl0ZXM7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICBpbnB1dExlbmd0aCAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKICB9CgogIC8vIGJsb2NrIGNvbXBsZXRlLCBpbmNyZW1lbnQgY291bnRlciAoaW5wdXQgYmxvY2spCiAgaW5jMzIodGhpcy5faW5CbG9jayk7Cn07Cgptb2Rlcy5jdHIucHJvdG90eXBlLmRlY3J5cHQgPSBtb2Rlcy5jdHIucHJvdG90eXBlLmVuY3J5cHQ7CgoKLyoqIEdhbG9pcy9Db3VudGVyIE1vZGUgKEdDTSkgKiovCgptb2Rlcy5nY20gPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdGhpcy5uYW1lID0gJ0dDTSc7CiAgdGhpcy5jaXBoZXIgPSBvcHRpb25zLmNpcGhlcjsKICB0aGlzLmJsb2NrU2l6ZSA9IG9wdGlvbnMuYmxvY2tTaXplIHx8IDE2OwogIHRoaXMuX2ludHMgPSB0aGlzLmJsb2NrU2l6ZSAvIDQ7CiAgdGhpcy5faW5CbG9jayA9IG5ldyBBcnJheSh0aGlzLl9pbnRzKTsKICB0aGlzLl9vdXRCbG9jayA9IG5ldyBBcnJheSh0aGlzLl9pbnRzKTsKICB0aGlzLl9wYXJ0aWFsT3V0cHV0ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwoKICAvLyBSIGlzIGFjdHVhbGx5IHRoaXMgdmFsdWUgY29uY2F0ZW5hdGVkIHdpdGggMTIwIG1vcmUgemVybyBiaXRzLCBidXQKICAvLyB3ZSBvbmx5IFhPUiBhZ2FpbnN0IFIgc28gdGhlIG90aGVyIHplcm9zIGhhdmUgbm8gZWZmZWN0IC0tIHdlIGp1c3QKICAvLyBhcHBseSB0aGlzIHZhbHVlIHRvIHRoZSBmaXJzdCBpbnRlZ2VyIGluIGEgYmxvY2sKICB0aGlzLl9SID0gMHhFMTAwMDAwMDsKfTsKCm1vZGVzLmdjbS5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYoISgnaXYnIGluIG9wdGlvbnMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgSVYgcGFyYW1ldGVyLicpOwogIH0KICAvLyBlbnN1cmUgSVYgaXMgYSBieXRlIGJ1ZmZlcgogIHZhciBpdiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKG9wdGlvbnMuaXYpOwoKICAvLyBubyBjaXBoZXJlZCBkYXRhIHByb2Nlc3NlZCB5ZXQKICB0aGlzLl9jaXBoZXJMZW5ndGggPSAwOwoKICAvLyBkZWZhdWx0IGFkZGl0aW9uYWwgZGF0YSBpcyBub25lCiAgdmFyIGFkZGl0aW9uYWxEYXRhOwogIGlmKCdhZGRpdGlvbmFsRGF0YScgaW4gb3B0aW9ucykgewogICAgYWRkaXRpb25hbERhdGEgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihvcHRpb25zLmFkZGl0aW9uYWxEYXRhKTsKICB9IGVsc2UgewogICAgYWRkaXRpb25hbERhdGEgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIH0KCiAgLy8gZGVmYXVsdCB0YWcgbGVuZ3RoIGlzIDEyOCBiaXRzCiAgaWYoJ3RhZ0xlbmd0aCcgaW4gb3B0aW9ucykgewogICAgdGhpcy5fdGFnTGVuZ3RoID0gb3B0aW9ucy50YWdMZW5ndGg7CiAgfSBlbHNlIHsKICAgIHRoaXMuX3RhZ0xlbmd0aCA9IDEyODsKICB9CgogIC8vIGlmIHRhZyBpcyBnaXZlbiwgZW5zdXJlIHRhZyBtYXRjaGVzIHRhZyBsZW5ndGgKICB0aGlzLl90YWcgPSBudWxsOwogIGlmKG9wdGlvbnMuZGVjcnlwdCkgewogICAgLy8gc2F2ZSB0YWcgdG8gY2hlY2sgbGF0ZXIKICAgIHRoaXMuX3RhZyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKG9wdGlvbnMudGFnKS5nZXRCeXRlcygpOwogICAgaWYodGhpcy5fdGFnLmxlbmd0aCAhPT0gKHRoaXMuX3RhZ0xlbmd0aCAvIDgpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignQXV0aGVudGljYXRpb24gdGFnIGRvZXMgbm90IG1hdGNoIHRhZyBsZW5ndGguJyk7CiAgICB9CiAgfQoKICAvLyBjcmVhdGUgdG1wIHN0b3JhZ2UgZm9yIGhhc2ggY2FsY3VsYXRpb24KICB0aGlzLl9oYXNoQmxvY2sgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CgogIC8vIG5vIHRhZyBnZW5lcmF0ZWQgeWV0CiAgdGhpcy50YWcgPSBudWxsOwoKICAvLyBnZW5lcmF0ZSBoYXNoIHN1YmtleQogIC8vIChhcHBseSBibG9jayBjaXBoZXIgdG8gInplcm8iIGJsb2NrKQogIHRoaXMuX2hhc2hTdWJrZXkgPSBuZXcgQXJyYXkodGhpcy5faW50cyk7CiAgdGhpcy5jaXBoZXIuZW5jcnlwdChbMCwgMCwgMCwgMF0sIHRoaXMuX2hhc2hTdWJrZXkpOwoKICAvLyBnZW5lcmF0ZSB0YWJsZSBNCiAgLy8gdXNlIDQtYml0IHRhYmxlcyAoMzIgY29tcG9uZW50IGRlY29tcG9zaXRpb24gb2YgYSAxNiBieXRlIHZhbHVlKQogIC8vIDgtYml0IHRhYmxlcyB0YWtlIG1vcmUgc3BhY2UgYW5kIGFyZSBrbm93biB0byBoYXZlIHNlY3VyaXR5CiAgLy8gdnVsbmVyYWJpbGl0aWVzIChpbiBuYXRpdmUgaW1wbGVtZW50YXRpb25zKQogIHRoaXMuY29tcG9uZW50Qml0cyA9IDQ7CiAgdGhpcy5fbSA9IHRoaXMuZ2VuZXJhdGVIYXNoVGFibGUodGhpcy5faGFzaFN1YmtleSwgdGhpcy5jb21wb25lbnRCaXRzKTsKCiAgLy8gTm90ZTogc3VwcG9ydCBJViBsZW5ndGggZGlmZmVyZW50IGZyb20gOTYgYml0cz8gKG9ubHkgc3VwcG9ydGluZwogIC8vIDk2IGJpdHMgaXMgcmVjb21tZW5kZWQgYnkgTklTVCBTUC04MDAtMzhEKQogIC8vIGdlbmVyYXRlIEpfMAogIHZhciBpdkxlbmd0aCA9IGl2Lmxlbmd0aCgpOwogIGlmKGl2TGVuZ3RoID09PSAxMikgewogICAgLy8gOTYtYml0IElWCiAgICB0aGlzLl9qMCA9IFtpdi5nZXRJbnQzMigpLCBpdi5nZXRJbnQzMigpLCBpdi5nZXRJbnQzMigpLCAxXTsKICB9IGVsc2UgewogICAgLy8gSVYgaXMgTk9UIDk2LWJpdHMKICAgIHRoaXMuX2owID0gWzAsIDAsIDAsIDBdOwogICAgd2hpbGUoaXYubGVuZ3RoKCkgPiAwKSB7CiAgICAgIHRoaXMuX2owID0gdGhpcy5naGFzaCgKICAgICAgICB0aGlzLl9oYXNoU3Via2V5LCB0aGlzLl9qMCwKICAgICAgICBbaXYuZ2V0SW50MzIoKSwgaXYuZ2V0SW50MzIoKSwgaXYuZ2V0SW50MzIoKSwgaXYuZ2V0SW50MzIoKV0pOwogICAgfQogICAgdGhpcy5fajAgPSB0aGlzLmdoYXNoKAogICAgICB0aGlzLl9oYXNoU3Via2V5LCB0aGlzLl9qMCwgWzAsIDBdLmNvbmNhdChmcm9tNjRUbzMyKGl2TGVuZ3RoICogOCkpKTsKICB9CgogIC8vIGdlbmVyYXRlIElDQiAoaW5pdGlhbCBjb3VudGVyIGJsb2NrKQogIHRoaXMuX2luQmxvY2sgPSB0aGlzLl9qMC5zbGljZSgwKTsKICBpbmMzMih0aGlzLl9pbkJsb2NrKTsKICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSAwOwoKICAvLyBjb25zdW1lIGF1dGhlbnRpY2F0aW9uIGRhdGEKICBhZGRpdGlvbmFsRGF0YSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGFkZGl0aW9uYWxEYXRhKTsKICAvLyBzYXZlIGFkZGl0aW9uYWwgZGF0YSBsZW5ndGggYXMgYSBCRSA2NC1iaXQgbnVtYmVyCiAgdGhpcy5fYURhdGFMZW5ndGggPSBmcm9tNjRUbzMyKGFkZGl0aW9uYWxEYXRhLmxlbmd0aCgpICogOCk7CiAgLy8gcGFkIGFkZGl0aW9uYWwgZGF0YSB0byAxMjggYml0ICgxNiBieXRlKSBibG9jayBzaXplCiAgdmFyIG92ZXJmbG93ID0gYWRkaXRpb25hbERhdGEubGVuZ3RoKCkgJSB0aGlzLmJsb2NrU2l6ZTsKICBpZihvdmVyZmxvdykgewogICAgYWRkaXRpb25hbERhdGEuZmlsbFdpdGhCeXRlKDAsIHRoaXMuYmxvY2tTaXplIC0gb3ZlcmZsb3cpOwogIH0KICB0aGlzLl9zID0gWzAsIDAsIDAsIDBdOwogIHdoaWxlKGFkZGl0aW9uYWxEYXRhLmxlbmd0aCgpID4gMCkgewogICAgdGhpcy5fcyA9IHRoaXMuZ2hhc2godGhpcy5faGFzaFN1YmtleSwgdGhpcy5fcywgWwogICAgICBhZGRpdGlvbmFsRGF0YS5nZXRJbnQzMigpLAogICAgICBhZGRpdGlvbmFsRGF0YS5nZXRJbnQzMigpLAogICAgICBhZGRpdGlvbmFsRGF0YS5nZXRJbnQzMigpLAogICAgICBhZGRpdGlvbmFsRGF0YS5nZXRJbnQzMigpCiAgICBdKTsKICB9Cn07Cgptb2Rlcy5nY20ucHJvdG90eXBlLmVuY3J5cHQgPSBmdW5jdGlvbihpbnB1dCwgb3V0cHV0LCBmaW5pc2gpIHsKICAvLyBub3QgZW5vdWdoIGlucHV0IHRvIGVuY3J5cHQKICB2YXIgaW5wdXRMZW5ndGggPSBpbnB1dC5sZW5ndGgoKTsKICBpZihpbnB1dExlbmd0aCA9PT0gMCkgewogICAgcmV0dXJuIHRydWU7CiAgfQoKICAvLyBlbmNyeXB0IGJsb2NrCiAgdGhpcy5jaXBoZXIuZW5jcnlwdCh0aGlzLl9pbkJsb2NrLCB0aGlzLl9vdXRCbG9jayk7CgogIC8vIGhhbmRsZSBmdWxsIGJsb2NrCiAgaWYodGhpcy5fcGFydGlhbEJ5dGVzID09PSAwICYmIGlucHV0TGVuZ3RoID49IHRoaXMuYmxvY2tTaXplKSB7CiAgICAvLyBYT1IgaW5wdXQgd2l0aCBvdXRwdXQKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX291dEJsb2NrW2ldIF49IGlucHV0LmdldEludDMyKCkpOwogICAgfQogICAgdGhpcy5fY2lwaGVyTGVuZ3RoICs9IHRoaXMuYmxvY2tTaXplOwogIH0gZWxzZSB7CiAgICAvLyBoYW5kbGUgcGFydGlhbCBibG9jawogICAgdmFyIHBhcnRpYWxCeXRlcyA9ICh0aGlzLmJsb2NrU2l6ZSAtIGlucHV0TGVuZ3RoKSAlIHRoaXMuYmxvY2tTaXplOwogICAgaWYocGFydGlhbEJ5dGVzID4gMCkgewogICAgICBwYXJ0aWFsQnl0ZXMgPSB0aGlzLmJsb2NrU2l6ZSAtIHBhcnRpYWxCeXRlczsKICAgIH0KCiAgICAvLyBYT1IgaW5wdXQgd2l0aCBvdXRwdXQKICAgIHRoaXMuX3BhcnRpYWxPdXRwdXQuY2xlYXIoKTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgICAgdGhpcy5fcGFydGlhbE91dHB1dC5wdXRJbnQzMihpbnB1dC5nZXRJbnQzMigpIF4gdGhpcy5fb3V0QmxvY2tbaV0pOwogICAgfQoKICAgIGlmKHBhcnRpYWxCeXRlcyA9PT0gMCB8fCBmaW5pc2gpIHsKICAgICAgLy8gaGFuZGxlIG92ZXJmbG93IHByaW9yIHRvIGhhc2hpbmcKICAgICAgaWYoZmluaXNoKSB7CiAgICAgICAgLy8gZ2V0IGJsb2NrIG92ZXJmbG93CiAgICAgICAgdmFyIG92ZXJmbG93ID0gaW5wdXRMZW5ndGggJSB0aGlzLmJsb2NrU2l6ZTsKICAgICAgICB0aGlzLl9jaXBoZXJMZW5ndGggKz0gb3ZlcmZsb3c7CiAgICAgICAgLy8gdHJ1bmNhdGUgZm9yIGhhc2ggZnVuY3Rpb24KICAgICAgICB0aGlzLl9wYXJ0aWFsT3V0cHV0LnRydW5jYXRlKHRoaXMuYmxvY2tTaXplIC0gb3ZlcmZsb3cpOwogICAgICB9IGVsc2UgewogICAgICAgIHRoaXMuX2NpcGhlckxlbmd0aCArPSB0aGlzLmJsb2NrU2l6ZTsKICAgICAgfQoKICAgICAgLy8gZ2V0IG91dHB1dCBibG9jayBmb3IgaGFzaGluZwogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy5faW50czsgKytpKSB7CiAgICAgICAgdGhpcy5fb3V0QmxvY2tbaV0gPSB0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEludDMyKCk7CiAgICAgIH0KICAgICAgdGhpcy5fcGFydGlhbE91dHB1dC5yZWFkIC09IHRoaXMuYmxvY2tTaXplOwogICAgfQoKICAgIC8vIHNraXAgYW55IHByZXZpb3VzIHBhcnRpYWwgYnl0ZXMKICAgIGlmKHRoaXMuX3BhcnRpYWxCeXRlcyA+IDApIHsKICAgICAgdGhpcy5fcGFydGlhbE91dHB1dC5nZXRCeXRlcyh0aGlzLl9wYXJ0aWFsQnl0ZXMpOwogICAgfQoKICAgIGlmKHBhcnRpYWxCeXRlcyA+IDAgJiYgIWZpbmlzaCkgewogICAgICAvLyBibG9jayBzdGlsbCBpbmNvbXBsZXRlLCByZXN0b3JlIGlucHV0IGJ1ZmZlciwgZ2V0IHBhcnRpYWwgb3V0cHV0LAogICAgICAvLyBhbmQgcmV0dXJuIGVhcmx5CiAgICAgIGlucHV0LnJlYWQgLT0gdGhpcy5ibG9ja1NpemU7CiAgICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICAgIHBhcnRpYWxCeXRlcyAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgICB0aGlzLl9wYXJ0aWFsQnl0ZXMgPSBwYXJ0aWFsQnl0ZXM7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIG91dHB1dC5wdXRCeXRlcyh0aGlzLl9wYXJ0aWFsT3V0cHV0LmdldEJ5dGVzKAogICAgICBpbnB1dExlbmd0aCAtIHRoaXMuX3BhcnRpYWxCeXRlcykpOwogICAgdGhpcy5fcGFydGlhbEJ5dGVzID0gMDsKICB9CgogIC8vIHVwZGF0ZSBoYXNoIGJsb2NrIFMKICB0aGlzLl9zID0gdGhpcy5naGFzaCh0aGlzLl9oYXNoU3Via2V5LCB0aGlzLl9zLCB0aGlzLl9vdXRCbG9jayk7CgogIC8vIGluY3JlbWVudCBjb3VudGVyIChpbnB1dCBibG9jaykKICBpbmMzMih0aGlzLl9pbkJsb2NrKTsKfTsKCm1vZGVzLmdjbS5wcm90b3R5cGUuZGVjcnlwdCA9IGZ1bmN0aW9uKGlucHV0LCBvdXRwdXQsIGZpbmlzaCkgewogIC8vIG5vdCBlbm91Z2ggaW5wdXQgdG8gZGVjcnlwdAogIHZhciBpbnB1dExlbmd0aCA9IGlucHV0Lmxlbmd0aCgpOwogIGlmKGlucHV0TGVuZ3RoIDwgdGhpcy5ibG9ja1NpemUgJiYgIShmaW5pc2ggJiYgaW5wdXRMZW5ndGggPiAwKSkgewogICAgcmV0dXJuIHRydWU7CiAgfQoKICAvLyBlbmNyeXB0IGJsb2NrIChHQ00gYWx3YXlzIHVzZXMgZW5jcnlwdGlvbiBtb2RlKQogIHRoaXMuY2lwaGVyLmVuY3J5cHQodGhpcy5faW5CbG9jaywgdGhpcy5fb3V0QmxvY2spOwoKICAvLyBpbmNyZW1lbnQgY291bnRlciAoaW5wdXQgYmxvY2spCiAgaW5jMzIodGhpcy5faW5CbG9jayk7CgogIC8vIHVwZGF0ZSBoYXNoIGJsb2NrIFMKICB0aGlzLl9oYXNoQmxvY2tbMF0gPSBpbnB1dC5nZXRJbnQzMigpOwogIHRoaXMuX2hhc2hCbG9ja1sxXSA9IGlucHV0LmdldEludDMyKCk7CiAgdGhpcy5faGFzaEJsb2NrWzJdID0gaW5wdXQuZ2V0SW50MzIoKTsKICB0aGlzLl9oYXNoQmxvY2tbM10gPSBpbnB1dC5nZXRJbnQzMigpOwogIHRoaXMuX3MgPSB0aGlzLmdoYXNoKHRoaXMuX2hhc2hTdWJrZXksIHRoaXMuX3MsIHRoaXMuX2hhc2hCbG9jayk7CgogIC8vIFhPUiBoYXNoIGlucHV0IHdpdGggb3V0cHV0CiAgZm9yKHZhciBpID0gMDsgaSA8IHRoaXMuX2ludHM7ICsraSkgewogICAgb3V0cHV0LnB1dEludDMyKHRoaXMuX291dEJsb2NrW2ldIF4gdGhpcy5faGFzaEJsb2NrW2ldKTsKICB9CgogIC8vIGluY3JlbWVudCBjaXBoZXIgZGF0YSBsZW5ndGgKICBpZihpbnB1dExlbmd0aCA8IHRoaXMuYmxvY2tTaXplKSB7CiAgICB0aGlzLl9jaXBoZXJMZW5ndGggKz0gaW5wdXRMZW5ndGggJSB0aGlzLmJsb2NrU2l6ZTsKICB9IGVsc2UgewogICAgdGhpcy5fY2lwaGVyTGVuZ3RoICs9IHRoaXMuYmxvY2tTaXplOwogIH0KfTsKCm1vZGVzLmdjbS5wcm90b3R5cGUuYWZ0ZXJGaW5pc2ggPSBmdW5jdGlvbihvdXRwdXQsIG9wdGlvbnMpIHsKICB2YXIgcnZhbCA9IHRydWU7CgogIC8vIGhhbmRsZSBvdmVyZmxvdwogIGlmKG9wdGlvbnMuZGVjcnlwdCAmJiBvcHRpb25zLm92ZXJmbG93KSB7CiAgICBvdXRwdXQudHJ1bmNhdGUodGhpcy5ibG9ja1NpemUgLSBvcHRpb25zLm92ZXJmbG93KTsKICB9CgogIC8vIGhhbmRsZSBhdXRoZW50aWNhdGlvbiB0YWcKICB0aGlzLnRhZyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIGNvbmNhdGVuYXRlIGFkZGl0aW9uYWwgZGF0YSBsZW5ndGggd2l0aCBjaXBoZXIgbGVuZ3RoCiAgdmFyIGxlbmd0aHMgPSB0aGlzLl9hRGF0YUxlbmd0aC5jb25jYXQoZnJvbTY0VG8zMih0aGlzLl9jaXBoZXJMZW5ndGggKiA4KSk7CgogIC8vIGluY2x1ZGUgbGVuZ3RocyBpbiBoYXNoCiAgdGhpcy5fcyA9IHRoaXMuZ2hhc2godGhpcy5faGFzaFN1YmtleSwgdGhpcy5fcywgbGVuZ3Rocyk7CgogIC8vIGRvIEdDVFIoSl8wLCBTKQogIHZhciB0YWcgPSBbXTsKICB0aGlzLmNpcGhlci5lbmNyeXB0KHRoaXMuX2owLCB0YWcpOwogIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLl9pbnRzOyArK2kpIHsKICAgIHRoaXMudGFnLnB1dEludDMyKHRoaXMuX3NbaV0gXiB0YWdbaV0pOwogIH0KCiAgLy8gdHJpbSB0YWcgdG8gbGVuZ3RoCiAgdGhpcy50YWcudHJ1bmNhdGUodGhpcy50YWcubGVuZ3RoKCkgJSAodGhpcy5fdGFnTGVuZ3RoIC8gOCkpOwoKICAvLyBjaGVjayBhdXRoZW50aWNhdGlvbiB0YWcKICBpZihvcHRpb25zLmRlY3J5cHQgJiYgdGhpcy50YWcuYnl0ZXMoKSAhPT0gdGhpcy5fdGFnKSB7CiAgICBydmFsID0gZmFsc2U7CiAgfQoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBTZWUgTklTVCBTUC04MDAtMzhEIDYuMyAoQWxnb3JpdGhtIDEpLiBUaGlzIGZ1bmN0aW9uIHBlcmZvcm1zIEdhbG9pcwogKiBmaWVsZCBtdWx0aXBsaWNhdGlvbi4gVGhlIGZpZWxkLCBHRigyXjEyOCksIGlzIGRlZmluZWQgYnkgdGhlIHBvbHlub21pYWw6CiAqCiAqIHheMTI4ICsgeF43ICsgeF4yICsgeCArIDEKICoKICogV2hpY2ggaXMgcmVwcmVzZW50ZWQgaW4gbGl0dGxlLWVuZGlhbiBiaW5hcnkgZm9ybSBhczogMTExMDAwMDEgKDB4ZTEpLiBXaGVuCiAqIHRoZSB2YWx1ZSBvZiBhIGNvZWZmaWNpZW50IGlzIDEsIGEgYml0IGlzIHNldC4gVGhlIHZhbHVlIFIsIGlzIHRoZQogKiBjb25jYXRlbmF0aW9uIG9mIHRoaXMgdmFsdWUgYW5kIDEyMCB6ZXJvIGJpdHMsIHlpZWxkaW5nIGEgMTI4LWJpdCB2YWx1ZQogKiB3aGljaCBtYXRjaGVzIHRoZSBibG9jayBzaXplLgogKgogKiBUaGlzIGZ1bmN0aW9uIHdpbGwgbXVsdGlwbHkgdHdvIGVsZW1lbnRzICh2ZWN0b3JzIG9mIGJ5dGVzKSwgWCBhbmQgWSwgaW4KICogdGhlIGZpZWxkIEdGKDJeMTI4KS4gVGhlIHJlc3VsdCBpcyBpbml0aWFsaXplZCB0byB6ZXJvLiBGb3IgZWFjaCBiaXQgb2YKICogWCAob3V0IG9mIDEyOCksIHhfaSwgaWYgeF9pIGlzIHNldCwgdGhlbiB0aGUgcmVzdWx0IGlzIG11bHRpcGxpZWQgKFhPUidkKQogKiBieSB0aGUgY3VycmVudCB2YWx1ZSBvZiBZLiBGb3IgZWFjaCBiaXQsIHRoZSB2YWx1ZSBvZiBZIHdpbGwgYmUgcmFpc2VkIGJ5CiAqIGEgcG93ZXIgb2YgeCAobXVsdGlwbGllZCBieSB0aGUgcG9seW5vbWlhbCB4KS4gVGhpcyBjYW4gYmUgYWNoaWV2ZWQgYnkKICogc2hpZnRpbmcgWSBvbmNlIHRvIHRoZSByaWdodC4gSWYgdGhlIGN1cnJlbnQgdmFsdWUgb2YgWSwgcHJpb3IgdG8gYmVpbmcKICogbXVsdGlwbGllZCBieSB4LCBoYXMgMCBhcyBpdHMgTFNCLCB0aGVuIGl0IGlzIGEgMTI3dGggZGVncmVlIHBvbHlub21pYWwuCiAqIE90aGVyd2lzZSwgd2UgbXVzdCBkaXZpZGUgYnkgUiBhZnRlciBzaGlmdGluZyB0byBmaW5kIHRoZSByZW1haW5kZXIuCiAqCiAqIEBwYXJhbSB4IHRoZSBmaXJzdCBibG9jayB0byBtdWx0aXBseSBieSB0aGUgc2Vjb25kLgogKiBAcGFyYW0geSB0aGUgc2Vjb25kIGJsb2NrIHRvIG11bHRpcGx5IGJ5IHRoZSBmaXJzdC4KICoKICogQHJldHVybiB0aGUgYmxvY2sgcmVzdWx0IG9mIHRoZSBtdWx0aXBsaWNhdGlvbi4KICovCm1vZGVzLmdjbS5wcm90b3R5cGUubXVsdGlwbHkgPSBmdW5jdGlvbih4LCB5KSB7CiAgdmFyIHpfaSA9IFswLCAwLCAwLCAwXTsKICB2YXIgdl9pID0geS5zbGljZSgwKTsKCiAgLy8gY2FsY3VsYXRlIFpfMTI4IChibG9jayBoYXMgMTI4IGJpdHMpCiAgZm9yKHZhciBpID0gMDsgaSA8IDEyODsgKytpKSB7CiAgICAvLyBpZiB4X2kgaXMgMCwgWl97aSsxfSA9IFpfaSAodW5jaGFuZ2VkKQogICAgLy8gZWxzZSBaX3tpKzF9ID0gWl9pIF4gVl9pCiAgICAvLyBnZXQgeF9pIGJ5IGZpbmRpbmcgMzItYml0IGludCBwb3NpdGlvbiwgdGhlbiBsZWZ0IHNoaWZ0IDEgYnkgcmVtYWluZGVyCiAgICB2YXIgeF9pID0geFsoaSAvIDMyKSB8IDBdICYgKDEgPDwgKDMxIC0gaSAlIDMyKSk7CiAgICBpZih4X2kpIHsKICAgICAgel9pWzBdIF49IHZfaVswXTsKICAgICAgel9pWzFdIF49IHZfaVsxXTsKICAgICAgel9pWzJdIF49IHZfaVsyXTsKICAgICAgel9pWzNdIF49IHZfaVszXTsKICAgIH0KCiAgICAvLyBpZiBMU0IoVl9pKSBpcyAxLCBWX2kgPSBWX2kgPj4gMQogICAgLy8gZWxzZSBWX2kgPSAoVl9pID4+IDEpIF4gUgogICAgdGhpcy5wb3codl9pLCB2X2kpOwogIH0KCiAgcmV0dXJuIHpfaTsKfTsKCm1vZGVzLmdjbS5wcm90b3R5cGUucG93ID0gZnVuY3Rpb24oeCwgb3V0KSB7CiAgLy8gaWYgTFNCKHgpIGlzIDEsIHggPSB4ID4+PiAxCiAgLy8gZWxzZSB4ID0gKHggPj4+IDEpIF4gUgogIHZhciBsc2IgPSB4WzNdICYgMTsKCiAgLy8gYWx3YXlzIGRvIHggPj4+IDE6CiAgLy8gc3RhcnRpbmcgd2l0aCB0aGUgcmlnaHRtb3N0IGludGVnZXIsIHNoaWZ0IGVhY2ggaW50ZWdlciB0byB0aGUgcmlnaHQKICAvLyBvbmUgYml0LCBwdWxsaW5nIGluIHRoZSBiaXQgZnJvbSB0aGUgaW50ZWdlciB0byB0aGUgbGVmdCBhcyBpdHMgdG9wCiAgLy8gbW9zdCBiaXQgKGRvIHRoaXMgZm9yIHRoZSBsYXN0IDMgaW50ZWdlcnMpCiAgZm9yKHZhciBpID0gMzsgaSA+IDA7IC0taSkgewogICAgb3V0W2ldID0gKHhbaV0gPj4+IDEpIHwgKCh4W2kgLSAxXSAmIDEpIDw8IDMxKTsKICB9CiAgLy8gc2hpZnQgdGhlIGZpcnN0IGludGVnZXIgbm9ybWFsbHkKICBvdXRbMF0gPSB4WzBdID4+PiAxOwoKICAvLyBpZiBsc2Igd2FzIG5vdCBzZXQsIHRoZW4gcG9seW5vbWlhbCBoYWQgYSBkZWdyZWUgb2YgMTI3IGFuZCBkb2Vzbid0CiAgLy8gbmVlZCB0byBkaXZpZGVkOyBvdGhlcndpc2UsIFhPUiB3aXRoIFIgdG8gZmluZCB0aGUgcmVtYWluZGVyOyB3ZSBvbmx5CiAgLy8gbmVlZCB0byBYT1IgdGhlIGZpcnN0IGludGVnZXIgc2luY2UgUiB0ZWNobmljYWxseSBlbmRzIHcvMTIwIHplcm8gYml0cwogIGlmKGxzYikgewogICAgb3V0WzBdIF49IHRoaXMuX1I7CiAgfQp9OwoKbW9kZXMuZ2NtLnByb3RvdHlwZS50YWJsZU11bHRpcGx5ID0gZnVuY3Rpb24oeCkgewogIC8vIGFzc3VtZXMgNC1iaXQgdGFibGVzIGFyZSB1c2VkCiAgdmFyIHogPSBbMCwgMCwgMCwgMF07CiAgZm9yKHZhciBpID0gMDsgaSA8IDMyOyArK2kpIHsKICAgIHZhciBpZHggPSAoaSAvIDgpIHwgMDsKICAgIHZhciB4X2kgPSAoeFtpZHhdID4+PiAoKDcgLSAoaSAlIDgpKSAqIDQpKSAmIDB4RjsKICAgIHZhciBhaCA9IHRoaXMuX21baV1beF9pXTsKICAgIHpbMF0gXj0gYWhbMF07CiAgICB6WzFdIF49IGFoWzFdOwogICAgelsyXSBePSBhaFsyXTsKICAgIHpbM10gXj0gYWhbM107CiAgfQogIHJldHVybiB6Owp9OwoKLyoqCiAqIEEgY29udGludWluZyB2ZXJzaW9uIG9mIHRoZSBHSEFTSCBhbGdvcml0aG0gdGhhdCBvcGVyYXRlcyBvbiBhIHNpbmdsZQogKiBibG9jay4gVGhlIGhhc2ggYmxvY2ssIGxhc3QgaGFzaCB2YWx1ZSAoWW0pIGFuZCB0aGUgbmV3IGJsb2NrIHRvIGhhc2gKICogYXJlIGdpdmVuLgogKgogKiBAcGFyYW0gaCB0aGUgaGFzaCBibG9jay4KICogQHBhcmFtIHkgdGhlIHByZXZpb3VzIHZhbHVlIGZvciBZbSwgdXNlIFswLCAwLCAwLCAwXSBmb3IgYSBuZXcgaGFzaC4KICogQHBhcmFtIHggdGhlIGJsb2NrIHRvIGhhc2guCiAqCiAqIEByZXR1cm4gdGhlIGhhc2hlZCB2YWx1ZSAoWW0pLgogKi8KbW9kZXMuZ2NtLnByb3RvdHlwZS5naGFzaCA9IGZ1bmN0aW9uKGgsIHksIHgpIHsKICB5WzBdIF49IHhbMF07CiAgeVsxXSBePSB4WzFdOwogIHlbMl0gXj0geFsyXTsKICB5WzNdIF49IHhbM107CiAgcmV0dXJuIHRoaXMudGFibGVNdWx0aXBseSh5KTsKICAvL3JldHVybiB0aGlzLm11bHRpcGx5KHksIGgpOwp9OwoKLyoqCiAqIFByZWNvbXB1dGVzIGEgdGFibGUgZm9yIG11bHRpcGx5aW5nIGFnYWluc3QgdGhlIGhhc2ggc3Via2V5LiBUaGlzCiAqIG1lY2hhbmlzbSBwcm92aWRlcyBhIHN1YnN0YW50aWFsIHNwZWVkIGluY3JlYXNlIG92ZXIgbXVsdGlwbGljYXRpb24KICogcGVyZm9ybWVkIHdpdGhvdXQgYSB0YWJsZS4gVGhlIHRhYmxlLWJhc2VkIG11bHRpcGxpY2F0aW9uIHRoaXMgdGFibGUgaXMKICogZm9yIHNvbHZlcyBYICogSCBieSBtdWx0aXBseWluZyBlYWNoIGNvbXBvbmVudCBvZiBYIGJ5IEggYW5kIHRoZW4KICogY29tcG9zaW5nIHRoZSByZXN1bHRzIHRvZ2V0aGVyIHVzaW5nIFhPUi4KICoKICogVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBnZW5lcmF0ZSB0YWJsZXMgd2l0aCBkaWZmZXJlbnQgYml0IHNpemVzCiAqIGZvciB0aGUgY29tcG9uZW50cywgaG93ZXZlciwgdGhpcyBpbXBsZW1lbnRhdGlvbiBhc3N1bWVzIHRoZXJlIGFyZQogKiAzMiBjb21wb25lbnRzIG9mIFggKHdoaWNoIGlzIGEgMTYgYnl0ZSB2ZWN0b3IpLCB0aGVyZWZvcmUgZWFjaCBjb21wb25lbnQKICogdGFrZXMgNC1iaXRzIChzbyB0aGUgdGFibGUgaXMgY29uc3RydWN0ZWQgd2l0aCBiaXRzPTQpLgogKgogKiBAcGFyYW0gaCB0aGUgaGFzaCBzdWJrZXkuCiAqIEBwYXJhbSBiaXRzIHRoZSBiaXQgc2l6ZSBmb3IgYSBjb21wb25lbnQuCiAqLwptb2Rlcy5nY20ucHJvdG90eXBlLmdlbmVyYXRlSGFzaFRhYmxlID0gZnVuY3Rpb24oaCwgYml0cykgewogIC8vIFRPRE86IFRoZXJlIGFyZSBmdXJ0aGVyIG9wdGltaXphdGlvbnMgdGhhdCB3b3VsZCB1c2Ugb25seSB0aGUKICAvLyBmaXJzdCB0YWJsZSBNXzAgKG9yIHNvbWUgdmFyaWFudCkgYWxvbmcgd2l0aCBhIHJlbWFpbmRlciB0YWJsZTsKICAvLyB0aGlzIGNhbiBiZSBleHBsb3JlZCBpbiB0aGUgZnV0dXJlCiAgdmFyIG11bHRpcGxpZXIgPSA4IC8gYml0czsKICB2YXIgcGVySW50ID0gNCAqIG11bHRpcGxpZXI7CiAgdmFyIHNpemUgPSAxNiAqIG11bHRpcGxpZXI7CiAgdmFyIG0gPSBuZXcgQXJyYXkoc2l6ZSk7CiAgZm9yKHZhciBpID0gMDsgaSA8IHNpemU7ICsraSkgewogICAgdmFyIHRtcCA9IFswLCAwLCAwLCAwXTsKICAgIHZhciBpZHggPSAoaSAvIHBlckludCkgfCAwOwogICAgdmFyIHNoZnQgPSAoKHBlckludCAtIDEgLSAoaSAlIHBlckludCkpICogYml0cyk7CiAgICB0bXBbaWR4XSA9ICgxIDw8IChiaXRzIC0gMSkpIDw8IHNoZnQ7CiAgICBtW2ldID0gdGhpcy5nZW5lcmF0ZVN1Ykhhc2hUYWJsZSh0aGlzLm11bHRpcGx5KHRtcCwgaCksIGJpdHMpOwogIH0KICByZXR1cm4gbTsKfTsKCi8qKgogKiBHZW5lcmF0ZXMgYSB0YWJsZSBmb3IgbXVsdGlwbHlpbmcgYWdhaW5zdCB0aGUgaGFzaCBzdWJrZXkgZm9yIG9uZQogKiBwYXJ0aWN1bGFyIGNvbXBvbmVudCAob3V0IG9mIGFsbCBwb3NzaWJsZSBjb21wb25lbnQgdmFsdWVzKS4KICoKICogQHBhcmFtIG1pZCB0aGUgcHJlLW11bHRpcGxpZWQgdmFsdWUgZm9yIHRoZSBtaWRkbGUga2V5IG9mIHRoZSB0YWJsZS4KICogQHBhcmFtIGJpdHMgdGhlIGJpdCBzaXplIGZvciBhIGNvbXBvbmVudC4KICovCm1vZGVzLmdjbS5wcm90b3R5cGUuZ2VuZXJhdGVTdWJIYXNoVGFibGUgPSBmdW5jdGlvbihtaWQsIGJpdHMpIHsKICAvLyBjb21wdXRlIHRoZSB0YWJsZSBxdWlja2x5IGJ5IG1pbmltaXppbmcgdGhlIG51bWJlciBvZgogIC8vIFBPVyBvcGVyYXRpb25zIC0tIHRoZXkgb25seSBuZWVkIHRvIGJlIHBlcmZvcm1lZCBmb3IgcG93ZXJzIG9mIDIsCiAgLy8gYWxsIG90aGVyIGVudHJpZXMgY2FuIGJlIGNvbXBvc2VkIGZyb20gdGhvc2UgcG93ZXJzIHVzaW5nIFhPUgogIHZhciBzaXplID0gMSA8PCBiaXRzOwogIHZhciBoYWxmID0gc2l6ZSA+Pj4gMTsKICB2YXIgbSA9IG5ldyBBcnJheShzaXplKTsKICBtW2hhbGZdID0gbWlkLnNsaWNlKDApOwogIHZhciBpID0gaGFsZiA+Pj4gMTsKICB3aGlsZShpID4gMCkgewogICAgLy8gcmFpc2UgbTBbMiAqIGldIGFuZCBzdG9yZSBpbiBtMFtpXQogICAgdGhpcy5wb3cobVsyICogaV0sIG1baV0gPSBbXSk7CiAgICBpID4+PSAxOwogIH0KICBpID0gMjsKICB3aGlsZShpIDwgaGFsZikgewogICAgZm9yKHZhciBqID0gMTsgaiA8IGk7ICsraikgewogICAgICB2YXIgbV9pID0gbVtpXTsKICAgICAgdmFyIG1faiA9IG1bal07CiAgICAgIG1baSArIGpdID0gWwogICAgICAgIG1faVswXSBeIG1falswXSwKICAgICAgICBtX2lbMV0gXiBtX2pbMV0sCiAgICAgICAgbV9pWzJdIF4gbV9qWzJdLAogICAgICAgIG1faVszXSBeIG1falszXQogICAgICBdOwogICAgfQogICAgaSAqPSAyOwogIH0KICBtWzBdID0gWzAsIDAsIDAsIDBdOwogIC8qIE5vdGU6IFdlIGNvdWxkIGF2b2lkIHN0b3JpbmcgdGhlc2UgYnkgZG9pbmcgY29tcG9zaXRpb24gZHVyaW5nIG11bHRpcGx5CiAgY2FsY3VsYXRlIHRvcCBoYWxmIHVzaW5nIGNvbXBvc2l0aW9uIGJ5IHNwZWVkIGlzIHByZWZlcnJlZC4gKi8KICBmb3IoaSA9IGhhbGYgKyAxOyBpIDwgc2l6ZTsgKytpKSB7CiAgICB2YXIgYyA9IG1baSBeIGhhbGZdOwogICAgbVtpXSA9IFttaWRbMF0gXiBjWzBdLCBtaWRbMV0gXiBjWzFdLCBtaWRbMl0gXiBjWzJdLCBtaWRbM10gXiBjWzNdXTsKICB9CiAgcmV0dXJuIG07Cn07CgoKLyoqIFV0aWxpdHkgZnVuY3Rpb25zICovCgpmdW5jdGlvbiB0cmFuc2Zvcm1JVihpdikgewogIGlmKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHsKICAgIC8vIGNvbnZlcnQgaXYgc3RyaW5nIGludG8gYnl0ZSBidWZmZXIKICAgIGl2ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoaXYpOwogIH0KCiAgaWYoZm9yZ2UudXRpbC5pc0FycmF5KGl2KSAmJiBpdi5sZW5ndGggPiA0KSB7CiAgICAvLyBjb252ZXJ0IGl2IGJ5dGUgYXJyYXkgaW50byBieXRlIGJ1ZmZlcgogICAgdmFyIHRtcCA9IGl2OwogICAgaXYgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgZm9yKHZhciBpID0gMDsgaSA8IHRtcC5sZW5ndGg7ICsraSkgewogICAgICBpdi5wdXRCeXRlKHRtcFtpXSk7CiAgICB9CiAgfQogIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkoaXYpKSB7CiAgICAvLyBjb252ZXJ0IGl2IGJ5dGUgYnVmZmVyIGludG8gMzItYml0IGludGVnZXIgYXJyYXkKICAgIGl2ID0gW2l2LmdldEludDMyKCksIGl2LmdldEludDMyKCksIGl2LmdldEludDMyKCksIGl2LmdldEludDMyKCldOwogIH0KCiAgcmV0dXJuIGl2Owp9CgpmdW5jdGlvbiBpbmMzMihibG9jaykgewogIC8vIGluY3JlbWVudCBsYXN0IDMyIGJpdHMgb2YgYmxvY2sgb25seQogIGJsb2NrW2Jsb2NrLmxlbmd0aCAtIDFdID0gKGJsb2NrW2Jsb2NrLmxlbmd0aCAtIDFdICsgMSkgJiAweEZGRkZGRkZGOwp9CgpmdW5jdGlvbiBmcm9tNjRUbzMyKG51bSkgewogIC8vIGNvbnZlcnQgNjQtYml0IG51bWJlciB0byB0d28gQkUgSW50MzJzCiAgcmV0dXJuIFsobnVtIC8gMHgxMDAwMDAwMDApIHwgMCwgbnVtICYgMHhGRkZGRkZGRl07Cn0KCgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdjaXBoZXJNb2Rlcyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9jaXBoZXJNb2RlcycsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogQWR2YW5jZWQgRW5jcnlwdGlvbiBTdGFuZGFyZCAoQUVTKSBpbXBsZW1lbnRhdGlvbi4KICoKICogVGhpcyBpbXBsZW1lbnRhdGlvbiBpcyBiYXNlZCBvbiB0aGUgcHVibGljIGRvbWFpbiBsaWJyYXJ5ICdqc2NyeXB0bycgd2hpY2gKICogd2FzIHdyaXR0ZW4gYnk6CiAqCiAqIEVtaWx5IFN0YXJrIChlc3RhcmtAc3RhbmZvcmQuZWR1KQogKiBNaWtlIEhhbWJ1cmcgKG1oYW1idXJnQHN0YW5mb3JkLmVkdSkKICogRGFuIEJvbmVoIChkYWJvQGNzLnN0YW5mb3JkLmVkdSkKICoKICogUGFydHMgb2YgdGhpcyBjb2RlIGFyZSBiYXNlZCBvbiB0aGUgT3BlblNTTCBpbXBsZW1lbnRhdGlvbiBvZiBBRVM6CiAqIGh0dHA6Ly93d3cub3BlbnNzbC5vcmcKICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovKiBBRVMgQVBJICovCmZvcmdlLmFlcyA9IGZvcmdlLmFlcyB8fCB7fTsKCi8qKgogKiBEZXByZWNhdGVkLiBJbnN0ZWFkLCB1c2U6CiAqCiAqIHZhciBjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKCdBRVMtPG1vZGU+Jywga2V5KTsKICogY2lwaGVyLnN0YXJ0KHtpdjogaXZ9KTsKICoKICogQ3JlYXRlcyBhbiBBRVMgY2lwaGVyIG9iamVjdCB0byBlbmNyeXB0IGRhdGEgdXNpbmcgdGhlIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqIFRoZSBvdXRwdXQgd2lsbCBiZSBzdG9yZWQgaW4gdGhlICdvdXRwdXQnIG1lbWJlciBvZiB0aGUgcmV0dXJuZWQgY2lwaGVyLgogKgogKiBUaGUga2V5IGFuZCBpdiBtYXkgYmUgZ2l2ZW4gYXMgYSBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5IG9mIGJ5dGVzLAogKiBhIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UuCiAqIEBwYXJhbSBvdXRwdXQgdGhlIGJ1ZmZlciB0byB3cml0ZSB0bywgbnVsbCB0byBjcmVhdGUgb25lLgogKiBAcGFyYW0gbW9kZSB0aGUgY2lwaGVyIG1vZGUgdG8gdXNlIChkZWZhdWx0OiAnQ0JDJykuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmFlcy5zdGFydEVuY3J5cHRpbmcgPSBmdW5jdGlvbihrZXksIGl2LCBvdXRwdXQsIG1vZGUpIHsKICB2YXIgY2lwaGVyID0gX2NyZWF0ZUNpcGhlcih7CiAgICBrZXk6IGtleSwKICAgIG91dHB1dDogb3V0cHV0LAogICAgZGVjcnlwdDogZmFsc2UsCiAgICBtb2RlOiBtb2RlCiAgfSk7CiAgY2lwaGVyLnN0YXJ0KGl2KTsKICByZXR1cm4gY2lwaGVyOwp9OwoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogdmFyIGNpcGhlciA9IGZvcmdlLmNpcGhlci5jcmVhdGVDaXBoZXIoJ0FFUy08bW9kZT4nLCBrZXkpOwogKgogKiBDcmVhdGVzIGFuIEFFUyBjaXBoZXIgb2JqZWN0IHRvIGVuY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gc3ltbWV0cmljIGtleS4KICoKICogVGhlIGtleSBtYXkgYmUgZ2l2ZW4gYXMgYSBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5IG9mIGJ5dGVzLCBhCiAqIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gbW9kZSB0aGUgY2lwaGVyIG1vZGUgdG8gdXNlIChkZWZhdWx0OiAnQ0JDJykuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyID0gZnVuY3Rpb24oa2V5LCBtb2RlKSB7CiAgcmV0dXJuIF9jcmVhdGVDaXBoZXIoewogICAga2V5OiBrZXksCiAgICBvdXRwdXQ6IG51bGwsCiAgICBkZWNyeXB0OiBmYWxzZSwKICAgIG1vZGU6IG1vZGUKICB9KTsKfTsKCi8qKgogKiBEZXByZWNhdGVkLiBJbnN0ZWFkLCB1c2U6CiAqCiAqIHZhciBkZWNpcGhlciA9IGZvcmdlLmNpcGhlci5jcmVhdGVEZWNpcGhlcignQUVTLTxtb2RlPicsIGtleSk7CiAqIGRlY2lwaGVyLnN0YXJ0KHtpdjogaXZ9KTsKICoKICogQ3JlYXRlcyBhbiBBRVMgY2lwaGVyIG9iamVjdCB0byBkZWNyeXB0IGRhdGEgdXNpbmcgdGhlIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqIFRoZSBvdXRwdXQgd2lsbCBiZSBzdG9yZWQgaW4gdGhlICdvdXRwdXQnIG1lbWJlciBvZiB0aGUgcmV0dXJuZWQgY2lwaGVyLgogKgogKiBUaGUga2V5IGFuZCBpdiBtYXkgYmUgZ2l2ZW4gYXMgYSBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5IG9mIGJ5dGVzLAogKiBhIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UuCiAqIEBwYXJhbSBvdXRwdXQgdGhlIGJ1ZmZlciB0byB3cml0ZSB0bywgbnVsbCB0byBjcmVhdGUgb25lLgogKiBAcGFyYW0gbW9kZSB0aGUgY2lwaGVyIG1vZGUgdG8gdXNlIChkZWZhdWx0OiAnQ0JDJykuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmFlcy5zdGFydERlY3J5cHRpbmcgPSBmdW5jdGlvbihrZXksIGl2LCBvdXRwdXQsIG1vZGUpIHsKICB2YXIgY2lwaGVyID0gX2NyZWF0ZUNpcGhlcih7CiAgICBrZXk6IGtleSwKICAgIG91dHB1dDogb3V0cHV0LAogICAgZGVjcnlwdDogdHJ1ZSwKICAgIG1vZGU6IG1vZGUKICB9KTsKICBjaXBoZXIuc3RhcnQoaXYpOwogIHJldHVybiBjaXBoZXI7Cn07CgovKioKICogRGVwcmVjYXRlZC4gSW5zdGVhZCwgdXNlOgogKgogKiB2YXIgZGVjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlRGVjaXBoZXIoJ0FFUy08bW9kZT4nLCBrZXkpOwogKgogKiBDcmVhdGVzIGFuIEFFUyBjaXBoZXIgb2JqZWN0IHRvIGRlY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gc3ltbWV0cmljIGtleS4KICoKICogVGhlIGtleSBtYXkgYmUgZ2l2ZW4gYXMgYSBzdHJpbmcgb2YgYnl0ZXMsIGFuIGFycmF5IG9mIGJ5dGVzLCBhCiAqIGJ5dGUgYnVmZmVyLCBvciBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gbW9kZSB0aGUgY2lwaGVyIG1vZGUgdG8gdXNlIChkZWZhdWx0OiAnQ0JDJykuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLmFlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyID0gZnVuY3Rpb24oa2V5LCBtb2RlKSB7CiAgcmV0dXJuIF9jcmVhdGVDaXBoZXIoewogICAga2V5OiBrZXksCiAgICBvdXRwdXQ6IG51bGwsCiAgICBkZWNyeXB0OiB0cnVlLAogICAgbW9kZTogbW9kZQogIH0pOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgQUVTIGNpcGhlciBhbGdvcml0aG0gb2JqZWN0LgogKgogKiBAcGFyYW0gbmFtZSB0aGUgbmFtZSBvZiB0aGUgYWxnb3JpdGhtLgogKiBAcGFyYW0gbW9kZSB0aGUgbW9kZSBmYWN0b3J5IGZ1bmN0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBBRVMgYWxnb3JpdGhtIG9iamVjdC4KICovCmZvcmdlLmFlcy5BbGdvcml0aG0gPSBmdW5jdGlvbihuYW1lLCBtb2RlKSB7CiAgaWYoIWluaXQpIHsKICAgIGluaXRpYWxpemUoKTsKICB9CiAgdmFyIHNlbGYgPSB0aGlzOwogIHNlbGYubmFtZSA9IG5hbWU7CiAgc2VsZi5tb2RlID0gbmV3IG1vZGUoewogICAgYmxvY2tTaXplOiAxNiwKICAgIGNpcGhlcjogewogICAgICBlbmNyeXB0OiBmdW5jdGlvbihpbkJsb2NrLCBvdXRCbG9jaykgewogICAgICAgIHJldHVybiBfdXBkYXRlQmxvY2soc2VsZi5fdywgaW5CbG9jaywgb3V0QmxvY2ssIGZhbHNlKTsKICAgICAgfSwKICAgICAgZGVjcnlwdDogZnVuY3Rpb24oaW5CbG9jaywgb3V0QmxvY2spIHsKICAgICAgICByZXR1cm4gX3VwZGF0ZUJsb2NrKHNlbGYuX3csIGluQmxvY2ssIG91dEJsb2NrLCB0cnVlKTsKICAgICAgfQogICAgfQogIH0pOwogIHNlbGYuX2luaXQgPSBmYWxzZTsKfTsKCi8qKgogKiBJbml0aWFsaXplcyB0aGlzIEFFUyBhbGdvcml0aG0gYnkgZXhwYW5kaW5nIGl0cyBrZXkuCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZS4KICogICAgICAgICAga2V5IHRoZSBrZXkgdG8gdXNlIHdpdGggdGhpcyBhbGdvcml0aG0uCiAqICAgICAgICAgIGRlY3J5cHQgdHJ1ZSBpZiB0aGUgYWxnb3JpdGhtIHNob3VsZCBiZSBpbml0aWFsaXplZCBmb3IgZGVjcnlwdGlvbiwKICogICAgICAgICAgICBmYWxzZSBmb3IgZW5jcnlwdGlvbi4KICovCmZvcmdlLmFlcy5BbGdvcml0aG0ucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgaWYodGhpcy5faW5pdCkgewogICAgcmV0dXJuOwogIH0KCiAgdmFyIGtleSA9IG9wdGlvbnMua2V5OwogIHZhciB0bXA7CgogIC8qIE5vdGU6IFRoZSBrZXkgbWF5IGJlIGEgc3RyaW5nIG9mIGJ5dGVzLCBhbiBhcnJheSBvZiBieXRlcywgYSBieXRlCiAgICBidWZmZXIsIG9yIGFuIGFycmF5IG9mIDMyLWJpdCBpbnRlZ2Vycy4gSWYgdGhlIGtleSBpcyBpbiBieXRlcywgdGhlbgogICAgaXQgbXVzdCBiZSAxNiwgMjQsIG9yIDMyIGJ5dGVzIGluIGxlbmd0aC4gSWYgaXQgaXMgaW4gMzItYml0CiAgICBpbnRlZ2VycywgaXQgbXVzdCBiZSA0LCA2LCBvciA4IGludGVnZXJzIGxvbmcuICovCgogIGlmKHR5cGVvZiBrZXkgPT09ICdzdHJpbmcnICYmCiAgICAoa2V5Lmxlbmd0aCA9PT0gMTYgfHwga2V5Lmxlbmd0aCA9PT0gMjQgfHwga2V5Lmxlbmd0aCA9PT0gMzIpKSB7CiAgICAvLyBjb252ZXJ0IGtleSBzdHJpbmcgaW50byBieXRlIGJ1ZmZlcgogICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoa2V5KTsKICB9IGVsc2UgaWYoZm9yZ2UudXRpbC5pc0FycmF5KGtleSkgJiYKICAgIChrZXkubGVuZ3RoID09PSAxNiB8fCBrZXkubGVuZ3RoID09PSAyNCB8fCBrZXkubGVuZ3RoID09PSAzMikpIHsKICAgIC8vIGNvbnZlcnQga2V5IGludGVnZXIgYXJyYXkgaW50byBieXRlIGJ1ZmZlcgogICAgdG1wID0ga2V5OwogICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCB0bXAubGVuZ3RoOyArK2kpIHsKICAgICAga2V5LnB1dEJ5dGUodG1wW2ldKTsKICAgIH0KICB9CgogIC8vIGNvbnZlcnQga2V5IGJ5dGUgYnVmZmVyIGludG8gMzItYml0IGludGVnZXIgYXJyYXkKICBpZighZm9yZ2UudXRpbC5pc0FycmF5KGtleSkpIHsKICAgIHRtcCA9IGtleTsKICAgIGtleSA9IFtdOwoKICAgIC8vIGtleSBsZW5ndGhzIG9mIDE2LCAyNCwgMzIgYnl0ZXMgYWxsb3dlZAogICAgdmFyIGxlbiA9IHRtcC5sZW5ndGgoKTsKICAgIGlmKGxlbiA9PT0gMTYgfHwgbGVuID09PSAyNCB8fCBsZW4gPT09IDMyKSB7CiAgICAgIGxlbiA9IGxlbiA+Pj4gMjsKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGxlbjsgKytpKSB7CiAgICAgICAga2V5LnB1c2godG1wLmdldEludDMyKCkpOwogICAgICB9CiAgICB9CiAgfQoKICAvLyBrZXkgbXVzdCBiZSBhbiBhcnJheSBvZiAzMi1iaXQgaW50ZWdlcnMgYnkgbm93CiAgaWYoIWZvcmdlLnV0aWwuaXNBcnJheShrZXkpIHx8CiAgICAhKGtleS5sZW5ndGggPT09IDQgfHwga2V5Lmxlbmd0aCA9PT0gNiB8fCBrZXkubGVuZ3RoID09PSA4KSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGtleSBwYXJhbWV0ZXIuJyk7CiAgfQoKICAvLyBlbmNyeXB0aW9uIG9wZXJhdGlvbiBpcyBhbHdheXMgdXNlZCBmb3IgdGhlc2UgbW9kZXMKICB2YXIgbW9kZSA9IHRoaXMubW9kZS5uYW1lOwogIHZhciBlbmNyeXB0T3AgPSAoWydDRkInLCAnT0ZCJywgJ0NUUicsICdHQ00nXS5pbmRleE9mKG1vZGUpICE9PSAtMSk7CgogIC8vIGRvIGtleSBleHBhbnNpb24KICB0aGlzLl93ID0gX2V4cGFuZEtleShrZXksIG9wdGlvbnMuZGVjcnlwdCAmJiAhZW5jcnlwdE9wKTsKICB0aGlzLl9pbml0ID0gdHJ1ZTsKfTsKCi8qKgogKiBFeHBhbmRzIGEga2V5LiBUeXBpY2FsbHkgb25seSB1c2VkIGZvciB0ZXN0aW5nLgogKgogKiBAcGFyYW0ga2V5IHRoZSBzeW1tZXRyaWMga2V5IHRvIGV4cGFuZCwgYXMgYW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLgogKiBAcGFyYW0gZGVjcnlwdCB0cnVlIHRvIGV4cGFuZCBmb3IgZGVjcnlwdGlvbiwgZmFsc2UgZm9yIGVuY3J5cHRpb24uCiAqCiAqIEByZXR1cm4gdGhlIGV4cGFuZGVkIGtleS4KICovCmZvcmdlLmFlcy5fZXhwYW5kS2V5ID0gZnVuY3Rpb24oa2V5LCBkZWNyeXB0KSB7CiAgaWYoIWluaXQpIHsKICAgIGluaXRpYWxpemUoKTsKICB9CiAgcmV0dXJuIF9leHBhbmRLZXkoa2V5LCBkZWNyeXB0KTsKfTsKCi8qKgogKiBVcGRhdGVzIGEgc2luZ2xlIGJsb2NrLiBUeXBpY2FsbHkgb25seSB1c2VkIGZvciB0ZXN0aW5nLgogKgogKiBAcGFyYW0gdyB0aGUgZXhwYW5kZWQga2V5IHRvIHVzZS4KICogQHBhcmFtIGlucHV0IGFuIGFycmF5IG9mIGJsb2NrLXNpemUgMzItYml0IHdvcmRzLgogKiBAcGFyYW0gb3V0cHV0IGFuIGFycmF5IG9mIGJsb2NrLXNpemUgMzItYml0IHdvcmRzLgogKiBAcGFyYW0gZGVjcnlwdCB0cnVlIHRvIGRlY3J5cHQsIGZhbHNlIHRvIGVuY3J5cHQuCiAqLwpmb3JnZS5hZXMuX3VwZGF0ZUJsb2NrID0gX3VwZGF0ZUJsb2NrOwoKCi8qKiBSZWdpc3RlciBBRVMgYWxnb3JpdGhtcyAqKi8KCnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtRUNCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmVjYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtQ0JDJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmNiYyk7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtQ0ZCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmNmYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtT0ZCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLm9mYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtQ1RSJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmN0cik7CnJlZ2lzdGVyQWxnb3JpdGhtKCdBRVMtR0NNJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmdjbSk7CgpmdW5jdGlvbiByZWdpc3RlckFsZ29yaXRobShuYW1lLCBtb2RlKSB7CiAgdmFyIGZhY3RvcnkgPSBmdW5jdGlvbigpIHsKICAgIHJldHVybiBuZXcgZm9yZ2UuYWVzLkFsZ29yaXRobShuYW1lLCBtb2RlKTsKICB9OwogIGZvcmdlLmNpcGhlci5yZWdpc3RlckFsZ29yaXRobShuYW1lLCBmYWN0b3J5KTsKfQoKCi8qKiBBRVMgaW1wbGVtZW50YXRpb24gKiovCgp2YXIgaW5pdCA9IGZhbHNlOyAvLyBub3QgeWV0IGluaXRpYWxpemVkCnZhciBOYiA9IDQ7ICAgICAgIC8vIG51bWJlciBvZiB3b3JkcyBjb21wcmlzaW5nIHRoZSBzdGF0ZSAoQUVTID0gNCkKdmFyIHNib3g7ICAgICAgICAgLy8gbm9uLWxpbmVhciBzdWJzdGl0dXRpb24gdGFibGUgdXNlZCBpbiBrZXkgZXhwYW5zaW9uCnZhciBpc2JveDsgICAgICAgIC8vIGludmVyc2lvbiBvZiBzYm94CnZhciByY29uOyAgICAgICAgIC8vIHJvdW5kIGNvbnN0YW50IHdvcmQgYXJyYXkKdmFyIG1peDsgICAgICAgICAgLy8gbWl4LWNvbHVtbnMgdGFibGUKdmFyIGltaXg7ICAgICAgICAgLy8gaW52ZXJzZSBtaXgtY29sdW1ucyB0YWJsZQoKLyoqCiAqIFBlcmZvcm1zIGluaXRpYWxpemF0aW9uLCBpZTogcHJlY29tcHV0ZXMgdGFibGVzIHRvIG9wdGltaXplIGZvciBzcGVlZC4KICoKICogT25lIHdheSB0byB1bmRlcnN0YW5kIGhvdyBBRVMgd29ya3MgaXMgdG8gaW1hZ2luZSB0aGF0ICdhZGRpdGlvbicgYW5kCiAqICdtdWx0aXBsaWNhdGlvbicgYXJlIGludGVyZmFjZXMgdGhhdCByZXF1aXJlIGNlcnRhaW4gbWF0aGVtYXRpY2FsCiAqIHByb3BlcnRpZXMgdG8gaG9sZCB0cnVlIChpZTogdGhleSBhcmUgYXNzb2NpYXRpdmUpIGJ1dCB0aGV5IG1pZ2h0IGhhdmUKICogZGlmZmVyZW50IGltcGxlbWVudGF0aW9ucyBhbmQgcHJvZHVjZSBkaWZmZXJlbnQga2luZHMgb2YgcmVzdWx0cyAuLi4KICogcHJvdmlkZWQgdGhhdCB0aGVpciBtYXRoZW1hdGljYWwgcHJvcGVydGllcyByZW1haW4gdHJ1ZS4gQUVTIGRlZmluZXMKICogaXRzIG93biBtZXRob2RzIG9mIGFkZGl0aW9uIGFuZCBtdWx0aXBsaWNhdGlvbiBidXQga2VlcHMgc29tZSBpbXBvcnRhbnQKICogcHJvcGVydGllcyB0aGUgc2FtZSwgaWU6IGFzc29jaWF0aXZpdHkgYW5kIGRpc3RyaWJ1dGl2aXR5LiBUaGUKICogZXhwbGFuYXRpb24gYmVsb3cgdHJpZXMgdG8gc2hlZCBzb21lIGxpZ2h0IG9uIGhvdyBBRVMgZGVmaW5lcyBhZGRpdGlvbgogKiBhbmQgbXVsdGlwbGljYXRpb24gb2YgYnl0ZXMgYW5kIDMyLWJpdCB3b3JkcyBpbiBvcmRlciB0byBwZXJmb3JtIGl0cwogKiBlbmNyeXB0aW9uIGFuZCBkZWNyeXB0aW9uIGFsZ29yaXRobXMuCiAqCiAqIFRoZSBiYXNpY3M6CiAqCiAqIFRoZSBBRVMgYWxnb3JpdGhtIHZpZXdzIGJ5dGVzIGFzIGJpbmFyeSByZXByZXNlbnRhdGlvbnMgb2YgcG9seW5vbWlhbHMKICogdGhhdCBoYXZlIGVpdGhlciAxIG9yIDAgYXMgdGhlIGNvZWZmaWNpZW50cy4gSXQgZGVmaW5lcyB0aGUgYWRkaXRpb24KICogb3Igc3VidHJhY3Rpb24gb2YgdHdvIGJ5dGVzIGFzIHRoZSBYT1Igb3BlcmF0aW9uLiBJdCBhbHNvIGRlZmluZXMgdGhlCiAqIG11bHRpcGxpY2F0aW9uIG9mIHR3byBieXRlcyBhcyBhIGZpbml0ZSBmaWVsZCByZWZlcnJlZCB0byBhcyBHRigyXjgpCiAqIChOb3RlOiAnR0YnIG1lYW5zICJHYWxvaXMgRmllbGQiIHdoaWNoIGlzIGEgZmllbGQgdGhhdCBjb250YWlucyBhIGZpbml0ZQogKiBudW1iZXIgb2YgZWxlbWVudHMgc28gR0YoMl44KSBoYXMgMjU2IGVsZW1lbnRzKS4KICoKICogVGhpcyBtZWFucyB0aGF0IGFueSB0d28gYnl0ZXMgY2FuIGJlIHJlcHJlc2VudGVkIGFzIGJpbmFyeSBwb2x5bm9taWFsczsKICogd2hlbiB0aGV5IG11bHRpcGxpZWQgdG9nZXRoZXIgYW5kIG1vZHVsYXJseSByZWR1Y2VkIGJ5IGFuIGlycmVkdWNpYmxlCiAqIHBvbHlub21pYWwgb2YgdGhlIDh0aCBkZWdyZWUsIHRoZSByZXN1bHRzIGFyZSB0aGUgZmllbGQgR0YoMl44KS4gVGhlCiAqIHNwZWNpZmljIGlycmVkdWNpYmxlIHBvbHlub21pYWwgdGhhdCBBRVMgdXNlcyBpbiBoZXhhZGVjaW1hbCBpcyAweDExYi4KICogVGhpcyBtdWx0aXBsaWNhdGlvbiBpcyBhc3NvY2lhdGl2ZSB3aXRoIDB4MDEgYXMgdGhlIGlkZW50aXR5OgogKgogKiAoYiAqIDB4MDEgPSBHRihiLCAweDAxKSA9IGIpLgogKgogKiBUaGUgb3BlcmF0aW9uIEdGKGIsIDB4MDIpIGNhbiBiZSBwZXJmb3JtZWQgYXQgdGhlIGJ5dGUgbGV2ZWwgYnkgbGVmdAogKiBzaGlmdGluZyBiIG9uY2UgYW5kIHRoZW4gWE9SJ2luZyBpdCAodG8gcGVyZm9ybSB0aGUgbW9kdWxhciByZWR1Y3Rpb24pCiAqIHdpdGggMHgxMWIgaWYgYiBpcyA+PSAxMjguIFJlcGVhdGVkIGFwcGxpY2F0aW9uIG9mIHRoZSBtdWx0aXBsaWNhdGlvbgogKiBvZiAweDAyIGNhbiBiZSB1c2VkIHRvIGltcGxlbWVudCB0aGUgbXVsdGlwbGljYXRpb24gb2YgYW55IHR3byBieXRlcy4KICoKICogRm9yIGluc3RhbmNlLCBtdWx0aXBseWluZyAweDU3IGFuZCAweDEzLCBkZW5vdGVkIGFzIEdGKDB4NTcsIDB4MTMpLCBjYW4KICogYmUgcGVyZm9ybWVkIGJ5IGZhY3RvcmluZyAweDEzIGludG8gMHgwMSwgMHgwMiwgYW5kIDB4MTAuIFRoZW4gdGhlc2UKICogZmFjdG9ycyBjYW4gZWFjaCBiZSBtdWx0aXBsaWVkIGJ5IDB4NTcgYW5kIHRoZW4gYWRkZWQgdG9nZXRoZXIuIFRvIGRvCiAqIHRoZSBtdWx0aXBsaWNhdGlvbiwgdmFsdWVzIGZvciAweDU3IG11bHRpcGxpZWQgYnkgZWFjaCBvZiB0aGVzZSAzIGZhY3RvcnMKICogY2FuIGJlIHByZWNvbXB1dGVkIGFuZCBzdG9yZWQgaW4gYSB0YWJsZS4gVG8gYWRkIHRoZW0sIHRoZSB2YWx1ZXMgZnJvbQogKiB0aGUgdGFibGUgYXJlIFhPUidkIHRvZ2V0aGVyLgogKgogKiBBRVMgYWxzbyBkZWZpbmVzIGFkZGl0aW9uIGFuZCBtdWx0aXBsaWNhdGlvbiBvZiB3b3JkcywgdGhhdCBpcyA0LWJ5dGUKICogbnVtYmVycyByZXByZXNlbnRlZCBhcyBwb2x5bm9taWFscyBvZiAzIGRlZ3JlZXMgd2hlcmUgdGhlIGNvZWZmaWNpZW50cwogKiBhcmUgdGhlIHZhbHVlcyBvZiB0aGUgYnl0ZXMuCiAqCiAqIFRoZSB3b3JkIFthMCwgYTEsIGEyLCBhM10gaXMgYSBwb2x5bm9taWFsIGEzeF4zICsgYTJ4XjIgKyBhMXggKyBhMC4KICoKICogQWRkaXRpb24gaXMgcGVyZm9ybWVkIGJ5IFhPUidpbmcgbGlrZSBwb3dlcnMgb2YgeC4gTXVsdGlwbGljYXRpb24KICogaXMgcGVyZm9ybWVkIGluIHR3byBzdGVwcywgdGhlIGZpcnN0IGlzIGFuIGFsZ2VicmlhYyBleHBhbnNpb24gYXMKICogeW91IHdvdWxkIGRvIG5vcm1hbGx5ICh3aGVyZSBhZGRpdGlvbiBpcyBYT1IpLiBCdXQgdGhlIHJlc3VsdCBpcwogKiBhIHBvbHlub21pYWwgbGFyZ2VyIHRoYW4gMyBkZWdyZWVzIGFuZCB0aHVzIGl0IGNhbm5vdCBmaXQgaW4gYSB3b3JkLiBTbwogKiBuZXh0IHRoZSByZXN1bHQgaXMgbW9kdWxhcmx5IHJlZHVjZWQgYnkgYW4gQUVTLXNwZWNpZmljIHBvbHlub21pYWwgb2YKICogZGVncmVlIDQgd2hpY2ggd2lsbCBhbHdheXMgcHJvZHVjZSBhIHBvbHlub21pYWwgb2YgbGVzcyB0aGFuIDQgZGVncmVlcwogKiBzdWNoIHRoYXQgaXQgd2lsbCBmaXQgaW4gYSB3b3JkLiBJbiBBRVMsIHRoaXMgcG9seW5vbWlhbCBpcyB4XjQgKyAxLgogKgogKiBUaGUgbW9kdWxhciBwcm9kdWN0IG9mIHR3byBwb2x5bm9taWFscyAnYScgYW5kICdiJyBpcyB0aHVzOgogKgogKiBkKHgpID0gZDN4XjMgKyBkMnheMiArIGQxeCArIGQwCiAqIHdpdGgKICogZDAgPSBHRihhMCwgYjApIF4gR0YoYTMsIGIxKSBeIEdGKGEyLCBiMikgXiBHRihhMSwgYjMpCiAqIGQxID0gR0YoYTEsIGIwKSBeIEdGKGEwLCBiMSkgXiBHRihhMywgYjIpIF4gR0YoYTIsIGIzKQogKiBkMiA9IEdGKGEyLCBiMCkgXiBHRihhMSwgYjEpIF4gR0YoYTAsIGIyKSBeIEdGKGEzLCBiMykKICogZDMgPSBHRihhMywgYjApIF4gR0YoYTIsIGIxKSBeIEdGKGExLCBiMikgXiBHRihhMCwgYjMpCiAqCiAqIEFzIGEgbWF0cml4OgogKgogKiBbZDBdID0gW2EwIGEzIGEyIGExXVtiMF0KICogW2QxXSAgIFthMSBhMCBhMyBhMl1bYjFdCiAqIFtkMl0gICBbYTIgYTEgYTAgYTNdW2IyXQogKiBbZDNdICAgW2EzIGEyIGExIGEwXVtiM10KICoKICogU3BlY2lhbCBwb2x5bm9taWFscyBkZWZpbmVkIGJ5IEFFUyAoMHgwMiA9PSB7MDJ9KToKICogYSh4KSAgICA9IHswM314XjMgKyB7MDF9eF4yICsgezAxfXggKyB7MDJ9CiAqIGFeLTEoeCkgPSB7MGJ9eF4zICsgezBkfXheMiArIHswOX14ICsgezBlfS4KICoKICogVGhlc2UgcG9seW5vbWlhbHMgYXJlIHVzZWQgaW4gdGhlIE1peENvbHVtbnMoKSBhbmQgSW52ZXJzZU1peENvbHVtbnMoKQogKiBvcGVyYXRpb25zLCByZXNwZWN0aXZlbHksIHRvIGNhdXNlIGVhY2ggZWxlbWVudCBpbiB0aGUgc3RhdGUgdG8gYWZmZWN0CiAqIHRoZSBvdXRwdXQgKHJlZmVycmVkIHRvIGFzIGRpZmZ1c2luZykuCiAqCiAqIFJvdFdvcmQoKSB1c2VzOiBhMCA9IGExID0gYTIgPSB7MDB9IGFuZCBhMyA9IHswMX0sIHdoaWNoIGlzIHRoZQogKiBwb2x5bm9taWFsIHgzLgogKgogKiBUaGUgU2hpZnRSb3dzKCkgbWV0aG9kIG1vZGlmaWVzIHRoZSBsYXN0IDMgcm93cyBpbiB0aGUgc3RhdGUgKHdoZXJlCiAqIHRoZSBzdGF0ZSBpcyA0IHdvcmRzIHdpdGggNCBieXRlcyBwZXIgd29yZCkgYnkgc2hpZnRpbmcgYnl0ZXMgY3ljbGljYWxseS4KICogVGhlIDFzdCBieXRlIGluIHRoZSBzZWNvbmQgcm93IGlzIG1vdmVkIHRvIHRoZSBlbmQgb2YgdGhlIHJvdy4gVGhlIDFzdAogKiBhbmQgMm5kIGJ5dGVzIGluIHRoZSB0aGlyZCByb3cgYXJlIG1vdmVkIHRvIHRoZSBlbmQgb2YgdGhlIHJvdy4gVGhlIDFzdCwKICogMm5kLCBhbmQgM3JkIGJ5dGVzIGFyZSBtb3ZlZCBpbiB0aGUgZm91cnRoIHJvdy4KICoKICogTW9yZSBkZXRhaWxzIG9uIGhvdyBBRVMgYXJpdGhtZXRpYyB3b3JrczoKICoKICogSW4gdGhlIHBvbHlub21pYWwgcmVwcmVzZW50YXRpb24gb2YgYmluYXJ5IG51bWJlcnMsIFhPUiBwZXJmb3JtcyBhZGRpdGlvbgogKiBhbmQgc3VidHJhY3Rpb24gYW5kIG11bHRpcGxpY2F0aW9uIGluIEdGKDJeOCkgZGVub3RlZCBhcyBHRihhLCBiKQogKiBjb3JyZXNwb25kcyB3aXRoIHRoZSBtdWx0aXBsaWNhdGlvbiBvZiBwb2x5bm9taWFscyBtb2R1bG8gYW4gaXJyZWR1Y2libGUKICogcG9seW5vbWlhbCBvZiBkZWdyZWUgOC4gSW4gb3RoZXIgd29yZHMsIGZvciBBRVMsIEdGKGEsIGIpIHdpbGwgbXVsdGlwbHkKICogcG9seW5vbWlhbCAnYScgd2l0aCBwb2x5bm9taWFsICdiJyBhbmQgdGhlbiBkbyBhIG1vZHVsYXIgcmVkdWN0aW9uIGJ5CiAqIGFuIEFFUy1zcGVjaWZpYyBpcnJlZHVjaWJsZSBwb2x5bm9taWFsIG9mIGRlZ3JlZSA4LgogKgogKiBBIHBvbHlub21pYWwgaXMgaXJyZWR1Y2libGUgaWYgaXRzIG9ubHkgZGl2aXNvcnMgYXJlIG9uZSBhbmQgaXRzZWxmLiBGb3IKICogdGhlIEFFUyBhbGdvcml0aG0sIHRoaXMgaXJyZWR1Y2libGUgcG9seW5vbWlhbCBpczoKICoKICogbSh4KSA9IHheOCArIHheNCArIHheMyArIHggKyAxLAogKgogKiBvciB7MDF9ezFifSBpbiBoZXhhZGVjaW1hbCBub3RhdGlvbiwgd2hlcmUgZWFjaCBjb2VmZmljaWVudCBpcyBhIGJpdDoKICogMTAwMDExMDExID0gMjgzID0gMHgxMWIuCiAqCiAqIEZvciBleGFtcGxlLCBHRigweDU3LCAweDgzKSA9IDB4YzEgYmVjYXVzZQogKgogKiAweDU3ID0gODcgID0gMDEwMTAxMTEgPSB4XjYgKyB4XjQgKyB4XjIgKyB4ICsgMQogKiAweDg1ID0gMTMxID0gMTAwMDAxMDEgPSB4XjcgKyB4ICsgMQogKgogKiAoeF42ICsgeF40ICsgeF4yICsgeCArIDEpICogKHheNyArIHggKyAxKQogKiA9ICB4XjEzICsgeF4xMSArIHheOSArIHheOCArIHheNyArCiAqICAgIHheNyArIHheNSArIHheMyArIHheMiArIHggKwogKiAgICB4XjYgKyB4XjQgKyB4XjIgKyB4ICsgMQogKiA9ICB4XjEzICsgeF4xMSArIHheOSArIHheOCArIHheNiArIHheNSArIHheNCArIHheMyArIDEgPSB5CiAqICAgIHkgbW9kdWxvICh4XjggKyB4XjQgKyB4XjMgKyB4ICsgMSkKICogPSAgeF43ICsgeF42ICsgMS4KICoKICogVGhlIG1vZHVsYXIgcmVkdWN0aW9uIGJ5IG0oeCkgZ3VhcmFudGVlcyB0aGUgcmVzdWx0IHdpbGwgYmUgYSBiaW5hcnkKICogcG9seW5vbWlhbCBvZiBsZXNzIHRoYW4gZGVncmVlIDgsIHNvIHRoYXQgaXQgY2FuIGZpdCBpbiBhIGJ5dGUuCiAqCiAqIFRoZSBvcGVyYXRpb24gdG8gbXVsdGlwbHkgYSBiaW5hcnkgcG9seW5vbWlhbCBiIHdpdGggeCAodGhlIHBvbHlub21pYWwKICogeCBpbiBiaW5hcnkgcmVwcmVzZW50YXRpb24gaXMgMDAwMDAwMTApIGlzOgogKgogKiBiXzd4XjggKyBiXzZ4XjcgKyBiXzV4XjYgKyBiXzR4XjUgKyBiXzN4XjQgKyBiXzJ4XjMgKyBiXzF4XjIgKyBiXzB4XjEKICoKICogVG8gZ2V0IEdGKGIsIHgpIHdlIG11c3QgcmVkdWNlIHRoYXQgYnkgbSh4KS4gSWYgYl83IGlzIDAgKHRoYXQgaXMgdGhlCiAqIG1vc3Qgc2lnbmlmaWNhbnQgYml0IGlzIDAgaW4gYikgdGhlbiB0aGUgcmVzdWx0IGlzIGFscmVhZHkgcmVkdWNlZC4gSWYKICogaXQgaXMgMSwgdGhlbiB3ZSBjYW4gcmVkdWNlIGl0IGJ5IHN1YnRyYWN0aW5nIG0oeCkgdmlhIGFuIFhPUi4KICoKICogSXQgZm9sbG93cyB0aGF0IG11bHRpcGxpY2F0aW9uIGJ5IHggKDAwMDAwMDEwIG9yIDB4MDIpIGNhbiBiZSBpbXBsZW1lbnRlZAogKiBieSBwZXJmb3JtaW5nIGEgbGVmdCBzaGlmdCBmb2xsb3dlZCBieSBhIGNvbmRpdGlvbmFsIGJpdHdpc2UgWE9SIHdpdGgKICogMHgxYi4gVGhpcyBvcGVyYXRpb24gb24gYnl0ZXMgaXMgZGVub3RlZCBieSB4dGltZSgpLiBNdWx0aXBsaWNhdGlvbiBieQogKiBoaWdoZXIgcG93ZXJzIG9mIHggY2FuIGJlIGltcGxlbWVudGVkIGJ5IHJlcGVhdGVkIGFwcGxpY2F0aW9uIG9mIHh0aW1lKCkuCiAqCiAqIEJ5IGFkZGluZyBpbnRlcm1lZGlhdGUgcmVzdWx0cywgbXVsdGlwbGljYXRpb24gYnkgYW55IGNvbnN0YW50IGNhbiBiZQogKiBpbXBsZW1lbnRlZC4gRm9yIGluc3RhbmNlOgogKgogKiBHRigweDU3LCAweDEzKSA9IDB4ZmUgYmVjYXVzZToKICoKICogeHRpbWUoYikgPSAoYiAmIDEyOCkgPyAoYiA8PCAxIF4gMHgxMWIpIDogKGIgPDwgMSkKICoKICogTm90ZTogV2UgWE9SIHdpdGggMHgxMWIgaW5zdGVhZCBvZiAweDFiIGJlY2F1c2UgaW4gamF2YXNjcmlwdCBvdXIKICogZGF0YXR5cGUgZm9yIGIgY2FuIGJlIGxhcmdlciB0aGFuIDEgYnl0ZSwgc28gYSBsZWZ0IHNoaWZ0IHdpbGwgbm90CiAqIGF1dG9tYXRpY2FsbHkgZWxpbWluYXRlIGJpdHMgdGhhdCBvdmVyZmxvdyBhIGJ5dGUgLi4uIGJ5IFhPUidpbmcgdGhlCiAqIG92ZXJmbG93IGJpdCB3aXRoIDEgKHRoZSBleHRyYSBvbmUgZnJvbSAweDExYikgd2UgemVybyBpdCBvdXQuCiAqCiAqIEdGKDB4NTcsIDB4MDIpID0geHRpbWUoMHg1NykgPSAweGFlCiAqIEdGKDB4NTcsIDB4MDQpID0geHRpbWUoMHhhZSkgPSAweDQ3CiAqIEdGKDB4NTcsIDB4MDgpID0geHRpbWUoMHg0NykgPSAweDhlCiAqIEdGKDB4NTcsIDB4MTApID0geHRpbWUoMHg4ZSkgPSAweDA3CiAqCiAqIEdGKDB4NTcsIDB4MTMpID0gR0YoMHg1NywgKDB4MDEgXiAweDAyIF4gMHgxMCkpCiAqCiAqIEFuZCBieSB0aGUgZGlzdHJpYnV0aXZlIHByb3BlcnR5IChzaW5jZSBYT1IgaXMgYWRkaXRpb24gYW5kIEdGKCkgaXMKICogbXVsdGlwbGljYXRpb24pOgogKgogKiA9IEdGKDB4NTcsIDB4MDEpIF4gR0YoMHg1NywgMHgwMikgXiBHRigweDU3LCAweDEwKQogKiA9IDB4NTcgXiAweGFlIF4gMHgwNwogKiA9IDB4ZmUuCiAqLwpmdW5jdGlvbiBpbml0aWFsaXplKCkgewogIGluaXQgPSB0cnVlOwoKICAvKiBQb3B1bGF0ZSB0aGUgUmNvbiB0YWJsZS4gVGhlc2UgYXJlIHRoZSB2YWx1ZXMgZ2l2ZW4gYnkKICAgIFt4XihpLTEpLHswMH0sezAwfSx7MDB9XSB3aGVyZSB4XihpLTEpIGFyZSBwb3dlcnMgb2YgeCAoYW5kIHggPSAweDAyKQogICAgaW4gdGhlIGZpZWxkIG9mIEdGKDJeOCksIHdoZXJlIGkgc3RhcnRzIGF0IDEuCgogICAgcmNvblswXSA9IFsweDAwLCAweDAwLCAweDAwLCAweDAwXQogICAgcmNvblsxXSA9IFsweDAxLCAweDAwLCAweDAwLCAweDAwXSAyXigxLTEpID0gMl4wID0gMQogICAgcmNvblsyXSA9IFsweDAyLCAweDAwLCAweDAwLCAweDAwXSAyXigyLTEpID0gMl4xID0gMgogICAgLi4uCiAgICByY29uWzldICA9IFsweDFCLCAweDAwLCAweDAwLCAweDAwXSAyXig5LTEpICA9IDJeOCA9IDB4MUIKICAgIHJjb25bMTBdID0gWzB4MzYsIDB4MDAsIDB4MDAsIDB4MDBdIDJeKDEwLTEpID0gMl45ID0gMHgzNgoKICAgIFdlIG9ubHkgc3RvcmUgdGhlIGZpcnN0IGJ5dGUgYmVjYXVzZSBpdCBpcyB0aGUgb25seSBvbmUgdXNlZC4KICAqLwogIHJjb24gPSBbMHgwMCwgMHgwMSwgMHgwMiwgMHgwNCwgMHgwOCwgMHgxMCwgMHgyMCwgMHg0MCwgMHg4MCwgMHgxQiwgMHgzNl07CgogIC8vIGNvbXB1dGUgeHRpbWUgdGFibGUgd2hpY2ggbWFwcyBpIG9udG8gR0YoaSwgMHgwMikKICB2YXIgeHRpbWUgPSBuZXcgQXJyYXkoMjU2KTsKICBmb3IodmFyIGkgPSAwOyBpIDwgMTI4OyArK2kpIHsKICAgIHh0aW1lW2ldID0gaSA8PCAxOwogICAgeHRpbWVbaSArIDEyOF0gPSAoaSArIDEyOCkgPDwgMSBeIDB4MTFCOwogIH0KCiAgLy8gY29tcHV0ZSBhbGwgb3RoZXIgdGFibGVzCiAgc2JveCA9IG5ldyBBcnJheSgyNTYpOwogIGlzYm94ID0gbmV3IEFycmF5KDI1Nik7CiAgbWl4ID0gbmV3IEFycmF5KDQpOwogIGltaXggPSBuZXcgQXJyYXkoNCk7CiAgZm9yKHZhciBpID0gMDsgaSA8IDQ7ICsraSkgewogICAgbWl4W2ldID0gbmV3IEFycmF5KDI1Nik7CiAgICBpbWl4W2ldID0gbmV3IEFycmF5KDI1Nik7CiAgfQogIHZhciBlID0gMCwgZWkgPSAwLCBlMiwgZTQsIGU4LCBzeCwgc3gyLCBtZSwgaW1lOwogIGZvcih2YXIgaSA9IDA7IGkgPCAyNTY7ICsraSkgewogICAgLyogV2UgbmVlZCB0byBnZW5lcmF0ZSB0aGUgU3ViQnl0ZXMoKSBzYm94IGFuZCBpc2JveCB0YWJsZXMgc28gdGhhdAogICAgICB3ZSBjYW4gcGVyZm9ybSBieXRlIHN1YnN0aXR1dGlvbnMuIFRoaXMgcmVxdWlyZXMgdXMgdG8gdHJhdmVyc2UKICAgICAgYWxsIG9mIHRoZSBlbGVtZW50cyBpbiBHRiwgZmluZCB0aGVpciBtdWx0aXBsaWNhdGl2ZSBpbnZlcnNlcywKICAgICAgYW5kIGFwcGx5IHRvIGVhY2ggdGhlIGZvbGxvd2luZyBhZmZpbmUgdHJhbnNmb3JtYXRpb246CgogICAgICBiaScgPSBiaSBeIGIoaSArIDQpIG1vZCA4IF4gYihpICsgNSkgbW9kIDggXiBiKGkgKyA2KSBtb2QgOCBeCiAgICAgICAgICAgIGIoaSArIDcpIG1vZCA4IF4gY2kKICAgICAgZm9yIDAgPD0gaSA8IDgsIHdoZXJlIGJpIGlzIHRoZSBpdGggYml0IG9mIHRoZSBieXRlLCBhbmQgY2kgaXMgdGhlCiAgICAgIGl0aCBiaXQgb2YgYSBieXRlIGMgd2l0aCB0aGUgdmFsdWUgezYzfSBvciB7MDExMDAwMTF9LgoKICAgICAgSXQgaXMgcG9zc2libGUgdG8gdHJhdmVyc2UgZXZlcnkgcG9zc2libGUgdmFsdWUgaW4gYSBHYWxvaXMgZmllbGQKICAgICAgdXNpbmcgd2hhdCBpcyByZWZlcnJlZCB0byBhcyBhICdnZW5lcmF0b3InLiBUaGVyZSBhcmUgbWFueQogICAgICBnZW5lcmF0b3JzICgxMjggb3V0IG9mIDI1Nik6IDMsNSw2LDksMTEsODIgdG8gbmFtZSBhIGZldy4gVG8gZnVsbHkKICAgICAgdHJhdmVyc2UgR0Ygd2UgaXRlcmF0ZSAyNTUgdGltZXMsIG11bHRpcGx5aW5nIGJ5IG91ciBnZW5lcmF0b3IKICAgICAgZWFjaCB0aW1lLgoKICAgICAgT24gZWFjaCBpdGVyYXRpb24gd2UgY2FuIGRldGVybWluZSB0aGUgbXVsdGlwbGljYXRpdmUgaW52ZXJzZSBmb3IKICAgICAgdGhlIGN1cnJlbnQgZWxlbWVudC4KCiAgICAgIFN1cHBvc2UgdGhlcmUgaXMgYW4gZWxlbWVudCBpbiBHRiAnZScuIEZvciBhIGdpdmVuIGdlbmVyYXRvciAnZycsCiAgICAgIGUgPSBnXnguIFRoZSBtdWx0aXBsaWNhdGl2ZSBpbnZlcnNlIG9mIGUgaXMgZ14oMjU1IC0geCkuIEl0IHR1cm5zCiAgICAgIG91dCB0aGF0IGlmIHVzZSB0aGUgaW52ZXJzZSBvZiBhIGdlbmVyYXRvciBhcyBhbm90aGVyIGdlbmVyYXRvcgogICAgICBpdCB3aWxsIHByb2R1Y2UgYWxsIG9mIHRoZSBjb3JyZXNwb25kaW5nIG11bHRpcGxpY2F0aXZlIGludmVyc2VzCiAgICAgIGF0IHRoZSBzYW1lIHRpbWUuIEZvciB0aGlzIHJlYXNvbiwgd2UgY2hvb3NlIDUgYXMgb3VyIGludmVyc2UKICAgICAgZ2VuZXJhdG9yIGJlY2F1c2UgaXQgb25seSByZXF1aXJlcyAyIG11bHRpcGxpZXMgYW5kIDEgYWRkIGFuZCBpdHMKICAgICAgaW52ZXJzZSwgODIsIHJlcXVpcmVzIHJlbGF0aXZlbHkgZmV3IG9wZXJhdGlvbnMgYXMgd2VsbC4KCiAgICAgIEluIG9yZGVyIHRvIGFwcGx5IHRoZSBhZmZpbmUgdHJhbnNmb3JtYXRpb24sIHRoZSBtdWx0aXBsaWNhdGl2ZQogICAgICBpbnZlcnNlICdlaScgb2YgJ2UnIGNhbiBiZSByZXBlYXRlZGx5IFhPUidkICg0IHRpbWVzKSB3aXRoIGEKICAgICAgYml0LWN5Y2xpbmcgb2YgJ2VpJy4gVG8gZG8gdGhpcyAnZWknIGlzIGZpcnN0IHN0b3JlZCBpbiAncycgYW5kCiAgICAgICd4Jy4gVGhlbiAncycgaXMgbGVmdCBzaGlmdGVkIGFuZCB0aGUgaGlnaCBiaXQgb2YgJ3MnIGlzIG1hZGUgdGhlCiAgICAgIGxvdyBiaXQuIFRoZSByZXN1bHRpbmcgdmFsdWUgaXMgc3RvcmVkIGluICdzJy4gVGhlbiAneCcgaXMgWE9SJ2QKICAgICAgd2l0aCAncycgYW5kIHN0b3JlZCBpbiAneCcuIE9uIGVhY2ggc3Vic2VxdWVudCBpdGVyYXRpb24gdGhlIHNhbWUKICAgICAgb3BlcmF0aW9uIGlzIHBlcmZvcm1lZC4gV2hlbiA0IGl0ZXJhdGlvbnMgYXJlIGNvbXBsZXRlLCAneCcgaXMKICAgICAgWE9SJ2Qgd2l0aCAnYycgKDB4NjMpIGFuZCB0aGUgdHJhbnNmb3JtZWQgdmFsdWUgaXMgc3RvcmVkIGluICd4Jy4KICAgICAgRm9yIGV4YW1wbGU6CgogICAgICBzID0gMDEwMDAwMDEKICAgICAgeCA9IDAxMDAwMDAxCgogICAgICBpdGVyYXRpb24gMTogcyA9IDEwMDAwMDEwLCB4IF49IHMKICAgICAgaXRlcmF0aW9uIDI6IHMgPSAwMDAwMDEwMSwgeCBePSBzCiAgICAgIGl0ZXJhdGlvbiAzOiBzID0gMDAwMDEwMTAsIHggXj0gcwogICAgICBpdGVyYXRpb24gNDogcyA9IDAwMDEwMTAwLCB4IF49IHMKICAgICAgeCBePSAweDYzCgogICAgICBUaGlzIGNhbiBiZSBkb25lIHdpdGggYSBsb29wIHdoZXJlIHMgPSAocyA8PCAxKSB8IChzID4+IDcpLiBIb3dldmVyLAogICAgICBpdCBjYW4gYWxzbyBiZSBkb25lIGJ5IHVzaW5nIGEgc2luZ2xlIDE2LWJpdCAoaW4gdGhpcyBjYXNlIDMyLWJpdCkKICAgICAgbnVtYmVyICdzeCcuIFNpbmNlIFhPUiBpcyBhbiBhc3NvY2lhdGl2ZSBvcGVyYXRpb24sIHdlIGNhbiBzZXQgJ3N4JwogICAgICB0byAnZWknIGFuZCB0aGVuIFhPUiBpdCB3aXRoICdzeCcgbGVmdC1zaGlmdGVkIDEsMiwzLCBhbmQgNCB0aW1lcy4KICAgICAgVGhlIG1vc3Qgc2lnbmlmaWNhbnQgYml0cyB3aWxsIGZsb3cgaW50byB0aGUgaGlnaCA4IGJpdCBwb3NpdGlvbnMKICAgICAgYW5kIGJlIGNvcnJlY3RseSBYT1InZCB3aXRoIG9uZSBhbm90aGVyLiBBbGwgdGhhdCByZW1haW5zIHdpbGwgYmUKICAgICAgdG8gY3ljbGUgdGhlIGhpZ2ggOCBiaXRzIGJ5IFhPUidpbmcgdGhlbSBhbGwgd2l0aCB0aGUgbG93ZXIgOCBiaXRzCiAgICAgIGFmdGVyd2FyZHMuCgogICAgICBBdCB0aGUgc2FtZSB0aW1lIHdlJ3JlIHBvcHVsYXRpbmcgc2JveCBhbmQgaXNib3ggd2UgY2FuIHByZWNvbXB1dGUKICAgICAgdGhlIG11bHRpcGxpY2F0aW9uIHdlJ2xsIG5lZWQgdG8gZG8gdG8gZG8gTWl4Q29sdW1ucygpIGxhdGVyLgogICAgKi8KCiAgICAvLyBhcHBseSBhZmZpbmUgdHJhbnNmb3JtYXRpb24KICAgIHN4ID0gZWkgXiAoZWkgPDwgMSkgXiAoZWkgPDwgMikgXiAoZWkgPDwgMykgXiAoZWkgPDwgNCk7CiAgICBzeCA9IChzeCA+PiA4KSBeIChzeCAmIDI1NSkgXiAweDYzOwoKICAgIC8vIHVwZGF0ZSB0YWJsZXMKICAgIHNib3hbZV0gPSBzeDsKICAgIGlzYm94W3N4XSA9IGU7CgogICAgLyogTWl4aW5nIGNvbHVtbnMgaXMgZG9uZSB1c2luZyBtYXRyaXggbXVsdGlwbGljYXRpb24uIFRoZSBjb2x1bW5zCiAgICAgIHRoYXQgYXJlIHRvIGJlIG1peGVkIGFyZSBlYWNoIGEgc2luZ2xlIHdvcmQgaW4gdGhlIGN1cnJlbnQgc3RhdGUuCiAgICAgIFRoZSBzdGF0ZSBoYXMgTmIgY29sdW1ucyAoNCBjb2x1bW5zKS4gVGhlcmVmb3JlIGVhY2ggY29sdW1uIGlzIGEKICAgICAgNCBieXRlIHdvcmQuIFNvIHRvIG1peCB0aGUgY29sdW1ucyBpbiBhIHNpbmdsZSBjb2x1bW4gJ2MnIHdoZXJlCiAgICAgIGl0cyByb3dzIGFyZSByMCwgcjEsIHIyLCBhbmQgcjMsIHdlIHVzZSB0aGUgZm9sbG93aW5nIG1hdHJpeAogICAgICBtdWx0aXBsaWNhdGlvbjoKCiAgICAgIFsyIDMgMSAxXSpbcjAsY109W3InMCxjXQogICAgICBbMSAyIDMgMV0gW3IxLGNdIFtyJzEsY10KICAgICAgWzEgMSAyIDNdIFtyMixjXSBbcicyLGNdCiAgICAgIFszIDEgMSAyXSBbcjMsY10gW3InMyxjXQoKICAgICAgcjAsIHIxLCByMiwgYW5kIHIzIGFyZSBlYWNoIDEgYnl0ZSBvZiBvbmUgb2YgdGhlIHdvcmRzIGluIHRoZQogICAgICBzdGF0ZSAoYSBjb2x1bW4pLiBUbyBkbyBtYXRyaXggbXVsdGlwbGljYXRpb24gZm9yIGVhY2ggbWl4ZWQKICAgICAgY29sdW1uIGMnIHdlIG11bHRpcGx5IHRoZSBjb3JyZXNwb25kaW5nIHJvdyBmcm9tIHRoZSBsZWZ0IG1hdHJpeAogICAgICB3aXRoIHRoZSBjb3JyZXNwb25kaW5nIGNvbHVtbiBmcm9tIHRoZSByaWdodCBtYXRyaXguIEluIHRvdGFsLCB3ZQogICAgICBnZXQgNCBlcXVhdGlvbnM6CgogICAgICByMCxjJyA9IDIqcjAsYyArIDMqcjEsYyArIDEqcjIsYyArIDEqcjMsYwogICAgICByMSxjJyA9IDEqcjAsYyArIDIqcjEsYyArIDMqcjIsYyArIDEqcjMsYwogICAgICByMixjJyA9IDEqcjAsYyArIDEqcjEsYyArIDIqcjIsYyArIDMqcjMsYwogICAgICByMyxjJyA9IDMqcjAsYyArIDEqcjEsYyArIDEqcjIsYyArIDIqcjMsYwoKICAgICAgQXMgdXN1YWwsIHRoZSBtdWx0aXBsaWNhdGlvbiBpcyBhcyBwcmV2aW91c2x5IGRlZmluZWQgYW5kIHRoZQogICAgICBhZGRpdGlvbiBpcyBYT1IuIEluIG9yZGVyIHRvIG9wdGltaXplIG1peGluZyBjb2x1bW5zIHdlIGNhbiBzdG9yZQogICAgICB0aGUgbXVsdGlwbGljYXRpb24gcmVzdWx0cyBpbiB0YWJsZXMuIElmIHlvdSB0aGluayBvZiB0aGUgd2hvbGUKICAgICAgY29sdW1uIGFzIGEgd29yZCAoaXQgbWlnaHQgaGVscCB0byB2aXN1YWxpemUgYnkgbWVudGFsbHkgcm90YXRpbmcKICAgICAgdGhlIGVxdWF0aW9ucyBhYm92ZSBieSBjb3VudGVyY2xvY2t3aXNlIDkwIGRlZ3JlZXMpIHRoZW4geW91IGNhbgogICAgICBzZWUgdGhhdCBpdCB3b3VsZCBiZSB1c2VmdWwgdG8gbWFwIHRoZSBtdWx0aXBsaWNhdGlvbnMgcGVyZm9ybWVkIG9uCiAgICAgIGVhY2ggYnl0ZSAocjAsIHIxLCByMiwgcjMpIG9udG8gYSB3b3JkIGFzIHdlbGwuIEZvciBpbnN0YW5jZSwgd2UKICAgICAgY291bGQgbWFwIDIqcjAsMSpyMCwxKnIwLDMqcjAgb250byBhIHdvcmQgYnkgc3RvcmluZyAyKnIwIGluIHRoZQogICAgICBoaWdoZXN0IDggYml0cyBhbmQgMypyMCBpbiB0aGUgbG93ZXN0IDggYml0cyAod2l0aCB0aGUgb3RoZXIgdHdvCiAgICAgIHJlc3BlY3RpdmVseSBpbiB0aGUgbWlkZGxlKS4gVGhpcyBtZWFucyB0aGF0IGEgdGFibGUgY2FuIGJlCiAgICAgIGNvbnN0cnVjdGVkIHRoYXQgdXNlcyByMCBhcyBhbiBpbmRleCB0byB0aGUgd29yZC4gV2UgY2FuIGRvIHRoZQogICAgICBzYW1lIHdpdGggcjEsIHIyLCBhbmQgcjMsIGNyZWF0aW5nIGEgdG90YWwgb2YgNCB0YWJsZXMuCgogICAgICBUbyBjb25zdHJ1Y3QgYSBmdWxsIGMnLCB3ZSBjYW4ganVzdCBsb29rIHVwIGVhY2ggYnl0ZSBvZiBjIGluCiAgICAgIHRoZWlyIHJlc3BlY3RpdmUgdGFibGVzIGFuZCBYT1IgdGhlIHJlc3VsdHMgdG9nZXRoZXIuCgogICAgICBBbHNvLCB0byBidWlsZCBlYWNoIHRhYmxlIHdlIG9ubHkgaGF2ZSB0byBjYWxjdWxhdGUgdGhlIHdvcmQKICAgICAgZm9yIDIsMSwxLDMgZm9yIGV2ZXJ5IGJ5dGUgLi4uIHdoaWNoIHdlIGNhbiBkbyBvbiBlYWNoIGl0ZXJhdGlvbgogICAgICBvZiB0aGlzIGxvb3Agc2luY2Ugd2Ugd2lsbCBpdGVyYXRlIG92ZXIgZXZlcnkgYnl0ZS4gQWZ0ZXIgd2UgaGF2ZQogICAgICBjYWxjdWxhdGVkIDIsMSwxLDMgd2UgY2FuIGdldCB0aGUgcmVzdWx0cyBmb3IgdGhlIG90aGVyIHRhYmxlcwogICAgICBieSBjeWNsaW5nIHRoZSBieXRlIGF0IHRoZSBlbmQgdG8gdGhlIGJlZ2lubmluZy4gRm9yIGluc3RhbmNlCiAgICAgIHdlIGNhbiB0YWtlIHRoZSByZXN1bHQgb2YgdGFibGUgMiwxLDEsMyBhbmQgcHJvZHVjZSB0YWJsZSAzLDIsMSwxCiAgICAgIGJ5IG1vdmluZyB0aGUgcmlnaHQgbW9zdCBieXRlIHRvIHRoZSBsZWZ0IG1vc3QgcG9zaXRpb24ganVzdCBsaWtlCiAgICAgIGhvdyB5b3UgY2FuIGltYWdpbmUgdGhlIDMgbW92ZWQgb3V0IG9mIDIsMSwxLDMgYW5kIHRvIHRoZSBmcm9udAogICAgICB0byBwcm9kdWNlIDMsMiwxLDEuCgogICAgICBUaGVyZSBpcyBhbm90aGVyIG9wdGltaXphdGlvbiBpbiB0aGF0IHRoZSBzYW1lIG11bHRpcGxlcyBvZgogICAgICB0aGUgY3VycmVudCBlbGVtZW50IHdlIG5lZWQgaW4gb3JkZXIgdG8gYWR2YW5jZSBvdXIgZ2VuZXJhdG9yCiAgICAgIHRvIHRoZSBuZXh0IGl0ZXJhdGlvbiBjYW4gYmUgcmV1c2VkIGluIHBlcmZvcm1pbmcgdGhlIDIsMSwxLDMKICAgICAgY2FsY3VsYXRpb24uIFdlIGFsc28gY2FsY3VsYXRlIHRoZSBpbnZlcnNlIG1peCBjb2x1bW4gdGFibGVzLAogICAgICB3aXRoIGUsOSxkLGIgYmVpbmcgdGhlIGludmVyc2Ugb2YgMiwxLDEsMy4KCiAgICAgIFdoZW4gd2UncmUgZG9uZSwgYW5kIHdlIG5lZWQgdG8gYWN0dWFsbHkgbWl4IGNvbHVtbnMsIHRoZSBmaXJzdAogICAgICBieXRlIG9mIGVhY2ggc3RhdGUgd29yZCBzaG91bGQgYmUgcHV0IHRocm91Z2ggbWl4WzBdICgyLDEsMSwzKSwKICAgICAgdGhlIHNlY29uZCB0aHJvdWdoIG1peFsxXSAoMywyLDEsMSkgYW5kIHNvIGZvcnRoLiBUaGVuIHRoZXkgc2hvdWxkCiAgICAgIGJlIFhPUidkIHRvZ2V0aGVyIHRvIHByb2R1Y2UgdGhlIGZ1bGx5IG1peGVkIGNvbHVtbi4KICAgICovCgogICAgLy8gY2FsY3VsYXRlIG1peCBhbmQgaW1peCB0YWJsZSB2YWx1ZXMKICAgIHN4MiA9IHh0aW1lW3N4XTsKICAgIGUyID0geHRpbWVbZV07CiAgICBlNCA9IHh0aW1lW2UyXTsKICAgIGU4ID0geHRpbWVbZTRdOwogICAgbWUgPQogICAgICAoc3gyIDw8IDI0KSBeICAvLyAyCiAgICAgIChzeCA8PCAxNikgXiAgIC8vIDEKICAgICAgKHN4IDw8IDgpIF4gICAgLy8gMQogICAgICAoc3ggXiBzeDIpOyAgICAvLyAzCiAgICBpbWUgPQogICAgICAoZTIgXiBlNCBeIGU4KSA8PCAyNCBeICAvLyBFICgxNCkKICAgICAgKGUgXiBlOCkgPDwgMTYgXiAgICAgICAgLy8gOQogICAgICAoZSBeIGU0IF4gZTgpIDw8IDggXiAgICAvLyBEICgxMykKICAgICAgKGUgXiBlMiBeIGU4KTsgICAgICAgICAgLy8gQiAoMTEpCiAgICAvLyBwcm9kdWNlIGVhY2ggb2YgdGhlIG1peCB0YWJsZXMgYnkgcm90YXRpbmcgdGhlIDIsMSwxLDMgdmFsdWUKICAgIGZvcih2YXIgbiA9IDA7IG4gPCA0OyArK24pIHsKICAgICAgbWl4W25dW2VdID0gbWU7CiAgICAgIGltaXhbbl1bc3hdID0gaW1lOwogICAgICAvLyBjeWNsZSB0aGUgcmlnaHQgbW9zdCBieXRlIHRvIHRoZSBsZWZ0IG1vc3QgcG9zaXRpb24KICAgICAgLy8gaWU6IDIsMSwxLDMgYmVjb21lcyAzLDIsMSwxCiAgICAgIG1lID0gbWUgPDwgMjQgfCBtZSA+Pj4gODsKICAgICAgaW1lID0gaW1lIDw8IDI0IHwgaW1lID4+PiA4OwogICAgfQoKICAgIC8vIGdldCBuZXh0IGVsZW1lbnQgYW5kIGludmVyc2UKICAgIGlmKGUgPT09IDApIHsKICAgICAgLy8gMSBpcyB0aGUgaW52ZXJzZSBvZiAxCiAgICAgIGUgPSBlaSA9IDE7CiAgICB9IGVsc2UgewogICAgICAvLyBlID0gMmUgKyAyKjIqMiooMTBlKSkgPSBtdWx0aXBseSBlIGJ5IDgyIChjaG9zZW4gZ2VuZXJhdG9yKQogICAgICAvLyBlaSA9IGVpICsgMioyKmVpID0gbXVsdGlwbHkgZWkgYnkgNSAoaW52ZXJzZSBnZW5lcmF0b3IpCiAgICAgIGUgPSBlMiBeIHh0aW1lW3h0aW1lW3h0aW1lW2UyIF4gZThdXV07CiAgICAgIGVpIF49IHh0aW1lW3h0aW1lW2VpXV07CiAgICB9CiAgfQp9CgovKioKICogR2VuZXJhdGVzIGEga2V5IHNjaGVkdWxlIHVzaW5nIHRoZSBBRVMga2V5IGV4cGFuc2lvbiBhbGdvcml0aG0uCiAqCiAqIFRoZSBBRVMgYWxnb3JpdGhtIHRha2VzIHRoZSBDaXBoZXIgS2V5LCBLLCBhbmQgcGVyZm9ybXMgYSBLZXkgRXhwYW5zaW9uCiAqIHJvdXRpbmUgdG8gZ2VuZXJhdGUgYSBrZXkgc2NoZWR1bGUuIFRoZSBLZXkgRXhwYW5zaW9uIGdlbmVyYXRlcyBhIHRvdGFsCiAqIG9mIE5iKihOciArIDEpIHdvcmRzOiB0aGUgYWxnb3JpdGhtIHJlcXVpcmVzIGFuIGluaXRpYWwgc2V0IG9mIE5iIHdvcmRzLAogKiBhbmQgZWFjaCBvZiB0aGUgTnIgcm91bmRzIHJlcXVpcmVzIE5iIHdvcmRzIG9mIGtleSBkYXRhLiBUaGUgcmVzdWx0aW5nCiAqIGtleSBzY2hlZHVsZSBjb25zaXN0cyBvZiBhIGxpbmVhciBhcnJheSBvZiA0LWJ5dGUgd29yZHMsIGRlbm90ZWQgW3dpIF0sCiAqIHdpdGggaSBpbiB0aGUgcmFuZ2UgMCDiiaQgaSA8IE5iKE5yICsgMSkuCiAqCiAqIEtleUV4cGFuc2lvbihieXRlIGtleVs0Kk5rXSwgd29yZCB3W05iKihOcisxKV0sIE5rKQogKiBBRVMtMTI4IChOYj00LCBOaz00LCBOcj0xMCkKICogQUVTLTE5MiAoTmI9NCwgTms9NiwgTnI9MTIpCiAqIEFFUy0yNTYgKE5iPTQsIE5rPTgsIE5yPTE0KQogKiBOb3RlOiBOcj1Oays2LgogKgogKiBOYiBpcyB0aGUgbnVtYmVyIG9mIGNvbHVtbnMgKDMyLWJpdCB3b3JkcykgY29tcHJpc2luZyB0aGUgU3RhdGUgKG9yCiAqIG51bWJlciBvZiBieXRlcyBpbiBhIGJsb2NrKS4gRm9yIEFFUywgTmI9NC4KICoKICogQHBhcmFtIGtleSB0aGUga2V5IHRvIHNjaGVkdWxlIChhcyBhbiBhcnJheSBvZiAzMi1iaXQgd29yZHMpLgogKiBAcGFyYW0gZGVjcnlwdCB0cnVlIHRvIG1vZGlmeSB0aGUga2V5IHNjaGVkdWxlIHRvIGRlY3J5cHQsIGZhbHNlIG5vdCB0by4KICoKICogQHJldHVybiB0aGUgZ2VuZXJhdGVkIGtleSBzY2hlZHVsZS4KICovCmZ1bmN0aW9uIF9leHBhbmRLZXkoa2V5LCBkZWNyeXB0KSB7CiAgLy8gY29weSB0aGUga2V5J3Mgd29yZHMgdG8gaW5pdGlhbGl6ZSB0aGUga2V5IHNjaGVkdWxlCiAgdmFyIHcgPSBrZXkuc2xpY2UoMCk7CgogIC8qIFJvdFdvcmQoKSB3aWxsIHJvdGF0ZSBhIHdvcmQsIG1vdmluZyB0aGUgZmlyc3QgYnl0ZSB0byB0aGUgbGFzdAogICAgYnl0ZSdzIHBvc2l0aW9uIChzaGlmdGluZyB0aGUgb3RoZXIgYnl0ZXMgbGVmdCkuCgogICAgV2Ugd2lsbCBiZSBnZXR0aW5nIHRoZSB2YWx1ZSBvZiBSY29uIGF0IGkgLyBOay4gJ2knIHdpbGwgaXRlcmF0ZQogICAgZnJvbSBOayB0byAoTmIgKiBOcisxKS4gTmsgPSA0ICg0IGJ5dGUga2V5KSwgTmIgPSA0ICg0IHdvcmRzIGluCiAgICBhIGJsb2NrKSwgTnIgPSBOayArIDYgKDEwKS4gVGhlcmVmb3JlICdpJyB3aWxsIGl0ZXJhdGUgZnJvbQogICAgNCB0byA0NCAoZXhjbHVzaXZlKS4gRWFjaCB0aW1lIHdlIGl0ZXJhdGUgNCB0aW1lcywgaSAvIE5rIHdpbGwKICAgIGluY3JlYXNlIGJ5IDEuIFdlIHVzZSBhIGNvdW50ZXIgaU5rIHRvIGtlZXAgdHJhY2sgb2YgdGhpcy4KICAgKi8KCiAgLy8gZ28gdGhyb3VnaCB0aGUgcm91bmRzIGV4cGFuZGluZyB0aGUga2V5CiAgdmFyIHRlbXAsIGlOayA9IDE7CiAgdmFyIE5rID0gdy5sZW5ndGg7CiAgdmFyIE5yMSA9IE5rICsgNiArIDE7CiAgdmFyIGVuZCA9IE5iICogTnIxOwogIGZvcih2YXIgaSA9IE5rOyBpIDwgZW5kOyArK2kpIHsKICAgIHRlbXAgPSB3W2kgLSAxXTsKICAgIGlmKGkgJSBOayA9PT0gMCkgewogICAgICAvLyB0ZW1wID0gU3ViV29yZChSb3RXb3JkKHRlbXApKSBeIFJjb25baSAvIE5rXQogICAgICB0ZW1wID0KICAgICAgICBzYm94W3RlbXAgPj4+IDE2ICYgMjU1XSA8PCAyNCBeCiAgICAgICAgc2JveFt0ZW1wID4+PiA4ICYgMjU1XSA8PCAxNiBeCiAgICAgICAgc2JveFt0ZW1wICYgMjU1XSA8PCA4IF4KICAgICAgICBzYm94W3RlbXAgPj4+IDI0XSBeIChyY29uW2lOa10gPDwgMjQpOwogICAgICBpTmsrKzsKICAgIH0gZWxzZSBpZihOayA+IDYgJiYgKGkgJSBOayA9PT0gNCkpIHsKICAgICAgLy8gdGVtcCA9IFN1YldvcmQodGVtcCkKICAgICAgdGVtcCA9CiAgICAgICAgc2JveFt0ZW1wID4+PiAyNF0gPDwgMjQgXgogICAgICAgIHNib3hbdGVtcCA+Pj4gMTYgJiAyNTVdIDw8IDE2IF4KICAgICAgICBzYm94W3RlbXAgPj4+IDggJiAyNTVdIDw8IDggXgogICAgICAgIHNib3hbdGVtcCAmIDI1NV07CiAgICB9CiAgICB3W2ldID0gd1tpIC0gTmtdIF4gdGVtcDsKICB9CgogICAvKiBXaGVuIHdlIGFyZSB1cGRhdGluZyBhIGNpcGhlciBibG9jayB3ZSBhbHdheXMgdXNlIHRoZSBjb2RlIHBhdGggZm9yCiAgICAgZW5jcnlwdGlvbiB3aGV0aGVyIHdlIGFyZSBkZWNyeXB0aW5nIG9yIG5vdCAodG8gc2hvcnRlbiBjb2RlIGFuZAogICAgIHNpbXBsaWZ5IHRoZSBnZW5lcmF0aW9uIG9mIGxvb2sgdXAgdGFibGVzKS4gSG93ZXZlciwgYmVjYXVzZSB0aGVyZQogICAgIGFyZSBkaWZmZXJlbmNlcyBpbiB0aGUgZGVjcnlwdGlvbiBhbGdvcml0aG0sIG90aGVyIHRoYW4ganVzdCBzd2FwcGluZwogICAgIGluIGRpZmZlcmVudCBsb29rIHVwIHRhYmxlcywgd2UgbXVzdCB0cmFuc2Zvcm0gb3VyIGtleSBzY2hlZHVsZSB0bwogICAgIGFjY291bnQgZm9yIHRoZXNlIGNoYW5nZXM6CgogICAgIDEuIFRoZSBkZWNyeXB0aW9uIGFsZ29yaXRobSBnZXRzIGl0cyBrZXkgcm91bmRzIGluIHJldmVyc2Ugb3JkZXIuCiAgICAgMi4gVGhlIGRlY3J5cHRpb24gYWxnb3JpdGhtIGFkZHMgdGhlIHJvdW5kIGtleSBiZWZvcmUgbWl4aW5nIGNvbHVtbnMKICAgICAgIGluc3RlYWQgb2YgYWZ0ZXJ3YXJkcy4KCiAgICAgV2UgZG9uJ3QgbmVlZCB0byBtb2RpZnkgb3VyIGtleSBzY2hlZHVsZSB0byBoYW5kbGUgdGhlIGZpcnN0IGNhc2UsCiAgICAgd2UgY2FuIGp1c3QgdHJhdmVyc2UgdGhlIGtleSBzY2hlZHVsZSBpbiByZXZlcnNlIG9yZGVyIHdoZW4gZGVjcnlwdGluZy4KCiAgICAgVGhlIHNlY29uZCBjYXNlIHJlcXVpcmVzIGEgbGl0dGxlIHdvcmsuCgogICAgIFRoZSB0YWJsZXMgd2UgYnVpbHQgZm9yIHBlcmZvcm1pbmcgcm91bmRzIHdpbGwgdGFrZSBhbiBpbnB1dCBhbmQgdGhlbgogICAgIHBlcmZvcm0gU3ViQnl0ZXMoKSBhbmQgTWl4Q29sdW1ucygpIG9yLCBmb3IgdGhlIGRlY3J5cHQgdmVyc2lvbiwKICAgICBJbnZTdWJCeXRlcygpIGFuZCBJbnZNaXhDb2x1bW5zKCkuIEJ1dCB0aGUgZGVjcnlwdCBhbGdvcml0aG0gcmVxdWlyZXMKICAgICB1cyB0byBBZGRSb3VuZEtleSgpIGJlZm9yZSBJbnZNaXhDb2x1bW5zKCkuIFRoaXMgbWVhbnMgd2UnbGwgbmVlZCB0bwogICAgIGFwcGx5IHNvbWUgdHJhbnNmb3JtYXRpb25zIHRvIHRoZSByb3VuZCBrZXkgdG8gaW52ZXJzZS1taXggaXRzIGNvbHVtbnMKICAgICBzbyB0aGV5J2xsIGJlIGNvcnJlY3QgZm9yIG1vdmluZyBBZGRSb3VuZEtleSgpIHRvIGFmdGVyIHRoZSBzdGF0ZSBoYXMKICAgICBoYWQgaXRzIGNvbHVtbnMgaW52ZXJzZS1taXhlZC4KCiAgICAgVG8gaW52ZXJzZS1taXggdGhlIGNvbHVtbnMgb2YgdGhlIHN0YXRlIHdoZW4gd2UncmUgZGVjcnlwdGluZyB3ZSB1c2UgYQogICAgIGxvb2t1cCB0YWJsZSB0aGF0IHdpbGwgYXBwbHkgSW52U3ViQnl0ZXMoKSBhbmQgSW52TWl4Q29sdW1ucygpIGF0IHRoZQogICAgIHNhbWUgdGltZS4gSG93ZXZlciwgdGhlIHJvdW5kIGtleSdzIGJ5dGVzIGFyZSBub3QgaW52ZXJzZS1zdWJzdGl0dXRlZAogICAgIGluIHRoZSBkZWNyeXB0aW9uIGFsZ29yaXRobS4gVG8gZ2V0IGFyb3VuZCB0aGlzIHByb2JsZW0sIHdlIGNhbiBmaXJzdAogICAgIHN1YnN0aXR1dGUgdGhlIGJ5dGVzIGluIHRoZSByb3VuZCBrZXkgc28gdGhhdCB3aGVuIHdlIGFwcGx5IHRoZQogICAgIHRyYW5zZm9ybWF0aW9uIHZpYSB0aGUgSW52U3ViQnl0ZXMoKStJbnZNaXhDb2x1bW5zKCkgdGFibGUsIGl0IHdpbGwKICAgICB1bmRvIG91ciBzdWJzdGl0dXRpb24gbGVhdmluZyB1cyB3aXRoIHRoZSBvcmlnaW5hbCB2YWx1ZSB0aGF0IHdlCiAgICAgd2FudCAtLSBhbmQgdGhlbiBpbnZlcnNlLW1peCB0aGF0IHZhbHVlLgoKICAgICBUaGlzIGNoYW5nZSB3aWxsIGNvcnJlY3RseSBhbHRlciBvdXIga2V5IHNjaGVkdWxlIHNvIHRoYXQgd2UgY2FuIFhPUgogICAgIGVhY2ggcm91bmQga2V5IHdpdGggb3VyIGFscmVhZHkgdHJhbnNmb3JtZWQgZGVjcnlwdGlvbiBzdGF0ZS4gVGhpcwogICAgIGFsbG93cyB1cyB0byB1c2UgdGhlIHNhbWUgY29kZSBwYXRoIGFzIHRoZSBlbmNyeXB0aW9uIGFsZ29yaXRobS4KCiAgICAgV2UgbWFrZSBvbmUgbW9yZSBjaGFuZ2UgdG8gdGhlIGRlY3J5cHRpb24ga2V5LiBTaW5jZSB0aGUgZGVjcnlwdGlvbgogICAgIGFsZ29yaXRobSBydW5zIGluIHJldmVyc2UgZnJvbSB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0sIHdlIHJldmVyc2UKICAgICB0aGUgb3JkZXIgb2YgdGhlIHJvdW5kIGtleXMgdG8gYXZvaWQgaGF2aW5nIHRvIGl0ZXJhdGUgb3ZlciB0aGUga2V5CiAgICAgc2NoZWR1bGUgYmFja3dhcmRzIHdoZW4gcnVubmluZyB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0gbGF0ZXIgaW4KICAgICBkZWNyeXB0aW9uIG1vZGUuIEluIGFkZGl0aW9uIHRvIHJldmVyc2luZyB0aGUgb3JkZXIgb2YgdGhlIHJvdW5kIGtleXMsCiAgICAgd2UgYWxzbyBzd2FwIGVhY2ggcm91bmQga2V5J3MgMm5kIGFuZCA0dGggcm93cy4gU2VlIHRoZSBjb21tZW50cwogICAgIHNlY3Rpb24gd2hlcmUgcm91bmRzIGFyZSBwZXJmb3JtZWQgZm9yIG1vcmUgZGV0YWlscyBhYm91dCB3aHkgdGhpcyBpcwogICAgIGRvbmUuIFRoZXNlIGNoYW5nZXMgYXJlIGRvbmUgaW5saW5lIHdpdGggdGhlIG90aGVyIHN1YnN0aXR1dGlvbgogICAgIGRlc2NyaWJlZCBhYm92ZS4KICAqLwogIGlmKGRlY3J5cHQpIHsKICAgIHZhciB0bXA7CiAgICB2YXIgbTAgPSBpbWl4WzBdOwogICAgdmFyIG0xID0gaW1peFsxXTsKICAgIHZhciBtMiA9IGltaXhbMl07CiAgICB2YXIgbTMgPSBpbWl4WzNdOwogICAgdmFyIHduZXcgPSB3LnNsaWNlKDApOwogICAgZW5kID0gdy5sZW5ndGg7CiAgICBmb3IodmFyIGkgPSAwLCB3aSA9IGVuZCAtIE5iOyBpIDwgZW5kOyBpICs9IE5iLCB3aSAtPSBOYikgewogICAgICAvLyBkbyBub3Qgc3ViIHRoZSBmaXJzdCBvciBsYXN0IHJvdW5kIGtleSAocm91bmQga2V5cyBhcmUgTmIKICAgICAgLy8gd29yZHMpIGFzIG5vIGNvbHVtbiBtaXhpbmcgaXMgcGVyZm9ybWVkIGJlZm9yZSB0aGV5IGFyZSBhZGRlZCwKICAgICAgLy8gYnV0IGRvIGNoYW5nZSB0aGUga2V5IG9yZGVyCiAgICAgIGlmKGkgPT09IDAgfHwgaSA9PT0gKGVuZCAtIE5iKSkgewogICAgICAgIHduZXdbaV0gPSB3W3dpXTsKICAgICAgICB3bmV3W2kgKyAxXSA9IHdbd2kgKyAzXTsKICAgICAgICB3bmV3W2kgKyAyXSA9IHdbd2kgKyAyXTsKICAgICAgICB3bmV3W2kgKyAzXSA9IHdbd2kgKyAxXTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBzdWJzdGl0dXRlIGVhY2ggcm91bmQga2V5IGJ5dGUgYmVjYXVzZSB0aGUgaW52ZXJzZS1taXgKICAgICAgICAvLyB0YWJsZSB3aWxsIGludmVyc2Utc3Vic3RpdHV0ZSBpdCAoZWZmZWN0aXZlbHkgY2FuY2VsIHRoZQogICAgICAgIC8vIHN1YnN0aXR1dGlvbiBiZWNhdXNlIHJvdW5kIGtleSBieXRlcyBhcmVuJ3Qgc3ViJ2QgaW4KICAgICAgICAvLyBkZWNyeXB0aW9uIG1vZGUpIGFuZCBzd2FwIGluZGV4ZXMgMyBhbmQgMQogICAgICAgIGZvcih2YXIgbiA9IDA7IG4gPCBOYjsgKytuKSB7CiAgICAgICAgICB0bXAgPSB3W3dpICsgbl07CiAgICAgICAgICB3bmV3W2kgKyAoMyYtbildID0KICAgICAgICAgICAgbTBbc2JveFt0bXAgPj4+IDI0XV0gXgogICAgICAgICAgICBtMVtzYm94W3RtcCA+Pj4gMTYgJiAyNTVdXSBeCiAgICAgICAgICAgIG0yW3Nib3hbdG1wID4+PiA4ICYgMjU1XV0gXgogICAgICAgICAgICBtM1tzYm94W3RtcCAmIDI1NV1dOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgdyA9IHduZXc7CiAgfQoKICByZXR1cm4gdzsKfQoKLyoqCiAqIFVwZGF0ZXMgYSBzaW5nbGUgYmxvY2sgKDE2IGJ5dGVzKSB1c2luZyBBRVMuIFRoZSB1cGRhdGUgd2lsbCBlaXRoZXIKICogZW5jcnlwdCBvciBkZWNyeXB0IHRoZSBibG9jay4KICoKICogQHBhcmFtIHcgdGhlIGtleSBzY2hlZHVsZS4KICogQHBhcmFtIGlucHV0IHRoZSBpbnB1dCBibG9jayAoYW4gYXJyYXkgb2YgMzItYml0IHdvcmRzKS4KICogQHBhcmFtIG91dHB1dCB0aGUgdXBkYXRlZCBvdXRwdXQgYmxvY2suCiAqIEBwYXJhbSBkZWNyeXB0IHRydWUgdG8gZGVjcnlwdCB0aGUgYmxvY2ssIGZhbHNlIHRvIGVuY3J5cHQgaXQuCiAqLwpmdW5jdGlvbiBfdXBkYXRlQmxvY2sodywgaW5wdXQsIG91dHB1dCwgZGVjcnlwdCkgewogIC8qCiAgQ2lwaGVyKGJ5dGUgaW5bNCpOYl0sIGJ5dGUgb3V0WzQqTmJdLCB3b3JkIHdbTmIqKE5yKzEpXSkKICBiZWdpbgogICAgYnl0ZSBzdGF0ZVs0LE5iXQogICAgc3RhdGUgPSBpbgogICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbMCwgTmItMV0pCiAgICBmb3Igcm91bmQgPSAxIHN0ZXAgMSB0byBOcuKAkzEKICAgICAgU3ViQnl0ZXMoc3RhdGUpCiAgICAgIFNoaWZ0Um93cyhzdGF0ZSkKICAgICAgTWl4Q29sdW1ucyhzdGF0ZSkKICAgICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbcm91bmQqTmIsIChyb3VuZCsxKSpOYi0xXSkKICAgIGVuZCBmb3IKICAgIFN1YkJ5dGVzKHN0YXRlKQogICAgU2hpZnRSb3dzKHN0YXRlKQogICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbTnIqTmIsIChOcisxKSpOYi0xXSkKICAgIG91dCA9IHN0YXRlCiAgZW5kCgogIEludkNpcGhlcihieXRlIGluWzQqTmJdLCBieXRlIG91dFs0Kk5iXSwgd29yZCB3W05iKihOcisxKV0pCiAgYmVnaW4KICAgIGJ5dGUgc3RhdGVbNCxOYl0KICAgIHN0YXRlID0gaW4KICAgIEFkZFJvdW5kS2V5KHN0YXRlLCB3W05yKk5iLCAoTnIrMSkqTmItMV0pCiAgICBmb3Igcm91bmQgPSBOci0xIHN0ZXAgLTEgZG93bnRvIDEKICAgICAgSW52U2hpZnRSb3dzKHN0YXRlKQogICAgICBJbnZTdWJCeXRlcyhzdGF0ZSkKICAgICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbcm91bmQqTmIsIChyb3VuZCsxKSpOYi0xXSkKICAgICAgSW52TWl4Q29sdW1ucyhzdGF0ZSkKICAgIGVuZCBmb3IKICAgIEludlNoaWZ0Um93cyhzdGF0ZSkKICAgIEludlN1YkJ5dGVzKHN0YXRlKQogICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbMCwgTmItMV0pCiAgICBvdXQgPSBzdGF0ZQogIGVuZAogICovCgogIC8vIEVuY3J5cHQ6IEFkZFJvdW5kS2V5KHN0YXRlLCB3WzAsIE5iLTFdKQogIC8vIERlY3J5cHQ6IEFkZFJvdW5kS2V5KHN0YXRlLCB3W05yKk5iLCAoTnIrMSkqTmItMV0pCiAgdmFyIE5yID0gdy5sZW5ndGggLyA0IC0gMTsKICB2YXIgbTAsIG0xLCBtMiwgbTMsIHN1YjsKICBpZihkZWNyeXB0KSB7CiAgICBtMCA9IGltaXhbMF07CiAgICBtMSA9IGltaXhbMV07CiAgICBtMiA9IGltaXhbMl07CiAgICBtMyA9IGltaXhbM107CiAgICBzdWIgPSBpc2JveDsKICB9IGVsc2UgewogICAgbTAgPSBtaXhbMF07CiAgICBtMSA9IG1peFsxXTsKICAgIG0yID0gbWl4WzJdOwogICAgbTMgPSBtaXhbM107CiAgICBzdWIgPSBzYm94OwogIH0KICB2YXIgYSwgYiwgYywgZCwgYTIsIGIyLCBjMjsKICBhID0gaW5wdXRbMF0gXiB3WzBdOwogIGIgPSBpbnB1dFtkZWNyeXB0ID8gMyA6IDFdIF4gd1sxXTsKICBjID0gaW5wdXRbMl0gXiB3WzJdOwogIGQgPSBpbnB1dFtkZWNyeXB0ID8gMSA6IDNdIF4gd1szXTsKICB2YXIgaSA9IDM7CgogIC8qIEluIG9yZGVyIHRvIHNoYXJlIGNvZGUgd2UgZm9sbG93IHRoZSBlbmNyeXB0aW9uIGFsZ29yaXRobSB3aGVuIGJvdGgKICAgIGVuY3J5cHRpbmcgYW5kIGRlY3J5cHRpbmcuIFRvIGFjY291bnQgZm9yIHRoZSBjaGFuZ2VzIHJlcXVpcmVkIGluIHRoZQogICAgZGVjcnlwdGlvbiBhbGdvcml0aG0sIHdlIHVzZSBkaWZmZXJlbnQgbG9va3VwIHRhYmxlcyB3aGVuIGRlY3J5cHRpbmcKICAgIGFuZCB1c2UgYSBtb2RpZmllZCBrZXkgc2NoZWR1bGUgdG8gYWNjb3VudCBmb3IgdGhlIGRpZmZlcmVuY2UgaW4gdGhlCiAgICBvcmRlciBvZiB0cmFuc2Zvcm1hdGlvbnMgYXBwbGllZCB3aGVuIHBlcmZvcm1pbmcgcm91bmRzLiBXZSBhbHNvIGdldAogICAga2V5IHJvdW5kcyBpbiByZXZlcnNlIG9yZGVyIChyZWxhdGl2ZSB0byBlbmNyeXB0aW9uKS4gKi8KICBmb3IodmFyIHJvdW5kID0gMTsgcm91bmQgPCBOcjsgKytyb3VuZCkgewogICAgLyogQXMgZGVzY3JpYmVkIGFib3ZlLCB3ZSdsbCBiZSB1c2luZyB0YWJsZSBsb29rdXBzIHRvIHBlcmZvcm0gdGhlCiAgICAgIGNvbHVtbiBtaXhpbmcuIEVhY2ggY29sdW1uIGlzIHN0b3JlZCBhcyBhIHdvcmQgaW4gdGhlIHN0YXRlICh0aGUKICAgICAgYXJyYXkgJ2lucHV0JyBoYXMgb25lIGNvbHVtbiBhcyBhIHdvcmQgYXQgZWFjaCBpbmRleCkuIEluIG9yZGVyIHRvCiAgICAgIG1peCBhIGNvbHVtbiwgd2UgcGVyZm9ybSB0aGVzZSB0cmFuc2Zvcm1hdGlvbnMgb24gZWFjaCByb3cgaW4gYywKICAgICAgd2hpY2ggaXMgMSBieXRlIGluIGVhY2ggd29yZC4gVGhlIG5ldyBjb2x1bW4gZm9yIGMwIGlzIGMnMDoKCiAgICAgICAgICAgICAgIG0wICAgICAgbTEgICAgICBtMiAgICAgIG0zCiAgICAgIHIwLGMnMCA9IDIqcjAsYzAgKyAzKnIxLGMwICsgMSpyMixjMCArIDEqcjMsYzAKICAgICAgcjEsYycwID0gMSpyMCxjMCArIDIqcjEsYzAgKyAzKnIyLGMwICsgMSpyMyxjMAogICAgICByMixjJzAgPSAxKnIwLGMwICsgMSpyMSxjMCArIDIqcjIsYzAgKyAzKnIzLGMwCiAgICAgIHIzLGMnMCA9IDMqcjAsYzAgKyAxKnIxLGMwICsgMSpyMixjMCArIDIqcjMsYzAKCiAgICAgIFNvIHVzaW5nIG1peCB0YWJsZXMgd2hlcmUgYzAgaXMgYSB3b3JkIHdpdGggcjAgYmVpbmcgaXRzIHVwcGVyCiAgICAgIDggYml0cyBhbmQgcjMgYmVpbmcgaXRzIGxvd2VyIDggYml0czoKCiAgICAgIG0wW2MwID4+IDI0XSB3aWxsIHlpZWxkIHRoaXMgd29yZDogWzIqcjAsMSpyMCwxKnIwLDMqcjBdCiAgICAgIC4uLgogICAgICBtM1tjMCAmIDI1NV0gd2lsbCB5aWVsZCB0aGlzIHdvcmQ6IFsxKnIzLDEqcjMsMypyMywyKnIzXQoKICAgICAgVGhlcmVmb3JlIHRvIG1peCB0aGUgY29sdW1ucyBpbiBlYWNoIHdvcmQgaW4gdGhlIHN0YXRlIHdlCiAgICAgIGRvIHRoZSBmb2xsb3dpbmcgKCYgMjU1IG9taXR0ZWQgZm9yIGJyZXZpdHkpOgogICAgICBjJzAscjAgPSBtMFtjMCA+PiAyNF0gXiBtMVtjMSA+PiAxNl0gXiBtMltjMiA+PiA4XSBeIG0zW2MzXQogICAgICBjJzAscjEgPSBtMFtjMCA+PiAyNF0gXiBtMVtjMSA+PiAxNl0gXiBtMltjMiA+PiA4XSBeIG0zW2MzXQogICAgICBjJzAscjIgPSBtMFtjMCA+PiAyNF0gXiBtMVtjMSA+PiAxNl0gXiBtMltjMiA+PiA4XSBeIG0zW2MzXQogICAgICBjJzAscjMgPSBtMFtjMCA+PiAyNF0gXiBtMVtjMSA+PiAxNl0gXiBtMltjMiA+PiA4XSBeIG0zW2MzXQoKICAgICAgSG93ZXZlciwgYmVmb3JlIG1peGluZywgdGhlIGFsZ29yaXRobSByZXF1aXJlcyB1cyB0byBwZXJmb3JtCiAgICAgIFNoaWZ0Um93cygpLiBUaGUgU2hpZnRSb3dzKCkgdHJhbnNmb3JtYXRpb24gY3ljbGljYWxseSBzaGlmdHMgdGhlCiAgICAgIGxhc3QgMyByb3dzIG9mIHRoZSBzdGF0ZSBvdmVyIGRpZmZlcmVudCBvZmZzZXRzLiBUaGUgZmlyc3Qgcm93CiAgICAgIChyID0gMCkgaXMgbm90IHNoaWZ0ZWQuCgogICAgICBzJ19yLGMgPSBzX3IsKGMgKyBzaGlmdChyLCBOYikgbW9kIE5iCiAgICAgIGZvciAwIDwgciA8IDQgYW5kIDAgPD0gYyA8IE5iIGFuZAogICAgICBzaGlmdCgxLCA0KSA9IDEKICAgICAgc2hpZnQoMiwgNCkgPSAyCiAgICAgIHNoaWZ0KDMsIDQpID0gMy4KCiAgICAgIFRoaXMgY2F1c2VzIHRoZSBmaXJzdCBieXRlIGluIHIgPSAxIHRvIGJlIG1vdmVkIHRvIHRoZSBlbmQgb2YKICAgICAgdGhlIHJvdywgdGhlIGZpcnN0IDIgYnl0ZXMgaW4gciA9IDIgdG8gYmUgbW92ZWQgdG8gdGhlIGVuZCBvZgogICAgICB0aGUgcm93LCB0aGUgZmlyc3QgMyBieXRlcyBpbiByID0gMyB0byBiZSBtb3ZlZCB0byB0aGUgZW5kIG9mCiAgICAgIHRoZSByb3c6CgogICAgICByMTogW2MwIGMxIGMyIGMzXSA9PiBbYzEgYzIgYzMgYzBdCiAgICAgIHIyOiBbYzAgYzEgYzIgYzNdICAgIFtjMiBjMyBjMCBjMV0KICAgICAgcjM6IFtjMCBjMSBjMiBjM10gICAgW2MzIGMwIGMxIGMyXQoKICAgICAgV2UgY2FuIG1ha2UgdGhlc2Ugc3Vic3RpdHV0aW9ucyBpbmxpbmUgd2l0aCBvdXIgY29sdW1uIG1peGluZyB0bwogICAgICBnZW5lcmF0ZSBhbiB1cGRhdGVkIHNldCBvZiBlcXVhdGlvbnMgdG8gcHJvZHVjZSBlYWNoIHdvcmQgaW4gdGhlCiAgICAgIHN0YXRlIChub3RlIHRoZSBjb2x1bW5zIGhhdmUgY2hhbmdlZCBwb3NpdGlvbnMpOgoKICAgICAgYzAgYzEgYzIgYzMgPT4gYzAgYzEgYzIgYzMKICAgICAgYzAgYzEgYzIgYzMgICAgYzEgYzIgYzMgYzAgIChjeWNsZWQgMSBieXRlKQogICAgICBjMCBjMSBjMiBjMyAgICBjMiBjMyBjMCBjMSAgKGN5Y2xlZCAyIGJ5dGVzKQogICAgICBjMCBjMSBjMiBjMyAgICBjMyBjMCBjMSBjMiAgKGN5Y2xlZCAzIGJ5dGVzKQoKICAgICAgVGhlcmVmb3JlOgoKICAgICAgYycwID0gMipyMCxjMCArIDMqcjEsYzEgKyAxKnIyLGMyICsgMSpyMyxjMwogICAgICBjJzAgPSAxKnIwLGMwICsgMipyMSxjMSArIDMqcjIsYzIgKyAxKnIzLGMzCiAgICAgIGMnMCA9IDEqcjAsYzAgKyAxKnIxLGMxICsgMipyMixjMiArIDMqcjMsYzMKICAgICAgYycwID0gMypyMCxjMCArIDEqcjEsYzEgKyAxKnIyLGMyICsgMipyMyxjMwoKICAgICAgYycxID0gMipyMCxjMSArIDMqcjEsYzIgKyAxKnIyLGMzICsgMSpyMyxjMAogICAgICBjJzEgPSAxKnIwLGMxICsgMipyMSxjMiArIDMqcjIsYzMgKyAxKnIzLGMwCiAgICAgIGMnMSA9IDEqcjAsYzEgKyAxKnIxLGMyICsgMipyMixjMyArIDMqcjMsYzAKICAgICAgYycxID0gMypyMCxjMSArIDEqcjEsYzIgKyAxKnIyLGMzICsgMipyMyxjMAoKICAgICAgLi4uIGFuZCBzbyBmb3J0aCBmb3IgYycyIGFuZCBjJzMuIFRoZSBpbXBvcnRhbnQgZGlzdGluY3Rpb24gaXMKICAgICAgdGhhdCB0aGUgY29sdW1ucyBhcmUgY3ljbGluZywgd2l0aCBjMCBiZWluZyB1c2VkIHdpdGggdGhlIG0wCiAgICAgIG1hcCB3aGVuIGNhbGN1bGF0aW5nIGMwLCBidXQgYzEgYmVpbmcgdXNlZCB3aXRoIHRoZSBtMCBtYXAgd2hlbgogICAgICBjYWxjdWxhdGluZyBjMSAuLi4gYW5kIHNvIGZvcnRoLgoKICAgICAgV2hlbiBwZXJmb3JtaW5nIHRoZSBpbnZlcnNlIHdlIHRyYW5zZm9ybSB0aGUgbWlycm9yIGltYWdlIGFuZAogICAgICBza2lwIHRoZSBib3R0b20gcm93LCBpbnN0ZWFkIG9mIHRoZSB0b3Agb25lLCBhbmQgbW92ZSB1cHdhcmRzOgoKICAgICAgYzMgYzIgYzEgYzAgPT4gYzAgYzMgYzIgYzEgIChjeWNsZWQgMyBieXRlcykgKnNhbWUgYXMgZW5jcnlwdGlvbgogICAgICBjMyBjMiBjMSBjMCAgICBjMSBjMCBjMyBjMiAgKGN5Y2xlZCAyIGJ5dGVzKQogICAgICBjMyBjMiBjMSBjMCAgICBjMiBjMSBjMCBjMyAgKGN5Y2xlZCAxIGJ5dGUpICAqc2FtZSBhcyBlbmNyeXB0aW9uCiAgICAgIGMzIGMyIGMxIGMwICAgIGMzIGMyIGMxIGMwCgogICAgICBJZiB5b3UgY29tcGFyZSB0aGUgcmVzdWx0aW5nIG1hdHJpY2VzIGZvciBTaGlmdFJvd3MoKStNaXhDb2x1bW5zKCkKICAgICAgYW5kIGZvciBJbnZTaGlmdFJvd3MoKStJbnZNaXhDb2x1bW5zKCkgdGhlIDJuZCBhbmQgNHRoIGNvbHVtbnMgYXJlCiAgICAgIGRpZmZlcmVudCAoaW4gZW5jcnlwdCBtb2RlIHZzLiBkZWNyeXB0IG1vZGUpLiBTbyBpbiBvcmRlciB0byB1c2UKICAgICAgdGhlIHNhbWUgY29kZSB0byBoYW5kbGUgYm90aCBlbmNyeXB0aW9uIGFuZCBkZWNyeXB0aW9uLCB3ZSB3aWxsCiAgICAgIG5lZWQgdG8gZG8gc29tZSBtYXBwaW5nLgoKICAgICAgSWYgaW4gZW5jcnlwdGlvbiBtb2RlIHdlIGxldCBhPWMwLCBiPWMxLCBjPWMyLCBkPWMzLCBhbmQgcjxOPiBiZQogICAgICBhIHJvdyBudW1iZXIgaW4gdGhlIHN0YXRlLCB0aGVuIHRoZSByZXN1bHRpbmcgbWF0cml4IGluIGVuY3J5cHRpb24KICAgICAgbW9kZSBmb3IgYXBwbHlpbmcgdGhlIGFib3ZlIHRyYW5zZm9ybWF0aW9ucyB3b3VsZCBiZToKCiAgICAgIHIxOiBhIGIgYyBkCiAgICAgIHIyOiBiIGMgZCBhCiAgICAgIHIzOiBjIGQgYSBiCiAgICAgIHI0OiBkIGEgYiBjCgogICAgICBJZiB3ZSBkaWQgdGhlIHNhbWUgaW4gZGVjcnlwdGlvbiBtb2RlIHdlIHdvdWxkIGdldDoKCiAgICAgIHIxOiBhIGQgYyBiCiAgICAgIHIyOiBiIGEgZCBjCiAgICAgIHIzOiBjIGIgYSBkCiAgICAgIHI0OiBkIGMgYiBhCgogICAgICBJZiBpbnN0ZWFkIHdlIHN3YXAgZCBhbmQgYiAoc2V0IGI9YzMgYW5kIGQ9YzEpLCB0aGVuIHdlIGdldDoKCiAgICAgIHIxOiBhIGIgYyBkCiAgICAgIHIyOiBkIGEgYiBjCiAgICAgIHIzOiBjIGQgYSBiCiAgICAgIHI0OiBiIGMgZCBhCgogICAgICBOb3cgdGhlIDFzdCBhbmQgM3JkIHJvd3MgYXJlIHRoZSBzYW1lIGFzIHRoZSBlbmNyeXB0aW9uIG1hdHJpeC4gQWxsCiAgICAgIHdlIG5lZWQgdG8gZG8gdGhlbiB0byBtYWtlIHRoZSBtYXBwaW5nIGV4YWN0bHkgdGhlIHNhbWUgaXMgdG8gc3dhcAogICAgICB0aGUgMm5kIGFuZCA0dGggcm93cyB3aGVuIGluIGRlY3J5cHRpb24gbW9kZS4gVG8gZG8gdGhpcyB3aXRob3V0CiAgICAgIGhhdmluZyB0byBkbyBpdCBvbiBlYWNoIGl0ZXJhdGlvbiwgd2Ugc3dhcHBlZCB0aGUgMm5kIGFuZCA0dGggcm93cwogICAgICBpbiB0aGUgZGVjcnlwdGlvbiBrZXkgc2NoZWR1bGUuIFdlIGFsc28gaGF2ZSB0byBkbyB0aGUgc3dhcCBhYm92ZQogICAgICB3aGVuIHdlIGZpcnN0IHB1bGwgaW4gdGhlIGlucHV0IGFuZCB3aGVuIHdlIHNldCB0aGUgZmluYWwgb3V0cHV0LiAqLwogICAgYTIgPQogICAgICBtMFthID4+PiAyNF0gXgogICAgICBtMVtiID4+PiAxNiAmIDI1NV0gXgogICAgICBtMltjID4+PiA4ICYgMjU1XSBeCiAgICAgIG0zW2QgJiAyNTVdIF4gd1srK2ldOwogICAgYjIgPQogICAgICBtMFtiID4+PiAyNF0gXgogICAgICBtMVtjID4+PiAxNiAmIDI1NV0gXgogICAgICBtMltkID4+PiA4ICYgMjU1XSBeCiAgICAgIG0zW2EgJiAyNTVdIF4gd1srK2ldOwogICAgYzIgPQogICAgICBtMFtjID4+PiAyNF0gXgogICAgICBtMVtkID4+PiAxNiAmIDI1NV0gXgogICAgICBtMlthID4+PiA4ICYgMjU1XSBeCiAgICAgIG0zW2IgJiAyNTVdIF4gd1srK2ldOwogICAgZCA9CiAgICAgIG0wW2QgPj4+IDI0XSBeCiAgICAgIG0xW2EgPj4+IDE2ICYgMjU1XSBeCiAgICAgIG0yW2IgPj4+IDggJiAyNTVdIF4KICAgICAgbTNbYyAmIDI1NV0gXiB3WysraV07CiAgICBhID0gYTI7CiAgICBiID0gYjI7CiAgICBjID0gYzI7CiAgfQoKICAvKgogICAgRW5jcnlwdDoKICAgIFN1YkJ5dGVzKHN0YXRlKQogICAgU2hpZnRSb3dzKHN0YXRlKQogICAgQWRkUm91bmRLZXkoc3RhdGUsIHdbTnIqTmIsIChOcisxKSpOYi0xXSkKCiAgICBEZWNyeXB0OgogICAgSW52U2hpZnRSb3dzKHN0YXRlKQogICAgSW52U3ViQnl0ZXMoc3RhdGUpCiAgICBBZGRSb3VuZEtleShzdGF0ZSwgd1swLCBOYi0xXSkKICAgKi8KICAgLy8gTm90ZTogcm93cyBhcmUgc2hpZnRlZCBpbmxpbmUKICBvdXRwdXRbMF0gPQogICAgKHN1YlthID4+PiAyNF0gPDwgMjQpIF4KICAgIChzdWJbYiA+Pj4gMTYgJiAyNTVdIDw8IDE2KSBeCiAgICAoc3ViW2MgPj4+IDggJiAyNTVdIDw8IDgpIF4KICAgIChzdWJbZCAmIDI1NV0pIF4gd1srK2ldOwogIG91dHB1dFtkZWNyeXB0ID8gMyA6IDFdID0KICAgIChzdWJbYiA+Pj4gMjRdIDw8IDI0KSBeCiAgICAoc3ViW2MgPj4+IDE2ICYgMjU1XSA8PCAxNikgXgogICAgKHN1YltkID4+PiA4ICYgMjU1XSA8PCA4KSBeCiAgICAoc3ViW2EgJiAyNTVdKSBeIHdbKytpXTsKICBvdXRwdXRbMl0gPQogICAgKHN1YltjID4+PiAyNF0gPDwgMjQpIF4KICAgIChzdWJbZCA+Pj4gMTYgJiAyNTVdIDw8IDE2KSBeCiAgICAoc3ViW2EgPj4+IDggJiAyNTVdIDw8IDgpIF4KICAgIChzdWJbYiAmIDI1NV0pIF4gd1srK2ldOwogIG91dHB1dFtkZWNyeXB0ID8gMSA6IDNdID0KICAgIChzdWJbZCA+Pj4gMjRdIDw8IDI0KSBeCiAgICAoc3ViW2EgPj4+IDE2ICYgMjU1XSA8PCAxNikgXgogICAgKHN1YltiID4+PiA4ICYgMjU1XSA8PCA4KSBeCiAgICAoc3ViW2MgJiAyNTVdKSBeIHdbKytpXTsKfQoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogZm9yZ2UuY2lwaGVyLmNyZWF0ZUNpcGhlcignQUVTLTxtb2RlPicsIGtleSk7CiAqIGZvcmdlLmNpcGhlci5jcmVhdGVEZWNpcGhlcignQUVTLTxtb2RlPicsIGtleSk7CiAqCiAqIENyZWF0ZXMgYSBkZXByZWNhdGVkIEFFUyBjaXBoZXIgb2JqZWN0LiBUaGlzIG9iamVjdCdzIG1vZGUgd2lsbCBkZWZhdWx0IHRvCiAqIENCQyAoY2lwaGVyLWJsb2NrLWNoYWluaW5nKS4KICoKICogVGhlIGtleSBhbmQgaXYgbWF5IGJlIGdpdmVuIGFzIGEgc3RyaW5nIG9mIGJ5dGVzLCBhbiBhcnJheSBvZiBieXRlcywgYQogKiBieXRlIGJ1ZmZlciwgb3IgYW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLgogKgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UuCiAqICAgICAgICAgIG91dHB1dCB0aGUgYnVmZmVyIHRvIHdyaXRlIHRvLgogKiAgICAgICAgICBkZWNyeXB0IHRydWUgZm9yIGRlY3J5cHRpb24sIGZhbHNlIGZvciBlbmNyeXB0aW9uLgogKiAgICAgICAgICBtb2RlIHRoZSBjaXBoZXIgbW9kZSB0byB1c2UgKGRlZmF1bHQ6ICdDQkMnKS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZnVuY3Rpb24gX2NyZWF0ZUNpcGhlcihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdmFyIG1vZGUgPSAob3B0aW9ucy5tb2RlIHx8ICdDQkMnKS50b1VwcGVyQ2FzZSgpOwogIHZhciBhbGdvcml0aG0gPSAnQUVTLScgKyBtb2RlOwoKICB2YXIgY2lwaGVyOwogIGlmKG9wdGlvbnMuZGVjcnlwdCkgewogICAgY2lwaGVyID0gZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKGFsZ29yaXRobSwgb3B0aW9ucy5rZXkpOwogIH0gZWxzZSB7CiAgICBjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKGFsZ29yaXRobSwgb3B0aW9ucy5rZXkpOwogIH0KCiAgLy8gYmFja3dhcmRzIGNvbXBhdGlibGUgc3RhcnQgQVBJCiAgdmFyIHN0YXJ0ID0gY2lwaGVyLnN0YXJ0OwogIGNpcGhlci5zdGFydCA9IGZ1bmN0aW9uKGl2LCBvcHRpb25zKSB7CiAgICAvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eTogc3VwcG9ydCBzZWNvbmQgYXJnIGFzIG91dHB1dCBidWZmZXIKICAgIHZhciBvdXRwdXQgPSBudWxsOwogICAgaWYob3B0aW9ucyBpbnN0YW5jZW9mIGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcikgewogICAgICBvdXRwdXQgPSBvcHRpb25zOwogICAgICBvcHRpb25zID0ge307CiAgICB9CiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICAgIG9wdGlvbnMub3V0cHV0ID0gb3V0cHV0OwogICAgb3B0aW9ucy5pdiA9IGl2OwogICAgc3RhcnQuY2FsbChjaXBoZXIsIG9wdGlvbnMpOwogIH07CgogIHJldHVybiBjaXBoZXI7Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ2Flcyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKAogICdqcy9hZXMnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9jaXBoZXInLCAnLi9jaXBoZXJNb2RlcycsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogT2JqZWN0IElEcyBmb3IgQVNOLjEuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEzIERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UucGtpID0gZm9yZ2UucGtpIHx8IHt9Owp2YXIgb2lkcyA9IGZvcmdlLnBraS5vaWRzID0gZm9yZ2Uub2lkcyA9IGZvcmdlLm9pZHMgfHwge307CgovLyBhbGdvcml0aG0gT0lEcwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEuMSddID0gJ3JzYUVuY3J5cHRpb24nOwpvaWRzWydyc2FFbmNyeXB0aW9uJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xLjEnOwovLyBOb3RlOiBtZDIgJiBtZDQgbm90IGltcGxlbWVudGVkCi8vb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xLjInXSA9ICdtZDJXaXRoUlNBRW5jcnlwdGlvbic7Ci8vb2lkc1snbWQyV2l0aFJTQUVuY3J5cHRpb24nXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuMic7Ci8vb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xLjMnXSA9ICdtZDRXaXRoUlNBRW5jcnlwdGlvbic7Ci8vb2lkc1snbWQ0V2l0aFJTQUVuY3J5cHRpb24nXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuMyc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS40J10gPSAnbWQ1V2l0aFJTQUVuY3J5cHRpb24nOwpvaWRzWydtZDVXaXRoUlNBRW5jcnlwdGlvbiddID0gJzEuMi44NDAuMTEzNTQ5LjEuMS40JzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xLjUnXSA9ICdzaGExV2l0aFJTQUVuY3J5cHRpb24nOwpvaWRzWydzaGExV2l0aFJTQUVuY3J5cHRpb24nXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuNSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS43J10gPSAnUlNBRVMtT0FFUCc7Cm9pZHNbJ1JTQUVTLU9BRVAnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuNyc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS44J10gPSAnbWdmMSc7Cm9pZHNbJ21nZjEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuOCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS45J10gPSAncFNwZWNpZmllZCc7Cm9pZHNbJ3BTcGVjaWZpZWQnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuOSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS4xMCddID0gJ1JTQVNTQS1QU1MnOwpvaWRzWydSU0FTU0EtUFNTJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xLjEwJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xLjExJ10gPSAnc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24nOwpvaWRzWydzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbiddID0gJzEuMi44NDAuMTEzNTQ5LjEuMS4xMSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMS4xMiddID0gJ3NoYTM4NFdpdGhSU0FFbmNyeXB0aW9uJzsKb2lkc1snc2hhMzg0V2l0aFJTQUVuY3J5cHRpb24nXSA9ICcxLjIuODQwLjExMzU0OS4xLjEuMTInOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEuMTMnXSA9ICdzaGE1MTJXaXRoUlNBRW5jcnlwdGlvbic7Cm9pZHNbJ3NoYTUxMldpdGhSU0FFbmNyeXB0aW9uJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xLjEzJzsKCm9pZHNbJzEuMy4xNC4zLjIuNyddID0gJ2Rlc0NCQyc7Cm9pZHNbJ2Rlc0NCQyddID0gJzEuMy4xNC4zLjIuNyc7CgpvaWRzWycxLjMuMTQuMy4yLjI2J10gPSAnc2hhMSc7Cm9pZHNbJ3NoYTEnXSA9ICcxLjMuMTQuMy4yLjI2JzsKb2lkc1snMi4xNi44NDAuMS4xMDEuMy40LjIuMSddID0gJ3NoYTI1Nic7Cm9pZHNbJ3NoYTI1NiddID0gJzIuMTYuODQwLjEuMTAxLjMuNC4yLjEnOwpvaWRzWycyLjE2Ljg0MC4xLjEwMS4zLjQuMi4yJ10gPSAnc2hhMzg0JzsKb2lkc1snc2hhMzg0J10gPSAnMi4xNi44NDAuMS4xMDEuMy40LjIuMic7Cm9pZHNbJzIuMTYuODQwLjEuMTAxLjMuNC4yLjMnXSA9ICdzaGE1MTInOwpvaWRzWydzaGE1MTInXSA9ICcyLjE2Ljg0MC4xLjEwMS4zLjQuMi4zJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMi41J10gPSAnbWQ1JzsKb2lkc1snbWQ1J10gPSAnMS4yLjg0MC4xMTM1NDkuMi41JzsKCi8vIHBrY3MjNyBjb250ZW50IHR5cGVzCm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy4xJ10gPSAnZGF0YSc7Cm9pZHNbJ2RhdGEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjcuMSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy4yJ10gPSAnc2lnbmVkRGF0YSc7Cm9pZHNbJ3NpZ25lZERhdGEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjcuMic7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy4zJ10gPSAnZW52ZWxvcGVkRGF0YSc7Cm9pZHNbJ2VudmVsb3BlZERhdGEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjcuMyc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy40J10gPSAnc2lnbmVkQW5kRW52ZWxvcGVkRGF0YSc7Cm9pZHNbJ3NpZ25lZEFuZEVudmVsb3BlZERhdGEnXSA9ICcxLjIuODQwLjExMzU0OS4xLjcuNCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuNy41J10gPSAnZGlnZXN0ZWREYXRhJzsKb2lkc1snZGlnZXN0ZWREYXRhJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS43LjUnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjcuNiddID0gJ2VuY3J5cHRlZERhdGEnOwpvaWRzWydlbmNyeXB0ZWREYXRhJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS43LjYnOwoKLy8gcGtjcyM5IG9pZHMKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS45LjEnXSA9ICdlbWFpbEFkZHJlc3MnOwpvaWRzWydlbWFpbEFkZHJlc3MnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuMSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4yJ10gPSAndW5zdHJ1Y3R1cmVkTmFtZSc7Cm9pZHNbJ3Vuc3RydWN0dXJlZE5hbWUnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuMic7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4zJ10gPSAnY29udGVudFR5cGUnOwpvaWRzWydjb250ZW50VHlwZSddID0gJzEuMi44NDAuMTEzNTQ5LjEuOS4zJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS45LjQnXSA9ICdtZXNzYWdlRGlnZXN0JzsKb2lkc1snbWVzc2FnZURpZ2VzdCddID0gJzEuMi44NDAuMTEzNTQ5LjEuOS40JzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS45LjUnXSA9ICdzaWduaW5nVGltZSc7Cm9pZHNbJ3NpZ25pbmdUaW1lJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS45LjUnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjkuNiddID0gJ2NvdW50ZXJTaWduYXR1cmUnOwpvaWRzWydjb3VudGVyU2lnbmF0dXJlJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS45LjYnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjkuNyddID0gJ2NoYWxsZW5nZVBhc3N3b3JkJzsKb2lkc1snY2hhbGxlbmdlUGFzc3dvcmQnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuNyc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS44J10gPSAndW5zdHJ1Y3R1cmVkQWRkcmVzcyc7Cm9pZHNbJ3Vuc3RydWN0dXJlZEFkZHJlc3MnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuOCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4xNCddID0gJ2V4dGVuc2lvblJlcXVlc3QnOwpvaWRzWydleHRlbnNpb25SZXF1ZXN0J10gPSAnMS4yLjg0MC4xMTM1NDkuMS45LjE0JzsKCm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4yMCddID0gJ2ZyaWVuZGx5TmFtZSc7Cm9pZHNbJ2ZyaWVuZGx5TmFtZSddID0gJzEuMi44NDAuMTEzNTQ5LjEuOS4yMCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuOS4yMSddID0gJ2xvY2FsS2V5SWQnOwpvaWRzWydsb2NhbEtleUlkJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS45LjIxJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS45LjIyLjEnXSA9ICd4NTA5Q2VydGlmaWNhdGUnOwpvaWRzWyd4NTA5Q2VydGlmaWNhdGUnXSA9ICcxLjIuODQwLjExMzU0OS4xLjkuMjIuMSc7CgovLyBwa2NzIzEyIHNhZmUgYmFncwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEwLjEuMSddID0gJ2tleUJhZyc7Cm9pZHNbJ2tleUJhZyddID0gJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS4xJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xMi4xMC4xLjInXSA9ICdwa2NzOFNocm91ZGVkS2V5QmFnJzsKb2lkc1sncGtjczhTaHJvdWRlZEtleUJhZyddID0gJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS4yJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xMi4xMC4xLjMnXSA9ICdjZXJ0QmFnJzsKb2lkc1snY2VydEJhZyddID0gJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS4zJzsKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS4xMi4xMC4xLjQnXSA9ICdjcmxCYWcnOwpvaWRzWydjcmxCYWcnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEyLjEwLjEuNCc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS41J10gPSAnc2VjcmV0QmFnJzsKb2lkc1snc2VjcmV0QmFnJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xMi4xMC4xLjUnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEwLjEuNiddID0gJ3NhZmVDb250ZW50c0JhZyc7Cm9pZHNbJ3NhZmVDb250ZW50c0JhZyddID0gJzEuMi44NDAuMTEzNTQ5LjEuMTIuMTAuMS42JzsKCi8vIHBhc3N3b3JkLWJhc2VkLWVuY3J5cHRpb24gZm9yIHBrY3MjMTIKb2lkc1snMS4yLjg0MC4xMTM1NDkuMS41LjEzJ10gPSAncGtjczVQQkVTMic7Cm9pZHNbJ3BrY3M1UEJFUzInXSA9ICcxLjIuODQwLjExMzU0OS4xLjUuMTMnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjUuMTInXSA9ICdwa2NzNVBCS0RGMic7Cm9pZHNbJ3BrY3M1UEJLREYyJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS41LjEyJzsKCm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMTIuMS4xJ10gPSAncGJlV2l0aFNIQUFuZDEyOEJpdFJDNCc7Cm9pZHNbJ3BiZVdpdGhTSEFBbmQxMjhCaXRSQzQnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEyLjEuMSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMTIuMS4yJ10gPSAncGJlV2l0aFNIQUFuZDQwQml0UkM0JzsKb2lkc1sncGJlV2l0aFNIQUFuZDQwQml0UkM0J10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjInOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEuMyddID0gJ3BiZVdpdGhTSEFBbmQzLUtleVRyaXBsZURFUy1DQkMnOwpvaWRzWydwYmVXaXRoU0hBQW5kMy1LZXlUcmlwbGVERVMtQ0JDJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjMnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEuNCddID0gJ3BiZVdpdGhTSEFBbmQyLUtleVRyaXBsZURFUy1DQkMnOwpvaWRzWydwYmVXaXRoU0hBQW5kMi1LZXlUcmlwbGVERVMtQ0JDJ10gPSAnMS4yLjg0MC4xMTM1NDkuMS4xMi4xLjQnOwpvaWRzWycxLjIuODQwLjExMzU0OS4xLjEyLjEuNSddID0gJ3BiZVdpdGhTSEFBbmQxMjhCaXRSQzItQ0JDJzsKb2lkc1sncGJlV2l0aFNIQUFuZDEyOEJpdFJDMi1DQkMnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEyLjEuNSc7Cm9pZHNbJzEuMi44NDAuMTEzNTQ5LjEuMTIuMS42J10gPSAncGJld2l0aFNIQUFuZDQwQml0UkMyLUNCQyc7Cm9pZHNbJ3BiZXdpdGhTSEFBbmQ0MEJpdFJDMi1DQkMnXSA9ICcxLjIuODQwLjExMzU0OS4xLjEyLjEuNic7CgovLyBzeW1tZXRyaWMga2V5IGFsZ29yaXRobSBvaWRzCm9pZHNbJzEuMi44NDAuMTEzNTQ5LjMuNyddID0gJ2Rlcy1FREUzLUNCQyc7Cm9pZHNbJ2Rlcy1FREUzLUNCQyddID0gJzEuMi44NDAuMTEzNTQ5LjMuNyc7Cm9pZHNbJzIuMTYuODQwLjEuMTAxLjMuNC4xLjInXSA9ICdhZXMxMjgtQ0JDJzsKb2lkc1snYWVzMTI4LUNCQyddID0gJzIuMTYuODQwLjEuMTAxLjMuNC4xLjInOwpvaWRzWycyLjE2Ljg0MC4xLjEwMS4zLjQuMS4yMiddID0gJ2FlczE5Mi1DQkMnOwpvaWRzWydhZXMxOTItQ0JDJ10gPSAnMi4xNi44NDAuMS4xMDEuMy40LjEuMjInOwpvaWRzWycyLjE2Ljg0MC4xLjEwMS4zLjQuMS40MiddID0gJ2FlczI1Ni1DQkMnOwpvaWRzWydhZXMyNTYtQ0JDJ10gPSAnMi4xNi44NDAuMS4xMDEuMy40LjEuNDInOwoKLy8gY2VydGlmaWNhdGUgaXNzdWVyL3N1YmplY3QgT0lEcwpvaWRzWycyLjUuNC4zJ10gPSAnY29tbW9uTmFtZSc7Cm9pZHNbJ2NvbW1vbk5hbWUnXSA9ICcyLjUuNC4zJzsKb2lkc1snMi41LjQuNSddID0gJ3NlcmlhbE5hbWUnOwpvaWRzWydzZXJpYWxOYW1lJ10gPSAnMi41LjQuNSc7Cm9pZHNbJzIuNS40LjYnXSA9ICdjb3VudHJ5TmFtZSc7Cm9pZHNbJ2NvdW50cnlOYW1lJ10gPSAnMi41LjQuNic7Cm9pZHNbJzIuNS40LjcnXSA9ICdsb2NhbGl0eU5hbWUnOwpvaWRzWydsb2NhbGl0eU5hbWUnXSA9ICcyLjUuNC43JzsKb2lkc1snMi41LjQuOCddID0gJ3N0YXRlT3JQcm92aW5jZU5hbWUnOwpvaWRzWydzdGF0ZU9yUHJvdmluY2VOYW1lJ10gPSAnMi41LjQuOCc7Cm9pZHNbJzIuNS40LjEwJ10gPSAnb3JnYW5pemF0aW9uTmFtZSc7Cm9pZHNbJ29yZ2FuaXphdGlvbk5hbWUnXSA9ICcyLjUuNC4xMCc7Cm9pZHNbJzIuNS40LjExJ10gPSAnb3JnYW5pemF0aW9uYWxVbml0TmFtZSc7Cm9pZHNbJ29yZ2FuaXphdGlvbmFsVW5pdE5hbWUnXSA9ICcyLjUuNC4xMSc7CgovLyBYLjUwOSBleHRlbnNpb24gT0lEcwpvaWRzWycyLjE2Ljg0MC4xLjExMzczMC4xLjEnXSA9ICduc0NlcnRUeXBlJzsKb2lkc1snbnNDZXJ0VHlwZSddID0gJzIuMTYuODQwLjEuMTEzNzMwLjEuMSc7Cm9pZHNbJzIuNS4yOS4xJ10gPSAnYXV0aG9yaXR5S2V5SWRlbnRpZmllcic7IC8vIGRlcHJlY2F0ZWQsIHVzZSAuMzUKb2lkc1snMi41LjI5LjInXSA9ICdrZXlBdHRyaWJ1dGVzJzsgLy8gb2Jzb2xldGUgdXNlIC4zNyBvciAuMTUKb2lkc1snMi41LjI5LjMnXSA9ICdjZXJ0aWZpY2F0ZVBvbGljaWVzJzsgLy8gZGVwcmVjYXRlZCwgdXNlIC4zMgpvaWRzWycyLjUuMjkuNCddID0gJ2tleVVzYWdlUmVzdHJpY3Rpb24nOyAvLyBvYnNvbGV0ZSB1c2UgLjM3IG9yIC4xNQpvaWRzWycyLjUuMjkuNSddID0gJ3BvbGljeU1hcHBpbmcnOyAvLyBkZXByZWNhdGVkIHVzZSAuMzMKb2lkc1snMi41LjI5LjYnXSA9ICdzdWJ0cmVlc0NvbnN0cmFpbnQnOyAvLyBvYnNvbGV0ZSB1c2UgLjMwCm9pZHNbJzIuNS4yOS43J10gPSAnc3ViamVjdEFsdE5hbWUnOyAvLyBkZXByZWNhdGVkIHVzZSAuMTcKb2lkc1snMi41LjI5LjgnXSA9ICdpc3N1ZXJBbHROYW1lJzsgLy8gZGVwcmVjYXRlZCB1c2UgLjE4Cm9pZHNbJzIuNS4yOS45J10gPSAnc3ViamVjdERpcmVjdG9yeUF0dHJpYnV0ZXMnOwpvaWRzWycyLjUuMjkuMTAnXSA9ICdiYXNpY0NvbnN0cmFpbnRzJzsgLy8gZGVwcmVjYXRlZCB1c2UgLjE5Cm9pZHNbJzIuNS4yOS4xMSddID0gJ25hbWVDb25zdHJhaW50cyc7IC8vIGRlcHJlY2F0ZWQgdXNlIC4zMApvaWRzWycyLjUuMjkuMTInXSA9ICdwb2xpY3lDb25zdHJhaW50cyc7IC8vIGRlcHJlY2F0ZWQgdXNlIC4zNgpvaWRzWycyLjUuMjkuMTMnXSA9ICdiYXNpY0NvbnN0cmFpbnRzJzsgLy8gZGVwcmVjYXRlZCB1c2UgLjE5Cm9pZHNbJzIuNS4yOS4xNCddID0gJ3N1YmplY3RLZXlJZGVudGlmaWVyJzsKb2lkc1snc3ViamVjdEtleUlkZW50aWZpZXInXSA9ICcyLjUuMjkuMTQnOwpvaWRzWycyLjUuMjkuMTUnXSA9ICdrZXlVc2FnZSc7Cm9pZHNbJ2tleVVzYWdlJ10gPSAnMi41LjI5LjE1JzsKb2lkc1snMi41LjI5LjE2J10gPSAncHJpdmF0ZUtleVVzYWdlUGVyaW9kJzsKb2lkc1snMi41LjI5LjE3J10gPSAnc3ViamVjdEFsdE5hbWUnOwpvaWRzWydzdWJqZWN0QWx0TmFtZSddID0gJzIuNS4yOS4xNyc7Cm9pZHNbJzIuNS4yOS4xOCddID0gJ2lzc3VlckFsdE5hbWUnOwpvaWRzWydpc3N1ZXJBbHROYW1lJ10gPSAnMi41LjI5LjE4JzsKb2lkc1snMi41LjI5LjE5J10gPSAnYmFzaWNDb25zdHJhaW50cyc7Cm9pZHNbJ2Jhc2ljQ29uc3RyYWludHMnXSA9ICcyLjUuMjkuMTknOwpvaWRzWycyLjUuMjkuMjAnXSA9ICdjUkxOdW1iZXInOwpvaWRzWycyLjUuMjkuMjEnXSA9ICdjUkxSZWFzb24nOwpvaWRzWycyLjUuMjkuMjInXSA9ICdleHBpcmF0aW9uRGF0ZSc7Cm9pZHNbJzIuNS4yOS4yMyddID0gJ2luc3RydWN0aW9uQ29kZSc7Cm9pZHNbJzIuNS4yOS4yNCddID0gJ2ludmFsaWRpdHlEYXRlJzsKb2lkc1snMi41LjI5LjI1J10gPSAnY1JMRGlzdHJpYnV0aW9uUG9pbnRzJzsgLy8gZGVwcmVjYXRlZCB1c2UgLjMxCm9pZHNbJzIuNS4yOS4yNiddID0gJ2lzc3VpbmdEaXN0cmlidXRpb25Qb2ludCc7IC8vIGRlcHJlY2F0ZWQgdXNlIC4yOApvaWRzWycyLjUuMjkuMjcnXSA9ICdkZWx0YUNSTEluZGljYXRvcic7Cm9pZHNbJzIuNS4yOS4yOCddID0gJ2lzc3VpbmdEaXN0cmlidXRpb25Qb2ludCc7Cm9pZHNbJzIuNS4yOS4yOSddID0gJ2NlcnRpZmljYXRlSXNzdWVyJzsKb2lkc1snMi41LjI5LjMwJ10gPSAnbmFtZUNvbnN0cmFpbnRzJzsKb2lkc1snMi41LjI5LjMxJ10gPSAnY1JMRGlzdHJpYnV0aW9uUG9pbnRzJzsKb2lkc1snMi41LjI5LjMyJ10gPSAnY2VydGlmaWNhdGVQb2xpY2llcyc7Cm9pZHNbJzIuNS4yOS4zMyddID0gJ3BvbGljeU1hcHBpbmdzJzsKb2lkc1snMi41LjI5LjM0J10gPSAncG9saWN5Q29uc3RyYWludHMnOyAvLyBkZXByZWNhdGVkIHVzZSAuMzYKb2lkc1snMi41LjI5LjM1J10gPSAnYXV0aG9yaXR5S2V5SWRlbnRpZmllcic7Cm9pZHNbJzIuNS4yOS4zNiddID0gJ3BvbGljeUNvbnN0cmFpbnRzJzsKb2lkc1snMi41LjI5LjM3J10gPSAnZXh0S2V5VXNhZ2UnOwpvaWRzWydleHRLZXlVc2FnZSddID0gJzIuNS4yOS4zNyc7Cm9pZHNbJzIuNS4yOS40NiddID0gJ2ZyZXNoZXN0Q1JMJzsKb2lkc1snMi41LjI5LjU0J10gPSAnaW5oaWJpdEFueVBvbGljeSc7CgovLyBleHRLZXlVc2FnZSBwdXJwb3NlcwpvaWRzWycxLjMuNi4xLjUuNS43LjMuMSddID0gJ3NlcnZlckF1dGgnOwpvaWRzWydzZXJ2ZXJBdXRoJ10gPSAnMS4zLjYuMS41LjUuNy4zLjEnOwpvaWRzWycxLjMuNi4xLjUuNS43LjMuMiddID0gJ2NsaWVudEF1dGgnOwpvaWRzWydjbGllbnRBdXRoJ10gPSAnMS4zLjYuMS41LjUuNy4zLjInOwpvaWRzWycxLjMuNi4xLjUuNS43LjMuMyddID0gJ2NvZGVTaWduaW5nJzsKb2lkc1snY29kZVNpZ25pbmcnXSA9ICcxLjMuNi4xLjUuNS43LjMuMyc7Cm9pZHNbJzEuMy42LjEuNS41LjcuMy40J10gPSAnZW1haWxQcm90ZWN0aW9uJzsKb2lkc1snZW1haWxQcm90ZWN0aW9uJ10gPSAnMS4zLjYuMS41LjUuNy4zLjQnOwpvaWRzWycxLjMuNi4xLjUuNS43LjMuOCddID0gJ3RpbWVTdGFtcGluZyc7Cm9pZHNbJ3RpbWVTdGFtcGluZyddID0gJzEuMy42LjEuNS41LjcuMy44JzsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ29pZHMnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvb2lkcycsWydyZXF1aXJlJywgJ21vZHVsZSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIEFic3RyYWN0IFN5bnRheCBOb3RhdGlvbiBOdW1iZXIgT25lLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNSBEaWdpdGFsIEJhemFhciwgSW5jLgogKgogKiBBbiBBUEkgZm9yIHN0b3JpbmcgZGF0YSB1c2luZyB0aGUgQWJzdHJhY3QgU3ludGF4IE5vdGF0aW9uIE51bWJlciBPbmUKICogZm9ybWF0IHVzaW5nIERFUiAoRGlzdGluZ3Vpc2hlZCBFbmNvZGluZyBSdWxlcykgZW5jb2RpbmcuIFRoaXMgZW5jb2RpbmcgaXMKICogY29tbW9ubHkgdXNlZCB0byBzdG9yZSBkYXRhIGZvciBQS0ksIGkuZS4gWC41MDkgQ2VydGlmaWNhdGVzLCBhbmQgdGhpcwogKiBpbXBsZW1lbnRhdGlvbiBleGlzdHMgZm9yIHRoYXQgcHVycG9zZS4KICoKICogQWJzdHJhY3QgU3ludGF4IE5vdGF0aW9uIE51bWJlciBPbmUgKEFTTi4xKSBpcyB1c2VkIHRvIGRlZmluZSB0aGUgYWJzdHJhY3QKICogc3ludGF4IG9mIGluZm9ybWF0aW9uIHdpdGhvdXQgcmVzdHJpY3RpbmcgdGhlIHdheSB0aGUgaW5mb3JtYXRpb24gaXMgZW5jb2RlZAogKiBmb3IgdHJhbnNtaXNzaW9uLiBJdCBwcm92aWRlcyBhIHN0YW5kYXJkIHRoYXQgYWxsb3dzIGZvciBvcGVuIHN5c3RlbXMKICogY29tbXVuaWNhdGlvbi4gQVNOLjEgZGVmaW5lcyB0aGUgc3ludGF4IG9mIGluZm9ybWF0aW9uIGRhdGEgYW5kIGEgbnVtYmVyIG9mCiAqIHNpbXBsZSBkYXRhIHR5cGVzIGFzIHdlbGwgYXMgYSBub3RhdGlvbiBmb3IgZGVzY3JpYmluZyB0aGVtIGFuZCBzcGVjaWZ5aW5nCiAqIHZhbHVlcyBmb3IgdGhlbS4KICoKICogVGhlIFJTQSBhbGdvcml0aG0gY3JlYXRlcyBwdWJsaWMgYW5kIHByaXZhdGUga2V5cyB0aGF0IGFyZSBvZnRlbiBzdG9yZWQgaW4KICogWC41MDkgb3IgUEtDUyNYIGZvcm1hdHMgLS0gd2hpY2ggdXNlIEFTTi4xIChlbmNvZGVkIGluIERFUiBmb3JtYXQpLiBUaGlzCiAqIGNsYXNzIHByb3ZpZGVzIHRoZSBtb3N0IGJhc2ljIGZ1bmN0aW9uYWxpdHkgcmVxdWlyZWQgdG8gc3RvcmUgYW5kIGxvYWQgRFNBCiAqIGtleXMgdGhhdCBhcmUgZW5jb2RlZCBhY2NvcmRpbmcgdG8gQVNOLjEuCiAqCiAqIFRoZSBtb3N0IGNvbW1vbiBiaW5hcnkgZW5jb2RpbmdzIGZvciBBU04uMSBhcmUgQkVSIChCYXNpYyBFbmNvZGluZyBSdWxlcykKICogYW5kIERFUiAoRGlzdGluZ3Vpc2hlZCBFbmNvZGluZyBSdWxlcykuIERFUiBpcyBqdXN0IGEgc3Vic2V0IG9mIEJFUiB0aGF0CiAqIGhhcyBzdHJpY3RlciByZXF1aXJlbWVudHMgZm9yIGhvdyBkYXRhIG11c3QgYmUgZW5jb2RlZC4KICoKICogRWFjaCBBU04uMSBzdHJ1Y3R1cmUgaGFzIGEgdGFnIChhIGJ5dGUgaWRlbnRpZnlpbmcgdGhlIEFTTi4xIHN0cnVjdHVyZSB0eXBlKQogKiBhbmQgYSBieXRlIGFycmF5IGZvciB0aGUgdmFsdWUgb2YgdGhpcyBBU04xIHN0cnVjdHVyZSB3aGljaCBtYXkgYmUgZGF0YSBvciBhCiAqIGxpc3Qgb2YgQVNOLjEgc3RydWN0dXJlcy4KICoKICogRWFjaCBBU04uMSBzdHJ1Y3R1cmUgdXNpbmcgQkVSIGlzIChUYWctTGVuZ3RoLVZhbHVlKToKICoKICogfCBieXRlIDAgfCBieXRlcyBYIHwgYnl0ZXMgWSB8CiAqIHwtLS0tLS0tLXwtLS0tLS0tLS18LS0tLS0tLS0tLQogKiB8ICB0YWcgICB8IGxlbmd0aCAgfCAgdmFsdWUgIHwKICoKICogQVNOLjEgYWxsb3dzIGZvciB0YWdzIHRvIGJlIG9mICJIaWdoLXRhZy1udW1iZXIgZm9ybSIgd2hpY2ggYWxsb3dzIGEgdGFnIHRvCiAqIGJlIHR3byBvciBtb3JlIG9jdGV0cywgYnV0IHRoYXQgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIGNsYXNzLiBBIHRhZyBpcwogKiBvbmx5IDEgYnl0ZS4gQml0cyAxLTUgZ2l2ZSB0aGUgdGFnIG51bWJlciAoaWUgdGhlIGRhdGEgdHlwZSB3aXRoaW4gYQogKiBwYXJ0aWN1bGFyICdjbGFzcycpLCA2IGluZGljYXRlcyB3aGV0aGVyIG9yIG5vdCB0aGUgQVNOLjEgdmFsdWUgaXMKICogY29uc3RydWN0ZWQgZnJvbSBvdGhlciBBU04uMSB2YWx1ZXMsIGFuZCBiaXRzIDcgYW5kIDggZ2l2ZSB0aGUgJ2NsYXNzJy4gSWYKICogYml0cyA3IGFuZCA4IGFyZSBib3RoIHplcm8sIHRoZSBjbGFzcyBpcyBVTklWRVJTQUwuIElmIG9ubHkgYml0IDcgaXMgc2V0LAogKiB0aGVuIHRoZSBjbGFzcyBpcyBBUFBMSUNBVElPTi4gSWYgb25seSBiaXQgOCBpcyBzZXQsIHRoZW4gdGhlIGNsYXNzIGlzCiAqIENPTlRFWFRfU1BFQ0lGSUMuIElmIGJvdGggYml0cyA3IGFuZCA4IGFyZSBzZXQsIHRoZW4gdGhlIGNsYXNzIGlzIFBSSVZBVEUuCiAqIFRoZSB0YWcgbnVtYmVycyBmb3IgdGhlIGRhdGEgdHlwZXMgZm9yIHRoZSBjbGFzcyBVTklWRVJTQUwgYXJlIGxpc3RlZCBiZWxvdzoKICoKICogVU5JVkVSU0FMIDAgUmVzZXJ2ZWQgZm9yIHVzZSBieSB0aGUgZW5jb2RpbmcgcnVsZXMKICogVU5JVkVSU0FMIDEgQm9vbGVhbiB0eXBlCiAqIFVOSVZFUlNBTCAyIEludGVnZXIgdHlwZQogKiBVTklWRVJTQUwgMyBCaXRzdHJpbmcgdHlwZQogKiBVTklWRVJTQUwgNCBPY3RldHN0cmluZyB0eXBlCiAqIFVOSVZFUlNBTCA1IE51bGwgdHlwZQogKiBVTklWRVJTQUwgNiBPYmplY3QgaWRlbnRpZmllciB0eXBlCiAqIFVOSVZFUlNBTCA3IE9iamVjdCBkZXNjcmlwdG9yIHR5cGUKICogVU5JVkVSU0FMIDggRXh0ZXJuYWwgdHlwZSBhbmQgSW5zdGFuY2Utb2YgdHlwZQogKiBVTklWRVJTQUwgOSBSZWFsIHR5cGUKICogVU5JVkVSU0FMIDEwIEVudW1lcmF0ZWQgdHlwZQogKiBVTklWRVJTQUwgMTEgRW1iZWRkZWQtcGR2IHR5cGUKICogVU5JVkVSU0FMIDEyIFVURjhTdHJpbmcgdHlwZQogKiBVTklWRVJTQUwgMTMgUmVsYXRpdmUgb2JqZWN0IGlkZW50aWZpZXIgdHlwZQogKiBVTklWRVJTQUwgMTQtMTUgUmVzZXJ2ZWQgZm9yIGZ1dHVyZSBlZGl0aW9ucwogKiBVTklWRVJTQUwgMTYgU2VxdWVuY2UgYW5kIFNlcXVlbmNlLW9mIHR5cGVzCiAqIFVOSVZFUlNBTCAxNyBTZXQgYW5kIFNldC1vZiB0eXBlcwogKiBVTklWRVJTQUwgMTgtMjIsIDI1LTMwIENoYXJhY3RlciBzdHJpbmcgdHlwZXMKICogVU5JVkVSU0FMIDIzLTI0IFRpbWUgdHlwZXMKICoKICogVGhlIGxlbmd0aCBvZiBhbiBBU04uMSBzdHJ1Y3R1cmUgaXMgc3BlY2lmaWVkIGFmdGVyIHRoZSB0YWcgaWRlbnRpZmllci4KICogVGhlcmUgaXMgYSBkZWZpbml0ZSBmb3JtIGFuZCBhbiBpbmRlZmluaXRlIGZvcm0uIFRoZSBpbmRlZmluaXRlIGZvcm0gbWF5CiAqIGJlIHVzZWQgaWYgdGhlIGVuY29kaW5nIGlzIGNvbnN0cnVjdGVkIGFuZCBub3QgYWxsIGltbWVkaWF0ZWx5IGF2YWlsYWJsZS4KICogVGhlIGluZGVmaW5pdGUgZm9ybSBpcyBlbmNvZGVkIHVzaW5nIGEgbGVuZ3RoIGJ5dGUgd2l0aCBvbmx5IHRoZSA4dGggYml0CiAqIHNldC4gVGhlIGVuZCBvZiB0aGUgY29uc3RydWN0ZWQgb2JqZWN0IGlzIG1hcmtlZCB1c2luZyBlbmQtb2YtY29udGVudHMKICogb2N0ZXRzICh0d28gemVybyBieXRlcykuCiAqCiAqIFRoZSBkZWZpbml0ZSBmb3JtIGxvb2tzIGxpa2UgdGhpczoKICoKICogVGhlIGxlbmd0aCBtYXkgdGFrZSB1cCAxIG9yIG1vcmUgYnl0ZXMsIGl0IGRlcGVuZHMgb24gdGhlIGxlbmd0aCBvZiB0aGUKICogdmFsdWUgb2YgdGhlIEFTTi4xIHN0cnVjdHVyZS4gREVSIGVuY29kaW5nIHJlcXVpcmVzIHRoYXQgaWYgdGhlIEFTTi4xCiAqIHN0cnVjdHVyZSBoYXMgYSB2YWx1ZSB0aGF0IGhhcyBhIGxlbmd0aCBncmVhdGVyIHRoYW4gMTI3LCBtb3JlIHRoYW4gMSBieXRlCiAqIHdpbGwgYmUgdXNlZCB0byBzdG9yZSBpdHMgbGVuZ3RoLCBvdGhlcndpc2UganVzdCBvbmUgYnl0ZSB3aWxsIGJlIHVzZWQuCiAqIFRoaXMgaXMgc3RyaWN0LgogKgogKiBJbiB0aGUgY2FzZSB0aGF0IHRoZSBsZW5ndGggb2YgdGhlIEFTTi4xIHZhbHVlIGlzIGxlc3MgdGhhbiAxMjcsIDEgb2N0ZXQKICogKGJ5dGUpIGlzIHVzZWQgdG8gc3RvcmUgdGhlICJzaG9ydCBmb3JtIiBsZW5ndGguIFRoZSA4dGggYml0IGhhcyBhIHZhbHVlIG9mCiAqIDAgaW5kaWNhdGluZyB0aGUgbGVuZ3RoIGlzICJzaG9ydCBmb3JtIiBhbmQgbm90ICJsb25nIGZvcm0iIGFuZCBiaXRzIDctMQogKiBnaXZlIHRoZSBsZW5ndGggb2YgdGhlIGRhdGEuIChUaGUgOHRoIGJpdCBpcyB0aGUgbGVmdC1tb3N0LCBtb3N0IHNpZ25pZmljYW50CiAqIGJpdDogYWxzbyBrbm93biBhcyBiaWcgZW5kaWFuIG9yIG5ldHdvcmsgZm9ybWF0KS4KICoKICogSW4gdGhlIGNhc2UgdGhhdCB0aGUgbGVuZ3RoIG9mIHRoZSBBU04uMSB2YWx1ZSBpcyBncmVhdGVyIHRoYW4gMTI3LCAyIHRvCiAqIDEyNyBvY3RldHMgKGJ5dGVzKSBhcmUgdXNlZCB0byBzdG9yZSB0aGUgImxvbmcgZm9ybSIgbGVuZ3RoLiBUaGUgZmlyc3QKICogYnl0ZSdzIDh0aCBiaXQgaXMgc2V0IHRvIDEgdG8gaW5kaWNhdGUgdGhlIGxlbmd0aCBpcyAibG9uZyBmb3JtLiIgQml0cyA3LTEKICogZ2l2ZSB0aGUgbnVtYmVyIG9mIGFkZGl0aW9uYWwgb2N0ZXRzLiBBbGwgZm9sbG93aW5nIG9jdGV0cyBhcmUgaW4gYmFzZSAyNTYKICogd2l0aCB0aGUgbW9zdCBzaWduaWZpY2FudCBkaWdpdCBmaXJzdCAodHlwaWNhbCBiaWctZW5kaWFuIGJpbmFyeSB1bnNpZ25lZAogKiBpbnRlZ2VyIHN0b3JhZ2UpLiBTbywgZm9yIGluc3RhbmNlLCBpZiB0aGUgbGVuZ3RoIG9mIGEgdmFsdWUgd2FzIDI1NywgdGhlCiAqIGZpcnN0IGJ5dGUgd291bGQgYmUgc2V0IHRvOgogKgogKiAxMDAwMDAxMCA9IDEzMCA9IDB4ODIuCiAqCiAqIFRoaXMgaW5kaWNhdGVzIHRoZXJlIGFyZSAyIG9jdGV0cyAoYmFzZSAyNTYpIGZvciB0aGUgbGVuZ3RoLiBUaGUgc2Vjb25kIGFuZAogKiB0aGlyZCBieXRlcyAodGhlIG9jdGV0cyBqdXN0IG1lbnRpb25lZCkgd291bGQgc3RvcmUgdGhlIGxlbmd0aCBpbiBiYXNlIDI1NjoKICoKICogb2N0ZXQgMjogMDAwMDAwMDEgPSAxICogMjU2XjEgPSAyNTYKICogb2N0ZXQgMzogMDAwMDAwMDEgPSAxICogMjU2XjAgPSAxCiAqIHRvdGFsID0gMjU3CiAqCiAqIFRoZSBhbGdvcml0aG0gZm9yIGNvbnZlcnRpbmcgYSBqcyBpbnRlZ2VyIHZhbHVlIG9mIDI1NyB0byBiYXNlLTI1NiBpczoKICoKICogdmFyIHZhbHVlID0gMjU3OwogKiB2YXIgYnl0ZXMgPSBbXTsKICogYnl0ZXNbMF0gPSAodmFsdWUgPj4+IDgpICYgMHhGRjsgLy8gbW9zdCBzaWduaWZpY2FudCBieXRlIGZpcnN0CiAqIGJ5dGVzWzFdID0gdmFsdWUgJiAweEZGOyAgICAgICAgLy8gbGVhc3Qgc2lnbmlmaWNhbnQgYnl0ZSBsYXN0CiAqCiAqIE9uIHRoZSBBU04uMSBVTklWRVJTQUwgT2JqZWN0IElkZW50aWZpZXIgKE9JRCkgdHlwZToKICoKICogQW4gT0lEIGNhbiBiZSB3cml0dGVuIGxpa2U6ICJ2YWx1ZTEudmFsdWUyLnZhbHVlMy4uLnZhbHVlTiIKICoKICogVGhlIERFUiBlbmNvZGluZyBydWxlczoKICoKICogVGhlIGZpcnN0IGJ5dGUgaGFzIHRoZSB2YWx1ZSA0MCAqIHZhbHVlMSArIHZhbHVlMi4KICogVGhlIGZvbGxvd2luZyBieXRlcywgaWYgYW55LCBlbmNvZGUgdGhlIHJlbWFpbmluZyB2YWx1ZXMuIEVhY2ggdmFsdWUgaXMKICogZW5jb2RlZCBpbiBiYXNlIDEyOCwgbW9zdCBzaWduaWZpY2FudCBkaWdpdCBmaXJzdCAoYmlnIGVuZGlhbiksIHdpdGggYXMKICogZmV3IGRpZ2l0cyBhcyBwb3NzaWJsZSwgYW5kIHRoZSBtb3N0IHNpZ25pZmljYW50IGJpdCBvZiBlYWNoIGJ5dGUgc2V0CiAqIHRvIDEgZXhjZXB0IHRoZSBsYXN0IGluIGVhY2ggdmFsdWUncyBlbmNvZGluZy4gRm9yIGV4YW1wbGU6IEdpdmVuIHRoZQogKiBPSUQgIjEuMi44NDAuMTEzNTQ5IiwgaXRzIERFUiBlbmNvZGluZyBpcyAocmVtZW1iZXIgZWFjaCBieXRlIGV4Y2VwdCB0aGUKICogbGFzdCBvbmUgaW4gZWFjaCBlbmNvZGluZyBpcyBPUidkIHdpdGggMHg4MCk6CiAqCiAqIGJ5dGUgMTogNDAgKiAxICsgMiA9IDQyID0gMHgyQS4KICogYnl0ZXMgMi0zOiAxMjggKiA2ICsgNzIgPSA4NDAgPSA2IDcyID0gNiA3MiA9IDB4MDY0OCA9IDB4ODY0OAogKiBieXRlcyA0LTY6IDE2Mzg0ICogNiArIDEyOCAqIDExOSArIDEzID0gNiAxMTkgMTMgPSAweDA2NzcwRCA9IDB4ODZGNzBECiAqCiAqIFRoZSBmaW5hbCB2YWx1ZSBpczogMHgyQTg2NDg4NkY3MEQuCiAqIFRoZSBmdWxsIE9JRCAoaW5jbHVkaW5nIEFTTi4xIHRhZyBhbmQgbGVuZ3RoIG9mIDYgYnl0ZXMpIGlzOgogKiAweDA2MDYyQTg2NDg4NkY3MEQKICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovKiBBU04uMSBBUEkgKi8KdmFyIGFzbjEgPSBmb3JnZS5hc24xID0gZm9yZ2UuYXNuMSB8fCB7fTsKCi8qKgogKiBBU04uMSBjbGFzc2VzLgogKi8KYXNuMS5DbGFzcyA9IHsKICBVTklWRVJTQUw6ICAgICAgICAweDAwLAogIEFQUExJQ0FUSU9OOiAgICAgIDB4NDAsCiAgQ09OVEVYVF9TUEVDSUZJQzogMHg4MCwKICBQUklWQVRFOiAgICAgICAgICAweEMwCn07CgovKioKICogQVNOLjEgdHlwZXMuIE5vdCBhbGwgdHlwZXMgYXJlIHN1cHBvcnRlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uLCBvbmx5CiAqIHRob3NlIG5lY2Vzc2FyeSB0byBpbXBsZW1lbnQgYSBzaW1wbGUgUEtJIGFyZSBpbXBsZW1lbnRlZC4KICovCmFzbjEuVHlwZSA9IHsKICBOT05FOiAgICAgICAgICAgICAwLAogIEJPT0xFQU46ICAgICAgICAgIDEsCiAgSU5URUdFUjogICAgICAgICAgMiwKICBCSVRTVFJJTkc6ICAgICAgICAzLAogIE9DVEVUU1RSSU5HOiAgICAgIDQsCiAgTlVMTDogICAgICAgICAgICAgNSwKICBPSUQ6ICAgICAgICAgICAgICA2LAogIE9ERVNDOiAgICAgICAgICAgIDcsCiAgRVhURVJOQUw6ICAgICAgICAgOCwKICBSRUFMOiAgICAgICAgICAgICA5LAogIEVOVU1FUkFURUQ6ICAgICAgMTAsCiAgRU1CRURERUQ6ICAgICAgICAxMSwKICBVVEY4OiAgICAgICAgICAgIDEyLAogIFJPSUQ6ICAgICAgICAgICAgMTMsCiAgU0VRVUVOQ0U6ICAgICAgICAxNiwKICBTRVQ6ICAgICAgICAgICAgIDE3LAogIFBSSU5UQUJMRVNUUklORzogMTksCiAgSUE1U1RSSU5HOiAgICAgICAyMiwKICBVVENUSU1FOiAgICAgICAgIDIzLAogIEdFTkVSQUxJWkVEVElNRTogMjQsCiAgQk1QU1RSSU5HOiAgICAgICAzMAp9OwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgYXNuMSBvYmplY3QuCiAqCiAqIEBwYXJhbSB0YWdDbGFzcyB0aGUgdGFnIGNsYXNzIGZvciB0aGUgb2JqZWN0LgogKiBAcGFyYW0gdHlwZSB0aGUgZGF0YSB0eXBlICh0YWcgbnVtYmVyKSBmb3IgdGhlIG9iamVjdC4KICogQHBhcmFtIGNvbnN0cnVjdGVkIHRydWUgaWYgdGhlIGFzbjEgb2JqZWN0IGlzIGluIGNvbnN0cnVjdGVkIGZvcm0uCiAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgZm9yIHRoZSBvYmplY3QsIGlmIGl0IGlzIG5vdCBjb25zdHJ1Y3RlZC4KICoKICogQHJldHVybiB0aGUgYXNuMSBvYmplY3QuCiAqLwphc24xLmNyZWF0ZSA9IGZ1bmN0aW9uKHRhZ0NsYXNzLCB0eXBlLCBjb25zdHJ1Y3RlZCwgdmFsdWUpIHsKICAvKiBBbiBhc24xIG9iamVjdCBoYXMgYSB0YWdDbGFzcywgYSB0eXBlLCBhIGNvbnN0cnVjdGVkIGZsYWcsIGFuZCBhCiAgICB2YWx1ZS4gVGhlIHZhbHVlJ3MgdHlwZSBkZXBlbmRzIG9uIHRoZSBjb25zdHJ1Y3RlZCBmbGFnLiBJZgogICAgY29uc3RydWN0ZWQsIGl0IHdpbGwgY29udGFpbiBhIGxpc3Qgb2Ygb3RoZXIgYXNuMSBvYmplY3RzLiBJZiBub3QsCiAgICBpdCB3aWxsIGNvbnRhaW4gdGhlIEFTTi4xIHZhbHVlIGFzIGFuIGFycmF5IG9mIGJ5dGVzIGZvcm1hdHRlZAogICAgYWNjb3JkaW5nIHRvIHRoZSBBU04uMSBkYXRhIHR5cGUuICovCgogIC8vIHJlbW92ZSB1bmRlZmluZWQgdmFsdWVzCiAgaWYoZm9yZ2UudXRpbC5pc0FycmF5KHZhbHVlKSkgewogICAgdmFyIHRtcCA9IFtdOwogICAgZm9yKHZhciBpID0gMDsgaSA8IHZhbHVlLmxlbmd0aDsgKytpKSB7CiAgICAgIGlmKHZhbHVlW2ldICE9PSB1bmRlZmluZWQpIHsKICAgICAgICB0bXAucHVzaCh2YWx1ZVtpXSk7CiAgICAgIH0KICAgIH0KICAgIHZhbHVlID0gdG1wOwogIH0KCiAgcmV0dXJuIHsKICAgIHRhZ0NsYXNzOiB0YWdDbGFzcywKICAgIHR5cGU6IHR5cGUsCiAgICBjb25zdHJ1Y3RlZDogY29uc3RydWN0ZWQsCiAgICBjb21wb3NlZDogY29uc3RydWN0ZWQgfHwgZm9yZ2UudXRpbC5pc0FycmF5KHZhbHVlKSwKICAgIHZhbHVlOiB2YWx1ZQogIH07Cn07CgovKioKICogR2V0cyB0aGUgbGVuZ3RoIG9mIGEgQkVSLWVuY29kZWQgQVNOLjEgdmFsdWUuCiAqCiAqIEluIGNhc2UgdGhlIGxlbmd0aCBpcyBub3Qgc3BlY2lmaWVkLCB1bmRlZmluZWQgaXMgcmV0dXJuZWQuCiAqCiAqIEBwYXJhbSBiIHRoZSBCRVItZW5jb2RlZCBBU04uMSBieXRlIGJ1ZmZlciwgc3RhcnRpbmcgd2l0aCB0aGUgZmlyc3QKICogICAgICAgICAgbGVuZ3RoIGJ5dGUuCiAqCiAqIEByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgQkVSLWVuY29kZWQgQVNOLjEgdmFsdWUgb3IgdW5kZWZpbmVkLgogKi8KdmFyIF9nZXRWYWx1ZUxlbmd0aCA9IGFzbjEuZ2V0QmVyVmFsdWVMZW5ndGggPSBmdW5jdGlvbihiKSB7CiAgLy8gVE9ETzogbW92ZSB0aGlzIGZ1bmN0aW9uIGFuZCByZWxhdGVkIERFUi9CRVIgZnVuY3Rpb25zIHRvIGEgZGVyLmpzCiAgLy8gZmlsZTsgYmV0dGVyIGFic3RyYWN0IEFTTi4xIGF3YXkgZnJvbSBkZXIvYmVyLgogIHZhciBiMiA9IGIuZ2V0Qnl0ZSgpOwogIGlmKGIyID09PSAweDgwKSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0KCiAgLy8gc2VlIGlmIHRoZSBsZW5ndGggaXMgInNob3J0IGZvcm0iIG9yICJsb25nIGZvcm0iIChiaXQgOCBzZXQpCiAgdmFyIGxlbmd0aDsKICB2YXIgbG9uZ0Zvcm0gPSBiMiAmIDB4ODA7CiAgaWYoIWxvbmdGb3JtKSB7CiAgICAvLyBsZW5ndGggaXMganVzdCB0aGUgZmlyc3QgYnl0ZQogICAgbGVuZ3RoID0gYjI7CiAgfSBlbHNlIHsKICAgIC8vIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhlIGxlbmd0aCBpcyBzcGVjaWZpZWQgaW4gYml0cyA3IHRocm91Z2ggMQogICAgLy8gYW5kIGVhY2ggbGVuZ3RoIGJ5dGUgaXMgaW4gYmlnLWVuZGlhbiBiYXNlLTI1NgogICAgbGVuZ3RoID0gYi5nZXRJbnQoKGIyICYgMHg3RikgPDwgMyk7CiAgfQogIHJldHVybiBsZW5ndGg7Cn07CgovKioKICogUGFyc2VzIGFuIGFzbjEgb2JqZWN0IGZyb20gYSBieXRlIGJ1ZmZlciBpbiBERVIgZm9ybWF0LgogKgogKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYnVmZmVyIHRvIHBhcnNlIGZyb20uCiAqIEBwYXJhbSBzdHJpY3QgdHJ1ZSB0byBiZSBzdHJpY3Qgd2hlbiBjaGVja2luZyB2YWx1ZSBsZW5ndGhzLCBmYWxzZSB0bwogKiAgICAgICAgICBhbGxvdyB0cnVuY2F0ZWQgdmFsdWVzIChkZWZhdWx0OiB0cnVlKS4KICoKICogQHJldHVybiB0aGUgcGFyc2VkIGFzbjEgb2JqZWN0LgogKi8KYXNuMS5mcm9tRGVyID0gZnVuY3Rpb24oYnl0ZXMsIHN0cmljdCkgewogIGlmKHN0cmljdCA9PT0gdW5kZWZpbmVkKSB7CiAgICBzdHJpY3QgPSB0cnVlOwogIH0KCiAgLy8gd3JhcCBpbiBidWZmZXIgaWYgbmVlZGVkCiAgaWYodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykgewogICAgYnl0ZXMgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihieXRlcyk7CiAgfQoKICAvLyBtaW5pbXVtIGxlbmd0aCBmb3IgQVNOLjEgREVSIHN0cnVjdHVyZSBpcyAyCiAgaWYoYnl0ZXMubGVuZ3RoKCkgPCAyKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1RvbyBmZXcgYnl0ZXMgdG8gcGFyc2UgREVSLicpOwogICAgZXJyb3IuYnl0ZXMgPSBieXRlcy5sZW5ndGgoKTsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gZ2V0IHRoZSBmaXJzdCBieXRlCiAgdmFyIGIxID0gYnl0ZXMuZ2V0Qnl0ZSgpOwoKICAvLyBnZXQgdGhlIHRhZyBjbGFzcwogIHZhciB0YWdDbGFzcyA9IChiMSAmIDB4QzApOwoKICAvLyBnZXQgdGhlIHR5cGUgKGJpdHMgMS01KQogIHZhciB0eXBlID0gYjEgJiAweDFGOwoKICAvLyBnZXQgdGhlIHZhbHVlIGxlbmd0aAogIHZhciBsZW5ndGggPSBfZ2V0VmFsdWVMZW5ndGgoYnl0ZXMpOwoKICAvLyBlbnN1cmUgdGhlcmUgYXJlIGVub3VnaCBieXRlcyB0byBnZXQgdGhlIHZhbHVlCiAgaWYoYnl0ZXMubGVuZ3RoKCkgPCBsZW5ndGgpIHsKICAgIGlmKHN0cmljdCkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1RvbyBmZXcgYnl0ZXMgdG8gcmVhZCBBU04uMSB2YWx1ZS4nKTsKICAgICAgZXJyb3IuZGV0YWlsID0gYnl0ZXMubGVuZ3RoKCkgKyAnIDwgJyArIGxlbmd0aDsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CiAgICAvLyBOb3RlOiBiZSBsZW5pZW50IHdpdGggdHJ1bmNhdGVkIHZhbHVlcwogICAgbGVuZ3RoID0gYnl0ZXMubGVuZ3RoKCk7CiAgfQoKICAvLyBwcmVwYXJlIHRvIGdldCB2YWx1ZQogIHZhciB2YWx1ZTsKCiAgLy8gY29uc3RydWN0ZWQgZmxhZyBpcyBiaXQgNiAoMzIgPSAweDIwKSBvZiB0aGUgZmlyc3QgYnl0ZQogIHZhciBjb25zdHJ1Y3RlZCA9ICgoYjEgJiAweDIwKSA9PT0gMHgyMCk7CgogIC8vIGRldGVybWluZSBpZiB0aGUgdmFsdWUgaXMgY29tcG9zZWQgb2Ygb3RoZXIgQVNOLjEgb2JqZWN0cyAoaWYgaXRzCiAgLy8gY29uc3RydWN0ZWQgaXQgd2lsbCBiZSBhbmQgaWYgaXRzIGEgQklUU1RSSU5HIGl0IG1heSBiZSkKICB2YXIgY29tcG9zZWQgPSBjb25zdHJ1Y3RlZDsKICBpZighY29tcG9zZWQgJiYgdGFnQ2xhc3MgPT09IGFzbjEuQ2xhc3MuVU5JVkVSU0FMICYmCiAgICB0eXBlID09PSBhc24xLlR5cGUuQklUU1RSSU5HICYmIGxlbmd0aCA+IDEpIHsKICAgIC8qIFRoZSBmaXJzdCBvY3RldCBnaXZlcyB0aGUgbnVtYmVyIG9mIGJpdHMgYnkgd2hpY2ggdGhlIGxlbmd0aCBvZiB0aGUKICAgICAgYml0IHN0cmluZyBpcyBsZXNzIHRoYW4gdGhlIG5leHQgbXVsdGlwbGUgb2YgZWlnaHQgKHRoaXMgaXMgY2FsbGVkCiAgICAgIHRoZSAibnVtYmVyIG9mIHVudXNlZCBiaXRzIikuCgogICAgICBUaGUgc2Vjb25kIGFuZCBmb2xsb3dpbmcgb2N0ZXRzIGdpdmUgdGhlIHZhbHVlIG9mIHRoZSBiaXQgc3RyaW5nCiAgICAgIGNvbnZlcnRlZCB0byBhbiBvY3RldCBzdHJpbmcuICovCiAgICAvLyBpZiB0aGVyZSBhcmUgbm8gdW51c2VkIGJpdHMsIG1heWJlIHRoZSBiaXRzdHJpbmcgaG9sZHMgQVNOLjEgb2JqcwogICAgdmFyIHJlYWQgPSBieXRlcy5yZWFkOwogICAgdmFyIHVudXNlZCA9IGJ5dGVzLmdldEJ5dGUoKTsKICAgIGlmKHVudXNlZCA9PT0gMCkgewogICAgICAvLyBpZiB0aGUgZmlyc3QgYnl0ZSBpbmRpY2F0ZXMgVU5JVkVSU0FMIG9yIENPTlRFWFRfU1BFQ0lGSUMsCiAgICAgIC8vIGFuZCB0aGUgbGVuZ3RoIGlzIHZhbGlkLCBhc3N1bWUgd2UndmUgZ290IGFuIEFTTi4xIG9iamVjdAogICAgICBiMSA9IGJ5dGVzLmdldEJ5dGUoKTsKICAgICAgdmFyIHRjID0gKGIxICYgMHhDMCk7CiAgICAgIGlmKHRjID09PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fCB0YyA9PT0gYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIHZhciBsZW4gPSBfZ2V0VmFsdWVMZW5ndGgoYnl0ZXMpOwogICAgICAgICAgY29tcG9zZWQgPSAobGVuID09PSBsZW5ndGggLSAoYnl0ZXMucmVhZCAtIHJlYWQpKTsKICAgICAgICAgIGlmKGNvbXBvc2VkKSB7CiAgICAgICAgICAgIC8vIGFkanVzdCByZWFkL2xlbmd0aCB0byBhY2NvdW50IGZvciB1bnVzZWQgYml0cyBieXRlCiAgICAgICAgICAgICsrcmVhZDsKICAgICAgICAgICAgLS1sZW5ndGg7CiAgICAgICAgICB9CiAgICAgICAgfSBjYXRjaChleCkge30KICAgICAgfQogICAgfQogICAgLy8gcmVzdG9yZSByZWFkIHBvaW50ZXIKICAgIGJ5dGVzLnJlYWQgPSByZWFkOwogIH0KCiAgaWYoY29tcG9zZWQpIHsKICAgIC8vIHBhcnNlIGNoaWxkIGFzbjEgb2JqZWN0cyBmcm9tIHRoZSB2YWx1ZQogICAgdmFsdWUgPSBbXTsKICAgIGlmKGxlbmd0aCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIC8vIGFzbjEgb2JqZWN0IG9mIGluZGVmaW5pdGUgbGVuZ3RoLCByZWFkIHVudGlsIGVuZCB0YWcKICAgICAgZm9yKDs7KSB7CiAgICAgICAgaWYoYnl0ZXMuYnl0ZXMoMikgPT09IFN0cmluZy5mcm9tQ2hhckNvZGUoMCwgMCkpIHsKICAgICAgICAgIGJ5dGVzLmdldEJ5dGVzKDIpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHZhbHVlLnB1c2goYXNuMS5mcm9tRGVyKGJ5dGVzLCBzdHJpY3QpKTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgLy8gcGFyc2luZyBhc24xIG9iamVjdCBvZiBkZWZpbml0ZSBsZW5ndGgKICAgICAgdmFyIHN0YXJ0ID0gYnl0ZXMubGVuZ3RoKCk7CiAgICAgIHdoaWxlKGxlbmd0aCA+IDApIHsKICAgICAgICB2YWx1ZS5wdXNoKGFzbjEuZnJvbURlcihieXRlcywgc3RyaWN0KSk7CiAgICAgICAgbGVuZ3RoIC09IHN0YXJ0IC0gYnl0ZXMubGVuZ3RoKCk7CiAgICAgICAgc3RhcnQgPSBieXRlcy5sZW5ndGgoKTsKICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICAvLyBhc24xIG5vdCBjb21wb3NlZCwgZ2V0IHJhdyB2YWx1ZQogICAgLy8gVE9ETzogZG8gREVSIHRvIE9JRCBjb252ZXJzaW9uIGFuZCB2aWNlLXZlcnNhIGluIC50b0Rlcj8KCiAgICBpZihsZW5ndGggPT09IHVuZGVmaW5lZCkgewogICAgICBpZihzdHJpY3QpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vbi1jb25zdHJ1Y3RlZCBBU04uMSBvYmplY3Qgb2YgaW5kZWZpbml0ZSBsZW5ndGguJyk7CiAgICAgIH0KICAgICAgLy8gYmUgbGVuaWVudCBhbmQgdXNlIHJlbWFpbmluZyBieXRlcwogICAgICBsZW5ndGggPSBieXRlcy5sZW5ndGgoKTsKICAgIH0KCiAgICBpZih0eXBlID09PSBhc24xLlR5cGUuQk1QU1RSSU5HKSB7CiAgICAgIHZhbHVlID0gJyc7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBsZW5ndGg7IGkgKz0gMikgewogICAgICAgIHZhbHVlICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYnl0ZXMuZ2V0SW50MTYoKSk7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHZhbHVlID0gYnl0ZXMuZ2V0Qnl0ZXMobGVuZ3RoKTsKICAgIH0KICB9CgogIC8vIGNyZWF0ZSBhbmQgcmV0dXJuIGFzbjEgb2JqZWN0CiAgcmV0dXJuIGFzbjEuY3JlYXRlKHRhZ0NsYXNzLCB0eXBlLCBjb25zdHJ1Y3RlZCwgdmFsdWUpOwp9OwoKLyoqCiAqIENvbnZlcnRzIHRoZSBnaXZlbiBhc24xIG9iamVjdCB0byBhIGJ1ZmZlciBvZiBieXRlcyBpbiBERVIgZm9ybWF0LgogKgogKiBAcGFyYW0gYXNuMSB0aGUgYXNuMSBvYmplY3QgdG8gY29udmVydCB0byBieXRlcy4KICoKICogQHJldHVybiB0aGUgYnVmZmVyIG9mIGJ5dGVzLgogKi8KYXNuMS50b0RlciA9IGZ1bmN0aW9uKG9iaikgewogIHZhciBieXRlcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIGJ1aWxkIHRoZSBmaXJzdCBieXRlCiAgdmFyIGIxID0gb2JqLnRhZ0NsYXNzIHwgb2JqLnR5cGU7CgogIC8vIGZvciBzdG9yaW5nIHRoZSBBU04uMSB2YWx1ZQogIHZhciB2YWx1ZSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIGlmIGNvbXBvc2VkLCB1c2UgZWFjaCBjaGlsZCBhc24xIG9iamVjdCdzIERFUiBieXRlcyBhcyB2YWx1ZQogIGlmKG9iai5jb21wb3NlZCkgewogICAgLy8gdHVybiBvbiA2dGggYml0ICgweDIwID0gMzIpIHRvIGluZGljYXRlIGFzbjEgaXMgY29uc3RydWN0ZWQKICAgIC8vIGZyb20gb3RoZXIgYXNuMSBvYmplY3RzCiAgICBpZihvYmouY29uc3RydWN0ZWQpIHsKICAgICAgYjEgfD0gMHgyMDsKICAgIH0gZWxzZSB7CiAgICAgIC8vIHR5cGUgaXMgYSBiaXQgc3RyaW5nLCBhZGQgdW51c2VkIGJpdHMgb2YgMHgwMAogICAgICB2YWx1ZS5wdXRCeXRlKDB4MDApOwogICAgfQoKICAgIC8vIGFkZCBhbGwgb2YgdGhlIGNoaWxkIERFUiBieXRlcyB0b2dldGhlcgogICAgZm9yKHZhciBpID0gMDsgaSA8IG9iai52YWx1ZS5sZW5ndGg7ICsraSkgewogICAgICBpZihvYmoudmFsdWVbaV0gIT09IHVuZGVmaW5lZCkgewogICAgICAgIHZhbHVlLnB1dEJ1ZmZlcihhc24xLnRvRGVyKG9iai52YWx1ZVtpXSkpOwogICAgICB9CiAgICB9CiAgfSBlbHNlIHsKICAgIC8vIHVzZSBhc24xLnZhbHVlIGRpcmVjdGx5CiAgICBpZihvYmoudHlwZSA9PT0gYXNuMS5UeXBlLkJNUFNUUklORykgewogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgb2JqLnZhbHVlLmxlbmd0aDsgKytpKSB7CiAgICAgICAgdmFsdWUucHV0SW50MTYob2JqLnZhbHVlLmNoYXJDb2RlQXQoaSkpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICB2YWx1ZS5wdXRCeXRlcyhvYmoudmFsdWUpOwogICAgfQogIH0KCiAgLy8gYWRkIHRhZyBieXRlCiAgYnl0ZXMucHV0Qnl0ZShiMSk7CgogIC8vIHVzZSAic2hvcnQgZm9ybSIgZW5jb2RpbmcKICBpZih2YWx1ZS5sZW5ndGgoKSA8PSAxMjcpIHsKICAgIC8vIG9uZSBieXRlIGRlc2NyaWJlcyB0aGUgbGVuZ3RoCiAgICAvLyBiaXQgOCA9IDAgYW5kIGJpdHMgNy0xID0gbGVuZ3RoCiAgICBieXRlcy5wdXRCeXRlKHZhbHVlLmxlbmd0aCgpICYgMHg3Rik7CiAgfSBlbHNlIHsKICAgIC8vIHVzZSAibG9uZyBmb3JtIiBlbmNvZGluZwogICAgLy8gMiB0byAxMjcgYnl0ZXMgZGVzY3JpYmUgdGhlIGxlbmd0aAogICAgLy8gZmlyc3QgYnl0ZTogYml0IDggPSAxIGFuZCBiaXRzIDctMSA9ICMgb2YgYWRkaXRpb25hbCBieXRlcwogICAgLy8gb3RoZXIgYnl0ZXM6IGxlbmd0aCBpbiBiYXNlIDI1NiwgYmlnLWVuZGlhbgogICAgdmFyIGxlbiA9IHZhbHVlLmxlbmd0aCgpOwogICAgdmFyIGxlbkJ5dGVzID0gJyc7CiAgICBkbyB7CiAgICAgIGxlbkJ5dGVzICs9IFN0cmluZy5mcm9tQ2hhckNvZGUobGVuICYgMHhGRik7CiAgICAgIGxlbiA9IGxlbiA+Pj4gODsKICAgIH0gd2hpbGUobGVuID4gMCk7CgogICAgLy8gc2V0IGZpcnN0IGJ5dGUgdG8gIyBieXRlcyB1c2VkIHRvIHN0b3JlIHRoZSBsZW5ndGggYW5kIHR1cm4gb24KICAgIC8vIGJpdCA4IHRvIGluZGljYXRlIGxvbmctZm9ybSBsZW5ndGggaXMgdXNlZAogICAgYnl0ZXMucHV0Qnl0ZShsZW5CeXRlcy5sZW5ndGggfCAweDgwKTsKCiAgICAvLyBjb25jYXRlbmF0ZSBsZW5ndGggYnl0ZXMgaW4gcmV2ZXJzZSBzaW5jZSB0aGV5IHdlcmUgZ2VuZXJhdGVkCiAgICAvLyBsaXR0bGUgZW5kaWFuIGFuZCB3ZSBuZWVkIGJpZyBlbmRpYW4KICAgIGZvcih2YXIgaSA9IGxlbkJ5dGVzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7CiAgICAgIGJ5dGVzLnB1dEJ5dGUobGVuQnl0ZXMuY2hhckNvZGVBdChpKSk7CiAgICB9CiAgfQoKICAvLyBjb25jYXRlbmF0ZSB2YWx1ZSBieXRlcwogIGJ5dGVzLnB1dEJ1ZmZlcih2YWx1ZSk7CiAgcmV0dXJuIGJ5dGVzOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIE9JRCBkb3Qtc2VwYXJhdGVkIHN0cmluZyB0byBhIGJ5dGUgYnVmZmVyLiBUaGUgYnl0ZSBidWZmZXIKICogY29udGFpbnMgb25seSB0aGUgREVSLWVuY29kZWQgdmFsdWUsIG5vdCBhbnkgdGFnIG9yIGxlbmd0aCBieXRlcy4KICoKICogQHBhcmFtIG9pZCB0aGUgT0lEIGRvdC1zZXBhcmF0ZWQgc3RyaW5nLgogKgogKiBAcmV0dXJuIHRoZSBieXRlIGJ1ZmZlci4KICovCmFzbjEub2lkVG9EZXIgPSBmdW5jdGlvbihvaWQpIHsKICAvLyBzcGxpdCBPSUQgaW50byBpbmRpdmlkdWFsIHZhbHVlcwogIHZhciB2YWx1ZXMgPSBvaWQuc3BsaXQoJy4nKTsKICB2YXIgYnl0ZXMgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwoKICAvLyBmaXJzdCBieXRlIGlzIDQwICogdmFsdWUxICsgdmFsdWUyCiAgYnl0ZXMucHV0Qnl0ZSg0MCAqIHBhcnNlSW50KHZhbHVlc1swXSwgMTApICsgcGFyc2VJbnQodmFsdWVzWzFdLCAxMCkpOwogIC8vIG90aGVyIGJ5dGVzIGFyZSBlYWNoIHZhbHVlIGluIGJhc2UgMTI4IHdpdGggOHRoIGJpdCBzZXQgZXhjZXB0IGZvcgogIC8vIHRoZSBsYXN0IGJ5dGUgZm9yIGVhY2ggdmFsdWUKICB2YXIgbGFzdCwgdmFsdWVCeXRlcywgdmFsdWUsIGI7CiAgZm9yKHZhciBpID0gMjsgaSA8IHZhbHVlcy5sZW5ndGg7ICsraSkgewogICAgLy8gcHJvZHVjZSB2YWx1ZSBieXRlcyBpbiByZXZlcnNlIGJlY2F1c2Ugd2UgZG9uJ3Qga25vdyBob3cgbWFueQogICAgLy8gYnl0ZXMgaXQgd2lsbCB0YWtlIHRvIHN0b3JlIHRoZSB2YWx1ZQogICAgbGFzdCA9IHRydWU7CiAgICB2YWx1ZUJ5dGVzID0gW107CiAgICB2YWx1ZSA9IHBhcnNlSW50KHZhbHVlc1tpXSwgMTApOwogICAgZG8gewogICAgICBiID0gdmFsdWUgJiAweDdGOwogICAgICB2YWx1ZSA9IHZhbHVlID4+PiA3OwogICAgICAvLyBpZiB2YWx1ZSBpcyBub3QgbGFzdCwgdGhlbiB0dXJuIG9uIDh0aCBiaXQKICAgICAgaWYoIWxhc3QpIHsKICAgICAgICBiIHw9IDB4ODA7CiAgICAgIH0KICAgICAgdmFsdWVCeXRlcy5wdXNoKGIpOwogICAgICBsYXN0ID0gZmFsc2U7CiAgICB9IHdoaWxlKHZhbHVlID4gMCk7CgogICAgLy8gYWRkIHZhbHVlIGJ5dGVzIGluIHJldmVyc2UgKG5lZWRzIHRvIGJlIGluIGJpZyBlbmRpYW4pCiAgICBmb3IodmFyIG4gPSB2YWx1ZUJ5dGVzLmxlbmd0aCAtIDE7IG4gPj0gMDsgLS1uKSB7CiAgICAgIGJ5dGVzLnB1dEJ5dGUodmFsdWVCeXRlc1tuXSk7CiAgICB9CiAgfQoKICByZXR1cm4gYnl0ZXM7Cn07CgovKioKICogQ29udmVydHMgYSBERVItZW5jb2RlZCBieXRlIGJ1ZmZlciB0byBhbiBPSUQgZG90LXNlcGFyYXRlZCBzdHJpbmcuIFRoZQogKiBieXRlIGJ1ZmZlciBzaG91bGQgY29udGFpbiBvbmx5IHRoZSBERVItZW5jb2RlZCB2YWx1ZSwgbm90IGFueSB0YWcgb3IKICogbGVuZ3RoIGJ5dGVzLgogKgogKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYnVmZmVyLgogKgogKiBAcmV0dXJuIHRoZSBPSUQgZG90LXNlcGFyYXRlZCBzdHJpbmcuCiAqLwphc24xLmRlclRvT2lkID0gZnVuY3Rpb24oYnl0ZXMpIHsKICB2YXIgb2lkOwoKICAvLyB3cmFwIGluIGJ1ZmZlciBpZiBuZWVkZWQKICBpZih0eXBlb2YgYnl0ZXMgPT09ICdzdHJpbmcnKSB7CiAgICBieXRlcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGJ5dGVzKTsKICB9CgogIC8vIGZpcnN0IGJ5dGUgaXMgNDAgKiB2YWx1ZTEgKyB2YWx1ZTIKICB2YXIgYiA9IGJ5dGVzLmdldEJ5dGUoKTsKICBvaWQgPSBNYXRoLmZsb29yKGIgLyA0MCkgKyAnLicgKyAoYiAlIDQwKTsKCiAgLy8gb3RoZXIgYnl0ZXMgYXJlIGVhY2ggdmFsdWUgaW4gYmFzZSAxMjggd2l0aCA4dGggYml0IHNldCBleGNlcHQgZm9yCiAgLy8gdGhlIGxhc3QgYnl0ZSBmb3IgZWFjaCB2YWx1ZQogIHZhciB2YWx1ZSA9IDA7CiAgd2hpbGUoYnl0ZXMubGVuZ3RoKCkgPiAwKSB7CiAgICBiID0gYnl0ZXMuZ2V0Qnl0ZSgpOwogICAgdmFsdWUgPSB2YWx1ZSA8PCA3OwogICAgLy8gbm90IHRoZSBsYXN0IGJ5dGUgZm9yIHRoZSB2YWx1ZQogICAgaWYoYiAmIDB4ODApIHsKICAgICAgdmFsdWUgKz0gYiAmIDB4N0Y7CiAgICB9IGVsc2UgewogICAgICAvLyBsYXN0IGJ5dGUKICAgICAgb2lkICs9ICcuJyArICh2YWx1ZSArIGIpOwogICAgICB2YWx1ZSA9IDA7CiAgICB9CiAgfQoKICByZXR1cm4gb2lkOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgVVRDVGltZSB2YWx1ZSB0byBhIGRhdGUuCiAqCiAqIE5vdGU6IEdlbmVyYWxpemVkVGltZSBoYXMgNCBkaWdpdHMgZm9yIHRoZSB5ZWFyIGFuZCBpcyB1c2VkIGZvciBYLjUwOQogKiBkYXRlcyBwYXNzZWQgMjA0OS4gUGFyc2luZyB0aGF0IHN0cnVjdHVyZSBoYXNuJ3QgYmVlbiBpbXBsZW1lbnRlZCB5ZXQuCiAqCiAqIEBwYXJhbSB1dGMgdGhlIFVUQ1RpbWUgdmFsdWUgdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgZGF0ZS4KICovCmFzbjEudXRjVGltZVRvRGF0ZSA9IGZ1bmN0aW9uKHV0YykgewogIC8qIFRoZSBmb2xsb3dpbmcgZm9ybWF0cyBjYW4gYmUgdXNlZDoKCiAgICBZWU1NRERoaG1tWgogICAgWVlNTUREaGhtbStoaCdtbScKICAgIFlZTU1ERGhobW0taGgnbW0nCiAgICBZWU1NRERoaG1tc3NaCiAgICBZWU1NRERoaG1tc3MraGgnbW0nCiAgICBZWU1NRERoaG1tc3MtaGgnbW0nCgogICAgV2hlcmU6CgogICAgWVkgaXMgdGhlIGxlYXN0IHNpZ25pZmljYW50IHR3byBkaWdpdHMgb2YgdGhlIHllYXIKICAgIE1NIGlzIHRoZSBtb250aCAoMDEgdG8gMTIpCiAgICBERCBpcyB0aGUgZGF5ICgwMSB0byAzMSkKICAgIGhoIGlzIHRoZSBob3VyICgwMCB0byAyMykKICAgIG1tIGFyZSB0aGUgbWludXRlcyAoMDAgdG8gNTkpCiAgICBzcyBhcmUgdGhlIHNlY29uZHMgKDAwIHRvIDU5KQogICAgWiBpbmRpY2F0ZXMgdGhhdCBsb2NhbCB0aW1lIGlzIEdNVCwgKyBpbmRpY2F0ZXMgdGhhdCBsb2NhbCB0aW1lIGlzCiAgICBsYXRlciB0aGFuIEdNVCwgYW5kIC0gaW5kaWNhdGVzIHRoYXQgbG9jYWwgdGltZSBpcyBlYXJsaWVyIHRoYW4gR01UCiAgICBoaCcgaXMgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSBvZmZzZXQgZnJvbSBHTVQgaW4gaG91cnMKICAgIG1tJyBpcyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIG9mZnNldCBmcm9tIEdNVCBpbiBtaW51dGVzICovCiAgdmFyIGRhdGUgPSBuZXcgRGF0ZSgpOwoKICAvLyBpZiBZWSA+PSA1MCB1c2UgMTl4eCwgaWYgWVkgPCA1MCB1c2UgMjB4eAogIHZhciB5ZWFyID0gcGFyc2VJbnQodXRjLnN1YnN0cigwLCAyKSwgMTApOwogIHllYXIgPSAoeWVhciA+PSA1MCkgPyAxOTAwICsgeWVhciA6IDIwMDAgKyB5ZWFyOwogIHZhciBNTSA9IHBhcnNlSW50KHV0Yy5zdWJzdHIoMiwgMiksIDEwKSAtIDE7IC8vIHVzZSAwLTExIGZvciBtb250aAogIHZhciBERCA9IHBhcnNlSW50KHV0Yy5zdWJzdHIoNCwgMiksIDEwKTsKICB2YXIgaGggPSBwYXJzZUludCh1dGMuc3Vic3RyKDYsIDIpLCAxMCk7CiAgdmFyIG1tID0gcGFyc2VJbnQodXRjLnN1YnN0cig4LCAyKSwgMTApOwogIHZhciBzcyA9IDA7CgogIC8vIG5vdCBqdXN0IFlZTU1ERGhobW1aCiAgaWYodXRjLmxlbmd0aCA+IDExKSB7CiAgICAvLyBnZXQgY2hhcmFjdGVyIGFmdGVyIG1pbnV0ZXMKICAgIHZhciBjID0gdXRjLmNoYXJBdCgxMCk7CiAgICB2YXIgZW5kID0gMTA7CgogICAgLy8gc2VlIGlmIHNlY29uZHMgYXJlIHByZXNlbnQKICAgIGlmKGMgIT09ICcrJyAmJiBjICE9PSAnLScpIHsKICAgICAgLy8gZ2V0IHNlY29uZHMKICAgICAgc3MgPSBwYXJzZUludCh1dGMuc3Vic3RyKDEwLCAyKSwgMTApOwogICAgICBlbmQgKz0gMjsKICAgIH0KICB9CgogIC8vIHVwZGF0ZSBkYXRlCiAgZGF0ZS5zZXRVVENGdWxsWWVhcih5ZWFyLCBNTSwgREQpOwogIGRhdGUuc2V0VVRDSG91cnMoaGgsIG1tLCBzcywgMCk7CgogIGlmKGVuZCkgewogICAgLy8gZ2V0ICsvLSBhZnRlciBlbmQgb2YgdGltZQogICAgYyA9IHV0Yy5jaGFyQXQoZW5kKTsKICAgIGlmKGMgPT09ICcrJyB8fCBjID09PSAnLScpIHsKICAgICAgLy8gZ2V0IGhvdXJzK21pbnV0ZXMgb2Zmc2V0CiAgICAgIHZhciBoaG9mZnNldCA9IHBhcnNlSW50KHV0Yy5zdWJzdHIoZW5kICsgMSwgMiksIDEwKTsKICAgICAgdmFyIG1tb2Zmc2V0ID0gcGFyc2VJbnQodXRjLnN1YnN0cihlbmQgKyA0LCAyKSwgMTApOwoKICAgICAgLy8gY2FsY3VsYXRlIG9mZnNldCBpbiBtaWxsaXNlY29uZHMKICAgICAgdmFyIG9mZnNldCA9IGhob2Zmc2V0ICogNjAgKyBtbW9mZnNldDsKICAgICAgb2Zmc2V0ICo9IDYwMDAwOwoKICAgICAgLy8gYXBwbHkgb2Zmc2V0CiAgICAgIGlmKGMgPT09ICcrJykgewogICAgICAgIGRhdGUuc2V0VGltZSgrZGF0ZSAtIG9mZnNldCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgb2Zmc2V0KTsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIGRhdGU7Cn07CgovKioKICogQ29udmVydHMgYSBHZW5lcmFsaXplZFRpbWUgdmFsdWUgdG8gYSBkYXRlLgogKgogKiBAcGFyYW0gZ2VudGltZSB0aGUgR2VuZXJhbGl6ZWRUaW1lIHZhbHVlIHRvIGNvbnZlcnQuCiAqCiAqIEByZXR1cm4gdGhlIGRhdGUuCiAqLwphc24xLmdlbmVyYWxpemVkVGltZVRvRGF0ZSA9IGZ1bmN0aW9uKGdlbnRpbWUpIHsKICAvKiBUaGUgZm9sbG93aW5nIGZvcm1hdHMgY2FuIGJlIHVzZWQ6CgogICAgWVlZWU1NRERISE1NU1MKICAgIFlZWVlNTURESEhNTVNTLmZmZgogICAgWVlZWU1NRERISE1NU1NaCiAgICBZWVlZTU1EREhITU1TUy5mZmZaCiAgICBZWVlZTU1EREhITU1TUytoaCdtbScKICAgIFlZWVlNTURESEhNTVNTLmZmZitoaCdtbScKICAgIFlZWVlNTURESEhNTVNTLWhoJ21tJwogICAgWVlZWU1NRERISE1NU1MuZmZmLWhoJ21tJwoKICAgIFdoZXJlOgoKICAgIFlZWVkgaXMgdGhlIHllYXIKICAgIE1NIGlzIHRoZSBtb250aCAoMDEgdG8gMTIpCiAgICBERCBpcyB0aGUgZGF5ICgwMSB0byAzMSkKICAgIGhoIGlzIHRoZSBob3VyICgwMCB0byAyMykKICAgIG1tIGFyZSB0aGUgbWludXRlcyAoMDAgdG8gNTkpCiAgICBzcyBhcmUgdGhlIHNlY29uZHMgKDAwIHRvIDU5KQogICAgLmZmZiBpcyB0aGUgc2Vjb25kIGZyYWN0aW9uLCBhY2N1cmF0ZSB0byB0aHJlZSBkZWNpbWFsIHBsYWNlcwogICAgWiBpbmRpY2F0ZXMgdGhhdCBsb2NhbCB0aW1lIGlzIEdNVCwgKyBpbmRpY2F0ZXMgdGhhdCBsb2NhbCB0aW1lIGlzCiAgICBsYXRlciB0aGFuIEdNVCwgYW5kIC0gaW5kaWNhdGVzIHRoYXQgbG9jYWwgdGltZSBpcyBlYXJsaWVyIHRoYW4gR01UCiAgICBoaCcgaXMgdGhlIGFic29sdXRlIHZhbHVlIG9mIHRoZSBvZmZzZXQgZnJvbSBHTVQgaW4gaG91cnMKICAgIG1tJyBpcyB0aGUgYWJzb2x1dGUgdmFsdWUgb2YgdGhlIG9mZnNldCBmcm9tIEdNVCBpbiBtaW51dGVzICovCiAgdmFyIGRhdGUgPSBuZXcgRGF0ZSgpOwoKICB2YXIgWVlZWSA9IHBhcnNlSW50KGdlbnRpbWUuc3Vic3RyKDAsIDQpLCAxMCk7CiAgdmFyIE1NID0gcGFyc2VJbnQoZ2VudGltZS5zdWJzdHIoNCwgMiksIDEwKSAtIDE7IC8vIHVzZSAwLTExIGZvciBtb250aAogIHZhciBERCA9IHBhcnNlSW50KGdlbnRpbWUuc3Vic3RyKDYsIDIpLCAxMCk7CiAgdmFyIGhoID0gcGFyc2VJbnQoZ2VudGltZS5zdWJzdHIoOCwgMiksIDEwKTsKICB2YXIgbW0gPSBwYXJzZUludChnZW50aW1lLnN1YnN0cigxMCwgMiksIDEwKTsKICB2YXIgc3MgPSBwYXJzZUludChnZW50aW1lLnN1YnN0cigxMiwgMiksIDEwKTsKICB2YXIgZmZmID0gMDsKICB2YXIgb2Zmc2V0ID0gMDsKICB2YXIgaXNVVEMgPSBmYWxzZTsKCiAgaWYoZ2VudGltZS5jaGFyQXQoZ2VudGltZS5sZW5ndGggLSAxKSA9PT0gJ1onKSB7CiAgICBpc1VUQyA9IHRydWU7CiAgfQoKICB2YXIgZW5kID0gZ2VudGltZS5sZW5ndGggLSA1LCBjID0gZ2VudGltZS5jaGFyQXQoZW5kKTsKICBpZihjID09PSAnKycgfHwgYyA9PT0gJy0nKSB7CiAgICAvLyBnZXQgaG91cnMrbWludXRlcyBvZmZzZXQKICAgIHZhciBoaG9mZnNldCA9IHBhcnNlSW50KGdlbnRpbWUuc3Vic3RyKGVuZCArIDEsIDIpLCAxMCk7CiAgICB2YXIgbW1vZmZzZXQgPSBwYXJzZUludChnZW50aW1lLnN1YnN0cihlbmQgKyA0LCAyKSwgMTApOwoKICAgIC8vIGNhbGN1bGF0ZSBvZmZzZXQgaW4gbWlsbGlzZWNvbmRzCiAgICBvZmZzZXQgPSBoaG9mZnNldCAqIDYwICsgbW1vZmZzZXQ7CiAgICBvZmZzZXQgKj0gNjAwMDA7CgogICAgLy8gYXBwbHkgb2Zmc2V0CiAgICBpZihjID09PSAnKycpIHsKICAgICAgb2Zmc2V0ICo9IC0xOwogICAgfQoKICAgIGlzVVRDID0gdHJ1ZTsKICB9CgogIC8vIGNoZWNrIGZvciBzZWNvbmQgZnJhY3Rpb24KICBpZihnZW50aW1lLmNoYXJBdCgxNCkgPT09ICcuJykgewogICAgZmZmID0gcGFyc2VGbG9hdChnZW50aW1lLnN1YnN0cigxNCksIDEwKSAqIDEwMDA7CiAgfQoKICBpZihpc1VUQykgewogICAgZGF0ZS5zZXRVVENGdWxsWWVhcihZWVlZLCBNTSwgREQpOwogICAgZGF0ZS5zZXRVVENIb3VycyhoaCwgbW0sIHNzLCBmZmYpOwoKICAgIC8vIGFwcGx5IG9mZnNldAogICAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgb2Zmc2V0KTsKICB9IGVsc2UgewogICAgZGF0ZS5zZXRGdWxsWWVhcihZWVlZLCBNTSwgREQpOwogICAgZGF0ZS5zZXRIb3VycyhoaCwgbW0sIHNzLCBmZmYpOwogIH0KCiAgcmV0dXJuIGRhdGU7Cn07CgovKioKICogQ29udmVydHMgYSBkYXRlIHRvIGEgVVRDVGltZSB2YWx1ZS4KICoKICogTm90ZTogR2VuZXJhbGl6ZWRUaW1lIGhhcyA0IGRpZ2l0cyBmb3IgdGhlIHllYXIgYW5kIGlzIHVzZWQgZm9yIFguNTA5CiAqIGRhdGVzIHBhc3NlZCAyMDQ5LiBDb252ZXJ0aW5nIHRvIGEgR2VuZXJhbGl6ZWRUaW1lIGhhc24ndCBiZWVuCiAqIGltcGxlbWVudGVkIHlldC4KICoKICogQHBhcmFtIGRhdGUgdGhlIGRhdGUgdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgVVRDVGltZSB2YWx1ZS4KICovCmFzbjEuZGF0ZVRvVXRjVGltZSA9IGZ1bmN0aW9uKGRhdGUpIHsKICAvLyBUT0RPOiB2YWxpZGF0ZTsgY3VycmVudGx5IGFzc3VtZXMgcHJvcGVyIGZvcm1hdAogIGlmKHR5cGVvZiBkYXRlID09PSAnc3RyaW5nJykgewogICAgcmV0dXJuIGRhdGU7CiAgfQoKICB2YXIgcnZhbCA9ICcnOwoKICAvLyBjcmVhdGUgZm9ybWF0IFlZTU1ERGhobW1zc1oKICB2YXIgZm9ybWF0ID0gW107CiAgZm9ybWF0LnB1c2goKCcnICsgZGF0ZS5nZXRVVENGdWxsWWVhcigpKS5zdWJzdHIoMikpOwogIGZvcm1hdC5wdXNoKCcnICsgKGRhdGUuZ2V0VVRDTW9udGgoKSArIDEpKTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDRGF0ZSgpKTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDSG91cnMoKSk7CiAgZm9ybWF0LnB1c2goJycgKyBkYXRlLmdldFVUQ01pbnV0ZXMoKSk7CiAgZm9ybWF0LnB1c2goJycgKyBkYXRlLmdldFVUQ1NlY29uZHMoKSk7CgogIC8vIGVuc3VyZSAyIGRpZ2l0cyBhcmUgdXNlZCBmb3IgZWFjaCBmb3JtYXQgZW50cnkKICBmb3IodmFyIGkgPSAwOyBpIDwgZm9ybWF0Lmxlbmd0aDsgKytpKSB7CiAgICBpZihmb3JtYXRbaV0ubGVuZ3RoIDwgMikgewogICAgICBydmFsICs9ICcwJzsKICAgIH0KICAgIHJ2YWwgKz0gZm9ybWF0W2ldOwogIH0KICBydmFsICs9ICdaJzsKCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ29udmVydHMgYSBkYXRlIHRvIGEgR2VuZXJhbGl6ZWRUaW1lIHZhbHVlLgogKgogKiBAcGFyYW0gZGF0ZSB0aGUgZGF0ZSB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBHZW5lcmFsaXplZFRpbWUgdmFsdWUgYXMgYSBzdHJpbmcuCiAqLwphc24xLmRhdGVUb0dlbmVyYWxpemVkVGltZSA9IGZ1bmN0aW9uKGRhdGUpIHsKICAvLyBUT0RPOiB2YWxpZGF0ZTsgY3VycmVudGx5IGFzc3VtZXMgcHJvcGVyIGZvcm1hdAogIGlmKHR5cGVvZiBkYXRlID09PSAnc3RyaW5nJykgewogICAgcmV0dXJuIGRhdGU7CiAgfQoKICB2YXIgcnZhbCA9ICcnOwoKICAvLyBjcmVhdGUgZm9ybWF0IFlZWVlNTURESEhNTVNTWgogIHZhciBmb3JtYXQgPSBbXTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDRnVsbFllYXIoKSk7CiAgZm9ybWF0LnB1c2goJycgKyAoZGF0ZS5nZXRVVENNb250aCgpICsgMSkpOwogIGZvcm1hdC5wdXNoKCcnICsgZGF0ZS5nZXRVVENEYXRlKCkpOwogIGZvcm1hdC5wdXNoKCcnICsgZGF0ZS5nZXRVVENIb3VycygpKTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDTWludXRlcygpKTsKICBmb3JtYXQucHVzaCgnJyArIGRhdGUuZ2V0VVRDU2Vjb25kcygpKTsKCiAgLy8gZW5zdXJlIDIgZGlnaXRzIGFyZSB1c2VkIGZvciBlYWNoIGZvcm1hdCBlbnRyeQogIGZvcih2YXIgaSA9IDA7IGkgPCBmb3JtYXQubGVuZ3RoOyArK2kpIHsKICAgIGlmKGZvcm1hdFtpXS5sZW5ndGggPCAyKSB7CiAgICAgIHJ2YWwgKz0gJzAnOwogICAgfQogICAgcnZhbCArPSBmb3JtYXRbaV07CiAgfQogIHJ2YWwgKz0gJ1onOwoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIGphdmFzY3JpcHQgaW50ZWdlciB0byBhIERFUi1lbmNvZGVkIGJ5dGUgYnVmZmVyIHRvIGJlIHVzZWQKICogYXMgdGhlIHZhbHVlIGZvciBhbiBJTlRFR0VSIHR5cGUuCiAqCiAqIEBwYXJhbSB4IHRoZSBpbnRlZ2VyLgogKgogKiBAcmV0dXJuIHRoZSBieXRlIGJ1ZmZlci4KICovCmFzbjEuaW50ZWdlclRvRGVyID0gZnVuY3Rpb24oeCkgewogIHZhciBydmFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBpZih4ID49IC0weDgwICYmIHggPCAweDgwKSB7CiAgICByZXR1cm4gcnZhbC5wdXRTaWduZWRJbnQoeCwgOCk7CiAgfQogIGlmKHggPj0gLTB4ODAwMCAmJiB4IDwgMHg4MDAwKSB7CiAgICByZXR1cm4gcnZhbC5wdXRTaWduZWRJbnQoeCwgMTYpOwogIH0KICBpZih4ID49IC0weDgwMDAwMCAmJiB4IDwgMHg4MDAwMDApIHsKICAgIHJldHVybiBydmFsLnB1dFNpZ25lZEludCh4LCAyNCk7CiAgfQogIGlmKHggPj0gLTB4ODAwMDAwMDAgJiYgeCA8IDB4ODAwMDAwMDApIHsKICAgIHJldHVybiBydmFsLnB1dFNpZ25lZEludCh4LCAzMik7CiAgfQogIHZhciBlcnJvciA9IG5ldyBFcnJvcignSW50ZWdlciB0b28gbGFyZ2U7IG1heCBpcyAzMi1iaXRzLicpOwogIGVycm9yLmludGVnZXIgPSB4OwogIHRocm93IGVycm9yOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgREVSLWVuY29kZWQgYnl0ZSBidWZmZXIgdG8gYSBqYXZhc2NyaXB0IGludGVnZXIuIFRoaXMgaXMKICogdHlwaWNhbGx5IHVzZWQgdG8gZGVjb2RlIHRoZSB2YWx1ZSBvZiBhbiBJTlRFR0VSIHR5cGUuCiAqCiAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZSBidWZmZXIuCiAqCiAqIEByZXR1cm4gdGhlIGludGVnZXIuCiAqLwphc24xLmRlclRvSW50ZWdlciA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgLy8gd3JhcCBpbiBidWZmZXIgaWYgbmVlZGVkCiAgaWYodHlwZW9mIGJ5dGVzID09PSAnc3RyaW5nJykgewogICAgYnl0ZXMgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihieXRlcyk7CiAgfQoKICB2YXIgbiA9IGJ5dGVzLmxlbmd0aCgpICogODsKICBpZihuID4gMzIpIHsKICAgIHRocm93IG5ldyBFcnJvcignSW50ZWdlciB0b28gbGFyZ2U7IG1heCBpcyAzMi1iaXRzLicpOwogIH0KICByZXR1cm4gYnl0ZXMuZ2V0U2lnbmVkSW50KG4pOwp9OwoKLyoqCiAqIFZhbGlkYXRlcyB0aGUgdGhhdCBnaXZlbiBBU04uMSBvYmplY3QgaXMgYXQgbGVhc3QgYSBzdXBlciBzZXQgb2YgdGhlCiAqIGdpdmVuIEFTTi4xIHN0cnVjdHVyZS4gT25seSB0YWcgY2xhc3NlcyBhbmQgdHlwZXMgYXJlIGNoZWNrZWQuIEFuCiAqIG9wdGlvbmFsIG1hcCBtYXkgYWxzbyBiZSBwcm92aWRlZCB0byBjYXB0dXJlIEFTTi4xIHZhbHVlcyB3aGlsZSB0aGUKICogc3RydWN0dXJlIGlzIGNoZWNrZWQuCiAqCiAqIFRvIGNhcHR1cmUgYW4gQVNOLjEgdmFsdWUsIHNldCBhbiBvYmplY3QgaW4gdGhlIHZhbGlkYXRvcidzICdjYXB0dXJlJwogKiBwYXJhbWV0ZXIgdG8gdGhlIGtleSB0byB1c2UgaW4gdGhlIGNhcHR1cmUgbWFwLiBUbyBjYXB0dXJlIHRoZSBmdWxsCiAqIEFTTi4xIG9iamVjdCwgc3BlY2lmeSAnY2FwdHVyZUFzbjEnLgogKgogKiBPYmplY3RzIGluIHRoZSB2YWxpZGF0b3IgbWF5IHNldCBhIGZpZWxkICdvcHRpb25hbCcgdG8gdHJ1ZSB0byBpbmRpY2F0ZQogKiB0aGF0IGl0IGlzbid0IG5lY2Vzc2FyeSB0byBwYXNzIHZhbGlkYXRpb24uCiAqCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIG9iamVjdCB0byB2YWxpZGF0ZS4KICogQHBhcmFtIHYgdGhlIEFTTi4xIHN0cnVjdHVyZSB2YWxpZGF0b3IuCiAqIEBwYXJhbSBjYXB0dXJlIGFuIG9wdGlvbmFsIG1hcCB0byBjYXB0dXJlIHZhbHVlcyBpbi4KICogQHBhcmFtIGVycm9ycyBhbiBvcHRpb25hbCBhcnJheSBmb3Igc3RvcmluZyB2YWxpZGF0aW9uIGVycm9ycy4KICoKICogQHJldHVybiB0cnVlIG9uIHN1Y2Nlc3MsIGZhbHNlIG9uIGZhaWx1cmUuCiAqLwphc24xLnZhbGlkYXRlID0gZnVuY3Rpb24ob2JqLCB2LCBjYXB0dXJlLCBlcnJvcnMpIHsKICB2YXIgcnZhbCA9IGZhbHNlOwoKICAvLyBlbnN1cmUgdGFnIGNsYXNzIGFuZCB0eXBlIGFyZSB0aGUgc2FtZSBpZiBzcGVjaWZpZWQKICBpZigob2JqLnRhZ0NsYXNzID09PSB2LnRhZ0NsYXNzIHx8IHR5cGVvZih2LnRhZ0NsYXNzKSA9PT0gJ3VuZGVmaW5lZCcpICYmCiAgICAob2JqLnR5cGUgPT09IHYudHlwZSB8fCB0eXBlb2Yodi50eXBlKSA9PT0gJ3VuZGVmaW5lZCcpKSB7CiAgICAvLyBlbnN1cmUgY29uc3RydWN0ZWQgZmxhZyBpcyB0aGUgc2FtZSBpZiBzcGVjaWZpZWQKICAgIGlmKG9iai5jb25zdHJ1Y3RlZCA9PT0gdi5jb25zdHJ1Y3RlZCB8fAogICAgICB0eXBlb2Yodi5jb25zdHJ1Y3RlZCkgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIHJ2YWwgPSB0cnVlOwoKICAgICAgLy8gaGFuZGxlIHN1YiB2YWx1ZXMKICAgICAgaWYodi52YWx1ZSAmJiBmb3JnZS51dGlsLmlzQXJyYXkodi52YWx1ZSkpIHsKICAgICAgICB2YXIgaiA9IDA7CiAgICAgICAgZm9yKHZhciBpID0gMDsgcnZhbCAmJiBpIDwgdi52YWx1ZS5sZW5ndGg7ICsraSkgewogICAgICAgICAgcnZhbCA9IHYudmFsdWVbaV0ub3B0aW9uYWwgfHwgZmFsc2U7CiAgICAgICAgICBpZihvYmoudmFsdWVbal0pIHsKICAgICAgICAgICAgcnZhbCA9IGFzbjEudmFsaWRhdGUob2JqLnZhbHVlW2pdLCB2LnZhbHVlW2ldLCBjYXB0dXJlLCBlcnJvcnMpOwogICAgICAgICAgICBpZihydmFsKSB7CiAgICAgICAgICAgICAgKytqOwogICAgICAgICAgICB9IGVsc2UgaWYodi52YWx1ZVtpXS5vcHRpb25hbCkgewogICAgICAgICAgICAgIHJ2YWwgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBpZighcnZhbCAmJiBlcnJvcnMpIHsKICAgICAgICAgICAgZXJyb3JzLnB1c2goCiAgICAgICAgICAgICAgJ1snICsgdi5uYW1lICsgJ10gJyArCiAgICAgICAgICAgICAgJ1RhZyBjbGFzcyAiJyArIHYudGFnQ2xhc3MgKyAnIiwgdHlwZSAiJyArCiAgICAgICAgICAgICAgdi50eXBlICsgJyIgZXhwZWN0ZWQgdmFsdWUgbGVuZ3RoICInICsKICAgICAgICAgICAgICB2LnZhbHVlLmxlbmd0aCArICciLCBnb3QgIicgKwogICAgICAgICAgICAgIG9iai52YWx1ZS5sZW5ndGggKyAnIicpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgaWYocnZhbCAmJiBjYXB0dXJlKSB7CiAgICAgICAgaWYodi5jYXB0dXJlKSB7CiAgICAgICAgICBjYXB0dXJlW3YuY2FwdHVyZV0gPSBvYmoudmFsdWU7CiAgICAgICAgfQogICAgICAgIGlmKHYuY2FwdHVyZUFzbjEpIHsKICAgICAgICAgIGNhcHR1cmVbdi5jYXB0dXJlQXNuMV0gPSBvYmo7CiAgICAgICAgfQogICAgICB9CiAgICB9IGVsc2UgaWYoZXJyb3JzKSB7CiAgICAgIGVycm9ycy5wdXNoKAogICAgICAgICdbJyArIHYubmFtZSArICddICcgKwogICAgICAgICdFeHBlY3RlZCBjb25zdHJ1Y3RlZCAiJyArIHYuY29uc3RydWN0ZWQgKyAnIiwgZ290ICInICsKICAgICAgICBvYmouY29uc3RydWN0ZWQgKyAnIicpOwogICAgfQogIH0gZWxzZSBpZihlcnJvcnMpIHsKICAgIGlmKG9iai50YWdDbGFzcyAhPT0gdi50YWdDbGFzcykgewogICAgICBlcnJvcnMucHVzaCgKICAgICAgICAnWycgKyB2Lm5hbWUgKyAnXSAnICsKICAgICAgICAnRXhwZWN0ZWQgdGFnIGNsYXNzICInICsgdi50YWdDbGFzcyArICciLCBnb3QgIicgKwogICAgICAgIG9iai50YWdDbGFzcyArICciJyk7CiAgICB9CiAgICBpZihvYmoudHlwZSAhPT0gdi50eXBlKSB7CiAgICAgIGVycm9ycy5wdXNoKAogICAgICAgICdbJyArIHYubmFtZSArICddICcgKwogICAgICAgICdFeHBlY3RlZCB0eXBlICInICsgdi50eXBlICsgJyIsIGdvdCAiJyArIG9iai50eXBlICsgJyInKTsKICAgIH0KICB9CiAgcmV0dXJuIHJ2YWw7Cn07CgovLyByZWdleCBmb3IgdGVzdGluZyBmb3Igbm9uLWxhdGluIGNoYXJhY3RlcnMKdmFyIF9ub25MYXRpblJlZ2V4ID0gL1teXFx1MDAwMC1cXHUwMGZmXS87CgovKioKICogUHJldHR5IHByaW50cyBhbiBBU04uMSBvYmplY3QgdG8gYSBzdHJpbmcuCiAqCiAqIEBwYXJhbSBvYmogdGhlIG9iamVjdCB0byB3cml0ZSBvdXQuCiAqIEBwYXJhbSBsZXZlbCB0aGUgbGV2ZWwgaW4gdGhlIHRyZWUuCiAqIEBwYXJhbSBpbmRlbnRhdGlvbiB0aGUgaW5kZW50YXRpb24gdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSBzdHJpbmcuCiAqLwphc24xLnByZXR0eVByaW50ID0gZnVuY3Rpb24ob2JqLCBsZXZlbCwgaW5kZW50YXRpb24pIHsKICB2YXIgcnZhbCA9ICcnOwoKICAvLyBzZXQgZGVmYXVsdCBsZXZlbCBhbmQgaW5kZW50YXRpb24KICBsZXZlbCA9IGxldmVsIHx8IDA7CiAgaW5kZW50YXRpb24gPSBpbmRlbnRhdGlvbiB8fCAyOwoKICAvLyBzdGFydCBuZXcgbGluZSBmb3IgZGVlcCBsZXZlbHMKICBpZihsZXZlbCA+IDApIHsKICAgIHJ2YWwgKz0gJ1xuJzsKICB9CgogIC8vIGNyZWF0ZSBpbmRlbnQKICB2YXIgaW5kZW50ID0gJyc7CiAgZm9yKHZhciBpID0gMDsgaSA8IGxldmVsICogaW5kZW50YXRpb247ICsraSkgewogICAgaW5kZW50ICs9ICcgJzsKICB9CgogIC8vIHByaW50IGNsYXNzOnR5cGUKICBydmFsICs9IGluZGVudCArICdUYWc6ICc7CiAgc3dpdGNoKG9iai50YWdDbGFzcykgewogIGNhc2UgYXNuMS5DbGFzcy5VTklWRVJTQUw6CiAgICBydmFsICs9ICdVbml2ZXJzYWw6JzsKICAgIGJyZWFrOwogIGNhc2UgYXNuMS5DbGFzcy5BUFBMSUNBVElPTjoKICAgIHJ2YWwgKz0gJ0FwcGxpY2F0aW9uOic7CiAgICBicmVhazsKICBjYXNlIGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQzoKICAgIHJ2YWwgKz0gJ0NvbnRleHQtU3BlY2lmaWM6JzsKICAgIGJyZWFrOwogIGNhc2UgYXNuMS5DbGFzcy5QUklWQVRFOgogICAgcnZhbCArPSAnUHJpdmF0ZTonOwogICAgYnJlYWs7CiAgfQoKICBpZihvYmoudGFnQ2xhc3MgPT09IGFzbjEuQ2xhc3MuVU5JVkVSU0FMKSB7CiAgICBydmFsICs9IG9iai50eXBlOwoKICAgIC8vIGtub3duIHR5cGVzCiAgICBzd2l0Y2gob2JqLnR5cGUpIHsKICAgIGNhc2UgYXNuMS5UeXBlLk5PTkU6CiAgICAgIHJ2YWwgKz0gJyAoTm9uZSknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkJPT0xFQU46CiAgICAgIHJ2YWwgKz0gJyAoQm9vbGVhbiknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkJJVFNUUklORzoKICAgICAgcnZhbCArPSAnIChCaXQgc3RyaW5nKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuSU5URUdFUjoKICAgICAgcnZhbCArPSAnIChJbnRlZ2VyKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuT0NURVRTVFJJTkc6CiAgICAgIHJ2YWwgKz0gJyAoT2N0ZXQgc3RyaW5nKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuTlVMTDoKICAgICAgcnZhbCArPSAnIChOdWxsKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuT0lEOgogICAgICBydmFsICs9ICcgKE9iamVjdCBJZGVudGlmaWVyKSc7CiAgICAgIGJyZWFrOwogICAgY2FzZSBhc24xLlR5cGUuT0RFU0M6CiAgICAgIHJ2YWwgKz0gJyAoT2JqZWN0IERlc2NyaXB0b3IpJzsKICAgICAgYnJlYWs7CiAgICBjYXNlIGFzbjEuVHlwZS5FWFRFUk5BTDoKICAgICAgcnZhbCArPSAnIChFeHRlcm5hbCBvciBJbnN0YW5jZSBvZiknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlJFQUw6CiAgICAgIHJ2YWwgKz0gJyAoUmVhbCknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkVOVU1FUkFURUQ6CiAgICAgIHJ2YWwgKz0gJyAoRW51bWVyYXRlZCknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkVNQkVEREVEOgogICAgICBydmFsICs9ICcgKEVtYmVkZGVkIFBEViknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlVURjg6CiAgICAgIHJ2YWwgKz0gJyAoVVRGOCknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlJPSUQ6CiAgICAgIHJ2YWwgKz0gJyAoUmVsYXRpdmUgT2JqZWN0IElkZW50aWZpZXIpJzsKICAgICAgYnJlYWs7CiAgICBjYXNlIGFzbjEuVHlwZS5TRVFVRU5DRToKICAgICAgcnZhbCArPSAnIChTZXF1ZW5jZSknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlNFVDoKICAgICAgcnZhbCArPSAnIChTZXQpJzsKICAgICAgYnJlYWs7CiAgICBjYXNlIGFzbjEuVHlwZS5QUklOVEFCTEVTVFJJTkc6CiAgICAgIHJ2YWwgKz0gJyAoUHJpbnRhYmxlIFN0cmluZyknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLklBNVN0cmluZzoKICAgICAgcnZhbCArPSAnIChJQTVTdHJpbmcgKEFTQ0lJKSknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLlVUQ1RJTUU6CiAgICAgIHJ2YWwgKz0gJyAoVVRDIHRpbWUpJzsKICAgICAgYnJlYWs7CiAgICBjYXNlIGFzbjEuVHlwZS5HRU5FUkFMSVpFRFRJTUU6CiAgICAgIHJ2YWwgKz0gJyAoR2VuZXJhbGl6ZWQgdGltZSknOwogICAgICBicmVhazsKICAgIGNhc2UgYXNuMS5UeXBlLkJNUFNUUklORzoKICAgICAgcnZhbCArPSAnIChCTVAgU3RyaW5nKSc7CiAgICAgIGJyZWFrOwogICAgfQogIH0gZWxzZSB7CiAgICBydmFsICs9IG9iai50eXBlOwogIH0KCiAgcnZhbCArPSAnXG4nOwogIHJ2YWwgKz0gaW5kZW50ICsgJ0NvbnN0cnVjdGVkOiAnICsgb2JqLmNvbnN0cnVjdGVkICsgJ1xuJzsKCiAgaWYob2JqLmNvbXBvc2VkKSB7CiAgICB2YXIgc3VidmFsdWVzID0gMDsKICAgIHZhciBzdWIgPSAnJzsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBvYmoudmFsdWUubGVuZ3RoOyArK2kpIHsKICAgICAgaWYob2JqLnZhbHVlW2ldICE9PSB1bmRlZmluZWQpIHsKICAgICAgICBzdWJ2YWx1ZXMgKz0gMTsKICAgICAgICBzdWIgKz0gYXNuMS5wcmV0dHlQcmludChvYmoudmFsdWVbaV0sIGxldmVsICsgMSwgaW5kZW50YXRpb24pOwogICAgICAgIGlmKChpICsgMSkgPCBvYmoudmFsdWUubGVuZ3RoKSB7CiAgICAgICAgICBzdWIgKz0gJywnOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcnZhbCArPSBpbmRlbnQgKyAnU3ViIHZhbHVlczogJyArIHN1YnZhbHVlcyArIHN1YjsKICB9IGVsc2UgewogICAgcnZhbCArPSBpbmRlbnQgKyAnVmFsdWU6ICc7CiAgICBpZihvYmoudHlwZSA9PT0gYXNuMS5UeXBlLk9JRCkgewogICAgICB2YXIgb2lkID0gYXNuMS5kZXJUb09pZChvYmoudmFsdWUpOwogICAgICBydmFsICs9IG9pZDsKICAgICAgaWYoZm9yZ2UucGtpICYmIGZvcmdlLnBraS5vaWRzKSB7CiAgICAgICAgaWYob2lkIGluIGZvcmdlLnBraS5vaWRzKSB7CiAgICAgICAgICBydmFsICs9ICcgKCcgKyBmb3JnZS5wa2kub2lkc1tvaWRdICsgJykgJzsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGlmKG9iai50eXBlID09PSBhc24xLlR5cGUuSU5URUdFUikgewogICAgICB0cnkgewogICAgICAgIHJ2YWwgKz0gYXNuMS5kZXJUb0ludGVnZXIob2JqLnZhbHVlKTsKICAgICAgfSBjYXRjaChleCkgewogICAgICAgIHJ2YWwgKz0gJzB4JyArIGZvcmdlLnV0aWwuYnl0ZXNUb0hleChvYmoudmFsdWUpOwogICAgICB9CiAgICB9IGVsc2UgaWYob2JqLnR5cGUgPT09IGFzbjEuVHlwZS5PQ1RFVFNUUklORykgewogICAgICBpZighX25vbkxhdGluUmVnZXgudGVzdChvYmoudmFsdWUpKSB7CiAgICAgICAgcnZhbCArPSAnKCcgKyBvYmoudmFsdWUgKyAnKSAnOwogICAgICB9CiAgICAgIHJ2YWwgKz0gJzB4JyArIGZvcmdlLnV0aWwuYnl0ZXNUb0hleChvYmoudmFsdWUpOwogICAgfSBlbHNlIGlmKG9iai50eXBlID09PSBhc24xLlR5cGUuVVRGOCkgewogICAgICBydmFsICs9IGZvcmdlLnV0aWwuZGVjb2RlVXRmOChvYmoudmFsdWUpOwogICAgfSBlbHNlIGlmKG9iai50eXBlID09PSBhc24xLlR5cGUuUFJJTlRBQkxFU1RSSU5HIHx8CiAgICAgIG9iai50eXBlID09PSBhc24xLlR5cGUuSUE1U3RyaW5nKSB7CiAgICAgIHJ2YWwgKz0gb2JqLnZhbHVlOwogICAgfSBlbHNlIGlmKF9ub25MYXRpblJlZ2V4LnRlc3Qob2JqLnZhbHVlKSkgewogICAgICBydmFsICs9ICcweCcgKyBmb3JnZS51dGlsLmJ5dGVzVG9IZXgob2JqLnZhbHVlKTsKICAgIH0gZWxzZSBpZihvYmoudmFsdWUubGVuZ3RoID09PSAwKSB7CiAgICAgIHJ2YWwgKz0gJ1tudWxsXSc7CiAgICB9IGVsc2UgewogICAgICBydmFsICs9IG9iai52YWx1ZTsKICAgIH0KICB9CgogIHJldHVybiBydmFsOwp9OwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAnYXNuMSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9hc24xJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCcsICcuL29pZHMnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogTWVzc2FnZSBEaWdlc3QgQWxnb3JpdGhtIDUgd2l0aCAxMjgtYml0IGRpZ2VzdCAoTUQ1KSBpbXBsZW1lbnRhdGlvbi4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7Cgp2YXIgbWQ1ID0gZm9yZ2UubWQ1ID0gZm9yZ2UubWQ1IHx8IHt9Owpmb3JnZS5tZCA9IGZvcmdlLm1kIHx8IHt9Owpmb3JnZS5tZC5hbGdvcml0aG1zID0gZm9yZ2UubWQuYWxnb3JpdGhtcyB8fCB7fTsKZm9yZ2UubWQubWQ1ID0gZm9yZ2UubWQuYWxnb3JpdGhtcy5tZDUgPSBtZDU7CgovKioKICogQ3JlYXRlcyBhbiBNRDUgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0LgogKgogKiBAcmV0dXJuIGEgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0LgogKi8KbWQ1LmNyZWF0ZSA9IGZ1bmN0aW9uKCkgewogIC8vIGRvIGluaXRpYWxpemF0aW9uIGFzIG5lY2Vzc2FyeQogIGlmKCFfaW5pdGlhbGl6ZWQpIHsKICAgIF9pbml0KCk7CiAgfQoKICAvLyBNRDUgc3RhdGUgY29udGFpbnMgZm91ciAzMi1iaXQgaW50ZWdlcnMKICB2YXIgX3N0YXRlID0gbnVsbDsKCiAgLy8gaW5wdXQgYnVmZmVyCiAgdmFyIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIHVzZWQgZm9yIHdvcmQgc3RvcmFnZQogIHZhciBfdyA9IG5ldyBBcnJheSgxNik7CgogIC8vIG1lc3NhZ2UgZGlnZXN0IG9iamVjdAogIHZhciBtZCA9IHsKICAgIGFsZ29yaXRobTogJ21kNScsCiAgICBibG9ja0xlbmd0aDogNjQsCiAgICBkaWdlc3RMZW5ndGg6IDE2LAogICAgLy8gNTYtYml0IGxlbmd0aCBvZiBtZXNzYWdlIHNvIGZhciAoZG9lcyBub3QgaW5jbHVkaW5nIHBhZGRpbmcpCiAgICBtZXNzYWdlTGVuZ3RoOiAwLAogICAgLy8gdHJ1ZSBtZXNzYWdlIGxlbmd0aAogICAgZnVsbE1lc3NhZ2VMZW5ndGg6IG51bGwsCiAgICAvLyBzaXplIG9mIG1lc3NhZ2UgbGVuZ3RoIGluIGJ5dGVzCiAgICBtZXNzYWdlTGVuZ3RoU2l6ZTogOAogIH07CgogIC8qKgogICAqIFN0YXJ0cyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQuc3RhcnQgPSBmdW5jdGlvbigpIHsKICAgIC8vIHVwIHRvIDU2LWJpdCBtZXNzYWdlIGxlbmd0aCBmb3IgY29udmVuaWVuY2UKICAgIG1kLm1lc3NhZ2VMZW5ndGggPSAwOwoKICAgIC8vIGZ1bGwgbWVzc2FnZSBsZW5ndGggKHNldCBtZC5tZXNzYWdlTGVuZ3RoNjQgZm9yIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5KQogICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGggPSBtZC5tZXNzYWdlTGVuZ3RoNjQgPSBbXTsKICAgIHZhciBpbnQzMnMgPSBtZC5tZXNzYWdlTGVuZ3RoU2l6ZSAvIDQ7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgaW50MzJzOyArK2kpIHsKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGgucHVzaCgwKTsKICAgIH0KICAgIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBfc3RhdGUgPSB7CiAgICAgIGgwOiAweDY3NDUyMzAxLAogICAgICBoMTogMHhFRkNEQUI4OSwKICAgICAgaDI6IDB4OThCQURDRkUsCiAgICAgIGgzOiAweDEwMzI1NDc2CiAgICB9OwogICAgcmV0dXJuIG1kOwogIH07CiAgLy8gc3RhcnQgZGlnZXN0IGF1dG9tYXRpY2FsbHkgZm9yIGZpcnN0IHRpbWUKICBtZC5zdGFydCgpOwoKICAvKioKICAgKiBVcGRhdGVzIHRoZSBkaWdlc3Qgd2l0aCB0aGUgZ2l2ZW4gbWVzc2FnZSBpbnB1dC4gVGhlIGdpdmVuIGlucHV0IGNhbgogICAqIHRyZWF0ZWQgYXMgcmF3IGlucHV0IChubyBlbmNvZGluZyB3aWxsIGJlIGFwcGxpZWQpIG9yIGFuIGVuY29kaW5nIG9mCiAgICogJ3V0ZjgnIG1heWJlIGdpdmVuIHRvIGVuY29kZSB0aGUgaW5wdXQgdXNpbmcgVVRGLTguCiAgICoKICAgKiBAcGFyYW0gbXNnIHRoZSBtZXNzYWdlIGlucHV0IHRvIHVwZGF0ZSB3aXRoLgogICAqIEBwYXJhbSBlbmNvZGluZyB0aGUgZW5jb2RpbmcgdG8gdXNlIChkZWZhdWx0OiAncmF3Jywgb3RoZXI6ICd1dGY4JykuCiAgICoKICAgKiBAcmV0dXJuIHRoaXMgZGlnZXN0IG9iamVjdC4KICAgKi8KICBtZC51cGRhdGUgPSBmdW5jdGlvbihtc2csIGVuY29kaW5nKSB7CiAgICBpZihlbmNvZGluZyA9PT0gJ3V0ZjgnKSB7CiAgICAgIG1zZyA9IGZvcmdlLnV0aWwuZW5jb2RlVXRmOChtc2cpOwogICAgfQoKICAgIC8vIHVwZGF0ZSBtZXNzYWdlIGxlbmd0aAogICAgdmFyIGxlbiA9IG1zZy5sZW5ndGg7CiAgICBtZC5tZXNzYWdlTGVuZ3RoICs9IGxlbjsKICAgIGxlbiA9IFsobGVuIC8gMHgxMDAwMDAwMDApID4+PiAwLCBsZW4gPj4+IDBdOwogICAgZm9yKHZhciBpID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGgubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIHsKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gKz0gbGVuWzFdOwogICAgICBsZW5bMV0gPSBsZW5bMF0gKyAoKG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldIC8gMHgxMDAwMDAwMDApID4+PiAwKTsKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gPSBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSA+Pj4gMDsKICAgICAgbGVuWzBdID0gKChsZW5bMV0gLyAweDEwMDAwMDAwMCkgPj4+IDApOwogICAgfQoKICAgIC8vIGFkZCBieXRlcyB0byBpbnB1dCBidWZmZXIKICAgIF9pbnB1dC5wdXRCeXRlcyhtc2cpOwoKICAgIC8vIHByb2Nlc3MgYnl0ZXMKICAgIF91cGRhdGUoX3N0YXRlLCBfdywgX2lucHV0KTsKCiAgICAvLyBjb21wYWN0IGlucHV0IGJ1ZmZlciBldmVyeSAySyBvciBpZiBlbXB0eQogICAgaWYoX2lucHV0LnJlYWQgPiAyMDQ4IHx8IF9pbnB1dC5sZW5ndGgoKSA9PT0gMCkgewogICAgICBfaW5wdXQuY29tcGFjdCgpOwogICAgfQoKICAgIHJldHVybiBtZDsKICB9OwoKICAvKioKICAgKiBQcm9kdWNlcyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiBhIGJ5dGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGRpZ2VzdCB2YWx1ZS4KICAgKi8KICBtZC5kaWdlc3QgPSBmdW5jdGlvbigpIHsKICAgIC8qIE5vdGU6IEhlcmUgd2UgY29weSB0aGUgcmVtYWluaW5nIGJ5dGVzIGluIHRoZSBpbnB1dCBidWZmZXIgYW5kCiAgICBhZGQgdGhlIGFwcHJvcHJpYXRlIE1ENSBwYWRkaW5nLiBUaGVuIHdlIGRvIHRoZSBmaW5hbCB1cGRhdGUKICAgIG9uIGEgY29weSBvZiB0aGUgc3RhdGUgc28gdGhhdCBpZiB0aGUgdXNlciB3YW50cyB0byBnZXQKICAgIGludGVybWVkaWF0ZSBkaWdlc3RzIHRoZXkgY2FuIGRvIHNvLiAqLwoKICAgIC8qIERldGVybWluZSB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRoYXQgbXVzdCBiZSBhZGRlZCB0byB0aGUgbWVzc2FnZQogICAgdG8gZW5zdXJlIGl0cyBsZW5ndGggaXMgY29uZ3J1ZW50IHRvIDQ0OCBtb2QgNTEyLiBJbiBvdGhlciB3b3JkcywKICAgIHRoZSBkYXRhIHRvIGJlIGRpZ2VzdGVkIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA1MTIgYml0cyAob3IgMTI4IGJ5dGVzKS4KICAgIFRoaXMgZGF0YSBpbmNsdWRlcyB0aGUgbWVzc2FnZSwgc29tZSBwYWRkaW5nLCBhbmQgdGhlIGxlbmd0aCBvZiB0aGUKICAgIG1lc3NhZ2UuIFNpbmNlIHRoZSBsZW5ndGggb2YgdGhlIG1lc3NhZ2Ugd2lsbCBiZSBlbmNvZGVkIGFzIDggYnl0ZXMgKDY0CiAgICBiaXRzKSwgdGhhdCBtZWFucyB0aGF0IHRoZSBsYXN0IHNlZ21lbnQgb2YgdGhlIGRhdGEgbXVzdCBoYXZlIDU2IGJ5dGVzCiAgICAoNDQ4IGJpdHMpIG9mIG1lc3NhZ2UgYW5kIHBhZGRpbmcuIFRoZXJlZm9yZSwgdGhlIGxlbmd0aCBvZiB0aGUgbWVzc2FnZQogICAgcGx1cyB0aGUgcGFkZGluZyBtdXN0IGJlIGNvbmdydWVudCB0byA0NDggbW9kIDUxMiBiZWNhdXNlCiAgICA1MTIgLSAxMjggPSA0NDguCgogICAgSW4gb3JkZXIgdG8gZmlsbCB1cCB0aGUgbWVzc2FnZSBsZW5ndGggaXQgbXVzdCBiZSBmaWxsZWQgd2l0aAogICAgcGFkZGluZyB0aGF0IGJlZ2lucyB3aXRoIDEgYml0IGZvbGxvd2VkIGJ5IGFsbCAwIGJpdHMuIFBhZGRpbmcKICAgIG11c3QgKmFsd2F5cyogYmUgcHJlc2VudCwgc28gaWYgdGhlIG1lc3NhZ2UgbGVuZ3RoIGlzIGFscmVhZHkKICAgIGNvbmdydWVudCB0byA0NDggbW9kIDUxMiwgdGhlbiA1MTIgcGFkZGluZyBiaXRzIG11c3QgYmUgYWRkZWQuICovCgogICAgdmFyIGZpbmFsQmxvY2sgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgZmluYWxCbG9jay5wdXRCeXRlcyhfaW5wdXQuYnl0ZXMoKSk7CgogICAgLy8gY29tcHV0ZSByZW1haW5pbmcgc2l6ZSB0byBiZSBkaWdlc3RlZCAoaW5jbHVkZSBtZXNzYWdlIGxlbmd0aCBzaXplKQogICAgdmFyIHJlbWFpbmluZyA9ICgKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGhbbWQuZnVsbE1lc3NhZ2VMZW5ndGgubGVuZ3RoIC0gMV0gKwogICAgICBtZC5tZXNzYWdlTGVuZ3RoU2l6ZSk7CgogICAgLy8gYWRkIHBhZGRpbmcgZm9yIG92ZXJmbG93IGJsb2NrU2l6ZSAtIG92ZXJmbG93CiAgICAvLyBfcGFkZGluZyBzdGFydHMgd2l0aCAxIGJ5dGUgd2l0aCBmaXJzdCBiaXQgaXMgc2V0IChieXRlIHZhbHVlIDEyOCksIHRoZW4KICAgIC8vIHRoZXJlIG1heSBiZSB1cCB0byAoYmxvY2tTaXplIC0gMSkgb3RoZXIgcGFkIGJ5dGVzCiAgICB2YXIgb3ZlcmZsb3cgPSByZW1haW5pbmcgJiAobWQuYmxvY2tMZW5ndGggLSAxKTsKICAgIGZpbmFsQmxvY2sucHV0Qnl0ZXMoX3BhZGRpbmcuc3Vic3RyKDAsIG1kLmJsb2NrTGVuZ3RoIC0gb3ZlcmZsb3cpKTsKCiAgICAvLyBzZXJpYWxpemUgbWVzc2FnZSBsZW5ndGggaW4gYml0cyBpbiBsaXR0bGUtZW5kaWFuIG9yZGVyOyBzaW5jZSBsZW5ndGgKICAgIC8vIGlzIHN0b3JlZCBpbiBieXRlcyB3ZSBtdWx0aXBseSBieSA4IGFuZCBhZGQgY2FycnkKICAgIHZhciBiaXRzLCBjYXJyeSA9IDA7CiAgICBmb3IodmFyIGkgPSBtZC5mdWxsTWVzc2FnZUxlbmd0aC5sZW5ndGggLSAxOyBpID49IDA7IC0taSkgewogICAgICBiaXRzID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gKiA4ICsgY2Fycnk7CiAgICAgIGNhcnJ5ID0gKGJpdHMgLyAweDEwMDAwMDAwMCkgPj4+IDA7CiAgICAgIGZpbmFsQmxvY2sucHV0SW50MzJMZShiaXRzID4+PiAwKTsKICAgIH0KCiAgICB2YXIgczIgPSB7CiAgICAgIGgwOiBfc3RhdGUuaDAsCiAgICAgIGgxOiBfc3RhdGUuaDEsCiAgICAgIGgyOiBfc3RhdGUuaDIsCiAgICAgIGgzOiBfc3RhdGUuaDMKICAgIH07CiAgICBfdXBkYXRlKHMyLCBfdywgZmluYWxCbG9jayk7CiAgICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBydmFsLnB1dEludDMyTGUoczIuaDApOwogICAgcnZhbC5wdXRJbnQzMkxlKHMyLmgxKTsKICAgIHJ2YWwucHV0SW50MzJMZShzMi5oMik7CiAgICBydmFsLnB1dEludDMyTGUoczIuaDMpOwogICAgcmV0dXJuIHJ2YWw7CiAgfTsKCiAgcmV0dXJuIG1kOwp9OwoKLy8gcGFkZGluZywgY29uc3RhbnQgdGFibGVzIGZvciBjYWxjdWxhdGluZyBtZDUKdmFyIF9wYWRkaW5nID0gbnVsbDsKdmFyIF9nID0gbnVsbDsKdmFyIF9yID0gbnVsbDsKdmFyIF9rID0gbnVsbDsKdmFyIF9pbml0aWFsaXplZCA9IGZhbHNlOwoKLyoqCiAqIEluaXRpYWxpemVzIHRoZSBjb25zdGFudCB0YWJsZXMuCiAqLwpmdW5jdGlvbiBfaW5pdCgpIHsKICAvLyBjcmVhdGUgcGFkZGluZwogIF9wYWRkaW5nID0gU3RyaW5nLmZyb21DaGFyQ29kZSgxMjgpOwogIF9wYWRkaW5nICs9IGZvcmdlLnV0aWwuZmlsbFN0cmluZyhTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDApLCA2NCk7CgogIC8vIGcgdmFsdWVzCiAgX2cgPSBbCiAgICAwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LAogICAgMSwgNiwgMTEsIDAsIDUsIDEwLCAxNSwgNCwgOSwgMTQsIDMsIDgsIDEzLCAyLCA3LCAxMiwKICAgIDUsIDgsIDExLCAxNCwgMSwgNCwgNywgMTAsIDEzLCAwLCAzLCA2LCA5LCAxMiwgMTUsIDIsCiAgICAwLCA3LCAxNCwgNSwgMTIsIDMsIDEwLCAxLCA4LCAxNSwgNiwgMTMsIDQsIDExLCAyLCA5XTsKCiAgLy8gcm91bmRzIHRhYmxlCiAgX3IgPSBbCiAgICA3LCAxMiwgMTcsIDIyLCAgNywgMTIsIDE3LCAyMiwgIDcsIDEyLCAxNywgMjIsICA3LCAxMiwgMTcsIDIyLAogICAgNSwgIDksIDE0LCAyMCwgIDUsICA5LCAxNCwgMjAsICA1LCAgOSwgMTQsIDIwLCAgNSwgIDksIDE0LCAyMCwKICAgIDQsIDExLCAxNiwgMjMsICA0LCAxMSwgMTYsIDIzLCAgNCwgMTEsIDE2LCAyMywgIDQsIDExLCAxNiwgMjMsCiAgICA2LCAxMCwgMTUsIDIxLCAgNiwgMTAsIDE1LCAyMSwgIDYsIDEwLCAxNSwgMjEsICA2LCAxMCwgMTUsIDIxXTsKCiAgLy8gZ2V0IHRoZSByZXN1bHQgb2YgYWJzKHNpbihpICsgMSkpIGFzIGEgMzItYml0IGludGVnZXIKICBfayA9IG5ldyBBcnJheSg2NCk7CiAgZm9yKHZhciBpID0gMDsgaSA8IDY0OyArK2kpIHsKICAgIF9rW2ldID0gTWF0aC5mbG9vcihNYXRoLmFicyhNYXRoLnNpbihpICsgMSkpICogMHgxMDAwMDAwMDApOwogIH0KCiAgLy8gbm93IGluaXRpYWxpemVkCiAgX2luaXRpYWxpemVkID0gdHJ1ZTsKfQoKLyoqCiAqIFVwZGF0ZXMgYW4gTUQ1IHN0YXRlIHdpdGggdGhlIGdpdmVuIGJ5dGUgYnVmZmVyLgogKgogKiBAcGFyYW0gcyB0aGUgTUQ1IHN0YXRlIHRvIHVwZGF0ZS4KICogQHBhcmFtIHcgdGhlIGFycmF5IHRvIHVzZSB0byBzdG9yZSB3b3Jkcy4KICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlIGJ1ZmZlciB0byB1cGRhdGUgd2l0aC4KICovCmZ1bmN0aW9uIF91cGRhdGUocywgdywgYnl0ZXMpIHsKICAvLyBjb25zdW1lIDUxMiBiaXQgKDY0IGJ5dGUpIGNodW5rcwogIHZhciB0LCBhLCBiLCBjLCBkLCBmLCByLCBpOwogIHZhciBsZW4gPSBieXRlcy5sZW5ndGgoKTsKICB3aGlsZShsZW4gPj0gNjQpIHsKICAgIC8vIGluaXRpYWxpemUgaGFzaCB2YWx1ZSBmb3IgdGhpcyBjaHVuawogICAgYSA9IHMuaDA7CiAgICBiID0gcy5oMTsKICAgIGMgPSBzLmgyOwogICAgZCA9IHMuaDM7CgogICAgLy8gcm91bmQgMQogICAgZm9yKGkgPSAwOyBpIDwgMTY7ICsraSkgewogICAgICB3W2ldID0gYnl0ZXMuZ2V0SW50MzJMZSgpOwogICAgICBmID0gZCBeIChiICYgKGMgXiBkKSk7CiAgICAgIHQgPSAoYSArIGYgKyBfa1tpXSArIHdbaV0pOwogICAgICByID0gX3JbaV07CiAgICAgIGEgPSBkOwogICAgICBkID0gYzsKICAgICAgYyA9IGI7CiAgICAgIGIgKz0gKHQgPDwgcikgfCAodCA+Pj4gKDMyIC0gcikpOwogICAgfQogICAgLy8gcm91bmQgMgogICAgZm9yKDsgaSA8IDMyOyArK2kpIHsKICAgICAgZiA9IGMgXiAoZCAmIChiIF4gYykpOwogICAgICB0ID0gKGEgKyBmICsgX2tbaV0gKyB3W19nW2ldXSk7CiAgICAgIHIgPSBfcltpXTsKICAgICAgYSA9IGQ7CiAgICAgIGQgPSBjOwogICAgICBjID0gYjsKICAgICAgYiArPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7CiAgICB9CiAgICAvLyByb3VuZCAzCiAgICBmb3IoOyBpIDwgNDg7ICsraSkgewogICAgICBmID0gYiBeIGMgXiBkOwogICAgICB0ID0gKGEgKyBmICsgX2tbaV0gKyB3W19nW2ldXSk7CiAgICAgIHIgPSBfcltpXTsKICAgICAgYSA9IGQ7CiAgICAgIGQgPSBjOwogICAgICBjID0gYjsKICAgICAgYiArPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7CiAgICB9CiAgICAvLyByb3VuZCA0CiAgICBmb3IoOyBpIDwgNjQ7ICsraSkgewogICAgICBmID0gYyBeIChiIHwgfmQpOwogICAgICB0ID0gKGEgKyBmICsgX2tbaV0gKyB3W19nW2ldXSk7CiAgICAgIHIgPSBfcltpXTsKICAgICAgYSA9IGQ7CiAgICAgIGQgPSBjOwogICAgICBjID0gYjsKICAgICAgYiArPSAodCA8PCByKSB8ICh0ID4+PiAoMzIgLSByKSk7CiAgICB9CgogICAgLy8gdXBkYXRlIGhhc2ggc3RhdGUKICAgIHMuaDAgPSAocy5oMCArIGEpIHwgMDsKICAgIHMuaDEgPSAocy5oMSArIGIpIHwgMDsKICAgIHMuaDIgPSAocy5oMiArIGMpIHwgMDsKICAgIHMuaDMgPSAocy5oMyArIGQpIHwgMDsKCiAgICBsZW4gLT0gNjQ7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdtZDUnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvbWQ1JyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBTZWN1cmUgSGFzaCBBbGdvcml0aG0gd2l0aCAxNjAtYml0IGRpZ2VzdCAoU0hBLTEpIGltcGxlbWVudGF0aW9uLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNSBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCnZhciBzaGExID0gZm9yZ2Uuc2hhMSA9IGZvcmdlLnNoYTEgfHwge307CmZvcmdlLm1kID0gZm9yZ2UubWQgfHwge307CmZvcmdlLm1kLmFsZ29yaXRobXMgPSBmb3JnZS5tZC5hbGdvcml0aG1zIHx8IHt9Owpmb3JnZS5tZC5zaGExID0gZm9yZ2UubWQuYWxnb3JpdGhtcy5zaGExID0gc2hhMTsKCi8qKgogKiBDcmVhdGVzIGEgU0hBLTEgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0LgogKgogKiBAcmV0dXJuIGEgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0LgogKi8Kc2hhMS5jcmVhdGUgPSBmdW5jdGlvbigpIHsKICAvLyBkbyBpbml0aWFsaXphdGlvbiBhcyBuZWNlc3NhcnkKICBpZighX2luaXRpYWxpemVkKSB7CiAgICBfaW5pdCgpOwogIH0KCiAgLy8gU0hBLTEgc3RhdGUgY29udGFpbnMgZml2ZSAzMi1iaXQgaW50ZWdlcnMKICB2YXIgX3N0YXRlID0gbnVsbDsKCiAgLy8gaW5wdXQgYnVmZmVyCiAgdmFyIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIHVzZWQgZm9yIHdvcmQgc3RvcmFnZQogIHZhciBfdyA9IG5ldyBBcnJheSg4MCk7CgogIC8vIG1lc3NhZ2UgZGlnZXN0IG9iamVjdAogIHZhciBtZCA9IHsKICAgIGFsZ29yaXRobTogJ3NoYTEnLAogICAgYmxvY2tMZW5ndGg6IDY0LAogICAgZGlnZXN0TGVuZ3RoOiAyMCwKICAgIC8vIDU2LWJpdCBsZW5ndGggb2YgbWVzc2FnZSBzbyBmYXIgKGRvZXMgbm90IGluY2x1ZGluZyBwYWRkaW5nKQogICAgbWVzc2FnZUxlbmd0aDogMCwKICAgIC8vIHRydWUgbWVzc2FnZSBsZW5ndGgKICAgIGZ1bGxNZXNzYWdlTGVuZ3RoOiBudWxsLAogICAgLy8gc2l6ZSBvZiBtZXNzYWdlIGxlbmd0aCBpbiBieXRlcwogICAgbWVzc2FnZUxlbmd0aFNpemU6IDgKICB9OwoKICAvKioKICAgKiBTdGFydHMgdGhlIGRpZ2VzdC4KICAgKgogICAqIEByZXR1cm4gdGhpcyBkaWdlc3Qgb2JqZWN0LgogICAqLwogIG1kLnN0YXJ0ID0gZnVuY3Rpb24oKSB7CiAgICAvLyB1cCB0byA1Ni1iaXQgbWVzc2FnZSBsZW5ndGggZm9yIGNvbnZlbmllbmNlCiAgICBtZC5tZXNzYWdlTGVuZ3RoID0gMDsKCiAgICAvLyBmdWxsIG1lc3NhZ2UgbGVuZ3RoIChzZXQgbWQubWVzc2FnZUxlbmd0aDY0IGZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSkKICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoID0gbWQubWVzc2FnZUxlbmd0aDY0ID0gW107CiAgICB2YXIgaW50MzJzID0gbWQubWVzc2FnZUxlbmd0aFNpemUgLyA0OwogICAgZm9yKHZhciBpID0gMDsgaSA8IGludDMyczsgKytpKSB7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLnB1c2goMCk7CiAgICB9CiAgICBfaW5wdXQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgX3N0YXRlID0gewogICAgICBoMDogMHg2NzQ1MjMwMSwKICAgICAgaDE6IDB4RUZDREFCODksCiAgICAgIGgyOiAweDk4QkFEQ0ZFLAogICAgICBoMzogMHgxMDMyNTQ3NiwKICAgICAgaDQ6IDB4QzNEMkUxRjAKICAgIH07CiAgICByZXR1cm4gbWQ7CiAgfTsKICAvLyBzdGFydCBkaWdlc3QgYXV0b21hdGljYWxseSBmb3IgZmlyc3QgdGltZQogIG1kLnN0YXJ0KCk7CgogIC8qKgogICAqIFVwZGF0ZXMgdGhlIGRpZ2VzdCB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlIGlucHV0LiBUaGUgZ2l2ZW4gaW5wdXQgY2FuCiAgICogdHJlYXRlZCBhcyByYXcgaW5wdXQgKG5vIGVuY29kaW5nIHdpbGwgYmUgYXBwbGllZCkgb3IgYW4gZW5jb2Rpbmcgb2YKICAgKiAndXRmOCcgbWF5YmUgZ2l2ZW4gdG8gZW5jb2RlIHRoZSBpbnB1dCB1c2luZyBVVEYtOC4KICAgKgogICAqIEBwYXJhbSBtc2cgdGhlIG1lc3NhZ2UgaW5wdXQgdG8gdXBkYXRlIHdpdGguCiAgICogQHBhcmFtIGVuY29kaW5nIHRoZSBlbmNvZGluZyB0byB1c2UgKGRlZmF1bHQ6ICdyYXcnLCBvdGhlcjogJ3V0ZjgnKS4KICAgKgogICAqIEByZXR1cm4gdGhpcyBkaWdlc3Qgb2JqZWN0LgogICAqLwogIG1kLnVwZGF0ZSA9IGZ1bmN0aW9uKG1zZywgZW5jb2RpbmcpIHsKICAgIGlmKGVuY29kaW5nID09PSAndXRmOCcpIHsKICAgICAgbXNnID0gZm9yZ2UudXRpbC5lbmNvZGVVdGY4KG1zZyk7CiAgICB9CgogICAgLy8gdXBkYXRlIG1lc3NhZ2UgbGVuZ3RoCiAgICB2YXIgbGVuID0gbXNnLmxlbmd0aDsKICAgIG1kLm1lc3NhZ2VMZW5ndGggKz0gbGVuOwogICAgbGVuID0gWyhsZW4gLyAweDEwMDAwMDAwMCkgPj4+IDAsIGxlbiA+Pj4gMF07CiAgICBmb3IodmFyIGkgPSBtZC5mdWxsTWVzc2FnZUxlbmd0aC5sZW5ndGggLSAxOyBpID49IDA7IC0taSkgewogICAgICBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSArPSBsZW5bMV07CiAgICAgIGxlblsxXSA9IGxlblswXSArICgobWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gLyAweDEwMDAwMDAwMCkgPj4+IDApOwogICAgICBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSA9IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldID4+PiAwOwogICAgICBsZW5bMF0gPSAoKGxlblsxXSAvIDB4MTAwMDAwMDAwKSA+Pj4gMCk7CiAgICB9CgogICAgLy8gYWRkIGJ5dGVzIHRvIGlucHV0IGJ1ZmZlcgogICAgX2lucHV0LnB1dEJ5dGVzKG1zZyk7CgogICAgLy8gcHJvY2VzcyBieXRlcwogICAgX3VwZGF0ZShfc3RhdGUsIF93LCBfaW5wdXQpOwoKICAgIC8vIGNvbXBhY3QgaW5wdXQgYnVmZmVyIGV2ZXJ5IDJLIG9yIGlmIGVtcHR5CiAgICBpZihfaW5wdXQucmVhZCA+IDIwNDggfHwgX2lucHV0Lmxlbmd0aCgpID09PSAwKSB7CiAgICAgIF9pbnB1dC5jb21wYWN0KCk7CiAgICB9CgogICAgcmV0dXJuIG1kOwogIH07CgogICAvKioKICAgICogUHJvZHVjZXMgdGhlIGRpZ2VzdC4KICAgICoKICAgICogQHJldHVybiBhIGJ5dGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGRpZ2VzdCB2YWx1ZS4KICAgICovCiAgIG1kLmRpZ2VzdCA9IGZ1bmN0aW9uKCkgewogICAgLyogTm90ZTogSGVyZSB3ZSBjb3B5IHRoZSByZW1haW5pbmcgYnl0ZXMgaW4gdGhlIGlucHV0IGJ1ZmZlciBhbmQKICAgIGFkZCB0aGUgYXBwcm9wcmlhdGUgU0hBLTEgcGFkZGluZy4gVGhlbiB3ZSBkbyB0aGUgZmluYWwgdXBkYXRlCiAgICBvbiBhIGNvcHkgb2YgdGhlIHN0YXRlIHNvIHRoYXQgaWYgdGhlIHVzZXIgd2FudHMgdG8gZ2V0CiAgICBpbnRlcm1lZGlhdGUgZGlnZXN0cyB0aGV5IGNhbiBkbyBzby4gKi8KCiAgICAvKiBEZXRlcm1pbmUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IG11c3QgYmUgYWRkZWQgdG8gdGhlIG1lc3NhZ2UKICAgIHRvIGVuc3VyZSBpdHMgbGVuZ3RoIGlzIGNvbmdydWVudCB0byA0NDggbW9kIDUxMi4gSW4gb3RoZXIgd29yZHMsCiAgICB0aGUgZGF0YSB0byBiZSBkaWdlc3RlZCBtdXN0IGJlIGEgbXVsdGlwbGUgb2YgNTEyIGJpdHMgKG9yIDEyOCBieXRlcykuCiAgICBUaGlzIGRhdGEgaW5jbHVkZXMgdGhlIG1lc3NhZ2UsIHNvbWUgcGFkZGluZywgYW5kIHRoZSBsZW5ndGggb2YgdGhlCiAgICBtZXNzYWdlLiBTaW5jZSB0aGUgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlIHdpbGwgYmUgZW5jb2RlZCBhcyA4IGJ5dGVzICg2NAogICAgYml0cyksIHRoYXQgbWVhbnMgdGhhdCB0aGUgbGFzdCBzZWdtZW50IG9mIHRoZSBkYXRhIG11c3QgaGF2ZSA1NiBieXRlcwogICAgKDQ0OCBiaXRzKSBvZiBtZXNzYWdlIGFuZCBwYWRkaW5nLiBUaGVyZWZvcmUsIHRoZSBsZW5ndGggb2YgdGhlIG1lc3NhZ2UKICAgIHBsdXMgdGhlIHBhZGRpbmcgbXVzdCBiZSBjb25ncnVlbnQgdG8gNDQ4IG1vZCA1MTIgYmVjYXVzZQogICAgNTEyIC0gMTI4ID0gNDQ4LgoKICAgIEluIG9yZGVyIHRvIGZpbGwgdXAgdGhlIG1lc3NhZ2UgbGVuZ3RoIGl0IG11c3QgYmUgZmlsbGVkIHdpdGgKICAgIHBhZGRpbmcgdGhhdCBiZWdpbnMgd2l0aCAxIGJpdCBmb2xsb3dlZCBieSBhbGwgMCBiaXRzLiBQYWRkaW5nCiAgICBtdXN0ICphbHdheXMqIGJlIHByZXNlbnQsIHNvIGlmIHRoZSBtZXNzYWdlIGxlbmd0aCBpcyBhbHJlYWR5CiAgICBjb25ncnVlbnQgdG8gNDQ4IG1vZCA1MTIsIHRoZW4gNTEyIHBhZGRpbmcgYml0cyBtdXN0IGJlIGFkZGVkLiAqLwoKICAgIHZhciBmaW5hbEJsb2NrID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGZpbmFsQmxvY2sucHV0Qnl0ZXMoX2lucHV0LmJ5dGVzKCkpOwoKICAgIC8vIGNvbXB1dGUgcmVtYWluaW5nIHNpemUgdG8gYmUgZGlnZXN0ZWQgKGluY2x1ZGUgbWVzc2FnZSBsZW5ndGggc2l6ZSkKICAgIHZhciByZW1haW5pbmcgPSAoCiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW21kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aCAtIDFdICsKICAgICAgbWQubWVzc2FnZUxlbmd0aFNpemUpOwoKICAgIC8vIGFkZCBwYWRkaW5nIGZvciBvdmVyZmxvdyBibG9ja1NpemUgLSBvdmVyZmxvdwogICAgLy8gX3BhZGRpbmcgc3RhcnRzIHdpdGggMSBieXRlIHdpdGggZmlyc3QgYml0IGlzIHNldCAoYnl0ZSB2YWx1ZSAxMjgpLCB0aGVuCiAgICAvLyB0aGVyZSBtYXkgYmUgdXAgdG8gKGJsb2NrU2l6ZSAtIDEpIG90aGVyIHBhZCBieXRlcwogICAgdmFyIG92ZXJmbG93ID0gcmVtYWluaW5nICYgKG1kLmJsb2NrTGVuZ3RoIC0gMSk7CiAgICBmaW5hbEJsb2NrLnB1dEJ5dGVzKF9wYWRkaW5nLnN1YnN0cigwLCBtZC5ibG9ja0xlbmd0aCAtIG92ZXJmbG93KSk7CgogICAgLy8gc2VyaWFsaXplIG1lc3NhZ2UgbGVuZ3RoIGluIGJpdHMgaW4gYmlnLWVuZGlhbiBvcmRlcjsgc2luY2UgbGVuZ3RoCiAgICAvLyBpcyBzdG9yZWQgaW4gYnl0ZXMgd2UgbXVsdGlwbHkgYnkgOCBhbmQgYWRkIGNhcnJ5IGZyb20gbmV4dCBpbnQKICAgIHZhciBtZXNzYWdlTGVuZ3RoID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIHZhciBuZXh0LCBjYXJyeTsKICAgIHZhciBiaXRzID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbMF0gKiA4OwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aDsgKytpKSB7CiAgICAgIG5leHQgPSBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpICsgMV0gKiA4OwogICAgICBjYXJyeSA9IChuZXh0IC8gMHgxMDAwMDAwMDApID4+PiAwOwogICAgICBiaXRzICs9IGNhcnJ5OwogICAgICBmaW5hbEJsb2NrLnB1dEludDMyKGJpdHMgPj4+IDApOwogICAgICBiaXRzID0gbmV4dDsKICAgIH0KCiAgICB2YXIgczIgPSB7CiAgICAgIGgwOiBfc3RhdGUuaDAsCiAgICAgIGgxOiBfc3RhdGUuaDEsCiAgICAgIGgyOiBfc3RhdGUuaDIsCiAgICAgIGgzOiBfc3RhdGUuaDMsCiAgICAgIGg0OiBfc3RhdGUuaDQKICAgIH07CiAgICBfdXBkYXRlKHMyLCBfdywgZmluYWxCbG9jayk7CiAgICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBydmFsLnB1dEludDMyKHMyLmgwKTsKICAgIHJ2YWwucHV0SW50MzIoczIuaDEpOwogICAgcnZhbC5wdXRJbnQzMihzMi5oMik7CiAgICBydmFsLnB1dEludDMyKHMyLmgzKTsKICAgIHJ2YWwucHV0SW50MzIoczIuaDQpOwogICAgcmV0dXJuIHJ2YWw7CiAgfTsKCiAgcmV0dXJuIG1kOwp9OwoKLy8gc2hhLTEgcGFkZGluZyBieXRlcyBub3QgaW5pdGlhbGl6ZWQgeWV0CnZhciBfcGFkZGluZyA9IG51bGw7CnZhciBfaW5pdGlhbGl6ZWQgPSBmYWxzZTsKCi8qKgogKiBJbml0aWFsaXplcyB0aGUgY29uc3RhbnQgdGFibGVzLgogKi8KZnVuY3Rpb24gX2luaXQoKSB7CiAgLy8gY3JlYXRlIHBhZGRpbmcKICBfcGFkZGluZyA9IFN0cmluZy5mcm9tQ2hhckNvZGUoMTI4KTsKICBfcGFkZGluZyArPSBmb3JnZS51dGlsLmZpbGxTdHJpbmcoU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKSwgNjQpOwoKICAvLyBub3cgaW5pdGlhbGl6ZWQKICBfaW5pdGlhbGl6ZWQgPSB0cnVlOwp9CgovKioKICogVXBkYXRlcyBhIFNIQS0xIHN0YXRlIHdpdGggdGhlIGdpdmVuIGJ5dGUgYnVmZmVyLgogKgogKiBAcGFyYW0gcyB0aGUgU0hBLTEgc3RhdGUgdG8gdXBkYXRlLgogKiBAcGFyYW0gdyB0aGUgYXJyYXkgdG8gdXNlIHRvIHN0b3JlIHdvcmRzLgogKiBAcGFyYW0gYnl0ZXMgdGhlIGJ5dGUgYnVmZmVyIHRvIHVwZGF0ZSB3aXRoLgogKi8KZnVuY3Rpb24gX3VwZGF0ZShzLCB3LCBieXRlcykgewogIC8vIGNvbnN1bWUgNTEyIGJpdCAoNjQgYnl0ZSkgY2h1bmtzCiAgdmFyIHQsIGEsIGIsIGMsIGQsIGUsIGYsIGk7CiAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aCgpOwogIHdoaWxlKGxlbiA+PSA2NCkgewogICAgLy8gdGhlIHcgYXJyYXkgd2lsbCBiZSBwb3B1bGF0ZWQgd2l0aCBzaXh0ZWVuIDMyLWJpdCBiaWctZW5kaWFuIHdvcmRzCiAgICAvLyBhbmQgdGhlbiBleHRlbmRlZCBpbnRvIDgwIDMyLWJpdCB3b3JkcyBhY2NvcmRpbmcgdG8gU0hBLTEgYWxnb3JpdGhtCiAgICAvLyBhbmQgZm9yIDMyLTc5IHVzaW5nIE1heCBMb2NrdHl1a2hpbidzIG9wdGltaXphdGlvbgoKICAgIC8vIGluaXRpYWxpemUgaGFzaCB2YWx1ZSBmb3IgdGhpcyBjaHVuawogICAgYSA9IHMuaDA7CiAgICBiID0gcy5oMTsKICAgIGMgPSBzLmgyOwogICAgZCA9IHMuaDM7CiAgICBlID0gcy5oNDsKCiAgICAvLyByb3VuZCAxCiAgICBmb3IoaSA9IDA7IGkgPCAxNjsgKytpKSB7CiAgICAgIHQgPSBieXRlcy5nZXRJbnQzMigpOwogICAgICB3W2ldID0gdDsKICAgICAgZiA9IGQgXiAoYiAmIChjIF4gZCkpOwogICAgICB0ID0gKChhIDw8IDUpIHwgKGEgPj4+IDI3KSkgKyBmICsgZSArIDB4NUE4Mjc5OTkgKyB0OwogICAgICBlID0gZDsKICAgICAgZCA9IGM7CiAgICAgIGMgPSAoYiA8PCAzMCkgfCAoYiA+Pj4gMik7CiAgICAgIGIgPSBhOwogICAgICBhID0gdDsKICAgIH0KICAgIGZvcig7IGkgPCAyMDsgKytpKSB7CiAgICAgIHQgPSAod1tpIC0gM10gXiB3W2kgLSA4XSBeIHdbaSAtIDE0XSBeIHdbaSAtIDE2XSk7CiAgICAgIHQgPSAodCA8PCAxKSB8ICh0ID4+PiAzMSk7CiAgICAgIHdbaV0gPSB0OwogICAgICBmID0gZCBeIChiICYgKGMgXiBkKSk7CiAgICAgIHQgPSAoKGEgPDwgNSkgfCAoYSA+Pj4gMjcpKSArIGYgKyBlICsgMHg1QTgyNzk5OSArIHQ7CiAgICAgIGUgPSBkOwogICAgICBkID0gYzsKICAgICAgYyA9IChiIDw8IDMwKSB8IChiID4+PiAyKTsKICAgICAgYiA9IGE7CiAgICAgIGEgPSB0OwogICAgfQogICAgLy8gcm91bmQgMgogICAgZm9yKDsgaSA8IDMyOyArK2kpIHsKICAgICAgdCA9ICh3W2kgLSAzXSBeIHdbaSAtIDhdIF4gd1tpIC0gMTRdIF4gd1tpIC0gMTZdKTsKICAgICAgdCA9ICh0IDw8IDEpIHwgKHQgPj4+IDMxKTsKICAgICAgd1tpXSA9IHQ7CiAgICAgIGYgPSBiIF4gYyBeIGQ7CiAgICAgIHQgPSAoKGEgPDwgNSkgfCAoYSA+Pj4gMjcpKSArIGYgKyBlICsgMHg2RUQ5RUJBMSArIHQ7CiAgICAgIGUgPSBkOwogICAgICBkID0gYzsKICAgICAgYyA9IChiIDw8IDMwKSB8IChiID4+PiAyKTsKICAgICAgYiA9IGE7CiAgICAgIGEgPSB0OwogICAgfQogICAgZm9yKDsgaSA8IDQwOyArK2kpIHsKICAgICAgdCA9ICh3W2kgLSA2XSBeIHdbaSAtIDE2XSBeIHdbaSAtIDI4XSBeIHdbaSAtIDMyXSk7CiAgICAgIHQgPSAodCA8PCAyKSB8ICh0ID4+PiAzMCk7CiAgICAgIHdbaV0gPSB0OwogICAgICBmID0gYiBeIGMgXiBkOwogICAgICB0ID0gKChhIDw8IDUpIHwgKGEgPj4+IDI3KSkgKyBmICsgZSArIDB4NkVEOUVCQTEgKyB0OwogICAgICBlID0gZDsKICAgICAgZCA9IGM7CiAgICAgIGMgPSAoYiA8PCAzMCkgfCAoYiA+Pj4gMik7CiAgICAgIGIgPSBhOwogICAgICBhID0gdDsKICAgIH0KICAgIC8vIHJvdW5kIDMKICAgIGZvcig7IGkgPCA2MDsgKytpKSB7CiAgICAgIHQgPSAod1tpIC0gNl0gXiB3W2kgLSAxNl0gXiB3W2kgLSAyOF0gXiB3W2kgLSAzMl0pOwogICAgICB0ID0gKHQgPDwgMikgfCAodCA+Pj4gMzApOwogICAgICB3W2ldID0gdDsKICAgICAgZiA9IChiICYgYykgfCAoZCAmIChiIF4gYykpOwogICAgICB0ID0gKChhIDw8IDUpIHwgKGEgPj4+IDI3KSkgKyBmICsgZSArIDB4OEYxQkJDREMgKyB0OwogICAgICBlID0gZDsKICAgICAgZCA9IGM7CiAgICAgIGMgPSAoYiA8PCAzMCkgfCAoYiA+Pj4gMik7CiAgICAgIGIgPSBhOwogICAgICBhID0gdDsKICAgIH0KICAgIC8vIHJvdW5kIDQKICAgIGZvcig7IGkgPCA4MDsgKytpKSB7CiAgICAgIHQgPSAod1tpIC0gNl0gXiB3W2kgLSAxNl0gXiB3W2kgLSAyOF0gXiB3W2kgLSAzMl0pOwogICAgICB0ID0gKHQgPDwgMikgfCAodCA+Pj4gMzApOwogICAgICB3W2ldID0gdDsKICAgICAgZiA9IGIgXiBjIF4gZDsKICAgICAgdCA9ICgoYSA8PCA1KSB8IChhID4+PiAyNykpICsgZiArIGUgKyAweENBNjJDMUQ2ICsgdDsKICAgICAgZSA9IGQ7CiAgICAgIGQgPSBjOwogICAgICBjID0gKGIgPDwgMzApIHwgKGIgPj4+IDIpOwogICAgICBiID0gYTsKICAgICAgYSA9IHQ7CiAgICB9CgogICAgLy8gdXBkYXRlIGhhc2ggc3RhdGUKICAgIHMuaDAgPSAocy5oMCArIGEpIHwgMDsKICAgIHMuaDEgPSAocy5oMSArIGIpIHwgMDsKICAgIHMuaDIgPSAocy5oMiArIGMpIHwgMDsKICAgIHMuaDMgPSAocy5oMyArIGQpIHwgMDsKICAgIHMuaDQgPSAocy5oNCArIGUpIHwgMDsKCiAgICBsZW4gLT0gNjQ7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdzaGExJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3NoYTEnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFNlY3VyZSBIYXNoIEFsZ29yaXRobSB3aXRoIDI1Ni1iaXQgZGlnZXN0IChTSEEtMjU2KSBpbXBsZW1lbnRhdGlvbi4KICoKICogU2VlIEZJUFMgMTgwLTIgZm9yIGRldGFpbHMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDE1IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKdmFyIHNoYTI1NiA9IGZvcmdlLnNoYTI1NiA9IGZvcmdlLnNoYTI1NiB8fCB7fTsKZm9yZ2UubWQgPSBmb3JnZS5tZCB8fCB7fTsKZm9yZ2UubWQuYWxnb3JpdGhtcyA9IGZvcmdlLm1kLmFsZ29yaXRobXMgfHwge307CmZvcmdlLm1kLnNoYTI1NiA9IGZvcmdlLm1kLmFsZ29yaXRobXMuc2hhMjU2ID0gc2hhMjU2OwoKLyoqCiAqIENyZWF0ZXMgYSBTSEEtMjU2IG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICoKICogQHJldHVybiBhIG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICovCnNoYTI1Ni5jcmVhdGUgPSBmdW5jdGlvbigpIHsKICAvLyBkbyBpbml0aWFsaXphdGlvbiBhcyBuZWNlc3NhcnkKICBpZighX2luaXRpYWxpemVkKSB7CiAgICBfaW5pdCgpOwogIH0KCiAgLy8gU0hBLTI1NiBzdGF0ZSBjb250YWlucyBlaWdodCAzMi1iaXQgaW50ZWdlcnMKICB2YXIgX3N0YXRlID0gbnVsbDsKCiAgLy8gaW5wdXQgYnVmZmVyCiAgdmFyIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIHVzZWQgZm9yIHdvcmQgc3RvcmFnZQogIHZhciBfdyA9IG5ldyBBcnJheSg2NCk7CgogIC8vIG1lc3NhZ2UgZGlnZXN0IG9iamVjdAogIHZhciBtZCA9IHsKICAgIGFsZ29yaXRobTogJ3NoYTI1NicsCiAgICBibG9ja0xlbmd0aDogNjQsCiAgICBkaWdlc3RMZW5ndGg6IDMyLAogICAgLy8gNTYtYml0IGxlbmd0aCBvZiBtZXNzYWdlIHNvIGZhciAoZG9lcyBub3QgaW5jbHVkaW5nIHBhZGRpbmcpCiAgICBtZXNzYWdlTGVuZ3RoOiAwLAogICAgLy8gdHJ1ZSBtZXNzYWdlIGxlbmd0aAogICAgZnVsbE1lc3NhZ2VMZW5ndGg6IG51bGwsCiAgICAvLyBzaXplIG9mIG1lc3NhZ2UgbGVuZ3RoIGluIGJ5dGVzCiAgICBtZXNzYWdlTGVuZ3RoU2l6ZTogOAogIH07CgogIC8qKgogICAqIFN0YXJ0cyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQuc3RhcnQgPSBmdW5jdGlvbigpIHsKICAgIC8vIHVwIHRvIDU2LWJpdCBtZXNzYWdlIGxlbmd0aCBmb3IgY29udmVuaWVuY2UKICAgIG1kLm1lc3NhZ2VMZW5ndGggPSAwOwoKICAgIC8vIGZ1bGwgbWVzc2FnZSBsZW5ndGggKHNldCBtZC5tZXNzYWdlTGVuZ3RoNjQgZm9yIGJhY2t3YXJkcy1jb21wYXRpYmlsaXR5KQogICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGggPSBtZC5tZXNzYWdlTGVuZ3RoNjQgPSBbXTsKICAgIHZhciBpbnQzMnMgPSBtZC5tZXNzYWdlTGVuZ3RoU2l6ZSAvIDQ7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgaW50MzJzOyArK2kpIHsKICAgICAgbWQuZnVsbE1lc3NhZ2VMZW5ndGgucHVzaCgwKTsKICAgIH0KICAgIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBfc3RhdGUgPSB7CiAgICAgIGgwOiAweDZBMDlFNjY3LAogICAgICBoMTogMHhCQjY3QUU4NSwKICAgICAgaDI6IDB4M0M2RUYzNzIsCiAgICAgIGgzOiAweEE1NEZGNTNBLAogICAgICBoNDogMHg1MTBFNTI3RiwKICAgICAgaDU6IDB4OUIwNTY4OEMsCiAgICAgIGg2OiAweDFGODNEOUFCLAogICAgICBoNzogMHg1QkUwQ0QxOQogICAgfTsKICAgIHJldHVybiBtZDsKICB9OwogIC8vIHN0YXJ0IGRpZ2VzdCBhdXRvbWF0aWNhbGx5IGZvciBmaXJzdCB0aW1lCiAgbWQuc3RhcnQoKTsKCiAgLyoqCiAgICogVXBkYXRlcyB0aGUgZGlnZXN0IHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UgaW5wdXQuIFRoZSBnaXZlbiBpbnB1dCBjYW4KICAgKiB0cmVhdGVkIGFzIHJhdyBpbnB1dCAobm8gZW5jb2Rpbmcgd2lsbCBiZSBhcHBsaWVkKSBvciBhbiBlbmNvZGluZyBvZgogICAqICd1dGY4JyBtYXliZSBnaXZlbiB0byBlbmNvZGUgdGhlIGlucHV0IHVzaW5nIFVURi04LgogICAqCiAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSBpbnB1dCB0byB1cGRhdGUgd2l0aC4KICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIHVzZSAoZGVmYXVsdDogJ3JhdycsIG90aGVyOiAndXRmOCcpLgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQudXBkYXRlID0gZnVuY3Rpb24obXNnLCBlbmNvZGluZykgewogICAgaWYoZW5jb2RpbmcgPT09ICd1dGY4JykgewogICAgICBtc2cgPSBmb3JnZS51dGlsLmVuY29kZVV0ZjgobXNnKTsKICAgIH0KCiAgICAvLyB1cGRhdGUgbWVzc2FnZSBsZW5ndGgKICAgIHZhciBsZW4gPSBtc2cubGVuZ3RoOwogICAgbWQubWVzc2FnZUxlbmd0aCArPSBsZW47CiAgICBsZW4gPSBbKGxlbiAvIDB4MTAwMDAwMDAwKSA+Pj4gMCwgbGVuID4+PiAwXTsKICAgIGZvcih2YXIgaSA9IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldICs9IGxlblsxXTsKICAgICAgbGVuWzFdID0gbGVuWzBdICsgKChtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSAvIDB4MTAwMDAwMDAwKSA+Pj4gMCk7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gPj4+IDA7CiAgICAgIGxlblswXSA9ICgobGVuWzFdIC8gMHgxMDAwMDAwMDApID4+PiAwKTsKICAgIH0KCiAgICAvLyBhZGQgYnl0ZXMgdG8gaW5wdXQgYnVmZmVyCiAgICBfaW5wdXQucHV0Qnl0ZXMobXNnKTsKCiAgICAvLyBwcm9jZXNzIGJ5dGVzCiAgICBfdXBkYXRlKF9zdGF0ZSwgX3csIF9pbnB1dCk7CgogICAgLy8gY29tcGFjdCBpbnB1dCBidWZmZXIgZXZlcnkgMksgb3IgaWYgZW1wdHkKICAgIGlmKF9pbnB1dC5yZWFkID4gMjA0OCB8fCBfaW5wdXQubGVuZ3RoKCkgPT09IDApIHsKICAgICAgX2lucHV0LmNvbXBhY3QoKTsKICAgIH0KCiAgICByZXR1cm4gbWQ7CiAgfTsKCiAgLyoqCiAgICogUHJvZHVjZXMgdGhlIGRpZ2VzdC4KICAgKgogICAqIEByZXR1cm4gYSBieXRlIGJ1ZmZlciBjb250YWluaW5nIHRoZSBkaWdlc3QgdmFsdWUuCiAgICovCiAgbWQuZGlnZXN0ID0gZnVuY3Rpb24oKSB7CiAgICAvKiBOb3RlOiBIZXJlIHdlIGNvcHkgdGhlIHJlbWFpbmluZyBieXRlcyBpbiB0aGUgaW5wdXQgYnVmZmVyIGFuZAogICAgYWRkIHRoZSBhcHByb3ByaWF0ZSBTSEEtMjU2IHBhZGRpbmcuIFRoZW4gd2UgZG8gdGhlIGZpbmFsIHVwZGF0ZQogICAgb24gYSBjb3B5IG9mIHRoZSBzdGF0ZSBzbyB0aGF0IGlmIHRoZSB1c2VyIHdhbnRzIHRvIGdldAogICAgaW50ZXJtZWRpYXRlIGRpZ2VzdHMgdGhleSBjYW4gZG8gc28uICovCgogICAgLyogRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgYnl0ZXMgdGhhdCBtdXN0IGJlIGFkZGVkIHRvIHRoZSBtZXNzYWdlCiAgICB0byBlbnN1cmUgaXRzIGxlbmd0aCBpcyBjb25ncnVlbnQgdG8gNDQ4IG1vZCA1MTIuIEluIG90aGVyIHdvcmRzLAogICAgdGhlIGRhdGEgdG8gYmUgZGlnZXN0ZWQgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDUxMiBiaXRzIChvciAxMjggYnl0ZXMpLgogICAgVGhpcyBkYXRhIGluY2x1ZGVzIHRoZSBtZXNzYWdlLCBzb21lIHBhZGRpbmcsIGFuZCB0aGUgbGVuZ3RoIG9mIHRoZQogICAgbWVzc2FnZS4gU2luY2UgdGhlIGxlbmd0aCBvZiB0aGUgbWVzc2FnZSB3aWxsIGJlIGVuY29kZWQgYXMgOCBieXRlcyAoNjQKICAgIGJpdHMpLCB0aGF0IG1lYW5zIHRoYXQgdGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgZGF0YSBtdXN0IGhhdmUgNTYgYnl0ZXMKICAgICg0NDggYml0cykgb2YgbWVzc2FnZSBhbmQgcGFkZGluZy4gVGhlcmVmb3JlLCB0aGUgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlCiAgICBwbHVzIHRoZSBwYWRkaW5nIG11c3QgYmUgY29uZ3J1ZW50IHRvIDQ0OCBtb2QgNTEyIGJlY2F1c2UKICAgIDUxMiAtIDEyOCA9IDQ0OC4KCiAgICBJbiBvcmRlciB0byBmaWxsIHVwIHRoZSBtZXNzYWdlIGxlbmd0aCBpdCBtdXN0IGJlIGZpbGxlZCB3aXRoCiAgICBwYWRkaW5nIHRoYXQgYmVnaW5zIHdpdGggMSBiaXQgZm9sbG93ZWQgYnkgYWxsIDAgYml0cy4gUGFkZGluZwogICAgbXVzdCAqYWx3YXlzKiBiZSBwcmVzZW50LCBzbyBpZiB0aGUgbWVzc2FnZSBsZW5ndGggaXMgYWxyZWFkeQogICAgY29uZ3J1ZW50IHRvIDQ0OCBtb2QgNTEyLCB0aGVuIDUxMiBwYWRkaW5nIGJpdHMgbXVzdCBiZSBhZGRlZC4gKi8KCiAgICB2YXIgZmluYWxCbG9jayA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBmaW5hbEJsb2NrLnB1dEJ5dGVzKF9pbnB1dC5ieXRlcygpKTsKCiAgICAvLyBjb21wdXRlIHJlbWFpbmluZyBzaXplIHRvIGJlIGRpZ2VzdGVkIChpbmNsdWRlIG1lc3NhZ2UgbGVuZ3RoIHNpemUpCiAgICB2YXIgcmVtYWluaW5nID0gKAogICAgICBtZC5mdWxsTWVzc2FnZUxlbmd0aFttZC5mdWxsTWVzc2FnZUxlbmd0aC5sZW5ndGggLSAxXSArCiAgICAgIG1kLm1lc3NhZ2VMZW5ndGhTaXplKTsKCiAgICAvLyBhZGQgcGFkZGluZyBmb3Igb3ZlcmZsb3cgYmxvY2tTaXplIC0gb3ZlcmZsb3cKICAgIC8vIF9wYWRkaW5nIHN0YXJ0cyB3aXRoIDEgYnl0ZSB3aXRoIGZpcnN0IGJpdCBpcyBzZXQgKGJ5dGUgdmFsdWUgMTI4KSwgdGhlbgogICAgLy8gdGhlcmUgbWF5IGJlIHVwIHRvIChibG9ja1NpemUgLSAxKSBvdGhlciBwYWQgYnl0ZXMKICAgIHZhciBvdmVyZmxvdyA9IHJlbWFpbmluZyAmIChtZC5ibG9ja0xlbmd0aCAtIDEpOwogICAgZmluYWxCbG9jay5wdXRCeXRlcyhfcGFkZGluZy5zdWJzdHIoMCwgbWQuYmxvY2tMZW5ndGggLSBvdmVyZmxvdykpOwoKICAgIC8vIHNlcmlhbGl6ZSBtZXNzYWdlIGxlbmd0aCBpbiBiaXRzIGluIGJpZy1lbmRpYW4gb3JkZXI7IHNpbmNlIGxlbmd0aAogICAgLy8gaXMgc3RvcmVkIGluIGJ5dGVzIHdlIG11bHRpcGx5IGJ5IDggYW5kIGFkZCBjYXJyeSBmcm9tIG5leHQgaW50CiAgICB2YXIgbWVzc2FnZUxlbmd0aCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICB2YXIgbmV4dCwgY2Fycnk7CiAgICB2YXIgYml0cyA9IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoWzBdICogODsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtZC5mdWxsTWVzc2FnZUxlbmd0aC5sZW5ndGg7ICsraSkgewogICAgICBuZXh0ID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaSArIDFdICogODsKICAgICAgY2FycnkgPSAobmV4dCAvIDB4MTAwMDAwMDAwKSA+Pj4gMDsKICAgICAgYml0cyArPSBjYXJyeTsKICAgICAgZmluYWxCbG9jay5wdXRJbnQzMihiaXRzID4+PiAwKTsKICAgICAgYml0cyA9IG5leHQ7CiAgICB9CgogICAgdmFyIHMyID0gewogICAgICBoMDogX3N0YXRlLmgwLAogICAgICBoMTogX3N0YXRlLmgxLAogICAgICBoMjogX3N0YXRlLmgyLAogICAgICBoMzogX3N0YXRlLmgzLAogICAgICBoNDogX3N0YXRlLmg0LAogICAgICBoNTogX3N0YXRlLmg1LAogICAgICBoNjogX3N0YXRlLmg2LAogICAgICBoNzogX3N0YXRlLmg3CiAgICB9OwogICAgX3VwZGF0ZShzMiwgX3csIGZpbmFsQmxvY2spOwogICAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgcnZhbC5wdXRJbnQzMihzMi5oMCk7CiAgICBydmFsLnB1dEludDMyKHMyLmgxKTsKICAgIHJ2YWwucHV0SW50MzIoczIuaDIpOwogICAgcnZhbC5wdXRJbnQzMihzMi5oMyk7CiAgICBydmFsLnB1dEludDMyKHMyLmg0KTsKICAgIHJ2YWwucHV0SW50MzIoczIuaDUpOwogICAgcnZhbC5wdXRJbnQzMihzMi5oNik7CiAgICBydmFsLnB1dEludDMyKHMyLmg3KTsKICAgIHJldHVybiBydmFsOwogIH07CgogIHJldHVybiBtZDsKfTsKCi8vIHNoYS0yNTYgcGFkZGluZyBieXRlcyBub3QgaW5pdGlhbGl6ZWQgeWV0CnZhciBfcGFkZGluZyA9IG51bGw7CnZhciBfaW5pdGlhbGl6ZWQgPSBmYWxzZTsKCi8vIHRhYmxlIG9mIGNvbnN0YW50cwp2YXIgX2sgPSBudWxsOwoKLyoqCiAqIEluaXRpYWxpemVzIHRoZSBjb25zdGFudCB0YWJsZXMuCiAqLwpmdW5jdGlvbiBfaW5pdCgpIHsKICAvLyBjcmVhdGUgcGFkZGluZwogIF9wYWRkaW5nID0gU3RyaW5nLmZyb21DaGFyQ29kZSgxMjgpOwogIF9wYWRkaW5nICs9IGZvcmdlLnV0aWwuZmlsbFN0cmluZyhTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDApLCA2NCk7CgogIC8vIGNyZWF0ZSBLIHRhYmxlIGZvciBTSEEtMjU2CiAgX2sgPSBbCiAgICAweDQyOGEyZjk4LCAweDcxMzc0NDkxLCAweGI1YzBmYmNmLCAweGU5YjVkYmE1LAogICAgMHgzOTU2YzI1YiwgMHg1OWYxMTFmMSwgMHg5MjNmODJhNCwgMHhhYjFjNWVkNSwKICAgIDB4ZDgwN2FhOTgsIDB4MTI4MzViMDEsIDB4MjQzMTg1YmUsIDB4NTUwYzdkYzMsCiAgICAweDcyYmU1ZDc0LCAweDgwZGViMWZlLCAweDliZGMwNmE3LCAweGMxOWJmMTc0LAogICAgMHhlNDliNjljMSwgMHhlZmJlNDc4NiwgMHgwZmMxOWRjNiwgMHgyNDBjYTFjYywKICAgIDB4MmRlOTJjNmYsIDB4NGE3NDg0YWEsIDB4NWNiMGE5ZGMsIDB4NzZmOTg4ZGEsCiAgICAweDk4M2U1MTUyLCAweGE4MzFjNjZkLCAweGIwMDMyN2M4LCAweGJmNTk3ZmM3LAogICAgMHhjNmUwMGJmMywgMHhkNWE3OTE0NywgMHgwNmNhNjM1MSwgMHgxNDI5Mjk2NywKICAgIDB4MjdiNzBhODUsIDB4MmUxYjIxMzgsIDB4NGQyYzZkZmMsIDB4NTMzODBkMTMsCiAgICAweDY1MGE3MzU0LCAweDc2NmEwYWJiLCAweDgxYzJjOTJlLCAweDkyNzIyYzg1LAogICAgMHhhMmJmZThhMSwgMHhhODFhNjY0YiwgMHhjMjRiOGI3MCwgMHhjNzZjNTFhMywKICAgIDB4ZDE5MmU4MTksIDB4ZDY5OTA2MjQsIDB4ZjQwZTM1ODUsIDB4MTA2YWEwNzAsCiAgICAweDE5YTRjMTE2LCAweDFlMzc2YzA4LCAweDI3NDg3NzRjLCAweDM0YjBiY2I1LAogICAgMHgzOTFjMGNiMywgMHg0ZWQ4YWE0YSwgMHg1YjljY2E0ZiwgMHg2ODJlNmZmMywKICAgIDB4NzQ4ZjgyZWUsIDB4NzhhNTYzNmYsIDB4ODRjODc4MTQsIDB4OGNjNzAyMDgsCiAgICAweDkwYmVmZmZhLCAweGE0NTA2Y2ViLCAweGJlZjlhM2Y3LCAweGM2NzE3OGYyXTsKCiAgLy8gbm93IGluaXRpYWxpemVkCiAgX2luaXRpYWxpemVkID0gdHJ1ZTsKfQoKLyoqCiAqIFVwZGF0ZXMgYSBTSEEtMjU2IHN0YXRlIHdpdGggdGhlIGdpdmVuIGJ5dGUgYnVmZmVyLgogKgogKiBAcGFyYW0gcyB0aGUgU0hBLTI1NiBzdGF0ZSB0byB1cGRhdGUuCiAqIEBwYXJhbSB3IHRoZSBhcnJheSB0byB1c2UgdG8gc3RvcmUgd29yZHMuCiAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZSBidWZmZXIgdG8gdXBkYXRlIHdpdGguCiAqLwpmdW5jdGlvbiBfdXBkYXRlKHMsIHcsIGJ5dGVzKSB7CiAgLy8gY29uc3VtZSA1MTIgYml0ICg2NCBieXRlKSBjaHVua3MKICB2YXIgdDEsIHQyLCBzMCwgczEsIGNoLCBtYWosIGksIGEsIGIsIGMsIGQsIGUsIGYsIGcsIGg7CiAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aCgpOwogIHdoaWxlKGxlbiA+PSA2NCkgewogICAgLy8gdGhlIHcgYXJyYXkgd2lsbCBiZSBwb3B1bGF0ZWQgd2l0aCBzaXh0ZWVuIDMyLWJpdCBiaWctZW5kaWFuIHdvcmRzCiAgICAvLyBhbmQgdGhlbiBleHRlbmRlZCBpbnRvIDY0IDMyLWJpdCB3b3JkcyBhY2NvcmRpbmcgdG8gU0hBLTI1NgogICAgZm9yKGkgPSAwOyBpIDwgMTY7ICsraSkgewogICAgICB3W2ldID0gYnl0ZXMuZ2V0SW50MzIoKTsKICAgIH0KICAgIGZvcig7IGkgPCA2NDsgKytpKSB7CiAgICAgIC8vIFhPUiB3b3JkIDIgd29yZHMgYWdvIHJvdCByaWdodCAxNywgcm90IHJpZ2h0IDE5LCBzaGZ0IHJpZ2h0IDEwCiAgICAgIHQxID0gd1tpIC0gMl07CiAgICAgIHQxID0KICAgICAgICAoKHQxID4+PiAxNykgfCAodDEgPDwgMTUpKSBeCiAgICAgICAgKCh0MSA+Pj4gMTkpIHwgKHQxIDw8IDEzKSkgXgogICAgICAgICh0MSA+Pj4gMTApOwogICAgICAvLyBYT1Igd29yZCAxNSB3b3JkcyBhZ28gcm90IHJpZ2h0IDcsIHJvdCByaWdodCAxOCwgc2hmdCByaWdodCAzCiAgICAgIHQyID0gd1tpIC0gMTVdOwogICAgICB0MiA9CiAgICAgICAgKCh0MiA+Pj4gNykgfCAodDIgPDwgMjUpKSBeCiAgICAgICAgKCh0MiA+Pj4gMTgpIHwgKHQyIDw8IDE0KSkgXgogICAgICAgICh0MiA+Pj4gMyk7CiAgICAgIC8vIHN1bSh0MSwgd29yZCA3IGFnbywgdDIsIHdvcmQgMTYgYWdvKSBtb2R1bG8gMl4zMgogICAgICB3W2ldID0gKHQxICsgd1tpIC0gN10gKyB0MiArIHdbaSAtIDE2XSkgfCAwOwogICAgfQoKICAgIC8vIGluaXRpYWxpemUgaGFzaCB2YWx1ZSBmb3IgdGhpcyBjaHVuawogICAgYSA9IHMuaDA7CiAgICBiID0gcy5oMTsKICAgIGMgPSBzLmgyOwogICAgZCA9IHMuaDM7CiAgICBlID0gcy5oNDsKICAgIGYgPSBzLmg1OwogICAgZyA9IHMuaDY7CiAgICBoID0gcy5oNzsKCiAgICAvLyByb3VuZCBmdW5jdGlvbgogICAgZm9yKGkgPSAwOyBpIDwgNjQ7ICsraSkgewogICAgICAvLyBTdW0xKGUpCiAgICAgIHMxID0KICAgICAgICAoKGUgPj4+IDYpIHwgKGUgPDwgMjYpKSBeCiAgICAgICAgKChlID4+PiAxMSkgfCAoZSA8PCAyMSkpIF4KICAgICAgICAoKGUgPj4+IDI1KSB8IChlIDw8IDcpKTsKICAgICAgLy8gQ2goZSwgZiwgZykgKG9wdGltaXplZCB0aGUgc2FtZSB3YXkgYXMgU0hBLTEpCiAgICAgIGNoID0gZyBeIChlICYgKGYgXiBnKSk7CiAgICAgIC8vIFN1bTAoYSkKICAgICAgczAgPQogICAgICAgICgoYSA+Pj4gMikgfCAoYSA8PCAzMCkpIF4KICAgICAgICAoKGEgPj4+IDEzKSB8IChhIDw8IDE5KSkgXgogICAgICAgICgoYSA+Pj4gMjIpIHwgKGEgPDwgMTApKTsKICAgICAgLy8gTWFqKGEsIGIsIGMpIChvcHRpbWl6ZWQgdGhlIHNhbWUgd2F5IGFzIFNIQS0xKQogICAgICBtYWogPSAoYSAmIGIpIHwgKGMgJiAoYSBeIGIpKTsKCiAgICAgIC8vIG1haW4gYWxnb3JpdGhtCiAgICAgIHQxID0gaCArIHMxICsgY2ggKyBfa1tpXSArIHdbaV07CiAgICAgIHQyID0gczAgKyBtYWo7CiAgICAgIGggPSBnOwogICAgICBnID0gZjsKICAgICAgZiA9IGU7CiAgICAgIGUgPSAoZCArIHQxKSB8IDA7CiAgICAgIGQgPSBjOwogICAgICBjID0gYjsKICAgICAgYiA9IGE7CiAgICAgIGEgPSAodDEgKyB0MikgfCAwOwogICAgfQoKICAgIC8vIHVwZGF0ZSBoYXNoIHN0YXRlCiAgICBzLmgwID0gKHMuaDAgKyBhKSB8IDA7CiAgICBzLmgxID0gKHMuaDEgKyBiKSB8IDA7CiAgICBzLmgyID0gKHMuaDIgKyBjKSB8IDA7CiAgICBzLmgzID0gKHMuaDMgKyBkKSB8IDA7CiAgICBzLmg0ID0gKHMuaDQgKyBlKSB8IDA7CiAgICBzLmg1ID0gKHMuaDUgKyBmKSB8IDA7CiAgICBzLmg2ID0gKHMuaDYgKyBnKSB8IDA7CiAgICBzLmg3ID0gKHMuaDcgKyBoKSB8IDA7CiAgICBsZW4gLT0gNjQ7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdzaGEyNTYnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvc2hhMjU2JyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBTZWN1cmUgSGFzaCBBbGdvcml0aG0gd2l0aCBhIDEwMjQtYml0IGJsb2NrIHNpemUgaW1wbGVtZW50YXRpb24uCiAqCiAqIFRoaXMgaW5jbHVkZXM6IFNIQS01MTIsIFNIQS0zODQsIFNIQS01MTIvMjI0LCBhbmQgU0hBLTUxMi8yNTYuIEZvcgogKiBTSEEtMjU2IChibG9jayBzaXplIDUxMiBiaXRzKSwgc2VlIHNoYTI1Ni5qcy4KICoKICogU2VlIEZJUFMgMTgwLTQgZm9yIGRldGFpbHMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxNC0yMDE1IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKdmFyIHNoYTUxMiA9IGZvcmdlLnNoYTUxMiA9IGZvcmdlLnNoYTUxMiB8fCB7fTsKZm9yZ2UubWQgPSBmb3JnZS5tZCB8fCB7fTsKZm9yZ2UubWQuYWxnb3JpdGhtcyA9IGZvcmdlLm1kLmFsZ29yaXRobXMgfHwge307CgovLyBTSEEtNTEyCmZvcmdlLm1kLnNoYTUxMiA9IGZvcmdlLm1kLmFsZ29yaXRobXMuc2hhNTEyID0gc2hhNTEyOwoKLy8gU0hBLTM4NAp2YXIgc2hhMzg0ID0gZm9yZ2Uuc2hhMzg0ID0gZm9yZ2Uuc2hhNTEyLnNoYTM4NCA9IGZvcmdlLnNoYTUxMi5zaGEzODQgfHwge307CnNoYTM4NC5jcmVhdGUgPSBmdW5jdGlvbigpIHsKICByZXR1cm4gc2hhNTEyLmNyZWF0ZSgnU0hBLTM4NCcpOwp9Owpmb3JnZS5tZC5zaGEzODQgPSBmb3JnZS5tZC5hbGdvcml0aG1zLnNoYTM4NCA9IHNoYTM4NDsKCi8vIFNIQS01MTIvMjU2CmZvcmdlLnNoYTUxMi5zaGEyNTYgPSBmb3JnZS5zaGE1MTIuc2hhMjU2IHx8IHsKICBjcmVhdGU6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHNoYTUxMi5jcmVhdGUoJ1NIQS01MTIvMjU2Jyk7CiAgfQp9Owpmb3JnZS5tZFsnc2hhNTEyLzI1NiddID0gZm9yZ2UubWQuYWxnb3JpdGhtc1snc2hhNTEyLzI1NiddID0KICBmb3JnZS5zaGE1MTIuc2hhMjU2OwoKLy8gU0hBLTUxMi8yMjQKZm9yZ2Uuc2hhNTEyLnNoYTIyNCA9IGZvcmdlLnNoYTUxMi5zaGEyMjQgfHwgewogIGNyZWF0ZTogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gc2hhNTEyLmNyZWF0ZSgnU0hBLTUxMi8yMjQnKTsKICB9Cn07CmZvcmdlLm1kWydzaGE1MTIvMjI0J10gPSBmb3JnZS5tZC5hbGdvcml0aG1zWydzaGE1MTIvMjI0J10gPQogIGZvcmdlLnNoYTUxMi5zaGEyMjQ7CgovKioKICogQ3JlYXRlcyBhIFNIQS0yIG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICoKICogQHBhcmFtIGFsZ29yaXRobSB0aGUgYWxnb3JpdGhtIHRvIHVzZSAoU0hBLTUxMiwgU0hBLTM4NCwgU0hBLTUxMi8yMjQsCiAqICAgICAgICAgIFNIQS01MTIvMjU2KS4KICoKICogQHJldHVybiBhIG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICovCnNoYTUxMi5jcmVhdGUgPSBmdW5jdGlvbihhbGdvcml0aG0pIHsKICAvLyBkbyBpbml0aWFsaXphdGlvbiBhcyBuZWNlc3NhcnkKICBpZighX2luaXRpYWxpemVkKSB7CiAgICBfaW5pdCgpOwogIH0KCiAgaWYodHlwZW9mIGFsZ29yaXRobSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIGFsZ29yaXRobSA9ICdTSEEtNTEyJzsKICB9CgogIGlmKCEoYWxnb3JpdGhtIGluIF9zdGF0ZXMpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgU0hBLTUxMiBhbGdvcml0aG06ICcgKyBhbGdvcml0aG0pOwogIH0KCiAgLy8gU0hBLTUxMiBzdGF0ZSBjb250YWlucyBlaWdodCA2NC1iaXQgaW50ZWdlcnMgKGVhY2ggYXMgdHdvIDMyLWJpdCBpbnRzKQogIHZhciBfc3RhdGUgPSBfc3RhdGVzW2FsZ29yaXRobV07CiAgdmFyIF9oID0gbnVsbDsKCiAgLy8gaW5wdXQgYnVmZmVyCiAgdmFyIF9pbnB1dCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIHVzZWQgZm9yIDY0LWJpdCB3b3JkIHN0b3JhZ2UKICB2YXIgX3cgPSBuZXcgQXJyYXkoODApOwogIGZvcih2YXIgd2kgPSAwOyB3aSA8IDgwOyArK3dpKSB7CiAgICBfd1t3aV0gPSBuZXcgQXJyYXkoMik7CiAgfQoKICAvLyBtZXNzYWdlIGRpZ2VzdCBvYmplY3QKICB2YXIgbWQgPSB7CiAgICAvLyBTSEEtNTEyID0+IHNoYTUxMgogICAgYWxnb3JpdGhtOiBhbGdvcml0aG0ucmVwbGFjZSgnLScsICcnKS50b0xvd2VyQ2FzZSgpLAogICAgYmxvY2tMZW5ndGg6IDEyOCwKICAgIGRpZ2VzdExlbmd0aDogNjQsCiAgICAvLyA1Ni1iaXQgbGVuZ3RoIG9mIG1lc3NhZ2Ugc28gZmFyIChkb2VzIG5vdCBpbmNsdWRpbmcgcGFkZGluZykKICAgIG1lc3NhZ2VMZW5ndGg6IDAsCiAgICAvLyB0cnVlIG1lc3NhZ2UgbGVuZ3RoCiAgICBmdWxsTWVzc2FnZUxlbmd0aDogbnVsbCwKICAgIC8vIHNpemUgb2YgbWVzc2FnZSBsZW5ndGggaW4gYnl0ZXMKICAgIG1lc3NhZ2VMZW5ndGhTaXplOiAxNgogIH07CgogIC8qKgogICAqIFN0YXJ0cyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQuc3RhcnQgPSBmdW5jdGlvbigpIHsKICAgIC8vIHVwIHRvIDU2LWJpdCBtZXNzYWdlIGxlbmd0aCBmb3IgY29udmVuaWVuY2UKICAgIG1kLm1lc3NhZ2VMZW5ndGggPSAwOwoKICAgIC8vIGZ1bGwgbWVzc2FnZSBsZW5ndGggKHNldCBtZC5tZXNzYWdlTGVuZ3RoMTI4IGZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eSkKICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoID0gbWQubWVzc2FnZUxlbmd0aDEyOCA9IFtdOwogICAgdmFyIGludDMycyA9IG1kLm1lc3NhZ2VMZW5ndGhTaXplIC8gNDsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBpbnQzMnM7ICsraSkgewogICAgICBtZC5mdWxsTWVzc2FnZUxlbmd0aC5wdXNoKDApOwogICAgfQogICAgX2lucHV0ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIF9oID0gbmV3IEFycmF5KF9zdGF0ZS5sZW5ndGgpOwogICAgZm9yKHZhciBpID0gMDsgaSA8IF9zdGF0ZS5sZW5ndGg7ICsraSkgewogICAgICBfaFtpXSA9IF9zdGF0ZVtpXS5zbGljZSgwKTsKICAgIH0KICAgIHJldHVybiBtZDsKICB9OwogIC8vIHN0YXJ0IGRpZ2VzdCBhdXRvbWF0aWNhbGx5IGZvciBmaXJzdCB0aW1lCiAgbWQuc3RhcnQoKTsKCiAgLyoqCiAgICogVXBkYXRlcyB0aGUgZGlnZXN0IHdpdGggdGhlIGdpdmVuIG1lc3NhZ2UgaW5wdXQuIFRoZSBnaXZlbiBpbnB1dCBjYW4KICAgKiB0cmVhdGVkIGFzIHJhdyBpbnB1dCAobm8gZW5jb2Rpbmcgd2lsbCBiZSBhcHBsaWVkKSBvciBhbiBlbmNvZGluZyBvZgogICAqICd1dGY4JyBtYXliZSBnaXZlbiB0byBlbmNvZGUgdGhlIGlucHV0IHVzaW5nIFVURi04LgogICAqCiAgICogQHBhcmFtIG1zZyB0aGUgbWVzc2FnZSBpbnB1dCB0byB1cGRhdGUgd2l0aC4KICAgKiBAcGFyYW0gZW5jb2RpbmcgdGhlIGVuY29kaW5nIHRvIHVzZSAoZGVmYXVsdDogJ3JhdycsIG90aGVyOiAndXRmOCcpLgogICAqCiAgICogQHJldHVybiB0aGlzIGRpZ2VzdCBvYmplY3QuCiAgICovCiAgbWQudXBkYXRlID0gZnVuY3Rpb24obXNnLCBlbmNvZGluZykgewogICAgaWYoZW5jb2RpbmcgPT09ICd1dGY4JykgewogICAgICBtc2cgPSBmb3JnZS51dGlsLmVuY29kZVV0ZjgobXNnKTsKICAgIH0KCiAgICAvLyB1cGRhdGUgbWVzc2FnZSBsZW5ndGgKICAgIHZhciBsZW4gPSBtc2cubGVuZ3RoOwogICAgbWQubWVzc2FnZUxlbmd0aCArPSBsZW47CiAgICBsZW4gPSBbKGxlbiAvIDB4MTAwMDAwMDAwKSA+Pj4gMCwgbGVuID4+PiAwXTsKICAgIGZvcih2YXIgaSA9IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSB7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldICs9IGxlblsxXTsKICAgICAgbGVuWzFdID0gbGVuWzBdICsgKChtZC5mdWxsTWVzc2FnZUxlbmd0aFtpXSAvIDB4MTAwMDAwMDAwKSA+Pj4gMCk7CiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW2ldID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbaV0gPj4+IDA7CiAgICAgIGxlblswXSA9ICgobGVuWzFdIC8gMHgxMDAwMDAwMDApID4+PiAwKTsKICAgIH0KCiAgICAvLyBhZGQgYnl0ZXMgdG8gaW5wdXQgYnVmZmVyCiAgICBfaW5wdXQucHV0Qnl0ZXMobXNnKTsKCiAgICAvLyBwcm9jZXNzIGJ5dGVzCiAgICBfdXBkYXRlKF9oLCBfdywgX2lucHV0KTsKCiAgICAvLyBjb21wYWN0IGlucHV0IGJ1ZmZlciBldmVyeSAySyBvciBpZiBlbXB0eQogICAgaWYoX2lucHV0LnJlYWQgPiAyMDQ4IHx8IF9pbnB1dC5sZW5ndGgoKSA9PT0gMCkgewogICAgICBfaW5wdXQuY29tcGFjdCgpOwogICAgfQoKICAgIHJldHVybiBtZDsKICB9OwoKICAvKioKICAgKiBQcm9kdWNlcyB0aGUgZGlnZXN0LgogICAqCiAgICogQHJldHVybiBhIGJ5dGUgYnVmZmVyIGNvbnRhaW5pbmcgdGhlIGRpZ2VzdCB2YWx1ZS4KICAgKi8KICBtZC5kaWdlc3QgPSBmdW5jdGlvbigpIHsKICAgIC8qIE5vdGU6IEhlcmUgd2UgY29weSB0aGUgcmVtYWluaW5nIGJ5dGVzIGluIHRoZSBpbnB1dCBidWZmZXIgYW5kCiAgICBhZGQgdGhlIGFwcHJvcHJpYXRlIFNIQS01MTIgcGFkZGluZy4gVGhlbiB3ZSBkbyB0aGUgZmluYWwgdXBkYXRlCiAgICBvbiBhIGNvcHkgb2YgdGhlIHN0YXRlIHNvIHRoYXQgaWYgdGhlIHVzZXIgd2FudHMgdG8gZ2V0CiAgICBpbnRlcm1lZGlhdGUgZGlnZXN0cyB0aGV5IGNhbiBkbyBzby4gKi8KCiAgICAvKiBEZXRlcm1pbmUgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IG11c3QgYmUgYWRkZWQgdG8gdGhlIG1lc3NhZ2UKICAgIHRvIGVuc3VyZSBpdHMgbGVuZ3RoIGlzIGNvbmdydWVudCB0byA4OTYgbW9kIDEwMjQuIEluIG90aGVyIHdvcmRzLAogICAgdGhlIGRhdGEgdG8gYmUgZGlnZXN0ZWQgbXVzdCBiZSBhIG11bHRpcGxlIG9mIDEwMjQgYml0cyAob3IgMTI4IGJ5dGVzKS4KICAgIFRoaXMgZGF0YSBpbmNsdWRlcyB0aGUgbWVzc2FnZSwgc29tZSBwYWRkaW5nLCBhbmQgdGhlIGxlbmd0aCBvZiB0aGUKICAgIG1lc3NhZ2UuIFNpbmNlIHRoZSBsZW5ndGggb2YgdGhlIG1lc3NhZ2Ugd2lsbCBiZSBlbmNvZGVkIGFzIDE2IGJ5dGVzICgxMjgKICAgIGJpdHMpLCB0aGF0IG1lYW5zIHRoYXQgdGhlIGxhc3Qgc2VnbWVudCBvZiB0aGUgZGF0YSBtdXN0IGhhdmUgMTEyIGJ5dGVzCiAgICAoODk2IGJpdHMpIG9mIG1lc3NhZ2UgYW5kIHBhZGRpbmcuIFRoZXJlZm9yZSwgdGhlIGxlbmd0aCBvZiB0aGUgbWVzc2FnZQogICAgcGx1cyB0aGUgcGFkZGluZyBtdXN0IGJlIGNvbmdydWVudCB0byA4OTYgbW9kIDEwMjQgYmVjYXVzZQogICAgMTAyNCAtIDEyOCA9IDg5Ni4KCiAgICBJbiBvcmRlciB0byBmaWxsIHVwIHRoZSBtZXNzYWdlIGxlbmd0aCBpdCBtdXN0IGJlIGZpbGxlZCB3aXRoCiAgICBwYWRkaW5nIHRoYXQgYmVnaW5zIHdpdGggMSBiaXQgZm9sbG93ZWQgYnkgYWxsIDAgYml0cy4gUGFkZGluZwogICAgbXVzdCAqYWx3YXlzKiBiZSBwcmVzZW50LCBzbyBpZiB0aGUgbWVzc2FnZSBsZW5ndGggaXMgYWxyZWFkeQogICAgY29uZ3J1ZW50IHRvIDg5NiBtb2QgMTAyNCwgdGhlbiAxMDI0IHBhZGRpbmcgYml0cyBtdXN0IGJlIGFkZGVkLiAqLwoKICAgIHZhciBmaW5hbEJsb2NrID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGZpbmFsQmxvY2sucHV0Qnl0ZXMoX2lucHV0LmJ5dGVzKCkpOwoKICAgIC8vIGNvbXB1dGUgcmVtYWluaW5nIHNpemUgdG8gYmUgZGlnZXN0ZWQgKGluY2x1ZGUgbWVzc2FnZSBsZW5ndGggc2l6ZSkKICAgIHZhciByZW1haW5pbmcgPSAoCiAgICAgIG1kLmZ1bGxNZXNzYWdlTGVuZ3RoW21kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aCAtIDFdICsKICAgICAgbWQubWVzc2FnZUxlbmd0aFNpemUpOwoKICAgIC8vIGFkZCBwYWRkaW5nIGZvciBvdmVyZmxvdyBibG9ja1NpemUgLSBvdmVyZmxvdwogICAgLy8gX3BhZGRpbmcgc3RhcnRzIHdpdGggMSBieXRlIHdpdGggZmlyc3QgYml0IGlzIHNldCAoYnl0ZSB2YWx1ZSAxMjgpLCB0aGVuCiAgICAvLyB0aGVyZSBtYXkgYmUgdXAgdG8gKGJsb2NrU2l6ZSAtIDEpIG90aGVyIHBhZCBieXRlcwogICAgdmFyIG92ZXJmbG93ID0gcmVtYWluaW5nICYgKG1kLmJsb2NrTGVuZ3RoIC0gMSk7CiAgICBmaW5hbEJsb2NrLnB1dEJ5dGVzKF9wYWRkaW5nLnN1YnN0cigwLCBtZC5ibG9ja0xlbmd0aCAtIG92ZXJmbG93KSk7CgogICAgLy8gc2VyaWFsaXplIG1lc3NhZ2UgbGVuZ3RoIGluIGJpdHMgaW4gYmlnLWVuZGlhbiBvcmRlcjsgc2luY2UgbGVuZ3RoCiAgICAvLyBpcyBzdG9yZWQgaW4gYnl0ZXMgd2UgbXVsdGlwbHkgYnkgOCBhbmQgYWRkIGNhcnJ5IGZyb20gbmV4dCBpbnQKICAgIHZhciBtZXNzYWdlTGVuZ3RoID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIHZhciBuZXh0LCBjYXJyeTsKICAgIHZhciBiaXRzID0gbWQuZnVsbE1lc3NhZ2VMZW5ndGhbMF0gKiA4OwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1kLmZ1bGxNZXNzYWdlTGVuZ3RoLmxlbmd0aDsgKytpKSB7CiAgICAgIG5leHQgPSBtZC5mdWxsTWVzc2FnZUxlbmd0aFtpICsgMV0gKiA4OwogICAgICBjYXJyeSA9IChuZXh0IC8gMHgxMDAwMDAwMDApID4+PiAwOwogICAgICBiaXRzICs9IGNhcnJ5OwogICAgICBmaW5hbEJsb2NrLnB1dEludDMyKGJpdHMgPj4+IDApOwogICAgICBiaXRzID0gbmV4dDsKICAgIH0KCiAgICB2YXIgaCA9IG5ldyBBcnJheShfaC5sZW5ndGgpOwogICAgZm9yKHZhciBpID0gMDsgaSA8IF9oLmxlbmd0aDsgKytpKSB7CiAgICAgIGhbaV0gPSBfaFtpXS5zbGljZSgwKTsKICAgIH0KICAgIF91cGRhdGUoaCwgX3csIGZpbmFsQmxvY2spOwogICAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgdmFyIGhsZW47CiAgICBpZihhbGdvcml0aG0gPT09ICdTSEEtNTEyJykgewogICAgICBobGVuID0gaC5sZW5ndGg7CiAgICB9IGVsc2UgaWYoYWxnb3JpdGhtID09PSAnU0hBLTM4NCcpIHsKICAgICAgaGxlbiA9IGgubGVuZ3RoIC0gMjsKICAgIH0gZWxzZSB7CiAgICAgIGhsZW4gPSBoLmxlbmd0aCAtIDQ7CiAgICB9CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgaGxlbjsgKytpKSB7CiAgICAgIHJ2YWwucHV0SW50MzIoaFtpXVswXSk7CiAgICAgIGlmKGkgIT09IGhsZW4gLSAxIHx8IGFsZ29yaXRobSAhPT0gJ1NIQS01MTIvMjI0JykgewogICAgICAgIHJ2YWwucHV0SW50MzIoaFtpXVsxXSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBydmFsOwogIH07CgogIHJldHVybiBtZDsKfTsKCi8vIHNoYS01MTIgcGFkZGluZyBieXRlcyBub3QgaW5pdGlhbGl6ZWQgeWV0CnZhciBfcGFkZGluZyA9IG51bGw7CnZhciBfaW5pdGlhbGl6ZWQgPSBmYWxzZTsKCi8vIHRhYmxlIG9mIGNvbnN0YW50cwp2YXIgX2sgPSBudWxsOwoKLy8gaW5pdGlhbCBoYXNoIHN0YXRlcwp2YXIgX3N0YXRlcyA9IG51bGw7CgovKioKICogSW5pdGlhbGl6ZXMgdGhlIGNvbnN0YW50IHRhYmxlcy4KICovCmZ1bmN0aW9uIF9pbml0KCkgewogIC8vIGNyZWF0ZSBwYWRkaW5nCiAgX3BhZGRpbmcgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKDEyOCk7CiAgX3BhZGRpbmcgKz0gZm9yZ2UudXRpbC5maWxsU3RyaW5nKFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwMCksIDEyOCk7CgogIC8vIGNyZWF0ZSBLIHRhYmxlIGZvciBTSEEtNTEyCiAgX2sgPSBbCiAgICBbMHg0MjhhMmY5OCwgMHhkNzI4YWUyMl0sIFsweDcxMzc0NDkxLCAweDIzZWY2NWNkXSwKICAgIFsweGI1YzBmYmNmLCAweGVjNGQzYjJmXSwgWzB4ZTliNWRiYTUsIDB4ODE4OWRiYmNdLAogICAgWzB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzhdLCBbMHg1OWYxMTFmMSwgMHhiNjA1ZDAxOV0sCiAgICBbMHg5MjNmODJhNCwgMHhhZjE5NGY5Yl0sIFsweGFiMWM1ZWQ1LCAweGRhNmQ4MTE4XSwKICAgIFsweGQ4MDdhYTk4LCAweGEzMDMwMjQyXSwgWzB4MTI4MzViMDEsIDB4NDU3MDZmYmVdLAogICAgWzB4MjQzMTg1YmUsIDB4NGVlNGIyOGNdLCBbMHg1NTBjN2RjMywgMHhkNWZmYjRlMl0sCiAgICBbMHg3MmJlNWQ3NCwgMHhmMjdiODk2Zl0sIFsweDgwZGViMWZlLCAweDNiMTY5NmIxXSwKICAgIFsweDliZGMwNmE3LCAweDI1YzcxMjM1XSwgWzB4YzE5YmYxNzQsIDB4Y2Y2OTI2OTRdLAogICAgWzB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDJdLCBbMHhlZmJlNDc4NiwgMHgzODRmMjVlM10sCiAgICBbMHgwZmMxOWRjNiwgMHg4YjhjZDViNV0sIFsweDI0MGNhMWNjLCAweDc3YWM5YzY1XSwKICAgIFsweDJkZTkyYzZmLCAweDU5MmIwMjc1XSwgWzB4NGE3NDg0YWEsIDB4NmVhNmU0ODNdLAogICAgWzB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDRdLCBbMHg3NmY5ODhkYSwgMHg4MzExNTNiNV0sCiAgICBbMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYl0sIFsweGE4MzFjNjZkLCAweDJkYjQzMjEwXSwKICAgIFsweGIwMDMyN2M4LCAweDk4ZmIyMTNmXSwgWzB4YmY1OTdmYzcsIDB4YmVlZjBlZTRdLAogICAgWzB4YzZlMDBiZjMsIDB4M2RhODhmYzJdLCBbMHhkNWE3OTE0NywgMHg5MzBhYTcyNV0sCiAgICBbMHgwNmNhNjM1MSwgMHhlMDAzODI2Zl0sIFsweDE0MjkyOTY3LCAweDBhMGU2ZTcwXSwKICAgIFsweDI3YjcwYTg1LCAweDQ2ZDIyZmZjXSwgWzB4MmUxYjIxMzgsIDB4NWMyNmM5MjZdLAogICAgWzB4NGQyYzZkZmMsIDB4NWFjNDJhZWRdLCBbMHg1MzM4MGQxMywgMHg5ZDk1YjNkZl0sCiAgICBbMHg2NTBhNzM1NCwgMHg4YmFmNjNkZV0sIFsweDc2NmEwYWJiLCAweDNjNzdiMmE4XSwKICAgIFsweDgxYzJjOTJlLCAweDQ3ZWRhZWU2XSwgWzB4OTI3MjJjODUsIDB4MTQ4MjM1M2JdLAogICAgWzB4YTJiZmU4YTEsIDB4NGNmMTAzNjRdLCBbMHhhODFhNjY0YiwgMHhiYzQyMzAwMV0sCiAgICBbMHhjMjRiOGI3MCwgMHhkMGY4OTc5MV0sIFsweGM3NmM1MWEzLCAweDA2NTRiZTMwXSwKICAgIFsweGQxOTJlODE5LCAweGQ2ZWY1MjE4XSwgWzB4ZDY5OTA2MjQsIDB4NTU2NWE5MTBdLAogICAgWzB4ZjQwZTM1ODUsIDB4NTc3MTIwMmFdLCBbMHgxMDZhYTA3MCwgMHgzMmJiZDFiOF0sCiAgICBbMHgxOWE0YzExNiwgMHhiOGQyZDBjOF0sIFsweDFlMzc2YzA4LCAweDUxNDFhYjUzXSwKICAgIFsweDI3NDg3NzRjLCAweGRmOGVlYjk5XSwgWzB4MzRiMGJjYjUsIDB4ZTE5YjQ4YThdLAogICAgWzB4MzkxYzBjYjMsIDB4YzVjOTVhNjNdLCBbMHg0ZWQ4YWE0YSwgMHhlMzQxOGFjYl0sCiAgICBbMHg1YjljY2E0ZiwgMHg3NzYzZTM3M10sIFsweDY4MmU2ZmYzLCAweGQ2YjJiOGEzXSwKICAgIFsweDc0OGY4MmVlLCAweDVkZWZiMmZjXSwgWzB4NzhhNTYzNmYsIDB4NDMxNzJmNjBdLAogICAgWzB4ODRjODc4MTQsIDB4YTFmMGFiNzJdLCBbMHg4Y2M3MDIwOCwgMHgxYTY0MzllY10sCiAgICBbMHg5MGJlZmZmYSwgMHgyMzYzMWUyOF0sIFsweGE0NTA2Y2ViLCAweGRlODJiZGU5XSwKICAgIFsweGJlZjlhM2Y3LCAweGIyYzY3OTE1XSwgWzB4YzY3MTc4ZjIsIDB4ZTM3MjUzMmJdLAogICAgWzB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWNdLCBbMHhkMTg2YjhjNywgMHgyMWMwYzIwN10sCiAgICBbMHhlYWRhN2RkNiwgMHhjZGUwZWIxZV0sIFsweGY1N2Q0ZjdmLCAweGVlNmVkMTc4XSwKICAgIFsweDA2ZjA2N2FhLCAweDcyMTc2ZmJhXSwgWzB4MGE2MzdkYzUsIDB4YTJjODk4YTZdLAogICAgWzB4MTEzZjk4MDQsIDB4YmVmOTBkYWVdLCBbMHgxYjcxMGIzNSwgMHgxMzFjNDcxYl0sCiAgICBbMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NF0sIFsweDMyY2FhYjdiLCAweDQwYzcyNDkzXSwKICAgIFsweDNjOWViZTBhLCAweDE1YzliZWJjXSwgWzB4NDMxZDY3YzQsIDB4OWMxMDBkNGNdLAogICAgWzB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjZdLCBbMHg1OTdmMjk5YywgMHhmYzY1N2UyYV0sCiAgICBbMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlY10sIFsweDZjNDQxOThjLCAweDRhNDc1ODE3XQogIF07CgogIC8vIGluaXRpYWwgaGFzaCBzdGF0ZXMKICBfc3RhdGVzID0ge307CiAgX3N0YXRlc1snU0hBLTUxMiddID0gWwogICAgWzB4NmEwOWU2NjcsIDB4ZjNiY2M5MDhdLAogICAgWzB4YmI2N2FlODUsIDB4ODRjYWE3M2JdLAogICAgWzB4M2M2ZWYzNzIsIDB4ZmU5NGY4MmJdLAogICAgWzB4YTU0ZmY1M2EsIDB4NWYxZDM2ZjFdLAogICAgWzB4NTEwZTUyN2YsIDB4YWRlNjgyZDFdLAogICAgWzB4OWIwNTY4OGMsIDB4MmIzZTZjMWZdLAogICAgWzB4MWY4M2Q5YWIsIDB4ZmI0MWJkNmJdLAogICAgWzB4NWJlMGNkMTksIDB4MTM3ZTIxNzldCiAgXTsKICBfc3RhdGVzWydTSEEtMzg0J10gPSBbCiAgICBbMHhjYmJiOWQ1ZCwgMHhjMTA1OWVkOF0sCiAgICBbMHg2MjlhMjkyYSwgMHgzNjdjZDUwN10sCiAgICBbMHg5MTU5MDE1YSwgMHgzMDcwZGQxN10sCiAgICBbMHgxNTJmZWNkOCwgMHhmNzBlNTkzOV0sCiAgICBbMHg2NzMzMjY2NywgMHhmZmMwMGIzMV0sCiAgICBbMHg4ZWI0NGE4NywgMHg2ODU4MTUxMV0sCiAgICBbMHhkYjBjMmUwZCwgMHg2NGY5OGZhN10sCiAgICBbMHg0N2I1NDgxZCwgMHhiZWZhNGZhNF0KICBdOwogIF9zdGF0ZXNbJ1NIQS01MTIvMjU2J10gPSBbCiAgICBbMHgyMjMxMjE5NCwgMHhGQzJCRjcyQ10sCiAgICBbMHg5RjU1NUZBMywgMHhDODRDNjRDMl0sCiAgICBbMHgyMzkzQjg2QiwgMHg2RjUzQjE1MV0sCiAgICBbMHg5NjM4NzcxOSwgMHg1OTQwRUFCRF0sCiAgICBbMHg5NjI4M0VFMiwgMHhBODhFRkZFM10sCiAgICBbMHhCRTVFMUUyNSwgMHg1Mzg2Mzk5Ml0sCiAgICBbMHgyQjAxOTlGQywgMHgyQzg1QjhBQV0sCiAgICBbMHgwRUI3MkREQywgMHg4MUM1MkNBMl0KICBdOwogIF9zdGF0ZXNbJ1NIQS01MTIvMjI0J10gPSBbCiAgICBbMHg4QzNEMzdDOCwgMHgxOTU0NERBMl0sCiAgICBbMHg3M0UxOTk2NiwgMHg4OURDRDRENl0sCiAgICBbMHgxREZBQjdBRSwgMHgzMkZGOUM4Ml0sCiAgICBbMHg2NzlERDUxNCwgMHg1ODJGOUZDRl0sCiAgICBbMHgwRjZEMkI2OSwgMHg3QkQ0NERBOF0sCiAgICBbMHg3N0UzNkY3MywgMHgwNEM0ODk0Ml0sCiAgICBbMHgzRjlEODVBOCwgMHg2QTFEMzZDOF0sCiAgICBbMHgxMTEyRTZBRCwgMHg5MUQ2OTJBMV0KICBdOwoKICAvLyBub3cgaW5pdGlhbGl6ZWQKICBfaW5pdGlhbGl6ZWQgPSB0cnVlOwp9CgovKioKICogVXBkYXRlcyBhIFNIQS01MTIgc3RhdGUgd2l0aCB0aGUgZ2l2ZW4gYnl0ZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBzIHRoZSBTSEEtNTEyIHN0YXRlIHRvIHVwZGF0ZS4KICogQHBhcmFtIHcgdGhlIGFycmF5IHRvIHVzZSB0byBzdG9yZSB3b3Jkcy4KICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlIGJ1ZmZlciB0byB1cGRhdGUgd2l0aC4KICovCmZ1bmN0aW9uIF91cGRhdGUocywgdywgYnl0ZXMpIHsKICAvLyBjb25zdW1lIDUxMiBiaXQgKDEyOCBieXRlKSBjaHVua3MKICB2YXIgdDFfaGksIHQxX2xvOwogIHZhciB0Ml9oaSwgdDJfbG87CiAgdmFyIHMwX2hpLCBzMF9sbzsKICB2YXIgczFfaGksIHMxX2xvOwogIHZhciBjaF9oaSwgY2hfbG87CiAgdmFyIG1hal9oaSwgbWFqX2xvOwogIHZhciBhX2hpLCBhX2xvOwogIHZhciBiX2hpLCBiX2xvOwogIHZhciBjX2hpLCBjX2xvOwogIHZhciBkX2hpLCBkX2xvOwogIHZhciBlX2hpLCBlX2xvOwogIHZhciBmX2hpLCBmX2xvOwogIHZhciBnX2hpLCBnX2xvOwogIHZhciBoX2hpLCBoX2xvOwogIHZhciBpLCBoaSwgbG8sIHcyLCB3NywgdzE1LCB3MTY7CiAgdmFyIGxlbiA9IGJ5dGVzLmxlbmd0aCgpOwogIHdoaWxlKGxlbiA+PSAxMjgpIHsKICAgIC8vIHRoZSB3IGFycmF5IHdpbGwgYmUgcG9wdWxhdGVkIHdpdGggc2l4dGVlbiA2NC1iaXQgYmlnLWVuZGlhbiB3b3JkcwogICAgLy8gYW5kIHRoZW4gZXh0ZW5kZWQgaW50byA2NCA2NC1iaXQgd29yZHMgYWNjb3JkaW5nIHRvIFNIQS01MTIKICAgIGZvcihpID0gMDsgaSA8IDE2OyArK2kpIHsKICAgICAgd1tpXVswXSA9IGJ5dGVzLmdldEludDMyKCkgPj4+IDA7CiAgICAgIHdbaV1bMV0gPSBieXRlcy5nZXRJbnQzMigpID4+PiAwOwogICAgfQogICAgZm9yKDsgaSA8IDgwOyArK2kpIHsKICAgICAgLy8gZm9yIHdvcmQgMiB3b3JkcyBhZ286IFJPVFIgMTkoeCkgXiBST1RSIDYxKHgpIF4gU0hSIDYoeCkKICAgICAgdzIgPSB3W2kgLSAyXTsKICAgICAgaGkgPSB3MlswXTsKICAgICAgbG8gPSB3MlsxXTsKCiAgICAgIC8vIGhpZ2ggYml0cwogICAgICB0MV9oaSA9ICgKICAgICAgICAoKGhpID4+PiAxOSkgfCAobG8gPDwgMTMpKSBeIC8vIFJPVFIgMTkKICAgICAgICAoKGxvID4+PiAyOSkgfCAoaGkgPDwgMykpIF4gLy8gUk9UUiA2MS8oc3dhcCArIFJPVFIgMjkpCiAgICAgICAgKGhpID4+PiA2KSkgPj4+IDA7IC8vIFNIUiA2CiAgICAgIC8vIGxvdyBiaXRzCiAgICAgIHQxX2xvID0gKAogICAgICAgICgoaGkgPDwgMTMpIHwgKGxvID4+PiAxOSkpIF4gLy8gUk9UUiAxOQogICAgICAgICgobG8gPDwgMykgfCAoaGkgPj4+IDI5KSkgXiAvLyBST1RSIDYxLyhzd2FwICsgUk9UUiAyOSkKICAgICAgICAoKGhpIDw8IDI2KSB8IChsbyA+Pj4gNikpKSA+Pj4gMDsgLy8gU0hSIDYKCiAgICAgIC8vIGZvciB3b3JkIDE1IHdvcmRzIGFnbzogUk9UUiAxKHgpIF4gUk9UUiA4KHgpIF4gU0hSIDcoeCkKICAgICAgdzE1ID0gd1tpIC0gMTVdOwogICAgICBoaSA9IHcxNVswXTsKICAgICAgbG8gPSB3MTVbMV07CgogICAgICAvLyBoaWdoIGJpdHMKICAgICAgdDJfaGkgPSAoCiAgICAgICAgKChoaSA+Pj4gMSkgfCAobG8gPDwgMzEpKSBeIC8vIFJPVFIgMQogICAgICAgICgoaGkgPj4+IDgpIHwgKGxvIDw8IDI0KSkgXiAvLyBST1RSIDgKICAgICAgICAoaGkgPj4+IDcpKSA+Pj4gMDsgLy8gU0hSIDcKICAgICAgLy8gbG93IGJpdHMKICAgICAgdDJfbG8gPSAoCiAgICAgICAgKChoaSA8PCAzMSkgfCAobG8gPj4+IDEpKSBeIC8vIFJPVFIgMQogICAgICAgICgoaGkgPDwgMjQpIHwgKGxvID4+PiA4KSkgXiAvLyBST1RSIDgKICAgICAgICAoKGhpIDw8IDI1KSB8IChsbyA+Pj4gNykpKSA+Pj4gMDsgLy8gU0hSIDcKCiAgICAgIC8vIHN1bSh0MSwgd29yZCA3IGFnbywgdDIsIHdvcmQgMTYgYWdvKSBtb2R1bG8gMl42NCAoY2FycnkgbG8gb3ZlcmZsb3cpCiAgICAgIHc3ID0gd1tpIC0gN107CiAgICAgIHcxNiA9IHdbaSAtIDE2XTsKICAgICAgbG8gPSAodDFfbG8gKyB3N1sxXSArIHQyX2xvICsgdzE2WzFdKTsKICAgICAgd1tpXVswXSA9ICh0MV9oaSArIHc3WzBdICsgdDJfaGkgKyB3MTZbMF0gKwogICAgICAgICgobG8gLyAweDEwMDAwMDAwMCkgPj4+IDApKSA+Pj4gMDsKICAgICAgd1tpXVsxXSA9IGxvID4+PiAwOwogICAgfQoKICAgIC8vIGluaXRpYWxpemUgaGFzaCB2YWx1ZSBmb3IgdGhpcyBjaHVuawogICAgYV9oaSA9IHNbMF1bMF07CiAgICBhX2xvID0gc1swXVsxXTsKICAgIGJfaGkgPSBzWzFdWzBdOwogICAgYl9sbyA9IHNbMV1bMV07CiAgICBjX2hpID0gc1syXVswXTsKICAgIGNfbG8gPSBzWzJdWzFdOwogICAgZF9oaSA9IHNbM11bMF07CiAgICBkX2xvID0gc1szXVsxXTsKICAgIGVfaGkgPSBzWzRdWzBdOwogICAgZV9sbyA9IHNbNF1bMV07CiAgICBmX2hpID0gc1s1XVswXTsKICAgIGZfbG8gPSBzWzVdWzFdOwogICAgZ19oaSA9IHNbNl1bMF07CiAgICBnX2xvID0gc1s2XVsxXTsKICAgIGhfaGkgPSBzWzddWzBdOwogICAgaF9sbyA9IHNbN11bMV07CgogICAgLy8gcm91bmQgZnVuY3Rpb24KICAgIGZvcihpID0gMDsgaSA8IDgwOyArK2kpIHsKICAgICAgLy8gU3VtMShlKSA9IFJPVFIgMTQoZSkgXiBST1RSIDE4KGUpIF4gUk9UUiA0MShlKQogICAgICBzMV9oaSA9ICgKICAgICAgICAoKGVfaGkgPj4+IDE0KSB8IChlX2xvIDw8IDE4KSkgXiAvLyBST1RSIDE0CiAgICAgICAgKChlX2hpID4+PiAxOCkgfCAoZV9sbyA8PCAxNCkpIF4gLy8gUk9UUiAxOAogICAgICAgICgoZV9sbyA+Pj4gOSkgfCAoZV9oaSA8PCAyMykpKSA+Pj4gMDsgLy8gUk9UUiA0MS8oc3dhcCArIFJPVFIgOSkKICAgICAgczFfbG8gPSAoCiAgICAgICAgKChlX2hpIDw8IDE4KSB8IChlX2xvID4+PiAxNCkpIF4gLy8gUk9UUiAxNAogICAgICAgICgoZV9oaSA8PCAxNCkgfCAoZV9sbyA+Pj4gMTgpKSBeIC8vIFJPVFIgMTgKICAgICAgICAoKGVfbG8gPDwgMjMpIHwgKGVfaGkgPj4+IDkpKSkgPj4+IDA7IC8vIFJPVFIgNDEvKHN3YXAgKyBST1RSIDkpCgogICAgICAvLyBDaChlLCBmLCBnKSAob3B0aW1pemVkIHRoZSBzYW1lIHdheSBhcyBTSEEtMSkKICAgICAgY2hfaGkgPSAoZ19oaSBeIChlX2hpICYgKGZfaGkgXiBnX2hpKSkpID4+PiAwOwogICAgICBjaF9sbyA9IChnX2xvIF4gKGVfbG8gJiAoZl9sbyBeIGdfbG8pKSkgPj4+IDA7CgogICAgICAvLyBTdW0wKGEpID0gUk9UUiAyOChhKSBeIFJPVFIgMzQoYSkgXiBST1RSIDM5KGEpCiAgICAgIHMwX2hpID0gKAogICAgICAgICgoYV9oaSA+Pj4gMjgpIHwgKGFfbG8gPDwgNCkpIF4gLy8gUk9UUiAyOAogICAgICAgICgoYV9sbyA+Pj4gMikgfCAoYV9oaSA8PCAzMCkpIF4gLy8gUk9UUiAzNC8oc3dhcCArIFJPVFIgMikKICAgICAgICAoKGFfbG8gPj4+IDcpIHwgKGFfaGkgPDwgMjUpKSkgPj4+IDA7IC8vIFJPVFIgMzkvKHN3YXAgKyBST1RSIDcpCiAgICAgIHMwX2xvID0gKAogICAgICAgICgoYV9oaSA8PCA0KSB8IChhX2xvID4+PiAyOCkpIF4gLy8gUk9UUiAyOAogICAgICAgICgoYV9sbyA8PCAzMCkgfCAoYV9oaSA+Pj4gMikpIF4gLy8gUk9UUiAzNC8oc3dhcCArIFJPVFIgMikKICAgICAgICAoKGFfbG8gPDwgMjUpIHwgKGFfaGkgPj4+IDcpKSkgPj4+IDA7IC8vIFJPVFIgMzkvKHN3YXAgKyBST1RSIDcpCgogICAgICAvLyBNYWooYSwgYiwgYykgKG9wdGltaXplZCB0aGUgc2FtZSB3YXkgYXMgU0hBLTEpCiAgICAgIG1hal9oaSA9ICgoYV9oaSAmIGJfaGkpIHwgKGNfaGkgJiAoYV9oaSBeIGJfaGkpKSkgPj4+IDA7CiAgICAgIG1hal9sbyA9ICgoYV9sbyAmIGJfbG8pIHwgKGNfbG8gJiAoYV9sbyBeIGJfbG8pKSkgPj4+IDA7CgogICAgICAvLyBtYWluIGFsZ29yaXRobQogICAgICAvLyB0MSA9IChoICsgczEgKyBjaCArIF9rW2ldICsgX3dbaV0pIG1vZHVsbyAyXjY0IChjYXJyeSBsbyBvdmVyZmxvdykKICAgICAgbG8gPSAoaF9sbyArIHMxX2xvICsgY2hfbG8gKyBfa1tpXVsxXSArIHdbaV1bMV0pOwogICAgICB0MV9oaSA9IChoX2hpICsgczFfaGkgKyBjaF9oaSArIF9rW2ldWzBdICsgd1tpXVswXSArCiAgICAgICAgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgICB0MV9sbyA9IGxvID4+PiAwOwoKICAgICAgLy8gdDIgPSBzMCArIG1haiBtb2R1bG8gMl42NCAoY2FycnkgbG8gb3ZlcmZsb3cpCiAgICAgIGxvID0gczBfbG8gKyBtYWpfbG87CiAgICAgIHQyX2hpID0gKHMwX2hpICsgbWFqX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgICB0Ml9sbyA9IGxvID4+PiAwOwoKICAgICAgaF9oaSA9IGdfaGk7CiAgICAgIGhfbG8gPSBnX2xvOwoKICAgICAgZ19oaSA9IGZfaGk7CiAgICAgIGdfbG8gPSBmX2xvOwoKICAgICAgZl9oaSA9IGVfaGk7CiAgICAgIGZfbG8gPSBlX2xvOwoKICAgICAgLy8gZSA9IChkICsgdDEpIG1vZHVsbyAyXjY0IChjYXJyeSBsbyBvdmVyZmxvdykKICAgICAgbG8gPSBkX2xvICsgdDFfbG87CiAgICAgIGVfaGkgPSAoZF9oaSArIHQxX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgICBlX2xvID0gbG8gPj4+IDA7CgogICAgICBkX2hpID0gY19oaTsKICAgICAgZF9sbyA9IGNfbG87CgogICAgICBjX2hpID0gYl9oaTsKICAgICAgY19sbyA9IGJfbG87CgogICAgICBiX2hpID0gYV9oaTsKICAgICAgYl9sbyA9IGFfbG87CgogICAgICAvLyBhID0gKHQxICsgdDIpIG1vZHVsbyAyXjY0IChjYXJyeSBsbyBvdmVyZmxvdykKICAgICAgbG8gPSB0MV9sbyArIHQyX2xvOwogICAgICBhX2hpID0gKHQxX2hpICsgdDJfaGkgKyAoKGxvIC8gMHgxMDAwMDAwMDApID4+PiAwKSkgPj4+IDA7CiAgICAgIGFfbG8gPSBsbyA+Pj4gMDsKICAgIH0KCiAgICAvLyB1cGRhdGUgaGFzaCBzdGF0ZSAoYWRkaXRpb25hbCBtb2R1bG8gMl42NCkKICAgIGxvID0gc1swXVsxXSArIGFfbG87CiAgICBzWzBdWzBdID0gKHNbMF1bMF0gKyBhX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1swXVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1sxXVsxXSArIGJfbG87CiAgICBzWzFdWzBdID0gKHNbMV1bMF0gKyBiX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1sxXVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1syXVsxXSArIGNfbG87CiAgICBzWzJdWzBdID0gKHNbMl1bMF0gKyBjX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1syXVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1szXVsxXSArIGRfbG87CiAgICBzWzNdWzBdID0gKHNbM11bMF0gKyBkX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1szXVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1s0XVsxXSArIGVfbG87CiAgICBzWzRdWzBdID0gKHNbNF1bMF0gKyBlX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1s0XVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1s1XVsxXSArIGZfbG87CiAgICBzWzVdWzBdID0gKHNbNV1bMF0gKyBmX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1s1XVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1s2XVsxXSArIGdfbG87CiAgICBzWzZdWzBdID0gKHNbNl1bMF0gKyBnX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1s2XVsxXSA9IGxvID4+PiAwOwoKICAgIGxvID0gc1s3XVsxXSArIGhfbG87CiAgICBzWzddWzBdID0gKHNbN11bMF0gKyBoX2hpICsgKChsbyAvIDB4MTAwMDAwMDAwKSA+Pj4gMCkpID4+PiAwOwogICAgc1s3XVsxXSA9IGxvID4+PiAwOwoKICAgIGxlbiAtPSAxMjg7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdzaGE1MTInOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvc2hhNTEyJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBOb2RlLmpzIG1vZHVsZSBmb3IgRm9yZ2UgbWVzc2FnZSBkaWdlc3RzLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgMjAxMS0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UubWQgPSBmb3JnZS5tZCB8fCB7fTsKZm9yZ2UubWQuYWxnb3JpdGhtcyA9IHsKICBtZDU6IGZvcmdlLm1kNSwKICBzaGExOiBmb3JnZS5zaGExLAogIHNoYTI1NjogZm9yZ2Uuc2hhMjU2Cn07CmZvcmdlLm1kLm1kNSA9IGZvcmdlLm1kNTsKZm9yZ2UubWQuc2hhMSA9IGZvcmdlLnNoYTE7CmZvcmdlLm1kLnNoYTI1NiA9IGZvcmdlLnNoYTI1NjsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ21kJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoCiAgJ2pzL21kJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vbWQ1JywgJy4vc2hhMScsICcuL3NoYTI1NicsICcuL3NoYTUxMiddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBIYXNoLWJhc2VkIE1lc3NhZ2UgQXV0aGVudGljYXRpb24gQ29kZSBpbXBsZW1lbnRhdGlvbi4gUmVxdWlyZXMgYSBtZXNzYWdlCiAqIGRpZ2VzdCBvYmplY3QgdGhhdCBjYW4gYmUgb2J0YWluZWQsIGZvciBleGFtcGxlLCBmcm9tIGZvcmdlLm1kLnNoYTEgb3IKICogZm9yZ2UubWQubWQ1LgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxMiBEaWdpdGFsIEJhemFhciwgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8qIEhNQUMgQVBJICovCnZhciBobWFjID0gZm9yZ2UuaG1hYyA9IGZvcmdlLmhtYWMgfHwge307CgovKioKICogQ3JlYXRlcyBhbiBITUFDIG9iamVjdCB0aGF0IHVzZXMgdGhlIGdpdmVuIG1lc3NhZ2UgZGlnZXN0IG9iamVjdC4KICoKICogQHJldHVybiBhbiBITUFDIG9iamVjdC4KICovCmhtYWMuY3JlYXRlID0gZnVuY3Rpb24oKSB7CiAgLy8gdGhlIGhtYWMga2V5IHRvIHVzZQogIHZhciBfa2V5ID0gbnVsbDsKCiAgLy8gdGhlIG1lc3NhZ2UgZGlnZXN0IHRvIHVzZQogIHZhciBfbWQgPSBudWxsOwoKICAvLyB0aGUgaW5uZXIgcGFkZGluZwogIHZhciBfaXBhZGRpbmcgPSBudWxsOwoKICAvLyB0aGUgb3V0ZXIgcGFkZGluZwogIHZhciBfb3BhZGRpbmcgPSBudWxsOwoKICAvLyBobWFjIGNvbnRleHQKICB2YXIgY3R4ID0ge307CgogIC8qKgogICAqIFN0YXJ0cyBvciByZXN0YXJ0cyB0aGUgSE1BQyB3aXRoIHRoZSBnaXZlbiBrZXkgYW5kIG1lc3NhZ2UgZGlnZXN0LgogICAqCiAgICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCB0byB1c2UsIG51bGwgdG8gcmV1c2UgdGhlIHByZXZpb3VzIG9uZSwKICAgKiAgICAgICAgICAgYSBzdHJpbmcgdG8gdXNlIGJ1aWx0aW4gJ3NoYTEnLCAnbWQ1JywgJ3NoYTI1NicuCiAgICogQHBhcmFtIGtleSB0aGUga2V5IHRvIHVzZSBhcyBhIHN0cmluZywgYXJyYXkgb2YgYnl0ZXMsIGJ5dGUgYnVmZmVyLAogICAqICAgICAgICAgICBvciBudWxsIHRvIHJldXNlIHRoZSBwcmV2aW91cyBrZXkuCiAgICovCiAgY3R4LnN0YXJ0ID0gZnVuY3Rpb24obWQsIGtleSkgewogICAgaWYobWQgIT09IG51bGwpIHsKICAgICAgaWYodHlwZW9mIG1kID09PSAnc3RyaW5nJykgewogICAgICAgIC8vIGNyZWF0ZSBidWlsdGluIG1lc3NhZ2UgZGlnZXN0CiAgICAgICAgbWQgPSBtZC50b0xvd2VyQ2FzZSgpOwogICAgICAgIGlmKG1kIGluIGZvcmdlLm1kLmFsZ29yaXRobXMpIHsKICAgICAgICAgIF9tZCA9IGZvcmdlLm1kLmFsZ29yaXRobXNbbWRdLmNyZWF0ZSgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gaGFzaCBhbGdvcml0aG0gIicgKyBtZCArICciJyk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIC8vIHN0b3JlIG1lc3NhZ2UgZGlnZXN0CiAgICAgICAgX21kID0gbWQ7CiAgICAgIH0KICAgIH0KCiAgICBpZihrZXkgPT09IG51bGwpIHsKICAgICAgLy8gcmV1c2UgcHJldmlvdXMga2V5CiAgICAgIGtleSA9IF9rZXk7CiAgICB9IGVsc2UgewogICAgICBpZih0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykgewogICAgICAgIC8vIGNvbnZlcnQgc3RyaW5nIGludG8gYnl0ZSBidWZmZXIKICAgICAgICBrZXkgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihrZXkpOwogICAgICB9IGVsc2UgaWYoZm9yZ2UudXRpbC5pc0FycmF5KGtleSkpIHsKICAgICAgICAvLyBjb252ZXJ0IGJ5dGUgYXJyYXkgaW50byBieXRlIGJ1ZmZlcgogICAgICAgIHZhciB0bXAgPSBrZXk7CiAgICAgICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgdG1wLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICBrZXkucHV0Qnl0ZSh0bXBbaV0pOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gaWYga2V5IGlzIGxvbmdlciB0aGFuIGJsb2Nrc2l6ZSwgaGFzaCBpdAogICAgICB2YXIga2V5bGVuID0ga2V5Lmxlbmd0aCgpOwogICAgICBpZihrZXlsZW4gPiBfbWQuYmxvY2tMZW5ndGgpIHsKICAgICAgICBfbWQuc3RhcnQoKTsKICAgICAgICBfbWQudXBkYXRlKGtleS5ieXRlcygpKTsKICAgICAgICBrZXkgPSBfbWQuZGlnZXN0KCk7CiAgICAgIH0KCiAgICAgIC8vIG1peCBrZXkgaW50byBpbm5lciBhbmQgb3V0ZXIgcGFkZGluZwogICAgICAvLyBpcGFkZGluZyA9IFsweDM2ICogYmxvY2tzaXplXSBeIGtleQogICAgICAvLyBvcGFkZGluZyA9IFsweDVDICogYmxvY2tzaXplXSBeIGtleQogICAgICBfaXBhZGRpbmcgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgICBfb3BhZGRpbmcgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgICBrZXlsZW4gPSBrZXkubGVuZ3RoKCk7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBrZXlsZW47ICsraSkgewogICAgICAgIHZhciB0bXAgPSBrZXkuYXQoaSk7CiAgICAgICAgX2lwYWRkaW5nLnB1dEJ5dGUoMHgzNiBeIHRtcCk7CiAgICAgICAgX29wYWRkaW5nLnB1dEJ5dGUoMHg1QyBeIHRtcCk7CiAgICAgIH0KCiAgICAgIC8vIGlmIGtleSBpcyBzaG9ydGVyIHRoYW4gYmxvY2tzaXplLCBhZGQgYWRkaXRpb25hbCBwYWRkaW5nCiAgICAgIGlmKGtleWxlbiA8IF9tZC5ibG9ja0xlbmd0aCkgewogICAgICAgIHZhciB0bXAgPSBfbWQuYmxvY2tMZW5ndGggLSBrZXlsZW47CiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHRtcDsgKytpKSB7CiAgICAgICAgICBfaXBhZGRpbmcucHV0Qnl0ZSgweDM2KTsKICAgICAgICAgIF9vcGFkZGluZy5wdXRCeXRlKDB4NUMpOwogICAgICAgIH0KICAgICAgfQogICAgICBfa2V5ID0ga2V5OwogICAgICBfaXBhZGRpbmcgPSBfaXBhZGRpbmcuYnl0ZXMoKTsKICAgICAgX29wYWRkaW5nID0gX29wYWRkaW5nLmJ5dGVzKCk7CiAgICB9CgogICAgLy8gZGlnZXN0IGlzIGRvbmUgbGlrZSBzbzogaGFzaChvcGFkZGluZyB8IGhhc2goaXBhZGRpbmcgfCBtZXNzYWdlKSkKCiAgICAvLyBwcmVwYXJlIHRvIGRvIGlubmVyIGhhc2gKICAgIC8vIGhhc2goaXBhZGRpbmcgfCBtZXNzYWdlKQogICAgX21kLnN0YXJ0KCk7CiAgICBfbWQudXBkYXRlKF9pcGFkZGluZyk7CiAgfTsKCiAgLyoqCiAgICogVXBkYXRlcyB0aGUgSE1BQyB3aXRoIHRoZSBnaXZlbiBtZXNzYWdlIGJ5dGVzLgogICAqCiAgICogQHBhcmFtIGJ5dGVzIHRoZSBieXRlcyB0byB1cGRhdGUgd2l0aC4KICAgKi8KICBjdHgudXBkYXRlID0gZnVuY3Rpb24oYnl0ZXMpIHsKICAgIF9tZC51cGRhdGUoYnl0ZXMpOwogIH07CgogIC8qKgogICAqIFByb2R1Y2VzIHRoZSBNZXNzYWdlIEF1dGhlbnRpY2F0aW9uIENvZGUgKE1BQykuCiAgICoKICAgKiBAcmV0dXJuIGEgYnl0ZSBidWZmZXIgY29udGFpbmluZyB0aGUgZGlnZXN0IHZhbHVlLgogICAqLwogIGN0eC5nZXRNYWMgPSBmdW5jdGlvbigpIHsKICAgIC8vIGRpZ2VzdCBpcyBkb25lIGxpa2Ugc286IGhhc2gob3BhZGRpbmcgfCBoYXNoKGlwYWRkaW5nIHwgbWVzc2FnZSkpCiAgICAvLyBoZXJlIHdlIGRvIHRoZSBvdXRlciBoYXNoaW5nCiAgICB2YXIgaW5uZXIgPSBfbWQuZGlnZXN0KCkuYnl0ZXMoKTsKICAgIF9tZC5zdGFydCgpOwogICAgX21kLnVwZGF0ZShfb3BhZGRpbmcpOwogICAgX21kLnVwZGF0ZShpbm5lcik7CiAgICByZXR1cm4gX21kLmRpZ2VzdCgpOwogIH07CiAgLy8gYWxpYXMgZm9yIGdldE1hYwogIGN0eC5kaWdlc3QgPSBjdHguZ2V0TWFjOwoKICByZXR1cm4gY3R4Owp9OwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAnaG1hYyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9obWFjJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vbWQnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgYmFzaWMgUEVNIChQcml2YWN5IEVuaGFuY2VkIE1haWwpIGFsZ29yaXRobXMuCiAqCiAqIFNlZTogUkZDIDE0MjEuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqCiAqIEEgRm9yZ2UgUEVNIG9iamVjdCBoYXMgdGhlIGZvbGxvd2luZyBmaWVsZHM6CiAqCiAqIHR5cGU6IGlkZW50aWZpZXMgdGhlIHR5cGUgb2YgbWVzc2FnZSAoZWc6ICJSU0EgUFJJVkFURSBLRVkiKS4KICoKICogcHJvY1R5cGU6IGlkZW50aWZpZXMgdGhlIHR5cGUgb2YgcHJvY2Vzc2luZyBwZXJmb3JtZWQgb24gdGhlIG1lc3NhZ2UsCiAqICAgaXQgaGFzIHR3byBzdWJmaWVsZHM6IHZlcnNpb24gYW5kIHR5cGUsIGVnOiA0LEVOQ1JZUFRFRC4KICoKICogY29udGVudERvbWFpbjogaWRlbnRpZmllcyB0aGUgdHlwZSBvZiBjb250ZW50IGluIHRoZSBtZXNzYWdlLCB0eXBpY2FsbHkKICogICBvbmx5IHVzZXMgdGhlIHZhbHVlOiAiUkZDODIyIi4KICoKICogZGVrSW5mbzogaWRlbnRpZmllcyB0aGUgbWVzc2FnZSBlbmNyeXB0aW9uIGFsZ29yaXRobSBhbmQgbW9kZSBhbmQgaW5jbHVkZXMKICogICBhbnkgcGFyYW1ldGVycyBmb3IgdGhlIGFsZ29yaXRobSwgaXQgaGFzIHR3byBzdWJmaWVsZHM6IGFsZ29yaXRobSBhbmQKICogICBwYXJhbWV0ZXJzLCBlZzogREVTLUNCQyxGODE0M0VERTU5NjBDNTk3LgogKgogKiBoZWFkZXJzOiBjb250YWlucyBhbGwgb3RoZXIgUEVNIGVuY2Fwc3VsYXRlZCBoZWFkZXJzIC0tIHdoZXJlIG9yZGVyIGlzCiAqICAgc2lnbmlmaWNhbnQgKGZvciBwYWlyaW5nIGRhdGEgbGlrZSByZWNpcGllbnQgSUQgKyBrZXkgaW5mbykuCiAqCiAqIGJvZHk6IHRoZSBiaW5hcnktZW5jb2RlZCBib2R5LgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIHNob3J0Y3V0IGZvciBwZW0gQVBJCnZhciBwZW0gPSBmb3JnZS5wZW0gPSBmb3JnZS5wZW0gfHwge307CgovKioKICogRW5jb2RlcyAoc2VyaWFsaXplcykgdGhlIGdpdmVuIFBFTSBvYmplY3QuCiAqCiAqIEBwYXJhbSBtc2cgdGhlIFBFTSBtZXNzYWdlIG9iamVjdCB0byBlbmNvZGUuCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgbWF4bGluZSB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lIGZvciB0aGUgYm9keSwgKGRlZmF1bHQ6IDY0KS4KICoKICogQHJldHVybiB0aGUgUEVNLWZvcm1hdHRlZCBzdHJpbmcuCiAqLwpwZW0uZW5jb2RlID0gZnVuY3Rpb24obXNnLCBvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdmFyIHJ2YWwgPSAnLS0tLS1CRUdJTiAnICsgbXNnLnR5cGUgKyAnLS0tLS1cclxuJzsKCiAgLy8gZW5jb2RlIHNwZWNpYWwgaGVhZGVycwogIHZhciBoZWFkZXI7CiAgaWYobXNnLnByb2NUeXBlKSB7CiAgICBoZWFkZXIgPSB7CiAgICAgIG5hbWU6ICdQcm9jLVR5cGUnLAogICAgICB2YWx1ZXM6IFtTdHJpbmcobXNnLnByb2NUeXBlLnZlcnNpb24pLCBtc2cucHJvY1R5cGUudHlwZV0KICAgIH07CiAgICBydmFsICs9IGZvbGRIZWFkZXIoaGVhZGVyKTsKICB9CiAgaWYobXNnLmNvbnRlbnREb21haW4pIHsKICAgIGhlYWRlciA9IHtuYW1lOiAnQ29udGVudC1Eb21haW4nLCB2YWx1ZXM6IFttc2cuY29udGVudERvbWFpbl19OwogICAgcnZhbCArPSBmb2xkSGVhZGVyKGhlYWRlcik7CiAgfQogIGlmKG1zZy5kZWtJbmZvKSB7CiAgICBoZWFkZXIgPSB7bmFtZTogJ0RFSy1JbmZvJywgdmFsdWVzOiBbbXNnLmRla0luZm8uYWxnb3JpdGhtXX07CiAgICBpZihtc2cuZGVrSW5mby5wYXJhbWV0ZXJzKSB7CiAgICAgIGhlYWRlci52YWx1ZXMucHVzaChtc2cuZGVrSW5mby5wYXJhbWV0ZXJzKTsKICAgIH0KICAgIHJ2YWwgKz0gZm9sZEhlYWRlcihoZWFkZXIpOwogIH0KCiAgaWYobXNnLmhlYWRlcnMpIHsKICAgIC8vIGVuY29kZSBhbGwgb3RoZXIgaGVhZGVycwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1zZy5oZWFkZXJzLmxlbmd0aDsgKytpKSB7CiAgICAgIHJ2YWwgKz0gZm9sZEhlYWRlcihtc2cuaGVhZGVyc1tpXSk7CiAgICB9CiAgfQoKICAvLyB0ZXJtaW5hdGUgaGVhZGVyCiAgaWYobXNnLnByb2NUeXBlKSB7CiAgICBydmFsICs9ICdcclxuJzsKICB9CgogIC8vIGFkZCBib2R5CiAgcnZhbCArPSBmb3JnZS51dGlsLmVuY29kZTY0KG1zZy5ib2R5LCBvcHRpb25zLm1heGxpbmUgfHwgNjQpICsgJ1xyXG4nOwoKICBydmFsICs9ICctLS0tLUVORCAnICsgbXNnLnR5cGUgKyAnLS0tLS1cclxuJzsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBEZWNvZGVzIChkZXNlcmlhbGl6ZXMpIGFsbCBQRU0gbWVzc2FnZXMgZm91bmQgaW4gdGhlIGdpdmVuIHN0cmluZy4KICoKICogQHBhcmFtIHN0ciB0aGUgUEVNLWZvcm1hdHRlZCBzdHJpbmcgdG8gZGVjb2RlLgogKgogKiBAcmV0dXJuIHRoZSBQRU0gbWVzc2FnZSBvYmplY3RzIGluIGFuIGFycmF5LgogKi8KcGVtLmRlY29kZSA9IGZ1bmN0aW9uKHN0cikgewogIHZhciBydmFsID0gW107CgogIC8vIHNwbGl0IHN0cmluZyBpbnRvIFBFTSBtZXNzYWdlcyAoYmUgbGVuaWVudCB3L0VPRiBvbiBCRUdJTiBsaW5lKQogIHZhciByTWVzc2FnZSA9IC9ccyotLS0tLUJFR0lOIChbQS1aMC05LSBdKyktLS0tLVxyP1xuPyhbXHgyMS1ceDdlXHNdKz8oPzpccj9cblxyP1xuKSk/KFs6QS1aYS16MC05K1wvPVxzXSs/KS0tLS0tRU5EIFwxLS0tLS0vZzsKICB2YXIgckhlYWRlciA9IC8oW1x4MjEtXHg3ZV0rKTpccyooW1x4MjEtXHg3ZVxzXjpdKykvOwogIHZhciByQ1JMRiA9IC9ccj9cbi87CiAgdmFyIG1hdGNoOwogIHdoaWxlKHRydWUpIHsKICAgIG1hdGNoID0gck1lc3NhZ2UuZXhlYyhzdHIpOwogICAgaWYoIW1hdGNoKSB7CiAgICAgIGJyZWFrOwogICAgfQoKICAgIHZhciBtc2cgPSB7CiAgICAgIHR5cGU6IG1hdGNoWzFdLAogICAgICBwcm9jVHlwZTogbnVsbCwKICAgICAgY29udGVudERvbWFpbjogbnVsbCwKICAgICAgZGVrSW5mbzogbnVsbCwKICAgICAgaGVhZGVyczogW10sCiAgICAgIGJvZHk6IGZvcmdlLnV0aWwuZGVjb2RlNjQobWF0Y2hbM10pCiAgICB9OwogICAgcnZhbC5wdXNoKG1zZyk7CgogICAgLy8gbm8gaGVhZGVycwogICAgaWYoIW1hdGNoWzJdKSB7CiAgICAgIGNvbnRpbnVlOwogICAgfQoKICAgIC8vIHBhcnNlIGhlYWRlcnMKICAgIHZhciBsaW5lcyA9IG1hdGNoWzJdLnNwbGl0KHJDUkxGKTsKICAgIHZhciBsaSA9IDA7CiAgICB3aGlsZShtYXRjaCAmJiBsaSA8IGxpbmVzLmxlbmd0aCkgewogICAgICAvLyBnZXQgbGluZSwgdHJpbSBhbnkgcmhzIHdoaXRlc3BhY2UKICAgICAgdmFyIGxpbmUgPSBsaW5lc1tsaV0ucmVwbGFjZSgvXHMrJC8sICcnKTsKCiAgICAgIC8vIFJGQzI4MjIgdW5mb2xkIGFueSBmb2xsb3dpbmcgZm9sZGVkIGxpbmVzCiAgICAgIGZvcih2YXIgbmwgPSBsaSArIDE7IG5sIDwgbGluZXMubGVuZ3RoOyArK25sKSB7CiAgICAgICAgdmFyIG5leHQgPSBsaW5lc1tubF07CiAgICAgICAgaWYoIS9ccy8udGVzdChuZXh0WzBdKSkgewogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGxpbmUgKz0gbmV4dDsKICAgICAgICBsaSA9IG5sOwogICAgICB9CgogICAgICAvLyBwYXJzZSBoZWFkZXIKICAgICAgbWF0Y2ggPSBsaW5lLm1hdGNoKHJIZWFkZXIpOwogICAgICBpZihtYXRjaCkgewogICAgICAgIHZhciBoZWFkZXIgPSB7bmFtZTogbWF0Y2hbMV0sIHZhbHVlczogW119OwogICAgICAgIHZhciB2YWx1ZXMgPSBtYXRjaFsyXS5zcGxpdCgnLCcpOwogICAgICAgIGZvcih2YXIgdmkgPSAwOyB2aSA8IHZhbHVlcy5sZW5ndGg7ICsrdmkpIHsKICAgICAgICAgIGhlYWRlci52YWx1ZXMucHVzaChsdHJpbSh2YWx1ZXNbdmldKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBQcm9jLVR5cGUgbXVzdCBiZSB0aGUgZmlyc3QgaGVhZGVyCiAgICAgICAgaWYoIW1zZy5wcm9jVHlwZSkgewogICAgICAgICAgaWYoaGVhZGVyLm5hbWUgIT09ICdQcm9jLVR5cGUnKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBQRU0gZm9ybWF0dGVkIG1lc3NhZ2UuIFRoZSBmaXJzdCAnICsKICAgICAgICAgICAgICAnZW5jYXBzdWxhdGVkIGhlYWRlciBtdXN0IGJlICJQcm9jLVR5cGUiLicpOwogICAgICAgICAgfSBlbHNlIGlmKGhlYWRlci52YWx1ZXMubGVuZ3RoICE9PSAyKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBQRU0gZm9ybWF0dGVkIG1lc3NhZ2UuIFRoZSAiUHJvYy1UeXBlIiAnICsKICAgICAgICAgICAgICAnaGVhZGVyIG11c3QgaGF2ZSB0d28gc3ViZmllbGRzLicpOwogICAgICAgICAgfQogICAgICAgICAgbXNnLnByb2NUeXBlID0ge3ZlcnNpb246IHZhbHVlc1swXSwgdHlwZTogdmFsdWVzWzFdfTsKICAgICAgICB9IGVsc2UgaWYoIW1zZy5jb250ZW50RG9tYWluICYmIGhlYWRlci5uYW1lID09PSAnQ29udGVudC1Eb21haW4nKSB7CiAgICAgICAgICAvLyBzcGVjaWFsLWNhc2UgQ29udGVudC1Eb21haW4KICAgICAgICAgIG1zZy5jb250ZW50RG9tYWluID0gdmFsdWVzWzBdIHx8ICcnOwogICAgICAgIH0gZWxzZSBpZighbXNnLmRla0luZm8gJiYgaGVhZGVyLm5hbWUgPT09ICdERUstSW5mbycpIHsKICAgICAgICAgIC8vIHNwZWNpYWwtY2FzZSBERUstSW5mbwogICAgICAgICAgaWYoaGVhZGVyLnZhbHVlcy5sZW5ndGggPT09IDApIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFBFTSBmb3JtYXR0ZWQgbWVzc2FnZS4gVGhlICJERUstSW5mbyIgJyArCiAgICAgICAgICAgICAgJ2hlYWRlciBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIHN1YmZpZWxkLicpOwogICAgICAgICAgfQogICAgICAgICAgbXNnLmRla0luZm8gPSB7YWxnb3JpdGhtOiB2YWx1ZXNbMF0sIHBhcmFtZXRlcnM6IHZhbHVlc1sxXSB8fCBudWxsfTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbXNnLmhlYWRlcnMucHVzaChoZWFkZXIpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgKytsaTsKICAgIH0KCiAgICBpZihtc2cucHJvY1R5cGUgPT09ICdFTkNSWVBURUQnICYmICFtc2cuZGVrSW5mbykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUEVNIGZvcm1hdHRlZCBtZXNzYWdlLiBUaGUgIkRFSy1JbmZvIiAnICsKICAgICAgICAnaGVhZGVyIG11c3QgYmUgcHJlc2VudCBpZiAiUHJvYy1UeXBlIiBpcyAiRU5DUllQVEVEIi4nKTsKICAgIH0KICB9CgogIGlmKHJ2YWwubGVuZ3RoID09PSAwKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUEVNIGZvcm1hdHRlZCBtZXNzYWdlLicpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgpmdW5jdGlvbiBmb2xkSGVhZGVyKGhlYWRlcikgewogIHZhciBydmFsID0gaGVhZGVyLm5hbWUgKyAnOiAnOwoKICAvLyBlbnN1cmUgdmFsdWVzIHdpdGggQ1JMRiBhcmUgZm9sZGVkCiAgdmFyIHZhbHVlcyA9IFtdOwogIHZhciBpbnNlcnRTcGFjZSA9IGZ1bmN0aW9uKG1hdGNoLCAkMSkgewogICAgcmV0dXJuICcgJyArICQxOwogIH07CiAgZm9yKHZhciBpID0gMDsgaSA8IGhlYWRlci52YWx1ZXMubGVuZ3RoOyArK2kpIHsKICAgIHZhbHVlcy5wdXNoKGhlYWRlci52YWx1ZXNbaV0ucmVwbGFjZSgvXihcUytcclxuKS8sIGluc2VydFNwYWNlKSk7CiAgfQogIHJ2YWwgKz0gdmFsdWVzLmpvaW4oJywnKSArICdcclxuJzsKCiAgLy8gZG8gZm9sZGluZwogIHZhciBsZW5ndGggPSAwOwogIHZhciBjYW5kaWRhdGUgPSAtMTsKICBmb3IodmFyIGkgPSAwOyBpIDwgcnZhbC5sZW5ndGg7ICsraSwgKytsZW5ndGgpIHsKICAgIGlmKGxlbmd0aCA+IDY1ICYmIGNhbmRpZGF0ZSAhPT0gLTEpIHsKICAgICAgdmFyIGluc2VydCA9IHJ2YWxbY2FuZGlkYXRlXTsKICAgICAgaWYoaW5zZXJ0ID09PSAnLCcpIHsKICAgICAgICArK2NhbmRpZGF0ZTsKICAgICAgICBydmFsID0gcnZhbC5zdWJzdHIoMCwgY2FuZGlkYXRlKSArICdcclxuICcgKyBydmFsLnN1YnN0cihjYW5kaWRhdGUpOwogICAgICB9IGVsc2UgewogICAgICAgIHJ2YWwgPSBydmFsLnN1YnN0cigwLCBjYW5kaWRhdGUpICsKICAgICAgICAgICdcclxuJyArIGluc2VydCArIHJ2YWwuc3Vic3RyKGNhbmRpZGF0ZSArIDEpOwogICAgICB9CiAgICAgIGxlbmd0aCA9IChpIC0gY2FuZGlkYXRlIC0gMSk7CiAgICAgIGNhbmRpZGF0ZSA9IC0xOwogICAgICArK2k7CiAgICB9IGVsc2UgaWYocnZhbFtpXSA9PT0gJyAnIHx8IHJ2YWxbaV0gPT09ICdcdCcgfHwgcnZhbFtpXSA9PT0gJywnKSB7CiAgICAgIGNhbmRpZGF0ZSA9IGk7CiAgICB9CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKZnVuY3Rpb24gbHRyaW0oc3RyKSB7CiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXHMrLywgJycpOwp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdwZW0nOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvcGVtJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBERVMgKERhdGEgRW5jcnlwdGlvbiBTdGFuZGFyZCkgaW1wbGVtZW50YXRpb24uCiAqCiAqIFRoaXMgaW1wbGVtZW50YXRpb24gc3VwcG9ydHMgREVTIGFzIHdlbGwgYXMgM0RFUy1FREUgaW4gRUNCIGFuZCBDQkMgbW9kZS4KICogSXQgaXMgYmFzZWQgb24gdGhlIEJTRC1saWNlbnNlZCBpbXBsZW1lbnRhdGlvbiBieSBQYXVsIFRlcm86CiAqCiAqIFBhdWwgVGVybywgSnVseSAyMDAxCiAqIGh0dHA6Ly93d3cudGVyby5jby51ay9kZXMvCiAqCiAqIE9wdGltaXNlZCBmb3IgcGVyZm9ybWFuY2Ugd2l0aCBsYXJnZSBibG9ja3MgYnkgTWljaGFlbCBIYXl3b3J0aCwgTm92ZW1iZXIgMjAwMQogKiBodHRwOi8vd3d3Lm5ldGRlYWxpbmcuY29tCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiBBTkQKICogQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFCiAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCiAqIEFSRSBESVNDTEFJTUVELiAgSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFCiAqIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMCiAqIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTCiAqIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKQogKiBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVAogKiBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZCiAqIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YKICogU1VDSCBEQU1BR0UuCiAqCiAqIEBhdXRob3IgU3RlZmFuIFNpZWdsCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMiBTdGVmYW4gU2llZ2wgPHN0ZXNpZUBicm9rZW5waXBlLmRlPgogKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8qIERFUyBBUEkgKi8KZm9yZ2UuZGVzID0gZm9yZ2UuZGVzIHx8IHt9OwoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogdmFyIGNpcGhlciA9IGZvcmdlLmNpcGhlci5jcmVhdGVDaXBoZXIoJ0RFUy08bW9kZT4nLCBrZXkpOwogKiBjaXBoZXIuc3RhcnQoe2l2OiBpdn0pOwogKgogKiBDcmVhdGVzIGFuIERFUyBjaXBoZXIgb2JqZWN0IHRvIGVuY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gc3ltbWV0cmljIGtleS4KICogVGhlIG91dHB1dCB3aWxsIGJlIHN0b3JlZCBpbiB0aGUgJ291dHB1dCcgbWVtYmVyIG9mIHRoZSByZXR1cm5lZCBjaXBoZXIuCiAqCiAqIFRoZSBrZXkgYW5kIGl2IG1heSBiZSBnaXZlbiBhcyBiaW5hcnktZW5jb2RlZCBzdHJpbmdzIG9mIGJ5dGVzIG9yCiAqIGJ5dGUgYnVmZmVycy4KICoKICogQHBhcmFtIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UgKDY0IG9yIDE5MiBiaXRzKS4KICogQHBhcmFtIGl2IHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IgdG8gdXNlLgogKiBAcGFyYW0gb3V0cHV0IHRoZSBidWZmZXIgdG8gd3JpdGUgdG8sIG51bGwgdG8gY3JlYXRlIG9uZS4KICogQHBhcmFtIG1vZGUgdGhlIGNpcGhlciBtb2RlIHRvIHVzZSAoZGVmYXVsdDogJ0NCQycgaWYgSVYgaXMKICogICAgICAgICAgZ2l2ZW4sICdFQ0InIGlmIG51bGwpLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwpmb3JnZS5kZXMuc3RhcnRFbmNyeXB0aW5nID0gZnVuY3Rpb24oa2V5LCBpdiwgb3V0cHV0LCBtb2RlKSB7CiAgdmFyIGNpcGhlciA9IF9jcmVhdGVDaXBoZXIoewogICAga2V5OiBrZXksCiAgICBvdXRwdXQ6IG91dHB1dCwKICAgIGRlY3J5cHQ6IGZhbHNlLAogICAgbW9kZTogbW9kZSB8fCAoaXYgPT09IG51bGwgPyAnRUNCJyA6ICdDQkMnKQogIH0pOwogIGNpcGhlci5zdGFydChpdik7CiAgcmV0dXJuIGNpcGhlcjsKfTsKCi8qKgogKiBEZXByZWNhdGVkLiBJbnN0ZWFkLCB1c2U6CiAqCiAqIHZhciBjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKCdERVMtPG1vZGU+Jywga2V5KTsKICoKICogQ3JlYXRlcyBhbiBERVMgY2lwaGVyIG9iamVjdCB0byBlbmNyeXB0IGRhdGEgdXNpbmcgdGhlIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqCiAqIFRoZSBrZXkgbWF5IGJlIGdpdmVuIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzIG9yIGEgYnl0ZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlICg2NCBvciAxOTIgYml0cykuCiAqIEBwYXJhbSBtb2RlIHRoZSBjaXBoZXIgbW9kZSB0byB1c2UgKGRlZmF1bHQ6ICdDQkMnKS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZm9yZ2UuZGVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXIgPSBmdW5jdGlvbihrZXksIG1vZGUpIHsKICByZXR1cm4gX2NyZWF0ZUNpcGhlcih7CiAgICBrZXk6IGtleSwKICAgIG91dHB1dDogbnVsbCwKICAgIGRlY3J5cHQ6IGZhbHNlLAogICAgbW9kZTogbW9kZQogIH0pOwp9OwoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogdmFyIGRlY2lwaGVyID0gZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKCdERVMtPG1vZGU+Jywga2V5KTsKICogZGVjaXBoZXIuc3RhcnQoe2l2OiBpdn0pOwogKgogKiBDcmVhdGVzIGFuIERFUyBjaXBoZXIgb2JqZWN0IHRvIGRlY3J5cHQgZGF0YSB1c2luZyB0aGUgZ2l2ZW4gc3ltbWV0cmljIGtleS4KICogVGhlIG91dHB1dCB3aWxsIGJlIHN0b3JlZCBpbiB0aGUgJ291dHB1dCcgbWVtYmVyIG9mIHRoZSByZXR1cm5lZCBjaXBoZXIuCiAqCiAqIFRoZSBrZXkgYW5kIGl2IG1heSBiZSBnaXZlbiBhcyBiaW5hcnktZW5jb2RlZCBzdHJpbmdzIG9mIGJ5dGVzIG9yCiAqIGJ5dGUgYnVmZmVycy4KICoKICogQHBhcmFtIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UgKDY0IG9yIDE5MiBiaXRzKS4KICogQHBhcmFtIGl2IHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IgdG8gdXNlLgogKiBAcGFyYW0gb3V0cHV0IHRoZSBidWZmZXIgdG8gd3JpdGUgdG8sIG51bGwgdG8gY3JlYXRlIG9uZS4KICogQHBhcmFtIG1vZGUgdGhlIGNpcGhlciBtb2RlIHRvIHVzZSAoZGVmYXVsdDogJ0NCQycgaWYgSVYgaXMKICogICAgICAgICAgZ2l2ZW4sICdFQ0InIGlmIG51bGwpLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwpmb3JnZS5kZXMuc3RhcnREZWNyeXB0aW5nID0gZnVuY3Rpb24oa2V5LCBpdiwgb3V0cHV0LCBtb2RlKSB7CiAgdmFyIGNpcGhlciA9IF9jcmVhdGVDaXBoZXIoewogICAga2V5OiBrZXksCiAgICBvdXRwdXQ6IG91dHB1dCwKICAgIGRlY3J5cHQ6IHRydWUsCiAgICBtb2RlOiBtb2RlIHx8IChpdiA9PT0gbnVsbCA/ICdFQ0InIDogJ0NCQycpCiAgfSk7CiAgY2lwaGVyLnN0YXJ0KGl2KTsKICByZXR1cm4gY2lwaGVyOwp9OwoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogdmFyIGRlY2lwaGVyID0gZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKCdERVMtPG1vZGU+Jywga2V5KTsKICoKICogQ3JlYXRlcyBhbiBERVMgY2lwaGVyIG9iamVjdCB0byBkZWNyeXB0IGRhdGEgdXNpbmcgdGhlIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqCiAqIFRoZSBrZXkgbWF5IGJlIGdpdmVuIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzIG9yIGEgYnl0ZSBidWZmZXIuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlICg2NCBvciAxOTIgYml0cykuCiAqIEBwYXJhbSBtb2RlIHRoZSBjaXBoZXIgbW9kZSB0byB1c2UgKGRlZmF1bHQ6ICdDQkMnKS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZm9yZ2UuZGVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXIgPSBmdW5jdGlvbihrZXksIG1vZGUpIHsKICByZXR1cm4gX2NyZWF0ZUNpcGhlcih7CiAgICBrZXk6IGtleSwKICAgIG91dHB1dDogbnVsbCwKICAgIGRlY3J5cHQ6IHRydWUsCiAgICBtb2RlOiBtb2RlCiAgfSk7Cn07CgovKioKICogQ3JlYXRlcyBhIG5ldyBERVMgY2lwaGVyIGFsZ29yaXRobSBvYmplY3QuCiAqCiAqIEBwYXJhbSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBhbGdvcml0aG0uCiAqIEBwYXJhbSBtb2RlIHRoZSBtb2RlIGZhY3RvcnkgZnVuY3Rpb24uCiAqCiAqIEByZXR1cm4gdGhlIERFUyBhbGdvcml0aG0gb2JqZWN0LgogKi8KZm9yZ2UuZGVzLkFsZ29yaXRobSA9IGZ1bmN0aW9uKG5hbWUsIG1vZGUpIHsKICB2YXIgc2VsZiA9IHRoaXM7CiAgc2VsZi5uYW1lID0gbmFtZTsKICBzZWxmLm1vZGUgPSBuZXcgbW9kZSh7CiAgICBibG9ja1NpemU6IDgsCiAgICBjaXBoZXI6IHsKICAgICAgZW5jcnlwdDogZnVuY3Rpb24oaW5CbG9jaywgb3V0QmxvY2spIHsKICAgICAgICByZXR1cm4gX3VwZGF0ZUJsb2NrKHNlbGYuX2tleXMsIGluQmxvY2ssIG91dEJsb2NrLCBmYWxzZSk7CiAgICAgIH0sCiAgICAgIGRlY3J5cHQ6IGZ1bmN0aW9uKGluQmxvY2ssIG91dEJsb2NrKSB7CiAgICAgICAgcmV0dXJuIF91cGRhdGVCbG9jayhzZWxmLl9rZXlzLCBpbkJsb2NrLCBvdXRCbG9jaywgdHJ1ZSk7CiAgICAgIH0KICAgIH0KICB9KTsKICBzZWxmLl9pbml0ID0gZmFsc2U7Cn07CgovKioKICogSW5pdGlhbGl6ZXMgdGhpcyBERVMgYWxnb3JpdGhtIGJ5IGV4cGFuZGluZyBpdHMga2V5LgogKgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIGtleSB0aGUga2V5IHRvIHVzZSB3aXRoIHRoaXMgYWxnb3JpdGhtLgogKiAgICAgICAgICBkZWNyeXB0IHRydWUgaWYgdGhlIGFsZ29yaXRobSBzaG91bGQgYmUgaW5pdGlhbGl6ZWQgZm9yIGRlY3J5cHRpb24sCiAqICAgICAgICAgICAgZmFsc2UgZm9yIGVuY3J5cHRpb24uCiAqLwpmb3JnZS5kZXMuQWxnb3JpdGhtLnByb3RvdHlwZS5pbml0aWFsaXplID0gZnVuY3Rpb24ob3B0aW9ucykgewogIGlmKHRoaXMuX2luaXQpIHsKICAgIHJldHVybjsKICB9CgogIHZhciBrZXkgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihvcHRpb25zLmtleSk7CiAgaWYodGhpcy5uYW1lLmluZGV4T2YoJzNERVMnKSA9PT0gMCkgewogICAgaWYoa2V5Lmxlbmd0aCgpICE9PSAyNCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgVHJpcGxlLURFUyBrZXkgc2l6ZTogJyArIGtleS5sZW5ndGgoKSAqIDgpOwogICAgfQogIH0KCiAgLy8gZG8ga2V5IGV4cGFuc2lvbiB0byAxNiBvciA0OCBzdWJrZXlzIChzaW5nbGUgb3IgdHJpcGxlIERFUykKICB0aGlzLl9rZXlzID0gX2NyZWF0ZUtleXMoa2V5KTsKICB0aGlzLl9pbml0ID0gdHJ1ZTsKfTsKCgovKiogUmVnaXN0ZXIgREVTIGFsZ29yaXRobXMgKiovCgpyZWdpc3RlckFsZ29yaXRobSgnREVTLUVDQicsIGZvcmdlLmNpcGhlci5tb2Rlcy5lY2IpOwpyZWdpc3RlckFsZ29yaXRobSgnREVTLUNCQycsIGZvcmdlLmNpcGhlci5tb2Rlcy5jYmMpOwpyZWdpc3RlckFsZ29yaXRobSgnREVTLUNGQicsIGZvcmdlLmNpcGhlci5tb2Rlcy5jZmIpOwpyZWdpc3RlckFsZ29yaXRobSgnREVTLU9GQicsIGZvcmdlLmNpcGhlci5tb2Rlcy5vZmIpOwpyZWdpc3RlckFsZ29yaXRobSgnREVTLUNUUicsIGZvcmdlLmNpcGhlci5tb2Rlcy5jdHIpOwoKcmVnaXN0ZXJBbGdvcml0aG0oJzNERVMtRUNCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLmVjYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCczREVTLUNCQycsIGZvcmdlLmNpcGhlci5tb2Rlcy5jYmMpOwpyZWdpc3RlckFsZ29yaXRobSgnM0RFUy1DRkInLCBmb3JnZS5jaXBoZXIubW9kZXMuY2ZiKTsKcmVnaXN0ZXJBbGdvcml0aG0oJzNERVMtT0ZCJywgZm9yZ2UuY2lwaGVyLm1vZGVzLm9mYik7CnJlZ2lzdGVyQWxnb3JpdGhtKCczREVTLUNUUicsIGZvcmdlLmNpcGhlci5tb2Rlcy5jdHIpOwoKZnVuY3Rpb24gcmVnaXN0ZXJBbGdvcml0aG0obmFtZSwgbW9kZSkgewogIHZhciBmYWN0b3J5ID0gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gbmV3IGZvcmdlLmRlcy5BbGdvcml0aG0obmFtZSwgbW9kZSk7CiAgfTsKICBmb3JnZS5jaXBoZXIucmVnaXN0ZXJBbGdvcml0aG0obmFtZSwgZmFjdG9yeSk7Cn0KCgovKiogREVTIGltcGxlbWVudGF0aW9uICoqLwoKdmFyIHNwZnVuY3Rpb24xID0gWzB4MTAxMDQwMCwwLDB4MTAwMDAsMHgxMDEwNDA0LDB4MTAxMDAwNCwweDEwNDA0LDB4NCwweDEwMDAwLDB4NDAwLDB4MTAxMDQwMCwweDEwMTA0MDQsMHg0MDAsMHgxMDAwNDA0LDB4MTAxMDAwNCwweDEwMDAwMDAsMHg0LDB4NDA0LDB4MTAwMDQwMCwweDEwMDA0MDAsMHgxMDQwMCwweDEwNDAwLDB4MTAxMDAwMCwweDEwMTAwMDAsMHgxMDAwNDA0LDB4MTAwMDQsMHgxMDAwMDA0LDB4MTAwMDAwNCwweDEwMDA0LDAsMHg0MDQsMHgxMDQwNCwweDEwMDAwMDAsMHgxMDAwMCwweDEwMTA0MDQsMHg0LDB4MTAxMDAwMCwweDEwMTA0MDAsMHgxMDAwMDAwLDB4MTAwMDAwMCwweDQwMCwweDEwMTAwMDQsMHgxMDAwMCwweDEwNDAwLDB4MTAwMDAwNCwweDQwMCwweDQsMHgxMDAwNDA0LDB4MTA0MDQsMHgxMDEwNDA0LDB4MTAwMDQsMHgxMDEwMDAwLDB4MTAwMDQwNCwweDEwMDAwMDQsMHg0MDQsMHgxMDQwNCwweDEwMTA0MDAsMHg0MDQsMHgxMDAwNDAwLDB4MTAwMDQwMCwwLDB4MTAwMDQsMHgxMDQwMCwwLDB4MTAxMDAwNF07CnZhciBzcGZ1bmN0aW9uMiA9IFstMHg3ZmVmN2ZlMCwtMHg3ZmZmODAwMCwweDgwMDAsMHgxMDgwMjAsMHgxMDAwMDAsMHgyMCwtMHg3ZmVmZmZlMCwtMHg3ZmZmN2ZlMCwtMHg3ZmZmZmZlMCwtMHg3ZmVmN2ZlMCwtMHg3ZmVmODAwMCwtMHg4MDAwMDAwMCwtMHg3ZmZmODAwMCwweDEwMDAwMCwweDIwLC0weDdmZWZmZmUwLDB4MTA4MDAwLDB4MTAwMDIwLC0weDdmZmY3ZmUwLDAsLTB4ODAwMDAwMDAsMHg4MDAwLDB4MTA4MDIwLC0weDdmZjAwMDAwLDB4MTAwMDIwLC0weDdmZmZmZmUwLDAsMHgxMDgwMDAsMHg4MDIwLC0weDdmZWY4MDAwLC0weDdmZjAwMDAwLDB4ODAyMCwwLDB4MTA4MDIwLC0weDdmZWZmZmUwLDB4MTAwMDAwLC0weDdmZmY3ZmUwLC0weDdmZjAwMDAwLC0weDdmZWY4MDAwLDB4ODAwMCwtMHg3ZmYwMDAwMCwtMHg3ZmZmODAwMCwweDIwLC0weDdmZWY3ZmUwLDB4MTA4MDIwLDB4MjAsMHg4MDAwLC0weDgwMDAwMDAwLDB4ODAyMCwtMHg3ZmVmODAwMCwweDEwMDAwMCwtMHg3ZmZmZmZlMCwweDEwMDAyMCwtMHg3ZmZmN2ZlMCwtMHg3ZmZmZmZlMCwweDEwMDAyMCwweDEwODAwMCwwLC0weDdmZmY4MDAwLDB4ODAyMCwtMHg4MDAwMDAwMCwtMHg3ZmVmZmZlMCwtMHg3ZmVmN2ZlMCwweDEwODAwMF07CnZhciBzcGZ1bmN0aW9uMyA9IFsweDIwOCwweDgwMjAyMDAsMCwweDgwMjAwMDgsMHg4MDAwMjAwLDAsMHgyMDIwOCwweDgwMDAyMDAsMHgyMDAwOCwweDgwMDAwMDgsMHg4MDAwMDA4LDB4MjAwMDAsMHg4MDIwMjA4LDB4MjAwMDgsMHg4MDIwMDAwLDB4MjA4LDB4ODAwMDAwMCwweDgsMHg4MDIwMjAwLDB4MjAwLDB4MjAyMDAsMHg4MDIwMDAwLDB4ODAyMDAwOCwweDIwMjA4LDB4ODAwMDIwOCwweDIwMjAwLDB4MjAwMDAsMHg4MDAwMjA4LDB4OCwweDgwMjAyMDgsMHgyMDAsMHg4MDAwMDAwLDB4ODAyMDIwMCwweDgwMDAwMDAsMHgyMDAwOCwweDIwOCwweDIwMDAwLDB4ODAyMDIwMCwweDgwMDAyMDAsMCwweDIwMCwweDIwMDA4LDB4ODAyMDIwOCwweDgwMDAyMDAsMHg4MDAwMDA4LDB4MjAwLDAsMHg4MDIwMDA4LDB4ODAwMDIwOCwweDIwMDAwLDB4ODAwMDAwMCwweDgwMjAyMDgsMHg4LDB4MjAyMDgsMHgyMDIwMCwweDgwMDAwMDgsMHg4MDIwMDAwLDB4ODAwMDIwOCwweDIwOCwweDgwMjAwMDAsMHgyMDIwOCwweDgsMHg4MDIwMDA4LDB4MjAyMDBdOwp2YXIgc3BmdW5jdGlvbjQgPSBbMHg4MDIwMDEsMHgyMDgxLDB4MjA4MSwweDgwLDB4ODAyMDgwLDB4ODAwMDgxLDB4ODAwMDAxLDB4MjAwMSwwLDB4ODAyMDAwLDB4ODAyMDAwLDB4ODAyMDgxLDB4ODEsMCwweDgwMDA4MCwweDgwMDAwMSwweDEsMHgyMDAwLDB4ODAwMDAwLDB4ODAyMDAxLDB4ODAsMHg4MDAwMDAsMHgyMDAxLDB4MjA4MCwweDgwMDA4MSwweDEsMHgyMDgwLDB4ODAwMDgwLDB4MjAwMCwweDgwMjA4MCwweDgwMjA4MSwweDgxLDB4ODAwMDgwLDB4ODAwMDAxLDB4ODAyMDAwLDB4ODAyMDgxLDB4ODEsMCwwLDB4ODAyMDAwLDB4MjA4MCwweDgwMDA4MCwweDgwMDA4MSwweDEsMHg4MDIwMDEsMHgyMDgxLDB4MjA4MSwweDgwLDB4ODAyMDgxLDB4ODEsMHgxLDB4MjAwMCwweDgwMDAwMSwweDIwMDEsMHg4MDIwODAsMHg4MDAwODEsMHgyMDAxLDB4MjA4MCwweDgwMDAwMCwweDgwMjAwMSwweDgwLDB4ODAwMDAwLDB4MjAwMCwweDgwMjA4MF07CnZhciBzcGZ1bmN0aW9uNSA9IFsweDEwMCwweDIwODAxMDAsMHgyMDgwMDAwLDB4NDIwMDAxMDAsMHg4MDAwMCwweDEwMCwweDQwMDAwMDAwLDB4MjA4MDAwMCwweDQwMDgwMTAwLDB4ODAwMDAsMHgyMDAwMTAwLDB4NDAwODAxMDAsMHg0MjAwMDEwMCwweDQyMDgwMDAwLDB4ODAxMDAsMHg0MDAwMDAwMCwweDIwMDAwMDAsMHg0MDA4MDAwMCwweDQwMDgwMDAwLDAsMHg0MDAwMDEwMCwweDQyMDgwMTAwLDB4NDIwODAxMDAsMHgyMDAwMTAwLDB4NDIwODAwMDAsMHg0MDAwMDEwMCwwLDB4NDIwMDAwMDAsMHgyMDgwMTAwLDB4MjAwMDAwMCwweDQyMDAwMDAwLDB4ODAxMDAsMHg4MDAwMCwweDQyMDAwMTAwLDB4MTAwLDB4MjAwMDAwMCwweDQwMDAwMDAwLDB4MjA4MDAwMCwweDQyMDAwMTAwLDB4NDAwODAxMDAsMHgyMDAwMTAwLDB4NDAwMDAwMDAsMHg0MjA4MDAwMCwweDIwODAxMDAsMHg0MDA4MDEwMCwweDEwMCwweDIwMDAwMDAsMHg0MjA4MDAwMCwweDQyMDgwMTAwLDB4ODAxMDAsMHg0MjAwMDAwMCwweDQyMDgwMTAwLDB4MjA4MDAwMCwwLDB4NDAwODAwMDAsMHg0MjAwMDAwMCwweDgwMTAwLDB4MjAwMDEwMCwweDQwMDAwMTAwLDB4ODAwMDAsMCwweDQwMDgwMDAwLDB4MjA4MDEwMCwweDQwMDAwMTAwXTsKdmFyIHNwZnVuY3Rpb242ID0gWzB4MjAwMDAwMTAsMHgyMDQwMDAwMCwweDQwMDAsMHgyMDQwNDAxMCwweDIwNDAwMDAwLDB4MTAsMHgyMDQwNDAxMCwweDQwMDAwMCwweDIwMDA0MDAwLDB4NDA0MDEwLDB4NDAwMDAwLDB4MjAwMDAwMTAsMHg0MDAwMTAsMHgyMDAwNDAwMCwweDIwMDAwMDAwLDB4NDAxMCwwLDB4NDAwMDEwLDB4MjAwMDQwMTAsMHg0MDAwLDB4NDA0MDAwLDB4MjAwMDQwMTAsMHgxMCwweDIwNDAwMDEwLDB4MjA0MDAwMTAsMCwweDQwNDAxMCwweDIwNDA0MDAwLDB4NDAxMCwweDQwNDAwMCwweDIwNDA0MDAwLDB4MjAwMDAwMDAsMHgyMDAwNDAwMCwweDEwLDB4MjA0MDAwMTAsMHg0MDQwMDAsMHgyMDQwNDAxMCwweDQwMDAwMCwweDQwMTAsMHgyMDAwMDAxMCwweDQwMDAwMCwweDIwMDA0MDAwLDB4MjAwMDAwMDAsMHg0MDEwLDB4MjAwMDAwMTAsMHgyMDQwNDAxMCwweDQwNDAwMCwweDIwNDAwMDAwLDB4NDA0MDEwLDB4MjA0MDQwMDAsMCwweDIwNDAwMDEwLDB4MTAsMHg0MDAwLDB4MjA0MDAwMDAsMHg0MDQwMTAsMHg0MDAwLDB4NDAwMDEwLDB4MjAwMDQwMTAsMCwweDIwNDA0MDAwLDB4MjAwMDAwMDAsMHg0MDAwMTAsMHgyMDAwNDAxMF07CnZhciBzcGZ1bmN0aW9uNyA9IFsweDIwMDAwMCwweDQyMDAwMDIsMHg0MDAwODAyLDAsMHg4MDAsMHg0MDAwODAyLDB4MjAwODAyLDB4NDIwMDgwMCwweDQyMDA4MDIsMHgyMDAwMDAsMCwweDQwMDAwMDIsMHgyLDB4NDAwMDAwMCwweDQyMDAwMDIsMHg4MDIsMHg0MDAwODAwLDB4MjAwODAyLDB4MjAwMDAyLDB4NDAwMDgwMCwweDQwMDAwMDIsMHg0MjAwMDAwLDB4NDIwMDgwMCwweDIwMDAwMiwweDQyMDAwMDAsMHg4MDAsMHg4MDIsMHg0MjAwODAyLDB4MjAwODAwLDB4MiwweDQwMDAwMDAsMHgyMDA4MDAsMHg0MDAwMDAwLDB4MjAwODAwLDB4MjAwMDAwLDB4NDAwMDgwMiwweDQwMDA4MDIsMHg0MjAwMDAyLDB4NDIwMDAwMiwweDIsMHgyMDAwMDIsMHg0MDAwMDAwLDB4NDAwMDgwMCwweDIwMDAwMCwweDQyMDA4MDAsMHg4MDIsMHgyMDA4MDIsMHg0MjAwODAwLDB4ODAyLDB4NDAwMDAwMiwweDQyMDA4MDIsMHg0MjAwMDAwLDB4MjAwODAwLDAsMHgyLDB4NDIwMDgwMiwwLDB4MjAwODAyLDB4NDIwMDAwMCwweDgwMCwweDQwMDAwMDIsMHg0MDAwODAwLDB4ODAwLDB4MjAwMDAyXTsKdmFyIHNwZnVuY3Rpb244ID0gWzB4MTAwMDEwNDAsMHgxMDAwLDB4NDAwMDAsMHgxMDA0MTA0MCwweDEwMDAwMDAwLDB4MTAwMDEwNDAsMHg0MCwweDEwMDAwMDAwLDB4NDAwNDAsMHgxMDA0MDAwMCwweDEwMDQxMDQwLDB4NDEwMDAsMHgxMDA0MTAwMCwweDQxMDQwLDB4MTAwMCwweDQwLDB4MTAwNDAwMDAsMHgxMDAwMDA0MCwweDEwMDAxMDAwLDB4MTA0MCwweDQxMDAwLDB4NDAwNDAsMHgxMDA0MDA0MCwweDEwMDQxMDAwLDB4MTA0MCwwLDAsMHgxMDA0MDA0MCwweDEwMDAwMDQwLDB4MTAwMDEwMDAsMHg0MTA0MCwweDQwMDAwLDB4NDEwNDAsMHg0MDAwMCwweDEwMDQxMDAwLDB4MTAwMCwweDQwLDB4MTAwNDAwNDAsMHgxMDAwLDB4NDEwNDAsMHgxMDAwMTAwMCwweDQwLDB4MTAwMDAwNDAsMHgxMDA0MDAwMCwweDEwMDQwMDQwLDB4MTAwMDAwMDAsMHg0MDAwMCwweDEwMDAxMDQwLDAsMHgxMDA0MTA0MCwweDQwMDQwLDB4MTAwMDAwNDAsMHgxMDA0MDAwMCwweDEwMDAxMDAwLDB4MTAwMDEwNDAsMCwweDEwMDQxMDQwLDB4NDEwMDAsMHg0MTAwMCwweDEwNDAsMHgxMDQwLDB4NDAwNDAsMHgxMDAwMDAwMCwweDEwMDQxMDAwXTsKCi8qKgogKiBDcmVhdGUgbmVjZXNzYXJ5IHN1YiBrZXlzLgogKgogKiBAcGFyYW0ga2V5IHRoZSA2NC1iaXQgb3IgMTkyLWJpdCBrZXkuCiAqCiAqIEByZXR1cm4gdGhlIGV4cGFuZGVkIGtleXMuCiAqLwpmdW5jdGlvbiBfY3JlYXRlS2V5cyhrZXkpIHsKICB2YXIgcGMyYnl0ZXMwICA9IFswLDB4NCwweDIwMDAwMDAwLDB4MjAwMDAwMDQsMHgxMDAwMCwweDEwMDA0LDB4MjAwMTAwMDAsMHgyMDAxMDAwNCwweDIwMCwweDIwNCwweDIwMDAwMjAwLDB4MjAwMDAyMDQsMHgxMDIwMCwweDEwMjA0LDB4MjAwMTAyMDAsMHgyMDAxMDIwNF0sCiAgICAgIHBjMmJ5dGVzMSAgPSBbMCwweDEsMHgxMDAwMDAsMHgxMDAwMDEsMHg0MDAwMDAwLDB4NDAwMDAwMSwweDQxMDAwMDAsMHg0MTAwMDAxLDB4MTAwLDB4MTAxLDB4MTAwMTAwLDB4MTAwMTAxLDB4NDAwMDEwMCwweDQwMDAxMDEsMHg0MTAwMTAwLDB4NDEwMDEwMV0sCiAgICAgIHBjMmJ5dGVzMiAgPSBbMCwweDgsMHg4MDAsMHg4MDgsMHgxMDAwMDAwLDB4MTAwMDAwOCwweDEwMDA4MDAsMHgxMDAwODA4LDAsMHg4LDB4ODAwLDB4ODA4LDB4MTAwMDAwMCwweDEwMDAwMDgsMHgxMDAwODAwLDB4MTAwMDgwOF0sCiAgICAgIHBjMmJ5dGVzMyAgPSBbMCwweDIwMDAwMCwweDgwMDAwMDAsMHg4MjAwMDAwLDB4MjAwMCwweDIwMjAwMCwweDgwMDIwMDAsMHg4MjAyMDAwLDB4MjAwMDAsMHgyMjAwMDAsMHg4MDIwMDAwLDB4ODIyMDAwMCwweDIyMDAwLDB4MjIyMDAwLDB4ODAyMjAwMCwweDgyMjIwMDBdLAogICAgICBwYzJieXRlczQgID0gWzAsMHg0MDAwMCwweDEwLDB4NDAwMTAsMCwweDQwMDAwLDB4MTAsMHg0MDAxMCwweDEwMDAsMHg0MTAwMCwweDEwMTAsMHg0MTAxMCwweDEwMDAsMHg0MTAwMCwweDEwMTAsMHg0MTAxMF0sCiAgICAgIHBjMmJ5dGVzNSAgPSBbMCwweDQwMCwweDIwLDB4NDIwLDAsMHg0MDAsMHgyMCwweDQyMCwweDIwMDAwMDAsMHgyMDAwNDAwLDB4MjAwMDAyMCwweDIwMDA0MjAsMHgyMDAwMDAwLDB4MjAwMDQwMCwweDIwMDAwMjAsMHgyMDAwNDIwXSwKICAgICAgcGMyYnl0ZXM2ICA9IFswLDB4MTAwMDAwMDAsMHg4MDAwMCwweDEwMDgwMDAwLDB4MiwweDEwMDAwMDAyLDB4ODAwMDIsMHgxMDA4MDAwMiwwLDB4MTAwMDAwMDAsMHg4MDAwMCwweDEwMDgwMDAwLDB4MiwweDEwMDAwMDAyLDB4ODAwMDIsMHgxMDA4MDAwMl0sCiAgICAgIHBjMmJ5dGVzNyAgPSBbMCwweDEwMDAwLDB4ODAwLDB4MTA4MDAsMHgyMDAwMDAwMCwweDIwMDEwMDAwLDB4MjAwMDA4MDAsMHgyMDAxMDgwMCwweDIwMDAwLDB4MzAwMDAsMHgyMDgwMCwweDMwODAwLDB4MjAwMjAwMDAsMHgyMDAzMDAwMCwweDIwMDIwODAwLDB4MjAwMzA4MDBdLAogICAgICBwYzJieXRlczggID0gWzAsMHg0MDAwMCwwLDB4NDAwMDAsMHgyLDB4NDAwMDIsMHgyLDB4NDAwMDIsMHgyMDAwMDAwLDB4MjA0MDAwMCwweDIwMDAwMDAsMHgyMDQwMDAwLDB4MjAwMDAwMiwweDIwNDAwMDIsMHgyMDAwMDAyLDB4MjA0MDAwMl0sCiAgICAgIHBjMmJ5dGVzOSAgPSBbMCwweDEwMDAwMDAwLDB4OCwweDEwMDAwMDA4LDAsMHgxMDAwMDAwMCwweDgsMHgxMDAwMDAwOCwweDQwMCwweDEwMDAwNDAwLDB4NDA4LDB4MTAwMDA0MDgsMHg0MDAsMHgxMDAwMDQwMCwweDQwOCwweDEwMDAwNDA4XSwKICAgICAgcGMyYnl0ZXMxMCA9IFswLDB4MjAsMCwweDIwLDB4MTAwMDAwLDB4MTAwMDIwLDB4MTAwMDAwLDB4MTAwMDIwLDB4MjAwMCwweDIwMjAsMHgyMDAwLDB4MjAyMCwweDEwMjAwMCwweDEwMjAyMCwweDEwMjAwMCwweDEwMjAyMF0sCiAgICAgIHBjMmJ5dGVzMTEgPSBbMCwweDEwMDAwMDAsMHgyMDAsMHgxMDAwMjAwLDB4MjAwMDAwLDB4MTIwMDAwMCwweDIwMDIwMCwweDEyMDAyMDAsMHg0MDAwMDAwLDB4NTAwMDAwMCwweDQwMDAyMDAsMHg1MDAwMjAwLDB4NDIwMDAwMCwweDUyMDAwMDAsMHg0MjAwMjAwLDB4NTIwMDIwMF0sCiAgICAgIHBjMmJ5dGVzMTIgPSBbMCwweDEwMDAsMHg4MDAwMDAwLDB4ODAwMTAwMCwweDgwMDAwLDB4ODEwMDAsMHg4MDgwMDAwLDB4ODA4MTAwMCwweDEwLDB4MTAxMCwweDgwMDAwMTAsMHg4MDAxMDEwLDB4ODAwMTAsMHg4MTAxMCwweDgwODAwMTAsMHg4MDgxMDEwXSwKICAgICAgcGMyYnl0ZXMxMyA9IFswLDB4NCwweDEwMCwweDEwNCwwLDB4NCwweDEwMCwweDEwNCwweDEsMHg1LDB4MTAxLDB4MTA1LDB4MSwweDUsMHgxMDEsMHgxMDVdOwoKICAvLyBob3cgbWFueSBpdGVyYXRpb25zICgxIGZvciBkZXMsIDMgZm9yIHRyaXBsZSBkZXMpCiAgLy8gY2hhbmdlZCBieSBQYXVsIDE2LzYvMjAwNyB0byB1c2UgVHJpcGxlIERFUyBmb3IgOSsgYnl0ZSBrZXlzCiAgdmFyIGl0ZXJhdGlvbnMgPSBrZXkubGVuZ3RoKCkgPiA4ID8gMyA6IDE7CgogIC8vIHN0b3JlcyB0aGUgcmV0dXJuIGtleXMKICB2YXIga2V5cyA9IFtdOwoKICAvLyBub3cgZGVmaW5lIHRoZSBsZWZ0IHNoaWZ0cyB3aGljaCBuZWVkIHRvIGJlIGRvbmUKICB2YXIgc2hpZnRzID0gWzAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDBdOwoKICB2YXIgbiA9IDAsIHRtcDsKICBmb3IodmFyIGogPSAwOyBqIDwgaXRlcmF0aW9uczsgaiArKykgewogICAgdmFyIGxlZnQgPSBrZXkuZ2V0SW50MzIoKTsKICAgIHZhciByaWdodCA9IGtleS5nZXRJbnQzMigpOwoKICAgIHRtcCA9ICgobGVmdCA+Pj4gNCkgXiByaWdodCkgJiAweDBmMGYwZjBmOwogICAgcmlnaHQgXj0gdG1wOwogICAgbGVmdCBePSAodG1wIDw8IDQpOwoKICAgIHRtcCA9ICgocmlnaHQgPj4+IC0xNikgXiBsZWZ0KSAmIDB4MDAwMGZmZmY7CiAgICBsZWZ0IF49IHRtcDsKICAgIHJpZ2h0IF49ICh0bXAgPDwgLTE2KTsKCiAgICB0bXAgPSAoKGxlZnQgPj4+IDIpIF4gcmlnaHQpICYgMHgzMzMzMzMzMzsKICAgIHJpZ2h0IF49IHRtcDsKICAgIGxlZnQgXj0gKHRtcCA8PCAyKTsKCiAgICB0bXAgPSAoKHJpZ2h0ID4+PiAtMTYpIF4gbGVmdCkgJiAweDAwMDBmZmZmOwogICAgbGVmdCBePSB0bXA7CiAgICByaWdodCBePSAodG1wIDw8IC0xNik7CgogICAgdG1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7CiAgICByaWdodCBePSB0bXA7CiAgICBsZWZ0IF49ICh0bXAgPDwgMSk7CgogICAgdG1wID0gKChyaWdodCA+Pj4gOCkgXiBsZWZ0KSAmIDB4MDBmZjAwZmY7CiAgICBsZWZ0IF49IHRtcDsKICAgIHJpZ2h0IF49ICh0bXAgPDwgOCk7CgogICAgdG1wID0gKChsZWZ0ID4+PiAxKSBeIHJpZ2h0KSAmIDB4NTU1NTU1NTU7CiAgICByaWdodCBePSB0bXA7CiAgICBsZWZ0IF49ICh0bXAgPDwgMSk7CgogICAgLy8gcmlnaHQgbmVlZHMgdG8gYmUgc2hpZnRlZCBhbmQgT1InZCB3aXRoIGxhc3QgZm91ciBiaXRzIG9mIGxlZnQKICAgIHRtcCA9IChsZWZ0IDw8IDgpIHwgKChyaWdodCA+Pj4gMjApICYgMHgwMDAwMDBmMCk7CgogICAgLy8gbGVmdCBuZWVkcyB0byBiZSBwdXQgdXBzaWRlIGRvd24KICAgIGxlZnQgPSAoKHJpZ2h0IDw8IDI0KSB8ICgocmlnaHQgPDwgOCkgJiAweGZmMDAwMCkgfAogICAgICAoKHJpZ2h0ID4+PiA4KSAmIDB4ZmYwMCkgfCAoKHJpZ2h0ID4+PiAyNCkgJiAweGYwKSk7CiAgICByaWdodCA9IHRtcDsKCiAgICAvLyBub3cgZ28gdGhyb3VnaCBhbmQgcGVyZm9ybSB0aGVzZSBzaGlmdHMgb24gdGhlIGxlZnQgYW5kIHJpZ2h0IGtleXMKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBzaGlmdHMubGVuZ3RoOyArK2kpIHsKICAgICAgLy9zaGlmdCB0aGUga2V5cyBlaXRoZXIgb25lIG9yIHR3byBiaXRzIHRvIHRoZSBsZWZ0CiAgICAgIGlmKHNoaWZ0c1tpXSkgewogICAgICAgIGxlZnQgPSAobGVmdCA8PCAyKSB8IChsZWZ0ID4+PiAyNik7CiAgICAgICAgcmlnaHQgPSAocmlnaHQgPDwgMikgfCAocmlnaHQgPj4+IDI2KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBsZWZ0ID0gKGxlZnQgPDwgMSkgfCAobGVmdCA+Pj4gMjcpOwogICAgICAgIHJpZ2h0ID0gKHJpZ2h0IDw8IDEpIHwgKHJpZ2h0ID4+PiAyNyk7CiAgICAgIH0KICAgICAgbGVmdCAmPSAtMHhmOwogICAgICByaWdodCAmPSAtMHhmOwoKICAgICAgLy8gbm93IGFwcGx5IFBDLTIsIGluIHN1Y2ggYSB3YXkgdGhhdCBFIGlzIGVhc2llciB3aGVuIGVuY3J5cHRpbmcgb3IKICAgICAgLy8gZGVjcnlwdGluZyB0aGlzIGNvbnZlcnNpb24gd2lsbCBsb29rIGxpa2UgUEMtMiBleGNlcHQgb25seSB0aGUgbGFzdCA2CiAgICAgIC8vIGJpdHMgb2YgZWFjaCBieXRlIGFyZSB1c2VkIHJhdGhlciB0aGFuIDQ4IGNvbnNlY3V0aXZlIGJpdHMgYW5kIHRoZQogICAgICAvLyBvcmRlciBvZiBsaW5lcyB3aWxsIGJlIGFjY29yZGluZyB0byBob3cgdGhlIFMgc2VsZWN0aW9uIGZ1bmN0aW9ucyB3aWxsCiAgICAgIC8vIGJlIGFwcGxpZWQ6IFMyLCBTNCwgUzYsIFM4LCBTMSwgUzMsIFM1LCBTNwogICAgICB2YXIgbGVmdHRtcCA9ICgKICAgICAgICBwYzJieXRlczBbbGVmdCA+Pj4gMjhdIHwgcGMyYnl0ZXMxWyhsZWZ0ID4+PiAyNCkgJiAweGZdIHwKICAgICAgICBwYzJieXRlczJbKGxlZnQgPj4+IDIwKSAmIDB4Zl0gfCBwYzJieXRlczNbKGxlZnQgPj4+IDE2KSAmIDB4Zl0gfAogICAgICAgIHBjMmJ5dGVzNFsobGVmdCA+Pj4gMTIpICYgMHhmXSB8IHBjMmJ5dGVzNVsobGVmdCA+Pj4gOCkgJiAweGZdIHwKICAgICAgICBwYzJieXRlczZbKGxlZnQgPj4+IDQpICYgMHhmXSk7CiAgICAgIHZhciByaWdodHRtcCA9ICgKICAgICAgICBwYzJieXRlczdbcmlnaHQgPj4+IDI4XSB8IHBjMmJ5dGVzOFsocmlnaHQgPj4+IDI0KSAmIDB4Zl0gfAogICAgICAgIHBjMmJ5dGVzOVsocmlnaHQgPj4+IDIwKSAmIDB4Zl0gfCBwYzJieXRlczEwWyhyaWdodCA+Pj4gMTYpICYgMHhmXSB8CiAgICAgICAgcGMyYnl0ZXMxMVsocmlnaHQgPj4+IDEyKSAmIDB4Zl0gfCBwYzJieXRlczEyWyhyaWdodCA+Pj4gOCkgJiAweGZdIHwKICAgICAgICBwYzJieXRlczEzWyhyaWdodCA+Pj4gNCkgJiAweGZdKTsKICAgICAgdG1wID0gKChyaWdodHRtcCA+Pj4gMTYpIF4gbGVmdHRtcCkgJiAweDAwMDBmZmZmOwogICAgICBrZXlzW24rK10gPSBsZWZ0dG1wIF4gdG1wOwogICAgICBrZXlzW24rK10gPSByaWdodHRtcCBeICh0bXAgPDwgMTYpOwogICAgfQogIH0KCiAgcmV0dXJuIGtleXM7Cn0KCi8qKgogKiBVcGRhdGVzIGEgc2luZ2xlIGJsb2NrICgxIGJ5dGUpIHVzaW5nIERFUy4gVGhlIHVwZGF0ZSB3aWxsIGVpdGhlcgogKiBlbmNyeXB0IG9yIGRlY3J5cHQgdGhlIGJsb2NrLgogKgogKiBAcGFyYW0ga2V5cyB0aGUgZXhwYW5kZWQga2V5cy4KICogQHBhcmFtIGlucHV0IHRoZSBpbnB1dCBibG9jayAoYW4gYXJyYXkgb2YgMzItYml0IHdvcmRzKS4KICogQHBhcmFtIG91dHB1dCB0aGUgdXBkYXRlZCBvdXRwdXQgYmxvY2suCiAqIEBwYXJhbSBkZWNyeXB0IHRydWUgdG8gZGVjcnlwdCB0aGUgYmxvY2ssIGZhbHNlIHRvIGVuY3J5cHQgaXQuCiAqLwpmdW5jdGlvbiBfdXBkYXRlQmxvY2soa2V5cywgaW5wdXQsIG91dHB1dCwgZGVjcnlwdCkgewogIC8vIHNldCB1cCBsb29wcyBmb3Igc2luZ2xlIG9yIHRyaXBsZSBERVMKICB2YXIgaXRlcmF0aW9ucyA9IGtleXMubGVuZ3RoID09PSAzMiA/IDMgOiA5OwogIHZhciBsb29waW5nOwogIGlmKGl0ZXJhdGlvbnMgPT09IDMpIHsKICAgIGxvb3BpbmcgPSBkZWNyeXB0ID8gWzMwLCAtMiwgLTJdIDogWzAsIDMyLCAyXTsKICB9IGVsc2UgewogICAgbG9vcGluZyA9IChkZWNyeXB0ID8KICAgICAgWzk0LCA2MiwgLTIsIDMyLCA2NCwgMiwgMzAsIC0yLCAtMl0gOgogICAgICBbMCwgMzIsIDIsIDYyLCAzMCwgLTIsIDY0LCA5NiwgMl0pOwogIH0KCiAgdmFyIHRtcDsKCiAgdmFyIGxlZnQgPSBpbnB1dFswXTsKICB2YXIgcmlnaHQgPSBpbnB1dFsxXTsKCiAgLy8gZmlyc3QgZWFjaCA2NCBiaXQgY2h1bmsgb2YgdGhlIG1lc3NhZ2UgbXVzdCBiZSBwZXJtdXRlZCBhY2NvcmRpbmcgdG8gSVAKICB0bXAgPSAoKGxlZnQgPj4+IDQpIF4gcmlnaHQpICYgMHgwZjBmMGYwZjsKICByaWdodCBePSB0bXA7CiAgbGVmdCBePSAodG1wIDw8IDQpOwoKICB0bXAgPSAoKGxlZnQgPj4+IDE2KSBeIHJpZ2h0KSAmIDB4MDAwMGZmZmY7CiAgcmlnaHQgXj0gdG1wOwogIGxlZnQgXj0gKHRtcCA8PCAxNik7CgogIHRtcCA9ICgocmlnaHQgPj4+IDIpIF4gbGVmdCkgJiAweDMzMzMzMzMzOwogIGxlZnQgXj0gdG1wOwogIHJpZ2h0IF49ICh0bXAgPDwgMik7CgogIHRtcCA9ICgocmlnaHQgPj4+IDgpIF4gbGVmdCkgJiAweDAwZmYwMGZmOwogIGxlZnQgXj0gdG1wOwogIHJpZ2h0IF49ICh0bXAgPDwgOCk7CgogIHRtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1OwogIHJpZ2h0IF49IHRtcDsKICBsZWZ0IF49ICh0bXAgPDwgMSk7CgogIC8vIHJvdGF0ZSBsZWZ0IDEgYml0CiAgbGVmdCA9ICgobGVmdCA8PCAxKSB8IChsZWZ0ID4+PiAzMSkpOwogIHJpZ2h0ID0gKChyaWdodCA8PCAxKSB8IChyaWdodCA+Pj4gMzEpKTsKCiAgZm9yKHZhciBqID0gMDsgaiA8IGl0ZXJhdGlvbnM7IGogKz0gMykgewogICAgdmFyIGVuZGxvb3AgPSBsb29waW5nW2ogKyAxXTsKICAgIHZhciBsb29waW5jID0gbG9vcGluZ1tqICsgMl07CgogICAgLy8gbm93IGdvIHRocm91Z2ggYW5kIHBlcmZvcm0gdGhlIGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbgogICAgZm9yKHZhciBpID0gbG9vcGluZ1tqXTsgaSAhPSBlbmRsb29wOyBpICs9IGxvb3BpbmMpIHsKICAgICAgdmFyIHJpZ2h0MSA9IHJpZ2h0IF4ga2V5c1tpXTsKICAgICAgdmFyIHJpZ2h0MiA9ICgocmlnaHQgPj4+IDQpIHwgKHJpZ2h0IDw8IDI4KSkgXiBrZXlzW2kgKyAxXTsKCiAgICAgIC8vIHBhc3NpbmcgdGhlc2UgYnl0ZXMgdGhyb3VnaCB0aGUgUyBzZWxlY3Rpb24gZnVuY3Rpb25zCiAgICAgIHRtcCA9IGxlZnQ7CiAgICAgIGxlZnQgPSByaWdodDsKICAgICAgcmlnaHQgPSB0bXAgXiAoCiAgICAgICAgc3BmdW5jdGlvbjJbKHJpZ2h0MSA+Pj4gMjQpICYgMHgzZl0gfAogICAgICAgIHNwZnVuY3Rpb240WyhyaWdodDEgPj4+IDE2KSAmIDB4M2ZdIHwKICAgICAgICBzcGZ1bmN0aW9uNlsocmlnaHQxID4+PiAgOCkgJiAweDNmXSB8CiAgICAgICAgc3BmdW5jdGlvbjhbcmlnaHQxICYgMHgzZl0gfAogICAgICAgIHNwZnVuY3Rpb24xWyhyaWdodDIgPj4+IDI0KSAmIDB4M2ZdIHwKICAgICAgICBzcGZ1bmN0aW9uM1socmlnaHQyID4+PiAxNikgJiAweDNmXSB8CiAgICAgICAgc3BmdW5jdGlvbjVbKHJpZ2h0MiA+Pj4gIDgpICYgMHgzZl0gfAogICAgICAgIHNwZnVuY3Rpb243W3JpZ2h0MiAmIDB4M2ZdKTsKICAgIH0KICAgIC8vIHVucmV2ZXJzZSBsZWZ0IGFuZCByaWdodAogICAgdG1wID0gbGVmdDsKICAgIGxlZnQgPSByaWdodDsKICAgIHJpZ2h0ID0gdG1wOwogIH0KCiAgLy8gcm90YXRlIHJpZ2h0IDEgYml0CiAgbGVmdCA9ICgobGVmdCA+Pj4gMSkgfCAobGVmdCA8PCAzMSkpOwogIHJpZ2h0ID0gKChyaWdodCA+Pj4gMSkgfCAocmlnaHQgPDwgMzEpKTsKCiAgLy8gbm93IHBlcmZvcm0gSVAtMSwgd2hpY2ggaXMgSVAgaW4gdGhlIG9wcG9zaXRlIGRpcmVjdGlvbgogIHRtcCA9ICgobGVmdCA+Pj4gMSkgXiByaWdodCkgJiAweDU1NTU1NTU1OwogIHJpZ2h0IF49IHRtcDsKICBsZWZ0IF49ICh0bXAgPDwgMSk7CgogIHRtcCA9ICgocmlnaHQgPj4+IDgpIF4gbGVmdCkgJiAweDAwZmYwMGZmOwogIGxlZnQgXj0gdG1wOwogIHJpZ2h0IF49ICh0bXAgPDwgOCk7CgogIHRtcCA9ICgocmlnaHQgPj4+IDIpIF4gbGVmdCkgJiAweDMzMzMzMzMzOwogIGxlZnQgXj0gdG1wOwogIHJpZ2h0IF49ICh0bXAgPDwgMik7CgogIHRtcCA9ICgobGVmdCA+Pj4gMTYpIF4gcmlnaHQpICYgMHgwMDAwZmZmZjsKICByaWdodCBePSB0bXA7CiAgbGVmdCBePSAodG1wIDw8IDE2KTsKCiAgdG1wID0gKChsZWZ0ID4+PiA0KSBeIHJpZ2h0KSAmIDB4MGYwZjBmMGY7CiAgcmlnaHQgXj0gdG1wOwogIGxlZnQgXj0gKHRtcCA8PCA0KTsKCiAgb3V0cHV0WzBdID0gbGVmdDsKICBvdXRwdXRbMV0gPSByaWdodDsKfQoKLyoqCiAqIERlcHJlY2F0ZWQuIEluc3RlYWQsIHVzZToKICoKICogZm9yZ2UuY2lwaGVyLmNyZWF0ZUNpcGhlcignREVTLTxtb2RlPicsIGtleSk7CiAqIGZvcmdlLmNpcGhlci5jcmVhdGVEZWNpcGhlcignREVTLTxtb2RlPicsIGtleSk7CiAqCiAqIENyZWF0ZXMgYSBkZXByZWNhdGVkIERFUyBjaXBoZXIgb2JqZWN0LiBUaGlzIG9iamVjdCdzIG1vZGUgd2lsbCBkZWZhdWx0IHRvCiAqIENCQyAoY2lwaGVyLWJsb2NrLWNoYWluaW5nKS4KICoKICogVGhlIGtleSBtYXkgYmUgZ2l2ZW4gYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMgb3IgYSBieXRlIGJ1ZmZlci4KICoKICogQHBhcmFtIG9wdGlvbnMgdGhlIG9wdGlvbnMgdG8gdXNlLgogKiAgICAgICAgICBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlICg2NCBvciAxOTIgYml0cykuCiAqICAgICAgICAgIG91dHB1dCB0aGUgYnVmZmVyIHRvIHdyaXRlIHRvLgogKiAgICAgICAgICBkZWNyeXB0IHRydWUgZm9yIGRlY3J5cHRpb24sIGZhbHNlIGZvciBlbmNyeXB0aW9uLgogKiAgICAgICAgICBtb2RlIHRoZSBjaXBoZXIgbW9kZSB0byB1c2UgKGRlZmF1bHQ6ICdDQkMnKS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZnVuY3Rpb24gX2NyZWF0ZUNpcGhlcihvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdmFyIG1vZGUgPSAob3B0aW9ucy5tb2RlIHx8ICdDQkMnKS50b1VwcGVyQ2FzZSgpOwogIHZhciBhbGdvcml0aG0gPSAnREVTLScgKyBtb2RlOwoKICB2YXIgY2lwaGVyOwogIGlmKG9wdGlvbnMuZGVjcnlwdCkgewogICAgY2lwaGVyID0gZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKGFsZ29yaXRobSwgb3B0aW9ucy5rZXkpOwogIH0gZWxzZSB7CiAgICBjaXBoZXIgPSBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKGFsZ29yaXRobSwgb3B0aW9ucy5rZXkpOwogIH0KCiAgLy8gYmFja3dhcmRzIGNvbXBhdGlibGUgc3RhcnQgQVBJCiAgdmFyIHN0YXJ0ID0gY2lwaGVyLnN0YXJ0OwogIGNpcGhlci5zdGFydCA9IGZ1bmN0aW9uKGl2LCBvcHRpb25zKSB7CiAgICAvLyBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eTogc3VwcG9ydCBzZWNvbmQgYXJnIGFzIG91dHB1dCBidWZmZXIKICAgIHZhciBvdXRwdXQgPSBudWxsOwogICAgaWYob3B0aW9ucyBpbnN0YW5jZW9mIGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcikgewogICAgICBvdXRwdXQgPSBvcHRpb25zOwogICAgICBvcHRpb25zID0ge307CiAgICB9CiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICAgIG9wdGlvbnMub3V0cHV0ID0gb3V0cHV0OwogICAgb3B0aW9ucy5pdiA9IGl2OwogICAgc3RhcnQuY2FsbChjaXBoZXIsIG9wdGlvbnMpOwogIH07CgogIHJldHVybiBjaXBoZXI7Cn0KCgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdkZXMnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgKICAnanMvZGVzJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vY2lwaGVyJywgJy4vY2lwaGVyTW9kZXMnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFBhc3N3b3JkLUJhc2VkIEtleS1EZXJpdmF0aW9uIEZ1bmN0aW9uICMyIGltcGxlbWVudGF0aW9uLgogKgogKiBTZWUgUkZDIDI4OTggZm9yIGRldGFpbHMuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEzIERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKdmFyIHBrY3M1ID0gZm9yZ2UucGtjczUgPSBmb3JnZS5wa2NzNSB8fCB7fTsKCnZhciBfbm9kZWpzID0gKAogIHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb25zICYmIHByb2Nlc3MudmVyc2lvbnMubm9kZSk7CnZhciBjcnlwdG87CmlmKF9ub2RlanMgJiYgIWZvcmdlLmRpc2FibGVOYXRpdmVDb2RlKSB7CiAgY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7Cn0KCi8qKgogKiBEZXJpdmVzIGEga2V5IGZyb20gYSBwYXNzd29yZC4KICoKICogQHBhcmFtIHAgdGhlIHBhc3N3b3JkIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogKiBAcGFyYW0gcyB0aGUgc2FsdCBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBieXRlcy4KICogQHBhcmFtIGMgdGhlIGl0ZXJhdGlvbiBjb3VudCwgYSBwb3NpdGl2ZSBpbnRlZ2VyLgogKiBAcGFyYW0gZGtMZW4gdGhlIGludGVuZGVkIGxlbmd0aCwgaW4gYnl0ZXMsIG9mIHRoZSBkZXJpdmVkIGtleSwKICogICAgICAgICAgKG1heDogMl4zMiAtIDEpICogaGFzaCBsZW5ndGggb2YgdGhlIFBSRi4KICogQHBhcmFtIFttZF0gdGhlIG1lc3NhZ2UgZGlnZXN0IChvciBhbGdvcml0aG0gaWRlbnRpZmllciBhcyBhIHN0cmluZykgdG8gdXNlCiAqICAgICAgICAgIGluIHRoZSBQUkYsIGRlZmF1bHRzIHRvIFNIQS0xLgogKiBAcGFyYW0gW2NhbGxiYWNrKGVyciwga2V5KV0gcHJlc2VuY2UgdHJpZ2dlcnMgYXN5bmNocm9ub3VzIHZlcnNpb24sIGNhbGxlZAogKiAgICAgICAgICBvbmNlIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLgogKgogKiBAcmV0dXJuIHRoZSBkZXJpdmVkIGtleSwgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMsIGZvciB0aGUKICogICAgICAgICAgIHN5bmNocm9ub3VzIHZlcnNpb24gKGlmIG5vIGNhbGxiYWNrIGlzIHNwZWNpZmllZCkuCiAqLwpmb3JnZS5wYmtkZjIgPSBwa2NzNS5wYmtkZjIgPSBmdW5jdGlvbihwLCBzLCBjLCBka0xlbiwgbWQsIGNhbGxiYWNrKSB7CiAgaWYodHlwZW9mIG1kID09PSAnZnVuY3Rpb24nKSB7CiAgICBjYWxsYmFjayA9IG1kOwogICAgbWQgPSBudWxsOwogIH0KCiAgLy8gdXNlIG5hdGl2ZSBpbXBsZW1lbnRhdGlvbiBpZiBwb3NzaWJsZSBhbmQgbm90IGRpc2FibGVkLCBub3RlIHRoYXQKICAvLyBzb21lIG5vZGUgdmVyc2lvbnMgb25seSBzdXBwb3J0IFNIQS0xLCBvdGhlcnMgYWxsb3cgZGlnZXN0IHRvIGJlIGNoYW5nZWQKICBpZihfbm9kZWpzICYmICFmb3JnZS5kaXNhYmxlTmF0aXZlQ29kZSAmJiBjcnlwdG8ucGJrZGYyICYmCiAgICAobWQgPT09IG51bGwgfHwgdHlwZW9mIG1kICE9PSAnb2JqZWN0JykgJiYKICAgIChjcnlwdG8ucGJrZGYyU3luYy5sZW5ndGggPiA0IHx8ICghbWQgfHwgbWQgPT09ICdzaGExJykpKSB7CiAgICBpZih0eXBlb2YgbWQgIT09ICdzdHJpbmcnKSB7CiAgICAgIC8vIGRlZmF1bHQgcHJmIHRvIFNIQS0xCiAgICAgIG1kID0gJ3NoYTEnOwogICAgfQogICAgcyA9IG5ldyBCdWZmZXIocywgJ2JpbmFyeScpOwogICAgaWYoIWNhbGxiYWNrKSB7CiAgICAgIGlmKGNyeXB0by5wYmtkZjJTeW5jLmxlbmd0aCA9PT0gNCkgewogICAgICAgIHJldHVybiBjcnlwdG8ucGJrZGYyU3luYyhwLCBzLCBjLCBka0xlbikudG9TdHJpbmcoJ2JpbmFyeScpOwogICAgICB9CiAgICAgIHJldHVybiBjcnlwdG8ucGJrZGYyU3luYyhwLCBzLCBjLCBka0xlbiwgbWQpLnRvU3RyaW5nKCdiaW5hcnknKTsKICAgIH0KICAgIGlmKGNyeXB0by5wYmtkZjJTeW5jLmxlbmd0aCA9PT0gNCkgewogICAgICByZXR1cm4gY3J5cHRvLnBia2RmMihwLCBzLCBjLCBka0xlbiwgZnVuY3Rpb24oZXJyLCBrZXkpIHsKICAgICAgICBpZihlcnIpIHsKICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpOwogICAgICAgIH0KICAgICAgICBjYWxsYmFjayhudWxsLCBrZXkudG9TdHJpbmcoJ2JpbmFyeScpKTsKICAgICAgfSk7CiAgICB9CiAgICByZXR1cm4gY3J5cHRvLnBia2RmMihwLCBzLCBjLCBka0xlbiwgbWQsIGZ1bmN0aW9uKGVyciwga2V5KSB7CiAgICAgIGlmKGVycikgewogICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpOwogICAgICB9CiAgICAgIGNhbGxiYWNrKG51bGwsIGtleS50b1N0cmluZygnYmluYXJ5JykpOwogICAgfSk7CiAgfQoKICBpZih0eXBlb2YgbWQgPT09ICd1bmRlZmluZWQnIHx8IG1kID09PSBudWxsKSB7CiAgICAvLyBkZWZhdWx0IHByZiB0byBTSEEtMQogICAgbWQgPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogIH0KICBpZih0eXBlb2YgbWQgPT09ICdzdHJpbmcnKSB7CiAgICBpZighKG1kIGluIGZvcmdlLm1kLmFsZ29yaXRobXMpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBoYXNoIGFsZ29yaXRobTogJyArIG1kKTsKICAgIH0KICAgIG1kID0gZm9yZ2UubWRbbWRdLmNyZWF0ZSgpOwogIH0KCiAgdmFyIGhMZW4gPSBtZC5kaWdlc3RMZW5ndGg7CgogIC8qIDEuIElmIGRrTGVuID4gKDJeMzIgLSAxKSAqIGhMZW4sIG91dHB1dCAiZGVyaXZlZCBrZXkgdG9vIGxvbmciIGFuZAogICAgc3RvcC4gKi8KICBpZihka0xlbiA+ICgweEZGRkZGRkZGICogaExlbikpIHsKICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ0Rlcml2ZWQga2V5IGlzIHRvbyBsb25nLicpOwogICAgaWYoY2FsbGJhY2spIHsKICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7CiAgICB9CiAgICB0aHJvdyBlcnI7CiAgfQoKICAvKiAyLiBMZXQgbGVuIGJlIHRoZSBudW1iZXIgb2YgaExlbi1vY3RldCBibG9ja3MgaW4gdGhlIGRlcml2ZWQga2V5LAogICAgcm91bmRpbmcgdXAsIGFuZCBsZXQgciBiZSB0aGUgbnVtYmVyIG9mIG9jdGV0cyBpbiB0aGUgbGFzdAogICAgYmxvY2s6CgogICAgbGVuID0gQ0VJTChka0xlbiAvIGhMZW4pLAogICAgciA9IGRrTGVuIC0gKGxlbiAtIDEpICogaExlbi4gKi8KICB2YXIgbGVuID0gTWF0aC5jZWlsKGRrTGVuIC8gaExlbik7CiAgdmFyIHIgPSBka0xlbiAtIChsZW4gLSAxKSAqIGhMZW47CgogIC8qIDMuIEZvciBlYWNoIGJsb2NrIG9mIHRoZSBkZXJpdmVkIGtleSBhcHBseSB0aGUgZnVuY3Rpb24gRiBkZWZpbmVkCiAgICBiZWxvdyB0byB0aGUgcGFzc3dvcmQgUCwgdGhlIHNhbHQgUywgdGhlIGl0ZXJhdGlvbiBjb3VudCBjLCBhbmQKICAgIHRoZSBibG9jayBpbmRleCB0byBjb21wdXRlIHRoZSBibG9jazoKCiAgICBUXzEgPSBGKFAsIFMsIGMsIDEpLAogICAgVF8yID0gRihQLCBTLCBjLCAyKSwKICAgIC4uLgogICAgVF9sZW4gPSBGKFAsIFMsIGMsIGxlbiksCgogICAgd2hlcmUgdGhlIGZ1bmN0aW9uIEYgaXMgZGVmaW5lZCBhcyB0aGUgZXhjbHVzaXZlLW9yIHN1bSBvZiB0aGUKICAgIGZpcnN0IGMgaXRlcmF0ZXMgb2YgdGhlIHVuZGVybHlpbmcgcHNldWRvcmFuZG9tIGZ1bmN0aW9uIFBSRgogICAgYXBwbGllZCB0byB0aGUgcGFzc3dvcmQgUCBhbmQgdGhlIGNvbmNhdGVuYXRpb24gb2YgdGhlIHNhbHQgUwogICAgYW5kIHRoZSBibG9jayBpbmRleCBpOgoKICAgIEYoUCwgUywgYywgaSkgPSB1XzEgWE9SIHVfMiBYT1IgLi4uIFhPUiB1X2MKCiAgICB3aGVyZQoKICAgIHVfMSA9IFBSRihQLCBTIHx8IElOVChpKSksCiAgICB1XzIgPSBQUkYoUCwgdV8xKSwKICAgIC4uLgogICAgdV9jID0gUFJGKFAsIHVfe2MtMX0pLgoKICAgIEhlcmUsIElOVChpKSBpcyBhIGZvdXItb2N0ZXQgZW5jb2Rpbmcgb2YgdGhlIGludGVnZXIgaSwgbW9zdAogICAgc2lnbmlmaWNhbnQgb2N0ZXQgZmlyc3QuICovCiAgdmFyIHByZiA9IGZvcmdlLmhtYWMuY3JlYXRlKCk7CiAgcHJmLnN0YXJ0KG1kLCBwKTsKICB2YXIgZGsgPSAnJzsKICB2YXIgeG9yLCB1X2MsIHVfYzE7CgogIC8vIHN5bmMgdmVyc2lvbgogIGlmKCFjYWxsYmFjaykgewogICAgZm9yKHZhciBpID0gMTsgaSA8PSBsZW47ICsraSkgewogICAgICAvLyBQUkYoUCwgUyB8fCBJTlQoaSkpIChmaXJzdCBpdGVyYXRpb24pCiAgICAgIHByZi5zdGFydChudWxsLCBudWxsKTsKICAgICAgcHJmLnVwZGF0ZShzKTsKICAgICAgcHJmLnVwZGF0ZShmb3JnZS51dGlsLmludDMyVG9CeXRlcyhpKSk7CiAgICAgIHhvciA9IHVfYzEgPSBwcmYuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKCiAgICAgIC8vIFBSRihQLCB1X3tjLTF9KSAob3RoZXIgaXRlcmF0aW9ucykKICAgICAgZm9yKHZhciBqID0gMjsgaiA8PSBjOyArK2opIHsKICAgICAgICBwcmYuc3RhcnQobnVsbCwgbnVsbCk7CiAgICAgICAgcHJmLnVwZGF0ZSh1X2MxKTsKICAgICAgICB1X2MgPSBwcmYuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKICAgICAgICAvLyBGKHAsIHMsIGMsIGkpCiAgICAgICAgeG9yID0gZm9yZ2UudXRpbC54b3JCeXRlcyh4b3IsIHVfYywgaExlbik7CiAgICAgICAgdV9jMSA9IHVfYzsKICAgICAgfQoKICAgICAgLyogNC4gQ29uY2F0ZW5hdGUgdGhlIGJsb2NrcyBhbmQgZXh0cmFjdCB0aGUgZmlyc3QgZGtMZW4gb2N0ZXRzIHRvCiAgICAgICAgcHJvZHVjZSBhIGRlcml2ZWQga2V5IERLOgoKICAgICAgICBESyA9IFRfMSB8fCBUXzIgfHwgIC4uLiAgfHwgVF9sZW48MC4uci0xPiAqLwogICAgICBkayArPSAoaSA8IGxlbikgPyB4b3IgOiB4b3Iuc3Vic3RyKDAsIHIpOwogICAgfQogICAgLyogNS4gT3V0cHV0IHRoZSBkZXJpdmVkIGtleSBESy4gKi8KICAgIHJldHVybiBkazsKICB9CgogIC8vIGFzeW5jIHZlcnNpb24KICB2YXIgaSA9IDEsIGo7CiAgZnVuY3Rpb24gb3V0ZXIoKSB7CiAgICBpZihpID4gbGVuKSB7CiAgICAgIC8vIGRvbmUKICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGRrKTsKICAgIH0KCiAgICAvLyBQUkYoUCwgUyB8fCBJTlQoaSkpIChmaXJzdCBpdGVyYXRpb24pCiAgICBwcmYuc3RhcnQobnVsbCwgbnVsbCk7CiAgICBwcmYudXBkYXRlKHMpOwogICAgcHJmLnVwZGF0ZShmb3JnZS51dGlsLmludDMyVG9CeXRlcyhpKSk7CiAgICB4b3IgPSB1X2MxID0gcHJmLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CgogICAgLy8gUFJGKFAsIHVfe2MtMX0pIChvdGhlciBpdGVyYXRpb25zKQogICAgaiA9IDI7CiAgICBpbm5lcigpOwogIH0KCiAgZnVuY3Rpb24gaW5uZXIoKSB7CiAgICBpZihqIDw9IGMpIHsKICAgICAgcHJmLnN0YXJ0KG51bGwsIG51bGwpOwogICAgICBwcmYudXBkYXRlKHVfYzEpOwogICAgICB1X2MgPSBwcmYuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKICAgICAgLy8gRihwLCBzLCBjLCBpKQogICAgICB4b3IgPSBmb3JnZS51dGlsLnhvckJ5dGVzKHhvciwgdV9jLCBoTGVuKTsKICAgICAgdV9jMSA9IHVfYzsKICAgICAgKytqOwogICAgICByZXR1cm4gZm9yZ2UudXRpbC5zZXRJbW1lZGlhdGUoaW5uZXIpOwogICAgfQoKICAgIC8qIDQuIENvbmNhdGVuYXRlIHRoZSBibG9ja3MgYW5kIGV4dHJhY3QgdGhlIGZpcnN0IGRrTGVuIG9jdGV0cyB0bwogICAgICBwcm9kdWNlIGEgZGVyaXZlZCBrZXkgREs6CgogICAgICBESyA9IFRfMSB8fCBUXzIgfHwgIC4uLiAgfHwgVF9sZW48MC4uci0xPiAqLwogICAgZGsgKz0gKGkgPCBsZW4pID8geG9yIDogeG9yLnN1YnN0cigwLCByKTsKCiAgICArK2k7CiAgICBvdXRlcigpOwogIH0KCiAgb3V0ZXIoKTsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3Bia2RmMic7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9wYmtkZjInLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9obWFjJywgJy4vbWQnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEEgamF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBhIGNyeXB0b2dyYXBoaWNhbGx5LXNlY3VyZQogKiBQc2V1ZG8gUmFuZG9tIE51bWJlciBHZW5lcmF0b3IgKFBSTkcpLiBUaGUgRm9ydHVuYSBhbGdvcml0aG0gaXMgZm9sbG93ZWQKICogaGVyZSB0aG91Z2ggdGhlIHVzZSBvZiBTSEEtMjU2IGlzIG5vdCBlbmZvcmNlZDsgd2hlbiBnZW5lcmF0aW5nIGFuCiAqIGEgUFJORyBjb250ZXh0LCB0aGUgaGFzaGluZyBhbGdvcml0aG0gYW5kIGJsb2NrIGNpcGhlciB1c2VkIGZvcgogKiB0aGUgZ2VuZXJhdG9yIGFyZSBzcGVjaWZpZWQgdmlhIGEgcGx1Z2luLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCnZhciBfbm9kZWpzID0gKAogIHR5cGVvZiBwcm9jZXNzICE9PSAndW5kZWZpbmVkJyAmJiBwcm9jZXNzLnZlcnNpb25zICYmIHByb2Nlc3MudmVyc2lvbnMubm9kZSk7CnZhciBfY3J5cHRvID0gbnVsbDsKaWYoIWZvcmdlLmRpc2FibGVOYXRpdmVDb2RlICYmIF9ub2RlanMgJiYgIXByb2Nlc3MudmVyc2lvbnNbJ25vZGUtd2Via2l0J10pIHsKICBfY3J5cHRvID0gcmVxdWlyZSgnY3J5cHRvJyk7Cn0KCi8qIFBSTkcgQVBJICovCnZhciBwcm5nID0gZm9yZ2UucHJuZyA9IGZvcmdlLnBybmcgfHwge307CgovKioKICogQ3JlYXRlcyBhIG5ldyBQUk5HIGNvbnRleHQuCiAqCiAqIEEgUFJORyBwbHVnaW4gbXVzdCBiZSBwYXNzZWQgaW4gdGhhdCB3aWxsIHByb3ZpZGU6CiAqCiAqIDEuIEEgZnVuY3Rpb24gdGhhdCBpbml0aWFsaXplcyB0aGUga2V5IGFuZCBzZWVkIG9mIGEgUFJORyBjb250ZXh0LiBJdAogKiAgIHdpbGwgYmUgZ2l2ZW4gYSAxNiBieXRlIGtleSBhbmQgYSAxNiBieXRlIHNlZWQuIEFueSBrZXkgZXhwYW5zaW9uCiAqICAgb3IgdHJhbnNmb3JtYXRpb24gb2YgdGhlIHNlZWQgZnJvbSBhIGJ5dGUgc3RyaW5nIGludG8gYW4gYXJyYXkgb2YKICogICBpbnRlZ2VycyAob3Igc2ltaWxhcikgc2hvdWxkIGJlIHBlcmZvcm1lZC4KICogMi4gVGhlIGNyeXB0b2dyYXBoaWMgZnVuY3Rpb24gdXNlZCBieSB0aGUgZ2VuZXJhdG9yLiBJdCB0YWtlcyBhIGtleSBhbmQKICogICBhIHNlZWQuCiAqIDMuIEEgc2VlZCBpbmNyZW1lbnQgZnVuY3Rpb24uIEl0IHRha2VzIHRoZSBzZWVkIGFuZCByZXR1cm5zIHNlZWQgKyAxLgogKiA0LiBBbiBhcGkgdG8gY3JlYXRlIGEgbWVzc2FnZSBkaWdlc3QuCiAqCiAqIEZvciBhbiBleGFtcGxlLCBzZWUgcmFuZG9tLmpzLgogKgogKiBAcGFyYW0gcGx1Z2luIHRoZSBQUk5HIHBsdWdpbiB0byB1c2UuCiAqLwpwcm5nLmNyZWF0ZSA9IGZ1bmN0aW9uKHBsdWdpbikgewogIHZhciBjdHggPSB7CiAgICBwbHVnaW46IHBsdWdpbiwKICAgIGtleTogbnVsbCwKICAgIHNlZWQ6IG51bGwsCiAgICB0aW1lOiBudWxsLAogICAgLy8gbnVtYmVyIG9mIHJlc2VlZHMgc28gZmFyCiAgICByZXNlZWRzOiAwLAogICAgLy8gYW1vdW50IG9mIGRhdGEgZ2VuZXJhdGVkIHNvIGZhcgogICAgZ2VuZXJhdGVkOiAwCiAgfTsKCiAgLy8gY3JlYXRlIDMyIGVudHJvcHkgcG9vbHMgKGVhY2ggaXMgYSBtZXNzYWdlIGRpZ2VzdCkKICB2YXIgbWQgPSBwbHVnaW4ubWQ7CiAgdmFyIHBvb2xzID0gbmV3IEFycmF5KDMyKTsKICBmb3IodmFyIGkgPSAwOyBpIDwgMzI7ICsraSkgewogICAgcG9vbHNbaV0gPSBtZC5jcmVhdGUoKTsKICB9CiAgY3R4LnBvb2xzID0gcG9vbHM7CgogIC8vIGVudHJvcHkgcG9vbHMgYXJlIHdyaXR0ZW4gdG8gY3ljbGljYWxseSwgc3RhcnRpbmcgYXQgaW5kZXggMAogIGN0eC5wb29sID0gMDsKCiAgLyoqCiAgICogR2VuZXJhdGVzIHJhbmRvbSBieXRlcy4gVGhlIGJ5dGVzIG1heSBiZSBnZW5lcmF0ZWQgc3luY2hyb25vdXNseSBvcgogICAqIGFzeW5jaHJvbm91c2x5LiBXZWIgd29ya2VycyBtdXN0IHVzZSB0aGUgYXN5bmNocm9ub3VzIGludGVyZmFjZSBvcgogICAqIGVsc2UgdGhlIGJlaGF2aW9yIGlzIHVuZGVmaW5lZC4KICAgKgogICAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIHJhbmRvbSBieXRlcyB0byBnZW5lcmF0ZS4KICAgKiBAcGFyYW0gW2NhbGxiYWNrKGVyciwgYnl0ZXMpXSBjYWxsZWQgb25jZSB0aGUgb3BlcmF0aW9uIGNvbXBsZXRlcy4KICAgKgogICAqIEByZXR1cm4gY291bnQgcmFuZG9tIGJ5dGVzIGFzIGEgc3RyaW5nLgogICAqLwogIGN0eC5nZW5lcmF0ZSA9IGZ1bmN0aW9uKGNvdW50LCBjYWxsYmFjaykgewogICAgLy8gZG8gc3luY2hyb25vdXNseQogICAgaWYoIWNhbGxiYWNrKSB7CiAgICAgIHJldHVybiBjdHguZ2VuZXJhdGVTeW5jKGNvdW50KTsKICAgIH0KCiAgICAvLyBzaW1wbGUgZ2VuZXJhdG9yIHVzaW5nIGNvdW50ZXItYmFzZWQgQ0JDCiAgICB2YXIgY2lwaGVyID0gY3R4LnBsdWdpbi5jaXBoZXI7CiAgICB2YXIgaW5jcmVtZW50ID0gY3R4LnBsdWdpbi5pbmNyZW1lbnQ7CiAgICB2YXIgZm9ybWF0S2V5ID0gY3R4LnBsdWdpbi5mb3JtYXRLZXk7CiAgICB2YXIgZm9ybWF0U2VlZCA9IGN0eC5wbHVnaW4uZm9ybWF0U2VlZDsKICAgIHZhciBiID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKCiAgICAvLyByZXNldCBrZXkgZm9yIGV2ZXJ5IHJlcXVlc3QKICAgIGN0eC5rZXkgPSBudWxsOwoKICAgIGdlbmVyYXRlKCk7CgogICAgZnVuY3Rpb24gZ2VuZXJhdGUoZXJyKSB7CiAgICAgIGlmKGVycikgewogICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpOwogICAgICB9CgogICAgICAvLyBzdWZmaWNpZW50IGJ5dGVzIGdlbmVyYXRlZAogICAgICBpZihiLmxlbmd0aCgpID49IGNvdW50KSB7CiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGIuZ2V0Qnl0ZXMoY291bnQpKTsKICAgICAgfQoKICAgICAgLy8gaWYgYW1vdW50IG9mIGRhdGEgZ2VuZXJhdGVkIGlzIGdyZWF0ZXIgdGhhbiAxIE1pQiwgdHJpZ2dlciByZXNlZWQKICAgICAgaWYoY3R4LmdlbmVyYXRlZCA+IDB4ZmZmZmYpIHsKICAgICAgICBjdHgua2V5ID0gbnVsbDsKICAgICAgfQoKICAgICAgaWYoY3R4LmtleSA9PT0gbnVsbCkgewogICAgICAgIC8vIHByZXZlbnQgc3RhY2sgb3ZlcmZsb3cKICAgICAgICByZXR1cm4gZm9yZ2UudXRpbC5uZXh0VGljayhmdW5jdGlvbigpIHsKICAgICAgICAgIF9yZXNlZWQoZ2VuZXJhdGUpOwogICAgICAgIH0pOwogICAgICB9CgogICAgICAvLyBnZW5lcmF0ZSB0aGUgcmFuZG9tIGJ5dGVzCiAgICAgIHZhciBieXRlcyA9IGNpcGhlcihjdHgua2V5LCBjdHguc2VlZCk7CiAgICAgIGN0eC5nZW5lcmF0ZWQgKz0gYnl0ZXMubGVuZ3RoOwogICAgICBiLnB1dEJ5dGVzKGJ5dGVzKTsKCiAgICAgIC8vIGdlbmVyYXRlIGJ5dGVzIGZvciBhIG5ldyBrZXkgYW5kIHNlZWQKICAgICAgY3R4LmtleSA9IGZvcm1hdEtleShjaXBoZXIoY3R4LmtleSwgaW5jcmVtZW50KGN0eC5zZWVkKSkpOwogICAgICBjdHguc2VlZCA9IGZvcm1hdFNlZWQoY2lwaGVyKGN0eC5rZXksIGN0eC5zZWVkKSk7CgogICAgICBmb3JnZS51dGlsLnNldEltbWVkaWF0ZShnZW5lcmF0ZSk7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogR2VuZXJhdGVzIHJhbmRvbSBieXRlcyBzeW5jaHJvbm91c2x5LgogICAqCiAgICogQHBhcmFtIGNvdW50IHRoZSBudW1iZXIgb2YgcmFuZG9tIGJ5dGVzIHRvIGdlbmVyYXRlLgogICAqCiAgICogQHJldHVybiBjb3VudCByYW5kb20gYnl0ZXMgYXMgYSBzdHJpbmcuCiAgICovCiAgY3R4LmdlbmVyYXRlU3luYyA9IGZ1bmN0aW9uKGNvdW50KSB7CiAgICAvLyBzaW1wbGUgZ2VuZXJhdG9yIHVzaW5nIGNvdW50ZXItYmFzZWQgQ0JDCiAgICB2YXIgY2lwaGVyID0gY3R4LnBsdWdpbi5jaXBoZXI7CiAgICB2YXIgaW5jcmVtZW50ID0gY3R4LnBsdWdpbi5pbmNyZW1lbnQ7CiAgICB2YXIgZm9ybWF0S2V5ID0gY3R4LnBsdWdpbi5mb3JtYXRLZXk7CiAgICB2YXIgZm9ybWF0U2VlZCA9IGN0eC5wbHVnaW4uZm9ybWF0U2VlZDsKCiAgICAvLyByZXNldCBrZXkgZm9yIGV2ZXJ5IHJlcXVlc3QKICAgIGN0eC5rZXkgPSBudWxsOwoKICAgIHZhciBiID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIHdoaWxlKGIubGVuZ3RoKCkgPCBjb3VudCkgewogICAgICAvLyBpZiBhbW91bnQgb2YgZGF0YSBnZW5lcmF0ZWQgaXMgZ3JlYXRlciB0aGFuIDEgTWlCLCB0cmlnZ2VyIHJlc2VlZAogICAgICBpZihjdHguZ2VuZXJhdGVkID4gMHhmZmZmZikgewogICAgICAgIGN0eC5rZXkgPSBudWxsOwogICAgICB9CgogICAgICBpZihjdHgua2V5ID09PSBudWxsKSB7CiAgICAgICAgX3Jlc2VlZFN5bmMoKTsKICAgICAgfQoKICAgICAgLy8gZ2VuZXJhdGUgdGhlIHJhbmRvbSBieXRlcwogICAgICB2YXIgYnl0ZXMgPSBjaXBoZXIoY3R4LmtleSwgY3R4LnNlZWQpOwogICAgICBjdHguZ2VuZXJhdGVkICs9IGJ5dGVzLmxlbmd0aDsKICAgICAgYi5wdXRCeXRlcyhieXRlcyk7CgogICAgICAvLyBnZW5lcmF0ZSBieXRlcyBmb3IgYSBuZXcga2V5IGFuZCBzZWVkCiAgICAgIGN0eC5rZXkgPSBmb3JtYXRLZXkoY2lwaGVyKGN0eC5rZXksIGluY3JlbWVudChjdHguc2VlZCkpKTsKICAgICAgY3R4LnNlZWQgPSBmb3JtYXRTZWVkKGNpcGhlcihjdHgua2V5LCBjdHguc2VlZCkpOwogICAgfQoKICAgIHJldHVybiBiLmdldEJ5dGVzKGNvdW50KTsKICB9OwoKICAvKioKICAgKiBQcml2YXRlIGZ1bmN0aW9uIHRoYXQgYXN5bmNocm9ub3VzbHkgcmVzZWVkcyBhIGdlbmVyYXRvci4KICAgKgogICAqIEBwYXJhbSBjYWxsYmFjayhlcnIpIGNhbGxlZCBvbmNlIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLgogICAqLwogIGZ1bmN0aW9uIF9yZXNlZWQoY2FsbGJhY2spIHsKICAgIGlmKGN0eC5wb29sc1swXS5tZXNzYWdlTGVuZ3RoID49IDMyKSB7CiAgICAgIF9zZWVkKCk7CiAgICAgIHJldHVybiBjYWxsYmFjaygpOwogICAgfQogICAgLy8gbm90IGVub3VnaCBzZWVkIGRhdGEuLi4KICAgIHZhciBuZWVkZWQgPSAoMzIgLSBjdHgucG9vbHNbMF0ubWVzc2FnZUxlbmd0aCkgPDwgNTsKICAgIGN0eC5zZWVkRmlsZShuZWVkZWQsIGZ1bmN0aW9uKGVyciwgYnl0ZXMpIHsKICAgICAgaWYoZXJyKSB7CiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7CiAgICAgIH0KICAgICAgY3R4LmNvbGxlY3QoYnl0ZXMpOwogICAgICBfc2VlZCgpOwogICAgICBjYWxsYmFjaygpOwogICAgfSk7CiAgfQoKICAvKioKICAgKiBQcml2YXRlIGZ1bmN0aW9uIHRoYXQgc3luY2hyb25vdXNseSByZXNlZWRzIGEgZ2VuZXJhdG9yLgogICAqLwogIGZ1bmN0aW9uIF9yZXNlZWRTeW5jKCkgewogICAgaWYoY3R4LnBvb2xzWzBdLm1lc3NhZ2VMZW5ndGggPj0gMzIpIHsKICAgICAgcmV0dXJuIF9zZWVkKCk7CiAgICB9CiAgICAvLyBub3QgZW5vdWdoIHNlZWQgZGF0YS4uLgogICAgdmFyIG5lZWRlZCA9ICgzMiAtIGN0eC5wb29sc1swXS5tZXNzYWdlTGVuZ3RoKSA8PCA1OwogICAgY3R4LmNvbGxlY3QoY3R4LnNlZWRGaWxlU3luYyhuZWVkZWQpKTsKICAgIF9zZWVkKCk7CiAgfQoKICAvKioKICAgKiBQcml2YXRlIGZ1bmN0aW9uIHRoYXQgc2VlZHMgYSBnZW5lcmF0b3Igb25jZSBlbm91Z2ggYnl0ZXMgYXJlIGF2YWlsYWJsZS4KICAgKi8KICBmdW5jdGlvbiBfc2VlZCgpIHsKICAgIC8vIGNyZWF0ZSBhIHBsdWdpbi1iYXNlZCBtZXNzYWdlIGRpZ2VzdAogICAgdmFyIG1kID0gY3R4LnBsdWdpbi5tZC5jcmVhdGUoKTsKCiAgICAvLyBkaWdlc3QgcG9vbCAwJ3MgZW50cm9weSBhbmQgcmVzdGFydCBpdAogICAgbWQudXBkYXRlKGN0eC5wb29sc1swXS5kaWdlc3QoKS5nZXRCeXRlcygpKTsKICAgIGN0eC5wb29sc1swXS5zdGFydCgpOwoKICAgIC8vIGRpZ2VzdCB0aGUgZW50cm9weSBvZiBvdGhlciBwb29scyB3aG9zZSBpbmRleCBrIG1lZXQgdGhlCiAgICAvLyBjb25kaXRpb24gJzJeayBtb2QgbiA9PSAwJyB3aGVyZSBuIGlzIHRoZSBudW1iZXIgb2YgcmVzZWVkcwogICAgdmFyIGsgPSAxOwogICAgZm9yKHZhciBpID0gMTsgaSA8IDMyOyArK2kpIHsKICAgICAgLy8gcHJldmVudCBzaWduZWQgbnVtYmVycyBmcm9tIGJlaW5nIHVzZWQKICAgICAgayA9IChrID09PSAzMSkgPyAweDgwMDAwMDAwIDogKGsgPDwgMik7CiAgICAgIGlmKGsgJSBjdHgucmVzZWVkcyA9PT0gMCkgewogICAgICAgIG1kLnVwZGF0ZShjdHgucG9vbHNbaV0uZGlnZXN0KCkuZ2V0Qnl0ZXMoKSk7CiAgICAgICAgY3R4LnBvb2xzW2ldLnN0YXJ0KCk7CiAgICAgIH0KICAgIH0KCiAgICAvLyBnZXQgZGlnZXN0IGZvciBrZXkgYnl0ZXMgYW5kIGl0ZXJhdGUgYWdhaW4gZm9yIHNlZWQgYnl0ZXMKICAgIHZhciBrZXlCeXRlcyA9IG1kLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CiAgICBtZC5zdGFydCgpOwogICAgbWQudXBkYXRlKGtleUJ5dGVzKTsKICAgIHZhciBzZWVkQnl0ZXMgPSBtZC5kaWdlc3QoKS5nZXRCeXRlcygpOwoKICAgIC8vIHVwZGF0ZQogICAgY3R4LmtleSA9IGN0eC5wbHVnaW4uZm9ybWF0S2V5KGtleUJ5dGVzKTsKICAgIGN0eC5zZWVkID0gY3R4LnBsdWdpbi5mb3JtYXRTZWVkKHNlZWRCeXRlcyk7CiAgICBjdHgucmVzZWVkcyA9IChjdHgucmVzZWVkcyA9PT0gMHhmZmZmZmZmZikgPyAwIDogY3R4LnJlc2VlZHMgKyAxOwogICAgY3R4LmdlbmVyYXRlZCA9IDA7CiAgfQoKICAvKioKICAgKiBUaGUgYnVpbHQtaW4gZGVmYXVsdCBzZWVkRmlsZS4gVGhpcyBzZWVkRmlsZSBpcyB1c2VkIHdoZW4gZW50cm9weQogICAqIGlzIG5lZWRlZCBpbW1lZGlhdGVseS4KICAgKgogICAqIEBwYXJhbSBuZWVkZWQgdGhlIG51bWJlciBvZiBieXRlcyB0aGF0IGFyZSBuZWVkZWQuCiAgICoKICAgKiBAcmV0dXJuIHRoZSByYW5kb20gYnl0ZXMuCiAgICovCiAgZnVuY3Rpb24gZGVmYXVsdFNlZWRGaWxlKG5lZWRlZCkgewogICAgLy8gdXNlIHdpbmRvdy5jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzIHN0cm9uZyBzb3VyY2Ugb2YgZW50cm9weSBpZiBhdmFpbGFibGUKICAgIHZhciBnZXRSYW5kb21WYWx1ZXMgPSBudWxsOwogICAgaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgdmFyIF9jcnlwdG8gPSB3aW5kb3cuY3J5cHRvIHx8IHdpbmRvdy5tc0NyeXB0bzsKICAgICAgaWYoX2NyeXB0byAmJiBfY3J5cHRvLmdldFJhbmRvbVZhbHVlcykgewogICAgICAgIGdldFJhbmRvbVZhbHVlcyA9IGZ1bmN0aW9uKGFycikgewogICAgICAgICAgcmV0dXJuIF9jcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKGFycik7CiAgICAgICAgfTsKICAgICAgfQogICAgfQoKICAgIHZhciBiID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGlmKGdldFJhbmRvbVZhbHVlcykgewogICAgICB3aGlsZShiLmxlbmd0aCgpIDwgbmVlZGVkKSB7CiAgICAgICAgLy8gbWF4IGJ5dGUgbGVuZ3RoIGlzIDY1NTM2IGJlZm9yZSBRdW90YUV4Y2VlZGVkRXJyb3IgaXMgdGhyb3duCiAgICAgICAgLy8gaHR0cDovL3d3dy53My5vcmcvVFIvV2ViQ3J5cHRvQVBJLyNSYW5kb21Tb3VyY2UtbWV0aG9kLWdldFJhbmRvbVZhbHVlcwogICAgICAgIHZhciBjb3VudCA9IE1hdGgubWF4KDEsIE1hdGgubWluKG5lZWRlZCAtIGIubGVuZ3RoKCksIDY1NTM2KSAvIDQpOwogICAgICAgIHZhciBlbnRyb3B5ID0gbmV3IFVpbnQzMkFycmF5KE1hdGguZmxvb3IoY291bnQpKTsKICAgICAgICB0cnkgewogICAgICAgICAgZ2V0UmFuZG9tVmFsdWVzKGVudHJvcHkpOwogICAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGVudHJvcHkubGVuZ3RoOyArK2kpIHsKICAgICAgICAgICAgYi5wdXRJbnQzMihlbnRyb3B5W2ldKTsKICAgICAgICAgIH0KICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgIC8qIG9ubHkgaWdub3JlIFF1b3RhRXhjZWVkZWRFcnJvciAqLwogICAgICAgICAgaWYoISh0eXBlb2YgUXVvdGFFeGNlZWRlZEVycm9yICE9PSAndW5kZWZpbmVkJyAmJgogICAgICAgICAgICBlIGluc3RhbmNlb2YgUXVvdGFFeGNlZWRlZEVycm9yKSkgewogICAgICAgICAgICB0aHJvdyBlOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIC8vIGJlIHNhZCBhbmQgYWRkIHNvbWUgd2VhayByYW5kb20gZGF0YQogICAgaWYoYi5sZW5ndGgoKSA8IG5lZWRlZCkgewogICAgICAvKiBEcmF3cyBmcm9tIFBhcmstTWlsbGVyICJtaW5pbWFsIHN0YW5kYXJkIiAzMSBiaXQgUFJORywKICAgICAgaW1wbGVtZW50ZWQgd2l0aCBEYXZpZCBHLiBDYXJ0YSdzIG9wdGltaXphdGlvbjogd2l0aCAzMiBiaXQgbWF0aAogICAgICBhbmQgd2l0aG91dCBkaXZpc2lvbiAoUHVibGljIERvbWFpbikuICovCiAgICAgIHZhciBoaSwgbG8sIG5leHQ7CiAgICAgIHZhciBzZWVkID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMHgwMTAwMDApOwogICAgICB3aGlsZShiLmxlbmd0aCgpIDwgbmVlZGVkKSB7CiAgICAgICAgbG8gPSAxNjgwNyAqIChzZWVkICYgMHhGRkZGKTsKICAgICAgICBoaSA9IDE2ODA3ICogKHNlZWQgPj4gMTYpOwogICAgICAgIGxvICs9IChoaSAmIDB4N0ZGRikgPDwgMTY7CiAgICAgICAgbG8gKz0gaGkgPj4gMTU7CiAgICAgICAgbG8gPSAobG8gJiAweDdGRkZGRkZGKSArIChsbyA+PiAzMSk7CiAgICAgICAgc2VlZCA9IGxvICYgMHhGRkZGRkZGRjsKCiAgICAgICAgLy8gY29uc3VtZSBsb3dlciAzIGJ5dGVzIG9mIHNlZWQKICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgMzsgKytpKSB7CiAgICAgICAgICAvLyB0aHJvdyBpbiBtb3JlIHBzZXVkbyByYW5kb20KICAgICAgICAgIG5leHQgPSBzZWVkID4+PiAoaSA8PCAzKTsKICAgICAgICAgIG5leHQgXj0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMHgwMTAwKTsKICAgICAgICAgIGIucHV0Qnl0ZShTdHJpbmcuZnJvbUNoYXJDb2RlKG5leHQgJiAweEZGKSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgcmV0dXJuIGIuZ2V0Qnl0ZXMobmVlZGVkKTsKICB9CiAgLy8gaW5pdGlhbGl6ZSBzZWVkIGZpbGUgQVBJcwogIGlmKF9jcnlwdG8pIHsKICAgIC8vIHVzZSBub2RlanMgYXN5bmMgQVBJCiAgICBjdHguc2VlZEZpbGUgPSBmdW5jdGlvbihuZWVkZWQsIGNhbGxiYWNrKSB7CiAgICAgIF9jcnlwdG8ucmFuZG9tQnl0ZXMobmVlZGVkLCBmdW5jdGlvbihlcnIsIGJ5dGVzKSB7CiAgICAgICAgaWYoZXJyKSB7CiAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTsKICAgICAgICB9CiAgICAgICAgY2FsbGJhY2sobnVsbCwgYnl0ZXMudG9TdHJpbmcoKSk7CiAgICAgIH0pOwogICAgfTsKICAgIC8vIHVzZSBub2RlanMgc3luYyBBUEkKICAgIGN0eC5zZWVkRmlsZVN5bmMgPSBmdW5jdGlvbihuZWVkZWQpIHsKICAgICAgcmV0dXJuIF9jcnlwdG8ucmFuZG9tQnl0ZXMobmVlZGVkKS50b1N0cmluZygpOwogICAgfTsKICB9IGVsc2UgewogICAgY3R4LnNlZWRGaWxlID0gZnVuY3Rpb24obmVlZGVkLCBjYWxsYmFjaykgewogICAgICB0cnkgewogICAgICAgIGNhbGxiYWNrKG51bGwsIGRlZmF1bHRTZWVkRmlsZShuZWVkZWQpKTsKICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgY2FsbGJhY2soZSk7CiAgICAgIH0KICAgIH07CiAgICBjdHguc2VlZEZpbGVTeW5jID0gZGVmYXVsdFNlZWRGaWxlOwogIH0KCiAgLyoqCiAgICogQWRkcyBlbnRyb3B5IHRvIGEgcHJuZyBjdHgncyBhY2N1bXVsYXRvci4KICAgKgogICAqIEBwYXJhbSBieXRlcyB0aGUgYnl0ZXMgb2YgZW50cm9weSBhcyBhIHN0cmluZy4KICAgKi8KICBjdHguY29sbGVjdCA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgICAvLyBpdGVyYXRlIG92ZXIgcG9vbHMgZGlzdHJpYnV0aW5nIGVudHJvcHkgY3ljbGljYWxseQogICAgdmFyIGNvdW50ID0gYnl0ZXMubGVuZ3RoOwogICAgZm9yKHZhciBpID0gMDsgaSA8IGNvdW50OyArK2kpIHsKICAgICAgY3R4LnBvb2xzW2N0eC5wb29sXS51cGRhdGUoYnl0ZXMuc3Vic3RyKGksIDEpKTsKICAgICAgY3R4LnBvb2wgPSAoY3R4LnBvb2wgPT09IDMxKSA/IDAgOiBjdHgucG9vbCArIDE7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogQ29sbGVjdHMgYW4gaW50ZWdlciBvZiBuIGJpdHMuCiAgICoKICAgKiBAcGFyYW0gaSB0aGUgaW50ZWdlciBlbnRyb3B5LgogICAqIEBwYXJhbSBuIHRoZSBudW1iZXIgb2YgYml0cyBpbiB0aGUgaW50ZWdlci4KICAgKi8KICBjdHguY29sbGVjdEludCA9IGZ1bmN0aW9uKGksIG4pIHsKICAgIHZhciBieXRlcyA9ICcnOwogICAgZm9yKHZhciB4ID0gMDsgeCA8IG47IHggKz0gOCkgewogICAgICBieXRlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChpID4+IHgpICYgMHhGRik7CiAgICB9CiAgICBjdHguY29sbGVjdChieXRlcyk7CiAgfTsKCiAgLyoqCiAgICogUmVnaXN0ZXJzIGEgV2ViIFdvcmtlciB0byByZWNlaXZlIGltbWVkaWF0ZSBlbnRyb3B5IGZyb20gdGhlIG1haW4gdGhyZWFkLgogICAqIFRoaXMgbWV0aG9kIGlzIHJlcXVpcmVkIHVudGlsIFdlYiBXb3JrZXJzIGNhbiBhY2Nlc3MgdGhlIG5hdGl2ZSBjcnlwdG8KICAgKiBBUEkuIFRoaXMgbWV0aG9kIHNob3VsZCBiZSBjYWxsZWQgdHdpY2UgZm9yIGVhY2ggY3JlYXRlZCB3b3JrZXIsIG9uY2UgaW4KICAgKiB0aGUgbWFpbiB0aHJlYWQsIGFuZCBvbmNlIGluIHRoZSB3b3JrZXIgaXRzZWxmLgogICAqCiAgICogQHBhcmFtIHdvcmtlciB0aGUgd29ya2VyIHRvIHJlZ2lzdGVyLgogICAqLwogIGN0eC5yZWdpc3RlcldvcmtlciA9IGZ1bmN0aW9uKHdvcmtlcikgewogICAgLy8gd29ya2VyIHJlY2VpdmVzIHJhbmRvbSBieXRlcwogICAgaWYod29ya2VyID09PSBzZWxmKSB7CiAgICAgIGN0eC5zZWVkRmlsZSA9IGZ1bmN0aW9uKG5lZWRlZCwgY2FsbGJhY2spIHsKICAgICAgICBmdW5jdGlvbiBsaXN0ZW5lcihlKSB7CiAgICAgICAgICB2YXIgZGF0YSA9IGUuZGF0YTsKICAgICAgICAgIGlmKGRhdGEuZm9yZ2UgJiYgZGF0YS5mb3JnZS5wcm5nKSB7CiAgICAgICAgICAgIHNlbGYucmVtb3ZlRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIGxpc3RlbmVyKTsKICAgICAgICAgICAgY2FsbGJhY2soZGF0YS5mb3JnZS5wcm5nLmVyciwgZGF0YS5mb3JnZS5wcm5nLmJ5dGVzKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc2VsZi5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuZXIpOwogICAgICAgIHNlbGYucG9zdE1lc3NhZ2Uoe2ZvcmdlOiB7cHJuZzoge25lZWRlZDogbmVlZGVkfX19KTsKICAgICAgfTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIG1haW4gdGhyZWFkIHNlbmRzIHJhbmRvbSBieXRlcyB1cG9uIHJlcXVlc3QKICAgICAgdmFyIGxpc3RlbmVyID0gZnVuY3Rpb24oZSkgewogICAgICAgIHZhciBkYXRhID0gZS5kYXRhOwogICAgICAgIGlmKGRhdGEuZm9yZ2UgJiYgZGF0YS5mb3JnZS5wcm5nKSB7CiAgICAgICAgICBjdHguc2VlZEZpbGUoZGF0YS5mb3JnZS5wcm5nLm5lZWRlZCwgZnVuY3Rpb24oZXJyLCBieXRlcykgewogICAgICAgICAgICB3b3JrZXIucG9zdE1lc3NhZ2Uoe2ZvcmdlOiB7cHJuZzoge2VycjogZXJyLCBieXRlczogYnl0ZXN9fX0pOwogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9OwogICAgICAvLyBUT0RPOiBkbyB3ZSBuZWVkIHRvIHJlbW92ZSB0aGUgZXZlbnQgbGlzdGVuZXIgd2hlbiB0aGUgd29ya2VyIGRpZXM/CiAgICAgIHdvcmtlci5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuZXIpOwogICAgfQogIH07CgogIHJldHVybiBjdHg7Cn07Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdwcm5nJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3BybmcnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9tZCcsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cgp9KSgpOwoKLyoqCiAqIEFuIEFQSSBmb3IgZ2V0dGluZyBjcnlwdG9ncmFwaGljYWxseS1zZWN1cmUgcmFuZG9tIGJ5dGVzLiBUaGUgYnl0ZXMgYXJlCiAqIGdlbmVyYXRlZCB1c2luZyB0aGUgRm9ydHVuYSBhbGdvcml0aG0gZGV2aXNlZCBieSBCcnVjZSBTY2huZWllciBhbmQKICogTmllbHMgRmVyZ3Vzb24uCiAqCiAqIEdldHRpbmcgc3Ryb25nIHJhbmRvbSBieXRlcyBpcyBub3QgeWV0IGVhc3kgdG8gZG8gaW4gamF2YXNjcmlwdC4gVGhlIG9ubHkKICogdHJ1aXNoIHJhbmRvbSBlbnRyb3B5IHRoYXQgY2FuIGJlIGNvbGxlY3RlZCBpcyBmcm9tIHRoZSBtb3VzZSwga2V5Ym9hcmQsIG9yCiAqIGZyb20gdGltaW5nIHdpdGggcmVzcGVjdCB0byBwYWdlIGxvYWRzLCBldGMuIFRoaXMgZ2VuZXJhdG9yIG1ha2VzIGEgcG9vcgogKiBhdHRlbXB0IGF0IHByb3ZpZGluZyByYW5kb20gYnl0ZXMgd2hlbiB0aG9zZSBzb3VyY2VzIGhhdmVuJ3QgeWV0IHByb3ZpZGVkCiAqIGVub3VnaCBlbnRyb3B5IHRvIGluaXRpYWxseSBzZWVkIG9yIHRvIHJlc2VlZCB0aGUgUFJORy4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDA5LTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBmb3JnZS5yYW5kb20gYWxyZWFkeSBkZWZpbmVkCmlmKGZvcmdlLnJhbmRvbSAmJiBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMpIHsKICByZXR1cm47Cn0KCihmdW5jdGlvbihqUXVlcnkpIHsKCi8vIHRoZSBkZWZhdWx0IHBybmcgcGx1Z2luLCB1c2VzIEFFUy0xMjgKdmFyIHBybmdfYWVzID0ge307CnZhciBfcHJuZ19hZXNfb3V0cHV0ID0gbmV3IEFycmF5KDQpOwp2YXIgX3BybmdfYWVzX2J1ZmZlciA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CnBybmdfYWVzLmZvcm1hdEtleSA9IGZ1bmN0aW9uKGtleSkgewogIC8vIGNvbnZlcnQgdGhlIGtleSBpbnRvIDMyLWJpdCBpbnRlZ2VycwogIHZhciB0bXAgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihrZXkpOwogIGtleSA9IG5ldyBBcnJheSg0KTsKICBrZXlbMF0gPSB0bXAuZ2V0SW50MzIoKTsKICBrZXlbMV0gPSB0bXAuZ2V0SW50MzIoKTsKICBrZXlbMl0gPSB0bXAuZ2V0SW50MzIoKTsKICBrZXlbM10gPSB0bXAuZ2V0SW50MzIoKTsKCiAgLy8gcmV0dXJuIHRoZSBleHBhbmRlZCBrZXkKICByZXR1cm4gZm9yZ2UuYWVzLl9leHBhbmRLZXkoa2V5LCBmYWxzZSk7Cn07CnBybmdfYWVzLmZvcm1hdFNlZWQgPSBmdW5jdGlvbihzZWVkKSB7CiAgLy8gY29udmVydCBzZWVkIGludG8gMzItYml0IGludGVnZXJzCiAgdmFyIHRtcCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKHNlZWQpOwogIHNlZWQgPSBuZXcgQXJyYXkoNCk7CiAgc2VlZFswXSA9IHRtcC5nZXRJbnQzMigpOwogIHNlZWRbMV0gPSB0bXAuZ2V0SW50MzIoKTsKICBzZWVkWzJdID0gdG1wLmdldEludDMyKCk7CiAgc2VlZFszXSA9IHRtcC5nZXRJbnQzMigpOwogIHJldHVybiBzZWVkOwp9Owpwcm5nX2Flcy5jaXBoZXIgPSBmdW5jdGlvbihrZXksIHNlZWQpIHsKICBmb3JnZS5hZXMuX3VwZGF0ZUJsb2NrKGtleSwgc2VlZCwgX3BybmdfYWVzX291dHB1dCwgZmFsc2UpOwogIF9wcm5nX2Flc19idWZmZXIucHV0SW50MzIoX3BybmdfYWVzX291dHB1dFswXSk7CiAgX3BybmdfYWVzX2J1ZmZlci5wdXRJbnQzMihfcHJuZ19hZXNfb3V0cHV0WzFdKTsKICBfcHJuZ19hZXNfYnVmZmVyLnB1dEludDMyKF9wcm5nX2Flc19vdXRwdXRbMl0pOwogIF9wcm5nX2Flc19idWZmZXIucHV0SW50MzIoX3BybmdfYWVzX291dHB1dFszXSk7CiAgcmV0dXJuIF9wcm5nX2Flc19idWZmZXIuZ2V0Qnl0ZXMoKTsKfTsKcHJuZ19hZXMuaW5jcmVtZW50ID0gZnVuY3Rpb24oc2VlZCkgewogIC8vIEZJWE1FOiBkbyB3ZSBjYXJlIGFib3V0IGNhcnJ5IG9yIHNpZ25lZCBpc3N1ZXM/CiAgKytzZWVkWzNdOwogIHJldHVybiBzZWVkOwp9Owpwcm5nX2Flcy5tZCA9IGZvcmdlLm1kLnNoYTI1NjsKCi8qKgogKiBDcmVhdGVzIGEgbmV3IFBSTkcuCiAqLwpmdW5jdGlvbiBzcGF3blBybmcoKSB7CiAgdmFyIGN0eCA9IGZvcmdlLnBybmcuY3JlYXRlKHBybmdfYWVzKTsKCiAgLyoqCiAgICogR2V0cyByYW5kb20gYnl0ZXMuIElmIGEgbmF0aXZlIHNlY3VyZSBjcnlwdG8gQVBJIGlzIHVuYXZhaWxhYmxlLCB0aGlzCiAgICogbWV0aG9kIHRyaWVzIHRvIG1ha2UgdGhlIGJ5dGVzIG1vcmUgdW5wcmVkaWN0YWJsZSBieSBkcmF3aW5nIGZyb20gZGF0YSB0aGF0CiAgICogY2FuIGJlIGNvbGxlY3RlZCBmcm9tIHRoZSB1c2VyIG9mIHRoZSBicm93c2VyLCBlZzogbW91c2UgbW92ZW1lbnQuCiAgICoKICAgKiBJZiBhIGNhbGxiYWNrIGlzIGdpdmVuLCB0aGlzIG1ldGhvZCB3aWxsIGJlIGNhbGxlZCBhc3luY2hyb25vdXNseS4KICAgKgogICAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIHJhbmRvbSBieXRlcyB0byBnZXQuCiAgICogQHBhcmFtIFtjYWxsYmFjayhlcnIsIGJ5dGVzKV0gY2FsbGVkIG9uY2UgdGhlIG9wZXJhdGlvbiBjb21wbGV0ZXMuCiAgICoKICAgKiBAcmV0dXJuIHRoZSByYW5kb20gYnl0ZXMgaW4gYSBzdHJpbmcuCiAgICovCiAgY3R4LmdldEJ5dGVzID0gZnVuY3Rpb24oY291bnQsIGNhbGxiYWNrKSB7CiAgICByZXR1cm4gY3R4LmdlbmVyYXRlKGNvdW50LCBjYWxsYmFjayk7CiAgfTsKCiAgLyoqCiAgICogR2V0cyByYW5kb20gYnl0ZXMgYXN5bmNocm9ub3VzbHkuIElmIGEgbmF0aXZlIHNlY3VyZSBjcnlwdG8gQVBJIGlzCiAgICogdW5hdmFpbGFibGUsIHRoaXMgbWV0aG9kIHRyaWVzIHRvIG1ha2UgdGhlIGJ5dGVzIG1vcmUgdW5wcmVkaWN0YWJsZSBieQogICAqIGRyYXdpbmcgZnJvbSBkYXRhIHRoYXQgY2FuIGJlIGNvbGxlY3RlZCBmcm9tIHRoZSB1c2VyIG9mIHRoZSBicm93c2VyLAogICAqIGVnOiBtb3VzZSBtb3ZlbWVudC4KICAgKgogICAqIEBwYXJhbSBjb3VudCB0aGUgbnVtYmVyIG9mIHJhbmRvbSBieXRlcyB0byBnZXQuCiAgICoKICAgKiBAcmV0dXJuIHRoZSByYW5kb20gYnl0ZXMgaW4gYSBzdHJpbmcuCiAgICovCiAgY3R4LmdldEJ5dGVzU3luYyA9IGZ1bmN0aW9uKGNvdW50KSB7CiAgICByZXR1cm4gY3R4LmdlbmVyYXRlKGNvdW50KTsKICB9OwoKICByZXR1cm4gY3R4Owp9CgovLyBjcmVhdGUgZGVmYXVsdCBwcm5nIGNvbnRleHQKdmFyIF9jdHggPSBzcGF3blBybmcoKTsKCi8vIGFkZCBvdGhlciBzb3VyY2VzIG9mIGVudHJvcHkgb25seSBpZiB3aW5kb3cuY3J5cHRvLmdldFJhbmRvbVZhbHVlcyBpcyBub3QKLy8gYXZhaWxhYmxlIC0tIG90aGVyd2lzZSB0aGlzIHNvdXJjZSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgdXNlZCBieSB0aGUgcHJuZwp2YXIgX25vZGVqcyA9ICgKICB0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvY2Vzcy52ZXJzaW9ucyAmJiBwcm9jZXNzLnZlcnNpb25zLm5vZGUpOwp2YXIgZ2V0UmFuZG9tVmFsdWVzID0gbnVsbDsKaWYodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHsKICB2YXIgX2NyeXB0byA9IHdpbmRvdy5jcnlwdG8gfHwgd2luZG93Lm1zQ3J5cHRvOwogIGlmKF9jcnlwdG8gJiYgX2NyeXB0by5nZXRSYW5kb21WYWx1ZXMpIHsKICAgIGdldFJhbmRvbVZhbHVlcyA9IGZ1bmN0aW9uKGFycikgewogICAgICByZXR1cm4gX2NyeXB0by5nZXRSYW5kb21WYWx1ZXMoYXJyKTsKICAgIH07CiAgfQp9CmlmKGZvcmdlLmRpc2FibGVOYXRpdmVDb2RlIHx8ICghX25vZGVqcyAmJiAhZ2V0UmFuZG9tVmFsdWVzKSkgewogIC8vIGlmIHRoaXMgaXMgYSB3ZWIgd29ya2VyLCBkbyBub3QgdXNlIHdlYWsgZW50cm9weSwgaW5zdGVhZCByZWdpc3RlciB0bwogIC8vIHJlY2VpdmUgc3Ryb25nIGVudHJvcHkgYXN5bmNocm9ub3VzbHkgZnJvbSB0aGUgbWFpbiB0aHJlYWQKICBpZih0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJyB8fCB3aW5kb3cuZG9jdW1lbnQgPT09IHVuZGVmaW5lZCkgewogICAgLy8gRklYTUU6CiAgfQoKICAvLyBnZXQgbG9hZCB0aW1lIGVudHJvcHkKICBfY3R4LmNvbGxlY3RJbnQoK25ldyBEYXRlKCksIDMyKTsKCiAgLy8gYWRkIHNvbWUgZW50cm9weSBmcm9tIG5hdmlnYXRvciBvYmplY3QKICBpZih0eXBlb2YobmF2aWdhdG9yKSAhPT0gJ3VuZGVmaW5lZCcpIHsKICAgIHZhciBfbmF2Qnl0ZXMgPSAnJzsKICAgIGZvcih2YXIga2V5IGluIG5hdmlnYXRvcikgewogICAgICB0cnkgewogICAgICAgIGlmKHR5cGVvZihuYXZpZ2F0b3Jba2V5XSkgPT0gJ3N0cmluZycpIHsKICAgICAgICAgIF9uYXZCeXRlcyArPSBuYXZpZ2F0b3Jba2V5XTsKICAgICAgICB9CiAgICAgIH0gY2F0Y2goZSkgewogICAgICAgIC8qIFNvbWUgbmF2aWdhdG9yIGtleXMgbWlnaHQgbm90IGJlIGFjY2Vzc2libGUsIGUuZy4gdGhlIGdlb2xvY2F0aW9uCiAgICAgICAgICBhdHRyaWJ1dGUgdGhyb3dzIGFuIGV4Y2VwdGlvbiBpZiB0b3VjaGVkIGluIE1vemlsbGEgY2hyb21lOi8vCiAgICAgICAgICBjb250ZXh0LgoKICAgICAgICAgIFNpbGVudGx5IGlnbm9yZSB0aGlzIGFuZCBqdXN0IGRvbid0IHVzZSB0aGlzIGFzIGEgc291cmNlIG9mCiAgICAgICAgICBlbnRyb3B5LiAqLwogICAgICB9CiAgICB9CiAgICBfY3R4LmNvbGxlY3QoX25hdkJ5dGVzKTsKICAgIF9uYXZCeXRlcyA9IG51bGw7CiAgfQoKICAvLyBhZGQgbW91c2UgYW5kIGtleWJvYXJkIGNvbGxlY3RvcnMgaWYganF1ZXJ5IGlzIGF2YWlsYWJsZQogIGlmKGpRdWVyeSkgewogICAgLy8gc2V0IHVwIG1vdXNlIGVudHJvcHkgY2FwdHVyZQogICAgalF1ZXJ5KCkubW91c2Vtb3ZlKGZ1bmN0aW9uKGUpIHsKICAgICAgLy8gYWRkIG1vdXNlIGNvb3JkcwogICAgICBfY3R4LmNvbGxlY3RJbnQoZS5jbGllbnRYLCAxNik7CiAgICAgIF9jdHguY29sbGVjdEludChlLmNsaWVudFksIDE2KTsKICAgIH0pOwoKICAgIC8vIHNldCB1cCBrZXlib2FyZCBlbnRyb3B5IGNhcHR1cmUKICAgIGpRdWVyeSgpLmtleXByZXNzKGZ1bmN0aW9uKGUpIHsKICAgICAgX2N0eC5jb2xsZWN0SW50KGUuY2hhckNvZGUsIDgpOwogICAgfSk7CiAgfQp9CgovKiBSYW5kb20gQVBJICovCmlmKCFmb3JnZS5yYW5kb20pIHsKICBmb3JnZS5yYW5kb20gPSBfY3R4Owp9IGVsc2UgewogIC8vIGV4dGVuZCBmb3JnZS5yYW5kb20gd2l0aCBfY3R4CiAgZm9yKHZhciBrZXkgaW4gX2N0eCkgewogICAgZm9yZ2UucmFuZG9tW2tleV0gPSBfY3R4W2tleV07CiAgfQp9CgovLyBleHBvc2Ugc3Bhd24gUFJORwpmb3JnZS5yYW5kb20uY3JlYXRlSW5zdGFuY2UgPSBzcGF3blBybmc7Cgp9KSh0eXBlb2YoalF1ZXJ5KSAhPT0gJ3VuZGVmaW5lZCcgPyBqUXVlcnkgOiBudWxsKTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3JhbmRvbSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9yYW5kb20nLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9hZXMnLCAnLi9tZCcsICcuL3BybmcnLCAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFJDMiBpbXBsZW1lbnRhdGlvbi4KICoKICogQGF1dGhvciBTdGVmYW4gU2llZ2wKICoKICogQ29weXJpZ2h0IChjKSAyMDEyIFN0ZWZhbiBTaWVnbCA8c3Rlc2llQGJyb2tlbnBpcGUuZGU+CiAqCiAqIEluZm9ybWF0aW9uIG9uIHRoZSBSQzIgY2lwaGVyIGlzIGF2YWlsYWJsZSBmcm9tIFJGQyAjMjI2OCwKICogaHR0cDovL3d3dy5pZXRmLm9yZy9yZmMvcmZjMjI2OC50eHQKICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7Cgp2YXIgcGlUYWJsZSA9IFsKICAweGQ5LCAweDc4LCAweGY5LCAweGM0LCAweDE5LCAweGRkLCAweGI1LCAweGVkLCAweDI4LCAweGU5LCAweGZkLCAweDc5LCAweDRhLCAweGEwLCAweGQ4LCAweDlkLAogIDB4YzYsIDB4N2UsIDB4MzcsIDB4ODMsIDB4MmIsIDB4NzYsIDB4NTMsIDB4OGUsIDB4NjIsIDB4NGMsIDB4NjQsIDB4ODgsIDB4NDQsIDB4OGIsIDB4ZmIsIDB4YTIsCiAgMHgxNywgMHg5YSwgMHg1OSwgMHhmNSwgMHg4NywgMHhiMywgMHg0ZiwgMHgxMywgMHg2MSwgMHg0NSwgMHg2ZCwgMHg4ZCwgMHgwOSwgMHg4MSwgMHg3ZCwgMHgzMiwKICAweGJkLCAweDhmLCAweDQwLCAweGViLCAweDg2LCAweGI3LCAweDdiLCAweDBiLCAweGYwLCAweDk1LCAweDIxLCAweDIyLCAweDVjLCAweDZiLCAweDRlLCAweDgyLAogIDB4NTQsIDB4ZDYsIDB4NjUsIDB4OTMsIDB4Y2UsIDB4NjAsIDB4YjIsIDB4MWMsIDB4NzMsIDB4NTYsIDB4YzAsIDB4MTQsIDB4YTcsIDB4OGMsIDB4ZjEsIDB4ZGMsCiAgMHgxMiwgMHg3NSwgMHhjYSwgMHgxZiwgMHgzYiwgMHhiZSwgMHhlNCwgMHhkMSwgMHg0MiwgMHgzZCwgMHhkNCwgMHgzMCwgMHhhMywgMHgzYywgMHhiNiwgMHgyNiwKICAweDZmLCAweGJmLCAweDBlLCAweGRhLCAweDQ2LCAweDY5LCAweDA3LCAweDU3LCAweDI3LCAweGYyLCAweDFkLCAweDliLCAweGJjLCAweDk0LCAweDQzLCAweDAzLAogIDB4ZjgsIDB4MTEsIDB4YzcsIDB4ZjYsIDB4OTAsIDB4ZWYsIDB4M2UsIDB4ZTcsIDB4MDYsIDB4YzMsIDB4ZDUsIDB4MmYsIDB4YzgsIDB4NjYsIDB4MWUsIDB4ZDcsCiAgMHgwOCwgMHhlOCwgMHhlYSwgMHhkZSwgMHg4MCwgMHg1MiwgMHhlZSwgMHhmNywgMHg4NCwgMHhhYSwgMHg3MiwgMHhhYywgMHgzNSwgMHg0ZCwgMHg2YSwgMHgyYSwKICAweDk2LCAweDFhLCAweGQyLCAweDcxLCAweDVhLCAweDE1LCAweDQ5LCAweDc0LCAweDRiLCAweDlmLCAweGQwLCAweDVlLCAweDA0LCAweDE4LCAweGE0LCAweGVjLAogIDB4YzIsIDB4ZTAsIDB4NDEsIDB4NmUsIDB4MGYsIDB4NTEsIDB4Y2IsIDB4Y2MsIDB4MjQsIDB4OTEsIDB4YWYsIDB4NTAsIDB4YTEsIDB4ZjQsIDB4NzAsIDB4MzksCiAgMHg5OSwgMHg3YywgMHgzYSwgMHg4NSwgMHgyMywgMHhiOCwgMHhiNCwgMHg3YSwgMHhmYywgMHgwMiwgMHgzNiwgMHg1YiwgMHgyNSwgMHg1NSwgMHg5NywgMHgzMSwKICAweDJkLCAweDVkLCAweGZhLCAweDk4LCAweGUzLCAweDhhLCAweDkyLCAweGFlLCAweDA1LCAweGRmLCAweDI5LCAweDEwLCAweDY3LCAweDZjLCAweGJhLCAweGM5LAogIDB4ZDMsIDB4MDAsIDB4ZTYsIDB4Y2YsIDB4ZTEsIDB4OWUsIDB4YTgsIDB4MmMsIDB4NjMsIDB4MTYsIDB4MDEsIDB4M2YsIDB4NTgsIDB4ZTIsIDB4ODksIDB4YTksCiAgMHgwZCwgMHgzOCwgMHgzNCwgMHgxYiwgMHhhYiwgMHgzMywgMHhmZiwgMHhiMCwgMHhiYiwgMHg0OCwgMHgwYywgMHg1ZiwgMHhiOSwgMHhiMSwgMHhjZCwgMHgyZSwKICAweGM1LCAweGYzLCAweGRiLCAweDQ3LCAweGU1LCAweGE1LCAweDljLCAweDc3LCAweDBhLCAweGE2LCAweDIwLCAweDY4LCAweGZlLCAweDdmLCAweGMxLCAweGFkCl07Cgp2YXIgcyA9IFsxLCAyLCAzLCA1XTsKCgovKioKICogUm90YXRlIGEgd29yZCBsZWZ0IGJ5IGdpdmVuIG51bWJlciBvZiBiaXRzLgogKgogKiBCaXRzIHRoYXQgYXJlIHNoaWZ0ZWQgb3V0IG9uIHRoZSBsZWZ0IGFyZSBwdXQgYmFjayBpbiBvbiB0aGUgcmlnaHQKICogaGFuZCBzaWRlLgogKgogKiBAcGFyYW0gd29yZCBUaGUgd29yZCB0byBzaGlmdCBsZWZ0LgogKiBAcGFyYW0gYml0cyBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnQgYnkuCiAqIEByZXR1cm4gVGhlIHJvdGF0ZWQgd29yZC4KICovCnZhciByb2wgPSBmdW5jdGlvbih3b3JkLCBiaXRzKSB7CiAgcmV0dXJuICgod29yZCA8PCBiaXRzKSAmIDB4ZmZmZikgfCAoKHdvcmQgJiAweGZmZmYpID4+ICgxNiAtIGJpdHMpKTsKfTsKCi8qKgogKiBSb3RhdGUgYSB3b3JkIHJpZ2h0IGJ5IGdpdmVuIG51bWJlciBvZiBiaXRzLgogKgogKiBCaXRzIHRoYXQgYXJlIHNoaWZ0ZWQgb3V0IG9uIHRoZSByaWdodCBhcmUgcHV0IGJhY2sgaW4gb24gdGhlIGxlZnQKICogaGFuZCBzaWRlLgogKgogKiBAcGFyYW0gd29yZCBUaGUgd29yZCB0byBzaGlmdCByaWdodC4KICogQHBhcmFtIGJpdHMgVGhlIG51bWJlciBvZiBiaXRzIHRvIHNoaWZ0IGJ5LgogKiBAcmV0dXJuIFRoZSByb3RhdGVkIHdvcmQuCiAqLwp2YXIgcm9yID0gZnVuY3Rpb24od29yZCwgYml0cykgewogIHJldHVybiAoKHdvcmQgJiAweGZmZmYpID4+IGJpdHMpIHwgKCh3b3JkIDw8ICgxNiAtIGJpdHMpKSAmIDB4ZmZmZik7Cn07CgoKLyogUkMyIEFQSSAqLwpmb3JnZS5yYzIgPSBmb3JnZS5yYzIgfHwge307CgovKioKICogUGVyZm9ybSBSQzIga2V5IGV4cGFuc2lvbiBhcyBwZXIgUkZDICMyMjY4LCBzZWN0aW9uIDIuCiAqCiAqIEBwYXJhbSBrZXkgdmFyaWFibGUtbGVuZ3RoIHVzZXIga2V5IChiZXR3ZWVuIDEgYW5kIDEyOCBieXRlcykKICogQHBhcmFtIGVmZktleUJpdHMgbnVtYmVyIG9mIGVmZmVjdGl2ZSBrZXkgYml0cyAoZGVmYXVsdDogMTI4KQogKiBAcmV0dXJuIHRoZSBleHBhbmRlZCBSQzIga2V5IChCeXRlQnVmZmVyIG9mIDEyOCBieXRlcykKICovCmZvcmdlLnJjMi5leHBhbmRLZXkgPSBmdW5jdGlvbihrZXksIGVmZktleUJpdHMpIHsKICBpZih0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykgewogICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoa2V5KTsKICB9CiAgZWZmS2V5Qml0cyA9IGVmZktleUJpdHMgfHwgMTI4OwoKICAvKiBpbnRyb2R1Y2UgdmFyaWFibGVzIHRoYXQgbWF0Y2ggdGhlIG5hbWVzIHVzZWQgaW4gUkZDICMyMjY4ICovCiAgdmFyIEwgPSBrZXk7CiAgdmFyIFQgPSBrZXkubGVuZ3RoKCk7CiAgdmFyIFQxID0gZWZmS2V5Qml0czsKICB2YXIgVDggPSBNYXRoLmNlaWwoVDEgLyA4KTsKICB2YXIgVE0gPSAweGZmID4+IChUMSAmIDB4MDcpOwogIHZhciBpOwoKICBmb3IoaSA9IFQ7IGkgPCAxMjg7IGkgKyspIHsKICAgIEwucHV0Qnl0ZShwaVRhYmxlWyhMLmF0KGkgLSAxKSArIEwuYXQoaSAtIFQpKSAmIDB4ZmZdKTsKICB9CgogIEwuc2V0QXQoMTI4IC0gVDgsIHBpVGFibGVbTC5hdCgxMjggLSBUOCkgJiBUTV0pOwoKICBmb3IoaSA9IDEyNyAtIFQ4OyBpID49IDA7IGkgLS0pIHsKICAgIEwuc2V0QXQoaSwgcGlUYWJsZVtMLmF0KGkgKyAxKSBeIEwuYXQoaSArIFQ4KV0pOwogIH0KCiAgcmV0dXJuIEw7Cn07CgoKLyoqCiAqIENyZWF0ZXMgYSBSQzIgY2lwaGVyIG9iamVjdC4KICoKICogQHBhcmFtIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UgKGFzIGJhc2UgZm9yIGtleSBnZW5lcmF0aW9uKS4KICogQHBhcmFtIGJpdHMgdGhlIG51bWJlciBvZiBlZmZlY3RpdmUga2V5IGJpdHMuCiAqIEBwYXJhbSBlbmNyeXB0IGZhbHNlIGZvciBkZWNyeXB0aW9uLCB0cnVlIGZvciBlbmNyeXB0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwp2YXIgY3JlYXRlQ2lwaGVyID0gZnVuY3Rpb24oa2V5LCBiaXRzLCBlbmNyeXB0KSB7CiAgdmFyIF9maW5pc2ggPSBmYWxzZSwgX2lucHV0ID0gbnVsbCwgX291dHB1dCA9IG51bGwsIF9pdiA9IG51bGw7CiAgdmFyIG1peFJvdW5kLCBtYXNoUm91bmQ7CiAgdmFyIGksIGosIEsgPSBbXTsKCiAgLyogRXhwYW5kIGtleSBhbmQgZmlsbCBpbnRvIEtbXSBBcnJheSAqLwogIGtleSA9IGZvcmdlLnJjMi5leHBhbmRLZXkoa2V5LCBiaXRzKTsKICBmb3IoaSA9IDA7IGkgPCA2NDsgaSArKykgewogICAgSy5wdXNoKGtleS5nZXRJbnQxNkxlKCkpOwogIH0KCiAgaWYoZW5jcnlwdCkgewogICAgLyoqCiAgICAgKiBQZXJmb3JtIG9uZSBtaXhpbmcgcm91bmQgImluIHBsYWNlIi4KICAgICAqCiAgICAgKiBAcGFyYW0gUiBBcnJheSBvZiBmb3VyIHdvcmRzIHRvIHBlcmZvcm0gbWl4aW5nIG9uLgogICAgICovCiAgICBtaXhSb3VuZCA9IGZ1bmN0aW9uKFIpIHsKICAgICAgZm9yKGkgPSAwOyBpIDwgNDsgaSsrKSB7CiAgICAgICAgUltpXSArPSBLW2pdICsgKFJbKGkgKyAzKSAlIDRdICYgUlsoaSArIDIpICUgNF0pICsKICAgICAgICAgICgoflJbKGkgKyAzKSAlIDRdKSAmIFJbKGkgKyAxKSAlIDRdKTsKICAgICAgICBSW2ldID0gcm9sKFJbaV0sIHNbaV0pOwogICAgICAgIGogKys7CiAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBQZXJmb3JtIG9uZSBtYXNoaW5nIHJvdW5kICJpbiBwbGFjZSIuCiAgICAgKgogICAgICogQHBhcmFtIFIgQXJyYXkgb2YgZm91ciB3b3JkcyB0byBwZXJmb3JtIG1hc2hpbmcgb24uCiAgICAgKi8KICAgIG1hc2hSb3VuZCA9IGZ1bmN0aW9uKFIpIHsKICAgICAgZm9yKGkgPSAwOyBpIDwgNDsgaSArKykgewogICAgICAgIFJbaV0gKz0gS1tSWyhpICsgMykgJSA0XSAmIDYzXTsKICAgICAgfQogICAgfTsKICB9IGVsc2UgewogICAgLyoqCiAgICAgKiBQZXJmb3JtIG9uZSByLW1peGluZyByb3VuZCAiaW4gcGxhY2UiLgogICAgICoKICAgICAqIEBwYXJhbSBSIEFycmF5IG9mIGZvdXIgd29yZHMgdG8gcGVyZm9ybSBtaXhpbmcgb24uCiAgICAgKi8KICAgIG1peFJvdW5kID0gZnVuY3Rpb24oUikgewogICAgICBmb3IoaSA9IDM7IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgUltpXSA9IHJvcihSW2ldLCBzW2ldKTsKICAgICAgICBSW2ldIC09IEtbal0gKyAoUlsoaSArIDMpICUgNF0gJiBSWyhpICsgMikgJSA0XSkgKwogICAgICAgICAgKCh+UlsoaSArIDMpICUgNF0pICYgUlsoaSArIDEpICUgNF0pOwogICAgICAgIGogLS07CiAgICAgIH0KICAgIH07CgogICAgLyoqCiAgICAgKiBQZXJmb3JtIG9uZSByLW1hc2hpbmcgcm91bmQgImluIHBsYWNlIi4KICAgICAqCiAgICAgKiBAcGFyYW0gUiBBcnJheSBvZiBmb3VyIHdvcmRzIHRvIHBlcmZvcm0gbWFzaGluZyBvbi4KICAgICAqLwogICAgbWFzaFJvdW5kID0gZnVuY3Rpb24oUikgewogICAgICBmb3IoaSA9IDM7IGkgPj0gMDsgaS0tKSB7CiAgICAgICAgUltpXSAtPSBLW1JbKGkgKyAzKSAlIDRdICYgNjNdOwogICAgICB9CiAgICB9OwogIH0KCiAgLyoqCiAgICogUnVuIHRoZSBzcGVjaWZpZWQgY2lwaGVyIGV4ZWN1dGlvbiBwbGFuLgogICAqCiAgICogVGhpcyBmdW5jdGlvbiB0YWtlcyBmb3VyIHdvcmRzIGZyb20gdGhlIGlucHV0IGJ1ZmZlciwgYXBwbGllcyB0aGUgSVYgb24KICAgKiBpdCAoaWYgcmVxdWVzdGVkKSBhbmQgcnVucyB0aGUgcHJvdmlkZWQgZXhlY3V0aW9uIHBsYW4uCiAgICoKICAgKiBUaGUgcGxhbiBtdXN0IGJlIHB1dCB0b2dldGhlciBpbiBmb3JtIG9mIGEgYXJyYXkgb2YgYXJyYXlzLiAgV2hlcmUgdGhlCiAgICogb3V0ZXIgb25lIGlzIHNpbXBseSBhIGxpc3Qgb2Ygc3RlcHMgdG8gcGVyZm9ybSBhbmQgdGhlIGlubmVyIG9uZSBuZWVkcwogICAqIHRvIGhhdmUgdHdvIGVsZW1lbnRzOiB0aGUgZmlyc3Qgb25lIHRlbGxpbmcgaG93IG1hbnkgcm91bmRzIHRvIHBlcmZvcm0sCiAgICogdGhlIHNlY29uZCBvbmUgdGVsbGluZyB3aGF0IHRvIGRvIChpLmUuIHRoZSBmdW5jdGlvbiB0byBjYWxsKS4KICAgKgogICAqIEBwYXJhbSB7QXJyYXl9IHBsYW4gVGhlIHBsYW4gdG8gZXhlY3V0ZS4KICAgKi8KICB2YXIgcnVuUGxhbiA9IGZ1bmN0aW9uKHBsYW4pIHsKICAgIHZhciBSID0gW107CgogICAgLyogR2V0IGRhdGEgZnJvbSBpbnB1dCBidWZmZXIgYW5kIGZpbGwgdGhlIGZvdXIgd29yZHMgaW50byBSICovCiAgICBmb3IoaSA9IDA7IGkgPCA0OyBpICsrKSB7CiAgICAgIHZhciB2YWwgPSBfaW5wdXQuZ2V0SW50MTZMZSgpOwoKICAgICAgaWYoX2l2ICE9PSBudWxsKSB7CiAgICAgICAgaWYoZW5jcnlwdCkgewogICAgICAgICAgLyogV2UncmUgZW5jcnlwdGluZywgYXBwbHkgdGhlIElWIGZpcnN0LiAqLwogICAgICAgICAgdmFsIF49IF9pdi5nZXRJbnQxNkxlKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8qIFdlJ3JlIGRlY3J5cHRpb24sIGtlZXAgY2lwaGVyIHRleHQgZm9yIG5leHQgYmxvY2suICovCiAgICAgICAgICBfaXYucHV0SW50MTZMZSh2YWwpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgUi5wdXNoKHZhbCAmIDB4ZmZmZik7CiAgICB9CgogICAgLyogUmVzZXQgZ2xvYmFsICJqIiB2YXJpYWJsZSBhcyBwZXIgc3BlYy4gKi8KICAgIGogPSBlbmNyeXB0ID8gMCA6IDYzOwoKICAgIC8qIFJ1biBleGVjdXRpb24gcGxhbi4gKi8KICAgIGZvcih2YXIgcHRyID0gMDsgcHRyIDwgcGxhbi5sZW5ndGg7IHB0ciArKykgewogICAgICBmb3IodmFyIGN0ciA9IDA7IGN0ciA8IHBsYW5bcHRyXVswXTsgY3RyICsrKSB7CiAgICAgICAgcGxhbltwdHJdWzFdKFIpOwogICAgICB9CiAgICB9CgogICAgLyogV3JpdGUgYmFjayByZXN1bHQgdG8gb3V0cHV0IGJ1ZmZlci4gKi8KICAgIGZvcihpID0gMDsgaSA8IDQ7IGkgKyspIHsKICAgICAgaWYoX2l2ICE9PSBudWxsKSB7CiAgICAgICAgaWYoZW5jcnlwdCkgewogICAgICAgICAgLyogV2UncmUgZW5jcnlwdGluZyBpbiBDQkMtbW9kZSwgZmVlZCBiYWNrIGVuY3J5cHRlZCBieXRlcyBpbnRvCiAgICAgICAgICAgICBJViBidWZmZXIgdG8gY2FycnkgaXQgZm9yd2FyZCB0byBuZXh0IGJsb2NrLiAqLwogICAgICAgICAgX2l2LnB1dEludDE2TGUoUltpXSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIFJbaV0gXj0gX2l2LmdldEludDE2TGUoKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIF9vdXRwdXQucHV0SW50MTZMZShSW2ldKTsKICAgIH0KICB9OwoKCiAgLyogQ3JlYXRlIGNpcGhlciBvYmplY3QgKi8KICB2YXIgY2lwaGVyID0gbnVsbDsKICBjaXBoZXIgPSB7CiAgICAvKioKICAgICAqIFN0YXJ0cyBvciByZXN0YXJ0cyB0aGUgZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uIHByb2Nlc3MsIHdoaWNoZXZlcgogICAgICogd2FzIHByZXZpb3VzbHkgY29uZmlndXJlZC4KICAgICAqCiAgICAgKiBUbyB1c2UgdGhlIGNpcGhlciBpbiBDQkMgbW9kZSwgaXYgbWF5IGJlIGdpdmVuIGVpdGhlciBhcyBhIHN0cmluZwogICAgICogb2YgYnl0ZXMsIG9yIGFzIGEgYnl0ZSBidWZmZXIuICBGb3IgRUNCIG1vZGUsIGdpdmUgbnVsbCBhcyBpdi4KICAgICAqCiAgICAgKiBAcGFyYW0gaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UsIG51bGwgZm9yIEVDQiBtb2RlLgogICAgICogQHBhcmFtIG91dHB1dCB0aGUgb3V0cHV0IHRoZSBidWZmZXIgdG8gd3JpdGUgdG8sIG51bGwgdG8gY3JlYXRlIG9uZS4KICAgICAqLwogICAgc3RhcnQ6IGZ1bmN0aW9uKGl2LCBvdXRwdXQpIHsKICAgICAgaWYoaXYpIHsKICAgICAgICAvKiBDQkMgbW9kZSAqLwogICAgICAgIGlmKHR5cGVvZiBpdiA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgIGl2ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoaXYpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgX2ZpbmlzaCA9IGZhbHNlOwogICAgICBfaW5wdXQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgICBfb3V0cHV0ID0gb3V0cHV0IHx8IG5ldyBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgICBfaXYgPSBpdjsKCiAgICAgIGNpcGhlci5vdXRwdXQgPSBfb3V0cHV0OwogICAgfSwKCiAgICAvKioKICAgICAqIFVwZGF0ZXMgdGhlIG5leHQgYmxvY2suCiAgICAgKgogICAgICogQHBhcmFtIGlucHV0IHRoZSBidWZmZXIgdG8gcmVhZCBmcm9tLgogICAgICovCiAgICB1cGRhdGU6IGZ1bmN0aW9uKGlucHV0KSB7CiAgICAgIGlmKCFfZmluaXNoKSB7CiAgICAgICAgLy8gbm90IGZpbmlzaGluZywgc28gZmlsbCB0aGUgaW5wdXQgYnVmZmVyIHdpdGggbW9yZSBpbnB1dAogICAgICAgIF9pbnB1dC5wdXRCdWZmZXIoaW5wdXQpOwogICAgICB9CgogICAgICB3aGlsZShfaW5wdXQubGVuZ3RoKCkgPj0gOCkgewogICAgICAgIHJ1blBsYW4oWwogICAgICAgICAgICBbIDUsIG1peFJvdW5kIF0sCiAgICAgICAgICAgIFsgMSwgbWFzaFJvdW5kIF0sCiAgICAgICAgICAgIFsgNiwgbWl4Um91bmQgXSwKICAgICAgICAgICAgWyAxLCBtYXNoUm91bmQgXSwKICAgICAgICAgICAgWyA1LCBtaXhSb3VuZCBdCiAgICAgICAgICBdKTsKICAgICAgfQogICAgfSwKCiAgICAvKioKICAgICAqIEZpbmlzaGVzIGVuY3J5cHRpbmcgb3IgZGVjcnlwdGluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gcGFkIGEgcGFkZGluZyBmdW5jdGlvbiB0byB1c2UsIG51bGwgZm9yIFBLQ1MjNyBwYWRkaW5nLAogICAgICogICAgICAgICAgIHNpZ25hdHVyZShibG9ja1NpemUsIGJ1ZmZlciwgZGVjcnlwdCkuCiAgICAgKgogICAgICogQHJldHVybiB0cnVlIGlmIHN1Y2Nlc3NmdWwsIGZhbHNlIG9uIGVycm9yLgogICAgICovCiAgICBmaW5pc2g6IGZ1bmN0aW9uKHBhZCkgewogICAgICB2YXIgcnZhbCA9IHRydWU7CgogICAgICBpZihlbmNyeXB0KSB7CiAgICAgICAgaWYocGFkKSB7CiAgICAgICAgICBydmFsID0gcGFkKDgsIF9pbnB1dCwgIWVuY3J5cHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBhZGQgUEtDUyM3IHBhZGRpbmcgdG8gYmxvY2sgKGVhY2ggcGFkIGJ5dGUgaXMgdGhlCiAgICAgICAgICAvLyB2YWx1ZSBvZiB0aGUgbnVtYmVyIG9mIHBhZCBieXRlcykKICAgICAgICAgIHZhciBwYWRkaW5nID0gKF9pbnB1dC5sZW5ndGgoKSA9PT0gOCkgPyA4IDogKDggLSBfaW5wdXQubGVuZ3RoKCkpOwogICAgICAgICAgX2lucHV0LmZpbGxXaXRoQnl0ZShwYWRkaW5nLCBwYWRkaW5nKTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmKHJ2YWwpIHsKICAgICAgICAvLyBkbyBmaW5hbCB1cGRhdGUKICAgICAgICBfZmluaXNoID0gdHJ1ZTsKICAgICAgICBjaXBoZXIudXBkYXRlKCk7CiAgICAgIH0KCiAgICAgIGlmKCFlbmNyeXB0KSB7CiAgICAgICAgLy8gY2hlY2sgZm9yIGVycm9yOiBpbnB1dCBkYXRhIG5vdCBhIG11bHRpcGxlIG9mIGJsb2NrIHNpemUKICAgICAgICBydmFsID0gKF9pbnB1dC5sZW5ndGgoKSA9PT0gMCk7CiAgICAgICAgaWYocnZhbCkgewogICAgICAgICAgaWYocGFkKSB7CiAgICAgICAgICAgIHJ2YWwgPSBwYWQoOCwgX291dHB1dCwgIWVuY3J5cHQpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gZW5zdXJlIHBhZGRpbmcgYnl0ZSBjb3VudCBpcyB2YWxpZAogICAgICAgICAgICB2YXIgbGVuID0gX291dHB1dC5sZW5ndGgoKTsKICAgICAgICAgICAgdmFyIGNvdW50ID0gX291dHB1dC5hdChsZW4gLSAxKTsKCiAgICAgICAgICAgIGlmKGNvdW50ID4gbGVuKSB7CiAgICAgICAgICAgICAgcnZhbCA9IGZhbHNlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIC8vIHRyaW0gb2ZmIHBhZGRpbmcgYnl0ZXMKICAgICAgICAgICAgICBfb3V0cHV0LnRydW5jYXRlKGNvdW50KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgcmV0dXJuIHJ2YWw7CiAgICB9CiAgfTsKCiAgcmV0dXJuIGNpcGhlcjsKfTsKCgovKioKICogQ3JlYXRlcyBhbiBSQzIgY2lwaGVyIG9iamVjdCB0byBlbmNyeXB0IGRhdGEgaW4gRUNCIG9yIENCQyBtb2RlIHVzaW5nIHRoZQogKiBnaXZlbiBzeW1tZXRyaWMga2V5LiBUaGUgb3V0cHV0IHdpbGwgYmUgc3RvcmVkIGluIHRoZSAnb3V0cHV0JyBtZW1iZXIKICogb2YgdGhlIHJldHVybmVkIGNpcGhlci4KICoKICogVGhlIGtleSBhbmQgaXYgbWF5IGJlIGdpdmVuIGFzIGEgc3RyaW5nIG9mIGJ5dGVzIG9yIGEgYnl0ZSBidWZmZXIuCiAqIFRoZSBjaXBoZXIgaXMgaW5pdGlhbGl6ZWQgdG8gdXNlIDEyOCBlZmZlY3RpdmUga2V5IGJpdHMuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKiBAcGFyYW0gaXYgdGhlIGluaXRpYWxpemF0aW9uIHZlY3RvciB0byB1c2UuCiAqIEBwYXJhbSBvdXRwdXQgdGhlIGJ1ZmZlciB0byB3cml0ZSB0bywgbnVsbCB0byBjcmVhdGUgb25lLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwpmb3JnZS5yYzIuc3RhcnRFbmNyeXB0aW5nID0gZnVuY3Rpb24oa2V5LCBpdiwgb3V0cHV0KSB7CiAgdmFyIGNpcGhlciA9IGZvcmdlLnJjMi5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyKGtleSwgMTI4KTsKICBjaXBoZXIuc3RhcnQoaXYsIG91dHB1dCk7CiAgcmV0dXJuIGNpcGhlcjsKfTsKCi8qKgogKiBDcmVhdGVzIGFuIFJDMiBjaXBoZXIgb2JqZWN0IHRvIGVuY3J5cHQgZGF0YSBpbiBFQ0Igb3IgQ0JDIG1vZGUgdXNpbmcgdGhlCiAqIGdpdmVuIHN5bW1ldHJpYyBrZXkuCiAqCiAqIFRoZSBrZXkgbWF5IGJlIGdpdmVuIGFzIGEgc3RyaW5nIG9mIGJ5dGVzIG9yIGEgYnl0ZSBidWZmZXIuCiAqCiAqIFRvIHN0YXJ0IGVuY3J5cHRpbmcgY2FsbCBzdGFydCgpIG9uIHRoZSBjaXBoZXIgd2l0aCBhbiBpdiBhbmQgb3B0aW9uYWwKICogb3V0cHV0IGJ1ZmZlci4KICoKICogQHBhcmFtIGtleSB0aGUgc3ltbWV0cmljIGtleSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdGhlIGNpcGhlci4KICovCmZvcmdlLnJjMi5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyID0gZnVuY3Rpb24oa2V5LCBiaXRzKSB7CiAgcmV0dXJuIGNyZWF0ZUNpcGhlcihrZXksIGJpdHMsIHRydWUpOwp9OwoKLyoqCiAqIENyZWF0ZXMgYW4gUkMyIGNpcGhlciBvYmplY3QgdG8gZGVjcnlwdCBkYXRhIGluIEVDQiBvciBDQkMgbW9kZSB1c2luZyB0aGUKICogZ2l2ZW4gc3ltbWV0cmljIGtleS4gVGhlIG91dHB1dCB3aWxsIGJlIHN0b3JlZCBpbiB0aGUgJ291dHB1dCcgbWVtYmVyCiAqIG9mIHRoZSByZXR1cm5lZCBjaXBoZXIuCiAqCiAqIFRoZSBrZXkgYW5kIGl2IG1heSBiZSBnaXZlbiBhcyBhIHN0cmluZyBvZiBieXRlcyBvciBhIGJ5dGUgYnVmZmVyLgogKiBUaGUgY2lwaGVyIGlzIGluaXRpYWxpemVkIHRvIHVzZSAxMjggZWZmZWN0aXZlIGtleSBiaXRzLgogKgogKiBAcGFyYW0ga2V5IHRoZSBzeW1tZXRyaWMga2V5IHRvIHVzZS4KICogQHBhcmFtIGl2IHRoZSBpbml0aWFsaXphdGlvbiB2ZWN0b3IgdG8gdXNlLgogKiBAcGFyYW0gb3V0cHV0IHRoZSBidWZmZXIgdG8gd3JpdGUgdG8sIG51bGwgdG8gY3JlYXRlIG9uZS4KICoKICogQHJldHVybiB0aGUgY2lwaGVyLgogKi8KZm9yZ2UucmMyLnN0YXJ0RGVjcnlwdGluZyA9IGZ1bmN0aW9uKGtleSwgaXYsIG91dHB1dCkgewogIHZhciBjaXBoZXIgPSBmb3JnZS5yYzIuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcihrZXksIDEyOCk7CiAgY2lwaGVyLnN0YXJ0KGl2LCBvdXRwdXQpOwogIHJldHVybiBjaXBoZXI7Cn07CgovKioKICogQ3JlYXRlcyBhbiBSQzIgY2lwaGVyIG9iamVjdCB0byBkZWNyeXB0IGRhdGEgaW4gRUNCIG9yIENCQyBtb2RlIHVzaW5nIHRoZQogKiBnaXZlbiBzeW1tZXRyaWMga2V5LgogKgogKiBUaGUga2V5IG1heSBiZSBnaXZlbiBhcyBhIHN0cmluZyBvZiBieXRlcyBvciBhIGJ5dGUgYnVmZmVyLgogKgogKiBUbyBzdGFydCBkZWNyeXB0aW5nIGNhbGwgc3RhcnQoKSBvbiB0aGUgY2lwaGVyIHdpdGggYW4gaXYgYW5kIG9wdGlvbmFsCiAqIG91dHB1dCBidWZmZXIuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHN5bW1ldHJpYyBrZXkgdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSBjaXBoZXIuCiAqLwpmb3JnZS5yYzIuY3JlYXRlRGVjcnlwdGlvbkNpcGhlciA9IGZ1bmN0aW9uKGtleSwgYml0cykgewogIHJldHVybiBjcmVhdGVDaXBoZXIoa2V5LCBiaXRzLCBmYWxzZSk7Cn07Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdyYzInOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvcmMyJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8vIENvcHlyaWdodCAoYykgMjAwNSAgVG9tIFd1Ci8vIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCi8vIFNlZSAiTElDRU5TRSIgZm9yIGRldGFpbHMuCgovLyBCYXNpYyBKYXZhU2NyaXB0IEJOIGxpYnJhcnkgLSBzdWJzZXQgdXNlZnVsIGZvciBSU0EgZW5jcnlwdGlvbi4KCi8qCkxpY2Vuc2luZyAoTElDRU5TRSkKLS0tLS0tLS0tLS0tLS0tLS0tLQoKVGhpcyBzb2Z0d2FyZSBpcyBjb3ZlcmVkIHVuZGVyIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0OgoqLwovKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMtMjAwNSAgVG9tIFd1CiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZwogKiBhIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUKICogIlNvZnR3YXJlIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZwogKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCiAqIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0bwogKiBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8KICogdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZQogKiBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUy1JUyIgQU5EIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCiAqIEVYUFJFU1MsIElNUExJRUQgT1IgT1RIRVJXSVNFLCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OLCBBTlkKICogV0FSUkFOVFkgT0YgTUVSQ0hBTlRBQklMSVRZIE9SIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgogKgogKiBJTiBOTyBFVkVOVCBTSEFMTCBUT00gV1UgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5DSURFTlRBTCwKICogSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9GIEFOWSBLSU5ELCBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSCiAqIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgT1IgTk9UIEFEVklTRUQgT0YKICogVEhFIFBPU1NJQklMSVRZIE9GIERBTUFHRSwgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBBUklTSU5HIE9VVAogKiBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKgogKiBJbiBhZGRpdGlvbiwgdGhlIGZvbGxvd2luZyBjb25kaXRpb24gYXBwbGllczoKICoKICogQWxsIHJlZGlzdHJpYnV0aW9ucyBtdXN0IHJldGFpbiBhbiBpbnRhY3QgY29weSBvZiB0aGlzIGNvcHlyaWdodCBub3RpY2UKICogYW5kIGRpc2NsYWltZXIuCiAqLwovKgpBZGRyZXNzIGFsbCBxdWVzdGlvbnMgcmVnYXJkaW5nIHRoaXMgbGljZW5zZSB0bzoKCiAgVG9tIFd1CiAgdGp3QGNzLlN0YW5mb3JkLkVEVQoqLwoKKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIEJpdHMgcGVyIGRpZ2l0CnZhciBkYml0czsKCi8vIEphdmFTY3JpcHQgZW5naW5lIGFuYWx5c2lzCnZhciBjYW5hcnkgPSAweGRlYWRiZWVmY2FmZTsKdmFyIGpfbG0gPSAoKGNhbmFyeSYweGZmZmZmZik9PTB4ZWZjYWZlKTsKCi8vIChwdWJsaWMpIENvbnN0cnVjdG9yCmZ1bmN0aW9uIEJpZ0ludGVnZXIoYSxiLGMpIHsKICB0aGlzLmRhdGEgPSBbXTsKICBpZihhICE9IG51bGwpCiAgICBpZigibnVtYmVyIiA9PSB0eXBlb2YgYSkgdGhpcy5mcm9tTnVtYmVyKGEsYixjKTsKICAgIGVsc2UgaWYoYiA9PSBudWxsICYmICJzdHJpbmciICE9IHR5cGVvZiBhKSB0aGlzLmZyb21TdHJpbmcoYSwyNTYpOwogICAgZWxzZSB0aGlzLmZyb21TdHJpbmcoYSxiKTsKfQoKLy8gcmV0dXJuIG5ldywgdW5zZXQgQmlnSW50ZWdlcgpmdW5jdGlvbiBuYmkoKSB7IHJldHVybiBuZXcgQmlnSW50ZWdlcihudWxsKTsgfQoKLy8gYW06IENvbXB1dGUgd19qICs9ICh4KnRoaXNfaSksIHByb3BhZ2F0ZSBjYXJyaWVzLAovLyBjIGlzIGluaXRpYWwgY2FycnksIHJldHVybnMgZmluYWwgY2FycnkuCi8vIGMgPCAzKmR2YWx1ZSwgeCA8IDIqZHZhbHVlLCB0aGlzX2kgPCBkdmFsdWUKLy8gV2UgbmVlZCB0byBzZWxlY3QgdGhlIGZhc3Rlc3Qgb25lIHRoYXQgd29ya3MgaW4gdGhpcyBlbnZpcm9ubWVudC4KCi8vIGFtMTogdXNlIGEgc2luZ2xlIG11bHQgYW5kIGRpdmlkZSB0byBnZXQgdGhlIGhpZ2ggYml0cywKLy8gbWF4IGRpZ2l0IGJpdHMgc2hvdWxkIGJlIDI2IGJlY2F1c2UKLy8gbWF4IGludGVybmFsIHZhbHVlID0gMipkdmFsdWVeMi0yKmR2YWx1ZSAoPCAyXjUzKQpmdW5jdGlvbiBhbTEoaSx4LHcsaixjLG4pIHsKICB3aGlsZSgtLW4gPj0gMCkgewogICAgdmFyIHYgPSB4KnRoaXMuZGF0YVtpKytdK3cuZGF0YVtqXStjOwogICAgYyA9IE1hdGguZmxvb3Iodi8weDQwMDAwMDApOwogICAgdy5kYXRhW2orK10gPSB2JjB4M2ZmZmZmZjsKICB9CiAgcmV0dXJuIGM7Cn0KLy8gYW0yIGF2b2lkcyBhIGJpZyBtdWx0LWFuZC1leHRyYWN0IGNvbXBsZXRlbHkuCi8vIE1heCBkaWdpdCBiaXRzIHNob3VsZCBiZSA8PSAzMCBiZWNhdXNlIHdlIGRvIGJpdHdpc2Ugb3BzCi8vIG9uIHZhbHVlcyB1cCB0byAyKmhkdmFsdWVeMi1oZHZhbHVlLTEgKDwgMl4zMSkKZnVuY3Rpb24gYW0yKGkseCx3LGosYyxuKSB7CiAgdmFyIHhsID0geCYweDdmZmYsIHhoID0geD4+MTU7CiAgd2hpbGUoLS1uID49IDApIHsKICAgIHZhciBsID0gdGhpcy5kYXRhW2ldJjB4N2ZmZjsKICAgIHZhciBoID0gdGhpcy5kYXRhW2krK10+PjE1OwogICAgdmFyIG0gPSB4aCpsK2gqeGw7CiAgICBsID0geGwqbCsoKG0mMHg3ZmZmKTw8MTUpK3cuZGF0YVtqXSsoYyYweDNmZmZmZmZmKTsKICAgIGMgPSAobD4+PjMwKSsobT4+PjE1KSt4aCpoKyhjPj4+MzApOwogICAgdy5kYXRhW2orK10gPSBsJjB4M2ZmZmZmZmY7CiAgfQogIHJldHVybiBjOwp9Ci8vIEFsdGVybmF0ZWx5LCBzZXQgbWF4IGRpZ2l0IGJpdHMgdG8gMjggc2luY2Ugc29tZQovLyBicm93c2VycyBzbG93IGRvd24gd2hlbiBkZWFsaW5nIHdpdGggMzItYml0IG51bWJlcnMuCmZ1bmN0aW9uIGFtMyhpLHgsdyxqLGMsbikgewogIHZhciB4bCA9IHgmMHgzZmZmLCB4aCA9IHg+PjE0OwogIHdoaWxlKC0tbiA+PSAwKSB7CiAgICB2YXIgbCA9IHRoaXMuZGF0YVtpXSYweDNmZmY7CiAgICB2YXIgaCA9IHRoaXMuZGF0YVtpKytdPj4xNDsKICAgIHZhciBtID0geGgqbCtoKnhsOwogICAgbCA9IHhsKmwrKChtJjB4M2ZmZik8PDE0KSt3LmRhdGFbal0rYzsKICAgIGMgPSAobD4+MjgpKyhtPj4xNCkreGgqaDsKICAgIHcuZGF0YVtqKytdID0gbCYweGZmZmZmZmY7CiAgfQogIHJldHVybiBjOwp9CgovLyBub2RlLmpzIChubyBicm93c2VyKQppZih0eXBlb2YobmF2aWdhdG9yKSA9PT0gJ3VuZGVmaW5lZCcpCnsKICAgQmlnSW50ZWdlci5wcm90b3R5cGUuYW0gPSBhbTM7CiAgIGRiaXRzID0gMjg7Cn0gZWxzZSBpZihqX2xtICYmIChuYXZpZ2F0b3IuYXBwTmFtZSA9PSAiTWljcm9zb2Z0IEludGVybmV0IEV4cGxvcmVyIikpIHsKICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMjsKICBkYml0cyA9IDMwOwp9IGVsc2UgaWYoal9sbSAmJiAobmF2aWdhdG9yLmFwcE5hbWUgIT0gIk5ldHNjYXBlIikpIHsKICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMTsKICBkYml0cyA9IDI2Owp9IGVsc2UgeyAvLyBNb3ppbGxhL05ldHNjYXBlIHNlZW1zIHRvIHByZWZlciBhbTMKICBCaWdJbnRlZ2VyLnByb3RvdHlwZS5hbSA9IGFtMzsKICBkYml0cyA9IDI4Owp9CgpCaWdJbnRlZ2VyLnByb3RvdHlwZS5EQiA9IGRiaXRzOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5ETSA9ICgoMTw8ZGJpdHMpLTEpOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5EViA9ICgxPDxkYml0cyk7Cgp2YXIgQklfRlAgPSA1MjsKQmlnSW50ZWdlci5wcm90b3R5cGUuRlYgPSBNYXRoLnBvdygyLEJJX0ZQKTsKQmlnSW50ZWdlci5wcm90b3R5cGUuRjEgPSBCSV9GUC1kYml0czsKQmlnSW50ZWdlci5wcm90b3R5cGUuRjIgPSAyKmRiaXRzLUJJX0ZQOwoKLy8gRGlnaXQgY29udmVyc2lvbnMKdmFyIEJJX1JNID0gIjAxMjM0NTY3ODlhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5eiI7CnZhciBCSV9SQyA9IG5ldyBBcnJheSgpOwp2YXIgcnIsdnY7CnJyID0gIjAiLmNoYXJDb2RlQXQoMCk7CmZvcih2diA9IDA7IHZ2IDw9IDk7ICsrdnYpIEJJX1JDW3JyKytdID0gdnY7CnJyID0gImEiLmNoYXJDb2RlQXQoMCk7CmZvcih2diA9IDEwOyB2diA8IDM2OyArK3Z2KSBCSV9SQ1tycisrXSA9IHZ2OwpyciA9ICJBIi5jaGFyQ29kZUF0KDApOwpmb3IodnYgPSAxMDsgdnYgPCAzNjsgKyt2dikgQklfUkNbcnIrK10gPSB2djsKCmZ1bmN0aW9uIGludDJjaGFyKG4pIHsgcmV0dXJuIEJJX1JNLmNoYXJBdChuKTsgfQpmdW5jdGlvbiBpbnRBdChzLGkpIHsKICB2YXIgYyA9IEJJX1JDW3MuY2hhckNvZGVBdChpKV07CiAgcmV0dXJuIChjPT1udWxsKT8tMTpjOwp9CgovLyAocHJvdGVjdGVkKSBjb3B5IHRoaXMgdG8gcgpmdW5jdGlvbiBibnBDb3B5VG8ocikgewogIGZvcih2YXIgaSA9IHRoaXMudC0xOyBpID49IDA7IC0taSkgci5kYXRhW2ldID0gdGhpcy5kYXRhW2ldOwogIHIudCA9IHRoaXMudDsKICByLnMgPSB0aGlzLnM7Cn0KCi8vIChwcm90ZWN0ZWQpIHNldCBmcm9tIGludGVnZXIgdmFsdWUgeCwgLURWIDw9IHggPCBEVgpmdW5jdGlvbiBibnBGcm9tSW50KHgpIHsKICB0aGlzLnQgPSAxOwogIHRoaXMucyA9ICh4PDApPy0xOjA7CiAgaWYoeCA+IDApIHRoaXMuZGF0YVswXSA9IHg7CiAgZWxzZSBpZih4IDwgLTEpIHRoaXMuZGF0YVswXSA9IHgrdGhpcy5EVjsKICBlbHNlIHRoaXMudCA9IDA7Cn0KCi8vIHJldHVybiBiaWdpbnQgaW5pdGlhbGl6ZWQgdG8gdmFsdWUKZnVuY3Rpb24gbmJ2KGkpIHsgdmFyIHIgPSBuYmkoKTsgci5mcm9tSW50KGkpOyByZXR1cm4gcjsgfQoKLy8gKHByb3RlY3RlZCkgc2V0IGZyb20gc3RyaW5nIGFuZCByYWRpeApmdW5jdGlvbiBibnBGcm9tU3RyaW5nKHMsYikgewogIHZhciBrOwogIGlmKGIgPT0gMTYpIGsgPSA0OwogIGVsc2UgaWYoYiA9PSA4KSBrID0gMzsKICBlbHNlIGlmKGIgPT0gMjU2KSBrID0gODsgLy8gYnl0ZSBhcnJheQogIGVsc2UgaWYoYiA9PSAyKSBrID0gMTsKICBlbHNlIGlmKGIgPT0gMzIpIGsgPSA1OwogIGVsc2UgaWYoYiA9PSA0KSBrID0gMjsKICBlbHNlIHsgdGhpcy5mcm9tUmFkaXgocyxiKTsgcmV0dXJuOyB9CiAgdGhpcy50ID0gMDsKICB0aGlzLnMgPSAwOwogIHZhciBpID0gcy5sZW5ndGgsIG1pID0gZmFsc2UsIHNoID0gMDsKICB3aGlsZSgtLWkgPj0gMCkgewogICAgdmFyIHggPSAoaz09OCk/c1tpXSYweGZmOmludEF0KHMsaSk7CiAgICBpZih4IDwgMCkgewogICAgICBpZihzLmNoYXJBdChpKSA9PSAiLSIpIG1pID0gdHJ1ZTsKICAgICAgY29udGludWU7CiAgICB9CiAgICBtaSA9IGZhbHNlOwogICAgaWYoc2ggPT0gMCkKICAgICAgdGhpcy5kYXRhW3RoaXMudCsrXSA9IHg7CiAgICBlbHNlIGlmKHNoK2sgPiB0aGlzLkRCKSB7CiAgICAgIHRoaXMuZGF0YVt0aGlzLnQtMV0gfD0gKHgmKCgxPDwodGhpcy5EQi1zaCkpLTEpKTw8c2g7CiAgICAgIHRoaXMuZGF0YVt0aGlzLnQrK10gPSAoeD4+KHRoaXMuREItc2gpKTsKICAgIH0gZWxzZQogICAgICB0aGlzLmRhdGFbdGhpcy50LTFdIHw9IHg8PHNoOwogICAgc2ggKz0gazsKICAgIGlmKHNoID49IHRoaXMuREIpIHNoIC09IHRoaXMuREI7CiAgfQogIGlmKGsgPT0gOCAmJiAoc1swXSYweDgwKSAhPSAwKSB7CiAgICB0aGlzLnMgPSAtMTsKICAgIGlmKHNoID4gMCkgdGhpcy5kYXRhW3RoaXMudC0xXSB8PSAoKDE8PCh0aGlzLkRCLXNoKSktMSk8PHNoOwogIH0KICB0aGlzLmNsYW1wKCk7CiAgaWYobWkpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyh0aGlzLHRoaXMpOwp9CgovLyAocHJvdGVjdGVkKSBjbGFtcCBvZmYgZXhjZXNzIGhpZ2ggd29yZHMKZnVuY3Rpb24gYm5wQ2xhbXAoKSB7CiAgdmFyIGMgPSB0aGlzLnMmdGhpcy5ETTsKICB3aGlsZSh0aGlzLnQgPiAwICYmIHRoaXMuZGF0YVt0aGlzLnQtMV0gPT0gYykgLS10aGlzLnQ7Cn0KCi8vIChwdWJsaWMpIHJldHVybiBzdHJpbmcgcmVwcmVzZW50YXRpb24gaW4gZ2l2ZW4gcmFkaXgKZnVuY3Rpb24gYm5Ub1N0cmluZyhiKSB7CiAgaWYodGhpcy5zIDwgMCkgcmV0dXJuICItIit0aGlzLm5lZ2F0ZSgpLnRvU3RyaW5nKGIpOwogIHZhciBrOwogIGlmKGIgPT0gMTYpIGsgPSA0OwogIGVsc2UgaWYoYiA9PSA4KSBrID0gMzsKICBlbHNlIGlmKGIgPT0gMikgayA9IDE7CiAgZWxzZSBpZihiID09IDMyKSBrID0gNTsKICBlbHNlIGlmKGIgPT0gNCkgayA9IDI7CiAgZWxzZSByZXR1cm4gdGhpcy50b1JhZGl4KGIpOwogIHZhciBrbSA9ICgxPDxrKS0xLCBkLCBtID0gZmFsc2UsIHIgPSAiIiwgaSA9IHRoaXMudDsKICB2YXIgcCA9IHRoaXMuREItKGkqdGhpcy5EQiklazsKICBpZihpLS0gPiAwKSB7CiAgICBpZihwIDwgdGhpcy5EQiAmJiAoZCA9IHRoaXMuZGF0YVtpXT4+cCkgPiAwKSB7IG0gPSB0cnVlOyByID0gaW50MmNoYXIoZCk7IH0KICAgIHdoaWxlKGkgPj0gMCkgewogICAgICBpZihwIDwgaykgewogICAgICAgIGQgPSAodGhpcy5kYXRhW2ldJigoMTw8cCktMSkpPDwoay1wKTsKICAgICAgICBkIHw9IHRoaXMuZGF0YVstLWldPj4ocCs9dGhpcy5EQi1rKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBkID0gKHRoaXMuZGF0YVtpXT4+KHAtPWspKSZrbTsKICAgICAgICBpZihwIDw9IDApIHsgcCArPSB0aGlzLkRCOyAtLWk7IH0KICAgICAgfQogICAgICBpZihkID4gMCkgbSA9IHRydWU7CiAgICAgIGlmKG0pIHIgKz0gaW50MmNoYXIoZCk7CiAgICB9CiAgfQogIHJldHVybiBtP3I6IjAiOwp9CgovLyAocHVibGljKSAtdGhpcwpmdW5jdGlvbiBibk5lZ2F0ZSgpIHsgdmFyIHIgPSBuYmkoKTsgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMscik7IHJldHVybiByOyB9CgovLyAocHVibGljKSB8dGhpc3wKZnVuY3Rpb24gYm5BYnMoKSB7IHJldHVybiAodGhpcy5zPDApP3RoaXMubmVnYXRlKCk6dGhpczsgfQoKLy8gKHB1YmxpYykgcmV0dXJuICsgaWYgdGhpcyA+IGEsIC0gaWYgdGhpcyA8IGEsIDAgaWYgZXF1YWwKZnVuY3Rpb24gYm5Db21wYXJlVG8oYSkgewogIHZhciByID0gdGhpcy5zLWEuczsKICBpZihyICE9IDApIHJldHVybiByOwogIHZhciBpID0gdGhpcy50OwogIHIgPSBpLWEudDsKICBpZihyICE9IDApIHJldHVybiAodGhpcy5zPDApPy1yOnI7CiAgd2hpbGUoLS1pID49IDApIGlmKChyPXRoaXMuZGF0YVtpXS1hLmRhdGFbaV0pICE9IDApIHJldHVybiByOwogIHJldHVybiAwOwp9CgovLyByZXR1cm5zIGJpdCBsZW5ndGggb2YgdGhlIGludGVnZXIgeApmdW5jdGlvbiBuYml0cyh4KSB7CiAgdmFyIHIgPSAxLCB0OwogIGlmKCh0PXg+Pj4xNikgIT0gMCkgeyB4ID0gdDsgciArPSAxNjsgfQogIGlmKCh0PXg+PjgpICE9IDApIHsgeCA9IHQ7IHIgKz0gODsgfQogIGlmKCh0PXg+PjQpICE9IDApIHsgeCA9IHQ7IHIgKz0gNDsgfQogIGlmKCh0PXg+PjIpICE9IDApIHsgeCA9IHQ7IHIgKz0gMjsgfQogIGlmKCh0PXg+PjEpICE9IDApIHsgeCA9IHQ7IHIgKz0gMTsgfQogIHJldHVybiByOwp9CgovLyAocHVibGljKSByZXR1cm4gdGhlIG51bWJlciBvZiBiaXRzIGluICJ0aGlzIgpmdW5jdGlvbiBibkJpdExlbmd0aCgpIHsKICBpZih0aGlzLnQgPD0gMCkgcmV0dXJuIDA7CiAgcmV0dXJuIHRoaXMuREIqKHRoaXMudC0xKStuYml0cyh0aGlzLmRhdGFbdGhpcy50LTFdXih0aGlzLnMmdGhpcy5ETSkpOwp9CgovLyAocHJvdGVjdGVkKSByID0gdGhpcyA8PCBuKkRCCmZ1bmN0aW9uIGJucERMU2hpZnRUbyhuLHIpIHsKICB2YXIgaTsKICBmb3IoaSA9IHRoaXMudC0xOyBpID49IDA7IC0taSkgci5kYXRhW2krbl0gPSB0aGlzLmRhdGFbaV07CiAgZm9yKGkgPSBuLTE7IGkgPj0gMDsgLS1pKSByLmRhdGFbaV0gPSAwOwogIHIudCA9IHRoaXMudCtuOwogIHIucyA9IHRoaXMuczsKfQoKLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgPj4gbipEQgpmdW5jdGlvbiBibnBEUlNoaWZ0VG8obixyKSB7CiAgZm9yKHZhciBpID0gbjsgaSA8IHRoaXMudDsgKytpKSByLmRhdGFbaS1uXSA9IHRoaXMuZGF0YVtpXTsKICByLnQgPSBNYXRoLm1heCh0aGlzLnQtbiwwKTsKICByLnMgPSB0aGlzLnM7Cn0KCi8vIChwcm90ZWN0ZWQpIHIgPSB0aGlzIDw8IG4KZnVuY3Rpb24gYm5wTFNoaWZ0VG8obixyKSB7CiAgdmFyIGJzID0gbiV0aGlzLkRCOwogIHZhciBjYnMgPSB0aGlzLkRCLWJzOwogIHZhciBibSA9ICgxPDxjYnMpLTE7CiAgdmFyIGRzID0gTWF0aC5mbG9vcihuL3RoaXMuREIpLCBjID0gKHRoaXMuczw8YnMpJnRoaXMuRE0sIGk7CiAgZm9yKGkgPSB0aGlzLnQtMTsgaSA+PSAwOyAtLWkpIHsKICAgIHIuZGF0YVtpK2RzKzFdID0gKHRoaXMuZGF0YVtpXT4+Y2JzKXxjOwogICAgYyA9ICh0aGlzLmRhdGFbaV0mYm0pPDxiczsKICB9CiAgZm9yKGkgPSBkcy0xOyBpID49IDA7IC0taSkgci5kYXRhW2ldID0gMDsKICByLmRhdGFbZHNdID0gYzsKICByLnQgPSB0aGlzLnQrZHMrMTsKICByLnMgPSB0aGlzLnM7CiAgci5jbGFtcCgpOwp9CgovLyAocHJvdGVjdGVkKSByID0gdGhpcyA+PiBuCmZ1bmN0aW9uIGJucFJTaGlmdFRvKG4scikgewogIHIucyA9IHRoaXMuczsKICB2YXIgZHMgPSBNYXRoLmZsb29yKG4vdGhpcy5EQik7CiAgaWYoZHMgPj0gdGhpcy50KSB7IHIudCA9IDA7IHJldHVybjsgfQogIHZhciBicyA9IG4ldGhpcy5EQjsKICB2YXIgY2JzID0gdGhpcy5EQi1iczsKICB2YXIgYm0gPSAoMTw8YnMpLTE7CiAgci5kYXRhWzBdID0gdGhpcy5kYXRhW2RzXT4+YnM7CiAgZm9yKHZhciBpID0gZHMrMTsgaSA8IHRoaXMudDsgKytpKSB7CiAgICByLmRhdGFbaS1kcy0xXSB8PSAodGhpcy5kYXRhW2ldJmJtKTw8Y2JzOwogICAgci5kYXRhW2ktZHNdID0gdGhpcy5kYXRhW2ldPj5iczsKICB9CiAgaWYoYnMgPiAwKSByLmRhdGFbdGhpcy50LWRzLTFdIHw9ICh0aGlzLnMmYm0pPDxjYnM7CiAgci50ID0gdGhpcy50LWRzOwogIHIuY2xhbXAoKTsKfQoKLy8gKHByb3RlY3RlZCkgciA9IHRoaXMgLSBhCmZ1bmN0aW9uIGJucFN1YlRvKGEscikgewogIHZhciBpID0gMCwgYyA9IDAsIG0gPSBNYXRoLm1pbihhLnQsdGhpcy50KTsKICB3aGlsZShpIDwgbSkgewogICAgYyArPSB0aGlzLmRhdGFbaV0tYS5kYXRhW2ldOwogICAgci5kYXRhW2krK10gPSBjJnRoaXMuRE07CiAgICBjID4+PSB0aGlzLkRCOwogIH0KICBpZihhLnQgPCB0aGlzLnQpIHsKICAgIGMgLT0gYS5zOwogICAgd2hpbGUoaSA8IHRoaXMudCkgewogICAgICBjICs9IHRoaXMuZGF0YVtpXTsKICAgICAgci5kYXRhW2krK10gPSBjJnRoaXMuRE07CiAgICAgIGMgPj49IHRoaXMuREI7CiAgICB9CiAgICBjICs9IHRoaXMuczsKICB9IGVsc2UgewogICAgYyArPSB0aGlzLnM7CiAgICB3aGlsZShpIDwgYS50KSB7CiAgICAgIGMgLT0gYS5kYXRhW2ldOwogICAgICByLmRhdGFbaSsrXSA9IGMmdGhpcy5ETTsKICAgICAgYyA+Pj0gdGhpcy5EQjsKICAgIH0KICAgIGMgLT0gYS5zOwogIH0KICByLnMgPSAoYzwwKT8tMTowOwogIGlmKGMgPCAtMSkgci5kYXRhW2krK10gPSB0aGlzLkRWK2M7CiAgZWxzZSBpZihjID4gMCkgci5kYXRhW2krK10gPSBjOwogIHIudCA9IGk7CiAgci5jbGFtcCgpOwp9CgovLyAocHJvdGVjdGVkKSByID0gdGhpcyAqIGEsIHIgIT0gdGhpcyxhIChIQUMgMTQuMTIpCi8vICJ0aGlzIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuCmZ1bmN0aW9uIGJucE11bHRpcGx5VG8oYSxyKSB7CiAgdmFyIHggPSB0aGlzLmFicygpLCB5ID0gYS5hYnMoKTsKICB2YXIgaSA9IHgudDsKICByLnQgPSBpK3kudDsKICB3aGlsZSgtLWkgPj0gMCkgci5kYXRhW2ldID0gMDsKICBmb3IoaSA9IDA7IGkgPCB5LnQ7ICsraSkgci5kYXRhW2kreC50XSA9IHguYW0oMCx5LmRhdGFbaV0scixpLDAseC50KTsKICByLnMgPSAwOwogIHIuY2xhbXAoKTsKICBpZih0aGlzLnMgIT0gYS5zKSBCaWdJbnRlZ2VyLlpFUk8uc3ViVG8ocixyKTsKfQoKLy8gKHByb3RlY3RlZCkgciA9IHRoaXNeMiwgciAhPSB0aGlzIChIQUMgMTQuMTYpCmZ1bmN0aW9uIGJucFNxdWFyZVRvKHIpIHsKICB2YXIgeCA9IHRoaXMuYWJzKCk7CiAgdmFyIGkgPSByLnQgPSAyKngudDsKICB3aGlsZSgtLWkgPj0gMCkgci5kYXRhW2ldID0gMDsKICBmb3IoaSA9IDA7IGkgPCB4LnQtMTsgKytpKSB7CiAgICB2YXIgYyA9IHguYW0oaSx4LmRhdGFbaV0sciwyKmksMCwxKTsKICAgIGlmKChyLmRhdGFbaSt4LnRdKz14LmFtKGkrMSwyKnguZGF0YVtpXSxyLDIqaSsxLGMseC50LWktMSkpID49IHguRFYpIHsKICAgICAgci5kYXRhW2kreC50XSAtPSB4LkRWOwogICAgICByLmRhdGFbaSt4LnQrMV0gPSAxOwogICAgfQogIH0KICBpZihyLnQgPiAwKSByLmRhdGFbci50LTFdICs9IHguYW0oaSx4LmRhdGFbaV0sciwyKmksMCwxKTsKICByLnMgPSAwOwogIHIuY2xhbXAoKTsKfQoKLy8gKHByb3RlY3RlZCkgZGl2aWRlIHRoaXMgYnkgbSwgcXVvdGllbnQgYW5kIHJlbWFpbmRlciB0byBxLCByIChIQUMgMTQuMjApCi8vIHIgIT0gcSwgdGhpcyAhPSBtLiAgcSBvciByIG1heSBiZSBudWxsLgpmdW5jdGlvbiBibnBEaXZSZW1UbyhtLHEscikgewogIHZhciBwbSA9IG0uYWJzKCk7CiAgaWYocG0udCA8PSAwKSByZXR1cm47CiAgdmFyIHB0ID0gdGhpcy5hYnMoKTsKICBpZihwdC50IDwgcG0udCkgewogICAgaWYocSAhPSBudWxsKSBxLmZyb21JbnQoMCk7CiAgICBpZihyICE9IG51bGwpIHRoaXMuY29weVRvKHIpOwogICAgcmV0dXJuOwogIH0KICBpZihyID09IG51bGwpIHIgPSBuYmkoKTsKICB2YXIgeSA9IG5iaSgpLCB0cyA9IHRoaXMucywgbXMgPSBtLnM7CiAgdmFyIG5zaCA9IHRoaXMuREItbmJpdHMocG0uZGF0YVtwbS50LTFdKTsJLy8gbm9ybWFsaXplIG1vZHVsdXMKICBpZihuc2ggPiAwKSB7IHBtLmxTaGlmdFRvKG5zaCx5KTsgcHQubFNoaWZ0VG8obnNoLHIpOyB9IGVsc2UgeyBwbS5jb3B5VG8oeSk7IHB0LmNvcHlUbyhyKTsgfQogIHZhciB5cyA9IHkudDsKICB2YXIgeTAgPSB5LmRhdGFbeXMtMV07CiAgaWYoeTAgPT0gMCkgcmV0dXJuOwogIHZhciB5dCA9IHkwKigxPDx0aGlzLkYxKSsoKHlzPjEpP3kuZGF0YVt5cy0yXT4+dGhpcy5GMjowKTsKICB2YXIgZDEgPSB0aGlzLkZWL3l0LCBkMiA9ICgxPDx0aGlzLkYxKS95dCwgZSA9IDE8PHRoaXMuRjI7CiAgdmFyIGkgPSByLnQsIGogPSBpLXlzLCB0ID0gKHE9PW51bGwpP25iaSgpOnE7CiAgeS5kbFNoaWZ0VG8oaix0KTsKICBpZihyLmNvbXBhcmVUbyh0KSA+PSAwKSB7CiAgICByLmRhdGFbci50KytdID0gMTsKICAgIHIuc3ViVG8odCxyKTsKICB9CiAgQmlnSW50ZWdlci5PTkUuZGxTaGlmdFRvKHlzLHQpOwogIHQuc3ViVG8oeSx5KTsJLy8gIm5lZ2F0aXZlIiB5IHNvIHdlIGNhbiByZXBsYWNlIHN1YiB3aXRoIGFtIGxhdGVyCiAgd2hpbGUoeS50IDwgeXMpIHkuZGF0YVt5LnQrK10gPSAwOwogIHdoaWxlKC0taiA+PSAwKSB7CiAgICAvLyBFc3RpbWF0ZSBxdW90aWVudCBkaWdpdAogICAgdmFyIHFkID0gKHIuZGF0YVstLWldPT15MCk/dGhpcy5ETTpNYXRoLmZsb29yKHIuZGF0YVtpXSpkMSsoci5kYXRhW2ktMV0rZSkqZDIpOwogICAgaWYoKHIuZGF0YVtpXSs9eS5hbSgwLHFkLHIsaiwwLHlzKSkgPCBxZCkgewkvLyBUcnkgaXQgb3V0CiAgICAgIHkuZGxTaGlmdFRvKGosdCk7CiAgICAgIHIuc3ViVG8odCxyKTsKICAgICAgd2hpbGUoci5kYXRhW2ldIDwgLS1xZCkgci5zdWJUbyh0LHIpOwogICAgfQogIH0KICBpZihxICE9IG51bGwpIHsKICAgIHIuZHJTaGlmdFRvKHlzLHEpOwogICAgaWYodHMgIT0gbXMpIEJpZ0ludGVnZXIuWkVSTy5zdWJUbyhxLHEpOwogIH0KICByLnQgPSB5czsKICByLmNsYW1wKCk7CiAgaWYobnNoID4gMCkgci5yU2hpZnRUbyhuc2gscik7CS8vIERlbm9ybWFsaXplIHJlbWFpbmRlcgogIGlmKHRzIDwgMCkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHIscik7Cn0KCi8vIChwdWJsaWMpIHRoaXMgbW9kIGEKZnVuY3Rpb24gYm5Nb2QoYSkgewogIHZhciByID0gbmJpKCk7CiAgdGhpcy5hYnMoKS5kaXZSZW1UbyhhLG51bGwscik7CiAgaWYodGhpcy5zIDwgMCAmJiByLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLlpFUk8pID4gMCkgYS5zdWJUbyhyLHIpOwogIHJldHVybiByOwp9CgovLyBNb2R1bGFyIHJlZHVjdGlvbiB1c2luZyAiY2xhc3NpYyIgYWxnb3JpdGhtCmZ1bmN0aW9uIENsYXNzaWMobSkgeyB0aGlzLm0gPSBtOyB9CmZ1bmN0aW9uIGNDb252ZXJ0KHgpIHsKICBpZih4LnMgPCAwIHx8IHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgcmV0dXJuIHgubW9kKHRoaXMubSk7CiAgZWxzZSByZXR1cm4geDsKfQpmdW5jdGlvbiBjUmV2ZXJ0KHgpIHsgcmV0dXJuIHg7IH0KZnVuY3Rpb24gY1JlZHVjZSh4KSB7IHguZGl2UmVtVG8odGhpcy5tLG51bGwseCk7IH0KZnVuY3Rpb24gY011bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB0aGlzLnJlZHVjZShyKTsgfQpmdW5jdGlvbiBjU3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IHRoaXMucmVkdWNlKHIpOyB9CgpDbGFzc2ljLnByb3RvdHlwZS5jb252ZXJ0ID0gY0NvbnZlcnQ7CkNsYXNzaWMucHJvdG90eXBlLnJldmVydCA9IGNSZXZlcnQ7CkNsYXNzaWMucHJvdG90eXBlLnJlZHVjZSA9IGNSZWR1Y2U7CkNsYXNzaWMucHJvdG90eXBlLm11bFRvID0gY011bFRvOwpDbGFzc2ljLnByb3RvdHlwZS5zcXJUbyA9IGNTcXJUbzsKCi8vIChwcm90ZWN0ZWQpIHJldHVybiAiLTEvdGhpcyAlIDJeREIiOyB1c2VmdWwgZm9yIE1vbnQuIHJlZHVjdGlvbgovLyBqdXN0aWZpY2F0aW9uOgovLyAgICAgICAgIHh5ID09IDEgKG1vZCBtKQovLyAgICAgICAgIHh5ID0gIDEra20KLy8gICB4eSgyLXh5KSA9ICgxK2ttKSgxLWttKQovLyB4W3koMi14eSldID0gMS1rXjJtXjIKLy8geFt5KDIteHkpXSA9PSAxIChtb2QgbV4yKQovLyBpZiB5IGlzIDEveCBtb2QgbSwgdGhlbiB5KDIteHkpIGlzIDEveCBtb2QgbV4yCi8vIHNob3VsZCByZWR1Y2UgeCBhbmQgeSgyLXh5KSBieSBtXjIgYXQgZWFjaCBzdGVwIHRvIGtlZXAgc2l6ZSBib3VuZGVkLgovLyBKUyBtdWx0aXBseSAib3ZlcmZsb3dzIiBkaWZmZXJlbnRseSBmcm9tIEMvQysrLCBzbyBjYXJlIGlzIG5lZWRlZCBoZXJlLgpmdW5jdGlvbiBibnBJbnZEaWdpdCgpIHsKICBpZih0aGlzLnQgPCAxKSByZXR1cm4gMDsKICB2YXIgeCA9IHRoaXMuZGF0YVswXTsKICBpZigoeCYxKSA9PSAwKSByZXR1cm4gMDsKICB2YXIgeSA9IHgmMzsJCS8vIHkgPT0gMS94IG1vZCAyXjIKICB5ID0gKHkqKDItKHgmMHhmKSp5KSkmMHhmOwkvLyB5ID09IDEveCBtb2QgMl40CiAgeSA9ICh5KigyLSh4JjB4ZmYpKnkpKSYweGZmOwkvLyB5ID09IDEveCBtb2QgMl44CiAgeSA9ICh5KigyLSgoKHgmMHhmZmZmKSp5KSYweGZmZmYpKSkmMHhmZmZmOwkvLyB5ID09IDEveCBtb2QgMl4xNgogIC8vIGxhc3Qgc3RlcCAtIGNhbGN1bGF0ZSBpbnZlcnNlIG1vZCBEViBkaXJlY3RseTsKICAvLyBhc3N1bWVzIDE2IDwgREIgPD0gMzIgYW5kIGFzc3VtZXMgYWJpbGl0eSB0byBoYW5kbGUgNDgtYml0IGludHMKICB5ID0gKHkqKDIteCp5JXRoaXMuRFYpKSV0aGlzLkRWOwkJLy8geSA9PSAxL3ggbW9kIDJeZGJpdHMKICAvLyB3ZSByZWFsbHkgd2FudCB0aGUgbmVnYXRpdmUgaW52ZXJzZSwgYW5kIC1EViA8IHkgPCBEVgogIHJldHVybiAoeT4wKT90aGlzLkRWLXk6LXk7Cn0KCi8vIE1vbnRnb21lcnkgcmVkdWN0aW9uCmZ1bmN0aW9uIE1vbnRnb21lcnkobSkgewogIHRoaXMubSA9IG07CiAgdGhpcy5tcCA9IG0uaW52RGlnaXQoKTsKICB0aGlzLm1wbCA9IHRoaXMubXAmMHg3ZmZmOwogIHRoaXMubXBoID0gdGhpcy5tcD4+MTU7CiAgdGhpcy51bSA9ICgxPDwobS5EQi0xNSkpLTE7CiAgdGhpcy5tdDIgPSAyKm0udDsKfQoKLy8geFIgbW9kIG0KZnVuY3Rpb24gbW9udENvbnZlcnQoeCkgewogIHZhciByID0gbmJpKCk7CiAgeC5hYnMoKS5kbFNoaWZ0VG8odGhpcy5tLnQscik7CiAgci5kaXZSZW1Ubyh0aGlzLm0sbnVsbCxyKTsKICBpZih4LnMgPCAwICYmIHIuY29tcGFyZVRvKEJpZ0ludGVnZXIuWkVSTykgPiAwKSB0aGlzLm0uc3ViVG8ocixyKTsKICByZXR1cm4gcjsKfQoKLy8geC9SIG1vZCBtCmZ1bmN0aW9uIG1vbnRSZXZlcnQoeCkgewogIHZhciByID0gbmJpKCk7CiAgeC5jb3B5VG8ocik7CiAgdGhpcy5yZWR1Y2Uocik7CiAgcmV0dXJuIHI7Cn0KCi8vIHggPSB4L1IgbW9kIG0gKEhBQyAxNC4zMikKZnVuY3Rpb24gbW9udFJlZHVjZSh4KSB7CiAgd2hpbGUoeC50IDw9IHRoaXMubXQyKQkvLyBwYWQgeCBzbyBhbSBoYXMgZW5vdWdoIHJvb20gbGF0ZXIKICAgIHguZGF0YVt4LnQrK10gPSAwOwogIGZvcih2YXIgaSA9IDA7IGkgPCB0aGlzLm0udDsgKytpKSB7CiAgICAvLyBmYXN0ZXIgd2F5IG9mIGNhbGN1bGF0aW5nIHUwID0geC5kYXRhW2ldKm1wIG1vZCBEVgogICAgdmFyIGogPSB4LmRhdGFbaV0mMHg3ZmZmOwogICAgdmFyIHUwID0gKGoqdGhpcy5tcGwrKCgoaip0aGlzLm1waCsoeC5kYXRhW2ldPj4xNSkqdGhpcy5tcGwpJnRoaXMudW0pPDwxNSkpJnguRE07CiAgICAvLyB1c2UgYW0gdG8gY29tYmluZSB0aGUgbXVsdGlwbHktc2hpZnQtYWRkIGludG8gb25lIGNhbGwKICAgIGogPSBpK3RoaXMubS50OwogICAgeC5kYXRhW2pdICs9IHRoaXMubS5hbSgwLHUwLHgsaSwwLHRoaXMubS50KTsKICAgIC8vIHByb3BhZ2F0ZSBjYXJyeQogICAgd2hpbGUoeC5kYXRhW2pdID49IHguRFYpIHsgeC5kYXRhW2pdIC09IHguRFY7IHguZGF0YVsrK2pdKys7IH0KICB9CiAgeC5jbGFtcCgpOwogIHguZHJTaGlmdFRvKHRoaXMubS50LHgpOwogIGlmKHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgeC5zdWJUbyh0aGlzLm0seCk7Cn0KCi8vIHIgPSAieF4yL1IgbW9kIG0iOyB4ICE9IHIKZnVuY3Rpb24gbW9udFNxclRvKHgscikgeyB4LnNxdWFyZVRvKHIpOyB0aGlzLnJlZHVjZShyKTsgfQoKLy8gciA9ICJ4eS9SIG1vZCBtIjsgeCx5ICE9IHIKZnVuY3Rpb24gbW9udE11bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB0aGlzLnJlZHVjZShyKTsgfQoKTW9udGdvbWVyeS5wcm90b3R5cGUuY29udmVydCA9IG1vbnRDb252ZXJ0OwpNb250Z29tZXJ5LnByb3RvdHlwZS5yZXZlcnQgPSBtb250UmV2ZXJ0OwpNb250Z29tZXJ5LnByb3RvdHlwZS5yZWR1Y2UgPSBtb250UmVkdWNlOwpNb250Z29tZXJ5LnByb3RvdHlwZS5tdWxUbyA9IG1vbnRNdWxUbzsKTW9udGdvbWVyeS5wcm90b3R5cGUuc3FyVG8gPSBtb250U3FyVG87CgovLyAocHJvdGVjdGVkKSB0cnVlIGlmZiB0aGlzIGlzIGV2ZW4KZnVuY3Rpb24gYm5wSXNFdmVuKCkgeyByZXR1cm4gKCh0aGlzLnQ+MCk/KHRoaXMuZGF0YVswXSYxKTp0aGlzLnMpID09IDA7IH0KCi8vIChwcm90ZWN0ZWQpIHRoaXNeZSwgZSA8IDJeMzIsIGRvaW5nIHNxciBhbmQgbXVsIHdpdGggInIiIChIQUMgMTQuNzkpCmZ1bmN0aW9uIGJucEV4cChlLHopIHsKICBpZihlID4gMHhmZmZmZmZmZiB8fCBlIDwgMSkgcmV0dXJuIEJpZ0ludGVnZXIuT05FOwogIHZhciByID0gbmJpKCksIHIyID0gbmJpKCksIGcgPSB6LmNvbnZlcnQodGhpcyksIGkgPSBuYml0cyhlKS0xOwogIGcuY29weVRvKHIpOwogIHdoaWxlKC0taSA+PSAwKSB7CiAgICB6LnNxclRvKHIscjIpOwogICAgaWYoKGUmKDE8PGkpKSA+IDApIHoubXVsVG8ocjIsZyxyKTsKICAgIGVsc2UgeyB2YXIgdCA9IHI7IHIgPSByMjsgcjIgPSB0OyB9CiAgfQogIHJldHVybiB6LnJldmVydChyKTsKfQoKLy8gKHB1YmxpYykgdGhpc15lICUgbSwgMCA8PSBlIDwgMl4zMgpmdW5jdGlvbiBibk1vZFBvd0ludChlLG0pIHsKICB2YXIgejsKICBpZihlIDwgMjU2IHx8IG0uaXNFdmVuKCkpIHogPSBuZXcgQ2xhc3NpYyhtKTsgZWxzZSB6ID0gbmV3IE1vbnRnb21lcnkobSk7CiAgcmV0dXJuIHRoaXMuZXhwKGUseik7Cn0KCi8vIHByb3RlY3RlZApCaWdJbnRlZ2VyLnByb3RvdHlwZS5jb3B5VG8gPSBibnBDb3B5VG87CkJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21JbnQgPSBibnBGcm9tSW50OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tU3RyaW5nID0gYm5wRnJvbVN0cmluZzsKQmlnSW50ZWdlci5wcm90b3R5cGUuY2xhbXAgPSBibnBDbGFtcDsKQmlnSW50ZWdlci5wcm90b3R5cGUuZGxTaGlmdFRvID0gYm5wRExTaGlmdFRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kclNoaWZ0VG8gPSBibnBEUlNoaWZ0VG87CkJpZ0ludGVnZXIucHJvdG90eXBlLmxTaGlmdFRvID0gYm5wTFNoaWZ0VG87CkJpZ0ludGVnZXIucHJvdG90eXBlLnJTaGlmdFRvID0gYm5wUlNoaWZ0VG87CkJpZ0ludGVnZXIucHJvdG90eXBlLnN1YlRvID0gYm5wU3ViVG87CkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5VG8gPSBibnBNdWx0aXBseVRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5zcXVhcmVUbyA9IGJucFNxdWFyZVRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZSZW1UbyA9IGJucERpdlJlbVRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5pbnZEaWdpdCA9IGJucEludkRpZ2l0OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5pc0V2ZW4gPSBibnBJc0V2ZW47CkJpZ0ludGVnZXIucHJvdG90eXBlLmV4cCA9IGJucEV4cDsKCi8vIHB1YmxpYwpCaWdJbnRlZ2VyLnByb3RvdHlwZS50b1N0cmluZyA9IGJuVG9TdHJpbmc7CkJpZ0ludGVnZXIucHJvdG90eXBlLm5lZ2F0ZSA9IGJuTmVnYXRlOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5hYnMgPSBibkFiczsKQmlnSW50ZWdlci5wcm90b3R5cGUuY29tcGFyZVRvID0gYm5Db21wYXJlVG87CkJpZ0ludGVnZXIucHJvdG90eXBlLmJpdExlbmd0aCA9IGJuQml0TGVuZ3RoOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5tb2QgPSBibk1vZDsKQmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93SW50ID0gYm5Nb2RQb3dJbnQ7CgovLyAiY29uc3RhbnRzIgpCaWdJbnRlZ2VyLlpFUk8gPSBuYnYoMCk7CkJpZ0ludGVnZXIuT05FID0gbmJ2KDEpOwoKLy8ganNibjIgbGliCgovL0NvcHlyaWdodCAoYykgMjAwNS0yMDA5ICBUb20gV3UKLy9BbGwgUmlnaHRzIFJlc2VydmVkLgovL1NlZSAiTElDRU5TRSIgZm9yIGRldGFpbHMgKFNlZSBqc2JuLmpzIGZvciBMSUNFTlNFKS4KCi8vRXh0ZW5kZWQgSmF2YVNjcmlwdCBCTiBmdW5jdGlvbnMsIHJlcXVpcmVkIGZvciBSU0EgcHJpdmF0ZSBvcHMuCgovL1ZlcnNpb24gMS4xOiBuZXcgQmlnSW50ZWdlcigiMCIsIDEwKSByZXR1cm5zICJwcm9wZXIiIHplcm8KCi8vKHB1YmxpYykKZnVuY3Rpb24gYm5DbG9uZSgpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5jb3B5VG8ocik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIHJldHVybiB2YWx1ZSBhcyBpbnRlZ2VyCmZ1bmN0aW9uIGJuSW50VmFsdWUoKSB7CmlmKHRoaXMucyA8IDApIHsKIGlmKHRoaXMudCA9PSAxKSByZXR1cm4gdGhpcy5kYXRhWzBdLXRoaXMuRFY7CiBlbHNlIGlmKHRoaXMudCA9PSAwKSByZXR1cm4gLTE7Cn0gZWxzZSBpZih0aGlzLnQgPT0gMSkgcmV0dXJuIHRoaXMuZGF0YVswXTsKZWxzZSBpZih0aGlzLnQgPT0gMCkgcmV0dXJuIDA7Ci8vIGFzc3VtZXMgMTYgPCBEQiA8IDMyCnJldHVybiAoKHRoaXMuZGF0YVsxXSYoKDE8PCgzMi10aGlzLkRCKSktMSkpPDx0aGlzLkRCKXx0aGlzLmRhdGFbMF07Cn0KCi8vKHB1YmxpYykgcmV0dXJuIHZhbHVlIGFzIGJ5dGUKZnVuY3Rpb24gYm5CeXRlVmFsdWUoKSB7IHJldHVybiAodGhpcy50PT0wKT90aGlzLnM6KHRoaXMuZGF0YVswXTw8MjQpPj4yNDsgfQoKLy8ocHVibGljKSByZXR1cm4gdmFsdWUgYXMgc2hvcnQgKGFzc3VtZXMgREI+PTE2KQpmdW5jdGlvbiBiblNob3J0VmFsdWUoKSB7IHJldHVybiAodGhpcy50PT0wKT90aGlzLnM6KHRoaXMuZGF0YVswXTw8MTYpPj4xNjsgfQoKLy8ocHJvdGVjdGVkKSByZXR1cm4geCBzLnQuIHJeeCA8IERWCmZ1bmN0aW9uIGJucENodW5rU2l6ZShyKSB7IHJldHVybiBNYXRoLmZsb29yKE1hdGguTE4yKnRoaXMuREIvTWF0aC5sb2cocikpOyB9CgovLyhwdWJsaWMpIDAgaWYgdGhpcyA9PSAwLCAxIGlmIHRoaXMgPiAwCmZ1bmN0aW9uIGJuU2lnTnVtKCkgewppZih0aGlzLnMgPCAwKSByZXR1cm4gLTE7CmVsc2UgaWYodGhpcy50IDw9IDAgfHwgKHRoaXMudCA9PSAxICYmIHRoaXMuZGF0YVswXSA8PSAwKSkgcmV0dXJuIDA7CmVsc2UgcmV0dXJuIDE7Cn0KCi8vKHByb3RlY3RlZCkgY29udmVydCB0byByYWRpeCBzdHJpbmcKZnVuY3Rpb24gYm5wVG9SYWRpeChiKSB7CmlmKGIgPT0gbnVsbCkgYiA9IDEwOwppZih0aGlzLnNpZ251bSgpID09IDAgfHwgYiA8IDIgfHwgYiA+IDM2KSByZXR1cm4gIjAiOwp2YXIgY3MgPSB0aGlzLmNodW5rU2l6ZShiKTsKdmFyIGEgPSBNYXRoLnBvdyhiLGNzKTsKdmFyIGQgPSBuYnYoYSksIHkgPSBuYmkoKSwgeiA9IG5iaSgpLCByID0gIiI7CnRoaXMuZGl2UmVtVG8oZCx5LHopOwp3aGlsZSh5LnNpZ251bSgpID4gMCkgewogciA9IChhK3ouaW50VmFsdWUoKSkudG9TdHJpbmcoYikuc3Vic3RyKDEpICsgcjsKIHkuZGl2UmVtVG8oZCx5LHopOwp9CnJldHVybiB6LmludFZhbHVlKCkudG9TdHJpbmcoYikgKyByOwp9CgovLyhwcm90ZWN0ZWQpIGNvbnZlcnQgZnJvbSByYWRpeCBzdHJpbmcKZnVuY3Rpb24gYm5wRnJvbVJhZGl4KHMsYikgewp0aGlzLmZyb21JbnQoMCk7CmlmKGIgPT0gbnVsbCkgYiA9IDEwOwp2YXIgY3MgPSB0aGlzLmNodW5rU2l6ZShiKTsKdmFyIGQgPSBNYXRoLnBvdyhiLGNzKSwgbWkgPSBmYWxzZSwgaiA9IDAsIHcgPSAwOwpmb3IodmFyIGkgPSAwOyBpIDwgcy5sZW5ndGg7ICsraSkgewogdmFyIHggPSBpbnRBdChzLGkpOwogaWYoeCA8IDApIHsKICAgaWYocy5jaGFyQXQoaSkgPT0gIi0iICYmIHRoaXMuc2lnbnVtKCkgPT0gMCkgbWkgPSB0cnVlOwogICBjb250aW51ZTsKIH0KIHcgPSBiKncreDsKIGlmKCsraiA+PSBjcykgewogICB0aGlzLmRNdWx0aXBseShkKTsKICAgdGhpcy5kQWRkT2Zmc2V0KHcsMCk7CiAgIGogPSAwOwogICB3ID0gMDsKIH0KfQppZihqID4gMCkgewogdGhpcy5kTXVsdGlwbHkoTWF0aC5wb3coYixqKSk7CiB0aGlzLmRBZGRPZmZzZXQodywwKTsKfQppZihtaSkgQmlnSW50ZWdlci5aRVJPLnN1YlRvKHRoaXMsdGhpcyk7Cn0KCi8vKHByb3RlY3RlZCkgYWx0ZXJuYXRlIGNvbnN0cnVjdG9yCmZ1bmN0aW9uIGJucEZyb21OdW1iZXIoYSxiLGMpIHsKaWYoIm51bWJlciIgPT0gdHlwZW9mIGIpIHsKIC8vIG5ldyBCaWdJbnRlZ2VyKGludCxpbnQsUk5HKQogaWYoYSA8IDIpIHRoaXMuZnJvbUludCgxKTsKIGVsc2UgewogICB0aGlzLmZyb21OdW1iZXIoYSxjKTsKICAgaWYoIXRoaXMudGVzdEJpdChhLTEpKSAgLy8gZm9yY2UgTVNCIHNldAogICAgIHRoaXMuYml0d2lzZVRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhLTEpLG9wX29yLHRoaXMpOwogICBpZih0aGlzLmlzRXZlbigpKSB0aGlzLmRBZGRPZmZzZXQoMSwwKTsgLy8gZm9yY2Ugb2RkCiAgIHdoaWxlKCF0aGlzLmlzUHJvYmFibGVQcmltZShiKSkgewogICAgIHRoaXMuZEFkZE9mZnNldCgyLDApOwogICAgIGlmKHRoaXMuYml0TGVuZ3RoKCkgPiBhKSB0aGlzLnN1YlRvKEJpZ0ludGVnZXIuT05FLnNoaWZ0TGVmdChhLTEpLHRoaXMpOwogICB9CiB9Cn0gZWxzZSB7CiAvLyBuZXcgQmlnSW50ZWdlcihpbnQsUk5HKQogdmFyIHggPSBuZXcgQXJyYXkoKSwgdCA9IGEmNzsKIHgubGVuZ3RoID0gKGE+PjMpKzE7CiBiLm5leHRCeXRlcyh4KTsKIGlmKHQgPiAwKSB4WzBdICY9ICgoMTw8dCktMSk7IGVsc2UgeFswXSA9IDA7CiB0aGlzLmZyb21TdHJpbmcoeCwyNTYpOwp9Cn0KCi8vKHB1YmxpYykgY29udmVydCB0byBiaWdlbmRpYW4gYnl0ZSBhcnJheQpmdW5jdGlvbiBiblRvQnl0ZUFycmF5KCkgewp2YXIgaSA9IHRoaXMudCwgciA9IG5ldyBBcnJheSgpOwpyWzBdID0gdGhpcy5zOwp2YXIgcCA9IHRoaXMuREItKGkqdGhpcy5EQiklOCwgZCwgayA9IDA7CmlmKGktLSA+IDApIHsKIGlmKHAgPCB0aGlzLkRCICYmIChkID0gdGhpcy5kYXRhW2ldPj5wKSAhPSAodGhpcy5zJnRoaXMuRE0pPj5wKQogICByW2srK10gPSBkfCh0aGlzLnM8PCh0aGlzLkRCLXApKTsKIHdoaWxlKGkgPj0gMCkgewogICBpZihwIDwgOCkgewogICAgIGQgPSAodGhpcy5kYXRhW2ldJigoMTw8cCktMSkpPDwoOC1wKTsKICAgICBkIHw9IHRoaXMuZGF0YVstLWldPj4ocCs9dGhpcy5EQi04KTsKICAgfSBlbHNlIHsKICAgICBkID0gKHRoaXMuZGF0YVtpXT4+KHAtPTgpKSYweGZmOwogICAgIGlmKHAgPD0gMCkgeyBwICs9IHRoaXMuREI7IC0taTsgfQogICB9CiAgIGlmKChkJjB4ODApICE9IDApIGQgfD0gLTI1NjsKICAgaWYoayA9PSAwICYmICh0aGlzLnMmMHg4MCkgIT0gKGQmMHg4MCkpICsrazsKICAgaWYoayA+IDAgfHwgZCAhPSB0aGlzLnMpIHJbaysrXSA9IGQ7CiB9Cn0KcmV0dXJuIHI7Cn0KCmZ1bmN0aW9uIGJuRXF1YWxzKGEpIHsgcmV0dXJuKHRoaXMuY29tcGFyZVRvKGEpPT0wKTsgfQpmdW5jdGlvbiBibk1pbihhKSB7IHJldHVybih0aGlzLmNvbXBhcmVUbyhhKTwwKT90aGlzOmE7IH0KZnVuY3Rpb24gYm5NYXgoYSkgeyByZXR1cm4odGhpcy5jb21wYXJlVG8oYSk+MCk/dGhpczphOyB9CgovLyhwcm90ZWN0ZWQpIHIgPSB0aGlzIG9wIGEgKGJpdHdpc2UpCmZ1bmN0aW9uIGJucEJpdHdpc2VUbyhhLG9wLHIpIHsKdmFyIGksIGYsIG0gPSBNYXRoLm1pbihhLnQsdGhpcy50KTsKZm9yKGkgPSAwOyBpIDwgbTsgKytpKSByLmRhdGFbaV0gPSBvcCh0aGlzLmRhdGFbaV0sYS5kYXRhW2ldKTsKaWYoYS50IDwgdGhpcy50KSB7CiBmID0gYS5zJnRoaXMuRE07CiBmb3IoaSA9IG07IGkgPCB0aGlzLnQ7ICsraSkgci5kYXRhW2ldID0gb3AodGhpcy5kYXRhW2ldLGYpOwogci50ID0gdGhpcy50Owp9IGVsc2UgewogZiA9IHRoaXMucyZ0aGlzLkRNOwogZm9yKGkgPSBtOyBpIDwgYS50OyArK2kpIHIuZGF0YVtpXSA9IG9wKGYsYS5kYXRhW2ldKTsKIHIudCA9IGEudDsKfQpyLnMgPSBvcCh0aGlzLnMsYS5zKTsKci5jbGFtcCgpOwp9CgovLyhwdWJsaWMpIHRoaXMgJiBhCmZ1bmN0aW9uIG9wX2FuZCh4LHkpIHsgcmV0dXJuIHgmeTsgfQpmdW5jdGlvbiBibkFuZChhKSB7IHZhciByID0gbmJpKCk7IHRoaXMuYml0d2lzZVRvKGEsb3BfYW5kLHIpOyByZXR1cm4gcjsgfQoKLy8ocHVibGljKSB0aGlzIHwgYQpmdW5jdGlvbiBvcF9vcih4LHkpIHsgcmV0dXJuIHh8eTsgfQpmdW5jdGlvbiBibk9yKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF9vcixyKTsgcmV0dXJuIHI7IH0KCi8vKHB1YmxpYykgdGhpcyBeIGEKZnVuY3Rpb24gb3BfeG9yKHgseSkgeyByZXR1cm4geF55OyB9CmZ1bmN0aW9uIGJuWG9yKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF94b3Iscik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIHRoaXMgJiB+YQpmdW5jdGlvbiBvcF9hbmRub3QoeCx5KSB7IHJldHVybiB4Jn55OyB9CmZ1bmN0aW9uIGJuQW5kTm90KGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5iaXR3aXNlVG8oYSxvcF9hbmRub3Qscik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIH50aGlzCmZ1bmN0aW9uIGJuTm90KCkgewp2YXIgciA9IG5iaSgpOwpmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpIHIuZGF0YVtpXSA9IHRoaXMuRE0mfnRoaXMuZGF0YVtpXTsKci50ID0gdGhpcy50OwpyLnMgPSB+dGhpcy5zOwpyZXR1cm4gcjsKfQoKLy8ocHVibGljKSB0aGlzIDw8IG4KZnVuY3Rpb24gYm5TaGlmdExlZnQobikgewp2YXIgciA9IG5iaSgpOwppZihuIDwgMCkgdGhpcy5yU2hpZnRUbygtbixyKTsgZWxzZSB0aGlzLmxTaGlmdFRvKG4scik7CnJldHVybiByOwp9CgovLyhwdWJsaWMpIHRoaXMgPj4gbgpmdW5jdGlvbiBiblNoaWZ0UmlnaHQobikgewp2YXIgciA9IG5iaSgpOwppZihuIDwgMCkgdGhpcy5sU2hpZnRUbygtbixyKTsgZWxzZSB0aGlzLnJTaGlmdFRvKG4scik7CnJldHVybiByOwp9CgovL3JldHVybiBpbmRleCBvZiBsb3dlc3QgMS1iaXQgaW4geCwgeCA8IDJeMzEKZnVuY3Rpb24gbGJpdCh4KSB7CmlmKHggPT0gMCkgcmV0dXJuIC0xOwp2YXIgciA9IDA7CmlmKCh4JjB4ZmZmZikgPT0gMCkgeyB4ID4+PSAxNjsgciArPSAxNjsgfQppZigoeCYweGZmKSA9PSAwKSB7IHggPj49IDg7IHIgKz0gODsgfQppZigoeCYweGYpID09IDApIHsgeCA+Pj0gNDsgciArPSA0OyB9CmlmKCh4JjMpID09IDApIHsgeCA+Pj0gMjsgciArPSAyOyB9CmlmKCh4JjEpID09IDApICsrcjsKcmV0dXJuIHI7Cn0KCi8vKHB1YmxpYykgcmV0dXJucyBpbmRleCBvZiBsb3dlc3QgMS1iaXQgKG9yIC0xIGlmIG5vbmUpCmZ1bmN0aW9uIGJuR2V0TG93ZXN0U2V0Qml0KCkgewpmb3IodmFyIGkgPSAwOyBpIDwgdGhpcy50OyArK2kpCiBpZih0aGlzLmRhdGFbaV0gIT0gMCkgcmV0dXJuIGkqdGhpcy5EQitsYml0KHRoaXMuZGF0YVtpXSk7CmlmKHRoaXMucyA8IDApIHJldHVybiB0aGlzLnQqdGhpcy5EQjsKcmV0dXJuIC0xOwp9CgovL3JldHVybiBudW1iZXIgb2YgMSBiaXRzIGluIHgKZnVuY3Rpb24gY2JpdCh4KSB7CnZhciByID0gMDsKd2hpbGUoeCAhPSAwKSB7IHggJj0geC0xOyArK3I7IH0KcmV0dXJuIHI7Cn0KCi8vKHB1YmxpYykgcmV0dXJuIG51bWJlciBvZiBzZXQgYml0cwpmdW5jdGlvbiBibkJpdENvdW50KCkgewp2YXIgciA9IDAsIHggPSB0aGlzLnMmdGhpcy5ETTsKZm9yKHZhciBpID0gMDsgaSA8IHRoaXMudDsgKytpKSByICs9IGNiaXQodGhpcy5kYXRhW2ldXngpOwpyZXR1cm4gcjsKfQoKLy8ocHVibGljKSB0cnVlIGlmZiBudGggYml0IGlzIHNldApmdW5jdGlvbiBiblRlc3RCaXQobikgewp2YXIgaiA9IE1hdGguZmxvb3Iobi90aGlzLkRCKTsKaWYoaiA+PSB0aGlzLnQpIHJldHVybih0aGlzLnMhPTApOwpyZXR1cm4oKHRoaXMuZGF0YVtqXSYoMTw8KG4ldGhpcy5EQikpKSE9MCk7Cn0KCi8vKHByb3RlY3RlZCkgdGhpcyBvcCAoMTw8bikKZnVuY3Rpb24gYm5wQ2hhbmdlQml0KG4sb3ApIHsKdmFyIHIgPSBCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQobik7CnRoaXMuYml0d2lzZVRvKHIsb3Ascik7CnJldHVybiByOwp9CgovLyhwdWJsaWMpIHRoaXMgfCAoMTw8bikKZnVuY3Rpb24gYm5TZXRCaXQobikgeyByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobixvcF9vcik7IH0KCi8vKHB1YmxpYykgdGhpcyAmIH4oMTw8bikKZnVuY3Rpb24gYm5DbGVhckJpdChuKSB7IHJldHVybiB0aGlzLmNoYW5nZUJpdChuLG9wX2FuZG5vdCk7IH0KCi8vKHB1YmxpYykgdGhpcyBeICgxPDxuKQpmdW5jdGlvbiBibkZsaXBCaXQobikgeyByZXR1cm4gdGhpcy5jaGFuZ2VCaXQobixvcF94b3IpOyB9CgovLyhwcm90ZWN0ZWQpIHIgPSB0aGlzICsgYQpmdW5jdGlvbiBibnBBZGRUbyhhLHIpIHsKdmFyIGkgPSAwLCBjID0gMCwgbSA9IE1hdGgubWluKGEudCx0aGlzLnQpOwp3aGlsZShpIDwgbSkgewogYyArPSB0aGlzLmRhdGFbaV0rYS5kYXRhW2ldOwogci5kYXRhW2krK10gPSBjJnRoaXMuRE07CiBjID4+PSB0aGlzLkRCOwp9CmlmKGEudCA8IHRoaXMudCkgewogYyArPSBhLnM7CiB3aGlsZShpIDwgdGhpcy50KSB7CiAgIGMgKz0gdGhpcy5kYXRhW2ldOwogICByLmRhdGFbaSsrXSA9IGMmdGhpcy5ETTsKICAgYyA+Pj0gdGhpcy5EQjsKIH0KIGMgKz0gdGhpcy5zOwp9IGVsc2UgewogYyArPSB0aGlzLnM7CiB3aGlsZShpIDwgYS50KSB7CiAgIGMgKz0gYS5kYXRhW2ldOwogICByLmRhdGFbaSsrXSA9IGMmdGhpcy5ETTsKICAgYyA+Pj0gdGhpcy5EQjsKIH0KIGMgKz0gYS5zOwp9CnIucyA9IChjPDApPy0xOjA7CmlmKGMgPiAwKSByLmRhdGFbaSsrXSA9IGM7CmVsc2UgaWYoYyA8IC0xKSByLmRhdGFbaSsrXSA9IHRoaXMuRFYrYzsKci50ID0gaTsKci5jbGFtcCgpOwp9CgovLyhwdWJsaWMpIHRoaXMgKyBhCmZ1bmN0aW9uIGJuQWRkKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5hZGRUbyhhLHIpOyByZXR1cm4gcjsgfQoKLy8ocHVibGljKSB0aGlzIC0gYQpmdW5jdGlvbiBiblN1YnRyYWN0KGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5zdWJUbyhhLHIpOyByZXR1cm4gcjsgfQoKLy8ocHVibGljKSB0aGlzICogYQpmdW5jdGlvbiBibk11bHRpcGx5KGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5tdWx0aXBseVRvKGEscik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIHRoaXMgLyBhCmZ1bmN0aW9uIGJuRGl2aWRlKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5kaXZSZW1UbyhhLHIsbnVsbCk7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIHRoaXMgJSBhCmZ1bmN0aW9uIGJuUmVtYWluZGVyKGEpIHsgdmFyIHIgPSBuYmkoKTsgdGhpcy5kaXZSZW1UbyhhLG51bGwscik7IHJldHVybiByOyB9CgovLyhwdWJsaWMpIFt0aGlzL2EsdGhpcyVhXQpmdW5jdGlvbiBibkRpdmlkZUFuZFJlbWFpbmRlcihhKSB7CnZhciBxID0gbmJpKCksIHIgPSBuYmkoKTsKdGhpcy5kaXZSZW1UbyhhLHEscik7CnJldHVybiBuZXcgQXJyYXkocSxyKTsKfQoKLy8ocHJvdGVjdGVkKSB0aGlzICo9IG4sIHRoaXMgPj0gMCwgMSA8IG4gPCBEVgpmdW5jdGlvbiBibnBETXVsdGlwbHkobikgewp0aGlzLmRhdGFbdGhpcy50XSA9IHRoaXMuYW0oMCxuLTEsdGhpcywwLDAsdGhpcy50KTsKKyt0aGlzLnQ7CnRoaXMuY2xhbXAoKTsKfQoKLy8ocHJvdGVjdGVkKSB0aGlzICs9IG4gPDwgdyB3b3JkcywgdGhpcyA+PSAwCmZ1bmN0aW9uIGJucERBZGRPZmZzZXQobix3KSB7CmlmKG4gPT0gMCkgcmV0dXJuOwp3aGlsZSh0aGlzLnQgPD0gdykgdGhpcy5kYXRhW3RoaXMudCsrXSA9IDA7CnRoaXMuZGF0YVt3XSArPSBuOwp3aGlsZSh0aGlzLmRhdGFbd10gPj0gdGhpcy5EVikgewogdGhpcy5kYXRhW3ddIC09IHRoaXMuRFY7CiBpZigrK3cgPj0gdGhpcy50KSB0aGlzLmRhdGFbdGhpcy50KytdID0gMDsKICsrdGhpcy5kYXRhW3ddOwp9Cn0KCi8vQSAibnVsbCIgcmVkdWNlcgpmdW5jdGlvbiBOdWxsRXhwKCkge30KZnVuY3Rpb24gbk5vcCh4KSB7IHJldHVybiB4OyB9CmZ1bmN0aW9uIG5NdWxUbyh4LHkscikgeyB4Lm11bHRpcGx5VG8oeSxyKTsgfQpmdW5jdGlvbiBuU3FyVG8oeCxyKSB7IHguc3F1YXJlVG8ocik7IH0KCk51bGxFeHAucHJvdG90eXBlLmNvbnZlcnQgPSBuTm9wOwpOdWxsRXhwLnByb3RvdHlwZS5yZXZlcnQgPSBuTm9wOwpOdWxsRXhwLnByb3RvdHlwZS5tdWxUbyA9IG5NdWxUbzsKTnVsbEV4cC5wcm90b3R5cGUuc3FyVG8gPSBuU3FyVG87CgovLyhwdWJsaWMpIHRoaXNeZQpmdW5jdGlvbiBiblBvdyhlKSB7IHJldHVybiB0aGlzLmV4cChlLG5ldyBOdWxsRXhwKCkpOyB9CgovLyhwcm90ZWN0ZWQpIHIgPSBsb3dlciBuIHdvcmRzIG9mICJ0aGlzICogYSIsIGEudCA8PSBuCi8vInRoaXMiIHNob3VsZCBiZSB0aGUgbGFyZ2VyIG9uZSBpZiBhcHByb3ByaWF0ZS4KZnVuY3Rpb24gYm5wTXVsdGlwbHlMb3dlclRvKGEsbixyKSB7CnZhciBpID0gTWF0aC5taW4odGhpcy50K2EudCxuKTsKci5zID0gMDsgLy8gYXNzdW1lcyBhLHRoaXMgPj0gMApyLnQgPSBpOwp3aGlsZShpID4gMCkgci5kYXRhWy0taV0gPSAwOwp2YXIgajsKZm9yKGogPSByLnQtdGhpcy50OyBpIDwgajsgKytpKSByLmRhdGFbaSt0aGlzLnRdID0gdGhpcy5hbSgwLGEuZGF0YVtpXSxyLGksMCx0aGlzLnQpOwpmb3IoaiA9IE1hdGgubWluKGEudCxuKTsgaSA8IGo7ICsraSkgdGhpcy5hbSgwLGEuZGF0YVtpXSxyLGksMCxuLWkpOwpyLmNsYW1wKCk7Cn0KCi8vKHByb3RlY3RlZCkgciA9ICJ0aGlzICogYSIgd2l0aG91dCBsb3dlciBuIHdvcmRzLCBuID4gMAovLyJ0aGlzIiBzaG91bGQgYmUgdGhlIGxhcmdlciBvbmUgaWYgYXBwcm9wcmlhdGUuCmZ1bmN0aW9uIGJucE11bHRpcGx5VXBwZXJUbyhhLG4scikgewotLW47CnZhciBpID0gci50ID0gdGhpcy50K2EudC1uOwpyLnMgPSAwOyAvLyBhc3N1bWVzIGEsdGhpcyA+PSAwCndoaWxlKC0taSA+PSAwKSByLmRhdGFbaV0gPSAwOwpmb3IoaSA9IE1hdGgubWF4KG4tdGhpcy50LDApOyBpIDwgYS50OyArK2kpCiByLmRhdGFbdGhpcy50K2ktbl0gPSB0aGlzLmFtKG4taSxhLmRhdGFbaV0sciwwLDAsdGhpcy50K2ktbik7CnIuY2xhbXAoKTsKci5kclNoaWZ0VG8oMSxyKTsKfQoKLy9CYXJyZXR0IG1vZHVsYXIgcmVkdWN0aW9uCmZ1bmN0aW9uIEJhcnJldHQobSkgewovLyBzZXR1cCBCYXJyZXR0CnRoaXMucjIgPSBuYmkoKTsKdGhpcy5xMyA9IG5iaSgpOwpCaWdJbnRlZ2VyLk9ORS5kbFNoaWZ0VG8oMiptLnQsdGhpcy5yMik7CnRoaXMubXUgPSB0aGlzLnIyLmRpdmlkZShtKTsKdGhpcy5tID0gbTsKfQoKZnVuY3Rpb24gYmFycmV0dENvbnZlcnQoeCkgewppZih4LnMgPCAwIHx8IHgudCA+IDIqdGhpcy5tLnQpIHJldHVybiB4Lm1vZCh0aGlzLm0pOwplbHNlIGlmKHguY29tcGFyZVRvKHRoaXMubSkgPCAwKSByZXR1cm4geDsKZWxzZSB7IHZhciByID0gbmJpKCk7IHguY29weVRvKHIpOyB0aGlzLnJlZHVjZShyKTsgcmV0dXJuIHI7IH0KfQoKZnVuY3Rpb24gYmFycmV0dFJldmVydCh4KSB7IHJldHVybiB4OyB9CgovL3ggPSB4IG1vZCBtIChIQUMgMTQuNDIpCmZ1bmN0aW9uIGJhcnJldHRSZWR1Y2UoeCkgewp4LmRyU2hpZnRUbyh0aGlzLm0udC0xLHRoaXMucjIpOwppZih4LnQgPiB0aGlzLm0udCsxKSB7IHgudCA9IHRoaXMubS50KzE7IHguY2xhbXAoKTsgfQp0aGlzLm11Lm11bHRpcGx5VXBwZXJUbyh0aGlzLnIyLHRoaXMubS50KzEsdGhpcy5xMyk7CnRoaXMubS5tdWx0aXBseUxvd2VyVG8odGhpcy5xMyx0aGlzLm0udCsxLHRoaXMucjIpOwp3aGlsZSh4LmNvbXBhcmVUbyh0aGlzLnIyKSA8IDApIHguZEFkZE9mZnNldCgxLHRoaXMubS50KzEpOwp4LnN1YlRvKHRoaXMucjIseCk7CndoaWxlKHguY29tcGFyZVRvKHRoaXMubSkgPj0gMCkgeC5zdWJUbyh0aGlzLm0seCk7Cn0KCi8vciA9IHheMiBtb2QgbTsgeCAhPSByCmZ1bmN0aW9uIGJhcnJldHRTcXJUbyh4LHIpIHsgeC5zcXVhcmVUbyhyKTsgdGhpcy5yZWR1Y2Uocik7IH0KCi8vciA9IHgqeSBtb2QgbTsgeCx5ICE9IHIKZnVuY3Rpb24gYmFycmV0dE11bFRvKHgseSxyKSB7IHgubXVsdGlwbHlUbyh5LHIpOyB0aGlzLnJlZHVjZShyKTsgfQoKQmFycmV0dC5wcm90b3R5cGUuY29udmVydCA9IGJhcnJldHRDb252ZXJ0OwpCYXJyZXR0LnByb3RvdHlwZS5yZXZlcnQgPSBiYXJyZXR0UmV2ZXJ0OwpCYXJyZXR0LnByb3RvdHlwZS5yZWR1Y2UgPSBiYXJyZXR0UmVkdWNlOwpCYXJyZXR0LnByb3RvdHlwZS5tdWxUbyA9IGJhcnJldHRNdWxUbzsKQmFycmV0dC5wcm90b3R5cGUuc3FyVG8gPSBiYXJyZXR0U3FyVG87CgovLyhwdWJsaWMpIHRoaXNeZSAlIG0gKEhBQyAxNC44NSkKZnVuY3Rpb24gYm5Nb2RQb3coZSxtKSB7CnZhciBpID0gZS5iaXRMZW5ndGgoKSwgaywgciA9IG5idigxKSwgejsKaWYoaSA8PSAwKSByZXR1cm4gcjsKZWxzZSBpZihpIDwgMTgpIGsgPSAxOwplbHNlIGlmKGkgPCA0OCkgayA9IDM7CmVsc2UgaWYoaSA8IDE0NCkgayA9IDQ7CmVsc2UgaWYoaSA8IDc2OCkgayA9IDU7CmVsc2UgayA9IDY7CmlmKGkgPCA4KQogeiA9IG5ldyBDbGFzc2ljKG0pOwplbHNlIGlmKG0uaXNFdmVuKCkpCiB6ID0gbmV3IEJhcnJldHQobSk7CmVsc2UKIHogPSBuZXcgTW9udGdvbWVyeShtKTsKCi8vIHByZWNvbXB1dGF0aW9uCnZhciBnID0gbmV3IEFycmF5KCksIG4gPSAzLCBrMSA9IGstMSwga20gPSAoMTw8ayktMTsKZ1sxXSA9IHouY29udmVydCh0aGlzKTsKaWYoayA+IDEpIHsKIHZhciBnMiA9IG5iaSgpOwogei5zcXJUbyhnWzFdLGcyKTsKIHdoaWxlKG4gPD0ga20pIHsKICAgZ1tuXSA9IG5iaSgpOwogICB6Lm11bFRvKGcyLGdbbi0yXSxnW25dKTsKICAgbiArPSAyOwogfQp9Cgp2YXIgaiA9IGUudC0xLCB3LCBpczEgPSB0cnVlLCByMiA9IG5iaSgpLCB0OwppID0gbmJpdHMoZS5kYXRhW2pdKS0xOwp3aGlsZShqID49IDApIHsKIGlmKGkgPj0gazEpIHcgPSAoZS5kYXRhW2pdPj4oaS1rMSkpJmttOwogZWxzZSB7CiAgIHcgPSAoZS5kYXRhW2pdJigoMTw8KGkrMSkpLTEpKTw8KGsxLWkpOwogICBpZihqID4gMCkgdyB8PSBlLmRhdGFbai0xXT4+KHRoaXMuREIraS1rMSk7CiB9CgogbiA9IGs7CiB3aGlsZSgodyYxKSA9PSAwKSB7IHcgPj49IDE7IC0tbjsgfQogaWYoKGkgLT0gbikgPCAwKSB7IGkgKz0gdGhpcy5EQjsgLS1qOyB9CiBpZihpczEpIHsgIC8vIHJldCA9PSAxLCBkb24ndCBib3RoZXIgc3F1YXJpbmcgb3IgbXVsdGlwbHlpbmcgaXQKICAgZ1t3XS5jb3B5VG8ocik7CiAgIGlzMSA9IGZhbHNlOwogfSBlbHNlIHsKICAgd2hpbGUobiA+IDEpIHsgei5zcXJUbyhyLHIyKTsgei5zcXJUbyhyMixyKTsgbiAtPSAyOyB9CiAgIGlmKG4gPiAwKSB6LnNxclRvKHIscjIpOyBlbHNlIHsgdCA9IHI7IHIgPSByMjsgcjIgPSB0OyB9CiAgIHoubXVsVG8ocjIsZ1t3XSxyKTsKIH0KCiB3aGlsZShqID49IDAgJiYgKGUuZGF0YVtqXSYoMTw8aSkpID09IDApIHsKICAgei5zcXJUbyhyLHIyKTsgdCA9IHI7IHIgPSByMjsgcjIgPSB0OwogICBpZigtLWkgPCAwKSB7IGkgPSB0aGlzLkRCLTE7IC0tajsgfQogfQp9CnJldHVybiB6LnJldmVydChyKTsKfQoKLy8ocHVibGljKSBnY2QodGhpcyxhKSAoSEFDIDE0LjU0KQpmdW5jdGlvbiBibkdDRChhKSB7CnZhciB4ID0gKHRoaXMuczwwKT90aGlzLm5lZ2F0ZSgpOnRoaXMuY2xvbmUoKTsKdmFyIHkgPSAoYS5zPDApP2EubmVnYXRlKCk6YS5jbG9uZSgpOwppZih4LmNvbXBhcmVUbyh5KSA8IDApIHsgdmFyIHQgPSB4OyB4ID0geTsgeSA9IHQ7IH0KdmFyIGkgPSB4LmdldExvd2VzdFNldEJpdCgpLCBnID0geS5nZXRMb3dlc3RTZXRCaXQoKTsKaWYoZyA8IDApIHJldHVybiB4OwppZihpIDwgZykgZyA9IGk7CmlmKGcgPiAwKSB7CiB4LnJTaGlmdFRvKGcseCk7CiB5LnJTaGlmdFRvKGcseSk7Cn0Kd2hpbGUoeC5zaWdudW0oKSA+IDApIHsKIGlmKChpID0geC5nZXRMb3dlc3RTZXRCaXQoKSkgPiAwKSB4LnJTaGlmdFRvKGkseCk7CiBpZigoaSA9IHkuZ2V0TG93ZXN0U2V0Qml0KCkpID4gMCkgeS5yU2hpZnRUbyhpLHkpOwogaWYoeC5jb21wYXJlVG8oeSkgPj0gMCkgewogICB4LnN1YlRvKHkseCk7CiAgIHguclNoaWZ0VG8oMSx4KTsKIH0gZWxzZSB7CiAgIHkuc3ViVG8oeCx5KTsKICAgeS5yU2hpZnRUbygxLHkpOwogfQp9CmlmKGcgPiAwKSB5LmxTaGlmdFRvKGcseSk7CnJldHVybiB5Owp9CgovLyhwcm90ZWN0ZWQpIHRoaXMgJSBuLCBuIDwgMl4yNgpmdW5jdGlvbiBibnBNb2RJbnQobikgewppZihuIDw9IDApIHJldHVybiAwOwp2YXIgZCA9IHRoaXMuRFYlbiwgciA9ICh0aGlzLnM8MCk/bi0xOjA7CmlmKHRoaXMudCA+IDApCiBpZihkID09IDApIHIgPSB0aGlzLmRhdGFbMF0lbjsKIGVsc2UgZm9yKHZhciBpID0gdGhpcy50LTE7IGkgPj0gMDsgLS1pKSByID0gKGQqcit0aGlzLmRhdGFbaV0pJW47CnJldHVybiByOwp9CgovLyhwdWJsaWMpIDEvdGhpcyAlIG0gKEhBQyAxNC42MSkKZnVuY3Rpb24gYm5Nb2RJbnZlcnNlKG0pIHsKdmFyIGFjID0gbS5pc0V2ZW4oKTsKaWYoKHRoaXMuaXNFdmVuKCkgJiYgYWMpIHx8IG0uc2lnbnVtKCkgPT0gMCkgcmV0dXJuIEJpZ0ludGVnZXIuWkVSTzsKdmFyIHUgPSBtLmNsb25lKCksIHYgPSB0aGlzLmNsb25lKCk7CnZhciBhID0gbmJ2KDEpLCBiID0gbmJ2KDApLCBjID0gbmJ2KDApLCBkID0gbmJ2KDEpOwp3aGlsZSh1LnNpZ251bSgpICE9IDApIHsKIHdoaWxlKHUuaXNFdmVuKCkpIHsKICAgdS5yU2hpZnRUbygxLHUpOwogICBpZihhYykgewogICAgIGlmKCFhLmlzRXZlbigpIHx8ICFiLmlzRXZlbigpKSB7IGEuYWRkVG8odGhpcyxhKTsgYi5zdWJUbyhtLGIpOyB9CiAgICAgYS5yU2hpZnRUbygxLGEpOwogICB9IGVsc2UgaWYoIWIuaXNFdmVuKCkpIGIuc3ViVG8obSxiKTsKICAgYi5yU2hpZnRUbygxLGIpOwogfQogd2hpbGUodi5pc0V2ZW4oKSkgewogICB2LnJTaGlmdFRvKDEsdik7CiAgIGlmKGFjKSB7CiAgICAgaWYoIWMuaXNFdmVuKCkgfHwgIWQuaXNFdmVuKCkpIHsgYy5hZGRUbyh0aGlzLGMpOyBkLnN1YlRvKG0sZCk7IH0KICAgICBjLnJTaGlmdFRvKDEsYyk7CiAgIH0gZWxzZSBpZighZC5pc0V2ZW4oKSkgZC5zdWJUbyhtLGQpOwogICBkLnJTaGlmdFRvKDEsZCk7CiB9CiBpZih1LmNvbXBhcmVUbyh2KSA+PSAwKSB7CiAgIHUuc3ViVG8odix1KTsKICAgaWYoYWMpIGEuc3ViVG8oYyxhKTsKICAgYi5zdWJUbyhkLGIpOwogfSBlbHNlIHsKICAgdi5zdWJUbyh1LHYpOwogICBpZihhYykgYy5zdWJUbyhhLGMpOwogICBkLnN1YlRvKGIsZCk7CiB9Cn0KaWYodi5jb21wYXJlVG8oQmlnSW50ZWdlci5PTkUpICE9IDApIHJldHVybiBCaWdJbnRlZ2VyLlpFUk87CmlmKGQuY29tcGFyZVRvKG0pID49IDApIHJldHVybiBkLnN1YnRyYWN0KG0pOwppZihkLnNpZ251bSgpIDwgMCkgZC5hZGRUbyhtLGQpOyBlbHNlIHJldHVybiBkOwppZihkLnNpZ251bSgpIDwgMCkgcmV0dXJuIGQuYWRkKG0pOyBlbHNlIHJldHVybiBkOwp9Cgp2YXIgbG93cHJpbWVzID0gWzIsMyw1LDcsMTEsMTMsMTcsMTksMjMsMjksMzEsMzcsNDEsNDMsNDcsNTMsNTksNjEsNjcsNzEsNzMsNzksODMsODksOTcsMTAxLDEwMywxMDcsMTA5LDExMywxMjcsMTMxLDEzNywxMzksMTQ5LDE1MSwxNTcsMTYzLDE2NywxNzMsMTc5LDE4MSwxOTEsMTkzLDE5NywxOTksMjExLDIyMywyMjcsMjI5LDIzMywyMzksMjQxLDI1MSwyNTcsMjYzLDI2OSwyNzEsMjc3LDI4MSwyODMsMjkzLDMwNywzMTEsMzEzLDMxNywzMzEsMzM3LDM0NywzNDksMzUzLDM1OSwzNjcsMzczLDM3OSwzODMsMzg5LDM5Nyw0MDEsNDA5LDQxOSw0MjEsNDMxLDQzMyw0MzksNDQzLDQ0OSw0NTcsNDYxLDQ2Myw0NjcsNDc5LDQ4Nyw0OTEsNDk5LDUwMyw1MDldOwp2YXIgbHBsaW0gPSAoMTw8MjYpL2xvd3ByaW1lc1tsb3dwcmltZXMubGVuZ3RoLTFdOwoKLy8ocHVibGljKSB0ZXN0IHByaW1hbGl0eSB3aXRoIGNlcnRhaW50eSA+PSAxLS41XnQKZnVuY3Rpb24gYm5Jc1Byb2JhYmxlUHJpbWUodCkgewp2YXIgaSwgeCA9IHRoaXMuYWJzKCk7CmlmKHgudCA9PSAxICYmIHguZGF0YVswXSA8PSBsb3dwcmltZXNbbG93cHJpbWVzLmxlbmd0aC0xXSkgewogZm9yKGkgPSAwOyBpIDwgbG93cHJpbWVzLmxlbmd0aDsgKytpKQogICBpZih4LmRhdGFbMF0gPT0gbG93cHJpbWVzW2ldKSByZXR1cm4gdHJ1ZTsKIHJldHVybiBmYWxzZTsKfQppZih4LmlzRXZlbigpKSByZXR1cm4gZmFsc2U7CmkgPSAxOwp3aGlsZShpIDwgbG93cHJpbWVzLmxlbmd0aCkgewogdmFyIG0gPSBsb3dwcmltZXNbaV0sIGogPSBpKzE7CiB3aGlsZShqIDwgbG93cHJpbWVzLmxlbmd0aCAmJiBtIDwgbHBsaW0pIG0gKj0gbG93cHJpbWVzW2orK107CiBtID0geC5tb2RJbnQobSk7CiB3aGlsZShpIDwgaikgaWYobSVsb3dwcmltZXNbaSsrXSA9PSAwKSByZXR1cm4gZmFsc2U7Cn0KcmV0dXJuIHgubWlsbGVyUmFiaW4odCk7Cn0KCi8vKHByb3RlY3RlZCkgdHJ1ZSBpZiBwcm9iYWJseSBwcmltZSAoSEFDIDQuMjQsIE1pbGxlci1SYWJpbikKZnVuY3Rpb24gYm5wTWlsbGVyUmFiaW4odCkgewp2YXIgbjEgPSB0aGlzLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTsKdmFyIGsgPSBuMS5nZXRMb3dlc3RTZXRCaXQoKTsKaWYoayA8PSAwKSByZXR1cm4gZmFsc2U7CnZhciByID0gbjEuc2hpZnRSaWdodChrKTsKdmFyIHBybmcgPSBibkdldFBybmcoKTsKdmFyIGE7CmZvcih2YXIgaSA9IDA7IGkgPCB0OyArK2kpIHsKIC8vIHNlbGVjdCB3aXRuZXNzICdhJyBhdCByYW5kb20gZnJvbSBiZXR3ZWVuIDEgYW5kIG4xCiBkbyB7CiAgIGEgPSBuZXcgQmlnSW50ZWdlcih0aGlzLmJpdExlbmd0aCgpLCBwcm5nKTsKIH0KIHdoaWxlKGEuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA8PSAwIHx8IGEuY29tcGFyZVRvKG4xKSA+PSAwKTsKIHZhciB5ID0gYS5tb2RQb3cocix0aGlzKTsKIGlmKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPSAwICYmIHkuY29tcGFyZVRvKG4xKSAhPSAwKSB7CiAgIHZhciBqID0gMTsKICAgd2hpbGUoaisrIDwgayAmJiB5LmNvbXBhcmVUbyhuMSkgIT0gMCkgewogICAgIHkgPSB5Lm1vZFBvd0ludCgyLHRoaXMpOwogICAgIGlmKHkuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSA9PSAwKSByZXR1cm4gZmFsc2U7CiAgIH0KICAgaWYoeS5jb21wYXJlVG8objEpICE9IDApIHJldHVybiBmYWxzZTsKIH0KfQpyZXR1cm4gdHJ1ZTsKfQoKLy8gZ2V0IHBzZXVkbyByYW5kb20gbnVtYmVyIGdlbmVyYXRvcgpmdW5jdGlvbiBibkdldFBybmcoKSB7CiAgLy8gY3JlYXRlIHBybmcgd2l0aCBhcGkgdGhhdCBtYXRjaGVzIEJpZ0ludGVnZXIgc2VjdXJlIHJhbmRvbQogIHJldHVybiB7CiAgICAvLyB4IGlzIGFuIGFycmF5IHRvIGZpbGwgd2l0aCBieXRlcwogICAgbmV4dEJ5dGVzOiBmdW5jdGlvbih4KSB7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgeFtpXSA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDB4MDEwMCk7CiAgICAgIH0KICAgIH0KICB9Owp9CgovL3Byb3RlY3RlZApCaWdJbnRlZ2VyLnByb3RvdHlwZS5jaHVua1NpemUgPSBibnBDaHVua1NpemU7CkJpZ0ludGVnZXIucHJvdG90eXBlLnRvUmFkaXggPSBibnBUb1JhZGl4OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5mcm9tUmFkaXggPSBibnBGcm9tUmFkaXg7CkJpZ0ludGVnZXIucHJvdG90eXBlLmZyb21OdW1iZXIgPSBibnBGcm9tTnVtYmVyOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXR3aXNlVG8gPSBibnBCaXR3aXNlVG87CkJpZ0ludGVnZXIucHJvdG90eXBlLmNoYW5nZUJpdCA9IGJucENoYW5nZUJpdDsKQmlnSW50ZWdlci5wcm90b3R5cGUuYWRkVG8gPSBibnBBZGRUbzsKQmlnSW50ZWdlci5wcm90b3R5cGUuZE11bHRpcGx5ID0gYm5wRE11bHRpcGx5OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kQWRkT2Zmc2V0ID0gYm5wREFkZE9mZnNldDsKQmlnSW50ZWdlci5wcm90b3R5cGUubXVsdGlwbHlMb3dlclRvID0gYm5wTXVsdGlwbHlMb3dlclRvOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5tdWx0aXBseVVwcGVyVG8gPSBibnBNdWx0aXBseVVwcGVyVG87CkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludCA9IGJucE1vZEludDsKQmlnSW50ZWdlci5wcm90b3R5cGUubWlsbGVyUmFiaW4gPSBibnBNaWxsZXJSYWJpbjsKCi8vcHVibGljCkJpZ0ludGVnZXIucHJvdG90eXBlLmNsb25lID0gYm5DbG9uZTsKQmlnSW50ZWdlci5wcm90b3R5cGUuaW50VmFsdWUgPSBibkludFZhbHVlOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5ieXRlVmFsdWUgPSBibkJ5dGVWYWx1ZTsKQmlnSW50ZWdlci5wcm90b3R5cGUuc2hvcnRWYWx1ZSA9IGJuU2hvcnRWYWx1ZTsKQmlnSW50ZWdlci5wcm90b3R5cGUuc2lnbnVtID0gYm5TaWdOdW07CkJpZ0ludGVnZXIucHJvdG90eXBlLnRvQnl0ZUFycmF5ID0gYm5Ub0J5dGVBcnJheTsKQmlnSW50ZWdlci5wcm90b3R5cGUuZXF1YWxzID0gYm5FcXVhbHM7CkJpZ0ludGVnZXIucHJvdG90eXBlLm1pbiA9IGJuTWluOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5tYXggPSBibk1heDsKQmlnSW50ZWdlci5wcm90b3R5cGUuYW5kID0gYm5BbmQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLm9yID0gYm5PcjsKQmlnSW50ZWdlci5wcm90b3R5cGUueG9yID0gYm5Yb3I7CkJpZ0ludGVnZXIucHJvdG90eXBlLmFuZE5vdCA9IGJuQW5kTm90OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5ub3QgPSBibk5vdDsKQmlnSW50ZWdlci5wcm90b3R5cGUuc2hpZnRMZWZ0ID0gYm5TaGlmdExlZnQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLnNoaWZ0UmlnaHQgPSBiblNoaWZ0UmlnaHQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLmdldExvd2VzdFNldEJpdCA9IGJuR2V0TG93ZXN0U2V0Qml0OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5iaXRDb3VudCA9IGJuQml0Q291bnQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLnRlc3RCaXQgPSBiblRlc3RCaXQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLnNldEJpdCA9IGJuU2V0Qml0OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5jbGVhckJpdCA9IGJuQ2xlYXJCaXQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLmZsaXBCaXQgPSBibkZsaXBCaXQ7CkJpZ0ludGVnZXIucHJvdG90eXBlLmFkZCA9IGJuQWRkOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5zdWJ0cmFjdCA9IGJuU3VidHJhY3Q7CkJpZ0ludGVnZXIucHJvdG90eXBlLm11bHRpcGx5ID0gYm5NdWx0aXBseTsKQmlnSW50ZWdlci5wcm90b3R5cGUuZGl2aWRlID0gYm5EaXZpZGU7CkJpZ0ludGVnZXIucHJvdG90eXBlLnJlbWFpbmRlciA9IGJuUmVtYWluZGVyOwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5kaXZpZGVBbmRSZW1haW5kZXIgPSBibkRpdmlkZUFuZFJlbWFpbmRlcjsKQmlnSW50ZWdlci5wcm90b3R5cGUubW9kUG93ID0gYm5Nb2RQb3c7CkJpZ0ludGVnZXIucHJvdG90eXBlLm1vZEludmVyc2UgPSBibk1vZEludmVyc2U7CkJpZ0ludGVnZXIucHJvdG90eXBlLnBvdyA9IGJuUG93OwpCaWdJbnRlZ2VyLnByb3RvdHlwZS5nY2QgPSBibkdDRDsKQmlnSW50ZWdlci5wcm90b3R5cGUuaXNQcm9iYWJsZVByaW1lID0gYm5Jc1Byb2JhYmxlUHJpbWU7CgovL0JpZ0ludGVnZXIgaW50ZXJmYWNlcyBub3QgaW1wbGVtZW50ZWQgaW4ganNibjoKCi8vQmlnSW50ZWdlcihpbnQgc2lnbnVtLCBieXRlW10gbWFnbml0dWRlKQovL2RvdWJsZSBkb3VibGVWYWx1ZSgpCi8vZmxvYXQgZmxvYXRWYWx1ZSgpCi8vaW50IGhhc2hDb2RlKCkKLy9sb25nIGxvbmdWYWx1ZSgpCi8vc3RhdGljIEJpZ0ludGVnZXIgdmFsdWVPZihsb25nIHZhbCkKCmZvcmdlLmpzYm4gPSBmb3JnZS5qc2JuIHx8IHt9Owpmb3JnZS5qc2JuLkJpZ0ludGVnZXIgPSBCaWdJbnRlZ2VyOwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAnanNibic7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9qc2JuJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFBhcnRpYWwgaW1wbGVtZW50YXRpb24gb2YgUEtDUyMxIHYyLjI6IFJTQS1PRUFQCiAqCiAqIE1vZGlmaWVkIGJ1dCBiYXNlZCBvbiB0aGUgZm9sbG93aW5nIE1JVCBhbmQgQlNEIGxpY2Vuc2VkIGNvZGU6CiAqCiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9ranVyL2pzandzL2Jsb2IvbWFzdGVyL3JzYS5qczoKICoKICogVGhlICdqc2p3cycoSlNPTiBXZWIgU2lnbmF0dXJlIEphdmFTY3JpcHQgTGlicmFyeSkgTGljZW5zZQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIgS2VuamkgVXJ1c2hpbWEKICoKICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weQogKiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSAiU29mdHdhcmUiKSwgdG8gZGVhbAogKiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzCiAqIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwKICogY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzCiAqIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiAqCiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluCiAqIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgogKgogKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgogKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCiAqIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKICogT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTgogKiBUSEUgU09GVFdBUkUuCiAqCiAqIGh0dHA6Ly93ZWJyc2EuY3ZzLnNvdXJjZWZvcmdlLm5ldC92aWV3dmMvd2VicnNhL0NsaWVudC9SU0FFUy1PQUVQLmpzP2NvbnRlbnQtdHlwZT10ZXh0JTJGcGxhaW46CiAqCiAqIFJTQUVTLU9BRVAuanMKICogJElkOiBSU0FFUy1PQUVQLmpzLHYgMS4xLjEuMSAyMDAzLzAzLzE5IDE1OjM3OjIwIGVsbGlzcHJpdGNoYXJkIEV4cCAkCiAqIEphdmFTY3JpcHQgSW1wbGVtZW50YXRpb24gb2YgUEtDUyAjMSB2Mi4xIFJTQSBDUllQVE9HUkFQSFkgU1RBTkRBUkQgKFJTQSBMYWJvcmF0b3JpZXMsIEp1bmUgMTQsIDIwMDIpCiAqIENvcHlyaWdodCAoQykgRWxsaXMgUHJpdGNoYXJkLCBHdWFyZGlhbiBVbmxpbWl0ZWQgMjAwMy4KICogQ29udGFjdDogZWxsaXNAbnVraW5ldGljcy5jb20KICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJTRCBMaWNlbnNlLgogKgogKiBPZmZpY2lhbCBkb2N1bWVudGF0aW9uOiBodHRwOi8vd3d3LnJzYS5jb20vcnNhbGFicy9ub2RlLmFzcD9pZD0yMTI1CiAqCiAqIEBhdXRob3IgRXZhbiBKb25lcyAoaHR0cDovL2V2YW5qb25lcy5jYS8pCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMy0yMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKLy8gc2hvcnRjdXQgZm9yIFBLQ1MjMSBBUEkKdmFyIHBrY3MxID0gZm9yZ2UucGtjczEgPSBmb3JnZS5wa2NzMSB8fCB7fTsKCi8qKgogKiBFbmNvZGUgdGhlIGdpdmVuIFJTQUVTLU9BRVAgbWVzc2FnZSAoTSkgdXNpbmcga2V5LCB3aXRoIG9wdGlvbmFsIGxhYmVsIChMKQogKiBhbmQgc2VlZC4KICoKICogVGhpcyBtZXRob2QgZG9lcyBub3QgcGVyZm9ybSBSU0EgZW5jcnlwdGlvbiwgaXQgb25seSBlbmNvZGVzIHRoZSBtZXNzYWdlCiAqIHVzaW5nIFJTQUVTLU9BRVAuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIFJTQSBrZXkgdG8gdXNlLgogKiBAcGFyYW0gbWVzc2FnZSB0aGUgbWVzc2FnZSB0byBlbmNvZGUuCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgbGFiZWwgYW4gb3B0aW9uYWwgbGFiZWwgdG8gdXNlLgogKiAgICAgICAgICBzZWVkIHRoZSBzZWVkIHRvIHVzZS4KICogICAgICAgICAgbWQgdGhlIG1lc3NhZ2UgZGlnZXN0IG9iamVjdCB0byB1c2UsIHVuZGVmaW5lZCBmb3IgU0hBLTEuCiAqICAgICAgICAgIG1nZjEgb3B0aW9uYWwgbWdmMSBwYXJhbWV0ZXJzOgogKiAgICAgICAgICAgIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlIGZvciBNR0YxLgogKgogKiBAcmV0dXJuIHRoZSBlbmNvZGVkIG1lc3NhZ2UgYnl0ZXMuCiAqLwpwa2NzMS5lbmNvZGVfcnNhX29hZXAgPSBmdW5jdGlvbihrZXksIG1lc3NhZ2UsIG9wdGlvbnMpIHsKICAvLyBwYXJzZSBhcmd1bWVudHMKICB2YXIgbGFiZWw7CiAgdmFyIHNlZWQ7CiAgdmFyIG1kOwogIHZhciBtZ2YxTWQ7CiAgLy8gbGVnYWN5IGFyZ3MgKGxhYmVsLCBzZWVkLCBtZCkKICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHsKICAgIGxhYmVsID0gb3B0aW9uczsKICAgIHNlZWQgPSBhcmd1bWVudHNbM10gfHwgdW5kZWZpbmVkOwogICAgbWQgPSBhcmd1bWVudHNbNF0gfHwgdW5kZWZpbmVkOwogIH0gZWxzZSBpZihvcHRpb25zKSB7CiAgICBsYWJlbCA9IG9wdGlvbnMubGFiZWwgfHwgdW5kZWZpbmVkOwogICAgc2VlZCA9IG9wdGlvbnMuc2VlZCB8fCB1bmRlZmluZWQ7CiAgICBtZCA9IG9wdGlvbnMubWQgfHwgdW5kZWZpbmVkOwogICAgaWYob3B0aW9ucy5tZ2YxICYmIG9wdGlvbnMubWdmMS5tZCkgewogICAgICBtZ2YxTWQgPSBvcHRpb25zLm1nZjEubWQ7CiAgICB9CiAgfQoKICAvLyBkZWZhdWx0IE9BRVAgdG8gU0hBLTEgbWVzc2FnZSBkaWdlc3QKICBpZighbWQpIHsKICAgIG1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICB9IGVsc2UgewogICAgbWQuc3RhcnQoKTsKICB9CgogIC8vIGRlZmF1bHQgTUdGLTEgdG8gc2FtZSBhcyBPQUVQCiAgaWYoIW1nZjFNZCkgewogICAgbWdmMU1kID0gbWQ7CiAgfQoKICAvLyBjb21wdXRlIGxlbmd0aCBpbiBieXRlcyBhbmQgY2hlY2sgb3V0cHV0CiAgdmFyIGtleUxlbmd0aCA9IE1hdGguY2VpbChrZXkubi5iaXRMZW5ndGgoKSAvIDgpOwogIHZhciBtYXhMZW5ndGggPSBrZXlMZW5ndGggLSAyICogbWQuZGlnZXN0TGVuZ3RoIC0gMjsKICBpZihtZXNzYWdlLmxlbmd0aCA+IG1heExlbmd0aCkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdSU0FFUy1PQUVQIGlucHV0IG1lc3NhZ2UgbGVuZ3RoIGlzIHRvbyBsb25nLicpOwogICAgZXJyb3IubGVuZ3RoID0gbWVzc2FnZS5sZW5ndGg7CiAgICBlcnJvci5tYXhMZW5ndGggPSBtYXhMZW5ndGg7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIGlmKCFsYWJlbCkgewogICAgbGFiZWwgPSAnJzsKICB9CiAgbWQudXBkYXRlKGxhYmVsLCAncmF3Jyk7CiAgdmFyIGxIYXNoID0gbWQuZGlnZXN0KCk7CgogIHZhciBQUyA9ICcnOwogIHZhciBQU19sZW5ndGggPSBtYXhMZW5ndGggLSBtZXNzYWdlLmxlbmd0aDsKICBmb3IgKHZhciBpID0gMDsgaSA8IFBTX2xlbmd0aDsgaSsrKSB7CiAgICBQUyArPSAnXHgwMCc7CiAgfQoKICB2YXIgREIgPSBsSGFzaC5nZXRCeXRlcygpICsgUFMgKyAnXHgwMScgKyBtZXNzYWdlOwoKICBpZighc2VlZCkgewogICAgc2VlZCA9IGZvcmdlLnJhbmRvbS5nZXRCeXRlcyhtZC5kaWdlc3RMZW5ndGgpOwogIH0gZWxzZSBpZihzZWVkLmxlbmd0aCAhPT0gbWQuZGlnZXN0TGVuZ3RoKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0ludmFsaWQgUlNBRVMtT0FFUCBzZWVkLiBUaGUgc2VlZCBsZW5ndGggbXVzdCAnICsKICAgICAgJ21hdGNoIHRoZSBkaWdlc3QgbGVuZ3RoLicpCiAgICBlcnJvci5zZWVkTGVuZ3RoID0gc2VlZC5sZW5ndGg7CiAgICBlcnJvci5kaWdlc3RMZW5ndGggPSBtZC5kaWdlc3RMZW5ndGg7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIHZhciBkYk1hc2sgPSByc2FfbWdmMShzZWVkLCBrZXlMZW5ndGggLSBtZC5kaWdlc3RMZW5ndGggLSAxLCBtZ2YxTWQpOwogIHZhciBtYXNrZWREQiA9IGZvcmdlLnV0aWwueG9yQnl0ZXMoREIsIGRiTWFzaywgREIubGVuZ3RoKTsKCiAgdmFyIHNlZWRNYXNrID0gcnNhX21nZjEobWFza2VkREIsIG1kLmRpZ2VzdExlbmd0aCwgbWdmMU1kKTsKICB2YXIgbWFza2VkU2VlZCA9IGZvcmdlLnV0aWwueG9yQnl0ZXMoc2VlZCwgc2VlZE1hc2ssIHNlZWQubGVuZ3RoKTsKCiAgLy8gcmV0dXJuIGVuY29kZWQgbWVzc2FnZQogIHJldHVybiAnXHgwMCcgKyBtYXNrZWRTZWVkICsgbWFza2VkREI7Cn07CgovKioKICogRGVjb2RlIHRoZSBnaXZlbiBSU0FFUy1PQUVQIGVuY29kZWQgbWVzc2FnZSAoRU0pIHVzaW5nIGtleSwgd2l0aCBvcHRpb25hbAogKiBsYWJlbCAoTCkuCiAqCiAqIFRoaXMgbWV0aG9kIGRvZXMgbm90IHBlcmZvcm0gUlNBIGRlY3J5cHRpb24sIGl0IG9ubHkgZGVjb2RlcyB0aGUgbWVzc2FnZQogKiB1c2luZyBSU0FFUy1PQUVQLgogKgogKiBAcGFyYW0ga2V5IHRoZSBSU0Ega2V5IHRvIHVzZS4KICogQHBhcmFtIGVtIHRoZSBlbmNvZGVkIG1lc3NhZ2UgdG8gZGVjb2RlLgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2U6CiAqICAgICAgICAgIGxhYmVsIGFuIG9wdGlvbmFsIGxhYmVsIHRvIHVzZS4KICogICAgICAgICAgbWQgdGhlIG1lc3NhZ2UgZGlnZXN0IG9iamVjdCB0byB1c2UgZm9yIE9BRVAsIHVuZGVmaW5lZCBmb3IgU0hBLTEuCiAqICAgICAgICAgIG1nZjEgb3B0aW9uYWwgbWdmMSBwYXJhbWV0ZXJzOgogKiAgICAgICAgICAgIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlIGZvciBNR0YxLgogKgogKiBAcmV0dXJuIHRoZSBkZWNvZGVkIG1lc3NhZ2UgYnl0ZXMuCiAqLwpwa2NzMS5kZWNvZGVfcnNhX29hZXAgPSBmdW5jdGlvbihrZXksIGVtLCBvcHRpb25zKSB7CiAgLy8gcGFyc2UgYXJncwogIHZhciBsYWJlbDsKICB2YXIgbWQ7CiAgdmFyIG1nZjFNZDsKICAvLyBsZWdhY3kgYXJncwogIGlmKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJykgewogICAgbGFiZWwgPSBvcHRpb25zOwogICAgbWQgPSBhcmd1bWVudHNbM10gfHwgdW5kZWZpbmVkOwogIH0gZWxzZSBpZihvcHRpb25zKSB7CiAgICBsYWJlbCA9IG9wdGlvbnMubGFiZWwgfHwgdW5kZWZpbmVkOwogICAgbWQgPSBvcHRpb25zLm1kIHx8IHVuZGVmaW5lZDsKICAgIGlmKG9wdGlvbnMubWdmMSAmJiBvcHRpb25zLm1nZjEubWQpIHsKICAgICAgbWdmMU1kID0gb3B0aW9ucy5tZ2YxLm1kOwogICAgfQogIH0KCiAgLy8gY29tcHV0ZSBsZW5ndGggaW4gYnl0ZXMKICB2YXIga2V5TGVuZ3RoID0gTWF0aC5jZWlsKGtleS5uLmJpdExlbmd0aCgpIC8gOCk7CgogIGlmKGVtLmxlbmd0aCAhPT0ga2V5TGVuZ3RoKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1JTQUVTLU9BRVAgZW5jb2RlZCBtZXNzYWdlIGxlbmd0aCBpcyBpbnZhbGlkLicpOwogICAgZXJyb3IubGVuZ3RoID0gZW0ubGVuZ3RoOwogICAgZXJyb3IuZXhwZWN0ZWRMZW5ndGggPSBrZXlMZW5ndGg7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIC8vIGRlZmF1bHQgT0FFUCB0byBTSEEtMSBtZXNzYWdlIGRpZ2VzdAogIGlmKG1kID09PSB1bmRlZmluZWQpIHsKICAgIG1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICB9IGVsc2UgewogICAgbWQuc3RhcnQoKTsKICB9CgogIC8vIGRlZmF1bHQgTUdGLTEgdG8gc2FtZSBhcyBPQUVQCiAgaWYoIW1nZjFNZCkgewogICAgbWdmMU1kID0gbWQ7CiAgfQoKICBpZihrZXlMZW5ndGggPCAyICogbWQuZGlnZXN0TGVuZ3RoICsgMikgewogICAgdGhyb3cgbmV3IEVycm9yKCdSU0FFUy1PQUVQIGtleSBpcyB0b28gc2hvcnQgZm9yIHRoZSBoYXNoIGZ1bmN0aW9uLicpOwogIH0KCiAgaWYoIWxhYmVsKSB7CiAgICBsYWJlbCA9ICcnOwogIH0KICBtZC51cGRhdGUobGFiZWwsICdyYXcnKTsKICB2YXIgbEhhc2ggPSBtZC5kaWdlc3QoKS5nZXRCeXRlcygpOwoKICAvLyBzcGxpdCB0aGUgbWVzc2FnZSBpbnRvIGl0cyBwYXJ0cwogIHZhciB5ID0gZW0uY2hhckF0KDApOwogIHZhciBtYXNrZWRTZWVkID0gZW0uc3Vic3RyaW5nKDEsIG1kLmRpZ2VzdExlbmd0aCArIDEpOwogIHZhciBtYXNrZWREQiA9IGVtLnN1YnN0cmluZygxICsgbWQuZGlnZXN0TGVuZ3RoKTsKCiAgdmFyIHNlZWRNYXNrID0gcnNhX21nZjEobWFza2VkREIsIG1kLmRpZ2VzdExlbmd0aCwgbWdmMU1kKTsKICB2YXIgc2VlZCA9IGZvcmdlLnV0aWwueG9yQnl0ZXMobWFza2VkU2VlZCwgc2VlZE1hc2ssIG1hc2tlZFNlZWQubGVuZ3RoKTsKCiAgdmFyIGRiTWFzayA9IHJzYV9tZ2YxKHNlZWQsIGtleUxlbmd0aCAtIG1kLmRpZ2VzdExlbmd0aCAtIDEsIG1nZjFNZCk7CiAgdmFyIGRiID0gZm9yZ2UudXRpbC54b3JCeXRlcyhtYXNrZWREQiwgZGJNYXNrLCBtYXNrZWREQi5sZW5ndGgpOwoKICB2YXIgbEhhc2hQcmltZSA9IGRiLnN1YnN0cmluZygwLCBtZC5kaWdlc3RMZW5ndGgpOwoKICAvLyBjb25zdGFudCB0aW1lIGNoZWNrIHRoYXQgYWxsIHZhbHVlcyBtYXRjaCB3aGF0IGlzIGV4cGVjdGVkCiAgdmFyIGVycm9yID0gKHkgIT09ICdceDAwJyk7CgogIC8vIGNvbnN0YW50IHRpbWUgY2hlY2sgbEhhc2ggdnMgbEhhc2hQcmltZQogIGZvcih2YXIgaSA9IDA7IGkgPCBtZC5kaWdlc3RMZW5ndGg7ICsraSkgewogICAgZXJyb3IgfD0gKGxIYXNoLmNoYXJBdChpKSAhPT0gbEhhc2hQcmltZS5jaGFyQXQoaSkpOwogIH0KCiAgLy8gImNvbnN0YW50IHRpbWUiIGZpbmQgdGhlIDB4MSBieXRlIHNlcGFyYXRpbmcgdGhlIHBhZGRpbmcgKHplcm9zKSBmcm9tIHRoZQogIC8vIG1lc3NhZ2UKICAvLyBUT0RPOiBJdCBtdXN0IGJlIHBvc3NpYmxlIHRvIGRvIHRoaXMgaW4gYSBiZXR0ZXIvc21hcnRlciB3YXk/CiAgdmFyIGluX3BzID0gMTsKICB2YXIgaW5kZXggPSBtZC5kaWdlc3RMZW5ndGg7CiAgZm9yKHZhciBqID0gbWQuZGlnZXN0TGVuZ3RoOyBqIDwgZGIubGVuZ3RoOyBqKyspIHsKICAgIHZhciBjb2RlID0gZGIuY2hhckNvZGVBdChqKTsKCiAgICB2YXIgaXNfMCA9IChjb2RlICYgMHgxKSBeIDB4MTsKCiAgICAvLyBub24temVybyBpZiBub3QgMCBvciAxIGluIHRoZSBwcyBzZWN0aW9uCiAgICB2YXIgZXJyb3JfbWFzayA9IGluX3BzID8gMHhmZmZlIDogMHgwMDAwOwogICAgZXJyb3IgfD0gKGNvZGUgJiBlcnJvcl9tYXNrKTsKCiAgICAvLyBsYXRjaCBpbl9wcyB0byB6ZXJvIGFmdGVyIHdlIGZpbmQgMHgxCiAgICBpbl9wcyA9IGluX3BzICYgaXNfMDsKICAgIGluZGV4ICs9IGluX3BzOwogIH0KCiAgaWYoZXJyb3IgfHwgZGIuY2hhckNvZGVBdChpbmRleCkgIT09IDB4MSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIFJTQUVTLU9BRVAgcGFkZGluZy4nKTsKICB9CgogIHJldHVybiBkYi5zdWJzdHJpbmcoaW5kZXggKyAxKTsKfTsKCmZ1bmN0aW9uIHJzYV9tZ2YxKHNlZWQsIG1hc2tMZW5ndGgsIGhhc2gpIHsKICAvLyBkZWZhdWx0IHRvIFNIQS0xIG1lc3NhZ2UgZGlnZXN0CiAgaWYoIWhhc2gpIHsKICAgIGhhc2ggPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogIH0KICB2YXIgdCA9ICcnOwogIHZhciBjb3VudCA9IE1hdGguY2VpbChtYXNrTGVuZ3RoIC8gaGFzaC5kaWdlc3RMZW5ndGgpOwogIGZvcih2YXIgaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CiAgICB2YXIgYyA9IFN0cmluZy5mcm9tQ2hhckNvZGUoCiAgICAgIChpID4+IDI0KSAmIDB4RkYsIChpID4+IDE2KSAmIDB4RkYsIChpID4+IDgpICYgMHhGRiwgaSAmIDB4RkYpOwogICAgaGFzaC5zdGFydCgpOwogICAgaGFzaC51cGRhdGUoc2VlZCArIGMpOwogICAgdCArPSBoYXNoLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CiAgfQogIHJldHVybiB0LnN1YnN0cmluZygwLCBtYXNrTGVuZ3RoKTsKfQoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncGtjczEnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvcGtjczEnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJywgJy4vcmFuZG9tJywgJy4vc2hhMSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBQcmltZSBudW1iZXIgZ2VuZXJhdGlvbiBBUEkuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAoYykgMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIGZvcmdlLnByaW1lIGFscmVhZHkgZGVmaW5lZAppZihmb3JnZS5wcmltZSkgewogIHJldHVybjsKfQoKLyogUFJJTUUgQVBJICovCnZhciBwcmltZSA9IGZvcmdlLnByaW1lID0gZm9yZ2UucHJpbWUgfHwge307Cgp2YXIgQmlnSW50ZWdlciA9IGZvcmdlLmpzYm4uQmlnSW50ZWdlcjsKCi8vIHByaW1lcyBhcmUgMzBrK2kgZm9yIGkgPSAxLCA3LCAxMSwgMTMsIDE3LCAxOSwgMjMsIDI5CnZhciBHQ0RfMzBfREVMVEEgPSBbNiwgNCwgMiwgNCwgMiwgNCwgNiwgMl07CnZhciBUSElSVFkgPSBuZXcgQmlnSW50ZWdlcihudWxsKTsKVEhJUlRZLmZyb21JbnQoMzApOwp2YXIgb3Bfb3IgPSBmdW5jdGlvbih4LCB5KSB7cmV0dXJuIHh8eTt9OwoKLyoqCiAqIEdlbmVyYXRlcyBhIHJhbmRvbSBwcm9iYWJsZSBwcmltZSB3aXRoIHRoZSBnaXZlbiBudW1iZXIgb2YgYml0cy4KICoKICogQWx0ZXJuYXRpdmUgYWxnb3JpdGhtcyBjYW4gYmUgc3BlY2lmaWVkIGJ5IG5hbWUgYXMgYSBzdHJpbmcgb3IgYXMgYW4KICogb2JqZWN0IHdpdGggY3VzdG9tIG9wdGlvbnMgbGlrZSBzbzoKICoKICogewogKiAgIG5hbWU6ICdQUklNRUlOQycsCiAqICAgb3B0aW9uczogewogKiAgICAgbWF4QmxvY2tUaW1lOiA8dGhlIG1heGltdW0gYW1vdW50IG9mIHRpbWUgdG8gYmxvY2sgdGhlIG1haW4KICogICAgICAgdGhyZWFkIGJlZm9yZSBhbGxvd2luZyBJL08gb3RoZXIgSlMgdG8gcnVuPiwKICogICAgIG1pbGxlclJhYmluVGVzdHM6IDx0aGUgbnVtYmVyIG9mIG1pbGxlci1yYWJpbiB0ZXN0cyB0byBydW4+LAogKiAgICAgd29ya2VyU2NyaXB0OiA8dGhlIHdvcmtlciBzY3JpcHQgVVJMPiwKICogICAgIHdvcmtlcnM6IDx0aGUgbnVtYmVyIG9mIHdlYiB3b3JrZXJzIChpZiBzdXBwb3J0ZWQpIHRvIHVzZSwKICogICAgICAgLTEgdG8gdXNlIGVzdGltYXRlZCBjb3JlcyBtaW51cyBvbmU+LgogKiAgICAgd29ya0xvYWQ6IHRoZSBzaXplIG9mIHRoZSB3b3JrIGxvYWQsIGllOiBudW1iZXIgb2YgcG9zc2libGUgcHJpbWUKICogICAgICAgbnVtYmVycyBmb3IgZWFjaCB3ZWIgd29ya2VyIHRvIGNoZWNrIHBlciB3b3JrIGFzc2lnbm1lbnQsCiAqICAgICAgIChkZWZhdWx0OiAxMDApLgogKiAgIH0KICogfQogKgogKiBAcGFyYW0gYml0cyB0aGUgbnVtYmVyIG9mIGJpdHMgZm9yIHRoZSBwcmltZSBudW1iZXIuCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZS4KICogICAgICAgICAgW2FsZ29yaXRobV0gdGhlIGFsZ29yaXRobSB0byB1c2UgKGRlZmF1bHQ6ICdQUklNRUlOQycpLgogKiAgICAgICAgICBbcHJuZ10gYSBjdXN0b20gY3J5cHRvLXNlY3VyZSBwc2V1ZG8tcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdG8gdXNlLAogKiAgICAgICAgICAgIHRoYXQgbXVzdCBkZWZpbmUgImdldEJ5dGVzU3luYyIuCiAqCiAqIEByZXR1cm4gY2FsbGJhY2soZXJyLCBudW0pIGNhbGxlZCBvbmNlIHRoZSBvcGVyYXRpb24gY29tcGxldGVzLgogKi8KcHJpbWUuZ2VuZXJhdGVQcm9iYWJsZVByaW1lID0gZnVuY3Rpb24oYml0cywgb3B0aW9ucywgY2FsbGJhY2spIHsKICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykgewogICAgY2FsbGJhY2sgPSBvcHRpb25zOwogICAgb3B0aW9ucyA9IHt9OwogIH0KICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKCiAgLy8gZGVmYXVsdCB0byBQUklNRUlOQyBhbGdvcml0aG0KICB2YXIgYWxnb3JpdGhtID0gb3B0aW9ucy5hbGdvcml0aG0gfHwgJ1BSSU1FSU5DJzsKICBpZih0eXBlb2YgYWxnb3JpdGhtID09PSAnc3RyaW5nJykgewogICAgYWxnb3JpdGhtID0ge25hbWU6IGFsZ29yaXRobX07CiAgfQogIGFsZ29yaXRobS5vcHRpb25zID0gYWxnb3JpdGhtLm9wdGlvbnMgfHwge307CgogIC8vIGNyZWF0ZSBwcm5nIHdpdGggYXBpIHRoYXQgbWF0Y2hlcyBCaWdJbnRlZ2VyIHNlY3VyZSByYW5kb20KICB2YXIgcHJuZyA9IG9wdGlvbnMucHJuZyB8fCBmb3JnZS5yYW5kb207CiAgdmFyIHJuZyA9IHsKICAgIC8vIHggaXMgYW4gYXJyYXkgdG8gZmlsbCB3aXRoIGJ5dGVzCiAgICBuZXh0Qnl0ZXM6IGZ1bmN0aW9uKHgpIHsKICAgICAgdmFyIGIgPSBwcm5nLmdldEJ5dGVzU3luYyh4Lmxlbmd0aCk7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCB4Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgeFtpXSA9IGIuY2hhckNvZGVBdChpKTsKICAgICAgfQogICAgfQogIH07CgogIGlmKGFsZ29yaXRobS5uYW1lID09PSAnUFJJTUVJTkMnKSB7CiAgICByZXR1cm4gcHJpbWVpbmNGaW5kUHJpbWUoYml0cywgcm5nLCBhbGdvcml0aG0ub3B0aW9ucywgY2FsbGJhY2spOwogIH0KCiAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHByaW1lIGdlbmVyYXRpb24gYWxnb3JpdGhtOiAnICsgYWxnb3JpdGhtLm5hbWUpOwp9OwoKZnVuY3Rpb24gcHJpbWVpbmNGaW5kUHJpbWUoYml0cywgcm5nLCBvcHRpb25zLCBjYWxsYmFjaykgewogIGlmKCd3b3JrZXJzJyBpbiBvcHRpb25zKSB7CiAgICByZXR1cm4gcHJpbWVpbmNGaW5kUHJpbWVXaXRoV29ya2VycyhiaXRzLCBybmcsIG9wdGlvbnMsIGNhbGxiYWNrKTsKICB9CiAgcmV0dXJuIHByaW1laW5jRmluZFByaW1lV2l0aG91dFdvcmtlcnMoYml0cywgcm5nLCBvcHRpb25zLCBjYWxsYmFjayk7Cn0KCmZ1bmN0aW9uIHByaW1laW5jRmluZFByaW1lV2l0aG91dFdvcmtlcnMoYml0cywgcm5nLCBvcHRpb25zLCBjYWxsYmFjaykgewogIC8vIGluaXRpYWxpemUgcmFuZG9tIG51bWJlcgogIHZhciBudW0gPSBnZW5lcmF0ZVJhbmRvbShiaXRzLCBybmcpOwoKICAvKiBOb3RlOiBBbGwgcHJpbWVzIGFyZSBvZiB0aGUgZm9ybSAzMGsraSBmb3IgaSA8IDMwIGFuZCBnY2QoMzAsIGkpPTEuIFRoZQogIG51bWJlciB3ZSBhcmUgZ2l2ZW4gaXMgYWx3YXlzIGFsaWduZWQgYXQgMzBrICsgMS4gRWFjaCB0aW1lIHRoZSBudW1iZXIgaXMKICBkZXRlcm1pbmVkIG5vdCB0byBiZSBwcmltZSB3ZSBhZGQgdG8gZ2V0IHRvIHRoZSBuZXh0ICdpJywgZWc6IGlmIHRoZSBudW1iZXIKICB3YXMgYXQgMzBrICsgMSB3ZSBhZGQgNi4gKi8KICB2YXIgZGVsdGFJZHggPSAwOwoKICAvLyBnZXQgcmVxdWlyZWQgbnVtYmVyIG9mIE1SIHRlc3RzCiAgdmFyIG1yVGVzdHMgPSBnZXRNaWxsZXJSYWJpblRlc3RzKG51bS5iaXRMZW5ndGgoKSk7CiAgaWYoJ21pbGxlclJhYmluVGVzdHMnIGluIG9wdGlvbnMpIHsKICAgIG1yVGVzdHMgPSBvcHRpb25zLm1pbGxlclJhYmluVGVzdHM7CiAgfQoKICAvLyBmaW5kIHByaW1lIG5lYXJlc3QgdG8gJ251bScgZm9yIG1heEJsb2NrVGltZSBtcwogIC8vIDEwIG1zIGdpdmVzIDVtcyBvZiBsZWV3YXkgZm9yIG90aGVyIGNhbGN1bGF0aW9ucyBiZWZvcmUgZHJvcHBpbmcKICAvLyBiZWxvdyA2MGZwcyAoMTAwMC82MCA9PSAxNi42NyksIGJ1dCBpbiByZWFsaXR5LCB0aGUgbnVtYmVyIHdpbGwKICAvLyBsaWtlbHkgYmUgaGlnaGVyIGR1ZSB0byBhbiAnYXRvbWljJyBiaWcgaW50IG1vZFBvdwogIHZhciBtYXhCbG9ja1RpbWUgPSAxMDsKICBpZignbWF4QmxvY2tUaW1lJyBpbiBvcHRpb25zKSB7CiAgICBtYXhCbG9ja1RpbWUgPSBvcHRpb25zLm1heEJsb2NrVGltZTsKICB9CiAgdmFyIHN0YXJ0ID0gK25ldyBEYXRlKCk7CiAgZG8gewogICAgLy8gb3ZlcmZsb3csIHJlZ2VuZXJhdGUgcmFuZG9tIG51bWJlcgogICAgaWYobnVtLmJpdExlbmd0aCgpID4gYml0cykgewogICAgICBudW0gPSBnZW5lcmF0ZVJhbmRvbShiaXRzLCBybmcpOwogICAgfQogICAgLy8gZG8gcHJpbWFsaXR5IHRlc3QKICAgIGlmKG51bS5pc1Byb2JhYmxlUHJpbWUobXJUZXN0cykpIHsKICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIG51bSk7CiAgICB9CiAgICAvLyBnZXQgbmV4dCBwb3RlbnRpYWwgcHJpbWUKICAgIG51bS5kQWRkT2Zmc2V0KEdDRF8zMF9ERUxUQVtkZWx0YUlkeCsrICUgOF0sIDApOwogIH0gd2hpbGUobWF4QmxvY2tUaW1lIDwgMCB8fCAoK25ldyBEYXRlKCkgLSBzdGFydCA8IG1heEJsb2NrVGltZSkpOwoKICAvLyBrZWVwIHRyeWluZyAoc2V0SW1tZWRpYXRlIHdvdWxkIGJlIGJldHRlciBoZXJlKQogIGZvcmdlLnV0aWwuc2V0SW1tZWRpYXRlKGZ1bmN0aW9uKCkgewogICAgcHJpbWVpbmNGaW5kUHJpbWVXaXRob3V0V29ya2VycyhiaXRzLCBybmcsIG9wdGlvbnMsIGNhbGxiYWNrKTsKICB9KTsKfQoKZnVuY3Rpb24gcHJpbWVpbmNGaW5kUHJpbWVXaXRoV29ya2VycyhiaXRzLCBybmcsIG9wdGlvbnMsIGNhbGxiYWNrKSB7CiAgLy8gd2ViIHdvcmtlcnMgdW5hdmFpbGFibGUKICBpZih0eXBlb2YgV29ya2VyID09PSAndW5kZWZpbmVkJykgewogICAgcmV0dXJuIHByaW1laW5jRmluZFByaW1lV2l0aG91dFdvcmtlcnMoYml0cywgcm5nLCBvcHRpb25zLCBjYWxsYmFjayk7CiAgfQoKICAvLyBpbml0aWFsaXplIHJhbmRvbSBudW1iZXIKICB2YXIgbnVtID0gZ2VuZXJhdGVSYW5kb20oYml0cywgcm5nKTsKCiAgLy8gdXNlIHdlYiB3b3JrZXJzIHRvIGdlbmVyYXRlIGtleXMKICB2YXIgbnVtV29ya2VycyA9IG9wdGlvbnMud29ya2VyczsKICB2YXIgd29ya0xvYWQgPSBvcHRpb25zLndvcmtMb2FkIHx8IDEwMDsKICB2YXIgcmFuZ2UgPSB3b3JrTG9hZCAqIDMwIC8gODsKICB2YXIgd29ya2VyU2NyaXB0ID0gb3B0aW9ucy53b3JrZXJTY3JpcHQgfHwgJ2ZvcmdlL3ByaW1lLndvcmtlci5qcyc7CiAgaWYobnVtV29ya2VycyA9PT0gLTEpIHsKICAgIHJldHVybiBmb3JnZS51dGlsLmVzdGltYXRlQ29yZXMoZnVuY3Rpb24oZXJyLCBjb3JlcykgewogICAgICBpZihlcnIpIHsKICAgICAgICAvLyBkZWZhdWx0IHRvIDIKICAgICAgICBjb3JlcyA9IDI7CiAgICAgIH0KICAgICAgbnVtV29ya2VycyA9IGNvcmVzIC0gMTsKICAgICAgZ2VuZXJhdGUoKTsKICAgIH0pOwogIH0KICBnZW5lcmF0ZSgpOwoKICBmdW5jdGlvbiBnZW5lcmF0ZSgpIHsKICAgIC8vIHJlcXVpcmUgYXQgbGVhc3QgMSB3b3JrZXIKICAgIG51bVdvcmtlcnMgPSBNYXRoLm1heCgxLCBudW1Xb3JrZXJzKTsKCiAgICAvLyBUT0RPOiBjb25zaWRlciBvcHRpbWl6aW5nIGJ5IHN0YXJ0aW5nIHdvcmtlcnMgb3V0c2lkZSBnZXRQcmltZSgpIC4uLgogICAgLy8gbm90ZSB0aGF0IGluIG9yZGVyIHRvIGNsZWFuIHVwIHRoZXkgd2lsbCBoYXZlIHRvIGJlIG1hZGUgaW50ZXJuYWxseQogICAgLy8gYXN5bmNocm9ub3VzIHdoaWNoIG1heSBhY3R1YWxseSBiZSBzbG93ZXIKCiAgICAvLyBzdGFydCB3b3JrZXJzIGltbWVkaWF0ZWx5CiAgICB2YXIgd29ya2VycyA9IFtdOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG51bVdvcmtlcnM7ICsraSkgewogICAgICAvLyBGSVhNRTogZml4IHBhdGggb3IgdXNlIGJsb2IgVVJMcwogICAgICB3b3JrZXJzW2ldID0gbmV3IFdvcmtlcih3b3JrZXJTY3JpcHQpOwogICAgfQogICAgdmFyIHJ1bm5pbmcgPSBudW1Xb3JrZXJzOwoKICAgIC8vIGxpc3RlbiBmb3IgcmVxdWVzdHMgZnJvbSB3b3JrZXJzIGFuZCBhc3NpZ24gcmFuZ2VzIHRvIGZpbmQgcHJpbWUKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBudW1Xb3JrZXJzOyArK2kpIHsKICAgICAgd29ya2Vyc1tpXS5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgd29ya2VyTWVzc2FnZSk7CiAgICB9CgogICAgLyogTm90ZTogVGhlIGRpc3RyaWJ1dGlvbiBvZiByYW5kb20gbnVtYmVycyBpcyB1bmtub3duLiBUaGVyZWZvcmUsIGVhY2gKICAgIHdlYiB3b3JrZXIgaXMgY29udGludW91c2x5IGFsbG9jYXRlZCBhIHJhbmdlIG9mIG51bWJlcnMgdG8gY2hlY2sgZm9yIGEKICAgIHJhbmRvbSBudW1iZXIgdW50aWwgb25lIGlzIGZvdW5kLgoKICAgIEV2ZXJ5IDMwIG51bWJlcnMgd2lsbCBiZSBjaGVja2VkIGp1c3QgOCB0aW1lcywgYmVjYXVzZSBwcmltZSBudW1iZXJzCiAgICBoYXZlIHRoZSBmb3JtOgoKICAgIDMwaytpLCBmb3IgaSA8IDMwIGFuZCBnY2QoMzAsIGkpPTEgKHRoZXJlIGFyZSA4IHZhbHVlcyBvZiBpIGZvciB0aGlzKQoKICAgIFRoZXJlZm9yZSwgaWYgd2Ugd2FudCBhIHdlYiB3b3JrZXIgdG8gcnVuIE4gY2hlY2tzIGJlZm9yZSBhc2tpbmcgZm9yCiAgICBhIG5ldyByYW5nZSBvZiBudW1iZXJzLCBlYWNoIHJhbmdlIG11c3QgY29udGFpbiBOKjMwLzggbnVtYmVycy4KCiAgICBGb3IgMTAwIGNoZWNrcyAod29ya0xvYWQpLCB0aGlzIGlzIGEgcmFuZ2Ugb2YgMzc1LiAqLwoKICAgIHZhciBmb3VuZCA9IGZhbHNlOwogICAgZnVuY3Rpb24gd29ya2VyTWVzc2FnZShlKSB7CiAgICAgIC8vIGlnbm9yZSBtZXNzYWdlLCBwcmltZSBhbHJlYWR5IGZvdW5kCiAgICAgIGlmKGZvdW5kKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICAtLXJ1bm5pbmc7CiAgICAgIHZhciBkYXRhID0gZS5kYXRhOwogICAgICBpZihkYXRhLmZvdW5kKSB7CiAgICAgICAgLy8gdGVybWluYXRlIGFsbCB3b3JrZXJzCiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHdvcmtlcnMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgIHdvcmtlcnNbaV0udGVybWluYXRlKCk7CiAgICAgICAgfQogICAgICAgIGZvdW5kID0gdHJ1ZTsKICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgbmV3IEJpZ0ludGVnZXIoZGF0YS5wcmltZSwgMTYpKTsKICAgICAgfQoKICAgICAgLy8gb3ZlcmZsb3csIHJlZ2VuZXJhdGUgcmFuZG9tIG51bWJlcgogICAgICBpZihudW0uYml0TGVuZ3RoKCkgPiBiaXRzKSB7CiAgICAgICAgbnVtID0gZ2VuZXJhdGVSYW5kb20oYml0cywgcm5nKTsKICAgICAgfQoKICAgICAgLy8gYXNzaWduIG5ldyByYW5nZSB0byBjaGVjawogICAgICB2YXIgaGV4ID0gbnVtLnRvU3RyaW5nKDE2KTsKCiAgICAgIC8vIHN0YXJ0IHByaW1lIHNlYXJjaAogICAgICBlLnRhcmdldC5wb3N0TWVzc2FnZSh7CiAgICAgICAgaGV4OiBoZXgsCiAgICAgICAgd29ya0xvYWQ6IHdvcmtMb2FkCiAgICAgIH0pOwoKICAgICAgbnVtLmRBZGRPZmZzZXQocmFuZ2UsIDApOwogICAgfQogIH0KfQoKLyoqCiAqIEdlbmVyYXRlcyBhIHJhbmRvbSBudW1iZXIgdXNpbmcgdGhlIGdpdmVuIG51bWJlciBvZiBiaXRzIGFuZCBSTkcuCiAqCiAqIEBwYXJhbSBiaXRzIHRoZSBudW1iZXIgb2YgYml0cyBmb3IgdGhlIG51bWJlci4KICogQHBhcmFtIHJuZyB0aGUgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSByYW5kb20gbnVtYmVyLgogKi8KZnVuY3Rpb24gZ2VuZXJhdGVSYW5kb20oYml0cywgcm5nKSB7CiAgdmFyIG51bSA9IG5ldyBCaWdJbnRlZ2VyKGJpdHMsIHJuZyk7CiAgLy8gZm9yY2UgTVNCIHNldAogIHZhciBiaXRzMSA9IGJpdHMgLSAxOwogIGlmKCFudW0udGVzdEJpdChiaXRzMSkpIHsKICAgIG51bS5iaXR3aXNlVG8oQmlnSW50ZWdlci5PTkUuc2hpZnRMZWZ0KGJpdHMxKSwgb3Bfb3IsIG51bSk7CiAgfQogIC8vIGFsaWduIG51bWJlciBvbiAzMGsrMSBib3VuZGFyeQogIG51bS5kQWRkT2Zmc2V0KDMxIC0gbnVtLm1vZChUSElSVFkpLmJ5dGVWYWx1ZSgpLCAwKTsKICByZXR1cm4gbnVtOwp9CgovKioKICogUmV0dXJucyB0aGUgcmVxdWlyZWQgbnVtYmVyIG9mIE1pbGxlci1SYWJpbiB0ZXN0cyB0byBnZW5lcmF0ZSBhCiAqIHByaW1lIHdpdGggYW4gZXJyb3IgcHJvYmFiaWxpdHkgb2YgKDEvMileODAuCiAqCiAqIFNlZSBIYW5kYm9vayBvZiBBcHBsaWVkIENyeXB0b2dyYXBoeSBDaGFwdGVyIDQsIFRhYmxlIDQuNC4KICoKICogQHBhcmFtIGJpdHMgdGhlIGJpdCBzaXplLgogKgogKiBAcmV0dXJuIHRoZSByZXF1aXJlZCBudW1iZXIgb2YgaXRlcmF0aW9ucy4KICovCmZ1bmN0aW9uIGdldE1pbGxlclJhYmluVGVzdHMoYml0cykgewogIGlmKGJpdHMgPD0gMTAwKSByZXR1cm4gMjc7CiAgaWYoYml0cyA8PSAxNTApIHJldHVybiAxODsKICBpZihiaXRzIDw9IDIwMCkgcmV0dXJuIDE1OwogIGlmKGJpdHMgPD0gMjUwKSByZXR1cm4gMTI7CiAgaWYoYml0cyA8PSAzMDApIHJldHVybiA5OwogIGlmKGJpdHMgPD0gMzUwKSByZXR1cm4gODsKICBpZihiaXRzIDw9IDQwMCkgcmV0dXJuIDc7CiAgaWYoYml0cyA8PSA1MDApIHJldHVybiA2OwogIGlmKGJpdHMgPD0gNjAwKSByZXR1cm4gNTsKICBpZihiaXRzIDw9IDgwMCkgcmV0dXJuIDQ7CiAgaWYoYml0cyA8PSAxMjUwKSByZXR1cm4gMzsKICByZXR1cm4gMjsKfQoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncHJpbWUnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvcHJpbWUnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJywgJy4vanNibicsICcuL3JhbmRvbSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKCn0pKCk7CgovKioKICogSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBiYXNpYyBSU0EgYWxnb3JpdGhtcy4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICoKICogVGhlIG9ubHkgYWxnb3JpdGhtIGN1cnJlbnRseSBzdXBwb3J0ZWQgZm9yIFBLSSBpcyBSU0EuCiAqCiAqIEFuIFJTQSBrZXkgaXMgb2Z0ZW4gc3RvcmVkIGluIEFTTi4xIERFUiBmb3JtYXQuIFRoZSBTdWJqZWN0UHVibGljS2V5SW5mbwogKiBBU04uMSBzdHJ1Y3R1cmUgaXMgY29tcG9zZWQgb2YgYW4gYWxnb3JpdGhtIG9mIHR5cGUgQWxnb3JpdGhtSWRlbnRpZmllcgogKiBhbmQgYSBzdWJqZWN0UHVibGljS2V5IG9mIHR5cGUgYml0IHN0cmluZy4KICoKICogVGhlIEFsZ29yaXRobUlkZW50aWZpZXIgY29udGFpbnMgYW4gT2JqZWN0IElkZW50aWZpZXIgKE9JRCkgYW5kIHBhcmFtZXRlcnMKICogZm9yIHRoZSBhbGdvcml0aG0sIGlmIGFueS4gSW4gdGhlIGNhc2Ugb2YgUlNBLCB0aGVyZSBhcmVuJ3QgYW55LgogKgogKiBTdWJqZWN0UHVibGljS2V5SW5mbyA6Oj0gU0VRVUVOQ0UgewogKiAgIGFsZ29yaXRobSBBbGdvcml0aG1JZGVudGlmaWVyLAogKiAgIHN1YmplY3RQdWJsaWNLZXkgQklUIFNUUklORwogKiB9CiAqCiAqIEFsZ29yaXRobUlkZW50aWZlciA6Oj0gU0VRVUVOQ0UgewogKiAgIGFsZ29yaXRobSBPQkpFQ1QgSURFTlRJRklFUiwKICogICBwYXJhbWV0ZXJzIEFOWSBERUZJTkVEIEJZIGFsZ29yaXRobSBPUFRJT05BTAogKiB9CiAqCiAqIEZvciBhbiBSU0EgcHVibGljIGtleSwgdGhlIHN1YmplY3RQdWJsaWNLZXkgaXM6CiAqCiAqIFJTQVB1YmxpY0tleSA6Oj0gU0VRVUVOQ0UgewogKiAgIG1vZHVsdXMgICAgICAgICAgICBJTlRFR0VSLCAgICAtLSBuCiAqICAgcHVibGljRXhwb25lbnQgICAgIElOVEVHRVIgICAgIC0tIGUKICogfQogKgogKiBQcml2YXRlS2V5SW5mbyA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gICAgICAgICAgICAgICAgICAgVmVyc2lvbiwKICogICBwcml2YXRlS2V5QWxnb3JpdGhtICAgICAgIFByaXZhdGVLZXlBbGdvcml0aG1JZGVudGlmaWVyLAogKiAgIHByaXZhdGVLZXkgICAgICAgICAgICAgICAgUHJpdmF0ZUtleSwKICogICBhdHRyaWJ1dGVzICAgICAgICAgICBbMF0gIElNUExJQ0lUIEF0dHJpYnV0ZXMgT1BUSU9OQUwKICogfQogKgogKiBWZXJzaW9uIDo6PSBJTlRFR0VSCiAqIFByaXZhdGVLZXlBbGdvcml0aG1JZGVudGlmaWVyIDo6PSBBbGdvcml0aG1JZGVudGlmaWVyCiAqIFByaXZhdGVLZXkgOjo9IE9DVEVUIFNUUklORwogKiBBdHRyaWJ1dGVzIDo6PSBTRVQgT0YgQXR0cmlidXRlCiAqCiAqIEFuIFJTQSBwcml2YXRlIGtleSBhcyB0aGUgZm9sbG93aW5nIHN0cnVjdHVyZToKICoKICogUlNBUHJpdmF0ZUtleSA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gVmVyc2lvbiwKICogICBtb2R1bHVzIElOVEVHRVIsIC0tIG4KICogICBwdWJsaWNFeHBvbmVudCBJTlRFR0VSLCAtLSBlCiAqICAgcHJpdmF0ZUV4cG9uZW50IElOVEVHRVIsIC0tIGQKICogICBwcmltZTEgSU5URUdFUiwgLS0gcAogKiAgIHByaW1lMiBJTlRFR0VSLCAtLSBxCiAqICAgZXhwb25lbnQxIElOVEVHRVIsIC0tIGQgbW9kIChwLTEpCiAqICAgZXhwb25lbnQyIElOVEVHRVIsIC0tIGQgbW9kIChxLTEpCiAqICAgY29lZmZpY2llbnQgSU5URUdFUiAtLSAoaW52ZXJzZSBvZiBxKSBtb2QgcAogKiB9CiAqCiAqIFZlcnNpb24gOjo9IElOVEVHRVIKICoKICogVGhlIE9JRCBmb3IgdGhlIFJTQSBrZXkgYWxnb3JpdGhtIGlzOiAxLjIuODQwLjExMzU0OS4xLjEuMQogKi8KKGZ1bmN0aW9uKCkgewpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KCmlmKHR5cGVvZiBCaWdJbnRlZ2VyID09PSAndW5kZWZpbmVkJykgewogIHZhciBCaWdJbnRlZ2VyID0gZm9yZ2UuanNibi5CaWdJbnRlZ2VyOwp9CgovLyBzaG9ydGN1dCBmb3IgYXNuLjEgQVBJCnZhciBhc24xID0gZm9yZ2UuYXNuMTsKCi8qCiAqIFJTQSBlbmNyeXB0aW9uIGFuZCBkZWNyeXB0aW9uLCBzZWUgUkZDIDIzMTMuCiAqLwpmb3JnZS5wa2kgPSBmb3JnZS5wa2kgfHwge307CmZvcmdlLnBraS5yc2EgPSBmb3JnZS5yc2EgPSBmb3JnZS5yc2EgfHwge307CnZhciBwa2kgPSBmb3JnZS5wa2k7CgovLyBmb3IgZmluZGluZyBwcmltZXMsIHdoaWNoIGFyZSAzMGsraSBmb3IgaSA9IDEsIDcsIDExLCAxMywgMTcsIDE5LCAyMywgMjkKdmFyIEdDRF8zMF9ERUxUQSA9IFs2LCA0LCAyLCA0LCAyLCA0LCA2LCAyXTsKCi8vIHZhbGlkYXRvciBmb3IgYSBQcml2YXRlS2V5SW5mbyBzdHJ1Y3R1cmUKdmFyIHByaXZhdGVLZXlWYWxpZGF0b3IgPSB7CiAgLy8gUHJpdmF0ZUtleUluZm8KICBuYW1lOiAnUHJpdmF0ZUtleUluZm8nLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICAvLyBWZXJzaW9uIChJTlRFR0VSKQogICAgbmFtZTogJ1ByaXZhdGVLZXlJbmZvLnZlcnNpb24nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHJpdmF0ZUtleVZlcnNpb24nCiAgfSwgewogICAgLy8gcHJpdmF0ZUtleUFsZ29yaXRobQogICAgbmFtZTogJ1ByaXZhdGVLZXlJbmZvLnByaXZhdGVLZXlBbGdvcml0aG0nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICB2YWx1ZTogW3sKICAgICAgbmFtZTogJ0FsZ29yaXRobUlkZW50aWZpZXIuYWxnb3JpdGhtJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdwcml2YXRlS2V5T2lkJwogICAgfV0KICB9LCB7CiAgICAvLyBQcml2YXRlS2V5CiAgICBuYW1lOiAnUHJpdmF0ZUtleUluZm8nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ByaXZhdGVLZXknCiAgfV0KfTsKCi8vIHZhbGlkYXRvciBmb3IgYW4gUlNBIHByaXZhdGUga2V5CnZhciByc2FQcml2YXRlS2V5VmFsaWRhdG9yID0gewogIC8vIFJTQVByaXZhdGVLZXkKICBuYW1lOiAnUlNBUHJpdmF0ZUtleScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIC8vIFZlcnNpb24gKElOVEVHRVIpCiAgICBuYW1lOiAnUlNBUHJpdmF0ZUtleS52ZXJzaW9uJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ByaXZhdGVLZXlWZXJzaW9uJwogIH0sIHsKICAgIC8vIG1vZHVsdXMgKG4pCiAgICBuYW1lOiAnUlNBUHJpdmF0ZUtleS5tb2R1bHVzJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ByaXZhdGVLZXlNb2R1bHVzJwogIH0sIHsKICAgIC8vIHB1YmxpY0V4cG9uZW50IChlKQogICAgbmFtZTogJ1JTQVByaXZhdGVLZXkucHVibGljRXhwb25lbnQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHJpdmF0ZUtleVB1YmxpY0V4cG9uZW50JwogIH0sIHsKICAgIC8vIHByaXZhdGVFeHBvbmVudCAoZCkKICAgIG5hbWU6ICdSU0FQcml2YXRlS2V5LnByaXZhdGVFeHBvbmVudCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdwcml2YXRlS2V5UHJpdmF0ZUV4cG9uZW50JwogIH0sIHsKICAgIC8vIHByaW1lMSAocCkKICAgIG5hbWU6ICdSU0FQcml2YXRlS2V5LnByaW1lMScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdwcml2YXRlS2V5UHJpbWUxJwogIH0sIHsKICAgIC8vIHByaW1lMiAocSkKICAgIG5hbWU6ICdSU0FQcml2YXRlS2V5LnByaW1lMicsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdwcml2YXRlS2V5UHJpbWUyJwogIH0sIHsKICAgIC8vIGV4cG9uZW50MSAoZCBtb2QgKHAtMSkpCiAgICBuYW1lOiAnUlNBUHJpdmF0ZUtleS5leHBvbmVudDEnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHJpdmF0ZUtleUV4cG9uZW50MScKICB9LCB7CiAgICAvLyBleHBvbmVudDIgKGQgbW9kIChxLTEpKQogICAgbmFtZTogJ1JTQVByaXZhdGVLZXkuZXhwb25lbnQyJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ByaXZhdGVLZXlFeHBvbmVudDInCiAgfSwgewogICAgLy8gY29lZmZpY2llbnQgKChpbnZlcnNlIG9mIHEpIG1vZCBwKQogICAgbmFtZTogJ1JTQVByaXZhdGVLZXkuY29lZmZpY2llbnQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHJpdmF0ZUtleUNvZWZmaWNpZW50JwogIH1dCn07CgovLyB2YWxpZGF0b3IgZm9yIGFuIFJTQSBwdWJsaWMga2V5CnZhciByc2FQdWJsaWNLZXlWYWxpZGF0b3IgPSB7CiAgLy8gUlNBUHVibGljS2V5CiAgbmFtZTogJ1JTQVB1YmxpY0tleScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIC8vIG1vZHVsdXMgKG4pCiAgICBuYW1lOiAnUlNBUHVibGljS2V5Lm1vZHVsdXMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHVibGljS2V5TW9kdWx1cycKICB9LCB7CiAgICAvLyBwdWJsaWNFeHBvbmVudCAoZSkKICAgIG5hbWU6ICdSU0FQdWJsaWNLZXkuZXhwb25lbnQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAncHVibGljS2V5RXhwb25lbnQnCiAgfV0KfTsKCi8vIHZhbGlkYXRvciBmb3IgYW4gU3ViamVjdFB1YmxpY0tleUluZm8gc3RydWN0dXJlCi8vIE5vdGU6IEN1cnJlbnRseSBvbmx5IHdvcmtzIHdpdGggYW4gUlNBIHB1YmxpYyBrZXkKdmFyIHB1YmxpY0tleVZhbGlkYXRvciA9IGZvcmdlLnBraS5yc2EucHVibGljS2V5VmFsaWRhdG9yID0gewogIG5hbWU6ICdTdWJqZWN0UHVibGljS2V5SW5mbycsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICBjYXB0dXJlQXNuMTogJ3N1YmplY3RQdWJsaWNLZXlJbmZvJywKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdTdWJqZWN0UHVibGljS2V5SW5mby5BbGdvcml0aG1JZGVudGlmaWVyJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdBbGdvcml0aG1JZGVudGlmaWVyLmFsZ29yaXRobScsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlOiAncHVibGljS2V5T2lkJwogICAgfV0KICB9LCB7CiAgICAvLyBzdWJqZWN0UHVibGljS2V5CiAgICBuYW1lOiAnU3ViamVjdFB1YmxpY0tleUluZm8uc3ViamVjdFB1YmxpY0tleScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuQklUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgdmFsdWU6IFt7CiAgICAgIC8vIFJTQVB1YmxpY0tleQogICAgICBuYW1lOiAnU3ViamVjdFB1YmxpY0tleUluZm8uc3ViamVjdFB1YmxpY0tleS5SU0FQdWJsaWNLZXknLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ3JzYVB1YmxpY0tleScKICAgIH1dCiAgfV0KfTsKCi8qKgogKiBXcmFwIGRpZ2VzdCBpbiBEaWdlc3RJbmZvIG9iamVjdC4KICoKICogVGhpcyBmdW5jdGlvbiBpbXBsZW1lbnRzIEVNU0EtUEtDUzEtdjFfNS1FTkNPREUgYXMgcGVyIFJGQyAzNDQ3LgogKgogKiBEaWdlc3RJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgZGlnZXN0QWxnb3JpdGhtIERpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgZGlnZXN0IERpZ2VzdAogKiB9CiAqCiAqIERpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXIgOjo9IEFsZ29yaXRobUlkZW50aWZpZXIKICogRGlnZXN0IDo6PSBPQ1RFVCBTVFJJTkcKICoKICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3Qgd2l0aCB0aGUgaGFzaCB0byBzaWduLgogKgogKiBAcmV0dXJuIHRoZSBlbmNvZGVkIG1lc3NhZ2UgKHJlYWR5IGZvciBSU0EgZW5jcnl0aW9uKQogKi8KdmFyIGVtc2FQa2NzMXYxNWVuY29kZSA9IGZ1bmN0aW9uKG1kKSB7CiAgLy8gZ2V0IHRoZSBvaWQgZm9yIHRoZSBhbGdvcml0aG0KICB2YXIgb2lkOwogIGlmKG1kLmFsZ29yaXRobSBpbiBwa2kub2lkcykgewogICAgb2lkID0gcGtpLm9pZHNbbWQuYWxnb3JpdGhtXTsKICB9IGVsc2UgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdVbmtub3duIG1lc3NhZ2UgZGlnZXN0IGFsZ29yaXRobS4nKTsKICAgIGVycm9yLmFsZ29yaXRobSA9IG1kLmFsZ29yaXRobTsKICAgIHRocm93IGVycm9yOwogIH0KICB2YXIgb2lkQnl0ZXMgPSBhc24xLm9pZFRvRGVyKG9pZCkuZ2V0Qnl0ZXMoKTsKCiAgLy8gY3JlYXRlIHRoZSBkaWdlc3QgaW5mbwogIHZhciBkaWdlc3RJbmZvID0gYXNuMS5jcmVhdGUoCiAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbXSk7CiAgdmFyIGRpZ2VzdEFsZ29yaXRobSA9IGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgW10pOwogIGRpZ2VzdEFsZ29yaXRobS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLCBvaWRCeXRlcykpOwogIGRpZ2VzdEFsZ29yaXRobS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5OVUxMLCBmYWxzZSwgJycpKTsKICB2YXIgZGlnZXN0ID0gYXNuMS5jcmVhdGUoCiAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgZmFsc2UsIG1kLmRpZ2VzdCgpLmdldEJ5dGVzKCkpOwogIGRpZ2VzdEluZm8udmFsdWUucHVzaChkaWdlc3RBbGdvcml0aG0pOwogIGRpZ2VzdEluZm8udmFsdWUucHVzaChkaWdlc3QpOwoKICAvLyBlbmNvZGUgZGlnZXN0IGluZm8KICByZXR1cm4gYXNuMS50b0RlcihkaWdlc3RJbmZvKS5nZXRCeXRlcygpOwp9OwoKLyoqCiAqIFBlcmZvcm1zIHheYyBtb2QgbiAoUlNBIGVuY3J5cHRpb24gb3IgZGVjcnlwdGlvbiBvcGVyYXRpb24pLgogKgogKiBAcGFyYW0geCB0aGUgbnVtYmVyIHRvIHJhaXNlIGFuZCBtb2QuCiAqIEBwYXJhbSBrZXkgdGhlIGtleSB0byB1c2UuCiAqIEBwYXJhbSBwdWIgdHJ1ZSBpZiB0aGUga2V5IGlzIHB1YmxpYywgZmFsc2UgaWYgcHJpdmF0ZS4KICoKICogQHJldHVybiB0aGUgcmVzdWx0IG9mIHheYyBtb2Qgbi4KICovCnZhciBfbW9kUG93ID0gZnVuY3Rpb24oeCwga2V5LCBwdWIpIHsKICBpZihwdWIpIHsKICAgIHJldHVybiB4Lm1vZFBvdyhrZXkuZSwga2V5Lm4pOwogIH0KCiAgaWYoIWtleS5wIHx8ICFrZXkucSkgewogICAgLy8gYWxsb3cgY2FsY3VsYXRpb24gd2l0aG91dCBDUlQgcGFyYW1zIChzbG93KQogICAgcmV0dXJuIHgubW9kUG93KGtleS5kLCBrZXkubik7CiAgfQoKICAvLyBwcmUtY29tcHV0ZSBkUCwgZFEsIGFuZCBxSW52IGlmIG5lY2Vzc2FyeQogIGlmKCFrZXkuZFApIHsKICAgIGtleS5kUCA9IGtleS5kLm1vZChrZXkucC5zdWJ0cmFjdChCaWdJbnRlZ2VyLk9ORSkpOwogIH0KICBpZigha2V5LmRRKSB7CiAgICBrZXkuZFEgPSBrZXkuZC5tb2Qoa2V5LnEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpKTsKICB9CiAgaWYoIWtleS5xSW52KSB7CiAgICBrZXkucUludiA9IGtleS5xLm1vZEludmVyc2Uoa2V5LnApOwogIH0KCiAgLyogQ2hpbmVzZSByZW1haW5kZXIgdGhlb3JlbSAoQ1JUKSBzdGF0ZXM6CgogICAgU3VwcG9zZSBuMSwgbjIsIC4uLiwgbmsgYXJlIHBvc2l0aXZlIGludGVnZXJzIHdoaWNoIGFyZSBwYWlyd2lzZQogICAgY29wcmltZSAobjEgYW5kIG4yIGhhdmUgbm8gY29tbW9uIGZhY3RvcnMgb3RoZXIgdGhhbiAxKS4gRm9yIGFueQogICAgaW50ZWdlcnMgeDEsIHgyLCAuLi4sIHhrIHRoZXJlIGV4aXN0cyBhbiBpbnRlZ2VyIHggc29sdmluZyB0aGUKICAgIHN5c3RlbSBvZiBzaW11bHRhbmVvdXMgY29uZ3J1ZW5jZXMgKHdoZXJlIH49IG1lYW5zIG1vZHVsYXJseQogICAgY29uZ3J1ZW50IHNvIGEgfj0gYiBtb2QgbiBtZWFucyBhIG1vZCBuID0gYiBtb2Qgbik6CgogICAgeCB+PSB4MSBtb2QgbjEKICAgIHggfj0geDIgbW9kIG4yCiAgICAuLi4KICAgIHggfj0geGsgbW9kIG5rCgogICAgVGhpcyBzeXN0ZW0gb2YgY29uZ3J1ZW5jZXMgaGFzIGEgc2luZ2xlIHNpbXVsdGFuZW91cyBzb2x1dGlvbiB4CiAgICBiZXR3ZWVuIDAgYW5kIG4gLSAxLiBGdXJ0aGVybW9yZSwgZWFjaCB4ayBzb2x1dGlvbiBhbmQgeCBpdHNlbGYKICAgIGlzIGNvbmdydWVudCBtb2R1bG8gdGhlIHByb2R1Y3QgbiA9IG4xKm4yKi4uLipuay4KICAgIFNvIHgxIG1vZCBuID0geDIgbW9kIG4gPSB4ayBtb2QgbiA9IHggbW9kIG4uCgogICAgVGhlIHNpbmdsZSBzaW11bHRhbmVvdXMgc29sdXRpb24geCBjYW4gYmUgc29sdmVkIHdpdGggdGhlIGZvbGxvd2luZwogICAgZXF1YXRpb246CgogICAgeCA9IHN1bSh4aSpyaSpzaSkgbW9kIG4gd2hlcmUgcmkgPSBuL25pIGFuZCBzaSA9IHJpXi0xIG1vZCBuaS4KCiAgICBXaGVyZSB4IGlzIGxlc3MgdGhhbiBuLCB4aSA9IHggbW9kIG5pLgoKICAgIEZvciBSU0Egd2UgYXJlIG9ubHkgY29uY2VybmVkIHdpdGggayA9IDIuIFRoZSBtb2R1bHVzIG4gPSBwcSwgd2hlcmUKICAgIHAgYW5kIHEgYXJlIGNvcHJpbWUuIFRoZSBSU0EgZGVjcnlwdGlvbiBhbGdvcml0aG0gaXM6CgogICAgeSA9IHheZCBtb2QgbgoKICAgIEdpdmVuIHRoZSBhYm92ZToKCiAgICB4MSA9IHheZCBtb2QgcAogICAgcjEgPSBuL3AgPSBxCiAgICBzMSA9IHFeLTEgbW9kIHAKICAgIHgyID0geF5kIG1vZCBxCiAgICByMiA9IG4vcSA9IHAKICAgIHMyID0gcF4tMSBtb2QgcQoKICAgIFNvIHkgPSAoeDFyMXMxICsgeDJyMnMyKSBtb2QgbgogICAgICAgICA9ICgoeF5kIG1vZCBwKXEocV4tMSBtb2QgcCkgKyAoeF5kIG1vZCBxKXAocF4tMSBtb2QgcSkpIG1vZCBuCgogICAgQWNjb3JkaW5nIHRvIEZlcm1hdCdzIExpdHRsZSBUaGVvcmVtLCBpZiB0aGUgbW9kdWx1cyBQIGlzIHByaW1lLAogICAgZm9yIGFueSBpbnRlZ2VyIEEgbm90IGV2ZW5seSBkaXZpc2libGUgYnkgUCwgQV4oUC0xKSB+PSAxIG1vZCBQLgogICAgU2luY2UgQSBpcyBub3QgZGl2aXNpYmxlIGJ5IFAgaXQgZm9sbG93cyB0aGF0IGlmOgogICAgTiB+PSBNIG1vZCAoUCAtIDEpLCB0aGVuIEFeTiBtb2QgUCA9IEFeTSBtb2QgUC4gVGhlcmVmb3JlOgoKICAgIEFeTiBtb2QgUCA9IEFeKE0gbW9kIChQIC0gMSkpIG1vZCBQLiAoVGhlIGxhdHRlciB0YWtlcyBsZXNzIGVmZm9ydAogICAgdG8gY2FsY3VsYXRlKS4gSW4gb3JkZXIgdG8gY2FsY3VsYXRlIHheZCBtb2QgcCBtb3JlIHF1aWNrbHkgdGhlCiAgICBleHBvbmVudCBkIG1vZCAocCAtIDEpIGlzIHN0b3JlZCBpbiB0aGUgUlNBIHByaXZhdGUga2V5ICh0aGUgc2FtZQogICAgaXMgZG9uZSBmb3IgeF5kIG1vZCBxKS4gVGhlc2UgdmFsdWVzIGFyZSByZWZlcnJlZCB0byBhcyBkUCBhbmQgZFEKICAgIHJlc3BlY3RpdmVseS4gVGhlcmVmb3JlIHdlIG5vdyBoYXZlOgoKICAgIHkgPSAoKHheZFAgbW9kIHApcShxXi0xIG1vZCBwKSArICh4XmRRIG1vZCBxKXAocF4tMSBtb2QgcSkpIG1vZCBuCgogICAgU2luY2Ugd2UnbGwgYmUgcmVkdWNpbmcgeF5kUCBieSBtb2R1bG8gcCAoc2FtZSBmb3IgcSkgd2UgY2FuIGFsc28KICAgIHJlZHVjZSB4IGJ5IHAgKGFuZCBxIHJlc3BlY3RpdmVseSkgYmVmb3JlIGhhbmQuIFRoZXJlZm9yZSwgbGV0CgogICAgeHAgPSAoKHggbW9kIHApXmRQIG1vZCBwKSwgYW5kCiAgICB4cSA9ICgoeCBtb2QgcSleZFEgbW9kIHEpLCB5aWVsZGluZzoKCiAgICB5ID0gKHhwKnEqKHFeLTEgbW9kIHApICsgeHEqcCoocF4tMSBtb2QgcSkpIG1vZCBuCgogICAgVGhpcyBjYW4gYmUgZnVydGhlciByZWR1Y2VkIHRvIGEgc2ltcGxlIGFsZ29yaXRobSB0aGF0IG9ubHkKICAgIHJlcXVpcmVzIDEgaW52ZXJzZSAodGhlIHEgaW52ZXJzZSBpcyB1c2VkKSB0byBiZSB1c2VkIGFuZCBzdG9yZWQuCiAgICBUaGUgYWxnb3JpdGhtIGlzIGNhbGxlZCBHYXJuZXIncyBhbGdvcml0aG0uIElmIHFJbnYgaXMgdGhlCiAgICBpbnZlcnNlIG9mIHEsIHdlIHNpbXBseSBjYWxjdWxhdGU6CgogICAgeSA9IChxSW52Kih4cCAtIHhxKSBtb2QgcCkgKiBxICsgeHEKCiAgICBIb3dldmVyLCB0aGVyZSBhcmUgdHdvIGZ1cnRoZXIgY29tcGxpY2F0aW9ucy4gRmlyc3QsIHdlIG5lZWQgdG8KICAgIGVuc3VyZSB0aGF0IHhwID4geHEgdG8gcHJldmVudCBzaWduZWQgQmlnSW50ZWdlcnMgZnJvbSBiZWluZyB1c2VkCiAgICBzbyB3ZSBhZGQgcCB1bnRpbCB0aGlzIGlzIHRydWUgKHNpbmNlIHdlIHdpbGwgYmUgbW9kJ2luZyB3aXRoCiAgICBwIGFueXdheSkuIFRoZW4sIHRoZXJlIGlzIGEga25vd24gdGltaW5nIGF0dGFjayBvbiBhbGdvcml0aG1zCiAgICB1c2luZyB0aGUgQ1JULiBUbyBtaXRpZ2F0ZSB0aGlzIHJpc2ssICJjcnlwdG9ncmFwaGljIGJsaW5kaW5nIgogICAgc2hvdWxkIGJlIHVzZWQuIFRoaXMgcmVxdWlyZXMgc2ltcGx5IGdlbmVyYXRpbmcgYSByYW5kb20gbnVtYmVyIHIKICAgIGJldHdlZW4gMCBhbmQgbi0xIGFuZCBpdHMgaW52ZXJzZSBhbmQgbXVsdGlwbHlpbmcgeCBieSByXmUgYmVmb3JlCiAgICBjYWxjdWxhdGluZyB5IGFuZCB0aGVuIG11bHRpcGx5aW5nIHkgYnkgcl4tMSBhZnRlcndhcmRzLiBOb3RlIHRoYXQKICAgIHIgbXVzdCBiZSBjb3ByaW1lIHdpdGggbiAoZ2NkKHIsIG4pID09PSAxKSBpbiBvcmRlciB0byBoYXZlIGFuCiAgICBpbnZlcnNlLgogICovCgogIC8vIGNyeXB0b2dyYXBoaWMgYmxpbmRpbmcKICB2YXIgcjsKICBkbyB7CiAgICByID0gbmV3IEJpZ0ludGVnZXIoCiAgICAgIGZvcmdlLnV0aWwuYnl0ZXNUb0hleChmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMoa2V5Lm4uYml0TGVuZ3RoKCkgLyA4KSksCiAgICAgIDE2KTsKICB9IHdoaWxlKHIuY29tcGFyZVRvKGtleS5uKSA+PSAwIHx8ICFyLmdjZChrZXkubikuZXF1YWxzKEJpZ0ludGVnZXIuT05FKSk7CiAgeCA9IHgubXVsdGlwbHkoci5tb2RQb3coa2V5LmUsIGtleS5uKSkubW9kKGtleS5uKTsKCiAgLy8gY2FsY3VsYXRlIHhwIGFuZCB4cQogIHZhciB4cCA9IHgubW9kKGtleS5wKS5tb2RQb3coa2V5LmRQLCBrZXkucCk7CiAgdmFyIHhxID0geC5tb2Qoa2V5LnEpLm1vZFBvdyhrZXkuZFEsIGtleS5xKTsKCiAgLy8geHAgbXVzdCBiZSBsYXJnZXIgdGhhbiB4cSB0byBhdm9pZCBzaWduZWQgYml0IHVzYWdlCiAgd2hpbGUoeHAuY29tcGFyZVRvKHhxKSA8IDApIHsKICAgIHhwID0geHAuYWRkKGtleS5wKTsKICB9CgogIC8vIGRvIGxhc3Qgc3RlcAogIHZhciB5ID0geHAuc3VidHJhY3QoeHEpCiAgICAubXVsdGlwbHkoa2V5LnFJbnYpLm1vZChrZXkucCkKICAgIC5tdWx0aXBseShrZXkucSkuYWRkKHhxKTsKCiAgLy8gcmVtb3ZlIGVmZmVjdCBvZiByYW5kb20gZm9yIGNyeXB0b2dyYXBoaWMgYmxpbmRpbmcKICB5ID0geS5tdWx0aXBseShyLm1vZEludmVyc2Uoa2V5Lm4pKS5tb2Qoa2V5Lm4pOwoKICByZXR1cm4geTsKfTsKCi8qKgogKiBOT1RFOiBUSElTIE1FVEhPRCBJUyBERVBSRUNBVEVELCB1c2UgJ3NpZ24nIG9uIGEgcHJpdmF0ZSBrZXkgb2JqZWN0IG9yCiAqICdlbmNyeXB0JyBvbiBhIHB1YmxpYyBrZXkgb2JqZWN0IGluc3RlYWQuCiAqCiAqIFBlcmZvcm1zIFJTQSBlbmNyeXB0aW9uLgogKgogKiBUaGUgcGFyYW1ldGVyIGJ0IGNvbnRyb2xzIHdoZXRoZXIgdG8gcHV0IHBhZGRpbmcgYnl0ZXMgYmVmb3JlIHRoZQogKiBtZXNzYWdlIHBhc3NlZCBpbi4gU2V0IGJ0IHRvIGVpdGhlciB0cnVlIG9yIGZhbHNlIHRvIGRpc2FibGUgcGFkZGluZwogKiBjb21wbGV0ZWx5IChpbiBvcmRlciB0byBoYW5kbGUgZS5nLiBFTVNBLVBTUyBlbmNvZGluZyBzZXBlcmF0ZWx5IGJlZm9yZSksCiAqIHNpZ25hbGluZyB3aGV0aGVyIHRoZSBlbmNyeXB0aW9uIG9wZXJhdGlvbiBpcyBhIHB1YmxpYyBrZXkgb3BlcmF0aW9uCiAqIChpLmUuIGVuY3J5cHRpbmcgZGF0YSkgb3Igbm90LCBpLmUuIHByaXZhdGUga2V5IG9wZXJhdGlvbiAoZGF0YSBzaWduaW5nKS4KICoKICogRm9yIFBLQ1MjMSB2MS41IHBhZGRpbmcgcGFzcyBpbiB0aGUgYmxvY2sgdHlwZSB0byB1c2UsIGkuZS4gZWl0aGVyIDB4MDEKICogKGZvciBzaWduaW5nKSBvciAweDAyIChmb3IgZW5jcnlwdGlvbikuIFRoZSBrZXkgb3BlcmF0aW9uIG1vZGUgKHByaXZhdGUKICogb3IgcHVibGljKSBpcyBkZXJpdmVkIGZyb20gdGhpcyBmbGFnIGluIHRoYXQgY2FzZSkuCiAqCiAqIEBwYXJhbSBtIHRoZSBtZXNzYWdlIHRvIGVuY3J5cHQgYXMgYSBieXRlIHN0cmluZy4KICogQHBhcmFtIGtleSB0aGUgUlNBIGtleSB0byB1c2UuCiAqIEBwYXJhbSBidCBmb3IgUEtDUyMxIHYxLjUgcGFkZGluZywgdGhlIGJsb2NrIHR5cGUgdG8gdXNlCiAqICAgKDB4MDEgZm9yIHByaXZhdGUga2V5LCAweDAyIGZvciBwdWJsaWMpLAogKiAgIHRvIGRpc2FibGUgcGFkZGluZzogdHJ1ZSA9IHB1YmxpYyBrZXksIGZhbHNlID0gcHJpdmF0ZSBrZXkuCiAqCiAqIEByZXR1cm4gdGhlIGVuY3J5cHRlZCBieXRlcyBhcyBhIHN0cmluZy4KICovCnBraS5yc2EuZW5jcnlwdCA9IGZ1bmN0aW9uKG0sIGtleSwgYnQpIHsKICB2YXIgcHViID0gYnQ7CiAgdmFyIGViOwoKICAvLyBnZXQgdGhlIGxlbmd0aCBvZiB0aGUgbW9kdWx1cyBpbiBieXRlcwogIHZhciBrID0gTWF0aC5jZWlsKGtleS5uLmJpdExlbmd0aCgpIC8gOCk7CgogIGlmKGJ0ICE9PSBmYWxzZSAmJiBidCAhPT0gdHJ1ZSkgewogICAgLy8gbGVnYWN5LCBkZWZhdWx0IHRvIFBLQ1MjMSB2MS41IHBhZGRpbmcKICAgIHB1YiA9IChidCA9PT0gMHgwMik7CiAgICBlYiA9IF9lbmNvZGVQa2NzMV92MV81KG0sIGtleSwgYnQpOwogIH0gZWxzZSB7CiAgICBlYiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBlYi5wdXRCeXRlcyhtKTsKICB9CgogIC8vIGxvYWQgZW5jcnlwdGlvbiBibG9jayBhcyBiaWcgaW50ZWdlciAneCcKICAvLyBGSVhNRTogaGV4IGNvbnZlcnNpb24gaW5lZmZpY2llbnQsIGdldCBCaWdJbnRlZ2VyIHcvYnl0ZSBzdHJpbmdzCiAgdmFyIHggPSBuZXcgQmlnSW50ZWdlcihlYi50b0hleCgpLCAxNik7CgogIC8vIGRvIFJTQSBlbmNyeXB0aW9uCiAgdmFyIHkgPSBfbW9kUG93KHgsIGtleSwgcHViKTsKCiAgLy8gY29udmVydCB5IGludG8gdGhlIGVuY3J5cHRlZCBkYXRhIGJ5dGUgc3RyaW5nLCBpZiB5IGlzIHNob3J0ZXIgaW4KICAvLyBieXRlcyB0aGFuIGssIHRoZW4gcHJlcGVuZCB6ZXJvIGJ5dGVzIHRvIGZpbGwgdXAgZWQKICAvLyBGSVhNRTogaGV4IGNvbnZlcnNpb24gaW5lZmZpY2llbnQsIGdldCBCaWdJbnRlZ2VyIHcvYnl0ZSBzdHJpbmdzCiAgdmFyIHloZXggPSB5LnRvU3RyaW5nKDE2KTsKICB2YXIgZWQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHZhciB6ZXJvcyA9IGsgLSBNYXRoLmNlaWwoeWhleC5sZW5ndGggLyAyKTsKICB3aGlsZSh6ZXJvcyA+IDApIHsKICAgIGVkLnB1dEJ5dGUoMHgwMCk7CiAgICAtLXplcm9zOwogIH0KICBlZC5wdXRCeXRlcyhmb3JnZS51dGlsLmhleFRvQnl0ZXMoeWhleCkpOwogIHJldHVybiBlZC5nZXRCeXRlcygpOwp9OwoKLyoqCiAqIE5PVEU6IFRISVMgTUVUSE9EIElTIERFUFJFQ0FURUQsIHVzZSAnZGVjcnlwdCcgb24gYSBwcml2YXRlIGtleSBvYmplY3Qgb3IKICogJ3ZlcmlmeScgb24gYSBwdWJsaWMga2V5IG9iamVjdCBpbnN0ZWFkLgogKgogKiBQZXJmb3JtcyBSU0EgZGVjcnlwdGlvbi4KICoKICogVGhlIHBhcmFtZXRlciBtbCBjb250cm9scyB3aGV0aGVyIHRvIGFwcGx5IFBLQ1MjMSB2MS41IHBhZGRpbmcKICogb3Igbm90LiAgU2V0IG1sID0gZmFsc2UgdG8gZGlzYWJsZSBwYWRkaW5nIHJlbW92YWwgY29tcGxldGVseQogKiAoaW4gb3JkZXIgdG8gaGFuZGxlIGUuZy4gRU1TQS1QU1MgbGF0ZXIgb24pIGFuZCBzaW1wbHkgcGFzcyBiYWNrCiAqIHRoZSBSU0EgZW5jcnlwdGlvbiBibG9jay4KICoKICogQHBhcmFtIGVkIHRoZSBlbmNyeXB0ZWQgZGF0YSB0byBkZWNyeXB0IGluIGFzIGEgYnl0ZSBzdHJpbmcuCiAqIEBwYXJhbSBrZXkgdGhlIFJTQSBrZXkgdG8gdXNlLgogKiBAcGFyYW0gcHViIHRydWUgZm9yIGEgcHVibGljIGtleSBvcGVyYXRpb24sIGZhbHNlIGZvciBwcml2YXRlLgogKiBAcGFyYW0gbWwgdGhlIG1lc3NhZ2UgbGVuZ3RoLCBpZiBrbm93biwgZmFsc2UgdG8gZGlzYWJsZSBwYWRkaW5nLgogKgogKiBAcmV0dXJuIHRoZSBkZWNyeXB0ZWQgbWVzc2FnZSBhcyBhIGJ5dGUgc3RyaW5nLgogKi8KcGtpLnJzYS5kZWNyeXB0ID0gZnVuY3Rpb24oZWQsIGtleSwgcHViLCBtbCkgewogIC8vIGdldCB0aGUgbGVuZ3RoIG9mIHRoZSBtb2R1bHVzIGluIGJ5dGVzCiAgdmFyIGsgPSBNYXRoLmNlaWwoa2V5Lm4uYml0TGVuZ3RoKCkgLyA4KTsKCiAgLy8gZXJyb3IgaWYgdGhlIGxlbmd0aCBvZiB0aGUgZW5jcnlwdGVkIGRhdGEgRUQgaXMgbm90IGsKICBpZihlZC5sZW5ndGggIT09IGspIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignRW5jcnlwdGVkIG1lc3NhZ2UgbGVuZ3RoIGlzIGludmFsaWQuJyk7CiAgICBlcnJvci5sZW5ndGggPSBlZC5sZW5ndGg7CiAgICBlcnJvci5leHBlY3RlZCA9IGs7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIC8vIGNvbnZlcnQgZW5jcnlwdGVkIGRhdGEgaW50byBhIGJpZyBpbnRlZ2VyCiAgLy8gRklYTUU6IGhleCBjb252ZXJzaW9uIGluZWZmaWNpZW50LCBnZXQgQmlnSW50ZWdlciB3L2J5dGUgc3RyaW5ncwogIHZhciB5ID0gbmV3IEJpZ0ludGVnZXIoZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoZWQpLnRvSGV4KCksIDE2KTsKCiAgLy8geSBtdXN0IGJlIGxlc3MgdGhhbiB0aGUgbW9kdWx1cyBvciBpdCB3YXNuJ3QgdGhlIHJlc3VsdCBvZgogIC8vIGEgcHJldmlvdXMgbW9kIG9wZXJhdGlvbiAoZW5jcnlwdGlvbikgdXNpbmcgdGhhdCBtb2R1bHVzCiAgaWYoeS5jb21wYXJlVG8oa2V5Lm4pID49IDApIHsKICAgIHRocm93IG5ldyBFcnJvcignRW5jcnlwdGVkIG1lc3NhZ2UgaXMgaW52YWxpZC4nKTsKICB9CgogIC8vIGRvIFJTQSBkZWNyeXB0aW9uCiAgdmFyIHggPSBfbW9kUG93KHksIGtleSwgcHViKTsKCiAgLy8gY3JlYXRlIHRoZSBlbmNyeXB0aW9uIGJsb2NrLCBpZiB4IGlzIHNob3J0ZXIgaW4gYnl0ZXMgdGhhbiBrLCB0aGVuCiAgLy8gcHJlcGVuZCB6ZXJvIGJ5dGVzIHRvIGZpbGwgdXAgZWIKICAvLyBGSVhNRTogaGV4IGNvbnZlcnNpb24gaW5lZmZpY2llbnQsIGdldCBCaWdJbnRlZ2VyIHcvYnl0ZSBzdHJpbmdzCiAgdmFyIHhoZXggPSB4LnRvU3RyaW5nKDE2KTsKICB2YXIgZWIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHZhciB6ZXJvcyA9IGsgLSBNYXRoLmNlaWwoeGhleC5sZW5ndGggLyAyKTsKICB3aGlsZSh6ZXJvcyA+IDApIHsKICAgIGViLnB1dEJ5dGUoMHgwMCk7CiAgICAtLXplcm9zOwogIH0KICBlYi5wdXRCeXRlcyhmb3JnZS51dGlsLmhleFRvQnl0ZXMoeGhleCkpOwoKICBpZihtbCAhPT0gZmFsc2UpIHsKICAgIC8vIGxlZ2FjeSwgZGVmYXVsdCB0byBQS0NTIzEgdjEuNSBwYWRkaW5nCiAgICByZXR1cm4gX2RlY29kZVBrY3MxX3YxXzUoZWIuZ2V0Qnl0ZXMoKSwga2V5LCBwdWIpOwogIH0KCiAgLy8gcmV0dXJuIG1lc3NhZ2UKICByZXR1cm4gZWIuZ2V0Qnl0ZXMoKTsKfTsKCi8qKgogKiBDcmVhdGVzIGFuIFJTQSBrZXktcGFpciBnZW5lcmF0aW9uIHN0YXRlIG9iamVjdC4gSXQgaXMgdXNlZCB0byBhbGxvdwogKiBrZXktZ2VuZXJhdGlvbiB0byBiZSBwZXJmb3JtZWQgaW4gc3RlcHMuIEl0IGFsc28gYWxsb3dzIGZvciBhIFVJIHRvCiAqIGRpc3BsYXkgcHJvZ3Jlc3MgdXBkYXRlcy4KICoKICogQHBhcmFtIGJpdHMgdGhlIHNpemUgZm9yIHRoZSBwcml2YXRlIGtleSBpbiBiaXRzLCBkZWZhdWx0cyB0byAyMDQ4LgogKiBAcGFyYW0gZSB0aGUgcHVibGljIGV4cG9uZW50IHRvIHVzZSwgZGVmYXVsdHMgdG8gNjU1MzcgKDB4MTAwMDEpLgogKiBAcGFyYW0gW29wdGlvbnNdIHRoZSBvcHRpb25zIHRvIHVzZS4KICogICAgICAgICAgcHJuZyBhIGN1c3RvbSBjcnlwdG8tc2VjdXJlIHBzZXVkby1yYW5kb20gbnVtYmVyIGdlbmVyYXRvciB0byB1c2UsCiAqICAgICAgICAgICAgdGhhdCBtdXN0IGRlZmluZSAiZ2V0Qnl0ZXNTeW5jIi4KICogICAgICAgICAgYWxnb3JpdGhtIHRoZSBhbGdvcml0aG0gdG8gdXNlIChkZWZhdWx0OiAnUFJJTUVJTkMnKS4KICoKICogQHJldHVybiB0aGUgc3RhdGUgb2JqZWN0IHRvIHVzZSB0byBnZW5lcmF0ZSB0aGUga2V5LXBhaXIuCiAqLwpwa2kucnNhLmNyZWF0ZUtleVBhaXJHZW5lcmF0aW9uU3RhdGUgPSBmdW5jdGlvbihiaXRzLCBlLCBvcHRpb25zKSB7CiAgLy8gVE9ETzogbWlncmF0ZSBzdGVwLWJhc2VkIHByaW1lIGdlbmVyYXRpb24gY29kZSB0byBmb3JnZS5wcmltZQoKICAvLyBzZXQgZGVmYXVsdCBiaXRzCiAgaWYodHlwZW9mKGJpdHMpID09PSAnc3RyaW5nJykgewogICAgYml0cyA9IHBhcnNlSW50KGJpdHMsIDEwKTsKICB9CiAgYml0cyA9IGJpdHMgfHwgMjA0ODsKCiAgLy8gY3JlYXRlIHBybmcgd2l0aCBhcGkgdGhhdCBtYXRjaGVzIEJpZ0ludGVnZXIgc2VjdXJlIHJhbmRvbQogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHZhciBwcm5nID0gb3B0aW9ucy5wcm5nIHx8IGZvcmdlLnJhbmRvbTsKICB2YXIgcm5nID0gewogICAgLy8geCBpcyBhbiBhcnJheSB0byBmaWxsIHdpdGggYnl0ZXMKICAgIG5leHRCeXRlczogZnVuY3Rpb24oeCkgewogICAgICB2YXIgYiA9IHBybmcuZ2V0Qnl0ZXNTeW5jKHgubGVuZ3RoKTsKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHgubGVuZ3RoOyArK2kpIHsKICAgICAgICB4W2ldID0gYi5jaGFyQ29kZUF0KGkpOwogICAgICB9CiAgICB9CiAgfTsKCiAgdmFyIGFsZ29yaXRobSA9IG9wdGlvbnMuYWxnb3JpdGhtIHx8ICdQUklNRUlOQyc7CgogIC8vIGNyZWF0ZSBQUklNRUlOQyBhbGdvcml0aG0gc3RhdGUKICB2YXIgcnZhbDsKICBpZihhbGdvcml0aG0gPT09ICdQUklNRUlOQycpIHsKICAgIHJ2YWwgPSB7CiAgICAgIGFsZ29yaXRobTogYWxnb3JpdGhtLAogICAgICBzdGF0ZTogMCwKICAgICAgYml0czogYml0cywKICAgICAgcm5nOiBybmcsCiAgICAgIGVJbnQ6IGUgfHwgNjU1MzcsCiAgICAgIGU6IG5ldyBCaWdJbnRlZ2VyKG51bGwpLAogICAgICBwOiBudWxsLAogICAgICBxOiBudWxsLAogICAgICBxQml0czogYml0cyA+PiAxLAogICAgICBwQml0czogYml0cyAtIChiaXRzID4+IDEpLAogICAgICBwcVN0YXRlOiAwLAogICAgICBudW06IG51bGwsCiAgICAgIGtleXM6IG51bGwKICAgIH07CiAgICBydmFsLmUuZnJvbUludChydmFsLmVJbnQpOwogIH0gZWxzZSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQga2V5IGdlbmVyYXRpb24gYWxnb3JpdGhtOiAnICsgYWxnb3JpdGhtKTsKICB9CgogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEF0dGVtcHRzIHRvIHJ1bnMgdGhlIGtleS1nZW5lcmF0aW9uIGFsZ29yaXRobSBmb3IgYXQgbW9zdCBuIHNlY29uZHMKICogKGFwcHJveGltYXRlbHkpIHVzaW5nIHRoZSBnaXZlbiBzdGF0ZS4gV2hlbiBrZXktZ2VuZXJhdGlvbiBoYXMgY29tcGxldGVkLAogKiB0aGUga2V5cyB3aWxsIGJlIHN0b3JlZCBpbiBzdGF0ZS5rZXlzLgogKgogKiBUbyB1c2UgdGhpcyBmdW5jdGlvbiB0byB1cGRhdGUgYSBVSSB3aGlsZSBnZW5lcmF0aW5nIGEga2V5IG9yIHRvIHByZXZlbnQKICogY2F1c2luZyBicm93c2VyIGxvY2t1cHMvd2FybmluZ3MsIHNldCAibiIgdG8gYSB2YWx1ZSBvdGhlciB0aGFuIDAuIEEKICogc2ltcGxlIHBhdHRlcm4gZm9yIGdlbmVyYXRpbmcgYSBrZXkgYW5kIHNob3dpbmcgYSBwcm9ncmVzcyBpbmRpY2F0b3IgaXM6CiAqCiAqIHZhciBzdGF0ZSA9IHBraS5yc2EuY3JlYXRlS2V5UGFpckdlbmVyYXRpb25TdGF0ZSgyMDQ4KTsKICogdmFyIHN0ZXAgPSBmdW5jdGlvbigpIHsKICogICAvLyBzdGVwIGtleS1nZW5lcmF0aW9uLCBydW4gYWxnb3JpdGhtIGZvciAxMDAgbXMsIHJlcGVhdAogKiAgIGlmKCFmb3JnZS5wa2kucnNhLnN0ZXBLZXlQYWlyR2VuZXJhdGlvblN0YXRlKHN0YXRlLCAxMDApKSB7CiAqICAgICBzZXRUaW1lb3V0KHN0ZXAsIDEpOwogKiAgIH0gZWxzZSB7CiAqICAgICAvLyBrZXktZ2VuZXJhdGlvbiBjb21wbGV0ZQogKiAgICAgLy8gVE9ETzogdHVybiBvZmYgcHJvZ3Jlc3MgaW5kaWNhdG9yIGhlcmUKICogICAgIC8vIFRPRE86IHVzZSB0aGUgZ2VuZXJhdGVkIGtleS1wYWlyIGluICJzdGF0ZS5rZXlzIgogKiAgIH0KICogfTsKICogLy8gVE9ETzogdHVybiBvbiBwcm9ncmVzcyBpbmRpY2F0b3IgaGVyZQogKiBzZXRUaW1lb3V0KHN0ZXAsIDApOwogKgogKiBAcGFyYW0gc3RhdGUgdGhlIHN0YXRlIHRvIHVzZS4KICogQHBhcmFtIG4gdGhlIG1heGltdW0gbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBydW4gdGhlIGFsZ29yaXRobSBmb3IsIDAKICogICAgICAgICAgdG8gcnVuIHRoZSBhbGdvcml0aG0gdG8gY29tcGxldGlvbi4KICoKICogQHJldHVybiB0cnVlIGlmIHRoZSBrZXktZ2VuZXJhdGlvbiBjb21wbGV0ZWQsIGZhbHNlIGlmIG5vdC4KICovCnBraS5yc2Euc3RlcEtleVBhaXJHZW5lcmF0aW9uU3RhdGUgPSBmdW5jdGlvbihzdGF0ZSwgbikgewogIC8vIHNldCBkZWZhdWx0IGFsZ29yaXRobSBpZiBub3Qgc2V0CiAgaWYoISgnYWxnb3JpdGhtJyBpbiBzdGF0ZSkpIHsKICAgIHN0YXRlLmFsZ29yaXRobSA9ICdQUklNRUlOQyc7CiAgfQoKICAvLyBUT0RPOiBtaWdyYXRlIHN0ZXAtYmFzZWQgcHJpbWUgZ2VuZXJhdGlvbiBjb2RlIHRvIGZvcmdlLnByaW1lCiAgLy8gVE9ETzogYWJzdHJhY3QgYXMgUFJJTUVJTkMgYWxnb3JpdGhtCgogIC8vIGRvIGtleSBnZW5lcmF0aW9uIChiYXNlZCBvbiBUb20gV3UncyByc2EuanMsIHNlZSBqc2JuLmpzIGxpY2Vuc2UpCiAgLy8gd2l0aCBzb21lIG1pbm9yIG9wdGltaXphdGlvbnMgYW5kIGRlc2lnbmVkIHRvIHJ1biBpbiBzdGVwcwoKICAvLyBsb2NhbCBzdGF0ZSB2YXJzCiAgdmFyIFRISVJUWSA9IG5ldyBCaWdJbnRlZ2VyKG51bGwpOwogIFRISVJUWS5mcm9tSW50KDMwKTsKICB2YXIgZGVsdGFJZHggPSAwOwogIHZhciBvcF9vciA9IGZ1bmN0aW9uKHgseSkgeyByZXR1cm4geHx5OyB9OwoKICAvLyBrZWVwIHN0ZXBwaW5nIHVudGlsIHRpbWUgbGltaXQgaXMgcmVhY2hlZCBvciBkb25lCiAgdmFyIHQxID0gK25ldyBEYXRlKCk7CiAgdmFyIHQyOwogIHZhciB0b3RhbCA9IDA7CiAgd2hpbGUoc3RhdGUua2V5cyA9PT0gbnVsbCAmJiAobiA8PSAwIHx8IHRvdGFsIDwgbikpIHsKICAgIC8vIGdlbmVyYXRlIHAgb3IgcQogICAgaWYoc3RhdGUuc3RhdGUgPT09IDApIHsKICAgICAgLyogTm90ZTogQWxsIHByaW1lcyBhcmUgb2YgdGhlIGZvcm06CgogICAgICAgIDMwaytpLCBmb3IgaSA8IDMwIGFuZCBnY2QoMzAsIGkpPTEsIHdoZXJlIHRoZXJlIGFyZSA4IHZhbHVlcyBmb3IgaQoKICAgICAgICBXaGVuIHdlIGdlbmVyYXRlIGEgcmFuZG9tIG51bWJlciwgd2UgYWx3YXlzIGFsaWduIGl0IGF0IDMwayArIDEuIEVhY2gKICAgICAgICB0aW1lIHRoZSBudW1iZXIgaXMgZGV0ZXJtaW5lZCBub3QgdG8gYmUgcHJpbWUgd2UgYWRkIHRvIGdldCB0byB0aGUKICAgICAgICBuZXh0ICdpJywgZWc6IGlmIHRoZSBudW1iZXIgd2FzIGF0IDMwayArIDEgd2UgYWRkIDYuICovCiAgICAgIHZhciBiaXRzID0gKHN0YXRlLnAgPT09IG51bGwpID8gc3RhdGUucEJpdHMgOiBzdGF0ZS5xQml0czsKICAgICAgdmFyIGJpdHMxID0gYml0cyAtIDE7CgogICAgICAvLyBnZXQgYSByYW5kb20gbnVtYmVyCiAgICAgIGlmKHN0YXRlLnBxU3RhdGUgPT09IDApIHsKICAgICAgICBzdGF0ZS5udW0gPSBuZXcgQmlnSW50ZWdlcihiaXRzLCBzdGF0ZS5ybmcpOwogICAgICAgIC8vIGZvcmNlIE1TQiBzZXQKICAgICAgICBpZighc3RhdGUubnVtLnRlc3RCaXQoYml0czEpKSB7CiAgICAgICAgICBzdGF0ZS5udW0uYml0d2lzZVRvKAogICAgICAgICAgICBCaWdJbnRlZ2VyLk9ORS5zaGlmdExlZnQoYml0czEpLCBvcF9vciwgc3RhdGUubnVtKTsKICAgICAgICB9CiAgICAgICAgLy8gYWxpZ24gbnVtYmVyIG9uIDMwaysxIGJvdW5kYXJ5CiAgICAgICAgc3RhdGUubnVtLmRBZGRPZmZzZXQoMzEgLSBzdGF0ZS5udW0ubW9kKFRISVJUWSkuYnl0ZVZhbHVlKCksIDApOwogICAgICAgIGRlbHRhSWR4ID0gMDsKCiAgICAgICAgKytzdGF0ZS5wcVN0YXRlOwogICAgICB9IGVsc2UgaWYoc3RhdGUucHFTdGF0ZSA9PT0gMSkgewogICAgICAgIC8vIHRyeSB0byBtYWtlIHRoZSBudW1iZXIgYSBwcmltZQogICAgICAgIGlmKHN0YXRlLm51bS5iaXRMZW5ndGgoKSA+IGJpdHMpIHsKICAgICAgICAgIC8vIG92ZXJmbG93LCB0cnkgYWdhaW4KICAgICAgICAgIHN0YXRlLnBxU3RhdGUgPSAwOwogICAgICAgICAgLy8gZG8gcHJpbWFsaXR5IHRlc3QKICAgICAgICB9IGVsc2UgaWYoc3RhdGUubnVtLmlzUHJvYmFibGVQcmltZSgKICAgICAgICAgIF9nZXRNaWxsZXJSYWJpblRlc3RzKHN0YXRlLm51bS5iaXRMZW5ndGgoKSkpKSB7CiAgICAgICAgICArK3N0YXRlLnBxU3RhdGU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8vIGdldCBuZXh0IHBvdGVudGlhbCBwcmltZQogICAgICAgICAgc3RhdGUubnVtLmRBZGRPZmZzZXQoR0NEXzMwX0RFTFRBW2RlbHRhSWR4KysgJSA4XSwgMCk7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYoc3RhdGUucHFTdGF0ZSA9PT0gMikgewogICAgICAgIC8vIGVuc3VyZSBudW1iZXIgaXMgY29wcmltZSB3aXRoIGUKICAgICAgICBzdGF0ZS5wcVN0YXRlID0KICAgICAgICAgIChzdGF0ZS5udW0uc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpLmdjZChzdGF0ZS5lKQogICAgICAgICAgLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT09IDApID8gMyA6IDA7CiAgICAgIH0gZWxzZSBpZihzdGF0ZS5wcVN0YXRlID09PSAzKSB7CiAgICAgICAgLy8gc3RvcmUgcCBvciBxCiAgICAgICAgc3RhdGUucHFTdGF0ZSA9IDA7CiAgICAgICAgaWYoc3RhdGUucCA9PT0gbnVsbCkgewogICAgICAgICAgc3RhdGUucCA9IHN0YXRlLm51bTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc3RhdGUucSA9IHN0YXRlLm51bTsKICAgICAgICB9CgogICAgICAgIC8vIGFkdmFuY2Ugc3RhdGUgaWYgYm90aCBwIGFuZCBxIGFyZSByZWFkeQogICAgICAgIGlmKHN0YXRlLnAgIT09IG51bGwgJiYgc3RhdGUucSAhPT0gbnVsbCkgewogICAgICAgICAgKytzdGF0ZS5zdGF0ZTsKICAgICAgICB9CiAgICAgICAgc3RhdGUubnVtID0gbnVsbDsKICAgICAgfQogICAgfSBlbHNlIGlmKHN0YXRlLnN0YXRlID09PSAxKSB7CiAgICAgIC8vIGVuc3VyZSBwIGlzIGxhcmdlciB0aGFuIHEgKHN3YXAgdGhlbSBpZiBub3QpCiAgICAgIGlmKHN0YXRlLnAuY29tcGFyZVRvKHN0YXRlLnEpIDwgMCkgewogICAgICAgIHN0YXRlLm51bSA9IHN0YXRlLnA7CiAgICAgICAgc3RhdGUucCA9IHN0YXRlLnE7CiAgICAgICAgc3RhdGUucSA9IHN0YXRlLm51bTsKICAgICAgfQogICAgICArK3N0YXRlLnN0YXRlOwogICAgfSBlbHNlIGlmKHN0YXRlLnN0YXRlID09PSAyKSB7CiAgICAgIC8vIGNvbXB1dGUgcGhpOiAocCAtIDEpKHEgLSAxKSAoRXVsZXIncyB0b3RpZW50IGZ1bmN0aW9uKQogICAgICBzdGF0ZS5wMSA9IHN0YXRlLnAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpOwogICAgICBzdGF0ZS5xMSA9IHN0YXRlLnEuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpOwogICAgICBzdGF0ZS5waGkgPSBzdGF0ZS5wMS5tdWx0aXBseShzdGF0ZS5xMSk7CiAgICAgICsrc3RhdGUuc3RhdGU7CiAgICB9IGVsc2UgaWYoc3RhdGUuc3RhdGUgPT09IDMpIHsKICAgICAgLy8gZW5zdXJlIGUgYW5kIHBoaSBhcmUgY29wcmltZQogICAgICBpZihzdGF0ZS5waGkuZ2NkKHN0YXRlLmUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgPT09IDApIHsKICAgICAgICAvLyBwaGkgYW5kIGUgYXJlIGNvcHJpbWUsIGFkdmFuY2UKICAgICAgICArK3N0YXRlLnN0YXRlOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIHBoaSBhbmQgZSBhcmVuJ3QgY29wcmltZSwgc28gZ2VuZXJhdGUgYSBuZXcgcCBhbmQgcQogICAgICAgIHN0YXRlLnAgPSBudWxsOwogICAgICAgIHN0YXRlLnEgPSBudWxsOwogICAgICAgIHN0YXRlLnN0YXRlID0gMDsKICAgICAgfQogICAgfSBlbHNlIGlmKHN0YXRlLnN0YXRlID09PSA0KSB7CiAgICAgIC8vIGNyZWF0ZSBuLCBlbnN1cmUgbiBpcyBoYXMgdGhlIHJpZ2h0IG51bWJlciBvZiBiaXRzCiAgICAgIHN0YXRlLm4gPSBzdGF0ZS5wLm11bHRpcGx5KHN0YXRlLnEpOwoKICAgICAgLy8gZW5zdXJlIG4gaXMgcmlnaHQgbnVtYmVyIG9mIGJpdHMKICAgICAgaWYoc3RhdGUubi5iaXRMZW5ndGgoKSA9PT0gc3RhdGUuYml0cykgewogICAgICAgIC8vIHN1Y2Nlc3MsIGFkdmFuY2UKICAgICAgICArK3N0YXRlLnN0YXRlOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIGZhaWxlZCwgZ2V0IG5ldyBxCiAgICAgICAgc3RhdGUucSA9IG51bGw7CiAgICAgICAgc3RhdGUuc3RhdGUgPSAwOwogICAgICB9CiAgICB9IGVsc2UgaWYoc3RhdGUuc3RhdGUgPT09IDUpIHsKICAgICAgLy8gc2V0IGtleXMKICAgICAgdmFyIGQgPSBzdGF0ZS5lLm1vZEludmVyc2Uoc3RhdGUucGhpKTsKICAgICAgc3RhdGUua2V5cyA9IHsKICAgICAgICBwcml2YXRlS2V5OiBwa2kucnNhLnNldFByaXZhdGVLZXkoCiAgICAgICAgICBzdGF0ZS5uLCBzdGF0ZS5lLCBkLCBzdGF0ZS5wLCBzdGF0ZS5xLAogICAgICAgICAgZC5tb2Qoc3RhdGUucDEpLCBkLm1vZChzdGF0ZS5xMSksCiAgICAgICAgICBzdGF0ZS5xLm1vZEludmVyc2Uoc3RhdGUucCkpLAogICAgICAgIHB1YmxpY0tleTogcGtpLnJzYS5zZXRQdWJsaWNLZXkoc3RhdGUubiwgc3RhdGUuZSkKICAgICAgfTsKICAgIH0KCiAgICAvLyB1cGRhdGUgdGltaW5nCiAgICB0MiA9ICtuZXcgRGF0ZSgpOwogICAgdG90YWwgKz0gdDIgLSB0MTsKICAgIHQxID0gdDI7CiAgfQoKICByZXR1cm4gc3RhdGUua2V5cyAhPT0gbnVsbDsKfTsKCi8qKgogKiBHZW5lcmF0ZXMgYW4gUlNBIHB1YmxpYy1wcml2YXRlIGtleSBwYWlyIGluIGEgc2luZ2xlIGNhbGwuCiAqCiAqIFRvIGdlbmVyYXRlIGEga2V5LXBhaXIgaW4gc3RlcHMgKHRvIGFsbG93IGZvciBwcm9ncmVzcyB1cGRhdGVzIGFuZCB0bwogKiBwcmV2ZW50IGJsb2NraW5nIG9yIHdhcm5pbmdzIGluIHNsb3cgYnJvd3NlcnMpIHRoZW4gdXNlIHRoZSBrZXktcGFpcgogKiBnZW5lcmF0aW9uIHN0YXRlIGZ1bmN0aW9ucy4KICoKICogVG8gZ2VuZXJhdGUgYSBrZXktcGFpciBhc3luY2hyb25vdXNseSAoZWl0aGVyIHRocm91Z2ggd2ViLXdvcmtlcnMsIGlmCiAqIGF2YWlsYWJsZSwgb3IgYnkgYnJlYWtpbmcgdXAgdGhlIHdvcmsgb24gdGhlIG1haW4gdGhyZWFkKSwgcGFzcyBhCiAqIGNhbGxiYWNrIGZ1bmN0aW9uLgogKgogKiBAcGFyYW0gW2JpdHNdIHRoZSBzaXplIGZvciB0aGUgcHJpdmF0ZSBrZXkgaW4gYml0cywgZGVmYXVsdHMgdG8gMjA0OC4KICogQHBhcmFtIFtlXSB0aGUgcHVibGljIGV4cG9uZW50IHRvIHVzZSwgZGVmYXVsdHMgdG8gNjU1MzcuCiAqIEBwYXJhbSBbb3B0aW9uc10gb3B0aW9ucyBmb3Iga2V5LXBhaXIgZ2VuZXJhdGlvbiwgaWYgZ2l2ZW4gdGhlbiAnYml0cycKICogICAgICAgICAgYW5kICdlJyBtdXN0ICpub3QqIGJlIGdpdmVuOgogKiAgICAgICAgICBiaXRzIHRoZSBzaXplIGZvciB0aGUgcHJpdmF0ZSBrZXkgaW4gYml0cywgKGRlZmF1bHQ6IDIwNDgpLgogKiAgICAgICAgICBlIHRoZSBwdWJsaWMgZXhwb25lbnQgdG8gdXNlLCAoZGVmYXVsdDogNjU1MzcgKDB4MTAwMDEpKS4KICogICAgICAgICAgd29ya2VyU2NyaXB0IHRoZSB3b3JrZXIgc2NyaXB0IFVSTC4KICogICAgICAgICAgd29ya2VycyB0aGUgbnVtYmVyIG9mIHdlYiB3b3JrZXJzIChpZiBzdXBwb3J0ZWQpIHRvIHVzZSwKICogICAgICAgICAgICAoZGVmYXVsdDogMikuCiAqICAgICAgICAgIHdvcmtMb2FkIHRoZSBzaXplIG9mIHRoZSB3b3JrIGxvYWQsIGllOiBudW1iZXIgb2YgcG9zc2libGUgcHJpbWUKICogICAgICAgICAgICBudW1iZXJzIGZvciBlYWNoIHdlYiB3b3JrZXIgdG8gY2hlY2sgcGVyIHdvcmsgYXNzaWdubWVudCwKICogICAgICAgICAgICAoZGVmYXVsdDogMTAwKS4KICogICAgICAgICAgZSB0aGUgcHVibGljIGV4cG9uZW50IHRvIHVzZSwgZGVmYXVsdHMgdG8gNjU1MzcuCiAqICAgICAgICAgIHBybmcgYSBjdXN0b20gY3J5cHRvLXNlY3VyZSBwc2V1ZG8tcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdG8gdXNlLAogKiAgICAgICAgICAgIHRoYXQgbXVzdCBkZWZpbmUgImdldEJ5dGVzU3luYyIuCiAqICAgICAgICAgIGFsZ29yaXRobSB0aGUgYWxnb3JpdGhtIHRvIHVzZSAoZGVmYXVsdDogJ1BSSU1FSU5DJykuCiAqIEBwYXJhbSBbY2FsbGJhY2soZXJyLCBrZXlwYWlyKV0gY2FsbGVkIG9uY2UgdGhlIG9wZXJhdGlvbiBjb21wbGV0ZXMuCiAqCiAqIEByZXR1cm4gYW4gb2JqZWN0IHdpdGggcHJpdmF0ZUtleSBhbmQgcHVibGljS2V5IHByb3BlcnRpZXMuCiAqLwpwa2kucnNhLmdlbmVyYXRlS2V5UGFpciA9IGZ1bmN0aW9uKGJpdHMsIGUsIG9wdGlvbnMsIGNhbGxiYWNrKSB7CiAgLy8gKGJpdHMpLCAob3B0aW9ucyksIChjYWxsYmFjaykKICBpZihhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7CiAgICBpZih0eXBlb2YgYml0cyA9PT0gJ29iamVjdCcpIHsKICAgICAgb3B0aW9ucyA9IGJpdHM7CiAgICAgIGJpdHMgPSB1bmRlZmluZWQ7CiAgICB9IGVsc2UgaWYodHlwZW9mIGJpdHMgPT09ICdmdW5jdGlvbicpIHsKICAgICAgY2FsbGJhY2sgPSBiaXRzOwogICAgICBiaXRzID0gdW5kZWZpbmVkOwogICAgfQogIH0gZWxzZSBpZihhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7CiAgICAvLyAoYml0cywgZSksIChiaXRzLCBvcHRpb25zKSwgKGJpdHMsIGNhbGxiYWNrKSwgKG9wdGlvbnMsIGNhbGxiYWNrKQogICAgaWYodHlwZW9mIGJpdHMgPT09ICdudW1iZXInKSB7CiAgICAgIGlmKHR5cGVvZiBlID09PSAnZnVuY3Rpb24nKSB7CiAgICAgICAgY2FsbGJhY2sgPSBlOwogICAgICAgIGUgPSB1bmRlZmluZWQ7CiAgICAgIH0gZWxzZSBpZih0eXBlb2YgZSAhPT0gJ251bWJlcicpIHsKICAgICAgICBvcHRpb25zID0gZTsKICAgICAgICBlID0gdW5kZWZpbmVkOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBvcHRpb25zID0gYml0czsKICAgICAgY2FsbGJhY2sgPSBlOwogICAgICBiaXRzID0gdW5kZWZpbmVkOwogICAgICBlID0gdW5kZWZpbmVkOwogICAgfQogIH0gZWxzZSBpZihhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7CiAgICAvLyAoYml0cywgZSwgb3B0aW9ucyksIChiaXRzLCBlLCBjYWxsYmFjayksIChiaXRzLCBvcHRpb25zLCBjYWxsYmFjaykKICAgIGlmKHR5cGVvZiBlID09PSAnbnVtYmVyJykgewogICAgICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgIGNhbGxiYWNrID0gb3B0aW9uczsKICAgICAgICBvcHRpb25zID0gdW5kZWZpbmVkOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBjYWxsYmFjayA9IG9wdGlvbnM7CiAgICAgIG9wdGlvbnMgPSBlOwogICAgICBlID0gdW5kZWZpbmVkOwogICAgfQogIH0KICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICBpZihiaXRzID09PSB1bmRlZmluZWQpIHsKICAgIGJpdHMgPSBvcHRpb25zLmJpdHMgfHwgMjA0ODsKICB9CiAgaWYoZSA9PT0gdW5kZWZpbmVkKSB7CiAgICBlID0gb3B0aW9ucy5lIHx8IDB4MTAwMDE7CiAgfQogIHZhciBzdGF0ZSA9IHBraS5yc2EuY3JlYXRlS2V5UGFpckdlbmVyYXRpb25TdGF0ZShiaXRzLCBlLCBvcHRpb25zKTsKICBpZighY2FsbGJhY2spIHsKICAgIHBraS5yc2Euc3RlcEtleVBhaXJHZW5lcmF0aW9uU3RhdGUoc3RhdGUsIDApOwogICAgcmV0dXJuIHN0YXRlLmtleXM7CiAgfQogIF9nZW5lcmF0ZUtleVBhaXIoc3RhdGUsIG9wdGlvbnMsIGNhbGxiYWNrKTsKfTsKCi8qKgogKiBTZXRzIGFuIFJTQSBwdWJsaWMga2V5IGZyb20gQmlnSW50ZWdlcnMgbW9kdWx1cyBhbmQgZXhwb25lbnQuCiAqCiAqIEBwYXJhbSBuIHRoZSBtb2R1bHVzLgogKiBAcGFyYW0gZSB0aGUgZXhwb25lbnQuCiAqCiAqIEByZXR1cm4gdGhlIHB1YmxpYyBrZXkuCiAqLwpwa2kuc2V0UnNhUHVibGljS2V5ID0gcGtpLnJzYS5zZXRQdWJsaWNLZXkgPSBmdW5jdGlvbihuLCBlKSB7CiAgdmFyIGtleSA9IHsKICAgIG46IG4sCiAgICBlOiBlCiAgfTsKCiAgLyoqCiAgICogRW5jcnlwdHMgdGhlIGdpdmVuIGRhdGEgd2l0aCB0aGlzIHB1YmxpYyBrZXkuIE5ld2VyIGFwcGxpY2F0aW9ucwogICAqIHNob3VsZCB1c2UgdGhlICdSU0EtT0FFUCcgZGVjcnlwdGlvbiBzY2hlbWUsICdSU0FFUy1QS0NTMS1WMV81JyBpcyBmb3IKICAgKiBsZWdhY3kgYXBwbGljYXRpb25zLgogICAqCiAgICogQHBhcmFtIGRhdGEgdGhlIGJ5dGUgc3RyaW5nIHRvIGVuY3J5cHQuCiAgICogQHBhcmFtIHNjaGVtZSB0aGUgZW5jcnlwdGlvbiBzY2hlbWUgdG8gdXNlOgogICAqICAgICAgICAgICdSU0FFUy1QS0NTMS1WMV81JyAoZGVmYXVsdCksCiAgICogICAgICAgICAgJ1JTQS1PQUVQJywKICAgKiAgICAgICAgICAnUkFXJywgJ05PTkUnLCBvciBudWxsIHRvIHBlcmZvcm0gcmF3IFJTQSBlbmNyeXB0aW9uLAogICAqICAgICAgICAgIGFuIG9iamVjdCB3aXRoIGFuICdlbmNvZGUnIHByb3BlcnR5IHNldCB0byBhIGZ1bmN0aW9uCiAgICogICAgICAgICAgd2l0aCB0aGUgc2lnbmF0dXJlICdmdW5jdGlvbihkYXRhLCBrZXkpJyB0aGF0IHJldHVybnMKICAgKiAgICAgICAgICBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZyByZXByZXNlbnRpbmcgdGhlIGVuY29kZWQgZGF0YS4KICAgKiBAcGFyYW0gc2NoZW1lT3B0aW9ucyBhbnkgc2NoZW1lLXNwZWNpZmljIG9wdGlvbnMuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBlbmNyeXB0ZWQgYnl0ZSBzdHJpbmcuCiAgICovCiAga2V5LmVuY3J5cHQgPSBmdW5jdGlvbihkYXRhLCBzY2hlbWUsIHNjaGVtZU9wdGlvbnMpIHsKICAgIGlmKHR5cGVvZiBzY2hlbWUgPT09ICdzdHJpbmcnKSB7CiAgICAgIHNjaGVtZSA9IHNjaGVtZS50b1VwcGVyQ2FzZSgpOwogICAgfSBlbHNlIGlmKHNjaGVtZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIHNjaGVtZSA9ICdSU0FFUy1QS0NTMS1WMV81JzsKICAgIH0KCiAgICBpZihzY2hlbWUgPT09ICdSU0FFUy1QS0NTMS1WMV81JykgewogICAgICBzY2hlbWUgPSB7CiAgICAgICAgZW5jb2RlOiBmdW5jdGlvbihtLCBrZXksIHB1YikgewogICAgICAgICAgcmV0dXJuIF9lbmNvZGVQa2NzMV92MV81KG0sIGtleSwgMHgwMikuZ2V0Qnl0ZXMoKTsKICAgICAgICB9CiAgICAgIH07CiAgICB9IGVsc2UgaWYoc2NoZW1lID09PSAnUlNBLU9BRVAnIHx8IHNjaGVtZSA9PT0gJ1JTQUVTLU9BRVAnKSB7CiAgICAgIHNjaGVtZSA9IHsKICAgICAgICBlbmNvZGU6IGZ1bmN0aW9uKG0sIGtleSkgewogICAgICAgICAgcmV0dXJuIGZvcmdlLnBrY3MxLmVuY29kZV9yc2Ffb2FlcChrZXksIG0sIHNjaGVtZU9wdGlvbnMpOwogICAgICAgIH0KICAgICAgfTsKICAgIH0gZWxzZSBpZihbJ1JBVycsICdOT05FJywgJ05VTEwnLCBudWxsXS5pbmRleE9mKHNjaGVtZSkgIT09IC0xKSB7CiAgICAgIHNjaGVtZSA9IHsgZW5jb2RlOiBmdW5jdGlvbihlKSB7IHJldHVybiBlOyB9IH07CiAgICB9IGVsc2UgaWYodHlwZW9mIHNjaGVtZSA9PT0gJ3N0cmluZycpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBlbmNyeXB0aW9uIHNjaGVtZTogIicgKyBzY2hlbWUgKyAnIi4nKTsKICAgIH0KCiAgICAvLyBkbyBzY2hlbWUtYmFzZWQgZW5jb2RpbmcgdGhlbiByc2EgZW5jcnlwdGlvbgogICAgdmFyIGUgPSBzY2hlbWUuZW5jb2RlKGRhdGEsIGtleSwgdHJ1ZSk7CiAgICByZXR1cm4gcGtpLnJzYS5lbmNyeXB0KGUsIGtleSwgdHJ1ZSk7CiAgfTsKCiAgLyoqCiAgICogVmVyaWZpZXMgdGhlIGdpdmVuIHNpZ25hdHVyZSBhZ2FpbnN0IHRoZSBnaXZlbiBkaWdlc3QuCiAgICoKICAgKiBQS0NTIzEgc3VwcG9ydHMgbXVsdGlwbGUgKGN1cnJlbnRseSB0d28pIHNpZ25hdHVyZSBzY2hlbWVzOgogICAqIFJTQVNTQS1QS0NTMS1WMV81IGFuZCBSU0FTU0EtUFNTLgogICAqCiAgICogQnkgZGVmYXVsdCB0aGlzIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlICJvbGQgc2NoZW1lIiwgaS5lLgogICAqIFJTQVNTQS1QS0NTMS1WMV81LCBpbiB3aGljaCBjYXNlIG9uY2UgUlNBLWRlY3J5cHRlZCwgdGhlCiAgICogc2lnbmF0dXJlIGlzIGFuIE9DVEVUIFNUUklORyB0aGF0IGhvbGRzIGEgRGlnZXN0SW5mby4KICAgKgogICAqIERpZ2VzdEluZm8gOjo9IFNFUVVFTkNFIHsKICAgKiAgIGRpZ2VzdEFsZ29yaXRobSBEaWdlc3RBbGdvcml0aG1JZGVudGlmaWVyLAogICAqICAgZGlnZXN0IERpZ2VzdAogICAqIH0KICAgKiBEaWdlc3RBbGdvcml0aG1JZGVudGlmaWVyIDo6PSBBbGdvcml0aG1JZGVudGlmaWVyCiAgICogRGlnZXN0IDo6PSBPQ1RFVCBTVFJJTkcKICAgKgogICAqIFRvIHBlcmZvcm0gUFNTIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24sIHByb3ZpZGUgYW4gaW5zdGFuY2UKICAgKiBvZiBGb3JnZSBQU1Mgb2JqZWN0IGFzIHRoZSBzY2hlbWUgcGFyYW1ldGVyLgogICAqCiAgICogQHBhcmFtIGRpZ2VzdCB0aGUgbWVzc2FnZSBkaWdlc3QgaGFzaCB0byBjb21wYXJlIGFnYWluc3QgdGhlIHNpZ25hdHVyZSwKICAgKiAgICAgICAgICBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZy4KICAgKiBAcGFyYW0gc2lnbmF0dXJlIHRoZSBzaWduYXR1cmUgdG8gdmVyaWZ5LCBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZy4KICAgKiBAcGFyYW0gc2NoZW1lIHNpZ25hdHVyZSB2ZXJpZmljYXRpb24gc2NoZW1lIHRvIHVzZToKICAgKiAgICAgICAgICAnUlNBU1NBLVBLQ1MxLVYxXzUnIG9yIHVuZGVmaW5lZCBmb3IgUlNBU1NBIFBLQ1MjMSB2MS41LAogICAqICAgICAgICAgIGEgRm9yZ2UgUFNTIG9iamVjdCBmb3IgUlNBU1NBLVBTUywKICAgKiAgICAgICAgICAnTk9ORScgb3IgbnVsbCBmb3Igbm9uZSwgRGlnZXN0SW5mbyB3aWxsIG5vdCBiZSBleHBlY3RlZCwgYnV0CiAgICogICAgICAgICAgICBQS0NTIzEgdjEuNSBwYWRkaW5nIHdpbGwgc3RpbGwgYmUgdXNlZC4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgc2lnbmF0dXJlIHdhcyB2ZXJpZmllZCwgZmFsc2UgaWYgbm90LgogICAqLwogICBrZXkudmVyaWZ5ID0gZnVuY3Rpb24oZGlnZXN0LCBzaWduYXR1cmUsIHNjaGVtZSkgewogICAgIGlmKHR5cGVvZiBzY2hlbWUgPT09ICdzdHJpbmcnKSB7CiAgICAgICBzY2hlbWUgPSBzY2hlbWUudG9VcHBlckNhc2UoKTsKICAgICB9IGVsc2UgaWYoc2NoZW1lID09PSB1bmRlZmluZWQpIHsKICAgICAgIHNjaGVtZSA9ICdSU0FTU0EtUEtDUzEtVjFfNSc7CiAgICAgfQoKICAgICBpZihzY2hlbWUgPT09ICdSU0FTU0EtUEtDUzEtVjFfNScpIHsKICAgICAgIHNjaGVtZSA9IHsKICAgICAgICAgdmVyaWZ5OiBmdW5jdGlvbihkaWdlc3QsIGQpIHsKICAgICAgICAgICAvLyByZW1vdmUgcGFkZGluZwogICAgICAgICAgIGQgPSBfZGVjb2RlUGtjczFfdjFfNShkLCBrZXksIHRydWUpOwogICAgICAgICAgIC8vIGQgaXMgQVNOLjEgQkVSLWVuY29kZWQgRGlnZXN0SW5mbwogICAgICAgICAgIHZhciBvYmogPSBhc24xLmZyb21EZXIoZCk7CiAgICAgICAgICAgLy8gY29tcGFyZSB0aGUgZ2l2ZW4gZGlnZXN0IHRvIHRoZSBkZWNyeXB0ZWQgb25lCiAgICAgICAgICAgcmV0dXJuIGRpZ2VzdCA9PT0gb2JqLnZhbHVlWzFdLnZhbHVlOwogICAgICAgICB9CiAgICAgICB9OwogICAgIH0gZWxzZSBpZihzY2hlbWUgPT09ICdOT05FJyB8fCBzY2hlbWUgPT09ICdOVUxMJyB8fCBzY2hlbWUgPT09IG51bGwpIHsKICAgICAgIHNjaGVtZSA9IHsKICAgICAgICAgdmVyaWZ5OiBmdW5jdGlvbihkaWdlc3QsIGQpIHsKICAgICAgICAgICAvLyByZW1vdmUgcGFkZGluZwogICAgICAgICAgIGQgPSBfZGVjb2RlUGtjczFfdjFfNShkLCBrZXksIHRydWUpOwogICAgICAgICAgIHJldHVybiBkaWdlc3QgPT09IGQ7CiAgICAgICAgIH0KICAgICAgIH07CiAgICAgfQoKICAgICAvLyBkbyByc2EgZGVjcnlwdGlvbiB3L28gYW55IGRlY29kaW5nLCB0aGVuIHZlcmlmeSAtLSB3aGljaCBkb2VzIGRlY29kaW5nCiAgICAgdmFyIGQgPSBwa2kucnNhLmRlY3J5cHQoc2lnbmF0dXJlLCBrZXksIHRydWUsIGZhbHNlKTsKICAgICByZXR1cm4gc2NoZW1lLnZlcmlmeShkaWdlc3QsIGQsIGtleS5uLmJpdExlbmd0aCgpKTsKICB9OwoKICByZXR1cm4ga2V5Owp9OwoKLyoqCiAqIFNldHMgYW4gUlNBIHByaXZhdGUga2V5IGZyb20gQmlnSW50ZWdlcnMgbW9kdWx1cywgZXhwb25lbnQsIHByaW1lcywKICogcHJpbWUgZXhwb25lbnRzLCBhbmQgbW9kdWxhciBtdWx0aXBsaWNhdGl2ZSBpbnZlcnNlLgogKgogKiBAcGFyYW0gbiB0aGUgbW9kdWx1cy4KICogQHBhcmFtIGUgdGhlIHB1YmxpYyBleHBvbmVudC4KICogQHBhcmFtIGQgdGhlIHByaXZhdGUgZXhwb25lbnQgKChpbnZlcnNlIG9mIGUpIG1vZCBuKS4KICogQHBhcmFtIHAgdGhlIGZpcnN0IHByaW1lLgogKiBAcGFyYW0gcSB0aGUgc2Vjb25kIHByaW1lLgogKiBAcGFyYW0gZFAgZXhwb25lbnQxIChkIG1vZCAocC0xKSkuCiAqIEBwYXJhbSBkUSBleHBvbmVudDIgKGQgbW9kIChxLTEpKS4KICogQHBhcmFtIHFJbnYgKChpbnZlcnNlIG9mIHEpIG1vZCBwKQogKgogKiBAcmV0dXJuIHRoZSBwcml2YXRlIGtleS4KICovCnBraS5zZXRSc2FQcml2YXRlS2V5ID0gcGtpLnJzYS5zZXRQcml2YXRlS2V5ID0gZnVuY3Rpb24oCiAgbiwgZSwgZCwgcCwgcSwgZFAsIGRRLCBxSW52KSB7CiAgdmFyIGtleSA9IHsKICAgIG46IG4sCiAgICBlOiBlLAogICAgZDogZCwKICAgIHA6IHAsCiAgICBxOiBxLAogICAgZFA6IGRQLAogICAgZFE6IGRRLAogICAgcUludjogcUludgogIH07CgogIC8qKgogICAqIERlY3J5cHRzIHRoZSBnaXZlbiBkYXRhIHdpdGggdGhpcyBwcml2YXRlIGtleS4gVGhlIGRlY3J5cHRpb24gc2NoZW1lCiAgICogbXVzdCBtYXRjaCB0aGUgb25lIHVzZWQgdG8gZW5jcnlwdCB0aGUgZGF0YS4KICAgKgogICAqIEBwYXJhbSBkYXRhIHRoZSBieXRlIHN0cmluZyB0byBkZWNyeXB0LgogICAqIEBwYXJhbSBzY2hlbWUgdGhlIGRlY3J5cHRpb24gc2NoZW1lIHRvIHVzZToKICAgKiAgICAgICAgICAnUlNBRVMtUEtDUzEtVjFfNScgKGRlZmF1bHQpLAogICAqICAgICAgICAgICdSU0EtT0FFUCcsCiAgICogICAgICAgICAgJ1JBVycsICdOT05FJywgb3IgbnVsbCB0byBwZXJmb3JtIHJhdyBSU0EgZGVjcnlwdGlvbi4KICAgKiBAcGFyYW0gc2NoZW1lT3B0aW9ucyBhbnkgc2NoZW1lLXNwZWNpZmljIG9wdGlvbnMuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBkZWNyeXB0ZWQgYnl0ZSBzdHJpbmcuCiAgICovCiAga2V5LmRlY3J5cHQgPSBmdW5jdGlvbihkYXRhLCBzY2hlbWUsIHNjaGVtZU9wdGlvbnMpIHsKICAgIGlmKHR5cGVvZiBzY2hlbWUgPT09ICdzdHJpbmcnKSB7CiAgICAgIHNjaGVtZSA9IHNjaGVtZS50b1VwcGVyQ2FzZSgpOwogICAgfSBlbHNlIGlmKHNjaGVtZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgIHNjaGVtZSA9ICdSU0FFUy1QS0NTMS1WMV81JzsKICAgIH0KCiAgICAvLyBkbyByc2EgZGVjcnlwdGlvbiB3L28gYW55IGRlY29kaW5nCiAgICB2YXIgZCA9IHBraS5yc2EuZGVjcnlwdChkYXRhLCBrZXksIGZhbHNlLCBmYWxzZSk7CgogICAgaWYoc2NoZW1lID09PSAnUlNBRVMtUEtDUzEtVjFfNScpIHsKICAgICAgc2NoZW1lID0geyBkZWNvZGU6IF9kZWNvZGVQa2NzMV92MV81IH07CiAgICB9IGVsc2UgaWYoc2NoZW1lID09PSAnUlNBLU9BRVAnIHx8IHNjaGVtZSA9PT0gJ1JTQUVTLU9BRVAnKSB7CiAgICAgIHNjaGVtZSA9IHsKICAgICAgICBkZWNvZGU6IGZ1bmN0aW9uKGQsIGtleSkgewogICAgICAgICAgcmV0dXJuIGZvcmdlLnBrY3MxLmRlY29kZV9yc2Ffb2FlcChrZXksIGQsIHNjaGVtZU9wdGlvbnMpOwogICAgICAgIH0KICAgICAgfTsKICAgIH0gZWxzZSBpZihbJ1JBVycsICdOT05FJywgJ05VTEwnLCBudWxsXS5pbmRleE9mKHNjaGVtZSkgIT09IC0xKSB7CiAgICAgIHNjaGVtZSA9IHsgZGVjb2RlOiBmdW5jdGlvbihkKSB7IHJldHVybiBkOyB9IH07CiAgICB9IGVsc2UgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGVuY3J5cHRpb24gc2NoZW1lOiAiJyArIHNjaGVtZSArICciLicpOwogICAgfQoKICAgIC8vIGRlY29kZSBhY2NvcmRpbmcgdG8gc2NoZW1lCiAgICByZXR1cm4gc2NoZW1lLmRlY29kZShkLCBrZXksIGZhbHNlKTsKICB9OwoKICAvKioKICAgKiBTaWducyB0aGUgZ2l2ZW4gZGlnZXN0LCBwcm9kdWNpbmcgYSBzaWduYXR1cmUuCiAgICoKICAgKiBQS0NTIzEgc3VwcG9ydHMgbXVsdGlwbGUgKGN1cnJlbnRseSB0d28pIHNpZ25hdHVyZSBzY2hlbWVzOgogICAqIFJTQVNTQS1QS0NTMS1WMV81IGFuZCBSU0FTU0EtUFNTLgogICAqCiAgICogQnkgZGVmYXVsdCB0aGlzIGltcGxlbWVudGF0aW9uIHVzZXMgdGhlICJvbGQgc2NoZW1lIiwgaS5lLgogICAqIFJTQVNTQS1QS0NTMS1WMV81LiBJbiBvcmRlciB0byBnZW5lcmF0ZSBhIFBTUyBzaWduYXR1cmUsIHByb3ZpZGUKICAgKiBhbiBpbnN0YW5jZSBvZiBGb3JnZSBQU1Mgb2JqZWN0IGFzIHRoZSBzY2hlbWUgcGFyYW1ldGVyLgogICAqCiAgICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3Qgd2l0aCB0aGUgaGFzaCB0byBzaWduLgogICAqIEBwYXJhbSBzY2hlbWUgdGhlIHNpZ25hdHVyZSBzY2hlbWUgdG8gdXNlOgogICAqICAgICAgICAgICdSU0FTU0EtUEtDUzEtVjFfNScgb3IgdW5kZWZpbmVkIGZvciBSU0FTU0EgUEtDUyMxIHYxLjUsCiAgICogICAgICAgICAgYSBGb3JnZSBQU1Mgb2JqZWN0IGZvciBSU0FTU0EtUFNTLAogICAqICAgICAgICAgICdOT05FJyBvciBudWxsIGZvciBub25lLCBEaWdlc3RJbmZvIHdpbGwgbm90IGJlIHVzZWQgYnV0CiAgICogICAgICAgICAgICBQS0NTIzEgdjEuNSBwYWRkaW5nIHdpbGwgc3RpbGwgYmUgdXNlZC4KICAgKgogICAqIEByZXR1cm4gdGhlIHNpZ25hdHVyZSBhcyBhIGJ5dGUgc3RyaW5nLgogICAqLwogIGtleS5zaWduID0gZnVuY3Rpb24obWQsIHNjaGVtZSkgewogICAgLyogTm90ZTogVGhlIGludGVybmFsIGltcGxlbWVudGF0aW9uIG9mIFJTQSBvcGVyYXRpb25zIGlzIGJlaW5nCiAgICAgIHRyYW5zaXRpb25lZCBhd2F5IGZyb20gYSBQS0NTIzEgdjEuNSBoYXJkLWNvZGVkIHNjaGVtZS4gU29tZSBsZWdhY3kKICAgICAgY29kZSBsaWtlIHRoZSB1c2Ugb2YgYW4gZW5jb2RpbmcgYmxvY2sgaWRlbnRpZmllciAnYnQnIHdpbGwgZXZlbnR1YWxseQogICAgICBiZSByZW1vdmVkLiAqLwoKICAgIC8vIHByaXZhdGUga2V5IG9wZXJhdGlvbgogICAgdmFyIGJ0ID0gZmFsc2U7CgogICAgaWYodHlwZW9mIHNjaGVtZSA9PT0gJ3N0cmluZycpIHsKICAgICAgc2NoZW1lID0gc2NoZW1lLnRvVXBwZXJDYXNlKCk7CiAgICB9CgogICAgaWYoc2NoZW1lID09PSB1bmRlZmluZWQgfHwgc2NoZW1lID09PSAnUlNBU1NBLVBLQ1MxLVYxXzUnKSB7CiAgICAgIHNjaGVtZSA9IHsgZW5jb2RlOiBlbXNhUGtjczF2MTVlbmNvZGUgfTsKICAgICAgYnQgPSAweDAxOwogICAgfSBlbHNlIGlmKHNjaGVtZSA9PT0gJ05PTkUnIHx8IHNjaGVtZSA9PT0gJ05VTEwnIHx8IHNjaGVtZSA9PT0gbnVsbCkgewogICAgICBzY2hlbWUgPSB7IGVuY29kZTogZnVuY3Rpb24oKSB7IHJldHVybiBtZDsgfSB9OwogICAgICBidCA9IDB4MDE7CiAgICB9CgogICAgLy8gZW5jb2RlIGFuZCB0aGVuIGVuY3J5cHQKICAgIHZhciBkID0gc2NoZW1lLmVuY29kZShtZCwga2V5Lm4uYml0TGVuZ3RoKCkpOwogICAgcmV0dXJuIHBraS5yc2EuZW5jcnlwdChkLCBrZXksIGJ0KTsKICB9OwoKICByZXR1cm4ga2V5Owp9OwoKLyoqCiAqIFdyYXBzIGFuIFJTQVByaXZhdGVLZXkgQVNOLjEgb2JqZWN0IGluIGFuIEFTTi4xIFByaXZhdGVLZXlJbmZvIG9iamVjdC4KICoKICogQHBhcmFtIHJzYUtleSB0aGUgQVNOLjEgUlNBUHJpdmF0ZUtleS4KICoKICogQHJldHVybiB0aGUgQVNOLjEgUHJpdmF0ZUtleUluZm8uCiAqLwpwa2kud3JhcFJzYVByaXZhdGVLZXkgPSBmdW5jdGlvbihyc2FLZXkpIHsKICAvLyBQcml2YXRlS2V5SW5mbwogIHJldHVybiBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyB2ZXJzaW9uICgwKQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIoMCkuZ2V0Qnl0ZXMoKSksCiAgICAvLyBwcml2YXRlS2V5QWxnb3JpdGhtCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIGFzbjEuY3JlYXRlKAogICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICBhc24xLm9pZFRvRGVyKHBraS5vaWRzLnJzYUVuY3J5cHRpb24pLmdldEJ5dGVzKCkpLAogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgIF0pLAogICAgLy8gUHJpdmF0ZUtleQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsCiAgICAgIGFzbjEudG9EZXIocnNhS2V5KS5nZXRCeXRlcygpKQogICAgXSk7Cn07CgovKioKICogQ29udmVydHMgYSBwcml2YXRlIGtleSBmcm9tIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiB0aGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgYSBQcml2YXRlS2V5SW5mbyBjb250YWluaW5nIGFuCiAqICAgICAgICAgIFJTQVByaXZhdGVLZXkgb3IgYW4gUlNBUHJpdmF0ZUtleS4KICoKICogQHJldHVybiB0aGUgcHJpdmF0ZSBrZXkuCiAqLwpwa2kucHJpdmF0ZUtleUZyb21Bc24xID0gZnVuY3Rpb24ob2JqKSB7CiAgLy8gZ2V0IFByaXZhdGVLZXlJbmZvCiAgdmFyIGNhcHR1cmUgPSB7fTsKICB2YXIgZXJyb3JzID0gW107CiAgaWYoYXNuMS52YWxpZGF0ZShvYmosIHByaXZhdGVLZXlWYWxpZGF0b3IsIGNhcHR1cmUsIGVycm9ycykpIHsKICAgIG9iaiA9IGFzbjEuZnJvbURlcihmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLnByaXZhdGVLZXkpKTsKICB9CgogIC8vIGdldCBSU0FQcml2YXRlS2V5CiAgY2FwdHVyZSA9IHt9OwogIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgcnNhUHJpdmF0ZUtleVZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBwcml2YXRlIGtleS4gJyArCiAgICAgICdBU04uMSBvYmplY3QgZG9lcyBub3QgY29udGFpbiBhbiBSU0FQcml2YXRlS2V5LicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3JzOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICAvLyBOb3RlOiBWZXJzaW9uIGlzIGN1cnJlbnRseSBpZ25vcmVkLgogIC8vIGNhcHR1cmUucHJpdmF0ZUtleVZlcnNpb24KICAvLyBGSVhNRTogaW5lZmZpY2llbnQsIGdldCBhIEJpZ0ludGVnZXIgdGhhdCB1c2VzIGJ5dGUgc3RyaW5ncwogIHZhciBuLCBlLCBkLCBwLCBxLCBkUCwgZFEsIHFJbnY7CiAgbiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHJpdmF0ZUtleU1vZHVsdXMpLnRvSGV4KCk7CiAgZSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHJpdmF0ZUtleVB1YmxpY0V4cG9uZW50KS50b0hleCgpOwogIGQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLnByaXZhdGVLZXlQcml2YXRlRXhwb25lbnQpLnRvSGV4KCk7CiAgcCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHJpdmF0ZUtleVByaW1lMSkudG9IZXgoKTsKICBxID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5wcml2YXRlS2V5UHJpbWUyKS50b0hleCgpOwogIGRQID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5wcml2YXRlS2V5RXhwb25lbnQxKS50b0hleCgpOwogIGRRID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5wcml2YXRlS2V5RXhwb25lbnQyKS50b0hleCgpOwogIHFJbnYgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLnByaXZhdGVLZXlDb2VmZmljaWVudCkudG9IZXgoKTsKCiAgLy8gc2V0IHByaXZhdGUga2V5CiAgcmV0dXJuIHBraS5zZXRSc2FQcml2YXRlS2V5KAogICAgbmV3IEJpZ0ludGVnZXIobiwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIoZSwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIoZCwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIocCwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIocSwgMTYpLAogICAgbmV3IEJpZ0ludGVnZXIoZFAsIDE2KSwKICAgIG5ldyBCaWdJbnRlZ2VyKGRRLCAxNiksCiAgICBuZXcgQmlnSW50ZWdlcihxSW52LCAxNikpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgcHJpdmF0ZSBrZXkgdG8gYW4gQVNOLjEgUlNBUHJpdmF0ZUtleS4KICoKICogQHBhcmFtIGtleSB0aGUgcHJpdmF0ZSBrZXkuCiAqCiAqIEByZXR1cm4gdGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIGFuIFJTQVByaXZhdGVLZXkuCiAqLwpwa2kucHJpdmF0ZUtleVRvQXNuMSA9IHBraS5wcml2YXRlS2V5VG9SU0FQcml2YXRlS2V5ID0gZnVuY3Rpb24oa2V5KSB7CiAgLy8gUlNBUHJpdmF0ZUtleQogIHJldHVybiBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyB2ZXJzaW9uICgwID0gb25seSAyIHByaW1lcywgMSBtdWx0aXBsZSBwcmltZXMpCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBhc24xLmludGVnZXJUb0RlcigwKS5nZXRCeXRlcygpKSwKICAgIC8vIG1vZHVsdXMgKG4pCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5uKSksCiAgICAvLyBwdWJsaWNFeHBvbmVudCAoZSkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIF9iblRvQnl0ZXMoa2V5LmUpKSwKICAgIC8vIHByaXZhdGVFeHBvbmVudCAoZCkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIF9iblRvQnl0ZXMoa2V5LmQpKSwKICAgIC8vIHByaXZhdGVLZXlQcmltZTEgKHApCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5wKSksCiAgICAvLyBwcml2YXRlS2V5UHJpbWUyIChxKQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgX2JuVG9CeXRlcyhrZXkucSkpLAogICAgLy8gcHJpdmF0ZUtleUV4cG9uZW50MSAoZFApCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5kUCkpLAogICAgLy8gcHJpdmF0ZUtleUV4cG9uZW50MiAoZFEpCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5kUSkpLAogICAgLy8gY29lZmZpY2llbnQgKHFJbnYpCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5xSW52KSkKICBdKTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIHB1YmxpYyBrZXkgZnJvbSBhbiBBU04uMSBTdWJqZWN0UHVibGljS2V5SW5mbyBvciBSU0FQdWJsaWNLZXkuCiAqCiAqIEBwYXJhbSBvYmogdGhlIGFzbjEgcmVwcmVzZW50YXRpb24gb2YgYSBTdWJqZWN0UHVibGljS2V5SW5mbyBvciBSU0FQdWJsaWNLZXkuCiAqCiAqIEByZXR1cm4gdGhlIHB1YmxpYyBrZXkuCiAqLwpwa2kucHVibGljS2V5RnJvbUFzbjEgPSBmdW5jdGlvbihvYmopIHsKICAvLyBnZXQgU3ViamVjdFB1YmxpY0tleUluZm8KICB2YXIgY2FwdHVyZSA9IHt9OwogIHZhciBlcnJvcnMgPSBbXTsKICBpZihhc24xLnZhbGlkYXRlKG9iaiwgcHVibGljS2V5VmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICAvLyBnZXQgb2lkCiAgICB2YXIgb2lkID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLnB1YmxpY0tleU9pZCk7CiAgICBpZihvaWQgIT09IHBraS5vaWRzLnJzYUVuY3J5cHRpb24pIHsKICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBwdWJsaWMga2V5LiBVbmtub3duIE9JRC4nKTsKICAgICAgZXJyb3Iub2lkID0gb2lkOwogICAgICB0aHJvdyBlcnJvcjsKICAgIH0KICAgIG9iaiA9IGNhcHR1cmUucnNhUHVibGljS2V5OwogIH0KCiAgLy8gZ2V0IFJTQSBwYXJhbXMKICBlcnJvcnMgPSBbXTsKICBpZighYXNuMS52YWxpZGF0ZShvYmosIHJzYVB1YmxpY0tleVZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBwdWJsaWMga2V5LiAnICsKICAgICAgJ0FTTi4xIG9iamVjdCBkb2VzIG5vdCBjb250YWluIGFuIFJTQVB1YmxpY0tleS4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gRklYTUU6IGluZWZmaWNpZW50LCBnZXQgYSBCaWdJbnRlZ2VyIHRoYXQgdXNlcyBieXRlIHN0cmluZ3MKICB2YXIgbiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHVibGljS2V5TW9kdWx1cykudG9IZXgoKTsKICB2YXIgZSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUucHVibGljS2V5RXhwb25lbnQpLnRvSGV4KCk7CgogIC8vIHNldCBwdWJsaWMga2V5CiAgcmV0dXJuIHBraS5zZXRSc2FQdWJsaWNLZXkoCiAgICBuZXcgQmlnSW50ZWdlcihuLCAxNiksCiAgICBuZXcgQmlnSW50ZWdlcihlLCAxNikpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgcHVibGljIGtleSB0byBhbiBBU04uMSBTdWJqZWN0UHVibGljS2V5SW5mby4KICoKICogQHBhcmFtIGtleSB0aGUgcHVibGljIGtleS4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIFN1YmplY3RQdWJsaWNLZXlJbmZvLgogKi8KcGtpLnB1YmxpY0tleVRvQXNuMSA9IHBraS5wdWJsaWNLZXlUb1N1YmplY3RQdWJsaWNLZXlJbmZvID0gZnVuY3Rpb24oa2V5KSB7CiAgLy8gU3ViamVjdFB1YmxpY0tleUluZm8KICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gQWxnb3JpdGhtSWRlbnRpZmllcgogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAvLyBhbGdvcml0aG0KICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgIGFzbjEub2lkVG9EZXIocGtpLm9pZHMucnNhRW5jcnlwdGlvbikuZ2V0Qnl0ZXMoKSksCiAgICAgIC8vIHBhcmFtZXRlcnMgKG51bGwpCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuTlVMTCwgZmFsc2UsICcnKQogICAgXSksCiAgICAvLyBzdWJqZWN0UHVibGljS2V5CiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLkJJVFNUUklORywgZmFsc2UsIFsKICAgICAgcGtpLnB1YmxpY0tleVRvUlNBUHVibGljS2V5KGtleSkKICAgIF0pCiAgXSk7Cn07CgovKioKICogQ29udmVydHMgYSBwdWJsaWMga2V5IHRvIGFuIEFTTi4xIFJTQVB1YmxpY0tleS4KICoKICogQHBhcmFtIGtleSB0aGUgcHVibGljIGtleS4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIFJTQVB1YmxpY0tleS4KICovCnBraS5wdWJsaWNLZXlUb1JTQVB1YmxpY0tleSA9IGZ1bmN0aW9uKGtleSkgewogIC8vIFJTQVB1YmxpY0tleQogIHJldHVybiBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyBtb2R1bHVzIChuKQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgX2JuVG9CeXRlcyhrZXkubikpLAogICAgLy8gcHVibGljRXhwb25lbnQgKGUpCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBfYm5Ub0J5dGVzKGtleS5lKSkKICBdKTsKfTsKCi8qKgogKiBFbmNvZGVzIGEgbWVzc2FnZSB1c2luZyBQS0NTIzEgdjEuNSBwYWRkaW5nLgogKgogKiBAcGFyYW0gbSB0aGUgbWVzc2FnZSB0byBlbmNvZGUuCiAqIEBwYXJhbSBrZXkgdGhlIFJTQSBrZXkgdG8gdXNlLgogKiBAcGFyYW0gYnQgdGhlIGJsb2NrIHR5cGUgdG8gdXNlLCBpLmUuIGVpdGhlciAweDAxIChmb3Igc2lnbmluZykgb3IgMHgwMgogKiAgICAgICAgICAoZm9yIGVuY3J5cHRpb24pLgogKgogKiBAcmV0dXJuIHRoZSBwYWRkZWQgYnl0ZSBidWZmZXIuCiAqLwpmdW5jdGlvbiBfZW5jb2RlUGtjczFfdjFfNShtLCBrZXksIGJ0KSB7CiAgdmFyIGViID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKCiAgLy8gZ2V0IHRoZSBsZW5ndGggb2YgdGhlIG1vZHVsdXMgaW4gYnl0ZXMKICB2YXIgayA9IE1hdGguY2VpbChrZXkubi5iaXRMZW5ndGgoKSAvIDgpOwoKICAvKiB1c2UgUEtDUyMxIHYxLjUgcGFkZGluZyAqLwogIGlmKG0ubGVuZ3RoID4gKGsgLSAxMSkpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignTWVzc2FnZSBpcyB0b28gbG9uZyBmb3IgUEtDUyMxIHYxLjUgcGFkZGluZy4nKTsKICAgIGVycm9yLmxlbmd0aCA9IG0ubGVuZ3RoOwogICAgZXJyb3IubWF4ID0gayAtIDExOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICAvKiBBIGJsb2NrIHR5cGUgQlQsIGEgcGFkZGluZyBzdHJpbmcgUFMsIGFuZCB0aGUgZGF0YSBEIHNoYWxsIGJlCiAgICBmb3JtYXR0ZWQgaW50byBhbiBvY3RldCBzdHJpbmcgRUIsIHRoZSBlbmNyeXB0aW9uIGJsb2NrOgoKICAgIEVCID0gMDAgfHwgQlQgfHwgUFMgfHwgMDAgfHwgRAoKICAgIFRoZSBibG9jayB0eXBlIEJUIHNoYWxsIGJlIGEgc2luZ2xlIG9jdGV0IGluZGljYXRpbmcgdGhlIHN0cnVjdHVyZSBvZgogICAgdGhlIGVuY3J5cHRpb24gYmxvY2suIEZvciB0aGlzIHZlcnNpb24gb2YgdGhlIGRvY3VtZW50IGl0IHNoYWxsIGhhdmUKICAgIHZhbHVlIDAwLCAwMSwgb3IgMDIuIEZvciBhIHByaXZhdGUta2V5IG9wZXJhdGlvbiwgdGhlIGJsb2NrIHR5cGUKICAgIHNoYWxsIGJlIDAwIG9yIDAxLiBGb3IgYSBwdWJsaWMta2V5IG9wZXJhdGlvbiwgaXQgc2hhbGwgYmUgMDIuCgogICAgVGhlIHBhZGRpbmcgc3RyaW5nIFBTIHNoYWxsIGNvbnNpc3Qgb2Ygay0zLXx8RHx8IG9jdGV0cy4gRm9yIGJsb2NrCiAgICB0eXBlIDAwLCB0aGUgb2N0ZXRzIHNoYWxsIGhhdmUgdmFsdWUgMDA7IGZvciBibG9jayB0eXBlIDAxLCB0aGV5CiAgICBzaGFsbCBoYXZlIHZhbHVlIEZGOyBhbmQgZm9yIGJsb2NrIHR5cGUgMDIsIHRoZXkgc2hhbGwgYmUKICAgIHBzZXVkb3JhbmRvbWx5IGdlbmVyYXRlZCBhbmQgbm9uemVyby4gVGhpcyBtYWtlcyB0aGUgbGVuZ3RoIG9mIHRoZQogICAgZW5jcnlwdGlvbiBibG9jayBFQiBlcXVhbCB0byBrLiAqLwoKICAvLyBidWlsZCB0aGUgZW5jcnlwdGlvbiBibG9jawogIGViLnB1dEJ5dGUoMHgwMCk7CiAgZWIucHV0Qnl0ZShidCk7CgogIC8vIGNyZWF0ZSB0aGUgcGFkZGluZwogIHZhciBwYWROdW0gPSBrIC0gMyAtIG0ubGVuZ3RoOwogIHZhciBwYWRCeXRlOwogIC8vIHByaXZhdGUga2V5IG9wCiAgaWYoYnQgPT09IDB4MDAgfHwgYnQgPT09IDB4MDEpIHsKICAgIHBhZEJ5dGUgPSAoYnQgPT09IDB4MDApID8gMHgwMCA6IDB4RkY7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgcGFkTnVtOyArK2kpIHsKICAgICAgZWIucHV0Qnl0ZShwYWRCeXRlKTsKICAgIH0KICB9IGVsc2UgewogICAgLy8gcHVibGljIGtleSBvcAogICAgLy8gcGFkIHdpdGggcmFuZG9tIG5vbi16ZXJvIHZhbHVlcwogICAgd2hpbGUocGFkTnVtID4gMCkgewogICAgICB2YXIgbnVtWmVyb3MgPSAwOwogICAgICB2YXIgcGFkQnl0ZXMgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMocGFkTnVtKTsKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IHBhZE51bTsgKytpKSB7CiAgICAgICAgcGFkQnl0ZSA9IHBhZEJ5dGVzLmNoYXJDb2RlQXQoaSk7CiAgICAgICAgaWYocGFkQnl0ZSA9PT0gMCkgewogICAgICAgICAgKytudW1aZXJvczsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZWIucHV0Qnl0ZShwYWRCeXRlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcGFkTnVtID0gbnVtWmVyb3M7CiAgICB9CiAgfQoKICAvLyB6ZXJvIGZvbGxvd2VkIGJ5IG1lc3NhZ2UKICBlYi5wdXRCeXRlKDB4MDApOwogIGViLnB1dEJ5dGVzKG0pOwoKICByZXR1cm4gZWI7Cn0KCi8qKgogKiBEZWNvZGVzIGEgbWVzc2FnZSB1c2luZyBQS0NTIzEgdjEuNSBwYWRkaW5nLgogKgogKiBAcGFyYW0gZW0gdGhlIG1lc3NhZ2UgdG8gZGVjb2RlLgogKiBAcGFyYW0ga2V5IHRoZSBSU0Ega2V5IHRvIHVzZS4KICogQHBhcmFtIHB1YiB0cnVlIGlmIHRoZSBrZXkgaXMgYSBwdWJsaWMga2V5LCBmYWxzZSBpZiBpdCBpcyBwcml2YXRlLgogKiBAcGFyYW0gbWwgdGhlIG1lc3NhZ2UgbGVuZ3RoLCBpZiBzcGVjaWZpZWQuCiAqCiAqIEByZXR1cm4gdGhlIGRlY29kZWQgYnl0ZXMuCiAqLwpmdW5jdGlvbiBfZGVjb2RlUGtjczFfdjFfNShlbSwga2V5LCBwdWIsIG1sKSB7CiAgLy8gZ2V0IHRoZSBsZW5ndGggb2YgdGhlIG1vZHVsdXMgaW4gYnl0ZXMKICB2YXIgayA9IE1hdGguY2VpbChrZXkubi5iaXRMZW5ndGgoKSAvIDgpOwoKICAvKiBJdCBpcyBhbiBlcnJvciBpZiBhbnkgb2YgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIG9jY3VyczoKCiAgICAxLiBUaGUgZW5jcnlwdGlvbiBibG9jayBFQiBjYW5ub3QgYmUgcGFyc2VkIHVuYW1iaWd1b3VzbHkuCiAgICAyLiBUaGUgcGFkZGluZyBzdHJpbmcgUFMgY29uc2lzdHMgb2YgZmV3ZXIgdGhhbiBlaWdodCBvY3RldHMKICAgICAgb3IgaXMgaW5jb25zaXNlbnQgd2l0aCB0aGUgYmxvY2sgdHlwZSBCVC4KICAgIDMuIFRoZSBkZWNyeXB0aW9uIHByb2Nlc3MgaXMgYSBwdWJsaWMta2V5IG9wZXJhdGlvbiBhbmQgdGhlIGJsb2NrCiAgICAgIHR5cGUgQlQgaXMgbm90IDAwIG9yIDAxLCBvciB0aGUgZGVjcnlwdGlvbiBwcm9jZXNzIGlzIGEKICAgICAgcHJpdmF0ZS1rZXkgb3BlcmF0aW9uIGFuZCB0aGUgYmxvY2sgdHlwZSBpcyBub3QgMDIuCiAgICovCgogIC8vIHBhcnNlIHRoZSBlbmNyeXB0aW9uIGJsb2NrCiAgdmFyIGViID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoZW0pOwogIHZhciBmaXJzdCA9IGViLmdldEJ5dGUoKTsKICB2YXIgYnQgPSBlYi5nZXRCeXRlKCk7CiAgaWYoZmlyc3QgIT09IDB4MDAgfHwKICAgIChwdWIgJiYgYnQgIT09IDB4MDAgJiYgYnQgIT09IDB4MDEpIHx8CiAgICAoIXB1YiAmJiBidCAhPSAweDAyKSB8fAogICAgKHB1YiAmJiBidCA9PT0gMHgwMCAmJiB0eXBlb2YobWwpID09PSAndW5kZWZpbmVkJykpIHsKICAgIHRocm93IG5ldyBFcnJvcignRW5jcnlwdGlvbiBibG9jayBpcyBpbnZhbGlkLicpOwogIH0KCiAgdmFyIHBhZE51bSA9IDA7CiAgaWYoYnQgPT09IDB4MDApIHsKICAgIC8vIGNoZWNrIGFsbCBwYWRkaW5nIGJ5dGVzIGZvciAweDAwCiAgICBwYWROdW0gPSBrIC0gMyAtIG1sOwogICAgZm9yKHZhciBpID0gMDsgaSA8IHBhZE51bTsgKytpKSB7CiAgICAgIGlmKGViLmdldEJ5dGUoKSAhPT0gMHgwMCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcignRW5jcnlwdGlvbiBibG9jayBpcyBpbnZhbGlkLicpOwogICAgICB9CiAgICB9CiAgfSBlbHNlIGlmKGJ0ID09PSAweDAxKSB7CiAgICAvLyBmaW5kIHRoZSBmaXJzdCBieXRlIHRoYXQgaXNuJ3QgMHhGRiwgc2hvdWxkIGJlIGFmdGVyIGFsbCBwYWRkaW5nCiAgICBwYWROdW0gPSAwOwogICAgd2hpbGUoZWIubGVuZ3RoKCkgPiAxKSB7CiAgICAgIGlmKGViLmdldEJ5dGUoKSAhPT0gMHhGRikgewogICAgICAgIC0tZWIucmVhZDsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICArK3BhZE51bTsKICAgIH0KICB9IGVsc2UgaWYoYnQgPT09IDB4MDIpIHsKICAgIC8vIGxvb2sgZm9yIDB4MDAgYnl0ZQogICAgcGFkTnVtID0gMDsKICAgIHdoaWxlKGViLmxlbmd0aCgpID4gMSkgewogICAgICBpZihlYi5nZXRCeXRlKCkgPT09IDB4MDApIHsKICAgICAgICAtLWViLnJlYWQ7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgKytwYWROdW07CiAgICB9CiAgfQoKICAvLyB6ZXJvIG11c3QgYmUgMHgwMCBhbmQgcGFkTnVtIG11c3QgYmUgKGsgLSAzIC0gbWVzc2FnZSBsZW5ndGgpCiAgdmFyIHplcm8gPSBlYi5nZXRCeXRlKCk7CiAgaWYoemVybyAhPT0gMHgwMCB8fCBwYWROdW0gIT09IChrIC0gMyAtIGViLmxlbmd0aCgpKSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdFbmNyeXB0aW9uIGJsb2NrIGlzIGludmFsaWQuJyk7CiAgfQoKICByZXR1cm4gZWIuZ2V0Qnl0ZXMoKTsKfQoKLyoqCiAqIFJ1bnMgdGhlIGtleS1nZW5lcmF0aW9uIGFsZ29yaXRobSBhc3luY2hyb25vdXNseSwgZWl0aGVyIGluIHRoZSBiYWNrZ3JvdW5kCiAqIHZpYSBXZWIgV29ya2Vycywgb3IgdXNpbmcgdGhlIG1haW4gdGhyZWFkIGFuZCBzZXRJbW1lZGlhdGUuCiAqCiAqIEBwYXJhbSBzdGF0ZSB0aGUga2V5LXBhaXIgZ2VuZXJhdGlvbiBzdGF0ZS4KICogQHBhcmFtIFtvcHRpb25zXSBvcHRpb25zIGZvciBrZXktcGFpciBnZW5lcmF0aW9uOgogKiAgICAgICAgICB3b3JrZXJTY3JpcHQgdGhlIHdvcmtlciBzY3JpcHQgVVJMLgogKiAgICAgICAgICB3b3JrZXJzIHRoZSBudW1iZXIgb2Ygd2ViIHdvcmtlcnMgKGlmIHN1cHBvcnRlZCkgdG8gdXNlLAogKiAgICAgICAgICAgIChkZWZhdWx0OiAyLCAtMSB0byB1c2UgZXN0aW1hdGVkIGNvcmVzIG1pbnVzIG9uZSkuCiAqICAgICAgICAgIHdvcmtMb2FkIHRoZSBzaXplIG9mIHRoZSB3b3JrIGxvYWQsIGllOiBudW1iZXIgb2YgcG9zc2libGUgcHJpbWUKICogICAgICAgICAgICBudW1iZXJzIGZvciBlYWNoIHdlYiB3b3JrZXIgdG8gY2hlY2sgcGVyIHdvcmsgYXNzaWdubWVudCwKICogICAgICAgICAgICAoZGVmYXVsdDogMTAwKS4KICogQHBhcmFtIGNhbGxiYWNrKGVyciwga2V5cGFpcikgY2FsbGVkIG9uY2UgdGhlIG9wZXJhdGlvbiBjb21wbGV0ZXMuCiAqLwpmdW5jdGlvbiBfZ2VuZXJhdGVLZXlQYWlyKHN0YXRlLCBvcHRpb25zLCBjYWxsYmFjaykgewogIGlmKHR5cGVvZiBvcHRpb25zID09PSAnZnVuY3Rpb24nKSB7CiAgICBjYWxsYmFjayA9IG9wdGlvbnM7CiAgICBvcHRpb25zID0ge307CiAgfQogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwoKICB2YXIgb3B0cyA9IHsKICAgIGFsZ29yaXRobTogewogICAgICBuYW1lOiBvcHRpb25zLmFsZ29yaXRobSB8fCAnUFJJTUVJTkMnLAogICAgICBvcHRpb25zOiB7CiAgICAgICAgd29ya2Vyczogb3B0aW9ucy53b3JrZXJzIHx8IDIsCiAgICAgICAgd29ya0xvYWQ6IG9wdGlvbnMud29ya0xvYWQgfHwgMTAwLAogICAgICAgIHdvcmtlclNjcmlwdDogb3B0aW9ucy53b3JrZXJTY3JpcHQKICAgICAgfQogICAgfQogIH07CiAgaWYoJ3BybmcnIGluIG9wdGlvbnMpIHsKICAgIG9wdHMucHJuZyA9IG9wdGlvbnMucHJuZzsKICB9CgogIGdlbmVyYXRlKCk7CgogIGZ1bmN0aW9uIGdlbmVyYXRlKCkgewogICAgLy8gZmluZCBwIGFuZCB0aGVuIHEgKGRvbmUgaW4gc2VyaWVzIHRvIHNpbXBsaWZ5KQogICAgZ2V0UHJpbWUoc3RhdGUucEJpdHMsIGZ1bmN0aW9uKGVyciwgbnVtKSB7CiAgICAgIGlmKGVycikgewogICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpOwogICAgICB9CiAgICAgIHN0YXRlLnAgPSBudW07CiAgICAgIGlmKHN0YXRlLnEgIT09IG51bGwpIHsKICAgICAgICByZXR1cm4gZmluaXNoKGVyciwgc3RhdGUucSk7CiAgICAgIH0KICAgICAgZ2V0UHJpbWUoc3RhdGUucUJpdHMsIGZpbmlzaCk7CiAgICB9KTsKICB9CgogIGZ1bmN0aW9uIGdldFByaW1lKGJpdHMsIGNhbGxiYWNrKSB7CiAgICBmb3JnZS5wcmltZS5nZW5lcmF0ZVByb2JhYmxlUHJpbWUoYml0cywgb3B0cywgY2FsbGJhY2spOwogIH0KCiAgZnVuY3Rpb24gZmluaXNoKGVyciwgbnVtKSB7CiAgICBpZihlcnIpIHsKICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7CiAgICB9CgogICAgLy8gc2V0IHEKICAgIHN0YXRlLnEgPSBudW07CgogICAgLy8gZW5zdXJlIHAgaXMgbGFyZ2VyIHRoYW4gcSAoc3dhcCB0aGVtIGlmIG5vdCkKICAgIGlmKHN0YXRlLnAuY29tcGFyZVRvKHN0YXRlLnEpIDwgMCkgewogICAgICB2YXIgdG1wID0gc3RhdGUucDsKICAgICAgc3RhdGUucCA9IHN0YXRlLnE7CiAgICAgIHN0YXRlLnEgPSB0bXA7CiAgICB9CgogICAgLy8gZW5zdXJlIHAgaXMgY29wcmltZSB3aXRoIGUKICAgIGlmKHN0YXRlLnAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpLmdjZChzdGF0ZS5lKQogICAgICAuY29tcGFyZVRvKEJpZ0ludGVnZXIuT05FKSAhPT0gMCkgewogICAgICBzdGF0ZS5wID0gbnVsbDsKICAgICAgZ2VuZXJhdGUoKTsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIGVuc3VyZSBxIGlzIGNvcHJpbWUgd2l0aCBlCiAgICBpZihzdGF0ZS5xLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKS5nY2Qoc3RhdGUuZSkKICAgICAgLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT09IDApIHsKICAgICAgc3RhdGUucSA9IG51bGw7CiAgICAgIGdldFByaW1lKHN0YXRlLnFCaXRzLCBmaW5pc2gpOwogICAgICByZXR1cm47CiAgICB9CgogICAgLy8gY29tcHV0ZSBwaGk6IChwIC0gMSkocSAtIDEpIChFdWxlcidzIHRvdGllbnQgZnVuY3Rpb24pCiAgICBzdGF0ZS5wMSA9IHN0YXRlLnAuc3VidHJhY3QoQmlnSW50ZWdlci5PTkUpOwogICAgc3RhdGUucTEgPSBzdGF0ZS5xLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTsKICAgIHN0YXRlLnBoaSA9IHN0YXRlLnAxLm11bHRpcGx5KHN0YXRlLnExKTsKCiAgICAvLyBlbnN1cmUgZSBhbmQgcGhpIGFyZSBjb3ByaW1lCiAgICBpZihzdGF0ZS5waGkuZ2NkKHN0YXRlLmUpLmNvbXBhcmVUbyhCaWdJbnRlZ2VyLk9ORSkgIT09IDApIHsKICAgICAgLy8gcGhpIGFuZCBlIGFyZW4ndCBjb3ByaW1lLCBzbyBnZW5lcmF0ZSBhIG5ldyBwIGFuZCBxCiAgICAgIHN0YXRlLnAgPSBzdGF0ZS5xID0gbnVsbDsKICAgICAgZ2VuZXJhdGUoKTsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIGNyZWF0ZSBuLCBlbnN1cmUgbiBpcyBoYXMgdGhlIHJpZ2h0IG51bWJlciBvZiBiaXRzCiAgICBzdGF0ZS5uID0gc3RhdGUucC5tdWx0aXBseShzdGF0ZS5xKTsKICAgIGlmKHN0YXRlLm4uYml0TGVuZ3RoKCkgIT09IHN0YXRlLmJpdHMpIHsKICAgICAgLy8gZmFpbGVkLCBnZXQgbmV3IHEKICAgICAgc3RhdGUucSA9IG51bGw7CiAgICAgIGdldFByaW1lKHN0YXRlLnFCaXRzLCBmaW5pc2gpOwogICAgICByZXR1cm47CiAgICB9CgogICAgLy8gc2V0IGtleXMKICAgIHZhciBkID0gc3RhdGUuZS5tb2RJbnZlcnNlKHN0YXRlLnBoaSk7CiAgICBzdGF0ZS5rZXlzID0gewogICAgICBwcml2YXRlS2V5OiBwa2kucnNhLnNldFByaXZhdGVLZXkoCiAgICAgICAgc3RhdGUubiwgc3RhdGUuZSwgZCwgc3RhdGUucCwgc3RhdGUucSwKICAgICAgICBkLm1vZChzdGF0ZS5wMSksIGQubW9kKHN0YXRlLnExKSwKICAgICAgICBzdGF0ZS5xLm1vZEludmVyc2Uoc3RhdGUucCkpLAogICAgICBwdWJsaWNLZXk6IHBraS5yc2Euc2V0UHVibGljS2V5KHN0YXRlLm4sIHN0YXRlLmUpCiAgICB9OwoKICAgIGNhbGxiYWNrKG51bGwsIHN0YXRlLmtleXMpOwogIH0KfQoKLyoqCiAqIENvbnZlcnRzIGEgcG9zaXRpdmUgQmlnSW50ZWdlciBpbnRvIDIncy1jb21wbGVtZW50IGJpZy1lbmRpYW4gYnl0ZXMuCiAqCiAqIEBwYXJhbSBiIHRoZSBiaWcgaW50ZWdlciB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBieXRlcy4KICovCmZ1bmN0aW9uIF9iblRvQnl0ZXMoYikgewogIC8vIHByZXBlbmQgMHgwMCBpZiBmaXJzdCBieXRlID49IDB4ODAKICB2YXIgaGV4ID0gYi50b1N0cmluZygxNik7CiAgaWYoaGV4WzBdID49ICc4JykgewogICAgaGV4ID0gJzAwJyArIGhleDsKICB9CiAgcmV0dXJuIGZvcmdlLnV0aWwuaGV4VG9CeXRlcyhoZXgpOwp9CgovKioKICogUmV0dXJucyB0aGUgcmVxdWlyZWQgbnVtYmVyIG9mIE1pbGxlci1SYWJpbiB0ZXN0cyB0byBnZW5lcmF0ZSBhCiAqIHByaW1lIHdpdGggYW4gZXJyb3IgcHJvYmFiaWxpdHkgb2YgKDEvMileODAuCiAqCiAqIFNlZSBIYW5kYm9vayBvZiBBcHBsaWVkIENyeXB0b2dyYXBoeSBDaGFwdGVyIDQsIFRhYmxlIDQuNC4KICoKICogQHBhcmFtIGJpdHMgdGhlIGJpdCBzaXplLgogKgogKiBAcmV0dXJuIHRoZSByZXF1aXJlZCBudW1iZXIgb2YgaXRlcmF0aW9ucy4KICovCmZ1bmN0aW9uIF9nZXRNaWxsZXJSYWJpblRlc3RzKGJpdHMpIHsKICBpZihiaXRzIDw9IDEwMCkgcmV0dXJuIDI3OwogIGlmKGJpdHMgPD0gMTUwKSByZXR1cm4gMTg7CiAgaWYoYml0cyA8PSAyMDApIHJldHVybiAxNTsKICBpZihiaXRzIDw9IDI1MCkgcmV0dXJuIDEyOwogIGlmKGJpdHMgPD0gMzAwKSByZXR1cm4gOTsKICBpZihiaXRzIDw9IDM1MCkgcmV0dXJuIDg7CiAgaWYoYml0cyA8PSA0MDApIHJldHVybiA3OwogIGlmKGJpdHMgPD0gNTAwKSByZXR1cm4gNjsKICBpZihiaXRzIDw9IDYwMCkgcmV0dXJuIDU7CiAgaWYoYml0cyA8PSA4MDApIHJldHVybiA0OwogIGlmKGJpdHMgPD0gMTI1MCkgcmV0dXJuIDM7CiAgcmV0dXJuIDI7Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3JzYSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9yc2EnLFsKICAncmVxdWlyZScsCiAgJ21vZHVsZScsCiAgJy4vYXNuMScsCiAgJy4vanNibicsCiAgJy4vb2lkcycsCiAgJy4vcGtjczEnLAogICcuL3ByaW1lJywKICAnLi9yYW5kb20nLAogICcuL3V0aWwnCl0sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFBhc3N3b3JkLWJhc2VkIGVuY3J5cHRpb24gZnVuY3Rpb25zLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKiBAYXV0aG9yIFN0ZWZhbiBTaWVnbCA8c3Rlc2llQGJyb2tlbnBpcGUuZGU+CiAqCiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEzIERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqIENvcHlyaWdodCAoYykgMjAxMiBTdGVmYW4gU2llZ2wgPHN0ZXNpZUBicm9rZW5waXBlLmRlPgogKgogKiBBbiBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbzoKICoKICogRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gOjo9IFNFUVVFTkNFIHsKICogICBlbmNyeXB0aW9uQWxnb3JpdGhtICBFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciwKICogICBlbmNyeXB0ZWREYXRhICAgICAgICBFbmNyeXB0ZWREYXRhIH0KICoKICogRW5jcnlwdGlvbkFsZ29yaXRobUlkZW50aWZpZXIgOjo9IEFsZ29yaXRobUlkZW50aWZpZXIKICoKICogRW5jcnlwdGVkRGF0YSA6Oj0gT0NURVQgU1RSSU5HCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKaWYodHlwZW9mIEJpZ0ludGVnZXIgPT09ICd1bmRlZmluZWQnKSB7CiAgdmFyIEJpZ0ludGVnZXIgPSBmb3JnZS5qc2JuLkJpZ0ludGVnZXI7Cn0KCi8vIHNob3J0Y3V0IGZvciBhc24uMSBBUEkKdmFyIGFzbjEgPSBmb3JnZS5hc24xOwoKLyogUGFzc3dvcmQtYmFzZWQgZW5jcnlwdGlvbiBpbXBsZW1lbnRhdGlvbi4gKi8KdmFyIHBraSA9IGZvcmdlLnBraSA9IGZvcmdlLnBraSB8fCB7fTsKcGtpLnBiZSA9IGZvcmdlLnBiZSA9IGZvcmdlLnBiZSB8fCB7fTsKdmFyIG9pZHMgPSBwa2kub2lkczsKCi8vIHZhbGlkYXRvciBmb3IgYW4gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gc3RydWN0dXJlCi8vIE5vdGU6IEN1cnJlbnRseSBvbmx5IHdvcmtzIHcvYWxnb3JpdGhtIHBhcmFtcwp2YXIgZW5jcnlwdGVkUHJpdmF0ZUtleVZhbGlkYXRvciA9IHsKICBuYW1lOiAnRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8nLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uZW5jcnlwdGlvbkFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnQWxnb3JpdGhtSWRlbnRpZmllci5hbGdvcml0aG0nLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2VuY3J5cHRpb25PaWQnCiAgICB9LCB7CiAgICAgIG5hbWU6ICdBbGdvcml0aG1JZGVudGlmaWVyLnBhcmFtZXRlcnMnLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIGNhcHR1cmVBc24xOiAnZW5jcnlwdGlvblBhcmFtcycKICAgIH1dCiAgfSwgewogICAgLy8gZW5jcnlwdGVkRGF0YQogICAgbmFtZTogJ0VuY3J5cHRlZFByaXZhdGVLZXlJbmZvLmVuY3J5cHRlZERhdGEnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2VuY3J5cHRlZERhdGEnCiAgfV0KfTsKCi8vIHZhbGlkYXRvciBmb3IgYSBQQkVTMkFsZ29yaXRobXMgc3RydWN0dXJlCi8vIE5vdGU6IEN1cnJlbnRseSBvbmx5IHdvcmtzIHcvUEJLREYyICsgQUVTIGVuY3J5cHRpb24gc2NoZW1lcwp2YXIgUEJFUzJBbGdvcml0aG1zVmFsaWRhdG9yID0gewogIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnUEJFUzJBbGdvcml0aG1zLmtleURlcml2YXRpb25GdW5jJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMua2V5RGVyaXZhdGlvbkZ1bmMub2lkJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdrZGZPaWQnCiAgICB9LCB7CiAgICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMucGFyYW1zJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAnUEJFUzJBbGdvcml0aG1zLnBhcmFtcy5zYWx0JywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBjYXB0dXJlOiAna2RmU2FsdCcKICAgICAgfSwgewogICAgICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMucGFyYW1zLml0ZXJhdGlvbkNvdW50JywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgICAgb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgICBjYXB0dXJlOiAna2RmSXRlcmF0aW9uQ291bnQnCiAgICAgIH1dCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMuZW5jcnlwdGlvblNjaGVtZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnUEJFUzJBbGdvcml0aG1zLmVuY3J5cHRpb25TY2hlbWUub2lkJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdlbmNPaWQnCiAgICB9LCB7CiAgICAgIG5hbWU6ICdQQkVTMkFsZ29yaXRobXMuZW5jcnlwdGlvblNjaGVtZS5pdicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdlbmNJdicKICAgIH1dCiAgfV0KfTsKCnZhciBwa2NzMTJQYmVQYXJhbXNWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ3BrY3MtMTJQYmVQYXJhbXMnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAncGtjcy0xMlBiZVBhcmFtcy5zYWx0JywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5PQ1RFVFNUUklORywKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdzYWx0JwogIH0sIHsKICAgIG5hbWU6ICdwa2NzLTEyUGJlUGFyYW1zLml0ZXJhdGlvbnMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAnaXRlcmF0aW9ucycKICB9XQp9OwoKLyoqCiAqIEVuY3J5cHRzIGEgQVNOLjEgUHJpdmF0ZUtleUluZm8gb2JqZWN0LCBwcm9kdWNpbmcgYW4gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uCiAqCiAqIFBCRVMyQWxnb3JpdGhtcyBBTEdPUklUSE0tSURFTlRJRklFUiA6Oj0KICogICB7IHtQQkVTMi1wYXJhbXMgSURFTlRJRklFRCBCWSBpZC1QQkVTMn0sIC4uLn0KICoKICogaWQtUEJFUzIgT0JKRUNUIElERU5USUZJRVIgOjo9IHtwa2NzLTUgMTN9CiAqCiAqIFBCRVMyLXBhcmFtcyA6Oj0gU0VRVUVOQ0UgewogKiAgIGtleURlcml2YXRpb25GdW5jIEFsZ29yaXRobUlkZW50aWZpZXIge3tQQkVTMi1LREZzfX0sCiAqICAgZW5jcnlwdGlvblNjaGVtZSBBbGdvcml0aG1JZGVudGlmaWVyIHt7UEJFUzItRW5jc319CiAqIH0KICoKICogUEJFUzItS0RGcyBBTEdPUklUSE0tSURFTlRJRklFUiA6Oj0KICogICB7IHtQQktERjItcGFyYW1zIElERU5USUZJRUQgQlkgaWQtUEJLREYyfSwgLi4uIH0KICoKICogUEJFUzItRW5jcyBBTEdPUklUSE0tSURFTlRJRklFUiA6Oj0geyAuLi4gfQogKgogKiBQQktERjItcGFyYW1zIDo6PSBTRVFVRU5DRSB7CiAqICAgc2FsdCBDSE9JQ0UgewogKiAgICAgc3BlY2lmaWVkIE9DVEVUIFNUUklORywKICogICAgIG90aGVyU291cmNlIEFsZ29yaXRobUlkZW50aWZpZXIge3tQQktERjItU2FsdFNvdXJjZXN9fQogKiAgIH0sCiAqICAgaXRlcmF0aW9uQ291bnQgSU5URUdFUiAoMS4uTUFYKSwKICogICBrZXlMZW5ndGggSU5URUdFUiAoMS4uTUFYKSBPUFRJT05BTCwKICogICBwcmYgQWxnb3JpdGhtSWRlbnRpZmllciB7e1BCS0RGMi1QUkZzfX0gREVGQVVMVCBhbGdpZC1obWFjV2l0aFNIQTEKICogfQogKgogKiBAcGFyYW0gb2JqIHRoZSBBU04uMSBQcml2YXRlS2V5SW5mbyBvYmplY3QuCiAqIEBwYXJhbSBwYXNzd29yZCB0aGUgcGFzc3dvcmQgdG8gZW5jcnlwdCB3aXRoLgogKiBAcGFyYW0gb3B0aW9uczoKICogICAgICAgICAgYWxnb3JpdGhtIHRoZSBlbmNyeXB0aW9uIGFsZ29yaXRobSB0byB1c2UKICogICAgICAgICAgICAoJ2FlczEyOCcsICdhZXMxOTInLCAnYWVzMjU2JywgJzNkZXMnKSwgZGVmYXVsdHMgdG8gJ2FlczEyOCcuCiAqICAgICAgICAgIGNvdW50IHRoZSBpdGVyYXRpb24gY291bnQgdG8gdXNlLgogKiAgICAgICAgICBzYWx0U2l6ZSB0aGUgc2FsdCBzaXplIHRvIHVzZS4KICoKICogQHJldHVybiB0aGUgQVNOLjEgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uCiAqLwpwa2kuZW5jcnlwdFByaXZhdGVLZXlJbmZvID0gZnVuY3Rpb24ob2JqLCBwYXNzd29yZCwgb3B0aW9ucykgewogIC8vIHNldCBkZWZhdWx0IG9wdGlvbnMKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICBvcHRpb25zLnNhbHRTaXplID0gb3B0aW9ucy5zYWx0U2l6ZSB8fCA4OwogIG9wdGlvbnMuY291bnQgPSBvcHRpb25zLmNvdW50IHx8IDIwNDg7CiAgb3B0aW9ucy5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobSB8fCAnYWVzMTI4JzsKCiAgLy8gZ2VuZXJhdGUgUEJFIHBhcmFtcwogIHZhciBzYWx0ID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzU3luYyhvcHRpb25zLnNhbHRTaXplKTsKICB2YXIgY291bnQgPSBvcHRpb25zLmNvdW50OwogIHZhciBjb3VudEJ5dGVzID0gYXNuMS5pbnRlZ2VyVG9EZXIoY291bnQpOwogIHZhciBka0xlbjsKICB2YXIgZW5jcnlwdGlvbkFsZ29yaXRobTsKICB2YXIgZW5jcnlwdGVkRGF0YTsKICBpZihvcHRpb25zLmFsZ29yaXRobS5pbmRleE9mKCdhZXMnKSA9PT0gMCB8fCBvcHRpb25zLmFsZ29yaXRobSA9PT0gJ2RlcycpIHsKICAgIC8vIERvIFBCRVMyCiAgICB2YXIgaXZMZW4sIGVuY09pZCwgY2lwaGVyRm47CiAgICBzd2l0Y2gob3B0aW9ucy5hbGdvcml0aG0pIHsKICAgIGNhc2UgJ2FlczEyOCc6CiAgICAgIGRrTGVuID0gMTY7CiAgICAgIGl2TGVuID0gMTY7CiAgICAgIGVuY09pZCA9IG9pZHNbJ2FlczEyOC1DQkMnXTsKICAgICAgY2lwaGVyRm4gPSBmb3JnZS5hZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgICAgYnJlYWs7CiAgICBjYXNlICdhZXMxOTInOgogICAgICBka0xlbiA9IDI0OwogICAgICBpdkxlbiA9IDE2OwogICAgICBlbmNPaWQgPSBvaWRzWydhZXMxOTItQ0JDJ107CiAgICAgIGNpcGhlckZuID0gZm9yZ2UuYWVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnYWVzMjU2JzoKICAgICAgZGtMZW4gPSAzMjsKICAgICAgaXZMZW4gPSAxNjsKICAgICAgZW5jT2lkID0gb2lkc1snYWVzMjU2LUNCQyddOwogICAgICBjaXBoZXJGbiA9IGZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyOwogICAgICBicmVhazsKICAgIGNhc2UgJ2Rlcyc6CiAgICAgIGRrTGVuID0gODsKICAgICAgaXZMZW4gPSA4OwogICAgICBlbmNPaWQgPSBvaWRzWydkZXNDQkMnXTsKICAgICAgY2lwaGVyRm4gPSBmb3JnZS5kZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCBlbmNyeXB0IHByaXZhdGUga2V5LiBVbmtub3duIGVuY3J5cHRpb24gYWxnb3JpdGhtLicpOwogICAgICBlcnJvci5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobTsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLy8gZW5jcnlwdCBwcml2YXRlIGtleSB1c2luZyBwYmUgU0hBLTEgYW5kIEFFUy9ERVMKICAgIHZhciBkayA9IGZvcmdlLnBrY3M1LnBia2RmMihwYXNzd29yZCwgc2FsdCwgY291bnQsIGRrTGVuKTsKICAgIHZhciBpdiA9IGZvcmdlLnJhbmRvbS5nZXRCeXRlc1N5bmMoaXZMZW4pOwogICAgdmFyIGNpcGhlciA9IGNpcGhlckZuKGRrKTsKICAgIGNpcGhlci5zdGFydChpdik7CiAgICBjaXBoZXIudXBkYXRlKGFzbjEudG9EZXIob2JqKSk7CiAgICBjaXBoZXIuZmluaXNoKCk7CiAgICBlbmNyeXB0ZWREYXRhID0gY2lwaGVyLm91dHB1dC5nZXRCeXRlcygpOwoKICAgIGVuY3J5cHRpb25BbGdvcml0aG0gPSBhc24xLmNyZWF0ZSgKICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0RlcihvaWRzWydwa2NzNVBCRVMyJ10pLmdldEJ5dGVzKCkpLAogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8ga2V5RGVyaXZhdGlvbkZ1bmMKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgICAgIGFzbjEub2lkVG9EZXIob2lkc1sncGtjczVQQktERjInXSkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgICAvLyBQQktERjItcGFyYW1zCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICAgIC8vIHNhbHQKICAgICAgICAgICAgYXNuMS5jcmVhdGUoCiAgICAgICAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIHNhbHQpLAogICAgICAgICAgICAvLyBpdGVyYXRpb24gY291bnQKICAgICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgICAgICAgICBjb3VudEJ5dGVzLmdldEJ5dGVzKCkpCiAgICAgICAgICBdKQogICAgICAgIF0pLAogICAgICAgIC8vIGVuY3J5cHRpb25TY2hlbWUKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgICAgIGFzbjEub2lkVG9EZXIoZW5jT2lkKS5nZXRCeXRlcygpKSwKICAgICAgICAgIC8vIGl2CiAgICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIGl2KQogICAgICAgIF0pCiAgICAgIF0pCiAgICBdKTsKICB9IGVsc2UgaWYob3B0aW9ucy5hbGdvcml0aG0gPT09ICczZGVzJykgewogICAgLy8gRG8gUEtDUzEyIFBCRQogICAgZGtMZW4gPSAyNDsKCiAgICB2YXIgc2FsdEJ5dGVzID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcihzYWx0KTsKICAgIHZhciBkayA9IHBraS5wYmUuZ2VuZXJhdGVQa2NzMTJLZXkocGFzc3dvcmQsIHNhbHRCeXRlcywgMSwgY291bnQsIGRrTGVuKTsKICAgIHZhciBpdiA9IHBraS5wYmUuZ2VuZXJhdGVQa2NzMTJLZXkocGFzc3dvcmQsIHNhbHRCeXRlcywgMiwgY291bnQsIGRrTGVuKTsKICAgIHZhciBjaXBoZXIgPSBmb3JnZS5kZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcihkayk7CiAgICBjaXBoZXIuc3RhcnQoaXYpOwogICAgY2lwaGVyLnVwZGF0ZShhc24xLnRvRGVyKG9iaikpOwogICAgY2lwaGVyLmZpbmlzaCgpOwogICAgZW5jcnlwdGVkRGF0YSA9IGNpcGhlci5vdXRwdXQuZ2V0Qnl0ZXMoKTsKCiAgICBlbmNyeXB0aW9uQWxnb3JpdGhtID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgIGFzbjEub2lkVG9EZXIob2lkc1sncGJlV2l0aFNIQUFuZDMtS2V5VHJpcGxlREVTLUNCQyddKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGtjcy0xMlBiZVBhcmFtcwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8gc2FsdAogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLCBzYWx0KSwKICAgICAgICAvLyBpdGVyYXRpb24gY291bnQKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICAgICAgY291bnRCeXRlcy5nZXRCeXRlcygpKQogICAgICBdKQogICAgXSk7CiAgfSBlbHNlIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IGVuY3J5cHQgcHJpdmF0ZSBrZXkuIFVua25vd24gZW5jcnlwdGlvbiBhbGdvcml0aG0uJyk7CiAgICBlcnJvci5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobTsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8KICB2YXIgcnZhbCA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgIC8vIGVuY3J5cHRpb25BbGdvcml0aG0KICAgIGVuY3J5cHRpb25BbGdvcml0aG0sCiAgICAvLyBlbmNyeXB0ZWREYXRhCiAgICBhc24xLmNyZWF0ZSgKICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIGVuY3J5cHRlZERhdGEpCiAgXSk7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogRGVjcnlwdHMgYSBBU04uMSBQcml2YXRlS2V5SW5mbyBvYmplY3QuCiAqCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIG9iamVjdC4KICogQHBhcmFtIHBhc3N3b3JkIHRoZSBwYXNzd29yZCB0byBkZWNyeXB0IHdpdGguCiAqCiAqIEByZXR1cm4gdGhlIEFTTi4xIFByaXZhdGVLZXlJbmZvIG9uIHN1Y2Nlc3MsIG51bGwgb24gZmFpbHVyZS4KICovCnBraS5kZWNyeXB0UHJpdmF0ZUtleUluZm8gPSBmdW5jdGlvbihvYmosIHBhc3N3b3JkKSB7CiAgdmFyIHJ2YWwgPSBudWxsOwoKICAvLyBnZXQgUEJFIHBhcmFtcwogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgZW5jcnlwdGVkUHJpdmF0ZUtleVZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBlbmNyeXB0ZWQgcHJpdmF0ZSBrZXkuICcgKwogICAgICAnQVNOLjEgb2JqZWN0IGlzIG5vdCBhIHN1cHBvcnRlZCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mby4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gZ2V0IGNpcGhlcgogIHZhciBvaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUuZW5jcnlwdGlvbk9pZCk7CiAgdmFyIGNpcGhlciA9IHBraS5wYmUuZ2V0Q2lwaGVyKG9pZCwgY2FwdHVyZS5lbmNyeXB0aW9uUGFyYW1zLCBwYXNzd29yZCk7CgogIC8vIGdldCBlbmNyeXB0ZWQgZGF0YQogIHZhciBlbmNyeXB0ZWQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLmVuY3J5cHRlZERhdGEpOwoKICBjaXBoZXIudXBkYXRlKGVuY3J5cHRlZCk7CiAgaWYoY2lwaGVyLmZpbmlzaCgpKSB7CiAgICBydmFsID0gYXNuMS5mcm9tRGVyKGNpcGhlci5vdXRwdXQpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ29udmVydHMgYSBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbyB0byBQRU0gZm9ybWF0LgogKgogKiBAcGFyYW0gZXBraSB0aGUgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uCiAqIEBwYXJhbSBtYXhsaW5lIHRoZSBtYXhpbXVtIGNoYXJhY3RlcnMgcGVyIGxpbmUsIGRlZmF1bHRzIHRvIDY0LgogKgogKiBAcmV0dXJuIHRoZSBQRU0tZm9ybWF0dGVkIGVuY3J5cHRlZCBwcml2YXRlIGtleS4KICovCnBraS5lbmNyeXB0ZWRQcml2YXRlS2V5VG9QZW0gPSBmdW5jdGlvbihlcGtpLCBtYXhsaW5lKSB7CiAgLy8gY29udmVydCB0byBERVIsIHRoZW4gUEVNLWVuY29kZQogIHZhciBtc2cgPSB7CiAgICB0eXBlOiAnRU5DUllQVEVEIFBSSVZBVEUgS0VZJywKICAgIGJvZHk6IGFzbjEudG9EZXIoZXBraSkuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnLCB7bWF4bGluZTogbWF4bGluZX0pOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgUEVNLWVuY29kZWQgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gdG8gQVNOLjEgZm9ybWF0LiBEZWNyeXB0aW9uCiAqIGlzIG5vdCBwZXJmb3JtZWQuCiAqCiAqIEBwYXJhbSBwZW0gdGhlIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvIGluIFBFTS1mb3JtYXQuCiAqCiAqIEByZXR1cm4gdGhlIEFTTi4xIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvLgogKi8KcGtpLmVuY3J5cHRlZFByaXZhdGVLZXlGcm9tUGVtID0gZnVuY3Rpb24ocGVtKSB7CiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKCiAgaWYobXNnLnR5cGUgIT09ICdFTkNSWVBURUQgUFJJVkFURSBLRVknKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IGVuY3J5cHRlZCBwcml2YXRlIGtleSBmcm9tIFBFTTsgJyArCiAgICAgICdQRU0gaGVhZGVyIHR5cGUgaXMgIkVOQ1JZUFRFRCBQUklWQVRFIEtFWSIuJyk7CiAgICBlcnJvci5oZWFkZXJUeXBlID0gbXNnLnR5cGU7CiAgICB0aHJvdyBlcnJvcjsKICB9CiAgaWYobXNnLnByb2NUeXBlICYmIG1zZy5wcm9jVHlwZS50eXBlID09PSAnRU5DUllQVEVEJykgewogICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgY29udmVydCBlbmNyeXB0ZWQgcHJpdmF0ZSBrZXkgZnJvbSBQRU07ICcgKwogICAgICAnUEVNIGlzIGVuY3J5cHRlZC4nKTsKICB9CgogIC8vIGNvbnZlcnQgREVSIHRvIEFTTi4xIG9iamVjdAogIHJldHVybiBhc24xLmZyb21EZXIobXNnLmJvZHkpOwp9OwoKLyoqCiAqIEVuY3J5cHRzIGFuIFJTQSBwcml2YXRlIGtleS4gQnkgZGVmYXVsdCwgdGhlIGtleSB3aWxsIGJlIHdyYXBwZWQgaW4KICogYSBQcml2YXRlS2V5SW5mbyBhbmQgZW5jcnlwdGVkIHRvIHByb2R1Y2UgYSBQS0NTIzggRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8uCiAqIFRoaXMgaXMgdGhlIHN0YW5kYXJkLCBwcmVmZXJyZWQgd2F5IHRvIGVuY3J5cHQgYSBwcml2YXRlIGtleS4KICoKICogVG8gcHJvZHVjZSBhIG5vbi1zdGFuZGFyZCBQRU0tZW5jcnlwdGVkIHByaXZhdGUga2V5IHRoYXQgdXNlcyBlbmNhcHN1bGF0ZWQKICogaGVhZGVycyB0byBpbmRpY2F0ZSB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0gKG9sZC1zdHlsZSBub24tUEtDUyM4IE9wZW5TU0wKICogcHJpdmF0ZSBrZXkgZW5jcnlwdGlvbiksIHNldCB0aGUgJ2xlZ2FjeScgb3B0aW9uIHRvIHRydWUuIE5vdGU6IFVzaW5nIHRoaXMKICogb3B0aW9uIHdpbGwgY2F1c2UgdGhlIGl0ZXJhdGlvbiBjb3VudCB0byBiZSBmb3JjZWQgdG8gMS4KICoKICogTm90ZTogVGhlICdkZXMnIGFsZ29yaXRobSBpcyBzdXBwb3J0ZWQsIGJ1dCBpdCBpcyBub3QgY29uc2lkZXJlZCB0byBiZQogKiBzZWN1cmUgYmVjYXVzZSBpdCBvbmx5IHVzZXMgYSBzaW5nbGUgNTYtYml0IGtleS4gSWYgcG9zc2libGUsIGl0IGlzIGhpZ2hseQogKiByZWNvbW1lbmRlZCB0aGF0IGEgZGlmZmVyZW50IGFsZ29yaXRobSBiZSB1c2VkLgogKgogKiBAcGFyYW0gcnNhS2V5IHRoZSBSU0Ega2V5IHRvIGVuY3J5cHQuCiAqIEBwYXJhbSBwYXNzd29yZCB0aGUgcGFzc3dvcmQgdG8gdXNlLgogKiBAcGFyYW0gb3B0aW9uczoKICogICAgICAgICAgYWxnb3JpdGhtOiB0aGUgZW5jcnlwdGlvbiBhbGdvcml0aG0gdG8gdXNlCiAqICAgICAgICAgICAgKCdhZXMxMjgnLCAnYWVzMTkyJywgJ2FlczI1NicsICczZGVzJywgJ2RlcycpLgogKiAgICAgICAgICBjb3VudDogdGhlIGl0ZXJhdGlvbiBjb3VudCB0byB1c2UuCiAqICAgICAgICAgIHNhbHRTaXplOiB0aGUgc2FsdCBzaXplIHRvIHVzZS4KICogICAgICAgICAgbGVnYWN5OiBvdXRwdXQgYW4gb2xkIG5vbi1QS0NTIzggUEVNLWVuY3J5cHRlZCtlbmNhcHN1bGF0ZWQKICogICAgICAgICAgICBoZWFkZXJzIChERUstSW5mbykgcHJpdmF0ZSBrZXkuCiAqCiAqIEByZXR1cm4gdGhlIFBFTS1lbmNvZGVkIEFTTi4xIEVuY3J5cHRlZFByaXZhdGVLZXlJbmZvLgogKi8KcGtpLmVuY3J5cHRSc2FQcml2YXRlS2V5ID0gZnVuY3Rpb24ocnNhS2V5LCBwYXNzd29yZCwgb3B0aW9ucykgewogIC8vIHN0YW5kYXJkIFBLQ1MjOAogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIGlmKCFvcHRpb25zLmxlZ2FjeSkgewogICAgLy8gZW5jcnlwdCBQcml2YXRlS2V5SW5mbwogICAgdmFyIHJ2YWwgPSBwa2kud3JhcFJzYVByaXZhdGVLZXkocGtpLnByaXZhdGVLZXlUb0FzbjEocnNhS2V5KSk7CiAgICBydmFsID0gcGtpLmVuY3J5cHRQcml2YXRlS2V5SW5mbyhydmFsLCBwYXNzd29yZCwgb3B0aW9ucyk7CiAgICByZXR1cm4gcGtpLmVuY3J5cHRlZFByaXZhdGVLZXlUb1BlbShydmFsKTsKICB9CgogIC8vIGxlZ2FjeSBub24tUEtDUyM4CiAgdmFyIGFsZ29yaXRobTsKICB2YXIgaXY7CiAgdmFyIGRrTGVuOwogIHZhciBjaXBoZXJGbjsKICBzd2l0Y2gob3B0aW9ucy5hbGdvcml0aG0pIHsKICBjYXNlICdhZXMxMjgnOgogICAgYWxnb3JpdGhtID0gJ0FFUy0xMjgtQ0JDJzsKICAgIGRrTGVuID0gMTY7CiAgICBpdiA9IGZvcmdlLnJhbmRvbS5nZXRCeXRlc1N5bmMoMTYpOwogICAgY2lwaGVyRm4gPSBmb3JnZS5hZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgIGJyZWFrOwogIGNhc2UgJ2FlczE5Mic6CiAgICBhbGdvcml0aG0gPSAnQUVTLTE5Mi1DQkMnOwogICAgZGtMZW4gPSAyNDsKICAgIGl2ID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzU3luYygxNik7CiAgICBjaXBoZXJGbiA9IGZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyOwogICAgYnJlYWs7CiAgY2FzZSAnYWVzMjU2JzoKICAgIGFsZ29yaXRobSA9ICdBRVMtMjU2LUNCQyc7CiAgICBka0xlbiA9IDMyOwogICAgaXYgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXNTeW5jKDE2KTsKICAgIGNpcGhlckZuID0gZm9yZ2UuYWVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXI7CiAgICBicmVhazsKICBjYXNlICczZGVzJzoKICAgIGFsZ29yaXRobSA9ICdERVMtRURFMy1DQkMnOwogICAgZGtMZW4gPSAyNDsKICAgIGl2ID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzU3luYyg4KTsKICAgIGNpcGhlckZuID0gZm9yZ2UuZGVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXI7CiAgICBicmVhazsKICBjYXNlICdkZXMnOgogICAgYWxnb3JpdGhtID0gJ0RFUy1DQkMnOwogICAgZGtMZW4gPSA4OwogICAgaXYgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXNTeW5jKDgpOwogICAgY2lwaGVyRm4gPSBmb3JnZS5kZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBlbmNyeXB0IFJTQSBwcml2YXRlIGtleTsgdW5zdXBwb3J0ZWQgJyArCiAgICAgICdlbmNyeXB0aW9uIGFsZ29yaXRobSAiJyArIG9wdGlvbnMuYWxnb3JpdGhtICsgJyIuJyk7CiAgICBlcnJvci5hbGdvcml0aG0gPSBvcHRpb25zLmFsZ29yaXRobTsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gZW5jcnlwdCBwcml2YXRlIGtleSB1c2luZyBPcGVuU1NMIGxlZ2FjeSBrZXkgZGVyaXZhdGlvbgogIHZhciBkayA9IGZvcmdlLnBiZS5vcGVuc3NsRGVyaXZlQnl0ZXMocGFzc3dvcmQsIGl2LnN1YnN0cigwLCA4KSwgZGtMZW4pOwogIHZhciBjaXBoZXIgPSBjaXBoZXJGbihkayk7CiAgY2lwaGVyLnN0YXJ0KGl2KTsKICBjaXBoZXIudXBkYXRlKGFzbjEudG9EZXIocGtpLnByaXZhdGVLZXlUb0FzbjEocnNhS2V5KSkpOwogIGNpcGhlci5maW5pc2goKTsKCiAgdmFyIG1zZyA9IHsKICAgIHR5cGU6ICdSU0EgUFJJVkFURSBLRVknLAogICAgcHJvY1R5cGU6IHsKICAgICAgdmVyc2lvbjogJzQnLAogICAgICB0eXBlOiAnRU5DUllQVEVEJwogICAgfSwKICAgIGRla0luZm86IHsKICAgICAgYWxnb3JpdGhtOiBhbGdvcml0aG0sCiAgICAgIHBhcmFtZXRlcnM6IGZvcmdlLnV0aWwuYnl0ZXNUb0hleChpdikudG9VcHBlckNhc2UoKQogICAgfSwKICAgIGJvZHk6IGNpcGhlci5vdXRwdXQuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnKTsKfTsKCi8qKgogKiBEZWNyeXB0cyBhbiBSU0EgcHJpdmF0ZSBrZXkuCiAqCiAqIEBwYXJhbSBwZW0gdGhlIFBFTS1mb3JtYXR0ZWQgRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8gdG8gZGVjcnlwdC4KICogQHBhcmFtIHBhc3N3b3JkIHRoZSBwYXNzd29yZCB0byB1c2UuCiAqCiAqIEByZXR1cm4gdGhlIFJTQSBrZXkgb24gc3VjY2VzcywgbnVsbCBvbiBmYWlsdXJlLgogKi8KcGtpLmRlY3J5cHRSc2FQcml2YXRlS2V5ID0gZnVuY3Rpb24ocGVtLCBwYXNzd29yZCkgewogIHZhciBydmFsID0gbnVsbDsKCiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKCiAgaWYobXNnLnR5cGUgIT09ICdFTkNSWVBURUQgUFJJVkFURSBLRVknICYmCiAgICBtc2cudHlwZSAhPT0gJ1BSSVZBVEUgS0VZJyAmJgogICAgbXNnLnR5cGUgIT09ICdSU0EgUFJJVkFURSBLRVknKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IHByaXZhdGUga2V5IGZyb20gUEVNOyBQRU0gaGVhZGVyIHR5cGUgJyArCiAgICAgICdpcyBub3QgIkVOQ1JZUFRFRCBQUklWQVRFIEtFWSIsICJQUklWQVRFIEtFWSIsIG9yICJSU0EgUFJJVkFURSBLRVkiLicpOwogICAgZXJyb3IuaGVhZGVyVHlwZSA9IGVycm9yOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB2YXIgZGtMZW47CiAgICB2YXIgY2lwaGVyRm47CiAgICBzd2l0Y2gobXNnLmRla0luZm8uYWxnb3JpdGhtKSB7CiAgICBjYXNlICdERVMtQ0JDJzoKICAgICAgZGtMZW4gPSA4OwogICAgICBjaXBoZXJGbiA9IGZvcmdlLmRlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyOwogICAgICBicmVhazsKICAgIGNhc2UgJ0RFUy1FREUzLUNCQyc6CiAgICAgIGRrTGVuID0gMjQ7CiAgICAgIGNpcGhlckZuID0gZm9yZ2UuZGVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnQUVTLTEyOC1DQkMnOgogICAgICBka0xlbiA9IDE2OwogICAgICBjaXBoZXJGbiA9IGZvcmdlLmFlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyOwogICAgICBicmVhazsKICAgIGNhc2UgJ0FFUy0xOTItQ0JDJzoKICAgICAgZGtMZW4gPSAyNDsKICAgICAgY2lwaGVyRm4gPSBmb3JnZS5hZXMuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcjsKICAgICAgYnJlYWs7CiAgICBjYXNlICdBRVMtMjU2LUNCQyc6CiAgICAgIGRrTGVuID0gMzI7CiAgICAgIGNpcGhlckZuID0gZm9yZ2UuYWVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAnUkMyLTQwLUNCQyc6CiAgICAgIGRrTGVuID0gNTsKICAgICAgY2lwaGVyRm4gPSBmdW5jdGlvbihrZXkpIHsKICAgICAgICByZXR1cm4gZm9yZ2UucmMyLmNyZWF0ZURlY3J5cHRpb25DaXBoZXIoa2V5LCA0MCk7CiAgICAgIH07CiAgICAgIGJyZWFrOwogICAgY2FzZSAnUkMyLTY0LUNCQyc6CiAgICAgIGRrTGVuID0gODsKICAgICAgY2lwaGVyRm4gPSBmdW5jdGlvbihrZXkpIHsKICAgICAgICByZXR1cm4gZm9yZ2UucmMyLmNyZWF0ZURlY3J5cHRpb25DaXBoZXIoa2V5LCA2NCk7CiAgICAgIH07CiAgICAgIGJyZWFrOwogICAgY2FzZSAnUkMyLTEyOC1DQkMnOgogICAgICBka0xlbiA9IDE2OwogICAgICBjaXBoZXJGbiA9IGZ1bmN0aW9uKGtleSkgewogICAgICAgIHJldHVybiBmb3JnZS5yYzIuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcihrZXksIDEyOCk7CiAgICAgIH07CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDb3VsZCBub3QgZGVjcnlwdCBwcml2YXRlIGtleTsgdW5zdXBwb3J0ZWQgJyArCiAgICAgICAgJ2VuY3J5cHRpb24gYWxnb3JpdGhtICInICsgbXNnLmRla0luZm8uYWxnb3JpdGhtICsgJyIuJyk7CiAgICAgIGVycm9yLmFsZ29yaXRobSA9IG1zZy5kZWtJbmZvLmFsZ29yaXRobTsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLy8gdXNlIE9wZW5TU0wgbGVnYWN5IGtleSBkZXJpdmF0aW9uCiAgICB2YXIgaXYgPSBmb3JnZS51dGlsLmhleFRvQnl0ZXMobXNnLmRla0luZm8ucGFyYW1ldGVycyk7CiAgICB2YXIgZGsgPSBmb3JnZS5wYmUub3BlbnNzbERlcml2ZUJ5dGVzKHBhc3N3b3JkLCBpdi5zdWJzdHIoMCwgOCksIGRrTGVuKTsKICAgIHZhciBjaXBoZXIgPSBjaXBoZXJGbihkayk7CiAgICBjaXBoZXIuc3RhcnQoaXYpOwogICAgY2lwaGVyLnVwZGF0ZShmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihtc2cuYm9keSkpOwogICAgaWYoY2lwaGVyLmZpbmlzaCgpKSB7CiAgICAgIHJ2YWwgPSBjaXBoZXIub3V0cHV0LmdldEJ5dGVzKCk7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gcnZhbDsKICAgIH0KICB9IGVsc2UgewogICAgcnZhbCA9IG1zZy5ib2R5OwogIH0KCiAgaWYobXNnLnR5cGUgPT09ICdFTkNSWVBURUQgUFJJVkFURSBLRVknKSB7CiAgICBydmFsID0gcGtpLmRlY3J5cHRQcml2YXRlS2V5SW5mbyhhc24xLmZyb21EZXIocnZhbCksIHBhc3N3b3JkKTsKICB9IGVsc2UgewogICAgLy8gZGVjcnlwdGlvbiBhbHJlYWR5IHBlcmZvcm1lZCBhYm92ZQogICAgcnZhbCA9IGFzbjEuZnJvbURlcihydmFsKTsKICB9CgogIGlmKHJ2YWwgIT09IG51bGwpIHsKICAgIHJ2YWwgPSBwa2kucHJpdmF0ZUtleUZyb21Bc24xKHJ2YWwpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogRGVyaXZlcyBhIFBLQ1MjMTIga2V5LgogKgogKiBAcGFyYW0gcGFzc3dvcmQgdGhlIHBhc3N3b3JkIHRvIGRlcml2ZSB0aGUga2V5IG1hdGVyaWFsIGZyb20sIG51bGwgb3IKICogICAgICAgICAgdW5kZWZpbmVkIGZvciBub25lLgogKiBAcGFyYW0gc2FsdCB0aGUgc2FsdCwgYXMgYSBCeXRlQnVmZmVyLCB0byB1c2UuCiAqIEBwYXJhbSBpZCB0aGUgUEtDUyMxMiBJRCBieXRlICgxID0ga2V5IG1hdGVyaWFsLCAyID0gSVYsIDMgPSBNQUMpLgogKiBAcGFyYW0gaXRlciB0aGUgaXRlcmF0aW9uIGNvdW50LgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGRlcml2ZSBmcm9tIHRoZSBwYXNzd29yZC4KICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCB0byB1c2UsIGRlZmF1bHRzIHRvIFNIQS0xLgogKgogKiBAcmV0dXJuIGEgQnl0ZUJ1ZmZlciB3aXRoIHRoZSBieXRlcyBkZXJpdmVkIGZyb20gdGhlIHBhc3N3b3JkLgogKi8KcGtpLnBiZS5nZW5lcmF0ZVBrY3MxMktleSA9IGZ1bmN0aW9uKHBhc3N3b3JkLCBzYWx0LCBpZCwgaXRlciwgbiwgbWQpIHsKICB2YXIgaiwgbDsKCiAgaWYodHlwZW9mIG1kID09PSAndW5kZWZpbmVkJyB8fCBtZCA9PT0gbnVsbCkgewogICAgbWQgPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogIH0KCiAgdmFyIHUgPSBtZC5kaWdlc3RMZW5ndGg7CiAgdmFyIHYgPSBtZC5ibG9ja0xlbmd0aDsKICB2YXIgcmVzdWx0ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwoKICAvKiBDb252ZXJ0IHBhc3N3b3JkIHRvIFVuaWNvZGUgYnl0ZSBidWZmZXIgKyB0cmFpbGluZyAwLWJ5dGUuICovCiAgdmFyIHBhc3NCdWYgPSBuZXcgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKCk7CiAgaWYocGFzc3dvcmQgIT09IG51bGwgJiYgcGFzc3dvcmQgIT09IHVuZGVmaW5lZCkgewogICAgZm9yKGwgPSAwOyBsIDwgcGFzc3dvcmQubGVuZ3RoOyBsKyspIHsKICAgICAgcGFzc0J1Zi5wdXRJbnQxNihwYXNzd29yZC5jaGFyQ29kZUF0KGwpKTsKICAgIH0KICAgIHBhc3NCdWYucHV0SW50MTYoMCk7CiAgfQoKICAvKiBMZW5ndGggb2Ygc2FsdCBhbmQgcGFzc3dvcmQgaW4gQllURVMuICovCiAgdmFyIHAgPSBwYXNzQnVmLmxlbmd0aCgpOwogIHZhciBzID0gc2FsdC5sZW5ndGgoKTsKCiAgLyogMS4gQ29uc3RydWN0IGEgc3RyaW5nLCBEICh0aGUgImRpdmVyc2lmaWVyIiksIGJ5IGNvbmNhdGVuYXRpbmcKICAgICAgICB2IGNvcGllcyBvZiBJRC4gKi8KICB2YXIgRCA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICBELmZpbGxXaXRoQnl0ZShpZCwgdik7CgogIC8qIDIuIENvbmNhdGVuYXRlIGNvcGllcyBvZiB0aGUgc2FsdCB0b2dldGhlciB0byBjcmVhdGUgYSBzdHJpbmcgUyBvZiBsZW5ndGgKICAgICAgICB2ICogY2VpbChzIC8gdikgYnl0ZXMgKHRoZSBmaW5hbCBjb3B5IG9mIHRoZSBzYWx0IG1heSBiZSB0cnVuYWN0ZWQKICAgICAgICB0byBjcmVhdGUgUykuCiAgICAgICAgTm90ZSB0aGF0IGlmIHRoZSBzYWx0IGlzIHRoZSBlbXB0eSBzdHJpbmcsIHRoZW4gc28gaXMgUy4gKi8KICB2YXIgU2xlbiA9IHYgKiBNYXRoLmNlaWwocyAvIHYpOwogIHZhciBTID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogIGZvcihsID0gMDsgbCA8IFNsZW47IGwgKyspIHsKICAgIFMucHV0Qnl0ZShzYWx0LmF0KGwgJSBzKSk7CiAgfQoKICAvKiAzLiBDb25jYXRlbmF0ZSBjb3BpZXMgb2YgdGhlIHBhc3N3b3JkIHRvZ2V0aGVyIHRvIGNyZWF0ZSBhIHN0cmluZyBQIG9mCiAgICAgICAgbGVuZ3RoIHYgKiBjZWlsKHAgLyB2KSBieXRlcyAodGhlIGZpbmFsIGNvcHkgb2YgdGhlIHBhc3N3b3JkIG1heSBiZQogICAgICAgIHRydW5jYXRlZCB0byBjcmVhdGUgUCkuCiAgICAgICAgTm90ZSB0aGF0IGlmIHRoZSBwYXNzd29yZCBpcyB0aGUgZW1wdHkgc3RyaW5nLCB0aGVuIHNvIGlzIFAuICovCiAgdmFyIFBsZW4gPSB2ICogTWF0aC5jZWlsKHAgLyB2KTsKICB2YXIgUCA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICBmb3IobCA9IDA7IGwgPCBQbGVuOyBsICsrKSB7CiAgICBQLnB1dEJ5dGUocGFzc0J1Zi5hdChsICUgcCkpOwogIH0KCiAgLyogNC4gU2V0IEk9U3x8UCB0byBiZSB0aGUgY29uY2F0ZW5hdGlvbiBvZiBTIGFuZCBQLiAqLwogIHZhciBJID0gUzsKICBJLnB1dEJ1ZmZlcihQKTsKCiAgLyogNS4gU2V0IGM9Y2VpbChuIC8gdSkuICovCiAgdmFyIGMgPSBNYXRoLmNlaWwobiAvIHUpOwoKICAvKiA2LiBGb3IgaT0xLCAyLCAuLi4sIGMsIGRvIHRoZSBmb2xsb3dpbmc6ICovCiAgZm9yKHZhciBpID0gMTsgaSA8PSBjOyBpICsrKSB7CiAgICAvKiBhKSBTZXQgQWk9SF5yKER8fEkpLiAobC5lLiB0aGUgcnRoIGhhc2ggb2YgRHx8SSwgSChIKEgoLi4uSChEfHxJKSkpKSAqLwogICAgdmFyIGJ1ZiA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICAgIGJ1Zi5wdXRCeXRlcyhELmJ5dGVzKCkpOwogICAgYnVmLnB1dEJ5dGVzKEkuYnl0ZXMoKSk7CiAgICBmb3IodmFyIHJvdW5kID0gMDsgcm91bmQgPCBpdGVyOyByb3VuZCArKykgewogICAgICBtZC5zdGFydCgpOwogICAgICBtZC51cGRhdGUoYnVmLmdldEJ5dGVzKCkpOwogICAgICBidWYgPSBtZC5kaWdlc3QoKTsKICAgIH0KCiAgICAvKiBiKSBDb25jYXRlbmF0ZSBjb3BpZXMgb2YgQWkgdG8gY3JlYXRlIGEgc3RyaW5nIEIgb2YgbGVuZ3RoIHYgYnl0ZXMgKHRoZQogICAgICAgICAgZmluYWwgY29weSBvZiBBaSBtYXkgYmUgdHJ1bmNhdGVkIHRvIGNyZWF0ZSBCKS4gKi8KICAgIHZhciBCID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogICAgZm9yKGwgPSAwOyBsIDwgdjsgbCArKykgewogICAgICBCLnB1dEJ5dGUoYnVmLmF0KGwgJSB1KSk7CiAgICB9CgogICAgLyogYykgVHJlYXRpbmcgSSBhcyBhIGNvbmNhdGVuYXRpb24gSTAsIEkxLCAuLi4sIElrLTEgb2Ygdi1ieXRlIGJsb2NrcywKICAgICAgICAgIHdoZXJlIGs9Y2VpbChzIC8gdikgKyBjZWlsKHAgLyB2KSwgbW9kaWZ5IEkgYnkgc2V0dGluZwogICAgICAgICAgSWo9KElqK0IrMSkgbW9kIDJ2IGZvciBlYWNoIGouICAqLwogICAgdmFyIGsgPSBNYXRoLmNlaWwocyAvIHYpICsgTWF0aC5jZWlsKHAgLyB2KTsKICAgIHZhciBJbmV3ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogICAgZm9yKGogPSAwOyBqIDwgazsgaiArKykgewogICAgICB2YXIgY2h1bmsgPSBuZXcgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKEkuZ2V0Qnl0ZXModikpOwogICAgICB2YXIgeCA9IDB4MWZmOwogICAgICBmb3IobCA9IEIubGVuZ3RoKCkgLSAxOyBsID49IDA7IGwgLS0pIHsKICAgICAgICB4ID0geCA+PiA4OwogICAgICAgIHggKz0gQi5hdChsKSArIGNodW5rLmF0KGwpOwogICAgICAgIGNodW5rLnNldEF0KGwsIHggJiAweGZmKTsKICAgICAgfQogICAgICBJbmV3LnB1dEJ1ZmZlcihjaHVuayk7CiAgICB9CiAgICBJID0gSW5ldzsKCiAgICAvKiBBZGQgQWkgdG8gQS4gKi8KICAgIHJlc3VsdC5wdXRCdWZmZXIoYnVmKTsKICB9CgogIHJlc3VsdC50cnVuY2F0ZShyZXN1bHQubGVuZ3RoKCkgLSBuKTsKICByZXR1cm4gcmVzdWx0Owp9OwoKLyoqCiAqIEdldCBuZXcgRm9yZ2UgY2lwaGVyIG9iamVjdCBpbnN0YW5jZS4KICoKICogQHBhcmFtIG9pZCB0aGUgT0lEIChpbiBzdHJpbmcgbm90YXRpb24pLgogKiBAcGFyYW0gcGFyYW1zIHRoZSBBU04uMSBwYXJhbXMgb2JqZWN0LgogKiBAcGFyYW0gcGFzc3dvcmQgdGhlIHBhc3N3b3JkIHRvIGRlY3J5cHQgd2l0aC4KICoKICogQHJldHVybiBuZXcgY2lwaGVyIG9iamVjdCBpbnN0YW5jZS4KICovCnBraS5wYmUuZ2V0Q2lwaGVyID0gZnVuY3Rpb24ob2lkLCBwYXJhbXMsIHBhc3N3b3JkKSB7CiAgc3dpdGNoKG9pZCkgewogIGNhc2UgcGtpLm9pZHNbJ3BrY3M1UEJFUzInXToKICAgIHJldHVybiBwa2kucGJlLmdldENpcGhlckZvclBCRVMyKG9pZCwgcGFyYW1zLCBwYXNzd29yZCk7CgogIGNhc2UgcGtpLm9pZHNbJ3BiZVdpdGhTSEFBbmQzLUtleVRyaXBsZURFUy1DQkMnXToKICBjYXNlIHBraS5vaWRzWydwYmV3aXRoU0hBQW5kNDBCaXRSQzItQ0JDJ106CiAgICByZXR1cm4gcGtpLnBiZS5nZXRDaXBoZXJGb3JQS0NTMTJQQkUob2lkLCBwYXJhbXMsIHBhc3N3b3JkKTsKCiAgZGVmYXVsdDoKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgZW5jcnlwdGVkIFBCRSBkYXRhIGJsb2NrLiBVbnN1cHBvcnRlZCBPSUQuJyk7CiAgICBlcnJvci5vaWQgPSBvaWQ7CiAgICBlcnJvci5zdXBwb3J0ZWRPaWRzID0gWwogICAgICAncGtjczVQQkVTMicsCiAgICAgICdwYmVXaXRoU0hBQW5kMy1LZXlUcmlwbGVERVMtQ0JDJywKICAgICAgJ3BiZXdpdGhTSEFBbmQ0MEJpdFJDMi1DQkMnCiAgICBdOwogICAgdGhyb3cgZXJyb3I7CiAgfQp9OwoKLyoqCiAqIEdldCBuZXcgRm9yZ2UgY2lwaGVyIG9iamVjdCBpbnN0YW5jZSBhY2NvcmRpbmcgdG8gUEJFUzIgcGFyYW1zIGJsb2NrLgogKgogKiBUaGUgcmV0dXJuZWQgY2lwaGVyIGluc3RhbmNlIGlzIGFscmVhZHkgc3RhcnRlZCB1c2luZyB0aGUgSVYKICogZnJvbSBQQkVTMiBwYXJhbWV0ZXIgYmxvY2suCiAqCiAqIEBwYXJhbSBvaWQgdGhlIFBLQ1MjNSBQQktERjIgT0lEIChpbiBzdHJpbmcgbm90YXRpb24pLgogKiBAcGFyYW0gcGFyYW1zIHRoZSBBU04uMSBQQkVTMi1wYXJhbXMgb2JqZWN0LgogKiBAcGFyYW0gcGFzc3dvcmQgdGhlIHBhc3N3b3JkIHRvIGRlY3J5cHQgd2l0aC4KICoKICogQHJldHVybiBuZXcgY2lwaGVyIG9iamVjdCBpbnN0YW5jZS4KICovCnBraS5wYmUuZ2V0Q2lwaGVyRm9yUEJFUzIgPSBmdW5jdGlvbihvaWQsIHBhcmFtcywgcGFzc3dvcmQpIHsKICAvLyBnZXQgUEJFIHBhcmFtcwogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKHBhcmFtcywgUEJFUzJBbGdvcml0aG1zVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIHBhc3N3b3JkLWJhc2VkLWVuY3J5cHRpb24gYWxnb3JpdGhtICcgKwogICAgICAncGFyYW1ldGVycy4gQVNOLjEgb2JqZWN0IGlzIG5vdCBhIHN1cHBvcnRlZCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mby4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gY2hlY2sgb2lkcwogIG9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5rZGZPaWQpOwogIGlmKG9pZCAhPT0gcGtpLm9pZHNbJ3BrY3M1UEJLREYyJ10pIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgZW5jcnlwdGVkIHByaXZhdGUga2V5LiAnICsKICAgICAgJ1Vuc3VwcG9ydGVkIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uIE9JRC4nKTsKICAgIGVycm9yLm9pZCA9IG9pZDsKICAgIGVycm9yLnN1cHBvcnRlZE9pZHMgPSBbJ3BrY3M1UEJLREYyJ107CiAgICB0aHJvdyBlcnJvcjsKICB9CiAgb2lkID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLmVuY09pZCk7CiAgaWYob2lkICE9PSBwa2kub2lkc1snYWVzMTI4LUNCQyddICYmCiAgICBvaWQgIT09IHBraS5vaWRzWydhZXMxOTItQ0JDJ10gJiYKICAgIG9pZCAhPT0gcGtpLm9pZHNbJ2FlczI1Ni1DQkMnXSAmJgogICAgb2lkICE9PSBwa2kub2lkc1snZGVzLUVERTMtQ0JDJ10gJiYKICAgIG9pZCAhPT0gcGtpLm9pZHNbJ2Rlc0NCQyddKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIGVuY3J5cHRlZCBwcml2YXRlIGtleS4gJyArCiAgICAgICdVbnN1cHBvcnRlZCBlbmNyeXB0aW9uIHNjaGVtZSBPSUQuJyk7CiAgICBlcnJvci5vaWQgPSBvaWQ7CiAgICBlcnJvci5zdXBwb3J0ZWRPaWRzID0gWwogICAgICAnYWVzMTI4LUNCQycsICdhZXMxOTItQ0JDJywgJ2FlczI1Ni1DQkMnLCAnZGVzLUVERTMtQ0JDJywgJ2Rlc0NCQyddOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICAvLyBzZXQgUEJFIHBhcmFtcwogIHZhciBzYWx0ID0gY2FwdHVyZS5rZGZTYWx0OwogIHZhciBjb3VudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUua2RmSXRlcmF0aW9uQ291bnQpOwogIGNvdW50ID0gY291bnQuZ2V0SW50KGNvdW50Lmxlbmd0aCgpIDw8IDMpOwogIHZhciBka0xlbjsKICB2YXIgY2lwaGVyRm47CiAgc3dpdGNoKHBraS5vaWRzW29pZF0pIHsKICBjYXNlICdhZXMxMjgtQ0JDJzoKICAgIGRrTGVuID0gMTY7CiAgICBjaXBoZXJGbiA9IGZvcmdlLmFlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyOwogICAgYnJlYWs7CiAgY2FzZSAnYWVzMTkyLUNCQyc6CiAgICBka0xlbiA9IDI0OwogICAgY2lwaGVyRm4gPSBmb3JnZS5hZXMuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcjsKICAgIGJyZWFrOwogIGNhc2UgJ2FlczI1Ni1DQkMnOgogICAgZGtMZW4gPSAzMjsKICAgIGNpcGhlckZuID0gZm9yZ2UuYWVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXI7CiAgICBicmVhazsKICBjYXNlICdkZXMtRURFMy1DQkMnOgogICAgZGtMZW4gPSAyNDsKICAgIGNpcGhlckZuID0gZm9yZ2UuZGVzLmNyZWF0ZURlY3J5cHRpb25DaXBoZXI7CiAgICBicmVhazsKICBjYXNlICdkZXNDQkMnOgogICAgZGtMZW4gPSA4OwogICAgY2lwaGVyRm4gPSBmb3JnZS5kZXMuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcjsKICAgIGJyZWFrOwogIH0KCiAgLy8gZGVjcnlwdCBwcml2YXRlIGtleSB1c2luZyBwYmUgU0hBLTEgYW5kIEFFUy9ERVMKICB2YXIgZGsgPSBmb3JnZS5wa2NzNS5wYmtkZjIocGFzc3dvcmQsIHNhbHQsIGNvdW50LCBka0xlbik7CiAgdmFyIGl2ID0gY2FwdHVyZS5lbmNJdjsKICB2YXIgY2lwaGVyID0gY2lwaGVyRm4oZGspOwogIGNpcGhlci5zdGFydChpdik7CgogIHJldHVybiBjaXBoZXI7Cn07CgovKioKICogR2V0IG5ldyBGb3JnZSBjaXBoZXIgb2JqZWN0IGluc3RhbmNlIGZvciBQS0NTIzEyIFBCRS4KICoKICogVGhlIHJldHVybmVkIGNpcGhlciBpbnN0YW5jZSBpcyBhbHJlYWR5IHN0YXJ0ZWQgdXNpbmcgdGhlIGtleSAmIElWCiAqIGRlcml2ZWQgZnJvbSB0aGUgcHJvdmlkZWQgcGFzc3dvcmQgYW5kIFBLQ1MjMTIgUEJFIHNhbHQuCiAqCiAqIEBwYXJhbSBvaWQgVGhlIFBLQ1MjMTIgUEJFIE9JRCAoaW4gc3RyaW5nIG5vdGF0aW9uKS4KICogQHBhcmFtIHBhcmFtcyBUaGUgQVNOLjEgUEtDUyMxMiBQQkUtcGFyYW1zIG9iamVjdC4KICogQHBhcmFtIHBhc3N3b3JkIFRoZSBwYXNzd29yZCB0byBkZWNyeXB0IHdpdGguCiAqCiAqIEByZXR1cm4gdGhlIG5ldyBjaXBoZXIgb2JqZWN0IGluc3RhbmNlLgogKi8KcGtpLnBiZS5nZXRDaXBoZXJGb3JQS0NTMTJQQkUgPSBmdW5jdGlvbihvaWQsIHBhcmFtcywgcGFzc3dvcmQpIHsKICAvLyBnZXQgUEJFIHBhcmFtcwogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKHBhcmFtcywgcGtjczEyUGJlUGFyYW1zVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIHBhc3N3b3JkLWJhc2VkLWVuY3J5cHRpb24gYWxnb3JpdGhtICcgKwogICAgICAncGFyYW1ldGVycy4gQVNOLjEgb2JqZWN0IGlzIG5vdCBhIHN1cHBvcnRlZCBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mby4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgdmFyIHNhbHQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLnNhbHQpOwogIHZhciBjb3VudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUuaXRlcmF0aW9ucyk7CiAgY291bnQgPSBjb3VudC5nZXRJbnQoY291bnQubGVuZ3RoKCkgPDwgMyk7CgogIHZhciBka0xlbiwgZEl2TGVuLCBjaXBoZXJGbjsKICBzd2l0Y2gob2lkKSB7CiAgICBjYXNlIHBraS5vaWRzWydwYmVXaXRoU0hBQW5kMy1LZXlUcmlwbGVERVMtQ0JDJ106CiAgICAgIGRrTGVuID0gMjQ7CiAgICAgIGRJdkxlbiA9IDg7CiAgICAgIGNpcGhlckZuID0gZm9yZ2UuZGVzLnN0YXJ0RGVjcnlwdGluZzsKICAgICAgYnJlYWs7CgogICAgY2FzZSBwa2kub2lkc1sncGJld2l0aFNIQUFuZDQwQml0UkMyLUNCQyddOgogICAgICBka0xlbiA9IDU7CiAgICAgIGRJdkxlbiA9IDg7CiAgICAgIGNpcGhlckZuID0gZnVuY3Rpb24oa2V5LCBpdikgewogICAgICAgIHZhciBjaXBoZXIgPSBmb3JnZS5yYzIuY3JlYXRlRGVjcnlwdGlvbkNpcGhlcihrZXksIDQwKTsKICAgICAgICBjaXBoZXIuc3RhcnQoaXYsIG51bGwpOwogICAgICAgIHJldHVybiBjaXBoZXI7CiAgICAgIH07CiAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgUEtDUyAjMTIgUEJFIGRhdGEgYmxvY2suIFVuc3VwcG9ydGVkIE9JRC4nKTsKICAgICAgZXJyb3Iub2lkID0gb2lkOwogICAgICB0aHJvdyBlcnJvcjsKICB9CgogIHZhciBrZXkgPSBwa2kucGJlLmdlbmVyYXRlUGtjczEyS2V5KHBhc3N3b3JkLCBzYWx0LCAxLCBjb3VudCwgZGtMZW4pOwogIHZhciBpdiA9IHBraS5wYmUuZ2VuZXJhdGVQa2NzMTJLZXkocGFzc3dvcmQsIHNhbHQsIDIsIGNvdW50LCBkSXZMZW4pOwoKICByZXR1cm4gY2lwaGVyRm4oa2V5LCBpdik7Cn07CgovKioKICogT3BlblNTTCdzIGxlZ2FjeSBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbi4KICoKICogU2VlOiBodHRwOi8vd3d3Lm9wZW5zc2wub3JnL2RvY3MvY3J5cHRvL0VWUF9CeXRlc1RvS2V5Lmh0bWwKICoKICogQHBhcmFtIHBhc3N3b3JkIHRoZSBwYXNzd29yZCB0byBkZXJpdmUgdGhlIGtleSBmcm9tLgogKiBAcGFyYW0gc2FsdCB0aGUgc2FsdCB0byB1c2UsIG51bGwgZm9yIG5vbmUuCiAqIEBwYXJhbSBka0xlbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCBmb3IgdGhlIGRlcml2ZWQga2V5LgogKiBAcGFyYW0gW29wdGlvbnNdIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgW21kXSBhbiBvcHRpb25hbCBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlLgogKi8KcGtpLnBiZS5vcGVuc3NsRGVyaXZlQnl0ZXMgPSBmdW5jdGlvbihwYXNzd29yZCwgc2FsdCwgZGtMZW4sIG1kKSB7CiAgaWYodHlwZW9mIG1kID09PSAndW5kZWZpbmVkJyB8fCBtZCA9PT0gbnVsbCkgewogICAgbWQgPSBmb3JnZS5tZC5tZDUuY3JlYXRlKCk7CiAgfQogIGlmKHNhbHQgPT09IG51bGwpIHsKICAgIHNhbHQgPSAnJzsKICB9CiAgdmFyIGRpZ2VzdHMgPSBbaGFzaChtZCwgcGFzc3dvcmQgKyBzYWx0KV07CiAgZm9yKHZhciBsZW5ndGggPSAxNiwgaSA9IDE7IGxlbmd0aCA8IGRrTGVuOyArK2ksIGxlbmd0aCArPSAxNikgewogICAgZGlnZXN0cy5wdXNoKGhhc2gobWQsIGRpZ2VzdHNbaSAtIDFdICsgcGFzc3dvcmQgKyBzYWx0KSk7CiAgfQogIHJldHVybiBkaWdlc3RzLmpvaW4oJycpLnN1YnN0cigwLCBka0xlbik7Cn07CgpmdW5jdGlvbiBoYXNoKG1kLCBieXRlcykgewogIHJldHVybiBtZC5zdGFydCgpLnVwZGF0ZShieXRlcykuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKfQoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncGJlJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3BiZScsWwogICdyZXF1aXJlJywKICAnbW9kdWxlJywKICAnLi9hZXMnLAogICcuL2FzbjEnLAogICcuL2RlcycsCiAgJy4vbWQnLAogICcuL29pZHMnLAogICcuL3BlbScsCiAgJy4vcGJrZGYyJywKICAnLi9yYW5kb20nLAogICcuL3JjMicsCiAgJy4vcnNhJywKICAnLi91dGlsJwpdLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIEFTTi4xIHZhbGlkYXRvcnMgZm9yIFBLQ1MjNyB2MS41LgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKiBAYXV0aG9yIFN0ZWZhbiBTaWVnbAogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTItMjAxNSBEaWdpdGFsIEJhemFhciwgSW5jLgogKiBDb3B5cmlnaHQgKGMpIDIwMTIgU3RlZmFuIFNpZWdsIDxzdGVzaWVAYnJva2VucGlwZS5kZT4KICoKICogVGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIFBLQ1MjNyBpcyBhcyBmb2xsb3dzCiAqIChzZWUgUkZDICMyMzE1IGZvciBkZXRhaWxzLCBodHRwOi8vd3d3LmlldGYub3JnL3JmYy9yZmMyMzE1LnR4dCk6CiAqCiAqIEEgUEtDUyM3IG1lc3NhZ2UgY29uc2lzdHMgb2YgYSBDb250ZW50SW5mbyBvbiByb290IGxldmVsLCB3aGljaCBtYXkKICogY29udGFpbiBhbnkgbnVtYmVyIG9mIGZ1cnRoZXIgQ29udGVudEluZm8gbmVzdGVkIGludG8gaXQuCiAqCiAqIENvbnRlbnRJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgY29udGVudFR5cGUgICAgICAgICAgICAgICAgQ29udGVudFR5cGUsCiAqICAgY29udGVudCAgICAgICAgICAgICAgIFswXSAgRVhQTElDSVQgQU5ZIERFRklORUQgQlkgY29udGVudFR5cGUgT1BUSU9OQUwKICogfQogKgogKiBDb250ZW50VHlwZSA6Oj0gT0JKRUNUIElERU5USUZJRVIKICoKICogRW52ZWxvcGVkRGF0YSA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gICAgICAgICAgICAgICAgICAgIFZlcnNpb24sCiAqICAgcmVjaXBpZW50SW5mb3MgICAgICAgICAgICAgUmVjaXBpZW50SW5mb3MsCiAqICAgZW5jcnlwdGVkQ29udGVudEluZm8gICAgICAgRW5jcnlwdGVkQ29udGVudEluZm8KICogfQogKgogKiBFbmNyeXB0ZWREYXRhIDo6PSBTRVFVRU5DRSB7CiAqICAgdmVyc2lvbiAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiwKICogICBlbmNyeXB0ZWRDb250ZW50SW5mbyAgICAgICBFbmNyeXB0ZWRDb250ZW50SW5mbwogKiB9CiAqCiAqIGlkLXNpZ25lZERhdGEgT0JKRUNUIElERU5USUZJRVIgOjo9IHsgaXNvKDEpIG1lbWJlci1ib2R5KDIpCiAqICAgdXMoODQwKSByc2Fkc2koMTEzNTQ5KSBwa2NzKDEpIHBrY3M3KDcpIDIgfQogKgogKiBTaWduZWREYXRhIDo6PSBTRVFVRU5DRSB7CiAqICAgdmVyc2lvbiAgICAgICAgICAgSU5URUdFUiwKICogICBkaWdlc3RBbGdvcml0aG1zICBEaWdlc3RBbGdvcml0aG1JZGVudGlmaWVycywKICogICBjb250ZW50SW5mbyAgICAgICBDb250ZW50SW5mbywKICogICBjZXJ0aWZpY2F0ZXMgICAgICBbMF0gSU1QTElDSVQgQ2VydGlmaWNhdGVzIE9QVElPTkFMLAogKiAgIGNybHMgICAgICAgICAgICAgIFsxXSBJTVBMSUNJVCBDZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0cyBPUFRJT05BTCwKICogICBzaWduZXJJbmZvcyAgICAgICBTaWduZXJJbmZvcwogKiB9CiAqCiAqIFNpZ25lckluZm9zIDo6PSBTRVQgT0YgU2lnbmVySW5mbwogKgogKiBTaWduZXJJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgdmVyc2lvbiAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiwKICogICBpc3N1ZXJBbmRTZXJpYWxOdW1iZXIgICAgICBJc3N1ZXJBbmRTZXJpYWxOdW1iZXIsCiAqICAgZGlnZXN0QWxnb3JpdGhtICAgICAgICAgICAgRGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllciwKICogICBhdXRoZW50aWNhdGVkQXR0cmlidXRlcyAgICBbMF0gSU1QTElDSVQgQXR0cmlidXRlcyBPUFRJT05BTCwKICogICBkaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtICBEaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciwKICogICBlbmNyeXB0ZWREaWdlc3QgICAgICAgICAgICBFbmNyeXB0ZWREaWdlc3QsCiAqICAgdW5hdXRoZW50aWNhdGVkQXR0cmlidXRlcyAgWzFdIElNUExJQ0lUIEF0dHJpYnV0ZXMgT1BUSU9OQUwKICogfQogKgogKiBFbmNyeXB0ZWREaWdlc3QgOjo9IE9DVEVUIFNUUklORwogKgogKiBBdHRyaWJ1dGVzIDo6PSBTRVQgT0YgQXR0cmlidXRlCiAqCiAqIEF0dHJpYnV0ZSA6Oj0gU0VRVUVOQ0UgewogKiAgIGF0dHJUeXBlICAgIE9CSkVDVCBJREVOVElGSUVSLAogKiAgIGF0dHJWYWx1ZXMgIFNFVCBPRiBBdHRyaWJ1dGVWYWx1ZQogKiB9CiAqCiAqIEF0dHJpYnV0ZVZhbHVlIDo6PSBBTlkKICoKICogVmVyc2lvbiA6Oj0gSU5URUdFUgogKgogKiBSZWNpcGllbnRJbmZvcyA6Oj0gU0VUIE9GIFJlY2lwaWVudEluZm8KICoKICogRW5jcnlwdGVkQ29udGVudEluZm8gOjo9IFNFUVVFTkNFIHsKICogICBjb250ZW50VHlwZSAgICAgICAgICAgICAgICAgQ29udGVudFR5cGUsCiAqICAgY29udGVudEVuY3J5cHRpb25BbGdvcml0aG0gIENvbnRlbnRFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciwKICogICBlbmNyeXB0ZWRDb250ZW50ICAgICAgIFswXSAgSU1QTElDSVQgRW5jcnlwdGVkQ29udGVudCBPUFRJT05BTAogKiB9CiAqCiAqIENvbnRlbnRFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciA6Oj0gQWxnb3JpdGhtSWRlbnRpZmllcgogKgogKiBUaGUgQWxnb3JpdGhtSWRlbnRpZmllciBjb250YWlucyBhbiBPYmplY3QgSWRlbnRpZmllciAoT0lEKSBhbmQgcGFyYW1ldGVycwogKiBmb3IgdGhlIGFsZ29yaXRobSwgaWYgYW55LiBJbiB0aGUgY2FzZSBvZiBBRVMgYW5kIERFUzMsIHRoZXJlIGlzIG9ubHkgb25lLAogKiB0aGUgSVYuCiAqCiAqIEFsZ29yaXRobUlkZW50aWZlciA6Oj0gU0VRVUVOQ0UgewogKiAgICBhbGdvcml0aG0gT0JKRUNUIElERU5USUZJRVIsCiAqICAgIHBhcmFtZXRlcnMgQU5ZIERFRklORUQgQlkgYWxnb3JpdGhtIE9QVElPTkFMCiAqIH0KICoKICogRW5jcnlwdGVkQ29udGVudCA6Oj0gT0NURVQgU1RSSU5HCiAqCiAqIFJlY2lwaWVudEluZm8gOjo9IFNFUVVFTkNFIHsKICogICB2ZXJzaW9uICAgICAgICAgICAgICAgICAgICAgVmVyc2lvbiwKICogICBpc3N1ZXJBbmRTZXJpYWxOdW1iZXIgICAgICAgSXNzdWVyQW5kU2VyaWFsTnVtYmVyLAogKiAgIGtleUVuY3J5cHRpb25BbGdvcml0aG0gICAgICBLZXlFbmNyeXB0aW9uQWxnb3JpdGhtSWRlbnRpZmllciwKICogICBlbmNyeXB0ZWRLZXkgICAgICAgICAgICAgICAgRW5jcnlwdGVkS2V5CiAqIH0KICoKICogSXNzdWVyQW5kU2VyaWFsTnVtYmVyIDo6PSBTRVFVRU5DRSB7CiAqICAgaXNzdWVyICAgICAgICAgICAgICAgICAgICAgIE5hbWUsCiAqICAgc2VyaWFsTnVtYmVyICAgICAgICAgICAgICAgIENlcnRpZmljYXRlU2VyaWFsTnVtYmVyCiAqIH0KICoKICogQ2VydGlmaWNhdGVTZXJpYWxOdW1iZXIgOjo9IElOVEVHRVIKICoKICogS2V5RW5jcnlwdGlvbkFsZ29yaXRobUlkZW50aWZpZXIgOjo9IEFsZ29yaXRobUlkZW50aWZpZXIKICoKICogRW5jcnlwdGVkS2V5IDo6PSBPQ1RFVCBTVFJJTkcKICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBzaG9ydGN1dCBmb3IgQVNOLjEgQVBJCnZhciBhc24xID0gZm9yZ2UuYXNuMTsKCi8vIHNob3J0Y3V0IGZvciBQS0NTIzcgQVBJCnZhciBwN3YgPSBmb3JnZS5wa2NzN2FzbjEgPSBmb3JnZS5wa2NzN2FzbjEgfHwge307CmZvcmdlLnBrY3M3ID0gZm9yZ2UucGtjczcgfHwge307CmZvcmdlLnBrY3M3LmFzbjEgPSBwN3Y7Cgp2YXIgY29udGVudEluZm9WYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0NvbnRlbnRJbmZvJywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIHZhbHVlOiBbewogICAgbmFtZTogJ0NvbnRlbnRJbmZvLkNvbnRlbnRUeXBlJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAnY29udGVudFR5cGUnCiAgfSwgewogICAgbmFtZTogJ0NvbnRlbnRJbmZvLmNvbnRlbnQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgIHR5cGU6IDAsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgY2FwdHVyZUFzbjE6ICdjb250ZW50JwogIH1dCn07CnA3di5jb250ZW50SW5mb1ZhbGlkYXRvciA9IGNvbnRlbnRJbmZvVmFsaWRhdG9yOwoKdmFyIGVuY3J5cHRlZENvbnRlbnRJbmZvVmFsaWRhdG9yID0gewogIG5hbWU6ICdFbmNyeXB0ZWRDb250ZW50SW5mbycsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdFbmNyeXB0ZWRDb250ZW50SW5mby5jb250ZW50VHlwZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2NvbnRlbnRUeXBlJwogIH0sIHsKICAgIG5hbWU6ICdFbmNyeXB0ZWRDb250ZW50SW5mby5jb250ZW50RW5jcnlwdGlvbkFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnRW5jcnlwdGVkQ29udGVudEluZm8uY29udGVudEVuY3J5cHRpb25BbGdvcml0aG0uYWxnb3JpdGhtJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdlbmNBbGdvcml0aG0nCiAgICB9LCB7CiAgICAgIG5hbWU6ICdFbmNyeXB0ZWRDb250ZW50SW5mby5jb250ZW50RW5jcnlwdGlvbkFsZ29yaXRobS5wYXJhbWV0ZXInLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIGNhcHR1cmVBc24xOiAnZW5jUGFyYW1ldGVyJwogICAgfV0KICB9LCB7CiAgICBuYW1lOiAnRW5jcnlwdGVkQ29udGVudEluZm8uZW5jcnlwdGVkQ29udGVudCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLAogICAgdHlwZTogMCwKICAgIC8qIFRoZSBQS0NTIzcgc3RydWN0dXJlIG91dHB1dCBieSBPcGVuU1NMIHNvbWV3aGF0IGRpZmZlcnMgZnJvbSB3aGF0CiAgICAgKiBvdGhlciBpbXBsZW1lbnRhdGlvbnMgZG8gZ2VuZXJhdGUuCiAgICAgKgogICAgICogT3BlblNTTCBnZW5lcmF0ZXMgYSBzdHJ1Y3R1cmUgbGlrZSB0aGlzOgogICAgICogU0VRVUVOQ0UgewogICAgICogICAgLi4uCiAgICAgKiAgICBbMF0KICAgICAqICAgICAgIDI2IERBIDY3IEQyIDE3IDlDIDQ1IDNDIEIxIDJBIEE4IDU5IDJGIDI5IDMzIDM4CiAgICAgKiAgICAgICBDMyBDMyBERiA4NiA3MSA3NCA3QSAxOSA5RiA0MCBEMCAyOSBCRSA4NSA5MCA0NQogICAgICogICAgICAgLi4uCiAgICAgKiB9CiAgICAgKgogICAgICogV2hlcmVhcyBvdGhlciBpbXBsZW1lbnRhdGlvbnMgKGFuZCB0aGlzIFBLQ1MjNyBtb2R1bGUpIGdlbmVyYXRlOgogICAgICogU0VRVUVOQ0UgewogICAgICogICAgLi4uCiAgICAgKiAgICBbMF0gewogICAgICogICAgICAgT0NURVQgU1RSSU5HCiAgICAgKiAgICAgICAgICAyNiBEQSA2NyBEMiAxNyA5QyA0NSAzQyBCMSAyQSBBOCA1OSAyRiAyOSAzMyAzOAogICAgICogICAgICAgICAgQzMgQzMgREYgODYgNzEgNzQgN0EgMTkgOUYgNDAgRDAgMjkgQkUgODUgOTAgNDUKICAgICAqICAgICAgICAgIC4uLgogICAgICogICAgfQogICAgICogfQogICAgICoKICAgICAqIEluIG9yZGVyIHRvIHN1cHBvcnQgYm90aCwgd2UganVzdCBjYXB0dXJlIHRoZSBjb250ZXh0IHNwZWNpZmljCiAgICAgKiBmaWVsZCBoZXJlLiAgVGhlIE9DVEVUIFNUUklORyBiaXQgaXMgcmVtb3ZlZCBiZWxvdy4KICAgICAqLwogICAgY2FwdHVyZTogJ2VuY3J5cHRlZENvbnRlbnQnLAogICAgY2FwdHVyZUFzbjE6ICdlbmNyeXB0ZWRDb250ZW50QXNuMScKICB9XQp9OwoKcDd2LmVudmVsb3BlZERhdGFWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0VudmVsb3BlZERhdGEnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnRW52ZWxvcGVkRGF0YS5WZXJzaW9uJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ZlcnNpb24nCiAgfSwgewogICAgbmFtZTogJ0VudmVsb3BlZERhdGEuUmVjaXBpZW50SW5mb3MnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFVCwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgY2FwdHVyZUFzbjE6ICdyZWNpcGllbnRJbmZvcycKICB9XS5jb25jYXQoZW5jcnlwdGVkQ29udGVudEluZm9WYWxpZGF0b3IpCn07CgpwN3YuZW5jcnlwdGVkRGF0YVZhbGlkYXRvciA9IHsKICBuYW1lOiAnRW5jcnlwdGVkRGF0YScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdFbmNyeXB0ZWREYXRhLlZlcnNpb24nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAndmVyc2lvbicKICB9XS5jb25jYXQoZW5jcnlwdGVkQ29udGVudEluZm9WYWxpZGF0b3IpCn07Cgp2YXIgc2lnbmVyVmFsaWRhdG9yID0gewogIG5hbWU6ICdTaWduZXJJbmZvJywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIHZhbHVlOiBbewogICAgbmFtZTogJ1NpZ25lckluZm8udmVyc2lvbicsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZQogIH0sIHsKICAgIG5hbWU6ICdTaWduZXJJbmZvLmlzc3VlckFuZFNlcmlhbE51bWJlcicsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnU2lnbmVySW5mby5pc3N1ZXJBbmRTZXJpYWxOdW1iZXIuaXNzdWVyJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ2lzc3VlcicKICAgIH0sIHsKICAgICAgbmFtZTogJ1NpZ25lckluZm8uaXNzdWVyQW5kU2VyaWFsTnVtYmVyLnNlcmlhbE51bWJlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ3NlcmlhbCcKICAgIH1dCiAgfSwgewogICAgbmFtZTogJ1NpZ25lckluZm8uZGlnZXN0QWxnb3JpdGhtJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdTaWduZXJJbmZvLmRpZ2VzdEFsZ29yaXRobS5hbGdvcml0aG0nLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2RpZ2VzdEFsZ29yaXRobScKICAgIH0sIHsKICAgICAgbmFtZTogJ1NpZ25lckluZm8uZGlnZXN0QWxnb3JpdGhtLnBhcmFtZXRlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlQXNuMTogJ2RpZ2VzdFBhcmFtZXRlcicsCiAgICAgIG9wdGlvbmFsOiB0cnVlCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdTaWduZXJJbmZvLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICB0eXBlOiAwLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICBvcHRpb25hbDogdHJ1ZSwKICAgIGNhcHR1cmU6ICdhdXRoZW50aWNhdGVkQXR0cmlidXRlcycKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVySW5mby5kaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgY2FwdHVyZTogJ3NpZ25hdHVyZUFsZ29yaXRobScKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVySW5mby5lbmNyeXB0ZWREaWdlc3QnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3NpZ25hdHVyZScKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVySW5mby51bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICB0eXBlOiAxLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICBvcHRpb25hbDogdHJ1ZSwKICAgIGNhcHR1cmU6ICd1bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzJwogIH1dCn07CgpwN3Yuc2lnbmVkRGF0YVZhbGlkYXRvciA9IHsKICBuYW1lOiAnU2lnbmVkRGF0YScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdTaWduZWREYXRhLlZlcnNpb24nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAndmVyc2lvbicKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVkRGF0YS5EaWdlc3RBbGdvcml0aG1zJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVQsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAnZGlnZXN0QWxnb3JpdGhtcycKICB9LAogIGNvbnRlbnRJbmZvVmFsaWRhdG9yLAogIHsKICAgIG5hbWU6ICdTaWduZWREYXRhLkNlcnRpZmljYXRlcycsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLAogICAgdHlwZTogMCwKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgY2FwdHVyZUFzbjE6ICdjZXJ0aWZpY2F0ZXMnCiAgfSwgewogICAgbmFtZTogJ1NpZ25lZERhdGEuQ2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdHMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgIHR5cGU6IDEsCiAgICBvcHRpb25hbDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAnY3JscycKICB9LCB7CiAgICBuYW1lOiAnU2lnbmVkRGF0YS5TaWduZXJJbmZvcycsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VULAogICAgY2FwdHVyZTogJ3NpZ25lckluZm9zJywKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgdmFsdWU6IFtzaWduZXJWYWxpZGF0b3JdCiAgfV0KfTsKCnA3di5yZWNpcGllbnRJbmZvVmFsaWRhdG9yID0gewogIG5hbWU6ICdSZWNpcGllbnRJbmZvJywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIHZhbHVlOiBbewogICAgbmFtZTogJ1JlY2lwaWVudEluZm8udmVyc2lvbicsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuSU5URUdFUiwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICd2ZXJzaW9uJwogIH0sIHsKICAgIG5hbWU6ICdSZWNpcGllbnRJbmZvLmlzc3VlckFuZFNlcmlhbCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnUmVjaXBpZW50SW5mby5pc3N1ZXJBbmRTZXJpYWwuaXNzdWVyJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ2lzc3VlcicKICAgIH0sIHsKICAgICAgbmFtZTogJ1JlY2lwaWVudEluZm8uaXNzdWVyQW5kU2VyaWFsLnNlcmlhbE51bWJlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ3NlcmlhbCcKICAgIH1dCiAgfSwgewogICAgbmFtZTogJ1JlY2lwaWVudEluZm8ua2V5RW5jcnlwdGlvbkFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnUmVjaXBpZW50SW5mby5rZXlFbmNyeXB0aW9uQWxnb3JpdGhtLmFsZ29yaXRobScsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlOiAnZW5jQWxnb3JpdGhtJwogICAgfSwgewogICAgICBuYW1lOiAnUmVjaXBpZW50SW5mby5rZXlFbmNyeXB0aW9uQWxnb3JpdGhtLnBhcmFtZXRlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlQXNuMTogJ2VuY1BhcmFtZXRlcicKICAgIH1dCiAgfSwgewogICAgbmFtZTogJ1JlY2lwaWVudEluZm8uZW5jcnlwdGVkS2V5JywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5PQ1RFVFNUUklORywKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdlbmNLZXknCiAgfV0KfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3BrY3M3YXNuMSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9wa2NzN2FzbjEnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9hc24xJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIG1hc2sgZ2VuZXJhdGlvbiBmdW5jdGlvbiBNR0YxLgogKgogKiBAYXV0aG9yIFN0ZWZhbiBTaWVnbAogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTIgU3RlZmFuIFNpZWdsIDxzdGVzaWVAYnJva2VucGlwZS5kZT4KICogQ29weXJpZ2h0IChjKSAyMDE0IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UubWdmID0gZm9yZ2UubWdmIHx8IHt9Owp2YXIgbWdmMSA9IGZvcmdlLm1nZi5tZ2YxID0gZm9yZ2UubWdmMSA9IGZvcmdlLm1nZjEgfHwge307CgovKioKICogQ3JlYXRlcyBhIE1HRjEgbWFzayBnZW5lcmF0aW9uIGZ1bmN0aW9uIG9iamVjdC4KICoKICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBBUEkgdG8gdXNlIChlZzogZm9yZ2UubWQuc2hhMS5jcmVhdGUoKSkuCiAqCiAqIEByZXR1cm4gYSBtYXNrIGdlbmVyYXRpb24gZnVuY3Rpb24gb2JqZWN0LgogKi8KbWdmMS5jcmVhdGUgPSBmdW5jdGlvbihtZCkgewogIHZhciBtZ2YgPSB7CiAgICAvKioKICAgICAqIEdlbmVyYXRlIG1hc2sgb2Ygc3BlY2lmaWVkIGxlbmd0aC4KICAgICAqCiAgICAgKiBAcGFyYW0ge1N0cmluZ30gc2VlZCBUaGUgc2VlZCBmb3IgbWFzayBnZW5lcmF0aW9uLgogICAgICogQHBhcmFtIG1hc2tMZW4gTnVtYmVyIG9mIGJ5dGVzIHRvIGdlbmVyYXRlLgogICAgICogQHJldHVybiB7U3RyaW5nfSBUaGUgZ2VuZXJhdGVkIG1hc2suCiAgICAgKi8KICAgIGdlbmVyYXRlOiBmdW5jdGlvbihzZWVkLCBtYXNrTGVuKSB7CiAgICAgIC8qIDIuIExldCBUIGJlIHRoZSBlbXB0eSBvY3RldCBzdHJpbmcuICovCiAgICAgIHZhciB0ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwoKICAgICAgLyogMy4gRm9yIGNvdW50ZXIgZnJvbSAwIHRvIGNlaWwobWFza0xlbiAvIGhMZW4pLCBkbyB0aGUgZm9sbG93aW5nOiAqLwogICAgICB2YXIgbGVuID0gTWF0aC5jZWlsKG1hc2tMZW4gLyBtZC5kaWdlc3RMZW5ndGgpOwogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgICAvKiBhLiBDb252ZXJ0IGNvdW50ZXIgdG8gYW4gb2N0ZXQgc3RyaW5nIEMgb2YgbGVuZ3RoIDQgb2N0ZXRzICovCiAgICAgICAgdmFyIGMgPSBuZXcgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKCk7CiAgICAgICAgYy5wdXRJbnQzMihpKTsKCiAgICAgICAgLyogYi4gQ29uY2F0ZW5hdGUgdGhlIGhhc2ggb2YgdGhlIHNlZWQgbWdmU2VlZCBhbmQgQyB0byB0aGUgb2N0ZXQKICAgICAgICAgKiBzdHJpbmcgVDogKi8KICAgICAgICBtZC5zdGFydCgpOwogICAgICAgIG1kLnVwZGF0ZShzZWVkICsgYy5nZXRCeXRlcygpKTsKICAgICAgICB0LnB1dEJ1ZmZlcihtZC5kaWdlc3QoKSk7CiAgICAgIH0KCiAgICAgIC8qIE91dHB1dCB0aGUgbGVhZGluZyBtYXNrTGVuIG9jdGV0cyBvZiBUIGFzIHRoZSBvY3RldCBzdHJpbmcgbWFzay4gKi8KICAgICAgdC50cnVuY2F0ZSh0Lmxlbmd0aCgpIC0gbWFza0xlbik7CiAgICAgIHJldHVybiB0LmdldEJ5dGVzKCk7CiAgICB9CiAgfTsKCiAgcmV0dXJuIG1nZjsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ21nZjEnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvbWdmMScsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogTm9kZS5qcyBtb2R1bGUgZm9yIEZvcmdlIG1hc2sgZ2VuZXJhdGlvbiBmdW5jdGlvbnMuCiAqCiAqIEBhdXRob3IgU3RlZmFuIFNpZWdsCiAqCiAqIENvcHlyaWdodCAyMDEyIFN0ZWZhbiBTaWVnbCA8c3Rlc2llQGJyb2tlbnBpcGUuZGU+CiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKZm9yZ2UubWdmID0gZm9yZ2UubWdmIHx8IHt9Owpmb3JnZS5tZ2YubWdmMSA9IGZvcmdlLm1nZjE7Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdtZ2YnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvbWdmJyxbJ3JlcXVpcmUnLCAnbW9kdWxlJywgJy4vbWdmMSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIFBLQ1MjMSBQU1Mgc2lnbmF0dXJlIHBhZGRpbmcuCiAqCiAqIEBhdXRob3IgU3RlZmFuIFNpZWdsCiAqCiAqIENvcHlyaWdodCAoYykgMjAxMiBTdGVmYW4gU2llZ2wgPHN0ZXNpZUBicm9rZW5waXBlLmRlPgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIHNob3J0Y3V0IGZvciBQU1MgQVBJCnZhciBwc3MgPSBmb3JnZS5wc3MgPSBmb3JnZS5wc3MgfHwge307CgovKioKICogQ3JlYXRlcyBhIFBTUyBzaWduYXR1cmUgc2NoZW1lIG9iamVjdC4KICoKICogVGhlcmUgYXJlIHNldmVyYWwgd2F5cyB0byBwcm92aWRlIGEgc2FsdCBmb3IgZW5jb2Rpbmc6CiAqCiAqIDEuIFNwZWNpZnkgdGhlIHNhbHRMZW5ndGggb25seSBhbmQgdGhlIGJ1aWx0LWluIFBSTkcgd2lsbCBnZW5lcmF0ZSBpdC4KICogMi4gU3BlY2lmeSB0aGUgc2FsdExlbmd0aCBhbmQgYSBjdXN0b20gUFJORyB3aXRoICdnZXRCeXRlc1N5bmMnIGRlZmluZWQgdGhhdAogKiAgIHdpbGwgYmUgdXNlZC4KICogMy4gU3BlY2lmeSB0aGUgc2FsdCBpdHNlbGYgYXMgYSBmb3JnZS51dGlsLkJ5dGVCdWZmZXIuCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIHRvIHVzZToKICogICAgICAgICAgbWQgdGhlIG1lc3NhZ2UgZGlnZXN0IG9iamVjdCB0byB1c2UsIGEgZm9yZ2UgbWQgaW5zdGFuY2UuCiAqICAgICAgICAgIG1nZiB0aGUgbWFzayBnZW5lcmF0aW9uIGZ1bmN0aW9uIHRvIHVzZSwgYSBmb3JnZSBtZ2YgaW5zdGFuY2UuCiAqICAgICAgICAgIFtzYWx0TGVuZ3RoXSB0aGUgbGVuZ3RoIG9mIHRoZSBzYWx0IGluIG9jdGV0cy4KICogICAgICAgICAgW3BybmddIHRoZSBwc2V1ZG8tcmFuZG9tIG51bWJlciBnZW5lcmF0b3IgdG8gdXNlIHRvIHByb2R1Y2UgYSBzYWx0LgogKiAgICAgICAgICBbc2FsdF0gdGhlIHNhbHQgdG8gdXNlIHdoZW4gZW5jb2RpbmcuCiAqCiAqIEByZXR1cm4gYSBzaWduYXR1cmUgc2NoZW1lIG9iamVjdC4KICovCnBzcy5jcmVhdGUgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgLy8gYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgdy9sZWdhY3kgYXJnczogaGFzaCwgbWdmLCBzTGVuCiAgaWYoYXJndW1lbnRzLmxlbmd0aCA9PT0gMykgewogICAgb3B0aW9ucyA9IHsKICAgICAgbWQ6IGFyZ3VtZW50c1swXSwKICAgICAgbWdmOiBhcmd1bWVudHNbMV0sCiAgICAgIHNhbHRMZW5ndGg6IGFyZ3VtZW50c1syXQogICAgfTsKICB9CgogIHZhciBoYXNoID0gb3B0aW9ucy5tZDsKICB2YXIgbWdmID0gb3B0aW9ucy5tZ2Y7CiAgdmFyIGhMZW4gPSBoYXNoLmRpZ2VzdExlbmd0aDsKCiAgdmFyIHNhbHRfID0gb3B0aW9ucy5zYWx0IHx8IG51bGw7CiAgaWYodHlwZW9mIHNhbHRfID09PSAnc3RyaW5nJykgewogICAgLy8gYXNzdW1lIGJpbmFyeS1lbmNvZGVkIHN0cmluZwogICAgc2FsdF8gPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihzYWx0Xyk7CiAgfQoKICB2YXIgc0xlbjsKICBpZignc2FsdExlbmd0aCcgaW4gb3B0aW9ucykgewogICAgc0xlbiA9IG9wdGlvbnMuc2FsdExlbmd0aDsKICB9IGVsc2UgaWYoc2FsdF8gIT09IG51bGwpIHsKICAgIHNMZW4gPSBzYWx0Xy5sZW5ndGgoKTsKICB9IGVsc2UgewogICAgdGhyb3cgbmV3IEVycm9yKCdTYWx0IGxlbmd0aCBub3Qgc3BlY2lmaWVkIG9yIHNwZWNpZmljIHNhbHQgbm90IGdpdmVuLicpOwogIH0KCiAgaWYoc2FsdF8gIT09IG51bGwgJiYgc2FsdF8ubGVuZ3RoKCkgIT09IHNMZW4pIHsKICAgIHRocm93IG5ldyBFcnJvcignR2l2ZW4gc2FsdCBsZW5ndGggZG9lcyBub3QgbWF0Y2ggbGVuZ3RoIG9mIGdpdmVuIHNhbHQuJyk7CiAgfQoKICB2YXIgcHJuZyA9IG9wdGlvbnMucHJuZyB8fCBmb3JnZS5yYW5kb207CgogIHZhciBwc3NvYmogPSB7fTsKCiAgLyoqCiAgICogRW5jb2RlcyBhIFBTUyBzaWduYXR1cmUuCiAgICoKICAgKiBUaGlzIGZ1bmN0aW9uIGltcGxlbWVudHMgRU1TQS1QU1MtRU5DT0RFIGFzIHBlciBSRkMgMzQ0Nywgc2VjdGlvbiA5LjEuMS4KICAgKgogICAqIEBwYXJhbSBtZCB0aGUgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0IHdpdGggdGhlIGhhc2ggdG8gc2lnbi4KICAgKiBAcGFyYW0gbW9kc0JpdHMgdGhlIGxlbmd0aCBvZiB0aGUgUlNBIG1vZHVsdXMgaW4gYml0cy4KICAgKgogICAqIEByZXR1cm4gdGhlIGVuY29kZWQgbWVzc2FnZSBhcyBhIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBsZW5ndGgKICAgKiAgICAgICAgICAgY2VpbCgobW9kQml0cyAtIDEpIC8gOCkuCiAgICovCiAgcHNzb2JqLmVuY29kZSA9IGZ1bmN0aW9uKG1kLCBtb2RCaXRzKSB7CiAgICB2YXIgaTsKICAgIHZhciBlbUJpdHMgPSBtb2RCaXRzIC0gMTsKICAgIHZhciBlbUxlbiA9IE1hdGguY2VpbChlbUJpdHMgLyA4KTsKCiAgICAvKiAyLiBMZXQgbUhhc2ggPSBIYXNoKE0pLCBhbiBvY3RldCBzdHJpbmcgb2YgbGVuZ3RoIGhMZW4uICovCiAgICB2YXIgbUhhc2ggPSBtZC5kaWdlc3QoKS5nZXRCeXRlcygpOwoKICAgIC8qIDMuIElmIGVtTGVuIDwgaExlbiArIHNMZW4gKyAyLCBvdXRwdXQgImVuY29kaW5nIGVycm9yIiBhbmQgc3RvcC4gKi8KICAgIGlmKGVtTGVuIDwgaExlbiArIHNMZW4gKyAyKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignTWVzc2FnZSBpcyB0b28gbG9uZyB0byBlbmNyeXB0LicpOwogICAgfQoKICAgIC8qIDQuIEdlbmVyYXRlIGEgcmFuZG9tIG9jdGV0IHN0cmluZyBzYWx0IG9mIGxlbmd0aCBzTGVuOyBpZiBzTGVuID0gMCwKICAgICAqICAgIHRoZW4gc2FsdCBpcyB0aGUgZW1wdHkgc3RyaW5nLiAqLwogICAgdmFyIHNhbHQ7CiAgICBpZihzYWx0XyA9PT0gbnVsbCkgewogICAgICBzYWx0ID0gcHJuZy5nZXRCeXRlc1N5bmMoc0xlbik7CiAgICB9IGVsc2UgewogICAgICBzYWx0ID0gc2FsdF8uYnl0ZXMoKTsKICAgIH0KCiAgICAvKiA1LiBMZXQgTScgPSAoMHgpMDAgMDAgMDAgMDAgMDAgMDAgMDAgMDAgfHwgbUhhc2ggfHwgc2FsdDsgKi8KICAgIHZhciBtXyA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICAgIG1fLmZpbGxXaXRoQnl0ZSgwLCA4KTsKICAgIG1fLnB1dEJ5dGVzKG1IYXNoKTsKICAgIG1fLnB1dEJ5dGVzKHNhbHQpOwoKICAgIC8qIDYuIExldCBIID0gSGFzaChNJyksIGFuIG9jdGV0IHN0cmluZyBvZiBsZW5ndGggaExlbi4gKi8KICAgIGhhc2guc3RhcnQoKTsKICAgIGhhc2gudXBkYXRlKG1fLmdldEJ5dGVzKCkpOwogICAgdmFyIGggPSBoYXNoLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CgogICAgLyogNy4gR2VuZXJhdGUgYW4gb2N0ZXQgc3RyaW5nIFBTIGNvbnNpc3Rpbmcgb2YgZW1MZW4gLSBzTGVuIC0gaExlbiAtIDIKICAgICAqICAgIHplcm8gb2N0ZXRzLiAgVGhlIGxlbmd0aCBvZiBQUyBtYXkgYmUgMC4gKi8KICAgIHZhciBwcyA9IG5ldyBmb3JnZS51dGlsLkJ5dGVCdWZmZXIoKTsKICAgIHBzLmZpbGxXaXRoQnl0ZSgwLCBlbUxlbiAtIHNMZW4gLSBoTGVuIC0gMik7CgogICAgLyogOC4gTGV0IERCID0gUFMgfHwgMHgwMSB8fCBzYWx0OyBEQiBpcyBhbiBvY3RldCBzdHJpbmcgb2YgbGVuZ3RoCiAgICAgKiAgICBlbUxlbiAtIGhMZW4gLSAxLiAqLwogICAgcHMucHV0Qnl0ZSgweDAxKTsKICAgIHBzLnB1dEJ5dGVzKHNhbHQpOwogICAgdmFyIGRiID0gcHMuZ2V0Qnl0ZXMoKTsKCiAgICAvKiA5LiBMZXQgZGJNYXNrID0gTUdGKEgsIGVtTGVuIC0gaExlbiAtIDEpLiAqLwogICAgdmFyIG1hc2tMZW4gPSBlbUxlbiAtIGhMZW4gLSAxOwogICAgdmFyIGRiTWFzayA9IG1nZi5nZW5lcmF0ZShoLCBtYXNrTGVuKTsKCiAgICAvKiAxMC4gTGV0IG1hc2tlZERCID0gREIgXHhvciBkYk1hc2suICovCiAgICB2YXIgbWFza2VkREIgPSAnJzsKICAgIGZvcihpID0gMDsgaSA8IG1hc2tMZW47IGkgKyspIHsKICAgICAgbWFza2VkREIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShkYi5jaGFyQ29kZUF0KGkpIF4gZGJNYXNrLmNoYXJDb2RlQXQoaSkpOwogICAgfQoKICAgIC8qIDExLiBTZXQgdGhlIGxlZnRtb3N0IDhlbUxlbiAtIGVtQml0cyBiaXRzIG9mIHRoZSBsZWZ0bW9zdCBvY3RldCBpbgogICAgICogICAgIG1hc2tlZERCIHRvIHplcm8uICovCiAgICB2YXIgbWFzayA9ICgweEZGMDAgPj4gKDggKiBlbUxlbiAtIGVtQml0cykpICYgMHhGRjsKICAgIG1hc2tlZERCID0gU3RyaW5nLmZyb21DaGFyQ29kZShtYXNrZWREQi5jaGFyQ29kZUF0KDApICYgfm1hc2spICsKICAgICAgbWFza2VkREIuc3Vic3RyKDEpOwoKICAgIC8qIDEyLiBMZXQgRU0gPSBtYXNrZWREQiB8fCBIIHx8IDB4YmMuCiAgICAgKiAxMy4gT3V0cHV0IEVNLiAqLwogICAgcmV0dXJuIG1hc2tlZERCICsgaCArIFN0cmluZy5mcm9tQ2hhckNvZGUoMHhiYyk7CiAgfTsKCiAgLyoqCiAgICogVmVyaWZpZXMgYSBQU1Mgc2lnbmF0dXJlLgogICAqCiAgICogVGhpcyBmdW5jdGlvbiBpbXBsZW1lbnRzIEVNU0EtUFNTLVZFUklGWSBhcyBwZXIgUkZDIDM0NDcsIHNlY3Rpb24gOS4xLjIuCiAgICoKICAgKiBAcGFyYW0gbUhhc2ggdGhlIG1lc3NhZ2UgZGlnZXN0IGhhc2gsIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nLCB0bwogICAqICAgICAgICAgY29tcGFyZSBhZ2FpbnN0IHRoZSBzaWduYXR1cmUuCiAgICogQHBhcmFtIGVtIHRoZSBlbmNvZGVkIG1lc3NhZ2UsIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nCiAgICogICAgICAgICAgKFJTQSBkZWNyeXB0aW9uIHJlc3VsdCkuCiAgICogQHBhcmFtIG1vZHNCaXRzIHRoZSBsZW5ndGggb2YgdGhlIFJTQSBtb2R1bHVzIGluIGJpdHMuCiAgICoKICAgKiBAcmV0dXJuIHRydWUgaWYgdGhlIHNpZ25hdHVyZSB3YXMgdmVyaWZpZWQsIGZhbHNlIGlmIG5vdC4KICAgKi8KICBwc3NvYmoudmVyaWZ5ID0gZnVuY3Rpb24obUhhc2gsIGVtLCBtb2RCaXRzKSB7CiAgICB2YXIgaTsKICAgIHZhciBlbUJpdHMgPSBtb2RCaXRzIC0gMTsKICAgIHZhciBlbUxlbiA9IE1hdGguY2VpbChlbUJpdHMgLyA4KTsKCiAgICAvKiBjLiBDb252ZXJ0IHRoZSBtZXNzYWdlIHJlcHJlc2VudGF0aXZlIG0gdG8gYW4gZW5jb2RlZCBtZXNzYWdlIEVNCiAgICAgKiAgICBvZiBsZW5ndGggZW1MZW4gPSBjZWlsKChtb2RCaXRzIC0gMSkgLyA4KSBvY3RldHMsIHdoZXJlIG1vZEJpdHMKICAgICAqICAgIGlzIHRoZSBsZW5ndGggaW4gYml0cyBvZiB0aGUgUlNBIG1vZHVsdXMgbiAqLwogICAgZW0gPSBlbS5zdWJzdHIoLWVtTGVuKTsKCiAgICAvKiAzLiBJZiBlbUxlbiA8IGhMZW4gKyBzTGVuICsgMiwgb3V0cHV0ICJpbmNvbnNpc3RlbnQiIGFuZCBzdG9wLiAqLwogICAgaWYoZW1MZW4gPCBoTGVuICsgc0xlbiArIDIpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbmNvbnNpc3RlbnQgcGFyYW1ldGVycyB0byBQU1Mgc2lnbmF0dXJlIHZlcmlmaWNhdGlvbi4nKTsKICAgIH0KCiAgICAvKiA0LiBJZiB0aGUgcmlnaHRtb3N0IG9jdGV0IG9mIEVNIGRvZXMgbm90IGhhdmUgaGV4YWRlY2ltYWwgdmFsdWUKICAgICAqICAgIDB4YmMsIG91dHB1dCAiaW5jb25zaXN0ZW50IiBhbmQgc3RvcC4gKi8KICAgIGlmKGVtLmNoYXJDb2RlQXQoZW1MZW4gLSAxKSAhPT0gMHhiYykgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ0VuY29kZWQgbWVzc2FnZSBkb2VzIG5vdCBlbmQgaW4gMHhCQy4nKTsKICAgIH0KCiAgICAvKiA1LiBMZXQgbWFza2VkREIgYmUgdGhlIGxlZnRtb3N0IGVtTGVuIC0gaExlbiAtIDEgb2N0ZXRzIG9mIEVNLCBhbmQKICAgICAqICAgIGxldCBIIGJlIHRoZSBuZXh0IGhMZW4gb2N0ZXRzLiAqLwogICAgdmFyIG1hc2tMZW4gPSBlbUxlbiAtIGhMZW4gLSAxOwogICAgdmFyIG1hc2tlZERCID0gZW0uc3Vic3RyKDAsIG1hc2tMZW4pOwogICAgdmFyIGggPSBlbS5zdWJzdHIobWFza0xlbiwgaExlbik7CgogICAgLyogNi4gSWYgdGhlIGxlZnRtb3N0IDhlbUxlbiAtIGVtQml0cyBiaXRzIG9mIHRoZSBsZWZ0bW9zdCBvY3RldCBpbgogICAgICogICAgbWFza2VkREIgYXJlIG5vdCBhbGwgZXF1YWwgdG8gemVybywgb3V0cHV0ICJpbmNvbnNpc3RlbnQiIGFuZCBzdG9wLiAqLwogICAgdmFyIG1hc2sgPSAoMHhGRjAwID4+ICg4ICogZW1MZW4gLSBlbUJpdHMpKSAmIDB4RkY7CiAgICBpZigobWFza2VkREIuY2hhckNvZGVBdCgwKSAmIG1hc2spICE9PSAwKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignQml0cyBiZXlvbmQga2V5c2l6ZSBub3QgemVybyBhcyBleHBlY3RlZC4nKTsKICAgIH0KCiAgICAvKiA3LiBMZXQgZGJNYXNrID0gTUdGKEgsIGVtTGVuIC0gaExlbiAtIDEpLiAqLwogICAgdmFyIGRiTWFzayA9IG1nZi5nZW5lcmF0ZShoLCBtYXNrTGVuKTsKCiAgICAvKiA4LiBMZXQgREIgPSBtYXNrZWREQiBceG9yIGRiTWFzay4gKi8KICAgIHZhciBkYiA9ICcnOwogICAgZm9yKGkgPSAwOyBpIDwgbWFza0xlbjsgaSArKykgewogICAgICBkYiArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKG1hc2tlZERCLmNoYXJDb2RlQXQoaSkgXiBkYk1hc2suY2hhckNvZGVBdChpKSk7CiAgICB9CgogICAgLyogOS4gU2V0IHRoZSBsZWZ0bW9zdCA4ZW1MZW4gLSBlbUJpdHMgYml0cyBvZiB0aGUgbGVmdG1vc3Qgb2N0ZXQKICAgICAqIGluIERCIHRvIHplcm8uICovCiAgICBkYiA9IFN0cmluZy5mcm9tQ2hhckNvZGUoZGIuY2hhckNvZGVBdCgwKSAmIH5tYXNrKSArIGRiLnN1YnN0cigxKTsKCiAgICAvKiAxMC4gSWYgdGhlIGVtTGVuIC0gaExlbiAtIHNMZW4gLSAyIGxlZnRtb3N0IG9jdGV0cyBvZiBEQiBhcmUgbm90IHplcm8KICAgICAqIG9yIGlmIHRoZSBvY3RldCBhdCBwb3NpdGlvbiBlbUxlbiAtIGhMZW4gLSBzTGVuIC0gMSAodGhlIGxlZnRtb3N0CiAgICAgKiBwb3NpdGlvbiBpcyAicG9zaXRpb24gMSIpIGRvZXMgbm90IGhhdmUgaGV4YWRlY2ltYWwgdmFsdWUgMHgwMSwKICAgICAqIG91dHB1dCAiaW5jb25zaXN0ZW50IiBhbmQgc3RvcC4gKi8KICAgIHZhciBjaGVja0xlbiA9IGVtTGVuIC0gaExlbiAtIHNMZW4gLSAyOwogICAgZm9yKGkgPSAwOyBpIDwgY2hlY2tMZW47IGkgKyspIHsKICAgICAgaWYoZGIuY2hhckNvZGVBdChpKSAhPT0gMHgwMCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcignTGVmdG1vc3Qgb2N0ZXRzIG5vdCB6ZXJvIGFzIGV4cGVjdGVkJyk7CiAgICAgIH0KICAgIH0KCiAgICBpZihkYi5jaGFyQ29kZUF0KGNoZWNrTGVuKSAhPT0gMHgwMSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ0luY29uc2lzdGVudCBQU1Mgc2lnbmF0dXJlLCAweDAxIG1hcmtlciBub3QgZm91bmQnKTsKICAgIH0KCiAgICAvKiAxMS4gTGV0IHNhbHQgYmUgdGhlIGxhc3Qgc0xlbiBvY3RldHMgb2YgREIuICovCiAgICB2YXIgc2FsdCA9IGRiLnN1YnN0cigtc0xlbik7CgogICAgLyogMTIuICBMZXQgTScgPSAoMHgpMDAgMDAgMDAgMDAgMDAgMDAgMDAgMDAgfHwgbUhhc2ggfHwgc2FsdCAqLwogICAgdmFyIG1fID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogICAgbV8uZmlsbFdpdGhCeXRlKDAsIDgpOwogICAgbV8ucHV0Qnl0ZXMobUhhc2gpOwogICAgbV8ucHV0Qnl0ZXMoc2FsdCk7CgogICAgLyogMTMuIExldCBIJyA9IEhhc2goTScpLCBhbiBvY3RldCBzdHJpbmcgb2YgbGVuZ3RoIGhMZW4uICovCiAgICBoYXNoLnN0YXJ0KCk7CiAgICBoYXNoLnVwZGF0ZShtXy5nZXRCeXRlcygpKTsKICAgIHZhciBoXyA9IGhhc2guZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKCiAgICAvKiAxNC4gSWYgSCA9IEgnLCBvdXRwdXQgImNvbnNpc3RlbnQuIiBPdGhlcndpc2UsIG91dHB1dCAiaW5jb25zaXN0ZW50LiIgKi8KICAgIHJldHVybiBoID09PSBoXzsKICB9OwoKICByZXR1cm4gcHNzb2JqOwp9OwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncHNzJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3BzcycsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL3JhbmRvbScsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBYLjUwOSBhbmQgcmVsYXRlZCBjb21wb25lbnRzIChzdWNoIGFzCiAqIENlcnRpZmljYXRpb24gU2lnbmluZyBSZXF1ZXN0cykgb2YgYSBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKgogKiBUaGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgYW4gWC41MDl2MyBjZXJ0aWZpY2F0ZSBpcyBhcyBmb2xsb3dzCiAqIChzZWUgUkZDIDI0NTkpOgogKgogKiBDZXJ0aWZpY2F0ZSA6Oj0gU0VRVUVOQ0UgewogKiAgIHRic0NlcnRpZmljYXRlICAgICAgIFRCU0NlcnRpZmljYXRlLAogKiAgIHNpZ25hdHVyZUFsZ29yaXRobSAgIEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgc2lnbmF0dXJlVmFsdWUgICAgICAgQklUIFNUUklORwogKiB9CiAqCiAqIFRCU0NlcnRpZmljYXRlIDo6PSBTRVFVRU5DRSB7CiAqICAgdmVyc2lvbiAgICAgICAgIFswXSAgRVhQTElDSVQgVmVyc2lvbiBERUZBVUxUIHYxLAogKiAgIHNlcmlhbE51bWJlciAgICAgICAgIENlcnRpZmljYXRlU2VyaWFsTnVtYmVyLAogKiAgIHNpZ25hdHVyZSAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgaXNzdWVyICAgICAgICAgICAgICAgTmFtZSwKICogICB2YWxpZGl0eSAgICAgICAgICAgICBWYWxpZGl0eSwKICogICBzdWJqZWN0ICAgICAgICAgICAgICBOYW1lLAogKiAgIHN1YmplY3RQdWJsaWNLZXlJbmZvIFN1YmplY3RQdWJsaWNLZXlJbmZvLAogKiAgIGlzc3VlclVuaXF1ZUlEICBbMV0gIElNUExJQ0lUIFVuaXF1ZUlkZW50aWZpZXIgT1BUSU9OQUwsCiAqICAgICAgICAgICAgICAgICAgICAgICAgLS0gSWYgcHJlc2VudCwgdmVyc2lvbiBzaGFsbCBiZSB2MiBvciB2MwogKiAgIHN1YmplY3RVbmlxdWVJRCBbMl0gIElNUExJQ0lUIFVuaXF1ZUlkZW50aWZpZXIgT1BUSU9OQUwsCiAqICAgICAgICAgICAgICAgICAgICAgICAgLS0gSWYgcHJlc2VudCwgdmVyc2lvbiBzaGFsbCBiZSB2MiBvciB2MwogKiAgIGV4dGVuc2lvbnMgICAgICBbM10gIEVYUExJQ0lUIEV4dGVuc2lvbnMgT1BUSU9OQUwKICogICAgICAgICAgICAgICAgICAgICAgICAtLSBJZiBwcmVzZW50LCB2ZXJzaW9uIHNoYWxsIGJlIHYzCiAqIH0KICoKICogVmVyc2lvbiA6Oj0gSU5URUdFUiAgeyB2MSgwKSwgdjIoMSksIHYzKDIpIH0KICoKICogQ2VydGlmaWNhdGVTZXJpYWxOdW1iZXIgOjo9IElOVEVHRVIKICoKICogTmFtZSA6Oj0gQ0hPSUNFIHsKICogICAvLyBvbmx5IG9uZSBwb3NzaWJsZSBjaG9pY2UgZm9yIG5vdwogKiAgIFJETlNlcXVlbmNlCiAqIH0KICoKICogUkROU2VxdWVuY2UgOjo9IFNFUVVFTkNFIE9GIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUKICoKICogUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZSA6Oj0gU0VUIE9GIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZQogKgogKiBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgOjo9IFNFUVVFTkNFIHsKICogICB0eXBlICAgICBBdHRyaWJ1dGVUeXBlLAogKiAgIHZhbHVlICAgIEF0dHJpYnV0ZVZhbHVlCiAqIH0KICogQXR0cmlidXRlVHlwZSA6Oj0gT0JKRUNUIElERU5USUZJRVIKICogQXR0cmlidXRlVmFsdWUgOjo9IEFOWSBERUZJTkVEIEJZIEF0dHJpYnV0ZVR5cGUKICoKICogVmFsaWRpdHkgOjo9IFNFUVVFTkNFIHsKICogICBub3RCZWZvcmUgICAgICBUaW1lLAogKiAgIG5vdEFmdGVyICAgICAgIFRpbWUKICogfQogKgogKiBUaW1lIDo6PSBDSE9JQ0UgewogKiAgIHV0Y1RpbWUgICAgICAgIFVUQ1RpbWUsCiAqICAgZ2VuZXJhbFRpbWUgICAgR2VuZXJhbGl6ZWRUaW1lCiAqIH0KICoKICogVW5pcXVlSWRlbnRpZmllciA6Oj0gQklUIFNUUklORwogKgogKiBTdWJqZWN0UHVibGljS2V5SW5mbyA6Oj0gU0VRVUVOQ0UgewogKiAgIGFsZ29yaXRobSAgICAgICAgICAgIEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgc3ViamVjdFB1YmxpY0tleSAgICAgQklUIFNUUklORwogKiB9CiAqCiAqIEV4dGVuc2lvbnMgOjo9IFNFUVVFTkNFIFNJWkUgKDEuLk1BWCkgT0YgRXh0ZW5zaW9uCiAqCiAqIEV4dGVuc2lvbiA6Oj0gU0VRVUVOQ0UgewogKiAgIGV4dG5JRCAgICAgIE9CSkVDVCBJREVOVElGSUVSLAogKiAgIGNyaXRpY2FsICAgIEJPT0xFQU4gREVGQVVMVCBGQUxTRSwKICogICBleHRuVmFsdWUgICBPQ1RFVCBTVFJJTkcKICogfQogKgogKiBUaGUgb25seSBrZXkgYWxnb3JpdGhtIGN1cnJlbnRseSBzdXBwb3J0ZWQgZm9yIFBLSSBpcyBSU0EuCiAqCiAqIFJTQVNTQS1QU1Mgc2lnbmF0dXJlcyBhcmUgZGVzY3JpYmVkIGluIFJGQyAzNDQ3IGFuZCBSRkMgNDA1NS4KICoKICogUEtDUyMxMCB2MS43IGRlc2NyaWJlcyBjZXJ0aWZpY2F0ZSBzaWduaW5nIHJlcXVlc3RzOgogKgogKiBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm86CiAqCiAqIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gICAgICAgSU5URUdFUiB7IHYxKDApIH0gKHYxLC4uLiksCiAqICAgc3ViamVjdCAgICAgICBOYW1lLAogKiAgIHN1YmplY3RQS0luZm8gU3ViamVjdFB1YmxpY0tleUluZm97eyBQS0luZm9BbGdvcml0aG1zIH19LAogKiAgIGF0dHJpYnV0ZXMgICAgWzBdIEF0dHJpYnV0ZXN7eyBDUklBdHRyaWJ1dGVzIH19CiAqIH0KICoKICogQXR0cmlidXRlcyB7IEFUVFJJQlVURTpJT1NldCB9IDo6PSBTRVQgT0YgQXR0cmlidXRle3sgSU9TZXQgfX0KICoKICogQ1JJQXR0cmlidXRlcyAgQVRUUklCVVRFICA6Oj0gewogKiAgIC4uLiAtLSBhZGQgYW55IGxvY2FsbHkgZGVmaW5lZCBhdHRyaWJ1dGVzIGhlcmUgLS0gfQogKgogKiBBdHRyaWJ1dGUgeyBBVFRSSUJVVEU6SU9TZXQgfSA6Oj0gU0VRVUVOQ0UgewogKiAgIHR5cGUgICBBVFRSSUJVVEUuJmlkKHtJT1NldH0pLAogKiAgIHZhbHVlcyBTRVQgU0laRSgxLi5NQVgpIE9GIEFUVFJJQlVURS4mVHlwZSh7SU9TZXR9e0B0eXBlfSkKICogfQogKgogKiBDZXJ0aWZpY2F0aW9uUmVxdWVzdCA6Oj0gU0VRVUVOQ0UgewogKiAgIGNlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8sCiAqICAgc2lnbmF0dXJlQWxnb3JpdGhtIEFsZ29yaXRobUlkZW50aWZpZXJ7eyBTaWduYXR1cmVBbGdvcml0aG1zIH19LAogKiAgIHNpZ25hdHVyZSAgICAgICAgICBCSVQgU1RSSU5HCiAqIH0KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBzaG9ydGN1dCBmb3IgYXNuLjEgQVBJCnZhciBhc24xID0gZm9yZ2UuYXNuMTsKCi8qIFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUgKFBLSSkgaW1wbGVtZW50YXRpb24uICovCnZhciBwa2kgPSBmb3JnZS5wa2kgPSBmb3JnZS5wa2kgfHwge307CnZhciBvaWRzID0gcGtpLm9pZHM7CgovLyBzaG9ydCBuYW1lIE9JRCBtYXBwaW5ncwp2YXIgX3Nob3J0TmFtZXMgPSB7fTsKX3Nob3J0TmFtZXNbJ0NOJ10gPSBvaWRzWydjb21tb25OYW1lJ107Cl9zaG9ydE5hbWVzWydjb21tb25OYW1lJ10gPSAnQ04nOwpfc2hvcnROYW1lc1snQyddID0gb2lkc1snY291bnRyeU5hbWUnXTsKX3Nob3J0TmFtZXNbJ2NvdW50cnlOYW1lJ10gPSAnQyc7Cl9zaG9ydE5hbWVzWydMJ10gPSBvaWRzWydsb2NhbGl0eU5hbWUnXTsKX3Nob3J0TmFtZXNbJ2xvY2FsaXR5TmFtZSddID0gJ0wnOwpfc2hvcnROYW1lc1snU1QnXSA9IG9pZHNbJ3N0YXRlT3JQcm92aW5jZU5hbWUnXTsKX3Nob3J0TmFtZXNbJ3N0YXRlT3JQcm92aW5jZU5hbWUnXSA9ICdTVCc7Cl9zaG9ydE5hbWVzWydPJ10gPSBvaWRzWydvcmdhbml6YXRpb25OYW1lJ107Cl9zaG9ydE5hbWVzWydvcmdhbml6YXRpb25OYW1lJ10gPSAnTyc7Cl9zaG9ydE5hbWVzWydPVSddID0gb2lkc1snb3JnYW5pemF0aW9uYWxVbml0TmFtZSddOwpfc2hvcnROYW1lc1snb3JnYW5pemF0aW9uYWxVbml0TmFtZSddID0gJ09VJzsKX3Nob3J0TmFtZXNbJ0UnXSA9IG9pZHNbJ2VtYWlsQWRkcmVzcyddOwpfc2hvcnROYW1lc1snZW1haWxBZGRyZXNzJ10gPSAnRSc7CgovLyB2YWxpZGF0b3IgZm9yIGFuIFN1YmplY3RQdWJsaWNLZXlJbmZvIHN0cnVjdHVyZQovLyBOb3RlOiBDdXJyZW50bHkgb25seSB3b3JrcyB3aXRoIGFuIFJTQSBwdWJsaWMga2V5CnZhciBwdWJsaWNLZXlWYWxpZGF0b3IgPSBmb3JnZS5wa2kucnNhLnB1YmxpY0tleVZhbGlkYXRvcjsKCi8vIHZhbGlkYXRvciBmb3IgYW4gWC41MDl2MyBjZXJ0aWZpY2F0ZQp2YXIgeDUwOUNlcnRpZmljYXRlVmFsaWRhdG9yID0gewogIG5hbWU6ICdDZXJ0aWZpY2F0ZScsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAndGJzQ2VydGlmaWNhdGUnLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS52ZXJzaW9uJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgICAgdHlwZTogMCwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUudmVyc2lvbi5pbnRlZ2VyJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICAgIGNhcHR1cmU6ICdjZXJ0VmVyc2lvbicKICAgICAgfV0KICAgIH0sIHsKICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnNlcmlhbE51bWJlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2NlcnRTZXJpYWxOdW1iZXInCiAgICB9LCB7CiAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS5zaWduYXR1cmUnLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIHZhbHVlOiBbewogICAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS5zaWduYXR1cmUuYWxnb3JpdGhtJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgICAgY2FwdHVyZTogJ2NlcnRpbmZvU2lnbmF0dXJlT2lkJwogICAgICB9LCB7CiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnNpZ25hdHVyZS5wYXJhbWV0ZXJzJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgICAgY2FwdHVyZUFzbjE6ICdjZXJ0aW5mb1NpZ25hdHVyZVBhcmFtcycKICAgICAgfV0KICAgIH0sIHsKICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLmlzc3VlcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgY2FwdHVyZUFzbjE6ICdjZXJ0SXNzdWVyJwogICAgfSwgewogICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUudmFsaWRpdHknLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIC8vIE5vdGU6IFVUQyBhbmQgZ2VuZXJhbGl6ZWQgdGltZXMgbWF5IGJvdGggYXBwZWFyIHNvIHRoZSBjYXB0dXJlCiAgICAgIC8vIG5hbWVzIGFyZSBiYXNlZCBvbiB0aGVpciBkZXRlY3RlZCBvcmRlciwgdGhlIG5hbWVzIHVzZWQgYmVsb3cKICAgICAgLy8gYXJlIG9ubHkgZm9yIHRoZSBjb21tb24gY2FzZSwgd2hpY2ggdmFsaWRpdHkgdGltZSByZWFsbHkgbWVhbnMKICAgICAgLy8gIm5vdEJlZm9yZSIgYW5kIHdoaWNoIG1lYW5zICJub3RBZnRlciIgd2lsbCBiZSBkZXRlcm1pbmVkIGJ5IG9yZGVyCiAgICAgIHZhbHVlOiBbewogICAgICAgIC8vIG5vdEJlZm9yZSAoVGltZSkgKFVUQyB0aW1lIGNhc2UpCiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnZhbGlkaXR5Lm5vdEJlZm9yZSAodXRjKScsCiAgICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICAgIHR5cGU6IGFzbjEuVHlwZS5VVENUSU1FLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBvcHRpb25hbDogdHJ1ZSwKICAgICAgICBjYXB0dXJlOiAnY2VydFZhbGlkaXR5MVVUQ1RpbWUnCiAgICAgIH0sIHsKICAgICAgICAvLyBub3RCZWZvcmUgKFRpbWUpIChnZW5lcmFsaXplZCB0aW1lIGNhc2UpCiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnZhbGlkaXR5Lm5vdEJlZm9yZSAoZ2VuZXJhbGl6ZWQpJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLkdFTkVSQUxJWkVEVElNRSwKICAgICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgICAgY2FwdHVyZTogJ2NlcnRWYWxpZGl0eTJHZW5lcmFsaXplZFRpbWUnCiAgICAgIH0sIHsKICAgICAgICAvLyBub3RBZnRlciAoVGltZSkgKG9ubHkgVVRDIHRpbWUgaXMgc3VwcG9ydGVkKQogICAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS52YWxpZGl0eS5ub3RBZnRlciAodXRjKScsCiAgICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICAgIHR5cGU6IGFzbjEuVHlwZS5VVENUSU1FLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBvcHRpb25hbDogdHJ1ZSwKICAgICAgICBjYXB0dXJlOiAnY2VydFZhbGlkaXR5M1VUQ1RpbWUnCiAgICAgIH0sIHsKICAgICAgICAvLyBub3RBZnRlciAoVGltZSkgKG9ubHkgVVRDIHRpbWUgaXMgc3VwcG9ydGVkKQogICAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5UQlNDZXJ0aWZpY2F0ZS52YWxpZGl0eS5ub3RBZnRlciAoZ2VuZXJhbGl6ZWQpJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLkdFTkVSQUxJWkVEVElNRSwKICAgICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgICAgY2FwdHVyZTogJ2NlcnRWYWxpZGl0eTRHZW5lcmFsaXplZFRpbWUnCiAgICAgIH1dCiAgICB9LCB7CiAgICAgIC8vIE5hbWUgKHN1YmplY3QpIChSRE5TZXF1ZW5jZSkKICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLnN1YmplY3QnLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIGNhcHR1cmVBc24xOiAnY2VydFN1YmplY3QnCiAgICB9LAogICAgICAvLyBTdWJqZWN0UHVibGljS2V5SW5mbwogICAgICBwdWJsaWNLZXlWYWxpZGF0b3IsCiAgICB7CiAgICAgIC8vIGlzc3VlclVuaXF1ZUlEIChvcHRpb25hbCkKICAgICAgbmFtZTogJ0NlcnRpZmljYXRlLlRCU0NlcnRpZmljYXRlLmlzc3VlclVuaXF1ZUlEJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgICAgdHlwZTogMSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuaXNzdWVyVW5pcXVlSUQuaWQnLAogICAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgICB0eXBlOiBhc24xLlR5cGUuQklUU1RSSU5HLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBjYXB0dXJlOiAnY2VydElzc3VlclVuaXF1ZUlkJwogICAgICB9XQogICAgfSwgewogICAgICAvLyBzdWJqZWN0VW5pcXVlSUQgKG9wdGlvbmFsKQogICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuc3ViamVjdFVuaXF1ZUlEJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgICAgdHlwZTogMiwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuc3ViamVjdFVuaXF1ZUlELmlkJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLkJJVFNUUklORywKICAgICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgICAgY2FwdHVyZTogJ2NlcnRTdWJqZWN0VW5pcXVlSWQnCiAgICAgIH1dCiAgICB9LCB7CiAgICAgIC8vIEV4dGVuc2lvbnMgKG9wdGlvbmFsKQogICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuZXh0ZW5zaW9ucycsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICAgIHR5cGU6IDMsCiAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ2NlcnRFeHRlbnNpb25zJywKICAgICAgb3B0aW9uYWw6IHRydWUKICAgIH1dCiAgfSwgewogICAgLy8gQWxnb3JpdGhtSWRlbnRpZmllciAoc2lnbmF0dXJlIGFsZ29yaXRobSkKICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5zaWduYXR1cmVBbGdvcml0aG0nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICB2YWx1ZTogW3sKICAgICAgLy8gYWxnb3JpdGhtCiAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0ZS5zaWduYXR1cmVBbGdvcml0aG0uYWxnb3JpdGhtJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdjZXJ0U2lnbmF0dXJlT2lkJwogICAgfSwgewogICAgICBuYW1lOiAnQ2VydGlmaWNhdGUuVEJTQ2VydGlmaWNhdGUuc2lnbmF0dXJlLnBhcmFtZXRlcnMnLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICBjYXB0dXJlQXNuMTogJ2NlcnRTaWduYXR1cmVQYXJhbXMnCiAgICB9XQogIH0sIHsKICAgIC8vIFNpZ25hdHVyZVZhbHVlCiAgICBuYW1lOiAnQ2VydGlmaWNhdGUuc2lnbmF0dXJlVmFsdWUnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLkJJVFNUUklORywKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdjZXJ0U2lnbmF0dXJlJwogIH1dCn07Cgp2YXIgcnNhc3NhUHNzUGFyYW1ldGVyVmFsaWRhdG9yID0gewogIG5hbWU6ICdyc2Fwc3MnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAncnNhcHNzLmhhc2hBbGdvcml0aG0nLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgIHR5cGU6IDAsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAncnNhcHNzLmhhc2hBbGdvcml0aG0uQWxnb3JpdGhtSWRlbnRpZmllcicsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5DbGFzcy5TRVFVRU5DRSwKICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgIG9wdGlvbmFsOiB0cnVlLAogICAgICB2YWx1ZTogW3sKICAgICAgICBuYW1lOiAncnNhcHNzLmhhc2hBbGdvcml0aG0uQWxnb3JpdGhtSWRlbnRpZmllci5hbGdvcml0aG0nLAogICAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBjYXB0dXJlOiAnaGFzaE9pZCcKICAgICAgICAvKiBwYXJhbWV0ZXIgYmxvY2sgb21pdHRlZCwgZm9yIFNIQTEgTlVMTCBhbnlob3cuICovCiAgICAgIH1dCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdyc2Fwc3MubWFza0dlbkFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLAogICAgdHlwZTogMSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdyc2Fwc3MubWFza0dlbkFsZ29yaXRobS5BbGdvcml0aG1JZGVudGlmaWVyJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLkNsYXNzLlNFUVVFTkNFLAogICAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgIHZhbHVlOiBbewogICAgICAgIG5hbWU6ICdyc2Fwc3MubWFza0dlbkFsZ29yaXRobS5BbGdvcml0aG1JZGVudGlmaWVyLmFsZ29yaXRobScsCiAgICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICAgIGNhcHR1cmU6ICdtYXNrR2VuT2lkJwogICAgICB9LCB7CiAgICAgICAgbmFtZTogJ3JzYXBzcy5tYXNrR2VuQWxnb3JpdGhtLkFsZ29yaXRobUlkZW50aWZpZXIucGFyYW1zJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgICAgIHZhbHVlOiBbewogICAgICAgICAgbmFtZTogJ3JzYXBzcy5tYXNrR2VuQWxnb3JpdGhtLkFsZ29yaXRobUlkZW50aWZpZXIucGFyYW1zLmFsZ29yaXRobScsCiAgICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICAgICAgY2FwdHVyZTogJ21hc2tHZW5IYXNoT2lkJwogICAgICAgICAgLyogcGFyYW1ldGVyIGJsb2NrIG9taXR0ZWQsIGZvciBTSEExIE5VTEwgYW55aG93LiAqLwogICAgICAgIH1dCiAgICAgIH1dCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdyc2Fwc3Muc2FsdExlbmd0aCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLAogICAgdHlwZTogMiwKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdyc2Fwc3Muc2FsdExlbmd0aC5zYWx0TGVuZ3RoJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICB0eXBlOiBhc24xLkNsYXNzLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ3NhbHRMZW5ndGgnCiAgICB9XQogIH0sIHsKICAgIG5hbWU6ICdyc2Fwc3MudHJhaWxlckZpZWxkJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICB0eXBlOiAzLAogICAgb3B0aW9uYWw6IHRydWUsCiAgICB2YWx1ZTogW3sKICAgICAgbmFtZTogJ3JzYXBzcy50cmFpbGVyLnRyYWlsZXInLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuQ2xhc3MuSU5URUdFUiwKICAgICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgICBjYXB0dXJlOiAndHJhaWxlcicKICAgIH1dCiAgfV0KfTsKCi8vIHZhbGlkYXRvciBmb3IgYSBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8gc3RydWN0dXJlCnZhciBjZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm9WYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0SW5mbycsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICBjYXB0dXJlQXNuMTogJ2NlcnRpZmljYXRpb25SZXF1ZXN0SW5mbycsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLmludGVnZXInLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICBjYXB0dXJlOiAnY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvVmVyc2lvbicKICB9LCB7CiAgICAvLyBOYW1lIChzdWJqZWN0KSAoUkROU2VxdWVuY2UpCiAgICBuYW1lOiAnQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLnN1YmplY3QnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICBjYXB0dXJlQXNuMTogJ2NlcnRpZmljYXRpb25SZXF1ZXN0SW5mb1N1YmplY3QnCiAgfSwKICAvLyBTdWJqZWN0UHVibGljS2V5SW5mbwogIHB1YmxpY0tleVZhbGlkYXRvciwKICB7CiAgICBuYW1lOiAnQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLmF0dHJpYnV0ZXMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywKICAgIHR5cGU6IDAsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIG9wdGlvbmFsOiB0cnVlLAogICAgY2FwdHVyZTogJ2NlcnRpZmljYXRpb25SZXF1ZXN0SW5mb0F0dHJpYnV0ZXMnLAogICAgdmFsdWU6IFt7CiAgICAgIG5hbWU6ICdDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8uYXR0cmlidXRlcycsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogICAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgdmFsdWU6IFt7CiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0SW5mby5hdHRyaWJ1dGVzLnR5cGUnLAogICAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZQogICAgICB9LCB7CiAgICAgICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0SW5mby5hdHRyaWJ1dGVzLnZhbHVlJywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLlNFVCwKICAgICAgICBjb25zdHJ1Y3RlZDogdHJ1ZQogICAgICB9XQogICAgfV0KICB9XQp9OwoKLy8gdmFsaWRhdG9yIGZvciBhIENlcnRpZmljYXRpb25SZXF1ZXN0IHN0cnVjdHVyZQp2YXIgY2VydGlmaWNhdGlvblJlcXVlc3RWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0JywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIGNhcHR1cmVBc24xOiAnY3NyJywKICB2YWx1ZTogWwogICAgY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvVmFsaWRhdG9yLCB7CiAgICAvLyBBbGdvcml0aG1JZGVudGlmaWVyIChzaWduYXR1cmUgYWxnb3JpdGhtKQogICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0LnNpZ25hdHVyZUFsZ29yaXRobScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIHZhbHVlOiBbewogICAgICAvLyBhbGdvcml0aG0KICAgICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0LnNpZ25hdHVyZUFsZ29yaXRobS5hbGdvcml0aG0nLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuVHlwZS5PSUQsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2NzclNpZ25hdHVyZU9pZCcKICAgIH0sIHsKICAgICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0LnNpZ25hdHVyZUFsZ29yaXRobS5wYXJhbWV0ZXJzJywKICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICBvcHRpb25hbDogdHJ1ZSwKICAgICAgY2FwdHVyZUFzbjE6ICdjc3JTaWduYXR1cmVQYXJhbXMnCiAgICB9XQogIH0sIHsKICAgIC8vIHNpZ25hdHVyZQogICAgbmFtZTogJ0NlcnRpZmljYXRpb25SZXF1ZXN0LnNpZ25hdHVyZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuQklUU1RSSU5HLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2NzclNpZ25hdHVyZScKICB9XQp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFJETlNlcXVlbmNlIG9mIEFTTi4xIERFUi1lbmNvZGVkIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUKICogc2V0cyBpbnRvIGFuIGFycmF5IHdpdGggb2JqZWN0cyB0aGF0IGhhdmUgdHlwZSBhbmQgdmFsdWUgcHJvcGVydGllcy4KICoKICogQHBhcmFtIHJkbiB0aGUgUkROU2VxdWVuY2UgdG8gY29udmVydC4KICogQHBhcmFtIG1kIGEgbWVzc2FnZSBkaWdlc3QgdG8gYXBwZW5kIHR5cGUgYW5kIHZhbHVlIHRvIGlmIHByb3ZpZGVkLgogKi8KcGtpLlJETkF0dHJpYnV0ZXNBc0FycmF5ID0gZnVuY3Rpb24ocmRuLCBtZCkgewogIHZhciBydmFsID0gW107CgogIC8vIGVhY2ggdmFsdWUgaW4gJ3JkbicgaW4gaXMgYSBTRVQgb2YgUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZQogIHZhciBzZXQsIGF0dHIsIG9iajsKICBmb3IodmFyIHNpID0gMDsgc2kgPCByZG4udmFsdWUubGVuZ3RoOyArK3NpKSB7CiAgICAvLyBnZXQgdGhlIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUgc2V0CiAgICBzZXQgPSByZG4udmFsdWVbc2ldOwoKICAgIC8vIGVhY2ggdmFsdWUgaW4gdGhlIFNFVCBpcyBhbiBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgc2VxdWVuY2UKICAgIC8vIGNvbnRhaW5pbmcgZmlyc3QgYSB0eXBlIChhbiBPSUQpIGFuZCBzZWNvbmQgYSB2YWx1ZSAoZGVmaW5lZCBieQogICAgLy8gdGhlIE9JRCkKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBzZXQudmFsdWUubGVuZ3RoOyArK2kpIHsKICAgICAgb2JqID0ge307CiAgICAgIGF0dHIgPSBzZXQudmFsdWVbaV07CiAgICAgIG9iai50eXBlID0gYXNuMS5kZXJUb09pZChhdHRyLnZhbHVlWzBdLnZhbHVlKTsKICAgICAgb2JqLnZhbHVlID0gYXR0ci52YWx1ZVsxXS52YWx1ZTsKICAgICAgb2JqLnZhbHVlVGFnQ2xhc3MgPSBhdHRyLnZhbHVlWzFdLnR5cGU7CiAgICAgIC8vIGlmIHRoZSBPSUQgaXMga25vd24sIGdldCBpdHMgbmFtZSBhbmQgc2hvcnQgbmFtZQogICAgICBpZihvYmoudHlwZSBpbiBvaWRzKSB7CiAgICAgICAgb2JqLm5hbWUgPSBvaWRzW29iai50eXBlXTsKICAgICAgICBpZihvYmoubmFtZSBpbiBfc2hvcnROYW1lcykgewogICAgICAgICAgb2JqLnNob3J0TmFtZSA9IF9zaG9ydE5hbWVzW29iai5uYW1lXTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYobWQpIHsKICAgICAgICBtZC51cGRhdGUob2JqLnR5cGUpOwogICAgICAgIG1kLnVwZGF0ZShvYmoudmFsdWUpOwogICAgICB9CiAgICAgIHJ2YWwucHVzaChvYmopOwogICAgfQogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ29udmVydHMgQVNOLjEgQ1JJQXR0cmlidXRlcyBpbnRvIGFuIGFycmF5IHdpdGggb2JqZWN0cyB0aGF0IGhhdmUgdHlwZSBhbmQKICogdmFsdWUgcHJvcGVydGllcy4KICoKICogQHBhcmFtIGF0dHJpYnV0ZXMgdGhlIENSSUF0dHJpYnV0ZXMgdG8gY29udmVydC4KICovCnBraS5DUklBdHRyaWJ1dGVzQXNBcnJheSA9IGZ1bmN0aW9uKGF0dHJpYnV0ZXMpIHsKICB2YXIgcnZhbCA9IFtdOwoKICAvLyBlYWNoIHZhbHVlIGluICdhdHRyaWJ1dGVzJyBpbiBpcyBhIFNFUVVFTkNFIHdpdGggYW4gT0lEIGFuZCBhIFNFVAogIGZvcih2YXIgc2kgPSAwOyBzaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyArK3NpKSB7CiAgICAvLyBnZXQgdGhlIGF0dHJpYnV0ZSBzZXF1ZW5jZQogICAgdmFyIHNlcSA9IGF0dHJpYnV0ZXNbc2ldOwoKICAgIC8vIGVhY2ggdmFsdWUgaW4gdGhlIFNFUVVFTkNFIGNvbnRhaW5pbmcgZmlyc3QgYSB0eXBlIChhbiBPSUQpIGFuZAogICAgLy8gc2Vjb25kIGEgc2V0IG9mIHZhbHVlcyAoZGVmaW5lZCBieSB0aGUgT0lEKQogICAgdmFyIHR5cGUgPSBhc24xLmRlclRvT2lkKHNlcS52YWx1ZVswXS52YWx1ZSk7CiAgICB2YXIgdmFsdWVzID0gc2VxLnZhbHVlWzFdLnZhbHVlOwogICAgZm9yKHZhciB2aSA9IDA7IHZpIDwgdmFsdWVzLmxlbmd0aDsgKyt2aSkgewogICAgICB2YXIgb2JqID0ge307CiAgICAgIG9iai50eXBlID0gdHlwZTsKICAgICAgb2JqLnZhbHVlID0gdmFsdWVzW3ZpXS52YWx1ZTsKICAgICAgb2JqLnZhbHVlVGFnQ2xhc3MgPSB2YWx1ZXNbdmldLnR5cGU7CiAgICAgIC8vIGlmIHRoZSBPSUQgaXMga25vd24sIGdldCBpdHMgbmFtZSBhbmQgc2hvcnQgbmFtZQogICAgICBpZihvYmoudHlwZSBpbiBvaWRzKSB7CiAgICAgICAgb2JqLm5hbWUgPSBvaWRzW29iai50eXBlXTsKICAgICAgICBpZihvYmoubmFtZSBpbiBfc2hvcnROYW1lcykgewogICAgICAgICAgb2JqLnNob3J0TmFtZSA9IF9zaG9ydE5hbWVzW29iai5uYW1lXTsKICAgICAgICB9CiAgICAgIH0KICAgICAgLy8gcGFyc2UgZXh0ZW5zaW9ucwogICAgICBpZihvYmoudHlwZSA9PT0gb2lkcy5leHRlbnNpb25SZXF1ZXN0KSB7CiAgICAgICAgb2JqLmV4dGVuc2lvbnMgPSBbXTsKICAgICAgICBmb3IodmFyIGVpID0gMDsgZWkgPCBvYmoudmFsdWUubGVuZ3RoOyArK2VpKSB7CiAgICAgICAgICBvYmouZXh0ZW5zaW9ucy5wdXNoKHBraS5jZXJ0aWZpY2F0ZUV4dGVuc2lvbkZyb21Bc24xKG9iai52YWx1ZVtlaV0pKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcnZhbC5wdXNoKG9iaik7CiAgICB9CiAgfQoKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIGFuIGlzc3VlciBvciBzdWJqZWN0IGF0dHJpYnV0ZSBmcm9tIGl0cyBuYW1lLCB0eXBlLCBvciBzaG9ydCBuYW1lLgogKgogKiBAcGFyYW0gb2JqIHRoZSBpc3N1ZXIgb3Igc3ViamVjdCBvYmplY3QuCiAqIEBwYXJhbSBvcHRpb25zIGEgc2hvcnQgbmFtZSBzdHJpbmcgb3IgYW4gb2JqZWN0IHdpdGg6CiAqICAgICAgICAgIHNob3J0TmFtZSB0aGUgc2hvcnQgbmFtZSBmb3IgdGhlIGF0dHJpYnV0ZS4KICogICAgICAgICAgbmFtZSB0aGUgbmFtZSBmb3IgdGhlIGF0dHJpYnV0ZS4KICogICAgICAgICAgdHlwZSB0aGUgdHlwZSBmb3IgdGhlIGF0dHJpYnV0ZS4KICoKICogQHJldHVybiB0aGUgYXR0cmlidXRlLgogKi8KZnVuY3Rpb24gX2dldEF0dHJpYnV0ZShvYmosIG9wdGlvbnMpIHsKICBpZih0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHsKICAgIG9wdGlvbnMgPSB7c2hvcnROYW1lOiBvcHRpb25zfTsKICB9CgogIHZhciBydmFsID0gbnVsbDsKICB2YXIgYXR0cjsKICBmb3IodmFyIGkgPSAwOyBydmFsID09PSBudWxsICYmIGkgPCBvYmouYXR0cmlidXRlcy5sZW5ndGg7ICsraSkgewogICAgYXR0ciA9IG9iai5hdHRyaWJ1dGVzW2ldOwogICAgaWYob3B0aW9ucy50eXBlICYmIG9wdGlvbnMudHlwZSA9PT0gYXR0ci50eXBlKSB7CiAgICAgIHJ2YWwgPSBhdHRyOwogICAgfSBlbHNlIGlmKG9wdGlvbnMubmFtZSAmJiBvcHRpb25zLm5hbWUgPT09IGF0dHIubmFtZSkgewogICAgICBydmFsID0gYXR0cjsKICAgIH0gZWxzZSBpZihvcHRpb25zLnNob3J0TmFtZSAmJiBvcHRpb25zLnNob3J0TmFtZSA9PT0gYXR0ci5zaG9ydE5hbWUpIHsKICAgICAgcnZhbCA9IGF0dHI7CiAgICB9CiAgfQogIHJldHVybiBydmFsOwp9CgovKioKICogQ29udmVydHMgc2lnbmF0dXJlIHBhcmFtZXRlcnMgZnJvbSBBU04uMSBzdHJ1Y3R1cmUuCiAqCiAqIEN1cnJlbnRseSBvbmx5IFJTQVNTQS1QU1Mgc3VwcG9ydGVkLiAgVGhlIFBLQ1MjMSB2MS41IHNpZ25hdHVyZSBzY2hlbWUgaGFkCiAqIG5vIHBhcmFtZXRlcnMuCiAqCiAqIFJTQVNTQS1QU1MtcGFyYW1zICA6Oj0gIFNFUVVFTkNFICB7CiAqICAgaGFzaEFsZ29yaXRobSAgICAgIFswXSBIYXNoQWxnb3JpdGhtIERFRkFVTFQKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYTFJZGVudGlmaWVyLAogKiAgIG1hc2tHZW5BbGdvcml0aG0gICBbMV0gTWFza0dlbkFsZ29yaXRobSBERUZBVUxUCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZ2YxU0hBMUlkZW50aWZpZXIsCiAqICAgc2FsdExlbmd0aCAgICAgICAgIFsyXSBJTlRFR0VSIERFRkFVTFQgMjAsCiAqICAgdHJhaWxlckZpZWxkICAgICAgIFszXSBJTlRFR0VSIERFRkFVTFQgMQogKiB9CiAqCiAqIEhhc2hBbGdvcml0aG0gIDo6PSAgQWxnb3JpdGhtSWRlbnRpZmllcgogKgogKiBNYXNrR2VuQWxnb3JpdGhtICA6Oj0gIEFsZ29yaXRobUlkZW50aWZpZXIKICoKICogQWxnb3JpdGhtSWRlbnRpZmVyIDo6PSBTRVFVRU5DRSB7CiAqICAgYWxnb3JpdGhtIE9CSkVDVCBJREVOVElGSUVSLAogKiAgIHBhcmFtZXRlcnMgQU5ZIERFRklORUQgQlkgYWxnb3JpdGhtIE9QVElPTkFMCiAqIH0KICoKICogQHBhcmFtIG9pZCBUaGUgT0lEIHNwZWNpZnlpbmcgdGhlIHNpZ25hdHVyZSBhbGdvcml0aG0KICogQHBhcmFtIG9iaiBUaGUgQVNOLjEgc3RydWN0dXJlIGhvbGRpbmcgdGhlIHBhcmFtZXRlcnMKICogQHBhcmFtIGZpbGxEZWZhdWx0cyBXaGV0aGVyIHRvIHVzZSByZXR1cm4gZGVmYXVsdCB2YWx1ZXMgd2hlcmUgb21pdHRlZAogKiBAcmV0dXJuIHNpZ25hdHVyZSBwYXJhbWV0ZXIgb2JqZWN0CiAqLwp2YXIgX3JlYWRTaWduYXR1cmVQYXJhbWV0ZXJzID0gZnVuY3Rpb24ob2lkLCBvYmosIGZpbGxEZWZhdWx0cykgewogIHZhciBwYXJhbXMgPSB7fTsKCiAgaWYob2lkICE9PSBvaWRzWydSU0FTU0EtUFNTJ10pIHsKICAgIHJldHVybiBwYXJhbXM7CiAgfQoKICBpZihmaWxsRGVmYXVsdHMpIHsKICAgIHBhcmFtcyA9IHsKICAgICAgaGFzaDogewogICAgICAgIGFsZ29yaXRobU9pZDogb2lkc1snc2hhMSddCiAgICAgIH0sCiAgICAgIG1nZjogewogICAgICAgIGFsZ29yaXRobU9pZDogb2lkc1snbWdmMSddLAogICAgICAgIGhhc2g6IHsKICAgICAgICAgIGFsZ29yaXRobU9pZDogb2lkc1snc2hhMSddCiAgICAgICAgfQogICAgICB9LAogICAgICBzYWx0TGVuZ3RoOiAyMAogICAgfTsKICB9CgogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgcnNhc3NhUHNzUGFyYW1ldGVyVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFJTQVNTQS1QU1MgcGFyYW1ldGVyIGJsb2NrLicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3JzOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICBpZihjYXB0dXJlLmhhc2hPaWQgIT09IHVuZGVmaW5lZCkgewogICAgcGFyYW1zLmhhc2ggPSBwYXJhbXMuaGFzaCB8fCB7fTsKICAgIHBhcmFtcy5oYXNoLmFsZ29yaXRobU9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5oYXNoT2lkKTsKICB9CgogIGlmKGNhcHR1cmUubWFza0dlbk9pZCAhPT0gdW5kZWZpbmVkKSB7CiAgICBwYXJhbXMubWdmID0gcGFyYW1zLm1nZiB8fCB7fTsKICAgIHBhcmFtcy5tZ2YuYWxnb3JpdGhtT2lkID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLm1hc2tHZW5PaWQpOwogICAgcGFyYW1zLm1nZi5oYXNoID0gcGFyYW1zLm1nZi5oYXNoIHx8IHt9OwogICAgcGFyYW1zLm1nZi5oYXNoLmFsZ29yaXRobU9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5tYXNrR2VuSGFzaE9pZCk7CiAgfQoKICBpZihjYXB0dXJlLnNhbHRMZW5ndGggIT09IHVuZGVmaW5lZCkgewogICAgcGFyYW1zLnNhbHRMZW5ndGggPSBjYXB0dXJlLnNhbHRMZW5ndGguY2hhckNvZGVBdCgwKTsKICB9CgogIHJldHVybiBwYXJhbXM7Cn07CgovKioKICogQ29udmVydHMgYW4gWC41MDkgY2VydGlmaWNhdGUgZnJvbSBQRU0gZm9ybWF0LgogKgogKiBOb3RlOiBJZiB0aGUgY2VydGlmaWNhdGUgaXMgdG8gYmUgdmVyaWZpZWQgdGhlbiBjb21wdXRlIGhhc2ggc2hvdWxkCiAqIGJlIHNldCB0byB0cnVlLiBUaGlzIHdpbGwgc2NhbiB0aGUgVEJTQ2VydGlmaWNhdGUgcGFydCBvZiB0aGUgQVNOLjEKICogb2JqZWN0IHdoaWxlIGl0IGlzIGNvbnZlcnRlZCBzbyBpdCBkb2Vzbid0IG5lZWQgdG8gYmUgY29udmVydGVkIGJhY2sKICogdG8gQVNOLjEtREVSLWVuY29kaW5nIGxhdGVyLgogKgogKiBAcGFyYW0gcGVtIHRoZSBQRU0tZm9ybWF0dGVkIGNlcnRpZmljYXRlLgogKiBAcGFyYW0gY29tcHV0ZUhhc2ggdHJ1ZSB0byBjb21wdXRlIHRoZSBoYXNoIGZvciB2ZXJpZmljYXRpb24uCiAqIEBwYXJhbSBzdHJpY3QgdHJ1ZSB0byBiZSBzdHJpY3Qgd2hlbiBjaGVja2luZyBBU04uMSB2YWx1ZSBsZW5ndGhzLCBmYWxzZSB0bwogKiAgICAgICAgICBhbGxvdyB0cnVuY2F0ZWQgdmFsdWVzIChkZWZhdWx0OiB0cnVlKS4KICoKICogQHJldHVybiB0aGUgY2VydGlmaWNhdGUuCiAqLwpwa2kuY2VydGlmaWNhdGVGcm9tUGVtID0gZnVuY3Rpb24ocGVtLCBjb21wdXRlSGFzaCwgc3RyaWN0KSB7CiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKCiAgaWYobXNnLnR5cGUgIT09ICdDRVJUSUZJQ0FURScgJiYKICAgIG1zZy50eXBlICE9PSAnWDUwOSBDRVJUSUZJQ0FURScgJiYKICAgIG1zZy50eXBlICE9PSAnVFJVU1RFRCBDRVJUSUZJQ0FURScpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ291bGQgbm90IGNvbnZlcnQgY2VydGlmaWNhdGUgZnJvbSBQRU07IFBFTSBoZWFkZXIgdHlwZSAnICsKICAgICAgJ2lzIG5vdCAiQ0VSVElGSUNBVEUiLCAiWDUwOSBDRVJUSUZJQ0FURSIsIG9yICJUUlVTVEVEIENFUlRJRklDQVRFIi4nKTsKICAgIGVycm9yLmhlYWRlclR5cGUgPSBtc2cudHlwZTsKICAgIHRocm93IGVycm9yOwogIH0KICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IGNlcnRpZmljYXRlIGZyb20gUEVNOyBQRU0gaXMgZW5jcnlwdGVkLicpOwogIH0KCiAgLy8gY29udmVydCBERVIgdG8gQVNOLjEgb2JqZWN0CiAgdmFyIG9iaiA9IGFzbjEuZnJvbURlcihtc2cuYm9keSwgc3RyaWN0KTsKCiAgcmV0dXJuIHBraS5jZXJ0aWZpY2F0ZUZyb21Bc24xKG9iaiwgY29tcHV0ZUhhc2gpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFguNTA5IGNlcnRpZmljYXRlIHRvIFBFTSBmb3JtYXQuCiAqCiAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZS4KICogQHBhcmFtIG1heGxpbmUgdGhlIG1heGltdW0gY2hhcmFjdGVycyBwZXIgbGluZSwgZGVmYXVsdHMgdG8gNjQuCiAqCiAqIEByZXR1cm4gdGhlIFBFTS1mb3JtYXR0ZWQgY2VydGlmaWNhdGUuCiAqLwpwa2kuY2VydGlmaWNhdGVUb1BlbSA9IGZ1bmN0aW9uKGNlcnQsIG1heGxpbmUpIHsKICAvLyBjb252ZXJ0IHRvIEFTTi4xLCB0aGVuIERFUiwgdGhlbiBQRU0tZW5jb2RlCiAgdmFyIG1zZyA9IHsKICAgIHR5cGU6ICdDRVJUSUZJQ0FURScsCiAgICBib2R5OiBhc24xLnRvRGVyKHBraS5jZXJ0aWZpY2F0ZVRvQXNuMShjZXJ0KSkuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnLCB7bWF4bGluZTogbWF4bGluZX0pOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFJTQSBwdWJsaWMga2V5IGZyb20gUEVNIGZvcm1hdC4KICoKICogQHBhcmFtIHBlbSB0aGUgUEVNLWZvcm1hdHRlZCBwdWJsaWMga2V5LgogKgogKiBAcmV0dXJuIHRoZSBwdWJsaWMga2V5LgogKi8KcGtpLnB1YmxpY0tleUZyb21QZW0gPSBmdW5jdGlvbihwZW0pIHsKICB2YXIgbXNnID0gZm9yZ2UucGVtLmRlY29kZShwZW0pWzBdOwoKICBpZihtc2cudHlwZSAhPT0gJ1BVQkxJQyBLRVknICYmIG1zZy50eXBlICE9PSAnUlNBIFBVQkxJQyBLRVknKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IHB1YmxpYyBrZXkgZnJvbSBQRU07IFBFTSBoZWFkZXIgJyArCiAgICAgICd0eXBlIGlzIG5vdCAiUFVCTElDIEtFWSIgb3IgIlJTQSBQVUJMSUMgS0VZIi4nKTsKICAgIGVycm9yLmhlYWRlclR5cGUgPSBtc2cudHlwZTsKICAgIHRocm93IGVycm9yOwogIH0KICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IHB1YmxpYyBrZXkgZnJvbSBQRU07IFBFTSBpcyBlbmNyeXB0ZWQuJyk7CiAgfQoKICAvLyBjb252ZXJ0IERFUiB0byBBU04uMSBvYmplY3QKICB2YXIgb2JqID0gYXNuMS5mcm9tRGVyKG1zZy5ib2R5KTsKCiAgcmV0dXJuIHBraS5wdWJsaWNLZXlGcm9tQXNuMShvYmopOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFJTQSBwdWJsaWMga2V5IHRvIFBFTSBmb3JtYXQgKHVzaW5nIGEgU3ViamVjdFB1YmxpY0tleUluZm8pLgogKgogKiBAcGFyYW0ga2V5IHRoZSBwdWJsaWMga2V5LgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lLCBkZWZhdWx0cyB0byA2NC4KICoKICogQHJldHVybiB0aGUgUEVNLWZvcm1hdHRlZCBwdWJsaWMga2V5LgogKi8KcGtpLnB1YmxpY0tleVRvUGVtID0gZnVuY3Rpb24oa2V5LCBtYXhsaW5lKSB7CiAgLy8gY29udmVydCB0byBBU04uMSwgdGhlbiBERVIsIHRoZW4gUEVNLWVuY29kZQogIHZhciBtc2cgPSB7CiAgICB0eXBlOiAnUFVCTElDIEtFWScsCiAgICBib2R5OiBhc24xLnRvRGVyKHBraS5wdWJsaWNLZXlUb0FzbjEoa2V5KSkuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnLCB7bWF4bGluZTogbWF4bGluZX0pOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFJTQSBwdWJsaWMga2V5IHRvIFBFTSBmb3JtYXQgKHVzaW5nIGFuIFJTQVB1YmxpY0tleSkuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHB1YmxpYyBrZXkuCiAqIEBwYXJhbSBtYXhsaW5lIHRoZSBtYXhpbXVtIGNoYXJhY3RlcnMgcGVyIGxpbmUsIGRlZmF1bHRzIHRvIDY0LgogKgogKiBAcmV0dXJuIHRoZSBQRU0tZm9ybWF0dGVkIHB1YmxpYyBrZXkuCiAqLwpwa2kucHVibGljS2V5VG9SU0FQdWJsaWNLZXlQZW0gPSBmdW5jdGlvbihrZXksIG1heGxpbmUpIHsKICAvLyBjb252ZXJ0IHRvIEFTTi4xLCB0aGVuIERFUiwgdGhlbiBQRU0tZW5jb2RlCiAgdmFyIG1zZyA9IHsKICAgIHR5cGU6ICdSU0EgUFVCTElDIEtFWScsCiAgICBib2R5OiBhc24xLnRvRGVyKHBraS5wdWJsaWNLZXlUb1JTQVB1YmxpY0tleShrZXkpKS5nZXRCeXRlcygpCiAgfTsKICByZXR1cm4gZm9yZ2UucGVtLmVuY29kZShtc2csIHttYXhsaW5lOiBtYXhsaW5lfSk7Cn07CgovKioKICogR2V0cyBhIGZpbmdlcnByaW50IGZvciB0aGUgZ2l2ZW4gcHVibGljIGtleS4KICoKICogQHBhcmFtIG9wdGlvbnMgdGhlIG9wdGlvbnMgdG8gdXNlLgogKiAgICAgICAgICBbbWRdIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlIChkZWZhdWx0cyB0byBmb3JnZS5tZC5zaGExKS4KICogICAgICAgICAgW3R5cGVdIHRoZSB0eXBlIG9mIGZpbmdlcnByaW50LCBzdWNoIGFzICdSU0FQdWJsaWNLZXknLAogKiAgICAgICAgICAgICdTdWJqZWN0UHVibGljS2V5SW5mbycgKGRlZmF1bHRzIHRvICdSU0FQdWJsaWNLZXknKS4KICogICAgICAgICAgW2VuY29kaW5nXSBhbiBhbHRlcm5hdGl2ZSBvdXRwdXQgZW5jb2RpbmcsIHN1Y2ggYXMgJ2hleCcKICogICAgICAgICAgICAoZGVmYXVsdHMgdG8gbm9uZSwgb3V0cHV0cyBhIGJ5dGUgYnVmZmVyKS4KICogICAgICAgICAgW2RlbGltaXRlcl0gdGhlIGRlbGltaXRlciB0byB1c2UgYmV0d2VlbiBieXRlcyBmb3IgJ2hleCcgZW5jb2RlZAogKiAgICAgICAgICAgIG91dHB1dCwgZWc6ICc6JyAoZGVmYXVsdHMgdG8gbm9uZSkuCiAqCiAqIEByZXR1cm4gdGhlIGZpbmdlcnByaW50IGFzIGEgYnl0ZSBidWZmZXIgb3Igb3RoZXIgZW5jb2RpbmcgYmFzZWQgb24gb3B0aW9ucy4KICovCnBraS5nZXRQdWJsaWNLZXlGaW5nZXJwcmludCA9IGZ1bmN0aW9uKGtleSwgb3B0aW9ucykgewogIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9OwogIHZhciBtZCA9IG9wdGlvbnMubWQgfHwgZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICB2YXIgdHlwZSA9IG9wdGlvbnMudHlwZSB8fCAnUlNBUHVibGljS2V5JzsKCiAgdmFyIGJ5dGVzOwogIHN3aXRjaCh0eXBlKSB7CiAgY2FzZSAnUlNBUHVibGljS2V5JzoKICAgIGJ5dGVzID0gYXNuMS50b0Rlcihwa2kucHVibGljS2V5VG9SU0FQdWJsaWNLZXkoa2V5KSkuZ2V0Qnl0ZXMoKTsKICAgIGJyZWFrOwogIGNhc2UgJ1N1YmplY3RQdWJsaWNLZXlJbmZvJzoKICAgIGJ5dGVzID0gYXNuMS50b0Rlcihwa2kucHVibGljS2V5VG9Bc24xKGtleSkpLmdldEJ5dGVzKCk7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGZpbmdlcnByaW50IHR5cGUgIicgKyBvcHRpb25zLnR5cGUgKyAnIi4nKTsKICB9CgogIC8vIGhhc2ggcHVibGljIGtleSBieXRlcwogIG1kLnN0YXJ0KCk7CiAgbWQudXBkYXRlKGJ5dGVzKTsKICB2YXIgZGlnZXN0ID0gbWQuZGlnZXN0KCk7CiAgaWYob3B0aW9ucy5lbmNvZGluZyA9PT0gJ2hleCcpIHsKICAgIHZhciBoZXggPSBkaWdlc3QudG9IZXgoKTsKICAgIGlmKG9wdGlvbnMuZGVsaW1pdGVyKSB7CiAgICAgIHJldHVybiBoZXgubWF0Y2goLy57Mn0vZykuam9pbihvcHRpb25zLmRlbGltaXRlcik7CiAgICB9CiAgICByZXR1cm4gaGV4OwogIH0gZWxzZSBpZihvcHRpb25zLmVuY29kaW5nID09PSAnYmluYXJ5JykgewogICAgcmV0dXJuIGRpZ2VzdC5nZXRCeXRlcygpOwogIH0gZWxzZSBpZihvcHRpb25zLmVuY29kaW5nKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcgIicgKyBvcHRpb25zLmVuY29kaW5nICsgJyIuJyk7CiAgfQogIHJldHVybiBkaWdlc3Q7Cn07CgovKioKICogQ29udmVydHMgYSBQS0NTIzEwIGNlcnRpZmljYXRpb24gcmVxdWVzdCAoQ1NSKSBmcm9tIFBFTSBmb3JtYXQuCiAqCiAqIE5vdGU6IElmIHRoZSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QgaXMgdG8gYmUgdmVyaWZpZWQgdGhlbiBjb21wdXRlIGhhc2gKICogc2hvdWxkIGJlIHNldCB0byB0cnVlLiBUaGlzIHdpbGwgc2NhbiB0aGUgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIHBhcnQgb2YKICogdGhlIEFTTi4xIG9iamVjdCB3aGlsZSBpdCBpcyBjb252ZXJ0ZWQgc28gaXQgZG9lc24ndCBuZWVkIHRvIGJlIGNvbnZlcnRlZAogKiBiYWNrIHRvIEFTTi4xLURFUi1lbmNvZGluZyBsYXRlci4KICoKICogQHBhcmFtIHBlbSB0aGUgUEVNLWZvcm1hdHRlZCBjZXJ0aWZpY2F0ZS4KICogQHBhcmFtIGNvbXB1dGVIYXNoIHRydWUgdG8gY29tcHV0ZSB0aGUgaGFzaCBmb3IgdmVyaWZpY2F0aW9uLgogKiBAcGFyYW0gc3RyaWN0IHRydWUgdG8gYmUgc3RyaWN0IHdoZW4gY2hlY2tpbmcgQVNOLjEgdmFsdWUgbGVuZ3RocywgZmFsc2UgdG8KICogICAgICAgICAgYWxsb3cgdHJ1bmNhdGVkIHZhbHVlcyAoZGVmYXVsdDogdHJ1ZSkuCiAqCiAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRpb24gcmVxdWVzdCAoQ1NSKS4KICovCnBraS5jZXJ0aWZpY2F0aW9uUmVxdWVzdEZyb21QZW0gPSBmdW5jdGlvbihwZW0sIGNvbXB1dGVIYXNoLCBzdHJpY3QpIHsKICB2YXIgbXNnID0gZm9yZ2UucGVtLmRlY29kZShwZW0pWzBdOwoKICBpZihtc2cudHlwZSAhPT0gJ0NFUlRJRklDQVRFIFJFUVVFU1QnKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IGNlcnRpZmljYXRpb24gcmVxdWVzdCBmcm9tIFBFTTsgJyArCiAgICAgICdQRU0gaGVhZGVyIHR5cGUgaXMgbm90ICJDRVJUSUZJQ0FURSBSRVFVRVNUIi4nKTsKICAgIGVycm9yLmhlYWRlclR5cGUgPSBtc2cudHlwZTsKICAgIHRocm93IGVycm9yOwogIH0KICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IGNlcnRpZmljYXRpb24gcmVxdWVzdCBmcm9tIFBFTTsgJyArCiAgICAgICdQRU0gaXMgZW5jcnlwdGVkLicpOwogIH0KCiAgLy8gY29udmVydCBERVIgdG8gQVNOLjEgb2JqZWN0CiAgdmFyIG9iaiA9IGFzbjEuZnJvbURlcihtc2cuYm9keSwgc3RyaWN0KTsKCiAgcmV0dXJuIHBraS5jZXJ0aWZpY2F0aW9uUmVxdWVzdEZyb21Bc24xKG9iaiwgY29tcHV0ZUhhc2gpOwp9OwoKLyoqCiAqIENvbnZlcnRzIGEgUEtDUyMxMCBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QgKENTUikgdG8gUEVNIGZvcm1hdC4KICoKICogQHBhcmFtIGNzciB0aGUgY2VydGlmaWNhdGlvbiByZXF1ZXN0LgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lLCBkZWZhdWx0cyB0byA2NC4KICoKICogQHJldHVybiB0aGUgUEVNLWZvcm1hdHRlZCBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QuCiAqLwpwa2kuY2VydGlmaWNhdGlvblJlcXVlc3RUb1BlbSA9IGZ1bmN0aW9uKGNzciwgbWF4bGluZSkgewogIC8vIGNvbnZlcnQgdG8gQVNOLjEsIHRoZW4gREVSLCB0aGVuIFBFTS1lbmNvZGUKICB2YXIgbXNnID0gewogICAgdHlwZTogJ0NFUlRJRklDQVRFIFJFUVVFU1QnLAogICAgYm9keTogYXNuMS50b0Rlcihwa2kuY2VydGlmaWNhdGlvblJlcXVlc3RUb0FzbjEoY3NyKSkuZ2V0Qnl0ZXMoKQogIH07CiAgcmV0dXJuIGZvcmdlLnBlbS5lbmNvZGUobXNnLCB7bWF4bGluZTogbWF4bGluZX0pOwp9OwoKLyoqCiAqIENyZWF0ZXMgYW4gZW1wdHkgWC41MDl2MyBSU0EgY2VydGlmaWNhdGUuCiAqCiAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRlLgogKi8KcGtpLmNyZWF0ZUNlcnRpZmljYXRlID0gZnVuY3Rpb24oKSB7CiAgdmFyIGNlcnQgPSB7fTsKICBjZXJ0LnZlcnNpb24gPSAweDAyOwogIGNlcnQuc2VyaWFsTnVtYmVyID0gJzAwJzsKICBjZXJ0LnNpZ25hdHVyZU9pZCA9IG51bGw7CiAgY2VydC5zaWduYXR1cmUgPSBudWxsOwogIGNlcnQuc2lnaW5mbyA9IHt9OwogIGNlcnQuc2lnaW5mby5hbGdvcml0aG1PaWQgPSBudWxsOwogIGNlcnQudmFsaWRpdHkgPSB7fTsKICBjZXJ0LnZhbGlkaXR5Lm5vdEJlZm9yZSA9IG5ldyBEYXRlKCk7CiAgY2VydC52YWxpZGl0eS5ub3RBZnRlciA9IG5ldyBEYXRlKCk7CgogIGNlcnQuaXNzdWVyID0ge307CiAgY2VydC5pc3N1ZXIuZ2V0RmllbGQgPSBmdW5jdGlvbihzbikgewogICAgcmV0dXJuIF9nZXRBdHRyaWJ1dGUoY2VydC5pc3N1ZXIsIHNuKTsKICB9OwogIGNlcnQuaXNzdWVyLmFkZEZpZWxkID0gZnVuY3Rpb24oYXR0cikgewogICAgX2ZpbGxNaXNzaW5nRmllbGRzKFthdHRyXSk7CiAgICBjZXJ0Lmlzc3Vlci5hdHRyaWJ1dGVzLnB1c2goYXR0cik7CiAgfTsKICBjZXJ0Lmlzc3Vlci5hdHRyaWJ1dGVzID0gW107CiAgY2VydC5pc3N1ZXIuaGFzaCA9IG51bGw7CgogIGNlcnQuc3ViamVjdCA9IHt9OwogIGNlcnQuc3ViamVjdC5nZXRGaWVsZCA9IGZ1bmN0aW9uKHNuKSB7CiAgICByZXR1cm4gX2dldEF0dHJpYnV0ZShjZXJ0LnN1YmplY3QsIHNuKTsKICB9OwogIGNlcnQuc3ViamVjdC5hZGRGaWVsZCA9IGZ1bmN0aW9uKGF0dHIpIHsKICAgIF9maWxsTWlzc2luZ0ZpZWxkcyhbYXR0cl0pOwogICAgY2VydC5zdWJqZWN0LmF0dHJpYnV0ZXMucHVzaChhdHRyKTsKICB9OwogIGNlcnQuc3ViamVjdC5hdHRyaWJ1dGVzID0gW107CiAgY2VydC5zdWJqZWN0Lmhhc2ggPSBudWxsOwoKICBjZXJ0LmV4dGVuc2lvbnMgPSBbXTsKICBjZXJ0LnB1YmxpY0tleSA9IG51bGw7CiAgY2VydC5tZCA9IG51bGw7CgogIC8qKgogICAqIFNldHMgdGhlIHN1YmplY3Qgb2YgdGhpcyBjZXJ0aWZpY2F0ZS4KICAgKgogICAqIEBwYXJhbSBhdHRycyB0aGUgYXJyYXkgb2Ygc3ViamVjdCBhdHRyaWJ1dGVzIHRvIHVzZS4KICAgKiBAcGFyYW0gdW5pcXVlSWQgYW4gb3B0aW9uYWwgYSB1bmlxdWUgSUQgdG8gdXNlLgogICAqLwogIGNlcnQuc2V0U3ViamVjdCA9IGZ1bmN0aW9uKGF0dHJzLCB1bmlxdWVJZCkgewogICAgLy8gc2V0IG5ldyBhdHRyaWJ1dGVzLCBjbGVhciBoYXNoCiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoYXR0cnMpOwogICAgY2VydC5zdWJqZWN0LmF0dHJpYnV0ZXMgPSBhdHRyczsKICAgIGRlbGV0ZSBjZXJ0LnN1YmplY3QudW5pcXVlSWQ7CiAgICBpZih1bmlxdWVJZCkgewogICAgICBjZXJ0LnN1YmplY3QudW5pcXVlSWQgPSB1bmlxdWVJZDsKICAgIH0KICAgIGNlcnQuc3ViamVjdC5oYXNoID0gbnVsbDsKICB9OwoKICAvKioKICAgKiBTZXRzIHRoZSBpc3N1ZXIgb2YgdGhpcyBjZXJ0aWZpY2F0ZS4KICAgKgogICAqIEBwYXJhbSBhdHRycyB0aGUgYXJyYXkgb2YgaXNzdWVyIGF0dHJpYnV0ZXMgdG8gdXNlLgogICAqIEBwYXJhbSB1bmlxdWVJZCBhbiBvcHRpb25hbCBhIHVuaXF1ZSBJRCB0byB1c2UuCiAgICovCiAgY2VydC5zZXRJc3N1ZXIgPSBmdW5jdGlvbihhdHRycywgdW5pcXVlSWQpIHsKICAgIC8vIHNldCBuZXcgYXR0cmlidXRlcywgY2xlYXIgaGFzaAogICAgX2ZpbGxNaXNzaW5nRmllbGRzKGF0dHJzKTsKICAgIGNlcnQuaXNzdWVyLmF0dHJpYnV0ZXMgPSBhdHRyczsKICAgIGRlbGV0ZSBjZXJ0Lmlzc3Vlci51bmlxdWVJZDsKICAgIGlmKHVuaXF1ZUlkKSB7CiAgICAgIGNlcnQuaXNzdWVyLnVuaXF1ZUlkID0gdW5pcXVlSWQ7CiAgICB9CiAgICBjZXJ0Lmlzc3Vlci5oYXNoID0gbnVsbDsKICB9OwoKICAvKioKICAgKiBTZXRzIHRoZSBleHRlbnNpb25zIG9mIHRoaXMgY2VydGlmaWNhdGUuCiAgICoKICAgKiBAcGFyYW0gZXh0cyB0aGUgYXJyYXkgb2YgZXh0ZW5zaW9ucyB0byB1c2UuCiAgICovCiAgY2VydC5zZXRFeHRlbnNpb25zID0gZnVuY3Rpb24oZXh0cykgewogICAgZm9yKHZhciBpID0gMDsgaSA8IGV4dHMubGVuZ3RoOyArK2kpIHsKICAgICAgX2ZpbGxNaXNzaW5nRXh0ZW5zaW9uRmllbGRzKGV4dHNbaV0sIHtjZXJ0OiBjZXJ0fSk7CiAgICB9CiAgICAvLyBzZXQgbmV3IGV4dGVuc2lvbnMKICAgIGNlcnQuZXh0ZW5zaW9ucyA9IGV4dHM7CiAgfTsKCiAgLyoqCiAgICogR2V0cyBhbiBleHRlbnNpb24gYnkgaXRzIG5hbWUgb3IgaWQuCiAgICoKICAgKiBAcGFyYW0gb3B0aW9ucyB0aGUgbmFtZSB0byB1c2Ugb3IgYW4gb2JqZWN0IHdpdGg6CiAgICogICAgICAgICAgbmFtZSB0aGUgbmFtZSB0byB1c2UuCiAgICogICAgICAgICAgaWQgdGhlIGlkIHRvIHVzZS4KICAgKgogICAqIEByZXR1cm4gdGhlIGV4dGVuc2lvbiBvciBudWxsIGlmIG5vdCBmb3VuZC4KICAgKi8KICBjZXJ0LmdldEV4dGVuc2lvbiA9IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAgIGlmKHR5cGVvZiBvcHRpb25zID09PSAnc3RyaW5nJykgewogICAgICBvcHRpb25zID0ge25hbWU6IG9wdGlvbnN9OwogICAgfQoKICAgIHZhciBydmFsID0gbnVsbDsKICAgIHZhciBleHQ7CiAgICBmb3IodmFyIGkgPSAwOyBydmFsID09PSBudWxsICYmIGkgPCBjZXJ0LmV4dGVuc2lvbnMubGVuZ3RoOyArK2kpIHsKICAgICAgZXh0ID0gY2VydC5leHRlbnNpb25zW2ldOwogICAgICBpZihvcHRpb25zLmlkICYmIGV4dC5pZCA9PT0gb3B0aW9ucy5pZCkgewogICAgICAgIHJ2YWwgPSBleHQ7CiAgICAgIH0gZWxzZSBpZihvcHRpb25zLm5hbWUgJiYgZXh0Lm5hbWUgPT09IG9wdGlvbnMubmFtZSkgewogICAgICAgIHJ2YWwgPSBleHQ7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBydmFsOwogIH07CgogIC8qKgogICAqIFNpZ25zIHRoaXMgY2VydGlmaWNhdGUgdXNpbmcgdGhlIGdpdmVuIHByaXZhdGUga2V5LgogICAqCiAgICogQHBhcmFtIGtleSB0aGUgcHJpdmF0ZSBrZXkgdG8gc2lnbiB3aXRoLgogICAqIEBwYXJhbSBtZCB0aGUgbWVzc2FnZSBkaWdlc3Qgb2JqZWN0IHRvIHVzZSAoZGVmYXVsdHMgdG8gZm9yZ2UubWQuc2hhMSkuCiAgICovCiAgY2VydC5zaWduID0gZnVuY3Rpb24oa2V5LCBtZCkgewogICAgLy8gVE9ETzogZ2V0IHNpZ25hdHVyZSBPSUQgZnJvbSBwcml2YXRlIGtleQogICAgY2VydC5tZCA9IG1kIHx8IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICB2YXIgYWxnb3JpdGhtT2lkID0gb2lkc1tjZXJ0Lm1kLmFsZ29yaXRobSArICdXaXRoUlNBRW5jcnlwdGlvbiddOwogICAgaWYoIWFsZ29yaXRobU9pZCkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb21wdXRlIGNlcnRpZmljYXRlIGRpZ2VzdC4gJyArCiAgICAgICAgJ1Vua25vd24gbWVzc2FnZSBkaWdlc3QgYWxnb3JpdGhtIE9JRC4nKTsKICAgICAgZXJyb3IuYWxnb3JpdGhtID0gY2VydC5tZC5hbGdvcml0aG07CiAgICAgIHRocm93IGVycm9yOwogICAgfQogICAgY2VydC5zaWduYXR1cmVPaWQgPSBjZXJ0LnNpZ2luZm8uYWxnb3JpdGhtT2lkID0gYWxnb3JpdGhtT2lkOwoKICAgIC8vIGdldCBUQlNDZXJ0aWZpY2F0ZSwgY29udmVydCB0byBERVIKICAgIGNlcnQudGJzQ2VydGlmaWNhdGUgPSBwa2kuZ2V0VEJTQ2VydGlmaWNhdGUoY2VydCk7CiAgICB2YXIgYnl0ZXMgPSBhc24xLnRvRGVyKGNlcnQudGJzQ2VydGlmaWNhdGUpOwoKICAgIC8vIGRpZ2VzdCBhbmQgc2lnbgogICAgY2VydC5tZC51cGRhdGUoYnl0ZXMuZ2V0Qnl0ZXMoKSk7CiAgICBjZXJ0LnNpZ25hdHVyZSA9IGtleS5zaWduKGNlcnQubWQpOwogIH07CgogIC8qKgogICAqIEF0dGVtcHRzIHZlcmlmeSB0aGUgc2lnbmF0dXJlIG9uIHRoZSBwYXNzZWQgY2VydGlmaWNhdGUgdXNpbmcgdGhpcwogICAqIGNlcnRpZmljYXRlJ3MgcHVibGljIGtleS4KICAgKgogICAqIEBwYXJhbSBjaGlsZCB0aGUgY2VydGlmaWNhdGUgdG8gdmVyaWZ5LgogICAqCiAgICogQHJldHVybiB0cnVlIGlmIHZlcmlmaWVkLCBmYWxzZSBpZiBub3QuCiAgICovCiAgY2VydC52ZXJpZnkgPSBmdW5jdGlvbihjaGlsZCkgewogICAgdmFyIHJ2YWwgPSBmYWxzZTsKCiAgICBpZighY2VydC5pc3N1ZWQoY2hpbGQpKSB7CiAgICAgIHZhciBpc3N1ZXIgPSBjaGlsZC5pc3N1ZXI7CiAgICAgIHZhciBzdWJqZWN0ID0gY2VydC5zdWJqZWN0OwogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1RoZSBwYXJlbnQgY2VydGlmaWNhdGUgZGlkIG5vdCBpc3N1ZSB0aGUgZ2l2ZW4gY2hpbGQgJyArCiAgICAgICAgJ2NlcnRpZmljYXRlOyB0aGUgY2hpbGQgY2VydGlmaWNhdGVcJ3MgaXNzdWVyIGRvZXMgbm90IG1hdGNoIHRoZSAnICsKICAgICAgICAncGFyZW50XCdzIHN1YmplY3QuJyk7CiAgICAgIGVycm9yLmV4cGVjdGVkSXNzdWVyID0gaXNzdWVyLmF0dHJpYnV0ZXM7CiAgICAgIGVycm9yLmFjdHVhbElzc3VlciA9IHN1YmplY3QuYXR0cmlidXRlczsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgdmFyIG1kID0gY2hpbGQubWQ7CiAgICBpZihtZCA9PT0gbnVsbCkgewogICAgICAvLyBjaGVjayBzaWduYXR1cmUgT0lEIGZvciBzdXBwb3J0ZWQgc2lnbmF0dXJlIHR5cGVzCiAgICAgIGlmKGNoaWxkLnNpZ25hdHVyZU9pZCBpbiBvaWRzKSB7CiAgICAgICAgdmFyIG9pZCA9IG9pZHNbY2hpbGQuc2lnbmF0dXJlT2lkXTsKICAgICAgICBzd2l0Y2gob2lkKSB7CiAgICAgICAgY2FzZSAnc2hhMVdpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICAgIG1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ21kNVdpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICAgIG1kID0gZm9yZ2UubWQubWQ1LmNyZWF0ZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnc2hhMjU2V2l0aFJTQUVuY3J5cHRpb24nOgogICAgICAgICAgbWQgPSBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdzaGE1MTJXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgICBtZCA9IGZvcmdlLm1kLnNoYTUxMi5jcmVhdGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ1JTQVNTQS1QU1MnOgogICAgICAgICAgbWQgPSBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYobWQgPT09IG51bGwpIHsKICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb21wdXRlIGNlcnRpZmljYXRlIGRpZ2VzdC4gJyArCiAgICAgICAgICAnVW5rbm93biBzaWduYXR1cmUgT0lELicpOwogICAgICAgIGVycm9yLnNpZ25hdHVyZU9pZCA9IGNoaWxkLnNpZ25hdHVyZU9pZDsKICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgfQoKICAgICAgLy8gcHJvZHVjZSBERVIgZm9ybWF0dGVkIFRCU0NlcnRpZmljYXRlIGFuZCBkaWdlc3QgaXQKICAgICAgdmFyIHRic0NlcnRpZmljYXRlID0gY2hpbGQudGJzQ2VydGlmaWNhdGUgfHwgcGtpLmdldFRCU0NlcnRpZmljYXRlKGNoaWxkKTsKICAgICAgdmFyIGJ5dGVzID0gYXNuMS50b0Rlcih0YnNDZXJ0aWZpY2F0ZSk7CiAgICAgIG1kLnVwZGF0ZShieXRlcy5nZXRCeXRlcygpKTsKICAgIH0KCiAgICBpZihtZCAhPT0gbnVsbCkgewogICAgICB2YXIgc2NoZW1lOwoKICAgICAgc3dpdGNoKGNoaWxkLnNpZ25hdHVyZU9pZCkgewogICAgICBjYXNlIG9pZHMuc2hhMVdpdGhSU0FFbmNyeXB0aW9uOgogICAgICAgIHNjaGVtZSA9IHVuZGVmaW5lZDsgIC8qIHVzZSBQS0NTIzEgdjEuNSBwYWRkaW5nIHNjaGVtZSAqLwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIG9pZHNbJ1JTQVNTQS1QU1MnXToKICAgICAgICB2YXIgaGFzaCwgbWdmOwoKICAgICAgICAvKiBpbml0aWFsaXplIG1nZiAqLwogICAgICAgIGhhc2ggPSBvaWRzW2NoaWxkLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmhhc2guYWxnb3JpdGhtT2lkXTsKICAgICAgICBpZihoYXNoID09PSB1bmRlZmluZWQgfHwgZm9yZ2UubWRbaGFzaF0gPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBNR0YgaGFzaCBmdW5jdGlvbi4nKTsKICAgICAgICAgIGVycm9yLm9pZCA9IGNoaWxkLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmhhc2guYWxnb3JpdGhtT2lkOwogICAgICAgICAgZXJyb3IubmFtZSA9IGhhc2g7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CgogICAgICAgIG1nZiA9IG9pZHNbY2hpbGQuc2lnbmF0dXJlUGFyYW1ldGVycy5tZ2YuYWxnb3JpdGhtT2lkXTsKICAgICAgICBpZihtZ2YgPT09IHVuZGVmaW5lZCB8fCBmb3JnZS5tZ2ZbbWdmXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIE1HRiBmdW5jdGlvbi4nKTsKICAgICAgICAgIGVycm9yLm9pZCA9IGNoaWxkLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmFsZ29yaXRobU9pZDsKICAgICAgICAgIGVycm9yLm5hbWUgPSBtZ2Y7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CgogICAgICAgIG1nZiA9IGZvcmdlLm1nZlttZ2ZdLmNyZWF0ZShmb3JnZS5tZFtoYXNoXS5jcmVhdGUoKSk7CgogICAgICAgIC8qIGluaXRpYWxpemUgaGFzaCBmdW5jdGlvbiAqLwogICAgICAgIGhhc2ggPSBvaWRzW2NoaWxkLnNpZ25hdHVyZVBhcmFtZXRlcnMuaGFzaC5hbGdvcml0aG1PaWRdOwogICAgICAgIGlmKGhhc2ggPT09IHVuZGVmaW5lZCB8fCBmb3JnZS5tZFtoYXNoXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICB0aHJvdyB7CiAgICAgICAgICAgIG1lc3NhZ2U6ICdVbnN1cHBvcnRlZCBSU0FTU0EtUFNTIGhhc2ggZnVuY3Rpb24uJywKICAgICAgICAgICAgb2lkOiBjaGlsZC5zaWduYXR1cmVQYXJhbWV0ZXJzLmhhc2guYWxnb3JpdGhtT2lkLAogICAgICAgICAgICBuYW1lOiBoYXNoCiAgICAgICAgICB9OwogICAgICAgIH0KCiAgICAgICAgc2NoZW1lID0gZm9yZ2UucHNzLmNyZWF0ZShmb3JnZS5tZFtoYXNoXS5jcmVhdGUoKSwgbWdmLAogICAgICAgICAgY2hpbGQuc2lnbmF0dXJlUGFyYW1ldGVycy5zYWx0TGVuZ3RoKTsKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgLy8gdmVyaWZ5IHNpZ25hdHVyZSBvbiBjZXJ0IHVzaW5nIHB1YmxpYyBrZXkKICAgICAgcnZhbCA9IGNlcnQucHVibGljS2V5LnZlcmlmeSgKICAgICAgICBtZC5kaWdlc3QoKS5nZXRCeXRlcygpLCBjaGlsZC5zaWduYXR1cmUsIHNjaGVtZSk7CiAgICB9CgogICAgcmV0dXJuIHJ2YWw7CiAgfTsKCiAgLyoqCiAgICogUmV0dXJucyB0cnVlIGlmIHRoaXMgY2VydGlmaWNhdGUncyBpc3N1ZXIgbWF0Y2hlcyB0aGUgcGFzc2VkCiAgICogY2VydGlmaWNhdGUncyBzdWJqZWN0LiBOb3RlIHRoYXQgbm8gc2lnbmF0dXJlIGNoZWNrIGlzIHBlcmZvcm1lZC4KICAgKgogICAqIEBwYXJhbSBwYXJlbnQgdGhlIGNlcnRpZmljYXRlIHRvIGNoZWNrLgogICAqCiAgICogQHJldHVybiB0cnVlIGlmIHRoaXMgY2VydGlmaWNhdGUncyBpc3N1ZXIgbWF0Y2hlcyB0aGUgcGFzc2VkIGNlcnRpZmljYXRlJ3MKICAgKiAgICAgICAgIHN1YmplY3QuCiAgICovCiAgY2VydC5pc0lzc3VlciA9IGZ1bmN0aW9uKHBhcmVudCkgewogICAgdmFyIHJ2YWwgPSBmYWxzZTsKCiAgICB2YXIgaSA9IGNlcnQuaXNzdWVyOwogICAgdmFyIHMgPSBwYXJlbnQuc3ViamVjdDsKCiAgICAvLyBjb21wYXJlIGhhc2hlcyBpZiBwcmVzZW50CiAgICBpZihpLmhhc2ggJiYgcy5oYXNoKSB7CiAgICAgIHJ2YWwgPSAoaS5oYXNoID09PSBzLmhhc2gpOwogICAgfSBlbHNlIGlmKGkuYXR0cmlidXRlcy5sZW5ndGggPT09IHMuYXR0cmlidXRlcy5sZW5ndGgpIHsKICAgICAgLy8gYWxsIGF0dHJpYnV0ZXMgYXJlIHRoZSBzYW1lIHNvIGlzc3VlciBtYXRjaGVzIHN1YmplY3QKICAgICAgcnZhbCA9IHRydWU7CiAgICAgIHZhciBpYXR0ciwgc2F0dHI7CiAgICAgIGZvcih2YXIgbiA9IDA7IHJ2YWwgJiYgbiA8IGkuYXR0cmlidXRlcy5sZW5ndGg7ICsrbikgewogICAgICAgIGlhdHRyID0gaS5hdHRyaWJ1dGVzW25dOwogICAgICAgIHNhdHRyID0gcy5hdHRyaWJ1dGVzW25dOwogICAgICAgIGlmKGlhdHRyLnR5cGUgIT09IHNhdHRyLnR5cGUgfHwgaWF0dHIudmFsdWUgIT09IHNhdHRyLnZhbHVlKSB7CiAgICAgICAgICAvLyBhdHRyaWJ1dGUgbWlzbWF0Y2gKICAgICAgICAgIHJ2YWwgPSBmYWxzZTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAvKioKICAgKiBSZXR1cm5zIHRydWUgaWYgdGhpcyBjZXJ0aWZpY2F0ZSdzIHN1YmplY3QgbWF0Y2hlcyB0aGUgaXNzdWVyIG9mIHRoZQogICAqIGdpdmVuIGNlcnRpZmljYXRlKS4gTm90ZSB0aGF0IG5vdCBzaWduYXR1cmUgY2hlY2sgaXMgcGVyZm9ybWVkLgogICAqCiAgICogQHBhcmFtIGNoaWxkIHRoZSBjZXJ0aWZpY2F0ZSB0byBjaGVjay4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGlzIGNlcnRpZmljYXRlJ3Mgc3ViamVjdCBtYXRjaGVzIHRoZSBwYXNzZWQKICAgKiAgICAgICAgIGNlcnRpZmljYXRlJ3MgaXNzdWVyLgogICAqLwogIGNlcnQuaXNzdWVkID0gZnVuY3Rpb24oY2hpbGQpIHsKICAgIHJldHVybiBjaGlsZC5pc0lzc3VlcihjZXJ0KTsKICB9OwoKICAvKioKICAgKiBHZW5lcmF0ZXMgdGhlIHN1YmplY3RLZXlJZGVudGlmaWVyIGZvciB0aGlzIGNlcnRpZmljYXRlIGFzIGJ5dGUgYnVmZmVyLgogICAqCiAgICogQHJldHVybiB0aGUgc3ViamVjdEtleUlkZW50aWZpZXIgZm9yIHRoaXMgY2VydGlmaWNhdGUgYXMgYnl0ZSBidWZmZXIuCiAgICovCiAgY2VydC5nZW5lcmF0ZVN1YmplY3RLZXlJZGVudGlmaWVyID0gZnVuY3Rpb24oKSB7CiAgICAvKiBTZWU6IDQuMi4xLjIgc2VjdGlvbiBvZiB0aGUgdGhlIFJGQzMyODAsIGtleUlkZW50aWZpZXIgaXMgZWl0aGVyOgoKICAgICAgKDEpIFRoZSBrZXlJZGVudGlmaWVyIGlzIGNvbXBvc2VkIG9mIHRoZSAxNjAtYml0IFNIQS0xIGhhc2ggb2YgdGhlCiAgICAgICAgdmFsdWUgb2YgdGhlIEJJVCBTVFJJTkcgc3ViamVjdFB1YmxpY0tleSAoZXhjbHVkaW5nIHRoZSB0YWcsCiAgICAgICAgbGVuZ3RoLCBhbmQgbnVtYmVyIG9mIHVudXNlZCBiaXRzKS4KCiAgICAgICgyKSBUaGUga2V5SWRlbnRpZmllciBpcyBjb21wb3NlZCBvZiBhIGZvdXIgYml0IHR5cGUgZmllbGQgd2l0aAogICAgICAgIHRoZSB2YWx1ZSAwMTAwIGZvbGxvd2VkIGJ5IHRoZSBsZWFzdCBzaWduaWZpY2FudCA2MCBiaXRzIG9mIHRoZQogICAgICAgIFNIQS0xIGhhc2ggb2YgdGhlIHZhbHVlIG9mIHRoZSBCSVQgU1RSSU5HIHN1YmplY3RQdWJsaWNLZXkKICAgICAgICAoZXhjbHVkaW5nIHRoZSB0YWcsIGxlbmd0aCwgYW5kIG51bWJlciBvZiB1bnVzZWQgYml0IHN0cmluZyBiaXRzKS4KICAgICovCgogICAgLy8gc2tpcHBpbmcgdGhlIHRhZywgbGVuZ3RoLCBhbmQgbnVtYmVyIG9mIHVudXNlZCBiaXRzIGlzIHRoZSBzYW1lCiAgICAvLyBhcyBqdXN0IHVzaW5nIHRoZSBSU0FQdWJsaWNLZXkgKGZvciBSU0Ega2V5cywgd2hpY2ggYXJlIHRoZQogICAgLy8gb25seSBvbmVzIHN1cHBvcnRlZCkKICAgIHJldHVybiBwa2kuZ2V0UHVibGljS2V5RmluZ2VycHJpbnQoY2VydC5wdWJsaWNLZXksIHt0eXBlOiAnUlNBUHVibGljS2V5J30pOwogIH07CgogIC8qKgogICAqIFZlcmlmaWVzIHRoZSBzdWJqZWN0S2V5SWRlbnRpZmllciBleHRlbnNpb24gdmFsdWUgZm9yIHRoaXMgY2VydGlmaWNhdGUKICAgKiBhZ2FpbnN0IGl0cyBwdWJsaWMga2V5LiBJZiBubyBleHRlbnNpb24gaXMgZm91bmQsIGZhbHNlIHdpbGwgYmUKICAgKiByZXR1cm5lZC4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB2ZXJpZmllZCwgZmFsc2UgaWYgbm90LgogICAqLwogIGNlcnQudmVyaWZ5U3ViamVjdEtleUlkZW50aWZpZXIgPSBmdW5jdGlvbigpIHsKICAgIHZhciBvaWQgPSBvaWRzWydzdWJqZWN0S2V5SWRlbnRpZmllciddOwogICAgZm9yKHZhciBpID0gMDsgaSA8IGNlcnQuZXh0ZW5zaW9ucy5sZW5ndGg7ICsraSkgewogICAgICB2YXIgZXh0ID0gY2VydC5leHRlbnNpb25zW2ldOwogICAgICBpZihleHQuaWQgPT09IG9pZCkgewogICAgICAgIHZhciBza2kgPSBjZXJ0LmdlbmVyYXRlU3ViamVjdEtleUlkZW50aWZpZXIoKS5nZXRCeXRlcygpOwogICAgICAgIHJldHVybiAoZm9yZ2UudXRpbC5oZXhUb0J5dGVzKGV4dC5zdWJqZWN0S2V5SWRlbnRpZmllcikgPT09IHNraSk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBmYWxzZTsKICB9OwoKICByZXR1cm4gY2VydDsKfTsKCi8qKgogKiBDb252ZXJ0cyBhbiBYLjUwOXYzIFJTQSBjZXJ0aWZpY2F0ZSBmcm9tIGFuIEFTTi4xIG9iamVjdC4KICoKICogTm90ZTogSWYgdGhlIGNlcnRpZmljYXRlIGlzIHRvIGJlIHZlcmlmaWVkIHRoZW4gY29tcHV0ZSBoYXNoIHNob3VsZAogKiBiZSBzZXQgdG8gdHJ1ZS4gVGhlcmUgaXMgY3VycmVudGx5IG5vIGltcGxlbWVudGF0aW9uIGZvciBjb252ZXJ0aW5nCiAqIGEgY2VydGlmaWNhdGUgYmFjayB0byBBU04uMSBzbyB0aGUgVEJTQ2VydGlmaWNhdGUgcGFydCBvZiB0aGUgQVNOLjEKICogb2JqZWN0IG5lZWRzIHRvIGJlIHNjYW5uZWQgYmVmb3JlIHRoZSBjZXJ0IG9iamVjdCBpcyBjcmVhdGVkLgogKgogKiBAcGFyYW0gb2JqIHRoZSBhc24xIHJlcHJlc2VudGF0aW9uIG9mIGFuIFguNTA5djMgUlNBIGNlcnRpZmljYXRlLgogKiBAcGFyYW0gY29tcHV0ZUhhc2ggdHJ1ZSB0byBjb21wdXRlIHRoZSBoYXNoIGZvciB2ZXJpZmljYXRpb24uCiAqCiAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRlLgogKi8KcGtpLmNlcnRpZmljYXRlRnJvbUFzbjEgPSBmdW5jdGlvbihvYmosIGNvbXB1dGVIYXNoKSB7CiAgLy8gdmFsaWRhdGUgY2VydGlmaWNhdGUgYW5kIGNhcHR1cmUgZGF0YQogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgeDUwOUNlcnRpZmljYXRlVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFguNTA5IGNlcnRpZmljYXRlLiAnICsKICAgICAgJ0FTTi4xIG9iamVjdCBpcyBub3QgYW4gWDUwOXYzIENlcnRpZmljYXRlLicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3JzOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICAvLyBlbnN1cmUgc2lnbmF0dXJlIGlzIG5vdCBpbnRlcnByZXRlZCBhcyBhbiBlbWJlZGRlZCBBU04uMSBvYmplY3QKICBpZih0eXBlb2YgY2FwdHVyZS5jZXJ0U2lnbmF0dXJlICE9PSAnc3RyaW5nJykgewogICAgdmFyIGNlcnRTaWduYXR1cmUgPSAnXHgwMCc7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgY2FwdHVyZS5jZXJ0U2lnbmF0dXJlLmxlbmd0aDsgKytpKSB7CiAgICAgIGNlcnRTaWduYXR1cmUgKz0gYXNuMS50b0RlcihjYXB0dXJlLmNlcnRTaWduYXR1cmVbaV0pLmdldEJ5dGVzKCk7CiAgICB9CiAgICBjYXB0dXJlLmNlcnRTaWduYXR1cmUgPSBjZXJ0U2lnbmF0dXJlOwogIH0KCiAgLy8gZ2V0IG9pZAogIHZhciBvaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUucHVibGljS2V5T2lkKTsKICBpZihvaWQgIT09IHBraS5vaWRzWydyc2FFbmNyeXB0aW9uJ10pIHsKICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgcHVibGljIGtleS4gT0lEIGlzIG5vdCBSU0EuJyk7CiAgfQoKICAvLyBjcmVhdGUgY2VydGlmaWNhdGUKICB2YXIgY2VydCA9IHBraS5jcmVhdGVDZXJ0aWZpY2F0ZSgpOwogIGNlcnQudmVyc2lvbiA9IGNhcHR1cmUuY2VydFZlcnNpb24gPwogICAgY2FwdHVyZS5jZXJ0VmVyc2lvbi5jaGFyQ29kZUF0KDApIDogMDsKICB2YXIgc2VyaWFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5jZXJ0U2VyaWFsTnVtYmVyKTsKICBjZXJ0LnNlcmlhbE51bWJlciA9IHNlcmlhbC50b0hleCgpOwogIGNlcnQuc2lnbmF0dXJlT2lkID0gZm9yZ2UuYXNuMS5kZXJUb09pZChjYXB0dXJlLmNlcnRTaWduYXR1cmVPaWQpOwogIGNlcnQuc2lnbmF0dXJlUGFyYW1ldGVycyA9IF9yZWFkU2lnbmF0dXJlUGFyYW1ldGVycygKICAgIGNlcnQuc2lnbmF0dXJlT2lkLCBjYXB0dXJlLmNlcnRTaWduYXR1cmVQYXJhbXMsIHRydWUpOwogIGNlcnQuc2lnaW5mby5hbGdvcml0aG1PaWQgPSBmb3JnZS5hc24xLmRlclRvT2lkKGNhcHR1cmUuY2VydGluZm9TaWduYXR1cmVPaWQpOwogIGNlcnQuc2lnaW5mby5wYXJhbWV0ZXJzID0gX3JlYWRTaWduYXR1cmVQYXJhbWV0ZXJzKGNlcnQuc2lnaW5mby5hbGdvcml0aG1PaWQsCiAgICBjYXB0dXJlLmNlcnRpbmZvU2lnbmF0dXJlUGFyYW1zLCBmYWxzZSk7CiAgLy8gc2tpcCAidW51c2VkIGJpdHMiIGluIHNpZ25hdHVyZSB2YWx1ZSBCSVRTVFJJTkcKICB2YXIgc2lnbmF0dXJlID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5jZXJ0U2lnbmF0dXJlKTsKICArK3NpZ25hdHVyZS5yZWFkOwogIGNlcnQuc2lnbmF0dXJlID0gc2lnbmF0dXJlLmdldEJ5dGVzKCk7CgogIHZhciB2YWxpZGl0eSA9IFtdOwogIGlmKGNhcHR1cmUuY2VydFZhbGlkaXR5MVVUQ1RpbWUgIT09IHVuZGVmaW5lZCkgewogICAgdmFsaWRpdHkucHVzaChhc24xLnV0Y1RpbWVUb0RhdGUoY2FwdHVyZS5jZXJ0VmFsaWRpdHkxVVRDVGltZSkpOwogIH0KICBpZihjYXB0dXJlLmNlcnRWYWxpZGl0eTJHZW5lcmFsaXplZFRpbWUgIT09IHVuZGVmaW5lZCkgewogICAgdmFsaWRpdHkucHVzaChhc24xLmdlbmVyYWxpemVkVGltZVRvRGF0ZSgKICAgICAgY2FwdHVyZS5jZXJ0VmFsaWRpdHkyR2VuZXJhbGl6ZWRUaW1lKSk7CiAgfQogIGlmKGNhcHR1cmUuY2VydFZhbGlkaXR5M1VUQ1RpbWUgIT09IHVuZGVmaW5lZCkgewogICAgdmFsaWRpdHkucHVzaChhc24xLnV0Y1RpbWVUb0RhdGUoY2FwdHVyZS5jZXJ0VmFsaWRpdHkzVVRDVGltZSkpOwogIH0KICBpZihjYXB0dXJlLmNlcnRWYWxpZGl0eTRHZW5lcmFsaXplZFRpbWUgIT09IHVuZGVmaW5lZCkgewogICAgdmFsaWRpdHkucHVzaChhc24xLmdlbmVyYWxpemVkVGltZVRvRGF0ZSgKICAgICAgY2FwdHVyZS5jZXJ0VmFsaWRpdHk0R2VuZXJhbGl6ZWRUaW1lKSk7CiAgfQogIGlmKHZhbGlkaXR5Lmxlbmd0aCA+IDIpIHsKICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgbm90QmVmb3JlL25vdEFmdGVyIHZhbGlkaXR5IHRpbWVzOyBtb3JlICcgKwogICAgICAndGhhbiB0d28gdGltZXMgd2VyZSBwcm92aWRlZCBpbiB0aGUgY2VydGlmaWNhdGUuJyk7CiAgfQogIGlmKHZhbGlkaXR5Lmxlbmd0aCA8IDIpIHsKICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgbm90QmVmb3JlL25vdEFmdGVyIHZhbGlkaXR5IHRpbWVzOyB0aGV5ICcgKwogICAgICAnd2VyZSBub3QgcHJvdmlkZWQgYXMgZWl0aGVyIFVUQ1RpbWUgb3IgR2VuZXJhbGl6ZWRUaW1lLicpOwogIH0KICBjZXJ0LnZhbGlkaXR5Lm5vdEJlZm9yZSA9IHZhbGlkaXR5WzBdOwogIGNlcnQudmFsaWRpdHkubm90QWZ0ZXIgPSB2YWxpZGl0eVsxXTsKCiAgLy8ga2VlcCBUQlNDZXJ0aWZpY2F0ZSB0byBwcmVzZXJ2ZSBzaWduYXR1cmUgd2hlbiBleHBvcnRpbmcKICBjZXJ0LnRic0NlcnRpZmljYXRlID0gY2FwdHVyZS50YnNDZXJ0aWZpY2F0ZTsKCiAgaWYoY29tcHV0ZUhhc2gpIHsKICAgIC8vIGNoZWNrIHNpZ25hdHVyZSBPSUQgZm9yIHN1cHBvcnRlZCBzaWduYXR1cmUgdHlwZXMKICAgIGNlcnQubWQgPSBudWxsOwogICAgaWYoY2VydC5zaWduYXR1cmVPaWQgaW4gb2lkcykgewogICAgICB2YXIgb2lkID0gb2lkc1tjZXJ0LnNpZ25hdHVyZU9pZF07CiAgICAgIHN3aXRjaChvaWQpIHsKICAgICAgY2FzZSAnc2hhMVdpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICBjZXJ0Lm1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnbWQ1V2l0aFJTQUVuY3J5cHRpb24nOgogICAgICAgIGNlcnQubWQgPSBmb3JnZS5tZC5tZDUuY3JlYXRlKCk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgJ3NoYTI1NldpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICBjZXJ0Lm1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdzaGE1MTJXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgY2VydC5tZCA9IGZvcmdlLm1kLnNoYTUxMi5jcmVhdGUoKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnUlNBU1NBLVBTUyc6CiAgICAgICAgY2VydC5tZCA9IGZvcmdlLm1kLnNoYTI1Ni5jcmVhdGUoKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogICAgaWYoY2VydC5tZCA9PT0gbnVsbCkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb21wdXRlIGNlcnRpZmljYXRlIGRpZ2VzdC4gJyArCiAgICAgICAgJ1Vua25vd24gc2lnbmF0dXJlIE9JRC4nKTsKICAgICAgZXJyb3Iuc2lnbmF0dXJlT2lkID0gY2VydC5zaWduYXR1cmVPaWQ7CiAgICAgIHRocm93IGVycm9yOwogICAgfQoKICAgIC8vIHByb2R1Y2UgREVSIGZvcm1hdHRlZCBUQlNDZXJ0aWZpY2F0ZSBhbmQgZGlnZXN0IGl0CiAgICB2YXIgYnl0ZXMgPSBhc24xLnRvRGVyKGNlcnQudGJzQ2VydGlmaWNhdGUpOwogICAgY2VydC5tZC51cGRhdGUoYnl0ZXMuZ2V0Qnl0ZXMoKSk7CiAgfQoKICAvLyBoYW5kbGUgaXNzdWVyLCBidWlsZCBpc3N1ZXIgbWVzc2FnZSBkaWdlc3QKICB2YXIgaW1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICBjZXJ0Lmlzc3Vlci5nZXRGaWVsZCA9IGZ1bmN0aW9uKHNuKSB7CiAgICByZXR1cm4gX2dldEF0dHJpYnV0ZShjZXJ0Lmlzc3Vlciwgc24pOwogIH07CiAgY2VydC5pc3N1ZXIuYWRkRmllbGQgPSBmdW5jdGlvbihhdHRyKSB7CiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoW2F0dHJdKTsKICAgIGNlcnQuaXNzdWVyLmF0dHJpYnV0ZXMucHVzaChhdHRyKTsKICB9OwogIGNlcnQuaXNzdWVyLmF0dHJpYnV0ZXMgPSBwa2kuUkROQXR0cmlidXRlc0FzQXJyYXkoY2FwdHVyZS5jZXJ0SXNzdWVyLCBpbWQpOwogIGlmKGNhcHR1cmUuY2VydElzc3VlclVuaXF1ZUlkKSB7CiAgICBjZXJ0Lmlzc3Vlci51bmlxdWVJZCA9IGNhcHR1cmUuY2VydElzc3VlclVuaXF1ZUlkOwogIH0KICBjZXJ0Lmlzc3Vlci5oYXNoID0gaW1kLmRpZ2VzdCgpLnRvSGV4KCk7CgogIC8vIGhhbmRsZSBzdWJqZWN0LCBidWlsZCBzdWJqZWN0IG1lc3NhZ2UgZGlnZXN0CiAgdmFyIHNtZCA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgY2VydC5zdWJqZWN0LmdldEZpZWxkID0gZnVuY3Rpb24oc24pIHsKICAgIHJldHVybiBfZ2V0QXR0cmlidXRlKGNlcnQuc3ViamVjdCwgc24pOwogIH07CiAgY2VydC5zdWJqZWN0LmFkZEZpZWxkID0gZnVuY3Rpb24oYXR0cikgewogICAgX2ZpbGxNaXNzaW5nRmllbGRzKFthdHRyXSk7CiAgICBjZXJ0LnN1YmplY3QuYXR0cmlidXRlcy5wdXNoKGF0dHIpOwogIH07CiAgY2VydC5zdWJqZWN0LmF0dHJpYnV0ZXMgPSBwa2kuUkROQXR0cmlidXRlc0FzQXJyYXkoY2FwdHVyZS5jZXJ0U3ViamVjdCwgc21kKTsKICBpZihjYXB0dXJlLmNlcnRTdWJqZWN0VW5pcXVlSWQpIHsKICAgIGNlcnQuc3ViamVjdC51bmlxdWVJZCA9IGNhcHR1cmUuY2VydFN1YmplY3RVbmlxdWVJZDsKICB9CiAgY2VydC5zdWJqZWN0Lmhhc2ggPSBzbWQuZGlnZXN0KCkudG9IZXgoKTsKCiAgLy8gaGFuZGxlIGV4dGVuc2lvbnMKICBpZihjYXB0dXJlLmNlcnRFeHRlbnNpb25zKSB7CiAgICBjZXJ0LmV4dGVuc2lvbnMgPSBwa2kuY2VydGlmaWNhdGVFeHRlbnNpb25zRnJvbUFzbjEoY2FwdHVyZS5jZXJ0RXh0ZW5zaW9ucyk7CiAgfSBlbHNlIHsKICAgIGNlcnQuZXh0ZW5zaW9ucyA9IFtdOwogIH0KCiAgLy8gY29udmVydCBSU0EgcHVibGljIGtleSBmcm9tIEFTTi4xCiAgY2VydC5wdWJsaWNLZXkgPSBwa2kucHVibGljS2V5RnJvbUFzbjEoY2FwdHVyZS5zdWJqZWN0UHVibGljS2V5SW5mbyk7CgogIHJldHVybiBjZXJ0Owp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIEFTTi4xIGV4dGVuc2lvbnMgb2JqZWN0ICh3aXRoIGV4dGVuc2lvbiBzZXF1ZW5jZXMgYXMgaXRzCiAqIHZhbHVlcykgaW50byBhbiBhcnJheSBvZiBleHRlbnNpb24gb2JqZWN0cyB3aXRoIHR5cGVzIGFuZCB2YWx1ZXMuCiAqCiAqIFN1cHBvcnRlZCBleHRlbnNpb25zOgogKgogKiBpZC1jZS1rZXlVc2FnZSBPQkpFQ1QgSURFTlRJRklFUiA6Oj0gIHsgaWQtY2UgMTUgfQogKiBLZXlVc2FnZSA6Oj0gQklUIFNUUklORyB7CiAqICAgZGlnaXRhbFNpZ25hdHVyZSAgICAgICAgKDApLAogKiAgIG5vblJlcHVkaWF0aW9uICAgICAgICAgICgxKSwKICogICBrZXlFbmNpcGhlcm1lbnQgICAgICAgICAoMiksCiAqICAgZGF0YUVuY2lwaGVybWVudCAgICAgICAgKDMpLAogKiAgIGtleUFncmVlbWVudCAgICAgICAgICAgICg0KSwKICogICBrZXlDZXJ0U2lnbiAgICAgICAgICAgICAoNSksCiAqICAgY1JMU2lnbiAgICAgICAgICAgICAgICAgKDYpLAogKiAgIGVuY2lwaGVyT25seSAgICAgICAgICAgICg3KSwKICogICBkZWNpcGhlck9ubHkgICAgICAgICAgICAoOCkKICogfQogKgogKiBpZC1jZS1iYXNpY0NvbnN0cmFpbnRzIE9CSkVDVCBJREVOVElGSUVSIDo6PSAgeyBpZC1jZSAxOSB9CiAqIEJhc2ljQ29uc3RyYWludHMgOjo9IFNFUVVFTkNFIHsKICogICBjQSAgICAgICAgICAgICAgICAgICAgICBCT09MRUFOIERFRkFVTFQgRkFMU0UsCiAqICAgcGF0aExlbkNvbnN0cmFpbnQgICAgICAgSU5URUdFUiAoMC4uTUFYKSBPUFRJT05BTAogKiB9CiAqCiAqIHN1YmplY3RBbHROYW1lIEVYVEVOU0lPTiA6Oj0gewogKiAgIFNZTlRBWCBHZW5lcmFsTmFtZXMKICogICBJREVOVElGSUVEIEJZIGlkLWNlLXN1YmplY3RBbHROYW1lCiAqIH0KICoKICogR2VuZXJhbE5hbWVzIDo6PSBTRVFVRU5DRSBTSVpFICgxLi5NQVgpIE9GIEdlbmVyYWxOYW1lCiAqCiAqIEdlbmVyYWxOYW1lIDo6PSBDSE9JQ0UgewogKiAgIG90aGVyTmFtZSAgICAgIFswXSBJTlNUQU5DRSBPRiBPVEhFUi1OQU1FLAogKiAgIHJmYzgyMk5hbWUgICAgIFsxXSBJQTVTdHJpbmcsCiAqICAgZE5TTmFtZSAgICAgICAgWzJdIElBNVN0cmluZywKICogICB4NDAwQWRkcmVzcyAgICBbM10gT1JBZGRyZXNzLAogKiAgIGRpcmVjdG9yeU5hbWUgIFs0XSBOYW1lLAogKiAgIGVkaVBhcnR5TmFtZSAgIFs1XSBFRElQYXJ0eU5hbWUsCiAqICAgdW5pZm9ybVJlc291cmNlSWRlbnRpZmllciBbNl0gSUE1U3RyaW5nLAogKiAgIElQQWRkcmVzcyAgICAgIFs3XSBPQ1RFVCBTVFJJTkcsCiAqICAgcmVnaXN0ZXJlZElEICAgWzhdIE9CSkVDVCBJREVOVElGSUVSCiAqIH0KICoKICogT1RIRVItTkFNRSA6Oj0gVFlQRS1JREVOVElGSUVSCiAqCiAqIEVESVBhcnR5TmFtZSA6Oj0gU0VRVUVOQ0UgewogKiAgIG5hbWVBc3NpZ25lciBbMF0gRGlyZWN0b3J5U3RyaW5nIHt1Yi1uYW1lfSBPUFRJT05BTCwKICogICBwYXJ0eU5hbWUgICAgWzFdIERpcmVjdG9yeVN0cmluZyB7dWItbmFtZX0KICogfQogKgogKiBAcGFyYW0gZXh0cyB0aGUgZXh0ZW5zaW9ucyBBU04uMSB3aXRoIGV4dGVuc2lvbiBzZXF1ZW5jZXMgdG8gcGFyc2UuCiAqCiAqIEByZXR1cm4gdGhlIGFycmF5LgogKi8KcGtpLmNlcnRpZmljYXRlRXh0ZW5zaW9uc0Zyb21Bc24xID0gZnVuY3Rpb24oZXh0cykgewogIHZhciBydmFsID0gW107CiAgZm9yKHZhciBpID0gMDsgaSA8IGV4dHMudmFsdWUubGVuZ3RoOyArK2kpIHsKICAgIC8vIGdldCBleHRlbnNpb24gc2VxdWVuY2UKICAgIHZhciBleHRzZXEgPSBleHRzLnZhbHVlW2ldOwogICAgZm9yKHZhciBlaSA9IDA7IGVpIDwgZXh0c2VxLnZhbHVlLmxlbmd0aDsgKytlaSkgewogICAgICBydmFsLnB1c2gocGtpLmNlcnRpZmljYXRlRXh0ZW5zaW9uRnJvbUFzbjEoZXh0c2VxLnZhbHVlW2VpXSkpOwogICAgfQogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogUGFyc2VzIGEgc2luZ2xlIGNlcnRpZmljYXRlIGV4dGVuc2lvbiBmcm9tIEFTTi4xLgogKgogKiBAcGFyYW0gZXh0IHRoZSBleHRlbnNpb24gaW4gQVNOLjEgZm9ybWF0LgogKgogKiBAcmV0dXJuIHRoZSBwYXJzZWQgZXh0ZW5zaW9uIGFzIGFuIG9iamVjdC4KICovCnBraS5jZXJ0aWZpY2F0ZUV4dGVuc2lvbkZyb21Bc24xID0gZnVuY3Rpb24oZXh0KSB7CiAgLy8gYW4gZXh0ZW5zaW9uIGhhczoKICAvLyBbMF0gZXh0bklEICAgICAgT0JKRUNUIElERU5USUZJRVIKICAvLyBbMV0gY3JpdGljYWwgICAgQk9PTEVBTiBERUZBVUxUIEZBTFNFCiAgLy8gWzJdIGV4dG5WYWx1ZSAgIE9DVEVUIFNUUklORwogIHZhciBlID0ge307CiAgZS5pZCA9IGFzbjEuZGVyVG9PaWQoZXh0LnZhbHVlWzBdLnZhbHVlKTsKICBlLmNyaXRpY2FsID0gZmFsc2U7CiAgaWYoZXh0LnZhbHVlWzFdLnR5cGUgPT09IGFzbjEuVHlwZS5CT09MRUFOKSB7CiAgICBlLmNyaXRpY2FsID0gKGV4dC52YWx1ZVsxXS52YWx1ZS5jaGFyQ29kZUF0KDApICE9PSAweDAwKTsKICAgIGUudmFsdWUgPSBleHQudmFsdWVbMl0udmFsdWU7CiAgfSBlbHNlIHsKICAgIGUudmFsdWUgPSBleHQudmFsdWVbMV0udmFsdWU7CiAgfQogIC8vIGlmIHRoZSBvaWQgaXMga25vd24sIGdldCBpdHMgbmFtZQogIGlmKGUuaWQgaW4gb2lkcykgewogICAgZS5uYW1lID0gb2lkc1tlLmlkXTsKCiAgICAvLyBoYW5kbGUga2V5IHVzYWdlCiAgICBpZihlLm5hbWUgPT09ICdrZXlVc2FnZScpIHsKICAgICAgLy8gZ2V0IHZhbHVlIGFzIEJJVCBTVFJJTkcKICAgICAgdmFyIGV2ID0gYXNuMS5mcm9tRGVyKGUudmFsdWUpOwogICAgICB2YXIgYjIgPSAweDAwOwogICAgICB2YXIgYjMgPSAweDAwOwogICAgICBpZihldi52YWx1ZS5sZW5ndGggPiAxKSB7CiAgICAgICAgLy8gc2tpcCBmaXJzdCBieXRlLCBqdXN0IGluZGljYXRlcyB1bnVzZWQgYml0cyB3aGljaAogICAgICAgIC8vIHdpbGwgYmUgcGFkZGVkIHdpdGggMHMgYW55d2F5CiAgICAgICAgLy8gZ2V0IGJ5dGVzIHdpdGggZmxhZyBiaXRzCiAgICAgICAgYjIgPSBldi52YWx1ZS5jaGFyQ29kZUF0KDEpOwogICAgICAgIGIzID0gZXYudmFsdWUubGVuZ3RoID4gMiA/IGV2LnZhbHVlLmNoYXJDb2RlQXQoMikgOiAwOwogICAgICB9CiAgICAgIC8vIHNldCBmbGFncwogICAgICBlLmRpZ2l0YWxTaWduYXR1cmUgPSAoYjIgJiAweDgwKSA9PT0gMHg4MDsKICAgICAgZS5ub25SZXB1ZGlhdGlvbiA9IChiMiAmIDB4NDApID09PSAweDQwOwogICAgICBlLmtleUVuY2lwaGVybWVudCA9IChiMiAmIDB4MjApID09PSAweDIwOwogICAgICBlLmRhdGFFbmNpcGhlcm1lbnQgPSAoYjIgJiAweDEwKSA9PT0gMHgxMDsKICAgICAgZS5rZXlBZ3JlZW1lbnQgPSAoYjIgJiAweDA4KSA9PT0gMHgwODsKICAgICAgZS5rZXlDZXJ0U2lnbiA9IChiMiAmIDB4MDQpID09PSAweDA0OwogICAgICBlLmNSTFNpZ24gPSAoYjIgJiAweDAyKSA9PT0gMHgwMjsKICAgICAgZS5lbmNpcGhlck9ubHkgPSAoYjIgJiAweDAxKSA9PT0gMHgwMTsKICAgICAgZS5kZWNpcGhlck9ubHkgPSAoYjMgJiAweDgwKSA9PT0gMHg4MDsKICAgIH0gZWxzZSBpZihlLm5hbWUgPT09ICdiYXNpY0NvbnN0cmFpbnRzJykgewogICAgICAvLyBoYW5kbGUgYmFzaWMgY29uc3RyYWludHMKICAgICAgLy8gZ2V0IHZhbHVlIGFzIFNFUVVFTkNFCiAgICAgIHZhciBldiA9IGFzbjEuZnJvbURlcihlLnZhbHVlKTsKICAgICAgLy8gZ2V0IGNBIEJPT0xFQU4gZmxhZyAoZGVmYXVsdHMgdG8gZmFsc2UpCiAgICAgIGlmKGV2LnZhbHVlLmxlbmd0aCA+IDAgJiYgZXYudmFsdWVbMF0udHlwZSA9PT0gYXNuMS5UeXBlLkJPT0xFQU4pIHsKICAgICAgICBlLmNBID0gKGV2LnZhbHVlWzBdLnZhbHVlLmNoYXJDb2RlQXQoMCkgIT09IDB4MDApOwogICAgICB9IGVsc2UgewogICAgICAgIGUuY0EgPSBmYWxzZTsKICAgICAgfQogICAgICAvLyBnZXQgcGF0aCBsZW5ndGggY29uc3RyYWludAogICAgICB2YXIgdmFsdWUgPSBudWxsOwogICAgICBpZihldi52YWx1ZS5sZW5ndGggPiAwICYmIGV2LnZhbHVlWzBdLnR5cGUgPT09IGFzbjEuVHlwZS5JTlRFR0VSKSB7CiAgICAgICAgdmFsdWUgPSBldi52YWx1ZVswXS52YWx1ZTsKICAgICAgfSBlbHNlIGlmKGV2LnZhbHVlLmxlbmd0aCA+IDEpIHsKICAgICAgICB2YWx1ZSA9IGV2LnZhbHVlWzFdLnZhbHVlOwogICAgICB9CiAgICAgIGlmKHZhbHVlICE9PSBudWxsKSB7CiAgICAgICAgZS5wYXRoTGVuQ29uc3RyYWludCA9IGFzbjEuZGVyVG9JbnRlZ2VyKHZhbHVlKTsKICAgICAgfQogICAgfSBlbHNlIGlmKGUubmFtZSA9PT0gJ2V4dEtleVVzYWdlJykgewogICAgICAvLyBoYW5kbGUgZXh0S2V5VXNhZ2UKICAgICAgLy8gdmFsdWUgaXMgYSBTRVFVRU5DRSBvZiBPSURzCiAgICAgIHZhciBldiA9IGFzbjEuZnJvbURlcihlLnZhbHVlKTsKICAgICAgZm9yKHZhciB2aSA9IDA7IHZpIDwgZXYudmFsdWUubGVuZ3RoOyArK3ZpKSB7CiAgICAgICAgdmFyIG9pZCA9IGFzbjEuZGVyVG9PaWQoZXYudmFsdWVbdmldLnZhbHVlKTsKICAgICAgICBpZihvaWQgaW4gb2lkcykgewogICAgICAgICAgZVtvaWRzW29pZF1dID0gdHJ1ZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgZVtvaWRdID0gdHJ1ZTsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSBpZihlLm5hbWUgPT09ICduc0NlcnRUeXBlJykgewogICAgICAvLyBoYW5kbGUgbnNDZXJ0VHlwZQogICAgICAvLyBnZXQgdmFsdWUgYXMgQklUIFNUUklORwogICAgICB2YXIgZXYgPSBhc24xLmZyb21EZXIoZS52YWx1ZSk7CiAgICAgIHZhciBiMiA9IDB4MDA7CiAgICAgIGlmKGV2LnZhbHVlLmxlbmd0aCA+IDEpIHsKICAgICAgICAvLyBza2lwIGZpcnN0IGJ5dGUsIGp1c3QgaW5kaWNhdGVzIHVudXNlZCBiaXRzIHdoaWNoCiAgICAgICAgLy8gd2lsbCBiZSBwYWRkZWQgd2l0aCAwcyBhbnl3YXkKICAgICAgICAvLyBnZXQgYnl0ZXMgd2l0aCBmbGFnIGJpdHMKICAgICAgICBiMiA9IGV2LnZhbHVlLmNoYXJDb2RlQXQoMSk7CiAgICAgIH0KICAgICAgLy8gc2V0IGZsYWdzCiAgICAgIGUuY2xpZW50ID0gKGIyICYgMHg4MCkgPT09IDB4ODA7CiAgICAgIGUuc2VydmVyID0gKGIyICYgMHg0MCkgPT09IDB4NDA7CiAgICAgIGUuZW1haWwgPSAoYjIgJiAweDIwKSA9PT0gMHgyMDsKICAgICAgZS5vYmpzaWduID0gKGIyICYgMHgxMCkgPT09IDB4MTA7CiAgICAgIGUucmVzZXJ2ZWQgPSAoYjIgJiAweDA4KSA9PT0gMHgwODsKICAgICAgZS5zc2xDQSA9IChiMiAmIDB4MDQpID09PSAweDA0OwogICAgICBlLmVtYWlsQ0EgPSAoYjIgJiAweDAyKSA9PT0gMHgwMjsKICAgICAgZS5vYmpDQSA9IChiMiAmIDB4MDEpID09PSAweDAxOwogICAgfSBlbHNlIGlmKAogICAgICBlLm5hbWUgPT09ICdzdWJqZWN0QWx0TmFtZScgfHwKICAgICAgZS5uYW1lID09PSAnaXNzdWVyQWx0TmFtZScpIHsKICAgICAgLy8gaGFuZGxlIHN1YmplY3RBbHROYW1lL2lzc3VlckFsdE5hbWUKICAgICAgZS5hbHROYW1lcyA9IFtdOwoKICAgICAgLy8gZXYgaXMgYSBTWU5UQVggU0VRVUVOQ0UKICAgICAgdmFyIGduOwogICAgICB2YXIgZXYgPSBhc24xLmZyb21EZXIoZS52YWx1ZSk7CiAgICAgIGZvcih2YXIgbiA9IDA7IG4gPCBldi52YWx1ZS5sZW5ndGg7ICsrbikgewogICAgICAgIC8vIGdldCBHZW5lcmFsTmFtZQogICAgICAgIGduID0gZXYudmFsdWVbbl07CgogICAgICAgIHZhciBhbHROYW1lID0gewogICAgICAgICAgdHlwZTogZ24udHlwZSwKICAgICAgICAgIHZhbHVlOiBnbi52YWx1ZQogICAgICAgIH07CiAgICAgICAgZS5hbHROYW1lcy5wdXNoKGFsdE5hbWUpOwoKICAgICAgICAvLyBOb3RlOiBTdXBwb3J0IGZvciB0eXBlcyAxLDIsNiw3LDgKICAgICAgICBzd2l0Y2goZ24udHlwZSkgewogICAgICAgIC8vIHJmYzgyMk5hbWUKICAgICAgICBjYXNlIDE6CiAgICAgICAgLy8gZE5TTmFtZQogICAgICAgIGNhc2UgMjoKICAgICAgICAvLyB1bmlmb3JtUmVzb3VyY2VJZGVudGlmaWVyIChVUkkpCiAgICAgICAgY2FzZSA2OgogICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gSVBBZGRyZXNzCiAgICAgICAgY2FzZSA3OgogICAgICAgICAgLy8gY29udmVydCB0byBJUHY0L0lQdjYgc3RyaW5nIHJlcHJlc2VudGF0aW9uCiAgICAgICAgICBhbHROYW1lLmlwID0gZm9yZ2UudXRpbC5ieXRlc1RvSVAoZ24udmFsdWUpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgLy8gcmVnaXN0ZXJlZElECiAgICAgICAgY2FzZSA4OgogICAgICAgICAgYWx0TmFtZS5vaWQgPSBhc24xLmRlclRvT2lkKGduLnZhbHVlKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAvLyB1bnN1cHBvcnRlZAogICAgICAgIH0KICAgICAgfQogICAgfSBlbHNlIGlmKGUubmFtZSA9PT0gJ3N1YmplY3RLZXlJZGVudGlmaWVyJykgewogICAgICAvLyB2YWx1ZSBpcyBhbiBPQ1RFVFNUUklORyB3L3RoZSBoYXNoIG9mIHRoZSBrZXktdHlwZSBzcGVjaWZpYwogICAgICAvLyBwdWJsaWMga2V5IHN0cnVjdHVyZSAoZWc6IFJTQVB1YmxpY0tleSkKICAgICAgdmFyIGV2ID0gYXNuMS5mcm9tRGVyKGUudmFsdWUpOwogICAgICBlLnN1YmplY3RLZXlJZGVudGlmaWVyID0gZm9yZ2UudXRpbC5ieXRlc1RvSGV4KGV2LnZhbHVlKTsKICAgIH0KICB9CiAgcmV0dXJuIGU7Cn07CgovKioKICogQ29udmVydHMgYSBQS0NTIzEwIGNlcnRpZmljYXRpb24gcmVxdWVzdCAoQ1NSKSBmcm9tIGFuIEFTTi4xIG9iamVjdC4KICoKICogTm90ZTogSWYgdGhlIGNlcnRpZmljYXRpb24gcmVxdWVzdCBpcyB0byBiZSB2ZXJpZmllZCB0aGVuIGNvbXB1dGUgaGFzaAogKiBzaG91bGQgYmUgc2V0IHRvIHRydWUuIFRoZXJlIGlzIGN1cnJlbnRseSBubyBpbXBsZW1lbnRhdGlvbiBmb3IgY29udmVydGluZwogKiBhIGNlcnRpZmljYXRlIGJhY2sgdG8gQVNOLjEgc28gdGhlIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyBwYXJ0IG9mIHRoZQogKiBBU04uMSBvYmplY3QgbmVlZHMgdG8gYmUgc2Nhbm5lZCBiZWZvcmUgdGhlIGNzciBvYmplY3QgaXMgY3JlYXRlZC4KICoKICogQHBhcmFtIG9iaiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIFBLQ1MjMTAgY2VydGlmaWNhdGlvbiByZXF1ZXN0IChDU1IpLgogKiBAcGFyYW0gY29tcHV0ZUhhc2ggdHJ1ZSB0byBjb21wdXRlIHRoZSBoYXNoIGZvciB2ZXJpZmljYXRpb24uCiAqCiAqIEByZXR1cm4gdGhlIGNlcnRpZmljYXRpb24gcmVxdWVzdCAoQ1NSKS4KICovCnBraS5jZXJ0aWZpY2F0aW9uUmVxdWVzdEZyb21Bc24xID0gZnVuY3Rpb24ob2JqLCBjb21wdXRlSGFzaCkgewogIC8vIHZhbGlkYXRlIGNlcnRpZmljYXRpb24gcmVxdWVzdCBhbmQgY2FwdHVyZSBkYXRhCiAgdmFyIGNhcHR1cmUgPSB7fTsKICB2YXIgZXJyb3JzID0gW107CiAgaWYoIWFzbjEudmFsaWRhdGUob2JqLCBjZXJ0aWZpY2F0aW9uUmVxdWVzdFZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzEwIGNlcnRpZmljYXRlIHJlcXVlc3QuICcgKwogICAgICAnQVNOLjEgb2JqZWN0IGlzIG5vdCBhIFBLQ1MjMTAgQ2VydGlmaWNhdGlvblJlcXVlc3QuJyk7CiAgICBlcnJvci5lcnJvcnMgPSBlcnJvcnM7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIC8vIGVuc3VyZSBzaWduYXR1cmUgaXMgbm90IGludGVycHJldGVkIGFzIGFuIGVtYmVkZGVkIEFTTi4xIG9iamVjdAogIGlmKHR5cGVvZiBjYXB0dXJlLmNzclNpZ25hdHVyZSAhPT0gJ3N0cmluZycpIHsKICAgIHZhciBjc3JTaWduYXR1cmUgPSAnXHgwMCc7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgY2FwdHVyZS5jc3JTaWduYXR1cmUubGVuZ3RoOyArK2kpIHsKICAgICAgY3NyU2lnbmF0dXJlICs9IGFzbjEudG9EZXIoY2FwdHVyZS5jc3JTaWduYXR1cmVbaV0pLmdldEJ5dGVzKCk7CiAgICB9CiAgICBjYXB0dXJlLmNzclNpZ25hdHVyZSA9IGNzclNpZ25hdHVyZTsKICB9CgogIC8vIGdldCBvaWQKICB2YXIgb2lkID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLnB1YmxpY0tleU9pZCk7CiAgaWYob2lkICE9PSBwa2kub2lkcy5yc2FFbmNyeXB0aW9uKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIHB1YmxpYyBrZXkuIE9JRCBpcyBub3QgUlNBLicpOwogIH0KCiAgLy8gY3JlYXRlIGNlcnRpZmljYXRpb24gcmVxdWVzdAogIHZhciBjc3IgPSBwa2kuY3JlYXRlQ2VydGlmaWNhdGlvblJlcXVlc3QoKTsKICBjc3IudmVyc2lvbiA9IGNhcHR1cmUuY3NyVmVyc2lvbiA/IGNhcHR1cmUuY3NyVmVyc2lvbi5jaGFyQ29kZUF0KDApIDogMDsKICBjc3Iuc2lnbmF0dXJlT2lkID0gZm9yZ2UuYXNuMS5kZXJUb09pZChjYXB0dXJlLmNzclNpZ25hdHVyZU9pZCk7CiAgY3NyLnNpZ25hdHVyZVBhcmFtZXRlcnMgPSBfcmVhZFNpZ25hdHVyZVBhcmFtZXRlcnMoCiAgICBjc3Iuc2lnbmF0dXJlT2lkLCBjYXB0dXJlLmNzclNpZ25hdHVyZVBhcmFtcywgdHJ1ZSk7CiAgY3NyLnNpZ2luZm8uYWxnb3JpdGhtT2lkID0gZm9yZ2UuYXNuMS5kZXJUb09pZChjYXB0dXJlLmNzclNpZ25hdHVyZU9pZCk7CiAgY3NyLnNpZ2luZm8ucGFyYW1ldGVycyA9IF9yZWFkU2lnbmF0dXJlUGFyYW1ldGVycygKICAgIGNzci5zaWdpbmZvLmFsZ29yaXRobU9pZCwgY2FwdHVyZS5jc3JTaWduYXR1cmVQYXJhbXMsIGZhbHNlKTsKICAvLyBza2lwICJ1bnVzZWQgYml0cyIgaW4gc2lnbmF0dXJlIHZhbHVlIEJJVFNUUklORwogIHZhciBzaWduYXR1cmUgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjYXB0dXJlLmNzclNpZ25hdHVyZSk7CiAgKytzaWduYXR1cmUucmVhZDsKICBjc3Iuc2lnbmF0dXJlID0gc2lnbmF0dXJlLmdldEJ5dGVzKCk7CgogIC8vIGtlZXAgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIHRvIHByZXNlcnZlIHNpZ25hdHVyZSB3aGVuIGV4cG9ydGluZwogIGNzci5jZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8gPSBjYXB0dXJlLmNlcnRpZmljYXRpb25SZXF1ZXN0SW5mbzsKCiAgaWYoY29tcHV0ZUhhc2gpIHsKICAgIC8vIGNoZWNrIHNpZ25hdHVyZSBPSUQgZm9yIHN1cHBvcnRlZCBzaWduYXR1cmUgdHlwZXMKICAgIGNzci5tZCA9IG51bGw7CiAgICBpZihjc3Iuc2lnbmF0dXJlT2lkIGluIG9pZHMpIHsKICAgICAgdmFyIG9pZCA9IG9pZHNbY3NyLnNpZ25hdHVyZU9pZF07CiAgICAgIHN3aXRjaChvaWQpIHsKICAgICAgY2FzZSAnc2hhMVdpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICBjc3IubWQgPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdtZDVXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgY3NyLm1kID0gZm9yZ2UubWQubWQ1LmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdzaGEyNTZXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgY3NyLm1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdzaGE1MTJXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgY3NyLm1kID0gZm9yZ2UubWQuc2hhNTEyLmNyZWF0ZSgpOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdSU0FTU0EtUFNTJzoKICAgICAgICBjc3IubWQgPSBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIGlmKGNzci5tZCA9PT0gbnVsbCkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb21wdXRlIGNlcnRpZmljYXRpb24gcmVxdWVzdCBkaWdlc3QuICcgKwogICAgICAgICdVbmtub3duIHNpZ25hdHVyZSBPSUQuJyk7CiAgICAgIGVycm9yLnNpZ25hdHVyZU9pZCA9IGNzci5zaWduYXR1cmVPaWQ7CiAgICAgIHRocm93IGVycm9yOwogICAgfQoKICAgIC8vIHByb2R1Y2UgREVSIGZvcm1hdHRlZCBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8gYW5kIGRpZ2VzdCBpdAogICAgdmFyIGJ5dGVzID0gYXNuMS50b0Rlcihjc3IuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvKTsKICAgIGNzci5tZC51cGRhdGUoYnl0ZXMuZ2V0Qnl0ZXMoKSk7CiAgfQoKICAvLyBoYW5kbGUgc3ViamVjdCwgYnVpbGQgc3ViamVjdCBtZXNzYWdlIGRpZ2VzdAogIHZhciBzbWQgPSBmb3JnZS5tZC5zaGExLmNyZWF0ZSgpOwogIGNzci5zdWJqZWN0LmdldEZpZWxkID0gZnVuY3Rpb24oc24pIHsKICAgIHJldHVybiBfZ2V0QXR0cmlidXRlKGNzci5zdWJqZWN0LCBzbik7CiAgfTsKICBjc3Iuc3ViamVjdC5hZGRGaWVsZCA9IGZ1bmN0aW9uKGF0dHIpIHsKICAgIF9maWxsTWlzc2luZ0ZpZWxkcyhbYXR0cl0pOwogICAgY3NyLnN1YmplY3QuYXR0cmlidXRlcy5wdXNoKGF0dHIpOwogIH07CiAgY3NyLnN1YmplY3QuYXR0cmlidXRlcyA9IHBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheSgKICAgIGNhcHR1cmUuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvU3ViamVjdCwgc21kKTsKICBjc3Iuc3ViamVjdC5oYXNoID0gc21kLmRpZ2VzdCgpLnRvSGV4KCk7CgogIC8vIGNvbnZlcnQgUlNBIHB1YmxpYyBrZXkgZnJvbSBBU04uMQogIGNzci5wdWJsaWNLZXkgPSBwa2kucHVibGljS2V5RnJvbUFzbjEoY2FwdHVyZS5zdWJqZWN0UHVibGljS2V5SW5mbyk7CgogIC8vIGNvbnZlcnQgYXR0cmlidXRlcyBmcm9tIEFTTi4xCiAgY3NyLmdldEF0dHJpYnV0ZSA9IGZ1bmN0aW9uKHNuKSB7CiAgICByZXR1cm4gX2dldEF0dHJpYnV0ZShjc3IsIHNuKTsKICB9OwogIGNzci5hZGRBdHRyaWJ1dGUgPSBmdW5jdGlvbihhdHRyKSB7CiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoW2F0dHJdKTsKICAgIGNzci5hdHRyaWJ1dGVzLnB1c2goYXR0cik7CiAgfTsKICBjc3IuYXR0cmlidXRlcyA9IHBraS5DUklBdHRyaWJ1dGVzQXNBcnJheSgKICAgIGNhcHR1cmUuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvQXR0cmlidXRlcyB8fCBbXSk7CgogIHJldHVybiBjc3I7Cn07CgovKioKICogQ3JlYXRlcyBhbiBlbXB0eSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QgKGEgQ1NSIG9yIGNlcnRpZmljYXRlIHNpZ25pbmcKICogcmVxdWVzdCkuIE9uY2UgY3JlYXRlZCwgaXRzIHB1YmxpYyBrZXkgYW5kIGF0dHJpYnV0ZXMgY2FuIGJlIHNldCBhbmQgdGhlbgogKiBpdCBjYW4gYmUgc2lnbmVkLgogKgogKiBAcmV0dXJuIHRoZSBlbXB0eSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QuCiAqLwpwa2kuY3JlYXRlQ2VydGlmaWNhdGlvblJlcXVlc3QgPSBmdW5jdGlvbigpIHsKICB2YXIgY3NyID0ge307CiAgY3NyLnZlcnNpb24gPSAweDAwOwogIGNzci5zaWduYXR1cmVPaWQgPSBudWxsOwogIGNzci5zaWduYXR1cmUgPSBudWxsOwogIGNzci5zaWdpbmZvID0ge307CiAgY3NyLnNpZ2luZm8uYWxnb3JpdGhtT2lkID0gbnVsbDsKCiAgY3NyLnN1YmplY3QgPSB7fTsKICBjc3Iuc3ViamVjdC5nZXRGaWVsZCA9IGZ1bmN0aW9uKHNuKSB7CiAgICByZXR1cm4gX2dldEF0dHJpYnV0ZShjc3Iuc3ViamVjdCwgc24pOwogIH07CiAgY3NyLnN1YmplY3QuYWRkRmllbGQgPSBmdW5jdGlvbihhdHRyKSB7CiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoW2F0dHJdKTsKICAgIGNzci5zdWJqZWN0LmF0dHJpYnV0ZXMucHVzaChhdHRyKTsKICB9OwogIGNzci5zdWJqZWN0LmF0dHJpYnV0ZXMgPSBbXTsKICBjc3Iuc3ViamVjdC5oYXNoID0gbnVsbDsKCiAgY3NyLnB1YmxpY0tleSA9IG51bGw7CiAgY3NyLmF0dHJpYnV0ZXMgPSBbXTsKICBjc3IuZ2V0QXR0cmlidXRlID0gZnVuY3Rpb24oc24pIHsKICAgIHJldHVybiBfZ2V0QXR0cmlidXRlKGNzciwgc24pOwogIH07CiAgY3NyLmFkZEF0dHJpYnV0ZSA9IGZ1bmN0aW9uKGF0dHIpIHsKICAgIF9maWxsTWlzc2luZ0ZpZWxkcyhbYXR0cl0pOwogICAgY3NyLmF0dHJpYnV0ZXMucHVzaChhdHRyKTsKICB9OwogIGNzci5tZCA9IG51bGw7CgogIC8qKgogICAqIFNldHMgdGhlIHN1YmplY3Qgb2YgdGhpcyBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QuCiAgICoKICAgKiBAcGFyYW0gYXR0cnMgdGhlIGFycmF5IG9mIHN1YmplY3QgYXR0cmlidXRlcyB0byB1c2UuCiAgICovCiAgY3NyLnNldFN1YmplY3QgPSBmdW5jdGlvbihhdHRycykgewogICAgLy8gc2V0IG5ldyBhdHRyaWJ1dGVzCiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoYXR0cnMpOwogICAgY3NyLnN1YmplY3QuYXR0cmlidXRlcyA9IGF0dHJzOwogICAgY3NyLnN1YmplY3QuaGFzaCA9IG51bGw7CiAgfTsKCiAgLyoqCiAgICogU2V0cyB0aGUgYXR0cmlidXRlcyBvZiB0aGlzIGNlcnRpZmljYXRpb24gcmVxdWVzdC4KICAgKgogICAqIEBwYXJhbSBhdHRycyB0aGUgYXJyYXkgb2YgYXR0cmlidXRlcyB0byB1c2UuCiAgICovCiAgY3NyLnNldEF0dHJpYnV0ZXMgPSBmdW5jdGlvbihhdHRycykgewogICAgLy8gc2V0IG5ldyBhdHRyaWJ1dGVzCiAgICBfZmlsbE1pc3NpbmdGaWVsZHMoYXR0cnMpOwogICAgY3NyLmF0dHJpYnV0ZXMgPSBhdHRyczsKICB9OwoKICAvKioKICAgKiBTaWducyB0aGlzIGNlcnRpZmljYXRpb24gcmVxdWVzdCB1c2luZyB0aGUgZ2l2ZW4gcHJpdmF0ZSBrZXkuCiAgICoKICAgKiBAcGFyYW0ga2V5IHRoZSBwcml2YXRlIGtleSB0byBzaWduIHdpdGguCiAgICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCBvYmplY3QgdG8gdXNlIChkZWZhdWx0cyB0byBmb3JnZS5tZC5zaGExKS4KICAgKi8KICBjc3Iuc2lnbiA9IGZ1bmN0aW9uKGtleSwgbWQpIHsKICAgIC8vIFRPRE86IGdldCBzaWduYXR1cmUgT0lEIGZyb20gcHJpdmF0ZSBrZXkKICAgIGNzci5tZCA9IG1kIHx8IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICB2YXIgYWxnb3JpdGhtT2lkID0gb2lkc1tjc3IubWQuYWxnb3JpdGhtICsgJ1dpdGhSU0FFbmNyeXB0aW9uJ107CiAgICBpZighYWxnb3JpdGhtT2lkKSB7CiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ291bGQgbm90IGNvbXB1dGUgY2VydGlmaWNhdGlvbiByZXF1ZXN0IGRpZ2VzdC4gJyArCiAgICAgICAgJ1Vua25vd24gbWVzc2FnZSBkaWdlc3QgYWxnb3JpdGhtIE9JRC4nKTsKICAgICAgZXJyb3IuYWxnb3JpdGhtID0gY3NyLm1kLmFsZ29yaXRobTsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CiAgICBjc3Iuc2lnbmF0dXJlT2lkID0gY3NyLnNpZ2luZm8uYWxnb3JpdGhtT2lkID0gYWxnb3JpdGhtT2lkOwoKICAgIC8vIGdldCBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8sIGNvbnZlcnQgdG8gREVSCiAgICBjc3IuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvID0gcGtpLmdldENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyhjc3IpOwogICAgdmFyIGJ5dGVzID0gYXNuMS50b0Rlcihjc3IuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvKTsKCiAgICAvLyBkaWdlc3QgYW5kIHNpZ24KICAgIGNzci5tZC51cGRhdGUoYnl0ZXMuZ2V0Qnl0ZXMoKSk7CiAgICBjc3Iuc2lnbmF0dXJlID0ga2V5LnNpZ24oY3NyLm1kKTsKICB9OwoKICAvKioKICAgKiBBdHRlbXB0cyB2ZXJpZnkgdGhlIHNpZ25hdHVyZSBvbiB0aGUgcGFzc2VkIGNlcnRpZmljYXRpb24gcmVxdWVzdCB1c2luZwogICAqIGl0cyBwdWJsaWMga2V5LgogICAqCiAgICogQSBDU1IgdGhhdCBoYXMgYmVlbiBleHBvcnRlZCB0byBhIGZpbGUgaW4gUEVNIGZvcm1hdCBjYW4gYmUgdmVyaWZpZWQgdXNpbmcKICAgKiBPcGVuU1NMIHVzaW5nIHRoaXMgY29tbWFuZDoKICAgKgogICAqIG9wZW5zc2wgcmVxIC1pbiA8dGhlLWNzci1wZW0tZmlsZT4gLXZlcmlmeSAtbm9vdXQgLXRleHQKICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB2ZXJpZmllZCwgZmFsc2UgaWYgbm90LgogICAqLwogIGNzci52ZXJpZnkgPSBmdW5jdGlvbigpIHsKICAgIHZhciBydmFsID0gZmFsc2U7CgogICAgdmFyIG1kID0gY3NyLm1kOwogICAgaWYobWQgPT09IG51bGwpIHsKICAgICAgLy8gY2hlY2sgc2lnbmF0dXJlIE9JRCBmb3Igc3VwcG9ydGVkIHNpZ25hdHVyZSB0eXBlcwogICAgICBpZihjc3Iuc2lnbmF0dXJlT2lkIGluIG9pZHMpIHsKICAgICAgICAvLyBUT0RPOiBjcmVhdGUgRFJZIGBPSUQgdG8gbWRgIGZ1bmN0aW9uCiAgICAgICAgdmFyIG9pZCA9IG9pZHNbY3NyLnNpZ25hdHVyZU9pZF07CiAgICAgICAgc3dpdGNoKG9pZCkgewogICAgICAgIGNhc2UgJ3NoYTFXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgICBtZCA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdtZDVXaXRoUlNBRW5jcnlwdGlvbic6CiAgICAgICAgICBtZCA9IGZvcmdlLm1kLm1kNS5jcmVhdGUoKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ3NoYTI1NldpdGhSU0FFbmNyeXB0aW9uJzoKICAgICAgICAgIG1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnc2hhNTEyV2l0aFJTQUVuY3J5cHRpb24nOgogICAgICAgICAgbWQgPSBmb3JnZS5tZC5zaGE1MTIuY3JlYXRlKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdSU0FTU0EtUFNTJzoKICAgICAgICAgIG1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmKG1kID09PSBudWxsKSB7CiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDb3VsZCBub3QgY29tcHV0ZSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QgZGlnZXN0LiAnICsKICAgICAgICAgICdVbmtub3duIHNpZ25hdHVyZSBPSUQuJyk7CiAgICAgICAgZXJyb3Iuc2lnbmF0dXJlT2lkID0gY3NyLnNpZ25hdHVyZU9pZDsKICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgfQoKICAgICAgLy8gcHJvZHVjZSBERVIgZm9ybWF0dGVkIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyBhbmQgZGlnZXN0IGl0CiAgICAgIHZhciBjcmkgPSBjc3IuY2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIHx8CiAgICAgICAgcGtpLmdldENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyhjc3IpOwogICAgICB2YXIgYnl0ZXMgPSBhc24xLnRvRGVyKGNyaSk7CiAgICAgIG1kLnVwZGF0ZShieXRlcy5nZXRCeXRlcygpKTsKICAgIH0KCiAgICBpZihtZCAhPT0gbnVsbCkgewogICAgICB2YXIgc2NoZW1lOwoKICAgICAgc3dpdGNoKGNzci5zaWduYXR1cmVPaWQpIHsKICAgICAgY2FzZSBvaWRzLnNoYTFXaXRoUlNBRW5jcnlwdGlvbjoKICAgICAgICAvKiB1c2UgUEtDUyMxIHYxLjUgcGFkZGluZyBzY2hlbWUgKi8KICAgICAgICBicmVhazsKICAgICAgY2FzZSBvaWRzWydSU0FTU0EtUFNTJ106CiAgICAgICAgdmFyIGhhc2gsIG1nZjsKCiAgICAgICAgLyogaW5pdGlhbGl6ZSBtZ2YgKi8KICAgICAgICBoYXNoID0gb2lkc1tjc3Iuc2lnbmF0dXJlUGFyYW1ldGVycy5tZ2YuaGFzaC5hbGdvcml0aG1PaWRdOwogICAgICAgIGlmKGhhc2ggPT09IHVuZGVmaW5lZCB8fCBmb3JnZS5tZFtoYXNoXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIE1HRiBoYXNoIGZ1bmN0aW9uLicpOwogICAgICAgICAgZXJyb3Iub2lkID0gY3NyLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmhhc2guYWxnb3JpdGhtT2lkOwogICAgICAgICAgZXJyb3IubmFtZSA9IGhhc2g7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CgogICAgICAgIG1nZiA9IG9pZHNbY3NyLnNpZ25hdHVyZVBhcmFtZXRlcnMubWdmLmFsZ29yaXRobU9pZF07CiAgICAgICAgaWYobWdmID09PSB1bmRlZmluZWQgfHwgZm9yZ2UubWdmW21nZl0gPT09IHVuZGVmaW5lZCkgewogICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBNR0YgZnVuY3Rpb24uJyk7CiAgICAgICAgICBlcnJvci5vaWQgPSBjc3Iuc2lnbmF0dXJlUGFyYW1ldGVycy5tZ2YuYWxnb3JpdGhtT2lkOwogICAgICAgICAgZXJyb3IubmFtZSA9IG1nZjsKICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgIH0KCiAgICAgICAgbWdmID0gZm9yZ2UubWdmW21nZl0uY3JlYXRlKGZvcmdlLm1kW2hhc2hdLmNyZWF0ZSgpKTsKCiAgICAgICAgLyogaW5pdGlhbGl6ZSBoYXNoIGZ1bmN0aW9uICovCiAgICAgICAgaGFzaCA9IG9pZHNbY3NyLnNpZ25hdHVyZVBhcmFtZXRlcnMuaGFzaC5hbGdvcml0aG1PaWRdOwogICAgICAgIGlmKGhhc2ggPT09IHVuZGVmaW5lZCB8fCBmb3JnZS5tZFtoYXNoXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIFJTQVNTQS1QU1MgaGFzaCBmdW5jdGlvbi4nKTsKICAgICAgICAgIGVycm9yLm9pZCA9IGNzci5zaWduYXR1cmVQYXJhbWV0ZXJzLmhhc2guYWxnb3JpdGhtT2lkOwogICAgICAgICAgZXJyb3IubmFtZSA9IGhhc2g7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CgogICAgICAgIHNjaGVtZSA9IGZvcmdlLnBzcy5jcmVhdGUoZm9yZ2UubWRbaGFzaF0uY3JlYXRlKCksIG1nZiwKICAgICAgICAgIGNzci5zaWduYXR1cmVQYXJhbWV0ZXJzLnNhbHRMZW5ndGgpOwogICAgICAgIGJyZWFrOwogICAgICB9CgogICAgICAvLyB2ZXJpZnkgc2lnbmF0dXJlIG9uIGNzciB1c2luZyBpdHMgcHVibGljIGtleQogICAgICBydmFsID0gY3NyLnB1YmxpY0tleS52ZXJpZnkoCiAgICAgICAgbWQuZGlnZXN0KCkuZ2V0Qnl0ZXMoKSwgY3NyLnNpZ25hdHVyZSwgc2NoZW1lKTsKICAgIH0KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICByZXR1cm4gY3NyOwp9OwoKLyoqCiAqIENvbnZlcnRzIGFuIFguNTA5IHN1YmplY3Qgb3IgaXNzdWVyIHRvIGFuIEFTTi4xIFJETlNlcXVlbmNlLgogKgogKiBAcGFyYW0gb2JqIHRoZSBzdWJqZWN0IG9yIGlzc3VlciAoZGlzdGluZ3Vpc2hlZCBuYW1lKS4KICoKICogQHJldHVybiB0aGUgQVNOLjEgUkROU2VxdWVuY2UuCiAqLwpmdW5jdGlvbiBfZG5Ub0FzbjEob2JqKSB7CiAgLy8gY3JlYXRlIGFuIGVtcHR5IFJETlNlcXVlbmNlCiAgdmFyIHJ2YWwgPSBhc24xLmNyZWF0ZSgKICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFtdKTsKCiAgLy8gaXRlcmF0ZSBvdmVyIGF0dHJpYnV0ZXMKICB2YXIgYXR0ciwgc2V0OwogIHZhciBhdHRycyA9IG9iai5hdHRyaWJ1dGVzOwogIGZvcih2YXIgaSA9IDA7IGkgPCBhdHRycy5sZW5ndGg7ICsraSkgewogICAgYXR0ciA9IGF0dHJzW2ldOwogICAgdmFyIHZhbHVlID0gYXR0ci52YWx1ZTsKCiAgICAvLyByZXVzZSB0YWcgY2xhc3MgZm9yIGF0dHJpYnV0ZSB2YWx1ZSBpZiBhdmFpbGFibGUKICAgIHZhciB2YWx1ZVRhZ0NsYXNzID0gYXNuMS5UeXBlLlBSSU5UQUJMRVNUUklORzsKICAgIGlmKCd2YWx1ZVRhZ0NsYXNzJyBpbiBhdHRyKSB7CiAgICAgIHZhbHVlVGFnQ2xhc3MgPSBhdHRyLnZhbHVlVGFnQ2xhc3M7CgogICAgICBpZih2YWx1ZVRhZ0NsYXNzID09PSBhc24xLlR5cGUuVVRGOCkgewogICAgICAgIHZhbHVlID0gZm9yZ2UudXRpbC5lbmNvZGVVdGY4KHZhbHVlKTsKICAgICAgfQogICAgICAvLyBGSVhNRTogaGFuZGxlIG1vcmUgZW5jb2RpbmdzCiAgICB9CgogICAgLy8gY3JlYXRlIGEgUmVsYXRpdmVEaXN0aW5ndWlzaGVkTmFtZSBzZXQKICAgIC8vIGVhY2ggdmFsdWUgaW4gdGhlIHNldCBpcyBhbiBBdHRyaWJ1dGVUeXBlQW5kVmFsdWUgZmlyc3QKICAgIC8vIGNvbnRhaW5pbmcgdGhlIHR5cGUgKGFuIE9JRCkgYW5kIHNlY29uZCB0aGUgdmFsdWUKICAgIHNldCA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VULCB0cnVlLCBbCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAvLyBBdHRyaWJ1dGVUeXBlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0RlcihhdHRyLnR5cGUpLmdldEJ5dGVzKCkpLAogICAgICAgIC8vIEF0dHJpYnV0ZVZhbHVlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIHZhbHVlVGFnQ2xhc3MsIGZhbHNlLCB2YWx1ZSkKICAgICAgXSkKICAgIF0pOwogICAgcnZhbC52YWx1ZS5wdXNoKHNldCk7CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIEdldHMgYWxsIHByaW50YWJsZSBhdHRyaWJ1dGVzICh0eXBpY2FsbHkgb2YgYW4gaXNzdWVyIG9yIHN1YmplY3QpIGluIGEKICogc2ltcGxpZmllZCBKU09OIGZvcm1hdCBmb3IgZGlzcGxheS4KICoKICogQHBhcmFtIGF0dHJzIHRoZSBhdHRyaWJ1dGVzLgogKgogKiBAcmV0dXJuIHRoZSBKU09OIGZvciBkaXNwbGF5LgogKi8KZnVuY3Rpb24gX2dldEF0dHJpYnV0ZXNBc0pzb24oYXR0cnMpIHsKICB2YXIgcnZhbCA9IHt9OwogIGZvcih2YXIgaSA9IDA7IGkgPCBhdHRycy5sZW5ndGg7ICsraSkgewogICAgdmFyIGF0dHIgPSBhdHRyc1tpXTsKICAgIGlmKGF0dHIuc2hvcnROYW1lICYmICgKICAgICAgYXR0ci52YWx1ZVRhZ0NsYXNzID09PSBhc24xLlR5cGUuVVRGOCB8fAogICAgICBhdHRyLnZhbHVlVGFnQ2xhc3MgPT09IGFzbjEuVHlwZS5QUklOVEFCTEVTVFJJTkcgfHwKICAgICAgYXR0ci52YWx1ZVRhZ0NsYXNzID09PSBhc24xLlR5cGUuSUE1U1RSSU5HKSkgewogICAgICB2YXIgdmFsdWUgPSBhdHRyLnZhbHVlOwogICAgICBpZihhdHRyLnZhbHVlVGFnQ2xhc3MgPT09IGFzbjEuVHlwZS5VVEY4KSB7CiAgICAgICAgdmFsdWUgPSBmb3JnZS51dGlsLmVuY29kZVV0ZjgoYXR0ci52YWx1ZSk7CiAgICAgIH0KICAgICAgaWYoIShhdHRyLnNob3J0TmFtZSBpbiBydmFsKSkgewogICAgICAgIHJ2YWxbYXR0ci5zaG9ydE5hbWVdID0gdmFsdWU7CiAgICAgIH0gZWxzZSBpZihmb3JnZS51dGlsLmlzQXJyYXkocnZhbFthdHRyLnNob3J0TmFtZV0pKSB7CiAgICAgICAgcnZhbFthdHRyLnNob3J0TmFtZV0ucHVzaCh2YWx1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcnZhbFthdHRyLnNob3J0TmFtZV0gPSBbcnZhbFthdHRyLnNob3J0TmFtZV0sIHZhbHVlXTsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIEZpbGxzIGluIG1pc3NpbmcgZmllbGRzIGluIGF0dHJpYnV0ZXMuCiAqCiAqIEBwYXJhbSBhdHRycyB0aGUgYXR0cmlidXRlcyB0byBmaWxsIG1pc3NpbmcgZmllbGRzIGluLgogKi8KZnVuY3Rpb24gX2ZpbGxNaXNzaW5nRmllbGRzKGF0dHJzKSB7CiAgdmFyIGF0dHI7CiAgZm9yKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgKytpKSB7CiAgICBhdHRyID0gYXR0cnNbaV07CgogICAgLy8gcG9wdWxhdGUgbWlzc2luZyBuYW1lCiAgICBpZih0eXBlb2YgYXR0ci5uYW1lID09PSAndW5kZWZpbmVkJykgewogICAgICBpZihhdHRyLnR5cGUgJiYgYXR0ci50eXBlIGluIHBraS5vaWRzKSB7CiAgICAgICAgYXR0ci5uYW1lID0gcGtpLm9pZHNbYXR0ci50eXBlXTsKICAgICAgfSBlbHNlIGlmKGF0dHIuc2hvcnROYW1lICYmIGF0dHIuc2hvcnROYW1lIGluIF9zaG9ydE5hbWVzKSB7CiAgICAgICAgYXR0ci5uYW1lID0gcGtpLm9pZHNbX3Nob3J0TmFtZXNbYXR0ci5zaG9ydE5hbWVdXTsKICAgICAgfQogICAgfQoKICAgIC8vIHBvcHVsYXRlIG1pc3NpbmcgdHlwZSAoT0lEKQogICAgaWYodHlwZW9mIGF0dHIudHlwZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgaWYoYXR0ci5uYW1lICYmIGF0dHIubmFtZSBpbiBwa2kub2lkcykgewogICAgICAgIGF0dHIudHlwZSA9IHBraS5vaWRzW2F0dHIubmFtZV07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdBdHRyaWJ1dGUgdHlwZSBub3Qgc3BlY2lmaWVkLicpOwogICAgICAgIGVycm9yLmF0dHJpYnV0ZSA9IGF0dHI7CiAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgIH0KICAgIH0KCiAgICAvLyBwb3B1bGF0ZSBtaXNzaW5nIHNob3J0bmFtZQogICAgaWYodHlwZW9mIGF0dHIuc2hvcnROYW1lID09PSAndW5kZWZpbmVkJykgewogICAgICBpZihhdHRyLm5hbWUgJiYgYXR0ci5uYW1lIGluIF9zaG9ydE5hbWVzKSB7CiAgICAgICAgYXR0ci5zaG9ydE5hbWUgPSBfc2hvcnROYW1lc1thdHRyLm5hbWVdOwogICAgICB9CiAgICB9CgogICAgLy8gY29udmVydCBleHRlbnNpb25zIHRvIHZhbHVlCiAgICBpZihhdHRyLnR5cGUgPT09IG9pZHMuZXh0ZW5zaW9uUmVxdWVzdCkgewogICAgICBhdHRyLnZhbHVlQ29uc3RydWN0ZWQgPSB0cnVlOwogICAgICBhdHRyLnZhbHVlVGFnQ2xhc3MgPSBhc24xLlR5cGUuU0VRVUVOQ0U7CiAgICAgIGlmKCFhdHRyLnZhbHVlICYmIGF0dHIuZXh0ZW5zaW9ucykgewogICAgICAgIGF0dHIudmFsdWUgPSBbXTsKICAgICAgICBmb3IodmFyIGVpID0gMDsgZWkgPCBhdHRyLmV4dGVuc2lvbnMubGVuZ3RoOyArK2VpKSB7CiAgICAgICAgICBhdHRyLnZhbHVlLnB1c2gocGtpLmNlcnRpZmljYXRlRXh0ZW5zaW9uVG9Bc24xKAogICAgICAgICAgICBfZmlsbE1pc3NpbmdFeHRlbnNpb25GaWVsZHMoYXR0ci5leHRlbnNpb25zW2VpXSkpKTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBpZih0eXBlb2YgYXR0ci52YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdBdHRyaWJ1dGUgdmFsdWUgbm90IHNwZWNpZmllZC4nKTsKICAgICAgZXJyb3IuYXR0cmlidXRlID0gYXR0cjsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CiAgfQp9CgovKioKICogRmlsbHMgaW4gbWlzc2luZyBmaWVsZHMgaW4gY2VydGlmaWNhdGUgZXh0ZW5zaW9ucy4KICoKICogQHBhcmFtIGUgdGhlIGV4dGVuc2lvbi4KICogQHBhcmFtIFtvcHRpb25zXSB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIFtjZXJ0XSB0aGUgY2VydGlmaWNhdGUgdGhlIGV4dGVuc2lvbnMgYXJlIGZvci4KICoKICogQHJldHVybiB0aGUgZXh0ZW5zaW9uLgogKi8KZnVuY3Rpb24gX2ZpbGxNaXNzaW5nRXh0ZW5zaW9uRmllbGRzKGUsIG9wdGlvbnMpIHsKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKCiAgLy8gcG9wdWxhdGUgbWlzc2luZyBuYW1lCiAgaWYodHlwZW9mIGUubmFtZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIGlmKGUuaWQgJiYgZS5pZCBpbiBwa2kub2lkcykgewogICAgICBlLm5hbWUgPSBwa2kub2lkc1tlLmlkXTsKICAgIH0KICB9CgogIC8vIHBvcHVsYXRlIG1pc3NpbmcgaWQKICBpZih0eXBlb2YgZS5pZCA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIGlmKGUubmFtZSAmJiBlLm5hbWUgaW4gcGtpLm9pZHMpIHsKICAgICAgZS5pZCA9IHBraS5vaWRzW2UubmFtZV07CiAgICB9IGVsc2UgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0V4dGVuc2lvbiBJRCBub3Qgc3BlY2lmaWVkLicpOwogICAgICBlcnJvci5leHRlbnNpb24gPSBlOwogICAgICB0aHJvdyBlcnJvcjsKICAgIH0KICB9CgogIGlmKHR5cGVvZiBlLnZhbHVlICE9PSAndW5kZWZpbmVkJykgewogICAgcmV0dXJuIGU7CiAgfQoKICAvLyBoYW5kbGUgbWlzc2luZyB2YWx1ZToKCiAgLy8gdmFsdWUgaXMgYSBCSVQgU1RSSU5HCiAgaWYoZS5uYW1lID09PSAna2V5VXNhZ2UnKSB7CiAgICAvLyBidWlsZCBmbGFncwogICAgdmFyIHVudXNlZCA9IDA7CiAgICB2YXIgYjIgPSAweDAwOwogICAgdmFyIGIzID0gMHgwMDsKICAgIGlmKGUuZGlnaXRhbFNpZ25hdHVyZSkgewogICAgICBiMiB8PSAweDgwOwogICAgICB1bnVzZWQgPSA3OwogICAgfQogICAgaWYoZS5ub25SZXB1ZGlhdGlvbikgewogICAgICBiMiB8PSAweDQwOwogICAgICB1bnVzZWQgPSA2OwogICAgfQogICAgaWYoZS5rZXlFbmNpcGhlcm1lbnQpIHsKICAgICAgYjIgfD0gMHgyMDsKICAgICAgdW51c2VkID0gNTsKICAgIH0KICAgIGlmKGUuZGF0YUVuY2lwaGVybWVudCkgewogICAgICBiMiB8PSAweDEwOwogICAgICB1bnVzZWQgPSA0OwogICAgfQogICAgaWYoZS5rZXlBZ3JlZW1lbnQpIHsKICAgICAgYjIgfD0gMHgwODsKICAgICAgdW51c2VkID0gMzsKICAgIH0KICAgIGlmKGUua2V5Q2VydFNpZ24pIHsKICAgICAgYjIgfD0gMHgwNDsKICAgICAgdW51c2VkID0gMjsKICAgIH0KICAgIGlmKGUuY1JMU2lnbikgewogICAgICBiMiB8PSAweDAyOwogICAgICB1bnVzZWQgPSAxOwogICAgfQogICAgaWYoZS5lbmNpcGhlck9ubHkpIHsKICAgICAgYjIgfD0gMHgwMTsKICAgICAgdW51c2VkID0gMDsKICAgIH0KICAgIGlmKGUuZGVjaXBoZXJPbmx5KSB7CiAgICAgIGIzIHw9IDB4ODA7CiAgICAgIHVudXNlZCA9IDc7CiAgICB9CgogICAgLy8gY3JlYXRlIGJpdCBzdHJpbmcKICAgIHZhciB2YWx1ZSA9IFN0cmluZy5mcm9tQ2hhckNvZGUodW51c2VkKTsKICAgIGlmKGIzICE9PSAwKSB7CiAgICAgIHZhbHVlICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoYjIpICsgU3RyaW5nLmZyb21DaGFyQ29kZShiMyk7CiAgICB9IGVsc2UgaWYoYjIgIT09IDApIHsKICAgICAgdmFsdWUgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShiMik7CiAgICB9CiAgICBlLnZhbHVlID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuQklUU1RSSU5HLCBmYWxzZSwgdmFsdWUpOwogIH0gZWxzZSBpZihlLm5hbWUgPT09ICdiYXNpY0NvbnN0cmFpbnRzJykgewogICAgLy8gYmFzaWNDb25zdHJhaW50cyBpcyBhIFNFUVVFTkNFCiAgICBlLnZhbHVlID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFtdKTsKICAgIC8vIGNBIEJPT0xFQU4gZmxhZyBkZWZhdWx0cyB0byBmYWxzZQogICAgaWYoZS5jQSkgewogICAgICBlLnZhbHVlLnZhbHVlLnB1c2goYXNuMS5jcmVhdGUoCiAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CT09MRUFOLCBmYWxzZSwKICAgICAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4RkYpKSk7CiAgICB9CiAgICBpZigncGF0aExlbkNvbnN0cmFpbnQnIGluIGUpIHsKICAgICAgZS52YWx1ZS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIoZS5wYXRoTGVuQ29uc3RyYWludCkuZ2V0Qnl0ZXMoKSkpOwogICAgfQogIH0gZWxzZSBpZihlLm5hbWUgPT09ICdleHRLZXlVc2FnZScpIHsKICAgIC8vIGV4dEtleVVzYWdlIGlzIGEgU0VRVUVOQ0Ugb2YgT0lEcwogICAgZS52YWx1ZSA9IGFzbjEuY3JlYXRlKAogICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbXSk7CiAgICB2YXIgc2VxID0gZS52YWx1ZS52YWx1ZTsKICAgIGZvcih2YXIga2V5IGluIGUpIHsKICAgICAgaWYoZVtrZXldICE9PSB0cnVlKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgLy8ga2V5IGlzIG5hbWUgaW4gT0lEIG1hcAogICAgICBpZihrZXkgaW4gb2lkcykgewogICAgICAgIHNlcS5wdXNoKGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELAogICAgICAgICAgZmFsc2UsIGFzbjEub2lkVG9EZXIob2lkc1trZXldKS5nZXRCeXRlcygpKSk7CiAgICAgIH0gZWxzZSBpZihrZXkuaW5kZXhPZignLicpICE9PSAtMSkgewogICAgICAgIC8vIGFzc3VtZSBrZXkgaXMgYW4gT0lECiAgICAgICAgc2VxLnB1c2goYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsCiAgICAgICAgICBmYWxzZSwgYXNuMS5vaWRUb0RlcihrZXkpLmdldEJ5dGVzKCkpKTsKICAgICAgfQogICAgfQogIH0gZWxzZSBpZihlLm5hbWUgPT09ICduc0NlcnRUeXBlJykgewogICAgLy8gbnNDZXJ0VHlwZSBpcyBhIEJJVCBTVFJJTkcKICAgIC8vIGJ1aWxkIGZsYWdzCiAgICB2YXIgdW51c2VkID0gMDsKICAgIHZhciBiMiA9IDB4MDA7CgogICAgaWYoZS5jbGllbnQpIHsKICAgICAgYjIgfD0gMHg4MDsKICAgICAgdW51c2VkID0gNzsKICAgIH0KICAgIGlmKGUuc2VydmVyKSB7CiAgICAgIGIyIHw9IDB4NDA7CiAgICAgIHVudXNlZCA9IDY7CiAgICB9CiAgICBpZihlLmVtYWlsKSB7CiAgICAgIGIyIHw9IDB4MjA7CiAgICAgIHVudXNlZCA9IDU7CiAgICB9CiAgICBpZihlLm9ianNpZ24pIHsKICAgICAgYjIgfD0gMHgxMDsKICAgICAgdW51c2VkID0gNDsKICAgIH0KICAgIGlmKGUucmVzZXJ2ZWQpIHsKICAgICAgYjIgfD0gMHgwODsKICAgICAgdW51c2VkID0gMzsKICAgIH0KICAgIGlmKGUuc3NsQ0EpIHsKICAgICAgYjIgfD0gMHgwNDsKICAgICAgdW51c2VkID0gMjsKICAgIH0KICAgIGlmKGUuZW1haWxDQSkgewogICAgICBiMiB8PSAweDAyOwogICAgICB1bnVzZWQgPSAxOwogICAgfQogICAgaWYoZS5vYmpDQSkgewogICAgICBiMiB8PSAweDAxOwogICAgICB1bnVzZWQgPSAwOwogICAgfQoKICAgIC8vIGNyZWF0ZSBiaXQgc3RyaW5nCiAgICB2YXIgdmFsdWUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKHVudXNlZCk7CiAgICBpZihiMiAhPT0gMCkgewogICAgICB2YWx1ZSArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGIyKTsKICAgIH0KICAgIGUudmFsdWUgPSBhc24xLmNyZWF0ZSgKICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CSVRTVFJJTkcsIGZhbHNlLCB2YWx1ZSk7CiAgfSBlbHNlIGlmKGUubmFtZSA9PT0gJ3N1YmplY3RBbHROYW1lJyB8fCBlLm5hbWUgPT09ICdpc3N1ZXJBbHROYW1lJykgewogICAgLy8gU1lOVEFYIFNFUVVFTkNFCiAgICBlLnZhbHVlID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgW10pOwoKICAgIHZhciBhbHROYW1lOwogICAgZm9yKHZhciBuID0gMDsgbiA8IGUuYWx0TmFtZXMubGVuZ3RoOyArK24pIHsKICAgICAgYWx0TmFtZSA9IGUuYWx0TmFtZXNbbl07CiAgICAgIHZhciB2YWx1ZSA9IGFsdE5hbWUudmFsdWU7CiAgICAgIC8vIGhhbmRsZSBJUAogICAgICBpZihhbHROYW1lLnR5cGUgPT09IDcgJiYgYWx0TmFtZS5pcCkgewogICAgICAgIHZhbHVlID0gZm9yZ2UudXRpbC5ieXRlc0Zyb21JUChhbHROYW1lLmlwKTsKICAgICAgICBpZih2YWx1ZSA9PT0gbnVsbCkgewogICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKAogICAgICAgICAgICAnRXh0ZW5zaW9uICJpcCIgdmFsdWUgaXMgbm90IGEgdmFsaWQgSVB2NCBvciBJUHY2IGFkZHJlc3MuJyk7CiAgICAgICAgICBlcnJvci5leHRlbnNpb24gPSBlOwogICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYoYWx0TmFtZS50eXBlID09PSA4KSB7CiAgICAgICAgLy8gaGFuZGxlIE9JRAogICAgICAgIGlmKGFsdE5hbWUub2lkKSB7CiAgICAgICAgICB2YWx1ZSA9IGFzbjEub2lkVG9EZXIoYXNuMS5vaWRUb0RlcihhbHROYW1lLm9pZCkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvLyBkZXByZWNhdGVkIC4uLiBjb252ZXJ0IHZhbHVlIHRvIE9JRAogICAgICAgICAgdmFsdWUgPSBhc24xLm9pZFRvRGVyKHZhbHVlKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgZS52YWx1ZS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgICAgIGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgYWx0TmFtZS50eXBlLCBmYWxzZSwKICAgICAgICB2YWx1ZSkpOwogICAgfQogIH0gZWxzZSBpZihlLm5hbWUgPT09ICdzdWJqZWN0S2V5SWRlbnRpZmllcicgJiYgb3B0aW9ucy5jZXJ0KSB7CiAgICB2YXIgc2tpID0gb3B0aW9ucy5jZXJ0LmdlbmVyYXRlU3ViamVjdEtleUlkZW50aWZpZXIoKTsKICAgIGUuc3ViamVjdEtleUlkZW50aWZpZXIgPSBza2kudG9IZXgoKTsKICAgIC8vIE9DVEVUU1RSSU5HIHcvZGlnZXN0CiAgICBlLnZhbHVlID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLCBza2kuZ2V0Qnl0ZXMoKSk7CiAgfQoKICAvLyBlbnN1cmUgdmFsdWUgaGFzIGJlZW4gZGVmaW5lZCBieSBub3cKICBpZih0eXBlb2YgZS52YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignRXh0ZW5zaW9uIHZhbHVlIG5vdCBzcGVjaWZpZWQuJyk7CiAgICBlcnJvci5leHRlbnNpb24gPSBlOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICByZXR1cm4gZTsKfQoKLyoqCiAqIENvbnZlcnQgc2lnbmF0dXJlIHBhcmFtZXRlcnMgb2JqZWN0IHRvIEFTTi4xCiAqCiAqIEBwYXJhbSB7U3RyaW5nfSBvaWQgU2lnbmF0dXJlIGFsZ29yaXRobSBPSUQKICogQHBhcmFtIHBhcmFtcyBUaGUgc2lnbmF0dXJlIHBhcmFtZXRycyBvYmplY3QKICogQHJldHVybiBBU04uMSBvYmplY3QgcmVwcmVzZW50aW5nIHNpZ25hdHVyZSBwYXJhbWV0ZXJzCiAqLwpmdW5jdGlvbiBfc2lnbmF0dXJlUGFyYW1ldGVyc1RvQXNuMShvaWQsIHBhcmFtcykgewogIHN3aXRjaChvaWQpIHsKICBjYXNlIG9pZHNbJ1JTQVNTQS1QU1MnXToKICAgIHZhciBwYXJ0cyA9IFtdOwoKICAgIGlmKHBhcmFtcy5oYXNoLmFsZ29yaXRobU9pZCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgIHBhcnRzLnB1c2goYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgICBhc24xLm9pZFRvRGVyKHBhcmFtcy5oYXNoLmFsZ29yaXRobU9pZCkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgICAgICBdKQogICAgICBdKSk7CiAgICB9CgogICAgaWYocGFyYW1zLm1nZi5hbGdvcml0aG1PaWQgIT09IHVuZGVmaW5lZCkgewogICAgICBwYXJ0cy5wdXNoKGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMSwgdHJ1ZSwgWwogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgICAgYXNuMS5vaWRUb0RlcihwYXJhbXMubWdmLmFsZ29yaXRobU9pZCkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgICAgICBhc24xLm9pZFRvRGVyKHBhcmFtcy5tZ2YuaGFzaC5hbGdvcml0aG1PaWQpLmdldEJ5dGVzKCkpLAogICAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgICAgICAgIF0pCiAgICAgICAgXSkKICAgICAgXSkpOwogICAgfQoKICAgIGlmKHBhcmFtcy5zYWx0TGVuZ3RoICE9PSB1bmRlZmluZWQpIHsKICAgICAgcGFydHMucHVzaChhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDIsIHRydWUsIFsKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIocGFyYW1zLnNhbHRMZW5ndGgpLmdldEJ5dGVzKCkpCiAgICAgIF0pKTsKICAgIH0KCiAgICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgcGFydHMpOwoKICBkZWZhdWx0OgogICAgcmV0dXJuIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuTlVMTCwgZmFsc2UsICcnKTsKICB9Cn0KCi8qKgogKiBDb252ZXJ0cyBhIGNlcnRpZmljYXRpb24gcmVxdWVzdCdzIGF0dHJpYnV0ZXMgdG8gYW4gQVNOLjEgc2V0IG9mCiAqIENSSUF0dHJpYnV0ZXMuCiAqCiAqIEBwYXJhbSBjc3IgY2VydGlmaWNhdGlvbiByZXF1ZXN0LgogKgogKiBAcmV0dXJuIHRoZSBBU04uMSBzZXQgb2YgQ1JJQXR0cmlidXRlcy4KICovCmZ1bmN0aW9uIF9DUklBdHRyaWJ1dGVzVG9Bc24xKGNzcikgewogIC8vIGNyZWF0ZSBhbiBlbXB0eSBjb250ZXh0LXNwZWNpZmljIGNvbnRhaW5lcgogIHZhciBydmFsID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbXSk7CgogIC8vIG5vIGF0dHJpYnV0ZXMsIHJldHVybiBlbXB0eSBjb250YWluZXIKICBpZihjc3IuYXR0cmlidXRlcy5sZW5ndGggPT09IDApIHsKICAgIHJldHVybiBydmFsOwogIH0KCiAgLy8gZWFjaCBhdHRyaWJ1dGUgaGFzIGEgc2VxdWVuY2Ugd2l0aCBhIHR5cGUgYW5kIGEgc2V0IG9mIHZhbHVlcwogIHZhciBhdHRycyA9IGNzci5hdHRyaWJ1dGVzOwogIGZvcih2YXIgaSA9IDA7IGkgPCBhdHRycy5sZW5ndGg7ICsraSkgewogICAgdmFyIGF0dHIgPSBhdHRyc1tpXTsKICAgIHZhciB2YWx1ZSA9IGF0dHIudmFsdWU7CgogICAgLy8gcmV1c2UgdGFnIGNsYXNzIGZvciBhdHRyaWJ1dGUgdmFsdWUgaWYgYXZhaWxhYmxlCiAgICB2YXIgdmFsdWVUYWdDbGFzcyA9IGFzbjEuVHlwZS5VVEY4OwogICAgaWYoJ3ZhbHVlVGFnQ2xhc3MnIGluIGF0dHIpIHsKICAgICAgdmFsdWVUYWdDbGFzcyA9IGF0dHIudmFsdWVUYWdDbGFzczsKICAgIH0KICAgIGlmKHZhbHVlVGFnQ2xhc3MgPT09IGFzbjEuVHlwZS5VVEY4KSB7CiAgICAgIHZhbHVlID0gZm9yZ2UudXRpbC5lbmNvZGVVdGY4KHZhbHVlKTsKICAgIH0KICAgIHZhciB2YWx1ZUNvbnN0cnVjdGVkID0gZmFsc2U7CiAgICBpZigndmFsdWVDb25zdHJ1Y3RlZCcgaW4gYXR0cikgewogICAgICB2YWx1ZUNvbnN0cnVjdGVkID0gYXR0ci52YWx1ZUNvbnN0cnVjdGVkOwogICAgfQogICAgLy8gRklYTUU6IGhhbmRsZSBtb3JlIGVuY29kaW5ncwoKICAgIC8vIGNyZWF0ZSBhIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUgc2V0CiAgICAvLyBlYWNoIHZhbHVlIGluIHRoZSBzZXQgaXMgYW4gQXR0cmlidXRlVHlwZUFuZFZhbHVlIGZpcnN0CiAgICAvLyBjb250YWluaW5nIHRoZSB0eXBlIChhbiBPSUQpIGFuZCBzZWNvbmQgdGhlIHZhbHVlCiAgICB2YXIgc2VxID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAvLyBBdHRyaWJ1dGVUeXBlCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICBhc24xLm9pZFRvRGVyKGF0dHIudHlwZSkuZ2V0Qnl0ZXMoKSksCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VULCB0cnVlLCBbCiAgICAgICAgLy8gQXR0cmlidXRlVmFsdWUKICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCB2YWx1ZVRhZ0NsYXNzLCB2YWx1ZUNvbnN0cnVjdGVkLCB2YWx1ZSkKICAgICAgXSkKICAgIF0pOwogICAgcnZhbC52YWx1ZS5wdXNoKHNlcSk7CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIEdldHMgdGhlIEFTTi4xIFRCU0NlcnRpZmljYXRlIHBhcnQgb2YgYW4gWC41MDl2MyBjZXJ0aWZpY2F0ZS4KICoKICogQHBhcmFtIGNlcnQgdGhlIGNlcnRpZmljYXRlLgogKgogKiBAcmV0dXJuIHRoZSBhc24xIFRCU0NlcnRpZmljYXRlLgogKi8KcGtpLmdldFRCU0NlcnRpZmljYXRlID0gZnVuY3Rpb24oY2VydCkgewogIC8vIFRCU0NlcnRpZmljYXRlCiAgdmFyIHRicyA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgIC8vIHZlcnNpb24KICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgWwogICAgICAvLyBpbnRlZ2VyCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIoY2VydC52ZXJzaW9uKS5nZXRCeXRlcygpKQogICAgXSksCiAgICAvLyBzZXJpYWxOdW1iZXIKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIGZvcmdlLnV0aWwuaGV4VG9CeXRlcyhjZXJ0LnNlcmlhbE51bWJlcikpLAogICAgLy8gc2lnbmF0dXJlCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIGFsZ29yaXRobQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0RlcihjZXJ0LnNpZ2luZm8uYWxnb3JpdGhtT2lkKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGFyYW1ldGVycwogICAgICBfc2lnbmF0dXJlUGFyYW1ldGVyc1RvQXNuMSgKICAgICAgICBjZXJ0LnNpZ2luZm8uYWxnb3JpdGhtT2lkLCBjZXJ0LnNpZ2luZm8ucGFyYW1ldGVycykKICAgIF0pLAogICAgLy8gaXNzdWVyCiAgICBfZG5Ub0FzbjEoY2VydC5pc3N1ZXIpLAogICAgLy8gdmFsaWRpdHkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgLy8gbm90QmVmb3JlCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuVVRDVElNRSwgZmFsc2UsCiAgICAgICAgYXNuMS5kYXRlVG9VdGNUaW1lKGNlcnQudmFsaWRpdHkubm90QmVmb3JlKSksCiAgICAgIC8vIG5vdEFmdGVyCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuVVRDVElNRSwgZmFsc2UsCiAgICAgICAgYXNuMS5kYXRlVG9VdGNUaW1lKGNlcnQudmFsaWRpdHkubm90QWZ0ZXIpKQogICAgXSksCiAgICAvLyBzdWJqZWN0CiAgICBfZG5Ub0FzbjEoY2VydC5zdWJqZWN0KSwKICAgIC8vIFN1YmplY3RQdWJsaWNLZXlJbmZvCiAgICBwa2kucHVibGljS2V5VG9Bc24xKGNlcnQucHVibGljS2V5KQogIF0pOwoKICBpZihjZXJ0Lmlzc3Vlci51bmlxdWVJZCkgewogICAgLy8gaXNzdWVyVW5pcXVlSUQgKG9wdGlvbmFsKQogICAgdGJzLnZhbHVlLnB1c2goCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMSwgdHJ1ZSwgWwogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuQklUU1RSSU5HLCBmYWxzZSwKICAgICAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwMCkgKwogICAgICAgICAgY2VydC5pc3N1ZXIudW5pcXVlSWQKICAgICAgICApCiAgICAgIF0pCiAgICApOwogIH0KICBpZihjZXJ0LnN1YmplY3QudW5pcXVlSWQpIHsKICAgIC8vIHN1YmplY3RVbmlxdWVJRCAob3B0aW9uYWwpCiAgICB0YnMudmFsdWUucHVzaCgKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAyLCB0cnVlLCBbCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CSVRTVFJJTkcsIGZhbHNlLAogICAgICAgICAgU3RyaW5nLmZyb21DaGFyQ29kZSgweDAwKSArCiAgICAgICAgICBjZXJ0LnN1YmplY3QudW5pcXVlSWQKICAgICAgICApCiAgICAgIF0pCiAgICApOwogIH0KCiAgaWYoY2VydC5leHRlbnNpb25zLmxlbmd0aCA+IDApIHsKICAgIC8vIGV4dGVuc2lvbnMgKG9wdGlvbmFsKQogICAgdGJzLnZhbHVlLnB1c2gocGtpLmNlcnRpZmljYXRlRXh0ZW5zaW9uc1RvQXNuMShjZXJ0LmV4dGVuc2lvbnMpKTsKICB9CgogIHJldHVybiB0YnM7Cn07CgovKioKICogR2V0cyB0aGUgQVNOLjEgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIHBhcnQgb2YgYQogKiBQS0NTIzEwIENlcnRpZmljYXRpb25SZXF1ZXN0LgogKgogKiBAcGFyYW0gY3NyIHRoZSBjZXJ0aWZpY2F0aW9uIHJlcXVlc3QuCiAqCiAqIEByZXR1cm4gdGhlIGFzbjEgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvLgogKi8KcGtpLmdldENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyA9IGZ1bmN0aW9uKGNzcikgewogIC8vIENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbwogIHZhciBjcmkgPSBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyB2ZXJzaW9uCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICBhc24xLmludGVnZXJUb0Rlcihjc3IudmVyc2lvbikuZ2V0Qnl0ZXMoKSksCiAgICAvLyBzdWJqZWN0CiAgICBfZG5Ub0FzbjEoY3NyLnN1YmplY3QpLAogICAgLy8gU3ViamVjdFB1YmxpY0tleUluZm8KICAgIHBraS5wdWJsaWNLZXlUb0FzbjEoY3NyLnB1YmxpY0tleSksCiAgICAvLyBhdHRyaWJ1dGVzCiAgICBfQ1JJQXR0cmlidXRlc1RvQXNuMShjc3IpCiAgXSk7CgogIHJldHVybiBjcmk7Cn07CgovKioKICogQ29udmVydHMgYSBEaXN0aW5ndWlzaGVkTmFtZSAoc3ViamVjdCBvciBpc3N1ZXIpIHRvIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIGRuIHRoZSBEaXN0aW5ndWlzaGVkTmFtZS4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIERpc3Rpbmd1aXNoZWROYW1lLgogKi8KcGtpLmRpc3Rpbmd1aXNoZWROYW1lVG9Bc24xID0gZnVuY3Rpb24oZG4pIHsKICByZXR1cm4gX2RuVG9Bc24xKGRuKTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhbiBYLjUwOXYzIFJTQSBjZXJ0aWZpY2F0ZSB0byBhbiBBU04uMSBvYmplY3QuCiAqCiAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZS4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhbiBYLjUwOXYzIFJTQSBjZXJ0aWZpY2F0ZS4KICovCnBraS5jZXJ0aWZpY2F0ZVRvQXNuMSA9IGZ1bmN0aW9uKGNlcnQpIHsKICAvLyBwcmVmZXIgY2FjaGVkIFRCU0NlcnRpZmljYXRlIG92ZXIgZ2VuZXJhdGluZyBvbmUKICB2YXIgdGJzQ2VydGlmaWNhdGUgPSBjZXJ0LnRic0NlcnRpZmljYXRlIHx8IHBraS5nZXRUQlNDZXJ0aWZpY2F0ZShjZXJ0KTsKCiAgLy8gQ2VydGlmaWNhdGUKICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gVEJTQ2VydGlmaWNhdGUKICAgIHRic0NlcnRpZmljYXRlLAogICAgLy8gQWxnb3JpdGhtSWRlbnRpZmllciAoc2lnbmF0dXJlIGFsZ29yaXRobSkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgLy8gYWxnb3JpdGhtCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICBhc24xLm9pZFRvRGVyKGNlcnQuc2lnbmF0dXJlT2lkKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGFyYW1ldGVycwogICAgICBfc2lnbmF0dXJlUGFyYW1ldGVyc1RvQXNuMShjZXJ0LnNpZ25hdHVyZU9pZCwgY2VydC5zaWduYXR1cmVQYXJhbWV0ZXJzKQogICAgXSksCiAgICAvLyBTaWduYXR1cmVWYWx1ZQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CSVRTVFJJTkcsIGZhbHNlLAogICAgICBTdHJpbmcuZnJvbUNoYXJDb2RlKDB4MDApICsgY2VydC5zaWduYXR1cmUpCiAgXSk7Cn07CgovKioKICogQ29udmVydHMgWC41MDl2MyBjZXJ0aWZpY2F0ZSBleHRlbnNpb25zIHRvIEFTTi4xLgogKgogKiBAcGFyYW0gZXh0cyB0aGUgZXh0ZW5zaW9ucyB0byBjb252ZXJ0LgogKgogKiBAcmV0dXJuIHRoZSBleHRlbnNpb25zIGluIEFTTi4xIGZvcm1hdC4KICovCnBraS5jZXJ0aWZpY2F0ZUV4dGVuc2lvbnNUb0FzbjEgPSBmdW5jdGlvbihleHRzKSB7CiAgLy8gY3JlYXRlIHRvcC1sZXZlbCBleHRlbnNpb24gY29udGFpbmVyCiAgdmFyIHJ2YWwgPSBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDMsIHRydWUsIFtdKTsKCiAgLy8gY3JlYXRlIGV4dGVuc2lvbiBzZXF1ZW5jZSAoc3RvcmVzIGEgc2VxdWVuY2UgZm9yIGVhY2ggZXh0ZW5zaW9uKQogIHZhciBzZXEgPSBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbXSk7CiAgcnZhbC52YWx1ZS5wdXNoKHNlcSk7CgogIGZvcih2YXIgaSA9IDA7IGkgPCBleHRzLmxlbmd0aDsgKytpKSB7CiAgICBzZXEudmFsdWUucHVzaChwa2kuY2VydGlmaWNhdGVFeHRlbnNpb25Ub0FzbjEoZXh0c1tpXSkpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ29udmVydHMgYSBzaW5nbGUgY2VydGlmaWNhdGUgZXh0ZW5zaW9uIHRvIEFTTi4xLgogKgogKiBAcGFyYW0gZXh0IHRoZSBleHRlbnNpb24gdG8gY29udmVydC4KICoKICogQHJldHVybiB0aGUgZXh0ZW5zaW9uIGluIEFTTi4xIGZvcm1hdC4KICovCnBraS5jZXJ0aWZpY2F0ZUV4dGVuc2lvblRvQXNuMSA9IGZ1bmN0aW9uKGV4dCkgewogIC8vIGNyZWF0ZSBhIHNlcXVlbmNlIGZvciBlYWNoIGV4dGVuc2lvbgogIHZhciBleHRzZXEgPSBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbXSk7CgogIC8vIGV4dG5JRCAoT0lEKQogIGV4dHNlcS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgYXNuMS5vaWRUb0RlcihleHQuaWQpLmdldEJ5dGVzKCkpKTsKCiAgLy8gY3JpdGljYWwgZGVmYXVsdHMgdG8gZmFsc2UKICBpZihleHQuY3JpdGljYWwpIHsKICAgIC8vIGNyaXRpY2FsIEJPT0xFQU4gREVGQVVMVCBGQUxTRQogICAgZXh0c2VxLnZhbHVlLnB1c2goYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuQk9PTEVBTiwgZmFsc2UsCiAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoMHhGRikpKTsKICB9CgogIHZhciB2YWx1ZSA9IGV4dC52YWx1ZTsKICBpZih0eXBlb2YgZXh0LnZhbHVlICE9PSAnc3RyaW5nJykgewogICAgLy8gdmFsdWUgaXMgYXNuLjEKICAgIHZhbHVlID0gYXNuMS50b0Rlcih2YWx1ZSkuZ2V0Qnl0ZXMoKTsKICB9CgogIC8vIGV4dG5WYWx1ZSAoT0NURVQgU1RSSU5HKQogIGV4dHNlcS52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIHZhbHVlKSk7CgogIHJldHVybiBleHRzZXE7Cn07CgovKioKICogQ29udmVydHMgYSBQS0NTIzEwIGNlcnRpZmljYXRpb24gcmVxdWVzdCB0byBhbiBBU04uMSBvYmplY3QuCiAqCiAqIEBwYXJhbSBjc3IgdGhlIGNlcnRpZmljYXRpb24gcmVxdWVzdC4KICoKICogQHJldHVybiB0aGUgYXNuMSByZXByZXNlbnRhdGlvbiBvZiBhIGNlcnRpZmljYXRpb24gcmVxdWVzdC4KICovCnBraS5jZXJ0aWZpY2F0aW9uUmVxdWVzdFRvQXNuMSA9IGZ1bmN0aW9uKGNzcikgewogIC8vIHByZWZlciBjYWNoZWQgQ2VydGlmaWNhdGlvblJlcXVlc3RJbmZvIG92ZXIgZ2VuZXJhdGluZyBvbmUKICB2YXIgY3JpID0gY3NyLmNlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyB8fAogICAgcGtpLmdldENlcnRpZmljYXRpb25SZXF1ZXN0SW5mbyhjc3IpOwoKICAvLyBDZXJ0aWZpY2F0ZQogIHJldHVybiBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAvLyBDZXJ0aWZpY2F0aW9uUmVxdWVzdEluZm8KICAgIGNyaSwKICAgIC8vIEFsZ29yaXRobUlkZW50aWZpZXIgKHNpZ25hdHVyZSBhbGdvcml0aG0pCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIGFsZ29yaXRobQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0Rlcihjc3Iuc2lnbmF0dXJlT2lkKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGFyYW1ldGVycwogICAgICBfc2lnbmF0dXJlUGFyYW1ldGVyc1RvQXNuMShjc3Iuc2lnbmF0dXJlT2lkLCBjc3Iuc2lnbmF0dXJlUGFyYW1ldGVycykKICAgIF0pLAogICAgLy8gc2lnbmF0dXJlCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLkJJVFNUUklORywgZmFsc2UsCiAgICAgIFN0cmluZy5mcm9tQ2hhckNvZGUoMHgwMCkgKyBjc3Iuc2lnbmF0dXJlKQogIF0pOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBDQSBzdG9yZS4KICoKICogQHBhcmFtIGNlcnRzIGFuIG9wdGlvbmFsIGFycmF5IG9mIGNlcnRpZmljYXRlIG9iamVjdHMgb3IgUEVNLWZvcm1hdHRlZAogKiAgICAgICAgICBjZXJ0aWZpY2F0ZSBzdHJpbmdzIHRvIGFkZCB0byB0aGUgQ0Egc3RvcmUuCiAqCiAqIEByZXR1cm4gdGhlIENBIHN0b3JlLgogKi8KcGtpLmNyZWF0ZUNhU3RvcmUgPSBmdW5jdGlvbihjZXJ0cykgewogIC8vIGNyZWF0ZSBDQSBzdG9yZQogIHZhciBjYVN0b3JlID0gewogICAgLy8gc3RvcmVkIGNlcnRpZmljYXRlcwogICAgY2VydHM6IHt9CiAgfTsKCiAgLyoqCiAgICogR2V0cyB0aGUgY2VydGlmaWNhdGUgdGhhdCBpc3N1ZWQgdGhlIHBhc3NlZCBjZXJ0aWZpY2F0ZSBvciBpdHMKICAgKiAncGFyZW50Jy4KICAgKgogICAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZSB0byBnZXQgdGhlIHBhcmVudCBmb3IuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBwYXJlbnQgY2VydGlmaWNhdGUgb3IgbnVsbCBpZiBub25lIHdhcyBmb3VuZC4KICAgKi8KICBjYVN0b3JlLmdldElzc3VlciA9IGZ1bmN0aW9uKGNlcnQpIHsKICAgIHZhciBydmFsID0gZ2V0QnlTdWJqZWN0KGNlcnQuaXNzdWVyKTsKCiAgICAvLyBzZWUgaWYgdGhlcmUgYXJlIG11bHRpcGxlIG1hdGNoZXMKICAgIC8qaWYoZm9yZ2UudXRpbC5pc0FycmF5KHJ2YWwpKSB7CiAgICAgIC8vIFRPRE86IHJlc29sdmUgbXVsdGlwbGUgbWF0Y2hlcyBieSBjaGVja2luZwogICAgICAvLyBhdXRob3JpdHlLZXkvc3ViamVjdEtleS9pc3N1ZXJVbmlxdWVJRC9vdGhlciBpZGVudGlmaWVycywgZXRjLgogICAgICAvLyBGSVhNRTogb3IgYWx0ZXJuYXRpdmVseSBkbyBhdXRob3JpdHkga2V5IG1hcHBpbmcKICAgICAgLy8gaWYgcG9zc2libGUgKFguNTA5djEgY2VydHMgY2FuJ3Qgd29yaz8pCiAgICAgIHRocm93IG5ldyBFcnJvcignUmVzb2x2aW5nIG11bHRpcGxlIGlzc3VlciBtYXRjaGVzIG5vdCBpbXBsZW1lbnRlZCB5ZXQuJyk7CiAgICB9Ki8KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAvKioKICAgKiBBZGRzIGEgdHJ1c3RlZCBjZXJ0aWZpY2F0ZSB0byB0aGUgc3RvcmUuCiAgICoKICAgKiBAcGFyYW0gY2VydCB0aGUgY2VydGlmaWNhdGUgdG8gYWRkIGFzIGEgdHJ1c3RlZCBjZXJ0aWZpY2F0ZSAoZWl0aGVyIGEKICAgKiAgICAgICAgICBwa2kuY2VydGlmaWNhdGUgb2JqZWN0IG9yIGEgUEVNLWZvcm1hdHRlZCBjZXJ0aWZpY2F0ZSkuCiAgICovCiAgY2FTdG9yZS5hZGRDZXJ0aWZpY2F0ZSA9IGZ1bmN0aW9uKGNlcnQpIHsKICAgIC8vIGNvbnZlcnQgZnJvbSBwZW0gaWYgbmVjZXNzYXJ5CiAgICBpZih0eXBlb2YgY2VydCA9PT0gJ3N0cmluZycpIHsKICAgICAgY2VydCA9IGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUZyb21QZW0oY2VydCk7CiAgICB9CgogICAgLy8gcHJvZHVjZSBzdWJqZWN0IGhhc2ggaWYgaXQgZG9lc24ndCBleGlzdAogICAgaWYoIWNlcnQuc3ViamVjdC5oYXNoKSB7CiAgICAgIHZhciBtZCA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICAgIGNlcnQuc3ViamVjdC5hdHRyaWJ1dGVzID0gIHBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheSgKICAgICAgICBfZG5Ub0FzbjEoY2VydC5zdWJqZWN0KSwgbWQpOwogICAgICBjZXJ0LnN1YmplY3QuaGFzaCA9IG1kLmRpZ2VzdCgpLnRvSGV4KCk7CiAgICB9CgogICAgaWYoY2VydC5zdWJqZWN0Lmhhc2ggaW4gY2FTdG9yZS5jZXJ0cykgewogICAgICAvLyBzdWJqZWN0IGhhc2ggYWxyZWFkeSBleGlzdHMsIGFwcGVuZCB0byBhcnJheQogICAgICB2YXIgdG1wID0gY2FTdG9yZS5jZXJ0c1tjZXJ0LnN1YmplY3QuaGFzaF07CiAgICAgIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkodG1wKSkgewogICAgICAgIHRtcCA9IFt0bXBdOwogICAgICB9CiAgICAgIHRtcC5wdXNoKGNlcnQpOwogICAgfSBlbHNlIHsKICAgICAgY2FTdG9yZS5jZXJ0c1tjZXJ0LnN1YmplY3QuaGFzaF0gPSBjZXJ0OwogICAgfQogIH07CgogIC8qKgogICAqIENoZWNrcyB0byBzZWUgaWYgdGhlIGdpdmVuIGNlcnRpZmljYXRlIGlzIGluIHRoZSBzdG9yZS4KICAgKgogICAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZSB0byBjaGVjay4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBpZiB0aGUgY2VydGlmaWNhdGUgaXMgaW4gdGhlIHN0b3JlLCBmYWxzZSBpZiBub3QuCiAgICovCiAgY2FTdG9yZS5oYXNDZXJ0aWZpY2F0ZSA9IGZ1bmN0aW9uKGNlcnQpIHsKICAgIHZhciBtYXRjaCA9IGdldEJ5U3ViamVjdChjZXJ0LnN1YmplY3QpOwogICAgaWYoIW1hdGNoKSB7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkobWF0Y2gpKSB7CiAgICAgIG1hdGNoID0gW21hdGNoXTsKICAgIH0KICAgIC8vIGNvbXBhcmUgREVSLWVuY29kaW5nIG9mIGNlcnRpZmljYXRlcwogICAgdmFyIGRlcjEgPSBhc24xLnRvRGVyKHBraS5jZXJ0aWZpY2F0ZVRvQXNuMShjZXJ0KSkuZ2V0Qnl0ZXMoKTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtYXRjaC5sZW5ndGg7ICsraSkgewogICAgICB2YXIgZGVyMiA9IGFzbjEudG9EZXIocGtpLmNlcnRpZmljYXRlVG9Bc24xKG1hdGNoW2ldKSkuZ2V0Qnl0ZXMoKTsKICAgICAgaWYoZGVyMSA9PT0gZGVyMikgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfTsKCiAgZnVuY3Rpb24gZ2V0QnlTdWJqZWN0KHN1YmplY3QpIHsKICAgIC8vIHByb2R1Y2Ugc3ViamVjdCBoYXNoIGlmIGl0IGRvZXNuJ3QgZXhpc3QKICAgIGlmKCFzdWJqZWN0Lmhhc2gpIHsKICAgICAgdmFyIG1kID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICAgICAgc3ViamVjdC5hdHRyaWJ1dGVzID0gIHBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheShfZG5Ub0FzbjEoc3ViamVjdCksIG1kKTsKICAgICAgc3ViamVjdC5oYXNoID0gbWQuZGlnZXN0KCkudG9IZXgoKTsKICAgIH0KICAgIHJldHVybiBjYVN0b3JlLmNlcnRzW3N1YmplY3QuaGFzaF0gfHwgbnVsbDsKICB9CgogIC8vIGF1dG8tYWRkIHBhc3NlZCBpbiBjZXJ0cwogIGlmKGNlcnRzKSB7CiAgICAvLyBwYXJzZSBQRU0tZm9ybWF0dGVkIGNlcnRpZmljYXRlcyBhcyBuZWNlc3NhcnkKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBjZXJ0cy5sZW5ndGg7ICsraSkgewogICAgICB2YXIgY2VydCA9IGNlcnRzW2ldOwogICAgICBjYVN0b3JlLmFkZENlcnRpZmljYXRlKGNlcnQpOwogICAgfQogIH0KCiAgcmV0dXJuIGNhU3RvcmU7Cn07CgovKioKICogQ2VydGlmaWNhdGUgdmVyaWZpY2F0aW9uIGVycm9ycywgYmFzZWQgb24gVExTLgogKi8KcGtpLmNlcnRpZmljYXRlRXJyb3IgPSB7CiAgYmFkX2NlcnRpZmljYXRlOiAnZm9yZ2UucGtpLkJhZENlcnRpZmljYXRlJywKICB1bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZTogJ2ZvcmdlLnBraS5VbnN1cHBvcnRlZENlcnRpZmljYXRlJywKICBjZXJ0aWZpY2F0ZV9yZXZva2VkOiAnZm9yZ2UucGtpLkNlcnRpZmljYXRlUmV2b2tlZCcsCiAgY2VydGlmaWNhdGVfZXhwaXJlZDogJ2ZvcmdlLnBraS5DZXJ0aWZpY2F0ZUV4cGlyZWQnLAogIGNlcnRpZmljYXRlX3Vua25vd246ICdmb3JnZS5wa2kuQ2VydGlmaWNhdGVVbmtub3duJywKICB1bmtub3duX2NhOiAnZm9yZ2UucGtpLlVua25vd25DZXJ0aWZpY2F0ZUF1dGhvcml0eScKfTsKCi8qKgogKiBWZXJpZmllcyBhIGNlcnRpZmljYXRlIGNoYWluIGFnYWluc3QgdGhlIGdpdmVuIENlcnRpZmljYXRlIEF1dGhvcml0eSBzdG9yZQogKiB3aXRoIGFuIG9wdGlvbmFsIGN1c3RvbSB2ZXJpZnkgY2FsbGJhY2suCiAqCiAqIEBwYXJhbSBjYVN0b3JlIGEgY2VydGlmaWNhdGUgc3RvcmUgdG8gdmVyaWZ5IGFnYWluc3QuCiAqIEBwYXJhbSBjaGFpbiB0aGUgY2VydGlmaWNhdGUgY2hhaW4gdG8gdmVyaWZ5LCB3aXRoIHRoZSByb290IG9yIGhpZ2hlc3QKICogICAgICAgICAgYXV0aG9yaXR5IGF0IHRoZSBlbmQgKGFuIGFycmF5IG9mIGNlcnRpZmljYXRlcykuCiAqIEBwYXJhbSB2ZXJpZnkgY2FsbGVkIGZvciBldmVyeSBjZXJ0aWZpY2F0ZSBpbiB0aGUgY2hhaW4uCiAqCiAqIFRoZSB2ZXJpZnkgY2FsbGJhY2sgaGFzIHRoZSBmb2xsb3dpbmcgc2lnbmF0dXJlOgogKgogKiB2ZXJpZmllZCAtIFNldCB0byB0cnVlIGlmIGNlcnRpZmljYXRlIHdhcyB2ZXJpZmllZCwgb3RoZXJ3aXNlIHRoZQogKiAgIHBraS5jZXJ0aWZpY2F0ZUVycm9yIGZvciB3aHkgdGhlIGNlcnRpZmljYXRlIGZhaWxlZC4KICogZGVwdGggLSBUaGUgY3VycmVudCBpbmRleCBpbiB0aGUgY2hhaW4sIHdoZXJlIDAgaXMgdGhlIGVuZCBwb2ludCdzIGNlcnQuCiAqIGNlcnRzIC0gVGhlIGNlcnRpZmljYXRlIGNoYWluLCAqTk9URSogYW4gZW1wdHkgY2hhaW4gaW5kaWNhdGVzIGFuIGFub255bW91cwogKiAgIGVuZCBwb2ludC4KICoKICogVGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzIGFuZCBvbiBmYWlsdXJlIGVpdGhlciB0aGUgYXBwcm9wcmlhdGUKICogcGtpLmNlcnRpZmljYXRlRXJyb3Igb3IgYW4gb2JqZWN0IHdpdGggJ2Vycm9yJyBzZXQgdG8gdGhlIGFwcHJvcHJpYXRlCiAqIHBraS5jZXJ0aWZpY2F0ZUVycm9yIGFuZCAnbWVzc2FnZScgc2V0IHRvIGEgY3VzdG9tIGVycm9yIG1lc3NhZ2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBpZiBzdWNjZXNzZnVsLCBlcnJvciB0aHJvd24gaWYgbm90LgogKi8KcGtpLnZlcmlmeUNlcnRpZmljYXRlQ2hhaW4gPSBmdW5jdGlvbihjYVN0b3JlLCBjaGFpbiwgdmVyaWZ5KSB7CiAgLyogRnJvbTogUkZDMzI4MCAtIEludGVybmV0IFguNTA5IFB1YmxpYyBLZXkgSW5mcmFzdHJ1Y3R1cmUgQ2VydGlmaWNhdGUKICAgIFNlY3Rpb24gNjogQ2VydGlmaWNhdGlvbiBQYXRoIFZhbGlkYXRpb24KICAgIFNlZSBpbmxpbmUgcGFyZW50aGV0aWNhbHMgcmVsYXRlZCB0byB0aGlzIHBhcnRpY3VsYXIgaW1wbGVtZW50YXRpb24uCgogICAgVGhlIHByaW1hcnkgZ29hbCBvZiBwYXRoIHZhbGlkYXRpb24gaXMgdG8gdmVyaWZ5IHRoZSBiaW5kaW5nIGJldHdlZW4KICAgIGEgc3ViamVjdCBkaXN0aW5ndWlzaGVkIG5hbWUgb3IgYSBzdWJqZWN0IGFsdGVybmF0aXZlIG5hbWUgYW5kIHN1YmplY3QKICAgIHB1YmxpYyBrZXksIGFzIHJlcHJlc2VudGVkIGluIHRoZSBlbmQgZW50aXR5IGNlcnRpZmljYXRlLCBiYXNlZCBvbiB0aGUKICAgIHB1YmxpYyBrZXkgb2YgdGhlIHRydXN0IGFuY2hvci4gVGhpcyByZXF1aXJlcyBvYnRhaW5pbmcgYSBzZXF1ZW5jZSBvZgogICAgY2VydGlmaWNhdGVzIHRoYXQgc3VwcG9ydCB0aGF0IGJpbmRpbmcuIFRoYXQgc2VxdWVuY2Ugc2hvdWxkIGJlIHByb3ZpZGVkCiAgICBpbiB0aGUgcGFzc2VkICdjaGFpbicuIFRoZSB0cnVzdCBhbmNob3Igc2hvdWxkIGJlIGluIHRoZSBnaXZlbiBDQQogICAgc3RvcmUuIFRoZSAnZW5kIGVudGl0eScgY2VydGlmaWNhdGUgaXMgdGhlIGNlcnRpZmljYXRlIHByb3ZpZGVkIGJ5IHRoZQogICAgZW5kIHBvaW50ICh0eXBpY2FsbHkgYSBzZXJ2ZXIpIGFuZCBpcyB0aGUgZmlyc3QgaW4gdGhlIGNoYWluLgoKICAgIFRvIG1lZXQgdGhpcyBnb2FsLCB0aGUgcGF0aCB2YWxpZGF0aW9uIHByb2Nlc3MgdmVyaWZpZXMsIGFtb25nIG90aGVyCiAgICB0aGluZ3MsIHRoYXQgYSBwcm9zcGVjdGl2ZSBjZXJ0aWZpY2F0aW9uIHBhdGggKGEgc2VxdWVuY2Ugb2YgbgogICAgY2VydGlmaWNhdGVzIG9yIGEgJ2NoYWluJykgc2F0aXNmaWVzIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCiAgICAoYSkgZm9yIGFsbCB4IGluIHsxLCAuLi4sIG4tMX0sIHRoZSBzdWJqZWN0IG9mIGNlcnRpZmljYXRlIHggaXMKICAgICAgICAgIHRoZSBpc3N1ZXIgb2YgY2VydGlmaWNhdGUgeCsxOwoKICAgIChiKSBjZXJ0aWZpY2F0ZSAxIGlzIGlzc3VlZCBieSB0aGUgdHJ1c3QgYW5jaG9yOwoKICAgIChjKSBjZXJ0aWZpY2F0ZSBuIGlzIHRoZSBjZXJ0aWZpY2F0ZSB0byBiZSB2YWxpZGF0ZWQ7IGFuZAoKICAgIChkKSBmb3IgYWxsIHggaW4gezEsIC4uLiwgbn0sIHRoZSBjZXJ0aWZpY2F0ZSB3YXMgdmFsaWQgYXQgdGhlCiAgICAgICAgICB0aW1lIGluIHF1ZXN0aW9uLgoKICAgIE5vdGUgdGhhdCBoZXJlICduJyBpcyBpbmRleCAwIGluIHRoZSBjaGFpbiBhbmQgMSBpcyB0aGUgbGFzdCBjZXJ0aWZpY2F0ZQogICAgaW4gdGhlIGNoYWluIGFuZCBpdCBtdXN0IGJlIHNpZ25lZCBieSBhIGNlcnRpZmljYXRlIGluIHRoZSBjb25uZWN0aW9uJ3MKICAgIENBIHN0b3JlLgoKICAgIFRoZSBwYXRoIHZhbGlkYXRpb24gcHJvY2VzcyBhbHNvIGRldGVybWluZXMgdGhlIHNldCBvZiBjZXJ0aWZpY2F0ZQogICAgcG9saWNpZXMgdGhhdCBhcmUgdmFsaWQgZm9yIHRoaXMgcGF0aCwgYmFzZWQgb24gdGhlIGNlcnRpZmljYXRlIHBvbGljaWVzCiAgICBleHRlbnNpb24sIHBvbGljeSBtYXBwaW5nIGV4dGVuc2lvbiwgcG9saWN5IGNvbnN0cmFpbnRzIGV4dGVuc2lvbiwgYW5kCiAgICBpbmhpYml0IGFueS1wb2xpY3kgZXh0ZW5zaW9uLgoKICAgIE5vdGU6IFBvbGljeSBtYXBwaW5nIGV4dGVuc2lvbiBub3Qgc3VwcG9ydGVkIChOb3QgUmVxdWlyZWQpLgoKICAgIE5vdGU6IElmIHRoZSBjZXJ0aWZpY2F0ZSBoYXMgYW4gdW5zdXBwb3J0ZWQgY3JpdGljYWwgZXh0ZW5zaW9uLCB0aGVuIGl0CiAgICBtdXN0IGJlIHJlamVjdGVkLgoKICAgIE5vdGU6IEEgY2VydGlmaWNhdGUgaXMgc2VsZi1pc3N1ZWQgaWYgdGhlIEROcyB0aGF0IGFwcGVhciBpbiB0aGUgc3ViamVjdAogICAgYW5kIGlzc3VlciBmaWVsZHMgYXJlIGlkZW50aWNhbCBhbmQgYXJlIG5vdCBlbXB0eS4KCiAgICBUaGUgcGF0aCB2YWxpZGF0aW9uIGFsZ29yaXRobSBhc3N1bWVzIHRoZSBmb2xsb3dpbmcgc2V2ZW4gaW5wdXRzIGFyZQogICAgcHJvdmlkZWQgdG8gdGhlIHBhdGggcHJvY2Vzc2luZyBsb2dpYy4gV2hhdCB0aGlzIHNwZWNpZmljIGltcGxlbWVudGF0aW9uCiAgICB3aWxsIHVzZSBpcyBwcm92aWRlZCBwYXJlbnRoZXRpY2FsbHk6CgogICAgKGEpIGEgcHJvc3BlY3RpdmUgY2VydGlmaWNhdGlvbiBwYXRoIG9mIGxlbmd0aCBuICh0aGUgJ2NoYWluJykKICAgIChiKSB0aGUgY3VycmVudCBkYXRlL3RpbWU6ICgnbm93JykuCiAgICAoYykgdXNlci1pbml0aWFsLXBvbGljeS1zZXQ6IEEgc2V0IG9mIGNlcnRpZmljYXRlIHBvbGljeSBpZGVudGlmaWVycwogICAgICAgICAgbmFtaW5nIHRoZSBwb2xpY2llcyB0aGF0IGFyZSBhY2NlcHRhYmxlIHRvIHRoZSBjZXJ0aWZpY2F0ZSB1c2VyLgogICAgICAgICAgVGhlIHVzZXItaW5pdGlhbC1wb2xpY3ktc2V0IGNvbnRhaW5zIHRoZSBzcGVjaWFsIHZhbHVlIGFueS1wb2xpY3kKICAgICAgICAgIGlmIHRoZSB1c2VyIGlzIG5vdCBjb25jZXJuZWQgYWJvdXQgY2VydGlmaWNhdGUgcG9saWN5CiAgICAgICAgICAoTm90IGltcGxlbWVudGVkLiBBbnkgcG9saWN5IGlzIGFjY2VwdGVkKS4KICAgIChkKSB0cnVzdCBhbmNob3IgaW5mb3JtYXRpb24sIGRlc2NyaWJpbmcgYSBDQSB0aGF0IHNlcnZlcyBhcyBhIHRydXN0CiAgICAgICAgICBhbmNob3IgZm9yIHRoZSBjZXJ0aWZpY2F0aW9uIHBhdGguIFRoZSB0cnVzdCBhbmNob3IgaW5mb3JtYXRpb24KICAgICAgICAgIGluY2x1ZGVzOgoKICAgICAgKDEpICB0aGUgdHJ1c3RlZCBpc3N1ZXIgbmFtZSwKICAgICAgKDIpICB0aGUgdHJ1c3RlZCBwdWJsaWMga2V5IGFsZ29yaXRobSwKICAgICAgKDMpICB0aGUgdHJ1c3RlZCBwdWJsaWMga2V5LCBhbmQKICAgICAgKDQpICBvcHRpb25hbGx5LCB0aGUgdHJ1c3RlZCBwdWJsaWMga2V5IHBhcmFtZXRlcnMgYXNzb2NpYXRlZAogICAgICAgICAgICAgd2l0aCB0aGUgcHVibGljIGtleS4KCiAgICAgIChUcnVzdCBhbmNob3JzIGFyZSBwcm92aWRlZCB2aWEgY2VydGlmaWNhdGVzIGluIHRoZSBDQSBzdG9yZSkuCgogICAgICBUaGUgdHJ1c3QgYW5jaG9yIGluZm9ybWF0aW9uIG1heSBiZSBwcm92aWRlZCB0byB0aGUgcGF0aCBwcm9jZXNzaW5nCiAgICAgIHByb2NlZHVyZSBpbiB0aGUgZm9ybSBvZiBhIHNlbGYtc2lnbmVkIGNlcnRpZmljYXRlLiBUaGUgdHJ1c3RlZCBhbmNob3IKICAgICAgaW5mb3JtYXRpb24gaXMgdHJ1c3RlZCBiZWNhdXNlIGl0IHdhcyBkZWxpdmVyZWQgdG8gdGhlIHBhdGggcHJvY2Vzc2luZwogICAgICBwcm9jZWR1cmUgYnkgc29tZSB0cnVzdHdvcnRoeSBvdXQtb2YtYmFuZCBwcm9jZWR1cmUuIElmIHRoZSB0cnVzdGVkCiAgICAgIHB1YmxpYyBrZXkgYWxnb3JpdGhtIHJlcXVpcmVzIHBhcmFtZXRlcnMsIHRoZW4gdGhlIHBhcmFtZXRlcnMgYXJlCiAgICAgIHByb3ZpZGVkIGFsb25nIHdpdGggdGhlIHRydXN0ZWQgcHVibGljIGtleSAoTm8gcGFyYW1ldGVycyB1c2VkIGluIHRoaXMKICAgICAgaW1wbGVtZW50YXRpb24pLgoKICAgIChlKSBpbml0aWFsLXBvbGljeS1tYXBwaW5nLWluaGliaXQsIHdoaWNoIGluZGljYXRlcyBpZiBwb2xpY3kgbWFwcGluZyBpcwogICAgICAgICAgYWxsb3dlZCBpbiB0aGUgY2VydGlmaWNhdGlvbiBwYXRoLgogICAgICAgICAgKE5vdCBpbXBsZW1lbnRlZCwgbm8gcG9saWN5IGNoZWNraW5nKQoKICAgIChmKSBpbml0aWFsLWV4cGxpY2l0LXBvbGljeSwgd2hpY2ggaW5kaWNhdGVzIGlmIHRoZSBwYXRoIG11c3QgYmUgdmFsaWQKICAgICAgICAgIGZvciBhdCBsZWFzdCBvbmUgb2YgdGhlIGNlcnRpZmljYXRlIHBvbGljaWVzIGluIHRoZSB1c2VyLWluaXRpYWwtCiAgICAgICAgICBwb2xpY3ktc2V0LgogICAgICAgICAgKE5vdCBpbXBsZW1lbnRlZCwgbm8gcG9saWN5IGNoZWNraW5nKQoKICAgIChnKSBpbml0aWFsLWFueS1wb2xpY3ktaW5oaWJpdCwgd2hpY2ggaW5kaWNhdGVzIHdoZXRoZXIgdGhlCiAgICAgICAgICBhbnlQb2xpY3kgT0lEIHNob3VsZCBiZSBwcm9jZXNzZWQgaWYgaXQgaXMgaW5jbHVkZWQgaW4gYQogICAgICAgICAgY2VydGlmaWNhdGUuCiAgICAgICAgICAoTm90IGltcGxlbWVudGVkLCBzbyBhbnkgcG9saWN5IGlzIHZhbGlkIHByb3ZpZGVkIHRoYXQgaXQgaXMKICAgICAgICAgIG5vdCBtYXJrZWQgYXMgY3JpdGljYWwpICovCgogIC8qIEJhc2ljIFBhdGggUHJvY2Vzc2luZzoKCiAgICBGb3IgZWFjaCBjZXJ0aWZpY2F0ZSBpbiB0aGUgJ2NoYWluJywgdGhlIGZvbGxvd2luZyBpcyBjaGVja2VkOgoKICAgIDEuIFRoZSBjZXJ0aWZpY2F0ZSB2YWxpZGl0eSBwZXJpb2QgaW5jbHVkZXMgdGhlIGN1cnJlbnQgdGltZS4KICAgIDIuIFRoZSBjZXJ0aWZpY2F0ZSB3YXMgc2lnbmVkIGJ5IGl0cyBwYXJlbnQgKHdoZXJlIHRoZSBwYXJlbnQgaXMgZWl0aGVyCiAgICAgICB0aGUgbmV4dCBpbiB0aGUgY2hhaW4gb3IgZnJvbSB0aGUgQ0Egc3RvcmUpLiBBbGxvdyBwcm9jZXNzaW5nIHRvCiAgICAgICBjb250aW51ZSB0byB0aGUgbmV4dCBzdGVwIGlmIG5vIHBhcmVudCBpcyBmb3VuZCBidXQgdGhlIGNlcnRpZmljYXRlIGlzCiAgICAgICBpbiB0aGUgQ0Egc3RvcmUuCiAgICAzLiBUT0RPOiBUaGUgY2VydGlmaWNhdGUgaGFzIG5vdCBiZWVuIHJldm9rZWQuCiAgICA0LiBUaGUgY2VydGlmaWNhdGUgaXNzdWVyIG5hbWUgbWF0Y2hlcyB0aGUgcGFyZW50J3Mgc3ViamVjdCBuYW1lLgogICAgNS4gVE9ETzogSWYgdGhlIGNlcnRpZmljYXRlIGlzIHNlbGYtaXNzdWVkIGFuZCBub3QgdGhlIGZpbmFsIGNlcnRpZmljYXRlCiAgICAgICBpbiB0aGUgY2hhaW4sIHNraXAgdGhpcyBzdGVwLCBvdGhlcndpc2UgdmVyaWZ5IHRoYXQgdGhlIHN1YmplY3QgbmFtZQogICAgICAgaXMgd2l0aGluIG9uZSBvZiB0aGUgcGVybWl0dGVkIHN1YnRyZWVzIG9mIFguNTAwIGRpc3Rpbmd1aXNoZWQgbmFtZXMKICAgICAgIGFuZCB0aGF0IGVhY2ggb2YgdGhlIGFsdGVybmF0aXZlIG5hbWVzIGluIHRoZSBzdWJqZWN0QWx0TmFtZSBleHRlbnNpb24KICAgICAgIChjcml0aWNhbCBvciBub24tY3JpdGljYWwpIGlzIHdpdGhpbiBvbmUgb2YgdGhlIHBlcm1pdHRlZCBzdWJ0cmVlcyBmb3IKICAgICAgIHRoYXQgbmFtZSB0eXBlLgogICAgNi4gVE9ETzogSWYgdGhlIGNlcnRpZmljYXRlIGlzIHNlbGYtaXNzdWVkIGFuZCBub3QgdGhlIGZpbmFsIGNlcnRpZmljYXRlCiAgICAgICBpbiB0aGUgY2hhaW4sIHNraXAgdGhpcyBzdGVwLCBvdGhlcndpc2UgdmVyaWZ5IHRoYXQgdGhlIHN1YmplY3QgbmFtZQogICAgICAgaXMgbm90IHdpdGhpbiBvbmUgb2YgdGhlIGV4Y2x1ZGVkIHN1YnRyZWVzIGZvciBYLjUwMCBkaXN0aW5ndWlzaGVkCiAgICAgICBuYW1lcyBhbmQgbm9uZSBvZiB0aGUgc3ViamVjdEFsdE5hbWUgZXh0ZW5zaW9uIG5hbWVzIGFyZSBleGNsdWRlZCBmb3IKICAgICAgIHRoYXQgbmFtZSB0eXBlLgogICAgNy4gVGhlIG90aGVyIHN0ZXBzIGluIHRoZSBhbGdvcml0aG0gZm9yIGJhc2ljIHBhdGggcHJvY2Vzc2luZyBpbnZvbHZlCiAgICAgICBoYW5kbGluZyB0aGUgcG9saWN5IGV4dGVuc2lvbiB3aGljaCBpcyBub3QgcHJlc2VudGx5IHN1cHBvcnRlZCBpbiB0aGlzCiAgICAgICBpbXBsZW1lbnRhdGlvbi4gSW5zdGVhZCwgaWYgYSBjcml0aWNhbCBwb2xpY3kgZXh0ZW5zaW9uIGlzIGZvdW5kLCB0aGUKICAgICAgIGNlcnRpZmljYXRlIGlzIHJlamVjdGVkIGFzIG5vdCBzdXBwb3J0ZWQuCiAgICA4LiBJZiB0aGUgY2VydGlmaWNhdGUgaXMgbm90IHRoZSBmaXJzdCBvciBpZiBpdHMgdGhlIG9ubHkgY2VydGlmaWNhdGUgaW4KICAgICAgIHRoZSBjaGFpbiAoaGF2aW5nIG5vIHBhcmVudCBmcm9tIHRoZSBDQSBzdG9yZSBvciBpcyBzZWxmLXNpZ25lZCkgYW5kIGl0CiAgICAgICBoYXMgYSBjcml0aWNhbCBrZXkgdXNhZ2UgZXh0ZW5zaW9uLCB2ZXJpZnkgdGhhdCB0aGUga2V5Q2VydFNpZ24gYml0IGlzCiAgICAgICBzZXQuIElmIHRoZSBrZXkgdXNhZ2UgZXh0ZW5zaW9uIGV4aXN0cywgdmVyaWZ5IHRoYXQgdGhlIGJhc2ljCiAgICAgICBjb25zdHJhaW50cyBleHRlbnNpb24gZXhpc3RzLiBJZiB0aGUgYmFzaWMgY29uc3RyYWludHMgZXh0ZW5zaW9uIGV4aXN0cywKICAgICAgIHZlcmlmeSB0aGF0IHRoZSBjQSBmbGFnIGlzIHNldC4gSWYgcGF0aExlbkNvbnN0cmFpbnQgaXMgc2V0LCBlbnN1cmUgdGhhdAogICAgICAgdGhlIG51bWJlciBvZiBjZXJ0aWZpY2F0ZXMgdGhhdCBwcmVjZWRlIGluIHRoZSBjaGFpbiAoY29tZSBlYXJsaWVyCiAgICAgICBpbiB0aGUgY2hhaW4gYXMgaW1wbGVtZW50ZWQgYmVsb3cpLCBleGNsdWRpbmcgdGhlIHZlcnkgZmlyc3QgaW4gdGhlCiAgICAgICBjaGFpbiAodHlwaWNhbGx5IHRoZSBlbmQtZW50aXR5IG9uZSksIGlzbid0IGdyZWF0ZXIgdGhhbiB0aGUKICAgICAgIHBhdGhMZW5Db25zdHJhaW50LiBUaGlzIGNvbnN0cmFpbnQgbGltaXRzIHRoZSBudW1iZXIgb2YgaW50ZXJtZWRpYXRlCiAgICAgICBDQXMgdGhhdCBtYXkgYXBwZWFyIGJlbG93IGEgQ0EgYmVmb3JlIG9ubHkgZW5kLWVudGl0eSBjZXJ0aWZpY2F0ZXMKICAgICAgIG1heSBiZSBpc3N1ZWQuICovCgogIC8vIGNvcHkgY2VydCBjaGFpbiByZWZlcmVuY2VzIHRvIGFub3RoZXIgYXJyYXkgdG8gcHJvdGVjdCBhZ2FpbnN0IGNoYW5nZXMKICAvLyBpbiB2ZXJpZnkgY2FsbGJhY2sKICBjaGFpbiA9IGNoYWluLnNsaWNlKDApOwogIHZhciBjZXJ0cyA9IGNoYWluLnNsaWNlKDApOwoKICAvLyBnZXQgY3VycmVudCBkYXRlCiAgdmFyIG5vdyA9IG5ldyBEYXRlKCk7CgogIC8vIHZlcmlmeSBlYWNoIGNlcnQgaW4gdGhlIGNoYWluIHVzaW5nIGl0cyBwYXJlbnQsIHdoZXJlIHRoZSBwYXJlbnQKICAvLyBpcyBlaXRoZXIgdGhlIG5leHQgaW4gdGhlIGNoYWluIG9yIGZyb20gdGhlIENBIHN0b3JlCiAgdmFyIGZpcnN0ID0gdHJ1ZTsKICB2YXIgZXJyb3IgPSBudWxsOwogIHZhciBkZXB0aCA9IDA7CiAgZG8gewogICAgdmFyIGNlcnQgPSBjaGFpbi5zaGlmdCgpOwogICAgdmFyIHBhcmVudCA9IG51bGw7CiAgICB2YXIgc2VsZlNpZ25lZCA9IGZhbHNlOwoKICAgIC8vIDEuIGNoZWNrIHZhbGlkIHRpbWUKICAgIGlmKG5vdyA8IGNlcnQudmFsaWRpdHkubm90QmVmb3JlIHx8IG5vdyA+IGNlcnQudmFsaWRpdHkubm90QWZ0ZXIpIHsKICAgICAgZXJyb3IgPSB7CiAgICAgICAgbWVzc2FnZTogJ0NlcnRpZmljYXRlIGlzIG5vdCB2YWxpZCB5ZXQgb3IgaGFzIGV4cGlyZWQuJywKICAgICAgICBlcnJvcjogcGtpLmNlcnRpZmljYXRlRXJyb3IuY2VydGlmaWNhdGVfZXhwaXJlZCwKICAgICAgICBub3RCZWZvcmU6IGNlcnQudmFsaWRpdHkubm90QmVmb3JlLAogICAgICAgIG5vdEFmdGVyOiBjZXJ0LnZhbGlkaXR5Lm5vdEFmdGVyLAogICAgICAgIG5vdzogbm93CiAgICAgIH07CiAgICB9CgogICAgLy8gMi4gdmVyaWZ5IHdpdGggcGFyZW50IGZyb20gY2hhaW4gb3IgQ0Egc3RvcmUKICAgIGlmKGVycm9yID09PSBudWxsKSB7CiAgICAgIHBhcmVudCA9IGNoYWluWzBdIHx8IGNhU3RvcmUuZ2V0SXNzdWVyKGNlcnQpOwogICAgICBpZihwYXJlbnQgPT09IG51bGwpIHsKICAgICAgICAvLyBjaGVjayBmb3Igc2VsZi1zaWduZWQgY2VydAogICAgICAgIGlmKGNlcnQuaXNJc3N1ZXIoY2VydCkpIHsKICAgICAgICAgIHNlbGZTaWduZWQgPSB0cnVlOwogICAgICAgICAgcGFyZW50ID0gY2VydDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmKHBhcmVudCkgewogICAgICAgIC8vIEZJWE1FOiBjdXJyZW50IENBIHN0b3JlIGltcGxlbWVudGF0aW9uIG1pZ2h0IGhhdmUgbXVsdGlwbGUKICAgICAgICAvLyBjZXJ0aWZpY2F0ZXMgd2hlcmUgdGhlIGlzc3VlciBjYW4ndCBiZSBkZXRlcm1pbmVkIGZyb20gdGhlCiAgICAgICAgLy8gY2VydGlmaWNhdGUgKGhhcHBlbnMgcmFyZWx5IHdpdGgsIGVnOiBvbGQgY2VydGlmaWNhdGVzKSBzbyBub3JtYWxpemUKICAgICAgICAvLyBieSBhbHdheXMgcHV0dGluZyBwYXJlbnRzIGludG8gYW4gYXJyYXkKICAgICAgICAvLyBUT0RPOiB0aGVyZSdzIG1heSBiZSBhbiBleHRyZW1lIGRlZ2VuZXJhdGUgY2FzZSBjdXJyZW50bHkgdW5jb3ZlcmVkCiAgICAgICAgLy8gd2hlcmUgYW4gb2xkIGludGVybWVkaWF0ZSBjZXJ0aWZpY2F0ZSBzZWVtcyB0byBoYXZlIGEgbWF0Y2hpbmcgcGFyZW50CiAgICAgICAgLy8gYnV0IG5vbmUgb2YgdGhlIHBhcmVudHMgYWN0dWFsbHkgdmVyaWZ5IC4uLiBidXQgdGhlIGludGVybWVkaWF0ZQogICAgICAgIC8vIGlzIGluIHRoZSBDQSBhbmQgaXQgc2hvdWxkIHBhc3MgdGhpcyBjaGVjazsgbmVlZHMgaW52ZXN0aWdhdGlvbgogICAgICAgIHZhciBwYXJlbnRzID0gcGFyZW50OwogICAgICAgIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkocGFyZW50cykpIHsKICAgICAgICAgIHBhcmVudHMgPSBbcGFyZW50c107CiAgICAgICAgfQoKICAgICAgICAvLyB0cnkgdG8gdmVyaWZ5IHdpdGggZWFjaCBwb3NzaWJsZSBwYXJlbnQgKHR5cGljYWxseSBvbmx5IG9uZSkKICAgICAgICB2YXIgdmVyaWZpZWQgPSBmYWxzZTsKICAgICAgICB3aGlsZSghdmVyaWZpZWQgJiYgcGFyZW50cy5sZW5ndGggPiAwKSB7CiAgICAgICAgICBwYXJlbnQgPSBwYXJlbnRzLnNoaWZ0KCk7CiAgICAgICAgICB0cnkgewogICAgICAgICAgICB2ZXJpZmllZCA9IHBhcmVudC52ZXJpZnkoY2VydCk7CiAgICAgICAgICB9IGNhdGNoKGV4KSB7CiAgICAgICAgICAgIC8vIGZhaWx1cmUgdG8gdmVyaWZ5LCBkb24ndCBjYXJlIHdoeSwgdHJ5IG5leHQgb25lCiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZighdmVyaWZpZWQpIHsKICAgICAgICAgIGVycm9yID0gewogICAgICAgICAgICBtZXNzYWdlOiAnQ2VydGlmaWNhdGUgc2lnbmF0dXJlIGlzIGludmFsaWQuJywKICAgICAgICAgICAgZXJyb3I6IHBraS5jZXJ0aWZpY2F0ZUVycm9yLmJhZF9jZXJ0aWZpY2F0ZQogICAgICAgICAgfTsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGlmKGVycm9yID09PSBudWxsICYmICghcGFyZW50IHx8IHNlbGZTaWduZWQpICYmCiAgICAgICAgIWNhU3RvcmUuaGFzQ2VydGlmaWNhdGUoY2VydCkpIHsKICAgICAgICAvLyBubyBwYXJlbnQgaXNzdWVyIGFuZCBjZXJ0aWZpY2F0ZSBpdHNlbGYgaXMgbm90IHRydXN0ZWQKICAgICAgICBlcnJvciA9IHsKICAgICAgICAgIG1lc3NhZ2U6ICdDZXJ0aWZpY2F0ZSBpcyBub3QgdHJ1c3RlZC4nLAogICAgICAgICAgZXJyb3I6IHBraS5jZXJ0aWZpY2F0ZUVycm9yLnVua25vd25fY2EKICAgICAgICB9OwogICAgICB9CiAgICB9CgogICAgLy8gVE9ETzogMy4gY2hlY2sgcmV2b2tlZAoKICAgIC8vIDQuIGNoZWNrIGZvciBtYXRjaGluZyBpc3N1ZXIvc3ViamVjdAogICAgaWYoZXJyb3IgPT09IG51bGwgJiYgcGFyZW50ICYmICFjZXJ0LmlzSXNzdWVyKHBhcmVudCkpIHsKICAgICAgLy8gcGFyZW50IGlzIG5vdCBpc3N1ZXIKICAgICAgZXJyb3IgPSB7CiAgICAgICAgbWVzc2FnZTogJ0NlcnRpZmljYXRlIGlzc3VlciBpcyBpbnZhbGlkLicsCiAgICAgICAgZXJyb3I6IHBraS5jZXJ0aWZpY2F0ZUVycm9yLmJhZF9jZXJ0aWZpY2F0ZQogICAgICB9OwogICAgfQoKICAgIC8vIDUuIFRPRE86IGNoZWNrIG5hbWVzIHdpdGggcGVybWl0dGVkIG5hbWVzIHRyZWUKCiAgICAvLyA2LiBUT0RPOiBjaGVjayBuYW1lcyBhZ2FpbnN0IGV4Y2x1ZGVkIG5hbWVzIHRyZWUKCiAgICAvLyA3LiBjaGVjayBmb3IgdW5zdXBwb3J0ZWQgY3JpdGljYWwgZXh0ZW5zaW9ucwogICAgaWYoZXJyb3IgPT09IG51bGwpIHsKICAgICAgLy8gc3VwcG9ydGVkIGV4dGVuc2lvbnMKICAgICAgdmFyIHNlID0gewogICAgICAgIGtleVVzYWdlOiB0cnVlLAogICAgICAgIGJhc2ljQ29uc3RyYWludHM6IHRydWUKICAgICAgfTsKICAgICAgZm9yKHZhciBpID0gMDsgZXJyb3IgPT09IG51bGwgJiYgaSA8IGNlcnQuZXh0ZW5zaW9ucy5sZW5ndGg7ICsraSkgewogICAgICAgIHZhciBleHQgPSBjZXJ0LmV4dGVuc2lvbnNbaV07CiAgICAgICAgaWYoZXh0LmNyaXRpY2FsICYmICEoZXh0Lm5hbWUgaW4gc2UpKSB7CiAgICAgICAgICBlcnJvciA9IHsKICAgICAgICAgICAgbWVzc2FnZToKICAgICAgICAgICAgICAnQ2VydGlmaWNhdGUgaGFzIGFuIHVuc3VwcG9ydGVkIGNyaXRpY2FsIGV4dGVuc2lvbi4nLAogICAgICAgICAgICBlcnJvcjogcGtpLmNlcnRpZmljYXRlRXJyb3IudW5zdXBwb3J0ZWRfY2VydGlmaWNhdGUKICAgICAgICAgIH07CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgLy8gOC4gY2hlY2sgZm9yIENBIGlmIGNlcnQgaXMgbm90IGZpcnN0IG9yIGlzIHRoZSBvbmx5IGNlcnRpZmljYXRlCiAgICAvLyByZW1haW5pbmcgaW4gY2hhaW4gd2l0aCBubyBwYXJlbnQgb3IgaXMgc2VsZi1zaWduZWQKICAgIGlmKGVycm9yID09PSBudWxsICYmCiAgICAgICghZmlyc3QgfHwgKGNoYWluLmxlbmd0aCA9PT0gMCAmJiAoIXBhcmVudCB8fCBzZWxmU2lnbmVkKSkpKSB7CiAgICAgIC8vIGZpcnN0IGNoZWNrIGtleVVzYWdlIGV4dGVuc2lvbiBhbmQgdGhlbiBiYXNpYyBjb25zdHJhaW50cwogICAgICB2YXIgYmNFeHQgPSBjZXJ0LmdldEV4dGVuc2lvbignYmFzaWNDb25zdHJhaW50cycpOwogICAgICB2YXIga2V5VXNhZ2VFeHQgPSBjZXJ0LmdldEV4dGVuc2lvbigna2V5VXNhZ2UnKTsKICAgICAgaWYoa2V5VXNhZ2VFeHQgIT09IG51bGwpIHsKICAgICAgICAvLyBrZXlDZXJ0U2lnbiBtdXN0IGJlIHRydWUgYW5kIHRoZXJlIG11c3QgYmUgYSBiYXNpYwogICAgICAgIC8vIGNvbnN0cmFpbnRzIGV4dGVuc2lvbgogICAgICAgIGlmKCFrZXlVc2FnZUV4dC5rZXlDZXJ0U2lnbiB8fCBiY0V4dCA9PT0gbnVsbCkgewogICAgICAgICAgLy8gYmFkIGNlcnRpZmljYXRlCiAgICAgICAgICBlcnJvciA9IHsKICAgICAgICAgICAgbWVzc2FnZToKICAgICAgICAgICAgICAnQ2VydGlmaWNhdGUga2V5VXNhZ2Ugb3IgYmFzaWNDb25zdHJhaW50cyBjb25mbGljdCAnICsKICAgICAgICAgICAgICAnb3IgaW5kaWNhdGUgdGhhdCB0aGUgY2VydGlmaWNhdGUgaXMgbm90IGEgQ0EuICcgKwogICAgICAgICAgICAgICdJZiB0aGUgY2VydGlmaWNhdGUgaXMgdGhlIG9ubHkgb25lIGluIHRoZSBjaGFpbiBvciAnICsKICAgICAgICAgICAgICAnaXNuXCd0IHRoZSBmaXJzdCB0aGVuIHRoZSBjZXJ0aWZpY2F0ZSBtdXN0IGJlIGEgJyArCiAgICAgICAgICAgICAgJ3ZhbGlkIENBLicsCiAgICAgICAgICAgIGVycm9yOiBwa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGUKICAgICAgICAgIH07CiAgICAgICAgfQogICAgICB9CiAgICAgIC8vIGJhc2ljIGNvbnN0cmFpbnRzIGNBIGZsYWcgbXVzdCBiZSBzZXQKICAgICAgaWYoZXJyb3IgPT09IG51bGwgJiYgYmNFeHQgIT09IG51bGwgJiYgIWJjRXh0LmNBKSB7CiAgICAgICAgLy8gYmFkIGNlcnRpZmljYXRlCiAgICAgICAgZXJyb3IgPSB7CiAgICAgICAgICBtZXNzYWdlOgogICAgICAgICAgICAnQ2VydGlmaWNhdGUgYmFzaWNDb25zdHJhaW50cyBpbmRpY2F0ZXMgdGhlIGNlcnRpZmljYXRlICcgKwogICAgICAgICAgICAnaXMgbm90IGEgQ0EuJywKICAgICAgICAgIGVycm9yOiBwa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGUKICAgICAgICB9OwogICAgICB9CiAgICAgIC8vIGlmIGVycm9yIGlzIG5vdCBudWxsIGFuZCBrZXlVc2FnZSBpcyBhdmFpbGFibGUsIHRoZW4gd2Uga25vdyBpdAogICAgICAvLyBoYXMga2V5Q2VydFNpZ24gYW5kIHRoZXJlIGlzIGEgYmFzaWMgY29uc3RyYWludHMgZXh0ZW5zaW9uIHRvbywKICAgICAgLy8gd2hpY2ggbWVhbnMgd2UgY2FuIGNoZWNrIHBhdGhMZW5Db25zdHJhaW50IChpZiBpdCBleGlzdHMpCiAgICAgIGlmKGVycm9yID09PSBudWxsICYmIGtleVVzYWdlRXh0ICE9PSBudWxsICYmCiAgICAgICAgJ3BhdGhMZW5Db25zdHJhaW50JyBpbiBiY0V4dCkgewogICAgICAgIC8vIHBhdGhMZW4gaXMgdGhlIG1heGltdW0gIyBvZiBpbnRlcm1lZGlhdGUgQ0EgY2VydHMgdGhhdCBjYW4gYmUKICAgICAgICAvLyBmb3VuZCBiZXR3ZWVuIHRoZSBjdXJyZW50IGNlcnRpZmljYXRlIGFuZCB0aGUgZW5kLWVudGl0eSAoZGVwdGggMCkKICAgICAgICAvLyBjZXJ0aWZpY2F0ZTsgdGhpcyBudW1iZXIgZG9lcyBub3QgaW5jbHVkZSB0aGUgZW5kLWVudGl0eSAoZGVwdGggMCwKICAgICAgICAvLyBsYXN0IGluIHRoZSBjaGFpbikgZXZlbiBpZiBpdCBoYXBwZW5zIHRvIGJlIGEgQ0EgY2VydGlmaWNhdGUgaXRzZWxmCiAgICAgICAgdmFyIHBhdGhMZW4gPSBkZXB0aCAtIDE7CiAgICAgICAgaWYocGF0aExlbiA+IGJjRXh0LnBhdGhMZW5Db25zdHJhaW50KSB7CiAgICAgICAgICAvLyBwYXRoTGVuQ29uc3RyYWludCB2aW9sYXRlZCwgYmFkIGNlcnRpZmljYXRlCiAgICAgICAgICBlcnJvciA9IHsKICAgICAgICAgICAgbWVzc2FnZToKICAgICAgICAgICAgICAnQ2VydGlmaWNhdGUgYmFzaWNDb25zdHJhaW50cyBwYXRoTGVuQ29uc3RyYWludCB2aW9sYXRlZC4nLAogICAgICAgICAgICBlcnJvcjogcGtpLmNlcnRpZmljYXRlRXJyb3IuYmFkX2NlcnRpZmljYXRlCiAgICAgICAgICB9OwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIC8vIGNhbGwgYXBwbGljYXRpb24gY2FsbGJhY2sKICAgIHZhciB2ZmQgPSAoZXJyb3IgPT09IG51bGwpID8gdHJ1ZSA6IGVycm9yLmVycm9yOwogICAgdmFyIHJldCA9IHZlcmlmeSA/IHZlcmlmeSh2ZmQsIGRlcHRoLCBjZXJ0cykgOiB2ZmQ7CiAgICBpZihyZXQgPT09IHRydWUpIHsKICAgICAgLy8gY2xlYXIgYW55IHNldCBlcnJvcgogICAgICBlcnJvciA9IG51bGw7CiAgICB9IGVsc2UgewogICAgICAvLyBpZiBwYXNzZWQgYmFzaWMgdGVzdHMsIHNldCBkZWZhdWx0IG1lc3NhZ2UgYW5kIGFsZXJ0CiAgICAgIGlmKHZmZCA9PT0gdHJ1ZSkgewogICAgICAgIGVycm9yID0gewogICAgICAgICAgbWVzc2FnZTogJ1RoZSBhcHBsaWNhdGlvbiByZWplY3RlZCB0aGUgY2VydGlmaWNhdGUuJywKICAgICAgICAgIGVycm9yOiBwa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGUKICAgICAgICB9OwogICAgICB9CgogICAgICAvLyBjaGVjayBmb3IgY3VzdG9tIGVycm9yIGluZm8KICAgICAgaWYocmV0IHx8IHJldCA9PT0gMCkgewogICAgICAgIC8vIHNldCBjdXN0b20gbWVzc2FnZSBhbmQgZXJyb3IKICAgICAgICBpZih0eXBlb2YgcmV0ID09PSAnb2JqZWN0JyAmJiAhZm9yZ2UudXRpbC5pc0FycmF5KHJldCkpIHsKICAgICAgICAgIGlmKHJldC5tZXNzYWdlKSB7CiAgICAgICAgICAgICBlcnJvci5tZXNzYWdlID0gcmV0Lm1lc3NhZ2U7CiAgICAgICAgICB9CiAgICAgICAgICBpZihyZXQuZXJyb3IpIHsKICAgICAgICAgICAgZXJyb3IuZXJyb3IgPSByZXQuZXJyb3I7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmKHR5cGVvZiByZXQgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgICAvLyBzZXQgY3VzdG9tIGVycm9yCiAgICAgICAgICBlcnJvci5lcnJvciA9IHJldDsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIC8vIHRocm93IGVycm9yCiAgICAgIHRocm93IGVycm9yOwogICAgfQoKICAgIC8vIG5vIGxvbmdlciBmaXJzdCBjZXJ0IGluIGNoYWluCiAgICBmaXJzdCA9IGZhbHNlOwogICAgKytkZXB0aDsKICB9IHdoaWxlKGNoYWluLmxlbmd0aCA+IDApOwoKICByZXR1cm4gdHJ1ZTsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3g1MDknOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZS5wa2k7CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3g1MDknLFsKICAncmVxdWlyZScsCiAgJ21vZHVsZScsCiAgJy4vYWVzJywKICAnLi9hc24xJywKICAnLi9kZXMnLAogICcuL21kJywKICAnLi9tZ2YnLAogICcuL29pZHMnLAogICcuL3BlbScsCiAgJy4vcHNzJywKICAnLi9yc2EnLAogICcuL3V0aWwnCl0sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgUEtDUyMxMi4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICogQGF1dGhvciBTdGVmYW4gU2llZ2wgPHN0ZXNpZUBicm9rZW5waXBlLmRlPgogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxNCBEaWdpdGFsIEJhemFhciwgSW5jLgogKiBDb3B5cmlnaHQgKGMpIDIwMTIgU3RlZmFuIFNpZWdsIDxzdGVzaWVAYnJva2VucGlwZS5kZT4KICoKICogVGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIFBLQ1MjMTIgaXMgYXMgZm9sbG93cwogKiAoc2VlIGZ0cDovL2Z0cC5yc2FzZWN1cml0eS5jb20vcHViL3BrY3MvcGtjcy0xMi9wa2NzLTEyLXRjMS5wZGYgZm9yIGRldGFpbHMpCiAqCiAqIFBGWCA6Oj0gU0VRVUVOQ0UgewogKiAgIHZlcnNpb24gIElOVEVHRVIge3YzKDMpfSh2MywuLi4pLAogKiAgIGF1dGhTYWZlIENvbnRlbnRJbmZvLAogKiAgIG1hY0RhdGEgIE1hY0RhdGEgT1BUSU9OQUwKICogfQogKgogKiBNYWNEYXRhIDo6PSBTRVFVRU5DRSB7CiAqICAgbWFjIERpZ2VzdEluZm8sCiAqICAgbWFjU2FsdCBPQ1RFVCBTVFJJTkcsCiAqICAgaXRlcmF0aW9ucyBJTlRFR0VSIERFRkFVTFQgMQogKiB9CiAqIE5vdGU6IFRoZSBpdGVyYXRpb25zIGRlZmF1bHQgaXMgZm9yIGhpc3RvcmljYWwgcmVhc29ucyBhbmQgaXRzIHVzZSBpcwogKiBkZXByZWNhdGVkLiBBIGhpZ2hlciB2YWx1ZSwgbGlrZSAxMDI0LCBpcyByZWNvbW1lbmRlZC4KICoKICogRGlnZXN0SW5mbyBpcyBkZWZpbmVkIGluIFBLQ1MjNyBhcyBmb2xsb3dzOgogKgogKiBEaWdlc3RJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgZGlnZXN0QWxnb3JpdGhtIERpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXIsCiAqICAgZGlnZXN0IERpZ2VzdAogKiB9CiAqCiAqIERpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXIgOjo9IEFsZ29yaXRobUlkZW50aWZpZXIKICoKICogVGhlIEFsZ29yaXRobUlkZW50aWZpZXIgY29udGFpbnMgYW4gT2JqZWN0IElkZW50aWZpZXIgKE9JRCkgYW5kIHBhcmFtZXRlcnMKICogZm9yIHRoZSBhbGdvcml0aG0sIGlmIGFueS4gSW4gdGhlIGNhc2Ugb2YgU0hBMSB0aGVyZSBpcyBub25lLgogKgogKiBBbGdvcml0aG1JZGVudGlmZXIgOjo9IFNFUVVFTkNFIHsKICogICAgYWxnb3JpdGhtIE9CSkVDVCBJREVOVElGSUVSLAogKiAgICBwYXJhbWV0ZXJzIEFOWSBERUZJTkVEIEJZIGFsZ29yaXRobSBPUFRJT05BTAogKiB9CiAqCiAqIERpZ2VzdCA6Oj0gT0NURVQgU1RSSU5HCiAqCiAqCiAqIENvbnRlbnRJbmZvIDo6PSBTRVFVRU5DRSB7CiAqICAgY29udGVudFR5cGUgQ29udGVudFR5cGUsCiAqICAgY29udGVudCAgICAgWzBdIEVYUExJQ0lUIEFOWSBERUZJTkVEIEJZIGNvbnRlbnRUeXBlIE9QVElPTkFMCiAqIH0KICoKICogQ29udGVudFR5cGUgOjo9IE9CSkVDVCBJREVOVElGSUVSCiAqCiAqIEF1dGhlbnRpY2F0ZWRTYWZlIDo6PSBTRVFVRU5DRSBPRiBDb250ZW50SW5mbwogKiAtLSBEYXRhIGlmIHVuZW5jcnlwdGVkCiAqIC0tIEVuY3J5cHRlZERhdGEgaWYgcGFzc3dvcmQtZW5jcnlwdGVkCiAqIC0tIEVudmVsb3BlZERhdGEgaWYgcHVibGljIGtleS1lbmNyeXB0ZWQKICoKICoKICogU2FmZUNvbnRlbnRzIDo6PSBTRVFVRU5DRSBPRiBTYWZlQmFnCiAqCiAqIFNhZmVCYWcgOjo9IFNFUVVFTkNFIHsKICogICBiYWdJZCAgICAgQkFHLVRZUEUuJmlkICh7UEtDUzEyQmFnU2V0fSkKICogICBiYWdWYWx1ZSAgWzBdIEVYUExJQ0lUIEJBRy1UWVBFLiZUeXBlKHtQS0NTMTJCYWdTZXR9e0BiYWdJZH0pLAogKiAgIGJhZ0F0dHJpYnV0ZXMgU0VUIE9GIFBLQ1MxMkF0dHJpYnV0ZSBPUFRJT05BTAogKiB9CiAqCiAqIFBLQ1MxMkF0dHJpYnV0ZSA6Oj0gU0VRVUVOQ0UgewogKiAgIGF0dHJJZCBBVFRSSUJVVEUuJmlkICh7UEtDUzEyQXR0clNldH0pLAogKiAgIGF0dHJWYWx1ZXMgU0VUIE9GIEFUVFJJQlVURS4mVHlwZSAoe1BLQ1MxMkF0dHJTZXR9e0BhdHRySWR9KQogKiB9IC0tIFRoaXMgdHlwZSBpcyBjb21wYXRpYmxlIHdpdGggdGhlIFguNTAwIHR5cGUg4oCZQXR0cmlidXRl4oCZCiAqCiAqIFBLQ1MxMkF0dHJTZXQgQVRUUklCVVRFIDo6PSB7CiAqICAgZnJpZW5kbHlOYW1lIHwgLS0gZnJvbSBQS0NTICM5CiAqICAgbG9jYWxLZXlJZCwgLS0gZnJvbSBQS0NTICM5CiAqICAgLi4uIC0tIE90aGVyIGF0dHJpYnV0ZXMgYXJlIGFsbG93ZWQKICogfQogKgogKiBDZXJ0QmFnIDo6PSBTRVFVRU5DRSB7CiAqICAgY2VydElkICAgIEJBRy1UWVBFLiZpZCAgICh7Q2VydFR5cGVzfSksCiAqICAgY2VydFZhbHVlIFswXSBFWFBMSUNJVCBCQUctVFlQRS4mVHlwZSAoe0NlcnRUeXBlc317QGNlcnRJZH0pCiAqIH0KICoKICogeDUwOUNlcnRpZmljYXRlIEJBRy1UWVBFIDo6PSB7T0NURVQgU1RSSU5HIElERU5USUZJRUQgQlkge2NlcnRUeXBlcyAxfX0KICogICAtLSBERVItZW5jb2RlZCBYLjUwOSBjZXJ0aWZpY2F0ZSBzdG9yZWQgaW4gT0NURVQgU1RSSU5HCiAqCiAqIHNkc2lDZXJ0aWZpY2F0ZSBCQUctVFlQRSA6Oj0ge0lBNVN0cmluZyBJREVOVElGSUVEIEJZIHtjZXJ0VHlwZXMgMn19CiAqIC0tIEJhc2U2NC1lbmNvZGVkIFNEU0kgY2VydGlmaWNhdGUgc3RvcmVkIGluIElBNVN0cmluZwogKgogKiBDZXJ0VHlwZXMgQkFHLVRZUEUgOjo9IHsKICogICB4NTA5Q2VydGlmaWNhdGUgfAogKiAgIHNkc2lDZXJ0aWZpY2F0ZSwKICogICAuLi4gLS0gRm9yIGZ1dHVyZSBleHRlbnNpb25zCiAqIH0KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBzaG9ydGN1dCBmb3IgYXNuLjEgJiBQS0kgQVBJCnZhciBhc24xID0gZm9yZ2UuYXNuMTsKdmFyIHBraSA9IGZvcmdlLnBraTsKCi8vIHNob3J0Y3V0IGZvciBQS0NTIzEyIEFQSQp2YXIgcDEyID0gZm9yZ2UucGtjczEyID0gZm9yZ2UucGtjczEyIHx8IHt9OwoKdmFyIGNvbnRlbnRJbmZvVmFsaWRhdG9yID0gewogIG5hbWU6ICdDb250ZW50SW5mbycsCiAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwgIC8vIGEgQ29udGVudEluZm8KICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICB2YWx1ZTogW3sKICAgIG5hbWU6ICdDb250ZW50SW5mby5jb250ZW50VHlwZScsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2NvbnRlbnRUeXBlJwogIH0sIHsKICAgIG5hbWU6ICdDb250ZW50SW5mby5jb250ZW50JywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAnY29udGVudCcKICB9XQp9OwoKdmFyIHBmeFZhbGlkYXRvciA9IHsKICBuYW1lOiAnUEZYJywKICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLAogIGNvbnN0cnVjdGVkOiB0cnVlLAogIHZhbHVlOiBbewogICAgbmFtZTogJ1BGWC52ZXJzaW9uJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5JTlRFR0VSLAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ3ZlcnNpb24nCiAgfSwKICBjb250ZW50SW5mb1ZhbGlkYXRvciwgewogICAgbmFtZTogJ1BGWC5tYWNEYXRhJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgIHR5cGU6IGFzbjEuVHlwZS5TRVFVRU5DRSwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgb3B0aW9uYWw6IHRydWUsCiAgICBjYXB0dXJlQXNuMTogJ21hYycsCiAgICB2YWx1ZTogW3sKICAgICAgbmFtZTogJ1BGWC5tYWNEYXRhLm1hYycsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLlNFUVVFTkNFLCAgLy8gRGlnZXN0SW5mbwogICAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgICAgdmFsdWU6IFt7CiAgICAgICAgbmFtZTogJ1BGWC5tYWNEYXRhLm1hYy5kaWdlc3RBbGdvcml0aG0nLAogICAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsICAvLyBEaWdlc3RBbGdvcml0aG1JZGVudGlmaWVyCiAgICAgICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICAgICAgdmFsdWU6IFt7CiAgICAgICAgICBuYW1lOiAnUEZYLm1hY0RhdGEubWFjLmRpZ2VzdEFsZ29yaXRobS5hbGdvcml0aG0nLAogICAgICAgICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgICAgICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICAgIGNhcHR1cmU6ICdtYWNBbGdvcml0aG0nCiAgICAgICAgfSwgewogICAgICAgICAgbmFtZTogJ1BGWC5tYWNEYXRhLm1hYy5kaWdlc3RBbGdvcml0aG0ucGFyYW1ldGVycycsCiAgICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgICBjYXB0dXJlQXNuMTogJ21hY0FsZ29yaXRobVBhcmFtZXRlcnMnCiAgICAgICAgfV0KICAgICAgfSwgewogICAgICAgIG5hbWU6ICdQRlgubWFjRGF0YS5tYWMuZGlnZXN0JywKICAgICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgICBjYXB0dXJlOiAnbWFjRGlnZXN0JwogICAgICB9XQogICAgfSwgewogICAgICBuYW1lOiAnUEZYLm1hY0RhdGEubWFjU2FsdCcsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLk9DVEVUU1RSSU5HLAogICAgICBjb25zdHJ1Y3RlZDogZmFsc2UsCiAgICAgIGNhcHR1cmU6ICdtYWNTYWx0JwogICAgfSwgewogICAgICBuYW1lOiAnUEZYLm1hY0RhdGEuaXRlcmF0aW9ucycsCiAgICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICAgICAgdHlwZTogYXNuMS5UeXBlLklOVEVHRVIsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgb3B0aW9uYWw6IHRydWUsCiAgICAgIGNhcHR1cmU6ICdtYWNJdGVyYXRpb25zJwogICAgfV0KICB9XQp9OwoKdmFyIHNhZmVCYWdWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ1NhZmVCYWcnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnU2FmZUJhZy5iYWdJZCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ2JhZ0lkJwogIH0sIHsKICAgIG5hbWU6ICdTYWZlQmFnLmJhZ1ZhbHVlJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIGNhcHR1cmVBc24xOiAnYmFnVmFsdWUnCiAgfSwgewogICAgbmFtZTogJ1NhZmVCYWcuYmFnQXR0cmlidXRlcycsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuU0VULAogICAgY29uc3RydWN0ZWQ6IHRydWUsCiAgICBvcHRpb25hbDogdHJ1ZSwKICAgIGNhcHR1cmU6ICdiYWdBdHRyaWJ1dGVzJwogIH1dCn07Cgp2YXIgYXR0cmlidXRlVmFsaWRhdG9yID0gewogIG5hbWU6ICdBdHRyaWJ1dGUnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnQXR0cmlidXRlLmF0dHJJZCcsCiAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICB0eXBlOiBhc24xLlR5cGUuT0lELAogICAgY29uc3RydWN0ZWQ6IGZhbHNlLAogICAgY2FwdHVyZTogJ29pZCcKICB9LCB7CiAgICBuYW1lOiAnQXR0cmlidXRlLmF0dHJWYWx1ZXMnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLlNFVCwKICAgIGNvbnN0cnVjdGVkOiB0cnVlLAogICAgY2FwdHVyZTogJ3ZhbHVlcycKICB9XQp9OwoKdmFyIGNlcnRCYWdWYWxpZGF0b3IgPSB7CiAgbmFtZTogJ0NlcnRCYWcnLAogIHRhZ0NsYXNzOiBhc24xLkNsYXNzLlVOSVZFUlNBTCwKICB0eXBlOiBhc24xLlR5cGUuU0VRVUVOQ0UsCiAgY29uc3RydWN0ZWQ6IHRydWUsCiAgdmFsdWU6IFt7CiAgICBuYW1lOiAnQ2VydEJhZy5jZXJ0SWQnLAogICAgdGFnQ2xhc3M6IGFzbjEuQ2xhc3MuVU5JVkVSU0FMLAogICAgdHlwZTogYXNuMS5UeXBlLk9JRCwKICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgIGNhcHR1cmU6ICdjZXJ0SWQnCiAgfSwgewogICAgbmFtZTogJ0NlcnRCYWcuY2VydFZhbHVlJywKICAgIHRhZ0NsYXNzOiBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsCiAgICBjb25zdHJ1Y3RlZDogdHJ1ZSwKICAgIC8qIFNvIGZhciB3ZSBvbmx5IHN1cHBvcnQgWC41MDkgY2VydGlmaWNhdGVzICh3aGljaCBhcmUgd3JhcHBlZCBpbgogICAgICAgYW4gT0NURVQgU1RSSU5HLCBoZW5jZSBoYXJkIGNvZGUgdGhhdCBoZXJlKS4gKi8KICAgIHZhbHVlOiBbewogICAgICBuYW1lOiAnQ2VydEJhZy5jZXJ0VmFsdWVbMF0nLAogICAgICB0YWdDbGFzczogYXNuMS5DbGFzcy5VTklWRVJTQUwsCiAgICAgIHR5cGU6IGFzbjEuQ2xhc3MuT0NURVRTVFJJTkcsCiAgICAgIGNvbnN0cnVjdGVkOiBmYWxzZSwKICAgICAgY2FwdHVyZTogJ2NlcnQnCiAgICB9XQogIH1dCn07CgovKioKICogU2VhcmNoIFNhZmVDb250ZW50cyBzdHJ1Y3R1cmUgZm9yIGJhZ3Mgd2l0aCBtYXRjaGluZyBhdHRyaWJ1dGVzLgogKgogKiBUaGUgc2VhcmNoIGNhbiBvcHRpb25hbGx5IGJlIG5hcnJvd2VkIGJ5IGEgY2VydGFpbiBiYWcgdHlwZS4KICoKICogQHBhcmFtIHNhZmVDb250ZW50cyB0aGUgU2FmZUNvbnRlbnRzIHN0cnVjdHVyZSB0byBzZWFyY2ggaW4uCiAqIEBwYXJhbSBhdHRyTmFtZSB0aGUgbmFtZSBvZiB0aGUgYXR0cmlidXRlIHRvIGNvbXBhcmUgYWdhaW5zdC4KICogQHBhcmFtIGF0dHJWYWx1ZSB0aGUgYXR0cmlidXRlIHZhbHVlIHRvIHNlYXJjaCBmb3IuCiAqIEBwYXJhbSBbYmFnVHlwZV0gYmFnIHR5cGUgdG8gbmFycm93IHNlYXJjaCBieS4KICoKICogQHJldHVybiBhbiBhcnJheSBvZiBtYXRjaGluZyBiYWdzLgogKi8KZnVuY3Rpb24gX2dldEJhZ3NCeUF0dHJpYnV0ZShzYWZlQ29udGVudHMsIGF0dHJOYW1lLCBhdHRyVmFsdWUsIGJhZ1R5cGUpIHsKICB2YXIgcmVzdWx0ID0gW107CgogIGZvcih2YXIgaSA9IDA7IGkgPCBzYWZlQ29udGVudHMubGVuZ3RoOyBpICsrKSB7CiAgICBmb3IodmFyIGogPSAwOyBqIDwgc2FmZUNvbnRlbnRzW2ldLnNhZmVCYWdzLmxlbmd0aDsgaiArKykgewogICAgICB2YXIgYmFnID0gc2FmZUNvbnRlbnRzW2ldLnNhZmVCYWdzW2pdOwogICAgICBpZihiYWdUeXBlICE9PSB1bmRlZmluZWQgJiYgYmFnLnR5cGUgIT09IGJhZ1R5cGUpIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICAvLyBvbmx5IGZpbHRlciBieSBiYWcgdHlwZSwgbm8gYXR0cmlidXRlIHNwZWNpZmllZAogICAgICBpZihhdHRyTmFtZSA9PT0gbnVsbCkgewogICAgICAgIHJlc3VsdC5wdXNoKGJhZyk7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYoYmFnLmF0dHJpYnV0ZXNbYXR0ck5hbWVdICE9PSB1bmRlZmluZWQgJiYKICAgICAgICBiYWcuYXR0cmlidXRlc1thdHRyTmFtZV0uaW5kZXhPZihhdHRyVmFsdWUpID49IDApIHsKICAgICAgICByZXN1bHQucHVzaChiYWcpOwogICAgICB9CiAgICB9CiAgfQoKICByZXR1cm4gcmVzdWx0Owp9CgovKioKICogQ29udmVydHMgYSBQS0NTIzEyIFBGWCBpbiBBU04uMSBub3RhdGlvbiBpbnRvIGEgUEZYIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiBUaGUgUEtDUyMxMiBQRlggaW4gQVNOLjEgbm90YXRpb24uCiAqIEBwYXJhbSBzdHJpY3QgdHJ1ZSB0byB1c2Ugc3RyaWN0IERFUiBkZWNvZGluZywgZmFsc2Ugbm90IHRvIChkZWZhdWx0OiB0cnVlKS4KICogQHBhcmFtIHtTdHJpbmd9IHBhc3N3b3JkIFBhc3N3b3JkIHRvIGRlY3J5cHQgd2l0aCAob3B0aW9uYWwpLgogKgogKiBAcmV0dXJuIFBLQ1MjMTIgUEZYIG9iamVjdC4KICovCnAxMi5wa2NzMTJGcm9tQXNuMSA9IGZ1bmN0aW9uKG9iaiwgc3RyaWN0LCBwYXNzd29yZCkgewogIC8vIGhhbmRsZSBhcmdzCiAgaWYodHlwZW9mIHN0cmljdCA9PT0gJ3N0cmluZycpIHsKICAgIHBhc3N3b3JkID0gc3RyaWN0OwogICAgc3RyaWN0ID0gdHJ1ZTsKICB9IGVsc2UgaWYoc3RyaWN0ID09PSB1bmRlZmluZWQpIHsKICAgIHN0cmljdCA9IHRydWU7CiAgfQoKICAvLyB2YWxpZGF0ZSBQRlggYW5kIGNhcHR1cmUgZGF0YQogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgcGZ4VmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFBLQ1MjMTIgUEZYLiAnICsKICAgICAgJ0FTTi4xIG9iamVjdCBpcyBub3QgYW4gUEtDUyMxMiBQRlguJyk7CiAgICBlcnJvci5lcnJvcnMgPSBlcnJvcjsKICAgIHRocm93IGVycm9yOwogIH0KCiAgdmFyIHBmeCA9IHsKICAgIHZlcnNpb246IGNhcHR1cmUudmVyc2lvbi5jaGFyQ29kZUF0KDApLAogICAgc2FmZUNvbnRlbnRzOiBbXSwKCiAgICAvKioKICAgICAqIEdldHMgYmFncyB3aXRoIG1hdGNoaW5nIGF0dHJpYnV0ZXMuCiAgICAgKgogICAgICogQHBhcmFtIGZpbHRlciB0aGUgYXR0cmlidXRlcyB0byBmaWx0ZXIgYnk6CiAgICAgKiAgICAgICAgICBbbG9jYWxLZXlJZF0gdGhlIGxvY2FsS2V5SWQgdG8gc2VhcmNoIGZvci4KICAgICAqICAgICAgICAgIFtsb2NhbEtleUlkSGV4XSB0aGUgbG9jYWxLZXlJZCBpbiBoZXggdG8gc2VhcmNoIGZvci4KICAgICAqICAgICAgICAgIFtmcmllbmRseU5hbWVdIHRoZSBmcmllbmRseSBuYW1lIHRvIHNlYXJjaCBmb3IuCiAgICAgKiAgICAgICAgICBbYmFnVHlwZV0gYmFnIHR5cGUgdG8gbmFycm93IGVhY2ggYXR0cmlidXRlIHNlYXJjaCBieS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGEgbWFwIG9mIGF0dHJpYnV0ZSB0eXBlIHRvIGFuIGFycmF5IG9mIG1hdGNoaW5nIGJhZ3Mgb3IsIGlmIG5vCiAgICAgKiAgICAgICAgICAgYXR0cmlidXRlIHdhcyBnaXZlbiBidXQgYSBiYWcgdHlwZSwgdGhlIG1hcCBrZXkgd2lsbCBiZSB0aGUKICAgICAqICAgICAgICAgICBiYWcgdHlwZS4KICAgICAqLwogICAgZ2V0QmFnczogZnVuY3Rpb24oZmlsdGVyKSB7CiAgICAgIHZhciBydmFsID0ge307CgogICAgICB2YXIgbG9jYWxLZXlJZDsKICAgICAgaWYoJ2xvY2FsS2V5SWQnIGluIGZpbHRlcikgewogICAgICAgIGxvY2FsS2V5SWQgPSBmaWx0ZXIubG9jYWxLZXlJZDsKICAgICAgfSBlbHNlIGlmKCdsb2NhbEtleUlkSGV4JyBpbiBmaWx0ZXIpIHsKICAgICAgICBsb2NhbEtleUlkID0gZm9yZ2UudXRpbC5oZXhUb0J5dGVzKGZpbHRlci5sb2NhbEtleUlkSGV4KTsKICAgICAgfQoKICAgICAgLy8gZmlsdGVyIG9uIGJhZ1R5cGUgb25seQogICAgICBpZihsb2NhbEtleUlkID09PSB1bmRlZmluZWQgJiYgISgnZnJpZW5kbHlOYW1lJyBpbiBmaWx0ZXIpICYmCiAgICAgICAgJ2JhZ1R5cGUnIGluIGZpbHRlcikgewogICAgICAgIHJ2YWxbZmlsdGVyLmJhZ1R5cGVdID0gX2dldEJhZ3NCeUF0dHJpYnV0ZSgKICAgICAgICAgIHBmeC5zYWZlQ29udGVudHMsIG51bGwsIG51bGwsIGZpbHRlci5iYWdUeXBlKTsKICAgICAgfQoKICAgICAgaWYobG9jYWxLZXlJZCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgcnZhbC5sb2NhbEtleUlkID0gX2dldEJhZ3NCeUF0dHJpYnV0ZSgKICAgICAgICAgIHBmeC5zYWZlQ29udGVudHMsICdsb2NhbEtleUlkJywKICAgICAgICAgIGxvY2FsS2V5SWQsIGZpbHRlci5iYWdUeXBlKTsKICAgICAgfQogICAgICBpZignZnJpZW5kbHlOYW1lJyBpbiBmaWx0ZXIpIHsKICAgICAgICBydmFsLmZyaWVuZGx5TmFtZSA9IF9nZXRCYWdzQnlBdHRyaWJ1dGUoCiAgICAgICAgICBwZnguc2FmZUNvbnRlbnRzLCAnZnJpZW5kbHlOYW1lJywKICAgICAgICAgIGZpbHRlci5mcmllbmRseU5hbWUsIGZpbHRlci5iYWdUeXBlKTsKICAgICAgfQoKICAgICAgcmV0dXJuIHJ2YWw7CiAgICB9LAoKICAgIC8qKgogICAgICogREVQUkVDQVRFRDogdXNlIGdldEJhZ3MoKSBpbnN0ZWFkLgogICAgICoKICAgICAqIEdldCBiYWdzIHdpdGggbWF0Y2hpbmcgZnJpZW5kbHlOYW1lIGF0dHJpYnV0ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gZnJpZW5kbHlOYW1lIHRoZSBmcmllbmRseSBuYW1lIHRvIHNlYXJjaCBmb3IuCiAgICAgKiBAcGFyYW0gW2JhZ1R5cGVdIGJhZyB0eXBlIHRvIG5hcnJvdyBzZWFyY2ggYnkuCiAgICAgKgogICAgICogQHJldHVybiBhbiBhcnJheSBvZiBiYWdzIHdpdGggbWF0Y2hpbmcgZnJpZW5kbHlOYW1lIGF0dHJpYnV0ZS4KICAgICAqLwogICAgZ2V0QmFnc0J5RnJpZW5kbHlOYW1lOiBmdW5jdGlvbihmcmllbmRseU5hbWUsIGJhZ1R5cGUpIHsKICAgICAgcmV0dXJuIF9nZXRCYWdzQnlBdHRyaWJ1dGUoCiAgICAgICAgcGZ4LnNhZmVDb250ZW50cywgJ2ZyaWVuZGx5TmFtZScsIGZyaWVuZGx5TmFtZSwgYmFnVHlwZSk7CiAgICB9LAoKICAgIC8qKgogICAgICogREVQUkVDQVRFRDogdXNlIGdldEJhZ3MoKSBpbnN0ZWFkLgogICAgICoKICAgICAqIEdldCBiYWdzIHdpdGggbWF0Y2hpbmcgbG9jYWxLZXlJZCBhdHRyaWJ1dGUuCiAgICAgKgogICAgICogQHBhcmFtIGxvY2FsS2V5SWQgdGhlIGxvY2FsS2V5SWQgdG8gc2VhcmNoIGZvci4KICAgICAqIEBwYXJhbSBbYmFnVHlwZV0gYmFnIHR5cGUgdG8gbmFycm93IHNlYXJjaCBieS4KICAgICAqCiAgICAgKiBAcmV0dXJuIGFuIGFycmF5IG9mIGJhZ3Mgd2l0aCBtYXRjaGluZyBsb2NhbEtleUlkIGF0dHJpYnV0ZS4KICAgICAqLwogICAgZ2V0QmFnc0J5TG9jYWxLZXlJZDogZnVuY3Rpb24obG9jYWxLZXlJZCwgYmFnVHlwZSkgewogICAgICByZXR1cm4gX2dldEJhZ3NCeUF0dHJpYnV0ZSgKICAgICAgICBwZnguc2FmZUNvbnRlbnRzLCAnbG9jYWxLZXlJZCcsIGxvY2FsS2V5SWQsIGJhZ1R5cGUpOwogICAgfQogIH07CgogIGlmKGNhcHR1cmUudmVyc2lvbi5jaGFyQ29kZUF0KDApICE9PSAzKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ1BLQ1MjMTIgUEZYIG9mIHZlcnNpb24gb3RoZXIgdGhhbiAzIG5vdCBzdXBwb3J0ZWQuJyk7CiAgICBlcnJvci52ZXJzaW9uID0gY2FwdHVyZS52ZXJzaW9uLmNoYXJDb2RlQXQoMCk7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIGlmKGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5jb250ZW50VHlwZSkgIT09IHBraS5vaWRzLmRhdGEpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignT25seSBQS0NTIzEyIFBGWCBpbiBwYXNzd29yZCBpbnRlZ3JpdHkgbW9kZSBzdXBwb3J0ZWQuJyk7CiAgICBlcnJvci5vaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUuY29udGVudFR5cGUpOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICB2YXIgZGF0YSA9IGNhcHR1cmUuY29udGVudC52YWx1ZVswXTsKICBpZihkYXRhLnRhZ0NsYXNzICE9PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fAogICAgIGRhdGEudHlwZSAhPT0gYXNuMS5UeXBlLk9DVEVUU1RSSU5HKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BLQ1MjMTIgYXV0aFNhZmUgY29udGVudCBkYXRhIGlzIG5vdCBhbiBPQ1RFVCBTVFJJTkcuJyk7CiAgfQogIGRhdGEgPSBfZGVjb2RlUGtjczdEYXRhKGRhdGEpOwoKICAvLyBjaGVjayBmb3IgTUFDCiAgaWYoY2FwdHVyZS5tYWMpIHsKICAgIHZhciBtZCA9IG51bGw7CiAgICB2YXIgbWFjS2V5Qnl0ZXMgPSAwOwogICAgdmFyIG1hY0FsZ29yaXRobSA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5tYWNBbGdvcml0aG0pOwogICAgc3dpdGNoKG1hY0FsZ29yaXRobSkgewogICAgY2FzZSBwa2kub2lkcy5zaGExOgogICAgICBtZCA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICAgIG1hY0tleUJ5dGVzID0gMjA7CiAgICAgIGJyZWFrOwogICAgY2FzZSBwa2kub2lkcy5zaGEyNTY6CiAgICAgIG1kID0gZm9yZ2UubWQuc2hhMjU2LmNyZWF0ZSgpOwogICAgICBtYWNLZXlCeXRlcyA9IDMyOwogICAgICBicmVhazsKICAgIGNhc2UgcGtpLm9pZHMuc2hhMzg0OgogICAgICBtZCA9IGZvcmdlLm1kLnNoYTM4NC5jcmVhdGUoKTsKICAgICAgbWFjS2V5Qnl0ZXMgPSA0ODsKICAgICAgYnJlYWs7CiAgICBjYXNlIHBraS5vaWRzLnNoYTUxMjoKICAgICAgbWQgPSBmb3JnZS5tZC5zaGE1MTIuY3JlYXRlKCk7CiAgICAgIG1hY0tleUJ5dGVzID0gNjQ7CiAgICAgIGJyZWFrOwogICAgY2FzZSBwa2kub2lkcy5tZDU6CiAgICAgIG1kID0gZm9yZ2UubWQubWQ1LmNyZWF0ZSgpOwogICAgICBtYWNLZXlCeXRlcyA9IDE2OwogICAgICBicmVhazsKICAgIH0KICAgIGlmKG1kID09PSBudWxsKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUyMxMiB1c2VzIHVuc3VwcG9ydGVkIE1BQyBhbGdvcml0aG06ICcgKyBtYWNBbGdvcml0aG0pOwogICAgfQoKICAgIC8vIHZlcmlmeSBNQUMgKGl0ZXJhdGlvbnMgZGVmYXVsdCB0byAxKQogICAgdmFyIG1hY1NhbHQgPSBuZXcgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKGNhcHR1cmUubWFjU2FsdCk7CiAgICB2YXIgbWFjSXRlcmF0aW9ucyA9ICgoJ21hY0l0ZXJhdGlvbnMnIGluIGNhcHR1cmUpID8KICAgICAgcGFyc2VJbnQoZm9yZ2UudXRpbC5ieXRlc1RvSGV4KGNhcHR1cmUubWFjSXRlcmF0aW9ucyksIDE2KSA6IDEpOwogICAgdmFyIG1hY0tleSA9IHAxMi5nZW5lcmF0ZUtleSgKICAgICAgcGFzc3dvcmQsIG1hY1NhbHQsIDMsIG1hY0l0ZXJhdGlvbnMsIG1hY0tleUJ5dGVzLCBtZCk7CiAgICB2YXIgbWFjID0gZm9yZ2UuaG1hYy5jcmVhdGUoKTsKICAgIG1hYy5zdGFydChtZCwgbWFjS2V5KTsKICAgIG1hYy51cGRhdGUoZGF0YS52YWx1ZSk7CiAgICB2YXIgbWFjVmFsdWUgPSBtYWMuZ2V0TWFjKCk7CiAgICBpZihtYWNWYWx1ZS5nZXRCeXRlcygpICE9PSBjYXB0dXJlLm1hY0RpZ2VzdCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BLQ1MjMTIgTUFDIGNvdWxkIG5vdCBiZSB2ZXJpZmllZC4gSW52YWxpZCBwYXNzd29yZD8nKTsKICAgIH0KICB9CgogIF9kZWNvZGVBdXRoZW50aWNhdGVkU2FmZShwZngsIGRhdGEudmFsdWUsIHN0cmljdCwgcGFzc3dvcmQpOwogIHJldHVybiBwZng7Cn07CgovKioKICogRGVjb2RlcyBQS0NTIzcgRGF0YS4gUEtDUyM3IChSRkMgMjMxNSkgZGVmaW5lcyAiRGF0YSIgYXMgYW4gT0NURVQgU1RSSU5HLAogKiBidXQgaXQgaXMgc29tZXRpbWVzIGFuIE9DVEVUIFNUUklORyB0aGF0IGlzIGNvbXBvc2VkL2NvbnN0cnVjdGVkIG9mIGNodW5rcywKICogZWFjaCBpdHMgb3duIE9DVEVUIFNUUklORy4gVGhpcyBpcyBCRVItZW5jb2RpbmcgdnMuIERFUi1lbmNvZGluZy4gVGhpcwogKiBmdW5jdGlvbiB0cmFuc2Zvcm1zIHRoaXMgY29ybmVyLWNhc2UgaW50byB0aGUgdXN1YWwgc2ltcGxlLAogKiBub24tY29tcG9zZWQvY29uc3RydWN0ZWQgT0NURVQgU1RSSU5HLgogKgogKiBUaGlzIGZ1bmN0aW9uIG1heSBiZSBtb3ZlZCB0byBBU04uMSBhdCBzb21lIHBvaW50IHRvIGJldHRlciBkZWFsIHdpdGgKICogbW9yZSBCRVItZW5jb2RpbmcgaXNzdWVzLCBzaG91bGQgdGhleSBhcmlzZS4KICoKICogQHBhcmFtIGRhdGEgdGhlIEFTTi4xIERhdGEgb2JqZWN0IHRvIHRyYW5zZm9ybS4KICovCmZ1bmN0aW9uIF9kZWNvZGVQa2NzN0RhdGEoZGF0YSkgewogIC8vIGhhbmRsZSBzcGVjaWFsIGNhc2Ugb2YgImNodW5rZWQiIGRhdGEgY29udGVudDogYW4gb2N0ZXQgc3RyaW5nIGNvbXBvc2VkCiAgLy8gb2Ygb3RoZXIgb2N0ZXQgc3RyaW5ncwogIGlmKGRhdGEuY29tcG9zZWQgfHwgZGF0YS5jb25zdHJ1Y3RlZCkgewogICAgdmFyIHZhbHVlID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBkYXRhLnZhbHVlLmxlbmd0aDsgKytpKSB7CiAgICAgIHZhbHVlLnB1dEJ5dGVzKGRhdGEudmFsdWVbaV0udmFsdWUpOwogICAgfQogICAgZGF0YS5jb21wb3NlZCA9IGRhdGEuY29uc3RydWN0ZWQgPSBmYWxzZTsKICAgIGRhdGEudmFsdWUgPSB2YWx1ZS5nZXRCeXRlcygpOwogIH0KICByZXR1cm4gZGF0YTsKfQoKLyoqCiAqIERlY29kZSBQS0NTIzEyIEF1dGhlbnRpY2F0ZWRTYWZlIChCRVIgZW5jb2RlZCkgaW50byBQRlggb2JqZWN0LgogKgogKiBUaGUgQXV0aGVudGljYXRlZFNhZmUgaXMgYSBCRVItZW5jb2RlZCBTRVFVRU5DRSBPRiBDb250ZW50SW5mby4KICoKICogQHBhcmFtIHBmeCBUaGUgUEtDUyMxMiBQRlggb2JqZWN0IHRvIGZpbGwuCiAqIEBwYXJhbSB7U3RyaW5nfSBhdXRoU2FmZSBCRVItZW5jb2RlZCBBdXRoZW50aWNhdGVkU2FmZS4KICogQHBhcmFtIHN0cmljdCB0cnVlIHRvIHVzZSBzdHJpY3QgREVSIGRlY29kaW5nLCBmYWxzZSBub3QgdG8uCiAqIEBwYXJhbSB7U3RyaW5nfSBwYXNzd29yZCBQYXNzd29yZCB0byBkZWNyeXB0IHdpdGggKG9wdGlvbmFsKS4KICovCmZ1bmN0aW9uIF9kZWNvZGVBdXRoZW50aWNhdGVkU2FmZShwZngsIGF1dGhTYWZlLCBzdHJpY3QsIHBhc3N3b3JkKSB7CiAgYXV0aFNhZmUgPSBhc24xLmZyb21EZXIoYXV0aFNhZmUsIHN0cmljdCk7ICAvKiBhY3R1YWxseSBpdCdzIEJFUiBlbmNvZGVkICovCgogIGlmKGF1dGhTYWZlLnRhZ0NsYXNzICE9PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fAogICAgIGF1dGhTYWZlLnR5cGUgIT09IGFzbjEuVHlwZS5TRVFVRU5DRSB8fAogICAgIGF1dGhTYWZlLmNvbnN0cnVjdGVkICE9PSB0cnVlKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ1BLQ1MjMTIgQXV0aGVudGljYXRlZFNhZmUgZXhwZWN0ZWQgdG8gYmUgYSAnICsKICAgICAgJ1NFUVVFTkNFIE9GIENvbnRlbnRJbmZvJyk7CiAgfQoKICBmb3IodmFyIGkgPSAwOyBpIDwgYXV0aFNhZmUudmFsdWUubGVuZ3RoOyBpICsrKSB7CiAgICB2YXIgY29udGVudEluZm8gPSBhdXRoU2FmZS52YWx1ZVtpXTsKCiAgICAvLyB2YWxpZGF0ZSBjb250ZW50SW5mbyBhbmQgY2FwdHVyZSBkYXRhCiAgICB2YXIgY2FwdHVyZSA9IHt9OwogICAgdmFyIGVycm9ycyA9IFtdOwogICAgaWYoIWFzbjEudmFsaWRhdGUoY29udGVudEluZm8sIGNvbnRlbnRJbmZvVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgQ29udGVudEluZm8uJyk7CiAgICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgdmFyIG9iaiA9IHsKICAgICAgZW5jcnlwdGVkOiBmYWxzZQogICAgfTsKICAgIHZhciBzYWZlQ29udGVudHMgPSBudWxsOwogICAgdmFyIGRhdGEgPSBjYXB0dXJlLmNvbnRlbnQudmFsdWVbMF07CiAgICBzd2l0Y2goYXNuMS5kZXJUb09pZChjYXB0dXJlLmNvbnRlbnRUeXBlKSkgewogICAgY2FzZSBwa2kub2lkcy5kYXRhOgogICAgICBpZihkYXRhLnRhZ0NsYXNzICE9PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fAogICAgICAgICBkYXRhLnR5cGUgIT09IGFzbjEuVHlwZS5PQ1RFVFNUUklORykgewogICAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUyMxMiBTYWZlQ29udGVudHMgRGF0YSBpcyBub3QgYW4gT0NURVQgU1RSSU5HLicpOwogICAgICB9CiAgICAgIHNhZmVDb250ZW50cyA9IF9kZWNvZGVQa2NzN0RhdGEoZGF0YSkudmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSBwa2kub2lkcy5lbmNyeXB0ZWREYXRhOgogICAgICBzYWZlQ29udGVudHMgPSBfZGVjcnlwdFNhZmVDb250ZW50cyhkYXRhLCBwYXNzd29yZCk7CiAgICAgIG9iai5lbmNyeXB0ZWQgPSB0cnVlOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgUEtDUyMxMiBjb250ZW50VHlwZS4nKTsKICAgICAgZXJyb3IuY29udGVudFR5cGUgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUuY29udGVudFR5cGUpOwogICAgICB0aHJvdyBlcnJvcjsKICAgIH0KCiAgICBvYmouc2FmZUJhZ3MgPSBfZGVjb2RlU2FmZUNvbnRlbnRzKHNhZmVDb250ZW50cywgc3RyaWN0LCBwYXNzd29yZCk7CiAgICBwZnguc2FmZUNvbnRlbnRzLnB1c2gob2JqKTsKICB9Cn0KCi8qKgogKiBEZWNyeXB0IFBLQ1MjNyBFbmNyeXB0ZWREYXRhIHN0cnVjdHVyZS4KICoKICogQHBhcmFtIGRhdGEgQVNOLjEgZW5jb2RlZCBFbmNyeXB0ZWRDb250ZW50SW5mbyBvYmplY3QuCiAqIEBwYXJhbSBwYXNzd29yZCBUaGUgdXNlci1wcm92aWRlZCBwYXNzd29yZC4KICoKICogQHJldHVybiBUaGUgZGVjcnlwdGVkIFNhZmVDb250ZW50cyAoQVNOLjEgb2JqZWN0KS4KICovCmZ1bmN0aW9uIF9kZWNyeXB0U2FmZUNvbnRlbnRzKGRhdGEsIHBhc3N3b3JkKSB7CiAgdmFyIGNhcHR1cmUgPSB7fTsKICB2YXIgZXJyb3JzID0gW107CiAgaWYoIWFzbjEudmFsaWRhdGUoCiAgICBkYXRhLCBmb3JnZS5wa2NzNy5hc24xLmVuY3J5cHRlZERhdGFWYWxpZGF0b3IsIGNhcHR1cmUsIGVycm9ycykpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgRW5jcnlwdGVkQ29udGVudEluZm8uJyk7CiAgICBlcnJvci5lcnJvcnMgPSBlcnJvcnM7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIHZhciBvaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUuY29udGVudFR5cGUpOwogIGlmKG9pZCAhPT0gcGtpLm9pZHMuZGF0YSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKAogICAgICAnUEtDUyMxMiBFbmNyeXB0ZWRDb250ZW50SW5mbyBDb250ZW50VHlwZSBpcyBub3QgRGF0YS4nKTsKICAgIGVycm9yLm9pZCA9IG9pZDsKICAgIHRocm93IGVycm9yOwogIH0KCiAgLy8gZ2V0IGNpcGhlcgogIG9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5lbmNBbGdvcml0aG0pOwogIHZhciBjaXBoZXIgPSBwa2kucGJlLmdldENpcGhlcihvaWQsIGNhcHR1cmUuZW5jUGFyYW1ldGVyLCBwYXNzd29yZCk7CgogIC8vIGdldCBlbmNyeXB0ZWQgZGF0YQogIHZhciBlbmNyeXB0ZWRDb250ZW50QXNuMSA9IF9kZWNvZGVQa2NzN0RhdGEoY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50QXNuMSk7CiAgdmFyIGVuY3J5cHRlZCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGVuY3J5cHRlZENvbnRlbnRBc24xLnZhbHVlKTsKCiAgY2lwaGVyLnVwZGF0ZShlbmNyeXB0ZWQpOwogIGlmKCFjaXBoZXIuZmluaXNoKCkpIHsKICAgIHRocm93IG5ldyBFcnJvcignRmFpbGVkIHRvIGRlY3J5cHQgUEtDUyMxMiBTYWZlQ29udGVudHMuJyk7CiAgfQoKICByZXR1cm4gY2lwaGVyLm91dHB1dC5nZXRCeXRlcygpOwp9CgovKioKICogRGVjb2RlIFBLQ1MjMTIgU2FmZUNvbnRlbnRzIChCRVItZW5jb2RlZCkgaW50byBhcnJheSBvZiBCYWcgb2JqZWN0cy4KICoKICogVGhlIHNhZmVDb250ZW50cyBpcyBhIEJFUi1lbmNvZGVkIFNFUVVFTkNFIE9GIFNhZmVCYWcuCiAqCiAqIEBwYXJhbSB7U3RyaW5nfSBzYWZlQ29udGVudHMgQkVSLWVuY29kZWQgc2FmZUNvbnRlbnRzLgogKiBAcGFyYW0gc3RyaWN0IHRydWUgdG8gdXNlIHN0cmljdCBERVIgZGVjb2RpbmcsIGZhbHNlIG5vdCB0by4KICogQHBhcmFtIHtTdHJpbmd9IHBhc3N3b3JkIFBhc3N3b3JkIHRvIGRlY3J5cHQgd2l0aCAob3B0aW9uYWwpLgogKgogKiBAcmV0dXJuIHtBcnJheX0gQXJyYXkgb2YgQmFnIG9iamVjdHMuCiAqLwpmdW5jdGlvbiBfZGVjb2RlU2FmZUNvbnRlbnRzKHNhZmVDb250ZW50cywgc3RyaWN0LCBwYXNzd29yZCkgewogIC8vIGlmIHN0cmljdCBhbmQgbm8gc2FmZSBjb250ZW50cywgcmV0dXJuIGVtcHR5IHNhZmVzCiAgaWYoIXN0cmljdCAmJiBzYWZlQ29udGVudHMubGVuZ3RoID09PSAwKSB7CiAgICByZXR1cm4gW107CiAgfQoKICAvLyBhY3R1YWxseSBpdCdzIEJFUi1lbmNvZGVkCiAgc2FmZUNvbnRlbnRzID0gYXNuMS5mcm9tRGVyKHNhZmVDb250ZW50cywgc3RyaWN0KTsKCiAgaWYoc2FmZUNvbnRlbnRzLnRhZ0NsYXNzICE9PSBhc24xLkNsYXNzLlVOSVZFUlNBTCB8fAogICAgc2FmZUNvbnRlbnRzLnR5cGUgIT09IGFzbjEuVHlwZS5TRVFVRU5DRSB8fAogICAgc2FmZUNvbnRlbnRzLmNvbnN0cnVjdGVkICE9PSB0cnVlKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICdQS0NTIzEyIFNhZmVDb250ZW50cyBleHBlY3RlZCB0byBiZSBhIFNFUVVFTkNFIE9GIFNhZmVCYWcuJyk7CiAgfQoKICB2YXIgcmVzID0gW107CiAgZm9yKHZhciBpID0gMDsgaSA8IHNhZmVDb250ZW50cy52YWx1ZS5sZW5ndGg7IGkrKykgewogICAgdmFyIHNhZmVCYWcgPSBzYWZlQ29udGVudHMudmFsdWVbaV07CgogICAgLy8gdmFsaWRhdGUgU2FmZUJhZyBhbmQgY2FwdHVyZSBkYXRhCiAgICB2YXIgY2FwdHVyZSA9IHt9OwogICAgdmFyIGVycm9ycyA9IFtdOwogICAgaWYoIWFzbjEudmFsaWRhdGUoc2FmZUJhZywgc2FmZUJhZ1ZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFNhZmVCYWcuJyk7CiAgICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLyogQ3JlYXRlIGJhZyBvYmplY3QgYW5kIHB1c2ggdG8gcmVzdWx0IGFycmF5LiAqLwogICAgdmFyIGJhZyA9IHsKICAgICAgdHlwZTogYXNuMS5kZXJUb09pZChjYXB0dXJlLmJhZ0lkKSwKICAgICAgYXR0cmlidXRlczogX2RlY29kZUJhZ0F0dHJpYnV0ZXMoY2FwdHVyZS5iYWdBdHRyaWJ1dGVzKQogICAgfTsKICAgIHJlcy5wdXNoKGJhZyk7CgogICAgdmFyIHZhbGlkYXRvciwgZGVjb2RlcjsKICAgIHZhciBiYWdBc24xID0gY2FwdHVyZS5iYWdWYWx1ZS52YWx1ZVswXTsKICAgIHN3aXRjaChiYWcudHlwZSkgewogICAgICBjYXNlIHBraS5vaWRzLnBrY3M4U2hyb3VkZWRLZXlCYWc6CiAgICAgICAgLyogYmFnQXNuMSBoYXMgYSBFbmNyeXB0ZWRQcml2YXRlS2V5SW5mbywgd2hpY2ggd2UgbmVlZCB0byBkZWNyeXB0LgogICAgICAgICAgIEFmdGVyd2FyZHMgd2UgY2FuIGhhbmRsZSBpdCBsaWtlIGEga2V5QmFnLAogICAgICAgICAgIHdoaWNoIGlzIGEgUHJpdmF0ZUtleUluZm8uICovCiAgICAgICAgYmFnQXNuMSA9IHBraS5kZWNyeXB0UHJpdmF0ZUtleUluZm8oYmFnQXNuMSwgcGFzc3dvcmQpOwogICAgICAgIGlmKGJhZ0FzbjEgPT09IG51bGwpIHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcigKICAgICAgICAgICAgJ1VuYWJsZSB0byBkZWNyeXB0IFBLQ1MjOCBTaHJvdWRlZEtleUJhZywgd3JvbmcgcGFzc3dvcmQ/Jyk7CiAgICAgICAgfQoKICAgICAgICAvKiBmYWxsIHRocm91Z2ggKi8KICAgICAgY2FzZSBwa2kub2lkcy5rZXlCYWc6CiAgICAgICAgLyogQSBQS0NTIzEyIGtleUJhZyBpcyBhIHNpbXBsZSBQcml2YXRlS2V5SW5mbyBhcyB1bmRlcnN0b29kIGJ5IG91cgogICAgICAgICAgIFBLSSBtb2R1bGUsIGhlbmNlIHdlIGRvbid0IGhhdmUgdG8gZG8gdmFsaWRhdGlvbi9jYXB0dXJpbmcgaGVyZSwKICAgICAgICAgICBqdXN0IHBhc3Mgd2hhdCB3ZSBhbHJlYWR5IGdvdC4gKi8KICAgICAgICB0cnkgewogICAgICAgICAgYmFnLmtleSA9IHBraS5wcml2YXRlS2V5RnJvbUFzbjEoYmFnQXNuMSk7CiAgICAgICAgfSBjYXRjaChlKSB7CiAgICAgICAgICAvLyBpZ25vcmUgdW5rbm93biBrZXkgdHlwZSwgcGFzcyBhc24xIHZhbHVlCiAgICAgICAgICBiYWcua2V5ID0gbnVsbDsKICAgICAgICAgIGJhZy5hc24xID0gYmFnQXNuMTsKICAgICAgICB9CiAgICAgICAgY29udGludWU7ICAvKiBOb3RoaW5nIG1vcmUgdG8gZG8uICovCgogICAgICBjYXNlIHBraS5vaWRzLmNlcnRCYWc6CiAgICAgICAgLyogQSBQS0NTIzEyIGNlcnRCYWcgY2FuIHdyYXAgYm90aCBYLjUwOSBhbmQgc2RzaSBjZXJ0aWZpY2F0ZXMuCiAgICAgICAgICAgVGhlcmVmb3JlIHB1dCB0aGUgU2FmZUJhZyBjb250ZW50IHRocm91Z2ggYW5vdGhlciB2YWxpZGF0b3IgdG8KICAgICAgICAgICBjYXB0dXJlIHRoZSBmaWVsZHMuICBBZnRlcndhcmRzIGNoZWNrICYgc3RvcmUgdGhlIHJlc3VsdHMuICovCiAgICAgICAgdmFsaWRhdG9yID0gY2VydEJhZ1ZhbGlkYXRvcjsKICAgICAgICBkZWNvZGVyID0gZnVuY3Rpb24oKSB7CiAgICAgICAgICBpZihhc24xLmRlclRvT2lkKGNhcHR1cmUuY2VydElkKSAhPT0gcGtpLm9pZHMueDUwOUNlcnRpZmljYXRlKSB7CiAgICAgICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcigKICAgICAgICAgICAgICAnVW5zdXBwb3J0ZWQgY2VydGlmaWNhdGUgdHlwZSwgb25seSBYLjUwOSBzdXBwb3J0ZWQuJyk7CiAgICAgICAgICAgIGVycm9yLm9pZCA9IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5jZXJ0SWQpOwogICAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyB0cnVlPXByb2R1Y2UgY2VydCBoYXNoCiAgICAgICAgICB2YXIgY2VydEFzbjEgPSBhc24xLmZyb21EZXIoY2FwdHVyZS5jZXJ0LCBzdHJpY3QpOwogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgYmFnLmNlcnQgPSBwa2kuY2VydGlmaWNhdGVGcm9tQXNuMShjZXJ0QXNuMSwgdHJ1ZSk7CiAgICAgICAgICB9IGNhdGNoKGUpIHsKICAgICAgICAgICAgLy8gaWdub3JlIHVua25vd24gY2VydCB0eXBlLCBwYXNzIGFzbjEgdmFsdWUKICAgICAgICAgICAgYmFnLmNlcnQgPSBudWxsOwogICAgICAgICAgICBiYWcuYXNuMSA9IGNlcnRBc24xOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgUEtDUyMxMiBTYWZlQmFnIHR5cGUuJyk7CiAgICAgICAgZXJyb3Iub2lkID0gYmFnLnR5cGU7CiAgICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLyogVmFsaWRhdGUgU2FmZUJhZyB2YWx1ZSAoaS5lLiBDZXJ0QmFnLCBldGMuKSBhbmQgY2FwdHVyZSBkYXRhIGlmIG5lZWRlZC4gKi8KICAgIGlmKHZhbGlkYXRvciAhPT0gdW5kZWZpbmVkICYmCiAgICAgICAhYXNuMS52YWxpZGF0ZShiYWdBc24xLCB2YWxpZGF0b3IsIGNhcHR1cmUsIGVycm9ycykpIHsKICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzEyICcgKyB2YWxpZGF0b3IubmFtZSk7CiAgICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgLyogQ2FsbCBkZWNvZGVyIGZ1bmN0aW9uIGZyb20gYWJvdmUgdG8gc3RvcmUgdGhlIHJlc3VsdHMuICovCiAgICBkZWNvZGVyKCk7CiAgfQoKICByZXR1cm4gcmVzOwp9CgovKioKICogRGVjb2RlIFBLQ1MjMTIgU0VUIE9GIFBLQ1MxMkF0dHJpYnV0ZSBpbnRvIEphdmFTY3JpcHQgb2JqZWN0LgogKgogKiBAcGFyYW0gYXR0cmlidXRlcyBTRVQgT0YgUEtDUzEyQXR0cmlidXRlIChBU04uMSBvYmplY3QpLgogKgogKiBAcmV0dXJuIHRoZSBkZWNvZGVkIGF0dHJpYnV0ZXMuCiAqLwpmdW5jdGlvbiBfZGVjb2RlQmFnQXR0cmlidXRlcyhhdHRyaWJ1dGVzKSB7CiAgdmFyIGRlY29kZWRBdHRycyA9IHt9OwoKICBpZihhdHRyaWJ1dGVzICE9PSB1bmRlZmluZWQpIHsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgKytpKSB7CiAgICAgIHZhciBjYXB0dXJlID0ge307CiAgICAgIHZhciBlcnJvcnMgPSBbXTsKICAgICAgaWYoIWFzbjEudmFsaWRhdGUoYXR0cmlidXRlc1tpXSwgYXR0cmlidXRlVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzEyIEJhZ0F0dHJpYnV0ZS4nKTsKICAgICAgICBlcnJvci5lcnJvcnMgPSBlcnJvcnM7CiAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgIH0KCiAgICAgIHZhciBvaWQgPSBhc24xLmRlclRvT2lkKGNhcHR1cmUub2lkKTsKICAgICAgaWYocGtpLm9pZHNbb2lkXSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgLy8gdW5zdXBwb3J0ZWQgYXR0cmlidXRlIHR5cGUsIGlnbm9yZS4KICAgICAgICBjb250aW51ZTsKICAgICAgfQoKICAgICAgZGVjb2RlZEF0dHJzW3BraS5vaWRzW29pZF1dID0gW107CiAgICAgIGZvcih2YXIgaiA9IDA7IGogPCBjYXB0dXJlLnZhbHVlcy5sZW5ndGg7ICsraikgewogICAgICAgIGRlY29kZWRBdHRyc1twa2kub2lkc1tvaWRdXS5wdXNoKGNhcHR1cmUudmFsdWVzW2pdLnZhbHVlKTsKICAgICAgfQogICAgfQogIH0KCiAgcmV0dXJuIGRlY29kZWRBdHRyczsKfQoKLyoqCiAqIFdyYXBzIGEgcHJpdmF0ZSBrZXkgYW5kIGNlcnRpZmljYXRlIGluIGEgUEtDUyMxMiBQRlggd3JhcHBlci4gSWYgYQogKiBwYXNzd29yZCBpcyBwcm92aWRlZCB0aGVuIHRoZSBwcml2YXRlIGtleSB3aWxsIGJlIGVuY3J5cHRlZC4KICoKICogQW4gZW50aXJlIGNlcnRpZmljYXRlIGNoYWluIG1heSBhbHNvIGJlIGluY2x1ZGVkLiBUbyBkbyB0aGlzLCBwYXNzCiAqIGFuIGFycmF5IGZvciB0aGUgImNlcnQiIHBhcmFtZXRlciB3aGVyZSB0aGUgZmlyc3QgY2VydGlmaWNhdGUgaXMKICogdGhlIG9uZSB0aGF0IGlzIHBhaXJlZCB3aXRoIHRoZSBwcml2YXRlIGtleSBhbmQgZWFjaCBzdWJzZXF1ZW50IG9uZQogKiB2ZXJpZmllcyB0aGUgcHJldmlvdXMgb25lLiBUaGUgY2VydGlmaWNhdGVzIG1heSBiZSBpbiBQRU0gZm9ybWF0IG9yCiAqIGhhdmUgYmVlbiBhbHJlYWR5IHBhcnNlZCBieSBGb3JnZS4KICoKICogQHRvZG8gaW1wbGVtZW50IHBhc3N3b3JkLWJhc2VkLWVuY3J5cHRpb24gZm9yIHRoZSB3aG9sZSBwYWNrYWdlCiAqCiAqIEBwYXJhbSBrZXkgdGhlIHByaXZhdGUga2V5LgogKiBAcGFyYW0gY2VydCB0aGUgY2VydGlmaWNhdGUgKG1heSBiZSBhbiBhcnJheSBvZiBjZXJ0aWZpY2F0ZXMgaW4gb3JkZXIKICogICAgICAgICAgdG8gc3BlY2lmeSBhIGNlcnRpZmljYXRlIGNoYWluKS4KICogQHBhcmFtIHBhc3N3b3JkIHRoZSBwYXNzd29yZCB0byB1c2UsIG51bGwgZm9yIG5vbmUuCiAqIEBwYXJhbSBvcHRpb25zOgogKiAgICAgICAgICBhbGdvcml0aG0gdGhlIGVuY3J5cHRpb24gYWxnb3JpdGhtIHRvIHVzZQogKiAgICAgICAgICAgICgnYWVzMTI4JywgJ2FlczE5MicsICdhZXMyNTYnLCAnM2RlcycpLCBkZWZhdWx0cyB0byAnYWVzMTI4Jy4KICogICAgICAgICAgY291bnQgdGhlIGl0ZXJhdGlvbiBjb3VudCB0byB1c2UuCiAqICAgICAgICAgIHNhbHRTaXplIHRoZSBzYWx0IHNpemUgdG8gdXNlLgogKiAgICAgICAgICB1c2VNYWMgdHJ1ZSB0byBpbmNsdWRlIGEgTUFDLCBmYWxzZSBub3QgdG8sIGRlZmF1bHRzIHRvIHRydWUuCiAqICAgICAgICAgIGxvY2FsS2V5SWQgdGhlIGxvY2FsIGtleSBJRCB0byB1c2UsIGluIGhleC4KICogICAgICAgICAgZnJpZW5kbHlOYW1lIHRoZSBmcmllbmRseSBuYW1lIHRvIHVzZS4KICogICAgICAgICAgZ2VuZXJhdGVMb2NhbEtleUlkIHRydWUgdG8gZ2VuZXJhdGUgYSByYW5kb20gbG9jYWwga2V5IElELAogKiAgICAgICAgICAgIGZhbHNlIG5vdCB0bywgZGVmYXVsdHMgdG8gdHJ1ZS4KICoKICogQHJldHVybiB0aGUgUEtDUyMxMiBQRlggQVNOLjEgb2JqZWN0LgogKi8KcDEyLnRvUGtjczEyQXNuMSA9IGZ1bmN0aW9uKGtleSwgY2VydCwgcGFzc3dvcmQsIG9wdGlvbnMpIHsKICAvLyBzZXQgZGVmYXVsdCBvcHRpb25zCiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgb3B0aW9ucy5zYWx0U2l6ZSA9IG9wdGlvbnMuc2FsdFNpemUgfHwgODsKICBvcHRpb25zLmNvdW50ID0gb3B0aW9ucy5jb3VudCB8fCAyMDQ4OwogIG9wdGlvbnMuYWxnb3JpdGhtID0gb3B0aW9ucy5hbGdvcml0aG0gfHwgb3B0aW9ucy5lbmNBbGdvcml0aG0gfHwgJ2FlczEyOCc7CiAgaWYoISgndXNlTWFjJyBpbiBvcHRpb25zKSkgewogICAgb3B0aW9ucy51c2VNYWMgPSB0cnVlOwogIH0KICBpZighKCdsb2NhbEtleUlkJyBpbiBvcHRpb25zKSkgewogICAgb3B0aW9ucy5sb2NhbEtleUlkID0gbnVsbDsKICB9CiAgaWYoISgnZ2VuZXJhdGVMb2NhbEtleUlkJyBpbiBvcHRpb25zKSkgewogICAgb3B0aW9ucy5nZW5lcmF0ZUxvY2FsS2V5SWQgPSB0cnVlOwogIH0KCiAgdmFyIGxvY2FsS2V5SWQgPSBvcHRpb25zLmxvY2FsS2V5SWQ7CiAgdmFyIGJhZ0F0dHJzOwogIGlmKGxvY2FsS2V5SWQgIT09IG51bGwpIHsKICAgIGxvY2FsS2V5SWQgPSBmb3JnZS51dGlsLmhleFRvQnl0ZXMobG9jYWxLZXlJZCk7CiAgfSBlbHNlIGlmKG9wdGlvbnMuZ2VuZXJhdGVMb2NhbEtleUlkKSB7CiAgICAvLyB1c2UgU0hBLTEgb2YgcGFpcmVkIGNlcnQsIGlmIGF2YWlsYWJsZQogICAgaWYoY2VydCkgewogICAgICB2YXIgcGFpcmVkQ2VydCA9IGZvcmdlLnV0aWwuaXNBcnJheShjZXJ0KSA/IGNlcnRbMF0gOiBjZXJ0OwogICAgICBpZih0eXBlb2YgcGFpcmVkQ2VydCA9PT0gJ3N0cmluZycpIHsKICAgICAgICBwYWlyZWRDZXJ0ID0gcGtpLmNlcnRpZmljYXRlRnJvbVBlbShwYWlyZWRDZXJ0KTsKICAgICAgfQogICAgICB2YXIgc2hhMSA9IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCk7CiAgICAgIHNoYTEudXBkYXRlKGFzbjEudG9EZXIocGtpLmNlcnRpZmljYXRlVG9Bc24xKHBhaXJlZENlcnQpKS5nZXRCeXRlcygpKTsKICAgICAgbG9jYWxLZXlJZCA9IHNoYTEuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIEZJWE1FOiBjb25zaWRlciB1c2luZyBTSEEtMSBvZiBwdWJsaWMga2V5ICh3aGljaCBjYW4gYmUgZ2VuZXJhdGVkCiAgICAgIC8vIGZyb20gcHJpdmF0ZSBrZXkgY29tcG9uZW50cyksIHNlZTogY2VydC5nZW5lcmF0ZVN1YmplY3RLZXlJZGVudGlmaWVyCiAgICAgIC8vIGdlbmVyYXRlIHJhbmRvbSBieXRlcwogICAgICBsb2NhbEtleUlkID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzKDIwKTsKICAgIH0KICB9CgogIHZhciBhdHRycyA9IFtdOwogIGlmKGxvY2FsS2V5SWQgIT09IG51bGwpIHsKICAgIGF0dHJzLnB1c2goCiAgICAgIC8vIGxvY2FsS2V5SUQKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIGF0dHJJZAogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgIGFzbjEub2lkVG9EZXIocGtpLm9pZHMubG9jYWxLZXlJZCkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgLy8gYXR0clZhbHVlcwogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VULCB0cnVlLCBbCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgICAgICAgbG9jYWxLZXlJZCkKICAgICAgICBdKQogICAgICBdKSk7CiAgfQogIGlmKCdmcmllbmRseU5hbWUnIGluIG9wdGlvbnMpIHsKICAgIGF0dHJzLnB1c2goCiAgICAgIC8vIGZyaWVuZGx5TmFtZQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8gYXR0cklkCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5mcmllbmRseU5hbWUpLmdldEJ5dGVzKCkpLAogICAgICAgIC8vIGF0dHJWYWx1ZXMKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFVCwgdHJ1ZSwgWwogICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5CTVBTVFJJTkcsIGZhbHNlLAogICAgICAgICAgICBvcHRpb25zLmZyaWVuZGx5TmFtZSkKICAgICAgICBdKQogICAgICBdKSk7CiAgfQoKICBpZihhdHRycy5sZW5ndGggPiAwKSB7CiAgICBiYWdBdHRycyA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VULCB0cnVlLCBhdHRycyk7CiAgfQoKICAvLyBjb2xsZWN0IGNvbnRlbnRzIGZvciBBdXRoZW50aWNhdGVkU2FmZQogIHZhciBjb250ZW50cyA9IFtdOwoKICAvLyBjcmVhdGUgc2FmZSBiYWcocykgZm9yIGNlcnRpZmljYXRlIGNoYWluCiAgdmFyIGNoYWluID0gW107CiAgaWYoY2VydCAhPT0gbnVsbCkgewogICAgaWYoZm9yZ2UudXRpbC5pc0FycmF5KGNlcnQpKSB7CiAgICAgIGNoYWluID0gY2VydDsKICAgIH0gZWxzZSB7CiAgICAgIGNoYWluID0gW2NlcnRdOwogICAgfQogIH0KCiAgdmFyIGNlcnRTYWZlQmFncyA9IFtdOwogIGZvcih2YXIgaSA9IDA7IGkgPCBjaGFpbi5sZW5ndGg7ICsraSkgewogICAgLy8gY29udmVydCBjZXJ0IGZyb20gUEVNIGFzIG5lY2Vzc2FyeQogICAgY2VydCA9IGNoYWluW2ldOwogICAgaWYodHlwZW9mIGNlcnQgPT09ICdzdHJpbmcnKSB7CiAgICAgIGNlcnQgPSBwa2kuY2VydGlmaWNhdGVGcm9tUGVtKGNlcnQpOwogICAgfQoKICAgIC8vIFNhZmVCYWcKICAgIHZhciBjZXJ0QmFnQXR0cnMgPSAoaSA9PT0gMCkgPyBiYWdBdHRycyA6IHVuZGVmaW5lZDsKICAgIHZhciBjZXJ0QXNuMSA9IHBraS5jZXJ0aWZpY2F0ZVRvQXNuMShjZXJ0KTsKICAgIHZhciBjZXJ0U2FmZUJhZyA9CiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAvLyBiYWdJZAogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgIGFzbjEub2lkVG9EZXIocGtpLm9pZHMuY2VydEJhZykuZ2V0Qnl0ZXMoKSksCiAgICAgICAgLy8gYmFnVmFsdWUKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICAgIC8vIENlcnRCYWcKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAgICAgLy8gY2VydElkCiAgICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgICAgICBhc24xLm9pZFRvRGVyKHBraS5vaWRzLng1MDlDZXJ0aWZpY2F0ZSkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgICAgIC8vIGNlcnRWYWx1ZSAoeDUwOUNlcnRpZmljYXRlKQogICAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLAogICAgICAgICAgICAgICAgYXNuMS50b0RlcihjZXJ0QXNuMSkuZ2V0Qnl0ZXMoKSkKICAgICAgICAgICAgXSldKV0pLAogICAgICAgIC8vIGJhZ0F0dHJpYnV0ZXMgKE9QVElPTkFMKQogICAgICAgIGNlcnRCYWdBdHRycwogICAgICBdKTsKICAgIGNlcnRTYWZlQmFncy5wdXNoKGNlcnRTYWZlQmFnKTsKICB9CgogIGlmKGNlcnRTYWZlQmFncy5sZW5ndGggPiAwKSB7CiAgICAvLyBTYWZlQ29udGVudHMKICAgIHZhciBjZXJ0U2FmZUNvbnRlbnRzID0gYXNuMS5jcmVhdGUoCiAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIGNlcnRTYWZlQmFncyk7CgogICAgLy8gQ29udGVudEluZm8KICAgIHZhciBjZXJ0Q0kgPQogICAgICAvLyBQS0NTIzcgQ29udGVudEluZm8KICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIGNvbnRlbnRUeXBlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgLy8gT0lEIGZvciB0aGUgY29udGVudCB0eXBlIGlzICdkYXRhJwogICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5kYXRhKS5nZXRCeXRlcygpKSwKICAgICAgICAvLyBjb250ZW50CiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbCiAgICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsCiAgICAgICAgICAgIGFzbjEudG9EZXIoY2VydFNhZmVDb250ZW50cykuZ2V0Qnl0ZXMoKSkKICAgICAgICBdKQogICAgICBdKTsKICAgIGNvbnRlbnRzLnB1c2goY2VydENJKTsKICB9CgogIC8vIGNyZWF0ZSBzYWZlIGNvbnRlbnRzIGZvciBwcml2YXRlIGtleQogIHZhciBrZXlCYWcgPSBudWxsOwogIGlmKGtleSAhPT0gbnVsbCkgewogICAgLy8gU2FmZUJhZwogICAgdmFyIHBrQXNuMSA9IHBraS53cmFwUnNhUHJpdmF0ZUtleShwa2kucHJpdmF0ZUtleVRvQXNuMShrZXkpKTsKICAgIGlmKHBhc3N3b3JkID09PSBudWxsKSB7CiAgICAgIC8vIG5vIGVuY3J5cHRpb24KICAgICAga2V5QmFnID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIGJhZ0lkCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5rZXlCYWcpLmdldEJ5dGVzKCkpLAogICAgICAgIC8vIGJhZ1ZhbHVlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbCiAgICAgICAgICAvLyBQcml2YXRlS2V5SW5mbwogICAgICAgICAgcGtBc24xCiAgICAgICAgXSksCiAgICAgICAgLy8gYmFnQXR0cmlidXRlcyAoT1BUSU9OQUwpCiAgICAgICAgYmFnQXR0cnMKICAgICAgXSk7CiAgICB9IGVsc2UgewogICAgICAvLyBlbmNyeXB0ZWQgUHJpdmF0ZUtleUluZm8KICAgICAga2V5QmFnID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIGJhZ0lkCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5wa2NzOFNocm91ZGVkS2V5QmFnKS5nZXRCeXRlcygpKSwKICAgICAgICAvLyBiYWdWYWx1ZQogICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgWwogICAgICAgICAgLy8gRW5jcnlwdGVkUHJpdmF0ZUtleUluZm8KICAgICAgICAgIHBraS5lbmNyeXB0UHJpdmF0ZUtleUluZm8ocGtBc24xLCBwYXNzd29yZCwgb3B0aW9ucykKICAgICAgICBdKSwKICAgICAgICAvLyBiYWdBdHRyaWJ1dGVzIChPUFRJT05BTCkKICAgICAgICBiYWdBdHRycwogICAgICBdKTsKICAgIH0KCiAgICAvLyBTYWZlQ29udGVudHMKICAgIHZhciBrZXlTYWZlQ29udGVudHMgPQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBba2V5QmFnXSk7CgogICAgLy8gQ29udGVudEluZm8KICAgIHZhciBrZXlDSSA9CiAgICAgIC8vIFBLQ1MjNyBDb250ZW50SW5mbwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8gY29udGVudFR5cGUKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgICAvLyBPSUQgZm9yIHRoZSBjb250ZW50IHR5cGUgaXMgJ2RhdGEnCiAgICAgICAgICBhc24xLm9pZFRvRGVyKHBraS5vaWRzLmRhdGEpLmdldEJ5dGVzKCkpLAogICAgICAgIC8vIGNvbnRlbnQKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICAgIGFzbjEuY3JlYXRlKAogICAgICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgICAgICAgYXNuMS50b0RlcihrZXlTYWZlQ29udGVudHMpLmdldEJ5dGVzKCkpCiAgICAgICAgXSkKICAgICAgXSk7CiAgICBjb250ZW50cy5wdXNoKGtleUNJKTsKICB9CgogIC8vIGNyZWF0ZSBBdXRoZW50aWNhdGVkU2FmZSBieSBzdHJpbmdpbmcgdG9nZXRoZXIgdGhlIGNvbnRlbnRzCiAgdmFyIHNhZmUgPSBhc24xLmNyZWF0ZSgKICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIGNvbnRlbnRzKTsKCiAgdmFyIG1hY0RhdGE7CiAgaWYob3B0aW9ucy51c2VNYWMpIHsKICAgIC8vIE1hY0RhdGEKICAgIHZhciBzaGExID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICAgIHZhciBtYWNTYWx0ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigKICAgICAgZm9yZ2UucmFuZG9tLmdldEJ5dGVzKG9wdGlvbnMuc2FsdFNpemUpKTsKICAgIHZhciBjb3VudCA9IG9wdGlvbnMuY291bnQ7CiAgICAvLyAxNjAtYml0IGtleQogICAgdmFyIGtleSA9IHAxMi5nZW5lcmF0ZUtleShwYXNzd29yZCwgbWFjU2FsdCwgMywgY291bnQsIDIwKTsKICAgIHZhciBtYWMgPSBmb3JnZS5obWFjLmNyZWF0ZSgpOwogICAgbWFjLnN0YXJ0KHNoYTEsIGtleSk7CiAgICBtYWMudXBkYXRlKGFzbjEudG9EZXIoc2FmZSkuZ2V0Qnl0ZXMoKSk7CiAgICB2YXIgbWFjVmFsdWUgPSBtYWMuZ2V0TWFjKCk7CiAgICBtYWNEYXRhID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAvLyBtYWMgRGlnZXN0SW5mbwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgLy8gZGlnZXN0QWxnb3JpdGhtCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgICAgLy8gYWxnb3JpdGhtID0gU0hBLTEKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5zaGExKS5nZXRCeXRlcygpKSwKICAgICAgICAgIC8vIHBhcmFtZXRlcnMgPSBOdWxsCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgICAgICBdKSwKICAgICAgICAvLyBkaWdlc3QKICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsCiAgICAgICAgICBmYWxzZSwgbWFjVmFsdWUuZ2V0Qnl0ZXMoKSkKICAgICAgXSksCiAgICAgIC8vIG1hY1NhbHQgT0NURVQgU1RSSU5HCiAgICAgIGFzbjEuY3JlYXRlKAogICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLCBtYWNTYWx0LmdldEJ5dGVzKCkpLAogICAgICAvLyBpdGVyYXRpb25zIElOVEVHRVIgKFhYWDogT25seSBzdXBwb3J0IGNvdW50IDwgNjU1MzYpCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIoY291bnQpLmdldEJ5dGVzKCkKICAgICAgKQogICAgXSk7CiAgfQoKICAvLyBQRlgKICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gdmVyc2lvbiAoMykKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIGFzbjEuaW50ZWdlclRvRGVyKDMpLmdldEJ5dGVzKCkpLAogICAgLy8gUEtDUyM3IENvbnRlbnRJbmZvCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIGNvbnRlbnRUeXBlCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICAvLyBPSUQgZm9yIHRoZSBjb250ZW50IHR5cGUgaXMgJ2RhdGEnCiAgICAgICAgYXNuMS5vaWRUb0Rlcihwa2kub2lkcy5kYXRhKS5nZXRCeXRlcygpKSwKICAgICAgLy8gY29udGVudAogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICBhc24xLmNyZWF0ZSgKICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLAogICAgICAgICAgYXNuMS50b0RlcihzYWZlKS5nZXRCeXRlcygpKQogICAgICBdKQogICAgXSksCiAgICBtYWNEYXRhCiAgXSk7Cn07CgovKioKICogRGVyaXZlcyBhIFBLQ1MjMTIga2V5LgogKgogKiBAcGFyYW0gcGFzc3dvcmQgdGhlIHBhc3N3b3JkIHRvIGRlcml2ZSB0aGUga2V5IG1hdGVyaWFsIGZyb20sIG51bGwgb3IKICogICAgICAgICAgdW5kZWZpbmVkIGZvciBub25lLgogKiBAcGFyYW0gc2FsdCB0aGUgc2FsdCwgYXMgYSBCeXRlQnVmZmVyLCB0byB1c2UuCiAqIEBwYXJhbSBpZCB0aGUgUEtDUyMxMiBJRCBieXRlICgxID0ga2V5IG1hdGVyaWFsLCAyID0gSVYsIDMgPSBNQUMpLgogKiBAcGFyYW0gaXRlciB0aGUgaXRlcmF0aW9uIGNvdW50LgogKiBAcGFyYW0gbiB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGRlcml2ZSBmcm9tIHRoZSBwYXNzd29yZC4KICogQHBhcmFtIG1kIHRoZSBtZXNzYWdlIGRpZ2VzdCB0byB1c2UsIGRlZmF1bHRzIHRvIFNIQS0xLgogKgogKiBAcmV0dXJuIGEgQnl0ZUJ1ZmZlciB3aXRoIHRoZSBieXRlcyBkZXJpdmVkIGZyb20gdGhlIHBhc3N3b3JkLgogKi8KcDEyLmdlbmVyYXRlS2V5ID0gZm9yZ2UucGJlLmdlbmVyYXRlUGtjczEyS2V5OwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAncGtjczEyJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL3BrY3MxMicsWwogICdyZXF1aXJlJywKICAnbW9kdWxlJywKICAnLi9hc24xJywKICAnLi9obWFjJywKICAnLi9vaWRzJywKICAnLi9wa2NzN2FzbjEnLAogICcuL3BiZScsCiAgJy4vcmFuZG9tJywKICAnLi9yc2EnLAogICcuL3NoYTEnLAogICcuL3V0aWwnLAogICcuL3g1MDknCl0sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEphdmFzY3JpcHQgaW1wbGVtZW50YXRpb24gb2YgYSBiYXNpYyBQdWJsaWMgS2V5IEluZnJhc3RydWN0dXJlLCBpbmNsdWRpbmcKICogc3VwcG9ydCBmb3IgUlNBIHB1YmxpYyBhbmQgcHJpdmF0ZSBrZXlzLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxMyBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8vIHNob3J0Y3V0IGZvciBhc24uMSBBUEkKdmFyIGFzbjEgPSBmb3JnZS5hc24xOwoKLyogUHVibGljIEtleSBJbmZyYXN0cnVjdHVyZSAoUEtJKSBpbXBsZW1lbnRhdGlvbi4gKi8KdmFyIHBraSA9IGZvcmdlLnBraSA9IGZvcmdlLnBraSB8fCB7fTsKCi8qKgogKiBOT1RFOiBUSElTIE1FVEhPRCBJUyBERVBSRUNBVEVELiBVc2UgcGVtLmRlY29kZSgpIGluc3RlYWQuCiAqCiAqIENvbnZlcnRzIFBFTS1mb3JtYXR0ZWQgZGF0YSB0byBERVIuCiAqCiAqIEBwYXJhbSBwZW0gdGhlIFBFTS1mb3JtYXR0ZWQgZGF0YS4KICoKICogQHJldHVybiB0aGUgREVSLWZvcm1hdHRlZCBkYXRhLgogKi8KcGtpLnBlbVRvRGVyID0gZnVuY3Rpb24ocGVtKSB7CiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IFBFTSB0byBERVI7IFBFTSBpcyBlbmNyeXB0ZWQuJyk7CiAgfQogIHJldHVybiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihtc2cuYm9keSk7Cn07CgovKioKICogQ29udmVydHMgYW4gUlNBIHByaXZhdGUga2V5IGZyb20gUEVNIGZvcm1hdC4KICoKICogQHBhcmFtIHBlbSB0aGUgUEVNLWZvcm1hdHRlZCBwcml2YXRlIGtleS4KICoKICogQHJldHVybiB0aGUgcHJpdmF0ZSBrZXkuCiAqLwpwa2kucHJpdmF0ZUtleUZyb21QZW0gPSBmdW5jdGlvbihwZW0pIHsKICB2YXIgbXNnID0gZm9yZ2UucGVtLmRlY29kZShwZW0pWzBdOwoKICBpZihtc2cudHlwZSAhPT0gJ1BSSVZBVEUgS0VZJyAmJiBtc2cudHlwZSAhPT0gJ1JTQSBQUklWQVRFIEtFWScpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ291bGQgbm90IGNvbnZlcnQgcHJpdmF0ZSBrZXkgZnJvbSBQRU07IFBFTSAnICsKICAgICAgJ2hlYWRlciB0eXBlIGlzIG5vdCAiUFJJVkFURSBLRVkiIG9yICJSU0EgUFJJVkFURSBLRVkiLicpOwogICAgZXJyb3IuaGVhZGVyVHlwZSA9IG1zZy50eXBlOwogICAgdGhyb3cgZXJyb3I7CiAgfQogIGlmKG1zZy5wcm9jVHlwZSAmJiBtc2cucHJvY1R5cGUudHlwZSA9PT0gJ0VOQ1JZUFRFRCcpIHsKICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IGNvbnZlcnQgcHJpdmF0ZSBrZXkgZnJvbSBQRU07IFBFTSBpcyBlbmNyeXB0ZWQuJyk7CiAgfQoKICAvLyBjb252ZXJ0IERFUiB0byBBU04uMSBvYmplY3QKICB2YXIgb2JqID0gYXNuMS5mcm9tRGVyKG1zZy5ib2R5KTsKCiAgcmV0dXJuIHBraS5wcml2YXRlS2V5RnJvbUFzbjEob2JqKTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhbiBSU0EgcHJpdmF0ZSBrZXkgdG8gUEVNIGZvcm1hdC4KICoKICogQHBhcmFtIGtleSB0aGUgcHJpdmF0ZSBrZXkuCiAqIEBwYXJhbSBtYXhsaW5lIHRoZSBtYXhpbXVtIGNoYXJhY3RlcnMgcGVyIGxpbmUsIGRlZmF1bHRzIHRvIDY0LgogKgogKiBAcmV0dXJuIHRoZSBQRU0tZm9ybWF0dGVkIHByaXZhdGUga2V5LgogKi8KcGtpLnByaXZhdGVLZXlUb1BlbSA9IGZ1bmN0aW9uKGtleSwgbWF4bGluZSkgewogIC8vIGNvbnZlcnQgdG8gQVNOLjEsIHRoZW4gREVSLCB0aGVuIFBFTS1lbmNvZGUKICB2YXIgbXNnID0gewogICAgdHlwZTogJ1JTQSBQUklWQVRFIEtFWScsCiAgICBib2R5OiBhc24xLnRvRGVyKHBraS5wcml2YXRlS2V5VG9Bc24xKGtleSkpLmdldEJ5dGVzKCkKICB9OwogIHJldHVybiBmb3JnZS5wZW0uZW5jb2RlKG1zZywge21heGxpbmU6IG1heGxpbmV9KTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIFByaXZhdGVLZXlJbmZvIHRvIFBFTSBmb3JtYXQuCiAqCiAqIEBwYXJhbSBwa2kgdGhlIFByaXZhdGVLZXlJbmZvLgogKiBAcGFyYW0gbWF4bGluZSB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lLCBkZWZhdWx0cyB0byA2NC4KICoKICogQHJldHVybiB0aGUgUEVNLWZvcm1hdHRlZCBwcml2YXRlIGtleS4KICovCnBraS5wcml2YXRlS2V5SW5mb1RvUGVtID0gZnVuY3Rpb24ocGtpLCBtYXhsaW5lKSB7CiAgLy8gY29udmVydCB0byBERVIsIHRoZW4gUEVNLWVuY29kZQogIHZhciBtc2cgPSB7CiAgICB0eXBlOiAnUFJJVkFURSBLRVknLAogICAgYm9keTogYXNuMS50b0Rlcihwa2kpLmdldEJ5dGVzKCkKICB9OwogIHJldHVybiBmb3JnZS5wZW0uZW5jb2RlKG1zZywge21heGxpbmU6IG1heGxpbmV9KTsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3BraSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9wa2knLFsKICAncmVxdWlyZScsCiAgJ21vZHVsZScsCiAgJy4vYXNuMScsCiAgJy4vb2lkcycsCiAgJy4vcGJlJywKICAnLi9wZW0nLAogICcuL3Bia2RmMicsCiAgJy4vcGtjczEyJywKICAnLi9wc3MnLAogICcuL3JzYScsCiAgJy4vdXRpbCcsCiAgJy4veDUwOScKXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogQSBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIFRyYW5zcG9ydCBMYXllciBTZWN1cml0eSAoVExTKS4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDA5LTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICoKICogVGhlIFRMUyBIYW5kc2hha2UgUHJvdG9jb2wgaW52b2x2ZXMgdGhlIGZvbGxvd2luZyBzdGVwczoKICoKICogLSBFeGNoYW5nZSBoZWxsbyBtZXNzYWdlcyB0byBhZ3JlZSBvbiBhbGdvcml0aG1zLCBleGNoYW5nZSByYW5kb20gdmFsdWVzLAogKiBhbmQgY2hlY2sgZm9yIHNlc3Npb24gcmVzdW1wdGlvbi4KICoKICogLSBFeGNoYW5nZSB0aGUgbmVjZXNzYXJ5IGNyeXB0b2dyYXBoaWMgcGFyYW1ldGVycyB0byBhbGxvdyB0aGUgY2xpZW50IGFuZAogKiBzZXJ2ZXIgdG8gYWdyZWUgb24gYSBwcmVtYXN0ZXIgc2VjcmV0LgogKgogKiAtIEV4Y2hhbmdlIGNlcnRpZmljYXRlcyBhbmQgY3J5cHRvZ3JhcGhpYyBpbmZvcm1hdGlvbiB0byBhbGxvdyB0aGUgY2xpZW50CiAqIGFuZCBzZXJ2ZXIgdG8gYXV0aGVudGljYXRlIHRoZW1zZWx2ZXMuCiAqCiAqIC0gR2VuZXJhdGUgYSBtYXN0ZXIgc2VjcmV0IGZyb20gdGhlIHByZW1hc3RlciBzZWNyZXQgYW5kIGV4Y2hhbmdlZCByYW5kb20KICogdmFsdWVzLgogKgogKiAtIFByb3ZpZGUgc2VjdXJpdHkgcGFyYW1ldGVycyB0byB0aGUgcmVjb3JkIGxheWVyLgogKgogKiAtIEFsbG93IHRoZSBjbGllbnQgYW5kIHNlcnZlciB0byB2ZXJpZnkgdGhhdCB0aGVpciBwZWVyIGhhcyBjYWxjdWxhdGVkIHRoZQogKiBzYW1lIHNlY3VyaXR5IHBhcmFtZXRlcnMgYW5kIHRoYXQgdGhlIGhhbmRzaGFrZSBvY2N1cnJlZCB3aXRob3V0IHRhbXBlcmluZwogKiBieSBhbiBhdHRhY2tlci4KICoKICogVXAgdG8gNCBkaWZmZXJlbnQgbWVzc2FnZXMgbWF5IGJlIHNlbnQgZHVyaW5nIGEga2V5IGV4Y2hhbmdlLiBUaGUgc2VydmVyCiAqIGNlcnRpZmljYXRlLCB0aGUgc2VydmVyIGtleSBleGNoYW5nZSwgdGhlIGNsaWVudCBjZXJ0aWZpY2F0ZSwgYW5kIHRoZQogKiBjbGllbnQga2V5IGV4Y2hhbmdlLgogKgogKiBBIHR5cGljYWwgaGFuZHNoYWtlIChmcm9tIHRoZSBjbGllbnQncyBwZXJzcGVjdGl2ZSkuCiAqCiAqIDEuIENsaWVudCBzZW5kcyBDbGllbnRIZWxsby4KICogMi4gQ2xpZW50IHJlY2VpdmVzIFNlcnZlckhlbGxvLgogKiAzLiBDbGllbnQgcmVjZWl2ZXMgb3B0aW9uYWwgQ2VydGlmaWNhdGUuCiAqIDQuIENsaWVudCByZWNlaXZlcyBvcHRpb25hbCBTZXJ2ZXJLZXlFeGNoYW5nZS4KICogNS4gQ2xpZW50IHJlY2VpdmVzIFNlcnZlckhlbGxvRG9uZS4KICogNi4gQ2xpZW50IHNlbmRzIG9wdGlvbmFsIENlcnRpZmljYXRlLgogKiA3LiBDbGllbnQgc2VuZHMgQ2xpZW50S2V5RXhjaGFuZ2UuCiAqIDguIENsaWVudCBzZW5kcyBvcHRpb25hbCBDZXJ0aWZpY2F0ZVZlcmlmeS4KICogOS4gQ2xpZW50IHNlbmRzIENoYW5nZUNpcGhlclNwZWMuCiAqIDEwLiBDbGllbnQgc2VuZHMgRmluaXNoZWQuCiAqIDExLiBDbGllbnQgcmVjZWl2ZXMgQ2hhbmdlQ2lwaGVyU3BlYy4KICogMTIuIENsaWVudCByZWNlaXZlcyBGaW5pc2hlZC4KICogMTMuIENsaWVudCBzZW5kcy9yZWNlaXZlcyBhcHBsaWNhdGlvbiBkYXRhLgogKgogKiBUbyByZXVzZSBhbiBleGlzdGluZyBzZXNzaW9uOgogKgogKiAxLiBDbGllbnQgc2VuZHMgQ2xpZW50SGVsbG8gd2l0aCBzZXNzaW9uIElEIGZvciByZXVzZS4KICogMi4gQ2xpZW50IHJlY2VpdmVzIFNlcnZlckhlbGxvIHdpdGggc2FtZSBzZXNzaW9uIElEIGlmIHJldXNpbmcuCiAqIDMuIENsaWVudCByZWNlaXZlcyBDaGFuZ2VDaXBoZXJTcGVjIG1lc3NhZ2UgaWYgcmV1c2luZy4KICogNC4gQ2xpZW50IHJlY2VpdmVzIEZpbmlzaGVkLgogKiA1LiBDbGllbnQgc2VuZHMgQ2hhbmdlQ2lwaGVyU3BlYy4KICogNi4gQ2xpZW50IHNlbmRzIEZpbmlzaGVkLgogKgogKiBOb3RlOiBDbGllbnQgaWdub3JlcyBIZWxsb1JlcXVlc3QgaWYgaW4gdGhlIG1pZGRsZSBvZiBhIGhhbmRzaGFrZS4KICoKICogUmVjb3JkIExheWVyOgogKgogKiBUaGUgcmVjb3JkIGxheWVyIGZyYWdtZW50cyBpbmZvcm1hdGlvbiBibG9ja3MgaW50byBUTFNQbGFpbnRleHQgcmVjb3JkcwogKiBjYXJyeWluZyBkYXRhIGluIGNodW5rcyBvZiAyXjE0IGJ5dGVzIG9yIGxlc3MuIENsaWVudCBtZXNzYWdlIGJvdW5kYXJpZXMgYXJlCiAqIG5vdCBwcmVzZXJ2ZWQgaW4gdGhlIHJlY29yZCBsYXllciAoaS5lLiwgbXVsdGlwbGUgY2xpZW50IG1lc3NhZ2VzIG9mIHRoZQogKiBzYW1lIENvbnRlbnRUeXBlIE1BWSBiZSBjb2FsZXNjZWQgaW50byBhIHNpbmdsZSBUTFNQbGFpbnRleHQgcmVjb3JkLCBvciBhCiAqIHNpbmdsZSBtZXNzYWdlIE1BWSBiZSBmcmFnbWVudGVkIGFjcm9zcyBzZXZlcmFsIHJlY29yZHMpLgogKgogKiBzdHJ1Y3QgewogKiAgIHVpbnQ4IG1ham9yOwogKiAgIHVpbnQ4IG1pbm9yOwogKiB9IFByb3RvY29sVmVyc2lvbjsKICoKICogc3RydWN0IHsKICogICBDb250ZW50VHlwZSB0eXBlOwogKiAgIFByb3RvY29sVmVyc2lvbiB2ZXJzaW9uOwogKiAgIHVpbnQxNiBsZW5ndGg7CiAqICAgb3BhcXVlIGZyYWdtZW50W1RMU1BsYWludGV4dC5sZW5ndGhdOwogKiB9IFRMU1BsYWludGV4dDsKICoKICogdHlwZToKICogICBUaGUgaGlnaGVyLWxldmVsIHByb3RvY29sIHVzZWQgdG8gcHJvY2VzcyB0aGUgZW5jbG9zZWQgZnJhZ21lbnQuCiAqCiAqIHZlcnNpb246CiAqICAgVGhlIHZlcnNpb24gb2YgdGhlIHByb3RvY29sIGJlaW5nIGVtcGxveWVkLiBUTFMgVmVyc2lvbiAxLjIgdXNlcyB2ZXJzaW9uCiAqICAgezMsIDN9LiBUTFMgVmVyc2lvbiAxLjAgdXNlcyB2ZXJzaW9uIHszLCAxfS4gTm90ZSB0aGF0IGEgY2xpZW50IHRoYXQKICogICBzdXBwb3J0cyBtdWx0aXBsZSB2ZXJzaW9ucyBvZiBUTFMgbWF5IG5vdCBrbm93IHdoYXQgdmVyc2lvbiB3aWxsIGJlCiAqICAgZW1wbG95ZWQgYmVmb3JlIGl0IHJlY2VpdmVzIHRoZSBTZXJ2ZXJIZWxsby4KICoKICogbGVuZ3RoOgogKiAgIFRoZSBsZW5ndGggKGluIGJ5dGVzKSBvZiB0aGUgZm9sbG93aW5nIFRMU1BsYWludGV4dC5mcmFnbWVudC4gVGhlIGxlbmd0aAogKiAgIE1VU1QgTk9UIGV4Y2VlZCAyXjE0ID0gMTYzODQgYnl0ZXMuCiAqCiAqIGZyYWdtZW50OgogKiAgIFRoZSBhcHBsaWNhdGlvbiBkYXRhLiBUaGlzIGRhdGEgaXMgdHJhbnNwYXJlbnQgYW5kIHRyZWF0ZWQgYXMgYW4KICogICBpbmRlcGVuZGVudCBibG9jayB0byBiZSBkZWFsdCB3aXRoIGJ5IHRoZSBoaWdoZXItbGV2ZWwgcHJvdG9jb2wgc3BlY2lmaWVkCiAqICAgYnkgdGhlIHR5cGUgZmllbGQuCiAqCiAqIEltcGxlbWVudGF0aW9ucyBNVVNUIE5PVCBzZW5kIHplcm8tbGVuZ3RoIGZyYWdtZW50cyBvZiBIYW5kc2hha2UsIEFsZXJ0LCBvcgogKiBDaGFuZ2VDaXBoZXJTcGVjIGNvbnRlbnQgdHlwZXMuIFplcm8tbGVuZ3RoIGZyYWdtZW50cyBvZiBBcHBsaWNhdGlvbiBkYXRhCiAqIE1BWSBiZSBzZW50IGFzIHRoZXkgYXJlIHBvdGVudGlhbGx5IHVzZWZ1bCBhcyBhIHRyYWZmaWMgYW5hbHlzaXMKICogY291bnRlcm1lYXN1cmUuCiAqCiAqIE5vdGU6IERhdGEgb2YgZGlmZmVyZW50IFRMUyByZWNvcmQgbGF5ZXIgY29udGVudCB0eXBlcyBNQVkgYmUgaW50ZXJsZWF2ZWQuCiAqIEFwcGxpY2F0aW9uIGRhdGEgaXMgZ2VuZXJhbGx5IG9mIGxvd2VyIHByZWNlZGVuY2UgZm9yIHRyYW5zbWlzc2lvbiB0aGFuCiAqIG90aGVyIGNvbnRlbnQgdHlwZXMuIEhvd2V2ZXIsIHJlY29yZHMgTVVTVCBiZSBkZWxpdmVyZWQgdG8gdGhlIG5ldHdvcmsgaW4KICogdGhlIHNhbWUgb3JkZXIgYXMgdGhleSBhcmUgcHJvdGVjdGVkIGJ5IHRoZSByZWNvcmQgbGF5ZXIuIFJlY2lwaWVudHMgTVVTVAogKiByZWNlaXZlIGFuZCBwcm9jZXNzIGludGVybGVhdmVkIGFwcGxpY2F0aW9uIGxheWVyIHRyYWZmaWMgZHVyaW5nIGhhbmRzaGFrZXMKICogc3Vic2VxdWVudCB0byB0aGUgZmlyc3Qgb25lIG9uIGEgY29ubmVjdGlvbi4KICoKICogc3RydWN0IHsKICogICBDb250ZW50VHlwZSB0eXBlOyAgICAgICAvLyBzYW1lIGFzIFRMU1BsYWludGV4dC50eXBlCiAqICAgUHJvdG9jb2xWZXJzaW9uIHZlcnNpb247Ly8gc2FtZSBhcyBUTFNQbGFpbnRleHQudmVyc2lvbgogKiAgIHVpbnQxNiBsZW5ndGg7CiAqICAgb3BhcXVlIGZyYWdtZW50W1RMU0NvbXByZXNzZWQubGVuZ3RoXTsKICogfSBUTFNDb21wcmVzc2VkOwogKgogKiBsZW5ndGg6CiAqICAgVGhlIGxlbmd0aCAoaW4gYnl0ZXMpIG9mIHRoZSBmb2xsb3dpbmcgVExTQ29tcHJlc3NlZC5mcmFnbWVudC4KICogICBUaGUgbGVuZ3RoIE1VU1QgTk9UIGV4Y2VlZCAyXjE0ICsgMTAyNC4KICoKICogZnJhZ21lbnQ6CiAqICAgVGhlIGNvbXByZXNzZWQgZm9ybSBvZiBUTFNQbGFpbnRleHQuZnJhZ21lbnQuCiAqCiAqIE5vdGU6IEEgQ29tcHJlc3Npb25NZXRob2QubnVsbCBvcGVyYXRpb24gaXMgYW4gaWRlbnRpdHkgb3BlcmF0aW9uOyBubyBmaWVsZHMKICogYXJlIGFsdGVyZWQuIEluIHRoaXMgaW1wbGVtZW50YXRpb24sIHNpbmNlIG5vIGNvbXByZXNzaW9uIGlzIHN1cHBvcnRlZCwKICogdW5jb21wcmVzc2VkIHJlY29yZHMgYXJlIGFsd2F5cyB0aGUgc2FtZSBhcyBjb21wcmVzc2VkIHJlY29yZHMuCiAqCiAqIEVuY3J5cHRpb24gSW5mb3JtYXRpb246CiAqCiAqIFRoZSBlbmNyeXB0aW9uIGFuZCBNQUMgZnVuY3Rpb25zIHRyYW5zbGF0ZSBhIFRMU0NvbXByZXNzZWQgc3RydWN0dXJlIGludG8gYQogKiBUTFNDaXBoZXJ0ZXh0LiBUaGUgZGVjcnlwdGlvbiBmdW5jdGlvbnMgcmV2ZXJzZSB0aGUgcHJvY2Vzcy4gVGhlIE1BQyBvZiB0aGUKICogcmVjb3JkIGFsc28gaW5jbHVkZXMgYSBzZXF1ZW5jZSBudW1iZXIgc28gdGhhdCBtaXNzaW5nLCBleHRyYSwgb3IgcmVwZWF0ZWQKICogbWVzc2FnZXMgYXJlIGRldGVjdGFibGUuCiAqCiAqIHN0cnVjdCB7CiAqICAgQ29udGVudFR5cGUgdHlwZTsKICogICBQcm90b2NvbFZlcnNpb24gdmVyc2lvbjsKICogICB1aW50MTYgbGVuZ3RoOwogKiAgIHNlbGVjdCAoU2VjdXJpdHlQYXJhbWV0ZXJzLmNpcGhlcl90eXBlKSB7CiAqICAgICBjYXNlIHN0cmVhbTogR2VuZXJpY1N0cmVhbUNpcGhlcjsKICogICAgIGNhc2UgYmxvY2s6ICBHZW5lcmljQmxvY2tDaXBoZXI7CiAqICAgICBjYXNlIGFlYWQ6ICAgR2VuZXJpY0FFQURDaXBoZXI7CiAqICAgfSBmcmFnbWVudDsKICogfSBUTFNDaXBoZXJ0ZXh0OwogKgogKiB0eXBlOgogKiAgIFRoZSB0eXBlIGZpZWxkIGlzIGlkZW50aWNhbCB0byBUTFNDb21wcmVzc2VkLnR5cGUuCiAqCiAqIHZlcnNpb246CiAqICAgVGhlIHZlcnNpb24gZmllbGQgaXMgaWRlbnRpY2FsIHRvIFRMU0NvbXByZXNzZWQudmVyc2lvbi4KICoKICogbGVuZ3RoOgogKiAgIFRoZSBsZW5ndGggKGluIGJ5dGVzKSBvZiB0aGUgZm9sbG93aW5nIFRMU0NpcGhlcnRleHQuZnJhZ21lbnQuCiAqICAgVGhlIGxlbmd0aCBNVVNUIE5PVCBleGNlZWQgMl4xNCArIDIwNDguCiAqCiAqIGZyYWdtZW50OgogKiAgIFRoZSBlbmNyeXB0ZWQgZm9ybSBvZiBUTFNDb21wcmVzc2VkLmZyYWdtZW50LCB3aXRoIHRoZSBNQUMuCiAqCiAqIE5vdGU6IE9ubHkgQ0JDIEJsb2NrIENpcGhlcnMgYXJlIHN1cHBvcnRlZCBieSB0aGlzIGltcGxlbWVudGF0aW9uLgogKgogKiBUaGUgVExTQ29tcHJlc3NlZC5mcmFnbWVudCBzdHJ1Y3R1cmVzIGFyZSBjb252ZXJ0ZWQgdG8vZnJvbSBibG9jawogKiBUTFNDaXBoZXJ0ZXh0LmZyYWdtZW50IHN0cnVjdHVyZXMuCiAqCiAqIHN0cnVjdCB7CiAqICAgb3BhcXVlIElWW1NlY3VyaXR5UGFyYW1ldGVycy5yZWNvcmRfaXZfbGVuZ3RoXTsKICogICBibG9jay1jaXBoZXJlZCBzdHJ1Y3QgewogKiAgICAgb3BhcXVlIGNvbnRlbnRbVExTQ29tcHJlc3NlZC5sZW5ndGhdOwogKiAgICAgb3BhcXVlIE1BQ1tTZWN1cml0eVBhcmFtZXRlcnMubWFjX2xlbmd0aF07CiAqICAgICB1aW50OCBwYWRkaW5nW0dlbmVyaWNCbG9ja0NpcGhlci5wYWRkaW5nX2xlbmd0aF07CiAqICAgICB1aW50OCBwYWRkaW5nX2xlbmd0aDsKICogICB9OwogKiB9IEdlbmVyaWNCbG9ja0NpcGhlcjsKICoKICogVGhlIE1BQyBpcyBnZW5lcmF0ZWQgYXMgZGVzY3JpYmVkIGluIFNlY3Rpb24gNi4yLjMuMS4KICoKICogSVY6CiAqICAgVGhlIEluaXRpYWxpemF0aW9uIFZlY3RvciAoSVYpIFNIT1VMRCBiZSBjaG9zZW4gYXQgcmFuZG9tLCBhbmQgTVVTVCBiZQogKiAgIHVucHJlZGljdGFibGUuIE5vdGUgdGhhdCBpbiB2ZXJzaW9ucyBvZiBUTFMgcHJpb3IgdG8gMS4xLCB0aGVyZSB3YXMgbm8KICogICBJViBmaWVsZCwgYW5kIHRoZSBsYXN0IGNpcGhlcnRleHQgYmxvY2sgb2YgdGhlIHByZXZpb3VzIHJlY29yZCAodGhlICJDQkMKICogICByZXNpZHVlIikgd2FzIHVzZWQgYXMgdGhlIElWLiBUaGlzIHdhcyBjaGFuZ2VkIHRvIHByZXZlbnQgdGhlIGF0dGFja3MKICogICBkZXNjcmliZWQgaW4gW0NCQ0FUVF0uIEZvciBibG9jayBjaXBoZXJzLCB0aGUgSVYgbGVuZ3RoIGlzIG9mIGxlbmd0aAogKiAgIFNlY3VyaXR5UGFyYW1ldGVycy5yZWNvcmRfaXZfbGVuZ3RoLCB3aGljaCBpcyBlcXVhbCB0byB0aGUKICogICBTZWN1cml0eVBhcmFtZXRlcnMuYmxvY2tfc2l6ZS4KICoKICogcGFkZGluZzoKICogICBQYWRkaW5nIHRoYXQgaXMgYWRkZWQgdG8gZm9yY2UgdGhlIGxlbmd0aCBvZiB0aGUgcGxhaW50ZXh0IHRvIGJlIGFuCiAqICAgaW50ZWdyYWwgbXVsdGlwbGUgb2YgdGhlIGJsb2NrIGNpcGhlcidzIGJsb2NrIGxlbmd0aC4gVGhlIHBhZGRpbmcgTUFZIGJlCiAqICAgYW55IGxlbmd0aCB1cCB0byAyNTUgYnl0ZXMsIGFzIGxvbmcgYXMgaXQgcmVzdWx0cyBpbiB0aGUKICogICBUTFNDaXBoZXJ0ZXh0Lmxlbmd0aCBiZWluZyBhbiBpbnRlZ3JhbCBtdWx0aXBsZSBvZiB0aGUgYmxvY2sgbGVuZ3RoLgogKiAgIExlbmd0aHMgbG9uZ2VyIHRoYW4gbmVjZXNzYXJ5IG1pZ2h0IGJlIGRlc2lyYWJsZSB0byBmcnVzdHJhdGUgYXR0YWNrcyBvbgogKiAgIGEgcHJvdG9jb2wgdGhhdCBhcmUgYmFzZWQgb24gYW5hbHlzaXMgb2YgdGhlIGxlbmd0aHMgb2YgZXhjaGFuZ2VkCiAqICAgbWVzc2FnZXMuIEVhY2ggdWludDggaW4gdGhlIHBhZGRpbmcgZGF0YSB2ZWN0b3IgTVVTVCBiZSBmaWxsZWQgd2l0aCB0aGUKICogICBwYWRkaW5nIGxlbmd0aCB2YWx1ZS4gVGhlIHJlY2VpdmVyIE1VU1QgY2hlY2sgdGhpcyBwYWRkaW5nIGFuZCBNVVNUIHVzZQogKiAgIHRoZSBiYWRfcmVjb3JkX21hYyBhbGVydCB0byBpbmRpY2F0ZSBwYWRkaW5nIGVycm9ycy4KICoKICogcGFkZGluZ19sZW5ndGg6CiAqICAgVGhlIHBhZGRpbmcgbGVuZ3RoIE1VU1QgYmUgc3VjaCB0aGF0IHRoZSB0b3RhbCBzaXplIG9mIHRoZQogKiAgIEdlbmVyaWNCbG9ja0NpcGhlciBzdHJ1Y3R1cmUgaXMgYSBtdWx0aXBsZSBvZiB0aGUgY2lwaGVyJ3MgYmxvY2sgbGVuZ3RoLgogKiAgIExlZ2FsIHZhbHVlcyByYW5nZSBmcm9tIHplcm8gdG8gMjU1LCBpbmNsdXNpdmUuIFRoaXMgbGVuZ3RoIHNwZWNpZmllcyB0aGUKICogICBsZW5ndGggb2YgdGhlIHBhZGRpbmcgZmllbGQgZXhjbHVzaXZlIG9mIHRoZSBwYWRkaW5nX2xlbmd0aCBmaWVsZCBpdHNlbGYuCiAqCiAqIFRoZSBlbmNyeXB0ZWQgZGF0YSBsZW5ndGggKFRMU0NpcGhlcnRleHQubGVuZ3RoKSBpcyBvbmUgbW9yZSB0aGFuIHRoZSBzdW0gb2YKICogU2VjdXJpdHlQYXJhbWV0ZXJzLmJsb2NrX2xlbmd0aCwgVExTQ29tcHJlc3NlZC5sZW5ndGgsCiAqIFNlY3VyaXR5UGFyYW1ldGVycy5tYWNfbGVuZ3RoLCBhbmQgcGFkZGluZ19sZW5ndGguCiAqCiAqIEV4YW1wbGU6IElmIHRoZSBibG9jayBsZW5ndGggaXMgOCBieXRlcywgdGhlIGNvbnRlbnQgbGVuZ3RoCiAqIChUTFNDb21wcmVzc2VkLmxlbmd0aCkgaXMgNjEgYnl0ZXMsIGFuZCB0aGUgTUFDIGxlbmd0aCBpcyAyMCBieXRlcywgdGhlbiB0aGUKICogbGVuZ3RoIGJlZm9yZSBwYWRkaW5nIGlzIDgyIGJ5dGVzICh0aGlzIGRvZXMgbm90IGluY2x1ZGUgdGhlIElWLiBUaHVzLCB0aGUKICogcGFkZGluZyBsZW5ndGggbW9kdWxvIDggbXVzdCBiZSBlcXVhbCB0byA2IGluIG9yZGVyIHRvIG1ha2UgdGhlIHRvdGFsIGxlbmd0aAogKiBhbiBldmVuIG11bHRpcGxlIG9mIDggYnl0ZXMgKHRoZSBibG9jayBsZW5ndGgpLiBUaGUgcGFkZGluZyBsZW5ndGggY2FuIGJlCiAqIDYsIDE0LCAyMiwgYW5kIHNvIG9uLCB0aHJvdWdoIDI1NC4gSWYgdGhlIHBhZGRpbmcgbGVuZ3RoIHdlcmUgdGhlIG1pbmltdW0KICogbmVjZXNzYXJ5LCA2LCB0aGUgcGFkZGluZyB3b3VsZCBiZSA2IGJ5dGVzLCBlYWNoIGNvbnRhaW5pbmcgdGhlIHZhbHVlIDYuCiAqIFRodXMsIHRoZSBsYXN0IDggb2N0ZXRzIG9mIHRoZSBHZW5lcmljQmxvY2tDaXBoZXIgYmVmb3JlIGJsb2NrIGVuY3J5cHRpb24KICogd291bGQgYmUgeHggMDYgMDYgMDYgMDYgMDYgMDYgMDYsIHdoZXJlIHh4IGlzIHRoZSBsYXN0IG9jdGV0IG9mIHRoZSBNQUMuCiAqCiAqIE5vdGU6IFdpdGggYmxvY2sgY2lwaGVycyBpbiBDQkMgbW9kZSAoQ2lwaGVyIEJsb2NrIENoYWluaW5nKSwgaXQgaXMgY3JpdGljYWwKICogdGhhdCB0aGUgZW50aXJlIHBsYWludGV4dCBvZiB0aGUgcmVjb3JkIGJlIGtub3duIGJlZm9yZSBhbnkgY2lwaGVydGV4dCBpcwogKiB0cmFuc21pdHRlZC4gT3RoZXJ3aXNlLCBpdCBpcyBwb3NzaWJsZSBmb3IgdGhlIGF0dGFja2VyIHRvIG1vdW50IHRoZSBhdHRhY2sKICogZGVzY3JpYmVkIGluIFtDQkNBVFRdLgogKgogKiBJbXBsZW1lbnRhdGlvbiBub3RlOiBDYW52ZWwgZXQgYWwuIFtDQkNUSU1FXSBoYXZlIGRlbW9uc3RyYXRlZCBhIHRpbWluZwogKiBhdHRhY2sgb24gQ0JDIHBhZGRpbmcgYmFzZWQgb24gdGhlIHRpbWUgcmVxdWlyZWQgdG8gY29tcHV0ZSB0aGUgTUFDLiBJbgogKiBvcmRlciB0byBkZWZlbmQgYWdhaW5zdCB0aGlzIGF0dGFjaywgaW1wbGVtZW50YXRpb25zIE1VU1QgZW5zdXJlIHRoYXQKICogcmVjb3JkIHByb2Nlc3NpbmcgdGltZSBpcyBlc3NlbnRpYWxseSB0aGUgc2FtZSB3aGV0aGVyIG9yIG5vdCB0aGUgcGFkZGluZwogKiBpcyBjb3JyZWN0LiBJbiBnZW5lcmFsLCB0aGUgYmVzdCB3YXkgdG8gZG8gdGhpcyBpcyB0byBjb21wdXRlIHRoZSBNQUMgZXZlbgogKiBpZiB0aGUgcGFkZGluZyBpcyBpbmNvcnJlY3QsIGFuZCBvbmx5IHRoZW4gcmVqZWN0IHRoZSBwYWNrZXQuIEZvciBpbnN0YW5jZSwKICogaWYgdGhlIHBhZCBhcHBlYXJzIHRvIGJlIGluY29ycmVjdCwgdGhlIGltcGxlbWVudGF0aW9uIG1pZ2h0IGFzc3VtZSBhCiAqIHplcm8tbGVuZ3RoIHBhZCBhbmQgdGhlbiBjb21wdXRlIHRoZSBNQUMuIFRoaXMgbGVhdmVzIGEgc21hbGwgdGltaW5nCiAqIGNoYW5uZWwsIHNpbmNlIE1BQyBwZXJmb3JtYW5jZSBkZXBlbmRzLCB0byBzb21lIGV4dGVudCwgb24gdGhlIHNpemUgb2YgdGhlCiAqIGRhdGEgZnJhZ21lbnQsIGJ1dCBpdCBpcyBub3QgYmVsaWV2ZWQgdG8gYmUgbGFyZ2UgZW5vdWdoIHRvIGJlIGV4cGxvaXRhYmxlLAogKiBkdWUgdG8gdGhlIGxhcmdlIGJsb2NrIHNpemUgb2YgZXhpc3RpbmcgTUFDcyBhbmQgdGhlIHNtYWxsIHNpemUgb2YgdGhlCiAqIHRpbWluZyBzaWduYWwuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKLyoqCiAqIEdlbmVyYXRlcyBwc2V1ZG8gcmFuZG9tIGJ5dGVzIGJ5IG1peGluZyB0aGUgcmVzdWx0IG9mIHR3byBoYXNoIGZ1bmN0aW9ucywKICogTUQ1IGFuZCBTSEEtMS4KICoKICogcHJmX1RMUzEoc2VjcmV0LCBsYWJlbCwgc2VlZCkgPQogKiAgIFBfTUQ1KFMxLCBsYWJlbCArIHNlZWQpIFhPUiBQX1NIQS0xKFMyLCBsYWJlbCArIHNlZWQpOwogKgogKiBFYWNoIFBfaGFzaCBmdW5jdGlvbiBmdW5jdGlvbnMgYXMgZm9sbG93czoKICoKICogUF9oYXNoKHNlY3JldCwgc2VlZCkgPSBITUFDX2hhc2goc2VjcmV0LCBBKDEpICsgc2VlZCkgKwogKiAgICAgICAgICAgICAgICAgICAgICAgIEhNQUNfaGFzaChzZWNyZXQsIEEoMikgKyBzZWVkKSArCiAqICAgICAgICAgICAgICAgICAgICAgICAgSE1BQ19oYXNoKHNlY3JldCwgQSgzKSArIHNlZWQpICsgLi4uCiAqIEEoKSBpcyBkZWZpbmVkIGFzOgogKiAgIEEoMCkgPSBzZWVkCiAqICAgQShpKSA9IEhNQUNfaGFzaChzZWNyZXQsIEEoaS0xKSkKICoKICogVGhlICcrJyBvcGVyYXRvciBkZW5vdGVzIGNvbmNhdGVuYXRpb24uCiAqCiAqIEFzIG1hbnkgaXRlcmF0aW9ucyBBKE4pIGFzIGFyZSBuZWVkZWQgYXJlIHBlcmZvcm1lZCB0byBnZW5lcmF0ZSBlbm91Z2gKICogcHNldWRvIHJhbmRvbSBieXRlIG91dHB1dC4gSWYgYW4gaXRlcmF0aW9uIGNyZWF0ZXMgbW9yZSBkYXRhIHRoYW4gaXMKICogbmVjZXNzYXJ5LCB0aGVuIGl0IGlzIHRydW5jYXRlZC4KICoKICogVGhlcmVmb3JlOgogKiBBKDEpID0gSE1BQ19oYXNoKHNlY3JldCwgQSgwKSkKICogICAgICA9IEhNQUNfaGFzaChzZWNyZXQsIHNlZWQpCiAqIEEoMikgPSBITUFDX2hhc2goc2VjcmV0LCBBKDEpKQogKiAgICAgID0gSE1BQ19oYXNoKHNlY3JldCwgSE1BQ19oYXNoKHNlY3JldCwgc2VlZCkpCiAqCiAqIFRoZXJlZm9yZToKICogUF9oYXNoKHNlY3JldCwgc2VlZCkgPQogKiAgIEhNQUNfaGFzaChzZWNyZXQsIEhNQUNfaGFzaChzZWNyZXQsIEEoMCkpICsgc2VlZCkgKwogKiAgIEhNQUNfaGFzaChzZWNyZXQsIEhNQUNfaGFzaChzZWNyZXQsIEEoMSkpICsgc2VlZCkgKwogKiAgIC4uLgogKgogKiBUaGVyZWZvcmU6CiAqIFBfaGFzaChzZWNyZXQsIHNlZWQpID0KICogICBITUFDX2hhc2goc2VjcmV0LCBITUFDX2hhc2goc2VjcmV0LCBzZWVkKSArIHNlZWQpICsKICogICBITUFDX2hhc2goc2VjcmV0LCBITUFDX2hhc2goc2VjcmV0LCBITUFDX2hhc2goc2VjcmV0LCBzZWVkKSkgKyBzZWVkKSArCiAqICAgLi4uCiAqCiAqIEBwYXJhbSBzZWNyZXQgdGhlIHNlY3JldCB0byB1c2UuCiAqIEBwYXJhbSBsYWJlbCB0aGUgbGFiZWwgdG8gdXNlLgogKiBAcGFyYW0gc2VlZCB0aGUgc2VlZCB2YWx1ZSB0byB1c2UuCiAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyB0byBnZW5lcmF0ZS4KICoKICogQHJldHVybiB0aGUgcHNldWRvIHJhbmRvbSBieXRlcyBpbiBhIGJ5dGUgYnVmZmVyLgogKi8KdmFyIHByZl9UTFMxID0gZnVuY3Rpb24oc2VjcmV0LCBsYWJlbCwgc2VlZCwgbGVuZ3RoKSB7CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwoKICAvKiBGb3IgVExTIDEuMCwgdGhlIHNlY3JldCBpcyBzcGxpdCBpbiBoYWxmLCBpbnRvIHR3byBzZWNyZXRzIG9mIGVxdWFsCiAgICBsZW5ndGguIElmIHRoZSBzZWNyZXQgaGFzIGFuIG9kZCBsZW5ndGggdGhlbiB0aGUgbGFzdCBieXRlIG9mIHRoZSBmaXJzdAogICAgaGFsZiB3aWxsIGJlIHRoZSBzYW1lIGFzIHRoZSBmaXJzdCBieXRlIG9mIHRoZSBzZWNvbmQuIFRoZSBsZW5ndGggb2YgdGhlCiAgICB0d28gc2VjcmV0cyBpcyBoYWxmIG9mIHRoZSBzZWNyZXQgcm91bmRlZCB1cC4gKi8KICB2YXIgaWR4ID0gKHNlY3JldC5sZW5ndGggPj4gMSk7CiAgdmFyIHNsZW4gPSBpZHggKyAoc2VjcmV0Lmxlbmd0aCAmIDEpOwogIHZhciBzMSA9IHNlY3JldC5zdWJzdHIoMCwgc2xlbik7CiAgdmFyIHMyID0gc2VjcmV0LnN1YnN0cihpZHgsIHNsZW4pOwogIHZhciBhaSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdmFyIGhtYWMgPSBmb3JnZS5obWFjLmNyZWF0ZSgpOwogIHNlZWQgPSBsYWJlbCArIHNlZWQ7CgogIC8vIGRldGVybWluZSB0aGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgdGhhdCBtdXN0IGJlIHBlcmZvcm1lZCB0byBnZW5lcmF0ZQogIC8vIGVub3VnaCBvdXRwdXQgYnl0ZXMsIG1kNSBjcmVhdGVzIDE2IGJ5dGUgaGFzaGVzLCBzaGExIGNyZWF0ZXMgMjAKICB2YXIgbWQ1aXRyID0gTWF0aC5jZWlsKGxlbmd0aCAvIDE2KTsKICB2YXIgc2hhMWl0ciA9IE1hdGguY2VpbChsZW5ndGggLyAyMCk7CgogIC8vIGRvIG1kNSBpdGVyYXRpb25zCiAgaG1hYy5zdGFydCgnTUQ1JywgczEpOwogIHZhciBtZDVieXRlcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgYWkucHV0Qnl0ZXMoc2VlZCk7CiAgZm9yKHZhciBpID0gMDsgaSA8IG1kNWl0cjsgKytpKSB7CiAgICAvLyBITUFDX2hhc2goc2VjcmV0LCBBKGktMSkpCiAgICBobWFjLnN0YXJ0KG51bGwsIG51bGwpOwogICAgaG1hYy51cGRhdGUoYWkuZ2V0Qnl0ZXMoKSk7CiAgICBhaS5wdXRCdWZmZXIoaG1hYy5kaWdlc3QoKSk7CgogICAgLy8gSE1BQ19oYXNoKHNlY3JldCwgQShpKSArIHNlZWQpCiAgICBobWFjLnN0YXJ0KG51bGwsIG51bGwpOwogICAgaG1hYy51cGRhdGUoYWkuYnl0ZXMoKSArIHNlZWQpOwogICAgbWQ1Ynl0ZXMucHV0QnVmZmVyKGhtYWMuZGlnZXN0KCkpOwogIH0KCiAgLy8gZG8gc2hhMSBpdGVyYXRpb25zCiAgaG1hYy5zdGFydCgnU0hBMScsIHMyKTsKICB2YXIgc2hhMWJ5dGVzID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBhaS5jbGVhcigpOwogIGFpLnB1dEJ5dGVzKHNlZWQpOwogIGZvcih2YXIgaSA9IDA7IGkgPCBzaGExaXRyOyArK2kpIHsKICAgIC8vIEhNQUNfaGFzaChzZWNyZXQsIEEoaS0xKSkKICAgIGhtYWMuc3RhcnQobnVsbCwgbnVsbCk7CiAgICBobWFjLnVwZGF0ZShhaS5nZXRCeXRlcygpKTsKICAgIGFpLnB1dEJ1ZmZlcihobWFjLmRpZ2VzdCgpKTsKCiAgICAvLyBITUFDX2hhc2goc2VjcmV0LCBBKGkpICsgc2VlZCkKICAgIGhtYWMuc3RhcnQobnVsbCwgbnVsbCk7CiAgICBobWFjLnVwZGF0ZShhaS5ieXRlcygpICsgc2VlZCk7CiAgICBzaGExYnl0ZXMucHV0QnVmZmVyKGhtYWMuZGlnZXN0KCkpOwogIH0KCiAgLy8gWE9SIHRoZSBtZDUgYnl0ZXMgd2l0aCB0aGUgc2hhMSBieXRlcwogIHJ2YWwucHV0Qnl0ZXMoZm9yZ2UudXRpbC54b3JCeXRlcygKICAgIG1kNWJ5dGVzLmdldEJ5dGVzKCksIHNoYTFieXRlcy5nZXRCeXRlcygpLCBsZW5ndGgpKTsKCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogR2VuZXJhdGVzIHBzZXVkbyByYW5kb20gYnl0ZXMgdXNpbmcgYSBTSEEyNTYgYWxnb3JpdGhtLiBGb3IgVExTIDEuMi4KICoKICogQHBhcmFtIHNlY3JldCB0aGUgc2VjcmV0IHRvIHVzZS4KICogQHBhcmFtIGxhYmVsIHRoZSBsYWJlbCB0byB1c2UuCiAqIEBwYXJhbSBzZWVkIHRoZSBzZWVkIHZhbHVlIHRvIHVzZS4KICogQHBhcmFtIGxlbmd0aCB0aGUgbnVtYmVyIG9mIGJ5dGVzIHRvIGdlbmVyYXRlLgogKgogKiBAcmV0dXJuIHRoZSBwc2V1ZG8gcmFuZG9tIGJ5dGVzIGluIGEgYnl0ZSBidWZmZXIuCiAqLwp2YXIgcHJmX3NoYTI1NiA9IGZ1bmN0aW9uKHNlY3JldCwgbGFiZWwsIHNlZWQsIGxlbmd0aCkgewogICAvLyBGSVhNRTogaW1wbGVtZW50IG1lIGZvciBUTFMgMS4yCn07CgovKioKICogR2V0cyBhIE1BQyBmb3IgYSByZWNvcmQgdXNpbmcgdGhlIFNIQS0xIGhhc2ggYWxnb3JpdGhtLgogKgogKiBAcGFyYW0ga2V5IHRoZSBtYWMga2V5LgogKiBAcGFyYW0gc3RhdGUgdGhlIHNlcXVlbmNlIG51bWJlciAoYXJyYXkgb2YgdHdvIDMyLWJpdCBpbnRlZ2VycykuCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICoKICogQHJldHVybiB0aGUgc2hhLTEgaGFzaCAoMjAgYnl0ZXMpIGZvciB0aGUgZ2l2ZW4gcmVjb3JkLgogKi8KdmFyIGhtYWNfc2hhMSA9IGZ1bmN0aW9uKGtleSwgc2VxTnVtLCByZWNvcmQpIHsKICAvKiBNQUMgaXMgY29tcHV0ZWQgbGlrZSBzbzoKICBITUFDX2hhc2goCiAgICBrZXksIHNlcU51bSArCiAgICAgIFRMU0NvbXByZXNzZWQudHlwZSArCiAgICAgIFRMU0NvbXByZXNzZWQudmVyc2lvbiArCiAgICAgIFRMU0NvbXByZXNzZWQubGVuZ3RoICsKICAgICAgVExTQ29tcHJlc3NlZC5mcmFnbWVudCkKICAqLwogIHZhciBobWFjID0gZm9yZ2UuaG1hYy5jcmVhdGUoKTsKICBobWFjLnN0YXJ0KCdTSEExJywga2V5KTsKICB2YXIgYiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgYi5wdXRJbnQzMihzZXFOdW1bMF0pOwogIGIucHV0SW50MzIoc2VxTnVtWzFdKTsKICBiLnB1dEJ5dGUocmVjb3JkLnR5cGUpOwogIGIucHV0Qnl0ZShyZWNvcmQudmVyc2lvbi5tYWpvcik7CiAgYi5wdXRCeXRlKHJlY29yZC52ZXJzaW9uLm1pbm9yKTsKICBiLnB1dEludDE2KHJlY29yZC5sZW5ndGgpOwogIGIucHV0Qnl0ZXMocmVjb3JkLmZyYWdtZW50LmJ5dGVzKCkpOwogIGhtYWMudXBkYXRlKGIuZ2V0Qnl0ZXMoKSk7CiAgcmV0dXJuIGhtYWMuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKfTsKCi8qKgogKiBDb21wcmVzc2VzIHRoZSBUTFNQbGFpbnRleHQgcmVjb3JkIGludG8gYSBUTFNDb21wcmVzc2VkIHJlY29yZCB1c2luZyB0aGUKICogZGVmbGF0ZSBhbGdvcml0aG0uCiAqCiAqIEBwYXJhbSBjIHRoZSBUTFMgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgVExTUGxhaW50ZXh0IHJlY29yZCB0byBjb21wcmVzcy4KICogQHBhcmFtIHMgdGhlIENvbm5lY3Rpb25TdGF0ZSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KdmFyIGRlZmxhdGUgPSBmdW5jdGlvbihjLCByZWNvcmQsIHMpIHsKICB2YXIgcnZhbCA9IGZhbHNlOwoKICB0cnkgewogICAgdmFyIGJ5dGVzID0gYy5kZWZsYXRlKHJlY29yZC5mcmFnbWVudC5nZXRCeXRlcygpKTsKICAgIHJlY29yZC5mcmFnbWVudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGJ5dGVzKTsKICAgIHJlY29yZC5sZW5ndGggPSBieXRlcy5sZW5ndGg7CiAgICBydmFsID0gdHJ1ZTsKICB9IGNhdGNoKGV4KSB7CiAgICAvLyBkZWZsYXRlIGVycm9yLCBmYWlsIG91dAogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogRGVjb21wcmVzc2VzIHRoZSBUTFNDb21wcmVzc2VkIHJlY29yZCBpbnRvIGEgVExTUGxhaW50ZXh0IHJlY29yZCB1c2luZyB0aGUKICogZGVmbGF0ZSBhbGdvcml0aG0uCiAqCiAqIEBwYXJhbSBjIHRoZSBUTFMgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgVExTQ29tcHJlc3NlZCByZWNvcmQgdG8gZGVjb21wcmVzcy4KICogQHBhcmFtIHMgdGhlIENvbm5lY3Rpb25TdGF0ZSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KdmFyIGluZmxhdGUgPSBmdW5jdGlvbihjLCByZWNvcmQsIHMpIHsKICB2YXIgcnZhbCA9IGZhbHNlOwoKICB0cnkgewogICAgdmFyIGJ5dGVzID0gYy5pbmZsYXRlKHJlY29yZC5mcmFnbWVudC5nZXRCeXRlcygpKTsKICAgIHJlY29yZC5mcmFnbWVudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGJ5dGVzKTsKICAgIHJlY29yZC5sZW5ndGggPSBieXRlcy5sZW5ndGg7CiAgICBydmFsID0gdHJ1ZTsKICB9IGNhdGNoKGV4KSB7CiAgICAvLyBpbmZsYXRlIGVycm9yLCBmYWlsIG91dAogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogUmVhZHMgYSBUTFMgdmFyaWFibGUtbGVuZ3RoIHZlY3RvciBmcm9tIGEgYnl0ZSBidWZmZXIuCiAqCiAqIFZhcmlhYmxlLWxlbmd0aCB2ZWN0b3JzIGFyZSBkZWZpbmVkIGJ5IHNwZWNpZnlpbmcgYSBzdWJyYW5nZSBvZiBsZWdhbAogKiBsZW5ndGhzLCBpbmNsdXNpdmVseSwgdXNpbmcgdGhlIG5vdGF0aW9uIDxmbG9vci4uY2VpbGluZz4uIFdoZW4gdGhlc2UgYXJlCiAqIGVuY29kZWQsIHRoZSBhY3R1YWwgbGVuZ3RoIHByZWNlZGVzIHRoZSB2ZWN0b3IncyBjb250ZW50cyBpbiB0aGUgYnl0ZQogKiBzdHJlYW0uIFRoZSBsZW5ndGggd2lsbCBiZSBpbiB0aGUgZm9ybSBvZiBhIG51bWJlciBjb25zdW1pbmcgYXMgbWFueSBieXRlcwogKiBhcyByZXF1aXJlZCB0byBob2xkIHRoZSB2ZWN0b3IncyBzcGVjaWZpZWQgbWF4aW11bSAoY2VpbGluZykgbGVuZ3RoLiBBCiAqIHZhcmlhYmxlLWxlbmd0aCB2ZWN0b3Igd2l0aCBhbiBhY3R1YWwgbGVuZ3RoIGZpZWxkIG9mIHplcm8gaXMgcmVmZXJyZWQgdG8KICogYXMgYW4gZW1wdHkgdmVjdG9yLgogKgogKiBAcGFyYW0gYiB0aGUgYnl0ZSBidWZmZXIuCiAqIEBwYXJhbSBsZW5CeXRlcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIHN0b3JlIHRoZSBsZW5ndGguCiAqCiAqIEByZXR1cm4gdGhlIHJlc3VsdGluZyBieXRlIGJ1ZmZlci4KICovCnZhciByZWFkVmVjdG9yID0gZnVuY3Rpb24oYiwgbGVuQnl0ZXMpIHsKICB2YXIgbGVuID0gMDsKICBzd2l0Y2gobGVuQnl0ZXMpIHsKICBjYXNlIDE6CiAgICBsZW4gPSBiLmdldEJ5dGUoKTsKICAgIGJyZWFrOwogIGNhc2UgMjoKICAgIGxlbiA9IGIuZ2V0SW50MTYoKTsKICAgIGJyZWFrOwogIGNhc2UgMzoKICAgIGxlbiA9IGIuZ2V0SW50MjQoKTsKICAgIGJyZWFrOwogIGNhc2UgNDoKICAgIGxlbiA9IGIuZ2V0SW50MzIoKTsKICAgIGJyZWFrOwogIH0KCiAgLy8gcmVhZCB2ZWN0b3IgYnl0ZXMgaW50byBhIG5ldyBidWZmZXIKICByZXR1cm4gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoYi5nZXRCeXRlcyhsZW4pKTsKfTsKCi8qKgogKiBXcml0ZXMgYSBUTFMgdmFyaWFibGUtbGVuZ3RoIHZlY3RvciB0byBhIGJ5dGUgYnVmZmVyLgogKgogKiBAcGFyYW0gYiB0aGUgYnl0ZSBidWZmZXIuCiAqIEBwYXJhbSBsZW5CeXRlcyB0aGUgbnVtYmVyIG9mIGJ5dGVzIHJlcXVpcmVkIHRvIHN0b3JlIHRoZSBsZW5ndGguCiAqIEBwYXJhbSB2IHRoZSBieXRlIGJ1ZmZlciB2ZWN0b3IuCiAqLwp2YXIgd3JpdGVWZWN0b3IgPSBmdW5jdGlvbihiLCBsZW5CeXRlcywgdikgewogIC8vIGVuY29kZSBsZW5ndGggYXQgdGhlIHN0YXJ0IG9mIHRoZSB2ZWN0b3IsIHdoZXJlIHRoZSBudW1iZXIgb2YgYnl0ZXMgZm9yCiAgLy8gdGhlIGxlbmd0aCBpcyB0aGUgbWF4aW11bSBudW1iZXIgb2YgYnl0ZXMgaXQgd291bGQgdGFrZSB0byBlbmNvZGUgdGhlCiAgLy8gdmVjdG9yJ3MgY2VpbGluZwogIGIucHV0SW50KHYubGVuZ3RoKCksIGxlbkJ5dGVzIDw8IDMpOwogIGIucHV0QnVmZmVyKHYpOwp9OwoKLyoqCiAqIFRoZSB0bHMgaW1wbGVtZW50YXRpb24uCiAqLwp2YXIgdGxzID0ge307CgovKioKICogVmVyc2lvbjogVExTIDEuMiA9IDMuMywgVExTIDEuMSA9IDMuMiwgVExTIDEuMCA9IDMuMS4gQm90aCBUTFMgMS4xIGFuZAogKiBUTFMgMS4yIHdlcmUgc3RpbGwgdG9vIG5ldyAoaWU6IG9wZW5TU0wgZGlkbid0IGltcGxlbWVudCB0aGVtKSBhdCB0aGUgdGltZQogKiBvZiB0aGlzIGltcGxlbWVudGF0aW9uIHNvIFRMUyAxLjAgd2FzIGltcGxlbWVudGVkIGluc3RlYWQuCiAqLwp0bHMuVmVyc2lvbnMgPSB7CiAgVExTXzFfMDoge21ham9yOiAzLCBtaW5vcjogMX0sCiAgVExTXzFfMToge21ham9yOiAzLCBtaW5vcjogMn0sCiAgVExTXzFfMjoge21ham9yOiAzLCBtaW5vcjogM30KfTsKdGxzLlN1cHBvcnRlZFZlcnNpb25zID0gWwogIHRscy5WZXJzaW9ucy5UTFNfMV8xLAogIHRscy5WZXJzaW9ucy5UTFNfMV8wCl07CnRscy5WZXJzaW9uID0gdGxzLlN1cHBvcnRlZFZlcnNpb25zWzBdOwoKLyoqCiAqIE1heGltdW0gZnJhZ21lbnQgc2l6ZS4gVHJ1ZSBtYXhpbXVtIGlzIDE2Mzg0LCBidXQgd2UgZnJhZ21lbnQgYmVmb3JlIHRoYXQKICogdG8gYWxsb3cgZm9yIHVudXN1YWwgc21hbGwgaW5jcmVhc2VzIGR1cmluZyBjb21wcmVzc2lvbi4KICovCnRscy5NYXhGcmFnbWVudCA9IDE2Mzg0IC0gMTAyNDsKCi8qKgogKiBXaGV0aGVyIHRoaXMgZW50aXR5IGlzIGNvbnNpZGVyZWQgdGhlICJjbGllbnQiIG9yICJzZXJ2ZXIiLgogKiBlbnVtIHsgc2VydmVyLCBjbGllbnQgfSBDb25uZWN0aW9uRW5kOwogKi8KdGxzLkNvbm5lY3Rpb25FbmQgPSB7CiAgc2VydmVyOiAwLAogIGNsaWVudDogMQp9OwoKLyoqCiAqIFBzZXVkby1yYW5kb20gZnVuY3Rpb24gYWxnb3JpdGhtIHVzZWQgdG8gZ2VuZXJhdGUga2V5cyBmcm9tIHRoZSBtYXN0ZXIKICogc2VjcmV0LgogKiBlbnVtIHsgdGxzX3ByZl9zaGEyNTYgfSBQUkZBbGdvcml0aG07CiAqLwp0bHMuUFJGQWxnb3JpdGhtID0gewogIHRsc19wcmZfc2hhMjU2OiAwCn07CgovKioKICogQnVsayBlbmNyeXB0aW9uIGFsZ29yaXRobXMuCiAqIGVudW0geyBudWxsLCByYzQsIGRlczMsIGFlcyB9IEJ1bGtDaXBoZXJBbGdvcml0aG07CiAqLwp0bHMuQnVsa0NpcGhlckFsZ29yaXRobSA9IHsKICBub25lOiBudWxsLAogIHJjNDogMCwKICBkZXMzOiAxLAogIGFlczogMgp9OwoKLyoqCiAqIENpcGhlciB0eXBlcy4KICogZW51bSB7IHN0cmVhbSwgYmxvY2ssIGFlYWQgfSBDaXBoZXJUeXBlOwogKi8KdGxzLkNpcGhlclR5cGUgPSB7CiAgc3RyZWFtOiAwLAogIGJsb2NrOiAxLAogIGFlYWQ6IDIKfTsKCi8qKgogKiBNQUMgKE1lc3NhZ2UgQXV0aGVudGljYXRpb24gQ29kZSkgYWxnb3JpdGhtcy4KICogZW51bSB7IG51bGwsIGhtYWNfbWQ1LCBobWFjX3NoYTEsIGhtYWNfc2hhMjU2LAogKiAgIGhtYWNfc2hhMzg0LCBobWFjX3NoYTUxMn0gTUFDQWxnb3JpdGhtOwogKi8KdGxzLk1BQ0FsZ29yaXRobSA9IHsKICBub25lOiBudWxsLAogIGhtYWNfbWQ1OiAwLAogIGhtYWNfc2hhMTogMSwKICBobWFjX3NoYTI1NjogMiwKICBobWFjX3NoYTM4NDogMywKICBobWFjX3NoYTUxMjogNAp9OwoKLyoqCiAqIENvbXByZXNzaW9uIGFsZ29yaXRobXMuCiAqIGVudW0geyBudWxsKDApLCBkZWZsYXRlKDEpLCAoMjU1KSB9IENvbXByZXNzaW9uTWV0aG9kOwogKi8KdGxzLkNvbXByZXNzaW9uTWV0aG9kID0gewogIG5vbmU6IDAsCiAgZGVmbGF0ZTogMQp9OwoKLyoqCiAqIFRMUyByZWNvcmQgY29udGVudCB0eXBlcy4KICogZW51bSB7CiAqICAgY2hhbmdlX2NpcGhlcl9zcGVjKDIwKSwgYWxlcnQoMjEpLCBoYW5kc2hha2UoMjIpLAogKiAgIGFwcGxpY2F0aW9uX2RhdGEoMjMpLCAoMjU1KQogKiB9IENvbnRlbnRUeXBlOwogKi8KdGxzLkNvbnRlbnRUeXBlID0gewogIGNoYW5nZV9jaXBoZXJfc3BlYzogMjAsCiAgYWxlcnQ6IDIxLAogIGhhbmRzaGFrZTogMjIsCiAgYXBwbGljYXRpb25fZGF0YTogMjMsCiAgaGVhcnRiZWF0OiAyNAp9OwoKLyoqCiAqIFRMUyBoYW5kc2hha2UgdHlwZXMuCiAqIGVudW0gewogKiAgIGhlbGxvX3JlcXVlc3QoMCksIGNsaWVudF9oZWxsbygxKSwgc2VydmVyX2hlbGxvKDIpLAogKiAgIGNlcnRpZmljYXRlKDExKSwgc2VydmVyX2tleV9leGNoYW5nZSAoMTIpLAogKiAgIGNlcnRpZmljYXRlX3JlcXVlc3QoMTMpLCBzZXJ2ZXJfaGVsbG9fZG9uZSgxNCksCiAqICAgY2VydGlmaWNhdGVfdmVyaWZ5KDE1KSwgY2xpZW50X2tleV9leGNoYW5nZSgxNiksCiAqICAgZmluaXNoZWQoMjApLCAoMjU1KQogKiB9IEhhbmRzaGFrZVR5cGU7CiAqLwp0bHMuSGFuZHNoYWtlVHlwZSA9IHsKICBoZWxsb19yZXF1ZXN0OiAwLAogIGNsaWVudF9oZWxsbzogMSwKICBzZXJ2ZXJfaGVsbG86IDIsCiAgY2VydGlmaWNhdGU6IDExLAogIHNlcnZlcl9rZXlfZXhjaGFuZ2U6IDEyLAogIGNlcnRpZmljYXRlX3JlcXVlc3Q6IDEzLAogIHNlcnZlcl9oZWxsb19kb25lOiAxNCwKICBjZXJ0aWZpY2F0ZV92ZXJpZnk6IDE1LAogIGNsaWVudF9rZXlfZXhjaGFuZ2U6IDE2LAogIGZpbmlzaGVkOiAyMAp9OwoKLyoqCiAqIFRMUyBBbGVydCBQcm90b2NvbC4KICoKICogZW51bSB7IHdhcm5pbmcoMSksIGZhdGFsKDIpLCAoMjU1KSB9IEFsZXJ0TGV2ZWw7CiAqCiAqIGVudW0gewogKiAgIGNsb3NlX25vdGlmeSgwKSwKICogICB1bmV4cGVjdGVkX21lc3NhZ2UoMTApLAogKiAgIGJhZF9yZWNvcmRfbWFjKDIwKSwKICogICBkZWNyeXB0aW9uX2ZhaWxlZCgyMSksCiAqICAgcmVjb3JkX292ZXJmbG93KDIyKSwKICogICBkZWNvbXByZXNzaW9uX2ZhaWx1cmUoMzApLAogKiAgIGhhbmRzaGFrZV9mYWlsdXJlKDQwKSwKICogICBiYWRfY2VydGlmaWNhdGUoNDIpLAogKiAgIHVuc3VwcG9ydGVkX2NlcnRpZmljYXRlKDQzKSwKICogICBjZXJ0aWZpY2F0ZV9yZXZva2VkKDQ0KSwKICogICBjZXJ0aWZpY2F0ZV9leHBpcmVkKDQ1KSwKICogICBjZXJ0aWZpY2F0ZV91bmtub3duKDQ2KSwKICogICBpbGxlZ2FsX3BhcmFtZXRlcig0NyksCiAqICAgdW5rbm93bl9jYSg0OCksCiAqICAgYWNjZXNzX2RlbmllZCg0OSksCiAqICAgZGVjb2RlX2Vycm9yKDUwKSwKICogICBkZWNyeXB0X2Vycm9yKDUxKSwKICogICBleHBvcnRfcmVzdHJpY3Rpb24oNjApLAogKiAgIHByb3RvY29sX3ZlcnNpb24oNzApLAogKiAgIGluc3VmZmljaWVudF9zZWN1cml0eSg3MSksCiAqICAgaW50ZXJuYWxfZXJyb3IoODApLAogKiAgIHVzZXJfY2FuY2VsZWQoOTApLAogKiAgIG5vX3JlbmVnb3RpYXRpb24oMTAwKSwKICogICAoMjU1KQogKiB9IEFsZXJ0RGVzY3JpcHRpb247CiAqCiAqIHN0cnVjdCB7CiAqICAgQWxlcnRMZXZlbCBsZXZlbDsKICogICBBbGVydERlc2NyaXB0aW9uIGRlc2NyaXB0aW9uOwogKiB9IEFsZXJ0OwogKi8KdGxzLkFsZXJ0ID0ge307CnRscy5BbGVydC5MZXZlbCA9IHsKICB3YXJuaW5nOiAxLAogIGZhdGFsOiAyCn07CnRscy5BbGVydC5EZXNjcmlwdGlvbiA9IHsKICBjbG9zZV9ub3RpZnk6IDAsCiAgdW5leHBlY3RlZF9tZXNzYWdlOiAxMCwKICBiYWRfcmVjb3JkX21hYzogMjAsCiAgZGVjcnlwdGlvbl9mYWlsZWQ6IDIxLAogIHJlY29yZF9vdmVyZmxvdzogMjIsCiAgZGVjb21wcmVzc2lvbl9mYWlsdXJlOiAzMCwKICBoYW5kc2hha2VfZmFpbHVyZTogNDAsCiAgYmFkX2NlcnRpZmljYXRlOiA0MiwKICB1bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZTogNDMsCiAgY2VydGlmaWNhdGVfcmV2b2tlZDogNDQsCiAgY2VydGlmaWNhdGVfZXhwaXJlZDogNDUsCiAgY2VydGlmaWNhdGVfdW5rbm93bjogNDYsCiAgaWxsZWdhbF9wYXJhbWV0ZXI6IDQ3LAogIHVua25vd25fY2E6IDQ4LAogIGFjY2Vzc19kZW5pZWQ6IDQ5LAogIGRlY29kZV9lcnJvcjogNTAsCiAgZGVjcnlwdF9lcnJvcjogNTEsCiAgZXhwb3J0X3Jlc3RyaWN0aW9uOiA2MCwKICBwcm90b2NvbF92ZXJzaW9uOiA3MCwKICBpbnN1ZmZpY2llbnRfc2VjdXJpdHk6IDcxLAogIGludGVybmFsX2Vycm9yOiA4MCwKICB1c2VyX2NhbmNlbGVkOiA5MCwKICBub19yZW5lZ290aWF0aW9uOiAxMDAKfTsKCi8qKgogKiBUTFMgSGVhcnRiZWF0IE1lc3NhZ2UgdHlwZXMuCiAqIGVudW0gewogKiAgIGhlYXJ0YmVhdF9yZXF1ZXN0KDEpLAogKiAgIGhlYXJ0YmVhdF9yZXNwb25zZSgyKSwKICogICAoMjU1KQogKiB9IEhlYXJ0YmVhdE1lc3NhZ2VUeXBlOwogKi8KdGxzLkhlYXJ0YmVhdE1lc3NhZ2VUeXBlID0gewogIGhlYXJ0YmVhdF9yZXF1ZXN0OiAxLAogIGhlYXJ0YmVhdF9yZXNwb25zZTogMgp9OwoKLyoqCiAqIFN1cHBvcnRlZCBjaXBoZXIgc3VpdGVzLgogKi8KdGxzLkNpcGhlclN1aXRlcyA9IHt9OwoKLyoqCiAqIEdldHMgYSBzdXBwb3J0ZWQgY2lwaGVyIHN1aXRlIGZyb20gaXRzIDIgYnl0ZSBJRC4KICoKICogQHBhcmFtIHR3b0J5dGVzIHR3byBieXRlcyBpbiBhIHN0cmluZy4KICoKICogQHJldHVybiB0aGUgbWF0Y2hpbmcgc3VwcG9ydGVkIGNpcGhlciBzdWl0ZSBvciBudWxsLgogKi8KdGxzLmdldENpcGhlclN1aXRlID0gZnVuY3Rpb24odHdvQnl0ZXMpIHsKICB2YXIgcnZhbCA9IG51bGw7CiAgZm9yKHZhciBrZXkgaW4gdGxzLkNpcGhlclN1aXRlcykgewogICAgdmFyIGNzID0gdGxzLkNpcGhlclN1aXRlc1trZXldOwogICAgaWYoY3MuaWRbMF0gPT09IHR3b0J5dGVzLmNoYXJDb2RlQXQoMCkgJiYKICAgICAgY3MuaWRbMV0gPT09IHR3b0J5dGVzLmNoYXJDb2RlQXQoMSkpIHsKICAgICAgcnZhbCA9IGNzOwogICAgICBicmVhazsKICAgIH0KICB9CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ2FsbGVkIHdoZW4gYW4gdW5leHBlY3RlZCByZWNvcmQgaXMgZW5jb3VudGVyZWQuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqLwp0bHMuaGFuZGxlVW5leHBlY3RlZCA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogIC8vIGlmIGNvbm5lY3Rpb24gaXMgY2xpZW50IGFuZCBjbG9zZWQsIGlnbm9yZSB1bmV4cGVjdGVkIG1lc3NhZ2VzCiAgdmFyIGlnbm9yZSA9ICghYy5vcGVuICYmIGMuZW50aXR5ID09PSB0bHMuQ29ubmVjdGlvbkVuZC5jbGllbnQpOwogIGlmKCFpZ25vcmUpIHsKICAgIGMuZXJyb3IoYywgewogICAgICBtZXNzYWdlOiAnVW5leHBlY3RlZCBtZXNzYWdlLiBSZWNlaXZlZCBUTFMgcmVjb3JkIG91dCBvZiBvcmRlci4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi51bmV4cGVjdGVkX21lc3NhZ2UKICAgICAgfQogICAgfSk7CiAgfQp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgY2xpZW50IHJlY2VpdmVzIGEgSGVsbG9SZXF1ZXN0IHJlY29yZC4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVIZWxsb1JlcXVlc3QgPSBmdW5jdGlvbihjLCByZWNvcmQsIGxlbmd0aCkgewogIC8vIGlnbm9yZSByZW5lZ290aWF0aW9uIHJlcXVlc3RzIGZyb20gdGhlIHNlcnZlciBkdXJpbmcgYSBoYW5kc2hha2UsIGJ1dAogIC8vIGlmIGhhbmRzaGFraW5nLCBzZW5kIGEgd2FybmluZyBhbGVydCB0aGF0IHJlbmVnb3RhdGlvbiBpcyBkZW5pZWQKICBpZighYy5oYW5kc2hha2luZyAmJiBjLmhhbmRzaGFrZXMgPiAwKSB7CiAgICAvLyBzZW5kIGFsZXJ0IHdhcm5pbmcKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlQWxlcnQoYywgewogICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC53YXJuaW5nLAogICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5ub19yZW5lZ290aWF0aW9uCiAgICB9KSk7CiAgICB0bHMuZmx1c2goYyk7CiAgfQoKICAvLyBjb250aW51ZQogIGMucHJvY2VzcygpOwp9OwoKLyoqCiAqIFBhcnNlcyBhIGhlbGxvIG1lc3NhZ2UgZnJvbSBhIENsaWVudEhlbGxvIG9yIFNlcnZlckhlbGxvIHJlY29yZC4KICoKICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkIHRvIHBhcnNlLgogKgogKiBAcmV0dXJuIHRoZSBwYXJzZWQgbWVzc2FnZS4KICovCnRscy5wYXJzZUhlbGxvTWVzc2FnZSA9IGZ1bmN0aW9uKGMsIHJlY29yZCwgbGVuZ3RoKSB7CiAgdmFyIG1zZyA9IG51bGw7CgogIHZhciBjbGllbnQgPSAoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCk7CgogIC8vIG1pbmltdW0gb2YgMzggYnl0ZXMgaW4gbWVzc2FnZQogIGlmKGxlbmd0aCA8IDM4KSB7CiAgICBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogY2xpZW50ID8KICAgICAgICAnSW52YWxpZCBTZXJ2ZXJIZWxsbyBtZXNzYWdlLiBNZXNzYWdlIHRvbyBzaG9ydC4nIDoKICAgICAgICAnSW52YWxpZCBDbGllbnRIZWxsbyBtZXNzYWdlLiBNZXNzYWdlIHRvbyBzaG9ydC4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5pbGxlZ2FsX3BhcmFtZXRlcgogICAgICB9CiAgICB9KTsKICB9IGVsc2UgewogICAgLy8gdXNlICdyZW1haW5pbmcnIHRvIGNhbGN1bGF0ZSAjIG9mIHJlbWFpbmluZyBieXRlcyBpbiB0aGUgbWVzc2FnZQogICAgdmFyIGIgPSByZWNvcmQuZnJhZ21lbnQ7CiAgICB2YXIgcmVtYWluaW5nID0gYi5sZW5ndGgoKTsKICAgIG1zZyA9IHsKICAgICAgdmVyc2lvbjogewogICAgICAgIG1ham9yOiBiLmdldEJ5dGUoKSwKICAgICAgICBtaW5vcjogYi5nZXRCeXRlKCkKICAgICAgfSwKICAgICAgcmFuZG9tOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihiLmdldEJ5dGVzKDMyKSksCiAgICAgIHNlc3Npb25faWQ6IHJlYWRWZWN0b3IoYiwgMSksCiAgICAgIGV4dGVuc2lvbnM6IFtdCiAgICB9OwogICAgaWYoY2xpZW50KSB7CiAgICAgIG1zZy5jaXBoZXJfc3VpdGUgPSBiLmdldEJ5dGVzKDIpOwogICAgICBtc2cuY29tcHJlc3Npb25fbWV0aG9kID0gYi5nZXRCeXRlKCk7CiAgICB9IGVsc2UgewogICAgICBtc2cuY2lwaGVyX3N1aXRlcyA9IHJlYWRWZWN0b3IoYiwgMik7CiAgICAgIG1zZy5jb21wcmVzc2lvbl9tZXRob2RzID0gcmVhZFZlY3RvcihiLCAxKTsKICAgIH0KCiAgICAvLyByZWFkIGV4dGVuc2lvbnMgaWYgdGhlcmUgYXJlIGFueSBieXRlcyBsZWZ0IGluIHRoZSBtZXNzYWdlCiAgICByZW1haW5pbmcgPSBsZW5ndGggLSAocmVtYWluaW5nIC0gYi5sZW5ndGgoKSk7CiAgICBpZihyZW1haW5pbmcgPiAwKSB7CiAgICAgIC8vIHBhcnNlIGV4dGVuc2lvbnMKICAgICAgdmFyIGV4dHMgPSByZWFkVmVjdG9yKGIsIDIpOwogICAgICB3aGlsZShleHRzLmxlbmd0aCgpID4gMCkgewogICAgICAgIG1zZy5leHRlbnNpb25zLnB1c2goewogICAgICAgICAgdHlwZTogW2V4dHMuZ2V0Qnl0ZSgpLCBleHRzLmdldEJ5dGUoKV0sCiAgICAgICAgICBkYXRhOiByZWFkVmVjdG9yKGV4dHMsIDIpCiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgIC8vIFRPRE86IG1ha2UgZXh0ZW5zaW9uIHN1cHBvcnQgbW9kdWxhcgogICAgICBpZighY2xpZW50KSB7CiAgICAgICAgZm9yKHZhciBpID0gMDsgaSA8IG1zZy5leHRlbnNpb25zLmxlbmd0aDsgKytpKSB7CiAgICAgICAgICB2YXIgZXh0ID0gbXNnLmV4dGVuc2lvbnNbaV07CgogICAgICAgICAgLy8gc3VwcG9ydCBTTkkgZXh0ZW5zaW9uCiAgICAgICAgICBpZihleHQudHlwZVswXSA9PT0gMHgwMCAmJiBleHQudHlwZVsxXSA9PT0gMHgwMCkgewogICAgICAgICAgICAvLyBnZXQgc2VydmVyIG5hbWUgbGlzdAogICAgICAgICAgICB2YXIgc25sID0gcmVhZFZlY3RvcihleHQuZGF0YSwgMik7CiAgICAgICAgICAgIHdoaWxlKHNubC5sZW5ndGgoKSA+IDApIHsKICAgICAgICAgICAgICAvLyByZWFkIHNlcnZlciBuYW1lIHR5cGUKICAgICAgICAgICAgICB2YXIgc25UeXBlID0gc25sLmdldEJ5dGUoKTsKCiAgICAgICAgICAgICAgLy8gb25seSBIb3N0TmFtZSB0eXBlICgweDAwKSBpcyBrbm93biwgYnJlYWsgb3V0IGlmCiAgICAgICAgICAgICAgLy8gYW5vdGhlciB0eXBlIGlzIGRldGVjdGVkCiAgICAgICAgICAgICAgaWYoc25UeXBlICE9PSAweDAwKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIGFkZCBob3N0IG5hbWUgdG8gc2VydmVyIG5hbWUgbGlzdAogICAgICAgICAgICAgIGMuc2Vzc2lvbi5leHRlbnNpb25zLnNlcnZlcl9uYW1lLnNlcnZlck5hbWVMaXN0LnB1c2goCiAgICAgICAgICAgICAgICByZWFkVmVjdG9yKHNubCwgMikuZ2V0Qnl0ZXMoKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICAvLyB2ZXJzaW9uIGFscmVhZHkgc2V0LCBkbyBub3QgYWxsb3cgdmVyc2lvbiBjaGFuZ2UKICAgIGlmKGMuc2Vzc2lvbi52ZXJzaW9uKSB7CiAgICAgIGlmKG1zZy52ZXJzaW9uLm1ham9yICE9PSBjLnNlc3Npb24udmVyc2lvbi5tYWpvciB8fAogICAgICAgIG1zZy52ZXJzaW9uLm1pbm9yICE9PSBjLnNlc3Npb24udmVyc2lvbi5taW5vcikgewogICAgICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgICAgIG1lc3NhZ2U6ICdUTFMgdmVyc2lvbiBjaGFuZ2UgaXMgZGlzYWxsb3dlZCBkdXJpbmcgcmVuZWdvdGlhdGlvbi4nLAogICAgICAgICAgc2VuZDogdHJ1ZSwKICAgICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24ucHJvdG9jb2xfdmVyc2lvbgogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICB9CiAgICB9CgogICAgLy8gZ2V0IHRoZSBjaG9zZW4gKFNlcnZlckhlbGxvKSBjaXBoZXIgc3VpdGUKICAgIGlmKGNsaWVudCkgewogICAgICAvLyBGSVhNRTogc2hvdWxkIGJlIGNoZWNraW5nIGNvbmZpZ3VyZWQgYWNjZXB0YWJsZSBjaXBoZXIgc3VpdGVzCiAgICAgIGMuc2Vzc2lvbi5jaXBoZXJTdWl0ZSA9IHRscy5nZXRDaXBoZXJTdWl0ZShtc2cuY2lwaGVyX3N1aXRlKTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIGdldCBhIHN1cHBvcnRlZCBwcmVmZXJyZWQgKENsaWVudEhlbGxvKSBjaXBoZXIgc3VpdGUKICAgICAgLy8gY2hvb3NlIHRoZSBmaXJzdCBzdXBwb3J0ZWQgY2lwaGVyIHN1aXRlCiAgICAgIHZhciB0bXAgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihtc2cuY2lwaGVyX3N1aXRlcy5ieXRlcygpKTsKICAgICAgd2hpbGUodG1wLmxlbmd0aCgpID4gMCkgewogICAgICAgIC8vIEZJWE1FOiBzaG91bGQgYmUgY2hlY2tpbmcgY29uZmlndXJlZCBhY2NlcHRhYmxlIHN1aXRlcwogICAgICAgIC8vIGNpcGhlciBzdWl0ZXMgdGFrZSB1cCAyIGJ5dGVzCiAgICAgICAgYy5zZXNzaW9uLmNpcGhlclN1aXRlID0gdGxzLmdldENpcGhlclN1aXRlKHRtcC5nZXRCeXRlcygyKSk7CiAgICAgICAgaWYoYy5zZXNzaW9uLmNpcGhlclN1aXRlICE9PSBudWxsKSB7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICAvLyBjaXBoZXIgc3VpdGUgbm90IHN1cHBvcnRlZAogICAgaWYoYy5zZXNzaW9uLmNpcGhlclN1aXRlID09PSBudWxsKSB7CiAgICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgICBtZXNzYWdlOiAnTm8gY2lwaGVyIHN1aXRlcyBpbiBjb21tb24uJywKICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5oYW5kc2hha2VfZmFpbHVyZQogICAgICAgIH0sCiAgICAgICAgY2lwaGVyU3VpdGU6IGZvcmdlLnV0aWwuYnl0ZXNUb0hleChtc2cuY2lwaGVyX3N1aXRlKQogICAgICB9KTsKICAgIH0KCiAgICAvLyBUT0RPOiBoYW5kbGUgY29tcHJlc3Npb24gbWV0aG9kcwogICAgaWYoY2xpZW50KSB7CiAgICAgIGMuc2Vzc2lvbi5jb21wcmVzc2lvbk1ldGhvZCA9IG1zZy5jb21wcmVzc2lvbl9tZXRob2Q7CiAgICB9IGVsc2UgewogICAgICAvLyBubyBjb21wcmVzc2lvbgogICAgICBjLnNlc3Npb24uY29tcHJlc3Npb25NZXRob2QgPSB0bHMuQ29tcHJlc3Npb25NZXRob2Qubm9uZTsKICAgIH0KICB9CgogIHJldHVybiBtc2c7Cn07CgovKioKICogQ3JlYXRlcyBzZWN1cml0eSBwYXJhbWV0ZXJzIGZvciB0aGUgZ2l2ZW4gY29ubmVjdGlvbiBiYXNlZCBvbiB0aGUgZ2l2ZW4KICogaGVsbG8gbWVzc2FnZS4KICoKICogQHBhcmFtIGMgdGhlIFRMUyBjb25uZWN0aW9uLgogKiBAcGFyYW0gbXNnIHRoZSBoZWxsbyBtZXNzYWdlLgogKi8KdGxzLmNyZWF0ZVNlY3VyaXR5UGFyYW1ldGVycyA9IGZ1bmN0aW9uKGMsIG1zZykgewogIC8qIE5vdGU6IHNlY3VyaXR5IHBhcmFtcyBhcmUgZnJvbSBUTFMgMS4yLCBzb21lIHZhbHVlcyBsaWtlIHByZl9hbGdvcml0aG0KICBhcmUgaWdub3JlZCBmb3IgVExTIDEuMC8xLjEgYW5kIHRoZSBidWlsdGluIGFzIHNwZWNpZmllZCBpbiB0aGUgc3BlYyBpcwogIHVzZWQuICovCgogIC8vIFRPRE86IGhhbmRsZSBvdGhlciBvcHRpb25zIGZyb20gc2VydmVyIHdoZW4gbW9yZSBzdXBwb3J0ZWQKCiAgLy8gZ2V0IGNsaWVudCBhbmQgc2VydmVyIHJhbmRvbXMKICB2YXIgY2xpZW50ID0gKGMuZW50aXR5ID09PSB0bHMuQ29ubmVjdGlvbkVuZC5jbGllbnQpOwogIHZhciBtc2dSYW5kb20gPSBtc2cucmFuZG9tLmJ5dGVzKCk7CiAgdmFyIGNSYW5kb20gPSBjbGllbnQgPyBjLnNlc3Npb24uc3AuY2xpZW50X3JhbmRvbSA6IG1zZ1JhbmRvbTsKICB2YXIgc1JhbmRvbSA9IGNsaWVudCA/IG1zZ1JhbmRvbSA6IHRscy5jcmVhdGVSYW5kb20oKS5nZXRCeXRlcygpOwoKICAvLyBjcmVhdGUgbmV3IHNlY3VyaXR5IHBhcmFtZXRlcnMKICBjLnNlc3Npb24uc3AgPSB7CiAgICBlbnRpdHk6IGMuZW50aXR5LAogICAgcHJmX2FsZ29yaXRobTogdGxzLlBSRkFsZ29yaXRobS50bHNfcHJmX3NoYTI1NiwKICAgIGJ1bGtfY2lwaGVyX2FsZ29yaXRobTogbnVsbCwKICAgIGNpcGhlcl90eXBlOiBudWxsLAogICAgZW5jX2tleV9sZW5ndGg6IG51bGwsCiAgICBibG9ja19sZW5ndGg6IG51bGwsCiAgICBmaXhlZF9pdl9sZW5ndGg6IG51bGwsCiAgICByZWNvcmRfaXZfbGVuZ3RoOiBudWxsLAogICAgbWFjX2FsZ29yaXRobTogbnVsbCwKICAgIG1hY19sZW5ndGg6IG51bGwsCiAgICBtYWNfa2V5X2xlbmd0aDogbnVsbCwKICAgIGNvbXByZXNzaW9uX2FsZ29yaXRobTogYy5zZXNzaW9uLmNvbXByZXNzaW9uTWV0aG9kLAogICAgcHJlX21hc3Rlcl9zZWNyZXQ6IG51bGwsCiAgICBtYXN0ZXJfc2VjcmV0OiBudWxsLAogICAgY2xpZW50X3JhbmRvbTogY1JhbmRvbSwKICAgIHNlcnZlcl9yYW5kb206IHNSYW5kb20KICB9Owp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgY2xpZW50IHJlY2VpdmVzIGEgU2VydmVySGVsbG8gcmVjb3JkLgogKgogKiBXaGVuIGEgU2VydmVySGVsbG8gbWVzc2FnZSB3aWxsIGJlIHNlbnQ6CiAqICAgVGhlIHNlcnZlciB3aWxsIHNlbmQgdGhpcyBtZXNzYWdlIGluIHJlc3BvbnNlIHRvIGEgY2xpZW50IGhlbGxvIG1lc3NhZ2UKICogICB3aGVuIGl0IHdhcyBhYmxlIHRvIGZpbmQgYW4gYWNjZXB0YWJsZSBzZXQgb2YgYWxnb3JpdGhtcy4gSWYgaXQgY2Fubm90CiAqICAgZmluZCBzdWNoIGEgbWF0Y2gsIGl0IHdpbGwgcmVzcG9uZCB3aXRoIGEgaGFuZHNoYWtlIGZhaWx1cmUgYWxlcnQuCiAqCiAqIHVpbnQyNCBsZW5ndGg7CiAqIHN0cnVjdCB7CiAqICAgUHJvdG9jb2xWZXJzaW9uIHNlcnZlcl92ZXJzaW9uOwogKiAgIFJhbmRvbSByYW5kb207CiAqICAgU2Vzc2lvbklEIHNlc3Npb25faWQ7CiAqICAgQ2lwaGVyU3VpdGUgY2lwaGVyX3N1aXRlOwogKiAgIENvbXByZXNzaW9uTWV0aG9kIGNvbXByZXNzaW9uX21ldGhvZDsKICogICBzZWxlY3QoZXh0ZW5zaW9uc19wcmVzZW50KSB7CiAqICAgICBjYXNlIGZhbHNlOgogKiAgICAgICBzdHJ1Y3Qge307CiAqICAgICBjYXNlIHRydWU6CiAqICAgICAgIEV4dGVuc2lvbiBleHRlbnNpb25zPDAuLjJeMTYtMT47CiAqICAgfTsKICogfSBTZXJ2ZXJIZWxsbzsKICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVTZXJ2ZXJIZWxsbyA9IGZ1bmN0aW9uKGMsIHJlY29yZCwgbGVuZ3RoKSB7CiAgdmFyIG1zZyA9IHRscy5wYXJzZUhlbGxvTWVzc2FnZShjLCByZWNvcmQsIGxlbmd0aCk7CiAgaWYoYy5mYWlsKSB7CiAgICByZXR1cm47CiAgfQoKICAvLyBlbnN1cmUgc2VydmVyIHZlcnNpb24gaXMgY29tcGF0aWJsZQogIGlmKG1zZy52ZXJzaW9uLm1pbm9yIDw9IGMudmVyc2lvbi5taW5vcikgewogICAgYy52ZXJzaW9uLm1pbm9yID0gbXNnLnZlcnNpb24ubWlub3I7CiAgfSBlbHNlIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0luY29tcGF0aWJsZSBUTFMgdmVyc2lvbi4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5wcm90b2NvbF92ZXJzaW9uCiAgICAgIH0KICAgIH0pOwogIH0KCiAgLy8gaW5kaWNhdGUgc2Vzc2lvbiB2ZXJzaW9uIGhhcyBiZWVuIHNldAogIGMuc2Vzc2lvbi52ZXJzaW9uID0gYy52ZXJzaW9uOwoKICAvLyBnZXQgdGhlIHNlc3Npb24gSUQgZnJvbSB0aGUgbWVzc2FnZQogIHZhciBzZXNzaW9uSWQgPSBtc2cuc2Vzc2lvbl9pZC5ieXRlcygpOwoKICAvLyBpZiB0aGUgc2Vzc2lvbiBJRCBpcyBub3QgYmxhbmsgYW5kIG1hdGNoZXMgdGhlIGNhY2hlZCBvbmUsIHJlc3VtZQogIC8vIHRoZSBzZXNzaW9uCiAgaWYoc2Vzc2lvbklkLmxlbmd0aCA+IDAgJiYgc2Vzc2lvbklkID09PSBjLnNlc3Npb24uaWQpIHsKICAgIC8vIHJlc3VtaW5nIHNlc3Npb24sIGV4cGVjdCBhIENoYW5nZUNpcGhlclNwZWMgbmV4dAogICAgYy5leHBlY3QgPSBTQ0M7CiAgICBjLnNlc3Npb24ucmVzdW1pbmcgPSB0cnVlOwoKICAgIC8vIGdldCBuZXcgc2VydmVyIHJhbmRvbQogICAgYy5zZXNzaW9uLnNwLnNlcnZlcl9yYW5kb20gPSBtc2cucmFuZG9tLmJ5dGVzKCk7CiAgfSBlbHNlIHsKICAgIC8vIG5vdCByZXN1bWluZywgZXhwZWN0IGEgc2VydmVyIENlcnRpZmljYXRlIG1lc3NhZ2UgbmV4dAogICAgYy5leHBlY3QgPSBTQ0U7CiAgICBjLnNlc3Npb24ucmVzdW1pbmcgPSBmYWxzZTsKCiAgICAvLyBjcmVhdGUgbmV3IHNlY3VyaXR5IHBhcmFtZXRlcnMKICAgIHRscy5jcmVhdGVTZWN1cml0eVBhcmFtZXRlcnMoYywgbXNnKTsKICB9CgogIC8vIHNldCBuZXcgc2Vzc2lvbiBJRAogIGMuc2Vzc2lvbi5pZCA9IHNlc3Npb25JZDsKCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIHNlcnZlciByZWNlaXZlcyBhIENsaWVudEhlbGxvIHJlY29yZC4KICoKICogV2hlbiBhIENsaWVudEhlbGxvIG1lc3NhZ2Ugd2lsbCBiZSBzZW50OgogKiAgIFdoZW4gYSBjbGllbnQgZmlyc3QgY29ubmVjdHMgdG8gYSBzZXJ2ZXIgaXQgaXMgcmVxdWlyZWQgdG8gc2VuZCB0aGUKICogICBjbGllbnQgaGVsbG8gYXMgaXRzIGZpcnN0IG1lc3NhZ2UuIFRoZSBjbGllbnQgY2FuIGFsc28gc2VuZCBhIGNsaWVudAogKiAgIGhlbGxvIGluIHJlc3BvbnNlIHRvIGEgaGVsbG8gcmVxdWVzdCBvciBvbiBpdHMgb3duIGluaXRpYXRpdmUgaW4gb3JkZXIKICogICB0byByZW5lZ290aWF0ZSB0aGUgc2VjdXJpdHkgcGFyYW1ldGVycyBpbiBhbiBleGlzdGluZyBjb25uZWN0aW9uLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlLgogKi8KdGxzLmhhbmRsZUNsaWVudEhlbGxvID0gZnVuY3Rpb24oYywgcmVjb3JkLCBsZW5ndGgpIHsKICB2YXIgbXNnID0gdGxzLnBhcnNlSGVsbG9NZXNzYWdlKGMsIHJlY29yZCwgbGVuZ3RoKTsKICBpZihjLmZhaWwpIHsKICAgIHJldHVybjsKICB9CgogIC8vIGdldCB0aGUgc2Vzc2lvbiBJRCBmcm9tIHRoZSBtZXNzYWdlCiAgdmFyIHNlc3Npb25JZCA9IG1zZy5zZXNzaW9uX2lkLmJ5dGVzKCk7CgogIC8vIHNlZSBpZiB0aGUgZ2l2ZW4gc2Vzc2lvbiBJRCBpcyBpbiB0aGUgY2FjaGUKICB2YXIgc2Vzc2lvbiA9IG51bGw7CiAgaWYoYy5zZXNzaW9uQ2FjaGUpIHsKICAgIHNlc3Npb24gPSBjLnNlc3Npb25DYWNoZS5nZXRTZXNzaW9uKHNlc3Npb25JZCk7CiAgICBpZihzZXNzaW9uID09PSBudWxsKSB7CiAgICAgIC8vIHNlc3Npb24gSUQgbm90IGZvdW5kCiAgICAgIHNlc3Npb25JZCA9ICcnOwogICAgfSBlbHNlIGlmKHNlc3Npb24udmVyc2lvbi5tYWpvciAhPT0gbXNnLnZlcnNpb24ubWFqb3IgfHwKICAgICAgc2Vzc2lvbi52ZXJzaW9uLm1pbm9yID4gbXNnLnZlcnNpb24ubWlub3IpIHsKICAgICAgLy8gaWYgc2Vzc2lvbiB2ZXJzaW9uIGlzIGluY29tcGF0aWJsZSB3aXRoIGNsaWVudCB2ZXJzaW9uLCBkbyBub3QgcmVzdW1lCiAgICAgIHNlc3Npb24gPSBudWxsOwogICAgICBzZXNzaW9uSWQgPSAnJzsKICAgIH0KICB9CgogIC8vIG5vIHNlc3Npb24gZm91bmQgdG8gcmVzdW1lLCBnZW5lcmF0ZSBhIG5ldyBzZXNzaW9uIElECiAgaWYoc2Vzc2lvbklkLmxlbmd0aCA9PT0gMCkgewogICAgc2Vzc2lvbklkID0gZm9yZ2UucmFuZG9tLmdldEJ5dGVzKDMyKTsKICB9CgogIC8vIHVwZGF0ZSBzZXNzaW9uCiAgYy5zZXNzaW9uLmlkID0gc2Vzc2lvbklkOwogIGMuc2Vzc2lvbi5jbGllbnRIZWxsb1ZlcnNpb24gPSBtc2cudmVyc2lvbjsKICBjLnNlc3Npb24uc3AgPSB7fTsKICBpZihzZXNzaW9uKSB7CiAgICAvLyB1c2UgdmVyc2lvbiBhbmQgc2VjdXJpdHkgcGFyYW1ldGVycyBmcm9tIHJlc3VtZWQgc2Vzc2lvbgogICAgYy52ZXJzaW9uID0gYy5zZXNzaW9uLnZlcnNpb24gPSBzZXNzaW9uLnZlcnNpb247CiAgICBjLnNlc3Npb24uc3AgPSBzZXNzaW9uLnNwOwogIH0gZWxzZSB7CiAgICAvLyB1c2UgaGlnaGVzdCBjb21wYXRpYmxlIG1pbm9yIHZlcnNpb24KICAgIHZhciB2ZXJzaW9uOwogICAgZm9yKHZhciBpID0gMTsgaSA8IHRscy5TdXBwb3J0ZWRWZXJzaW9ucy5sZW5ndGg7ICsraSkgewogICAgICB2ZXJzaW9uID0gdGxzLlN1cHBvcnRlZFZlcnNpb25zW2ldOwogICAgICBpZih2ZXJzaW9uLm1pbm9yIDw9IG1zZy52ZXJzaW9uLm1pbm9yKSB7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIGMudmVyc2lvbiA9IHttYWpvcjogdmVyc2lvbi5tYWpvciwgbWlub3I6IHZlcnNpb24ubWlub3J9OwogICAgYy5zZXNzaW9uLnZlcnNpb24gPSBjLnZlcnNpb247CiAgfQoKICAvLyBpZiBhIHNlc3Npb24gaXMgc2V0LCByZXN1bWUgaXQKICBpZihzZXNzaW9uICE9PSBudWxsKSB7CiAgICAvLyByZXN1bWluZyBzZXNzaW9uLCBleHBlY3QgYSBDaGFuZ2VDaXBoZXJTcGVjIG5leHQKICAgIGMuZXhwZWN0ID0gQ0NDOwogICAgYy5zZXNzaW9uLnJlc3VtaW5nID0gdHJ1ZTsKCiAgICAvLyBnZXQgbmV3IGNsaWVudCByYW5kb20KICAgIGMuc2Vzc2lvbi5zcC5jbGllbnRfcmFuZG9tID0gbXNnLnJhbmRvbS5ieXRlcygpOwogIH0gZWxzZSB7CiAgICAvLyBub3QgcmVzdW1pbmcsIGV4cGVjdCBhIENlcnRpZmljYXRlIG9yIENsaWVudEtleUV4Y2hhbmdlCiAgICBjLmV4cGVjdCA9IChjLnZlcmlmeUNsaWVudCAhPT0gZmFsc2UpID8gQ0NFIDogQ0tFOwogICAgYy5zZXNzaW9uLnJlc3VtaW5nID0gZmFsc2U7CgogICAgLy8gY3JlYXRlIG5ldyBzZWN1cml0eSBwYXJhbWV0ZXJzCiAgICB0bHMuY3JlYXRlU2VjdXJpdHlQYXJhbWV0ZXJzKGMsIG1zZyk7CiAgfQoKICAvLyBjb25uZWN0aW9uIG5vdyBvcGVuCiAgYy5vcGVuID0gdHJ1ZTsKCiAgLy8gcXVldWUgc2VydmVyIGhlbGxvCiAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVSZWNvcmQoYywgewogICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgIGRhdGE6IHRscy5jcmVhdGVTZXJ2ZXJIZWxsbyhjKQogIH0pKTsKCiAgaWYoYy5zZXNzaW9uLnJlc3VtaW5nKSB7CiAgICAvLyBxdWV1ZSBjaGFuZ2UgY2lwaGVyIHNwZWMgbWVzc2FnZQogICAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVSZWNvcmQoYywgewogICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuY2hhbmdlX2NpcGhlcl9zcGVjLAogICAgICBkYXRhOiB0bHMuY3JlYXRlQ2hhbmdlQ2lwaGVyU3BlYygpCiAgICB9KSk7CgogICAgLy8gY3JlYXRlIHBlbmRpbmcgc3RhdGUKICAgIGMuc3RhdGUucGVuZGluZyA9IHRscy5jcmVhdGVDb25uZWN0aW9uU3RhdGUoYyk7CgogICAgLy8gY2hhbmdlIGN1cnJlbnQgd3JpdGUgc3RhdGUgdG8gcGVuZGluZyB3cml0ZSBzdGF0ZQogICAgYy5zdGF0ZS5jdXJyZW50LndyaXRlID0gYy5zdGF0ZS5wZW5kaW5nLndyaXRlOwoKICAgIC8vIHF1ZXVlIGZpbmlzaGVkCiAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgIHR5cGU6IHRscy5Db250ZW50VHlwZS5oYW5kc2hha2UsCiAgICAgIGRhdGE6IHRscy5jcmVhdGVGaW5pc2hlZChjKQogICAgfSkpOwogIH0gZWxzZSB7CiAgICAvLyBxdWV1ZSBzZXJ2ZXIgY2VydGlmaWNhdGUKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgICAgZGF0YTogdGxzLmNyZWF0ZUNlcnRpZmljYXRlKGMpCiAgICB9KSk7CgogICAgaWYoIWMuZmFpbCkgewogICAgICAvLyBxdWV1ZSBzZXJ2ZXIga2V5IGV4Y2hhbmdlCiAgICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlLAogICAgICAgIGRhdGE6IHRscy5jcmVhdGVTZXJ2ZXJLZXlFeGNoYW5nZShjKQogICAgICB9KSk7CgogICAgICAvLyByZXF1ZXN0IGNsaWVudCBjZXJ0aWZpY2F0ZSBpZiBzZXQKICAgICAgaWYoYy52ZXJpZnlDbGllbnQgIT09IGZhbHNlKSB7CiAgICAgICAgLy8gcXVldWUgY2VydGlmaWNhdGUgcmVxdWVzdAogICAgICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICAgIHR5cGU6IHRscy5Db250ZW50VHlwZS5oYW5kc2hha2UsCiAgICAgICAgICBkYXRhOiB0bHMuY3JlYXRlQ2VydGlmaWNhdGVSZXF1ZXN0KGMpCiAgICAgICAgfSkpOwogICAgICB9CgogICAgICAvLyBxdWV1ZSBzZXJ2ZXIgaGVsbG8gZG9uZQogICAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgICAgICBkYXRhOiB0bHMuY3JlYXRlU2VydmVySGVsbG9Eb25lKGMpCiAgICAgIH0pKTsKICAgIH0KICB9CgogIC8vIHNlbmQgcmVjb3JkcwogIHRscy5mbHVzaChjKTsKCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIGNsaWVudCByZWNlaXZlcyBhIENlcnRpZmljYXRlIHJlY29yZC4KICoKICogV2hlbiB0aGlzIG1lc3NhZ2Ugd2lsbCBiZSBzZW50OgogKiAgIFRoZSBzZXJ2ZXIgbXVzdCBzZW5kIGEgY2VydGlmaWNhdGUgd2hlbmV2ZXIgdGhlIGFncmVlZC11cG9uIGtleSBleGNoYW5nZQogKiAgIG1ldGhvZCBpcyBub3QgYW4gYW5vbnltb3VzIG9uZS4gVGhpcyBtZXNzYWdlIHdpbGwgYWx3YXlzIGltbWVkaWF0ZWx5CiAqICAgZm9sbG93IHRoZSBzZXJ2ZXIgaGVsbG8gbWVzc2FnZS4KICoKICogTWVhbmluZyBvZiB0aGlzIG1lc3NhZ2U6CiAqICAgVGhlIGNlcnRpZmljYXRlIHR5cGUgbXVzdCBiZSBhcHByb3ByaWF0ZSBmb3IgdGhlIHNlbGVjdGVkIGNpcGhlciBzdWl0ZSdzCiAqICAga2V5IGV4Y2hhbmdlIGFsZ29yaXRobSwgYW5kIGlzIGdlbmVyYWxseSBhbiBYLjUwOXYzIGNlcnRpZmljYXRlLiBJdCBtdXN0CiAqICAgY29udGFpbiBhIGtleSB3aGljaCBtYXRjaGVzIHRoZSBrZXkgZXhjaGFuZ2UgbWV0aG9kLCBhcyBmb2xsb3dzLiBVbmxlc3MKICogICBvdGhlcndpc2Ugc3BlY2lmaWVkLCB0aGUgc2lnbmluZyBhbGdvcml0aG0gZm9yIHRoZSBjZXJ0aWZpY2F0ZSBtdXN0IGJlCiAqICAgdGhlIHNhbWUgYXMgdGhlIGFsZ29yaXRobSBmb3IgdGhlIGNlcnRpZmljYXRlIGtleS4gVW5sZXNzIG90aGVyd2lzZQogKiAgIHNwZWNpZmllZCwgdGhlIHB1YmxpYyBrZXkgbWF5IGJlIG9mIGFueSBsZW5ndGguCiAqCiAqIG9wYXF1ZSBBU04uMUNlcnQ8MS4uMl4yNC0xPjsKICogc3RydWN0IHsKICogICBBU04uMUNlcnQgY2VydGlmaWNhdGVfbGlzdDwxLi4yXjI0LTE+OwogKiB9IENlcnRpZmljYXRlOwogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlLgogKi8KdGxzLmhhbmRsZUNlcnRpZmljYXRlID0gZnVuY3Rpb24oYywgcmVjb3JkLCBsZW5ndGgpIHsKICAvLyBtaW5pbXVtIG9mIDMgYnl0ZXMgaW4gbWVzc2FnZQogIGlmKGxlbmd0aCA8IDMpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0ludmFsaWQgQ2VydGlmaWNhdGUgbWVzc2FnZS4gTWVzc2FnZSB0b28gc2hvcnQuJywKICAgICAgc2VuZDogdHJ1ZSwKICAgICAgYWxlcnQ6IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uaWxsZWdhbF9wYXJhbWV0ZXIKICAgICAgfQogICAgfSk7CiAgfQoKICB2YXIgYiA9IHJlY29yZC5mcmFnbWVudDsKICB2YXIgbXNnID0gewogICAgY2VydGlmaWNhdGVfbGlzdDogcmVhZFZlY3RvcihiLCAzKQogIH07CgogIC8qIFRoZSBzZW5kZXIncyBjZXJ0aWZpY2F0ZSB3aWxsIGJlIGZpcnN0IGluIHRoZSBsaXN0IChjaGFpbiksIGVhY2gKICAgIHN1YnNlcXVlbnQgb25lIHRoYXQgZm9sbG93cyB3aWxsIGNlcnRpZnkgdGhlIHByZXZpb3VzIG9uZSwgYnV0IHJvb3QKICAgIGNlcnRpZmljYXRlcyAoc2VsZi1zaWduZWQpIHRoYXQgc3BlY2lmeSB0aGUgY2VydGlmaWNhdGUgYXV0aG9yaXR5IG1heQogICAgYmUgb21pdHRlZCB1bmRlciB0aGUgYXNzdW1wdGlvbiB0aGF0IGNsaWVudHMgbXVzdCBhbHJlYWR5IHBvc3Nlc3MgaXQuICovCiAgdmFyIGNlcnQsIGFzbjE7CiAgdmFyIGNlcnRzID0gW107CiAgdHJ5IHsKICAgIHdoaWxlKG1zZy5jZXJ0aWZpY2F0ZV9saXN0Lmxlbmd0aCgpID4gMCkgewogICAgICAvLyBlYWNoIGVudHJ5IGluIG1zZy5jZXJ0aWZpY2F0ZV9saXN0IGlzIGEgdmVjdG9yIHdpdGggMyBsZW4gYnl0ZXMKICAgICAgY2VydCA9IHJlYWRWZWN0b3IobXNnLmNlcnRpZmljYXRlX2xpc3QsIDMpOwogICAgICBhc24xID0gZm9yZ2UuYXNuMS5mcm9tRGVyKGNlcnQpOwogICAgICBjZXJ0ID0gZm9yZ2UucGtpLmNlcnRpZmljYXRlRnJvbUFzbjEoYXNuMSwgdHJ1ZSk7CiAgICAgIGNlcnRzLnB1c2goY2VydCk7CiAgICB9CiAgfSBjYXRjaChleCkgewogICAgcmV0dXJuIGMuZXJyb3IoYywgewogICAgICBtZXNzYWdlOiAnQ291bGQgbm90IHBhcnNlIGNlcnRpZmljYXRlIGxpc3QuJywKICAgICAgY2F1c2U6IGV4LAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5iYWRfY2VydGlmaWNhdGUKICAgICAgfQogICAgfSk7CiAgfQoKICAvLyBlbnN1cmUgYXQgbGVhc3QgMSBjZXJ0aWZpY2F0ZSB3YXMgcHJvdmlkZWQgaWYgaW4gY2xpZW50LW1vZGUKICAvLyBvciBpZiB2ZXJpZnlDbGllbnQgd2FzIHNldCB0byB0cnVlIHRvIHJlcXVpcmUgYSBjZXJ0aWZpY2F0ZQogIC8vIChhcyBvcHBvc2VkIHRvICdvcHRpb25hbCcpCiAgdmFyIGNsaWVudCA9IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KTsKICBpZigoY2xpZW50IHx8IGMudmVyaWZ5Q2xpZW50ID09PSB0cnVlKSAmJiBjZXJ0cy5sZW5ndGggPT09IDApIHsKICAgIC8vIGVycm9yLCBubyBjZXJ0aWZpY2F0ZQogICAgYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6IGNsaWVudCA/CiAgICAgICAgJ05vIHNlcnZlciBjZXJ0aWZpY2F0ZSBwcm92aWRlZC4nIDoKICAgICAgICAnTm8gY2xpZW50IGNlcnRpZmljYXRlIHByb3ZpZGVkLicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmlsbGVnYWxfcGFyYW1ldGVyCiAgICAgIH0KICAgIH0pOwogIH0gZWxzZSBpZihjZXJ0cy5sZW5ndGggPT09IDApIHsKICAgIC8vIG5vIGNlcnRzIHRvIHZlcmlmeQogICAgLy8gZXhwZWN0IGEgU2VydmVyS2V5RXhjaGFuZ2Ugb3IgQ2xpZW50S2V5RXhjaGFuZ2UgbWVzc2FnZSBuZXh0CiAgICBjLmV4cGVjdCA9IGNsaWVudCA/IFNLRSA6IENLRTsKICB9IGVsc2UgewogICAgLy8gc2F2ZSBjZXJ0aWZpY2F0ZSBpbiBzZXNzaW9uCiAgICBpZihjbGllbnQpIHsKICAgICAgYy5zZXNzaW9uLnNlcnZlckNlcnRpZmljYXRlID0gY2VydHNbMF07CiAgICB9IGVsc2UgewogICAgICBjLnNlc3Npb24uY2xpZW50Q2VydGlmaWNhdGUgPSBjZXJ0c1swXTsKICAgIH0KCiAgICBpZih0bHMudmVyaWZ5Q2VydGlmaWNhdGVDaGFpbihjLCBjZXJ0cykpIHsKICAgICAgLy8gZXhwZWN0IGEgU2VydmVyS2V5RXhjaGFuZ2Ugb3IgQ2xpZW50S2V5RXhjaGFuZ2UgbWVzc2FnZSBuZXh0CiAgICAgIGMuZXhwZWN0ID0gY2xpZW50ID8gU0tFIDogQ0tFOwogICAgfQogIH0KCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIGNsaWVudCByZWNlaXZlcyBhIFNlcnZlcktleUV4Y2hhbmdlIHJlY29yZC4KICoKICogV2hlbiB0aGlzIG1lc3NhZ2Ugd2lsbCBiZSBzZW50OgogKiAgIFRoaXMgbWVzc2FnZSB3aWxsIGJlIHNlbnQgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIHNlcnZlciBjZXJ0aWZpY2F0ZQogKiAgIG1lc3NhZ2UgKG9yIHRoZSBzZXJ2ZXIgaGVsbG8gbWVzc2FnZSwgaWYgdGhpcyBpcyBhbiBhbm9ueW1vdXMKICogICBuZWdvdGlhdGlvbikuCiAqCiAqICAgVGhlIHNlcnZlciBrZXkgZXhjaGFuZ2UgbWVzc2FnZSBpcyBzZW50IGJ5IHRoZSBzZXJ2ZXIgb25seSB3aGVuIHRoZQogKiAgIHNlcnZlciBjZXJ0aWZpY2F0ZSBtZXNzYWdlIChpZiBzZW50KSBkb2VzIG5vdCBjb250YWluIGVub3VnaCBkYXRhIHRvCiAqICAgYWxsb3cgdGhlIGNsaWVudCB0byBleGNoYW5nZSBhIHByZW1hc3RlciBzZWNyZXQuCiAqCiAqIE1lYW5pbmcgb2YgdGhpcyBtZXNzYWdlOgogKiAgIFRoaXMgbWVzc2FnZSBjb252ZXlzIGNyeXB0b2dyYXBoaWMgaW5mb3JtYXRpb24gdG8gYWxsb3cgdGhlIGNsaWVudCB0bwogKiAgIGNvbW11bmljYXRlIHRoZSBwcmVtYXN0ZXIgc2VjcmV0OiBlaXRoZXIgYW4gUlNBIHB1YmxpYyBrZXkgdG8gZW5jcnlwdAogKiAgIHRoZSBwcmVtYXN0ZXIgc2VjcmV0IHdpdGgsIG9yIGEgRGlmZmllLUhlbGxtYW4gcHVibGljIGtleSB3aXRoIHdoaWNoIHRoZQogKiAgIGNsaWVudCBjYW4gY29tcGxldGUgYSBrZXkgZXhjaGFuZ2UgKHdpdGggdGhlIHJlc3VsdCBiZWluZyB0aGUgcHJlbWFzdGVyCiAqICAgc2VjcmV0LikKICoKICogZW51bSB7CiAqICAgZGhlX2RzcywgZGhlX3JzYSwgZGhfYW5vbiwgcnNhLCBkaF9kc3MsIGRoX3JzYQogKiB9IEtleUV4Y2hhbmdlQWxnb3JpdGhtOwogKgogKiBzdHJ1Y3QgewogKiAgIG9wYXF1ZSBkaF9wPDEuLjJeMTYtMT47CiAqICAgb3BhcXVlIGRoX2c8MS4uMl4xNi0xPjsKICogICBvcGFxdWUgZGhfWXM8MS4uMl4xNi0xPjsKICogfSBTZXJ2ZXJESFBhcmFtczsKICoKICogc3RydWN0IHsKICogICBzZWxlY3QoS2V5RXhjaGFuZ2VBbGdvcml0aG0pIHsKICogICAgIGNhc2UgZGhfYW5vbjoKICogICAgICAgU2VydmVyREhQYXJhbXMgcGFyYW1zOwogKiAgICAgY2FzZSBkaGVfZHNzOgogKiAgICAgY2FzZSBkaGVfcnNhOgogKiAgICAgICBTZXJ2ZXJESFBhcmFtcyBwYXJhbXM7CiAqICAgICAgIGRpZ2l0YWxseS1zaWduZWQgc3RydWN0IHsKICogICAgICAgICBvcGFxdWUgY2xpZW50X3JhbmRvbVszMl07CiAqICAgICAgICAgb3BhcXVlIHNlcnZlcl9yYW5kb21bMzJdOwogKiAgICAgICAgIFNlcnZlckRIUGFyYW1zIHBhcmFtczsKICogICAgICAgfSBzaWduZWRfcGFyYW1zOwogKiAgICAgY2FzZSByc2E6CiAqICAgICBjYXNlIGRoX2RzczoKICogICAgIGNhc2UgZGhfcnNhOgogKiAgICAgICBzdHJ1Y3Qge307CiAqICAgfTsKICogfSBTZXJ2ZXJLZXlFeGNoYW5nZTsKICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVTZXJ2ZXJLZXlFeGNoYW5nZSA9IGZ1bmN0aW9uKGMsIHJlY29yZCwgbGVuZ3RoKSB7CiAgLy8gdGhpcyBpbXBsZW1lbnRhdGlvbiBvbmx5IHN1cHBvcnRzIFJTQSwgbm8gRGlmZmllLUhlbGxtYW4gc3VwcG9ydAogIC8vIHNvIGFueSBsZW5ndGggPiAwIGlzIGludmFsaWQKICBpZihsZW5ndGggPiAwKSB7CiAgICByZXR1cm4gYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIGtleSBwYXJhbWV0ZXJzLiBPbmx5IFJTQSBpcyBzdXBwb3J0ZWQuJywKICAgICAgc2VuZDogdHJ1ZSwKICAgICAgYWxlcnQ6IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24udW5zdXBwb3J0ZWRfY2VydGlmaWNhdGUKICAgICAgfQogICAgfSk7CiAgfQoKICAvLyBleHBlY3QgYW4gb3B0aW9uYWwgQ2VydGlmaWNhdGVSZXF1ZXN0IG1lc3NhZ2UgbmV4dAogIGMuZXhwZWN0ID0gU0NSOwoKICAvLyBjb250aW51ZQogIGMucHJvY2VzcygpOwp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgY2xpZW50IHJlY2VpdmVzIGEgQ2xpZW50S2V5RXhjaGFuZ2UgcmVjb3JkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKiBAcGFyYW0gbGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlLgogKi8KdGxzLmhhbmRsZUNsaWVudEtleUV4Y2hhbmdlID0gZnVuY3Rpb24oYywgcmVjb3JkLCBsZW5ndGgpIHsKICAvLyB0aGlzIGltcGxlbWVudGF0aW9uIG9ubHkgc3VwcG9ydHMgUlNBLCBubyBEaWZmaWUtSGVsbG1hbiBzdXBwb3J0CiAgLy8gc28gYW55IGxlbmd0aCA8IDQ4IGlzIGludmFsaWQKICBpZihsZW5ndGggPCA0OCkgewogICAgcmV0dXJuIGMuZXJyb3IoYywgewogICAgICBtZXNzYWdlOiAnSW52YWxpZCBrZXkgcGFyYW1ldGVycy4gT25seSBSU0EgaXMgc3VwcG9ydGVkLicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLnVuc3VwcG9ydGVkX2NlcnRpZmljYXRlCiAgICAgIH0KICAgIH0pOwogIH0KCiAgdmFyIGIgPSByZWNvcmQuZnJhZ21lbnQ7CiAgdmFyIG1zZyA9IHsKICAgIGVuY19wcmVfbWFzdGVyX3NlY3JldDogcmVhZFZlY3RvcihiLCAyKS5nZXRCeXRlcygpCiAgfTsKCiAgLy8gZG8gcnNhIGRlY3J5cHRpb24KICB2YXIgcHJpdmF0ZUtleSA9IG51bGw7CiAgaWYoYy5nZXRQcml2YXRlS2V5KSB7CiAgICB0cnkgewogICAgICBwcml2YXRlS2V5ID0gYy5nZXRQcml2YXRlS2V5KGMsIGMuc2Vzc2lvbi5zZXJ2ZXJDZXJ0aWZpY2F0ZSk7CiAgICAgIHByaXZhdGVLZXkgPSBmb3JnZS5wa2kucHJpdmF0ZUtleUZyb21QZW0ocHJpdmF0ZUtleSk7CiAgICB9IGNhdGNoKGV4KSB7CiAgICAgIGMuZXJyb3IoYywgewogICAgICAgIG1lc3NhZ2U6ICdDb3VsZCBub3QgZ2V0IHByaXZhdGUga2V5LicsCiAgICAgICAgY2F1c2U6IGV4LAogICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgfQogICAgICB9KTsKICAgIH0KICB9CgogIGlmKHByaXZhdGVLZXkgPT09IG51bGwpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ05vIHByaXZhdGUga2V5IHNldC4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5pbnRlcm5hbF9lcnJvcgogICAgICB9CiAgICB9KTsKICB9CgogIHRyeSB7CiAgICAvLyBkZWNyeXB0IDQ4LWJ5dGUgcHJlLW1hc3RlciBzZWNyZXQKICAgIHZhciBzcCA9IGMuc2Vzc2lvbi5zcDsKICAgIHNwLnByZV9tYXN0ZXJfc2VjcmV0ID0gcHJpdmF0ZUtleS5kZWNyeXB0KG1zZy5lbmNfcHJlX21hc3Rlcl9zZWNyZXQpOwoKICAgIC8vIGVuc3VyZSBjbGllbnQgaGVsbG8gdmVyc2lvbiBtYXRjaGVzIGZpcnN0IDIgYnl0ZXMKICAgIHZhciB2ZXJzaW9uID0gYy5zZXNzaW9uLmNsaWVudEhlbGxvVmVyc2lvbjsKICAgIGlmKHZlcnNpb24ubWFqb3IgIT09IHNwLnByZV9tYXN0ZXJfc2VjcmV0LmNoYXJDb2RlQXQoMCkgfHwKICAgICAgdmVyc2lvbi5taW5vciAhPT0gc3AucHJlX21hc3Rlcl9zZWNyZXQuY2hhckNvZGVBdCgxKSkgewogICAgICAvLyBlcnJvciwgZG8gbm90IHNlbmQgYWxlcnQgKHNlZSBCTEVJIGF0dGFjayBiZWxvdykKICAgICAgdGhyb3cgbmV3IEVycm9yKCdUTFMgdmVyc2lvbiByb2xsYmFjayBhdHRhY2sgZGV0ZWN0ZWQuJyk7CiAgICB9CiAgfSBjYXRjaChleCkgewogICAgLyogTm90ZTogRGFuaWVsIEJsZWljaGVuYmFjaGVyIFtCTEVJXSBjYW4gYmUgdXNlZCB0byBhdHRhY2sgYQogICAgICBUTFMgc2VydmVyIHdoaWNoIGlzIHVzaW5nIFBLQ1MjMSBlbmNvZGVkIFJTQSwgc28gaW5zdGVhZCBvZgogICAgICBmYWlsaW5nIGhlcmUsIHdlIGdlbmVyYXRlIDQ4IHJhbmRvbSBieXRlcyBhbmQgdXNlIHRoYXQgYXMKICAgICAgdGhlIHByZS1tYXN0ZXIgc2VjcmV0LiAqLwogICAgc3AucHJlX21hc3Rlcl9zZWNyZXQgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMoNDgpOwogIH0KCiAgLy8gZXhwZWN0IGEgQ2VydGlmaWNhdGVWZXJpZnkgbWVzc2FnZSBpZiBhIENlcnRpZmljYXRlIHdhcyByZWNlaXZlZCB0aGF0CiAgLy8gZG9lcyBub3QgaGF2ZSBmaXhlZCBEaWZmaWUtSGVsbG1hbiBwYXJhbXMsIG90aGVyd2lzZSBleHBlY3QKICAvLyBDaGFuZ2VDaXBoZXJTcGVjCiAgYy5leHBlY3QgPSBDQ0M7CiAgaWYoYy5zZXNzaW9uLmNsaWVudENlcnRpZmljYXRlICE9PSBudWxsKSB7CiAgICAvLyBvbmx5IFJTQSBzdXBwb3J0LCBzbyBleHBlY3QgQ2VydGlmaWNhdGVWZXJpZnkKICAgIC8vIFRPRE86IHN1cHBvcnQgRGlmZmllLUhlbGxtYW4KICAgIGMuZXhwZWN0ID0gQ0NWOwogIH0KCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIGNsaWVudCByZWNlaXZlcyBhIENlcnRpZmljYXRlUmVxdWVzdCByZWNvcmQuCiAqCiAqIFdoZW4gdGhpcyBtZXNzYWdlIHdpbGwgYmUgc2VudDoKICogICBBIG5vbi1hbm9ueW1vdXMgc2VydmVyIGNhbiBvcHRpb25hbGx5IHJlcXVlc3QgYSBjZXJ0aWZpY2F0ZSBmcm9tIHRoZQogKiAgIGNsaWVudCwgaWYgYXBwcm9wcmlhdGUgZm9yIHRoZSBzZWxlY3RlZCBjaXBoZXIgc3VpdGUuIFRoaXMgbWVzc2FnZSwgaWYKICogICBzZW50LCB3aWxsIGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgU2VydmVyIEtleSBFeGNoYW5nZSBtZXNzYWdlIChpZiBpdCBpcwogKiAgIHNlbnQ7IG90aGVyd2lzZSwgdGhlIFNlcnZlciBDZXJ0aWZpY2F0ZSBtZXNzYWdlKS4KICoKICogZW51bSB7CiAqICAgcnNhX3NpZ24oMSksIGRzc19zaWduKDIpLCByc2FfZml4ZWRfZGgoMyksIGRzc19maXhlZF9kaCg0KSwKICogICByc2FfZXBoZW1lcmFsX2RoX1JFU0VSVkVEKDUpLCBkc3NfZXBoZW1lcmFsX2RoX1JFU0VSVkVEKDYpLAogKiAgIGZvcnRlenphX2Rtc19SRVNFUlZFRCgyMCksICgyNTUpCiAqIH0gQ2xpZW50Q2VydGlmaWNhdGVUeXBlOwogKgogKiBvcGFxdWUgRGlzdGluZ3Vpc2hlZE5hbWU8MS4uMl4xNi0xPjsKICoKICogc3RydWN0IHsKICogICBDbGllbnRDZXJ0aWZpY2F0ZVR5cGUgY2VydGlmaWNhdGVfdHlwZXM8MS4uMl44LTE+OwogKiAgIFNpZ25hdHVyZUFuZEhhc2hBbGdvcml0aG0gc3VwcG9ydGVkX3NpZ25hdHVyZV9hbGdvcml0aG1zPDJeMTYtMT47CiAqICAgRGlzdGluZ3Vpc2hlZE5hbWUgY2VydGlmaWNhdGVfYXV0aG9yaXRpZXM8MC4uMl4xNi0xPjsKICogfSBDZXJ0aWZpY2F0ZVJlcXVlc3Q7CiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqIEBwYXJhbSBsZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgaGFuZHNoYWtlIG1lc3NhZ2UuCiAqLwp0bHMuaGFuZGxlQ2VydGlmaWNhdGVSZXF1ZXN0ID0gZnVuY3Rpb24oYywgcmVjb3JkLCBsZW5ndGgpIHsKICAvLyBtaW5pbXVtIG9mIDMgYnl0ZXMgaW4gbWVzc2FnZQogIGlmKGxlbmd0aCA8IDMpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0ludmFsaWQgQ2VydGlmaWNhdGVSZXF1ZXN0LiBNZXNzYWdlIHRvbyBzaG9ydC4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5pbGxlZ2FsX3BhcmFtZXRlcgogICAgICB9CiAgICB9KTsKICB9CgogIC8vIFRPRE86IFRMUyAxLjIrIGhhcyBkaWZmZXJlbnQgZm9ybWF0IGluY2x1ZGluZwogIC8vIFNpZ25hdHVyZUFuZEhhc2hBbGdvcml0aG0gYWZ0ZXIgY2VydCB0eXBlcwogIHZhciBiID0gcmVjb3JkLmZyYWdtZW50OwogIHZhciBtc2cgPSB7CiAgICBjZXJ0aWZpY2F0ZV90eXBlczogcmVhZFZlY3RvcihiLCAxKSwKICAgIGNlcnRpZmljYXRlX2F1dGhvcml0aWVzOiByZWFkVmVjdG9yKGIsIDIpCiAgfTsKCiAgLy8gc2F2ZSBjZXJ0aWZpY2F0ZSByZXF1ZXN0IGluIHNlc3Npb24KICBjLnNlc3Npb24uY2VydGlmaWNhdGVSZXF1ZXN0ID0gbXNnOwoKICAvLyBleHBlY3QgYSBTZXJ2ZXJIZWxsb0RvbmUgbWVzc2FnZSBuZXh0CiAgYy5leHBlY3QgPSBTSEQ7CgogIC8vIGNvbnRpbnVlCiAgYy5wcm9jZXNzKCk7Cn07CgovKioKICogQ2FsbGVkIHdoZW4gYSBzZXJ2ZXIgcmVjZWl2ZXMgYSBDZXJ0aWZpY2F0ZVZlcmlmeSByZWNvcmQuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqIEBwYXJhbSBsZW5ndGggdGhlIGxlbmd0aCBvZiB0aGUgaGFuZHNoYWtlIG1lc3NhZ2UuCiAqLwp0bHMuaGFuZGxlQ2VydGlmaWNhdGVWZXJpZnkgPSBmdW5jdGlvbihjLCByZWNvcmQsIGxlbmd0aCkgewogIGlmKGxlbmd0aCA8IDIpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0ludmFsaWQgQ2VydGlmaWNhdGVWZXJpZnkuIE1lc3NhZ2UgdG9vIHNob3J0LicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmlsbGVnYWxfcGFyYW1ldGVyCiAgICAgIH0KICAgIH0pOwogIH0KCiAgLy8gcmV3aW5kIHRvIGdldCBmdWxsIGJ5dGVzIGZvciBtZXNzYWdlIHNvIGl0IGNhbiBiZSBtYW51YWxseQogIC8vIGRpZ2VzdGVkIGJlbG93IChzcGVjaWFsIGNhc2UgZm9yIENlcnRpZmljYXRlVmVyaWZ5IG1lc3NhZ2VzIGJlY2F1c2UKICAvLyB0aGV5IG11c3QgYmUgZGlnZXN0ZWQgKmFmdGVyKiBoYW5kbGluZyBhcyBvcHBvc2VkIHRvIGFsbCBvdGhlcnMpCiAgdmFyIGIgPSByZWNvcmQuZnJhZ21lbnQ7CiAgYi5yZWFkIC09IDQ7CiAgdmFyIG1zZ0J5dGVzID0gYi5ieXRlcygpOwogIGIucmVhZCArPSA0OwoKICB2YXIgbXNnID0gewogICAgc2lnbmF0dXJlOiByZWFkVmVjdG9yKGIsIDIpLmdldEJ5dGVzKCkKICB9OwoKICAvLyBUT0RPOiBhZGQgc3VwcG9ydCBmb3IgRFNBCgogIC8vIGdlbmVyYXRlIGRhdGEgdG8gdmVyaWZ5CiAgdmFyIHZlcmlmeSA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgdmVyaWZ5LnB1dEJ1ZmZlcihjLnNlc3Npb24ubWQ1LmRpZ2VzdCgpKTsKICB2ZXJpZnkucHV0QnVmZmVyKGMuc2Vzc2lvbi5zaGExLmRpZ2VzdCgpKTsKICB2ZXJpZnkgPSB2ZXJpZnkuZ2V0Qnl0ZXMoKTsKCiAgdHJ5IHsKICAgIHZhciBjZXJ0ID0gYy5zZXNzaW9uLmNsaWVudENlcnRpZmljYXRlOwogICAgLypiID0gZm9yZ2UucGtpLnJzYS5kZWNyeXB0KAogICAgICBtc2cuc2lnbmF0dXJlLCBjZXJ0LnB1YmxpY0tleSwgdHJ1ZSwgdmVyaWZ5Lmxlbmd0aCk7CiAgICBpZihiICE9PSB2ZXJpZnkpIHsqLwogICAgaWYoIWNlcnQucHVibGljS2V5LnZlcmlmeSh2ZXJpZnksIG1zZy5zaWduYXR1cmUsICdOT05FJykpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKCdDZXJ0aWZpY2F0ZVZlcmlmeSBzaWduYXR1cmUgZG9lcyBub3QgbWF0Y2guJyk7CiAgICB9CgogICAgLy8gZGlnZXN0IG1lc3NhZ2Ugbm93IHRoYXQgaXQgaGFzIGJlZW4gaGFuZGxlZAogICAgYy5zZXNzaW9uLm1kNS51cGRhdGUobXNnQnl0ZXMpOwogICAgYy5zZXNzaW9uLnNoYTEudXBkYXRlKG1zZ0J5dGVzKTsKICB9IGNhdGNoKGV4KSB7CiAgICByZXR1cm4gYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6ICdCYWQgc2lnbmF0dXJlIGluIENlcnRpZmljYXRlVmVyaWZ5LicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmhhbmRzaGFrZV9mYWlsdXJlCiAgICAgIH0KICAgIH0pOwogIH0KCiAgLy8gZXhwZWN0IENoYW5nZUNpcGhlclNwZWMKICBjLmV4cGVjdCA9IENDQzsKCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIGNsaWVudCByZWNlaXZlcyBhIFNlcnZlckhlbGxvRG9uZSByZWNvcmQuCiAqCiAqIFdoZW4gdGhpcyBtZXNzYWdlIHdpbGwgYmUgc2VudDoKICogICBUaGUgc2VydmVyIGhlbGxvIGRvbmUgbWVzc2FnZSBpcyBzZW50IGJ5IHRoZSBzZXJ2ZXIgdG8gaW5kaWNhdGUgdGhlIGVuZAogKiAgIG9mIHRoZSBzZXJ2ZXIgaGVsbG8gYW5kIGFzc29jaWF0ZWQgbWVzc2FnZXMuIEFmdGVyIHNlbmRpbmcgdGhpcyBtZXNzYWdlCiAqICAgdGhlIHNlcnZlciB3aWxsIHdhaXQgZm9yIGEgY2xpZW50IHJlc3BvbnNlLgogKgogKiBNZWFuaW5nIG9mIHRoaXMgbWVzc2FnZToKICogICBUaGlzIG1lc3NhZ2UgbWVhbnMgdGhhdCB0aGUgc2VydmVyIGlzIGRvbmUgc2VuZGluZyBtZXNzYWdlcyB0byBzdXBwb3J0CiAqICAgdGhlIGtleSBleGNoYW5nZSwgYW5kIHRoZSBjbGllbnQgY2FuIHByb2NlZWQgd2l0aCBpdHMgcGhhc2Ugb2YgdGhlIGtleQogKiAgIGV4Y2hhbmdlLgogKgogKiAgIFVwb24gcmVjZWlwdCBvZiB0aGUgc2VydmVyIGhlbGxvIGRvbmUgbWVzc2FnZSB0aGUgY2xpZW50IHNob3VsZCB2ZXJpZnkKICogICB0aGF0IHRoZSBzZXJ2ZXIgcHJvdmlkZWQgYSB2YWxpZCBjZXJ0aWZpY2F0ZSBpZiByZXF1aXJlZCBhbmQgY2hlY2sgdGhhdAogKiAgIHRoZSBzZXJ2ZXIgaGVsbG8gcGFyYW1ldGVycyBhcmUgYWNjZXB0YWJsZS4KICoKICogc3RydWN0IHt9IFNlcnZlckhlbGxvRG9uZTsKICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVTZXJ2ZXJIZWxsb0RvbmUgPSBmdW5jdGlvbihjLCByZWNvcmQsIGxlbmd0aCkgewogIC8vIGxlbiBtdXN0IGJlIDAgYnl0ZXMKICBpZihsZW5ndGggPiAwKSB7CiAgICByZXR1cm4gYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIFNlcnZlckhlbGxvRG9uZSBtZXNzYWdlLiBJbnZhbGlkIGxlbmd0aC4nLAogICAgICBzZW5kOiB0cnVlLAogICAgICBhbGVydDogewogICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5yZWNvcmRfb3ZlcmZsb3cKICAgICAgfQogICAgfSk7CiAgfQoKICBpZihjLnNlcnZlckNlcnRpZmljYXRlID09PSBudWxsKSB7CiAgICAvLyBubyBzZXJ2ZXIgY2VydGlmaWNhdGUgd2FzIHByb3ZpZGVkCiAgICB2YXIgZXJyb3IgPSB7CiAgICAgIG1lc3NhZ2U6ICdObyBzZXJ2ZXIgY2VydGlmaWNhdGUgcHJvdmlkZWQuIE5vdCBlbm91Z2ggc2VjdXJpdHkuJywKICAgICAgc2VuZDogdHJ1ZSwKICAgICAgYWxlcnQ6IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uaW5zdWZmaWNpZW50X3NlY3VyaXR5CiAgICAgIH0KICAgIH07CgogICAgLy8gY2FsbCBhcHBsaWNhdGlvbiBjYWxsYmFjawogICAgdmFyIGRlcHRoID0gMDsKICAgIHZhciByZXQgPSBjLnZlcmlmeShjLCBlcnJvci5hbGVydC5kZXNjcmlwdGlvbiwgZGVwdGgsIFtdKTsKICAgIGlmKHJldCAhPT0gdHJ1ZSkgewogICAgICAvLyBjaGVjayBmb3IgY3VzdG9tIGFsZXJ0IGluZm8KICAgICAgaWYocmV0IHx8IHJldCA9PT0gMCkgewogICAgICAgIC8vIHNldCBjdXN0b20gbWVzc2FnZSBhbmQgYWxlcnQgZGVzY3JpcHRpb24KICAgICAgICBpZih0eXBlb2YgcmV0ID09PSAnb2JqZWN0JyAmJiAhZm9yZ2UudXRpbC5pc0FycmF5KHJldCkpIHsKICAgICAgICAgIGlmKHJldC5tZXNzYWdlKSB7CiAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgPSByZXQubWVzc2FnZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmKHJldC5hbGVydCkgewogICAgICAgICAgICBlcnJvci5hbGVydC5kZXNjcmlwdGlvbiA9IHJldC5hbGVydDsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYodHlwZW9mIHJldCA9PT0gJ251bWJlcicpIHsKICAgICAgICAgIC8vIHNldCBjdXN0b20gYWxlcnQgZGVzY3JpcHRpb24KICAgICAgICAgIGVycm9yLmFsZXJ0LmRlc2NyaXB0aW9uID0gcmV0OwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gc2VuZCBlcnJvcgogICAgICByZXR1cm4gYy5lcnJvcihjLCBlcnJvcik7CiAgICB9CiAgfQoKICAvLyBjcmVhdGUgY2xpZW50IGNlcnRpZmljYXRlIG1lc3NhZ2UgaWYgcmVxdWVzdGVkCiAgaWYoYy5zZXNzaW9uLmNlcnRpZmljYXRlUmVxdWVzdCAhPT0gbnVsbCkgewogICAgcmVjb3JkID0gdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgIHR5cGU6IHRscy5Db250ZW50VHlwZS5oYW5kc2hha2UsCiAgICAgIGRhdGE6IHRscy5jcmVhdGVDZXJ0aWZpY2F0ZShjKQogICAgfSk7CiAgICB0bHMucXVldWUoYywgcmVjb3JkKTsKICB9CgogIC8vIGNyZWF0ZSBjbGllbnQga2V5IGV4Y2hhbmdlIG1lc3NhZ2UKICByZWNvcmQgPSB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlLAogICAgIGRhdGE6IHRscy5jcmVhdGVDbGllbnRLZXlFeGNoYW5nZShjKQogIH0pOwogIHRscy5xdWV1ZShjLCByZWNvcmQpOwoKICAvLyBleHBlY3Qgbm8gbWVzc2FnZXMgdW50aWwgdGhlIGZvbGxvd2luZyBjYWxsYmFjayBoYXMgYmVlbiBjYWxsZWQKICBjLmV4cGVjdCA9IFNFUjsKCiAgLy8gY3JlYXRlIGNhbGxiYWNrIHRvIGhhbmRsZSBjbGllbnQgc2lnbmF0dXJlIChmb3IgY2xpZW50LWNlcnRzKQogIHZhciBjYWxsYmFjayA9IGZ1bmN0aW9uKGMsIHNpZ25hdHVyZSkgewogICAgaWYoYy5zZXNzaW9uLmNlcnRpZmljYXRlUmVxdWVzdCAhPT0gbnVsbCAmJgogICAgICBjLnNlc3Npb24uY2xpZW50Q2VydGlmaWNhdGUgIT09IG51bGwpIHsKICAgICAgLy8gY3JlYXRlIGNlcnRpZmljYXRlIHZlcmlmeSBtZXNzYWdlCiAgICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlLAogICAgICAgIGRhdGE6IHRscy5jcmVhdGVDZXJ0aWZpY2F0ZVZlcmlmeShjLCBzaWduYXR1cmUpCiAgICAgIH0pKTsKICAgIH0KCiAgICAvLyBjcmVhdGUgY2hhbmdlIGNpcGhlciBzcGVjIG1lc3NhZ2UKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmNoYW5nZV9jaXBoZXJfc3BlYywKICAgICAgZGF0YTogdGxzLmNyZWF0ZUNoYW5nZUNpcGhlclNwZWMoKQogICAgfSkpOwoKICAgIC8vIGNyZWF0ZSBwZW5kaW5nIHN0YXRlCiAgICBjLnN0YXRlLnBlbmRpbmcgPSB0bHMuY3JlYXRlQ29ubmVjdGlvblN0YXRlKGMpOwoKICAgIC8vIGNoYW5nZSBjdXJyZW50IHdyaXRlIHN0YXRlIHRvIHBlbmRpbmcgd3JpdGUgc3RhdGUKICAgIGMuc3RhdGUuY3VycmVudC53cml0ZSA9IGMuc3RhdGUucGVuZGluZy53cml0ZTsKCiAgICAvLyBjcmVhdGUgZmluaXNoZWQgbWVzc2FnZQogICAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVSZWNvcmQoYywgewogICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlLAogICAgICBkYXRhOiB0bHMuY3JlYXRlRmluaXNoZWQoYykKICAgIH0pKTsKCiAgICAvLyBleHBlY3QgYSBzZXJ2ZXIgQ2hhbmdlQ2lwaGVyU3BlYyBtZXNzYWdlIG5leHQKICAgIGMuZXhwZWN0ID0gU0NDOwoKICAgIC8vIHNlbmQgcmVjb3JkcwogICAgdGxzLmZsdXNoKGMpOwoKICAgIC8vIGNvbnRpbnVlCiAgICBjLnByb2Nlc3MoKTsKICB9OwoKICAvLyBpZiB0aGVyZSBpcyBubyBjZXJ0aWZpY2F0ZSByZXF1ZXN0IG9yIG5vIGNsaWVudCBjZXJ0aWZpY2F0ZSwgZG8KICAvLyBjYWxsYmFjayBpbW1lZGlhdGVseQogIGlmKGMuc2Vzc2lvbi5jZXJ0aWZpY2F0ZVJlcXVlc3QgPT09IG51bGwgfHwKICAgIGMuc2Vzc2lvbi5jbGllbnRDZXJ0aWZpY2F0ZSA9PT0gbnVsbCkgewogICAgcmV0dXJuIGNhbGxiYWNrKGMsIG51bGwpOwogIH0KCiAgLy8gb3RoZXJ3aXNlIGdldCB0aGUgY2xpZW50IHNpZ25hdHVyZQogIHRscy5nZXRDbGllbnRTaWduYXR1cmUoYywgY2FsbGJhY2spOwp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgQ2hhbmdlQ2lwaGVyU3BlYyByZWNvcmQgaXMgcmVjZWl2ZWQuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqLwp0bHMuaGFuZGxlQ2hhbmdlQ2lwaGVyU3BlYyA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogIGlmKHJlY29yZC5mcmFnbWVudC5nZXRCeXRlKCkgIT09IDB4MDEpIHsKICAgIHJldHVybiBjLmVycm9yKGMsIHsKICAgICAgbWVzc2FnZTogJ0ludmFsaWQgQ2hhbmdlQ2lwaGVyU3BlYyBtZXNzYWdlIHJlY2VpdmVkLicsCiAgICAgIHNlbmQ6IHRydWUsCiAgICAgIGFsZXJ0OiB7CiAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmlsbGVnYWxfcGFyYW1ldGVyCiAgICAgIH0KICAgIH0pOwogIH0KCiAgLy8gY3JlYXRlIHBlbmRpbmcgc3RhdGUgaWY6CiAgLy8gMS4gUmVzdW1pbmcgc2Vzc2lvbiBpbiBjbGllbnQgbW9kZSBPUgogIC8vIDIuIE5PVCByZXN1bWluZyBzZXNzaW9uIGluIHNlcnZlciBtb2RlCiAgdmFyIGNsaWVudCA9IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KTsKICBpZigoYy5zZXNzaW9uLnJlc3VtaW5nICYmIGNsaWVudCkgfHwgKCFjLnNlc3Npb24ucmVzdW1pbmcgJiYgIWNsaWVudCkpIHsKICAgIGMuc3RhdGUucGVuZGluZyA9IHRscy5jcmVhdGVDb25uZWN0aW9uU3RhdGUoYyk7CiAgfQoKICAvLyBjaGFuZ2UgY3VycmVudCByZWFkIHN0YXRlIHRvIHBlbmRpbmcgcmVhZCBzdGF0ZQogIGMuc3RhdGUuY3VycmVudC5yZWFkID0gYy5zdGF0ZS5wZW5kaW5nLnJlYWQ7CgogIC8vIGNsZWFyIHBlbmRpbmcgc3RhdGUgaWY6CiAgLy8gMS4gTk9UIHJlc3VtaW5nIHNlc3Npb24gaW4gY2xpZW50IG1vZGUgT1IKICAvLyAyLiByZXN1bWluZyBhIHNlc3Npb24gaW4gc2VydmVyIG1vZGUKICBpZigoIWMuc2Vzc2lvbi5yZXN1bWluZyAmJiBjbGllbnQpIHx8IChjLnNlc3Npb24ucmVzdW1pbmcgJiYgIWNsaWVudCkpIHsKICAgIGMuc3RhdGUucGVuZGluZyA9IG51bGw7CiAgfQoKICAvLyBleHBlY3QgYSBGaW5pc2hlZCByZWNvcmQgbmV4dAogIGMuZXhwZWN0ID0gY2xpZW50ID8gU0ZJIDogQ0ZJOwoKICAvLyBjb250aW51ZQogIGMucHJvY2VzcygpOwp9OwoKLyoqCiAqIENhbGxlZCB3aGVuIGEgRmluaXNoZWQgcmVjb3JkIGlzIHJlY2VpdmVkLgogKgogKiBXaGVuIHRoaXMgbWVzc2FnZSB3aWxsIGJlIHNlbnQ6CiAqICAgQSBmaW5pc2hlZCBtZXNzYWdlIGlzIGFsd2F5cyBzZW50IGltbWVkaWF0ZWx5IGFmdGVyIGEgY2hhbmdlCiAqICAgY2lwaGVyIHNwZWMgbWVzc2FnZSB0byB2ZXJpZnkgdGhhdCB0aGUga2V5IGV4Y2hhbmdlIGFuZAogKiAgIGF1dGhlbnRpY2F0aW9uIHByb2Nlc3NlcyB3ZXJlIHN1Y2Nlc3NmdWwuIEl0IGlzIGVzc2VudGlhbCB0aGF0IGEKICogICBjaGFuZ2UgY2lwaGVyIHNwZWMgbWVzc2FnZSBiZSByZWNlaXZlZCBiZXR3ZWVuIHRoZSBvdGhlcgogKiAgIGhhbmRzaGFrZSBtZXNzYWdlcyBhbmQgdGhlIEZpbmlzaGVkIG1lc3NhZ2UuCiAqCiAqIE1lYW5pbmcgb2YgdGhpcyBtZXNzYWdlOgogKiAgIFRoZSBmaW5pc2hlZCBtZXNzYWdlIGlzIHRoZSBmaXJzdCBwcm90ZWN0ZWQgd2l0aCB0aGUganVzdC0KICogICBuZWdvdGlhdGVkIGFsZ29yaXRobXMsIGtleXMsIGFuZCBzZWNyZXRzLiBSZWNpcGllbnRzIG9mIGZpbmlzaGVkCiAqICAgbWVzc2FnZXMgbXVzdCB2ZXJpZnkgdGhhdCB0aGUgY29udGVudHMgYXJlIGNvcnJlY3QuICBPbmNlIGEgc2lkZQogKiAgIGhhcyBzZW50IGl0cyBGaW5pc2hlZCBtZXNzYWdlIGFuZCByZWNlaXZlZCBhbmQgdmFsaWRhdGVkIHRoZQogKiAgIEZpbmlzaGVkIG1lc3NhZ2UgZnJvbSBpdHMgcGVlciwgaXQgbWF5IGJlZ2luIHRvIHNlbmQgYW5kIHJlY2VpdmUKICogICBhcHBsaWNhdGlvbiBkYXRhIG92ZXIgdGhlIGNvbm5lY3Rpb24uCiAqCiAqIHN0cnVjdCB7CiAqICAgb3BhcXVlIHZlcmlmeV9kYXRhW3ZlcmlmeV9kYXRhX2xlbmd0aF07CiAqIH0gRmluaXNoZWQ7CiAqCiAqIHZlcmlmeV9kYXRhCiAqICAgUFJGKG1hc3Rlcl9zZWNyZXQsIGZpbmlzaGVkX2xhYmVsLCBIYXNoKGhhbmRzaGFrZV9tZXNzYWdlcykpCiAqICAgICBbMC4udmVyaWZ5X2RhdGFfbGVuZ3RoLTFdOwogKgogKiBmaW5pc2hlZF9sYWJlbAogKiAgIEZvciBGaW5pc2hlZCBtZXNzYWdlcyBzZW50IGJ5IHRoZSBjbGllbnQsIHRoZSBzdHJpbmcKICogICAiY2xpZW50IGZpbmlzaGVkIi4gRm9yIEZpbmlzaGVkIG1lc3NhZ2VzIHNlbnQgYnkgdGhlIHNlcnZlciwgdGhlCiAqICAgc3RyaW5nICJzZXJ2ZXIgZmluaXNoZWQiLgogKgogKiB2ZXJpZnlfZGF0YV9sZW5ndGggZGVwZW5kcyBvbiB0aGUgY2lwaGVyIHN1aXRlLiBJZiBpdCBpcyBub3Qgc3BlY2lmaWVkCiAqIGJ5IHRoZSBjaXBoZXIgc3VpdGUsIHRoZW4gaXQgaXMgMTIuIFZlcnNpb25zIG9mIFRMUyA8IDEuMiBhbHdheXMgdXNlZAogKiAxMiBieXRlcy4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSByZWNvcmQgdGhlIHJlY29yZC4KICogQHBhcmFtIGxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZS4KICovCnRscy5oYW5kbGVGaW5pc2hlZCA9IGZ1bmN0aW9uKGMsIHJlY29yZCwgbGVuZ3RoKSB7CiAgLy8gcmV3aW5kIHRvIGdldCBmdWxsIGJ5dGVzIGZvciBtZXNzYWdlIHNvIGl0IGNhbiBiZSBtYW51YWxseQogIC8vIGRpZ2VzdGVkIGJlbG93IChzcGVjaWFsIGNhc2UgZm9yIEZpbmlzaGVkIG1lc3NhZ2VzIGJlY2F1c2UgdGhleQogIC8vIG11c3QgYmUgZGlnZXN0ZWQgKmFmdGVyKiBoYW5kbGluZyBhcyBvcHBvc2VkIHRvIGFsbCBvdGhlcnMpCiAgdmFyIGIgPSByZWNvcmQuZnJhZ21lbnQ7CiAgYi5yZWFkIC09IDQ7CiAgdmFyIG1zZ0J5dGVzID0gYi5ieXRlcygpOwogIGIucmVhZCArPSA0OwoKICAvLyBtZXNzYWdlIGNvbnRhaW5zIG9ubHkgdmVyaWZ5X2RhdGEKICB2YXIgdmQgPSByZWNvcmQuZnJhZ21lbnQuZ2V0Qnl0ZXMoKTsKCiAgLy8gZW5zdXJlIHZlcmlmeSBkYXRhIGlzIGNvcnJlY3QKICBiID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBiLnB1dEJ1ZmZlcihjLnNlc3Npb24ubWQ1LmRpZ2VzdCgpKTsKICBiLnB1dEJ1ZmZlcihjLnNlc3Npb24uc2hhMS5kaWdlc3QoKSk7CgogIC8vIHNldCBsYWJlbCBiYXNlZCBvbiBlbnRpdHkgdHlwZQogIHZhciBjbGllbnQgPSAoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCk7CiAgdmFyIGxhYmVsID0gY2xpZW50ID8gJ3NlcnZlciBmaW5pc2hlZCcgOiAnY2xpZW50IGZpbmlzaGVkJzsKCiAgLy8gVE9ETzogZGV0ZXJtaW5lIHByZiBmdW5jdGlvbiBhbmQgdmVyaWZ5IGxlbmd0aCBmb3IgVExTIDEuMgogIHZhciBzcCA9IGMuc2Vzc2lvbi5zcDsKICB2YXIgdmRsID0gMTI7CiAgdmFyIHByZiA9IHByZl9UTFMxOwogIGIgPSBwcmYoc3AubWFzdGVyX3NlY3JldCwgbGFiZWwsIGIuZ2V0Qnl0ZXMoKSwgdmRsKTsKICBpZihiLmdldEJ5dGVzKCkgIT09IHZkKSB7CiAgICByZXR1cm4gYy5lcnJvcihjLCB7CiAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIHZlcmlmeV9kYXRhIGluIEZpbmlzaGVkIG1lc3NhZ2UuJywKICAgICAgc2VuZDogdHJ1ZSwKICAgICAgYWxlcnQ6IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uZGVjcnlwdF9lcnJvcgogICAgICB9CiAgICB9KTsKICB9CgogIC8vIGRpZ2VzdCBmaW5pc2hlZCBtZXNzYWdlIG5vdyB0aGF0IGl0IGhhcyBiZWVuIGhhbmRsZWQKICBjLnNlc3Npb24ubWQ1LnVwZGF0ZShtc2dCeXRlcyk7CiAgYy5zZXNzaW9uLnNoYTEudXBkYXRlKG1zZ0J5dGVzKTsKCiAgLy8gcmVzdW1pbmcgc2Vzc2lvbiBhcyBjbGllbnQgb3IgTk9UIHJlc3VtaW5nIHNlc3Npb24gYXMgc2VydmVyCiAgaWYoKGMuc2Vzc2lvbi5yZXN1bWluZyAmJiBjbGllbnQpIHx8ICghYy5zZXNzaW9uLnJlc3VtaW5nICYmICFjbGllbnQpKSB7CiAgICAvLyBjcmVhdGUgY2hhbmdlIGNpcGhlciBzcGVjIG1lc3NhZ2UKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmNoYW5nZV9jaXBoZXJfc3BlYywKICAgICAgZGF0YTogdGxzLmNyZWF0ZUNoYW5nZUNpcGhlclNwZWMoKQogICAgfSkpOwoKICAgIC8vIGNoYW5nZSBjdXJyZW50IHdyaXRlIHN0YXRlIHRvIHBlbmRpbmcgd3JpdGUgc3RhdGUsIGNsZWFyIHBlbmRpbmcKICAgIGMuc3RhdGUuY3VycmVudC53cml0ZSA9IGMuc3RhdGUucGVuZGluZy53cml0ZTsKICAgIGMuc3RhdGUucGVuZGluZyA9IG51bGw7CgogICAgLy8gY3JlYXRlIGZpbmlzaGVkIG1lc3NhZ2UKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgICAgZGF0YTogdGxzLmNyZWF0ZUZpbmlzaGVkKGMpCiAgICB9KSk7CiAgfQoKICAvLyBleHBlY3QgYXBwbGljYXRpb24gZGF0YSBuZXh0CiAgYy5leHBlY3QgPSBjbGllbnQgPyBTQUQgOiBDQUQ7CgogIC8vIGhhbmRzaGFrZSBjb21wbGV0ZQogIGMuaGFuZHNoYWtpbmcgPSBmYWxzZTsKICArK2MuaGFuZHNoYWtlczsKCiAgLy8gc2F2ZSBhY2Nlc3MgdG8gcGVlciBjZXJ0aWZpY2F0ZQogIGMucGVlckNlcnRpZmljYXRlID0gY2xpZW50ID8KICAgIGMuc2Vzc2lvbi5zZXJ2ZXJDZXJ0aWZpY2F0ZSA6IGMuc2Vzc2lvbi5jbGllbnRDZXJ0aWZpY2F0ZTsKCiAgLy8gc2VuZCByZWNvcmRzCiAgdGxzLmZsdXNoKGMpOwoKICAvLyBub3cgY29ubmVjdGVkCiAgYy5pc0Nvbm5lY3RlZCA9IHRydWU7CiAgYy5jb25uZWN0ZWQoYyk7CgogIC8vIGNvbnRpbnVlCiAgYy5wcm9jZXNzKCk7Cn07CgovKioKICogQ2FsbGVkIHdoZW4gYW4gQWxlcnQgcmVjb3JkIGlzIHJlY2VpdmVkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKi8KdGxzLmhhbmRsZUFsZXJ0ID0gZnVuY3Rpb24oYywgcmVjb3JkKSB7CiAgLy8gcmVhZCBhbGVydAogIHZhciBiID0gcmVjb3JkLmZyYWdtZW50OwogIHZhciBhbGVydCA9IHsKICAgIGxldmVsOiBiLmdldEJ5dGUoKSwKICAgIGRlc2NyaXB0aW9uOiBiLmdldEJ5dGUoKQogIH07CgogIC8vIFRPRE86IGNvbnNpZGVyIHVzaW5nIGEgdGFibGU/CiAgLy8gZ2V0IGFwcHJvcHJpYXRlIG1lc3NhZ2UKICB2YXIgbXNnOwogIHN3aXRjaChhbGVydC5kZXNjcmlwdGlvbikgewogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNsb3NlX25vdGlmeToKICAgIG1zZyA9ICdDb25uZWN0aW9uIGNsb3NlZC4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24udW5leHBlY3RlZF9tZXNzYWdlOgogICAgbXNnID0gJ1VuZXhwZWN0ZWQgbWVzc2FnZS4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uYmFkX3JlY29yZF9tYWM6CiAgICBtc2cgPSAnQmFkIHJlY29yZCBNQUMuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmRlY3J5cHRpb25fZmFpbGVkOgogICAgbXNnID0gJ0RlY3J5cHRpb24gZmFpbGVkLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5yZWNvcmRfb3ZlcmZsb3c6CiAgICBtc2cgPSAnUmVjb3JkIG92ZXJmbG93Lic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5kZWNvbXByZXNzaW9uX2ZhaWx1cmU6CiAgICBtc2cgPSAnRGVjb21wcmVzc2lvbiBmYWlsZWQuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmhhbmRzaGFrZV9mYWlsdXJlOgogICAgbXNnID0gJ0hhbmRzaGFrZSBmYWlsdXJlLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5iYWRfY2VydGlmaWNhdGU6CiAgICBtc2cgPSAnQmFkIGNlcnRpZmljYXRlLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi51bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZToKICAgIG1zZyA9ICdVbnN1cHBvcnRlZCBjZXJ0aWZpY2F0ZS4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uY2VydGlmaWNhdGVfcmV2b2tlZDoKICAgIG1zZyA9ICdDZXJ0aWZpY2F0ZSByZXZva2VkLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5jZXJ0aWZpY2F0ZV9leHBpcmVkOgogICAgbXNnID0gJ0NlcnRpZmljYXRlIGV4cGlyZWQuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNlcnRpZmljYXRlX3Vua25vd246CiAgICBtc2cgPSAnQ2VydGlmaWNhdGUgdW5rbm93bi4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uaWxsZWdhbF9wYXJhbWV0ZXI6CiAgICBtc2cgPSAnSWxsZWdhbCBwYXJhbWV0ZXIuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLnVua25vd25fY2E6CiAgICBtc2cgPSAnVW5rbm93biBjZXJ0aWZpY2F0ZSBhdXRob3JpdHkuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmFjY2Vzc19kZW5pZWQ6CiAgICBtc2cgPSAnQWNjZXNzIGRlbmllZC4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uZGVjb2RlX2Vycm9yOgogICAgbXNnID0gJ0RlY29kZSBlcnJvci4nOwogICAgYnJlYWs7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uZGVjcnlwdF9lcnJvcjoKICAgIG1zZyA9ICdEZWNyeXB0IGVycm9yLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5leHBvcnRfcmVzdHJpY3Rpb246CiAgICBtc2cgPSAnRXhwb3J0IHJlc3RyaWN0aW9uLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5wcm90b2NvbF92ZXJzaW9uOgogICAgbXNnID0gJ1Vuc3VwcG9ydGVkIHByb3RvY29sIHZlcnNpb24uJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmluc3VmZmljaWVudF9zZWN1cml0eToKICAgIG1zZyA9ICdJbnN1ZmZpY2llbnQgc2VjdXJpdHkuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yOgogICAgbXNnID0gJ0ludGVybmFsIGVycm9yLic7CiAgICBicmVhazsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi51c2VyX2NhbmNlbGVkOgogICAgbXNnID0gJ1VzZXIgY2FuY2VsZWQuJzsKICAgIGJyZWFrOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLm5vX3JlbmVnb3RpYXRpb246CiAgICBtc2cgPSAnUmVuZWdvdGlhdGlvbiBub3Qgc3VwcG9ydGVkLic7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgbXNnID0gJ1Vua25vd24gZXJyb3IuJzsKICAgIGJyZWFrOwogIH0KCiAgLy8gY2xvc2UgY29ubmVjdGlvbiBvbiBjbG9zZV9ub3RpZnksIG5vdCBhbiBlcnJvcgogIGlmKGFsZXJ0LmRlc2NyaXB0aW9uID09PSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uY2xvc2Vfbm90aWZ5KSB7CiAgICByZXR1cm4gYy5jbG9zZSgpOwogIH0KCiAgLy8gY2FsbCBlcnJvciBoYW5kbGVyCiAgYy5lcnJvcihjLCB7CiAgICBtZXNzYWdlOiBtc2csCiAgICBzZW5kOiBmYWxzZSwKICAgIC8vIG9yaWdpbiBpcyB0aGUgb3Bwb3NpdGUgZW5kCiAgICBvcmlnaW46IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KSA/ICdzZXJ2ZXInIDogJ2NsaWVudCcsCiAgICBhbGVydDogYWxlcnQKICB9KTsKCiAgLy8gY29udGludWUKICBjLnByb2Nlc3MoKTsKfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhIEhhbmRzaGFrZSByZWNvcmQgaXMgcmVjZWl2ZWQuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gcmVjb3JkIHRoZSByZWNvcmQuCiAqLwp0bHMuaGFuZGxlSGFuZHNoYWtlID0gZnVuY3Rpb24oYywgcmVjb3JkKSB7CiAgLy8gZ2V0IHRoZSBoYW5kc2hha2UgdHlwZSBhbmQgbWVzc2FnZSBsZW5ndGgKICB2YXIgYiA9IHJlY29yZC5mcmFnbWVudDsKICB2YXIgdHlwZSA9IGIuZ2V0Qnl0ZSgpOwogIHZhciBsZW5ndGggPSBiLmdldEludDI0KCk7CgogIC8vIHNlZSBpZiB0aGUgcmVjb3JkIGZyYWdtZW50IGRvZXNuJ3QgeWV0IGNvbnRhaW4gdGhlIGZ1bGwgbWVzc2FnZQogIGlmKGxlbmd0aCA+IGIubGVuZ3RoKCkpIHsKICAgIC8vIGNhY2hlIHRoZSByZWNvcmQsIGNsZWFyIGl0cyBmcmFnbWVudCwgYW5kIHJlc2V0IHRoZSBidWZmZXIgcmVhZAogICAgLy8gcG9pbnRlciBiZWZvcmUgdGhlIHR5cGUgYW5kIGxlbmd0aCB3ZXJlIHJlYWQKICAgIGMuZnJhZ21lbnRlZCA9IHJlY29yZDsKICAgIHJlY29yZC5mcmFnbWVudCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICBiLnJlYWQgLT0gNDsKCiAgICAvLyBjb250aW51ZQogICAgcmV0dXJuIGMucHJvY2VzcygpOwogIH0KCiAgLy8gZnVsbCBtZXNzYWdlIG5vdyBhdmFpbGFibGUsIGNsZWFyIGNhY2hlLCByZXNldCByZWFkIHBvaW50ZXIgdG8KICAvLyBiZWZvcmUgdHlwZSBhbmQgbGVuZ3RoCiAgYy5mcmFnbWVudGVkID0gbnVsbDsKICBiLnJlYWQgLT0gNDsKCiAgLy8gc2F2ZSB0aGUgaGFuZHNoYWtlIGJ5dGVzIGZvciBkaWdlc3Rpb24gYWZ0ZXIgaGFuZGxlciBpcyBmb3VuZAogIC8vIChpbmNsdWRlIHR5cGUgYW5kIGxlbmd0aCBvZiBoYW5kc2hha2UgbXNnKQogIHZhciBieXRlcyA9IGIuYnl0ZXMobGVuZ3RoICsgNCk7CgogIC8vIHJlc3RvcmUgcmVhZCBwb2ludGVyCiAgYi5yZWFkICs9IDQ7CgogIC8vIGhhbmRsZSBleHBlY3RlZCBtZXNzYWdlCiAgaWYodHlwZSBpbiBoc1RhYmxlW2MuZW50aXR5XVtjLmV4cGVjdF0pIHsKICAgIC8vIGluaXRpYWxpemUgc2VydmVyIHNlc3Npb24KICAgIGlmKGMuZW50aXR5ID09PSB0bHMuQ29ubmVjdGlvbkVuZC5zZXJ2ZXIgJiYgIWMub3BlbiAmJiAhYy5mYWlsKSB7CiAgICAgIGMuaGFuZHNoYWtpbmcgPSB0cnVlOwogICAgICBjLnNlc3Npb24gPSB7CiAgICAgICAgdmVyc2lvbjogbnVsbCwKICAgICAgICBleHRlbnNpb25zOiB7CiAgICAgICAgICBzZXJ2ZXJfbmFtZTogewogICAgICAgICAgICBzZXJ2ZXJOYW1lTGlzdDogW10KICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIGNpcGhlclN1aXRlOiBudWxsLAogICAgICAgIGNvbXByZXNzaW9uTWV0aG9kOiBudWxsLAogICAgICAgIHNlcnZlckNlcnRpZmljYXRlOiBudWxsLAogICAgICAgIGNsaWVudENlcnRpZmljYXRlOiBudWxsLAogICAgICAgIG1kNTogZm9yZ2UubWQubWQ1LmNyZWF0ZSgpLAogICAgICAgIHNoYTE6IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCkKICAgICAgfTsKICAgIH0KCiAgICAvKiBVcGRhdGUgaGFuZHNoYWtlIG1lc3NhZ2VzIGRpZ2VzdC4gRmluaXNoZWQgYW5kIENlcnRpZmljYXRlVmVyaWZ5CiAgICAgIG1lc3NhZ2VzIGFyZSBub3QgZGlnZXN0ZWQgaGVyZS4gVGhleSBjYW4ndCBiZSBkaWdlc3RlZCBhcyBwYXJ0IG9mCiAgICAgIHRoZSB2ZXJpZnlfZGF0YSB0aGF0IHRoZXkgY29udGFpbi4gVGhlc2UgbWVzc2FnZXMgYXJlIG1hbnVhbGx5CiAgICAgIGRpZ2VzdGVkIGluIHRoZWlyIGhhbmRsZXJzLiBIZWxsb1JlcXVlc3QgbWVzc2FnZXMgYXJlIHNpbXBseSBuZXZlcgogICAgICBpbmNsdWRlZCBpbiB0aGUgaGFuZHNoYWtlIG1lc3NhZ2UgZGlnZXN0IGFjY29yZGluZyB0byBzcGVjLiAqLwogICAgaWYodHlwZSAhPT0gdGxzLkhhbmRzaGFrZVR5cGUuaGVsbG9fcmVxdWVzdCAmJgogICAgICB0eXBlICE9PSB0bHMuSGFuZHNoYWtlVHlwZS5jZXJ0aWZpY2F0ZV92ZXJpZnkgJiYKICAgICAgdHlwZSAhPT0gdGxzLkhhbmRzaGFrZVR5cGUuZmluaXNoZWQpIHsKICAgICAgYy5zZXNzaW9uLm1kNS51cGRhdGUoYnl0ZXMpOwogICAgICBjLnNlc3Npb24uc2hhMS51cGRhdGUoYnl0ZXMpOwogICAgfQoKICAgIC8vIGhhbmRsZSBzcGVjaWZpYyBoYW5kc2hha2UgdHlwZSByZWNvcmQKICAgIGhzVGFibGVbYy5lbnRpdHldW2MuZXhwZWN0XVt0eXBlXShjLCByZWNvcmQsIGxlbmd0aCk7CiAgfSBlbHNlIHsKICAgIC8vIHVuZXhwZWN0ZWQgcmVjb3JkCiAgICB0bHMuaGFuZGxlVW5leHBlY3RlZChjLCByZWNvcmQpOwogIH0KfTsKCi8qKgogKiBDYWxsZWQgd2hlbiBhbiBBcHBsaWNhdGlvbkRhdGEgcmVjb3JkIGlzIHJlY2VpdmVkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKi8KdGxzLmhhbmRsZUFwcGxpY2F0aW9uRGF0YSA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogIC8vIGJ1ZmZlciBkYXRhLCBub3RpZnkgdGhhdCBpdHMgcmVhZHkKICBjLmRhdGEucHV0QnVmZmVyKHJlY29yZC5mcmFnbWVudCk7CiAgYy5kYXRhUmVhZHkoYyk7CgogIC8vIGNvbnRpbnVlCiAgYy5wcm9jZXNzKCk7Cn07CgovKioKICogQ2FsbGVkIHdoZW4gYSBIZWFydGJlYXQgcmVjb3JkIGlzIHJlY2VpdmVkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkLgogKi8KdGxzLmhhbmRsZUhlYXJ0YmVhdCA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogIC8vIGdldCB0aGUgaGVhcnRiZWF0IHR5cGUgYW5kIHBheWxvYWQKICB2YXIgYiA9IHJlY29yZC5mcmFnbWVudDsKICB2YXIgdHlwZSA9IGIuZ2V0Qnl0ZSgpOwogIHZhciBsZW5ndGggPSBiLmdldEludDE2KCk7CiAgdmFyIHBheWxvYWQgPSBiLmdldEJ5dGVzKGxlbmd0aCk7CgogIGlmKHR5cGUgPT09IHRscy5IZWFydGJlYXRNZXNzYWdlVHlwZS5oZWFydGJlYXRfcmVxdWVzdCkgewogICAgLy8gZGlzY2FyZCByZXF1ZXN0IGR1cmluZyBoYW5kc2hha2Ugb3IgaWYgbGVuZ3RoIGlzIHRvbyBsYXJnZQogICAgaWYoYy5oYW5kc2hha2luZyB8fCBsZW5ndGggPiBwYXlsb2FkLmxlbmd0aCkgewogICAgICAvLyBjb250aW51ZQogICAgICByZXR1cm4gYy5wcm9jZXNzKCk7CiAgICB9CiAgICAvLyByZXRyYW5zbWl0IHBheWxvYWQKICAgIHRscy5xdWV1ZShjLCB0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhlYXJ0YmVhdCwKICAgICAgZGF0YTogdGxzLmNyZWF0ZUhlYXJ0YmVhdCgKICAgICAgICB0bHMuSGVhcnRiZWF0TWVzc2FnZVR5cGUuaGVhcnRiZWF0X3Jlc3BvbnNlLCBwYXlsb2FkKQogICAgfSkpOwogICAgdGxzLmZsdXNoKGMpOwogIH0gZWxzZSBpZih0eXBlID09PSB0bHMuSGVhcnRiZWF0TWVzc2FnZVR5cGUuaGVhcnRiZWF0X3Jlc3BvbnNlKSB7CiAgICAvLyBjaGVjayBwYXlsb2FkIGFnYWluc3QgZXhwZWN0ZWQgcGF5bG9hZCwgZGlzY2FyZCBoZWFydGJlYXQgaWYgbm8gbWF0Y2gKICAgIGlmKHBheWxvYWQgIT09IGMuZXhwZWN0ZWRIZWFydGJlYXRQYXlsb2FkKSB7CiAgICAgIC8vIGNvbnRpbnVlCiAgICAgIHJldHVybiBjLnByb2Nlc3MoKTsKICAgIH0KCiAgICAvLyBub3RpZnkgdGhhdCBhIHZhbGlkIGhlYXJ0YmVhdCB3YXMgcmVjZWl2ZWQKICAgIGlmKGMuaGVhcnRiZWF0UmVjZWl2ZWQpIHsKICAgICAgYy5oZWFydGJlYXRSZWNlaXZlZChjLCBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihwYXlsb2FkKSk7CiAgICB9CiAgfQoKICAvLyBjb250aW51ZQogIGMucHJvY2VzcygpOwp9OwoKLyoqCiAqIFRoZSB0cmFuc2lzdGlvbmFsIHN0YXRlIHRhYmxlcyBmb3IgcmVjZWl2aW5nIFRMUyByZWNvcmRzLiBJdCBtYXBzIHRoZQogKiBjdXJyZW50IFRMUyBlbmdpbmUgc3RhdGUgYW5kIGEgcmVjZWl2ZWQgcmVjb3JkIHRvIGEgZnVuY3Rpb24gdG8gaGFuZGxlIHRoZQogKiByZWNvcmQgYW5kIHVwZGF0ZSB0aGUgc3RhdGUuCiAqCiAqIEZvciBpbnN0YW5jZSwgaWYgdGhlIGN1cnJlbnQgc3RhdGUgaXMgU0hFLCB0aGVuIHRoZSBUTFMgZW5naW5lIGlzIGV4cGVjdGluZwogKiBhIFNlcnZlckhlbGxvIHJlY29yZC4gT25jZSBhIHJlY29yZCBpcyByZWNlaXZlZCwgdGhlIGhhbmRsZXIgZnVuY3Rpb24gaXMKICogbG9va2VkIHVwIHVzaW5nIHRoZSBzdGF0ZSBTSEUgYW5kIHRoZSByZWNvcmQncyBjb250ZW50IHR5cGUuCiAqCiAqIFRoZSByZXN1bHRpbmcgZnVuY3Rpb24gd2lsbCBlaXRoZXIgYmUgYW4gZXJyb3IgaGFuZGxlciBvciBhIHJlY29yZCBoYW5kbGVyLgogKiBUaGUgZnVuY3Rpb24gd2lsbCB0YWtlIHdoYXRldmVyIGFjdGlvbiBpcyBhcHByb3ByaWF0ZSBhbmQgdXBkYXRlIHRoZSBzdGF0ZQogKiBmb3IgdGhlIG5leHQgcmVjb3JkLgogKgogKiBUaGUgc3RhdGVzIGFyZSBhbGwgYmFzZWQgb24gcG9zc2libGUgc2VydmVyIHJlY29yZCB0eXBlcy4gTm90ZSB0aGF0IHRoZQogKiBjbGllbnQgd2lsbCBuZXZlciBzcGVjaWZpY2FsbHkgZXhwZWN0IHRvIHJlY2VpdmUgYSBIZWxsb1JlcXVlc3Qgb3IgYW4gYWxlcnQKICogZnJvbSB0aGUgc2VydmVyIHNvIHRoZXJlIGlzIG5vIHN0YXRlIHRoYXQgcmVmbGVjdHMgdGhpcy4gVGhlc2UgbWVzc2FnZXMgbWF5CiAqIG9jY3VyIGF0IGFueSB0aW1lLgogKgogKiBUaGVyZSBhcmUgdHdvIHRhYmxlcyBmb3IgbWFwcGluZyBzdGF0ZXMgYmVjYXVzZSB0aGVyZSBpcyBhIHNlY29uZCB0aWVyIG9mCiAqIHR5cGVzIGZvciBoYW5kc2hha2UgbWVzc2FnZXMuIE9uY2UgYSByZWNvcmQgd2l0aCBhIGNvbnRlbnQgdHlwZSBvZiBoYW5kc2hha2UKICogaXMgcmVjZWl2ZWQsIHRoZSBoYW5kc2hha2UgcmVjb3JkIGhhbmRsZXIgd2lsbCBsb29rIHVwIHRoZSBoYW5kc2hha2UgdHlwZSBpbgogKiB0aGUgc2Vjb25kYXJ5IG1hcCB0byBnZXQgaXRzIGFwcHJvcHJpYXRlIGhhbmRsZXIuCiAqCiAqIFZhbGlkIG1lc3NhZ2Ugb3JkZXJzIGFyZSBhcyBmb2xsb3dzOgogKgogKiA9PT09PT09PT09PT09PT09PT09PT09PUZVTEwgSEFORFNIQUtFPT09PT09PT09PT09PT09PT09PT09PQogKiBDbGllbnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlcnZlcgogKgogKiBDbGllbnRIZWxsbyAgICAgICAgICAgICAgICAgIC0tLS0tLS0tPgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZXJ2ZXJIZWxsbwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENlcnRpZmljYXRlKgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNlcnZlcktleUV4Y2hhbmdlKgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2VydGlmaWNhdGVSZXF1ZXN0KgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwtLS0tLS0tLSAgICAgIFNlcnZlckhlbGxvRG9uZQogKiBDZXJ0aWZpY2F0ZSoKICogQ2xpZW50S2V5RXhjaGFuZ2UKICogQ2VydGlmaWNhdGVWZXJpZnkqCiAqIFtDaGFuZ2VDaXBoZXJTcGVjXQogKiBGaW5pc2hlZCAgICAgICAgICAgICAgICAgICAgIC0tLS0tLS0tPgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtDaGFuZ2VDaXBoZXJTcGVjXQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwtLS0tLS0tLSAgICAgICAgICAgICBGaW5pc2hlZAogKiBBcHBsaWNhdGlvbiBEYXRhICAgICAgICAgICAgIDwtLS0tLS0tPiAgICAgQXBwbGljYXRpb24gRGF0YQogKgogKiA9PT09PT09PT09PT09PT09PT09PT1TRVNTSU9OIFJFU1VNUFRJT049PT09PT09PT09PT09PT09PT09PT0KICogQ2xpZW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VydmVyCiAqCiAqIENsaWVudEhlbGxvICAgICAgICAgICAgICAgICAgIC0tLS0tLS0tPgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VydmVySGVsbG8KICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW0NoYW5nZUNpcGhlclNwZWNdCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwtLS0tLS0tLSAgICAgICAgICAgICBGaW5pc2hlZAogKiBbQ2hhbmdlQ2lwaGVyU3BlY10KICogRmluaXNoZWQgICAgICAgICAgICAgICAgICAgICAgLS0tLS0tLS0+CiAqIEFwcGxpY2F0aW9uIERhdGEgICAgICAgICAgICAgIDwtLS0tLS0tPiAgICAgQXBwbGljYXRpb24gRGF0YQogKi8KLy8gY2xpZW50IGV4cGVjdCBzdGF0ZXMgKGluZGljYXRlIHdoaWNoIHJlY29yZHMgYXJlIGV4cGVjdGVkIHRvIGJlIHJlY2VpdmVkKQp2YXIgU0hFID0gMDsgLy8gcmN2IHNlcnZlciBoZWxsbwp2YXIgU0NFID0gMTsgLy8gcmN2IHNlcnZlciBjZXJ0aWZpY2F0ZQp2YXIgU0tFID0gMjsgLy8gcmN2IHNlcnZlciBrZXkgZXhjaGFuZ2UKdmFyIFNDUiA9IDM7IC8vIHJjdiBjZXJ0aWZpY2F0ZSByZXF1ZXN0CnZhciBTSEQgPSA0OyAvLyByY3Ygc2VydmVyIGhlbGxvIGRvbmUKdmFyIFNDQyA9IDU7IC8vIHJjdiBjaGFuZ2UgY2lwaGVyIHNwZWMKdmFyIFNGSSA9IDY7IC8vIHJjdiBmaW5pc2hlZAp2YXIgU0FEID0gNzsgLy8gcmN2IGFwcGxpY2F0aW9uIGRhdGEKdmFyIFNFUiA9IDg7IC8vIG5vdCBleHBlY3RpbmcgYW55IG1lc3NhZ2VzIGF0IHRoaXMgcG9pbnQKCi8vIHNlcnZlciBleHBlY3Qgc3RhdGVzCnZhciBDSEUgPSAwOyAvLyByY3YgY2xpZW50IGhlbGxvCnZhciBDQ0UgPSAxOyAvLyByY3YgY2xpZW50IGNlcnRpZmljYXRlCnZhciBDS0UgPSAyOyAvLyByY3YgY2xpZW50IGtleSBleGNoYW5nZQp2YXIgQ0NWID0gMzsgLy8gcmN2IGNlcnRpZmljYXRlIHZlcmlmeQp2YXIgQ0NDID0gNDsgLy8gcmN2IGNoYW5nZSBjaXBoZXIgc3BlYwp2YXIgQ0ZJID0gNTsgLy8gcmN2IGZpbmlzaGVkCnZhciBDQUQgPSA2OyAvLyByY3YgYXBwbGljYXRpb24gZGF0YQp2YXIgQ0VSID0gNzsgLy8gbm90IGV4cGVjdGluZyBhbnkgbWVzc2FnZXMgYXQgdGhpcyBwb2ludAoKLy8gbWFwIGNsaWVudCBjdXJyZW50IGV4cGVjdCBzdGF0ZSBhbmQgY29udGVudCB0eXBlIHRvIGZ1bmN0aW9uCnZhciBfXyA9IHRscy5oYW5kbGVVbmV4cGVjdGVkOwp2YXIgUjAgPSB0bHMuaGFuZGxlQ2hhbmdlQ2lwaGVyU3BlYzsKdmFyIFIxID0gdGxzLmhhbmRsZUFsZXJ0Owp2YXIgUjIgPSB0bHMuaGFuZGxlSGFuZHNoYWtlOwp2YXIgUjMgPSB0bHMuaGFuZGxlQXBwbGljYXRpb25EYXRhOwp2YXIgUjQgPSB0bHMuaGFuZGxlSGVhcnRiZWF0Owp2YXIgY3RUYWJsZSA9IFtdOwpjdFRhYmxlW3Rscy5Db25uZWN0aW9uRW5kLmNsaWVudF0gPSBbCi8vICAgICAgQ0MsQUwsSFMsQUQsSEIKLypTSEUqL1tfXyxSMSxSMixfXyxSNF0sCi8qU0NFKi9bX18sUjEsUjIsX18sUjRdLAovKlNLRSovW19fLFIxLFIyLF9fLFI0XSwKLypTQ1IqL1tfXyxSMSxSMixfXyxSNF0sCi8qU0hEKi9bX18sUjEsUjIsX18sUjRdLAovKlNDQyovW1IwLFIxLF9fLF9fLFI0XSwKLypTRkkqL1tfXyxSMSxSMixfXyxSNF0sCi8qU0FEKi9bX18sUjEsUjIsUjMsUjRdLAovKlNFUiovW19fLFIxLFIyLF9fLFI0XQpdOwoKLy8gbWFwIHNlcnZlciBjdXJyZW50IGV4cGVjdCBzdGF0ZSBhbmQgY29udGVudCB0eXBlIHRvIGZ1bmN0aW9uCmN0VGFibGVbdGxzLkNvbm5lY3Rpb25FbmQuc2VydmVyXSA9IFsKLy8gICAgICBDQyxBTCxIUyxBRAovKkNIRSovW19fLFIxLFIyLF9fLFI0XSwKLypDQ0UqL1tfXyxSMSxSMixfXyxSNF0sCi8qQ0tFKi9bX18sUjEsUjIsX18sUjRdLAovKkNDViovW19fLFIxLFIyLF9fLFI0XSwKLypDQ0MqL1tSMCxSMSxfXyxfXyxSNF0sCi8qQ0ZJKi9bX18sUjEsUjIsX18sUjRdLAovKkNBRCovW19fLFIxLFIyLFIzLFI0XSwKLypDRVIqL1tfXyxSMSxSMixfXyxSNF0KXTsKCi8vIG1hcCBjbGllbnQgY3VycmVudCBleHBlY3Qgc3RhdGUgYW5kIGhhbmRzaGFrZSB0eXBlIHRvIGZ1bmN0aW9uCnZhciBIMCA9IHRscy5oYW5kbGVIZWxsb1JlcXVlc3Q7CnZhciBIMSA9IHRscy5oYW5kbGVTZXJ2ZXJIZWxsbzsKdmFyIEgyID0gdGxzLmhhbmRsZUNlcnRpZmljYXRlOwp2YXIgSDMgPSB0bHMuaGFuZGxlU2VydmVyS2V5RXhjaGFuZ2U7CnZhciBINCA9IHRscy5oYW5kbGVDZXJ0aWZpY2F0ZVJlcXVlc3Q7CnZhciBINSA9IHRscy5oYW5kbGVTZXJ2ZXJIZWxsb0RvbmU7CnZhciBINiA9IHRscy5oYW5kbGVGaW5pc2hlZDsKdmFyIGhzVGFibGUgPSBbXTsKaHNUYWJsZVt0bHMuQ29ubmVjdGlvbkVuZC5jbGllbnRdID0gWwovLyAgICAgIEhSLDAxLFNILDAzLDA0LDA1LDA2LDA3LDA4LDA5LDEwLFNDLFNLLENSLEhELDE1LENLLDE3LDE4LDE5LEZJCi8qU0hFKi9bX18sX18sSDEsX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX19dLAovKlNDRSovW0gwLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLEgyLEgzLEg0LEg1LF9fLF9fLF9fLF9fLF9fLF9fXSwKLypTS0UqL1tIMCxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxIMyxINCxINSxfXyxfXyxfXyxfXyxfXyxfX10sCi8qU0NSKi9bSDAsX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sSDQsSDUsX18sX18sX18sX18sX18sX19dLAovKlNIRCovW0gwLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLEg1LF9fLF9fLF9fLF9fLF9fLF9fXSwKLypTQ0MqL1tIMCxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfX10sCi8qU0ZJKi9bSDAsX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sSDZdLAovKlNBRCovW0gwLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fXSwKLypTRVIqL1tIMCxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfX10KXTsKCi8vIG1hcCBzZXJ2ZXIgY3VycmVudCBleHBlY3Qgc3RhdGUgYW5kIGhhbmRzaGFrZSB0eXBlIHRvIGZ1bmN0aW9uCi8vIE5vdGU6IENBRFtDSF0gZG9lcyBub3QgbWFwIHRvIEZCIGJlY2F1c2UgcmVuZWdvdGF0aW9uIGlzIHByb2hpYml0ZWQKdmFyIEg3ID0gdGxzLmhhbmRsZUNsaWVudEhlbGxvOwp2YXIgSDggPSB0bHMuaGFuZGxlQ2xpZW50S2V5RXhjaGFuZ2U7CnZhciBIOSA9IHRscy5oYW5kbGVDZXJ0aWZpY2F0ZVZlcmlmeTsKaHNUYWJsZVt0bHMuQ29ubmVjdGlvbkVuZC5zZXJ2ZXJdID0gWwovLyAgICAgIDAxLENILDAyLDAzLDA0LDA1LDA2LDA3LDA4LDA5LDEwLENDLDEyLDEzLDE0LENWLENLLDE3LDE4LDE5LEZJCi8qQ0hFKi9bX18sSDcsX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX19dLAovKkNDRSovW19fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLEgyLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fXSwKLypDS0UqL1tfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxIOCxfXyxfXyxfXyxfX10sCi8qQ0NWKi9bX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sSDksX18sX18sX18sX18sX19dLAovKkNDQyovW19fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fXSwKLypDRkkqL1tfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxfXyxINl0sCi8qQ0FEKi9bX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX18sX19dLAovKkNFUiovW19fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fLF9fXQpdOwoKLyoqCiAqIEdlbmVyYXRlcyB0aGUgbWFzdGVyX3NlY3JldCBhbmQga2V5cyB1c2luZyB0aGUgZ2l2ZW4gc2VjdXJpdHkgcGFyYW1ldGVycy4KICoKICogVGhlIHNlY3VyaXR5IHBhcmFtZXRlcnMgZm9yIGEgVExTIGNvbm5lY3Rpb24gc3RhdGUgYXJlIGRlZmluZWQgYXMgc3VjaDoKICoKICogc3RydWN0IHsKICogICBDb25uZWN0aW9uRW5kICAgICAgICAgIGVudGl0eTsKICogICBQUkZBbGdvcml0aG0gICAgICAgICAgIHByZl9hbGdvcml0aG07CiAqICAgQnVsa0NpcGhlckFsZ29yaXRobSAgICBidWxrX2NpcGhlcl9hbGdvcml0aG07CiAqICAgQ2lwaGVyVHlwZSAgICAgICAgICAgICBjaXBoZXJfdHlwZTsKICogICB1aW50OCAgICAgICAgICAgICAgICAgIGVuY19rZXlfbGVuZ3RoOwogKiAgIHVpbnQ4ICAgICAgICAgICAgICAgICAgYmxvY2tfbGVuZ3RoOwogKiAgIHVpbnQ4ICAgICAgICAgICAgICAgICAgZml4ZWRfaXZfbGVuZ3RoOwogKiAgIHVpbnQ4ICAgICAgICAgICAgICAgICAgcmVjb3JkX2l2X2xlbmd0aDsKICogICBNQUNBbGdvcml0aG0gICAgICAgICAgIG1hY19hbGdvcml0aG07CiAqICAgdWludDggICAgICAgICAgICAgICAgICBtYWNfbGVuZ3RoOwogKiAgIHVpbnQ4ICAgICAgICAgICAgICAgICAgbWFjX2tleV9sZW5ndGg7CiAqICAgQ29tcHJlc3Npb25NZXRob2QgICAgICBjb21wcmVzc2lvbl9hbGdvcml0aG07CiAqICAgb3BhcXVlICAgICAgICAgICAgICAgICBtYXN0ZXJfc2VjcmV0WzQ4XTsKICogICBvcGFxdWUgICAgICAgICAgICAgICAgIGNsaWVudF9yYW5kb21bMzJdOwogKiAgIG9wYXF1ZSAgICAgICAgICAgICAgICAgc2VydmVyX3JhbmRvbVszMl07CiAqIH0gU2VjdXJpdHlQYXJhbWV0ZXJzOwogKgogKiBOb3RlIHRoYXQgdGhpcyBkZWZpbml0aW9uIGlzIGZyb20gVExTIDEuMi4gSW4gVExTIDEuMCBzb21lIG9mIHRoZXNlCiAqIHBhcmFtZXRlcnMgYXJlIGlnbm9yZWQgYmVjYXVzZSwgZm9yIGluc3RhbmNlLCB0aGUgUFJGQWxnb3JpdGhtIGlzIGEKICogYnVpbHRpbi1maXhlZCBhbGdvcml0aG0gY29tYmluaW5nIGl0ZXJhdGlvbnMgb2YgTUQ1IGFuZCBTSEEtMSBpbiBUTFMgMS4wLgogKgogKiBUaGUgUmVjb3JkIFByb3RvY29sIHJlcXVpcmVzIGFuIGFsZ29yaXRobSB0byBnZW5lcmF0ZSBrZXlzIHJlcXVpcmVkIGJ5IHRoZQogKiBjdXJyZW50IGNvbm5lY3Rpb24gc3RhdGUuCiAqCiAqIFRoZSBtYXN0ZXIgc2VjcmV0IGlzIGV4cGFuZGVkIGludG8gYSBzZXF1ZW5jZSBvZiBzZWN1cmUgYnl0ZXMsIHdoaWNoIGlzIHRoZW4KICogc3BsaXQgdG8gYSBjbGllbnQgd3JpdGUgTUFDIGtleSwgYSBzZXJ2ZXIgd3JpdGUgTUFDIGtleSwgYSBjbGllbnQgd3JpdGUKICogZW5jcnlwdGlvbiBrZXksIGFuZCBhIHNlcnZlciB3cml0ZSBlbmNyeXB0aW9uIGtleS4gSW4gVExTIDEuMCBhIGNsaWVudCB3cml0ZQogKiBJViBhbmQgc2VydmVyIHdyaXRlIElWIGFyZSBhbHNvIGdlbmVyYXRlZC4gRWFjaCBvZiB0aGVzZSBpcyBnZW5lcmF0ZWQgZnJvbQogKiB0aGUgYnl0ZSBzZXF1ZW5jZSBpbiB0aGF0IG9yZGVyLiBVbnVzZWQgdmFsdWVzIGFyZSBlbXB0eS4gSW4gVExTIDEuMiwgc29tZQogKiBBRUFEIGNpcGhlcnMgbWF5IGFkZGl0aW9uYWxseSByZXF1aXJlIGEgY2xpZW50IHdyaXRlIElWIGFuZCBhIHNlcnZlciB3cml0ZQogKiBJViAoc2VlIFNlY3Rpb24gNi4yLjMuMykuCiAqCiAqIFdoZW4ga2V5cywgTUFDIGtleXMsIGFuZCBJVnMgYXJlIGdlbmVyYXRlZCwgdGhlIG1hc3RlciBzZWNyZXQgaXMgdXNlZCBhcyBhbgogKiBlbnRyb3B5IHNvdXJjZS4KICoKICogVG8gZ2VuZXJhdGUgdGhlIGtleSBtYXRlcmlhbCwgY29tcHV0ZToKICoKICogbWFzdGVyX3NlY3JldCA9IFBSRihwcmVfbWFzdGVyX3NlY3JldCwgIm1hc3RlciBzZWNyZXQiLAogKiAgICAgICAgICAgICAgICAgICAgIENsaWVudEhlbGxvLnJhbmRvbSArIFNlcnZlckhlbGxvLnJhbmRvbSkKICoKICoga2V5X2Jsb2NrID0gUFJGKFNlY3VyaXR5UGFyYW1ldGVycy5tYXN0ZXJfc2VjcmV0LAogKiAgICAgICAgICAgICAgICAgImtleSBleHBhbnNpb24iLAogKiAgICAgICAgICAgICAgICAgU2VjdXJpdHlQYXJhbWV0ZXJzLnNlcnZlcl9yYW5kb20gKwogKiAgICAgICAgICAgICAgICAgU2VjdXJpdHlQYXJhbWV0ZXJzLmNsaWVudF9yYW5kb20pOwogKgogKiB1bnRpbCBlbm91Z2ggb3V0cHV0IGhhcyBiZWVuIGdlbmVyYXRlZC4gVGhlbiwgdGhlIGtleV9ibG9jayBpcwogKiBwYXJ0aXRpb25lZCBhcyBmb2xsb3dzOgogKgogKiBjbGllbnRfd3JpdGVfTUFDX2tleVtTZWN1cml0eVBhcmFtZXRlcnMubWFjX2tleV9sZW5ndGhdCiAqIHNlcnZlcl93cml0ZV9NQUNfa2V5W1NlY3VyaXR5UGFyYW1ldGVycy5tYWNfa2V5X2xlbmd0aF0KICogY2xpZW50X3dyaXRlX2tleVtTZWN1cml0eVBhcmFtZXRlcnMuZW5jX2tleV9sZW5ndGhdCiAqIHNlcnZlcl93cml0ZV9rZXlbU2VjdXJpdHlQYXJhbWV0ZXJzLmVuY19rZXlfbGVuZ3RoXQogKiBjbGllbnRfd3JpdGVfSVZbU2VjdXJpdHlQYXJhbWV0ZXJzLmZpeGVkX2l2X2xlbmd0aF0KICogc2VydmVyX3dyaXRlX0lWW1NlY3VyaXR5UGFyYW1ldGVycy5maXhlZF9pdl9sZW5ndGhdCiAqCiAqIEluIFRMUyAxLjIsIHRoZSBjbGllbnRfd3JpdGVfSVYgYW5kIHNlcnZlcl93cml0ZV9JViBhcmUgb25seSBnZW5lcmF0ZWQgZm9yCiAqIGltcGxpY2l0IG5vbmNlIHRlY2huaXF1ZXMgYXMgZGVzY3JpYmVkIGluIFNlY3Rpb24gMy4yLjEgb2YgW0FFQURdLiBUaGlzCiAqIGltcGxlbWVudGF0aW9uIHVzZXMgVExTIDEuMCBzbyBJVnMgYXJlIGdlbmVyYXRlZC4KICoKICogSW1wbGVtZW50YXRpb24gbm90ZTogVGhlIGN1cnJlbnRseSBkZWZpbmVkIGNpcGhlciBzdWl0ZSB3aGljaCByZXF1aXJlcyB0aGUKICogbW9zdCBtYXRlcmlhbCBpcyBBRVNfMjU2X0NCQ19TSEEyNTYuIEl0IHJlcXVpcmVzIDIgeCAzMiBieXRlIGtleXMgYW5kIDIgeCAzMgogKiBieXRlIE1BQyBrZXlzLCBmb3IgYSB0b3RhbCAxMjggYnl0ZXMgb2Yga2V5IG1hdGVyaWFsLiBJbiBUTFMgMS4wIGl0IGFsc28KICogcmVxdWlyZXMgMiB4IDE2IGJ5dGUgSVZzLCBzbyBpdCBhY3R1YWxseSB0YWtlcyAxNjAgYnl0ZXMgb2Yga2V5IG1hdGVyaWFsLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHNwIHRoZSBzZWN1cml0eSBwYXJhbWV0ZXJzIHRvIHVzZS4KICoKICogQHJldHVybiB0aGUgc2VjdXJpdHkga2V5cy4KICovCnRscy5nZW5lcmF0ZUtleXMgPSBmdW5jdGlvbihjLCBzcCkgewogIC8vIFRMU19SU0FfV0lUSF9BRVNfMTI4X0NCQ19TSEEgKHJlcXVpcmVkIHRvIGJlIGNvbXBsaWFudCB3aXRoIFRMUyAxLjIpICYKICAvLyBUTFNfUlNBX1dJVEhfQUVTXzI1Nl9DQkNfU0hBIGFyZSB0aGUgb25seSBjaXBoZXIgc3VpdGVzIGltcGxlbWVudGVkCiAgLy8gYXQgcHJlc2VudAoKICAvLyBUTFNfREhFX0RTU19XSVRIXzNERVNfRURFX0NCQ19TSEEgaXMgcmVxdWlyZWQgdG8gYmUgY29tcGxpYW50IHdpdGgKICAvLyBUTFMgMS4wIGJ1dCB3ZSBkb24ndCBjYXJlIHJpZ2h0IG5vdyBiZWNhdXNlIEFFUyBpcyBiZXR0ZXIgYW5kIHdlIGhhdmUKICAvLyBhbiBpbXBsZW1lbnRhdGlvbiBmb3IgaXQKCiAgLy8gVE9ETzogVExTIDEuMiBpbXBsZW1lbnRhdGlvbgogIC8qCiAgLy8gZGV0ZXJtaW5lIHRoZSBQUkYKICB2YXIgcHJmOwogIHN3aXRjaChzcC5wcmZfYWxnb3JpdGhtKSB7CiAgY2FzZSB0bHMuUFJGQWxnb3JpdGhtLnRsc19wcmZfc2hhMjU2OgogICAgcHJmID0gcHJmX3NoYTI1NjsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuCiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgUFJGJyk7CiAgfQogICovCgogIC8vIFRMUyAxLjAvMS4xIGltcGxlbWVudGF0aW9uCiAgdmFyIHByZiA9IHByZl9UTFMxOwoKICAvLyBjb25jYXRlbmF0ZSBzZXJ2ZXIgYW5kIGNsaWVudCByYW5kb20KICB2YXIgcmFuZG9tID0gc3AuY2xpZW50X3JhbmRvbSArIHNwLnNlcnZlcl9yYW5kb207CgogIC8vIG9ubHkgY3JlYXRlIG1hc3RlciBzZWNyZXQgaWYgc2Vzc2lvbiBpcyBuZXcKICBpZighYy5zZXNzaW9uLnJlc3VtaW5nKSB7CiAgICAvLyBjcmVhdGUgbWFzdGVyIHNlY3JldCwgY2xlYW4gdXAgcHJlLW1hc3RlciBzZWNyZXQKICAgIHNwLm1hc3Rlcl9zZWNyZXQgPSBwcmYoCiAgICAgIHNwLnByZV9tYXN0ZXJfc2VjcmV0LCAnbWFzdGVyIHNlY3JldCcsIHJhbmRvbSwgNDgpLmJ5dGVzKCk7CiAgICBzcC5wcmVfbWFzdGVyX3NlY3JldCA9IG51bGw7CiAgfQoKICAvLyBnZW5lcmF0ZSB0aGUgYW1vdW50IG9mIGtleSBtYXRlcmlhbCBuZWVkZWQKICByYW5kb20gPSBzcC5zZXJ2ZXJfcmFuZG9tICsgc3AuY2xpZW50X3JhbmRvbTsKICB2YXIgbGVuZ3RoID0gMiAqIHNwLm1hY19rZXlfbGVuZ3RoICsgMiAqIHNwLmVuY19rZXlfbGVuZ3RoOwoKICAvLyBpbmNsdWRlIElWIGZvciBUTFMvMS4wCiAgdmFyIHRsczEwID0gKGMudmVyc2lvbi5tYWpvciA9PT0gdGxzLlZlcnNpb25zLlRMU18xXzAubWFqb3IgJiYKICAgIGMudmVyc2lvbi5taW5vciA9PT0gdGxzLlZlcnNpb25zLlRMU18xXzAubWlub3IpOwogIGlmKHRsczEwKSB7CiAgICBsZW5ndGggKz0gMiAqIHNwLmZpeGVkX2l2X2xlbmd0aDsKICB9CiAgdmFyIGttID0gcHJmKHNwLm1hc3Rlcl9zZWNyZXQsICdrZXkgZXhwYW5zaW9uJywgcmFuZG9tLCBsZW5ndGgpOwoKICAvLyBzcGxpdCB0aGUga2V5IG1hdGVyaWFsIGludG8gdGhlIE1BQyBhbmQgZW5jcnlwdGlvbiBrZXlzCiAgdmFyIHJ2YWwgPSB7CiAgICBjbGllbnRfd3JpdGVfTUFDX2tleToga20uZ2V0Qnl0ZXMoc3AubWFjX2tleV9sZW5ndGgpLAogICAgc2VydmVyX3dyaXRlX01BQ19rZXk6IGttLmdldEJ5dGVzKHNwLm1hY19rZXlfbGVuZ3RoKSwKICAgIGNsaWVudF93cml0ZV9rZXk6IGttLmdldEJ5dGVzKHNwLmVuY19rZXlfbGVuZ3RoKSwKICAgIHNlcnZlcl93cml0ZV9rZXk6IGttLmdldEJ5dGVzKHNwLmVuY19rZXlfbGVuZ3RoKQogIH07CgogIC8vIGluY2x1ZGUgVExTIDEuMCBJVnMKICBpZih0bHMxMCkgewogICAgcnZhbC5jbGllbnRfd3JpdGVfSVYgPSBrbS5nZXRCeXRlcyhzcC5maXhlZF9pdl9sZW5ndGgpOwogICAgcnZhbC5zZXJ2ZXJfd3JpdGVfSVYgPSBrbS5nZXRCeXRlcyhzcC5maXhlZF9pdl9sZW5ndGgpOwogIH0KCiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ3JlYXRlcyBhIG5ldyBpbml0aWFsaXplZCBUTFMgY29ubmVjdGlvbiBzdGF0ZS4gQSBjb25uZWN0aW9uIHN0YXRlIGhhcwogKiBhIHJlYWQgbW9kZSBhbmQgYSB3cml0ZSBtb2RlLgogKgogKiBjb21wcmVzc2lvbiBzdGF0ZToKICogICBUaGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgY29tcHJlc3Npb24gYWxnb3JpdGhtLgogKgogKiBjaXBoZXIgc3RhdGU6CiAqICAgVGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGVuY3J5cHRpb24gYWxnb3JpdGhtLiBUaGlzIHdpbGwgY29uc2lzdCBvZiB0aGUKICogICBzY2hlZHVsZWQga2V5IGZvciB0aGF0IGNvbm5lY3Rpb24uIEZvciBzdHJlYW0gY2lwaGVycywgdGhpcyB3aWxsIGFsc28KICogICBjb250YWluIHdoYXRldmVyIHN0YXRlIGluZm9ybWF0aW9uIGlzIG5lY2Vzc2FyeSB0byBhbGxvdyB0aGUgc3RyZWFtIHRvCiAqICAgY29udGludWUgdG8gZW5jcnlwdCBvciBkZWNyeXB0IGRhdGEuCiAqCiAqIE1BQyBrZXk6CiAqICAgVGhlIE1BQyBrZXkgZm9yIHRoZSBjb25uZWN0aW9uLgogKgogKiBzZXF1ZW5jZSBudW1iZXI6CiAqICAgRWFjaCBjb25uZWN0aW9uIHN0YXRlIGNvbnRhaW5zIGEgc2VxdWVuY2UgbnVtYmVyLCB3aGljaCBpcyBtYWludGFpbmVkCiAqICAgc2VwYXJhdGVseSBmb3IgcmVhZCBhbmQgd3JpdGUgc3RhdGVzLiBUaGUgc2VxdWVuY2UgbnVtYmVyIE1VU1QgYmUgc2V0IHRvCiAqICAgemVybyB3aGVuZXZlciBhIGNvbm5lY3Rpb24gc3RhdGUgaXMgbWFkZSB0aGUgYWN0aXZlIHN0YXRlLiBTZXF1ZW5jZQogKiAgIG51bWJlcnMgYXJlIG9mIHR5cGUgdWludDY0IGFuZCBtYXkgbm90IGV4Y2VlZCAyXjY0LTEuIFNlcXVlbmNlIG51bWJlcnMgZG8KICogICBub3Qgd3JhcC4gSWYgYSBUTFMgaW1wbGVtZW50YXRpb24gd291bGQgbmVlZCB0byB3cmFwIGEgc2VxdWVuY2UgbnVtYmVyLAogKiAgIGl0IG11c3QgcmVuZWdvdGlhdGUgaW5zdGVhZC4gQSBzZXF1ZW5jZSBudW1iZXIgaXMgaW5jcmVtZW50ZWQgYWZ0ZXIgZWFjaAogKiAgIHJlY29yZDogc3BlY2lmaWNhbGx5LCB0aGUgZmlyc3QgcmVjb3JkIHRyYW5zbWl0dGVkIHVuZGVyIGEgcGFydGljdWxhcgogKiAgIGNvbm5lY3Rpb24gc3RhdGUgTVVTVCB1c2Ugc2VxdWVuY2UgbnVtYmVyIDAuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBuZXcgaW5pdGlhbGl6ZWQgVExTIGNvbm5lY3Rpb24gc3RhdGUuCiAqLwp0bHMuY3JlYXRlQ29ubmVjdGlvblN0YXRlID0gZnVuY3Rpb24oYykgewogIHZhciBjbGllbnQgPSAoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCk7CgogIHZhciBjcmVhdGVNb2RlID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgbW9kZSA9IHsKICAgICAgLy8gdHdvIDMyLWJpdCBudW1iZXJzLCBmaXJzdCBpcyBtb3N0IHNpZ25pZmljYW50CiAgICAgIHNlcXVlbmNlTnVtYmVyOiBbMCwgMF0sCiAgICAgIG1hY0tleTogbnVsbCwKICAgICAgbWFjTGVuZ3RoOiAwLAogICAgICBtYWNGdW5jdGlvbjogbnVsbCwKICAgICAgY2lwaGVyU3RhdGU6IG51bGwsCiAgICAgIGNpcGhlckZ1bmN0aW9uOiBmdW5jdGlvbihyZWNvcmQpIHtyZXR1cm4gdHJ1ZTt9LAogICAgICBjb21wcmVzc2lvblN0YXRlOiBudWxsLAogICAgICBjb21wcmVzc0Z1bmN0aW9uOiBmdW5jdGlvbihyZWNvcmQpIHtyZXR1cm4gdHJ1ZTt9LAogICAgICB1cGRhdGVTZXF1ZW5jZU51bWJlcjogZnVuY3Rpb24oKSB7CiAgICAgICAgaWYobW9kZS5zZXF1ZW5jZU51bWJlclsxXSA9PT0gMHhGRkZGRkZGRikgewogICAgICAgICAgbW9kZS5zZXF1ZW5jZU51bWJlclsxXSA9IDA7CiAgICAgICAgICArK21vZGUuc2VxdWVuY2VOdW1iZXJbMF07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICsrbW9kZS5zZXF1ZW5jZU51bWJlclsxXTsKICAgICAgICB9CiAgICAgIH0KICAgIH07CiAgICByZXR1cm4gbW9kZTsKICB9OwogIHZhciBzdGF0ZSA9IHsKICAgIHJlYWQ6IGNyZWF0ZU1vZGUoKSwKICAgIHdyaXRlOiBjcmVhdGVNb2RlKCkKICB9OwoKICAvLyB1cGRhdGUgZnVuY3Rpb24gaW4gcmVhZCBtb2RlIHdpbGwgZGVjcnlwdCB0aGVuIGRlY29tcHJlc3MgYSByZWNvcmQKICBzdGF0ZS5yZWFkLnVwZGF0ZSA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogICAgaWYoIXN0YXRlLnJlYWQuY2lwaGVyRnVuY3Rpb24ocmVjb3JkLCBzdGF0ZS5yZWFkKSkgewogICAgICBjLmVycm9yKGMsIHsKICAgICAgICBtZXNzYWdlOiAnQ291bGQgbm90IGRlY3J5cHQgcmVjb3JkIG9yIGJhZCBNQUMuJywKICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgLy8gZG9lc24ndCBtYXR0ZXIgaWYgZGVjcnlwdGlvbiBmYWlsZWQgb3IgTUFDIHdhcwogICAgICAgICAgLy8gaW52YWxpZCwgcmV0dXJuIHRoZSBzYW1lIGVycm9yIHNvIGFzIG5vdCB0byByZXZlYWwKICAgICAgICAgIC8vIHdoaWNoIG9uZSBvY2N1cnJlZAogICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5iYWRfcmVjb3JkX21hYwogICAgICAgIH0KICAgICAgfSk7CiAgICB9IGVsc2UgaWYoIXN0YXRlLnJlYWQuY29tcHJlc3NGdW5jdGlvbihjLCByZWNvcmQsIHN0YXRlLnJlYWQpKSB7CiAgICAgIGMuZXJyb3IoYywgewogICAgICAgIG1lc3NhZ2U6ICdDb3VsZCBub3QgZGVjb21wcmVzcyByZWNvcmQuJywKICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5kZWNvbXByZXNzaW9uX2ZhaWx1cmUKICAgICAgICB9CiAgICAgIH0pOwogICAgfQogICAgcmV0dXJuICFjLmZhaWw7CiAgfTsKCiAgLy8gdXBkYXRlIGZ1bmN0aW9uIGluIHdyaXRlIG1vZGUgd2lsbCBjb21wcmVzcyB0aGVuIGVuY3J5cHQgYSByZWNvcmQKICBzdGF0ZS53cml0ZS51cGRhdGUgPSBmdW5jdGlvbihjLCByZWNvcmQpIHsKICAgIGlmKCFzdGF0ZS53cml0ZS5jb21wcmVzc0Z1bmN0aW9uKGMsIHJlY29yZCwgc3RhdGUud3JpdGUpKSB7CiAgICAgIC8vIGVycm9yLCBidXQgZG8gbm90IHNlbmQgYWxlcnQgc2luY2UgaXQgd291bGQgcmVxdWlyZQogICAgICAvLyBjb21wcmVzc2lvbiBhcyB3ZWxsCiAgICAgIGMuZXJyb3IoYywgewogICAgICAgIG1lc3NhZ2U6ICdDb3VsZCBub3QgY29tcHJlc3MgcmVjb3JkLicsCiAgICAgICAgc2VuZDogZmFsc2UsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgfQogICAgICB9KTsKICAgIH0gZWxzZSBpZighc3RhdGUud3JpdGUuY2lwaGVyRnVuY3Rpb24ocmVjb3JkLCBzdGF0ZS53cml0ZSkpIHsKICAgICAgLy8gZXJyb3IsIGJ1dCBkbyBub3Qgc2VuZCBhbGVydCBzaW5jZSBpdCB3b3VsZCByZXF1aXJlCiAgICAgIC8vIGVuY3J5cHRpb24gYXMgd2VsbAogICAgICBjLmVycm9yKGMsIHsKICAgICAgICBtZXNzYWdlOiAnQ291bGQgbm90IGVuY3J5cHQgcmVjb3JkLicsCiAgICAgICAgc2VuZDogZmFsc2UsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgfQogICAgICB9KTsKICAgIH0KICAgIHJldHVybiAhYy5mYWlsOwogIH07CgogIC8vIGhhbmRsZSBzZWN1cml0eSBwYXJhbWV0ZXJzCiAgaWYoYy5zZXNzaW9uKSB7CiAgICB2YXIgc3AgPSBjLnNlc3Npb24uc3A7CiAgICBjLnNlc3Npb24uY2lwaGVyU3VpdGUuaW5pdFNlY3VyaXR5UGFyYW1ldGVycyhzcCk7CgogICAgLy8gZ2VuZXJhdGUga2V5cwogICAgc3Aua2V5cyA9IHRscy5nZW5lcmF0ZUtleXMoYywgc3ApOwogICAgc3RhdGUucmVhZC5tYWNLZXkgPSBjbGllbnQgPwogICAgICBzcC5rZXlzLnNlcnZlcl93cml0ZV9NQUNfa2V5IDogc3Aua2V5cy5jbGllbnRfd3JpdGVfTUFDX2tleTsKICAgIHN0YXRlLndyaXRlLm1hY0tleSA9IGNsaWVudCA/CiAgICAgIHNwLmtleXMuY2xpZW50X3dyaXRlX01BQ19rZXkgOiBzcC5rZXlzLnNlcnZlcl93cml0ZV9NQUNfa2V5OwoKICAgIC8vIGNpcGhlciBzdWl0ZSBzZXR1cAogICAgYy5zZXNzaW9uLmNpcGhlclN1aXRlLmluaXRDb25uZWN0aW9uU3RhdGUoc3RhdGUsIGMsIHNwKTsKCiAgICAvLyBjb21wcmVzc2lvbiBzZXR1cAogICAgc3dpdGNoKHNwLmNvbXByZXNzaW9uX2FsZ29yaXRobSkgewogICAgY2FzZSB0bHMuQ29tcHJlc3Npb25NZXRob2Qubm9uZToKICAgICAgYnJlYWs7CiAgICBjYXNlIHRscy5Db21wcmVzc2lvbk1ldGhvZC5kZWZsYXRlOgogICAgICBzdGF0ZS5yZWFkLmNvbXByZXNzRnVuY3Rpb24gPSBpbmZsYXRlOwogICAgICBzdGF0ZS53cml0ZS5jb21wcmVzc0Z1bmN0aW9uID0gZGVmbGF0ZTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGNvbXByZXNzaW9uIGFsZ29yaXRobS4nKTsKICAgIH0KICB9CgogIHJldHVybiBzdGF0ZTsKfTsKCi8qKgogKiBDcmVhdGVzIGEgUmFuZG9tIHN0cnVjdHVyZS4KICoKICogc3RydWN0IHsKICogICB1aW50MzIgZ210X3VuaXhfdGltZTsKICogICBvcGFxdWUgcmFuZG9tX2J5dGVzWzI4XTsKICogfSBSYW5kb207CiAqCiAqIGdtdF91bml4X3RpbWU6CiAqICAgVGhlIGN1cnJlbnQgdGltZSBhbmQgZGF0ZSBpbiBzdGFuZGFyZCBVTklYIDMyLWJpdCBmb3JtYXQgKHNlY29uZHMgc2luY2UKICogICB0aGUgbWlkbmlnaHQgc3RhcnRpbmcgSmFuIDEsIDE5NzAsIFVUQywgaWdub3JpbmcgbGVhcCBzZWNvbmRzKSBhY2NvcmRpbmcKICogICB0byB0aGUgc2VuZGVyJ3MgaW50ZXJuYWwgY2xvY2suIENsb2NrcyBhcmUgbm90IHJlcXVpcmVkIHRvIGJlIHNldAogKiAgIGNvcnJlY3RseSBieSB0aGUgYmFzaWMgVExTIHByb3RvY29sOyBoaWdoZXItbGV2ZWwgb3IgYXBwbGljYXRpb24KICogICBwcm90b2NvbHMgbWF5IGRlZmluZSBhZGRpdGlvbmFsIHJlcXVpcmVtZW50cy4gTm90ZSB0aGF0LCBmb3IgaGlzdG9yaWNhbAogKiAgIHJlYXNvbnMsIHRoZSBkYXRhIGVsZW1lbnQgaXMgbmFtZWQgdXNpbmcgR01ULCB0aGUgcHJlZGVjZXNzb3Igb2YgdGhlCiAqICAgY3VycmVudCB3b3JsZHdpZGUgdGltZSBiYXNlLCBVVEMuCiAqIHJhbmRvbV9ieXRlczoKICogICAyOCBieXRlcyBnZW5lcmF0ZWQgYnkgYSBzZWN1cmUgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IuCiAqCiAqIEByZXR1cm4gdGhlIFJhbmRvbSBzdHJ1Y3R1cmUgYXMgYSBieXRlIGFycmF5LgogKi8KdGxzLmNyZWF0ZVJhbmRvbSA9IGZ1bmN0aW9uKCkgewogIC8vIGdldCBVVEMgbWlsbGlzZWNvbmRzCiAgdmFyIGQgPSBuZXcgRGF0ZSgpOwogIHZhciB1dGMgPSArZCArIGQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwMDAwOwogIHZhciBydmFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBydmFsLnB1dEludDMyKHV0Yyk7CiAgcnZhbC5wdXRCeXRlcyhmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMoMjgpKTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDcmVhdGVzIGEgVExTIHJlY29yZCB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZCBkYXRhLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIG9wdGlvbnM6CiAqICAgdHlwZTogdGhlIHJlY29yZCB0eXBlLgogKiAgIGRhdGE6IHRoZSBwbGFpbiB0ZXh0IGRhdGEgaW4gYSBieXRlIGJ1ZmZlci4KICoKICogQHJldHVybiB0aGUgY3JlYXRlZCByZWNvcmQuCiAqLwp0bHMuY3JlYXRlUmVjb3JkID0gZnVuY3Rpb24oYywgb3B0aW9ucykgewogIGlmKCFvcHRpb25zLmRhdGEpIHsKICAgIHJldHVybiBudWxsOwogIH0KICB2YXIgcmVjb3JkID0gewogICAgdHlwZTogb3B0aW9ucy50eXBlLAogICAgdmVyc2lvbjogewogICAgICBtYWpvcjogYy52ZXJzaW9uLm1ham9yLAogICAgICBtaW5vcjogYy52ZXJzaW9uLm1pbm9yCiAgICB9LAogICAgbGVuZ3RoOiBvcHRpb25zLmRhdGEubGVuZ3RoKCksCiAgICBmcmFnbWVudDogb3B0aW9ucy5kYXRhCiAgfTsKICByZXR1cm4gcmVjb3JkOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBUTFMgYWxlcnQgcmVjb3JkLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIGFsZXJ0OgogKiAgIGxldmVsOiB0aGUgVExTIGFsZXJ0IGxldmVsLgogKiAgIGRlc2NyaXB0aW9uOiB0aGUgVExTIGFsZXJ0IGRlc2NyaXB0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBjcmVhdGVkIGFsZXJ0IHJlY29yZC4KICovCnRscy5jcmVhdGVBbGVydCA9IGZ1bmN0aW9uKGMsIGFsZXJ0KSB7CiAgdmFyIGIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIGIucHV0Qnl0ZShhbGVydC5sZXZlbCk7CiAgYi5wdXRCeXRlKGFsZXJ0LmRlc2NyaXB0aW9uKTsKICByZXR1cm4gdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuYWxlcnQsCiAgICBkYXRhOiBiCiAgfSk7Cn07CgovKiBUaGUgc3RydWN0dXJlIG9mIGEgVExTIGhhbmRzaGFrZSBtZXNzYWdlLgogKgogKiBzdHJ1Y3QgewogKiAgICBIYW5kc2hha2VUeXBlIG1zZ190eXBlOyAgICAvLyBoYW5kc2hha2UgdHlwZQogKiAgICB1aW50MjQgbGVuZ3RoOyAgICAgICAgICAgICAvLyBieXRlcyBpbiBtZXNzYWdlCiAqICAgIHNlbGVjdChIYW5kc2hha2VUeXBlKSB7CiAqICAgICAgIGNhc2UgaGVsbG9fcmVxdWVzdDogICAgICAgSGVsbG9SZXF1ZXN0OwogKiAgICAgICBjYXNlIGNsaWVudF9oZWxsbzogICAgICAgIENsaWVudEhlbGxvOwogKiAgICAgICBjYXNlIHNlcnZlcl9oZWxsbzogICAgICAgIFNlcnZlckhlbGxvOwogKiAgICAgICBjYXNlIGNlcnRpZmljYXRlOiAgICAgICAgIENlcnRpZmljYXRlOwogKiAgICAgICBjYXNlIHNlcnZlcl9rZXlfZXhjaGFuZ2U6IFNlcnZlcktleUV4Y2hhbmdlOwogKiAgICAgICBjYXNlIGNlcnRpZmljYXRlX3JlcXVlc3Q6IENlcnRpZmljYXRlUmVxdWVzdDsKICogICAgICAgY2FzZSBzZXJ2ZXJfaGVsbG9fZG9uZTogICBTZXJ2ZXJIZWxsb0RvbmU7CiAqICAgICAgIGNhc2UgY2VydGlmaWNhdGVfdmVyaWZ5OiAgQ2VydGlmaWNhdGVWZXJpZnk7CiAqICAgICAgIGNhc2UgY2xpZW50X2tleV9leGNoYW5nZTogQ2xpZW50S2V5RXhjaGFuZ2U7CiAqICAgICAgIGNhc2UgZmluaXNoZWQ6ICAgICAgICAgICAgRmluaXNoZWQ7CiAqICAgIH0gYm9keTsKICogfSBIYW5kc2hha2U7CiAqLwoKLyoqCiAqIENyZWF0ZXMgYSBDbGllbnRIZWxsbyBtZXNzYWdlLgogKgogKiBvcGFxdWUgU2Vzc2lvbklEPDAuLjMyPjsKICogZW51bSB7IG51bGwoMCksIGRlZmxhdGUoMSksICgyNTUpIH0gQ29tcHJlc3Npb25NZXRob2Q7CiAqIHVpbnQ4IENpcGhlclN1aXRlWzJdOwogKgogKiBzdHJ1Y3QgewogKiAgIFByb3RvY29sVmVyc2lvbiBjbGllbnRfdmVyc2lvbjsKICogICBSYW5kb20gcmFuZG9tOwogKiAgIFNlc3Npb25JRCBzZXNzaW9uX2lkOwogKiAgIENpcGhlclN1aXRlIGNpcGhlcl9zdWl0ZXM8Mi4uMl4xNi0yPjsKICogICBDb21wcmVzc2lvbk1ldGhvZCBjb21wcmVzc2lvbl9tZXRob2RzPDEuLjJeOC0xPjsKICogICBzZWxlY3QoZXh0ZW5zaW9uc19wcmVzZW50KSB7CiAqICAgICBjYXNlIGZhbHNlOgogKiAgICAgICBzdHJ1Y3Qge307CiAqICAgICBjYXNlIHRydWU6CiAqICAgICAgIEV4dGVuc2lvbiBleHRlbnNpb25zPDAuLjJeMTYtMT47CiAqICAgfTsKICogfSBDbGllbnRIZWxsbzsKICoKICogVGhlIGV4dGVuc2lvbiBmb3JtYXQgZm9yIGV4dGVuZGVkIGNsaWVudCBoZWxsb3MgYW5kIHNlcnZlciBoZWxsb3MgaXM6CiAqCiAqIHN0cnVjdCB7CiAqICAgRXh0ZW5zaW9uVHlwZSBleHRlbnNpb25fdHlwZTsKICogICBvcGFxdWUgZXh0ZW5zaW9uX2RhdGE8MC4uMl4xNi0xPjsKICogfSBFeHRlbnNpb247CiAqCiAqIEhlcmU6CiAqCiAqIC0gImV4dGVuc2lvbl90eXBlIiBpZGVudGlmaWVzIHRoZSBwYXJ0aWN1bGFyIGV4dGVuc2lvbiB0eXBlLgogKiAtICJleHRlbnNpb25fZGF0YSIgY29udGFpbnMgaW5mb3JtYXRpb24gc3BlY2lmaWMgdG8gdGhlIHBhcnRpY3VsYXIKICogZXh0ZW5zaW9uIHR5cGUuCiAqCiAqIFRoZSBleHRlbnNpb24gdHlwZXMgZGVmaW5lZCBpbiB0aGlzIGRvY3VtZW50IGFyZToKICoKICogZW51bSB7CiAqICAgc2VydmVyX25hbWUoMCksIG1heF9mcmFnbWVudF9sZW5ndGgoMSksCiAqICAgY2xpZW50X2NlcnRpZmljYXRlX3VybCgyKSwgdHJ1c3RlZF9jYV9rZXlzKDMpLAogKiAgIHRydW5jYXRlZF9obWFjKDQpLCBzdGF0dXNfcmVxdWVzdCg1KSwgKDY1NTM1KQogKiB9IEV4dGVuc2lvblR5cGU7CiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBDbGllbnRIZWxsbyBieXRlIGJ1ZmZlci4KICovCnRscy5jcmVhdGVDbGllbnRIZWxsbyA9IGZ1bmN0aW9uKGMpIHsKICAvLyBzYXZlIGhlbGxvIHZlcnNpb24KICBjLnNlc3Npb24uY2xpZW50SGVsbG9WZXJzaW9uID0gewogICAgbWFqb3I6IGMudmVyc2lvbi5tYWpvciwKICAgIG1pbm9yOiBjLnZlcnNpb24ubWlub3IKICB9OwoKICAvLyBjcmVhdGUgc3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMKICB2YXIgY2lwaGVyU3VpdGVzID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBmb3IodmFyIGkgPSAwOyBpIDwgYy5jaXBoZXJTdWl0ZXMubGVuZ3RoOyArK2kpIHsKICAgIHZhciBjcyA9IGMuY2lwaGVyU3VpdGVzW2ldOwogICAgY2lwaGVyU3VpdGVzLnB1dEJ5dGUoY3MuaWRbMF0pOwogICAgY2lwaGVyU3VpdGVzLnB1dEJ5dGUoY3MuaWRbMV0pOwogIH0KICB2YXIgY1N1aXRlcyA9IGNpcGhlclN1aXRlcy5sZW5ndGgoKTsKCiAgLy8gY3JlYXRlIHN1cHBvcnRlZCBjb21wcmVzc2lvbiBtZXRob2RzLCBudWxsIGFsd2F5cyBzdXBwb3J0ZWQsIGJ1dAogIC8vIGFsc28gc3VwcG9ydCBkZWZsYXRlIGlmIGNvbm5lY3Rpb24gaGFzIGluZmxhdGUgYW5kIGRlZmxhdGUgbWV0aG9kcwogIHZhciBjb21wcmVzc2lvbk1ldGhvZHMgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIGNvbXByZXNzaW9uTWV0aG9kcy5wdXRCeXRlKHRscy5Db21wcmVzc2lvbk1ldGhvZC5ub25lKTsKICAvLyBGSVhNRTogZGVmbGF0ZSBzdXBwb3J0IGRpc2FibGVkIHVudGlsIGlzc3VlcyB3aXRoIHJhdyBkZWZsYXRlIGRhdGEKICAvLyB3aXRob3V0IHpsaWIgaGVhZGVycyBhcmUgcmVzb2x2ZWQKICAvKgogIGlmKGMuaW5mbGF0ZSAhPT0gbnVsbCAmJiBjLmRlZmxhdGUgIT09IG51bGwpIHsKICAgIGNvbXByZXNzaW9uTWV0aG9kcy5wdXRCeXRlKHRscy5Db21wcmVzc2lvbk1ldGhvZC5kZWZsYXRlKTsKICB9CiAgKi8KICB2YXIgY01ldGhvZHMgPSBjb21wcmVzc2lvbk1ldGhvZHMubGVuZ3RoKCk7CgogIC8vIGNyZWF0ZSBUTFMgU05JIChzZXJ2ZXIgbmFtZSBpbmRpY2F0aW9uKSBleHRlbnNpb24gaWYgdmlydHVhbCBob3N0CiAgLy8gaGFzIGJlZW4gc3BlY2lmaWVkLCBzZWUgUkZDIDM1NDYKICB2YXIgZXh0ZW5zaW9ucyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgaWYoYy52aXJ0dWFsSG9zdCkgewogICAgLy8gY3JlYXRlIGV4dGVuc2lvbiBzdHJ1Y3QKICAgIHZhciBleHQgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgZXh0LnB1dEJ5dGUoMHgwMCk7IC8vIHR5cGUgc2VydmVyX25hbWUgKEV4dGVuc2lvblR5cGUgaXMgMiBieXRlcykKICAgIGV4dC5wdXRCeXRlKDB4MDApOwoKICAgIC8qIEluIG9yZGVyIHRvIHByb3ZpZGUgdGhlIHNlcnZlciBuYW1lLCBjbGllbnRzIE1BWSBpbmNsdWRlIGFuCiAgICAgKiBleHRlbnNpb24gb2YgdHlwZSAic2VydmVyX25hbWUiIGluIHRoZSAoZXh0ZW5kZWQpIGNsaWVudCBoZWxsby4KICAgICAqIFRoZSAiZXh0ZW5zaW9uX2RhdGEiIGZpZWxkIG9mIHRoaXMgZXh0ZW5zaW9uIFNIQUxMIGNvbnRhaW4KICAgICAqICJTZXJ2ZXJOYW1lTGlzdCIgd2hlcmU6CiAgICAgKgogICAgICogc3RydWN0IHsKICAgICAqICAgTmFtZVR5cGUgbmFtZV90eXBlOwogICAgICogICBzZWxlY3QobmFtZV90eXBlKSB7CiAgICAgKiAgICAgY2FzZSBob3N0X25hbWU6IEhvc3ROYW1lOwogICAgICogICB9IG5hbWU7CiAgICAgKiB9IFNlcnZlck5hbWU7CiAgICAgKgogICAgICogZW51bSB7CiAgICAgKiAgIGhvc3RfbmFtZSgwKSwgKDI1NSkKICAgICAqIH0gTmFtZVR5cGU7CiAgICAgKgogICAgICogb3BhcXVlIEhvc3ROYW1lPDEuLjJeMTYtMT47CiAgICAgKgogICAgICogc3RydWN0IHsKICAgICAqICAgU2VydmVyTmFtZSBzZXJ2ZXJfbmFtZV9saXN0PDEuLjJeMTYtMT4KICAgICAqIH0gU2VydmVyTmFtZUxpc3Q7CiAgICAgKi8KICAgIHZhciBzZXJ2ZXJOYW1lID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICAgIHNlcnZlck5hbWUucHV0Qnl0ZSgweDAwKTsgLy8gdHlwZSBob3N0X25hbWUKICAgIHdyaXRlVmVjdG9yKHNlcnZlck5hbWUsIDIsIGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGMudmlydHVhbEhvc3QpKTsKCiAgICAvLyBTZXJ2ZXJOYW1lTGlzdCBpcyBpbiBleHRlbnNpb25fZGF0YQogICAgdmFyIHNuTGlzdCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICB3cml0ZVZlY3Rvcihzbkxpc3QsIDIsIHNlcnZlck5hbWUpOwogICAgd3JpdGVWZWN0b3IoZXh0LCAyLCBzbkxpc3QpOwogICAgZXh0ZW5zaW9ucy5wdXRCdWZmZXIoZXh0KTsKICB9CiAgdmFyIGV4dExlbmd0aCA9IGV4dGVuc2lvbnMubGVuZ3RoKCk7CiAgaWYoZXh0TGVuZ3RoID4gMCkgewogICAgLy8gYWRkIGV4dGVuc2lvbiB2ZWN0b3IgbGVuZ3RoCiAgICBleHRMZW5ndGggKz0gMjsKICB9CgogIC8vIGRldGVybWluZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlCiAgLy8gY2lwaGVyIHN1aXRlcyBhbmQgY29tcHJlc3Npb24gbWV0aG9kcyBzaXplIHdpbGwgbmVlZCB0byBiZQogIC8vIHVwZGF0ZWQgaWYgbW9yZSBnZXQgYWRkZWQgdG8gdGhlIGxpc3QKICB2YXIgc2Vzc2lvbklkID0gYy5zZXNzaW9uLmlkOwogIHZhciBsZW5ndGggPQogICAgc2Vzc2lvbklkLmxlbmd0aCArIDEgKyAvLyBzZXNzaW9uIElEIHZlY3RvcgogICAgMiArICAgICAgICAgICAgICAgICAgICAvLyB2ZXJzaW9uIChtYWpvciArIG1pbm9yKQogICAgNCArIDI4ICsgICAgICAgICAgICAgICAvLyByYW5kb20gdGltZSBhbmQgcmFuZG9tIGJ5dGVzCiAgICAyICsgY1N1aXRlcyArICAgICAgICAgIC8vIGNpcGhlciBzdWl0ZXMgdmVjdG9yCiAgICAxICsgY01ldGhvZHMgKyAgICAgICAgIC8vIGNvbXByZXNzaW9uIG1ldGhvZHMgdmVjdG9yCiAgICBleHRMZW5ndGg7ICAgICAgICAgICAgIC8vIGV4dGVuc2lvbnMgdmVjdG9yCgogIC8vIGJ1aWxkIHJlY29yZCBmcmFnbWVudAogIHZhciBydmFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBydmFsLnB1dEJ5dGUodGxzLkhhbmRzaGFrZVR5cGUuY2xpZW50X2hlbGxvKTsKICBydmFsLnB1dEludDI0KGxlbmd0aCk7ICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZHNoYWtlIGxlbmd0aAogIHJ2YWwucHV0Qnl0ZShjLnZlcnNpb24ubWFqb3IpOyAgICAgICAgICAgICAvLyBtYWpvciB2ZXJzaW9uCiAgcnZhbC5wdXRCeXRlKGMudmVyc2lvbi5taW5vcik7ICAgICAgICAgICAgIC8vIG1pbm9yIHZlcnNpb24KICBydmFsLnB1dEJ5dGVzKGMuc2Vzc2lvbi5zcC5jbGllbnRfcmFuZG9tKTsgLy8gcmFuZG9tIHRpbWUgKyBieXRlcwogIHdyaXRlVmVjdG9yKHJ2YWwsIDEsIGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKHNlc3Npb25JZCkpOwogIHdyaXRlVmVjdG9yKHJ2YWwsIDIsIGNpcGhlclN1aXRlcyk7CiAgd3JpdGVWZWN0b3IocnZhbCwgMSwgY29tcHJlc3Npb25NZXRob2RzKTsKICBpZihleHRMZW5ndGggPiAwKSB7CiAgICB3cml0ZVZlY3RvcihydmFsLCAyLCBleHRlbnNpb25zKTsKICB9CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ3JlYXRlcyBhIFNlcnZlckhlbGxvIG1lc3NhZ2UuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKgogKiBAcmV0dXJuIHRoZSBTZXJ2ZXJIZWxsbyBieXRlIGJ1ZmZlci4KICovCnRscy5jcmVhdGVTZXJ2ZXJIZWxsbyA9IGZ1bmN0aW9uKGMpIHsKICAvLyBkZXRlcm1pbmUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZQogIHZhciBzZXNzaW9uSWQgPSBjLnNlc3Npb24uaWQ7CiAgdmFyIGxlbmd0aCA9CiAgICBzZXNzaW9uSWQubGVuZ3RoICsgMSArIC8vIHNlc3Npb24gSUQgdmVjdG9yCiAgICAyICsgICAgICAgICAgICAgICAgICAgIC8vIHZlcnNpb24gKG1ham9yICsgbWlub3IpCiAgICA0ICsgMjggKyAgICAgICAgICAgICAgIC8vIHJhbmRvbSB0aW1lIGFuZCByYW5kb20gYnl0ZXMKICAgIDIgKyAgICAgICAgICAgICAgICAgICAgLy8gY2hvc2VuIGNpcGhlciBzdWl0ZQogICAgMTsgICAgICAgICAgICAgICAgICAgICAvLyBjaG9zZW4gY29tcHJlc3Npb24gbWV0aG9kCgogIC8vIGJ1aWxkIHJlY29yZCBmcmFnbWVudAogIHZhciBydmFsID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBydmFsLnB1dEJ5dGUodGxzLkhhbmRzaGFrZVR5cGUuc2VydmVyX2hlbGxvKTsKICBydmFsLnB1dEludDI0KGxlbmd0aCk7ICAgICAgICAgICAgICAgICAgICAgLy8gaGFuZHNoYWtlIGxlbmd0aAogIHJ2YWwucHV0Qnl0ZShjLnZlcnNpb24ubWFqb3IpOyAgICAgICAgICAgICAvLyBtYWpvciB2ZXJzaW9uCiAgcnZhbC5wdXRCeXRlKGMudmVyc2lvbi5taW5vcik7ICAgICAgICAgICAgIC8vIG1pbm9yIHZlcnNpb24KICBydmFsLnB1dEJ5dGVzKGMuc2Vzc2lvbi5zcC5zZXJ2ZXJfcmFuZG9tKTsgLy8gcmFuZG9tIHRpbWUgKyBieXRlcwogIHdyaXRlVmVjdG9yKHJ2YWwsIDEsIGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKHNlc3Npb25JZCkpOwogIHJ2YWwucHV0Qnl0ZShjLnNlc3Npb24uY2lwaGVyU3VpdGUuaWRbMF0pOwogIHJ2YWwucHV0Qnl0ZShjLnNlc3Npb24uY2lwaGVyU3VpdGUuaWRbMV0pOwogIHJ2YWwucHV0Qnl0ZShjLnNlc3Npb24uY29tcHJlc3Npb25NZXRob2QpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBDZXJ0aWZpY2F0ZSBtZXNzYWdlLgogKgogKiBXaGVuIHRoaXMgbWVzc2FnZSB3aWxsIGJlIHNlbnQ6CiAqICAgVGhpcyBpcyB0aGUgZmlyc3QgbWVzc2FnZSB0aGUgY2xpZW50IGNhbiBzZW5kIGFmdGVyIHJlY2VpdmluZyBhIHNlcnZlcgogKiAgIGhlbGxvIGRvbmUgbWVzc2FnZSBhbmQgdGhlIGZpcnN0IG1lc3NhZ2UgdGhlIHNlcnZlciBjYW4gc2VuZCBhZnRlcgogKiAgIHNlbmRpbmcgYSBTZXJ2ZXJIZWxsby4gVGhpcyBjbGllbnQgbWVzc2FnZSBpcyBvbmx5IHNlbnQgaWYgdGhlIHNlcnZlcgogKiAgIHJlcXVlc3RzIGEgY2VydGlmaWNhdGUuIElmIG5vIHN1aXRhYmxlIGNlcnRpZmljYXRlIGlzIGF2YWlsYWJsZSwgdGhlCiAqICAgY2xpZW50IHNob3VsZCBzZW5kIGEgY2VydGlmaWNhdGUgbWVzc2FnZSBjb250YWluaW5nIG5vIGNlcnRpZmljYXRlcy4gSWYKICogICBjbGllbnQgYXV0aGVudGljYXRpb24gaXMgcmVxdWlyZWQgYnkgdGhlIHNlcnZlciBmb3IgdGhlIGhhbmRzaGFrZSB0bwogKiAgIGNvbnRpbnVlLCBpdCBtYXkgcmVzcG9uZCB3aXRoIGEgZmF0YWwgaGFuZHNoYWtlIGZhaWx1cmUgYWxlcnQuCiAqCiAqIG9wYXF1ZSBBU04uMUNlcnQ8MS4uMl4yNC0xPjsKICoKICogc3RydWN0IHsKICogICBBU04uMUNlcnQgY2VydGlmaWNhdGVfbGlzdDwwLi4yXjI0LTE+OwogKiB9IENlcnRpZmljYXRlOwogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgQ2VydGlmaWNhdGUgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlQ2VydGlmaWNhdGUgPSBmdW5jdGlvbihjKSB7CiAgLy8gVE9ETzogY2hlY2sgY2VydGlmaWNhdGUgcmVxdWVzdCB0byBlbnN1cmUgdHlwZXMgYXJlIHN1cHBvcnRlZAoKICAvLyBnZXQgYSBjZXJ0aWZpY2F0ZSAoYSBjZXJ0aWZpY2F0ZSBhcyBhIFBFTSBzdHJpbmcpCiAgdmFyIGNsaWVudCA9IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KTsKICB2YXIgY2VydCA9IG51bGw7CiAgaWYoYy5nZXRDZXJ0aWZpY2F0ZSkgewogICAgdmFyIGhpbnQ7CiAgICBpZihjbGllbnQpIHsKICAgICAgaGludCA9IGMuc2Vzc2lvbi5jZXJ0aWZpY2F0ZVJlcXVlc3Q7CiAgICB9IGVsc2UgewogICAgICBoaW50ID0gYy5zZXNzaW9uLmV4dGVuc2lvbnMuc2VydmVyX25hbWUuc2VydmVyTmFtZUxpc3Q7CiAgICB9CiAgICBjZXJ0ID0gYy5nZXRDZXJ0aWZpY2F0ZShjLCBoaW50KTsKICB9CgogIC8vIGJ1ZmZlciB0byBob2xkIGNlcnRpZmljYXRlIGxpc3QKICB2YXIgY2VydExpc3QgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIGlmKGNlcnQgIT09IG51bGwpIHsKICAgIHRyeSB7CiAgICAgIC8vIG5vcm1hbGl6ZSBjZXJ0IHRvIGEgY2hhaW4gb2YgY2VydGlmaWNhdGVzCiAgICAgIGlmKCFmb3JnZS51dGlsLmlzQXJyYXkoY2VydCkpIHsKICAgICAgICBjZXJ0ID0gW2NlcnRdOwogICAgICB9CiAgICAgIHZhciBhc24xID0gbnVsbDsKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IGNlcnQubGVuZ3RoOyArK2kpIHsKICAgICAgICB2YXIgbXNnID0gZm9yZ2UucGVtLmRlY29kZShjZXJ0W2ldKVswXTsKICAgICAgICBpZihtc2cudHlwZSAhPT0gJ0NFUlRJRklDQVRFJyAmJgogICAgICAgICAgbXNnLnR5cGUgIT09ICdYNTA5IENFUlRJRklDQVRFJyAmJgogICAgICAgICAgbXNnLnR5cGUgIT09ICdUUlVTVEVEIENFUlRJRklDQVRFJykgewogICAgICAgICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDb3VsZCBub3QgY29udmVydCBjZXJ0aWZpY2F0ZSBmcm9tIFBFTTsgUEVNICcgKwogICAgICAgICAgICAnaGVhZGVyIHR5cGUgaXMgbm90ICJDRVJUSUZJQ0FURSIsICJYNTA5IENFUlRJRklDQVRFIiwgb3IgJyArCiAgICAgICAgICAgICciVFJVU1RFRCBDRVJUSUZJQ0FURSIuJyk7CiAgICAgICAgICBlcnJvci5oZWFkZXJUeXBlID0gbXNnLnR5cGU7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CiAgICAgICAgaWYobXNnLnByb2NUeXBlICYmIG1zZy5wcm9jVHlwZS50eXBlID09PSAnRU5DUllQVEVEJykgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgY29udmVydCBjZXJ0aWZpY2F0ZSBmcm9tIFBFTTsgUEVNIGlzIGVuY3J5cHRlZC4nKTsKICAgICAgICB9CgogICAgICAgIHZhciBkZXIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihtc2cuYm9keSk7CiAgICAgICAgaWYoYXNuMSA9PT0gbnVsbCkgewogICAgICAgICAgYXNuMSA9IGZvcmdlLmFzbjEuZnJvbURlcihkZXIuYnl0ZXMoKSwgZmFsc2UpOwogICAgICAgIH0KCiAgICAgICAgLy8gY2VydGlmaWNhdGUgZW50cnkgaXMgaXRzZWxmIGEgdmVjdG9yIHdpdGggMyBsZW5ndGggYnl0ZXMKICAgICAgICB2YXIgY2VydEJ1ZmZlciA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgICAgICAgd3JpdGVWZWN0b3IoY2VydEJ1ZmZlciwgMywgZGVyKTsKCiAgICAgICAgLy8gYWRkIGNlcnQgdmVjdG9yIHRvIGNlcnQgbGlzdCB2ZWN0b3IKICAgICAgICBjZXJ0TGlzdC5wdXRCdWZmZXIoY2VydEJ1ZmZlcik7CiAgICAgIH0KCiAgICAgIC8vIHNhdmUgY2VydGlmaWNhdGUKICAgICAgY2VydCA9IGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUZyb21Bc24xKGFzbjEpOwogICAgICBpZihjbGllbnQpIHsKICAgICAgICBjLnNlc3Npb24uY2xpZW50Q2VydGlmaWNhdGUgPSBjZXJ0OwogICAgICB9IGVsc2UgewogICAgICAgIGMuc2Vzc2lvbi5zZXJ2ZXJDZXJ0aWZpY2F0ZSA9IGNlcnQ7CiAgICAgIH0KICAgIH0gY2F0Y2goZXgpIHsKICAgICAgcmV0dXJuIGMuZXJyb3IoYywgewogICAgICAgIG1lc3NhZ2U6ICdDb3VsZCBub3Qgc2VuZCBjZXJ0aWZpY2F0ZSBsaXN0LicsCiAgICAgICAgY2F1c2U6IGV4LAogICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmJhZF9jZXJ0aWZpY2F0ZQogICAgICAgIH0KICAgICAgfSk7CiAgICB9CiAgfQoKICAvLyBkZXRlcm1pbmUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZQogIHZhciBsZW5ndGggPSAzICsgY2VydExpc3QubGVuZ3RoKCk7IC8vIGNlcnQgbGlzdCB2ZWN0b3IKCiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5jZXJ0aWZpY2F0ZSk7CiAgcnZhbC5wdXRJbnQyNChsZW5ndGgpOwogIHdyaXRlVmVjdG9yKHJ2YWwsIDMsIGNlcnRMaXN0KTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDcmVhdGVzIGEgQ2xpZW50S2V5RXhjaGFuZ2UgbWVzc2FnZS4KICoKICogV2hlbiB0aGlzIG1lc3NhZ2Ugd2lsbCBiZSBzZW50OgogKiAgIFRoaXMgbWVzc2FnZSBpcyBhbHdheXMgc2VudCBieSB0aGUgY2xpZW50LiBJdCB3aWxsIGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUKICogICBjbGllbnQgY2VydGlmaWNhdGUgbWVzc2FnZSwgaWYgaXQgaXMgc2VudC4gT3RoZXJ3aXNlIGl0IHdpbGwgYmUgdGhlIGZpcnN0CiAqICAgbWVzc2FnZSBzZW50IGJ5IHRoZSBjbGllbnQgYWZ0ZXIgaXQgcmVjZWl2ZXMgdGhlIHNlcnZlciBoZWxsbyBkb25lCiAqICAgbWVzc2FnZS4KICoKICogTWVhbmluZyBvZiB0aGlzIG1lc3NhZ2U6CiAqICAgV2l0aCB0aGlzIG1lc3NhZ2UsIHRoZSBwcmVtYXN0ZXIgc2VjcmV0IGlzIHNldCwgZWl0aGVyIHRob3VnaCBkaXJlY3QKICogICB0cmFuc21pc3Npb24gb2YgdGhlIFJTQS1lbmNyeXB0ZWQgc2VjcmV0LCBvciBieSB0aGUgdHJhbnNtaXNzaW9uIG9mCiAqICAgRGlmZmllLUhlbGxtYW4gcGFyYW1ldGVycyB3aGljaCB3aWxsIGFsbG93IGVhY2ggc2lkZSB0byBhZ3JlZSB1cG9uIHRoZQogKiAgIHNhbWUgcHJlbWFzdGVyIHNlY3JldC4gV2hlbiB0aGUga2V5IGV4Y2hhbmdlIG1ldGhvZCBpcyBESF9SU0Egb3IgREhfRFNTLAogKiAgIGNsaWVudCBjZXJ0aWZpY2F0aW9uIGhhcyBiZWVuIHJlcXVlc3RlZCwgYW5kIHRoZSBjbGllbnQgd2FzIGFibGUgdG8KICogICByZXNwb25kIHdpdGggYSBjZXJ0aWZpY2F0ZSB3aGljaCBjb250YWluZWQgYSBEaWZmaWUtSGVsbG1hbiBwdWJsaWMga2V5CiAqICAgd2hvc2UgcGFyYW1ldGVycyAoZ3JvdXAgYW5kIGdlbmVyYXRvcikgbWF0Y2hlZCB0aG9zZSBzcGVjaWZpZWQgYnkgdGhlCiAqICAgc2VydmVyIGluIGl0cyBjZXJ0aWZpY2F0ZSwgdGhpcyBtZXNzYWdlIHdpbGwgbm90IGNvbnRhaW4gYW55IGRhdGEuCiAqCiAqIE1lYW5pbmcgb2YgdGhpcyBtZXNzYWdlOgogKiAgIElmIFJTQSBpcyBiZWluZyB1c2VkIGZvciBrZXkgYWdyZWVtZW50IGFuZCBhdXRoZW50aWNhdGlvbiwgdGhlIGNsaWVudAogKiAgIGdlbmVyYXRlcyBhIDQ4LWJ5dGUgcHJlbWFzdGVyIHNlY3JldCwgZW5jcnlwdHMgaXQgdXNpbmcgdGhlIHB1YmxpYyBrZXkKICogICBmcm9tIHRoZSBzZXJ2ZXIncyBjZXJ0aWZpY2F0ZSBvciB0aGUgdGVtcG9yYXJ5IFJTQSBrZXkgcHJvdmlkZWQgaW4gYQogKiAgIHNlcnZlciBrZXkgZXhjaGFuZ2UgbWVzc2FnZSwgYW5kIHNlbmRzIHRoZSByZXN1bHQgaW4gYW4gZW5jcnlwdGVkCiAqICAgcHJlbWFzdGVyIHNlY3JldCBtZXNzYWdlLiBUaGlzIHN0cnVjdHVyZSBpcyBhIHZhcmlhbnQgb2YgdGhlIGNsaWVudAogKiAgIGtleSBleGNoYW5nZSBtZXNzYWdlLCBub3QgYSBtZXNzYWdlIGluIGl0c2VsZi4KICoKICogc3RydWN0IHsKICogICBzZWxlY3QoS2V5RXhjaGFuZ2VBbGdvcml0aG0pIHsKICogICAgIGNhc2UgcnNhOiBFbmNyeXB0ZWRQcmVNYXN0ZXJTZWNyZXQ7CiAqICAgICBjYXNlIGRpZmZpZV9oZWxsbWFuOiBDbGllbnREaWZmaWVIZWxsbWFuUHVibGljOwogKiAgIH0gZXhjaGFuZ2Vfa2V5czsKICogfSBDbGllbnRLZXlFeGNoYW5nZTsKICoKICogc3RydWN0IHsKICogICBQcm90b2NvbFZlcnNpb24gY2xpZW50X3ZlcnNpb247CiAqICAgb3BhcXVlIHJhbmRvbVs0Nl07CiAqIH0gUHJlTWFzdGVyU2VjcmV0OwogKgogKiBzdHJ1Y3QgewogKiAgIHB1YmxpYy1rZXktZW5jcnlwdGVkIFByZU1hc3RlclNlY3JldCBwcmVfbWFzdGVyX3NlY3JldDsKICogfSBFbmNyeXB0ZWRQcmVNYXN0ZXJTZWNyZXQ7CiAqCiAqIEEgcHVibGljLWtleS1lbmNyeXB0ZWQgZWxlbWVudCBpcyBlbmNvZGVkIGFzIGEgdmVjdG9yIDwwLi4yXjE2LTE+LgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgQ2xpZW50S2V5RXhjaGFuZ2UgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlQ2xpZW50S2V5RXhjaGFuZ2UgPSBmdW5jdGlvbihjKSB7CiAgLy8gY3JlYXRlIGJ1ZmZlciB0byBlbmNyeXB0CiAgdmFyIGIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwoKICAvLyBhZGQgaGlnaGVzdCBjbGllbnQtc3VwcG9ydGVkIHByb3RvY29sIHRvIGhlbHAgc2VydmVyIGF2b2lkIHZlcnNpb24KICAvLyByb2xsYmFjayBhdHRhY2tzCiAgYi5wdXRCeXRlKGMuc2Vzc2lvbi5jbGllbnRIZWxsb1ZlcnNpb24ubWFqb3IpOwogIGIucHV0Qnl0ZShjLnNlc3Npb24uY2xpZW50SGVsbG9WZXJzaW9uLm1pbm9yKTsKCiAgLy8gZ2VuZXJhdGUgYW5kIGFkZCA0NiByYW5kb20gYnl0ZXMKICBiLnB1dEJ5dGVzKGZvcmdlLnJhbmRvbS5nZXRCeXRlcyg0NikpOwoKICAvLyBzYXZlIHByZS1tYXN0ZXIgc2VjcmV0CiAgdmFyIHNwID0gYy5zZXNzaW9uLnNwOwogIHNwLnByZV9tYXN0ZXJfc2VjcmV0ID0gYi5nZXRCeXRlcygpOwoKICAvLyBSU0EtZW5jcnlwdCB0aGUgcHJlLW1hc3RlciBzZWNyZXQKICB2YXIga2V5ID0gYy5zZXNzaW9uLnNlcnZlckNlcnRpZmljYXRlLnB1YmxpY0tleTsKICBiID0ga2V5LmVuY3J5cHQoc3AucHJlX21hc3Rlcl9zZWNyZXQpOwoKICAvKiBOb3RlOiBUaGUgZW5jcnlwdGVkIHByZS1tYXN0ZXIgc2VjcmV0IHdpbGwgYmUgc3RvcmVkIGluIGEKICAgIHB1YmxpYy1rZXktZW5jcnlwdGVkIG9wYXF1ZSB2ZWN0b3IgdGhhdCBoYXMgdGhlIGxlbmd0aCBwcmVmaXhlZCB1c2luZwogICAgMiBieXRlcywgc28gaW5jbHVkZSB0aG9zZSAyIGJ5dGVzIGluIHRoZSBoYW5kc2hha2UgbWVzc2FnZSBsZW5ndGguIFRoaXMKICAgIGlzIGRvbmUgYXMgYSBtaW5vciBvcHRpbWl6YXRpb24gaW5zdGVhZCBvZiBjYWxsaW5nIHdyaXRlVmVjdG9yKCkuICovCgogIC8vIGRldGVybWluZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlCiAgdmFyIGxlbmd0aCA9IGIubGVuZ3RoICsgMjsKCiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5jbGllbnRfa2V5X2V4Y2hhbmdlKTsKICBydmFsLnB1dEludDI0KGxlbmd0aCk7CiAgLy8gYWRkIHZlY3RvciBsZW5ndGggYnl0ZXMKICBydmFsLnB1dEludDE2KGIubGVuZ3RoKTsKICBydmFsLnB1dEJ5dGVzKGIpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBTZXJ2ZXJLZXlFeGNoYW5nZSBtZXNzYWdlLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgU2VydmVyS2V5RXhjaGFuZ2UgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlU2VydmVyS2V5RXhjaGFuZ2UgPSBmdW5jdGlvbihjKSB7CiAgLy8gdGhpcyBpbXBsZW1lbnRhdGlvbiBvbmx5IHN1cHBvcnRzIFJTQSwgbm8gRGlmZmllLUhlbGxtYW4gc3VwcG9ydCwKICAvLyBzbyB0aGlzIHJlY29yZCBpcyBlbXB0eQoKICAvLyBkZXRlcm1pbmUgbGVuZ3RoIG9mIHRoZSBoYW5kc2hha2UgbWVzc2FnZQogIHZhciBsZW5ndGggPSAwOwoKICAvLyBidWlsZCByZWNvcmQgZnJhZ21lbnQKICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgaWYobGVuZ3RoID4gMCkgewogICAgcnZhbC5wdXRCeXRlKHRscy5IYW5kc2hha2VUeXBlLnNlcnZlcl9rZXlfZXhjaGFuZ2UpOwogICAgcnZhbC5wdXRJbnQyNChsZW5ndGgpOwogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBHZXRzIHRoZSBzaWduZWQgZGF0YSB1c2VkIHRvIHZlcmlmeSBhIGNsaWVudC1zaWRlIGNlcnRpZmljYXRlLiBTZWUKICogdGxzLmNyZWF0ZUNlcnRpZmljYXRlVmVyaWZ5KCkgZm9yIGRldGFpbHMuCiAqCiAqIEBwYXJhbSBjIHRoZSBjb25uZWN0aW9uLgogKiBAcGFyYW0gY2FsbGJhY2sgdGhlIGNhbGxiYWNrIHRvIGNhbGwgb25jZSB0aGUgc2lnbmVkIGRhdGEgaXMgcmVhZHkuCiAqLwp0bHMuZ2V0Q2xpZW50U2lnbmF0dXJlID0gZnVuY3Rpb24oYywgY2FsbGJhY2spIHsKICAvLyBnZW5lcmF0ZSBkYXRhIHRvIFJTQSBlbmNyeXB0CiAgdmFyIGIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIGIucHV0QnVmZmVyKGMuc2Vzc2lvbi5tZDUuZGlnZXN0KCkpOwogIGIucHV0QnVmZmVyKGMuc2Vzc2lvbi5zaGExLmRpZ2VzdCgpKTsKICBiID0gYi5nZXRCeXRlcygpOwoKICAvLyBjcmVhdGUgZGVmYXVsdCBzaWduaW5nIGZ1bmN0aW9uIGFzIG5lY2Vzc2FyeQogIGMuZ2V0U2lnbmF0dXJlID0gYy5nZXRTaWduYXR1cmUgfHwgZnVuY3Rpb24oYywgYiwgY2FsbGJhY2spIHsKICAgIC8vIGRvIHJzYSBlbmNyeXB0aW9uLCBjYWxsIGNhbGxiYWNrCiAgICB2YXIgcHJpdmF0ZUtleSA9IG51bGw7CiAgICBpZihjLmdldFByaXZhdGVLZXkpIHsKICAgICAgdHJ5IHsKICAgICAgICBwcml2YXRlS2V5ID0gYy5nZXRQcml2YXRlS2V5KGMsIGMuc2Vzc2lvbi5jbGllbnRDZXJ0aWZpY2F0ZSk7CiAgICAgICAgcHJpdmF0ZUtleSA9IGZvcmdlLnBraS5wcml2YXRlS2V5RnJvbVBlbShwcml2YXRlS2V5KTsKICAgICAgfSBjYXRjaChleCkgewogICAgICAgIGMuZXJyb3IoYywgewogICAgICAgICAgbWVzc2FnZTogJ0NvdWxkIG5vdCBnZXQgcHJpdmF0ZSBrZXkuJywKICAgICAgICAgIGNhdXNlOiBleCwKICAgICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgICBhbGVydDogewogICAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KICAgIGlmKHByaXZhdGVLZXkgPT09IG51bGwpIHsKICAgICAgYy5lcnJvcihjLCB7CiAgICAgICAgbWVzc2FnZTogJ05vIHByaXZhdGUga2V5IHNldC4nLAogICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmludGVybmFsX2Vycm9yCiAgICAgICAgfQogICAgICB9KTsKICAgIH0gZWxzZSB7CiAgICAgIGIgPSBwcml2YXRlS2V5LnNpZ24oYiwgbnVsbCk7CiAgICB9CiAgICBjYWxsYmFjayhjLCBiKTsKICB9OwoKICAvLyBnZXQgY2xpZW50IHNpZ25hdHVyZQogIGMuZ2V0U2lnbmF0dXJlKGMsIGIsIGNhbGxiYWNrKTsKfTsKCi8qKgogKiBDcmVhdGVzIGEgQ2VydGlmaWNhdGVWZXJpZnkgbWVzc2FnZS4KICoKICogTWVhbmluZyBvZiB0aGlzIG1lc3NhZ2U6CiAqICAgVGhpcyBzdHJ1Y3R1cmUgY29udmV5cyB0aGUgY2xpZW50J3MgRGlmZmllLUhlbGxtYW4gcHVibGljIHZhbHVlCiAqICAgKFljKSBpZiBpdCB3YXMgbm90IGFscmVhZHkgaW5jbHVkZWQgaW4gdGhlIGNsaWVudCdzIGNlcnRpZmljYXRlLgogKiAgIFRoZSBlbmNvZGluZyB1c2VkIGZvciBZYyBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBlbnVtZXJhdGVkCiAqICAgUHVibGljVmFsdWVFbmNvZGluZy4gVGhpcyBzdHJ1Y3R1cmUgaXMgYSB2YXJpYW50IG9mIHRoZSBjbGllbnQKICogICBrZXkgZXhjaGFuZ2UgbWVzc2FnZSwgbm90IGEgbWVzc2FnZSBpbiBpdHNlbGYuCiAqCiAqIFdoZW4gdGhpcyBtZXNzYWdlIHdpbGwgYmUgc2VudDoKICogICBUaGlzIG1lc3NhZ2UgaXMgdXNlZCB0byBwcm92aWRlIGV4cGxpY2l0IHZlcmlmaWNhdGlvbiBvZiBhIGNsaWVudAogKiAgIGNlcnRpZmljYXRlLiBUaGlzIG1lc3NhZ2UgaXMgb25seSBzZW50IGZvbGxvd2luZyBhIGNsaWVudAogKiAgIGNlcnRpZmljYXRlIHRoYXQgaGFzIHNpZ25pbmcgY2FwYWJpbGl0eSAoaS5lLiBhbGwgY2VydGlmaWNhdGVzCiAqICAgZXhjZXB0IHRob3NlIGNvbnRhaW5pbmcgZml4ZWQgRGlmZmllLUhlbGxtYW4gcGFyYW1ldGVycykuIFdoZW4KICogICBzZW50LCBpdCB3aWxsIGltbWVkaWF0ZWx5IGZvbGxvdyB0aGUgY2xpZW50IGtleSBleGNoYW5nZSBtZXNzYWdlLgogKgogKiBzdHJ1Y3QgewogKiAgIFNpZ25hdHVyZSBzaWduYXR1cmU7CiAqIH0gQ2VydGlmaWNhdGVWZXJpZnk7CiAqCiAqIENlcnRpZmljYXRlVmVyaWZ5LnNpZ25hdHVyZS5tZDVfaGFzaAogKiAgIE1ENShoYW5kc2hha2VfbWVzc2FnZXMpOwogKgogKiBDZXJ0aWZpY2F0ZS5zaWduYXR1cmUuc2hhX2hhc2gKICogICBTSEEoaGFuZHNoYWtlX21lc3NhZ2VzKTsKICoKICogSGVyZSBoYW5kc2hha2VfbWVzc2FnZXMgcmVmZXJzIHRvIGFsbCBoYW5kc2hha2UgbWVzc2FnZXMgc2VudCBvcgogKiByZWNlaXZlZCBzdGFydGluZyBhdCBjbGllbnQgaGVsbG8gdXAgdG8gYnV0IG5vdCBpbmNsdWRpbmcgdGhpcwogKiBtZXNzYWdlLCBpbmNsdWRpbmcgdGhlIHR5cGUgYW5kIGxlbmd0aCBmaWVsZHMgb2YgdGhlIGhhbmRzaGFrZQogKiBtZXNzYWdlcy4KICoKICogc2VsZWN0KFNpZ25hdHVyZUFsZ29yaXRobSkgewogKiAgIGNhc2UgYW5vbnltb3VzOiBzdHJ1Y3QgeyB9OwogKiAgIGNhc2UgcnNhOgogKiAgICAgZGlnaXRhbGx5LXNpZ25lZCBzdHJ1Y3QgewogKiAgICAgICBvcGFxdWUgbWQ1X2hhc2hbMTZdOwogKiAgICAgICBvcGFxdWUgc2hhX2hhc2hbMjBdOwogKiAgICAgfTsKICogICBjYXNlIGRzYToKICogICAgIGRpZ2l0YWxseS1zaWduZWQgc3RydWN0IHsKICogICAgICAgb3BhcXVlIHNoYV9oYXNoWzIwXTsKICogICAgIH07CiAqIH0gU2lnbmF0dXJlOwogKgogKiBJbiBkaWdpdGFsIHNpZ25pbmcsIG9uZS13YXkgaGFzaCBmdW5jdGlvbnMgYXJlIHVzZWQgYXMgaW5wdXQgZm9yIGEKICogc2lnbmluZyBhbGdvcml0aG0uIEEgZGlnaXRhbGx5LXNpZ25lZCBlbGVtZW50IGlzIGVuY29kZWQgYXMgYW4gb3BhcXVlCiAqIHZlY3RvciA8MC4uMl4xNi0xPiwgd2hlcmUgdGhlIGxlbmd0aCBpcyBzcGVjaWZpZWQgYnkgdGhlIHNpZ25pbmcKICogYWxnb3JpdGhtIGFuZCBrZXkuCiAqCiAqIEluIFJTQSBzaWduaW5nLCBhIDM2LWJ5dGUgc3RydWN0dXJlIG9mIHR3byBoYXNoZXMgKG9uZSBTSEEgYW5kIG9uZQogKiBNRDUpIGlzIHNpZ25lZCAoZW5jcnlwdGVkIHdpdGggdGhlIHByaXZhdGUga2V5KS4gSXQgaXMgZW5jb2RlZCB3aXRoCiAqIFBLQ1MgIzEgYmxvY2sgdHlwZSAwIG9yIHR5cGUgMSBhcyBkZXNjcmliZWQgaW4gW1BLQ1MxXS4KICoKICogSW4gRFNTLCB0aGUgMjAgYnl0ZXMgb2YgdGhlIFNIQSBoYXNoIGFyZSBydW4gZGlyZWN0bHkgdGhyb3VnaCB0aGUKICogRGlnaXRhbCBTaWduaW5nIEFsZ29yaXRobSB3aXRoIG5vIGFkZGl0aW9uYWwgaGFzaGluZy4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSBzaWduYXR1cmUgdGhlIHNpZ25hdHVyZSB0byBpbmNsdWRlIGluIHRoZSBtZXNzYWdlLgogKgogKiBAcmV0dXJuIHRoZSBDZXJ0aWZpY2F0ZVZlcmlmeSBieXRlIGJ1ZmZlci4KICovCnRscy5jcmVhdGVDZXJ0aWZpY2F0ZVZlcmlmeSA9IGZ1bmN0aW9uKGMsIHNpZ25hdHVyZSkgewogIC8qIE5vdGU6IFRoZSBzaWduYXR1cmUgd2lsbCBiZSBzdG9yZWQgaW4gYSAiZGlnaXRhbGx5LXNpZ25lZCIgb3BhcXVlCiAgICB2ZWN0b3IgdGhhdCBoYXMgdGhlIGxlbmd0aCBwcmVmaXhlZCB1c2luZyAyIGJ5dGVzLCBzbyBpbmNsdWRlIHRob3NlCiAgICAyIGJ5dGVzIGluIHRoZSBoYW5kc2hha2UgbWVzc2FnZSBsZW5ndGguIFRoaXMgaXMgZG9uZSBhcyBhIG1pbm9yCiAgICBvcHRpbWl6YXRpb24gaW5zdGVhZCBvZiBjYWxsaW5nIHdyaXRlVmVjdG9yKCkuICovCgogIC8vIGRldGVybWluZSBsZW5ndGggb2YgdGhlIGhhbmRzaGFrZSBtZXNzYWdlCiAgdmFyIGxlbmd0aCA9IHNpZ25hdHVyZS5sZW5ndGggKyAyOwoKICAvLyBidWlsZCByZWNvcmQgZnJhZ21lbnQKICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgcnZhbC5wdXRCeXRlKHRscy5IYW5kc2hha2VUeXBlLmNlcnRpZmljYXRlX3ZlcmlmeSk7CiAgcnZhbC5wdXRJbnQyNChsZW5ndGgpOwogIC8vIGFkZCB2ZWN0b3IgbGVuZ3RoIGJ5dGVzCiAgcnZhbC5wdXRJbnQxNihzaWduYXR1cmUubGVuZ3RoKTsKICBydmFsLnB1dEJ5dGVzKHNpZ25hdHVyZSk7CiAgcmV0dXJuIHJ2YWw7Cn07CgovKioKICogQ3JlYXRlcyBhIENlcnRpZmljYXRlUmVxdWVzdCBtZXNzYWdlLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgQ2VydGlmaWNhdGVSZXF1ZXN0IGJ5dGUgYnVmZmVyLgogKi8KdGxzLmNyZWF0ZUNlcnRpZmljYXRlUmVxdWVzdCA9IGZ1bmN0aW9uKGMpIHsKICAvLyBUT0RPOiBzdXBwb3J0IG90aGVyIGNlcnRpZmljYXRlIHR5cGVzCiAgdmFyIGNlcnRUeXBlcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CgogIC8vIGNvbW1vbiBSU0EgY2VydGlmaWNhdGUgdHlwZQogIGNlcnRUeXBlcy5wdXRCeXRlKDB4MDEpOwoKICAvLyBUT0RPOiB2ZXJpZnkgdGhhdCB0aGlzIGRhdGEgZm9ybWF0IGlzIGNvcnJlY3QKICAvLyBhZGQgZGlzdGluZ3Vpc2hlZCBuYW1lcyBmcm9tIENBIHN0b3JlCiAgdmFyIGNBcyA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgZm9yKHZhciBrZXkgaW4gYy5jYVN0b3JlLmNlcnRzKSB7CiAgICB2YXIgY2VydCA9IGMuY2FTdG9yZS5jZXJ0c1trZXldOwogICAgdmFyIGRuID0gZm9yZ2UucGtpLmRpc3Rpbmd1aXNoZWROYW1lVG9Bc24xKGNlcnQuc3ViamVjdCk7CiAgICBjQXMucHV0QnVmZmVyKGZvcmdlLmFzbjEudG9EZXIoZG4pKTsKICB9CgogIC8vIFRPRE86IFRMUyAxLjIrIGhhcyBhIGRpZmZlcmVudCBmb3JtYXQKCiAgLy8gZGV0ZXJtaW5lIGxlbmd0aCBvZiB0aGUgaGFuZHNoYWtlIG1lc3NhZ2UKICB2YXIgbGVuZ3RoID0KICAgIDEgKyBjZXJ0VHlwZXMubGVuZ3RoKCkgKwogICAgMiArIGNBcy5sZW5ndGgoKTsKCiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5jZXJ0aWZpY2F0ZV9yZXF1ZXN0KTsKICBydmFsLnB1dEludDI0KGxlbmd0aCk7CiAgd3JpdGVWZWN0b3IocnZhbCwgMSwgY2VydFR5cGVzKTsKICB3cml0ZVZlY3RvcihydmFsLCAyLCBjQXMpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBTZXJ2ZXJIZWxsb0RvbmUgbWVzc2FnZS4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqCiAqIEByZXR1cm4gdGhlIFNlcnZlckhlbGxvRG9uZSBieXRlIGJ1ZmZlci4KICovCnRscy5jcmVhdGVTZXJ2ZXJIZWxsb0RvbmUgPSBmdW5jdGlvbihjKSB7CiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5zZXJ2ZXJfaGVsbG9fZG9uZSk7CiAgcnZhbC5wdXRJbnQyNCgwKTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDcmVhdGVzIGEgQ2hhbmdlQ2lwaGVyU3BlYyBtZXNzYWdlLgogKgogKiBUaGUgY2hhbmdlIGNpcGhlciBzcGVjIHByb3RvY29sIGV4aXN0cyB0byBzaWduYWwgdHJhbnNpdGlvbnMgaW4KICogY2lwaGVyaW5nIHN0cmF0ZWdpZXMuIFRoZSBwcm90b2NvbCBjb25zaXN0cyBvZiBhIHNpbmdsZSBtZXNzYWdlLAogKiB3aGljaCBpcyBlbmNyeXB0ZWQgYW5kIGNvbXByZXNzZWQgdW5kZXIgdGhlIGN1cnJlbnQgKG5vdCB0aGUgcGVuZGluZykKICogY29ubmVjdGlvbiBzdGF0ZS4gVGhlIG1lc3NhZ2UgY29uc2lzdHMgb2YgYSBzaW5nbGUgYnl0ZSBvZiB2YWx1ZSAxLgogKgogKiBzdHJ1Y3QgewogKiAgIGVudW0geyBjaGFuZ2VfY2lwaGVyX3NwZWMoMSksICgyNTUpIH0gdHlwZTsKICogfSBDaGFuZ2VDaXBoZXJTcGVjOwogKgogKiBAcmV0dXJuIHRoZSBDaGFuZ2VDaXBoZXJTcGVjIGJ5dGUgYnVmZmVyLgogKi8KdGxzLmNyZWF0ZUNoYW5nZUNpcGhlclNwZWMgPSBmdW5jdGlvbigpIHsKICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgcnZhbC5wdXRCeXRlKDB4MDEpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBGaW5pc2hlZCBtZXNzYWdlLgogKgogKiBzdHJ1Y3QgewogKiAgIG9wYXF1ZSB2ZXJpZnlfZGF0YVsxMl07CiAqIH0gRmluaXNoZWQ7CiAqCiAqIHZlcmlmeV9kYXRhCiAqICAgUFJGKG1hc3Rlcl9zZWNyZXQsIGZpbmlzaGVkX2xhYmVsLCBNRDUoaGFuZHNoYWtlX21lc3NhZ2VzKSArCiAqICAgU0hBLTEoaGFuZHNoYWtlX21lc3NhZ2VzKSkgWzAuLjExXTsKICoKICogZmluaXNoZWRfbGFiZWwKICogICBGb3IgRmluaXNoZWQgbWVzc2FnZXMgc2VudCBieSB0aGUgY2xpZW50LCB0aGUgc3RyaW5nICJjbGllbnQKICogICBmaW5pc2hlZCIuIEZvciBGaW5pc2hlZCBtZXNzYWdlcyBzZW50IGJ5IHRoZSBzZXJ2ZXIsIHRoZQogKiAgIHN0cmluZyAic2VydmVyIGZpbmlzaGVkIi4KICoKICogaGFuZHNoYWtlX21lc3NhZ2VzCiAqICAgQWxsIG9mIHRoZSBkYXRhIGZyb20gYWxsIGhhbmRzaGFrZSBtZXNzYWdlcyB1cCB0byBidXQgbm90CiAqICAgaW5jbHVkaW5nIHRoaXMgbWVzc2FnZS4gVGhpcyBpcyBvbmx5IGRhdGEgdmlzaWJsZSBhdCB0aGUKICogICBoYW5kc2hha2UgbGF5ZXIgYW5kIGRvZXMgbm90IGluY2x1ZGUgcmVjb3JkIGxheWVyIGhlYWRlcnMuCiAqICAgVGhpcyBpcyB0aGUgY29uY2F0ZW5hdGlvbiBvZiBhbGwgdGhlIEhhbmRzaGFrZSBzdHJ1Y3R1cmVzIGFzCiAqICAgZGVmaW5lZCBpbiA3LjQgZXhjaGFuZ2VkIHRodXMgZmFyLgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgRmluaXNoZWQgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlRmluaXNoZWQgPSBmdW5jdGlvbihjKSB7CiAgLy8gZ2VuZXJhdGUgdmVyaWZ5X2RhdGEKICB2YXIgYiA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgYi5wdXRCdWZmZXIoYy5zZXNzaW9uLm1kNS5kaWdlc3QoKSk7CiAgYi5wdXRCdWZmZXIoYy5zZXNzaW9uLnNoYTEuZGlnZXN0KCkpOwoKICAvLyBUT0RPOiBkZXRlcm1pbmUgcHJmIGZ1bmN0aW9uIGFuZCB2ZXJpZnkgbGVuZ3RoIGZvciBUTFMgMS4yCiAgdmFyIGNsaWVudCA9IChjLmVudGl0eSA9PT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KTsKICB2YXIgc3AgPSBjLnNlc3Npb24uc3A7CiAgdmFyIHZkbCA9IDEyOwogIHZhciBwcmYgPSBwcmZfVExTMTsKICB2YXIgbGFiZWwgPSBjbGllbnQgPyAnY2xpZW50IGZpbmlzaGVkJyA6ICdzZXJ2ZXIgZmluaXNoZWQnOwogIGIgPSBwcmYoc3AubWFzdGVyX3NlY3JldCwgbGFiZWwsIGIuZ2V0Qnl0ZXMoKSwgdmRsKTsKCiAgLy8gYnVpbGQgcmVjb3JkIGZyYWdtZW50CiAgdmFyIHJ2YWwgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIHJ2YWwucHV0Qnl0ZSh0bHMuSGFuZHNoYWtlVHlwZS5maW5pc2hlZCk7CiAgcnZhbC5wdXRJbnQyNChiLmxlbmd0aCgpKTsKICBydmFsLnB1dEJ1ZmZlcihiKTsKICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBDcmVhdGVzIGEgSGVhcnRiZWF0TWVzc2FnZSAoU2VlIFJGQyA2NTIwKS4KICoKICogc3RydWN0IHsKICogICBIZWFydGJlYXRNZXNzYWdlVHlwZSB0eXBlOwogKiAgIHVpbnQxNiBwYXlsb2FkX2xlbmd0aDsKICogICBvcGFxdWUgcGF5bG9hZFtIZWFydGJlYXRNZXNzYWdlLnBheWxvYWRfbGVuZ3RoXTsKICogICBvcGFxdWUgcGFkZGluZ1twYWRkaW5nX2xlbmd0aF07CiAqIH0gSGVhcnRiZWF0TWVzc2FnZTsKICoKICogVGhlIHRvdGFsIGxlbmd0aCBvZiBhIEhlYXJ0YmVhdE1lc3NhZ2UgTVVTVCBOT1QgZXhjZWVkIDJeMTQgb3IKICogbWF4X2ZyYWdtZW50X2xlbmd0aCB3aGVuIG5lZ290aWF0ZWQgYXMgZGVmaW5lZCBpbiBbUkZDNjA2Nl0uCiAqCiAqIHR5cGU6IFRoZSBtZXNzYWdlIHR5cGUsIGVpdGhlciBoZWFydGJlYXRfcmVxdWVzdCBvciBoZWFydGJlYXRfcmVzcG9uc2UuCiAqCiAqIHBheWxvYWRfbGVuZ3RoOiBUaGUgbGVuZ3RoIG9mIHRoZSBwYXlsb2FkLgogKgogKiBwYXlsb2FkOiBUaGUgcGF5bG9hZCBjb25zaXN0cyBvZiBhcmJpdHJhcnkgY29udGVudC4KICoKICogcGFkZGluZzogVGhlIHBhZGRpbmcgaXMgcmFuZG9tIGNvbnRlbnQgdGhhdCBNVVNUIGJlIGlnbm9yZWQgYnkgdGhlCiAqICAgcmVjZWl2ZXIuIFRoZSBsZW5ndGggb2YgYSBIZWFydGJlYXRNZXNzYWdlIGlzIFRMU1BsYWludGV4dC5sZW5ndGgKICogICBmb3IgVExTIGFuZCBEVExTUGxhaW50ZXh0Lmxlbmd0aCBmb3IgRFRMUy4gRnVydGhlcm1vcmUsIHRoZQogKiAgIGxlbmd0aCBvZiB0aGUgdHlwZSBmaWVsZCBpcyAxIGJ5dGUsIGFuZCB0aGUgbGVuZ3RoIG9mIHRoZQogKiAgIHBheWxvYWRfbGVuZ3RoIGlzIDIuIFRoZXJlZm9yZSwgdGhlIHBhZGRpbmdfbGVuZ3RoIGlzCiAqICAgVExTUGxhaW50ZXh0Lmxlbmd0aCAtIHBheWxvYWRfbGVuZ3RoIC0gMyBmb3IgVExTIGFuZAogKiAgIERUTFNQbGFpbnRleHQubGVuZ3RoIC0gcGF5bG9hZF9sZW5ndGggLSAzIGZvciBEVExTLiBUaGUKICogICBwYWRkaW5nX2xlbmd0aCBNVVNUIGJlIGF0IGxlYXN0IDE2LgogKgogKiBUaGUgc2VuZGVyIG9mIGEgSGVhcnRiZWF0TWVzc2FnZSBNVVNUIHVzZSBhIHJhbmRvbSBwYWRkaW5nIG9mIGF0CiAqIGxlYXN0IDE2IGJ5dGVzLiBUaGUgcGFkZGluZyBvZiBhIHJlY2VpdmVkIEhlYXJ0YmVhdE1lc3NhZ2UgbWVzc2FnZQogKiBNVVNUIGJlIGlnbm9yZWQuCiAqCiAqIElmIHRoZSBwYXlsb2FkX2xlbmd0aCBvZiBhIHJlY2VpdmVkIEhlYXJ0YmVhdE1lc3NhZ2UgaXMgdG9vIGxhcmdlLAogKiB0aGUgcmVjZWl2ZWQgSGVhcnRiZWF0TWVzc2FnZSBNVVNUIGJlIGRpc2NhcmRlZCBzaWxlbnRseS4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqIEBwYXJhbSB0eXBlIHRoZSB0bHMuSGVhcnRiZWF0TWVzc2FnZVR5cGUuCiAqIEBwYXJhbSBwYXlsb2FkIHRoZSBoZWFydGJlYXQgZGF0YSB0byBzZW5kIGFzIHRoZSBwYXlsb2FkLgogKiBAcGFyYW0gW3BheWxvYWRMZW5ndGhdIHRoZSBwYXlsb2FkIGxlbmd0aCB0byB1c2UsIGRlZmF1bHRzIHRvIHRoZQogKiAgICAgICAgICBhY3R1YWwgcGF5bG9hZCBsZW5ndGguCiAqCiAqIEByZXR1cm4gdGhlIEhlYXJ0YmVhdFJlcXVlc3QgYnl0ZSBidWZmZXIuCiAqLwp0bHMuY3JlYXRlSGVhcnRiZWF0ID0gZnVuY3Rpb24odHlwZSwgcGF5bG9hZCwgcGF5bG9hZExlbmd0aCkgewogIGlmKHR5cGVvZiBwYXlsb2FkTGVuZ3RoID09PSAndW5kZWZpbmVkJykgewogICAgcGF5bG9hZExlbmd0aCA9IHBheWxvYWQubGVuZ3RoOwogIH0KICAvLyBidWlsZCByZWNvcmQgZnJhZ21lbnQKICB2YXIgcnZhbCA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgcnZhbC5wdXRCeXRlKHR5cGUpOyAgICAgICAgICAgICAgIC8vIGhlYXJ0YmVhdCBtZXNzYWdlIHR5cGUKICBydmFsLnB1dEludDE2KHBheWxvYWRMZW5ndGgpOyAgICAgLy8gcGF5bG9hZCBsZW5ndGgKICBydmFsLnB1dEJ5dGVzKHBheWxvYWQpOyAgICAgICAgICAgLy8gcGF5bG9hZAogIC8vIHBhZGRpbmcKICB2YXIgcGxhaW50ZXh0TGVuZ3RoID0gcnZhbC5sZW5ndGgoKTsKICB2YXIgcGFkZGluZ0xlbmd0aCA9IE1hdGgubWF4KDE2LCBwbGFpbnRleHRMZW5ndGggLSBwYXlsb2FkTGVuZ3RoIC0gMyk7CiAgcnZhbC5wdXRCeXRlcyhmb3JnZS5yYW5kb20uZ2V0Qnl0ZXMocGFkZGluZ0xlbmd0aCkpOwogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIEZyYWdtZW50cywgY29tcHJlc3NlcywgZW5jcnlwdHMsIGFuZCBxdWV1ZXMgYSByZWNvcmQgZm9yIGRlbGl2ZXJ5LgogKgogKiBAcGFyYW0gYyB0aGUgY29ubmVjdGlvbi4KICogQHBhcmFtIHJlY29yZCB0aGUgcmVjb3JkIHRvIHF1ZXVlLgogKi8KdGxzLnF1ZXVlID0gZnVuY3Rpb24oYywgcmVjb3JkKSB7CiAgLy8gZXJyb3IgZHVyaW5nIHJlY29yZCBjcmVhdGlvbgogIGlmKCFyZWNvcmQpIHsKICAgIHJldHVybjsKICB9CgogIC8vIGlmIHRoZSByZWNvcmQgaXMgYSBoYW5kc2hha2UgcmVjb3JkLCB1cGRhdGUgaGFuZHNoYWtlIGhhc2hlcwogIGlmKHJlY29yZC50eXBlID09PSB0bHMuQ29udGVudFR5cGUuaGFuZHNoYWtlKSB7CiAgICB2YXIgYnl0ZXMgPSByZWNvcmQuZnJhZ21lbnQuYnl0ZXMoKTsKICAgIGMuc2Vzc2lvbi5tZDUudXBkYXRlKGJ5dGVzKTsKICAgIGMuc2Vzc2lvbi5zaGExLnVwZGF0ZShieXRlcyk7CiAgICBieXRlcyA9IG51bGw7CiAgfQoKICAvLyBoYW5kbGUgcmVjb3JkIGZyYWdtZW50YXRpb24KICB2YXIgcmVjb3JkczsKICBpZihyZWNvcmQuZnJhZ21lbnQubGVuZ3RoKCkgPD0gdGxzLk1heEZyYWdtZW50KSB7CiAgICByZWNvcmRzID0gW3JlY29yZF07CiAgfSBlbHNlIHsKICAgIC8vIGZyYWdtZW50IGRhdGEgYXMgbG9uZyBhcyBpdCBpcyB0b28gbG9uZwogICAgcmVjb3JkcyA9IFtdOwogICAgdmFyIGRhdGEgPSByZWNvcmQuZnJhZ21lbnQuYnl0ZXMoKTsKICAgIHdoaWxlKGRhdGEubGVuZ3RoID4gdGxzLk1heEZyYWdtZW50KSB7CiAgICAgIHJlY29yZHMucHVzaCh0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICB0eXBlOiByZWNvcmQudHlwZSwKICAgICAgICBkYXRhOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihkYXRhLnNsaWNlKDAsIHRscy5NYXhGcmFnbWVudCkpCiAgICAgIH0pKTsKICAgICAgZGF0YSA9IGRhdGEuc2xpY2UodGxzLk1heEZyYWdtZW50KTsKICAgIH0KICAgIC8vIGFkZCBsYXN0IHJlY29yZAogICAgaWYoZGF0YS5sZW5ndGggPiAwKSB7CiAgICAgIHJlY29yZHMucHVzaCh0bHMuY3JlYXRlUmVjb3JkKGMsIHsKICAgICAgICB0eXBlOiByZWNvcmQudHlwZSwKICAgICAgICBkYXRhOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihkYXRhKQogICAgICB9KSk7CiAgICB9CiAgfQoKICAvLyBjb21wcmVzcyBhbmQgZW5jcnlwdCBhbGwgZnJhZ21lbnRlZCByZWNvcmRzCiAgZm9yKHZhciBpID0gMDsgaSA8IHJlY29yZHMubGVuZ3RoICYmICFjLmZhaWw7ICsraSkgewogICAgLy8gdXBkYXRlIHRoZSByZWNvcmQgdXNpbmcgY3VycmVudCB3cml0ZSBzdGF0ZQogICAgdmFyIHJlYyA9IHJlY29yZHNbaV07CiAgICB2YXIgcyA9IGMuc3RhdGUuY3VycmVudC53cml0ZTsKICAgIGlmKHMudXBkYXRlKGMsIHJlYykpIHsKICAgICAgLy8gc3RvcmUgcmVjb3JkCiAgICAgIGMucmVjb3Jkcy5wdXNoKHJlYyk7CiAgICB9CiAgfQp9OwoKLyoqCiAqIEZsdXNoZXMgYWxsIHF1ZXVlZCByZWNvcmRzIHRvIHRoZSBvdXRwdXQgYnVmZmVyIGFuZCBjYWxscyB0aGUKICogdGxzRGF0YVJlYWR5KCkgaGFuZGxlciBvbiB0aGUgZ2l2ZW4gY29ubmVjdGlvbi4KICoKICogQHBhcmFtIGMgdGhlIGNvbm5lY3Rpb24uCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KdGxzLmZsdXNoID0gZnVuY3Rpb24oYykgewogIGZvcih2YXIgaSA9IDA7IGkgPCBjLnJlY29yZHMubGVuZ3RoOyArK2kpIHsKICAgIHZhciByZWNvcmQgPSBjLnJlY29yZHNbaV07CgogICAgLy8gYWRkIHJlY29yZCBoZWFkZXIgYW5kIGZyYWdtZW50CiAgICBjLnRsc0RhdGEucHV0Qnl0ZShyZWNvcmQudHlwZSk7CiAgICBjLnRsc0RhdGEucHV0Qnl0ZShyZWNvcmQudmVyc2lvbi5tYWpvcik7CiAgICBjLnRsc0RhdGEucHV0Qnl0ZShyZWNvcmQudmVyc2lvbi5taW5vcik7CiAgICBjLnRsc0RhdGEucHV0SW50MTYocmVjb3JkLmZyYWdtZW50Lmxlbmd0aCgpKTsKICAgIGMudGxzRGF0YS5wdXRCdWZmZXIoYy5yZWNvcmRzW2ldLmZyYWdtZW50KTsKICB9CiAgYy5yZWNvcmRzID0gW107CiAgcmV0dXJuIGMudGxzRGF0YVJlYWR5KGMpOwp9OwoKLyoqCiAqIE1hcHMgYSBwa2kuY2VydGlmaWNhdGVFcnJvciB0byBhIHRscy5BbGVydC5EZXNjcmlwdGlvbi4KICoKICogQHBhcmFtIGVycm9yIHRoZSBlcnJvciB0byBtYXAuCiAqCiAqIEByZXR1cm4gdGhlIGFsZXJ0IGRlc2NyaXB0aW9uLgogKi8KdmFyIF9jZXJ0RXJyb3JUb0FsZXJ0RGVzYyA9IGZ1bmN0aW9uKGVycm9yKSB7CiAgc3dpdGNoKGVycm9yKSB7CiAgY2FzZSB0cnVlOgogICAgcmV0dXJuIHRydWU7CiAgY2FzZSBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGU6CiAgICByZXR1cm4gdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmJhZF9jZXJ0aWZpY2F0ZTsKICBjYXNlIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLnVuc3VwcG9ydGVkX2NlcnRpZmljYXRlOgogICAgcmV0dXJuIHRscy5BbGVydC5EZXNjcmlwdGlvbi51bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZTsKICBjYXNlIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLmNlcnRpZmljYXRlX3Jldm9rZWQ6CiAgICByZXR1cm4gdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNlcnRpZmljYXRlX3Jldm9rZWQ7CiAgY2FzZSBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci5jZXJ0aWZpY2F0ZV9leHBpcmVkOgogICAgcmV0dXJuIHRscy5BbGVydC5EZXNjcmlwdGlvbi5jZXJ0aWZpY2F0ZV9leHBpcmVkOwogIGNhc2UgZm9yZ2UucGtpLmNlcnRpZmljYXRlRXJyb3IuY2VydGlmaWNhdGVfdW5rbm93bjoKICAgIHJldHVybiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uY2VydGlmaWNhdGVfdW5rbm93bjsKICBjYXNlIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLnVua25vd25fY2E6CiAgICByZXR1cm4gdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLnVua25vd25fY2E7CiAgZGVmYXVsdDoKICAgIHJldHVybiB0bHMuQWxlcnQuRGVzY3JpcHRpb24uYmFkX2NlcnRpZmljYXRlOwogIH0KfTsKCi8qKgogKiBNYXBzIGEgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uIHRvIGEgcGtpLmNlcnRpZmljYXRlRXJyb3IuCiAqCiAqIEBwYXJhbSBkZXNjIHRoZSBhbGVydCBkZXNjcmlwdGlvbi4KICoKICogQHJldHVybiB0aGUgY2VydGlmaWNhdGUgZXJyb3IuCiAqLwp2YXIgX2FsZXJ0RGVzY1RvQ2VydEVycm9yID0gZnVuY3Rpb24oZGVzYykgewogIHN3aXRjaChkZXNjKSB7CiAgY2FzZSB0cnVlOgogICAgcmV0dXJuIHRydWU7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uYmFkX2NlcnRpZmljYXRlOgogICAgcmV0dXJuIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLmJhZF9jZXJ0aWZpY2F0ZTsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi51bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZToKICAgIHJldHVybiBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci51bnN1cHBvcnRlZF9jZXJ0aWZpY2F0ZTsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi5jZXJ0aWZpY2F0ZV9yZXZva2VkOgogICAgcmV0dXJuIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLmNlcnRpZmljYXRlX3Jldm9rZWQ7CiAgY2FzZSB0bHMuQWxlcnQuRGVzY3JpcHRpb24uY2VydGlmaWNhdGVfZXhwaXJlZDoKICAgIHJldHVybiBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci5jZXJ0aWZpY2F0ZV9leHBpcmVkOwogIGNhc2UgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNlcnRpZmljYXRlX3Vua25vd246CiAgICByZXR1cm4gZm9yZ2UucGtpLmNlcnRpZmljYXRlRXJyb3IuY2VydGlmaWNhdGVfdW5rbm93bjsKICBjYXNlIHRscy5BbGVydC5EZXNjcmlwdGlvbi51bmtub3duX2NhOgogICAgcmV0dXJuIGZvcmdlLnBraS5jZXJ0aWZpY2F0ZUVycm9yLnVua25vd25fY2E7CiAgZGVmYXVsdDoKICAgIHJldHVybiBmb3JnZS5wa2kuY2VydGlmaWNhdGVFcnJvci5iYWRfY2VydGlmaWNhdGU7CiAgfQp9OwoKLyoqCiAqIFZlcmlmaWVzIGEgY2VydGlmaWNhdGUgY2hhaW4gYWdhaW5zdCB0aGUgZ2l2ZW4gY29ubmVjdGlvbidzCiAqIENlcnRpZmljYXRlIEF1dGhvcml0eSBzdG9yZS4KICoKICogQHBhcmFtIGMgdGhlIFRMUyBjb25uZWN0aW9uLgogKiBAcGFyYW0gY2hhaW4gdGhlIGNlcnRpZmljYXRlIGNoYWluIHRvIHZlcmlmeSwgd2l0aCB0aGUgcm9vdCBvciBoaWdoZXN0CiAqICAgICAgICAgIGF1dGhvcml0eSBhdCB0aGUgZW5kLgogKgogKiBAcmV0dXJuIHRydWUgaWYgc3VjY2Vzc2Z1bCwgZmFsc2UgaWYgbm90LgogKi8KdGxzLnZlcmlmeUNlcnRpZmljYXRlQ2hhaW4gPSBmdW5jdGlvbihjLCBjaGFpbikgewogIHRyeSB7CiAgICAvLyB2ZXJpZnkgY2hhaW4KICAgIGZvcmdlLnBraS52ZXJpZnlDZXJ0aWZpY2F0ZUNoYWluKGMuY2FTdG9yZSwgY2hhaW4sCiAgICAgIGZ1bmN0aW9uIHZlcmlmeSh2ZmQsIGRlcHRoLCBjaGFpbikgewogICAgICAgIC8vIGNvbnZlcnQgcGtpLmNlcnRpZmljYXRlRXJyb3IgdG8gdGxzIGFsZXJ0IGRlc2NyaXB0aW9uCiAgICAgICAgdmFyIGRlc2MgPSBfY2VydEVycm9yVG9BbGVydERlc2ModmZkKTsKCiAgICAgICAgLy8gY2FsbCBhcHBsaWNhdGlvbiBjYWxsYmFjawogICAgICAgIHZhciByZXQgPSBjLnZlcmlmeShjLCB2ZmQsIGRlcHRoLCBjaGFpbik7CiAgICAgICAgaWYocmV0ICE9PSB0cnVlKSB7CiAgICAgICAgICBpZih0eXBlb2YgcmV0ID09PSAnb2JqZWN0JyAmJiAhZm9yZ2UudXRpbC5pc0FycmF5KHJldCkpIHsKICAgICAgICAgICAgLy8gdGhyb3cgY3VzdG9tIGVycm9yCiAgICAgICAgICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignVGhlIGFwcGxpY2F0aW9uIHJlamVjdGVkIHRoZSBjZXJ0aWZpY2F0ZS4nKTsKICAgICAgICAgICAgZXJyb3Iuc2VuZCA9IHRydWU7CiAgICAgICAgICAgIGVycm9yLmFsZXJ0ID0gewogICAgICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5iYWRfY2VydGlmaWNhdGUKICAgICAgICAgICAgfTsKICAgICAgICAgICAgaWYocmV0Lm1lc3NhZ2UpIHsKICAgICAgICAgICAgICBlcnJvci5tZXNzYWdlID0gcmV0Lm1lc3NhZ2U7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYocmV0LmFsZXJ0KSB7CiAgICAgICAgICAgICAgZXJyb3IuYWxlcnQuZGVzY3JpcHRpb24gPSByZXQuYWxlcnQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgICB9CgogICAgICAgICAgLy8gY29udmVydCB0bHMgYWxlcnQgZGVzY3JpcHRpb24gdG8gcGtpLmNlcnRpZmljYXRlRXJyb3IKICAgICAgICAgIGlmKHJldCAhPT0gdmZkKSB7CiAgICAgICAgICAgIHJldCA9IF9hbGVydERlc2NUb0NlcnRFcnJvcihyZXQpOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSk7CiAgfSBjYXRjaChleCkgewogICAgLy8gYnVpbGQgdGxzIGVycm9yIGlmIG5vdCBhbHJlYWR5IGN1c3RvbWl6ZWQKICAgIHZhciBlcnIgPSBleDsKICAgIGlmKHR5cGVvZiBlcnIgIT09ICdvYmplY3QnIHx8IGZvcmdlLnV0aWwuaXNBcnJheShlcnIpKSB7CiAgICAgIGVyciA9IHsKICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgIGFsZXJ0OiB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgICAgZGVzY3JpcHRpb246IF9jZXJ0RXJyb3JUb0FsZXJ0RGVzYyhleCkKICAgICAgICB9CiAgICAgIH07CiAgICB9CiAgICBpZighKCdzZW5kJyBpbiBlcnIpKSB7CiAgICAgIGVyci5zZW5kID0gdHJ1ZTsKICAgIH0KICAgIGlmKCEoJ2FsZXJ0JyBpbiBlcnIpKSB7CiAgICAgIGVyci5hbGVydCA9IHsKICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLmZhdGFsLAogICAgICAgIGRlc2NyaXB0aW9uOiBfY2VydEVycm9yVG9BbGVydERlc2MoZXJyLmVycm9yKQogICAgICB9OwogICAgfQoKICAgIC8vIHNlbmQgZXJyb3IKICAgIGMuZXJyb3IoYywgZXJyKTsKICB9CgogIHJldHVybiAhYy5mYWlsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgVExTIHNlc3Npb24gY2FjaGUuCiAqCiAqIEBwYXJhbSBjYWNoZSBvcHRpb25hbCBtYXAgb2Ygc2Vzc2lvbiBJRCB0byBjYWNoZWQgc2Vzc2lvbi4KICogQHBhcmFtIGNhcGFjaXR5IHRoZSBtYXhpbXVtIHNpemUgZm9yIHRoZSBjYWNoZSAoZGVmYXVsdDogMTAwKS4KICoKICogQHJldHVybiB0aGUgbmV3IFRMUyBzZXNzaW9uIGNhY2hlLgogKi8KdGxzLmNyZWF0ZVNlc3Npb25DYWNoZSA9IGZ1bmN0aW9uKGNhY2hlLCBjYXBhY2l0eSkgewogIHZhciBydmFsID0gbnVsbDsKCiAgLy8gYXNzdW1lIGlucHV0IGlzIGFscmVhZHkgYSBzZXNzaW9uIGNhY2hlIG9iamVjdAogIGlmKGNhY2hlICYmIGNhY2hlLmdldFNlc3Npb24gJiYgY2FjaGUuc2V0U2Vzc2lvbiAmJiBjYWNoZS5vcmRlcikgewogICAgcnZhbCA9IGNhY2hlOwogIH0gZWxzZSB7CiAgICAvLyBjcmVhdGUgY2FjaGUKICAgIHJ2YWwgPSB7fTsKICAgIHJ2YWwuY2FjaGUgPSBjYWNoZSB8fCB7fTsKICAgIHJ2YWwuY2FwYWNpdHkgPSBNYXRoLm1heChjYXBhY2l0eSB8fCAxMDAsIDEpOwogICAgcnZhbC5vcmRlciA9IFtdOwoKICAgIC8vIHN0b3JlIG9yZGVyIGZvciBzZXNzaW9ucywgZGVsZXRlIHNlc3Npb24gb3ZlcmZsb3cKICAgIGZvcih2YXIga2V5IGluIGNhY2hlKSB7CiAgICAgIGlmKHJ2YWwub3JkZXIubGVuZ3RoIDw9IGNhcGFjaXR5KSB7CiAgICAgICAgcnZhbC5vcmRlci5wdXNoKGtleSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVsZXRlIGNhY2hlW2tleV07CiAgICAgIH0KICAgIH0KCiAgICAvLyBnZXQgYSBzZXNzaW9uIGZyb20gYSBzZXNzaW9uIElEIChvciBnZXQgYW55IHNlc3Npb24pCiAgICBydmFsLmdldFNlc3Npb24gPSBmdW5jdGlvbihzZXNzaW9uSWQpIHsKICAgICAgdmFyIHNlc3Npb24gPSBudWxsOwogICAgICB2YXIga2V5ID0gbnVsbDsKCiAgICAgIC8vIGlmIHNlc3Npb24gSUQgcHJvdmlkZWQsIHVzZSBpdAogICAgICBpZihzZXNzaW9uSWQpIHsKICAgICAgICBrZXkgPSBmb3JnZS51dGlsLmJ5dGVzVG9IZXgoc2Vzc2lvbklkKTsKICAgICAgfSBlbHNlIGlmKHJ2YWwub3JkZXIubGVuZ3RoID4gMCkgewogICAgICAgIC8vIGdldCBmaXJzdCBzZXNzaW9uIGZyb20gY2FjaGUKICAgICAgICBrZXkgPSBydmFsLm9yZGVyWzBdOwogICAgICB9CgogICAgICBpZihrZXkgIT09IG51bGwgJiYga2V5IGluIHJ2YWwuY2FjaGUpIHsKICAgICAgICAvLyBnZXQgY2FjaGVkIHNlc3Npb24gYW5kIHJlbW92ZSBmcm9tIGNhY2hlCiAgICAgICAgc2Vzc2lvbiA9IHJ2YWwuY2FjaGVba2V5XTsKICAgICAgICBkZWxldGUgcnZhbC5jYWNoZVtrZXldOwogICAgICAgIGZvcih2YXIgaSBpbiBydmFsLm9yZGVyKSB7CiAgICAgICAgICBpZihydmFsLm9yZGVyW2ldID09PSBrZXkpIHsKICAgICAgICAgICAgcnZhbC5vcmRlci5zcGxpY2UoaSwgMSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQoKICAgICAgcmV0dXJuIHNlc3Npb247CiAgICB9OwoKICAgIC8vIHNldCBhIHNlc3Npb24gaW4gdGhlIGNhY2hlCiAgICBydmFsLnNldFNlc3Npb24gPSBmdW5jdGlvbihzZXNzaW9uSWQsIHNlc3Npb24pIHsKICAgICAgLy8gcmVtb3ZlIHNlc3Npb24gZnJvbSBjYWNoZSBpZiBhdCBjYXBhY2l0eQogICAgICBpZihydmFsLm9yZGVyLmxlbmd0aCA9PT0gcnZhbC5jYXBhY2l0eSkgewogICAgICAgIHZhciBrZXkgPSBydmFsLm9yZGVyLnNoaWZ0KCk7CiAgICAgICAgZGVsZXRlIHJ2YWwuY2FjaGVba2V5XTsKICAgICAgfQogICAgICAvLyBhZGQgc2Vzc2lvbiB0byBjYWNoZQogICAgICB2YXIga2V5ID0gZm9yZ2UudXRpbC5ieXRlc1RvSGV4KHNlc3Npb25JZCk7CiAgICAgIHJ2YWwub3JkZXIucHVzaChrZXkpOwogICAgICBydmFsLmNhY2hlW2tleV0gPSBzZXNzaW9uOwogICAgfTsKICB9CgogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgVExTIGNvbm5lY3Rpb24uCiAqCiAqIFNlZSBwdWJsaWMgY3JlYXRlQ29ubmVjdGlvbigpIGRvY3MgZm9yIG1vcmUgZGV0YWlscy4KICoKICogQHBhcmFtIG9wdGlvbnMgdGhlIG9wdGlvbnMgZm9yIHRoaXMgY29ubmVjdGlvbi4KICoKICogQHJldHVybiB0aGUgbmV3IFRMUyBjb25uZWN0aW9uLgogKi8KdGxzLmNyZWF0ZUNvbm5lY3Rpb24gPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgdmFyIGNhU3RvcmUgPSBudWxsOwogIGlmKG9wdGlvbnMuY2FTdG9yZSkgewogICAgLy8gaWYgQ0Egc3RvcmUgaXMgYW4gYXJyYXksIGNvbnZlcnQgaXQgdG8gYSBDQSBzdG9yZSBvYmplY3QKICAgIGlmKGZvcmdlLnV0aWwuaXNBcnJheShvcHRpb25zLmNhU3RvcmUpKSB7CiAgICAgIGNhU3RvcmUgPSBmb3JnZS5wa2kuY3JlYXRlQ2FTdG9yZShvcHRpb25zLmNhU3RvcmUpOwogICAgfSBlbHNlIHsKICAgICAgY2FTdG9yZSA9IG9wdGlvbnMuY2FTdG9yZTsKICAgIH0KICB9IGVsc2UgewogICAgLy8gY3JlYXRlIGVtcHR5IENBIHN0b3JlCiAgICBjYVN0b3JlID0gZm9yZ2UucGtpLmNyZWF0ZUNhU3RvcmUoKTsKICB9CgogIC8vIHNldHVwIGRlZmF1bHQgY2lwaGVyIHN1aXRlcwogIHZhciBjaXBoZXJTdWl0ZXMgPSBvcHRpb25zLmNpcGhlclN1aXRlcyB8fCBudWxsOwogIGlmKGNpcGhlclN1aXRlcyA9PT0gbnVsbCkgewogICAgY2lwaGVyU3VpdGVzID0gW107CiAgICBmb3IodmFyIGtleSBpbiB0bHMuQ2lwaGVyU3VpdGVzKSB7CiAgICAgIGNpcGhlclN1aXRlcy5wdXNoKHRscy5DaXBoZXJTdWl0ZXNba2V5XSk7CiAgICB9CiAgfQoKICAvLyBzZXQgZGVmYXVsdCBlbnRpdHkKICB2YXIgZW50aXR5ID0gKG9wdGlvbnMuc2VydmVyIHx8IGZhbHNlKSA/CiAgICB0bHMuQ29ubmVjdGlvbkVuZC5zZXJ2ZXIgOiB0bHMuQ29ubmVjdGlvbkVuZC5jbGllbnQ7CgogIC8vIGNyZWF0ZSBzZXNzaW9uIGNhY2hlIGlmIHJlcXVlc3RlZAogIHZhciBzZXNzaW9uQ2FjaGUgPSBvcHRpb25zLnNlc3Npb25DYWNoZSA/CiAgICB0bHMuY3JlYXRlU2Vzc2lvbkNhY2hlKG9wdGlvbnMuc2Vzc2lvbkNhY2hlKSA6IG51bGw7CgogIC8vIGNyZWF0ZSBUTFMgY29ubmVjdGlvbgogIHZhciBjID0gewogICAgdmVyc2lvbjoge21ham9yOiB0bHMuVmVyc2lvbi5tYWpvciwgbWlub3I6IHRscy5WZXJzaW9uLm1pbm9yfSwKICAgIGVudGl0eTogZW50aXR5LAogICAgc2Vzc2lvbklkOiBvcHRpb25zLnNlc3Npb25JZCwKICAgIGNhU3RvcmU6IGNhU3RvcmUsCiAgICBzZXNzaW9uQ2FjaGU6IHNlc3Npb25DYWNoZSwKICAgIGNpcGhlclN1aXRlczogY2lwaGVyU3VpdGVzLAogICAgY29ubmVjdGVkOiBvcHRpb25zLmNvbm5lY3RlZCwKICAgIHZpcnR1YWxIb3N0OiBvcHRpb25zLnZpcnR1YWxIb3N0IHx8IG51bGwsCiAgICB2ZXJpZnlDbGllbnQ6IG9wdGlvbnMudmVyaWZ5Q2xpZW50IHx8IGZhbHNlLAogICAgdmVyaWZ5OiBvcHRpb25zLnZlcmlmeSB8fCBmdW5jdGlvbihjbiwgdmZkLCBkcHRoLCBjdHMpIHtyZXR1cm4gdmZkO30sCiAgICBnZXRDZXJ0aWZpY2F0ZTogb3B0aW9ucy5nZXRDZXJ0aWZpY2F0ZSB8fCBudWxsLAogICAgZ2V0UHJpdmF0ZUtleTogb3B0aW9ucy5nZXRQcml2YXRlS2V5IHx8IG51bGwsCiAgICBnZXRTaWduYXR1cmU6IG9wdGlvbnMuZ2V0U2lnbmF0dXJlIHx8IG51bGwsCiAgICBpbnB1dDogZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKSwKICAgIHRsc0RhdGE6IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCksCiAgICBkYXRhOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpLAogICAgdGxzRGF0YVJlYWR5OiBvcHRpb25zLnRsc0RhdGFSZWFkeSwKICAgIGRhdGFSZWFkeTogb3B0aW9ucy5kYXRhUmVhZHksCiAgICBoZWFydGJlYXRSZWNlaXZlZDogb3B0aW9ucy5oZWFydGJlYXRSZWNlaXZlZCwKICAgIGNsb3NlZDogb3B0aW9ucy5jbG9zZWQsCiAgICBlcnJvcjogZnVuY3Rpb24oYywgZXgpIHsKICAgICAgLy8gc2V0IG9yaWdpbiBpZiBub3Qgc2V0CiAgICAgIGV4Lm9yaWdpbiA9IGV4Lm9yaWdpbiB8fAogICAgICAgICgoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCkgPyAnY2xpZW50JyA6ICdzZXJ2ZXInKTsKCiAgICAgIC8vIHNlbmQgVExTIGFsZXJ0CiAgICAgIGlmKGV4LnNlbmQpIHsKICAgICAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZUFsZXJ0KGMsIGV4LmFsZXJ0KSk7CiAgICAgICAgdGxzLmZsdXNoKGMpOwogICAgICB9CgogICAgICAvLyBlcnJvciBpcyBmYXRhbCBieSBkZWZhdWx0CiAgICAgIHZhciBmYXRhbCA9IChleC5mYXRhbCAhPT0gZmFsc2UpOwogICAgICBpZihmYXRhbCkgewogICAgICAgIC8vIHNldCBmYWlsIGZsYWcKICAgICAgICBjLmZhaWwgPSB0cnVlOwogICAgICB9CgogICAgICAvLyBjYWxsIGVycm9yIGhhbmRsZXIgZmlyc3QKICAgICAgb3B0aW9ucy5lcnJvcihjLCBleCk7CgogICAgICBpZihmYXRhbCkgewogICAgICAgIC8vIGZhdGFsIGVycm9yLCBjbG9zZSBjb25uZWN0aW9uLCBkbyBub3QgY2xlYXIgZmFpbAogICAgICAgIGMuY2xvc2UoZmFsc2UpOwogICAgICB9CiAgICB9LAogICAgZGVmbGF0ZTogb3B0aW9ucy5kZWZsYXRlIHx8IG51bGwsCiAgICBpbmZsYXRlOiBvcHRpb25zLmluZmxhdGUgfHwgbnVsbAogIH07CgogIC8qKgogICAqIFJlc2V0cyBhIGNsb3NlZCBUTFMgY29ubmVjdGlvbiBmb3IgcmV1c2UuIENhbGxlZCBpbiBjLmNsb3NlKCkuCiAgICoKICAgKiBAcGFyYW0gY2xlYXJGYWlsIHRydWUgdG8gY2xlYXIgdGhlIGZhaWwgZmxhZyAoZGVmYXVsdDogdHJ1ZSkuCiAgICovCiAgYy5yZXNldCA9IGZ1bmN0aW9uKGNsZWFyRmFpbCkgewogICAgYy52ZXJzaW9uID0ge21ham9yOiB0bHMuVmVyc2lvbi5tYWpvciwgbWlub3I6IHRscy5WZXJzaW9uLm1pbm9yfTsKICAgIGMucmVjb3JkID0gbnVsbDsKICAgIGMuc2Vzc2lvbiA9IG51bGw7CiAgICBjLnBlZXJDZXJ0aWZpY2F0ZSA9IG51bGw7CiAgICBjLnN0YXRlID0gewogICAgICBwZW5kaW5nOiBudWxsLAogICAgICBjdXJyZW50OiBudWxsCiAgICB9OwogICAgYy5leHBlY3QgPSAoYy5lbnRpdHkgPT09IHRscy5Db25uZWN0aW9uRW5kLmNsaWVudCkgPyBTSEUgOiBDSEU7CiAgICBjLmZyYWdtZW50ZWQgPSBudWxsOwogICAgYy5yZWNvcmRzID0gW107CiAgICBjLm9wZW4gPSBmYWxzZTsKICAgIGMuaGFuZHNoYWtlcyA9IDA7CiAgICBjLmhhbmRzaGFraW5nID0gZmFsc2U7CiAgICBjLmlzQ29ubmVjdGVkID0gZmFsc2U7CiAgICBjLmZhaWwgPSAhKGNsZWFyRmFpbCB8fCB0eXBlb2YoY2xlYXJGYWlsKSA9PT0gJ3VuZGVmaW5lZCcpOwogICAgYy5pbnB1dC5jbGVhcigpOwogICAgYy50bHNEYXRhLmNsZWFyKCk7CiAgICBjLmRhdGEuY2xlYXIoKTsKICAgIGMuc3RhdGUuY3VycmVudCA9IHRscy5jcmVhdGVDb25uZWN0aW9uU3RhdGUoYyk7CiAgfTsKCiAgLy8gZG8gaW5pdGlhbCByZXNldCBvZiBjb25uZWN0aW9uCiAgYy5yZXNldCgpOwoKICAvKioKICAgKiBVcGRhdGVzIHRoZSBjdXJyZW50IFRMUyBlbmdpbmUgc3RhdGUgYmFzZWQgb24gdGhlIGdpdmVuIHJlY29yZC4KICAgKgogICAqIEBwYXJhbSBjIHRoZSBUTFMgY29ubmVjdGlvbi4KICAgKiBAcGFyYW0gcmVjb3JkIHRoZSBUTFMgcmVjb3JkIHRvIGFjdCBvbi4KICAgKi8KICB2YXIgX3VwZGF0ZSA9IGZ1bmN0aW9uKGMsIHJlY29yZCkgewogICAgLy8gZ2V0IHJlY29yZCBoYW5kbGVyIChhbGlnbiB0eXBlIGluIHRhYmxlIGJ5IHN1YnRyYWN0aW5nIGxvd2VzdCkKICAgIHZhciBhbGlnbmVkID0gcmVjb3JkLnR5cGUgLSB0bHMuQ29udGVudFR5cGUuY2hhbmdlX2NpcGhlcl9zcGVjOwogICAgdmFyIGhhbmRsZXJzID0gY3RUYWJsZVtjLmVudGl0eV1bYy5leHBlY3RdOwogICAgaWYoYWxpZ25lZCBpbiBoYW5kbGVycykgewogICAgICBoYW5kbGVyc1thbGlnbmVkXShjLCByZWNvcmQpOwogICAgfSBlbHNlIHsKICAgICAgLy8gdW5leHBlY3RlZCByZWNvcmQKICAgICAgdGxzLmhhbmRsZVVuZXhwZWN0ZWQoYywgcmVjb3JkKTsKICAgIH0KICB9OwoKICAvKioKICAgKiBSZWFkcyB0aGUgcmVjb3JkIGhlYWRlciBhbmQgaW5pdGlhbGl6ZXMgdGhlIG5leHQgcmVjb3JkIG9uIHRoZSBnaXZlbgogICAqIGNvbm5lY3Rpb24uCiAgICoKICAgKiBAcGFyYW0gYyB0aGUgVExTIGNvbm5lY3Rpb24gd2l0aCB0aGUgbmV4dCByZWNvcmQuCiAgICoKICAgKiBAcmV0dXJuIDAgaWYgdGhlIGlucHV0IGRhdGEgY291bGQgYmUgcHJvY2Vzc2VkLCBvdGhlcndpc2UgdGhlCiAgICogICAgICAgICBudW1iZXIgb2YgYnl0ZXMgcmVxdWlyZWQgZm9yIGRhdGEgdG8gYmUgcHJvY2Vzc2VkLgogICAqLwogIHZhciBfcmVhZFJlY29yZEhlYWRlciA9IGZ1bmN0aW9uKGMpIHsKICAgIHZhciBydmFsID0gMDsKCiAgICAvLyBnZXQgaW5wdXQgYnVmZmVyIGFuZCBpdHMgbGVuZ3RoCiAgICB2YXIgYiA9IGMuaW5wdXQ7CiAgICB2YXIgbGVuID0gYi5sZW5ndGgoKTsKCiAgICAvLyBuZWVkIGF0IGxlYXN0IDUgYnl0ZXMgdG8gaW5pdGlhbGl6ZSBhIHJlY29yZAogICAgaWYobGVuIDwgNSkgewogICAgICBydmFsID0gNSAtIGxlbjsKICAgIH0gZWxzZSB7CiAgICAgIC8vIGVub3VnaCBieXRlcyBmb3IgaGVhZGVyCiAgICAgIC8vIGluaXRpYWxpemUgcmVjb3JkCiAgICAgIGMucmVjb3JkID0gewogICAgICAgIHR5cGU6IGIuZ2V0Qnl0ZSgpLAogICAgICAgIHZlcnNpb246IHsKICAgICAgICAgIG1ham9yOiBiLmdldEJ5dGUoKSwKICAgICAgICAgIG1pbm9yOiBiLmdldEJ5dGUoKQogICAgICAgIH0sCiAgICAgICAgbGVuZ3RoOiBiLmdldEludDE2KCksCiAgICAgICAgZnJhZ21lbnQ6IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCksCiAgICAgICAgcmVhZHk6IGZhbHNlCiAgICAgIH07CgogICAgICAvLyBjaGVjayByZWNvcmQgdmVyc2lvbgogICAgICB2YXIgY29tcGF0aWJsZVZlcnNpb24gPSAoYy5yZWNvcmQudmVyc2lvbi5tYWpvciA9PT0gYy52ZXJzaW9uLm1ham9yKTsKICAgICAgaWYoY29tcGF0aWJsZVZlcnNpb24gJiYgYy5zZXNzaW9uICYmIGMuc2Vzc2lvbi52ZXJzaW9uKSB7CiAgICAgICAgLy8gc2Vzc2lvbiB2ZXJzaW9uIGFscmVhZHkgc2V0LCByZXF1aXJlIHNhbWUgbWlub3IgdmVyc2lvbgogICAgICAgIGNvbXBhdGlibGVWZXJzaW9uID0gKGMucmVjb3JkLnZlcnNpb24ubWlub3IgPT09IGMudmVyc2lvbi5taW5vcik7CiAgICAgIH0KICAgICAgaWYoIWNvbXBhdGlibGVWZXJzaW9uKSB7CiAgICAgICAgYy5lcnJvcihjLCB7CiAgICAgICAgICBtZXNzYWdlOiAnSW5jb21wYXRpYmxlIFRMUyB2ZXJzaW9uLicsCiAgICAgICAgICBzZW5kOiB0cnVlLAogICAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgICAgbGV2ZWw6IHRscy5BbGVydC5MZXZlbC5mYXRhbCwKICAgICAgICAgICAgZGVzY3JpcHRpb246IHRscy5BbGVydC5EZXNjcmlwdGlvbi5wcm90b2NvbF92ZXJzaW9uCiAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAvKioKICAgKiBSZWFkcyB0aGUgbmV4dCByZWNvcmQncyBjb250ZW50cyBhbmQgYXBwZW5kcyBpdHMgbWVzc2FnZSB0byBhbnkKICAgKiBwcmV2aW91c2x5IGZyYWdtZW50ZWQgbWVzc2FnZS4KICAgKgogICAqIEBwYXJhbSBjIHRoZSBUTFMgY29ubmVjdGlvbiB3aXRoIHRoZSBuZXh0IHJlY29yZC4KICAgKgogICAqIEByZXR1cm4gMCBpZiB0aGUgaW5wdXQgZGF0YSBjb3VsZCBiZSBwcm9jZXNzZWQsIG90aGVyd2lzZSB0aGUKICAgKiAgICAgICAgIG51bWJlciBvZiBieXRlcyByZXF1aXJlZCBmb3IgZGF0YSB0byBiZSBwcm9jZXNzZWQuCiAgICovCiAgdmFyIF9yZWFkUmVjb3JkID0gZnVuY3Rpb24oYykgewogICAgdmFyIHJ2YWwgPSAwOwoKICAgIC8vIGVuc3VyZSB0aGVyZSBpcyBlbm91Z2ggaW5wdXQgZGF0YSB0byBnZXQgdGhlIGVudGlyZSByZWNvcmQKICAgIHZhciBiID0gYy5pbnB1dDsKICAgIHZhciBsZW4gPSBiLmxlbmd0aCgpOwogICAgaWYobGVuIDwgYy5yZWNvcmQubGVuZ3RoKSB7CiAgICAgIC8vIG5vdCBlbm91Z2ggZGF0YSB5ZXQsIHJldHVybiBob3cgbXVjaCBpcyByZXF1aXJlZAogICAgICBydmFsID0gYy5yZWNvcmQubGVuZ3RoIC0gbGVuOwogICAgfSBlbHNlIHsKICAgICAgLy8gdGhlcmUgaXMgZW5vdWdoIGRhdGEgdG8gcGFyc2UgdGhlIHBlbmRpbmcgcmVjb3JkCiAgICAgIC8vIGZpbGwgcmVjb3JkIGZyYWdtZW50IGFuZCBjb21wYWN0IGlucHV0IGJ1ZmZlcgogICAgICBjLnJlY29yZC5mcmFnbWVudC5wdXRCeXRlcyhiLmdldEJ5dGVzKGMucmVjb3JkLmxlbmd0aCkpOwogICAgICBiLmNvbXBhY3QoKTsKCiAgICAgIC8vIHVwZGF0ZSByZWNvcmQgdXNpbmcgY3VycmVudCByZWFkIHN0YXRlCiAgICAgIHZhciBzID0gYy5zdGF0ZS5jdXJyZW50LnJlYWQ7CiAgICAgIGlmKHMudXBkYXRlKGMsIGMucmVjb3JkKSkgewogICAgICAgIC8vIHNlZSBpZiB0aGVyZSBpcyBhIHByZXZpb3VzbHkgZnJhZ21lbnRlZCBtZXNzYWdlIHRoYXQgdGhlCiAgICAgICAgLy8gbmV3IHJlY29yZCdzIG1lc3NhZ2UgZnJhZ21lbnQgc2hvdWxkIGJlIGFwcGVuZGVkIHRvCiAgICAgICAgaWYoYy5mcmFnbWVudGVkICE9PSBudWxsKSB7CiAgICAgICAgICAvLyBpZiB0aGUgcmVjb3JkIHR5cGUgbWF0Y2hlcyBhIHByZXZpb3VzbHkgZnJhZ21lbnRlZAogICAgICAgICAgLy8gcmVjb3JkLCBhcHBlbmQgdGhlIHJlY29yZCBmcmFnbWVudCB0byBpdAogICAgICAgICAgaWYoYy5mcmFnbWVudGVkLnR5cGUgPT09IGMucmVjb3JkLnR5cGUpIHsKICAgICAgICAgICAgLy8gY29uY2F0ZW5hdGUgcmVjb3JkIGZyYWdtZW50cwogICAgICAgICAgICBjLmZyYWdtZW50ZWQuZnJhZ21lbnQucHV0QnVmZmVyKGMucmVjb3JkLmZyYWdtZW50KTsKICAgICAgICAgICAgYy5yZWNvcmQgPSBjLmZyYWdtZW50ZWQ7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvLyBlcnJvciwgaW52YWxpZCBmcmFnbWVudGVkIHJlY29yZAogICAgICAgICAgICBjLmVycm9yKGMsIHsKICAgICAgICAgICAgICBtZXNzYWdlOiAnSW52YWxpZCBmcmFnbWVudGVkIHJlY29yZC4nLAogICAgICAgICAgICAgIHNlbmQ6IHRydWUsCiAgICAgICAgICAgICAgYWxlcnQ6IHsKICAgICAgICAgICAgICAgIGxldmVsOiB0bHMuQWxlcnQuTGV2ZWwuZmF0YWwsCiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjoKICAgICAgICAgICAgICAgICAgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLnVuZXhwZWN0ZWRfbWVzc2FnZQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyByZWNvcmQgaXMgbm93IHJlYWR5CiAgICAgICAgYy5yZWNvcmQucmVhZHkgPSB0cnVlOwogICAgICB9CiAgICB9CgogICAgcmV0dXJuIHJ2YWw7CiAgfTsKCiAgLyoqCiAgICogUGVyZm9ybXMgYSBoYW5kc2hha2UgdXNpbmcgdGhlIFRMUyBIYW5kc2hha2UgUHJvdG9jb2wsIGFzIGEgY2xpZW50LgogICAqCiAgICogVGhpcyBtZXRob2Qgc2hvdWxkIG9ubHkgYmUgY2FsbGVkIGlmIHRoZSBjb25uZWN0aW9uIGlzIGluIGNsaWVudCBtb2RlLgogICAqCiAgICogQHBhcmFtIHNlc3Npb25JZCB0aGUgc2Vzc2lvbiBJRCB0byB1c2UsIG51bGwgdG8gc3RhcnQgYSBuZXcgb25lLgogICAqLwogIGMuaGFuZHNoYWtlID0gZnVuY3Rpb24oc2Vzc2lvbklkKSB7CiAgICAvLyBlcnJvciB0byBjYWxsIHRoaXMgaW4gbm9uLWNsaWVudCBtb2RlCiAgICBpZihjLmVudGl0eSAhPT0gdGxzLkNvbm5lY3Rpb25FbmQuY2xpZW50KSB7CiAgICAgIC8vIG5vdCBmYXRhbCBlcnJvcgogICAgICBjLmVycm9yKGMsIHsKICAgICAgICBtZXNzYWdlOiAnQ2Fubm90IGluaXRpYXRlIGhhbmRzaGFrZSBhcyBhIHNlcnZlci4nLAogICAgICAgIGZhdGFsOiBmYWxzZQogICAgICB9KTsKICAgIH0gZWxzZSBpZihjLmhhbmRzaGFraW5nKSB7CiAgICAgIC8vIGhhbmRzaGFrZSBpcyBhbHJlYWR5IGluIHByb2dyZXNzLCBmYWlsIGJ1dCBub3QgZmF0YWwgZXJyb3IKICAgICAgYy5lcnJvcihjLCB7CiAgICAgICAgbWVzc2FnZTogJ0hhbmRzaGFrZSBhbHJlYWR5IGluIHByb2dyZXNzLicsCiAgICAgICAgZmF0YWw6IGZhbHNlCiAgICAgIH0pOwogICAgfSBlbHNlIHsKICAgICAgLy8gY2xlYXIgZmFpbCBmbGFnIG9uIHJldXNlCiAgICAgIGlmKGMuZmFpbCAmJiAhYy5vcGVuICYmIGMuaGFuZHNoYWtlcyA9PT0gMCkgewogICAgICAgIGMuZmFpbCA9IGZhbHNlOwogICAgICB9CgogICAgICAvLyBub3cgaGFuZHNoYWtpbmcKICAgICAgYy5oYW5kc2hha2luZyA9IHRydWU7CgogICAgICAvLyBkZWZhdWx0IHRvIGJsYW5rIChuZXcgc2Vzc2lvbikKICAgICAgc2Vzc2lvbklkID0gc2Vzc2lvbklkIHx8ICcnOwoKICAgICAgLy8gaWYgYSBzZXNzaW9uIElEIHdhcyBzcGVjaWZpZWQsIHRyeSB0byBmaW5kIGl0IGluIHRoZSBjYWNoZQogICAgICB2YXIgc2Vzc2lvbiA9IG51bGw7CiAgICAgIGlmKHNlc3Npb25JZC5sZW5ndGggPiAwKSB7CiAgICAgICAgaWYoYy5zZXNzaW9uQ2FjaGUpIHsKICAgICAgICAgIHNlc3Npb24gPSBjLnNlc3Npb25DYWNoZS5nZXRTZXNzaW9uKHNlc3Npb25JZCk7CiAgICAgICAgfQoKICAgICAgICAvLyBtYXRjaGluZyBzZXNzaW9uIG5vdCBmb3VuZCBpbiBjYWNoZSwgY2xlYXIgc2Vzc2lvbiBJRAogICAgICAgIGlmKHNlc3Npb24gPT09IG51bGwpIHsKICAgICAgICAgIHNlc3Npb25JZCA9ICcnOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gbm8gc2Vzc2lvbiBnaXZlbiwgZ3JhYiBhIHNlc3Npb24gZnJvbSB0aGUgY2FjaGUsIGlmIGF2YWlsYWJsZQogICAgICBpZihzZXNzaW9uSWQubGVuZ3RoID09PSAwICYmIGMuc2Vzc2lvbkNhY2hlKSB7CiAgICAgICAgc2Vzc2lvbiA9IGMuc2Vzc2lvbkNhY2hlLmdldFNlc3Npb24oKTsKICAgICAgICBpZihzZXNzaW9uICE9PSBudWxsKSB7CiAgICAgICAgICBzZXNzaW9uSWQgPSBzZXNzaW9uLmlkOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gc2V0IHVwIHNlc3Npb24KICAgICAgYy5zZXNzaW9uID0gewogICAgICAgIGlkOiBzZXNzaW9uSWQsCiAgICAgICAgdmVyc2lvbjogbnVsbCwKICAgICAgICBjaXBoZXJTdWl0ZTogbnVsbCwKICAgICAgICBjb21wcmVzc2lvbk1ldGhvZDogbnVsbCwKICAgICAgICBzZXJ2ZXJDZXJ0aWZpY2F0ZTogbnVsbCwKICAgICAgICBjZXJ0aWZpY2F0ZVJlcXVlc3Q6IG51bGwsCiAgICAgICAgY2xpZW50Q2VydGlmaWNhdGU6IG51bGwsCiAgICAgICAgc3A6IHt9LAogICAgICAgIG1kNTogZm9yZ2UubWQubWQ1LmNyZWF0ZSgpLAogICAgICAgIHNoYTE6IGZvcmdlLm1kLnNoYTEuY3JlYXRlKCkKICAgICAgfTsKCiAgICAgIC8vIHVzZSBleGlzdGluZyBzZXNzaW9uIGluZm9ybWF0aW9uCiAgICAgIGlmKHNlc3Npb24pIHsKICAgICAgICAvLyBvbmx5IHVwZGF0ZSB2ZXJzaW9uIG9uIGNvbm5lY3Rpb24sIHNlc3Npb24gdmVyc2lvbiBub3QgeWV0IHNldAogICAgICAgIGMudmVyc2lvbiA9IHNlc3Npb24udmVyc2lvbjsKICAgICAgICBjLnNlc3Npb24uc3AgPSBzZXNzaW9uLnNwOwogICAgICB9CgogICAgICAvLyBnZW5lcmF0ZSBuZXcgY2xpZW50IHJhbmRvbQogICAgICBjLnNlc3Npb24uc3AuY2xpZW50X3JhbmRvbSA9IHRscy5jcmVhdGVSYW5kb20oKS5nZXRCeXRlcygpOwoKICAgICAgLy8gY29ubmVjdGlvbiBub3cgb3BlbgogICAgICBjLm9wZW4gPSB0cnVlOwoKICAgICAgLy8gc2VuZCBoZWxsbwogICAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgICAgdHlwZTogdGxzLkNvbnRlbnRUeXBlLmhhbmRzaGFrZSwKICAgICAgICBkYXRhOiB0bHMuY3JlYXRlQ2xpZW50SGVsbG8oYykKICAgICAgfSkpOwogICAgICB0bHMuZmx1c2goYyk7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogQ2FsbGVkIHdoZW4gVExTIHByb3RvY29sIGRhdGEgaGFzIGJlZW4gcmVjZWl2ZWQgZnJvbSBzb21ld2hlcmUgYW5kIHNob3VsZAogICAqIGJlIHByb2Nlc3NlZCBieSB0aGUgVExTIGVuZ2luZS4KICAgKgogICAqIEBwYXJhbSBkYXRhIHRoZSBUTFMgcHJvdG9jb2wgZGF0YSwgYXMgYSBzdHJpbmcsIHRvIHByb2Nlc3MuCiAgICoKICAgKiBAcmV0dXJuIDAgaWYgdGhlIGRhdGEgY291bGQgYmUgcHJvY2Vzc2VkLCBvdGhlcndpc2UgdGhlIG51bWJlciBvZiBieXRlcwogICAqICAgICAgICAgcmVxdWlyZWQgZm9yIGRhdGEgdG8gYmUgcHJvY2Vzc2VkLgogICAqLwogIGMucHJvY2VzcyA9IGZ1bmN0aW9uKGRhdGEpIHsKICAgIHZhciBydmFsID0gMDsKCiAgICAvLyBidWZmZXIgaW5wdXQgZGF0YQogICAgaWYoZGF0YSkgewogICAgICBjLmlucHV0LnB1dEJ5dGVzKGRhdGEpOwogICAgfQoKICAgIC8vIHByb2Nlc3MgbmV4dCByZWNvcmQgaWYgbm8gZmFpbHVyZSwgcHJvY2VzcyB3aWxsIGJlIGNhbGxlZCBhZnRlcgogICAgLy8gZWFjaCByZWNvcmQgaXMgaGFuZGxlZCAoc2luY2UgaGFuZGxpbmcgY2FuIGJlIGFzeW5jaHJvbm91cykKICAgIGlmKCFjLmZhaWwpIHsKICAgICAgLy8gcmVzZXQgcmVjb3JkIGlmIHJlYWR5IGFuZCBub3cgZW1wdHkKICAgICAgaWYoYy5yZWNvcmQgIT09IG51bGwgJiYKICAgICAgICBjLnJlY29yZC5yZWFkeSAmJiBjLnJlY29yZC5mcmFnbWVudC5pc0VtcHR5KCkpIHsKICAgICAgICBjLnJlY29yZCA9IG51bGw7CiAgICAgIH0KCiAgICAgIC8vIGlmIHRoZXJlIGlzIG5vIHBlbmRpbmcgcmVjb3JkLCB0cnkgdG8gcmVhZCByZWNvcmQgaGVhZGVyCiAgICAgIGlmKGMucmVjb3JkID09PSBudWxsKSB7CiAgICAgICAgcnZhbCA9IF9yZWFkUmVjb3JkSGVhZGVyKGMpOwogICAgICB9CgogICAgICAvLyByZWFkIHRoZSBuZXh0IHJlY29yZCAoaWYgcmVjb3JkIG5vdCB5ZXQgcmVhZHkpCiAgICAgIGlmKCFjLmZhaWwgJiYgYy5yZWNvcmQgIT09IG51bGwgJiYgIWMucmVjb3JkLnJlYWR5KSB7CiAgICAgICAgcnZhbCA9IF9yZWFkUmVjb3JkKGMpOwogICAgICB9CgogICAgICAvLyByZWNvcmQgcmVhZHkgdG8gYmUgaGFuZGxlZCwgdXBkYXRlIGVuZ2luZSBzdGF0ZQogICAgICBpZighYy5mYWlsICYmIGMucmVjb3JkICE9PSBudWxsICYmIGMucmVjb3JkLnJlYWR5KSB7CiAgICAgICAgX3VwZGF0ZShjLCBjLnJlY29yZCk7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcnZhbDsKICB9OwoKICAvKioKICAgKiBSZXF1ZXN0cyB0aGF0IGFwcGxpY2F0aW9uIGRhdGEgYmUgcGFja2FnZWQgaW50byBhIFRMUyByZWNvcmQuIFRoZQogICAqIHRsc0RhdGFSZWFkeSBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkIHdoZW4gdGhlIFRMUyByZWNvcmQocykgaGF2ZSBiZWVuCiAgICogcHJlcGFyZWQuCiAgICoKICAgKiBAcGFyYW0gZGF0YSB0aGUgYXBwbGljYXRpb24gZGF0YSwgYXMgYSByYXcgJ2JpbmFyeScgZW5jb2RlZCBzdHJpbmcsIHRvCiAgICogICAgICAgICAgYmUgc2VudDsgdG8gc2VuZCB1dGYtMTYvdXRmLTggc3RyaW5nIGRhdGEsIHVzZSB0aGUgcmV0dXJuIHZhbHVlCiAgICogICAgICAgICAgb2YgdXRpbC5lbmNvZGVVdGY4KHN0cikuCiAgICoKICAgKiBAcmV0dXJuIHRydWUgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZS4KICAgKi8KICBjLnByZXBhcmUgPSBmdW5jdGlvbihkYXRhKSB7CiAgICB0bHMucXVldWUoYywgdGxzLmNyZWF0ZVJlY29yZChjLCB7CiAgICAgIHR5cGU6IHRscy5Db250ZW50VHlwZS5hcHBsaWNhdGlvbl9kYXRhLAogICAgICBkYXRhOiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihkYXRhKQogICAgfSkpOwogICAgcmV0dXJuIHRscy5mbHVzaChjKTsKICB9OwoKICAvKioKICAgKiBSZXF1ZXN0cyB0aGF0IGEgaGVhcnRiZWF0IHJlcXVlc3QgYmUgcGFja2FnZWQgaW50byBhIFRMUyByZWNvcmQgZm9yCiAgICogdHJhbnNtaXNzaW9uLiBUaGUgdGxzRGF0YVJlYWR5IGhhbmRsZXIgd2lsbCBiZSBjYWxsZWQgd2hlbiBUTFMgcmVjb3JkKHMpCiAgICogaGF2ZSBiZWVuIHByZXBhcmVkLgogICAqCiAgICogV2hlbiBhIGhlYXJ0YmVhdCByZXNwb25zZSBoYXMgYmVlbiByZWNlaXZlZCwgdGhlIGhlYXJ0YmVhdFJlY2VpdmVkCiAgICogaGFuZGxlciB3aWxsIGJlIGNhbGxlZCB3aXRoIHRoZSBtYXRjaGluZyBwYXlsb2FkLiBUaGlzIGhhbmRsZXIgY2FuCiAgICogYmUgdXNlZCB0byBjbGVhciBhIHJldHJhbnNtaXNzaW9uIHRpbWVyLCBldGMuCiAgICoKICAgKiBAcGFyYW0gcGF5bG9hZCB0aGUgaGVhcnRiZWF0IGRhdGEgdG8gc2VuZCBhcyB0aGUgcGF5bG9hZCBpbiB0aGUgbWVzc2FnZS4KICAgKiBAcGFyYW0gW3BheWxvYWRMZW5ndGhdIHRoZSBwYXlsb2FkIGxlbmd0aCB0byB1c2UsIGRlZmF1bHRzIHRvIHRoZQogICAqICAgICAgICAgIGFjdHVhbCBwYXlsb2FkIGxlbmd0aC4KICAgKgogICAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogICAqLwogIGMucHJlcGFyZUhlYXJ0YmVhdFJlcXVlc3QgPSBmdW5jdGlvbihwYXlsb2FkLCBwYXlsb2FkTGVuZ3RoKSB7CiAgICBpZihwYXlsb2FkIGluc3RhbmNlb2YgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKSB7CiAgICAgIHBheWxvYWQgPSBwYXlsb2FkLmJ5dGVzKCk7CiAgICB9CiAgICBpZih0eXBlb2YgcGF5bG9hZExlbmd0aCA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgcGF5bG9hZExlbmd0aCA9IHBheWxvYWQubGVuZ3RoOwogICAgfQogICAgYy5leHBlY3RlZEhlYXJ0YmVhdFBheWxvYWQgPSBwYXlsb2FkOwogICAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVSZWNvcmQoYywgewogICAgICB0eXBlOiB0bHMuQ29udGVudFR5cGUuaGVhcnRiZWF0LAogICAgICBkYXRhOiB0bHMuY3JlYXRlSGVhcnRiZWF0KAogICAgICAgIHRscy5IZWFydGJlYXRNZXNzYWdlVHlwZS5oZWFydGJlYXRfcmVxdWVzdCwgcGF5bG9hZCwgcGF5bG9hZExlbmd0aCkKICAgIH0pKTsKICAgIHJldHVybiB0bHMuZmx1c2goYyk7CiAgfTsKCiAgLyoqCiAgICogQ2xvc2VzIHRoZSBjb25uZWN0aW9uIChzZW5kcyBhIGNsb3NlX25vdGlmeSBhbGVydCkuCiAgICoKICAgKiBAcGFyYW0gY2xlYXJGYWlsIHRydWUgdG8gY2xlYXIgdGhlIGZhaWwgZmxhZyAoZGVmYXVsdDogdHJ1ZSkuCiAgICovCiAgYy5jbG9zZSA9IGZ1bmN0aW9uKGNsZWFyRmFpbCkgewogICAgLy8gc2F2ZSBzZXNzaW9uIGlmIGNvbm5lY3Rpb24gZGlkbid0IGZhaWwKICAgIGlmKCFjLmZhaWwgJiYgYy5zZXNzaW9uQ2FjaGUgJiYgYy5zZXNzaW9uKSB7CiAgICAgIC8vIG9ubHkgbmVlZCB0byBwcmVzZXJ2ZSBzZXNzaW9uIElELCB2ZXJzaW9uLCBhbmQgc2VjdXJpdHkgcGFyYW1zCiAgICAgIHZhciBzZXNzaW9uID0gewogICAgICAgIGlkOiBjLnNlc3Npb24uaWQsCiAgICAgICAgdmVyc2lvbjogYy5zZXNzaW9uLnZlcnNpb24sCiAgICAgICAgc3A6IGMuc2Vzc2lvbi5zcAogICAgICB9OwogICAgICBzZXNzaW9uLnNwLmtleXMgPSBudWxsOwogICAgICBjLnNlc3Npb25DYWNoZS5zZXRTZXNzaW9uKHNlc3Npb24uaWQsIHNlc3Npb24pOwogICAgfQoKICAgIGlmKGMub3BlbikgewogICAgICAvLyBjb25uZWN0aW9uIG5vIGxvbmdlciBvcGVuLCBjbGVhciBpbnB1dAogICAgICBjLm9wZW4gPSBmYWxzZTsKICAgICAgYy5pbnB1dC5jbGVhcigpOwoKICAgICAgLy8gaWYgY29ubmVjdGVkIG9yIGhhbmRzaGFraW5nLCBzZW5kIGFuIGFsZXJ0CiAgICAgIGlmKGMuaXNDb25uZWN0ZWQgfHwgYy5oYW5kc2hha2luZykgewogICAgICAgIGMuaXNDb25uZWN0ZWQgPSBjLmhhbmRzaGFraW5nID0gZmFsc2U7CgogICAgICAgIC8vIHNlbmQgY2xvc2Vfbm90aWZ5IGFsZXJ0CiAgICAgICAgdGxzLnF1ZXVlKGMsIHRscy5jcmVhdGVBbGVydChjLCB7CiAgICAgICAgICBsZXZlbDogdGxzLkFsZXJ0LkxldmVsLndhcm5pbmcsCiAgICAgICAgICBkZXNjcmlwdGlvbjogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uLmNsb3NlX25vdGlmeQogICAgICAgIH0pKTsKICAgICAgICB0bHMuZmx1c2goYyk7CiAgICAgIH0KCiAgICAgIC8vIGNhbGwgaGFuZGxlcgogICAgICBjLmNsb3NlZChjKTsKICAgIH0KCiAgICAvLyByZXNldCBUTFMgY29ubmVjdGlvbiwgZG8gbm90IGNsZWFyIGZhaWwgZmxhZwogICAgYy5yZXNldChjbGVhckZhaWwpOwogIH07CgogIHJldHVybiBjOwp9OwoKLyogVExTIEFQSSAqLwpmb3JnZS50bHMgPSBmb3JnZS50bHMgfHwge307CgovLyBleHBvc2Ugbm9uLWZ1bmN0aW9ucwpmb3IodmFyIGtleSBpbiB0bHMpIHsKICBpZih0eXBlb2YgdGxzW2tleV0gIT09ICdmdW5jdGlvbicpIHsKICAgIGZvcmdlLnRsc1trZXldID0gdGxzW2tleV07CiAgfQp9CgovLyBleHBvc2UgcHJmX3RsczEgZm9yIHRlc3RpbmcKZm9yZ2UudGxzLnByZl90bHMxID0gcHJmX1RMUzE7CgovLyBleHBvc2Ugc2hhMSBobWFjIG1ldGhvZApmb3JnZS50bHMuaG1hY19zaGExID0gaG1hY19zaGExOwoKLy8gZXhwb3NlIHNlc3Npb24gY2FjaGUgY3JlYXRpb24KZm9yZ2UudGxzLmNyZWF0ZVNlc3Npb25DYWNoZSA9IHRscy5jcmVhdGVTZXNzaW9uQ2FjaGU7CgovKioKICogQ3JlYXRlcyBhIG5ldyBUTFMgY29ubmVjdGlvbi4gVGhpcyBkb2VzIG5vdCBtYWtlIGFueSBhc3N1bXB0aW9ucyBhYm91dCB0aGUKICogdHJhbnNwb3J0IGxheWVyIHRoYXQgVExTIGlzIHdvcmtpbmcgb24gdG9wIG9mLCBpZTogaXQgZG9lcyBub3QgYXNzdW1lIHRoZXJlCiAqIGlzIGEgVENQL0lQIGNvbm5lY3Rpb24gb3IgZXN0YWJsaXNoIG9uZS4gQSBUTFMgY29ubmVjdGlvbiBpcyB0b3RhbGx5CiAqIGFic3RyYWN0ZWQgYXdheSBmcm9tIHRoZSBsYXllciBpcyBydW5zIG9uIHRvcCBvZiwgaXQgbWVyZWx5IGVzdGFibGlzaGVzIGEKICogc2VjdXJlIGNoYW5uZWwgYmV0d2VlbiBhIGNsaWVudCIgYW5kIGEgInNlcnZlciIuCiAqCiAqIEEgVExTIGNvbm5lY3Rpb24gY29udGFpbnMgNCBjb25uZWN0aW9uIHN0YXRlczogcGVuZGluZyByZWFkIGFuZCB3cml0ZSwgYW5kCiAqIGN1cnJlbnQgcmVhZCBhbmQgd3JpdGUuCiAqCiAqIEF0IGluaXRpYWxpemF0aW9uLCB0aGUgY3VycmVudCByZWFkIGFuZCB3cml0ZSBzdGF0ZXMgd2lsbCBiZSBudWxsLiBPbmx5IG9uY2UKICogdGhlIHNlY3VyaXR5IHBhcmFtZXRlcnMgaGF2ZSBiZWVuIHNldCBhbmQgdGhlIGtleXMgaGF2ZSBiZWVuIGdlbmVyYXRlZCBjYW4KICogdGhlIHBlbmRpbmcgc3RhdGVzIGJlIGNvbnZlcnRlZCBpbnRvIGN1cnJlbnQgc3RhdGVzLiBDdXJyZW50IHN0YXRlcyB3aWxsIGJlCiAqIHVwZGF0ZWQgZm9yIGVhY2ggcmVjb3JkIHByb2Nlc3NlZC4KICoKICogQSBjdXN0b20gY2VydGlmaWNhdGUgdmVyaWZ5IGNhbGxiYWNrIG1heSBiZSBwcm92aWRlZCB0byBjaGVjayBpbmZvcm1hdGlvbgogKiBsaWtlIHRoZSBjb21tb24gbmFtZSBvbiB0aGUgc2VydmVyJ3MgY2VydGlmaWNhdGUuIEl0IHdpbGwgYmUgY2FsbGVkIGZvcgogKiBldmVyeSBjZXJ0aWZpY2F0ZSBpbiB0aGUgY2hhaW4uIEl0IGhhcyB0aGUgZm9sbG93aW5nIHNpZ25hdHVyZToKICoKICogdmFyaWFibGUgZnVuYyhjLCBjZXJ0cywgaW5kZXgsIHByZVZlcmlmeSkKICogV2hlcmU6CiAqIGMgICAgICAgICBUaGUgVExTIGNvbm5lY3Rpb24KICogdmVyaWZpZWQgIFNldCB0byB0cnVlIGlmIGNlcnRpZmljYXRlIHdhcyB2ZXJpZmllZCwgb3RoZXJ3aXNlIHRoZSBhbGVydAogKiAgICAgICAgICAgdGxzLkFsZXJ0LkRlc2NyaXB0aW9uIGZvciB3aHkgdGhlIGNlcnRpZmljYXRlIGZhaWxlZC4KICogZGVwdGggICAgIFRoZSBjdXJyZW50IGluZGV4IGluIHRoZSBjaGFpbiwgd2hlcmUgMCBpcyB0aGUgc2VydmVyJ3MgY2VydC4KICogY2VydHMgICAgIFRoZSBjZXJ0aWZpY2F0ZSBjaGFpbiwgKk5PVEUqIGlmIHRoZSBzZXJ2ZXIgd2FzIGFub255bW91cyB0aGVuCiAqICAgICAgICAgICB0aGUgY2hhaW4gd2lsbCBiZSBlbXB0eS4KICoKICogVGhlIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzIGFuZCBvbiBmYWlsdXJlIGVpdGhlciB0aGUgYXBwcm9wcmlhdGUKICogdGxzLkFsZXJ0LkRlc2NyaXB0aW9uIG9yIGFuIG9iamVjdCB3aXRoICdhbGVydCcgc2V0IHRvIHRoZSBhcHByb3ByaWF0ZQogKiB0bHMuQWxlcnQuRGVzY3JpcHRpb24gYW5kICdtZXNzYWdlJyBzZXQgdG8gYSBjdXN0b20gZXJyb3IgbWVzc2FnZS4gSWYgdHJ1ZQogKiBpcyBub3QgcmV0dXJuZWQgdGhlbiB0aGUgY29ubmVjdGlvbiB3aWxsIGFib3J0IHVzaW5nLCBpbiBvcmRlciBvZgogKiBhdmFpbGFiaWxpdHksIGZpcnN0IHRoZSByZXR1cm5lZCBhbGVydCBkZXNjcmlwdGlvbiwgc2Vjb25kIHRoZSBwcmVWZXJpZnkKICogYWxlcnQgZGVzY3JpcHRpb24sIGFuZCBsYXN0bHkgdGhlIGRlZmF1bHQgJ2JhZF9jZXJ0aWZpY2F0ZScuCiAqCiAqIFRoZXJlIGFyZSB0aHJlZSBjYWxsYmFja3MgdGhhdCBjYW4gYmUgdXNlZCB0byBtYWtlIHVzZSBvZiBjbGllbnQtc2lkZQogKiBjZXJ0aWZpY2F0ZXMgd2hlcmUgZWFjaCB0YWtlcyB0aGUgVExTIGNvbm5lY3Rpb24gYXMgdGhlIGZpcnN0IHBhcmFtZXRlcjoKICoKICogZ2V0Q2VydGlmaWNhdGUoY29ubiwgaGludCkKICogICBUaGUgc2Vjb25kIHBhcmFtZXRlciBpcyBhIGhpbnQgYXMgdG8gd2hpY2ggY2VydGlmaWNhdGUgc2hvdWxkIGJlCiAqICAgcmV0dXJuZWQuIElmIHRoZSBjb25uZWN0aW9uIGVudGl0eSBpcyBhIGNsaWVudCwgdGhlbiB0aGUgaGludCB3aWxsIGJlCiAqICAgdGhlIENlcnRpZmljYXRlUmVxdWVzdCBtZXNzYWdlIGZyb20gdGhlIHNlcnZlciB0aGF0IGlzIHBhcnQgb2YgdGhlCiAqICAgVExTIHByb3RvY29sLiBJZiB0aGUgY29ubmVjdGlvbiBlbnRpdHkgaXMgYSBzZXJ2ZXIsIHRoZW4gaXQgd2lsbCBiZQogKiAgIHRoZSBzZXJ2ZXJuYW1lIGxpc3QgcHJvdmlkZWQgdmlhIGFuIFNOSSBleHRlbnNpb24gdGhlIENsaWVudEhlbGxvLCBpZgogKiAgIG9uZSB3YXMgcHJvdmlkZWQgKGVtcHR5IGFycmF5IGlmIG5vdCkuIFRoZSBoaW50IGNhbiBiZSBleGFtaW5lZCB0bwogKiAgIGRldGVybWluZSB3aGljaCBjZXJ0aWZpY2F0ZSB0byB1c2UgKGFkdmFuY2VkKS4gTW9zdCBpbXBsZW1lbnRhdGlvbnMKICogICB3aWxsIGp1c3QgcmV0dXJuIGEgY2VydGlmaWNhdGUuIFRoZSByZXR1cm4gdmFsdWUgbXVzdCBiZSBhCiAqICAgUEVNLWZvcm1hdHRlZCBjZXJ0aWZpY2F0ZSBvciBhbiBhcnJheSBvZiBQRU0tZm9ybWF0dGVkIGNlcnRpZmljYXRlcwogKiAgIHRoYXQgY29uc3RpdHV0ZSBhIGNlcnRpZmljYXRlIGNoYWluLCB3aXRoIHRoZSBmaXJzdCBpbiB0aGUgYXJyYXkvY2hhaW4KICogICBiZWluZyB0aGUgY2xpZW50J3MgY2VydGlmaWNhdGUuCiAqIGdldFByaXZhdGVLZXkoY29ubiwgY2VydGlmaWNhdGUpCiAqICAgVGhlIHNlY29uZCBwYXJhbWV0ZXIgaXMgYW4gZm9yZ2UucGtpIFguNTA5IGNlcnRpZmljYXRlIG9iamVjdCB0aGF0CiAqICAgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSByZXF1ZXN0ZWQgcHJpdmF0ZSBrZXkuIFRoZSByZXR1cm4gdmFsdWUgbXVzdAogKiAgIGJlIGEgUEVNLWZvcm1hdHRlZCBwcml2YXRlIGtleS4KICogZ2V0U2lnbmF0dXJlKGNvbm4sIGJ5dGVzLCBjYWxsYmFjaykKICogICBUaGlzIGNhbGxiYWNrIGNhbiBiZSB1c2VkIGluc3RlYWQgb2YgZ2V0UHJpdmF0ZUtleSBpZiB0aGUgcHJpdmF0ZSBrZXkKICogICBpcyBub3QgZGlyZWN0bHkgYWNjZXNzaWJsZSBpbiBqYXZhc2NyaXB0IG9yIHNob3VsZCBub3QgYmUuIEZvcgogKiAgIGluc3RhbmNlLCBhIHNlY3VyZSBleHRlcm5hbCB3ZWIgc2VydmljZSBjb3VsZCBwcm92aWRlIHRoZSBzaWduYXR1cmUKICogICBpbiBleGNoYW5nZSBmb3IgYXBwcm9wcmlhdGUgY3JlZGVudGlhbHMuIFRoZSBzZWNvbmQgcGFyYW1ldGVyIGlzIGEKICogICBzdHJpbmcgb2YgYnl0ZXMgdG8gYmUgc2lnbmVkIHRoYXQgYXJlIHBhcnQgb2YgdGhlIFRMUyBwcm90b2NvbC4gVGhlc2UKICogICBieXRlcyBhcmUgdXNlZCB0byB2ZXJpZnkgdGhhdCB0aGUgcHJpdmF0ZSBrZXkgZm9yIHRoZSBwcmV2aW91c2x5CiAqICAgcHJvdmlkZWQgY2xpZW50LXNpZGUgY2VydGlmaWNhdGUgaXMgYWNjZXNzaWJsZSB0byB0aGUgY2xpZW50LiBUaGUKICogICBjYWxsYmFjayBpcyBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgMiBwYXJhbWV0ZXJzLCB0aGUgVExTIGNvbm5lY3Rpb24KICogICBhbmQgdGhlIFJTQSBlbmNyeXB0ZWQgKHNpZ25lZCkgYnl0ZXMgYXMgYSBzdHJpbmcuIFRoaXMgY2FsbGJhY2sgbXVzdAogKiAgIGJlIGNhbGxlZCBvbmNlIHRoZSBzaWduYXR1cmUgaXMgcmVhZHkuCiAqCiAqIEBwYXJhbSBvcHRpb25zIHRoZSBvcHRpb25zIGZvciB0aGlzIGNvbm5lY3Rpb246CiAqICAgc2VydmVyOiB0cnVlIGlmIHRoZSBjb25uZWN0aW9uIGlzIHNlcnZlci1zaWRlLCBmYWxzZSBmb3IgY2xpZW50LgogKiAgIHNlc3Npb25JZDogYSBzZXNzaW9uIElEIHRvIHJldXNlLCBudWxsIGZvciBhIG5ldyBjb25uZWN0aW9uLgogKiAgIGNhU3RvcmU6IGFuIGFycmF5IG9mIGNlcnRpZmljYXRlcyB0byB0cnVzdC4KICogICBzZXNzaW9uQ2FjaGU6IGEgc2Vzc2lvbiBjYWNoZSB0byB1c2UuCiAqICAgY2lwaGVyU3VpdGVzOiBhbiBvcHRpb25hbCBhcnJheSBvZiBjaXBoZXIgc3VpdGVzIHRvIHVzZSwKICogICAgIHNlZSB0bHMuQ2lwaGVyU3VpdGVzLgogKiAgIGNvbm5lY3RlZDogZnVuY3Rpb24oY29ubikgY2FsbGVkIHdoZW4gdGhlIGZpcnN0IGhhbmRzaGFrZSBjb21wbGV0ZXMuCiAqICAgdmlydHVhbEhvc3Q6IHRoZSB2aXJ0dWFsIHNlcnZlciBuYW1lIHRvIHVzZSBpbiBhIFRMUyBTTkkgZXh0ZW5zaW9uLgogKiAgIHZlcmlmeUNsaWVudDogdHJ1ZSB0byByZXF1aXJlIGEgY2xpZW50IGNlcnRpZmljYXRlIGluIHNlcnZlciBtb2RlLAogKiAgICAgJ29wdGlvbmFsJyB0byByZXF1ZXN0IG9uZSwgZmFsc2Ugbm90IHRvIChkZWZhdWx0OiBmYWxzZSkuCiAqICAgdmVyaWZ5OiBhIGhhbmRsZXIgdXNlZCB0byBjdXN0b20gdmVyaWZ5IGNlcnRpZmljYXRlcyBpbiB0aGUgY2hhaW4uCiAqICAgZ2V0Q2VydGlmaWNhdGU6IGFuIG9wdGlvbmFsIGNhbGxiYWNrIHVzZWQgdG8gZ2V0IGEgY2VydGlmaWNhdGUgb3IKICogICAgIGEgY2hhaW4gb2YgY2VydGlmaWNhdGVzIChhcyBhbiBhcnJheSkuCiAqICAgZ2V0UHJpdmF0ZUtleTogYW4gb3B0aW9uYWwgY2FsbGJhY2sgdXNlZCB0byBnZXQgYSBwcml2YXRlIGtleS4KICogICBnZXRTaWduYXR1cmU6IGFuIG9wdGlvbmFsIGNhbGxiYWNrIHVzZWQgdG8gZ2V0IGEgc2lnbmF0dXJlLgogKiAgIHRsc0RhdGFSZWFkeTogZnVuY3Rpb24oY29ubikgY2FsbGVkIHdoZW4gVExTIHByb3RvY29sIGRhdGEgaGFzIGJlZW4KICogICAgIHByZXBhcmVkIGFuZCBpcyByZWFkeSB0byBiZSB1c2VkICh0eXBpY2FsbHkgc2VudCBvdmVyIGEgc29ja2V0CiAqICAgICBjb25uZWN0aW9uIHRvIGl0cyBkZXN0aW5hdGlvbiksIHJlYWQgZnJvbSBjb25uLnRsc0RhdGEgYnVmZmVyLgogKiAgIGRhdGFSZWFkeTogZnVuY3Rpb24oY29ubikgY2FsbGVkIHdoZW4gYXBwbGljYXRpb24gZGF0YSBoYXMKICogICAgIGJlZW4gcGFyc2VkIGZyb20gYSBUTFMgcmVjb3JkIGFuZCBzaG91bGQgYmUgY29uc3VtZWQgYnkgdGhlCiAqICAgICBhcHBsaWNhdGlvbiwgcmVhZCBmcm9tIGNvbm4uZGF0YSBidWZmZXIuCiAqICAgY2xvc2VkOiBmdW5jdGlvbihjb25uKSBjYWxsZWQgd2hlbiB0aGUgY29ubmVjdGlvbiBoYXMgYmVlbiBjbG9zZWQuCiAqICAgZXJyb3I6IGZ1bmN0aW9uKGNvbm4sIGVycm9yKSBjYWxsZWQgd2hlbiB0aGVyZSB3YXMgYW4gZXJyb3IuCiAqICAgZGVmbGF0ZTogZnVuY3Rpb24oaW5CeXRlcykgaWYgcHJvdmlkZWQsIHdpbGwgZGVmbGF0ZSBUTFMgcmVjb3JkcyB1c2luZwogKiAgICAgdGhlIGRlZmxhdGUgYWxnb3JpdGhtIGlmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgaXQuCiAqICAgaW5mbGF0ZTogZnVuY3Rpb24oaW5CeXRlcykgaWYgcHJvdmlkZWQsIHdpbGwgaW5mbGF0ZSBUTFMgcmVjb3JkcyB1c2luZwogKiAgICAgdGhlIGRlZmxhdGUgYWxnb3JpdGhtIGlmIHRoZSBzZXJ2ZXIgc3VwcG9ydHMgaXQuCiAqCiAqIEByZXR1cm4gdGhlIG5ldyBUTFMgY29ubmVjdGlvbi4KICovCmZvcmdlLnRscy5jcmVhdGVDb25uZWN0aW9uID0gdGxzLmNyZWF0ZUNvbm5lY3Rpb247Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICd0bHMnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvdGxzJyxbCiAgJ3JlcXVpcmUnLAogICdtb2R1bGUnLAogICcuL2FzbjEnLAogICcuL2htYWMnLAogICcuL21kJywKICAnLi9wZW0nLAogICcuL3BraScsCiAgJy4vcmFuZG9tJywKICAnLi91dGlsJ10sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIEEgSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBBRVMgQ2lwaGVyIFN1aXRlcyBmb3IgVExTLgogKgogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDktMjAxNSBEaWdpdGFsIEJhemFhciwgSW5jLgogKgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCnZhciB0bHMgPSBmb3JnZS50bHM7CgovKioKICogU3VwcG9ydGVkIGNpcGhlciBzdWl0ZXMuCiAqLwp0bHMuQ2lwaGVyU3VpdGVzWydUTFNfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBJ10gPSB7CiAgaWQ6IFsweDAwLDB4MmZdLAogIG5hbWU6ICdUTFNfUlNBX1dJVEhfQUVTXzEyOF9DQkNfU0hBJywKICBpbml0U2VjdXJpdHlQYXJhbWV0ZXJzOiBmdW5jdGlvbihzcCkgewogICAgc3AuYnVsa19jaXBoZXJfYWxnb3JpdGhtID0gdGxzLkJ1bGtDaXBoZXJBbGdvcml0aG0uYWVzOwogICAgc3AuY2lwaGVyX3R5cGUgPSB0bHMuQ2lwaGVyVHlwZS5ibG9jazsKICAgIHNwLmVuY19rZXlfbGVuZ3RoID0gMTY7CiAgICBzcC5ibG9ja19sZW5ndGggPSAxNjsKICAgIHNwLmZpeGVkX2l2X2xlbmd0aCA9IDE2OwogICAgc3AucmVjb3JkX2l2X2xlbmd0aCA9IDE2OwogICAgc3AubWFjX2FsZ29yaXRobSA9IHRscy5NQUNBbGdvcml0aG0uaG1hY19zaGExOwogICAgc3AubWFjX2xlbmd0aCA9IDIwOwogICAgc3AubWFjX2tleV9sZW5ndGggPSAyMDsKICB9LAogIGluaXRDb25uZWN0aW9uU3RhdGU6IGluaXRDb25uZWN0aW9uU3RhdGUKfTsKdGxzLkNpcGhlclN1aXRlc1snVExTX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQSddID0gewogIGlkOiBbMHgwMCwweDM1XSwKICBuYW1lOiAnVExTX1JTQV9XSVRIX0FFU18yNTZfQ0JDX1NIQScsCiAgaW5pdFNlY3VyaXR5UGFyYW1ldGVyczogZnVuY3Rpb24oc3ApIHsKICAgIHNwLmJ1bGtfY2lwaGVyX2FsZ29yaXRobSA9IHRscy5CdWxrQ2lwaGVyQWxnb3JpdGhtLmFlczsKICAgIHNwLmNpcGhlcl90eXBlID0gdGxzLkNpcGhlclR5cGUuYmxvY2s7CiAgICBzcC5lbmNfa2V5X2xlbmd0aCA9IDMyOwogICAgc3AuYmxvY2tfbGVuZ3RoID0gMTY7CiAgICBzcC5maXhlZF9pdl9sZW5ndGggPSAxNjsKICAgIHNwLnJlY29yZF9pdl9sZW5ndGggPSAxNjsKICAgIHNwLm1hY19hbGdvcml0aG0gPSB0bHMuTUFDQWxnb3JpdGhtLmhtYWNfc2hhMTsKICAgIHNwLm1hY19sZW5ndGggPSAyMDsKICAgIHNwLm1hY19rZXlfbGVuZ3RoID0gMjA7CiAgfSwKICBpbml0Q29ubmVjdGlvblN0YXRlOiBpbml0Q29ubmVjdGlvblN0YXRlCn07CgpmdW5jdGlvbiBpbml0Q29ubmVjdGlvblN0YXRlKHN0YXRlLCBjLCBzcCkgewogIHZhciBjbGllbnQgPSAoYy5lbnRpdHkgPT09IGZvcmdlLnRscy5Db25uZWN0aW9uRW5kLmNsaWVudCk7CgogIC8vIGNpcGhlciBzZXR1cAogIHN0YXRlLnJlYWQuY2lwaGVyU3RhdGUgPSB7CiAgICBpbml0OiBmYWxzZSwKICAgIGNpcGhlcjogZm9yZ2UuY2lwaGVyLmNyZWF0ZURlY2lwaGVyKCdBRVMtQ0JDJywgY2xpZW50ID8KICAgICAgc3Aua2V5cy5zZXJ2ZXJfd3JpdGVfa2V5IDogc3Aua2V5cy5jbGllbnRfd3JpdGVfa2V5KSwKICAgIGl2OiBjbGllbnQgPyBzcC5rZXlzLnNlcnZlcl93cml0ZV9JViA6IHNwLmtleXMuY2xpZW50X3dyaXRlX0lWCiAgfTsKICBzdGF0ZS53cml0ZS5jaXBoZXJTdGF0ZSA9IHsKICAgIGluaXQ6IGZhbHNlLAogICAgY2lwaGVyOiBmb3JnZS5jaXBoZXIuY3JlYXRlQ2lwaGVyKCdBRVMtQ0JDJywgY2xpZW50ID8KICAgICAgc3Aua2V5cy5jbGllbnRfd3JpdGVfa2V5IDogc3Aua2V5cy5zZXJ2ZXJfd3JpdGVfa2V5KSwKICAgIGl2OiBjbGllbnQgPyBzcC5rZXlzLmNsaWVudF93cml0ZV9JViA6IHNwLmtleXMuc2VydmVyX3dyaXRlX0lWCiAgfTsKICBzdGF0ZS5yZWFkLmNpcGhlckZ1bmN0aW9uID0gZGVjcnlwdF9hZXNfY2JjX3NoYTE7CiAgc3RhdGUud3JpdGUuY2lwaGVyRnVuY3Rpb24gPSBlbmNyeXB0X2Flc19jYmNfc2hhMTsKCiAgLy8gTUFDIHNldHVwCiAgc3RhdGUucmVhZC5tYWNMZW5ndGggPSBzdGF0ZS53cml0ZS5tYWNMZW5ndGggPSBzcC5tYWNfbGVuZ3RoOwogIHN0YXRlLnJlYWQubWFjRnVuY3Rpb24gPSBzdGF0ZS53cml0ZS5tYWNGdW5jdGlvbiA9IHRscy5obWFjX3NoYTE7Cn0KCi8qKgogKiBFbmNyeXB0cyB0aGUgVExTQ29tcHJlc3NlZCByZWNvcmQgaW50byBhIFRMU0NpcGhlclRleHQgcmVjb3JkIHVzaW5nIEFFUwogKiBpbiBDQkMgbW9kZS4KICoKICogQHBhcmFtIHJlY29yZCB0aGUgVExTQ29tcHJlc3NlZCByZWNvcmQgdG8gZW5jcnlwdC4KICogQHBhcmFtIHMgdGhlIENvbm5lY3Rpb25TdGF0ZSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KZnVuY3Rpb24gZW5jcnlwdF9hZXNfY2JjX3NoYTEocmVjb3JkLCBzKSB7CiAgdmFyIHJ2YWwgPSBmYWxzZTsKCiAgLy8gYXBwZW5kIE1BQyB0byBmcmFnbWVudCwgdXBkYXRlIHNlcXVlbmNlIG51bWJlcgogIHZhciBtYWMgPSBzLm1hY0Z1bmN0aW9uKHMubWFjS2V5LCBzLnNlcXVlbmNlTnVtYmVyLCByZWNvcmQpOwogIHJlY29yZC5mcmFnbWVudC5wdXRCeXRlcyhtYWMpOwogIHMudXBkYXRlU2VxdWVuY2VOdW1iZXIoKTsKCiAgLy8gVExTIDEuMSsgdXNlIGFuIGV4cGxpY2l0IElWIGV2ZXJ5IHRpbWUgdG8gcHJvdGVjdCBhZ2FpbnN0IENCQyBhdHRhY2tzCiAgdmFyIGl2OwogIGlmKHJlY29yZC52ZXJzaW9uLm1pbm9yID09PSB0bHMuVmVyc2lvbnMuVExTXzFfMC5taW5vcikgewogICAgLy8gdXNlIHRoZSBwcmUtZ2VuZXJhdGVkIElWIHdoZW4gaW5pdGlhbGl6aW5nIGZvciBUTFMgMS4wLCBvdGhlcndpc2UgdXNlCiAgICAvLyB0aGUgcmVzaWR1ZSBmcm9tIHRoZSBwcmV2aW91cyBlbmNyeXB0aW9uCiAgICBpdiA9IHMuY2lwaGVyU3RhdGUuaW5pdCA/IG51bGwgOiBzLmNpcGhlclN0YXRlLml2OwogIH0gZWxzZSB7CiAgICBpdiA9IGZvcmdlLnJhbmRvbS5nZXRCeXRlc1N5bmMoMTYpOwogIH0KCiAgcy5jaXBoZXJTdGF0ZS5pbml0ID0gdHJ1ZTsKCiAgLy8gc3RhcnQgY2lwaGVyCiAgdmFyIGNpcGhlciA9IHMuY2lwaGVyU3RhdGUuY2lwaGVyOwogIGNpcGhlci5zdGFydCh7aXY6IGl2fSk7CgogIC8vIFRMUyAxLjErIHdyaXRlIElWIGludG8gb3V0cHV0CiAgaWYocmVjb3JkLnZlcnNpb24ubWlub3IgPj0gdGxzLlZlcnNpb25zLlRMU18xXzEubWlub3IpIHsKICAgIGNpcGhlci5vdXRwdXQucHV0Qnl0ZXMoaXYpOwogIH0KCiAgLy8gZG8gZW5jcnlwdGlvbiAoZGVmYXVsdCBwYWRkaW5nIGlzIGFwcHJvcHJpYXRlKQogIGNpcGhlci51cGRhdGUocmVjb3JkLmZyYWdtZW50KTsKICBpZihjaXBoZXIuZmluaXNoKGVuY3J5cHRfYWVzX2NiY19zaGExX3BhZGRpbmcpKSB7CiAgICAvLyBzZXQgcmVjb3JkIGZyYWdtZW50IHRvIGVuY3J5cHRlZCBvdXRwdXQKICAgIHJlY29yZC5mcmFnbWVudCA9IGNpcGhlci5vdXRwdXQ7CiAgICByZWNvcmQubGVuZ3RoID0gcmVjb3JkLmZyYWdtZW50Lmxlbmd0aCgpOwogICAgcnZhbCA9IHRydWU7CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIEhhbmRsZXMgcGFkZGluZyBmb3IgYWVzX2NiY19zaGExIGluIGVuY3J5cHQgbW9kZS4KICoKICogQHBhcmFtIGJsb2NrU2l6ZSB0aGUgYmxvY2sgc2l6ZS4KICogQHBhcmFtIGlucHV0IHRoZSBpbnB1dCBidWZmZXIuCiAqIEBwYXJhbSBkZWNyeXB0IHRydWUgaW4gZGVjcnlwdCBtb2RlLCBmYWxzZSBpbiBlbmNyeXB0IG1vZGUuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KZnVuY3Rpb24gZW5jcnlwdF9hZXNfY2JjX3NoYTFfcGFkZGluZyhibG9ja1NpemUsIGlucHV0LCBkZWNyeXB0KSB7CiAgLyogVGhlIGVuY3J5cHRlZCBkYXRhIGxlbmd0aCAoVExTQ2lwaGVydGV4dC5sZW5ndGgpIGlzIG9uZSBtb3JlIHRoYW4gdGhlIHN1bQogICBvZiBTZWN1cml0eVBhcmFtZXRlcnMuYmxvY2tfbGVuZ3RoLCBUTFNDb21wcmVzc2VkLmxlbmd0aCwKICAgU2VjdXJpdHlQYXJhbWV0ZXJzLm1hY19sZW5ndGgsIGFuZCBwYWRkaW5nX2xlbmd0aC4KCiAgIFRoZSBwYWRkaW5nIG1heSBiZSBhbnkgbGVuZ3RoIHVwIHRvIDI1NSBieXRlcyBsb25nLCBhcyBsb25nIGFzIGl0IHJlc3VsdHMgaW4KICAgdGhlIFRMU0NpcGhlcnRleHQubGVuZ3RoIGJlaW5nIGFuIGludGVncmFsIG11bHRpcGxlIG9mIHRoZSBibG9jayBsZW5ndGguCiAgIExlbmd0aHMgbG9uZ2VyIHRoYW4gbmVjZXNzYXJ5IG1pZ2h0IGJlIGRlc2lyYWJsZSB0byBmcnVzdHJhdGUgYXR0YWNrcyBvbiBhCiAgIHByb3RvY29sIGJhc2VkIG9uIGFuYWx5c2lzIG9mIHRoZSBsZW5ndGhzIG9mIGV4Y2hhbmdlZCBtZXNzYWdlcy4gRWFjaCB1aW50OAogICBpbiB0aGUgcGFkZGluZyBkYXRhIHZlY3RvciBtdXN0IGJlIGZpbGxlZCB3aXRoIHRoZSBwYWRkaW5nIGxlbmd0aCB2YWx1ZS4KCiAgIFRoZSBwYWRkaW5nIGxlbmd0aCBzaG91bGQgYmUgc3VjaCB0aGF0IHRoZSB0b3RhbCBzaXplIG9mIHRoZQogICBHZW5lcmljQmxvY2tDaXBoZXIgc3RydWN0dXJlIGlzIGEgbXVsdGlwbGUgb2YgdGhlIGNpcGhlcidzIGJsb2NrIGxlbmd0aC4KICAgTGVnYWwgdmFsdWVzIHJhbmdlIGZyb20gemVybyB0byAyNTUsIGluY2x1c2l2ZS4gVGhpcyBsZW5ndGggc3BlY2lmaWVzIHRoZQogICBsZW5ndGggb2YgdGhlIHBhZGRpbmcgZmllbGQgZXhjbHVzaXZlIG9mIHRoZSBwYWRkaW5nX2xlbmd0aCBmaWVsZCBpdHNlbGYuCgogICBUaGlzIGlzIHNsaWdodGx5IGRpZmZlcmVudCBmcm9tIFBLQ1MjNyBiZWNhdXNlIHRoZSBwYWRkaW5nIHZhbHVlIGlzIDEKICAgbGVzcyB0aGFuIHRoZSBhY3R1YWwgbnVtYmVyIG9mIHBhZGRpbmcgYnl0ZXMgaWYgeW91IGluY2x1ZGUgdGhlCiAgIHBhZGRpbmdfbGVuZ3RoIHVpbnQ4IGl0c2VsZiBhcyBhIHBhZGRpbmcgYnl0ZS4gKi8KICBpZighZGVjcnlwdCkgewogICAgLy8gZ2V0IHRoZSBudW1iZXIgb2YgcGFkZGluZyBieXRlcyByZXF1aXJlZCB0byByZWFjaCB0aGUgYmxvY2tTaXplIGFuZAogICAgLy8gc3VidHJhY3QgMSBmb3IgdGhlIHBhZGRpbmcgdmFsdWUgKHRvIG1ha2Ugcm9vbSBmb3IgdGhlIHBhZGRpbmdfbGVuZ3RoCiAgICAvLyB1aW50OCkKICAgIHZhciBwYWRkaW5nID0gYmxvY2tTaXplIC0gKGlucHV0Lmxlbmd0aCgpICUgYmxvY2tTaXplKTsKICAgIGlucHV0LmZpbGxXaXRoQnl0ZShwYWRkaW5nIC0gMSwgcGFkZGluZyk7CiAgfQogIHJldHVybiB0cnVlOwp9CgovKioKICogSGFuZGxlcyBwYWRkaW5nIGZvciBhZXNfY2JjX3NoYTEgaW4gZGVjcnlwdCBtb2RlLgogKgogKiBAcGFyYW0gYmxvY2tTaXplIHRoZSBibG9jayBzaXplLgogKiBAcGFyYW0gb3V0cHV0IHRoZSBvdXRwdXQgYnVmZmVyLgogKiBAcGFyYW0gZGVjcnlwdCB0cnVlIGluIGRlY3J5cHQgbW9kZSwgZmFsc2UgaW4gZW5jcnlwdCBtb2RlLgogKgogKiBAcmV0dXJuIHRydWUgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZS4KICovCmZ1bmN0aW9uIGRlY3J5cHRfYWVzX2NiY19zaGExX3BhZGRpbmcoYmxvY2tTaXplLCBvdXRwdXQsIGRlY3J5cHQpIHsKICB2YXIgcnZhbCA9IHRydWU7CiAgaWYoZGVjcnlwdCkgewogICAgLyogVGhlIGxhc3QgYnl0ZSBpbiB0aGUgb3V0cHV0IHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIHBhZGRpbmcgYnl0ZXMgbm90CiAgICAgIGluY2x1ZGluZyBpdHNlbGYuIEVhY2ggb2YgdGhlIHBhZGRpbmcgYnl0ZXMgaGFzIHRoZSBzYW1lIHZhbHVlIGFzIHRoYXQKICAgICAgbGFzdCBieXRlIChrbm93biBhcyB0aGUgcGFkZGluZ19sZW5ndGgpLiBIZXJlIHdlIGNoZWNrIGFsbCBwYWRkaW5nCiAgICAgIGJ5dGVzIHRvIGVuc3VyZSB0aGV5IGhhdmUgdGhlIHZhbHVlIG9mIHBhZGRpbmdfbGVuZ3RoIGV2ZW4gaWYgb25lIG9mCiAgICAgIHRoZW0gaXMgYmFkIGluIG9yZGVyIHRvIHdhcmQtb2ZmIHRpbWluZyBhdHRhY2tzLiAqLwogICAgdmFyIGxlbiA9IG91dHB1dC5sZW5ndGgoKTsKICAgIHZhciBwYWRkaW5nTGVuZ3RoID0gb3V0cHV0Lmxhc3QoKTsKICAgIGZvcih2YXIgaSA9IGxlbiAtIDEgLSBwYWRkaW5nTGVuZ3RoOyBpIDwgbGVuIC0gMTsgKytpKSB7CiAgICAgIHJ2YWwgPSBydmFsICYmIChvdXRwdXQuYXQoaSkgPT0gcGFkZGluZ0xlbmd0aCk7CiAgICB9CiAgICBpZihydmFsKSB7CiAgICAgIC8vIHRyaW0gb2ZmIHBhZGRpbmcgYnl0ZXMgYW5kIGxhc3QgcGFkZGluZyBsZW5ndGggYnl0ZQogICAgICBvdXRwdXQudHJ1bmNhdGUocGFkZGluZ0xlbmd0aCArIDEpOwogICAgfQogIH0KICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIERlY3J5cHRzIGEgVExTQ2lwaGVyVGV4dCByZWNvcmQgaW50byBhIFRMU0NvbXByZXNzZWQgcmVjb3JkIHVzaW5nCiAqIEFFUyBpbiBDQkMgbW9kZS4KICoKICogQHBhcmFtIHJlY29yZCB0aGUgVExTQ2lwaGVyVGV4dCByZWNvcmQgdG8gZGVjcnlwdC4KICogQHBhcmFtIHMgdGhlIENvbm5lY3Rpb25TdGF0ZSB0byB1c2UuCiAqCiAqIEByZXR1cm4gdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgogKi8KdmFyIGNvdW50ID0gMDsKZnVuY3Rpb24gZGVjcnlwdF9hZXNfY2JjX3NoYTEocmVjb3JkLCBzKSB7CiAgdmFyIHJ2YWwgPSBmYWxzZTsKICArK2NvdW50OwoKICB2YXIgaXY7CiAgaWYocmVjb3JkLnZlcnNpb24ubWlub3IgPT09IHRscy5WZXJzaW9ucy5UTFNfMV8wLm1pbm9yKSB7CiAgICAvLyB1c2UgcHJlLWdlbmVyYXRlZCBJViB3aGVuIGluaXRpYWxpemluZyBmb3IgVExTIDEuMCwgb3RoZXJ3aXNlIHVzZSB0aGUKICAgIC8vIHJlc2lkdWUgZnJvbSB0aGUgcHJldmlvdXMgZGVjcnlwdGlvbgogICAgaXYgPSBzLmNpcGhlclN0YXRlLmluaXQgPyBudWxsIDogcy5jaXBoZXJTdGF0ZS5pdjsKICB9IGVsc2UgewogICAgLy8gVExTIDEuMSsgdXNlIGFuIGV4cGxpY2l0IElWIGV2ZXJ5IHRpbWUgdG8gcHJvdGVjdCBhZ2FpbnN0IENCQyBhdHRhY2tzCiAgICAvLyB0aGF0IGlzIGFwcGVuZGVkIHRvIHRoZSByZWNvcmQgZnJhZ21lbnQKICAgIGl2ID0gcmVjb3JkLmZyYWdtZW50LmdldEJ5dGVzKDE2KTsKICB9CgogIHMuY2lwaGVyU3RhdGUuaW5pdCA9IHRydWU7CgogIC8vIHN0YXJ0IGNpcGhlcgogIHZhciBjaXBoZXIgPSBzLmNpcGhlclN0YXRlLmNpcGhlcjsKICBjaXBoZXIuc3RhcnQoe2l2OiBpdn0pOwoKICAvLyBkbyBkZWNyeXB0aW9uCiAgY2lwaGVyLnVwZGF0ZShyZWNvcmQuZnJhZ21lbnQpOwogIHJ2YWwgPSBjaXBoZXIuZmluaXNoKGRlY3J5cHRfYWVzX2NiY19zaGExX3BhZGRpbmcpOwoKICAvLyBldmVuIGlmIGRlY3J5cHRpb24gZmFpbHMsIGtlZXAgZ29pbmcgdG8gbWluaW1pemUgdGltaW5nIGF0dGFja3MKCiAgLy8gZGVjcnlwdGVkIGRhdGE6CiAgLy8gZmlyc3QgKGxlbiAtIDIwKSBieXRlcyA9IGFwcGxpY2F0aW9uIGRhdGEKICAvLyBsYXN0IDIwIGJ5dGVzICAgICAgICAgID0gTUFDCiAgdmFyIG1hY0xlbiA9IHMubWFjTGVuZ3RoOwoKICAvLyBjcmVhdGUgYSByYW5kb20gTUFDIHRvIGNoZWNrIGFnYWluc3Qgc2hvdWxkIHRoZSBtYWMgbGVuZ3RoIGNoZWNrIGZhaWwKICAvLyBOb3RlOiBkbyB0aGlzIHJlZ2FyZGxlc3Mgb2YgdGhlIGZhaWx1cmUgdG8ga2VlcCB0aW1pbmcgY29uc2lzdGVudAogIHZhciBtYWMgPSBmb3JnZS5yYW5kb20uZ2V0Qnl0ZXNTeW5jKG1hY0xlbik7CgogIC8vIGdldCBmcmFnbWVudCBhbmQgbWFjCiAgdmFyIGxlbiA9IGNpcGhlci5vdXRwdXQubGVuZ3RoKCk7CiAgaWYobGVuID49IG1hY0xlbikgewogICAgcmVjb3JkLmZyYWdtZW50ID0gY2lwaGVyLm91dHB1dC5nZXRCeXRlcyhsZW4gLSBtYWNMZW4pOwogICAgbWFjID0gY2lwaGVyLm91dHB1dC5nZXRCeXRlcyhtYWNMZW4pOwogIH0gZWxzZSB7CiAgICAvLyBiYWQgZGF0YSwgYnV0IGdldCBieXRlcyBhbnl3YXkgdG8gdHJ5IHRvIGtlZXAgdGltaW5nIGNvbnNpc3RlbnQKICAgIHJlY29yZC5mcmFnbWVudCA9IGNpcGhlci5vdXRwdXQuZ2V0Qnl0ZXMoKTsKICB9CiAgcmVjb3JkLmZyYWdtZW50ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIocmVjb3JkLmZyYWdtZW50KTsKICByZWNvcmQubGVuZ3RoID0gcmVjb3JkLmZyYWdtZW50Lmxlbmd0aCgpOwoKICAvLyBzZWUgaWYgZGF0YSBpbnRlZ3JpdHkgY2hlY2tzIG91dCwgdXBkYXRlIHNlcXVlbmNlIG51bWJlcgogIHZhciBtYWMyID0gcy5tYWNGdW5jdGlvbihzLm1hY0tleSwgcy5zZXF1ZW5jZU51bWJlciwgcmVjb3JkKTsKICBzLnVwZGF0ZVNlcXVlbmNlTnVtYmVyKCk7CiAgcnZhbCA9IGNvbXBhcmVNYWNzKHMubWFjS2V5LCBtYWMsIG1hYzIpICYmIHJ2YWw7CiAgcmV0dXJuIHJ2YWw7Cn0KCi8qKgogKiBTYWZlbHkgY29tcGFyZSB0d28gTUFDcy4gVGhpcyBmdW5jdGlvbiB3aWxsIGNvbXBhcmUgdHdvIE1BQ3MgaW4gYSB3YXkKICogdGhhdCBwcm90ZWN0cyBhZ2FpbnN0IHRpbWluZyBhdHRhY2tzLgogKgogKiBUT0RPOiBFeHBvc2UgZWxzZXdoZXJlIGFzIGEgdXRpbGl0eSBBUEkuCiAqCiAqIFNlZTogaHR0cHM6Ly93d3cubmNjZ3JvdXAudHJ1c3QvdXMvYWJvdXQtdXMvbmV3c3Jvb20tYW5kLWV2ZW50cy9ibG9nLzIwMTEvZmVicnVhcnkvZG91YmxlLWhtYWMtdmVyaWZpY2F0aW9uLwogKgogKiBAcGFyYW0ga2V5IHRoZSBNQUMga2V5IHRvIHVzZS4KICogQHBhcmFtIG1hYzEgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMuCiAqIEBwYXJhbSBtYWMyIGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogKgogKiBAcmV0dXJuIHRydWUgaWYgdGhlIE1BQ3MgYXJlIHRoZSBzYW1lLCBmYWxzZSBpZiBub3QuCiAqLwpmdW5jdGlvbiBjb21wYXJlTWFjcyhrZXksIG1hYzEsIG1hYzIpIHsKICB2YXIgaG1hYyA9IGZvcmdlLmhtYWMuY3JlYXRlKCk7CgogIGhtYWMuc3RhcnQoJ1NIQTEnLCBrZXkpOwogIGhtYWMudXBkYXRlKG1hYzEpOwogIG1hYzEgPSBobWFjLmRpZ2VzdCgpLmdldEJ5dGVzKCk7CgogIGhtYWMuc3RhcnQobnVsbCwgbnVsbCk7CiAgaG1hYy51cGRhdGUobWFjMik7CiAgbWFjMiA9IGhtYWMuZGlnZXN0KCkuZ2V0Qnl0ZXMoKTsKCiAgcmV0dXJuIG1hYzEgPT09IG1hYzI7Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ2Flc0NpcGhlclN1aXRlcyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9hZXNDaXBoZXJTdWl0ZXMnLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi9hZXMnLCAnLi90bHMnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogRGVidWdnaW5nIHN1cHBvcnQgZm9yIHdlYiBhcHBsaWNhdGlvbnMuCiAqCiAqIEBhdXRob3IgRGF2aWQgSS4gTGVobiA8ZGxlaG5AZGlnaXRhbGJhemFhci5jb20+CiAqCiAqIENvcHlyaWdodCAyMDA4LTIwMTMgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovKiBERUJVRyBBUEkgKi8KZm9yZ2UuZGVidWcgPSBmb3JnZS5kZWJ1ZyB8fCB7fTsKCi8vIFByaXZhdGUgc3RvcmFnZSBmb3IgZGVidWdnaW5nLgovLyBVc2VmdWwgdG8gZXhwb3NlIGRhdGEgdGhhdCBpcyBvdGhlcndpc2UgdW52aWV3YWJsZSBiZWhpbmQgY2xvc3VyZXMuCi8vIE5PVEU6IHJlbWVtYmVyIHRoYXQgdGhpcyBjYW4gaG9sZCByZWZlcmVuY2VzIHRvIGRhdGEgYW5kIGNhdXNlIGxlYWtzIQovLyBmb3JtYXQgaXMgImZvcmdlLl9kZWJ1Zy48bW9kdWxlbmFtZT4uPGRhdGFuYW1lPiA9IGRhdGEiCi8vIEV4YW1wbGU6Ci8vIChmdW5jdGlvbigpIHsKLy8gICB2YXIgY2F0ID0gJ2ZvcmdlLnRlc3QuVGVzdCc7IC8vIGRlYnVnZ2luZyBjYXRlZ29yeQovLyAgIHZhciBzU3RhdGUgPSB7Li4ufTsgLy8gbG9jYWwgc3RhdGUKLy8gICBmb3JnZS5kZWJ1Zy5zZXQoY2F0LCAnc1N0YXRlJywgc1N0YXRlKTsKLy8gfSkoKTsKZm9yZ2UuZGVidWcuc3RvcmFnZSA9IHt9OwoKLyoqCiAqIEdldHMgZGVidWcgZGF0YS4gT21pdCBuYW1lIGZvciBhbGwgY2F0IGRhdGEgIE9taXQgbmFtZSBhbmQgY2F0IGZvcgogKiBhbGwgZGF0YS4KICoKICogQHBhcmFtIGNhdCBuYW1lIG9mIGRlYnVnZ2luZyBjYXRlZ29yeS4KICogQHBhcmFtIG5hbWUgbmFtZSBvZiBkYXRhIHRvIGdldCAob3B0aW9uYWwpLgogKiBAcmV0dXJuIG9iamVjdCB3aXRoIHJlcXVlc3RlZCBkZWJ1ZyBkYXRhIG9yIHVuZGVmaW5lZC4KICovCmZvcmdlLmRlYnVnLmdldCA9IGZ1bmN0aW9uKGNhdCwgbmFtZSkgewogIHZhciBydmFsOwogIGlmKHR5cGVvZihjYXQpID09PSAndW5kZWZpbmVkJykgewogICAgcnZhbCA9IGZvcmdlLmRlYnVnLnN0b3JhZ2U7CiAgfSBlbHNlIGlmKGNhdCBpbiBmb3JnZS5kZWJ1Zy5zdG9yYWdlKSB7CiAgICBpZih0eXBlb2YobmFtZSkgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIHJ2YWwgPSBmb3JnZS5kZWJ1Zy5zdG9yYWdlW2NhdF07CiAgICB9IGVsc2UgewogICAgICBydmFsID0gZm9yZ2UuZGVidWcuc3RvcmFnZVtjYXRdW25hbWVdOwogICAgfQogIH0KICByZXR1cm4gcnZhbDsKfTsKCi8qKgogKiBTZXRzIGRlYnVnIGRhdGEuCiAqCiAqIEBwYXJhbSBjYXQgbmFtZSBvZiBkZWJ1Z2dpbmcgY2F0ZWdvcnkuCiAqIEBwYXJhbSBuYW1lIG5hbWUgb2YgZGF0YSB0byBzZXQuCiAqIEBwYXJhbSBkYXRhIGRhdGEgdG8gc2V0LgogKi8KZm9yZ2UuZGVidWcuc2V0ID0gZnVuY3Rpb24oY2F0LCBuYW1lLCBkYXRhKSB7CiAgaWYoIShjYXQgaW4gZm9yZ2UuZGVidWcuc3RvcmFnZSkpIHsKICAgIGZvcmdlLmRlYnVnLnN0b3JhZ2VbY2F0XSA9IHt9OwogIH0KICBmb3JnZS5kZWJ1Zy5zdG9yYWdlW2NhdF1bbmFtZV0gPSBkYXRhOwp9OwoKLyoqCiAqIENsZWFycyBkZWJ1ZyBkYXRhLiBPbWl0IG5hbWUgZm9yIGFsbCBjYXQgZGF0YS4gT21pdCBuYW1lIGFuZCBjYXQgZm9yCiAqIGFsbCBkYXRhLgogKgogKiBAcGFyYW0gY2F0IG5hbWUgb2YgZGVidWdnaW5nIGNhdGVnb3J5LgogKiBAcGFyYW0gbmFtZSBuYW1lIG9mIGRhdGEgdG8gY2xlYXIgb3Igb21pdCB0byBjbGVhciBlbnRpcmUgY2F0ZWdvcnkuCiAqLwpmb3JnZS5kZWJ1Zy5jbGVhciA9IGZ1bmN0aW9uKGNhdCwgbmFtZSkgewogIGlmKHR5cGVvZihjYXQpID09PSAndW5kZWZpbmVkJykgewogICAgZm9yZ2UuZGVidWcuc3RvcmFnZSA9IHt9OwogIH0gZWxzZSBpZihjYXQgaW4gZm9yZ2UuZGVidWcuc3RvcmFnZSkgewogICAgaWYodHlwZW9mKG5hbWUpID09PSAndW5kZWZpbmVkJykgewogICAgICBkZWxldGUgZm9yZ2UuZGVidWcuc3RvcmFnZVtjYXRdOwogICAgfSBlbHNlIHsKICAgICAgZGVsZXRlIGZvcmdlLmRlYnVnLnN0b3JhZ2VbY2F0XVtuYW1lXTsKICAgIH0KICB9Cn07Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdkZWJ1Zyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9kZWJ1ZycsWydyZXF1aXJlJywgJ21vZHVsZSddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBKYXZhc2NyaXB0IGltcGxlbWVudGF0aW9uIG9mIFJTQS1LRU0uCiAqCiAqIEBhdXRob3IgTGF1dGFybyBDb3p6YW5pIFJvZHJpZ3VlegogKiBAYXV0aG9yIERhdmUgTG9uZ2xleQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTQgTGF1dGFybyBDb3p6YW5pIDxsYXV0YXJvLmNvenphbmlAc2N5dGwuY29tPgogKiBDb3B5cmlnaHQgKGMpIDIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7Cgpmb3JnZS5rZW0gPSBmb3JnZS5rZW0gfHwge307Cgp2YXIgQmlnSW50ZWdlciA9IGZvcmdlLmpzYm4uQmlnSW50ZWdlcjsKCi8qKgogKiBUaGUgQVBJIGZvciB0aGUgUlNBIEtleSBFbmNhcHN1bGF0aW9uIE1lY2hhbmlzbSAoUlNBLUtFTSkgZnJvbSBJU08gMTgwMzMtMi4KICovCmZvcmdlLmtlbS5yc2EgPSB7fTsKCi8qKgogKiBDcmVhdGVzIGFuIFJTQSBLRU0gQVBJIG9iamVjdCBmb3IgZ2VuZXJhdGluZyBhIHNlY3JldCBhc3ltbWV0cmljIGtleS4KICoKICogVGhlIHN5bW1ldHJpYyBrZXkgbWF5IGJlIGdlbmVyYXRlZCB2aWEgYSBjYWxsIHRvICdlbmNyeXB0Jywgd2hpY2ggd2lsbAogKiBwcm9kdWNlIGEgY2lwaGVydGV4dCB0byBiZSB0cmFuc21pdHRlZCB0byB0aGUgcmVjaXBpZW50IGFuZCBhIGtleSB0byBiZQogKiBrZXB0IHNlY3JldC4gVGhlIGNpcGhlcnRleHQgaXMgYSBwYXJhbWV0ZXIgdG8gYmUgcGFzc2VkIHRvICdkZWNyeXB0JyB3aGljaAogKiB3aWxsIHByb2R1Y2UgdGhlIHNhbWUgc2VjcmV0IGtleSBmb3IgdGhlIHJlY2lwaWVudCB0byB1c2UgdG8gZGVjcnlwdCBhCiAqIG1lc3NhZ2UgdGhhdCB3YXMgZW5jcnlwdGVkIHdpdGggdGhlIHNlY3JldCBrZXkuCiAqCiAqIEBwYXJhbSBrZGYgdGhlIEtERiBBUEkgdG8gdXNlIChlZzogbmV3IGZvcmdlLmtlbS5rZGYxKCkpLgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIFtwcm5nXSBhIGN1c3RvbSBjcnlwdG8tc2VjdXJlIHBzZXVkby1yYW5kb20gbnVtYmVyIGdlbmVyYXRvciB0byB1c2UsCiAqICAgICAgICAgICAgdGhhdCBtdXN0IGRlZmluZSAiZ2V0Qnl0ZXNTeW5jIi4KICovCmZvcmdlLmtlbS5yc2EuY3JlYXRlID0gZnVuY3Rpb24oa2RmLCBvcHRpb25zKSB7CiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307CiAgdmFyIHBybmcgPSBvcHRpb25zLnBybmcgfHwgZm9yZ2UucmFuZG9tOwoKICB2YXIga2VtID0ge307CgogIC8qKgogICAqIEdlbmVyYXRlcyBhIHNlY3JldCBrZXkgYW5kIGl0cyBlbmNhcHN1bGF0aW9uLgogICAqCiAgICogQHBhcmFtIHB1YmxpY0tleSB0aGUgUlNBIHB1YmxpYyBrZXkgdG8gZW5jcnlwdCB3aXRoLgogICAqIEBwYXJhbSBrZXlMZW5ndGggdGhlIGxlbmd0aCwgaW4gYnl0ZXMsIG9mIHRoZSBzZWNyZXQga2V5IHRvIGdlbmVyYXRlLgogICAqCiAgICogQHJldHVybiBhbiBvYmplY3Qgd2l0aDoKICAgKiAgIGVuY2Fwc3VsYXRpb246IHRoZSBjaXBoZXJ0ZXh0IGZvciBnZW5lcmF0aW5nIHRoZSBzZWNyZXQga2V5LCBhcyBhCiAgICogICAgIGJpbmFyeS1lbmNvZGVkIHN0cmluZyBvZiBieXRlcy4KICAgKiAgIGtleTogdGhlIHNlY3JldCBrZXkgdG8gdXNlIGZvciBlbmNyeXB0aW5nIGEgbWVzc2FnZS4KICAgKi8KICBrZW0uZW5jcnlwdCA9IGZ1bmN0aW9uKHB1YmxpY0tleSwga2V5TGVuZ3RoKSB7CiAgICAvLyBnZW5lcmF0ZSBhIHJhbmRvbSByIHdoZXJlIDEgPiByID4gbgogICAgdmFyIGJ5dGVMZW5ndGggPSBNYXRoLmNlaWwocHVibGljS2V5Lm4uYml0TGVuZ3RoKCkgLyA4KTsKICAgIHZhciByOwogICAgZG8gewogICAgICByID0gbmV3IEJpZ0ludGVnZXIoCiAgICAgICAgZm9yZ2UudXRpbC5ieXRlc1RvSGV4KHBybmcuZ2V0Qnl0ZXNTeW5jKGJ5dGVMZW5ndGgpKSwKICAgICAgICAxNikubW9kKHB1YmxpY0tleS5uKTsKICAgIH0gd2hpbGUoci5lcXVhbHMoQmlnSW50ZWdlci5aRVJPKSk7CgogICAgLy8gcHJlcGVuZCByIHdpdGggemVyb3MKICAgIHIgPSBmb3JnZS51dGlsLmhleFRvQnl0ZXMoci50b1N0cmluZygxNikpOwogICAgdmFyIHplcm9zID0gYnl0ZUxlbmd0aCAtIHIubGVuZ3RoOwogICAgaWYoemVyb3MgPiAwKSB7CiAgICAgIHIgPSBmb3JnZS51dGlsLmZpbGxTdHJpbmcoU3RyaW5nLmZyb21DaGFyQ29kZSgwKSwgemVyb3MpICsgcjsKICAgIH0KCiAgICAvLyBlbmNyeXB0IHRoZSByYW5kb20KICAgIHZhciBlbmNhcHN1bGF0aW9uID0gcHVibGljS2V5LmVuY3J5cHQociwgJ05PTkUnKTsKCiAgICAvLyBnZW5lcmF0ZSB0aGUgc2VjcmV0IGtleQogICAgdmFyIGtleSA9IGtkZi5nZW5lcmF0ZShyLCBrZXlMZW5ndGgpOwoKICAgIHJldHVybiB7ZW5jYXBzdWxhdGlvbjogZW5jYXBzdWxhdGlvbiwga2V5OiBrZXl9OwogIH07CgogIC8qKgogICAqIERlY3J5cHRzIGFuIGVuY2Fwc3VsYXRlZCBzZWNyZXQga2V5LgogICAqCiAgICogQHBhcmFtIHByaXZhdGVLZXkgdGhlIFJTQSBwcml2YXRlIGtleSB0byBkZWNyeXB0IHdpdGguCiAgICogQHBhcmFtIGVuY2Fwc3VsYXRpb24gdGhlIGNpcGhlcnRleHQgZm9yIGdlbmVyYXRpbmcgdGhlIHNlY3JldCBrZXksIGFzCiAgICogICAgICAgICAgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcgb2YgYnl0ZXMuCiAgICogQHBhcmFtIGtleUxlbmd0aCB0aGUgbGVuZ3RoLCBpbiBieXRlcywgb2YgdGhlIHNlY3JldCBrZXkgdG8gZ2VuZXJhdGUuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBzZWNyZXQga2V5IGFzIGEgYmluYXJ5LWVuY29kZWQgc3RyaW5nIG9mIGJ5dGVzLgogICAqLwogIGtlbS5kZWNyeXB0ID0gZnVuY3Rpb24ocHJpdmF0ZUtleSwgZW5jYXBzdWxhdGlvbiwga2V5TGVuZ3RoKSB7CiAgICAvLyBkZWNyeXB0IHRoZSBlbmNhcHN1bGF0aW9uIGFuZCBnZW5lcmF0ZSB0aGUgc2VjcmV0IGtleQogICAgdmFyIHIgPSBwcml2YXRlS2V5LmRlY3J5cHQoZW5jYXBzdWxhdGlvbiwgJ05PTkUnKTsKICAgIHJldHVybiBrZGYuZ2VuZXJhdGUociwga2V5TGVuZ3RoKTsKICB9OwoKICByZXR1cm4ga2VtOwp9OwoKLy8gVE9ETzogYWRkIGZvcmdlLmtlbS5rZGYuY3JlYXRlKCdLREYxJywge21kOiAuLi4sIC4uLn0pIEFQST8KCi8qKgogKiBDcmVhdGVzIGEga2V5IGRlcml2YXRpb24gQVBJIG9iamVjdCB0aGF0IGltcGxlbWVudHMgS0RGMSBwZXIgSVNPIDE4MDMzLTIuCiAqCiAqIEBwYXJhbSBtZCB0aGUgaGFzaCBBUEkgdG8gdXNlLgogKiBAcGFyYW0gW2RpZ2VzdExlbmd0aF0gYW4gb3B0aW9uYWwgZGlnZXN0IGxlbmd0aCB0aGF0IG11c3QgYmUgcG9zaXRpdmUgYW5kCiAqICAgICAgICAgIGxlc3MgdGhhbiBvciBlcXVhbCB0byBtZC5kaWdlc3RMZW5ndGguCiAqCiAqIEByZXR1cm4gYSBLREYxIEFQSSBvYmplY3QuCiAqLwpmb3JnZS5rZW0ua2RmMSA9IGZ1bmN0aW9uKG1kLCBkaWdlc3RMZW5ndGgpIHsKICBfY3JlYXRlS0RGKHRoaXMsIG1kLCAwLCBkaWdlc3RMZW5ndGggfHwgbWQuZGlnZXN0TGVuZ3RoKTsKfTsKCi8qKgogKiBDcmVhdGVzIGEga2V5IGRlcml2YXRpb24gQVBJIG9iamVjdCB0aGF0IGltcGxlbWVudHMgS0RGMiBwZXIgSVNPIDE4MDMzLTIuCiAqCiAqIEBwYXJhbSBtZCB0aGUgaGFzaCBBUEkgdG8gdXNlLgogKiBAcGFyYW0gW2RpZ2VzdExlbmd0aF0gYW4gb3B0aW9uYWwgZGlnZXN0IGxlbmd0aCB0aGF0IG11c3QgYmUgcG9zaXRpdmUgYW5kCiAqICAgICAgICAgIGxlc3MgdGhhbiBvciBlcXVhbCB0byBtZC5kaWdlc3RMZW5ndGguCiAqCiAqIEByZXR1cm4gYSBLREYyIEFQSSBvYmplY3QuCiAqLwpmb3JnZS5rZW0ua2RmMiA9IGZ1bmN0aW9uKG1kLCBkaWdlc3RMZW5ndGgpIHsKICBfY3JlYXRlS0RGKHRoaXMsIG1kLCAxLCBkaWdlc3RMZW5ndGggfHwgbWQuZGlnZXN0TGVuZ3RoKTsKfTsKCi8qKgogKiBDcmVhdGVzIGEgS0RGMSBvciBLREYyIEFQSSBvYmplY3QuCiAqCiAqIEBwYXJhbSBtZCB0aGUgaGFzaCBBUEkgdG8gdXNlLgogKiBAcGFyYW0gY291bnRlclN0YXJ0IHRoZSBzdGFydGluZyBpbmRleCBmb3IgdGhlIGNvdW50ZXIuCiAqIEBwYXJhbSBkaWdlc3RMZW5ndGggdGhlIGRpZ2VzdCBsZW5ndGggdG8gdXNlLgogKgogKiBAcmV0dXJuIHRoZSBLREYgQVBJIG9iamVjdC4KICovCmZ1bmN0aW9uIF9jcmVhdGVLREYoa2RmLCBtZCwgY291bnRlclN0YXJ0LCBkaWdlc3RMZW5ndGgpIHsKICAvKioKICAgKiBHZW5lcmF0ZSBhIGtleSBvZiB0aGUgc3BlY2lmaWVkIGxlbmd0aC4KICAgKgogICAqIEBwYXJhbSB4IHRoZSBiaW5hcnktZW5jb2RlZCBieXRlIHN0cmluZyB0byBnZW5lcmF0ZSBhIGtleSBmcm9tLgogICAqIEBwYXJhbSBsZW5ndGggdGhlIG51bWJlciBvZiBieXRlcyB0byBnZW5lcmF0ZSAodGhlIHNpemUgb2YgdGhlIGtleSkuCiAgICoKICAgKiBAcmV0dXJuIHRoZSBrZXkgYXMgYSBiaW5hcnktZW5jb2RlZCBzdHJpbmcuCiAgICovCiAga2RmLmdlbmVyYXRlID0gZnVuY3Rpb24oeCwgbGVuZ3RoKSB7CiAgICB2YXIga2V5ID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwoKICAgIC8vIHJ1biBjb3VudGVyIGZyb20gY291bnRlclN0YXJ0IHRvIGNlaWwobGVuZ3RoIC8gSGFzaC5sZW4pCiAgICB2YXIgayA9IE1hdGguY2VpbChsZW5ndGggLyBkaWdlc3RMZW5ndGgpICsgY291bnRlclN0YXJ0OwoKICAgIHZhciBjID0gbmV3IGZvcmdlLnV0aWwuQnl0ZUJ1ZmZlcigpOwogICAgZm9yKHZhciBpID0gY291bnRlclN0YXJ0OyBpIDwgazsgKytpKSB7CiAgICAgIC8vIEkyT1NQKGksIDQpOiBjb252ZXJ0IGNvdW50ZXIgdG8gYW4gb2N0ZXQgc3RyaW5nIG9mIDQgb2N0ZXRzCiAgICAgIGMucHV0SW50MzIoaSk7CgogICAgICAvLyBkaWdlc3QgJ3gnIGFuZCB0aGUgY291bnRlciBhbmQgYWRkIHRoZSByZXN1bHQgdG8gdGhlIGtleQogICAgICBtZC5zdGFydCgpOwogICAgICBtZC51cGRhdGUoeCArIGMuZ2V0Qnl0ZXMoKSk7CiAgICAgIHZhciBoYXNoID0gbWQuZGlnZXN0KCk7CiAgICAgIGtleS5wdXRCeXRlcyhoYXNoLmdldEJ5dGVzKGRpZ2VzdExlbmd0aCkpOwogICAgfQoKICAgIC8vIHRydW5jYXRlIHRvIHRoZSBjb3JyZWN0IGtleSBsZW5ndGgKICAgIGtleS50cnVuY2F0ZShrZXkubGVuZ3RoKCkgLSBsZW5ndGgpOwogICAgcmV0dXJuIGtleS5nZXRCeXRlcygpOwogIH07Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ2tlbSc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9rZW0nLFsncmVxdWlyZScsICdtb2R1bGUnLCAnLi91dGlsJywnLi9yYW5kb20nLCcuL2pzYm4nXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogQ3Jvc3MtYnJvd3NlciBzdXBwb3J0IGZvciBsb2dnaW5nIGluIGEgd2ViIGFwcGxpY2F0aW9uLgogKgogKiBAYXV0aG9yIERhdmlkIEkuIExlaG4gPGRsZWhuQGRpZ2l0YWxiYXphYXIuY29tPgogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDgtMjAxMyBEaWdpdGFsIEJhemFhciwgSW5jLgogKi8KKGZ1bmN0aW9uKCkgewovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSBpbXBsZW1lbnRhdGlvbiAjIyMjIyMjIyMjICovCmZ1bmN0aW9uIGluaXRNb2R1bGUoZm9yZ2UpIHsKCi8qIExPRyBBUEkgKi8KZm9yZ2UubG9nID0gZm9yZ2UubG9nIHx8IHt9OwoKLyoqCiAqIEFwcGxpY2F0aW9uIGxvZ2dpbmcgc3lzdGVtLgogKgogKiBFYWNoIGxvZ2dlciBsZXZlbCBhdmFpbGFibGUgYXMgaXQncyBvd24gZnVuY3Rpb24gb2YgdGhlIGZvcm06CiAqICAgZm9yZ2UubG9nLmxldmVsKGNhdGVnb3J5LCBhcmdzLi4uKQogKiBUaGUgY2F0ZWdvcnkgaXMgYW4gYXJiaXRyYXJ5IHN0cmluZywgYW5kIHRoZSBhcmdzIGFyZSB0aGUgc2FtZSBhcwogKiBGaXJlYnVnJ3MgY29uc29sZS5sb2cgQVBJLiBCeSBkZWZhdWx0IHRoZSBjYWxsIHdpbGwgYmUgb3V0cHV0IGFzOgogKiAgICdMRVZFTCBbY2F0ZWdvcnldIDxhcmdzWzBdPiwgYXJnc1sxXSwgLi4uJwogKiBUaGlzIGVuYWJsZXMgcHJvcGVyICUgZm9ybWF0dGluZyB2aWEgdGhlIGZpcnN0IGFyZ3VtZW50LgogKiBFYWNoIGNhdGVnb3J5IGlzIGVuYWJsZWQgYnkgZGVmYXVsdCBidXQgY2FuIGJlIGVuYWJsZWQgb3IgZGlzYWJsZWQgd2l0aAogKiB0aGUgc2V0Q2F0ZWdvcnlFbmFibGVkKCkgZnVuY3Rpb24uCiAqLwovLyBsaXN0IG9mIGtub3duIGxldmVscwpmb3JnZS5sb2cubGV2ZWxzID0gWwogICdub25lJywgJ2Vycm9yJywgJ3dhcm5pbmcnLCAnaW5mbycsICdkZWJ1ZycsICd2ZXJib3NlJywgJ21heCddOwovLyBpbmZvIG9uIHRoZSBsZXZlbHMgaW5kZXhlZCBieSBuYW1lOgovLyAgIGluZGV4OiBsZXZlbCBpbmRleAovLyAgIG5hbWU6IHVwcGVyY2FzZWQgZGlzcGxheSBuYW1lCnZhciBzTGV2ZWxJbmZvID0ge307Ci8vIGxpc3Qgb2YgbG9nZ2Vycwp2YXIgc0xvZ2dlcnMgPSBbXTsKLyoqCiAqIFN0YW5kYXJkIGNvbnNvbGUgbG9nZ2VyLiBJZiBubyBjb25zb2xlIHN1cHBvcnQgaXMgZW5hYmxlZCB0aGlzIHdpbGwKICogcmVtYWluIG51bGwuIENoZWNrIGJlZm9yZSB1c2luZy4KICovCnZhciBzQ29uc29sZUxvZ2dlciA9IG51bGw7CgovLyBsb2dnZXIgZmxhZ3MKLyoqCiAqIExvY2sgdGhlIGxldmVsIGF0IHRoZSBjdXJyZW50IHZhbHVlLiBVc2VkIGluIGNhc2VzIHdoZXJlIHVzZXIgY29uZmlnIG1heQogKiBzZXQgdGhlIGxldmVsIHN1Y2ggdGhhdCBvbmx5IGNyaXRpY2FsIG1lc3NhZ2VzIGFyZSBzZWVuIGJ1dCBtb3JlIHZlcmJvc2UKICogbWVzc2FnZXMgYXJlIG5lZWRlZCBmb3IgZGVidWdnaW5nIG9yIG90aGVyIHB1cnBvc2VzLgogKi8KZm9yZ2UubG9nLkxFVkVMX0xPQ0tFRCA9ICgxIDw8IDEpOwovKioKICogQWx3YXlzIGNhbGwgbG9nIGZ1bmN0aW9uLiBCeSBkZWZhdWx0LCB0aGUgbG9nZ2luZyBzeXN0ZW0gd2lsbCBjaGVjayB0aGUKICogbWVzc2FnZSBsZXZlbCBhZ2FpbnN0IGxvZ2dlci5sZXZlbCBiZWZvcmUgY2FsbGluZyB0aGUgbG9nIGZ1bmN0aW9uLiBUaGlzCiAqIGZsYWcgYWxsb3dzIHRoZSBmdW5jdGlvbiB0byBkbyBpdHMgb3duIGNoZWNrLgogKi8KZm9yZ2UubG9nLk5PX0xFVkVMX0NIRUNLID0gKDEgPDwgMik7Ci8qKgogKiBQZXJmb3JtIG1lc3NhZ2UgaW50ZXJwb2xhdGlvbiB3aXRoIHRoZSBwYXNzZWQgYXJndW1lbnRzLiAiJSIgc3R5bGUKICogZmllbGRzIGluIGxvZyBtZXNzYWdlcyB3aWxsIGJlIHJlcGxhY2VkIGJ5IGFyZ3VtZW50cyBhcyBuZWVkZWQuIFNvbWUKICogbG9nZ2Vycywgc3VjaCBhcyBGaXJlYnVnLCBtYXkgZG8gdGhpcyBhdXRvbWF0aWNhbGx5LiBUaGUgb3JpZ2luYWwgbG9nCiAqIG1lc3NhZ2Ugd2lsbCBiZSBhdmFpbGFibGUgYXMgJ21lc3NhZ2UnIGFuZCB0aGUgaW50ZXJwb2xhdGVkIHZlcnNpb24gd2lsbAogKiBiZSBhdmFpbGFibGUgYXMgJ2Z1bGxNZXNzYWdlJy4KICovCmZvcmdlLmxvZy5JTlRFUlBPTEFURSA9ICgxIDw8IDMpOwoKLy8gc2V0dXAgZWFjaCBsb2cgbGV2ZWwKZm9yKHZhciBpID0gMDsgaSA8IGZvcmdlLmxvZy5sZXZlbHMubGVuZ3RoOyArK2kpIHsKICB2YXIgbGV2ZWwgPSBmb3JnZS5sb2cubGV2ZWxzW2ldOwogIHNMZXZlbEluZm9bbGV2ZWxdID0gewogICAgaW5kZXg6IGksCiAgICBuYW1lOiBsZXZlbC50b1VwcGVyQ2FzZSgpCiAgfTsKfQoKLyoqCiAqIE1lc3NhZ2UgbG9nZ2VyLiBXaWxsIGRpc3BhdGNoIGEgbWVzc2FnZSB0byByZWdpc3RlcmVkIGxvZ2dlcnMgYXMgbmVlZGVkLgogKgogKiBAcGFyYW0gbWVzc2FnZSBtZXNzYWdlIG9iamVjdAogKi8KZm9yZ2UubG9nLmxvZ01lc3NhZ2UgPSBmdW5jdGlvbihtZXNzYWdlKSB7CiAgdmFyIG1lc3NhZ2VMZXZlbEluZGV4ID0gc0xldmVsSW5mb1ttZXNzYWdlLmxldmVsXS5pbmRleDsKICBmb3IodmFyIGkgPSAwOyBpIDwgc0xvZ2dlcnMubGVuZ3RoOyArK2kpIHsKICAgIHZhciBsb2dnZXIgPSBzTG9nZ2Vyc1tpXTsKICAgIGlmKGxvZ2dlci5mbGFncyAmIGZvcmdlLmxvZy5OT19MRVZFTF9DSEVDSykgewogICAgICBsb2dnZXIuZihtZXNzYWdlKTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIGdldCBsb2dnZXIgbGV2ZWwKICAgICAgdmFyIGxvZ2dlckxldmVsSW5kZXggPSBzTGV2ZWxJbmZvW2xvZ2dlci5sZXZlbF0uaW5kZXg7CiAgICAgIC8vIGNoZWNrIGxldmVsCiAgICAgIGlmKG1lc3NhZ2VMZXZlbEluZGV4IDw9IGxvZ2dlckxldmVsSW5kZXgpIHsKICAgICAgICAvLyBtZXNzYWdlIGNyaXRpY2FsIGVub3VnaCwgY2FsbCBsb2dnZXIKICAgICAgICBsb2dnZXIuZihsb2dnZXIsIG1lc3NhZ2UpOwogICAgICB9CiAgICB9CiAgfQp9OwoKLyoqCiAqIFNldHMgdGhlICdzdGFuZGFyZCcga2V5IG9uIGEgbWVzc2FnZSBvYmplY3QgdG86CiAqICJMRVZFTCBbY2F0ZWdvcnldICIgKyBtZXNzYWdlCiAqCiAqIEBwYXJhbSBtZXNzYWdlIGEgbWVzc2FnZSBsb2cgb2JqZWN0CiAqLwpmb3JnZS5sb2cucHJlcGFyZVN0YW5kYXJkID0gZnVuY3Rpb24obWVzc2FnZSkgewogIGlmKCEoJ3N0YW5kYXJkJyBpbiBtZXNzYWdlKSkgewogICAgbWVzc2FnZS5zdGFuZGFyZCA9CiAgICAgIHNMZXZlbEluZm9bbWVzc2FnZS5sZXZlbF0ubmFtZSArCiAgICAgIC8vJyAnICsgK21lc3NhZ2UudGltZXN0YW1wICsKICAgICAgJyBbJyArIG1lc3NhZ2UuY2F0ZWdvcnkgKyAnXSAnICsKICAgICAgbWVzc2FnZS5tZXNzYWdlOwogIH0KfTsKCi8qKgogKiBTZXRzIHRoZSAnZnVsbCcga2V5IG9uIGEgbWVzc2FnZSBvYmplY3QgdG8gdGhlIG9yaWdpbmFsIG1lc3NhZ2UKICogaW50ZXJwb2xhdGVkIHZpYSAlIGZvcm1hdHRpbmcgd2l0aCB0aGUgbWVzc2FnZSBhcmd1bWVudHMuCiAqCiAqIEBwYXJhbSBtZXNzYWdlIGEgbWVzc2FnZSBsb2cgb2JqZWN0LgogKi8KZm9yZ2UubG9nLnByZXBhcmVGdWxsID0gZnVuY3Rpb24obWVzc2FnZSkgewogIGlmKCEoJ2Z1bGwnIGluIG1lc3NhZ2UpKSB7CiAgICAvLyBjb3B5IGFyZ3MgYW5kIGluc2VydCBtZXNzYWdlIGF0IHRoZSBmcm9udAogICAgdmFyIGFyZ3MgPSBbbWVzc2FnZS5tZXNzYWdlXTsKICAgIGFyZ3MgPSBhcmdzLmNvbmNhdChbXSB8fCBtZXNzYWdlWydhcmd1bWVudHMnXSk7CiAgICAvLyBmb3JtYXQgdGhlIG1lc3NhZ2UKICAgIG1lc3NhZ2UuZnVsbCA9IGZvcmdlLnV0aWwuZm9ybWF0LmFwcGx5KHRoaXMsIGFyZ3MpOwogIH0KfTsKCi8qKgogKiBBcHBsaWVzIGJvdGggcHJlcGFyc2VTdGFuZGFyZCgpIGFuZCBwcmVwYXJlRnVsbCgpIHRvIGEgbWVzc2FnZSBvYmplY3QgYW5kCiAqIHN0b3JlIHJlc3VsdCBpbiAnc3RhbmRhcmRGdWxsJy4KICoKICogQHBhcmFtIG1lc3NhZ2UgYSBtZXNzYWdlIGxvZyBvYmplY3QuCiAqLwpmb3JnZS5sb2cucHJlcGFyZVN0YW5kYXJkRnVsbCA9IGZ1bmN0aW9uKG1lc3NhZ2UpIHsKICBpZighKCdzdGFuZGFyZEZ1bGwnIGluIG1lc3NhZ2UpKSB7CiAgICAvLyBGSVhNRSBpbXBsZW1lbnQgJ3N0YW5kYXJkRnVsbCcgbG9nZ2luZwogICAgZm9yZ2UubG9nLnByZXBhcmVTdGFuZGFyZChtZXNzYWdlKTsKICAgIG1lc3NhZ2Uuc3RhbmRhcmRGdWxsID0gbWVzc2FnZS5zdGFuZGFyZDsKICB9Cn07CgovLyBjcmVhdGUgbG9nIGxldmVsIGZ1bmN0aW9ucwppZih0cnVlKSB7CiAgLy8gbGV2ZWxzIGZvciB3aGljaCB3ZSB3YW50IGZ1bmN0aW9ucwogIHZhciBsZXZlbHMgPSBbJ2Vycm9yJywgJ3dhcm5pbmcnLCAnaW5mbycsICdkZWJ1ZycsICd2ZXJib3NlJ107CiAgZm9yKHZhciBpID0gMDsgaSA8IGxldmVscy5sZW5ndGg7ICsraSkgewogICAgLy8gd3JhcCBpbiBhIGZ1bmN0aW9uIHRvIGVuc3VyZSBwcm9wZXIgbGV2ZWwgdmFyIGlzIHBhc3NlZAogICAgKGZ1bmN0aW9uKGxldmVsKSB7CiAgICAgIC8vIGNyZWF0ZSBmdW5jdGlvbiBmb3IgdGhpcyBsZXZlbAogICAgICBmb3JnZS5sb2dbbGV2ZWxdID0gZnVuY3Rpb24oY2F0ZWdvcnksIG1lc3NhZ2UvKiwgYXJncy4uLiovKSB7CiAgICAgICAgLy8gY29udmVydCBhcmd1bWVudHMgdG8gcmVhbCBhcnJheSwgcmVtb3ZlIGNhdGVnb3J5IGFuZCBtZXNzYWdlCiAgICAgICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLnNsaWNlKDIpOwogICAgICAgIC8vIGNyZWF0ZSBtZXNzYWdlIG9iamVjdAogICAgICAgIC8vIE5vdGU6IGludGVycG9sYXRpb24gYW5kIHN0YW5kYXJkIGZvcm1hdHRpbmcgaXMgZG9uZSBsYXppbHkKICAgICAgICB2YXIgbXNnID0gewogICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLAogICAgICAgICAgbGV2ZWw6IGxldmVsLAogICAgICAgICAgY2F0ZWdvcnk6IGNhdGVnb3J5LAogICAgICAgICAgbWVzc2FnZTogbWVzc2FnZSwKICAgICAgICAgICdhcmd1bWVudHMnOiBhcmdzCiAgICAgICAgICAvKnN0YW5kYXJkKi8KICAgICAgICAgIC8qZnVsbCovCiAgICAgICAgICAvKmZ1bGxNZXNzYWdlKi8KICAgICAgICB9OwogICAgICAgIC8vIHByb2Nlc3MgdGhpcyBtZXNzYWdlCiAgICAgICAgZm9yZ2UubG9nLmxvZ01lc3NhZ2UobXNnKTsKICAgICAgfTsKICAgIH0pKGxldmVsc1tpXSk7CiAgfQp9CgovKioKICogQ3JlYXRlcyBhIG5ldyBsb2dnZXIgd2l0aCBzcGVjaWZpZWQgY3VzdG9tIGxvZ2dpbmcgZnVuY3Rpb24uCiAqCiAqIFRoZSBsb2dnaW5nIGZ1bmN0aW9uIGhhcyBhIHNpZ25hdHVyZSBvZjoKICogICBmdW5jdGlvbihsb2dnZXIsIG1lc3NhZ2UpCiAqIGxvZ2dlcjogY3VycmVudCBsb2dnZXIKICogbWVzc2FnZTogb2JqZWN0OgogKiAgIGxldmVsOiBsZXZlbCBpZAogKiAgIGNhdGVnb3J5OiBjYXRlZ29yeQogKiAgIG1lc3NhZ2U6IHN0cmluZyBtZXNzYWdlCiAqICAgYXJndW1lbnRzOiBBcnJheSBvZiBleHRyYSBhcmd1bWVudHMKICogICBmdWxsTWVzc2FnZTogaW50ZXJwb2xhdGVkIG1lc3NhZ2UgYW5kIGFyZ3VtZW50cyBpZiBJTlRFUlBPTEFURSBmbGFnIHNldAogKgogKiBAcGFyYW0gbG9nRnVuY3Rpb24gYSBsb2dnaW5nIGZ1bmN0aW9uIHdoaWNoIHRha2VzIGEgbG9nIG1lc3NhZ2Ugb2JqZWN0CiAqICAgICAgICAgIGFzIGEgcGFyYW1ldGVyLgogKgogKiBAcmV0dXJuIGEgbG9nZ2VyIG9iamVjdC4KICovCmZvcmdlLmxvZy5tYWtlTG9nZ2VyID0gZnVuY3Rpb24obG9nRnVuY3Rpb24pIHsKICB2YXIgbG9nZ2VyID0gewogICAgZmxhZ3M6IDAsCiAgICBmOiBsb2dGdW5jdGlvbgogIH07CiAgZm9yZ2UubG9nLnNldExldmVsKGxvZ2dlciwgJ25vbmUnKTsKICByZXR1cm4gbG9nZ2VyOwp9OwoKLyoqCiAqIFNldHMgdGhlIGN1cnJlbnQgbG9nIGxldmVsIG9uIGEgbG9nZ2VyLgogKgogKiBAcGFyYW0gbG9nZ2VyIHRoZSB0YXJnZXQgbG9nZ2VyLgogKiBAcGFyYW0gbGV2ZWwgdGhlIG5ldyBtYXhpbXVtIGxvZyBsZXZlbCBhcyBhIHN0cmluZy4KICoKICogQHJldHVybiB0cnVlIGlmIHNldCwgZmFsc2UgaWYgbm90LgogKi8KZm9yZ2UubG9nLnNldExldmVsID0gZnVuY3Rpb24obG9nZ2VyLCBsZXZlbCkgewogIHZhciBydmFsID0gZmFsc2U7CiAgaWYobG9nZ2VyICYmICEobG9nZ2VyLmZsYWdzICYgZm9yZ2UubG9nLkxFVkVMX0xPQ0tFRCkpIHsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBmb3JnZS5sb2cubGV2ZWxzLmxlbmd0aDsgKytpKSB7CiAgICAgIHZhciBhVmFsaWRMZXZlbCA9IGZvcmdlLmxvZy5sZXZlbHNbaV07CiAgICAgIGlmKGxldmVsID09IGFWYWxpZExldmVsKSB7CiAgICAgICAgLy8gc2V0IGxldmVsCiAgICAgICAgbG9nZ2VyLmxldmVsID0gbGV2ZWw7CiAgICAgICAgcnZhbCA9IHRydWU7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9CgogIHJldHVybiBydmFsOwp9OwoKLyoqCiAqIExvY2tzIHRoZSBsb2cgbGV2ZWwgYXQgaXRzIGN1cnJlbnQgdmFsdWUuCiAqCiAqIEBwYXJhbSBsb2dnZXIgdGhlIHRhcmdldCBsb2dnZXIuCiAqIEBwYXJhbSBsb2NrIGJvb2xlYW4gbG9jayB2YWx1ZSwgZGVmYXVsdCB0byB0cnVlLgogKi8KZm9yZ2UubG9nLmxvY2sgPSBmdW5jdGlvbihsb2dnZXIsIGxvY2spIHsKICBpZih0eXBlb2YgbG9jayA9PT0gJ3VuZGVmaW5lZCcgfHwgbG9jaykgewogICAgbG9nZ2VyLmZsYWdzIHw9IGZvcmdlLmxvZy5MRVZFTF9MT0NLRUQ7CiAgfSBlbHNlIHsKICAgIGxvZ2dlci5mbGFncyAmPSB+Zm9yZ2UubG9nLkxFVkVMX0xPQ0tFRDsKICB9Cn07CgovKioKICogQWRkcyBhIGxvZ2dlci4KICoKICogQHBhcmFtIGxvZ2dlciB0aGUgbG9nZ2VyIG9iamVjdC4KICovCmZvcmdlLmxvZy5hZGRMb2dnZXIgPSBmdW5jdGlvbihsb2dnZXIpIHsKICBzTG9nZ2Vycy5wdXNoKGxvZ2dlcik7Cn07CgovLyBzZXR1cCB0aGUgY29uc29sZSBsb2dnZXIgaWYgcG9zc2libGUsIGVsc2UgY3JlYXRlIGZha2UgY29uc29sZS5sb2cKaWYodHlwZW9mKGNvbnNvbGUpICE9PSAndW5kZWZpbmVkJyAmJiAnbG9nJyBpbiBjb25zb2xlKSB7CiAgdmFyIGxvZ2dlcjsKICBpZihjb25zb2xlLmVycm9yICYmIGNvbnNvbGUud2FybiAmJiBjb25zb2xlLmluZm8gJiYgY29uc29sZS5kZWJ1ZykgewogICAgLy8gbG9va3MgbGlrZSBGaXJlYnVnLXN0eWxlIGxvZ2dpbmcgaXMgYXZhaWxhYmxlCiAgICAvLyBsZXZlbCBoYW5kbGVycyBtYXAKICAgIHZhciBsZXZlbEhhbmRsZXJzID0gewogICAgICBlcnJvcjogY29uc29sZS5lcnJvciwKICAgICAgd2FybmluZzogY29uc29sZS53YXJuLAogICAgICBpbmZvOiBjb25zb2xlLmluZm8sCiAgICAgIGRlYnVnOiBjb25zb2xlLmRlYnVnLAogICAgICB2ZXJib3NlOiBjb25zb2xlLmRlYnVnCiAgICB9OwogICAgdmFyIGYgPSBmdW5jdGlvbihsb2dnZXIsIG1lc3NhZ2UpIHsKICAgICAgZm9yZ2UubG9nLnByZXBhcmVTdGFuZGFyZChtZXNzYWdlKTsKICAgICAgdmFyIGhhbmRsZXIgPSBsZXZlbEhhbmRsZXJzW21lc3NhZ2UubGV2ZWxdOwogICAgICAvLyBwcmVwZW5kIHN0YW5kYXJkIG1lc3NhZ2UgYW5kIGNvbmNhdCBhcmdzCiAgICAgIHZhciBhcmdzID0gW21lc3NhZ2Uuc3RhbmRhcmRdOwogICAgICBhcmdzID0gYXJncy5jb25jYXQobWVzc2FnZVsnYXJndW1lbnRzJ10uc2xpY2UoKSk7CiAgICAgIC8vIGFwcGx5IHRvIGxvdy1sZXZlbCBjb25zb2xlIGZ1bmN0aW9uCiAgICAgIGhhbmRsZXIuYXBwbHkoY29uc29sZSwgYXJncyk7CiAgICB9OwogICAgbG9nZ2VyID0gZm9yZ2UubG9nLm1ha2VMb2dnZXIoZik7CiAgfSBlbHNlIHsKICAgIC8vIG9ubHkgYXBwZWFyIHRvIGhhdmUgYmFzaWMgY29uc29sZS5sb2cKICAgIHZhciBmID0gZnVuY3Rpb24obG9nZ2VyLCBtZXNzYWdlKSB7CiAgICAgIGZvcmdlLmxvZy5wcmVwYXJlU3RhbmRhcmRGdWxsKG1lc3NhZ2UpOwogICAgICBjb25zb2xlLmxvZyhtZXNzYWdlLnN0YW5kYXJkRnVsbCk7CiAgICB9OwogICAgbG9nZ2VyID0gZm9yZ2UubG9nLm1ha2VMb2dnZXIoZik7CiAgfQogIGZvcmdlLmxvZy5zZXRMZXZlbChsb2dnZXIsICdkZWJ1ZycpOwogIGZvcmdlLmxvZy5hZGRMb2dnZXIobG9nZ2VyKTsKICBzQ29uc29sZUxvZ2dlciA9IGxvZ2dlcjsKfSBlbHNlIHsKICAvLyBkZWZpbmUgZmFrZSBjb25zb2xlLmxvZyB0byBhdm9pZCBwb3RlbnRpYWwgc2NyaXB0IGVycm9ycyBvbgogIC8vIGJyb3dzZXJzIHRoYXQgZG8gbm90IGhhdmUgY29uc29sZSBsb2dnaW5nCiAgY29uc29sZSA9IHsKICAgIGxvZzogZnVuY3Rpb24oKSB7fQogIH07Cn0KCi8qCiAqIENoZWNrIGZvciBsb2dnaW5nIGNvbnRyb2wgcXVlcnkgdmFycy4KICoKICogY29uc29sZS5sZXZlbD08bGV2ZWwtbmFtZT4KICogU2V0J3MgdGhlIGNvbnNvbGUgbG9nIGxldmVsIGJ5IG5hbWUuICBVc2VmdWwgdG8gb3ZlcnJpZGUgZGVmYXVsdHMgYW5kCiAqIGFsbG93IG1vcmUgdmVyYm9zZSBsb2dnaW5nIGJlZm9yZSBhIHVzZXIgY29uZmlnIGlzIGxvYWRlZC4KICoKICogY29uc29sZS5sb2NrPTx0cnVlfGZhbHNlPgogKiBMb2NrIHRoZSBjb25zb2xlIGxvZyBsZXZlbCBhdCB3aGF0ZXZlciBsZXZlbCBpdCBpcyBzZXQgYXQuICBUaGlzIGlzIHJ1bgogKiBhZnRlciBjb25zb2xlLmxldmVsIGlzIHByb2Nlc3NlZC4gIFVzZWZ1bCB0byBmb3JjZSBhIGxldmVsIG9mIHZlcmJvc2l0eQogKiB0aGF0IGNvdWxkIG90aGVyd2lzZSBiZSBsaW1pdGVkIGJ5IGEgdXNlciBjb25maWcuCiAqLwppZihzQ29uc29sZUxvZ2dlciAhPT0gbnVsbCkgewogIHZhciBxdWVyeSA9IGZvcmdlLnV0aWwuZ2V0UXVlcnlWYXJpYWJsZXMoKTsKICBpZignY29uc29sZS5sZXZlbCcgaW4gcXVlcnkpIHsKICAgIC8vIHNldCB3aXRoIGxhc3QgdmFsdWUKICAgIGZvcmdlLmxvZy5zZXRMZXZlbCgKICAgICAgc0NvbnNvbGVMb2dnZXIsIHF1ZXJ5Wydjb25zb2xlLmxldmVsJ10uc2xpY2UoLTEpWzBdKTsKICB9CiAgaWYoJ2NvbnNvbGUubG9jaycgaW4gcXVlcnkpIHsKICAgIC8vIHNldCB3aXRoIGxhc3QgdmFsdWUKICAgIHZhciBsb2NrID0gcXVlcnlbJ2NvbnNvbGUubG9jayddLnNsaWNlKC0xKVswXTsKICAgIGlmKGxvY2sgPT0gJ3RydWUnKSB7CiAgICAgIGZvcmdlLmxvZy5sb2NrKHNDb25zb2xlTG9nZ2VyKTsKICAgIH0KICB9Cn0KCi8vIHByb3ZpZGUgcHVibGljIGFjY2VzcyB0byBjb25zb2xlIGxvZ2dlcgpmb3JnZS5sb2cuY29uc29sZUxvZ2dlciA9IHNDb25zb2xlTG9nZ2VyOwoKfSAvLyBlbmQgbW9kdWxlIGltcGxlbWVudGF0aW9uCgovKiAjIyMjIyMjIyMjIEJlZ2luIG1vZHVsZSB3cmFwcGVyICMjIyMjIyMjIyMgKi8KdmFyIG5hbWUgPSAnbG9nJzsKaWYodHlwZW9mIGRlZmluZSAhPT0gJ2Z1bmN0aW9uJykgewogIC8vIE5vZGVKUyAtPiBBTUQKICBpZih0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUuZXhwb3J0cykgewogICAgdmFyIG5vZGVKUyA9IHRydWU7CiAgICBkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICAgICAgZmFjdG9yeShyZXF1aXJlLCBtb2R1bGUpOwogICAgfTsKICB9IGVsc2UgewogICAgLy8gPHNjcmlwdD4KICAgIGlmKHR5cGVvZiBmb3JnZSA9PT0gJ3VuZGVmaW5lZCcpIHsKICAgICAgZm9yZ2UgPSB7fTsKICAgIH0KICAgIHJldHVybiBpbml0TW9kdWxlKGZvcmdlKTsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KS5jb25jYXQoaW5pdE1vZHVsZSk7CiAgICAvLyBoYW5kbGUgY2lyY3VsYXIgZGVwZW5kZW5jaWVzCiAgICBmb3JnZSA9IGZvcmdlIHx8IHt9OwogICAgZm9yZ2UuZGVmaW5lZCA9IGZvcmdlLmRlZmluZWQgfHwge307CiAgICBpZihmb3JnZS5kZWZpbmVkW25hbWVdKSB7CiAgICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICAgIH0KICAgIGZvcmdlLmRlZmluZWRbbmFtZV0gPSB0cnVlOwogICAgZm9yKHZhciBpID0gMDsgaSA8IG1vZHMubGVuZ3RoOyArK2kpIHsKICAgICAgbW9kc1tpXShmb3JnZSk7CiAgICB9CiAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgfTsKfTsKdmFyIHRtcERlZmluZSA9IGRlZmluZTsKZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgZGVwcyA9ICh0eXBlb2YgaWRzID09PSAnc3RyaW5nJykgPyBmYWN0b3J5LnNsaWNlKDIpIDogaWRzLnNsaWNlKDIpOwogIGlmKG5vZGVKUykgewogICAgZGVsZXRlIGRlZmluZTsKICAgIHJldHVybiB0bXBEZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7CiAgfQogIGRlZmluZSA9IHRtcERlZmluZTsKICByZXR1cm4gZGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9OwpkZWZpbmUoJ2pzL2xvZycsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL3V0aWwnXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogSmF2YXNjcmlwdCBpbXBsZW1lbnRhdGlvbiBvZiBQS0NTIzcgdjEuNS4KICoKICogQGF1dGhvciBTdGVmYW4gU2llZ2wKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICoKICogQ29weXJpZ2h0IChjKSAyMDEyIFN0ZWZhbiBTaWVnbCA8c3Rlc2llQGJyb2tlbnBpcGUuZGU+CiAqIENvcHlyaWdodCAoYykgMjAxMi0yMDE1IERpZ2l0YWwgQmF6YWFyLCBJbmMuCiAqCiAqIEN1cnJlbnRseSB0aGlzIGltcGxlbWVudGF0aW9uIG9ubHkgc3VwcG9ydHMgQ29udGVudFR5cGUgb2YgRW52ZWxvcGVkRGF0YSwKICogRW5jcnlwdGVkRGF0YSwgb3IgU2lnbmVkRGF0YSBhdCB0aGUgcm9vdCBsZXZlbC4gVGhlIHRvcCBsZXZlbCBlbGVtZW50cyBtYXkKICogY29udGFpbiBvbmx5IGEgQ29udGVudEluZm8gb2YgQ29udGVudFR5cGUgRGF0YSwgaS5lLiBwbGFpbiBkYXRhLiBGdXJ0aGVyCiAqIG5lc3RpbmcgaXMgbm90ICh5ZXQpIHN1cHBvcnRlZC4KICoKICogVGhlIEZvcmdlIHZhbGlkYXRvcnMgZm9yIFBLQ1MgIzcncyBBU04uMSBzdHJ1Y3R1cmVzIGFyZSBhdmFpbGFibGUgZnJvbQogKiBhIHNlcGFyYXRlIGZpbGUgcGtjczdhc24xLmpzLCBzaW5jZSB0aG9zZSBhcmUgcmVmZXJlbmNlZCBmcm9tIG90aGVyCiAqIFBLQ1Mgc3RhbmRhcmRzIGxpa2UgUEtDUyAjMTIuCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKLy8gc2hvcnRjdXQgZm9yIEFTTi4xIEFQSQp2YXIgYXNuMSA9IGZvcmdlLmFzbjE7CgovLyBzaG9ydGN1dCBmb3IgUEtDUyM3IEFQSQp2YXIgcDcgPSBmb3JnZS5wa2NzNyA9IGZvcmdlLnBrY3M3IHx8IHt9OwoKLyoqCiAqIENvbnZlcnRzIGEgUEtDUyM3IG1lc3NhZ2UgZnJvbSBQRU0gZm9ybWF0LgogKgogKiBAcGFyYW0gcGVtIHRoZSBQRU0tZm9ybWF0dGVkIFBLQ1MjNyBtZXNzYWdlLgogKgogKiBAcmV0dXJuIHRoZSBQS0NTIzcgbWVzc2FnZS4KICovCnA3Lm1lc3NhZ2VGcm9tUGVtID0gZnVuY3Rpb24ocGVtKSB7CiAgdmFyIG1zZyA9IGZvcmdlLnBlbS5kZWNvZGUocGVtKVswXTsKCiAgaWYobXNnLnR5cGUgIT09ICdQS0NTNycpIHsKICAgIHZhciBlcnJvciA9IG5ldyBFcnJvcignQ291bGQgbm90IGNvbnZlcnQgUEtDUyM3IG1lc3NhZ2UgZnJvbSBQRU07IFBFTSAnICsKICAgICAgJ2hlYWRlciB0eXBlIGlzIG5vdCAiUEtDUyM3Ii4nKTsKICAgIGVycm9yLmhlYWRlclR5cGUgPSBtc2cudHlwZTsKICAgIHRocm93IGVycm9yOwogIH0KICBpZihtc2cucHJvY1R5cGUgJiYgbXNnLnByb2NUeXBlLnR5cGUgPT09ICdFTkNSWVBURUQnKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NvdWxkIG5vdCBjb252ZXJ0IFBLQ1MjNyBtZXNzYWdlIGZyb20gUEVNOyBQRU0gaXMgZW5jcnlwdGVkLicpOwogIH0KCiAgLy8gY29udmVydCBERVIgdG8gQVNOLjEgb2JqZWN0CiAgdmFyIG9iaiA9IGFzbjEuZnJvbURlcihtc2cuYm9keSk7CgogIHJldHVybiBwNy5tZXNzYWdlRnJvbUFzbjEob2JqKTsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIFBLQ1MjNyBtZXNzYWdlIHRvIFBFTSBmb3JtYXQuCiAqCiAqIEBwYXJhbSBtc2cgVGhlIFBLQ1MjNyBtZXNzYWdlIG9iamVjdAogKiBAcGFyYW0gbWF4bGluZSBUaGUgbWF4aW11bSBjaGFyYWN0ZXJzIHBlciBsaW5lLCBkZWZhdWx0cyB0byA2NC4KICoKICogQHJldHVybiBUaGUgUEVNLWZvcm1hdHRlZCBQS0NTIzcgbWVzc2FnZS4KICovCnA3Lm1lc3NhZ2VUb1BlbSA9IGZ1bmN0aW9uKG1zZywgbWF4bGluZSkgewogIC8vIGNvbnZlcnQgdG8gQVNOLjEsIHRoZW4gREVSLCB0aGVuIFBFTS1lbmNvZGUKICB2YXIgcGVtT2JqID0gewogICAgdHlwZTogJ1BLQ1M3JywKICAgIGJvZHk6IGFzbjEudG9EZXIobXNnLnRvQXNuMSgpKS5nZXRCeXRlcygpCiAgfTsKICByZXR1cm4gZm9yZ2UucGVtLmVuY29kZShwZW1PYmosIHttYXhsaW5lOiBtYXhsaW5lfSk7Cn07CgovKioKICogQ29udmVydHMgYSBQS0NTIzcgbWVzc2FnZSBmcm9tIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiB0aGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgYSBDb250ZW50SW5mby4KICoKICogQHJldHVybiB0aGUgUEtDUyM3IG1lc3NhZ2UuCiAqLwpwNy5tZXNzYWdlRnJvbUFzbjEgPSBmdW5jdGlvbihvYmopIHsKICAvLyB2YWxpZGF0ZSByb290IGxldmVsIENvbnRlbnRJbmZvIGFuZCBjYXB0dXJlIGRhdGEKICB2YXIgY2FwdHVyZSA9IHt9OwogIHZhciBlcnJvcnMgPSBbXTsKICBpZighYXNuMS52YWxpZGF0ZShvYmosIHA3LmFzbjEuY29udGVudEluZm9WYWxpZGF0b3IsIGNhcHR1cmUsIGVycm9ycykpCiAgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzcgbWVzc2FnZS4gJyArCiAgICAgICdBU04uMSBvYmplY3QgaXMgbm90IGFuIFBLQ1MjNyBDb250ZW50SW5mby4nKTsKICAgIGVycm9yLmVycm9ycyA9IGVycm9yczsKICAgIHRocm93IGVycm9yOwogIH0KCiAgdmFyIGNvbnRlbnRUeXBlID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLmNvbnRlbnRUeXBlKTsKICB2YXIgbXNnOwoKICBzd2l0Y2goY29udGVudFR5cGUpIHsKICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMuZW52ZWxvcGVkRGF0YToKICAgICAgbXNnID0gcDcuY3JlYXRlRW52ZWxvcGVkRGF0YSgpOwogICAgICBicmVhazsKCiAgICBjYXNlIGZvcmdlLnBraS5vaWRzLmVuY3J5cHRlZERhdGE6CiAgICAgIG1zZyA9IHA3LmNyZWF0ZUVuY3J5cHRlZERhdGEoKTsKICAgICAgYnJlYWs7CgogICAgY2FzZSBmb3JnZS5wa2kub2lkcy5zaWduZWREYXRhOgogICAgICBtc2cgPSBwNy5jcmVhdGVTaWduZWREYXRhKCk7CiAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IHJlYWQgUEtDUyM3IG1lc3NhZ2UuIENvbnRlbnRUeXBlIHdpdGggT0lEICcgKwogICAgICAgIGNvbnRlbnRUeXBlICsgJyBpcyBub3QgKHlldCkgc3VwcG9ydGVkLicpOwogIH0KCiAgbXNnLmZyb21Bc24xKGNhcHR1cmUuY29udGVudC52YWx1ZVswXSk7CiAgcmV0dXJuIG1zZzsKfTsKCnA3LmNyZWF0ZVNpZ25lZERhdGEgPSBmdW5jdGlvbigpIHsKICB2YXIgbXNnID0gbnVsbDsKICBtc2cgPSB7CiAgICB0eXBlOiBmb3JnZS5wa2kub2lkcy5zaWduZWREYXRhLAogICAgdmVyc2lvbjogMSwKICAgIGNlcnRpZmljYXRlczogW10sCiAgICBjcmxzOiBbXSwKICAgIC8vIFRPRE86IGFkZCBqc29uLWZvcm1hdHRlZCBzaWduZXIgc3R1ZmYgaGVyZT8KICAgIHNpZ25lcnM6IFtdLAogICAgLy8gcG9wdWxhdGVkIGR1cmluZyBzaWduKCkKICAgIGRpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXJzOiBbXSwKICAgIGNvbnRlbnRJbmZvOiBudWxsLAogICAgc2lnbmVySW5mb3M6IFtdLAoKICAgIGZyb21Bc24xOiBmdW5jdGlvbihvYmopIHsKICAgICAgLy8gdmFsaWRhdGUgU2lnbmVkRGF0YSBjb250ZW50IGJsb2NrIGFuZCBjYXB0dXJlIGRhdGEuCiAgICAgIF9mcm9tQXNuMShtc2csIG9iaiwgcDcuYXNuMS5zaWduZWREYXRhVmFsaWRhdG9yKTsKICAgICAgbXNnLmNlcnRpZmljYXRlcyA9IFtdOwogICAgICBtc2cuY3JscyA9IFtdOwogICAgICBtc2cuZGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllcnMgPSBbXTsKICAgICAgbXNnLmNvbnRlbnRJbmZvID0gbnVsbDsKICAgICAgbXNnLnNpZ25lckluZm9zID0gW107CgogICAgICB2YXIgY2VydHMgPSBtc2cucmF3Q2FwdHVyZS5jZXJ0aWZpY2F0ZXMudmFsdWU7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBjZXJ0cy5sZW5ndGg7ICsraSkgewogICAgICAgIG1zZy5jZXJ0aWZpY2F0ZXMucHVzaChmb3JnZS5wa2kuY2VydGlmaWNhdGVGcm9tQXNuMShjZXJ0c1tpXSkpOwogICAgICB9CgogICAgICAvLyBUT0RPOiBwYXJzZSBjcmxzCiAgICB9LAoKICAgIHRvQXNuMTogZnVuY3Rpb24oKSB7CiAgICAgIC8vIGRlZ2VuZXJhdGUgY2FzZSB3aXRoIG5vIGNvbnRlbnQKICAgICAgaWYoIW1zZy5jb250ZW50SW5mbykgewogICAgICAgIG1zZy5zaWduKCk7CiAgICAgIH0KCiAgICAgIHZhciBjZXJ0cyA9IFtdOwogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgbXNnLmNlcnRpZmljYXRlcy5sZW5ndGg7ICsraSkgewogICAgICAgIGNlcnRzLnB1c2goZm9yZ2UucGtpLmNlcnRpZmljYXRlVG9Bc24xKG1zZy5jZXJ0aWZpY2F0ZXNbaV0pKTsKICAgICAgfQoKICAgICAgdmFyIGNybHMgPSBbXTsKICAgICAgLy8gVE9ETzogaW1wbGVtZW50IENSTHMKCiAgICAgIC8vIFswXSBTaWduZWREYXRhCiAgICAgIHZhciBzaWduZWREYXRhID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAwLCB0cnVlLCBbCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgICAgLy8gVmVyc2lvbgogICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIobXNnLnZlcnNpb24pLmdldEJ5dGVzKCkpLAogICAgICAgICAgLy8gRGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllcnMKICAgICAgICAgIGFzbjEuY3JlYXRlKAogICAgICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFVCwgdHJ1ZSwKICAgICAgICAgICAgbXNnLmRpZ2VzdEFsZ29yaXRobUlkZW50aWZpZXJzKSwKICAgICAgICAgIC8vIENvbnRlbnRJbmZvCiAgICAgICAgICBtc2cuY29udGVudEluZm8KICAgICAgICBdKQogICAgICBdKTsKICAgICAgaWYoY2VydHMubGVuZ3RoID4gMCkgewogICAgICAgIC8vIFswXSBJTVBMSUNJVCBFeHRlbmRlZENlcnRpZmljYXRlc0FuZENlcnRpZmljYXRlcyBPUFRJT05BTAogICAgICAgIHNpZ25lZERhdGEudmFsdWVbMF0udmFsdWUucHVzaCgKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgY2VydHMpKTsKICAgICAgfQogICAgICBpZihjcmxzLmxlbmd0aCA+IDApIHsKICAgICAgICAvLyBbMV0gSU1QTElDSVQgQ2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdHMgT1BUSU9OQUwKICAgICAgICBzaWduZWREYXRhLnZhbHVlWzBdLnZhbHVlLnB1c2goCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDEsIHRydWUsIGNybHMpKTsKICAgICAgfQogICAgICAvLyBTaWduZXJJbmZvcwogICAgICBzaWduZWREYXRhLnZhbHVlWzBdLnZhbHVlLnB1c2goCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVQsIHRydWUsCiAgICAgICAgICBtc2cuc2lnbmVySW5mb3MpKTsKCiAgICAgIC8vIENvbnRlbnRJbmZvCiAgICAgIHJldHVybiBhc24xLmNyZWF0ZSgKICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgICAgICAvLyBDb250ZW50VHlwZQogICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgICBhc24xLm9pZFRvRGVyKG1zZy50eXBlKS5nZXRCeXRlcygpKSwKICAgICAgICAgIC8vIFswXSBTaWduZWREYXRhCiAgICAgICAgICBzaWduZWREYXRhCiAgICAgICAgXSk7CiAgICB9LAoKICAgIC8qKgogICAgICogQWRkIChhbm90aGVyKSBlbnRpdHkgdG8gbGlzdCBvZiBzaWduZXJzLgogICAgICoKICAgICAqIE5vdGU6IElmIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIGFyZSBwcm92aWRlZCwgdGhlbiwgcGVyIFJGQyAyMzE1LAogICAgICogdGhleSBtdXN0IGluY2x1ZGUgYXQgbGVhc3QgdHdvIGF0dHJpYnV0ZXM6IGNvbnRlbnQgdHlwZSBhbmQKICAgICAqIG1lc3NhZ2UgZGlnZXN0LiBUaGUgbWVzc2FnZSBkaWdlc3QgYXR0cmlidXRlIHZhbHVlIHdpbGwgYmUKICAgICAqIGF1dG8tY2FsY3VsYXRlZCBkdXJpbmcgc2lnbmluZyBhbmQgd2lsbCBiZSBpZ25vcmVkIGlmIHByb3ZpZGVkLgogICAgICoKICAgICAqIEhlcmUncyBhbiBleGFtcGxlIG9mIHByb3ZpZGluZyB0aGVzZSB0d28gYXR0cmlidXRlczoKICAgICAqCiAgICAgKiBmb3JnZS5wa2NzNy5jcmVhdGVTaWduZWREYXRhKCk7CiAgICAgKiBwNy5hZGRTaWduZXIoewogICAgICogICBpc3N1ZXI6IGNlcnQuaXNzdWVyLmF0dHJpYnV0ZXMsCiAgICAgKiAgIHNlcmlhbE51bWJlcjogY2VydC5zZXJpYWxOdW1iZXIsCiAgICAgKiAgIGtleTogcHJpdmF0ZUtleSwKICAgICAqICAgZGlnZXN0QWxnb3JpdGhtOiBmb3JnZS5wa2kub2lkcy5zaGExLAogICAgICogICBhdXRoZW50aWNhdGVkQXR0cmlidXRlczogW3sKICAgICAqICAgICB0eXBlOiBmb3JnZS5wa2kub2lkcy5jb250ZW50VHlwZSwKICAgICAqICAgICB2YWx1ZTogZm9yZ2UucGtpLm9pZHMuZGF0YQogICAgICogICB9LCB7CiAgICAgKiAgICAgdHlwZTogZm9yZ2UucGtpLm9pZHMubWVzc2FnZURpZ2VzdAogICAgICogICB9XQogICAgICogfSk7CiAgICAgKgogICAgICogVE9ETzogU3VwcG9ydCBbc3ViamVjdEtleUlkZW50aWZpZXJdIGFzIHNpZ25lcidzIElELgogICAgICoKICAgICAqIEBwYXJhbSBzaWduZXIgdGhlIHNpZ25lciBpbmZvcm1hdGlvbjoKICAgICAqICAgICAgICAgIGtleSB0aGUgc2lnbmVyJ3MgcHJpdmF0ZSBrZXkuCiAgICAgKiAgICAgICAgICBbY2VydGlmaWNhdGVdIGEgY2VydGlmaWNhdGUgY29udGFpbmluZyB0aGUgcHVibGljIGtleQogICAgICogICAgICAgICAgICBhc3NvY2lhdGVkIHdpdGggdGhlIHNpZ25lcidzIHByaXZhdGUga2V5OyB1c2UgdGhpcyBvcHRpb24gYXMKICAgICAqICAgICAgICAgICAgYW4gYWx0ZXJuYXRpdmUgdG8gc3BlY2lmeWluZyBzaWduZXIuaXNzdWVyIGFuZAogICAgICogICAgICAgICAgICBzaWduZXIuc2VyaWFsTnVtYmVyLgogICAgICogICAgICAgICAgW2lzc3Vlcl0gdGhlIGlzc3VlciBhdHRyaWJ1dGVzIChlZzogY2VydC5pc3N1ZXIuYXR0cmlidXRlcykuCiAgICAgKiAgICAgICAgICBbc2VyaWFsTnVtYmVyXSB0aGUgc2lnbmVyJ3MgY2VydGlmaWNhdGUncyBzZXJpYWwgbnVtYmVyIGluCiAgICAgKiAgICAgICAgICAgaGV4YWRlY2ltYWwgKGVnOiBjZXJ0LnNlcmlhbE51bWJlcikuCiAgICAgKiAgICAgICAgICBbZGlnZXN0QWxnb3JpdGhtXSB0aGUgbWVzc2FnZSBkaWdlc3QgT0lELCBhcyBhIHN0cmluZywgdG8gdXNlCiAgICAgKiAgICAgICAgICAgIChlZzogZm9yZ2UucGtpLm9pZHMuc2hhMSkuCiAgICAgKiAgICAgICAgICBbYXV0aGVudGljYXRlZEF0dHJpYnV0ZXNdIGFuIG9wdGlvbmFsIGFycmF5IG9mIGF0dHJpYnV0ZXMKICAgICAqICAgICAgICAgICAgdG8gYWxzbyBzaWduIGFsb25nIHdpdGggdGhlIGNvbnRlbnQuCiAgICAgKi8KICAgIGFkZFNpZ25lcjogZnVuY3Rpb24oc2lnbmVyKSB7CiAgICAgIHZhciBpc3N1ZXIgPSBzaWduZXIuaXNzdWVyOwogICAgICB2YXIgc2VyaWFsTnVtYmVyID0gc2lnbmVyLnNlcmlhbE51bWJlcjsKICAgICAgaWYoc2lnbmVyLmNlcnRpZmljYXRlKSB7CiAgICAgICAgdmFyIGNlcnQgPSBzaWduZXIuY2VydGlmaWNhdGU7CiAgICAgICAgaWYodHlwZW9mIGNlcnQgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgICBjZXJ0ID0gZm9yZ2UucGtpLmNlcnRpZmljYXRlRnJvbVBlbShjZXJ0KTsKICAgICAgICB9CiAgICAgICAgaXNzdWVyID0gY2VydC5pc3N1ZXIuYXR0cmlidXRlczsKICAgICAgICBzZXJpYWxOdW1iZXIgPSBjZXJ0LnNlcmlhbE51bWJlcjsKICAgICAgfQogICAgICB2YXIga2V5ID0gc2lnbmVyLmtleTsKICAgICAgaWYoIWtleSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcigKICAgICAgICAgICdDb3VsZCBub3QgYWRkIFBLQ1MjNyBzaWduZXI7IG5vIHByaXZhdGUga2V5IHNwZWNpZmllZC4nKTsKICAgICAgfQogICAgICBpZih0eXBlb2Yga2V5ID09PSAnc3RyaW5nJykgewogICAgICAgIGtleSA9IGZvcmdlLnBraS5wcml2YXRlS2V5RnJvbVBlbShrZXkpOwogICAgICB9CgogICAgICAvLyBlbnN1cmUgT0lEIGtub3duIGZvciBkaWdlc3QgYWxnb3JpdGhtCiAgICAgIHZhciBkaWdlc3RBbGdvcml0aG0gPSBzaWduZXIuZGlnZXN0QWxnb3JpdGhtIHx8IGZvcmdlLnBraS5vaWRzLnNoYTE7CiAgICAgIHN3aXRjaChkaWdlc3RBbGdvcml0aG0pIHsKICAgICAgY2FzZSBmb3JnZS5wa2kub2lkcy5zaGExOgogICAgICBjYXNlIGZvcmdlLnBraS5vaWRzLnNoYTI1NjoKICAgICAgY2FzZSBmb3JnZS5wa2kub2lkcy5zaGEzODQ6CiAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMuc2hhNTEyOgogICAgICBjYXNlIGZvcmdlLnBraS5vaWRzLm1kNToKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICAgICAnQ291bGQgbm90IGFkZCBQS0NTIzcgc2lnbmVyOyB1bmtub3duIG1lc3NhZ2UgZGlnZXN0IGFsZ29yaXRobTogJyArCiAgICAgICAgICBkaWdlc3RBbGdvcml0aG0pOwogICAgICB9CgogICAgICAvLyBpZiBhdXRoZW50aWNhdGVkQXR0cmlidXRlcyBpcyBwcmVzZW50LCB0aGVuIHRoZSBhdHRyaWJ1dGVzCiAgICAgIC8vIG11c3QgY29udGFpbiBhdCBsZWFzdCBQS0NTICM5IGNvbnRlbnQtdHlwZSBhbmQgbWVzc2FnZS1kaWdlc3QKICAgICAgdmFyIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzID0gc2lnbmVyLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIHx8IFtdOwogICAgICBpZihhdXRoZW50aWNhdGVkQXR0cmlidXRlcy5sZW5ndGggPiAwKSB7CiAgICAgICAgdmFyIGNvbnRlbnRUeXBlID0gZmFsc2U7CiAgICAgICAgdmFyIG1lc3NhZ2VEaWdlc3QgPSBmYWxzZTsKICAgICAgICBmb3IodmFyIGkgPSAwOyBpIDwgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMubGVuZ3RoOyArK2kpIHsKICAgICAgICAgIHZhciBhdHRyID0gYXV0aGVudGljYXRlZEF0dHJpYnV0ZXNbaV07CiAgICAgICAgICBpZighY29udGVudFR5cGUgJiYgYXR0ci50eXBlID09PSBmb3JnZS5wa2kub2lkcy5jb250ZW50VHlwZSkgewogICAgICAgICAgICBjb250ZW50VHlwZSA9IHRydWU7CiAgICAgICAgICAgIGlmKG1lc3NhZ2VEaWdlc3QpIHsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmKCFtZXNzYWdlRGlnZXN0ICYmIGF0dHIudHlwZSA9PT0gZm9yZ2UucGtpLm9pZHMubWVzc2FnZURpZ2VzdCkgewogICAgICAgICAgICBtZXNzYWdlRGlnZXN0ID0gdHJ1ZTsKICAgICAgICAgICAgaWYoY29udGVudFR5cGUpIHsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmKCFjb250ZW50VHlwZSB8fCAhbWVzc2FnZURpZ2VzdCkgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNpZ25lci5hdXRoZW50aWNhdGVkQXR0cmlidXRlcy4gSWYgJyArCiAgICAgICAgICAgICdzaWduZXIuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgaXMgc3BlY2lmaWVkLCB0aGVuIGl0IG11c3QgJyArCiAgICAgICAgICAgICdjb250YWluIGF0IGxlYXN0IHR3byBhdHRyaWJ1dGVzLCBQS0NTICM5IGNvbnRlbnQtdHlwZSBhbmQgJyArCiAgICAgICAgICAgICdQS0NTICM5IG1lc3NhZ2UtZGlnZXN0LicpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgbXNnLnNpZ25lcnMucHVzaCh7CiAgICAgICAga2V5OiBrZXksCiAgICAgICAgdmVyc2lvbjogMSwKICAgICAgICBpc3N1ZXI6IGlzc3VlciwKICAgICAgICBzZXJpYWxOdW1iZXI6IHNlcmlhbE51bWJlciwKICAgICAgICBkaWdlc3RBbGdvcml0aG06IGRpZ2VzdEFsZ29yaXRobSwKICAgICAgICBzaWduYXR1cmVBbGdvcml0aG06IGZvcmdlLnBraS5vaWRzLnJzYUVuY3J5cHRpb24sCiAgICAgICAgc2lnbmF0dXJlOiBudWxsLAogICAgICAgIGF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzOiBhdXRoZW50aWNhdGVkQXR0cmlidXRlcywKICAgICAgICB1bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzOiBbXQogICAgICB9KTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBTaWducyB0aGUgY29udGVudC4KICAgICAqLwogICAgc2lnbjogZnVuY3Rpb24oKSB7CiAgICAgIC8vIGF1dG8tZ2VuZXJhdGUgY29udGVudCBpbmZvCiAgICAgIGlmKHR5cGVvZiBtc2cuY29udGVudCAhPT0gJ29iamVjdCcgfHwgbXNnLmNvbnRlbnRJbmZvID09PSBudWxsKSB7CiAgICAgICAgLy8gdXNlIERhdGEgQ29udGVudEluZm8KICAgICAgICBtc2cuY29udGVudEluZm8gPSBhc24xLmNyZWF0ZSgKICAgICAgICAgIGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAgICAgLy8gQ29udGVudFR5cGUKICAgICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgICAgIGFzbjEub2lkVG9EZXIoZm9yZ2UucGtpLm9pZHMuZGF0YSkuZ2V0Qnl0ZXMoKSkKICAgICAgICAgIF0pOwoKICAgICAgICAvLyBhZGQgYWN0dWFsIGNvbnRlbnQsIGlmIHByZXNlbnQKICAgICAgICBpZignY29udGVudCcgaW4gbXNnKSB7CiAgICAgICAgICB2YXIgY29udGVudDsKICAgICAgICAgIGlmKG1zZy5jb250ZW50IGluc3RhbmNlb2YgZm9yZ2UudXRpbC5CeXRlQnVmZmVyKSB7CiAgICAgICAgICAgIGNvbnRlbnQgPSBtc2cuY29udGVudC5ieXRlcygpOwogICAgICAgICAgfSBlbHNlIGlmKHR5cGVvZiBtc2cuY29udGVudCA9PT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgY29udGVudCA9IGZvcmdlLnV0aWwuZW5jb2RlVXRmOChtc2cuY29udGVudCk7CiAgICAgICAgICB9CgogICAgICAgICAgbXNnLmNvbnRlbnRJbmZvLnZhbHVlLnB1c2goCiAgICAgICAgICAgIC8vIFswXSBFWFBMSUNJVCBjb250ZW50CiAgICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgWwogICAgICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLAogICAgICAgICAgICAgICAgY29udGVudCkKICAgICAgICAgICAgXSkpOwogICAgICAgIH0KICAgICAgfQoKICAgICAgLy8gbm8gc2lnbmVycywgcmV0dXJuIGVhcmx5IChkZWdlbmVyYXRlIGNhc2UgZm9yIGNlcnRpZmljYXRlIGNvbnRhaW5lcikKICAgICAgaWYobXNnLnNpZ25lcnMubGVuZ3RoID09PSAwKSB7CiAgICAgICAgcmV0dXJuOwogICAgICB9CgogICAgICAvLyBnZW5lcmF0ZSBkaWdlc3QgYWxnb3JpdGhtIGlkZW50aWZpZXJzCiAgICAgIHZhciBtZHMgPSBhZGREaWdlc3RBbGdvcml0aG1JZHMoKTsKCiAgICAgIC8vIGdlbmVyYXRlIHNpZ25lckluZm9zCiAgICAgIGFkZFNpZ25lckluZm9zKG1kcyk7CiAgICB9LAoKICAgIHZlcmlmeTogZnVuY3Rpb24oKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUyM3IHNpZ25hdHVyZSB2ZXJpZmljYXRpb24gbm90IHlldCBpbXBsZW1lbnRlZC4nKTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBBZGQgYSBjZXJ0aWZpY2F0ZS4KICAgICAqCiAgICAgKiBAcGFyYW0gY2VydCB0aGUgY2VydGlmaWNhdGUgdG8gYWRkLgogICAgICovCiAgICBhZGRDZXJ0aWZpY2F0ZTogZnVuY3Rpb24oY2VydCkgewogICAgICAvLyBjb252ZXJ0IGZyb20gUEVNCiAgICAgIGlmKHR5cGVvZiBjZXJ0ID09PSAnc3RyaW5nJykgewogICAgICAgIGNlcnQgPSBmb3JnZS5wa2kuY2VydGlmaWNhdGVGcm9tUGVtKGNlcnQpOwogICAgICB9CiAgICAgIG1zZy5jZXJ0aWZpY2F0ZXMucHVzaChjZXJ0KTsKICAgIH0sCgogICAgLyoqCiAgICAgKiBBZGQgYSBjZXJ0aWZpY2F0ZSByZXZva2F0aW9uIGxpc3QuCiAgICAgKgogICAgICogQHBhcmFtIGNybCB0aGUgY2VydGlmaWNhdGUgcmV2b2thdGlvbiBsaXN0IHRvIGFkZC4KICAgICAqLwogICAgYWRkQ2VydGlmaWNhdGVSZXZva2F0aW9uTGlzdDogZnVuY3Rpb24oY3JsKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignUEtDUyM3IENSTCBzdXBwb3J0IG5vdCB5ZXQgaW1wbGVtZW50ZWQuJyk7CiAgICB9CiAgfTsKICByZXR1cm4gbXNnOwoKICBmdW5jdGlvbiBhZGREaWdlc3RBbGdvcml0aG1JZHMoKSB7CiAgICB2YXIgbWRzID0ge307CgogICAgZm9yKHZhciBpID0gMDsgaSA8IG1zZy5zaWduZXJzLmxlbmd0aDsgKytpKSB7CiAgICAgIHZhciBzaWduZXIgPSBtc2cuc2lnbmVyc1tpXTsKICAgICAgdmFyIG9pZCA9IHNpZ25lci5kaWdlc3RBbGdvcml0aG07CiAgICAgIGlmKCEob2lkIGluIG1kcykpIHsKICAgICAgICAvLyBjb250ZW50IGRpZ2VzdAogICAgICAgIG1kc1tvaWRdID0gZm9yZ2UubWRbZm9yZ2UucGtpLm9pZHNbb2lkXV0uY3JlYXRlKCk7CiAgICAgIH0KICAgICAgaWYoc2lnbmVyLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzLmxlbmd0aCA9PT0gMCkgewogICAgICAgIC8vIG5vIGN1c3RvbSBhdHRyaWJ1dGVzIHRvIGRpZ2VzdDsgdXNlIGNvbnRlbnQgbWVzc2FnZSBkaWdlc3QKICAgICAgICBzaWduZXIubWQgPSBtZHNbb2lkXTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvLyBjdXN0b20gYXR0cmlidXRlcyB0byBiZSBkaWdlc3RlZDsgdXNlIG93biBtZXNzYWdlIGRpZ2VzdAogICAgICAgIC8vIFRPRE86IG9wdGltaXplIHRvIGp1c3QgY29weSBtZXNzYWdlIGRpZ2VzdCBzdGF0ZSBpZiB0aGF0CiAgICAgICAgLy8gZmVhdHVyZSBpcyBldmVyIHN1cHBvcnRlZCB3aXRoIG1lc3NhZ2UgZGlnZXN0cwogICAgICAgIHNpZ25lci5tZCA9IGZvcmdlLm1kW2ZvcmdlLnBraS5vaWRzW29pZF1dLmNyZWF0ZSgpOwogICAgICB9CiAgICB9CgogICAgLy8gYWRkIHVuaXF1ZSBkaWdlc3QgYWxnb3JpdGhtIGlkZW50aWZpZXJzCiAgICBtc2cuZGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllcnMgPSBbXTsKICAgIGZvcih2YXIgb2lkIGluIG1kcykgewogICAgICBtc2cuZGlnZXN0QWxnb3JpdGhtSWRlbnRpZmllcnMucHVzaCgKICAgICAgICAvLyBBbGdvcml0aG1JZGVudGlmaWVyCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgICAgLy8gYWxnb3JpdGhtCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgICAgIGFzbjEub2lkVG9EZXIob2lkKS5nZXRCeXRlcygpKSwKICAgICAgICAgIC8vIHBhcmFtZXRlcnMgKG51bGwpCiAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgICAgICBdKSk7CiAgICB9CgogICAgcmV0dXJuIG1kczsKICB9CgogIGZ1bmN0aW9uIGFkZFNpZ25lckluZm9zKG1kcykgewogICAgLy8gTm90ZTogQ29udGVudEluZm8gaXMgYSBTRVFVRU5DRSB3aXRoIDIgdmFsdWVzLCBzZWNvbmQgdmFsdWUgaXMKICAgIC8vIHRoZSBjb250ZW50IGZpZWxkIGFuZCBpcyBvcHRpb25hbCBmb3IgYSBDb250ZW50SW5mbyBidXQgcmVxdWlyZWQgaGVyZQogICAgLy8gc2luY2Ugc2lnbmVycyBhcmUgcHJlc2VudAogICAgaWYobXNnLmNvbnRlbnRJbmZvLnZhbHVlLmxlbmd0aCA8IDIpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKAogICAgICAgICdDb3VsZCBub3Qgc2lnbiBQS0NTIzcgbWVzc2FnZTsgdGhlcmUgaXMgbm8gY29udGVudCB0byBzaWduLicpOwogICAgfQoKICAgIC8vIGdldCBDb250ZW50SW5mbyBjb250ZW50IHR5cGUKICAgIHZhciBjb250ZW50VHlwZSA9IGFzbjEuZGVyVG9PaWQobXNnLmNvbnRlbnRJbmZvLnZhbHVlWzBdLnZhbHVlKTsKCiAgICAvLyBnZXQgQ29udGVudEluZm8gY29udGVudAogICAgdmFyIGNvbnRlbnQgPSBtc2cuY29udGVudEluZm8udmFsdWVbMV07CiAgICAvLyBza2lwIFswXSBFWFBMSUNJVCBjb250ZW50IHdyYXBwZXIKICAgIGNvbnRlbnQgPSBjb250ZW50LnZhbHVlWzBdOwoKICAgIC8vIHNlcmlhbGl6ZSBjb250ZW50CiAgICB2YXIgYnl0ZXMgPSBhc24xLnRvRGVyKGNvbnRlbnQpOwoKICAgIC8vIHNraXAgaWRlbnRpZmllciBhbmQgbGVuZ3RoIHBlciBSRkMgMjMxNSA5LjMKICAgIC8vIHNraXAgaWRlbnRpZmllciAoMSBieXRlKQogICAgYnl0ZXMuZ2V0Qnl0ZSgpOwogICAgLy8gcmVhZCBhbmQgZGlzY2FyZCBsZW5ndGggYnl0ZXMKICAgIGFzbjEuZ2V0QmVyVmFsdWVMZW5ndGgoYnl0ZXMpOwogICAgYnl0ZXMgPSBieXRlcy5nZXRCeXRlcygpOwoKICAgIC8vIGRpZ2VzdCBjb250ZW50IERFUiB2YWx1ZSBieXRlcwogICAgZm9yKHZhciBvaWQgaW4gbWRzKSB7CiAgICAgIG1kc1tvaWRdLnN0YXJ0KCkudXBkYXRlKGJ5dGVzKTsKICAgIH0KCiAgICAvLyBzaWduIGNvbnRlbnQKICAgIHZhciBzaWduaW5nVGltZSA9IG5ldyBEYXRlKCk7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbXNnLnNpZ25lcnMubGVuZ3RoOyArK2kpIHsKICAgICAgdmFyIHNpZ25lciA9IG1zZy5zaWduZXJzW2ldOwoKICAgICAgaWYoc2lnbmVyLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzLmxlbmd0aCA9PT0gMCkgewogICAgICAgIC8vIGlmIENvbnRlbnRJbmZvIGNvbnRlbnQgdHlwZSBpcyBub3QgIkRhdGEiLCB0aGVuCiAgICAgICAgLy8gYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgbXVzdCBiZSBwcmVzZW50IHBlciBSRkMgMjMxNQogICAgICAgIGlmKGNvbnRlbnRUeXBlICE9PSBmb3JnZS5wa2kub2lkcy5kYXRhKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoCiAgICAgICAgICAgICdJbnZhbGlkIHNpZ25lcjsgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgbXVzdCBiZSBwcmVzZW50ICcgKwogICAgICAgICAgICAnd2hlbiB0aGUgQ29udGVudEluZm8gY29udGVudCB0eXBlIGlzIG5vdCBQS0NTIzcgRGF0YS4nKTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gcHJvY2VzcyBhdXRoZW50aWNhdGVkIGF0dHJpYnV0ZXMKICAgICAgICAvLyBbMF0gSU1QTElDSVQKICAgICAgICBzaWduZXIuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXNBc24xID0gYXNuMS5jcmVhdGUoCiAgICAgICAgICBhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFtdKTsKCiAgICAgICAgLy8gcGVyIFJGQyAyMzE1LCBhdHRyaWJ1dGVzIGFyZSB0byBiZSBkaWdlc3RlZCB1c2luZyBhIFNFVCBjb250YWluZXIKICAgICAgICAvLyBub3QgdGhlIGFib3ZlIFswXSBJTVBMSUNJVCBjb250YWluZXIKICAgICAgICB2YXIgYXR0cnNBc24xID0gYXNuMS5jcmVhdGUoCiAgICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFVCwgdHJ1ZSwgW10pOwoKICAgICAgICBmb3IodmFyIGFpID0gMDsgYWkgPCBzaWduZXIuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMubGVuZ3RoOyArK2FpKSB7CiAgICAgICAgICB2YXIgYXR0ciA9IHNpZ25lci5hdXRoZW50aWNhdGVkQXR0cmlidXRlc1thaV07CiAgICAgICAgICBpZihhdHRyLnR5cGUgPT09IGZvcmdlLnBraS5vaWRzLm1lc3NhZ2VEaWdlc3QpIHsKICAgICAgICAgICAgLy8gdXNlIGNvbnRlbnQgbWVzc2FnZSBkaWdlc3QgYXMgdmFsdWUKICAgICAgICAgICAgYXR0ci52YWx1ZSA9IG1kc1tzaWduZXIuZGlnZXN0QWxnb3JpdGhtXS5kaWdlc3QoKTsKICAgICAgICAgIH0gZWxzZSBpZihhdHRyLnR5cGUgPT09IGZvcmdlLnBraS5vaWRzLnNpZ25pbmdUaW1lKSB7CiAgICAgICAgICAgIC8vIGF1dG8tcG9wdWxhdGUgc2lnbmluZyB0aW1lIGlmIG5vdCBhbHJlYWR5IHNldAogICAgICAgICAgICBpZighYXR0ci52YWx1ZSkgewogICAgICAgICAgICAgIGF0dHIudmFsdWUgPSBzaWduaW5nVGltZTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIC8vIGNvbnZlcnQgdG8gQVNOLjEgYW5kIHB1c2ggb250byBBdHRyaWJ1dGVzIFNFVCAoZm9yIHNpZ25pbmcpIGFuZAogICAgICAgICAgLy8gb250byBhdXRoZW50aWNhdGVkQXR0cmlidXRlc0FzbjEgdG8gY29tcGxldGUgU2lnbmVkRGF0YSBBU04uMQogICAgICAgICAgLy8gVE9ETzogb3B0aW1pemUgYXdheSBkdXBsaWNhdGlvbgogICAgICAgICAgYXR0cnNBc24xLnZhbHVlLnB1c2goX2F0dHJpYnV0ZVRvQXNuMShhdHRyKSk7CiAgICAgICAgICBzaWduZXIuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXNBc24xLnZhbHVlLnB1c2goX2F0dHJpYnV0ZVRvQXNuMShhdHRyKSk7CiAgICAgICAgfQoKICAgICAgICAvLyBERVItc2VyaWFsaXplIGFuZCBkaWdlc3QgU0VUIE9GIGF0dHJpYnV0ZXMgb25seQogICAgICAgIGJ5dGVzID0gYXNuMS50b0RlcihhdHRyc0FzbjEpLmdldEJ5dGVzKCk7CiAgICAgICAgc2lnbmVyLm1kLnN0YXJ0KCkudXBkYXRlKGJ5dGVzKTsKICAgICAgfQoKICAgICAgLy8gc2lnbiBkaWdlc3QKICAgICAgc2lnbmVyLnNpZ25hdHVyZSA9IHNpZ25lci5rZXkuc2lnbihzaWduZXIubWQsICdSU0FTU0EtUEtDUzEtVjFfNScpOwogICAgfQoKICAgIC8vIGFkZCBzaWduZXIgaW5mbwogICAgbXNnLnNpZ25lckluZm9zID0gX3NpZ25lcnNUb0FzbjEobXNnLnNpZ25lcnMpOwogIH0KfTsKCi8qKgogKiBDcmVhdGVzIGFuIGVtcHR5IFBLQ1MjNyBtZXNzYWdlIG9mIHR5cGUgRW5jcnlwdGVkRGF0YS4KICoKICogQHJldHVybiB0aGUgbWVzc2FnZS4KICovCnA3LmNyZWF0ZUVuY3J5cHRlZERhdGEgPSBmdW5jdGlvbigpIHsKICB2YXIgbXNnID0gbnVsbDsKICBtc2cgPSB7CiAgICB0eXBlOiBmb3JnZS5wa2kub2lkcy5lbmNyeXB0ZWREYXRhLAogICAgdmVyc2lvbjogMCwKICAgIGVuY3J5cHRlZENvbnRlbnQ6IHsKICAgICAgYWxnb3JpdGhtOiBmb3JnZS5wa2kub2lkc1snYWVzMjU2LUNCQyddCiAgICB9LAoKICAgIC8qKgogICAgICogUmVhZHMgYW4gRW5jcnlwdGVkRGF0YSBjb250ZW50IGJsb2NrIChpbiBBU04uMSBmb3JtYXQpCiAgICAgKgogICAgICogQHBhcmFtIG9iaiBUaGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgdGhlIEVuY3J5cHRlZERhdGEgY29udGVudCBibG9jawogICAgICovCiAgICBmcm9tQXNuMTogZnVuY3Rpb24ob2JqKSB7CiAgICAgIC8vIFZhbGlkYXRlIEVuY3J5cHRlZERhdGEgY29udGVudCBibG9jayBhbmQgY2FwdHVyZSBkYXRhLgogICAgICBfZnJvbUFzbjEobXNnLCBvYmosIHA3LmFzbjEuZW5jcnlwdGVkRGF0YVZhbGlkYXRvcik7CiAgICB9LAoKICAgIC8qKgogICAgICogRGVjcnlwdCBlbmNyeXB0ZWQgY29udGVudAogICAgICoKICAgICAqIEBwYXJhbSBrZXkgVGhlIChzeW1tZXRyaWMpIGtleSBhcyBhIGJ5dGUgYnVmZmVyCiAgICAgKi8KICAgIGRlY3J5cHQ6IGZ1bmN0aW9uKGtleSkgewogICAgICBpZihrZXkgIT09IHVuZGVmaW5lZCkgewogICAgICAgIG1zZy5lbmNyeXB0ZWRDb250ZW50LmtleSA9IGtleTsKICAgICAgfQogICAgICBfZGVjcnlwdENvbnRlbnQobXNnKTsKICAgIH0KICB9OwogIHJldHVybiBtc2c7Cn07CgovKioKICogQ3JlYXRlcyBhbiBlbXB0eSBQS0NTIzcgbWVzc2FnZSBvZiB0eXBlIEVudmVsb3BlZERhdGEuCiAqCiAqIEByZXR1cm4gdGhlIG1lc3NhZ2UuCiAqLwpwNy5jcmVhdGVFbnZlbG9wZWREYXRhID0gZnVuY3Rpb24oKSB7CiAgdmFyIG1zZyA9IG51bGw7CiAgbXNnID0gewogICAgdHlwZTogZm9yZ2UucGtpLm9pZHMuZW52ZWxvcGVkRGF0YSwKICAgIHZlcnNpb246IDAsCiAgICByZWNpcGllbnRzOiBbXSwKICAgIGVuY3J5cHRlZENvbnRlbnQ6IHsKICAgICAgYWxnb3JpdGhtOiBmb3JnZS5wa2kub2lkc1snYWVzMjU2LUNCQyddCiAgICB9LAoKICAgIC8qKgogICAgICogUmVhZHMgYW4gRW52ZWxvcGVkRGF0YSBjb250ZW50IGJsb2NrIChpbiBBU04uMSBmb3JtYXQpCiAgICAgKgogICAgICogQHBhcmFtIG9iaiB0aGUgQVNOLjEgcmVwcmVzZW50YXRpb24gb2YgdGhlIEVudmVsb3BlZERhdGEgY29udGVudCBibG9jay4KICAgICAqLwogICAgZnJvbUFzbjE6IGZ1bmN0aW9uKG9iaikgewogICAgICAvLyB2YWxpZGF0ZSBFbnZlbG9wZWREYXRhIGNvbnRlbnQgYmxvY2sgYW5kIGNhcHR1cmUgZGF0YQogICAgICB2YXIgY2FwdHVyZSA9IF9mcm9tQXNuMShtc2csIG9iaiwgcDcuYXNuMS5lbnZlbG9wZWREYXRhVmFsaWRhdG9yKTsKICAgICAgbXNnLnJlY2lwaWVudHMgPSBfcmVjaXBpZW50c0Zyb21Bc24xKGNhcHR1cmUucmVjaXBpZW50SW5mb3MudmFsdWUpOwogICAgfSwKCiAgICB0b0FzbjE6IGZ1bmN0aW9uKCkgewogICAgICAvLyBDb250ZW50SW5mbwogICAgICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAgIC8vIENvbnRlbnRUeXBlCiAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICAgICAgYXNuMS5vaWRUb0Rlcihtc2cudHlwZSkuZ2V0Qnl0ZXMoKSksCiAgICAgICAgLy8gWzBdIEVudmVsb3BlZERhdGEKICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLkNPTlRFWFRfU1BFQ0lGSUMsIDAsIHRydWUsIFsKICAgICAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgICAgICAgLy8gVmVyc2lvbgogICAgICAgICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICAgICAgICAgIGFzbjEuaW50ZWdlclRvRGVyKG1zZy52ZXJzaW9uKS5nZXRCeXRlcygpKSwKICAgICAgICAgICAgLy8gUmVjaXBpZW50SW5mb3MKICAgICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVQsIHRydWUsCiAgICAgICAgICAgICAgX3JlY2lwaWVudHNUb0FzbjEobXNnLnJlY2lwaWVudHMpKSwKICAgICAgICAgICAgLy8gRW5jcnlwdGVkQ29udGVudEluZm8KICAgICAgICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwKICAgICAgICAgICAgICBfZW5jcnlwdGVkQ29udGVudFRvQXNuMShtc2cuZW5jcnlwdGVkQ29udGVudCkpCiAgICAgICAgICBdKQogICAgICAgIF0pCiAgICAgIF0pOwogICAgfSwKCiAgICAvKioKICAgICAqIEZpbmQgcmVjaXBpZW50IGJ5IFguNTA5IGNlcnRpZmljYXRlJ3MgaXNzdWVyLgogICAgICoKICAgICAqIEBwYXJhbSBjZXJ0IHRoZSBjZXJ0aWZpY2F0ZSB3aXRoIHRoZSBpc3N1ZXIgdG8gbG9vayBmb3IuCiAgICAgKgogICAgICogQHJldHVybiB0aGUgcmVjaXBpZW50IG9iamVjdC4KICAgICAqLwogICAgZmluZFJlY2lwaWVudDogZnVuY3Rpb24oY2VydCkgewogICAgICB2YXIgc0F0dHIgPSBjZXJ0Lmlzc3Vlci5hdHRyaWJ1dGVzOwoKICAgICAgZm9yKHZhciBpID0gMDsgaSA8IG1zZy5yZWNpcGllbnRzLmxlbmd0aDsgKytpKSB7CiAgICAgICAgdmFyIHIgPSBtc2cucmVjaXBpZW50c1tpXTsKICAgICAgICB2YXIgckF0dHIgPSByLmlzc3VlcjsKCiAgICAgICAgaWYoci5zZXJpYWxOdW1iZXIgIT09IGNlcnQuc2VyaWFsTnVtYmVyKSB7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGlmKHJBdHRyLmxlbmd0aCAhPT0gc0F0dHIubGVuZ3RoKSB7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIHZhciBtYXRjaCA9IHRydWU7CiAgICAgICAgZm9yKHZhciBqID0gMDsgaiA8IHNBdHRyLmxlbmd0aDsgKytqKSB7CiAgICAgICAgICBpZihyQXR0cltqXS50eXBlICE9PSBzQXR0cltqXS50eXBlIHx8CiAgICAgICAgICAgIHJBdHRyW2pdLnZhbHVlICE9PSBzQXR0cltqXS52YWx1ZSkgewogICAgICAgICAgICBtYXRjaCA9IGZhbHNlOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmKG1hdGNoKSB7CiAgICAgICAgICByZXR1cm4gcjsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIHJldHVybiBudWxsOwogICAgfSwKCiAgICAvKioKICAgICAqIERlY3J5cHQgZW52ZWxvcGVkIGNvbnRlbnQKICAgICAqCiAgICAgKiBAcGFyYW0gcmVjaXBpZW50IFRoZSByZWNpcGllbnQgb2JqZWN0IHJlbGF0ZWQgdG8gdGhlIHByaXZhdGUga2V5CiAgICAgKiBAcGFyYW0gcHJpdktleSBUaGUgKFJTQSkgcHJpdmF0ZSBrZXkgb2JqZWN0CiAgICAgKi8KICAgIGRlY3J5cHQ6IGZ1bmN0aW9uKHJlY2lwaWVudCwgcHJpdktleSkgewogICAgICBpZihtc2cuZW5jcnlwdGVkQ29udGVudC5rZXkgPT09IHVuZGVmaW5lZCAmJiByZWNpcGllbnQgIT09IHVuZGVmaW5lZCAmJgogICAgICAgIHByaXZLZXkgIT09IHVuZGVmaW5lZCkgewogICAgICAgIHN3aXRjaChyZWNpcGllbnQuZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pIHsKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMucnNhRW5jcnlwdGlvbjoKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMuZGVzQ0JDOgogICAgICAgICAgICB2YXIga2V5ID0gcHJpdktleS5kZWNyeXB0KHJlY2lwaWVudC5lbmNyeXB0ZWRDb250ZW50LmNvbnRlbnQpOwogICAgICAgICAgICBtc2cuZW5jcnlwdGVkQ29udGVudC5rZXkgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihrZXkpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3VwcG9ydGVkIGFzeW1tZXRyaWMgY2lwaGVyLCAnICsKICAgICAgICAgICAgICAnT0lEICcgKyByZWNpcGllbnQuZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pOwogICAgICAgIH0KICAgICAgfQoKICAgICAgX2RlY3J5cHRDb250ZW50KG1zZyk7CiAgICB9LAoKICAgIC8qKgogICAgICogQWRkIChhbm90aGVyKSBlbnRpdHkgdG8gbGlzdCBvZiByZWNpcGllbnRzLgogICAgICoKICAgICAqIEBwYXJhbSBjZXJ0IFRoZSBjZXJ0aWZpY2F0ZSBvZiB0aGUgZW50aXR5IHRvIGFkZC4KICAgICAqLwogICAgYWRkUmVjaXBpZW50OiBmdW5jdGlvbihjZXJ0KSB7CiAgICAgIG1zZy5yZWNpcGllbnRzLnB1c2goewogICAgICAgIHZlcnNpb246IDAsCiAgICAgICAgaXNzdWVyOiBjZXJ0Lmlzc3Vlci5hdHRyaWJ1dGVzLAogICAgICAgIHNlcmlhbE51bWJlcjogY2VydC5zZXJpYWxOdW1iZXIsCiAgICAgICAgZW5jcnlwdGVkQ29udGVudDogewogICAgICAgICAgLy8gV2Ugc2ltcGx5IGFzc3VtZSByc2FFbmNyeXB0aW9uIGhlcmUsIHNpbmNlIGZvcmdlLnBraSBvbmx5CiAgICAgICAgICAvLyBzdXBwb3J0cyBSU0Egc28gZmFyLiAgSWYgdGhlIFBLSSBtb2R1bGUgc3VwcG9ydHMgb3RoZXIKICAgICAgICAgIC8vIGNpcGhlcnMgb25lIGRheSwgd2UgbmVlZCB0byBtb2RpZnkgdGhpcyBvbmUgYXMgd2VsbC4KICAgICAgICAgIGFsZ29yaXRobTogZm9yZ2UucGtpLm9pZHMucnNhRW5jcnlwdGlvbiwKICAgICAgICAgIGtleTogY2VydC5wdWJsaWNLZXkKICAgICAgICB9CiAgICAgIH0pOwogICAgfSwKCiAgICAvKioKICAgICAqIEVuY3J5cHQgZW52ZWxvcGVkIGNvbnRlbnQuCiAgICAgKgogICAgICogVGhpcyBmdW5jdGlvbiBzdXBwb3J0cyB0d28gb3B0aW9uYWwgYXJndW1lbnRzLCBjaXBoZXIgYW5kIGtleSwgd2hpY2gKICAgICAqIGNhbiBiZSB1c2VkIHRvIGluZmx1ZW5jZSBzeW1tZXRyaWMgZW5jcnlwdGlvbi4gIFVubGVzcyBjaXBoZXIgaXMKICAgICAqIHByb3ZpZGVkLCB0aGUgY2lwaGVyIHNwZWNpZmllZCBpbiBlbmNyeXB0ZWRDb250ZW50LmFsZ29yaXRobSBpcyB1c2VkCiAgICAgKiAoZGVmYXVsdHMgdG8gQUVTLTI1Ni1DQkMpLiAgSWYgbm8ga2V5IGlzIHByb3ZpZGVkLCBlbmNyeXB0ZWRDb250ZW50LmtleQogICAgICogaXMgKHJlLSl1c2VkLiAgSWYgdGhhdCBvbmUncyBub3Qgc2V0LCBhIHJhbmRvbSBrZXkgd2lsbCBiZSBnZW5lcmF0ZWQKICAgICAqIGF1dG9tYXRpY2FsbHkuCiAgICAgKgogICAgICogQHBhcmFtIFtrZXldIFRoZSBrZXkgdG8gYmUgdXNlZCBmb3Igc3ltbWV0cmljIGVuY3J5cHRpb24uCiAgICAgKiBAcGFyYW0gW2NpcGhlcl0gVGhlIE9JRCBvZiB0aGUgc3ltbWV0cmljIGNpcGhlciB0byB1c2UuCiAgICAgKi8KICAgIGVuY3J5cHQ6IGZ1bmN0aW9uKGtleSwgY2lwaGVyKSB7CiAgICAgIC8vIFBhcnQgMTogU3ltbWV0cmljIGVuY3J5cHRpb24KICAgICAgaWYobXNnLmVuY3J5cHRlZENvbnRlbnQuY29udGVudCA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgY2lwaGVyID0gY2lwaGVyIHx8IG1zZy5lbmNyeXB0ZWRDb250ZW50LmFsZ29yaXRobTsKICAgICAgICBrZXkgPSBrZXkgfHwgbXNnLmVuY3J5cHRlZENvbnRlbnQua2V5OwoKICAgICAgICB2YXIga2V5TGVuLCBpdkxlbiwgY2lwaEZuOwogICAgICAgIHN3aXRjaChjaXBoZXIpIHsKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHNbJ2FlczEyOC1DQkMnXToKICAgICAgICAgICAga2V5TGVuID0gMTY7CiAgICAgICAgICAgIGl2TGVuID0gMTY7CiAgICAgICAgICAgIGNpcGhGbiA9IGZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICBjYXNlIGZvcmdlLnBraS5vaWRzWydhZXMxOTItQ0JDJ106CiAgICAgICAgICAgIGtleUxlbiA9IDI0OwogICAgICAgICAgICBpdkxlbiA9IDE2OwogICAgICAgICAgICBjaXBoRm4gPSBmb3JnZS5hZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgY2FzZSBmb3JnZS5wa2kub2lkc1snYWVzMjU2LUNCQyddOgogICAgICAgICAgICBrZXlMZW4gPSAzMjsKICAgICAgICAgICAgaXZMZW4gPSAxNjsKICAgICAgICAgICAgY2lwaEZuID0gZm9yZ2UuYWVzLmNyZWF0ZUVuY3J5cHRpb25DaXBoZXI7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHNbJ2Rlcy1FREUzLUNCQyddOgogICAgICAgICAgICBrZXlMZW4gPSAyNDsKICAgICAgICAgICAgaXZMZW4gPSA4OwogICAgICAgICAgICBjaXBoRm4gPSBmb3JnZS5kZXMuY3JlYXRlRW5jcnlwdGlvbkNpcGhlcjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBzeW1tZXRyaWMgY2lwaGVyLCBPSUQgJyArIGNpcGhlcik7CiAgICAgICAgfQoKICAgICAgICBpZihrZXkgPT09IHVuZGVmaW5lZCkgewogICAgICAgICAga2V5ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoZm9yZ2UucmFuZG9tLmdldEJ5dGVzKGtleUxlbikpOwogICAgICAgIH0gZWxzZSBpZihrZXkubGVuZ3RoKCkgIT0ga2V5TGVuKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N5bW1ldHJpYyBrZXkgaGFzIHdyb25nIGxlbmd0aDsgJyArCiAgICAgICAgICAgICdnb3QgJyArIGtleS5sZW5ndGgoKSArICcgYnl0ZXMsIGV4cGVjdGVkICcgKyBrZXlMZW4gKyAnLicpOwogICAgICAgIH0KCiAgICAgICAgLy8gS2VlcCBhIGNvcHkgb2YgdGhlIGtleSAmIElWIGluIHRoZSBvYmplY3QsIHNvIHRoZSBjYWxsZXIgY2FuCiAgICAgICAgLy8gdXNlIGl0IGZvciB3aGF0ZXZlciByZWFzb24uCiAgICAgICAgbXNnLmVuY3J5cHRlZENvbnRlbnQuYWxnb3JpdGhtID0gY2lwaGVyOwogICAgICAgIG1zZy5lbmNyeXB0ZWRDb250ZW50LmtleSA9IGtleTsKICAgICAgICBtc2cuZW5jcnlwdGVkQ29udGVudC5wYXJhbWV0ZXIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigKICAgICAgICAgIGZvcmdlLnJhbmRvbS5nZXRCeXRlcyhpdkxlbikpOwoKICAgICAgICB2YXIgY2lwaCA9IGNpcGhGbihrZXkpOwogICAgICAgIGNpcGguc3RhcnQobXNnLmVuY3J5cHRlZENvbnRlbnQucGFyYW1ldGVyLmNvcHkoKSk7CiAgICAgICAgY2lwaC51cGRhdGUobXNnLmNvbnRlbnQpOwoKICAgICAgICAvLyBUaGUgZmluaXNoIGZ1bmN0aW9uIGRvZXMgUEtDUyM3IHBhZGRpbmcgYnkgZGVmYXVsdCwgdGhlcmVmb3JlCiAgICAgICAgLy8gbm8gYWN0aW9uIHJlcXVpcmVkIGJ5IHVzLgogICAgICAgIGlmKCFjaXBoLmZpbmlzaCgpKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N5bW1ldHJpYyBlbmNyeXB0aW9uIGZhaWxlZC4nKTsKICAgICAgICB9CgogICAgICAgIG1zZy5lbmNyeXB0ZWRDb250ZW50LmNvbnRlbnQgPSBjaXBoLm91dHB1dDsKICAgICAgfQoKICAgICAgLy8gUGFydCAyOiBhc3ltbWV0cmljIGVuY3J5cHRpb24gZm9yIGVhY2ggcmVjaXBpZW50CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtc2cucmVjaXBpZW50cy5sZW5ndGg7ICsraSkgewogICAgICAgIHZhciByZWNpcGllbnQgPSBtc2cucmVjaXBpZW50c1tpXTsKCiAgICAgICAgLy8gTm90aGluZyB0byBkbywgZW5jcnlwdGlvbiBhbHJlYWR5IGRvbmUuCiAgICAgICAgaWYocmVjaXBpZW50LmVuY3J5cHRlZENvbnRlbnQuY29udGVudCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIHN3aXRjaChyZWNpcGllbnQuZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pIHsKICAgICAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHMucnNhRW5jcnlwdGlvbjoKICAgICAgICAgICAgcmVjaXBpZW50LmVuY3J5cHRlZENvbnRlbnQuY29udGVudCA9CiAgICAgICAgICAgICAgcmVjaXBpZW50LmVuY3J5cHRlZENvbnRlbnQua2V5LmVuY3J5cHQoCiAgICAgICAgICAgICAgICBtc2cuZW5jcnlwdGVkQ29udGVudC5rZXkuZGF0YSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgYXN5bW1ldHJpYyBjaXBoZXIsIE9JRCAnICsKICAgICAgICAgICAgICByZWNpcGllbnQuZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH07CiAgcmV0dXJuIG1zZzsKfTsKCi8qKgogKiBDb252ZXJ0cyBhIHNpbmdsZSByZWNpcGllbnQgZnJvbSBhbiBBU04uMSBvYmplY3QuCiAqCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIFJlY2lwaWVudEluZm8uCiAqCiAqIEByZXR1cm4gdGhlIHJlY2lwaWVudCBvYmplY3QuCiAqLwpmdW5jdGlvbiBfcmVjaXBpZW50RnJvbUFzbjEob2JqKSB7CiAgLy8gdmFsaWRhdGUgRW52ZWxvcGVkRGF0YSBjb250ZW50IGJsb2NrIGFuZCBjYXB0dXJlIGRhdGEKICB2YXIgY2FwdHVyZSA9IHt9OwogIHZhciBlcnJvcnMgPSBbXTsKICBpZighYXNuMS52YWxpZGF0ZShvYmosIHA3LmFzbjEucmVjaXBpZW50SW5mb1ZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzcgUmVjaXBpZW50SW5mby4gJyArCiAgICAgICdBU04uMSBvYmplY3QgaXMgbm90IGFuIFBLQ1MjNyBSZWNpcGllbnRJbmZvLicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3JzOwogICAgdGhyb3cgZXJyb3I7CiAgfQoKICByZXR1cm4gewogICAgdmVyc2lvbjogY2FwdHVyZS52ZXJzaW9uLmNoYXJDb2RlQXQoMCksCiAgICBpc3N1ZXI6IGZvcmdlLnBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheShjYXB0dXJlLmlzc3VlciksCiAgICBzZXJpYWxOdW1iZXI6IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUuc2VyaWFsKS50b0hleCgpLAogICAgZW5jcnlwdGVkQ29udGVudDogewogICAgICBhbGdvcml0aG06IGFzbjEuZGVyVG9PaWQoY2FwdHVyZS5lbmNBbGdvcml0aG0pLAogICAgICBwYXJhbWV0ZXI6IGNhcHR1cmUuZW5jUGFyYW1ldGVyLnZhbHVlLAogICAgICBjb250ZW50OiBjYXB0dXJlLmVuY0tleQogICAgfQogIH07Cn0KCi8qKgogKiBDb252ZXJ0cyBhIHNpbmdsZSByZWNpcGllbnQgb2JqZWN0IHRvIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiB0aGUgcmVjaXBpZW50IG9iamVjdC4KICoKICogQHJldHVybiB0aGUgQVNOLjEgUmVjaXBpZW50SW5mby4KICovCmZ1bmN0aW9uIF9yZWNpcGllbnRUb0FzbjEob2JqKSB7CiAgcmV0dXJuIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgIC8vIFZlcnNpb24KICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuSU5URUdFUiwgZmFsc2UsCiAgICAgIGFzbjEuaW50ZWdlclRvRGVyKG9iai52ZXJzaW9uKS5nZXRCeXRlcygpKSwKICAgIC8vIElzc3VlckFuZFNlcmlhbE51bWJlcgogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgICAvLyBOYW1lCiAgICAgIGZvcmdlLnBraS5kaXN0aW5ndWlzaGVkTmFtZVRvQXNuMSh7YXR0cmlidXRlczogb2JqLmlzc3Vlcn0pLAogICAgICAvLyBTZXJpYWwKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgICBmb3JnZS51dGlsLmhleFRvQnl0ZXMob2JqLnNlcmlhbE51bWJlcikpCiAgICBdKSwKICAgIC8vIEtleUVuY3J5cHRpb25BbGdvcml0aG1JZGVudGlmaWVyCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIEFsZ29yaXRobQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0RlcihvYmouZW5jcnlwdGVkQ29udGVudC5hbGdvcml0aG0pLmdldEJ5dGVzKCkpLAogICAgICAvLyBQYXJhbWV0ZXIsIGZvcmNlIE5VTEwsIG9ubHkgUlNBIHN1cHBvcnRlZCBmb3Igbm93LgogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk5VTEwsIGZhbHNlLCAnJykKICAgIF0pLAogICAgLy8gRW5jcnlwdGVkS2V5CiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgb2JqLmVuY3J5cHRlZENvbnRlbnQuY29udGVudCkKICBdKTsKfQoKLyoqCiAqIE1hcCBhIHNldCBvZiBSZWNpcGllbnRJbmZvIEFTTi4xIG9iamVjdHMgdG8gcmVjaXBpZW50IG9iamVjdHMuCiAqCiAqIEBwYXJhbSBpbmZvcyBhbiBhcnJheSBvZiBBU04uMSByZXByZXNlbnRhdGlvbnMgUmVjaXBpZW50SW5mbyAoaS5lLiBTRVQgT0YpLgogKgogKiBAcmV0dXJuIGFuIGFycmF5IG9mIHJlY2lwaWVudCBvYmplY3RzLgogKi8KZnVuY3Rpb24gX3JlY2lwaWVudHNGcm9tQXNuMShpbmZvcykgewogIHZhciByZXQgPSBbXTsKICBmb3IodmFyIGkgPSAwOyBpIDwgaW5mb3MubGVuZ3RoOyArK2kpIHsKICAgIHJldC5wdXNoKF9yZWNpcGllbnRGcm9tQXNuMShpbmZvc1tpXSkpOwogIH0KICByZXR1cm4gcmV0Owp9CgovKioKICogTWFwIGFuIGFycmF5IG9mIHJlY2lwaWVudCBvYmplY3RzIHRvIEFTTi4xIFJlY2lwaWVudEluZm8gb2JqZWN0cy4KICoKICogQHBhcmFtIHJlY2lwaWVudHMgYW4gYXJyYXkgb2YgcmVjaXBpZW50SW5mbyBvYmplY3RzLgogKgogKiBAcmV0dXJuIGFuIGFycmF5IG9mIEFTTi4xIFJlY2lwaWVudEluZm9zLgogKi8KZnVuY3Rpb24gX3JlY2lwaWVudHNUb0FzbjEocmVjaXBpZW50cykgewogIHZhciByZXQgPSBbXTsKICBmb3IodmFyIGkgPSAwOyBpIDwgcmVjaXBpZW50cy5sZW5ndGg7ICsraSkgewogICAgcmV0LnB1c2goX3JlY2lwaWVudFRvQXNuMShyZWNpcGllbnRzW2ldKSk7CiAgfQogIHJldHVybiByZXQ7Cn0KCi8qKgogKiBDb252ZXJ0cyBhIHNpbmdsZSBzaWduZXIgZnJvbSBhbiBBU04uMSBvYmplY3QuCiAqCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIGEgU2lnbmVySW5mby4KICoKICogQHJldHVybiB0aGUgc2lnbmVyIG9iamVjdC4KICovCmZ1bmN0aW9uIF9zaWduZXJGcm9tQXNuMShvYmopIHsKICAvLyB2YWxpZGF0ZSBFbnZlbG9wZWREYXRhIGNvbnRlbnQgYmxvY2sgYW5kIGNhcHR1cmUgZGF0YQogIHZhciBjYXB0dXJlID0ge307CiAgdmFyIGVycm9ycyA9IFtdOwogIGlmKCFhc24xLnZhbGlkYXRlKG9iaiwgcDcuYXNuMS5zaWduZXJJbmZvVmFsaWRhdG9yLCBjYXB0dXJlLCBlcnJvcnMpKSB7CiAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ0Nhbm5vdCByZWFkIFBLQ1MjNyBTaWduZXJJbmZvLiAnICsKICAgICAgJ0FTTi4xIG9iamVjdCBpcyBub3QgYW4gUEtDUyM3IFNpZ25lckluZm8uJyk7CiAgICBlcnJvci5lcnJvcnMgPSBlcnJvcnM7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIHZhciBydmFsID0gewogICAgdmVyc2lvbjogY2FwdHVyZS52ZXJzaW9uLmNoYXJDb2RlQXQoMCksCiAgICBpc3N1ZXI6IGZvcmdlLnBraS5SRE5BdHRyaWJ1dGVzQXNBcnJheShjYXB0dXJlLmlzc3VlciksCiAgICBzZXJpYWxOdW1iZXI6IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKGNhcHR1cmUuc2VyaWFsKS50b0hleCgpLAogICAgZGlnZXN0QWxnb3JpdGhtOiBhc24xLmRlclRvT2lkKGNhcHR1cmUuZGlnZXN0QWxnb3JpdGhtKSwKICAgIHNpZ25hdHVyZUFsZ29yaXRobTogYXNuMS5kZXJUb09pZChjYXB0dXJlLnNpZ25hdHVyZUFsZ29yaXRobSksCiAgICBzaWduYXR1cmU6IGNhcHR1cmUuc2lnbmF0dXJlLAogICAgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXM6IFtdLAogICAgdW5hdXRoZW50aWNhdGVkQXR0cmlidXRlczogW10KICB9OwoKICAvLyBUT0RPOiBjb252ZXJ0IGF0dHJpYnV0ZXMKICB2YXIgYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMgPSBjYXB0dXJlLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIHx8IFtdOwogIHZhciB1bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzID0gY2FwdHVyZS51bmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzIHx8IFtdOwoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIENvbnZlcnRzIGEgc2luZ2xlIHNpZ25lckluZm8gb2JqZWN0IHRvIGFuIEFTTi4xIG9iamVjdC4KICoKICogQHBhcmFtIG9iaiB0aGUgc2lnbmVySW5mbyBvYmplY3QuCiAqCiAqIEByZXR1cm4gdGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIGEgU2lnbmVySW5mby4KICovCmZ1bmN0aW9uIF9zaWduZXJUb0FzbjEob2JqKSB7CiAgLy8gU2lnbmVySW5mbwogIHZhciBydmFsID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gdmVyc2lvbgogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5JTlRFR0VSLCBmYWxzZSwKICAgICAgYXNuMS5pbnRlZ2VyVG9EZXIob2JqLnZlcnNpb24pLmdldEJ5dGVzKCkpLAogICAgLy8gaXNzdWVyQW5kU2VyaWFsTnVtYmVyCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIG5hbWUKICAgICAgZm9yZ2UucGtpLmRpc3Rpbmd1aXNoZWROYW1lVG9Bc24xKHthdHRyaWJ1dGVzOiBvYmouaXNzdWVyfSksCiAgICAgIC8vIHNlcmlhbAogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLklOVEVHRVIsIGZhbHNlLAogICAgICAgIGZvcmdlLnV0aWwuaGV4VG9CeXRlcyhvYmouc2VyaWFsTnVtYmVyKSkKICAgIF0pLAogICAgLy8gZGlnZXN0QWxnb3JpdGhtCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFUVVFTkNFLCB0cnVlLCBbCiAgICAgIC8vIGFsZ29yaXRobQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgICAgYXNuMS5vaWRUb0RlcihvYmouZGlnZXN0QWxnb3JpdGhtKS5nZXRCeXRlcygpKSwKICAgICAgLy8gcGFyYW1ldGVycyAobnVsbCkKICAgICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5OVUxMLCBmYWxzZSwgJycpCiAgICBdKQogIF0pOwoKICAvLyBhdXRoZW50aWNhdGVkQXR0cmlidXRlcyAoT1BUSU9OQUwpCiAgaWYob2JqLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzQXNuMSkgewogICAgLy8gYWRkIEFTTi4xIHByZXZpb3VzbHkgZ2VuZXJhdGVkIGR1cmluZyBzaWduaW5nCiAgICBydmFsLnZhbHVlLnB1c2gob2JqLmF1dGhlbnRpY2F0ZWRBdHRyaWJ1dGVzQXNuMSk7CiAgfQoKICAvLyBkaWdlc3RFbmNyeXB0aW9uQWxnb3JpdGhtCiAgcnZhbC52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgIC8vIGFsZ29yaXRobQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICBhc24xLm9pZFRvRGVyKG9iai5zaWduYXR1cmVBbGdvcml0aG0pLmdldEJ5dGVzKCkpLAogICAgLy8gcGFyYW1ldGVycyAobnVsbCkKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuTlVMTCwgZmFsc2UsICcnKQogIF0pKTsKCiAgLy8gZW5jcnlwdGVkRGlnZXN0CiAgcnZhbC52YWx1ZS5wdXNoKGFzbjEuY3JlYXRlKAogICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PQ1RFVFNUUklORywgZmFsc2UsIG9iai5zaWduYXR1cmUpKTsKCiAgLy8gdW5hdXRoZW50aWNhdGVkQXR0cmlidXRlcyAoT1BUSU9OQUwpCiAgaWYob2JqLnVuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMubGVuZ3RoID4gMCkgewogICAgLy8gWzFdIElNUExJQ0lUCiAgICB2YXIgYXR0cnNBc24xID0gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5DT05URVhUX1NQRUNJRklDLCAxLCB0cnVlLCBbXSk7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgb2JqLnVuYXV0aGVudGljYXRlZEF0dHJpYnV0ZXMubGVuZ3RoOyArK2kpIHsKICAgICAgdmFyIGF0dHIgPSBvYmoudW5hdXRoZW50aWNhdGVkQXR0cmlidXRlc1tpXTsKICAgICAgYXR0cnNBc24xLnZhbHVlcy5wdXNoKF9hdHRyaWJ1dGVUb0FzbjEoYXR0cikpOwogICAgfQogICAgcnZhbC52YWx1ZS5wdXNoKGF0dHJzQXNuMSk7CiAgfQoKICByZXR1cm4gcnZhbDsKfQoKLyoqCiAqIE1hcCBhIHNldCBvZiBTaWduZXJJbmZvIEFTTi4xIG9iamVjdHMgdG8gYW4gYXJyYXkgb2Ygc2lnbmVyIG9iamVjdHMuCiAqCiAqIEBwYXJhbSBzaWduZXJJbmZvQXNuMXMgYW4gYXJyYXkgb2YgQVNOLjEgU2lnbmVySW5mb3MgKGkuZS4gU0VUIE9GKS4KICoKICogQHJldHVybiBhbiBhcnJheSBvZiBzaWduZXJzIG9iamVjdHMuCiAqLwpmdW5jdGlvbiBfc2lnbmVyc0Zyb21Bc24xKHNpZ25lckluZm9Bc24xcykgewogIHZhciByZXQgPSBbXTsKICBmb3IodmFyIGkgPSAwOyBpIDwgc2lnbmVySW5mb0FzbjFzLmxlbmd0aDsgKytpKSB7CiAgICByZXQucHVzaChfc2lnbmVyRnJvbUFzbjEoc2lnbmVySW5mb0FzbjFzW2ldKSk7CiAgfQogIHJldHVybiByZXQ7Cn0KCi8qKgogKiBNYXAgYW4gYXJyYXkgb2Ygc2lnbmVyIG9iamVjdHMgdG8gQVNOLjEgb2JqZWN0cy4KICoKICogQHBhcmFtIHNpZ25lcnMgYW4gYXJyYXkgb2Ygc2lnbmVyIG9iamVjdHMuCiAqCiAqIEByZXR1cm4gYW4gYXJyYXkgb2YgQVNOLjEgU2lnbmVySW5mb3MuCiAqLwpmdW5jdGlvbiBfc2lnbmVyc1RvQXNuMShzaWduZXJzKSB7CiAgdmFyIHJldCA9IFtdOwogIGZvcih2YXIgaSA9IDA7IGkgPCBzaWduZXJzLmxlbmd0aDsgKytpKSB7CiAgICByZXQucHVzaChfc2lnbmVyVG9Bc24xKHNpZ25lcnNbaV0pKTsKICB9CiAgcmV0dXJuIHJldDsKfQoKLyoqCiAqIENvbnZlcnQgYW4gYXR0cmlidXRlIG9iamVjdCB0byBhbiBBU04uMSBBdHRyaWJ1dGUuCiAqCiAqIEBwYXJhbSBhdHRyIHRoZSBhdHRyaWJ1dGUgb2JqZWN0LgogKgogKiBAcmV0dXJuIHRoZSBBU04uMSBBdHRyaWJ1dGUuCiAqLwpmdW5jdGlvbiBfYXR0cmlidXRlVG9Bc24xKGF0dHIpIHsKICB2YXIgdmFsdWU7CgogIC8vIFRPRE86IGdlbmVyYWxpemUgdG8gc3VwcG9ydCBtb3JlIGF0dHJpYnV0ZXMKICBpZihhdHRyLnR5cGUgPT09IGZvcmdlLnBraS5vaWRzLmNvbnRlbnRUeXBlKSB7CiAgICB2YWx1ZSA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgYXNuMS5vaWRUb0RlcihhdHRyLnZhbHVlKS5nZXRCeXRlcygpKTsKICB9IGVsc2UgaWYoYXR0ci50eXBlID09PSBmb3JnZS5wa2kub2lkcy5tZXNzYWdlRGlnZXN0KSB7CiAgICB2YWx1ZSA9IGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0NURVRTVFJJTkcsIGZhbHNlLAogICAgICBhdHRyLnZhbHVlLmJ5dGVzKCkpOwogIH0gZWxzZSBpZihhdHRyLnR5cGUgPT09IGZvcmdlLnBraS5vaWRzLnNpZ25pbmdUaW1lKSB7CiAgICAvKiBOb3RlIHBlciBSRkMgMjk4NTogRGF0ZXMgYmV0d2VlbiAxIEphbnVhcnkgMTk1MCBhbmQgMzEgRGVjZW1iZXIgMjA0OQogICAgICAoaW5jbHVzaXZlKSBNVVNUIGJlIGVuY29kZWQgYXMgVVRDVGltZS4gQW55IGRhdGVzIHdpdGggeWVhciB2YWx1ZXMKICAgICAgYmVmb3JlIDE5NTAgb3IgYWZ0ZXIgMjA0OSBNVVNUIGJlIGVuY29kZWQgYXMgR2VuZXJhbGl6ZWRUaW1lLiBbRnVydGhlcixdCiAgICAgIFVUQ1RpbWUgdmFsdWVzIE1VU1QgYmUgZXhwcmVzc2VkIGluIEdyZWVud2ljaCBNZWFuIFRpbWUgKFp1bHUpIGFuZCBNVVNUCiAgICAgIGluY2x1ZGUgc2Vjb25kcyAoaS5lLiwgdGltZXMgYXJlIFlZTU1EREhITU1TU1opLCBldmVuIHdoZXJlIHRoZQogICAgICBudW1iZXIgb2Ygc2Vjb25kcyBpcyB6ZXJvLiAgTWlkbmlnaHQgKEdNVCkgbXVzdCBiZSByZXByZXNlbnRlZCBhcwogICAgICAiWVlNTUREMDAwMDAwWiIuICovCiAgICAvLyBUT0RPOiBtYWtlIHRoZXNlIG1vZHVsZS1sZXZlbCBjb25zdGFudHMKICAgIHZhciBqYW5fMV8xOTUwID0gbmV3IERhdGUoJ0phbiAxLCAxOTUwIDAwOjAwOjAwWicpOwogICAgdmFyIGphbl8xXzIwNTAgPSBuZXcgRGF0ZSgnSmFuIDEsIDIwNTAgMDA6MDA6MDBaJyk7CiAgICB2YXIgZGF0ZSA9IGF0dHIudmFsdWU7CiAgICBpZih0eXBlb2YgZGF0ZSA9PT0gJ3N0cmluZycpIHsKICAgICAgLy8gdHJ5IHRvIHBhcnNlIGRhdGUKICAgICAgdmFyIHRpbWVzdGFtcCA9IERhdGUucGFyc2UoZGF0ZSk7CiAgICAgIGlmKCFpc05hTih0aW1lc3RhbXApKSB7CiAgICAgICAgZGF0ZSA9IG5ldyBEYXRlKHRpbWVzdGFtcCk7CiAgICAgIH0gZWxzZSBpZihkYXRlLmxlbmd0aCA9PT0gMTMpIHsKICAgICAgICAvLyBZWU1NRERISE1NU1NaICgxMyBjaGFycyBmb3IgVVRDVGltZSkKICAgICAgICBkYXRlID0gYXNuMS51dGNUaW1lVG9EYXRlKGRhdGUpOwogICAgICB9IGVsc2UgewogICAgICAgIC8vIGFzc3VtZSBnZW5lcmFsaXplZCB0aW1lCiAgICAgICAgZGF0ZSA9IGFzbjEuZ2VuZXJhbGl6ZWRUaW1lVG9EYXRlKGRhdGUpOwogICAgICB9CiAgICB9CgogICAgaWYoZGF0ZSA+PSBqYW5fMV8xOTUwICYmIGRhdGUgPCBqYW5fMV8yMDUwKSB7CiAgICAgIHZhbHVlID0gYXNuMS5jcmVhdGUoCiAgICAgICAgYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5VVENUSU1FLCBmYWxzZSwKICAgICAgICBhc24xLmRhdGVUb1V0Y1RpbWUoZGF0ZSkpOwogICAgfSBlbHNlIHsKICAgICAgdmFsdWUgPSBhc24xLmNyZWF0ZSgKICAgICAgICBhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLkdFTkVSQUxJWkVEVElNRSwgZmFsc2UsCiAgICAgICAgYXNuMS5kYXRlVG9HZW5lcmFsaXplZFRpbWUoZGF0ZSkpOwogICAgfQogIH0KCiAgLy8gVE9ETzogZXhwb3NlIGFzIGNvbW1vbiBBUEkgY2FsbAogIC8vIGNyZWF0ZSBhIFJlbGF0aXZlRGlzdGluZ3Vpc2hlZE5hbWUgc2V0CiAgLy8gZWFjaCB2YWx1ZSBpbiB0aGUgc2V0IGlzIGFuIEF0dHJpYnV0ZVR5cGVBbmRWYWx1ZSBmaXJzdAogIC8vIGNvbnRhaW5pbmcgdGhlIHR5cGUgKGFuIE9JRCkgYW5kIHNlY29uZCB0aGUgdmFsdWUKICByZXR1cm4gYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5TRVFVRU5DRSwgdHJ1ZSwgWwogICAgLy8gQXR0cmlidXRlVHlwZQogICAgYXNuMS5jcmVhdGUoYXNuMS5DbGFzcy5VTklWRVJTQUwsIGFzbjEuVHlwZS5PSUQsIGZhbHNlLAogICAgICBhc24xLm9pZFRvRGVyKGF0dHIudHlwZSkuZ2V0Qnl0ZXMoKSksCiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLlNFVCwgdHJ1ZSwgWwogICAgICAvLyBBdHRyaWJ1dGVWYWx1ZQogICAgICB2YWx1ZQogICAgXSkKICBdKTsKfQoKLyoqCiAqIE1hcCBtZXNzYWdlcyBlbmNyeXB0ZWQgY29udGVudCB0byBBU04uMSBvYmplY3RzLgogKgogKiBAcGFyYW0gZWMgVGhlIGVuY3J5cHRlZENvbnRlbnQgb2JqZWN0IG9mIHRoZSBtZXNzYWdlLgogKgogKiBAcmV0dXJuIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbmNyeXB0ZWRDb250ZW50IG9iamVjdCAoU0VRVUVOQ0UpLgogKi8KZnVuY3Rpb24gX2VuY3J5cHRlZENvbnRlbnRUb0FzbjEoZWMpIHsKICByZXR1cm4gWwogICAgLy8gQ29udGVudFR5cGUsIGFsd2F5cyBEYXRhIGZvciB0aGUgbW9tZW50CiAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9JRCwgZmFsc2UsCiAgICAgIGFzbjEub2lkVG9EZXIoZm9yZ2UucGtpLm9pZHMuZGF0YSkuZ2V0Qnl0ZXMoKSksCiAgICAvLyBDb250ZW50RW5jcnlwdGlvbkFsZ29yaXRobUlkZW50aWZpZXIKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuU0VRVUVOQ0UsIHRydWUsIFsKICAgICAgLy8gQWxnb3JpdGhtCiAgICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuVU5JVkVSU0FMLCBhc24xLlR5cGUuT0lELCBmYWxzZSwKICAgICAgICBhc24xLm9pZFRvRGVyKGVjLmFsZ29yaXRobSkuZ2V0Qnl0ZXMoKSksCiAgICAgIC8vIFBhcmFtZXRlcnMgKElWKQogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgICBlYy5wYXJhbWV0ZXIuZ2V0Qnl0ZXMoKSkKICAgIF0pLAogICAgLy8gWzBdIEVuY3J5cHRlZENvbnRlbnQKICAgIGFzbjEuY3JlYXRlKGFzbjEuQ2xhc3MuQ09OVEVYVF9TUEVDSUZJQywgMCwgdHJ1ZSwgWwogICAgICBhc24xLmNyZWF0ZShhc24xLkNsYXNzLlVOSVZFUlNBTCwgYXNuMS5UeXBlLk9DVEVUU1RSSU5HLCBmYWxzZSwKICAgICAgICBlYy5jb250ZW50LmdldEJ5dGVzKCkpCiAgICBdKQogIF07Cn0KCi8qKgogKiBSZWFkcyB0aGUgImNvbW1vbiBwYXJ0IiBvZiBhbiBQS0NTIzcgY29udGVudCBibG9jayAoaW4gQVNOLjEgZm9ybWF0KQogKgogKiBUaGlzIGZ1bmN0aW9uIHJlYWRzIHRoZSAiY29tbW9uIHBhcnQiIG9mIHRoZSBQS0NTIzcgY29udGVudCBibG9ja3MKICogRW5jcnlwdGVkRGF0YSBhbmQgRW52ZWxvcGVkRGF0YSwgaS5lLiB2ZXJzaW9uIG51bWJlciBhbmQgc3ltbWV0cmljYWxseQogKiBlbmNyeXB0ZWQgY29udGVudCBibG9jay4KICoKICogVGhlIHJlc3VsdCBvZiB0aGUgQVNOLjEgdmFsaWRhdGUgYW5kIGNhcHR1cmUgcHJvY2VzcyBpcyByZXR1cm5lZAogKiB0byBhbGxvdyB0aGUgY2FsbGVyIHRvIGV4dHJhY3QgZnVydGhlciBkYXRhLCBlLmcuIHRoZSBsaXN0IG9mIHJlY2lwaWVudHMKICogaW4gY2FzZSBvZiBhIEVudmVsb3BlZERhdGEgb2JqZWN0LgogKgogKiBAcGFyYW0gbXNnIHRoZSBQS0NTIzcgb2JqZWN0IHRvIHJlYWQgdGhlIGRhdGEgdG8uCiAqIEBwYXJhbSBvYmogdGhlIEFTTi4xIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb250ZW50IGJsb2NrLgogKiBAcGFyYW0gdmFsaWRhdG9yIHRoZSBBU04uMSBzdHJ1Y3R1cmUgdmFsaWRhdG9yIG9iamVjdCB0byB1c2UuCiAqCiAqIEByZXR1cm4gdGhlIHZhbHVlIG1hcCBjYXB0dXJlZCBieSB2YWxpZGF0b3Igb2JqZWN0LgogKi8KZnVuY3Rpb24gX2Zyb21Bc24xKG1zZywgb2JqLCB2YWxpZGF0b3IpIHsKICB2YXIgY2FwdHVyZSA9IHt9OwogIHZhciBlcnJvcnMgPSBbXTsKICBpZighYXNuMS52YWxpZGF0ZShvYmosIHZhbGlkYXRvciwgY2FwdHVyZSwgZXJyb3JzKSkgewogICAgdmFyIGVycm9yID0gbmV3IEVycm9yKCdDYW5ub3QgcmVhZCBQS0NTIzcgbWVzc2FnZS4gJyArCiAgICAgICdBU04uMSBvYmplY3QgaXMgbm90IGEgc3VwcG9ydGVkIFBLQ1MjNyBtZXNzYWdlLicpOwogICAgZXJyb3IuZXJyb3JzID0gZXJyb3I7CiAgICB0aHJvdyBlcnJvcjsKICB9CgogIC8vIENoZWNrIGNvbnRlbnRUeXBlLCBzbyBmYXIgd2Ugb25seSBzdXBwb3J0IChyYXcpIERhdGEuCiAgdmFyIGNvbnRlbnRUeXBlID0gYXNuMS5kZXJUb09pZChjYXB0dXJlLmNvbnRlbnRUeXBlKTsKICBpZihjb250ZW50VHlwZSAhPT0gZm9yZ2UucGtpLm9pZHMuZGF0YSkgewogICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCBQS0NTIzcgbWVzc2FnZS4gJyArCiAgICAgICdPbmx5IHdyYXBwZWQgQ29udGVudFR5cGUgRGF0YSBzdXBwb3J0ZWQuJyk7CiAgfQoKICBpZihjYXB0dXJlLmVuY3J5cHRlZENvbnRlbnQpIHsKICAgIHZhciBjb250ZW50ID0gJyc7CiAgICBpZihmb3JnZS51dGlsLmlzQXJyYXkoY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50KSkgewogICAgICBmb3IodmFyIGkgPSAwOyBpIDwgY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50Lmxlbmd0aDsgKytpKSB7CiAgICAgICAgaWYoY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50W2ldLnR5cGUgIT09IGFzbjEuVHlwZS5PQ1RFVFNUUklORykgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdNYWxmb3JtZWQgUEtDUyM3IG1lc3NhZ2UsIGV4cGVjdGluZyBlbmNyeXB0ZWQgJyArCiAgICAgICAgICAgICdjb250ZW50IGNvbnN0cnVjdGVkIG9mIG9ubHkgT0NURVQgU1RSSU5HIG9iamVjdHMuJyk7CiAgICAgICAgfQogICAgICAgIGNvbnRlbnQgKz0gY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50W2ldLnZhbHVlOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBjb250ZW50ID0gY2FwdHVyZS5lbmNyeXB0ZWRDb250ZW50OwogICAgfQogICAgbXNnLmVuY3J5cHRlZENvbnRlbnQgPSB7CiAgICAgIGFsZ29yaXRobTogYXNuMS5kZXJUb09pZChjYXB0dXJlLmVuY0FsZ29yaXRobSksCiAgICAgIHBhcmFtZXRlcjogZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY2FwdHVyZS5lbmNQYXJhbWV0ZXIudmFsdWUpLAogICAgICBjb250ZW50OiBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcihjb250ZW50KQogICAgfTsKICB9CgogIGlmKGNhcHR1cmUuY29udGVudCkgewogICAgdmFyIGNvbnRlbnQgPSAnJzsKICAgIGlmKGZvcmdlLnV0aWwuaXNBcnJheShjYXB0dXJlLmNvbnRlbnQpKSB7CiAgICAgIGZvcih2YXIgaSA9IDA7IGkgPCBjYXB0dXJlLmNvbnRlbnQubGVuZ3RoOyArK2kpIHsKICAgICAgICBpZihjYXB0dXJlLmNvbnRlbnRbaV0udHlwZSAhPT0gYXNuMS5UeXBlLk9DVEVUU1RSSU5HKSB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ01hbGZvcm1lZCBQS0NTIzcgbWVzc2FnZSwgZXhwZWN0aW5nICcgKwogICAgICAgICAgICAnY29udGVudCBjb25zdHJ1Y3RlZCBvZiBvbmx5IE9DVEVUIFNUUklORyBvYmplY3RzLicpOwogICAgICAgIH0KICAgICAgICBjb250ZW50ICs9IGNhcHR1cmUuY29udGVudFtpXS52YWx1ZTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgY29udGVudCA9IGNhcHR1cmUuY29udGVudDsKICAgIH0KICAgIG1zZy5jb250ZW50ID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoY29udGVudCk7CiAgfQoKICBtc2cudmVyc2lvbiA9IGNhcHR1cmUudmVyc2lvbi5jaGFyQ29kZUF0KDApOwogIG1zZy5yYXdDYXB0dXJlID0gY2FwdHVyZTsKCiAgcmV0dXJuIGNhcHR1cmU7Cn0KCi8qKgogKiBEZWNyeXB0IHRoZSBzeW1tZXRyaWNhbGx5IGVuY3J5cHRlZCBjb250ZW50IGJsb2NrIG9mIHRoZSBQS0NTIzcgbWVzc2FnZS4KICoKICogRGVjcnlwdGlvbiBpcyBza2lwcGVkIGluIGNhc2UgdGhlIFBLQ1MjNyBtZXNzYWdlIG9iamVjdCBhbHJlYWR5IGhhcyBhCiAqIChkZWNyeXB0ZWQpIGNvbnRlbnQgYXR0cmlidXRlLiAgVGhlIGFsZ29yaXRobSwga2V5IGFuZCBjaXBoZXIgcGFyYW1ldGVycwogKiAocHJvYmFibHkgdGhlIGl2KSBhcmUgdGFrZW4gZnJvbSB0aGUgZW5jcnlwdGVkQ29udGVudCBhdHRyaWJ1dGUgb2YgdGhlCiAqIG1lc3NhZ2Ugb2JqZWN0LgogKgogKiBAcGFyYW0gVGhlIFBLQ1MjNyBtZXNzYWdlIG9iamVjdC4KICovCmZ1bmN0aW9uIF9kZWNyeXB0Q29udGVudChtc2cpIHsKICBpZihtc2cuZW5jcnlwdGVkQ29udGVudC5rZXkgPT09IHVuZGVmaW5lZCkgewogICAgdGhyb3cgbmV3IEVycm9yKCdTeW1tZXRyaWMga2V5IG5vdCBhdmFpbGFibGUuJyk7CiAgfQoKICBpZihtc2cuY29udGVudCA9PT0gdW5kZWZpbmVkKSB7CiAgICB2YXIgY2lwaDsKCiAgICBzd2l0Y2gobXNnLmVuY3J5cHRlZENvbnRlbnQuYWxnb3JpdGhtKSB7CiAgICAgIGNhc2UgZm9yZ2UucGtpLm9pZHNbJ2FlczEyOC1DQkMnXToKICAgICAgY2FzZSBmb3JnZS5wa2kub2lkc1snYWVzMTkyLUNCQyddOgogICAgICBjYXNlIGZvcmdlLnBraS5vaWRzWydhZXMyNTYtQ0JDJ106CiAgICAgICAgY2lwaCA9IGZvcmdlLmFlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyKG1zZy5lbmNyeXB0ZWRDb250ZW50LmtleSk7CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIGZvcmdlLnBraS5vaWRzWydkZXNDQkMnXToKICAgICAgY2FzZSBmb3JnZS5wa2kub2lkc1snZGVzLUVERTMtQ0JDJ106CiAgICAgICAgY2lwaCA9IGZvcmdlLmRlcy5jcmVhdGVEZWNyeXB0aW9uQ2lwaGVyKG1zZy5lbmNyeXB0ZWRDb250ZW50LmtleSk7CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgc3ltbWV0cmljIGNpcGhlciwgT0lEICcgKwogICAgICAgICAgbXNnLmVuY3J5cHRlZENvbnRlbnQuYWxnb3JpdGhtKTsKICAgIH0KICAgIGNpcGguc3RhcnQobXNnLmVuY3J5cHRlZENvbnRlbnQucGFyYW1ldGVyKTsKICAgIGNpcGgudXBkYXRlKG1zZy5lbmNyeXB0ZWRDb250ZW50LmNvbnRlbnQpOwoKICAgIGlmKCFjaXBoLmZpbmlzaCgpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcignU3ltbWV0cmljIGRlY3J5cHRpb24gZmFpbGVkLicpOwogICAgfQoKICAgIG1zZy5jb250ZW50ID0gY2lwaC5vdXRwdXQ7CiAgfQp9Cgp9IC8vIGVuZCBtb2R1bGUgaW1wbGVtZW50YXRpb24KCi8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIHdyYXBwZXIgIyMjIyMjIyMjIyAqLwp2YXIgbmFtZSA9ICdwa2NzNyc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9wa2NzNycsWwogICdyZXF1aXJlJywKICAnbW9kdWxlJywKICAnLi9hZXMnLAogICcuL2FzbjEnLAogICcuL2RlcycsCiAgJy4vb2lkcycsCiAgJy4vcGVtJywKICAnLi9wa2NzN2FzbjEnLAogICcuL3JhbmRvbScsCiAgJy4vdXRpbCcsCiAgJy4veDUwOScKXSwgZnVuY3Rpb24oKSB7CiAgZGVmaW5lRnVuYy5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfSk7Cn0pKCk7CgovKioKICogRnVuY3Rpb25zIHRvIG91dHB1dCBrZXlzIGluIFNTSC1mcmllbmRseSBmb3JtYXRzLgogKgogKiBUaGlzIGlzIHBhcnQgb2YgdGhlIEZvcmdlIHByb2plY3Qgd2hpY2ggbWF5IGJlIHVzZWQgdW5kZXIgdGhlIHRlcm1zIG9mCiAqIGVpdGhlciB0aGUgQlNEIExpY2Vuc2Ugb3IgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIChHUEwpIFZlcnNpb24gMi4KICoKICogU2VlOiBodHRwczovL2dpdGh1Yi5jb20vZGlnaXRhbGJhemFhci9mb3JnZS9ibG9iL2NiZWJjYTM3ODA2NTg3MDNkOTI1YjYxYjJjYWZmYjFkMjYzYTZjMWQvTElDRU5TRQogKgogKiBAYXV0aG9yIGh0dHBzOi8vZ2l0aHViLmNvbS9zaGVsbGFjCiAqLwooZnVuY3Rpb24oKSB7Ci8qICMjIyMjIyMjIyMgQmVnaW4gbW9kdWxlIGltcGxlbWVudGF0aW9uICMjIyMjIyMjIyMgKi8KZnVuY3Rpb24gaW5pdE1vZHVsZShmb3JnZSkgewoKdmFyIHNzaCA9IGZvcmdlLnNzaCA9IGZvcmdlLnNzaCB8fCB7fTsKCi8qKgogKiBFbmNvZGVzIChhbmQgb3B0aW9uYWxseSBlbmNyeXB0cykgYSBwcml2YXRlIFJTQSBrZXkgYXMgYSBQdXR0eSBQUEsgZmlsZS4KICoKICogQHBhcmFtIHByaXZhdGVLZXkgdGhlIGtleS4KICogQHBhcmFtIHBhc3NwaHJhc2UgYSBwYXNzcGhyYXNlIHRvIHByb3RlY3QgdGhlIGtleSAoZmFsc3kgZm9yIG5vIGVuY3J5cHRpb24pLgogKiBAcGFyYW0gY29tbWVudCBhIGNvbW1lbnQgdG8gaW5jbHVkZSBpbiB0aGUga2V5IGZpbGUuCiAqCiAqIEByZXR1cm4gdGhlIFBQSyBmaWxlIGFzIGEgc3RyaW5nLgogKi8Kc3NoLnByaXZhdGVLZXlUb1B1dHR5ID0gZnVuY3Rpb24ocHJpdmF0ZUtleSwgcGFzc3BocmFzZSwgY29tbWVudCkgewogIGNvbW1lbnQgPSBjb21tZW50IHx8ICcnOwogIHBhc3NwaHJhc2UgPSBwYXNzcGhyYXNlIHx8ICcnOwogIHZhciBhbGdvcml0aG0gPSAnc3NoLXJzYSc7CiAgdmFyIGVuY3J5cHRpb25BbGdvcml0aG0gPSAocGFzc3BocmFzZSA9PT0gJycpID8gJ25vbmUnIDogJ2FlczI1Ni1jYmMnOwoKICB2YXIgcHBrID0gJ1B1VFRZLVVzZXItS2V5LUZpbGUtMjogJyArIGFsZ29yaXRobSArICdcclxuJzsKICBwcGsgKz0gJ0VuY3J5cHRpb246ICcgKyBlbmNyeXB0aW9uQWxnb3JpdGhtICsgJ1xyXG4nOwogIHBwayArPSAnQ29tbWVudDogJyArIGNvbW1lbnQgKyAnXHJcbic7CgogIC8vIHB1YmxpYyBrZXkgaW50byBidWZmZXIgZm9yIHBwawogIHZhciBwdWJidWZmZXIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIF9hZGRTdHJpbmdUb0J1ZmZlcihwdWJidWZmZXIsIGFsZ29yaXRobSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihwdWJidWZmZXIsIHByaXZhdGVLZXkuZSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihwdWJidWZmZXIsIHByaXZhdGVLZXkubik7CgogIC8vIHdyaXRlIHB1YmxpYyBrZXkKICB2YXIgcHViID0gZm9yZ2UudXRpbC5lbmNvZGU2NChwdWJidWZmZXIuYnl0ZXMoKSwgNjQpOwogIHZhciBsZW5ndGggPSBNYXRoLmZsb29yKHB1Yi5sZW5ndGggLyA2NikgKyAxOyAvLyA2NiA9IDY0ICsgXHJcbgogIHBwayArPSAnUHVibGljLUxpbmVzOiAnICsgbGVuZ3RoICsgJ1xyXG4nOwogIHBwayArPSBwdWI7CgogIC8vIHByaXZhdGUga2V5IGludG8gYSBidWZmZXIKICB2YXIgcHJpdmJ1ZmZlciA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihwcml2YnVmZmVyLCBwcml2YXRlS2V5LmQpOwogIF9hZGRCaWdJbnRlZ2VyVG9CdWZmZXIocHJpdmJ1ZmZlciwgcHJpdmF0ZUtleS5wKTsKICBfYWRkQmlnSW50ZWdlclRvQnVmZmVyKHByaXZidWZmZXIsIHByaXZhdGVLZXkucSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihwcml2YnVmZmVyLCBwcml2YXRlS2V5LnFJbnYpOwoKICAvLyBvcHRpb25hbGx5IGVuY3J5cHQgdGhlIHByaXZhdGUga2V5CiAgdmFyIHByaXY7CiAgaWYoIXBhc3NwaHJhc2UpIHsKICAgIC8vIHVzZSB0aGUgdW5lbmNyeXB0ZWQgYnVmZmVyCiAgICBwcml2ID0gZm9yZ2UudXRpbC5lbmNvZGU2NChwcml2YnVmZmVyLmJ5dGVzKCksIDY0KTsKICB9IGVsc2UgewogICAgLy8gZW5jcnlwdCBSU0Ega2V5IHVzaW5nIHBhc3NwaHJhc2UKICAgIHZhciBlbmNMZW4gPSBwcml2YnVmZmVyLmxlbmd0aCgpICsgMTYgLSAxOwogICAgZW5jTGVuIC09IGVuY0xlbiAlIDE2OwoKICAgIC8vIHBhZCBwcml2YXRlIGtleSB3aXRoIHNoYTEtZCBkYXRhIC0tIG5lZWRzIHRvIGJlIGEgbXVsdGlwbGUgb2YgMTYKICAgIHZhciBwYWRkaW5nID0gX3NoYTEocHJpdmJ1ZmZlci5ieXRlcygpKTsKCiAgICBwYWRkaW5nLnRydW5jYXRlKHBhZGRpbmcubGVuZ3RoKCkgLSBlbmNMZW4gKyBwcml2YnVmZmVyLmxlbmd0aCgpKTsKICAgIHByaXZidWZmZXIucHV0QnVmZmVyKHBhZGRpbmcpOwoKICAgIHZhciBhZXNrZXkgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogICAgYWVza2V5LnB1dEJ1ZmZlcihfc2hhMSgnXHgwMFx4MDBceDAwXHgwMCcsIHBhc3NwaHJhc2UpKTsKICAgIGFlc2tleS5wdXRCdWZmZXIoX3NoYTEoJ1x4MDBceDAwXHgwMFx4MDEnLCBwYXNzcGhyYXNlKSk7CgogICAgLy8gZW5jcnlwdCBzb21lIGJ5dGVzIHVzaW5nIENCQyBtb2RlCiAgICAvLyBrZXkgaXMgNDAgYnl0ZXMsIHNvIHRydW5jYXRlICpieSogOCBieXRlcwogICAgdmFyIGNpcGhlciA9IGZvcmdlLmFlcy5jcmVhdGVFbmNyeXB0aW9uQ2lwaGVyKGFlc2tleS50cnVuY2F0ZSg4KSwgJ0NCQycpOwogICAgY2lwaGVyLnN0YXJ0KGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCkuZmlsbFdpdGhCeXRlKDAsIDE2KSk7CiAgICBjaXBoZXIudXBkYXRlKHByaXZidWZmZXIuY29weSgpKTsKICAgIGNpcGhlci5maW5pc2goKTsKICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIub3V0cHV0OwoKICAgIC8vIE5vdGU6IHRoaXMgYXBwZWFycyB0byBkaWZmZXIgZnJvbSBQdXR0eSAtLSBpcyBmb3JnZSB3cm9uZywgb3IgcHV0dHk/CiAgICAvLyBkdWUgdG8gcGFkZGluZyB3ZSBmaW5pc2ggYXMgYW4gZXhhY3QgbXVsdGlwbGUgb2YgMTYKICAgIGVuY3J5cHRlZC50cnVuY2F0ZSgxNik7IC8vIGFsbCBwYWRkaW5nCgogICAgcHJpdiA9IGZvcmdlLnV0aWwuZW5jb2RlNjQoZW5jcnlwdGVkLmJ5dGVzKCksIDY0KTsKICB9CgogIC8vIG91dHB1dCBwcml2YXRlIGtleQogIGxlbmd0aCA9IE1hdGguZmxvb3IocHJpdi5sZW5ndGggLyA2NikgKyAxOyAvLyA2NCArIFxyXG4KICBwcGsgKz0gJ1xyXG5Qcml2YXRlLUxpbmVzOiAnICsgbGVuZ3RoICsgJ1xyXG4nOwogIHBwayArPSBwcml2OwoKICAvLyBNQUMKICB2YXIgbWFja2V5ID0gX3NoYTEoJ3B1dHR5LXByaXZhdGUta2V5LWZpbGUtbWFjLWtleScsIHBhc3NwaHJhc2UpOwoKICB2YXIgbWFjYnVmZmVyID0gZm9yZ2UudXRpbC5jcmVhdGVCdWZmZXIoKTsKICBfYWRkU3RyaW5nVG9CdWZmZXIobWFjYnVmZmVyLCBhbGdvcml0aG0pOwogIF9hZGRTdHJpbmdUb0J1ZmZlcihtYWNidWZmZXIsIGVuY3J5cHRpb25BbGdvcml0aG0pOwogIF9hZGRTdHJpbmdUb0J1ZmZlcihtYWNidWZmZXIsIGNvbW1lbnQpOwogIG1hY2J1ZmZlci5wdXRJbnQzMihwdWJidWZmZXIubGVuZ3RoKCkpOwogIG1hY2J1ZmZlci5wdXRCdWZmZXIocHViYnVmZmVyKTsKICBtYWNidWZmZXIucHV0SW50MzIocHJpdmJ1ZmZlci5sZW5ndGgoKSk7CiAgbWFjYnVmZmVyLnB1dEJ1ZmZlcihwcml2YnVmZmVyKTsKCiAgdmFyIGhtYWMgPSBmb3JnZS5obWFjLmNyZWF0ZSgpOwogIGhtYWMuc3RhcnQoJ3NoYTEnLCBtYWNrZXkpOwogIGhtYWMudXBkYXRlKG1hY2J1ZmZlci5ieXRlcygpKTsKCiAgcHBrICs9ICdcclxuUHJpdmF0ZS1NQUM6ICcgKyBobWFjLmRpZ2VzdCgpLnRvSGV4KCkgKyAnXHJcbic7CgogIHJldHVybiBwcGs7Cn07CgovKioKICogRW5jb2RlcyBhIHB1YmxpYyBSU0Ega2V5IGFzIGFuIE9wZW5TU0ggZmlsZS4KICoKICogQHBhcmFtIGtleSB0aGUga2V5LgogKiBAcGFyYW0gY29tbWVudCBhIGNvbW1lbnQuCiAqCiAqIEByZXR1cm4gdGhlIHB1YmxpYyBrZXkgaW4gT3BlblNTSCBmb3JtYXQuCiAqLwpzc2gucHVibGljS2V5VG9PcGVuU1NIID0gZnVuY3Rpb24oa2V5LCBjb21tZW50KSB7CiAgdmFyIHR5cGUgPSAnc3NoLXJzYSc7CiAgY29tbWVudCA9IGNvbW1lbnQgfHwgJyc7CgogIHZhciBidWZmZXIgPSBmb3JnZS51dGlsLmNyZWF0ZUJ1ZmZlcigpOwogIF9hZGRTdHJpbmdUb0J1ZmZlcihidWZmZXIsIHR5cGUpOwogIF9hZGRCaWdJbnRlZ2VyVG9CdWZmZXIoYnVmZmVyLCBrZXkuZSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihidWZmZXIsIGtleS5uKTsKCiAgcmV0dXJuIHR5cGUgKyAnICcgKyBmb3JnZS51dGlsLmVuY29kZTY0KGJ1ZmZlci5ieXRlcygpKSArICcgJyArIGNvbW1lbnQ7Cn07CgovKioKICogRW5jb2RlcyBhIHByaXZhdGUgUlNBIGtleSBhcyBhbiBPcGVuU1NIIGZpbGUuCiAqCiAqIEBwYXJhbSBrZXkgdGhlIGtleS4KICogQHBhcmFtIHBhc3NwaHJhc2UgYSBwYXNzcGhyYXNlIHRvIHByb3RlY3QgdGhlIGtleSAoZmFsc3kgZm9yIG5vIGVuY3J5cHRpb24pLgogKgogKiBAcmV0dXJuIHRoZSBwdWJsaWMga2V5IGluIE9wZW5TU0ggZm9ybWF0LgogKi8Kc3NoLnByaXZhdGVLZXlUb09wZW5TU0ggPSBmdW5jdGlvbihwcml2YXRlS2V5LCBwYXNzcGhyYXNlKSB7CiAgaWYoIXBhc3NwaHJhc2UpIHsKICAgIHJldHVybiBmb3JnZS5wa2kucHJpdmF0ZUtleVRvUGVtKHByaXZhdGVLZXkpOwogIH0KICAvLyBPcGVuU1NIIHByaXZhdGUga2V5IGlzIGp1c3QgYSBsZWdhY3kgZm9ybWF0LCBpdCBzZWVtcwogIHJldHVybiBmb3JnZS5wa2kuZW5jcnlwdFJzYVByaXZhdGVLZXkocHJpdmF0ZUtleSwgcGFzc3BocmFzZSwKICAgIHtsZWdhY3k6IHRydWUsIGFsZ29yaXRobTogJ2FlczEyOCd9KTsKfTsKCi8qKgogKiBHZXRzIHRoZSBTU0ggZmluZ2VycHJpbnQgZm9yIHRoZSBnaXZlbiBwdWJsaWMga2V5LgogKgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb3B0aW9ucyB0byB1c2UuCiAqICAgICAgICAgIFttZF0gdGhlIG1lc3NhZ2UgZGlnZXN0IG9iamVjdCB0byB1c2UgKGRlZmF1bHRzIHRvIGZvcmdlLm1kLm1kNSkuCiAqICAgICAgICAgIFtlbmNvZGluZ10gYW4gYWx0ZXJuYXRpdmUgb3V0cHV0IGVuY29kaW5nLCBzdWNoIGFzICdoZXgnCiAqICAgICAgICAgICAgKGRlZmF1bHRzIHRvIG5vbmUsIG91dHB1dHMgYSBieXRlIGJ1ZmZlcikuCiAqICAgICAgICAgIFtkZWxpbWl0ZXJdIHRoZSBkZWxpbWl0ZXIgdG8gdXNlIGJldHdlZW4gYnl0ZXMgZm9yICdoZXgnIGVuY29kZWQKICogICAgICAgICAgICBvdXRwdXQsIGVnOiAnOicgKGRlZmF1bHRzIHRvIG5vbmUpLgogKgogKiBAcmV0dXJuIHRoZSBmaW5nZXJwcmludCBhcyBhIGJ5dGUgYnVmZmVyIG9yIG90aGVyIGVuY29kaW5nIGJhc2VkIG9uIG9wdGlvbnMuCiAqLwpzc2guZ2V0UHVibGljS2V5RmluZ2VycHJpbnQgPSBmdW5jdGlvbihrZXksIG9wdGlvbnMpIHsKICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTsKICB2YXIgbWQgPSBvcHRpb25zLm1kIHx8IGZvcmdlLm1kLm1kNS5jcmVhdGUoKTsKCiAgdmFyIHR5cGUgPSAnc3NoLXJzYSc7CiAgdmFyIGJ1ZmZlciA9IGZvcmdlLnV0aWwuY3JlYXRlQnVmZmVyKCk7CiAgX2FkZFN0cmluZ1RvQnVmZmVyKGJ1ZmZlciwgdHlwZSk7CiAgX2FkZEJpZ0ludGVnZXJUb0J1ZmZlcihidWZmZXIsIGtleS5lKTsKICBfYWRkQmlnSW50ZWdlclRvQnVmZmVyKGJ1ZmZlciwga2V5Lm4pOwoKICAvLyBoYXNoIHB1YmxpYyBrZXkgYnl0ZXMKICBtZC5zdGFydCgpOwogIG1kLnVwZGF0ZShidWZmZXIuZ2V0Qnl0ZXMoKSk7CiAgdmFyIGRpZ2VzdCA9IG1kLmRpZ2VzdCgpOwogIGlmKG9wdGlvbnMuZW5jb2RpbmcgPT09ICdoZXgnKSB7CiAgICB2YXIgaGV4ID0gZGlnZXN0LnRvSGV4KCk7CiAgICBpZihvcHRpb25zLmRlbGltaXRlcikgewogICAgICByZXR1cm4gaGV4Lm1hdGNoKC8uezJ9L2cpLmpvaW4ob3B0aW9ucy5kZWxpbWl0ZXIpOwogICAgfQogICAgcmV0dXJuIGhleDsKICB9IGVsc2UgaWYob3B0aW9ucy5lbmNvZGluZyA9PT0gJ2JpbmFyeScpIHsKICAgIHJldHVybiBkaWdlc3QuZ2V0Qnl0ZXMoKTsKICB9IGVsc2UgaWYob3B0aW9ucy5lbmNvZGluZykgewogICAgdGhyb3cgbmV3IEVycm9yKCdVbmtub3duIGVuY29kaW5nICInICsgb3B0aW9ucy5lbmNvZGluZyArICciLicpOwogIH0KICByZXR1cm4gZGlnZXN0Owp9OwoKLyoqCiAqIEFkZHMgbGVuKHZhbCkgdGhlbiB2YWwgdG8gYSBidWZmZXIuCiAqCiAqIEBwYXJhbSBidWZmZXIgdGhlIGJ1ZmZlciB0byBhZGQgdG8uCiAqIEBwYXJhbSB2YWwgYSBiaWcgaW50ZWdlci4KICovCmZ1bmN0aW9uIF9hZGRCaWdJbnRlZ2VyVG9CdWZmZXIoYnVmZmVyLCB2YWwpIHsKICB2YXIgaGV4VmFsID0gdmFsLnRvU3RyaW5nKDE2KTsKICAvLyBlbnN1cmUgMnMgY29tcGxlbWVudCArdmUKICBpZihoZXhWYWxbMF0gPj0gJzgnKSB7CiAgICBoZXhWYWwgPSAnMDAnICsgaGV4VmFsOwogIH0KICB2YXIgYnl0ZXMgPSBmb3JnZS51dGlsLmhleFRvQnl0ZXMoaGV4VmFsKTsKICBidWZmZXIucHV0SW50MzIoYnl0ZXMubGVuZ3RoKTsKICBidWZmZXIucHV0Qnl0ZXMoYnl0ZXMpOwp9CgovKioKICogQWRkcyBsZW4odmFsKSB0aGVuIHZhbCB0byBhIGJ1ZmZlci4KICoKICogQHBhcmFtIGJ1ZmZlciB0aGUgYnVmZmVyIHRvIGFkZCB0by4KICogQHBhcmFtIHZhbCBhIHN0cmluZy4KICovCmZ1bmN0aW9uIF9hZGRTdHJpbmdUb0J1ZmZlcihidWZmZXIsIHZhbCkgewogIGJ1ZmZlci5wdXRJbnQzMih2YWwubGVuZ3RoKTsKICBidWZmZXIucHV0U3RyaW5nKHZhbCk7Cn0KCi8qKgogKiBIYXNoZXMgdGhlIGFyZ3VtZW50cyBpbnRvIG9uZSB2YWx1ZSB1c2luZyBTSEEtMS4KICoKICogQHJldHVybiB0aGUgc2hhMSBoYXNoIG9mIHRoZSBwcm92aWRlZCBhcmd1bWVudHMuCiAqLwpmdW5jdGlvbiBfc2hhMSgpIHsKICB2YXIgc2hhID0gZm9yZ2UubWQuc2hhMS5jcmVhdGUoKTsKICB2YXIgbnVtID0gYXJndW1lbnRzLmxlbmd0aDsKICBmb3IgKHZhciBpID0gMDsgaSA8IG51bTsgKytpKSB7CiAgICBzaGEudXBkYXRlKGFyZ3VtZW50c1tpXSk7CiAgfQogIHJldHVybiBzaGEuZGlnZXN0KCk7Cn0KCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3NzaCc7CmlmKHR5cGVvZiBkZWZpbmUgIT09ICdmdW5jdGlvbicpIHsKICAvLyBOb2RlSlMgLT4gQU1ECiAgaWYodHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcgJiYgbW9kdWxlLmV4cG9ydHMpIHsKICAgIHZhciBub2RlSlMgPSB0cnVlOwogICAgZGVmaW5lID0gZnVuY3Rpb24oaWRzLCBmYWN0b3J5KSB7CiAgICAgIGZhY3RvcnkocmVxdWlyZSwgbW9kdWxlKTsKICAgIH07CiAgfSBlbHNlIHsKICAgIC8vIDxzY3JpcHQ+CiAgICBpZih0eXBlb2YgZm9yZ2UgPT09ICd1bmRlZmluZWQnKSB7CiAgICAgIGZvcmdlID0ge307CiAgICB9CiAgICByZXR1cm4gaW5pdE1vZHVsZShmb3JnZSk7CiAgfQp9Ci8vIEFNRAp2YXIgZGVwczsKdmFyIGRlZmluZUZ1bmMgPSBmdW5jdGlvbihyZXF1aXJlLCBtb2R1bGUpIHsKICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGZvcmdlKSB7CiAgICB2YXIgbW9kcyA9IGRlcHMubWFwKGZ1bmN0aW9uKGRlcCkgewogICAgICByZXR1cm4gcmVxdWlyZShkZXApOwogICAgfSkuY29uY2F0KGluaXRNb2R1bGUpOwogICAgLy8gaGFuZGxlIGNpcmN1bGFyIGRlcGVuZGVuY2llcwogICAgZm9yZ2UgPSBmb3JnZSB8fCB7fTsKICAgIGZvcmdlLmRlZmluZWQgPSBmb3JnZS5kZWZpbmVkIHx8IHt9OwogICAgaWYoZm9yZ2UuZGVmaW5lZFtuYW1lXSkgewogICAgICByZXR1cm4gZm9yZ2VbbmFtZV07CiAgICB9CiAgICBmb3JnZS5kZWZpbmVkW25hbWVdID0gdHJ1ZTsKICAgIGZvcih2YXIgaSA9IDA7IGkgPCBtb2RzLmxlbmd0aDsgKytpKSB7CiAgICAgIG1vZHNbaV0oZm9yZ2UpOwogICAgfQogICAgcmV0dXJuIGZvcmdlW25hbWVdOwogIH07Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9zc2gnLFsKICAncmVxdWlyZScsCiAgJ21vZHVsZScsCiAgJy4vYWVzJywKICAnLi9obWFjJywKICAnLi9tZDUnLAogICcuL3NoYTEnLAogICcuL3V0aWwnCl0sIGZ1bmN0aW9uKCkgewogIGRlZmluZUZ1bmMuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn0pOwp9KSgpOwoKLyoqCiAqIFN1cHBvcnQgZm9yIGNvbmN1cnJlbnQgdGFzayBtYW5hZ2VtZW50IGFuZCBzeW5jaHJvbml6YXRpb24gaW4gd2ViCiAqIGFwcGxpY2F0aW9ucy4KICoKICogQGF1dGhvciBEYXZlIExvbmdsZXkKICogQGF1dGhvciBEYXZpZCBJLiBMZWhuIDxkbGVobkBkaWdpdGFsYmF6YWFyLmNvbT4KICoKICogQ29weXJpZ2h0IChjKSAyMDA5LTIwMTMgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgaW1wbGVtZW50YXRpb24gIyMjIyMjIyMjIyAqLwpmdW5jdGlvbiBpbml0TW9kdWxlKGZvcmdlKSB7CgovLyBsb2dnaW5nIGNhdGVnb3J5CnZhciBjYXQgPSAnZm9yZ2UudGFzayc7CgovLyB2ZXJib3NlIGxldmVsCi8vIDA6IG9mZiwgMTogYSBsaXR0bGUsIDI6IGEgd2hvbGUgbG90Ci8vIFZlcmJvc2UgZGVidWcgbG9nZ2luZyBpcyBzdXJyb3VuZGVkIGJ5IGEgbGV2ZWwgY2hlY2sgdG8gYXZvaWQgdGhlCi8vIHBlcmZvcm1hbmNlIGlzc3VlcyB3aXRoIGV2ZW4gY2FsbGluZyB0aGUgbG9nZ2luZyBjb2RlIHJlZ2FyZGxlc3MgaWYgaXQKLy8gaXMgYWN0dWFsbHkgbG9nZ2VkLiAgRm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMgdGhpcyBzaG91bGQgbm90IGJlIHNldCB0byAyCi8vIGZvciBwcm9kdWN0aW9uIHVzZS4KLy8gZXg6IGlmKHNWTCA+PSAyKSBmb3JnZS5sb2cudmVyYm9zZSguLi4uKQp2YXIgc1ZMID0gMDsKCi8vIHRyYWNrIHRhc2tzIGZvciBkZWJ1Z2dpbmcKdmFyIHNUYXNrcyA9IHt9Owp2YXIgc05leHRUYXNrSWQgPSAwOwovLyBkZWJ1ZyBhY2Nlc3MKZm9yZ2UuZGVidWcuc2V0KGNhdCwgJ3Rhc2tzJywgc1Rhc2tzKTsKCi8vIGEgbWFwIG9mIHRhc2sgdHlwZSB0byB0YXNrIHF1ZXVlCnZhciBzVGFza1F1ZXVlcyA9IHt9OwovLyBkZWJ1ZyBhY2Nlc3MKZm9yZ2UuZGVidWcuc2V0KGNhdCwgJ3F1ZXVlcycsIHNUYXNrUXVldWVzKTsKCi8vIG5hbWUgZm9yIHVubmFtZWQgdGFza3MKdmFyIHNOb1Rhc2tOYW1lID0gJz8nOwoKLy8gbWF4aW11bSBudW1iZXIgb2YgZG9OZXh0KCkgcmVjdXJzaW9ucyBiZWZvcmUgYSBjb250ZXh0IHN3YXAgb2NjdXJzCi8vIEZJWE1FOiBtaWdodCBuZWVkIHRvIHR3ZWFrIHRoaXMgYmFzZWQgb24gdGhlIGJyb3dzZXIKdmFyIHNNYXhSZWN1cnNpb25zID0gMzA7CgovLyB0aW1lIHNsaWNlIGZvciBkb2luZyB0YXNrcyBiZWZvcmUgYSBjb250ZXh0IHN3YXAgb2NjdXJzCi8vIEZJWE1FOiBtaWdodCBuZWVkIHRvIHR3ZWFrIHRoaXMgYmFzZWQgb24gdGhlIGJyb3dzZXIKdmFyIHNUaW1lU2xpY2UgPSAyMDsKCi8qKgogKiBUYXNrIHN0YXRlcy4KICoKICogUkVBRFk6IHJlYWR5IHRvIHN0YXJ0IHByb2Nlc3NpbmcKICogUlVOTklORzogdGFzayBvciBhIHN1YnRhc2sgaXMgcnVubmluZwogKiBCTE9DS0VEOiB0YXNrIGlzIHdhaXRpbmcgdG8gYWNxdWlyZSBOIHBlcm1pdHMgdG8gY29udGludWUKICogU0xFRVBJTkc6IHRhc2sgaXMgc2xlZXBpbmcgZm9yIGEgcGVyaW9kIG9mIHRpbWUKICogRE9ORTogdGFzayBpcyBkb25lCiAqIEVSUk9SOiB0YXNrIGhhcyBhbiBlcnJvcgogKi8KdmFyIFJFQURZID0gJ3JlYWR5JzsKdmFyIFJVTk5JTkcgPSAncnVubmluZyc7CnZhciBCTE9DS0VEID0gJ2Jsb2NrZWQnOwp2YXIgU0xFRVBJTkcgPSAnc2xlZXBpbmcnOwp2YXIgRE9ORSA9ICdkb25lJzsKdmFyIEVSUk9SID0gJ2Vycm9yJzsKCi8qKgogKiBUYXNrIGFjdGlvbnMuICBVc2VkIHRvIGNvbnRyb2wgc3RhdGUgdHJhbnNpdGlvbnMuCiAqCiAqIFNUT1A6IHN0b3AgcHJvY2Vzc2luZwogKiBTVEFSVDogc3RhcnQgcHJvY2Vzc2luZyB0YXNrcwogKiBCTE9DSzogYmxvY2sgdGFzayBmcm9tIGNvbnRpbnVpbmcgdW50aWwgMSBvciBtb3JlIHBlcm1pdHMgYXJlIHJlbGVhc2VkCiAqIFVOQkxPQ0s6IHJlbGVhc2Ugb25lIG9yIG1vcmUgcGVybWl0cwogKiBTTEVFUDogc2xlZXAgZm9yIGEgcGVyaW9kIG9mIHRpbWUKICogV0FLRVVQOiB3YWtldXAgZWFybHkgZnJvbSBTTEVFUElORyBzdGF0ZQogKiBDQU5DRUw6IGNhbmNlbCBmdXJ0aGVyIHRhc2tzCiAqIEZBSUw6IGEgZmFpbHVyZSBvY2N1cmVkCiAqLwp2YXIgU1RPUCA9ICdzdG9wJzsKdmFyIFNUQVJUID0gJ3N0YXJ0JzsKdmFyIEJMT0NLID0gJ2Jsb2NrJzsKdmFyIFVOQkxPQ0sgPSAndW5ibG9jayc7CnZhciBTTEVFUCA9ICdzbGVlcCc7CnZhciBXQUtFVVAgPSAnd2FrZXVwJzsKdmFyIENBTkNFTCA9ICdjYW5jZWwnOwp2YXIgRkFJTCA9ICdmYWlsJzsKCi8qKgogKiBTdGF0ZSB0cmFuc2l0aW9uIHRhYmxlLgogKgogKiBuZXh0U3RhdGUgPSBzU3RhdGVUYWJsZVtjdXJyZW50U3RhdGVdW2FjdGlvbl0KICovCnZhciBzU3RhdGVUYWJsZSA9IHt9OwoKc1N0YXRlVGFibGVbUkVBRFldID0ge307CnNTdGF0ZVRhYmxlW1JFQURZXVtTVE9QXSA9IFJFQURZOwpzU3RhdGVUYWJsZVtSRUFEWV1bU1RBUlRdID0gUlVOTklORzsKc1N0YXRlVGFibGVbUkVBRFldW0NBTkNFTF0gPSBET05FOwpzU3RhdGVUYWJsZVtSRUFEWV1bRkFJTF0gPSBFUlJPUjsKCnNTdGF0ZVRhYmxlW1JVTk5JTkddID0ge307CnNTdGF0ZVRhYmxlW1JVTk5JTkddW1NUT1BdID0gUkVBRFk7CnNTdGF0ZVRhYmxlW1JVTk5JTkddW1NUQVJUXSA9IFJVTk5JTkc7CnNTdGF0ZVRhYmxlW1JVTk5JTkddW0JMT0NLXSA9IEJMT0NLRUQ7CnNTdGF0ZVRhYmxlW1JVTk5JTkddW1VOQkxPQ0tdID0gUlVOTklORzsKc1N0YXRlVGFibGVbUlVOTklOR11bU0xFRVBdID0gU0xFRVBJTkc7CnNTdGF0ZVRhYmxlW1JVTk5JTkddW1dBS0VVUF0gPSBSVU5OSU5HOwpzU3RhdGVUYWJsZVtSVU5OSU5HXVtDQU5DRUxdID0gRE9ORTsKc1N0YXRlVGFibGVbUlVOTklOR11bRkFJTF0gPSBFUlJPUjsKCnNTdGF0ZVRhYmxlW0JMT0NLRURdID0ge307CnNTdGF0ZVRhYmxlW0JMT0NLRURdW1NUT1BdID0gQkxPQ0tFRDsKc1N0YXRlVGFibGVbQkxPQ0tFRF1bU1RBUlRdID0gQkxPQ0tFRDsKc1N0YXRlVGFibGVbQkxPQ0tFRF1bQkxPQ0tdID0gQkxPQ0tFRDsKc1N0YXRlVGFibGVbQkxPQ0tFRF1bVU5CTE9DS10gPSBCTE9DS0VEOwpzU3RhdGVUYWJsZVtCTE9DS0VEXVtTTEVFUF0gPSBCTE9DS0VEOwpzU3RhdGVUYWJsZVtCTE9DS0VEXVtXQUtFVVBdID0gQkxPQ0tFRDsKc1N0YXRlVGFibGVbQkxPQ0tFRF1bQ0FOQ0VMXSA9IERPTkU7CnNTdGF0ZVRhYmxlW0JMT0NLRURdW0ZBSUxdID0gRVJST1I7CgpzU3RhdGVUYWJsZVtTTEVFUElOR10gPSB7fTsKc1N0YXRlVGFibGVbU0xFRVBJTkddW1NUT1BdID0gU0xFRVBJTkc7CnNTdGF0ZVRhYmxlW1NMRUVQSU5HXVtTVEFSVF0gPSBTTEVFUElORzsKc1N0YXRlVGFibGVbU0xFRVBJTkddW0JMT0NLXSA9IFNMRUVQSU5HOwpzU3RhdGVUYWJsZVtTTEVFUElOR11bVU5CTE9DS10gPSBTTEVFUElORzsKc1N0YXRlVGFibGVbU0xFRVBJTkddW1NMRUVQXSA9IFNMRUVQSU5HOwpzU3RhdGVUYWJsZVtTTEVFUElOR11bV0FLRVVQXSA9IFNMRUVQSU5HOwpzU3RhdGVUYWJsZVtTTEVFUElOR11bQ0FOQ0VMXSA9IERPTkU7CnNTdGF0ZVRhYmxlW1NMRUVQSU5HXVtGQUlMXSA9IEVSUk9SOwoKc1N0YXRlVGFibGVbRE9ORV0gPSB7fTsKc1N0YXRlVGFibGVbRE9ORV1bU1RPUF0gPSBET05FOwpzU3RhdGVUYWJsZVtET05FXVtTVEFSVF0gPSBET05FOwpzU3RhdGVUYWJsZVtET05FXVtCTE9DS10gPSBET05FOwpzU3RhdGVUYWJsZVtET05FXVtVTkJMT0NLXSA9IERPTkU7CnNTdGF0ZVRhYmxlW0RPTkVdW1NMRUVQXSA9IERPTkU7CnNTdGF0ZVRhYmxlW0RPTkVdW1dBS0VVUF0gPSBET05FOwpzU3RhdGVUYWJsZVtET05FXVtDQU5DRUxdID0gRE9ORTsKc1N0YXRlVGFibGVbRE9ORV1bRkFJTF0gPSBFUlJPUjsKCnNTdGF0ZVRhYmxlW0VSUk9SXSA9IHt9OwpzU3RhdGVUYWJsZVtFUlJPUl1bU1RPUF0gPSBFUlJPUjsKc1N0YXRlVGFibGVbRVJST1JdW1NUQVJUXSA9IEVSUk9SOwpzU3RhdGVUYWJsZVtFUlJPUl1bQkxPQ0tdID0gRVJST1I7CnNTdGF0ZVRhYmxlW0VSUk9SXVtVTkJMT0NLXSA9IEVSUk9SOwpzU3RhdGVUYWJsZVtFUlJPUl1bU0xFRVBdID0gRVJST1I7CnNTdGF0ZVRhYmxlW0VSUk9SXVtXQUtFVVBdID0gRVJST1I7CnNTdGF0ZVRhYmxlW0VSUk9SXVtDQU5DRUxdID0gRVJST1I7CnNTdGF0ZVRhYmxlW0VSUk9SXVtGQUlMXSA9IEVSUk9SOwoKLyoqCiAqIENyZWF0ZXMgYSBuZXcgdGFzay4KICoKICogQHBhcmFtIG9wdGlvbnMgb3B0aW9ucyBmb3IgdGhpcyB0YXNrCiAqICAgcnVuOiB0aGUgcnVuIGZ1bmN0aW9uIGZvciB0aGUgdGFzayAocmVxdWlyZWQpCiAqICAgbmFtZTogdGhlIHJ1biBmdW5jdGlvbiBmb3IgdGhlIHRhc2sgKG9wdGlvbmFsKQogKiAgIHBhcmVudDogcGFyZW50IG9mIHRoaXMgdGFzayAob3B0aW9uYWwpCiAqCiAqIEByZXR1cm4gdGhlIGVtcHR5IHRhc2suCiAqLwp2YXIgVGFzayA9IGZ1bmN0aW9uKG9wdGlvbnMpIHsKICAvLyB0YXNrIGlkCiAgdGhpcy5pZCA9IC0xOwoKICAvLyB0YXNrIG5hbWUKICB0aGlzLm5hbWUgPSBvcHRpb25zLm5hbWUgfHwgc05vVGFza05hbWU7CgogIC8vIHRhc2sgaGFzIG5vIHBhcmVudAogIHRoaXMucGFyZW50ID0gb3B0aW9ucy5wYXJlbnQgfHwgbnVsbDsKCiAgLy8gc2F2ZSBydW4gZnVuY3Rpb24KICB0aGlzLnJ1biA9IG9wdGlvbnMucnVuOwoKICAvLyBjcmVhdGUgYSBxdWV1ZSBvZiBzdWJ0YXNrcyB0byBydW4KICB0aGlzLnN1YnRhc2tzID0gW107CgogIC8vIGVycm9yIGZsYWcKICB0aGlzLmVycm9yID0gZmFsc2U7CgogIC8vIHN0YXRlIG9mIHRoZSB0YXNrCiAgdGhpcy5zdGF0ZSA9IFJFQURZOwoKICAvLyBudW1iZXIgb2YgdGltZXMgdGhlIHRhc2sgaGFzIGJlZW4gYmxvY2tlZCAoYWxzbyB0aGUgbnVtYmVyCiAgLy8gb2YgcGVybWl0cyBuZWVkZWQgdG8gYmUgcmVsZWFzZWQgdG8gY29udGludWUgcnVubmluZykKICB0aGlzLmJsb2NrcyA9IDA7CgogIC8vIHRpbWVvdXQgaWQgd2hlbiBzbGVlcGluZwogIHRoaXMudGltZW91dElkID0gbnVsbDsKCiAgLy8gbm8gc3dhcCB0aW1lIHlldAogIHRoaXMuc3dhcFRpbWUgPSBudWxsOwoKICAvLyBubyB1c2VyIGRhdGEKICB0aGlzLnVzZXJEYXRhID0gbnVsbDsKCiAgLy8gaW5pdGlhbGl6ZSB0YXNrCiAgLy8gRklYTUU6IGRlYWwgd2l0aCBvdmVyZmxvdwogIHRoaXMuaWQgPSBzTmV4dFRhc2tJZCsrOwogIHNUYXNrc1t0aGlzLmlkXSA9IHRoaXM7CiAgaWYoc1ZMID49IDEpIHsKICAgIGZvcmdlLmxvZy52ZXJib3NlKGNhdCwgJ1slc11bJXNdIGluaXQnLCB0aGlzLmlkLCB0aGlzLm5hbWUsIHRoaXMpOwogIH0KfTsKCi8qKgogKiBMb2dzIGRlYnVnIGluZm9ybWF0aW9uIG9uIHRoaXMgdGFzayBhbmQgdGhlIHN5c3RlbSBzdGF0ZS4KICovClRhc2sucHJvdG90eXBlLmRlYnVnID0gZnVuY3Rpb24obXNnKSB7CiAgbXNnID0gbXNnIHx8ICcnOwogIGZvcmdlLmxvZy5kZWJ1ZyhjYXQsIG1zZywKICAgICdbJXNdWyVzXSB0YXNrOicsIHRoaXMuaWQsIHRoaXMubmFtZSwgdGhpcywKICAgICdzdWJ0YXNrczonLCB0aGlzLnN1YnRhc2tzLmxlbmd0aCwKICAgICdxdWV1ZTonLCBzVGFza1F1ZXVlcyk7Cn07CgovKioKICogQWRkcyBhIHN1YnRhc2sgdG8gcnVuIGFmdGVyIHRhc2suZG9OZXh0KCkgb3IgdGFzay5mYWlsKCkgaXMgY2FsbGVkLgogKgogKiBAcGFyYW0gbmFtZSBodW1hbiByZWFkYWJsZSBuYW1lIGZvciB0aGlzIHRhc2sgKG9wdGlvbmFsKS4KICogQHBhcmFtIHN1YnJ1biBhIGZ1bmN0aW9uIHRvIHJ1biB0aGF0IHRha2VzIHRoZSBjdXJyZW50IHRhc2sgYXMKICogICAgICAgICAgaXRzIGZpcnN0IHBhcmFtZXRlci4KICoKICogQHJldHVybiB0aGUgY3VycmVudCB0YXNrICh1c2VmdWwgZm9yIGNoYWluaW5nIG5leHQoKSBjYWxscykuCiAqLwpUYXNrLnByb3RvdHlwZS5uZXh0ID0gZnVuY3Rpb24obmFtZSwgc3VicnVuKSB7CiAgLy8ganVnZ2xlIHBhcmFtZXRlcnMgaWYgaXQgbG9va3MgbGlrZSBubyBuYW1lIGlzIGdpdmVuCiAgaWYodHlwZW9mKG5hbWUpID09PSAnZnVuY3Rpb24nKSB7CiAgICBzdWJydW4gPSBuYW1lOwoKICAgIC8vIGluaGVyaXQgcGFyZW50J3MgbmFtZQogICAgbmFtZSA9IHRoaXMubmFtZTsKICB9CiAgLy8gY3JlYXRlIHN1YnRhc2ssIHNldCBwYXJlbnQgdG8gdGhpcyB0YXNrLCBwcm9wYWdhdGUgY2FsbGJhY2tzCiAgdmFyIHN1YnRhc2sgPSBuZXcgVGFzayh7CiAgICBydW46IHN1YnJ1biwKICAgIG5hbWU6IG5hbWUsCiAgICBwYXJlbnQ6IHRoaXMKICB9KTsKICAvLyBzdGFydCBzdWJ0YXNrcyBydW5uaW5nCiAgc3VidGFzay5zdGF0ZSA9IFJVTk5JTkc7CiAgc3VidGFzay50eXBlID0gdGhpcy50eXBlOwogIHN1YnRhc2suc3VjY2Vzc0NhbGxiYWNrID0gdGhpcy5zdWNjZXNzQ2FsbGJhY2sgfHwgbnVsbDsKICBzdWJ0YXNrLmZhaWx1cmVDYWxsYmFjayA9IHRoaXMuZmFpbHVyZUNhbGxiYWNrIHx8IG51bGw7CgogIC8vIHF1ZXVlIGEgbmV3IHN1YnRhc2sKICB0aGlzLnN1YnRhc2tzLnB1c2goc3VidGFzayk7CgogIHJldHVybiB0aGlzOwp9OwoKLyoqCiAqIEFkZHMgc3VidGFza3MgdG8gcnVuIGluIHBhcmFsbGVsIGFmdGVyIHRhc2suZG9OZXh0KCkgb3IgdGFzay5mYWlsKCkKICogaXMgY2FsbGVkLgogKgogKiBAcGFyYW0gbmFtZSBodW1hbiByZWFkYWJsZSBuYW1lIGZvciB0aGlzIHRhc2sgKG9wdGlvbmFsKS4KICogQHBhcmFtIHN1YnJ1biBmdW5jdGlvbnMgdG8gcnVuIHRoYXQgdGFrZSB0aGUgY3VycmVudCB0YXNrIGFzCiAqICAgICAgICAgIHRoZWlyIGZpcnN0IHBhcmFtZXRlci4KICoKICogQHJldHVybiB0aGUgY3VycmVudCB0YXNrICh1c2VmdWwgZm9yIGNoYWluaW5nIG5leHQoKSBjYWxscykuCiAqLwpUYXNrLnByb3RvdHlwZS5wYXJhbGxlbCA9IGZ1bmN0aW9uKG5hbWUsIHN1YnJ1bikgewogIC8vIGp1Z2dsZSBwYXJhbWV0ZXJzIGlmIGl0IGxvb2tzIGxpa2Ugbm8gbmFtZSBpcyBnaXZlbgogIGlmKGZvcmdlLnV0aWwuaXNBcnJheShuYW1lKSkgewogICAgc3VicnVuID0gbmFtZTsKCiAgICAvLyBpbmhlcml0IHBhcmVudCdzIG5hbWUKICAgIG5hbWUgPSB0aGlzLm5hbWU7CiAgfQogIC8vIFdyYXAgcGFyYWxsZWwgdGFza3MgaW4gYSByZWd1bGFyIHRhc2sgc28gdGhleSBhcmUgc3RhcnRlZCBhdCB0aGUKICAvLyBwcm9wZXIgdGltZS4KICByZXR1cm4gdGhpcy5uZXh0KG5hbWUsIGZ1bmN0aW9uKHRhc2spIHsKICAgIC8vIGJsb2NrIHdhaXRpbmcgZm9yIHN1YnRhc2tzCiAgICB2YXIgcHRhc2sgPSB0YXNrOwogICAgcHRhc2suYmxvY2soc3VicnVuLmxlbmd0aCk7CgogICAgLy8gd2UgcGFzcyB0aGUgaXRlcmF0b3IgZnJvbSB0aGUgbG9vcCBiZWxvdyBhcyBhIHBhcmFtZXRlcgogICAgLy8gdG8gYSBmdW5jdGlvbiBiZWNhdXNlIGl0IGlzIG90aGVyd2lzZSBpbmNsdWRlZCBpbiB0aGUKICAgIC8vIGNsb3N1cmUgYW5kIGNoYW5nZXMgYXMgdGhlIGxvb3AgY2hhbmdlcyAtLSBjYXVzaW5nIGkKICAgIC8vIHRvIGFsd2F5cyBiZSBzZXQgdG8gaXRzIGhpZ2hlc3QgdmFsdWUKICAgIHZhciBzdGFydFBhcmFsbGVsVGFzayA9IGZ1bmN0aW9uKHBuYW1lLCBwaSkgewogICAgICBmb3JnZS50YXNrLnN0YXJ0KHsKICAgICAgICB0eXBlOiBwbmFtZSwKICAgICAgICBydW46IGZ1bmN0aW9uKHRhc2spIHsKICAgICAgICAgICBzdWJydW5bcGldKHRhc2spOwogICAgICAgIH0sCiAgICAgICAgc3VjY2VzczogZnVuY3Rpb24odGFzaykgewogICAgICAgICAgIHB0YXNrLnVuYmxvY2soKTsKICAgICAgICB9LAogICAgICAgIGZhaWx1cmU6IGZ1bmN0aW9uKHRhc2spIHsKICAgICAgICAgICBwdGFzay51bmJsb2NrKCk7CiAgICAgICAgfQogICAgICB9KTsKICAgIH07CgogICAgZm9yKHZhciBpID0gMDsgaSA8IHN1YnJ1bi5sZW5ndGg7IGkrKykgewogICAgICAvLyBUeXBlIG11c3QgYmUgdW5pcXVlIHNvIHRhc2sgc3RhcnRzIGluIHBhcmFsbGVsOgogICAgICAvLyAgICBuYW1lICsgcHJpdmF0ZSBzdHJpbmcgKyB0YXNrIGlkICsgc3ViLXRhc2sgaW5kZXgKICAgICAgLy8gc3RhcnQgdGFza3MgaW4gcGFyYWxsZWwgYW5kIHVuYmxvY2sgd2hlbiB0aGUgZmluaXNoCiAgICAgIHZhciBwbmFtZSA9IG5hbWUgKyAnX19wYXJhbGxlbC0nICsgdGFzay5pZCArICctJyArIGk7CiAgICAgIHZhciBwaSA9IGk7CiAgICAgIHN0YXJ0UGFyYWxsZWxUYXNrKHBuYW1lLCBwaSk7CiAgICB9CiAgfSk7Cn07CgovKioKICogU3RvcHMgYSBydW5uaW5nIHRhc2suCiAqLwpUYXNrLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5zdGF0ZSA9IHNTdGF0ZVRhYmxlW3RoaXMuc3RhdGVdW1NUT1BdOwp9OwoKLyoqCiAqIFN0YXJ0cyBydW5uaW5nIGEgdGFzay4KICovClRhc2sucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oKSB7CiAgdGhpcy5lcnJvciA9IGZhbHNlOwogIHRoaXMuc3RhdGUgPSBzU3RhdGVUYWJsZVt0aGlzLnN0YXRlXVtTVEFSVF07CgogIC8vIHRyeSB0byByZXN0YXJ0CiAgaWYodGhpcy5zdGF0ZSA9PT0gUlVOTklORykgewogICAgdGhpcy5zdGFydCA9IG5ldyBEYXRlKCk7CiAgICB0aGlzLnJ1bih0aGlzKTsKICAgIHJ1bk5leHQodGhpcywgMCk7CiAgfQp9OwoKLyoqCiAqIEJsb2NrcyBhIHRhc2sgdW50aWwgaXQgb25lIG9yIG1vcmUgcGVybWl0cyBoYXZlIGJlZW4gcmVsZWFzZWQuIFRoZQogKiB0YXNrIHdpbGwgbm90IHJlc3VtZSB1bnRpbCB0aGUgcmVxdWVzdGVkIG51bWJlciBvZiBwZXJtaXRzIGhhdmUKICogYmVlbiByZWxlYXNlZCB3aXRoIGNhbGwocykgdG8gdW5ibG9jaygpLgogKgogKiBAcGFyYW0gbiBudW1iZXIgb2YgcGVybWl0cyB0byB3YWl0IGZvcihkZWZhdWx0OiAxKS4KICovClRhc2sucHJvdG90eXBlLmJsb2NrID0gZnVuY3Rpb24obikgewogIG4gPSB0eXBlb2YobikgPT09ICd1bmRlZmluZWQnID8gMSA6IG47CiAgdGhpcy5ibG9ja3MgKz0gbjsKICBpZih0aGlzLmJsb2NrcyA+IDApIHsKICAgIHRoaXMuc3RhdGUgPSBzU3RhdGVUYWJsZVt0aGlzLnN0YXRlXVtCTE9DS107CiAgfQp9OwoKLyoqCiAqIFJlbGVhc2VzIGEgcGVybWl0IHRvIHVuYmxvY2sgYSB0YXNrLiBJZiBhIHRhc2sgd2FzIGJsb2NrZWQgYnkKICogcmVxdWVzdGluZyBOIHBlcm1pdHMgdmlhIGJsb2NrKCksIHRoZW4gaXQgd2lsbCBvbmx5IGNvbnRpbnVlCiAqIHJ1bm5pbmcgb25jZSBlbm91Z2ggcGVybWl0cyBoYXZlIGJlZW4gcmVsZWFzZWQgdmlhIHVuYmxvY2soKSBjYWxscy4KICoKICogSWYgbXVsdGlwbGUgcHJvY2Vzc2VzIG5lZWQgdG8gc3luY2hyb25pemUgd2l0aCBhIHNpbmdsZSB0YXNrIHRoZW4KICogdXNlIGEgY29uZGl0aW9uIHZhcmlhYmxlIChzZWUgZm9yZ2UudGFzay5jcmVhdGVDb25kaXRpb24pLiBJdCBpcwogKiBhbiBlcnJvciB0byB1bmJsb2NrIGEgdGFzayBtb3JlIHRpbWVzIHRoYW4gaXQgaGFzIGJlZW4gYmxvY2tlZC4KICoKICogQHBhcmFtIG4gbnVtYmVyIG9mIHBlcm1pdHMgdG8gcmVsZWFzZSAoZGVmYXVsdDogMSkuCiAqCiAqIEByZXR1cm4gdGhlIGN1cnJlbnQgYmxvY2sgY291bnQgKHRhc2sgaXMgdW5ibG9ja2VkIHdoZW4gY291bnQgaXMgMCkKICovClRhc2sucHJvdG90eXBlLnVuYmxvY2sgPSBmdW5jdGlvbihuKSB7CiAgbiA9IHR5cGVvZihuKSA9PT0gJ3VuZGVmaW5lZCcgPyAxIDogbjsKICB0aGlzLmJsb2NrcyAtPSBuOwogIGlmKHRoaXMuYmxvY2tzID09PSAwICYmIHRoaXMuc3RhdGUgIT09IERPTkUpIHsKICAgIHRoaXMuc3RhdGUgPSBSVU5OSU5HOwogICAgcnVuTmV4dCh0aGlzLCAwKTsKICB9CiAgcmV0dXJuIHRoaXMuYmxvY2tzOwp9OwoKLyoqCiAqIFNsZWVwIGZvciBhIHBlcmlvZCBvZiB0aW1lIGJlZm9yZSByZXN1bWluZyB0YXNrcy4KICoKICogQHBhcmFtIG4gbnVtYmVyIG9mIG1pbGxpc2Vjb25kcyB0byBzbGVlcCAoZGVmYXVsdDogMCkuCiAqLwpUYXNrLnByb3RvdHlwZS5zbGVlcCA9IGZ1bmN0aW9uKG4pIHsKICBuID0gdHlwZW9mKG4pID09PSAndW5kZWZpbmVkJyA/IDAgOiBuOwogIHRoaXMuc3RhdGUgPSBzU3RhdGVUYWJsZVt0aGlzLnN0YXRlXVtTTEVFUF07CiAgdmFyIHNlbGYgPSB0aGlzOwogIHRoaXMudGltZW91dElkID0gc2V0VGltZW91dChmdW5jdGlvbigpIHsKICAgIHNlbGYudGltZW91dElkID0gbnVsbDsKICAgIHNlbGYuc3RhdGUgPSBSVU5OSU5HOwogICAgcnVuTmV4dChzZWxmLCAwKTsKICB9LCBuKTsKfTsKCi8qKgogKiBXYWl0cyBvbiBhIGNvbmRpdGlvbiB2YXJpYWJsZSB1bnRpbCBub3RpZmllZC4gVGhlIG5leHQgdGFzayB3aWxsCiAqIG5vdCBiZSBzY2hlZHVsZWQgdW50aWwgbm90aWZpY2F0aW9uLiBBIGNvbmRpdGlvbiB2YXJpYWJsZSBjYW4gYmUKICogY3JlYXRlZCB3aXRoIGZvcmdlLnRhc2suY3JlYXRlQ29uZGl0aW9uKCkuCiAqCiAqIE9uY2UgY29uZC5ub3RpZnkoKSBpcyBjYWxsZWQsIHRoZSB0YXNrIHdpbGwgY29udGludWUuCiAqCiAqIEBwYXJhbSBjb25kIHRoZSBjb25kaXRpb24gdmFyaWFibGUgdG8gd2FpdCBvbi4KICovClRhc2sucHJvdG90eXBlLndhaXQgPSBmdW5jdGlvbihjb25kKSB7CiAgY29uZC53YWl0KHRoaXMpOwp9OwoKLyoqCiAqIElmIHNsZWVwaW5nLCB3YWtldXAgYW5kIGNvbnRpbnVlIHJ1bm5pbmcgdGFza3MuCiAqLwpUYXNrLnByb3RvdHlwZS53YWtldXAgPSBmdW5jdGlvbigpIHsKICBpZih0aGlzLnN0YXRlID09PSBTTEVFUElORykgewogICAgY2FuY2VsVGltZW91dCh0aGlzLnRpbWVvdXRJZCk7CiAgICB0aGlzLnRpbWVvdXRJZCA9IG51bGw7CiAgICB0aGlzLnN0YXRlID0gUlVOTklORzsKICAgIHJ1bk5leHQodGhpcywgMCk7CiAgfQp9OwoKLyoqCiAqIENhbmNlbCBhbGwgcmVtYWluaW5nIHN1YnRhc2tzIG9mIHRoaXMgdGFzay4KICovClRhc2sucHJvdG90eXBlLmNhbmNlbCA9IGZ1bmN0aW9uKCkgewogIHRoaXMuc3RhdGUgPSBzU3RhdGVUYWJsZVt0aGlzLnN0YXRlXVtDQU5DRUxdOwogIC8vIHJlbW92ZSBwZXJtaXRzIG5lZWRlZAogIHRoaXMucGVybWl0c05lZWRlZCA9IDA7CiAgLy8gY2FuY2VsIHRpbWVvdXRzCiAgaWYodGhpcy50aW1lb3V0SWQgIT09IG51bGwpIHsKICAgIGNhbmNlbFRpbWVvdXQodGhpcy50aW1lb3V0SWQpOwogICAgdGhpcy50aW1lb3V0SWQgPSBudWxsOwogIH0KICAvLyByZW1vdmUgc3VidGFza3MKICB0aGlzLnN1YnRhc2tzID0gW107Cn07CgovKioKICogRmluaXNoZXMgdGhpcyB0YXNrIHdpdGggZmFpbHVyZSBhbmQgc2V0cyBlcnJvciBmbGFnLiBUaGUgZW50aXJlCiAqIHRhc2sgd2lsbCBiZSBhYm9ydGVkIHVubGVzcyB0aGUgbmV4dCB0YXNrIHRoYXQgc2hvdWxkIGV4ZWN1dGUKICogaXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyLiBUaGlzIGFsbG93cyBsZXZlbHMgb2Ygc3VidGFza3MgdG8gYmUKICogc2tpcHBlZC4gRm9yIGluc3RhbmNlLCB0byBhYm9ydCBvbmx5IHRoaXMgdGFza3MncyBzdWJ0YXNrcywgdGhlbgogKiBjYWxsIGZhaWwodGFzay5wYXJlbnQpLiBUbyBhYm9ydCB0aGlzIHRhc2sncyBzdWJ0YXNrcyBhbmQgaXRzCiAqIHBhcmVudCdzIHN1YnRhc2tzLCBjYWxsIGZhaWwodGFzay5wYXJlbnQucGFyZW50KS4gVG8gYWJvcnQKICogYWxsIHRhc2tzIGFuZCBzaW1wbHkgY2FsbCB0aGUgdGFzayBjYWxsYmFjaywgY2FsbCBmYWlsKCkgb3IKICogZmFpbChudWxsKS4KICoKICogVGhlIHRhc2sgY2FsbGJhY2sgKHN1Y2Nlc3Mgb3IgZmFpbHVyZSkgd2lsbCBhbHdheXMsIGV2ZW50dWFsbHksIGJlCiAqIGNhbGxlZC4KICoKICogQHBhcmFtIG5leHQgdGhlIHRhc2sgdG8gY29udGludWUgYXQsIG9yIG51bGwgdG8gYWJvcnQgZW50aXJlbHkuCiAqLwpUYXNrLnByb3RvdHlwZS5mYWlsID0gZnVuY3Rpb24obmV4dCkgewogIC8vIHNldCBlcnJvciBmbGFnCiAgdGhpcy5lcnJvciA9IHRydWU7CgogIC8vIGZpbmlzaCB0YXNrCiAgZmluaXNoKHRoaXMsIHRydWUpOwoKICBpZihuZXh0KSB7CiAgICAvLyBwcm9wYWdhdGUgdGFzayBpbmZvCiAgICBuZXh0LmVycm9yID0gdGhpcy5lcnJvcjsKICAgIG5leHQuc3dhcFRpbWUgPSB0aGlzLnN3YXBUaW1lOwogICAgbmV4dC51c2VyRGF0YSA9IHRoaXMudXNlckRhdGE7CgogICAgLy8gZG8gbmV4dCB0YXNrIGFzIHNwZWNpZmllZAogICAgcnVuTmV4dChuZXh0LCAwKTsKICB9IGVsc2UgewogICAgaWYodGhpcy5wYXJlbnQgIT09IG51bGwpIHsKICAgICAgLy8gZmluaXNoIHJvb3QgdGFzayAoZW5zdXJlcyBpdCBpcyByZW1vdmVkIGZyb20gdGFzayBxdWV1ZSkKICAgICAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50OwogICAgICB3aGlsZShwYXJlbnQucGFyZW50ICE9PSBudWxsKSB7CiAgICAgICAgLy8gcHJvcGFnYXRlIHRhc2sgaW5mbwogICAgICAgIHBhcmVudC5lcnJvciA9IHRoaXMuZXJyb3I7CiAgICAgICAgcGFyZW50LnN3YXBUaW1lID0gdGhpcy5zd2FwVGltZTsKICAgICAgICBwYXJlbnQudXNlckRhdGEgPSB0aGlzLnVzZXJEYXRhOwogICAgICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnQ7CiAgICAgIH0KICAgICAgZmluaXNoKHBhcmVudCwgdHJ1ZSk7CiAgICB9CgogICAgLy8gY2FsbCBmYWlsdXJlIGNhbGxiYWNrIGlmIG9uZSBleGlzdHMKICAgIGlmKHRoaXMuZmFpbHVyZUNhbGxiYWNrKSB7CiAgICAgIHRoaXMuZmFpbHVyZUNhbGxiYWNrKHRoaXMpOwogICAgfQogIH0KfTsKCi8qKgogKiBBc3luY2hyb25vdXNseSBzdGFydCBhIHRhc2suCiAqCiAqIEBwYXJhbSB0YXNrIHRoZSB0YXNrIHRvIHN0YXJ0LgogKi8KdmFyIHN0YXJ0ID0gZnVuY3Rpb24odGFzaykgewogIHRhc2suZXJyb3IgPSBmYWxzZTsKICB0YXNrLnN0YXRlID0gc1N0YXRlVGFibGVbdGFzay5zdGF0ZV1bU1RBUlRdOwogIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7CiAgICBpZih0YXNrLnN0YXRlID09PSBSVU5OSU5HKSB7CiAgICAgIHRhc2suc3dhcFRpbWUgPSArbmV3IERhdGUoKTsKICAgICAgdGFzay5ydW4odGFzayk7CiAgICAgIHJ1bk5leHQodGFzaywgMCk7CiAgICB9CiAgfSwgMCk7Cn07CgovKioKICogUnVuIHRoZSBuZXh0IHN1YnRhc2sgb3IgZmluaXNoIHRoaXMgdGFzay4KICoKICogQHBhcmFtIHRhc2sgdGhlIHRhc2sgdG8gcHJvY2Vzcy4KICogQHBhcmFtIHJlY3Vyc2UgdGhlIHJlY3Vyc2lvbiBjb3VudC4KICovCnZhciBydW5OZXh0ID0gZnVuY3Rpb24odGFzaywgcmVjdXJzZSkgewogIC8vIGdldCB0aW1lIHNpbmNlIGxhc3QgY29udGV4dCBzd2FwIChtcyksIGlmIGVub3VnaCB0aW1lIGhhcyBwYXNzZWQgc2V0CiAgLy8gc3dhcCB0byB0cnVlIHRvIGluZGljYXRlIHRoYXQgZG9OZXh0IHdhcyBwZXJmb3JtZWQgYXN5bmNocm9ub3VzbHkKICAvLyBhbHNvLCBpZiByZWN1cnNlIGlzIHRvbyBoaWdoIGRvIGFzeW5jaHJvbm91c2x5CiAgdmFyIHN3YXAgPQogICAgKHJlY3Vyc2UgPiBzTWF4UmVjdXJzaW9ucykgfHwKICAgICgrbmV3IERhdGUoKSAtIHRhc2suc3dhcFRpbWUpID4gc1RpbWVTbGljZTsKCiAgdmFyIGRvTmV4dCA9IGZ1bmN0aW9uKHJlY3Vyc2UpIHsKICAgIHJlY3Vyc2UrKzsKICAgIGlmKHRhc2suc3RhdGUgPT09IFJVTk5JTkcpIHsKICAgICAgaWYoc3dhcCkgewogICAgICAgIC8vIHVwZGF0ZSBzd2FwIHRpbWUKICAgICAgICB0YXNrLnN3YXBUaW1lID0gK25ldyBEYXRlKCk7CiAgICAgIH0KCiAgICAgIGlmKHRhc2suc3VidGFza3MubGVuZ3RoID4gMCkgewogICAgICAgIC8vIHJ1biBuZXh0IHN1YnRhc2sKICAgICAgICB2YXIgc3VidGFzayA9IHRhc2suc3VidGFza3Muc2hpZnQoKTsKICAgICAgICBzdWJ0YXNrLmVycm9yID0gdGFzay5lcnJvcjsKICAgICAgICBzdWJ0YXNrLnN3YXBUaW1lID0gdGFzay5zd2FwVGltZTsKICAgICAgICBzdWJ0YXNrLnVzZXJEYXRhID0gdGFzay51c2VyRGF0YTsKICAgICAgICBzdWJ0YXNrLnJ1bihzdWJ0YXNrKTsKICAgICAgICBpZighc3VidGFzay5lcnJvcikgewogICAgICAgICAgIHJ1bk5leHQoc3VidGFzaywgcmVjdXJzZSk7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGZpbmlzaCh0YXNrKTsKCiAgICAgICAgaWYoIXRhc2suZXJyb3IpIHsKICAgICAgICAgIC8vIGNoYWluIGJhY2sgdXAgYW5kIHJ1biBwYXJlbnQKICAgICAgICAgIGlmKHRhc2sucGFyZW50ICE9PSBudWxsKSB7CiAgICAgICAgICAgIC8vIHByb3BhZ2F0ZSB0YXNrIGluZm8KICAgICAgICAgICAgdGFzay5wYXJlbnQuZXJyb3IgPSB0YXNrLmVycm9yOwogICAgICAgICAgICB0YXNrLnBhcmVudC5zd2FwVGltZSA9IHRhc2suc3dhcFRpbWU7CiAgICAgICAgICAgIHRhc2sucGFyZW50LnVzZXJEYXRhID0gdGFzay51c2VyRGF0YTsKCiAgICAgICAgICAgIC8vIG5vIHN1YnRhc2tzIGxlZnQsIGNhbGwgcnVuIG5leHQgc3VidGFzayBvbiBwYXJlbnQKICAgICAgICAgICAgcnVuTmV4dCh0YXNrLnBhcmVudCwgcmVjdXJzZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKCiAgaWYoc3dhcCkgewogICAgLy8gd2UncmUgc3dhcHBpbmcsIHNvIHJ1biBhc3luY2hyb25vdXNseQogICAgc2V0VGltZW91dChkb05leHQsIDApOwogIH0gZWxzZSB7CiAgICAvLyBub3Qgc3dhcHBpbmcsIHNvIHJ1biBzeW5jaHJvbm91c2x5CiAgICBkb05leHQocmVjdXJzZSk7CiAgfQp9OwoKLyoqCiAqIEZpbmlzaGVzIGEgdGFzayBhbmQgbG9va3MgZm9yIHRoZSBuZXh0IHRhc2sgaW4gdGhlIHF1ZXVlIHRvIHN0YXJ0LgogKgogKiBAcGFyYW0gdGFzayB0aGUgdGFzayB0byBmaW5pc2guCiAqIEBwYXJhbSBzdXBwcmVzc0NhbGxiYWNrcyB0cnVlIHRvIHN1cHByZXNzIGNhbGxiYWNrcy4KICovCnZhciBmaW5pc2ggPSBmdW5jdGlvbih0YXNrLCBzdXBwcmVzc0NhbGxiYWNrcykgewogIC8vIHN1YnRhc2sgaXMgbm93IGRvbmUKICB0YXNrLnN0YXRlID0gRE9ORTsKCiAgZGVsZXRlIHNUYXNrc1t0YXNrLmlkXTsKICBpZihzVkwgPj0gMSkgewogICAgZm9yZ2UubG9nLnZlcmJvc2UoY2F0LCAnWyVzXVslc10gZmluaXNoJywKICAgICAgdGFzay5pZCwgdGFzay5uYW1lLCB0YXNrKTsKICB9CgogIC8vIG9ubHkgZG8gcXVldWUgcHJvY2Vzc2luZyBmb3Igcm9vdCB0YXNrcwogIGlmKHRhc2sucGFyZW50ID09PSBudWxsKSB7CiAgICAvLyByZXBvcnQgZXJyb3IgaWYgcXVldWUgaXMgbWlzc2luZwogICAgaWYoISh0YXNrLnR5cGUgaW4gc1Rhc2tRdWV1ZXMpKSB7CiAgICAgIGZvcmdlLmxvZy5lcnJvcihjYXQsCiAgICAgICAgJ1slc11bJXNdIHRhc2sgcXVldWUgbWlzc2luZyBbJXNdJywKICAgICAgICB0YXNrLmlkLCB0YXNrLm5hbWUsIHRhc2sudHlwZSk7CiAgICB9IGVsc2UgaWYoc1Rhc2tRdWV1ZXNbdGFzay50eXBlXS5sZW5ndGggPT09IDApIHsKICAgICAgLy8gcmVwb3J0IGVycm9yIGlmIHF1ZXVlIGlzIGVtcHR5CiAgICAgIGZvcmdlLmxvZy5lcnJvcihjYXQsCiAgICAgICAgJ1slc11bJXNdIHRhc2sgcXVldWUgZW1wdHkgWyVzXScsCiAgICAgICAgdGFzay5pZCwgdGFzay5uYW1lLCB0YXNrLnR5cGUpOwogICAgfSBlbHNlIGlmKHNUYXNrUXVldWVzW3Rhc2sudHlwZV1bMF0gIT09IHRhc2spIHsKICAgICAgLy8gcmVwb3J0IGVycm9yIGlmIHRoaXMgdGFzayBpc24ndCB0aGUgZmlyc3QgaW4gdGhlIHF1ZXVlCiAgICAgIGZvcmdlLmxvZy5lcnJvcihjYXQsCiAgICAgICAgJ1slc11bJXNdIHRhc2sgbm90IGZpcnN0IGluIHF1ZXVlIFslc10nLAogICAgICAgIHRhc2suaWQsIHRhc2submFtZSwgdGFzay50eXBlKTsKICAgIH0gZWxzZSB7CiAgICAgIC8vIHJlbW92ZSBvdXJzZWx2ZXMgZnJvbSB0aGUgcXVldWUKICAgICAgc1Rhc2tRdWV1ZXNbdGFzay50eXBlXS5zaGlmdCgpOwogICAgICAvLyBjbGVhbiB1cCBxdWV1ZSBpZiBpdCBpcyBlbXB0eQogICAgICBpZihzVGFza1F1ZXVlc1t0YXNrLnR5cGVdLmxlbmd0aCA9PT0gMCkgewogICAgICAgIGlmKHNWTCA+PSAxKSB7CiAgICAgICAgICBmb3JnZS5sb2cudmVyYm9zZShjYXQsICdbJXNdWyVzXSBkZWxldGUgcXVldWUgWyVzXScsCiAgICAgICAgICAgIHRhc2suaWQsIHRhc2submFtZSwgdGFzay50eXBlKTsKICAgICAgICB9CiAgICAgICAgLyogTm90ZTogT25seSBhIHRhc2sgY2FuIGRlbGV0ZSBhIHF1ZXVlIG9mIGl0cyBvd24gdHlwZS4gVGhpcwogICAgICAgICBpcyB1c2VkIGFzIGEgd2F5IHRvIHN5bmNocm9uaXplIHRhc2tzLiBJZiBhIHF1ZXVlIGZvciBhIGNlcnRhaW4KICAgICAgICAgdGFzayB0eXBlIGV4aXN0cywgdGhlbiBhIHRhc2sgb2YgdGhhdCB0eXBlIGlzIHJ1bm5pbmcuCiAgICAgICAgICovCiAgICAgICAgZGVsZXRlIHNUYXNrUXVldWVzW3Rhc2sudHlwZV07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gZGVxdWV1ZSB0aGUgbmV4dCB0YXNrIGFuZCBzdGFydCBpdAogICAgICAgIGlmKHNWTCA+PSAxKSB7CiAgICAgICAgICBmb3JnZS5sb2cudmVyYm9zZShjYXQsCiAgICAgICAgICAgICdbJXNdWyVzXSBxdWV1ZSBzdGFydCBuZXh0IFslc10gcmVtYWluOiVzJywKICAgICAgICAgICAgdGFzay5pZCwgdGFzay5uYW1lLCB0YXNrLnR5cGUsCiAgICAgICAgICAgIHNUYXNrUXVldWVzW3Rhc2sudHlwZV0ubGVuZ3RoKTsKICAgICAgICB9CiAgICAgICAgc1Rhc2tRdWV1ZXNbdGFzay50eXBlXVswXS5zdGFydCgpOwogICAgICB9CiAgICB9CgogICAgaWYoIXN1cHByZXNzQ2FsbGJhY2tzKSB7CiAgICAgIC8vIGNhbGwgZmluYWwgY2FsbGJhY2sgaWYgb25lIGV4aXN0cwogICAgICBpZih0YXNrLmVycm9yICYmIHRhc2suZmFpbHVyZUNhbGxiYWNrKSB7CiAgICAgICAgdGFzay5mYWlsdXJlQ2FsbGJhY2sodGFzayk7CiAgICAgIH0gZWxzZSBpZighdGFzay5lcnJvciAmJiB0YXNrLnN1Y2Nlc3NDYWxsYmFjaykgewogICAgICAgIHRhc2suc3VjY2Vzc0NhbGxiYWNrKHRhc2spOwogICAgICB9CiAgICB9CiAgfQp9OwoKLyogVGFza3MgQVBJICovCmZvcmdlLnRhc2sgPSBmb3JnZS50YXNrIHx8IHt9OwoKLyoqCiAqIFN0YXJ0cyBhIG5ldyB0YXNrIHRoYXQgd2lsbCBydW4gdGhlIHBhc3NlZCBmdW5jdGlvbiBhc3luY2hyb25vdXNseS4KICoKICogSW4gb3JkZXIgdG8gZmluaXNoIHRoZSB0YXNrLCBlaXRoZXIgdGFzay5kb05leHQoKSBvciB0YXNrLmZhaWwoKQogKiAqbXVzdCogYmUgY2FsbGVkLgogKgogKiBUaGUgdGFzayBtdXN0IGhhdmUgYSB0eXBlIChhIHN0cmluZyBpZGVudGlmaWVyKSB0aGF0IGNhbiBiZSB1c2VkIHRvCiAqIHN5bmNocm9uaXplIGl0IHdpdGggb3RoZXIgdGFza3Mgb2YgdGhlIHNhbWUgdHlwZS4gVGhhdCB0eXBlIGNhbiBhbHNvCiAqIGJlIHVzZWQgdG8gY2FuY2VsIHRhc2tzIHRoYXQgaGF2ZW4ndCBzdGFydGVkIHlldC4KICoKICogVG8gc3RhcnQgYSB0YXNrLCB0aGUgZm9sbG93aW5nIG9iamVjdCBtdXN0IGJlIHByb3ZpZGVkIGFzIGEgcGFyYW1ldGVyCiAqIChlYWNoIGZ1bmN0aW9uIHRha2VzIGEgdGFzayBvYmplY3QgYXMgaXRzIGZpcnN0IHBhcmFtZXRlcik6CiAqCiAqIHsKICogICB0eXBlOiB0aGUgdHlwZSBvZiB0YXNrLgogKiAgIHJ1bjogdGhlIGZ1bmN0aW9uIHRvIHJ1biB0byBleGVjdXRlIHRoZSB0YXNrLgogKiAgIHN1Y2Nlc3M6IGEgY2FsbGJhY2sgdG8gY2FsbCB3aGVuIHRoZSB0YXNrIHN1Y2NlZWRzIChvcHRpb25hbCkuCiAqICAgZmFpbHVyZTogYSBjYWxsYmFjayB0byBjYWxsIHdoZW4gdGhlIHRhc2sgZmFpbHMgKG9wdGlvbmFsKS4KICogfQogKgogKiBAcGFyYW0gb3B0aW9ucyB0aGUgb2JqZWN0IGFzIGRlc2NyaWJlZCBhYm92ZS4KICovCmZvcmdlLnRhc2suc3RhcnQgPSBmdW5jdGlvbihvcHRpb25zKSB7CiAgLy8gY3JlYXRlIGEgbmV3IHRhc2sKICB2YXIgdGFzayA9IG5ldyBUYXNrKHsKICAgIHJ1bjogb3B0aW9ucy5ydW4sCiAgICBuYW1lOiBvcHRpb25zLm5hbWUgfHwgc05vVGFza05hbWUKICB9KTsKICB0YXNrLnR5cGUgPSBvcHRpb25zLnR5cGU7CiAgdGFzay5zdWNjZXNzQ2FsbGJhY2sgPSBvcHRpb25zLnN1Y2Nlc3MgfHwgbnVsbDsKICB0YXNrLmZhaWx1cmVDYWxsYmFjayA9IG9wdGlvbnMuZmFpbHVyZSB8fCBudWxsOwoKICAvLyBhcHBlbmQgdGhlIHRhc2sgb250byB0aGUgYXBwcm9wcmlhdGUgcXVldWUKICBpZighKHRhc2sudHlwZSBpbiBzVGFza1F1ZXVlcykpIHsKICAgIGlmKHNWTCA+PSAxKSB7CiAgICAgIGZvcmdlLmxvZy52ZXJib3NlKGNhdCwgJ1slc11bJXNdIGNyZWF0ZSBxdWV1ZSBbJXNdJywKICAgICAgICB0YXNrLmlkLCB0YXNrLm5hbWUsIHRhc2sudHlwZSk7CiAgICB9CiAgICAvLyBjcmVhdGUgdGhlIHF1ZXVlIHdpdGggdGhlIG5ldyB0YXNrCiAgICBzVGFza1F1ZXVlc1t0YXNrLnR5cGVdID0gW3Rhc2tdOwogICAgc3RhcnQodGFzayk7CiAgfSBlbHNlIHsKICAgIC8vIHB1c2ggdGhlIHRhc2sgb250byB0aGUgcXVldWUsIGl0IHdpbGwgYmUgcnVuIGFmdGVyIGEgdGFzawogICAgLy8gd2l0aCB0aGUgc2FtZSB0eXBlIGNvbXBsZXRlcwogICAgc1Rhc2tRdWV1ZXNbb3B0aW9ucy50eXBlXS5wdXNoKHRhc2spOwogIH0KfTsKCi8qKgogKiBDYW5jZWxzIGFsbCB0YXNrcyBvZiB0aGUgZ2l2ZW4gdHlwZSB0aGF0IGhhdmVuJ3Qgc3RhcnRlZCB5ZXQuCiAqCiAqIEBwYXJhbSB0eXBlIHRoZSB0eXBlIG9mIHRhc2sgdG8gY2FuY2VsLgogKi8KZm9yZ2UudGFzay5jYW5jZWwgPSBmdW5jdGlvbih0eXBlKSB7CiAgLy8gZmluZCB0aGUgdGFzayBxdWV1ZQogIGlmKHR5cGUgaW4gc1Rhc2tRdWV1ZXMpIHsKICAgIC8vIGVtcHR5IGFsbCBidXQgdGhlIGN1cnJlbnQgdGFzayBmcm9tIHRoZSBxdWV1ZQogICAgc1Rhc2tRdWV1ZXNbdHlwZV0gPSBbc1Rhc2tRdWV1ZXNbdHlwZV1bMF1dOwogIH0KfTsKCi8qKgogKiBDcmVhdGVzIGEgY29uZGl0aW9uIHZhcmlhYmxlIHRvIHN5bmNocm9uaXplIHRhc2tzLiBUbyBtYWtlIGEgdGFzayB3YWl0CiAqIG9uIHRoZSBjb25kaXRpb24gdmFyaWFibGUsIGNhbGwgdGFzay53YWl0KGNvbmRpdGlvbikuIFRvIG5vdGlmeSBhbGwKICogdGFza3MgdGhhdCBhcmUgd2FpdGluZywgY2FsbCBjb25kaXRpb24ubm90aWZ5KCkuCiAqCiAqIEByZXR1cm4gdGhlIGNvbmRpdGlvbiB2YXJpYWJsZS4KICovCmZvcmdlLnRhc2suY3JlYXRlQ29uZGl0aW9uID0gZnVuY3Rpb24oKSB7CiAgdmFyIGNvbmQgPSB7CiAgICAvLyBhbGwgdGFza3MgdGhhdCBhcmUgYmxvY2tlZAogICAgdGFza3M6IHt9CiAgfTsKCiAgLyoqCiAgICogQ2F1c2VzIHRoZSBnaXZlbiB0YXNrIHRvIGJsb2NrIHVudGlsIG5vdGlmeSBpcyBjYWxsZWQuIElmIHRoZSB0YXNrCiAgICogaXMgYWxyZWFkeSB3YWl0aW5nIG9uIHRoaXMgY29uZGl0aW9uIHRoZW4gdGhpcyBpcyBhIG5vLW9wLgogICAqCiAgICogQHBhcmFtIHRhc2sgdGhlIHRhc2sgdG8gY2F1c2UgdG8gd2FpdC4KICAgKi8KICBjb25kLndhaXQgPSBmdW5jdGlvbih0YXNrKSB7CiAgICAvLyBvbmx5IGJsb2NrIG9uY2UKICAgIGlmKCEodGFzay5pZCBpbiBjb25kLnRhc2tzKSkgewogICAgICAgdGFzay5ibG9jaygpOwogICAgICAgY29uZC50YXNrc1t0YXNrLmlkXSA9IHRhc2s7CiAgICB9CiAgfTsKCiAgLyoqCiAgICogTm90aWZpZXMgYWxsIHdhaXRpbmcgdGFza3MgdG8gd2FrZSB1cC4KICAgKi8KICBjb25kLm5vdGlmeSA9IGZ1bmN0aW9uKCkgewogICAgLy8gc2luY2UgdW5ibG9jaygpIHdpbGwgcnVuIHRoZSBuZXh0IHRhc2sgZnJvbSBoZXJlLCBtYWtlIHN1cmUgdG8KICAgIC8vIGNsZWFyIHRoZSBjb25kaXRpb24ncyBibG9ja2VkIHRhc2sgbGlzdCBiZWZvcmUgdW5ibG9ja2luZwogICAgdmFyIHRtcCA9IGNvbmQudGFza3M7CiAgICBjb25kLnRhc2tzID0ge307CiAgICBmb3IodmFyIGlkIGluIHRtcCkgewogICAgICB0bXBbaWRdLnVuYmxvY2soKTsKICAgIH0KICB9OwoKICByZXR1cm4gY29uZDsKfTsKCn0gLy8gZW5kIG1vZHVsZSBpbXBsZW1lbnRhdGlvbgoKLyogIyMjIyMjIyMjIyBCZWdpbiBtb2R1bGUgd3JhcHBlciAjIyMjIyMjIyMjICovCnZhciBuYW1lID0gJ3Rhc2snOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICBmb3JnZSA9IHt9OwogICAgfQogICAgcmV0dXJuIGluaXRNb2R1bGUoZm9yZ2UpOwogIH0KfQovLyBBTUQKdmFyIGRlcHM7CnZhciBkZWZpbmVGdW5jID0gZnVuY3Rpb24ocmVxdWlyZSwgbW9kdWxlKSB7CiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihmb3JnZSkgewogICAgdmFyIG1vZHMgPSBkZXBzLm1hcChmdW5jdGlvbihkZXApIHsKICAgICAgcmV0dXJuIHJlcXVpcmUoZGVwKTsKICAgIH0pLmNvbmNhdChpbml0TW9kdWxlKTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZVtuYW1lXTsKICB9Owp9Owp2YXIgdG1wRGVmaW5lID0gZGVmaW5lOwpkZWZpbmUgPSBmdW5jdGlvbihpZHMsIGZhY3RvcnkpIHsKICBkZXBzID0gKHR5cGVvZiBpZHMgPT09ICdzdHJpbmcnKSA/IGZhY3Rvcnkuc2xpY2UoMikgOiBpZHMuc2xpY2UoMik7CiAgaWYobm9kZUpTKSB7CiAgICBkZWxldGUgZGVmaW5lOwogICAgcmV0dXJuIHRtcERlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKICB9CiAgZGVmaW5lID0gdG1wRGVmaW5lOwogIHJldHVybiBkZWZpbmUuYXBwbHkobnVsbCwgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSk7Cn07CmRlZmluZSgnanMvdGFzaycsWydyZXF1aXJlJywgJ21vZHVsZScsICcuL2RlYnVnJywgJy4vbG9nJywgJy4vdXRpbCddLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCi8qKgogKiBOb2RlLmpzIG1vZHVsZSBmb3IgRm9yZ2UuCiAqCiAqIEBhdXRob3IgRGF2ZSBMb25nbGV5CiAqCiAqIENvcHlyaWdodCAyMDExLTIwMTQgRGlnaXRhbCBCYXphYXIsIEluYy4KICovCihmdW5jdGlvbigpIHsKdmFyIG5hbWUgPSAnZm9yZ2UnOwppZih0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7CiAgLy8gTm9kZUpTIC0+IEFNRAogIGlmKHR5cGVvZiBtb2R1bGUgPT09ICdvYmplY3QnICYmIG1vZHVsZS5leHBvcnRzKSB7CiAgICB2YXIgbm9kZUpTID0gdHJ1ZTsKICAgIGRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogICAgICBmYWN0b3J5KHJlcXVpcmUsIG1vZHVsZSk7CiAgICB9OwogIH0gZWxzZSB7CiAgICAvLyA8c2NyaXB0PgogICAgaWYodHlwZW9mIGZvcmdlID09PSAndW5kZWZpbmVkJykgewogICAgICAvLyBzZXQgdG8gdHJ1ZSB0byBkaXNhYmxlIG5hdGl2ZSBjb2RlIGlmIGV2ZW4gaXQncyBhdmFpbGFibGUKICAgICAgZm9yZ2UgPSB7ZGlzYWJsZU5hdGl2ZUNvZGU6IGZhbHNlfTsKICAgIH0KICAgIHJldHVybjsKICB9Cn0KLy8gQU1ECnZhciBkZXBzOwp2YXIgZGVmaW5lRnVuYyA9IGZ1bmN0aW9uKHJlcXVpcmUsIG1vZHVsZSkgewogIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZm9yZ2UpIHsKICAgIHZhciBtb2RzID0gZGVwcy5tYXAoZnVuY3Rpb24oZGVwKSB7CiAgICAgIHJldHVybiByZXF1aXJlKGRlcCk7CiAgICB9KTsKICAgIC8vIGhhbmRsZSBjaXJjdWxhciBkZXBlbmRlbmNpZXMKICAgIGZvcmdlID0gZm9yZ2UgfHwge307CiAgICBmb3JnZS5kZWZpbmVkID0gZm9yZ2UuZGVmaW5lZCB8fCB7fTsKICAgIGlmKGZvcmdlLmRlZmluZWRbbmFtZV0pIHsKICAgICAgcmV0dXJuIGZvcmdlW25hbWVdOwogICAgfQogICAgZm9yZ2UuZGVmaW5lZFtuYW1lXSA9IHRydWU7CiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbW9kcy5sZW5ndGg7ICsraSkgewogICAgICBtb2RzW2ldKGZvcmdlKTsKICAgIH0KICAgIHJldHVybiBmb3JnZTsKICB9OwogIC8vIHNldCB0byB0cnVlIHRvIGRpc2FibGUgbmF0aXZlIGNvZGUgaWYgZXZlbiBpdCdzIGF2YWlsYWJsZQogIG1vZHVsZS5leHBvcnRzLmRpc2FibGVOYXRpdmVDb2RlID0gdHJ1ZTsKICBtb2R1bGUuZXhwb3J0cyhtb2R1bGUuZXhwb3J0cyk7Cn07CnZhciB0bXBEZWZpbmUgPSBkZWZpbmU7CmRlZmluZSA9IGZ1bmN0aW9uKGlkcywgZmFjdG9yeSkgewogIGRlcHMgPSAodHlwZW9mIGlkcyA9PT0gJ3N0cmluZycpID8gZmFjdG9yeS5zbGljZSgyKSA6IGlkcy5zbGljZSgyKTsKICBpZihub2RlSlMpIHsKICAgIGRlbGV0ZSBkZWZpbmU7CiAgICByZXR1cm4gdG1wRGVmaW5lLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwogIH0KICBkZWZpbmUgPSB0bXBEZWZpbmU7CiAgcmV0dXJuIGRlZmluZS5hcHBseShudWxsLCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApKTsKfTsKZGVmaW5lKCdqcy9mb3JnZScsWwogICdyZXF1aXJlJywKICAnbW9kdWxlJywKICAnLi9hZXMnLAogICcuL2Flc0NpcGhlclN1aXRlcycsCiAgJy4vYXNuMScsCiAgJy4vY2lwaGVyJywKICAnLi9jaXBoZXJNb2RlcycsCiAgJy4vZGVidWcnLAogICcuL2RlcycsCiAgJy4vaG1hYycsCiAgJy4va2VtJywKICAnLi9sb2cnLAogICcuL21kJywKICAnLi9tZ2YxJywKICAnLi9wYmtkZjInLAogICcuL3BlbScsCiAgJy4vcGtjczcnLAogICcuL3BrY3MxJywKICAnLi9wa2NzMTInLAogICcuL3BraScsCiAgJy4vcHJpbWUnLAogICcuL3BybmcnLAogICcuL3BzcycsCiAgJy4vcmFuZG9tJywKICAnLi9yYzInLAogICcuL3NzaCcsCiAgJy4vdGFzaycsCiAgJy4vdGxzJywKICAnLi91dGlsJwpdLCBmdW5jdGlvbigpIHsKICBkZWZpbmVGdW5jLmFwcGx5KG51bGwsIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCkpOwp9KTsKfSkoKTsKCgpyZXR1cm4gcmVxdWlyZSgnanMvZm9yZ2UnKTsKCn0pOwovKioNCiogQGZpbGVvdmVydmlldyBJbnRlbChyKSBBTVQgQ2VydGlmaWNhdGUgZnVuY3Rpb25zDQoqIEBhdXRob3IgWWxpYW4gU2FpbnQtSGlsYWlyZQ0KKiBAdmVyc2lvbiB2MC4yLjBiDQoqLw0KDQovLyBDaGVjayB3aGljaCBrZXkgcGFpciBtYXRjaGVzIHRoZSBwdWJsaWMga2V5IGluIHRoZSBjZXJ0aWZpY2F0ZQ0KZnVuY3Rpb24gYW10Y2VydF9saW5rQ2VydFByaXZhdGVLZXkoY2VydHMsIGtleXMpIHsNCiAgICBmb3IgKHZhciBpIGluIGNlcnRzKSB7DQogICAgICAgIHZhciBjZXJ0ID0gY2VydHNbaV07DQogICAgICAgIHRyeSB7DQogICAgICAgICAgICBpZiAoeHhDZXJ0UHJpdmF0ZUtleXMubGVuZ3RoID09IDApIHJldHVybjsNCiAgICAgICAgICAgIHZhciBwdWJsaWNLZXlQRU0gPSBmb3JnZS5wa2kucHVibGljS2V5VG9QZW0oZm9yZ2UucGtpLmNlcnRpZmljYXRlRnJvbUFzbjEoZm9yZ2UuYXNuMS5mcm9tRGVyKGNlcnQuWDUwOUNlcnRpZmljYXRlKSkucHVibGljS2V5KS5zdWJzdHJpbmcoMjggKyAzMikucmVwbGFjZSgvKFxyXG58XG58XHIpL2dtLCAiIik7DQogICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGtleXMubGVuZ3RoOyBqKyspIHsNCiAgICAgICAgICAgICAgICBpZiAocHVibGljS2V5UEVNID09PSAoa2V5c1tqXVsnREVSS2V5J10gKyAnLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tJykpIHsNCiAgICAgICAgICAgICAgICAgICAga2V5c1tqXS5YQ2VydCA9IGNlcnQ7IC8vIExpbmsgdGhlIGtleSBwYWlyIHRvIHRoZSBjZXJ0aWZpY2F0ZQ0KICAgICAgICAgICAgICAgICAgICBjZXJ0LlhQcml2YXRlS2V5ID0ga2V5c1tqXTsgLy8gTGluayB0aGUgY2VydGlmaWNhdGUgdG8gdGhlIGtleSBwYWlyDQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9IGNhdGNoIChlKSB7IGNvbnNvbGUubG9nKGUpOyB9DQogICAgfQ0KfQ0KDQovLyBMb2FkIGEgUDEyIGZpbGUsIGRlY29kZXMgaXQgdXNpbmcgdGhlIHBhc3N3b3JkIGFuZCByZXR1cm5zIHRoZSBwcml2YXRlIGtleSBoYW5kbGUNCmZ1bmN0aW9uIGFtdGNlcnRfbG9hZFAxMkZpbGUoZmlsZSwgcGFzc3dvcmQsIGZ1bmMpIHsNCiAgICB0cnkgew0KICAgICAgICAvLyBFbmNvZGUgaW4gQmFzZTY0IHNvIEZvcmdlIEFQSSBjYW4gcGFyc2UgaXQuDQogICAgICAgIHZhciBwMTJEZXIgPSB3aW5kb3cuZm9yZ2UudXRpbC5kZWNvZGU2NChidG9hKGZpbGUpKTsNCiAgICAgICAgdmFyIHAxMkFzbjEgPSB3aW5kb3cuZm9yZ2UuYXNuMS5mcm9tRGVyKHAxMkRlcik7DQogICAgICAgIHZhciBwMTIgPSB3aW5kb3cuZm9yZ2UucGtjczEyLnBrY3MxMkZyb21Bc24xKHAxMkFzbjEsIHBhc3N3b3JkKTsNCg0KICAgICAgICAvLyBQcml2YXRlIGtleSBpcyBzdG9yZWQgaW4gYSBzaHJvdWRlZCBrZXkgYmFnDQogICAgICAgIHZhciBiYWdzID0gcDEyLmdldEJhZ3MoeyBiYWdUeXBlOiB3aW5kb3cuZm9yZ2UucGtpLm9pZHMucGtjczhTaHJvdWRlZEtleUJhZyB9KTsNCiAgICAgICAgY29uc29sZS5hc3NlcnQoYmFnc1t3aW5kb3cuZm9yZ2UucGtpLm9pZHMucGtjczhTaHJvdWRlZEtleUJhZ10gJiYgYmFnc1t3aW5kb3cuZm9yZ2UucGtpLm9pZHMucGtjczhTaHJvdWRlZEtleUJhZ10ubGVuZ3RoID4gMCk7DQogICAgICAgIA0KICAgICAgICAvLyBJbXBvcnQgdGhlIEZvcmdlIHByaXZhdGUga2V5IHN0cnVjdHVyZSBpbnRvIFdlYiBDcnlwdG8NCiAgICAgICAgdmFyIHByaXZhdGVLZXkgPSBiYWdzW3dpbmRvdy5mb3JnZS5wa2kub2lkcy5wa2NzOFNocm91ZGVkS2V5QmFnXVswXS5rZXk7DQogICAgICAgIHZhciByc2FQcml2YXRlS2V5ID0gd2luZG93LmZvcmdlLnBraS5wcml2YXRlS2V5VG9Bc24xKHByaXZhdGVLZXkpOw0KICAgICAgICB2YXIgcHJpdmF0ZUtleUluZm8gPSB3aW5kb3cuZm9yZ2UucGtpLndyYXBSc2FQcml2YXRlS2V5KHJzYVByaXZhdGVLZXkpOw0KICAgICAgICB2YXIgcGtjczggPSB3aW5kb3cuZm9yZ2UuYXNuMS50b0Rlcihwcml2YXRlS2V5SW5mbykuZ2V0Qnl0ZXMoKTsNCiAgICAgICAgDQogICAgICAgIC8vIEdldCB0aGUgaXNzdWVyIGF0dHJpYnV0ZXMNCiAgICAgICAgdmFyIGNlcnRCYWdzID0gcDEyLmdldEJhZ3MoeyBiYWdUeXBlOiB3aW5kb3cuZm9yZ2UucGtpLm9pZHMuY2VydEJhZyB9KTsNCiAgICAgICAgdmFyIGlzc3VlckF0dHJpYnV0ZXMgPSBjZXJ0QmFnc1t3aW5kb3cuZm9yZ2UucGtpLm9pZHMuY2VydEJhZ11bMF0uY2VydC5zdWJqZWN0LmF0dHJpYnV0ZXM7DQoNCiAgICAgICAgdmFyIGJhZ3MxID0gcDEyLmdldEJhZ3MoeyBiYWdUeXBlOiBmb3JnZS5wa2kub2lkcy5jZXJ0QmFnIH0pOw0KICAgICAgICB2YXIgY2VydCA9IGJhZ3MxW2ZvcmdlLnBraS5vaWRzLmNlcnRCYWddWzBdLmNlcnQ7DQoNCiAgICAgICAgZnVuYyhwcml2YXRlS2V5LCBpc3N1ZXJBdHRyaWJ1dGVzLCBjZXJ0KTsNCiAgICAgICAgcmV0dXJuIHRydWU7DQogICAgfSBjYXRjaCAoZXgpIHsgfQ0KICAgIHJldHVybiBmYWxzZTsNCn0NCg0KZnVuY3Rpb24gYW10Y2VydF9zaWduV2l0aENhS2V5KERFUktleSwgY2FQcml2YXRlS2V5LCBjZXJ0QXR0cmlidXRlcywgaXNzdWVyQXR0cmlidXRlcywgZXh0S2V5VXNhZ2UpIHsNCiAgICBpZiAoIWNhUHJpdmF0ZUtleSB8fCBjYVByaXZhdGVLZXkgPT0gbnVsbCkgew0KICAgICAgICB2YXIgY2VydEFuZEtleSA9IGFtdGNlcnRfY3JlYXRlQ2VydGlmaWNhdGUoaXNzdWVyQXR0cmlidXRlcyk7DQogICAgICAgIGNhUHJpdmF0ZUtleSA9IGNlcnRBbmRLZXkua2V5Ow0KICAgIH0NCiAgICByZXR1cm4gYW10Y2VydF9jcmVhdGVDZXJ0aWZpY2F0ZShjZXJ0QXR0cmlidXRlcywgY2FQcml2YXRlS2V5LCBERVJLZXksIGlzc3VlckF0dHJpYnV0ZXMsIGV4dEtleVVzYWdlKTsNCn0NCg0KLy8gLS0tIEV4dGVuZGVkIEtleSBVc2FnZSBPSUQncyAtLS0NCi8vIDEuMy42LjEuNS41LjcuMy4xICAgICAgICAgICAgPSBUTFMgU2VydmVyIGNlcnRpZmljYXRlDQovLyAxLjMuNi4xLjUuNS43LjMuMiAgICAgICAgICAgID0gVExTIENsaWVudCBjZXJ0aWZpY2F0ZQ0KLy8gMi4xNi44NDAuMS4xMTM3NDEuMS4yLjEgICAgICA9IEludGVsIEFNVCBSZW1vdGUgQ29uc29sZQ0KLy8gMi4xNi44NDAuMS4xMTM3NDEuMS4yLjIgICAgICA9IEludGVsIEFNVCBMb2NhbCBDb25zb2xlDQovLyAyLjE2Ljg0MC4xLjExMzc0MS4xLjIuMyAgICAgID0gSW50ZWwgQU1UIENsaWVudCBTZXR1cCBDZXJ0aWZpY2F0ZSAoWmVyby1Ub3VjaCkNCg0KLy8gR2VuZXJhdGUgYSBjZXJ0aWZpY2F0ZSB3aXRoIGEgc2V0IG9mIGF0dHJpYnV0ZXMgc2lnbmVkIGJ5IGEgcm9vdENlcnQuIElmIHRoZSByb290Q2VydCBpcyBvYm1pdHRlZCwgdGhlIGdlbmVyYXRlZCBjZXJ0aWZpY2F0ZSBpcyBzZWxmLXNpZ25lZC4NCmZ1bmN0aW9uIGFtdGNlcnRfY3JlYXRlQ2VydGlmaWNhdGUoY2VydEF0dHJpYnV0ZXMsIGNhUHJpdmF0ZUtleSwgREVSS2V5LCBpc3N1ZXJBdHRyaWJ1dGVzLCBleHRLZXlVc2FnZSkgew0KICAgIC8vIEdlbmVyYXRlIGEga2V5cGFpciBhbmQgY3JlYXRlIGFuIFguNTA5djMgY2VydGlmaWNhdGUNCiAgICB2YXIga2V5cywgY2VydCA9IGZvcmdlLnBraS5jcmVhdGVDZXJ0aWZpY2F0ZSgpOw0KICAgIGlmICghREVSS2V5KSB7DQogICAgICAgIGtleXMgPSBmb3JnZS5wa2kucnNhLmdlbmVyYXRlS2V5UGFpcigyMDQ4KTsNCiAgICAgICAgY2VydC5wdWJsaWNLZXkgPSBrZXlzLnB1YmxpY0tleTsNCiAgICB9IGVsc2Ugew0KICAgICAgICBjZXJ0LnB1YmxpY0tleSA9IGZvcmdlLnBraS5wdWJsaWNLZXlGcm9tUGVtKCctLS0tLUJFR0lOIFBVQkxJQyBLRVktLS0tLScgKyBERVJLZXkgKyAnLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tJyk7DQogICAgfQ0KICAgIGNlcnQuc2VyaWFsTnVtYmVyID0gJycgKyBNYXRoLmZsb29yKChNYXRoLnJhbmRvbSgpICogMTAwMDAwKSArIDEpOw0KICAgIGNlcnQudmFsaWRpdHkubm90QmVmb3JlID0gbmV3IERhdGUoKTsNCiAgICBjZXJ0LnZhbGlkaXR5Lm5vdEJlZm9yZS5zZXRGdWxsWWVhcihjZXJ0LnZhbGlkaXR5Lm5vdEJlZm9yZS5nZXRGdWxsWWVhcigpIC0gMSk7IC8vIENyZWF0ZSBhIGNlcnRpZmljYXRlIHRoYXQgaXMgdmFsaWQgb25lIHllYXIgYmVmb3JlLCB0byBtYWtlIHN1cmUgb3V0LW9mLXN5bmMgY2xvY2tzIGRvbid0IHJlamVjdCB0aGlzIGNlcnQuDQogICAgY2VydC52YWxpZGl0eS5ub3RBZnRlciA9IG5ldyBEYXRlKCk7DQogICAgY2VydC52YWxpZGl0eS5ub3RBZnRlci5zZXRGdWxsWWVhcihjZXJ0LnZhbGlkaXR5Lm5vdEFmdGVyLmdldEZ1bGxZZWFyKCkgKyAzMCk7DQogICAgdmFyIGF0dHJzID0gW107DQogICAgaWYgKGNlcnRBdHRyaWJ1dGVzWydDTiddKSBhdHRycy5wdXNoKHsgbmFtZTogJ2NvbW1vbk5hbWUnLCB2YWx1ZTogY2VydEF0dHJpYnV0ZXNbJ0NOJ10gfSk7DQogICAgaWYgKGNlcnRBdHRyaWJ1dGVzWydDJ10pIGF0dHJzLnB1c2goeyBuYW1lOiAnY291bnRyeU5hbWUnLCB2YWx1ZTogY2VydEF0dHJpYnV0ZXNbJ0MnXSB9KTsNCiAgICBpZiAoY2VydEF0dHJpYnV0ZXNbJ1NUJ10pIGF0dHJzLnB1c2goeyBzaG9ydE5hbWU6ICdTVCcsIHZhbHVlOiBjZXJ0QXR0cmlidXRlc1snU1QnXSB9KTsNCiAgICBpZiAoY2VydEF0dHJpYnV0ZXNbJ08nXSkgYXR0cnMucHVzaCh7IG5hbWU6ICdvcmdhbml6YXRpb25OYW1lJywgdmFsdWU6IGNlcnRBdHRyaWJ1dGVzWydPJ10gfSk7DQogICAgY2VydC5zZXRTdWJqZWN0KGF0dHJzKTsNCg0KICAgIGlmIChjYVByaXZhdGVLZXkpIHsNCiAgICAgICAgLy8gVXNlIHJvb3QgYXR0cmlidXRlcw0KICAgICAgICB2YXIgcm9vdGF0dHJzID0gW107DQogICAgICAgIGlmIChpc3N1ZXJBdHRyaWJ1dGVzWydDTiddKSByb290YXR0cnMucHVzaCh7IG5hbWU6ICdjb21tb25OYW1lJywgdmFsdWU6IGlzc3VlckF0dHJpYnV0ZXNbJ0NOJ10gfSk7DQogICAgICAgIGlmIChpc3N1ZXJBdHRyaWJ1dGVzWydDJ10pIHJvb3RhdHRycy5wdXNoKHsgbmFtZTogJ2NvdW50cnlOYW1lJywgdmFsdWU6IGlzc3VlckF0dHJpYnV0ZXNbJ0MnXSB9KTsNCiAgICAgICAgaWYgKGlzc3VlckF0dHJpYnV0ZXNbJ1NUJ10pIHJvb3RhdHRycy5wdXNoKHsgc2hvcnROYW1lOiAnU1QnLCB2YWx1ZTogaXNzdWVyQXR0cmlidXRlc1snU1QnXSB9KTsNCiAgICAgICAgaWYgKGlzc3VlckF0dHJpYnV0ZXNbJ08nXSkgcm9vdGF0dHJzLnB1c2goeyBuYW1lOiAnb3JnYW5pemF0aW9uTmFtZScsIHZhbHVlOiBpc3N1ZXJBdHRyaWJ1dGVzWydPJ10gfSk7DQogICAgICAgIGNlcnQuc2V0SXNzdWVyKHJvb3RhdHRycyk7DQogICAgfSBlbHNlIHsNCiAgICAgICAgLy8gVXNlIG91ciBvd24gYXR0cmlidXRlcw0KICAgICAgICBjZXJ0LnNldElzc3VlcihhdHRycyk7DQogICAgfQ0KDQogICAgaWYgKGNhUHJpdmF0ZUtleSA9PSB1bmRlZmluZWQpIHsNCiAgICAgICAgLy8gQ3JlYXRlIGEgcm9vdCBjZXJ0aWZpY2F0ZQ0KICAgICAgICBjZXJ0LnNldEV4dGVuc2lvbnMoW3sNCiAgICAgICAgICAgIG5hbWU6ICdiYXNpY0NvbnN0cmFpbnRzJywNCiAgICAgICAgICAgIGNBOiB0cnVlDQogICAgICAgIH0sIHsNCiAgICAgICAgICAgIG5hbWU6ICduc0NlcnRUeXBlJywNCiAgICAgICAgICAgIHNzbENBOiB0cnVlLA0KICAgICAgICAgICAgZW1haWxDQTogdHJ1ZSwNCiAgICAgICAgICAgIG9iakNBOiB0cnVlDQogICAgICAgIH0sIHsNCiAgICAgICAgICAgIG5hbWU6ICdzdWJqZWN0S2V5SWRlbnRpZmllcicNCiAgICAgICAgfV0pOw0KICAgIH0gZWxzZSB7DQogICAgICAgIGlmIChleHRLZXlVc2FnZSA9PSBudWxsKSB7IGV4dEtleVVzYWdlID0geyBuYW1lOiAnZXh0S2V5VXNhZ2UnLCBzZXJ2ZXJBdXRoOiB0cnVlLCB9IH0gZWxzZSB7IGV4dEtleVVzYWdlLm5hbWUgPSAnZXh0S2V5VXNhZ2UnOyB9DQoNCiAgICAgICAgLyoNCiAgICAgICAgew0KICAgICAgICAgICAgbmFtZTogJ2V4dEtleVVzYWdlJywNCiAgICAgICAgICAgIHNlcnZlckF1dGg6IHRydWUsDQogICAgICAgICAgICBjbGllbnRBdXRoOiB0cnVlLA0KICAgICAgICAgICAgY29kZVNpZ25pbmc6IHRydWUsDQogICAgICAgICAgICBlbWFpbFByb3RlY3Rpb246IHRydWUsDQogICAgICAgICAgICB0aW1lU3RhbXBpbmc6IHRydWUsDQogICAgICAgICAgICAnMi4xNi44NDAuMS4xMTM3NDEuMS4yLjEnOiB0cnVlDQogICAgICAgIH0NCiAgICAgICAgKi8NCg0KICAgICAgICAvLyBDcmVhdGUgYSBsZWFmIGNlcnRpZmljYXRlDQogICAgICAgIGNlcnQuc2V0RXh0ZW5zaW9ucyhbew0KICAgICAgICAgICAgbmFtZTogJ2Jhc2ljQ29uc3RyYWludHMnDQogICAgICAgIH0sIHsNCiAgICAgICAgICAgIG5hbWU6ICdrZXlVc2FnZScsDQogICAgICAgICAgICBrZXlDZXJ0U2lnbjogdHJ1ZSwNCiAgICAgICAgICAgIGRpZ2l0YWxTaWduYXR1cmU6IHRydWUsDQogICAgICAgICAgICBub25SZXB1ZGlhdGlvbjogdHJ1ZSwNCiAgICAgICAgICAgIGtleUVuY2lwaGVybWVudDogdHJ1ZSwNCiAgICAgICAgICAgIGRhdGFFbmNpcGhlcm1lbnQ6IHRydWUNCiAgICAgICAgfSwgZXh0S2V5VXNhZ2UsIHsNCiAgICAgICAgICAgIG5hbWU6ICduc0NlcnRUeXBlJywNCiAgICAgICAgICAgIGNsaWVudDogdHJ1ZSwNCiAgICAgICAgICAgIHNlcnZlcjogdHJ1ZSwNCiAgICAgICAgICAgIGVtYWlsOiB0cnVlLA0KICAgICAgICAgICAgb2Jqc2lnbjogdHJ1ZSwNCiAgICAgICAgfSwgew0KICAgICAgICAgICAgbmFtZTogJ3N1YmplY3RLZXlJZGVudGlmaWVyJw0KICAgICAgICB9XSk7DQogICAgfQ0KDQogICAgLy8gU2VsZi1zaWduIGNlcnRpZmljYXRlDQogICAgaWYgKGNhUHJpdmF0ZUtleSkgew0KICAgICAgICBjZXJ0LnNpZ24oY2FQcml2YXRlS2V5LCBmb3JnZS5tZC5zaGEyNTYuY3JlYXRlKCkpOw0KICAgIH0gZWxzZSB7DQogICAgICAgIGNlcnQuc2lnbihrZXlzLnByaXZhdGVLZXksIGZvcmdlLm1kLnNoYTI1Ni5jcmVhdGUoKSk7DQogICAgfQ0KDQogICAgaWYgKERFUktleSkgew0KICAgICAgICByZXR1cm4gY2VydDsNCiAgICB9IGVsc2Ugew0KICAgICAgICByZXR1cm4geyAnY2VydCc6IGNlcnQsICdrZXknOiBrZXlzLnByaXZhdGVLZXkgfTsNCiAgICB9DQp9DQoNCmZ1bmN0aW9uIF9zdHJpbmdUb0FycmF5QnVmZmVyKHN0cikgew0KICAgIHZhciBidWYgPSBuZXcgQXJyYXlCdWZmZXIoc3RyLmxlbmd0aCk7DQogICAgdmFyIGJ1ZlZpZXcgPSBuZXcgVWludDhBcnJheShidWYpOw0KICAgIGZvciAodmFyIGkgPSAwLCBzdHJMZW4gPSBzdHIubGVuZ3RoOyBpIDwgc3RyTGVuOyBpKyspIHsgYnVmVmlld1tpXSA9IHN0ci5jaGFyQ29kZUF0KGkpOyB9DQogICAgcmV0dXJuIGJ1ZjsNCn0NCg0KZnVuY3Rpb24gX2FycmF5QnVmZmVyVG9TdHJpbmcoYnVmZmVyKSB7DQogICAgdmFyIGJpbmFyeSA9ICcnOw0KICAgIHZhciBieXRlcyA9IG5ldyBVaW50OEFycmF5KGJ1ZmZlcik7DQogICAgdmFyIGxlbiA9IGJ5dGVzLmJ5dGVMZW5ndGg7DQogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykgeyBiaW5hcnkgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShieXRlc1tpXSk7IH0NCiAgICByZXR1cm4gYmluYXJ5Ow0KfQ0KLyoqDQoqIEBmaWxlb3ZlcnZpZXcgU2NyaXB0IENvbXBpbGVyIC8gRGVjb21waWxlciAvIFJ1bm5lcg0KKiBAYXV0aG9yIFlsaWFuIFNhaW50LUhpbGFpcmUNCiogQHZlcnNpb24gdjAuMS4wZQ0KKi8NCg0KLy8gQ29yZSBmdW5jdGlvbnMNCnNjcmlwdF9mdW5jdGlvblRhYmxlMSA9IFsnbm9wJywgJ2p1bXAnLCAnc2V0JywgJ3ByaW50JywgJ2RpYWxvZycsICdnZXRpdGVtJywgJ3N1YnN0cicsICdpbmRleG9mJywgJ3NwbGl0JywgJ2pvaW4nLCAnbGVuZ3RoJywgJ2pzb25wYXJzZScsICdqc29uc3RyJywgJ2FkZCcsICdzdWJzdHJhY3QnLCAncGFyc2VpbnQnLCAnd3NiYXRjaGVudW0nLCAnd3NwdXQnLCAnd3NjcmVhdGUnLCAnd3NkZWxldGUnLCAnd3NleGVjJywgJ3NjcmlwdHNwZWVkJywgJ3dzc3Vic2NyaWJlJywgJ3dzdW5zdWJzY3JpYmUnLCAncmVhZGNoYXInLCAnc2lnbndpdGhkdW1teWNhJ107DQoNCi8vIGZ1bmN0aW9ucyBvZiB0eXBlIEFSRzEgPSBmdW5jKEFSRzIsIEFSRzMsIEFSRzQsIEFSRzUsIEFSRzYpDQpzY3JpcHRfZnVuY3Rpb25UYWJsZTIgPSBbJ2VuY29kZXVyaScsICdkZWNvZGV1cmknLCAncGFzc3dvcmRjaGVjaycsICdhdG9iJywgJ2J0b2EnLCAnaGV4MnN0cicsICdzdHIyaGV4JywgJ3JhbmRvbScsICdtZDUnLCAnbWFrZXRvYXJyYXknLCAncmVhZHNob3J0JywgJ3JlYWRzaG9ydHgnLCAncmVhZGludCcsICdyZWFkc2ludCcsICdyZWFkaW50eCcsICdzaG9ydHRvc3RyJywgJ3Nob3J0dG9zdHJ4JywgJ2ludHRvc3RyJywgJ2ludHRvc3RyeCddOw0KDQovLyBmdW5jdGlvbnMgb2YgdHlwZSBBUkcxID0gZnVuYyhBUkcyLCBBUkczLCBBUkc0LCBBUkc1LCBBUkc2KQ0Kc2NyaXB0X2Z1bmN0aW9uVGFibGVYMiA9IFtlbmNvZGVVUkksIGRlY29kZVVSSSwgcGFzc3dvcmRjaGVjaywgd2luZG93LmF0b2IuYmluZCh3aW5kb3cpLCB3aW5kb3cuYnRvYS5iaW5kKHdpbmRvdyksIGhleDJyc3RyLCByc3RyMmhleCwgcmFuZG9tLCByc3RyX21kNSwgTWFrZVRvQXJyYXksIFJlYWRTaG9ydCwgUmVhZFNob3J0WCwgUmVhZEludCwgUmVhZFNJbnQsIFJlYWRJbnRYLCBTaG9ydFRvU3RyLCBTaG9ydFRvU3RyWCwgSW50VG9TdHIsIEludFRvU3RyWF07DQoNCi8vIE9wdGlvbmFsIGZ1bmN0aW9ucyBvZiB0eXBlIEFSRzEgPSBmdW5jKEFSRzIsIEFSRzMsIEFSRzQsIEFSRzUsIEFSRzYpDQpzY3JpcHRfZnVuY3Rpb25UYWJsZTMgPSBbJ3B1bGxzeXN0ZW1zdGF0dXMnLCAncHVsbGV2ZW50bG9nJywgJ3B1bGxhdWRpdGxvZycsICdwdWxsY2VydGlmaWNhdGVzJywgJ3B1bGx3YXRjaGRvZycsICdwdWxsc3lzdGVtZGVmZW5zZScsICdwdWxsaGFyZHdhcmUnLCAncHVsbHVzZXJpbmZvJywgJ3B1bGxyZW1vdGVhY2Nlc3MnLCAnaGlnaGxpZ2h0YmxvY2snLCAnZGlzY29ubmVjdCcsICdnZXRzaWRzdHJpbmcnLCAnZ2V0c2lkYnl0ZWFycmF5JywgJ3B1bGxldmVudHN1YnNjcmlwdGlvbnMnXTsNCg0KLy8gT3B0aW9uYWwgZnVuY3Rpb25zIG9mIHR5cGUgQVJHMSA9IGZ1bmMoQVJHMiwgQVJHMywgQVJHNCwgQVJHNSwgQVJHNikNCnNjcmlwdF9mdW5jdGlvblRhYmxlWDMgPSBbDQogICAgUHVsbFN5c3RlbVN0YXR1cw0KICAgICwNCiAgICANCiAgICBQdWxsRXZlbnRMb2cNCiAgICAgICAgLA0KICAgIA0KICAgIFB1bGxBdWRpdExvZw0KICAgICAgICAsDQogICAgDQogICAgUHVsbENlcnRpZmljYXRlcw0KICAgICAgICAsDQogICAgDQogICAgUHVsbFdhdGNoZG9nDQogICAgICAgICwNCiAgICANCiAgICBQdWxsU3lzdGVtRGVmZW5zZQ0KICAgICAgICAsDQogICAgDQogICAgUHVsbEhhcmR3YXJlDQogICAgICAgICwNCiAgICBQdWxsVXNlckluZm8NCiAgICAsDQogICAgDQogICAgUHVsbFJlbW90ZUFjY2Vzcw0KICAgICAgICAsDQogICAgDQogICAgc2NyaXB0X0hpZ2hsaWdodEJsb2NrDQogICAgICAgICwNCiAgICAgICAgLA0KICAgIGZ1bmN0aW9uIChydW5uZXIsIHgpIHsgcmV0dXJuIEdldFNpZFN0cmluZyh4KTsgfQ0KICAgICwNCiAgICBmdW5jdGlvbiAocnVubmVyLCB4KSB7IHJldHVybiBHZXRTaWRCeXRlQXJyYXkoeCk7IH0NCiAgICAsDQogICAgXTsNCg0KLy8gU2V0dXAgdGhlIHNjcmlwdCBzdGF0ZQ0KZnVuY3Rpb24gc2NyaXB0X3NldHVwKGJpbmFyeSwgc3RhcnR2YXJzKSB7DQogICAgdmFyIG9iaiA9IHsgc3RhcnR2YXJzOnN0YXJ0dmFycyB9Ow0KICAgIGlmIChiaW5hcnkubGVuZ3RoIDwgNikgeyBjb25zb2xlLmVycm9yKCdJbnZhbGlkIHNjcmlwdCBsZW5ndGgnKTsgcmV0dXJuIG51bGw7IH0gLy8gU2NyaXB0IG11c3QgaGF2ZSBhdCBsZWFzdCA2IGJ5dGUgaGVhZGVyDQogICAgaWYgKFJlYWRJbnQoYmluYXJ5LCAwKSAhPSAweDI0N0QyOTQ1KSB7IGNvbnNvbGUuZXJyb3IoJ0ludmFsaWQgYmluYXJ5IHNjcmlwdCcpOyByZXR1cm4gbnVsbDsgfSAvLyBDaGVjayB0aGUgc2NyaXB0IG1hZ2ljIGhlYWRlcg0KICAgIGlmIChSZWFkU2hvcnQoYmluYXJ5LCA0KSA+IDEpIHsgY29uc29sZS5lcnJvcignVW5zdXBwb3J0ZWQgc2NyaXB0IHZlcnNpb24nKTsgcmV0dXJuIG51bGw7IH0gLy8gQ2hlY2sgdGhlIHNjcmlwdCB2ZXJzaW9uDQogICAgb2JqLnNjcmlwdCA9IGJpbmFyeS5zdWJzdHJpbmcoNik7DQogICAgLy8gb2JqLm9uU3RlcDsNCiAgICAvLyBvYmoub25Db25zb2xlOw0KDQogICAgLy8gUmVzZXQgdGhlIHNjcmlwdCB0byB0aGUgc3RhcnQNCiAgICBvYmoucmVzZXQgPSBmdW5jdGlvbiAoc3RlcHNwZWVkKSB7DQogICAgICAgIG9iai5zdG9wKCk7DQogICAgICAgIG9iai5pcCA9IDA7DQogICAgICAgIG9iai52YXJpYWJsZXMgPSBzdGFydHZhcnM7DQogICAgICAgIG9iai5zdGF0ZSA9IDE7DQogICAgfQ0KDQogICAgLy8gU3RhcnQgdGhlIHNjcmlwdA0KICAgIG9iai5zdGFydCA9IGZ1bmN0aW9uIChzdGVwc3BlZWQpIHsNCiAgICAgICAgb2JqLnN0b3AoKTsNCiAgICAgICAgb2JqLnN0ZXBzcGVlZCA9IHN0ZXBzcGVlZDsNCiAgICAgICAgaWYgKHN0ZXBzcGVlZCA+IDApIHsgb2JqLnRpbWVyID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkgeyBvYmouc3RlcCgpIH0sIHN0ZXBzcGVlZCk7IH0NCiAgICB9DQoNCiAgICAvLyBTdG9wIHRoZSBzY3JpcHQNCiAgICBvYmouc3RvcCA9IGZ1bmN0aW9uICgpIHsNCiAgICAgICAgaWYgKG9iai50aW1lciAhPSBudWxsKSB7IGNsZWFySW50ZXJ2YWwob2JqLnRpbWVyKTsgfQ0KICAgICAgICBvYmoudGltZXIgPSBudWxsOw0KICAgICAgICBvYmouc3RlcHNwZWVkID0gMDsNCiAgICB9DQoNCiAgICAvLyBmdW5jdGlvbiB1c2VkIHRvIGxvYWQgYW5kIHN0b3JlIHZhcmlhYmxlIHZhbHVlcw0KICAgIG9iai5nZXRWYXIgPSBmdW5jdGlvbiAobmFtZSkgeyBpZiAobmFtZSA9PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7IHJldHVybiBvYmouZ2V0VmFyRXgobmFtZS5zcGxpdCgnLicpLCBvYmoudmFyaWFibGVzKTsgfQ0KICAgIG9iai5nZXRWYXJFeCA9IGZ1bmN0aW9uIChuYW1lLCB2YWwpIHsgdHJ5IHsgaWYgKG5hbWUgPT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkOyBpZiAobmFtZS5sZW5ndGggPT0gMCkgcmV0dXJuIHZhbDsgcmV0dXJuIG9iai5nZXRWYXJFeChuYW1lLnNsaWNlKDEpLCB2YWxbbmFtZVswXV0pOyB9IGNhdGNoIChlKSB7IHJldHVybiBudWxsOyB9IH0NCiAgICBvYmouc2V0VmFyID0gZnVuY3Rpb24gKG5hbWUsIHZhbCkgeyBvYmouc2V0VmFyRXgobmFtZS5zcGxpdCgnLicpLCBvYmoudmFyaWFibGVzLCB2YWwpOyB9DQogICAgb2JqLnNldFZhckV4ID0gZnVuY3Rpb24gKG5hbWUsIHZhcnMsIHZhbCkgeyBpZiAobmFtZS5sZW5ndGggPT0gMSkgeyB2YXJzW25hbWVbMF1dID0gdmFsOyB9IGVsc2UgeyBvYmouc2V0VmFyRXgobmFtZS5zbGljZSgxKSwgdmFyc1tuYW1lWzBdXSwgdmFsKTsgfSB9DQoNCiAgICAvLyBSdW4gdGhlIHNjcmlwdCBvbmUgc3RlcCBmb3J3YXJkDQogICAgb2JqLnN0ZXAgPSBmdW5jdGlvbiAoKSB7DQogICAgICAgIGlmIChvYmouc3RhdGUgIT0gMSkgcmV0dXJuOw0KICAgICAgICBpZiAob2JqLmlwIDwgb2JqLnNjcmlwdC5sZW5ndGgpIHsNCiAgICAgICAgICAgIHZhciBjbWRpZCA9IFJlYWRTaG9ydChvYmouc2NyaXB0LCBvYmouaXApOw0KICAgICAgICAgICAgdmFyIGNtZGxlbiA9IFJlYWRTaG9ydChvYmouc2NyaXB0LCBvYmouaXAgKyAyKTsNCiAgICAgICAgICAgIHZhciBhcmdjb3VudCA9IFJlYWRTaG9ydChvYmouc2NyaXB0LCBvYmouaXAgKyA0KTsNCiAgICAgICAgICAgIHZhciBhcmdwdHIgPSBvYmouaXAgKyA2Ow0KICAgICAgICAgICAgdmFyIGFyZ3MgPSBbXTsNCg0KICAgICAgICAgICAgLy8gQ2xlYXIgYWxsIHRlbXAgdmFyaWFibGVzIChUaGlzIGlzIG9wdGlvbmFsKQ0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBvYmoudmFyaWFibGVzKSB7IGlmIChpLnN0YXJ0c1dpdGgoJ19fJykpIHsgZGVsZXRlIG9iai52YXJpYWJsZXNbaV07IH0gfQ0KDQogICAgICAgICAgICAvLyBMb29wIG9uIGVhY2ggYXJndW1lbnQsIG1vdmluZyBmb3J3YXJkIGJ5IHRoZSBhcmd1bWVudCBsZW5ndGggZWFjaCB0aW1lDQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ2NvdW50OyBpKyspIHsNCiAgICAgICAgICAgICAgICB2YXIgYXJnbGVuID0gUmVhZFNob3J0KG9iai5zY3JpcHQsIGFyZ3B0cik7DQogICAgICAgICAgICAgICAgdmFyIGFyZ3ZhbCA9IG9iai5zY3JpcHQuc3Vic3RyaW5nKGFyZ3B0ciArIDIsIGFyZ3B0ciArIDIgKyBhcmdsZW4pOw0KICAgICAgICAgICAgICAgIHZhciBhcmd0eXAgPSBhcmd2YWwuY2hhckNvZGVBdCgwKTsNCiAgICAgICAgICAgICAgICBhcmd2YWwgPSBhcmd2YWwuc3Vic3RyaW5nKDEpOw0KICAgICAgICAgICAgICAgIGlmIChhcmd0eXAgPCAyKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgdmFsdWUgYW5kIHJlcGxhY2UgYWxsIHt2YXJ9IHdpdGggdmFyaWFibGUgdmFsdWVzDQogICAgICAgICAgICAgICAgICAgIHdoaWxlIChhcmd2YWwuc3BsaXQoInsiKS5sZW5ndGggPiAxKSB7IHZhciB0ID0gYXJndmFsLnNwbGl0KCJ7IikucG9wKCkuc3BsaXQoIn0iKS5zaGlmdCgpOyBhcmd2YWwgPSBhcmd2YWwucmVwbGFjZSgneycgKyB0ICsgJ30nLCBvYmouZ2V0VmFyKHQpKTsgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoYXJndHlwID09IDEpIHsgb2JqLnZhcmlhYmxlc1snX18nICsgaV0gPSBkZWNvZGVVUkkoYXJndmFsKTsgYXJndmFsID0gJ19fJyArIGk7IH0gLy8gSWYgYXJndHlwIGlzIDEsIHRoaXMgaXMgYSBsaXRlcmFsLiBTdG9yZSBpbiB0ZW1wIHZhcmlhYmxlLg0KICAgICAgICAgICAgICAgICAgICBhcmdzLnB1c2goYXJndmFsKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKGFyZ3R5cCA9PSAyIHx8IGFyZ3R5cCA9PSAzKSB7DQogICAgICAgICAgICAgICAgICAgIG9iai52YXJpYWJsZXNbJ19fJyArIGldID0gUmVhZFNJbnQoYXJndmFsLCAwKTsNCiAgICAgICAgICAgICAgICAgICAgYXJncy5wdXNoKCdfXycgKyBpKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgYXJncHRyICs9ICgyICsgYXJnbGVuKTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gTW92ZSBpbnN0cnVjdGlvbiBwb2ludGVyIGZvcndhcmQgYnkgY29tbWFuZCBzaXplDQogICAgICAgICAgICBvYmouaXAgKz0gY21kbGVuOw0KDQogICAgICAgICAgICAvLyBHZXQgYWxsIHZhcmlhYmxlIHZhbHVlcw0KICAgICAgICAgICAgdmFyIGFyZ3N2YWwgPSBbXTsNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTA7IGkrKykgeyBhcmdzdmFsLnB1c2gob2JqLmdldFZhcihhcmdzW2ldKSk7IH0NCiAgICAgICAgICAgIHZhciBzdG9yZUluQXJnMDsNCg0KICAgICAgICAgICAgdHJ5IHsNCiAgICAgICAgICAgICAgICBpZiAoY21kaWQgPCAxMDAwMCkgew0KICAgICAgICAgICAgICAgICAgICAvLyBMZXRzIHJ1biB0aGUgYWN0dWFsIGNvbW1hbmQNCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjbWRpZCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAwOiAvLyBub3ANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTogLy8ganVtcChsYWJlbCkgb3IganVtcChsYWJlbCwgYSwgY29tcGFyZSwgYikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXJnc3ZhbFsyXSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXJnc3ZhbFsyXSA9PSAnPCcgJiYgYXJnc3ZhbFsxXSA8IGFyZ3N2YWxbM10pIHx8DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYXJnc3ZhbFsyXSA9PSAnPD0nICYmIGFyZ3N2YWxbMV0gPD0gYXJnc3ZhbFszXSkgfHwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcmdzdmFsWzJdID09ICchPScgJiYgYXJnc3ZhbFsxXSAhPSBhcmdzdmFsWzNdKSB8fA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFyZ3N2YWxbMl0gPT0gJz0nICYmIGFyZ3N2YWxbMV0gPT0gYXJnc3ZhbFszXSkgfHwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhcmdzdmFsWzJdID09ICc+PScgJiYgYXJnc3ZhbFsxXSA+PSBhcmdzdmFsWzNdKSB8fA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGFyZ3N2YWxbMl0gPT0gJz4nICYmIGFyZ3N2YWxbMV0gPiBhcmdzdmFsWzNdKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHsgb2JqLmlwID0gYXJnc3ZhbFswXTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5pcCA9IGFyZ3N2YWxbMF07IC8vIFNldCB0aGUgaW5zdHJ1Y3Rpb24gcG9pbnRlciB0byB0aGUgbmV3IGxvY2F0aW9uIGluIHRoZSBzY3JpcHQNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IC8vIHNldCh2YXJpYWJsZSwgdmFsdWUpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3NbMV0gPT0gdW5kZWZpbmVkKSBkZWxldGUgb2JqLnZhcmlhYmxlc1thcmdzWzBdXTsgZWxzZSBvYmouc2V0VmFyKGFyZ3NbMF0sIGFyZ3N2YWxbMV0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzOiAvLyBwcmludChtZXNzYWdlKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvYmoub25Db25zb2xlKSB7IG9iai5vbkNvbnNvbGUob2JqLnRvU3RyaW5nKGFyZ3N2YWxbMF0pLCBvYmopOyB9IGVsc2UgeyBjb25zb2xlLmxvZyhvYmoudG9TdHJpbmcoYXJnc3ZhbFswXSkpOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gIFEob2JqLmNvbnNvbGVpZCkudmFsdWUgKz0gKCkgKyAnXG4nKTsgUShvYmouY29uc29sZSkuc2Nyb2xsVG9wID0gUShvYmouY29uc29sZSkuc2Nyb2xsSGVpZ2h0Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiAvLyBkaWFsb2codGl0bGUsIGNvbnRlbnQsIGJ1dHRvbnMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouZGlhbG9nID0gdHJ1ZTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCBhcmdzdmFsWzBdLCBhcmdzdmFsWzJdLCBvYmoueHhTdGVwRGlhbG9nT2ssIGFyZ3N2YWxbMV0sIG9iaik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDU6IC8vIGdldGl0ZW0oYSwgYiwgYykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIGFyZ3N2YWxbMV0pIHsgaWYgKGFyZ3N2YWxbMV1baV1bYXJnc3ZhbFsyXV0gPT0gYXJnc3ZhbFszXSkgeyBzdG9yZUluQXJnMCA9IGk7IH0gfTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNjogLy8gc3Vic3RyKHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYywgaW5kZXgsIGxlbikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IGFyZ3N2YWxbMV0uc3Vic3RyKGFyZ3N2YWxbMl0sIGFyZ3N2YWxbM10pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA3OiAvLyBpbmRleE9mKHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYywgaW5kZXgsIGxlbikNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IGFyZ3N2YWxbMV0uaW5kZXhPZihhcmdzdmFsWzJdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgODogLy8gc3BsaXQodmFyaWFibGVfZGVzdCwgdmFyaWFibGVfc3JjLCBzZXBhcmF0b3IpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVJbkFyZzAgPSBhcmdzdmFsWzFdLnNwbGl0KGFyZ3N2YWxbMl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA5OiAvLyBqb2luKHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYywgc2VwYXJhdG9yKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlSW5BcmcwID0gYXJnc3ZhbFsxXS5qb2luKGFyZ3N2YWxbMl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMDogLy8gbGVuZ3RoKHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IGFyZ3N2YWxbMV0ubGVuZ3RoOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMTogLy8ganNvbnBhcnNlKHZhcmlhYmxlX2Rlc3QsIGpzb24pDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVJbkFyZzAgPSBKU09OLnBhcnNlKGFyZ3N2YWxbMV0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMjogLy8ganNvbnN0cih2YXJpYWJsZV9kZXN0LCB2YXJpYWJsZV9zcmMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVJbkFyZzAgPSBKU09OLnN0cmluZ2lmeShhcmdzdmFsWzFdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTM6IC8vIGFkZCh2YXJpYWJsZV9kZXN0LCB2YXJpYWJsZV9zcmMsIHZhbHVlKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlSW5BcmcwID0gKGFyZ3N2YWxbMV0gKyBhcmdzdmFsWzJdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTQ6IC8vIHN1YnN0cmFjdCh2YXJpYWJsZV9kZXN0LCB2YXJpYWJsZV9zcmMsIHZhbHVlKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlSW5BcmcwID0gKGFyZ3N2YWxbMV0gLSBhcmdzdmFsWzJdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTU6IC8vIHBhcnNlSW50KHZhcmlhYmxlX2Rlc3QsIHZhcmlhYmxlX3NyYykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IHBhcnNlSW50KGFyZ3N2YWxbMV0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxNjogLy8gd3NiYXRjaGVudW0obmFtZSwgb2JqZWN0TGlzdCkNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouc3RhdGUgPSAyOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5hbXRzdGFjay5CYXRjaEVudW0oYXJnc3ZhbFswXSwgYXJnc3ZhbFsxXSwgb2JqLnh4V3NtYW5SZXR1cm4sIG9iaik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDE3OiAvLyB3c3B1dChuYW1lLCBhcmdzKQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5zdGF0ZSA9IDI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLmFtdHN0YWNrLlB1dChhcmdzdmFsWzBdLCBhcmdzdmFsWzFdLCBvYmoueHhXc21hblJldHVybiwgb2JqKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTg6IC8vIHdzY3JlYXRlKG5hbWUsIGFyZ3MpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouYW10c3RhY2suQ3JlYXRlKGFyZ3N2YWxbMF0sIGFyZ3N2YWxbMV0sIG9iai54eFdzbWFuUmV0dXJuLCBvYmopOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOTogLy8gd3NkZWxldGUobmFtZSwgYXJncykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouc3RhdGUgPSAyOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5hbXRzdGFjay5EZWxldGUoYXJnc3ZhbFswXSwgYXJnc3ZhbFsxXSwgb2JqLnh4V3NtYW5SZXR1cm4sIG9iaik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDIwOiAvLyB3c2V4ZWMobmFtZSwgbWV0aG9kLCBhcmdzLCBzZWxlY3RvcnMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouYW10c3RhY2suRXhlYyhhcmdzdmFsWzBdLCBhcmdzdmFsWzFdLCBhcmdzdmFsWzJdLCBvYmoueHhXc21hblJldHVybiwgb2JqLCAwLCBhcmdzdmFsWzNdKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMjE6IC8vIFNjcmlwdCBTcGVlZA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iai5zdGVwc3BlZWQgPSBhcmdzdmFsWzBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvYmoudGltZXIgIT0gbnVsbCkgeyBjbGVhckludGVydmFsKG9iai50aW1lcik7IG9iai50aW1lciA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHsgb2JqLnN0ZXAoKSB9LCBvYmouc3RlcHNwZWVkKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMjogLy8gd3NzdWJzY3JpYmUobmFtZSwgZGVsaXZlcnksIHVybCwgc2VsZWN0b3JzLCBvcGFxdWUsIHVzZXIsIHBhc3MpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouYW10c3RhY2suU3Vic2NyaWJlKGFyZ3N2YWxbMF0sIGFyZ3N2YWxbMV0sIGFyZ3N2YWxbMl0sIG9iai54eFdzbWFuUmV0dXJuLCBvYmosIDAsIGFyZ3N2YWxbM10sIGFyZ3N2YWxbNF0sIGFyZ3N2YWxbNV0sIGFyZ3N2YWxbNl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyMzogLy8gd3N1bnN1YnNjcmliZShuYW1lLCBzZWxlY3RvcnMpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmouYW10c3RhY2suVW5TdWJzY3JpYmUoYXJnc3ZhbFswXSwgb2JqLnh4V3NtYW5SZXR1cm4sIG9iaiwgMCwgYXJnc3ZhbFsxXSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI0OiAvLyByZWFkY2hhcihzdHIsIHBvcykNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhhcmdzdmFsWzFdLCBhcmdzdmFsWzJdLCBhcmdzdmFsWzFdLmNoYXJDb2RlQXQoYXJnc3ZhbFsyXSkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3JlSW5BcmcwID0gYXJnc3ZhbFsxXS5jaGFyQ29kZUF0KGFyZ3N2YWxbMl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOw0KICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyNTogLy8gc2lnbldpdGhEdW1teUNhDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gMjsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBERVJLZXksIHh4Q2FQcml2YXRlS2V5LCBjZXJ0YXR0cmlidXRlcywgaXNzdWVyYXR0cmlidXRlcw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFtdGNlcnRfc2lnbldpdGhDYUtleShhcmdzdmFsWzBdLCBudWxsLCBhcmdzdmFsWzFdLCB7ICdDTic6ICdVbnRydXN0ZWQgUm9vdCBDZXJ0aWZpY2F0ZScgfSwgb2JqLnh4U2lnbldpdGhEdW1teUNhUmV0dXJuKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OiB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqLnN0YXRlID0gOTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCJTY3JpcHQgRXJyb3IsIHVua25vd24gY29tbWFuZDogIiArIGNtZGlkKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChjbWRpZCA8IDIwMDAwKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAvLyBmdW5jdGlvbnMgb2YgdHlwZSBBUkcxID0gZnVuYyhBUkcyLCBBUkczLCBBUkc0LCBBUkc1LCBBUkc2KQ0KICAgICAgICAgICAgICAgICAgICAgICAgc3RvcmVJbkFyZzAgPSBzY3JpcHRfZnVuY3Rpb25UYWJsZVgyW2NtZGlkIC0gMTAwMDBdKGFyZ3N2YWxbMV0sIGFyZ3N2YWxbMl0sIGFyZ3N2YWxbM10sIGFyZ3N2YWxbNF0sIGFyZ3N2YWxbNV0sIGFyZ3N2YWxbNl0pOw0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gT3B0aW9uYWwgZnVuY3Rpb25zIG9mIHR5cGUgQVJHMSA9IGZ1bmMoQVJHMiwgQVJHMywgQVJHNCwgQVJHNSwgQVJHNikNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzY3JpcHRfZnVuY3Rpb25UYWJsZVgzICYmIHNjcmlwdF9mdW5jdGlvblRhYmxlWDNbY21kaWQgLSAyMDAwMF0pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZUluQXJnMCA9IHNjcmlwdF9mdW5jdGlvblRhYmxlWDNbY21kaWQgLSAyMDAwMF0ob2JqLCBhcmdzdmFsWzFdLCBhcmdzdmFsWzJdLCBhcmdzdmFsWzNdLCBhcmdzdmFsWzRdLCBhcmdzdmFsWzVdLCBhcmdzdmFsWzZdKTsgLy8gTm90ZSB0aGF0IG9wdGlvbmFsIGNhbGxzIHN0YXJ0IHdpdGggIm9iaiIgYXMgZmlyc3QgYXJndW1lbnQuDQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBpZiAoc3RvcmVJbkFyZzAgIT0gdW5kZWZpbmVkKSBvYmouc2V0VmFyKGFyZ3NbMF0sIHN0b3JlSW5BcmcwKTsNCiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsNCiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGUgPT0gJ29iamVjdCcpIHsgZSA9IGUubWVzc2FnZTsgfQ0KICAgICAgICAgICAgICAgIG9iai5zZXRWYXIoJ19leGNlcHRpb24nLCBlKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGlmIChvYmouc3RhdGUgPT0gMSAmJiBvYmouaXAgPj0gb2JqLnNjcmlwdC5sZW5ndGgpIHsgb2JqLnN0YXRlID0gMDsgb2JqLnN0b3AoKTsgfQ0KICAgICAgICBpZiAob2JqLm9uU3RlcCkgb2JqLm9uU3RlcChvYmopOw0KICAgICAgICByZXR1cm4gb2JqOw0KICAgIH0NCg0KICAgIG9iai54eFN0ZXBEaWFsb2dPayA9IGZ1bmN0aW9uIChidXR0b24pIHsNCiAgICAgICAgb2JqLnZhcmlhYmxlc1snRGlhbG9nU2VsZWN0J10gPSBidXR0b247DQogICAgICAgIG9iai5zdGF0ZSA9IDE7DQogICAgICAgIG9iai5kaWFsb2cgPSBmYWxzZTsNCiAgICAgICAgaWYgKG9iai5vblN0ZXApIG9iai5vblN0ZXAob2JqKTsNCiAgICB9DQoNCiAgICANCiAgICBvYmoueHhXc21hblJldHVybiA9IGZ1bmN0aW9uIChzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICBvYmouc2V0VmFyKG5hbWUsIHJlc3BvbnNlcyk7DQogICAgICAgIG9iai5zZXRWYXIoJ3dzbWFuX3Jlc3VsdCcsIHN0YXR1cyk7DQogICAgICAgIG9iai5zZXRWYXIoJ3dzbWFuX3Jlc3VsdF9zdHInLCAoKGh0dHBFcnJvclRhYmxlW3N0YXR1c10pID8gKGh0dHBFcnJvclRhYmxlW3N0YXR1c10pIDogKCdFcnJvciAjJyArIHN0YXR1cykpKTsNCiAgICAgICAgb2JqLnN0YXRlID0gMTsNCiAgICAgICAgaWYgKG9iai5vblN0ZXApIG9iai5vblN0ZXAob2JqKTsNCiAgICB9DQoNCiAgICANCiAgICBvYmoueHhTaWduV2l0aER1bW15Q2FSZXR1cm4gPSBmdW5jdGlvbiAoY2VydCkgew0KICAgICAgICBvYmouc2V0VmFyKCdzaWduZWRfY2VydCcsIGJ0b2EoX2FycmF5QnVmZmVyVG9TdHJpbmcoY2VydCkpKTsNCiAgICAgICAgb2JqLnN0YXRlID0gMTsNCiAgICAgICAgaWYgKG9iai5vblN0ZXApIG9iai5vblN0ZXAob2JqKTsNCiAgICB9DQogICAgDQogICAgb2JqLnRvU3RyaW5nID0gZnVuY3Rpb24gKHgpIHsgaWYgKHR5cGVvZiB4ID09ICdvYmplY3QnKSByZXR1cm4gSlNPTi5zdHJpbmdpZnkoeCk7IHJldHVybiB4OyB9DQoNCiAgICBvYmoucmVzZXQoKTsNCiAgICByZXR1cm4gb2JqOw0KfQ0KDQovLyBBcmd1bWVudCB0eXBlczogMCA9IFZhcmlhYmxlLCAxID0gU3RyaW5nLCAyID0gSW50ZWdlciwgMyA9IExhYmVsDQpmdW5jdGlvbiBzY3JpcHRfY29tcGlsZShzY3JpcHQsIG9ubXNnKSB7DQogICAgdmFyIHIgPSAnJywgc2NyaXB0bGluZXMgPSBzY3JpcHQuc3BsaXQoJ1xuJyksIGxhYmVscyA9IHt9LCBsYWJlbHN3YXAgPSBbXSwgc3dhcHMgPSBbXTsNCiAgICAvLyBHbyB0aHJ1IGVhY2ggc2NyaXB0IGxpbmUgYW5kIGVuY29kZSBpdA0KICAgIGZvciAodmFyIGkgaW4gc2NyaXB0bGluZXMpIHsNCiAgICAgICAgdmFyIHNjcmlwdGxpbmUgPSBzY3JpcHRsaW5lc1tpXTsNCiAgICAgICAgaWYgKHNjcmlwdGxpbmUuc3RhcnRzV2l0aCgnIyNTV0FQICcpKSB7IHZhciB4ID0gc2NyaXB0bGluZS5zcGxpdCgnICcpOyBpZiAoeC5sZW5ndGggPT0gMykgeyBzd2Fwc1t4WzFdXSA9IHhbMl07IH0gfSAvLyBBZGQgYSBzd2FwIGluc3RhbmNlDQogICAgICAgIGlmIChzY3JpcHRsaW5lWzBdID09ICcjJyB8fCBzY3JpcHRsaW5lLmxlbmd0aCA9PSAwKSBjb250aW51ZTsgLy8gU2tpcCBjb21tZW50cyAmIGJsYW5rIGxpbmVzDQogICAgICAgIGZvciAodmFyIHggaW4gc3dhcHMpIHsgc2NyaXB0bGluZSA9IHNjcmlwdGxpbmUuc3BsaXQoeCkuam9pbihzd2Fwc1t4XSk7IH0gLy8gQXBwbHkgYWxsIHN3YXBzDQogICAgICAgIHZhciBrZXl3b3JkcyA9IHNjcmlwdGxpbmUubWF0Y2goLyJbXiJdKiJ8W15ccyJdKy9nKTsNCiAgICAgICAgaWYgKGtleXdvcmRzLmxlbmd0aCA9PSAwKSBjb250aW51ZTsgLy8gU2tpcCBibGFuayBsaW5lcw0KICAgICAgICBpZiAoc2NyaXB0bGluZVswXSA9PSAnOicpIHsgbGFiZWxzW2tleXdvcmRzWzBdLnRvVXBwZXJDYXNlKCldID0gci5sZW5ndGg7IGNvbnRpbnVlOyB9IC8vIE1hcmsgYSBsYWJlbCBwb3NpdGlvbg0KICAgICAgICB2YXIgZnVuY0luZGV4ID0gc2NyaXB0X2Z1bmN0aW9uVGFibGUxLmluZGV4T2Yoa2V5d29yZHNbMF0udG9Mb3dlckNhc2UoKSk7DQogICAgICAgIGlmIChmdW5jSW5kZXggPT0gLTEpIHsgZnVuY0luZGV4ID0gc2NyaXB0X2Z1bmN0aW9uVGFibGUyLmluZGV4T2Yoa2V5d29yZHNbMF0udG9Mb3dlckNhc2UoKSk7IGlmIChmdW5jSW5kZXggPj0gMCkgZnVuY0luZGV4ICs9IDEwMDAwOyB9DQogICAgICAgIGlmIChmdW5jSW5kZXggPT0gLTEpIHsgZnVuY0luZGV4ID0gc2NyaXB0X2Z1bmN0aW9uVGFibGUzLmluZGV4T2Yoa2V5d29yZHNbMF0udG9Mb3dlckNhc2UoKSk7IGlmIChmdW5jSW5kZXggPj0gMCkgZnVuY0luZGV4ICs9IDIwMDAwOyB9IC8vIE9wdGlvbmFsIG1ldGhvZHMNCiAgICAgICAgaWYgKGZ1bmNJbmRleCA9PSAtMSkgeyBpZiAob25tc2cpIHsgb25tc2coIlVuYWJsZWQgdG8gY29tcGlsZSwgdW5rbm93biBjb21tYW5kOiAiICsga2V5d29yZHNbMF0pOyB9IHJldHVybiAnJzsgfQ0KICAgICAgICAvLyBFbmNvZGUgQ29tbWFuZElkLCBDbWRTaXplLCBBcmdDb3VudCwgQXJnMUxlbiwgQXJnMSwgQXJnMkxlbiwgQXJnMi4uLg0KICAgICAgICB2YXIgY21kID0gU2hvcnRUb1N0cihrZXl3b3Jkcy5sZW5ndGggLSAxKTsNCiAgICAgICAgZm9yICh2YXIgaiBpbiBrZXl3b3Jkcykgew0KICAgICAgICAgICAgaWYgKGogPT0gMCkgY29udGludWU7DQogICAgICAgICAgICBpZiAoa2V5d29yZHNbal1bMF0gPT0gJzonKSB7DQogICAgICAgICAgICAgICAgbGFiZWxzd2FwLnB1c2goW2tleXdvcmRzW2pdLCByLmxlbmd0aCArIGNtZC5sZW5ndGggKyA3XSk7IC8vIEFkZCBhIGxhYmVsIHN3YXANCiAgICAgICAgICAgICAgICBjbWQgKz0gU2hvcnRUb1N0cig1KSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMykgKyBJbnRUb1N0cigweEZGRkZGRkZGKTsgLy8gUHV0IGFuIGVtcHR5IGxhYmVsDQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHZhciBhcmdpbnQgPSBwYXJzZUludChrZXl3b3Jkc1tqXSk7DQogICAgICAgICAgICAgICAgaWYgKGFyZ2ludCA9PSBrZXl3b3Jkc1tqXSkgew0KICAgICAgICAgICAgICAgICAgICBjbWQgKz0gU2hvcnRUb1N0cig1KSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMikgKyBJbnRUb1N0cihhcmdpbnQpOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChrZXl3b3Jkc1tqXVswXSA9PSAnIicgJiYga2V5d29yZHNbal1ba2V5d29yZHNbal0ubGVuZ3RoIC0gMV0gPT0gJyInKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBjbWQgKz0gU2hvcnRUb1N0cihrZXl3b3Jkc1tqXS5sZW5ndGggLSAxKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMSkgKyBrZXl3b3Jkc1tqXS5zdWJzdHJpbmcoMSwga2V5d29yZHNbal0ubGVuZ3RoIC0gMSk7DQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICBjbWQgKz0gU2hvcnRUb1N0cihrZXl3b3Jkc1tqXS5sZW5ndGggKyAxKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoMCkgKyBrZXl3b3Jkc1tqXTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICBjbWQgPSBTaG9ydFRvU3RyKGZ1bmNJbmRleCkgKyBTaG9ydFRvU3RyKGNtZC5sZW5ndGggKyA0KSArIGNtZDsNCiAgICAgICAgciArPSBjbWQ7DQogICAgfQ0KICAgIC8vIFBlcmZvcm0gYWxsIHRoZSBuZWVkZWQgbGFiZWwgc3dhcHMNCiAgICBmb3IgKGkgaW4gbGFiZWxzd2FwKSB7DQogICAgICAgIHZhciBsYWJlbCA9IGxhYmVsc3dhcFtpXVswXS50b1VwcGVyQ2FzZSgpLCBwb3NpdGlvbiA9IGxhYmVsc3dhcFtpXVsxXSwgdGFyZ2V0ID0gbGFiZWxzW2xhYmVsXTsNCiAgICAgICAgaWYgKHRhcmdldCA9PSB1bmRlZmluZWQpIHsgaWYgKG9ubXNnKSB7IG9ubXNnKCJVbmFibGVkIHRvIGNvbXBpbGUsIHVua25vd24gbGFiZWw6ICIgKyBsYWJlbCk7IH0gcmV0dXJuICcnOyB9DQogICAgICAgIHIgPSByLnN1YnN0cigwLCBwb3NpdGlvbikgKyBJbnRUb1N0cih0YXJnZXQpICsgci5zdWJzdHIocG9zaXRpb24gKyA0KTsNCiAgICB9DQogICAgcmV0dXJuIEludFRvU3RyKDB4MjQ3RDI5NDUpICsgU2hvcnRUb1N0cigxKSArIHI7DQp9DQoNCi8vIERlY29tcGlsZSB0aGUgc2NyaXB0LCBpbnRlbmRlZCBmb3IgZGVidWdnaW5nIG9ubHkNCmZ1bmN0aW9uIHNjcmlwdF9kZWNvbXBpbGUoYmluYXJ5LCBvbmVjbWQpIHsNCiAgICB2YXIgciA9ICcnLCBwdHIgPSA2LCBsYWJlbGNvdW50ID0gMCwgbGFiZWxzID0ge307DQogICAgaWYgKG9uZWNtZCA+PSAwKSB7DQogICAgICAgIHB0ciA9IG9uZWNtZDsgLy8gSWYgd2UgYXJlIGRlY29tcGlsaW5nIGp1c3Qgb25lIGNvbW1hbmQsIHNldCB0aGUgcHRyIHRvIHRoYXQgY29tbWFuZC4NCiAgICB9IGVsc2Ugew0KICAgICAgICBpZiAoYmluYXJ5Lmxlbmd0aCA8IDYpIHsgcmV0dXJuICcjIEludmFsaWQgc2NyaXB0IGxlbmd0aCc7IH0NCiAgICAgICAgdmFyIG1hZ2ljID0gUmVhZEludChiaW5hcnksIDApOw0KICAgICAgICB2YXIgdmVyc2lvbiA9IFJlYWRTaG9ydChiaW5hcnksIDQpOw0KICAgICAgICBpZiAobWFnaWMgIT0gMHgyNDdEMjk0NSkgeyByZXR1cm4gJyMgSW52YWxpZCBiaW5hcnkgc2NyaXB0OiAnICsgbWFnaWM7IH0NCiAgICAgICAgaWYgKHZlcnNpb24gIT0gMSkgeyByZXR1cm4gJyMgSW52YWxpZCBzY3JpcHQgdmVyc2lvbic7IH0NCiAgICB9DQogICAgLy8gTG9vcCBvbiBlYWNoIGNvbW1hbmQsIG1vdmluZyBmb3J3YXJkIGJ5IHRoZSBjb21tYW5kIGxlbmd0aCBlYWNoIHRpbWUuDQogICAgd2hpbGUgKHB0ciA8IGJpbmFyeS5sZW5ndGgpIHsNCiAgICAgICAgdmFyIGNtZGlkID0gUmVhZFNob3J0KGJpbmFyeSwgcHRyKTsNCiAgICAgICAgdmFyIGNtZGxlbiA9IFJlYWRTaG9ydChiaW5hcnksIHB0ciArIDIpOw0KICAgICAgICB2YXIgYXJnY291bnQgPSBSZWFkU2hvcnQoYmluYXJ5LCBwdHIgKyA0KTsNCiAgICAgICAgdmFyIGFyZ3B0ciA9IHB0ciArIDY7DQogICAgICAgIHZhciBhcmdzdHIgPSAnJzsNCiAgICAgICAgaWYgKCEob25lY21kID49IDApKSByICs9ICI6bGFiZWwiICsgKHB0ciAtIDYpICsgIlxuIjsNCiAgICAgICAgLy8gTG9vcCBvbiBlYWNoIGFyZ3VtZW50LCBtb3ZpbmcgZm9yd2FyZCBieSB0aGUgYXJndW1lbnQgbGVuZ3RoIGVhY2ggdGltZQ0KICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ2NvdW50OyBpKyspIHsNCiAgICAgICAgICAgIHZhciBhcmdsZW4gPSBSZWFkU2hvcnQoYmluYXJ5LCBhcmdwdHIpOw0KICAgICAgICAgICAgdmFyIGFyZ3ZhbCA9IGJpbmFyeS5zdWJzdHJpbmcoYXJncHRyICsgMiwgYXJncHRyICsgMiArIGFyZ2xlbik7DQogICAgICAgICAgICB2YXIgYXJndHlwID0gYXJndmFsLmNoYXJDb2RlQXQoMCk7DQogICAgICAgICAgICBpZiAoYXJndHlwID09IDApIHsgYXJnc3RyICs9ICcgJyArIGFyZ3ZhbC5zdWJzdHJpbmcoMSk7IH0gLy8gVmFyaWFibGUNCiAgICAgICAgICAgIGVsc2UgaWYgKGFyZ3R5cCA9PSAxKSB7IGFyZ3N0ciArPSAnIFwiJyArIGFyZ3ZhbC5zdWJzdHJpbmcoMSkgKyAnXCInOyB9IC8vIFN0cmluZw0KICAgICAgICAgICAgZWxzZSBpZiAoYXJndHlwID09IDIpIHsgYXJnc3RyICs9ICcgJyArIFJlYWRJbnQoYXJndmFsLCAxKTsgfSAvLyBJbnRlZ2VyDQogICAgICAgICAgICBlbHNlIGlmIChhcmd0eXAgPT0gMykgeyAvLyBMYWJlbA0KICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSBSZWFkSW50KGFyZ3ZhbCwgMSk7DQogICAgICAgICAgICAgICAgdmFyIGxhYmVsID0gbGFiZWxzW3RhcmdldF07DQogICAgICAgICAgICAgICAgaWYgKCFsYWJlbCkgeyBsYWJlbCA9ICI6bGFiZWwiICsgdGFyZ2V0OyBsYWJlbHNbbGFiZWxdID0gdGFyZ2V0OyB9DQogICAgICAgICAgICAgICAgYXJnc3RyICs9ICcgJyArIGxhYmVsOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgYXJncHRyICs9ICgyICsgYXJnbGVuKTsNCiAgICAgICAgfQ0KICAgICAgICAvLyBHbyBpbiB0aGUgc2NyaXB0IGZ1bmN0aW9uIHRhYmxlIHRvIGRlY29kZSB0aGUgZnVuY3Rpb24NCiAgICAgICAgaWYgKGNtZGlkIDwgMTAwMDApIHsNCiAgICAgICAgICAgIHIgKz0gc2NyaXB0X2Z1bmN0aW9uVGFibGUxW2NtZGlkXSArIGFyZ3N0ciArICJcbiI7DQogICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBpZiAoY21kaWQgPj0gMjAwMDApIHsNCiAgICAgICAgICAgICAgICByICs9IHNjcmlwdF9mdW5jdGlvblRhYmxlM1tjbWRpZCAtIDIwMDAwXSArIGFyZ3N0ciArICJcbiI7IC8vIE9wdGlvbmFsIG1ldGhvZHMNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgciArPSBzY3JpcHRfZnVuY3Rpb25UYWJsZTJbY21kaWQgLSAxMDAwMF0gKyBhcmdzdHIgKyAiXG4iOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIHB0ciArPSBjbWRsZW47DQogICAgICAgIGlmIChvbmVjbWQgPj0gMCkgcmV0dXJuIHI7IC8vIElmIHdlIGFyZSBkZWNvbXBpbGluZyBqdXN0IG9uZSBjb21tYW5kLCBleGl0IG5vdw0KICAgIH0NCiAgICAvLyBSZW1vdmUgYWxsIHVudXNlZCBsYWJlbHMNCiAgICB2YXIgc2NyaXB0bGluZXMgPSByLnNwbGl0KCdcbicpOw0KICAgIHIgPSAnJzsNCiAgICBmb3IgKHZhciBpIGluIHNjcmlwdGxpbmVzKSB7DQogICAgICAgIHZhciBsaW5lID0gc2NyaXB0bGluZXNbaV07DQogICAgICAgIGlmIChsaW5lWzBdICE9ICc6JykgeyByICs9IGxpbmUgKyAnXG4nOyB9IGVsc2UgeyBpZiAobGFiZWxzW2xpbmVdKSB7IHIgKz0gbGluZSArICdcbic7IH0gfQ0KICAgIH0NCiAgICByZXR1cm4gcjsNCn0NCi8qKiANCiogQGRlc2NyaXB0aW9uIEludGVsKFIpIEFNVCBTZXR1cC5iaW4gUGFyc2VyDQoqIEBhdXRob3IgWWxpYW4gU2FpbnQtSGlsYWlyZQ0KKiBAdmVyc2lvbiB2MC4xLjANCiovDQoNCi8vIEludGVsKFIpIEFNVCBTZXR1cC5iaW4gR1VJRCdzDQp2YXIgQW10U2V0dXBCaW5TZXR1cEd1aWRzID0gWw0KICAgICJceGI1XHgxNlx4ZmJceDcxXHg4N1x4Y2JceGY5XHg0YVx4YjRceDQxXHhjYVx4N2JceDM4XHgzNVx4NzhceGY5IiwgLy8gVmVyc2lvbiAxDQogICAgIlx4OTZceGIyXHg4MVx4NThceGNmXHg2Ylx4NzJceDRjXHg4Ylx4OTFceGExXHg1ZVx4NTFceDJlXHg5OVx4YzQiLCAvLyBWZXJzaW9uIDINCiAgICAiXHhhN1x4ZjdceGY2XHhjNlx4ODlceGM0XHhmNlx4NDdceDkzXHhlZFx4ZTJceGU1XHgwMlx4MGRceGE1XHgxZCIsIC8vIFZlcnNpb24gMw0KICAgICJceGFhXHhhOVx4MzRceDUyXHhlMVx4MjlceGE5XHg0NFx4OGRceDRkXHgwOFx4MWNceDA3XHhiOVx4NjNceDUzIiAgLy8gVmVyc2lvbiA0DQpdOw0KDQovLyBOb3RlcyBhYm91dCB2ZXJzaW9uIDIgb2Ygc2V0dXAuYmluOg0KLy8gICAtIERlZmF1bHQgImFkbWluIiBtdXN0IGJlIGZvbGxvd2VkIGJ5IGEgbmV3IE1FQnggcGFzc3dvcmQNCi8vICAgLSBNRV9WQVJJQUJMRV9JREVOVElGSUVSX01BTkFHRUFCSUxJVFlfRkVBVFVSRV9TRUxFQ1RJT04gbWF5IG5vdCBhcHBlYXIgYWZ0ZXIgYW55IENNIHNldHRpbmdzDQovLyAgIC0gQ01fVkFSSUFCTEVfSURFTlRJRklFUl9VU0VSX0RFRklORURfQ0VSVF9BREQgbXVzdCBiZSBwcmVjZWRlZCBieSBzZXR0aW5nIENNX1ZBUklBQkxFX0lERU5USUZJRVJfVVNFUl9ERUZJTkVEX0NFUlRTX0NPTkZJRyB0byAoVE9ETyEpDQoNCi8vIEdlbmVyYWwgbm90ZXM6DQovLyAgIC0gU2V0dXAuYmluIHNob3VsZCBhbHdheXMgc3RhcnQgd2l0aCAiQ3VycmVudE1FQnggUHdkIiwgIm5ld01lYnggUHdkIiwgIm1hbmFnZWFiaWxpdHkgc2VsZWN0aW9uIiAoaWYgcHJlc2VudCkuDQoNCi8vIEludGVsKFIpIEFNVCB2YXJpYWJsZSBpZGVudGlmaWVycw0KLy8gVHlwZTogMCA9IEJpbmFyIFN0cmluZ3ksIDEgPSBDaGFyLCAyID0gU2hvcnQsIDMgPSBJbnQNCnZhciBBbXRTZXR1cEJpblZhcklkcyA9DQp7DQogICAgMTogew0KICAgICAgICAxOiAgWzAsICJDdXJyZW50IE1FQnggUGFzc3dvcmQiXSwNCiAgICAgICAgMjogIFswLCAiTmV3IE1FQnggUGFzc3dvcmQiXSwNCiAgICAgICAgMzogIFsxLCAiTWFuYWdlYWJpbGl0eSBGZWF0dXJlIFNlbGVjdGlvbiJdLA0KICAgICAgICA0OiAgWzEsICJGaXJtd2FyZSBMb2NhbCBVcGRhdGUiLCAgICAgICAgICAgICAgICAgICAvLyAwID0gRGlzYWJsZWQsIDEgPSBFbmFibGVkLCAyID0gUGFzc3dvcmQgUHJvdGVjdGVkDQogICAgICAgICAgICB7IDA6ICJEaXNhYmxlZCIsIDE6ICJFbmFibGVkIiwgMjogIlBhc3N3b3JkIFByb3RlY3RlZCIgfV0sDQogICAgICAgIDU6ICBbMSwgIkZpcm13YXJlIFVwZGF0ZSBRdWFsaWZpZXIiLCAgICAgICAgICAgICAgIC8vIDAgPSBBbHdheXMsIDEgPSBOZXZlciwgMiA9IFJlc3RyaWN0ZWQNCiAgICAgICAgICAgIHsgMDogIkFsd2F5cyIsIDE6ICJOZXZlciIsIDI6ICJSZXN0cmljdGVkIiB9XSwNCiAgICAgICAgNjogIFs0LCAiUG93ZXIgUGFja2FnZSJdICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gR1VJRCBMZW5ndGggKDE2IGJ5dGVzKSwgSW50ZWwgQU1UIHZlcnNpb24gMi4xLCAzIGFuZCA0DQogICAgfSwNCiAgICAyOiB7DQogICAgICAgIDE6ICBbMCwgIlByb3Zpc2lvbmluZyBQcmVzaGFyZWQgS2V5IElEIChQSUQpIl0sDQogICAgICAgIDI6ICBbMCwgIlByb3Zpc2lvbmluZyBQcmVzaGFyZWQgS2V5IChQUFMpIl0sDQogICAgICAgIDM6ICBbMCwgIlBLSSBETlMgU3VmZml4Il0sICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDI1NSBieXRlcyBtYXggbGVuZ3RoDQogICAgICAgIDQ6ICBbMCwgIkNvbmZpZ3VyYXRpb24gU2VydmVyIEZRRE4iXSwgICAgICAgICAgICAgIC8vIDI1NSBieXRlcyBtYXggbGVuZ3RoDQogICAgICAgIDU6ICBbMSwgIlJlbW90ZSBDb25maWd1cmF0aW9uIEVuYWJsZWQgKFJDRkcpIiwgICAgIC8vIDAgPSBPZmYsIDEgPSBPbg0KICAgICAgICAgICAgeyAwOiAiT2ZmIiwgMTogIk9uIiB9XSwNCiAgICAgICAgNjogIFsxLCAiUHJlLUluc3RhbGxlZCBDZXJ0aWZpY2F0ZXMgRW5hYmxlZCIsICAgICAgLy8gMCA9IE9mZiwgMSA9IE9uDQogICAgICAgICAgICB7IDA6ICJPZmYiLCAxOiAiT24iIH1dLA0KICAgICAgICA3OiAgWzEsICJVc2VyIERlZmluZWQgQ2VydGlmaWNhdGUgQ29uZmlndXJhdGlvbiIsICAvLyAwID0gRGlzYWJsZWQsIDEgPSBFbmFibGVkLCAyID0gRGVsZXRlDQogICAgICAgICAgICB7IDA6ICJEaXNhYmxlZCIsIDE6ICJFbmFibGVkIiwgMjogIkRlbGV0ZSIgfV0sDQogICAgICAgIDg6ICBbMCwgIlVzZXIgRGVmaW5lZCBDZXJ0aWZpY2F0ZSBBZGRpdGlvbiJdLCAgICAgIC8vIDEgYnl0ZSBoYXNoIGFsZ28sIDIwIHRvIDQ4IGJ5dGVzIGhhc2gsIDEgYnl0ZSBuYW1lIGxlbmd0aCwgdXAgdG8gMzIgYnl0ZXMgZnJpZW5kbHkgbmFtZSwgMSA9IFNIQTEgKDIwIGJ5dGVzKSwgMiA9IFNIQTI1NiAoMzIgYnl0ZXMpLCAzID0gU0hBMzg0ICg0OCBieXRlcykuIEFsZ28gMiAmIDMgYXJlIGZvciB2ZXJzaW9uIDMgYW5kIHVwLg0KICAgICAgICAxMDogWzEsICJTT0wvSURFUiBSZWRpcmVjdGlvbiBDb25maWd1cmF0aW9uIl0sDQogICAgICAgIDExOiBbMCwgIkhvc3RuYW1lIl0sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIDYzIGJ5dGVzIG1heCBsZW5ndGgNCiAgICAgICAgMTI6IFswLCAiRG9tYWluIE5hbWUiXSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gMjU1IGJ5dGVzIG1heCBsZW5ndGgNCiAgICAgICAgMTM6IFsxLCAiREhDUCIsIHsgMTogIkRpc2FibGVkIiwgMjogIkVuYWJsZWQiIH1dLA0KICAgICAgICAxNDogWzEsICJTZWN1cmUgRmlybXdhcmUgVXBkYXRlIChTRldVKSIsICAgICAgICAgICAvLyAwID0gRGlzYWJsZWQsIDEgPSBFbmFibGVkDQogICAgICAgICAgICB7IDA6ICJEaXNhYmxlZCIsIDE6ICJFbmFibGVkIiB9XSwNCiAgICAgICAgMTU6IFswLCAiSVRPIl0sDQogICAgICAgIDE2OiBbMSwgIlByb3Zpc2lvbmluZyBNb2RlIChQTSkiLCAgICAgICAgICAgICAgICAgIC8vIDEgPSBFbnRlcnByaXNlLCAyID0gU21hbGwgQnVpc25lc3MgKFNNQikNCiAgICAgICAgICAgIHsgMDogIkVudGVycHJpc2UiLCAxOiAiU21hbGwgQnVpc25lc3MifV0sDQogICAgICAgIDE3OiBbMCwgIlByb3Zpc2lvbmluZyBTZXJ2ZXIgQWRkcmVzcyJdLA0KICAgICAgICAxODogWzIsICJQcm92aXNpb24gU2VydmVyIFBvcnQgTnVtYmVyIChQU1BPKSJdLA0KICAgICAgICAxOTogWzAsICJTdGF0aWMgUFY0IFBhcmFtZXRlcnMiXSwNCiAgICAgICAgMjA6IFswLCAiVkxBTiJdLA0KICAgICAgICAyMTogWzAsICJQQVNTIFBvbGljeSBGbGFnIl0sDQogICAgICAgIDIyOiBbMCwgIklQdjYiXSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIExlbmd0aCBpcyAyMDQgYnl0ZXMgb2xkIGZvcm1hdCwgODQgYnl0ZXMgbmV3IGZvcm1hdCwgVmVyc2lvbiAzKyBvbmx5DQogICAgICAgIDIzOiBbMSwgIlNoYXJlZC9EZWRpY2F0ZWQgRlFETiIsICAgICAgICAgICAgICAgICAgIC8vIDAgPSBEZWRpY2F0ZWQsIDEgPSBTaGFyZWQuIFRoaXMgb3B0aW9uIGlzIHZhbGlkIG9ubHkgaWYgY29uZmlndXJpbmcgdGhlIGhvc3RuYW1lIGFzIHdlbGwNCiAgICAgICAgICAgIHsgMDogIkRlZGljYXRlZCIsIDE6ICJTaGFyZWQiIH1dLA0KICAgICAgICAyNDogWzEsICJEeW5hbWljIEROUyBVcGRhdGUiLCAgICAgICAgICAgICAgICAgICAgICAvLyAwID0gRGlzYWJsZWQsIDEgPSBFbmFibGVkDQogICAgICAgICAgICB7IDA6ICJEaXNhYmxlZCIsIDE6ICJFbmFibGVkIiB9XSwNCiAgICAgICAgMjU6IFsxLCAiUmVtb3RlIERlc2t0b3AgKEtWTSkgU3RhdGUiLCAgICAgICAgICAgICAgLy8gMCA9IERpc2FibGVkLCAxID0gRW5hYmxlZA0KICAgICAgICAgICAgeyAwOiAiRGlzYWJsZWQiLCAxOiAiRW5hYmxlZCIgfV0sDQogICAgICAgIDI2OiBbMSwgIk9wdC1pbiBVc2VyIENvbnNlbnQgT3B0aW9uIiwgICAgICAgICAgICAgIC8vIDAgPSBEaXNhYmxlZCwgMSA9IEtWTSwgMHhGRiA9IEFMTA0KICAgICAgICAgICAgeyAwIDogIkRpc2FibGVkIiwgMSA6ICJLVk0iLCAyNTUgOiAiQWxsIiB9XSwNCiAgICAgICAgMjc6IFsxLCAiT3B0LWluIFJlbW90ZSBJVCBDb25zZW50IFBvbGljeSIsICAgICAgICAgLy8gMCA9IERpc2FibGVkLCAxID0gRW5hYmxlZC4gQWxsb3dzIHVzZXIgY29uc2VudCB0byBiZSBjb25maWd1cmVkIHJlbW90ZWx5Lg0KICAgICAgICAgICAgeyAwIDogIkRpc2FibGVkIiwgMSA6ICJFbmFibGVkIn0gXSwNCiAgICAgICAgMjg6IFsxLCAiTUUgUHJvdmlzaW9uIEhhbHQgQWN0aXZlIiwgICAgICAgICAgICAgICAgLy8gMCA9IFN0b3AsIDEgPSBTdGFydC4gVGhlICJNRSBwcm92aXNpb25pbmcgSGFsdC9BY3RpdmF0ZSIgY29tbWFuZCBtdXN0IGFwcGVhciBpbiB0aGUgZmlsZSBvbmx5IGFmdGVyICJQS0lETlNTdWZmaXgiLCAiQ29uZmlnU2VydmVyRlFETiIgYW5kICJQcm92aXNpb25pbmcgU2VydmVyIEFkZHJlc3MiDQogICAgICAgICAgICB7IDAgOiAiU3RvcCIsIDEgOiAiU3RhcnQifV0sDQogICAgICAgIDI5OiBbMSwgIk1hbnVhbCBTZXR1cCBhbmQgQ29uZmlndXJhdGlvbiIsICAgICAgICAgIC8vIDAgPSBBdXRvbWF0ZWQsIDEgPSBNYW51YWwNCiAgICAgICAgICAgIHsgMCA6ICJBdXRvbWF0ZWQiLCAxIDogIk1hbnVhbCJ9XSwNCiAgICAgICAgMzA6IFszLCAiU3VwcG9ydCBDaGFubmVsIElkZW50aWZpZXIiXSwgICAgICAgICAgICAgLy8gNCBieXRlcyBsZW5ndGguIFN1cHBvcnQgY2hhbm5lbCBpZGVudGlmaWVyICh2YWxpZCB2YWx1ZXM6IDEtNjU1MzUpDQogICAgICAgIDMxOiBbMCwgIlN1cHBvcnQgQ2hhbm5lbCBEZXNjcmlwdGlvbiJdLCAgICAgICAgICAgIC8vIDYwIGJ5dGVzIG1heC4gRnJpZW5kbHkgbmFtZSB1c2VkIHRvIGRlc2NyaWJlIHRoZSBwYXJ0eSByZXByZXNlbnRlZGJ5IHRoZSBzdXBwb3J0IGNoYW5uZWwgaWRlbnRpZmllci4NCiAgICAgICAgMzI6IFswLCAiU2VydmljZSBBY2NvdW50IE51bWJlciJdLCAgICAgICAgICAgICAgICAgLy8gMzIgYnl0ZXMgbWF4LiBVbmlxdWUgc3RyaW5nIGlkZW50aWZpZXIgZ2l2ZW4gdG8gdGhlIGVuZCB1c2VyIGJ5IHRoZSBzZXJ2aWNlIHByb3ZpZGVyLg0KICAgICAgICAzMzogWzAsICJFbnJvbGxlbWVudCBQYXNzY29kZSJdLCAgICAgICAgICAgICAgICAgICAvLyAzMiBieXRlcyBtYXgNCiAgICAgICAgMzQ6IFszLCAiU2VydmljZSBUeXBlIl0sICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gNCBieXRlcyBsZW5ndGguIDEgPSBSZWFjdGl2ZSwgMiA9IFByb2FjdGl2ZSwgNCA9IE9uZSBUaW1lIFNlc3Npb24NCiAgICAgICAgMzU6IFswLCAiU2VydmljZSBQcm92aWRlciBJZGVudGlmaWVyIl0gICAgICAgICAgICAgLy8gR1VJRCBMZW5ndGggKDE2IGJ5dGVzKQ0KICAgIH0NCn0NCg0KDQovLyBQYXJzZSB0aGUgU2V0dXAuYmluIGZpbGUNCnZhciBBbXRTZXR1cEJpbkNyZWF0ZSA9IGZ1bmN0aW9uICh2ZXJzaW9uLCBmbGFncykgew0KICAgIHZhciBvYmogPSB7fTsNCiAgICBvYmouZmlsZVR5cGUgPSB2ZXJzaW9uOw0KICAgIG9iai5yZWNvcmRDaHVua0NvdW50ID0gMDsNCiAgICBvYmoucmVjb3JkSGVhZGVyQnl0ZUNvdW50ID0gMDsNCiAgICBvYmoucmVjb3JkTnVtYmVyID0gMDsNCiAgICBvYmoubWFqb3JWZXJzaW9uID0gdmVyc2lvbjsNCiAgICBvYmoubWlub3JWZXJzaW9uID0gMDsNCiAgICBvYmouZmxhZ3MgPSBmbGFnczsNCiAgICBvYmouZGF0YVJlY29yZHNDb25zdW1lZCA9IDA7DQogICAgb2JqLmRhdGFSZWNvcmRDaHVua0NvdW50ID0gMDsNCiAgICBvYmoucmVjb3JkcyA9IFtdOw0KICAgIHJldHVybiBvYmo7DQp9DQoNCg0KLy8gUGFyc2UgdGhlIFNldHVwLmJpbiBmaWxlDQp2YXIgQW10U2V0dXBCaW5EZWNvZGUgPSBmdW5jdGlvbiAoZmlsZSkgew0KDQogICAgLy8gRm9ybWF0IG9mIHRoZSBzZXR1cCBmaWxlIGhlYWRlcjoNCiAgICAvLyBGaWxlVHlwZVVVSUQoMTYpICAgICAgICAgLSB1bmlxdWVseSBpZGVudGlmaWVzIHRoZSBmaWxlIHR5cGUuIFRoaXMgaWRlbnRpZmllciB3aWxsIHJlbWFpbiB2YWxpZCBhbmQgY29uc3RhbnQgYWNyb3NzIGFsbCB2ZXJzaW9ucyBvZiB0aGUgZmlsZSB0eXBlLg0KICAgIC8vIFJlY29yZENodW5rQ291bnQoMikgICAgICAtIGluZGljYXRlcyB0aGUgbnVtYmVyIG9mIDUxMi1ieXRlIGNodW5rcyBvY2N1cGllZCBieSB0aGlzIHJlY29yZCwgaW5jbHVkaW5nIGFsbCBoZWFkZXIsIGJvZHksIGFuZCByZXNlcnZlZCBmaWVsZHMuDQogICAgLy8gUmVjb3JkSGVhZGVyQnl0ZXMoMikgICAgIC0gaW5kaWNhdGVzIHRoZSBsZW5ndGggb2YgdGhlIHJlY29yZCBoZWFkZXIgaW4gYnl0ZXMuDQogICAgLy8gUmVjb3JkTnVtYmVyKDQpICAgICAgICAgIC0gdW5pcXVlbHkgaWRlbnRpZmllcyB0aGUgcmVjb3JkIGFtb25nIGFsbCByZWNvcmRzIGluIHRoZSBmaWxlLiBUaGUgZmllbGQgY29udGFpbnMgYSBub24tbmVnYXRpdmUgb3JkaW5hbCB2YWx1ZS4gVGhlIHZhbHVlIG9mIHRoaXMgZmllbGQgaXMgYWx3YXlzIHplcm8gaW4gdGhlIExvY2FsIFByb3Zpc2lvbmluZyBGaWxlIEhlYWRlciBSZWNvcmQuDQogICAgLy8gTWFqb3JWZXJzaW9uKDEpICAgICAgICAgIC0gaWRlbnRpZmllcyB0aGUgbWFqb3IgdmVyc2lvbiBvZiB0aGUgZmlsZSBmb3JtYXQgc3BlY2lmaWNhdGlvbi4gVGhpcyBpcyBhIHBvc2l0aXZlIGludGVnZXIgdGhhdCBpcyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gMS4gVGhlIE1ham9yIFZlcnNpb24gbnVtYmVyIGlzIGluY3JlbWVudGVkIHRvIGluZGljYXRlIHRoYXQgY2hhbmdlcyBoYXZlIGJlZW4gaW50cm9kdWNlZCB0aGF0IHdpbGwgY2F1c2UgY29kZSB3cml0dGVuIGFnYWluc3QgYSBsb3dlciBNYWpvciBWZXJzaW9uIG51bWJlciB0byBmYWlsLg0KICAgIC8vIE1pbm9yVmVyc2lvbigxKSAgICAgICAgICAtIGlkZW50aWZpZXMgdGhlIG1pbm9yIHZlcnNpb24gb2YgdGhlIGZpbGUgZm9ybWF0IHNwZWNpZmljYXRpb24uIFRoaXMgaXMgYW4gaW50ZWdlciB0aGF0IGlzIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byAwLiBUaGUgTWlub3IgVmVyc2lvbiBudW1iZXIgaXMgaW5jcmVtZW50ZWQgdG8gaW5kaWNhdGUgdGhhdCBjaGFuZ2VzIGhhdmUgYmVlbiBpbnRyb2R1Y2VkIHRoYXQgd2lsbCBub3QgY2F1c2UgY29kZSB3cml0dGVuIGFnYWluc3QgdGhlIHNhbWUgTWFqb3IgVmVyc2lvbiBhbmQgYSBsb3dlciBNaW5vciBWZXJzaW9uIG51bWJlciB0byBmYWlsLiBUaGUgcHVycG9zZSBvZiB0aGlzIGJlaGF2aW9yIGlzIHRvIGFsbG93IGEgc2luZ2xlIGxvY2FsIHByb3Zpc2lvbmluZyBmaWxlIHRvIGJlIHVzZWQgZm9yIG11bHRpcGxlIGdlbmVyYXRpb25zIG9mIEludGVs77+9IEFNVCBwbGF0Zm9ybS4NCiAgICAvLyBEYXRhUmVjb3JkQ291bnQoNCkgICAgICAgLSBpbmRpY2F0ZXMgdGhlIHRvdGFsIG51bWJlciBvZiBkYXRhIHJlY29yZHMgd3JpdHRlbiBpbiB0aGUgZmlsZSB3aGVuIGl0IHdhcyBjcmVhdGVkLg0KICAgIC8vIERhdGFSZWNvcmRzQ29uc3VtZWQoNCkgICAtIGlzIGEgY291bnRlciB2YWx1ZSB0aGF0IGJlZ2lucyBhdCAwIGFuZCBpcyBpbmNyZW1lbnRlZCBieSAxIGJ5IGVhY2ggcGxhdGZvcm0gQklPUyB3aGVuIGl0IGNvbnN1bWVzIGEgZGF0YSByZWNvcmQgZnJvbSB0aGUgZmlsZS4gVGhpcyB2YWx1ZSBpcyB1c2VkIHRvIGRldGVybWluZSB0aGUgb2Zmc2V0IG9mIHRoZSBuZXh0IGRhdGEgcmVjb3JkIGluIHRoZSBmaWxlLg0KICAgIC8vIERhdGFSZWNvcmRDaHVua0NvdW50KDIpICAtIGNvbnRhaW5zIHRoZSBudW1iZXIgb2YgNTEyLWJ5dGUgY2h1bmtzIGluIGVhY2ggZGF0YSByZWNvcmQuIEFsbCBkYXRhIHJlY29yZHMgYXJlIHRoZSBzYW1lIGxlbmd0aC4NCiAgICAvLyBNb2R1bGVMaXN0ICAgICAgICAgICAgICAgLSBjb250YWlucyBhIGxpc3Qgb2YgbW9kdWxlIGlkZW50aWZpZXJzLiBBIG1vZHVsZe+/vXMgaWRlbnRpZmllciBhcHBlYXJzIGluIHRoZSBsaXN0IGlmIGFuZCBvbmx5IGlmIHRoZSBkYXRhIHJlY29yZHMgY29udGFpbiBlbnRyaWVzIGZvciB0aGF0IG1vZHVsZS4gRWFjaCBtb2R1bGUgaWRlbnRpZmllciBpcyB0d28gYnl0ZXMgaW4gbGVuZ3RoLiBUaGUgbGlzdCBpcyB0ZXJtaW5hdGVkIGJ5IGFuIGlkZW50aWZpZXIgdmFsdWUgb2YgMC4gDQoNCiAgICB2YXIgb2JqID0ge30sIFVVSUQgPSBmaWxlLnN1YnN0cmluZygwLCAxNik7DQogICAgb2JqLmZpbGVUeXBlID0gMDsNCiAgICBmb3IgKHZhciBpIGluIEFtdFNldHVwQmluU2V0dXBHdWlkcykgeyBpZiAoVVVJRCA9PSBBbXRTZXR1cEJpblNldHVwR3VpZHNbaV0pIG9iai5maWxlVHlwZSA9ICgraSArIDEpOyB9DQogICAgaWYgKG9iai5maWxlVHlwZSA9PSAwKSByZXR1cm47IC8vIEJhZCBoZWFkZXINCiAgICBvYmoucmVjb3JkQ2h1bmtDb3VudCA9IFJlYWRTaG9ydFgoZmlsZSwgMTYpOw0KICAgIG9iai5yZWNvcmRIZWFkZXJCeXRlQ291bnQgPSBSZWFkU2hvcnRYKGZpbGUsIDE4KTsNCiAgICBvYmoucmVjb3JkTnVtYmVyID0gUmVhZEludFgoZmlsZSwgMjApOw0KICAgIG9iai5tYWpvclZlcnNpb24gPSBmaWxlLmNoYXJDb2RlQXQoMjQpOw0KICAgIG9iai5taW5vclZlcnNpb24gPSBmaWxlLmNoYXJDb2RlQXQoMjUpOw0KICAgIG9iai5mbGFncyA9IFJlYWRTaG9ydFgoZmlsZSwgMjYpOyAgICAgICAgICAgICAgICAgICAvLyBGbGFnczogMSA9IERvIG5vdCBjb25zdW1lIHJlY29yZHMNCiAgICB2YXIgZGF0YVJlY29yZENvdW50ID0gUmVhZEludFgoZmlsZSwgMjgpOw0KICAgIG9iai5kYXRhUmVjb3Jkc0NvbnN1bWVkID0gUmVhZEludFgoZmlsZSwgMzIpOw0KICAgIG9iai5kYXRhUmVjb3JkQ2h1bmtDb3VudCA9IFJlYWRTaG9ydFgoZmlsZSwgMzYpOw0KICAgIG9iai5yZWNvcmRzID0gW107DQoNCiAgICB2YXIgcHRyID0gNTEyOw0KICAgIHdoaWxlIChwdHIgKyA1MTIgPD0gZmlsZS5sZW5ndGgpIHsNCg0KICAgICAgICAvLyBGb3JtYXQgb2YgYSBkYXRhIHJlY29yZCBoZWFkZXI6DQogICAgICAgIC8vIFJlY29yZFR5cGVJZGVudGlmaWVyKDQpICAgICAgICAgICAtIGlkZW50aWZpZXMgdGhlIHR5cGUgb2YgcmVjb3JkIChpbiB0aGlzIGNhc2UgYSBkYXRhIHJlY29yZCkuIFJlY29yZCBJZGVudGlmaWVyczogSW52YWxpZCAtIDAsIERhdGEgUmVjb3JkIC0gMQ0KICAgICAgICAvLyBSZWNvcmRGbGFncyg0KSAgICAgICAgICAgICAgICAgICAgLSBjb250YWlucyBhIHNldCBvZiBiaXQgZmxhZ3MgdGhhdCBjaGFyYWN0ZXJpemUgdGhlIHJlY29yZC4NCiAgICAgICAgLy8gUmVjb3JkQ2h1bmtDb3VudCgyKSAgICAgICAgICAgICAgIC0gY29udGFpbnMgdGhlIG51bWJlciBvZiA1MTItYnl0ZSBjaHVua3Mgb2NjdXBpZWQgYnkgdGhlIHJlY29yZCBpbmNsdWRpbmcgYWxsIGhlYWRlciwgYm9keSwgYW5kIHJlc2VydmVkIGZpZWxkcy4NCiAgICAgICAgLy8gUmVjb3JkSGVhZGVyQnl0ZUNvdW50KDIpICAgICAgICAgIC0gaW5kaWNhdGVzIHRoZSBsZW5ndGggb2YgdGhlIHJlY29yZCBoZWFkZXIgaW4gYnl0ZXMuDQogICAgICAgIC8vIFJlY29yZE51bWJlcig0KSAgICAgICAgICAgICAgICAgICAtIHVuaXF1ZWx5IGlkZW50aWZpZXMgdGhlIHJlY29yZCBhbW9uZyBhbGwgcmVjb3JkcyBpbiB0aGUgZmlsZSwgaW5jbHVkaW5nIGludmFsaWQgYXMgd2VsbCBhcyB2YWxpZCByZWNvcmRzLiBUaGUgaWRlbnRpZmllciBpcyBhIG5vbi1uZWdhdGl2ZSBpbnRlZ2VyLg0KDQogICAgICAgIHZhciByID0ge307DQogICAgICAgIHIudHlwZUlkZW50aWZpZXIgPSBSZWFkSW50WChmaWxlLCBwdHIpOw0KICAgICAgICByLmZsYWdzID0gUmVhZEludFgoZmlsZSwgcHRyICsgNCk7ICAgICAgICAgICAgICAvLyBGbGFnczogMSA9IFZhbGlkLCAyID0gU2NyYW1ibGVkDQogICAgICAgIHIuY2h1bmtDb3VudCA9IFJlYWRTaG9ydFgoZmlsZSwgcHRyICsgOCk7DQogICAgICAgIHIuaGVhZGVyQnl0ZUNvdW50ID0gUmVhZFNob3J0WChmaWxlLCBwdHIgKyAxMCk7DQogICAgICAgIHIubnVtYmVyID0gUmVhZEludFgoZmlsZSwgcHRyICsgMTIpOw0KICAgICAgICByLnZhcmlhYmxlcyA9IFtdOw0KDQogICAgICAgIHZhciBwdHIyID0gMCwgcmVjYmluID0gZmlsZS5zdWJzdHJpbmcocHRyICsgMjQsIHB0ciArIDUxMik7DQogICAgICAgIGlmICgoci5mbGFncyAmIDIpICE9IDApIHsgcmVjYmluID0gQW10U2V0dXBCaW5EZXNjcmFtYmxlUmVjb3JkRGF0YShyZWNiaW4pOyB9IC8vIERlLVNjcmFtYmxlIHRoZSByZWNvcmQNCiAgICAgICAgd2hpbGUgKDEpIHsNCg0KICAgICAgICAgICAgLy8gRm9ybWF0IG9mIGEgZGF0YSByZWNvcmQgZW50cnk6DQogICAgICAgICAgICAvLyBNb2R1bGVJZGVudGlmaWVyKDIpICAgICAgICAgICAtIGlkZW50aWZpZXMgdGhlIHRhcmdldCBNRSBtb2R1bGUgZm9yIHRoZSBlbnRyeS4NCiAgICAgICAgICAgIC8vIFZhcmlhYmxlSWRlbnRpZmllcigyKSAgICAgICAgIC0gYW4gZW51bWVyYXRpb24gdmFsdWUgdGhhdCBpZGVudGlmaWVzIHRoZSB2YXJpYWJsZS4gVmFyaWFibGUgaWRlbnRpZmllcnMgYXJlIHVuaXF1ZSB0byBlYWNoIE1vZHVsZUlkZW50aWZpZXIuDQogICAgICAgICAgICAvLyBWYXJpYWJsZUxlbmd0aCgyKSAgICAgICAgICAgICAtIGlzIHRoZSBsZW5ndGggb2YgdGhlIHZhcmlhYmxlIHZhbHVlIGluIGJ5dGVzLg0KICAgICAgICAgICAgLy8gVmFyaWFibGVWYWx1ZSAgICAgICAgICAgICAgICAgLSBpcyB0aGUgdmFsdWUgdG8gYmUgYXNzaWduZWQgdG8gdGhlIHZhcmlhYmxlLg0KDQogICAgICAgICAgICB2YXIgdiA9IHt9Ow0KICAgICAgICAgICAgdi5tb2R1bGVpZCA9IFJlYWRTaG9ydFgocmVjYmluLCBwdHIyKTsNCiAgICAgICAgICAgIHYudmFyaWQgPSBSZWFkU2hvcnRYKHJlY2JpbiwgcHRyMiArIDIpOw0KICAgICAgICAgICAgaWYgKHYubW9kdWxlaWQgPT0gMCB8fCB2LnZhcmlkID09IDApIGJyZWFrOw0KICAgICAgICAgICAgaWYgKEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdKSB7DQogICAgICAgICAgICAgICAgdi5sZW5ndGggPSBSZWFkU2hvcnRYKHJlY2JpbiwgcHRyMiArIDQpOw0KICAgICAgICAgICAgICAgIHYudHlwZSA9IEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdWzBdOw0KICAgICAgICAgICAgICAgIHYuZGVzYyA9IEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdWzFdOw0KICAgICAgICAgICAgICAgIHYudmFsdWUgPSByZWNiaW4uc3Vic3RyaW5nKHB0cjIgKyA4LCBwdHIyICsgOCArIHYubGVuZ3RoKTsNCiAgICAgICAgICAgICAgICBpZiAodi50eXBlID09IDEgJiYgdi5sZW5ndGggPT0gMSkgdi52YWx1ZSA9IHYudmFsdWUuY2hhckNvZGVBdCgwKTsgLy8gMSBieXRlIG51bWJlcg0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKHYudHlwZSA9PSAyICYmIHYubGVuZ3RoID09IDIpIHYudmFsdWUgPSBSZWFkU2hvcnRYKHYudmFsdWUsIDApOyAvLyAyIGJ5dGUgbnVtYmVyDQogICAgICAgICAgICAgICAgZWxzZSBpZiAodi50eXBlID09IDMgJiYgdi5sZW5ndGggPT0gNCkgdi52YWx1ZSA9IFJlYWRJbnRYKHYudmFsdWUsIDApOyAvLyA0IGJ5dGUgbnVtYmVyDQogICAgICAgICAgICAgICAgZWxzZSBpZiAodi50eXBlID09IDQpIHYudmFsdWUgPSBndWlkVG9TdHIocnN0cjJoZXgodi52YWx1ZSkpOyAvLyBHVUlEDQogICAgICAgICAgICAgICAgci52YXJpYWJsZXMucHVzaCh2KTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHB0cjIgKz0gKDggKyAoTWF0aC5mbG9vcigodi5sZW5ndGggKyAzKSAvIDQpICogNCkpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gU29ydCB0aGUgdmFyaWFibGVzDQogICAgICAgIHIudmFyaWFibGVzLnNvcnQoQW10U2V0dXBCaW5WYXJpYWJsZUNvbXBhcmUpOw0KDQogICAgICAgIG9iai5yZWNvcmRzLnB1c2gocik7DQogICAgICAgIHB0ciArPSA1MTI7DQogICAgfQ0KDQogICAgaWYgKGRhdGFSZWNvcmRDb3VudCAhPSBvYmoucmVjb3Jkcy5sZW5ndGgpIHJldHVybjsgLy8gTWlzbWF0Y2ggcmVjb3JkIGNvdW50DQogICAgcmV0dXJuIG9iajsNCn0NCg0KLy8gQ29uc3RydWN0IGEgU2V0dXAuYmluIGZpbGUNCnZhciBBbXRTZXR1cEJpbkVuY29kZSA9IGZ1bmN0aW9uIChvYmopIHsNCiAgICBpZiAob2JqLmZpbGVUeXBlIDwgMSAmJiBvYmouZmlsZVR5cGUgPiBBbXRTZXR1cEJpblNldHVwR3VpZHMubGVuZ3RoKSByZXR1cm4gbnVsbDsNCiAgICB2YXIgb3V0ID0gW10sIHIgPSBBbXRTZXR1cEJpblNldHVwR3VpZHNbb2JqLmZpbGVUeXBlIC0gMV0sIHJlY2NvdW50ID0gMDsNCiAgICByICs9IFNob3J0VG9TdHJYKG9iai5yZWNvcmRDaHVua0NvdW50KTsNCiAgICByICs9IFNob3J0VG9TdHJYKG9iai5yZWNvcmRIZWFkZXJCeXRlQ291bnQpOw0KICAgIHIgKz0gSW50VG9TdHJYKG9iai5yZWNvcmROdW1iZXIpOw0KICAgIHIgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShvYmoubWFqb3JWZXJzaW9uLCBvYmoubWlub3JWZXJzaW9uKTsNCiAgICByICs9IFNob3J0VG9TdHJYKG9iai5mbGFncyk7IC8vIEZsYWdzOiAxID0gRG8gbm90IGNvbnN1bWUgcmVjb3Jkcw0KICAgIHIgKz0gSW50VG9TdHJYKG9iai5yZWNvcmRzLmxlbmd0aCk7DQogICAgciArPSBJbnRUb1N0clgob2JqLmRhdGFSZWNvcmRzQ29uc3VtZWQpOw0KICAgIHIgKz0gU2hvcnRUb1N0clgob2JqLmRhdGFSZWNvcmRDaHVua0NvdW50KTsNCiAgICB3aGlsZSAoci5sZW5ndGggPCA1MTIpIHsgciArPSAiXDAiOyB9IC8vIFBhZCB0aGUgaGVhZGVyDQogICAgb3V0LnB1c2gocik7DQoNCiAgICAvLyBXcml0ZSBlYWNoIHJlY29yZA0KICAgIGZvciAodmFyIGkgaW4gb2JqLnJlY29yZHMpIHsNCiAgICAgICAgdmFyIHIyID0gIiIsIHJlYyA9IG9iai5yZWNvcmRzW2ldOw0KICAgICAgICByMiArPSBJbnRUb1N0clgocmVjLnR5cGVJZGVudGlmaWVyKTsNCiAgICAgICAgcjIgKz0gSW50VG9TdHJYKHJlYy5mbGFncyk7DQogICAgICAgIHIyICs9IEludFRvU3RyWCgwKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVzZXJ2ZWQNCiAgICAgICAgcjIgKz0gSW50VG9TdHJYKDApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBSZXNlcnZlZA0KICAgICAgICByMiArPSBTaG9ydFRvU3RyWCgxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlYy5jaHVua0NvdW50DQogICAgICAgIHIyICs9IFNob3J0VG9TdHJYKDI0KTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVjLmhlYWRlckJ5dGVDb3VudA0KICAgICAgICByMiArPSBJbnRUb1N0clgoKytyZWNjb3VudCk7DQoNCiAgICAgICAgLy8gU29ydCB0aGUgdmFyaWFibGVzDQogICAgICAgIHJlYy52YXJpYWJsZXMuc29ydChBbXRTZXR1cEJpblZhcmlhYmxlQ29tcGFyZSk7DQoNCiAgICAgICAgLyoNCiAgICAgICAgLy8gQ2hhbmdlIHZhcmlhYmxlIHByaW9yaXR5DQogICAgICAgIEFtdFNldHVwQmluTW92ZVRvVG9wKHIudmFyaWFibGVzLCAxLCAzKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFuYWdlYWJpbGl0eSBGZWF0dXJlIFNlbGVjdGlvbg0KICAgICAgICBBbXRTZXR1cEJpbk1vdmVUb1RvcChyLnZhcmlhYmxlcywgMSwgMik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5ldyBNRUJ4IHBhc3N3b3JkDQogICAgICAgIEFtdFNldHVwQmluTW92ZVRvVG9wKHIudmFyaWFibGVzLCAxLCAxKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ3VycmVudCBNRUJ4IHBhc3N3b3JkDQogICAgICAgICovDQoNCiAgICAgICAgLy8gV3JpdGUgZWFjaCB2YXJpYWJsZQ0KICAgICAgICBmb3IgKHZhciBqIGluIHJlYy52YXJpYWJsZXMpIHsNCiAgICAgICAgICAgIHZhciByMyA9ICIiLCB2ID0gcmVjLnZhcmlhYmxlc1tqXSwgZGF0YSA9IHYudmFsdWU7DQogICAgICAgICAgICB2LnR5cGUgPSBBbXRTZXR1cEJpblZhcklkc1t2Lm1vZHVsZWlkXVt2LnZhcmlkXVswXTsgICAgICAgICAgICAgLy8gU2V0IHRoZSBjb3JyZWN0IHR5cGUgaWYgbm90IGFscmVheSBjb25uZWN0DQogICAgICAgICAgICBpZiAoKHYudHlwZSA+IDApICYmICh2LnR5cGUgPCA0KSkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhIG51bWVyaWMgdmFsdWUsIGVuY29kZSBpdCBjb3JyZWN0bHkNCiAgICAgICAgICAgICAgICBkYXRhID0gcGFyc2VJbnQoZGF0YSk7DQogICAgICAgICAgICAgICAgaWYgKHYudHlwZSA9PSAxKSBkYXRhID0gU3RyaW5nLmZyb21DaGFyQ29kZShkYXRhKTsNCiAgICAgICAgICAgICAgICBpZiAodi50eXBlID09IDIpIGRhdGEgPSBTaG9ydFRvU3RyWChkYXRhKTsNCiAgICAgICAgICAgICAgICBpZiAodi50eXBlID09IDMpIGRhdGEgPSBJbnRUb1N0clgoZGF0YSk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAodi50eXBlID09IDQpIHsgZGF0YSA9IGhleDJyc3RyKGd1aWRUb1N0cihkYXRhLnNwbGl0KCctJykuam9pbignJykpLnNwbGl0KCctJykuam9pbignJykpOyB9DQogICAgICAgICAgICByMyArPSBTaG9ydFRvU3RyWCh2Lm1vZHVsZWlkKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTW9kdWxlIElkZW50aWZpZXINCiAgICAgICAgICAgIHIzICs9IFNob3J0VG9TdHJYKHYudmFyaWQpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWYXJpYWJsZSBJZGVudGlmaWVyDQogICAgICAgICAgICByMyArPSBTaG9ydFRvU3RyWChkYXRhLmxlbmd0aCk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVmFyaWFibGUgTGVuZ3RoDQogICAgICAgICAgICByMyArPSBTaG9ydFRvU3RyWCgwKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVzZXJ2ZWQNCiAgICAgICAgICAgIHIzICs9IGRhdGE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBWYXJpYWJsZSBEYXRhDQogICAgICAgICAgICB3aGlsZSAocjMubGVuZ3RoICUgNCAhPSAwKSB7IHIzICs9ICJcMCI7IH0gICAgICAgICAgICAgICAgICAgICAgLy8gUGFkIHRoZSB2YXJpYWJsZQ0KICAgICAgICAgICAgcjIgKz0gcjM7DQogICAgICAgIH0NCg0KICAgICAgICB3aGlsZSAocjIubGVuZ3RoIDwgNTEyKSB7IHIyICs9ICJcMCI7IH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBhZCB0aGUgcmVjb3JkDQogICAgICAgIGlmICgocmVjLmZsYWdzICYgMikgIT0gMCkgeyByMiA9IHIyLnN1YnN0cmluZygwLCAyNCkgKyBBbXRTZXR1cEJpblNjcmFtYmxlUmVjb3JkRGF0YShyMi5zdWJzdHJpbmcoMjQpKTsgfSAvLyBTY3JhbWJsZSB0aGUgcmVjb3JkIHN0YXJ0aW5nIGF0IGJ5dGUgMjQsIGFmdGVyIHRoZSBoZWFkZXINCiAgICAgICAgb3V0LnB1c2gocjIpOw0KICAgIH0NCiAgICByZXR1cm4gb3V0LmpvaW4oJycpOw0KfQ0KDQovLyBVc2VkIHRvIHNvcnQgdmFyaWFibGVzDQpmdW5jdGlvbiBBbXRTZXR1cEJpblZhcmlhYmxlQ29tcGFyZShhLCBiKSB7DQogICAgaWYgKGEubW9kdWxlaWQgPiBiLm1vZHVsZWlkKSByZXR1cm4gMTsNCiAgICBpZiAoYS5tb2R1bGVpZCA8IGIubW9kdWxlaWQpIHJldHVybiAtMTsNCiAgICBpZiAoYS52YXJpZCA+IGIudmFyaWQpIHJldHVybiAxOw0KICAgIGlmIChhLnZhcmlkIDwgYi52YXJpZCkgcmV0dXJuIC0xOw0KICAgIHJldHVybiAwOw0KfQ0KDQovLyBTY3JhbWJsZSBhbmQgdW4tc2NyYW1ibGUgcmVjb3Jkcw0KZnVuY3Rpb24gQW10U2V0dXBCaW5TY3JhbWJsZVJlY29yZERhdGEoZGF0YSkgeyB2YXIgb3V0ID0gIiI7IGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykgeyBvdXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZSgoZGF0YS5jaGFyQ29kZUF0KGkpICsgMTcpICYgMHhGRik7IH0gcmV0dXJuIG91dDsgfQ0KZnVuY3Rpb24gQW10U2V0dXBCaW5EZXNjcmFtYmxlUmVjb3JkRGF0YShkYXRhKSB7IHZhciBvdXQgPSAiIjsgZm9yICh2YXIgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSB7IG91dCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKChkYXRhLmNoYXJDb2RlQXQoaSkgKyAweEVGKSAmIDB4RkYpOyB9IHJldHVybiBvdXQ7IH0NCg0KLy8gRmluZCBhIG1vZHVsZWlkL3ZhcmlkIGluIHRoZSB2YXJpYWJsZSBsaXN0LCBpZiBmb3VuZCwgbW92ZSBpdCB0byB0aGUgdG9wDQovL2Z1bmN0aW9uIEFtdFNldHVwQmluTW92ZVRvVG9wKHZhcmlhYmxlcywgbW9kdWxlaWQsIHZhcmlkKSB7IHZhciBpID0gLTE7IGZvciAodmFyIGogaW4gdmFyaWFibGVzKSB7IGlmICgodmFyaWFibGVzW2pdLm1vZHVsZWlkID09IG1vZHVsZWlkKSAmJiAodmFyaWFibGVzW2pdLnZhcmlkID09IHZhcmlkKSkgeyBpID0gajsgfSB9IGlmIChpID4gMSkgeyBBcnJheUVsZW1lbnRNb3ZlKHZhcmlhYmxlcywgaSwgMCk7IH0gfQ0KLyogRmlsZVNhdmVyLmpzDQogKiBBIHNhdmVBcygpIEZpbGVTYXZlciBpbXBsZW1lbnRhdGlvbi4NCiAqIDEuMS4yMDE1MTAwMw0KICoNCiAqIEJ5IEVsaSBHcmV5LCBodHRwOi8vZWxpZ3JleS5jb20NCiAqIExpY2Vuc2U6IE1JVA0KICogICBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2VsaWdyZXkvRmlsZVNhdmVyLmpzL2Jsb2IvbWFzdGVyL0xJQ0VOU0UubWQNCiAqLw0KDQovKmdsb2JhbCBzZWxmICovDQovKmpzbGludCBiaXR3aXNlOiB0cnVlLCBpbmRlbnQ6IDQsIGxheGJyZWFrOiB0cnVlLCBsYXhjb21tYTogdHJ1ZSwgc21hcnR0YWJzOiB0cnVlLCBwbHVzcGx1czogdHJ1ZSAqLw0KDQovKiEgQHNvdXJjZSBodHRwOi8vcHVybC5lbGlncmV5LmNvbS9naXRodWIvRmlsZVNhdmVyLmpzL2Jsb2IvbWFzdGVyL0ZpbGVTYXZlci5qcyAqLw0KDQp2YXIgc2F2ZUFzID0gc2F2ZUFzIHx8IChmdW5jdGlvbiAodmlldykgew0KICAgICJ1c2Ugc3RyaWN0IjsNCiAgICAvLyBJRSA8MTAgaXMgZXhwbGljaXRseSB1bnN1cHBvcnRlZA0KICAgIGlmICh0eXBlb2YgbmF2aWdhdG9yICE9PSAidW5kZWZpbmVkIiAmJiAvTVNJRSBbMS05XVwuLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7DQogICAgICAgIHJldHVybjsNCiAgICB9DQogICAgdmFyDQoJCSAgZG9jID0gdmlldy5kb2N1bWVudA0KCQkgIC8vIG9ubHkgZ2V0IFVSTCB3aGVuIG5lY2Vzc2FyeSBpbiBjYXNlIEJsb2IuanMgaGFzbid0IG92ZXJyaWRkZW4gaXQgeWV0DQoJCSwgZ2V0X1VSTCA9IGZ1bmN0aW9uICgpIHsNCgkJICAgIHJldHVybiB2aWV3LlVSTCB8fCB2aWV3LndlYmtpdFVSTCB8fCB2aWV3Ow0KCQl9DQoJCSwgc2F2ZV9saW5rID0gZG9jLmNyZWF0ZUVsZW1lbnROUygiaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIsICJhIikNCgkJLCBjYW5fdXNlX3NhdmVfbGluayA9ICJkb3dubG9hZCIgaW4gc2F2ZV9saW5rDQoJCSwgY2xpY2sgPSBmdW5jdGlvbiAobm9kZSkgew0KCQkgICAgdmFyIGV2ZW50ID0gbmV3IE1vdXNlRXZlbnQoImNsaWNrIik7DQoJCSAgICBub2RlLmRpc3BhdGNoRXZlbnQoZXZlbnQpOw0KCQl9DQoJCSwgaXNfc2FmYXJpID0gL1ZlcnNpb25cL1tcZFwuXSsuKlNhZmFyaS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KQ0KCQksIHdlYmtpdF9yZXFfZnMgPSB2aWV3LndlYmtpdFJlcXVlc3RGaWxlU3lzdGVtDQoJCSwgcmVxX2ZzID0gdmlldy5yZXF1ZXN0RmlsZVN5c3RlbSB8fCB3ZWJraXRfcmVxX2ZzIHx8IHZpZXcubW96UmVxdWVzdEZpbGVTeXN0ZW0NCgkJLCB0aHJvd19vdXRzaWRlID0gZnVuY3Rpb24gKGV4KSB7DQoJCSAgICAodmlldy5zZXRJbW1lZGlhdGUgfHwgdmlldy5zZXRUaW1lb3V0KShmdW5jdGlvbiAoKSB7DQoJCSAgICAgICAgdGhyb3cgZXg7DQoJCSAgICB9LCAwKTsNCgkJfQ0KCQksIGZvcmNlX3NhdmVhYmxlX3R5cGUgPSAiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIg0KCQksIGZzX21pbl9zaXplID0gMA0KCQkvLyBTZWUgaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTM3NTI5NyNjNyBhbmQNCgkJLy8gaHR0cHM6Ly9naXRodWIuY29tL2VsaWdyZXkvRmlsZVNhdmVyLmpzL2NvbW1pdC80ODU5MzBhI2NvbW1pdGNvbW1lbnQtODc2ODA0Nw0KCQkvLyBmb3IgdGhlIHJlYXNvbmluZyBiZWhpbmQgdGhlIHRpbWVvdXQgYW5kIHJldm9jYXRpb24gZmxvdw0KCQksIGFyYml0cmFyeV9yZXZva2VfdGltZW91dCA9IDUwMCAvLyBpbiBtcw0KCQksIHJldm9rZSA9IGZ1bmN0aW9uIChmaWxlKSB7DQoJCSAgICB2YXIgcmV2b2tlciA9IGZ1bmN0aW9uICgpIHsNCgkJICAgICAgICBpZiAodHlwZW9mIGZpbGUgPT09ICJzdHJpbmciKSB7IC8vIGZpbGUgaXMgYW4gb2JqZWN0IFVSTA0KCQkgICAgICAgICAgICBnZXRfVVJMKCkucmV2b2tlT2JqZWN0VVJMKGZpbGUpOw0KCQkgICAgICAgIH0gZWxzZSB7IC8vIGZpbGUgaXMgYSBGaWxlDQoJCSAgICAgICAgICAgIGZpbGUucmVtb3ZlKCk7DQoJCSAgICAgICAgfQ0KCQkgICAgfTsNCgkJICAgIGlmICh2aWV3LmNocm9tZSkgew0KCQkgICAgICAgIHJldm9rZXIoKTsNCgkJICAgIH0gZWxzZSB7DQoJCSAgICAgICAgc2V0VGltZW91dChyZXZva2VyLCBhcmJpdHJhcnlfcmV2b2tlX3RpbWVvdXQpOw0KCQkgICAgfQ0KCQl9DQoJCSwgZGlzcGF0Y2ggPSBmdW5jdGlvbiAoZmlsZXNhdmVyLCBldmVudF90eXBlcywgZXZlbnQpIHsNCgkJICAgIGV2ZW50X3R5cGVzID0gW10uY29uY2F0KGV2ZW50X3R5cGVzKTsNCgkJICAgIHZhciBpID0gZXZlbnRfdHlwZXMubGVuZ3RoOw0KCQkgICAgd2hpbGUgKGktLSkgew0KCQkgICAgICAgIHZhciBsaXN0ZW5lciA9IGZpbGVzYXZlclsib24iICsgZXZlbnRfdHlwZXNbaV1dOw0KCQkgICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIgPT09ICJmdW5jdGlvbiIpIHsNCgkJICAgICAgICAgICAgdHJ5IHsNCgkJICAgICAgICAgICAgICAgIGxpc3RlbmVyLmNhbGwoZmlsZXNhdmVyLCBldmVudCB8fCBmaWxlc2F2ZXIpOw0KCQkgICAgICAgICAgICB9IGNhdGNoIChleCkgew0KCQkgICAgICAgICAgICAgICAgdGhyb3dfb3V0c2lkZShleCk7DQoJCSAgICAgICAgICAgIH0NCgkJICAgICAgICB9DQoJCSAgICB9DQoJCX0NCgkJLCBhdXRvX2JvbSA9IGZ1bmN0aW9uIChibG9iKSB7DQoJCSAgICAvLyBwcmVwZW5kIEJPTSBmb3IgVVRGLTggWE1MIGFuZCB0ZXh0IHR5cGVzIChpbmNsdWRpbmcgSFRNTCkNCgkJICAgIGlmICgvXlxzKig/OnRleHRcL1xTKnxhcHBsaWNhdGlvblwveG1sfFxTKlwvXFMqXCt4bWwpXHMqOy4qY2hhcnNldFxzKj1ccyp1dGYtOC9pLnRlc3QoYmxvYi50eXBlKSkgew0KCQkgICAgICAgIHJldHVybiBuZXcgQmxvYihbIlx1ZmVmZiIsIGJsb2JdLCB7IHR5cGU6IGJsb2IudHlwZSB9KTsNCgkJICAgIH0NCgkJICAgIHJldHVybiBibG9iOw0KCQl9DQoJCSwgRmlsZVNhdmVyID0gZnVuY3Rpb24gKGJsb2IsIG5hbWUsIG5vX2F1dG9fYm9tKSB7DQoJCSAgICBpZiAoIW5vX2F1dG9fYm9tKSB7DQoJCSAgICAgICAgYmxvYiA9IGF1dG9fYm9tKGJsb2IpOw0KCQkgICAgfQ0KCQkgICAgLy8gRmlyc3QgdHJ5IGEuZG93bmxvYWQsIHRoZW4gd2ViIGZpbGVzeXN0ZW0sIHRoZW4gb2JqZWN0IFVSTHMNCgkJICAgIHZhcg0KCQkJCSAgZmlsZXNhdmVyID0gdGhpcw0KCQkJCSwgdHlwZSA9IGJsb2IudHlwZQ0KCQkJCSwgYmxvYl9jaGFuZ2VkID0gZmFsc2UNCgkJCQksIG9iamVjdF91cmwNCgkJCQksIHRhcmdldF92aWV3DQoJCQkJLCBkaXNwYXRjaF9hbGwgPSBmdW5jdGlvbiAoKSB7DQoJCQkJICAgIGRpc3BhdGNoKGZpbGVzYXZlciwgIndyaXRlc3RhcnQgcHJvZ3Jlc3Mgd3JpdGUgd3JpdGVlbmQiLnNwbGl0KCIgIikpOw0KCQkJCX0NCgkJCQkvLyBvbiBhbnkgZmlsZXN5cyBlcnJvcnMgcmV2ZXJ0IHRvIHNhdmluZyB3aXRoIG9iamVjdCBVUkxzDQoJCQkJLCBmc19lcnJvciA9IGZ1bmN0aW9uICgpIHsNCgkJCQkgICAgaWYgKHRhcmdldF92aWV3ICYmIGlzX3NhZmFyaSAmJiB0eXBlb2YgRmlsZVJlYWRlciAhPT0gInVuZGVmaW5lZCIpIHsNCgkJCQkgICAgICAgIC8vIFNhZmFyaSBkb2Vzbid0IGFsbG93IGRvd25sb2FkaW5nIG9mIGJsb2IgdXJscw0KCQkJCSAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQoJCQkJICAgICAgICByZWFkZXIub25sb2FkZW5kID0gZnVuY3Rpb24gKCkgew0KCQkJCSAgICAgICAgICAgIHZhciBiYXNlNjREYXRhID0gcmVhZGVyLnJlc3VsdDsNCgkJCQkgICAgICAgICAgICB0YXJnZXRfdmlldy5sb2NhdGlvbi5ocmVmID0gImRhdGE6YXR0YWNobWVudC9maWxlIiArIGJhc2U2NERhdGEuc2xpY2UoYmFzZTY0RGF0YS5zZWFyY2goL1ssO10vKSk7DQoJCQkJICAgICAgICAgICAgZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTsNCgkJCQkgICAgICAgICAgICBkaXNwYXRjaF9hbGwoKTsNCgkJCQkgICAgICAgIH07DQoJCQkJICAgICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChibG9iKTsNCgkJCQkgICAgICAgIGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLklOSVQ7DQoJCQkJICAgICAgICByZXR1cm47DQoJCQkJICAgIH0NCgkJCQkgICAgLy8gZG9uJ3QgY3JlYXRlIG1vcmUgb2JqZWN0IFVSTHMgdGhhbiBuZWVkZWQNCgkJCQkgICAgaWYgKGJsb2JfY2hhbmdlZCB8fCAhb2JqZWN0X3VybCkgew0KCQkJCSAgICAgICAgb2JqZWN0X3VybCA9IGdldF9VUkwoKS5jcmVhdGVPYmplY3RVUkwoYmxvYik7DQoJCQkJICAgIH0NCgkJCQkgICAgaWYgKHRhcmdldF92aWV3KSB7DQoJCQkJICAgICAgICB0YXJnZXRfdmlldy5sb2NhdGlvbi5ocmVmID0gb2JqZWN0X3VybDsNCgkJCQkgICAgfSBlbHNlIHsNCgkJCQkgICAgICAgIHZhciBuZXdfdGFiID0gdmlldy5vcGVuKG9iamVjdF91cmwsICJfYmxhbmsiKTsNCgkJCQkgICAgICAgIGlmIChuZXdfdGFiID09IHVuZGVmaW5lZCAmJiBpc19zYWZhcmkpIHsNCgkJCQkgICAgICAgICAgICAvL0FwcGxlIGRvIG5vdCBhbGxvdyB3aW5kb3cub3Blbiwgc2VlIGh0dHA6Ly9iaXQubHkvMWtaZmZSSQ0KCQkJCSAgICAgICAgICAgIHZpZXcubG9jYXRpb24uaHJlZiA9IG9iamVjdF91cmwNCgkJCQkgICAgICAgIH0NCgkJCQkgICAgfQ0KCQkJCSAgICBmaWxlc2F2ZXIucmVhZHlTdGF0ZSA9IGZpbGVzYXZlci5ET05FOw0KCQkJCSAgICBkaXNwYXRjaF9hbGwoKTsNCgkJCQkgICAgcmV2b2tlKG9iamVjdF91cmwpOw0KCQkJCX0NCgkJCQksIGFib3J0YWJsZSA9IGZ1bmN0aW9uIChmdW5jKSB7DQoJCQkJICAgIHJldHVybiBmdW5jdGlvbiAoKSB7DQoJCQkJICAgICAgICBpZiAoZmlsZXNhdmVyLnJlYWR5U3RhdGUgIT09IGZpbGVzYXZlci5ET05FKSB7DQoJCQkJICAgICAgICAgICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgYXJndW1lbnRzKTsNCgkJCQkgICAgICAgIH0NCgkJCQkgICAgfTsNCgkJCQl9DQoJCQkJLCBjcmVhdGVfaWZfbm90X2ZvdW5kID0geyBjcmVhdGU6IHRydWUsIGV4Y2x1c2l2ZTogZmFsc2UgfQ0KCQkJCSwgc2xpY2UNCgkJICAgIDsNCgkJICAgIGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLklOSVQ7DQoJCSAgICBpZiAoIW5hbWUpIHsNCgkJICAgICAgICBuYW1lID0gImRvd25sb2FkIjsNCgkJICAgIH0NCgkJICAgIGlmIChjYW5fdXNlX3NhdmVfbGluaykgew0KCQkgICAgICAgIG9iamVjdF91cmwgPSBnZXRfVVJMKCkuY3JlYXRlT2JqZWN0VVJMKGJsb2IpOw0KCQkgICAgICAgIHNhdmVfbGluay5ocmVmID0gb2JqZWN0X3VybDsNCgkJICAgICAgICBzYXZlX2xpbmsuZG93bmxvYWQgPSBuYW1lOw0KCQkgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgew0KCQkgICAgICAgICAgICBjbGljayhzYXZlX2xpbmspOw0KCQkgICAgICAgICAgICBkaXNwYXRjaF9hbGwoKTsNCgkJICAgICAgICAgICAgcmV2b2tlKG9iamVjdF91cmwpOw0KCQkgICAgICAgICAgICBmaWxlc2F2ZXIucmVhZHlTdGF0ZSA9IGZpbGVzYXZlci5ET05FOw0KCQkgICAgICAgIH0pOw0KCQkgICAgICAgIHJldHVybjsNCgkJICAgIH0NCgkJICAgIC8vIE9iamVjdCBhbmQgd2ViIGZpbGVzeXN0ZW0gVVJMcyBoYXZlIGEgcHJvYmxlbSBzYXZpbmcgaW4gR29vZ2xlIENocm9tZSB3aGVuDQoJCSAgICAvLyB2aWV3ZWQgaW4gYSB0YWIsIHNvIEkgZm9yY2Ugc2F2ZSB3aXRoIGFwcGxpY2F0aW9uL29jdGV0LXN0cmVhbQ0KCQkgICAgLy8gaHR0cDovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9OTExNTgNCgkJICAgIC8vIFVwZGF0ZTogR29vZ2xlIGVycmFudGx5IGNsb3NlZCA5MTE1OCwgSSBzdWJtaXR0ZWQgaXQgYWdhaW46DQoJCSAgICAvLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9Mzg5NjQyDQoJCSAgICBpZiAodmlldy5jaHJvbWUgJiYgdHlwZSAmJiB0eXBlICE9PSBmb3JjZV9zYXZlYWJsZV90eXBlKSB7DQoJCSAgICAgICAgc2xpY2UgPSBibG9iLnNsaWNlIHx8IGJsb2Iud2Via2l0U2xpY2U7DQoJCSAgICAgICAgYmxvYiA9IHNsaWNlLmNhbGwoYmxvYiwgMCwgYmxvYi5zaXplLCBmb3JjZV9zYXZlYWJsZV90eXBlKTsNCgkJICAgICAgICBibG9iX2NoYW5nZWQgPSB0cnVlOw0KCQkgICAgfQ0KCQkgICAgLy8gU2luY2UgSSBjYW4ndCBiZSBzdXJlIHRoYXQgdGhlIGd1ZXNzZWQgbWVkaWEgdHlwZSB3aWxsIHRyaWdnZXIgYSBkb3dubG9hZA0KCQkgICAgLy8gaW4gV2ViS2l0LCBJIGFwcGVuZCAuZG93bmxvYWQgdG8gdGhlIGZpbGVuYW1lLg0KCQkgICAgLy8gaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTY1NDQwDQoJCSAgICBpZiAod2Via2l0X3JlcV9mcyAmJiBuYW1lICE9PSAiZG93bmxvYWQiKSB7DQoJCSAgICAgICAgbmFtZSArPSAiLmRvd25sb2FkIjsNCgkJICAgIH0NCgkJICAgIGlmICh0eXBlID09PSBmb3JjZV9zYXZlYWJsZV90eXBlIHx8IHdlYmtpdF9yZXFfZnMpIHsNCgkJICAgICAgICB0YXJnZXRfdmlldyA9IHZpZXc7DQoJCSAgICB9DQoJCSAgICBpZiAoIXJlcV9mcykgew0KCQkgICAgICAgIGZzX2Vycm9yKCk7DQoJCSAgICAgICAgcmV0dXJuOw0KCQkgICAgfQ0KCQkgICAgZnNfbWluX3NpemUgKz0gYmxvYi5zaXplOw0KCQkgICAgcmVxX2ZzKHZpZXcuVEVNUE9SQVJZLCBmc19taW5fc2l6ZSwgYWJvcnRhYmxlKGZ1bmN0aW9uIChmcykgew0KCQkgICAgICAgIGZzLnJvb3QuZ2V0RGlyZWN0b3J5KCJzYXZlZCIsIGNyZWF0ZV9pZl9ub3RfZm91bmQsIGFib3J0YWJsZShmdW5jdGlvbiAoZGlyKSB7DQoJCSAgICAgICAgICAgIHZhciBzYXZlID0gZnVuY3Rpb24gKCkgew0KCQkgICAgICAgICAgICAgICAgZGlyLmdldEZpbGUobmFtZSwgY3JlYXRlX2lmX25vdF9mb3VuZCwgYWJvcnRhYmxlKGZ1bmN0aW9uIChmaWxlKSB7DQoJCSAgICAgICAgICAgICAgICAgICAgZmlsZS5jcmVhdGVXcml0ZXIoYWJvcnRhYmxlKGZ1bmN0aW9uICh3cml0ZXIpIHsNCgkJICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLm9ud3JpdGVlbmQgPSBmdW5jdGlvbiAoZXZlbnQpIHsNCgkJICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldF92aWV3LmxvY2F0aW9uLmhyZWYgPSBmaWxlLnRvVVJMKCk7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc2F2ZXIucmVhZHlTdGF0ZSA9IGZpbGVzYXZlci5ET05FOw0KCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGF0Y2goZmlsZXNhdmVyLCAid3JpdGVlbmQiLCBldmVudCk7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXZva2UoZmlsZSk7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIH07DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlci5vbmVycm9yID0gZnVuY3Rpb24gKCkgew0KCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVycm9yID0gd3JpdGVyLmVycm9yOw0KCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVycm9yLmNvZGUgIT09IGVycm9yLkFCT1JUX0VSUikgew0KCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZzX2Vycm9yKCk7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIH07DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICJ3cml0ZXN0YXJ0IHByb2dyZXNzIHdyaXRlIGFib3J0Ii5zcGxpdCgiICIpLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXJbIm9uIiArIGV2ZW50XSA9IGZpbGVzYXZlclsib24iICsgZXZlbnRdOw0KCQkgICAgICAgICAgICAgICAgICAgICAgICB9KTsNCgkJICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLndyaXRlKGJsb2IpOw0KCQkgICAgICAgICAgICAgICAgICAgICAgICBmaWxlc2F2ZXIuYWJvcnQgPSBmdW5jdGlvbiAoKSB7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cml0ZXIuYWJvcnQoKTsNCgkJICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLkRPTkU7DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIH07DQoJCSAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVzYXZlci5yZWFkeVN0YXRlID0gZmlsZXNhdmVyLldSSVRJTkc7DQoJCSAgICAgICAgICAgICAgICAgICAgfSksIGZzX2Vycm9yKTsNCgkJICAgICAgICAgICAgICAgIH0pLCBmc19lcnJvcik7DQoJCSAgICAgICAgICAgIH07DQoJCSAgICAgICAgICAgIGRpci5nZXRGaWxlKG5hbWUsIHsgY3JlYXRlOiBmYWxzZSB9LCBhYm9ydGFibGUoZnVuY3Rpb24gKGZpbGUpIHsNCgkJICAgICAgICAgICAgICAgIC8vIGRlbGV0ZSBmaWxlIGlmIGl0IGFscmVhZHkgZXhpc3RzDQoJCSAgICAgICAgICAgICAgICBmaWxlLnJlbW92ZSgpOw0KCQkgICAgICAgICAgICAgICAgc2F2ZSgpOw0KCQkgICAgICAgICAgICB9KSwgYWJvcnRhYmxlKGZ1bmN0aW9uIChleCkgew0KCQkgICAgICAgICAgICAgICAgaWYgKGV4LmNvZGUgPT09IGV4Lk5PVF9GT1VORF9FUlIpIHsNCgkJICAgICAgICAgICAgICAgICAgICBzYXZlKCk7DQoJCSAgICAgICAgICAgICAgICB9IGVsc2Ugew0KCQkgICAgICAgICAgICAgICAgICAgIGZzX2Vycm9yKCk7DQoJCSAgICAgICAgICAgICAgICB9DQoJCSAgICAgICAgICAgIH0pKTsNCgkJICAgICAgICB9KSwgZnNfZXJyb3IpOw0KCQkgICAgfSksIGZzX2Vycm9yKTsNCgkJfQ0KCQksIEZTX3Byb3RvID0gRmlsZVNhdmVyLnByb3RvdHlwZQ0KCQksIHNhdmVBcyA9IGZ1bmN0aW9uIChibG9iLCBuYW1lLCBub19hdXRvX2JvbSkgew0KCQkgICAgcmV0dXJuIG5ldyBGaWxlU2F2ZXIoYmxvYiwgbmFtZSwgbm9fYXV0b19ib20pOw0KCQl9DQogICAgOw0KICAgIC8vIElFIDEwKyAobmF0aXZlIHNhdmVBcykNCiAgICBpZiAodHlwZW9mIG5hdmlnYXRvciAhPT0gInVuZGVmaW5lZCIgJiYgbmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2IpIHsNCiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChibG9iLCBuYW1lLCBub19hdXRvX2JvbSkgew0KICAgICAgICAgICAgaWYgKCFub19hdXRvX2JvbSkgew0KICAgICAgICAgICAgICAgIGJsb2IgPSBhdXRvX2JvbShibG9iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHJldHVybiBuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYihibG9iLCBuYW1lIHx8ICJkb3dubG9hZCIpOw0KICAgICAgICB9Ow0KICAgIH0NCg0KICAgIEZTX3Byb3RvLmFib3J0ID0gZnVuY3Rpb24gKCkgew0KICAgICAgICB2YXIgZmlsZXNhdmVyID0gdGhpczsNCiAgICAgICAgZmlsZXNhdmVyLnJlYWR5U3RhdGUgPSBmaWxlc2F2ZXIuRE9ORTsNCiAgICAgICAgZGlzcGF0Y2goZmlsZXNhdmVyLCAiYWJvcnQiKTsNCiAgICB9Ow0KICAgIEZTX3Byb3RvLnJlYWR5U3RhdGUgPSBGU19wcm90by5JTklUID0gMDsNCiAgICBGU19wcm90by5XUklUSU5HID0gMTsNCiAgICBGU19wcm90by5ET05FID0gMjsNCg0KICAgIEZTX3Byb3RvLmVycm9yID0NCglGU19wcm90by5vbndyaXRlc3RhcnQgPQ0KCUZTX3Byb3RvLm9ucHJvZ3Jlc3MgPQ0KCUZTX3Byb3RvLm9ud3JpdGUgPQ0KCUZTX3Byb3RvLm9uYWJvcnQgPQ0KCUZTX3Byb3RvLm9uZXJyb3IgPQ0KCUZTX3Byb3RvLm9ud3JpdGVlbmQgPQ0KCQludWxsOw0KDQogICAgcmV0dXJuIHNhdmVBczsNCn0oDQoJICAgdHlwZW9mIHNlbGYgIT09ICJ1bmRlZmluZWQiICYmIHNlbGYNCgl8fCB0eXBlb2Ygd2luZG93ICE9PSAidW5kZWZpbmVkIiAmJiB3aW5kb3cNCgl8fCB0aGlzLmNvbnRlbnQNCikpOw0KLy8gYHNlbGZgIGlzIHVuZGVmaW5lZCBpbiBGaXJlZm94IGZvciBBbmRyb2lkIGNvbnRlbnQgc2NyaXB0IGNvbnRleHQNCi8vIHdoaWxlIGB0aGlzYCBpcyBuc0lDb250ZW50RnJhbWVNZXNzYWdlTWFuYWdlcg0KLy8gd2l0aCBhbiBhdHRyaWJ1dGUgYGNvbnRlbnRgIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIHdpbmRvdw0KDQppZiAodHlwZW9mIG1vZHVsZSAhPT0gInVuZGVmaW5lZCIgJiYgbW9kdWxlLmV4cG9ydHMpIHsNCiAgICBtb2R1bGUuZXhwb3J0cy5zYXZlQXMgPSBzYXZlQXM7DQp9IGVsc2UgaWYgKCh0eXBlb2YgZGVmaW5lICE9PSAidW5kZWZpbmVkIiAmJiBkZWZpbmUgIT09IG51bGwpICYmIChkZWZpbmUuYW1kICE9IG51bGwpKSB7DQogICAgZGVmaW5lKFtdLCBmdW5jdGlvbiAoKSB7DQogICAgICAgIHJldHVybiBzYXZlQXM7DQogICAgfSk7DQp9DQoNCiAgICAgICAgdmFyIHZlcnNpb24gPSAnMC43LjUnOw0KICAgICAgICB2YXIgdXJsdmFycyA9IHt9Ow0KICAgICAgICB2YXIgYW10c3RhY2s7DQogICAgICAgIHZhciB3c3N0YWNrID0gbnVsbDsNCiAgICAgICAgdmFyIEFsbFdzbWFuID0gIkFNVF84MDIxeENyZWRlbnRpYWxDb250ZXh0LEFNVF84MDIxWFByb2ZpbGUsQU1UX0FjdGl2ZUZpbHRlclN0YXRpc3RpY3MsQU1UX0FnZW50UHJlc2VuY2VDYXBhYmlsaXRpZXMsQU1UX0FnZW50UHJlc2VuY2VJbnRlcmZhY2VQb2xpY3ksQU1UX0FnZW50UHJlc2VuY2VTZXJ2aWNlLEFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2csQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ0FjdGlvbixBTVRfQWxhcm1DbG9ja1NlcnZpY2UsSVBTX0FsYXJtQ2xvY2tPY2N1cnJlbmNlLEFNVF9Bc3NldFRhYmxlLEFNVF9Bc3NldFRhYmxlU2VydmljZSxBTVRfQXVkaXRMb2csQU1UX0F1ZGl0UG9saWN5UnVsZSxBTVRfQXV0aG9yaXphdGlvblNlcnZpY2UsQU1UX0Jvb3RDYXBhYmlsaXRpZXMsQU1UX0Jvb3RTZXR0aW5nRGF0YSxBTVRfQ29tcGxleEZpbHRlckVudHJ5QmFzZSxBTVRfQ1JMLEFNVF9DcnlwdG9ncmFwaGljQ2FwYWJpbGl0aWVzLEFNVF9FQUNDcmVkZW50aWFsQ29udGV4dCxBTVRfRW5kcG9pbnRBY2Nlc3NDb250cm9sU2VydmljZSxBTVRfRW52aXJvbm1lbnREZXRlY3Rpb25JbnRlcmZhY2VQb2xpY3ksQU1UX0Vudmlyb25tZW50RGV0ZWN0aW9uU2V0dGluZ0RhdGEsQU1UX0V0aGVybmV0UG9ydFNldHRpbmdzLEFNVF9FdmVudExvZ0VudHJ5LEFNVF9FdmVudE1hbmFnZXJTZXJ2aWNlLEFNVF9FdmVudFN1YnNjcmliZXIsQU1UX0ZpbHRlckVudHJ5QmFzZSxBTVRfRmlsdGVySW5TeXN0ZW1EZWZlbnNlUG9saWN5LEFNVF9HZW5lcmFsU2V0dGluZ3MsQU1UX0dlbmVyYWxTeXN0ZW1EZWZlbnNlQ2FwYWJpbGl0aWVzLEFNVF9IZHI4MDIxRmlsdGVyLEFNVF9IZXVyaXN0aWNQYWNrZXRGaWx0ZXJJbnRlcmZhY2VQb2xpY3ksQU1UX0hldXJpc3RpY1BhY2tldEZpbHRlclNldHRpbmdzLEFNVF9IZXVyaXN0aWNQYWNrZXRGaWx0ZXJTdGF0aXN0aWNzLEFNVF9JbnRlcmZhY2VQb2xpY3ksQU1UX0lQSGVhZGVyc0ZpbHRlcixBTVRfS2VyYmVyb3NTZXR0aW5nRGF0YSxBTVRfTWFuYWdlbWVudFByZXNlbmNlUmVtb3RlU0FQLEFNVF9NZXNzYWdlTG9nLEFNVF9NUFNVc2VybmFtZVBhc3N3b3JkLEFNVF9OZXR3b3JrRmlsdGVyLEFNVF9OZXR3b3JrUG9ydERlZmF1bHRTeXN0ZW1EZWZlbnNlUG9saWN5LEFNVF9OZXR3b3JrUG9ydFN5c3RlbURlZmVuc2VDYXBhYmlsaXRpZXMsQU1UX05ldHdvcmtQb3J0U3lzdGVtRGVmZW5zZVBvbGljeSxBTVRfUENJRGV2aWNlLEFNVF9QRVRDYXBhYmlsaXRpZXMsQU1UX1BFVEZpbHRlckZvclRhcmdldCxBTVRfUEVURmlsdGVyU2V0dGluZyxBTVRfUHJvdmlzaW9uaW5nQ2VydGlmaWNhdGVIYXNoLEFNVF9QdWJsaWNLZXlDZXJ0aWZpY2F0ZSxBTVRfUHVibGljS2V5TWFuYWdlbWVudENhcGFiaWxpdGllcyxBTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2UsQU1UX1B1YmxpY1ByaXZhdGVLZXlQYWlyLEFNVF9SZWRpcmVjdGlvblNlcnZpY2UsQU1UX1JlbW90ZUFjY2Vzc0NhcGFiaWxpdGllcyxBTVRfUmVtb3RlQWNjZXNzQ3JlZGVudGlhbENvbnRleHQsQU1UX1JlbW90ZUFjY2Vzc1BvbGljeUFwcGxpZXNUb01QUyxBTVRfUmVtb3RlQWNjZXNzUG9saWN5UnVsZSxBTVRfUmVtb3RlQWNjZXNzU2VydmljZSxBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSxBTVRfU05NUEV2ZW50U3Vic2NyaWJlcixBTVRfU3RhdGVUcmFuc2l0aW9uQ29uZGl0aW9uLEFNVF9TeXN0ZW1EZWZlbnNlUG9saWN5LEFNVF9TeXN0ZW1EZWZlbnNlUG9saWN5SW5TZXJ2aWNlLEFNVF9TeXN0ZW1EZWZlbnNlU2VydmljZSxBTVRfU3lzdGVtUG93ZXJTY2hlbWUsQU1UX1RoaXJkUGFydHlEYXRhU3RvcmFnZUFkbWluaXN0cmF0aW9uU2VydmljZSxBTVRfVGhpcmRQYXJ0eURhdGFTdG9yYWdlU2VydmljZSxBTVRfVGltZVN5bmNocm9uaXphdGlvblNlcnZpY2UsQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0LEFNVF9UTFNQcm90b2NvbEVuZHBvaW50LEFNVF9UTFNQcm90b2NvbEVuZHBvaW50Q29sbGVjdGlvbixBTVRfVExTU2V0dGluZ0RhdGEsQU1UX1RyYXBUYXJnZXRGb3JTZXJ2aWNlLEFNVF9Vc2VySW5pdGlhdGVkQ29ubmVjdGlvblNlcnZpY2UsQU1UX1dlYlVJU2VydmljZSxBTVRfV2lGaVBvcnRDb25maWd1cmF0aW9uU2VydmljZSxDSU1fQWJzdHJhY3RJbmRpY2F0aW9uU3Vic2NyaXB0aW9uLENJTV9BY2NvdW50LENJTV9BY2NvdW50TWFuYWdlbWVudENhcGFiaWxpdGllcyxDSU1fQWNjb3VudE1hbmFnZW1lbnRTZXJ2aWNlLENJTV9BY2NvdW50T25TeXN0ZW0sQ0lNX0FkbWluRG9tYWluLENJTV9BbGVydEluZGljYXRpb24sQ0lNX0Fzc2lnbmVkSWRlbnRpdHksQ0lNX0Fzc29jaWF0ZWRQb3dlck1hbmFnZW1lbnRTZXJ2aWNlLENJTV9BdXRoZW50aWNhdGlvblNlcnZpY2UsQ0lNX0F1dGhvcml6YXRpb25TZXJ2aWNlLENJTV9CSU9TRWxlbWVudCxDSU1fQklPU0ZlYXR1cmUsQ0lNX0JJT1NGZWF0dXJlQklPU0VsZW1lbnRzLENJTV9Cb290Q29uZmlnU2V0dGluZyxDSU1fQm9vdFNlcnZpY2UsQ0lNX0Jvb3RTZXR0aW5nRGF0YSxDSU1fQm9vdFNvdXJjZVNldHRpbmcsQ0lNX0NhcGFiaWxpdGllcyxDSU1fQ2FyZCxDSU1fQ2hhc3NpcyxDSU1fQ2hpcCxDSU1fQ29sbGVjdGlvbixDSU1fQ29tcG9uZW50LENJTV9Db21wdXRlclN5c3RlbSxDSU1fQ29tcHV0ZXJTeXN0ZW1QYWNrYWdlLENJTV9Db25jcmV0ZUNvbXBvbmVudCxDSU1fQ29uY3JldGVEZXBlbmRlbmN5LENJTV9Db250cm9sbGVyLENJTV9Db29saW5nRGV2aWNlLENJTV9DcmVkZW50aWFsLENJTV9DcmVkZW50aWFsQ29udGV4dCxDSU1fQ3JlZGVudGlhbE1hbmFnZW1lbnRTZXJ2aWNlLENJTV9EZXBlbmRlbmN5LENJTV9EZXZpY2VTQVBJbXBsZW1lbnRhdGlvbixDSU1fRWxlbWVudENhcGFiaWxpdGllcyxDSU1fRWxlbWVudENvbmZvcm1zVG9Qcm9maWxlLENJTV9FbGVtZW50TG9jYXRpb24sQ0lNX0VsZW1lbnRTZXR0aW5nRGF0YSxDSU1fRWxlbWVudFNvZnR3YXJlSWRlbnRpdHksQ0lNX0VsZW1lbnRTdGF0aXN0aWNhbERhdGEsQ0lNX0VuYWJsZWRMb2dpY2FsRWxlbWVudCxDSU1fRW5hYmxlZExvZ2ljYWxFbGVtZW50Q2FwYWJpbGl0aWVzLENJTV9FdGhlcm5ldFBvcnQsQ0lNX0ZhbixDSU1fRmlsdGVyQ29sbGVjdGlvbixDSU1fRmlsdGVyQ29sbGVjdGlvblN1YnNjcmlwdGlvbixDSU1fSG9zdGVkQWNjZXNzUG9pbnQsQ0lNX0hvc3RlZERlcGVuZGVuY3ksQ0lNX0hvc3RlZFNlcnZpY2UsQ0lNX0lkZW50aXR5LENJTV9JRUVFODAyMXhDYXBhYmlsaXRpZXMsQ0lNX0lFRUU4MDIxeFNldHRpbmdzLENJTV9JbmRpY2F0aW9uLENJTV9JbmRpY2F0aW9uU2VydmljZSxDSU1fSW5zdGFsbGVkU29mdHdhcmVJZGVudGl0eSxDSU1fS1ZNUmVkaXJlY3Rpb25TQVAsQ0lNX0xBTkVuZHBvaW50LENJTV9MaXN0ZW5lckRlc3RpbmF0aW9uLENJTV9MaXN0ZW5lckRlc3RpbmF0aW9uV1NNYW5hZ2VtZW50LENJTV9Mb2NhdGlvbixDSU1fTG9nLENJTV9Mb2dFbnRyeSxDSU1fTG9naWNhbERldmljZSxDSU1fTG9naWNhbEVsZW1lbnQsQ0lNX0xvZ2ljYWxQb3J0LENJTV9Mb2dpY2FsUG9ydENhcGFiaWxpdGllcyxDSU1fTG9nTWFuYWdlc1JlY29yZCxDSU1fTWFuYWdlZENyZWRlbnRpYWwsQ0lNX01hbmFnZWRFbGVtZW50LENJTV9NYW5hZ2VkU3lzdGVtRWxlbWVudCxDSU1fTWVkaWFBY2Nlc3NEZXZpY2UsQ0lNX01lbWJlck9mQ29sbGVjdGlvbixDSU1fTWVtb3J5LENJTV9NZXNzYWdlTG9nLENJTV9OZXR3b3JrUG9ydCxDSU1fTmV0d29ya1BvcnRDYXBhYmlsaXRpZXMsQ0lNX05ldHdvcmtQb3J0Q29uZmlndXJhdGlvblNlcnZpY2UsQ0lNX09yZGVyZWRDb21wb25lbnQsQ0lNX093bmluZ0NvbGxlY3Rpb25FbGVtZW50LENJTV9Pd25pbmdKb2JFbGVtZW50LENJTV9QQ0lDb250cm9sbGVyLENJTV9QaHlzaWNhbENvbXBvbmVudCxDSU1fUGh5c2ljYWxFbGVtZW50LENJTV9QaHlzaWNhbEVsZW1lbnRMb2NhdGlvbixDSU1fUGh5c2ljYWxGcmFtZSxDSU1fUGh5c2ljYWxNZW1vcnksQ0lNX1BoeXNpY2FsUGFja2FnZSxDSU1fUG9saWN5LENJTV9Qb2xpY3lBY3Rpb24sQ0lNX1BvbGljeUNvbmRpdGlvbixDSU1fUG9saWN5SW5TeXN0ZW0sQ0lNX1BvbGljeVJ1bGUsQ0lNX1BvbGljeVJ1bGVJblN5c3RlbSxDSU1fUG9saWN5U2V0LENJTV9Qb2xpY3lTZXRBcHBsaWVzVG9FbGVtZW50LENJTV9Qb2xpY3lTZXRJblN5c3RlbSxDSU1fUG93ZXJNYW5hZ2VtZW50Q2FwYWJpbGl0aWVzLENJTV9Qb3dlck1hbmFnZW1lbnRTZXJ2aWNlLENJTV9Qb3dlclN1cHBseSxDSU1fUHJpdmlsZWdlLENJTV9Qcml2aWxlZ2VNYW5hZ2VtZW50Q2FwYWJpbGl0aWVzLENJTV9Qcml2aWxlZ2VNYW5hZ2VtZW50U2VydmljZSxDSU1fUHJvY2Vzc0luZGljYXRpb24sQ0lNX1Byb2Nlc3NvcixDSU1fUHJvdG9jb2xFbmRwb2ludCxDSU1fUHJvdmlkZXNTZXJ2aWNlVG9FbGVtZW50LENJTV9SZWFsaXplcyxDSU1fUmVjb3JkRm9yTG9nLENJTV9SZWNvcmRMb2csQ0lNX1JlZGlyZWN0aW9uU2VydmljZSxDSU1fUmVmZXJlbmNlZFByb2ZpbGUsQ0lNX1JlZ2lzdGVyZWRQcm9maWxlLENJTV9SZW1vdGVBY2Nlc3NBdmFpbGFibGVUb0VsZW1lbnQsQ0lNX1JlbW90ZUlkZW50aXR5LENJTV9SZW1vdGVQb3J0LENJTV9SZW1vdGVTZXJ2aWNlQWNjZXNzUG9pbnQsQ0lNX1JvbGUsQ0lNX1JvbGVCYXNlZEF1dGhvcml6YXRpb25TZXJ2aWNlLENJTV9Sb2xlQmFzZWRNYW5hZ2VtZW50Q2FwYWJpbGl0aWVzLENJTV9Sb2xlTGltaXRlZFRvVGFyZ2V0LENJTV9TQVBBdmFpbGFibGVGb3JFbGVtZW50LENJTV9TZWN1cml0eVNlcnZpY2UsQ0lNX1NlbnNvcixDSU1fU2VydmljZSxDSU1fU2VydmljZUFjY2Vzc0J5U0FQLENJTV9TZXJ2aWNlQWNjZXNzUG9pbnQsQ0lNX1NlcnZpY2VBZmZlY3RzRWxlbWVudCxDSU1fU2VydmljZUF2YWlsYWJsZVRvRWxlbWVudCxDSU1fU2VydmljZVNBUERlcGVuZGVuY3ksQ0lNX1NlcnZpY2VTZXJ2aWNlRGVwZW5kZW5jeSxDSU1fU2V0dGluZ0RhdGEsQ0lNX1NoYXJlZENyZWRlbnRpYWwsQ0lNX1NvZnR3YXJlRWxlbWVudCxDSU1fU29mdHdhcmVGZWF0dXJlLENJTV9Tb2Z0d2FyZUZlYXR1cmVTb2Z0d2FyZUVsZW1lbnRzLENJTV9Tb2Z0d2FyZUlkZW50aXR5LENJTV9TdGF0aXN0aWNhbERhdGEsQ0lNX1N0b3JhZ2VFeHRlbnQsQ0lNX1N5c3RlbSxDSU1fU3lzdGVtQklPUyxDSU1fU3lzdGVtQ29tcG9uZW50LENJTV9TeXN0ZW1EZXZpY2UsQ0lNX1N5c3RlbVBhY2thZ2luZyxDSU1fVXNlT2ZMb2csQ0lNX1dhdGNoZG9nLENJTV9XaUZpRW5kcG9pbnQsQ0lNX1dpRmlFbmRwb2ludENhcGFiaWxpdGllcyxDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MsQ0lNX1dpRmlQb3J0LENJTV9XaUZpUG9ydENhcGFiaWxpdGllcyxJUFNfQWRtaW5Qcm92aXNpb25pbmdSZWNvcmQsSVBTX0NsaWVudFByb3Zpc2lvbmluZ1JlY29yZCxJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlLElQU19Ib3N0SVBTZXR0aW5ncyxJUFNfSFRUUFByb3h5U2VydmljZSxJUFNfSFRUUFByb3h5QWNjZXNzUG9pbnQsSVBTX0lkZXJTZXNzaW9uVXNpbmdQb3J0LElQU19JUHY2UG9ydFNldHRpbmdzLElQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhLElQU19Ldm1TZXNzaW9uVXNpbmdQb3J0LElQU19NYW51YWxQcm92aXNpb25pbmdSZWNvcmQsSVBTX09wdEluU2VydmljZSxJUFNfUHJvdmlzaW9uaW5nQXVkaXRSZWNvcmQsSVBTX1Byb3Zpc2lvbmluZ1JlY29yZExvZyxJUFNfUmFzU2Vzc2lvblVzaW5nUG9ydCxJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UsSVBTX1NjcmVlblNldHRpbmdEYXRhLElQU19TZWNJT1NlcnZpY2UsSVBTX1Nlc3Npb25Vc2luZ1BvcnQsSVBTX1NvbFNlc3Npb25Vc2luZ1BvcnQsSVBTX1RMU1Byb3Zpc2lvbmluZ1JlY29yZCxJUFNfV2F0Y2hEb2dBY3Rpb24iLnNwbGl0KCcsJyk7DQogICAgICAgIHZhciBkaXNjb25uZWN0dXJsID0gbnVsbDsNCiAgICAgICAgdmFyIGN1cnJlbnRWaWV3ID0gMDsNCiAgICAgICAgdmFyIExvYWRpbmdIdG1sID0gIjxkaXYgc3R5bGU9dGV4dC1hbGlnbjpjZW50ZXI7cGFkZGluZy10b3A6MjBweD5Mb2FkaW5nLi4uPGRpdj4iOw0KICAgICAgICB2YXIgYW10dmVyc2lvbiA9IDA7DQogICAgICAgIHZhciBhbXR2ZXJzaW9ubWluID0gMDsNCiAgICAgICAgdmFyIGFtdEZpcnN0UHVsbCA9IDA7IC8vIEJpdG1hc2ssIFNldCB0aGlzIHdoZW4gdGhlIGZpcnN0IHB1bGwgcmVxdWVzdCBpcyBtYWRlIG9uIGEgZGV2aWNlOiAxID0gSGFyZHdhcmVJbmZvLCAyID0gV2lyZWxlc3NJbmZvLCA0ID0gU3lzdGVtRGVmZW5zZSwgOCA9IFN0b3JhZ2UsIDE2ID0gRXZlbnRMb2csIDMyID0gQXVkaXRMb2cNCg0KICAgICAgICB2YXIgYW10d2lyZWxlc3NpZiA9IC0xOyAvLyBTZXQgdG8gdGhlIGludGVyZmFjZSBpbmRleCBmb3IgdGhlIHdpcmVsZXNzIGludGVyZmFjZSwgLTEgaWYgbm8gd2lyZWxlc3MuDQogICAgICAgIHZhciB3ZWJjb21waWxlcmZlYXR1cmVzID0gWydBZ2VudFByZXNlbmNlJywnQWxhcm1zJywnQXVkaXRMb2cnLCdDZXJ0aWZpY2F0ZXMnLCdDb21wdXRlclNlbGVjdG9yVG9vbGJhcicsJ0Rlc2t0b3AtU2V0dGluZ3MnLCdFdmVudExvZycsJ0ZpbGVTYXZlcicsJ0hhcmR3YXJlSW5mbycsJ0xvb2stQ29tbWFuZGVyJywnTW9kZS1MTVMnLCdOZXR3b3JrU2V0dGluZ3MnLCdSZW1vdGVBY2Nlc3MnLCdTY3JpcHRpbmcnLCdTY3JpcHRpbmctRWRpdG9yJywnU3RvcmFnZScsJ1N5c3RlbURlZmVuc2UnLCdVU0JTZXR1cCcsJ1dpcmVsZXNzJ107DQogICAgICAgIHZhciBTdGF0dXNTdHJzID0gWydEaXNjb25uZWN0ZWQnLCAnQ29ubmVjdGluZy4uLicsICdTZXR1cC4uLicsICdDb25uZWN0ZWQnXTsNCg0KICAgICAgICB2YXIgc2NyaXB0c3RhdGU7DQoNCiAgICAgICAgdmFyIHNldHVwYmluOw0KICAgICAgICB2YXIgc2VsZWN0ZWRSZWNvcmQgPSAwOw0KICAgICAgICB2YXIgc2VsZWN0ZWRWYXJpYWJsZSA9IDA7DQoNCiAgICAgICAgdmFyIGFtdFBvd2VyUG9sbFRpbWVyID0gbnVsbDsNCg0KICAgICAgICB2YXIgbG1zID0gbnVsbDsNCiAgICAgICAgdmFyIHQsIHQyLCByc2VwYXNzID0gbnVsbDsgLy8gR2xvYmFsIHRlbXBvcmFyeSB2YXJpYWJsZQ0KDQogICAgICAgIGZ1bmN0aW9uIHN0YXJ0dXAoKSB7DQogICAgICAgICAgICAvLyBUaGlzIGlzIGEgYml0IGZyZWVreSwgYnV0IGFsbCBIVE1MIGlucHV0IGVsZW1lbnRzIGFyZSBqdXN0IGdvaW5nIHRvIGJlIGFjY2Vzc2libGUgZGlyZWN0bHkuDQogICAgICAgICAgICB2YXIgYWxsZWxlbWVudHMgPSBkb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnaW5wdXQnKTsNCiAgICAgICAgICAgIGZvciAodCA9IDA7IHQgPCBhbGxlbGVtZW50cy5sZW5ndGg7IHQrKykgeyBpZiAoYWxsZWxlbWVudHNbdF0uaWQpIHsgd2luZG93W2FsbGVsZW1lbnRzW3RdLmlkXSA9IGFsbGVsZW1lbnRzW3RdOyB9IH0NCg0KDQogICAgICAgICAgICB1cmx2YXJzID0gZ2V0VXJsVmFycygpOw0KDQoNCg0KICAgICAgICAgICAgLy8gU2V0dXAgTE1TDQogICAgICAgICAgICBsbXMgPSBDcmVhdGVMbXNDb250cm9sKCk7DQogICAgICAgICAgICBsbXMub25TdGF0ZUNoYW5nZWQgPSBsbXNDaGFuZ2VkU3RhdGU7DQogICAgICAgICAgICBsbXMub25EYXRhID0gbG1zT25EYXRhOw0KICAgICAgICAgICAgbG1zLlN0YXJ0KCk7DQogICAgICAgICAgICBRSCgnaWRfbG1zRGF0YScsIExvYWRpbmdIdG1sKTsNCiAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhJywgJycpOw0KICAgICAgICAgICAgUUgoJ2lkX2NvbXB1dGVybmFtZScsICdDb25maWd1cmF0aW9uIENvbnNvbGUgdicgKyB2ZXJzaW9uKTsNCiAgICAgICAgICAgIGdvKDEwMSk7DQogICAgICAgICAgICBsbXNSZWZyZXNoKCk7DQoNCg0KDQoNCiAgICAgICAgICAgIC8vIE1hc3RlciBkcmFnICYgZHJvcA0KICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ292ZXInLCBoYWx0RXZlbnQsIGZhbHNlKTsNCiAgICAgICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdsZWF2ZScsIGhhbHRFdmVudCwgZmFsc2UpOw0KICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignZHJvcCcsIGRvY3VtZW50RmlsZVNlbGVjdEhhbmRsZXIsIGZhbHNlKTsNCg0KDQogICAgICAgICAgICAvLyBTZXR1cCBUZXJtaW5hbCBkcmFnICYgZHJvcA0KICAgICAgICAgICAgUSgncDE2JykuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ292ZXInLCBoYWx0RXZlbnQsIGZhbHNlKTsNCiAgICAgICAgICAgIFEoJ3AxNicpLmFkZEV2ZW50TGlzdGVuZXIoJ2RyYWdsZWF2ZScsIGhhbHRFdmVudCwgZmFsc2UpOw0KICAgICAgICAgICAgUSgncDE2JykuYWRkRXZlbnRMaXN0ZW5lcignZHJvcCcsIGNlcnRfRmlsZVNlbGVjdEhhbmRsZXIsIGZhbHNlKTsNCg0KDQoNCg0KDQoNCg0KDQogICAgICAgICAgICB1c2JfZGlzcGxheVNldHVwQmluKCk7DQoNCiAgICAgICAgICAgIC8vIEFkZCBhbGwgcG9zc2libGUgdmFyaWFibGUgdHlwZXMgdG8gZGlhbG9nIDE2DQogICAgICAgICAgICB2YXIgb3B0aW9ucyA9ICcnOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBBbXRTZXR1cEJpblZhcklkcykgeyBmb3IgKHZhciBqIGluIEFtdFNldHVwQmluVmFySWRzW2ldKSB7IG9wdGlvbnMgKz0gJzxvcHRpb24gdmFsdWU9IicgKyBpICsgIi0iICsgaiArICciPicgKyBBbXRTZXR1cEJpblZhcklkc1tpXVtqXVsxXSB9IH0NCiAgICAgICAgICAgIFFIKCdkMTZ0eXBlJywgb3B0aW9ucyk7DQoNCiAgICAgICAgICAgIGRvY3VtZW50Lm9ua2V5dXAgPSBoYW5kbGVLZXlVcDsNCiAgICAgICAgICAgIGRvY3VtZW50Lm9ua2V5ZG93biA9IGhhbmRsZUtleURvd247DQogICAgICAgICAgICBkb2N1bWVudC5vbmtleXByZXNzID0gaGFuZGxlS2V5UHJlc3M7DQogICAgICAgICAgICB3aW5kb3cub25yZXNpemUgPSBjZW50ZXI7DQogICAgICAgICAgICBjZW50ZXIoKTsNCg0KDQoNCg0KICAgICAgICAgICAgc2NyaXB0TG9hZFN0YXJ0aW5nQmxvY2tzKCk7DQoNCg0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZG9jdW1lbnRGaWxlU2VsZWN0SGFuZGxlcihlKSB7DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQogICAgICAgICAgICBpZiAoZS5kYXRhVHJhbnNmZXIgPT0gbnVsbCB8fCBlLmRhdGFUcmFuc2Zlci5maWxlcy5sZW5ndGggIT0gMSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIGYgPSBudWxsLCBmaWxlbmFtZSA9IGUuZGF0YVRyYW5zZmVyLmZpbGVzWzBdLm5hbWUudG9Mb3dlckNhc2UoKTsNCg0KICAgICAgICAgICAgaWYgKGN1cnJlbnRWaWV3ID09IDIxKSB7IFVwbG9hZFRvU3RvcmFnZShlLmRhdGFUcmFuc2Zlci5maWxlc1swXSwgZmlsZW5hbWUpOyByZXR1cm47IH0NCg0KICAgICAgICAgICAgaWYgKGN1cnJlbnRWaWV3ID09IDEwMiAmJiBmaWxlbmFtZS5lbmRzV2l0aCgnLmJpbicpKSB7IGYgPSB1c2Jfb25TZXR1cEJpblJlYWQ7IH0NCg0KICAgICAgICAgICAgaWYgKHdzc3RhY2sgIT0gbnVsbCAmJiAoZmlsZW5hbWUuZW5kc1dpdGgoJy5tZXNjcmlwdCcpIHx8IGZpbGVuYW1lLmVuZHNXaXRoKCcubWVibG9ja3MnKSkpIHsgZiA9IHNjcmlwdF9vblNjcmlwdFJlYWQ7IH0NCiAgICAgICAgICAgIGlmIChmICE9IG51bGwpIHsgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7IHJlYWRlci5vbmxvYWQgPSBmOyByZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKGUuZGF0YVRyYW5zZmVyLmZpbGVzWzBdKTsgfQ0KICAgICAgICB9DQoNCg0KDQoNCiAgICAgICAgLy8gQ2FsbGVkIHdoZW4gdGhlIExNUyBjb250cm9sIGNoYW5uZWwgY2hhbmdlcyBzdGF0ZQ0KICAgICAgICBmdW5jdGlvbiBsbXNDaGFuZ2VkU3RhdGUoc2VuZGVyLCBzdGF0ZSkNCiAgICAgICAgew0KICAgICAgICAgICAgLy9jb25zb2xlLmxvZygiTE1TIENvbnRyb2wgQ2hhbm5lbCBTdGF0ZTogIiArIHN0YXRlKTsNCiAgICAgICAgICAgIGlmIChzdGF0ZSA9PSAwKSB7IA0KICAgICAgICAgICAgICAgIHNldERpYWxvZ01vZGUoKTsNCiAgICAgICAgICAgICAgICBRVignaWRfbG1zVG9vbEJhckNvbnRlbnQnLCBmYWxzZSk7DQogICAgICAgICAgICAgICAgUUgoJ2lkX2xtc0RhdGEnLCAnPGRpdiBzdHlsZT10ZXh0LWFsaWduOmNlbnRlcjtwYWRkaW5nLXRvcDoyMHB4Pk1pY3JvTE1TIGRpc2Nvbm5lY3RlZC48ZGl2PicpOw0KICAgICAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhMicsICcnKTsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RhdGUgPT0gMikgeyBRVignaWRfbG1zVG9vbEJhckNvbnRlbnQnLCB0cnVlKTsgbG1zUmVmcmVzaCgpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBsbXNMb2dpbigpIHsgd2luZG93LmxvY2F0aW9uLmhyZWYgPSAnL2F1dGhpbmRleC5odG1sJzsgfQ0KDQogICAgICAgIHZhciBsbXNQcm92aXNpb25pbmdTdGF0ZXMgPSBbJ1ByZS1Qcm92aXNpb25pbmcnLCAnSW4tUHJvdmlzaW9uaW5nJywgJ1Bvc3QtUHJvdmlzaW9uaW5nJ107DQogICAgICAgIHZhciBsbXNQcm92aXNpb25pbmdNb2RlcyA9IFsnTm9uZScsICdFbnRlcnByaXNlIE1vZGUnLCAnU21hbGwgQnVpc25lc3MgTW9kZScsICdSZW1vdGUgQXNzaXN0YW5jZSBNb2RlJ107DQogICAgICAgIHZhciBsbXNNZUluZm8gPSBudWxsOw0KICAgICAgICB2YXIgbG1zVGVtcCA9IG51bGw7DQogICAgICAgIHZhciBsbXNOb3RpZmljYXRpb25zID0gbnVsbDsNCg0KICAgICAgICAvLyBDYWxsZWQgd2hlbiBkYXRhIGlzIHJlY2VpdmVkIG9uIHRoZSBMTVMgY29udHJvbCBjaGFubmVsDQogICAgICAgIGZ1bmN0aW9uIGxtc09uRGF0YShzZW5kZXIsIGRhdGEpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBjbWRpZCA9IFJlYWRTaG9ydFgoZGF0YSwgMCk7DQogICAgICAgICAgICAvL2NvbnNvbGUubG9nKCJMTVMgQ29udHJvbCBDaGFubmVsIERhdGE6ICIgKyBkYXRhICsgIiwgY21kaWQ6IiArIGNtZGlkKTsNCg0KICAgICAgICAgICAgc3dpdGNoICgrY21kaWQpIHsNCiAgICAgICAgICAgICAgICBjYXNlIDE6IHsgLy8gTUUgSW5mb3JtYXRpb24NCiAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZyhkYXRhLnN1YnN0cmluZygyKSk7DQogICAgICAgICAgICAgICAgICAgIHZhciBtZWluZm8gPSBKU09OLnBhcnNlKGRhdGEuc3Vic3RyaW5nKDIpKTsNCiAgICAgICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0xvZ2luQnV0dG9uJywgbWVpbmZvWydMb2dpbk1vZGUnXSA9PSAxKTsNCg0KICAgICAgICAgICAgICAgICAgICAvLyBJZiBJbnRlbCBBTVQgaXMgaW4tYmV0d2VlbiBzdGF0ZXMsIHJlbG9hZCBkYXRhIGluIGEgZmV3IHNlY29uZHMuDQogICAgICAgICAgICAgICAgICAgIGlmICgobWVpbmZvWydUcnVzdGVkSGFzaGVzJ10gIT0gbnVsbCkgJiYgKG1laW5mb1snUHJvdmlzaW9uaW5nTW9kZSddID09IC04NTg5OTM0NjApKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBRVignaWRfbG1zQ29uZmlndXJlQnV0dG9uJywgZmFsc2UpOw0KICAgICAgICAgICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0FjdGl2YXRlQnV0dG9uJywgZmFsc2UpOw0KICAgICAgICAgICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0RlYWN0aXZhdGVCdXR0b24nLCBmYWxzZSk7DQogICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGxtc1JlZnJlc2gsIDEwMDApOw0KICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAgICAgbG1zTWVJbmZvID0gbWVpbmZvOw0KICAgICAgICAgICAgICAgICAgICBpZiAobWVpbmZvWydQcm92aXNpb25pbmdTdGF0ZSddID09IG51bGwpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhJywgJzxkaXYgc3R5bGU9dGV4dC1hbGlnbjpjZW50ZXI7cGFkZGluZy10b3A6MjBweD5JbnRlbCZyZWc7IEFNVCBub3QgZm91bmQ8ZGl2PicpOw0KICAgICAgICAgICAgICAgICAgICAgICAgUUgoJ2lkX2xtc0RhdGEyJywgJycpOw0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgbWVpbmZvWydGbGFncyddID0gK21laW5mb1snRmxhZ3MnXTsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHggPSAnPGgyPkN1cnJlbnQgU3RhdHVzPC9oMj4nOw0KICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZVN0YXJ0KCk7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAobWVpbmZvWydQcm92aXNpb25pbmdTdGF0ZSddICE9IDIpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkFjdGl2YXRpb24gc3RhdGUiLCBsbXNQcm92aXNpb25pbmdTdGF0ZXNbbWVpbmZvWydQcm92aXNpb25pbmdTdGF0ZSddXSk7DQogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtZWluZm9bJ0ZsYWdzJ10gJiAyKSB7IHggKz0gVGFibGVFbnRyeSgnQWN0aXZhdGlvbiBzdGF0ZScsICdBY3RpdmF0ZWQgaW4gQ2xpZW50IENvbnRyb2wgTW9kZScpOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAobWVpbmZvWydGbGFncyddICYgNCkgeyB4ICs9IFRhYmxlRW50cnkoJ0FjdGl2YXRpb24gc3RhdGUnLCAnQWN0aXZhdGVkIGluIEFkbWluIENvbnRyb2wgTW9kZScpOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7IHggKz0gVGFibGVFbnRyeSgnQWN0aXZhdGlvbiBzdGF0ZScsICdBY3RpdmF0ZWQsICcgKyBsbXNQcm92aXNpb25pbmdNb2Rlc1ttZWluZm9bJ1Byb3Zpc2lvbmluZ01vZGUnXV0pOyB9DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoJ0ludGVsJnJlZzsgQU1UIHZlcnNpb24nLCBhZGRMaW5rKG1laW5mb1snVmVyc2lvbnMnXVsnQU1UJ10sICdsbXNTaG93VmVyc2lvbnNEbGcoKScpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtZWluZm9bJ01laVZlcnNpb24nXSAhPSBudWxsKSB7IHggKz0gVGFibGVFbnRyeSgnSW50ZWwmcmVnOyBNRUkgZHJpdmVyIHZlcnNpb24nLCBtZWluZm9bJ01laVZlcnNpb24nXSk7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbmQoKTsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1laW5mb1snUHJvdmlzaW9uaW5nU3RhdGUnXSAhPSAyKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSAnPGgyPkFjdGl2YXRpb24gSW5mb3JtYXRpb248L2gyPic7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZVN0YXJ0KCk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG1laW5mb1snRG5zU3VmZml4J10pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCdUcnVzdGVkIEROUyBzdWZmaXgnLCBtZWluZm9bJ0Ruc1N1ZmZpeCddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoJ1RydXN0ZWQgRE5TIHN1ZmZpeCcsICc8aT5Ob3QgU2V0PC9pPicpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWVpbmZvWydUcnVzdGVkSGFzaGVzJ10gIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobWVpbmZvWydUcnVzdGVkSGFzaGVzJ10ubGVuZ3RoID09IDEpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgnVHJ1c3RlZCBoYXNoZXMnLCBhZGRMaW5rKG1laW5mb1snVHJ1c3RlZEhhc2hlcyddLmxlbmd0aCArICcgaGFzaCcsICdsbXNTaG93VHJ1c3RlZEhhc2hlc0RsZygpJykpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCdUcnVzdGVkIGhhc2hlcycsIGFkZExpbmsobWVpbmZvWydUcnVzdGVkSGFzaGVzJ10ubGVuZ3RoICsgJyBoYXNoZXMnLCAnbG1zU2hvd1RydXN0ZWRIYXNoZXNEbGcoKScpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW5kKCk7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhJywgeCk7DQogICAgICAgICAgICAgICAgICAgICAgICBRVignaWRfbG1zRGF0YTInLCB0cnVlKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGxtc05vdGlmaWNhdGlvbnMgPSBtZWluZm9bJ05vdGlmaWNhdGlvbnMnXS5yZXZlcnNlKCk7DQogICAgICAgICAgICAgICAgICAgICAgICBsbXNSZWZyZXNoTm90aWZpY2F0aW9ucygpOw0KICAgICAgICAgICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0NvbmZpZ3VyZUJ1dHRvbicsIChtZWluZm9bJ1Byb3Zpc2lvbmluZ1N0YXRlJ10gPT0gMikpOyAvLyBPbmx5IGRpc3BsYXkgdGhlICJMb2dpbi4uLiIgYnV0dG9uIGlmIEludGVsIEFNVCBpcyBpbiBwb3N0LXByb3Zpc2lvbmluZyBzdGF0ZS4NCiAgICAgICAgICAgICAgICAgICAgICAgIFFWKCdpZF9sbXNBY3RpdmF0ZUJ1dHRvbicsIChtZWluZm9bJ1Byb3Zpc2lvbmluZ1N0YXRlJ10gPT0gMCkgJiYgKG1laW5mb1snTG9naW5Nb2RlJ10gPj0gMikpOyAvLyBPbmx5IGRpc3BsYXkgdGhlICJBY3RpdmF0ZS4uLiIgYnV0dG9uIGlmIEludGVsIEFNVCBpcyBpbiBwcmUtcHJvdmlzaW9uaW5nIHN0YXRlIGFuZCB3ZSBhcmUgYWRybWluaXN0cmF0b3IuDQogICAgICAgICAgICAgICAgICAgICAgICBRVignaWRfbG1zRGVhY3RpdmF0ZUJ1dHRvbicsIChtZWluZm9bJ1Byb3Zpc2lvbmluZ1N0YXRlJ10gPT0gMikgJiYgKG1laW5mb1snRmxhZ3MnXSAmIDIpICYmIChtZWluZm9bJ0xvZ2luTW9kZSddID49IDIpKTsgLy8gT25seSBkaXNwbGF5IHRoZSAiRGVhY3RpdmF0ZS4uLiIgYnV0dG9uIGlmIEludGVsIEFNVCBpcyBpbiBwb3J0LXByb3Zpc2lvbmluZyBzdGF0ZSAmIGluIGNsaWVudCBjb250cm9sIG1vZGUgJiB3ZSBhcmUgYWRybWluaXN0cmF0b3IuDQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGNhc2UgMjogeyAvLyBJbnRlbCBNRSBVbi1Qcm92aXNpb25pbmcNCiAgICAgICAgICAgICAgICAgICAgbG1zRGVhY3RpdmF0ZVgyKFJlYWRJbnRYKGRhdGEsIDIpKTsNCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGNhc2UgMzogeyAvLyBJbnRlbCBNRSBTeXN0ZW0gQWNjb3VudCBJbmZvcm1hdGlvbg0KICAgICAgICAgICAgICAgICAgICB2YXIgc3RhdHVzID0gUmVhZEludFgoZGF0YSwgMik7DQogICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnSW50ZWwmcmVnOyBBTVQgQWN0aXZhdGlvbicsICdGYWlsZWQgdG8gZ2V0IGFjY291bnQgaW5mb3JtYXRpb24sIHN0YXR1cyAnICsgc3RhdHVzKTsNCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtZXVzZXIgPSBkYXRhLnN1YnN0cmluZyg2LCBkYXRhLmluZGV4T2YoJ1wwJywgNikpOw0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIG1lcGFzcyA9IGRhdGEuc3Vic3RyaW5nKDM5LCBkYXRhLmluZGV4T2YoJ1wwJywgMzkpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIFFIKCdpZF9kaWFsb2dNZXNzYWdlJywgJ0ZldGNoaW5nIGFjdGl2YXRpb24gc3RhdHVzLi4uJyk7DQogICAgICAgICAgICAgICAgICAgICAgICB3c3N0YWNrID0gV3NtYW5TdGFja0NyZWF0ZVNlcnZpY2UoImxvY2FsaG9zdCIsIDE2OTkyLCBtZXVzZXIsIG1lcGFzcywgZmFsc2UpOw0KICAgICAgICAgICAgICAgICAgICAgICAgYW10c3RhY2sgPSBBbXRTdGFja0NyZWF0ZVNlcnZpY2Uod3NzdGFjayk7DQogICAgICAgICAgICAgICAgICAgICAgICBhbXRzdGFjay5vblByb2Nlc3NDaGFuZ2VkID0gb25Qcm9jZXNzQ2hhbmdlZDsNCiAgICAgICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLkJhdGNoRW51bShudWxsLCBbJypBTVRfR2VuZXJhbFNldHRpbmdzJywgJypJUFNfSG9zdEJhc2VkU2V0dXBTZXJ2aWNlJ10sIGxtc0FjdGl2YXRpb25YMSk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGNhc2UgOTogeyAvLyBOZXcgbm90aWZpY2F0aW9uDQogICAgICAgICAgICAgICAgICAgIHZhciBub3RpZmljYXRpb24gPSBKU09OLnBhcnNlKGRhdGEuc3Vic3RyaW5nKDIpKTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGxtc05vdGlmaWNhdGlvbnMgPT0gbnVsbCkgeyBsbXNOb3RpZmljYXRpb25zID0gW107IH0NCiAgICAgICAgICAgICAgICAgICAgbG1zTm90aWZpY2F0aW9ucy51bnNoaWZ0KG5vdGlmaWNhdGlvbik7DQogICAgICAgICAgICAgICAgICAgIGxtc1JlZnJlc2hOb3RpZmljYXRpb25zKCk7DQogICAgICAgICAgICAgICAgICAgIGlmICgobm90aWZpY2F0aW9uLmNvZGUgPT0gJ2lBTVQwMDU1LTAnKSB8fCAobm90aWZpY2F0aW9uLmNvZGUgPT0gJ2lBTVQwMDU1LTEnKSB8fCAobm90aWZpY2F0aW9uLmNvZGUgPT0gJ2lBTVQwMDU1LTInKSkgeyBzZXREaWFsb2dNb2RlKCk7IGxtc1JlZnJlc2goKTsgfQ0KICAgICAgICAgICAgICAgICAgICBicmVhazsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBsbXNSZWZyZXNoTm90aWZpY2F0aW9ucygpIHsNCiAgICAgICAgICAgIHZhciB4ID0gJzxoMj5Ob3RpZmljYXRpb25zPC9oMj4nICsgVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgaWYgKGxtc05vdGlmaWNhdGlvbnMgJiYgbG1zTm90aWZpY2F0aW9ucy5sZW5ndGggPiAwKSB7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBsbXNOb3RpZmljYXRpb25zKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBuID0gbG1zTm90aWZpY2F0aW9uc1tpXSwgdiA9IG4uc3RyOw0KICAgICAgICAgICAgICAgICAgICBpZiAobi5jb2RlICE9ICdpQU1UMDA1MC0zMicpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2LmluZGV4T2YoJ1VzZXIgTm90aWZpY2F0aW9uIEFsZXJ0IC0gJykgPT0gMCkgeyB2ID0gdi5zdWJzdHJpbmcoMjYpOyB9DQogICAgICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkobmV3IERhdGUobi5kYXRlKS50b0xvY2FsZVN0cmluZygpLCB2KTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgeCArPSAiPHRyPjx0ZCBzdHlsZT1wYWRkaW5nOjhweD48aT5ObyBub3RpZmljYXRpb25zIGZvdW5kLjwvaT48dGQ+IjsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoKTsNCiAgICAgICAgICAgIFFIKCdpZF9sbXNEYXRhMicsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gbG1zQWN0aXZhdGlvblgxKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdJbnRlbCZyZWc7IEFNVCBBY3RpdmF0aW9uJywgJ0ZhaWxlZCB0byBmZXRjaCBhY3RpdmF0aW9uIHN0YXR1cywgc3RhdHVzICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZXNbJ0lQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2UnXS5yZXNwb25zZVsnQWxsb3dlZENvbnRyb2xNb2RlcyddLmxlbmd0aCAhPSAyKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnSW50ZWwmcmVnOyBBTVQgQWN0aXZhdGlvbicsICdDbGllbnQgY29udHJvbCBtb2RlIGFjdGl2YXRpb24gbm90IGFsbG93ZWQnKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgbG1zVGVtcCA9IHJlc3BvbnNlc1snQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlOw0KICAgICAgICAgICAgICAgIGFtdHN0YWNrLklQU19Ib3N0QmFzZWRTZXR1cFNlcnZpY2VfU2V0dXAoMiwgcnN0cjJoZXgocnN0cl9tZDUoJ2FkbWluOicgKyByZXNwb25zZXNbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZVsnRGlnZXN0UmVhbG0nXSArICc6JyArIGQ0cGFzc3dvcmQudmFsdWUpKSwgbnVsbCwgbnVsbCwgbnVsbCwgbnVsbCwgbG1zQWN0aXZhdGlvblgyKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGxtc0FjdGl2YXRpb25YMihzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDAgfHwgcmVzcG9uc2UuQm9keVsnUmV0dXJuVmFsdWUnXSAhPSAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnSW50ZWwmcmVnOyBBTVQgQWN0aXZhdGlvbicsICdGYWlsZWQgYWN0aXZhdGlvbiwgc3RhdHVzICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBzZXREaWFsb2dNb2RlKCk7DQogICAgICAgICAgICAgICAgbG1zUmVmcmVzaCgpOw0KICAgICAgICAgICAgICAgIGxtc1RlbXBbJ0hvc3ROYW1lJ10gPSBsbXNNZUluZm9bJ09zSG9zdG5hbWUnXTsgLy8gU2V0IHRoZSBPUyBob3N0bmFtZQ0KICAgICAgICAgICAgICAgIC8vIFRPRE86IEFsc28gc2V0IHRoZSBsb2NhbCBGUUROIGlmIHdlIGNhbiBnZXQgaXQgZnJvbSBMTVMNCiAgICAgICAgICAgICAgICB3c3N0YWNrID0gV3NtYW5TdGFja0NyZWF0ZVNlcnZpY2UoJ2xvY2FsaG9zdCcsIDE2OTkyLCAnYWRtaW4nLCBkNHBhc3N3b3JkLnZhbHVlLCBmYWxzZSk7DQogICAgICAgICAgICAgICAgYW10c3RhY2sgPSBBbXRTdGFja0NyZWF0ZVNlcnZpY2Uod3NzdGFjayk7DQogICAgICAgICAgICAgICAgYW10c3RhY2sub25Qcm9jZXNzQ2hhbmdlZCA9IG9uUHJvY2Vzc0NoYW5nZWQ7DQogICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfR2VuZXJhbFNldHRpbmdzJywgbG1zVGVtcCwgZnVuY3Rpb24oKSB7IH0sIDAsIDEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gbG1zRGVhY3RpdmF0ZSgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgbG1zLlN0YXRlICE9IDIpIHJldHVybjsNCiAgICAgICAgICAgIFFIKCdpZF9kaWFsb2dNZXNzYWdlJywgJ0NvbmZpcm0gSW50ZWwmcmVnOyBBTVQgZGVhY3RpdmF0aW9uPycpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxLCAiSW50ZWwmcmVnOyBBTVQgRGVhY3RpdmF0aW9uIiwgMywgbG1zRGVhY3RpdmF0ZVgxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGxtc0RlYWN0aXZhdGVYMSgpIHsNCiAgICAgICAgICAgIHN0YXR1c2JveCgnSW50ZWwmcmVnOyBBTVQgRGVhY3RpdmF0aW9uJywgJ0RlYWN0aXZhdGluZyBJbnRlbCZyZWc7IEFNVC4uLicpDQogICAgICAgICAgICBsbXMuU2VuZENtZCgyLCBJbnRUb1N0clgoMSkpOyAvLyBTZW5kIHJlcXVlc3QgZm9yIGRlYWN0aXZhdGlvbg0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gbG1zRGVhY3RpdmF0ZVgyKHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnSW50ZWwmcmVnOyBBTVQgRGVhY3RpdmF0aW9uJywgJ0ZhaWxlZCBkZWFjdGl2YXRpb24sIHN0YXR1cyAnICsgc3RhdHVzKQ0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBRSCgnaWRfbG1zRGF0YScsICdQbGVhc2Ugd2FpdCBmb3IgZGVhY3RpdmF0aW9uLi4uJyk7DQogICAgICAgICAgICAgICAgUVYoJ2lkX2xtc0RhdGEyJywgZmFsc2UpOw0KICAgICAgICAgICAgICAgIHNldERpYWxvZ01vZGUoKTsNCiAgICAgICAgICAgICAgICBsbXNSZWZyZXNoKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAvLyBSZWZyZXNoIGJ1dHRvbiBvbiB0aGUgVUkNCiAgICAgICAgZnVuY3Rpb24gbG1zUmVmcmVzaCgpIHsNCiAgICAgICAgICAgIGlmIChsbXMuU3RhdGUgIT0gMikgcmV0dXJuOw0KICAgICAgICAgICAgbG1zLlNlbmRDbWQoMSwgIiIpOyAvLyBTZW5kIHRoZSByZXF1ZXN0IGJhc2ljIGluZm9ybWF0aW9uIGNvbW1hbmQNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENvbmZpZ3VyZSBidXR0b24gb24gdGhlIFVJDQogICAgICAgIGZ1bmN0aW9uIGxtc0NvbmZpZ3VyZSgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoNCwgJ0ludGVsJnJlZzsgQU1UIExvZ2luJywgMywgZnVuY3Rpb24gKCkgeyBsbXNDb25maWd1cmVMb2dpbigpOyB9KTsNCiAgICAgICAgICAgIC8vZDR1c2VybmFtZS5yZWFkT25seSA9IGZhbHNlOw0KICAgICAgICAgICAgZDR1c2VybmFtZS5kaXNhYmxlZCA9IGZhbHNlOw0KICAgICAgICAgICAgaWYgKGQ0dXNlcm5hbWUudmFsdWUgPT0gJ2FkbWluJykgZDR1c2VybmFtZS52YWx1ZSA9ICcnOw0KICAgICAgICAgICAgaW5wdXRCb3hGb2N1cygnZDR1c2VybmFtZScpOw0KICAgICAgICAgICAgbG1zVXBkYXRlTG9naW5EaWFsb2coKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENhbGxlZCB3aGVuIHRoZSB1c2VyIGhpdHMgT0sgb24gdGhlIGxvZ2luIGRpYWxvZw0KICAgICAgICBmdW5jdGlvbiBsbXNDb25maWd1cmVMb2dpbigpIHsNCiAgICAgICAgICAgIHZhciB1c2VyID0gZDR1c2VybmFtZS52YWx1ZTsNCiAgICAgICAgICAgIGlmICh1c2VyID09ICcnKSB1c2VyID0gJ2FkbWluJzsNCiAgICAgICAgICAgIGNvbm5lY3QoJ2xvY2FsaG9zdCcsIDE2OTkyLCB1c2VyLCBkNHBhc3N3b3JkLnZhbHVlLCAwKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIEFjdGl2YXRlIGJ1dHRvbiBvbiB0aGUgVUkNCiAgICAgICAgZnVuY3Rpb24gbG1zQWN0aXZhdGUoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlfHwgbG1zLlN0YXRlICE9IDIpIHJldHVybjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoNCwgJ0ludGVsJnJlZzsgQU1UIEFjdGl2YXRpb24nLCAzLCBmdW5jdGlvbiAoKSB7IGxtc0FjdGl2YXRlRXgoKTsgfSk7DQogICAgICAgICAgICAvL2Q0dXNlcm5hbWUucmVhZE9ubHkgPSB0cnVlOw0KICAgICAgICAgICAgZDR1c2VybmFtZS5kaXNhYmxlZCA9IHRydWU7DQogICAgICAgICAgICBkNHVzZXJuYW1lLnZhbHVlID0gJ2FkbWluJzsNCiAgICAgICAgICAgIGlucHV0Qm94Rm9jdXMoJ2Q0cGFzc3dvcmQnKTsNCiAgICAgICAgICAgIGxtc1VwZGF0ZUxvZ2luRGlhbG9nKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBHbyBoZWFkIHdpdGggSW50ZWwgQU1UIGNsaWVudCBjb250cm9sIG1vZGUgYWN0aXZhdGlvbg0KICAgICAgICBmdW5jdGlvbiBsbXNBY3RpdmF0ZUV4KCkNCiAgICAgICAgew0KICAgICAgICAgICAgbG1zLlNlbmRDbWQoMyk7IC8vIFNlbmQgcmVxdWVzdCBmb3IgYWNjb3VudCBpbmZvcm1hdGlvbg0KICAgICAgICAgICAgc3RhdHVzYm94KCdJbnRlbCZyZWc7IEFNVCBBY3RpdmF0aW9uJywgJ0ZldGNoaW5nIEFjY291bnQgSW5mb3JtYXRpb24uLi4nKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENhbGxlZCBlYWNoIHRpbWUgc29tZXRoaW5nIGNoYW5nZXMgaW4gdGhlIGxvZ2luIGRpYWxvZw0KICAgICAgICBmdW5jdGlvbiBsbXNVcGRhdGVMb2dpbkRpYWxvZyhlLCBkKSB7DQogICAgICAgICAgICB2YXIgb2sgPSBwYXNzd29yZGNoZWNrKGQ0cGFzc3dvcmQudmFsdWUpOw0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgICAgIGlmIChlICE9IG51bGwgJiYgZS5rZXlDb2RlID09IDEzICYmIGQgPT0gMSkgaW5wdXRCb3hGb2N1cygnZDRwYXNzd29yZCcpOw0KICAgICAgICAgICAgaWYgKG9rID09IHRydWUgJiYgZSAhPSBudWxsICYmIGUua2V5Q29kZSA9PSAxMyAmJiBkID09IDIpIGRpYWxvZ2Nsb3NlKDEpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGxtc0hhc2hBcmdTdHJpbmdzID0gWyJNRDUiLCAiU0hBMSIsICJTSEEyNTYiLCAiU0hBNTEyIl07DQogICAgICAgIGZ1bmN0aW9uIGxtc1Nob3dUcnVzdGVkSGFzaGVzRGxnKCkgew0KICAgICAgICAgICAgLy8ge1wiQUNcIjolZCxcIkRGXCI6JWQsXCJBTFwiOiVkLFwiTkFcIjpcIiVzXCIsXCJIQVwiOlwiJXNcIn0iDQoNCiAgICAgICAgICAgIHZhciB4ID0gIjxkaXYgc3R5bGU9bWF4LWhlaWdodDoyNDBweDtvdmVyZmxvdy15OnNjcm9sbD4iICsgVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBsbXNNZUluZm9bJ1RydXN0ZWRIYXNoZXMnXSkNCiAgICAgICAgICAgIHsNCiAgICAgICAgICAgICAgICAvL3ggKz0gIjxiPiIgKyBsbXNNZUluZm9bJ1RydXN0ZWRIYXNoZXMnXVtpXVsnTmFtZSddICsgIjwvYj48YnI+PHNwYW4gc3R5bGU9Zm9udC1zaXplOjEwcHg+IiArIGxtc0hhc2hBcmdTdHJpbmdzW2xtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydIYXNoQWxnb3JpdGhtJ11dICsgKGxtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydBY3RpdmUnXSA9PSAxPyIsIEFjdGl2ZSI6IiIpICsgKGxtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydEZWZhdWx0J10gPT0gMT8iLCBEZWZhdWx0IjoiIikgKyAiPC9zcGFuPjxicj48c3BhbiBzdHlsZT1mb250LXNpemU6MTBweD4iICsgbG1zTWVJbmZvWydUcnVzdGVkSGFzaGVzJ11baV1bJ0hhc2gnXSArICI8L3NwYW4+PGJyPjxicj4iOw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiPGI+IiArIGxtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydOYW1lJ10gKyAiPC9iPjxicj48c3BhbiBzdHlsZT1mb250LXNpemU6MTBweD4iICsgbG1zSGFzaEFyZ1N0cmluZ3NbbG1zTWVJbmZvWydUcnVzdGVkSGFzaGVzJ11baV1bJ0hhc2hBbGdvcml0aG0nXV0gKyAobG1zTWVJbmZvWydUcnVzdGVkSGFzaGVzJ11baV1bJ0FjdGl2ZSddID09IDE/IiwgQWN0aXZlIjoiIikgKyAobG1zTWVJbmZvWydUcnVzdGVkSGFzaGVzJ11baV1bJ0RlZmF1bHQnXSA9PSAxPyIsIERlZmF1bHQiOiIiKSArICI8L3NwYW4+PGJyPjxzcGFuIHN0eWxlPWZvbnQtc2l6ZTo4cHg+IiArIGxtc01lSW5mb1snVHJ1c3RlZEhhc2hlcyddW2ldWydIYXNoJ10gKyAiPC9zcGFuPiIsICIiKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoKSArICI8L2Rpdj4iOw0KICAgICAgICAgICAgbWVzc2FnZWJveCgiSW50ZWwmcmVnOyBBTVQgVHJ1c3RlZCBIYXNoZXMiLCB4KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGxtc1Nob3dWZXJzaW9uc0RsZygpIHsNCiAgICAgICAgICAgIHZhciB4ID0gVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJJbnRlbCZyZWc7IEFNVCIsIGxtc01lSW5mb1snVmVyc2lvbnMnXVsnQU1UJ10pOw0KICAgICAgICAgICAgaWYgKGxtc01lSW5mb1snTWVpVmVyc2lvbiddICE9IG51bGwpIHsgeCArPSBUYWJsZUVudHJ5KCJJbnRlbCZyZWc7IE1FSSBkcml2ZXIiLCBsbXNNZUluZm9bJ01laVZlcnNpb24nXSk7IH0NCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gbG1zTWVJbmZvWydWZXJzaW9ucyddKSB7IGlmIChpICE9ICdBTVQnKSB4ICs9IFRhYmxlRW50cnkoaSwgbG1zTWVJbmZvWydWZXJzaW9ucyddW2ldKTsgfQ0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgbWVzc2FnZWJveCgiSW50ZWwmcmVnOyBBTVQgVmVyc2lvbnMiLCB4KTsNCiAgICAgICAgfQ0KDQoNCg0KICAgICAgICBmdW5jdGlvbiBjbGVhbnVwKCkgew0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gaGFuZGxlS2V5VXAoZSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gaGFuZGxlS2V5RG93bihlKSB7DQogICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdoYW5kbGVLZXlEb3duJywgZSk7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBoYW5kbGVLZXlQcmVzcyhlKSB7DQogICAgICAgICAgICAvL2NvbnNvbGUubG9nKCdoYW5kbGVLZXlQcmVzcycsIGUpOw0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGNvbm5lY3RGdW5jID0gbnVsbDsNCiAgICAgICAgdmFyIGNvbm5lY3RGdW5jVGFnID0gbnVsbDsNCiAgICAgICAgZnVuY3Rpb24gY29ubmVjdChob3N0LCBwb3J0LCB1c2VyLCBwYXNzLCB0bHMsIGZ1bmMsIGZ1bmN0YWcpIHsNCiAgICAgICAgICAgIGdvKDApOw0KICAgICAgICAgICAgZnVsbHNjcmVlbm9ubHkgPSBmYWxzZTsNCiAgICAgICAgICAgIGNvbm5lY3RGdW5jID0gZnVuYzsNCiAgICAgICAgICAgIGNvbm5lY3RGdW5jVGFnID0gZnVuY3RhZzsNCg0KDQoNCiAgICAgICAgICAgIHdzc3RhY2sgPSBXc21hblN0YWNrQ3JlYXRlU2VydmljZShob3N0LCBwb3J0LCB1c2VyLCBwYXNzLCB0bHMpOw0KICAgICAgICAgICAgYW10c3RhY2sgPSBBbXRTdGFja0NyZWF0ZVNlcnZpY2Uod3NzdGFjayk7DQogICAgICAgICAgICBhbXRzdGFjay5vblByb2Nlc3NDaGFuZ2VkID0gb25Qcm9jZXNzQ2hhbmdlZDsNCg0KICAgICAgICAgICAgLy8gU2V0dXAgVExTIGNoZWNraW5nDQoNCiAgICAgICAgICAgIC8vIEhpZGUgVExTIGluZGljYXRvcg0KDQogICAgICAgICAgICAvLyBIaWRlIG1vc3Qgb2YgdGhlIGxlZnQgbWVudSBvcHRpb25zLCB3ZSB3aWxsIHNlZSB0aGVtIGFzIHdlIGxvYWQgZGF0YQ0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDI7IGkgPCAyNTsgaSsrKSB7IFFWKCdnbycgKyBpLCBmYWxzZSk7IH0NCiAgICAgICAgICAgIFFWKCdnbzgnLCB0cnVlKTsgLy8gTmV0d29yayBTZXR0aW5ncw0KICAgICAgICAgICAgLy9RVignZ28xNScsIGZhbHNlKTsgLy8gQXVkaXQgTG9nDQoNCiAgICAgICAgICAgIC8vUVYoJ2dvMTYnLCBmYWxzZSk7IC8vIFNlY3VyaXR5IFNldHRpbmdzDQoNCiAgICAgICAgICAgIC8vUVYoJ2dvMTcnLCBmYWxzZSk7IC8vIFJlbW90ZSBBY2Nlc3MNCg0KICAgICAgICAgICAgUVYoJ2dvMjAnLCB0cnVlKTsgLy8gU2NyaXB0aW5nIEVkaXRvcg0KDQoNCg0KICAgICAgICAgICAgLy8gQ2xlYXIgdGhlIGRpc3BsYXllZCBwb3dlciBzdGF0ZQ0KDQogICAgICAgICAgICAvLyBDbGVhciBldmVyeXRoaW5nLCBtYWtlIHN1cmUgYWxsIGNvbm5lY3Rpb24gc3RhdGUgaXMgcmVzZXQuDQogICAgICAgICAgICBhbXR2ZXJzaW9uID0gYW10dmVyc2lvbm1pbiA9IGFtdEZpcnN0UHVsbCA9IDA7DQogICAgICAgICAgICBhbXRzeXNzdGF0ZSA9IGFtdGRlbHRhdGltZSA9IGFtdGxvZ2ljYWxlbGVtZW50cyA9IEhhcmR3YXJlSW52ZW50b3J5ID0gdW5kZWZpbmVkOw0KICAgICAgICAgICAgYW10UG93ZXJCb290Q2FwYWJpbGl0aWVzID0gbnVsbDsNCiAgICAgICAgICAgIHh4QWNjb3VudEZldGNoID0gOTk5Ow0KDQogICAgICAgICAgICAvLyBTaG93IGxvYWRpbmcgb24gYWxsIHBhbmVscw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlU3lzU3RhdHVzJywgTG9hZGluZ0h0bWwpOw0KDQogICAgICAgICAgICBRSCgnaWRfVGFibGVOZXR3b3JrU2V0dGluZ3NTcGFuJywgTG9hZGluZ0h0bWwpOw0KICAgICAgICAgICAgYW10d2lyZWxlc3NpZiA9IC0xOw0KDQogICAgICAgICAgICB4eFdpcmVsZXNzID0gdW5kZWZpbmVkOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlV2lmaTInLCAnJyk7DQoNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVN5c0luZm8nLCBMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIHh4QWNjb3VudEFkbWluTmFtZSA9IG51bGw7DQogICAgICAgICAgICB4eEFjY291bnRSZWFsbUluZm8gPSB7fTsNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVVzZXJBY2NvdW50cycsIExvYWRpbmdIdG1sKTsNCg0KICAgICAgICAgICAgZXZlbnRtZXNzYWdlcyA9IG51bGw7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVFdmVudExvZycsJycpOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlRXZlbnRMb2cyJyxMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIGF1ZGl0TG9nID0gbnVsbDsNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZUF1ZGl0TG9nMScsICcnKTsNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZUF1ZGl0TG9nMicsIExvYWRpbmdIdG1sKTsNCg0KICAgICAgICAgICAgeHhDZXJ0aWZpY2F0ZXMgPSBudWxsOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlQ2VydHMnLCBMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIHh4UmVtb3RlQWNjZXNzID0gbnVsbDsNCiAgICAgICAgICAgIHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uID0gbnVsbDsNCiAgICAgICAgICAgIHh4Q2lyYVNlcnZlcnMgPSBudWxsOw0KICAgICAgICAgICAgeHhVc2VySW5pdGlhdGVkQ2lyYSA9IG51bGw7DQogICAgICAgICAgICB4eFJlbW90ZUFjY2Vzc0NyZWRlbnRpYUxpbmtzID0gbnVsbDsNCiAgICAgICAgICAgIHh4TVBTVXNlclBhc3MgPSBudWxsOw0KICAgICAgICAgICAgeHhQb2xpY2llcyA9IG51bGw7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVSZW1vdGVBY2Nlc3MnLCBMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVN5c3RlbUFnZW50UHJlc2VuY2UnLCBMb2FkaW5nSHRtbCk7DQoNCiAgICAgICAgICAgIHh4U3lzdGVtRGVmZW5zZSA9IG51bGw7DQogICAgICAgICAgICB4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3kgPSB7fTsNCiAgICAgICAgICAgIHh4VXBkYXRpbmdEZWZlbnNlU3RhdHMgPSBmYWxzZTsNCiAgICAgICAgICAgIHh4RmlsdGVyU3RhdGlzdGljcyA9IFt7fSwge31dOyAvLyBXaXJlZCBhbmQgd2lyZWxlc3MgaW50ZXJmYWNlIHN0YXRzDQogICAgICAgICAgICB4eEZpbHRlclN0YXRpc3RpY3NUaW1lciA9IG51bGw7DQogICAgICAgICAgICB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9IGZhbHNlOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlU3lzdGVtRGVmZW5zZScsIExvYWRpbmdIdG1sKTsNCg0KDQogICAgICAgICAgICAvLyBTdGFydCBwdWxsaW5nIEludGVsIEFNVCBpbmZvcm1hdGlvbg0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKCIiLCBbIkNJTV9Tb2Z0d2FyZUlkZW50aXR5IiwgIipBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSJdLCBwcm9jZXNzU3lzdGVtVmVyc2lvbik7IC8vIEdldCBJbnRlbCBBTVQgdmVyc2lvbiBpbmZvcm1hdGlvbiBhbmQgcGxlbnR5IG1vcmUNCiAgICAgICAgICAgIC8vYW10c3RhY2suRW51bSgiQ0lNX0xvZ2ljYWxFbGVtZW50IiwgcHJvY2Vzc1N5c3RlbVZlcnNpb24pOyAvLyBHZXQgSW50ZWwgQU1UIHZlcnNpb24gaW5mb3JtYXRpb24gYW5kIHBsZW50eSBtb3JlDQoNCg0KDQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBkaXNjb25uZWN0KCkgew0KDQoNCg0KDQoNCg0KICAgICAgICAgICAgU3RvcERlZmVuc2VTdGF0c1RpbWVyKCk7DQoNCg0KICAgICAgICAgICAgc2NyaXB0X1N0b3AoKTsNCg0KICAgICAgICAgICAgYnJlYWtTY3JpcHRCdXR0b24oKTsNCg0KICAgICAgICAgICAgZGlhbG9nY2xvc2UoMCk7DQoNCiAgICAgICAgICAgIFFIKCdpZF9jb21wdXRlcm5hbWUnLCAnJyk7DQogICAgICAgICAgICBpZiAoYW10c3RhY2spIHsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5vblByb2Nlc3NDaGFuZ2VkID0gbnVsbDsgLy8gVW4taG9vayBwcm9ncmVzcyBpbmRpY2F0b3INCiAgICAgICAgICAgICAgICBhbXRzdGFjay5DYW5jZWxBbGxRdWVyaWVzKDk5OSk7IC8vIEZhaWwgYWxsIHBlbmRpbmcgV1NNQU4gY2FsbHMuIFNldCB0byA5OTkgdG8gaW5kaWNhdGUgbm90IHRvIGNhbGwgYmFjayBhbnkgb2YgdGhlIHBlbmRpbmcgY2FsbHMgd2l0aCBlcnJvcnMuDQogICAgICAgICAgICAgICAgYW10c3RhY2sgPSBudWxsOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY2xlYW51cCgpOw0KICAgICAgICAgICAgd3NzdGFjayA9IG51bGw7DQogICAgICAgICAgICBkZWxldGUgYW10c3RhY2s7DQogICAgICAgICAgICBvblByb2Nlc3NDaGFuZ2VkKDAsIDEpOw0KICAgICAgICAgICAgZ28oMTAxKTsNCg0KDQoNCiAgICAgICAgICAgIFFIKCdpZF9jb21wdXRlcm5hbWUnLCAnUmVtb3RlIE1hbmFnZW1lbnQgQ29uc29sZSB2JyArIHZlcnNpb24pOw0KICAgICAgICAgICAgDQoNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIG9uUHJvY2Vzc0NoYW5nZWQoYSwgYikgew0KICAgICAgICAgICAgUVMoJ2lkX3Byb2dyZXNzYmFyJykud2lkdGggPSAoKGEgKiAxMDApIC8gYikgKyAiJSI7DQogICAgICAgICAgICBpZiAoYSA9PSAwKSByZWZyZXNoQnV0dG9ucyh0cnVlKTsgLy8gSWYgbm90aGluZyBpcyBiZWluZyBkb25lLCByZS1lbmFibGUgcmVmcmVzaCBidXR0b25zDQoNCg0KICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm90aGluZyBiZWluZyBkb25lIG5vdywgc2VlIGlmIHdlIGNhbiBwdWxsIG1vcmUgaW5mb3JtYXRpb24NCiAgICAgICAgICAgIGlmIChhICE9IDAgfHwgIWFtdHN0YWNrKSByZXR1cm47DQogICAgICAgICAgICBpZiAoKGFtdHZlcnNpb24gPiAwKSAmJiAoKGFtdEZpcnN0UHVsbCAmIDY0KSA9PSAwKSkgew0KICAgICAgICAgICAgICAgIGFtdEZpcnN0UHVsbCB8PSA2NDsNCiAgICAgICAgICAgICAgICBQdWxsUG93ZXJQb2xpY3koKTsNCg0KICAgICAgICAgICAgICAgIFB1bGxXYXRjaGRvZygpOw0KDQoNCiAgICAgICAgICAgICAgICBzY3JpcHRWaWV3QnV0dG9uKHNjcmlwdF9CdWlsZGluZ0Jsb2Nrcz8xOjApOw0KDQogICAgICAgICAgICAgICAgaWYgKGFtdHZlcnNpb24gPiA1KSB7DQoNCiAgICAgICAgICAgICAgICAgICAgUHVsbENlcnRpZmljYXRlcygpOw0KDQogICAgICAgICAgICAgICAgICAgIFB1bGxSZW1vdGVBY2Nlc3MoKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgcmV0dXJuOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAoKGFtdEZpcnN0UHVsbCAmIDEpID09IDApIHsgUHVsbEhhcmR3YXJlKCk7IHJldHVybjsgfQ0KDQogICAgICAgICAgICBpZiAoKGFtdEZpcnN0UHVsbCAmIDE2KSA9PSAwKSB7IFB1bGxFdmVudExvZygpOyByZXR1cm47IH0NCg0KICAgICAgICAgICAgaWYgKChhbXRGaXJzdFB1bGwgJiAzMikgPT0gMCkgeyBQdWxsQXVkaXRMb2coKTsgcmV0dXJuOyB9DQogICAgICAgIH0NCg0KDQogICAgICAgIGZ1bmN0aW9uIHRvb2xtZW51Y2xpY2soeCkgew0KICAgICAgICAgICAgUVYoJ2lkX21lbnVpdGVtMScsIGN1cnJlbnRWaWV3ID09IDEwMSk7DQoNCiAgICAgICAgICAgIFFWKCdpZF9tZW51aXRlbTInLCBjdXJyZW50VmlldyA9PSAxMDIpOw0KDQogICAgICAgICAgICB2YXIgZCA9IChRUygnaWRfY29tcHV0ZXJTZWxlY3Rvck1lbnUnKS5kaXNwbGF5ID09ICdub25lJyk7DQogICAgICAgICAgICBpZiAoZCA9PSB0cnVlICYmIHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgeHhkaWFsb2dNb2RlID0gKGQgPT0gdHJ1ZSk/OTk5OnVuZGVmaW5lZDsNCiAgICAgICAgICAgIFFWKCdpZF9jb21wdXRlclNlbGVjdG9yTWVudScsIGQpOw0KICAgICAgICAgICAgaWYgKHggPT0gMCkgcmV0dXJuOw0KICAgICAgICAgICAgZ28oeCk7DQogICAgICAgIH0NCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gQk9UVE9NIElORk9STUFUSU9OIFNUUklORw0KICAgICAgICAvLw0KDQoNCiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1N5c3RlbVZlcnNpb24oc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCB8fCBzdGF0dXMgPT0gNDAwKSB7DQogICAgICAgICAgICAgICAgdmFyIHY7DQogICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsNCiAgICAgICAgICAgICAgICAgICAgLy9hbXRsb2dpY2FsZWxlbWVudHMgPSByZXNwb25zZXM7DQogICAgICAgICAgICAgICAgICAgIGFtdGxvZ2ljYWxlbGVtZW50cyA9IFtdOw0KICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2VzICE9IG51bGwpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZXNbIkNJTV9Tb2Z0d2FyZUlkZW50aXR5Il0gIT0gbnVsbCAmJiByZXNwb25zZXNbIkNJTV9Tb2Z0d2FyZUlkZW50aXR5Il0ucmVzcG9uc2VzICE9IG51bGwpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbXRsb2dpY2FsZWxlbWVudHMgPSByZXNwb25zZXNbIkNJTV9Tb2Z0d2FyZUlkZW50aXR5Il0ucmVzcG9uc2VzOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZXNbIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIl0gIT0gbnVsbCAmJiByZXNwb25zZXNbIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIl0ucmVzcG9uc2UgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbXRsb2dpY2FsZWxlbWVudHMucHVzaChyZXNwb25zZXNbIkFNVF9TZXR1cEFuZENvbmZpZ3VyYXRpb25TZXJ2aWNlIl0ucmVzcG9uc2UpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoYW10bG9naWNhbGVsZW1lbnRzLmxlbmd0aCA9PSAwKSB7IGNvbnNvbGUuZXJyb3IoJ0VSUk9SOiBDb3VsZCBub3QgZ2V0IEludGVsIEFNVCB2ZXJzaW9uLicpOyBkaXNjb25uZWN0KCk7IHJldHVybjsgfSAvLyBDb3VsZCBub3QgZ2V0IEludGVsIEFNVCB2ZXJzaW9uLCBkaXNjb25uZWN0KCk7DQogICAgICAgICAgICAgICAgICAgIHYgPSBnZXRJbnN0YW5jZShhbXRsb2dpY2FsZWxlbWVudHMsICJBTVQiKVsiVmVyc2lvblN0cmluZyJdOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIHYgPSBzdGFjay53c21hbi5jb21tLmFtdFZlcnNpb247DQogICAgICAgICAgICAgICAgICAgIGlmICghdikgeyBlcnJjaGVjayg0MDAsIHN0YWNrKTsgcmV0dXJuOyB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGFtdHZlcnNpb24gPSBwYXJzZUludCh2LnNwbGl0KCcuJylbMF0pOw0KICAgICAgICAgICAgICAgIGFtdHZlcnNpb25taW4gPSBwYXJzZUludCh2LnNwbGl0KCcuJylbMV0pOw0KDQoNCiAgICAgICAgICAgICAgICAvL2lmIChhbXR2ZXJzaW9uID4gMTApIHsgd3NzdGFjay5jb21tLk1heEFjdGl2ZUFqYXhDb3VudCA9IDQ7IGFtdHN0YWNrLk1heEFjdGl2ZUVudW1zQ291bnQgPSAxOyBjb25zb2xlLmxvZygnSFRUUCBQaXBlbGluaW5nIGFjdGl2YXRlZCcpOyB9IC8vIFdpdGggSW50ZWwgQU1UIDExIGFuZCBoaWdoZXIsIHVzZSBIVFRQIHBpcGVsaW5pbmcuDQoNCiAgICAgICAgICAgICAgICBQdWxsU3lzdGVtU3RhdHVzKCk7DQogICAgICAgICAgICAgICAgdXBkYXRlU3lzdGVtU3RhdHVzKCk7DQoNCiAgICAgICAgICAgICAgICAvLyBQZXJmb3JtIGxvYWRzIG1vcmUgV1NNQU4gb25seSBpZiBuZWVkZWQNCiAgICAgICAgICAgICAgICBpZiAoKHVybHZhcnNbJ2t2bW9ubHknXSAhPSAxKSAmJiAoZnVsbHNjcmVlbm9ubHkgPT0gZmFsc2UpKSB7DQogICAgICAgICAgICAgICAgICAgIFB1bGxVc2VySW5mbygpOw0KDQoNCiAgICAgICAgICAgICAgICAgICAgaWYgKGFtdHZlcnNpb24gPj0gOCkgUHVsbEFsYXJtcygpOw0KICAgICAgICAgICAgICAgIH0NCg0KDQogICAgICAgICAgICAgICAgLy8gQ29ubmVjdGlvbiBjYWxsYmFjaw0KICAgICAgICAgICAgICAgIGlmIChjb25uZWN0RnVuYykgeyBjb25uZWN0RnVuYyhjb25uZWN0RnVuY1RhZyk7IGNvbm5lY3RGdW5jID0gbnVsbDsgY29ubmVjdEZ1bmNUYWcgPSBudWxsOyB9DQoNCg0KDQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIGVycmNoZWNrKHN0YXR1cywgc3RhY2spOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ29udHJvbCB0aGUgc3RhdGUgb2YgYWxsIHJlZnJlc2ggYnV0dG9ucw0KICAgICAgICB2YXIgcmVmcmVzaEJ1dHRvbnNTdGF0ZSA9IHRydWU7DQogICAgICAgIGZ1bmN0aW9uIHJlZnJlc2hCdXR0b25zKHgpIHsNCiAgICAgICAgICAgIGlmIChyZWZyZXNoQnV0dG9uc1N0YXRlID09IHgpIHJldHVybjsNCiAgICAgICAgICAgIHJlZnJlc2hCdXR0b25zU3RhdGUgPSB4Ow0KICAgICAgICAgICAgdmFyIGkgPSAwLCBlID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0Jyk7DQogICAgICAgICAgICBmb3IgKDsgaSA8IGUubGVuZ3RoOyBpKyspIHsgaWYgKGVbaV0ubmFtZSA9PSAncmVmcmVzaGJ0bicpIHsgZVtpXS5kaXNhYmxlZCA9ICF4OyB9IH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIERpc3BsYXkgVExTIGNlcnRpZmljYXRlDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gU1lTVEVNIFNUQVRVUyBQQU5FTA0KICAgICAgICAvLw0KDQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFN5c3RlbVN0YXR1cyh4KSB7DQogICAgICAgICAgICByZWZyZXNoQnV0dG9ucyhmYWxzZSk7DQogICAgICAgICAgICBhbXRzdGFjay5BTVRfVGltZVN5bmNocm9uaXphdGlvblNlcnZpY2VfR2V0TG93QWNjdXJhY3lUaW1lU3luY2gocHJvY2Vzc1N5c3RlbVRpbWUpOw0KDQogICAgICAgICAgICB2YXIgcXVlcnkgPSBbIkNJTV9TZXJ2aWNlQXZhaWxhYmxlVG9FbGVtZW50IiwgIipBTVRfR2VuZXJhbFNldHRpbmdzIiwgIkFNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyIsICIqQU1UX1JlZGlyZWN0aW9uU2VydmljZSIsICJDSU1fRWxlbWVudFNldHRpbmdEYXRhIl07DQogICAgICAgICAgICBpZiAoYW10dmVyc2lvbiA+IDUpIHF1ZXJ5LnB1c2goIklQU19JUHY2UG9ydFNldHRpbmdzIiwgIipDSU1fS1ZNUmVkaXJlY3Rpb25TQVAiLCAiKklQU19PcHRJblNlcnZpY2UiLCIqSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEiKTsNCiAgICAgICAgICAgIGlmIChhbXR2ZXJzaW9uID4gOSkgcXVlcnkucHVzaCgiKklQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSIpOw0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKCIiLCBxdWVyeSwgcHJvY2Vzc1N5c3RlbVN0YXR1cywgdHJ1ZSk7DQoNCiAgICAgICAgICAgIGlmICh4ID09IDEpIFB1bGxXaXJlbGVzcygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1N5c3RlbVRpbWUoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoZXJyY2hlY2soc3RhdHVzLCBzdGFjaykpIHJldHVybjsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSB7DQogICAgICAgICAgICAgICAgLy8gQ29udmVydCBtcyB0byB0aW1lIGFuZCBhZGp1c3QgZm9yIHRoZSB0aW1lem9uZQ0KICAgICAgICAgICAgICAgIHZhciB0ID0gbmV3IERhdGUoKSwgdDIgPSBuZXcgRGF0ZSgpOw0KICAgICAgICAgICAgICAgIHQuc2V0VGltZShyZXNwb25zZXMuQm9keVsiVGEwIl0gKiAxMDAwICsgKHQuZ2V0VGltZXpvbmVPZmZzZXQoKSAqIDYwICogMTAwMCkpOw0KICAgICAgICAgICAgICAgIGFtdGRlbHRhdGltZSA9IHQgLSB0MjsNCiAgICAgICAgICAgICAgICB1cGRhdGVTeXN0ZW1TdGF0dXMoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIHZhciBhbXRkZWx0YXRpbWU7DQogICAgICAgIHZhciBhbXRzeXNzdGF0ZTsNCiAgICAgICAgdmFyIGFtdGxvZ2ljYWxlbGVtZW50czsgLy8gcHJvY2Vzc1N5c3RlbVZlcnNpb24NCiAgICAgICAgdmFyIGFtdGZlYXR1cmVzID0ge307DQogICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NTeXN0ZW1TdGF0dXMoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICAvLyBJZiB0aGlzIGNvbXB1dGVyIGhhcyBubyBLVk0sIGlnbm9yZSBhbmQgY29udGludWUgKFN0YW5kYXJkIE1hbmFnZWFiaWxpdHkpDQogICAgICAgICAgICBpZiAoKHJlc3BvbnNlc1snSVBTX1NjcmVlbkNvbmZpZ3VyYXRpb25TZXJ2aWNlJ10gPT0gdW5kZWZpbmVkKSB8fCAocmVzcG9uc2VzWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXS5zdGF0dXMgPT0gNDAwKSkgeyByZXNwb25zZXNbJ0lQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSddID0gbnVsbDsgfQ0KICAgICAgICAgICAgaWYgKChyZXNwb25zZXNbJ0lQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhJ10gPT0gdW5kZWZpbmVkKSB8fCAocmVzcG9uc2VzWydJUFNfS1ZNUmVkaXJlY3Rpb25TZXR0aW5nRGF0YSddLnN0YXR1cyA9PSA0MDApKSB7IHJlc3BvbnNlc1snSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnXSA9IG51bGw7IH0NCiAgICAgICAgICAgIGlmICgocmVzcG9uc2VzWydDSU1fS1ZNUmVkaXJlY3Rpb25TQVAnXSA9PSB1bmRlZmluZWQpIHx8IChyZXNwb25zZXNbJ0NJTV9LVk1SZWRpcmVjdGlvblNBUCddLnN0YXR1cyA9PSA0MDApKSB7IHJlc3BvbnNlc1snQ0lNX0tWTVJlZGlyZWN0aW9uU0FQJ10gPSBudWxsOyB9DQogICAgICAgICAgICBpZiAoKHJlc3BvbnNlc1snSVBTX09wdEluU2VydmljZSddID09IHVuZGVmaW5lZCkgfHwgKHJlc3BvbnNlc1snSVBTX09wdEluU2VydmljZSddLnN0YXR1cyA9PSA0MDApKSB7IHJlc3BvbnNlc1snSVBTX09wdEluU2VydmljZSddID0gbnVsbDsgfQ0KICAgICAgICAgICAgaWYgKChyZXNwb25zZXNbJ0FNVF9SZWRpcmVjdGlvblNlcnZpY2UnXSAhPSB1bmRlZmluZWQpICYmIChyZXNwb25zZXNbJ0FNVF9SZWRpcmVjdGlvblNlcnZpY2UnXS5zdGF0dXMgPT0gMjAwKSkgeyBRVignZ28xMycsIHRydWUpOyB9IC8vIFNob3cgdGhlIHRlcm1pbmFsDQoNCiAgICAgICAgICAgIC8vIFJlc2V0IHRoZSBzdGF0dXMgYWZ0ZXIgcG9zc2libGUgS1ZNIHJlbW92YWwNCiAgICAgICAgICAgIHN0YXR1cyA9IDA7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHJlc3BvbnNlcykgeyBpZiAoKHJlc3BvbnNlc1tpXSAhPSBudWxsKSAmJiAocmVzcG9uc2VzW2ldLnN0YXR1cyA+IHN0YXR1cykpIHsgc3RhdHVzID0gcmVzcG9uc2VzW2ldLnN0YXR1czsgfSB9DQoNCiAgICAgICAgICAgIGlmICgoc3RhdHVzICE9IDQwMCkgJiYgZXJyY2hlY2soc3RhdHVzLCBzdGFjaykpIHJldHVybjsNCiAgICAgICAgICAgIGFtdHN5c3N0YXRlID0gcmVzcG9uc2VzOw0KICAgICAgICAgICAgdXBkYXRlU3lzdGVtU3RhdHVzKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1cGRhdGVTeXN0ZW1TdGF0dXMoKSB7DQogICAgICAgICAgICBpZiAoKCFhbXRzeXNzdGF0ZSkgfHwgKGN1cnJlbnRWaWV3ID4gOTkpKSByZXR1cm47DQogICAgICAgICAgIA0KICAgICAgICAgICAgLy8gU3lzdGVtIFN0YXR1cyBUYWJsZQ0KICAgICAgICAgICAgdmFyIHN5c3RlbWRlZmVuc2UgPSAwLCBob3N0LCB5LCB4ID0gVGFibGVTdGFydCgpLCBmZWF0dXJlcyA9ICcnLCBncyA9IGFtdHN5c3N0YXRlWydBTVRfR2VuZXJhbFNldHRpbmdzJ10ucmVzcG9uc2U7DQoNCiAgICAgICAgICAgIGhvc3QgPSBnc1siSG9zdE5hbWUiXTsNCiAgICAgICAgICAgIHkgPSBnc1siRG9tYWluTmFtZSJdOw0KICAgICAgICAgICAgaWYgKHkgIT0gbnVsbCAmJiB5Lmxlbmd0aCA+IDApIGhvc3QgKz0gIi4iICsgeTsNCiAgICAgICAgICAgIGlmIChob3N0Lmxlbmd0aCA9PSAwKSB7IGhvc3QgPSAiPGk+Tm9uZTwvaT4iOyB9IGVsc2UgeyBob3N0ID0gRXNjYXBlSHRtbChob3N0KTsgfQ0KICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJOYW1lICYgRG9tYWluIiwgYWRkTGlua0NvbmRpdGlvbmFsKGhvc3QsICdzaG93RWRpdE5hbWVEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgaWYgKEhhcmR3YXJlSW52ZW50b3J5KSB4ICs9IFRhYmxlRW50cnkoIlN5c3RlbSBJRCIsIGd1aWRUb1N0cihIYXJkd2FyZUludmVudG9yeVsnQ0lNX0NvbXB1dGVyU3lzdGVtUGFja2FnZSddLnJlc3BvbnNlWyJQbGF0Zm9ybUdVSUQiXS50b0xvd2VyQ2FzZSgpKSk7DQogICAgICAgICAgICBpZiAoYW10bG9naWNhbGVsZW1lbnRzKSB7DQogICAgICAgICAgICAgICAgdmFyIG1vZGUgPSAnJywgc2NzID0gZ2V0SXRlbShhbXRsb2dpY2FsZWxlbWVudHMsICJDcmVhdGlvbkNsYXNzTmFtZSIsICJBTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZSIpOw0KDQogICAgICAgICAgICAgICAgaWYgKChzY3NbIlByb3Zpc2lvbmluZ1N0YXRlIl0gPT0gMikgJiYgKGFtdHZlcnNpb24gPiA1KSkgew0KICAgICAgICAgICAgICAgICAgICBtb2RlID0gJyBhY3RpdmF0ZWQgaW4gQWRtaW4gQ29udHJvbCBNb2RlIChBQ00pJzsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHNjc1siUHJvdmlzaW9uaW5nTW9kZSJdID09IDQpIHsgbW9kZSA9ICcgYWN0aXZhdGVkIGluIENsaWVudCBDb250cm9sIE1vZGUgKENDTSknOyBzeXN0ZW1kZWZlbnNlID0gOTsgfQ0KICAgICAgICAgICAgICAgIH0NCg0KDQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJJbnRlbCZyZWc7IE1FIiwgInYiICsgZ2V0SXRlbShhbXRsb2dpY2FsZWxlbWVudHMsICJJbnN0YW5jZUlEIiwgIkFNVCIpWyJWZXJzaW9uU3RyaW5nIl0gKyBtb2RlKTsNCg0KICAgICAgICAgICAgfQ0KDQoNCg0KDQogICAgICAgICAgICBRSCgnaWRfY29tcHV0ZXJuYW1lJywgJ0NvbXB1dGVyOiAnICsgKChnc1siSG9zdE5hbWUiXSA9PSAnJykgPyAiPGk+Tm9uZTwvaT4iIDogZ3NbIkhvc3ROYW1lIl0pKTsNCg0KDQoNCg0KICAgICAgICAgICAgLy8gSW50ZWwgQU1UIEZlYXR1cmVzDQogICAgICAgICAgICBpZiAoYW10c3lzc3RhdGVbJ0FNVF9SZWRpcmVjdGlvblNlcnZpY2UnXS5zdGF0dXMgPT0gMjAwKSB7DQogICAgICAgICAgICAgICAgdmFyIHJlZGlyID0gYW10ZmVhdHVyZXNbMF0gPSAoYW10c3lzc3RhdGVbJ0FNVF9SZWRpcmVjdGlvblNlcnZpY2UnXS5yZXNwb25zZVsiTGlzdGVuZXJFbmFibGVkIl0gPT0gdHJ1ZSk7DQogICAgICAgICAgICAgICAgdmFyIHNvbCA9IGFtdGZlYXR1cmVzWzFdID0gKChhbXRzeXNzdGF0ZVsnQU1UX1JlZGlyZWN0aW9uU2VydmljZSddLnJlc3BvbnNlWyJFbmFibGVkU3RhdGUiXSAmIDIpICE9IDApOw0KICAgICAgICAgICAgICAgIHZhciBpZGVyID0gYW10ZmVhdHVyZXNbMl0gPSAoKGFtdHN5c3N0YXRlWydBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlJ10ucmVzcG9uc2VbIkVuYWJsZWRTdGF0ZSJdICYgMSkgIT0gMCk7DQogICAgICAgICAgICAgICAgdmFyIGt2bSA9IGFtdGZlYXR1cmVzWzNdID0gdW5kZWZpbmVkOw0KICAgICAgICAgICAgICAgIGlmICgoYW10dmVyc2lvbiA+IDUpICYmIChhbXRzeXNzdGF0ZVsnQ0lNX0tWTVJlZGlyZWN0aW9uU0FQJ10gIT0gbnVsbCkpIHsNCiAgICAgICAgICAgICAgICAgICAga3ZtID0gYW10ZmVhdHVyZXNbM10gPSAoKGFtdHN5c3N0YXRlWydDSU1fS1ZNUmVkaXJlY3Rpb25TQVAnXS5yZXNwb25zZVsiRW5hYmxlZFN0YXRlIl0gPT0gNiAmJiBhbXRzeXNzdGF0ZVsnQ0lNX0tWTVJlZGlyZWN0aW9uU0FQJ10ucmVzcG9uc2VbIlJlcXVlc3RlZFN0YXRlIl0gPT0gMikgfHwgYW10c3lzc3RhdGVbJ0NJTV9LVk1SZWRpcmVjdGlvblNBUCddLnJlc3BvbnNlWyJFbmFibGVkU3RhdGUiXSA9PSAyIHx8IGFtdHN5c3N0YXRlWydDSU1fS1ZNUmVkaXJlY3Rpb25TQVAnXS5yZXNwb25zZVsiRW5hYmxlZFN0YXRlIl0gPT0gNik7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmIChyZWRpcikgZmVhdHVyZXMgKz0gIiwgUmVkaXJlY3Rpb24gUG9ydCI7DQogICAgICAgICAgICAgICAgaWYgKHNvbCkgZmVhdHVyZXMgKz0gIiwgU2VyaWFsLW92ZXItTEFOIjsNCiAgICAgICAgICAgICAgICBpZiAoaWRlcikgZmVhdHVyZXMgKz0gIiwgSURFLVJlZGlyZWN0IjsNCiAgICAgICAgICAgICAgICBpZiAoa3ZtKSBmZWF0dXJlcyArPSAiLCBLVk0iOw0KICAgICAgICAgICAgICAgIGlmIChmZWF0dXJlcyA9PSAnJykgZmVhdHVyZXMgPSAiICBOb25lIjsNCiAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkFjdGl2ZSBGZWF0dXJlcyIsIGFkZExpbmtDb25kaXRpb25hbChmZWF0dXJlcy5zdWJzdHJpbmcoMiksICdzaG93RmVhdHVyZXNEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAoKGFtdHN5c3N0YXRlWydJUFNfS1ZNUmVkaXJlY3Rpb25TZXR0aW5nRGF0YSddICE9IG51bGwpICYmIChhbXRzeXNzdGF0ZVsnSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnXS5yZXNwb25zZSkpIHsNCiAgICAgICAgICAgICAgICB2YXIgZGVza3RvcFNldHRpbmdzID0gYW10c3lzc3RhdGVbJ0lQU19LVk1SZWRpcmVjdGlvblNldHRpbmdEYXRhJ10ucmVzcG9uc2U7DQogICAgICAgICAgICAgICAgdmFyIHNjcmVlbm5hbWUgPSAnUHJpbWFyeSBkaXNwbGF5JzsNCiAgICAgICAgICAgICAgICBpZiAoKGFtdHZlcnNpb24gPiA3KSAmJiAoZGVza3RvcFNldHRpbmdzWydEZWZhdWx0U2NyZWVuJ10gIT09IHVuZGVmaW5lZCkgJiYgKGRlc2t0b3BTZXR0aW5nc1snRGVmYXVsdFNjcmVlbiddIDwgMjU1KSkgeyBzY3JlZW5uYW1lID0gWydQcmltYXJ5IGRpc3BsYXknLCAnU2Vjb25kYXJ5IGRpc3BsYXknLCAnM3JkIGRpc3BsYXknXVtkZXNrdG9wU2V0dGluZ3NbJ0RlZmF1bHRTY3JlZW4nXV07IH0NCiAgICAgICAgICAgICAgICBmZWF0dXJlcyA9ICc8c3BhbiB0aXRsZT0iVGhlIGRlZmF1bHQgcmVtb3RlIGRpc3BsYXkgaXMgdGhlICcgKyBzY3JlZW5uYW1lLnRvTG93ZXJDYXNlKCkgKyAnIj4nICsgc2NyZWVubmFtZSArICI8L3NwYW4+IjsNCiAgICAgICAgICAgICAgICBpZiAoZGVza3RvcFNldHRpbmdzWydJczU5MDBQb3J0RW5hYmxlZCddID09IHRydWUpIHsgZmVhdHVyZXMgKz0gIiwgUG9ydCA1OTAwIGVuYWJsZWQiOyB9DQogICAgICAgICAgICAgICAgaWYgKGRlc2t0b3BTZXR0aW5nc1snT3B0SW5Qb2xpY3knXSA9PSB0cnVlKSB7IGZlYXR1cmVzICs9ICIsICIgKyBkZXNrdG9wU2V0dGluZ3NbJ09wdEluUG9saWN5VGltZW91dCddICsgIiBzZWNvbmQiICsgKChkZXNrdG9wU2V0dGluZ3NbJ09wdEluUG9saWN5VGltZW91dCddID4gMCk/J3MnOicnKSArICIgb3B0LWluIjsgfQ0KICAgICAgICAgICAgICAgIGZlYXR1cmVzICs9ICIsICIgKyBkZXNrdG9wU2V0dGluZ3NbJ1Nlc3Npb25UaW1lb3V0J10gKyAiIG1pbnV0ZSIgKyAoKGRlc2t0b3BTZXR0aW5nc1snU2Vzc2lvblRpbWVvdXQnXSA+IDApID8gJ3MnIDogJycpICsgIiBzZXNzaW9uIHRpbWVvdXQiOw0KDQogICAgICAgICAgICAgICAgLy8gU2NyZWVuIGJsYW5raW5nIG9uIEFNVCAxMCBhbmQgaGlnaGVyDQogICAgICAgICAgICAgICAgaWYgKChhbXR2ZXJzaW9uID4gOSkgJiYgKGFtdHN5c3N0YXRlWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXSAhPSBudWxsKSkgew0KICAgICAgICAgICAgICAgICAgICB2YXIgc2NyZWVuQmxhbmtpbmcgPSAoKGFtdHN5c3N0YXRlWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXS5yZXNwb25zZVsiRW5hYmxlZFN0YXRlIl0gJiAxKSAhPSAwKTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHNjcmVlbkJsYW5raW5nKSBmZWF0dXJlcyArPSAiLCBCbGFua2luZyBBbGxvd2VkIjsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIH0NCg0KDQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJSZW1vdGUgRGVza3RvcCIsIGFkZExpbmtDb25kaXRpb25hbChmZWF0dXJlcywgJ3Nob3dEZXNrdG9wU2V0dGluZ3NEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBJbnRlbCBBTVQgdXNlciBDb25zZW50DQogICAgICAgICAgICBpZiAoKGFtdHZlcnNpb24gPiA1KSAmJiAoYW10c3lzc3RhdGVbJ0lQU19PcHRJblNlcnZpY2UnXSAhPSBudWxsKSAmJiAoYW10c3lzc3RhdGVbJ0lQU19PcHRJblNlcnZpY2UnXS5yZXNwb25zZSAhPSB1bmRlZmluZWQpKSB7DQogICAgICAgICAgICAgICAgZmVhdHVyZXMgPSAiVW5rbm93biBzdGF0ZSI7DQogICAgICAgICAgICAgICAgdmFyIG9wdGlucmVxdWlyZWQgPSBhbXRzeXNzdGF0ZVsnSVBTX09wdEluU2VydmljZSddLnJlc3BvbnNlWyJPcHRJblJlcXVpcmVkIl07DQogICAgICAgICAgICAgICAgaWYgKG9wdGlucmVxdWlyZWQgPT0gMCkgeyBmZWF0dXJlcyA9ICJOb3QgUmVxdWlyZWQiOyB9DQogICAgICAgICAgICAgICAgaWYgKG9wdGlucmVxdWlyZWQgPT0gMSkgeyBmZWF0dXJlcyA9ICJSZXF1aXJlZCBmb3IgS1ZNIG9ubHkiOyB9DQogICAgICAgICAgICAgICAgaWYgKG9wdGlucmVxdWlyZWQgPT0gMHhGRkZGRkZGRikgeyBmZWF0dXJlcyA9ICJBbHdheXMgUmVxdWlyZWQiOyB9DQogICAgICAgICAgICAgICAgaWYgKGFtdHN5c3N0YXRlWydJUFNfT3B0SW5TZXJ2aWNlJ10ucmVzcG9uc2VbIkNhbk1vZGlmeU9wdEluUG9saWN5Il0gPT0gdHJ1ZSkgZmVhdHVyZXMgPSBhZGRMaW5rQ29uZGl0aW9uYWwoZmVhdHVyZXMsICdzaG93Q29uc2VudERsZygpJywgeHhBY2NvdW50QWRtaW5OYW1lKTsgLy8gSWYgd2UgY2FuIG1vZGlmeSB1c2VyIGNvbnNlbnQgc2V0dGluZ3MsIGFkZCB0aGUgbGluayB0byBkbyBpdC4NCiAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIlVzZXIgQ29uc2VudCIsIGZlYXR1cmVzKTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gSW50ZWwgQU1UIFBvd2VyIHBvbGljeQ0KICAgICAgICAgICAgaWYgKEFtdFN5c3RlbVBvd2VyU2NoZW1lcyAhPSBudWxsKSB7DQogICAgICAgICAgICAgICAgdmFyIGVsZW1lbnRTZXR0aW5ncyA9IGFtdHN5c3N0YXRlWydDSU1fRWxlbWVudFNldHRpbmdEYXRhJ10ucmVzcG9uc2VzOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxlbWVudFNldHRpbmdzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50U2V0dGluZ3NbaV1bJ1NldHRpbmdEYXRhJ10gJiYgZWxlbWVudFNldHRpbmdzW2ldWydJc0N1cnJlbnQnXSA9PSAxICYmIGVsZW1lbnRTZXR0aW5nc1tpXVsnU2V0dGluZ0RhdGEnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydSZXNvdXJjZVVSSSddID09ICdodHRwOi8vaW50ZWwuY29tL3diZW0vd3NjaW0vMS9hbXQtc2NoZW1hLzEvQU1UX1N5c3RlbVBvd2VyU2NoZW1lJykgew0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gRm91bmQgdGhlIGFjdGl2ZSBJbnRlbCBBTVQgcG93ZXIgc2NoZW1lDQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcG93ZXJndWlkID0gZWxlbWVudFNldHRpbmdzW2ldWydTZXR0aW5nRGF0YSddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ11bMV1bJ1ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3cgZmluZCB0aGUgbmFtZSBvZiB0aGUgcG93ZXIgc2NoZW1hIGluIHRoZSBBTVRfU3lzdGVtUG93ZXJTY2hlbWUgdGFibGUNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgQW10U3lzdGVtUG93ZXJTY2hlbWVzLmxlbmd0aDsgaisrKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKEFtdFN5c3RlbVBvd2VyU2NoZW1lc1tqXVsnU2NoZW1lR1VJRCddID09IHBvd2VyZ3VpZCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGb3VuZCB0aGUgcG93ZXIgc2NoZW1lIG5hbWUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJQb3dlciBQb2xpY3kiLCBhZGRMaW5rQ29uZGl0aW9uYWwoQW10U3lzdGVtUG93ZXJTY2hlbWVzW2pdWydEZXNjcmlwdGlvbiddLnNwbGl0KCc6JyApWzFdLCAic2hvd1Bvd2VyUG9saWN5RGxnKFwiIiArIHBvd2VyZ3VpZCArICJcIikiLCB4eEFjY291bnRBZG1pbk5hbWUpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIGlmIChhbXRkZWx0YXRpbWUpIHsgeCArPSBUYWJsZUVudHJ5KCJEYXRlICYgVGltZSIsIG5ldyBEYXRlKG5ldyBEYXRlKCkuZ2V0VGltZSgpICsgYW10ZGVsdGF0aW1lKS50b0xvY2FsZVN0cmluZygpKTsgfQ0KICAgICAgICAgICAgdmFyIGJ1dHRvbnMgPSBBZGRSZWZyZXNoQnV0dG9uKCJQdWxsU3lzdGVtU3RhdHVzKCkiKSArICIgIjsNCg0KICAgICAgICAgICAgYnV0dG9ucyArPSBBZGRCdXR0b24oIlNhdmUgU3RhdGUuLi4iLCAic2F2ZUVudGlyZUFtdFN0YXRlKCkiKSArICIgIjsNCg0KICAgICAgICAgICAgYnV0dG9ucyArPSBBZGRCdXR0b24oIlJ1biBTY3JpcHQuLi4iLCAic2NyaXB0X3J1blNjcmlwdERsZygpIikgKyAiICI7DQogICAgICAgICAgICB4ICs9IFRhYmxlRW5kKGJ1dHRvbnMpOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlU3lzU3RhdHVzJywgeCk7DQoNCg0KICAgICAgICAgICAgdmFyIHggPSAiPHRhYmxlIGNsYXNzPWxvZzEgY2VsbHBhZGRpbmc9MCBjZWxsc3BhY2luZz0wIHN0eWxlPXdpZHRoOjEwMCU7Ym9yZGVyLXJhZGl1czo4cHg+IjsNCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoIjxkaXY+Jm5ic3A7IiArIEFkZFJlZnJlc2hCdXR0b24oIlB1bGxTeXN0ZW1TdGF0dXMoMSkiKQ0KDQogICAgICAgICAgICAgICAgKyAnIENoYW5naW5nIG5ldHdvcmsgc2V0dGluZ3MgbWF5IGNhdXNlIHRoaXMgcGFnZSB0byBiZSB1bmF2YWlsYWJsZSBmb3IgYSBmZXcgc2Vjb25kcy4nDQogICAgICAgICAgICApOw0KDQogICAgICAgICAgICAvLyBHZW5lcmFsIHNldHRpbmdzDQogICAgICAgICAgICB4ICs9ICI8YnI+PGgyPkdlbmVyYWwgU2V0dGluZ3M8L2gyPiI7DQogICAgICAgICAgICB4ICs9IFRhYmxlU3RhcnQoKTsNCg0KICAgICAgICAgICAgLy8gTmV0d29yayBzdGF0ZQ0KICAgICAgICAgICAgLy8gaWYgKGdzWyJBTVROZXR3b3JrRW5hYmxlZCJdKSB7IHggKz0gVGFibGVFbnRyeSgiTmV0d29yayBzdGF0ZSIsIChnc1siQU1UTmV0d29ya0VuYWJsZWQiXT09MSk/IkVuYWJsZWQiOiJEaXNhYmxlZCIpOyB9DQoNCiAgICAgICAgICAgIC8vIFNoYXJlZCBGUURODQogICAgICAgICAgICB2YXIgZnFkbnNoYXJlID0gJyc7DQogICAgICAgICAgICBpZiAoaG9zdCAhPSAiPGk+Tm9uZTwvaT4iKSB7DQogICAgICAgICAgICAgICAgaWYgKGdzWyJTaGFyZWRGUUROIl0gPT0gdHJ1ZSkgZnFkbnNoYXJlID0gJywgc2hhcmVkIHdpdGggT1MnOw0KICAgICAgICAgICAgICAgIGlmIChnc1siU2hhcmVkRlFETiJdID09IGZhbHNlKSBmcWRuc2hhcmUgPSAnLCBkaWZmZXJlbnQgZnJvbSBPUyc7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIk5hbWUgJiBEb21haW4iLCBhZGRMaW5rQ29uZGl0aW9uYWwoaG9zdCArIGZxZG5zaGFyZSwgJ3Nob3dFZGl0TmFtZURsZygxKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KDQogICAgICAgICAgICAvLyBEeW5hbWljIEROUw0KICAgICAgICAgICAgdmFyIGRkbnMgPSAnRGlzYWJsZWQnOw0KICAgICAgICAgICAgaWYgKGdzWyJERE5TVXBkYXRlRW5hYmxlZCJdID09IHRydWUpIHsNCiAgICAgICAgICAgICAgICBkZG5zID0gIkVuYWJsZWQgZWFjaCAiICsgZ3NbIkRETlNQZXJpb2RpY1VwZGF0ZUludGVydmFsIl0gKyAiIG1pbnV0ZXMsIFRUTCBpcyAiICsgZ3NbIkRETlNUVEwiXSArICIgbWludXRlcyI7DQogICAgICAgICAgICB9IGVsc2UgaWYgKGdzWyJERE5TVXBkYXRlQnlESENQU2VydmVyRW5hYmxlZCJdID09IHRydWUpIHsNCiAgICAgICAgICAgICAgICBkZG5zID0gIlVwZGF0ZSBieSBESENQIHNlcnZlciI7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkR5bmFtaWMgRE5TIiwgYWRkTGlua0NvbmRpdGlvbmFsKGRkbnMsICdzaG93RWRpdERuc0RsZygpJywgeHhBY2NvdW50QWRtaW5OYW1lKSk7DQogICAgICAgICAgICB4ICs9IFRhYmxlRW5kKCk7DQoNCiAgICAgICAgICAgIGZvciAodmFyIHkgaW4gYW10c3lzc3RhdGVbJ0FNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyddLnJlc3BvbnNlcykgew0KICAgICAgICAgICAgICAgIHZhciB6ID0gYW10c3lzc3RhdGVbJ0FNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyddLnJlc3BvbnNlc1t5XTsNCiAgICAgICAgICAgICAgICBpZiAoelsnV0xBTkxpbmtQcm90ZWN0aW9uTGV2ZWwnXSB8fCAoeSA9PSAxKSkgeyBhbXR3aXJlbGVzc2lmID0geTsgfSAvLyBTZXQgdGhlIHdpcmVsZXNzIGludGVyZmFjZSwgdGhpcyBzZWVtcyB0byBjb3ZlciBuZXcgd2lyZWxlc3Mgb25seSBjb21wdXRlcnMgYW5kIG9sZGVyIGNvbXB1dGVycyB3aXRoIGR1YWwgaW50ZXJmYWNlcy4NCiAgICAgICAgICAgICAgICBpZiAoKHkgPT0gMCkgJiYgKGFtdHdpcmVsZXNzaWYgIT0geSkgJiYgKHpbIk1BQ0FkZHJlc3MiXSA9PSAiMDAtMDAtMDAtMDAtMDAtMDAiKSkgeyBjb250aW51ZTsgfSAvLyBPbiBjb21wdXRlcnMgd2l0aCBvbmx5IHdpcmVsZXNzLCB0aGUgd2lyZWQgaW50ZXJmYWNlIHdpbGwgaGF2ZSBhIG51bGwgTUFDLCBza2lwIGl0Lg0KICAgICAgICAgICAgICAgIGlmICh5ID09IDApIHN5c3RlbWRlZmVuc2UrKzsNCiAgICAgICAgICAgICAgICB4ICs9ICI8YnI+PGgyPiIgKyAoKGFtdHdpcmVsZXNzaWYgPT0geSk/J1dpcmVsZXNzJzonV2lyZWQnKSArICIgSW50ZXJmYWNlPC9oMj4iOw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVTdGFydCgpOw0KDQogICAgICAgICAgICAgICAgLyoNCiAgICAgICAgICAgICAgICB2YXIgbHAgPSBbXSwgbGlua3BvbGljeSA9IE1ha2VUb0FycmF5KHpbIkxpbmtQb2xpY3kiXSk7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBsaW5rcG9saWN5KSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBhcCA9IGxpbmtwb2xpY3lbcF07DQogICAgICAgICAgICAgICAgICAgIGlmIChhcCA9PSAxKSBscC5wdXNoKCJTMC9BQyIpOw0KICAgICAgICAgICAgICAgICAgICBpZiAoYXAgPT0gMTQpIGxwLnB1c2goIlN4L0FDIik7DQogICAgICAgICAgICAgICAgICAgIGlmIChhcCA9PSAxNikgbHAucHVzaCgiUzAvREMiKTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGFwID09IDIyNCkgbHAucHVzaCgiU3gvREMiKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJMaW5rIHN0YXRlIiwgKHpbIkxpbmtJc1VwIl0gPT0gdHJ1ZT8nTGluayBpcyB1cCc6J0xpbmsgaXMgZG93bicpICsgIiwgYXZhaWxhYmxlIGluICIgKyBscC5qb2luKCcsICcpKTsNCiAgICAgICAgICAgICAgICAqLw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiTGluayBzdGF0ZSIsICh6WyJMaW5rSXNVcCJdID09IHRydWU/J0xpbmsgaXMgdXAnOidMaW5rIGlzIGRvd24nKSk7DQogICAgICAgICAgICAgICAgaWYgKHpbIk1BQ0FkZHJlc3MiXSAhPSAiMDAtMDAtMDAtMDAtMDAtMDAiKSB7IHggKz0gVGFibGVFbnRyeSgiTUFDIGFkZHJlc3MiLCB6WyJNQUNBZGRyZXNzIl0pOyB9DQoNCg0KICAgICAgICAgICAgICAgIGlmICgoYW10d2lyZWxlc3NpZiA9PSB5KSAmJiB4eFdpcmVsZXNzICYmIHh4V2lyZWxlc3NbJ0NJTV9XaUZpUG9ydENhcGFiaWxpdGllcyddLnJlc3BvbnNlKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIFN0YXJ0IGFuZCBzdGF0ZQ0KICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIlN0YXRlIiwgYWRkTGlua0NvbmRpdGlvbmFsKHh4V2lmaVN0YXRlW3h4V2lyZWxlc3NbJ0NJTV9XaUZpUG9ydCddLnJlc3BvbnNlWyJFbmFibGVkU3RhdGUiXV0sICdzaG93V2lmaVN0YXRlRGxnKCknLCB4eEFjY291bnRBZG1pbk5hbWUpKTsNCiAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIC8qIFRoaXMgaXMgbm90IHRoYXQgdXNlZnVsDQogICAgICAgICAgICAgICAgICAgIC8vIENhcGFiaWxpdGllcw0KICAgICAgICAgICAgICAgICAgICB2YXIgcyA9ICcnLCBzYyA9IHh4V2lyZWxlc3NbJ0NJTV9XaUZpUG9ydENhcGFiaWxpdGllcyddLnJlc3BvbnNlLCBzdXBwb3J0ZWRUeXBlcyA9IHNjWyJTdXBwb3J0ZWRQb3J0VHlwZXMiXTsNCiAgICAgICAgICAgICAgICAgICAgZm9yIChpIGluIHN1cHBvcnRlZFR5cGVzKSB7IHMgKz0gIiwgODAyLjExIiArICJhYmduIltzdXBwb3J0ZWRUeXBlc1tpXSAtIDcwXTsgfQ0KICAgICAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkNhcGFiaWxpdGVzIiwgcy5zdWJzdHJpbmcoMikpOw0KICAgICAgICAgICAgICAgICAgICAqLw0KDQogICAgICAgICAgICAgICAgICAgIC8vIEN1cnJlbnQgcmFkaW8gc3RhdGUNCiAgICAgICAgICAgICAgICAgICAgcyA9IHh4V2lyZWxlc3NbJ0NJTV9XaUZpRW5kcG9pbnQnXS5yZXNwb25zZVsnTEFOSUQnXTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJSYWRpbyBTdGF0ZSIsIHh4UmFkaW9TdGF0ZVt4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50J10ucmVzcG9uc2VbJ0VuYWJsZWRTdGF0ZSddXSArICIsIFNTSUQ6ICIgKyAocz9zOiI8aT5Ob25lPC9pPiIpKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICBpZiAoYW10d2lyZWxlc3NpZiAhPSB5KSB7DQogICAgICAgICAgICAgICAgICAgIC8vIFRoaW5ncyB0aGF0IGFyZSBzcGVjaWZpYyB0byB0aGUgd2lyZWQgaW50ZXJmYWNlDQogICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiUmVzcG9uZCB0byBwaW5nIiwgYWRkTGlua0NvbmRpdGlvbmFsKFsiRGlzYWJsZWQiLCJJQ01QIHJlc3BvbnNlIiwiUk1DUCByZXNwb25zZSIsIklDTVAgJiBSTUNQIHJlc3BvbnNlIl1bZ3NbIlBpbmdSZXNwb25zZUVuYWJsZWQiXSArIChnc1siUm1jcFBpbmdSZXNwb25zZUVuYWJsZWQiXSA8PCAxKV0sICJzaG93UGluZ0FjdGlvbkRsZygpIiwgeHhBY2NvdW50QWRtaW5OYW1lKSk7DQogICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NCBzdGF0ZSIsIGFkZExpbmtDb25kaXRpb25hbCh6WyJESENQRW5hYmxlZCJdID09IHRydWU/IkF1dG9tYXRpYyB1c2luZyBESENQIHNlcnZlciI6IlN0YXRpYyBJUCBhZGRyZXNzIiwgInNob3dJUFNldHVwRGxnKCkiLCB4eEFjY291bnRBZG1pbk5hbWUpKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAvLyBEaXNwbGF5IElQdjQgY3VycmVudCBzZXR0aW5ncw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NCBhZGRyZXNzIiwgaXNJcEFkZHJlc3MoelsiSVBBZGRyZXNzIl0sIk5vbmUiKSk7DQogICAgICAgICAgICAgICAgaWYgKGlzSXBBZGRyZXNzKHpbIkRlZmF1bHRHYXRld2F5Il0pKSB7IHggKz0gVGFibGVFbnRyeSgiSVB2NCBnYXRld2F5IC8gTWFzayIsIHpbIkRlZmF1bHRHYXRld2F5Il0gKyAiIC8gIiArIGlzSXBBZGRyZXNzKHpbIlN1Ym5ldE1hc2siXSwiTm9uZSIpKTsgfQ0KICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgIHZhciBkbnMgPSB6WyJQcmltYXJ5RE5TIl07DQogICAgICAgICAgICAgICAgaWYgKGlzSXBBZGRyZXNzKGRucykpIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHpbIlNlY29uZGFyeUROUyJdKSBkbnMgKz0gIiAvICIgKyB6WyJTZWNvbmRhcnlETlMiXTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJJUHY0IGRvbWFpbiBuYW1lIHNlcnZlciIsIGRucyk7DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgaWYgKChhbXRzeXNzdGF0ZVsnSVBTX0lQdjZQb3J0U2V0dGluZ3MnXS5zdGF0dXMgPT0gMjAwKSAmJiAoYW10dmVyc2lvbiA+IDUpKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIElQdjYgaXMgZW5hYmxlZCBmb3IgdGhpcyBpbnRlcmZhY2UNCiAgICAgICAgICAgICAgICAgICAgdmFyIHp6ID0gYW10c3lzc3RhdGVbJ0lQU19JUHY2UG9ydFNldHRpbmdzJ10ucmVzcG9uc2VzW3ldOw0KICAgICAgICAgICAgICAgICAgICB2YXIgaXB2NnN0YXRlID0gJ0Rpc2FibGVkJywgaXB2NiwgaXB2Nm1hbnVhbCwgZWxlbWVudFNldHRpbmdzID0gYW10c3lzc3RhdGVbJ0NJTV9FbGVtZW50U2V0dGluZ0RhdGEnXS5yZXNwb25zZXM7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZWxlbWVudFNldHRpbmdzLmxlbmd0aDsgaSsrKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbWVudFNldHRpbmdzW2ldWydTZXR0aW5nRGF0YSddICYmIGVsZW1lbnRTZXR0aW5nc1tpXVsnU2V0dGluZ0RhdGEnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWydWYWx1ZSddID09ICdJbnRlbChyKSBJUFMgSVB2NiBTZXR0aW5ncyAnICsgeSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlwdjYgPSAoZWxlbWVudFNldHRpbmdzW2ldWydJc0N1cnJlbnQnXSA9PSAxKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIG1hbnVhbCBhZGRyZXNzZXMgaGF2ZSBiZWVuIGFkZGVkDQogICAgICAgICAgICAgICAgICAgIGlmIChpcHY2ID09IHRydWUpIHsgDQogICAgICAgICAgICAgICAgICAgICAgICBpcHY2bWFudWFsID0gaXNJcEFkZHJlc3MoenpbIklQdjZBZGRyZXNzIl0pIHx8IGlzSXBBZGRyZXNzKHp6WyJEZWZhdWx0Um91dGVyIl0pIHx8IGlzSXBBZGRyZXNzKHp6WyJQcmltYXJ5RE5TIl0pIHx8IGlzSXBBZGRyZXNzKHp6WyJTZWNvbmRhcnlETlMiXSk7DQogICAgICAgICAgICAgICAgICAgICAgICBpcHY2c3RhdGUgPSAnRW5hYmxlZCwgQXV0b21hdGljICcgKyAoaXB2Nm1hbnVhbD8iJiBtYW51YWwiOiIiKSArICIgYWRkcmVzc2VzIjsNCiAgICAgICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgICAgIC8vIERpc3BsYXkgSVB2NiBjdXJyZW50IHNldHRpbmdzDQogICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NiBzdGF0ZSIsIGFkZExpbmtDb25kaXRpb25hbChpcHY2c3RhdGUsICJzaG93SVB2NlN0YXRlRGxnKCIgKyB5ICsgIiwiICsgaXB2NiArICIpIiwgeHhBY2NvdW50QWRtaW5OYW1lKSk7DQogICAgICAgICAgICAgICAgICAgIGlmIChpcHY2ID09IHRydWUpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh6elsiQ3VycmVudEFkZHJlc3NJbmZvIl0gJiYgenpbIkN1cnJlbnRBZGRyZXNzSW5mbyJdLmxlbmd0aCA+IDApIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB6elsiQ3VycmVudEFkZHJlc3NJbmZvIl0gPSBNYWtlVG9BcnJheSh6elsiQ3VycmVudEFkZHJlc3NJbmZvIl0pOyAvLyBCZWNhdXNlIG91ciBXU01BTiBzdGFjayBkb2VzIG5vdCBrbm93IGlmIHRoaXMgaXMgYSBhcnJheSwgd2UgbmVlZCB0byBtYWtlIGl0IGFuIGFycmF5IGlmIGl0IGNvbnRhaW5zIDEgZWxlbWVudC4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcHY2YWRkciA9ICcnOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgenpbIkN1cnJlbnRBZGRyZXNzSW5mbyJdLmxlbmd0aDsgaSsrKSB7IGlmIChpcHY2YWRkci5sZW5ndGggPiAwKSBpcHY2YWRkciArPSAiLCAiOyBpcHY2YWRkciArPSB6elsiQ3VycmVudEFkZHJlc3NJbmZvIl1baV0uc3BsaXQoJywnKVswXTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NiBhZGRyZXNzIiwgYWRkTGluayhpcHY2YWRkciwgInNob3dJUHY2QWRkckRsZygiICsgeSArICIsXCIiICsgenpbIkN1cnJlbnRBZGRyZXNzSW5mbyJdICsgIlwiKSIpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJJUHY2IGFkZHJlc3MiLCAnTm9uZScpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzSXBBZGRyZXNzKHp6WyJDdXJyZW50RGVmYXVsdFJvdXRlciJdKSkgeyB4ICs9IFRhYmxlRW50cnkoIklQdjYgZGVmYXVsdCByb3V0ZXIiLCB6elsiQ3VycmVudERlZmF1bHRSb3V0ZXIiXSk7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0lwQWRkcmVzcyh6elsiQ3VycmVudFByaW1hcnlETlMiXSkpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZG5zID0genpbIkN1cnJlbnRQcmltYXJ5RE5TIl07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzSXBBZGRyZXNzKHp6WyJDdXJyZW50U2Vjb25kYXJ5RE5TIl0pKSBkbnMgKz0gIiAvICIgKyB6elsiQ3VycmVudFNlY29uZGFyeUROUyJdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiSVB2NiBkb21haW4gbmFtZSBzZXJ2ZXIiLCBkbnMpOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBPbmx5IGRvIG1vcmUgV1NNQU4gaWYgd2UgbmVlZCBpdA0KICAgICAgICAgICAgaWYgKCh1cmx2YXJzWydrdm1vbmx5J10gIT0gMSkgJiYgKGZ1bGxzY3JlZW5vbmx5ID09IGZhbHNlKSkgew0KDQogICAgICAgICAgICAgICAgLy8gSWYgdGhlcmUgaXMgYSB3aXJlbGVzcyBpbnRlcmZhY2UsIGdldCB0aGUgZGF0YSBmb3IgaXQuIElmIG5vdCwgc2hvdyB0aGF0IHRoZXJlIGlzIG5vdC4NCiAgICAgICAgICAgICAgICBpZiAoYW10d2lyZWxlc3NpZiAhPSAtMSkgeyBpZiAoKGFtdEZpcnN0UHVsbCAmIDIpID09IDApIFB1bGxXaXJlbGVzcygpOyB9DQogICAgICAgICAgICAgICAgUUgoJ2lkX1RhYmxlTmV0d29ya1NldHRpbmdzU3BhbicsIHgpOw0KDQoNCiAgICAgICAgICAgICAgICAvLyBJZiBpbiBBQ00gbW9kZSBhbmQgd2UgaGF2ZSBhIHdpcmVkIGludGVyZmFjZSwgcHVsbCBTeXN0ZW0gRGVmZW5zZSBpbmZvcm1hdGlvbg0KICAgICAgICAgICAgICAgIGlmICgoc3lzdGVtZGVmZW5zZSA9PSAxKSAmJiAoKGFtdEZpcnN0UHVsbCAmIDQpID09IDApKSBQdWxsU3lzdGVtRGVmZW5zZSgpOw0KDQoNCiAgICAgICAgICAgICAgICBpZiAoKChhbXRGaXJzdFB1bGwgJiA4KSA9PSAwKSAmJiAoYW10dmVyc2lvbiA+IDExIHx8IChhbXR2ZXJzaW9uID09IDExICYmIGFtdHZlcnNpb25taW4gPiA1KSkpIHsgUHVsbFN0b3JhZ2UoKTsgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICBpZiAoY3VycmVudFZpZXcgPT0gMCkgZ28oMSwgMSk7IC8vIElmIHdlIGFyZSBhdCB0aGUgbG9hZGluZyBzY3JlZW4sIG1vc3QgdG8gU3lzdGVtIFN0YXR1cyBzY3JlZW4NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGlzSXBBZGRyZXNzKHQsIHgpIHsgcmV0dXJuICh0ICYmIHQgIT0gbnVsbCAmJiB0Lmxlbmd0aCA+IDAgJiYgdCAhPSAnOjonICYmIHQgIT0gJzo6MCcpP3Q6eDsgfQ0KDQoNCiAgICAgICAgdmFyIEludGVsQW10RW50aXJlU3RhdGU7DQogICAgICAgIHZhciBJbnRlbEFtdEVudGlyZVN0YXRlQ2FsbHM7DQogICAgICAgIGZ1bmN0aW9uIHNhdmVFbnRpcmVBbXRTdGF0ZSgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBuID0gJycsIGQgPSBuZXcgRGF0ZSgpOw0KICAgICAgICAgICAgaWYgKGFtdHN5c3N0YXRlKSB7IG4gPSAiLSIgKyBhbXRzeXNzdGF0ZVsnQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlWydIb3N0TmFtZSddOyB9DQogICAgICAgICAgICBuICs9ICctJyArIGQuZ2V0RnVsbFllYXIoKSArICItIiArICgiMCIrKGQuZ2V0TW9udGgoKSsxKSkuc2xpY2UoLTIpICsgIi0iICsgKCIwIiArIGQuZ2V0RGF0ZSgpKS5zbGljZSgtMikgKyAiLSIgKyAoIjAiICsgZC5nZXRIb3VycygpKS5zbGljZSgtMikgKyAiLSIgKyAoIjAiICsgZC5nZXRNaW51dGVzKCkpLnNsaWNlKC0yKTs7DQogICAgICAgICAgICBpZHhfZDE5c2F2ZXN0YXRlZmlsZW5hbWUudmFsdWUgPSAnYW10c3RhdGUnICsgbiArICcuanNvbic7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDE5LCAiU2F2ZSBFbnRpcmUgSW50ZWwmcmVnOyBBTVQgU3RhdGUiLCAzLCBzYXZlRW50aXJlQW10U3RhdGVPayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzYXZlRW50aXJlQW10U3RhdGVPaygpIHsNCiAgICAgICAgICAgIEludGVsQW10RW50aXJlU3RhdGUgPSB7ICd3ZWJhcHB2ZXJzaW9uJzp2ZXJzaW9uLCdsb2NhbHRpbWUnOkRhdGUoKSwndXRjdGltZSc6bmV3IERhdGUoKS50b1VUQ1N0cmluZygpLCdpc290aW1lJzpuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCkgfTsNCiAgICAgICAgICAgIFFIKCdpZF9kaWFsb2dNZXNzYWdlJywgJ0ZldGNoaW5nIGVudGlyZSBzdGF0ZSwgcGxlYXNlIHdhaXQuLi4nKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMSwgIlNhdmUgRW50aXJlIEludGVsJnJlZzsgQU1UIFN0YXRlIiwgMCwgbnVsbCk7DQoNCiAgICAgICAgICAgIC8vIEZldGNoIGV2ZXJ5dGhpbmchDQogICAgICAgICAgICBJbnRlbEFtdEVudGlyZVN0YXRlQ2FsbHMgPSAzOw0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKG51bGwsIEFsbFdzbWFuLCBzYXZlRW50aXJlQW10U3RhdGVPazIsIG51bGwsIHRydWUpOw0KICAgICAgICAgICAgYW10c3RhY2suR2V0QXVkaXRMb2coc2F2ZUVudGlyZUFtdFN0YXRlT2szKTsNCiAgICAgICAgICAgIGFtdHN0YWNrLkdldE1lc3NhZ2VMb2coc2F2ZUVudGlyZUFtdFN0YXRlT2s0KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNhdmVFbnRpcmVBbXRTdGF0ZU9rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsgSW50ZWxBbXRFbnRpcmVTdGF0ZVsnd3NtYW5lbnVtcyddID0gcmVzcG9uc2VzOyBzYXZlRW50aXJlQW10U3RhdGVEb25lKCk7IH0NCiAgICAgICAgZnVuY3Rpb24gc2F2ZUVudGlyZUFtdFN0YXRlT2szKHN0YWNrLCBtZXNzYWdlcykgeyBJbnRlbEFtdEVudGlyZVN0YXRlWydhdWRpdGxvZyddID0gbWVzc2FnZXM7IHNhdmVFbnRpcmVBbXRTdGF0ZURvbmUoKTsgfQ0KICAgICAgICBmdW5jdGlvbiBzYXZlRW50aXJlQW10U3RhdGVPazQoc3RhY2ssIG1lc3NhZ2VzKSB7IEludGVsQW10RW50aXJlU3RhdGVbJ2V2ZW50bG9nJ10gPSBtZXNzYWdlczsgc2F2ZUVudGlyZUFtdFN0YXRlRG9uZSgpOyB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2F2ZUVudGlyZUFtdFN0YXRlRG9uZSgpIHsNCiAgICAgICAgICAgIGlmICgtLUludGVsQW10RW50aXJlU3RhdGVDYWxscyAhPSAwKSByZXR1cm47DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKCk7DQoNCiAgICAgICAgICAgIHNhdmVBcyhkYXRhMmJsb2IoSlNPTi5zdHJpbmdpZnkoSW50ZWxBbXRFbnRpcmVTdGF0ZSwgbnVsbCwgJyAgJykucmVwbGFjZSgvXG4vZywgJ1xyXG4nKSksIGlkeF9kMTlzYXZlc3RhdGVmaWxlbmFtZS52YWx1ZSk7DQogICAgICAgIH0NCg0KDQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0Rlc2t0b3BTZXR0aW5nc0RsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBkZXNrdG9wU2V0dGluZ3MgPSBhbXRzeXNzdGF0ZVsnSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnXS5yZXNwb25zZTsNCiAgICAgICAgICAgIHZhciB4ID0gJzxkaXYgc3R5bGU9dGV4dC1hbGlnbjpsZWZ0Pic7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9c3ViZGRpc3BsYXkgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHg+PG9wdGlvbiB2YWx1ZT0wPlByaW1hcnkgZGlzcGxheTwvb3B0aW9uPjxvcHRpb24gdmFsdWU9MT5TZWNvbmRhcnkgZGlzcGxheTwvb3B0aW9uPiI7DQogICAgICAgICAgICBpZiAoYW10dmVyc2lvbiA+IDkpIHsgeCArPSAiPG9wdGlvbiB2YWx1ZT0yPjNyZCBkaXNwbGF5PC9vcHRpb24+IjsgfQ0KICAgICAgICAgICAgeCArPSAiPC9zZWxlY3Q+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+RGVmYXVsdCBkaXNwbGF5PC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPXN1YnNlc3Npb250aW1lb3V0IHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IG1heGxlbmd0aD01IG9ua2V5cHJlc3M9J3JldHVybiBudW1iZXJzT25seShldmVudCknPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PlNlc3Npb24gdGltZW91dCAoTWludXRlcyk8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgaWYgKGRlc2t0b3BTZXR0aW5nc1snT3B0SW5Qb2xpY3knXSA9PSB0cnVlKSB7IHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPXN1Ym9wdGludGltZW91dCBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBtYXhsZW5ndGg9NSBvbmtleXByZXNzPSdyZXR1cm4gbnVtYmVyc09ubHkoZXZlbnQpJz48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5PcHQtaW4gdGltZW91dCAoU2Vjb25kcyk8L2Rpdj48L2Rpdj4iOyB9DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9c3ViZGxlZ2FjeSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBvbmNoYW5nZT1zaG93RGVza3RvcFNldHRpbmdzRGxnVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0wPkRpc2FibGVkLCBSZWNvbW1lbmRlZDwvb3B0aW9uPjxvcHRpb24gdmFsdWU9MT5FbmFibGVkLCBMZWdhY3kgS1ZNIHZpZXdlcnM8L29wdGlvbj48L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5Qb3J0IDU5MDA8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweCBpZD1zdWJzcGFzc3g+PGlucHV0IGlkPXN1YnNwYXNzIHR5cGU9cGFzc3dvcmQgYXV0b2NvbXBsZXRlPW9mZiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBtYXhsZW5ndGg9OCBvbmtleXVwPXNob3dEZXNrdG9wU2V0dGluZ3NEbGdVcGRhdGUoKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD41OTAwIHBhc3N3b3JkICg4IGNoYXJzKTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICBpZiAoKGFtdHZlcnNpb24gPiA5KSAmJiAoYW10c3lzc3RhdGVbJ0lQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSddICE9IG51bGwpKSB7IHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PHNlbGVjdCBpZD1zdWJzYiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBvbmNoYW5nZT1zaG93RGVza3RvcFNldHRpbmdzRGxnVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0wPkRpc2FibGVkPC9vcHRpb24+PG9wdGlvbiB2YWx1ZT0xPkVuYWJsZWQ8L29wdGlvbj48L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweCB0aXRsZT0nVGhpcyBmZWF0dXJlIGlzIG5vdCBvZnRlbiBzdXBwb3J0ZWQnPlNjcmVlbiBCbGFua2luZzwvZGl2PjwvZGl2PiI7IH0NCiAgICAgICAgICAgIHggKz0gIjwvZGl2PiI7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiUmVtb3RlIERlc2t0b3AgU2V0dGluZ3MiLCAzLCBzaG93RGVza3RvcFNldHRpbmdzRGxnT2ssIHgpOw0KICAgICAgICAgICAgUSgnc3ViZGRpc3BsYXknKS52YWx1ZSA9IGRlc2t0b3BTZXR0aW5nc1snRGVmYXVsdFNjcmVlbiddOw0KICAgICAgICAgICAgUSgnc3Vic2Vzc2lvbnRpbWVvdXQnKS52YWx1ZSA9IGRlc2t0b3BTZXR0aW5nc1snU2Vzc2lvblRpbWVvdXQnXTsNCiAgICAgICAgICAgIGlmIChkZXNrdG9wU2V0dGluZ3NbJ09wdEluUG9saWN5J10gPT0gdHJ1ZSkgeyBRKCdzdWJvcHRpbnRpbWVvdXQnKS52YWx1ZSA9IGRlc2t0b3BTZXR0aW5nc1snT3B0SW5Qb2xpY3lUaW1lb3V0J107IH0NCiAgICAgICAgICAgIFEoJ3N1YmRsZWdhY3knKS52YWx1ZSA9ICgoZGVza3RvcFNldHRpbmdzWydJczU5MDBQb3J0RW5hYmxlZCddID09IHRydWUpID8gMSA6IDApOw0KICAgICAgICAgICAgaWYgKChhbXR2ZXJzaW9uID4gOSkgJiYgKGFtdHN5c3N0YXRlWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXSAhPSBudWxsKSkgeyBRKCdzdWJzYicpLnZhbHVlID0gYW10c3lzc3RhdGVbJ0lQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSddLnJlc3BvbnNlWyJFbmFibGVkU3RhdGUiXTsgfQ0KICAgICAgICAgICAgc2hvd0Rlc2t0b3BTZXR0aW5nc0RsZ1VwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0Rlc2t0b3BTZXR0aW5nc0RsZ1VwZGF0ZSgpIHsNCiAgICAgICAgICAgIFFWKCdzdWJzcGFzc3gnLCAoUSgnc3ViZGxlZ2FjeScpLnZhbHVlID09IDEpKTsNCiAgICAgICAgICAgIHZhciBvayA9ICgoUSgnc3ViZGxlZ2FjeScpLnZhbHVlID09IDApIHx8IChRKCdzdWJzcGFzcycpLnZhbHVlLmxlbmd0aCA9PSA4KSB8fCAoUSgnc3Vic3Bhc3MnKS52YWx1ZS5sZW5ndGggPT0gMCkpICYmIChRKCdzdWJzZXNzaW9udGltZW91dCcpLnZhbHVlLmxlbmd0aCA+IDApOw0KICAgICAgICAgICAgaWYgKChhbXRzeXNzdGF0ZVsnSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnXS5yZXNwb25zZVsnT3B0SW5Qb2xpY3knXSA9PSB0cnVlKSAmJiAoUSgnc3Vib3B0aW50aW1lb3V0JykudmFsdWUubGVuZ3RoID09IDApKSB7IG9rID0gZmFsc2U7IH0NCiAgICAgICAgICAgIFFFKCdpZHhfZGxnT2tCdXR0b24nLCBvayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93RGVza3RvcFNldHRpbmdzRGxnT2soKSB7DQogICAgICAgICAgICB2YXIgeCA9IENsb25lKGFtdHN5c3N0YXRlWydJUFNfS1ZNUmVkaXJlY3Rpb25TZXR0aW5nRGF0YSddLnJlc3BvbnNlKTsNCiAgICAgICAgICAgIHhbJ0RlZmF1bHRTY3JlZW4nXSA9IFEoJ3N1YmRkaXNwbGF5JykudmFsdWUNCiAgICAgICAgICAgIHhbJ1Nlc3Npb25UaW1lb3V0J10gPSBRKCdzdWJzZXNzaW9udGltZW91dCcpLnZhbHVlOw0KICAgICAgICAgICAgeFsnSXM1OTAwUG9ydEVuYWJsZWQnXSA9IChRKCdzdWJkbGVnYWN5JykudmFsdWUgPT0gMSk7DQogICAgICAgICAgICBpZiAoeFsnT3B0SW5Qb2xpY3knXSA9PSB0cnVlKSB7IHhbJ09wdEluUG9saWN5VGltZW91dCddID0gUSgnc3Vib3B0aW50aW1lb3V0JykudmFsdWU7IH0NCiAgICAgICAgICAgIGlmICh4WydJczU5MDBQb3J0RW5hYmxlZCddID09IHRydWUpIHsgeFsnUkZCUGFzc3dvcmQnXSA9IFEoJ3N1YnNwYXNzJykudmFsdWU7IH0NCiAgICAgICAgICAgIGFtdHN0YWNrLlB1dCgnSVBTX0tWTVJlZGlyZWN0aW9uU2V0dGluZ0RhdGEnLCB4LCBzaG93RGVza3RvcFNldHRpbmdzRGxnT2syKTsNCg0KICAgICAgICAgICAgLy8gU2NyZWVuIGJsYW5raW5nDQogICAgICAgICAgICB2YXIgeSA9IENsb25lKGFtdHN5c3N0YXRlWydJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnXS5yZXNwb25zZSk7DQogICAgICAgICAgICB5WydFbmFibGVkU3RhdGUnXSA9IHBhcnNlSW50KFEoJ3N1YnNiJykudmFsdWUpOw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdJUFNfU2NyZWVuQ29uZmlndXJhdGlvblNlcnZpY2UnLCB5LCBzaG93RGVza3RvcFNldHRpbmdzRGxnT2szKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dEZXNrdG9wU2V0dGluZ3NEbGdPazIoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgUHVsbFN5c3RlbVN0YXR1cygpOyBlbHNlIG1lc3NhZ2Vib3goIlJlbW90ZSBEZXNrdG9wIFNldHRpbmdzIiwgIkVycm9yICIgKyBzdGF0dXMgKyAiLCB1bmFibGUgdG8gc2V0IHZhbHVlcy4iKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dEZXNrdG9wU2V0dGluZ3NEbGdPazMoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goIkVycm9yIiwgIlNjcmVlbiBCbGFua2luZyBjb3VsZCBub3QgYmUgc2V0LCBibGFua2luZyBtYXkgbm90IGJlIHN1cHBvcnRlZCBvbiB0aGlzIHN5c3RlbSAoIiArIHN0YXR1cyArICIpLiIpOyByZXR1cm47IH0NCiAgICAgICAgICAgIGFtdHN0YWNrLkdldCgiSVBTX1NjcmVlbkNvbmZpZ3VyYXRpb25TZXJ2aWNlIiwgZnVuY3Rpb24gKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgYW10c3lzc3RhdGVbJ0lQU19TY3JlZW5Db25maWd1cmF0aW9uU2VydmljZSddLnJlc3BvbnNlID0gcmVzcG9uc2UuQm9keTsgdXBkYXRlU3lzdGVtU3RhdHVzKCk7IH0NCiAgICAgICAgICAgIH0sIDAsIDEpOw0KICAgICAgICB9DQoNCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gRVZFTlQgTE9HIFBBTkVMDQogICAgICAgIC8vDQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbEV2ZW50TG9nKGJ1dHRvbikgew0KICAgICAgICAgICAgaWYgKGJ1dHRvbiA9PSAxICYmIHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgYW10Rmlyc3RQdWxsIHw9IDE2Ow0KICAgICAgICAgICAgYW10c3RhY2suRW51bSgiQU1UX01lc3NhZ2VMb2ciLCBwcm9jZXNzTWVzc2FnZUxvZzApOw0KICAgICAgICAgICAgYW10c3RhY2suR2V0TWVzc2FnZUxvZyhwcm9jZXNzTWVzc2FnZUxvZzEpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIHByb2Nlc3NNZXNzYWdlTG9nMHJlc3BvbnNlcyA9IG51bGw7DQogICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NNZXNzYWdlTG9nMChzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSByZXR1cm47DQogICAgICAgICAgICBpZiAoc3RhdHVzKSBRVignZ282JywgdHJ1ZSk7IC8vIFNob3cgZXZlbnQgbG9nIGxlZnQgcGFuZWwgb3B0aW9uDQogICAgICAgICAgICBpZiAocmVzcG9uc2VzKSBwcm9jZXNzTWVzc2FnZUxvZzByZXNwb25zZXMgPSByZXNwb25zZXM7DQogICAgICAgICAgICB2YXIgZnIgPSAnJywgeCA9ICI8dGFibGUgY2xhc3M9bG9nMSBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjhweD4iOw0KICAgICAgICAgICAgaWYgKHByb2Nlc3NNZXNzYWdlTG9nMHJlc3BvbnNlcyAhPSBudWxsKSB7IGZyID0gKChwcm9jZXNzTWVzc2FnZUxvZzByZXNwb25zZXNbMF1bIklzRnJvemVuIl0gPT0gdHJ1ZSkgPyBBZGRCdXR0b24oIlVuLWZyZWV6ZSBMb2ciLCAiRnJlZXplTG9nKDApIikgOiBBZGRCdXR0b24oIkZyZWV6ZSBMb2ciLCAiRnJlZXplTG9nKDEpIikpOyB9DQoNCg0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgiPGRpdiBzdHlsZT1mbG9hdDpyaWdodD48aW5wdXQgaWQ9ZXZlbnRGaWx0ZXIgcGxhY2Vob2xkZXI9RmlsdGVyIHN0eWxlPW1hcmdpbjo0cHggb25rZXl1cD1ldmVudEZpbHRlcigpPiZuYnNwOzwvZGl2PjxkaXY+Jm5ic3A7IiArIEFkZFJlZnJlc2hCdXR0b24oIlB1bGxFdmVudExvZygxKSIpICsgQWRkQnV0dG9uKCJDbGVhciBMb2ciLCAiQ2xlYXJMb2coKSIpICsgQWRkQnV0dG9uKCJTYXZlLi4uIiwgIlNhdmVFdmVudExvZygpIikgKyBmcik7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVFdmVudExvZycsIHggKyAnPGJyPicpOw0KICAgICAgICB9DQoNCg0KICAgICAgICBmdW5jdGlvbiBTYXZlRXZlbnRMb2coKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8IGV2ZW50bWVzc2FnZXMgPT0gbnVsbCkgcmV0dXJuOw0KICAgICAgICAgICAgU2F2ZUpzb25GaWxlKCdJbnRlbEFtdEV2ZW50bG9nJywgJ2V2ZW50cycsICdJbnRlbCBBTVQgRXZlbnQgTG9nJywgZXZlbnRtZXNzYWdlcyk7DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgZXZlbnRtZXNzYWdlcyA9IG51bGw7DQogICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NNZXNzYWdlTG9nMShzdGFjaywgbWVzc2FnZXMpIHsNCiAgICAgICAgICAgIGV2ZW50bWVzc2FnZXMgPSBtZXNzYWdlczsNCiAgICAgICAgICAgIHZhciBpLCB5ID0gMCwgeCA9ICI8dGFibGUgY2xhc3M9bG9nMSBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjhweD48dHI+PHRkIHdpZHRoPTgwcHg+PHA+PHRkPjx0ZD48dGQ+IjsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6OTBweD48Yj4mbmJzcDsmbmJzcDtFdmVudDwvYj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6MTEwcHg+PGI+VGltZTwvYj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6MTYwcHg+PGI+U291cmNlPC9iPjx0ZCBjbGFzcz1yMT48Yj5EZXNjcmlwdGlvbjwvYj4iOw0KICAgICAgICAgICAgZm9yIChpIGluIG1lc3NhZ2VzKSB7DQogICAgICAgICAgICAgICAgeSsrOw0KICAgICAgICAgICAgICAgIHZhciBpY29uID0gMSwgbSA9IG1lc3NhZ2VzW2ldOw0KICAgICAgICAgICAgICAgIGlmIChtWydFdmVudFNldmVyaXR5J10gPj0gOCkgeyBpY29uID0gMjsgfSBpZiAobVsnRXZlbnRTZXZlcml0eSddID49IDE2KSB7IGljb24gPSAzOyB9DQogICAgICAgICAgICAgICAgeCArPSAiPHRyIGlkPXhhbXRldmVudCIgKyBpICsgIiBjbGFzcz1yMyBvbmNsaWNrPXNob3dFdmVudERldGFpbHMoIiArIGkgKyAiKT48dGQgY2xhc3M9cjE+PHA+PGRpdiBjbGFzcz1pY29uIiArIGljb24gKyAiIHN0eWxlPWRpc3BsYXk6YmxvY2s7ZmxvYXQ6bGVmdDttYXJnaW4tbGVmdDo1cHg7bWFyZ2luLXJpZ2h0OjVweD48L2Rpdj4iICsgKHBhcnNlSW50KGkpICsgMSkgKyAiPHRkIGNsYXNzPXIxIHRpdGxlPSciICsgbVsnVGltZSddLnRvTG9jYWxlU3RyaW5nKCkgKyAiJz4iICsgbVsnVGltZSddLnRvTG9jYWxlRGF0ZVN0cmluZygnZW4nLCB7IHllYXI6ICJudW1lcmljIiwgbW9udGg6ICIyLWRpZ2l0IiwgZGF5OiAibnVtZXJpYyIgfSkgKyAiPGJyPiIgKyBtWydUaW1lJ10udG9Mb2NhbGVUaW1lU3RyaW5nKCdlbicsIHsgaG91cjoiMi1kaWdpdCIsIG1pbnV0ZToiMi1kaWdpdCIsIHNlY29uZDoiMi1kaWdpdCIgfSkgKyAiPHRkIGNsYXNzPXIxPiIgKyBtWydFbnRpdHlTdHInXS5yZXBsYWNlKCIocikiLCAiJnJlZzsiKSArICI8dGQgY2xhc3M9cjE+IiArIG1bJ0Rlc2MnXTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoeSA9PSAwID8gIiZuYnNwOyIgOiAiIik7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVFdmVudExvZzInLCB4ICsgJzxicj4nKTsNCiAgICAgICAgICAgIHByb2Nlc3NNZXNzYWdlTG9nMCgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gRnJlZXplTG9nKHgpIHsgaWYgKCF4eGRpYWxvZ01vZGUpIHsgYW10c3RhY2suQU1UX01lc3NhZ2VMb2dfRnJlZXplTG9nKHgsIGZ1bmN0aW9uICgpIHsgYW10c3RhY2suRW51bSgiQU1UX01lc3NhZ2VMb2ciLCBwcm9jZXNzTWVzc2FnZUxvZzApOyB9KSB9IH0NCiAgICAgICAgZnVuY3Rpb24gQ2xlYXJMb2coeCkgeyBpZiAoIXh4ZGlhbG9nTW9kZSkgeyBRSCgnaWRfZGlhbG9nTWVzc2FnZScsICdDbGVhciBldmVudCBsb2c/Jyk7IHNldERpYWxvZ01vZGUoMSwgIkV2ZW50IExvZyIsIDMsIENsZWFyTG9nRXgpOyB9IH0NCiAgICAgICAgZnVuY3Rpb24gQ2xlYXJMb2dFeCgpIHsgYW10c3RhY2suQU1UX01lc3NhZ2VMb2dfQ2xlYXJMb2coZnVuY3Rpb24gKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgeyBpZiAoc3RhdHVzICE9IDIwMCkgbWVzc2FnZWJveCgiRXZlbnQgTG9nIiwgIlVuYWJsZSB0byBjbGVhciwgRXJyb3I6ICIgKyBzdGF0dXMpOyBlbHNlIFB1bGxFdmVudExvZygpOyB9KSB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0V2ZW50RGV0YWlscyhoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgbSA9IGV2ZW50bWVzc2FnZXNbaF07DQogICAgICAgICAgICB2YXIgeCA9ICc8ZGl2IHN0eWxlPXRleHQtYWxpZ246bGVmdD4nOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlRpbWUiLCBtWydUaW1lJ10udG9Mb2NhbGVTdHJpbmcoKSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU291cmNlIiwgbVsnRW50aXR5U3RyJ10ucmVwbGFjZSgiKHIpIiwgIiZyZWc7IikpOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkRlc2NyaXB0aW9uIiwgbVsnRGVzYyddKTsNCiAgICAgICAgICAgIHggKz0gTW9yZVN0YXJ0KCk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiRGV2aWNlIEFkZHJlc3MiLCBtWydEZXZpY2VBZGRyZXNzJ10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkVudGl0eSIsIG1bJ0VudGl0eSddKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJFbnRpdHkgSW5zdGFuY2UiLCBtWydFbnRpdHlJbnN0YW5jZSddKTsNCiAgICAgICAgICAgIHZhciBlID0gJyc7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIG1bJ0V2ZW50RGF0YSddKSB7IGlmIChlLmxlbmd0aCA+IDApIGUgKz0nLCc7IGUgKz0gbVsnRXZlbnREYXRhJ11baV07IH0NCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJEYXRhIiwgZSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiT2Zmc2V0IiwgbVsnRXZlbnRPZmZzZXQnXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU2Vuc29yIFR5cGUiLCBtWydFdmVudFNlbnNvclR5cGUnXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU2V2ZXJpdHkiLCBtWydFdmVudFNldmVyaXR5J10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlNvdXJjZSBUeXBlIiwgbVsnRXZlbnRTb3VyY2VUeXBlJ10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlR5cGUiLCBtWydFdmVudFR5cGUnXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU2Vuc29yIE51bWJlciIsIG1bJ1NlbnNvck51bWJlciddKTsNCiAgICAgICAgICAgIHggKz0gTW9yZUVuZCgpOw0KICAgICAgICAgICAgeCArPSAiPC9kaXY+IjsNCiAgICAgICAgICAgIG1lc3NhZ2Vib3goIkV2ZW50ICMiICsgKGggKyAxKSArICIgRGV0YWlscyIsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZXZlbnRGaWx0ZXIoKSB7DQogICAgICAgICAgICB2YXIgZmlsdGVyID0gUSgnZXZlbnRGaWx0ZXInKS52YWx1ZS50b0xvd2VyQ2FzZSgpOw0KICAgICAgICAgICAgZm9yICh2YXIgdyBpbiBldmVudG1lc3NhZ2VzKSB7IFFWKCd4YW10ZXZlbnQnICsgdywgZmlsdGVyID09ICcnIHx8IGV2ZW50bWVzc2FnZXNbd11bJ0Rlc2MnXS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoZmlsdGVyKSA+PSAwIHx8IGV2ZW50bWVzc2FnZXNbd11bJ0VudGl0eVN0ciddLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihmaWx0ZXIpID49IDApOyB9DQogICAgICAgIH0NCg0KDQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEFVRElUIExPRyBQQU5FTA0KICAgICAgICAvLw0KDQogICAgICAgIGZ1bmN0aW9uIFB1bGxBdWRpdExvZyhidXR0b24pIHsNCiAgICAgICAgICAgIGlmIChidXR0b24gPT0gMSAmJiB4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIGFtdEZpcnN0UHVsbCB8PSAzMjsNCiAgICAgICAgICAgIGFtdHN0YWNrLkVudW0oIkFNVF9BdWRpdExvZyIsIHByb2Nlc3NBdWRpdExvZzApOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGF1ZGl0TG9nID0gbnVsbDsNCiAgICAgICAgdmFyIGF1ZGl0TG9nRW5hYmxlZFN0YXRlcyA9IFsiVW5rbm93biIsICJPdGhlciIsICJFbmFibGVkIiwgIkRpc2FibGVkIiwgIlNodXR0aW5nIERvd24iLCAiTm90IEFwcGxpY2FibGUiLCAiRW5hYmxlZCBidXQgT2ZmbGluZSIsICJJbiBUZXN0IiwgIkRlZmVycmVkIiwgIlF1aWVzY2UiLCAiU3RhcnRpbmciXTsNCg0KICAgICAgICBmdW5jdGlvbiBwcm9jZXNzQXVkaXRMb2cwKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsNCiAgICAgICAgICAgICAgICBRVignZ28xNScsIHRydWUpOyAvLyBTaG93IGF1ZGl0IGxvZyBsZWZ0IHBhbmVsIG9wdGlvbg0KDQogICAgICAgICAgICAgICAgdmFyIHIgPSByZXNwb25zZXNbMF1bIkF1ZGl0U3RhdGUiXTsNCiAgICAgICAgICAgICAgICB2YXIgYXVkaXRzdGF0ZSA9IChyICYgMHgwMSkgPyAnRGlzYWJsZWQnIDogJ0VuYWJsZWQnOw0KICAgICAgICAgICAgICAgIGlmIChyICYgMHgwMikgYXVkaXRzdGF0ZSArPSAiLCBMb2NrZWQiOw0KICAgICAgICAgICAgICAgIGlmIChyICYgMHgwNCkgYXVkaXRzdGF0ZSArPSAiLCBBbG1vc3QgRnVsbCI7DQogICAgICAgICAgICAgICAgaWYgKHIgJiAweDA4KSBhdWRpdHN0YXRlICs9ICIsIEZ1bGwiOw0KICAgICAgICAgICAgICAgIGlmIChyICYgMHgxMCkgYXVkaXRzdGF0ZSArPSAiLCBOb0tleSI7DQoNCiAgICAgICAgICAgICAgICB2YXIgeCA9ICI8aDE+QXVkaXQgTG9nIFNldHRpbmdzPC9oMT4iICsgVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiU3RhdGUiLCBhdWRpdHN0YXRlKTsNCiAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIlN0b3JhZ2UiLCByZXNwb25zZXNbMF1bIkN1cnJlbnROdW1iZXJPZlJlY29yZHMiXSArICIgcmVjb3JkKHMpLCAiICsgcmVzcG9uc2VzWzBdWyJQZXJjZW50YWdlRnJlZSJdICsgIiUgZnJlZSIpOw0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiT3ZlcndyaXRlIHBvbGljeSIsICgocmVzcG9uc2VzWzBdWyJPdmVyd3JpdGVQb2xpY3kiXSA9PSAyKSA/ICJXcmFwcyB3aGVuIGZ1bGwiIDogIk5ldmVyIG92ZXJ3cml0ZXMiKSk7DQogICAgICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgICAgIFFIKCdpZF9UYWJsZUF1ZGl0TG9nMScsIHgpOw0KDQogICAgICAgICAgICAgICAgYW10c3RhY2suR2V0QXVkaXRMb2cocHJvY2Vzc0F1ZGl0TG9nMSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBwcm9jZXNzQXVkaXRMb2cxKHN0YWNrLCBtZXNzYWdlcykgew0KICAgICAgICAgICAgYXVkaXRMb2cgPSBtZXNzYWdlczsNCiAgICAgICAgICAgIHZhciBpLCB4ID0gIjx0YWJsZSBjbGFzcz1sb2cxIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6OHB4PiI7DQoNCiAgICAgICAgICAgIHggKz0gVGFibGVFbmQoIjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ+PGlucHV0IGlkPWF1ZGl0RmlsdGVyIHBsYWNlaG9sZGVyPUZpbHRlciBzdHlsZT1tYXJnaW46NHB4IG9ua2V5dXA9YXVkaXRGaWx0ZXIoKT4mbmJzcDs8L2Rpdj48ZGl2PiAiICsgQWRkUmVmcmVzaEJ1dHRvbigiUHVsbEF1ZGl0TG9nKDEpIikgKyBBZGRCdXR0b24oIlNhdmUuLi4iLCAiU2F2ZUF1ZGl0TG9nKCkiKSArIEFkZEJ1dHRvbigiQ2xlYXIgTG9nIiwgIkNsZWFyQXVkaXRMb2coKSIpIC8qICsgQWRkQnV0dG9uKCJTZXR0aW5ncy4uLiIsICJTaG93QXVkaXRMb2dTZXR0aW5ncygpIikqLykgKyAiPGJyPiI7DQogICAgICAgICAgICBpZiAobWVzc2FnZXMubGVuZ3RoID09IDApIHsNCiAgICAgICAgICAgICAgICB4ID0gIk5vIGF1ZGl0IGxvZyBldmVudHMgZm91bmQuIjsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgdmFyIHkgPSAwOw0KICAgICAgICAgICAgICAgIHggKz0gIjx0YWJsZSBjbGFzcz1sb2cxIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6OHB4Pjx0cj48dGQgd2lkdGg9ODBweD48cD48dGQ+PHRkPjx0ZD4iOw0KICAgICAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6MTEwcHg+Jm5ic3A7Jm5ic3A7PGI+VGltZTwvYj48dGQgY2xhc3M9cjEgc3R5bGU9d2lkdGg6MjYwcHg+PGI+SW5pdGlhdG9yPC9iPjx0ZCBjbGFzcz1yMT48Yj5BY3Rpb248L2I+IjsNCiAgICAgICAgICAgICAgICBmb3IgKGkgaW4gbWVzc2FnZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIG0gPSBtZXNzYWdlc1tpXSwgZGVzY3JpcHRpb24gPSBtWydBdWRpdEFwcCddLCBpbml0aWF0b3IgPSBtWydJbml0aWF0b3InXTsNCiAgICAgICAgICAgICAgICAgICAgeSsrOw0KICAgICAgICAgICAgICAgICAgICB2YXIgYWRkciA9ICcnOw0KICAgICAgICAgICAgICAgICAgICBpZiAobVsnTmV0QWRkcmVzcyddLmxlbmd0aCA+IDApIGFkZHIgPSBtWydOZXRBZGRyZXNzJ10ucmVwbGFjZSgnMDAwMDowMDAwOjAwMDA6MDAwMDowMDAwOjAwMDA6MDAwMDowMDAxJywnOjoxJyk7DQogICAgICAgICAgICAgICAgICAgIGlmIChtWydFdmVudCddKSBkZXNjcmlwdGlvbiArPSAiLCAiICsgbVsnRXZlbnQnXTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKG1bJ0V4U3RyJ10gIT0gbnVsbCkgZGVzY3JpcHRpb24gKz0gIiwgIiArIG1bJ0V4U3RyJ107DQogICAgICAgICAgICAgICAgICAgIGlmIChpbml0aWF0b3IgIT0gJycgJiYgYWRkciAhPSAnJykgaW5pdGlhdG9yICs9ICIsICI7DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjx0ciBpZD14YW10YXVkaXQiICsgaSArICIgY2xhc3M9cjMgb25jbGljaz1zaG93QXVkaXREZXRhaWxzKCIgKyBpICsgIik+PHRkIGNsYXNzPXIxIHRpdGxlPSciICsgbVsnVGltZSddLnRvTG9jYWxlU3RyaW5nKCkgKyAiJz4mbmJzcDsmbmJzcDsiICsgbVsnVGltZSddLnRvTG9jYWxlRGF0ZVN0cmluZygnZW4nLCB7IHllYXI6ICJudW1lcmljIiwgbW9udGg6ICIyLWRpZ2l0IiwgZGF5OiAibnVtZXJpYyIgfSkgKyAiPGJyPiZuYnNwOyZuYnNwOyIgKyBtWydUaW1lJ10udG9Mb2NhbGVUaW1lU3RyaW5nKCdlbicsIHsgaG91cjoiMi1kaWdpdCIsIG1pbnV0ZToiMi1kaWdpdCIsIHNlY29uZDoiMi1kaWdpdCIgfSkgKyAiPHRkIGNsYXNzPXIxPiIgKyBpbml0aWF0b3IgKyBhZGRyICsgIjx0ZCBjbGFzcz1yMT4iICsgZGVzY3JpcHRpb247DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbmQoeSA9PSAwID8gIiZuYnNwOyIgOiAiIikgKyAiPGJyPiI7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBRSCgnaWRfVGFibGVBdWRpdExvZzInLCB4KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGF1ZGl0RmlsdGVyKCkgew0KICAgICAgICAgICAgdmFyIGZpbHRlciA9IFEoJ2F1ZGl0RmlsdGVyJykudmFsdWUudG9Mb3dlckNhc2UoKTsNCiAgICAgICAgICAgIGZvciAodmFyIHcgaW4gYXVkaXRMb2cpIHsgUVYoJ3hhbXRhdWRpdCcgKyB3LCBmaWx0ZXIgPT0gJycgfHwgSlNPTi5zdHJpbmdpZnkoYXVkaXRMb2dbd10pLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihmaWx0ZXIpID49IDApOyB9DQogICAgICAgIH0NCg0KDQogICAgICAgIGZ1bmN0aW9uIFNhdmVBdWRpdExvZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgYXVkaXRMb2cgPT0gbnVsbCkgcmV0dXJuOw0KICAgICAgICAgICAgU2F2ZUpzb25GaWxlKCdJbnRlbEFtdEF1ZGl0bG9nJywgJ2F1ZGl0ZXZlbnRzJywgJ0ludGVsIEFNVCBBdWRpdCBMb2cnLCBhdWRpdExvZyk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBDbGVhckF1ZGl0TG9nKHgpIHsgUUgoJ2lkX2RpYWxvZ01lc3NhZ2UnLCAnQ2xlYXIgYXVkaXQgbG9nPycpOyBzZXREaWFsb2dNb2RlKDEsICJBdWRpdCBMb2ciLCAzLCBDbGVhckF1ZGl0TG9nRXgpOyB9DQogICAgICAgIGZ1bmN0aW9uIENsZWFyQXVkaXRMb2dFeCgpIHsNCiAgICAgICAgICAgIC8vYW10c3RhY2suQU1UX0F1ZGl0TG9nX0NsZWFyTG9nKGZ1bmN0aW9uICgpIHsgUHVsbEF1ZGl0TG9nKCk7IH0pDQogICAgICAgICAgICB2YXIgaGFuZGxlID0gYW10c3RhY2suQU1UX0F1ZGl0TG9nX1NldEF1ZGl0TG9jaygxLDAsIGhhbmRsZSwgZnVuY3Rpb24oKSB7IGFtdHN0YWNrLkFNVF9BdWRpdExvZ19DbGVhckxvZyhmdW5jdGlvbiAoKSB7IGFtdHN0YWNrLkFNVF9BdWRpdExvZ19TZXRBdWRpdExvY2soMCwgMiwgaGFuZGxlLCBmdW5jdGlvbiAoKSB7IHNldFRpbWVvdXQoUHVsbEF1ZGl0TG9nLDEwMDApO30pOyB9KTsgfSk7ICAgICAgICAgDQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBTaG93QXVkaXRMb2dTZXR0aW5ncygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9BdWRpdExvZ19SZXF1ZXN0U3RhdGVDaGFuZ2UoMiwgMCwgQXVkaXRMb2dTZXR0aW5nc0NvbXBsZXRlZCk7IC8vIEVuYWJsZQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQXVkaXRMb2dTZXR0aW5nc0NvbXBsZXRlZChzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSBQdWxsQXVkaXRMb2coKTsgZWxzZSBtZXNzYWdlYm94KCJBdWRpdCBMb2ciLCAiRXJyb3I6ICIgKyBzdGF0dXMpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0F1ZGl0RGV0YWlscyhoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgaSwgbSA9IGF1ZGl0TG9nW2hdLCB4ID0gJzxkaXYgc3R5bGU9dGV4dC1hbGlnbjpsZWZ0Pic7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiVGltZSIsIG1bJ1RpbWUnXS50b0xvY2FsZVN0cmluZygpKTsNCiAgICAgICAgICAgIGlmIChtWydJbml0aWF0b3InXSAhPSAnJykgeCArPSBhZGRIdG1sVmFsdWUoIkluaXRpYXRvciIsIG1bJ0luaXRpYXRvciddKTsNCiAgICAgICAgICAgIGlmIChtWydOZXRBZGRyZXNzJ10gIT0gJycpIHggKz0gYWRkSHRtbFZhbHVlKCJBZGRyZXNzIiwgbVsnTmV0QWRkcmVzcyddKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJBcHBsaWNhdGlvbiIsIG1bJ0F1ZGl0QXBwJ10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkV2ZW50IiwgbVsnRXZlbnQnXSk7DQogICAgICAgICAgICBpZiAobVsnRXhTdHInXSAhPSBudWxsKSB7DQogICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkV4dGVuZGVkIERhdGEiLCBtWydFeFN0ciddKTsNCiAgICAgICAgICAgIH0gZWxzZSBpZiAobVsnRXgnXS5sZW5ndGggPiAwKSB7DQogICAgICAgICAgICAgICAgdmFyIGUgPSAnJzsNCiAgICAgICAgICAgICAgICBmb3IgKGkgaW4gbVsnRXgnXSkgeyBpZiAoZS5sZW5ndGggPiAwKSBlICs9ICcsJzsgZSArPSBtWydFeCddLmNoYXJDb2RlQXQoaSk7IH0NCiAgICAgICAgICAgICAgICBpZiAoZSAhPSAnJykgeCArPSBhZGRIdG1sVmFsdWUoIkRhdGEgVmFsdWVzIiwgZSk7DQogICAgICAgICAgICAgICAgaWYgKG1bJ0V4J10ubGVuZ3RoID4gMiAmJiBSZWFkU2hvcnQobVsnRXgnXSwgMCkgPT0gKG1bJ0V4J10ubGVuZ3RoIC0gMikpIHggKz0gYWRkSHRtbFZhbHVlKCJEYXRhIFN0cmluZyIsIG1bJ0V4J10uc3Vic3RyaW5nKDIpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gIjwvZGl2PiI7DQogICAgICAgICAgICBtZXNzYWdlYm94KCJBdWRpdCBFdmVudCAjIiArIChoICsgMSkgKyAiIERldGFpbHMiLCB4KTsNCiAgICAgICAgfQ0KDQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIENlcnRpZmljYXRlcw0KICAgICAgICAvLw0KDQogICAgICAgIHZhciB4eENlcnRpZmljYXRlcyA9IG51bGw7DQogICAgICAgIHZhciB4eENlcnRQcml2YXRlS2V5cyA9IG51bGw7DQogICAgICAgIHZhciB4eFRsc1NldHRpbmdzID0gbnVsbDsNCiAgICAgICAgdmFyIHh4VGxzQ3VycmVudENlcnQgPSBudWxsOw0KICAgICAgICB2YXIgeHhUTFNDcmVkZW50aWFsQ29udGV4dCA9IG51bGw7DQogICAgICAgIHZhciB4eENhUHJpdmF0ZUtleSA9IG51bGw7DQogICAgICAgIHZhciB4eENhU3ViamVjdEF0dHJpYnV0ZXMgPSBudWxsOw0KDQogICAgICAgIGZ1bmN0aW9uIFB1bGxDZXJ0aWZpY2F0ZXMoKSB7DQogICAgICAgICAgICAvLyBXZSBvbmx5IGRlYWwgd2l0aCBjZXJ0aWZpY2F0ZXMgc3RhcnRpbmcgd2l0aCBJbnRlbCBBTVQgNiBhbmQgYmV5b25kDQogICAgICAgICAgICBhbXRzdGFjay5CYXRjaEVudW0obnVsbCwgWyJBTVRfUHVibGljS2V5Q2VydGlmaWNhdGUiLCAiQU1UX1B1YmxpY1ByaXZhdGVLZXlQYWlyIiwgIkFNVF9UTFNTZXR0aW5nRGF0YSIsICJBTVRfVExTQ3JlZGVudGlhbENvbnRleHQiXSwgcHJvY2Vzc0NlcnRzMSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBwcm9jZXNzQ2VydHMxKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKChzdGF0dXMgPT0gNDAwKSB8fCBlcnJjaGVjayhzdGF0dXMsIHN0YWNrKSkgcmV0dXJuOw0KICAgICAgICAgICAgUVYoJ2dvMTYnLCB0cnVlKTsgLy8gU2VjdXJpdHkgU2V0dGluZ3MNCiAgICAgICAgICAgIHh4Q2VydGlmaWNhdGVzID0gcmVzcG9uc2VzWyJBTVRfUHVibGljS2V5Q2VydGlmaWNhdGUiXS5yZXNwb25zZXM7DQogICAgICAgICAgICB4eENlcnRQcml2YXRlS2V5cyA9IHJlc3BvbnNlc1siQU1UX1B1YmxpY1ByaXZhdGVLZXlQYWlyIl0ucmVzcG9uc2VzOw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5ncyA9IHJlc3BvbnNlc1siQU1UX1RMU1NldHRpbmdEYXRhIl0ucmVzcG9uc2VzOw0KICAgICAgICAgICAgeHhUTFNDcmVkZW50aWFsQ29udGV4dCA9IHJlc3BvbnNlc1siQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0Il0ucmVzcG9uc2VzOw0KDQogICAgICAgICAgICAvLyBTZWxlY3QgdGhlIGN1cnJlbnQgVExTIGNlcnRpZmljYXRlIGluIHRoZSBkcm9wIGRvd24gYm94DQogICAgICAgICAgICB4eFRsc0N1cnJlbnRDZXJ0ID0gbnVsbDsNCiAgICAgICAgICAgIGlmICh4eFRMU0NyZWRlbnRpYWxDb250ZXh0Lmxlbmd0aCA+IDApIHsNCiAgICAgICAgICAgICAgICB2YXIgY2VydEluc3RhbmNlSWQgPSB4eFRMU0NyZWRlbnRpYWxDb250ZXh0WzBdWydFbGVtZW50SW5Db250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVsnVmFsdWUnXTsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4Q2VydGlmaWNhdGVzKSB7IGlmICh4eENlcnRpZmljYXRlc1tpXVsnSW5zdGFuY2VJRCddID09IGNlcnRJbnN0YW5jZUlkKSB7IHh4VGxzQ3VycmVudENlcnQgPSBpOyB9IH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gU2V0dXAgdGhlIGNlcnRpZmljYXRlcw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eENlcnRpZmljYXRlcykgew0KICAgICAgICAgICAgICAgIHh4Q2VydGlmaWNhdGVzW2ldLlRydXN0ZWRSb290Q2VydGZpY2F0ZSA9ICh4eENlcnRpZmljYXRlc1tpXVsiVHJ1c3RlZFJvb3RDZXJ0ZmljYXRlIl0gPT0gdHJ1ZSk7DQogICAgICAgICAgICAgICAgeHhDZXJ0aWZpY2F0ZXNbaV0uWDUwOUNlcnRpZmljYXRlID0gd2luZG93LmF0b2IoeHhDZXJ0aWZpY2F0ZXNbaV1bIlg1MDlDZXJ0aWZpY2F0ZSJdKTsNCiAgICAgICAgICAgICAgICB4eENlcnRpZmljYXRlc1tpXS5YSXNzdWVyID0gcGFyc2VDZXJ0TmFtZSh4eENlcnRpZmljYXRlc1tpXVsiSXNzdWVyIl0pOw0KICAgICAgICAgICAgICAgIHh4Q2VydGlmaWNhdGVzW2ldLlhTdWJqZWN0ID0gcGFyc2VDZXJ0TmFtZSh4eENlcnRpZmljYXRlc1tpXVsiU3ViamVjdCJdKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGFtdGNlcnRfbGlua0NlcnRQcml2YXRlS2V5KHh4Q2VydGlmaWNhdGVzLCB4eENlcnRQcml2YXRlS2V5cyk7IC8vIFRoaXMgbGlua3MgYWxsIGNlcnRpZmljYXRlcyBhbmQgcHJpdmF0ZSBrZXlzDQoNCiAgICAgICAgICAgIHVwZGF0ZUNlcnRpZmljYXRlcygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcGFyc2VDZXJ0TmFtZSh4KSB7DQogICAgICAgICAgICB2YXIgaiwgciA9IHt9LCB4eCA9IHguc3BsaXQoJywnKTsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHgpIHsgaiA9IHh4W2ldLmluZGV4T2YoJz0nKTsgclt4eFtpXS5zdWJzdHJpbmcoMCwgaildID0geHhbaV0uc3Vic3RyaW5nKGogKyAxKTsgfQ0KICAgICAgICAgICAgcmV0dXJuIHI7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBnZXRUbHNTZWN1cml0eVN0YXRlKHgpIHsNCiAgICAgICAgICAgIGlmICh4eFRsc1NldHRpbmdzW3hdWydFbmFibGVkJ10gPT0gZmFsc2UpIHJldHVybiAiRGlzYWJsZWQiOw0KICAgICAgICAgICAgdmFyIHIgPSAoKHh4VGxzU2V0dGluZ3NbeF1bJ011dHVhbEF1dGhlbnRpY2F0aW9uJ10gPT0gdHJ1ZSkgPyAnTXV0dWFsLWF1dGggVExTJyA6ICdTZXJ2ZXItYXV0aCBUTFMnKSArICgoeHhUbHNTZXR0aW5nc1t4XVsnQWNjZXB0Tm9uU2VjdXJlQ29ubmVjdGlvbnMnXSA9PSB0cnVlKSA/ICIgYW5kIG5vbi1UTFMiIDogIiIpOw0KICAgICAgICAgICAgaWYgKCh4eFRsc1NldHRpbmdzW3hdWydNdXR1YWxBdXRoZW50aWNhdGlvbiddID09IHRydWUpICYmICh4eFRsc1NldHRpbmdzW3hdWydUcnVzdGVkQ04nXSkpIHsNCiAgICAgICAgICAgICAgICB2YXIgdHJ1c3RlZENuID0gTWFrZVRvQXJyYXkoeHhUbHNTZXR0aW5nc1t4XVsnVHJ1c3RlZENOJ10pOw0KICAgICAgICAgICAgICAgIGlmICh0cnVzdGVkQ24ubGVuZ3RoID4gMCkgeyByICs9ICIsIFRydXN0ZWQgbmFtZSIgKyAoKHRydXN0ZWRDbi5sZW5ndGggPiAxKT8ncyc6JycpICsgIjogIiArIHRydXN0ZWRDbi5qb2luKCcsICcpICsgIi4iOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gcjsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVwZGF0ZUNlcnRpZmljYXRlcygpIHsNCiAgICAgICAgICAgIGlmICh4eENlcnRpZmljYXRlcyA9PSBudWxsKSByZXR1cm47DQoNCiAgICAgICAgICAgIC8vIEZpZ3VyZSBvdXQgd2hhdCBpbmRleCBpcyBsb2NhbCAmIHJlbW90ZQ0KICAgICAgICAgICAgdmFyIGxvY2FsTmR4ID0gKCh4eFRsc1NldHRpbmdzWzBdWydJbnN0YW5jZUlEJ10gPT0gJ0ludGVsKHIpIEFNVCBMTVMgVExTIFNldHRpbmdzJykpID8gMCA6IDEsIHJlbW90ZU5keCA9ICgxIC0gbG9jYWxOZHgpOw0KDQogICAgICAgICAgICAvLyBHZW5lcmFsIHNldHRpbmdzDQogICAgICAgICAgICB2YXIgeCA9IFRhYmxlU3RhcnQoKTsNCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiUmVtb3RlIFRMUyBzZWN1cml0eSIsIGFkZExpbmtDb25kaXRpb25hbChnZXRUbHNTZWN1cml0eVN0YXRlKHJlbW90ZU5keCksICdzaG93U2V0VGxzU2VjdXJpdHlEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJMb2NhbCBUTFMgc2VjdXJpdHkiLCBhZGRMaW5rQ29uZGl0aW9uYWwoZ2V0VGxzU2VjdXJpdHlTdGF0ZShsb2NhbE5keCksICdzaG93U2V0VGxzU2VjdXJpdHlEbGcoKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgeCArPSAiPGJyPiIgKyBUYWJsZVN0YXJ0MigpICsgIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCBjZXJ0aWZpY2F0ZXMgZm9yIHRoaXMgY29tcHV0ZXIuPGJyPjxicj4iOw0KICAgICAgICAgICAgaWYgKHh4Q2VydGlmaWNhdGVzLmxlbmd0aCA9PSAwICYmIHh4Q2VydFByaXZhdGVLZXlzLmxlbmd0aCA9PSAwKSB7DQogICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD48YnI+PGk+Tm8gY2VydGlmaWNhdGVzIGZvdW5kLjwvaT48L2Rpdj48YnI+IjsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eENlcnRpZmljYXRlcykgew0KICAgICAgICAgICAgICAgICAgICB2YXIgZGVzYyA9ICcnOw0KICAgICAgICAgICAgICAgICAgICBpZiAoeHhDZXJ0aWZpY2F0ZXNbaV0uVHJ1c3RlZFJvb3RDZXJ0ZmljYXRlKSBkZXNjID0gJywgVHJ1c3RlZCBSb290JzsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHh4Q2VydGlmaWNhdGVzW2ldLlhQcml2YXRlS2V5KSBkZXNjID0gJywgUHJpdmF0ZSBLZXknOw0KICAgICAgICAgICAgICAgICAgICBpZiAoaSA9PSB4eFRsc0N1cnJlbnRDZXJ0KSBkZXNjICs9ICcsIFRMUyBjZXJ0JzsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIG9uY2xpY2s9c2hvd0NlcnREZXRhaWxzKCIgKyBpICsgIik+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDozcHg+PGI+IiArIEVzY2FwZUh0bWwoeHhDZXJ0aWZpY2F0ZXNbaV0uWFN1YmplY3RbIkNOIl0pICsgIjwvYj48aT4iICsgZGVzYyArICI8L2k+PC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eENlcnRQcml2YXRlS2V5cykgew0KICAgICAgICAgICAgICAgICAgICBpZiAoIXh4Q2VydFByaXZhdGVLZXlzW2ldLlhDZXJ0KSB7DQogICAgICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93S2V5UGFpckRldGFpbHMoIiArIGkgKyAiKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48aT5VbmFzc2lnbmVkIFByaXZhdGUgS2V5IFBhaXIgIyIgKyBpICsgIjwvaT48L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgdmFyIGJ1dHRvbnMgPSBBZGRSZWZyZXNoQnV0dG9uKCJQdWxsQ2VydGlmaWNhdGVzKCkiKTsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHsgYnV0dG9ucyArPSAoQWRkQnV0dG9uKCJBZGQgQ2VydGlmaWNhdGUuLi4iLCAiYWRkQ2VydEJ1dHRvbigpIikgKyBBZGRCdXR0b24oIklzc3VlIENlcnRpZmljYXRlLi4uIiwgImlzc3VlQ2VydEJ1dHRvbigpIikpOyB9DQogICAgICAgICAgICB4ICs9ICI8YnI+PHRkIGNsYXNzPXIxPiIgKyBUYWJsZUVuZChidXR0b25zKTsNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZUNlcnRzJywgeCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93S2V5UGFpckRldGFpbHMoaCkgew0KICAgICAgICAgICAgdmFyIHggPSAiVGhpcyBpcyBhIHB1YmxpYy9wcml2YXRlIGNlcnRpZmljYXRlIGtleSBwYWlyIHRoYXQgZG9lcyBub3QgYmVsb25nIHRvIGFueSBjZXJ0aWZpY2F0ZXMuIFRoaXMgZW50cnkgc2hvdWxkIGJlIHRlbXBvcmFyeS4iOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIktleSBQYWlyICMiICsgaCwgNSwgZnVuY3Rpb24gKGIpIHsgaWYgKGIgPT0gMikgeyBhbXRzdGFjay5EZWxldGUoJ0FNVF9QdWJsaWNQcml2YXRlS2V5UGFpcicsIHsgJ0luc3RhbmNlSUQnOiB4eENlcnRQcml2YXRlS2V5c1toXVsnSW5zdGFuY2VJRCddIH0sIFB1bGxDZXJ0aWZpY2F0ZXMsIDAsIDEpOyB9IH0sIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIHh4Q2VydFN1YmplY3ROYW1lcyA9IHsgJ0NOJzogJ0NvbW1vbiBOYW1lJywgJ08nOiAnT3JnYW5pemF0aW9uJywgJ09VJzogJ09yZyBVbml0JywgJ1MnOiAnU3RhdGUvUHJvdmluY2UnLCAnU1QnOiAnU3RhdGUvUHJvdmluY2UnLCAnTCc6ICdMb2NhbGl0eScsICdDJzogJ0NvdW50cnknLCAnU04nOiAnU3VybmFtZScsICdHTic6ICdHaXZlbiBuYW1lJyB9Ow0KICAgICAgICBmdW5jdGlvbiBzaG93Q2VydERldGFpbHMoaCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIGMgPSB4eENlcnRpZmljYXRlc1toXSwgeCA9ICc8YnI+JzsNCg0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkNlcnRpZmljYXRlIiwgYy5YNTA5Q2VydGlmaWNhdGUubGVuZ3RoICsgIiBieXRlcywgPGEgc3R5bGU9Y3Vyc29yOnBvaW50ZXI7Y29sb3I6Ymx1ZSBvbmNsaWNrPWRvd25sb2FkQ2VydCgiICsgaCArICIpPkRvd25sb2FkPC9hPiIpOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlRydXN0ZWQgcm9vdCIsIGMuVHJ1c3RlZFJvb3RDZXJ0ZmljYXRlID8gIlllcyIgOiAiTm8iKTsNCiAgICAgICAgICAgIGlmIChjLlRydXN0ZWRSb290Q2VydGZpY2F0ZSA9PSBmYWxzZSAmJiBjLlhQcml2YXRlS2V5KSB7IHggKz0gYWRkSHRtbFZhbHVlKCdQcml2YXRlIGtleScsICdQcmVzZW50Jyk7IH0NCg0KICAgICAgICAgICAgLy8gU2hvdyBjZXJ0aWZpY2F0ZSB1c2FnZXMNCiAgICAgICAgICAgIC8qDQogICAgICAgICAgICB5ID0gW107DQogICAgICAgICAgICBpZiAoZXh0S2V5VXNhZ2UgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgIGlmIChleHRLZXlVc2FnZS5jbGllbnRBdXRoID09IHRydWUpIHsgeS5wdXNoKCJUTFMmbmJzcDtDbGllbnQiKTsgfQ0KICAgICAgICAgICAgICAgIGlmIChleHRLZXlVc2FnZS5jb2RlU2lnbmluZyA9PSB0cnVlKSB7IHkucHVzaCgiQ29kZSZuYnNwO1NpZ25pbmciKTsgfQ0KICAgICAgICAgICAgICAgIGlmIChleHRLZXlVc2FnZS5lbWFpbFByb3RlY3Rpb24gPT0gdHJ1ZSkgeyB5LnB1c2goIkVNYWlsIik7IH0NCiAgICAgICAgICAgICAgICBpZiAoZXh0S2V5VXNhZ2Uuc2VydmVyQXV0aCA9PSB0cnVlKSB7IHkucHVzaCgiVExTJm5ic3A7U2VydmVyIik7IH0NCiAgICAgICAgICAgICAgICBpZiAoZXh0S2V5VXNhZ2VbIjIuMTYuODQwLjEuMTEzNzQxLjEuMi4xIl0gPT0gdHJ1ZSkgeyB5LnB1c2goIkludGVsJnJlZzsmbmJzcDtBTVQgQ29uc29sZSIpOyB9DQogICAgICAgICAgICAgICAgaWYgKGV4dEtleVVzYWdlWyIyLjE2Ljg0MC4xLjExMzc0MS4xLjIuMiJdID09IHRydWUpIHsgeS5wdXNoKCJJbnRlbCZyZWc7Jm5ic3A7QU1UIEFnZW50Iik7IH0NCiAgICAgICAgICAgICAgICBpZiAoZXh0S2V5VXNhZ2VbIjIuMTYuODQwLjEuMTEzNzQxLjEuMi4zIl0gPT0gdHJ1ZSkgeyB5LnB1c2goIkludGVsJnJlZzsmbmJzcDtBTVQgQWN0aXZhdGlvbiIpOyB9DQogICAgICAgICAgICAgICAgaWYgKGV4dEtleVVzYWdlLnRpbWVTdGFtcGluZyA9PSB0cnVlKSB7IHkucHVzaCgiVGltZSZuYnNwO1N0YW1waW5nIik7IH0NCiAgICAgICAgICAgICAgICBpZiAoeS5sZW5ndGggPiAwKSB7IHggKz0gYWRkSHRtbFZhbHVlTm9UaXRsZSgiQ2VydGlmaWNhdGUgVXNhZ2UiLCB5LmpvaW4oJywgJykgKyAnLicpICsgJzxiciBjbGVhcj1hbGwgLz4nOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICAqLw0KDQogICAgICAgICAgICB4ICs9ICc8YnI+PGRpdiBzdHlsZT0iYm9yZGVyLWJvdHRvbToxcHggc29saWQgZ3JheSI+PGk+Q2VydGlmaWNhdGUgU3ViamVjdDwvaT48L2Rpdj48YnI+JzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYy5YU3ViamVjdCkgeyBpZiAoYy5YU3ViamVjdFtpXSkgeyB4ICs9IGFkZEh0bWxWYWx1ZSh4eENlcnRTdWJqZWN0TmFtZXNbaV0gPyB4eENlcnRTdWJqZWN0TmFtZXNbaV0gOiBpLCBFc2NhcGVIdG1sKGMuWFN1YmplY3RbaV0pKTsgfSB9DQogICAgICAgICAgICAvLyB4ICs9IGFkZEh0bWxWYWx1ZU5vVGl0bGUoJ0ZpbmdlcnByaW50JywgYy5maW5nZXJwcmludC5zdWJzdHJpbmcoMCwyOSkgKyAnPGJyIC8+JyArIGMuZmluZ2VycHJpbnQuc3Vic3RyaW5nKDMwKSk7IC8vIFRPRE86IFBhcnNlIHRoZSBjZXJ0aWZpY2F0ZSB1c2luZyBGb3JnZSBhbmQgZ2V0IHRoZSBmaW5nZXJwcmludA0KICAgICAgICAgICAgeCArPSAnPGJyPjxkaXYgc3R5bGU9ImJvcmRlci1ib3R0b206MXB4IHNvbGlkIGdyYXkiPjxpPklzc3VlciBDZXJ0aWZpY2F0ZTwvaT48L2Rpdj48YnI+JzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYy5YSXNzdWVyKSB7IGlmIChjLlhJc3N1ZXJbaV0pIHsgeCArPSBhZGRIdG1sVmFsdWUoeHhDZXJ0U3ViamVjdE5hbWVzW2ldID8geHhDZXJ0U3ViamVjdE5hbWVzW2ldIDogaSwgRXNjYXBlSHRtbChjLlhJc3N1ZXJbaV0pKTsgfSB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiQ2VydGlmaWNhdGUgLSAiICsgRXNjYXBlSHRtbChjLlhTdWJqZWN0WyJDTiJdKSwgNSwgZnVuY3Rpb24gKGIpIHsNCiAgICAgICAgICAgICAgICBpZiAoYiA9PSAyKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIGEgcHJpdmF0ZSBrZXksIGRlbGV0ZSBpdC4NCiAgICAgICAgICAgICAgICAgICAgaWYgKHh4Q2VydGlmaWNhdGVzW2hdLlhQcml2YXRlS2V5KSBhbXRzdGFjay5EZWxldGUoJ0FNVF9QdWJsaWNQcml2YXRlS2V5UGFpcicsIHsgJ0luc3RhbmNlSUQnOiB4eENlcnRpZmljYXRlc1toXS5YUHJpdmF0ZUtleVsnSW5zdGFuY2VJRCddIH0sIGZ1bmN0aW9uICgpIHsgfSwgMCwgMSk7DQogICAgICAgICAgICAgICAgICAgIC8vIERlbGV0ZSB0aGUgY2VydGlmaWNhdGUNCiAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suRGVsZXRlKCdBTVRfUHVibGljS2V5Q2VydGlmaWNhdGUnLCB4eENlcnRpZmljYXRlc1toXSwgY2VydGlmaWNhdGVSZW1vdmVkLCAwLCAxKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9LCB4KTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgZnVuY3Rpb24gZG93bmxvYWRDZXJ0KGgpIHsgDQoNCiAgICAgICAgICAgIHNhdmVBcyhkYXRhMmJsb2IoeHhDZXJ0aWZpY2F0ZXNbaF0uWDUwOUNlcnRpZmljYXRlKSwgeHhDZXJ0aWZpY2F0ZXNbaF0uWFN1YmplY3RbJ0NOJ10gKyAiLmNlciIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2VydF9GaWxlU2VsZWN0SGFuZGxlcihlKSB7DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQogICAgICAgICAgICBpZiAoZS5kYXRhVHJhbnNmZXIuZmlsZXMubGVuZ3RoID09IDEpIHsNCiAgICAgICAgICAgICAgICBpZiAoZS5kYXRhVHJhbnNmZXIuZmlsZXNbMF0ubmFtZS50b0xvd2VyQ2FzZSgpLmVuZHNXaXRoKCcucDEyJykpIHsNCiAgICAgICAgICAgICAgICAgICAgaXNzdWVDZXJ0QnV0dG9uKGUuZGF0YVRyYW5zZmVyLmZpbGVzKTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBhZGRDZXJ0QnV0dG9uKGUuZGF0YVRyYW5zZmVyLmZpbGVzKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgeHhEcmFnRHJvcENlcnRGaWxlcyA9IG51bGw7DQogICAgICAgIGZ1bmN0aW9uIGFkZENlcnRCdXR0b24oZmlsZXMpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgIXh4QWNjb3VudEFkbWluTmFtZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MTBweD48L2Rpdj4nOw0KICAgICAgICAgICAgeHhEcmFnRHJvcENlcnRGaWxlcyA9IGZpbGVzOw0KDQogICAgICAgICAgICB2YXIgaW5wdXQgPSAiPGlucHV0IGlkPWNlcnRvcGVuIG9uY2hhbmdlPWFkZENlcnRCdXR0b25VcGRhdGUoKSB0eXBlPWZpbGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHggYWNjZXB0PScuY2VyLC5wZW0nPiI7DQogICAgICAgICAgICBpZiAoeHhEcmFnRHJvcENlcnRGaWxlcykgeyBpbnB1dCA9ICc8aW5wdXQgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHggcmVhZG9ubHkgZGlzYWJsZWQgdmFsdWU9IicgKyB4eERyYWdEcm9wQ2VydEZpbGVzWzBdLm5hbWUgKyAnIj4nOyB9DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PiIgKyBpbnB1dCArICI8ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5DZXJ0aWZpY2F0ZSBmaWxlPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PHNlbGVjdCBpZD1jZXJ0dHlwZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjBweD48b3B0aW9uIHZhbHVlPTA+Q2hhaW4gQ2VydGlmaWNhdGU8L29wdGlvbj48b3B0aW9uIHZhbHVlPTE+VHJ1c3RlZCBSb290IENlcnRpZmljYXRlPC9vcHRpb24+PC9zZWxlY3Q+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q2VydGlmaWNhdGUgdHlwZTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiQWRkIENlcnRpZmljYXRlIiwgMywgYWRkQ2VydEJ1dHRvbk9rLCB4KTsNCiAgICAgICAgICAgIGFkZENlcnRCdXR0b25VcGRhdGUoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZENlcnRCdXR0b25VcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgY2VydG9wZW4gPSBnZXRJbnB1dEVsZW1lbnQoJ2NlcnRvcGVuJyk7DQogICAgICAgICAgICBRRSgnaWR4X2RsZ09rQnV0dG9uJywgIWNlcnRvcGVuIHx8IGNlcnRvcGVuLmZpbGVzLmxlbmd0aCA9PSAxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZENlcnRCdXR0b25PaygpIHsNCg0KICAgICAgICAgICAgdmFyIGNlcnRvcGVuID0gZ2V0SW5wdXRFbGVtZW50KCdjZXJ0b3BlbicpOw0KICAgICAgICAgICAgdmFyIGZpbGVzID0geHhEcmFnRHJvcENlcnRGaWxlczsNCiAgICAgICAgICAgIGlmIChjZXJ0b3BlbikgZmlsZXMgPSBjZXJ0b3Blbi5maWxlczsNCiAgICAgICAgICAgIGlmIChmaWxlcyAmJiBmaWxlcy5sZW5ndGggPT0gMSkgew0KICAgICAgICAgICAgICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpOw0KICAgICAgICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSBhZGRDZXJ0QnV0dG9uT2syOw0KICAgICAgICAgICAgICAgIHJlYWRlci5yZWFkQXNCaW5hcnlTdHJpbmcoZmlsZXNbMF0pOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgIA0KICAgICAgICBmdW5jdGlvbiBhZGRDZXJ0QnV0dG9uT2syKGZpbGUpIHsNCiAgICAgICAgICAgIHZhciBkYXRhID0gZmlsZS50YXJnZXQucmVzdWx0Ow0KICAgICAgICAgICAgdmFyIGkgPSBkYXRhLmluZGV4T2YoJy0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLScpOw0KICAgICAgICAgICAgaWYgKGkgPiAwKSB7DQogICAgICAgICAgICAgICAgLy8gVGhpcyBpcyBhIC5QRU0gZmlsZSwga2VlcCBldmVyeXRoaW5nIGJldHdlZW4gQkVHSU4vRU5ELCBjbGVhbiBpdCB1cCBhbmQgdXNlIGFzLWlzLiBJdCdzIGFscmVhZHkgQmFzZTY0Lg0KICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLnN1YnN0cmluZyhpICsgMjcpOw0KICAgICAgICAgICAgICAgIGkgPSBkYXRhLmluZGV4T2YoJy0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0nKTsNCiAgICAgICAgICAgICAgICBpZiAoaSA+IDApIGRhdGEgPSBkYXRhLnN1YnN0cmluZygwLCBpKQ0KICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLnJlcGxhY2UoL1xyXG4vZywgJycpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGEgLkNFUiBmaWxlLCBqdXN0IGJhc2U2NCBlbmNvZGUgaXQgYW5kIHdlIHNob3VsZCBiZSBvay4NCiAgICAgICAgICAgICAgICBkYXRhID0gYnRvYShkYXRhKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChnZXRTZWxlY3RFbGVtZW50KCdjZXJ0dHlwZScpLnZhbHVlID09IDEpIHsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfQWRkVHJ1c3RlZFJvb3RDZXJ0aWZpY2F0ZShkYXRhLCBjZXJ0aWZpY2F0ZUFkZGVkKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgYW10c3RhY2suQU1UX1B1YmxpY0tleU1hbmFnZW1lbnRTZXJ2aWNlX0FkZENlcnRpZmljYXRlKGRhdGEsIGNlcnRpZmljYXRlQWRkZWQpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gaXNzdWVDZXJ0QnV0dG9uKGZpbGVzKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8ICF4eEFjY291bnRBZG1pbk5hbWUpIHJldHVybjsNCiAgICAgICAgICAgIHh4RHJhZ0Ryb3BDZXJ0RmlsZXMgPSBmaWxlczsNCg0KDQoNCiAgICAgICAgICAgIHZhciB4ID0gJycsIGlucHV0ID0gIjxpbnB1dCBpZD1jZXJ0b3BlbiB0eXBlPWZpbGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjMwcHggb25jaGFuZ2U9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgYWNjZXB0PScucDEyJz4iOw0KICAgICAgICAgICAgaWYgKHh4RHJhZ0Ryb3BDZXJ0RmlsZXMpIHsgaW5wdXQgPSAnPGlucHV0IHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4IHJlYWRvbmx5IGRpc2FibGVkIHZhbHVlPSInICsgeHhEcmFnRHJvcENlcnRGaWxlc1swXS5uYW1lICsgJyI+JzsgfQ0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZWhlaWdodDoyNnB4O21hcmdpbi10b3A6MTRweD4iICsgaW5wdXQgKyAiPGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q2VydGlmaWNhdGUgZmlsZTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxpbnB1dCBvbmtleXVwPWlzc3VlQ2VydEJ1dHRvblVwZGF0ZSgpIGlkPWNlcnRvcGVucGFzcyB0eXBlPXBhc3N3b3JkIGF1dG9jb21wbGV0ZT1vZmYgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjMwcHg+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q2VydGlmaWNhdGUgcGFzc3dvcmQ8L2Rpdj48L2Rpdj4iOw0KDQogICAgICAgICAgICB4ICs9ICc8YnI+PGRpdiBzdHlsZT0iYm9yZGVyLWJvdHRvbToxcHggc29saWQgZ3JheSI+PGk+SW50ZWwmcmVnOyBBTVQgQ2VydGlmaWNhdGU8L2k+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IG9ua2V5dXA9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgaWQ9Y2VydGNuIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PkNvbW1vbiBOYW1lPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IG9ua2V5dXA9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgaWQ9Y2VydG8gc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjMwcHg+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+T3JnYW5pemF0aW9uPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IG9ua2V5dXA9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgaWQ9Y2VydHN0IHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIzMHB4PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PlN0YXRlL1Byb3ZpbmNlPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IG9ua2V5dXA9aXNzdWVDZXJ0QnV0dG9uVXBkYXRlKCkgaWQ9Y2VydGMgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjMwcHg+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q291bnRyeTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICc8ZGl2PkNlcnRpZmljYXRlIFVzYWdlczwvZGl2Pjx1bCBzdHlsZT0ibGlzdC1zdHlsZS10eXBlOm5vbmU7aGVpZ2h0OjEwMHB4O292ZXJmbG93OmF1dG87d2lkdGg6MTAwJTtib3JkZXI6IDFweCBzb2xpZCAjMDAwO2JhY2tncm91bmQtY29sb3I6d2hpdGU7b3ZlcmZsb3cteDpoaWRkZW47bWFyZ2luOjA7cGFkZGluZzowIj4nOw0KICAgICAgICAgICAgLy94ICs9ICc8bGk+PGxhYmVsPjxpbnB1dCB0eXBlPWNoZWNrYm94IGlkPWQxMV9jdTE+SW50ZWwmcmVnOyBBTVQgQ29uc29sZTwvbGFiZWw+PC9saT4nOw0KICAgICAgICAgICAgLy94ICs9ICc8bGk+PGxhYmVsPjxpbnB1dCB0eXBlPWNoZWNrYm94IGlkPWQxMV9jdTI+SW50ZWwmcmVnOyBBTVQgQWdlbnQ8L2xhYmVsPjwvbGk+JzsNCiAgICAgICAgICAgIC8veCArPSAnPGxpPjxsYWJlbD48aW5wdXQgdHlwZT1jaGVja2JveCBpZD1kMTFfY3UzPkludGVsJnJlZzsgQU1UIEFjdGl2YXRpb248L2xhYmVsPjwvbGk+JzsNCiAgICAgICAgICAgIHggKz0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggaWQ9ZDExX2N1NCBjaGVja2VkPlRMUyBTZXJ2ZXIgKEhUVFBTKTwvbGFiZWw+PC9saT4nOw0KICAgICAgICAgICAgeCArPSAnPGxpPjxsYWJlbD48aW5wdXQgdHlwZT1jaGVja2JveCBpZD1kMTFfY3U1PlRMUyBDbGllbnQgKEhUVFBTKTwvbGFiZWw+PC9saT4nOw0KICAgICAgICAgICAgeCArPSAnPGxpPjxsYWJlbD48aW5wdXQgdHlwZT1jaGVja2JveCBpZD1kMTFfY3U2PkVtYWlsIFByb3RlY3Rpb248L2xhYmVsPjwvbGk+JzsNCiAgICAgICAgICAgIHggKz0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggaWQ9ZDExX2N1Nz5Db2RlIFNpZ25pbmc8L2xhYmVsPjwvbGk+JzsNCiAgICAgICAgICAgIHggKz0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggaWQ9ZDExX2N1OD5UaW1lIFN0YW1wPC9sYWJlbD48L2xpPic7DQogICAgICAgICAgICB4ICs9ICc8L3VsPic7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiSXNzdWUgQ2VydGlmaWNhdGUiLCAzLCBpc3N1ZUNlcnRCdXR0b25PaywgeCk7DQogICAgICAgICAgICBpc3N1ZUNlcnRCdXR0b25VcGRhdGUoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGlzc3VlQ2VydEJ1dHRvblVwZGF0ZSgpIHsNCiAgICAgICAgICAgIHZhciBjZXJ0b3BlbiA9IGdldElucHV0RWxlbWVudCgnY2VydG9wZW4nKTsNCiAgICAgICAgICAgIFFFKCdjZXJ0b3BlbnBhc3MnLCAhY2VydG9wZW4gfHwgKGNlcnRvcGVuICYmIGNlcnRvcGVuLmZpbGVzLmxlbmd0aCA9PSAxKSk7DQogICAgICAgICAgICB2YXIgeCA9ICghY2VydG9wZW4gfHwgY2VydG9wZW4uZmlsZXMubGVuZ3RoIDwgMik7DQogICAgICAgICAgICBpZiAoKCFjZXJ0b3BlbiB8fCAoY2VydG9wZW4gJiYgY2VydG9wZW4uZmlsZXMubGVuZ3RoKSkgPT0gMSAmJiBRKCdjZXJ0b3BlbnBhc3MnKS52YWx1ZSA9PSAnJykgeCA9IGZhbHNlOw0KICAgICAgICAgICAgaWYgKGdldElucHV0RWxlbWVudCgnY2VydGNuJykudmFsdWUgPT0gJycgfHwgZ2V0SW5wdXRFbGVtZW50KCdjZXJ0bycpLnZhbHVlID09ICcnIHx8IGdldElucHV0RWxlbWVudCgnY2VydHN0JykudmFsdWUgPT0gJycgfHwgZ2V0SW5wdXRFbGVtZW50KCdjZXJ0YycpLnZhbHVlID09ICcnKSB7IHggPSBmYWxzZTsgfQ0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gaXNzdWVDZXJ0QnV0dG9uT2soKSB7DQoNCiAgICAgICAgICAgIHZhciBjZXJ0b3BlbiA9IGdldElucHV0RWxlbWVudCgnY2VydG9wZW4nKTsNCiAgICAgICAgICAgIHZhciBmaWxlcyA9IHh4RHJhZ0Ryb3BDZXJ0RmlsZXM7DQogICAgICAgICAgICBpZiAoY2VydG9wZW4pIGZpbGVzID0gY2VydG9wZW4uZmlsZXM7DQogICAgICAgICAgICBpZiAoZmlsZXMgJiYgZmlsZXMubGVuZ3RoID09IDEpIHsNCiAgICAgICAgICAgICAgICAvLyBJc3N1ZSBhIGNlcnRpZmljYXRlIHVzaW5nIHRoaXMgZmlsZQ0KICAgICAgICAgICAgICAgIHZhciByZWFkZXIgPSBuZXcgRmlsZVJlYWRlcigpOw0KICAgICAgICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSBpc3N1ZUNlcnRCdXR0b25PazI7DQogICAgICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyhmaWxlc1swXSk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIC8vIElzc3VlIGEgY2VydGlmaWNhdGUgdXNpbmcgYSBkdW1teSBDQQ0KICAgICAgICAgICAgICAgIGlzc3VlQ2VydEJ1dHRvbk9rMyhudWxsKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGlzc3VlQ2VydEJ1dHRvbk9rMihmaWxlKSB7DQogICAgICAgICAgICAvLyBMb2FkIHRoZSBDQSBjZXJ0aWZpY2F0ZSBhbmQgcHJpdmF0ZSBrZXkNCiAgICAgICAgICAgIHZhciByID0gYW10Y2VydF9sb2FkUDEyRmlsZShmaWxlLnRhcmdldC5yZXN1bHQsIFEoJ2NlcnRvcGVucGFzcycpLnZhbHVlLCBpc3N1ZUNlcnRCdXR0b25PazMpOw0KICAgICAgICAgICAgaWYgKHIgPT0gZmFsc2UpIHsgbWVzc2FnZWJveCgiSXNzdWUgQ2VydGlmaWNhdGUiLCAiVW5hYmxlIHRvIGRlY3J5cHQvZGVjb2RlIGNlcnRpZmljYXRlLiIpOyByZXR1cm47IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGlzc3VlQ2VydEJ1dHRvbk9rMyhwcml2YXRlS2V5LCBzdWJqZWN0QXR0cmlidXRlcywgY2VydCkgew0KICAgICAgICAgICAgLy8gQXNrIEludGVsIEFNVCB0byBnZW5lcmF0ZSBhIGtleSBwYWlyDQogICAgICAgICAgICB4eENhUHJpdmF0ZUtleSA9IHByaXZhdGVLZXk7DQogICAgICAgICAgICB4eENhU3ViamVjdEF0dHJpYnV0ZXMgPSBzdWJqZWN0QXR0cmlidXRlczsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9QdWJsaWNLZXlNYW5hZ2VtZW50U2VydmljZV9HZW5lcmF0ZUtleVBhaXIoMCwgMjA0OCwgR2VuZXJhdGVLZXlQYWlyUmVzcG9uc2UpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gR2VuZXJhdGVLZXlQYWlyUmVzcG9uc2Uoc3RhY2ssIHNlcnZpY2VOYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCdJc3N1ZSBDZXJ0aWZpY2F0ZScsICdGYWlsZWQgdG8gZ2VuZXJhdGUga2V5IHBhaXIuIFN0YXR1czogJyArIHN0YXR1cyk7IHJldHVybjsgfQ0KICAgICAgICAgICAgaWYgKHJlc3BvbnNlLkJvZHlbJ1JldHVyblZhbHVlJ10gIT0gMCkgeyBtZXNzYWdlYm94KCdJc3N1ZSBDZXJ0aWZpY2F0ZScsICdGYWlsZWQgdG8gZ2VuZXJhdGUga2V5IHBhaXIsICcgKyByZXNwb25zZS5Cb2R5WydSZXR1cm5WYWx1ZVN0ciddKTsgcmV0dXJuOyB9DQoNCiAgICAgICAgICAgIC8vIEdldCB0aGUgbmV3IGtleSBwYWlyDQogICAgICAgICAgICBhbXRzdGFjay5FbnVtKCJBTVRfUHVibGljUHJpdmF0ZUtleVBhaXIiLCBHZW5lcmF0ZUtleVBhaXJSZXNwb25zZTIsIHJlc3BvbnNlLkJvZHlbJ0tleVBhaXInXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWydWYWx1ZSddKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEdlbmVyYXRlS2V5UGFpclJlc3BvbnNlMihzdGFjaywgc2VydmljZU5hbWUsIHJlc3BvbnNlLCBzdGF0dXMsIHRhZykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsgbWVzc2FnZWJveCgnSXNzdWUgQ2VydGlmaWNhdGUnLCAnRmFpbGVkIHRvIGdlbmVyYXRlIGtleSBwYWlyLiBTdGF0dXM6ICcgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgIHZhciBERVJLZXkgPSBudWxsOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiByZXNwb25zZSkgeyBpZiAocmVzcG9uc2VbaV1bJ0luc3RhbmNlSUQnXSA9PSB0YWcpIERFUktleSA9IHJlc3BvbnNlW2ldWydERVJLZXknXTsgfQ0KDQogICAgICAgICAgICAvLyBHZXQgY2VydGlmaWNhdGUgdmFsdWVzDQogICAgICAgICAgICB2YXIgY2VydGF0dHJpYnV0ZXMgPSB7ICdDTic6IGdldElucHV0RWxlbWVudCgnY2VydGNuJykudmFsdWUsICdPJzogZ2V0SW5wdXRFbGVtZW50KCdjZXJ0bycpLnZhbHVlLCAnU1QnOiBnZXRJbnB1dEVsZW1lbnQoJ2NlcnRzdCcpLnZhbHVlLCAnQyc6IGdldElucHV0RWxlbWVudCgnY2VydGMnKS52YWx1ZSB9Ow0KICAgICAgICAgICAgdmFyIGlzc3VlcmF0dHJpYnV0ZXMgPSB7ICdDTic6ICdVbnRydXN0ZWQgUm9vdCBDZXJ0aWZpY2F0ZScgfTsNCiAgICAgICAgICAgIGlmICh4eENhUHJpdmF0ZUtleSAhPSBudWxsICYmIHh4Q2FTdWJqZWN0QXR0cmlidXRlcykgew0KICAgICAgICAgICAgICAgIGlzc3VlcmF0dHJpYnV0ZXMgPSB7fTsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4Q2FTdWJqZWN0QXR0cmlidXRlcykgew0KICAgICAgICAgICAgICAgICAgICBpc3N1ZXJhdHRyaWJ1dGVzW3h4Q2FTdWJqZWN0QXR0cmlidXRlc1tpXS5zaG9ydE5hbWVdID0geHhDYVN1YmplY3RBdHRyaWJ1dGVzW2ldLnZhbHVlOyAvLyBUaGUgaXNzdWluZyBDQSdzIHN1YmplY3QgYXR0cmlidXRlcyANCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9IA0KDQogICAgICAgICAgICAvLyBGaWd1cmUgb3V0IHRoZSBleHRlbmRlZCBrZXkgdXNhZ2VzDQogICAgICAgICAgICB2YXIgZXh0S2V5VXNhZ2UgPSB7IG5hbWU6ICdleHRLZXlVc2FnZScgfQ0KICAgICAgICAgICAgLy9pZiAoUSgnZDExX2N1MScpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2VbJzIuMTYuODQwLjEuMTEzNzQxLjEuMi4xJ10gPSB0cnVlOyBleHRLZXlVc2FnZS5jbGllbnRBdXRoID0gdHJ1ZTsgfQ0KICAgICAgICAgICAgLy9pZiAoUSgnZDExX2N1MicpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2VbJzIuMTYuODQwLjEuMTEzNzQxLjEuMi4yJ10gPSB0cnVlOyBleHRLZXlVc2FnZS5jbGllbnRBdXRoID0gdHJ1ZTsgfQ0KICAgICAgICAgICAgLy9pZiAoUSgnZDExX2N1MycpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2VbJzIuMTYuODQwLjEuMTEzNzQxLjEuMi4zJ10gPSB0cnVlOyBleHRLZXlVc2FnZS5jbGllbnRBdXRoID0gdHJ1ZTsgfQ0KICAgICAgICAgICAgaWYgKFEoJ2QxMV9jdTQnKS5jaGVja2VkKSB7IGV4dEtleVVzYWdlLnNlcnZlckF1dGggPSB0cnVlOyB9DQogICAgICAgICAgICBpZiAoUSgnZDExX2N1NScpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2UuY2xpZW50QXV0aCA9IHRydWU7IH0NCiAgICAgICAgICAgIGlmIChRKCdkMTFfY3U2JykuY2hlY2tlZCkgeyBleHRLZXlVc2FnZS5lbWFpbFByb3RlY3Rpb24gPSB0cnVlOyB9DQogICAgICAgICAgICBpZiAoUSgnZDExX2N1NycpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2UuY29kZVNpZ25pbmcgPSB0cnVlOyB9DQogICAgICAgICAgICBpZiAoUSgnZDExX2N1OCcpLmNoZWNrZWQpIHsgZXh0S2V5VXNhZ2UudGltZVN0YW1waW5nID0gdHJ1ZTsgfQ0KDQogICAgICAgICAgICAvLyBTaWduIHRoZSBrZXkgcGFpciB1c2luZyB0aGUgQ0EgY2VydGlmaWF0ZQ0KICAgICAgICAgICAgdmFyIGNlcnQgPSBhbXRjZXJ0X3NpZ25XaXRoQ2FLZXkoREVSS2V5LCB4eENhUHJpdmF0ZUtleSwgY2VydGF0dHJpYnV0ZXMsIGlzc3VlcmF0dHJpYnV0ZXMsIGV4dEtleVVzYWdlKTsNCiAgICAgICAgICAgIGlmIChjZXJ0ID09IG51bGwpIHsgbWVzc2FnZWJveCgnSXNzdWUgQ2VydGlmaWNhdGUnLCAnVW5hYmxlIHRvIHNpZ24gY2VydGlmaWNhdGUuJyk7IHJldHVybjsgfQ0KDQogICAgICAgICAgICAvLyBQbGFjZSB0aGUgcmVzdWx0aW5nIHNpZ25lZCBjZXJ0aWZpY2F0ZSBiYWNrIGludG8gQU1UDQogICAgICAgICAgICB2YXIgcGVtID0gZm9yZ2UucGtpLmNlcnRpZmljYXRlVG9QZW0oY2VydCkucmVwbGFjZSgvKFxyXG58XG58XHIpL2dtLCAiIik7DQogICAgICAgICAgICBhbXRzdGFjay5BTVRfUHVibGljS2V5TWFuYWdlbWVudFNlcnZpY2VfQWRkQ2VydGlmaWNhdGUocGVtLnN1YnN0cmluZygyNywgcGVtLmxlbmd0aCAtIDI1KSwgR2VuZXJhdGVLZXlQYWlyUmVzcG9uc2U0KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEdlbmVyYXRlS2V5UGFpclJlc3BvbnNlNChzdGFjaywgc2VydmljZU5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goJ0lzc3VlIENlcnRpZmljYXRlJywgJ0ZhaWxlZCB0byBnZW5lcmF0ZSBrZXkgcGFpci4gU3RhdHVzOiAnICsgc3RhdHVzKTsgcmV0dXJuOyB9DQogICAgICAgICAgICBQdWxsQ2VydGlmaWNhdGVzKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBjZXJ0aWZpY2F0ZUFkZGVkKHN0YWNrLCBzZXJ2aWNlTmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgeyBpZiAoc3RhdHVzICE9IDIwMCB8fCByZXNwb25zZS5Cb2R5WydSZXR1cm5WYWx1ZSddICE9IDApIHsgbWVzc2FnZWJveCgnQWRkIENlcnRpZmljYXRlJywgJ1VuYWJsZSB0byBhZGQgY2VydGlmaWNhdGUsIGVycm9yICcgKyAoc3RhdHVzICE9IDIwMCA/IHN0YXR1cyA6IHJlc3BvbnNlLkJvZHlbJ1JldHVyblZhbHVlU3RyJ10pKTsgfSBlbHNlIFB1bGxDZXJ0aWZpY2F0ZXMoKTsgfQ0KICAgICAgICBmdW5jdGlvbiBjZXJ0aWZpY2F0ZVJlbW92ZWQoc3RhY2ssIHNlcnZpY2VOYW1lLCBoZWFkZXIsIHN0YXR1cykgeyBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCdSZW1vdmUgQ2VydGlmaWNhdGUnLCAnVW5hYmxlIHRvIHJlbW92ZSBjZXJ0aWZpY2F0ZSwgZXJyb3IgJyArIHN0YXR1cyk7IH0gZWxzZSBQdWxsQ2VydGlmaWNhdGVzKCk7IH0NCg0KICAgICAgICBmdW5jdGlvbiBnZXRJbnB1dEVsZW1lbnQoaWQpIHsgdmFyIGFsbGVsZW1lbnRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0Jyk7IGZvciAodCA9IDA7IHQgPCBhbGxlbGVtZW50cy5sZW5ndGg7IHQrKykgeyBpZiAoYWxsZWxlbWVudHNbdF0uaWQgPT0gaWQpIHJldHVybiBhbGxlbGVtZW50c1t0XTsgfSB9DQogICAgICAgIGZ1bmN0aW9uIGdldFNlbGVjdEVsZW1lbnQoaWQpIHsgdmFyIGFsbGVsZW1lbnRzID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ3NlbGVjdCcpOyBmb3IgKHQgPSAwOyB0IDwgYWxsZWxlbWVudHMubGVuZ3RoOyB0KyspIHsgaWYgKGFsbGVsZW1lbnRzW3RdLmlkID09IGlkKSByZXR1cm4gYWxsZWxlbWVudHNbdF07IH0gfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dTZXRUbHNTZWN1cml0eURsZyh4KSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9ICcnOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48c2VsZWN0IG9uY2hhbmdlPXNob3dTZXRUbHNTZWN1cml0eURsZ1VwZGF0ZSgpIGlkPXRsc2NlcnQgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHg+PG9wdGlvbiB2YWx1ZT0tMT5ObyBDZXJ0aWZpY2F0ZSwgVExTIERpc2FibGVkPC9vcHRpb24+IjsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhDZXJ0aWZpY2F0ZXMpIHsgaWYgKHh4Q2VydGlmaWNhdGVzW2ldLlRydXN0ZWRSb290Q2VydGZpY2F0ZSA9PSBmYWxzZSAmJiB4eENlcnRpZmljYXRlc1tpXS5YUHJpdmF0ZUtleSAmJiAoeHhUbHNDdXJyZW50Q2VydCA9PSBudWxsIHx8IHh4VGxzQ3VycmVudENlcnQgPT0gaSkpIHsgeCArPSAiPG9wdGlvbiB2YWx1ZT0iICsgaSArICI+IiArIHh4Q2VydGlmaWNhdGVzW2ldLlhTdWJqZWN0WyJDTiJdICsgIjwvb3B0aW9uPiI7IH0gfQ0KICAgICAgICAgICAgeCArPSAiPC9zZWxlY3Q+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+Q2VydGlmaWNhdGU8L2Rpdj48L2Rpdj4iOw0KDQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9dGxzcmVtb3RlIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG9uY2hhbmdlPXNob3dTZXRUbHNTZWN1cml0eURsZ1VwZGF0ZSgpPjxvcHRpb24gdmFsdWU9MD5TZXJ2ZXItYXV0aCBUTFMgb25seTwvb3B0aW9uPjxvcHRpb24gdmFsdWU9MT5TZXJ2ZXItYXV0aCwgbm9uLVRMUyBhbGxvd2VkPC9vcHRpb24+IjsNCiAgICAgICAgICAgIGlmIChhbXR2ZXJzaW9uIDwgOCkgeyB4ICs9ICI8b3B0aW9uIHZhbHVlPTI+TXV0dWFsLWF1dGggVExTIG9ubHk8L29wdGlvbj48b3B0aW9uIHZhbHVlPTM+TXV0dWFsLWF1dGgsIG5vbi1UTFMgYWxsb3dlZDwvb3B0aW9uPiI7IH0gLy8gU3VwcG9ydCBmb3IgbXV0dWFsLWF1dGggVExTIHNlZW1zIHRvIGhhdmUgYmVlbiByZW1vdmVkIG9uIEFNVDggYW5kIGFmdGVyDQogICAgICAgICAgICB4ICs9ICI8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5TZWN1cml0eTwvZGl2PjwvZGl2PjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHggaWQ9ZDExcmNuIHRpdGxlPSdDb21tYSBzZXBlcmF0ZWQgbGlzdCBvZiBjZXJ0aWZpY2F0ZSBjb21tb24gbmFtZXMgdGhhdCB3aWxsIGJlIGFsbG93ZWQgdG8gY29ubmVjdCByZW1vdGVseS4nPjxpbnB1dCBpZD1kMTFfcmNuIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG9ua2V5dXA9c2hvd1NldFRsc1NlY3VyaXR5RGxnVXBkYXRlKCkgcGxhY2Vob2xkZXI9J25hbWUxLCBuYW1lMic+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+UmVtb3RlIENOJ3M8L2Rpdj48L2Rpdj4iOw0KDQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiVExTIFNldHRpbmdzIiwgMywgc2hvd1NldFRsc1NlY3VyaXR5RGxnT2ssIHgpOw0KDQogICAgICAgICAgICAvLyBTZWxlY3QgdGhlIGN1cnJlbnQgVExTIGNlcnRpZmljYXRlIGluIHRoZSBkcm9wIGRvd24gYm94DQogICAgICAgICAgICBpZiAoKHh4VExTQ3JlZGVudGlhbENvbnRleHQubGVuZ3RoID09IDApIHx8ICh4eFRsc1NldHRpbmdzWzBdWydFbmFibGVkJ10gPT0gZmFsc2UpIHx8ICh4eFRsc1NldHRpbmdzWzFdWydFbmFibGVkJ10gPT0gZmFsc2UpKSB7DQogICAgICAgICAgICAgICAgZ2V0U2VsZWN0RWxlbWVudCgndGxzY2VydCcpLnZhbHVlID0gLTE7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHZhciBjZXJ0SW5zdGFuY2VJZCA9IHh4VExTQ3JlZGVudGlhbENvbnRleHRbMF1bJ0VsZW1lbnRJbkNvbnRleHQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWydWYWx1ZSddOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhDZXJ0aWZpY2F0ZXMpIHsgaWYgKHh4Q2VydGlmaWNhdGVzW2ldWydJbnN0YW5jZUlEJ10gPT0gY2VydEluc3RhbmNlSWQpIHsgZ2V0U2VsZWN0RWxlbWVudCgndGxzY2VydCcpLnZhbHVlID0gaTsgfSB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIEZpZ3VyZSBvdXQgd2hhdCBpbmRleCBpcyBsb2NhbCAmIHJlbW90ZQ0KICAgICAgICAgICAgdmFyIGxvY2FsTmR4ID0gKCh4eFRsc1NldHRpbmdzWzBdWydJbnN0YW5jZUlEJ10gPT0gJ0ludGVsKHIpIEFNVCBMTVMgVExTIFNldHRpbmdzJykpID8gMCA6IDEsIHJlbW90ZU5keCA9ICgxIC0gbG9jYWxOZHgpOw0KDQogICAgICAgICAgICAvLyBTZWxlY3QgY29ycmVjdCBUTFMgb3B0aW9ucyBpbiB0aGUgZHJvcCBkb3duIGJveGVzDQogICAgICAgICAgICBnZXRTZWxlY3RFbGVtZW50KCd0bHNyZW1vdGUnKS52YWx1ZSA9ICgoeHhUbHNTZXR0aW5nc1tyZW1vdGVOZHhdWydNdXR1YWxBdXRoZW50aWNhdGlvbiddID09IHRydWUpID8gMiA6IDApICsgKCh4eFRsc1NldHRpbmdzW3JlbW90ZU5keF1bJ0FjY2VwdE5vblNlY3VyZUNvbm5lY3Rpb25zJ10gPT0gdHJ1ZSkgPyAxIDogMCk7DQogICAgICAgICAgICBpZiAoeHhUbHNTZXR0aW5nc1tyZW1vdGVOZHhdWydUcnVzdGVkQ04nXSkgeyBRKCdkMTFfcmNuJykudmFsdWUgPSBNYWtlVG9BcnJheSh4eFRsc1NldHRpbmdzW3JlbW90ZU5keF1bJ1RydXN0ZWRDTiddKS5qb2luKCcsICcpOyB9DQoNCiAgICAgICAgICAgIHNob3dTZXRUbHNTZWN1cml0eURsZ1VwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1NldFRsc1NlY3VyaXR5RGxnVXBkYXRlKCkgew0KICAgICAgICAgICAgdmFyIGggPSBnZXRTZWxlY3RFbGVtZW50KCd0bHNjZXJ0JykudmFsdWU7DQogICAgICAgICAgICBRRSgndGxzcmVtb3RlJywgaCAhPSAtMSk7DQogICAgICAgICAgICBRVignZDExcmNuJywgKGggIT0gLTEpICYmIChnZXRTZWxlY3RFbGVtZW50KCd0bHNyZW1vdGUnKS52YWx1ZSA+IDEpKTsNCiAgICAgICAgICAgIHZhciBvayA9IHRydWU7DQogICAgICAgICAgICBpZiAoKGdldFNlbGVjdEVsZW1lbnQoJ3Rsc3JlbW90ZScpLnZhbHVlID4gMSkgJiYgKCFzcGxpdERvbWFpbnMoUSgnZDExX3JjbicpLnZhbHVlKSkpIHsgb2sgPSBmYWxzZTsgfQ0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIHZhciBzZXRUbHNTZWN1cml0eVBlbmRpbmdDYWxsczsNCiAgICAgICAgdmFyIHNldFRsc1NlY3VyaXR5RGVsZXRlQ3JlZGVudGlhbENvbnRleHQ7DQogICAgICAgIGZ1bmN0aW9uIHNob3dTZXRUbHNTZWN1cml0eURsZ09rKCkgew0KICAgICAgICAgICAgdmFyIGggPSBnZXRTZWxlY3RFbGVtZW50KCd0bHNjZXJ0JykudmFsdWU7DQogICAgICAgICAgICB2YXIgciA9IGdldFNlbGVjdEVsZW1lbnQoJ3Rsc3JlbW90ZScpLnZhbHVlOw0KICAgICAgICAgICAgdmFyIHh4VGxzU2V0dGluZ3MyID0gQ2xvbmUoeHhUbHNTZXR0aW5ncyk7DQogICAgICAgICAgICBzZXRUbHNTZWN1cml0eVBlbmRpbmdDYWxscyA9IDA7DQogICAgICAgICAgICBzZXRUbHNTZWN1cml0eURlbGV0ZUNyZWRlbnRpYWxDb250ZXh0ID0gbnVsbDsNCg0KICAgICAgICAgICAgaWYgKGggIT0gLTEpIHsNCiAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIFRMUyBjZXJ0aWZpY2F0ZQ0KICAgICAgICAgICAgICAgIGlmICh4eFRMU0NyZWRlbnRpYWxDb250ZXh0Lmxlbmd0aCA+IDApIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gTW9kaWZ5IHRoZSBjdXJyZW50IGNvbnRleHQNCiAgICAgICAgICAgICAgICAgICAgdmFyIG5ld1RMU0NyZWRlbnRpYWxDb250ZXh0ID0gQ2xvbmUoeHhUTFNDcmVkZW50aWFsQ29udGV4dFswXSk7DQogICAgICAgICAgICAgICAgICAgIG5ld1RMU0NyZWRlbnRpYWxDb250ZXh0WydFbGVtZW50SW5Db250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVsnVmFsdWUnXSA9IHh4Q2VydGlmaWNhdGVzW2hdWydJbnN0YW5jZUlEJ107DQogICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLlB1dCgnQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0JywgbmV3VExTQ3JlZGVudGlhbENvbnRleHQsIHNldFRsc1NlY3VyaXR5UmVzcG9uc2UsIDAsIDEpOw0KICAgICAgICAgICAgICAgICAgICBzZXRUbHNTZWN1cml0eVBlbmRpbmdDYWxscysrOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIC8vIEFkZCBhIG5ldyBzZWN1cml0eSBjb250ZXh0DQogICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLkNyZWF0ZSgnQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0Jywgew0KICAgICAgICAgICAgICAgICAgICAgICAgJ0VsZW1lbnRJbkNvbnRleHQnOic8YTpBZGRyZXNzPi93c21hbjwvYTpBZGRyZXNzPjxhOlJlZmVyZW5jZVBhcmFtZXRlcnM+PHc6UmVzb3VyY2VVUkk+JyArIGFtdHN0YWNrLkNvbXBsZXRlTmFtZSgnQU1UX1B1YmxpY0tleUNlcnRpZmljYXRlJykgKyAnPC93OlJlc291cmNlVVJJPjx3OlNlbGVjdG9yU2V0Pjx3OlNlbGVjdG9yIE5hbWU9Ikluc3RhbmNlSUQiPicgKyB4eENlcnRpZmljYXRlc1toXVsnSW5zdGFuY2VJRCddICsgJzwvdzpTZWxlY3Rvcj48L3c6U2VsZWN0b3JTZXQ+PC9hOlJlZmVyZW5jZVBhcmFtZXRlcnM+JywNCiAgICAgICAgICAgICAgICAgICAgICAgICdFbGVtZW50UHJvdmlkaW5nQ29udGV4dCc6JzxhOkFkZHJlc3M+L3dzbWFuPC9hOkFkZHJlc3M+PGE6UmVmZXJlbmNlUGFyYW1ldGVycz48dzpSZXNvdXJjZVVSST4nICsgYW10c3RhY2suQ29tcGxldGVOYW1lKCdBTVRfVExTUHJvdG9jb2xFbmRwb2ludENvbGxlY3Rpb24nKSArICc8L3c6UmVzb3VyY2VVUkk+PHc6U2VsZWN0b3JTZXQ+PHc6U2VsZWN0b3IgTmFtZT0iRWxlbWVudE5hbWUiPlRMU1Byb3RvY29sRW5kcG9pbnRJbnN0YW5jZXMgQ29sbGVjdGlvbjwvdzpTZWxlY3Rvcj48L3c6U2VsZWN0b3JTZXQ+PC9hOlJlZmVyZW5jZVBhcmFtZXRlcnM+JyB9LCBzZXRUbHNTZWN1cml0eVJlc3BvbnNlKTsNCiAgICAgICAgICAgICAgICAgICAgc2V0VGxzU2VjdXJpdHlQZW5kaW5nQ2FsbHMrKzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIC8vIENsZWFyIHRoZSBUTFMgY2VydGlmaWNhdGUgYXNzb2NpYXRpb24gKE1PVkUgVEhJUykNCiAgICAgICAgICAgICAgICBpZiAoeHhUTFNDcmVkZW50aWFsQ29udGV4dC5sZW5ndGggPiAwKSB7IHNldFRsc1NlY3VyaXR5RGVsZXRlQ3JlZGVudGlhbENvbnRleHQgPSBDbG9uZSh4eFRMU0NyZWRlbnRpYWxDb250ZXh0WzBdKTsgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBGaWd1cmUgb3V0IHdoYXQgaW5kZXggaXMgbG9jYWwgJiByZW1vdGUNCiAgICAgICAgICAgIHZhciBsb2NhbE5keCA9ICgoeHhUbHNTZXR0aW5nc1swXVsnSW5zdGFuY2VJRCddID09ICdJbnRlbChyKSBBTVQgTE1TIFRMUyBTZXR0aW5ncycpKSA/IDAgOiAxLCByZW1vdGVOZHggPSAoMSAtIGxvY2FsTmR4KTsNCg0KICAgICAgICAgICAgLy8gUmVtb3RlIFRMUyBzZXR0aW5ncw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5nczJbcmVtb3RlTmR4XVsnRW5hYmxlZCddID0gKGggIT0gLTEpOw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5nczJbcmVtb3RlTmR4XVsnTXV0dWFsQXV0aGVudGljYXRpb24nXSA9IChyID49IDIpOw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5nczJbcmVtb3RlTmR4XVsnQWNjZXB0Tm9uU2VjdXJlQ29ubmVjdGlvbnMnXSA9ICgociAlIDIpID09IDEpOw0KICAgICAgICAgICAgeHhUbHNTZXR0aW5nczJbcmVtb3RlTmR4XVsnVHJ1c3RlZENOJ10gPSBzcGxpdERvbWFpbnMoUSgnZDExX3JjbicpLnZhbHVlKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgLy8gTG9jYWwgVExTIHNldHRpbmdzDQogICAgICAgICAgICB4eFRsc1NldHRpbmdzMltsb2NhbE5keF1bJ0VuYWJsZWQnXSA9IChoICE9IC0xKTsNCg0KICAgICAgICAgICAgLy8gVXBkYXRlIFRMUyBzZXR0aW5ncw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfVExTU2V0dGluZ0RhdGEnLCB4eFRsc1NldHRpbmdzMlswXSwgc2V0VGxzU2VjdXJpdHlSZXNwb25zZSwgMCwgMSwgeHhUbHNTZXR0aW5nczJbMF0pOw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfVExTU2V0dGluZ0RhdGEnLCB4eFRsc1NldHRpbmdzMlsxXSwgc2V0VGxzU2VjdXJpdHlSZXNwb25zZSwgMCwgMSwgeHhUbHNTZXR0aW5nczJbMV0pOw0KICAgICAgICAgICAgc2V0VGxzU2VjdXJpdHlQZW5kaW5nQ2FsbHMgKz0gMjsNCg0KICAgICAgICAgICAgc3RhdHVzYm94KCJUTFMgU2V0dGluZ3MiLCAiQXBwbHlpbmcgbmV3IHNlY3VyaXR5IHNldHRpbmdzLi4uIik7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBTcGxpdCBhIHN0cmluZyBpbnRvIGEgYXJyYXkgb2YgZG9tYWlucy4gUmV0dXJuIG51bGwgaWYgbm90IGEgdmFsaWQgbGlzdC4NCiAgICAgICAgZnVuY3Rpb24gc3BsaXREb21haW5zKHN0cikgew0KICAgICAgICAgICAgc3RyID0gc3RyLnNwbGl0KCcsJyk7DQogICAgICAgICAgICBpZiAoc3RyLmxlbmd0aCA9PSAwKSByZXR1cm47DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHN0cikgeyBzdHJbaV0gPSBzdHJbaV0udHJpbSgpOyBpZiAoKHN0cltpXS5pbmRleE9mKCcgJykgPj0gMCkgfHwgKHN0cltpXS5sZW5ndGggPT0gMCkpIHJldHVybjsgfQ0KICAgICAgICAgICAgaWYgKHN0ci5sZW5ndGggPiA0KSByZXR1cm47DQogICAgICAgICAgICByZXR1cm4gc3RyOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2V0VGxzU2VjdXJpdHlSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCIiLCAiRmFpbGVkIHRvIHNldCBUTFMgc2VjdXJpdHksIHN0YXR1cyA9ICIgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgIGlmIChyZXNwb25zZS5Cb2R5WydSZXR1cm5WYWx1ZVN0ciddICYmICFtZXRob2RjaGVjayhyZXNwb25zZSkpIHJldHVybjsNCg0KICAgICAgICAgICAgLy8gQ2hlY2sgaWYgYWxsIHRoZSBjYWxscyBhcmUgZG9uZQ0KICAgICAgICAgICAgaWYgKCgtLXNldFRsc1NlY3VyaXR5UGVuZGluZ0NhbGxzKSA9PSAwKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIC8vIFBlcmZvcm0gYSBjb21taXQNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5BTVRfU2V0dXBBbmRDb25maWd1cmF0aW9uU2VydmljZV9Db21taXRDaGFuZ2VzKG51bGwsIHNldFRsc1NlY3VyaXR5UmVzcG9uc2UyKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNldFRsc1NlY3VyaXR5UmVzcG9uc2UyKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCIiLCAiRmFpbGVkIHRvIHNldCBUTFMgc2VjdXJpdHksIHN0YXR1cyA9ICIgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgIC8vIGlmIChyZXNwb25zZS5Cb2R5WydSZXR1cm5WYWx1ZVN0ciddICYmICFtZXRob2RjaGVjayhyZXNwb25zZSkpIHJldHVybjsNCiAgICAgICAgICAgIHNldFRpbWVvdXQoc2V0VGxzU2VjdXJpdHlSZXNwb25zZTMsIDIwMDApOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2V0VGxzU2VjdXJpdHlSZXNwb25zZTMoKSB7DQogICAgICAgICAgICBpZiAoc2V0VGxzU2VjdXJpdHlEZWxldGVDcmVkZW50aWFsQ29udGV4dCAhPSBudWxsKSB7IGFtdHN0YWNrLkRlbGV0ZSgnQU1UX1RMU0NyZWRlbnRpYWxDb250ZXh0Jywgc2V0VGxzU2VjdXJpdHlEZWxldGVDcmVkZW50aWFsQ29udGV4dCwgZnVuY3Rpb24gKCkgeyB9KTsgfQ0KICAgICAgICAgICAgUHVsbENlcnRpZmljYXRlcygpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgpOw0KICAgICAgICB9DQoNCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gQUdFTlQgUFJFU0VOQ0UNCiAgICAgICAgLy8NCg0KICAgICAgICB2YXIgeHhXYXRjaGRvZyA9IG51bGw7DQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFdhdGNoZG9nKCkgew0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKG51bGwsIFsiKkFNVF9BZ2VudFByZXNlbmNlQ2FwYWJpbGl0aWVzIiwgIkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2ciLCAiQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ0FjdGlvbiIsICJBTVRfU3RhdGVUcmFuc2l0aW9uQ29uZGl0aW9uIiwgIkNJTV9Db25jcmV0ZURlcGVuZGVuY3kiXSwgUHVsbFdhdGNoZG9nUmVzcG9uc2UpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFdhdGNoZG9nUmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoKHN0YXR1cyA9PSAyMDApICYmIChyZXNwb25zZXNbJ0FNVF9BZ2VudFByZXNlbmNlQ2FwYWJpbGl0aWVzJ10uc3RhdHVzID09IDIwMCkpIHsNCiAgICAgICAgICAgICAgICB4eFdhdGNoZG9nID0gcmVzcG9uc2VzOw0KICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgLy8gUGxhY2UgdGhlIGFjdGlvbnMgaW50byB0aGUgd2F0Y2hkb2dzIGZvciBlYXN5IG5hdmlnYXRpb24uDQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFdhdGNoZG9nWydDSU1fQ29uY3JldGVEZXBlbmRlbmN5J10ucmVzcG9uc2VzKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBsaW5rID0geHhXYXRjaGRvZ1snQ0lNX0NvbmNyZXRlRGVwZW5kZW5jeSddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHgxID0gZ2V0SXRlbShsaW5rWydBbnRlY2VkZW50J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXSwgJ0BOYW1lJywgJ0NyZWF0aW9uQ2xhc3NOYW1lJyk7DQogICAgICAgICAgICAgICAgICAgIGlmICh4MSAmJiB4MVsnVmFsdWUnXSA9PSAnQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZycpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZXZpY2VpZCA9IGdldEl0ZW0obGlua1snQW50ZWNlZGVudCddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10sICdATmFtZScsICdEZXZpY2VJRCcpWydWYWx1ZSddOw0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvbGljeUNvbmRpdGlvbk5hbWUgPSBnZXRJdGVtKGxpbmtbJ0RlcGVuZGVudCddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10sICdATmFtZScsICdQb2xpY3lDb25kaXRpb25OYW1lJylbJ1ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2F0Y2hkb2cgPSBnZXRJdGVtKHh4V2F0Y2hkb2dbJ0FNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2cnXS5yZXNwb25zZXMsICdEZXZpY2VJRCcsIGRldmljZWlkKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0cmFuc2l0aW9uUG9saWN5ID0gZ2V0SXRlbSh4eFdhdGNoZG9nWydBTVRfU3RhdGVUcmFuc2l0aW9uQ29uZGl0aW9uJ10ucmVzcG9uc2VzLCAnUG9saWN5Q29uZGl0aW9uTmFtZScsIHBvbGljeUNvbmRpdGlvbk5hbWUpOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF3YXRjaGRvZy50cmFuc2l0aW9ucykgd2F0Y2hkb2cudHJhbnNpdGlvbnMgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHdhdGNoZG9nLnRyYW5zaXRpb25zLnB1c2godHJhbnNpdGlvblBvbGljeSk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKHgxICYmIHgxWydWYWx1ZSddID09ICdBTVRfU3RhdGVUcmFuc2l0aW9uQ29uZGl0aW9uJykgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvbGljeUNvbmRpdGlvbk5hbWUgPSBnZXRJdGVtKGxpbmtbJ0FudGVjZWRlbnQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddLCAnQE5hbWUnLCAnUG9saWN5Q29uZGl0aW9uTmFtZScpWydWYWx1ZSddOw0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBvbGljeUFjdGlvbk5hbWUgPSBnZXRJdGVtKGxpbmtbJ0RlcGVuZGVudCddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10sICdATmFtZScsICdQb2xpY3lBY3Rpb25OYW1lJylbJ1ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgdHJhbnNpdGlvblBvbGljeSA9IGdldEl0ZW0oeHhXYXRjaGRvZ1snQU1UX1N0YXRlVHJhbnNpdGlvbkNvbmRpdGlvbiddLnJlc3BvbnNlcywgJ1BvbGljeUNvbmRpdGlvbk5hbWUnLCBwb2xpY3lDb25kaXRpb25OYW1lKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3YXRjaGRvZ0FjdGlvbiA9IGdldEl0ZW0oeHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ0FjdGlvbiddLnJlc3BvbnNlcywgJ1BvbGljeUFjdGlvbk5hbWUnLCBwb2xpY3lBY3Rpb25OYW1lKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdHJhbnNpdGlvblBvbGljeS5hY3Rpb25zKSB0cmFuc2l0aW9uUG9saWN5LmFjdGlvbnMgPSBbXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zaXRpb25Qb2xpY3kuYWN0aW9ucy5wdXNoKHdhdGNoZG9nQWN0aW9uKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIHVwZGF0ZVdhdGNoZG9nKCk7DQogICAgICAgICAgICAgICAgUVYoJ2dvMTknLCB0cnVlKTsgLy8gU2hvdyBBZ2VudCBQcmVzZW5jZSBwYW5lbA0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIHdhdGNoZG9nRW5hYmxlZFN0YXRlcyA9IFsgJ1Vua25vd24nLCAnT3RoZXInLCAnRW5hYmxlZCcsICdEaXNhYmxlZCcsICdTaHV0dGluZyBEb3duJywgJ05vdCBBcHBsaWNhYmxlJywgJ0VuYWJsZWQgYnV0IE9mZmxpbmUnLCAnSW4gVGVzdCcsICdEZWZlcnJlZCcsICdRdWllc2NlJywgJ1N0YXJ0aW5nJyBdOw0KICAgICAgICB2YXIgd2F0Y2hkb2dNb25pdG9yZWRFbnRpdHkgPSBbICdVbmtub3duJywgJ090aGVyJywgJ09wZXJhdGluZyBTeXN0ZW0nLCAnT3BlcmF0aW5nIFN5c3RlbSBCb290IFByb2Nlc3MnLCAnT3BlcmF0aW5nIFN5c3RlbSBTaHV0ZG93biBQcm9jZXNzJywgJ0Zpcm13YXJlIEJvb3QgUHJvY2VzcycsICdCSU9TIEJvb3QgUHJvY2VzcycsICdBcHBsaWNhdGlvbicsICdTZXJ2aWNlIFByb2Nlc3NvcicgXTsNCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlV2F0Y2hkb2coKSB7DQogICAgICAgICAgICBpZiAoeHhXYXRjaGRvZyA9PSBudWxsKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9ICcnOw0KDQogICAgICAgICAgICAvLyBHbG9iYWwgQWdlbnQgUHJlc2Vuc2UgVmFsdWVzDQogICAgICAgICAgICB4ICs9IFRhYmxlU3RhcnQoKTsNCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiTWF4aW11bSBXYXRjaGRvZ3MiLCB4eFdhdGNoZG9nWydBTVRfQWdlbnRQcmVzZW5jZUNhcGFiaWxpdGllcyddLnJlc3BvbnNlWydNYXhUb3RhbEFnZW50cyddICsgIiB3YXRjaGRvZ3MiKTsNCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiTWF4aW11bSBUb3RhbCBBY3Rpb25zIiwgeHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VDYXBhYmlsaXRpZXMnXS5yZXNwb25zZVsnTWF4VG90YWxBY3Rpb25zJ10gKyAiIGFjdGlvbnMiKTsNCiAgICAgICAgICAgIC8vIHggKz0gVGFibGVFbnRyeSgiTWF4aW11bSBFQUMgV2F0Y2hkb2dzIiwgeHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VDYXBhYmlsaXRpZXMnXS5yZXNwb25zZVsnTWF4RWFjQWdlbnRzJ10gKyAiIHdhdGNoZG9ncyIpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpICsgIjxicj4iOw0KDQogICAgICAgICAgICAvLyBXYXRjaGRvZ3MNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCBhZ2VudCBwcmVzZW5jZSB3YXRjaGRvZ3MuPGJyPjxicj4iOw0KICAgICAgICAgICAgaWYgKCh4eFdhdGNoZG9nWydBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nJ10ucmVzcG9uc2VzID09IG51bGwpIHx8ICh4eFdhdGNoZG9nWydBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nJ10ucmVzcG9uc2VzLmxlbmd0aCA9PSAwKSkgew0KICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGk+Tm8gYWdlbnQgcHJlc2VuY2Ugd2F0Y2hkb2cgZm91bmQuPC9pPjwvZGl2Pjxicj4iOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4V2F0Y2hkb2dbJ0FNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2cnXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHcgPSB4eFdhdGNoZG9nWydBTVRfQWdlbnRQcmVzZW5jZVdhdGNoZG9nJ10ucmVzcG9uc2VzW2ldOw0KICAgICAgICAgICAgICAgICAgICB2YXIgbiA9IGd1aWRUb1N0cihyc3RyMmhleChhdG9iKHdbJ0RldmljZUlEJ10pKSk7DQogICAgICAgICAgICAgICAgICAgIGlmICh3WydNb25pdG9yZWRFbnRpdHlEZXNjcmlwdGlvbiddICYmIHdbJ01vbml0b3JlZEVudGl0eURlc2NyaXB0aW9uJ10gIT0gJycpIG4gPSBFc2NhcGVIdG1sKHdbJ01vbml0b3JlZEVudGl0eURlc2NyaXB0aW9uJ10pOw0KICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93V2F0Y2hkb2dEZXRhaWxzKCIgKyBpICsgIik+PGlucHV0IHR5cGU9YnV0dG9uIHN0eWxlPWZsb2F0OnJpZ2h0IHZhbHVlPSdBZGQgQWN0aW9uLi4uJyBvbmNsaWNrPWFkZFdhdGNoZG9nQWN0aW9uKGV2ZW50LCIgKyBpICsgIik+IjsNCiAgICAgICAgICAgICAgICAgICAgaWYgKHcudHJhbnNpdGlvbnMpIHsgeCArPSAiPGlucHV0IHR5cGU9YnV0dG9uIHN0eWxlPWZsb2F0OnJpZ2h0IHZhbHVlPSdEZWxldGUgQWN0aW9ucy4uLicgb25jbGljaz1kZWxldGVXYXRjaGRvZ0FjdGlvbnMoZXZlbnQsIiArIGkgKyAiKT4iOyB9DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyBuICsgIjwvYj4sICIgKyBhbXRzdGFjay5XYXRjaGRvZ0N1cnJlbnRTdGF0ZXNbd1snQ3VycmVudFN0YXRlJ11dICsgIjwvZGl2PiI7DQogICAgICAgICAgICAgICAgICAgIHZhciB4eCA9ICcnOw0KICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBqIGluIHcudHJhbnNpdGlvbnMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0ID0gdy50cmFuc2l0aW9uc1tqXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4eCAhPSAnJykgeHggKz0gIjxicj4iOw0KICAgICAgICAgICAgICAgICAgICAgICAgeHggKz0gZ2V0V2F0Y2hkb2dUcmFuc2l0aW9uU3RyKHRbJ09sZFN0YXRlJ10pICsgIiAmcmFycjsgIiArIGdldFdhdGNoZG9nVHJhbnNpdGlvblN0cih0WydOZXdTdGF0ZSddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0LmFjdGlvbnMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgYWN0aW9uID0gdC5hY3Rpb25zWzBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhY3Rpb25bJ0V2ZW50T25UcmFuc2l0aW9uJ10gPT0gdHJ1ZSkgeyB4eCArPSAiIDogRXZlbnQgdG8gbG9nIjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIGlmICh4eCAhPSAnJykgeyB4ICs9ICI8ZGl2IHN0eWxlPXBhZGRpbmc6MTJweD4iICsgeHggKyAiPC9kaXY+IjsgfQ0KICAgICAgICAgICAgICAgICAgICB4ICs9ICI8L2Rpdj4iOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZChBZGRSZWZyZXNoQnV0dG9uKCJQdWxsV2F0Y2hkb2coKSIpICsgQWRkQnV0dG9uKCJBZGQgV2F0Y2hkb2cuLi4iLCAiQWRkV2F0Y2hkb2coKSIpKTsNCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KDQogICAgICAgICAgICBRSCgnaWRfVGFibGVTeXN0ZW1BZ2VudFByZXNlbmNlJywgeCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBnZXRXYXRjaGRvZ1RyYW5zaXRpb25TdHIocykgew0KICAgICAgICAgICAgaWYgKHMgPT0gMzEpIHJldHVybiAiQW55IFN0YXRlIjsNCiAgICAgICAgICAgIHZhciB4ID0gJyc7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGFtdHN0YWNrLldhdGNoZG9nQ3VycmVudFN0YXRlcykgeyBpZiAoKHMgJiBpKSAhPSAwKSB7IHggKz0gJywgJyArIGFtdHN0YWNrLldhdGNoZG9nQ3VycmVudFN0YXRlc1tpXTsgfSB9DQogICAgICAgICAgICByZXR1cm4geC5zdWJzdHJpbmcoMik7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93V2F0Y2hkb2dEZXRhaWxzKGkpIHsNCiAgICAgICAgICAgIHZhciB3ID0geHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZyddLnJlc3BvbnNlc1tpXTsNCg0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIC8veCArPSBhZGRIdG1sVmFsdWUoJ0RldmljZUlEJywgZ3VpZFRvU3RyKHJzdHIyaGV4KGF0b2Iod1snRGV2aWNlSUQnXSkpKSk7DQogICAgICAgICAgICBpZiAod1snTW9uaXRvcmVkRW50aXR5RGVzY3JpcHRpb24nXSAmJiB3WydNb25pdG9yZWRFbnRpdHlEZXNjcmlwdGlvbiddICE9ICcnKSB4ICs9IGFkZEh0bWxWYWx1ZSgnRGVzY3JpcHRpb24nLCBFc2NhcGVIdG1sKHdbJ01vbml0b3JlZEVudGl0eURlc2NyaXB0aW9uJ10pKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdNb25pdG9yZWQgRW50aXR5Jywgd2F0Y2hkb2dNb25pdG9yZWRFbnRpdHlbd1snTW9uaXRvcmVkRW50aXR5J11dKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdDdXJyZW50IFN0YXRlJywgYW10c3RhY2suV2F0Y2hkb2dDdXJyZW50U3RhdGVzW3dbJ0N1cnJlbnRTdGF0ZSddXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnRW5hYmxlZCBTdGF0ZScsIHdhdGNoZG9nRW5hYmxlZFN0YXRlc1t3WydFbmFibGVkU3RhdGUnXV0pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ1N0YXJ0dXAgSW50ZXJ2YWwnLCB3WydTdGFydHVwSW50ZXJ2YWwnXSArICcgc2Vjb25kKHMpJyk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnVGltZW91dCBJbnRlcnZhbCcsIHdbJ1RpbWVvdXRJbnRlcnZhbCddICsgJyBzZWNvbmQocyknKTsNCg0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ1dhdGNoZG9nICcgKyBndWlkVG9TdHIocnN0cjJoZXgoYXRvYih3WydEZXZpY2VJRCddKSkpLCA1LCBzaG93V2F0Y2hkb2dEZXRhaWxzT2ssIHgsIHcpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1dhdGNoZG9nRGV0YWlsc09rKHgsIHcpIHsNCiAgICAgICAgICAgIGlmICh4ID09IDIpIHsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5EZWxldGUoJ0FNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2cnLCB7ICdEZXZpY2VJRCc6IHdbJ0RldmljZUlEJ10gfSwgUHVsbFdhdGNoZG9nKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZFdhdGNoZG9nKCkgew0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPXdnbmFtZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweCBtYXhsZW5ndGg9MTYgb25rZXl1cD1BZGRXYXRjaGRvZ1VwZGF0ZSgpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4Pk5hbWU8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48aW5wdXQgaWQ9d2dndWlkIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI0MHB4IG1heGxlbmd0aD0zNiBvbmtleXVwPUFkZFdhdGNoZG9nVXBkYXRlKCk+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHggdGl0bGU9J0dlbmVyYXRlIHJhbmRvbSBEZXZpY2VJRCc+IiArIGFkZExpbmsoIkRldmljZUlEIiwgIkdlbmVyYXRlV2F0Y2hkb2dHdWlkKCkiKSArICI8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48aW5wdXQgaWQ9d2dzdGFydCBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweCBtYXhsZW5ndGg9OCBwbGFjZWhvbGRlcj0zNjAwIG9ua2V5dXA9QWRkV2F0Y2hkb2dVcGRhdGUoKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5TdGFydHVwIChzZWNvbmRzKTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxpbnB1dCBpZD13Z3RpbWVvdXQgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjQwcHggbWF4bGVuZ3RoPTggcGxhY2Vob2xkZXI9NjAgb25rZXl1cD1BZGRXYXRjaGRvZ1VwZGF0ZSgpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PlRpbWVvdXQgKHNlY29uZHMpPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdBZGQgV2F0Y2hkb2cnLCAzLCBBZGRXYXRjaGRvZ09rLCB4KTsNCiAgICAgICAgICAgIEFkZFdhdGNoZG9nVXBkYXRlKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBHZW5lcmF0ZVdhdGNoZG9nR3VpZCgpIHsNCiAgICAgICAgICAgIHZhciBpLCBndWlkID0gJyc7DQogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgMTY7IGkrKykgeyBndWlkICs9IFN0cmluZy5mcm9tQ2hhckNvZGUocmFuZG9tKDI1NSkpOyB9DQogICAgICAgICAgICBRKCd3Z2d1aWQnKS52YWx1ZSA9IGd1aWRUb1N0cihyc3RyMmhleChndWlkKSk7DQogICAgICAgICAgICBBZGRXYXRjaGRvZ1VwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkV2F0Y2hkb2dVcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgb2sgPSAoUSgnd2dzdGFydCcpLnZhbHVlID09ICcnIHx8IHBhcnNlSW50KFEoJ3dnc3RhcnQnKS52YWx1ZSkgPiAwKSAmJiAoUSgnd2d0aW1lb3V0JykudmFsdWUgPT0gJycgfHwgcGFyc2VJbnQoUSgnd2d0aW1lb3V0JykudmFsdWUpID4gMCk7DQogICAgICAgICAgICB2YXIgZ2MgPSAwLCBnID0gUSgnd2dndWlkJykudmFsdWUudG9Mb3dlckNhc2UoKTsNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZy5sZW5ndGg7IGkrKykgew0KICAgICAgICAgICAgICAgIHZhciBjID0gZy5jaGFyQ29kZUF0KGkpOw0KICAgICAgICAgICAgICAgIGlmIChjID09IDQ1KSBjb250aW51ZTsNCiAgICAgICAgICAgICAgICBpZiAoKGMgPj0gNDggJiYgYyA8PSA1NykgfHwgKGMgPj0gOTcgJiYgYyA8PSAxMDIpKSB7IGdjKys7IH0gZWxzZSB7IG9rID0gZmFsc2U7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChnYyAhPSAzMikgb2sgPSBmYWxzZTsNCiAgICAgICAgICAgIFFFKCdkbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZFdhdGNoZG9nT2soKSB7DQogICAgICAgICAgICB2YXIgdGltZW91dCA9IFEoJ3dndGltZW91dCcpLnZhbHVlLCBzdGFydHVwID0gUSgnd2dzdGFydCcpLnZhbHVlOw0KICAgICAgICAgICAgaWYgKHRpbWVvdXQgPT0gJycpIHRpbWVvdXQgPSA2MDsNCiAgICAgICAgICAgIGlmIChzdGFydHVwID09ICcnKSBzdGFydHVwID0gMzYwMDsNCiAgICAgICAgICAgIHZhciBndWlkID0gYnRvYShoZXgycnN0cihndWlkVG9TdHIoUSgnd2dndWlkJykudmFsdWUucmVwbGFjZSgvLS9nLCAnJykpLnJlcGxhY2UoLy0vZywgJycpKSk7DQogICAgICAgICAgICB2YXIgd2RvZyA9IHsgJ0NyZWF0aW9uQ2xhc3NOYW1lJzogMCwgJ0RldmljZUlEJzogZ3VpZCwgJ1N0YXJ0dXBJbnRlcnZhbCc6IHN0YXJ0dXAsICdTeXN0ZW1DcmVhdGlvbkNsYXNzTmFtZSc6IDAsICdTeXN0ZW1OYW1lJzogMCwgJ1RpbWVvdXRJbnRlcnZhbCc6IHRpbWVvdXQsICdNb25pdG9yZWRFbnRpdHlEZXNjcmlwdGlvbic6IFEoJ3dnbmFtZScpLnZhbHVlIH07DQogICAgICAgICAgICBhbXRzdGFjay5DcmVhdGUoJ0FNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2cnLCB3ZG9nLCBBZGRXYXRjaGRvZ09rMik7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRXYXRjaGRvZ09rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnV2F0Y2hkb2cnLCAiVW5hYmxlIHRvIGFkZCB3YXRjaGRvZywgZXJyb3IgIyIgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsV2F0Y2hkb2coKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZFdhdGNoZG9nQWN0aW9uKGUsIGkpIHsNCiAgICAgICAgICAgIHZhciB3ID0geHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZyddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgIHZhciB4ID0gJzx0YWJsZT4nOw0KICAgICAgICAgICAgeCArPSAnPHRkIHN0eWxlPXdpZHRoOjE4MHB4PkZyb208YnI+Jw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBhbXRzdGFjay5XYXRjaGRvZ0N1cnJlbnRTdGF0ZXMpIHsNCiAgICAgICAgICAgICAgICB4ICs9ICc8aW5wdXQgaWQ9d2dzYScgKyBpICsgJyB0eXBlPWNoZWNrYm94IG9uY2xpY2s9YWRkV2F0Y2hkb2dBY3Rpb25VcGRhdGUoKT4gJyArIGFtdHN0YWNrLldhdGNoZG9nQ3VycmVudFN0YXRlc1tpXSArICc8YnIgLz4nOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSAnPHRkPlRvPGJyPicNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYW10c3RhY2suV2F0Y2hkb2dDdXJyZW50U3RhdGVzKSB7DQogICAgICAgICAgICAgICAgeCArPSAnPGlucHV0IGlkPXdnc2InICsgaSArICcgdHlwZT1jaGVja2JveCBvbmNsaWNrPWFkZFdhdGNoZG9nQWN0aW9uVXBkYXRlKCk+ICcgKyBhbXRzdGFjay5XYXRjaGRvZ0N1cnJlbnRTdGF0ZXNbaV0gKyAnPGJyIC8+JzsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gJzwvdGFibGU+PGJyPlBlcmZvcm0gQWN0aW9uPGJyPjxpbnB1dCBpZD13Z3NldmVudCB0eXBlPWNoZWNrYm94IGNoZWNrZWQgb25jbGljaz1hZGRXYXRjaGRvZ0FjdGlvblVwZGF0ZSgpPldyaXRlIHRvIGV2ZW50IGxvZzxiciAvPic7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnQWRkIFdhdGNoZG9nIEFjdGlvbicsIDMsIGFkZFdhdGNoZG9nQWN0aW9uT2ssIHgsIHcpOw0KICAgICAgICAgICAgYWRkV2F0Y2hkb2dBY3Rpb25VcGRhdGUoKTsNCiAgICAgICAgICAgIGhhbHRFdmVudChlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZFdhdGNoZG9nQWN0aW9uVXBkYXRlKCkgew0KICAgICAgICAgICAgdmFyIHRmcm9tID0gMCwgdHRvID0gMDsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYW10c3RhY2suV2F0Y2hkb2dDdXJyZW50U3RhdGVzKSB7DQogICAgICAgICAgICAgICAgaWYgKFEoJ3dnc2EnICsgaSkuY2hlY2tlZCA9PSB0cnVlKSB0ZnJvbSArPSBwYXJzZUludChpKTsNCiAgICAgICAgICAgICAgICBpZiAoUSgnd2dzYicgKyBpKS5jaGVja2VkID09IHRydWUpIHR0byArPSBwYXJzZUludChpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIFFFKCdkbGdPa0J1dHRvbicsIHRmcm9tID4gMCAmJiB0dG8gPiAwICYmIFEoJ3dnc2V2ZW50JykuY2hlY2tlZCA9PSB0cnVlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZFdhdGNoZG9nQWN0aW9uT2soYiwgdykgew0KICAgICAgICAgICAgdmFyIHRmcm9tID0gMCwgdHRvID0gMDsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYW10c3RhY2suV2F0Y2hkb2dDdXJyZW50U3RhdGVzKSB7DQogICAgICAgICAgICAgICAgaWYgKFEoJ3dnc2EnICsgaSkuY2hlY2tlZCA9PSB0cnVlKSB0ZnJvbSArPSBwYXJzZUludChpKTsNCiAgICAgICAgICAgICAgICBpZiAoUSgnd2dzYicgKyBpKS5jaGVja2VkID09IHRydWUpIHR0byArPSBwYXJzZUludChpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9BZ2VudFByZXNlbmNlV2F0Y2hkb2dfQWRkQWN0aW9uKHRmcm9tLCB0dG8sIFEoJ3dnc2V2ZW50JykuY2hlY2tlZCwgbnVsbCwgbnVsbCwgQWRkV2F0Y2hkb2dBY3Rpb25SZXNwb25zZSwgbnVsbCwgMCwgeyAnRGV2aWNlSUQnOiB3WydEZXZpY2VJRCddIH0pOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkV2F0Y2hkb2dBY3Rpb25SZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnV2F0Y2hkb2cgQWN0aW9uJywgIlVuYWJsZSB0byBhZGQgd2F0Y2hkb2cgYWN0aW9uLCBlcnJvciAjIiArIHN0YXR1cyk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFB1bGxXYXRjaGRvZygpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGVsZXRlV2F0Y2hkb2dBY3Rpb25zKGUsIGkpIHsNCiAgICAgICAgICAgIHZhciB3ID0geHhXYXRjaGRvZ1snQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZyddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdEZWxldGUgV2F0Y2hkb2cgQWN0aW9ucycsIDMsIGRlbGV0ZVdhdGNoZG9nQWN0aW9uc09rLCAiRGVsZXRlIGFsbCBhY3Rpb25zIGZvciB0aGlzIHdhdGNoZG9nPyIsIHcpOw0KICAgICAgICAgICAgaGFsdEV2ZW50KGUpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGVsZXRlV2F0Y2hkb2dBY3Rpb25zT2soYiwgdykgew0KICAgICAgICAgICAgYW10c3RhY2suQU1UX0FnZW50UHJlc2VuY2VXYXRjaGRvZ19EZWxldGVBbGxBY3Rpb25zKGRlbGV0ZVdhdGNoZG9nQWN0aW9uUmVzcG9uc2UsIG51bGwsIDAsIHsgJ0RldmljZUlEJzogd1snRGV2aWNlSUQnXSB9KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGRlbGV0ZVdhdGNoZG9nQWN0aW9uUmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goJ1dhdGNoZG9nIEFjdGlvbicsICJVbmFibGUgdG8gcmVtb3ZlIHdhdGNoZG9nIGFjdGlvbnMsIGVycm9yICMiICsgc3RhdHVzKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgUHVsbFdhdGNoZG9nKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICANCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIFNZU1RFTSBERUZFTlNFIFBBTkVMDQogICAgICAgIC8vDQoNCiAgICAgICAgdmFyIHh4U3lzdGVtRGVmZW5zZSA9IG51bGw7DQogICAgICAgIHZhciB4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3kgPSB7fTsNCiAgICAgICAgdmFyIHh4VXBkYXRpbmdEZWZlbnNlU3RhdHMgPSBmYWxzZTsNCiAgICAgICAgdmFyIHh4RmlsdGVyU3RhdGlzdGljcyA9IFt7fSwge31dOyAvLyBXaXJlZCBhbmQgd2lyZWxlc3MgaW50ZXJmYWNlIHN0YXRzDQogICAgICAgIHZhciB4eEZpbHRlclN0YXRpc3RpY3NUaW1lciA9IG51bGw7DQogICAgICAgIHZhciB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9IGZhbHNlOw0KDQogICAgICAgIHZhciB4eFN5c3RlbURlZmVuY2VGaWx0ZXJFdGhlcm5ldFR5cGVzID0geyAyMDQ4OiAnQWxsIElQIFBhY2tldHMnLCAyMDU0OiAnQWxsIEFSUCBQYWNrZXRzJyB9Ow0KICAgICAgICB2YXIgeHhTeXN0ZW1EZWZlbmNlRmlsdGVySVBUeXBlcyA9IHsgNDogJ0lQdjQnLCA2OiAnSVB2NicgfTsNCiAgICAgICAgdmFyIHh4U3lzdGVtRGVmZW5jZUZpbHRlckRlc2MgPSB7IDA6ICdBbGxvdywgQ291bnQnLCAxOiAnRHJvcCwgQ291bnQnLCAyOiAnUmF0ZSBsaW1pdCcsIDM6ICdBbGxvdycsIDQ6ICdEcm9wJyB9Ow0KICAgICAgICB2YXIgeHhTeXN0ZW1EZWZlbmNlRmlsdGVycyA9IHsgJ0hkclByb3RvY29sSUQnOiAxLCAnSGRyRGVzdEFkZHJlc3MnOiAyLCAnSGRyRGVzdE1hc2snOiAyLCAnSGRyU3JjQWRkcmVzcyc6IDIsICdIZHJTcmNNYXNrJzogMiwgJ0hkclNyY1BvcnRTdGFydCc6IDEsICdIZHJTcmNQb3J0RW5kJzogMSwgJ0hkckRlc3RQb3J0U3RhcnQnOiAxLCAnSGRyRGVzdFBvcnRFbmQnOiAxLCAnSGRyU3JjQWRkcmVzc0VuZE9mUmFuZ2UnOiAyLCAnSGRyRGVzdEFkZHJlc3NFbmRPZlJhbmdlICc6IDIsICdUQ1BGbGFnc09uJzogMywgJ1RDUEZsYWdzT2ZmJzogMyB9Ow0KDQogICAgICAgIGZ1bmN0aW9uIFB1bGxTeXN0ZW1EZWZlbnNlKCkgew0KICAgICAgICAgICAgYW10Rmlyc3RQdWxsIHw9IDQ7DQogICAgICAgICAgICBhbXRzdGFjay5CYXRjaEVudW0obnVsbCwgWyJBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSIsICJBTVRfTmV0d29ya1BvcnRTeXN0ZW1EZWZlbnNlUG9saWN5IiwgIkFNVF9IZHI4MDIxRmlsdGVyIiwgIkFNVF9JUEhlYWRlcnNGaWx0ZXIiLCAiQU1UX05ldHdvcmtGaWx0ZXIiXSwgUHVsbFN5c3RlbURlZmVuc2VSZXNwb25zZSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBQdWxsU3lzdGVtRGVmZW5zZVJlc3BvbnNlKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsNCiAgICAgICAgICAgICAgICB4eFN5c3RlbURlZmVuc2UgPSByZXNwb25zZXM7DQogICAgICAgICAgICAgICAgdXBkYXRlU3lzdGVtRGVmZW5zZSgpOw0KICAgICAgICAgICAgICAgIFFWKCdnbzE4JywgdHJ1ZSk7IC8vIFNob3cgU3lzdGVtIERlZmVuc2UgUGFuZWwNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVN5c3RlbURlZmVuc2UoKSB7DQogICAgICAgICAgICBpZiAoeHhTeXN0ZW1EZWZlbnNlID09IG51bGwpIHJldHVybjsNCiAgICAgICAgICAgIHZhciB4ID0gJyc7DQoNCiAgICAgICAgICAgIC8vIEdldCBhY3RpdmUgcG9saWNpZXMNCiAgICAgICAgICAgIHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeSA9IHt9Ow0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFN5c3RlbURlZmVuc2VbJ0FNVF9OZXR3b3JrUG9ydFN5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICB2YXIgbGluayA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX05ldHdvcmtQb3J0U3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICB2YXIgYSA9ICtnZXRJdGVtKGxpbmtbJ0FudGVjZWRlbnQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddLCAnQE5hbWUnLCAnRGV2aWNlSUQnKVsnVmFsdWUnXS5zdWJzdHJpbmcoMjcpOw0KICAgICAgICAgICAgICAgIHZhciBiID0gbGlua1snRGVwZW5kZW50J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVsnVmFsdWUnXTsNCiAgICAgICAgICAgICAgICB2YXIgcCA9IGdldEl0ZW0oeHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlcywgJ0luc3RhbmNlSUQnLCBiKTsNCiAgICAgICAgICAgICAgICB4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3lbYV0gPSBwOw0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBHbG9iYWwgU3lzdGVtIERlZmVuc2Ugc2V0dGluZ3MNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydCgpOw0KICAgICAgICAgICAgdmFyIHBvbGljeW5hbWUgPSAnPGk+Tm9uZTwvaT4nOw0KICAgICAgICAgICAgaWYgKHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeVswXSkgeyBwb2xpY3luYW1lID0geHhTeXN0ZW1EZWZlbmNlTGlua2VkUG9saWN5WzBdWydQb2xpY3lOYW1lJ107IH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiRGVmYXVsdCBXaXJlZCBQb2xpY3kiLCBhZGRMaW5rKHBvbGljeW5hbWUsICdjaGFuZ2VEZWZhdWx0UG9saWN5KDApJykpOw0KICAgICAgICAgICAgLyoNCiAgICAgICAgICAgIHBvbGljeW5hbWUgPSAnPGk+Tm9uZTwvaT4nOw0KICAgICAgICAgICAgaWYgKHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeVsxXSkgeyBwb2xpY3luYW1lID0geHhTeXN0ZW1EZWZlbmNlTGlua2VkUG9saWN5WzFdWydQb2xpY3lOYW1lJ107IH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiRGVmYXVsdCBXaXJlbGVzcyBQb2xpY3kiLCBhZGRMaW5rKHBvbGljeW5hbWUsICdjaGFuZ2VEZWZhdWx0UG9saWN5KDEpJykpOw0KICAgICAgICAgICAgKi8NCg0KICAgICAgICAgICAgLy8gRmlsdGVyIFN0YXRpc3RpY3MNCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjsgaSsrKSB7DQogICAgICAgICAgICAgICAgdmFyIGYgPSB4eEZpbHRlclN0YXRpc3RpY3NbaV07DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaiBpbiBmKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBjID0gZltqXTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT0gMSkgYyArPSAnIHBhY2tldCc7IGVsc2UgYyArPSAnIHBhY2tldHMnOw0KICAgICAgICAgICAgICAgICAgICB2YXIgam4gPSAoKGk9PTApPydXaXJlZCAnOidXaXJlbGVzcyAnKSArIGo7DQogICAgICAgICAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeShqbiwgYyk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KICAgICAgICAgICAgeCArPSAiPGJyPiI7DQoNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg7Ym9yZGVyOjA+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCBzeXN0ZW0gZGVmZW5zZSBwb2xpY2llcy48YnI+PGJyPiI7DQogICAgICAgICAgICBpZiAoeHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlcy5sZW5ndGggPT0gMCkgew0KICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGk+Tm8gc3lzdGVtIGRlZmVuc2UgcG9saWNpZXMgZm91bmQuPC9pPjwvZGl2Pjxicj4iOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4U3lzdGVtRGVmZW5zZVsnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHBvbGljeSA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgICAgIHZhciBkZXNjID0gJyc7DQogICAgICAgICAgICAgICAgICAgIGlmIChwb2xpY3lbJ0ZpbHRlckNyZWF0aW9uSGFuZGxlcyddKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBwb2xpY3lbJ0ZpbHRlckNyZWF0aW9uSGFuZGxlcyddID0gTWFrZVRvQXJyYXkocG9saWN5WydGaWx0ZXJDcmVhdGlvbkhhbmRsZXMnXSk7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IHBvbGljeVsnRmlsdGVyQ3JlYXRpb25IYW5kbGVzJ10ubGVuZ3RoOw0KICAgICAgICAgICAgICAgICAgICAgICAgZGVzYyA9ICcsICcgKyBjICsgJyBmaWx0ZXInICsgKGMgPiAxPydzJzonJyk7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIG9uY2xpY2s9c2hvd1BvbGljeURldGFpbHMoIiArIGkgKyAiKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48Yj4iICsgRXNjYXBlSHRtbChwb2xpY3lbJ1BvbGljeU5hbWUnXSkgKyAiPC9iPiIgKyBkZXNjICsgIjwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICB4ICs9ICI8dHI+PHRkIGNsYXNzPXIxIHN0eWxlPXBhZGRpbmctbGVmdDoxNXB4Pjxicj5NYW5hZ2UgSW50ZWwmcmVnOyBBTVQgc3lzdGVtIGRlZmVuc2UgZmlsdGVycy48YnI+PGJyPiI7DQogICAgICAgICAgICBpZiAoeHhTeXN0ZW1EZWZlbnNlWydBTVRfSGRyODAyMUZpbHRlciddLnJlc3BvbnNlcy5sZW5ndGggPT0gMCAmJiB4eFN5c3RlbURlZmVuc2VbJ0FNVF9JUEhlYWRlcnNGaWx0ZXInXS5yZXNwb25zZXMubGVuZ3RoID09IDApIHsNCiAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPXBhZGRpbmctbGVmdDoxNXB4PjxpPk5vIHN5c3RlbSBkZWZlbnNlIGZpbHRlcnMgZm91bmQuPC9pPjwvZGl2Pjxicj4iOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4U3lzdGVtRGVmZW5zZVsnQU1UX0hkcjgwMjFGaWx0ZXInXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0hkcjgwMjFGaWx0ZXInXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgICAgIHZhciBkZXNjID0geHhTeXN0ZW1EZWZlbmNlRmlsdGVyRXRoZXJuZXRUeXBlc1tmaWx0ZXJbJ0hkclByb3RvY29sSUQ4MDIxJ11dOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIWRlc2MpIGRlc2MgPSAnQWxsIEV0aGVybmV0IFByb3RvY29sICcgKyBmaWx0ZXJbJ0hkclByb3RvY29sSUQ4MDIxJ107DQogICAgICAgICAgICAgICAgICAgIGRlc2MgKz0gJywgJyArIHh4U3lzdGVtRGVmZW5jZUZpbHRlckRlc2NbZmlsdGVyWydGaWx0ZXJQcm9maWxlJ11dOw0KICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyWydGaWx0ZXJQcm9maWxlJ10gPT0gMikgeyBkZXNjICs9ICIgYXQgIiArIGZpbHRlclsnRmlsdGVyUHJvZmlsZURhdGEnXSArICIgcGFja2V0IC8gc2VjIjsgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyWydBY3Rpb25FdmVudE9uTWF0Y2gnXSA9PSB0cnVlKSBkZXNjICs9ICcsIEV2ZW50IG9uIG1hdGNoJzsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIG9uY2xpY2s9c2hvd0ZpbHRlckRldGFpbHMoMCwiICsgaSArICIpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyAoZmlsdGVyWydGaWx0ZXJEaXJlY3Rpb24nXSA9PSAwID8gJyYjODU5MjsgJyA6ICcmIzg1OTQ7ICcpICsgRXNjYXBlSHRtbChmaWx0ZXJbIk5hbWUiXSkgKyAiPC9iPiwgIiArIGRlc2MgKyAiPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFN5c3RlbURlZmVuc2VbJ0FNVF9JUEhlYWRlcnNGaWx0ZXInXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0lQSGVhZGVyc0ZpbHRlciddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGRlc2MgPSB4eFN5c3RlbURlZmVuY2VGaWx0ZXJJUFR5cGVzW2ZpbHRlclsnSGRySVBWZXJzaW9uJ11dOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIWRlc2MpIGRlc2MgPSAnQWxsIEV0aGVybmV0IFByb3RvY29sICcgKyBmaWx0ZXJbJ0hkcklQVmVyc2lvbiddOw0KICAgICAgICAgICAgICAgICAgICBkZXNjICs9ICcsICcgKyB4eFN5c3RlbURlZmVuY2VGaWx0ZXJEZXNjW2ZpbHRlclsnRmlsdGVyUHJvZmlsZSddXTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlclsnRmlsdGVyUHJvZmlsZSddID09IDIpIHsgZGVzYyArPSAiIGF0ICIgKyBmaWx0ZXJbJ0ZpbHRlclByb2ZpbGVEYXRhJ10gKyAiIHBhY2tldCAvIHNlYyI7IH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlclsnQWN0aW9uRXZlbnRPbk1hdGNoJ10gPT0gdHJ1ZSkgZGVzYyArPSAnLCBFdmVudCBvbiBtYXRjaCc7DQogICAgICAgICAgICAgICAgICAgIHZhciBmaWx0ZXJjb3VudCA9IDA7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4geHhTeXN0ZW1EZWZlbmNlRmlsdGVycykgeyBpZiAoZmlsdGVyW2pdKSBmaWx0ZXJjb3VudCsrOyB9DQogICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXJjb3VudCA+IDApIGRlc2MgKz0gJywgJyArIGZpbHRlcmNvdW50ICsgJyBmaWx0ZXInICsgKGZpbHRlcmNvdW50PjE/J3MnOicnKTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIG9uY2xpY2s9c2hvd0ZpbHRlckRldGFpbHMoMSwiICsgaSArICIpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyAoZmlsdGVyWydGaWx0ZXJEaXJlY3Rpb24nXSA9PSAwID8gJyYjODU5MjsgJyA6ICcmIzg1OTQ7ICcpICsgRXNjYXBlSHRtbChmaWx0ZXJbIk5hbWUiXSkgKyAiPC9iPiwgIiArIGRlc2MgKyAiPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICB4ICs9ICI8YnI+PHRkIGNsYXNzPXIxPiIgKyBUYWJsZUVuZChBZGRSZWZyZXNoQnV0dG9uKCJQdWxsU3lzdGVtRGVmZW5zZSgpIikgKyAvKkFkZEJ1dHRvbigiVXBkYXRlIFN0YXRzIiwgIlVwZGF0ZURlZmVuc2VTdGF0cygpIikgKyovIEFkZEJ1dHRvbigiQWRkIEZpbHRlci4uLiIsICJBZGREZWZlbnNlRmlsdGVyKCkiKSArIEFkZEJ1dHRvbigiQWRkIFBvbGljeS4uLiIsICJBZGREZWZlbnNlUG9saWN5KCkiKSk7DQoNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVN5c3RlbURlZmVuc2UnLCB4KTsNCg0KICAgICAgICAgICAgaWYgKHh4RmlsdGVyU3RhdGlzdGljc1RpbWVyID09IG51bGwpIHsNCiAgICAgICAgICAgICAgICBVcGRhdGVEZWZlbnNlU3RhdHMoKTsNCiAgICAgICAgICAgICAgICB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9IGZhbHNlOw0KICAgICAgICAgICAgICAgIGlmICghdXJsdmFyc1snbm9yZWZyZXNoJ10pIHsgeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXIgPSBzZXRJbnRlcnZhbChVcGRhdGVEZWZlbnNlU3RhdHMsIDUwMDApOyB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBTdG9wRGVmZW5zZVN0YXRzVGltZXIoKSB7DQogICAgICAgICAgICBpZiAoeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXIgIT0gbnVsbCkgeyBjbGVhckludGVydmFsKHh4RmlsdGVyU3RhdGlzdGljc1RpbWVyKTsgeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXIgPSBudWxsOyB9DQogICAgICAgICAgICB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9IGZhbHNlOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gVXBkYXRlRGVmZW5zZVN0YXRzKG4pIHsNCiAgICAgICAgICAgIGlmICghbiAmJiB4eEZpbHRlclN0YXRpc3RpY3NUaW1lckFjdGl2ZSA9PSB0cnVlKSB7IHJldHVybjsgfQ0KICAgICAgICAgICAgeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXJBY3RpdmUgPSB0cnVlOw0KICAgICAgICAgICAgdmFyIG5ldHdvcmsgPSBuP246MDsNCiAgICAgICAgICAgIGlmICh4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3lbbmV0d29ya10pIHsNCiAgICAgICAgICAgICAgICB2YXIgZXJlZiA9ICc8YTpBZGRyZXNzPjwvYTpBZGRyZXNzPjxhOlJlZmVyZW5jZVBhcmFtZXRlcnM+PHc6UmVzb3VyY2VVUkk+aHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NpbS1zY2hlbWEvMi9DSU1fRXRoZXJuZXRQb3J0PC93OlJlc291cmNlVVJJPjx3OlNlbGVjdG9yU2V0Pjx3OlNlbGVjdG9yIE5hbWU9IkRldmljZUlEIj5JbnRlbChyKSBBTVQgRXRoZXJuZXQgUG9ydCAnICsgbmV0d29yayArICc8L3c6U2VsZWN0b3I+PC93OlNlbGVjdG9yU2V0PjwvYTpSZWZlcmVuY2VQYXJhbWV0ZXJzPic7DQogICAgICAgICAgICAgICAgYW10c3RhY2suQU1UX1N5c3RlbURlZmVuc2VQb2xpY3lfVXBkYXRlU3RhdGlzdGljcyhlcmVmLCBmYWxzZSwgVXBkYXRlRGVmZW5zZVN0YXRzMiwgbmV0d29yaywgMCwgeyAnSW5zdGFuY2VJRCc6IHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeVtuZXR3b3JrXVsnSW5zdGFuY2VJRCddIH0pOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAvLyBObyBhY3RpdmUgcG9saWN5LCBzdG9wIHRoZSB0aW1lcg0KICAgICAgICAgICAgICAgIHh4RmlsdGVyU3RhdGlzdGljc1tuZXR3b3JrXSA9IHt9Ow0KICAgICAgICAgICAgICAgIHVwZGF0ZVN5c3RlbURlZmVuc2UoKTsNCiAgICAgICAgICAgICAgICBTdG9wRGVmZW5zZVN0YXRzVGltZXIoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIFVwZGF0ZURlZmVuc2VTdGF0czIoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzLCBuZXR3b3JrKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgew0KICAgICAgICAgICAgICAgIGFtdHN0YWNrLkVudW0oJ0FNVF9BY3RpdmVGaWx0ZXJTdGF0aXN0aWNzJywgVXBkYXRlRGVmZW5zZVN0YXRzMywgbmV0d29yayk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFN0b3BEZWZlbnNlU3RhdHNUaW1lcigpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gVXBkYXRlRGVmZW5zZVN0YXRzMyhzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMsIG5ldHdvcmspIHsNCiAgICAgICAgICAgIHZhciBjb3VudCA9IDA7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgew0KICAgICAgICAgICAgICAgIHh4RmlsdGVyU3RhdGlzdGljc1tuZXR3b3JrXSA9IHt9Ow0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gcmVzcG9uc2VzKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciByZWFkY291bnQgPSByZXNwb25zZXNbaV1bJ1JlYWRDb3VudCddOw0KICAgICAgICAgICAgICAgICAgICAvLyB2YXIgbWF0Y2hlZCA9IHJlc3BvbnNlc1tpXVsnRmlsdGVyTWF0Y2hlZCddOw0KICAgICAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IGdldEl0ZW0ocmVzcG9uc2VzW2ldWydEZXBlbmRlbnQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWzFdWydWYWx1ZSddWydFbmRwb2ludFJlZmVyZW5jZSddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10sICdATmFtZScsICdOYW1lJylbJ1ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgIHh4RmlsdGVyU3RhdGlzdGljc1tuZXR3b3JrXVtuYW1lXSA9IHJlYWRjb3VudDsNCiAgICAgICAgICAgICAgICAgICAgY291bnQrKzsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgdXBkYXRlU3lzdGVtRGVmZW5zZSgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeHhGaWx0ZXJTdGF0aXN0aWNzVGltZXJBY3RpdmUgPSBmYWxzZTsNCiAgICAgICAgICAgIC8vIElmIHRoZXJlIGlzIG5vIHN0YXRpc3RpY3MsIHN0b3AgdGhlIHRpbWVyDQogICAgICAgICAgICBpZiAoY291bnQgPT0gMCkgeyBTdG9wRGVmZW5zZVN0YXRzVGltZXIoKTsgfSAvLyBUT0RPOiBDaGFuZ2UgdGhpcyB0byBhbGxvdyBmb3Igd2lyZWxlc3MNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGNoYW5nZURlZmF1bHRQb2xpY3kobmV0d29yaykgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PHNlbGVjdCBpZD1wb2xpY3lTZWxlY3Rpb24gc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjY2cHg+PG9wdGlvbiB2YWx1ZT0tMT5Ob25lIjsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlcykgeyB4ICs9ICI8b3B0aW9uIHZhbHVlPSIgKyBpICsgKCh4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3lbbmV0d29ya10gJiYgeHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlc1tpXVsnSW5zdGFuY2VJRCddID09IHh4U3lzdGVtRGVmZW5jZUxpbmtlZFBvbGljeVtuZXR3b3JrXVsnSW5zdGFuY2VJRCddKSA/ICcgc2VsZWN0ZWQnIDogJycpICsgIj4iICsgeHhTeXN0ZW1EZWZlbnNlWydBTVRfU3lzdGVtRGVmZW5zZVBvbGljeSddLnJlc3BvbnNlc1tpXVsnUG9saWN5TmFtZSddOyB9DQogICAgICAgICAgICB4ICs9ICI8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5EZWZhdWx0IFBvbGljeTwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnRGVmYXVsdCBTeXN0ZW0gRGVmZW5zZSBQb2xpY3knLCAzLCBjaGFuZ2VEZWZhdWx0UG9saWN5T2ssIHgsIG5ldHdvcmspOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2hhbmdlRGVmYXVsdFBvbGljeU9rKGJ1dHRvbiwgbmV0d29yaykgew0KICAgICAgICAgICAgdmFyIGkgPSBRKCdwb2xpY3lTZWxlY3Rpb24nKS52YWx1ZTsNCiAgICAgICAgICAgIHZhciBvbGRwb2xpY3kgPSB4eFN5c3RlbURlZmVuY2VMaW5rZWRQb2xpY3lbbmV0d29ya107DQogICAgICAgICAgICBpZiAob2xkcG9saWN5KSB7IGFtdHN0YWNrLkRlbGV0ZSgnQU1UX05ldHdvcmtQb3J0U3lzdGVtRGVmZW5zZVBvbGljeScsICc8dzpTZWxlY3RvclNldD48dzpTZWxlY3RvciBOYW1lPSJBbnRlY2VkZW50Ij48YTpFbmRwb2ludFJlZmVyZW5jZSB4bWxuczpiPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciIHhtbG5zOmM9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiPjxhOkFkZHJlc3M+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL3JvbGUvYW5vbnltb3VzPC9hOkFkZHJlc3M+PGE6UmVmZXJlbmNlUGFyYW1ldGVycz48dzpSZXNvdXJjZVVSST5odHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY2ltLXNjaGVtYS8yL0NJTV9FdGhlcm5ldFBvcnQ8L3c6UmVzb3VyY2VVUkk+PHc6U2VsZWN0b3JTZXQ+PHc6U2VsZWN0b3IgTmFtZT0iQ3JlYXRpb25DbGFzc05hbWUiPkNJTV9FdGhlcm5ldFBvcnQ8L3c6U2VsZWN0b3I+PHc6U2VsZWN0b3IgTmFtZT0iRGV2aWNlSUQiPkludGVsKHIpIEFNVCBFdGhlcm5ldCBQb3J0ICcgKyBuZXR3b3JrICsgJzwvdzpTZWxlY3Rvcj48L3c6U2VsZWN0b3JTZXQ+PC9hOlJlZmVyZW5jZVBhcmFtZXRlcnM+PC9hOkVuZHBvaW50UmVmZXJlbmNlPjwvdzpTZWxlY3Rvcj48dzpTZWxlY3RvciBOYW1lPSJEZXBlbmRlbnQiPjxhOkVuZHBvaW50UmVmZXJlbmNlIHhtbG5zOmI9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyIgeG1sbnM6Yz0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZCI+PGE6QWRkcmVzcz5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L2E6QWRkcmVzcz48YTpSZWZlcmVuY2VQYXJhbWV0ZXJzPjx3OlJlc291cmNlVVJJPmh0dHA6Ly9pbnRlbC5jb20vd2JlbS93c2NpbS8xL2FtdC1zY2hlbWEvMS9BTVRfU3lzdGVtRGVmZW5zZVBvbGljeTwvdzpSZXNvdXJjZVVSST48dzpTZWxlY3RvclNldD48dzpTZWxlY3RvciBOYW1lPSJJbnN0YW5jZUlEIj4nICsgb2xkcG9saWN5WydJbnN0YW5jZUlEJ10gKyAnPC93OlNlbGVjdG9yPjwvdzpTZWxlY3RvclNldD48L2E6UmVmZXJlbmNlUGFyYW1ldGVycz48L2E6RW5kcG9pbnRSZWZlcmVuY2U+PC93OlNlbGVjdG9yPjwvdzpTZWxlY3RvclNldD4nLCAoKGkgPT0gLTEpID8gUHVsbFN5c3RlbURlZmVuc2UgOiBmdW5jdGlvbiAoKSB7IH0pKTsgfQ0KDQogICAgICAgICAgICBpZiAoaSA+PSAwKSB7DQogICAgICAgICAgICAgICAgdmFyIHBvbGljeSA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgdmFyIGVyZWYgPSAnPEFkZHJlc3MgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyI+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nPC9BZGRyZXNzPjxSZWZlcmVuY2VQYXJhbWV0ZXJzIHhtbG5zPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciPjxSZXNvdXJjZVVSSSB4bWxucz0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZCI+aHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NpbS1zY2hlbWEvMi9DSU1fRXRoZXJuZXRQb3J0PC9SZXNvdXJjZVVSST48U2VsZWN0b3JTZXQgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiPjxTZWxlY3RvciBOYW1lPSJEZXZpY2VJRCI+SW50ZWwocikgQU1UIEV0aGVybmV0IFBvcnQgJyArIG5ldHdvcmsgKyAnPC9TZWxlY3Rvcj48L1NlbGVjdG9yU2V0PjwvUmVmZXJlbmNlUGFyYW1ldGVycz4nOw0KICAgICAgICAgICAgICAgIHZhciBwcmVmID0gJzxBZGRyZXNzIHhtbG5zPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciPmh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZzwvQWRkcmVzcz48UmVmZXJlbmNlUGFyYW1ldGVycyB4bWxucz0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nIj48UmVzb3VyY2VVUkkgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiPmh0dHA6Ly9pbnRlbC5jb20vd2JlbS93c2NpbS8xL2FtdC1zY2hlbWEvMS9BTVRfU3lzdGVtRGVmZW5zZVBvbGljeTwvUmVzb3VyY2VVUkk+PFNlbGVjdG9yU2V0IHhtbG5zPSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIj48U2VsZWN0b3IgTmFtZT0iSW5zdGFuY2VJRCI+JyArIHBvbGljeVsnSW5zdGFuY2VJRCddICsgJzwvU2VsZWN0b3I+PC9TZWxlY3RvclNldD48L1JlZmVyZW5jZVBhcmFtZXRlcnM+JzsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5DcmVhdGUoJ0FNVF9OZXR3b3JrUG9ydFN5c3RlbURlZmVuc2VQb2xpY3knLCB7ICdBbnRlY2VkZW50JzogZXJlZiwgJ0RlcGVuZGVudCc6IHByZWYgfSwgY2hhbmdlRGVmYXVsdFBvbGljeU9rMik7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBjaGFuZ2VEZWZhdWx0UG9saWN5T2syKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdEZWZhdWx0IFN5c3RlbSBEZWZlbnNlIFBvbGljeScsICJVbmFibGUgdG8gc2V0IHBvbGljeSwgZXJyb3IgIiArIHN0YXR1cyk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFB1bGxTeXN0ZW1EZWZlbnNlKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGREZWZlbnNlRmlsdGVyKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPWZpbHRlcm5hbWUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHggbWF4bGVuZ3RoPTE2IG9ua2V5dXA9QWRkRGVmZW5zZUZpbHRlclVwZGF0ZSgpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4Pk5hbWU8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48c2VsZWN0IGlkPWZpbHRlcnR5cGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjY2cHggb25jaGFuZ2U9QWRkRGVmZW5zZUZpbHRlclVwZGF0ZSgpPjxvcHRpb24gdmFsdWU9MD5FdGhlcm5ldCBJUCBQYWNrZXQgRmlsdGVyPG9wdGlvbiB2YWx1ZT0xPkV0aGVybmV0IEFSUCBQYWNrZXQgRmlsdGVyPG9wdGlvbiB2YWx1ZT0yPklQdjQgUGFja2V0IEZpbHRlcjxvcHRpb24gdmFsdWU9Mz5JUHY2IFBhY2tldCBGaWx0ZXI8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5UeXBlPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHggaWQ9aXBmaWx0ZXJkaXY+PGlucHV0IGlkPWlwZmlsdGVyIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IHBsYWNlaG9sZGVyPVwiT3B0aW9uYWwgUnVsZXNcIiBvbmtleXVwPUFkZERlZmVuc2VGaWx0ZXJVcGRhdGUoKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5NYXRjaGluZyBSdWxlczwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9ZmlsdGVyZGlyIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2NnB4IG9uY2hhbmdlPUFkZERlZmVuc2VGaWx0ZXJVcGRhdGUoKT48b3B0aW9uIHZhbHVlPTA+T3V0Ym91bmQgLyBUcmFuc21pdDxvcHRpb24gdmFsdWU9MT5JbmJvdW5kIC8gUmVjZWl2ZTwvc2VsZWN0PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PkRpcmVjdGlvbjwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICB4ICs9ICI8ZGl2IHN0eWxlPWhlaWdodDoyNnB4O21hcmdpbi10b3A6NHB4PjxzZWxlY3QgaWQ9ZmlsdGVycHJvZmlsZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjZweCBvbmNoYW5nZT1BZGREZWZlbnNlRmlsdGVyVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0wPkFsbG93LCBDb3VudDxvcHRpb24gdmFsdWU9MT5Ecm9wLCBDb3VudDxvcHRpb24gdmFsdWU9Mj5SYXRlIExpbWl0PG9wdGlvbiB2YWx1ZT0zPkFsbG93PG9wdGlvbiB2YWx1ZT00PkRyb3A8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5BY3Rpb248L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweCBpZD1maWx0ZXJkYXRhZGl2PjxpbnB1dCBpZD1maWx0ZXJkYXRhIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG1heGxlbmd0aD04IG9ua2V5dXA9QWRkRGVmZW5zZUZpbHRlclVwZGF0ZSgpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PlBhY2tldHMgLyBzZWNvbmQ8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48c2VsZWN0IGlkPWZpbHRlcmFjdGlvbiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjZweCBvbmNoYW5nZT1BZGREZWZlbnNlRmlsdGVyVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT1mYWxzZT5EbyBOb3RoaW5nPG9wdGlvbiB2YWx1ZT0xPkV2ZW50IG9uIG1hdGNoPC9zZWxlY3Q+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDo0cHg+RXZlbnQgTG9nPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdBZGQgU3lzdGVtIERlZmVuc2UgRmlsdGVyJywgMywgQWRkRGVmZW5zZUZpbHRlck9rLCB4KTsNCiAgICAgICAgICAgIEFkZERlZmVuc2VGaWx0ZXJVcGRhdGUoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZERlZmVuc2VGaWx0ZXJPaygpIHsNCiAgICAgICAgICAgIGlmIChRKCdmaWx0ZXJ0eXBlJykudmFsdWUgPD0gMSkgew0KICAgICAgICAgICAgICAgIC8vIEFkZCBFdGhlcm5ldCBJUCBvciBBUlAgZmlsdGVyDQogICAgICAgICAgICAgICAgdmFyIHByb3RvY29sID0gKFEoJ2ZpbHRlcnR5cGUnKS52YWx1ZSA9PSAwKSA/IDIwNDggOiAyMDU0OyAvLyBJUCA6IEFSUA0KICAgICAgICAgICAgICAgIHZhciBmaWx0ZXIgPSB7ICdJbnN0YW5jZUlEICc6IDAsICdOYW1lJzogUSgnZmlsdGVybmFtZScpLnZhbHVlLCAnQ3JlYXRpb25DbGFzc05hbWUnOiAwLCAnU3lzdGVtTmFtZSc6IDAsICdTeXN0ZW1DcmVhdGlvbkNsYXNzTmFtZSc6IDAsICdIZHJQcm90b2NvbElEODAyMSc6IHByb3RvY29sLCAnRmlsdGVyUHJvZmlsZSc6IFEoJ2ZpbHRlcnByb2ZpbGUnKS52YWx1ZSwgJ0ZpbHRlckRpcmVjdGlvbic6IFEoJ2ZpbHRlcmRpcicpLnZhbHVlLCAnQWN0aW9uRXZlbnRPbk1hdGNoJzogUSgnZmlsdGVyYWN0aW9uJykudmFsdWUgfTsNCiAgICAgICAgICAgICAgICBpZiAoUSgnZmlsdGVycHJvZmlsZScpLnZhbHVlID09IDIpIGZpbHRlclsnRmlsdGVyUHJvZmlsZURhdGEnXSA9IFEoJ2ZpbHRlcmRhdGEnKS52YWx1ZTsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5DcmVhdGUoJ0FNVF9IZHI4MDIxRmlsdGVyJywgZmlsdGVyLCBBZGREZWZlbnNlRmlsdGVyT2syKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gQWRkIElQdjQgb3IgSVB2NiBGaWx0ZXINCiAgICAgICAgICAgICAgICB2YXIgcHJvdG9jb2wgPSAoUSgnZmlsdGVydHlwZScpLnZhbHVlID09IDIpID8gNCA6IDY7IC8vIElQdjQgOiBJUHY2DQogICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHsgJ0luc3RhbmNlSUQgJzogMCwgJ05hbWUnOiBRKCdmaWx0ZXJuYW1lJykudmFsdWUsICdDcmVhdGlvbkNsYXNzTmFtZSc6IDAsICdTeXN0ZW1OYW1lJzogMCwgJ1N5c3RlbUNyZWF0aW9uQ2xhc3NOYW1lJzogMCwgJ0hkcklQVmVyc2lvbic6IHByb3RvY29sLCAnRmlsdGVyUHJvZmlsZSc6IFEoJ2ZpbHRlcnByb2ZpbGUnKS52YWx1ZSwgJ0ZpbHRlckRpcmVjdGlvbic6IFEoJ2ZpbHRlcmRpcicpLnZhbHVlLCAnQWN0aW9uRXZlbnRPbk1hdGNoJzogUSgnZmlsdGVyYWN0aW9uJykudmFsdWUgfTsNCg0KICAgICAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBmaWx0ZXIgc3RyaW5nDQogICAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9zb2Z0d2FyZS5pbnRlbC5jb20vc2l0ZXMvbWFuYWdlYWJpbGl0eS9BTVRfSW1wbGVtZW50YXRpb25fYW5kX1JlZmVyZW5jZV9HdWlkZS9kZWZhdWx0Lmh0bT90dXJsPUhUTUxEb2N1bWVudHMlMkZXUy1NYW5hZ2VtZW50X0NsYXNzX1JlZmVyZW5jZSUyRkFNVF9IZHI4MDIxRmlsdGVyLmh0bQ0KICAgICAgICAgICAgICAgIHZhciBmaWx0ZXJzdHJzID0gUSgnaXBmaWx0ZXInKS52YWx1ZS5zcGxpdCgnLCcpOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gZmlsdGVyc3Rycykgew0KICAgICAgICAgICAgICAgICAgICB2YXIgeHggPSBmaWx0ZXJzdHJzW2ldLmluZGV4T2YoJz0nKTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIG4gPSBmaWx0ZXJzdHJzW2ldLnN1YnN0cmluZygwLCB4eCk7DQogICAgICAgICAgICAgICAgICAgIHZhciB2ID0gZmlsdGVyc3Ryc1tpXS5zdWJzdHJpbmcoeHggKyAxKTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHQgPSB4eFN5c3RlbURlZmVuY2VGaWx0ZXJzW25dOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIXQpIHsgbiA9ICJIZHIiICsgbjsgdCA9IHh4U3lzdGVtRGVmZW5jZUZpbHRlcnNbbl07IH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKHQpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE86IFBhcnNlIHYgKHRoZSB2YWx1ZSkgYmFzZWQgb24gdGhlIHR5cGUgdC4NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0ID09IDIgJiYgcHJvdG9jb2wgPT0gNCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElQdjQgYWRkcmVzcw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpcHNwbGl0ID0gdi5zcGxpdCgnLicpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpcHNwbGl0Lmxlbmd0aCA9PSA0KSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmlsdGVyW25dID0gYnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KGlwc3BsaXRbMF0pLCBwYXJzZUludChpcHNwbGl0WzFdKSwgcGFyc2VJbnQoaXBzcGxpdFsyXSksIHBhcnNlSW50KGlwc3BsaXRbM10pKSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vZmlsdGVyW25dID0gWyBwYXJzZUludChpcHNwbGl0WzBdKSwgcGFyc2VJbnQoaXBzcGxpdFsxXSksIHBhcnNlSW50KGlwc3BsaXRbMl0pLCBwYXJzZUludChpcHNwbGl0WzNdKSBdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJbbl0gPSByc3RyMmhleChTdHJpbmcuZnJvbUNoYXJDb2RlKHBhcnNlSW50KGlwc3BsaXRbMF0pLCBwYXJzZUludChpcHNwbGl0WzFdKSwgcGFyc2VJbnQoaXBzcGxpdFsyXSksIHBhcnNlSW50KGlwc3BsaXRbM10pKSk7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPdGhlciB2YWx1ZXMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJbbl0gPSB2Ow0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgaWYgKFEoJ2ZpbHRlcnByb2ZpbGUnKS52YWx1ZSA9PSAyKSBmaWx0ZXJbJ0ZpbHRlclByb2ZpbGVEYXRhJ10gPSBRKCdmaWx0ZXJkYXRhJykudmFsdWU7DQogICAgICAgICAgICAgICAgYW10c3RhY2suQ3JlYXRlKCdBTVRfSVBIZWFkZXJzRmlsdGVyJywgZmlsdGVyLCBBZGREZWZlbnNlRmlsdGVyT2syKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZERlZmVuc2VGaWx0ZXJVcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgb2sgPSBRKCdmaWx0ZXJuYW1lJykudmFsdWUubGVuZ3RoID4gMDsNCiAgICAgICAgICAgIGlmIChvayAmJiBRKCdmaWx0ZXJwcm9maWxlJykudmFsdWUgPT0gMikgeyB2YXIgaSA9IHBhcnNlSW50KFEoJ2ZpbHRlcmRhdGEnKS52YWx1ZSk7IG9rID0gKGkgPiAwICYmIGkgPCAweEZGRkZGRkZGKTsgfQ0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgICAgIFFWKCdmaWx0ZXJkYXRhZGl2JywgUSgnZmlsdGVycHJvZmlsZScpLnZhbHVlID09IDIpOw0KICAgICAgICAgICAgUVYoJ2lwZmlsdGVyZGl2JywgUSgnZmlsdGVydHlwZScpLnZhbHVlID49IDIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkRGVmZW5zZUZpbHRlck9rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnQWRkIFN5c3RlbSBEZWZlbnNlIEZpbHRlcicsICJVbmFibGUgdG8gYWRkIGZpbHRlciwgZXJyb3IgIyIgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsU3lzdGVtRGVmZW5zZSgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0ZpbHRlckRldGFpbHModCwgaSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIGRlc2MsIGZpbHRlciwgdHlwZSwgdG47DQogICAgICAgICAgICBpZiAodCA9PSAwKSB7DQogICAgICAgICAgICAgICAgdG4gPSAnQU1UX0hkcjgwMjFGaWx0ZXInOw0KICAgICAgICAgICAgICAgIHR5cGUgPSAnRXRoZXJuZXQgVHJhZmZpYyc7DQogICAgICAgICAgICAgICAgZmlsdGVyID0geHhTeXN0ZW1EZWZlbnNlW3RuXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgZGVzYyA9IHh4U3lzdGVtRGVmZW5jZUZpbHRlckV0aGVybmV0VHlwZXNbZmlsdGVyWydIZHJQcm90b2NvbElEODAyMSddXTsNCiAgICAgICAgICAgICAgICBpZiAoIWRlc2MpIGRlc2MgPSAnQWxsIEV0aGVybmV0IFByb3RvY29sICcgKyBmaWx0ZXJbJ0hkclByb3RvY29sSUQ4MDIxJ107DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHRuID0gJ0FNVF9JUEhlYWRlcnNGaWx0ZXInOw0KICAgICAgICAgICAgICAgIHR5cGUgPSAnSVAgVHJhZmZpYyc7DQogICAgICAgICAgICAgICAgZmlsdGVyID0geHhTeXN0ZW1EZWZlbnNlW3RuXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgZGVzYyA9IHh4U3lzdGVtRGVmZW5jZUZpbHRlcklQVHlwZXNbZmlsdGVyWydIZHJJUFZlcnNpb24nXV07DQogICAgICAgICAgICAgICAgaWYgKCFkZXNjKSBkZXNjID0gJ0FsbCBJUCBQcm90b2NvbCAnICsgZmlsdGVyWydIZHJJUFZlcnNpb24nXTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHZhciB4ID0gJyc7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnTmFtZScsIEVzY2FwZUh0bWwoZmlsdGVyWyJOYW1lIl0pKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdUeXBlJywgdHlwZSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnTWF0Y2hpbmcgVHJhZmZpYycsIGRlc2MpOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ0RpcmVjdGlvbicsIGZpbHRlclsnRmlsdGVyRGlyZWN0aW9uJ10gPT0gMCA/ICdPdXRib3VuZCAvIFRyYW5zbWl0JyA6ICdJbmJvdW5kIC8gUmVjZWl2ZScpOw0KICAgICAgICAgICAgaWYgKHQgPT0gMSkgew0KICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4geHhTeXN0ZW1EZWZlbmNlRmlsdGVycykgew0KICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyW2pdKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbiA9IGosIHYgPSBmaWx0ZXJbal0sIHQgPSB4eFN5c3RlbURlZmVuY2VGaWx0ZXJzW2pdOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHQgPT0gMiAmJiB2Lmxlbmd0aCA9PSA0KSB7IHYgPSBoZXgycnN0cih2KTsgdiA9IHYuY2hhckNvZGVBdCgwKSArICcuJyArIHYuY2hhckNvZGVBdCgxKSArICcuJyArIHYuY2hhckNvZGVBdCgyKSArICcuJyArIHYuY2hhckNvZGVBdCgzKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG4uc3RhcnRzV2l0aCgnSGRyJykpIG4gPSBuLnN1YnN0cmluZygzKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdGaWx0ZXIgJyArIG4sIHYpOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ0V2ZW50IG9uIG1hdGNoJywgKGZpbHRlclsnQWN0aW9uRXZlbnRPbk1hdGNoJ10gPT0gdHJ1ZSkgPyAnWWVzJyA6ICdObycpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ0V0aGVybmV0IEZpbHRlciAjJyArIGZpbHRlclsnSW5zdGFuY2VJRCddLCA1LCBzaG93RmlsdGVyRGV0YWlsc09rLCB4LCBbdG4sIGZpbHRlcl0pOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0ZpbHRlckRldGFpbHNPayhiLCB0YWcpIHsNCiAgICAgICAgICAgIGlmIChiID09IDIpIHsgYW10c3RhY2suRGVsZXRlKHRhZ1swXSwgdGFnWzFdLCBkZWxldGVEZWZlbnNlRmlsdGVyKTsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGVsZXRlRGVmZW5zZUZpbHRlcihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnUmVtb3ZlIEZpbHRlcicsICJVbmFibGUgdG8gcmVtb3ZlIGZpbHRlciwgbWFrZSBzdXJlIGl0J3Mgbm90IGluIHVzZS4iKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgUHVsbFN5c3RlbURlZmVuc2UoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIHZhciB4eEFkZERlZmVuc2VQb2xpY3lGaWx0ZXJzOw0KICAgICAgICBmdW5jdGlvbiBBZGREZWZlbnNlUG9saWN5KCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgeHhBZGREZWZlbnNlUG9saWN5RmlsdGVycyA9IFtdOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PGlucHV0IGlkPXBvbGljeW5hbWUgdGl0bGU9Jzxwb2xpY3kgbmFtZT46PHBvbGljeSBwcmVjZWRlbmNlIG51bWJlcj4nIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG1heGxlbmd0aD0xNiBvbmtleXVwPUFkZERlZmVuc2VQb2xpY3lVcGRhdGUoKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5OYW1lPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg7bWFyZ2luLXRvcDo0cHg+PHNlbGVjdCBpZD1wb2xpY3l0eCB0aXRsZT0nRGVmYXVsdCBhY3Rpb24gdG8gdGFrZSBmb3Igb3V0Ym91bmQgdHJhZmZpYycgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MTMzcHg+PG9wdGlvbiB2YWx1ZT0wPkFsbG93PG9wdGlvbiB2YWx1ZT0xPkRyb3A8b3B0aW9uIHZhbHVlPTI+QWxsb3csQ291bnQ8b3B0aW9uIHZhbHVlPTM+RHJvcCxDb3VudDxvcHRpb24gdmFsdWU9ND5BbGxvdyxDb3VudCxFdmVudDxvcHRpb24gdmFsdWU9NT5Ecm9wLENvdW50LEV2ZW50PC9zZWxlY3Q+PHNlbGVjdCBpZD1wb2xpY3lyeCBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoxMzNweCB0aXRsZT0nRGVmYXVsdCBhY3Rpb24gdG8gdGFrZSBmb3IgaW5ib3VuZCB0cmFmZmljJz48b3B0aW9uIHZhbHVlPTA+QWxsb3c8b3B0aW9uIHZhbHVlPTE+RHJvcDxvcHRpb24gdmFsdWU9Mj5BbGxvdyxDb3VudDxvcHRpb24gdmFsdWU9Mz5Ecm9wLENvdW50PG9wdGlvbiB2YWx1ZT00PkFsbG93LENvdW50LEV2ZW50PG9wdGlvbiB2YWx1ZT01PkRyb3AsQ291bnQsRXZlbnQ8L3NlbGVjdD48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjRweD5EZWZhdWx0IFRYIC8gUlg8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBpZD1wb2xpY3lGaWx0ZXJzPjwvZGl2PiI7DQogICAgICAgICAgICBpZiAoeHhTeXN0ZW1EZWZlbnNlWydBTVRfSGRyODAyMUZpbHRlciddLnJlc3BvbnNlcy5sZW5ndGggPiAwIHx8IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0lQSGVhZGVyc0ZpbHRlciddLnJlc3BvbnNlcy5sZW5ndGggPiAwKSB7DQogICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6MjZweDttYXJnaW4tdG9wOjRweD48ZGl2IHN0eWxlPWZsb2F0OnJpZ2h0PjxzZWxlY3QgaWQ9eGZpbHRlciBzdHlsZT13aWR0aDoxODZweD4iOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhTeXN0ZW1EZWZlbnNlWydBTVRfSGRyODAyMUZpbHRlciddLnJlc3BvbnNlcykgew0KICAgICAgICAgICAgICAgICAgICB2YXIgZmlsdGVyID0geHhTeXN0ZW1EZWZlbnNlWydBTVRfSGRyODAyMUZpbHRlciddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPG9wdGlvbiB2YWx1ZT0iICsgZmlsdGVyWyJJbnN0YW5jZUlEIl0gKyAiPiIgKyBmaWx0ZXJbIk5hbWUiXTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFN5c3RlbURlZmVuc2VbJ0FNVF9JUEhlYWRlcnNGaWx0ZXInXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGZpbHRlciA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0lQSGVhZGVyc0ZpbHRlciddLnJlc3BvbnNlc1tpXTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPG9wdGlvbiB2YWx1ZT0iICsgZmlsdGVyWyJJbnN0YW5jZUlEIl0gKyAiPiIgKyBmaWx0ZXJbIk5hbWUiXTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgeCArPSAiPC9zZWxlY3Q+PGlucHV0IGlkPWFkZEZpbHRlckJ1dHRvbiB0eXBlPWJ1dHRvbiB2YWx1ZT1BZGQgc3R5bGU9d2lkdGg6ODBweCBvbmNsaWNrPWFkZEZpbHRlckJ1dHRvbigpPjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6NHB4PkFkZCBGaWx0ZXI8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ0FkZCBTeXN0ZW0gRGVmZW5zZSBQb2xpY3knLCAzLCBBZGREZWZlbnNlUG9saWN5T2ssIHgpOw0KICAgICAgICAgICAgQWRkRGVmZW5zZVBvbGljeVVwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gYWRkRmlsdGVyQnV0dG9uKCkgew0KICAgICAgICAgICAgaWYgKHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMuaW5kZXhPZihRKCd4ZmlsdGVyJykudmFsdWUpID49IDApIHJldHVybjsNCiAgICAgICAgICAgIHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMucHVzaChRKCd4ZmlsdGVyJykudmFsdWUpOw0KICAgICAgICAgICAgQWRkRGVmZW5zZVBvbGljeVVwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcmVtb3ZlRmlsdGVyQnV0dG9uKGgpIHsNCiAgICAgICAgICAgIHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMuc3BsaWNlKGgsIDEpOw0KICAgICAgICAgICAgQWRkRGVmZW5zZVBvbGljeVVwZGF0ZSgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkRGVmZW5zZVBvbGljeVVwZGF0ZSgpIHsNCiAgICAgICAgICAgIHZhciBvayA9IFEoJ3BvbGljeW5hbWUnKS52YWx1ZS5zcGxpdCgnOicpWzBdLmxlbmd0aCA+IDA7DQogICAgICAgICAgICBRRSgnaWR4X2RsZ09rQnV0dG9uJywgb2spOw0KICAgICAgICAgICAgaWYgKHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMubGVuZ3RoID09IDApIHsNCiAgICAgICAgICAgICAgICBRSCgncG9saWN5RmlsdGVycycsICc8YnI+PGk+VGhpcyBwb2xpY3kgY29udGFpbnMgbm8gZmlsdGVycy48L2k+PGJyPjxicj4nKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4QWRkRGVmZW5zZVBvbGljeUZpbHRlcnMpIHsNCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBjbGFzcz1pdGVtQmFyIHN0eWxlPW1hcmdpbi1yaWdodDowPjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ+IiArIEFkZEJ1dHRvbjIoIlJlbW92ZSIsICJyZW1vdmVGaWx0ZXJCdXR0b24oIiArIGkgKyAiKSIpICsgIjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4O21heC13aWR0aDoyNjBweDtvdmVyZmxvdzpoaWRkZW4+PGI+IiArIEdldEZpbHRlckJ5SWQoeHhBZGREZWZlbnNlUG9saWN5RmlsdGVyc1tpXSlbJ05hbWUnXSArICI8L2I+PC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgUUgoJ3BvbGljeUZpbHRlcnMnLCB4KTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIFRPRE86IE9uY2UgbG9hZGVkLCB3ZSBjb3VsZCBtYWtlIGEgdGFibGUgb2YgImhhbmRsZSAtPiBmaWx0ZXIiIHdoZXJlIGJvdGggZmlsdGVyIHR5cGVzIGFyZSBtaXhlZC1pbi4gQ291bGQgbWFrZSB0aGluZ3Mgc2ltcGxlci9zbWFsbGVyPw0KICAgICAgICAvLyBXZSB3b3VsZCBvbmx5IGhhdmUgb25lIHRhYmxlIHRvIGxvb3AgaW5zdGVhZCBvZiB0d28gYXQgYSBmZXcgcGxhY2VzLiBUaGlzIGZ1bmN0aW9uIHdvdWxkIGJlIHJlbW92ZWQgY29tcGxldGVseS4NCiAgICAgICAgZnVuY3Rpb24gR2V0RmlsdGVyQnlJZChoKSB7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4U3lzdGVtRGVmZW5zZVsnQU1UX0hkcjgwMjFGaWx0ZXInXS5yZXNwb25zZXMpIHsgdmFyIGZpbHRlciA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX0hkcjgwMjFGaWx0ZXInXS5yZXNwb25zZXNbaV07IGlmIChmaWx0ZXJbIkluc3RhbmNlSUQiXSA9PSBoKSByZXR1cm4gZmlsdGVyOyB9DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4U3lzdGVtRGVmZW5zZVsnQU1UX0lQSGVhZGVyc0ZpbHRlciddLnJlc3BvbnNlcykgeyB2YXIgZmlsdGVyID0geHhTeXN0ZW1EZWZlbnNlWydBTVRfSVBIZWFkZXJzRmlsdGVyJ10ucmVzcG9uc2VzW2ldOyBpZiAoZmlsdGVyWyJJbnN0YW5jZUlEIl0gPT0gaCkgcmV0dXJuIGZpbHRlcjsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkRGVmZW5zZVBvbGljeU9rKCkgew0KICAgICAgICAgICAgdmFyIHR4ID0gUSgncG9saWN5dHgnKS52YWx1ZTsNCiAgICAgICAgICAgIHZhciByeCA9IFEoJ3BvbGljeXJ4JykudmFsdWU7DQogICAgICAgICAgICB2YXIgcHJpID0gMDsNCiAgICAgICAgICAgIHZhciBuID0gUSgncG9saWN5bmFtZScpLnZhbHVlLnNwbGl0KCc6Jyk7DQogICAgICAgICAgICBpZiAobi5sZW5ndGggPT0gMikgcHJpID0gcGFyc2VJbnQoblsxXSk7DQogICAgICAgICAgICB2YXIgZmlsdGVyID0geyAnSW5zdGFuY2VJRCAnOiAwLCAnUG9saWN5TmFtZSc6IG5bMF0sICdQb2xpY3lQcmVjZWRlbmNlJzogcHJpLCAnVHhEZWZhdWx0Q291bnQnOiAodHggPiAxKSwgJ1R4RGVmYXVsdERyb3AnOiAodHggJSAyID09IDEpLCAnVHhEZWZhdWx0TWF0Y2hFdmVudCc6ICh0eCA+IDMpLCAnUnhEZWZhdWx0Q291bnQnOiAocnggPiAxKSwgJ1J4RGVmYXVsdERyb3AnOiAocnggJSAyID09IDEpLCAnUnhEZWZhdWx0TWF0Y2hFdmVudCc6IChyeCA+IDMpIH07DQogICAgICAgICAgICBpZiAoeHhBZGREZWZlbnNlUG9saWN5RmlsdGVycy5sZW5ndGggPiAwKSBmaWx0ZXJbJ0ZpbHRlckNyZWF0aW9uSGFuZGxlcyddID0geHhBZGREZWZlbnNlUG9saWN5RmlsdGVyczsNCiAgICAgICAgICAgIGFtdHN0YWNrLkNyZWF0ZSgnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knLCBmaWx0ZXIsIEFkZERlZmVuc2VQb2xpY3lPazIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkRGVmZW5zZVBvbGljeU9rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnQWRkIFN5c3RlbSBEZWZlbnNlIFBvbGljeScsICJVbmFibGUgdG8gYWRkIHBvbGljeSwgZXJyb3IgIyIgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsU3lzdGVtRGVmZW5zZSgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1BvbGljeURldGFpbHMoaSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHBvbGljeSA9IHh4U3lzdGVtRGVmZW5zZVsnQU1UX1N5c3RlbURlZmVuc2VQb2xpY3knXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICB2YXIgeCA9ICcnOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ05hbWUnLCBFc2NhcGVIdG1sKHBvbGljeVsiUG9saWN5TmFtZSJdKSk7DQogICAgICAgICAgICBpZiAocG9saWN5WyJQb2xpY3lQcmVjZWRlbmNlIl0gIT0gMCkgeCArPSBhZGRIdG1sVmFsdWUoJ1ByZWNlZGVuY2UnLCBwb2xpY3lbIlBvbGljeVByZWNlZGVuY2UiXSk7DQoNCiAgICAgICAgICAgIHZhciBhY3Rpb24gPSAocG9saWN5WyJUeERlZmF1bHREcm9wIl0gPT0gdHJ1ZSkgPyAnRHJvcCcgOiAnQWxsb3cnOw0KICAgICAgICAgICAgaWYgKHBvbGljeVsiVHhEZWZhdWx0Q291bnQiXSA9PSB0cnVlKSBhY3Rpb24gKz0gJywgQ291bnQnOw0KICAgICAgICAgICAgaWYgKHBvbGljeVsiVHhEZWZhdWx0TWF0Y2hFdmVudCJdID09IHRydWUpIGFjdGlvbiArPSAnLCBFdmVudCc7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnRGVmYXVsdCBUWCBBY3Rpb24nLCBhY3Rpb24pOw0KDQogICAgICAgICAgICBhY3Rpb24gPSAocG9saWN5WyJSeERlZmF1bHREcm9wIl0gPT0gdHJ1ZSkgPyAnRHJvcCcgOiAnQWxsb3cnOw0KICAgICAgICAgICAgaWYgKHBvbGljeVsiUnhEZWZhdWx0Q291bnQiXSA9PSB0cnVlKSBhY3Rpb24gKz0gJywgQ291bnQnOw0KICAgICAgICAgICAgaWYgKHBvbGljeVsiUnhEZWZhdWx0TWF0Y2hFdmVudCJdID09IHRydWUpIGFjdGlvbiArPSAnLCBFdmVudCc7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgnRGVmYXVsdCBSWCBBY3Rpb24nLCBhY3Rpb24pOw0KDQogICAgICAgICAgICBpZiAocG9saWN5WydGaWx0ZXJDcmVhdGlvbkhhbmRsZXMnXSkgeyBmb3IgKHZhciBpIGluIHBvbGljeVsnRmlsdGVyQ3JlYXRpb25IYW5kbGVzJ10pIHsgeCArPSBhZGRIdG1sVmFsdWUoJ0ZpbHRlciAjJyArICgraSArIDEpLCBHZXRGaWx0ZXJCeUlkKHBvbGljeVsnRmlsdGVyQ3JlYXRpb25IYW5kbGVzJ11baV0pWydOYW1lJ10pOyB9IH0NCg0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ1BvbGljeSAjJyArIHBvbGljeVsnSW5zdGFuY2VJRCddLnN1YnN0cmluZygyMCksIDUsIHNob3dQb2xpY3lEZXRhaWxzT2ssIHgsIHBvbGljeSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93UG9saWN5RGV0YWlsc09rKGIsIHRhZykgew0KICAgICAgICAgICAgaWYgKGIgPT0gMikgeyBhbXRzdGFjay5EZWxldGUoJ0FNVF9TeXN0ZW1EZWZlbnNlUG9saWN5JywgdGFnLCBkZWxldGVEZWZlbnNlUG9saWN5KTsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGVsZXRlRGVmZW5zZVBvbGljeShzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnUmVtb3ZlIFBvbGljeScsICJVbmFibGUgdG8gcmVtb3ZlIHBvbGljeSwgbWFrZSBzdXJlIGl0J3Mgbm90IGluIHVzZS4iKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgUHVsbFN5c3RlbURlZmVuc2UoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQoNCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gV0lSRUxFU1MgU0VUVElOR1MgUEFORUwNCiAgICAgICAgLy8NCg0KICAgICAgICB2YXIgeHhXaXJlbGVzczsNCiAgICAgICAgZnVuY3Rpb24gUHVsbFdpcmVsZXNzKCkgew0KICAgICAgICAgICAgYW10Rmlyc3RQdWxsIHw9IDI7DQogICAgICAgICAgICB0cnkgeyBpZiAoYW10d2lyZWxlc3NpZiA9PSAtMSkgcmV0dXJuOyB9IGNhdGNoIChlKSB7fSAvLyBJZiB0aGUgd2lyZWxlc3MgYWRhcHRlciBoYXMgbm8gTUFDLCBkb24ndCBzaG93IHRoaXMuDQogICAgICAgICAgICBhbXRzdGFjay5CYXRjaEVudW0oIiIsIFsiKkNJTV9XaUZpUG9ydENhcGFiaWxpdGllcyIsICIqQ0lNX1dpRmlQb3J0IiwgIipDSU1fV2lGaUVuZHBvaW50IiwgIkNJTV9XaUZpRW5kcG9pbnRTZXR0aW5ncyJdLCBwcm9jZXNzV2lyZWxlc3MpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gd2lmaVJlZnJlc2goKSB7IGlmICgheHhkaWFsb2dNb2RlKSBQdWxsV2lyZWxlc3MoKTsgfQ0KDQogICAgICAgIHZhciB4eFdpZmlTdGF0ZSA9IHsgMzogJ0Rpc2FibGVkJywgMzI3Njg6ICdFbmFibGVkIGluIFMwJywgMzI3Njk6ICdFbmFibGVkIGluIFMwLCBTeC9BQycgfTsNCiAgICAgICAgdmFyIHh4UmFkaW9TdGF0ZSA9IAl7IDI6ICdPbiwgQ29ubmVjdGVkJywgMzogJ09mZicsIDY6ICdPbiwgRGlzY29ubmVjdGVkJyB9Ow0KICAgICAgICB2YXIgeHhXaWZpQXV0aGVudGljYXRpb25NZXRob2Q9IHsgMTogJ090aGVyJywgMjogJ09wZW4nLCAzOiAnU2hhcmVkIEtleScsIDQ6ICdXUEEgUFNLJywgNTogJ1dQQSBJRUVFIDgwMi4xeCcsIDY6ICdXUEEyIFBTSycsIDc6ICdXUEEyIElFRUUgODAyLjF4JyB9Ow0KICAgICAgICB2YXIgeHhXaWZpRW5jcnlwdGlvbk1ldGhvZCA9IHsgMTogJ090aGVyJywgMjogJ1dFUCcsIDM6ICdUS0lQLVJDNCcsIDQ6ICdDQ01QLUFFUycsIDU6ICdOb25lJyB9OyAvLyBGb3IgMiAmIDUsIEF1dGhlbnRpY2F0aW9uTWV0aG9kIG11c3QgYmUgMiBvciAzLiBGb3IgMyAmIDQgQXV0aGVudGljYXRpb25NZXRob2QgbXVzdCBiZSA0LDUsNiBvciA3DQoNCiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1dpcmVsZXNzKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgeHhXaXJlbGVzcyA9IHJlc3BvbnNlczsgfSBlbHNlIHsgeHhXaXJlbGVzcyA9IHVuZGVmaW5lZDsgfQ0KICAgICAgICAgICAgdXBkYXRlU3lzdGVtU3RhdHVzKCk7DQogICAgICAgICAgICBzaG93V2lyZWxlc3NJbmZvKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93V2lyZWxlc3NJbmZvKCkgew0KICAgICAgICAgICAgaWYgKCF4eFdpcmVsZXNzKSByZXR1cm47DQogICAgICAgICAgICB2YXIgaSwgaiwgcyA9ICIiLCBzYywgeCA9ICI8YnI+PGgyPldpcmVsZXNzIFByb2ZpbGVzPC9oMj4iOw0KICAgICAgICAgICAgaWYgKCEoeHhXaXJlbGVzc1snQ0lNX1dpRmlQb3J0Q2FwYWJpbGl0aWVzJ10ucmVzcG9uc2UpKSByZXR1cm47DQoNCiAgICAgICAgICAgIC8vIFNob3cgV0lGSSBwcm9maWxlcyBzb3J0ZWQgYnkgcHJpb3JpdHkNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjIgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPldpcmVsZXNzIHByb2ZpbGVzIHRoYXQgSW50ZWwmcmVnOyBBTVQgd2lsbCB1c2UgZm9yIG5ldHdvcmsgY29ubmVjdGl2aXR5Ljxicj48YnI+IjsNCiAgICAgICAgICAgIHMgPSAwOw0KICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgMjU2OyBpKyspIHsNCiAgICAgICAgICAgICAgICBmb3IgKGogaW4geHhXaXJlbGVzc1snQ0lNX1dpRmlFbmRwb2ludFNldHRpbmdzJ10ucmVzcG9uc2VzKSB7DQogICAgICAgICAgICAgICAgICAgIHNjID0geHhXaXJlbGVzc1snQ0lNX1dpRmlFbmRwb2ludFNldHRpbmdzJ10ucmVzcG9uc2VzW2pdOw0KICAgICAgICAgICAgICAgICAgICBpZiAoc2NbJ0F1dGhlbnRpY2F0aW9uTWV0aG9kJ10gPT0gMSkgY29udGludWU7IC8vIFNraXAgIkVuZHBvaW50IFVzZXIgU2V0dGluZ3MiDQogICAgICAgICAgICAgICAgICAgIGlmIChzY1snUHJpb3JpdHknXSA9PSBpKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93V2lmaURldGFpbHMoIiArIGogKyAiKT48ZGl2IHN0eWxlPWZsb2F0OnJpZ2h0PiIgKyBFc2NhcGVIdG1sKHNjWydTU0lEJ10pICsgIiwgIiArIHh4V2lmaUF1dGhlbnRpY2F0aW9uTWV0aG9kW3NjWydBdXRoZW50aWNhdGlvbk1ldGhvZCddXSArICIsICIgKyB4eFdpZmlFbmNyeXB0aW9uTWV0aG9kW3NjWydFbmNyeXB0aW9uTWV0aG9kJ11dICsgIiAmbmJzcDsgIjsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHggKz0gQWRkQnV0dG9uMigiUmVtb3ZlIiwgIndpZmlSZW1vdmVCdXR0b24oXCIiICsgaiArICJcIikiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gIjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyBFc2NhcGVIdG1sKHNjWydFbGVtZW50TmFtZSddKSArICI8L2I+PC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICAgICAgICAgIHMrKzsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChzID09IDApIHggKz0gJzxpPk5vIFdpcmVsZXNzIFByb2ZpbGVzIFByZXNlbnQ8L2k+PGJyPic7DQoNCiAgICAgICAgICAgIC8vIEVuZCBvZiB0YWJsZQ0KICAgICAgICAgICAgeCArPSAiPGJyPjx0ZCBjbGFzcz1yMj4iOw0KICAgICAgICAgICAgaWYgKHh4QWNjb3VudEFkbWluTmFtZSkgeCArPSBUYWJsZUVuZChBZGRCdXR0b24oIk5ldyBQcm9maWxlIiwgInNob3dXaWZpTmV3UHJvZmlsZSgpIikpOyBlbHNlIHggKz0gVGFibGVFbmQoJycpOw0KICAgICAgICAgICAgUUgoJ2lkX1RhYmxlV2lmaTInLCB4ICsgIjxicj4iKTsNCiAgICAgICAgfQ0KICAgICAgICANCiAgICAgICAgZnVuY3Rpb24gc2hvd1dpZmlTdGF0ZURsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBzID0gIiI7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4V2lmaVN0YXRlKSB7IHMgKz0gJzxpbnB1dCB0eXBlPXJhZGlvIG5hbWU9ZDExIGlkPXdsJyArIGkgKyAnIHZhbHVlPScgKyBpICsgJyAnICsgKCh4eFdpcmVsZXNzWydDSU1fV2lGaVBvcnQnXS5yZXNwb25zZVsiRW5hYmxlZFN0YXRlIl0gPT0gaSk/ImNoZWNrZWQiOiIiKSArICc+JyArIHh4V2lmaVN0YXRlW2ldICsgJzxicj4nOyB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnV2lyZWxlc3MgU3RhdGUnLCAzLCB3aWZpU3RhdGVEbGcsIHMpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gd2lmaVN0YXRlRGxnKCkgeyBhbXRzdGFjay5DSU1fV2lGaVBvcnRfUmVxdWVzdFN0YXRlQ2hhbmdlKCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPWQxMV06Y2hlY2tlZCcpLnZhbHVlLCBudWxsLCBmdW5jdGlvbigpIHsgYW10c3RhY2suR2V0KCJDSU1fV2lGaVBvcnQiLCBmdW5jdGlvbihzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgeyBpZiAoc3RhdHVzID09IDIwMCkgeyB4eFdpcmVsZXNzWydDSU1fV2lGaVBvcnQnXS5yZXNwb25zZSA9IHJlc3BvbnNlLkJvZHk7IHNob3dXaXJlbGVzc0luZm8oKTsgfSB9ICk7IH0gKTsgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dXaWZpRGV0YWlscyhoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgaSwgc2MgPSB4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXNbaF0sIHggPSAnPGRpdiBzdHlsZT10ZXh0LWFsaWduOmxlZnQ+JzsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJQcm9maWxlIE5hbWUiLCBFc2NhcGVIdG1sKHNjWydFbGVtZW50TmFtZSddKSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiU1NJRCIsIHNjWydTU0lEJ10pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkF1dGhlbnRpY2F0aW9uIiwgeHhXaWZpQXV0aGVudGljYXRpb25NZXRob2Rbc2NbJ0F1dGhlbnRpY2F0aW9uTWV0aG9kJ11dKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJFbmNyeXB0aW9uIiwgeHhXaWZpRW5jcnlwdGlvbk1ldGhvZFtzY1snRW5jcnlwdGlvbk1ldGhvZCddXSk7DQogICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiUHJpb3JpdHkiLCBzY1snUHJpb3JpdHknXSk7DQogICAgICAgICAgICB4ICs9ICI8L2Rpdj4iOw0KICAgICAgICAgICAgbWVzc2FnZWJveCgiV2lyZWxlc3MgUHJvZmlsZSIsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gd2lmaVJlbW92ZUJ1dHRvbihoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgc2MgPSB4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXNbaF07DQogICAgICAgICAgICBRSCgnaWRfZGlhbG9nTWVzc2FnZScsICdSZW1vdmUgd2lyZWxlc3MgcHJvZmlsZSBcIicgKyBzY1siRWxlbWVudE5hbWUiXSArICdcIj8nKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMSwgIldpcmVsZXNzIFByb2ZpbGUiLCAzLCBmdW5jdGlvbiAoKSB7IHJlbW92ZVdpZmlCdXR0b25FeChoKSB9KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHJlbW92ZVdpZmlCdXR0b25FeChoKSB7DQogICAgICAgICAgICB2YXIgc2MgPSB4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXNbaF07DQogICAgICAgICAgICBhbXRzdGFjay5EZWxldGUoJ0NJTV9XaUZpRW5kcG9pbnRTZXR0aW5ncycsIHsgSW5zdGFuY2VJRDogc2NbJ0luc3RhbmNlSUQnXSB9LCByZW1vdmVXaWZpRW50cnlSZXNwb25zZSwgMCwgMSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiByZW1vdmVXaWZpRW50cnlSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICBpZiAobWV0aG9kY2hlY2socmVzcG9uc2UpKSByZXR1cm47DQogICAgICAgICAgICBhbXRzdGFjay5FbnVtKCJDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MiLCBmdW5jdGlvbihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsgaWYgKHN0YXR1cyA9PSAyMDApIHsgeHhXaXJlbGVzc1snQ0lNX1dpRmlFbmRwb2ludFNldHRpbmdzJ10ucmVzcG9uc2VzID0gcmVzcG9uc2VzOyBzaG93V2lyZWxlc3NJbmZvKCk7IH0gfSApOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1dpZmlOZXdQcm9maWxlKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIGZvciAoaSA9IDE7IGkgPCAyNTY7IGkrKykgew0KICAgICAgICAgICAgICAgIHZhciB0ID0gMTsNCiAgICAgICAgICAgICAgICBmb3IgKGogaW4geHhXaXJlbGVzc1snQ0lNX1dpRmlFbmRwb2ludFNldHRpbmdzJ10ucmVzcG9uc2VzKSB7IGlmICh4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXNbal1bJ1ByaW9yaXR5J10gPT0gaSkgdCA9IDA7IH0NCiAgICAgICAgICAgICAgICBpZiAodCkgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPScrIGkgKyc+JysgaTsgfSAvLyBPcHRpb24gaXMgYSB0YWcgdGhhdCBpcyBzZWxmIGNsb3NpbmcuDQogICAgICAgICAgICB9DQogICAgICAgICAgICBRSCgnaWR4X2QxMnByaScsIHgpOw0KDQogICAgICAgICAgICBpZHhfZDEyYXV0aC52YWx1ZSA9IDY7DQogICAgICAgICAgICBpZHhfZDEyZW5jLnZhbHVlID0gNDsNCg0KICAgICAgICAgICAgaWR4X2QxMm5hbWUudmFsdWUgPSBpZHhfZDEyc3NpZC52YWx1ZSA9IGlkeF9kMTJwYXNzd29yZDEudmFsdWUgPSBpZHhfZDEycGFzc3dvcmQyLnZhbHVlID0gJyc7DQoNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTIsICJBZGQgV2lyZWxlc3MgUHJvZmlsZSIsIDMsIGZ1bmN0aW9uICgpIHsgYWRkV2lmaVByb2ZpbGUoKSB9KTsNCiAgICAgICAgICAgIHVwZGF0ZVdpZmlEaWFsb2coKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGFkZFdpZmlQcm9maWxlKCkgew0KICAgICAgICAgICAgYW10c3RhY2suQU1UX1dpRmlQb3J0Q29uZmlndXJhdGlvblNlcnZpY2VfQWRkV2lGaVNldHRpbmdzKA0KCQkJCXsNCgkJCQkgICAgJ19fcGFyYW1ldGVyVHlwZSc6ICdyZWZlcmVuY2UnLA0KCQkJCSAgICAnX19yZXNvdXJjZVVyaSc6IGFtdHN0YWNrLkNvbXBsZXRlTmFtZSgnQ0lNX1dpRmlFbmRwb2ludCcpLA0KCQkJCSAgICAnTmFtZSc6ICdXaUZpIEVuZHBvaW50IDAnDQoJCQkJfSwgew0KCQkJCSAgICAnX19wYXJhbWV0ZXJUeXBlJzogJ2luc3RhbmNlJywNCgkJCQkgICAgJ19fbmFtZXNwYWNlJzogYW10c3RhY2suQ29tcGxldGVOYW1lKCdDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnKSwNCgkJCQkgICAgJ0VsZW1lbnROYW1lJzogaWR4X2QxMm5hbWUudmFsdWUsDQoJCQkJICAgICdJbnN0YW5jZUlEJzogJ0ludGVsKHIpIEFNVDpXaUZpIEVuZHBvaW50IFNldHRpbmdzICcgKyBpZHhfZDEybmFtZS52YWx1ZSwNCgkJCQkgICAgJ0F1dGhlbnRpY2F0aW9uTWV0aG9kJzogaWR4X2QxMmF1dGgudmFsdWUsDQoJCQkJICAgICdFbmNyeXB0aW9uTWV0aG9kJzogaWR4X2QxMmVuYy52YWx1ZSwNCgkJCQkgICAgJ1NTSUQnOiBpZHhfZDEyc3NpZC52YWx1ZSwNCgkJCQkgICAgJ1ByaW9yaXR5JzogaWR4X2QxMnByaS52YWx1ZSwNCgkJCQkgICAgJ1BTS1Bhc3NQaHJhc2UnOiBpZHhfZDEycGFzc3dvcmQxLnZhbHVlDQoJCQkJfSwNCgkJCQludWxsLCBudWxsLCBudWxsLCByZW1vdmVXaWZpRW50cnlSZXNwb25zZQ0KCQkJKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVwZGF0ZVdpZmlEaWFsb2coKSB7DQogICAgICAgICAgICB2YXIgciA9IHRydWU7DQogICAgICAgICAgICB2YXIgYSA9IGlkeF9kMTJhdXRoLnZhbHVlOw0KICAgICAgICAgICAgdmFyIGUgPSBpZHhfZDEyZW5jLnZhbHVlOw0KICAgICAgICAgICAgUVYoJ2lkX2QxMmUyJywgYSA8IDQpOw0KICAgICAgICAgICAgUVYoJ2lkX2QxMmUzJywgYSA+IDMpOw0KICAgICAgICAgICAgUVYoJ2lkX2QxMmU0JywgYSA+IDMpOw0KICAgICAgICAgICAgUVYoJ2lkX2QxMmU1JywgYSA8IDQpOw0KICAgICAgICAgICAgaWYgKGEgPCA0ICYmIChlID09IDMgfHwgZSA9PSA0KSkgeyBpZHhfZDEyZW5jLnZhbHVlID0gMjsgfQ0KICAgICAgICAgICAgaWYgKGEgPiAzICYmIChlID09IDIgfHwgZSA9PSA1KSkgeyBpZHhfZDEyZW5jLnZhbHVlID0gMzsgfQ0KDQogICAgICAgICAgICAvLyBDaGVjayBpZiB0aGVyZSBpcyBhbHJlYWR5IGEgcHJvZmlsZSB3aXRoIHRoaXMgbmFtZQ0KICAgICAgICAgICAgZm9yICh2YXIgaiBpbiB4eFdpcmVsZXNzWydDSU1fV2lGaUVuZHBvaW50U2V0dGluZ3MnXS5yZXNwb25zZXMpIHsgaWYgKHh4V2lyZWxlc3NbJ0NJTV9XaUZpRW5kcG9pbnRTZXR0aW5ncyddLnJlc3BvbnNlc1tqXVsnRWxlbWVudE5hbWUnXSA9PSBpZHhfZDEybmFtZS52YWx1ZSkgeyByID0gZmFsc2U7IH0gfQ0KDQogICAgICAgICAgICBRRSgnaWR4X2RsZ09rQnV0dG9uJywgciA9PSB0cnVlICYmIChpZHhfZDEybmFtZS52YWx1ZS5sZW5ndGggPiAwKSAmJiAoaWR4X2QxMnNzaWQudmFsdWUubGVuZ3RoID4gMCkgJiYgKGlkeF9kMTJwYXNzd29yZDEudmFsdWUubGVuZ3RoID4gNykgJiYgKGlkeF9kMTJwYXNzd29yZDEudmFsdWUgPT0gaWR4X2QxMnBhc3N3b3JkMi52YWx1ZSkpOw0KICAgICAgICB9DQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEhBUkRXQVJFIElORk9STUFUSU9OIFBBTkVMDQogICAgICAgIC8vDQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbEhhcmR3YXJlKCkgew0KICAgICAgICAgICAgYW10c3RhY2suQmF0Y2hFbnVtKCIiLCBbIipDSU1fQ29tcHV0ZXJTeXN0ZW1QYWNrYWdlIiwgIkNJTV9TeXN0ZW1QYWNrYWdpbmciLCAiKkNJTV9DaGFzc2lzIiwgIkNJTV9DaGlwIiwgIipDSU1fQ2FyZCIsICIqQ0lNX0JJT1NFbGVtZW50IiwgIkNJTV9Qcm9jZXNzb3IiLCAiQ0lNX1BoeXNpY2FsTWVtb3J5IiwgIkNJTV9NZWRpYUFjY2Vzc0RldmljZSIsICJDSU1fUGh5c2ljYWxQYWNrYWdlIl0sIHByb2Nlc3NIYXJkd2FyZSk7DQogICAgICAgICAgICBhbXRGaXJzdFB1bGwgfD0gMTsgLy8gU2V0IHRoZSBoYXJkd2FyZSBpbmZvIGJpdCBvbiwgaW5kaWNhdGVzIHdlIGFyZSBwdWxsaW5nIHRoaXMgaW5mb3JtYXRpb24uDQogICAgICAgIH0NCg0KICAgICAgICAvLyBodHRwOi8vd3d3LmRtdGYub3JnL3NpdGVzL2RlZmF1bHQvZmlsZXMvc3RhbmRhcmRzL2RvY3VtZW50cy9EU1AwMTM0XzIuNy4xLnBkZg0KICAgICAgICB2YXIgRE1URkNQVVN0YXR1cyA9IFsiVW5rbm93biIsICJFbmFibGVkIiwgIkRpc2FibGVkIGJ5IFVzZXIiLCAiRGlzYWJsZWQgQnkgQklPUyAoUE9TVCBFcnJvcikiLCAiSWRsZSIsICJPdGhlciJdOw0KICAgICAgICB2YXIgRE1URk1lbVR5cGUgPSBbIlVua25vd24iLCAiT3RoZXIiLCAiRFJBTSIsICJTeW5jaHJvbm91cyBEUkFNIiwgIkNhY2hlIERSQU0iLCAiRURPIiwgIkVEUkFNIiwgIlZSQU0iLCAiU1JBTSIsICJSQU0iLCAiUk9NIiwgIkZsYXNoIiwgIkVFUFJPTSIsICJGRVBST00iLCAiRVBST00iLCAiQ0RSQU0iLCAiM0RSQU0iLCAiU0RSQU0iLCAiU0dSQU0iLCAiUkRSQU0iLCAiRERSIiwgIkREUi0yIiwgIkJSQU0iLCAiRkItRElNTSIsICJERFIzIiwgIkZCRDIiLCAiRERSNCIsICJMUEREUiIsICJMUEREUjIiLCAiTFBERFIzIiwgIkxQRERSNCJdOw0KICAgICAgICB2YXIgRE1URk1lbUZvcm1GYWN0b3IgPSBbJycsICdPdGhlcicsJ1Vua25vd24nLCdTSU1NJywnU0lQJywnQ2hpcCcsJ0RJUCcsJ1pJUCcsJ1Byb3ByaWV0YXJ5IENhcmQnLCdESU1NJywnVFNPUCcsJ1JvdyBvZiBjaGlwcycsJ1JJTU0nLCdTT0RJTU0nLCdTUklNTScsJ0ZCLURJTSddOw0KICAgICAgICB2YXIgRE1URlByb2NGYW1pbGx5ID0geyAvLyBQYWdlIDQ2IG9mIERNVEYgZG9jdW1lbnQNCiAgICAgICAgICAgIDE5MTogJ0ludGVsJnJlZzsgQ29yZSZ0cmFkZTsgMiBEdW8gUHJvY2Vzc29yJywNCiAgICAgICAgICAgIDE5MjogJ0ludGVsJnJlZzsgQ29yZSZ0cmFkZTsgMiBTb2xvIHByb2Nlc3NvcicsDQogICAgICAgICAgICAxOTM6ICdJbnRlbCZyZWc7IENvcmUmdHJhZGU7IDIgRXh0cmVtZSBwcm9jZXNzb3InLA0KICAgICAgICAgICAgMTk0OiAnSW50ZWwmcmVnOyBDb3JlJnRyYWRlOyAyIFF1YWQgcHJvY2Vzc29yJywNCiAgICAgICAgICAgIDE5NTogJ0ludGVsJnJlZzsgQ29yZSZ0cmFkZTsgMiBFeHRyZW1lIG1vYmlsZSBwcm9jZXNzb3InLA0KICAgICAgICAgICAgMTk2OiAnSW50ZWwmcmVnOyBDb3JlJnRyYWRlOyAyIER1byBtb2JpbGUgcHJvY2Vzc29yJywNCiAgICAgICAgICAgIDE5NzogJ0ludGVsJnJlZzsgQ29yZSZ0cmFkZTsgMiBTb2xvIG1vYmlsZSBwcm9jZXNzb3InLA0KICAgICAgICAgICAgMTk4OiAnSW50ZWwmcmVnOyBDb3JlJnRyYWRlOyBpNyBwcm9jZXNzb3InLA0KICAgICAgICAgICAgMTk5OiAnRHVhbC1Db3JlIEludGVsJnJlZzsgQ2VsZXJvbiZyZWc7IHByb2Nlc3NvcicgfTsNCg0KICAgICAgICB2YXIgSGFyZHdhcmVJbnZlbnRvcnk7DQogICAgICAgIGZ1bmN0aW9uIHByb2Nlc3NIYXJkd2FyZShzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSByZXR1cm47DQoNCiAgICAgICAgICAgIHZhciBpLCB4ID0gIjx0YWJsZSBjbGFzcz1sb2cxIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6OHB4PiI7DQogICAgICAgICAgICBIYXJkd2FyZUludmVudG9yeSA9IHJlc3BvbnNlczsNCiAgICAgICAgICAgIFFWKCdnbzInLCB0cnVlKTsgLy8gU2hvdyAiSGFyZHdhcmUgSW5mb3JtYXRpb24iIG9uIGxlZnQgcGFuZWwNCg0KDQogICAgICAgICAgICB4ICs9IFRhYmxlRW5kKCI8ZGl2PiZuYnNwOyIgKyBBZGRSZWZyZXNoQnV0dG9uKCJQdWxsSGFyZHdhcmUoMSkiKSArIEFkZEJ1dHRvbigiU2F2ZS4uLiIsICJTYXZlSGFyZHdhcmVMb2coKSIpICsgJyBIYXJkd2FyZSBpbmZvcm1hdGlvbiBpcyBnYXRoZXJlZCBhdCBzeXN0ZW0gYm9vdCB0aW1lLicpOw0KDQogICAgICAgICAgICB2YXIgYmEgPSByZXNwb25zZXNbJ0NJTV9DaGFzc2lzJ10ucmVzcG9uc2U7DQogICAgICAgICAgICB2YXIgYmIgPSByZXNwb25zZXNbJ0NJTV9DYXJkJ10ucmVzcG9uc2U7DQogICAgICAgICAgICB2YXIgdiA9IHJlc3BvbnNlc1snQ0lNX0JJT1NFbGVtZW50J10ucmVzcG9uc2VbIlNvZnR3YXJlRWxlbWVudElEIl07DQogICAgICAgICAgICANCiAgICAgICAgICAgIHggKz0gIjxicj48aDI+UGxhdGZvcm08L2gyPiI7DQogICAgICAgICAgICB4ICs9IEZ1bGxUYWJsZSh7IkNvbXB1dGVyIG1vZGVsIjpiYVsiTW9kZWwiXSwgIk1hbnVmYWN0dXJlciI6YmFbIk1hbnVmYWN0dXJlciJdLCAiVmVyc2lvbiI6YmFbIlZlcnNpb24iXSwgIlNlcmlhbCBudW1iZXIiOmJhWyJTZXJpYWxOdW1iZXIiXSwgIlN5c3RlbSBJRCI6Z3VpZFRvU3RyKHJlc3BvbnNlc1snQ0lNX1N5c3RlbVBhY2thZ2luZyddLnJlc3BvbnNlc1swXVsiUGxhdGZvcm1HVUlEIl0pLnRvTG93ZXJDYXNlKCl9LCAnJyk7DQoNCiAgICAgICAgICAgIHggKz0gIjxicj48aDI+QmFzZWJvYXJkPC9oMj4iOw0KICAgICAgICAgICAgeCArPSBGdWxsVGFibGUoeyAiTWFudWZhY3R1cmVyIjpiYlsiTWFudWZhY3R1cmVyIl0sICJQcm9kdWN0IG5hbWUiOmJiWyJNb2RlbCJdLCAiVmVyc2lvbiI6YmJbIlZlcnNpb24iXSwgIlNlcmlhbCBudW1iZXIiOmJiWyJTZXJpYWxOdW1iZXIiXSwgIkFzc2V0IHRhZyI6YmJbIlRhZyJdLCAiUmVwbGFjZWFibGU/IjooYmJbIkNhbkJlRlJVZWQiXT09dHJ1ZSk/J1llcyc6J05vJyB9LCcnKTsNCiAgICAgICAgICAgIA0KICAgICAgICAgICAgeCArPSAiPGJyPjxoMj5CSU9TPC9oMj4iOw0KICAgICAgICAgICAgeCArPSBGdWxsVGFibGUoeyJWZW5kb3IiOnJlc3BvbnNlc1snQ0lNX0JJT1NFbGVtZW50J10ucmVzcG9uc2VbIk1hbnVmYWN0dXJlciJdLCAiVmVyc2lvbiI6diwgIlJlbGVhc2UgZGF0ZSI6bmV3IERhdGUocmVzcG9uc2VzWydDSU1fQklPU0VsZW1lbnQnXS5yZXNwb25zZVsiUmVsZWFzZURhdGUiXVsnRGF0ZXRpbWUnXSkudG9Mb2NhbGVEYXRlU3RyaW5nKCdlbicsIHt0aW1lWm9uZTonVVRDJ30pfSwnJyk7DQogICAgICAgICAgICANCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KICAgICAgICAgICAgZm9yIChpIGluIHJlc3BvbnNlc1snQ0lNX1Byb2Nlc3NvciddLnJlc3BvbnNlcykgew0KICAgICAgICAgICAgICAgIHZhciBwID0gcmVzcG9uc2VzWydDSU1fUHJvY2Vzc29yJ10ucmVzcG9uc2VzW2ldOw0KICAgICAgICAgICAgICAgIHZhciBxID0gcmVzcG9uc2VzWydDSU1fQ2hpcCddLnJlc3BvbnNlc1tpXTsgLy8gVGhpcyBpcyBhIHNob3J0Y3V0LCB3ZSBhc3N1bWUgdGhhdCB0aGUgZmlyc3QgZW50cmllcyBpbiBDSU1fQ2hpcCBhcmUgdGhlIHByb2Nlc3NvcnMsIGluIHRoZSBzYW1lIG9yZGVyLg0KICAgICAgICAgICAgICAgIHggKz0gIjxoMj5Qcm9jZXNzb3IgIiArIChwYXJzZUludChpKSArIDEpICsgIjwvaDI+IjsNCiAgICAgICAgICAgICAgICB4ICs9IEZ1bGxUYWJsZSh7Ik1hbnVmYWN0dXJlciI6dHJhZGVtYXJrcyhxWyJNYW51ZmFjdHVyZXIiXSksICJGYW1pbHkiOkRNVEZQcm9jRmFtaWxseVtwWyJGYW1pbHkiXV0sICJWZXJzaW9uIjp0cmFkZW1hcmtzKHFbIlZlcnNpb24iXSksICJNYXhpbXVtIHNvY2tldCBzcGVlZCI6cFsiTWF4Q2xvY2tTcGVlZCJdICsgIiBNSHoiLCAiU3RhdHVzIjpETVRGQ1BVU3RhdHVzW3BbIkNQVVN0YXR1cyJdXX0sJycpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSAiPGJyPiI7DQoNCiAgICAgICAgICAgIGZvciAoaSBpbiByZXNwb25zZXNbJ0NJTV9QaHlzaWNhbE1lbW9yeSddLnJlc3BvbnNlcykgew0KICAgICAgICAgICAgICAgIHZhciBtID0gcmVzcG9uc2VzWydDSU1fUGh5c2ljYWxNZW1vcnknXS5yZXNwb25zZXNbaV07DQogICAgICAgICAgICAgICAgeCArPSAiPGgyPk1lbW9yeSBNb2R1bGUgIiArICgraSArIDEpICsgIjwvaDI+IjsNCiAgICAgICAgICAgICAgICB4ICs9IEZ1bGxUYWJsZSh7IkJhbmsgTGFiZWwiOm1bIkJhbmtMYWJlbCJdLCAiTWFudWZhY3R1cmVyIjptWyJNYW51ZmFjdHVyZXIiXSwgIlNlcmlhbCBOdW1iZXIiOm1bIlNlcmlhbE51bWJlciJdLCAiU2l6ZSI6cGFyc2VJbnQobVsiQ2FwYWNpdHkiXSAvIDB4MTAwMDAwKSArICIgTUIiLCAiRm9ybSBmYWN0b3IiOkRNVEZNZW1Gb3JtRmFjdG9yW21bIkZvcm1GYWN0b3IiXV0sICJUeXBlIjpETVRGTWVtVHlwZVttWyJNZW1vcnlUeXBlIl1dLCAiQXNzZXQgdGFnIjptWyJUYWciXSwgIlBhcnQgbnVtYmVyIjptWyJQYXJ0TnVtYmVyIl19LCcnKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KDQogICAgICAgICAgICBmb3IgKGkgaW4gcmVzcG9uc2VzWydDSU1fTWVkaWFBY2Nlc3NEZXZpY2UnXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICB2YXIgbSA9IHJlc3BvbnNlc1snQ0lNX01lZGlhQWNjZXNzRGV2aWNlJ10ucmVzcG9uc2VzW2ldOw0KICAgICAgICAgICAgICAgIHZhciBuID0gcmVzcG9uc2VzWydDSU1fUGh5c2ljYWxQYWNrYWdlJ10ucmVzcG9uc2VzWytpICsgMV07IC8vIFRoaXMgaXMgYSBzaG9ydGN1dCwgd2UgYXNzdW1lIENJTV9QaHlzaWNhbFBhY2thZ2UgaXMgdGhlIHNhbWUgYXMgQ0lNX01lZGlhQWNjZXNzRGV2aWNlIGV4Y2VwdCBmb3IgdGhlIGZpcnN0IGVudHJ5Lg0KICAgICAgICAgICAgICAgIHggKz0gIjxoMj5TdG9yYWdlIE1lZGlhICIgKyAocGFyc2VJbnQoaSkgKyAxKSArICI8L2gyPiI7DQogICAgICAgICAgICAgICAgeCArPSBGdWxsVGFibGUoeyJNb2RlbCI6blsnTW9kZWwnXSwiU2VyaWFsIG51bWJlciI6KG5bJ1NlcmlhbE51bWJlciddPT0nJz8nVW5rbm93bic6blsnU2VyaWFsTnVtYmVyJ10pLCAiU2l6ZSI6cGFyc2VJbnQoTWF0aC5yb3VuZChtWyJNYXhNZWRpYVNpemUiXSAqIDEwMDAgLyAweDEwMDAwMCkpICsgIiBNQiJ9LCcnKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gIjxicj4iOw0KDQogICAgICAgICAgICBRSCgnaWRfVGFibGVTeXNJbmZvJywgeCk7DQogICAgICAgICAgICB1cGRhdGVTeXN0ZW1TdGF0dXMoKTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgZnVuY3Rpb24gU2F2ZUhhcmR3YXJlTG9nKCkgew0KICAgICAgICAgICAgaWYgKCF4eGRpYWxvZ01vZGUgJiYgSGFyZHdhcmVJbnZlbnRvcnkpIFNhdmVKc29uRmlsZSgnSW50ZWxBbXRIYXJkd2FyZScsICdoYXJkd2FyZScsICdJbnRlbCBBTVQgSGFyZHdhcmUgSW5mb3JtYXRpb24nLCBIYXJkd2FyZUludmVudG9yeSk7DQogICAgICAgIH0NCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIFBPV0VSIFBPTElDWQ0KICAgICAgICAvLw0KDQogICAgICAgIHZhciBBbXRTeXN0ZW1Qb3dlclNjaGVtZXMgPSBudWxsOw0KICAgICAgICBmdW5jdGlvbiBQdWxsUG93ZXJQb2xpY3koKSB7IGFtdHN0YWNrLkVudW0oIkFNVF9TeXN0ZW1Qb3dlclNjaGVtZSIsIHBvd2VyUG9saWN5UmVzcG9uc2UpOyB9DQogICAgICAgIGZ1bmN0aW9uIHBvd2VyUG9saWN5UmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsgQW10U3lzdGVtUG93ZXJTY2hlbWVzID0gcmVzcG9uc2U7IHVwZGF0ZVN5c3RlbVN0YXR1cygpOyB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1Bvd2VyUG9saWN5RGxnKGN1cnJlbnRndWlkKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgcyA9ICIiOw0KDQogICAgICAgICAgICAvLyBOb3cgZmluZCB0aGUgbmFtZSBvZiB0aGUgcG93ZXIgc2NoZW1hIGluIHRoZSBBTVRfU3lzdGVtUG93ZXJTY2hlbWUgdGFibGUNCiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgQW10U3lzdGVtUG93ZXJTY2hlbWVzLmxlbmd0aDsgaisrKSB7DQogICAgICAgICAgICAgICAgdmFyIHNlbGVjdGVkID0gKChBbXRTeXN0ZW1Qb3dlclNjaGVtZXNbal1bJ1NjaGVtZUdVSUQnXSA9PSBjdXJyZW50Z3VpZCk/JyBjaGVja2VkJzonJyk7DQogICAgICAgICAgICAgICAgcyArPSAnPGlucHV0IHR5cGU9cmFkaW8gbmFtZT1wb3dlcnBvbGljeSB2YWx1ZT1cIicgKyBBbXRTeXN0ZW1Qb3dlclNjaGVtZXNbal1bJ0luc3RhbmNlSUQnXSArICJcIiAiICsgc2VsZWN0ZWQgKyAnPicgKyBBbXRTeXN0ZW1Qb3dlclNjaGVtZXNbal1bJ0Rlc2NyaXB0aW9uJ10gKyAnPGJyPic7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdJbnRlbCZyZWc7IEFNVCBQb3dlciBQb2xpY3knLCAzLCBzaG93UG93ZXJQb2xpY3lEbGdPaywgcyk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93UG93ZXJQb2xpY3lEbGdPaygpIHsNCiAgICAgICAgICAgIHZhciBpZCA9IG51bGwsIGkgPSAwLCBlID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0Jyk7DQogICAgICAgICAgICBmb3IgKDsgaSA8IGUubGVuZ3RoOyBpKyspIHsgaWYgKGVbaV0ubmFtZSA9PSAncG93ZXJwb2xpY3knICYmIGVbaV0uY2hlY2tlZCkgeyBpZCA9IGVbaV0udmFsdWU7IH0gfQ0KICAgICAgICAgICAgYW10c3RhY2suQU1UX1N5c3RlbVBvd2VyU2NoZW1lX1NldFBvd2VyU2NoZW1lKHNob3dQb3dlclBvbGljeURsZ09rRG9uZSwgaWQpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1Bvd2VyUG9saWN5RGxnT2tEb25lKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7IGlmIChzdGF0dXMgPT0gMjAwKSBQdWxsU3lzdGVtU3RhdHVzKCk7IH0NCg0KICAgICAgICAvLw0KICAgICAgICAvLyBVU0VSIElORk9STUFUSU9OIFBBTkVMDQogICAgICAgIC8vDQoNCiAgICAgICAgdmFyIHh4QWNjb3VudEFkbWluTmFtZSwgeHhBY2NvdW50UmVhbG1JbmZvLCB4eEFjY291bnRFbmFibGVkSW5mbyA9IHt9LCB4eEFjY291bnRGZXRjaCwgc2hvd0hpZGRlbkFjY291bnRzID0gZmFsc2U7DQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFVzZXJJbmZvKCkgew0KICAgICAgICAgICAgeHhBY2NvdW50RmV0Y2ggPSAxOw0KICAgICAgICAgICAgZGVsZXRlIHh4QWNjb3VudEFkbWluTmFtZTsNCiAgICAgICAgICAgIHh4QWNjb3VudFJlYWxtSW5mbyA9IHt9Ow0KICAgICAgICAgICAgYW10c3RhY2suQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX0dldEFkbWluQWNsRW50cnkoZ2V0QWRtaW5BY2xFbnRyeVJlc3BvbnNlKTsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9FbnVtZXJhdGVVc2VyQWNsRW50cmllcygxLCBlbnVtZXJhdGVVc2VyQWNsRW50cmllc1Jlc3BvbnNlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGdldEFkbWluQWNsRW50cnlSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHJldHVybjsNCiAgICAgICAgICAgIHh4QWNjb3VudFJlYWxtSW5mb1stMV0gPSB7ICdBY2Nlc3NQZXJtaXNzaW9uJzogOTk5LCAnRGlnZXN0VXNlcm5hbWUnOiByZXNwb25zZS5Cb2R5WyJVc2VybmFtZSJdLCAnUmVhbG1zJzpudWxsIH07DQogICAgICAgICAgICB4eEFjY291bnRBZG1pbk5hbWUgPSByZXNwb25zZS5Cb2R5WyJVc2VybmFtZSJdOw0KICAgICAgICAgICAgdXBkYXRlQWNjb3VudHMoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVudW1lcmF0ZVVzZXJBY2xFbnRyaWVzUmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSByZXR1cm47DQogICAgICAgICAgICAvL2lmIChlcnJjaGVjayhzdGF0dXMsIHN0YWNrKSkgcmV0dXJuOw0KICAgICAgICAgICAgbWV0aG9kY2hlY2socmVzcG9uc2UpOw0KICAgICAgICAgICAgUVYoJ2dvMTEnLCB0cnVlKTsgLy8gU2hvdyAiVXNlciBBY2NvdW50cyIgb24gbGVmdCBwYW5lbA0KICAgICAgICAgICAgeHhBY2NvdW50RmV0Y2ggPSByZXNwb25zZS5Cb2R5WyJIYW5kbGVzIl0ubGVuZ3RoOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiByZXNwb25zZS5Cb2R5WyJIYW5kbGVzIl0pIHsNCiAgICAgICAgICAgICAgICB2YXIgaCA9IHJlc3BvbnNlLkJvZHlbIkhhbmRsZXMiXVtpXTsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfR2V0QWNsRW5hYmxlZFN0YXRlKGgsIGdldEFjbEVuYWJsZWRTdGF0ZVJlc3BvbnNlLCBoKTsNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfR2V0VXNlckFjbEVudHJ5RXgoaCwgZ2V0VXNlckFjbEVudHJ5RXhSZXNwb25zZSwgaCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICB1cGRhdGVBY2NvdW50cygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZ2V0VXNlckFjbEVudHJ5RXhSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICB4eEFjY291bnRGZXRjaC0tOw0KICAgICAgICAgICAgLy9pZiAoZXJyY2hlY2soc3RhdHVzLCBzdGFjaykpIHJldHVybjsNCiAgICAgICAgICAgIC8vbWV0aG9kY2hlY2socmVzcG9uc2UpOw0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgLy8gU29tZXRpbWVzIEludGVsIEFNVCB3aWxsIGp1c3QgZnJlYWsgb3V0IG9uIHRoaXMgY2FsbCwgaWYgaXQncyB0aGUgY2FzZSwganVzdCBjYXJyeSBvbi4NCiAgICAgICAgICAgICAgICByZXNwb25zZS5Cb2R5WyJIYW5kbGUiXSA9IHRhZzsNCiAgICAgICAgICAgICAgICBpZiAoIXJlc3BvbnNlLkJvZHlbIlJlYWxtcyJdKSByZXNwb25zZS5Cb2R5WyJSZWFsbXMiXSA9IFtdOw0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFBcnJheS5pc0FycmF5KHJlc3BvbnNlLkJvZHlbIlJlYWxtcyJdKSkgcmVzcG9uc2UuQm9keVsiUmVhbG1zIl0gPSBbcmVzcG9uc2UuQm9keVsiUmVhbG1zIl1dOyAvLyBJZiAiUmVhbG1zIiBpcyBub3QgYW4gYXJyYXksIGl0J3MgYmVjYXVzZSBpdCdzIGp1c3Qgb25lIHJlYWxtLiBGaXggaXMgc28gaXQncyBhbiBhcnJheSBvZiBvbmUuDQogICAgICAgICAgICAgICAgeHhBY2NvdW50UmVhbG1JbmZvW3RhZ10gPSByZXNwb25zZS5Cb2R5Ow0KICAgICAgICAgICAgICAgIHVwZGF0ZUFjY291bnRzKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBnZXRBY2xFbmFibGVkU3RhdGVSZXNwb25zZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICAvL2lmIChlcnJjaGVjayhzdGF0dXMsIHN0YWNrKSkgcmV0dXJuOw0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgLy8gU29tZXRpbWVzIEludGVsIEFNVCB3aWxsIGp1c3QgZnJlYWsgb3V0IG9uIHRoaXMgY2FsbCwgaWYgaXQncyB0aGUgY2FzZSwganVzdCBjYXJyeSBvbi4NCiAgICAgICAgICAgICAgICB4eEFjY291bnRFbmFibGVkSW5mb1t0YWddID0gcmVzcG9uc2UuQm9keTsNCiAgICAgICAgICAgICAgICB1cGRhdGVBY2NvdW50cygpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2V0QWNsRW5hYmxlZFN0YXRlUmVzcG9uc2Uoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMsIHRhZykgew0KICAgICAgICAgICAgaWYgKGVycmNoZWNrKHN0YXR1cywgc3RhY2spKSByZXR1cm47DQogICAgICAgICAgICBtZXRob2RjaGVjayhyZXNwb25zZSk7DQogICAgICAgICAgICBhbXRzdGFjay5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfR2V0QWNsRW5hYmxlZFN0YXRlKHRhZywgZ2V0QWNsRW5hYmxlZFN0YXRlUmVzcG9uc2UsIHRhZyk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1cGRhdGVBY2NvdW50cygpIHsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRGZXRjaCA+IDApIHJldHVybjsNCiAgICAgICAgICAgIHZhciB4ID0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSB0aGUgSW50ZWwmcmVnOyBBTVQgdXNlciBhY2NvdW50cyBmb3IgdGhpcyBjb21wdXRlci48YnI+PGJyPiI7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4QWNjb3VudFJlYWxtSW5mbykgew0KICAgICAgICAgICAgICAgIHZhciByID0geHhBY2NvdW50UmVhbG1JbmZvW2ldLCBuYW1lLCBoaWRkZW4gPSBmYWxzZSwgc3RhdGUgPSAwOw0KICAgICAgICAgICAgICAgIGlmIChyWyJEaWdlc3RVc2VybmFtZSJdKSB7IG5hbWUgPSByWyJEaWdlc3RVc2VybmFtZSJdOyBoaWRkZW4gPSAobmFtZVswXSA9PSAnJCcgJiYgbmFtZVsxXSA9PSAnJCcpOyB9IGVsc2UgeyBuYW1lID0gR2V0U2lkU3RyaW5nKGF0b2IoclsiS2VyYmVyb3NVc2VyU2lkIl0pKTsgfQ0KICAgICAgICAgICAgICAgIGlmICh4eEFjY291bnRFbmFibGVkSW5mb1tpXSAmJiBuYW1lICE9ICckJE9zQWRtaW4nKSB7IHN0YXRlID0gKHh4QWNjb3VudEVuYWJsZWRJbmZvW2ldWydFbmFibGVkJ10gPT0gdHJ1ZSk/MToyOyB9DQogICAgICAgICAgICAgICAgaWYgKHNob3dIaWRkZW5BY2NvdW50cyB8fCAhaGlkZGVuKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciByYiA9ICIiOw0KICAgICAgICAgICAgICAgICAgICBpZiAoclsiQWNjZXNzUGVybWlzc2lvbiJdICE9IDk5OSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN0YXRlID09IDIpIHsgcmIgKz0gIkRpc2FibGVkLCAiOyB9DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmMgPSAwOw0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpIGluIHJbIlJlYWxtcyJdKSB7IGlmIChhbXRzdGFjay5SZWFsbU5hbWVzW3JbIlJlYWxtcyJdW2ldXSAhPSAnJykgeyByYysrOyB9IH0gLy8gQ291bnQgb25seSByZWFsbXMgdGhhdCBoYXZlIGEgbmFtZSwgcmVtb3ZpbmcgcmVzZXJ2ZWQgcmVhbG1zLg0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJbIlJlYWxtcyJdLmluZGV4T2YoMjApID49IDApIHJiICs9ICJBdWRpdG9yLCAiOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJbIlJlYWxtcyJdLmluZGV4T2YoMykgPj0gMCkgeyByYiArPSAiQWRtaW5pc3RyYXRvciI7IH0gZWxzZSB7IGlmIChyYyA9PSAxKSB7IHJiICs9ICIxIHJlYWxtIjsgfSBlbHNlIHsgcmIgKz0gcmMgKyAiIHJlYWxtcyI7IH0gfQ0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgcmIgKz0gIkFkbWluaXN0cmF0b3IiOw0KICAgICAgICAgICAgICAgICAgICAgICAgclsiSGFuZGxlIl0gPSAtMTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93VXNlckRldGFpbHMoIiArIHJbIkhhbmRsZSJdICsgIik+PGRpdiBzdHlsZT1mbG9hdDpyaWdodD4iOw0KICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdGUgPiAwICYmIHh4QWNjb3VudEFkbWluTmFtZSkgeCArPSAiICIgKyBBZGRCdXR0b24yKChzdGF0ZSA9PSAxPydEaXNhYmxlJzonRW5hYmxlJyksICJjaGFuZ2VBY2NvdW50U3RhdGVCdXR0b24oZXZlbnQsIiArIHJbIkhhbmRsZSJdICsgIiwiICsgc3RhdGUgKyAiKSIpOw0KICAgICAgICAgICAgICAgICAgICBpZiAoIWhpZGRlbiAmJiB4eEFjY291bnRBZG1pbk5hbWUpIHggKz0gIiAiICsgQWRkQnV0dG9uMigiRWRpdC4uLiIsICJjaGFuZ2VBY2NvdW50QnV0dG9uKGV2ZW50LCIgKyByWyJIYW5kbGUiXSArICIpIik7DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4O3dpZHRoOjMzMHB4O2Zsb2F0OmxlZnQ7b3ZlcmZsb3cteDpoaWRkZW4gdGl0bGU9JyIgKyBuYW1lICsgIic+PGI+IiArIG5hbWUgKyAiPC9iPjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PiIgKyByYiArICI8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHZhciB5ID0gIjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ7bWFyZ2luLXJpZ2h0OjhweD48YSB0aXRsZT0nVG9nZ2xlIGhpZGRlbiBhY2NvdW50cycgc3R5bGU9Y29sb3I6Z3JheTtjdXJzb3I6cG9pbnRlciBvbmNsaWNrPXRvZ2dsZUFjY291bnRCdXR0b24oKT4iICsgKHNob3dIaWRkZW5BY2NvdW50cz8nJiN4MjVCMjsnOicmI3gyNUJDOycpICsgIjwvYT48L2Rpdj48ZGl2PiZuYnNwOyIgKyBBZGRSZWZyZXNoQnV0dG9uKCJ4eEFjY291bnRGZXRjaD05OTk7UHVsbFVzZXJJbmZvKCkiKTsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHkgKz0gQWRkQnV0dG9uKCJOZXcgQWNjb3VudCIsICJuZXdBY2NvdW50QnV0dG9uKCkiKTsNCiAgICAgICAgICAgIHggKz0gIjxicj48dGQgY2xhc3M9cjE+IiArIFRhYmxlRW5kKHkgKyAiPC9kaXY+Iik7DQogICAgICAgICAgICBRSCgnaWRfVGFibGVVc2VyQWNjb3VudHMnLCB4KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHRvZ2dsZUFjY291bnRCdXR0b24oKSB7DQogICAgICAgICAgICBzaG93SGlkZGVuQWNjb3VudHMgPSAhc2hvd0hpZGRlbkFjY291bnRzOw0KICAgICAgICAgICAgdXBkYXRlQWNjb3VudHMoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHJlbW92ZVVzZXJBY2xFbnRyeVJlc3BvbnNlKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzLCB0YWcpIHsNCiAgICAgICAgICAgIGlmIChtZXRob2RjaGVjayhyZXNwb25zZSkpIHJldHVybjsNCiAgICAgICAgICAgIFB1bGxVc2VySW5mbygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2hhbmdlQWNjb3VudFN0YXRlQnV0dG9uKGUsIGgsIHMpIHsNCiAgICAgICAgICAgIGhhbHRFdmVudChlKTsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9BdXRob3JpemF0aW9uU2VydmljZV9TZXRBY2xFbmFibGVkU3RhdGUoaCwgKHM9PTE/ZmFsc2U6dHJ1ZSksIHNldEFjbEVuYWJsZWRTdGF0ZVJlc3BvbnNlLCBoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGNoYW5nZUFjY291bnRCdXR0b24oZSwgaCkgew0KICAgICAgICAgICAgaGFsdEV2ZW50KGUpOw0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdXBkYXRlUmVhbG1zKHh4QWNjb3VudFJlYWxtSW5mb1toXVsiUmVhbG1zIl0pOw0KICAgICAgICAgICAgZDJ1c2VybmFtZS52YWx1ZSA9IHh4QWNjb3VudFJlYWxtSW5mb1toXVsiRGlnZXN0VXNlcm5hbWUiXSA/IHh4QWNjb3VudFJlYWxtSW5mb1toXVsiRGlnZXN0VXNlcm5hbWUiXSA6IEdldFNpZFN0cmluZyhhdG9iKHh4QWNjb3VudFJlYWxtSW5mb1toXVsiS2VyYmVyb3NVc2VyU2lkIl0pKTsNCiAgICAgICAgICAgIGQycGFzc3dvcmQxLnZhbHVlID0gZDJwYXNzd29yZDIudmFsdWUgPSAnJzsNCiAgICAgICAgICAgIGQycGVybWlzc2lvbi52YWx1ZSA9IHh4QWNjb3VudFJlYWxtSW5mb1toXVsiQWNjZXNzUGVybWlzc2lvbiJdOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgyLCAiRWRpdCBBY2NvdW50IiwgKChoPT0tMSk/Mzo3KSwgZnVuY3Rpb24gKGJ1dHRvbikgeyBjaGFuZ2VBY2NvdW50QnV0dG9uRXgoaCwgYnV0dG9uKTsgfSk7IC8vIElmIGhhbmRsZSBpcyAtMSwgb25seSBkaXNwbGF5IE9LL0NhbmNlbCBidXR0b25zLCBpZiBub3QsIGFsc28gZGlzcGxheSBkZWxldGUgYnV0dG9uLg0KICAgICAgICAgICAgdXBkYXRlQWNjb3VudERpYWxvZygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gbmV3QWNjb3VudEJ1dHRvbigpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHVwZGF0ZVJlYWxtcyhbXSk7DQogICAgICAgICAgICBkMnVzZXJuYW1lLnZhbHVlID0gZDJwYXNzd29yZDEudmFsdWUgPSBkMnBhc3N3b3JkMi52YWx1ZSA9ICcnOw0KICAgICAgICAgICAgZDJwZXJtaXNzaW9uLnZhbHVlID0gMjsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMiwgIk5ldyBBY2NvdW50IiwgMywgZnVuY3Rpb24gKCkgeyBjaGFuZ2VBY2NvdW50QnV0dG9uRXgobnVsbCwgMSk7IH0pOw0KICAgICAgICAgICAgdXBkYXRlQWNjb3VudERpYWxvZygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2hhbmdlQWNjb3VudEJ1dHRvbkV4KGgsIGJ1dHRvbikgew0KICAgICAgICAgICAgaWYgKGJ1dHRvbiA9PSAxKSB7IC8vIE9LIEJ1dHRvbg0KICAgICAgICAgICAgICAgIHZhciByZWFsbXMgPSBbXSwgdXNlcm5hbWUgPSBkMnVzZXJuYW1lLnZhbHVlLCBwZXJtaXNzaW9uID0gZDJwZXJtaXNzaW9uLnZhbHVlLCBwYXNzd29yZCA9IGQycGFzc3dvcmQxLnZhbHVlLCBzaWQgPSBHZXRTaWRCeXRlQXJyYXkoUSgnZDJ1c2VybmFtZScpLnZhbHVlKSwgZCA9IG51bGw7DQogICAgICAgICAgICAgICAgaWYgKHVzZXJuYW1lLmxlbmd0aCA9PSAwIHx8IHBhc3N3b3JkICE9IGQycGFzc3dvcmQyLnZhbHVlKSB7IG1lc3NhZ2Vib3goIkFjY291bnQgRXJyb3IiLCAiSW52YWxpZCBQYXJhbWV0ZXJzIik7IHJldHVybjsgfQ0KICAgICAgICAgICAgICAgIGlmIChzaWQgPT0gbnVsbCkgeyBkID0gd2luZG93LmJ0b2EocnN0cl9tZDUodXNlcm5hbWUgKyAiOiIgKyBhbXRzeXNzdGF0ZVsnQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlWyJEaWdlc3RSZWFsbSJdICsgIjoiICsgcGFzc3dvcmQpKTsgfSBlbHNlIHsgdXNlcm5hbWUgPSBudWxsOyBzaWQgPSBidG9hKHNpZCk7IH0NCiAgICAgICAgICAgICAgICBpZiAoaCAhPSAtMSkgeyBmb3IgKHZhciB5IGluIGFtdHN0YWNrLlJlYWxtTmFtZXMpIHsgaWYgKCgoYW10c3RhY2suUmVhbG1OYW1lc1t5XSkgfHwgKHkgPT0gMykpICYmIFEoJ3J4JyArIHkpLmNoZWNrZWQpIHsgcmVhbG1zLnB1c2goeSk7IH0gfSB9DQogICAgICAgICAgICAgICAgaWYgKGggPT0gbnVsbCkgeyBhbXRzdGFjay5BTVRfQXV0aG9yaXphdGlvblNlcnZpY2VfQWRkVXNlckFjbEVudHJ5RXgodXNlcm5hbWUsIGQsIHNpZCwgcGVybWlzc2lvbiwgcmVhbG1zLCB1c2VyQWNsRW50cnlFeFJlc3BvbnNlKTsgfQ0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKGggPT0gLTEpIHsgYW10c3RhY2suQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX1NldEFkbWluQWNsRW50cnlFeCh1c2VybmFtZSwgZCwgdXNlckFjbEVudHJ5RXhSZXNwb25zZSk7IH0NCiAgICAgICAgICAgICAgICBlbHNlIHsgYW10c3RhY2suQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX1VwZGF0ZVVzZXJBY2xFbnRyeUV4KGgsIHVzZXJuYW1lLCBkLCBzaWQsIHBlcm1pc3Npb24sIHJlYWxtcywgdXNlckFjbEVudHJ5RXhSZXNwb25zZSk7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChidXR0b24gPT0gMikgeyAvLyBEZWxldGUgQnV0dG9uDQogICAgICAgICAgICAgICAgYW10c3RhY2suQU1UX0F1dGhvcml6YXRpb25TZXJ2aWNlX1JlbW92ZVVzZXJBY2xFbnRyeShoLCByZW1vdmVVc2VyQWNsRW50cnlSZXNwb25zZSk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2VyQWNsRW50cnlFeFJlc3BvbnNlKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzLCB0YWcpIHsgaWYgKG1ldGhvZGNoZWNrKHJlc3BvbnNlKSkgcmV0dXJuOyBQdWxsVXNlckluZm8oKTsgfQ0KICAgICAgICBmdW5jdGlvbiB1cGRhdGVSZWFsbXMocikgew0KICAgICAgICAgICAgUVYoJ2lkX2QycGVybWlzc2lvbnMnLCByICE9IG51bGwpOw0KICAgICAgICAgICAgaWYgKHIgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgIHZhciB4ID0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggb25jaGFuZ2U9dXBkYXRlQWNjb3VudERpYWxvZygpIGlkPXJ4MycgKyAoKHIuaW5kZXhPZigzKSA+PSAwKT8nIGNoZWNrZWQnOicnKSArICc+QWRtaW5pc3RyYXRvcjwvbGFiZWw+PC9saT48aHIgLz4nOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIHkgaW4gYW10c3RhY2suUmVhbG1OYW1lcykgeyB2YXIgYyA9ICcnOyBpZiAoci5pbmRleE9mKHBhcnNlSW50KHkpKSA+PSAwKSBjID0gJyBjaGVja2VkJzsgaWYgKGFtdHN0YWNrLlJlYWxtTmFtZXNbeV0pIHggKz0gJzxsaT48bGFiZWw+PGlucHV0IHR5cGU9Y2hlY2tib3ggb25jaGFuZ2U9dXBkYXRlQWNjb3VudERpYWxvZygpIGlkPXJ4JyArIHkgKyBjICsgJz4nICsgYW10c3RhY2suUmVhbG1OYW1lc1t5XSArICc8L2xhYmVsPjwvbGk+JzsgfQ0KICAgICAgICAgICAgICAgIFFIKCdpZF9kMnJlYWxtcycsIHgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlQWNjb3VudERpYWxvZygpIHsNCiAgICAgICAgICAgIHZhciBvayA9IGZhbHNlOw0KICAgICAgICAgICAgZm9yICh2YXIgeSBpbiBhbXRzdGFjay5SZWFsbU5hbWVzKSB7IGlmICgoKGFtdHN0YWNrLlJlYWxtTmFtZXNbeV0pIHx8ICh5ID09IDMpKSAmJiBRKCdyeCcgKyB5KS5jaGVja2VkKSB7IG9rID0gdHJ1ZTsgfSB9DQogICAgICAgICAgICBvayAmPSAoZDJ1c2VybmFtZS52YWx1ZS5sZW5ndGggPiAwICYmIHBhc3N3b3JkY2hlY2soZDJwYXNzd29yZDEudmFsdWUpICYmIGQycGFzc3dvcmQxLnZhbHVlID09IGQycGFzc3dvcmQyLnZhbHVlKTsNCiAgICAgICAgICAgIFFFKCdpZHhfZGxnT2tCdXR0b24nLCBvayk7DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgeHhVc2VyUGVybWlzc2lvbnMgPSBbJ0xvY2FsIG9ubHknICwgJ05ldHdvcmsgb25seScsICdBbGwgKExvY2FsICYgTmV0d29yayknXTsNCiAgICAgICAgZnVuY3Rpb24gc2hvd1VzZXJEZXRhaWxzKGgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBhID0geHhBY2NvdW50UmVhbG1JbmZvW2hdLCB4ID0gJzxkaXYgc3R5bGU9dGV4dC1hbGlnbjpsZWZ0Pic7DQogICAgICAgICAgICB2YXIgaSwgbiA9IGFbIkRpZ2VzdFVzZXJuYW1lIl07DQogICAgICAgICAgICBpZiAoIW4pIG4gPSBHZXRTaWRTdHJpbmcoYXRvYihhWyJLZXJiZXJvc1VzZXJTaWQiXSkpOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIk5hbWUiLCBuKTsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRFbmFibGVkSW5mb1toXSkgeyB4ICs9IGFkZEh0bWxWYWx1ZSgiU3RhdGUiLCAoKHh4QWNjb3VudEVuYWJsZWRJbmZvW2hdWydFbmFibGVkJ10gPT0gdHJ1ZSk/J0VuYWJsZWQnOidEaXNhYmxlZCcpKTsgfQ0KICAgICAgICAgICAgaWYgKG4gPT0geHhBY2NvdW50QWRtaW5OYW1lKSB7DQogICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlBlcm1pc3Npb24iLCAiQWRtaW5pc3RyYXRvciIpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiUGVybWlzc2lvbiIsIHh4VXNlclBlcm1pc3Npb25zW2FbIkFjY2Vzc1Blcm1pc3Npb24iXV0pOw0KICAgICAgICAgICAgICAgIHZhciB5ID0gJyc7DQogICAgICAgICAgICAgICAgaWYgKGFbIlJlYWxtcyJdLmluZGV4T2YoMykgPj0gMCkgew0KICAgICAgICAgICAgICAgICAgICB5ID0gJ0FkbWluaXN0cmF0b3InOw0KICAgICAgICAgICAgICAgICAgICBpZiAoYVsiUmVhbG1zIl0uaW5kZXhPZigyMCkgPj0gMCkgeSArPSAiLCBBdWRpdG9yIjsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBmb3IgKGkgaW4geHhBY2NvdW50UmVhbG1JbmZvW2hdWyJSZWFsbXMiXSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFtdHN0YWNrLlJlYWxtTmFtZXNbYVsiUmVhbG1zIl1baV1dICE9ICcnKSB7IC8vIFJlbW92ZSBibGFuayByZXNlcnZlZCByZWFsbXMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoeS5sZW5ndGggPiAwKSB5ICs9ICIsICI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeSArPSBhbXRzdGFjay5SZWFsbU5hbWVzW2FbIlJlYWxtcyJdW2ldXTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAoeS5sZW5ndGggPT0gMCkgeSA9ICdOb25lJzsNCiAgICAgICAgICAgICAgICB4ICs9IGFkZEh0bWxWYWx1ZSgiUmVhbG1zIiwgIiIpICsgIjxiPiIgKyB5ICsgIjwvYj4iOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSAiPC9kaXY+IjsNCiAgICAgICAgICAgIG1lc3NhZ2Vib3goIkFjY291bnQgIiArIG4sIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gV1NNQU4gQlJPV1NFUiBQQU5FTA0KICAgICAgICAvLw0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gUmVtb3RlIFRlcm1pbmFsDQogICAgICAgIC8vDQoNCg0KICAgICAgICAvLw0KICAgICAgICAvLyBSZW1vdGUgRGVza3RvcA0KICAgICAgICAvLw0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gUmVtb3RlIElERVINCiAgICAgICAgLy8NCg0KDQoNCg0KICAgICAgICAvLw0KICAgICAgICAvLyBSZW1vdGUgQWNjZXNzDQogICAgICAgIC8vDQoNCiAgICAgICAgdmFyIHh4UmVtb3RlQWNjZXNzID0gbnVsbDsNCiAgICAgICAgdmFyIHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uID0gbnVsbDsNCiAgICAgICAgdmFyIHh4Q2lyYVNlcnZlcnMgPSBudWxsOw0KICAgICAgICB2YXIgeHhVc2VySW5pdGlhdGVkQ2lyYSA9IG51bGw7DQogICAgICAgIHZhciB4eFVzZXJJbml0aWF0ZWRFbmFibGVkU3RhdGUgPSB7IDMyNzY4OiAnRGlzYWJsZWQnLCAzMjc2OTogJ0JJT1MgZW5hYmxlZCcsIDMyNzcwOiAnT1MgZW5hYmxlJywgMzI3NzE6ICdCSU9TICYgT1MgZW5hYmxlZCcgfTsNCiAgICAgICAgdmFyIHh4UmVtb3RlQWNjZXNzQ3JlZGVudGlhTGlua3MgPSBudWxsOw0KICAgICAgICB2YXIgeHhNUFNVc2VyUGFzcyA9IG51bGw7DQogICAgICAgIHZhciB4eFBvbGljaWVzID0gbnVsbDsNCg0KICAgICAgICBmdW5jdGlvbiBQdWxsUmVtb3RlQWNjZXNzKCkgew0KICAgICAgICAgICAgLy8gV2Ugb25seSBkZWFsIHdpdGggcmVtb3RlIGFjY2VzcyBzdGFydGluZyB3aXRoIEludGVsIEFNVCA2IGFuZCBiZXlvbmQNCg0KICAgICAgICAgICAgdmFyIHJlcXVlc3RzID0gWyIqQU1UX0Vudmlyb25tZW50RGV0ZWN0aW9uU2V0dGluZ0RhdGEiLCAiQU1UX01hbmFnZW1lbnRQcmVzZW5jZVJlbW90ZVNBUCIsICJBTVRfUmVtb3RlQWNjZXNzQ3JlZGVudGlhbENvbnRleHQiLCAiQU1UX1JlbW90ZUFjY2Vzc1BvbGljeUFwcGxpZXNUb01QUyIsICJBTVRfUmVtb3RlQWNjZXNzUG9saWN5UnVsZSIsICIqQU1UX1VzZXJJbml0aWF0ZWRDb25uZWN0aW9uU2VydmljZSIsICJBTVRfTVBTVXNlcm5hbWVQYXNzd29yZCJdOw0KICAgICAgICAgICAgaWYgKGFtdHZlcnNpb24gPiAxMSkgeyByZXF1ZXN0cy5wdXNoKCIqSVBTX0hUVFBQcm94eVNlcnZpY2UiLCAiSVBTX0hUVFBQcm94eUFjY2Vzc1BvaW50Iik7IH0NCiAgICAgICAgICAgIGFtdHN0YWNrLkJhdGNoRW51bShudWxsLCByZXF1ZXN0cywgcHJvY2Vzc1JlbW90ZTEpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcHJvY2Vzc1JlbW90ZTEoc3RhY2ssIG5hbWUsIHJlc3BvbnNlcywgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDQwMCkgcmV0dXJuOw0KICAgICAgICAgICAgaWYgKChlcnJjaGVjayhzdGF0dXMsIHN0YWNrKSkgfHwgKHJlc3BvbnNlc1siQU1UX1VzZXJJbml0aWF0ZWRDb25uZWN0aW9uU2VydmljZSJdID09IHVuZGVmaW5lZCB8fCByZXNwb25zZXNbIkFNVF9Vc2VySW5pdGlhdGVkQ29ubmVjdGlvblNlcnZpY2UiXS5yZXNwb25zZSA9PSB1bmRlZmluZWQpKSByZXR1cm47DQogICAgICAgICAgICBRVignZ28xNycsIHRydWUpOyAvLyBSZW1vdGUgQWNjZXNzDQogICAgICAgICAgICB4eFJlbW90ZUFjY2VzcyA9IHJlc3BvbnNlczsNCiAgICAgICAgICAgIHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uID0gcmVzcG9uc2VzWyJBTVRfRW52aXJvbm1lbnREZXRlY3Rpb25TZXR0aW5nRGF0YSJdLnJlc3BvbnNlOw0KICAgICAgICAgICAgeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXSA9IE1ha2VUb0FycmF5KHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uWydEZXRlY3Rpb25TdHJpbmdzJ10pOw0KICAgICAgICAgICAgeHhDaXJhU2VydmVycyA9IHJlc3BvbnNlc1siQU1UX01hbmFnZW1lbnRQcmVzZW5jZVJlbW90ZVNBUCJdLnJlc3BvbnNlczsNCiAgICAgICAgICAgIHh4VXNlckluaXRpYXRlZENpcmEgPSByZXNwb25zZXNbIkFNVF9Vc2VySW5pdGlhdGVkQ29ubmVjdGlvblNlcnZpY2UiXS5yZXNwb25zZTsNCiAgICAgICAgICAgIHh4UmVtb3RlQWNjZXNzQ3JlZGVudGlhTGlua3MgPSByZXNwb25zZXNbIkFNVF9SZW1vdGVBY2Nlc3NDcmVkZW50aWFsQ29udGV4dCJdLnJlc3BvbnNlczsNCiAgICAgICAgICAgIHh4TVBTVXNlclBhc3MgPSByZXNwb25zZXNbIkFNVF9NUFNVc2VybmFtZVBhc3N3b3JkIl0ucmVzcG9uc2VzOw0KDQogICAgICAgICAgICAvLyBGaWd1cmUgb3V0IHBvbGljaWVzIGF0dGFjaGVkIHRvIHNlcnZlcnMuIENyZWF0ZSBhIHBvbGljeSB0eXBlIHRvIHNlcnZlciB0YWJsZS4NCiAgICAgICAgICAgIHh4UG9saWNpZXMgPSB7ICdVc2VyJzogW10sICdBbGVydCc6IFtdLCAnUGVyaW9kaWMnOiBbXSB9Ow0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiByZXNwb25zZXNbIkFNVF9SZW1vdGVBY2Nlc3NQb2xpY3lBcHBsaWVzVG9NUFMiXS5yZXNwb25zZXMpIHsNCiAgICAgICAgICAgICAgICB2YXIgcG9saWN5ID0gcmVzcG9uc2VzWyJBTVRfUmVtb3RlQWNjZXNzUG9saWN5QXBwbGllc1RvTVBTIl0ucmVzcG9uc2VzW2ldOw0KICAgICAgICAgICAgICAgIHZhciBzZXJ2ZXIgPSBDbG9uZShnZXRJdGVtKHh4Q2lyYVNlcnZlcnMsICJOYW1lIiwgZ2V0SXRlbShwb2xpY3lbJ01hbmFnZWRFbGVtZW50J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXSwgIkBOYW1lIiwgIk5hbWUiKVsnVmFsdWUnXSkpOw0KICAgICAgICAgICAgICAgIHNlcnZlci5NcHNUeXBlID0gcG9saWN5WydNcHNUeXBlJ107IC8vIE1wc1R5cGUgd2FzIGFkZGVkIGluIEludGVsIEFNVCAxMS42DQogICAgICAgICAgICAgICAgdmFyIHB0eXBlID0gKGdldEl0ZW0ocG9saWN5WydQb2xpY3lTZXQnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddLCAiQE5hbWUiLCAiUG9saWN5UnVsZU5hbWUiKVsnVmFsdWUnXSkuc3BsaXQoJyAnKVswXTsNCiAgICAgICAgICAgICAgICB4eFBvbGljaWVzW3B0eXBlXS5wdXNoKHNlcnZlcik7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHVwZGF0ZVJlbW90ZUFjY2VzcygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlUmVtb3RlQWNjZXNzKCkgew0KICAgICAgICAgICAgaWYgKHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uID09IG51bGwpIHJldHVybjsNCiAgICAgICAgICAgIHZhciB4ID0gJycsIGUgPSAnRGlzYWJsZWQnLCBjaXJhUHJveHlTdXBwb3J0ID0gKHh4UmVtb3RlQWNjZXNzWyJJUFNfSFRUUFByb3h5U2VydmljZSJdICYmIHh4UmVtb3RlQWNjZXNzWyJJUFNfSFRUUFByb3h5QWNjZXNzUG9pbnQiXSk7DQogICAgICAgICAgICBpZiAoeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXSAmJiB4eEVudmlyb25lbWVudERldGVjdGlvblsnRGV0ZWN0aW9uU3RyaW5ncyddLmxlbmd0aCA+IDApIHsgZSA9ICdFbmFibGVkLCAnICsgeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXS5sZW5ndGggKyAnIGRvbWFpbicgKyAoeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXS5sZW5ndGggPiAxPydzJzonJyk7IH0NCg0KICAgICAgICAgICAgLy8gR2VuZXJhbCBzZXR0aW5ncw0KICAgICAgICAgICAgeCArPSBUYWJsZVN0YXJ0KCk7DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkVudmlyb25tZW50IGRldGVjdGlvbiIsIGFkZExpbmsoZSwgJ2VkaXRFbnZpcm9ubWVudERldGVjdGlvbigpJykpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVudHJ5KCJVc2VyIGluaXRpYXRpb24gb3B0aW9ucyIsIGFkZExpbmtDb25kaXRpb25hbCh4eFVzZXJJbml0aWF0ZWRFbmFibGVkU3RhdGVbeHhVc2VySW5pdGlhdGVkQ2lyYVsnRW5hYmxlZFN0YXRlJ11dLCAnZWRpdFVzZXJJbml0aWF0ZWRDaXJhKCknLCB4eEFjY291bnRBZG1pbk5hbWUpKTsNCiAgICAgICAgICAgIHZhciB5ID0gJzxpPk5vbmU8L2k+JzsNCiAgICAgICAgICAgIGlmICh4eFBvbGljaWVzWydVc2VyJ10ubGVuZ3RoID4gMCkgeyB5ID0gJyc7IGZvciAodmFyIGkgaW4geHhQb2xpY2llc1snVXNlciddKSB7IGlmICh5Lmxlbmd0aCA+IDApIHkgKz0gJywgJzsgeSArPSB4eFBvbGljaWVzWydVc2VyJ11baV1bJ0FjY2Vzc0luZm8nXTsgaWYgKHh4UG9saWNpZXNbJ1VzZXInXVtpXS5NcHNUeXBlID09IDEpIHsgeSArPSAnIChDSUxBKSc7IH0gfSB9DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIlVzZXIgaW5pdGlhdGVkIGNvbm5lY3Rpb24iLCBhZGRMaW5rQ29uZGl0aW9uYWwoeSwgJ2VkaXRNcHNQb2xpY3koIlVzZXIiKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgdmFyIHkgPSAnPGk+Tm9uZTwvaT4nOw0KICAgICAgICAgICAgaWYgKHh4UG9saWNpZXNbJ0FsZXJ0J10ubGVuZ3RoID4gMCkgeyB5ID0gJyc7IGZvciAodmFyIGkgaW4geHhQb2xpY2llc1snQWxlcnQnXSkgeyBpZiAoeS5sZW5ndGggPiAwKSB5ICs9ICcsICc7IHkgKz0geHhQb2xpY2llc1snQWxlcnQnXVtpXVsnQWNjZXNzSW5mbyddOyBpZiAoeHhQb2xpY2llc1snQWxlcnQnXVtpXS5NcHNUeXBlID09IDEpIHsgeSArPSAnIChDSUxBKSc7IH0gfSB9DQogICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIkFsZXJ0IGluaXRpYXRlZCBjb25uZWN0aW9uIiwgYWRkTGlua0NvbmRpdGlvbmFsKHksICdlZGl0TXBzUG9saWN5KCJBbGVydCIpJywgeHhBY2NvdW50QWRtaW5OYW1lKSk7DQogICAgICAgICAgICB2YXIgeSA9ICc8aT5Ob25lPC9pPic7DQogICAgICAgICAgICBpZiAoeHhQb2xpY2llc1snUGVyaW9kaWMnXS5sZW5ndGggPiAwKSB7IHkgPSAnJzsgZm9yICh2YXIgaSBpbiB4eFBvbGljaWVzWydQZXJpb2RpYyddKSB7IGlmICh5Lmxlbmd0aCA+IDApIHkgKz0gJywgJzsgeSArPSB4eFBvbGljaWVzWydQZXJpb2RpYyddW2ldWydBY2Nlc3NJbmZvJ107IGlmICh4eFBvbGljaWVzWydQZXJpb2RpYyddW2ldLk1wc1R5cGUgPT0gMSkgeyB5ICs9ICcgKENJTEEpJzsgfSB9IH0NCiAgICAgICAgICAgIHZhciBwZXJpb2RpY1BvbGljeSA9IGdldEl0ZW0oeHhSZW1vdGVBY2Nlc3NbIkFNVF9SZW1vdGVBY2Nlc3NQb2xpY3lSdWxlIl0ucmVzcG9uc2VzLCAiUG9saWN5UnVsZU5hbWUiLCAiUGVyaW9kaWMiKTsNCiAgICAgICAgICAgIGlmIChwZXJpb2RpY1BvbGljeSkgew0KICAgICAgICAgICAgICAgIHZhciBleGRhdGEgPSBhdG9iKHBlcmlvZGljUG9saWN5WydFeHRlbmRlZERhdGEnXSk7DQogICAgICAgICAgICAgICAgaWYgKFJlYWRJbnQoZXhkYXRhLCAwKSA9PSAwKSB7IHkgKz0gJywgZWFjaCAnICsgUmVhZEludChleGRhdGEsIDQpICsgJyBzZWNvbmRzJzsgfQ0KICAgICAgICAgICAgICAgIGlmIChSZWFkSW50KGV4ZGF0YSwgMCkgPT0gMSkgeyB2YXIgaG91cnMgPSBSZWFkSW50KGV4ZGF0YSwgNCk7IHZhciBtaW51dGVzID0gUmVhZEludChleGRhdGEsIDgpOyBpZiAobWludXRlcyA8IDEwKSBtaW51dGVzID0gJzAnICsgbWludXRlczsgeSArPSAnLCBhdCAnICsgaG91cnMgKyAiOiIgKyBtaW51dGVzICsgJyBkYWlseSc7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gVGFibGVFbnRyeSgiUGVyaW9kaWMgY29ubmVjdGlvbiIsIGFkZExpbmtDb25kaXRpb25hbCh5LCAnZWRpdE1wc1BvbGljeSgiUGVyaW9kaWMiKScsIHh4QWNjb3VudEFkbWluTmFtZSkpOw0KICAgICAgICAgICAgeCArPSBUYWJsZUVuZCgpOw0KDQogICAgICAgICAgICAvLyBTaG93IE1QUyBzZXJ2ZXJzDQogICAgICAgICAgICB4ICs9ICI8YnI+IjsNCiAgICAgICAgICAgIHggKz0gVGFibGVTdGFydDIoKTsNCiAgICAgICAgICAgIHggKz0gIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCByZW1vdGUgbWFuYWdlbWVudCBzZXJ2ZXJzLjxicj48YnI+IjsNCiAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzLmxlbmd0aCA9PSAwKSB7DQogICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD48YnI+PGk+Tm8gcmVtb3RlIHNlcnZlcnMgZm91bmQuPC9pPjwvZGl2Pjxicj4iOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4Q2lyYVNlcnZlcnMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGRlc2MgPSAnOicgKyB4eENpcmFTZXJ2ZXJzW2ldWydQb3J0J107DQogICAgICAgICAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzW2ldWydDTiddKSBkZXNjICs9ICcsICcgKyB4eENpcmFTZXJ2ZXJzW2ldWydDTiddOw0KICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93U2VydmVyRGV0YWlscygiICsgaSArICIpPjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4PjxiPiIgKyB4eENpcmFTZXJ2ZXJzW2ldWyJBY2Nlc3NJbmZvIl0gKyAiPC9iPiIgKyBFc2NhcGVIdG1sKGRlc2MpICsgIjwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAvLyBTaG93IE1QUyBwcm94aWVzIGlmIHN1cHBvcnRlZA0KICAgICAgICAgICAgaWYgKGNpcmFQcm94eVN1cHBvcnQpIHsNCiAgICAgICAgICAgICAgICB4ICs9ICI8YnI+TWFuYWdlIEhUVFAgcHJveGllcyB1c2VkIGZvciBtYW5hZ2VtZW50IGNvbm5lY3Rpb25zLjxicj48YnI+IjsNCiAgICAgICAgICAgICAgICB2YXIgcHJveHlTZXJ2aWNlID0geHhSZW1vdGVBY2Nlc3NbIklQU19IVFRQUHJveHlTZXJ2aWNlIl0ucmVzcG9uc2U7DQogICAgICAgICAgICAgICAgdmFyIHByb3hpZXMgPSB4eFJlbW90ZUFjY2Vzc1siSVBTX0hUVFBQcm94eUFjY2Vzc1BvaW50Il0ucmVzcG9uc2VzOw0KICAgICAgICAgICAgICAgIGlmIChwcm94aWVzLmxlbmd0aCA9PSAwKSB7DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPjxpPk5vIHByb3hpZXMgY29uZmlndXJlZC48L2k+PC9kaXY+PGJyPiI7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBwcm94aWVzKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAvL3ggKz0gIjxkaXYgY2xhc3M9aXRlbUJhciBvbmNsaWNrPXNob3dQcm94eURldGFpbHMoIiArIGkgKyAiKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48Yj4iICsgRXNjYXBlSHRtbChwcm94aWVzW2ldWydBY2Nlc3NJbmZvJ10pICsgIjoiICsgcHJveGllc1tpXVsnUHJveHlQb3J0J10gKyAiPC9iPiAvICIgKyBFc2NhcGVIdG1sKHByb3hpZXNbaV1bJ05ldHdvcmtEbnNTdWZmaXgnXSkgKyAiPC9kaXY+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgY2xhc3M9aXRlbUJhciBvbmNsaWNrPXNob3dQcm94eURldGFpbHMoIiArIGkgKyAiKT48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48Yj4iICsgRXNjYXBlSHRtbChwcm94aWVzW2ldWydBY2Nlc3NJbmZvJ10pICsgIjoiICsgcHJveGllc1tpXVsnUG9ydCddICsgIjwvYj4gLyAiICsgRXNjYXBlSHRtbChwcm94aWVzW2ldWydOZXR3b3JrRG5zU3VmZml4J10pICsgIjwvZGl2PjwvZGl2PiI7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHZhciBhZGRzZXJ2ZXJidXR0b24gPSAnJzsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHsNCiAgICAgICAgICAgICAgICBhZGRzZXJ2ZXJidXR0b24gPSBBZGRCdXR0b24oIkFkZCBTZXJ2ZXIuLi4iLCAiQWRkUmVtb3RlQWNjZXNzU2VydmVyKCkiKTsNCiAgICAgICAgICAgICAgICBpZiAoY2lyYVByb3h5U3VwcG9ydCkgeyBhZGRzZXJ2ZXJidXR0b24gKz0gQWRkQnV0dG9uKCJBZGQgUHJveHkuLi4iLCAiQWRkUmVtb3RlQWNjZXNzUHJveHkoKSIpOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICB4ICs9ICI8YnI+PHRkIGNsYXNzPXIxPiIgKyBUYWJsZUVuZChBZGRSZWZyZXNoQnV0dG9uKCJQdWxsUmVtb3RlQWNjZXNzKCkiKSArIGFkZHNlcnZlcmJ1dHRvbik7DQoNCiAgICAgICAgICAgIFFIKCdpZF9UYWJsZVJlbW90ZUFjY2VzcycsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIHh4RWRpdE1wc1BvbGljeVR5cGU7DQogICAgICAgIGZ1bmN0aW9uIGVkaXRNcHNQb2xpY3kodHlwZSkgew0KICAgICAgICAgICAgdmFyIHggPSAnJywgY2lsYVN1cHBvcnQgPSAoKGFtdHZlcnNpb24gPiAxMSkgfHwgKChhbXR2ZXJzaW9uID09IDExKSAmJiAoYW10dmVyc2lvbiA+PSA2KSkpOw0KICAgICAgICAgICAgeHhFZGl0TXBzUG9saWN5VHlwZSA9IHR5cGU7DQogICAgICAgICAgICB2YXIgbmFtZSA9IHh4RWRpdE1wc1BvbGljeVR5cGU7DQogICAgICAgICAgICBpZiAobmFtZSA9PSAnVXNlcicpIG5hbWUgPSAnVXNlciBJbml0aWF0ZWQnOw0KICAgICAgICAgICAgdmFyIHBvbGljeSA9IGdldEl0ZW0oeHhSZW1vdGVBY2Nlc3NbIkFNVF9SZW1vdGVBY2Nlc3NQb2xpY3lSdWxlIl0ucmVzcG9uc2VzLCAiUG9saWN5UnVsZU5hbWUiLCBuYW1lKTsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PHNlbGVjdCBpZD1kMnNlcnZlcjEgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjA2cHggb25jaGFuZ2U9ZWRpdE1wc1BvbGljeVVwZGF0ZSgpPic7DQogICAgICAgICAgICB4ICs9ICc8b3B0aW9uIHZhbHVlPS0xPihOb25lKScNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhDaXJhU2VydmVycykgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPScgKyBpICsgJycgKyAoKHh4UG9saWNpZXNbdHlwZV1bMF0gJiYgeHhQb2xpY2llc1t0eXBlXVswXVsnTmFtZSddID09IHh4Q2lyYVNlcnZlcnNbaV1bJ05hbWUnXSkgPyAnIHNlbGVjdGVkJyA6ICcnKSArICc+JyArIHh4Q2lyYVNlcnZlcnNbaV1bJ0FjY2Vzc0luZm8nXSB9DQogICAgICAgICAgICB4ICs9ICc8L3NlbGVjdD48ZGl2PlByaW1hcnkgc2VydmVyPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIGlmIChjaWxhU3VwcG9ydCkgeyB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9ZDJzZXJ2ZXIxY2lyYSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDZweCBvbmNoYW5nZT1lZGl0TXBzUG9saWN5VXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0wPkNJUkEgLSBFeHRlcm5hbDxvcHRpb24gdmFsdWU9MScgKyAoKCh4eFBvbGljaWVzW3R5cGVdWzBdKSAmJiAoeHhQb2xpY2llc1t0eXBlXVswXS5NcHNUeXBlID09IDEpKT8nIHNlbGVjdGVkJzonJykgKyAnPkNJTEEgLSBJbnRlcm5hbDwvc2VsZWN0PjxkaXY+UHJpbWFyeSBNUFMgVHlwZTwvZGl2PjwvZGl2Pic7IH0NCiAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzLmxlbmd0aCA+IDEpIHsNCiAgICAgICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9ZDJzZXJ2ZXIyIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwNnB4IG9uY2hhbmdlPWVkaXRNcHNQb2xpY3lVcGRhdGUoKT4nOw0KICAgICAgICAgICAgICAgIHggKz0gJzxvcHRpb24gdmFsdWU9LTE+KE5vbmUpJw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhDaXJhU2VydmVycykgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPScgKyBpICsgJycgKyAoKHh4UG9saWNpZXNbdHlwZV1bMV0gJiYgeHhQb2xpY2llc1t0eXBlXVsxXVsnTmFtZSddID09IHh4Q2lyYVNlcnZlcnNbaV1bJ05hbWUnXSkgPyAnIHNlbGVjdGVkJyA6ICcnKSArICc+JyArIHh4Q2lyYVNlcnZlcnNbaV1bJ0FjY2Vzc0luZm8nXSB9DQogICAgICAgICAgICAgICAgeCArPSAnPC9zZWxlY3Q+PGRpdj5TZWNvbmRhcnkgc2VydmVyPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgICAgICBpZiAoY2lsYVN1cHBvcnQpIHsgeCArPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48c2VsZWN0IGlkPWQyc2VydmVyMmNpcmEgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjA2cHggb25jaGFuZ2U9ZWRpdE1wc1BvbGljeVVwZGF0ZSgpPjxvcHRpb24gdmFsdWU9MD5DSVJBIC0gRXh0ZXJuYWw8b3B0aW9uIHZhbHVlPTEnICsgKCgoeHhQb2xpY2llc1t0eXBlXVsxXSkgJiYgKHh4UG9saWNpZXNbdHlwZV1bMV0uTXBzVHlwZSA9PSAxKSkgPyAnIHNlbGVjdGVkJyA6ICcnKSArICc+Q0lMQSAtIEludGVybmFsPC9zZWxlY3Q+PGRpdj5TZWNvbmRhcnkgTVBTIFR5cGU8L2Rpdj48L2Rpdj4nOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICB2YXIgdCwgdiA9IDA7DQogICAgICAgICAgICBpZiAocG9saWN5KSB7IHYgPSBwb2xpY3lbJ1R1bm5lbExpZmVUaW1lJ107IH0NCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWQybGlmZXRpbWUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggb25jaGFuZ2U9ZWRpdE1wc1BvbGljeVVwZGF0ZSgpIHZhbHVlPScgKyB2ICsgJz4nOw0KICAgICAgICAgICAgeCArPSAnPGRpdj5UdW5uZWwgbGlmZXRpbWUgKFNlY29uZHMpPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIGlmICh0eXBlID09ICdQZXJpb2RpYycpIHsNCiAgICAgICAgICAgICAgICB0ID0gMDsNCiAgICAgICAgICAgICAgICB2ID0gMzYwMDsNCiAgICAgICAgICAgICAgICBpZiAocG9saWN5KSB7DQogICAgICAgICAgICAgICAgICAgIHZhciB4eCA9IGF0b2IocG9saWN5WydFeHRlbmRlZERhdGEnXSk7DQogICAgICAgICAgICAgICAgICAgIHQgPSBSZWFkSW50KHh4LCAwKTsNCiAgICAgICAgICAgICAgICAgICAgdiA9IFJlYWRJbnQoeHgsIDQpOw0KICAgICAgICAgICAgICAgICAgICBpZiAodCA9PSAxKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgbW0gPSBSZWFkSW50KHh4LCA4KTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtbSA8IDEwKSBtbSA9ICcwJyArIG1tOw0KICAgICAgICAgICAgICAgICAgICAgICAgdiArPSAnOicgKyBtbTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9ZDJ0dHlwZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDZweCBvbmNoYW5nZT1lZGl0TXBzUG9saWN5VXBkYXRlKCk+JzsNCiAgICAgICAgICAgICAgICB4ICs9ICc8b3B0aW9uIHZhbHVlPTAnICsgKHQgPT0gMCA/ICcgc2VsZWN0ZWQnIDogJycpICsgJz5QZXJpb2RpYywgdGltZSBpbnRlcnZhbDxvcHRpb24gdmFsdWU9MScgKyAodCA9PSAxID8gJyBzZWxlY3RlZCcgOiAnJykgKyAnPlRpbWUgb2YgZGF5LCBvbmNlIGEgZGF5Jw0KICAgICAgICAgICAgICAgIHggKz0gJzwvc2VsZWN0PjxkaXY+VHJpZ2dlciB0eXBlPC9kaXY+PC9kaXY+PGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48aW5wdXQgaWQ9ZDJ0aW1lciBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBvbmtleXVwPWVkaXRNcHNQb2xpY3lVcGRhdGUoKSB2YWx1ZT0nICsgdiArICc+PGRpdiBpZD10dHlwZWxhYmVsPjwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCB0eXBlICsgIiBDb25uZWN0aW9uIiwgMywgZWRpdE1wc1BvbGljeU9rLCB4KTsNCiAgICAgICAgICAgIGVkaXRNcHNQb2xpY3lVcGRhdGUoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVkaXRNcHNQb2xpY3lVcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgY2lsYVN1cHBvcnQgPSAoKGFtdHZlcnNpb24gPiAxMSkgfHwgKChhbXR2ZXJzaW9uID09IDExKSAmJiAoYW10dmVyc2lvbiA+PSA2KSkpOw0KICAgICAgICAgICAgdmFyIG9rID0gKHh4Q2lyYVNlcnZlcnMubGVuZ3RoIDw9IDEgfHwgKChRKCdkMnNlcnZlcjEnKS52YWx1ZSA9PSAtMSkgfHwgKFEoJ2Qyc2VydmVyMScpLnZhbHVlICE9IFEoJ2Qyc2VydmVyMicpLnZhbHVlKSkpOw0KICAgICAgICAgICAgaWYgKG9rID09IHRydWUgJiYgeHhFZGl0TXBzUG9saWN5VHlwZSA9PSAnUGVyaW9kaWMnICYmIFEoJ2QydHR5cGUnKS52YWx1ZSA9PSAxKSB7IHZhciBoaG1tID0gUSgnZDJ0aW1lcicpLnZhbHVlLnNwbGl0KCc6Jyk7IGlmIChoaG1tLmxlbmd0aCAhPSAyKSBvayA9IGZhbHNlOyBlbHNlIHsgdmFyIGhoID0gcGFyc2VJbnQoaGhtbVswXSk7IHZhciBtbSA9IHBhcnNlSW50KGhobW1bMV0pOyBpZiAoaGggPCAwIHx8IGhoID4gMjMgfHwgbW0gPCAwIHx8IG1tID4gNTkpIG9rID0gZmFsc2U7IH0gfQ0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzLmxlbmd0aCA+IDEpIFFFKCdkMnNlcnZlcjInLCBRKCdkMnNlcnZlcjEnKS52YWx1ZSAhPSAtMSk7DQogICAgICAgICAgICBpZiAoeHhFZGl0TXBzUG9saWN5VHlwZSA9PSAnUGVyaW9kaWMnKSB7DQogICAgICAgICAgICAgICAgUUUoJ2QydGltZXInLCBRKCdkMnNlcnZlcjEnKS52YWx1ZSAhPSAtMSk7DQogICAgICAgICAgICAgICAgUUgoJ3R0eXBlbGFiZWwnLCBRKCdkMnR0eXBlJykudmFsdWUgPT0gMCA/ICdUcmlnZ2VyIGludGVydmFsIChTZWNvbmRzKScgOiAnVGltZSBvZiBkYXkgKEhIOk1NKScpOw0KICAgICAgICAgICAgICAgIFFFKCdkMnR0eXBlJywgUSgnZDJzZXJ2ZXIxJykudmFsdWUgIT0gLTEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgUUUoJ2QybGlmZXRpbWUnLCBRKCdkMnNlcnZlcjEnKS52YWx1ZSAhPSAtMSk7DQoNCiAgICAgICAgICAgIC8vIElmIHdlIGFyZSBvbiBJbnRlbCBBTVQgMTEuNiBvciBoaWdoZXIsIGVuYWJsZSB0aGUgQ0lSQS9DSUxBIHNlbGVjdG9yIHdoZW4gbmVlZGVkLg0KICAgICAgICAgICAgaWYgKGNpbGFTdXBwb3J0KSB7DQogICAgICAgICAgICAgICAgUUUoJ2Qyc2VydmVyMWNpcmEnLCBRKCdkMnNlcnZlcjEnKS52YWx1ZSA+IC0xKQ0KICAgICAgICAgICAgICAgIGlmICh4eENpcmFTZXJ2ZXJzLmxlbmd0aCA+IDEpIHsgUUUoJ2Qyc2VydmVyMmNpcmEnLCAoUSgnZDJzZXJ2ZXIxJykudmFsdWUgPiAtMSkgJiYgKFEoJ2Qyc2VydmVyMicpLnZhbHVlID4gLTEpKTsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdE1wc1BvbGljeU9rKCkgew0KICAgICAgICAgICAgdmFyIG5hbWUgPSB4eEVkaXRNcHNQb2xpY3lUeXBlOw0KICAgICAgICAgICAgaWYgKG5hbWUgPT0gJ1VzZXInKSB7IG5hbWUgPSAnVXNlciBJbml0aWF0ZWQnOyB9DQoNCiAgICAgICAgICAgIGlmIChnZXRJdGVtKHh4UmVtb3RlQWNjZXNzWyJBTVRfUmVtb3RlQWNjZXNzUG9saWN5UnVsZSJdLnJlc3BvbnNlcywgIlBvbGljeVJ1bGVOYW1lIiwgbmFtZSkpIHsNCiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgb2xkIHBvbGljeQ0KICAgICAgICAgICAgICAgIGFtdHN0YWNrLkRlbGV0ZSgnQU1UX1JlbW90ZUFjY2Vzc1BvbGljeVJ1bGUnLCB7ICdQb2xpY3lSdWxlTmFtZSc6IG5hbWUgfSwgZWRpdE1wc1BvbGljeU9rMik7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIC8vIE5vIG9sZCBwb2xpY3kgdG8gcmVtb3ZlLCBza2lwIHRoaXMuDQogICAgICAgICAgICAgICAgZWRpdE1wc1BvbGljeU9rMigpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdE1wc1BvbGljeU9rMihzdGFjaywgbmFtZSwgcmVzcG9uc2VzLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIHZhciBjaWxhU3VwcG9ydCA9ICgoYW10dmVyc2lvbiA+IDExKSB8fCAoKGFtdHZlcnNpb24gPT0gMTEpICYmIChhbXR2ZXJzaW9uID49IDYpKSk7DQogICAgICAgICAgICBpZiAoUSgnZDJzZXJ2ZXIxJykudmFsdWUgPT0gLTEpIHsgUHVsbFJlbW90ZUFjY2VzcygpOyByZXR1cm47IH0NCg0KICAgICAgICAgICAgdmFyIHRyaWdnZXIgPSAwOw0KICAgICAgICAgICAgaWYgKHh4RWRpdE1wc1BvbGljeVR5cGUgPT0gJ0FsZXJ0JykgdHJpZ2dlciA9IDE7DQogICAgICAgICAgICBpZiAoeHhFZGl0TXBzUG9saWN5VHlwZSA9PSAnUGVyaW9kaWMnKSB0cmlnZ2VyID0gMjsNCg0KICAgICAgICAgICAgLy8gU2V0dXAgZXh0ZW5kZWQgZGF0YQ0KICAgICAgICAgICAgdmFyIGV4dGVuZGVkRGF0YSA9IG51bGw7DQogICAgICAgICAgICBpZiAodHJpZ2dlciA9PSAyKSB7DQogICAgICAgICAgICAgICAgdmFyIHRpbWVydHlwZSA9IFEoJ2QydHR5cGUnKS52YWx1ZTsNCiAgICAgICAgICAgICAgICB2YXIgZXhkYXRhID0gSW50VG9TdHIoUSgnZDJ0aW1lcicpLnZhbHVlKTsgLy8gSW50ZXJ2YWwgdHJpZ2dlcg0KICAgICAgICAgICAgICAgIGlmICh0aW1lcnR5cGUgPT0gMSkgeyB2YXIgaGhtbSA9IFEoJ2QydGltZXInKS52YWx1ZS5zcGxpdCgnOicpOyBleGRhdGEgPSBJbnRUb1N0cihwYXJzZUludChoaG1tWzBdKSkgKyBJbnRUb1N0cihwYXJzZUludChoaG1tWzFdKSk7IH0gLy8gVGltZSBvZiBkYXkgdHJpZ2dlcg0KICAgICAgICAgICAgICAgIGV4dGVuZGVkRGF0YSA9IGJ0b2EoSW50VG9TdHIodGltZXJ0eXBlKSArIGV4ZGF0YSk7DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIENyZWF0ZSB0aGUgTVBTIHNlcnZlciByZWZlcmVuY2VzDQogICAgICAgICAgICB2YXIgc2VydmVyMSwgc2VydmVyMjsNCiAgICAgICAgICAgIGlmIChRKCdkMnNlcnZlcjEnKS52YWx1ZSA+PSAwKSB7IHNlcnZlcjEgPSAnPEFkZHJlc3MgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyI+aHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nL3JvbGUvYW5vbnltb3VzPC9BZGRyZXNzPjxSZWZlcmVuY2VQYXJhbWV0ZXJzIHhtbG5zPSJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3NpbmciPjxSZXNvdXJjZVVSSSB4bWxucz0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZCI+aHR0cDovL2ludGVsLmNvbS93YmVtL3dzY2ltLzEvYW10LXNjaGVtYS8xL0FNVF9NYW5hZ2VtZW50UHJlc2VuY2VSZW1vdGVTQVA8L1Jlc291cmNlVVJJPjxTZWxlY3RvclNldCB4bWxucz0iaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c21hbi8xL3dzbWFuLnhzZCI+PFNlbGVjdG9yIE5hbWU9Ik5hbWUiPicgKyB4eENpcmFTZXJ2ZXJzW1EoJ2Qyc2VydmVyMScpLnZhbHVlXVsnTmFtZSddICsgJzwvU2VsZWN0b3I+PC9TZWxlY3RvclNldD48L1JlZmVyZW5jZVBhcmFtZXRlcnM+JzsgfQ0KICAgICAgICAgICAgaWYgKFEoJ2Qyc2VydmVyMScpLnZhbHVlID49IDAgJiYgeHhDaXJhU2VydmVycy5sZW5ndGggPiAxICYmIFEoJ2Qyc2VydmVyMicpLnZhbHVlID49IDApIHsgc2VydmVyMiA9ICc8QWRkcmVzcyB4bWxucz0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nIj5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmcvcm9sZS9hbm9ueW1vdXM8L0FkZHJlc3M+PFJlZmVyZW5jZVBhcmFtZXRlcnMgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyI+PFJlc291cmNlVVJJIHhtbG5zPSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIj5odHRwOi8vaW50ZWwuY29tL3diZW0vd3NjaW0vMS9hbXQtc2NoZW1hLzEvQU1UX01hbmFnZW1lbnRQcmVzZW5jZVJlbW90ZVNBUDwvUmVzb3VyY2VVUkk+PFNlbGVjdG9yU2V0IHhtbG5zPSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIj48U2VsZWN0b3IgTmFtZT0iTmFtZSI+JyArIHh4Q2lyYVNlcnZlcnNbUSgnZDJzZXJ2ZXIyJykudmFsdWVdWydOYW1lJ10gKyAnPC9TZWxlY3Rvcj48L1NlbGVjdG9yU2V0PjwvUmVmZXJlbmNlUGFyYW1ldGVycz4nOyB9DQoNCiAgICAgICAgICAgIC8vIFB1dCB0aGUgQ0lSQS9DSUxBIHNlcnZlcnMgaW4gdGhlIHJpZ2h0IGJpbnMuDQogICAgICAgICAgICB2YXIgY2lyYVNlcnZlcnMgPSBbXTsNCiAgICAgICAgICAgIHZhciBjaWxhU2VydmVycyA9IFtdOw0KICAgICAgICAgICAgaWYgKGNpbGFTdXBwb3J0KSB7DQogICAgICAgICAgICAgICAgLy8gT25seSBJbnRlbCBBTVQgMTEuNiBzdXBwb3J0cyB0aGlzDQogICAgICAgICAgICAgICAgaWYgKHNlcnZlcjEpIHsNCiAgICAgICAgICAgICAgICAgICAgaWYgKFEoJ2Qyc2VydmVyMWNpcmEnKS52YWx1ZSA9PSAwKSB7IGNpcmFTZXJ2ZXJzLnB1c2goc2VydmVyMSk7IH0gZWxzZSB7IGNpbGFTZXJ2ZXJzLnB1c2goc2VydmVyMSk7IH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKHNlcnZlcjIpIHsgaWYgKFEoJ2Qyc2VydmVyMmNpcmEnKS52YWx1ZSA9PSAwKSB7IGNpcmFTZXJ2ZXJzLnB1c2goc2VydmVyMik7IH0gZWxzZSB7IGNpbGFTZXJ2ZXJzLnB1c2goc2VydmVyMik7IH0gfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gSWYgb2xkZXIgdGhhbiBJbnRlbCBBTVQgMTEuNiwgcHV0IGFsbCBzZXJ2ZXJzIGluIHRoZSBDSVJBIGJ1Y2tldC4NCiAgICAgICAgICAgICAgICBpZiAoc2VydmVyMSkgeyBjaXJhU2VydmVycy5wdXNoKHNlcnZlcjEpOyBpZiAoc2VydmVyMikgeyBjaXJhU2VydmVycy5wdXNoKHNlcnZlcjIpOyB9IH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gR28gYWhlYWQgYW5kIGNyZWF0ZSB0aGUgbmV3IENJUkEvQ0lMQSBwb2xpY3kuDQogICAgICAgICAgICBhbXRzdGFjay5BTVRfUmVtb3RlQWNjZXNzU2VydmljZV9BZGRSZW1vdGVBY2Nlc3NQb2xpY3lSdWxlKHRyaWdnZXIsIFEoJ2QybGlmZXRpbWUnKS52YWx1ZSwgZXh0ZW5kZWREYXRhLCBjaXJhU2VydmVycywgY2lsYVNlcnZlcnMsIFB1bGxSZW1vdGVBY2Nlc3MpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcDsNCiAgICAgICAgZnVuY3Rpb24gZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uKGEpIHsNCiAgICAgICAgICAgIGlmIChhICE9IDEpIHsgZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wID0gKHh4RW52aXJvbmVtZW50RGV0ZWN0aW9uWydEZXRlY3Rpb25TdHJpbmdzJ10pID8gQ2xvbmUoeHhFbnZpcm9uZW1lbnREZXRlY3Rpb25bJ0RldGVjdGlvblN0cmluZ3MnXSkgOiBbXTsgfQ0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHggKz0gJ0VudGVyIHVwIHRvIDQgaW50cmFuZXQgZG9tYWluIHN1ZmZpeC4gSWYgdGhlIGNvbXB1dGVyIGlzIG91dHNpZGUgdGhlc2UgZG9tYWlucywgSW50ZWwmcmVnOyBBTVQgbG9jYWwgcG9ydHMgd2lsbCBiZSBjbG9zZWQgYW5kIHJlbW90ZSBzZXJ2ZXIgY29ubmVjdGlvbnMgd2lsbCBiZSBhY3RpdmUuPGJyPjxicj4nOw0KICAgICAgICAgICAgaWYgKGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcC5sZW5ndGggPT0gMCkgeyB4ICs9ICI8aT5ObyBpbnRyYW5ldCBkb21haW5zLCBFbnZpcm9uZW1udCBkZXRlY3Rpb24gZGlzYWJsZWQuPC9pPjxicj4iOyB9DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcCkgeyB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgc3R5bGU9bWFyZ2luLXJpZ2h0OjA+PGRpdiBzdHlsZT1mbG9hdDpyaWdodD4iICsgQWRkQnV0dG9uMigiUmVtb3ZlIiwgImVkaXRFbnZpcm9ubWVudERldGVjdGlvblJlbW92ZSgiICsgaSArICIpIikgKyAiPC9kaXY+PGRpdiBzdHlsZT1wYWRkaW5nLXRvcDozcHg7bWF4LXdpZHRoOjI2MHB4O292ZXJmbG93OmhpZGRlbiB0aXRsZT0nIiArIGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcFtpXSArICInPjxiPiIgKyBlZGl0RW52aXJvbm1lbnREZXRlY3Rpb25UbXBbaV0gKyAiPC9iPjwvZGl2PjwvZGl2PiI7IH0NCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUgJiYgZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wLmxlbmd0aCA8IDQpIHsgeCArPSAiPGJyPjxpbnB1dCBpZD1lZElucHV0IHBsYWNlaG9sZGVyPWludHJhbmV0Lm9yZyBzdHlsZT13aWR0aDoyNzZweCBvbmtleXVwPWVkSW5wdXRDaGcoKSBtYXhsZW5ndGg9NjM+PGlucHV0IHR5cGU9YnV0dG9uIGlkPWVkQWRkIHZhbHVlPUFkZCBzdHlsZT13aWR0aDo4MHB4O21hcmdpbi1sZWZ0OjVweCBvbmNsaWNrPWVkaXRFbnZpcm9ubWVudERldGVjdGlvbkFkZCgpPiI7IH0NCiAgICAgICAgICAgIGlmIChhID09IDEpIFFIKCdpZF9kaWFsb2dPcHRpb25zJywgeCk7IGVsc2Ugc2V0RGlhbG9nTW9kZSgxMSwgJ0Vudmlyb25tZW50IERldGVjdGlvbicsIHh4QWNjb3VudEFkbWluTmFtZT8zOjEsIGVkaXRFbnZpcm9ubWVudERldGVjdGlvbkRsZywgeCk7DQogICAgICAgICAgICBlZElucHV0Q2hnKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBlZGl0RW52aXJvbm1lbnREZXRlY3Rpb25EbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhBY2NvdW50QWRtaW5OYW1lKSB7DQogICAgICAgICAgICAgICAgdmFyIHQgPSBDbG9uZSh4eEVudmlyb25lbWVudERldGVjdGlvbik7DQogICAgICAgICAgICAgICAgdFsnRGV0ZWN0aW9uU3RyaW5ncyddID0gZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wOw0KICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coJ0FNVF9FbnZpcm9ubWVudERldGVjdGlvblNldHRpbmdEYXRhJywgdCk7DQogICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfRW52aXJvbm1lbnREZXRlY3Rpb25TZXR0aW5nRGF0YScsIHQsIGVkaXRFbnZpcm9ubWVudERldGVjdGlvbkRsZzIsIDAsIDEpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uRGxnMihzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsgbWVzc2FnZWJveCgnRW52aXJvbm1lbnQgRGV0ZWN0aW9uJywgJ0ZhaWxlZCB0byBhZGQgc2VydmVyLCBzdGF0dXMgJyArIHN0YXR1cyk7IH0NCiAgICAgICAgICAgIGVsc2UgaWYgKChyZXNwb25zZS5Cb2R5WyJSZXR1cm5WYWx1ZSJdKSAmJiAocmVzcG9uc2UuQm9keVsiUmV0dXJuVmFsdWUiXSAhPSAwKSkgeyBtZXNzYWdlYm94KCdFbnZpcm9ubWVudCBEZXRlY3Rpb24nLCByZXNwb25zZS5Cb2R5LlJldHVyblZhbHVlU3RyLnJlcGxhY2UoL18vZywgJyAnKSk7IH0NCiAgICAgICAgICAgIGVsc2UgeyBQdWxsUmVtb3RlQWNjZXNzKCk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVkSW5wdXRDaGcoKSB7DQogICAgICAgICAgICBpZiAoZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wLmxlbmd0aCA8IDQpIFFFKCdlZEFkZCcsIFEoJ2VkSW5wdXQnKS52YWx1ZS5sZW5ndGggPiAwKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVkaXRFbnZpcm9ubWVudERldGVjdGlvbkFkZCgpIHsNCiAgICAgICAgICAgIGVkaXRFbnZpcm9ubWVudERldGVjdGlvblRtcC5wdXNoKFEoJ2VkSW5wdXQnKS52YWx1ZSk7DQogICAgICAgICAgICBlZGl0RW52aXJvbm1lbnREZXRlY3Rpb24oMSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBlZGl0RW52aXJvbm1lbnREZXRlY3Rpb25SZW1vdmUoaCkgew0KICAgICAgICAgICAgZWRpdEVudmlyb25tZW50RGV0ZWN0aW9uVG1wLnNwbGljZShoLCAxKTsNCiAgICAgICAgICAgIGVkaXRFbnZpcm9ubWVudERldGVjdGlvbigxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGVkaXRVc2VySW5pdGlhdGVkQ2lyYSgpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBzID0gIiI7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4VXNlckluaXRpYXRlZEVuYWJsZWRTdGF0ZSkgeyBzICs9ICc8aW5wdXQgdHlwZT1yYWRpbyBuYW1lPWQxMSBpZD13bCcgKyBpICsgJyB2YWx1ZT0nICsgaSArICcgJyArICgoeHhVc2VySW5pdGlhdGVkQ2lyYVsnRW5hYmxlZFN0YXRlJ10gPT0gaSkgPyAiY2hlY2tlZCIgOiAiIikgKyAnPicgKyB4eFVzZXJJbml0aWF0ZWRFbmFibGVkU3RhdGVbaV0gKyAnPGJyPic7IH0NCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdVc2VyIEluaXRpYXRlZCBUdW5uZWwnLCAzLCBlZGl0VXNlckluaXRpYXRlZENpcmFEbGcsIHMpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdFVzZXJJbml0aWF0ZWRDaXJhRGxnKCkgeyBhbXRzdGFjay5BTVRfVXNlckluaXRpYXRlZENvbm5lY3Rpb25TZXJ2aWNlX1JlcXVlc3RTdGF0ZUNoYW5nZShkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPWQxMV06Y2hlY2tlZCcpLnZhbHVlLCBudWxsLCBlZGl0VXNlckluaXRpYXRlZENpcmFEbGcyKTsgfQ0KICAgICAgICBmdW5jdGlvbiBlZGl0VXNlckluaXRpYXRlZENpcmFEbGcyKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7IGlmIChzdGF0dXMgPT0gMjAwKSB7IGFtdHN0YWNrLkdldCgnQU1UX1VzZXJJbml0aWF0ZWRDb25uZWN0aW9uU2VydmljZScsIGVkaXRVc2VySW5pdGlhdGVkQ2lyYURsZzMsIDAsIDEpOyB9IH0NCiAgICAgICAgZnVuY3Rpb24gZWRpdFVzZXJJbml0aWF0ZWRDaXJhRGxnMyhzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgeyBpZiAoc3RhdHVzID09IDIwMCkgeyB4eFVzZXJJbml0aWF0ZWRDaXJhID0gcmVzcG9uc2UuQm9keTsgdXBkYXRlUmVtb3RlQWNjZXNzKCk7IH0gfQ0KDQogICAgICAgIHZhciB4eFNob3dTZXJ2ZXJEZXRhaWxzSGFuZGxlOw0KICAgICAgICBmdW5jdGlvbiBzaG93U2VydmVyRGV0YWlscyhoKSB7DQogICAgICAgICAgICB4eFNob3dTZXJ2ZXJEZXRhaWxzSGFuZGxlID0gaDsNCiAgICAgICAgICAgIHZhciBzZXJ2ZXIgPSB4eENpcmFTZXJ2ZXJzW2hdOw0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJBY2Nlc3MgTmFtZSIsIHNlcnZlclsiQWNjZXNzSW5mbyJdKTsNCiAgICAgICAgICAgIGlmIChzZXJ2ZXJbIlBvcnQiXSkgeCArPSBhZGRIdG1sVmFsdWUoIlBvcnQiLCBzZXJ2ZXJbIlBvcnQiXSk7DQogICAgICAgICAgICBpZiAoc2VydmVyWyJDTiJdKSB4ICs9IGFkZEh0bWxWYWx1ZSgiQ29tbW9uIE5hbWUiLCBzZXJ2ZXJbIkNOIl0pOw0KDQogICAgICAgICAgICB2YXIgY3JlZGVudGlhbGxpbmsgPSBnZXRFbGVtZW50V2l0aENvbnRleHRTZWxlY3RvclZhbHVlKHh4UmVtb3RlQWNjZXNzQ3JlZGVudGlhTGlua3MsIHNlcnZlclsnTmFtZSddKTsNCiAgICAgICAgICAgIGlmIChjcmVkZW50aWFsbGluaykgew0KICAgICAgICAgICAgICAgIHZhciBjcmVkZW50aWFsc2VsZWN0b3J2YWx1ZSA9IGNyZWRlbnRpYWxsaW5rWydFbGVtZW50SW5Db250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVsnVmFsdWUnXTsNCiAgICAgICAgICAgICAgICBpZiAoY3JlZGVudGlhbHNlbGVjdG9ydmFsdWUuaW5kZXhPZignVXNlcm5hbWUnKSA+IDApIHsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ0F1dGhlbnRpY2F0aW9uIFR5cGUnLCAnVXNlciAmIFBhc3MgLyBTZXJ2ZXItQXV0aCBUTFMnKTsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ1JlbW90ZSBJRCcsIGdldEluc3RhbmNlKHh4TVBTVXNlclBhc3MsIGNyZWRlbnRpYWxzZWxlY3RvcnZhbHVlKVsnUmVtb3RlSUQnXSk7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoJ0F1dGhlbnRpY2F0aW9uIFR5cGUnLCAnQ2VydGlmaWNhdGUgLyBNdXR1YWwtQXV0aCBUTFMnKTsNCg0KICAgICAgICAgICAgICAgICAgICB2YXIgYyA9IGdldEluc3RhbmNlKHh4Q2VydGlmaWNhdGVzLCBjcmVkZW50aWFsc2VsZWN0b3J2YWx1ZSk7DQogICAgICAgICAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCdDZXJ0aWZpY2F0ZSBOYW1lJywgcGFyc2VDZXJ0TmFtZShjWydTdWJqZWN0J10pWydDTiddKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIHZhciBidXR0b25zID0gMTsNCiAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIGJ1dHRvbnMgPSA1Ow0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIlJlbW90ZSBTZXJ2ZXIgIyIgKyAoaCArIDEpLCBidXR0b25zLCBzaG93U2VydmVyRGV0YWlsc09rLCB4KTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGdldEVsZW1lbnRXaXRoQ29udGV4dFNlbGVjdG9yVmFsdWUoZWxlbWVudHMsIHZhbHVlKSB7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGVsZW1lbnRzKSB7DQogICAgICAgICAgICAgICAgZWxlbWVudHNbaV1bJ0VsZW1lbnRQcm92aWRpbmdDb250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXSA9IE1ha2VUb0FycmF5KGVsZW1lbnRzW2ldWydFbGVtZW50UHJvdmlkaW5nQ29udGV4dCddWydSZWZlcmVuY2VQYXJhbWV0ZXJzJ11bJ1NlbGVjdG9yU2V0J11bJ1NlbGVjdG9yJ10pOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gZWxlbWVudHNbaV1bJ0VsZW1lbnRQcm92aWRpbmdDb250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXSkgeyBpZiAoZWxlbWVudHNbaV1bJ0VsZW1lbnRQcm92aWRpbmdDb250ZXh0J11bJ1JlZmVyZW5jZVBhcmFtZXRlcnMnXVsnU2VsZWN0b3JTZXQnXVsnU2VsZWN0b3InXVtqXVsnVmFsdWUnXSA9PSB2YWx1ZSkgcmV0dXJuIGVsZW1lbnRzW2ldOyB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICByZXR1cm4gbnVsbDsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dTZXJ2ZXJEZXRhaWxzT2socikgew0KICAgICAgICAgICAgLy8gRGVsZXRlIHRoZSBzZWxlY3RlZCBDSVJBIHNlcnZlciANCiAgICAgICAgICAgIGlmIChyID09IDIpIHsgYW10c3RhY2suRGVsZXRlKCdBTVRfTWFuYWdlbWVudFByZXNlbmNlUmVtb3RlU0FQJywgeyAnTmFtZSc6IHh4Q2lyYVNlcnZlcnNbeHhTaG93U2VydmVyRGV0YWlsc0hhbmRsZV1bJ05hbWUnXSB9LCBzaG93U2VydmVyRGV0YWlsc09rMik7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dTZXJ2ZXJEZXRhaWxzT2syKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSA0MDgpIHsgbWVzc2FnZWJveCgnUmVtb3RlIFNlcnZlciBSZW1vdmFsJywgJ1VuYWJsZSB0byByZW1vdmUgc2VydmVyLCBhY2Nlc3MgZGVuaWVkLicpOyB9IGVsc2UgeyBQdWxsUmVtb3RlQWNjZXNzKCk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHBhcnNlQ2VydE5hbWUoeCkgew0KICAgICAgICAgICAgdmFyIGosIHIgPSB7fSwgeHggPSB4LnNwbGl0KCcsJyk7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHh4KSB7IGogPSB4eFtpXS5pbmRleE9mKCc9Jyk7IHJbeHhbaV0uc3Vic3RyaW5nKDAsIGopXSA9IHh4W2ldLnN1YnN0cmluZyhqICsgMSk7IH0NCiAgICAgICAgICAgIHJldHVybiByOw0KICAgICAgICB9DQogICAgICAgIA0KICAgICAgICBmdW5jdGlvbiBzaG93UHJveHlEZXRhaWxzKGgpIHsNCiAgICAgICAgICAgIHZhciBwcm94eSA9IHh4UmVtb3RlQWNjZXNzWyJJUFNfSFRUUFByb3h5QWNjZXNzUG9pbnQiXS5yZXNwb25zZXNbaF07DQoNCiAgICAgICAgICAgIHZhciB4ID0gYWRkSHRtbFZhbHVlKCJBY2Nlc3MgbmFtZSIsIHByb3h5WyJBY2Nlc3NJbmZvIl0gKyAnOicgKyBwcm94eVsiUHJveHlQb3J0Il0pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkROUyBzdWZmZXgiLCBwcm94eVsiTmV0d29ya0Ruc1N1ZmZpeCJdKTsNCiAgICAgICAgICAgIC8veCArPSBhZGRIdG1sVmFsdWUoIlByb3h5IHR5cGUiLCBbJ0FkbWluaXN0cmF0b3InLCAnT3BlcmF0aW5nIHN5c3RlbSddW3Byb3h5WyJQcm94eVR5cGUiXV0pOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIlByb3h5IHR5cGUiLCBbJ0FkbWluaXN0cmF0b3InLCAnT3BlcmF0aW5nIHN5c3RlbSddW3Byb3h5WyJUeXBlIl1dKTsNCiAgICAgICAgICAgIC8veCArPSBhZGRIdG1sVmFsdWUoIkxhc3QgdGltZSB1c2VkIiwgcHJveHlbIkxhc3RUaW1lVXNlZCJdKTsNCg0KICAgICAgICAgICAgdmFyIGJ1dHRvbnMgPSAxOw0KICAgICAgICAgICAgaWYgKHh4QWNjb3VudEFkbWluTmFtZSkgeyBidXR0b25zID0gNTsgfQ0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIkhUVFAgUHJveHkgIyIgKyAoaCArIDEpLCBidXR0b25zLCBzaG93UHJveHlEZXRhaWxzT2ssIHgsIGgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1Byb3h5RGV0YWlsc09rKHIsIGgpIHsNCiAgICAgICAgICAgIC8vIERlbGV0ZSB0aGUgc2VsZWN0ZWQgcHJveHkgc2VydmVyDQogICAgICAgICAgICB2YXIgcHJveHkgPSB4eFJlbW90ZUFjY2Vzc1siSVBTX0hUVFBQcm94eUFjY2Vzc1BvaW50Il0ucmVzcG9uc2VzW2hdOw0KICAgICAgICAgICAgaWYgKHIgPT0gMikgeyBhbXRzdGFjay5EZWxldGUoJ0lQU19IVFRQUHJveHlBY2Nlc3NQb2ludCcsIHsgJ05hbWUnOiBwcm94eVsnTmFtZSddIH0sIHNob3dQcm94eURldGFpbHNPazIpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93UHJveHlEZXRhaWxzT2syKHN0YWNrLCBuYW1lLCByZXNwb25zZXMsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSA0MDgpIHsgbWVzc2FnZWJveCgnSFRUUCBQcm94eSBSZW1vdmFsJywgJ1VuYWJsZSB0byByZW1vdmUgSFRUUCBwcm94eSwgYWNjZXNzIGRlbmllZC4nKTsgfSBlbHNlIHsgUHVsbFJlbW90ZUFjY2VzcygpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NQcm94eSgpIHsNCiAgICAgICAgICAgIC8vIEFkZFJlbW90ZUFjY2Vzc1Byb3h5IEhvc3QgbmFtZSA9IDIsIElwdjQgPSAzLCBJcHY2ID0gNA0KICAgICAgICAgICAgdmFyIHggPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48c2VsZWN0IGlkPWQydHlwZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDZweCBvbmNoYW5nZT1BZGRSZW1vdGVBY2Nlc3NQcm94eVVwZGF0ZSgpPjxvcHRpb24gdmFsdWU9Mj5Ib3N0bmFtZSBGUUROPG9wdGlvbiB2YWx1ZT0zPklQdjQgYWRkcmVzczxvcHRpb24gdmFsdWU9ND5JUHY2IGFkZHJlc3M8L3NlbGVjdD48ZGl2PkNvbm5lY3Rpb24gdHlwZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMmhvc3Qgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggbWF4bGVuZ3RoPTI1NSBvbmtleXVwPUFkZFJlbW90ZUFjY2Vzc1Byb3h5VXBkYXRlKCk+PGRpdiBpZD1kMnR5cGVzcGFuPjwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMnBvcnQgb25rZXlwcmVzcz0icmV0dXJuIChldmVudC5jaGFyQ29kZSA9PSAwIHx8IChldmVudC5jaGFyQ29kZSA+PSA0OCAmJiBldmVudC5jaGFyQ29kZSA8PSA1NykpIiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMDBweCBvbmtleXVwPUFkZFJlbW90ZUFjY2Vzc1Byb3h5VXBkYXRlKCk+PGRpdj5Qb3J0PC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWQyZG9tYWluIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IG1heGxlbmd0aD0xOTEgb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NQcm94eVVwZGF0ZSgpPjxkaXY+RE5TIHN1ZmZpeDwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiQWRkIEhUVFAgUHJveHkiLCAzLCBBZGRSZW1vdGVBY2Nlc3NQcm94eU9rLCB4KTsNCiAgICAgICAgICAgIEFkZFJlbW90ZUFjY2Vzc1Byb3h5VXBkYXRlKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NQcm94eVVwZGF0ZSgpIHsNCiAgICAgICAgICAgIHZhciBvayA9IChRKCdkMmhvc3QnKS52YWx1ZS5sZW5ndGggIT0gMCkgJiYgKFEoJ2QyZG9tYWluJykudmFsdWUubGVuZ3RoICE9IDApOw0KICAgICAgICAgICAgaWYgKChRKCdkMnBvcnQnKS52YWx1ZS5sZW5ndGggPT0gMCkgfHwgKHBhcnNlSW50KFEoJ2QycG9ydCcpLnZhbHVlKSA+IDY1NTM1KSkgeyBvayA9IGZhbHNlOyB9DQogICAgICAgICAgICBRRSgnaWR4X2RsZ09rQnV0dG9uJywgb2spOw0KICAgICAgICAgICAgUUgoJ2QydHlwZXNwYW4nLCBbJycsICcnLCAnRlFETiAvIGhvc3RuYW1lJywgJ0lQdjQgYWRkcmVzcycsICdJUHY2IGFkZHJlc3MnXVtRKCdkMnR5cGUnKS52YWx1ZV0pOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gQWRkUmVtb3RlQWNjZXNzUHJveHlPaygpIHsNCiAgICAgICAgICAgIGFtdHN0YWNrLklQU19IVFRQUHJveHlTZXJ2aWNlX0FkZFByb3h5QWNjZXNzUG9pbnQoUSgnZDJob3N0JykudmFsdWUsIFEoJ2QydHlwZScpLnZhbHVlLCBwYXJzZUludChRKCdkMnBvcnQnKS52YWx1ZSksIFEoJ2QyZG9tYWluJykudmFsdWUsIEFkZFJlbW90ZUFjY2Vzc1Byb3h5T2syKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIEFkZFJlbW90ZUFjY2Vzc1Byb3h5T2syKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goJ0FkZCBQcm94eSBTZXJ2ZXInLCAnRmFpbGVkIHRvIGFkZCBwcm94eSwgc3RhdHVzICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5Cb2R5WyJSZXR1cm5WYWx1ZSJdICE9IDApIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdBZGQgUHJveHkgU2VydmVyJywgcmVzcG9uc2UuQm9keS5SZXR1cm5WYWx1ZVN0ci5yZXBsYWNlKC9fL2csICcgJykpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsUmVtb3RlQWNjZXNzKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NTZXJ2ZXIoKSB7DQoNCiAgICAgICAgICAgIHZhciBjZXJ0cyA9IFtdOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eENlcnRpZmljYXRlcykgeyBpZiAoeHhDZXJ0aWZpY2F0ZXNbaV0uWFByaXZhdGVLZXkpIHsgY2VydHMucHVzaCh4eENlcnRpZmljYXRlc1tpXSk7IH0gfQ0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PHNlbGVjdCBpZD1kMnR5cGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjA2cHggb25jaGFuZ2U9QWRkUmVtb3RlQWNjZXNzU2VydmVyVXBkYXRlKCk+PG9wdGlvbiB2YWx1ZT0yMDE+SG9zdG5hbWUgRlFETjxvcHRpb24gdmFsdWU9Mz5JUHY0IGFkZHJlc3M8L3NlbGVjdD48ZGl2PkNvbm5lY3Rpb24gdHlwZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMm5hbWUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKT48ZGl2IGlkPWQybG5hbWU+PC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWQycG9ydCBvbmtleXByZXNzPSJyZXR1cm4gKGV2ZW50LmNoYXJDb2RlID09IDAgfHwgKGV2ZW50LmNoYXJDb2RlID49IDQ4ICYmIGV2ZW50LmNoYXJDb2RlIDw9IDU3KSkiIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IHZhbHVlPTQ0MzMgb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKT48ZGl2PlNlcnZlciBwb3J0PC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHggaWQ9ZDJ1Y24+PGlucHV0IGlkPWQyY24gc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKT48ZGl2PlNlcnZlciBDb21tb24gTmFtZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9ZDJhdXRoIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwNnB4IG9uY2hhbmdlPUFkZFJlbW90ZUFjY2Vzc1NlcnZlclVwZGF0ZSgpPic7DQogICAgICAgICAgICBpZiAoY2VydHMubGVuZ3RoID4gMCkgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPTE+Q2VydGlmaWNhdGUnOyB9DQogICAgICAgICAgICB4ICs9ICc8b3B0aW9uIHZhbHVlPTI+VXNlcm5hbWUvUGFzc3dvcmQ8L3NlbGVjdD48ZGl2PkF1dGhlbnRpY2F0aW9uIHR5cGU8L2Rpdj48L2Rpdj4nOw0KICAgICAgICAgICAgeCArPSAnPHNwYW4gaWQ9ZDJ1dHlwZT4nOw0KICAgICAgICAgICAgeCArPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48aW5wdXQgaWQ9ZDJ1c2VyIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4IG9ua2V5dXA9QWRkUmVtb3RlQWNjZXNzU2VydmVyVXBkYXRlKCk+PGRpdj5Vc2VybmFtZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMnBhc3Mgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjAwcHggb25rZXl1cD1BZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKT48ZGl2PlN0cm9uZyBQYXNzd29yZDwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8L3NwYW4+JzsNCiAgICAgICAgICAgIHggKz0gJzxzcGFuIGlkPWQyY3R5cGU+JzsNCiAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PHNlbGVjdCBpZD1kMmNlcnQgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjA2cHggb25jaGFuZ2U9QWRkUmVtb3RlQWNjZXNzU2VydmVyVXBkYXRlKCk+JzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gY2VydHMpIHsgeCArPSAnPG9wdGlvbiB2YWx1ZT0nICsgY2VydHNbaV1bJ0luc3RhbmNlSUQnXS5zdWJzdHJpbmcoMzQpICsgJz4nICsgcGFyc2VDZXJ0TmFtZShjZXJ0c1tpXVsnU3ViamVjdCddKVsnQ04nXTsgfQ0KICAgICAgICAgICAgeCArPSAnPC9zZWxlY3Q+PGRpdj5DZXJ0aWZpY2F0ZTwvZGl2PjwvZGl2Pjwvc3Bhbj4nOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIkFkZCBSZW1vdGUgU2VydmVyIiwgMywgQWRkUmVtb3RlQWNjZXNzU2VydmVyT2ssIHgpOw0KICAgICAgICAgICAgQWRkUmVtb3RlQWNjZXNzU2VydmVyVXBkYXRlKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJPaygpIHsNCiAgICAgICAgICAgIHZhciBjcmVmLCB1c2VyLCBwYXNzLCBjbjsNCiAgICAgICAgICAgIGlmIChRKCdkMmF1dGgnKS52YWx1ZSA9PSAxKSB7DQogICAgICAgICAgICAgICAgY3JlZiA9ICc8QWRkcmVzcyB4bWxucz0iaHR0cDovL3NjaGVtYXMueG1sc29hcC5vcmcvd3MvMjAwNC8wOC9hZGRyZXNzaW5nIj5odHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA0LzA4L2FkZHJlc3Npbmc8L0FkZHJlc3M+PFJlZmVyZW5jZVBhcmFtZXRlcnMgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLnhtbHNvYXAub3JnL3dzLzIwMDQvMDgvYWRkcmVzc2luZyI+PFJlc291cmNlVVJJIHhtbG5zPSJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzbWFuLzEvd3NtYW4ueHNkIj5odHRwOi8vaW50ZWwuY29tL3diZW0vd3NjaW0vMS9hbXQtc2NoZW1hLzEvQU1UX1B1YmxpY0tleUNlcnRpZmljYXRlPC9SZXNvdXJjZVVSST48U2VsZWN0b3JTZXQgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLmRtdGYub3JnL3diZW0vd3NtYW4vMS93c21hbi54c2QiPjxTZWxlY3RvciBOYW1lPSJJbnN0YW5jZUlEIj5JbnRlbChyKSBBTVQgQ2VydGlmaWNhdGU6IEhhbmRsZTogJyArIFEoJ2QyY2VydCcpLnZhbHVlICsgJzwvU2VsZWN0b3I+PC9TZWxlY3RvclNldD48L1JlZmVyZW5jZVBhcmFtZXRlcnM+JzsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgdXNlciA9IFEoJ2QydXNlcicpLnZhbHVlOw0KICAgICAgICAgICAgICAgIHBhc3MgPSBRKCdkMnBhc3MnKS52YWx1ZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGlmIChRKCdkMmNuJykudmFsdWUubGVuZ3RoID4gMCkgY24gPSBRKCdkMmNuJykudmFsdWU7DQogICAgICAgICAgICBhbXRzdGFjay5BTVRfUmVtb3RlQWNjZXNzU2VydmljZV9BZGRNcFNlcnZlcihRKCdkMm5hbWUnKS52YWx1ZSwgUSgnZDJ0eXBlJykudmFsdWUsIFEoJ2QycG9ydCcpLnZhbHVlLCBRKCdkMmF1dGgnKS52YWx1ZSwgY3JlZiwgdXNlciwgcGFzcywgY24sIEFkZFJlbW90ZUFjY2Vzc1NlcnZlck9rMik7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJPazIoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7DQogICAgICAgICAgICAgICAgbWVzc2FnZWJveCgnQWRkIEludGVybmV0IFNlcnZlcicsICdGYWlsZWQgdG8gYWRkIHNlcnZlciwgc3RhdHVzICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfSBlbHNlIGlmIChyZXNwb25zZS5Cb2R5WyJSZXR1cm5WYWx1ZSJdICE9IDApIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdBZGQgSW50ZXJuZXQgU2VydmVyJywgcmVzcG9uc2UuQm9keS5SZXR1cm5WYWx1ZVN0ci5yZXBsYWNlKC9fL2csICcgJykpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBQdWxsUmVtb3RlQWNjZXNzKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBBZGRSZW1vdGVBY2Nlc3NTZXJ2ZXJVcGRhdGUoKSB7DQogICAgICAgICAgICB2YXIgb2sgPSAoUSgnZDJuYW1lJykudmFsdWUubGVuZ3RoICE9IDApOw0KICAgICAgICAgICAgaWYgKFEoJ2QydHlwZScpLnZhbHVlID09IDMgJiYgb2sgPT0gdHJ1ZSkgIHsgb2sgPSAoUSgnZDJjbicpLnZhbHVlLmxlbmd0aCAhPSAwKTsgfQ0KICAgICAgICAgICAgaWYgKFEoJ2QyYXV0aCcpLnZhbHVlID09IDIgJiYgb2sgPT0gdHJ1ZSkgeyBvayA9ICgoUSgnZDJ1c2VyJykudmFsdWUubGVuZ3RoICE9IDApICYmIChwYXNzd29yZGNoZWNrKFEoJ2QycGFzcycpLnZhbHVlKSkpOyB9DQogICAgICAgICAgICBpZiAoKFEoJ2QycG9ydCcpLnZhbHVlLmxlbmd0aCA9PSAwKSB8fCAocGFyc2VJbnQoUSgnZDJwb3J0JykudmFsdWUpID4gNjU1MzUpKSB7IG9rID0gZmFsc2U7IH0NCiAgICAgICAgICAgIGlmICgoUSgnZDJuYW1lJykudmFsdWUuaW5kZXhPZignOicpICE9IC0xKSB8fCAoKFEoJ2QydHlwZScpLnZhbHVlID09IDMpICYmIChRKCdkMmNuJykudmFsdWUuaW5kZXhPZignOicpICE9IC0xKSkpIHsgb2sgPSBmYWxzZTsgfQ0KICAgICAgICAgICAgUUgoJ2QybG5hbWUnLCAoUSgnZDJ0eXBlJykudmFsdWUgPT0gMjAxKSA/ICdIb3N0bmFtZScgOiAnSVB2NCBBZGRyZXNzJyk7DQogICAgICAgICAgICBRVignZDJ1dHlwZScsIFEoJ2QyYXV0aCcpLnZhbHVlID09IDIpOw0KICAgICAgICAgICAgUVYoJ2QydWNuJywgUSgnZDJ0eXBlJykudmFsdWUgPT0gMyk7DQogICAgICAgICAgICBRVignZDJjdHlwZScsIFEoJ2QyYXV0aCcpLnZhbHVlID09IDEpOw0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIG9rKTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gRWRpdCBDb21wdXRlciBOYW1lICYgRE5TIGZlYXR1cmUNCiAgICAgICAgLy8NCg0KICAgICAgICBmdW5jdGlvbiBzaG93RWRpdE5hbWVEbGcoeCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHQgPSBhbXRzeXNzdGF0ZVsnQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlWyJIb3N0TmFtZSJdLCB5ID0gYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZVsiRG9tYWluTmFtZSJdOw0KICAgICAgICAgICAgaWYgKHkgIT0gbnVsbCAmJiB5Lmxlbmd0aCA+IDApIHQgKz0gIi4iICsgeTsNCiAgICAgICAgICAgIHZhciByID0gJzxicj48ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1kMTFuYW1lIHZhbHVlPSInICsgdCArICciIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4PjxkaXY+TmFtZSAmIERvbWFpbjwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICBpZiAoeCA9PSAxKSB7DQogICAgICAgICAgICAgICAgdmFyIHMgPSAoYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZVsiU2hhcmVkRlFETiJdID09IHRydWUpOw0KICAgICAgICAgICAgICAgIHIgKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PHNlbGVjdCBpZD1kMTFmcWRuIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIwMHB4PjxvcHRpb24gdmFsdWU9dHJ1ZSAnICsgKHM/J3NlbGVjdGVkJzonJykgKyAnPlNoYXJlZCwgc2FtZSBhcyBPUzxvcHRpb24gdmFsdWU9ImZhbHNlIiAnICsgKHM/Jyc6J3NlbGVjdGVkJykgKyAnPkRlZGljYXRlZCwgZGlmZmVyZW50IGZyb20gT1M8L3NlbGVjdD48ZGl2Pk5hbWUgU2hhcmluZzwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnQ29tcHV0ZXIgTmFtZScsIDMsIGVkaXROYW1lRGxnT2ssIHIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZWRpdE5hbWVEbGdPaygpIHsNCiAgICAgICAgICAgIHZhciBpID0gUSgnZDExbmFtZScpLnZhbHVlLCBqID0gaS5pbmRleE9mKCcuJyksIGsgPSAnJzsNCiAgICAgICAgICAgIGlmIChqID49IDApIHsgayA9IGkuc3Vic3RyaW5nKGogKyAxKTsgaSA9IGkuc3Vic3RyaW5nKDAsIGopOyB9DQogICAgICAgICAgICB2YXIgY2xvbmUgPSBDbG9uZShhbXRzeXNzdGF0ZVsnQU1UX0dlbmVyYWxTZXR0aW5ncyddLnJlc3BvbnNlKTsNCiAgICAgICAgICAgIGNsb25lWyJIb3N0TmFtZSJdID0gaTsNCiAgICAgICAgICAgIGNsb25lWyJEb21haW5OYW1lIl0gPSBrOw0KICAgICAgICAgICAgaWYgKFEoJ2QxMWZxZG4nKSkgeyBjbG9uZVsiU2hhcmVkRlFETiJdID0gZDExZnFkbi52YWx1ZTsgfQ0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfR2VuZXJhbFNldHRpbmdzJywgY2xvbmUsIGZ1bmN0aW9uKCkgeyBhbXRzdGFjay5HZXQoJ0FNVF9HZW5lcmFsU2V0dGluZ3MnLCBjb21wdXRlck5hbWVHZXQsIDAsIDEpOyB9LCAwLCAxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGNvbXB1dGVyTmFtZUdldChzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZSA9IHJlc3BvbnNlLkJvZHk7IHVwZGF0ZVN5c3RlbVN0YXR1cygpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93RWRpdERuc0RsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBnID0gYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZTsNCiAgICAgICAgICAgIHZhciB2ID0gMDsNCiAgICAgICAgICAgIGlmIChnWyJERE5TVXBkYXRlQnlESENQU2VydmVyRW5hYmxlZCJdID09IHRydWUpIHYgPSAxOw0KICAgICAgICAgICAgaWYgKGdbIkRETlNVcGRhdGVFbmFibGVkIl0gPT0gdHJ1ZSkgdiA9IDI7DQogICAgICAgICAgICBpZHhfZDIzZGRucy52YWx1ZSA9IHY7DQogICAgICAgICAgICBpZHhfZDIzaW50ZXJ2YWwudmFsdWUgPSBnWydERE5TUGVyaW9kaWNVcGRhdGVJbnRlcnZhbCddOw0KICAgICAgICAgICAgaWR4X2QyM3R0bC52YWx1ZSA9IGdbJ0RETlNUVEwnXTsNCiAgICAgICAgICAgIHNob3dFZGl0RG5zRGxnQ2hhbmdlKCk7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDIzLCAnRHluYW1pYyBETlMgY2xpZW50JywgMywgc2hvd0VkaXREbnNEbGdPayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93RWRpdERuc0RsZ09rKCkgew0KICAgICAgICAgICAgdmFyIGNsb25lID0gQ2xvbmUoYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZSk7DQogICAgICAgICAgICBjbG9uZVsiREROU1VwZGF0ZUVuYWJsZWQiXSA9ICgoaWR4X2QyM2RkbnMudmFsdWUgPT0gMik/dHJ1ZTpmYWxzZSk7DQogICAgICAgICAgICBjbG9uZVsiREROU1VwZGF0ZUJ5REhDUFNlcnZlckVuYWJsZWQiXSA9ICgoaWR4X2QyM2RkbnMudmFsdWUgPT0gMSk/dHJ1ZTpmYWxzZSk7DQogICAgICAgICAgICBpZiAoaWR4X2QyM2RkbnMudmFsdWUgPT0gMikgew0KICAgICAgICAgICAgICAgIGNsb25lWyJERE5TUGVyaW9kaWNVcGRhdGVJbnRlcnZhbCJdID0gaWR4X2QyM2ludGVydmFsLnZhbHVlOw0KICAgICAgICAgICAgICAgIGNsb25lWyJERE5TVFRMIl0gPSBpZHhfZDIzdHRsLnZhbHVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCdBTVRfR2VuZXJhbFNldHRpbmdzJywgY2xvbmUsIGZ1bmN0aW9uKCkgeyBhbXRzdGFjay5HZXQoJ0FNVF9HZW5lcmFsU2V0dGluZ3MnLCBjb21wdXRlck5hbWVHZXQsIDAsIDEpOyB9LCAwLCAxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dFZGl0RG5zRGxnQ2hhbmdlKCkgew0KICAgICAgICAgICAgUUUoJ2lkeF9kMjNpbnRlcnZhbCcsIGlkeF9kMjNkZG5zLnZhbHVlID09IDIpOw0KICAgICAgICAgICAgUUUoJ2lkeF9kMjN0dGwnLCBpZHhfZDIzZGRucy52YWx1ZSA9PSAyKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEludGVsIEFNVCBGZWF0dXJlcw0KICAgICAgICAvLw0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dGZWF0dXJlc0RsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgIXh4QWNjb3VudEFkbWluTmFtZSkgcmV0dXJuOw0KICAgICAgICAgICAgaWR4X2Q5cmVkaXIuY2hlY2tlZCA9IGFtdGZlYXR1cmVzWzBdLCBpZHhfZDlrdm0uY2hlY2tlZCA9IGFtdGZlYXR1cmVzWzNdLCBpZHhfZDlpZGVyLmNoZWNrZWQgPSBhbXRmZWF0dXJlc1syXSwgaWR4X2Q5c29sLmNoZWNrZWQgPSBhbXRmZWF0dXJlc1sxXTsNCiAgICAgICAgICAgIFFWKCdpZHhfZDlrdm1fZGl2JywgYW10ZmVhdHVyZXNbM10gIT0gdW5kZWZpbmVkKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoOSwgJ0ludGVsJnJlZzsgQU1UIEZlYXR1cmVzJywgMywgZmVhdHVyZXNEbGdPaykNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGZlYXR1cmVzRGxnT2soKSB7DQogICAgICAgICAgICB2YXIgciA9IGFtdHN5c3N0YXRlWydBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlJ10ucmVzcG9uc2U7DQogICAgICAgICAgICByWyJMaXN0ZW5lckVuYWJsZWQiXSA9IGlkeF9kOXJlZGlyLmNoZWNrZWQ7DQogICAgICAgICAgICByWyJFbmFibGVkU3RhdGUiXSA9IDMyNzY4ICsgKChpZHhfZDlpZGVyLmNoZWNrZWQ/MTowKSArIChpZHhfZDlzb2wuY2hlY2tlZD8yOjApKTsNCiAgICAgICAgICAgIGFtdHN0YWNrLkFNVF9SZWRpcmVjdGlvblNlcnZpY2VfUmVxdWVzdFN0YXRlQ2hhbmdlKHJbIkVuYWJsZWRTdGF0ZSJdLA0KICAgICAgICAgICAgICAgIGZ1bmN0aW9uKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goIkVycm9yIiwgIlJlZGlyZWN0aW9uU2VydmljZSwgUmVxdWVzdFN0YXRlQ2hhbmdlIEVycm9yICIgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suQ0lNX0tWTVJlZGlyZWN0aW9uU0FQX1JlcXVlc3RTdGF0ZUNoYW5nZSgoaWR4X2Q5a3ZtLmNoZWNrZWQpPzI6MywgMCwNCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24oc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goIkVycm9yIiwgIktWTVJlZGlyZWN0aW9uU0FQLCBSZXF1ZXN0U3RhdGVDaGFuZ2UgRXJyb3IgIiArIHN0YXR1cyk7IHJldHVybjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCJBTVRfUmVkaXJlY3Rpb25TZXJ2aWNlIiwgciwgZnVuY3Rpb24oc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgeyBtZXNzYWdlYm94KCJFcnJvciIsICJSZWRpcmVjdGlvblNlcnZpY2UgUFVUIEVycm9yICIgKyBzdGF0dXMpOyByZXR1cm47IH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbXRzdGFjay5HZXQoIkFNVF9SZWRpcmVjdGlvblNlcnZpY2UiLCBmZWF0dXJlc0RsZ0dldDEsIDAsIDEpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLkdldCgiQ0lNX0tWTVJlZGlyZWN0aW9uU0FQIiwgZmVhdHVyZXNEbGdHZXQyLCAwLCAxKSB9LCAwLCAxKQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgKTt9DQogICAgICAgICAgICApOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZmVhdHVyZXNEbGdHZXQxKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgeyBhbXRzeXNzdGF0ZVsnQU1UX1JlZGlyZWN0aW9uU2VydmljZSddLnJlc3BvbnNlID0gcmVzcG9uc2UuQm9keTsgdXBkYXRlU3lzdGVtU3RhdHVzKCk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGZlYXR1cmVzRGxnR2V0MihzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsgYW10c3lzc3RhdGVbJ0NJTV9LVk1SZWRpcmVjdGlvblNBUCddLnJlc3BvbnNlID0gcmVzcG9uc2UuQm9keTsgdXBkYXRlU3lzdGVtU3RhdHVzKCk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEludGVsIEFNVCBVc2VyIENvbnNlbnQNCiAgICAgICAgLy8NCg0KICAgICAgICBmdW5jdGlvbiBzaG93Q29uc2VudERsZygpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHZhciBvcHRpbnJlcXVpcmVkID0gYW10c3lzc3RhdGVbJ0lQU19PcHRJblNlcnZpY2UnXS5yZXNwb25zZVsiT3B0SW5SZXF1aXJlZCJdOw0KICAgICAgICAgICAgaWR4X2QxMG5vbmUuY2hlY2tlZCA9IChvcHRpbnJlcXVpcmVkID09IDApOw0KICAgICAgICAgICAgaWR4X2QxMGt2bS5jaGVja2VkID0gKG9wdGlucmVxdWlyZWQgPT0gMSk7DQogICAgICAgICAgICBpZHhfZDEwYWxsLmNoZWNrZWQgPSAob3B0aW5yZXF1aXJlZCA9PSAweEZGRkZGRkZGKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTAsICdVc2VyIENvbnNlbnQnLCAzLCBjb25zZW50RGxnT2spDQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBjb25zZW50RGxnT2soKSB7DQogICAgICAgICAgICBhbXRzeXNzdGF0ZVsnSVBTX09wdEluU2VydmljZSddLnJlc3BvbnNlWyJPcHRJblJlcXVpcmVkIl0gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdpbnB1dFtuYW1lPWQxMF06Y2hlY2tlZCcpLnZhbHVlOw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCJJUFNfT3B0SW5TZXJ2aWNlIiwgYW10c3lzc3RhdGVbJ0lQU19PcHRJblNlcnZpY2UnXS5yZXNwb25zZSwgZnVuY3Rpb24oKSB7IGFtdHN0YWNrLkdldCgiSVBTX09wdEluU2VydmljZSIsIGNvbnNlbnRHZXQsIDAsIDEpOyB9LCAwLCAxKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIGNvbnNlbnRHZXQoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSB7IFB1bGxTeXN0ZW1TdGF0dXMoKTsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gTkVUV09SSyBTRVRUSU5HUw0KICAgICAgICAvLw0KDQoNCg0KICAgICAgICAvKg0KICAgICAgICBJUHY2ICVBZGRyVHlwZSU6DQogICAgICAgICAgICAwIC0gQWRkcmVzcyBnZW5lcmF0ZWQgZnJvbTogZmU4MDo6LzY0ICsgSW50ZXJmYWNlIElELA0KICAgICAgICAgICAgMSAtIEFkZHJlc3MgZ2VuZXJhdGVkIGZyb206IFtSb3V0ZXIgYWR2ZXJ0aXNlZCBwcmVmaXhdICsgW0ludGVyZmFjZSBJRF0sDQogICAgICAgICAgICAyIC0gR2xvYmFsIElQdjYgYWRkcmVzcyBvYnRhaW5lZCBmcm9tIERIQ1B2NiBTZXJ2ZXIsDQogICAgICAgICAgICAzIC0gSVB2NiB1bmljYXN0IGFkZHJlc3MgY29uZmlndXJlZCBieSB0aGUgdXNlciwNCiAgICAgICAgICAgIDQgLSBSZXR1cm5lZCBieSBGVyBmb3IgSVB2NiBhZGRyZXNzZXMgdGhhdCBhcmUgbm90IG93bmVkIGJ5IEZXIChzdWNoIGFzIElQdjYgcm91dGVyIGFkZHJlc3MsIGNvbmZpZ3VyYXRpb24gc2VydmVyIGFkZHJlc3MgZXRjLikNCg0KICAgICAgICBJUHY2ICVBZGRyU3RhdGUlOg0KICAgICAgICAgICAgMCAtIERBRCBpcyBzdGlsbCBpbiBwcm9jZXNzIGZvciB0aGlzIGFkZHJlc3MsDQogICAgICAgICAgICAxIC0gQWRkcmVzcyBpcyB2YWxpZCBhbmQgbWF5IGJlIHVzZWQgZm9yIG5ldyBjb21tdW5pY2F0aW9uLA0KICAgICAgICAgICAgMiAtIEFkZHJlc3MgaXMgZGVwcmVjYXRlZCBhbmQgc2hvdWxkIG5vdCBiZSB1c2VkIGZvciBuZXcgY29tbXVuaWNhdGlvbiwNCiAgICAgICAgICAgIDMgLSBDb3ZlcnMgYm90aCB0aGUgcHJlZmVycmVkIGFuZCBkZXByZWNhdGVkIHN0YXRlcywNCiAgICAgICAgICAgIDQgLSBUaGUgdmFsaWQgbGlmZXRpbWUgb2YgdGhlIGFkZHJlc3MgaGFzIGV4cGlyZWQsDQogICAgICAgICAgICA1IC0gQW4gaW50ZXJmYWNlIElEIGNvbGxpc2lvbiBoYXMgYmVlbiBkZXRlY3RlZCBmb3IgdGhpcyBhZGRyZXNzIHdoZW4gcGVyZm9ybWluZyBEQUQsDQogICAgICAgICAgICA2IC0gUmV0dXJuZWQgYnkgRlcgZm9yIElQdjYgYWRkcmVzc2VzIHRoYXQgYXJlIG5vdCBvd25lZCBieSBGVyAoc3VjaCBhcyBJUHY2IHJvdXRlciBhZGRyZXNzLCBjb25maWd1cmF0aW9uIHNlcnZlciBhZGRyZXNzIGV0Yy4NCiAgICAgICAgKi8NCiAgICAgICAgLy8gaXB2NmFkZHJ0eXBlIGFyZSBlbGVtZW50IDAgdG8gNCwgaXB2NmFkZHJzdGF0ZSBhcmUgNSBhbmQgYWZ0ZXIuIE1lcmdlZCBib3RoIGFycmF5cyB0byBjdXQgZG93biBzaXplDQogICAgICAgIHZhciBpcHY2YWRkcnR5cGUgPSBbIkxpbmsgbG9jYWwgYWRkcmVzcyIsICJOZXR3b3JrIGxvY2FsIGFkZHJlc3MiLCAiR2xvYmFsIGFkZHJlc3MiLCAiVXNlciBjb25maWd1cmVkIiwgIk5vdCBhbGxvd2VkIiwgIkRBRCBpbiBwcm9ncmVzcyIsICJ2YWxpZCIsICJkZXByZWNhdGVkIiwgInByZWZlcnJlZC9kZXByZWNhdGVkIiwgImV4cGlyZWQiLCAiY29sbGlzaW9uIiwgIm5vdCBhbGxvd2VkIl07DQogICAgICAgIGZ1bmN0aW9uIHNob3dJUHY2QWRkckRsZyhuZXRpZmlkLCBhZGRyc3RyKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9IFRhYmxlU3RhcnQoKTsNCiAgICAgICAgICAgIHQgPSBhZGRyc3RyLnNwbGl0KCcsJyk7DQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHQubGVuZ3RoOyBpICs9IDMpIHsNCiAgICAgICAgICAgICAgICB4ICs9IFRhYmxlRW50cnkoIjxiPiIgKyB0W2ldICsgIjwvYj48YnI+PHNwYW4gc3R5bGU9Zm9udC1zaXplOjEwcHg+IiArIGlwdjZhZGRydHlwZVt0W2kgKyAxXV0gKyAiLCAiICsgaXB2NmFkZHJ0eXBlWyt0W2kgKyAyXSArIDVdICsgIjwvc3Bhbj4iLCAiIik7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAnSVB2NiBhZGRyZXNzZXMgZm9yICcgKyAobmV0aWZpZD09MD8nd2lyZWQnOid3aXJlbGVzcycpICsgJyBpbnRlcmZhY2UnLCAxLCBudWxsLCB4ICsgVGFibGVFbmQoKSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93SVB2NlN0YXRlRGxnKG5ldGlmaWQsIHN0YXRlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8ICFhbXRzeXNzdGF0ZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHp6ID0gYW10c3lzc3RhdGVbJ0lQU19JUHY2UG9ydFNldHRpbmdzJ10ucmVzcG9uc2VzW25ldGlmaWRdOw0KICAgICAgICAgICAgaXB2Nm1hbnVhbCA9IChuZXRpZmlkID09IDAgJiYgKGlzSXBBZGRyZXNzKHp6WyJJUHY2QWRkcmVzcyJdKSB8fCBpc0lwQWRkcmVzcyh6elsiRGVmYXVsdFJvdXRlciJdKSB8fCBpc0lwQWRkcmVzcyh6elsiUHJpbWFyeUROUyJdKSB8fCBpc0lwQWRkcmVzcyh6elsiU2Vjb25kYXJ5RE5TIl0pKSk7DQoNCiAgICAgICAgICAgIFFWKCdpZF9kMjFtYW51YWxkaXYnLCBuZXRpZmlkID09IDApOw0KICAgICAgICAgICAgUVYoJ2lkX2QyMXN1Ym5ldGRpdicsIGZhbHNlKTsNCiAgICAgICAgICAgIFFWKCdkMjFvMCcsIHRydWUpOw0KICAgICAgICAgICAgUVYoJ2QyMWwwJywgdHJ1ZSk7DQogICAgICAgICAgICBRSCgnZDIxbDAnLCAnSVB2NiBkaXNhYmxlZCcpOw0KICAgICAgICAgICAgUUgoJ2QyMWwxJywgJ0lQdjYgZW5hYmxlZCwgYXV0b21hdGljJyk7DQogICAgICAgICAgICBRSCgnZDIxbDInLCAnSVB2NiBlbmFibGVkLCBhdXRvbWF0aWMgKyBtYW51YWwgYWRkcmVzc2UnKTsNCiAgICAgICAgICAgIGQyMW8wLmNoZWNrZWQgPSAhc3RhdGU7DQogICAgICAgICAgICBkMjFvMS5jaGVja2VkID0gc3RhdGUgJiYgIWlwdjZtYW51YWw7DQogICAgICAgICAgICBkMjFvMi5jaGVja2VkID0gc3RhdGUgJiYgaXB2Nm1hbnVhbDsNCiAgICAgICAgICAgIGlkeF9kMjFhZGRyZXNzLnZhbHVlID0gaXNJcEFkZHJlc3MoenpbIklQdjZBZGRyZXNzIl0sJycpOw0KICAgICAgICAgICAgaWR4X2QyMWdhdGV3YXkudmFsdWUgPSBpc0lwQWRkcmVzcyh6elsiRGVmYXVsdFJvdXRlciJdLCcnKTsNCiAgICAgICAgICAgIGlkeF9kMjFkbnMxLnZhbHVlID0gaXNJcEFkZHJlc3MoenpbIlByaW1hcnlETlMiXSwnJyk7DQogICAgICAgICAgICBpZHhfZDIxZG5zMi52YWx1ZSA9IGlzSXBBZGRyZXNzKHp6WyJTZWNvbmRhcnlETlMiXSwnJyk7DQogICAgICAgICAgICB1cGRhdGVJUFNldHVwRGxnKCk7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDIxLCAnSVB2NiBzdXBwb3J0IGZvciAnICsgKG5ldGlmaWQ9PTA/J3dpcmVkJzond2lyZWxlc3MnKSArICcgaW50ZXJmYWNlJywgMywgZnVuY3Rpb24oKSB7IHNob3dJUHY2U3RhdGVEbGdPayhuZXRpZmlkKSB9KQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0lQdjZTdGF0ZURsZ09rKG5ldGlmaWQpIHsNCiAgICAgICAgICAgIHZhciB6eiA9IGFtdHN5c3N0YXRlWydJUFNfSVB2NlBvcnRTZXR0aW5ncyddLnJlc3BvbnNlc1tuZXRpZmlkXTsNCiAgICAgICAgICAgIGlmIChuZXRpZmlkID09IDApIHsgLy8gV2UgY2FuIG9ubHkgc2V0IElQdjYgbWFudWFsIGFkZHJlc3MgZm9yIHdpcmVkIGludGVyZmFjZQ0KICAgICAgICAgICAgICAgIGlmIChkMjFvMS5jaGVja2VkKSB7IC8vIEZ1bGx5IGF1dG9tYXRpYywgY2xlYXIgYWxsIGFkZHJlc3Nlcw0KICAgICAgICAgICAgICAgICAgICB6elsiSVB2NkFkZHJlc3MiXSA9IHp6WyJEZWZhdWx0Um91dGVyIl0gPSB6elsiUHJpbWFyeUROUyJdID0genpbIlNlY29uZGFyeUROUyJdID0gIjo6IjsNCiAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCJJUFNfSVB2NlBvcnRTZXR0aW5ncyIsIHp6LCBzaG93SVB2NlN0YXRlRGxnRG9uZSk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmIChkMjFvMi5jaGVja2VkKSB7IC8vIE1hbnVhbCwgc2V0IGFkZHJlc3Nlcw0KICAgICAgICAgICAgICAgICAgICB6elsiSVB2NkFkZHJlc3MiXSA9IGlkeF9kMjFhZGRyZXNzLnZhbHVlOw0KICAgICAgICAgICAgICAgICAgICB6elsiRGVmYXVsdFJvdXRlciJdID0gaWR4X2QyMWdhdGV3YXkudmFsdWU7DQogICAgICAgICAgICAgICAgICAgIHp6WyJQcmltYXJ5RE5TIl0gPSBpZHhfZDIxZG5zMS52YWx1ZTsNCiAgICAgICAgICAgICAgICAgICAgenpbIlNlY29uZGFyeUROUyJdID0gaWR4X2QyMWRuczIudmFsdWU7DQogICAgICAgICAgICAgICAgICAgIGFtdHN0YWNrLlB1dCgiSVBTX0lQdjZQb3J0U2V0dGluZ3MiLCB6eiwgc2hvd0lQdjZTdGF0ZURsZ0RvbmUpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIC8vIFRoaXMgY29kZSBlbmFibGVzL2Rpc2FibGVzIElQdjYgZm9yIGEgZ2l2ZW4gaW50ZXJmYWNlLg0KICAgICAgICAgICAgdmFyIGVsZW1lbnRTZXR0aW5ncyA9IGFtdHN5c3N0YXRlWydDSU1fRWxlbWVudFNldHRpbmdEYXRhJ10ucmVzcG9uc2VzOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50U2V0dGluZ3MubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudFNldHRpbmdzW2ldWydTZXR0aW5nRGF0YSddICYmIGVsZW1lbnRTZXR0aW5nc1tpXVsnU2V0dGluZ0RhdGEnXVsnUmVmZXJlbmNlUGFyYW1ldGVycyddWydTZWxlY3RvclNldCddWydTZWxlY3RvciddWydWYWx1ZSddID09ICgnSW50ZWwocikgSVBTIElQdjYgU2V0dGluZ3MgJyArIG5ldGlmaWQpKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBjbG9uZSA9IENsb25lKGVsZW1lbnRTZXR0aW5nc1tpXSk7DQogICAgICAgICAgICAgICAgICAgIGNsb25lWydJc0N1cnJlbnQnXSA9ICgoZDIxbzAuY2hlY2tlZCk/MjoxKTsNCiAgICAgICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCJDSU1fRWxlbWVudFNldHRpbmdEYXRhIiwgY2xvbmUsIHNob3dJUHY2U3RhdGVEbGdEb25lKTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93SVB2NlN0YXRlRGxnRG9uZShzdGFjaywgbmFtZSwgcmVzcG9uc2UsIHN0YXR1cykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSAyMDApIHsNCiAgICAgICAgICAgICAgICBhbXRzeXNzdGF0ZSA9IHVuZGVmaW5lZDsNCiAgICAgICAgICAgICAgICBQdWxsU3lzdGVtU3RhdHVzKCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goJ0lQdjYgc3VwcG9ydCcsICdVbmFibGUgdG8gc2V0IElQdjYgc3RhdGUsIGVycm9yICcgKyBzdGF0dXMpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd1BpbmdBY3Rpb25EbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgZyA9IGFtdHN5c3N0YXRlWydBTVRfR2VuZXJhbFNldHRpbmdzJ10ucmVzcG9uc2U7DQogICAgICAgICAgICB2YXIgdiA9IChnWyJQaW5nUmVzcG9uc2VFbmFibGVkIl0gPT0gdHJ1ZSkgKyAoKGdbIlJtY3BQaW5nUmVzcG9uc2VFbmFibGVkIl0gPT0gdHJ1ZSkgPDwgMSk7DQogICAgICAgICAgICBkMjBhLmNoZWNrZWQgPSAodiA9PSAwKTsNCiAgICAgICAgICAgIGQyMGIuY2hlY2tlZCA9ICh2ID09IDEpOw0KICAgICAgICAgICAgZDIwYy5jaGVja2VkID0gKHYgPT0gMik7DQogICAgICAgICAgICBkMjBkLmNoZWNrZWQgPSAodiA9PSAzKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMjAsICdJbnRlbCZyZWc7IEFNVCBQaW5nIFJlc3BvbnNlJywgMywgc2hvd1BpbmdBY3Rpb25EbGdPayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93UGluZ0FjdGlvbkRsZ09rKCkgew0KICAgICAgICAgICAgdmFyIGNsb25lID0gQ2xvbmUoYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZSk7DQogICAgICAgICAgICB2YXIgdiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2lucHV0W25hbWU9ZDIwXTpjaGVja2VkJykudmFsdWU7DQogICAgICAgICAgICBjbG9uZVsiUGluZ1Jlc3BvbnNlRW5hYmxlZCJdID0gKCh2ICYgMSkgIT0gMCk7DQogICAgICAgICAgICBjbG9uZVsiUm1jcFBpbmdSZXNwb25zZUVuYWJsZWQiXSA9ICgodiAmIDIpICE9IDApOw0KICAgICAgICAgICAgYW10c3RhY2suUHV0KCJBTVRfR2VuZXJhbFNldHRpbmdzIiwgY2xvbmUsIFB1bGxTeXN0ZW1TdGF0dXMsIDAsIDEpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0lQU2V0dXBEbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9IGFtdHN5c3N0YXRlWydBTVRfRXRoZXJuZXRQb3J0U2V0dGluZ3MnXS5yZXNwb25zZXNbMF07DQogICAgICAgICAgICBRVignaWRfZDIxbWFudWFsZGl2JywgdHJ1ZSk7DQogICAgICAgICAgICBRVignaWRfZDIxc3VibmV0ZGl2JywgdHJ1ZSk7DQogICAgICAgICAgICBRVignZDIxbzAnLCBmYWxzZSk7DQogICAgICAgICAgICBRVignZDIxbDAnLCBmYWxzZSk7DQogICAgICAgICAgICBRSCgnZDIxbDEnLCAnQXV0b21hdGljIGNvbmZpZ3VyYXRpb24gdXNpbmcgREhDUCBzZXJ2ZXInKTsNCiAgICAgICAgICAgIFFIKCdkMjFsMicsICdTdGF0aWMgY29uZmlndXJhdGlvbiB1c2luZyBJUHY0IHNldHRpbmdzIGJlbG93Jyk7DQogICAgICAgICAgICBkMjFvMS5jaGVja2VkID0gKHhbJ0RIQ1BFbmFibGVkJ10gPT0gdHJ1ZSk7DQogICAgICAgICAgICBkMjFvMi5jaGVja2VkID0gIWQyMW8xLmNoZWNrZWQ7DQogICAgICAgICAgICBpZHhfZDIxYWRkcmVzcy52YWx1ZSA9IGlzSXBBZGRyZXNzKHhbIklQQWRkcmVzcyJdLCcnKTsNCiAgICAgICAgICAgIGlkeF9kMjFzdWJuZXQudmFsdWUgPSBpc0lwQWRkcmVzcyh4WyJTdWJuZXRNYXNrIl0sJycpOw0KICAgICAgICAgICAgaWR4X2QyMWdhdGV3YXkudmFsdWUgPSBpc0lwQWRkcmVzcyh4WyJEZWZhdWx0R2F0ZXdheSJdLCcnKTsNCiAgICAgICAgICAgIGlkeF9kMjFkbnMxLnZhbHVlID0gaXNJcEFkZHJlc3MoeFsiUHJpbWFyeUROUyJdLCcnKTsNCiAgICAgICAgICAgIGlkeF9kMjFkbnMyLnZhbHVlID0gaXNJcEFkZHJlc3MoeFsiU2Vjb25kYXJ5RE5TIl0sJycpOw0KICAgICAgICAgICAgdXBkYXRlSVBTZXR1cERsZygpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgyMSwgJ0lQdjQgU2V0dGluZ3MnLCAzLCBzaG93SVBTZXR1cERsZ09rKQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXBkYXRlSVBTZXR1cERsZygpIHsNCiAgICAgICAgICAgIGlkeF9kMjFhZGRyZXNzLmRpc2FibGVkID0gaWR4X2QyMXN1Ym5ldC5kaXNhYmxlZCA9IGlkeF9kMjFnYXRld2F5LmRpc2FibGVkID0gaWR4X2QyMWRuczEuZGlzYWJsZWQgPSBpZHhfZDIxZG5zMi5kaXNhYmxlZCA9ICFkMjFvMi5jaGVja2VkOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0lQU2V0dXBEbGdPaygpIHsNCiAgICAgICAgICAgIHZhciB4ID0gQ2xvbmUoYW10c3lzc3RhdGVbJ0FNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyddLnJlc3BvbnNlc1swXSk7DQogICAgICAgICAgICB4WydESENQRW5hYmxlZCddID0gZDIxbzEuY2hlY2tlZDsNCiAgICAgICAgICAgIGRlbGV0ZSB4WyJJUEFkZHJlc3MiXTsNCiAgICAgICAgICAgIGRlbGV0ZSB4WyJTdWJuZXRNYXNrIl07DQogICAgICAgICAgICBkZWxldGUgeFsiRGVmYXVsdEdhdGV3YXkiXTsNCiAgICAgICAgICAgIGRlbGV0ZSB4WyJQcmltYXJ5RE5TIl07DQogICAgICAgICAgICBkZWxldGUgeFsiU2Vjb25kYXJ5RE5TIl07DQogICAgICAgICAgICBpZiAoZDIxbzEuY2hlY2tlZCA9PSBmYWxzZSkgew0KICAgICAgICAgICAgICAgIHhbIklQQWRkcmVzcyJdID0gaWR4X2QyMWFkZHJlc3MudmFsdWU7DQogICAgICAgICAgICAgICAgeFsiU3VibmV0TWFzayJdID0gaWR4X2QyMXN1Ym5ldC52YWx1ZTsNCiAgICAgICAgICAgICAgICB4WyJEZWZhdWx0R2F0ZXdheSJdID0gaWR4X2QyMWdhdGV3YXkudmFsdWU7DQogICAgICAgICAgICAgICAgaWYgKGlkeF9kMjFkbnMxLnZhbHVlICE9ICcnKSB4WyJQcmltYXJ5RE5TIl0gPSBpZHhfZDIxZG5zMS52YWx1ZTsNCiAgICAgICAgICAgICAgICBpZiAoaWR4X2QyMWRuczIudmFsdWUgIT0gJycpIHhbIlNlY29uZGFyeUROUyJdID0gaWR4X2QyMWRuczIudmFsdWU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBhbXRzdGFjay5QdXQoIkFNVF9FdGhlcm5ldFBvcnRTZXR0aW5ncyIsIHgsIHNob3dJUFNldHVwRGxnRG9uZSwgMCwgMSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93SVBTZXR1cERsZ0RvbmUoc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSB7DQogICAgICAgICAgICAgICAgYW10c3lzc3RhdGUgPSB1bmRlZmluZWQ7DQogICAgICAgICAgICAgICAgUHVsbFN5c3RlbVN0YXR1cygpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBtZXNzYWdlYm94KCdJUHY0IFNldHRpbmdzJywgJ1VuYWJsZSB0byBzZXQgbmV0d29yayBwYXJhbWV0ZXJzLCBlcnJvciAnICsgc3RhdHVzKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQoNCg0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gU3RvcmFnZQ0KICAgICAgICAvLw0KDQogICAgICAgIHZhciB4eFN0b3JhZ2UgPSBudWxsOw0KICAgICAgICB2YXIgeHhTdG9yYWdlVmVuZG9ycyA9IFtdOw0KICAgICAgICB2YXIgeHhTdG9yYWdlQXBwbGljYXRpb25zID0gW107DQoNCiAgICAgICAgZnVuY3Rpb24gUHVsbFN0b3JhZ2UoKSB7DQogICAgICAgICAgICBhbXRGaXJzdFB1bGwgfD0gODsNCiAgICAgICAgICAgIHdzc3RhY2suY29tbS5QZXJmb3JtQWpheCgiIiwgUHVsbFN0b3JhZ2VSZXNwb25zZSwgbnVsbCwgMCwgIi9hbXQtc3RvcmFnZS8iLCAiR0VUIik7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBQdWxsU3RvcmFnZVJlc3BvbnNlKGRhdGEsIHN0YXR1cywgdGFnKSB7DQogICAgICAgICAgICBpZiAoYW10c3RhY2suUGVuZGluZ0JhdGNoT3BlcmF0aW9ucyA9PSAwKSByZWZyZXNoQnV0dG9ucyh0cnVlKTsgLy8gSWYgbm90aGluZyBpcyBiZWluZyBkb25lLCByZS1lbmFibGUgcmVmcmVzaCBidXR0b25zDQogICAgICAgICAgICANCiAgICAgICAgICAgIGlmIChzdGF0dXMgPT0gMjAwKSB7DQogICAgICAgICAgICAgICAgUVYoJ2dvMjEnLCB0cnVlKTsgLy8gU2hvdyBTdG9yYWdlIFBhbmVsDQoNCiAgICAgICAgICAgICAgICB2YXIgbGVuOyAvLyBSZW1vdmUgYWxsIGNoYXJzIHRoYXQgYXJlIGJlbG93IDMyLCB0aGlzIHdpbGwgYWxsb3cgcGFyc2luZyBldmVuIHRoZSB0aGUgZmlybXdhcmUgZ2l2ZXMgdXMgZ2FyYmFnZS4NCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDMyOyBpKyspIHsgZG8geyBsZW4gPSBkYXRhLmxlbmd0aDsgZGF0YSA9IGRhdGEucmVwbGFjZShTdHJpbmcuZnJvbUNoYXJDb2RlKGkpLCAnJyk7IH0gd2hpbGUgKGxlbiA+IGRhdGEubGVuZ3RoKTsgfQ0KICAgICAgICAgICAgICAgIC8vZGF0YSA9ICd7ImluZm9ybWF0aW9uIjogeyJ2ZXJzaW9uIjogMS4xLCJyZWFsbXMiOiA3NzY1NzU5LCJ1c2VyIjogImFkbWluIn0sImNvbnRlbnQiOiBbeyJuYW1lIjogImluZGV4Lmh0bSIsInNpemUiOiAzODg2NH0seyJ2ZW5kb3IiOiAiVXNlciIsImFwcCI6ICJTREsiLCJuYW1lIjogIlNhbXBsZS5odG1sIiwic2l6ZSI6IDI2NzYwLCJsaW5rIjogIlNESyBTYW1wbGUifSx7InZlbmRvciI6ICJVc2VyIiwiYXBwIjogIlNESyIsIm5hbWUiOiAid3MuanMiLCJzaXplIjogNDI1NzUsImxpbmsiOiAiU0RLIFNhbXBsZSJ9LHsidmVuZG9yIjogIlVzZXIiLCJhcHAiOiAiU0RLIiwibmFtZSI6ICJidHAubWluLmNzcyIsInNpemUiOiAxMjEyNjUsImxpbmsiOiAiU0RLIFNhbXBsZSJ9LHsidmVuZG9yIjogIlVzZXIiLCJhcHAiOiAiU0RLIiwibmFtZSI6ICJsb2dvLnBuZyIsInNpemUiOiAyODAzLCJsaW5rIjogIlNESyBTYW1wbGUifV19JzsNCiAgICAgICAgICAgICAgICB0cnkgeyB4eFN0b3JhZ2UgPSBKU09OLnBhcnNlKGRhdGEpOyB9IGNhdGNoIChlKSB7IHJldHVybjsgfQ0KICAgICAgICAgICAgICAgIHh4U3RvcmFnZVZlbmRvcnMgPSBbXTsNCiAgICAgICAgICAgICAgICB4eFN0b3JhZ2VBcHBsaWNhdGlvbnMgPSBbXTsNCiAgICAgICAgICAgICAgICB2YXIgY29udGVudCA9IHh4U3RvcmFnZVsnY29udGVudCddOw0KDQogICAgICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29udGVudCkpIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gTmV3IGZsYXQgZm9ybWF0LCBjb252ZXJ0IHRvIHRyZWUgZm9ybWF0Lg0KICAgICAgICAgICAgICAgICAgICB2YXIgbmV3Y29udGVudCA9IHt9Ow0KICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIGNvbnRlbnQpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2ZW5kb3IgPSBjb250ZW50W2ldWyJ2ZW5kb3IiXSA/IGNvbnRlbnRbaV1bInZlbmRvciJdIDogJyc7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIW5ld2NvbnRlbnRbdmVuZG9yXSkgeyBuZXdjb250ZW50W3ZlbmRvcl0gPSB7fTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGFwcCA9IGNvbnRlbnRbaV1bImFwcCJdID8gY29udGVudFtpXVsiYXBwIl0gOiAnJzsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbmV3Y29udGVudFt2ZW5kb3JdW2FwcF0pIHsgbmV3Y29udGVudFt2ZW5kb3JdW2FwcF0gPSB7fTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRbaV1bIm5hbWUiXSkgeyBuZXdjb250ZW50W3ZlbmRvcl1bYXBwXVtjb250ZW50W2ldWyJuYW1lIl1dID0gY29udGVudFtpXTsgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIHh4U3RvcmFnZVsnY29udGVudCddID0gY29udGVudCA9IG5ld2NvbnRlbnQ7DQogICAgICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gVHJlZSBmb3JtYXQsIG1vdmUgaW5kZXguaHRtIGFuZCBsb2dvbi5odG0NCiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRbJ2luZGV4Lmh0bSddIHx8IGNvbnRlbnRbJ2xvZ29uLmh0bSddKSB7IGNvbnRlbnRbJyddID0geyAnJzoge30gfTsgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoY29udGVudFsnaW5kZXguaHRtJ10pIHsgY29udGVudFsnJ11bJyddWydpbmRleC5odG0nXSA9IGNvbnRlbnRbJ2luZGV4Lmh0bSddOyBkZWxldGUgY29udGVudFsnaW5kZXguaHRtJ107IH0NCiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRbJ2xvZ29uLmh0bSddKSB7IGNvbnRlbnRbJyddWycnXVsnbG9nb24uaHRtJ10gPSBjb250ZW50Wydsb2dvbi5odG0nXTsgZGVsZXRlIGNvbnRlbnRbJ2xvZ29uLmh0bSddOyB9DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgLy8gRGlzcGxheSBhbGwgc3RvcmFnZSBmaWxlcw0KICAgICAgICAgICAgICAgIHZhciBjb3VudCA9IDAsIHggPSBUYWJsZVN0YXJ0MigpICsgIjx0cj48dGQgY2xhc3M9cjEgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPk1hbmFnZSBJbnRlbCZyZWc7IEFNVCBzdG9yYWdlIGZvciB0aGlzIGNvbXB1dGVyLjxicj48YnI+IjsNCiAgICAgICAgICAgICAgICB2YXIgaWksIGpqLCB4eCA9ICIiLCBsaW5rcyA9ICIiLCBsaW5raWQgPSAzMDsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIGNvbnRlbnQpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGpjb3VudCA9IDA7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gY29udGVudFtpXSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgamNvdW50Kys7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIga2NvdW50ID0gMDsNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGsgaW4gY29udGVudFtpXVtqXSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtjb3VudCsrOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpICE9IGlpIHx8IGogIT0gamopIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHh4ICE9ICIiKSB7IHggKz0geHg7IHh4ID0gIjxicj4iOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlpID0gaTsgamogPSBqOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaSAhPSAnJykgeyB4eCArPSBFc2NhcGVIdG1sKGkgKyAiIC8gIiArIGopOyB9IGVsc2UgeyB4eCArPSAiUm9vdCIgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3ZhciBoYW5kbGUgPSAiXCIiICsgaSArICJcIixcIiIgKyBqICsgIlwiLFwiIiArIGsgKyAiXCIiOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYW5kbGUgPSAiXCIiICsgaSArICgoaSAhPSAnJykgPyAnLycgOiAnJykgKyBqICsgKChqICE9ICcnKSA/ICcvJyA6ICcnKSArIGsgKyAiXCIiOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHh4ICs9ICc8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93U3RvcmFnZURldGFpbHMoIicgKyBpICsgJyIsIicgKyBqICsgJyIsIicgKyBrICsgJyIsJyArIGhhbmRsZSArICcpPjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ+JzsNCg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHh4ICs9ICIgIiArIEFkZEJ1dHRvbjIoIk9wZW4iLCAiT3BlbkZyb21TdG9yYWdlKCIgKyBoYW5kbGUgKyAiLGV2ZW50KSIpOw0KDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeHggKz0gIiAiICsgQWRkQnV0dG9uMigiRG93bmxvYWQiLCAiRG93bmxvYWRGcm9tU3RvcmFnZSgiICsgaGFuZGxlICsgIixcIiIgKyBrICsgIlwiLGV2ZW50KSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHh4ICs9ICI8L2Rpdj48ZGl2IHN0eWxlPXBhZGRpbmctdG9wOjNweD48Yj4iICsgRXNjYXBlSHRtbChrKSArICI8L2I+LCA8aT4iICsgY29udGVudFtpXVtqXVtrXVsnc2l6ZSddICsgIiBieXRlczwvaT48L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50Kys7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHh4U3RvcmFnZVZlbmRvcnMuaW5kZXhPZihpKSA9PSAtMSkgeHhTdG9yYWdlVmVuZG9ycy5wdXNoKGkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4eFN0b3JhZ2VBcHBsaWNhdGlvbnMuaW5kZXhPZihqKSA9PSAtMSkgeHhTdG9yYWdlQXBwbGljYXRpb25zLnB1c2goaik7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2NvdW50ID09IDApIHsgIC8vIENsZWFyIGVtcHR5IGFwcGxpY2F0aW9uICYgdmVuZG9yDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBmdW5jdGlvbiAoKSB7IH0sIG51bGwsIDAsICIvYW10LXN0b3JhZ2UvIiArIGkgKyAiLyIgKyBqLCAiREVMRVRFIik7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBmdW5jdGlvbiAoKSB7IH0sIG51bGwsIDAsICIvYW10LXN0b3JhZ2UvIiArIGksICJERUxFVEUiKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAoamNvdW50ID09IDApIHsgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBmdW5jdGlvbiAoKSB7IH0sIG51bGwsIDAsICIvYW10LXN0b3JhZ2UvIiArIGksICJERUxFVEUiKTsgfSAvLyBDbGVhciBlbXB0eSB2ZW5kb3INCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgaWYgKHh4ICE9ICIiKSB4ICs9IHh4Ow0KICAgICAgICAgICAgICAgIGlmIChjb3VudCA9PSAwKSB7IHggKz0gIjxkaXYgc3R5bGU9cGFkZGluZy1sZWZ0OjE1cHg+PGJyPjxpPk5vIGZpbGVzIGZvdW5kLjwvaT48L2Rpdj48YnI+IjsgfQ0KICAgICAgICAgICAgICAgIHggKz0gIjxicj48dGQgY2xhc3M9cjE+IiArIFRhYmxlRW5kKEFkZFJlZnJlc2hCdXR0b24oIlB1bGxTdG9yYWdlKCkiKSArIEFkZEJ1dHRvbigiVXBsb2FkLi4uIiwgIlVwbG9hZFRvU3RvcmFnZSgpIikNCiAgICAgICAgICAgICAgICApOw0KICAgICAgICAgICAgICAgIFFIKCdpZF9UYWJsZVN5c3RlbVN0b3JhZ2UnLCB4KTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgUUgoJ2lkX1RhYmxlU3lzdGVtU3RvcmFnZScsICdVbmFibGUgdG8gbG9hZCBzdG9yYWdlIGRhdGEuLi48YnIvPicgKyBBZGRCdXR0b24oIlJlZnJlc2giLCAiUHVsbFN0b3JhZ2UoKSIpKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dTdG9yYWdlRGV0YWlscyhpLCBqLCBrLCBoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9ICcnLCBpdGVtID0geHhTdG9yYWdlWydjb250ZW50J11baV1bal1ba107DQogICAgICAgICAgICBpZiAoaSAhPSAnJykgeCArPSBhZGRIdG1sVmFsdWUoIlZlbmRvciIsIGkpOw0KICAgICAgICAgICAgaWYgKGogIT0gJycpIHggKz0gYWRkSHRtbFZhbHVlKCJBcHBsaWNhdGlvbiIsIGopOw0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIk5hbWUiLCBrKTsNCiAgICAgICAgICAgIHggKz0gYWRkSHRtbFZhbHVlKCJTaXplIiwgaXRlbVsnc2l6ZSddICsgJyBieXRlcycpOw0KICAgICAgICAgICAgaWYgKGl0ZW1bJ2xpbmsnXSkgeyB4ICs9IGFkZEh0bWxWYWx1ZSgiTGluayIsIGl0ZW1bJ2xpbmsnXSk7IH0NCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdTdG9yYWdlIEl0ZW0nLCA1LCBzaG93U3RvcmFnZURldGFpbHNFeCwgeCwgaCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93U3RvcmFnZURldGFpbHNFeChidXR0b25zLCBoYW5kbGUpIHsNCiAgICAgICAgICAgIGlmIChidXR0b25zID09IDIpIHsgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBzdG9yYWdlRGVsZXRlUmVzcG9uc2UsIG51bGwsIDAsICcvYW10LXN0b3JhZ2UvJyArIGhhbmRsZSwgIkRFTEVURSIpOyB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzdG9yYWdlRGVsZXRlUmVzcG9uc2UoZGF0YSwgc3RhdHVzKSB7DQogICAgICAgICAgICBpZiAoc3RhdHVzICE9IDIwMCkgew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goIlN0b3JhZ2UiLCAiVW5hYmxlIHRvIGRlbGV0ZSBmaWxlIChFUlIiICsgc3RhdHVzICsgIiksIGNoZWNrIHRoYXQgdGhlIGNvbXB1dGVyIGlzIHBvd2VyZWQgb24uIik7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFB1bGxTdG9yYWdlKCk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KDQogICAgICAgIGZ1bmN0aW9uIERvd25sb2FkRnJvbVN0b3JhZ2UoaGFuZGxlLCBmaWxlbmFtZSwgZSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgaGFsdEV2ZW50KGUpOw0KICAgICAgICAgICAgd3NzdGFjay5jb21tLlBlcmZvcm1BamF4KCIiLCBEb3dubG9hZEZyb21TdG9yYWdlRXgsIGZpbGVuYW1lLCAwLCAnL2FtdC1zdG9yYWdlLycgKyBoYW5kbGUsICJHRVQiKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIERvd25sb2FkRnJvbVN0b3JhZ2VFeChkYXRhLCBzdGF0dXMsIHRhZykgew0KICAgICAgICAgICAgaWYgKChzdGF0dXMgIT0gMjAwKSB8fCAoZGF0YSA9PSBudWxsKSkgeyBjb25zb2xlLmxvZyhzdGF0dXMsICdEYXRhID0gbnVsbCcpOyByZXR1cm47IH0NCiAgICAgICAgICAgIHNhdmVBcyhkYXRhMmJsb2IoZGF0YSksIHRhZyk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBPcGVuRnJvbVN0b3JhZ2UoaGFuZGxlLCBlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQoNCiAgICAgICAgICAgIHZhciBuZXdXaW5kb3cgPSB3aW5kb3cub3BlbignaHR0cDovLycgKyB3c3N0YWNrLmNvbW0uaG9zdCArICc6JyArIHdzc3RhY2suY29tbS5wb3J0ICsgJy9hbXQtc3RvcmFnZS8nICsgaGFuZGxlLCAnX2JsYW5rJyk7DQogICAgICAgICAgICBuZXdXaW5kb3cub3BlbmVyID0gbnVsbDsNCiAgICAgICAgICAgIG5ld1dpbmRvdy5mb2N1cygpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gUHVzaFRvU3RvcmFnZSh2ZW5kb3JBcHBuYW1lRmlsZW5hbWUsIGRhdGEsIGFwcGVuZCkgew0KICAgICAgICAgICAgdmFyIHRhZyA9IG51bGw7DQogICAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggPiA3MDAwKSB7IHRhZyA9IFt2ZW5kb3JBcHBuYW1lRmlsZW5hbWUsIGRhdGEuc3Vic3RyaW5nKDcwMDApXTsgZGF0YSA9IGRhdGEuc3Vic3RyaW5nKDAsIDcwMDApOyB9DQogICAgICAgICAgICB3c3N0YWNrLmNvbW0uUGVyZm9ybUFqYXgoZGF0YSwgUHVzaFRvU3RvcmFnZVJlc3BvbnNlLCB0YWcsIDAsICIvYW10LXN0b3JhZ2UvIiArIHZlbmRvckFwcG5hbWVGaWxlbmFtZSArIChhcHBlbmQgPT0gdHJ1ZSA/ICI/YXBwZW5kPSIgOiAiIiksICJQVVQiKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIFB1c2hUb1N0b3JhZ2VSZXNwb25zZShkYXRhLCBzdGF0dXMsIHRhZykgew0KICAgICAgICAgICAgaWYgKHN0YXR1cyAhPSAyMDApIHsgbWVzc2FnZWJveCgiU3RvcmFnZSIsICJVbmFibGUgdG8gcHVzaCBmaWxlIChFUlIiICsgc3RhdHVzICsgIiksIGNoZWNrIHRoYXQgdGhlIGNvbXB1dGVyIGlzIHBvd2VyZWQgb24uIik7IH0gZWxzZSB7DQogICAgICAgICAgICAgICAgaWYgKHRhZyAhPSBudWxsKSB7IFB1c2hUb1N0b3JhZ2UodGFnWzBdLCB0YWdbMV0sIHRydWUpOyB9IGVsc2UgeyBQdWxsU3RvcmFnZSgpOyB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBVcGxvYWRUb1N0b3JhZ2UoZmlsZSwgZmlsZW5hbWUpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIGlmICghZmlsZW5hbWUpIHsgZmlsZW5hbWUgPSAnJzsgfQ0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIHggKz0gJzxicj5TZWxlY3QgYSBzbWFsbCBmaWxlIHRvIHVwbG9hZCB0byBzdG9yYWdlIGFuZCBlbnRlciBhIHZlbmRvciwgYXBwbGljYXRpb24gYW5kIGZpbGVuYW1lLjxicj4nOw0KICAgICAgICAgICAgaWYgKCFmaWxlKSB7DQogICAgICAgICAgICAgICAgeCArPSAnPGJyPjxkaXYgc3R5bGU9aGVpZ2h0OjIwcHg+PGlucHV0IHR5cGU9ZmlsZSBpZD1tc3RvcmFnZWZpbGUgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjQwcHggb25jaGFuZ2U9U2V0U3RvcmFnZU5hbWUoKT48ZGl2PlVwbG9hZCBmaWxlPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgeCArPSAnPGJyPjxkaXYgc3R5bGU9aGVpZ2h0OjIwcHg+PGlucHV0IGlkPW1zdG9yYWdlZmlsZSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweCByZWFkb25seSBkaXNhYmxlZD1kaXNhYmxlZCB2YWx1ZT0iJyArIGZpbGVuYW1lICsgJyIgPjxkaXY+VXBsb2FkIGZpbGU8L2Rpdj48L2Rpdj4nOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgeCArPSAnPGJyPjxkaXYgc3R5bGU9aGVpZ2h0OjE2cHg+PGlucHV0IGlkPW1zdG9yYWdldmVuZG9yIHBsYWNlaG9sZGVyPVZlbmRvciBsaXN0PW1zdG9yYWdldmVuZG9ybGlzdCBtYXhsZW5ndGg9MTEgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjQwcHg+PGRpdj5WZW5kb3IgbmFtZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8YnI+PGRpdiBzdHlsZT1oZWlnaHQ6MTZweD48aW5wdXQgaWQ9bXN0b3JhZ2VhcHBsaWNhdGlvbiBwbGFjZWhvbGRlcj1BcHAgbGlzdD1tc3RvcmFnZWFwcGxpY2F0aW9ubGlzdCBtYXhsZW5ndGg9MTEgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjQwcHg+PGRpdj5BcHBsaWNhdGlvbiBuYW1lPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxicj48ZGl2IHN0eWxlPWhlaWdodDoxNnB4PjxpbnB1dCBpZD1tc3RvcmFnZWZpbGVuYW1lIHBsYWNlaG9sZGVyPUZpbGVuYW1lIG1heGxlbmd0aD0xMSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweD48ZGl2PkZpbGVuYW1lPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgIHggKz0gJzxicj48ZGl2IHN0eWxlPWhlaWdodDoxNnB4PjxpbnB1dCBpZD1tc3RvcmFnZXR5cGUgcGxhY2Vob2xkZXI9YXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIGxpc3Q9bXN0b3JhZ2V0eXBlbGlzdCBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNDBweD48ZGl2Pk1JTUUgVHlwZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB4ICs9ICc8YnI+PGRpdiBzdHlsZT1oZWlnaHQ6MTZweD48aW5wdXQgaWQ9bXN0b3JhZ2VsaW5rIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI0MHB4PjxkaXYgdGl0bGU9IklmIHNldCwgY3JlYXRlcyBhIGxpbmsgdG8gdGhpcyBjb250ZW50IGZyb20gdGhlIG1haW4gd2ViIHBhZ2UiPkxpbms8L2Rpdj48L2Rpdj48YnI+JzsNCiAgICAgICAgICAgIHggKz0gJzxkYXRhbGlzdCBpZD1tc3RvcmFnZXZlbmRvcmxpc3Q+JzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4geHhTdG9yYWdlVmVuZG9ycykgeyB4ICs9ICc8b3B0aW9uIHZhbHVlPSInICsgeHhTdG9yYWdlVmVuZG9yc1tpXSArICciPic7IH0NCiAgICAgICAgICAgIHggKz0gJzwvZGF0YWxpc3Q+JzsNCiAgICAgICAgICAgIHggKz0gJzxkYXRhbGlzdCBpZD1tc3RvcmFnZWFwcGxpY2F0aW9ubGlzdD4nOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB4eFN0b3JhZ2VBcHBsaWNhdGlvbnMpIHsgeCArPSAnPG9wdGlvbiB2YWx1ZT0iJyArIHh4U3RvcmFnZUFwcGxpY2F0aW9uc1tpXSArICciPic7IH0NCiAgICAgICAgICAgIHggKz0gJzwvZGF0YWxpc3Q+PGRhdGFsaXN0IGlkPW1zdG9yYWdldHlwZWxpc3Q+PG9wdGlvbiB2YWx1ZT0iYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtIj48b3B0aW9uIHZhbHVlPSJpbWFnZS9qcGVnIj48b3B0aW9uIHZhbHVlPSJ0ZXh0L2h0bWwiPjxvcHRpb24gdmFsdWU9InRleHQvcGxhaW4iPjwvZGF0YWxpc3Q+JzsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsICdTdG9yYWdlIFVwbG9hZCcsIDMsIFVwbG9hZFRvU3RvcmFnZUV4LCB4LCBmaWxlKTsNCiAgICAgICAgICAgIGlmIChmaWxlKSB7IFNldFN0b3JhZ2VOYW1lKGZpbGVuYW1lKTsgfQ0KICAgICAgICB9DQoNCg0KICAgICAgICBmdW5jdGlvbiBVcGxvYWRUb1N0b3JhZ2VFeChidXR0b24sIHRhZykgew0KICAgICAgICAgICAgaWYgKCF0YWcpIHsNCiAgICAgICAgICAgICAgICB2YXIgeCA9IFEoJ21zdG9yYWdlZmlsZScpOw0KICAgICAgICAgICAgICAgIGlmICh4LmZpbGVzLmxlbmd0aCAhPSAxKSByZXR1cm47DQogICAgICAgICAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQogICAgICAgICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IFVwbG9hZFRvU3RvcmFnZUV4MjsNCiAgICAgICAgICAgICAgICByZWFkZXIuZmlsZW5hbWUgPSB4LmZpbGVzWzBdLm5hbWU7DQogICAgICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyh4LmZpbGVzWzBdKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQogICAgICAgICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IFVwbG9hZFRvU3RvcmFnZUV4MjsNCiAgICAgICAgICAgICAgICByZWFkZXIuZmlsZW5hbWUgPSBRKCdtc3RvcmFnZWZpbGUnKS52YWx1ZTsNCiAgICAgICAgICAgICAgICByZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKHRhZyk7DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBTZXRTdG9yYWdlTmFtZShmaWxlbmFtZSkgew0KICAgICAgICAgICAgaWYgKCFmaWxlbmFtZSkgew0KICAgICAgICAgICAgICAgIHZhciB4ID0gUSgnbXN0b3JhZ2VmaWxlJyk7DQogICAgICAgICAgICAgICAgaWYgKHguZmlsZXMubGVuZ3RoID09IDEpIHsgZmlsZW5hbWUgPSB4LmZpbGVzWzBdLm5hbWU7IH0gZWxzZSB7IGZpbGVuYW1lID0gJyc7IH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGZpbGVuYW1lID0gZmlsZW5hbWUuc3BsaXQoJyAnKS5qb2luKCcnKTsNCiAgICAgICAgICAgIHZhciBmaWxlbmFtZVNwbGl0ID0gZmlsZW5hbWUuc3BsaXQoJy0nKTsNCiAgICAgICAgICAgIGlmIChmaWxlbmFtZVNwbGl0Lmxlbmd0aCA9PSAzICYmIGZpbGVuYW1lU3BsaXRbMF0ubGVuZ3RoIDwgMTIgJiYgZmlsZW5hbWVTcGxpdFsxXS5sZW5ndGggPCAxMikgew0KICAgICAgICAgICAgICAgIFEoJ21zdG9yYWdldmVuZG9yJykudmFsdWUgPSBmaWxlbmFtZVNwbGl0WzBdOw0KICAgICAgICAgICAgICAgIFEoJ21zdG9yYWdlYXBwbGljYXRpb24nKS52YWx1ZSA9IGZpbGVuYW1lU3BsaXRbMV07DQogICAgICAgICAgICAgICAgZmlsZW5hbWUgPSBmaWxlbmFtZVNwbGl0WzJdOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZmlsZW5hbWUgPSBmaWxlbmFtZS5zcGxpdCgnLScpLmpvaW4oJycpOw0KICAgICAgICAgICAgaWYgKGZpbGVuYW1lLmVuZHNXaXRoKCcuZ3onKSkgZmlsZW5hbWUgPSBmaWxlbmFtZS5zdWJzdHJpbmcoMCwgZmlsZW5hbWUubGVuZ3RoIC0gMyk7DQogICAgICAgICAgICBpZiAoZmlsZW5hbWUuZW5kc1dpdGgoJy5odG0nKSB8fCBmaWxlbmFtZS5lbmRzV2l0aCgnLmh0bWwnKSkgUSgnbXN0b3JhZ2V0eXBlJykudmFsdWUgPSAidGV4dC9odG1sIjsNCiAgICAgICAgICAgIGVsc2UgaWYgKGZpbGVuYW1lLmVuZHNXaXRoKCcudHh0JykpIFEoJ21zdG9yYWdldHlwZScpLnZhbHVlID0gInRleHQvcGxhaW4iOw0KICAgICAgICAgICAgaWYgKGZpbGVuYW1lLmxlbmd0aCA+IDExKSBmaWxlbmFtZSA9IGZpbGVuYW1lLnN1YnN0cmluZygwLCAxMSk7DQogICAgICAgICAgICBRKCdtc3RvcmFnZWZpbGVuYW1lJykudmFsdWUgPSBmaWxlbmFtZTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIFVwbG9hZFRvU3RvcmFnZUV4MihmaWxlKSB7DQogICAgICAgICAgICB2YXIgdmFmLCB2ZW5kb3IgPSBRKCdtc3RvcmFnZXZlbmRvcicpLnZhbHVlOw0KICAgICAgICAgICAgdmFyIGFwcCA9IFEoJ21zdG9yYWdlYXBwbGljYXRpb24nKS52YWx1ZTsNCiAgICAgICAgICAgIHZhciBmaWxlbmFtZSA9IFEoJ21zdG9yYWdlZmlsZW5hbWUnKS52YWx1ZTsNCiAgICAgICAgICAgIGlmIChmaWxlbmFtZSA9PSAnJykgZmlsZW5hbWUgPSAnRmlsZW5hbWUnOw0KICAgICAgICAgICAgdmFyIG1pbWV0eXBlID0gUSgnbXN0b3JhZ2V0eXBlJykudmFsdWU7DQogICAgICAgICAgICBpZiAobWltZXR5cGUgPT0gJycpIG1pbWV0eXBlID0gJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbSc7DQogICAgICAgICAgICB2YXIgbGluayA9IFEoJ21zdG9yYWdlbGluaycpLnZhbHVlOw0KICAgICAgICAgICAgaWYgKHZlbmRvciA9PSAnJyAmJiBhcHAgPT0gJycgJiYgKGZpbGVuYW1lLnRvTG93ZXJDYXNlKCkgPT0gJ2xvZ29uLmh0bScgfHwgZmlsZW5hbWUudG9Mb3dlckNhc2UoKSA9PSAnaW5kZXguaHRtJykpIHsNCiAgICAgICAgICAgICAgICB2YWYgPSBmaWxlbmFtZS50b0xvd2VyQ2FzZSgpOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBpZiAodmVuZG9yID09ICcnKSB2ZW5kb3IgPSAnVmVuZG9yJzsNCiAgICAgICAgICAgICAgICBpZiAoYXBwID09ICcnKSBhcHAgPSAnQXBwJzsNCiAgICAgICAgICAgICAgICB2YWYgPSB2ZW5kb3IgKyAiLyIgKyBhcHAgKyAiLyIgKyBmaWxlbmFtZTsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgdmFyIGRhdGEgPSAiPG1ldGFkYXRhPjxoZWFkZXJzPiI7DQogICAgICAgICAgICB2YXIgZmlsZW5hbWUgPSBmaWxlLnRhcmdldC5maWxlbmFtZTsNCiAgICAgICAgICAgIGlmICghZmlsZW5hbWUpIHsgZmlsZW5hbWUgPSBRKCdtc3RvcmFnZWZpbGUnKS5maWxlc1swXS5uYW1lOyB9DQogICAgICAgICAgICBpZiAoZmlsZW5hbWUuZW5kc1dpdGgoJy5neicpKSB7IGRhdGEgKz0gIjxoPkNvbnRlbnQtRW5jb2Rpbmc6IGd6aXA8L2g+IjsgfQ0KICAgICAgICAgICAgZGF0YSArPSAiPGg+Q29udGVudC1UeXBlOiAiICsgbWltZXR5cGUgKyAiPC9oPjwvaGVhZGVycz4iOyAvLyA8aD5YLVVBLUNvbXBhdGlibGU6IElFPUVkZ2U8L2g+DQogICAgICAgICAgICBpZiAobGluayAhPSAnJykgZGF0YSArPSAiPGxpbms+IiArIGxpbmsgKyAiPC9saW5rPiI7DQogICAgICAgICAgICBkYXRhICs9ICI8L21ldGFkYXRhPiIgKyBmaWxlLnRhcmdldC5yZXN1bHQ7DQoNCiAgICAgICAgICAgIFB1c2hUb1N0b3JhZ2UodmFmLCBkYXRhKTsNCiAgICAgICAgfQ0KDQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIEFsYXJtIFBhbmVsDQogICAgICAgIC8vDQoNCiAgICAgICAgZnVuY3Rpb24gX2ZtdGRhdGV0aW1lKHN0cikgew0KICAgICAgICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKCJUIiwiICIpLnJlcGxhY2UoIloiLCIiKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIF9mbXRpbnRlcnZhbChzdHIpIHsNCiAgICAgICAgICAgIHZhciBjbCA9IHN0ci5yZXBsYWNlKCJUIiwgIiIpLnN1YnN0cmluZyhzdHIuaW5kZXhPZignUCcpICsgMSk7DQogICAgICAgICAgICBjbCA9ICcgJyArIGNsLnJlcGxhY2UoIkQiLCAiIGRheXMgIikucmVwbGFjZSgiSCIsICIgaG91cnMgIikucmVwbGFjZSgiTSIsIiBtaW51dGVzICIpOw0KICAgICAgICAgICAgY2wgPSBjbC5yZXBsYWNlKCIgMSBkYXlzICIsICIgMSBkYXkgIikucmVwbGFjZSgiIDEgaG91cnMgIiwgIiAxIGhvdXIgIikucmVwbGFjZSgiIDEgbWludXRlcyAiLCIgMSBtaW51dGUgIik7DQogICAgICAgICAgICByZXR1cm4gY2wuc3Vic3RyaW5nKDAsIGNsLmxlbmd0aCAtIDEpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gX2ZtdHRpbWVwYWQoc3RyKSB7DQogICAgICAgICAgICBzdHIgPSAnJyArIHN0cjsNCiAgICAgICAgICAgIHdoaWxlIChzdHIubGVuZ3RoIDwgMikgeyBzdHIgPSAnMCcgKyBzdHI7IH0NCiAgICAgICAgICAgIHJldHVybiBzdHI7DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgeHhBbGFybXMgPSBudWxsOw0KDQogICAgICAgIGZ1bmN0aW9uIFB1bGxBbGFybXMoKSB7DQogICAgICAgICAgICB2YXIgeCA9IFRhYmxlU3RhcnQyKCkgKyAiPHRyPjx0ZCBjbGFzcz1yMSBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD48YnI+TWFuYWdlIHdha2UgYWxhcm1zLjxicj48YnI+Ig0KICAgICAgICAgICAgYW10c3RhY2suRW51bSgiSVBTX0FsYXJtQ2xvY2tPY2N1cnJlbmNlIiwgZnVuY3Rpb24oc3RhY2ssIG5hbWUsIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICBpZiAoc3RhdHVzID09IDIwMCkgew0KICAgICAgICAgICAgICAgICAgICBRVigiZ28yMyIsIHRydWUpOw0KICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UubGVuZ3RoID4gMCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgeHhBbGFybXMgPSByZXNwb25zZTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmVzcG9uc2UubGVuZ3RoOyBpKyspIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgd2FrZXRpbWUgPSBuZXcgRGF0ZShyZXNwb25zZVtpXVsiU3RhcnRUaW1lIl1bIkRhdGV0aW1lIl0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBkZXRhaWxzID0gJzxiPicgKyByZXNwb25zZVtpXVsiRWxlbWVudE5hbWUiXSArICc8L2I+LCB3YWtlIG9uICcgKyB3YWtldGltZS50b0xvY2FsZVN0cmluZygpLnJlcGxhY2UoJywgJywgJyBhdCAnKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2VbaV1bIkludGVydmFsIl0gIT0gdW5kZWZpbmVkKSB7IGRldGFpbHMgKz0gJyBhbmQgZWFjaCcgKyBfZm10aW50ZXJ2YWwocmVzcG9uc2VbaV1bIkludGVydmFsIl1bIkludGVydmFsIl0pOyB9DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNlW2ldWyJEZWxldGVPbkNvbXBsZXRpb24iXSA9PSB0cnVlKSB7IGRldGFpbHMgKz0gJywgZGVsZXRlIHdoZW4gZG9uZSc7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IGNsYXNzPWl0ZW1CYXIgb25jbGljaz1zaG93QWxlcnREZXRhaWxzKCIgKyBpICsgIik+PGRpdiBzdHlsZT1mbG9hdDpyaWdodD4iOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHggKz0gIiAiICsgQWRkQnV0dG9uMigiRWRpdC4uLiIsICJzaG93QWRkQWxhcm0oIiArIGkgKyAiKSIpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gIjwvZGl2PjxkaXYgc3R5bGU9cGFkZGluZy10b3A6M3B4O3dpZHRoOmF1dG87ZmxvYXQ6bGVmdDtvdmVyZmxvdy14OmhpZGRlbj4iICsgZGV0YWlscyArICI8L2Rpdj48L2Rpdj4iOw0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgeHhBbGFybXMgPSBudWxsOw0KICAgICAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD48YnI+PGk+Tm8gd2FrZSBhbGFybXMgcmVnaXN0ZXJlZC48L2k+PC9kaXY+PGJyPiI7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgdmFyIHkgPSAiPGRpdj4mbmJzcDsiICsgQWRkUmVmcmVzaEJ1dHRvbigiUHVsbEFsYXJtcygpIik7DQogICAgICAgICAgICAgICAgICAgIGlmICh4eEFjY291bnRBZG1pbk5hbWUpIHsgeSArPSBBZGRCdXR0b24oIlJlbW92ZSBhbGwgYWxhcm1zIiwgIlJlbW92ZUFsbEFsYXJtcygpIikgKyBBZGRCdXR0b24oIkFkZCIsICJzaG93QWRkQWxhcm0oKSIpOyB9DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjxicj48dGQgY2xhc3M9cjE+IiArIFRhYmxlRW5kKHkgKyAiPC9kaXY+Iik7DQogICAgICAgICAgICAgICAgICAgIFFIKCdpZF9UYWJsZUFsYXJtJywgeCk7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgfSwgbnVsbCwgdHJ1ZSk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBwcmVwYXJlQWxhcm1PY2N1cmVuY2VUZW1wbGF0ZShpZCwgbm0sIHN0YXJ0LCBpbnRlcnZhbCwgZGVsKSB7DQogICAgICAgICAgICByZXR1cm4gIjxkOkFsYXJtVGVtcGxhdGUgeG1sbnM6ZD1cImh0dHA6Ly9pbnRlbC5jb20vd2JlbS93c2NpbS8xL2FtdC1zY2hlbWEvMS9BTVRfQWxhcm1DbG9ja1NlcnZpY2VcIiB4bWxuczpzPVwiaHR0cDovL2ludGVsLmNvbS93YmVtL3dzY2ltLzEvaXBzLXNjaGVtYS8xL0lQU19BbGFybUNsb2NrT2NjdXJyZW5jZVwiPjxzOkluc3RhbmNlSUQ+IiArIGlkICsgIjwvczpJbnN0YW5jZUlEPjxzOlN0YXJ0VGltZT48cDpEYXRldGltZSB4bWxuczpwPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NvbW1vblwiPiIgKyBzdGFydCArICI8L3A6RGF0ZXRpbWU+PC9zOlN0YXJ0VGltZT48czpJbnRlcnZhbD48cDpJbnRlcnZhbCB4bWxuczpwPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NvbW1vblwiPiIgKyBpbnRlcnZhbCArICI8L3A6SW50ZXJ2YWw+PC9zOkludGVydmFsPjxzOkRlbGV0ZU9uQ29tcGxldGlvbj4iICsgZGVsICsgIjwvczpEZWxldGVPbkNvbXBsZXRpb24+PC9kOkFsYXJtVGVtcGxhdGU+IjsNCiAgICAgICAgfQ0KICAgICAgICANCiAgICAgICAgZnVuY3Rpb24gUmVtb3ZlQWxsQWxhcm1zKCl7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDEsICJSZW1vdmUgYWxsIHdha2UgYWxhcm1zIiwgMywgUmVtb3ZlQWxsQWxhcm1zRXgsICJDb25maXJtIHJlbW92YWwgb2YgYWxsIHdha2UgYWxhcm1zPyIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gUmVtb3ZlQWxsQWxhcm1zRXgoKSB7DQogICAgICAgICAgICB2YXIgZGVsZXRlQ291bnQgPSB4eEFsYXJtcy5sZW5ndGg7DQogICAgICAgICAgICBmb3IgKHZhciBhIGluIHh4QWxhcm1zKSB7IGFtdHN0YWNrLkRlbGV0ZSgiSVBTX0FsYXJtQ2xvY2tPY2N1cnJlbmNlIiwgeHhBbGFybXNbYV0sIGZ1bmN0aW9uKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7IGlmICgtLWRlbGV0ZUNvdW50ID09IDApIHsgUHVsbEFsYXJtcygpOyB9fSk7IH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dBZGRBbGFybShhbHJtKXsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIFFFKCdkMjVhbGFybV9uYW1lJywgIWFscm0pOw0KICAgICAgICAgICAgaWYgKGFscm0gIT0gdW5kZWZpbmVkKSB7DQogICAgICAgICAgICAgICAgdmFyIGFsYXJtID0geHhBbGFybXNbYWxybV0sIHdha2V0aW1lID0gbmV3IERhdGUoYWxhcm1bIlN0YXJ0VGltZSJdWyJEYXRldGltZSJdKTsNCiAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9uYW1lJykudmFsdWUgPSBhbGFybVsiRWxlbWVudE5hbWUiXTsNCiAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9zZGF0ZScpLnZhbHVlID0gd2FrZXRpbWUuZ2V0RnVsbFllYXIoKSArICctJyArIF9mbXR0aW1lcGFkKHdha2V0aW1lLmdldE1vbnRoKCkgKyAxKSArICctJyArIF9mbXR0aW1lcGFkKHdha2V0aW1lLmdldERhdGUoKSk7DQogICAgICAgICAgICAgICAgUSgnZDI1YWxhcm1fc3RpbWUnKS52YWx1ZSA9IHdha2V0aW1lLmdldEhvdXJzKCkgKyAnOicgKyBfZm10dGltZXBhZCh3YWtldGltZS5nZXRNaW51dGVzKCkpICsgJzonICsgX2ZtdHRpbWVwYWQod2FrZXRpbWUuZ2V0U2Vjb25kcygpKTsNCiAgICAgICAgICAgICAgICBpZiAoYWxhcm1bIkludGVydmFsIl0pIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGogPSBhbGFybVsiSW50ZXJ2YWwiXVsiSW50ZXJ2YWwiXS5yZXBsYWNlKCdQJywnJykucmVwbGFjZSgnVCcsJycpLnJlcGxhY2UoJ0QnLCdELCcpLnJlcGxhY2UoJ0gnLCdILCcpLnJlcGxhY2UoJ00nLCdNLCcpLnNwbGl0KCcsJyksIGsgPSBbMCwgMCwgMF07DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gaikgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGpsID0galtpXS5sZW5ndGggLSAxOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGpbaV1bamxdID09ICdEJykgeyBrWzBdID0gcGFyc2VJbnQoaltpXS5zdWJzdHJpbmcoMCwgamwpKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGpbaV1bamxdID09ICdIJykgeyBrWzFdID0gcGFyc2VJbnQoaltpXS5zdWJzdHJpbmcoMCwgamwpKTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGpbaV1bamxdID09ICdNJykgeyBrWzJdID0gcGFyc2VJbnQoaltpXS5zdWJzdHJpbmcoMCwgamwpKTsgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIFEoJ2QyNWFsYXJtX2ludGVydmFsJykudmFsdWUgPSBrLmpvaW4oJy0nKTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9pbnRlcnZhbCcpLnZhbHVlID0gJyc7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIFEoJ2QyNWFsYXJtX2RvYycpLnZhbHVlID0gKGFsYXJtWyJEZWxldGVPbkNvbXBsZXRpb24iXSA9PSB0cnVlKT8xOjA7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHZhciBjdXJyZW50VGltZSA9IG5ldyBEYXRlKCk7DQogICAgICAgICAgICAgICAgY3VycmVudFRpbWUuc2V0RGF0ZShuZXcgRGF0ZSgpLmdldERhdGUoKSArIDEpOw0KICAgICAgICAgICAgICAgIFEoJ2QyNWFsYXJtX25hbWUnKS52YWx1ZSA9ICcnOw0KICAgICAgICAgICAgICAgIFEoJ2QyNWFsYXJtX3NkYXRlJykudmFsdWUgPSBjdXJyZW50VGltZS5nZXRGdWxsWWVhcigpICsgJy0nICsgX2ZtdHRpbWVwYWQoY3VycmVudFRpbWUuZ2V0TW9udGgoKSArIDEpICsgJy0nICsgX2ZtdHRpbWVwYWQoY3VycmVudFRpbWUuZ2V0RGF0ZSgpKTsNCiAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9zdGltZScpLnZhbHVlID0gY3VycmVudFRpbWUuZ2V0SG91cnMoKSArICc6JyArIF9mbXR0aW1lcGFkKGN1cnJlbnRUaW1lLmdldE1pbnV0ZXMoKSkgKyAnOjAwJzsNCiAgICAgICAgICAgICAgICBRKCdkMjVhbGFybV9pbnRlcnZhbCcpLnZhbHVlID0gJyc7DQogICAgICAgICAgICAgICAgUSgnZDI1YWxhcm1fZG9jJykudmFsdWUgPSAwOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgyNSwgIkFkZCBuZXcgYWxhcm0iLCAoYWxybSAhPSB1bmRlZmluZWQpPzc6Mywgc2hvd0FkZEFsYXJtT2ssICcnLCBhbHJtKTsNCiAgICAgICAgICAgIGFsZXJ0RGlhbG9nVXBkYXRlKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBhbGVydERpYWxvZ1VwZGF0ZSgpIHsNCiAgICAgICAgICAgIHZhciBpbCA9IFEoJ2QyNWFsYXJtX2ludGVydmFsJykudmFsdWUuc3BsaXQoJy0nKS5sZW5ndGg7DQogICAgICAgICAgICB2YXIgb2sgPSAoUSgnZDI1YWxhcm1fbmFtZScpLnZhbHVlLmxlbmd0aCA+IDApICYmIChRKCdkMjVhbGFybV9zZGF0ZScpLnZhbHVlLnNwbGl0KCctJykubGVuZ3RoID09IDMpICYmIChRKCdkMjVhbGFybV9zdGltZScpLnZhbHVlLnNwbGl0KCc6JykubGVuZ3RoID09IDMpICYmICgoaWwgPT0gMSkgfHwgKGlsID09IDMpKTsNCiAgICAgICAgICAgIFFFKCdpZHhfZGxnT2tCdXR0b24nLCBvayk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiBzaG93QWRkQWxhcm1PayhidXR0b24sIGFscm0pIHsNCiAgICAgICAgICAgIGlmIChidXR0b24gPT0gMikgeyBzaG93QWxlcnREZXRhaWxzRGVsZXRlKGJ1dHRvbiwgYWxybSk7IHJldHVybjsgfQ0KICAgICAgICAgICAgdmFyIGFsYXJtX25hbWUgPSBRKCdkMjVhbGFybV9uYW1lJykudmFsdWU7DQogICAgICAgICAgICB2YXIgeDEgPSBRKCdkMjVhbGFybV9zZGF0ZScpLnZhbHVlLnNwbGl0KCctJyk7DQogICAgICAgICAgICB2YXIgeDIgPSBRKCdkMjVhbGFybV9zdGltZScpLnZhbHVlLnNwbGl0KCc6Jyk7DQogICAgICAgICAgICB2YXIgdCA9IG5ldyBEYXRlKHgxWzBdLCB4MVsxXSAtIDEsIHgxWzJdLCB4MlswXSwgeDJbMV0sIHgyWzJdLCAwKTsgLy8gTm90IHN1cmUgd2h5LCBidXQgbW9udGggaXMgMCA9IEpBTiwgMTEgPSBERUMNCiAgICAgICAgICAgIHZhciBhbGFybV9zdGFydHRpbWUgPSBfZm10dGltZXBhZCh0LmdldFVUQ0Z1bGxZZWFyKCkpICsgJy0nICsgX2ZtdHRpbWVwYWQodC5nZXRVVENNb250aCgpICsgMSkgKyAnLScgKyBfZm10dGltZXBhZCh0LmdldFVUQ0RhdGUoKSkgKyAnVCcgKyBfZm10dGltZXBhZCh0LmdldFVUQ0hvdXJzKCkpICsgJzonICsgX2ZtdHRpbWVwYWQodC5nZXRVVENNaW51dGVzKCkpICsgJzonICsgX2ZtdHRpbWVwYWQodC5nZXRVVENTZWNvbmRzKCkpICsgJ1onOw0KICAgICAgICAgICAgdmFyIHggPSBRKCdkMjVhbGFybV9pbnRlcnZhbCcpLnZhbHVlLnNwbGl0KCctJyk7DQogICAgICAgICAgICBpZiAoeC5sZW5ndGggIT0gMykgeyB4ID0gWzAsIDAsIDBdOyB9DQogICAgICAgICAgICB2YXIgYWxhcm1faW50ZXJ2YWwgPSAnUCcgKyB4WzBdICsgJ0RUJyArIHhbMV0gKyAnSCcgKyB4WzJdICsgJ00nOw0KICAgICAgICAgICAgdmFyIGFsYXJtX2RvYyA9IChRKCdkMjVhbGFybV9kb2MnKS52YWx1ZSA9PSAxKTsNCiAgICAgICAgICAgIHZhciB0cGwgPSBwcmVwYXJlQWxhcm1PY2N1cmVuY2VUZW1wbGF0ZShhbGFybV9uYW1lLCBhbGFybV9uYW1lLCBhbGFybV9zdGFydHRpbWUsIGFsYXJtX2ludGVydmFsLCBhbGFybV9kb2MpOw0KICAgICAgICAgICAgaWYgKGFscm0gPT0gdW5kZWZpbmVkKSB7DQogICAgICAgICAgICAgICAgd3NzdGFjay5FeGVjTWV0aG9kWG1sKGFtdHN0YWNrLkNvbXBsZXRlTmFtZSgiQU1UX0FsYXJtQ2xvY2tTZXJ2aWNlIiksICJBZGRBbGFybSIsIHRwbCwNCiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKHdzLCByZXN1cmksIHJlc3BvbnNlLCBzdGF0dXMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goJ0FkZCBhbGFybScsICdGYWlsZWQgdG8gYWRkIGFsYXJtLiBTdGF0dXM6ICcgKyBzdGF0dXMgKyAnLjxici8+VmVyaWZ5IHRoZSBhbGFybSBpcyBmb3IgYSBmdXR1cmUgdGltZS4nKTsgcmV0dXJuOyB9DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAocmVzcG9uc2UuQm9keVsnUmV0dXJuVmFsdWUnXSAhPSAwKSB7IG1lc3NhZ2Vib3goJ0FkZCBhbGFybScsICdGYWlsZWQgdG8gYWRkIGFsYXJtLCAnICsgcmVzcG9uc2UuQm9keVsnUmV0dXJuVmFsdWVTdHInXSArICcuPGJyLz5WZXJpZnkgdGhlIGFsYXJtIGlzIGZvciBhIGZ1dHVyZSB0aW1lLicpOyByZXR1cm47IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIFB1bGxBbGFybXMoKTsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIHZhciBhbGFybXggPSBDbG9uZSh4eEFsYXJtc1thbHJtXSk7DQogICAgICAgICAgICAgICAgYWxhcm14WyJTdGFydFRpbWUiXSA9ICI8cDpEYXRldGltZSB4bWxuczpwPVwiaHR0cDovL3NjaGVtYXMuZG10Zi5vcmcvd2JlbS93c2NpbS8xL2NvbW1vblwiPiIgKyBhbGFybV9zdGFydHRpbWUgKyAiPC9wOkRhdGV0aW1lPiI7DQogICAgICAgICAgICAgICAgYWxhcm14WyJJbnRlcnZhbCJdID0gIjxwOkludGVydmFsIHhtbG5zOnA9XCJodHRwOi8vc2NoZW1hcy5kbXRmLm9yZy93YmVtL3dzY2ltLzEvY29tbW9uXCI+IiArIGFsYXJtX2ludGVydmFsICsgIjwvcDpJbnRlcnZhbD4iOw0KICAgICAgICAgICAgICAgIGFsYXJteFsiRGVsZXRlT25Db21wbGV0aW9uIl0gPSBhbGFybV9kb2M7DQogICAgICAgICAgICAgICAgYW10c3RhY2suUHV0KCJJUFNfQWxhcm1DbG9ja09jY3VycmVuY2UiLCBhbGFybXgsIGZ1bmN0aW9uICh3cywgcmVzdXJpLCByZXNwb25zZSwgc3RhdHVzKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChzdGF0dXMgIT0gMjAwKSB7IG1lc3NhZ2Vib3goJ0VkaXQgYWxhcm0nLCAnRmFpbGVkIHRvIGNoYW5nZSBhbGFybS4gU3RhdHVzOiAnICsgc3RhdHVzICsgJy48YnIvPlZlcmlmeSB0aGUgYWxhcm0gZm9yIGF0IGEgZnV0dXJlIHRpbWUuJyk7IHJldHVybjsgfQ0KICAgICAgICAgICAgICAgICAgICBQdWxsQWxhcm1zKCk7DQogICAgICAgICAgICAgICAgfSwgbnVsbCwgbnVsbCwgeyAiSW5zdGFuY2VJRCIgOiBhbGFybXhbIkluc3RhbmNlSUQiXX0pOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gc2hvd0FsZXJ0RGV0YWlscyhpKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgYWxhcm0gPSB4eEFsYXJtc1tpXSwgd2FrZXRpbWUgPSBuZXcgRGF0ZShhbGFybVsiU3RhcnRUaW1lIl1bIkRhdGV0aW1lIl0pOw0KICAgICAgICAgICAgdmFyIHggPSAnPGRpdiBzdHlsZT10ZXh0LWFsaWduOmxlZnQ+JyArIGFkZEh0bWxWYWx1ZSgiTmFtZSIsIGFsYXJtWyJFbGVtZW50TmFtZSJdKSArIGFkZEh0bWxWYWx1ZSgiV2FrZSB0aW1lIiwgd2FrZXRpbWUudG9Mb2NhbGVTdHJpbmcoKS5yZXBsYWNlKCcsICcsICcgYXQgJykpOw0KICAgICAgICAgICAgaWYgKGFsYXJtWyJJbnRlcnZhbCJdICE9IHVuZGVmaW5lZCkgeyB4ICs9IGFkZEh0bWxWYWx1ZSgiSW50ZXJuYWwiLCBfZm10aW50ZXJ2YWwoYWxhcm1bIkludGVydmFsIl1bIkludGVydmFsIl0pKTsgfQ0KICAgICAgICAgICAgeCArPSBhZGRIdG1sVmFsdWUoIkFmdGVyIHdha2UiLCAoYWxhcm1bIkRlbGV0ZU9uQ29tcGxldGlvbiJdID09IHRydWUpPyJEZWxldGUgQWxhcm0iOiJLZWVwIEFsYXJtIikgKyAiPC9kaXY+IjsNCiAgICAgICAgICAgIG1lc3NhZ2Vib3goIkFsYXJtICIgKyBhbGFybVsiRWxlbWVudE5hbWUiXSwgeCk7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiQWxhcm0gIiArIGFsYXJtWyJFbGVtZW50TmFtZSJdLCA1LCBzaG93QWxlcnREZXRhaWxzRGVsZXRlLCB4LCBpKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNob3dBbGVydERldGFpbHNEZWxldGUoYnV0dG9uLCB0YWcpIHsNCiAgICAgICAgICAgIGlmIChidXR0b24gPT0gMikgeyBhbXRzdGFjay5EZWxldGUoIklQU19BbGFybUNsb2NrT2NjdXJyZW5jZSIsIHh4QWxhcm1zW3RhZ10sIGZ1bmN0aW9uKHN0YWNrLCBuYW1lLCByZXNwb25zZSwgc3RhdHVzKSB7IFB1bGxBbGFybXMoKTsgfSk7IH0NCiAgICAgICAgfQ0KDQoNCg0KDQogICAgICAgIC8vDQogICAgICAgIC8vIFNjcmlwdGluZw0KICAgICAgICAvLw0KDQogICAgICAgIC8vIENhbGxlZCBieSB0aGUgIlJ1biBTY3JpcHQuLi4iIGJ1dHRvbi4gRGlzcGxheSBhIGRpYWxvZyBib3ggdG8gYXNrIGZvciB0aGUgc2NyaXB0IGZpbGUuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9ydW5TY3JpcHREbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8IHNjcmlwdHN0YXRlKSByZXR1cm47DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiUnVuIFNjcmlwdCIsIDMsIHNjcmlwdF9ydW5TY3JpcHREbGdPaywgIjxicj48aW5wdXQgaWQ9c2NyaXB0b3BlbiB0eXBlPWZpbGUgc3R5bGU9d2lkdGg6MTAwJSBhY2NlcHQ9Lm1lc2NyaXB0PiIpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gT25jZSB0aGUgc2NyaXB0IGZpbGUgaXMgc2VsZWN0ZWQsIGRlY29kZSB0aGUgc2NyaXB0IGhlcmUuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9ydW5TY3JpcHREbGdPayhyKSB7DQogICAgICAgICAgICBpZiAociAhPSAxKSByZXR1cm47DQogICAgICAgICAgICB2YXIgeCA9IFEoJ3NjcmlwdG9wZW4nKTsNCiAgICAgICAgICAgIGlmICh4LmZpbGVzLmxlbmd0aCAhPSAxKSByZXR1cm47DQogICAgICAgICAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsNCiAgICAgICAgICAgIHJlYWRlci5vbmxvYWQgPSBzY3JpcHRfb25TY3JpcHRSZWFkOw0KICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyh4LmZpbGVzWzBdKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENhbGxlZCBvbmNlIHRoZSBzY3JpcHQgaXMgZGVjb2RlZCwgZ2V0IHRoZSBzY3JpcHQgc2V0dXAgYW5kIHN0YXJ0IHJ1bm5pbmcgaXQuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9vblNjcmlwdFJlYWQoZmlsZSkgew0KICAgICAgICAgICAgdmFyIHg7DQogICAgICAgICAgICB0cnkgeyB4ID0gSlNPTi5wYXJzZShmaWxlLnRhcmdldC5yZXN1bHQpOyB9IGNhdGNoIChlKSB7fQ0KDQogICAgICAgICAgICBpZiAoY3VycmVudFZpZXcgPT0gMjApIHsNCiAgICAgICAgICAgICAgICAvLyBMb2FkIHNjcmlwdCBpbnRvIGVkaXRvcg0KICAgICAgICAgICAgICAgIGlmICh4WydzY3JpcHRUZXh0J10pIFEoJ3NjcmlwdGFyZWEnKS52YWx1ZSA9IHhbJ3NjcmlwdFRleHQnXTsNCiAgICAgICAgICAgICAgICBpZiAoeFsnbWVzY3JpcHQnXSkgUSgnY29tcGlsZWRhcmVhJykudmFsdWUgPSByc3RyMmhleChhdG9iKHhbJ21lc2NyaXB0J10pKTsNCiAgICAgICAgICAgICAgICBpZiAoeFsnYmxvY2tzJ10pIHsgc2NyaXB0X3NldEJ1aWxkQmxvY2tzKHhbJ2Jsb2NrcyddKTsgc2NyaXB0Vmlld0J1dHRvbigxKTsgfSBlbHNlIHsgc2NyaXB0X3NldEJ1aWxkQmxvY2tzKCk7IHNjcmlwdFZpZXdCdXR0b24oMCk7IH0NCiAgICAgICAgICAgICAgICBpZiAoeFsnc2NyaXB0QmxvY2tzJ10pIHsgc2NyaXB0X0Jsb2NrU2NyaXB0ID0geFsnc2NyaXB0QmxvY2tzJ107IH0gZWxzZSB7IGlmICghc2NyaXB0X0J1aWxkaW5nQmxvY2tzKSB7IHNjcmlwdF9CbG9ja1NjcmlwdCA9IFtdOyB9IH0NCg0KICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgc2NyaXB0QmxvY2tzIHRvIHRoZSBsYXRlc3QgYmxvY2tzLiBUaGlzIGlzIGRvZXMgYmVjYXVzZSB3ZSBtYXkgdXBkYXRlIGFuIGV4aXN0aW5nIHNjcmlwdCB0byBuZXcgYmxvY2tzLg0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gc2NyaXB0X0Jsb2NrU2NyaXB0KSB7DQogICAgICAgICAgICAgICAgICAgIHZhciBibG9jayA9IHNjcmlwdF9CbG9ja1NjcmlwdFtpXTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHhibG9jayA9IHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1tibG9ja1sneG5hbWUnXV07DQogICAgICAgICAgICAgICAgICAgIGlmICh4YmxvY2spIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBiID0gQ2xvbmUoeGJsb2NrKTsgLy8gQ2xvbmUgYSBuZXcgYmxvY2ssIHRoZW4gc2V0IGFsbCB0aGUgdmFyaWFibGVzLg0KICAgICAgICAgICAgICAgICAgICAgICAgYlsnaWQnXSA9IGJsb2NrWydpZCddOw0KICAgICAgICAgICAgICAgICAgICAgICAgYlsneG5hbWUnXSA9IGJsb2NrWyd4bmFtZSddOw0KICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiBpbiBiLnZhcnMpIHsgaWYgKGJsb2NrLnZhcnNbal0pIHsgYi52YXJzW2pdWyd2YWx1ZSddID0gYmxvY2sudmFyc1tqXVsndmFsdWUnXTsgfSB9DQogICAgICAgICAgICAgICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRbaV0gPSBiOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgLy8gUmVzZXQgdGhlIHNjcmlwdCBzdGF0ZQ0KICAgICAgICAgICAgICAgIGZ1cGRhdGVzY3JpcHQoKTsNCiAgICAgICAgICAgICAgICBkZWxldGUgc2NyaXB0c3RhdGU7DQogICAgICAgICAgICAgICAgcmVzZXRTY3JpcHRCdXR0b24oKTsNCiAgICAgICAgICAgICAgICByZXR1cm47DQogICAgICAgICAgICB9DQogICAgICAgICAgICB2YXIgc3RhcnR2YXJzID0geyAnX2ludGVyYWN0aXZlJzoxIH07DQoNCiAgICAgICAgICAgIHN0YXJ0dmFyc1snX2NlcnRpZmljYXRlcyddID0gMTsNCg0KICAgICAgICAgICAgc3RhcnR2YXJzWydfbW9kZSddID0gJ0Zpcm13YXJlJzsNCg0KICAgICAgICAgICAgc3RhcnR2YXJzWydfbW9kZSddID0gJ01lc2hDZW50cmFsMic7DQoNCiAgICAgICAgICAgIHN0YXJ0dmFyc1snX21vZGUnXSA9ICdMTVMnOw0KICAgICAgICAgICAgaWYgKHggJiYgeFsnbWVzY3JpcHQnXSkgc2NyaXB0c3RhdGUgPSBzY3JpcHRfc2V0dXAoYXRvYih4WydtZXNjcmlwdCddKSwgc3RhcnR2YXJzKTsNCiAgICAgICAgICAgIGlmIChzY3JpcHRzdGF0ZSkgew0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLndzc3RhY2sgPSB3c3N0YWNrOw0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLmFtdHN0YWNrID0gYW10c3RhY2s7DQogICAgICAgICAgICAgICAgc2NyaXB0c3RhdGUub25TdGVwID0gc2NyaXB0X3VwZGF0ZVNjcmlwdFN0YXRlOw0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLm9uQ29uc29sZSA9IHNjcmlwdF9jb25zb2xlOw0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLnN0YXJ0KDEwMCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIG1lc3NhZ2Vib3goIlJ1biBTY3JpcHQiLCAiSW52YWxpZCBzY3JpcHQgZmlsZS4iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENhbGxlZCB3aGVuIHRoZSBzY3JpcHQgY2hhbmdlcyBzdGF0ZSwgZGlzcGxheXMgdGhlIGdyZWVuIHN0YXR1cyBiYXIgYXQgdGhlIHRvcCBvZiB0aGUgd2ViIHBhZ2UuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF91cGRhdGVTY3JpcHRTdGF0ZSgpIHsNCiAgICAgICAgICAgIGlmIChzY3JpcHRzdGF0ZSkgew0KICAgICAgICAgICAgICAgIFFWKCdpZF9zY3JpcHRzdGF0dXMnLCBzY3JpcHRzdGF0ZS5zdGF0ZSA+IDApOyBjZW50ZXIoKTsNCiAgICAgICAgICAgICAgICBpZiAoc2NyaXB0c3RhdGUuc3RhdGUgPT0gMCkgew0KICAgICAgICAgICAgICAgICAgICBzY3JpcHRzdGF0ZSA9IHVuZGVmaW5lZDsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgYnkgYSBydW5uaW5nIHNjcmlwdCB0byB1cGRhdGUgdGhlIGNvbnNvbGUuIFRoZSBsYXN0IG1lc3NhZ2UgaW4gdGhlIGNvbnNvbGUgaXMgZGlzcGxheWVkIGluIHRoZSB0b3AgZ3JlZW4gYmFyLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfY29uc29sZShtc2cpIHsNCiAgICAgICAgICAgIGlmIChtc2cuaW5kZXhPZigiSU5GTzogIikgPT0gMCkgeyBtc2cgPSBtc2cuc3Vic3RyaW5nKDYpOyB9DQogICAgICAgICAgICBpZiAobXNnLmluZGV4T2YoIlNVQ0NFU1M6ICIpID09IDApIHsgbXNnID0gbXNnLnN1YnN0cmluZyg5KTsgfQ0KICAgICAgICAgICAgaWYgKG1zZy5pbmRleE9mKCJFUlJPUjogIikgPT0gMCkgeyBtc2cgPSBtc2cuc3Vic3RyaW5nKDcpOyB9DQogICAgICAgICAgICBRSCgnaWRfc2NyaXB0c3RhdHVzc3RyJywgJywgJyArIG1zZyk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgYnkgdGhlICJTdG9wIiBidXR0b24gb24gdGhlIHNjcmlwdCBzdGF0dXMgYmFyLiBDYXVzZXMgdGhlIHNjcmlwdCB0byBzdG9wLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfU3RvcCgpIHsNCiAgICAgICAgICAgIGlmIChzY3JpcHRzdGF0ZSkgew0KICAgICAgICAgICAgICAgIGlmIChzY3JpcHRzdGF0ZS5kaWFsb2cgPT0gdHJ1ZSkgeyBzZXREaWFsb2dNb2RlKDApOyB9DQogICAgICAgICAgICAgICAgc2NyaXB0c3RhdGUuc3RvcCgpOw0KICAgICAgICAgICAgICAgIHNjcmlwdHN0YXRlLnN0YXRlID0gMDsNCiAgICAgICAgICAgICAgICBzY3JpcHRfdXBkYXRlU2NyaXB0U3RhdGUoKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQoNCg0KICAgICAgICANCiAgICAgICAgdmFyIHNjcmlwdF9CdWlsZGluZ0Jsb2NrczsgLy8gTGlzdCBvZiBibG9jayB0aGF0IGNhbiBiZSB1c2VkIHRvIGJ1aWxkIGEgc2NyaXB0LiBUaGlzIGlzIHNob3duIG9uIHRoZSBsaXN0IHNpZGUuDQogICAgICAgIHZhciBzY3JpcHRfU3RhcnRpbmdCdWlsZGluZ0Jsb2NrczsgLy8gTGlzdCBvZiBibG9jayB0aGF0IGNhbiBiZSB1c2VkIHRvIGJ1aWxkIGEgc2NyaXB0IHdoZW4geW91IGdldCBzdGFydGVkLg0KICAgICAgICB2YXIgc2NyaXB0X0Jsb2NrU2NyaXB0ID0gW107IC8vIExpc3Qgb2YgYmxvY2tzIHRoYXQgYXJlIHBhcnQgb2YgdGhlIGN1cnJlbnQgc2NyaXB0Lg0KICAgICAgICB2YXIgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IG51bGw7IC8vIFRoZSBpZGVudGlmaWVyIG9mIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgYmxvY2suDQogICAgICAgIHZhciBzY3JpcHRfQnVpbGRlclZpZXcgPSAwOyAvLyAwID0gRWRpdG9yIFZpZXcsIDEgPSBCdWlsZGVyIFZpZXcNCiAgICAgICAgdmFyIGVkaXRzY3JpcHRzdGF0ZTsgLy8gVGhpcyBpcyB0aGUgaW5zdGFuY2Ugb2YgdGhlIHNjcmlwdCBydW5uZXIgdXNlZCBieSB0aGUgZWRpdG9yLiBUaGlzIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBydW5uZXIgdXNlZCBieSB0aGUgd2ViIHBhZ2UuDQoNCg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRMb2FkU3RhcnRpbmdCbG9ja3MoKSB7DQoNCiAgICAgICAgICAgIHZhciByZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7DQogICAgICAgICAgICByZXF1ZXN0Lm9ubG9hZCA9IGZ1bmN0aW9uKCkgew0KICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0LnN0YXR1cyA+PSAyMDAgJiYgcmVxdWVzdC5zdGF0dXMgPCA0MDApIHsNCiAgICAgICAgICAgICAgICAgICAgLy8gU3VjY2Vzcw0KICAgICAgICAgICAgICAgICAgICB2YXIgeDsNCiAgICAgICAgICAgICAgICAgICAgdHJ5IHsgeCA9IEpTT04ucGFyc2UocmVxdWVzdC5yZXNwb25zZVRleHQpOyB9IGNhdGNoIChlKSB7fQ0KICAgICAgICAgICAgICAgICAgICBpZiAoKHgpICYmICh4WydibG9ja3MnXSkpIHsgc2NyaXB0X1N0YXJ0aW5nQnVpbGRpbmdCbG9ja3MgPSB4WydibG9ja3MnXTsgc2NyaXB0X3NldEJ1aWxkQmxvY2tzKHNjcmlwdF9TdGFydGluZ0J1aWxkaW5nQmxvY2tzKTsgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH07DQogICAgICAgICAgICByZXF1ZXN0Lm9uZXJyb3IgPSBmdW5jdGlvbigpIHsgY29uc29sZS5sb2coJ0ZhaWxlZCB0byBnZXQgc2NyaXB0IGJsb2NrcycpOyB9Ow0KICAgICAgICAgICAgcmVxdWVzdC5vcGVuKCdHRVQnLCAnc2NyaXB0YmxvY2tzLnR4dCcsIHRydWUpOw0KICAgICAgICAgICAgcmVxdWVzdC5zZW5kKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgYnkgdGhlICJWaWV3IEVkaXRvciIgb3IgIlZpZXcgQnVpbGRlciIgYnV0dG9uIHRvIHRvZ2dsZSBiZXR3ZWVuIHRoZSB2aWV3IG1vZGVzLg0KICAgICAgICAvLyBJZiB0aGVyZSBpcyBubyBjb25zdHJ1Y3Rpb24gYmxvY2tzLCBkaXNwbGF5IHRoZSBzY3JpcHQgZWRpdG9yIG9ubHkuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdFZpZXdCdXR0b24oeCkgew0KICAgICAgICAgICAgc2NyaXB0X0J1aWxkZXJWaWV3ID0geDsNCiAgICAgICAgICAgIFFWKCdzY3JpcHRlZGl0b3InLCB4ID09IDApOw0KICAgICAgICAgICAgUVYoJ3NjcmlwdGJ1aWxkZXInLCB4ID09IDEpOw0KICAgICAgICAgICAgUVYoJ3ZpZXdFZGl0b3JCdXR0b24nLCBzY3JpcHRfQnVpbGRpbmdCbG9ja3MgJiYgKHggPT0gMSkpOw0KICAgICAgICAgICAgUVYoJ3ZpZXdCdWlsZGVyQnV0dG9uJywgc2NyaXB0X0J1aWxkaW5nQmxvY2tzICYmICh4ID09IDApKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIERpc3BsYXkgdGhlIGxpc3Qgb2YgY29uc3RydWN0aW9uIHNjcmlwdCBibG9jayBvbiB0aGUgbGVmdCBzaWRlLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfc2V0QnVpbGRCbG9ja3MoYmxvY2tzKSB7DQogICAgICAgICAgICBzY3JpcHRfQnVpbGRpbmdCbG9ja3MgPSBibG9ja3M7DQogICAgICAgICAgICB2YXIgeCA9ICcnOw0KICAgICAgICAgICAgaWYgKGJsb2Nrcykgew0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gYmxvY2tzKSB7DQogICAgICAgICAgICAgICAgICAgIGlmIChpLmNoYXJDb2RlQXQoMCkgIT0gOTUpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gJzxkaXYgaWQ9c2Jsb2NrXycgKyBpICsgJyBzdHlsZT1jdXJzb3I6cG9pbnRlcjtiYWNrZ3JvdW5kLWNvbG9yOiNjY2M7d2lkdGg6YXV0bztwYWRkaW5nOjVweDttYXJnaW46MnB4IG9uZGJsY2xpY2s9c2NyaXB0X2ZhZGRibG9jaygiJyArIGkgKyAnIikgZHJhZ2dhYmxlPXRydWUgb25kcmFnc3RhcnQ9c2NyaXB0X2ZvbmRyYWdzdGFydChldmVudCx0aGlzKSBvbmRyYWdlbmQ9c2NyaXB0X2ZvbmRyYWdlbmQoZXZlbnQsdGhpcykgdGl0bGU9IicgKyBibG9ja3NbaV1bJ2Rlc2MnXSArICciJzsNCiAgICAgICAgICAgICAgICAgICAgICAgIHggKz0gJz4nICsgYmxvY2tzW2ldWyduYW1lJ10gKyAnPC9kaXY+JzsNCiAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIFFIKCdibG9ja3MnLCB4KTsNCiAgICAgICAgICAgIHNjcmlwdF9mb25maWx0ZXJjaGFuZ2VkKCk7DQogICAgICAgICAgICBzY3JpcHRWaWV3QnV0dG9uKHNjcmlwdF9CdWlsZGluZ0Jsb2Nrcz8xOjApOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQWRkIGEgbmV3IGJsb2NrIHRvIHRoZSBlbmQgb2YgdGhlIGJsb2NrIHNjcmlwdC4gVGhpcyBpcyBjYWxsZWQgd2hlbiB5b3UgcmlnaHQgY2xpY2sgb24gYSBibG9jayBhbmQgaGl0ICJBZGQiIGluIHRoZSBjb250ZXh0IG1lbnUuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mYWRkYmxvY2soaCkgew0KICAgICAgICAgICAgdmFyIGIgPSBDbG9uZShzY3JpcHRfQnVpbGRpbmdCbG9ja3NbaF0pOyAvLyBUbyBhZGQgYSBuZXcgYmxvY2sgdG8gdGhlIHNjcmlwdCwgY2xvbmUgdGhlIGJsb2NrLCBhc3NpZ24gaXQgYSByYW5kb20gaWQgYW5kIHNldCB0aGUgeG5hbWUgdG8gdGhlIG5hbWUgb2YgdGhlIGJsb2NrLg0KICAgICAgICAgICAgYlsnaWQnXSA9IE1hdGgucmFuZG9tKCk7DQogICAgICAgICAgICBiWyd4bmFtZSddID0gaDsNCiAgICAgICAgICAgIHNjcmlwdF9CbG9ja1NjcmlwdC5wdXNoKGIpOyAvLyBOb3cgdGhhdCBhIGJsb2NrIGlzIGNyZWF0ZWQsIGFkZCBpdCBhdCB0aGUgZW5kIG9mIHRoZSBzY3JpcHQgYW5kIHNldCBpdCBhcyB0aGUgc2VsZWN0ZWQgYmxvY2suDQogICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID0gc2NyaXB0X0Jsb2NrU2NyaXB0Lmxlbmd0aCAtIDE7DQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7IC8vIFJlLWRpc3BsYXkgdGhlIGxpc3Qgb2Ygc2NyaXB0IGJsb2Nrcy4gVGhlIHNlbGVjdGVkIGJsb2NrIHdpbGwgYWxzbyBiZSBoaWdobGlnaHRlZC4NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIEVkaXQgYSBzY3JpcHQgYmxvY2sNCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZlZGl0YmxvY2soaCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgJ0VkaXQgJyArIHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1toXVsnbmFtZSddLCAzLCBzY3JpcHRfZmVkaXRibG9ja0V4LCAnRWRpdCB0aGlzIGJsb2NrPyBUaGlzIG9wZXJhdGlvbiB3aWxsIHJlc2V0IHRoZSBibG9jayBlZGl0b3IgYW5kIGxvYWQgdGhlIGJsb2NrIGNvZGUgaW50byB0aGUgY29kZSBlZGl0b3IuJywgaCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgd2hlbiB0aGUgc2NyaXB0IGJsb2NrIGVkaXQgZGlhbG9nIGlzIGNsb3NlZC4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZlZGl0YmxvY2tFeChidXR0b24sIGgpIHsNCiAgICAgICAgICAgIHNjcmlwdF9uZXdTY3JpcHREbGdPaygpOw0KICAgICAgICAgICAgc2NyaXB0Vmlld0J1dHRvbigwKTsNCiAgICAgICAgICAgIHZhciB4ID0gJycsIGIgPSBzY3JpcHRfQnVpbGRpbmdCbG9ja3NbaF07DQogICAgICAgICAgICB4ICs9ICcjIyFCTE9DSyEjI1xyXG4jaWQ9JyArIGggKyAnXHJcbiNuYW1lPScgKyBiWyduYW1lJ10gKyAnXHJcbiNkZXNjPScgKyBiWydkZXNjJ10gKyAnXHJcbiMjIUJMT0NLISMjXHJcbic7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIGJbJ3ZhcnMnXSkgew0KICAgICAgICAgICAgICAgIHZhciB2ID0gYlsndmFycyddW2ldOw0KICAgICAgICAgICAgICAgIHggKz0gJyMjIVZBUiEjI1xyXG4jaWQ9JyArIGkgKyAnXHJcbiNuYW1lPScgKyB2WyduYW1lJ10gKyAnXHJcbiNkZXNjPScgKyB2WydkZXNjJ10gKyAnXHJcbiN0eXBlPScgKyB2Wyd0eXBlJ10gKyAnXHJcbic7DQogICAgICAgICAgICAgICAgaWYgKHZbJ21heGxlbmd0aCddKSB7IHggKz0gJyNtYXhsZW5ndGg9JyArIHZbJ21heGxlbmd0aCddICsgJ1xyXG4nOyB9DQogICAgICAgICAgICAgICAgaWYgKHZbJ3ZhbHVlcyddKSB7IGZvciAodmFyIGogaW4gdlsndmFsdWVzJ10pIHsgeCArPSAnI3ZhbHVlcy0nICsgaiArJz0nICsgdlsndmFsdWVzJ11bal0gKyAnXHJcbic7IH0gfQ0KICAgICAgICAgICAgICAgIHggKz0gJyN2YWx1ZT0nICsgdlsndmFsdWUnXSArICdcclxuIyNTV0FQICUlJScgKyBpICsgJyUlJSAnICsgdlsndmFsdWUnXSArICdcclxuJzsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHggKz0gJyMjIVZBUiEjI1xyXG4jI1NXQVAgJSUlfiUlJSAwXHJcblxyXG4jIyFCTE9DSyEjI1xyXG4nICsgYlsnY29kZSddICsgJ1xyXG4jIyFCTE9DSyEjI1xyXG4nOw0KICAgICAgICAgICAgUSgnc2NyaXB0YXJlYScpLnZhbHVlID0geDsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mQ29udmVydFNjcmlwdFRvSnNvbkJsb2NrKHNjcmlwdCkgew0KICAgICAgICAgICAgdmFyIHJlc3VsdCA9IHt9LCBzY3JpcHRwYXJ0cyA9IHNjcmlwdC5zcGxpdCgnIyMhQkxPQ0shIyNcbicpLCBzY3JpcHRsaW5lcyA9IHNjcmlwdHBhcnRzWzFdLnNwbGl0KCdcbicpOw0KDQogICAgICAgICAgICAvLyBQYXJzZSBpbmZvcm1hdGlvbiBwYXJ0DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHNjcmlwdGxpbmVzKSB7DQogICAgICAgICAgICAgICAgdmFyIHMgPSBzY3JpcHRsaW5lc1tpXS5zcGxpdCgnPScpOw0KICAgICAgICAgICAgICAgIGlmIChzLmxlbmd0aCA9PSAyKSB7IHJlc3VsdFtzWzBdLnN1YnN0cmluZygxKV0gPSBzWzFdOyB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIFBhcnNlIHZhcmlhYmxlcyBwYXJ0DQogICAgICAgICAgICByZXN1bHRbJ3ZhcnMnXSA9IHt9Ow0KICAgICAgICAgICAgc2NyaXB0dmFyaWFibGVzID0gc2NyaXB0cGFydHNbMl0uc3BsaXQoJyMjIVZBUiEjI1xuJyk7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHNjcmlwdHZhcmlhYmxlcykgew0KICAgICAgICAgICAgICAgIHNjcmlwdGxpbmVzID0gc2NyaXB0dmFyaWFibGVzW2ldLnNwbGl0KCdcbicpOw0KICAgICAgICAgICAgICAgIHZhciB2ID0ge30sIHZhbHVlcyA9IHt9LCB2YWx1ZXNsZW4gPSAwOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gc2NyaXB0bGluZXMpIHsNCiAgICAgICAgICAgICAgICAgICAgdmFyIHMgPSBzY3JpcHRsaW5lc1tqXS5zcGxpdCgnPScpOw0KICAgICAgICAgICAgICAgICAgICBpZiAoKHMubGVuZ3RoID09IDIpICYmIChzWzFdKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChzWzBdKSAmJiAoc1swXS5sZW5ndGggPiAwKSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzWzBdLnN1YnN0cmluZygwLCA4KSA9PSAnI3ZhbHVlcy0nKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlc1tzWzBdLnN1YnN0cmluZyg4KV0gPSBzWzFdOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXNsZW4rKzsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2W3NbMF0uc3Vic3RyaW5nKDEpXSA9IHNbMV07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmICh2LmlkKSB7DQogICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZXNsZW4gPiAwKSB7IHZbJ3ZhbHVlcyddID0gdmFsdWVzOyB9DQogICAgICAgICAgICAgICAgICAgIHZhciBpZCA9IHYuaWQ7DQogICAgICAgICAgICAgICAgICAgIGRlbGV0ZSB2LmlkOw0KICAgICAgICAgICAgICAgICAgICByZXN1bHRbJ3ZhcnMnXVtpZF0gPSB2Ow0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gUGFyc2UgY29kZSBwYXJ0DQogICAgICAgICAgICByZXN1bHRbJ2NvZGUnXSA9IHNjcmlwdHBhcnRzWzNdOw0KDQogICAgICAgICAgICAvLyBQYWNrYWdlIHRoZSByZXN1bHQNCiAgICAgICAgICAgIHZhciBpZCA9IHJlc3VsdC5pZDsNCiAgICAgICAgICAgIGRlbGV0ZSByZXN1bHQuaWQ7DQogICAgICAgICAgICB2YXIgciA9IHt9Ow0KICAgICAgICAgICAgcltpZF0gPSByZXN1bHQ7DQogICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkociwgbnVsbCwgJyAgJyk7DQogICAgICAgIH0NCg0KICAgICAgICAvKg0KICAgICAgICAvLyBJZiB0aGUgZGVsZXRlIGtleSBpcyBwcmVzc2VkLCBkZWxldGUgdGhlIGJsb2NrDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25rZXlwcmVzcyhlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBpZiAoZS5rZXkgPT0gJ0RlbGV0ZScgJiYgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCAhPSBudWxsKSB7DQogICAgICAgICAgICAgICAgLy9kZWxldGUgc2NyaXB0X0Jsb2NrU2NyaXB0W3NjcmlwdF9CbG9ja1NjcmlwdFNlbGVjdGVkSWRdOw0KICAgICAgICAgICAgICAgIHNjcmlwdF9CbG9ja1NjcmlwdC5zcGxpY2Uoc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCwgMSk7DQogICAgICAgICAgICAgICAgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IG51bGw7DQogICAgICAgICAgICAgICAgZnVwZGF0ZXNjcmlwdCgpOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQogICAgICAgICovDQoNCiAgICAgICAgLy8gRmlsZXIgdGhlIGxpc3Qgb2YgYmxvY2tzIG9uIHRoZSBsZWZ0IHNpZGUgbGlzdC4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmZpbHRlcmNoYW5nZWQoKSB7DQogICAgICAgICAgICB2YXIgZmlsdGVyID0gUSgnYmxvY2tmaWx0ZXInKS52YWx1ZS50b0xvd2VyQ2FzZSgpOw0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBzY3JpcHRfQnVpbGRpbmdCbG9ja3MpIHsNCiAgICAgICAgICAgICAgICAvLyBTY3JpcHQgYmxvY2tzIHRoYXQgc3RhcnQgd2l0aCAiXyIgYXJlIGhpZGRlbiBibG9ja3MgYW5kIHNob3VsZCBuZXZlciBiZSBzaG93bi4NCiAgICAgICAgICAgICAgICBpZiAoaS5jaGFyQ29kZUF0KDApICE9IDk1KSB7IFFWKCdzYmxvY2tfJyArIGksIChzY3JpcHRfQnVpbGRpbmdCbG9ja3NbaV1bJ25hbWUnXS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoZmlsdGVyKSA+PSAwIHx8IHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1tpXVsnZGVzYyddLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihmaWx0ZXIpID49IDApKTsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ2FsbGVkIHdoZW4geW91IGNsaWNrIG9uIGEgYmxvY2suIElmIHlvdSBkb3VibGUgY2xpY2ssIG9uIGEgYmxvY2ssIGRvIGxpa2UgcHJlc3Npbmcgb24gdGhlICJFZGl0Li4uIiBidXR0b24uDQogICAgICAgIHZhciBzY3JpcHRfZm9uY2xpY2tEYmxDbGlja0RldGVjdEluZGV4ID0gbnVsbDsNCiAgICAgICAgdmFyIHNjcmlwdF9mb25jbGlja0RibENsaWNrRGV0ZWN0VGltZSA9IG51bGw7DQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25jbGljayhlLCB0KSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID0gbnVsbDsNCiAgICAgICAgICAgIGlmICh0KSB7IHQgPSBmZ2V0UGFyZW50V2l0aElkKHQpOyBpZiAodC5pZC5zdGFydHNXaXRoKCd4YmxvY2tfJykpIHsgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IHQuaWQuc3Vic3RyaW5nKDcpOyB9IH0gLy8gRmlndXJlIG91dCB3aGF0IGJsb2NrIHdhcyBjbGlja2VkIG9uDQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7IC8vIFRoaXMgd2lsbCBzaG93IHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgYmxvY2sgaW4gYSBkaWZmZXJlbnQgY29sb3IuDQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQoNCiAgICAgICAgICAgIC8vIEZpZ3VyZSBvdXQgaWYgdGhpcyBpcyBhIGRvdWJsZSBjbGljay4gV2UgbmVlZCB0d28gY2xpY2tzIG9uIHRoZSBzYW1lIG9iamVjdCB3aXRoaW4gMjUwbXMuDQogICAgICAgICAgICBpZiAoc2NyaXB0X2ZvbmNsaWNrRGJsQ2xpY2tEZXRlY3RJbmRleCA9PSBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkICYmIChuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHNjcmlwdF9mb25jbGlja0RibENsaWNrRGV0ZWN0VGltZSkgPCAyNTApIHsgcmV0dXJuIHNjcmlwdF9mb25lZGl0Y2xpY2soc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCk7IH0NCiAgICAgICAgICAgIHNjcmlwdF9mb25jbGlja0RibENsaWNrRGV0ZWN0SW5kZXggPSBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkOw0KICAgICAgICAgICAgc2NyaXB0X2ZvbmNsaWNrRGJsQ2xpY2tEZXRlY3RUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBTY3JpcHQgYmxvY2sgZHJhZyAmIGRyb3AgZnVuY3Rpb25zLCBhbGxvdyB0aGUgdXNlciB0byBjcmVhdGUgYW5kIG1vdmUgc2NyaXB0IGJsb2Nrcy4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmRyYWdzdGFydChlLCB0KSB7IGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsgdCA9IGZnZXRQYXJlbnRXaXRoSWQodCk7IHQuc3R5bGUub3BhY2l0eSA9ICcwLjQnOyBlLmRhdGFUcmFuc2Zlci5lZmZlY3RBbGxvd2VkID0gJ21vdmUnOyBlLmRhdGFUcmFuc2Zlci5zZXREYXRhKCdzY3JpcHRidWlsZGVyL2Jsb2NrJywgdC5pZCk7IH0NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmRyYWdlbmQoZSwgdCkgICB7IGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsgdCA9IGZnZXRQYXJlbnRXaXRoSWQodCk7IHQuc3R5bGUub3BhY2l0eSA9ICcxLjAnOyB9DQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25kcmFnZW50ZXIoZSwgdCkgeyBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47IGZnZXRQYXJlbnRXaXRoSWQodCkuc3R5bGVbJ2JvcmRlci10b3AnXSA9ICdzb2xpZCAycHggYmxhY2snOyB9DQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25kcmFnbGVhdmUoZSwgdCkgeyBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47IGUgPSBlLm9yaWdpbmFsRXZlbnQgfHwgZTsgdmFyIGN1cnJlbnRFbGVtZW50ID0gZG9jdW1lbnQuZWxlbWVudEZyb21Qb2ludChlLnBhZ2VYLCBlLnBhZ2VZKTsgaWYgKCF0LmNvbnRhaW5zKGN1cnJlbnRFbGVtZW50KSkgeyBmZ2V0UGFyZW50V2l0aElkKHQpLnN0eWxlWydib3JkZXItdG9wJ10gPSAnbm9uZSc7IH0gfQ0KDQogICAgICAgIC8vIENhbGxlZCB3aGVuIHlvdSBkcm9wIGEgYmxvY2sgb24gdGhlIGJsb2NrIHNjcmlwdCBhcmVhLiBUaGlzIGNvZGUgd2lsbCBhZGQgb3IgbW92ZSBhIGJsb2NrIGludG8gaXQncyBuZXcgcGxhY2UuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9mb25kcm9wKGUsIHQpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHQgPSBmZ2V0UGFyZW50V2l0aElkKHQpOw0KICAgICAgICAgICAgdmFyIGIsIHggPSBlLmRhdGFUcmFuc2Zlci5nZXREYXRhKCdzY3JpcHRidWlsZGVyL2Jsb2NrJyksIGRwID0gcGFyc2VJbnQodC5pZC5zdWJzdHJpbmcoNykpOw0KICAgICAgICAgICAgaWYgKHggPT0gJycpIHsgZG9jdW1lbnRGaWxlU2VsZWN0SGFuZGxlcihlKTsgcmV0dXJuOyB9DQogICAgICAgICAgICBpZiAoeC5zdGFydHNXaXRoKCJzYmxvY2tfIikpIHsNCiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgYSBuZXcgc2NyaXB0IGJsb2NrDQogICAgICAgICAgICAgICAgYiA9IENsb25lKHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1t4LnN1YnN0cmluZyg3KV0pOw0KICAgICAgICAgICAgICAgIGJbJ2lkJ10gPSBNYXRoLnJhbmRvbSgpOw0KICAgICAgICAgICAgICAgIGJbJ3huYW1lJ10gPSB4LnN1YnN0cmluZyg3KTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gUHVsbCBhbiBleGlzdGluZyBzY3JpcHQgYmxvY2sgZnJvbSB0aGUgbGlzdA0KICAgICAgICAgICAgICAgIHZhciBpID0gcGFyc2VJbnQoeC5zdWJzdHJpbmcoNykpOw0KICAgICAgICAgICAgICAgIGIgPSBzY3JpcHRfQmxvY2tTY3JpcHRbaV07DQogICAgICAgICAgICAgICAgc2NyaXB0X0Jsb2NrU2NyaXB0LnNwbGljZShpLCAxKTsNCiAgICAgICAgICAgICAgICBpZiAoZHAgPiBpKSBkcC0tOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaWYgKHQuaWQgPT0gJ3NjcmlwdGJsb2NrcycpIHsNCiAgICAgICAgICAgICAgICAvLyBQdXQgdGhlIGJsb2NrIGF0IHRoZSBlbmQgb2YgdGhlIGxpc3QNCiAgICAgICAgICAgICAgICBpZiAoYikgc2NyaXB0X0Jsb2NrU2NyaXB0LnB1c2goYik7DQogICAgICAgICAgICAgICAgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IHNjcmlwdF9CbG9ja1NjcmlwdC5sZW5ndGggLSAxOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICAvLyBJbnNlcnQgdGhlIGJsb2NrIHdpdGhpbiB0aGUgbGlzdCwgYWJvdmUgdGhlIGRyb3AgcG9pbnQNCiAgICAgICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHQuc3BsaWNlKGRwLCAwLCBiKTsNCiAgICAgICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID0gZHA7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgd2hlbiB5b3UgaGl0ICJFZGl0Li4uIiBvbiBhIGJsb2NrLCBkaXNwbGF5cyBhIGRpYWxvZyBib3ggd2l0aCBhbGwgYmxvY2sgYXR0cmlidXRlcy4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmVkaXRjbGljayhoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICB2YXIgYmxvY2sgPSBzY3JpcHRfQmxvY2tTY3JpcHRbaF07DQogICAgICAgICAgICBzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID0gaDsNCiAgICAgICAgICAgIGZ1cGRhdGVzY3JpcHQoKTsNCg0KICAgICAgICAgICAgaWYgKGJsb2NrICE9IG51bGwpIHsNCiAgICAgICAgICAgICAgICB2YXIgYiA9IGJsb2NrWyd2YXJzJ10gPyA3IDogNTsNCiAgICAgICAgICAgICAgICB2YXIgYyA9IGJsb2NrWydkZXNjJ10gKyAiPGJyPjxicj4iOw0KICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddKSB7DQogICAgICAgICAgICAgICAgICAgIC8vIEZvciBlYWNoIHZhcmlhYmxlIGluIGEgYmxvY2ssIGFkZCB0aGUgcHJvcGVyIGlucHV0IGNvbnRyb2wgZm9yIHRoaXMgdmFyaWFibGUgYW5kIHNldCB0aGUgY29udHJvbCB0byB0aGUgY3VycmVudCB2YWx1ZS4NCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBibG9ja1sndmFycyddKSB7DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgZCA9IGJsb2NrWyd2YXJzJ11baV1bJ3ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICB2YXIgYXR0cmlidXRlcyA9ICcnOw0KICAgICAgICAgICAgICAgICAgICAgICAgLy8gQmxvY2sgdmFsdWVzIGNhbiBiZSBvbiB0eXBlIDE6VGV4dCwyOk51bWJlciwzOkRyb3BEb3duTGlzdCw0OnBhc3N3b3JkLDU6TXVsdGlTZWxlY3QNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWydtYXhsZW5ndGgnXSkgYXR0cmlidXRlcyArPSAoIiBtYXhsZW5ndGg9IiArIGJsb2NrWyd2YXJzJ11baV1bJ21heGxlbmd0aCddKTsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gMikgeyBhdHRyaWJ1dGVzICs9ICIgb25rZXlwcmVzcz0ncmV0dXJuIG51bWJlcnNPbmx5KGV2ZW50KSciIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gMSB8fCBibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gMikgeyBkID0gIjxpbnB1dCB0aXRsZT0nIiArIGJsb2NrWyd2YXJzJ11baV1bJ2Rlc2MnXSArICInIGlkPXNjcmlwdFh2YWx1ZV8iICsgaSArICIgdmFsdWU9JyIgKyBibG9ja1sndmFycyddW2ldWyd2YWx1ZSddICsgIicgIiArIGF0dHJpYnV0ZXMgKyAiIHN0eWxlPXdpZHRoOjEwMCU+PC9pbnB1dD4iOyB9DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbJ3ZhcnMnXVtpXVsndHlwZSddID09IDMpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkID0gIjxzZWxlY3QgdGl0bGU9JyIgKyBibG9ja1sndmFycyddW2ldWydkZXNjJ10gKyAiJyBpZD1zY3JpcHRYdmFsdWVfIiArIGkgKyAiIHN0eWxlPXdpZHRoOjEwMCU7cGFkZGluZzowO21hcmdpbjowPiI7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaiBpbiBibG9ja1sndmFycyddW2ldWyd2YWx1ZXMnXSkgeyBkICs9ICI8b3B0aW9uIHZhbHVlPSIgKyBqICsgKGogPT0gYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWUnXSA/ICIgc2VsZWN0ZWQiIDogIiIpICsgIj4iICsgYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWVzJ11bal0gKyAiPC9vcHRpb24+IjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQgKz0gIjwvc2VsZWN0PiI7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbJ3ZhcnMnXVtpXVsndHlwZSddID09IDQpIHsgZCA9ICI8aW5wdXQgdHlwZT1wYXNzd29yZCBhdXRvY29tcGxldGU9b2ZmIHRpdGxlPSciICsgYmxvY2tbJ3ZhcnMnXVtpXVsnZGVzYyddICsgIicgaWQ9c2NyaXB0WHZhbHVlXyIgKyBpICsgIiB2YWx1ZT0nIiArIGJsb2NrWyd2YXJzJ11baV1bJ3ZhbHVlJ10gKyAiJyAiICsgYXR0cmlidXRlcyArICIgc3R5bGU9d2lkdGg6MTAwJT48L2lucHV0PiI7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gNSkgeyBkID0gJyc7IH0NCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gNikgeyBkID0gIjxpbnB1dCB0eXBlPWZpbGUgdGl0bGU9JyIgKyBibG9ja1sndmFycyddW2ldWydkZXNjJ10gKyAiJyBpZD1zY3JpcHRYdmFsdWVfIiArIGkgKyAiICIgKyBhdHRyaWJ1dGVzICsgIiBzdHlsZT13aWR0aDoxMDAlPjwvaW5wdXQ+IjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgYyArPSAnPHRhYmxlIHN0eWxlPXdpZHRoOjEwMCUgdGl0bGU9IicgKyBibG9ja1sndmFycyddW2ldWydkZXNjJ10gKyAnIj48dGQgc3R5bGU9d2lkdGg6MTIwcHg+JyArIGJsb2NrWyd2YXJzJ11baV1bJ25hbWUnXSArICc8dGQ+PGI+JyArIGQgKyAnPC9iPjwvdGFibGU+JzsNCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gNSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4ID0gJyc7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYyArPSAnPHVsIGlkPXNjcmlwdFh2YWx1ZV8nICsgaSArICcgc3R5bGU9Imxpc3Qtc3R5bGUtdHlwZTpub25lO2hlaWdodDoxMDBweDtvdmVyZmxvdzphdXRvO3dpZHRoOjEwMCU7Ym9yZGVyOjFweCBzb2xpZCAjMDAwO2JhY2tncm91bmQtY29sb3I6d2hpdGU7b3ZlcmZsb3cteDpoaWRkZW47bWFyZ2luOjA7cGFkZGluZzowIj4nOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIHkgaW4gYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWVzJ10pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHhjID0gJyc7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChibG9ja1sndmFycyddW2ldWyd2YWx1ZSddLmluZGV4T2YoeSkgPj0gMCkgeGMgPSAnIGNoZWNrZWQnOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjICs9ICc8bGk+PGxhYmVsPjxpbnB1dCB0eXBlPWNoZWNrYm94IGlkPXNjcmlwdFh2YWx1ZXhfJyArIGkgKyAnLScgKyB5ICsgJycgKyB4YyArICc+JyArIGJsb2NrWyd2YXJzJ11baV1bJ3ZhbHVlcyddW3ldICsgJzwvbGFiZWw+PC9saT4nOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjICs9ICc8L3VsPic7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIC8vIFBhcmFtZXRlcnM6IERpYWxvZyBNb2RlICgwID0gbm9uZSksIERpYWxvZyBUaXRsZSwgQnV0dG9ucyAoMSA9IE9LLCAyID0gQ2FuY2VsLCAzID0gT0sgJiBDYW5jZWwpLCBDYWxsIGJhY2sgZnVuY3Rpb24oMCA9IENhbmNlbCwgMSA9IE9LKSwgRGlhbG9nIENvbnRlbnQgKE1vZGUgMTEgb25seSkNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTEsIGJsb2NrLm5hbWUsIGIsIHNjcmlwdF9mb25lZGl0Y2xpY2tFeCwgYywgaCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDYWxsZWQgd2hlbiB0aGUgc2NyaXB0IGJsb2NrIGVkaXQgZGlhbG9nIGlzIGNsb3NlZC4NCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2ZvbmVkaXRjbGlja0V4KGJ1dHRvbiwgdGFnKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBpZiAoYnV0dG9uID09IDIpIHsNCiAgICAgICAgICAgICAgICAvLyBEZWxldGUgdGhpcyBibG9jaw0KICAgICAgICAgICAgICAgIHNjcmlwdF9CbG9ja1NjcmlwdC5zcGxpY2UodGFnLCAxKTsNCiAgICAgICAgICAgICAgICBpZiAoc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9PSB0YWcpIHsgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IG51bGw7IH0NCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gQ2hhbmdlIHRoaXMgYmxvY2sgd2l0aCBuZXcgYXJndW1lbnRzDQogICAgICAgICAgICAgICAgdmFyIGJsb2NrID0gc2NyaXB0X0Jsb2NrU2NyaXB0W3RhZ107DQogICAgICAgICAgICAgICAgaWYgKGJsb2NrWyd2YXJzJ10pIHsNCiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBibG9ja1sndmFycyddKSB7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYmxvY2tbJ3ZhcnMnXVtpXVsndHlwZSddID09IDUpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBibG9ja1sndmFycyddW2ldWyd2YWx1ZSddID0gW107DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgeSBpbiBibG9ja1sndmFycyddW2ldWyd2YWx1ZXMnXSkgeyBpZiAoUSgnc2NyaXB0WHZhbHVleF8nICsgaSArICctJyArIHkpLmNoZWNrZWQpIGJsb2NrWyd2YXJzJ11baV1bJ3ZhbHVlJ10ucHVzaCh5KTsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChibG9ja1sndmFycyddW2ldWyd0eXBlJ10gPT0gNikgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciB4ID0gUSgnc2NyaXB0WHZhbHVlXycgKyBpKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoeC5maWxlcy5sZW5ndGggPT0gMSkgew0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLm9ubG9hZCA9IGZ1bmN0aW9uKGZpbGUpIHsgYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWUnXSA9IGJ0b2EoZmlsZS50YXJnZXQucmVzdWx0KTsgZnVwZGF0ZXNjcmlwdCgpOyB9Ow0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFkZXIucmVhZEFzQmluYXJ5U3RyaW5nKHguZmlsZXNbMF0pOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2tbJ3ZhcnMnXVtpXVsndmFsdWUnXSA9IFEoJ3NjcmlwdFh2YWx1ZV8nICsgaSkudmFsdWU7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBmdXBkYXRlc2NyaXB0KCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBTdGFydGluZyB3aXRoIGEgY2hpbGQgZWxlbWVudCwgZ28gdXAgb25lIHBhcmVudCBhdCBhIHRpbWUgdW50aWwgd2UgZmluZCBhbiBlbGVtZW50IHdpdGggYW4gSUQuDQogICAgICAgIGZ1bmN0aW9uIGZnZXRQYXJlbnRXaXRoSWQoeCkgeyB3aGlsZSAoIXguaWQpIHsgeCA9IHgucGFyZW50RWxlbWVudDsgfSByZXR1cm4geDsgfQ0KDQogICAgICAgIC8vIERpc3BsYXlzIHRoZSBsaXN0IG9mIHNjcmlwdCBibG9ja3MgdG8gdGhlIEhUTUwgcGFnZS4gRWFjaCBibG9jayBpcyBkaXNwbGF5ZWQgd2l0aCBpdCdzIG5hbWUsIGF0dHJpYnV0ZXMgYW5kIGFuIGVkaXQgYnV0dG9uLg0KICAgICAgICBmdW5jdGlvbiBmdXBkYXRlc2NyaXB0KCkgew0KICAgICAgICAgICAgdmFyIHggPSAnJzsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gc2NyaXB0X0Jsb2NrU2NyaXB0KSB7DQogICAgICAgICAgICAgICAgeCArPSAnPGRpdiBpZD14YmxvY2tfJyArIGkgKyAnIHN0eWxlPWN1cnNvcjpwb2ludGVyO21pbi1oZWlnaHQ6MjRweDtiYWNrZ3JvdW5kLWNvbG9yOiMnICsgKChzY3JpcHRfQmxvY2tTY3JpcHRTZWxlY3RlZElkID09IGkpID8gJ2FhYScgOiAnY2NjJykgKyAnO3dpZHRoOmF1dG87cGFkZGluZzo1cHg7bWFyZ2luOjJweCBkcmFnZ2FibGU9dHJ1ZSBvbmNsaWNrPXNjcmlwdF9mb25jbGljayhldmVudCx0aGlzKSBvbmRyYWdlbnRlcj1zY3JpcHRfZm9uZHJhZ2VudGVyKGV2ZW50LHRoaXMpIG9uZHJhZ2xlYXZlPXNjcmlwdF9mb25kcmFnbGVhdmUoZXZlbnQsdGhpcykgb25kcmFnc3RhcnQ9c2NyaXB0X2ZvbmRyYWdzdGFydChldmVudCx0aGlzKSBvbmRyYWdlbmQ9c2NyaXB0X2ZvbmRyYWdlbmQoZXZlbnQsdGhpcykgb25kcm9wPXNjcmlwdF9mb25kcm9wKGV2ZW50LHRoaXMpIHRpdGxlPSInICsgc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWydkZXNjJ10gKyAnIic7DQogICAgICAgICAgICAgICAgeCArPSAnPjxpbnB1dCBzdHlsZT1mbG9hdDpyaWdodCB0eXBlPWJ1dHRvbiB2YWx1ZT1FZGl0Li4uIG9uY2xpY2s9c2NyaXB0X2ZvbmVkaXRjbGljaygnICsgaSArICcpPjxkaXYgc3R5bGU9Zm9udC1zaXplOjE2cHg+PGI+JyArIHNjcmlwdF9CbG9ja1NjcmlwdFtpXS5uYW1lICsgJzwvYj4nOw0KICAgICAgICAgICAgICAgIGlmIChzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ3ZhcnMnXSkgew0KICAgICAgICAgICAgICAgICAgICB2YXIgciA9IDA7DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjx0YWJsZSBjbGFzcz0nc2NyaXB0QmxvY2tWYXIgdXMnIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6NXB4O21hcmdpbi10b3A6OHB4PiI7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ10pIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB2ID0gc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ3ZhbHVlJ107DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ3R5cGUnXSA9PSA0ICYmIHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsndmFycyddW2pdWyd2YWx1ZSddLmxlbmd0aCA+IDApIHYgPSAiKioqKioiOw0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsndmFycyddW2pdWyd0eXBlJ10gPT0gMykgdiA9IHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsndmFycyddW2pdWyd2YWx1ZXMnXVtzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ3ZhcnMnXVtqXVsndmFsdWUnXV07DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ3R5cGUnXSA9PSA2KSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsndmFycyddW2pdWyd2YWx1ZSddKSB7IHYgPSAiQmluYXJ5IGZpbGUsICIgKyBzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ3ZhcnMnXVtqXVsndmFsdWUnXS5sZW5ndGggKyAiIGJ5dGVzIjsgfSBlbHNlIHsgdiA9ICJOb3Qgc2V0IjsgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgICAgICAgeCArPSAiPHRyIHRpdGxlPSciICsgc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ2Rlc2MnXSArICInPjx0ZCB3aWR0aD0yMDBweCBzdHlsZT0nIiArIChyID4gMCA/ICJib3JkZXItdG9wOjFweCBzb2xpZCAjYTgxMGE4IiA6ICIiKSArICInPjxwPiIgKyBzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ3ZhcnMnXVtqXVsnbmFtZSddICsgIjx0ZCBzdHlsZT0nIiArIChyID4gMCA/ICJib3JkZXItdG9wOjFweCBzb2xpZCAjYTgxMGE4IiA6ICIiKSArICInPiIgKyB2Ow0KICAgICAgICAgICAgICAgICAgICAgICAgcisrOw0KICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIHggKz0gIjx0cj48dGQgc3R5bGU9aGVpZ2h0OjNweD48L3RhYmxlPiI7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIHggKz0gJzwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAoeCA9PSAnJykgeyB4ID0gJzxkaXYgc3R5bGU9InBhZGRpbmc6MTVweDtjb2xvcjpncmF5Ij5TdGFydCB5b3VyIHNjcmlwdCBieSBkcmFnICYgZHJvcHBpbmcgYmxvY2tzIGZyb20gdGhlIGxlZnQgc2lkZSBpbnRvIHRoaXMgc2NyaXB0aW5nIGJveC48ZGl2Pic7IH0NCiAgICAgICAgICAgIFFIKCdzY3JpcHRibG9ja3MnLCB4ICsgIjxkaXYgc3R5bGU9aGVpZ2h0OjgwcHg+PC9kaXY+Iik7DQogICAgICAgICAgICBmb3IgKHZhciBpIGluIHNjcmlwdF9CbG9ja1NjcmlwdCkgeyBRUygneGJsb2NrXycgKyBpKS5ib3JkZXJMZWZ0ID0gKHNjcmlwdF9DdXJyZW50SGlnaGxpZ2h0QmxvY2sgPT0gaSkgPyAiM3B4IHNvbGlkIGJsYWNrIiA6ICIiOyB9DQogICAgICAgICAgICBzY3JpcHRfYmxvY2tzVG9TY3JpcHQoKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIENvbnZlcnQgdGhlIGxpc3Qgb2YgYmxvY2tzIGludG8gYSBzY3JpcHQgdGhhdCBjYW4gYmUgY29tcGlsZWQNCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X2Jsb2Nrc1RvU2NyaXB0KCkgew0KICAgICAgICAgICAgdmFyIHNjcmlwdCA9ICcnOw0KICAgICAgICAgICAgaWYgKHNjcmlwdF9CdWlsZGluZ0Jsb2Nrcykgew0KICAgICAgICAgICAgICAgIGlmIChzY3JpcHRfQnVpbGRpbmdCbG9ja3NbJ19zdGFydCddKSB7IHNjcmlwdCArPSAnIyMjIyMgU3RhcnRpbmcgQmxvY2sgIyMjIyNcclxuJyArIHNjcmlwdF9CdWlsZGluZ0Jsb2Nrc1snX3N0YXJ0J11bJ2NvZGUnXSArICdcclxuXHJcbic7IH0NCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHNjcmlwdF9CbG9ja1NjcmlwdCkgew0KICAgICAgICAgICAgICAgICAgICB2YXIgY29kZSA9IHNjcmlwdF9CbG9ja1NjcmlwdFtpXVsnY29kZSddOw0KICAgICAgICAgICAgICAgICAgICBjb2RlID0gY29kZS5zcGxpdCgiJSUlfiUlJSIpLmpvaW4oaSk7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogaW4gc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ10pIHsgY29kZSA9IGNvZGUuc3BsaXQoIiUlJSIgKyBqICsgIiUlJSIpLmpvaW4oc2NyaXB0X0Jsb2NrU2NyaXB0W2ldWyd2YXJzJ11bal1bJ3ZhbHVlJ10pOyB9DQogICAgICAgICAgICAgICAgICAgIHNjcmlwdCArPSAnIyMjIyMgQmxvY2s6ICcgKyBzY3JpcHRfQmxvY2tTY3JpcHRbaV1bJ25hbWUnXSArICcgIyMjIyNcclxuSGlnaGxpZ2h0QmxvY2sgX190ICcgKyBpICsgJ1xyXG4nICsgY29kZSArICdcclxuXHJcbic7DQogICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgIGlmIChzY3JpcHRfQnVpbGRpbmdCbG9ja3NbJ19lbmQnXSkgeyBzY3JpcHQgKz0gJyMjIyMjIEVuZGluZyBCbG9jayAjIyMjI1xyXG4nICsgc2NyaXB0X0J1aWxkaW5nQmxvY2tzWydfZW5kJ11bJ2NvZGUnXSArICdcclxuSGlnaGxpZ2h0QmxvY2tcclxuJzsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgUSgnc2NyaXB0YXJlYScpLnZhbHVlID0gc2NyaXB0Ow0KICAgICAgICB9DQoNCiAgICAgICAgLy8gSGlnaGxpZ2h0IGEgc2NyaXB0IGJsb2NrLiBUaGlzIGlzIHVzZWZ1bCB0byBrbm93IHdoYXQgYmxvY2sgdGhlIHNjcmlwdCBpcyBjdXJyZW50bHkgcnVubmluZw0KICAgICAgICB2YXIgc2NyaXB0X0N1cnJlbnRIaWdobGlnaHRCbG9jazsNCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X0hpZ2hsaWdodEJsb2NrKHJ1bm5lciwgeCkgew0KICAgICAgICAgICAgaWYgKHJ1bm5lciA9PSBlZGl0c2NyaXB0c3RhdGUpIHsgLy8gT25seSBoaWdobGlnaHQgYmxvY2tzIGlmIHRoZSBzY3JwdCBlZGl0b3IgaXMgcnVubmluZyB0aGUgc2NyaXB0LiBJZiBydW5uaW5nIGEgc2NyaXB0IG9uIHRoZSBwYWdlLCBkb24ndCBoaWdobGlnaHQgYmxvY2tzIGluIHRoZSBlZGl0b3IuDQogICAgICAgICAgICAgICAgc2NyaXB0X0N1cnJlbnRIaWdobGlnaHRCbG9jayA9IHg7DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBzY3JpcHRfQmxvY2tTY3JpcHQpIHsgUVMoJ3hibG9ja18nICsgaSkuYm9yZGVyTGVmdCA9IChzY3JpcHRfQ3VycmVudEhpZ2hsaWdodEJsb2NrID09IGkpID8gIjNweCBzb2xpZCBibGFjayIgOiAiIjsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ2FsbGVkIGJ5IHRoZSAiTmV3Li4uIiBidXR0b24gdG8gcmVzZXQgdGhlIHNjcmlwdCBlZGl0b3IgdG8gdGhlIHN0YXJ0DQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF9uZXdTY3JpcHREbGcoKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDExLCAiTmV3IFNjcmlwdCIsIDMsIHNjcmlwdF9uZXdTY3JpcHREbGdPaywgIjxicj5SZXNldCAmIGNsZWFyIHRoZSBzY3JpcHQgZWRpdG9yPyIpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gQ2xlYXIgdGhlIHNjcmlwdCBlZGl0b3INCiAgICAgICAgZnVuY3Rpb24gc2NyaXB0X25ld1NjcmlwdERsZ09rKCkgew0KICAgICAgICAgICAgc2NyaXB0X3NldEJ1aWxkQmxvY2tzKHNjcmlwdF9TdGFydGluZ0J1aWxkaW5nQmxvY2tzKTsNCiAgICAgICAgICAgIHNjcmlwdF9CbG9ja1NjcmlwdCA9IFtdOw0KICAgICAgICAgICAgc2NyaXB0X0Jsb2NrU2NyaXB0U2VsZWN0ZWRJZCA9IG51bGw7DQogICAgICAgICAgICBkZWxldGUgZWRpdHNjcmlwdHN0YXRlOw0KICAgICAgICAgICAgc2NyaXB0Vmlld0J1dHRvbihzY3JpcHRfQnVpbGRpbmdCbG9ja3M/MTowKTsNCiAgICAgICAgICAgIFFIKCd2YXJpYWJsZXMnLCAnJyk7DQogICAgICAgICAgICBRKCdzY3JpcHRhcmVhJykudmFsdWUgPSAnJzsNCiAgICAgICAgICAgIHJlc2V0U2NyaXB0QnV0dG9uKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBDb21waWxlIGFuZCByZXNldCBhIHNjcmlwdCB0byB0aGUgc3RhcnRpbmcgcG9zaXRpb24NCiAgICAgICAgZnVuY3Rpb24gcmVzZXRTY3JpcHRCdXR0b24oKSB7DQogICAgICAgICAgICAvLyBDb21waWxlIHRoZSBzY3JpcHQNCiAgICAgICAgICAgIGJyZWFrU2NyaXB0QnV0dG9uKCk7DQogICAgICAgICAgICBRKCdjb21waWxlZGFyZWEnKS52YWx1ZSA9IHJzdHIyaGV4KHNjcmlwdF9jb21waWxlKFEoJ3NjcmlwdGFyZWEnKS52YWx1ZSwgZnVuY3Rpb24obSkgeyBtZXNzYWdlYm94KCJTY3JpcHQgQ29tcGlsZSBFcnJvciIsIG0pOyB9KSk7DQogICAgICAgICAgICBkZWxldGUgZWRpdHNjcmlwdHN0YXRlOw0KDQogICAgICAgICAgICAvLyBSZXNldCB0aGUgc2NyaXB0IGVudmlyb25tZW50DQogICAgICAgICAgICBRKCdjb25zb2xlJykudmFsdWUgPSAnJzsNCiAgICAgICAgICAgIFFIKCd2YXJpYWJsZXMnLCAnJyk7DQogICAgICAgICAgICBRSCgnRWRpdFNjcmlwdFN0YXR1cycsICdTdG9wcGVkJyk7DQogICAgICAgICAgICBpZiAoc2NyaXB0X0J1aWxkZXJWaWV3ID09IDEpIHsgZnVwZGF0ZXNjcmlwdCgpOyB9DQogICAgICAgICAgICBpZiAoUSgnY29tcGlsZWRhcmVhJykudmFsdWUubGVuZ3RoID09IDApIHJldHVybjsNCg0KICAgICAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IHNjcmlwdCBydW50aW1lIG9iamVjdA0KICAgICAgICAgICAgdmFyIHN0YXJ0dmFycyA9IHsgJ19pbnRlcmFjdGl2ZSc6MSB9Ow0KDQogICAgICAgICAgICBzdGFydHZhcnNbJ19jZXJ0aWZpY2F0ZXMnXSA9IDE7DQoNCiAgICAgICAgICAgIHN0YXJ0dmFyc1snX21vZGUnXSA9ICdGaXJtd2FyZSc7DQoNCiAgICAgICAgICAgIHN0YXJ0dmFyc1snX21vZGUnXSA9ICdNZXNoQ2VudHJhbDInOw0KDQogICAgICAgICAgICBzdGFydHZhcnNbJ19tb2RlJ10gPSAnTE1TJzsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRzdGF0ZSA9IHNjcmlwdF9zZXR1cChoZXgycnN0cihRKCdjb21waWxlZGFyZWEnKS52YWx1ZSksIHN0YXJ0dmFycyk7DQogICAgICAgICAgICBlZGl0c2NyaXB0c3RhdGUud3NzdGFjayA9IHdzc3RhY2s7DQogICAgICAgICAgICBlZGl0c2NyaXB0c3RhdGUuYW10c3RhY2sgPSBhbXRzdGFjazsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRzdGF0ZS5vblN0ZXAgPSBlZGl0c2NyaXB0X3VwZGF0ZVNjcmlwdFN0YXRlOw0KICAgICAgICAgICAgZWRpdHNjcmlwdHN0YXRlLm9uQ29uc29sZSA9IGVkaXRzY3JpcHRfY29uc29sZTsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRfdXBkYXRlU2NyaXB0U3RhdGUoZWRpdHNjcmlwdHN0YXRlKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIFN0YXJ0IHJ1bm5pbmcgdGhlIHNjcmlwdA0KICAgICAgICBmdW5jdGlvbiBydW5TY3JpcHRCdXR0b24oKSB7DQogICAgICAgICAgICBpZiAoZWRpdHNjcmlwdHN0YXRlID09IG51bGwpIHJlc2V0U2NyaXB0QnV0dG9uKCk7DQogICAgICAgICAgICBpZiAoZWRpdHNjcmlwdHN0YXRlID09IG51bGwpIHJldHVybjsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRzdGF0ZS5zdGFydCgxMDApOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gU3RvcC9QYXVzZSB0aGUgc2NyaXB0DQogICAgICAgIGZ1bmN0aW9uIGJyZWFrU2NyaXB0QnV0dG9uKCkgew0KICAgICAgICAgICAgaWYgKGVkaXRzY3JpcHRzdGF0ZSA9PSBudWxsKSByZXR1cm47DQogICAgICAgICAgICBlZGl0c2NyaXB0c3RhdGUuc3RvcCgpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gUnVuIG9uZSBzdGVwIG9mIHRoZSBzY3JpcHQNCiAgICAgICAgZnVuY3Rpb24gc3RlcFNjcmlwdEJ1dHRvbigpIHsNCiAgICAgICAgICAgIGlmIChlZGl0c2NyaXB0c3RhdGUgPT0gbnVsbCkgcmVzZXRTY3JpcHRCdXR0b24oKTsNCiAgICAgICAgICAgIGlmIChlZGl0c2NyaXB0c3RhdGUgPT0gbnVsbCkgcmV0dXJuOw0KICAgICAgICAgICAgYnJlYWtTY3JpcHRCdXR0b24oKTsNCiAgICAgICAgICAgIGVkaXRzY3JpcHRzdGF0ZS5zdGVwKCk7DQogICAgICAgIH0NCg0KICAgICAgICAvLyBEaXNwbGF5IGEgbmV3IGxpbmUgaW50byB0aGUgc2NyaXB0IGNvbnNvbGUNCiAgICAgICAgZnVuY3Rpb24gZWRpdHNjcmlwdF9jb25zb2xlKG1zZykgew0KICAgICAgICAgICAgUSgnY29uc29sZScpLnZhbHVlICs9IChtc2cgKyAnXG4nKTsNCiAgICAgICAgfQ0KDQogICAgICAgIC8vIFVwZGF0ZSB0aGUgc2NyaXB0IHN0YXRlIGluZm9ybWF0aW9uIGFuZCBkaXNwbGF5ZWQgdmFyaWFibGVzDQogICAgICAgIHZhciBzY3JpcHRfc3RhdGVzID0gWydTdG9wcGVkJywgJ1J1bm5pbmcnLCAnUGF1c2VkJ107DQogICAgICAgIGZ1bmN0aW9uIGVkaXRzY3JpcHRfdXBkYXRlU2NyaXB0U3RhdGUocnVuc3RhdGUpIHsNCiAgICAgICAgICAgIC8vIFVwZGF0ZSB2YXJpYWJsZXMNCiAgICAgICAgICAgIHZhciByID0gJyc7DQogICAgICAgICAgICBpZiAocnVuc3RhdGUgJiYgcnVuc3RhdGUgIT0gbnVsbCkgew0KICAgICAgICAgICAgICAgIHZhciB2cyA9IFtdOw0KICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gcnVuc3RhdGUudmFyaWFibGVzKSB7IGlmICghaS5zdGFydHNXaXRoKCdfXycpKSB2cy5wdXNoKGkpOyB9DQogICAgICAgICAgICAgICAgdnMuc29ydCgpOw0KICAgICAgICAgICAgICAgIC8vZm9yICh2YXIgaSBpbiB2cykgeyByICs9IHZzW2ldICsgIiA9ICIgKyBzY3JpcHRfdG9TdHJpbmcocnVuc3RhdGUudmFyaWFibGVzW3ZzW2ldXSkgKyAiXG4iOyB9DQogICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiB2cykgew0KICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHJ1bnN0YXRlLnZhcmlhYmxlc1t2c1tpXV0gPT0gJ29iamVjdCcpIHsNCiAgICAgICAgICAgICAgICAgICAgICAgIHIgKz0gIjxiPiIgKyB2c1tpXSArICI8L2I+ID0gIiArIE9iamVjdFRvU3RyaW5nRXgocnVuc3RhdGUudmFyaWFibGVzW3ZzW2ldXSwgMikgKyAiPGJyPiI7DQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgICAgICByICs9ICI8Yj4iICsgdnNbaV0gKyAiPC9iPiA9ICIgKyBFc2NhcGVIdG1sKHNjcmlwdF90b1N0cmluZyhydW5zdGF0ZS52YXJpYWJsZXNbdnNbaV1dKSkgKyAiPGJyPiI7DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQogICAgICAgICAgICBRSCgndmFyaWFibGVzJywgcik7DQoNCiAgICAgICAgICAgIC8vIFVwZGF0ZSBzdGF0ZQ0KICAgICAgICAgICAgciA9ICdTdG9wcGVkLCBObyBTY3JpcHQnOw0KICAgICAgICAgICAgaWYgKHJ1bnN0YXRlICYmIHJ1bnN0YXRlICE9IG51bGwpIHsgciA9IHNjcmlwdF9zdGF0ZXNbcnVuc3RhdGUuc3RhdGVdOyBpZiAocnVuc3RhdGUuc3RhdGUgPiAwKSByICs9ICIsICIgKyBydW5zdGF0ZS5pcCArICIgOiAiICsgc2NyaXB0X2RlY29tcGlsZShydW5zdGF0ZS5zY3JpcHQsIHJ1bnN0YXRlLmlwKTsgfQ0KICAgICAgICAgICAgaWYgKHIubGVuZ3RoID4gNTApIHsgciA9IHIuc3Vic3RyaW5nKDAsIDUwKSArICIuLi4iOyB9DQogICAgICAgICAgICBRSCgnRWRpdFNjcmlwdFN0YXR1cycsIHIpOw0KICAgICAgICB9DQoNCiAgICAgICAgLy8gUmV0dXJuIGEgc3RyaW5nIGZyb20gYW55IGlucHV0LCBpZiB0aGUgaW5wdXQgaXMgYW4gb2JqZWN0LCBzdHJpbmdpZnkgaXQuDQogICAgICAgIGZ1bmN0aW9uIHNjcmlwdF90b1N0cmluZyh4KSB7IGlmICh0eXBlb2YgeCA9PSAnb2JqZWN0JykgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHgpOyByZXR1cm4geDsgfQ0KDQoNCiAgICAgICAgLy8gU2F2ZSBhIHNjcmlwdCB0byBkaXNrLCBzdGFydCBieSBzaG93aW5nIGEgZGlhbG9nIGJveCB0byBwcm9tcHQgdG8gdGhlIGZpbGVuYW1lLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfc2F2ZVNjcmlwdChlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlIHx8IHNjcmlwdHN0YXRlKSByZXR1cm47DQogICAgICAgICAgICBpZiAoZSAmJiAoZS5zaGlmdEtleSA9PSB0cnVlKSkgew0KICAgICAgICAgICAgICAgIC8vIFNhdmUgYXMgc2NyaXB0IGJsb2NrDQogICAgICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIlNjcmlwdCBCbG9jayIsIDEsIG51bGwsICI8YnI+PHRleHRhcmVhIGlkPXNjcmlwdFNhdmVTY3JpcHRKc29uQmxvY2sgc3R5bGU9d2lkdGg6MTAwJTtoZWlnaHQ6MjAwcHg7cmVzaXplOnZlcnRpY2FsIC8+Iik7DQogICAgICAgICAgICAgICAgUUgoJ3NjcmlwdFNhdmVTY3JpcHRKc29uQmxvY2snLCBzY3JpcHRfZkNvbnZlcnRTY3JpcHRUb0pzb25CbG9jayhRKCdzY3JpcHRhcmVhJykudmFsdWUpKTsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgLy8gU2F2ZSBhcyAubWVzY3JpcHQgZmlsZQ0KDQogICAgICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxMSwgIlNhdmUgU2NyaXB0IiwgMywgc2NyaXB0X3NhdmVTY3JpcHRPaywgIjxicj48aW5wdXQgaWQ9c2NyaXB0c2F2ZW5hbWUgc3R5bGU9d2lkdGg6MTAwJSB2YWx1ZT10ZXN0Lm1lc2NyaXB0ID4iKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIC8vIE9uY2UgdGhlIGZpbGVuYW1lIGlzIHNlbGVjdGVkLCBzYXZlIHRoZSBmaWxlLg0KICAgICAgICBmdW5jdGlvbiBzY3JpcHRfc2F2ZVNjcmlwdE9rKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHggPSBKU09OLnN0cmluZ2lmeSh7DQogICAgICAgICAgICAgICAgInNjcmlwdFRleHQiOiBRKCdzY3JpcHRhcmVhJykudmFsdWUsDQogICAgICAgICAgICAgICAgIm1lc2NyaXB0IjogYnRvYShzY3JpcHRfY29tcGlsZShRKCdzY3JpcHRhcmVhJykudmFsdWUpKSwNCiAgICAgICAgICAgICAgICAiYmxvY2tzIjogc2NyaXB0X1N0YXJ0aW5nQnVpbGRpbmdCbG9ja3MsDQogICAgICAgICAgICAgICAgInNjcmlwdEJsb2NrcyI6IHNjcmlwdF9CbG9ja1NjcmlwdA0KICAgICAgICAgICAgfSwgbnVsbCwgJyAgJyk7DQogICAgICAgICAgICBzYXZlQXMoZGF0YTJibG9iKHgpLCBRKCdzY3JpcHRzYXZlbmFtZScpLnZhbHVlKTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgDQoNCg0KICAgICAgICAvLw0KICAgICAgICAvLyBVU0IgU0VUVVAuQklODQogICAgICAgIC8vDQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX25ld1NldHVwQmluKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgaWR4X2QxNHZlcnNpb24udmFsdWUgPSA0Ow0KICAgICAgICAgICAgaWR4X2QxNGNvbnN1bWUudmFsdWUgPSAxOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxNCwgIkNyZWF0ZSBuZXcgU2V0dXAuYmluIGZpbGUiLCAzLCB1c2JfbmV3U2V0dXBCaW5Payk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2JfbmV3U2V0dXBCaW5PayhyKSB7DQogICAgICAgICAgICBpZiAociA9PSAxKSB7IHNldHVwYmluID0gQW10U2V0dXBCaW5DcmVhdGUoaWR4X2QxNHZlcnNpb24udmFsdWUsIGlkeF9kMTRjb25zdW1lLnZhbHVlKTsgfSAvLyBPSyBCdXR0b24NCiAgICAgICAgICAgIHVzYl9kaXNwbGF5U2V0dXBCaW4oKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9vcGVuU2V0dXBCaW4oKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQoNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTUsICJPcGVuIFNldHVwLmJpbiBmaWxlIiwgMywgdXNiX29wZW5TZXR1cEJpbk9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9vcGVuU2V0dXBCaW5PaygpIHsNCiAgICAgICAgICAgIHZhciB4ID0gUSgnZDE1c2V0dXBiaW5maWxlJyk7DQogICAgICAgICAgICBpZiAoeC5maWxlcy5sZW5ndGggIT0gMSkgcmV0dXJuOw0KICAgICAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7DQogICAgICAgICAgICByZWFkZXIub25sb2FkID0gdXNiX29uU2V0dXBCaW5SZWFkOw0KICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0JpbmFyeVN0cmluZyh4LmZpbGVzWzBdKTsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX3NhdmVTZXR1cEJpbigpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgfHwgIXNldHVwYmluKSByZXR1cm47DQoNCiAgICAgICAgICAgIHNhdmVBcyhkYXRhMmJsb2IoQW10U2V0dXBCaW5FbmNvZGUoc2V0dXBiaW4pKSwgInNldHVwLmJpbiIpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX29uU2V0dXBCaW5SZWFkKGZpbGUpIHsNCiAgICAgICAgICAgIHNldHVwYmluID0gQW10U2V0dXBCaW5EZWNvZGUoZmlsZS50YXJnZXQucmVzdWx0KTsNCiAgICAgICAgICAgIGlmICghc2V0dXBiaW4pIHsgbWVzc2FnZWJveCgiT3BlbiBGaWxlIiwgIkludmFsaWQgb3IgY29ycnVwdCBzZXR1cC5iaW4gZmlsZS4gVW5hYmxlIHRvIG9wZW4uIik7IH0gZWxzZSB7IHVzYl9kaXNwbGF5U2V0dXBCaW4oKTsgfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2Rpc3BsYXlTZXR1cEJpbigpIHsNCiAgICAgICAgICAgIFFWKCdpZF9TdGFydHVwU2NyZWVuJywgIXNldHVwYmluKTsNCg0KICAgICAgICAgICAgUVYoJ2lkX3NhdmVTZXR1cEJpbicsIHNldHVwYmluKTsNCiAgICAgICAgICAgIGlmICghc2V0dXBiaW4pIHsgcmV0dXJuIFFIKCdpZF9TZXR1cEJpbkFyZWEnLCAnJyk7IH0NCiAgICAgICAgICAgIA0KICAgICAgICAgICAgLy8gVXBkYXRlIHJlY29yZCBjb3VudA0KICAgICAgICAgICAgdmFyIGNvbnN1bWVkID0gMDsNCiAgICAgICAgICAgIGZvciAodmFyIGkgaW4gc2V0dXBiaW4ucmVjb3JkcykgeyBpZiAoKHNldHVwYmluLnJlY29yZHNbaV0uZmxhZ3MgJiAxKSA9PSAwKSB7IGNvbnN1bWVkKys7IH0gfQ0KICAgICAgICAgICAgc2V0dXBiaW4uZGF0YVJlY29yZHNDb25zdW1lZCA9IGNvbnN1bWVkOw0KDQogICAgICAgICAgICAvLyBNYWluIEhlYWRlciAgICAgICAgICAgIA0KICAgICAgICAgICAgdmFyIHggPSAiPHRhYmxlIG9uY2xpY2s9dXNiX2VkaXRoZWFkZXIoZXZlbnQpIGNsYXNzPSdsb2cxIHVzJyBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjhweDtjdXJzb3I6cG9pbnRlcj48dHI+PHRkPjxwPjx0ZD4iOw0KICAgICAgICAgICAgeCArPSAiPHRyPjx0ZCBjbGFzcz1yMiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweD4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1mbG9hdDpyaWdodDttYXJnaW4tcmlnaHQ6MTJweCBvbmNsaWNrPXVzYl9hZGRSZWNvcmRTZXR1cEJpbigpPjxhPjx1IHRpdGxlPSdBZGQgYSBuZXcgcmVjb3JkJz5BZGQgUmVjb3JkPC91PjwvYT48L2Rpdj4iOw0KICAgICAgICAgICAgeCArPSAiPGRpdj48c3Ryb25nPkludGVsJnJlZzsgQU1UIFNldHVwLmJpbiBmaWxlIHZlcnNpb24gIiArIHNldHVwYmluLm1ham9yVmVyc2lvbiArICIuIiArIHNldHVwYmluLm1pbm9yVmVyc2lvbiArICI8L3N0cm9uZz4uPC9kaXY+IjsNCiAgICAgICAgICAgIHggKz0gKCgoc2V0dXBiaW4uZmxhZ3MgJiAxKSA9PSAwKSA/ICJSZWNvcmRzIHdpbGwgYmUgY29uc3VtZWQuIiA6ICJSZWNvcmRzIHdpbGwgbm90IGJlIGNvbnN1bWVkLiIpOw0KICAgICAgICAgICAgeCArPSAiPGJyPlJlY29yZHM6ICIgKyBzZXR1cGJpbi5yZWNvcmRzLmxlbmd0aCArICIsIENvbnN1bWVkOiAiICsgc2V0dXBiaW4uZGF0YVJlY29yZHNDb25zdW1lZCArICI8YnI+IjsNCiAgICAgICAgICAgIHggKz0gIjx0ciBzdHlsZT1oZWlnaHQ6NHB4PjwvdGFibGU+IjsNCg0KICAgICAgICAgICAgLy8gRGlzcGxheSBlYWNoIHJlY29yZA0KICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBzZXR1cGJpbi5yZWNvcmRzKSB7DQogICAgICAgICAgICAgICAgdmFyIHJlYyA9IHNldHVwYmluLnJlY29yZHNbaV07DQogICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1oZWlnaHQ6NHB4PjwvZGl2Pjx0YWJsZSBjbGFzcz0nbG9nMSB1cycgY2VsbHBhZGRpbmc9MCBjZWxsc3BhY2luZz0wIHN0eWxlPXdpZHRoOjEwMCU7Ym9yZGVyLXJhZGl1czo4cHg+PHRyPjx0ZD48cD48dGQ+PHRyPjx0ZCBjbGFzcz1yMiBzdHlsZT1wYWRkaW5nLWxlZnQ6MTVweDtjdXJzb3I6cG9pbnRlcj4iOw0KICAgICAgICAgICAgICAgIHggKz0gIjxkaXYgc3R5bGU9ZmxvYXQ6cmlnaHQ7bWFyZ2luLXJpZ2h0OjEycHggb25jbGljaz0ndXNiX2FkZHZhcmlhYmxlKGV2ZW50LCIgKyBpICsgIiknPjxhPjx1IHRpdGxlPSdBZGQgYSBuZXcgdmFyaWFibGUnPkFkZCBWYXJpYWJsZTwvdT48L2E+PC9kaXY+IjsNCiAgICAgICAgICAgICAgICB4ICs9ICI8ZGl2IG9uY2xpY2s9J3VzYl9lZGl0cmVjb3JkKGV2ZW50LCAiICsgaSArICIpJz5SZWNvcmQgIzxzdHJvbmc+IiArICgraSArIDEpICsgIjwvc3Ryb25nPi4gVGhpcyByZWNvcmQgaXM6IDxzdHJvbmc+IiArICgocmVjLmZsYWdzICYgMSkgPyAiVmFsaWQiIDogIkNvbnN1bWVkIikgKyAoKHJlYy5mbGFncyAmIDIpID8gIiwgU2NyYW1ibGVkIiA6ICIiKSArICI8L3N0cm9uZz48L2Rpdj4iOw0KDQogICAgICAgICAgICAgICAgLy8gRGlzcGxheSBlYWNoIHZhcmlhYmxlDQogICAgICAgICAgICAgICAgZm9yICh2YXIgaiBpbiByZWMudmFyaWFibGVzKSB7DQogICAgICAgICAgICAgICAgICAgIHZhciB2ID0gcmVjLnZhcmlhYmxlc1tqXSwgdmFsID0gdi52YWx1ZTsNCiAgICAgICAgICAgICAgICAgICAgaWYgKEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdWzJdICYmIEFtdFNldHVwQmluVmFySWRzW3YubW9kdWxlaWRdW3YudmFyaWRdWzJdW3ZhbF0pIHsgdmFsID0gQW10U2V0dXBCaW5WYXJJZHNbdi5tb2R1bGVpZF1bdi52YXJpZF1bMl1bdmFsXTsgfQ0KICAgICAgICAgICAgICAgICAgICBpZiAodi5tb2R1bGVpZCA9PSAyICYmIHYudmFyaWQgPT0gOCkgew0KICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2h0eXBlID0gdmFsLmNoYXJDb2RlQXQoMCk7DQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzaHR5cGUgPj0gMCAmJiBoYXNodHlwZSA8PSAzKSB7DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2hzaXplID0gWzIwLCAzMiwgNDhdW2hhc2h0eXBlIC0gMV07DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2ggPSByc3RyMmhleCh2YWwuc3Vic3RyaW5nKDEsIGhhc2hzaXplICsgMSkpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYXNobmFtZXNpemUgPSB2YWwuY2hhckNvZGVBdCgxICsgaGFzaHNpemUpOw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBoYXNobmFtZSA9IHZhbC5zdWJzdHJpbmcoMiArIGhhc2hzaXplLCAyICsgaGFzaHNpemUgKyBoYXNobmFtZXNpemUpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsID0gWydTSEExJywgJ1NIQTI1NicsICdTSEEzODQnXVtoYXNodHlwZSAtIDFdICsgJywgJyArIGhhc2huYW1lICsgJywgJyArIGhhc2g7DQogICAgICAgICAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgICAgeCArPSAiPGRpdiBzdHlsZT1tYXJnaW4tcmlnaHQ6MTJweD48dGFibGUgb25jbGljaz0ndXNiX2VkaXR2YXJpYWJsZShldmVudCwgIiArIGkgKyAiLCIgKyBqICsgIiknIGNsYXNzPSdpdGVtQmFyIHVzJyBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjRweDttYXJnaW4tdG9wOjJweDttYXJnaW4tYm90dG9tOjJweDtwYWRkaW5nOjA+PHRyPjx0ZD48cCBzdHlsZT1mbG9hdDpyaWdodDttYXJnaW4tcmlnaHQ6OHB4PjxiPiIgKyB2YWwgKyAiPC9iPjxwPiIgKyB2WydkZXNjJ10gKyAiPHRyIHN0eWxlPWhlaWdodDo0cHg+PC90YWJsZT48L2Rpdj4iOw0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIHggKz0gIjx0ciBzdHlsZT1oZWlnaHQ6NHB4PjwvdGFibGU+IjsNCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgUUgoJ2lkX1NldHVwQmluQXJlYScsIHgpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2FkZFJlY29yZFNldHVwQmluKCkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgZDEzdmFsaWQuY2hlY2tlZCA9IDE7DQogICAgICAgICAgICBkMTNzY3JhbWJsZS5jaGVja2VkID0gMDsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTMsICJOZXcgUmVjb3JkICMiLCAzLCB1c2JfYWRkUmVjb3JkU2V0dXBCaW5Payk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2JfYWRkUmVjb3JkU2V0dXBCaW5PaygpIHsNCiAgICAgICAgICAgIHZhciByID0ge307DQogICAgICAgICAgICByLnR5cGVJZGVudGlmaWVyID0gMTsNCiAgICAgICAgICAgIHIuZmxhZ3MgPSAoZDEzdmFsaWQuY2hlY2tlZCA/IDEgOiAwKSArIChkMTNzY3JhbWJsZS5jaGVja2VkID8gMiA6IDApOw0KICAgICAgICAgICAgci5jaHVua0NvdW50ID0gMDsNCiAgICAgICAgICAgIHIuaGVhZGVyQnl0ZUNvdW50ID0gMDsNCiAgICAgICAgICAgIHIubnVtYmVyID0gMDsNCiAgICAgICAgICAgIHIudmFyaWFibGVzID0gW107DQogICAgICAgICAgICBzZXR1cGJpbi5yZWNvcmRzLnB1c2gocik7DQogICAgICAgICAgICB1c2JfZGlzcGxheVNldHVwQmluKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2JfZWRpdGhlYWRlcihlKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBoYWx0RXZlbnQoZSk7DQogICAgICAgICAgICBpZHhfZDE0dmVyc2lvbi52YWx1ZSA9IHNldHVwYmluLm1ham9yVmVyc2lvbjsNCiAgICAgICAgICAgIGlkeF9kMTRjb25zdW1lLnZhbHVlID0gKHNldHVwYmluLmZsYWdzICYgMSk7DQogICAgICAgICAgICBzZXREaWFsb2dNb2RlKDE0LCAiRWRpdCBIZWFkZXIiLCA3LCB1c2JfZWRpdGhlYWRlcm9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9lZGl0aGVhZGVyb2socikgew0KICAgICAgICAgICAgaWYgKHIgPT0gMikgew0KICAgICAgICAgICAgICAgIGRlbGV0ZSBzZXR1cGJpbjsNCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgc2V0dXBiaW4ubWFqb3JWZXJzaW9uID0gaWR4X2QxNHZlcnNpb24udmFsdWU7DQogICAgICAgICAgICAgICAgc2V0dXBiaW4uZmxhZ3MgPSBpZHhfZDE0Y29uc3VtZS52YWx1ZTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIHVzYl9kaXNwbGF5U2V0dXBCaW4oKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9lZGl0cmVjb3JkKGUsIGkpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUpIHJldHVybjsNCiAgICAgICAgICAgIHNlbGVjdGVkUmVjb3JkID0gaTsNCiAgICAgICAgICAgIHNlbGVjdGVkVmFyaWFibGUgPSAtMTsNCiAgICAgICAgICAgIGhhbHRFdmVudChlKTsNCiAgICAgICAgICAgIGQxM3ZhbGlkLmNoZWNrZWQgPSAoc2V0dXBiaW4ucmVjb3Jkc1tzZWxlY3RlZFJlY29yZF0uZmxhZ3MgJiAxKTsNCiAgICAgICAgICAgIGQxM3NjcmFtYmxlLmNoZWNrZWQgPSAoc2V0dXBiaW4ucmVjb3Jkc1tzZWxlY3RlZFJlY29yZF0uZmxhZ3MgJiAyKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTMsICJFZGl0IFJlY29yZCAjIiArIChpICsgMSksIDcsIHVzYl9lZGl0cmVjb3Jkb2spOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2VkaXRyZWNvcmRvayhyKSB7DQogICAgICAgICAgICBpZiAociA9PSAxKSB7IHNldHVwYmluLnJlY29yZHNbc2VsZWN0ZWRSZWNvcmRdLmZsYWdzID0gKGQxM3ZhbGlkLmNoZWNrZWQgPyAxIDogMCkgKyAoZDEzc2NyYW1ibGUuY2hlY2tlZCA/IDIgOiAwKTsgfSAvLyBFZGl0IFJlY29yZA0KICAgICAgICAgICAgaWYgKHIgPT0gMikgeyBzZXR1cGJpbi5yZWNvcmRzLnNwbGljZShzZWxlY3RlZFJlY29yZCwgMSk7IH0gLy8gRGVsZXRlIFJlY29yZA0KICAgICAgICAgICAgdXNiX2Rpc3BsYXlTZXR1cEJpbigpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2VkaXR2YXJpYWJsZShlLCBpLCBqKSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBzZWxlY3RlZFJlY29yZCA9IGk7DQogICAgICAgICAgICBzZWxlY3RlZFZhcmlhYmxlID0gajsNCiAgICAgICAgICAgIHZhciBtb2RpZCA9IHNldHVwYmluLnJlY29yZHNbaV0udmFyaWFibGVzW2pdLm1vZHVsZWlkOw0KICAgICAgICAgICAgdmFyIHZhcmlkID0gc2V0dXBiaW4ucmVjb3Jkc1tpXS52YXJpYWJsZXNbal0udmFyaWQ7DQogICAgICAgICAgICBkMTZ0eXBlLnZhbHVlID0gbW9kaWQgKyAiLSIgKyB2YXJpZDsNCiAgICAgICAgICAgIGQxNnR5cGUuZGlzYWJsZWQgPSB0cnVlOw0KICAgICAgICAgICAgdXNiX29uZDE2dHlwZWNoYW5nZSgpOw0KICAgICAgICAgICAgUVYoJ2QxNmdlbmVyaWN2YWx1ZScsIGZhbHNlKTsNCiAgICAgICAgICAgIFFWKCdkMTZjdXN0b212YWx1ZScsIGZhbHNlKTsNCiAgICAgICAgICAgIGlmIChtb2RpZCA9PSAyICYmIHZhcmlkID09IDgpIHsNCiAgICAgICAgICAgICAgICB2YXIgeCA9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxzZWxlY3QgaWQ9aWR4X2QxNnZhbGMxIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG9uY2hhbmdlPXVzYl9vbmQxNmNoZWNraGFzaCgpPjxvcHRpb24gdmFsdWU9MT5TSEExPC9vcHRpb24+JzsNCiAgICAgICAgICAgICAgICBpZiAoc2V0dXBiaW4ubWFqb3JWZXJzaW9uID49IDMpIHsgeCArPSAnPG9wdGlvbiB2YWx1ZT0yPlNIQTI1Njwvb3B0aW9uPjxvcHRpb24gdmFsdWU9Mz5TSEEzODQ8L29wdGlvbj4nOyB9DQogICAgICAgICAgICAgICAgeCArPSAnPC9zZWxlY3Q+PGRpdj5IYXNoIFR5cGU8L2Rpdj48L2Rpdj4nOw0KICAgICAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWlkeF9kMTZ2YWxjMiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjBweCBvbmtleXVwPXVzYl9vbmQxNmNoZWNraGFzaCgpPjxkaXY+SGFzaCAoSEVYKTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICAgICAgeCArPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48aW5wdXQgaWQ9aWR4X2QxNnZhbGMzIHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjI2MHB4IG9ua2V5dXA9dXNiX29uZDE2Y2hlY2toYXNoKCkgbWF4bGVuZ3RoPTMxPjxkaXY+SGFzaCBOYW1lPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgICAgICBRSCgnZDE2Y3VzdG9tdmFsdWUnLCB4KTsNCiAgICAgICAgICAgICAgICBRVignZDE2Y3VzdG9tdmFsdWUnLCB0cnVlKTsNCiAgICAgICAgICAgICAgICB2YXIgdmFsID0gc2V0dXBiaW4ucmVjb3Jkc1tpXS52YXJpYWJsZXNbal0udmFsdWU7DQogICAgICAgICAgICAgICAgdmFyIGhhc2h0eXBlID0gdmFsLmNoYXJDb2RlQXQoMCk7DQogICAgICAgICAgICAgICAgaWYgKGhhc2h0eXBlID49IDAgJiYgaGFzaHR5cGUgPD0gMykgew0KICAgICAgICAgICAgICAgICAgICB2YXIgaGFzaHNpemUgPSBbMjAsIDMyLCA0OF1baGFzaHR5cGUgLSAxXTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2ggPSByc3RyMmhleCh2YWwuc3Vic3RyaW5nKDEsIGhhc2hzaXplICsgMSkpOw0KICAgICAgICAgICAgICAgICAgICB2YXIgaGFzaG5hbWVzaXplID0gdmFsLmNoYXJDb2RlQXQoMSArIGhhc2hzaXplKTsNCiAgICAgICAgICAgICAgICAgICAgdmFyIGhhc2huYW1lID0gdmFsLnN1YnN0cmluZygyICsgaGFzaHNpemUsIDIgKyBoYXNoc2l6ZSArIGhhc2huYW1lc2l6ZSkNCiAgICAgICAgICAgICAgICAgICAgdmFsID0gWydTSEExJywgJ1NIQTI1NicsICdTSEEzODQnXVtoYXNodHlwZSAtIDFdICsgJywgJyArIGhhc2huYW1lICsgJywgJyArIGhhc2g7DQogICAgICAgICAgICAgICAgICAgIFEoJ2lkeF9kMTZ2YWxjMScpLnZhbHVlID0gaGFzaHR5cGU7DQogICAgICAgICAgICAgICAgICAgIFEoJ2lkeF9kMTZ2YWxjMicpLnZhbHVlID0gaGFzaDsNCiAgICAgICAgICAgICAgICAgICAgUSgnaWR4X2QxNnZhbGMzJykudmFsdWUgPSBoYXNobmFtZTsNCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgdXNiX29uZDE2Y2hlY2toYXNoKCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFFWKCdkMTZnZW5lcmljdmFsdWUnLCB0cnVlKTsNCiAgICAgICAgICAgICAgICBpZHhfZDE2dmFsdWUxLnZhbHVlID0gaWR4X2QxNnZhbHVlMi52YWx1ZSA9IHNldHVwYmluLnJlY29yZHNbaV0udmFyaWFibGVzW2pdLnZhbHVlOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgaGFsdEV2ZW50KGUpOw0KICAgICAgICAgICAgc2V0RGlhbG9nTW9kZSgxNiwgIkVkaXQgUmVjb3JkICMiICsgKGkgKyAxKSArICIsIFZhcmlhYmxlICMiICsgKGogKyAxKSwgNywgdXNiX2VkaXR2YXJpYWJsZW9rKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9lZGl0dmFyaWFibGVvayhyKSB7DQogICAgICAgICAgICBpZiAociA9PSAxKSB7IC8vIE9LDQogICAgICAgICAgICAgICAgdmFyIGlkcyA9IGQxNnR5cGUudmFsdWUuc3BsaXQoJy0nKTsNCiAgICAgICAgICAgICAgICB2YXIgbW9kaWQgPSAraWRzWzBdOw0KICAgICAgICAgICAgICAgIHZhciB2YXJpZCA9ICtpZHNbMV07DQogICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gIiI7DQogICAgICAgICAgICAgICAgdmFyIHZhcmRlc2NyaXB0aW9uID0gQW10U2V0dXBCaW5WYXJJZHNbbW9kaWRdW3ZhcmlkXTsNCiAgICAgICAgICAgICAgICBpZiAobW9kaWQgPT0gMiAmJiB2YXJpZCA9PSA4KSB7DQogICAgICAgICAgICAgICAgICAgIHZhbHVlID0gU3RyaW5nLmZyb21DaGFyQ29kZShRKCdpZHhfZDE2dmFsYzEnKS52YWx1ZSkgKyBoZXgycnN0cihRKCdpZHhfZDE2dmFsYzInKS52YWx1ZSkgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKFEoJ2lkeF9kMTZ2YWxjMycpLnZhbHVlLmxlbmd0aCkgKyBRKCdpZHhfZDE2dmFsYzMnKS52YWx1ZTsNCiAgICAgICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgICAgICBpZiAodmFyZGVzY3JpcHRpb25bMl0pIHsgdmFsdWUgPSBpZHhfZDE2dmFsdWUxLnZhbHVlOyB9IGVsc2UgeyB2YWx1ZSA9IGlkeF9kMTZ2YWx1ZTIudmFsdWU7IH0NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICAgICAgc2V0dXBiaW4ucmVjb3Jkc1tzZWxlY3RlZFJlY29yZF0udmFyaWFibGVzW3NlbGVjdGVkVmFyaWFibGVdLnZhbHVlID0gdmFsdWU7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBpZiAociA9PSAyKSB7IHNldHVwYmluLnJlY29yZHNbc2VsZWN0ZWRSZWNvcmRdLnZhcmlhYmxlcy5zcGxpY2Uoc2VsZWN0ZWRWYXJpYWJsZSwgMSk7IH0gLy8gRGVsZXRlDQogICAgICAgICAgICB1c2JfZGlzcGxheVNldHVwQmluKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2JfYWRkdmFyaWFibGUoZSwgaSkgew0KICAgICAgICAgICAgaWYgKHh4ZGlhbG9nTW9kZSkgcmV0dXJuOw0KICAgICAgICAgICAgc2VsZWN0ZWRSZWNvcmQgPSBpOw0KICAgICAgICAgICAgZDE2dHlwZS52YWx1ZSA9ICIxLTEiOw0KICAgICAgICAgICAgZDE2dHlwZS5kaXNhYmxlZCA9IGZhbHNlOw0KICAgICAgICAgICAgaWR4X2QxNnZhbHVlMS52YWx1ZSA9IGlkeF9kMTZ2YWx1ZTIudmFsdWUgPSAiIjsNCiAgICAgICAgICAgIHVzYl9vbmQxNnR5cGVjaGFuZ2UoKTsNCiAgICAgICAgICAgIGhhbHRFdmVudChlKTsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoMTYsICJBZGQgVmFyaWFibGUgdG8gUmVjb3JkICMiICsgKGkgKyAxKSwgMywgdXNiX2FkZHZhcmlhYmxlb2spOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2FkZHZhcmlhYmxlb2soKSB7DQogICAgICAgICAgICB2YXIgaWRzID0gZDE2dHlwZS52YWx1ZS5zcGxpdCgnLScpOw0KICAgICAgICAgICAgdmFyIG1vZGlkID0gK2lkc1swXTsNCiAgICAgICAgICAgIHZhciB2YXJpZCA9ICtpZHNbMV07DQogICAgICAgICAgICB2YXIgdmFsdWUgPSAiIjsNCiAgICAgICAgICAgIHZhciB2YXJkZXNjcmlwdGlvbiA9IEFtdFNldHVwQmluVmFySWRzW21vZGlkXVt2YXJpZF07DQogICAgICAgICAgICBpZiAobW9kaWQgPT0gMiAmJiB2YXJpZCA9PSA4KSB7DQogICAgICAgICAgICAgICAgdmFsdWUgPSBTdHJpbmcuZnJvbUNoYXJDb2RlKFEoJ2lkeF9kMTZ2YWxjMScpLnZhbHVlKSArIGhleDJyc3RyKFEoJ2lkeF9kMTZ2YWxjMicpLnZhbHVlKSArIFN0cmluZy5mcm9tQ2hhckNvZGUoUSgnaWR4X2QxNnZhbGMzJykudmFsdWUubGVuZ3RoKSArIFEoJ2lkeF9kMTZ2YWxjMycpLnZhbHVlOw0KICAgICAgICAgICAgfSBlbHNlIHsNCiAgICAgICAgICAgICAgICBpZiAodmFyZGVzY3JpcHRpb25bMl0pIHsgdmFsdWUgPSBpZHhfZDE2dmFsdWUxLnZhbHVlOyB9IGVsc2UgeyB2YWx1ZSA9IGlkeF9kMTZ2YWx1ZTIudmFsdWU7IH0NCiAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IHZhcmlhYmxlDQogICAgICAgICAgICB2YXIgdiA9IHt9Ow0KICAgICAgICAgICAgdi5tb2R1bGVpZCA9IG1vZGlkOw0KICAgICAgICAgICAgdi52YXJpZCA9IHZhcmlkOw0KICAgICAgICAgICAgdi5sZW5ndGggPSAtMTsNCiAgICAgICAgICAgIHYudHlwZSA9IEFtdFNldHVwQmluVmFySWRzW21vZGlkXVt2YXJpZF1bMF07DQogICAgICAgICAgICB2LmRlc2MgPSBBbXRTZXR1cEJpblZhcklkc1ttb2RpZF1bdmFyaWRdWzFdOw0KICAgICAgICAgICAgdi52YWx1ZSA9IHZhbHVlOw0KICAgICAgICAgICAgc2V0dXBiaW4ucmVjb3Jkc1tzZWxlY3RlZFJlY29yZF0udmFyaWFibGVzLnB1c2godik7DQoNCiAgICAgICAgICAgIHNldHVwYmluLnJlY29yZHNbc2VsZWN0ZWRSZWNvcmRdLnZhcmlhYmxlcy5zb3J0KEFtdFNldHVwQmluVmFyaWFibGVDb21wYXJlKTsgLy8gU29ydCB0aGUgdmFyaWFibGVzDQogICAgICAgICAgICB1c2JfZGlzcGxheVNldHVwQmluKCk7DQogICAgICAgIH0NCg0KICAgICAgICBmdW5jdGlvbiB1c2Jfb25kMTZ0eXBlY2hhbmdlKCkgew0KICAgICAgICAgICAgdmFyIGlkcyA9IGQxNnR5cGUudmFsdWUuc3BsaXQoJy0nKTsNCiAgICAgICAgICAgIHZhciBtb2RpZCA9ICtpZHNbMF07DQogICAgICAgICAgICB2YXIgdmFyaWQgPSAraWRzWzFdOw0KICAgICAgICAgICAgdmFyIHZhcmRlc2NyaXB0aW9uID0gQW10U2V0dXBCaW5WYXJJZHNbbW9kaWRdW3ZhcmlkXTsNCiAgICAgICAgICAgIFFWKCdkMTZnZW5lcmljdmFsdWUnLCBmYWxzZSk7DQogICAgICAgICAgICBRVignZDE2Y3VzdG9tdmFsdWUnLCBmYWxzZSk7DQogICAgICAgICAgICBpZiAobW9kaWQgPT0gMiAmJiB2YXJpZCA9PSA4KSB7DQogICAgICAgICAgICAgICAgdmFyIHggPSAnPGRpdiBzdHlsZT1oZWlnaHQ6MjZweD48c2VsZWN0IGlkPWlkeF9kMTZ2YWxjMSBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjBweCBvbmNoYW5nZT11c2Jfb25kMTZjaGVja2hhc2goKT48b3B0aW9uIHZhbHVlPTE+U0hBMTwvb3B0aW9uPic7DQogICAgICAgICAgICAgICAgaWYgKHNldHVwYmluLm1ham9yVmVyc2lvbiA+PSAzKSB7IHggKz0gJzxvcHRpb24gdmFsdWU9Mj5TSEEyNTY8L29wdGlvbj48b3B0aW9uIHZhbHVlPTM+U0hBMzg0PC9vcHRpb24+JzsgfQ0KICAgICAgICAgICAgICAgIHggKz0gJzwvc2VsZWN0PjxkaXY+SGFzaCBUeXBlPC9kaXY+PC9kaXY+JzsNCiAgICAgICAgICAgICAgICB4ICs9ICc8ZGl2IHN0eWxlPWhlaWdodDoyNnB4PjxpbnB1dCBpZD1pZHhfZDE2dmFsYzIgc3R5bGU9ZmxvYXQ6cmlnaHQ7d2lkdGg6MjYwcHggb25rZXl1cD11c2Jfb25kMTZjaGVja2hhc2goKT48ZGl2Pkhhc2ggKEhFWCk8L2Rpdj48L2Rpdj4nOw0KICAgICAgICAgICAgICAgIHggKz0gJzxkaXYgc3R5bGU9aGVpZ2h0OjI2cHg+PGlucHV0IGlkPWlkeF9kMTZ2YWxjMyBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyNjBweCBvbmtleXVwPXVzYl9vbmQxNmNoZWNraGFzaCgpIG1heGxlbmd0aD0zMT48ZGl2Pkhhc2ggTmFtZTwvZGl2PjwvZGl2Pic7DQogICAgICAgICAgICAgICAgUVYoJ2QxNmN1c3RvbXZhbHVlJywgdHJ1ZSk7DQogICAgICAgICAgICAgICAgUUgoJ2QxNmN1c3RvbXZhbHVlJywgeCk7DQogICAgICAgICAgICAgICAgdXNiX29uZDE2Y2hlY2toYXNoKCk7DQogICAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgICAgIFFWKCdkMTZnZW5lcmljdmFsdWUnLCB0cnVlKTsNCiAgICAgICAgICAgICAgICBpZiAodmFyZGVzY3JpcHRpb25bMl0pIHsNCiAgICAgICAgICAgICAgICAgICAgUVYoJ2lkeF9kMTZ2YWx1ZTEnLCB0cnVlKTsNCiAgICAgICAgICAgICAgICAgICAgUVYoJ2lkeF9kMTZ2YWx1ZTInLCBmYWxzZSk7DQogICAgICAgICAgICAgICAgICAgIHZhciBvcHRpb25zID0gIiI7DQogICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gdmFyZGVzY3JpcHRpb25bMl0pIHsgb3B0aW9ucyArPSAnPG9wdGlvbiB2YWx1ZT0iJyArIGkgKyAnIj4nICsgdmFyZGVzY3JpcHRpb25bMl1baV0gfQ0KICAgICAgICAgICAgICAgICAgICBRSCgnaWR4X2QxNnZhbHVlMScsIG9wdGlvbnMpOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICAgIFFWKCdpZHhfZDE2dmFsdWUxJywgZmFsc2UpOw0KICAgICAgICAgICAgICAgICAgICBRVignaWR4X2QxNnZhbHVlMicsIHRydWUpOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9vbmQxNmNoZWNraGFzaCgpIHsNCiAgICAgICAgICAgIHZhciBoYXNodHlwZSA9IFEoJ2lkeF9kMTZ2YWxjMScpLnZhbHVlOw0KICAgICAgICAgICAgdmFyIGhhc2hsZW4gPSBoZXgycnN0cihRKCdpZHhfZDE2dmFsYzInKS52YWx1ZSkubGVuZ3RoOw0KICAgICAgICAgICAgUUUoJ2lkeF9kbGdPa0J1dHRvbicsIChRKCdpZHhfZDE2dmFsYzMnKS52YWx1ZS5sZW5ndGggPiAwKSAmJiAoKGhhc2h0eXBlID09IDEpICYmIChoYXNobGVuID09IDIwKSkgfHwgKChoYXNodHlwZSA9PSAyKSAmJiAoaGFzaGxlbiA9PSAzMikpIHx8ICgoaGFzaHR5cGUgPT0gMykgJiYgKGhhc2hsZW4gPT0gNDgpKSk7DQogICAgICAgIH0NCg0KICAgICAgICB2YXIgdXNiX2FscGhhYmV0ID0gIjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWiI7DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2NvbXB1dGVDaGVja3N1bShzKSB7DQogICAgICAgICAgICB2YXIgQSA9IDA7DQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHMubGVuZ3RoOyBpKyspIEEgKz0gcy5jaGFyQ29kZUF0KGkpOw0KICAgICAgICAgICAgcmV0dXJuIHVzYl9hbHBoYWJldFtBICUgMzZdOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gdXNiX2dlbmVyYXRlUmFuZG9tUGlkKCkgew0KICAgICAgICAgICAgdmFyIHBpZCA9ICIiOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA3OyBpKyspIHsgcGlkICs9IHVzYl9hbHBoYWJldFtyYW5kb20oMzYpXTsgfQ0KICAgICAgICAgICAgcmV0dXJuIHBpZCArIHVzYl9jb21wdXRlQ2hlY2tzdW0ocGlkKTsNCiAgICAgICAgfQ0KDQogICAgICAgIGZ1bmN0aW9uIHVzYl9nZW5lcmF0ZVJhbmRvbVBwcygpDQogICAgICAgIHsNCiAgICAgICAgICAgIHZhciBwcHMgPSAiIiwgczsNCiAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgODsgaisrKQ0KICAgICAgICAgICAgew0KICAgICAgICAgICAgICAgIHMgPSAiIjsNCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDM7IGkrKykgcyArPSB1c2JfYWxwaGFiZXRbcmFuZG9tKDM2KV07DQogICAgICAgICAgICAgICAgcHBzICs9IHMgKyB1c2JfY29tcHV0ZUNoZWNrc3VtKHMpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIHBwczsNCiAgICAgICAgfQ0KDQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gUE9QVVAgRElBTE9HDQogICAgICAgIC8vDQoNCiAgICAgICAgLy8gdW5kZWZpbmVkID0gSGlkZGVuLCAxID0gR2VuZXJpYyBNZXNzYWdlDQogICAgICAgIHZhciB4eGRpYWxvZ01vZGU7DQogICAgICAgIHZhciB4eGRpYWxvZ0Z1bmM7DQogICAgICAgIHZhciB4eGRpYWxvZ0J1dHRvbnM7DQogICAgICAgIHZhciB4eGRpYWxvZ1RhZzsNCg0KICAgICAgICAvLyBEaXNwbGF5IGEgZGlhbG9nIGJveA0KICAgICAgICAvLyBQYXJhbWV0ZXJzOiBEaWFsb2cgTW9kZSAoMCA9IG5vbmUpLCBEaWFsb2cgVGl0bGUsIEJ1dHRvbnMgKDEgPSBPSywgMiA9IENhbmNlbCwgMyA9IE9LICYgQ2FuY2VsKSwgQ2FsbCBiYWNrIGZ1bmN0aW9uKDAgPSBDYW5jZWwsIDEgPSBPSyksIERpYWxvZyBDb250ZW50IChNb2RlIDExIG9ubHkpDQogICAgICAgIGZ1bmN0aW9uIHNldERpYWxvZ01vZGUoeCwgeSwgYiwgZiwgYywgdGFnKSB7DQogICAgICAgICAgICB4eGRpYWxvZ01vZGUgPSB4Ow0KICAgICAgICAgICAgeHhkaWFsb2dGdW5jID0gZjsNCiAgICAgICAgICAgIHh4ZGlhbG9nQnV0dG9ucyA9IGI7DQogICAgICAgICAgICB4eGRpYWxvZ1RhZyA9IHRhZzsNCiAgICAgICAgICAgIFFFKCdpZHhfZGxnT2tCdXR0b24nLCB0cnVlKTsNCiAgICAgICAgICAgIFFWKCdpZHhfZGxnT2tCdXR0b24nLCBiICYgMSk7DQogICAgICAgICAgICBRVignaWR4X2RsZ0NhbmNlbEJ1dHRvbicsIGIgJiAyKTsNCiAgICAgICAgICAgIFFWKCdpZF9kaWFsb2djbG9zZScsIGIgJiAyKTsNCiAgICAgICAgICAgIFFWKCdpZHhfZGxnRGVsZXRlQnV0dG9uJywgYiAmIDQpOw0KICAgICAgICAgICAgaWYgKHkpIFFIKCdpZF9kaWFsb2d0aXRsZScsIHkpOw0KICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCAyNjsgaSsrKSB7IFFWKCdkaWFsb2cnICsgaSwgaSA9PSB4KTsgfSAvLyBFZGl0IHRoaXMgbGluZSB3aGVuIG1vcmUgZGlhbG9ncyBhcmUgYWRkZWQNCiAgICAgICAgICAgIFFWKCdkaWFsb2cnLCB4KTsNCiAgICAgICAgICAgIGlmIChjKSB7IGlmICh4ID09IDExKSB7IFFIKCdpZF9kaWFsb2dPcHRpb25zJywgYyk7IH0gZWxzZSB7IFFIKCdpZF9kaWFsb2dNZXNzYWdlJywgYyk7IH0gfQ0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZGlhbG9nY2xvc2UoeCkgew0KICAgICAgICAgICAgdmFyIGYgPSB4eGRpYWxvZ0Z1bmMsIGIgPSB4eGRpYWxvZ0J1dHRvbnMsIHQgPSB4eGRpYWxvZ1RhZzsNCiAgICAgICAgICAgIHNldERpYWxvZ01vZGUoKTsNCiAgICAgICAgICAgIGlmICgoKGIgJiA4KSB8fCB4KSAmJiBmKSBmKHgsIHQpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gY2VudGVyKCkgew0KICAgICAgICAgICAgUVMoJ2RpYWxvZycpLmxlZnQgPSAoKCgoZ2V0RG9jV2lkdGgoKSAtIDQwMCkgLyAyKSkgKyAicHgiKTsNCg0KICAgICAgICAgICAgLy9RUygnaWRfbWFpbmFyZWFfZnJhbWUnKS5oZWlnaHQgPSBRKCdpZF9tYWluYXJlYScpLm9mZnNldEhlaWdodDsNCiAgICAgICAgfQ0KICAgICAgICBmdW5jdGlvbiBtZXNzYWdlYm94KHQsIG0pIHsgUUgoJ2lkX2RpYWxvZ01lc3NhZ2UnLCBtKTsgc2V0RGlhbG9nTW9kZSgxLCB0LCAxKTsgfQ0KICAgICAgICBmdW5jdGlvbiBzdGF0dXNib3godCwgbSkgeyBRSCgnaWRfZGlhbG9nTWVzc2FnZScsIG0pOyBzZXREaWFsb2dNb2RlKDEsIHQpOyB9DQoNCiAgICAgICAgLy8NCiAgICAgICAgLy8gR0VORVJJQyBNRVRIT0RTDQogICAgICAgIC8vDQoNCg0KICAgICAgICBmdW5jdGlvbiBTYXZlSnNvbkZpbGUobmFtZSwgbmFtZTIsIGRlc2MsIGRhdGEpIHsNCiAgICAgICAgICAgIHZhciBuID0gJycsIHIgPSB7fSwgZCA9IG5ldyBEYXRlKCk7DQogICAgICAgICAgICBpZiAoYW10c3lzc3RhdGUpIHsNCiAgICAgICAgICAgICAgICBuID0gIi0iICsgYW10c3lzc3RhdGVbJ0FNVF9HZW5lcmFsU2V0dGluZ3MnXS5yZXNwb25zZVsnSG9zdE5hbWUnXTsNCiAgICAgICAgICAgICAgICByID0geyd3ZWJhcHB2ZXJzaW9uJzp2ZXJzaW9uLCdkZXNjcmlwdGlvbic6ZGVzYywnaG9zdG5hbWUnOmFtdHN5c3N0YXRlWydBTVRfR2VuZXJhbFNldHRpbmdzJ10ucmVzcG9uc2VbJ0hvc3ROYW1lJ10sJ2xvY2FsdGltZSc6RGF0ZSgpLCd1dGN0aW1lJzpuZXcgRGF0ZSgpLnRvVVRDU3RyaW5nKCksJ2lzb3RpbWUnOm5ldyBEYXRlKCkudG9JU09TdHJpbmcoKX07DQogICAgICAgICAgICAgICAgaWYgKEhhcmR3YXJlSW52ZW50b3J5KSByWydzeXN0ZW1pZCddID0gZ3VpZFRvU3RyKEhhcmR3YXJlSW52ZW50b3J5WydDSU1fQ29tcHV0ZXJTeXN0ZW1QYWNrYWdlJ10ucmVzcG9uc2VbIlBsYXRmb3JtR1VJRCJdLnRvTG93ZXJDYXNlKCkpOw0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgbiArPSAnLScgKyBkLmdldEZ1bGxZZWFyKCkgKyAiLSIgKyAoIjAiKyhkLmdldE1vbnRoKCkrMSkpLnNsaWNlKC0yKSArICItIiArICgiMCIgKyBkLmdldERhdGUoKSkuc2xpY2UoLTIpICsgIi0iICsgKCIwIiArIGQuZ2V0SG91cnMoKSkuc2xpY2UoLTIpICsgIi0iICsgKCIwIiArIGQuZ2V0TWludXRlcygpKS5zbGljZSgtMik7Ow0KICAgICAgICAgICAgcltuYW1lMl0gPSBkYXRhOw0KDQogICAgICAgICAgICBzYXZlQXMoZGF0YTJibG9iKEpTT04uc3RyaW5naWZ5KHIsIG51bGwsICcgICcpLnJlcGxhY2UoL1xuL2csICdcclxuJykpLCBuYW1lICsgbiArICcuanNvbicpOw0KICAgICAgICB9DQoNCiAgICAgICAgdmFyIGh0dHBFcnJvclRhYmxlID0gew0KICAgICAgICAgICAgMjAwOiAnT0snLA0KICAgICAgICAgICAgNDAxOiAnQXV0aGVudGljYXRpb24gRXJyb3InLA0KICAgICAgICAgICAgNDA4OiAnVGltZW91dCBFcnJvcicsDQogICAgICAgICAgICA2MDE6ICdXU01BTiBQYXJzaW5nIEVycm9yJywNCiAgICAgICAgICAgIDYwMjogJ1VuYWJsZSB0byBwYXJzZSBIVFRQIHJlc3BvbnNlIGhlYWRlcicsDQogICAgICAgICAgICA2MDM6ICdVbmV4cGVjdGVkIEhUVFAgZW51bSByZXNwb25zZScsDQogICAgICAgICAgICA2MDQ6ICdVbmV4cGVjdGVkIEhUVFAgcHVsbCByZXNwb25zZScsDQogICAgICAgIH0NCiAgICAgICAgZnVuY3Rpb24gZXJyY2hlY2socywgc3RhY2spIHsNCiAgICAgICAgICAgIGlmICh3c3N0YWNrID09IG51bGwgfHwgYW10c3RhY2sgIT0gc3RhY2spIHJldHVybiB0cnVlOw0KICAgICAgICAgICAgaWYgKHMgIT0gMjAwICYmIHMgIT0gOSkgew0KICAgICAgICAgICAgICAgIHNldERpYWxvZ01vZGUoKTsNCiAgICAgICAgICAgICAgICB3c3N0YWNrLmNvbW0uRmFpbEFsbEVycm9yID0gOTk5OyAvLyBDYXVzZSBhbGwgbmV3IHJlc3BvbnNlcyB0byBiZSBzaWxlbnQNCiAgICAgICAgICAgICAgICBhbXRzdGFjay5DYW5jZWxBbGxRdWVyaWVzKDk5OSk7DQogICAgICAgICAgICAgICAgUUgoJ2lkX21lc3NhZ2V2aWV3c3RyJywgKChodHRwRXJyb3JUYWJsZVtzXSk/KGh0dHBFcnJvclRhYmxlW3NdKTooJ0Vycm9yICMnICsgcykpKTsNCiAgICAgICAgICAgICAgICBnbygxMDApOw0KICAgICAgICAgICAgICAgIFFTKCdpZF9wcm9ncmVzc2JhcicpLndpZHRoID0gMDsNCg0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgcmV0dXJuIChzICE9IDIwMCk7DQogICAgICAgIH0NCg0KDQogICAgICAgIGZ1bmN0aW9uIGdvaUZyYW1lKGUseCx5KSB7DQogICAgICAgICAgICBpZiAoeHhkaWFsb2dNb2RlKSByZXR1cm47DQogICAgICAgICAgICBnbyh4KTsNCiAgICAgICAgICAgIGlmICgoZS5zaGlmdEtleSA9PSB0cnVlKSB8fCAoUSgnaWRfU3RvcmFnZUlGcmFtZScpLnNyYy5lbmRzV2l0aCh5KSA9PSBmYWxzZSkpIFEoJ2lkX1N0b3JhZ2VJRnJhbWUnKS5zcmMgPSB5Ow0KICAgICAgICAgICAgUVYoJ2lkX21haW5hcmVhX3BhZCcsIGZhbHNlKTsNCiAgICAgICAgICAgIFFWKCdpZF9tYWluYXJlYV9mcmFtZScsIHRydWUpOw0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gZ28oeCwgZm9yY2UpIHsNCiAgICAgICAgICAgIGlmICh4eGRpYWxvZ01vZGUgJiYgZm9yY2UgIT0gMSkgcmV0dXJuOw0KDQogICAgICAgICAgICBRVignaWRfbWFpbmFyZWFfZnJhbWUnLCBmYWxzZSk7DQogICAgICAgICAgICBRVignaWRfbWFpbmFyZWFfcGFkJywgdHJ1ZSk7DQoNCiAgICAgICAgICAgIFFWKCdpZF9sbXNNYWluUGFuZWwnLCB4ID09IDEwMSk7DQoNCiAgICAgICAgICAgIFFWKCdpZF91c2JTZXR1cFBhbmVsJywgeCA9PSAxMDIpOw0KICAgICAgICAgICAgUVYoJ2lkX21lc3NhZ2V2aWV3JywgeCA9PSAxMDApOw0KICAgICAgICAgICAgUVYoJ2lkX21haW52aWV3JywgeCA8IDEwMCk7DQogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDgwOyBpKyspIHsgLy8gRWRpdCB0aGlzIGxpbmUgd2hlbiBhZGRpbmcgYSBuZXcgc2NyZWVuDQogICAgICAgICAgICAgICAgUVYoJ3AnICsgaSwgaSA9PSB4KTsNCiAgICAgICAgICAgICAgICB2YXIgcSA9IFFTKCdnbycgKyBpKTsNCi8vICMjI0JFR0lOIyMje0xvb2stSW50ZWx9DQogICAgICAgICAgICAgICAgaWYgKHEpIHsgcVsnYmFja2dyb3VuZC1jb2xvciddID0gKChpID09IHgpPyIjYWJjYWUxIjoiIik7IH0gLy8gI2U4ZWVmZQ0KLy8gIyMjRU5EIyMje0xvb2stSW50ZWx9DQoNCiAgICAgICAgICAgICAgICBpZiAocSkgeyBxWydiYWNrZ3JvdW5kLWNvbG9yJ10gPSAoKGkgPT0geCk/ImdyYXkiOiIiKTsgfQ0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgY3VycmVudFZpZXcgPSB4Ow0KICAgICAgICB9DQoNCiAgICAgICAgZnVuY3Rpb24gcG9ydHNGcm9tSG9zdChob3N0LCB0bHMpIHsgdmFyIHggPSBkZWNvZGVVUklDb21wb25lbnQoaG9zdCkuc3BsaXQoJzonKSwgaHAgPSAoKHRscyA9PSAwKSA/IDE2OTkyIDogMTY5OTMpLCBycCA9ICgodGxzID09IDApID8gMTY5OTQgOiAxNjk5NSk7IGlmICh4Lmxlbmd0aCA+IDEpIHsgaHAgPSBwYXJzZUludCh4WzFdKTsgfSBpZiAoeC5sZW5ndGggPiAyKSB7IHJwID0gcGFyc2VJbnQoeFsyXSk7IH0gcmV0dXJuIHsgaG9zdDogeFswXSwgaHR0cDogaHAsIHJlZGlyOiBycCB9IH0NCiAgICAgICAgZnVuY3Rpb24gYWRkTGluayh4LCBmKSB7IHJldHVybiAiPGEgc3R5bGU9Y3Vyc29yOnBvaW50ZXI7Y29sb3I6Ymx1ZSBvbmNsaWNrPSciICsgZiArICInPiZkaWFtczsgIiArIHggKyAiPC9hPiI7IH0NCiAgICAgICAgZnVuY3Rpb24gYWRkTGlua0NvbmRpdGlvbmFsKHgsIGYsIGMpIHsgaWYgKGMpIHJldHVybiBhZGRMaW5rKHgsIGYpOyByZXR1cm4geDsgfQ0KICAgICAgICBmdW5jdGlvbiBoYWx0RXZlbnQoZSkgeyBpZiAoZS5wcmV2ZW50RGVmYXVsdCkgZS5wcmV2ZW50RGVmYXVsdCgpOyBpZiAoZS5zdG9wUHJvcGFnYXRpb24pIGUuc3RvcFByb3BhZ2F0aW9uKCk7IHJldHVybiBmYWxzZTsgfQ0KICAgICAgICBmdW5jdGlvbiBhZGRPcHRpb24ocSwgdCwgaSkgeyB2YXIgb3B0aW9uID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgib3B0aW9uIik7IG9wdGlvbi50ZXh0ID0gdDsgb3B0aW9uLnZhbHVlID0gaTsgUShxKS5hZGQob3B0aW9uKTsgfQ0KICAgICAgICBmdW5jdGlvbiBhZGREaXNhYmxlZE9wdGlvbihxLCB0LCBpKSB7IHZhciBvcHRpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJvcHRpb24iKTsgb3B0aW9uLnRleHQgPSB0OyBvcHRpb24udmFsdWUgPSBpOyBvcHRpb24uZGlzYWJsZWQgPSAxOyBRKHEpLmFkZChvcHRpb24pOyB9DQogICAgICAgIGZ1bmN0aW9uIHBhc3N3b3JkY2hlY2socCkgeyBpZiAocC5sZW5ndGggPCA4KSByZXR1cm4gZmFsc2U7IHZhciB1cHBlciA9IDAsIGxvd2VyID0gMCwgbnVtYmVyID0gMCwgbm9uYWxwaGEgPSAwOyBmb3IgKHZhciBpIGluIHApIHsgdmFyIGMgPSBwLmNoYXJDb2RlQXQoaSk7IGlmICgoYyA+IDY0KSAmJiAoYyA8IDkxKSkgeyB1cHBlciA9IDE7IH0gZWxzZSBpZiAoKGMgPiA5NikgJiYgKGMgPCAxMjMpKSB7IGxvd2VyID0gMTsgfSBlbHNlIGlmICgoYyA+IDQ3KSAmJiAoYyA8IDU4KSkgeyBudW1iZXIgPSAxOyB9IGVsc2UgeyBub25hbHBoYSA9IDE7IH0gfSByZXR1cm4gKCh1cHBlciArIGxvd2VyICsgbnVtYmVyICsgbm9uYWxwaGEpID09IDQpOyB9DQogICAgICAgIGZ1bmN0aW9uIG1ldGhvZGNoZWNrKHIpIHsgaWYgKHIgJiYgciAhPSBudWxsICYmIHIuQm9keSAmJiByLkJvZHlbJ1JldHVyblZhbHVlJ10gIT0gMCkgeyBtZXNzYWdlYm94KCJDYWxsIEVycm9yIiwgci5IZWFkZXJbJ01ldGhvZCddICsgIjogIiArIChyLkJvZHkuUmV0dXJuVmFsdWVTdHIgKyAnJykucmVwbGFjZSgiXyIsICIgIikpOyByZXR1cm4gdHJ1ZTsgfSByZXR1cm4gZmFsc2U7IH0NCiAgICAgICAgZnVuY3Rpb24gVGFibGVTdGFydCgpIHsgcmV0dXJuICI8dGFibGUgY2xhc3M9J2xvZzEgdXMnIGNlbGxwYWRkaW5nPTAgY2VsbHNwYWNpbmc9MCBzdHlsZT13aWR0aDoxMDAlO2JvcmRlci1yYWRpdXM6OHB4Pjx0cj48dGQgd2lkdGg9MjAwcHg+PHA+PHRkPiI7IH0NCiAgICAgICAgZnVuY3Rpb24gVGFibGVTdGFydDIoKSB7IHJldHVybiAiPHRhYmxlIGNsYXNzPSdsb2cxIHVzJyBjZWxscGFkZGluZz0wIGNlbGxzcGFjaW5nPTAgc3R5bGU9d2lkdGg6MTAwJTtib3JkZXItcmFkaXVzOjhweD48dHI+PHRkPjxwPjx0ZD4iOyB9DQogICAgICAgIGZ1bmN0aW9uIFRhYmxlRW50cnkobiwgdikgeyByZXR1cm4gIjx0cj48dGQgY2xhc3M9cjE+PHA+IiArIG4gKyAiPHRkIGNsYXNzPXIxPiIgKyB2OyB9DQogICAgICAgIGZ1bmN0aW9uIEZ1bGxUYWJsZSh4LCBlKSB7IHZhciByID0gVGFibGVTdGFydCgpOyBmb3IgKGkgaW4geCkgeyBpZiAoaSAmJiB4W2ldKSByICs9IFRhYmxlRW50cnkoaSwgeFtpXSk7IH0gcmV0dXJuIHIgKyBUYWJsZUVuZChlKTsgfQ0KICAgICAgICBmdW5jdGlvbiBUYWJsZUVuZChuKSB7IHJldHVybiAiPHRyPjx0ZCBjb2xzcGFuPTI+PHA+IiArIChuP246JycpICsgIjwvdGFibGU+IjsgfQ0KICAgICAgICBmdW5jdGlvbiBBZGRCdXR0b24odiwgZikgeyByZXR1cm4gIjxpbnB1dCB0eXBlPWJ1dHRvbiB2YWx1ZT0nIiArIHYgKyAiJyBvbmNsaWNrPSciICsgZiArICInIHN0eWxlPW1hcmdpbjo0cHg+IjsgfQ0KICAgICAgICBmdW5jdGlvbiBBZGRCdXR0b24yKHYsIGYsIHMpIHsgcmV0dXJuICI8aW5wdXQgdHlwZT1idXR0b24gdmFsdWU9JyIgKyB2ICsgIicgb25jbGljaz0nIiArIGYgKyAiJyAiICsgcyArICI+IjsgfQ0KICAgICAgICBmdW5jdGlvbiBBZGRSZWZyZXNoQnV0dG9uKGYpIHsgcmV0dXJuICI8aW5wdXQgdHlwZT1idXR0b24gbmFtZT1yZWZyZXNoYnRuIHZhbHVlPVJlZnJlc2ggb25jbGljaz0ncmVmcmVzaEJ1dHRvbnMoZmFsc2UpOyIgKyBmICsgIicgc3R5bGU9bWFyZ2luOjRweCAiICsgKHJlZnJlc2hCdXR0b25zU3RhdGU9PWZhbHNlPyJkaXNhYmxlZCI6IiIpICsgIj4iOyB9DQogICAgICAgIGZ1bmN0aW9uIE1vcmVTdGFydCgpIHsgcmV0dXJuICI8YSBzdHlsZT1jdXJzb3I6cG9pbnRlcjtjb2xvcjpibHVlIGlkPW1vcmV4eHgxIG9uY2xpY2s9UVYoXCJtb3JleHh4MVwiLGZhbHNlKTtRVihcIm1vcmV4eHgyXCIsdHJ1ZSk+JiN4MjVCQzsgTW9yZTwvYT48ZGl2IGlkPW1vcmV4eHgyIHN0eWxlPWRpc3BsYXk6bm9uZT48YnI+PGhyPiI7IH07DQogICAgICAgIGZ1bmN0aW9uIE1vcmVFbmQoKSB7IHJldHVybiAiPGEgc3R5bGU9Y3Vyc29yOnBvaW50ZXI7Y29sb3I6Ymx1ZSBvbmNsaWNrPVFWKFwibW9yZXh4eDJcIixmYWxzZSk7UVYoXCJtb3JleHh4MVwiLHRydWUpPiYjeDI1QjI7IExlc3M8L2E+PC9kaXY+IjsgfTsNCiAgICAgICAgZnVuY3Rpb24gZ2V0U2VsZWN0ZWRPcHRpb25zKHNlbCkgeyB2YXIgb3B0cyA9IFtdLCBvcHQ7IGZvciAodmFyIGkgPSAwLCBsZW4gPSBzZWwub3B0aW9ucy5sZW5ndGg7IGkgPCBsZW47IGkrKykgeyBvcHQgPSBzZWwub3B0aW9uc1tpXTsgaWYgKG9wdC5zZWxlY3RlZCkgeyBvcHRzLnB1c2gob3B0LnZhbHVlKTsgfSB9IHJldHVybiBvcHRzOyB9DQogICAgICAgIGZ1bmN0aW9uIGdldEluc3RhbmNlKHgsIHkpIHsgZm9yICh2YXIgaSBpbiB4KSB7IGlmICh4W2ldWyJJbnN0YW5jZUlEIl0gPT0geSkgcmV0dXJuIHhbaV07IH0gcmV0dXJuIG51bGw7IH0NCiAgICAgICAgZnVuY3Rpb24gZ2V0SXRlbSh4LCB5LCB6KSB7IGZvciAodmFyIGkgaW4geCkgeyBpZiAoeFtpXVt5XSA9PSB6KSByZXR1cm4geFtpXTsgfSByZXR1cm4gbnVsbDsgfQ0KICAgICAgICBmdW5jdGlvbiBndWlkVG9TdHIoZykgeyByZXR1cm4gZy5zdWJzdHJpbmcoNiwgOCkgKyBnLnN1YnN0cmluZyg0LCA2KSArIGcuc3Vic3RyaW5nKDIsIDQpICsgZy5zdWJzdHJpbmcoMCwgMikgKyAiLSIgKyBnLnN1YnN0cmluZygxMCwgMTIpICsgZy5zdWJzdHJpbmcoOCwgMTApICsgIi0iICsgZy5zdWJzdHJpbmcoMTQsIDE2KSArIGcuc3Vic3RyaW5nKDEyLCAxNCkgKyAiLSIgKyBnLnN1YnN0cmluZygxNiwgMjApICsgIi0iICsgZy5zdWJzdHJpbmcoMjApOyB9DQogICAgICAgIGZ1bmN0aW9uIGdldFVybFZhcnMoKSB7IHZhciBqLCBoYXNoLCB2YXJzID0gW10sIGhhc2hlcyA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNsaWNlKHdpbmRvdy5sb2NhdGlvbi5ocmVmLmluZGV4T2YoJz8nKSArIDEpLnNwbGl0KCcmJyk7IGZvciAodmFyIGkgPSAwOyBpIDwgaGFzaGVzLmxlbmd0aDsgaSsrKSB7IGogPSBoYXNoZXNbaV0uaW5kZXhPZignPScpOyBpZiAoaiA+IDApIHsgdmFyc1toYXNoZXNbaV0uc3Vic3RyaW5nKDAsIGopXSA9IGhhc2hlc1tpXS5zdWJzdHJpbmcoaiArIDEsIGhhc2hlc1tpXS5sZW5ndGgpOyB9IH0gcmV0dXJuIHZhcnM7IH0NCiAgICAgICAgZnVuY3Rpb24gZ2V0RG9jV2lkdGgoKSB7IGlmICh3aW5kb3cuaW5uZXJXaWR0aCkgcmV0dXJuIHdpbmRvdy5pbm5lcldpZHRoOyBpZiAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aCAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGggIT0gMCkgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aDsgcmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdib2R5JylbMF0uY2xpZW50V2lkdGg7IH0NCiAgICAgICAgZnVuY3Rpb24gZ2V0RG9jSGVpZ2h0KCkgeyBpZiAod2luZG93LmlubmVySGVpZ2h0KSByZXR1cm4gd2luZG93LmlubmVySGVpZ2h0OyBpZiAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICYmIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCAhPSAwKSByZXR1cm4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodDsgcmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdib2R5JylbMF0uY2xpZW50SGVpZ2h0OyB9DQogICAgICAgIGZ1bmN0aW9uIGFkZEh0bWxWYWx1ZSh0LCB2KSB7IHJldHVybiAnPGRpdiBzdHlsZT1oZWlnaHQ6MjBweD48ZGl2IHN0eWxlPWZsb2F0OnJpZ2h0O3dpZHRoOjIyMHB4O292ZXJmbG93OmhpZGRlbj48YiB0aXRsZT0iJyArIHYgKyAnIj4nICsgdiArICc8L2I+PC9kaXY+PGRpdj4nICsgdCArICc8L2Rpdj48L2Rpdj4nOyB9DQogICAgICAgIGZ1bmN0aW9uIGFkZEh0bWxWYWx1ZU5vVGl0bGUodCwgdikgeyByZXR1cm4gJzxkaXYgc3R5bGU9aGVpZ2h0OjIwcHg+PGRpdiBzdHlsZT1mbG9hdDpyaWdodDt3aWR0aDoyMjBweDtvdmVyZmxvdzpoaWRkZW4+JyArIHYgKyAnPC9iPjwvZGl2PjxkaXY+JyArIHQgKyAnPC9kaXY+PC9kaXY+JzsgfQ0KICAgICAgICBmdW5jdGlvbiBudW1iZXJzT25seShlLCB4KSB7IHJldHVybiAoZXZlbnQuY2hhckNvZGUgPT0gMCkgfHwgKGV2ZW50LmNoYXJDb2RlID09IHgpIHx8IChldmVudC5jaGFyQ29kZSA+PSA0OCAmJiBldmVudC5jaGFyQ29kZSA8PSA1Nyk7IH0NCg0KDQogICAgICAgIC8vIEdldCB0aGluZ3Mgc3RhcnRlZA0KICAgICAgICBzdGFydHVwKCk7DQogICAgPC9zY3JpcHQ+";amtLms.meshCommander=http.createServer();amtLms.meshCommander.listen(16994);amtLms.meshCommander.on("upgrade",function(f,g,c){switch(f.url.split("?")[0]){case"/lms.ashx":g.ws=g.upgradeWebSocket();g.ws.on("data",processLmsControlData);g.ws.on("end",function(){if(lmsControlSockets[this.id]){delete lmsControlSockets[this.id]}});var d=lmsControlSocketsNextId++;lmsControlSockets[d]=g.ws;g.ws.id=d;break;case"/webrelay.ashx":g.ws=g.upgradeWebSocket();if(amtLms.connected==true){amtLms.bindDuplexStream(g.ws,"IPv4",16992)}else{var e=require("net");g.relay=e.connect({host:"127.0.0.1",port:16992});g.relay.on("connect",function(){g.ws.on("data",function(h){g.relay.write(h)});g.ws.on("end",function(){g.relay.end()})});g.relay.on("data",function(h){g.ws.write(h)});g.relay.on("close",function(){g.ws.end()})}break;default:g.end();break}});amtLms.meshCommander.on("request",function(f,g){switch(f.url.split("?")[0]){case"/":var d=null;try{d=fs.readFileSync("lmscommander.htm")}catch(c){}if(d!=null){g.writeHead(200,"OK",{Server:"JSLMS","Cache-Control":"max-age=0, no-cache","X-Frame-Options":"DENY","Content-Type":"text/html","Transfer-Encoding":"chunked"});g.end(d)}else{g.writeHead(200,"OK",{Server:"JSLMS","Cache-Control":"max-age=0, no-cache","X-Frame-Options":"DENY","Content-Type":"text/html","Content-Encoding":"gzip","Transfer-Encoding":"chunked",ETag:b});g.end(Buffer.from(a,"base64"))}break;default:g.statusCode=404;g.statusMessage="Not Found";g.end();break}})}function setupMeiOsAdmin(a,b){if(amtMei==null){if(a){a(b)}}else{amtMei.getLocalSystemAccount(function(f){var d=require("amt-wsman-duk");var e=require("amt-wsman");var c=require("amt");oswsstack=new e(d,"127.0.0.1",16992,f.user,f.pass,false);osamtstack=new c(oswsstack);if(a){a(b)}amtMei.getVersion(function(k){var g=null;try{for(var j in k.Versions){if(k.Versions[j].Description=="AMT"){g=parseInt(k.Versions[j].Version.split(".")[0])}}}catch(h){}if((g!=null)&&(g>=12)){kvmGetData("skip");tempTimer=setInterval(function(){kvmGetData()},2000);kvmSetData(JSON.stringify({action:"restart",ver:1}))}})})}}function kvmGetData(a){osamtstack.IPS_KVMRedirectionSettingData_DataChannelRead(kvmDataGetResponse,a)}function kvmDataGetResponse(d,b,c,f,g){if((g!="skip")&&(f==200)&&(c.Body.ReturnValue==0)){var h=null;try{h=Buffer.from(c.Body.DataMessage,"base64").toString()}catch(a){return}if(h!=null){kvmProcessData(c.Body.RealmsBitmap,c.Body.MessageId,h)}}}var webRtcDesktop=null;function kvmProcessData(d,c,g){var a=null;try{a=JSON.parse(g)}catch(b){}if((a!=null)&&(a.action)){if(a.action=="present"){kvmSetData(JSON.stringify({action:"present",ver:1,platform:process.platform}))}if(a.action=="offer"){webRtcDesktop={};var f=require("ILibWebRTC");webRtcDesktop.webrtc=f.createConnection();webRtcDesktop.webrtc.on("connected",function(){});webRtcDesktop.webrtc.on("disconnected",function(){webRtcCleanUp()});webRtcDesktop.webrtc.on("dataChannel",function(h){webRtcDesktop.rtcchannel=h;var e=require("meshDesktop");webRtcDesktop.kvm=e.getRemoteDesktopStream();webRtcDesktop.kvm.pipe(webRtcDesktop.rtcchannel,{dataTypeSkip:1,end:false});webRtcDesktop.rtcchannel.on("end",function(){webRtcCleanUp()});webRtcDesktop.rtcchannel.on("data",function(j){kvmCtrlData(this,j)});webRtcDesktop.rtcchannel.pipe(webRtcDesktop.kvm,{dataTypeSkip:1,end:false})});kvmSetData(JSON.stringify({action:"answer",ver:1,sdp:webRtcDesktop.webrtc.setOffer(a.sdp)}))}}}var path={join:function(){var c=[];for(var a in arguments){var b=arguments[a];if(b!=null){while(b.endsWith("/")||b.endsWith("\\")){b=b.substring(0,b.length-1)}if(a!=0){while(b.startsWith("/")||b.startsWith("\\")){b=b.substring(1)}}c.push(b)}}if(c.length==0){return"/"}return c.join("/")}};function getDirectoryInfo(f){var g={path:f,dir:[]};if(((f==undefined)||(f==""))&&(process.platform=="win32")){var h=null;try{h=fs.readDrivesSync()}catch(b){}if(h!=null){for(var c=0;c0&&c.charCodeAt(0)!=123){if(this.fileupload!=null){c=Buffer.from(c,"base64");var k=c.readUInt32BE(0);if((k==16777216)||(k==16777217)){fs.writeSync(this.fileupload.fp,c.slice(4));b.write({action:"upload",sub:"ack",reqid:this.fileupload.reqid});if(k==16777217){fs.closeSync(this.fileupload.fp);this.fileupload=null}}}return}try{c=JSON.parse(c)}catch(g){console.error("Invalid JSON: "+c);return}if((c.path!=null)&&(process.platform!="win32")&&(c.path[0]!="/")){c.path="/"+c.path}switch(c.action){case"ping":b.write({action:"pong"});break;case"ls":var p=getDirectoryInfo(c.path);if(c.reqid!=undefined){p.reqid=c.reqid}b.write(p);break;case"mkdir":fs.mkdirSync(c.path);break;case"rm":for(var l in c.delfiles){var j=path.join(c.path,c.delfiles[l]);try{fs.unlinkSync(j)}catch(f){console.log(f)}}break;case"rename":var o=path.join(c.path,c.oldname);var n=path.join(c.path,c.newname);try{fs.renameSync(o,n)}catch(f){console.log(f)}break;case"download":var r=0;if(c.sub=="start"){if(this.filedownload!=null){b.write({action:"download",sub:"cancel",id:this.filedownload.id});delete this.filedownload}this.filedownload={id:c.id,path:c.path,ptr:0};try{this.filedownload.f=fs.openSync(this.filedownload.path,"rbN")}catch(f){b.write({action:"download",sub:"cancel",id:this.filedownload.id});delete this.filedownload}if(this.filedownload){b.write({action:"download",sub:"start",id:c.id})}}else{if((this.filedownload!=null)&&(c.id==this.filedownload.id)){if(c.sub=="startack"){r=8}else{if(c.sub=="stop"){delete this.filedownload}else{if(c.sub=="ack"){r=1}}}}}while(r>0){r--;var a=Buffer.alloc(4096);var m=fs.readSync(this.filedownload.f,a,4,4092,null);this.filedownload.ptr+=m;if(m<4092){a.writeInt32BE(16777217,0);fs.closeSync(this.filedownload.f);delete this.filedownload;r=0}else{a.writeInt32BE(16777216,0)}b.write(a.slice(0,m+4).toString("base64"))}break;case"upload":if(c.sub=="start"){if(this.fileupload!=null){fs.closeSync(this.fileupload.fp)}if(!c.path||!c.name){break}this.fileupload={reqid:c.reqid};var h=path.join(c.path,c.name);try{this.fileupload.fp=fs.openSync(h,"wbN")}catch(f){}if(this.fileupload.fp){b.write({action:"upload",sub:"start",reqid:this.fileupload.reqid})}else{this.fileupload=null;b.write({action:"upload",sub:"error",reqid:this.fileupload.reqid})}}else{if(c.sub=="cancel"){if(this.fileupload!=null){fs.closeSync(this.fileupload.fp);this.fileupload=null}}}break;case"copy":for(var l in c.names){var q=path.join(c.scpath,c.names[l]),d=path.join(c.dspath,c.names[l]);if(q!=d){try{fs.copyFileSync(q,d)}catch(f){}}}break;case"move":for(var l in c.names){var q=path.join(c.scpath,c.names[l]),d=path.join(c.dspath,c.names[l]);if(q!=d){try{fs.copyFileSync(q,d);fs.unlinkSync(q)}catch(f){}}}break;default:break}}function webRtcCleanUp(){if(webRtcDesktop==null){return}if(webRtcDesktop.rtcchannel){try{webRtcDesktop.rtcchannel.close()}catch(a){}try{webRtcDesktop.rtcchannel.removeAllListeners("data")}catch(a){}try{webRtcDesktop.rtcchannel.removeAllListeners("end")}catch(a){}delete webRtcDesktop.rtcchannel}if(webRtcDesktop.webrtc){try{webRtcDesktop.webrtc.close()}catch(a){}try{webRtcDesktop.webrtc.removeAllListeners("connected")}catch(a){}try{webRtcDesktop.webrtc.removeAllListeners("disconnected")}catch(a){}try{webRtcDesktop.webrtc.removeAllListeners("dataChannel")}catch(a){}delete webRtcDesktop.webrtc}if(webRtcDesktop.kvm){try{webRtcDesktop.kvm.end()}catch(a){}delete webRtcDesktop.kvm}webRtcDesktop=null}function kvmSetData(a){osamtstack.IPS_KVMRedirectionSettingData_DataChannelWrite(Buffer.from(a).toString("base64"),function(){})}function startLmsWsmanResponse(d,b,c,e){if(e==600){console.log("ERROR: Unable to connect to Intel(R) AMT.")}else{if(e!=200){console.log("ERROR: Unable to get object from Intel(R) AMT, status = "+e+".")}else{var a=c.CIM_SoftwareIdentity.responses;if(a.length>0){var f=getInstance(a,"AMT")["VersionString"];amtversion=parseInt(f.split(".")[0]);amtversionmin=parseInt(f.split(".")[1])}}}}function processLmsControlData(b){if(b.length<2){return}var a=b.readUInt16LE(0);switch(a){case 1:getAmtInfo(function(c,d){c.LoginMode=2;d.write(Buffer.concat([Buffer.from("0100","hex"),Buffer.from(JSON.stringify(c))]))},this);break;case 2:if(b.length<6){break}amtMei.unprovision(b.readUInt32LE(2),function(e,d){var c=Buffer.alloc(6);c.writeUInt16LE(2,0);c.writeUInt32LE(e,2);d.write(c)},this);break;case 3:amtMei.getLocalSystemAccount(function(c,d){d.write(Buffer.concat([Buffer.from("030000000000","hex"),c.raw]))},this);break;case 4:amtMei.startConfiguration(function(e,d){var c=Buffer.alloc(6);c.writeUInt16LE(7,0);c.writeUInt32LE(e,2);d.write(c)},this);break;case 5:amtMei.stopConfiguration(function(e,d){var c=Buffer.alloc(6);c.writeUInt16LE(7,0);c.writeUInt32LE(e,2);d.write(c)},this);break;case 6:amtMei.openUserInitiatedConnection(function(e,d){var c=Buffer.alloc(6);c.writeUInt16LE(7,0);c.writeUInt32LE(e,2);d.write(c)},this);break;case 7:amtMei.closeUserInitiatedConnection(function(e,d){var c=Buffer.alloc(6);c.writeUInt16LE(7,0);c.writeUInt32LE(e,2);d.write(c)},this);break;case 8:amtMei.getRemoteAccessConnectionStatus(function(e,d){var c=Buffer.alloc(6);c.writeUInt16LE(8,0);c.writeUInt32LE(e.status,2);d.write(Buffer.concat([c,e.raw]))},this);break;default:break}}function startRouter(){tcpserver=net.createServer(OnTcpClientConnected);tcpserver.on("error",function(a){console.log("ERROR: "+JSON.stringify(a));exit(0);return});tcpserver.listen(settings.localport,function(){if(settings.remotename==null){console.log("Redirecting local port "+settings.localport+" to remote port "+settings.remoteport+".")}else{console.log("Redirecting local port "+settings.localport+" to "+settings.remotename+":"+settings.remoteport+".")}console.log("Press ctrl-c to exit.")})}function OnTcpClientConnected(a){try{debug(1,"Client connected");a.on("end",function(){disconnectTunnel(this,this.websocket,"Client closed")});a.pause();try{options=http.parseUri(settings.serverurl+"?user="+settings.username+"&pass="+settings.password+"&nodeid="+settings.remotenodeid+"&tcpport="+settings.remoteport)}catch(b){console.log('Unable to parse "serverUrl".');process.exit(1);return}options.checkServerIdentity=onVerifyServer;options.rejectUnauthorized=false;a.websocket=http.request(options);a.websocket.tcp=a;a.websocket.tunneling=false;a.websocket.upgrade=OnWebSocket;a.websocket.on("error",function(c){console.log("ERROR: "+JSON.stringify(c))});a.websocket.end()}catch(b){debug(2,b)}}function disconnectTunnel(c,d,b){if(d!=null){try{d.end()}catch(a){debug(2,a)}}if(c!=null){try{c.end()}catch(a){debug(2,a)}}debug(1,"Tunnel disconnected: "+b)}function OnWebSocket(b,c,a){debug(1,"Websocket connected");c.on("data",function(d){if(this.parent.tunneling==false){d=d.toString();if(d=="c"){this.parent.tunneling=true;this.pipe(this.parent.tcp);this.parent.tcp.pipe(this);debug(1,"Tunnel active")}else{if((d.length>6)&&(d.substring(0,6)=="error:")){console.log(d.substring(6));disconnectTunnel(this.tcp,this,d.substring(6))}}}});c.on("error",function(d){disconnectTunnel(this.tcp,this,"Websocket error")});c.on("close",function(d){disconnectTunnel(this.tcp,this,"Websocket closed")});c.parent=this}function discoverMeshServer(){console.log("Looking for server...");discoveryInterval=setInterval(discoverMeshServerOnce,5000);discoverMeshServerOnce()}function discoverMeshServerOnce(){var f=os.networkInterfaces();for(var a in f){if(f.hasOwnProperty(a)){for(var d=0;dm){g+="}";m++}f=JSON.parse(g)}catch(j){console.log("Error: Unable to parse Intel AMT response: "+g,j);a(null)}if(a!=null){a(d.statusCode,f)}})});c.on("error",function(d){console.log("Error occured: "+JSON.stringify(d));if(b==true){if(a!=null){a(null)}}else{getAmtStorage(a,true)}});c.end()}function pushToStorage(f,e,b,c,g){if(g==null){g=0}var h=digest.request({protocol:settings.protocol,method:"PUT",host:settings.hostname,path:("/amt-storage/"+f+((g!=0)?"?append=":"")),port:settings.localport});h.on("error",function(j){console.log("Error occured: "+JSON.stringify(j));if(c!=null){c(null)}});h.on("response",function(j){debug(1,"Chunk Done",b.length,g);if((j.statusCode==200)&&(g0)?"":"Content-Encoding:gzipContent-Type:text/html"+((e!=null)?(""+e+""):"")+"";var a=((b.length-g)>(7000-d.length))?(7000-d.length):(b.length-g);h.write(Buffer.concat([new Buffer(d),b.slice(g,g+a)]));g+=a;h.end()}function verifyStorage(c,a,b){var d=digest.request({protocol:settings.protocol,method:"GET",host:settings.hostname,path:("/amt-storage/"+c),port:settings.localport});d.on("error",function(f){console.log("Verify error occured: "+JSON.stringify(f));if(b!=null){b(null)}});d.on("response",function(e){e.ptr=0;e.ok=true;e.on("data",function(f){if(f.toString("hex")!=a.slice(e.ptr,e.ptr+f.length).toString("hex")){e.ok=false;console.log("Verifiy failed ("+e.ptr+", "+f.length+").")}e.ptr+=f.length});e.on("end",function(){if(b!=null){b(e.ok)}})});d.end()}function deleteStorage(b,a,c){var d=digest.request({protocol:settings.protocol,method:"DELETE",host:settings.hostname,path:"/amt-storage/"+b,port:settings.localport});d.on("error",function(f){if((f=="Error: Socket was unexpectedly closed")&&(c!=true)){deleteStorage(b,a,true)}else{if(a!=null){if(f.statusCode){a(f.statusCode)}else{a(null)}}}});d.on("response",function(e){if(a!=null){a(e.statusCode)}});d.end()}function parseUrlArguments(d){var c={},e=d.split("?");if(e.length<2){return c}e=e[1].split("&");for(var a in e){var b=e[a].indexOf("=");if(b>0){c[e[a].substring(0,b).toLowerCase()]=e[a].substring(b+1)}}return c}function removeItemFromArray(a,b){var c=a.indexOf(b);if(c!==-1){a.splice(c,1)}}var serviceName=null;var serviceOpSpecified=0;var serviceInstall=0;for(var i in process.argv){if(process.argv[i].toLowerCase()=="install"){serviceInstall=1}else{if(process.argv[i].toLowerCase()=="uninstall"){serviceInstall=-1}}if((process.argv[i].toLowerCase()=="microlms")||(process.argv[i].toLowerCase()=="amtlms")||(process.argv[i].toLowerCase()=="lms")){serviceName="MicroLMS";break}if((process.argv[i].toLowerCase()=="meshcommander")||(process.argv[i].toLowerCase()=="commander")){serviceName="MeshCommander";break}}if(serviceName==null){for(var i in process.argv){if((process.argv[i].toLowerCase()=="install")||(process.argv[i].toLowerCase()=="uninstall")){console.log("In order to install/uninstall, a service type must be specified.");process.exit()}}if(process.execPath.includes("MicroLMS")){serviceName="MicroLMS"}else{if(process.execPath.includes("MeshCommander")){serviceName="MeshCommander"}else{serviceName="not_a_service"}}}if(serviceInstall==0){run(process.argv)}else{var serviceHost=require("service-host");var meshcmdService=new serviceHost({name:serviceName,startType:"AUTO_START"});meshcmdService.on("serviceStart",function onStart(){console.setDestination(console.Destinations.DISABLED);if(process.execPath.includes("MicroLMS")){run([process.execPath,"microlms"])}else{if(process.execPath.includes("MeshCommander")){run([process.execPath,"meshcommander"])}else{console.log("Aborting Service Start, because unknown binary: "+process.execPath);process.exit(1)}}});meshcmdService.on("serviceStop",function onStop(){console.log("Stopping service");process.exit()});meshcmdService.on("normalStart",function onNormalStart(){try{run(process.argv)}catch(a){console.log("ERROR: "+a)}});meshcmdService.run()}; \ No newline at end of file diff --git a/public/commander.htm b/public/commander.htm index 8cc1fa28..d2c2ed1c 100644 --- a/public/commander.htm +++ b/public/commander.htm @@ -11,125 +11,125 @@ function ObjectToStringEx(b,c){var a="";if(0!=b&&(!b||null==b))return"(Null)";if function ObjectToStringEx2(b,c){var a="";if(0!=b&&(!b||null==b))return"(Null)";if(b instanceof Array)for(var d in b)a+="\r\n"+gap2(c)+"Item #"+d+": "+ObjectToStringEx2(b[d],c+1);else if(b instanceof Object)for(d in b)a+="\r\n"+gap2(c)+d+" = "+ObjectToStringEx2(b[d],c+1);else a+=EscapeHtml(b);return a}function gap(b){for(var c="",a=0;a<4*b;a++)c+=" ";return c}function gap2(b){for(var c="",a=0;a<4*b;a++)c+=" ";return c}function ObjectToString(b){return ObjectToStringEx(b,0)} function ObjectToString2(b){return ObjectToStringEx2(b,0)}function hex2rstr(b){if("string"!=typeof b||0==b.length)return"";var c="";b=(""+b).match(/../g);for(var a;a=b.shift();)c+=String.fromCharCode("0x"+a);return c}function char2hex(b){return(b+256).toString(16).substr(-2).toUpperCase()}function rstr2hex(b){var c="",a;for(a=0;a>9)-1);b("DEV_FLOPPY",d);break;case 176:if(null==e.floppy||0==e.floppy.size)return e.SendCommandEndResponse(0,2,c,58,0),-1;null!=e.cdrom&&(d=(e.cdrom.size>>11)-1);b("DEV_CDDVD",d);break;default:return b("SCSI Internal error 4",c),-1}b("SCSI: READ_CAPACITY2",c,C);e.SendDataToHost(C,!0,IntToStr(d)+String.fromCharCode(0,0,176== -c?8:2,0),z&1);break;case 40:C=ReadInt(d,2);d=ReadShort(d,7);b("SCSI: READ_10",c,C,d);a(c,C,d,z);break;case 42:case 46:C=ReadInt(d,2);d=ReadShort(d,7);b("SCSI: WRITE_10",c,C,d);e.SendGetDataFromHost(c,512*d);break;case 67:C=ReadShort(d,7);var F=d.charCodeAt(1)&2,r=d.charCodeAt(2)&7;0==r&&(r=d.charCodeAt(9)>>6);b("SCSI: READ_TOC, dev="+c+", buflen="+C+", msf="+F+", format="+r);switch(c){case 160:return e.SendCommandEndResponse(1,5,c,32,0),-1;case 176:break;default:return b("SCSI Internal error 9",c), --1}1==r?e.SendDataToHost(c,!0,String.fromCharCode(0,10,1,1,0,20,1,0,0,0,0,0),z&1):0==r&&(F?e.SendDataToHost(c,!0,String.fromCharCode(0,18,1,1,0,20,1,0,0,0,2,0,0,20,170,0,0,0,52,19),z&1):e.SendDataToHost(c,!0,String.fromCharCode(0,18,1,1,0,20,1,0,0,0,0,0,0,20,170,0,0,0,0,0),z&1));break;case 70:var r=2!=d.charCodeAt(1),M=ReadShort(d,2);C=ReadShort(d,7);b("SCSI: GET_CONFIGURATION",c,r,M,C);if(0==C)return e.SendDataToHost(c,!0,IntToStr(60)+IntToStr(8),z&1),-1;F=IntToStr(8);0==M&&(F+=B);if(1==M||r&&1> -M)F+=l;if(2==M||r&&2>M)F+=g;if(3==M||r&&3>M)F+=x;if(16==M||r&&16>M)F+=u;if(30==M||r&&30>M)F+=J;if(256==M||r&&256>M)F+=A;if(261==M||r&&261>M)F+=y;F=IntToStr(F.length)+F;F.length>C&&(F=F.substring(0,C));e.SendDataToHost(c,!0,F,z&1);return-1;case 74:b("SCSI: GET_EVENT_STATUS_NOTIFICATION",c,d.charCodeAt(1),d.charCodeAt(4),d.charCodeAt(9));if(1!=d.charCodeAt(1)&&16!=d.charCodeAt(4)){b("SCSI ERROR");e.SendCommandEndResponse(1,5,c,38,1);break}d=0;160==c&&null!=e.floppy?d=2:176==c&&null!=e.cdrom&&(d=2); -e.SendDataToHost(c,!0,String.fromCharCode(0,d,128,0),z&1);break;case 76:e.SendCommand(81,IntToStrX(0)+IntToStrX(0)+IntToStrX(0)+String.fromCharCode(135,80,3,0,0,0,176,81,5,32,0),!0);break;case 81:return b("SCSI READ_DISC_INFO",c),e.SendCommandEndResponse(0,5,c,32,0),-1;case 85:return b("SCSI ERROR: MODE_SELECT_10",c),e.SendCommandEndResponse(1,5,c,32,0),-1;case 90:b("SCSI: MODE_SENSE_10",c,d.charCodeAt(2)&63);C=ReadShort(d,7);F=null;if(0==C)return e.SendDataToHost(c,!0,IntToStr(60)+IntToStr(8),z& -1),-1;C=0;160==c?null!=e.floppy&&(C=e.floppy.size>>9):null!=e.cdrom&&(C=e.cdrom.size>>11);switch(d.charCodeAt(2)&63){case 1:F=160==c?2880>=C?H:E:D;break;case 5:160==c&&(F=2880>=C?v:q);break;case 63:F=160==c?2880>=C?n:k:w;break;case 26:176==c&&(F=p);break;case 29:176==c&&(F=h);break;case 42:176==c&&(F=m)}null==F?e.SendCommandEndResponse(0,5,c,32,0):e.SendDataToHost(c,!0,F,z&1);break;default:return b("IDER: Unknown SCSI command",d.charCodeAt(0)),e.SendCommandEndResponse(0,5,c,32,0),-1}return 0}function a(a, -b,c,n){var h=null,y=0;160==a&&(h=e.floppy,null!=e.floppy&&(y=e.floppy.size>>9));176==a&&(h=e.cdrom,null!=e.cdrom&&(y=e.cdrom.size>>11));if(0>c||b+c>y)return e.SendCommandEndResponse(1,5,a,33,0),0;if(0==c)return e.SendCommandEndResponse(1,0,a,0,0),0;null!=h&&(e.sectorStats&&e.sectorStats(1,160==a?0:1,y,b,c),160==a?(b<<=9,c<<=9):(b<<=11,c<<=11),null!==F?z.push({media:h,dev:a,lba:b,len:c,fr:n}):(F=h,M=a,W=b,r=c,d(n)))}function d(a){var b=r,c=W;r>e.iderinfo.readbfr&&(b=e.iderinfo.readbfr);r-=b;W+=b;var n= -new FileReader;n.onload=function(){e.SendDataToHost(M,0==r,this.result,a&1);if(0>9:0),e.sectorStats(0,1,e.cdrom?e.cdrom.size>>11:0))};e.Stop= -function(){b("IDER-Stop");e.parent.Stop()};e.ProcessData=function(a){e.bytesFromAmt+=a.length;e.acc+=a;for(b("IDER-ProcessData",e.acc.length,rstr2hex(e.acc));;){a=e.ProcessDataEx();if(0==a)break;if(e.inSequence!=ReadIntX(e.acc,4)){b("ERROR: Out of sequence",e.inSequence,ReadIntX(e.acc,4));e.Stop();break}e.inSequence++;e.acc=e.acc.substring(a)}};e.SendCommand=function(a,c,n,h){null==c&&(c="");n=50>8,0,n?180:181,0,2,0,h&255,h>>8,a,88,133,0,3,0,0,0,a,80,0,0,0,0,0,0)+c,b,n):e.SendCommand(84, -String.fromCharCode(0,c.length&255,c.length>>8,0,n?180:181,0,2,0,h&255,h>>8,a,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0)+c,b,n)};e.SendGetDataFromHost=function(a,b){e.SendCommand(82,String.fromCharCode(0,b&255,b>>8,0,181,0,0,0,b&255,b>>8,a,88,0,0,0,0,0,0,0,0,0,0,0),!1)};e.SendDisableEnableFeatures=function(a,b){null==b&&(b="");e.SendCommand(72,String.fromCharCode(a)+b)};e.ProcessDataEx=function(){if(8>e.acc.length)return 0;switch(e.acc.charCodeAt(0)){case 65:if(30>e.acc.length)break;var a=e.acc.charCodeAt(29); +var CreateAmtRemoteIder=function(){function b(){urlvars&&urlvars.idertrace&&console.log.apply(console,[].concat($jscomp.arrayFromArguments(arguments)))}function c(c,d,x,z){switch(d.charCodeAt(0)){case 0:b("SCSI: TEST_UNIT_READY",c);switch(c){case 160:if(null==e.floppy)return e.SendCommandEndResponse(1,2,c,58,0),-1;if(0==e.floppyReady)return e.floppyReady=!0,e.SendCommandEndResponse(1,6,c,40,0),-1;break;case 176:if(null==e.cdrom)return e.SendCommandEndResponse(1,2,c,58,0),-1;if(0==e.cdromReady)return e.cdromReady= +!0,e.SendCommandEndResponse(1,6,c,40,0),-1;break;default:return b("SCSI Internal error 3",c),-1}e.SendCommandEndResponse(1,0,c,0,0);break;case 8:z=((d.charCodeAt(1)&31)<<16)+(d.charCodeAt(2)<<8)+d.charCodeAt(3);d=d.charCodeAt(4);0==d&&(d=256);b("SCSI: READ_6",c,z,d);a(c,z,d,x);break;case 10:return z=((d.charCodeAt(1)&31)<<16)+(d.charCodeAt(2)<<8)+d.charCodeAt(3),d=d.charCodeAt(4),0==d&&(d=256),b("SCSI: WRITE_6",c,z,d),e.SendCommandEndResponse(1,2,c,58,0),-1;case 26:b("SCSI: MODE_SENSE_6",c);if(63== +d.charCodeAt(2)&&0==d.charCodeAt(3)){z=d=0;switch(c){case 160:if(null==e.floppy)return e.SendCommandEndResponse(1,2,c,58,0),-1;d=0;z=128;break;case 176:if(null==e.cdrom)return e.SendCommandEndResponse(1,2,c,58,0),-1;d=5;z=128;break;default:return b("SCSI Internal error 6",c),-1}e.SendDataToHost(c,!0,String.fromCharCode(0,d,z,0),x&1);return}e.SendCommandEndResponse(1,5,c,36,0);break;case 27:e.SendCommandEndResponse(1,0,c);break;case 30:b("SCSI: ALLOW_MEDIUM_REMOVAL",c);if(160==c&&null==e.floppy||176== +c&&null==e.cdrom)return e.SendCommandEndResponse(1,2,c,58,0),-1;e.SendCommandEndResponse(1,0,c,0,0);break;case 35:b("SCSI: READ_FORMAT_CAPACITIES",c);z=ReadShort(d,7);switch(c){case 160:if(null==e.floppy||0==e.floppy.size)return e.SendCommandEndResponse(0,5,c,36,0),-1;break;case 176:if(null==e.cdrom||0==e.cdrom.size)return e.SendCommandEndResponse(0,5,c,36,0),-1;break;default:return b("SCSI Internal error 4",c),-1}e.SendDataToHost(c,!0,IntToStr(8)+String.fromCharCode(0,0,11,64,2,0,2,0),x&1);break; +case 37:b("SCSI: READ_CAPACITY",c);d=0;switch(c){case 160:if(null==e.floppy||0==e.floppy.size)return e.SendCommandEndResponse(0,2,c,58,0),-1;null!=e.floppy&&(d=(e.floppy.size>>9)-1);b("DEV_FLOPPY",d);break;case 176:if(null==e.floppy||0==e.floppy.size)return e.SendCommandEndResponse(0,2,c,58,0),-1;null!=e.cdrom&&(d=(e.cdrom.size>>11)-1);b("DEV_CDDVD",d);break;default:return b("SCSI Internal error 4",c),-1}b("SCSI: READ_CAPACITY2",c,z);e.SendDataToHost(z,!0,IntToStr(d)+String.fromCharCode(0,0,176== +c?8:2,0),x&1);break;case 40:z=ReadInt(d,2);d=ReadShort(d,7);b("SCSI: READ_10",c,z,d);a(c,z,d,x);break;case 42:case 46:z=ReadInt(d,2);d=ReadShort(d,7);b("SCSI: WRITE_10",c,z,d);e.SendGetDataFromHost(c,512*d);break;case 67:z=ReadShort(d,7);var C=d.charCodeAt(1)&2,q=d.charCodeAt(2)&7;0==q&&(q=d.charCodeAt(9)>>6);b("SCSI: READ_TOC, dev="+c+", buflen="+z+", msf="+C+", format="+q);switch(c){case 160:return e.SendCommandEndResponse(1,5,c,32,0),-1;case 176:break;default:return b("SCSI Internal error 9",c), +-1}1==q?e.SendDataToHost(c,!0,String.fromCharCode(0,10,1,1,0,20,1,0,0,0,0,0),x&1):0==q&&(C?e.SendDataToHost(c,!0,String.fromCharCode(0,18,1,1,0,20,1,0,0,0,2,0,0,20,170,0,0,0,52,19),x&1):e.SendDataToHost(c,!0,String.fromCharCode(0,18,1,1,0,20,1,0,0,0,0,0,0,20,170,0,0,0,0,0),x&1));break;case 70:var q=2!=d.charCodeAt(1),M=ReadShort(d,2);z=ReadShort(d,7);b("SCSI: GET_CONFIGURATION",c,q,M,z);if(0==z)return e.SendDataToHost(c,!0,IntToStr(60)+IntToStr(8),x&1),-1;C=IntToStr(8);0==M&&(C+=k);if(1==M||q&&1> +M)C+=y;if(2==M||q&&2>M)C+=h;if(3==M||q&&3>M)C+=K;if(16==M||q&&16>M)C+=r;if(30==M||q&&30>M)C+=E;if(256==M||q&&256>M)C+=A;if(261==M||q&&261>M)C+=B;C=IntToStr(C.length)+C;C.length>z&&(C=C.substring(0,z));e.SendDataToHost(c,!0,C,x&1);return-1;case 74:b("SCSI: GET_EVENT_STATUS_NOTIFICATION",c,d.charCodeAt(1),d.charCodeAt(4),d.charCodeAt(9));if(1!=d.charCodeAt(1)&&16!=d.charCodeAt(4)){b("SCSI ERROR");e.SendCommandEndResponse(1,5,c,38,1);break}d=0;160==c&&null!=e.floppy?d=2:176==c&&null!=e.cdrom&&(d=2); +e.SendDataToHost(c,!0,String.fromCharCode(0,d,128,0),x&1);break;case 76:e.SendCommand(81,IntToStrX(0)+IntToStrX(0)+IntToStrX(0)+String.fromCharCode(135,80,3,0,0,0,176,81,5,32,0),!0);break;case 81:return b("SCSI READ_DISC_INFO",c),e.SendCommandEndResponse(0,5,c,32,0),-1;case 85:return b("SCSI ERROR: MODE_SELECT_10",c),e.SendCommandEndResponse(1,5,c,32,0),-1;case 90:b("SCSI: MODE_SENSE_10",c,d.charCodeAt(2)&63);z=ReadShort(d,7);C=null;if(0==z)return e.SendDataToHost(c,!0,IntToStr(60)+IntToStr(8),x& +1),-1;z=0;160==c?null!=e.floppy&&(z=e.floppy.size>>9):null!=e.cdrom&&(z=e.cdrom.size>>11);switch(d.charCodeAt(2)&63){case 1:C=160==c?2880>=z?I:F:D;break;case 5:160==c&&(C=2880>=z?u:g);break;case 63:C=160==c?2880>=z?p:l:v;break;case 26:176==c&&(C=n);break;case 29:176==c&&(C=w);break;case 42:176==c&&(C=m)}null==C?e.SendCommandEndResponse(0,5,c,32,0):e.SendDataToHost(c,!0,C,x&1);break;default:return b("IDER: Unknown SCSI command",d.charCodeAt(0)),e.SendCommandEndResponse(0,5,c,32,0),-1}return 0}function a(a, +b,c,p){var B=null,k=0;160==a&&(B=e.floppy,null!=e.floppy&&(k=e.floppy.size>>9));176==a&&(B=e.cdrom,null!=e.cdrom&&(k=e.cdrom.size>>11));if(0>c||b+c>k)return e.SendCommandEndResponse(1,5,a,33,0),0;if(0==c)return e.SendCommandEndResponse(1,0,a,0,0),0;null!=B&&(e.sectorStats&&e.sectorStats(1,160==a?0:1,k,b,c),160==a?(b<<=9,c<<=9):(b<<=11,c<<=11),null!==C?z.push({media:B,dev:a,lba:b,len:c,fr:p}):(C=B,M=a,aa=b,q=c,d(p)))}function d(a){var b=q,c=aa;q>e.iderinfo.readbfr&&(b=e.iderinfo.readbfr);q-=b;aa+= +b;var p=new FileReader;p.onload=function(){e.SendDataToHost(M,0==q,this.result,a&1);if(0>9:0),e.sectorStats(0,1,e.cdrom?e.cdrom.size>> +11:0))};e.Stop=function(){b("IDER-Stop");e.parent.Stop()};e.ProcessData=function(a){e.bytesFromAmt+=a.length;e.acc+=a;for(b("IDER-ProcessData",e.acc.length,rstr2hex(e.acc));;){a=e.ProcessDataEx();if(0==a)break;if(e.inSequence!=ReadIntX(e.acc,4)){b("ERROR: Out of sequence",e.inSequence,ReadIntX(e.acc,4));e.Stop();break}e.inSequence++;e.acc=e.acc.substring(a)}};e.SendCommand=function(a,c,p,B){null==c&&(c="");p=50>8,0,p?180:181,0,2,0,B&255,B>>8,a,88,133,0,3,0,0,0,a,80,0,0,0,0,0,0)+c,b,p):e.SendCommand(84, +String.fromCharCode(0,c.length&255,c.length>>8,0,p?180:181,0,2,0,B&255,B>>8,a,88,0,0,0,0,0,0,0,0,0,0,0,0,0,0)+c,b,p)};e.SendGetDataFromHost=function(a,b){e.SendCommand(82,String.fromCharCode(0,b&255,b>>8,0,181,0,0,0,b&255,b>>8,a,88,0,0,0,0,0,0,0,0,0,0,0),!1)};e.SendDisableEnableFeatures=function(a,b){null==b&&(b="");e.SendCommand(72,String.fromCharCode(a)+b)};e.ProcessDataEx=function(){if(8>e.acc.length)return 0;switch(e.acc.charCodeAt(0)){case 65:if(30>e.acc.length)break;var a=e.acc.charCodeAt(29); if(e.acc.length<30+a)break;e.iderinfo={};e.iderinfo.major=e.acc.charCodeAt(8);e.iderinfo.minor=e.acc.charCodeAt(9);e.iderinfo.fwmajor=e.acc.charCodeAt(10);e.iderinfo.fwminor=e.acc.charCodeAt(11);e.iderinfo.readbfr=ReadShortX(e.acc,16);e.iderinfo.writebfr=ReadShortX(e.acc,18);e.iderinfo.proto=e.acc.charCodeAt(21);e.iderinfo.iana=ReadIntX(e.acc,25);b(e.iderinfo);0!=e.iderinfo.proto&&(b("Unknown proto",e.iderinfo.proto),e.Stop());8192e.acc.length)break;a=e.acc.charCodeAt(8);null===F?(e.SendCommand(71),b("RESETOCCURED1",a)):(C=!0,b("RESETOCCURED2", -a));return 9;case 73:if(13>e.acc.length)break;var a=e.acc.charCodeAt(8),n=ReadIntX(e.acc,9);b("STATUS_DATA",a,n);switch(a){case 1:n&1&&(0==e.iderStart?e.SendDisableEnableFeatures(3,IntToStrX(9)):1==e.iderStart?e.SendDisableEnableFeatures(3,IntToStrX(17)):2==e.iderStart&&e.SendDisableEnableFeatures(3,IntToStrX(25)));break;case 2:e.enabled=n&2?!0:!1;b("IDER Status: "+e.enabled);break;case 3:1!=n&&b("Register toggle failure")}return 13;case 74:if(11>e.acc.length)break;b("IDER: ABORT",e.acc.charCodeAt(8)); -return 11;case 75:return 8;case 80:if(28>e.acc.length)break;var a=e.acc.charCodeAt(14)&16?176:160,n=e.acc.charCodeAt(14),h=e.acc.substring(16,28),d=e.acc.charCodeAt(9);b("SCSI_CMD",a,rstr2hex(h),d,n);c(a,h,d,n);return 28;case 83:if(14>e.acc.length)break;a=ReadShortX(e.acc,9);if(e.acc.length<14+a)break;b("SCSI_WRITE, len = "+(14+a));e.SendCommand(81,String.fromCharCode(0,0,0,0,0,0,0,0,0,0,0,0,135,112,3,0,0,0,160,81,7,39,0),!0);return 14+a;default:b("Unknown IDER command",e.acc[0]),e.Stop()}return 0}; -var z=[],C=!1,F=null,M,W,r;return e},CreateAmtRemoteServerIder=function(){function b(){urlvars&&urlvars.idertrace&&console.log.apply(console,[].concat($jscomp.arrayFromArguments(arguments)))}var c={protocol:4,iderStart:0,floppy:null,cdrom:null,state:0,onStateChanged:null,m:{sectorStats:null,onDialogPrompt:null,dialogPrompt:function(a){c.socket.send(JSON.stringify({action:"dialogResponse",args:a}))},bytesToAmt:0,bytesFromAmt:0,server:!0,Stop:function(){c.Stop()}},xxStateChange:function(a){if(c.state!= -a&&(b("SIDER-StateChange",a),c.state=a,null!=c.onStateChanged))c.onStateChanged(c,c.state)},Start:function(a,d,e,q,k){b("SIDER-Start",a,d,e,q,k);c.host=a;c.port=d;c.user=e;c.pass=q;c.connectstate=0;c.socket=new WebSocket(window.location.protocol.replace("http","ws")+"//"+window.location.host+window.location.pathname.substring(0,window.location.pathname.lastIndexOf("/"))+"/webider.ashx?host="+a+"&port="+d+"&tls="+k+("*"==e?"&serverauth=1":"")+("undefined"===typeof q?"&serverauth=1&user="+e:"")+"&tls1only="+ +e.Stop());8192e.acc.length)break;a=e.acc.charCodeAt(8);null===C?(e.SendCommand(71),b("RESETOCCURED1",a)):(x=!0,b("RESETOCCURED2", +a));return 9;case 73:if(13>e.acc.length)break;var a=e.acc.charCodeAt(8),p=ReadIntX(e.acc,9);b("STATUS_DATA",a,p);switch(a){case 1:p&1&&(0==e.iderStart?e.SendDisableEnableFeatures(3,IntToStrX(9)):1==e.iderStart?e.SendDisableEnableFeatures(3,IntToStrX(17)):2==e.iderStart&&e.SendDisableEnableFeatures(3,IntToStrX(25)));break;case 2:e.enabled=p&2?!0:!1;b("IDER Status: "+e.enabled);break;case 3:1!=p&&b("Register toggle failure")}return 13;case 74:if(11>e.acc.length)break;b("IDER: ABORT",e.acc.charCodeAt(8)); +return 11;case 75:return 8;case 80:if(28>e.acc.length)break;var a=e.acc.charCodeAt(14)&16?176:160,p=e.acc.charCodeAt(14),B=e.acc.substring(16,28),d=e.acc.charCodeAt(9);b("SCSI_CMD",a,rstr2hex(B),d,p);c(a,B,d,p);return 28;case 83:if(14>e.acc.length)break;a=ReadShortX(e.acc,9);if(e.acc.length<14+a)break;b("SCSI_WRITE, len = "+(14+a));e.SendCommand(81,String.fromCharCode(0,0,0,0,0,0,0,0,0,0,0,0,135,112,3,0,0,0,160,81,7,39,0),!0);return 14+a;default:b("Unknown IDER command",e.acc[0]),e.Stop()}return 0}; +var z=[],x=!1,C=null,M,aa,q;return e},CreateAmtRemoteServerIder=function(){function b(){urlvars&&urlvars.idertrace&&console.log.apply(console,[].concat($jscomp.arrayFromArguments(arguments)))}var c={protocol:4,iderStart:0,floppy:null,cdrom:null,state:0,onStateChanged:null,m:{sectorStats:null,onDialogPrompt:null,dialogPrompt:function(a){c.socket.send(JSON.stringify({action:"dialogResponse",args:a}))},bytesToAmt:0,bytesFromAmt:0,server:!0,Stop:function(){c.Stop()}},xxStateChange:function(a){if(c.state!= +a&&(b("SIDER-StateChange",a),c.state=a,null!=c.onStateChanged))c.onStateChanged(c,c.state)},Start:function(a,d,e,g,l){b("SIDER-Start",a,d,e,g,l);c.host=a;c.port=d;c.user=e;c.pass=g;c.connectstate=0;c.socket=new WebSocket(window.location.protocol.replace("http","ws")+"//"+window.location.host+window.location.pathname.substring(0,window.location.pathname.lastIndexOf("/"))+"/webider.ashx?host="+a+"&port="+d+"&tls="+l+("*"==e?"&serverauth=1":"")+("undefined"===typeof g?"&serverauth=1&user="+e:"")+"&tls1only="+ c.tlsv1only);c.socket.onopen=c.xxOnSocketConnected;c.socket.onmessage=c.xxOnMessage;c.socket.onclose=c.xxOnSocketClosed;c.xxStateChange(1)},Stop:function(){b("SIDER-Stop");null!=c.socket&&(c.socket.close(),c.socket=null);c.xxStateChange(0)},xxOnSocketConnected:function(){c.xxStateChange(2);c.socket.send(JSON.stringify({action:"start"}))},xxOnMessage:function(a){var b=null;try{b=JSON.parse(a.data)}catch(e){}if(null!=b&&"string"==typeof b.action)switch(b.action){case "dialog":if(null!=c.m.onDialogPrompt)c.m.onDialogPrompt(c, b.args,b.buttons);break;case "state":2==b.state&&c.xxStateChange(3);break;case "stats":c.m.bytesToAmt=b.toAmt;c.m.bytesFromAmt=b.fromAmt;c.m.sectorStats&&c.m.sectorStats(b.mode,b.dev,b.total,b.start,b.len);break;case "error":console.log("IDER Error: "+";Floppy disk image does not exist;Invalid floppy disk image;Unable to open floppy disk image;CDROM disk image does not exist;Invalid CDROM disk image;Unable to open CDROM disk image;Can't perform IDER with no disk images".split(";")[b.code]);break; -default:console.log("Unknown Server IDER action: "+b.action),breal}},xxOnSocketClosed:function(){c.Stop()}};return c},CreateWsmanComm=function(b,c,a,d,e){function q(){p.socketState=2;p.socketParseState=0;p.socketAccumulator="";p.socketHeader=null;p.socketData="";for(i in p.pendingAjaxCall)p.sendRequest(p.pendingAjaxCall[i][0],p.pendingAjaxCall[i][3],p.pendingAjaxCall[i][4])}function k(a){if("object"==typeof a.data)if(1==m)w.push(a.data);else if(h.readAsBinaryString)m=!0,h.readAsBinaryString(new Blob([a.data])); -else if(h.readAsArrayBuffer)m=!0,h.readAsArrayBuffer(a.data);else{var b="";a=new Uint8Array(a.data);for(var c=a.byteLength,n=0;na)break;p.socketHeader=p.socketAccumulator.substring(0, -a).split("\r\n");if(null==p.amtVersion)for(n in p.socketHeader)0==p.socketHeader[n].indexOf("Server: Intel(R) Active Management Technology ")&&(p.amtVersion=p.socketHeader[n].substring(46));p.socketAccumulator=p.socketAccumulator.substring(a+4);p.socketParseState=1;p.socketData="";p.socketXHeader={Directive:p.socketHeader[0].split(" ")};for(n in p.socketHeader)0!=n&&(a=p.socketHeader[n].indexOf(":"),p.socketXHeader[p.socketHeader[n].substring(0,a).toLowerCase()]=p.socketHeader[n].substring(a+2))}if(1== -p.socketParseState){b=-1;if(void 0==p.socketXHeader.connection||"close"!=p.socketXHeader.connection.toLowerCase()||void 0!=p.socketXHeader["transfer-encoding"]&&"chunked"==p.socketXHeader["transfer-encoding"].toLowerCase())if(void 0!=p.socketXHeader["content-length"]){b=parseInt(p.socketXHeader["content-length"]);if(p.socketAccumulator.lengthc)break;b=parseInt(p.socketAccumulator.substring(0,c),16);if(isNaN(b)){p.websocket&&p.websocket.close();break}if(p.socketAccumulator.length++p.authcounter?p.challengeParams=p.parseDigest(c["www-authenticate"]):(c=p.pendingAjaxCall.shift(),p.authcounter=0,p.ActiveAjaxCount--, -p.gotNextMessages(a,"success",{status:b},c),p.PerformNextAjax()),p.socketParseState=0,p.socketHeader=null)}}}function n(a){0==p.inDataCount&&(p.tlsv1only=1-p.tlsv1only);p.socketState=0;null!=p.socket&&(p.socket.close(),p.socket=null);if(0=p.MaxActiveAjaxCount||0==p.PendingAjax.length)){var a=p.PendingAjax.shift(); -p.PerformAjaxEx(a[0],a[1],a[2],a[3],a[4]);p.PerformNextAjax()}};p.PerformAjaxEx=function(a,b,c,n,h){if(0!=p.FailAllError)p.gotNextMessagesError({status:p.FailAllError},"error",null,[a,b,c,n,h]);else return a||(a=""),p.ActiveAjaxCount++,p.PerformAjaxExNodeJS(a,b,c,n,h)};p.pendingAjaxCall=[];p.PerformAjaxExNodeJS=function(a,b,c,n,h){p.PerformAjaxExNodeJS2(a,b,c,n,h,3)};p.PerformAjaxExNodeJS2=function(a,b,c,n,h,d){0>=d||0!=p.FailAllError?(p.ActiveAjaxCount--,999!=p.FailAllError&&p.gotNextMessages(null, -"error",{status:0==p.FailAllError?408:p.FailAllError},[a,b,c,n,h]),p.PerformNextAjax()):(p.pendingAjaxCall.push([a,b,c,n,h,d]),0==p.socketState?p.xxConnectHttpSocket():2==p.socketState&&p.sendRequest(a,n,h))};p.sendRequest=function(a,b,c){b=b?b:"/wsman";c=c?c:"POST";var n=c+" "+b+" HTTP/1.1\r\n";if(null!=p.challengeParams){p.digestRealm=p.challengeParams.realm;if(p.digestRealmMatch&&p.digestRealm!=p.digestRealmMatch){p.FailAllError=997;p.CancelAllQueries(997);return}c=hex_md5(hex_md5(p.user+":"+p.challengeParams.realm+ -":"+p.pass)+":"+p.challengeParams.nonce+":"+p.noncecounter+":"+p.cnonce+":"+p.challengeParams.qop+":"+hex_md5(c+":"+b));n+="Authorization: "+p.renderDigest({username:p.user,realm:p.challengeParams.realm,nonce:p.challengeParams.nonce,uri:b,qop:p.challengeParams.qop,response:c,nc:p.noncecounter++,cnonce:p.cnonce})+"\r\n"}a=n+="Host: "+p.host+":"+p.port+"\r\nContent-Length: "+a.length+"\r\n\r\n"+a;if(2==p.socketState&&null!=p.socket&&p.socket.readyState==WebSocket.OPEN){b=new Uint8Array(a.length);for(n= -0;na)break;n.socketHeader=n.socketAccumulator.substring(0, +a).split("\r\n");if(null==n.amtVersion)for(p in n.socketHeader)0==n.socketHeader[p].indexOf("Server: Intel(R) Active Management Technology ")&&(n.amtVersion=n.socketHeader[p].substring(46));n.socketAccumulator=n.socketAccumulator.substring(a+4);n.socketParseState=1;n.socketData="";n.socketXHeader={Directive:n.socketHeader[0].split(" ")};for(p in n.socketHeader)0!=p&&(a=n.socketHeader[p].indexOf(":"),n.socketXHeader[n.socketHeader[p].substring(0,a).toLowerCase()]=n.socketHeader[p].substring(a+2))}if(1== +n.socketParseState){b=-1;if(void 0==n.socketXHeader.connection||"close"!=n.socketXHeader.connection.toLowerCase()||void 0!=n.socketXHeader["transfer-encoding"]&&"chunked"==n.socketXHeader["transfer-encoding"].toLowerCase())if(void 0!=n.socketXHeader["content-length"]){b=parseInt(n.socketXHeader["content-length"]);if(n.socketAccumulator.lengthc)break;b=parseInt(n.socketAccumulator.substring(0,c),16);if(isNaN(b)){n.websocket&&n.websocket.close();break}if(n.socketAccumulator.length++n.authcounter?n.challengeParams=n.parseDigest(c["www-authenticate"]):(c=n.pendingAjaxCall.shift(),n.authcounter=0,n.ActiveAjaxCount--, +n.gotNextMessages(a,"success",{status:b},c),n.PerformNextAjax()),n.socketParseState=0,n.socketHeader=null)}}}function p(a){0==n.inDataCount&&(n.tlsv1only=1-n.tlsv1only);n.socketState=0;null!=n.socket&&(n.socket.close(),n.socket=null);if(0=n.MaxActiveAjaxCount||0==n.PendingAjax.length)){var a=n.PendingAjax.shift(); +n.PerformAjaxEx(a[0],a[1],a[2],a[3],a[4]);n.PerformNextAjax()}};n.PerformAjaxEx=function(a,b,c,p,d){if(0!=n.FailAllError)n.gotNextMessagesError({status:n.FailAllError},"error",null,[a,b,c,p,d]);else return a||(a=""),n.ActiveAjaxCount++,n.PerformAjaxExNodeJS(a,b,c,p,d)};n.pendingAjaxCall=[];n.PerformAjaxExNodeJS=function(a,b,c,p,d){n.PerformAjaxExNodeJS2(a,b,c,p,d,3)};n.PerformAjaxExNodeJS2=function(a,b,c,p,d,e){0>=e||0!=n.FailAllError?(n.ActiveAjaxCount--,999!=n.FailAllError&&n.gotNextMessages(null, +"error",{status:0==n.FailAllError?408:n.FailAllError},[a,b,c,p,d]),n.PerformNextAjax()):(n.pendingAjaxCall.push([a,b,c,p,d,e]),0==n.socketState?n.xxConnectHttpSocket():2==n.socketState&&n.sendRequest(a,p,d))};n.sendRequest=function(a,b,c){b=b?b:"/wsman";c=c?c:"POST";var p=c+" "+b+" HTTP/1.1\r\n";if(null!=n.challengeParams){n.digestRealm=n.challengeParams.realm;if(n.digestRealmMatch&&n.digestRealm!=n.digestRealmMatch){n.FailAllError=997;n.CancelAllQueries(997);return}c=hex_md5(hex_md5(n.user+":"+n.challengeParams.realm+ +":"+n.pass)+":"+n.challengeParams.nonce+":"+n.noncecounter+":"+n.cnonce+":"+n.challengeParams.qop+":"+hex_md5(c+":"+b));p+="Authorization: "+n.renderDigest({username:n.user,realm:n.challengeParams.realm,nonce:n.challengeParams.nonce,uri:b,qop:n.challengeParams.qop,response:c,nc:n.noncecounter++,cnonce:n.cnonce})+"\r\n"}a=p+="Host: "+n.host+":"+n.port+"\r\nContent-Length: "+a.length+"\r\n\r\n"+a;if(2==n.socketState&&null!=n.socket&&n.socket.readyState==WebSocket.OPEN){b=new Uint8Array(a.length);for(p= +0;pc.amtaccumulator.length)return;switch(c.amtaccumulator.charCodeAt(1)){case 0:if(13>c.amtaccumulator.length)return;b= -c.amtaccumulator.charCodeAt(12);if(c.amtaccumulator.length<13+b)return;c.xxSend(String.fromCharCode(19,0,0,0,0,0,0,0,0));a=13+b;break;default:c.Stop()}break;case 20:if(9>c.amtaccumulator.length)return;var e=ReadIntX(c.amtaccumulator,5);if(c.amtaccumulator.length<9+e)return;var n=c.amtaccumulator.charCodeAt(1),b=c.amtaccumulator.charCodeAt(4),h=[];for(a=0;ac.amtaccumulator.length)break;a=23;c.xxSend(String.fromCharCode(39,0,0,0)+IntToStrX(c.amtsequence++)+String.fromCharCode(0,0,27,0,0,0));1==c.protocol&&(c.amtkeepalivetimer=setInterval(c.xxSendAmtKeepAlive,2E3)); +c.xxOnMessage=function(b){c.inDataCount++;if("object"==typeof b.data)if(1==d)e.push(b.data);else if(a.readAsBinaryString)d=!0,a.readAsBinaryString(new Blob([b.data]));else if(f.readAsArrayBuffer)d=!0,a.readAsArrayBuffer(b.data);else{var l="";b=new Uint8Array(b.data);for(var u=b.byteLength,p=0;pc.amtaccumulator.length)return;switch(c.amtaccumulator.charCodeAt(1)){case 0:if(13>c.amtaccumulator.length)return;b= +c.amtaccumulator.charCodeAt(12);if(c.amtaccumulator.length<13+b)return;c.xxSend(String.fromCharCode(19,0,0,0,0,0,0,0,0));a=13+b;break;default:c.Stop()}break;case 20:if(9>c.amtaccumulator.length)return;var e=ReadIntX(c.amtaccumulator,5);if(c.amtaccumulator.length<9+e)return;var p=c.amtaccumulator.charCodeAt(1),b=c.amtaccumulator.charCodeAt(4),w=[];for(a=0;ac.amtaccumulator.length)break;a=23;c.xxSend(String.fromCharCode(39,0,0,0)+IntToStrX(c.amtsequence++)+String.fromCharCode(0,0,27,0,0,0));1==c.protocol&&(c.amtkeepalivetimer=setInterval(c.xxSendAmtKeepAlive,2E3)); c.connectstate=1;c.xxStateChange(3);break;case 41:if(10>c.amtaccumulator.length)break;a=10;break;case 42:if(10>c.amtaccumulator.length)break;b=10+((c.amtaccumulator.charCodeAt(9)&255)<<8)+(c.amtaccumulator.charCodeAt(8)&255);if(c.amtaccumulator.lengthc.amtaccumulator.length)break;a=8;break;case 65:if(8>c.amtaccumulator.length)break;c.connectstate=1;c.m.Start();8'+a.InstanceID+"";var b="",c;for(c in a)if(a.hasOwnProperty(c)){b+=''; -if(a[c].ReferenceParameters){var b=b+"",b=b+(""+a[c].Address+""+a[c].ReferenceParameters.ResourceURI+""),n=a[c].ReferenceParameters.SelectorSet.Selector;if(Array.isArray(n))for(var d=0;d"+n[d].Value+"";else b+=""+n.Value+"";b+=""}else b+=a[c]; -b+=""}return b+""}var p={NextMessageId:1,Address:"/wsman"};p.comm=CreateWsmanComm(b,c,a,d,e,q);p.PerformAjax=function(a,b,c,n,d){null==d&&(d="");p.comm.PerformAjax('
"+a,function(a,c,n){200!=c?b(p,null,{Header:{HttpError:c}},c,n):(a=p.ParseWsman(a))&&null!=a?b(p,a.Header.ResourceURI,a,200,n):b(p,null,{Header:{HttpError:c}},601,n)},c,n)};p.CancelAllQueries=function(a){p.comm.CancelAllQueries(a)};p.GetNameFromUrl=function(a){var b=a.lastIndexOf("/");return-1==b?a:a.substring(b+1)};p.ExecSubscribe=function(a,b,c,d,e,g,x,u,J,A){var y="",H="";u="";null!=J&&null!=A&&(y='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken'+ -J+''+A+"",H='');null!=u&&(u=""+u+"");"PushWithAck"==b?b="dmtf.org/wbem/wsman/1/wsman/PushWithAck":"Push"==b&&(b="xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push"); -a="http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe"+p.Address+""+a+""+p.NextMessageId++ +"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"+n(x)+y+'
'+c+""+u+""+H+"";p.PerformAjax(a+"
",d,e, -g,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:m="http://x.com"')};p.ExecUnSubscribe=function(a,b,c,d,e){a="http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe"+p.Address+""+a+""+p.NextMessageId++ +"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"+n(e)+"";p.PerformAjax(a+"",b,c,d,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"')}; -p.ExecPut=function(a,b,c,d,e,g){g="http://schemas.xmlsoap.org/ws/2004/09/transfer/Put"+p.Address+""+a+""+p.NextMessageId++ +"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60.000S"+n(g)+"";if(a&&null!=b){var x=p.GetNameFromUrl(a);a="';for(var u in b)if(b.hasOwnProperty(u)&& -0!==u.indexOf("__")&&0!==u.indexOf("@")&&null!=b[u]&&"function"!==typeof b[u])if("object"===typeof b[u]&&b[u].ReferenceParameters){a+=""+b[u].Address+""+b[u].ReferenceParameters.ResourceURI+"";var J=b[u].ReferenceParameters.SelectorSet.Selector;if(Array.isArray(J))for(var A=0;A"+J[A].Value+"";else a+=""+J.Value+""; -a+=""}else if(Array.isArray(b[u]))for(A=0;A"+b[u][A].toString()+"";else a+=""+b[u].toString()+"";b=a+("")}else b="";p.PerformAjax(g+b+"",c,d,e)};p.ExecCreate=function(a,b,c,d,e,g){var x=p.GetNameFromUrl(a);a="http://schemas.xmlsoap.org/ws/2004/09/transfer/Create"+p.Address+""+a+""+p.NextMessageId++ + -"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S"+n(g)+"';for(var u in b)a+=""+b[u]+"";p.PerformAjax(a+"",c,d,e)};p.ExecDelete=function(a,b,c,d,e){a="http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete"+p.Address+""+a+""+p.NextMessageId++ + -"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S"+n(b)+"";p.PerformAjax(a,c,d,e)};p.ExecGet=function(a,b,c,n){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get"+p.Address+""+a+""+p.NextMessageId++ +"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S", -b,c,n)};p.ExecMethod=function(a,b,c,n,d,e,x){var u="",J;for(J in c)if(null!=c[J])if(Array.isArray(c[J]))for(var A in c[J])u+=""+c[J][A]+"";else u+=""+c[J]+"";p.ExecMethodXml(a,b,u,n,d,e,x)};p.ExecMethodXml=function(a,b,c,d,e,g,x){p.PerformAjax(a+"/"+b+""+p.Address+""+a+""+p.NextMessageId++ +"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S"+ -n(x)+"'+c+"",d,e,g)};p.ExecEnum=function(a,b,c,n){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate"+p.Address+""+a+""+p.NextMessageId++ +'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S', -b,c,n)};p.ExecPull=function(a,b,c,n,d){p.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull"+p.Address+""+a+""+p.NextMessageId++ +'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S'+b+"", -c,n,d)};p.ParseWsman=function(a){try{if(!a.childNodes){var b=a;if(window.DOMParser)a=(new DOMParser).parseFromString(b,"text/xml");else{var c=new ActiveXObject("Microsoft.XMLDOM");c.async=!1;c.loadXML(b);a=c}}var b={Header:{}},n=a.getElementsByTagName("Header")[0],d;n||(n=a.getElementsByTagName("a:Header")[0]);if(!n)return null;for(c=0;c=m.MaxActiveEnumsCount||0==m.PendingEnums.length?c():(a=m.PendingEnums.shift(), -m.Enum(a[0],a[1],a[2]),e(0))}function q(a,b,n,d,h,e,z){m.PendingBatchOperations-=2;var C=b.shift(),g=m.Enum;"*"==C[0]&&(g=m.Get,C=C.substring(1));g(C,function(h,C,g,l,F){F[2][C]={response:null==g?null:g.Body,responses:g,status:l};0==F[1].length||401==l||1!=e&&200!=l&&400!=l?(m.PendingBatchOperations-=2*b.length,c(),n(m,a,F[2],l,d)):(c(),q(a,b,n,d,F[2],z))},[a,b,h],z);c()}function k(a){a.names.length<=a.current?a.callback(m,a.name,a.responses,200,a.tag):(m.wsman.ExecGet(m.CompleteName(a.names[a.current]), -function(b,c,n,d){null==n||200!=d?a.callback(m,a.name,null,d,a.tag):(a.responses[n.Header.Method]=n,k(a))},a.pri),a.current++);c()}function v(a,b,c,d,h){if(200!=d||"0"!=c.Body.ReturnValue)h[0](m,null,h[2]);else m.AMT_MessageLog_GetRecords(c.Body.IterationIdentifier,390,n,h)}function n(a,b,c,d,h){if(200!=d||"0"!=c.Body.ReturnValue)h[0](m,null,h[2]);else{var e,z,C;b=h[2];d=new Date;var g=c.Body.RecordArray;"string"===typeof g&&(c.Body.RecordArray=[c.Body.RecordArray]);for(e in g){a=null;try{a=window.atob(g[e])}catch(l){}if(null!= -a&&(z=ReadIntX(a,0),0z)){C={DeviceAddress:a.charCodeAt(4),EventSensorType:a.charCodeAt(5),EventType:a.charCodeAt(6),EventOffset:a.charCodeAt(7),EventSourceType:a.charCodeAt(8),EventSeverity:a.charCodeAt(9),SensorNumber:a.charCodeAt(10),Entity:a.charCodeAt(11),EntityInstance:a.charCodeAt(12),EventData:[],Time:new Date(1E3*(z+60*d.getTimezoneOffset()))};for(z=13;21>z;z++)C.EventData.push(a.charCodeAt(z));C.EntityStr=x[C.Entity];C.Desc=p(C.EventSensorType,C.EventOffset,C.EventData,C.Entity); -C.EntityStr||(C.EntityStr="Unknown");b.push(C)}}if(1!=c.Body.NoMoreRecords)m.AMT_MessageLog_GetRecords(c.Body.IterationIdentifier,390,n,[h[0],b,h[2]]);else h[0](m,b,h[2])}}function p(a,b,c,n){if(15==a)return 235==c[0]?"Invalid Data":0==b?l[c[1]]:g[c[1]];if(18==a&&170==c[0])return"Agent watchdog "+char2hex(c[4])+char2hex(c[3])+char2hex(c[2])+char2hex(c[1])+"-"+char2hex(c[6])+char2hex(c[5])+"-... changed to "+m.WatchdogCurrentStates[c[7]];if(5==a&&0==b)return"Case intrusion";if(192==a&&0==b&&170==c[0]&& +77,82);c.RedirectStartIder=String.fromCharCode(16,0,0,0,73,68,69,82);return c},WsmanStackCreateService=function(b,c,a,d,e,g){function l(a){for(var b,c={},p=0;p'+a.InstanceID+"";var b="",c;for(c in a)if(a.hasOwnProperty(c)){b+=''; +if(a[c].ReferenceParameters){var b=b+"",b=b+(""+a[c].Address+""+a[c].ReferenceParameters.ResourceURI+""),p=a[c].ReferenceParameters.SelectorSet.Selector;if(Array.isArray(p))for(var d=0;d"+p[d].Value+"";else b+=""+p.Value+"";b+=""}else b+=a[c]; +b+=""}return b+""}var n={NextMessageId:1,Address:"/wsman"};n.comm=CreateWsmanComm(b,c,a,d,e,g);n.PerformAjax=function(a,b,c,p,d){null==d&&(d="");n.comm.PerformAjax('
"+a,function(a,c,p){200!=c?b(n,null,{Header:{HttpError:c}},c,p):(a=n.ParseWsman(a))&&null!=a?b(n,a.Header.ResourceURI,a,200,p):b(n,null,{Header:{HttpError:c}},601,p)},c,p)};n.CancelAllQueries=function(a){n.comm.CancelAllQueries(a)};n.GetNameFromUrl=function(a){var b=a.lastIndexOf("/");return-1==b?a:a.substring(b+1)};n.ExecSubscribe=function(a,b,c,d,e,h,K,r,E,A){var B="",I="";r="";null!=E&&null!=A&&(B='http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken'+ +E+''+A+"",I='');null!=r&&(r=""+r+"");"PushWithAck"==b?b="dmtf.org/wbem/wsman/1/wsman/PushWithAck":"Push"==b&&(b="xmlsoap.org/ws/2004/08/eventing/DeliveryModes/Push"); +a="http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe"+n.Address+""+a+""+n.NextMessageId++ +"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"+p(K)+B+'
'+c+""+r+""+I+"";n.PerformAjax(a+"
",d,e, +h,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:m="http://x.com"')};n.ExecUnSubscribe=function(a,b,c,d,e){a="http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe"+n.Address+""+a+""+n.NextMessageId++ +"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"+p(e)+"";n.PerformAjax(a+"",b,c,d,'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"')}; +n.ExecPut=function(a,b,c,d,e,h){h="http://schemas.xmlsoap.org/ws/2004/09/transfer/Put"+n.Address+""+a+""+n.NextMessageId++ +"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60.000S"+p(h)+"";if(a&&null!=b){var K=n.GetNameFromUrl(a);a="';for(var r in b)if(b.hasOwnProperty(r)&& +0!==r.indexOf("__")&&0!==r.indexOf("@")&&null!=b[r]&&"function"!==typeof b[r])if("object"===typeof b[r]&&b[r].ReferenceParameters){a+=""+b[r].Address+""+b[r].ReferenceParameters.ResourceURI+"";var E=b[r].ReferenceParameters.SelectorSet.Selector;if(Array.isArray(E))for(var A=0;A"+E[A].Value+"";else a+=""+E.Value+""; +a+=""}else if(Array.isArray(b[r]))for(A=0;A"+b[r][A].toString()+"";else a+=""+b[r].toString()+"";b=a+("")}else b="";n.PerformAjax(h+b+"",c,d,e)};n.ExecCreate=function(a,b,c,d,e,h){var K=n.GetNameFromUrl(a);a="http://schemas.xmlsoap.org/ws/2004/09/transfer/Create"+n.Address+""+a+""+n.NextMessageId++ + +"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S"+p(h)+"';for(var r in b)a+=""+b[r]+"";n.PerformAjax(a+"",c,d,e)};n.ExecDelete=function(a,b,c,d,e){a="http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete"+n.Address+""+a+""+n.NextMessageId++ + +"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S"+p(b)+"";n.PerformAjax(a,c,d,e)};n.ExecGet=function(a,b,c,p){n.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get"+n.Address+""+a+""+n.NextMessageId++ +"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S", +b,c,p)};n.ExecMethod=function(a,b,c,p,d,e,K){var r="",E;for(E in c)if(null!=c[E])if(Array.isArray(c[E]))for(var A in c[E])r+=""+c[E][A]+"";else r+=""+c[E]+"";n.ExecMethodXml(a,b,r,p,d,e,K)};n.ExecMethodXml=function(a,b,c,d,e,h,K){n.PerformAjax(a+"/"+b+""+n.Address+""+a+""+n.NextMessageId++ +"http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S"+ +p(K)+"'+c+"",d,e,h)};n.ExecEnum=function(a,b,c,p){n.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate"+n.Address+""+a+""+n.NextMessageId++ +'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S', +b,c,p)};n.ExecPull=function(a,b,c,p,d){n.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull"+n.Address+""+a+""+n.NextMessageId++ +'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymousPT60S'+b+"", +c,p,d)};n.ParseWsman=function(a){try{if(!a.childNodes){var b=a;if(window.DOMParser)a=(new DOMParser).parseFromString(b,"text/xml");else{var c=new ActiveXObject("Microsoft.XMLDOM");c.async=!1;c.loadXML(b);a=c}}var b={Header:{}},p=a.getElementsByTagName("Header")[0],d;p||(p=a.getElementsByTagName("a:Header")[0]);if(!p)return null;for(c=0;c=m.MaxActiveEnumsCount||0==m.PendingEnums.length?c():(a=m.PendingEnums.shift(), +m.Enum(a[0],a[1],a[2]),e(0))}function g(a,b,p,d,e,k,z){m.PendingBatchOperations-=2;var x=b.shift(),h=m.Enum;"*"==x[0]&&(h=m.Get,x=x.substring(1));h(x,function(e,x,h,C,r){r[2][x]={response:null==h?null:h.Body,responses:h,status:C};0==r[1].length||401==C||1!=k&&200!=C&&400!=C?(m.PendingBatchOperations-=2*b.length,c(),p(m,a,r[2],C,d)):(c(),g(a,b,p,d,r[2],z))},[a,b,e],z);c()}function l(a){a.names.length<=a.current?a.callback(m,a.name,a.responses,200,a.tag):(m.wsman.ExecGet(m.CompleteName(a.names[a.current]), +function(b,c,p,d){null==p||200!=d?a.callback(m,a.name,null,d,a.tag):(a.responses[p.Header.Method]=p,l(a))},a.pri),a.current++);c()}function u(a,b,c,d,e){if(200!=d||"0"!=c.Body.ReturnValue)e[0](m,null,e[2]);else m.AMT_MessageLog_GetRecords(c.Body.IterationIdentifier,390,p,e)}function p(a,b,c,d,e){if(200!=d||"0"!=c.Body.ReturnValue)e[0](m,null,e[2]);else{var k,z,x;b=e[2];d=new Date;var h=c.Body.RecordArray;"string"===typeof h&&(c.Body.RecordArray=[c.Body.RecordArray]);for(k in h){a=null;try{a=window.atob(h[k])}catch(r){}if(null!= +a&&(z=ReadIntX(a,0),0z)){x={DeviceAddress:a.charCodeAt(4),EventSensorType:a.charCodeAt(5),EventType:a.charCodeAt(6),EventOffset:a.charCodeAt(7),EventSourceType:a.charCodeAt(8),EventSeverity:a.charCodeAt(9),SensorNumber:a.charCodeAt(10),Entity:a.charCodeAt(11),EntityInstance:a.charCodeAt(12),EventData:[],Time:new Date(1E3*(z+60*d.getTimezoneOffset()))};for(z=13;21>z;z++)x.EventData.push(a.charCodeAt(z));x.EntityStr=K[x.Entity];x.Desc=n(x.EventSensorType,x.EventOffset,x.EventData,x.Entity); +x.EntityStr||(x.EntityStr="Unknown");b.push(x)}}if(1!=c.Body.NoMoreRecords)m.AMT_MessageLog_GetRecords(c.Body.IterationIdentifier,390,p,[e[0],b,e[2]]);else e[0](m,b,e[2])}}function n(a,b,c,p){if(15==a)return 235==c[0]?"Invalid Data":0==b?y[c[1]]:h[c[1]];if(18==a&&170==c[0])return"Agent watchdog "+char2hex(c[4])+char2hex(c[3])+char2hex(c[2])+char2hex(c[1])+"-"+char2hex(c[6])+char2hex(c[5])+"-... changed to "+m.WatchdogCurrentStates[c[7]];if(5==a&&0==b)return"Case intrusion";if(192==a&&0==b&&170==c[0]&& 48==c[1]){if(0==c[2])return"A remote Serial Over LAN session was established.";if(1==c[2])return"Remote Serial Over LAN session finished. User control was restored.";if(2==c[2])return"A remote IDE-Redirection session was established.";if(3==c[2])return"Remote IDE-Redirection session finished. User control was restored."}if(36==a)return a=(c[1]<<24)+(c[2]<<16)+(c[3]<<8)+c[4],b="#"+c[0],170==c[0]&&(b="wired"),4294967293==a?"All received packet filter was matched on "+b+" interface.":4294967292==a?"All outbound packet filter was matched on "+ b+" interface.":4294967290==a?"Spoofed packet filter was matched on "+b+" interface.":"Filter "+a+" was matched on "+b+" interface.";if(192==a)return 0==c[2]?"Security policy invoked. Some or all network traffic (TX) was stopped.":2==c[2]?"Security policy invoked. Some or all network traffic (RX) was stopped.":"Security policy invoked.";if(193==a){if(170==c[0]&&48==c[1]&&0==c[2]&&0==c[3])return"User request for remote connection.";if(170==c[0]&&32==c[1]&&3==c[2]&&1==c[3])return"EAC error: attempt to get posture while NAC in Intel\ufffd AMT is disabled."; -if(170==c[0]&&32==c[1]&&4==c[2]&&0==c[3])return"Certificate revoked. "}return 6==a?"Authentication failed "+(c[1]+(c[2]<<8))+" times. The system may be under attack.":30==a?"No bootable media":32==a?"Operating system lockup or power interrupt":35==a?"System boot failure":37==a?"System firmware started (at least one CPU is properly executing).":"Unknown Sensor Type #"+a}function h(a,b,c,n,d){if(200!=n)d[0](m,[],n);else{var e,z,C=d[1],g=new Date,l;if(0Local",e=5);3==b.InitiatorType&&(b.Initiator="KVM Default Port",e=5);l=ReadInt(a,e);b.Time=new Date(1E3*(l+60*g.getTimezoneOffset()));e+=4;b.MCLocationType=a.charCodeAt(e++);l=a.charCodeAt(e++);b.NetAddress=a.substring(e,e+l);e+=l;l=a.charCodeAt(e++);b.Ex=a.substring(e,e+l);b.ExStr=m.GetAuditLogExtendedDataStr(100*b.AuditAppID+b.EventID,b.Ex);C.push(b)}if(c.Body.TotalRecordCount>C.length)m.AMT_AuditLog_ReadRecords(C.length+1,h,[d[0],C]); -else d[0](m,C,n)}}var m={};m.wsman=b;m.pfx=["http://intel.com/wbem/wscim/1/amt-schema/1/","http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/","http://intel.com/wbem/wscim/1/ips-schema/1/"];m.PendingEnums=[];m.PendingBatchOperations=0;m.ActiveEnumsCount=0;m.MaxActiveEnumsCount=1;m.onProcessChanged=null;var w=0,B=0;m.GetPendingActions=function(){return 2*m.PendingEnums.length+m.ActiveEnumsCount+m.wsman.comm.PendingAjax.length+m.wsman.comm.ActiveAjaxCount+m.PendingBatchOperations};m.Subscribe=function(a, -b,n,d,h,e,z,C,g,l){m.wsman.ExecSubscribe(m.CompleteName(a),b,n,function(b,n,e,y){c();d(m,a,e,y,h)},0,e,z,C,g,l);c()};m.UnSubscribe=function(a,b,n,d,h){m.wsman.ExecUnSubscribe(m.CompleteName(a),function(d,h,e,g){c();b(m,a,e,g,n)},0,d,h);c()};m.Get=function(a,b,n,d){m.wsman.ExecGet(m.CompleteName(a),function(d,h,e,C){c();b(m,a,e,C,n)},0,d);c()};m.Put=function(a,b,n,d,h,e){m.wsman.ExecPut(m.CompleteName(a),b,function(b,h,e,g){c();n(m,a,e,g,d)},0,h,e);c()};m.Create=function(a,b,n,d,h){m.wsman.ExecCreate(m.CompleteName(a), -b,function(b,h,e,g){c();n(m,a,e,g,d)},0,h);c()};m.Delete=function(a,b,n,d,h){m.wsman.ExecDelete(m.CompleteName(a),b,function(b,h,e,g){c();n(m,a,e,g,d)},0,h);c()};m.Exec=function(a,b,n,d,h,e,z){m.wsman.ExecMethod(m.CompleteName(a),b,n,function(b,n,e,z){c();d(m,a,m.CompleteExecResponse(e),z,h)},0,e,z);c()};m.ExecWithXml=function(a,b,n,d,h,e,z){m.wsman.ExecMethodXml(m.CompleteName(a),b,execArgumentsToXml(n),function(b,n,e,z){c();d(m,a,m.CompleteExecResponse(e),z,h)},0,e,z);c()};m.Enum=function(b,n,d, -h){m.ActiveEnumsCountLocal",e=5);3==b.InitiatorType&&(b.Initiator="KVM Default Port",e=5);h=ReadInt(a,e);b.Time=new Date(1E3*(h+60*k.getTimezoneOffset()));e+=4;b.MCLocationType=a.charCodeAt(e++);h=a.charCodeAt(e++);b.NetAddress=a.substring(e,e+h);e+=h;h=a.charCodeAt(e++);b.Ex=a.substring(e,e+h);b.ExStr=m.GetAuditLogExtendedDataStr(100*b.AuditAppID+b.EventID,b.Ex);x.push(b)}if(c.Body.TotalRecordCount>x.length)m.AMT_AuditLog_ReadRecords(x.length+1,w,[d[0],x]); +else d[0](m,x,p)}}var m={};m.wsman=b;m.pfx=["http://intel.com/wbem/wscim/1/amt-schema/1/","http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/","http://intel.com/wbem/wscim/1/ips-schema/1/"];m.PendingEnums=[];m.PendingBatchOperations=0;m.ActiveEnumsCount=0;m.MaxActiveEnumsCount=1;m.onProcessChanged=null;var v=0,k=0;m.GetPendingActions=function(){return 2*m.PendingEnums.length+m.ActiveEnumsCount+m.wsman.comm.PendingAjax.length+m.wsman.comm.ActiveAjaxCount+m.PendingBatchOperations};m.Subscribe=function(a, +b,p,d,e,k,z,x,h,r){m.wsman.ExecSubscribe(m.CompleteName(a),b,p,function(b,p,B,z){c();d(m,a,B,z,e)},0,k,z,x,h,r);c()};m.UnSubscribe=function(a,b,p,d,e){m.wsman.ExecUnSubscribe(m.CompleteName(a),function(d,e,x,k){c();b(m,a,x,k,p)},0,d,e);c()};m.Get=function(a,b,p,d){m.wsman.ExecGet(m.CompleteName(a),function(d,e,z,x){c();b(m,a,z,x,p)},0,d);c()};m.Put=function(a,b,p,d,e,k){m.wsman.ExecPut(m.CompleteName(a),b,function(b,e,k,h){c();p(m,a,k,h,d)},0,e,k);c()};m.Create=function(a,b,p,d,e){m.wsman.ExecCreate(m.CompleteName(a), +b,function(b,e,x,k){c();p(m,a,x,k,d)},0,e);c()};m.Delete=function(a,b,p,d,e){m.wsman.ExecDelete(m.CompleteName(a),b,function(b,e,x,k){c();p(m,a,x,k,d)},0,e);c()};m.Exec=function(a,b,p,d,e,k,z){m.wsman.ExecMethod(m.CompleteName(a),b,p,function(b,p,B,z){c();d(m,a,m.CompleteExecResponse(B),z,e)},0,k,z);c()};m.ExecWithXml=function(a,b,p,d,e,k,z){m.wsman.ExecMethodXml(m.CompleteName(a),b,execArgumentsToXml(p),function(b,p,B,z){c();d(m,a,m.CompleteExecResponse(B),z,e)},0,k,z);c()};m.Enum=function(b,p,d, +e){m.ActiveEnumsCounthttp://schemas.xmlsoap.org/ws/2004/08/addressinghttp://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystemCIM_ComputerSystemManagedSystem', null,null,b)};m.SetBootConfigRole=function(a,b){m.CIM_BootService_SetBootConfigRole('
http://schemas.xmlsoap.org/ws/2004/08/addressing
http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_BootConfigSettingIntel(r) AMT: Boot Configuration 0', -a,b)};m.CancelAllQueries=function(a){m.wsman.CancelAllQueries(a)};m.AMT_AgentPresenceWatchdog_RegisterAgent=function(a){m.Exec("AMT_AgentPresenceWatchdog","RegisterAgent",{},a)};m.AMT_AgentPresenceWatchdog_AssertPresence=function(a,b){m.Exec("AMT_AgentPresenceWatchdog","AssertPresence",{SequenceNumber:a},b)};m.AMT_AgentPresenceWatchdog_AssertShutdown=function(a,b){m.Exec("AMT_AgentPresenceWatchdog","AssertShutdown",{SequenceNumber:a},b)};m.AMT_AgentPresenceWatchdog_AddAction=function(a,b,c,n,d,h, -e,C,g){m.Exec("AMT_AgentPresenceWatchdog","AddAction",{OldState:a,NewState:b,EventOnTransition:c,ActionSd:n,ActionEac:d},h,e,C,g)};m.AMT_AgentPresenceWatchdog_DeleteAllActions=function(a,b,c,n){m.Exec("AMT_AgentPresenceWatchdog","DeleteAllActions",{},a,b,c,n)};m.AMT_AgentPresenceWatchdogAction_GetActionEac=function(a){m.Exec("AMT_AgentPresenceWatchdogAction","GetActionEac",{},a)};m.AMT_AgentPresenceWatchdogVA_RegisterAgent=function(a){m.Exec("AMT_AgentPresenceWatchdogVA","RegisterAgent",{},a)};m.AMT_AgentPresenceWatchdogVA_AssertPresence= -function(a,b){m.Exec("AMT_AgentPresenceWatchdogVA","AssertPresence",{SequenceNumber:a},b)};m.AMT_AgentPresenceWatchdogVA_AssertShutdown=function(a,b){m.Exec("AMT_AgentPresenceWatchdogVA","AssertShutdown",{SequenceNumber:a},b)};m.AMT_AgentPresenceWatchdogVA_AddAction=function(a,b,c,n,d,h){m.Exec("AMT_AgentPresenceWatchdogVA","AddAction",{OldState:a,NewState:b,EventOnTransition:c,ActionSd:n,ActionEac:d},h)};m.AMT_AgentPresenceWatchdogVA_DeleteAllActions=function(a,b){m.Exec("AMT_AgentPresenceWatchdogVA", -"DeleteAllActions",{_method_dummy:a},b)};m.AMT_AuditLog_ClearLog=function(a){m.Exec("AMT_AuditLog","ClearLog",{},a)};m.AMT_AuditLog_RequestStateChange=function(a,b,c){m.Exec("AMT_AuditLog","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.AMT_AuditLog_ReadRecords=function(a,b,c){m.Exec("AMT_AuditLog","ReadRecords",{StartIndex:a},b,c)};m.AMT_AuditLog_SetAuditLock=function(a,b,c,n){m.Exec("AMT_AuditLog","SetAuditLock",{LockTimeoutInSeconds:a,Flag:b,Handle:c},n)};m.AMT_AuditLog_ExportAuditLogSignature= -function(a,b){m.Exec("AMT_AuditLog","ExportAuditLogSignature",{SigningMechanism:a},b)};m.AMT_AuditLog_SetSigningKeyMaterial=function(a,b,c,n,d){m.Exec("AMT_AuditLog","SetSigningKeyMaterial",{SigningMechanismType:a,SigningKey:b,LengthOfCertificates:c,Certificates:n},d)};m.AMT_AuditPolicyRule_SetAuditPolicy=function(a,b,c,n,d){m.Exec("AMT_AuditPolicyRule","SetAuditPolicy",{Enable:a,AuditedAppID:b,EventID:c,PolicyType:n},d)};m.AMT_AuditPolicyRule_SetAuditPolicyBulk=function(a,b,c,n,d){m.Exec("AMT_AuditPolicyRule", -"SetAuditPolicyBulk",{Enable:a,AuditedAppID:b,EventID:c,PolicyType:n},d)};m.AMT_AuthorizationService_AddUserAclEntryEx=function(a,b,c,n,d,h){m.Exec("AMT_AuthorizationService","AddUserAclEntryEx",{DigestUsername:a,DigestPassword:b,KerberosUserSid:c,AccessPermission:n,Realms:d},h)};m.AMT_AuthorizationService_EnumerateUserAclEntries=function(a,b){m.Exec("AMT_AuthorizationService","EnumerateUserAclEntries",{StartIndex:a},b)};m.AMT_AuthorizationService_GetUserAclEntryEx=function(a,b,c){m.Exec("AMT_AuthorizationService", -"GetUserAclEntryEx",{Handle:a},b,c)};m.AMT_AuthorizationService_UpdateUserAclEntryEx=function(a,b,c,n,d,h,e){m.Exec("AMT_AuthorizationService","UpdateUserAclEntryEx",{Handle:a,DigestUsername:b,DigestPassword:c,KerberosUserSid:n,AccessPermission:d,Realms:h},e)};m.AMT_AuthorizationService_RemoveUserAclEntry=function(a,b){m.Exec("AMT_AuthorizationService","RemoveUserAclEntry",{Handle:a},b)};m.AMT_AuthorizationService_SetAdminAclEntryEx=function(a,b,c){m.Exec("AMT_AuthorizationService","SetAdminAclEntryEx", -{Username:a,DigestPassword:b},c)};m.AMT_AuthorizationService_GetAdminAclEntry=function(a){m.Exec("AMT_AuthorizationService","GetAdminAclEntry",{},a)};m.AMT_AuthorizationService_GetAdminAclEntryStatus=function(a){m.Exec("AMT_AuthorizationService","GetAdminAclEntryStatus",{},a)};m.AMT_AuthorizationService_GetAdminNetAclEntryStatus=function(a){m.Exec("AMT_AuthorizationService","GetAdminNetAclEntryStatus",{},a)};m.AMT_AuthorizationService_SetAclEnabledState=function(a,b,c,n){m.Exec("AMT_AuthorizationService", -"SetAclEnabledState",{Handle:a,Enabled:b},c,n)};m.AMT_AuthorizationService_GetAclEnabledState=function(a,b,c){m.Exec("AMT_AuthorizationService","GetAclEnabledState",{Handle:a},b,c)};m.AMT_EndpointAccessControlService_RequestStateChange=function(a,b,c){m.Exec("AMT_EndpointAccessControlService","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.AMT_EndpointAccessControlService_GetPosture=function(a,b){m.Exec("AMT_EndpointAccessControlService","GetPosture",{PostureType:a},b)};m.AMT_EndpointAccessControlService_GetPostureHash= +a,b)};m.CancelAllQueries=function(a){m.wsman.CancelAllQueries(a)};m.AMT_AgentPresenceWatchdog_RegisterAgent=function(a){m.Exec("AMT_AgentPresenceWatchdog","RegisterAgent",{},a)};m.AMT_AgentPresenceWatchdog_AssertPresence=function(a,b){m.Exec("AMT_AgentPresenceWatchdog","AssertPresence",{SequenceNumber:a},b)};m.AMT_AgentPresenceWatchdog_AssertShutdown=function(a,b){m.Exec("AMT_AgentPresenceWatchdog","AssertShutdown",{SequenceNumber:a},b)};m.AMT_AgentPresenceWatchdog_AddAction=function(a,b,c,p,d,e, +z,x,k){m.Exec("AMT_AgentPresenceWatchdog","AddAction",{OldState:a,NewState:b,EventOnTransition:c,ActionSd:p,ActionEac:d},e,z,x,k)};m.AMT_AgentPresenceWatchdog_DeleteAllActions=function(a,b,c,p){m.Exec("AMT_AgentPresenceWatchdog","DeleteAllActions",{},a,b,c,p)};m.AMT_AgentPresenceWatchdogAction_GetActionEac=function(a){m.Exec("AMT_AgentPresenceWatchdogAction","GetActionEac",{},a)};m.AMT_AgentPresenceWatchdogVA_RegisterAgent=function(a){m.Exec("AMT_AgentPresenceWatchdogVA","RegisterAgent",{},a)};m.AMT_AgentPresenceWatchdogVA_AssertPresence= +function(a,b){m.Exec("AMT_AgentPresenceWatchdogVA","AssertPresence",{SequenceNumber:a},b)};m.AMT_AgentPresenceWatchdogVA_AssertShutdown=function(a,b){m.Exec("AMT_AgentPresenceWatchdogVA","AssertShutdown",{SequenceNumber:a},b)};m.AMT_AgentPresenceWatchdogVA_AddAction=function(a,b,c,p,d,e){m.Exec("AMT_AgentPresenceWatchdogVA","AddAction",{OldState:a,NewState:b,EventOnTransition:c,ActionSd:p,ActionEac:d},e)};m.AMT_AgentPresenceWatchdogVA_DeleteAllActions=function(a,b){m.Exec("AMT_AgentPresenceWatchdogVA", +"DeleteAllActions",{_method_dummy:a},b)};m.AMT_AuditLog_ClearLog=function(a){m.Exec("AMT_AuditLog","ClearLog",{},a)};m.AMT_AuditLog_RequestStateChange=function(a,b,c){m.Exec("AMT_AuditLog","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.AMT_AuditLog_ReadRecords=function(a,b,c){m.Exec("AMT_AuditLog","ReadRecords",{StartIndex:a},b,c)};m.AMT_AuditLog_SetAuditLock=function(a,b,c,p){m.Exec("AMT_AuditLog","SetAuditLock",{LockTimeoutInSeconds:a,Flag:b,Handle:c},p)};m.AMT_AuditLog_ExportAuditLogSignature= +function(a,b){m.Exec("AMT_AuditLog","ExportAuditLogSignature",{SigningMechanism:a},b)};m.AMT_AuditLog_SetSigningKeyMaterial=function(a,b,c,p,d){m.Exec("AMT_AuditLog","SetSigningKeyMaterial",{SigningMechanismType:a,SigningKey:b,LengthOfCertificates:c,Certificates:p},d)};m.AMT_AuditPolicyRule_SetAuditPolicy=function(a,b,c,p,d){m.Exec("AMT_AuditPolicyRule","SetAuditPolicy",{Enable:a,AuditedAppID:b,EventID:c,PolicyType:p},d)};m.AMT_AuditPolicyRule_SetAuditPolicyBulk=function(a,b,c,p,d){m.Exec("AMT_AuditPolicyRule", +"SetAuditPolicyBulk",{Enable:a,AuditedAppID:b,EventID:c,PolicyType:p},d)};m.AMT_AuthorizationService_AddUserAclEntryEx=function(a,b,c,p,d,e){m.Exec("AMT_AuthorizationService","AddUserAclEntryEx",{DigestUsername:a,DigestPassword:b,KerberosUserSid:c,AccessPermission:p,Realms:d},e)};m.AMT_AuthorizationService_EnumerateUserAclEntries=function(a,b){m.Exec("AMT_AuthorizationService","EnumerateUserAclEntries",{StartIndex:a},b)};m.AMT_AuthorizationService_GetUserAclEntryEx=function(a,b,c){m.Exec("AMT_AuthorizationService", +"GetUserAclEntryEx",{Handle:a},b,c)};m.AMT_AuthorizationService_UpdateUserAclEntryEx=function(a,b,c,p,d,e,z){m.Exec("AMT_AuthorizationService","UpdateUserAclEntryEx",{Handle:a,DigestUsername:b,DigestPassword:c,KerberosUserSid:p,AccessPermission:d,Realms:e},z)};m.AMT_AuthorizationService_RemoveUserAclEntry=function(a,b){m.Exec("AMT_AuthorizationService","RemoveUserAclEntry",{Handle:a},b)};m.AMT_AuthorizationService_SetAdminAclEntryEx=function(a,b,c){m.Exec("AMT_AuthorizationService","SetAdminAclEntryEx", +{Username:a,DigestPassword:b},c)};m.AMT_AuthorizationService_GetAdminAclEntry=function(a){m.Exec("AMT_AuthorizationService","GetAdminAclEntry",{},a)};m.AMT_AuthorizationService_GetAdminAclEntryStatus=function(a){m.Exec("AMT_AuthorizationService","GetAdminAclEntryStatus",{},a)};m.AMT_AuthorizationService_GetAdminNetAclEntryStatus=function(a){m.Exec("AMT_AuthorizationService","GetAdminNetAclEntryStatus",{},a)};m.AMT_AuthorizationService_SetAclEnabledState=function(a,b,c,p){m.Exec("AMT_AuthorizationService", +"SetAclEnabledState",{Handle:a,Enabled:b},c,p)};m.AMT_AuthorizationService_GetAclEnabledState=function(a,b,c){m.Exec("AMT_AuthorizationService","GetAclEnabledState",{Handle:a},b,c)};m.AMT_EndpointAccessControlService_RequestStateChange=function(a,b,c){m.Exec("AMT_EndpointAccessControlService","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.AMT_EndpointAccessControlService_GetPosture=function(a,b){m.Exec("AMT_EndpointAccessControlService","GetPosture",{PostureType:a},b)};m.AMT_EndpointAccessControlService_GetPostureHash= function(a,b){m.Exec("AMT_EndpointAccessControlService","GetPostureHash",{PostureType:a},b)};m.AMT_EndpointAccessControlService_UpdatePostureState=function(a,b){m.Exec("AMT_EndpointAccessControlService","UpdatePostureState",{UpdateType:a},b)};m.AMT_EndpointAccessControlService_GetEacOptions=function(a){m.Exec("AMT_EndpointAccessControlService","GetEacOptions",{},a)};m.AMT_EndpointAccessControlService_SetEacOptions=function(a,b,c){m.Exec("AMT_EndpointAccessControlService","SetEacOptions",{EacVendors:a, PostureHashAlgorithm:b},c)};m.AMT_EnvironmentDetectionSettingData_SetSystemDefensePolicy=function(a,b){m.Exec("AMT_EnvironmentDetectionSettingData","SetSystemDefensePolicy",{Policy:a},b)};m.AMT_EnvironmentDetectionSettingData_EnableVpnRouting=function(a,b){m.Exec("AMT_EnvironmentDetectionSettingData","EnableVpnRouting",{Enable:a},b)};m.AMT_EthernetPortSettings_SetLinkPreference=function(a,b,c){m.Exec("AMT_EthernetPortSettings","SetLinkPreference",{LinkPreference:a,Timeout:b},c)};m.AMT_HeuristicPacketFilterStatistics_ResetSelectedStats= function(a,b){m.Exec("AMT_HeuristicPacketFilterStatistics","ResetSelectedStats",{SelectedStatistics:a},b)};m.AMT_KerberosSettingData_GetCredentialCacheState=function(a){m.Exec("AMT_KerberosSettingData","GetCredentialCacheState",{},a)};m.AMT_KerberosSettingData_SetCredentialCacheState=function(a,b){m.Exec("AMT_KerberosSettingData","SetCredentialCacheState",{Enable:a},b)};m.AMT_MessageLog_CancelIteration=function(a,b){m.Exec("AMT_MessageLog","CancelIteration",{IterationIdentifier:a},b)};m.AMT_MessageLog_RequestStateChange= -function(a,b,c){m.Exec("AMT_MessageLog","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.AMT_MessageLog_ClearLog=function(a){m.Exec("AMT_MessageLog","ClearLog",{},a)};m.AMT_MessageLog_GetRecords=function(a,b,c,n){m.Exec("AMT_MessageLog","GetRecords",{IterationIdentifier:a,MaxReadRecords:b},c,n)};m.AMT_MessageLog_GetRecord=function(a,b,c){m.Exec("AMT_MessageLog","GetRecord",{IterationIdentifier:a,PositionToNext:b},c)};m.AMT_MessageLog_PositionAtRecord=function(a,b,c,n){m.Exec("AMT_MessageLog", -"PositionAtRecord",{IterationIdentifier:a,MoveAbsolute:b,RecordNumber:c},n)};m.AMT_MessageLog_PositionToFirstRecord=function(a,b){m.Exec("AMT_MessageLog","PositionToFirstRecord",{},a,b)};m.AMT_MessageLog_FreezeLog=function(a,b){m.Exec("AMT_MessageLog","FreezeLog",{Freeze:a},b)};m.AMT_PublicKeyManagementService_AddCRL=function(a,b,c){m.Exec("AMT_PublicKeyManagementService","AddCRL",{Url:a,SerialNumbers:b},c)};m.AMT_PublicKeyManagementService_ResetCRLList=function(a,b){m.Exec("AMT_PublicKeyManagementService", +function(a,b,c){m.Exec("AMT_MessageLog","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.AMT_MessageLog_ClearLog=function(a){m.Exec("AMT_MessageLog","ClearLog",{},a)};m.AMT_MessageLog_GetRecords=function(a,b,c,p){m.Exec("AMT_MessageLog","GetRecords",{IterationIdentifier:a,MaxReadRecords:b},c,p)};m.AMT_MessageLog_GetRecord=function(a,b,c){m.Exec("AMT_MessageLog","GetRecord",{IterationIdentifier:a,PositionToNext:b},c)};m.AMT_MessageLog_PositionAtRecord=function(a,b,c,p){m.Exec("AMT_MessageLog", +"PositionAtRecord",{IterationIdentifier:a,MoveAbsolute:b,RecordNumber:c},p)};m.AMT_MessageLog_PositionToFirstRecord=function(a,b){m.Exec("AMT_MessageLog","PositionToFirstRecord",{},a,b)};m.AMT_MessageLog_FreezeLog=function(a,b){m.Exec("AMT_MessageLog","FreezeLog",{Freeze:a},b)};m.AMT_PublicKeyManagementService_AddCRL=function(a,b,c){m.Exec("AMT_PublicKeyManagementService","AddCRL",{Url:a,SerialNumbers:b},c)};m.AMT_PublicKeyManagementService_ResetCRLList=function(a,b){m.Exec("AMT_PublicKeyManagementService", "ResetCRLList",{_method_dummy:a},b)};m.AMT_PublicKeyManagementService_AddCertificate=function(a,b){m.Exec("AMT_PublicKeyManagementService","AddCertificate",{CertificateBlob:a},b)};m.AMT_PublicKeyManagementService_AddTrustedRootCertificate=function(a,b){m.Exec("AMT_PublicKeyManagementService","AddTrustedRootCertificate",{CertificateBlob:a},b)};m.AMT_PublicKeyManagementService_AddKey=function(a,b){m.Exec("AMT_PublicKeyManagementService","AddKey",{KeyBlob:a},b)};m.AMT_PublicKeyManagementService_GeneratePKCS10Request= -function(a,b,c,n){m.Exec("AMT_PublicKeyManagementService","GeneratePKCS10Request",{KeyPair:a,DNName:b,Usage:c},n)};m.AMT_PublicKeyManagementService_GeneratePKCS10RequestEx=function(a,b,c,n){m.Exec("AMT_PublicKeyManagementService","GeneratePKCS10RequestEx",{KeyPair:a,SigningAlgorithm:b,NullSignedCertificateRequest:c},n)};m.AMT_PublicKeyManagementService_GenerateKeyPair=function(a,b,c){m.Exec("AMT_PublicKeyManagementService","GenerateKeyPair",{KeyAlgorithm:a,KeyLength:b},c)};m.AMT_RedirectionService_RequestStateChange= -function(a,b){m.Exec("AMT_RedirectionService","RequestStateChange",{RequestedState:a},b)};m.AMT_RedirectionService_TerminateSession=function(a,b){m.Exec("AMT_RedirectionService","TerminateSession",{SessionType:a},b)};m.AMT_RemoteAccessService_AddMpServer=function(a,b,c,n,d,h,e,C,g){m.Exec("AMT_RemoteAccessService","AddMpServer",{AccessInfo:a,InfoFormat:b,Port:c,AuthMethod:n,Certificate:d,Username:h,Password:e,CN:C},g)};m.AMT_RemoteAccessService_AddRemoteAccessPolicyRule=function(a,b,c,n,d,h){m.Exec("AMT_RemoteAccessService", -"AddRemoteAccessPolicyRule",{Trigger:a,TunnelLifeTime:b,ExtendedData:c,MpServer:n,InternalMpServer:d},h)};m.AMT_RemoteAccessService_CloseRemoteAccessConnection=function(a,b){m.Exec("AMT_RemoteAccessService","CloseRemoteAccessConnection",{_method_dummy:a},b)};m.AMT_SetupAndConfigurationService_CommitChanges=function(a,b){m.Exec("AMT_SetupAndConfigurationService","CommitChanges",{_method_dummy:a},b)};m.AMT_SetupAndConfigurationService_Unprovision=function(a,b){m.Exec("AMT_SetupAndConfigurationService", +function(a,b,c,p){m.Exec("AMT_PublicKeyManagementService","GeneratePKCS10Request",{KeyPair:a,DNName:b,Usage:c},p)};m.AMT_PublicKeyManagementService_GeneratePKCS10RequestEx=function(a,b,c,p){m.Exec("AMT_PublicKeyManagementService","GeneratePKCS10RequestEx",{KeyPair:a,SigningAlgorithm:b,NullSignedCertificateRequest:c},p)};m.AMT_PublicKeyManagementService_GenerateKeyPair=function(a,b,c){m.Exec("AMT_PublicKeyManagementService","GenerateKeyPair",{KeyAlgorithm:a,KeyLength:b},c)};m.AMT_RedirectionService_RequestStateChange= +function(a,b){m.Exec("AMT_RedirectionService","RequestStateChange",{RequestedState:a},b)};m.AMT_RedirectionService_TerminateSession=function(a,b){m.Exec("AMT_RedirectionService","TerminateSession",{SessionType:a},b)};m.AMT_RemoteAccessService_AddMpServer=function(a,b,c,p,d,e,z,x,k){m.Exec("AMT_RemoteAccessService","AddMpServer",{AccessInfo:a,InfoFormat:b,Port:c,AuthMethod:p,Certificate:d,Username:e,Password:z,CN:x},k)};m.AMT_RemoteAccessService_AddRemoteAccessPolicyRule=function(a,b,c,p,d,e){m.Exec("AMT_RemoteAccessService", +"AddRemoteAccessPolicyRule",{Trigger:a,TunnelLifeTime:b,ExtendedData:c,MpServer:p,InternalMpServer:d},e)};m.AMT_RemoteAccessService_CloseRemoteAccessConnection=function(a,b){m.Exec("AMT_RemoteAccessService","CloseRemoteAccessConnection",{_method_dummy:a},b)};m.AMT_SetupAndConfigurationService_CommitChanges=function(a,b){m.Exec("AMT_SetupAndConfigurationService","CommitChanges",{_method_dummy:a},b)};m.AMT_SetupAndConfigurationService_Unprovision=function(a,b){m.Exec("AMT_SetupAndConfigurationService", "Unprovision",{ProvisioningMode:a},b)};m.AMT_SetupAndConfigurationService_PartialUnprovision=function(a,b){m.Exec("AMT_SetupAndConfigurationService","PartialUnprovision",{_method_dummy:a},b)};m.AMT_SetupAndConfigurationService_ResetFlashWearOutProtection=function(a,b){m.Exec("AMT_SetupAndConfigurationService","ResetFlashWearOutProtection",{_method_dummy:a},b)};m.AMT_SetupAndConfigurationService_ExtendProvisioningPeriod=function(a,b){m.Exec("AMT_SetupAndConfigurationService","ExtendProvisioningPeriod", {Duration:a},b)};m.AMT_SetupAndConfigurationService_SetMEBxPassword=function(a,b){m.Exec("AMT_SetupAndConfigurationService","SetMEBxPassword",{Password:a},b)};m.AMT_SetupAndConfigurationService_SetTLSPSK=function(a,b,c){m.Exec("AMT_SetupAndConfigurationService","SetTLSPSK",{PID:a,PPS:b},c)};m.AMT_SetupAndConfigurationService_GetProvisioningAuditRecord=function(a){m.Exec("AMT_SetupAndConfigurationService","GetProvisioningAuditRecord",{},a)};m.AMT_SetupAndConfigurationService_GetUuid=function(a){m.Exec("AMT_SetupAndConfigurationService", "GetUuid",{},a)};m.AMT_SetupAndConfigurationService_GetUnprovisionBlockingComponents=function(a){m.Exec("AMT_SetupAndConfigurationService","GetUnprovisionBlockingComponents",{},a)};m.AMT_SetupAndConfigurationService_GetProvisioningAuditRecordV2=function(a){m.Exec("AMT_SetupAndConfigurationService","GetProvisioningAuditRecordV2",{},a)};m.AMT_SystemDefensePolicy_GetTimeout=function(a){m.Exec("AMT_SystemDefensePolicy","GetTimeout",{},a)};m.AMT_SystemDefensePolicy_SetTimeout=function(a,b){m.Exec("AMT_SystemDefensePolicy", -"SetTimeout",{Timeout:a},b)};m.AMT_SystemDefensePolicy_UpdateStatistics=function(a,b,c,n,d,h){m.Exec("AMT_SystemDefensePolicy","UpdateStatistics",{NetworkInterface:a,ResetOnRead:b},c,n,d,h)};m.AMT_SystemPowerScheme_SetPowerScheme=function(a,b,c){m.Exec("AMT_SystemPowerScheme","SetPowerScheme",{},a,c,0,{InstanceID:b})};m.AMT_TimeSynchronizationService_GetLowAccuracyTimeSynch=function(a,b){m.Exec("AMT_TimeSynchronizationService","GetLowAccuracyTimeSynch",{},a,b)};m.AMT_TimeSynchronizationService_SetHighAccuracyTimeSynch= -function(a,b,c,n,d){m.Exec("AMT_TimeSynchronizationService","SetHighAccuracyTimeSynch",{Ta0:a,Tm1:b,Tm2:c},n,d)};m.AMT_UserInitiatedConnectionService_RequestStateChange=function(a,b,c){m.Exec("AMT_UserInitiatedConnectionService","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.AMT_WebUIService_RequestStateChange=function(a,b,c){m.Exec("AMT_WebUIService","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.AMT_WiFiPortConfigurationService_AddWiFiSettings=function(a,b,c,n,d,h){m.ExecWithXml("AMT_WiFiPortConfigurationService", -"AddWiFiSettings",{WiFiEndpoint:a,WiFiEndpointSettingsInput:b,IEEE8021xSettingsInput:c,ClientCredential:n,CACredential:d},h)};m.AMT_WiFiPortConfigurationService_UpdateWiFiSettings=function(a,b,c,n,d,h){m.ExecWithXml("AMT_WiFiPortConfigurationService","UpdateWiFiSettings",{WiFiEndpointSettings:a,WiFiEndpointSettingsInput:b,IEEE8021xSettingsInput:c,ClientCredential:n,CACredential:d},h)};m.AMT_WiFiPortConfigurationService_DeleteAllITProfiles=function(a,b){m.Exec("AMT_WiFiPortConfigurationService","DeleteAllITProfiles", +"SetTimeout",{Timeout:a},b)};m.AMT_SystemDefensePolicy_UpdateStatistics=function(a,b,c,p,d,e){m.Exec("AMT_SystemDefensePolicy","UpdateStatistics",{NetworkInterface:a,ResetOnRead:b},c,p,d,e)};m.AMT_SystemPowerScheme_SetPowerScheme=function(a,b,c){m.Exec("AMT_SystemPowerScheme","SetPowerScheme",{},a,c,0,{InstanceID:b})};m.AMT_TimeSynchronizationService_GetLowAccuracyTimeSynch=function(a,b){m.Exec("AMT_TimeSynchronizationService","GetLowAccuracyTimeSynch",{},a,b)};m.AMT_TimeSynchronizationService_SetHighAccuracyTimeSynch= +function(a,b,c,p,d){m.Exec("AMT_TimeSynchronizationService","SetHighAccuracyTimeSynch",{Ta0:a,Tm1:b,Tm2:c},p,d)};m.AMT_UserInitiatedConnectionService_RequestStateChange=function(a,b,c){m.Exec("AMT_UserInitiatedConnectionService","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.AMT_WebUIService_RequestStateChange=function(a,b,c){m.Exec("AMT_WebUIService","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.AMT_WiFiPortConfigurationService_AddWiFiSettings=function(a,b,c,p,d,e){m.ExecWithXml("AMT_WiFiPortConfigurationService", +"AddWiFiSettings",{WiFiEndpoint:a,WiFiEndpointSettingsInput:b,IEEE8021xSettingsInput:c,ClientCredential:p,CACredential:d},e)};m.AMT_WiFiPortConfigurationService_UpdateWiFiSettings=function(a,b,c,p,d,e){m.ExecWithXml("AMT_WiFiPortConfigurationService","UpdateWiFiSettings",{WiFiEndpointSettings:a,WiFiEndpointSettingsInput:b,IEEE8021xSettingsInput:c,ClientCredential:p,CACredential:d},e)};m.AMT_WiFiPortConfigurationService_DeleteAllITProfiles=function(a,b){m.Exec("AMT_WiFiPortConfigurationService","DeleteAllITProfiles", {_method_dummy:a},b)};m.AMT_WiFiPortConfigurationService_DeleteAllUserProfiles=function(a,b){m.Exec("AMT_WiFiPortConfigurationService","DeleteAllUserProfiles",{_method_dummy:a},b)};m.CIM_Account_RequestStateChange=function(a,b,c){m.Exec("CIM_Account","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.CIM_AccountManagementService_CreateAccount=function(a,b,c){m.Exec("CIM_AccountManagementService","CreateAccount",{System:a,AccountTemplate:b},c)};m.CIM_BootConfigSetting_ChangeBootOrder=function(a, b){m.Exec("CIM_BootConfigSetting","ChangeBootOrder",{Source:a},b)};m.CIM_BootService_SetBootConfigRole=function(a,b,c){m.Exec("CIM_BootService","SetBootConfigRole",{BootConfigSetting:a,Role:b},c,0,1)};m.CIM_Card_ConnectorPower=function(a,b,c){m.Exec("CIM_Card","ConnectorPower",{Connector:a,PoweredOn:b},c)};m.CIM_Card_IsCompatible=function(a,b){m.Exec("CIM_Card","IsCompatible",{ElementToCheck:a},b)};m.CIM_Chassis_IsCompatible=function(a,b){m.Exec("CIM_Chassis","IsCompatible",{ElementToCheck:a},b)}; m.CIM_Fan_SetSpeed=function(a,b){m.Exec("CIM_Fan","SetSpeed",{DesiredSpeed:a},b)};m.CIM_KVMRedirectionSAP_RequestStateChange=function(a,b,c){m.Exec("CIM_KVMRedirectionSAP","RequestStateChange",{RequestedState:a},c)};m.CIM_MediaAccessDevice_LockMedia=function(a,b){m.Exec("CIM_MediaAccessDevice","LockMedia",{Lock:a},b)};m.CIM_MediaAccessDevice_SetPowerState=function(a,b,c){m.Exec("CIM_MediaAccessDevice","SetPowerState",{PowerState:a,Time:b},c)};m.CIM_MediaAccessDevice_Reset=function(a){m.Exec("CIM_MediaAccessDevice", "Reset",{},a)};m.CIM_MediaAccessDevice_EnableDevice=function(a,b){m.Exec("CIM_MediaAccessDevice","EnableDevice",{Enabled:a},b)};m.CIM_MediaAccessDevice_OnlineDevice=function(a,b){m.Exec("CIM_MediaAccessDevice","OnlineDevice",{Online:a},b)};m.CIM_MediaAccessDevice_QuiesceDevice=function(a,b){m.Exec("CIM_MediaAccessDevice","QuiesceDevice",{Quiesce:a},b)};m.CIM_MediaAccessDevice_SaveProperties=function(a){m.Exec("CIM_MediaAccessDevice","SaveProperties",{},a)};m.CIM_MediaAccessDevice_RestoreProperties= function(a){m.Exec("CIM_MediaAccessDevice","RestoreProperties",{},a)};m.CIM_MediaAccessDevice_RequestStateChange=function(a,b,c){m.Exec("CIM_MediaAccessDevice","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.CIM_PhysicalFrame_IsCompatible=function(a,b){m.Exec("CIM_PhysicalFrame","IsCompatible",{ElementToCheck:a},b)};m.CIM_PhysicalPackage_IsCompatible=function(a,b){m.Exec("CIM_PhysicalPackage","IsCompatible",{ElementToCheck:a},b)};m.CIM_PowerManagementService_RequestPowerStateChange= -function(a,b,c,n,d){m.Exec("CIM_PowerManagementService","RequestPowerStateChange",{PowerState:a,ManagedElement:b,Time:c,TimeoutPeriod:n},d,0,1)};m.CIM_PowerSupply_SetPowerState=function(a,b,c){m.Exec("CIM_PowerSupply","SetPowerState",{PowerState:a,Time:b},c)};m.CIM_PowerSupply_Reset=function(a){m.Exec("CIM_PowerSupply","Reset",{},a)};m.CIM_PowerSupply_EnableDevice=function(a,b){m.Exec("CIM_PowerSupply","EnableDevice",{Enabled:a},b)};m.CIM_PowerSupply_OnlineDevice=function(a,b){m.Exec("CIM_PowerSupply", +function(a,b,c,p,d){m.Exec("CIM_PowerManagementService","RequestPowerStateChange",{PowerState:a,ManagedElement:b,Time:c,TimeoutPeriod:p},d,0,1)};m.CIM_PowerSupply_SetPowerState=function(a,b,c){m.Exec("CIM_PowerSupply","SetPowerState",{PowerState:a,Time:b},c)};m.CIM_PowerSupply_Reset=function(a){m.Exec("CIM_PowerSupply","Reset",{},a)};m.CIM_PowerSupply_EnableDevice=function(a,b){m.Exec("CIM_PowerSupply","EnableDevice",{Enabled:a},b)};m.CIM_PowerSupply_OnlineDevice=function(a,b){m.Exec("CIM_PowerSupply", "OnlineDevice",{Online:a},b)};m.CIM_PowerSupply_QuiesceDevice=function(a,b){m.Exec("CIM_PowerSupply","QuiesceDevice",{Quiesce:a},b)};m.CIM_PowerSupply_SaveProperties=function(a){m.Exec("CIM_PowerSupply","SaveProperties",{},a)};m.CIM_PowerSupply_RestoreProperties=function(a){m.Exec("CIM_PowerSupply","RestoreProperties",{},a)};m.CIM_PowerSupply_RequestStateChange=function(a,b,c){m.Exec("CIM_PowerSupply","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.CIM_Processor_SetPowerState=function(a, b,c){m.Exec("CIM_Processor","SetPowerState",{PowerState:a,Time:b},c)};m.CIM_Processor_Reset=function(a){m.Exec("CIM_Processor","Reset",{},a)};m.CIM_Processor_EnableDevice=function(a,b){m.Exec("CIM_Processor","EnableDevice",{Enabled:a},b)};m.CIM_Processor_OnlineDevice=function(a,b){m.Exec("CIM_Processor","OnlineDevice",{Online:a},b)};m.CIM_Processor_QuiesceDevice=function(a,b){m.Exec("CIM_Processor","QuiesceDevice",{Quiesce:a},b)};m.CIM_Processor_SaveProperties=function(a){m.Exec("CIM_Processor","SaveProperties", {},a)};m.CIM_Processor_RestoreProperties=function(a){m.Exec("CIM_Processor","RestoreProperties",{},a)};m.CIM_Processor_RequestStateChange=function(a,b,c){m.Exec("CIM_Processor","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.CIM_RecordLog_ClearLog=function(a){m.Exec("CIM_RecordLog","ClearLog",{},a)};m.CIM_RecordLog_RequestStateChange=function(a,b,c){m.Exec("CIM_RecordLog","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.CIM_RedirectionService_RequestStateChange=function(a, @@ -138,20 +138,20 @@ b,c){m.Exec("CIM_RedirectionService","RequestStateChange",{RequestedState:a,Time "KeepAlive",{},a)};m.CIM_Watchdog_SetPowerState=function(a,b,c){m.Exec("CIM_Watchdog","SetPowerState",{PowerState:a,Time:b},c)};m.CIM_Watchdog_Reset=function(a){m.Exec("CIM_Watchdog","Reset",{},a)};m.CIM_Watchdog_EnableDevice=function(a,b){m.Exec("CIM_Watchdog","EnableDevice",{Enabled:a},b)};m.CIM_Watchdog_OnlineDevice=function(a,b){m.Exec("CIM_Watchdog","OnlineDevice",{Online:a},b)};m.CIM_Watchdog_QuiesceDevice=function(a,b){m.Exec("CIM_Watchdog","QuiesceDevice",{Quiesce:a},b)};m.CIM_Watchdog_SaveProperties= function(a){m.Exec("CIM_Watchdog","SaveProperties",{},a)};m.CIM_Watchdog_RestoreProperties=function(a){m.Exec("CIM_Watchdog","RestoreProperties",{},a)};m.CIM_Watchdog_RequestStateChange=function(a,b,c){m.Exec("CIM_Watchdog","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.CIM_WiFiPort_SetPowerState=function(a,b,c){m.Exec("CIM_WiFiPort","SetPowerState",{PowerState:a,Time:b},c)};m.CIM_WiFiPort_Reset=function(a){m.Exec("CIM_WiFiPort","Reset",{},a)};m.CIM_WiFiPort_EnableDevice=function(a, b){m.Exec("CIM_WiFiPort","EnableDevice",{Enabled:a},b)};m.CIM_WiFiPort_OnlineDevice=function(a,b){m.Exec("CIM_WiFiPort","OnlineDevice",{Online:a},b)};m.CIM_WiFiPort_QuiesceDevice=function(a,b){m.Exec("CIM_WiFiPort","QuiesceDevice",{Quiesce:a},b)};m.CIM_WiFiPort_SaveProperties=function(a){m.Exec("CIM_WiFiPort","SaveProperties",{},a)};m.CIM_WiFiPort_RestoreProperties=function(a){m.Exec("CIM_WiFiPort","RestoreProperties",{},a)};m.CIM_WiFiPort_RequestStateChange=function(a,b,c){m.Exec("CIM_WiFiPort", -"RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.IPS_HostBasedSetupService_Setup=function(a,b,c,n,d,h,e){m.Exec("IPS_HostBasedSetupService","Setup",{NetAdminPassEncryptionType:a,NetworkAdminPassword:b,McNonce:c,Certificate:n,SigningAlgorithm:d,DigitalSignature:h},e)};m.IPS_HostBasedSetupService_AddNextCertInChain=function(a,b,c,n){m.Exec("IPS_HostBasedSetupService","AddNextCertInChain",{NextCertificate:a,IsLeafCertificate:b,IsRootCertificate:c},n)};m.IPS_HostBasedSetupService_AdminSetup= -function(a,b,c,n,d,h){m.Exec("IPS_HostBasedSetupService","AdminSetup",{NetAdminPassEncryptionType:a,NetworkAdminPassword:b,McNonce:c,SigningAlgorithm:n,DigitalSignature:d},h)};m.IPS_HostBasedSetupService_UpgradeClientToAdmin=function(a,b,c,n){m.Exec("IPS_HostBasedSetupService","UpgradeClientToAdmin",{McNonce:a,SigningAlgorithm:b,DigitalSignature:c},n)};m.IPS_HostBasedSetupService_DisableClientControlMode=function(a,b){m.Exec("IPS_HostBasedSetupService","DisableClientControlMode",{_method_dummy:a}, +"RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.IPS_HostBasedSetupService_Setup=function(a,b,c,p,d,e,z){m.Exec("IPS_HostBasedSetupService","Setup",{NetAdminPassEncryptionType:a,NetworkAdminPassword:b,McNonce:c,Certificate:p,SigningAlgorithm:d,DigitalSignature:e},z)};m.IPS_HostBasedSetupService_AddNextCertInChain=function(a,b,c,p){m.Exec("IPS_HostBasedSetupService","AddNextCertInChain",{NextCertificate:a,IsLeafCertificate:b,IsRootCertificate:c},p)};m.IPS_HostBasedSetupService_AdminSetup= +function(a,b,c,p,d,e){m.Exec("IPS_HostBasedSetupService","AdminSetup",{NetAdminPassEncryptionType:a,NetworkAdminPassword:b,McNonce:c,SigningAlgorithm:p,DigitalSignature:d},e)};m.IPS_HostBasedSetupService_UpgradeClientToAdmin=function(a,b,c,p){m.Exec("IPS_HostBasedSetupService","UpgradeClientToAdmin",{McNonce:a,SigningAlgorithm:b,DigitalSignature:c},p)};m.IPS_HostBasedSetupService_DisableClientControlMode=function(a,b){m.Exec("IPS_HostBasedSetupService","DisableClientControlMode",{_method_dummy:a}, b)};m.IPS_KVMRedirectionSettingData_TerminateSession=function(a){m.Exec("IPS_KVMRedirectionSettingData","TerminateSession",{},a)};m.IPS_KVMRedirectionSettingData_DataChannelRead=function(a){m.Exec("IPS_KVMRedirectionSettingData","DataChannelRead",{},a)};m.IPS_KVMRedirectionSettingData_DataChannelWrite=function(a,b){m.Exec("IPS_KVMRedirectionSettingData","DataChannelWrite",{DataMessage:a},b)};m.IPS_OptInService_StartOptIn=function(a){m.Exec("IPS_OptInService","StartOptIn",{},a)};m.IPS_OptInService_CancelOptIn= function(a){m.Exec("IPS_OptInService","CancelOptIn",{},a)};m.IPS_OptInService_SendOptInCode=function(a,b){m.Exec("IPS_OptInService","SendOptInCode",{OptInCode:a},b)};m.IPS_OptInService_StartService=function(a){m.Exec("IPS_OptInService","StartService",{},a)};m.IPS_OptInService_StopService=function(a){m.Exec("IPS_OptInService","StopService",{},a)};m.IPS_OptInService_RequestStateChange=function(a,b,c){m.Exec("IPS_OptInService","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.IPS_ProvisioningRecordLog_RequestStateChange= function(a,b,c){m.Exec("IPS_ProvisioningRecordLog","RequestStateChange",{RequestedState:a,TimeoutPeriod:b},c)};m.IPS_ProvisioningRecordLog_ClearLog=function(a,b){m.Exec("IPS_ProvisioningRecordLog","ClearLog",{_method_dummy:a},b)};m.IPS_ScreenConfigurationService_SetSessionState=function(a,b,c){m.Exec("IPS_ScreenConfigurationService","SetSessionState",{SessionState:a,ConsecutiveRebootsNum:b},c)};m.IPS_SecIOService_RequestStateChange=function(a,b,c){m.Exec("IPS_SecIOService","RequestStateChange",{RequestedState:a, -TimeoutPeriod:b},c)};m.IPS_HTTPProxyService_AddProxyAccessPoint=function(a,b,c,n,d){m.Exec("IPS_HTTPProxyService","AddProxyAccessPoint",{AccessInfo:a,InfoFormat:b,Port:c,NetworkDnsSuffix:n},d)};m.AmtStatusToStr=function(a){return m.AmtStatusCodes[a]?m.AmtStatusCodes[a]:"UNKNOWN_ERROR"};m.AmtStatusCodes={0:"SUCCESS",1:"INTERNAL_ERROR",2:"NOT_READY",3:"INVALID_PT_MODE",4:"INVALID_MESSAGE_LENGTH",5:"TABLE_FINGERPRINT_NOT_AVAILABLE",6:"INTEGRITY_CHECK_FAILED",7:"UNSUPPORTED_ISVS_VERSION",8:"APPLICATION_NOT_REGISTERED", +TimeoutPeriod:b},c)};m.IPS_HTTPProxyService_AddProxyAccessPoint=function(a,b,c,p,d){m.Exec("IPS_HTTPProxyService","AddProxyAccessPoint",{AccessInfo:a,InfoFormat:b,Port:c,NetworkDnsSuffix:p},d)};m.AmtStatusToStr=function(a){return m.AmtStatusCodes[a]?m.AmtStatusCodes[a]:"UNKNOWN_ERROR"};m.AmtStatusCodes={0:"SUCCESS",1:"INTERNAL_ERROR",2:"NOT_READY",3:"INVALID_PT_MODE",4:"INVALID_MESSAGE_LENGTH",5:"TABLE_FINGERPRINT_NOT_AVAILABLE",6:"INTEGRITY_CHECK_FAILED",7:"UNSUPPORTED_ISVS_VERSION",8:"APPLICATION_NOT_REGISTERED", 9:"INVALID_REGISTRATION_DATA",10:"APPLICATION_DOES_NOT_EXIST",11:"NOT_ENOUGH_STORAGE",12:"INVALID_NAME",13:"BLOCK_DOES_NOT_EXIST",14:"INVALID_BYTE_OFFSET",15:"INVALID_BYTE_COUNT",16:"NOT_PERMITTED",17:"NOT_OWNER",18:"BLOCK_LOCKED_BY_OTHER",19:"BLOCK_NOT_LOCKED",20:"INVALID_GROUP_PERMISSIONS",21:"GROUP_DOES_NOT_EXIST",22:"INVALID_MEMBER_COUNT",23:"MAX_LIMIT_REACHED",24:"INVALID_AUTH_TYPE",25:"AUTHENTICATION_FAILED",26:"INVALID_DHCP_MODE",27:"INVALID_IP_ADDRESS",28:"INVALID_DOMAIN_NAME",29:"UNSUPPORTED_VERSION", 30:"REQUEST_UNEXPECTED",31:"INVALID_TABLE_TYPE",32:"INVALID_PROVISIONING_STATE",33:"UNSUPPORTED_OBJECT",34:"INVALID_TIME",35:"INVALID_INDEX",36:"INVALID_PARAMETER",37:"INVALID_NETMASK",38:"FLASH_WRITE_LIMIT_EXCEEDED",39:"INVALID_IMAGE_LENGTH",40:"INVALID_IMAGE_SIGNATURE",41:"PROPOSE_ANOTHER_VERSION",42:"INVALID_PID_FORMAT",43:"INVALID_PPS_FORMAT",44:"BIST_COMMAND_BLOCKED",45:"CONNECTION_FAILED",46:"CONNECTION_TOO_MANY",47:"RNG_GENERATION_IN_PROGRESS",48:"RNG_NOT_READY",49:"CERTIFICATE_NOT_READY", 1024:"DISABLED_BY_POLICY",2048:"NETWORK_IF_ERROR_BASE",2049:"UNSUPPORTED_OEM_NUMBER",2050:"UNSUPPORTED_BOOT_OPTION",2051:"INVALID_COMMAND",2052:"INVALID_SPECIAL_COMMAND",2053:"INVALID_HANDLE",2054:"INVALID_PASSWORD",2055:"INVALID_REALM",2056:"STORAGE_ACL_ENTRY_IN_USE",2057:"DATA_MISSING",2058:"DUPLICATE",2059:"EVENTLOG_FROZEN",2060:"PKI_MISSING_KEYS",2061:"PKI_GENERATING_KEYS",2062:"INVALID_KEY",2063:"INVALID_CERT",2064:"CERT_KEY_NOT_MATCH",2065:"MAX_KERB_DOMAIN_REACHED",2066:"UNSUPPORTED",2067:"INVALID_PRIORITY", -2068:"NOT_FOUND",2069:"INVALID_CREDENTIALS",2070:"INVALID_PASSPHRASE",2072:"NO_ASSOCIATION",2075:"AUDIT_FAIL",2076:"BLOCKING_COMPONENT",2081:"USER_CONSENT_REQUIRED",4096:"APP_INTERNAL_ERROR",4097:"NOT_INITIALIZED",4098:"LIB_VERSION_UNSUPPORTED",4099:"INVALID_PARAM",4100:"RESOURCES",4101:"HARDWARE_ACCESS_ERROR",4102:"REQUESTOR_NOT_REGISTERED",4103:"NETWORK_ERROR",4104:"PARAM_BUFFER_TOO_SHORT",4105:"COM_NOT_INITIALIZED_IN_THREAD",4106:"URL_REQUIRED"};m.GetMessageLog=function(a,b){m.AMT_MessageLog_PositionToFirstRecord(v, -[a,b,[]])};var l="Unspecified.;No system memory is physically installed in the system.;No usable system memory, all installed memory has experienced an unrecoverable failure.;Unrecoverable hard-disk/ATAPI/IDE device failure.;Unrecoverable system-board failure.;Unrecoverable diskette subsystem failure.;Unrecoverable hard-disk controller failure.;Unrecoverable PS/2 or USB keyboard failure.;Removable boot media not found.;Unrecoverable video controller failure.;No video device detected.;Firmware (BIOS) ROM corruption detected.;CPU voltage mismatch (processors that share same supply have mismatched voltage requirements);CPU speed matching failure".split(";"), -g="Unspecified.;Memory initialization.;Starting hard-disk initialization and test;Secondary processor(s) initialization;User authentication;User-initiated system setup;USB resource configuration;PCI resource configuration;Option ROM initialization;Video initialization;Cache initialization;SM Bus initialization;Keyboard controller initialization;Embedded controller/management controller initialization;Docking station attachment;Enabling docking station;Docking station ejection;Disabling docking station;Calling operating system wake-up vector;Starting operating system boot process;Baseboard or motherboard initialization;reserved;Floppy initialization;Keyboard test;Pointing device test;Primary processor initialization".split(";"), -x="Unspecified;Other;Unknown;Processor;Disk;Peripheral;System management module;System board;Memory module;Processor module;Power supply;Add in card;Front panel board;Back panel board;Power system board;Drive backplane;System internal expansion board;Other system board;Processor board;Power unit;Power module;Power management board;Chassis back panel board;System chassis;Sub chassis;Other chassis board;Disk drive bay;Peripheral bay;Device bay;Fan cooling;Cooling unit;Cable interconnect;Memory device;System management software;BIOS;Intel(r) ME;System bus;Group;Intel(r) ME;External environment;Battery;Processing blade;Connectivity switch;Processor/memory module;I/O module;Processor I/O module;Management controller firmware;IPMI channel;PCI bus;PCI express bus;SCSI bus;SATA/SAS bus;Processor front side bus".split(";"); -m.RealmNames=";;Redirection;;Hardware Asset;Remote Control;Storage;Event Manager;Storage Admin;Agent Presence Local;Agent Presence Remote;Circuit Breaker;Network Time;General Information;Firmware Update;EIT;LocalUN;Endpoint Access Control;Endpoint Access Control Admin;Event Log Reader;Audit Log;ACL Realm;;;Local System".split(";");m.WatchdogCurrentStates={1:"Not Started",2:"Stopped",4:"Running",8:"Expired",16:"Suspended"};var u={16:"Security Admin",17:"RCO",18:"Redirection Manager",19:"Firmware Update Manager", +2068:"NOT_FOUND",2069:"INVALID_CREDENTIALS",2070:"INVALID_PASSPHRASE",2072:"NO_ASSOCIATION",2075:"AUDIT_FAIL",2076:"BLOCKING_COMPONENT",2081:"USER_CONSENT_REQUIRED",4096:"APP_INTERNAL_ERROR",4097:"NOT_INITIALIZED",4098:"LIB_VERSION_UNSUPPORTED",4099:"INVALID_PARAM",4100:"RESOURCES",4101:"HARDWARE_ACCESS_ERROR",4102:"REQUESTOR_NOT_REGISTERED",4103:"NETWORK_ERROR",4104:"PARAM_BUFFER_TOO_SHORT",4105:"COM_NOT_INITIALIZED_IN_THREAD",4106:"URL_REQUIRED"};m.GetMessageLog=function(a,b){m.AMT_MessageLog_PositionToFirstRecord(u, +[a,b,[]])};var y="Unspecified.;No system memory is physically installed in the system.;No usable system memory, all installed memory has experienced an unrecoverable failure.;Unrecoverable hard-disk/ATAPI/IDE device failure.;Unrecoverable system-board failure.;Unrecoverable diskette subsystem failure.;Unrecoverable hard-disk controller failure.;Unrecoverable PS/2 or USB keyboard failure.;Removable boot media not found.;Unrecoverable video controller failure.;No video device detected.;Firmware (BIOS) ROM corruption detected.;CPU voltage mismatch (processors that share same supply have mismatched voltage requirements);CPU speed matching failure".split(";"), +h="Unspecified.;Memory initialization.;Starting hard-disk initialization and test;Secondary processor(s) initialization;User authentication;User-initiated system setup;USB resource configuration;PCI resource configuration;Option ROM initialization;Video initialization;Cache initialization;SM Bus initialization;Keyboard controller initialization;Embedded controller/management controller initialization;Docking station attachment;Enabling docking station;Docking station ejection;Disabling docking station;Calling operating system wake-up vector;Starting operating system boot process;Baseboard or motherboard initialization;reserved;Floppy initialization;Keyboard test;Pointing device test;Primary processor initialization".split(";"), +K="Unspecified;Other;Unknown;Processor;Disk;Peripheral;System management module;System board;Memory module;Processor module;Power supply;Add in card;Front panel board;Back panel board;Power system board;Drive backplane;System internal expansion board;Other system board;Processor board;Power unit;Power module;Power management board;Chassis back panel board;System chassis;Sub chassis;Other chassis board;Disk drive bay;Peripheral bay;Device bay;Fan cooling;Cooling unit;Cable interconnect;Memory device;System management software;BIOS;Intel(r) ME;System bus;Group;Intel(r) ME;External environment;Battery;Processing blade;Connectivity switch;Processor/memory module;I/O module;Processor I/O module;Management controller firmware;IPMI channel;PCI bus;PCI express bus;SCSI bus;SATA/SAS bus;Processor front side bus".split(";"); +m.RealmNames=";;Redirection;;Hardware Asset;Remote Control;Storage;Event Manager;Storage Admin;Agent Presence Local;Agent Presence Remote;Circuit Breaker;Network Time;General Information;Firmware Update;EIT;LocalUN;Endpoint Access Control;Endpoint Access Control Admin;Event Log Reader;Audit Log;ACL Realm;;;Local System".split(";");m.WatchdogCurrentStates={1:"Not Started",2:"Stopped",4:"Running",8:"Expired",16:"Suspended"};var r={16:"Security Admin",17:"RCO",18:"Redirection Manager",19:"Firmware Update Manager", 20:"Security Audit Log",21:"Network Time",22:"Network Administration",23:"Storage Administration",24:"Event Manager",25:"Circuit Breaker Manager",26:"Agent Presence Manager",27:"Wireless Configuration",28:"EAC",29:"KVM",30:"User Opt-In Events",32:"Screen Blanking",33:"Watchdog Events",1600:"Provisioning Started",1601:"Provisioning Completed",1602:"ACL Entry Added",1603:"ACL Entry Modified",1604:"ACL Entry Removed",1605:"ACL Access with Invalid Credentials",1606:"ACL Entry State",1607:"TLS State Changed", 1608:"TLS Server Certificate Set",1609:"TLS Server Certificate Remove",1610:"TLS Trusted Root Certificate Added",1611:"TLS Trusted Root Certificate Removed",1612:"TLS Preshared Key Set",1613:"Kerberos Settings Modified",1614:"Kerberos Master Key Modified",1615:"Flash Wear out Counters Reset",1616:"Power Package Modified",1617:"Set Realm Authentication Mode",1618:"Upgrade Client to Admin Control Mode",1619:"Unprovisioning Started",1700:"Performed Power Up",1701:"Performed Power Down",1702:"Performed Power Cycle", 1703:"Performed Reset",1704:"Set Boot Options",1800:"IDER Session Opened",1801:"IDER Session Closed",1802:"IDER Enabled",1803:"IDER Disabled",1804:"SoL Session Opened",1805:"SoL Session Closed",1806:"SoL Enabled",1807:"SoL Disabled",1808:"KVM Session Started",1809:"KVM Session Ended",1810:"KVM Enabled",1811:"KVM Disabled",1812:"VNC Password Failed 3 Times",1900:"Firmware Updated",1901:"Firmware Update Failed",2E3:"Security Audit Log Cleared",2001:"Security Audit Policy Modified",2002:"Security Audit Log Disabled", @@ -159,21 +159,21 @@ m.RealmNames=";;Redirection;;Hardware Asset;Remote Control;Storage;Event Manager 2500:"CB Filter Added",2501:"CB Filter Removed",2502:"CB Policy Added",2503:"CB Policy Removed",2504:"CB Default Policy Set",2505:"CB Heuristics Option Set",2506:"CB Heuristics State Cleared",2600:"Agent Watchdog Added",2601:"Agent Watchdog Removed",2602:"Agent Watchdog Action Set",2700:"Wireless Profile Added",2701:"Wireless Profile Removed",2702:"Wireless Profile Updated",2800:"EAC Posture Signer SET",2801:"EAC Enabled",2802:"EAC Disabled",2803:"EAC Posture State",2804:"EAC Set Options",2900:"KVM Opt-in Enabled", 2901:"KVM Opt-in Disabled",2902:"KVM Password Changed",2903:"KVM Consent Succeeded",2904:"KVM Consent Failed",3E3:"Opt-In Policy Change",3001:"Send Consent Code Event",3002:"Start Opt-In Blocked Event"};m.GetAuditLogExtendedDataStr=function(a,b){if((1602==a||1604==a)&&0==b.charCodeAt(0))return b.substring(2,2+b.charCodeAt(1));if(1603==a)return 0==b.charCodeAt(1)?b.substring(3):null;if(1605==a)return["Invalid ME access","Invalid MEBx access"][b.charCodeAt(0)];if(1606==a){var c=["Disabled","Enabled"][b.charCodeAt(0)]; 0==b.charCodeAt(1)&&(c+=", "+b.substring(3));return c}return 1607==a?"Remote "+["NoAuth","ServerAuth","MutualAuth"][b.charCodeAt(0)]+", Local "+["NoAuth","ServerAuth","MutualAuth"][b.charCodeAt(1)]:1617==a?m.RealmNames[ReadInt(b,0)]+", "+["NoAuth","Auth","Disabled"][b.charCodeAt(4)]:1619==a?["BIOS","MEBx","Local MEI","Local WSMAN","Remote WSAMN"][b.charCodeAt(0)]:1900==a?"From "+ReadShort(b,0)+"."+ReadShort(b,2)+"."+ReadShort(b,4)+"."+ReadShort(b,6)+" to "+ReadShort(b,8)+"."+ReadShort(b,10)+"."+ReadShort(b, -12)+"."+ReadShort(b,14):2100==a?(c=new Date,c.setTime(1E3*ReadInt(b,0)+6E4*(new Date).getTimezoneOffset()),c.toLocaleString()):3E3==a?"From "+["None","KVM","All"][b.charCodeAt(0)]+" to "+["None","KVM","All"][b.charCodeAt(1)]:3001==a?["Success","Failed 3 times"][b.charCodeAt(0)]:null};m.GetAuditLog=function(a){m.AMT_AuditLog_ReadRecords(1,h,[a,[]])};return m}function hex_md5(b){return forge.md.md5.create().update(b).digest().toHex()}function rstr_md5(b){return hex2rstr(hex_md5(b))} +12)+"."+ReadShort(b,14):2100==a?(c=new Date,c.setTime(1E3*ReadInt(b,0)+6E4*(new Date).getTimezoneOffset()),c.toLocaleString()):3E3==a?"From "+["None","KVM","All"][b.charCodeAt(0)]+" to "+["None","KVM","All"][b.charCodeAt(1)]:3001==a?["Success","Failed 3 times"][b.charCodeAt(0)]:null};m.GetAuditLog=function(a){m.AMT_AuditLog_ReadRecords(1,w,[a,[]])};return m}function hex_md5(b){return forge.md.md5.create().update(b).digest().toHex()}function rstr_md5(b){return hex2rstr(hex_md5(b))} function execArgumentsToXml(b){if(void 0===b||null===b)return null;var c="",a;for(a in b){var d=b[a];d&&(c="reference"===d.__parameterType?c+referenceToXml(a,d):c+instanceToXml(a,d))}return c} -function instanceToXml(b,c){if(void 0===c||null===c)return null;var a=!!c.__namespace,d=a?"",q;for(q in c)c.hasOwnProperty(q)&&0!==q.indexOf("__")&&("function"===typeof c[q]||Array.isArray(c[q])||("object"===typeof c[q]?console.error("only convert one level down..."):a+=d+q+">"+c[q].toString()+e+q+">"));return a+("")} +function instanceToXml(b,c){if(void 0===c||null===c)return null;var a=!!c.__namespace,d=a?"",g;for(g in c)c.hasOwnProperty(g)&&0!==g.indexOf("__")&&("function"===typeof c[g]||Array.isArray(c[g])||("object"===typeof c[g]?console.error("only convert one level down..."):a+=d+g+">"+c[g].toString()+e+g+">"));return a+("")} function referenceToXml(b,c){if(void 0===c||null===c)return null;var a="/wsman"+c.__resourceUri+"",d;for(d in c)c.hasOwnProperty(d)&&0!==d.indexOf("__")&&("function"===typeof c[d]||"object"===typeof c[d]||Array.isArray(c[d])||(a+=''+c[d].toString()+""));return a+("")} function GetSidString(b){for(var c="S-"+b.charCodeAt(0)+"-"+b.charCodeAt(7),a=2;ab.length||"s"!=b[0]&&"S"!=b[0])return null;for(var c=1;c=this.length()};d.ByteStringBuffer.prototype.putByte=function(a){return this.putBytes(String.fromCharCode(a))}; d.ByteStringBuffer.prototype.fillWithByte=function(a,b){a=String.fromCharCode(a);for(var c=this.data;0>>=1,0>8& 255)+String.fromCharCode(a&255))};d.ByteStringBuffer.prototype.putInt24=function(a){return this.putBytes(String.fromCharCode(a>>16&255)+String.fromCharCode(a>>8&255)+String.fromCharCode(a&255))};d.ByteStringBuffer.prototype.putInt32=function(a){return this.putBytes(String.fromCharCode(a>>24&255)+String.fromCharCode(a>>16&255)+String.fromCharCode(a>>8&255)+String.fromCharCode(a&255))};d.ByteStringBuffer.prototype.putInt16Le=function(a){return this.putBytes(String.fromCharCode(a&255)+String.fromCharCode(a>> @@ -184,9 +184,9 @@ function(){var a=this.data.charCodeAt(this.read)^this.data.charCodeAt(this.read+ function(a){var b=this.getInt(a);a=2<=a&&(b-=a<<1);return b};d.ByteStringBuffer.prototype.getBytes=function(a){var b;a?(a=Math.min(this.length(),a),b=this.data.slice(this.read,this.read+a),this.read+=a):0===a?b="":(b=0===this.read?this.data:this.data.slice(this.read),this.clear());return b};d.ByteStringBuffer.prototype.bytes=function(a){return"undefined"===typeof a?this.data.slice(this.read):this.data.slice(this.read,this.read+a)};d.ByteStringBuffer.prototype.at=function(a){return this.data.charCodeAt(this.read+ a)};d.ByteStringBuffer.prototype.setAt=function(a,b){this.data=this.data.substr(0,this.read+a)+String.fromCharCode(b)+this.data.substr(this.read+a+1);return this};d.ByteStringBuffer.prototype.last=function(){return this.data.charCodeAt(this.data.length-1)};d.ByteStringBuffer.prototype.copy=function(){var a=d.createBuffer(this.data);a.read=this.read;return a};d.ByteStringBuffer.prototype.compact=function(){0c&&(a+="0");a+=c.toString(16)}return a};d.ByteStringBuffer.prototype.toString=function(){return d.decodeUtf8(this.bytes())};d.DataBuffer=function(a,b){b=b||{};this.read=b.readOffset|| -0;this.growSize=b.growSize||1024;var c=d.isArrayBuffer(a),n=d.isArrayBufferView(a);c||n?(this.data=c?new DataView(a):new DataView(a.buffer,a.byteOffset,a.byteLength),this.write="writeOffset"in b?b.writeOffset:this.data.byteLength):(this.data=new DataView(new ArrayBuffer(0)),this.write=0,null!==a&&void 0!==a&&this.putBytes(a),"writeOffset"in b&&(this.write=b.writeOffset))};d.DataBuffer.prototype.length=function(){return this.write-this.read};d.DataBuffer.prototype.isEmpty=function(){return 0>=this.length()}; +0;this.growSize=b.growSize||1024;var c=d.isArrayBuffer(a),p=d.isArrayBufferView(a);c||p?(this.data=c?new DataView(a):new DataView(a.buffer,a.byteOffset,a.byteLength),this.write="writeOffset"in b?b.writeOffset:this.data.byteLength):(this.data=new DataView(new ArrayBuffer(0)),this.write=0,null!==a&&void 0!==a&&this.putBytes(a),"writeOffset"in b&&(this.write=b.writeOffset))};d.DataBuffer.prototype.length=function(){return this.write-this.read};d.DataBuffer.prototype.isEmpty=function(){return 0>=this.length()}; d.DataBuffer.prototype.accommodate=function(a,b){if(this.length()>=a)return this;b=Math.max(b||this.growSize,a);var c=new Uint8Array(this.data.buffer,this.data.byteOffset,this.data.byteLength),d=new Uint8Array(this.length()+b);d.set(c);this.data=new DataView(d.buffer);return this};d.DataBuffer.prototype.putByte=function(a){this.accommodate(1);this.data.setUint8(this.write++,a);return this};d.DataBuffer.prototype.fillWithByte=function(a,b){this.accommodate(b);for(var c=0;c>8&65535);this.data.setInt8(this.write,a>>16&255);this.write+=3;return this}; @@ -197,69 +197,69 @@ this.data.getInt32(this.read,!0);this.read+=4;return a};d.DataBuffer.prototype.g d.DataBuffer.prototype.bytes=function(a){return"undefined"===typeof a?this.data.slice(this.read):this.data.slice(this.read,this.read+a)};d.DataBuffer.prototype.at=function(a){return this.data.getUint8(this.read+a)};d.DataBuffer.prototype.setAt=function(a,b){this.data.setUint8(a,b);return this};d.DataBuffer.prototype.last=function(){return this.data.getUint8(this.write-1)};d.DataBuffer.prototype.copy=function(){return new d.DataBuffer(this)};d.DataBuffer.prototype.compact=function(){if(0c&&(a+="0");a+=c.toString(16)}return a};d.DataBuffer.prototype.toString=function(a){var b=new Uint8Array(this.data,this.read,this.length());a=a||"utf8";if("binary"===a||"raw"===a)return d.binary.raw.encode(b);if("hex"===a)return d.binary.hex.encode(b);if("base64"===a)return d.binary.base64.encode(b);if("utf8"===a)return d.text.utf8.decode(b);if("utf16"===a)return d.text.utf16.decode(b);throw Error("Invalid encoding: "+a);};d.createBuffer=function(a,b){void 0!==a&&"utf8"=== -(b||"raw")&&(a=d.encodeUtf8(a));return new d.ByteBuffer(a)};d.fillString=function(a,b){for(var c="";0>>=1,0>24&255)+String.fromCharCode(a>>16&255)+String.fromCharCode(a>>8&255)+String.fromCharCode(a&255)};var e=[62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,64,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];d.encode64=function(a,b){for(var c="",d="",n,e,g,h=0;h>2),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt((n&3)<<4|e>>4),isNaN(e)?c+="==":(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt((e&15)<<2|g>>6),c+=isNaN(g)?"=":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(g&63)),b&&c.length>b&&(d+=c.substr(0,b)+"\r\n",c=c.substr(b));return d+ -c};d.decode64=function(a){a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var b="",c,d,n,g,h=0;h>4),64!==n&&(b+=String.fromCharCode((d&15)<<4|n>>2),64!==g&&(b+=String.fromCharCode((n&3)<<6|g)));return b};d.encodeUtf8=function(a){return unescape(encodeURIComponent(a))};d.decodeUtf8=function(a){return decodeURIComponent(escape(a))};d.binary={raw:{},hex:{},base64:{}}; -d.binary.raw.encode=function(a){return String.fromCharCode.apply(null,a)};d.binary.raw.decode=function(a,b,c){var d=b;d||(d=new Uint8Array(a.length));for(var n=c=c||0,e=0;e>2),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt((n&3)<<4|e>>4),isNaN(e)?c+="==":(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt((e&15)<<2|g>>6),c+=isNaN(g)?"=":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(g&63)),b&&c.length>b&&(d+=c.substr(0, -b)+"\r\n",c=c.substr(b));return d+c};d.binary.base64.decode=function(a,b,c){var d=b;d||(d=new Uint8Array(3*Math.ceil(a.length/4)));a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");c=c||0;for(var n,g,h,l,u=0,p=c;u>4,64!==h&&(d[p++]=(g&15)<<4|h>>2,64!==l&&(d[p++]=(h&3)<<6|l));return b?p-c:d.subarray(0,p)};d.text={utf8:{},utf16:{}};d.text.utf8.encode=function(a,b,c){a=d.encodeUtf8(a); -var n=b;n||(n=new Uint8Array(a.length));for(var e=c=c||0,g=0;g");break;case "%":e.push("%");break;default:e.push("<#"+ -c+"?>")}e.push(a.substring(d));return e.join("")};d.formatNumber=function(a,b,c,d){var n=isNaN(b=Math.abs(b))?2:b;b=void 0===c?",":c;d=void 0===d?".":d;c=0>a?"-":"";var e=parseInt(a=Math.abs(+a||0).toFixed(n),10)+"",g=3e;++e)if(a[e]&&0!==a[e].length){var g=d.hexToBytes(a[e]);2>g.length&&n.putByte(0);n.putBytes(g)}else n.fillWithByte(0,c),c=0;return n.getBytes()};d.bytesToIP=function(a){return 4===a.length?d.bytesToIPv4(a):16===a.length?d.bytesToIPv6(a):null};d.bytesToIPv4=function(a){if(4!==a.length)return null;for(var b=[],c=0;cc[n].end-c[n].start&&(n=c.length-1)):c.push({start:u,end:u})}b.push(g)}0l.st&&n.stn.st&&l.st>>=1,0>24&255)+String.fromCharCode(a>>16&255)+String.fromCharCode(a>>8&255)+String.fromCharCode(a&255)};var e=[62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,64,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];d.encode64=function(a,b){for(var c="",d="",p,e,k,h=0;h>2),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt((p&3)<<4|e>>4),isNaN(e)?c+="==":(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt((e&15)<<2|k>>6),c+=isNaN(k)?"=":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(k&63)),b&&c.length>b&&(d+=c.substr(0,b)+"\r\n",c=c.substr(b));return d+ +c};d.decode64=function(a){a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var b="",c,d,p,k,h=0;h>4),64!==p&&(b+=String.fromCharCode((d&15)<<4|p>>2),64!==k&&(b+=String.fromCharCode((p&3)<<6|k)));return b};d.encodeUtf8=function(a){return unescape(encodeURIComponent(a))};d.decodeUtf8=function(a){return decodeURIComponent(escape(a))};d.binary={raw:{},hex:{},base64:{}}; +d.binary.raw.encode=function(a){return String.fromCharCode.apply(null,a)};d.binary.raw.decode=function(a,b,c){var d=b;d||(d=new Uint8Array(a.length));for(var p=c=c||0,e=0;e>2),c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt((p&3)<<4|e>>4),isNaN(e)?c+="==":(c+="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt((e&15)<<2|k>>6),c+=isNaN(k)?"=":"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".charAt(k&63)),b&&c.length>b&&(d+=c.substr(0, +b)+"\r\n",c=c.substr(b));return d+c};d.binary.base64.decode=function(a,b,c){var d=b;d||(d=new Uint8Array(3*Math.ceil(a.length/4)));a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");c=c||0;for(var p,k,h,r,y=0,n=c;y>4,64!==h&&(d[n++]=(k&15)<<4|h>>2,64!==r&&(d[n++]=(h&3)<<6|r));return b?n-c:d.subarray(0,n)};d.text={utf8:{},utf16:{}};d.text.utf8.encode=function(a,b,c){a=d.encodeUtf8(a); +var p=b;p||(p=new Uint8Array(a.length));for(var e=c=c||0,k=0;k");break;case "%":e.push("%");break;default:e.push("<#"+ +c+"?>")}e.push(a.substring(d));return e.join("")};d.formatNumber=function(a,b,c,d){var p=isNaN(b=Math.abs(b))?2:b;b=void 0===c?",":c;d=void 0===d?".":d;c=0>a?"-":"";var e=parseInt(a=Math.abs(+a||0).toFixed(p),10)+"",k=3e;++e)if(a[e]&&0!==a[e].length){var k=d.hexToBytes(a[e]);2>k.length&&p.putByte(0);p.putBytes(k)}else p.fillWithByte(0,c),c=0;return p.getBytes()};d.bytesToIP=function(a){return 4===a.length?d.bytesToIPv4(a):16===a.length?d.bytesToIPv6(a):null};d.bytesToIPv4=function(a){if(4!==a.length)return null;for(var b=[],c=0;cc[p].end-c[p].start&&(p=c.length-1)):c.push({start:r,end:r})}b.push(k)}0z.st&&p.stp.st&&z.stthis.blockSize<<2)return!1;a.truncate(c);return!0};w.cbc=function(a){a=a||{};this.name="CBC";this.cipher=a.cipher;this.blockSize=a.blockSize||16;this._ints=this.blockSize/4;this._inBlock=Array(this._ints); -this._outBlock=Array(this._ints)};w.cbc.prototype.start=function(a){if(null===a.iv){if(!this._prev)throw Error("Invalid IV parameter.");this._iv=this._prev.slice(0)}else if("iv"in a)this._iv=c(a.iv),this._prev=this._iv.slice(0);else throw Error("Invalid IV parameter.");};w.cbc.prototype.encrypt=function(a,b,c){if(a.length()this.blockSize<<2)return!1;a.truncate(c);return!0};w.cfb=function(b){b=b||{};this.name="CFB";this.cipher=b.cipher;this.blockSize=b.blockSize||16;this._ints=this.blockSize/4;this._inBlock=null;this._outBlock=Array(this._ints);this._partialBlock=Array(this._ints);this._partialOutput=a.util.createBuffer();this._partialBytes=0};w.cfb.prototype.start=function(a){if(!("iv"in a))throw Error("Invalid IV parameter.");this._iv=c(a.iv);this._inBlock= -this._iv.slice(0);this._partialBytes=0};w.cfb.prototype.encrypt=function(a,b,c){var d=a.length();if(0===d)return!0;this.cipher.encrypt(this._inBlock,this._outBlock);if(0===this._partialBytes&&d>=this.blockSize)for(var n=0;n=this.blockSize)for(var n=0;n=this.blockSize)for(var n=0;n=this.blockSize)for(var e=0;e< -this._ints;++e)b.putInt32(a.getInt32()^this._outBlock[e]);else{var p=(this.blockSize-n)%this.blockSize;0=this.blockSize){for(var e=0;en;++n)a[n/32|0]&1<<31-n%32&&(c[0]^=d[0],c[1]^=d[1],c[2]^=d[2],c[3]^=d[3]),this.pow(d,d);return c};w.gcm.prototype.pow=function(a,b){for(var c=a[3]&1,d=3;0>>1|(a[d-1]&1)<<31;b[0]=a[0]>>>1;c&&(b[0]^=this._R)};w.gcm.prototype.tableMultiply=function(a){for(var b= -[0,0,0,0],c=0;32>c;++c){var d=this._m[c][a[c/8|0]>>>4*(7-c%8)&15];b[0]^=d[0];b[1]^=d[1];b[2]^=d[2];b[3]^=d[3]}return b};w.gcm.prototype.ghash=function(a,b,c){b[0]^=c[0];b[1]^=c[1];b[2]^=c[2];b[3]^=c[3];return this.tableMultiply(b)};w.gcm.prototype.generateHashTable=function(a,b){for(var c=8/b,d=4*c,c=16*c,n=Array(c),e=0;e>>1,n=Array(c);n[d]=a.slice(0);for(var e=d>>>1;0>=1;for(e=2;eb;++b)a[b]=b<<1,a[b+128]=b+128<<1^283;x=Array(256);u=Array(256);A=Array(4);y=Array(4);for(b=0;4>b;++b)A[b]=Array(256),y[b]=Array(256);for(var c=0,n=0,e,h,g,p,m,b=0;256>b;++b){p=n^n<<1^n<<2^n<<3^n<<4;p=p>>8^p&255^99;x[c]=p;u[p]=c;m=a[p];e=a[c];h=a[e];g=a[h];m^=m<<24^p<<16^p<<8^p;h=(e^h^g)<<24^(c^ -g)<<16^(c^h^g)<<8^c^e^g;for(var w=0;4>w;++w)A[w][c]=m,y[w][p]=h,m=m<<24|m>>>8,h=h<<24|h>>>8;0===c?c=n=1:(c=e^a[a[a[e^g]]],n^=a[a[n]])}}function e(a,b){for(var c=a.slice(0),d,n=1,h=c.length,l=g*(h+6+1),p=h;p>>16&255]<<24^x[d>>>8&255]<<16^x[d&255]<<8^x[d>>>24]^q[n]<<24,n++):6>>24]<<24^x[d>>>16&255]<<16^x[d>>>8&255]<<8^x[d&255]),c[p]=c[p-h]^d;if(b){for(var n=y[0],h=y[1],m=y[2],u=y[3],w=c.slice(0),l=c.length,p=0,k=l-g;p>>24]]^h[x[d>>>16&255]]^m[x[d>>>8&255]]^u[x[d&255]];c=w}return c}function w(a,b,c,d){var n=a.length/4-1,e,h,g,l,p;d?(e=y[0],h=y[1],g=y[2],l=y[3],p=u):(e=A[0],h=A[1],g=A[2],l=A[3],p=x);var m,w,k,q,B,J;m=b[0]^a[0];w=b[d?3:1]^a[1];k=b[2]^a[2];b=b[d?1:3]^a[3];for(var v=3,Z=1;Z>>24]^h[w>>>16&255]^g[k>>>8&255]^l[b&255]^a[++v],B=e[w>>>24]^h[k>>>16&255]^g[b>>>8&255]^l[m&255]^a[++v],J=e[k>>>24]^ -h[b>>>16&255]^g[m>>>8&255]^l[w&255]^a[++v],b=e[b>>>24]^h[m>>>16&255]^g[w>>>8&255]^l[k&255]^a[++v],m=q,w=B,k=J;c[0]=p[m>>>24]<<24^p[w>>>16&255]<<16^p[k>>>8&255]<<8^p[b&255]^a[++v];c[d?3:1]=p[w>>>24]<<24^p[k>>>16&255]<<16^p[b>>>8&255]<<8^p[m&255]^a[++v];c[2]=p[k>>>24]<<24^p[b>>>16&255]<<16^p[m>>>8&255]<<8^p[w&255]^a[++v];c[d?1:3]=p[b>>>24]<<24^p[m>>>16&255]<<16^p[w>>>8&255]<<8^p[k&255]^a[++v]}function k(b){b=b||{};var c="AES-"+(b.mode||"CBC").toUpperCase(),d;d=b.decrypt?a.cipher.createDecipher(c,b.key): -a.cipher.createCipher(c,b.key);var e=d.start;d.start=function(b,c){var h=null;c instanceof a.util.ByteBuffer&&(h=c,c={});c=c||{};c.output=h;c.iv=b;e.call(d,c)};return d}a.aes=a.aes||{};a.aes.startEncrypting=function(a,b,c,d){a=k({key:a,output:c,decrypt:!1,mode:d});a.start(b);return a};a.aes.createEncryptionCipher=function(a,b){return k({key:a,output:null,decrypt:!1,mode:b})};a.aes.startDecrypting=function(a,b,c,d){a=k({key:a,output:c,decrypt:!0,mode:d});a.start(b);return a};a.aes.createDecryptionCipher= -function(a,b){return k({key:a,output:null,decrypt:!0,mode:b})};a.aes.Algorithm=function(a,b){l||d();var c=this;c.name=a;c.mode=new b({blockSize:16,cipher:{encrypt:function(a,b){return w(c._w,a,b,!1)},decrypt:function(a,b){return w(c._w,a,b,!0)}}});c._init=!1};a.aes.Algorithm.prototype.initialize=function(b){if(!this._init){var c=b.key,d;if("string"===typeof c&&(16===c.length||24===c.length||32===c.length))c=a.util.createBuffer(c);else if(a.util.isArray(c)&&(16===c.length||24===c.length||32===c.length)){d= -c;for(var c=a.util.createBuffer(),h=0;h>>=2,h=0;hthis.blockSize<<2)return!1;a.truncate(c);return!0};v.cbc=function(a){a=a||{};this.name="CBC";this.cipher=a.cipher;this.blockSize=a.blockSize||16;this._ints=this.blockSize/4;this._inBlock=Array(this._ints); +this._outBlock=Array(this._ints)};v.cbc.prototype.start=function(a){if(null===a.iv){if(!this._prev)throw Error("Invalid IV parameter.");this._iv=this._prev.slice(0)}else if("iv"in a)this._iv=c(a.iv),this._prev=this._iv.slice(0);else throw Error("Invalid IV parameter.");};v.cbc.prototype.encrypt=function(a,b,c){if(a.length()this.blockSize<<2)return!1;a.truncate(c);return!0};v.cfb=function(b){b=b||{};this.name="CFB";this.cipher=b.cipher;this.blockSize=b.blockSize||16;this._ints=this.blockSize/4;this._inBlock=null;this._outBlock=Array(this._ints);this._partialBlock=Array(this._ints);this._partialOutput=a.util.createBuffer();this._partialBytes=0};v.cfb.prototype.start=function(a){if(!("iv"in a))throw Error("Invalid IV parameter.");this._iv=c(a.iv);this._inBlock= +this._iv.slice(0);this._partialBytes=0};v.cfb.prototype.encrypt=function(a,b,c){var d=a.length();if(0===d)return!0;this.cipher.encrypt(this._inBlock,this._outBlock);if(0===this._partialBytes&&d>=this.blockSize)for(var p=0;p=this.blockSize)for(var p=0;p=this.blockSize)for(var p=0;p=this.blockSize)for(var e=0;e< +this._ints;++e)b.putInt32(a.getInt32()^this._outBlock[e]);else{var n=(this.blockSize-p)%this.blockSize;0=this.blockSize){for(var e=0;ep;++p)a[p/32|0]&1<<31-p%32&&(c[0]^=d[0],c[1]^=d[1],c[2]^=d[2],c[3]^=d[3]),this.pow(d,d);return c};v.gcm.prototype.pow=function(a,b){for(var c=a[3]&1,d=3;0>>1|(a[d-1]&1)<<31;b[0]=a[0]>>>1;c&&(b[0]^=this._R)};v.gcm.prototype.tableMultiply=function(a){for(var b= +[0,0,0,0],c=0;32>c;++c){var d=this._m[c][a[c/8|0]>>>4*(7-c%8)&15];b[0]^=d[0];b[1]^=d[1];b[2]^=d[2];b[3]^=d[3]}return b};v.gcm.prototype.ghash=function(a,b,c){b[0]^=c[0];b[1]^=c[1];b[2]^=c[2];b[3]^=c[3];return this.tableMultiply(b)};v.gcm.prototype.generateHashTable=function(a,b){for(var c=8/b,d=4*c,c=16*c,p=Array(c),e=0;e>>1,p=Array(c);p[d]=a.slice(0);for(var e=d>>>1;0>=1;for(e=2;eb;++b)a[b]=b<<1,a[b+128]=b+128<<1^283;l=Array(256);r=Array(256);A=Array(4);B=Array(4);for(b=0;4>b;++b)A[b]=Array(256),B[b]=Array(256);for(var c=0,p=0,e,k,h,n,m,b=0;256>b;++b){n=p^p<<1^p<<2^p<<3^p<<4;n=n>>8^n&255^99;l[c]=n;r[n]=c;m=a[n];e=a[c];k=a[e];h=a[k];m^=m<<24^n<<16^n<<8^n;k=(e^k^h)<<24^(c^ +h)<<16^(c^k^h)<<8^c^e^h;for(var v=0;4>v;++v)A[v][c]=m,B[v][n]=k,m=m<<24|m>>>8,k=k<<24|k>>>8;0===c?c=p=1:(c=e^a[a[a[e^h]]],p^=a[a[p]])}}function e(a,b){for(var c=a.slice(0),d,p=1,k=c.length,r=h*(k+6+1),n=k;n>>16&255]<<24^l[d>>>8&255]<<16^l[d&255]<<8^l[d>>>24]^E[p]<<24,p++):6>>24]<<24^l[d>>>16&255]<<16^l[d>>>8&255]<<8^l[d&255]),c[n]=c[n-k]^d;if(b){for(var p=B[0],k=B[1],m=B[2],y=B[3],v=c.slice(0),r=c.length,n=0,A=r-h;n>>24]]^k[l[d>>>16&255]]^m[l[d>>>8&255]]^y[l[d&255]];c=v}return c}function v(a,b,c,d){var p=a.length/4-1,e,k,h,n,m;d?(e=B[0],k=B[1],h=B[2],n=B[3],m=r):(e=A[0],k=A[1],h=A[2],n=A[3],m=l);var y,v,w,E,g,u;y=b[0]^a[0];v=b[d?3:1]^a[1];w=b[2]^a[2];b=b[d?1:3]^a[3];for(var U=3,Z=1;Z>>24]^k[v>>>16&255]^h[w>>>8&255]^n[b&255]^a[++U],g=e[v>>>24]^k[w>>>16&255]^h[b>>>8&255]^n[y&255]^a[++U],u=e[w>>>24]^ +k[b>>>16&255]^h[y>>>8&255]^n[v&255]^a[++U],b=e[b>>>24]^k[y>>>16&255]^h[v>>>8&255]^n[w&255]^a[++U],y=E,v=g,w=u;c[0]=m[y>>>24]<<24^m[v>>>16&255]<<16^m[w>>>8&255]<<8^m[b&255]^a[++U];c[d?3:1]=m[v>>>24]<<24^m[w>>>16&255]<<16^m[b>>>8&255]<<8^m[y&255]^a[++U];c[2]=m[w>>>24]<<24^m[b>>>16&255]<<16^m[y>>>8&255]<<8^m[v&255]^a[++U];c[d?1:3]=m[b>>>24]<<24^m[y>>>16&255]<<16^m[v>>>8&255]<<8^m[w&255]^a[++U]}function k(b){b=b||{};var c="AES-"+(b.mode||"CBC").toUpperCase(),d;d=b.decrypt?a.cipher.createDecipher(c,b.key): +a.cipher.createCipher(c,b.key);var e=d.start;d.start=function(b,c){var k=null;c instanceof a.util.ByteBuffer&&(k=c,c={});c=c||{};c.output=k;c.iv=b;e.call(d,c)};return d}a.aes=a.aes||{};a.aes.startEncrypting=function(a,b,c,d){a=k({key:a,output:c,decrypt:!1,mode:d});a.start(b);return a};a.aes.createEncryptionCipher=function(a,b){return k({key:a,output:null,decrypt:!1,mode:b})};a.aes.startDecrypting=function(a,b,c,d){a=k({key:a,output:c,decrypt:!0,mode:d});a.start(b);return a};a.aes.createDecryptionCipher= +function(a,b){return k({key:a,output:null,decrypt:!0,mode:b})};a.aes.Algorithm=function(a,b){y||d();var c=this;c.name=a;c.mode=new b({blockSize:16,cipher:{encrypt:function(a,b){return v(c._w,a,b,!1)},decrypt:function(a,b){return v(c._w,a,b,!0)}}});c._init=!1};a.aes.Algorithm.prototype.initialize=function(b){if(!this._init){var c=b.key,d;if("string"===typeof c&&(16===c.length||24===c.length||32===c.length))c=a.util.createBuffer(c);else if(a.util.isArray(c)&&(16===c.length||24===c.length||32===c.length)){d= +c;for(var c=a.util.createBuffer(),k=0;k>>=2,k=0;kb.length()){var l=Error("Too few bytes to parse DER.");l.bytes=b.length();throw l;}var g=b.getByte(),l=g&192,m=g&31,u=d(b);if(b.length()b.length()){var m=Error("Too few bytes to parse DER.");m.bytes=b.length();throw m;}var h=b.getByte(),m=h&192,l=h&31,r=d(b);if(b.length()=h.length())d.putByte(h.length()&127);else{m=h.length();b="";do b+=String.fromCharCode(m&255),m>>>=8;while(0>>=7,d||(m|=128),e.push(m),d=!1;while(0c[a].length&&(b+="0"),b+=c[a];return b+"Z"};c.dateToGeneralizedTime=function(a){if("string"=== +return d};c.oidToDer=function(b){b=b.split(".");var c=a.util.createBuffer();c.putByte(40*parseInt(b[0],10)+parseInt(b[1],10));for(var d,e,m,r,n=2;n>>=7,d||(r|=128),e.push(r),d=!1;while(0c[a].length&&(b+="0"),b+=c[a];return b+"Z"};c.dateToGeneralizedTime=function(a){if("string"=== typeof a)return a;var b="",c=[];c.push(""+a.getUTCFullYear());c.push(""+(a.getUTCMonth()+1));c.push(""+a.getUTCDate());c.push(""+a.getUTCHours());c.push(""+a.getUTCMinutes());c.push(""+a.getUTCSeconds());for(a=0;ac[a].length&&(b+="0"),b+=c[a];return b+"Z"};c.integerToDer=function(b){var c=a.util.createBuffer();if(-128<=b&&128>b)return c.putSignedInt(b,8);if(-32768<=b&&32768>b)return c.putSignedInt(b,16);if(-8388608<=b&&8388608>b)return c.putSignedInt(b,24);if(-2147483648<=b&&2147483648> b)return c.putSignedInt(b,32);c=Error("Integer too large; max is 32-bits.");c.integer=b;throw c;};c.derToInteger=function(b){"string"===typeof b&&(b=a.util.createBuffer(b));var c=8*b.length();if(32b;++b)g[b]=Math.floor(4294967296* -Math.abs(Math.sin(b+1)));x=!0}function d(a,b,c){for(var e,n,h,m,z,C,p,x=c.length();64<=x;){n=a.h0;h=a.h1;m=a.h2;z=a.h3;for(p=0;16>p;++p)b[p]=c.getInt32Le(),e=z^h&(m^z),e=n+e+g[p]+b[p],C=l[p],n=z,z=m,m=h,h+=e<>>32-C;for(;32>p;++p)e=m^z&(h^m),e=n+e+g[p]+b[q[p]],C=l[p],n=z,z=m,m=h,h+=e<>>32-C;for(;48>p;++p)e=h^m^z,e=n+e+g[p]+b[q[p]],C=l[p],n=z,z=m,m=h,h+=e<>>32-C;for(;64>p;++p)e=m^(h|~z),e=n+e+g[p]+b[q[p]],C=l[p],n=z,z=m,m=h,h+=e<>>32-C;a.h0=a.h0+n|0;a.h1=a.h1+h|0;a.h2=a.h2+m|0;a.h3= -a.h3+z|0;x-=64}}var e=a.md5=a.md5||{};a.md=a.md||{};a.md.algorithms=a.md.algorithms||{};a.md.md5=a.md.algorithms.md5=e;e.create=function(){x||c();var b=null,e=a.util.createBuffer(),g=Array(16),l={algorithm:"md5",blockLength:64,digestLength:16,messageLength:0,fullMessageLength:null,messageLengthSize:8,start:function(){l.messageLength=0;l.fullMessageLength=l.messageLength64=[];for(var c=l.messageLengthSize/4,d=0;d>>0,p>>>0],z=l.fullMessageLength.length-1;0<=z;--z)l.fullMessageLength[z]+=p[1],p[1]=p[0]+(l.fullMessageLength[z]/4294967296>>>0),l.fullMessageLength[z]>>>=0,p[0]=p[1]/4294967296>>>0;e.putBytes(c);d(b,g,e);(2048>>0,c.putInt32Le(p>>>0);p={h0:b.h0,h1:b.h1,h2:b.h2,h3:b.h3};d(p,g,c);c=a.util.createBuffer();c.putInt32Le(p.h0);c.putInt32Le(p.h1);c.putInt32Le(p.h2);c.putInt32Le(p.h3);return c};return l};var k=null,q=null,l=null,g=null,x=!1}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e= -!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge={}),b(forge);var q,k=function(a,c){c.exports=function(c){var e=q.map(function(b){return a(b)}).concat(b);c=c||{};c.defined=c.defined||{};if(c.defined.md5)return c.md5;c.defined.md5=!0;for(var p=0;pD;++D)e=d.getInt32(),b[D]=e,w=m^h&(p^m),e=(n<<5|n>>>27)+w+k+1518500249+e,k=m,m=p,p=h<<30|h>>>2,h=n,n=e;for(;20>D;++D)e=b[D-3]^b[D-8]^b[D-14]^b[D-16],e=e<<1|e>>>31,b[D]=e,w=m^h&(p^m),e=(n<<5|n>>>27)+w+k+1518500249+e,k=m,m=p,p=h<<30|h>>>2,h=n,n=e;for(;32> -D;++D)e=b[D-3]^b[D-8]^b[D-14]^b[D-16],e=e<<1|e>>>31,b[D]=e,w=h^p^m,e=(n<<5|n>>>27)+w+k+1859775393+e,k=m,m=p,p=h<<30|h>>>2,h=n,n=e;for(;40>D;++D)e=b[D-6]^b[D-16]^b[D-28]^b[D-32],e=e<<2|e>>>30,b[D]=e,w=h^p^m,e=(n<<5|n>>>27)+w+k+1859775393+e,k=m,m=p,p=h<<30|h>>>2,h=n,n=e;for(;60>D;++D)e=b[D-6]^b[D-16]^b[D-28]^b[D-32],e=e<<2|e>>>30,b[D]=e,w=h&p|m&(h^p),e=(n<<5|n>>>27)+w+k+2400959708+e,k=m,m=p,p=h<<30|h>>>2,h=n,n=e;for(;80>D;++D)e=b[D-6]^b[D-16]^b[D-28]^b[D-32],e=e<<2|e>>>30,b[D]=e,w=h^p^m,e=(n<<5|n>>> -27)+w+k+3395469782+e,k=m,m=p,p=h<<30|h>>>2,h=n,n=e;a.h0=a.h0+n|0;a.h1=a.h1+h|0;a.h2=a.h2+p|0;a.h3=a.h3+m|0;a.h4=a.h4+k|0;z-=64}}var d=a.sha1=a.sha1||{};a.md=a.md||{};a.md.algorithms=a.md.algorithms||{};a.md.sha1=a.md.algorithms.sha1=d;d.create=function(){k||(e=String.fromCharCode(128),e+=a.util.fillString(String.fromCharCode(0),64),k=!0);var b=null,d=a.util.createBuffer(),h=Array(80),x={algorithm:"sha1",blockLength:64,digestLength:20,messageLength:0,fullMessageLength:null,messageLengthSize:8,start:function(){x.messageLength= -0;x.fullMessageLength=x.messageLength64=[];for(var c=x.messageLengthSize/4,e=0;e>>0,k>>>0],w=x.fullMessageLength.length-1;0<=w;--w)x.fullMessageLength[w]+=k[1],k[1]=k[0]+(x.fullMessageLength[w]/4294967296>>>0),x.fullMessageLength[w]>>>= -0,k[0]=k[1]/4294967296>>>0;d.putBytes(e);c(b,h,d);(2048>>0,q+=w,u.putInt32(q>>>0),q=k;k={h0:b.h0,h1:b.h1,h2:b.h2,h3:b.h3, -h4:b.h4};c(k,h,u);u=a.util.createBuffer();u.putInt32(k.h0);u.putInt32(k.h1);u.putInt32(k.h2);u.putInt32(k.h3);u.putInt32(k.h4);return u};return x};var e=null,k=!1}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e=!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge={}),b(forge);var q,k=function(a,c){c.exports=function(c){var e=q.map(function(b){return a(b)}).concat(b);c=c||{};c.defined=c.defined||{};if(c.defined.sha1)return c.sha1;c.defined.sha1= -!0;for(var p=0;pm;++m)b[m]=d.getInt32(); -for(;64>m;++m)e=b[m-2],e=(e>>>17|e<<15)^(e>>>19|e<<13)^e>>>10,n=b[m-15],n=(n>>>7|n<<25)^(n>>>18|n<<14)^n>>>3,b[m]=e+b[m-7]+n+b[m-16]|0;k=a.h0;D=a.h1;z=a.h2;C=a.h3;F=a.h4;w=a.h5;v=a.h6;r=a.h7;for(m=0;64>m;++m)e=(F>>>6|F<<26)^(F>>>11|F<<21)^(F>>>25|F<<7),h=v^F&(w^v),n=(k>>>2|k<<30)^(k>>>13|k<<19)^(k>>>22|k<<10),p=k&D|z&(k^D),e=r+e+h+q[m]+b[m],n+=p,r=v,v=w,w=F,F=C+e|0,C=z,z=D,D=k,k=e+n|0;a.h0=a.h0+k|0;a.h1=a.h1+D|0;a.h2=a.h2+z|0;a.h3=a.h3+C|0;a.h4=a.h4+F|0;a.h5=a.h5+w|0;a.h6=a.h6+v|0;a.h7=a.h7+r|0;R-= -64}}var d=a.sha256=a.sha256||{};a.md=a.md||{};a.md.algorithms=a.md.algorithms||{};a.md.sha256=a.md.algorithms.sha256=d;d.create=function(){k||(e=String.fromCharCode(128),e+=a.util.fillString(String.fromCharCode(0),64),q=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349, -2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],k=!0);var b=null,d=a.util.createBuffer(),h=Array(64),u={algorithm:"sha256",blockLength:64,digestLength:32, -messageLength:0,fullMessageLength:null,messageLengthSize:8,start:function(){u.messageLength=0;u.fullMessageLength=u.messageLength64=[];for(var c=u.messageLengthSize/4,e=0;e>>0,k>>>0],w=u.fullMessageLength.length- -1;0<=w;--w)u.fullMessageLength[w]+=k[1],k[1]=k[0]+(u.fullMessageLength[w]/4294967296>>>0),u.fullMessageLength[w]>>>=0,k[0]=k[1]/4294967296>>>0;d.putBytes(e);c(b,h,d);(2048>>0,B+=q,k.putInt32(B>>>0),B=w;w={h0:b.h0,h1:b.h1,h2:b.h2,h3:b.h3,h4:b.h4,h5:b.h5,h6:b.h6,h7:b.h7};c(w,h,k);k=a.util.createBuffer();k.putInt32(w.h0);k.putInt32(w.h1);k.putInt32(w.h2);k.putInt32(w.h3);k.putInt32(w.h4);k.putInt32(w.h5);k.putInt32(w.h6);k.putInt32(w.h7);return k};return u};var e=null,k=!1,q=null}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e=!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge= -{}),b(forge);var q,k=function(a,c){c.exports=function(c){var e=q.map(function(b){return a(b)}).concat(b);c=c||{};c.defined=c.defined||{};if(c.defined.sha256)return c.sha256;c.defined.sha256=!0;for(var p=0;pI;++I)b[I][0]=d.getInt32()>>>0,b[I][1]=d.getInt32()>>>0;for(;80>I;++I)m=b[I-2],k=m[0],m=m[1],e=((k>>>19|m<<13)^(m>>>29|k<<3)^k>>>6)>>>0,n=((k<<13|m>>>19)^(m<<3|k>>>29)^(k<<26|m>>>6))>>>0,m=b[I-15],k=m[0],m=m[1],h=((k>>>1|m<<31)^(k>>>8|m<<24)^k>>>7)>>>0,g=((k<<31|m>>>1)^(k<<24|m>>>8)^(k<<25|m>>>7))>>>0,k=b[I-7],w=b[I- -16],m=n+k[1]+g+w[1],b[I][0]=e+k[0]+h+w[0]+(m/4294967296>>>0)>>>0,b[I][1]=m>>>0;k=a[0][0];w=a[0][1];r=a[1][0];q=a[1][1];B=a[2][0];T=a[2][1];ca=a[3][0];O=a[3][1];v=a[4][0];V=a[4][1];ba=a[5][0];Z=a[5][1];N=a[6][0];aa=a[6][1];L=a[7][0];G=a[7][1];for(I=0;80>I;++I)e=((v>>>14|V<<18)^(v>>>18|V<<14)^(V>>>9|v<<23))>>>0,m=((v<<18|V>>>14)^(v<<14|V>>>18)^(V<<23|v>>>9))>>>0,n=(N^v&(ba^N))>>>0,z=(aa^V&(Z^aa))>>>0,h=((k>>>28|w<<4)^(w>>>2|k<<30)^(w>>>7|k<<25))>>>0,g=((k<<4|w>>>28)^(w<<30|k>>>2)^(w<<25|k>>>7))>>>0, -C=(k&r|B&(k^r))>>>0,p=(w&q|T&(w^q))>>>0,m=G+m+z+l[I][1]+b[I][1],e=L+e+n+l[I][0]+b[I][0]+(m/4294967296>>>0)>>>0,n=m>>>0,m=g+p,h=h+C+(m/4294967296>>>0)>>>0,g=m>>>0,L=N,G=aa,N=ba,aa=Z,ba=v,Z=V,m=O+n,v=ca+e+(m/4294967296>>>0)>>>0,V=m>>>0,ca=B,O=T,B=r,T=q,r=k,q=w,m=n+g,k=e+h+(m/4294967296>>>0)>>>0,w=m>>>0;m=a[0][1]+w;a[0][0]=a[0][0]+k+(m/4294967296>>>0)>>>0;a[0][1]=m>>>0;m=a[1][1]+q;a[1][0]=a[1][0]+r+(m/4294967296>>>0)>>>0;a[1][1]=m>>>0;m=a[2][1]+T;a[2][0]=a[2][0]+B+(m/4294967296>>>0)>>>0;a[2][1]=m>>> -0;m=a[3][1]+O;a[3][0]=a[3][0]+ca+(m/4294967296>>>0)>>>0;a[3][1]=m>>>0;m=a[4][1]+V;a[4][0]=a[4][0]+v+(m/4294967296>>>0)>>>0;a[4][1]=m>>>0;m=a[5][1]+Z;a[5][0]=a[5][0]+ba+(m/4294967296>>>0)>>>0;a[5][1]=m>>>0;m=a[6][1]+aa;a[6][0]=a[6][0]+N+(m/4294967296>>>0)>>>0;a[6][1]=m>>>0;m=a[7][1]+G;a[7][0]=a[7][0]+L+(m/4294967296>>>0)>>>0;a[7][1]=m>>>0;Y-=128}}var d=a.sha512=a.sha512||{};a.md=a.md||{};a.md.algorithms=a.md.algorithms||{};a.md.sha512=a.md.algorithms.sha512=d;var e=a.sha384=a.sha512.sha384=a.sha512.sha384|| -{};e.create=function(){return d.create("SHA-384")};a.md.sha384=a.md.algorithms.sha384=e;a.sha512.sha256=a.sha512.sha256||{create:function(){return d.create("SHA-512/256")}};a.md["sha512/256"]=a.md.algorithms["sha512/256"]=a.sha512.sha256;a.sha512.sha224=a.sha512.sha224||{create:function(){return d.create("SHA-512/224")}};a.md["sha512/224"]=a.md.algorithms["sha512/224"]=a.sha512.sha224;d.create=function(b){q||(k=String.fromCharCode(128),k+=a.util.fillString(String.fromCharCode(0),128),l=[[1116352408, +'", got "'+b.tagClass+'"'),b.type!==d.type&&h.push("["+d.name+'] Expected type "'+d.type+'", got "'+b.type+'"'));else if(b.constructed===d.constructed||"undefined"===typeof d.constructed){m=!0;if(d.value&&a.util.isArray(d.value))for(var r=0,l=0;m&&lb;++b)h[b]=Math.floor(4294967296* +Math.abs(Math.sin(b+1)));g=!0}function d(a,b,c){for(var e,p,m,n,z,x,C,l=c.length();64<=l;){p=a.h0;m=a.h1;n=a.h2;z=a.h3;for(C=0;16>C;++C)b[C]=c.getInt32Le(),e=z^m&(n^z),e=p+e+h[C]+b[C],x=y[C],p=z,z=n,n=m,m+=e<>>32-x;for(;32>C;++C)e=n^z&(m^n),e=p+e+h[C]+b[k[C]],x=y[C],p=z,z=n,n=m,m+=e<>>32-x;for(;48>C;++C)e=m^n^z,e=p+e+h[C]+b[k[C]],x=y[C],p=z,z=n,n=m,m+=e<>>32-x;for(;64>C;++C)e=n^(m|~z),e=p+e+h[C]+b[k[C]],x=y[C],p=z,z=n,n=m,m+=e<>>32-x;a.h0=a.h0+p|0;a.h1=a.h1+m|0;a.h2=a.h2+n|0;a.h3= +a.h3+z|0;l-=64}}var e=a.md5=a.md5||{};a.md=a.md||{};a.md.algorithms=a.md.algorithms||{};a.md.md5=a.md.algorithms.md5=e;e.create=function(){g||c();var b=null,e=a.util.createBuffer(),h=Array(16),k={algorithm:"md5",blockLength:64,digestLength:16,messageLength:0,fullMessageLength:null,messageLengthSize:8,start:function(){k.messageLength=0;k.fullMessageLength=k.messageLength64=[];for(var c=k.messageLengthSize/4,d=0;d>>0,n>>>0],z=k.fullMessageLength.length-1;0<=z;--z)k.fullMessageLength[z]+=n[1],n[1]=n[0]+(k.fullMessageLength[z]/4294967296>>>0),k.fullMessageLength[z]>>>=0,n[0]=n[1]/4294967296>>>0;e.putBytes(c);d(b,h,e);(2048>>0,c.putInt32Le(m>>>0);m={h0:b.h0,h1:b.h1,h2:b.h2,h3:b.h3};d(m,h,c);c=a.util.createBuffer();c.putInt32Le(m.h0);c.putInt32Le(m.h1);c.putInt32Le(m.h2);c.putInt32Le(m.h3);return c};return k};var l=null,k=null,y=null,h=null,g=!1}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e= +!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge={}),b(forge);var g,l=function(a,c){c.exports=function(c){var e=g.map(function(b){return a(b)}).concat(b);c=c||{};c.defined=c.defined||{};if(c.defined.md5)return c.md5;c.defined.md5=!0;for(var n=0;nD;++D)e=d.getInt32(),b[D]=e,w=l^m&(n^l),e=(p<<5|p>>>27)+w+v+1518500249+e,v=l,l=n,n=m<<30|m>>>2,m=p,p=e;for(;20>D;++D)e=b[D-3]^b[D-8]^b[D-14]^b[D-16],e=e<<1|e>>>31,b[D]=e,w=l^m&(n^l),e=(p<<5|p>>>27)+w+v+1518500249+e,v=l,l=n,n=m<<30|m>>>2,m=p,p=e;for(;32> +D;++D)e=b[D-3]^b[D-8]^b[D-14]^b[D-16],e=e<<1|e>>>31,b[D]=e,w=m^n^l,e=(p<<5|p>>>27)+w+v+1859775393+e,v=l,l=n,n=m<<30|m>>>2,m=p,p=e;for(;40>D;++D)e=b[D-6]^b[D-16]^b[D-28]^b[D-32],e=e<<2|e>>>30,b[D]=e,w=m^n^l,e=(p<<5|p>>>27)+w+v+1859775393+e,v=l,l=n,n=m<<30|m>>>2,m=p,p=e;for(;60>D;++D)e=b[D-6]^b[D-16]^b[D-28]^b[D-32],e=e<<2|e>>>30,b[D]=e,w=m&n|l&(m^n),e=(p<<5|p>>>27)+w+v+2400959708+e,v=l,l=n,n=m<<30|m>>>2,m=p,p=e;for(;80>D;++D)e=b[D-6]^b[D-16]^b[D-28]^b[D-32],e=e<<2|e>>>30,b[D]=e,w=m^n^l,e=(p<<5|p>>> +27)+w+v+3395469782+e,v=l,l=n,n=m<<30|m>>>2,m=p,p=e;a.h0=a.h0+p|0;a.h1=a.h1+m|0;a.h2=a.h2+n|0;a.h3=a.h3+l|0;a.h4=a.h4+v|0;z-=64}}var d=a.sha1=a.sha1||{};a.md=a.md||{};a.md.algorithms=a.md.algorithms||{};a.md.sha1=a.md.algorithms.sha1=d;d.create=function(){l||(e=String.fromCharCode(128),e+=a.util.fillString(String.fromCharCode(0),64),l=!0);var b=null,d=a.util.createBuffer(),h=Array(80),w={algorithm:"sha1",blockLength:64,digestLength:20,messageLength:0,fullMessageLength:null,messageLengthSize:8,start:function(){w.messageLength= +0;w.fullMessageLength=w.messageLength64=[];for(var c=w.messageLengthSize/4,e=0;e>>0,l>>>0],v=w.fullMessageLength.length-1;0<=v;--v)w.fullMessageLength[v]+=l[1],l[1]=l[0]+(w.fullMessageLength[v]/4294967296>>>0),w.fullMessageLength[v]>>>= +0,l[0]=l[1]/4294967296>>>0;d.putBytes(e);c(b,h,d);(2048>>0,v+=A,r.putInt32(v>>>0),v=l;l={h0:b.h0,h1:b.h1,h2:b.h2,h3:b.h3, +h4:b.h4};c(l,h,r);r=a.util.createBuffer();r.putInt32(l.h0);r.putInt32(l.h1);r.putInt32(l.h2);r.putInt32(l.h3);r.putInt32(l.h4);return r};return w};var e=null,l=!1}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e=!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge={}),b(forge);var g,l=function(a,c){c.exports=function(c){var e=g.map(function(b){return a(b)}).concat(b);c=c||{};c.defined=c.defined||{};if(c.defined.sha1)return c.sha1;c.defined.sha1= +!0;for(var n=0;nl;++l)b[l]=d.getInt32(); +for(;64>l;++l)e=b[l-2],e=(e>>>17|e<<15)^(e>>>19|e<<13)^e>>>10,p=b[l-15],p=(p>>>7|p<<25)^(p>>>18|p<<14)^p>>>3,b[l]=e+b[l-7]+p+b[l-16]|0;w=a.h0;D=a.h1;z=a.h2;x=a.h3;C=a.h4;v=a.h5;g=a.h6;q=a.h7;for(l=0;64>l;++l)e=(C>>>6|C<<26)^(C>>>11|C<<21)^(C>>>25|C<<7),m=g^C&(v^g),p=(w>>>2|w<<30)^(w>>>13|w<<19)^(w>>>22|w<<10),n=w&D|z&(w^D),e=q+e+m+k[l]+b[l],p+=n,q=g,g=v,v=C,C=x+e|0,x=z,z=D,D=w,w=e+p|0;a.h0=a.h0+w|0;a.h1=a.h1+D|0;a.h2=a.h2+z|0;a.h3=a.h3+x|0;a.h4=a.h4+C|0;a.h5=a.h5+v|0;a.h6=a.h6+g|0;a.h7=a.h7+q|0;u-= +64}}var d=a.sha256=a.sha256||{};a.md=a.md||{};a.md.algorithms=a.md.algorithms||{};a.md.sha256=a.md.algorithms.sha256=d;d.create=function(){l||(e=String.fromCharCode(128),e+=a.util.fillString(String.fromCharCode(0),64),k=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349, +2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],l=!0);var b=null,d=a.util.createBuffer(),w=Array(64),r={algorithm:"sha256",blockLength:64,digestLength:32, +messageLength:0,fullMessageLength:null,messageLengthSize:8,start:function(){r.messageLength=0;r.fullMessageLength=r.messageLength64=[];for(var c=r.messageLengthSize/4,e=0;e>>0,k>>>0],l=r.fullMessageLength.length- +1;0<=l;--l)r.fullMessageLength[l]+=k[1],k[1]=k[0]+(r.fullMessageLength[l]/4294967296>>>0),r.fullMessageLength[l]>>>=0,k[0]=k[1]/4294967296>>>0;d.putBytes(e);c(b,w,d);(2048>>0,g+=v,k.putInt32(g>>>0),g=l;l={h0:b.h0,h1:b.h1,h2:b.h2,h3:b.h3,h4:b.h4,h5:b.h5,h6:b.h6,h7:b.h7};c(l,w,k);k=a.util.createBuffer();k.putInt32(l.h0);k.putInt32(l.h1);k.putInt32(l.h2);k.putInt32(l.h3);k.putInt32(l.h4);k.putInt32(l.h5);k.putInt32(l.h6);k.putInt32(l.h7);return k};return r};var e=null,l=!1,k=null}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e=!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge= +{}),b(forge);var g,l=function(a,c){c.exports=function(c){var e=g.map(function(b){return a(b)}).concat(b);c=c||{};c.defined=c.defined||{};if(c.defined.sha256)return c.sha256;c.defined.sha256=!0;for(var n=0;nH;++H)b[H][0]=d.getInt32()>>>0,b[H][1]=d.getInt32()>>>0;for(;80>H;++H)h=b[H-2],l=h[0],h=h[1],e=((l>>>19|h<<13)^(h>>>29|l<<3)^l>>>6)>>>0,p=((l<<13|h>>>19)^(h<<3|l>>>29)^(l<<26|h>>>6))>>>0,h=b[H-15],l=h[0],h=h[1],k=((l>>>1|h<<31)^(l>>>8|h<<24)^l>>>7)>>>0,m=((l<<31|h>>>1)^(l<<24|h>>>8)^(l<<25|h>>>7))>>>0,l=b[H-7],w=b[H- +16],h=p+l[1]+m+w[1],b[H][0]=e+l[0]+k+w[0]+(h/4294967296>>>0)>>>0,b[H][1]=h>>>0;l=a[0][0];w=a[0][1];q=a[1][0];v=a[1][1];g=a[2][0];S=a[2][1];ca=a[3][0];O=a[3][1];u=a[4][0];W=a[4][1];U=a[5][0];Z=a[5][1];N=a[6][0];Y=a[6][1];L=a[7][0];G=a[7][1];for(H=0;80>H;++H)e=((u>>>14|W<<18)^(u>>>18|W<<14)^(W>>>9|u<<23))>>>0,h=((u<<18|W>>>14)^(u<<14|W>>>18)^(W<<23|u>>>9))>>>0,p=(N^u&(U^N))>>>0,z=(Y^W&(Z^Y))>>>0,k=((l>>>28|w<<4)^(w>>>2|l<<30)^(w>>>7|l<<25))>>>0,m=((l<<4|w>>>28)^(w<<30|l>>>2)^(w<<25|l>>>7))>>>0,x=(l& +q|g&(l^q))>>>0,n=(w&v|S&(w^v))>>>0,h=G+h+z+y[H][1]+b[H][1],e=L+e+p+y[H][0]+b[H][0]+(h/4294967296>>>0)>>>0,p=h>>>0,h=m+n,k=k+x+(h/4294967296>>>0)>>>0,m=h>>>0,L=N,G=Y,N=U,Y=Z,U=u,Z=W,h=O+p,u=ca+e+(h/4294967296>>>0)>>>0,W=h>>>0,ca=g,O=S,g=q,S=v,q=l,v=w,h=p+m,l=e+k+(h/4294967296>>>0)>>>0,w=h>>>0;h=a[0][1]+w;a[0][0]=a[0][0]+l+(h/4294967296>>>0)>>>0;a[0][1]=h>>>0;h=a[1][1]+v;a[1][0]=a[1][0]+q+(h/4294967296>>>0)>>>0;a[1][1]=h>>>0;h=a[2][1]+S;a[2][0]=a[2][0]+g+(h/4294967296>>>0)>>>0;a[2][1]=h>>>0;h=a[3][1]+ +O;a[3][0]=a[3][0]+ca+(h/4294967296>>>0)>>>0;a[3][1]=h>>>0;h=a[4][1]+W;a[4][0]=a[4][0]+u+(h/4294967296>>>0)>>>0;a[4][1]=h>>>0;h=a[5][1]+Z;a[5][0]=a[5][0]+U+(h/4294967296>>>0)>>>0;a[5][1]=h>>>0;h=a[6][1]+Y;a[6][0]=a[6][0]+N+(h/4294967296>>>0)>>>0;a[6][1]=h>>>0;h=a[7][1]+G;a[7][0]=a[7][0]+L+(h/4294967296>>>0)>>>0;a[7][1]=h>>>0;ba-=128}}var d=a.sha512=a.sha512||{};a.md=a.md||{};a.md.algorithms=a.md.algorithms||{};a.md.sha512=a.md.algorithms.sha512=d;var e=a.sha384=a.sha512.sha384=a.sha512.sha384||{}; +e.create=function(){return d.create("SHA-384")};a.md.sha384=a.md.algorithms.sha384=e;a.sha512.sha256=a.sha512.sha256||{create:function(){return d.create("SHA-512/256")}};a.md["sha512/256"]=a.md.algorithms["sha512/256"]=a.sha512.sha256;a.sha512.sha224=a.sha512.sha224||{create:function(){return d.create("SHA-512/224")}};a.md["sha512/224"]=a.md.algorithms["sha512/224"]=a.sha512.sha224;d.create=function(b){k||(l=String.fromCharCode(128),l+=a.util.fillString(String.fromCharCode(0),128),y=[[1116352408, 3609767458],[1899447441,602891725],[3049323471,3964484399],[3921009573,2173295548],[961987163,4081628472],[1508970993,3053834265],[2453635748,2937671579],[2870763221,3664609560],[3624381080,2734883394],[310598401,1164996542],[607225278,1323610764],[1426881987,3590304994],[1925078388,4068182383],[2162078206,991336113],[2614888103,633803317],[3248222580,3479774868],[3835390401,2666613458],[4022224774,944711139],[264347078,2341262773],[604807628,2007800933],[770255983,1495990901],[1249150122,1856431235], [1555081692,3175218132],[1996064986,2198950837],[2554220882,3999719339],[2821834349,766784016],[2952996808,2566594879],[3210313671,3203337956],[3336571891,1034457026],[3584528711,2466948901],[113926993,3758326383],[338241895,168717936],[666307205,1188179964],[773529912,1546045734],[1294757372,1522805485],[1396182291,2643833823],[1695183700,2343527390],[1986661051,1014477480],[2177026350,1206759142],[2456956037,344077627],[2730485921,1290863460],[2820302411,3158454273],[3259730800,3505952657],[3345764771, 106217008],[3516065817,3606008344],[3600352804,1432725776],[4094571909,1467031594],[275423344,851169720],[430227734,3100823752],[506948616,1363258195],[659060556,3750685593],[883997877,3785050280],[958139571,3318307427],[1322822218,3812723403],[1537002063,2003034995],[1747873779,3602036899],[1955562222,1575990012],[2024104815,1125592928],[2227730452,2716904306],[2361852424,442776044],[2428436474,593698344],[2756734187,3733110249],[3204031479,2999351573],[3329325298,3815920427],[3391569614,3928383900], -[3515267271,566280711],[3940187606,3454069534],[4118630271,4000239992],[116418474,1914138554],[174292421,2731055270],[289380356,3203993006],[460393269,320620315],[685471733,587496836],[852142971,1086792851],[1017036298,365543100],[1126000580,2618297676],[1288033470,3409855158],[1501505948,4234509866],[1607167915,987167468],[1816402316,1246189591]],g={"SHA-512":[[1779033703,4089235720],[3144134277,2227873595],[1013904242,4271175723],[2773480762,1595750129],[1359893119,2917565137],[2600822924,725511199], +[3515267271,566280711],[3940187606,3454069534],[4118630271,4000239992],[116418474,1914138554],[174292421,2731055270],[289380356,3203993006],[460393269,320620315],[685471733,587496836],[852142971,1086792851],[1017036298,365543100],[1126000580,2618297676],[1288033470,3409855158],[1501505948,4234509866],[1607167915,987167468],[1816402316,1246189591]],h={"SHA-512":[[1779033703,4089235720],[3144134277,2227873595],[1013904242,4271175723],[2773480762,1595750129],[1359893119,2917565137],[2600822924,725511199], [528734635,4215389547],[1541459225,327033209]],"SHA-384":[[3418070365,3238371032],[1654270250,914150663],[2438529370,812702999],[355462360,4144912697],[1731405415,4290775857],[2394180231,1750603025],[3675008525,1694076839],[1203062813,3204075428]],"SHA-512/256":[[573645204,4230739756],[2673172387,3360449730],[596883563,1867755857],[2520282905,1497426621],[2519219938,2827943907],[3193839141,1401305490],[721525244,746961066],[246885852,2177182882]],"SHA-512/224":[[2352822216,424955298],[1944164710, -2312950998],[502970286,855612546],[1738396948,1479516111],[258812777,2077511080],[2011393907,79989058],[1067287976,1780299464],[286451373,2446758561]]},q=!0);"undefined"===typeof b&&(b="SHA-512");if(!(b in g))throw Error("Invalid SHA-512 algorithm: "+b);for(var d=g[b],e=null,h=a.util.createBuffer(),m=Array(80),H=0;80>H;++H)m[H]=Array(2);var E={algorithm:b.replace("-","").toLowerCase(),blockLength:128,digestLength:64,messageLength:0,fullMessageLength:null,messageLengthSize:16,start:function(){E.messageLength= -0;E.fullMessageLength=E.messageLength128=[];for(var b=E.messageLengthSize/4,c=0;c>>0,g>>>0],l=E.fullMessageLength.length-1;0<=l;--l)E.fullMessageLength[l]+=g[1],g[1]=g[0]+(E.fullMessageLength[l]/4294967296>>>0),E.fullMessageLength[l]>>>=0,g[0]= -g[1]/4294967296>>>0;h.putBytes(b);c(e,m,h);(2048>>0,l+=C,d.putInt32(l>>>0),l=g;g=Array(e.length);for(u=0;ub.blockLength&&(b.start(),b.update(l.bytes()),l=b.digest());c=a.util.createBuffer();d=a.util.createBuffer();u=l.length();for(k=0;k>>4^m)&252645135;m^=b;h^=b<<4;b=(h>>>16^m)&65535;m^=b;h^=b<<16;b=(m>>>2^h)&858993459;h^=b;m^=b<<2;b=(m>>>8^h)&16711935;h^=b;m^=b<<8;b=(h>>>1^m)&1431655765;for(var m=m^b,h=h^b<<1,h=h<<1|h>>>31,m=m<<1|m>>>31,p=0;p>>4|m<<28)^a[R+1];b=h; -h=m;m=b^(q[U>>>24&63]|g[U>>>16&63]|u[U>>>8&63]|A[U&63]|k[T>>>24&63]|l[T>>>16&63]|x[T>>>8&63]|J[T&63])}b=h;h=m;m=b}h=h>>>1|h<<31;m=m>>>1|m<<31;b=(h>>>1^m)&1431655765;m^=b;h^=b<<1;b=(m>>>8^h)&16711935;h^=b;m^=b<<8;b=(m>>>2^h)&858993459;h^=b;m^=b<<2;b=(h>>>16^m)&65535;m^=b;h^=b<<16;b=(h>>>4^m)&252645135;c[0]=h^b<<4;c[1]=m^b}function e(b){b=b||{};var c="DES-"+(b.mode||"CBC").toUpperCase(),d;d=b.decrypt?a.cipher.createDecipher(c,b.key):a.cipher.createCipher(c,b.key);var h=d.start;d.start=function(b,c){var e= +2312950998],[502970286,855612546],[1738396948,1479516111],[258812777,2077511080],[2011393907,79989058],[1067287976,1780299464],[286451373,2446758561]]},k=!0);"undefined"===typeof b&&(b="SHA-512");if(!(b in h))throw Error("Invalid SHA-512 algorithm: "+b);for(var d=h[b],e=null,m=a.util.createBuffer(),w=Array(80),g=0;80>g;++g)w[g]=Array(2);var F={algorithm:b.replace("-","").toLowerCase(),blockLength:128,digestLength:64,messageLength:0,fullMessageLength:null,messageLengthSize:16,start:function(){F.messageLength= +0;F.fullMessageLength=F.messageLength128=[];for(var b=F.messageLengthSize/4,c=0;c>>0,h>>>0],k=F.fullMessageLength.length-1;0<=k;--k)F.fullMessageLength[k]+=h[1],h[1]=h[0]+(F.fullMessageLength[k]/4294967296>>>0),F.fullMessageLength[k]>>>=0,h[0]= +h[1]/4294967296>>>0;m.putBytes(b);c(e,w,m);(2048>>0,k+=x,d.putInt32(k>>>0),k=h;h=Array(e.length);for(r=0;rb.blockLength&&(b.start(),b.update(y.bytes()),y=b.digest());c=a.util.createBuffer();d=a.util.createBuffer();r=y.length();for(l=0;l>>4^m)&252645135;m^=b;x^=b<<4;b=(x>>>16^m)&65535;m^=b;x^=b<<16;b=(m>>>2^x)&858993459;x^=b;m^=b<<2;b=(m>>>8^x)&16711935;x^=b;m^=b<<8;b=(x>>>1^m)&1431655765;for(var m=m^b,x=x^b<<1,x=x<<1|x>>>31,m=m<<1|m>>>31,n=0;n>>4|m<<28)^a[u+1];b=x; +x=m;m=b^(k[T>>>24&63]|h[T>>>16&63]|r[T>>>8&63]|A[T&63]|l[S>>>24&63]|y[S>>>16&63]|g[S>>>8&63]|E[S&63])}b=x;x=m;m=b}x=x>>>1|x<<31;m=m>>>1|m<<31;b=(x>>>1^m)&1431655765;m^=b;x^=b<<1;b=(m>>>8^x)&16711935;x^=b;m^=b<<8;b=(m>>>2^x)&858993459;x^=b;m^=b<<2;b=(x>>>16^m)&65535;m^=b;x^=b<<16;b=(x>>>4^m)&252645135;c[0]=x^b<<4;c[1]=m^b}function e(b){b=b||{};var c="DES-"+(b.mode||"CBC").toUpperCase(),d;d=b.decrypt?a.cipher.createDecipher(c,b.key):a.cipher.createCipher(c,b.key);var h=d.start;d.start=function(b,c){var e= null;c instanceof a.util.ByteBuffer&&(e=c,c={});c=c||{};c.output=e;c.iv=b;h.call(d,c)};return d}a.des=a.des||{};a.des.startEncrypting=function(a,b,c,d){a=e({key:a,output:c,decrypt:!1,mode:d||(null===b?"ECB":"CBC")});a.start(b);return a};a.des.createEncryptionCipher=function(a,b){return e({key:a,output:null,decrypt:!1,mode:b})};a.des.startDecrypting=function(a,b,c,d){a=e({key:a,output:c,decrypt:!0,mode:d||(null===b?"ECB":"CBC")});a.start(b);return a};a.des.createDecryptionCipher=function(a,b){return e({key:a, output:null,decrypt:!0,mode:b})};a.des.Algorithm=function(a,b){var c=this;c.name=a;c.mode=new b({blockSize:8,cipher:{encrypt:function(a,b){return d(c._keys,a,b,!1)},decrypt:function(a,b){return d(c._keys,a,b,!0)}}});c._init=!1};a.des.Algorithm.prototype.initialize=function(b){if(!this._init){b=a.util.createBuffer(b.key);if(0===this.name.indexOf("3DES")&&24!==b.length())throw Error("Invalid Triple-DES key size: "+8*b.length());for(var c=[0,4,536870912,536870916,65536,65540,536936448,536936452,512, -516,536871424,536871428,66048,66052,536936960,536936964],d=[0,1,1048576,1048577,67108864,67108865,68157440,68157441,256,257,1048832,1048833,67109120,67109121,68157696,68157697],e=[0,8,2048,2056,16777216,16777224,16779264,16779272,0,8,2048,2056,16777216,16777224,16779264,16779272],h=[0,2097152,134217728,136314880,8192,2105344,134225920,136323072,131072,2228224,134348800,136445952,139264,2236416,134356992,136454144],g=[0,262144,16,262160,0,262144,16,262160,4096,266240,4112,266256,4096,266240,4112,266256], -m=[0,1024,32,1056,0,1024,32,1056,33554432,33555456,33554464,33555488,33554432,33555456,33554464,33555488],p=[0,268435456,524288,268959744,2,268435458,524290,268959746,0,268435456,524288,268959744,2,268435458,524290,268959746],l=[0,65536,2048,67584,536870912,536936448,536872960,536938496,131072,196608,133120,198656,537001984,537067520,537004032,537069568],u=[0,262144,0,262144,2,262146,2,262146,33554432,33816576,33554432,33816576,33554434,33816578,33554434,33816578],k=[0,268435456,8,268435464,0,268435456, -8,268435464,1024,268436480,1032,268436488,1024,268436480,1032,268436488],q=[0,32,0,32,1048576,1048608,1048576,1048608,8192,8224,8192,8224,1056768,1056800,1056768,1056800],w=[0,16777216,512,16777728,2097152,18874368,2097664,18874880,67108864,83886080,67109376,83886592,69206016,85983232,69206528,85983744],x=[0,4096,134217728,134221824,524288,528384,134742016,134746112,16,4112,134217744,134221840,524304,528400,134742032,134746128],A=[0,4,256,260,0,4,256,260,1,5,257,261,1,5,257,261],J=8>>4^G)&252645135;G^=N;L^=N<<4;N=(G>>>-16^L)&65535;L^=N;G^=N<<-16;N=(L>>>2^G)&858993459;G^=N;L^=N<<2;N=(G>>>-16^L)&65535;L^=N;G^=N<<-16;N=(L>>>1^G)&1431655765;G^=N;L^=N<<1;N=(G>>>8^L)&16711935;L^=N;G^=N<<8;N=(L>>>1^G)&1431655765;G^=N;L^=N<<1;N=L<<8|G>>>20&240;for(var L=G<<24|G<<8&16711680|G>>>8&65280|G>>>24&240,G=N,I=0;I>>26,G=G<<2|G>>>26):(L=L<<1|L>>>27,G=G<<1|G>>> -27);var L=L&-15,G=G&-15,Y=c[L>>>28]|d[L>>>24&15]|e[L>>>20&15]|h[L>>>16&15]|g[L>>>12&15]|m[L>>>8&15]|p[L>>>4&15],da=l[G>>>28]|u[G>>>24&15]|k[G>>>20&15]|q[G>>>16&15]|w[G>>>12&15]|x[G>>>8&15]|A[G>>>4&15];N=(da>>>16^Y)&65535;B[Z++]=Y^N;B[Z++]=da^N<<16}}this._keys=B;this._init=!0}};c("DES-ECB",a.cipher.modes.ecb);c("DES-CBC",a.cipher.modes.cbc);c("DES-CFB",a.cipher.modes.cfb);c("DES-OFB",a.cipher.modes.ofb);c("DES-CTR",a.cipher.modes.ctr);c("3DES-ECB",a.cipher.modes.ecb);c("3DES-CBC",a.cipher.modes.cbc); -c("3DES-CFB",a.cipher.modes.cfb);c("3DES-OFB",a.cipher.modes.ofb);c("3DES-CTR",a.cipher.modes.ctr);var k=[16843776,0,65536,16843780,16842756,66564,4,65536,1024,16843776,16843780,1024,16778244,16842756,16777216,4,1028,16778240,16778240,66560,66560,16842752,16842752,16778244,65540,16777220,16777220,65540,0,1028,66564,16777216,65536,16843780,4,16842752,16843776,16777216,16777216,1024,16842756,65536,66560,16777220,1024,4,16778244,66564,16843780,65540,16842752,16778244,16777220,1028,66564,16843776,1028, -16778240,16778240,0,65540,66560,0,16842756],q=[-2146402272,-2147450880,32768,1081376,1048576,32,-2146435040,-2147450848,-2147483616,-2146402272,-2146402304,-2147483648,-2147450880,1048576,32,-2146435040,1081344,1048608,-2147450848,0,-2147483648,32768,1081376,-2146435072,1048608,-2147483616,0,1081344,32800,-2146402304,-2146435072,32800,0,1081376,-2146435040,1048576,-2147450848,-2146435072,-2146402304,32768,-2146435072,-2147450880,32,-2146402272,1081376,32,32768,-2147483648,32800,-2146402304,1048576, --2147483616,1048608,-2147450848,-2147483616,1048608,1081344,0,-2147450880,32800,-2147483648,-2146435040,-2146402272,1081344],l=[520,134349312,0,134348808,134218240,0,131592,134218240,131080,134217736,134217736,131072,134349320,131080,134348800,520,134217728,8,134349312,512,131584,134348800,134348808,131592,134218248,131584,131072,134218248,8,134349320,512,134217728,134349312,134217728,131080,520,131072,134349312,134218240,0,512,131080,134349320,134218240,134217736,512,0,134348808,134218248,131072, -134217728,134349320,8,131592,131584,134217736,134348800,134218248,520,134348800,131592,8,134348808,131584],g=[8396801,8321,8321,128,8396928,8388737,8388609,8193,0,8396800,8396800,8396929,129,0,8388736,8388609,1,8192,8388608,8396801,128,8388608,8193,8320,8388737,1,8320,8388736,8192,8396928,8396929,129,8388736,8388609,8396800,8396929,129,0,0,8396800,8320,8388736,8388737,1,8396801,8321,8321,128,8396929,129,1,8192,8388609,8193,8396928,8388737,8193,8320,8388608,8396801,128,8388608,8192,8396928],x=[256, +516,536871424,536871428,66048,66052,536936960,536936964],d=[0,1,1048576,1048577,67108864,67108865,68157440,68157441,256,257,1048832,1048833,67109120,67109121,68157696,68157697],e=[0,8,2048,2056,16777216,16777224,16779264,16779272,0,8,2048,2056,16777216,16777224,16779264,16779272],h=[0,2097152,134217728,136314880,8192,2105344,134225920,136323072,131072,2228224,134348800,136445952,139264,2236416,134356992,136454144],x=[0,262144,16,262160,0,262144,16,262160,4096,266240,4112,266256,4096,266240,4112,266256], +m=[0,1024,32,1056,0,1024,32,1056,33554432,33555456,33554464,33555488,33554432,33555456,33554464,33555488],k=[0,268435456,524288,268959744,2,268435458,524290,268959746,0,268435456,524288,268959744,2,268435458,524290,268959746],n=[0,65536,2048,67584,536870912,536936448,536872960,536938496,131072,196608,133120,198656,537001984,537067520,537004032,537069568],r=[0,262144,0,262144,2,262146,2,262146,33554432,33816576,33554432,33816576,33554434,33816578,33554434,33816578],y=[0,268435456,8,268435464,0,268435456, +8,268435464,1024,268436480,1032,268436488,1024,268436480,1032,268436488],l=[0,32,0,32,1048576,1048608,1048576,1048608,8192,8224,8192,8224,1056768,1056800,1056768,1056800],A=[0,16777216,512,16777728,2097152,18874368,2097664,18874880,67108864,83886080,67109376,83886592,69206016,85983232,69206528,85983744],g=[0,4096,134217728,134221824,524288,528384,134742016,134746112,16,4112,134217744,134221840,524304,528400,134742032,134746128],w=[0,4,256,260,0,4,256,260,1,5,257,261,1,5,257,261],v=8>>4^G)&252645135;G^=N;L^=N<<4;N=(G>>>-16^L)&65535;L^=N;G^=N<<-16;N=(L>>>2^G)&858993459;G^=N;L^=N<<2;N=(G>>>-16^L)&65535;L^=N;G^=N<<-16;N=(L>>>1^G)&1431655765;G^=N;L^=N<<1;N=(G>>>8^L)&16711935;L^=N;G^=N<<8;N=(L>>>1^G)&1431655765;G^=N;L^=N<<1;N=L<<8|G>>>20&240;for(var L=G<<24|G<<8&16711680|G>>>8&65280|G>>>24&240,G=N,H=0;H>>26,G=G<<2|G>>>26):(L=L<<1|L>>>27,G=G<<1|G>>>27); +var L=L&-15,G=G&-15,ba=c[L>>>28]|d[L>>>24&15]|e[L>>>20&15]|h[L>>>16&15]|x[L>>>12&15]|m[L>>>8&15]|k[L>>>4&15],da=n[G>>>28]|r[G>>>24&15]|y[G>>>20&15]|l[G>>>16&15]|A[G>>>12&15]|g[G>>>8&15]|w[G>>>4&15];N=(da>>>16^ba)&65535;E[u++]=ba^N;E[u++]=da^N<<16}}this._keys=E;this._init=!0}};c("DES-ECB",a.cipher.modes.ecb);c("DES-CBC",a.cipher.modes.cbc);c("DES-CFB",a.cipher.modes.cfb);c("DES-OFB",a.cipher.modes.ofb);c("DES-CTR",a.cipher.modes.ctr);c("3DES-ECB",a.cipher.modes.ecb);c("3DES-CBC",a.cipher.modes.cbc); +c("3DES-CFB",a.cipher.modes.cfb);c("3DES-OFB",a.cipher.modes.ofb);c("3DES-CTR",a.cipher.modes.ctr);var l=[16843776,0,65536,16843780,16842756,66564,4,65536,1024,16843776,16843780,1024,16778244,16842756,16777216,4,1028,16778240,16778240,66560,66560,16842752,16842752,16778244,65540,16777220,16777220,65540,0,1028,66564,16777216,65536,16843780,4,16842752,16843776,16777216,16777216,1024,16842756,65536,66560,16777220,1024,4,16778244,66564,16843780,65540,16842752,16778244,16777220,1028,66564,16843776,1028, +16778240,16778240,0,65540,66560,0,16842756],k=[-2146402272,-2147450880,32768,1081376,1048576,32,-2146435040,-2147450848,-2147483616,-2146402272,-2146402304,-2147483648,-2147450880,1048576,32,-2146435040,1081344,1048608,-2147450848,0,-2147483648,32768,1081376,-2146435072,1048608,-2147483616,0,1081344,32800,-2146402304,-2146435072,32800,0,1081376,-2146435040,1048576,-2147450848,-2146435072,-2146402304,32768,-2146435072,-2147450880,32,-2146402272,1081376,32,32768,-2147483648,32800,-2146402304,1048576, +-2147483616,1048608,-2147450848,-2147483616,1048608,1081344,0,-2147450880,32800,-2147483648,-2146435040,-2146402272,1081344],y=[520,134349312,0,134348808,134218240,0,131592,134218240,131080,134217736,134217736,131072,134349320,131080,134348800,520,134217728,8,134349312,512,131584,134348800,134348808,131592,134218248,131584,131072,134218248,8,134349320,512,134217728,134349312,134217728,131080,520,131072,134349312,134218240,0,512,131080,134349320,134218240,134217736,512,0,134348808,134218248,131072, +134217728,134349320,8,131592,131584,134217736,134348800,134218248,520,134348800,131592,8,134348808,131584],h=[8396801,8321,8321,128,8396928,8388737,8388609,8193,0,8396800,8396800,8396929,129,0,8388736,8388609,1,8192,8388608,8396801,128,8388608,8193,8320,8388737,1,8320,8388736,8192,8396928,8396929,129,8388736,8388609,8396800,8396929,129,0,0,8396800,8320,8388736,8388737,1,8396801,8321,8321,128,8396929,129,1,8192,8388609,8193,8396928,8388737,8193,8320,8388608,8396801,128,8388608,8192,8396928],g=[256, 34078976,34078720,1107296512,524288,256,1073741824,34078720,1074266368,524288,33554688,1074266368,1107296512,1107820544,524544,1073741824,33554432,1074266112,1074266112,0,1073742080,1107820800,1107820800,33554688,1107820544,1073742080,0,1107296256,34078976,33554432,1107296256,524544,524288,1107296512,256,33554432,1073741824,34078720,1107296512,1074266368,33554688,1073741824,1107820544,34078976,1074266368,256,33554432,1107820544,1107820800,524544,1107296256,1107820800,34078720,0,1074266112,1107296256, -524544,33554688,1073742080,524288,0,1074266112,34078976,1073742080],u=[536870928,541065216,16384,541081616,541065216,16,541081616,4194304,536887296,4210704,4194304,536870928,4194320,536887296,536870912,16400,0,4194320,536887312,16384,4210688,536887312,16,541065232,541065232,0,4210704,541081600,16400,4210688,541081600,536870912,536887296,16,541065232,4210688,541081616,4194304,16400,536870928,4194304,536887296,536870912,16400,536870928,541081616,4210688,541065216,4210704,541081600,0,541065232,16,16384, -541065216,4210704,16384,4194320,536887312,0,541081600,536870912,4194320,536887312],J=[2097152,69206018,67110914,0,2048,67110914,2099202,69208064,69208066,2097152,0,67108866,2,67108864,69206018,2050,67110912,2099202,2097154,67110912,67108866,69206016,69208064,2097154,69206016,2048,2050,69208066,2099200,2,67108864,2099200,67108864,2099200,2097152,67110914,67110914,69206018,69206018,2,2097154,67108864,67110912,2097152,69208064,2050,2099202,69208064,2050,67108866,69208066,69206016,2099200,0,2,69208066, +524544,33554688,1073742080,524288,0,1074266112,34078976,1073742080],r=[536870928,541065216,16384,541081616,541065216,16,541081616,4194304,536887296,4210704,4194304,536870928,4194320,536887296,536870912,16400,0,4194320,536887312,16384,4210688,536887312,16,541065232,541065232,0,4210704,541081600,16400,4210688,541081600,536870912,536887296,16,541065232,4210688,541081616,4194304,16400,536870928,4194304,536887296,536870912,16400,536870928,541081616,4210688,541065216,4210704,541081600,0,541065232,16,16384, +541065216,4210704,16384,4194320,536887312,0,541081600,536870912,4194320,536887312],E=[2097152,69206018,67110914,0,2048,67110914,2099202,69208064,69208066,2097152,0,67108866,2,67108864,69206018,2050,67110912,2099202,2097154,67110912,67108866,69206016,69208064,2097154,69206016,2048,2050,69208066,2099200,2,67108864,2099200,67108864,2099200,2097152,67110914,67110914,69206018,69206018,2,2097154,67108864,67110912,2097152,69208064,2050,2099202,69208064,2050,67108866,69208066,69206016,2099200,0,2,69208066, 0,2099202,69206016,2048,67108866,67110912,2048,2097154],A=[268439616,4096,262144,268701760,268435456,268439616,64,268435456,262208,268697600,268701760,266240,268701696,266304,4096,64,268697600,268435520,268439552,4160,266240,262208,268697664,268701696,4160,0,0,268697664,268435520,268439552,266304,262144,266304,262144,268701696,4096,64,268697664,4096,266304,268439552,64,268435520,268697600,268697664,268435456,262144,268439616,0,268701760,262208,268435520,268697600,268439552,268439616,0,268701760,266240, -266240,4160,4160,262208,268435456,268701696]}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e=!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge={}),b(forge);var q,k=function(a,c){c.exports=function(c){var e=q.map(function(b){return a(b)}).concat(b);c=c||{};c.defined=c.defined||{};if(c.defined.des)return c.des;c.defined.des=!0;for(var p=0;pv)return u(null,z); -D.start(null,null);D.update(c);D.update(a.util.int32ToBytes(W));C=M=D.digest().getBytes();r=2;q()}function q(){if(r<=d)return D.start(null,null),D.update(M),F=D.digest().getBytes(),C=a.util.xorBytes(C,F,y),M=F,++r,a.util.setImmediate(q);z+=W4294967295*y){b=Error("Derived key is too long."); -if(u)return u(b);throw b;}var v=Math.ceil(g/y),E=g-(v-1)*y,D=a.hmac.create();D.start(p,b);var z="",C,F,M;if(!u){for(var W=1;W<=v;++W){D.start(null,null);D.update(c);D.update(a.util.int32ToBytes(W));C=M=D.digest().getBytes();for(var r=2;r<=d;++r)D.start(null,null),D.update(M),F=D.digest().getBytes(),C=a.util.xorBytes(C,F,y),M=F;z+=Wc;++c)b=31===b?2147483648:b<<2,0===b%g.reseeds&&(a.update(g.pools[c].digest().getBytes()),g.pools[c].start());b=a.digest().getBytes();a.start();a.update(b);a=a.digest().getBytes();g.key=g.plugin.formatKey(b);g.seed=g.plugin.formatSeed(a);g.reseeds=4294967295===g.reseeds?0:g.reseeds+1;g.generated=0}function p(b){var c=null;if("undefined"!==typeof window){var d=window.crypto||window.msCrypto;d&&d.getRandomValues&&(c=function(a){return d.getRandomValues(a)})}var e= -a.util.createBuffer();if(c)for(;e.length()>16),h+=(c&32767)<<16,h+=c>>15,h=(h&2147483647)+(h>>31),c=h&4294967295,h=0;3>h;++h)g=c>>>(h<<3),g^=Math.floor(256*Math.random()), -e.putByte(String.fromCharCode(g&255));return e.getBytes(b)}var g={plugin:b,key:null,seed:null,time:null,reseeds:0,generated:0};b=b.md;for(var k=Array(32),u=0;32>u;++u)k[u]=b.create();g.pools=k;g.pool=0;g.generate=function(b,d){function e(u){if(u)return d(u);if(C.length()>=b)return d(null,C.getBytes(b));1048575>d&255);g.collect(c)};g.registerWorker=function(a){a===self?g.seedFile=function(a,b){function c(a){a=a.data;a.forge&&a.forge.prng&&(self.removeEventListener("message",c),b(a.forge.prng.err,a.forge.prng.bytes))}self.addEventListener("message",c);self.postMessage({forge:{prng:{needed:a}}})}:a.addEventListener("message",function(b){b=b.data;b.forge&&b.forge.prng&&g.seedFile(b.forge.prng.needed,function(b,c){a.postMessage({forge:{prng:{err:b,bytes:c}}})})})}; -return g}}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e=!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge={}),b(forge);var q,k=function(a,c){c.exports=function(c){var e=q.map(function(b){return a(b)}).concat(b);c=c||{};c.defined=c.defined||{};if(c.defined.prng)return c.prng;c.defined.prng=!0;for(var p=0;pI)return r(null,z); +D.start(null,null);D.update(c);D.update(a.util.int32ToBytes(u));x=M=D.digest().getBytes();q=2;A()}function A(){if(q<=d)return D.start(null,null),D.update(M),C=D.digest().getBytes(),x=a.util.xorBytes(x,C,g),M=C,++q,a.util.setImmediate(A);z+=u4294967295*g){b=Error("Derived key is too long."); +if(r)return r(b);throw b;}var I=Math.ceil(h/g),F=h-(I-1)*g,D=a.hmac.create();D.start(n,b);var z="",x,C,M;if(!r){for(var u=1;u<=I;++u){D.start(null,null);D.update(c);D.update(a.util.int32ToBytes(u));x=M=D.digest().getBytes();for(var q=2;q<=d;++q)D.start(null,null),D.update(M),C=D.digest().getBytes(),x=a.util.xorBytes(x,C,g),M=C;z+=uc;++c)b=31===b?2147483648:b<<2,0===b%h.reseeds&&(a.update(h.pools[c].digest().getBytes()),h.pools[c].start());b=a.digest().getBytes();a.start();a.update(b);a=a.digest().getBytes();h.key=h.plugin.formatKey(b);h.seed=h.plugin.formatSeed(a);h.reseeds=4294967295===h.reseeds?0:h.reseeds+1;h.generated=0}function n(b){var c=null;if("undefined"!==typeof window){var d=window.crypto||window.msCrypto;d&&d.getRandomValues&&(c=function(a){return d.getRandomValues(a)})}var e= +a.util.createBuffer();if(c)for(;e.length()>16),h+=(c&32767)<<16,h+=c>>15,h=(h&2147483647)+(h>>31),c=h&4294967295,h=0;3>h;++h)m=c>>>(h<<3),m^=Math.floor(256*Math.random()), +e.putByte(String.fromCharCode(m&255));return e.getBytes(b)}var h={plugin:b,key:null,seed:null,time:null,reseeds:0,generated:0};b=b.md;for(var l=Array(32),r=0;32>r;++r)l[r]=b.create();h.pools=l;h.pool=0;h.generate=function(b,d){function e(r){if(r)return d(r);if(x.length()>=b)return d(null,x.getBytes(b));1048575>d&255);h.collect(c)};h.registerWorker=function(a){a===self?h.seedFile=function(a,b){function c(a){a=a.data;a.forge&&a.forge.prng&&(self.removeEventListener("message",c),b(a.forge.prng.err,a.forge.prng.bytes))}self.addEventListener("message",c);self.postMessage({forge:{prng:{needed:a}}})}:a.addEventListener("message",function(b){b=b.data;b.forge&&b.forge.prng&&h.seedFile(b.forge.prng.needed,function(b,c){a.postMessage({forge:{prng:{err:b,bytes:c}}})})})}; +return h}}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e=!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge={}),b(forge);var g,l=function(a,c){c.exports=function(c){var e=g.map(function(b){return a(b)}).concat(b);c=c||{};c.defined=c.defined||{};if(c.defined.prng)return c.prng;c.defined.prng=!0;for(var n=0;n>(m&7),k;for(k=h;128>k;k++)e.putByte(c[e.at(k- -1)+e.at(k-h)&255]);e.setAt(128-u,c[e.at(128-u)&m]);for(k=127-u;0<=k;k--)e.setAt(k,c[e.at(k+1)^e.at(k+u)]);return e};var e=function(b,c,e){var g=!1,m=null,p=null,k=null,q,y,v,E,D=[];b=a.rc2.expandKey(b,c);for(v=0;64>v;v++)D.push(b.getInt16Le());e?(q=function(a){for(v=0;4>v;v++){a[v]+=D[E]+(a[(v+3)%4]&a[(v+2)%4])+(~a[(v+3)%4]&a[(v+1)%4]);var b=a[v],c=d[v];a[v]=b<>16-c;E++}},y=function(a){for(v=0;4>v;v++)a[v]+=D[a[(v+3)%4]&63]}):(q=function(a){for(v=3;0<=v;v--){var b=a[v],c=d[v];a[v]= -(b&65535)>>c|b<<16-c&65535;a[v]-=D[E]+(a[(v+3)%4]&a[(v+2)%4])+(~a[(v+3)%4]&a[(v+1)%4]);E--}},y=function(a){for(v=3;0<=v;v--)a[v]-=D[a[(v+3)%4]&63]});var z=null;return z={start:function(b,c){b&&"string"===typeof b&&(b=a.util.createBuffer(b));g=!1;m=a.util.createBuffer();p=c||new a.util.createBuffer;k=b;z.output=p},update:function(a){for(g||m.putBuffer(a);8<=m.length();){a=[[5,q],[1,y],[6,q],[1,y],[5,q]];var b=[];for(v=0;4>v;v++){var c=m.getInt16Le();null!==k&&(e?c^=k.getInt16Le():k.putInt16Le(c)); -b.push(c&65535)}E=e?0:63;for(c=0;cv;v++)null!==k&&(e?k.putInt16Le(b[v]):b[v]^=k.getInt16Le()),p.putInt16Le(b[v])}},finish:function(a){var b=!0;if(e)if(a)b=a(8,m,!e);else{var c=8===m.length()?8:8-m.length();m.fillWithByte(c,c)}b&&(g=!0,z.update());!e&&(b=0===m.length())&&(a?b=a(8,p,!e):(a=p.length(),c=p.at(a-1),c>a?b=!1:p.truncate(c)));return b}}};a.rc2.startEncrypting=function(b,c,d){b=a.rc2.createEncryptionCipher(b,128);b.start(c,d);return b}; -a.rc2.createEncryptionCipher=function(a,b){return e(a,b,!0)};a.rc2.startDecrypting=function(b,c,d){b=a.rc2.createDecryptionCipher(b,128);b.start(c,d);return b};a.rc2.createDecryptionCipher=function(a,b){return e(a,b,!1)}}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e=!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge={}),b(forge);var q,k=function(a,c){c.exports=function(c){var e=q.map(function(b){return a(b)}).concat(b);c=c||{};c.defined=c.defined|| -{};if(c.defined.rc2)return c.rc2;c.defined.rc2=!0;for(var p=0;p>=15;0<=--n;){var g=this.data[a]&32767,m=this.data[a++]>>15,z=b*g+m*h,g=h*g+((z&32767)<<15)+c.data[d]+(e&1073741823);e=(g>>>30)+(z>>>15)+b*m+(e>>>30);c.data[d++]=g&1073741823}return e}function q(a,b, -c,d,e,n){var h=b&16383;for(b>>=14;0<=--n;){var g=this.data[a]&16383,m=this.data[a++]>>14,z=b*g+m*h,g=h*g+((z&16383)<<14)+c.data[d]+e;e=(g>>28)+(z>>14)+b*m;c.data[d++]=g&268435455}return e}function l(a,b){var c=W[a.charCodeAt(b)];return null==c?-1:c}function g(a){var b=d();b.fromInt(a);return b}function x(a){var b=1,c;0!=(c=a>>>16)&&(a=c,b+=16);0!=(c=a>>8)&&(a=c,b+=8);0!=(c=a>>4)&&(a=c,b+=4);0!=(c=a>>2)&&(a=c,b+=2);0!=a>>1&&(b+=1);return b}function u(a){this.m=a}function v(a){this.m=a;this.mp=a.invDigit(); -this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<=r;++r)W[M++]=r;M=97;for(r=10;36>r;++r)W[M++]=r;M=65;for(r=10;36>r;++r)W[M++]=r;u.prototype.convert=function(a){return 0>a.s||0<=a.compareTo(this.m)?a.mod(this.m):a};u.prototype.revert=function(a){return a};u.prototype.reduce= -function(a){a.divRemTo(this.m,null,a)};u.prototype.mulTo=function(a,b,c){a.multiplyTo(b,c);this.reduce(c)};u.prototype.sqrTo=function(a,b){a.squareTo(b);this.reduce(b)};v.prototype.convert=function(a){var b=d();a.abs().dlShiftTo(this.m.t,b);b.divRemTo(this.m,null,b);0>a.s&&0>15)*this.mpl&this.um)<<15)&a.DM,c=b+this.m.t;for(a.data[c]+=this.m.am(0,d,a,b,0,this.m.t);a.data[c]>=a.DV;)a.data[c]-=a.DV,a.data[++c]++}a.clamp();a.drShiftTo(this.m.t,a);0<=a.compareTo(this.m)&&a.subTo(this.m,a)};v.prototype.mulTo=function(a,b,c){a.multiplyTo(b,c);this.reduce(c)};v.prototype.sqrTo=function(a,b){a.squareTo(b);this.reduce(b)};c.prototype.copyTo=function(a){for(var b=this.t-1;0<=b;--b)a.data[b]=this.data[b];a.t=this.t;a.s=this.s}; -c.prototype.fromInt=function(a){this.t=1;this.s=0>a?-1:0;0a?this.data[0]=a+this.DV:this.t=0};c.prototype.fromString=function(a,b){var d;if(16==b)d=4;else if(8==b)d=3;else if(256==b)d=8;else if(2==b)d=1;else if(32==b)d=5;else if(4==b)d=2;else{this.fromRadix(a,b);return}this.s=this.t=0;for(var e=a.length,n=!1,h=0;0<=--e;){var g=8==d?a[e]&255:l(a,e);0>g?"-"==a.charAt(e)&&(n=!0):(n=!1,0==h?this.data[this.t++]=g:h+d>this.DB?(this.data[this.t-1]|=(g&(1<>this.DB-h):this.data[this.t-1]|=g<=this.DB&&(h-=this.DB))}8==d&&0!=(a[0]&128)&&(this.s=-1,0>d|h,h=(this.data[g]&e)<=this.t)b.t=0;else{var d=a%this.DB,e=this.DB-d,n=(1<>d;for(var h= -c+1;h>d;0>=this.DB;if(a.t>=this.DB;d+=this.s}else{for(d+=this.s;c>=this.DB;d-=a.s}b.s=0>d?-1:0;-1>d?b.data[c++]=this.DV+d:0=b.DV&&(a.data[c+b.t]-=b.DV,a.data[c+b.t+1]=1)}0=n.t)){var g=this.abs();if(g.t>this.F2:0),u=this.FV/C,C=(1<z&&c.ZERO.subTo(e,e)}}}};c.prototype.invDigit=function(){if(1>this.t)return 0;var a=this.data[0];if(0==(a&1))return 0;var b=a&3,b=b*(2- -(a&15)*b)&15,b=b*(2-(a&255)*b)&255,b=b*(2-((a&65535)*b&65535))&65535,b=b*(2-a*b%this.DV)%this.DV;return 0a)return c.ONE;var e=d(),n=d(),g=b.convert(this),m=x(a)-1;for(g.copyTo(e);0<=--m;)if(b.sqrTo(e,n),0<(a&1<this.s)return"-"+this.negate().toString(a);if(16==a)a= -4;else if(8==a)a=3;else if(2==a)a=1;else if(32==a)a=5;else if(4==a)a=2;else return this.toRadix(a);var b=(1<>h)&&(d=!0,e="0123456789abcdefghijklmnopqrstuvwxyz".charAt(c));0<=n;)h>(h+=this.DB-a)):(c=this.data[n]>>(h-=a)&b,0>=h&&(h+=this.DB,--n)),0this.s?this.negate():this};c.prototype.compareTo=function(a){var b=this.s-a.s;if(0!=b)return b;var c=this.t,b=c-a.t;if(0!=b)return 0>this.s?-b:b;for(;0<=--c;)if(0!=(b=this.data[c]-a.data[c]))return b;return 0};c.prototype.bitLength=function(){return 0>=this.t?0:this.DB*(this.t-1)+x(this.data[this.t-1]^this.s&this.DM)};c.prototype.mod=function(a){var b=d();this.abs().divRemTo(a,null,b);0>this.s&&0a||b.isEven()?new u(b):new v(b);return this.exp(a,c)};c.ZERO=g(0);c.ONE=g(1);D.prototype.convert=z;D.prototype.revert=z;D.prototype.mulTo=function(a,b,c){a.multiplyTo(b,c)};D.prototype.sqrTo=function(a,b){a.squareTo(b)};C.prototype.convert=function(a){if(0>a.s||a.t>2*this.m.t)return a.mod(this.m);if(0>a.compareTo(this.m))return a;var b=d();a.copyTo(b);this.reduce(b);return b};C.prototype.revert=function(a){return a};C.prototype.reduce=function(a){a.drShiftTo(this.m.t- -1,this.r2);a.t>this.m.t+1&&(a.t=this.m.t+1,a.clamp());this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);for(this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);0>a.compareTo(this.r2);)a.dAddOffset(1,this.m.t+1);for(a.subTo(this.r2,a);0<=a.compareTo(this.m);)a.subTo(this.m,a)};C.prototype.mulTo=function(a,b,c){a.multiplyTo(b,c);this.reduce(c)};C.prototype.sqrTo=function(a,b){a.squareTo(b);this.reduce(b)};var R=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109, -113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509],U=67108864/R[R.length-1];c.prototype.chunkSize=function(a){return Math.floor(Math.LN2*this.DB/Math.log(a))};c.prototype.toRadix=function(a){null==a&&(a=10);if(0==this.signum()||2>a||36z?"-"==a.charAt(m)&&0==this.signum()&&(n=!0):(g=b*g+z,++h>=d&&(this.dMultiply(e),this.dAddOffset(g,0),g=h=0))}0a)this.fromInt(1);else for(this.fromNumber(a,d),this.testBit(a-1)||this.bitwiseTo(c.ONE.shiftLeft(a-1),y,this),this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(b);)this.dAddOffset(2,0),this.bitLength()>a&&this.subTo(c.ONE.shiftLeft(a-1),this);else{d=[];var e=a&7;d.length=(a>>3)+1;b.nextBytes(d);d[0]=0>=this.DB;if(a.t>(m&7),l;for(l=h;128>l;l++)e.putByte(c[e.at(l- +1)+e.at(l-h)&255]);e.setAt(128-r,c[e.at(128-r)&m]);for(l=127-r;0<=l;l--)e.setAt(l,c[e.at(l+1)^e.at(l+r)]);return e};var e=function(b,c,e){var h=!1,m=null,n=null,l=null,g,B,u,F,D=[];b=a.rc2.expandKey(b,c);for(u=0;64>u;u++)D.push(b.getInt16Le());e?(g=function(a){for(u=0;4>u;u++){a[u]+=D[F]+(a[(u+3)%4]&a[(u+2)%4])+(~a[(u+3)%4]&a[(u+1)%4]);var b=a[u],c=d[u];a[u]=b<>16-c;F++}},B=function(a){for(u=0;4>u;u++)a[u]+=D[a[(u+3)%4]&63]}):(g=function(a){for(u=3;0<=u;u--){var b=a[u],c=d[u];a[u]= +(b&65535)>>c|b<<16-c&65535;a[u]-=D[F]+(a[(u+3)%4]&a[(u+2)%4])+(~a[(u+3)%4]&a[(u+1)%4]);F--}},B=function(a){for(u=3;0<=u;u--)a[u]-=D[a[(u+3)%4]&63]});var z=null;return z={start:function(b,c){b&&"string"===typeof b&&(b=a.util.createBuffer(b));h=!1;m=a.util.createBuffer();n=c||new a.util.createBuffer;l=b;z.output=n},update:function(a){for(h||m.putBuffer(a);8<=m.length();){a=[[5,g],[1,B],[6,g],[1,B],[5,g]];var b=[];for(u=0;4>u;u++){var c=m.getInt16Le();null!==l&&(e?c^=l.getInt16Le():l.putInt16Le(c)); +b.push(c&65535)}F=e?0:63;for(c=0;cu;u++)null!==l&&(e?l.putInt16Le(b[u]):b[u]^=l.getInt16Le()),n.putInt16Le(b[u])}},finish:function(a){var b=!0;if(e)if(a)b=a(8,m,!e);else{var c=8===m.length()?8:8-m.length();m.fillWithByte(c,c)}b&&(h=!0,z.update());!e&&(b=0===m.length())&&(a?b=a(8,n,!e):(a=n.length(),c=n.at(a-1),c>a?b=!1:n.truncate(c)));return b}}};a.rc2.startEncrypting=function(b,c,d){b=a.rc2.createEncryptionCipher(b,128);b.start(c,d);return b}; +a.rc2.createEncryptionCipher=function(a,b){return e(a,b,!0)};a.rc2.startDecrypting=function(b,c,d){b=a.rc2.createDecryptionCipher(b,128);b.start(c,d);return b};a.rc2.createDecryptionCipher=function(a,b){return e(a,b,!1)}}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e=!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge={}),b(forge);var g,l=function(a,c){c.exports=function(c){var e=g.map(function(b){return a(b)}).concat(b);c=c||{};c.defined=c.defined|| +{};if(c.defined.rc2)return c.rc2;c.defined.rc2=!0;for(var n=0;n>=15;0<=--p;){var m=this.data[a]&32767,z=this.data[a++]>>15,x=b*m+z*h,m=h*m+((x&32767)<<15)+c.data[d]+(e&1073741823);e=(m>>>30)+(x>>>15)+b*z+(e>>>30);c.data[d++]=m&1073741823}return e}function k(a,b, +c,d,e,p){var h=b&16383;for(b>>=14;0<=--p;){var m=this.data[a]&16383,z=this.data[a++]>>14,x=b*m+z*h,m=h*m+((x&16383)<<14)+c.data[d]+e;e=(m>>28)+(x>>14)+b*z;c.data[d++]=m&268435455}return e}function y(a,b){var c=aa[a.charCodeAt(b)];return null==c?-1:c}function h(a){var b=d();b.fromInt(a);return b}function g(a){var b=1,c;0!=(c=a>>>16)&&(a=c,b+=16);0!=(c=a>>8)&&(a=c,b+=8);0!=(c=a>>4)&&(a=c,b+=4);0!=(c=a>>2)&&(a=c,b+=2);0!=a>>1&&(b+=1);return b}function r(a){this.m=a}function E(a){this.m=a;this.mp=a.invDigit(); +this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<=q;++q)aa[M++]=q;M=97;for(q=10;36>q;++q)aa[M++]=q;M=65;for(q=10;36>q;++q)aa[M++]=q;r.prototype.convert=function(a){return 0>a.s||0<=a.compareTo(this.m)?a.mod(this.m):a};r.prototype.revert=function(a){return a};r.prototype.reduce= +function(a){a.divRemTo(this.m,null,a)};r.prototype.mulTo=function(a,b,c){a.multiplyTo(b,c);this.reduce(c)};r.prototype.sqrTo=function(a,b){a.squareTo(b);this.reduce(b)};E.prototype.convert=function(a){var b=d();a.abs().dlShiftTo(this.m.t,b);b.divRemTo(this.m,null,b);0>a.s&&0>15)*this.mpl&this.um)<<15)&a.DM,c=b+this.m.t;for(a.data[c]+=this.m.am(0,d,a,b,0,this.m.t);a.data[c]>=a.DV;)a.data[c]-=a.DV,a.data[++c]++}a.clamp();a.drShiftTo(this.m.t,a);0<=a.compareTo(this.m)&&a.subTo(this.m,a)};E.prototype.mulTo=function(a,b,c){a.multiplyTo(b,c);this.reduce(c)};E.prototype.sqrTo=function(a,b){a.squareTo(b);this.reduce(b)};c.prototype.copyTo=function(a){for(var b=this.t-1;0<=b;--b)a.data[b]=this.data[b];a.t=this.t;a.s=this.s}; +c.prototype.fromInt=function(a){this.t=1;this.s=0>a?-1:0;0a?this.data[0]=a+this.DV:this.t=0};c.prototype.fromString=function(a,b){var d;if(16==b)d=4;else if(8==b)d=3;else if(256==b)d=8;else if(2==b)d=1;else if(32==b)d=5;else if(4==b)d=2;else{this.fromRadix(a,b);return}this.s=this.t=0;for(var e=a.length,p=!1,h=0;0<=--e;){var m=8==d?a[e]&255:y(a,e);0>m?"-"==a.charAt(e)&&(p=!0):(p=!1,0==h?this.data[this.t++]=m:h+d>this.DB?(this.data[this.t-1]|=(m&(1<>this.DB-h):this.data[this.t-1]|=m<=this.DB&&(h-=this.DB))}8==d&&0!=(a[0]&128)&&(this.s=-1,0>d|h,h=(this.data[m]&e)<=this.t)b.t=0;else{var d=a%this.DB,e=this.DB-d,p=(1<>d;for(var h= +c+1;h>d;0>=this.DB;if(a.t>=this.DB;d+=this.s}else{for(d+=this.s;c>=this.DB;d-=a.s}b.s=0>d?-1:0;-1>d?b.data[c++]=this.DV+d:0=b.DV&&(a.data[c+b.t]-=b.DV,a.data[c+b.t+1]=1)}0=p.t)){var h=this.abs();if(h.t>this.F2:0),r=this.FV/k,k=(1<z&&c.ZERO.subTo(e,e)}}}};c.prototype.invDigit=function(){if(1>this.t)return 0;var a=this.data[0];if(0==(a&1))return 0;var b=a&3,b=b*(2- +(a&15)*b)&15,b=b*(2-(a&255)*b)&255,b=b*(2-((a&65535)*b&65535))&65535,b=b*(2-a*b%this.DV)%this.DV;return 0a)return c.ONE;var e=d(),p=d(),h=b.convert(this),m=g(a)-1;for(h.copyTo(e);0<=--m;)if(b.sqrTo(e,p),0<(a&1<this.s)return"-"+this.negate().toString(a);if(16==a)a= +4;else if(8==a)a=3;else if(2==a)a=1;else if(32==a)a=5;else if(4==a)a=2;else return this.toRadix(a);var b=(1<>h)&&(d=!0,e="0123456789abcdefghijklmnopqrstuvwxyz".charAt(c));0<=p;)h>(h+=this.DB-a)):(c=this.data[p]>>(h-=a)&b,0>=h&&(h+=this.DB,--p)),0this.s?this.negate():this};c.prototype.compareTo=function(a){var b=this.s-a.s;if(0!=b)return b;var c=this.t,b=c-a.t;if(0!=b)return 0>this.s?-b:b;for(;0<=--c;)if(0!=(b=this.data[c]-a.data[c]))return b;return 0};c.prototype.bitLength=function(){return 0>=this.t?0:this.DB*(this.t-1)+g(this.data[this.t-1]^this.s&this.DM)};c.prototype.mod=function(a){var b=d();this.abs().divRemTo(a,null,b);0>this.s&&0a||b.isEven()?new r(b):new E(b);return this.exp(a,c)};c.ZERO=h(0);c.ONE=h(1);D.prototype.convert=z;D.prototype.revert=z;D.prototype.mulTo=function(a,b,c){a.multiplyTo(b,c)};D.prototype.sqrTo=function(a,b){a.squareTo(b)};x.prototype.convert=function(a){if(0>a.s||a.t>2*this.m.t)return a.mod(this.m);if(0>a.compareTo(this.m))return a;var b=d();a.copyTo(b);this.reduce(b);return b};x.prototype.revert=function(a){return a};x.prototype.reduce=function(a){a.drShiftTo(this.m.t- +1,this.r2);a.t>this.m.t+1&&(a.t=this.m.t+1,a.clamp());this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);for(this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);0>a.compareTo(this.r2);)a.dAddOffset(1,this.m.t+1);for(a.subTo(this.r2,a);0<=a.compareTo(this.m);)a.subTo(this.m,a)};x.prototype.mulTo=function(a,b,c){a.multiplyTo(b,c);this.reduce(c)};x.prototype.sqrTo=function(a,b){a.squareTo(b);this.reduce(b)};var V=[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109, +113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509],T=67108864/V[V.length-1];c.prototype.chunkSize=function(a){return Math.floor(Math.LN2*this.DB/Math.log(a))};c.prototype.toRadix=function(a){null==a&&(a=10);if(0==this.signum()||2>a||36x?"-"==a.charAt(z)&&0==this.signum()&&(p=!0):(m=b*m+x,++h>=d&&(this.dMultiply(e),this.dAddOffset(m,0),m=h=0))}0a)this.fromInt(1);else for(this.fromNumber(a,d),this.testBit(a-1)||this.bitwiseTo(c.ONE.shiftLeft(a-1),B,this),this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(b);)this.dAddOffset(2,0),this.bitLength()>a&&this.subTo(c.ONE.shiftLeft(a-1),this);else{d=[];var e=a&7;d.length=(a>>3)+1;b.nextBytes(d);d[0]=0>=this.DB;if(a.t>=this.DB;d+=this.s}else{for(d+=this.s;c>=this.DB;d+=a.s}b.s=0>d?-1:0;0d&&(b.data[c++]=this.DV+d);b.t=c;b.clamp()};c.prototype.dMultiply=function(a){this.data[this.t]=this.am(0,a-1,this,0,0,this.t);++this.t;this.clamp()};c.prototype.dAddOffset=function(a,b){if(0!=a){for(;this.t<=b;)this.data[this.t++]=0;for(this.data[b]+=a;this.data[b]>=this.DV;)this.data[b]-=this.DV,++b>=this.t&&(this.data[this.t++]= 0),++this.data[b]}};c.prototype.multiplyLowerTo=function(a,b,c){var d=Math.min(this.t+a.t,b);c.s=0;for(c.t=d;0=a)return 0;var b=this.DV%a,c=0>this.s?a-1:0;if(0=d)return!1;for(var e=b.shiftRight(d),n=F(),h,g=0;g=h.compareTo(c.ONE)||0<=h.compareTo(b));h=h.modPow(e,this);if(0!=h.compareTo(c.ONE)&&0!=h.compareTo(b)){for(var m=1;m++=a)return 0;var b=this.DV%a,c=0>this.s?a-1:0;if(0=d)return!1;for(var e=b.shiftRight(d),p=C(),h,m=0;m=h.compareTo(c.ONE)||0<=h.compareTo(b));h=h.modPow(e,this);if(0!=h.compareTo(c.ONE)&&0!=h.compareTo(b)){for(var z=1;z++this.s){if(1==this.t)return this.data[0]-this.DV;if(0==this.t)return-1}else{if(1==this.t)return this.data[0];if(0==this.t)return 0}return(this.data[1]&(1<<32-this.DB)-1)<>24};c.prototype.shortValue= function(){return 0==this.t?this.s:this.data[0]<<16>>16};c.prototype.signum=function(){return 0>this.s?-1:0>=this.t||1==this.t&&0>=this.data[0]?0:1};c.prototype.toByteArray=function(){var a=this.t,b=[];b[0]=this.s;var c=this.DB-a*this.DB%8,d,e=0;if(0>c)!=(this.s&this.DM)>>c&&(b[e++]=d|this.s<c?(d=(this.data[a]&(1<>(c+=this.DB-8)):(d=this.data[a]>>(c-=8)&255,0>=c&&(c+=this.DB,--a)),0!=(d&128)&&(d|=-256),0==e&& -(this.s&128)!=(d&128)&&++e,0this.compareTo(a)?this:a};c.prototype.max=function(a){return 0a?this.rShiftTo(-a,b):this.lShiftTo(a,b);return b};c.prototype.shiftRight=function(a){var b=d();0>a?this.lShiftTo(-a,b):this.rShiftTo(a,b);return b};c.prototype.getLowestSetBit=function(){for(var a=0;a>=16,c+=16); -0==(a&255)&&(a>>=8,c+=8);0==(a&15)&&(a>>=4,c+=4);0==(a&3)&&(a>>=2,c+=2);0==(a&1)&&++c;a=c}return b+a}return 0>this.s?this.t*this.DB:-1};c.prototype.bitCount=function(){for(var a=0,b=this.s&this.DM,c=0;c=this.t?0!=this.s:0!=(this.data[b]&1<=c)return n;e=18>c?1:48>c?3:144>c?4:768>c?5:6;m=8>c?new u(b):b.isEven()?new C(b):new v(b);var z=[],l=3,p=e-1,k=(1<=p?r=a.data[F]>>c-p&k:(r=(a.data[F]&(1<>this.DB+c-p));for(l=e;0==(r&1);)r>>=1,--l;0>(c-=l)&&(c+=this.DB,--F); -if(q)z[r].copyTo(n),q=!1;else{for(;1--c&&(c=this.DB-1,--F)}return m.revert(n)};c.prototype.modInverse=function(a){var b=a.isEven();if(this.isEven()&&b||0==a.signum())return c.ZERO;for(var d=a.clone(),e=this.clone(),n=g(1),h=g(0),m=g(0),z=g(1);0!=d.signum();){for(;d.isEven();)d.rShiftTo(1,d),b?(n.isEven()&&h.isEven()||(n.addTo(this,n),h.subTo(a,h)),n.rShiftTo(1, -n)):h.isEven()||h.subTo(a,h),h.rShiftTo(1,h);for(;e.isEven();)e.rShiftTo(1,e),b?(m.isEven()&&z.isEven()||(m.addTo(this,m),z.subTo(a,z)),m.rShiftTo(1,m)):z.isEven()||z.subTo(a,z),z.rShiftTo(1,z);0<=d.compareTo(e)?(d.subTo(e,d),b&&n.subTo(m,n),h.subTo(z,h)):(e.subTo(d,e),b&&m.subTo(n,m),z.subTo(h,z))}if(0!=e.compareTo(c.ONE))return c.ZERO;if(0<=z.compareTo(a))return z.subtract(a);if(0>z.signum())z.addTo(a,z);else return z;return 0>z.signum()?z.add(a):z};c.prototype.pow=function(a){return this.exp(a, +(this.s&128)!=(d&128)&&++e,0this.compareTo(a)?this:a};c.prototype.max=function(a){return 0a?this.rShiftTo(-a,b):this.lShiftTo(a,b);return b};c.prototype.shiftRight=function(a){var b=d();0>a?this.lShiftTo(-a,b):this.rShiftTo(a,b);return b};c.prototype.getLowestSetBit=function(){for(var a=0;a>=16,c+=16); +0==(a&255)&&(a>>=8,c+=8);0==(a&15)&&(a>>=4,c+=4);0==(a&3)&&(a>>=2,c+=2);0==(a&1)&&++c;a=c}return b+a}return 0>this.s?this.t*this.DB:-1};c.prototype.bitCount=function(){for(var a=0,b=this.s&this.DM,c=0;c=this.t?0!=this.s:0!=(this.data[b]&1<=c)return p;e=18>c?1:48>c?3:144>c?4:768>c?5:6;m=8>c?new r(b):b.isEven()?new x(b):new E(b);var z=[],k=3,n=e-1,C=(1<=n?q=a.data[l]>>c-n&C:(q=(a.data[l]&(1<>this.DB+c-n));for(k=e;0==(q&1);)q>>=1,--k;0>(c-=k)&&(c+=this.DB,--l); +if(y)z[q].copyTo(p),y=!1;else{for(;1--c&&(c=this.DB-1,--l)}return m.revert(p)};c.prototype.modInverse=function(a){var b=a.isEven();if(this.isEven()&&b||0==a.signum())return c.ZERO;for(var d=a.clone(),e=this.clone(),p=h(1),m=h(0),z=h(0),x=h(1);0!=d.signum();){for(;d.isEven();)d.rShiftTo(1,d),b?(p.isEven()&&m.isEven()||(p.addTo(this,p),m.subTo(a,m)),p.rShiftTo(1, +p)):m.isEven()||m.subTo(a,m),m.rShiftTo(1,m);for(;e.isEven();)e.rShiftTo(1,e),b?(z.isEven()&&x.isEven()||(z.addTo(this,z),x.subTo(a,x)),z.rShiftTo(1,z)):x.isEven()||x.subTo(a,x),x.rShiftTo(1,x);0<=d.compareTo(e)?(d.subTo(e,d),b&&p.subTo(z,p),m.subTo(x,m)):(e.subTo(d,e),b&&z.subTo(p,z),x.subTo(m,x))}if(0!=e.compareTo(c.ONE))return c.ZERO;if(0<=x.compareTo(a))return x.subtract(a);if(0>x.signum())x.addTo(a,x);else return x;return 0>x.signum()?x.add(a):x};c.prototype.pow=function(a){return this.exp(a, new D)};c.prototype.gcd=function(a){var b=0>this.s?this.negate():this.clone();a=0>a.s?a.negate():a.clone();if(0>b.compareTo(a)){var c=b,b=a;a=c}var c=b.getLowestSetBit(),d=a.getLowestSetBit();if(0>d)return b;c>24&255,p>>16&255,p>>8&255,p&255);e.start();e.update(b+k);h+=e.digest().getBytes()}return h.substring(0,d)}var d=a.pkcs1=a.pkcs1||{};d.encode_rsa_oaep=function(b,d,e,h,g){var k,u,q,A;"string"===typeof e?(k=e,u=h||void 0,q=g||void 0):e&&(k=e.label||void 0,u=e.seed||void 0,q=e.md||void 0,e.mgf1&&e.mgf1.md&&(A=e.mgf1.md));q?q.start():q=a.md.sha1.create(); -A||(A=q);b=Math.ceil(b.n.bitLength()/8);e=b-2*q.digestLength-2;if(d.length>e)throw A=Error("RSAES-OAEP input message length is too long."),A.length=d.length,A.maxLength=e,A;k||(k="");q.update(k,"raw");k=q.digest();h="";e-=d.length;for(g=0;gb&&(m=k(b,c));if(m.isProbablePrime(l))return g(null,m);m.dAddOffset(x[z++%8],0)}while(0>p||+new Date-ub&&(z=k(b,c));m=z.toString(16);e.target.postMessage({hex:m,workLoad:u}); -z.dAddOffset(q,0)}}C=Math.max(1,C);for(var d=[],e=0;e=a?27:150>=a?18:200>=a?15:250>=a?12:300>=a?9:350>=a?8:400>=a?7:500>=a?6:600>=a?5:800>=a?4:1250>=a?3:2}if(!a.prime){var l=a.prime=a.prime||{},g=a.jsbn.BigInteger,x=[6,4,2,4,2,4,6,2],u=new g(null);u.fromInt(30);var v=function(a,b){return a|b};l.generateProbablePrime=function(b,d,e){"function"===typeof d&&(e=d,d={});d=d||{};var h=d.algorithm||"PRIMEINC";"string"===typeof h&&(h={name:h});h.options=h.options||{};var g=d.prng||a.random;d={nextBytes:function(a){for(var b=g.getBytesSync(a.length), -c=0;cd-11)throw h= -Error("Message is too long for PKCS#1 v1.5 padding."),h.length=b.length,h.max=d-11,h;h.putByte(0);h.putByte(e);d=d-3-b.length;if(0===e||1===e){e=0===e?0:255;for(var g=0;gb.p.compareTo(b.q)){var e=b.p;b.p=b.q;b.q=e}0!==b.p.subtract(l.ONE).gcd(b.e).compareTo(l.ONE)?(b.p=null,h()):0!==b.q.subtract(l.ONE).gcd(b.e).compareTo(l.ONE)?(b.q=null,g(b.qBits,m)):(b.p1=b.p.subtract(l.ONE),b.q1=b.q.subtract(l.ONE),b.phi=b.p1.multiply(b.q1),0!==b.phi.gcd(b.e).compareTo(l.ONE)?(b.p=b.q=null,h()):(b.n=b.p.multiply(b.q),b.n.bitLength()!==b.bits?(b.q=null,g(b.qBits,m)): -(e=b.e.modInverse(b.phi),b.keys={privateKey:x.rsa.setPrivateKey(b.n,b.e,e,b.p,b.q,e.mod(b.p1),e.mod(b.q1),b.q.modInverse(b.p)),publicKey:x.rsa.setPublicKey(b.n,b.e)},d(null,b.keys))))}"function"===typeof c&&(d=c,c={});c=c||{};var p={algorithm:{name:c.algorithm||"PRIMEINC",options:{workers:c.workers||2,workLoad:c.workLoad||100,workerScript:c.workerScript}}};"prng"in c&&(p.prng=c.prng);h()}function k(b){b=b.toString(16);"8"<=b[0]&&(b="00"+b);return a.util.hexToBytes(b)}function q(a){return 100>=a?27: -150>=a?18:200>=a?15:250>=a?12:300>=a?9:350>=a?8:400>=a?7:500>=a?6:600>=a?5:800>=a?4:1250>=a?3:2}if("undefined"===typeof l)var l=a.jsbn.BigInteger;var g=a.asn1;a.pki=a.pki||{};a.pki.rsa=a.rsa=a.rsa||{};var x=a.pki,u=[6,4,2,4,2,4,6,2],v={name:"PrivateKeyInfo",tagClass:g.Class.UNIVERSAL,type:g.Type.SEQUENCE,constructed:!0,value:[{name:"PrivateKeyInfo.version",tagClass:g.Class.UNIVERSAL,type:g.Type.INTEGER,constructed:!1,capture:"privateKeyVersion"},{name:"PrivateKeyInfo.privateKeyAlgorithm",tagClass:g.Class.UNIVERSAL, -type:g.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:g.Class.UNIVERSAL,type:g.Type.OID,constructed:!1,capture:"privateKeyOid"}]},{name:"PrivateKeyInfo",tagClass:g.Class.UNIVERSAL,type:g.Type.OCTETSTRING,constructed:!1,capture:"privateKey"}]},A={name:"RSAPrivateKey",tagClass:g.Class.UNIVERSAL,type:g.Type.SEQUENCE,constructed:!0,value:[{name:"RSAPrivateKey.version",tagClass:g.Class.UNIVERSAL,type:g.Type.INTEGER,constructed:!1,capture:"privateKeyVersion"},{name:"RSAPrivateKey.modulus", -tagClass:g.Class.UNIVERSAL,type:g.Type.INTEGER,constructed:!1,capture:"privateKeyModulus"},{name:"RSAPrivateKey.publicExponent",tagClass:g.Class.UNIVERSAL,type:g.Type.INTEGER,constructed:!1,capture:"privateKeyPublicExponent"},{name:"RSAPrivateKey.privateExponent",tagClass:g.Class.UNIVERSAL,type:g.Type.INTEGER,constructed:!1,capture:"privateKeyPrivateExponent"},{name:"RSAPrivateKey.prime1",tagClass:g.Class.UNIVERSAL,type:g.Type.INTEGER,constructed:!1,capture:"privateKeyPrime1"},{name:"RSAPrivateKey.prime2", -tagClass:g.Class.UNIVERSAL,type:g.Type.INTEGER,constructed:!1,capture:"privateKeyPrime2"},{name:"RSAPrivateKey.exponent1",tagClass:g.Class.UNIVERSAL,type:g.Type.INTEGER,constructed:!1,capture:"privateKeyExponent1"},{name:"RSAPrivateKey.exponent2",tagClass:g.Class.UNIVERSAL,type:g.Type.INTEGER,constructed:!1,capture:"privateKeyExponent2"},{name:"RSAPrivateKey.coefficient",tagClass:g.Class.UNIVERSAL,type:g.Type.INTEGER,constructed:!1,capture:"privateKeyCoefficient"}]},y={name:"RSAPublicKey",tagClass:g.Class.UNIVERSAL, -type:g.Type.SEQUENCE,constructed:!0,value:[{name:"RSAPublicKey.modulus",tagClass:g.Class.UNIVERSAL,type:g.Type.INTEGER,constructed:!1,capture:"publicKeyModulus"},{name:"RSAPublicKey.exponent",tagClass:g.Class.UNIVERSAL,type:g.Type.INTEGER,constructed:!1,capture:"publicKeyExponent"}]},H=a.pki.rsa.publicKeyValidator={name:"SubjectPublicKeyInfo",tagClass:g.Class.UNIVERSAL,type:g.Type.SEQUENCE,constructed:!0,captureAsn1:"subjectPublicKeyInfo",value:[{name:"SubjectPublicKeyInfo.AlgorithmIdentifier",tagClass:g.Class.UNIVERSAL, -type:g.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:g.Class.UNIVERSAL,type:g.Type.OID,constructed:!1,capture:"publicKeyOid"}]},{name:"SubjectPublicKeyInfo.subjectPublicKey",tagClass:g.Class.UNIVERSAL,type:g.Type.BITSTRING,constructed:!1,value:[{name:"SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey",tagClass:g.Class.UNIVERSAL,type:g.Type.SEQUENCE,constructed:!0,optional:!0,captureAsn1:"rsaPublicKey"}]}]},E=function(a){var b;if(a.algorithm in x.oids)b=x.oids[a.algorithm]; -else throw b=Error("Unknown message digest algorithm."),b.algorithm=a.algorithm,b;var c=g.oidToDer(b).getBytes();b=g.create(g.Class.UNIVERSAL,g.Type.SEQUENCE,!0,[]);var d=g.create(g.Class.UNIVERSAL,g.Type.SEQUENCE,!0,[]);d.value.push(g.create(g.Class.UNIVERSAL,g.Type.OID,!1,c));d.value.push(g.create(g.Class.UNIVERSAL,g.Type.NULL,!1,""));a=g.create(g.Class.UNIVERSAL,g.Type.OCTETSTRING,!1,a.digest().getBytes());b.value.push(d);b.value.push(a);return g.toDer(b).getBytes()},D=function(b,c,d){if(d)return b.modPow(c.e, -c.n);if(!c.p||!c.q)return b.modPow(c.d,c.n);c.dP||(c.dP=c.d.mod(c.p.subtract(l.ONE)));c.dQ||(c.dQ=c.d.mod(c.q.subtract(l.ONE)));c.qInv||(c.qInv=c.q.modInverse(c.p));do d=new l(a.util.bytesToHex(a.random.getBytes(c.n.bitLength()/8)),16);while(0<=d.compareTo(c.n)||!d.gcd(c.n).equals(l.ONE));b=b.multiply(d.modPow(c.e,c.n)).mod(c.n);var e=b.mod(c.p).modPow(c.dP,c.p);for(b=b.mod(c.q).modPow(c.dQ,c.q);0>e.compareTo(b);)e=e.add(c.p);b=e.subtract(b).multiply(c.qInv).mod(c.p).multiply(c.q).add(b);return b= -b.multiply(d.modInverse(c.n)).mod(c.n)};x.rsa.encrypt=function(b,d,e){var h=e,g=Math.ceil(d.n.bitLength()/8);!1!==e&&!0!==e?(h=2===e,e=c(b,d,e)):(e=a.util.createBuffer(),e.putBytes(b));b=new l(e.toHex(),16);d=D(b,d,h).toString(16);h=a.util.createBuffer();for(g-=Math.ceil(d.length/2);0>1,pBits:b-(b>>1),pqState:0,num:null,keys:null},b.e.fromInt(b.eInt);else throw Error("Invalid key generation algorithm: "+d);return b};x.rsa.stepKeyPairGenerationState=function(a,b){"algorithm"in a||(a.algorithm="PRIMEINC");var c=new l(null);c.fromInt(30);for(var d=0,e=function(a,b){return a|b},n=+new Date,h,g=0;null===a.keys&& -(0>=b||gh?a.pqState=0:a.num.isProbablePrime(q(a.num.bitLength()))?++a.pqState:a.num.dAddOffset(u[d++%8],0):2===a.pqState?a.pqState=0===a.num.subtract(l.ONE).gcd(a.e).compareTo(l.ONE)?3:0:3===a.pqState&&(a.pqState=0,null===a.p?a.p=a.num:a.q=a.num, -null!==a.p&&null!==a.q&&++a.state,a.num=null)}else 1===a.state?(0>a.p.compareTo(a.q)&&(a.num=a.p,a.p=a.q,a.q=a.num),++a.state):2===a.state?(a.p1=a.p.subtract(l.ONE),a.q1=a.q.subtract(l.ONE),a.phi=a.p1.multiply(a.q1),++a.state):3===a.state?0===a.phi.gcd(a.e).compareTo(l.ONE)?++a.state:(a.p=null,a.q=null,a.state=0):4===a.state?(a.n=a.p.multiply(a.q),a.n.bitLength()===a.bits?++a.state:(a.q=null,a.state=0)):5===a.state&&(h=a.e.modInverse(a.phi),a.keys={privateKey:x.rsa.setPrivateKey(a.n,a.e,h,a.p,a.q, -h.mod(a.p1),h.mod(a.q1),a.q.modInverse(a.p)),publicKey:x.rsa.setPublicKey(a.n,a.e)});h=+new Date;g+=h-n;n=h}return null!==a.keys};x.rsa.generateKeyPair=function(a,b,c,d){1===arguments.length?"object"===typeof a?(c=a,a=void 0):"function"===typeof a&&(d=a,a=void 0):2===arguments.length?"number"===typeof a?"function"===typeof b?(d=b,b=void 0):"number"!==typeof b&&(c=b,b=void 0):(c=a,d=b,b=a=void 0):3===arguments.length&&("number"===typeof b?"function"===typeof c&&(d=c,c=void 0):(d=c,c=b,b=void 0));c= -c||{};void 0===a&&(a=c.bits||2048);void 0===b&&(b=c.e||65537);var n=x.rsa.createKeyPairGenerationState(a,b,c);if(!d)return x.rsa.stepKeyPairGenerationState(n,0),n.keys;e(n,c,d)};x.setRsaPublicKey=x.rsa.setPublicKey=function(b,e){var m={n:b,e:e,encrypt:function(b,d,e){"string"===typeof d?d=d.toUpperCase():void 0===d&&(d="RSAES-PKCS1-V1_5");if("RSAES-PKCS1-V1_5"===d)d={encode:function(a,b,d){return c(a,b,2).getBytes()}};else if("RSA-OAEP"===d||"RSAES-OAEP"===d)d={encode:function(b,c){return a.pkcs1.encode_rsa_oaep(c, -b,e)}};else if(-1!==["RAW","NONE","NULL",null].indexOf(d))d={encode:function(a){return a}};else if("string"===typeof d)throw Error('Unsupported encryption scheme: "'+d+'".');b=d.encode(b,m,!0);return x.rsa.encrypt(b,m,!0)},verify:function(a,b,c){"string"===typeof c?c=c.toUpperCase():void 0===c&&(c="RSASSA-PKCS1-V1_5");if("RSASSA-PKCS1-V1_5"===c)c={verify:function(a,b){b=d(b,m,!0);var c=g.fromDer(b);return a===c.value[1].value}};else if("NONE"===c||"NULL"===c||null===c)c={verify:function(a,b){b=d(b, -m,!0);return a===b}};b=x.rsa.decrypt(b,m,!0,!1);return c.verify(a,b,m.n.bitLength())}};return m};x.setRsaPrivateKey=x.rsa.setPrivateKey=function(b,c,e,g,m,l,p,k){var u={n:b,e:c,d:e,p:g,q:m,dP:l,dQ:p,qInv:k,decrypt:function(b,c,e){"string"===typeof c?c=c.toUpperCase():void 0===c&&(c="RSAES-PKCS1-V1_5");b=x.rsa.decrypt(b,u,!1,!1);if("RSAES-PKCS1-V1_5"===c)c={decode:d};else if("RSA-OAEP"===c||"RSAES-OAEP"===c)c={decode:function(b,c){return a.pkcs1.decode_rsa_oaep(c,b,e)}};else if(-1!==["RAW","NONE", -"NULL",null].indexOf(c))c={decode:function(a){return a}};else throw Error('Unsupported encryption scheme: "'+c+'".');return c.decode(b,u,!1)},sign:function(a,b){var c=!1;"string"===typeof b&&(b=b.toUpperCase());if(void 0===b||"RSASSA-PKCS1-V1_5"===b)b={encode:E},c=1;else if("NONE"===b||"NULL"===b||null===b)b={encode:function(){return a}},c=1;var d=b.encode(a,u.n.bitLength());return x.rsa.encrypt(d,u,c)}};return u};x.wrapRsaPrivateKey=function(a){return g.create(g.Class.UNIVERSAL,g.Type.SEQUENCE,!0, -[g.create(g.Class.UNIVERSAL,g.Type.INTEGER,!1,g.integerToDer(0).getBytes()),g.create(g.Class.UNIVERSAL,g.Type.SEQUENCE,!0,[g.create(g.Class.UNIVERSAL,g.Type.OID,!1,g.oidToDer(x.oids.rsaEncryption).getBytes()),g.create(g.Class.UNIVERSAL,g.Type.NULL,!1,"")]),g.create(g.Class.UNIVERSAL,g.Type.OCTETSTRING,!1,g.toDer(a).getBytes())])};x.privateKeyFromAsn1=function(b){var c={},d=[];g.validate(b,v,c,d)&&(b=g.fromDer(a.util.createBuffer(c.privateKey)));c={};d=[];if(!g.validate(b,A,c,d))throw c=Error("Cannot read private key. ASN.1 object does not contain an RSAPrivateKey."), -c.errors=d,c;var e,h,m,p,k,d=a.util.createBuffer(c.privateKeyModulus).toHex();b=a.util.createBuffer(c.privateKeyPublicExponent).toHex();e=a.util.createBuffer(c.privateKeyPrivateExponent).toHex();h=a.util.createBuffer(c.privateKeyPrime1).toHex();m=a.util.createBuffer(c.privateKeyPrime2).toHex();p=a.util.createBuffer(c.privateKeyExponent1).toHex();k=a.util.createBuffer(c.privateKeyExponent2).toHex();c=a.util.createBuffer(c.privateKeyCoefficient).toHex();return x.setRsaPrivateKey(new l(d,16),new l(b, -16),new l(e,16),new l(h,16),new l(m,16),new l(p,16),new l(k,16),new l(c,16))};x.privateKeyToAsn1=x.privateKeyToRSAPrivateKey=function(a){return g.create(g.Class.UNIVERSAL,g.Type.SEQUENCE,!0,[g.create(g.Class.UNIVERSAL,g.Type.INTEGER,!1,g.integerToDer(0).getBytes()),g.create(g.Class.UNIVERSAL,g.Type.INTEGER,!1,k(a.n)),g.create(g.Class.UNIVERSAL,g.Type.INTEGER,!1,k(a.e)),g.create(g.Class.UNIVERSAL,g.Type.INTEGER,!1,k(a.d)),g.create(g.Class.UNIVERSAL,g.Type.INTEGER,!1,k(a.p)),g.create(g.Class.UNIVERSAL, -g.Type.INTEGER,!1,k(a.q)),g.create(g.Class.UNIVERSAL,g.Type.INTEGER,!1,k(a.dP)),g.create(g.Class.UNIVERSAL,g.Type.INTEGER,!1,k(a.dQ)),g.create(g.Class.UNIVERSAL,g.Type.INTEGER,!1,k(a.qInv))])};x.publicKeyFromAsn1=function(b){var c={},d=[];if(g.validate(b,H,c,d)){d=g.derToOid(c.publicKeyOid);if(d!==x.oids.rsaEncryption)throw c=Error("Cannot read public key. Unknown OID."),c.oid=d,c;b=c.rsaPublicKey}d=[];if(!g.validate(b,y,c,d))throw c=Error("Cannot read public key. ASN.1 object does not contain an RSAPublicKey."), -c.errors=d,c;d=a.util.createBuffer(c.publicKeyModulus).toHex();c=a.util.createBuffer(c.publicKeyExponent).toHex();return x.setRsaPublicKey(new l(d,16),new l(c,16))};x.publicKeyToAsn1=x.publicKeyToSubjectPublicKeyInfo=function(a){return g.create(g.Class.UNIVERSAL,g.Type.SEQUENCE,!0,[g.create(g.Class.UNIVERSAL,g.Type.SEQUENCE,!0,[g.create(g.Class.UNIVERSAL,g.Type.OID,!1,g.oidToDer(x.oids.rsaEncryption).getBytes()),g.create(g.Class.UNIVERSAL,g.Type.NULL,!1,"")]),g.create(g.Class.UNIVERSAL,g.Type.BITSTRING, -!1,[x.publicKeyToRSAPublicKey(a)])])};x.publicKeyToRSAPublicKey=function(a){return g.create(g.Class.UNIVERSAL,g.Type.SEQUENCE,!0,[g.create(g.Class.UNIVERSAL,g.Type.INTEGER,!1,k(a.n)),g.create(g.Class.UNIVERSAL,g.Type.INTEGER,!1,k(a.e))])}}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e=!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge={}),b(forge);var q,k=function(a,c){c.exports=function(c){var e=q.map(function(b){return a(b)}).concat(b);c=c|| -{};c.defined=c.defined||{};if(c.defined.rsa)return c.rsa;c.defined.rsa=!0;for(var p=0;p>24&255,l>>16&255,l>>8&255,l&255);e.start();e.update(b+r);n+=e.digest().getBytes()}return n.substring(0,d)}var d=a.pkcs1=a.pkcs1||{};d.encode_rsa_oaep=function(b,d,e,l,h){var g,r,w,A;"string"===typeof e?(g=e,r=l||void 0,w=h||void 0):e&&(g=e.label||void 0,r=e.seed||void 0,w=e.md||void 0,e.mgf1&&e.mgf1.md&&(A=e.mgf1.md));w?w.start():w=a.md.sha1.create(); +A||(A=w);b=Math.ceil(b.n.bitLength()/8);e=b-2*w.digestLength-2;if(d.length>e)throw A=Error("RSAES-OAEP input message length is too long."),A.length=d.length,A.maxLength=e,A;g||(g="");w.update(g,"raw");g=w.digest();l="";e-=d.length;for(h=0;hb&&(m=l(b,c));if(m.isProbablePrime(x))return h(null,m);m.dAddOffset(g[z++%8],0)}while(0>r||+new Date-nb&&(z=l(b,c));x=z.toString(16);e.target.postMessage({hex:x,workLoad:n}); +z.dAddOffset(y,0)}}x=Math.max(1,x);for(var d=[],e=0;e=a?27:150>=a?18:200>=a?15:250>=a?12:300>=a?9:350>=a?8:400>=a?7:500>=a?6:600>=a?5:800>=a?4:1250>=a?3:2}if(!a.prime){var y=a.prime=a.prime||{},h=a.jsbn.BigInteger,g=[6,4,2,4,2,4,6,2],r=new h(null);r.fromInt(30);var E=function(a,b){return a|b};y.generateProbablePrime=function(b,d,e){"function"===typeof d&&(e=d,d={});d=d||{};var h=d.algorithm||"PRIMEINC";"string"===typeof h&&(h={name:h});h.options=h.options||{};var m=d.prng||a.random;d={nextBytes:function(a){for(var b=m.getBytesSync(a.length), +c=0;cd-11)throw h= +Error("Message is too long for PKCS#1 v1.5 padding."),h.length=b.length,h.max=d-11,h;h.putByte(0);h.putByte(e);d=d-3-b.length;if(0===e||1===e){e=0===e?0:255;for(var m=0;mb.p.compareTo(b.q)){var e=b.p;b.p=b.q;b.q=e}0!==b.p.subtract(y.ONE).gcd(b.e).compareTo(y.ONE)?(b.p=null,h()):0!==b.q.subtract(y.ONE).gcd(b.e).compareTo(y.ONE)?(b.q=null,m(b.qBits,k)):(b.p1=b.p.subtract(y.ONE),b.q1=b.q.subtract(y.ONE),b.phi=b.p1.multiply(b.q1),0!==b.phi.gcd(b.e).compareTo(y.ONE)?(b.p=b.q=null,h()):(b.n=b.p.multiply(b.q),b.n.bitLength()!==b.bits?(b.q=null,m(b.qBits,k)): +(e=b.e.modInverse(b.phi),b.keys={privateKey:g.rsa.setPrivateKey(b.n,b.e,e,b.p,b.q,e.mod(b.p1),e.mod(b.q1),b.q.modInverse(b.p)),publicKey:g.rsa.setPublicKey(b.n,b.e)},d(null,b.keys))))}"function"===typeof c&&(d=c,c={});c=c||{};var r={algorithm:{name:c.algorithm||"PRIMEINC",options:{workers:c.workers||2,workLoad:c.workLoad||100,workerScript:c.workerScript}}};"prng"in c&&(r.prng=c.prng);h()}function l(b){b=b.toString(16);"8"<=b[0]&&(b="00"+b);return a.util.hexToBytes(b)}function k(a){return 100>=a?27: +150>=a?18:200>=a?15:250>=a?12:300>=a?9:350>=a?8:400>=a?7:500>=a?6:600>=a?5:800>=a?4:1250>=a?3:2}if("undefined"===typeof y)var y=a.jsbn.BigInteger;var h=a.asn1;a.pki=a.pki||{};a.pki.rsa=a.rsa=a.rsa||{};var g=a.pki,r=[6,4,2,4,2,4,6,2],E={name:"PrivateKeyInfo",tagClass:h.Class.UNIVERSAL,type:h.Type.SEQUENCE,constructed:!0,value:[{name:"PrivateKeyInfo.version",tagClass:h.Class.UNIVERSAL,type:h.Type.INTEGER,constructed:!1,capture:"privateKeyVersion"},{name:"PrivateKeyInfo.privateKeyAlgorithm",tagClass:h.Class.UNIVERSAL, +type:h.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:h.Class.UNIVERSAL,type:h.Type.OID,constructed:!1,capture:"privateKeyOid"}]},{name:"PrivateKeyInfo",tagClass:h.Class.UNIVERSAL,type:h.Type.OCTETSTRING,constructed:!1,capture:"privateKey"}]},A={name:"RSAPrivateKey",tagClass:h.Class.UNIVERSAL,type:h.Type.SEQUENCE,constructed:!0,value:[{name:"RSAPrivateKey.version",tagClass:h.Class.UNIVERSAL,type:h.Type.INTEGER,constructed:!1,capture:"privateKeyVersion"},{name:"RSAPrivateKey.modulus", +tagClass:h.Class.UNIVERSAL,type:h.Type.INTEGER,constructed:!1,capture:"privateKeyModulus"},{name:"RSAPrivateKey.publicExponent",tagClass:h.Class.UNIVERSAL,type:h.Type.INTEGER,constructed:!1,capture:"privateKeyPublicExponent"},{name:"RSAPrivateKey.privateExponent",tagClass:h.Class.UNIVERSAL,type:h.Type.INTEGER,constructed:!1,capture:"privateKeyPrivateExponent"},{name:"RSAPrivateKey.prime1",tagClass:h.Class.UNIVERSAL,type:h.Type.INTEGER,constructed:!1,capture:"privateKeyPrime1"},{name:"RSAPrivateKey.prime2", +tagClass:h.Class.UNIVERSAL,type:h.Type.INTEGER,constructed:!1,capture:"privateKeyPrime2"},{name:"RSAPrivateKey.exponent1",tagClass:h.Class.UNIVERSAL,type:h.Type.INTEGER,constructed:!1,capture:"privateKeyExponent1"},{name:"RSAPrivateKey.exponent2",tagClass:h.Class.UNIVERSAL,type:h.Type.INTEGER,constructed:!1,capture:"privateKeyExponent2"},{name:"RSAPrivateKey.coefficient",tagClass:h.Class.UNIVERSAL,type:h.Type.INTEGER,constructed:!1,capture:"privateKeyCoefficient"}]},B={name:"RSAPublicKey",tagClass:h.Class.UNIVERSAL, +type:h.Type.SEQUENCE,constructed:!0,value:[{name:"RSAPublicKey.modulus",tagClass:h.Class.UNIVERSAL,type:h.Type.INTEGER,constructed:!1,capture:"publicKeyModulus"},{name:"RSAPublicKey.exponent",tagClass:h.Class.UNIVERSAL,type:h.Type.INTEGER,constructed:!1,capture:"publicKeyExponent"}]},u=a.pki.rsa.publicKeyValidator={name:"SubjectPublicKeyInfo",tagClass:h.Class.UNIVERSAL,type:h.Type.SEQUENCE,constructed:!0,captureAsn1:"subjectPublicKeyInfo",value:[{name:"SubjectPublicKeyInfo.AlgorithmIdentifier",tagClass:h.Class.UNIVERSAL, +type:h.Type.SEQUENCE,constructed:!0,value:[{name:"AlgorithmIdentifier.algorithm",tagClass:h.Class.UNIVERSAL,type:h.Type.OID,constructed:!1,capture:"publicKeyOid"}]},{name:"SubjectPublicKeyInfo.subjectPublicKey",tagClass:h.Class.UNIVERSAL,type:h.Type.BITSTRING,constructed:!1,value:[{name:"SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey",tagClass:h.Class.UNIVERSAL,type:h.Type.SEQUENCE,constructed:!0,optional:!0,captureAsn1:"rsaPublicKey"}]}]},F=function(a){var b;if(a.algorithm in g.oids)b=g.oids[a.algorithm]; +else throw b=Error("Unknown message digest algorithm."),b.algorithm=a.algorithm,b;var c=h.oidToDer(b).getBytes();b=h.create(h.Class.UNIVERSAL,h.Type.SEQUENCE,!0,[]);var d=h.create(h.Class.UNIVERSAL,h.Type.SEQUENCE,!0,[]);d.value.push(h.create(h.Class.UNIVERSAL,h.Type.OID,!1,c));d.value.push(h.create(h.Class.UNIVERSAL,h.Type.NULL,!1,""));a=h.create(h.Class.UNIVERSAL,h.Type.OCTETSTRING,!1,a.digest().getBytes());b.value.push(d);b.value.push(a);return h.toDer(b).getBytes()},D=function(b,c,d){if(d)return b.modPow(c.e, +c.n);if(!c.p||!c.q)return b.modPow(c.d,c.n);c.dP||(c.dP=c.d.mod(c.p.subtract(y.ONE)));c.dQ||(c.dQ=c.d.mod(c.q.subtract(y.ONE)));c.qInv||(c.qInv=c.q.modInverse(c.p));do d=new y(a.util.bytesToHex(a.random.getBytes(c.n.bitLength()/8)),16);while(0<=d.compareTo(c.n)||!d.gcd(c.n).equals(y.ONE));b=b.multiply(d.modPow(c.e,c.n)).mod(c.n);var e=b.mod(c.p).modPow(c.dP,c.p);for(b=b.mod(c.q).modPow(c.dQ,c.q);0>e.compareTo(b);)e=e.add(c.p);b=e.subtract(b).multiply(c.qInv).mod(c.p).multiply(c.q).add(b);return b= +b.multiply(d.modInverse(c.n)).mod(c.n)};g.rsa.encrypt=function(b,d,e){var h=e,m=Math.ceil(d.n.bitLength()/8);!1!==e&&!0!==e?(h=2===e,e=c(b,d,e)):(e=a.util.createBuffer(),e.putBytes(b));b=new y(e.toHex(),16);d=D(b,d,h).toString(16);h=a.util.createBuffer();for(m-=Math.ceil(d.length/2);0>1,pBits:b-(b>>1),pqState:0,num:null,keys:null},b.e.fromInt(b.eInt);else throw Error("Invalid key generation algorithm: "+d);return b};g.rsa.stepKeyPairGenerationState=function(a,b){"algorithm"in a||(a.algorithm="PRIMEINC");var c=new y(null);c.fromInt(30);for(var d=0,e=function(a,b){return a|b},p=+new Date,h,m=0;null===a.keys&& +(0>=b||mh?a.pqState=0:a.num.isProbablePrime(k(a.num.bitLength()))?++a.pqState:a.num.dAddOffset(r[d++%8],0):2===a.pqState?a.pqState=0===a.num.subtract(y.ONE).gcd(a.e).compareTo(y.ONE)?3:0:3===a.pqState&&(a.pqState=0,null===a.p?a.p=a.num:a.q=a.num, +null!==a.p&&null!==a.q&&++a.state,a.num=null)}else 1===a.state?(0>a.p.compareTo(a.q)&&(a.num=a.p,a.p=a.q,a.q=a.num),++a.state):2===a.state?(a.p1=a.p.subtract(y.ONE),a.q1=a.q.subtract(y.ONE),a.phi=a.p1.multiply(a.q1),++a.state):3===a.state?0===a.phi.gcd(a.e).compareTo(y.ONE)?++a.state:(a.p=null,a.q=null,a.state=0):4===a.state?(a.n=a.p.multiply(a.q),a.n.bitLength()===a.bits?++a.state:(a.q=null,a.state=0)):5===a.state&&(h=a.e.modInverse(a.phi),a.keys={privateKey:g.rsa.setPrivateKey(a.n,a.e,h,a.p,a.q, +h.mod(a.p1),h.mod(a.q1),a.q.modInverse(a.p)),publicKey:g.rsa.setPublicKey(a.n,a.e)});h=+new Date;m+=h-p;p=h}return null!==a.keys};g.rsa.generateKeyPair=function(a,b,c,d){1===arguments.length?"object"===typeof a?(c=a,a=void 0):"function"===typeof a&&(d=a,a=void 0):2===arguments.length?"number"===typeof a?"function"===typeof b?(d=b,b=void 0):"number"!==typeof b&&(c=b,b=void 0):(c=a,d=b,b=a=void 0):3===arguments.length&&("number"===typeof b?"function"===typeof c&&(d=c,c=void 0):(d=c,c=b,b=void 0));c= +c||{};void 0===a&&(a=c.bits||2048);void 0===b&&(b=c.e||65537);var p=g.rsa.createKeyPairGenerationState(a,b,c);if(!d)return g.rsa.stepKeyPairGenerationState(p,0),p.keys;e(p,c,d)};g.setRsaPublicKey=g.rsa.setPublicKey=function(b,e){var m={n:b,e:e,encrypt:function(b,d,e){"string"===typeof d?d=d.toUpperCase():void 0===d&&(d="RSAES-PKCS1-V1_5");if("RSAES-PKCS1-V1_5"===d)d={encode:function(a,b,d){return c(a,b,2).getBytes()}};else if("RSA-OAEP"===d||"RSAES-OAEP"===d)d={encode:function(b,c){return a.pkcs1.encode_rsa_oaep(c, +b,e)}};else if(-1!==["RAW","NONE","NULL",null].indexOf(d))d={encode:function(a){return a}};else if("string"===typeof d)throw Error('Unsupported encryption scheme: "'+d+'".');b=d.encode(b,m,!0);return g.rsa.encrypt(b,m,!0)},verify:function(a,b,c){"string"===typeof c?c=c.toUpperCase():void 0===c&&(c="RSASSA-PKCS1-V1_5");if("RSASSA-PKCS1-V1_5"===c)c={verify:function(a,b){b=d(b,m,!0);var c=h.fromDer(b);return a===c.value[1].value}};else if("NONE"===c||"NULL"===c||null===c)c={verify:function(a,b){b=d(b, +m,!0);return a===b}};b=g.rsa.decrypt(b,m,!0,!1);return c.verify(a,b,m.n.bitLength())}};return m};g.setRsaPrivateKey=g.rsa.setPrivateKey=function(b,c,e,h,m,k,r,n){var l={n:b,e:c,d:e,p:h,q:m,dP:k,dQ:r,qInv:n,decrypt:function(b,c,e){"string"===typeof c?c=c.toUpperCase():void 0===c&&(c="RSAES-PKCS1-V1_5");b=g.rsa.decrypt(b,l,!1,!1);if("RSAES-PKCS1-V1_5"===c)c={decode:d};else if("RSA-OAEP"===c||"RSAES-OAEP"===c)c={decode:function(b,c){return a.pkcs1.decode_rsa_oaep(c,b,e)}};else if(-1!==["RAW","NONE", +"NULL",null].indexOf(c))c={decode:function(a){return a}};else throw Error('Unsupported encryption scheme: "'+c+'".');return c.decode(b,l,!1)},sign:function(a,b){var c=!1;"string"===typeof b&&(b=b.toUpperCase());if(void 0===b||"RSASSA-PKCS1-V1_5"===b)b={encode:F},c=1;else if("NONE"===b||"NULL"===b||null===b)b={encode:function(){return a}},c=1;var d=b.encode(a,l.n.bitLength());return g.rsa.encrypt(d,l,c)}};return l};g.wrapRsaPrivateKey=function(a){return h.create(h.Class.UNIVERSAL,h.Type.SEQUENCE,!0, +[h.create(h.Class.UNIVERSAL,h.Type.INTEGER,!1,h.integerToDer(0).getBytes()),h.create(h.Class.UNIVERSAL,h.Type.SEQUENCE,!0,[h.create(h.Class.UNIVERSAL,h.Type.OID,!1,h.oidToDer(g.oids.rsaEncryption).getBytes()),h.create(h.Class.UNIVERSAL,h.Type.NULL,!1,"")]),h.create(h.Class.UNIVERSAL,h.Type.OCTETSTRING,!1,h.toDer(a).getBytes())])};g.privateKeyFromAsn1=function(b){var c={},d=[];h.validate(b,E,c,d)&&(b=h.fromDer(a.util.createBuffer(c.privateKey)));c={};d=[];if(!h.validate(b,A,c,d))throw c=Error("Cannot read private key. ASN.1 object does not contain an RSAPrivateKey."), +c.errors=d,c;var e,m,k,r,n,d=a.util.createBuffer(c.privateKeyModulus).toHex();b=a.util.createBuffer(c.privateKeyPublicExponent).toHex();e=a.util.createBuffer(c.privateKeyPrivateExponent).toHex();m=a.util.createBuffer(c.privateKeyPrime1).toHex();k=a.util.createBuffer(c.privateKeyPrime2).toHex();r=a.util.createBuffer(c.privateKeyExponent1).toHex();n=a.util.createBuffer(c.privateKeyExponent2).toHex();c=a.util.createBuffer(c.privateKeyCoefficient).toHex();return g.setRsaPrivateKey(new y(d,16),new y(b, +16),new y(e,16),new y(m,16),new y(k,16),new y(r,16),new y(n,16),new y(c,16))};g.privateKeyToAsn1=g.privateKeyToRSAPrivateKey=function(a){return h.create(h.Class.UNIVERSAL,h.Type.SEQUENCE,!0,[h.create(h.Class.UNIVERSAL,h.Type.INTEGER,!1,h.integerToDer(0).getBytes()),h.create(h.Class.UNIVERSAL,h.Type.INTEGER,!1,l(a.n)),h.create(h.Class.UNIVERSAL,h.Type.INTEGER,!1,l(a.e)),h.create(h.Class.UNIVERSAL,h.Type.INTEGER,!1,l(a.d)),h.create(h.Class.UNIVERSAL,h.Type.INTEGER,!1,l(a.p)),h.create(h.Class.UNIVERSAL, +h.Type.INTEGER,!1,l(a.q)),h.create(h.Class.UNIVERSAL,h.Type.INTEGER,!1,l(a.dP)),h.create(h.Class.UNIVERSAL,h.Type.INTEGER,!1,l(a.dQ)),h.create(h.Class.UNIVERSAL,h.Type.INTEGER,!1,l(a.qInv))])};g.publicKeyFromAsn1=function(b){var c={},d=[];if(h.validate(b,u,c,d)){d=h.derToOid(c.publicKeyOid);if(d!==g.oids.rsaEncryption)throw c=Error("Cannot read public key. Unknown OID."),c.oid=d,c;b=c.rsaPublicKey}d=[];if(!h.validate(b,B,c,d))throw c=Error("Cannot read public key. ASN.1 object does not contain an RSAPublicKey."), +c.errors=d,c;d=a.util.createBuffer(c.publicKeyModulus).toHex();c=a.util.createBuffer(c.publicKeyExponent).toHex();return g.setRsaPublicKey(new y(d,16),new y(c,16))};g.publicKeyToAsn1=g.publicKeyToSubjectPublicKeyInfo=function(a){return h.create(h.Class.UNIVERSAL,h.Type.SEQUENCE,!0,[h.create(h.Class.UNIVERSAL,h.Type.SEQUENCE,!0,[h.create(h.Class.UNIVERSAL,h.Type.OID,!1,h.oidToDer(g.oids.rsaEncryption).getBytes()),h.create(h.Class.UNIVERSAL,h.Type.NULL,!1,"")]),h.create(h.Class.UNIVERSAL,h.Type.BITSTRING, +!1,[g.publicKeyToRSAPublicKey(a)])])};g.publicKeyToRSAPublicKey=function(a){return h.create(h.Class.UNIVERSAL,h.Type.SEQUENCE,!0,[h.create(h.Class.UNIVERSAL,h.Type.INTEGER,!1,l(a.n)),h.create(h.Class.UNIVERSAL,h.Type.INTEGER,!1,l(a.e))])}}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e=!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge={}),b(forge);var g,l=function(a,c){c.exports=function(c){var e=g.map(function(b){return a(b)}).concat(b);c=c|| +{};c.defined=c.defined||{};if(c.defined.rsa)return c.rsa;c.defined.rsa=!0;for(var n=0;n>=8,V+=B.at(l)+S.at(l),S.setAt(l,V&255);O.putBuffer(S)}x=O;q.putBuffer(v)}q.truncate(q.length()-h);return q};k.pbe.getCipher=function(a,b,c){switch(a){case k.oids.pkcs5PBES2:return k.pbe.getCipherForPBES2(a,b,c);case k.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:case k.oids["pbewithSHAAnd40BitRC2-CBC"]:return k.pbe.getCipherForPKCS12PBE(a,b,c);default:throw b=Error("Cannot read encrypted PBE data block. Unsupported OID."),b.oid=a,b.supportedOids=["pkcs5PBES2","pbeWithSHAAnd3-KeyTripleDES-CBC", -"pbewithSHAAnd40BitRC2-CBC"],b;}};k.pbe.getCipherForPBES2=function(b,c,d){var h={};b=[];if(!e.validate(c,g,h,b)){var l=Error("Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");l.errors=b;throw l;}b=e.derToOid(h.kdfOid);if(b!==k.oids.pkcs5PBKDF2)throw l=Error("Cannot read encrypted private key. Unsupported key derivation function OID."),l.oid=b,l.supportedOids=["pkcs5PBKDF2"],l;b=e.derToOid(h.encOid);if(b!==k.oids["aes128-CBC"]&& -b!==k.oids["aes192-CBC"]&&b!==k.oids["aes256-CBC"]&&b!==k.oids["des-EDE3-CBC"]&&b!==k.oids.desCBC)throw l=Error("Cannot read encrypted private key. Unsupported encryption scheme OID."),l.oid=b,l.supportedOids=["aes128-CBC","aes192-CBC","aes256-CBC","des-EDE3-CBC","desCBC"],l;c=h.kdfSalt;var p=a.util.createBuffer(h.kdfIterationCount),p=p.getInt(p.length()<<3),q;switch(k.oids[b]){case "aes128-CBC":q=16;l=a.aes.createDecryptionCipher;break;case "aes192-CBC":q=24;l=a.aes.createDecryptionCipher;break; -case "aes256-CBC":q=32;l=a.aes.createDecryptionCipher;break;case "des-EDE3-CBC":q=24;l=a.des.createDecryptionCipher;break;case "desCBC":q=8,l=a.des.createDecryptionCipher}b=a.pkcs5.pbkdf2(d,c,p,q);h=h.encIv;l=l(b);l.start(h);return l};k.pbe.getCipherForPKCS12PBE=function(b,c,d){var h={},g=[];if(!e.validate(c,x,h,g))throw d=Error("Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo."),d.errors=g,d;var g=a.util.createBuffer(h.salt),h=a.util.createBuffer(h.iterations), -h=h.getInt(h.length()<<3),l;switch(b){case k.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:l=24;c=8;b=a.des.startDecrypting;break;case k.oids["pbewithSHAAnd40BitRC2-CBC"]:l=5;c=8;b=function(b,c){var d=a.rc2.createDecryptionCipher(b,40);d.start(c,null);return d};break;default:throw d=Error("Cannot read PKCS #12 PBE data block. Unsupported OID."),d.oid=b,d;}l=k.pbe.generatePkcs12Key(d,g,1,h,l);d=k.pbe.generatePkcs12Key(d,g,2,h,c);return b(l,d)};k.pbe.opensslDeriveBytes=function(b,d,e,h){if("undefined"=== -typeof h||null===h)h=a.md.md5.create();null===d&&(d="");for(var g=[c(h,b+d)],l=16,m=1;l>=8,W+=u.at(n)+R.at(n),R.setAt(n,W&255);O.putBuffer(R)}g=O;y.putBuffer(v)}y.truncate(y.length()-h);return y};l.pbe.getCipher=function(a,b,c){switch(a){case l.oids.pkcs5PBES2:return l.pbe.getCipherForPBES2(a,b,c);case l.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:case l.oids["pbewithSHAAnd40BitRC2-CBC"]:return l.pbe.getCipherForPKCS12PBE(a,b,c);default:throw b=Error("Cannot read encrypted PBE data block. Unsupported OID."),b.oid=a,b.supportedOids=["pkcs5PBES2","pbeWithSHAAnd3-KeyTripleDES-CBC", +"pbewithSHAAnd40BitRC2-CBC"],b;}};l.pbe.getCipherForPBES2=function(b,c,d){var k={};b=[];if(!e.validate(c,h,k,b)){var n=Error("Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.");n.errors=b;throw n;}b=e.derToOid(k.kdfOid);if(b!==l.oids.pkcs5PBKDF2)throw n=Error("Cannot read encrypted private key. Unsupported key derivation function OID."),n.oid=b,n.supportedOids=["pkcs5PBKDF2"],n;b=e.derToOid(k.encOid);if(b!==l.oids["aes128-CBC"]&& +b!==l.oids["aes192-CBC"]&&b!==l.oids["aes256-CBC"]&&b!==l.oids["des-EDE3-CBC"]&&b!==l.oids.desCBC)throw n=Error("Cannot read encrypted private key. Unsupported encryption scheme OID."),n.oid=b,n.supportedOids=["aes128-CBC","aes192-CBC","aes256-CBC","des-EDE3-CBC","desCBC"],n;c=k.kdfSalt;var y=a.util.createBuffer(k.kdfIterationCount),y=y.getInt(y.length()<<3),g;switch(l.oids[b]){case "aes128-CBC":g=16;n=a.aes.createDecryptionCipher;break;case "aes192-CBC":g=24;n=a.aes.createDecryptionCipher;break; +case "aes256-CBC":g=32;n=a.aes.createDecryptionCipher;break;case "des-EDE3-CBC":g=24;n=a.des.createDecryptionCipher;break;case "desCBC":g=8,n=a.des.createDecryptionCipher}b=a.pkcs5.pbkdf2(d,c,y,g);k=k.encIv;n=n(b);n.start(k);return n};l.pbe.getCipherForPKCS12PBE=function(b,c,d){var h={},k=[];if(!e.validate(c,g,h,k))throw d=Error("Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo."),d.errors=k,d;var k=a.util.createBuffer(h.salt),h=a.util.createBuffer(h.iterations), +h=h.getInt(h.length()<<3),n;switch(b){case l.oids["pbeWithSHAAnd3-KeyTripleDES-CBC"]:n=24;c=8;b=a.des.startDecrypting;break;case l.oids["pbewithSHAAnd40BitRC2-CBC"]:n=5;c=8;b=function(b,c){var d=a.rc2.createDecryptionCipher(b,40);d.start(c,null);return d};break;default:throw d=Error("Cannot read PKCS #12 PBE data block. Unsupported OID."),d.oid=b,d;}n=l.pbe.generatePkcs12Key(d,k,1,h,n);d=l.pbe.generatePkcs12Key(d,k,2,h,c);return b(n,d)};l.pbe.opensslDeriveBytes=function(b,d,e,h){if("undefined"=== +typeof h||null===h)h=a.md.md5.create();null===d&&(d="");for(var m=[c(h,b+d)],k=16,l=1;k>8*y-v&255;E=String.fromCharCode(E.charCodeAt(0)&~v)+E.substr(1); -return E+H+String.fromCharCode(188)},verify:function(b,g,k){var p;p=k-1;k=Math.ceil(p/8);g=g.substr(-k);if(k>8*k-p&255;if(0!==(v.charCodeAt(0)&E))throw Error("Bits beyond keysize not zero as expected.");var D=d.generate(g,q),z="";for(p=0;p>8*u-g&255;F=String.fromCharCode(F.charCodeAt(0)&~g)+F.substr(1); +return F+I+String.fromCharCode(188)},verify:function(b,h,k){var n;n=k-1;k=Math.ceil(n/8);h=h.substr(-k);if(k>8*k-n&255;if(0!==(u.charCodeAt(0)&F))throw Error("Bits beyond keysize not zero as expected.");var D=d.generate(h,g),z="";for(n=0;nl.length)throw Error("Cannot read notBefore/notAfter validity times; they were not provided as either UTCTime or GeneralizedTime."); -r.validity.notBefore=l[0];r.validity.notAfter=l[1];r.tbsCertificate=h.tbsCertificate;if(d){r.md=null;if(r.signatureOid in u)switch(l=u[r.signatureOid],l){case "sha1WithRSAEncryption":r.md=a.md.sha1.create();break;case "md5WithRSAEncryption":r.md=a.md.md5.create();break;case "sha256WithRSAEncryption":r.md=a.md.sha256.create();break;case "sha512WithRSAEncryption":r.md=a.md.sha512.create();break;case "RSASSA-PSS":r.md=a.md.sha256.create()}if(null===r.md)throw h=Error("Could not compute certificate digest. Unknown signature OID."), -h.signatureOid=r.signatureOid,h;l=g.toDer(r.tbsCertificate);r.md.update(l.getBytes())}l=a.md.sha1.create();r.issuer.getField=function(a){return c(r.issuer,a)};r.issuer.addField=function(a){e([a]);r.issuer.attributes.push(a)};r.issuer.attributes=x.RDNAttributesAsArray(h.certIssuer,l);h.certIssuerUniqueId&&(r.issuer.uniqueId=h.certIssuerUniqueId);r.issuer.hash=l.digest().toHex();l=a.md.sha1.create();r.subject.getField=function(a){return c(r.subject,a)};r.subject.addField=function(a){e([a]);r.subject.attributes.push(a)}; -r.subject.attributes=x.RDNAttributesAsArray(h.certSubject,l);h.certSubjectUniqueId&&(r.subject.uniqueId=h.certSubjectUniqueId);r.subject.hash=l.digest().toHex();r.extensions=h.certExtensions?x.certificateExtensionsFromAsn1(h.certExtensions):[];r.publicKey=x.publicKeyFromAsn1(h.subjectPublicKeyInfo);return r};x.certificateExtensionsFromAsn1=function(a){for(var b=[],c=0;ck.validity.notAfter)l={message:"Certificate is not valid yet or has expired.",error:x.certificateError.certificate_expired,notBefore:k.validity.notBefore,notAfter:k.validity.notAfter,now:h};if(null===l){p=c[0]||b.getIssuer(k);null===p&&k.isIssuer(k)&&(u=!0,p=k);if(p){var q=p;a.util.isArray(q)||(q=[q]);for(var D=!1;!D&&0g.pathLenConstraint&&(l={message:"Certificate basicConstraints pathLenConstraint violated.",error:x.certificateError.bad_certificate}));k=null===l?!0:l.error;g=d?d(k,m,e):k;if(!0===g)l=null;else{!0===k&&(l={message:"The application rejected the certificate.",error:x.certificateError.bad_certificate}); -if(g||0===g)"object"!==typeof g||a.util.isArray(g)?"string"===typeof g&&(l.error=g):(g.message&&(l.message=g.message),g.error&&(l.error=g.error));throw l;}g=!1;++m}while(0l.length)throw Error("Cannot read notBefore/notAfter validity times; they were not provided as either UTCTime or GeneralizedTime."); +q.validity.notBefore=l[0];q.validity.notAfter=l[1];q.tbsCertificate=k.tbsCertificate;if(d){q.md=null;if(q.signatureOid in r)switch(l=r[q.signatureOid],l){case "sha1WithRSAEncryption":q.md=a.md.sha1.create();break;case "md5WithRSAEncryption":q.md=a.md.md5.create();break;case "sha256WithRSAEncryption":q.md=a.md.sha256.create();break;case "sha512WithRSAEncryption":q.md=a.md.sha512.create();break;case "RSASSA-PSS":q.md=a.md.sha256.create()}if(null===q.md)throw k=Error("Could not compute certificate digest. Unknown signature OID."), +k.signatureOid=q.signatureOid,k;l=h.toDer(q.tbsCertificate);q.md.update(l.getBytes())}l=a.md.sha1.create();q.issuer.getField=function(a){return c(q.issuer,a)};q.issuer.addField=function(a){e([a]);q.issuer.attributes.push(a)};q.issuer.attributes=g.RDNAttributesAsArray(k.certIssuer,l);k.certIssuerUniqueId&&(q.issuer.uniqueId=k.certIssuerUniqueId);q.issuer.hash=l.digest().toHex();l=a.md.sha1.create();q.subject.getField=function(a){return c(q.subject,a)};q.subject.addField=function(a){e([a]);q.subject.attributes.push(a)}; +q.subject.attributes=g.RDNAttributesAsArray(k.certSubject,l);k.certSubjectUniqueId&&(q.subject.uniqueId=k.certSubjectUniqueId);q.subject.hash=l.digest().toHex();q.extensions=k.certExtensions?g.certificateExtensionsFromAsn1(k.certExtensions):[];q.publicKey=g.publicKeyFromAsn1(k.subjectPublicKeyInfo);return q};g.certificateExtensionsFromAsn1=function(a){for(var b=[],c=0;cn.validity.notAfter)m={message:"Certificate is not valid yet or has expired.",error:g.certificateError.certificate_expired,notBefore:n.validity.notBefore,notAfter:n.validity.notAfter,now:h};if(null===m){r=c[0]||b.getIssuer(n);null===r&&n.isIssuer(n)&&(y=!0,r=n);if(r){var D=r;a.util.isArray(D)||(D=[D]);for(var u=!1;!u&&0k.pathLenConstraint&&(m={message:"Certificate basicConstraints pathLenConstraint violated.",error:g.certificateError.bad_certificate}));n=null===m?!0:m.error;k=d?d(n,l,e):n;if(!0===k)m=null;else{!0===n&&(m={message:"The application rejected the certificate.",error:g.certificateError.bad_certificate}); +if(k||0===k)"object"!==typeof k||a.util.isArray(k)?"string"===typeof k&&(m.error=k):(k.message&&(m.message=k.message),k.error&&(m.error=k.error));throw m;}k=!1;++l}while(0>1,l=g+(b.length&1),k=b.substr(0,l),l=b.substr(g,l);b=a.util.createBuffer();g=a.hmac.create();d=c+d;var m=Math.ceil(e/16);c=Math.ceil(e/20);g.start("MD5",k);k=a.util.createBuffer();b.putBytes(d); -for(var p=0;pd)b.error(b,{message:h?"Invalid ServerHello message. Message too short.":"Invalid ClientHello message. Message too short.",send:!0,alert:{level:l.Alert.Level.fatal,description:l.Alert.Description.illegal_parameter}});else{c=c.fragment;var g=c.length(),e={version:{major:c.getByte(),minor:c.getByte()},random:a.util.createBuffer(c.getBytes(32)),session_id:k(c,1),extensions:[]};h?(e.cipher_suite=c.getBytes(2),e.compression_method=c.getByte()):(e.cipher_suites=k(c,2),e.compression_methods= -k(c,1));g=d-(g-c.length());if(0c.version.minor)d=null,e="";0===e.length&&(e=a.random.getBytes(32));b.session.id=e;b.session.clientHelloVersion= -c.version;b.session.sp={};if(d)b.version=b.session.version=d.version,b.session.sp=d.sp;else{for(var h,e=1;ed)return b.error(b,{message:"Invalid Certificate message. Message too short.",send:!0,alert:{level:l.Alert.Level.fatal,description:l.Alert.Description.illegal_parameter}});d=k(c.fragment,3);var e,h;c=[];try{for(;0d)return b.error(b,{message:"Invalid key parameters. Only RSA is supported.", -send:!0,alert:{level:l.Alert.Level.fatal,description:l.Alert.Description.unsupported_certificate}});c=k(c.fragment,2).getBytes();d=null;if(b.getPrivateKey)try{d=b.getPrivateKey(b,b.session.serverCertificate),d=a.pki.privateKeyFromPem(d)}catch(e){b.error(b,{message:"Could not get private key.",cause:e,send:!0,alert:{level:l.Alert.Level.fatal,description:l.Alert.Description.internal_error}})}if(null===d)return b.error(b,{message:"No private key set.",send:!0,alert:{level:l.Alert.Level.fatal,description:l.Alert.Description.internal_error}}); -try{var h=b.session.sp;h.pre_master_secret=d.decrypt(c);var g=b.session.clientHelloVersion;if(g.major!==h.pre_master_secret.charCodeAt(0)||g.minor!==h.pre_master_secret.charCodeAt(1))throw Error("TLS version rollback attack detected.");}catch(e){h.pre_master_secret=a.random.getBytes(48)}b.expect=F;null!==b.session.clientCertificate&&(b.expect=C);b.process()};l.handleCertificateRequest=function(a,b,c){if(3>c)return a.error(a,{message:"Invalid CertificateRequest. Message too short.",send:!0,alert:{level:l.Alert.Level.fatal, -description:l.Alert.Description.illegal_parameter}});b=b.fragment;b={certificate_types:k(b,1),certificate_authorities:k(b,2)};a.session.certificateRequest=b;a.expect=v;a.process()};l.handleCertificateVerify=function(b,c,d){if(2>d)return b.error(b,{message:"Invalid CertificateVerify. Message too short.",send:!0,alert:{level:l.Alert.Level.fatal,description:l.Alert.Description.illegal_parameter}});d=c.fragment;d.read-=4;c=d.bytes();d.read+=4;d=k(d,2).getBytes();var e=a.util.createBuffer();e.putBuffer(b.session.md5.digest()); -e.putBuffer(b.session.sha1.digest());e=e.getBytes();try{if(!b.session.clientCertificate.publicKey.verify(e,d,"NONE"))throw Error("CertificateVerify signature does not match.");b.session.md5.update(c);b.session.sha1.update(c)}catch(h){return b.error(b,{message:"Bad signature in CertificateVerify.",send:!0,alert:{level:l.Alert.Level.fatal,description:l.Alert.Description.handshake_failure}})}b.expect=F;b.process()};l.handleServerHelloDone=function(b,c,d){if(0d.length())return b.fragmented=c,c.fragment=a.util.createBuffer(),d.read-=4,b.process();b.fragmented=null;d.read-=4;var g=d.bytes(h+ -4);d.read+=4;e in ba[b.entity][b.expect]?(b.entity!==l.ConnectionEnd.server||b.open||b.fail||(b.handshaking=!0,b.session={version:null,extensions:{server_name:{serverNameList:[]}},cipherSuite:null,compressionMethod:null,serverCertificate:null,clientCertificate:null,md5:a.md.md5.create(),sha1:a.md.sha1.create()}),e!==l.HandshakeType.hello_request&&e!==l.HandshakeType.certificate_verify&&e!==l.HandshakeType.finished&&(b.session.md5.update(g),b.session.sha1.update(g)),ba[b.entity][b.expect][e](b,c,h)): -l.handleUnexpected(b,c)};l.handleApplicationData=function(a,b){a.data.putBuffer(b.fragment);a.dataReady(a);a.process()};l.handleHeartbeat=function(b,c){var d=c.fragment,e=d.getByte(),h=d.getInt16(),d=d.getBytes(h);if(e===l.HeartbeatMessageType.heartbeat_request){if(b.handshaking||h>d.length)return b.process();l.queue(b,l.createRecord(b,{type:l.ContentType.heartbeat,data:l.createHeartbeat(l.HeartbeatMessageType.heartbeat_response,d)}));l.flush(b)}else if(e===l.HeartbeatMessageType.heartbeat_response){if(d!== -b.expectedHeartbeatPayload)return b.process();b.heartbeatReceived&&b.heartbeatReceived(b,a.util.createBuffer(d))}b.process()};var g=1,x=2,u=3,v=4,A=5,y=6,H=7,E=8,D=1,z=2,C=3,F=4,M=5,W=6,r=l.handleUnexpected,R=l.handleChangeCipherSpec,U=l.handleAlert,T=l.handleHandshake,ca=l.handleApplicationData,O=l.handleHeartbeat,S=[];S[l.ConnectionEnd.client]=[[r,U,T,r,O],[r,U,T,r,O],[r,U,T,r,O],[r,U,T,r,O],[r,U,T,r,O],[R,U,r,r,O],[r,U,T,r,O],[r,U,T,ca,O],[r,U,T,r,O]];S[l.ConnectionEnd.server]=[[r,U,T,r,O],[r, -U,T,r,O],[r,U,T,r,O],[r,U,T,r,O],[R,U,r,r,O],[r,U,T,r,O],[r,U,T,ca,O],[r,U,T,r,O]];var R=l.handleHelloRequest,U=l.handleCertificate,T=l.handleServerKeyExchange,ca=l.handleCertificateRequest,O=l.handleServerHelloDone,V=l.handleFinished,ba=[];ba[l.ConnectionEnd.client]=[[r,r,l.handleServerHello,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r],[R,r,r,r,r,r,r,r,r,r,r,U,T,ca,O,r,r,r,r,r,r],[R,r,r,r,r,r,r,r,r,r,r,r,T,ca,O,r,r,r,r,r,r],[R,r,r,r,r,r,r,r,r,r,r,r,r,ca,O,r,r,r,r,r,r],[R,r,r,r,r,r,r,r,r,r,r,r,r,r,O,r,r, -r,r,r,r],[R,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r],[R,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,V],[R,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r],[R,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r]];ba[l.ConnectionEnd.server]=[[r,l.handleClientHello,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r],[r,r,r,r,r,r,r,r,r,r,r,U,r,r,r,r,r,r,r,r,r],[r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,l.handleClientKeyExchange,r,r,r,r],[r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,l.handleCertificateVerify,r,r,r,r,r],[r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r],[r, -r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,V],[r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r],[r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r,r]];l.generateKeys=function(a,b){var d=b.client_random+b.server_random;a.session.resuming||(b.master_secret=c(b.pre_master_secret,"master secret",d,48).bytes(),b.pre_master_secret=null);var d=b.server_random+b.client_random,e=2*b.mac_key_length+2*b.enc_key_length,h=a.version.major===l.Versions.TLS_1_0.major&&a.version.minor===l.Versions.TLS_1_0.minor;h&&(e+=2*b.fixed_iv_length); -d=c(b.master_secret,"key expansion",d,e);e={client_write_MAC_key:d.getBytes(b.mac_key_length),server_write_MAC_key:d.getBytes(b.mac_key_length),client_write_key:d.getBytes(b.enc_key_length),server_write_key:d.getBytes(b.enc_key_length)};h&&(e.client_write_IV=d.getBytes(b.fixed_iv_length),e.server_write_IV=d.getBytes(b.fixed_iv_length));return e};l.createConnectionState=function(a){var b=a.entity===l.ConnectionEnd.client,c=function(){var a={sequenceNumber:[0,0],macKey:null,macLength:0,macFunction:null, -cipherState:null,cipherFunction:function(a){return!0},compressionState:null,compressFunction:function(a){return!0},updateSequenceNumber:function(){4294967295===a.sequenceNumber[1]?(a.sequenceNumber[1]=0,++a.sequenceNumber[0]):++a.sequenceNumber[1]}};return a},g={read:c(),write:c()};g.read.update=function(a,b){g.read.cipherFunction(b,g.read)?g.read.compressFunction(a,b,g.read)||a.error(a,{message:"Could not decompress record.",send:!0,alert:{level:l.Alert.Level.fatal,description:l.Alert.Description.decompression_failure}}): -a.error(a,{message:"Could not decrypt record or bad MAC.",send:!0,alert:{level:l.Alert.Level.fatal,description:l.Alert.Description.bad_record_mac}});return!a.fail};g.write.update=function(a,b){g.write.compressFunction(a,b,g.write)?g.write.cipherFunction(b,g.write)||a.error(a,{message:"Could not encrypt record.",send:!1,alert:{level:l.Alert.Level.fatal,description:l.Alert.Description.internal_error}}):a.error(a,{message:"Could not compress record.",send:!1,alert:{level:l.Alert.Level.fatal,description:l.Alert.Description.internal_error}}); -return!a.fail};if(a.session)switch(c=a.session.sp,a.session.cipherSuite.initSecurityParameters(c),c.keys=l.generateKeys(a,c),g.read.macKey=b?c.keys.server_write_MAC_key:c.keys.client_write_MAC_key,g.write.macKey=b?c.keys.client_write_MAC_key:c.keys.server_write_MAC_key,a.session.cipherSuite.initConnectionState(g,a,c),c.compression_algorithm){case l.CompressionMethod.none:break;case l.CompressionMethod.deflate:g.read.compressFunction=e;g.write.compressFunction=d;break;default:throw Error("Unsupported compression algorithm."); -}return g};l.createRandom=function(){var b=new Date,b=+b+6E4*b.getTimezoneOffset(),c=a.util.createBuffer();c.putInt32(b);c.putBytes(a.random.getBytes(28));return c};l.createRecord=function(a,b){return b.data?{type:b.type,version:{major:a.version.major,minor:a.version.minor},length:b.data.length(),fragment:b.data}:null};l.createAlert=function(b,c){var d=a.util.createBuffer();d.putByte(c.level);d.putByte(c.description);return l.createRecord(b,{type:l.ContentType.alert,data:d})};l.createClientHello= -function(b){b.session.clientHelloVersion={major:b.version.major,minor:b.version.minor};for(var c=a.util.createBuffer(),d=0;dl.MaxFragment;)d.push(l.createRecord(b,{type:c.type,data:a.util.createBuffer(e.slice(0,l.MaxFragment))})),e=e.slice(l.MaxFragment);0>1,k=h+(b.length&1),l=b.substr(0,k),k=b.substr(h,k);b=a.util.createBuffer();h=a.hmac.create();d=c+d;var m=Math.ceil(e/16);c=Math.ceil(e/20);h.start("MD5",l);l=a.util.createBuffer();b.putBytes(d); +for(var r=0;rd)b.error(b,{message:h?"Invalid ServerHello message. Message too short.":"Invalid ClientHello message. Message too short.",send:!0,alert:{level:g.Alert.Level.fatal,description:g.Alert.Description.illegal_parameter}});else{c=c.fragment;var k=c.length(),e={version:{major:c.getByte(),minor:c.getByte()},random:a.util.createBuffer(c.getBytes(32)),session_id:l(c,1),extensions:[]};h?(e.cipher_suite=c.getBytes(2),e.compression_method=c.getByte()):(e.cipher_suites=l(c,2),e.compression_methods= +l(c,1));k=d-(k-c.length());if(0c.version.minor)d=null,e="";0===e.length&&(e=a.random.getBytes(32));b.session.id=e;b.session.clientHelloVersion= +c.version;b.session.sp={};if(d)b.version=b.session.version=d.version,b.session.sp=d.sp;else{for(var h,e=1;ed)return b.error(b,{message:"Invalid Certificate message. Message too short.",send:!0,alert:{level:g.Alert.Level.fatal,description:g.Alert.Description.illegal_parameter}});d=l(c.fragment,3);var e,h;c=[];try{for(;0d)return b.error(b,{message:"Invalid key parameters. Only RSA is supported.", +send:!0,alert:{level:g.Alert.Level.fatal,description:g.Alert.Description.unsupported_certificate}});c=l(c.fragment,2).getBytes();d=null;if(b.getPrivateKey)try{d=b.getPrivateKey(b,b.session.serverCertificate),d=a.pki.privateKeyFromPem(d)}catch(e){b.error(b,{message:"Could not get private key.",cause:e,send:!0,alert:{level:g.Alert.Level.fatal,description:g.Alert.Description.internal_error}})}if(null===d)return b.error(b,{message:"No private key set.",send:!0,alert:{level:g.Alert.Level.fatal,description:g.Alert.Description.internal_error}}); +try{var h=b.session.sp;h.pre_master_secret=d.decrypt(c);var k=b.session.clientHelloVersion;if(k.major!==h.pre_master_secret.charCodeAt(0)||k.minor!==h.pre_master_secret.charCodeAt(1))throw Error("TLS version rollback attack detected.");}catch(e){h.pre_master_secret=a.random.getBytes(48)}b.expect=C;null!==b.session.clientCertificate&&(b.expect=x);b.process()};g.handleCertificateRequest=function(a,b,c){if(3>c)return a.error(a,{message:"Invalid CertificateRequest. Message too short.",send:!0,alert:{level:g.Alert.Level.fatal, +description:g.Alert.Description.illegal_parameter}});b=b.fragment;b={certificate_types:l(b,1),certificate_authorities:l(b,2)};a.session.certificateRequest=b;a.expect=E;a.process()};g.handleCertificateVerify=function(b,c,d){if(2>d)return b.error(b,{message:"Invalid CertificateVerify. Message too short.",send:!0,alert:{level:g.Alert.Level.fatal,description:g.Alert.Description.illegal_parameter}});d=c.fragment;d.read-=4;c=d.bytes();d.read+=4;d=l(d,2).getBytes();var e=a.util.createBuffer();e.putBuffer(b.session.md5.digest()); +e.putBuffer(b.session.sha1.digest());e=e.getBytes();try{if(!b.session.clientCertificate.publicKey.verify(e,d,"NONE"))throw Error("CertificateVerify signature does not match.");b.session.md5.update(c);b.session.sha1.update(c)}catch(h){return b.error(b,{message:"Bad signature in CertificateVerify.",send:!0,alert:{level:g.Alert.Level.fatal,description:g.Alert.Description.handshake_failure}})}b.expect=C;b.process()};g.handleServerHelloDone=function(b,c,d){if(0d.length())return b.fragmented=c,c.fragment=a.util.createBuffer(),d.read-=4,b.process();b.fragmented=null;d.read-=4;var k=d.bytes(h+ +4);d.read+=4;e in U[b.entity][b.expect]?(b.entity!==g.ConnectionEnd.server||b.open||b.fail||(b.handshaking=!0,b.session={version:null,extensions:{server_name:{serverNameList:[]}},cipherSuite:null,compressionMethod:null,serverCertificate:null,clientCertificate:null,md5:a.md.md5.create(),sha1:a.md.sha1.create()}),e!==g.HandshakeType.hello_request&&e!==g.HandshakeType.certificate_verify&&e!==g.HandshakeType.finished&&(b.session.md5.update(k),b.session.sha1.update(k)),U[b.entity][b.expect][e](b,c,h)): +g.handleUnexpected(b,c)};g.handleApplicationData=function(a,b){a.data.putBuffer(b.fragment);a.dataReady(a);a.process()};g.handleHeartbeat=function(b,c){var d=c.fragment,e=d.getByte(),h=d.getInt16(),d=d.getBytes(h);if(e===g.HeartbeatMessageType.heartbeat_request){if(b.handshaking||h>d.length)return b.process();g.queue(b,g.createRecord(b,{type:g.ContentType.heartbeat,data:g.createHeartbeat(g.HeartbeatMessageType.heartbeat_response,d)}));g.flush(b)}else if(e===g.HeartbeatMessageType.heartbeat_response){if(d!== +b.expectedHeartbeatPayload)return b.process();b.heartbeatReceived&&b.heartbeatReceived(b,a.util.createBuffer(d))}b.process()};var h=1,u=2,r=3,E=4,A=5,B=6,I=7,F=8,D=1,z=2,x=3,C=4,M=5,aa=6,q=g.handleUnexpected,V=g.handleChangeCipherSpec,T=g.handleAlert,S=g.handleHandshake,ca=g.handleApplicationData,O=g.handleHeartbeat,R=[];R[g.ConnectionEnd.client]=[[q,T,S,q,O],[q,T,S,q,O],[q,T,S,q,O],[q,T,S,q,O],[q,T,S,q,O],[V,T,q,q,O],[q,T,S,q,O],[q,T,S,ca,O],[q,T,S,q,O]];R[g.ConnectionEnd.server]=[[q,T,S,q,O],[q, +T,S,q,O],[q,T,S,q,O],[q,T,S,q,O],[V,T,q,q,O],[q,T,S,q,O],[q,T,S,ca,O],[q,T,S,q,O]];var V=g.handleHelloRequest,T=g.handleCertificate,S=g.handleServerKeyExchange,ca=g.handleCertificateRequest,O=g.handleServerHelloDone,W=g.handleFinished,U=[];U[g.ConnectionEnd.client]=[[q,q,g.handleServerHello,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q],[V,q,q,q,q,q,q,q,q,q,q,T,S,ca,O,q,q,q,q,q,q],[V,q,q,q,q,q,q,q,q,q,q,q,S,ca,O,q,q,q,q,q,q],[V,q,q,q,q,q,q,q,q,q,q,q,q,ca,O,q,q,q,q,q,q],[V,q,q,q,q,q,q,q,q,q,q,q,q,q,O,q,q,q, +q,q,q],[V,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q],[V,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,W],[V,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q],[V,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q]];U[g.ConnectionEnd.server]=[[q,g.handleClientHello,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q],[q,q,q,q,q,q,q,q,q,q,q,T,q,q,q,q,q,q,q,q,q],[q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,g.handleClientKeyExchange,q,q,q,q],[q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,g.handleCertificateVerify,q,q,q,q,q],[q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q],[q,q, +q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,W],[q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q],[q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q,q]];g.generateKeys=function(a,b){var d=b.client_random+b.server_random;a.session.resuming||(b.master_secret=c(b.pre_master_secret,"master secret",d,48).bytes(),b.pre_master_secret=null);var d=b.server_random+b.client_random,e=2*b.mac_key_length+2*b.enc_key_length,h=a.version.major===g.Versions.TLS_1_0.major&&a.version.minor===g.Versions.TLS_1_0.minor;h&&(e+=2*b.fixed_iv_length); +d=c(b.master_secret,"key expansion",d,e);e={client_write_MAC_key:d.getBytes(b.mac_key_length),server_write_MAC_key:d.getBytes(b.mac_key_length),client_write_key:d.getBytes(b.enc_key_length),server_write_key:d.getBytes(b.enc_key_length)};h&&(e.client_write_IV=d.getBytes(b.fixed_iv_length),e.server_write_IV=d.getBytes(b.fixed_iv_length));return e};g.createConnectionState=function(a){var b=a.entity===g.ConnectionEnd.client,c=function(){var a={sequenceNumber:[0,0],macKey:null,macLength:0,macFunction:null, +cipherState:null,cipherFunction:function(a){return!0},compressionState:null,compressFunction:function(a){return!0},updateSequenceNumber:function(){4294967295===a.sequenceNumber[1]?(a.sequenceNumber[1]=0,++a.sequenceNumber[0]):++a.sequenceNumber[1]}};return a},h={read:c(),write:c()};h.read.update=function(a,b){h.read.cipherFunction(b,h.read)?h.read.compressFunction(a,b,h.read)||a.error(a,{message:"Could not decompress record.",send:!0,alert:{level:g.Alert.Level.fatal,description:g.Alert.Description.decompression_failure}}): +a.error(a,{message:"Could not decrypt record or bad MAC.",send:!0,alert:{level:g.Alert.Level.fatal,description:g.Alert.Description.bad_record_mac}});return!a.fail};h.write.update=function(a,b){h.write.compressFunction(a,b,h.write)?h.write.cipherFunction(b,h.write)||a.error(a,{message:"Could not encrypt record.",send:!1,alert:{level:g.Alert.Level.fatal,description:g.Alert.Description.internal_error}}):a.error(a,{message:"Could not compress record.",send:!1,alert:{level:g.Alert.Level.fatal,description:g.Alert.Description.internal_error}}); +return!a.fail};if(a.session)switch(c=a.session.sp,a.session.cipherSuite.initSecurityParameters(c),c.keys=g.generateKeys(a,c),h.read.macKey=b?c.keys.server_write_MAC_key:c.keys.client_write_MAC_key,h.write.macKey=b?c.keys.client_write_MAC_key:c.keys.server_write_MAC_key,a.session.cipherSuite.initConnectionState(h,a,c),c.compression_algorithm){case g.CompressionMethod.none:break;case g.CompressionMethod.deflate:h.read.compressFunction=e;h.write.compressFunction=d;break;default:throw Error("Unsupported compression algorithm."); +}return h};g.createRandom=function(){var b=new Date,b=+b+6E4*b.getTimezoneOffset(),c=a.util.createBuffer();c.putInt32(b);c.putBytes(a.random.getBytes(28));return c};g.createRecord=function(a,b){return b.data?{type:b.type,version:{major:a.version.major,minor:a.version.minor},length:b.data.length(),fragment:b.data}:null};g.createAlert=function(b,c){var d=a.util.createBuffer();d.putByte(c.level);d.putByte(c.description);return g.createRecord(b,{type:g.ContentType.alert,data:d})};g.createClientHello= +function(b){b.session.clientHelloVersion={major:b.version.major,minor:b.version.minor};for(var c=a.util.createBuffer(),d=0;dg.MaxFragment;)d.push(g.createRecord(b,{type:c.type,data:a.util.createBuffer(e.slice(0,g.MaxFragment))})),e=e.slice(g.MaxFragment);0d?c=5-d:(g.record={type:b.getByte(),version:{major:b.getByte(),minor:b.getByte()},length:b.getInt16(),fragment:a.util.createBuffer(),ready:!1},(b=g.record.version.major===g.version.major)&&g.session&&g.session.version&&(b=g.record.version.minor===g.version.minor),b||g.error(g,{message:"Incompatible TLS version.",send:!0, -alert:{level:l.Alert.Level.fatal,description:l.Alert.Description.protocol_version}}))}if(!g.fail&&null!==g.record&&!g.record.ready){c=g;b=0;var d=c.input,e=d.length();e=l.Versions.TLS_1_1.minor&&k.output.putBytes(h);k.update(b.fragment);k.finish(e)&&(b.fragment=k.output,b.length=b.fragment.length(),g=!0);return g}function e(a,b,c){c||(a-=b.length()%a,b.fillWithByte(a-1,a));return!0}function k(a,b,c){a=!0;if(c){c=b.length();for(var d=b.last(),e=c-1- -d;e=h?(b.fragment=e.output.getBytes(p-h),m=e.output.getBytes(h)):b.fragment=e.output.getBytes();b.fragment=a.util.createBuffer(b.fragment);b.length= -b.fragment.length();h=c.macFunction(c.macKey,c.sequenceNumber,b);c.updateSequenceNumber();e=c.macKey;p=a.hmac.create();p.start("SHA1",e);p.update(m);m=p.digest().getBytes();p.start(null,null);p.update(h);h=p.digest().getBytes();return m===h&&d}var l=a.tls;l.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA={id:[0,47],name:"TLS_RSA_WITH_AES_128_CBC_SHA",initSecurityParameters:function(a){a.bulk_cipher_algorithm=l.BulkCipherAlgorithm.aes;a.cipher_type=l.CipherType.block;a.enc_key_length=16;a.block_length=16; +c){c.origin=c.origin||(a.entity===g.ConnectionEnd.client?"client":"server");c.send&&(g.queue(a,g.createAlert(a,c.alert)),g.flush(a));var d=!1!==c.fatal;d&&(a.fail=!0);b.error(a,c);d&&a.close(!1)},deflate:b.deflate||null,inflate:b.inflate||null,reset:function(a){k.version={major:g.Version.major,minor:g.Version.minor};k.record=null;k.session=null;k.peerCertificate=null;k.state={pending:null,current:null};k.expect=0;k.fragmented=null;k.records=[];k.open=!1;k.handshakes=0;k.handshaking=!1;k.isConnected= +!1;k.fail=!(a||"undefined"===typeof a);k.input.clear();k.tlsData.clear();k.data.clear();k.state.current=g.createConnectionState(k)}};k.reset();k.handshake=function(b){if(k.entity!==g.ConnectionEnd.client)k.error(k,{message:"Cannot initiate handshake as a server.",fatal:!1});else if(k.handshaking)k.error(k,{message:"Handshake already in progress.",fatal:!1});else{k.fail&&!k.open&&0===k.handshakes&&(k.fail=!1);k.handshaking=!0;b=b||"";var c=null;0d?c=5-d:(k.record={type:b.getByte(),version:{major:b.getByte(),minor:b.getByte()},length:b.getInt16(),fragment:a.util.createBuffer(),ready:!1},(b=k.record.version.major===k.version.major)&&k.session&&k.session.version&&(b=k.record.version.minor===k.version.minor),b||k.error(k,{message:"Incompatible TLS version.",send:!0, +alert:{level:g.Alert.Level.fatal,description:g.Alert.Description.protocol_version}}))}if(!k.fail&&null!==k.record&&!k.record.ready){c=k;b=0;var d=c.input,e=d.length();e=l.Versions.TLS_1_1.minor&&k.output.putBytes(g);k.update(b.fragment);k.finish(e)&&(b.fragment=k.output,b.length=b.fragment.length(),h=!0);return h}function e(a,b,c){c||(a-=b.length()%a,b.fillWithByte(a-1,a));return!0}function g(a,b,c){a=!0;if(c){c=b.length();for(var d=b.last(),e=c-1- +d;e=k?(b.fragment=e.output.getBytes(n-k),m=e.output.getBytes(k)):b.fragment=e.output.getBytes();b.fragment=a.util.createBuffer(b.fragment);b.length= +b.fragment.length();k=c.macFunction(c.macKey,c.sequenceNumber,b);c.updateSequenceNumber();e=c.macKey;n=a.hmac.create();n.start("SHA1",e);n.update(m);m=n.digest().getBytes();n.start(null,null);n.update(k);k=n.digest().getBytes();return m===k&&d}var l=a.tls;l.CipherSuites.TLS_RSA_WITH_AES_128_CBC_SHA={id:[0,47],name:"TLS_RSA_WITH_AES_128_CBC_SHA",initSecurityParameters:function(a){a.bulk_cipher_algorithm=l.BulkCipherAlgorithm.aes;a.cipher_type=l.CipherType.block;a.enc_key_length=16;a.block_length=16; a.fixed_iv_length=16;a.record_iv_length=16;a.mac_algorithm=l.MACAlgorithm.hmac_sha1;a.mac_length=20;a.mac_key_length=20},initConnectionState:c};l.CipherSuites.TLS_RSA_WITH_AES_256_CBC_SHA={id:[0,53],name:"TLS_RSA_WITH_AES_256_CBC_SHA",initSecurityParameters:function(a){a.bulk_cipher_algorithm=l.BulkCipherAlgorithm.aes;a.cipher_type=l.CipherType.block;a.enc_key_length=32;a.block_length=16;a.fixed_iv_length=16;a.record_iv_length=16;a.mac_algorithm=l.MACAlgorithm.hmac_sha1;a.mac_length=20;a.mac_key_length= -20},initConnectionState:c};var g=0}if("function"!==typeof a)if("object"===typeof module&&module.exports){var e=!0;a=function(a,b){b(c,module)}}else return"undefined"===typeof forge&&(forge={}),b(forge);var q,k=function(a,c){c.exports=function(c){var e=q.map(function(b){return a(b)}).concat(b);c=c||{};c.defined=c.defined||{};if(c.defined.aesCipherSuites)return c.aesCipherSuites;c.defined.aesCipherSuites=!0;for(var k=0;k=c&&e=c&&eb.contentInfo.value.length)throw Error("Could not sign PKCS#7 message; there is no content to sign.");var g=u.derToOid(b.contentInfo.value[0].value),d=b.contentInfo.value[1],d=d.value[0],h=u.toDer(d);h.getByte();u.getBerValueLength(h);var h=h.getBytes(),l;for(l in c)c[l].start().update(h);l=new Date;for(d=0;db.contentInfo.value.length)throw Error("Could not sign PKCS#7 message; there is no content to sign.");var h=r.derToOid(b.contentInfo.value[0].value),d=b.contentInfo.value[1],d=d.value[0],l=r.toDer(d);l.getByte();r.getBerValueLength(l);var l=l.getBytes(),m;for(m in c)c[m].start().update(l);m=new Date;for(d=0;db.length)return console.error("Invalid script length"),null;if(612182341!=ReadInt(b,0))return console.error("Invalid binary script"),null;if(1m){for(;1n;n++)c.push(a.getVar(v[n]));var B; -try{if(1E4>b)switch(b){case 0:break;case 1:if(c[2]){if("<"==c[2]&&c[1]="==c[2]&&c[1]>=c[3]||">"==c[2]&&c[1]>c[3])a.ip=c[0]}else a.ip=c[0];break;case 2:void 0==v[1]?delete a.variables[v[0]]:a.setVar(v[0],c[1]);break;case 3:if(a.onConsole)a.onConsole(a.toString(c[0]),a);else console.log(a.toString(c[0]));break;case 4:a.state=2;a.dialog=!0;setDialogMode(11,c[0],c[2],a.xxStepDialogOk,c[1],a);break;case 5:for(n in c[1])c[1][n][c[2]]== -c[3]&&(B=n);break;case 6:B=c[1].substr(c[2],c[3]);break;case 7:B=c[1].indexOf(c[2]);break;case 8:B=c[1].split(c[2]);break;case 9:B=c[1].join(c[2]);break;case 10:B=c[1].length;break;case 11:B=JSON.parse(c[1]);break;case 12:B=JSON.stringify(c[1]);break;case 13:B=c[1]+c[2];break;case 14:B=c[1]-c[2];break;case 15:B=parseInt(c[1]);break;case 16:a.state=2;a.amtstack.BatchEnum(c[0],c[1],a.xxWsmanReturn,a);break;case 17:a.state=2;a.amtstack.Put(c[0],c[1],a.xxWsmanReturn,a);break;case 18:a.state=2;a.amtstack.Create(c[0], +a.timer=null;a.stepspeed=0};a.getVar=function(b){return void 0==b?void 0:a.getVarEx(b.split("."),a.variables)};a.getVarEx=function(b,c){try{return void 0==b?void 0:0==b.length?c:a.getVarEx(b.slice(1),c[b[0]])}catch(g){return null}};a.setVar=function(b,c){a.setVarEx(b.split("."),a.variables,c)};a.setVarEx=function(b,c,g){1==b.length?c[b[0]]=g:a.setVarEx(b.slice(1),c[b[0]],g)};a.step=function(){if(1==a.state){if(a.ipm){for(;1p;p++)c.push(a.getVar(u[p]));var k; +try{if(1E4>b)switch(b){case 0:break;case 1:if(c[2]){if("<"==c[2]&&c[1]="==c[2]&&c[1]>=c[3]||">"==c[2]&&c[1]>c[3])a.ip=c[0]}else a.ip=c[0];break;case 2:void 0==u[1]?delete a.variables[u[0]]:a.setVar(u[0],c[1]);break;case 3:if(a.onConsole)a.onConsole(a.toString(c[0]),a);else console.log(a.toString(c[0]));break;case 4:a.state=2;a.dialog=!0;setDialogMode(11,c[0],c[2],a.xxStepDialogOk,c[1],a);break;case 5:for(p in c[1])c[1][p][c[2]]== +c[3]&&(k=p);break;case 6:k=c[1].substr(c[2],c[3]);break;case 7:k=c[1].indexOf(c[2]);break;case 8:k=c[1].split(c[2]);break;case 9:k=c[1].join(c[2]);break;case 10:k=c[1].length;break;case 11:k=JSON.parse(c[1]);break;case 12:k=JSON.stringify(c[1]);break;case 13:k=c[1]+c[2];break;case 14:k=c[1]-c[2];break;case 15:k=parseInt(c[1]);break;case 16:a.state=2;a.amtstack.BatchEnum(c[0],c[1],a.xxWsmanReturn,a);break;case 17:a.state=2;a.amtstack.Put(c[0],c[1],a.xxWsmanReturn,a);break;case 18:a.state=2;a.amtstack.Create(c[0], c[1],a.xxWsmanReturn,a);break;case 19:a.state=2;a.amtstack.Delete(c[0],c[1],a.xxWsmanReturn,a);break;case 20:a.state=2;a.amtstack.Exec(c[0],c[1],c[2],a.xxWsmanReturn,a,0,c[3]);break;case 21:a.stepspeed=c[0];null!=a.timer&&(clearInterval(a.timer),a.timer=setInterval(function(){a.step()},a.stepspeed));break;case 22:a.state=2;a.amtstack.Subscribe(c[0],c[1],c[2],a.xxWsmanReturn,a,0,c[3],c[4],c[5],c[6]);break;case 23:a.state=2;a.amtstack.UnSubscribe(c[0],a.xxWsmanReturn,a,0,c[1]);break;case 24:console.log(c[1], -c[2],c[1].charCodeAt(c[2]));B=c[1].charCodeAt(c[2]);break;case 25:a.state=2;amtcert_signWithCaKey(c[0],null,c[1],{CN:"Untrusted Root Certificate"},a.xxSignWithDummyCaReturn);break;default:a.state=9,console.error("Script Error, unknown command: "+b)}else 2E4>b?B=script_functionTableX2[b-1E4](c[1],c[2],c[3],c[4],c[5],c[6]):script_functionTableX3&&script_functionTableX3[b-2E4]&&(B=script_functionTableX3[b-2E4](a,c[1],c[2],c[3],c[4],c[5],c[6]));void 0!=B&&a.setVar(v[0],B)}catch(l){"object"==typeof l&& -(l=l.message),a.setVar("_exception",l)}}1==a.state&&a.ip>=a.script.length&&(a.state=0,a.stop());if(a.onStep)a.onStep(a);return a}};a.xxStepDialogOk=function(b){a.variables.DialogSelect=b;a.state=1;a.dialog=!1;if(a.onStep)a.onStep(a)};a.xxWsmanReturn=function(b,c,q,k){a.setVar(c,q);a.setVar("wsman_result",k);a.setVar("wsman_result_str",httpErrorTable[k]?httpErrorTable[k]:"Error #"+k);a.state=1;if(a.onStep)a.onStep(a)};a.xxSignWithDummyCaReturn=function(b){a.setVar("signed_cert",btoa(_arrayBufferToString(b))); +c[2],c[1].charCodeAt(c[2]));k=c[1].charCodeAt(c[2]);break;case 25:a.state=2;amtcert_signWithCaKey(c[0],null,c[1],{CN:"Untrusted Root Certificate"},a.xxSignWithDummyCaReturn);break;default:a.state=9,console.error("Script Error, unknown command: "+b)}else 2E4>b?k=script_functionTableX2[b-1E4](c[1],c[2],c[3],c[4],c[5],c[6]):script_functionTableX3&&script_functionTableX3[b-2E4]&&(k=script_functionTableX3[b-2E4](a,c[1],c[2],c[3],c[4],c[5],c[6]));void 0!=k&&a.setVar(u[0],k)}catch(y){"object"==typeof y&& +(y=y.message),a.setVar("_exception",y)}}1==a.state&&a.ip>=a.script.length&&(a.state=0,a.stop());if(a.onStep)a.onStep(a);return a}};a.xxStepDialogOk=function(b){a.variables.DialogSelect=b;a.state=1;a.dialog=!1;if(a.onStep)a.onStep(a)};a.xxWsmanReturn=function(b,c,g,l){a.setVar(c,g);a.setVar("wsman_result",l);a.setVar("wsman_result_str",httpErrorTable[l]?httpErrorTable[l]:"Error #"+l);a.state=1;if(a.onStep)a.onStep(a)};a.xxSignWithDummyCaReturn=function(b){a.setVar("signed_cert",btoa(_arrayBufferToString(b))); a.state=1;if(a.onStep)a.onStep(a)};a.toString=function(a){return"object"==typeof a?JSON.stringify(a):a};a.reset();return a} -function script_compile(b,c){var a="",d=b.split("\n"),e={},q=[],k=[],v;for(v in d){var n=d[v];if(n.startsWith("##SWAP ")){var p=n.split(" ");3==p.length&&(k[p[1]]=p[2])}if("#"!=n[0]&&0!=n.length){for(p in k)n=n.split(p).join(k[p]);var h=n.match(/"[^"]*"|[^\s"]+/g);if(0!=h.length)if(":"==n[0])e[h[0].toUpperCase()]=a.length;else{n=script_functionTable1.indexOf(h[0].toLowerCase());-1==n&&(n=script_functionTable2.indexOf(h[0].toLowerCase()),0<=n&&(n+=1E4));-1==n&&(n=script_functionTable3.indexOf(h[0].toLowerCase()), -0<=n&&(n+=2E4));if(-1==n)return c&&c("Unabled to compile, unknown command: "+h[0]),"";var m=ShortToStr(h.length-1),w;for(w in h)if(0!=w)if(":"==h[w][0])q.push([h[w],a.length+m.length+7]),m+=ShortToStr(5)+String.fromCharCode(3)+IntToStr(4294967295);else var B=parseInt(h[w]),m=B==h[w]?m+(ShortToStr(5)+String.fromCharCode(2)+IntToStr(B)):'"'==h[w][0]&&'"'==h[w][h[w].length-1]?m+(ShortToStr(h[w].length-1)+String.fromCharCode(1)+h[w].substring(1,h[w].length-1)):m+(ShortToStr(h[w].length+1)+String.fromCharCode(0)+ -h[w]);m=ShortToStr(n)+ShortToStr(m.length+4)+m;a+=m}}}for(v in q){d=q[v][0].toUpperCase();k=q[v][1];p=e[d];if(void 0==p)return c&&c("Unabled to compile, unknown label: "+d),"";a=a.substr(0,k)+IntToStr(p)+a.substr(k+4)}return IntToStr(612182341)+ShortToStr(1)+a} -function script_decompile(b,c){var a="",d=6,e={};if(0<=c)d=c;else{if(6>b.length)return"# Invalid script length";var q=ReadInt(b,0),k=ReadShort(b,4);if(612182341!=q)return"# Invalid binary script: "+q;if(1!=k)return"# Invalid script version"}for(;dq?a+(script_functionTable1[q]+p+"\n"):2E4<=q?a+(script_functionTable3[q-2E4]+p+"\n"):a+(script_functionTable2[q-1E4]+p+"\n");d+=k;if(0<=c)return a}d=a.split("\n");a="";for(h in d)q=d[h],":"!=q[0]?a+=q+"\n":e[q]&&(a+=q+"\n");return a} -var CreateAmtRemoteDesktop=function(b,c){function a(a,b,c,m,n,p,w,B){var E=a.charCodeAt(b++);B={};var D=0,z=0;if(0==E){for(n=0;n>8&248)+","+(E>>3&252)+","+((E&31)<<3))+")",a=q(c,m),m=k(c,m),h.canvas.fillRect(a,m,n,p);else if(1E){p=4;z=15;for(n=0;n=E&&(p=2,z=3);for(;D>n&z],D++);d(h.spare,c,m)}else if(128==E){for(;D>8&248,h.spare.data[c++]=a>>3&252,h.spare.data[c++]=(a&31)<<3);h.spare.data[c]=255}function q(a,b){return 0==h.rotation||1==h.rotation?a:2==h.rotation?a-h.canvas.canvas.width:3==h.rotation?a-h.canvas.canvas.height:0}function k(a, -b){return 0==h.rotation?b:1==h.rotation?b-h.canvas.canvas.width:2==h.rotation?b-h.canvas.canvas.height:3==h.rotation?b:0}function v(a){return 127=c&&(d=c+32);112<=c&&124>=c&&(d=c+65358);8==c&&(d=65288);9==c&&(d=65289);13==c&&(d=65293);16==c&&(d=65505);17==c&&(d=65507);18==c&&(d=65513);27==c&&(d=65307);33==c&&(d=65365);34==c&&(d=65366);35==c&&(d=65367);36==c&&(d=65360);37==c&&(d=65361);38==c&&(d=65362);39==c&&(d=65363);40==c&&(d=65364);45==c&&(d=65379);46==c&&(d=65535);96<=c&&105>=c&&(d=c- -48);106==c&&(d=42);107==c&&(d=43);109==c&&(d=45);110==c&&(d=46);111==c&&(d=47);186==c&&(d=59);187==c&&(d=61);188==c&&(d=44);189==c&&(d=45);190==c&&(d=46);191==c&&(d=47);192==c&&(d=96);219==c&&(d=91);220==c&&(d=92);221==c&&(d=93);222==c&&(d=39);h.sendkey(d,a)}return h.haltEvent(b)}var h={};h.canvasid=b;h.scrolldiv=c;h.canvas=Q(b).getContext("2d");h.protocol=2;h.state=0;h.acc="";h.ScreenWidth=960;h.ScreenHeight=700;h.width=0;h.height=0;h.rwidth=0;h.rheight=0;h.bpp=2;h.useZRLE=!0;h.showmouse=!0;h.buttonmask= -0;h.spare=null;h.sparew=0;h.spareh=0;h.sparew2=0;h.spareh2=0;h.sparecache={};h.ZRLEfirst=1;h.onScreenSizeChange=null;h.frameRateDelay=0;h.noMouseRotate=!1;h.rotation=0;h.kvmDataSupported=!1;h.onKvmData=null;h.onKvmDataPending=[];h.onKvmDataAck=-1;h.holding=!1;h.lastKeepAlive=Date.now();h.inflate=ZLIB.inflateInit(-15);h.Debug=function(a){console.log(a)};h.xxStateChange=function(a){0==a?(h.canvas.fillStyle="#000000",h.canvas.fillRect(0,0,h.width,h.height),h.canvas.canvas.width=h.rwidth=h.width=640, -h.canvas.canvas.height=h.rheight=h.height=400,QS(h.canvasid).cursor="auto",h.inflate=ZLIB.inflateInit(-15)):h.showmouse||(QS(h.canvasid).cursor="none")};h.ProcessData=function(b){if(b)for(h.acc+=b;0h.acc.length)return;h.state=100+ReadShort(h.acc,2);c=4;break;case 2:c=1;break;case 3:if(8>h.acc.length)return;b=ReadInt(h.acc,4)+8;if(h.acc.lengthk.length)c=0;else if(b=ReadInt(h.acc,4)+8,k.lengthq){if(1>c||64m||64h.acc.length)break;v=ReadInt(h.acc,12);if(h.acc.length<16+v)break;q=16; -5a;)a+=4;a%=4;if(1==h.holding)h.rotation=a;else{if(a==h.rotation)return!0;var b= -h.canvas.canvas.width,c=h.canvas.canvas.height;if(1==h.rotation||3==h.rotation)b=h.canvas.canvas.height,c=h.canvas.canvas.width;null==h.tcanvas&&(h.tcanvas=document.createElement("canvas"));var d=h.tcanvas.getContext("2d");d.setTransform(1,0,0,1,0,0);d.canvas.width=b;d.canvas.height=c;d.rotate(-90*h.rotation*Math.PI/180);0==h.rotation&&d.drawImage(h.canvas.canvas,0,0);1==h.rotation&&d.drawImage(h.canvas.canvas,-h.canvas.canvas.width,0);2==h.rotation&&d.drawImage(h.canvas.canvas,-h.canvas.canvas.width, --h.canvas.canvas.height);3==h.rotation&&d.drawImage(h.canvas.canvas,0,-h.canvas.canvas.height);if(0==h.rotation||2==h.rotation)h.canvas.canvas.height=b,h.canvas.canvas.width=c;if(1==h.rotation||3==h.rotation)h.canvas.canvas.height=c,h.canvas.canvas.width=b;h.canvas.setTransform(1,0,0,1,0,0);h.canvas.rotate(90*a*Math.PI/180);h.rotation=a;h.canvas.drawImage(h.tcanvas,q(0,0),k(0,0));h.width=h.canvas.canvas.width;h.height=h.canvas.canvas.height;if(null!=h.onScreenResize)h.onScreenResize(h,h.width,h.height, -h.CanvasId);return!0}};h.Start=function(){h.state=0;h.acc="";h.ZRLEfirst=1;h.inflate.inflateReset();h.onKvmDataPending=[];h.onKvmDataAck=-1;h.kvmDataSupported=!1;for(var a in h.sparecache)delete h.sparecache[a]};h.Stop=function(){h.UnGrabMouseInput();h.UnGrabKeyInput();h.parent.Stop()};h.Send=function(a){h.parent.Send(a)};var m={Pause:19,CapsLock:20,Space:32,Quote:39,Minus:45,NumpadMultiply:42,NumpadAdd:43,PrintScreen:44,Comma:44,NumpadSubtract:45,NumpadDecimal:46,Period:46,Slash:47,NumpadDivide:47, -Semicolon:59,Equal:61,OSLeft:91,BracketLeft:91,OSRight:91,Backslash:92,BracketRight:93,ContextMenu:93,Backquote:96,NumLock:144,ScrollLock:145,Backspace:65288,Tab:65289,Enter:65293,NumpadEnter:65293,Escape:65307,Delete:65535,Home:65360,PageUp:65365,PageDown:65366,ArrowLeft:65361,ArrowUp:65362,ArrowRight:65363,ArrowDown:65364,End:65367,Insert:65379,F1:65470,F2:65471,F3:65472,F4:65473,F5:65474,F6:65475,F7:65476,F8:65477,F9:65478,F10:65479,F11:65480,F12:65481,ShiftLeft:65505,ShiftRight:65506,ControlLeft:65507, -ControlRight:65508,AltLeft:65513,AltRight:65514,MetaLeft:65511,MetaRight:65512};h.sendkey=function(a,b){if("object"==typeof a)for(var c in a)h.sendkey(a[c][0],a[c][1]);else h.Send(String.fromCharCode(4,b,0,0)+IntToStr(a))};h.sendKvmData=function(a){!0!==h.onKvmDataAck?h.onKvmDataPending.push(a):(urlvars&&urlvars.kvmdatatrace&&console.log("KVM-Send("+a.length+"): "+a),a="\x00KvmDataChannel\x00"+a,h.Send(String.fromCharCode(6,0,0,0)+IntToStr(a.length)+a),h.onKvmDataAck=!1)};h.sendKeepAlive=function(){h.lastKeepAlive< -Date.now()-5E3&&(h.lastKeepAlive=Date.now(),h.Send(String.fromCharCode(6,0,0,0)+IntToStr(16)+"\x00KvmDataChannel\x00"))};h.SendCtrlAltDelMsg=function(){h.sendcad()};h.sendcad=function(){h.sendkey(65507,1);h.sendkey(65513,1);h.sendkey(65535,1);h.sendkey(65535,0);h.sendkey(65513,0);h.sendkey(65507,0)};var w=!1,B=!1;h.GrabMouseInput=function(){if(1!=w){var a=h.canvas.canvas;a.onmouseup=h.mouseup;a.onmousedown=h.mousedown;a.onmousemove=h.mousemove;w=!0}};h.UnGrabMouseInput=function(){if(0!=w){var a=h.canvas.canvas; -a.onmousemove=null;a.onmouseup=null;a.onmousedown=null;w=!1}};h.GrabKeyInput=function(){1!=B&&(document.onkeyup=h.handleKeyUp,document.onkeydown=h.handleKeyDown,document.onkeypress=h.handleKeys,B=!0)};h.UnGrabKeyInput=function(){0!=B&&(document.onkeyup=null,document.onkeydown=null,document.onkeypress=null,B=!1)};h.handleKeys=function(a){return h.haltEvent(a)};h.handleKeyUp=function(a){return p(0,a)};h.handleKeyDown=function(a){return p(1,a)};h.haltEvent=function(a){a.preventDefault&&a.preventDefault(); -a.stopPropagation&&a.stopPropagation();return!1};h.mousedown=function(a){h.buttonmask|=1<b.length)){var c=null,d=0,v=0,n=ReadShort(b,0),p=ReadShort(b,2);p!=b.length&&1==a.debugmode&&console.log(p,b.length,p==b.length);if(18<=n)console.error("Invalid KVM command "+n+" of size "+p),console.log("Invalid KVM data",b.length,b,rstr2hex(b)); -else if(p>b.length)console.error("KVM invalid command size",p,b.length);else{if(3==n||4==n||7==n)c=b.substring(4,p),d=((c.charCodeAt(0)&255)<<8)+(c.charCodeAt(1)&255),v=((c.charCodeAt(2)&255)<<8)+(c.charCodeAt(3)&255);switch(n){case 3:if(a.FirstDraw)a.onResize();a.ProcessPictureMsg(c,d,v);break;case 4:if(a.FirstDraw)a.onResize();a.TilesDrawn==a.tilesReceived?a.ProcessCopyRectMsg(c):a.PendingOperations.push([++tilesReceived,1,c]);break;case 7:a.ProcessScreenMsg(d,v);a.SendKeyMsgKC(a.KeyAction.UP,16); -a.SendKeyMsgKC(a.KeyAction.UP,17);a.SendKeyMsgKC(a.KeyAction.UP,18);a.SendKeyMsgKC(a.KeyAction.UP,91);a.SendKeyMsgKC(a.KeyAction.UP,92);a.SendKeyMsgKC(a.KeyAction.UP,16);a.send(String.fromCharCode(0,14,0,4));break;case 11:c=[];d=((b.charCodeAt(4)&255)<<8)+(b.charCodeAt(5)&255);if(0>8,b&255))};a.intToStr=function(a){return String.fromCharCode(a>>24&255,a>>16&255,a>>8&255,a&255)}; -a.shortToStr=function(a){return String.fromCharCode(a>>8&255,a&255)};a.onResize=function(){if(0!=a.ScreenWidth&&0!=a.ScreenHeight&&(a.Canvas.canvas.width!=a.ScreenWidth||a.Canvas.canvas.height!=a.ScreenHeight)){if(a.FirstDraw&&(a.Canvas.canvas.width=a.ScreenWidth,a.Canvas.canvas.height=a.ScreenHeight,a.Canvas.fillRect(0,0,a.ScreenWidth,a.ScreenHeight),null!=a.onScreenSizeChange))a.onScreenSizeChange(a,a.ScreenWidth,a.ScreenHeight,a.CanvasId);a.FirstDraw=!1}};a.xxMouseInputGrab=!1;a.xxKeyInputGrab= -!1;a.xxMouseMove=function(b){3==a.State&&a.SendMouseMsg(a.KeyAction.NONE,b);b.preventDefault&&b.preventDefault();b.stopPropagation&&b.stopPropagation();return!1};a.xxMouseUp=function(b){3==a.State&&a.SendMouseMsg(a.KeyAction.UP,b);b.preventDefault&&b.preventDefault();b.stopPropagation&&b.stopPropagation();return!1};a.xxMouseDown=function(b){3==a.State&&a.SendMouseMsg(a.KeyAction.DOWN,b);b.preventDefault&&b.preventDefault();b.stopPropagation&&b.stopPropagation();return!1};a.xxDOMMouseScroll=function(b){return 3== -a.State?(a.SendMouseMsg(a.KeyAction.SCROLL,b),!1):!0};a.xxMouseWheel=function(b){return 3==a.State?(a.SendMouseMsg(a.KeyAction.SCROLL,b),!1):!0};a.xxKeyUp=function(b){3==a.State&&a.SendKeyMsg(a.KeyAction.UP,b);b.preventDefault&&b.preventDefault();b.stopPropagation&&b.stopPropagation();return!1};a.xxKeyDown=function(b){3==a.State&&a.SendKeyMsg(a.KeyAction.DOWN,b);b.preventDefault&&b.preventDefault();b.stopPropagation&&b.stopPropagation();return!1};a.xxKeyPress=function(a){a.preventDefault&&a.preventDefault(); -a.stopPropagation&&a.stopPropagation();return!1};a.handleKeys=function(b){return 1==a.stopInput||3!=desktop.State?!1:a.xxKeyPress(b)};a.handleKeyUp=function(b){if(1==a.stopInput||3!=desktop.State)return!1;if(5>a.firstUpKeys.length&&(a.firstUpKeys.push(b.keyCode),5==a.firstUpKeys.length)){var c=a.firstUpKeys.join(",");if("16,17,91,91,16"==c||"16,17,18,91,92"==c)a.stopInput=!0}return a.xxKeyUp(b)};a.handleKeyDown=function(b){return 1==a.stopInput||3!=desktop.State?!1:a.xxKeyDown(b)};a.mousedown=function(b){return 1== -a.stopInput?!1:a.xxMouseDown(b)};a.mouseup=function(b){return 1==a.stopInput?!1:a.xxMouseUp(b)};a.mousemove=function(b){return 1==a.stopInput?!1:a.xxMouseMove(b)};a.mousewheel=function(b){return 1==a.stopInput?!1:a.xxMouseWheel(b)};a.xxMsTouchEvent=function(b){if(4!=b.originalEvent.pointerType){b.preventDefault&&b.preventDefault();b.stopPropagation&&b.stopPropagation();if("MSPointerDown"==b.type||"MSPointerMove"==b.type||"MSPointerUp"==b.type){var c=0,d=b.originalEvent.pointerId%256,v=Canvas.canvas.width/ -a.CanvasId.clientWidth*b.offsetX,n=Canvas.canvas.height/a.CanvasId.clientHeight*b.offsetY;"MSPointerDown"==b.type?c=65542:"MSPointerMove"==b.type?c=131078:"MSPointerUp"==b.type&&(c=262144);a.TouchArray[d]||(a.TouchArray[d]={x:v,y:n});a.SendTouchMsg2(d,c);"MSPointerUp"==b.type&&delete a.TouchArray[d]}else alert(b.type);return!0}};a.xxTouchStart=function(b){if(3==a.State)if(b.preventDefault&&b.preventDefault(),0==a.touchenabled||1==a.touchenabled){if(!(1b;)b+=4;b%=4;if(b==a.rotation)return!0;var c=a.Canvas.canvas.width,d=a.Canvas.canvas.height;if(1==a.rotation||3==a.rotation)c=a.Canvas.canvas.height,d=a.Canvas.canvas.width;null==a.tcanvas&&(a.tcanvas=document.createElement("canvas"));var v=a.tcanvas.getContext("2d");v.setTransform(1,0,0,1,0,0);v.canvas.width=c;v.canvas.height=d;v.rotate(-90*a.rotation*Math.PI/180);0==a.rotation&&v.drawImage(a.Canvas.canvas,0,0);1==a.rotation&&v.drawImage(a.Canvas.canvas,-a.Canvas.canvas.width, -0);2==a.rotation&&v.drawImage(a.Canvas.canvas,-a.Canvas.canvas.width,-a.Canvas.canvas.height);3==a.rotation&&v.drawImage(a.Canvas.canvas,0,-a.Canvas.canvas.height);if(0==a.rotation||2==a.rotation)a.Canvas.canvas.height=c,a.Canvas.canvas.width=d;if(1==a.rotation||3==a.rotation)a.Canvas.canvas.height=d,a.Canvas.canvas.width=c;a.Canvas.setTransform(1,0,0,1,0,0);a.Canvas.rotate(90*b*Math.PI/180);a.rotation=b;a.Canvas.drawImage(a.tcanvas,a.rotX(0,0),a.rotY(0,0));a.ScreenWidth=a.Canvas.canvas.width;a.ScreenHeight= -a.Canvas.canvas.height;if(null!=a.onScreenSizeChange)a.onScreenSizeChange(a,a.ScreenWidth,a.ScreenHeight,a.CanvasId);return!0};a.MuchTheSame=function(a,b){return 4>Math.abs(a-b)};a.Debug=function(a){console.log(a)};a.getIEVersion=function(){var a=-1;"Microsoft Internet Explorer"==navigator.appName&&null!=/MSIE ([0-9]{1,}[.0-9]{0,})/.exec(navigator.userAgent)&&(a=parseFloat(RegExp.$1));return a};a.haltEvent=function(a){a.preventDefault&&a.preventDefault();a.stopPropagation&&a.stopPropagation();return!1}; -return a},CreateKvmDataChannel=function(b,c,a){var d={};d.m=c;c.parent=d;d.webchannel=b;d.State=0;d.protocol=c.protocol;d.onStateChanged=null;d.onControlMsg=null;d.debugmode=0;d.keepalive=a;d.rtcKeepAlive=null;d.Start=function(){1==d.debugmode&&console.log("start");d.xxStateChange(3);d.webchannel.onmessage=d.xxOnMessage;d.rtcKeepAlive=setInterval(d.xxSendRtcKeepAlive,3E4)};var e=new FileReader,q=!1,k=[];e.readAsBinaryString?e.onload=function(a){d.xxOnSocketData(a.target.result);0==k.length?q=!1:e.readAsBinaryString(new Blob([k.shift()]))}: -e.readAsArrayBuffer&&(e.onloadend=function(a){d.xxOnSocketData(a.target.result);0==k.length?q=!1:e.readAsArrayBuffer(k.shift())});d.xxOnMessage=function(a){if("string"==typeof a.data){if(null!=d.onControlMsg)d.onControlMsg(a.data)}else if("object"==typeof a.data)if(1==q)k.push(a.data);else if(e.readAsBinaryString)q=!0,e.readAsBinaryString(new Blob([a.data]));else if(f.readAsArrayBuffer)q=!0,e.readAsArrayBuffer(a.data);else{var b="";a=new Uint8Array(a.data);for(var c=a.byteLength,h=0;hk.width&&(w=k.width);B>k.height-1&&(B=k.height-1);switch(b){case "\b":0k.height-1&&(q(1),B=k.height-1);break;case "\r":w=0;break;default:w>=k.width&&(w=0,m&&B++,B>=k.height-1&&(q(1),B=k.height-1)),a(b),w++}}}function a(a){J[B][w]=a;u[B][w]=(p<<6)+(h<<12)+n}function d(){for(var a= -h<<12,b=w;b=q){g[x]=g[x]?10*g[x]+(q-0):q-0;break}else if(";"==q){x++;break}else{g[0]||(g[0]=0);var v=g,y=x+1,A=void 0;switch(q){case "c":k.TermResetScreen();break;case "A":1==y&&(B-=v[0],0>B&&(B=0));break;case "B":1==y&&(B+=v[0],B>k.height&&(B=k.height));break;case "C":1==y&&(w+=v[0],w>k.width&&(w=k.width));break;case "D":1==y&&(w-=v[0],0>w&&(w=0));break;case "d":1==y&&(B=v[0]-1,B>k.height&&(B=k.height),0>B&&(B=0)); -break;case "G":1==y&&(w=v[0]-1,0>w&&(w=0),79v[0]&&(v[0]=1),1>v[1]&&(v[1]=1),v[0]>k.height&&(v[0]=k.height),v[1]>k.width&&(v[1]=k.width),B=v[0]-1,w=v[1]-1):w=B=0;break;case "m":for(A=0;Ap&&(p+=8):2==v[A]||22==v[A]?8<=p&&(p-=8):7==v[A]?n=2:27==v[A]?n=0:30<=v[A]&& -37>=v[A]?(q=8<=p,p=v[A]-30,q&&8>=p&&(p+=8)):40<=v[A]&&47>=v[A]?h=v[A]-40:90<=v[A]&&99>=v[A]?p=v[A]-82:100<=v[A]&&109>=v[A]&&(h=v[A]-92):(h=0,p=7,n=0);break;case "K":if(0!=y&&(1!=y||v[0]&&0!=v[0])){if(1==y)if(1==v[0])for(q=h<<12,v=0;v=a.which&&1==a.ctrlKey)k.TermSendKey(a.which-64),a.preventDefault&&a.preventDefault(),a.stopPropagation&&a.stopPropagation(); -else{if(27==a.which)return k.TermSendKeys(String.fromCharCode(27)),!0;if(37==a.which)return k.TermSendKeys(String.fromCharCode(27,91,68)),!0;if(38==a.which)return k.TermSendKeys(String.fromCharCode(27,91,65)),!0;if(39==a.which)return k.TermSendKeys(String.fromCharCode(27,91,67)),!0;if(40==a.which)return k.TermSendKeys(String.fromCharCode(27,91,66)),!0;if(9==a.which)return k.TermSendKeys("\t"),a.preventDefault&&a.preventDefault(),a.stopPropagation&&a.stopPropagation(),!0;var b=[80,81,119,120,116,117, -113,114,112,77],c=[49,50,51,52,53,54,55,56,57,48,33,64],d=[80,81,82,83,84,85,86,87,88,89,90,91];if(111a.which&&0==a.repeat){if(0==k.fxEmulation&&122>a.which)return k.TermSendKeys(String.fromCharCode(27,91,79,b[a.which-112])),!0;if(1==k.fxEmulation)return k.TermSendKeys(String.fromCharCode(27,c[a.which-112])),!0;if(2==k.fxEmulation)return k.TermSendKeys(String.fromCharCode(27,79,d[a.which-112])),!0}if(8!=a.which&&32!=a.which&&9!=a.which)return!0;k.TermSendKey(a.which);a.preventDefault&& -a.preventDefault();a.stopPropagation&&a.stopPropagation();return!1}};k.TermDraw=function(){for(var a,b="",c="",d=1,e,g=0;g>e&63],a&1&&(b+=";text-decoration:underline"),b+=';">',c=""+c,d=a),a=J[g][h],a){case "&":b+="&";break;case "<":b+="<";break;case ">":b+=">";break;case " ":b+=" ";break;default:b+= -a}g!=k.height-1&&(b+="
")}k.DivElement.innerHTML=""+b+c+""};k.TermInit=function(){k.TermResetScreen()};k.Init();return k},ZLIB=ZLIB||{}; +function script_compile(b,c){var a="",d=b.split("\n"),e={},g=[],l=[],u;for(u in d){var p=d[u];if(p.startsWith("##SWAP ")){var n=p.split(" ");3==n.length&&(l[n[1]]=n[2])}if("#"!=p[0]&&0!=p.length){for(n in l)p=p.split(n).join(l[n]);var w=p.match(/"[^"]*"|[^\s"]+/g);if(0!=w.length)if(":"==p[0])e[w[0].toUpperCase()]=a.length;else{p=script_functionTable1.indexOf(w[0].toLowerCase());-1==p&&(p=script_functionTable2.indexOf(w[0].toLowerCase()),0<=p&&(p+=1E4));-1==p&&(p=script_functionTable3.indexOf(w[0].toLowerCase()), +0<=p&&(p+=2E4));if(-1==p)return c&&c("Unabled to compile, unknown command: "+w[0]),"";var m=ShortToStr(w.length-1),v;for(v in w)if(0!=v)if(":"==w[v][0])g.push([w[v],a.length+m.length+7]),m+=ShortToStr(5)+String.fromCharCode(3)+IntToStr(4294967295);else var k=parseInt(w[v]),m=k==w[v]?m+(ShortToStr(5)+String.fromCharCode(2)+IntToStr(k)):'"'==w[v][0]&&'"'==w[v][w[v].length-1]?m+(ShortToStr(w[v].length-1)+String.fromCharCode(1)+w[v].substring(1,w[v].length-1)):m+(ShortToStr(w[v].length+1)+String.fromCharCode(0)+ +w[v]);m=ShortToStr(p)+ShortToStr(m.length+4)+m;a+=m}}}for(u in g){d=g[u][0].toUpperCase();l=g[u][1];n=e[d];if(void 0==n)return c&&c("Unabled to compile, unknown label: "+d),"";a=a.substr(0,l)+IntToStr(n)+a.substr(l+4)}return IntToStr(612182341)+ShortToStr(1)+a} +function script_decompile(b,c){var a="",d=6,e={};if(0<=c)d=c;else{if(6>b.length)return"# Invalid script length";var g=ReadInt(b,0),l=ReadShort(b,4);if(612182341!=g)return"# Invalid binary script: "+g;if(1!=l)return"# Invalid script version"}for(;dg?a+(script_functionTable1[g]+n+"\n"):2E4<=g?a+(script_functionTable3[g-2E4]+n+"\n"):a+(script_functionTable2[g-1E4]+n+"\n");d+=l;if(0<=c)return a}d=a.split("\n");a="";for(w in d)g=d[w],":"!=g[0]?a+=g+"\n":e[g]&&(a+=g+"\n");return a} +var CreateAmtRemoteDesktop=function(b,c){function a(a,b,c,h,m,v,D,z){var x=a.charCodeAt(b++);z={};var C=0,y=0;if(0==x){if(2==k.bpp)for(m=0;m>8&248)+","+(x>>3&252)+","+((x&31)<<3))+")",a=p(c,h),h=n(c,h),k.canvas.fillRect(a,h,m,v);else if(1 +x){v=4;y=15;if(2==k.bpp){for(m=0;m=x&&(v=2,y=3);for(;C>m&y],C++)}else{for(m=0;m=x&&(v=2,y=3);for(;C>m&y],C++)}d(k.spare,c,h)}else if(128==x){if(2==k.bpp)for(;C>8&248;k.spare.data[c+1]=a>>3&252;k.spare.data[c+2]=(a&31)<<3}function l(a,b,c){b<<=2;var d=a&224,e=(a&28)<<3;for(a=w((a&3)<<6);0<=--c;)k.spare.data[b]=d,k.spare.data[b+1]=e,k.spare.data[b+2]=a,b+=4}function u(a,b,c){b<<=2;var d=a>>8&248,e=a>>3&252;for(a=(a&31)<<3;0<=--c;)k.spare.data[b]=d,k.spare.data[b+1]=e,k.spare.data[b+2]=a,b+=4}function p(a,b){return 0==k.rotation||1==k.rotation?a:2==k.rotation?a-k.canvas.canvas.width:3==k.rotation? +a-k.canvas.canvas.height:0}function n(a,b){return 0==k.rotation?b:1==k.rotation?b-k.canvas.canvas.width:2==k.rotation?b-k.canvas.canvas.height:3==k.rotation?b:0}function w(a){return 127=c&&(d=c+32);112<=c&&124>=c&&(d=c+65358);8==c&&(d=65288);9==c&&(d=65289);13==c&&(d=65293);16==c&&(d=65505);17==c&&(d=65507);18==c&&(d=65513);27==c&&(d=65307);33==c&&(d=65365);34==c&&(d=65366);35==c&&(d=65367);36==c&&(d=65360);37==c&&(d=65361);38==c&&(d=65362);39==c&&(d=65363);40==c&&(d=65364);45==c&&(d=65379);46==c&&(d= +65535);96<=c&&105>=c&&(d=c-48);106==c&&(d=42);107==c&&(d=43);109==c&&(d=45);110==c&&(d=46);111==c&&(d=47);186==c&&(d=59);187==c&&(d=61);188==c&&(d=44);189==c&&(d=45);190==c&&(d=46);191==c&&(d=47);192==c&&(d=96);219==c&&(d=91);220==c&&(d=92);221==c&&(d=93);222==c&&(d=39);k.sendkey(d,a)}return k.haltEvent(b)}var k={};k.canvasid=b;k.scrolldiv=c;k.canvas=Q(b).getContext("2d");k.protocol=2;k.state=0;k.acc="";k.ScreenWidth=960;k.ScreenHeight=700;k.width=0;k.height=0;k.rwidth=0;k.rheight=0;k.bpp=2;k.useZRLE= +!0;k.showmouse=!0;k.buttonmask=0;k.spare=null;k.sparew=0;k.spareh=0;k.sparew2=0;k.spareh2=0;k.sparecache={};k.ZRLEfirst=1;k.onScreenSizeChange=null;k.frameRateDelay=0;k.noMouseRotate=!1;k.rotation=0;k.kvmDataSupported=!1;k.onKvmData=null;k.onKvmDataPending=[];k.onKvmDataAck=-1;k.holding=!1;k.lastKeepAlive=Date.now();k.inflate=ZLIB.inflateInit(-15);k.Debug=function(a){console.log(a)};k.xxStateChange=function(a){0==a?(k.canvas.fillStyle="#000000",k.canvas.fillRect(0,0,k.width,k.height),k.canvas.canvas.width= +k.rwidth=k.width=640,k.canvas.canvas.height=k.rheight=k.height=400,QS(k.canvasid).cursor="auto",k.inflate=ZLIB.inflateInit(-15)):k.showmouse||(QS(k.canvasid).cursor="none")};k.ProcessData=function(b){if(b)for(k.acc+=b;0k.acc.length)return;k.state=100+ReadShort(k.acc,2);c=4;break;case 2:c=1;break;case 3:if(8>k.acc.length)return;b=ReadInt(k.acc,4)+8;if(k.acc.lengthh.length)c=0;else if(b=ReadInt(k.acc,4)+8,h.lengthn){if(1>c||64l||64k.acc.length)break;u=ReadInt(k.acc,12);if(k.acc.length<16+u)break;n=16;5a;)a+=4;a%=4;if(1==k.holding)k.rotation=a;else{if(a==k.rotation)return!0;var b=k.canvas.canvas.width,c=k.canvas.canvas.height;if(1==k.rotation||3==k.rotation)b=k.canvas.canvas.height,c=k.canvas.canvas.width;null==k.tcanvas&&(k.tcanvas=document.createElement("canvas"));var d=k.tcanvas.getContext("2d");d.setTransform(1,0,0,1,0,0);d.canvas.width=b;d.canvas.height=c;d.rotate(-90*k.rotation*Math.PI/180);0==k.rotation&&d.drawImage(k.canvas.canvas,0,0);1==k.rotation&&d.drawImage(k.canvas.canvas, +-k.canvas.canvas.width,0);2==k.rotation&&d.drawImage(k.canvas.canvas,-k.canvas.canvas.width,-k.canvas.canvas.height);3==k.rotation&&d.drawImage(k.canvas.canvas,0,-k.canvas.canvas.height);if(0==k.rotation||2==k.rotation)k.canvas.canvas.height=b,k.canvas.canvas.width=c;if(1==k.rotation||3==k.rotation)k.canvas.canvas.height=c,k.canvas.canvas.width=b;k.canvas.setTransform(1,0,0,1,0,0);k.canvas.rotate(90*a*Math.PI/180);k.rotation=a;k.canvas.drawImage(k.tcanvas,p(0,0),n(0,0));k.width=k.canvas.canvas.width; +k.height=k.canvas.canvas.height;if(null!=k.onScreenResize)k.onScreenResize(k,k.width,k.height,k.CanvasId);return!0}};k.Start=function(){k.state=0;k.acc="";k.ZRLEfirst=1;k.inflate.inflateReset();k.onKvmDataPending=[];k.onKvmDataAck=-1;k.kvmDataSupported=!1;for(var a in k.sparecache)delete k.sparecache[a]};k.Stop=function(){k.UnGrabMouseInput();k.UnGrabKeyInput();k.parent.Stop()};k.Send=function(a){k.parent.Send(a)};var y={Pause:19,CapsLock:20,Space:32,Quote:39,Minus:45,NumpadMultiply:42,NumpadAdd:43, +PrintScreen:44,Comma:44,NumpadSubtract:45,NumpadDecimal:46,Period:46,Slash:47,NumpadDivide:47,Semicolon:59,Equal:61,OSLeft:91,BracketLeft:91,OSRight:91,Backslash:92,BracketRight:93,ContextMenu:93,Backquote:96,NumLock:144,ScrollLock:145,Backspace:65288,Tab:65289,Enter:65293,NumpadEnter:65293,Escape:65307,Delete:65535,Home:65360,PageUp:65365,PageDown:65366,ArrowLeft:65361,ArrowUp:65362,ArrowRight:65363,ArrowDown:65364,End:65367,Insert:65379,F1:65470,F2:65471,F3:65472,F4:65473,F5:65474,F6:65475,F7:65476, +F8:65477,F9:65478,F10:65479,F11:65480,F12:65481,ShiftLeft:65505,ShiftRight:65506,ControlLeft:65507,ControlRight:65508,AltLeft:65513,AltRight:65514,MetaLeft:65511,MetaRight:65512};k.sendkey=function(a,b){if("object"==typeof a)for(var c in a)k.sendkey(a[c][0],a[c][1]);else k.Send(String.fromCharCode(4,b,0,0)+IntToStr(a))};k.sendKvmData=function(a){!0!==k.onKvmDataAck?k.onKvmDataPending.push(a):(urlvars&&urlvars.kvmdatatrace&&console.log("KVM-Send("+a.length+"): "+a),a="\x00KvmDataChannel\x00"+a,k.Send(String.fromCharCode(6, +0,0,0)+IntToStr(a.length)+a),k.onKvmDataAck=!1)};k.sendKeepAlive=function(){k.lastKeepAliveb.length)){var c=null,d=0,u=0,p=ReadShort(b,0),n=ReadShort(b,2);n!=b.length&&1==a.debugmode&&console.log(n,b.length,n==b.length);if(18<=p)console.error("Invalid KVM command "+ +p+" of size "+n),console.log("Invalid KVM data",b.length,b,rstr2hex(b));else if(n>b.length)console.error("KVM invalid command size",n,b.length);else{if(3==p||4==p||7==p)c=b.substring(4,n),d=((c.charCodeAt(0)&255)<<8)+(c.charCodeAt(1)&255),u=((c.charCodeAt(2)&255)<<8)+(c.charCodeAt(3)&255);switch(p){case 3:if(a.FirstDraw)a.onResize();a.ProcessPictureMsg(c,d,u);break;case 4:if(a.FirstDraw)a.onResize();a.TilesDrawn==a.tilesReceived?a.ProcessCopyRectMsg(c):a.PendingOperations.push([++tilesReceived,1, +c]);break;case 7:a.ProcessScreenMsg(d,u);a.SendKeyMsgKC(a.KeyAction.UP,16);a.SendKeyMsgKC(a.KeyAction.UP,17);a.SendKeyMsgKC(a.KeyAction.UP,18);a.SendKeyMsgKC(a.KeyAction.UP,91);a.SendKeyMsgKC(a.KeyAction.UP,92);a.SendKeyMsgKC(a.KeyAction.UP,16);a.send(String.fromCharCode(0,14,0,4));break;case 11:c=[];d=((b.charCodeAt(4)&255)<<8)+(b.charCodeAt(5)&255);if(0>8, +b&255))};a.intToStr=function(a){return String.fromCharCode(a>>24&255,a>>16&255,a>>8&255,a&255)};a.shortToStr=function(a){return String.fromCharCode(a>>8&255,a&255)};a.onResize=function(){if(0!=a.ScreenWidth&&0!=a.ScreenHeight&&(a.Canvas.canvas.width!=a.ScreenWidth||a.Canvas.canvas.height!=a.ScreenHeight)){if(a.FirstDraw&&(a.Canvas.canvas.width=a.ScreenWidth,a.Canvas.canvas.height=a.ScreenHeight,a.Canvas.fillRect(0,0,a.ScreenWidth,a.ScreenHeight),null!=a.onScreenSizeChange))a.onScreenSizeChange(a, +a.ScreenWidth,a.ScreenHeight,a.CanvasId);a.FirstDraw=!1}};a.xxMouseInputGrab=!1;a.xxKeyInputGrab=!1;a.xxMouseMove=function(b){3==a.State&&a.SendMouseMsg(a.KeyAction.NONE,b);b.preventDefault&&b.preventDefault();b.stopPropagation&&b.stopPropagation();return!1};a.xxMouseUp=function(b){3==a.State&&a.SendMouseMsg(a.KeyAction.UP,b);b.preventDefault&&b.preventDefault();b.stopPropagation&&b.stopPropagation();return!1};a.xxMouseDown=function(b){3==a.State&&a.SendMouseMsg(a.KeyAction.DOWN,b);b.preventDefault&& +b.preventDefault();b.stopPropagation&&b.stopPropagation();return!1};a.xxDOMMouseScroll=function(b){return 3==a.State?(a.SendMouseMsg(a.KeyAction.SCROLL,b),!1):!0};a.xxMouseWheel=function(b){return 3==a.State?(a.SendMouseMsg(a.KeyAction.SCROLL,b),!1):!0};a.xxKeyUp=function(b){3==a.State&&a.SendKeyMsg(a.KeyAction.UP,b);b.preventDefault&&b.preventDefault();b.stopPropagation&&b.stopPropagation();return!1};a.xxKeyDown=function(b){3==a.State&&a.SendKeyMsg(a.KeyAction.DOWN,b);b.preventDefault&&b.preventDefault(); +b.stopPropagation&&b.stopPropagation();return!1};a.xxKeyPress=function(a){a.preventDefault&&a.preventDefault();a.stopPropagation&&a.stopPropagation();return!1};a.handleKeys=function(b){return 1==a.stopInput||3!=desktop.State?!1:a.xxKeyPress(b)};a.handleKeyUp=function(b){if(1==a.stopInput||3!=desktop.State)return!1;if(5>a.firstUpKeys.length&&(a.firstUpKeys.push(b.keyCode),5==a.firstUpKeys.length)){var c=a.firstUpKeys.join(",");if("16,17,91,91,16"==c||"16,17,18,91,92"==c)a.stopInput=!0}return a.xxKeyUp(b)}; +a.handleKeyDown=function(b){return 1==a.stopInput||3!=desktop.State?!1:a.xxKeyDown(b)};a.mousedown=function(b){return 1==a.stopInput?!1:a.xxMouseDown(b)};a.mouseup=function(b){return 1==a.stopInput?!1:a.xxMouseUp(b)};a.mousemove=function(b){return 1==a.stopInput?!1:a.xxMouseMove(b)};a.mousewheel=function(b){return 1==a.stopInput?!1:a.xxMouseWheel(b)};a.xxMsTouchEvent=function(b){if(4!=b.originalEvent.pointerType){b.preventDefault&&b.preventDefault();b.stopPropagation&&b.stopPropagation();if("MSPointerDown"== +b.type||"MSPointerMove"==b.type||"MSPointerUp"==b.type){var c=0,d=b.originalEvent.pointerId%256,u=Canvas.canvas.width/a.CanvasId.clientWidth*b.offsetX,p=Canvas.canvas.height/a.CanvasId.clientHeight*b.offsetY;"MSPointerDown"==b.type?c=65542:"MSPointerMove"==b.type?c=131078:"MSPointerUp"==b.type&&(c=262144);a.TouchArray[d]||(a.TouchArray[d]={x:u,y:p});a.SendTouchMsg2(d,c);"MSPointerUp"==b.type&&delete a.TouchArray[d]}else alert(b.type);return!0}};a.xxTouchStart=function(b){if(3==a.State)if(b.preventDefault&& +b.preventDefault(),0==a.touchenabled||1==a.touchenabled){if(!(1b;)b+=4;b%=4;if(b==a.rotation)return!0;var c=a.Canvas.canvas.width,d=a.Canvas.canvas.height;if(1==a.rotation||3==a.rotation)c=a.Canvas.canvas.height,d=a.Canvas.canvas.width;null==a.tcanvas&&(a.tcanvas=document.createElement("canvas"));var u=a.tcanvas.getContext("2d"); +u.setTransform(1,0,0,1,0,0);u.canvas.width=c;u.canvas.height=d;u.rotate(-90*a.rotation*Math.PI/180);0==a.rotation&&u.drawImage(a.Canvas.canvas,0,0);1==a.rotation&&u.drawImage(a.Canvas.canvas,-a.Canvas.canvas.width,0);2==a.rotation&&u.drawImage(a.Canvas.canvas,-a.Canvas.canvas.width,-a.Canvas.canvas.height);3==a.rotation&&u.drawImage(a.Canvas.canvas,0,-a.Canvas.canvas.height);if(0==a.rotation||2==a.rotation)a.Canvas.canvas.height=c,a.Canvas.canvas.width=d;if(1==a.rotation||3==a.rotation)a.Canvas.canvas.height= +d,a.Canvas.canvas.width=c;a.Canvas.setTransform(1,0,0,1,0,0);a.Canvas.rotate(90*b*Math.PI/180);a.rotation=b;a.Canvas.drawImage(a.tcanvas,a.rotX(0,0),a.rotY(0,0));a.ScreenWidth=a.Canvas.canvas.width;a.ScreenHeight=a.Canvas.canvas.height;if(null!=a.onScreenSizeChange)a.onScreenSizeChange(a,a.ScreenWidth,a.ScreenHeight,a.CanvasId);return!0};a.MuchTheSame=function(a,b){return 4>Math.abs(a-b)};a.Debug=function(a){console.log(a)};a.getIEVersion=function(){var a=-1;"Microsoft Internet Explorer"==navigator.appName&& +null!=/MSIE ([0-9]{1,}[.0-9]{0,})/.exec(navigator.userAgent)&&(a=parseFloat(RegExp.$1));return a};a.haltEvent=function(a){a.preventDefault&&a.preventDefault();a.stopPropagation&&a.stopPropagation();return!1};return a},CreateKvmDataChannel=function(b,c,a){var d={};d.m=c;c.parent=d;d.webchannel=b;d.State=0;d.protocol=c.protocol;d.onStateChanged=null;d.onControlMsg=null;d.debugmode=0;d.keepalive=a;d.rtcKeepAlive=null;d.Start=function(){1==d.debugmode&&console.log("start");d.xxStateChange(3);d.webchannel.onmessage= +d.xxOnMessage;d.rtcKeepAlive=setInterval(d.xxSendRtcKeepAlive,3E4)};var e=new FileReader,g=!1,l=[];e.readAsBinaryString?e.onload=function(a){d.xxOnSocketData(a.target.result);0==l.length?g=!1:e.readAsBinaryString(new Blob([l.shift()]))}:e.readAsArrayBuffer&&(e.onloadend=function(a){d.xxOnSocketData(a.target.result);0==l.length?g=!1:e.readAsArrayBuffer(l.shift())});d.xxOnMessage=function(a){if("string"==typeof a.data){if(null!=d.onControlMsg)d.onControlMsg(a.data)}else if("object"==typeof a.data)if(1== +g)l.push(a.data);else if(e.readAsBinaryString)g=!0,e.readAsBinaryString(new Blob([a.data]));else if(f.readAsArrayBuffer)g=!0,e.readAsArrayBuffer(a.data);else{var b="";a=new Uint8Array(a.data);for(var c=a.byteLength,w=0;wl.width&&(v=l.width);k>l.height-1&&(k=l.height-1);switch(b){case "\b":0l.height-1&&(g(1),k=l.height-1);break;case "\r":v=0;break;default:v>=l.width&&(v=0,m&&k++,k>=l.height-1&&(g(1),k=l.height-1)),a(b),v++}}}function a(a){E[k][v]=a;r[k][v]=(n<<6)+(w<<12)+p}function d(){for(var a=w<<12,b=v;b=g){h[K]=h[K]?10*h[K]+(g-0):g-0;break}else if(";"==g){K++;break}else{h[0]|| +(h[0]=0);var u=h,B=K+1,A=void 0;switch(g){case "c":l.TermResetScreen();break;case "A":1==B&&(k-=u[0],0>k&&(k=0));break;case "B":1==B&&(k+=u[0],k>l.height&&(k=l.height));break;case "C":1==B&&(v+=u[0],v>l.width&&(v=l.width));break;case "D":1==B&&(v-=u[0],0>v&&(v=0));break;case "d":1==B&&(k=u[0]-1,k>l.height&&(k=l.height),0>k&&(k=0));break;case "G":1==B&&(v=u[0]-1,0>v&&(v=0),79u[0]&&(u[0]=1),1>u[1]&&(u[1]=1),u[0]>l.height&&(u[0]=l.height),u[1]>l.width&&(u[1]=l.width),k=u[0]-1,v=u[1]-1):v=k=0;break;case "m":for(A=0;An&&(n+=8):2==u[A]||22==u[A]?8<=n&&(n-=8):7==u[A]?p=2:27==u[A]?p=0:30<=u[A]&&37>=u[A]?(g=8<=n,n=u[A]-30,g&&8>=n&&(n+=8)):40<=u[A]&&47>=u[A]?w=u[A]-40:90<=u[A]&&99>=u[A]?n=u[A]-82:100<=u[A]&&109>=u[A]&&(w=u[A]-92):(w=0,n=7,p=0);break;case "K":if(0!=B&&(1!=B|| +u[0]&&0!=u[0])){if(1==B)if(1==u[0])for(g=w<<12,u=0;u=a.which&&1==a.ctrlKey)l.TermSendKey(a.which-64),a.preventDefault&&a.preventDefault(),a.stopPropagation&&a.stopPropagation();else{if(27==a.which)return l.TermSendKeys(String.fromCharCode(27)),!0;if(37==a.which)return l.TermSendKeys(String.fromCharCode(27,91,68)),!0;if(38==a.which)return l.TermSendKeys(String.fromCharCode(27, +91,65)),!0;if(39==a.which)return l.TermSendKeys(String.fromCharCode(27,91,67)),!0;if(40==a.which)return l.TermSendKeys(String.fromCharCode(27,91,66)),!0;if(9==a.which)return l.TermSendKeys("\t"),a.preventDefault&&a.preventDefault(),a.stopPropagation&&a.stopPropagation(),!0;var b=[80,81,119,120,116,117,113,114,112,77],c=[49,50,51,52,53,54,55,56,57,48,33,64],d=[80,81,82,83,84,85,86,87,88,89,90,91];if(111a.which&&0==a.repeat){if(0==l.fxEmulation&&122>a.which)return l.TermSendKeys(String.fromCharCode(27, +91,79,b[a.which-112])),!0;if(1==l.fxEmulation)return l.TermSendKeys(String.fromCharCode(27,c[a.which-112])),!0;if(2==l.fxEmulation)return l.TermSendKeys(String.fromCharCode(27,79,d[a.which-112])),!0}if(8!=a.which&&32!=a.which&&9!=a.which)return!0;l.TermSendKey(a.which);a.preventDefault&&a.preventDefault();a.stopPropagation&&a.stopPropagation();return!1}};l.TermDraw=function(){for(var a,b="",c="",d=1,e,g=0;g>e&63],a&1&&(b+=";text-decoration:underline"),b+=';">',c=""+c,d=a),a=E[g][h],a){case "&":b+="&";break;case "<":b+="<";break;case ">":b+=">";break;case " ":b+=" ";break;default:b+=a}g!=l.height-1&&(b+="
")}l.DivElement.innerHTML=""+b+c+""};l.TermInit=function(){l.TermResetScreen()};l.Init();return l},ZLIB=ZLIB||{}; "undefined"===typeof ZLIB.common_initialized&&(ZLIB.Z_NO_FLUSH=0,ZLIB.Z_PARTIAL_FLUSH=1,ZLIB.Z_SYNC_FLUSH=2,ZLIB.Z_FULL_FLUSH=3,ZLIB.Z_FINISH=4,ZLIB.Z_BLOCK=5,ZLIB.Z_TREES=6,ZLIB.Z_OK=0,ZLIB.Z_STREAM_END=1,ZLIB.Z_NEED_DICT=2,ZLIB.Z_ERRNO=-1,ZLIB.Z_STREAM_ERROR=-2,ZLIB.Z_DATA_ERROR=-3,ZLIB.Z_MEM_ERROR=-4,ZLIB.Z_BUF_ERROR=-5,ZLIB.Z_VERSION_ERROR=-6,ZLIB.Z_DEFLATED=8,ZLIB.z_stream=function(){this.total_out=this.avail_out=this.next_out=this.total_in=this.avail_in=this.next_in=0;this.state=this.msg=null; this.adler=this.data_type=0;this.output_data=this.input_data="";this.error=0;this.checksum_function=null},ZLIB.gz_header=function(){this.xflags=this.time=this.text=0;this.os=255;this.extra=null;this.extra_max=this.extra_len=0;this.name=null;this.name_max=0;this.comment=null;this.done=this.hcrc=this.comm_max=0},ZLIB.common_initialized=!0);"undefined"===typeof ZLIB&&alert("ZLIB is not defined. SRC zlib.js before zlib-inflate.js"); -(function(){function b(a,b){var c=a.next,d=2==b?a.distbits:a.lenbits,e=a.work,g=a.lens,h=2==b?a.nlen:0,k=a.codes,l;l=1==b?a.nlen:2==b?a.ndist:19;var m,n,p,q,v,w,B,y,E,H,G,I,Y,da,fa,ga,ha,P,K=Array(16);v=Array(16);for(m=0;15>=m;m++)K[m]=0;for(n=0;np&&(q=p);if(0==p)return I={op:64,bits:1,val:0},k[c++]=I,k[c++]=I,2==b?a.distbits=1:a.lenbits=1,a.next=c,0;for(d=1;d=m;m++)if(w<<=1,w-=K[m],0>w)return-1;if(0m;m++)v[m+1]=v[m]+K[m];for(n=0;nP?(I.op=ga[ha+e[n]],I.val=da[fa+e[n]]):I.op=96;w=1<>>v)+E]=I;while(0!=E);for(w=1<>>= -1;0!=w?(y&=w-1,y+=w):y=0;n++;if(0==--K[m]){if(m==p)break;m=g[h+e[n]]}if(m>q&&(y&G)!=H){0==v&&(v=q);Y+=d;l=m-v;for(w=1<=w)break;l++;w<<=1}B+=1<a;a++)this.codes[a]=b;this.was=this.back=this.sane=0}function q(a){var b;y||(y=eval("([ {op:96,bits:7,val:0},{op:0,bits:8,val:80},{op:0,bits:8,val:16},{op:20,bits:8,val:115},{op:18,bits:7,val:31},{op:0,bits:8,val:112},{op:0,bits:8,val:48}, {op:0,bits:9,val:192},{op:16,bits:7,val:10},{op:0,bits:8,val:96},{op:0,bits:8,val:32},{op:0,bits:9,val:160},{op:0,bits:8,val:0},{op:0,bits:8,val:128}, {op:0,bits:8,val:64},{op:0,bits:9,val:224},{op:16,bits:7,val:6},{op:0,bits:8,val:88},{op:0,bits:8,val:24},{op:0,bits:9,val:144},{op:19,bits:7,val:59}, {op:0,bits:8,val:120},{op:0,bits:8,val:56},{op:0,bits:9,val:208},{op:17,bits:7,val:17},{op:0,bits:8,val:104},{op:0,bits:8,val:40},{op:0,bits:9,val:176}, {op:0,bits:8,val:8},{op:0,bits:8,val:136},{op:0,bits:8,val:72},{op:0,bits:9,val:240},{op:16,bits:7,val:4},{op:0,bits:8,val:84},{op:0,bits:8,val:20}, {op:21,bits:8,val:227},{op:19,bits:7,val:43},{op:0,bits:8,val:116},{op:0,bits:8,val:52},{op:0,bits:9,val:200},{op:17,bits:7,val:13},{op:0,bits:8,val:100}, {op:0,bits:8,val:36},{op:0,bits:9,val:168},{op:0,bits:8,val:4},{op:0,bits:8,val:132},{op:0,bits:8,val:68},{op:0,bits:9,val:232},{op:16,bits:7,val:8}, {op:0,bits:8,val:92},{op:0,bits:8,val:28},{op:0,bits:9,val:152},{op:20,bits:7,val:83},{op:0,bits:8,val:124},{op:0,bits:8,val:60},{op:0,bits:9,val:216}, {op:18,bits:7,val:23},{op:0,bits:8,val:108},{op:0,bits:8,val:44},{op:0,bits:9,val:184},{op:0,bits:8,val:12},{op:0,bits:8,val:140},{op:0,bits:8,val:76}, {op:0,bits:9,val:248},{op:16,bits:7,val:3},{op:0,bits:8,val:82},{op:0,bits:8,val:18},{op:21,bits:8,val:163},{op:19,bits:7,val:35},{op:0,bits:8,val:114}, {op:0,bits:8,val:50},{op:0,bits:9,val:196},{op:17,bits:7,val:11},{op:0,bits:8,val:98},{op:0,bits:8,val:34},{op:0,bits:9,val:164},{op:0,bits:8,val:2}, {op:0,bits:8,val:130},{op:0,bits:8,val:66},{op:0,bits:9,val:228},{op:16,bits:7,val:7},{op:0,bits:8,val:90},{op:0,bits:8,val:26},{op:0,bits:9,val:148}, {op:20,bits:7,val:67},{op:0,bits:8,val:122},{op:0,bits:8,val:58},{op:0,bits:9,val:212},{op:18,bits:7,val:19},{op:0,bits:8,val:106},{op:0,bits:8,val:42}, {op:0,bits:9,val:180},{op:0,bits:8,val:10},{op:0,bits:8,val:138},{op:0,bits:8,val:74},{op:0,bits:9,val:244},{op:16,bits:7,val:5},{op:0,bits:8,val:86}, {op:0,bits:8,val:22},{op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:118},{op:0,bits:8,val:54},{op:0,bits:9,val:204},{op:17,bits:7,val:15}, {op:0,bits:8,val:102},{op:0,bits:8,val:38},{op:0,bits:9,val:172},{op:0,bits:8,val:6},{op:0,bits:8,val:134},{op:0,bits:8,val:70},{op:0,bits:9,val:236}, {op:16,bits:7,val:9},{op:0,bits:8,val:94},{op:0,bits:8,val:30},{op:0,bits:9,val:156},{op:20,bits:7,val:99},{op:0,bits:8,val:126},{op:0,bits:8,val:62}, {op:0,bits:9,val:220},{op:18,bits:7,val:27},{op:0,bits:8,val:110},{op:0,bits:8,val:46},{op:0,bits:9,val:188},{op:0,bits:8,val:14},{op:0,bits:8,val:142}, {op:0,bits:8,val:78},{op:0,bits:9,val:252},{op:96,bits:7,val:0},{op:0,bits:8,val:81},{op:0,bits:8,val:17},{op:21,bits:8,val:131},{op:18,bits:7,val:31}, {op:0,bits:8,val:113},{op:0,bits:8,val:49},{op:0,bits:9,val:194},{op:16,bits:7,val:10},{op:0,bits:8,val:97},{op:0,bits:8,val:33},{op:0,bits:9,val:162}, {op:0,bits:8,val:1},{op:0,bits:8,val:129},{op:0,bits:8,val:65},{op:0,bits:9,val:226},{op:16,bits:7,val:6},{op:0,bits:8,val:89},{op:0,bits:8,val:25}, {op:0,bits:9,val:146},{op:19,bits:7,val:59},{op:0,bits:8,val:121},{op:0,bits:8,val:57},{op:0,bits:9,val:210},{op:17,bits:7,val:17},{op:0,bits:8,val:105}, {op:0,bits:8,val:41},{op:0,bits:9,val:178},{op:0,bits:8,val:9},{op:0,bits:8,val:137},{op:0,bits:8,val:73},{op:0,bits:9,val:242},{op:16,bits:7,val:4}, {op:0,bits:8,val:85},{op:0,bits:8,val:21},{op:16,bits:8,val:258},{op:19,bits:7,val:43},{op:0,bits:8,val:117},{op:0,bits:8,val:53},{op:0,bits:9,val:202}, {op:17,bits:7,val:13},{op:0,bits:8,val:101},{op:0,bits:8,val:37},{op:0,bits:9,val:170},{op:0,bits:8,val:5},{op:0,bits:8,val:133},{op:0,bits:8,val:69}, {op:0,bits:9,val:234},{op:16,bits:7,val:8},{op:0,bits:8,val:93},{op:0,bits:8,val:29},{op:0,bits:9,val:154},{op:20,bits:7,val:83},{op:0,bits:8,val:125}, {op:0,bits:8,val:61},{op:0,bits:9,val:218},{op:18,bits:7,val:23},{op:0,bits:8,val:109},{op:0,bits:8,val:45},{op:0,bits:9,val:186},{op:0,bits:8,val:13}, {op:0,bits:8,val:141},{op:0,bits:8,val:77},{op:0,bits:9,val:250},{op:16,bits:7,val:3},{op:0,bits:8,val:83},{op:0,bits:8,val:19},{op:21,bits:8,val:195}, {op:19,bits:7,val:35},{op:0,bits:8,val:115},{op:0,bits:8,val:51},{op:0,bits:9,val:198},{op:17,bits:7,val:11},{op:0,bits:8,val:99},{op:0,bits:8,val:35}, {op:0,bits:9,val:166},{op:0,bits:8,val:3},{op:0,bits:8,val:131},{op:0,bits:8,val:67},{op:0,bits:9,val:230},{op:16,bits:7,val:7},{op:0,bits:8,val:91}, {op:0,bits:8,val:27},{op:0,bits:9,val:150},{op:20,bits:7,val:67},{op:0,bits:8,val:123},{op:0,bits:8,val:59},{op:0,bits:9,val:214},{op:18,bits:7,val:19}, {op:0,bits:8,val:107},{op:0,bits:8,val:43},{op:0,bits:9,val:182},{op:0,bits:8,val:11},{op:0,bits:8,val:139},{op:0,bits:8,val:75},{op:0,bits:9,val:246}, {op:16,bits:7,val:5},{op:0,bits:8,val:87},{op:0,bits:8,val:23},{op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:119},{op:0,bits:8,val:55}, {op:0,bits:9,val:206},{op:17,bits:7,val:15},{op:0,bits:8,val:103},{op:0,bits:8,val:39},{op:0,bits:9,val:174},{op:0,bits:8,val:7},{op:0,bits:8,val:135}, {op:0,bits:8,val:71},{op:0,bits:9,val:238},{op:16,bits:7,val:9},{op:0,bits:8,val:95},{op:0,bits:8,val:31},{op:0,bits:9,val:158},{op:20,bits:7,val:99}, {op:0,bits:8,val:127},{op:0,bits:8,val:63},{op:0,bits:9,val:222},{op:18,bits:7,val:27},{op:0,bits:8,val:111},{op:0,bits:8,val:47},{op:0,bits:9,val:190}, {op:0,bits:8,val:15},{op:0,bits:8,val:143},{op:0,bits:8,val:79},{op:0,bits:9,val:254},{op:96,bits:7,val:0},{op:0,bits:8,val:80},{op:0,bits:8,val:16}, {op:20,bits:8,val:115},{op:18,bits:7,val:31},{op:0,bits:8,val:112},{op:0,bits:8,val:48},{op:0,bits:9,val:193},{op:16,bits:7,val:10},{op:0,bits:8,val:96}, {op:0,bits:8,val:32},{op:0,bits:9,val:161},{op:0,bits:8,val:0},{op:0,bits:8,val:128},{op:0,bits:8,val:64},{op:0,bits:9,val:225},{op:16,bits:7,val:6}, {op:0,bits:8,val:88},{op:0,bits:8,val:24},{op:0,bits:9,val:145},{op:19,bits:7,val:59},{op:0,bits:8,val:120},{op:0,bits:8,val:56},{op:0,bits:9,val:209}, {op:17,bits:7,val:17},{op:0,bits:8,val:104},{op:0,bits:8,val:40},{op:0,bits:9,val:177},{op:0,bits:8,val:8},{op:0,bits:8,val:136},{op:0,bits:8,val:72}, {op:0,bits:9,val:241},{op:16,bits:7,val:4},{op:0,bits:8,val:84},{op:0,bits:8,val:20},{op:21,bits:8,val:227},{op:19,bits:7,val:43},{op:0,bits:8,val:116}, {op:0,bits:8,val:52},{op:0,bits:9,val:201},{op:17,bits:7,val:13},{op:0,bits:8,val:100},{op:0,bits:8,val:36},{op:0,bits:9,val:169},{op:0,bits:8,val:4}, {op:0,bits:8,val:132},{op:0,bits:8,val:68},{op:0,bits:9,val:233},{op:16,bits:7,val:8},{op:0,bits:8,val:92},{op:0,bits:8,val:28},{op:0,bits:9,val:153}, {op:20,bits:7,val:83},{op:0,bits:8,val:124},{op:0,bits:8,val:60},{op:0,bits:9,val:217},{op:18,bits:7,val:23},{op:0,bits:8,val:108},{op:0,bits:8,val:44}, {op:0,bits:9,val:185},{op:0,bits:8,val:12},{op:0,bits:8,val:140},{op:0,bits:8,val:76},{op:0,bits:9,val:249},{op:16,bits:7,val:3},{op:0,bits:8,val:82}, {op:0,bits:8,val:18},{op:21,bits:8,val:163},{op:19,bits:7,val:35},{op:0,bits:8,val:114},{op:0,bits:8,val:50},{op:0,bits:9,val:197},{op:17,bits:7,val:11}, {op:0,bits:8,val:98},{op:0,bits:8,val:34},{op:0,bits:9,val:165},{op:0,bits:8,val:2},{op:0,bits:8,val:130},{op:0,bits:8,val:66},{op:0,bits:9,val:229}, {op:16,bits:7,val:7},{op:0,bits:8,val:90},{op:0,bits:8,val:26},{op:0,bits:9,val:149},{op:20,bits:7,val:67},{op:0,bits:8,val:122},{op:0,bits:8,val:58}, {op:0,bits:9,val:213},{op:18,bits:7,val:19},{op:0,bits:8,val:106},{op:0,bits:8,val:42},{op:0,bits:9,val:181},{op:0,bits:8,val:10},{op:0,bits:8,val:138}, {op:0,bits:8,val:74},{op:0,bits:9,val:245},{op:16,bits:7,val:5},{op:0,bits:8,val:86},{op:0,bits:8,val:22},{op:64,bits:8,val:0},{op:19,bits:7,val:51}, {op:0,bits:8,val:118},{op:0,bits:8,val:54},{op:0,bits:9,val:205},{op:17,bits:7,val:15},{op:0,bits:8,val:102},{op:0,bits:8,val:38},{op:0,bits:9,val:173}, {op:0,bits:8,val:6},{op:0,bits:8,val:134},{op:0,bits:8,val:70},{op:0,bits:9,val:237},{op:16,bits:7,val:9},{op:0,bits:8,val:94},{op:0,bits:8,val:30}, {op:0,bits:9,val:157},{op:20,bits:7,val:99},{op:0,bits:8,val:126},{op:0,bits:8,val:62},{op:0,bits:9,val:221},{op:18,bits:7,val:27},{op:0,bits:8,val:110}, {op:0,bits:8,val:46},{op:0,bits:9,val:189},{op:0,bits:8,val:14},{op:0,bits:8,val:142},{op:0,bits:8,val:78},{op:0,bits:9,val:253},{op:96,bits:7,val:0}, {op:0,bits:8,val:81},{op:0,bits:8,val:17},{op:21,bits:8,val:131},{op:18,bits:7,val:31},{op:0,bits:8,val:113},{op:0,bits:8,val:49},{op:0,bits:9,val:195}, {op:16,bits:7,val:10},{op:0,bits:8,val:97},{op:0,bits:8,val:33},{op:0,bits:9,val:163},{op:0,bits:8,val:1},{op:0,bits:8,val:129},{op:0,bits:8,val:65}, {op:0,bits:9,val:227},{op:16,bits:7,val:6},{op:0,bits:8,val:89},{op:0,bits:8,val:25},{op:0,bits:9,val:147},{op:19,bits:7,val:59},{op:0,bits:8,val:121}, {op:0,bits:8,val:57},{op:0,bits:9,val:211},{op:17,bits:7,val:17},{op:0,bits:8,val:105},{op:0,bits:8,val:41},{op:0,bits:9,val:179},{op:0,bits:8,val:9}, {op:0,bits:8,val:137},{op:0,bits:8,val:73},{op:0,bits:9,val:243},{op:16,bits:7,val:4},{op:0,bits:8,val:85},{op:0,bits:8,val:21},{op:16,bits:8,val:258}, {op:19,bits:7,val:43},{op:0,bits:8,val:117},{op:0,bits:8,val:53},{op:0,bits:9,val:203},{op:17,bits:7,val:13},{op:0,bits:8,val:101},{op:0,bits:8,val:37}, {op:0,bits:9,val:171},{op:0,bits:8,val:5},{op:0,bits:8,val:133},{op:0,bits:8,val:69},{op:0,bits:9,val:235},{op:16,bits:7,val:8},{op:0,bits:8,val:93}, {op:0,bits:8,val:29},{op:0,bits:9,val:155},{op:20,bits:7,val:83},{op:0,bits:8,val:125},{op:0,bits:8,val:61},{op:0,bits:9,val:219},{op:18,bits:7,val:23}, {op:0,bits:8,val:109},{op:0,bits:8,val:45},{op:0,bits:9,val:187},{op:0,bits:8,val:13},{op:0,bits:8,val:141},{op:0,bits:8,val:77},{op:0,bits:9,val:251}, {op:16,bits:7,val:3},{op:0,bits:8,val:83},{op:0,bits:8,val:19},{op:21,bits:8,val:195},{op:19,bits:7,val:35},{op:0,bits:8,val:115},{op:0,bits:8,val:51}, {op:0,bits:9,val:199},{op:17,bits:7,val:11},{op:0,bits:8,val:99},{op:0,bits:8,val:35},{op:0,bits:9,val:167},{op:0,bits:8,val:3},{op:0,bits:8,val:131}, {op:0,bits:8,val:67},{op:0,bits:9,val:231},{op:16,bits:7,val:7},{op:0,bits:8,val:91},{op:0,bits:8,val:27},{op:0,bits:9,val:151},{op:20,bits:7,val:67}, {op:0,bits:8,val:123},{op:0,bits:8,val:59},{op:0,bits:9,val:215},{op:18,bits:7,val:19},{op:0,bits:8,val:107},{op:0,bits:8,val:43},{op:0,bits:9,val:183}, {op:0,bits:8,val:11},{op:0,bits:8,val:139},{op:0,bits:8,val:75},{op:0,bits:9,val:247},{op:16,bits:7,val:5},{op:0,bits:8,val:87},{op:0,bits:8,val:23}, {op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:119},{op:0,bits:8,val:55},{op:0,bits:9,val:207},{op:17,bits:7,val:15},{op:0,bits:8,val:103}, {op:0,bits:8,val:39},{op:0,bits:9,val:175},{op:0,bits:8,val:7},{op:0,bits:8,val:135},{op:0,bits:8,val:71},{op:0,bits:9,val:239},{op:16,bits:7,val:9}, {op:0,bits:8,val:95},{op:0,bits:8,val:31},{op:0,bits:9,val:159},{op:20,bits:7,val:99},{op:0,bits:8,val:127},{op:0,bits:8,val:63},{op:0,bits:9,val:223}, {op:18,bits:7,val:27},{op:0,bits:8,val:111},{op:0,bits:8,val:47},{op:0,bits:9,val:191},{op:0,bits:8,val:15},{op:0,bits:8,val:143},{op:0,bits:8,val:79}, {op:0,bits:9,val:255}])")); -H||(H=eval("([ {op:16,bits:5,val:1},{op:23,bits:5,val:257},{op:19,bits:5,val:17},{op:27,bits:5,val:4097},{op:17,bits:5,val:5},{op:25,bits:5,val:1025}, {op:21,bits:5,val:65},{op:29,bits:5,val:16385},{op:16,bits:5,val:3},{op:24,bits:5,val:513},{op:20,bits:5,val:33},{op:28,bits:5,val:8193}, {op:18,bits:5,val:9},{op:26,bits:5,val:2049},{op:22,bits:5,val:129},{op:64,bits:5,val:0},{op:16,bits:5,val:2},{op:23,bits:5,val:385}, {op:19,bits:5,val:25},{op:27,bits:5,val:6145},{op:17,bits:5,val:7},{op:25,bits:5,val:1537},{op:21,bits:5,val:97},{op:29,bits:5,val:24577}, {op:16,bits:5,val:4},{op:24,bits:5,val:769},{op:20,bits:5,val:49},{op:28,bits:5,val:12289},{op:18,bits:5,val:13},{op:26,bits:5,val:3073}, {op:22,bits:5,val:193},{op:64,bits:5,val:0}])")); -a.lencode=0;a.distcode=512;for(b=0;512>b;b++)a.codes[b]=y[b];for(b=0;32>b;b++)a.codes[b+512]=H[b];a.lenbits=9;a.distbits=5}function k(a,b){a.state.check=a.checksum_function(a.state.check,[b&255,b>>>8&255],0,2)}function v(a,b){b.strm=a;b.left=a.avail_out;b.next=a.next_in;b.have=a.avail_in;b.hold=a.state.hold;b.bits=a.state.bits;return b}function n(a){var b=a.strm;b.next_in=a.next;b.avail_out=a.left;b.avail_in=a.have;b.state.hold=a.hold;b.state.bits=a.bits}function p(a){a.hold=0;a.bits=0}function h(a){if(0== -a.have)return!1;a.have--;a.hold+=(a.strm.input_data.charCodeAt(a.next++)&255)<>>=b;a.bits-=b}function l(a){a.hold>>>=a.bits&7;a.bits-=a.bits&7}function g(a){return(a>>>24&255)+(a>>>8&65280)+((a&65280)<<8)+((a&255)<<24)}var x=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],u=[16,16,16,16,16,16,16,16,17,17,17,17, -18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,203,69],J=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],A=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];ZLIB.inflate_copyright=" inflate 1.2.6 Copyright 1995-2012 Mark Adler ";ZLIB.inflateResetKeep=function(a){var b;if(!a||!a.state)return ZLIB.Z_STREAM_ERROR;b=a.state;a.total_in=a.total_out=b.total=0;a.msg=null;b.wrap&&(a.adler= +(function(){function b(a,b){var c=a.next,d=2==b?a.distbits:a.lenbits,e=a.work,g=a.lens,h=2==b?a.nlen:0,k=a.codes,l;l=1==b?a.nlen:2==b?a.ndist:19;var m,n,p,u,v,w,y,B,F,L,G,H,I,da,fa,ga,ha,P,J=Array(16);v=Array(16);for(m=0;15>=m;m++)J[m]=0;for(n=0;np&&(u=p);if(0==p)return H={op:64,bits:1,val:0},k[c++]=H,k[c++]=H,2==b?a.distbits=1:a.lenbits=1,a.next=c,0;for(d=1;d=m;m++)if(w<<=1,w-=J[m],0>w)return-1;if(0m;m++)v[m+1]=v[m]+J[m];for(n=0;nP?(H.op=ga[ha+e[n]],H.val=da[fa+e[n]]):H.op=96;w=1<>>v)+F]=H;while(0!=F);for(w=1<>>= +1;0!=w?(B&=w-1,B+=w):B=0;n++;if(0==--J[m]){if(m==p)break;m=g[h+e[n]]}if(m>u&&(B&G)!=L){0==v&&(v=u);I+=d;l=m-v;for(w=1<=w)break;l++;w<<=1}y+=1<a;a++)this.codes[a]=b;this.was=this.back=this.sane=0}function g(a){var b;B||(B=eval("([ {op:96,bits:7,val:0},{op:0,bits:8,val:80},{op:0,bits:8,val:16},{op:20,bits:8,val:115},{op:18,bits:7,val:31},{op:0,bits:8,val:112},{op:0,bits:8,val:48}, {op:0,bits:9,val:192},{op:16,bits:7,val:10},{op:0,bits:8,val:96},{op:0,bits:8,val:32},{op:0,bits:9,val:160},{op:0,bits:8,val:0},{op:0,bits:8,val:128}, {op:0,bits:8,val:64},{op:0,bits:9,val:224},{op:16,bits:7,val:6},{op:0,bits:8,val:88},{op:0,bits:8,val:24},{op:0,bits:9,val:144},{op:19,bits:7,val:59}, {op:0,bits:8,val:120},{op:0,bits:8,val:56},{op:0,bits:9,val:208},{op:17,bits:7,val:17},{op:0,bits:8,val:104},{op:0,bits:8,val:40},{op:0,bits:9,val:176}, {op:0,bits:8,val:8},{op:0,bits:8,val:136},{op:0,bits:8,val:72},{op:0,bits:9,val:240},{op:16,bits:7,val:4},{op:0,bits:8,val:84},{op:0,bits:8,val:20}, {op:21,bits:8,val:227},{op:19,bits:7,val:43},{op:0,bits:8,val:116},{op:0,bits:8,val:52},{op:0,bits:9,val:200},{op:17,bits:7,val:13},{op:0,bits:8,val:100}, {op:0,bits:8,val:36},{op:0,bits:9,val:168},{op:0,bits:8,val:4},{op:0,bits:8,val:132},{op:0,bits:8,val:68},{op:0,bits:9,val:232},{op:16,bits:7,val:8}, {op:0,bits:8,val:92},{op:0,bits:8,val:28},{op:0,bits:9,val:152},{op:20,bits:7,val:83},{op:0,bits:8,val:124},{op:0,bits:8,val:60},{op:0,bits:9,val:216}, {op:18,bits:7,val:23},{op:0,bits:8,val:108},{op:0,bits:8,val:44},{op:0,bits:9,val:184},{op:0,bits:8,val:12},{op:0,bits:8,val:140},{op:0,bits:8,val:76}, {op:0,bits:9,val:248},{op:16,bits:7,val:3},{op:0,bits:8,val:82},{op:0,bits:8,val:18},{op:21,bits:8,val:163},{op:19,bits:7,val:35},{op:0,bits:8,val:114}, {op:0,bits:8,val:50},{op:0,bits:9,val:196},{op:17,bits:7,val:11},{op:0,bits:8,val:98},{op:0,bits:8,val:34},{op:0,bits:9,val:164},{op:0,bits:8,val:2}, {op:0,bits:8,val:130},{op:0,bits:8,val:66},{op:0,bits:9,val:228},{op:16,bits:7,val:7},{op:0,bits:8,val:90},{op:0,bits:8,val:26},{op:0,bits:9,val:148}, {op:20,bits:7,val:67},{op:0,bits:8,val:122},{op:0,bits:8,val:58},{op:0,bits:9,val:212},{op:18,bits:7,val:19},{op:0,bits:8,val:106},{op:0,bits:8,val:42}, {op:0,bits:9,val:180},{op:0,bits:8,val:10},{op:0,bits:8,val:138},{op:0,bits:8,val:74},{op:0,bits:9,val:244},{op:16,bits:7,val:5},{op:0,bits:8,val:86}, {op:0,bits:8,val:22},{op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:118},{op:0,bits:8,val:54},{op:0,bits:9,val:204},{op:17,bits:7,val:15}, {op:0,bits:8,val:102},{op:0,bits:8,val:38},{op:0,bits:9,val:172},{op:0,bits:8,val:6},{op:0,bits:8,val:134},{op:0,bits:8,val:70},{op:0,bits:9,val:236}, {op:16,bits:7,val:9},{op:0,bits:8,val:94},{op:0,bits:8,val:30},{op:0,bits:9,val:156},{op:20,bits:7,val:99},{op:0,bits:8,val:126},{op:0,bits:8,val:62}, {op:0,bits:9,val:220},{op:18,bits:7,val:27},{op:0,bits:8,val:110},{op:0,bits:8,val:46},{op:0,bits:9,val:188},{op:0,bits:8,val:14},{op:0,bits:8,val:142}, {op:0,bits:8,val:78},{op:0,bits:9,val:252},{op:96,bits:7,val:0},{op:0,bits:8,val:81},{op:0,bits:8,val:17},{op:21,bits:8,val:131},{op:18,bits:7,val:31}, {op:0,bits:8,val:113},{op:0,bits:8,val:49},{op:0,bits:9,val:194},{op:16,bits:7,val:10},{op:0,bits:8,val:97},{op:0,bits:8,val:33},{op:0,bits:9,val:162}, {op:0,bits:8,val:1},{op:0,bits:8,val:129},{op:0,bits:8,val:65},{op:0,bits:9,val:226},{op:16,bits:7,val:6},{op:0,bits:8,val:89},{op:0,bits:8,val:25}, {op:0,bits:9,val:146},{op:19,bits:7,val:59},{op:0,bits:8,val:121},{op:0,bits:8,val:57},{op:0,bits:9,val:210},{op:17,bits:7,val:17},{op:0,bits:8,val:105}, {op:0,bits:8,val:41},{op:0,bits:9,val:178},{op:0,bits:8,val:9},{op:0,bits:8,val:137},{op:0,bits:8,val:73},{op:0,bits:9,val:242},{op:16,bits:7,val:4}, {op:0,bits:8,val:85},{op:0,bits:8,val:21},{op:16,bits:8,val:258},{op:19,bits:7,val:43},{op:0,bits:8,val:117},{op:0,bits:8,val:53},{op:0,bits:9,val:202}, {op:17,bits:7,val:13},{op:0,bits:8,val:101},{op:0,bits:8,val:37},{op:0,bits:9,val:170},{op:0,bits:8,val:5},{op:0,bits:8,val:133},{op:0,bits:8,val:69}, {op:0,bits:9,val:234},{op:16,bits:7,val:8},{op:0,bits:8,val:93},{op:0,bits:8,val:29},{op:0,bits:9,val:154},{op:20,bits:7,val:83},{op:0,bits:8,val:125}, {op:0,bits:8,val:61},{op:0,bits:9,val:218},{op:18,bits:7,val:23},{op:0,bits:8,val:109},{op:0,bits:8,val:45},{op:0,bits:9,val:186},{op:0,bits:8,val:13}, {op:0,bits:8,val:141},{op:0,bits:8,val:77},{op:0,bits:9,val:250},{op:16,bits:7,val:3},{op:0,bits:8,val:83},{op:0,bits:8,val:19},{op:21,bits:8,val:195}, {op:19,bits:7,val:35},{op:0,bits:8,val:115},{op:0,bits:8,val:51},{op:0,bits:9,val:198},{op:17,bits:7,val:11},{op:0,bits:8,val:99},{op:0,bits:8,val:35}, {op:0,bits:9,val:166},{op:0,bits:8,val:3},{op:0,bits:8,val:131},{op:0,bits:8,val:67},{op:0,bits:9,val:230},{op:16,bits:7,val:7},{op:0,bits:8,val:91}, {op:0,bits:8,val:27},{op:0,bits:9,val:150},{op:20,bits:7,val:67},{op:0,bits:8,val:123},{op:0,bits:8,val:59},{op:0,bits:9,val:214},{op:18,bits:7,val:19}, {op:0,bits:8,val:107},{op:0,bits:8,val:43},{op:0,bits:9,val:182},{op:0,bits:8,val:11},{op:0,bits:8,val:139},{op:0,bits:8,val:75},{op:0,bits:9,val:246}, {op:16,bits:7,val:5},{op:0,bits:8,val:87},{op:0,bits:8,val:23},{op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:119},{op:0,bits:8,val:55}, {op:0,bits:9,val:206},{op:17,bits:7,val:15},{op:0,bits:8,val:103},{op:0,bits:8,val:39},{op:0,bits:9,val:174},{op:0,bits:8,val:7},{op:0,bits:8,val:135}, {op:0,bits:8,val:71},{op:0,bits:9,val:238},{op:16,bits:7,val:9},{op:0,bits:8,val:95},{op:0,bits:8,val:31},{op:0,bits:9,val:158},{op:20,bits:7,val:99}, {op:0,bits:8,val:127},{op:0,bits:8,val:63},{op:0,bits:9,val:222},{op:18,bits:7,val:27},{op:0,bits:8,val:111},{op:0,bits:8,val:47},{op:0,bits:9,val:190}, {op:0,bits:8,val:15},{op:0,bits:8,val:143},{op:0,bits:8,val:79},{op:0,bits:9,val:254},{op:96,bits:7,val:0},{op:0,bits:8,val:80},{op:0,bits:8,val:16}, {op:20,bits:8,val:115},{op:18,bits:7,val:31},{op:0,bits:8,val:112},{op:0,bits:8,val:48},{op:0,bits:9,val:193},{op:16,bits:7,val:10},{op:0,bits:8,val:96}, {op:0,bits:8,val:32},{op:0,bits:9,val:161},{op:0,bits:8,val:0},{op:0,bits:8,val:128},{op:0,bits:8,val:64},{op:0,bits:9,val:225},{op:16,bits:7,val:6}, {op:0,bits:8,val:88},{op:0,bits:8,val:24},{op:0,bits:9,val:145},{op:19,bits:7,val:59},{op:0,bits:8,val:120},{op:0,bits:8,val:56},{op:0,bits:9,val:209}, {op:17,bits:7,val:17},{op:0,bits:8,val:104},{op:0,bits:8,val:40},{op:0,bits:9,val:177},{op:0,bits:8,val:8},{op:0,bits:8,val:136},{op:0,bits:8,val:72}, {op:0,bits:9,val:241},{op:16,bits:7,val:4},{op:0,bits:8,val:84},{op:0,bits:8,val:20},{op:21,bits:8,val:227},{op:19,bits:7,val:43},{op:0,bits:8,val:116}, {op:0,bits:8,val:52},{op:0,bits:9,val:201},{op:17,bits:7,val:13},{op:0,bits:8,val:100},{op:0,bits:8,val:36},{op:0,bits:9,val:169},{op:0,bits:8,val:4}, {op:0,bits:8,val:132},{op:0,bits:8,val:68},{op:0,bits:9,val:233},{op:16,bits:7,val:8},{op:0,bits:8,val:92},{op:0,bits:8,val:28},{op:0,bits:9,val:153}, {op:20,bits:7,val:83},{op:0,bits:8,val:124},{op:0,bits:8,val:60},{op:0,bits:9,val:217},{op:18,bits:7,val:23},{op:0,bits:8,val:108},{op:0,bits:8,val:44}, {op:0,bits:9,val:185},{op:0,bits:8,val:12},{op:0,bits:8,val:140},{op:0,bits:8,val:76},{op:0,bits:9,val:249},{op:16,bits:7,val:3},{op:0,bits:8,val:82}, {op:0,bits:8,val:18},{op:21,bits:8,val:163},{op:19,bits:7,val:35},{op:0,bits:8,val:114},{op:0,bits:8,val:50},{op:0,bits:9,val:197},{op:17,bits:7,val:11}, {op:0,bits:8,val:98},{op:0,bits:8,val:34},{op:0,bits:9,val:165},{op:0,bits:8,val:2},{op:0,bits:8,val:130},{op:0,bits:8,val:66},{op:0,bits:9,val:229}, {op:16,bits:7,val:7},{op:0,bits:8,val:90},{op:0,bits:8,val:26},{op:0,bits:9,val:149},{op:20,bits:7,val:67},{op:0,bits:8,val:122},{op:0,bits:8,val:58}, {op:0,bits:9,val:213},{op:18,bits:7,val:19},{op:0,bits:8,val:106},{op:0,bits:8,val:42},{op:0,bits:9,val:181},{op:0,bits:8,val:10},{op:0,bits:8,val:138}, {op:0,bits:8,val:74},{op:0,bits:9,val:245},{op:16,bits:7,val:5},{op:0,bits:8,val:86},{op:0,bits:8,val:22},{op:64,bits:8,val:0},{op:19,bits:7,val:51}, {op:0,bits:8,val:118},{op:0,bits:8,val:54},{op:0,bits:9,val:205},{op:17,bits:7,val:15},{op:0,bits:8,val:102},{op:0,bits:8,val:38},{op:0,bits:9,val:173}, {op:0,bits:8,val:6},{op:0,bits:8,val:134},{op:0,bits:8,val:70},{op:0,bits:9,val:237},{op:16,bits:7,val:9},{op:0,bits:8,val:94},{op:0,bits:8,val:30}, {op:0,bits:9,val:157},{op:20,bits:7,val:99},{op:0,bits:8,val:126},{op:0,bits:8,val:62},{op:0,bits:9,val:221},{op:18,bits:7,val:27},{op:0,bits:8,val:110}, {op:0,bits:8,val:46},{op:0,bits:9,val:189},{op:0,bits:8,val:14},{op:0,bits:8,val:142},{op:0,bits:8,val:78},{op:0,bits:9,val:253},{op:96,bits:7,val:0}, {op:0,bits:8,val:81},{op:0,bits:8,val:17},{op:21,bits:8,val:131},{op:18,bits:7,val:31},{op:0,bits:8,val:113},{op:0,bits:8,val:49},{op:0,bits:9,val:195}, {op:16,bits:7,val:10},{op:0,bits:8,val:97},{op:0,bits:8,val:33},{op:0,bits:9,val:163},{op:0,bits:8,val:1},{op:0,bits:8,val:129},{op:0,bits:8,val:65}, {op:0,bits:9,val:227},{op:16,bits:7,val:6},{op:0,bits:8,val:89},{op:0,bits:8,val:25},{op:0,bits:9,val:147},{op:19,bits:7,val:59},{op:0,bits:8,val:121}, {op:0,bits:8,val:57},{op:0,bits:9,val:211},{op:17,bits:7,val:17},{op:0,bits:8,val:105},{op:0,bits:8,val:41},{op:0,bits:9,val:179},{op:0,bits:8,val:9}, {op:0,bits:8,val:137},{op:0,bits:8,val:73},{op:0,bits:9,val:243},{op:16,bits:7,val:4},{op:0,bits:8,val:85},{op:0,bits:8,val:21},{op:16,bits:8,val:258}, {op:19,bits:7,val:43},{op:0,bits:8,val:117},{op:0,bits:8,val:53},{op:0,bits:9,val:203},{op:17,bits:7,val:13},{op:0,bits:8,val:101},{op:0,bits:8,val:37}, {op:0,bits:9,val:171},{op:0,bits:8,val:5},{op:0,bits:8,val:133},{op:0,bits:8,val:69},{op:0,bits:9,val:235},{op:16,bits:7,val:8},{op:0,bits:8,val:93}, {op:0,bits:8,val:29},{op:0,bits:9,val:155},{op:20,bits:7,val:83},{op:0,bits:8,val:125},{op:0,bits:8,val:61},{op:0,bits:9,val:219},{op:18,bits:7,val:23}, {op:0,bits:8,val:109},{op:0,bits:8,val:45},{op:0,bits:9,val:187},{op:0,bits:8,val:13},{op:0,bits:8,val:141},{op:0,bits:8,val:77},{op:0,bits:9,val:251}, {op:16,bits:7,val:3},{op:0,bits:8,val:83},{op:0,bits:8,val:19},{op:21,bits:8,val:195},{op:19,bits:7,val:35},{op:0,bits:8,val:115},{op:0,bits:8,val:51}, {op:0,bits:9,val:199},{op:17,bits:7,val:11},{op:0,bits:8,val:99},{op:0,bits:8,val:35},{op:0,bits:9,val:167},{op:0,bits:8,val:3},{op:0,bits:8,val:131}, {op:0,bits:8,val:67},{op:0,bits:9,val:231},{op:16,bits:7,val:7},{op:0,bits:8,val:91},{op:0,bits:8,val:27},{op:0,bits:9,val:151},{op:20,bits:7,val:67}, {op:0,bits:8,val:123},{op:0,bits:8,val:59},{op:0,bits:9,val:215},{op:18,bits:7,val:19},{op:0,bits:8,val:107},{op:0,bits:8,val:43},{op:0,bits:9,val:183}, {op:0,bits:8,val:11},{op:0,bits:8,val:139},{op:0,bits:8,val:75},{op:0,bits:9,val:247},{op:16,bits:7,val:5},{op:0,bits:8,val:87},{op:0,bits:8,val:23}, {op:64,bits:8,val:0},{op:19,bits:7,val:51},{op:0,bits:8,val:119},{op:0,bits:8,val:55},{op:0,bits:9,val:207},{op:17,bits:7,val:15},{op:0,bits:8,val:103}, {op:0,bits:8,val:39},{op:0,bits:9,val:175},{op:0,bits:8,val:7},{op:0,bits:8,val:135},{op:0,bits:8,val:71},{op:0,bits:9,val:239},{op:16,bits:7,val:9}, {op:0,bits:8,val:95},{op:0,bits:8,val:31},{op:0,bits:9,val:159},{op:20,bits:7,val:99},{op:0,bits:8,val:127},{op:0,bits:8,val:63},{op:0,bits:9,val:223}, {op:18,bits:7,val:27},{op:0,bits:8,val:111},{op:0,bits:8,val:47},{op:0,bits:9,val:191},{op:0,bits:8,val:15},{op:0,bits:8,val:143},{op:0,bits:8,val:79}, {op:0,bits:9,val:255}])")); +I||(I=eval("([ {op:16,bits:5,val:1},{op:23,bits:5,val:257},{op:19,bits:5,val:17},{op:27,bits:5,val:4097},{op:17,bits:5,val:5},{op:25,bits:5,val:1025}, {op:21,bits:5,val:65},{op:29,bits:5,val:16385},{op:16,bits:5,val:3},{op:24,bits:5,val:513},{op:20,bits:5,val:33},{op:28,bits:5,val:8193}, {op:18,bits:5,val:9},{op:26,bits:5,val:2049},{op:22,bits:5,val:129},{op:64,bits:5,val:0},{op:16,bits:5,val:2},{op:23,bits:5,val:385}, {op:19,bits:5,val:25},{op:27,bits:5,val:6145},{op:17,bits:5,val:7},{op:25,bits:5,val:1537},{op:21,bits:5,val:97},{op:29,bits:5,val:24577}, {op:16,bits:5,val:4},{op:24,bits:5,val:769},{op:20,bits:5,val:49},{op:28,bits:5,val:12289},{op:18,bits:5,val:13},{op:26,bits:5,val:3073}, {op:22,bits:5,val:193},{op:64,bits:5,val:0}])")); +a.lencode=0;a.distcode=512;for(b=0;512>b;b++)a.codes[b]=B[b];for(b=0;32>b;b++)a.codes[b+512]=I[b];a.lenbits=9;a.distbits=5}function l(a,b){a.state.check=a.checksum_function(a.state.check,[b&255,b>>>8&255],0,2)}function u(a,b){b.strm=a;b.left=a.avail_out;b.next=a.next_in;b.have=a.avail_in;b.hold=a.state.hold;b.bits=a.state.bits;return b}function p(a){var b=a.strm;b.next_in=a.next;b.avail_out=a.left;b.avail_in=a.have;b.state.hold=a.hold;b.state.bits=a.bits}function n(a){a.hold=0;a.bits=0}function w(a){if(0== +a.have)return!1;a.have--;a.hold+=(a.strm.input_data.charCodeAt(a.next++)&255)<>>=b;a.bits-=b}function y(a){a.hold>>>=a.bits&7;a.bits-=a.bits&7}function h(a){return(a>>>24&255)+(a>>>8&65280)+((a&65280)<<8)+((a&255)<<24)}var K=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],r=[16,16,16,16,16,16,16,16,17,17,17,17, +18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,203,69],E=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],A=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];ZLIB.inflate_copyright=" inflate 1.2.6 Copyright 1995-2012 Mark Adler ";ZLIB.inflateResetKeep=function(a){var b;if(!a||!a.state)return ZLIB.Z_STREAM_ERROR;b=a.state;a.total_in=a.total_out=b.total=0;a.msg=null;b.wrap&&(a.adler= b.wrap&1);b.mode=0;b.last=0;b.havedict=0;b.dmax=32768;b.head=null;b.hold=0;b.bits=0;b.lencode=0;b.distcode=0;b.next=0;b.sane=1;b.back=-1;return ZLIB.Z_OK};ZLIB.inflateReset=function(a,b){var c,e;if(!a||!a.state)return ZLIB.Z_STREAM_ERROR;e=a.state;"undefined"===typeof b&&(b=15);0>b?(c=0,b=-b):(c=(b>>>4)+1,48>b&&(b&=15));a.checksum_function=1==c&&"function"===typeof ZLIB.adler32?ZLIB.adler32:2==c&&"function"===typeof ZLIB.crc32?ZLIB.crc32:d;if(b&&(8>b||15b)return a.hold=0,a.bits=0,ZLIB.Z_OK;if(16>>8))%31){a.msg="incorrect header check"; -d.mode=29;break}if(w(e,4)!=ZLIB.Z_DEFLATED){a.msg="unknown compression method";d.mode=29;break}B(e,4);y=w(e,4)+8;if(0==d.wbits)d.wbits=y;else if(y>d.wbits){a.msg="invalid window size";d.mode=29;break}d.dmax=1<>>8&1);d.flags&512&&k(a,e.hold);p(e);d.mode=2;case 2:if(!m(e,32))break a;null!==d.head&&(d.head.time=e.hold);d.flags&512&&(r=e.hold,a.state.check=a.checksum_function(a.state.check,[r&255,r>>>8&255,r>>>16&255,r>>>24&255],0,4));p(e);d.mode=3;case 3:if(!m(e,16))break a;null!==d.head&&(d.head.xflags=e.hold&255,d.head.os=e.hold>>>8);d.flags&512&&k(a,e.hold);p(e);d.mode=4;case 4:if(d.flags&1024){if(!m(e,16))break a;d.length=e.hold;null!==d.head&&(d.head.extra_len=e.hold);d.flags&512&& -k(a,e.hold);p(e);d.head.extra=""}else null!==d.head&&(d.head.extra=null);d.mode=5;case 5:if(d.flags&1024&&(r=d.length,r>e.have&&(r=e.have),r&&(null!==d.head&&null!==d.head.extra&&(y=d.head.extra_len-d.length,d.head.extra+=a.input_data.substring(e.next,e.next+(y+r>d.head.extra_max?d.head.extra_max-y:r))),d.flags&512&&(d.check=a.checksum_function(d.check,a.input_data,e.next,r)),e.have-=r,e.next+=r,d.length-=r),d.length))break a;d.length=0;d.mode=6;case 6:if(d.flags&2048){if(0==e.have)break a;null!== -d.head&&null===d.head.name&&(d.head.name="");r=0;do{y=a.input_data.charAt(e.next+r);r++;if("\x00"===y)break;null!==d.head&&d.length>>9&1,d.head.done=1);a.adler=d.check=a.checksum_function(0,null, -0,0);d.mode=11;break;case 9:if(!m(e,32))break a;a.adler=d.check=g(e.hold);p(e);d.mode=10;case 10:if(0==d.havedict)return n(e),ZLIB.Z_NEED_DICT;a.adler=d.check=a.checksum_function(0,null,0,0);d.mode=11;case 11:if(c==ZLIB.Z_BLOCK||c==ZLIB.Z_TREES)break a;case 12:if(d.last){l(e);d.mode=26;break}if(!m(e,3))break a;d.last=w(e,1);B(e,1);switch(w(e,2)){case 0:d.mode=13;break;case 1:q(d);d.mode=19;if(c==ZLIB.Z_TREES){B(e,2);break a}break;case 2:d.mode=16;break;case 3:a.msg="invalid block type",d.mode=29}B(e, -2);break;case 13:l(e);if(!m(e,32))break a;if((e.hold&65535)!=(e.hold>>>16&65535^65535)){a.msg="invalid stored block lengths";d.mode=29;break}d.length=e.hold&65535;p(e);d.mode=14;if(c==ZLIB.Z_TREES)break a;case 14:d.mode=15;case 15:if(r=d.length){r>e.have&&(r=e.have);r>e.left&&(r=e.left);if(0==r)break a;a.output_data+=a.input_data.substring(e.next,e.next+r);a.next_out+=r;e.have-=r;e.next+=r;e.left-=r;d.length-=r;break}d.mode=11;break;case 16:if(!m(e,14))break a;d.nlen=w(e,5)+257;B(e,5);d.ndist=w(e, -5)+1;B(e,5);d.ncode=w(e,4)+4;B(e,4);if(286d.have;)d.lens[E[d.have++]]=0;d.next=0;d.lencode=0;d.lenbits=7;if(J=b(d,0)){a.msg="invalid code lengths set";d.mode=29;break}d.have=0;d.mode=18;case 18:for(;d.have -r.val)B(e,r.bits),d.lens[d.have++]=r.val;else{if(16==r.val){if(!m(e,r.bits+2))break a;B(e,r.bits);if(0==d.have){a.msg="invalid bit length repeat";d.mode=29;break}y=d.lens[d.have-1];r=3+w(e,2);B(e,2)}else if(17==r.val){if(!m(e,r.bits+3))break a;B(e,r.bits);y=0;r=3+w(e,3);B(e,3)}else{if(!m(e,r.bits+7))break a;B(e,r.bits);y=0;r=11+w(e,7);B(e,7)}if(d.have+r>d.nlen+d.ndist){a.msg="invalid bit length repeat";d.mode=29;break}for(;r--;)d.lens[d.have++]=y}}if(29==d.mode)break;if(0==d.lens[256]){a.msg="invalid code -- missing end-of-block"; -d.mode=29;break}d.next=0;d.lencode=d.next;d.lenbits=9;if(J=b(d,1)){a.msg="invalid literal/lengths set";d.mode=29;break}d.distcode=d.next;d.distbits=6;if(J=b(d,2)){a.msg="invalid distances set";d.mode=29;break}d.mode=19;if(c==ZLIB.Z_TREES)break a;case 19:d.mode=20;case 20:if(6<=e.have&&258<=e.left){n(e);r=a;var H=A=y=void 0,O=void 0,S=void 0,V=void 0,ba=void 0,Z=void 0,N=void 0,aa=void 0,L=void 0,G=void 0,I=void 0,Y=void 0,da=void 0,fa=void 0,ga=void 0,ha=void 0,P=void 0,K=void 0,X=void 0,ia=void 0, -ea=-1,P=-1,y=r.state,A=r.input_data,H=r.next_in,O=H+r.avail_in-5,S=r.next_out,V=S-(x-r.avail_out),ba=S+(r.avail_out-257),Z=y.wsize,N=y.whave,aa=y.wnext,L=y.window,G=y.hold,I=y.bits,Y=y.codes,da=y.lencode,fa=y.distcode,ga=(1<I&&(G+=(A.charCodeAt(H++)&255)<>>=K;I-=K;K=P.op;if(0==K)r.output_data+=String.fromCharCode(P.val),S++;else if(K&16){X=P.val;if(K&=15)I>>=K,I-=K;15>I&&(G+=(A.charCodeAt(H++)&255)<>>=K;I-=K;K=P.op;if(K&16){ia=P.val;K&=15;I>>=K;I-=K;K=S-V;if(ia>K){K=ia-K;if(K>N&&y.sane){r.msg="invalid distance too far back";y.mode=29;break b}ea=0;P=-1;ea=0==aa?ea+(Z-K):ea+(aa-K);KS-P&&(K=S-P);r.output_data+=r.output_data.substring(P,P+K);S+=K;X-=K;P+=K;for(S+=X;2>>3;H-=X;I-=X<<3;G&=(1<>> -y.bits)];if(y.bits+r.bits<=e.bits)break;if(!h(e))break a}B(e,y.bits);d.back+=y.bits}B(e,r.bits);d.back+=r.bits;d.length=r.val;if(0==r.op){d.mode=25;break}if(r.op&32){d.back=-1;d.mode=11;break}if(r.op&64){a.msg="invalid literal/length code";d.mode=29;break}d.extra=r.op&15;d.mode=21;case 21:if(d.extra){if(!m(e,d.extra))break a;d.length+=w(e,d.extra);B(e,d.extra);d.back+=d.extra}d.was=d.length;d.mode=22;case 22:for(;;){r=d.codes[d.distcode+w(e,d.distbits)];if(r.bits<=e.bits)break;if(!h(e))break a}if(0== -(r.op&240)){for(y=r;;){r=d.codes[d.distcode+y.val+(w(e,y.bits+y.op)>>>y.bits)];if(y.bits+r.bits<=e.bits)break;if(!h(e))break a}B(e,y.bits);d.back+=y.bits}B(e,r.bits);d.back+=r.bits;if(r.op&64){a.msg="invalid distance code";d.mode=29;break}d.offset=r.val;d.extra=r.op&15;d.mode=23;case 23:if(d.extra){if(!m(e,d.extra))break a;d.offset+=w(e,d.extra);B(e,d.extra);d.back+=d.extra}d.mode=24;case 24:if(0==e.left)break a;r=x-e.left;if(d.offset>r){r=d.offset-r;if(r>d.whave&&d.sane){a.msg="invalid distance too far back"; -d.mode=29;break}r>d.wnext?(r-=d.wnext,y=d.wsize-r):y=d.wnext-r;A=-1;r>d.length&&(r=d.length)}else y=-1,A=a.next_out-d.offset,r=d.length;r>e.left&&(r=e.left);e.left-=r;d.length-=r;if(0<=y)a.output_data+=d.window.substring(y,y+r),a.next_out+=r;else{a.next_out+=r;do a.output_data+=a.output_data.charAt(A++);while(--r)}0==d.length&&(d.mode=20);break;case 25:if(0==e.left)break a;a.output_data+=String.fromCharCode(d.length);a.next_out++;e.left--;d.mode=20;break;case 26:if(d.wrap){if(!m(e,32))break a;x-= -e.left;a.total_out+=x;d.total+=x;x&&(a.adler=d.check=a.checksum_function(d.check,a.output_data,a.output_data.length-x,x));x=e.left;if((d.flags?e.hold:g(e.hold))!=d.check){a.msg="incorrect data check";d.mode=29;break}p(e)}d.mode=27;case 27:if(d.wrap&&d.flags){if(!m(e,32))break a;if(e.hold!=(d.total&4294967295)){a.msg="incorrect length check";d.mode=29;break}p(e)}d.mode=28;case 28:J=ZLIB.Z_STREAM_END;break a;case 29:J=ZLIB.Z_DATA_ERROR;break a;case 30:return ZLIB.Z_MEM_ERROR;default:return ZLIB.Z_STREAM_ERROR}n(e); -if(d.wsize||x!=a.avail_out&&29>d.mode&&(26>d.mode||c!=ZLIB.Z_FINISH))e=a.state,r=a.output_data.length,null===e.window&&(e.window=""),0==e.wsize&&(e.wsize=1<=e.wsize?a.output_data.substring(r-e.wsize):e.whave+rb)return a.hold=0,a.bits=0,ZLIB.Z_OK;if(16>>8))%31){a.msg="incorrect header check"; +d.mode=29;break}if(v(e,4)!=ZLIB.Z_DEFLATED){a.msg="unknown compression method";d.mode=29;break}k(e,4);A=v(e,4)+8;if(0==d.wbits)d.wbits=A;else if(A>d.wbits){a.msg="invalid window size";d.mode=29;break}d.dmax=1<>>8&1);d.flags&512&&l(a,e.hold);n(e);d.mode=2;case 2:if(!m(e,32))break a;null!==d.head&&(d.head.time=e.hold);d.flags&512&&(q=e.hold,a.state.check=a.checksum_function(a.state.check,[q&255,q>>>8&255,q>>>16&255,q>>>24&255],0,4));n(e);d.mode=3;case 3:if(!m(e,16))break a;null!==d.head&&(d.head.xflags=e.hold&255,d.head.os=e.hold>>>8);d.flags&512&&l(a,e.hold);n(e);d.mode=4;case 4:if(d.flags&1024){if(!m(e,16))break a;d.length=e.hold;null!==d.head&&(d.head.extra_len=e.hold);d.flags&512&& +l(a,e.hold);n(e);d.head.extra=""}else null!==d.head&&(d.head.extra=null);d.mode=5;case 5:if(d.flags&1024&&(q=d.length,q>e.have&&(q=e.have),q&&(null!==d.head&&null!==d.head.extra&&(A=d.head.extra_len-d.length,d.head.extra+=a.input_data.substring(e.next,e.next+(A+q>d.head.extra_max?d.head.extra_max-A:q))),d.flags&512&&(d.check=a.checksum_function(d.check,a.input_data,e.next,q)),e.have-=q,e.next+=q,d.length-=q),d.length))break a;d.length=0;d.mode=6;case 6:if(d.flags&2048){if(0==e.have)break a;null!== +d.head&&null===d.head.name&&(d.head.name="");q=0;do{A=a.input_data.charAt(e.next+q);q++;if("\x00"===A)break;null!==d.head&&d.length>>9&1,d.head.done=1);a.adler=d.check=a.checksum_function(0,null, +0,0);d.mode=11;break;case 9:if(!m(e,32))break a;a.adler=d.check=h(e.hold);n(e);d.mode=10;case 10:if(0==d.havedict)return p(e),ZLIB.Z_NEED_DICT;a.adler=d.check=a.checksum_function(0,null,0,0);d.mode=11;case 11:if(c==ZLIB.Z_BLOCK||c==ZLIB.Z_TREES)break a;case 12:if(d.last){y(e);d.mode=26;break}if(!m(e,3))break a;d.last=v(e,1);k(e,1);switch(v(e,2)){case 0:d.mode=13;break;case 1:g(d);d.mode=19;if(c==ZLIB.Z_TREES){k(e,2);break a}break;case 2:d.mode=16;break;case 3:a.msg="invalid block type",d.mode=29}k(e, +2);break;case 13:y(e);if(!m(e,32))break a;if((e.hold&65535)!=(e.hold>>>16&65535^65535)){a.msg="invalid stored block lengths";d.mode=29;break}d.length=e.hold&65535;n(e);d.mode=14;if(c==ZLIB.Z_TREES)break a;case 14:d.mode=15;case 15:if(q=d.length){q>e.have&&(q=e.have);q>e.left&&(q=e.left);if(0==q)break a;a.output_data+=a.input_data.substring(e.next,e.next+q);a.next_out+=q;e.have-=q;e.next+=q;e.left-=q;d.length-=q;break}d.mode=11;break;case 16:if(!m(e,14))break a;d.nlen=v(e,5)+257;k(e,5);d.ndist=v(e, +5)+1;k(e,5);d.ncode=v(e,4)+4;k(e,4);if(286d.have;)d.lens[F[d.have++]]=0;d.next=0;d.lencode=0;d.lenbits=7;if(K=b(d,0)){a.msg="invalid code lengths set";d.mode=29;break}d.have=0;d.mode=18;case 18:for(;d.have +q.val)k(e,q.bits),d.lens[d.have++]=q.val;else{if(16==q.val){if(!m(e,q.bits+2))break a;k(e,q.bits);if(0==d.have){a.msg="invalid bit length repeat";d.mode=29;break}A=d.lens[d.have-1];q=3+v(e,2);k(e,2)}else if(17==q.val){if(!m(e,q.bits+3))break a;k(e,q.bits);A=0;q=3+v(e,3);k(e,3)}else{if(!m(e,q.bits+7))break a;k(e,q.bits);A=0;q=11+v(e,7);k(e,7)}if(d.have+q>d.nlen+d.ndist){a.msg="invalid bit length repeat";d.mode=29;break}for(;q--;)d.lens[d.have++]=A}}if(29==d.mode)break;if(0==d.lens[256]){a.msg="invalid code -- missing end-of-block"; +d.mode=29;break}d.next=0;d.lencode=d.next;d.lenbits=9;if(K=b(d,1)){a.msg="invalid literal/lengths set";d.mode=29;break}d.distcode=d.next;d.distbits=6;if(K=b(d,2)){a.msg="invalid distances set";d.mode=29;break}d.mode=19;if(c==ZLIB.Z_TREES)break a;case 19:d.mode=20;case 20:if(6<=e.have&&258<=e.left){p(e);q=a;var I=E=A=void 0,O=void 0,R=void 0,W=void 0,U=void 0,Z=void 0,N=void 0,Y=void 0,L=void 0,G=void 0,H=void 0,ba=void 0,da=void 0,fa=void 0,ga=void 0,ha=void 0,P=void 0,J=void 0,X=void 0,ia=void 0, +ea=-1,P=-1,A=q.state,E=q.input_data,I=q.next_in,O=I+q.avail_in-5,R=q.next_out,W=R-(B-q.avail_out),U=R+(q.avail_out-257),Z=A.wsize,N=A.whave,Y=A.wnext,L=A.window,G=A.hold,H=A.bits,ba=A.codes,da=A.lencode,fa=A.distcode,ga=(1<H&&(G+=(E.charCodeAt(I++)&255)<>>=J;H-=J;J=P.op;if(0==J)q.output_data+=String.fromCharCode(P.val),R++;else if(J&16){X=P.val;if(J&=15)H>>=J,H-=J;15>H&&(G+=(E.charCodeAt(I++)&255)<>>=J;H-=J;J=P.op;if(J&16){ia=P.val;J&=15;H>>=J;H-=J;J=R-W;if(ia>J){J=ia-J;if(J>N&&A.sane){q.msg="invalid distance too far back";A.mode=29;break b}ea=0;P=-1;ea=0==Y?ea+(Z-J):ea+(Y-J);JR-P&&(J=R-P);q.output_data+=q.output_data.substring(P,P+J);R+=J;X-=J;P+=J;for(R+=X;2>>3;I-=X;H-=X<<3;G&=(1<>> +A.bits)];if(A.bits+q.bits<=e.bits)break;if(!w(e))break a}k(e,A.bits);d.back+=A.bits}k(e,q.bits);d.back+=q.bits;d.length=q.val;if(0==q.op){d.mode=25;break}if(q.op&32){d.back=-1;d.mode=11;break}if(q.op&64){a.msg="invalid literal/length code";d.mode=29;break}d.extra=q.op&15;d.mode=21;case 21:if(d.extra){if(!m(e,d.extra))break a;d.length+=v(e,d.extra);k(e,d.extra);d.back+=d.extra}d.was=d.length;d.mode=22;case 22:for(;;){q=d.codes[d.distcode+v(e,d.distbits)];if(q.bits<=e.bits)break;if(!w(e))break a}if(0== +(q.op&240)){for(A=q;;){q=d.codes[d.distcode+A.val+(v(e,A.bits+A.op)>>>A.bits)];if(A.bits+q.bits<=e.bits)break;if(!w(e))break a}k(e,A.bits);d.back+=A.bits}k(e,q.bits);d.back+=q.bits;if(q.op&64){a.msg="invalid distance code";d.mode=29;break}d.offset=q.val;d.extra=q.op&15;d.mode=23;case 23:if(d.extra){if(!m(e,d.extra))break a;d.offset+=v(e,d.extra);k(e,d.extra);d.back+=d.extra}d.mode=24;case 24:if(0==e.left)break a;q=B-e.left;if(d.offset>q){q=d.offset-q;if(q>d.whave&&d.sane){a.msg="invalid distance too far back"; +d.mode=29;break}q>d.wnext?(q-=d.wnext,A=d.wsize-q):A=d.wnext-q;E=-1;q>d.length&&(q=d.length)}else A=-1,E=a.next_out-d.offset,q=d.length;q>e.left&&(q=e.left);e.left-=q;d.length-=q;if(0<=A)a.output_data+=d.window.substring(A,A+q),a.next_out+=q;else{a.next_out+=q;do a.output_data+=a.output_data.charAt(E++);while(--q)}0==d.length&&(d.mode=20);break;case 25:if(0==e.left)break a;a.output_data+=String.fromCharCode(d.length);a.next_out++;e.left--;d.mode=20;break;case 26:if(d.wrap){if(!m(e,32))break a;B-= +e.left;a.total_out+=B;d.total+=B;B&&(a.adler=d.check=a.checksum_function(d.check,a.output_data,a.output_data.length-B,B));B=e.left;if((d.flags?e.hold:h(e.hold))!=d.check){a.msg="incorrect data check";d.mode=29;break}n(e)}d.mode=27;case 27:if(d.wrap&&d.flags){if(!m(e,32))break a;if(e.hold!=(d.total&4294967295)){a.msg="incorrect length check";d.mode=29;break}n(e)}d.mode=28;case 28:K=ZLIB.Z_STREAM_END;break a;case 29:K=ZLIB.Z_DATA_ERROR;break a;case 30:return ZLIB.Z_MEM_ERROR;default:return ZLIB.Z_STREAM_ERROR}p(e); +if(d.wsize||B!=a.avail_out&&29>d.mode&&(26>d.mode||c!=ZLIB.Z_FINISH))e=a.state,q=a.output_data.length,null===e.window&&(e.window=""),0==e.wsize&&(e.wsize=1<=e.wsize?a.output_data.substring(q-e.wsize):e.whave+q>>16&65535;a&=65535;if(1==q)return a+=b.charCodeAt(c)&255,65521<=a&&(a-=65521),k+=a,65521<=k&&(k-=65521),a|k<<16;if(null===b)return 1;if(16>q){for(;q--;)a+=b.charCodeAt(c++)&255,k+=a;65521<=a&&(a-=65521);return a|k%65521<<16}for(;5552<=q;){q-=5552;v=347;do a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)& -255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a;while(--v);a%=65521;k%=65521}if(q){for(;16<=q;)q-=16,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)& -255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a,a+=b.charCodeAt(c++)&255,k+=a;for(;q--;)a+=b.charCodeAt(c++)&255,k+=a;a%=65521;k%=65521}return a|k<<16}function c(a,b,c,q){var k,v;k=a>>>16&65535;a&=65535;if(1==q)return a+=b[c],65521<=a&&(a-=65521),k+=a,65521<=k&&(k-=65521), -a|k<<16;if(null===b)return 1;if(16>q){for(;q--;)a+=b[c++],k+=a;65521<=a&&(a-=65521);return a|k%65521<<16}for(;5552<=q;){q-=5552;v=347;do a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a;while(--v);a%=65521;k%=65521}if(q){for(;16<=q;)q-=16,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+= -a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a,a+=b[c++],k+=a;for(;q--;)a+=b[c++],k+=a;a%=65521;k%=65521}return a|k<<16}ZLIB.adler32=function(a,d,e,q){return"string"===typeof d?b(a,d,e,q):c(a,d,e,q)};ZLIB.adler32_combine=function(a,b,c){var q,k;if(0>c)return 4294967295;k=c%65521;c=a&65535;q=k*c%65521;c+=(b&65535)+65521-1;q+=(a>>16&65535)+(b>>16&65535)+65521-k;65521<=c&&(c-=65521);65521<=c&&(c-= -65521);131042<=q&&(q-=131042);65521<=q&&(q-=65521);return c|q<<16}})();"undefined"===typeof ZLIB&&alert("ZLIB is not defined. SRC zlib.js before zlib-crc32.js"); -(function(){function b(a,b){var c,k=0;for(c=0;b;)b&1&&(c^=a[k]),b>>=1,k++;return c}function c(a,c){var q;for(q=0;32>q;q++)a[q]=b(c,c[q])}var a=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886, +(function(){function b(a,b,c,g){var l,u;l=a>>>16&65535;a&=65535;if(1==g)return a+=b.charCodeAt(c)&255,65521<=a&&(a-=65521),l+=a,65521<=l&&(l-=65521),a|l<<16;if(null===b)return 1;if(16>g){for(;g--;)a+=b.charCodeAt(c++)&255,l+=a;65521<=a&&(a-=65521);return a|l%65521<<16}for(;5552<=g;){g-=5552;u=347;do a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)& +255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a;while(--u);a%=65521;l%=65521}if(g){for(;16<=g;)g-=16,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)& +255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a,a+=b.charCodeAt(c++)&255,l+=a;for(;g--;)a+=b.charCodeAt(c++)&255,l+=a;a%=65521;l%=65521}return a|l<<16}function c(a,b,c,g){var l,u;l=a>>>16&65535;a&=65535;if(1==g)return a+=b[c],65521<=a&&(a-=65521),l+=a,65521<=l&&(l-=65521), +a|l<<16;if(null===b)return 1;if(16>g){for(;g--;)a+=b[c++],l+=a;65521<=a&&(a-=65521);return a|l%65521<<16}for(;5552<=g;){g-=5552;u=347;do a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a;while(--u);a%=65521;l%=65521}if(g){for(;16<=g;)g-=16,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+= +a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a,a+=b[c++],l+=a;for(;g--;)a+=b[c++],l+=a;a%=65521;l%=65521}return a|l<<16}ZLIB.adler32=function(a,d,e,g){return"string"===typeof d?b(a,d,e,g):c(a,d,e,g)};ZLIB.adler32_combine=function(a,b,c){var g,l;if(0>c)return 4294967295;l=c%65521;c=a&65535;g=l*c%65521;c+=(b&65535)+65521-1;g+=(a>>16&65535)+(b>>16&65535)+65521-l;65521<=c&&(c-=65521);65521<=c&&(c-= +65521);131042<=g&&(g-=131042);65521<=g&&(g-=65521);return c|g<<16}})();"undefined"===typeof ZLIB&&alert("ZLIB is not defined. SRC zlib.js before zlib-crc32.js"); +(function(){function b(a,b){var c,l=0;for(c=0;b;)b&1&&(c^=a[l]),b>>=1,l++;return c}function c(a,c){var g;for(g=0;32>g;g++)a[g]=b(c,c[g])}var a=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886, 3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444, 476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989, 3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135, 1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745, -1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];ZLIB.crc32=function(b,c,q,k){if("string"===typeof c){if(null==c)c=0;else{for(b^=4294967295;8<=k;)b=a[(b^c.charCodeAt(q++))&255]^b>>>8,b= -a[(b^c.charCodeAt(q++))&255]^b>>>8,b=a[(b^c.charCodeAt(q++))&255]^b>>>8,b=a[(b^c.charCodeAt(q++))&255]^b>>>8,b=a[(b^c.charCodeAt(q++))&255]^b>>>8,b=a[(b^c.charCodeAt(q++))&255]^b>>>8,b=a[(b^c.charCodeAt(q++))&255]^b>>>8,b=a[(b^c.charCodeAt(q++))&255]^b>>>8,k-=8;if(k){do b=a[(b^c.charCodeAt(q++))&255]^b>>>8;while(--k)}c=b^4294967295}return c}if(null==c)c=0;else{for(b^=4294967295;8<=k;)b=a[(b^c[q++])&255]^b>>>8,b=a[(b^c[q++])&255]^b>>>8,b=a[(b^c[q++])&255]^b>>>8,b=a[(b^c[q++])&255]^b>>>8,b=a[(b^c[q++])& -255]^b>>>8,b=a[(b^c[q++])&255]^b>>>8,b=a[(b^c[q++])&255]^b>>>8,b=a[(b^c[q++])&255]^b>>>8,k-=8;if(k){do b=a[(b^c[q++])&255]^b>>>8;while(--k)}c=b^4294967295}return c};ZLIB.crc32_combine=function(a,e,q){var k,v,n,p;if(0>=q)return a;n=Array(32);p=Array(32);p[0]=3988292384;for(k=v=1;32>k;k++)p[k]=v,v<<=1;c(n,p);c(p,n);do{c(n,p);q&1&&(a=b(n,a));q>>=1;if(0==q)break;c(p,n);q&1&&(a=b(p,a));q>>=1}while(0!=q);return a^e}})(); -var saveAs=saveAs||function(b){if("undefined"===typeof navigator||!/MSIE [1-9]\./.test(navigator.userAgent)){var c=b.document.createElementNS("http://www.w3.org/1999/xhtml","a"),a="download"in c,d=/Version\/[\d\.]+.*Safari/.test(navigator.userAgent),e=b.webkitRequestFileSystem,q=b.requestFileSystem||e||b.mozRequestFileSystem,k=function(a){(b.setImmediate||b.setTimeout)(function(){throw a;},0)},v=0,n=function(a){var c=function(){"string"===typeof a?(b.URL||b.webkitURL||b).revokeObjectURL(a):a.remove()}; -b.chrome?c():setTimeout(c,500)},p=function(a,b,c){b=[].concat(b);for(var d=b.length;d--;){var e=a["on"+b[d]];if("function"===typeof e)try{e.call(a,c||a)}catch(h){k(h)}}},h=function(a){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\ufeff",a],{type:a.type}):a},m=function(k,l,g){g||(k=h(k));var m=this;g=k.type;var u=!1,w,A,y=function(){p(m,["writestart","progress","write","writeend"])},H=function(){if(A&&d&&"undefined"!==typeof FileReader){var a= -new FileReader;a.onloadend=function(){var b=a.result;A.location.href="data:attachment/file"+b.slice(b.search(/[,;]/));m.readyState=m.DONE;y()};a.readAsDataURL(k);m.readyState=m.INIT}else{if(u||!w)w=(b.URL||b.webkitURL||b).createObjectURL(k);A?A.location.href=w:void 0==b.open(w,"_blank")&&d&&(b.location.href=w);m.readyState=m.DONE;y();n(w)}},E=function(a){return function(){if(m.readyState!==m.DONE)return a.apply(this,arguments)}},D={create:!0,exclusive:!1},z;m.readyState=m.INIT;l||(l="download");if(a)w= -(b.URL||b.webkitURL||b).createObjectURL(k),c.href=w,c.download=l,setTimeout(function(){var a=new MouseEvent("click");c.dispatchEvent(a);y();n(w);m.readyState=m.DONE});else{b.chrome&&g&&"application/octet-stream"!==g&&(z=k.slice||k.webkitSlice,k=z.call(k,0,k.size,"application/octet-stream"),u=!0);e&&"download"!==l&&(l+=".download");if("application/octet-stream"===g||e)A=b;q?(v+=k.size,q(b.TEMPORARY,v,E(function(a){a.root.getDirectory("saved",D,E(function(a){var b=function(){a.getFile(l,D,E(function(a){a.createWriter(E(function(b){b.onwriteend= -function(b){A.location.href=a.toURL();m.readyState=m.DONE;p(m,"writeend",b);n(a)};b.onerror=function(){var a=b.error;a.code!==a.ABORT_ERR&&H()};["writestart","progress","write","abort"].forEach(function(a){b["on"+a]=m["on"+a]});b.write(k);m.abort=function(){b.abort();m.readyState=m.DONE};m.readyState=m.WRITING}),H)}),H)};a.getFile(l,{create:!1},E(function(a){a.remove();b()}),E(function(a){a.code===a.NOT_FOUND_ERR?b():H()}))}),H)}),H)):H()}},w=m.prototype;if("undefined"!==typeof navigator&&navigator.msSaveOrOpenBlob)return function(a, -b,c){c||(a=h(a));return navigator.msSaveOrOpenBlob(a,b||"download")};w.abort=function(){this.readyState=this.DONE;p(this,"abort")};w.readyState=w.INIT=0;w.WRITING=1;w.DONE=2;w.error=w.onwritestart=w.onprogress=w.onwrite=w.onabort=w.onerror=w.onwriteend=null;return function(a,b,c){return new m(a,b,c)}}}("undefined"!==typeof self&&self||"undefined"!==typeof window&&window||this.content); +1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];ZLIB.crc32=function(b,c,g,l){if("string"===typeof c){if(null==c)c=0;else{for(b^=4294967295;8<=l;)b=a[(b^c.charCodeAt(g++))&255]^b>>>8,b= +a[(b^c.charCodeAt(g++))&255]^b>>>8,b=a[(b^c.charCodeAt(g++))&255]^b>>>8,b=a[(b^c.charCodeAt(g++))&255]^b>>>8,b=a[(b^c.charCodeAt(g++))&255]^b>>>8,b=a[(b^c.charCodeAt(g++))&255]^b>>>8,b=a[(b^c.charCodeAt(g++))&255]^b>>>8,b=a[(b^c.charCodeAt(g++))&255]^b>>>8,l-=8;if(l){do b=a[(b^c.charCodeAt(g++))&255]^b>>>8;while(--l)}c=b^4294967295}return c}if(null==c)c=0;else{for(b^=4294967295;8<=l;)b=a[(b^c[g++])&255]^b>>>8,b=a[(b^c[g++])&255]^b>>>8,b=a[(b^c[g++])&255]^b>>>8,b=a[(b^c[g++])&255]^b>>>8,b=a[(b^c[g++])& +255]^b>>>8,b=a[(b^c[g++])&255]^b>>>8,b=a[(b^c[g++])&255]^b>>>8,b=a[(b^c[g++])&255]^b>>>8,l-=8;if(l){do b=a[(b^c[g++])&255]^b>>>8;while(--l)}c=b^4294967295}return c};ZLIB.crc32_combine=function(a,e,g){var l,u,p,n;if(0>=g)return a;p=Array(32);n=Array(32);n[0]=3988292384;for(l=u=1;32>l;l++)n[l]=u,u<<=1;c(p,n);c(n,p);do{c(p,n);g&1&&(a=b(p,a));g>>=1;if(0==g)break;c(n,p);g&1&&(a=b(n,a));g>>=1}while(0!=g);return a^e}})(); +var saveAs=saveAs||function(b){if("undefined"===typeof navigator||!/MSIE [1-9]\./.test(navigator.userAgent)){var c=b.document.createElementNS("http://www.w3.org/1999/xhtml","a"),a="download"in c,d=/Version\/[\d\.]+.*Safari/.test(navigator.userAgent),e=b.webkitRequestFileSystem,g=b.requestFileSystem||e||b.mozRequestFileSystem,l=function(a){(b.setImmediate||b.setTimeout)(function(){throw a;},0)},u=0,p=function(a){var c=function(){"string"===typeof a?(b.URL||b.webkitURL||b).revokeObjectURL(a):a.remove()}; +b.chrome?c():setTimeout(c,500)},n=function(a,b,c){b=[].concat(b);for(var d=b.length;d--;){var e=a["on"+b[d]];if("function"===typeof e)try{e.call(a,c||a)}catch(g){l(g)}}},w=function(a){return/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type)?new Blob(["\ufeff",a],{type:a.type}):a},m=function(k,l,h){h||(k=w(k));var m=this;h=k.type;var r=!1,v,A,B=function(){n(m,["writestart","progress","write","writeend"])},I=function(){if(A&&d&&"undefined"!==typeof FileReader){var a= +new FileReader;a.onloadend=function(){var b=a.result;A.location.href="data:attachment/file"+b.slice(b.search(/[,;]/));m.readyState=m.DONE;B()};a.readAsDataURL(k);m.readyState=m.INIT}else{if(r||!v)v=(b.URL||b.webkitURL||b).createObjectURL(k);A?A.location.href=v:void 0==b.open(v,"_blank")&&d&&(b.location.href=v);m.readyState=m.DONE;B();p(v)}},F=function(a){return function(){if(m.readyState!==m.DONE)return a.apply(this,arguments)}},D={create:!0,exclusive:!1},z;m.readyState=m.INIT;l||(l="download");if(a)v= +(b.URL||b.webkitURL||b).createObjectURL(k),c.href=v,c.download=l,setTimeout(function(){var a=new MouseEvent("click");c.dispatchEvent(a);B();p(v);m.readyState=m.DONE});else{b.chrome&&h&&"application/octet-stream"!==h&&(z=k.slice||k.webkitSlice,k=z.call(k,0,k.size,"application/octet-stream"),r=!0);e&&"download"!==l&&(l+=".download");if("application/octet-stream"===h||e)A=b;g?(u+=k.size,g(b.TEMPORARY,u,F(function(a){a.root.getDirectory("saved",D,F(function(a){var b=function(){a.getFile(l,D,F(function(a){a.createWriter(F(function(b){b.onwriteend= +function(b){A.location.href=a.toURL();m.readyState=m.DONE;n(m,"writeend",b);p(a)};b.onerror=function(){var a=b.error;a.code!==a.ABORT_ERR&&I()};["writestart","progress","write","abort"].forEach(function(a){b["on"+a]=m["on"+a]});b.write(k);m.abort=function(){b.abort();m.readyState=m.DONE};m.readyState=m.WRITING}),I)}),I)};a.getFile(l,{create:!1},F(function(a){a.remove();b()}),F(function(a){a.code===a.NOT_FOUND_ERR?b():I()}))}),I)}),I)):I()}},v=m.prototype;if("undefined"!==typeof navigator&&navigator.msSaveOrOpenBlob)return function(a, +b,c){c||(a=w(a));return navigator.msSaveOrOpenBlob(a,b||"download")};v.abort=function(){this.readyState=this.DONE;n(this,"abort")};v.readyState=v.INIT=0;v.WRITING=1;v.DONE=2;v.error=v.onwritestart=v.onprogress=v.onwrite=v.onabort=v.onerror=v.onwriteend=null;return function(a,b,c){return new m(a,b,c)}}}("undefined"!==typeof self&&self||"undefined"!==typeof window&&window||this.content); "undefined"!==typeof module&&module.exports?module.exports.saveAs=saveAs:"undefined"!==typeof define&&null!==define&&null!=define.amd&&define([],function(){return saveAs}); var version="0.7.7",urlvars={},amtstack,wsstack=null,AllWsman="AMT_8021xCredentialContext AMT_8021XProfile AMT_ActiveFilterStatistics AMT_AgentPresenceCapabilities AMT_AgentPresenceInterfacePolicy AMT_AgentPresenceService AMT_AgentPresenceWatchdog AMT_AgentPresenceWatchdogAction AMT_AlarmClockService IPS_AlarmClockOccurrence AMT_AssetTable AMT_AssetTableService AMT_AuditLog AMT_AuditPolicyRule AMT_AuthorizationService AMT_BootCapabilities AMT_BootSettingData AMT_ComplexFilterEntryBase AMT_CRL AMT_CryptographicCapabilities AMT_EACCredentialContext AMT_EndpointAccessControlService AMT_EnvironmentDetectionInterfacePolicy AMT_EnvironmentDetectionSettingData AMT_EthernetPortSettings AMT_EventLogEntry AMT_EventManagerService AMT_EventSubscriber AMT_FilterEntryBase AMT_FilterInSystemDefensePolicy AMT_GeneralSettings AMT_GeneralSystemDefenseCapabilities AMT_Hdr8021Filter AMT_HeuristicPacketFilterInterfacePolicy AMT_HeuristicPacketFilterSettings AMT_HeuristicPacketFilterStatistics AMT_InterfacePolicy AMT_IPHeadersFilter AMT_KerberosSettingData AMT_ManagementPresenceRemoteSAP AMT_MessageLog AMT_MPSUsernamePassword AMT_NetworkFilter AMT_NetworkPortDefaultSystemDefensePolicy AMT_NetworkPortSystemDefenseCapabilities AMT_NetworkPortSystemDefensePolicy AMT_PCIDevice AMT_PETCapabilities AMT_PETFilterForTarget AMT_PETFilterSetting AMT_ProvisioningCertificateHash AMT_PublicKeyCertificate AMT_PublicKeyManagementCapabilities AMT_PublicKeyManagementService AMT_PublicPrivateKeyPair AMT_RedirectionService AMT_RemoteAccessCapabilities AMT_RemoteAccessCredentialContext AMT_RemoteAccessPolicyAppliesToMPS AMT_RemoteAccessPolicyRule AMT_RemoteAccessService AMT_SetupAndConfigurationService AMT_SNMPEventSubscriber AMT_StateTransitionCondition AMT_SystemDefensePolicy AMT_SystemDefensePolicyInService AMT_SystemDefenseService AMT_SystemPowerScheme AMT_ThirdPartyDataStorageAdministrationService AMT_ThirdPartyDataStorageService AMT_TimeSynchronizationService AMT_TLSCredentialContext AMT_TLSProtocolEndpoint AMT_TLSProtocolEndpointCollection AMT_TLSSettingData AMT_TrapTargetForService AMT_UserInitiatedConnectionService AMT_WebUIService AMT_WiFiPortConfigurationService CIM_AbstractIndicationSubscription CIM_Account CIM_AccountManagementCapabilities CIM_AccountManagementService CIM_AccountOnSystem CIM_AdminDomain CIM_AlertIndication CIM_AssignedIdentity CIM_AssociatedPowerManagementService CIM_AuthenticationService CIM_AuthorizationService CIM_BIOSElement CIM_BIOSFeature CIM_BIOSFeatureBIOSElements CIM_BootConfigSetting CIM_BootService CIM_BootSettingData CIM_BootSourceSetting CIM_Capabilities CIM_Card CIM_Chassis CIM_Chip CIM_Collection CIM_Component CIM_ComputerSystem CIM_ComputerSystemPackage CIM_ConcreteComponent CIM_ConcreteDependency CIM_Controller CIM_CoolingDevice CIM_Credential CIM_CredentialContext CIM_CredentialManagementService CIM_Dependency CIM_DeviceSAPImplementation CIM_ElementCapabilities CIM_ElementConformsToProfile CIM_ElementLocation CIM_ElementSettingData CIM_ElementSoftwareIdentity CIM_ElementStatisticalData CIM_EnabledLogicalElement CIM_EnabledLogicalElementCapabilities CIM_EthernetPort CIM_Fan CIM_FilterCollection CIM_FilterCollectionSubscription CIM_HostedAccessPoint CIM_HostedDependency CIM_HostedService CIM_Identity CIM_IEEE8021xCapabilities CIM_IEEE8021xSettings CIM_Indication CIM_IndicationService CIM_InstalledSoftwareIdentity CIM_KVMRedirectionSAP CIM_LANEndpoint CIM_ListenerDestination CIM_ListenerDestinationWSManagement CIM_Location CIM_Log CIM_LogEntry CIM_LogicalDevice CIM_LogicalElement CIM_LogicalPort CIM_LogicalPortCapabilities CIM_LogManagesRecord CIM_ManagedCredential CIM_ManagedElement CIM_ManagedSystemElement CIM_MediaAccessDevice CIM_MemberOfCollection CIM_Memory CIM_MessageLog CIM_NetworkPort CIM_NetworkPortCapabilities CIM_NetworkPortConfigurationService CIM_OrderedComponent CIM_OwningCollectionElement CIM_OwningJobElement CIM_PCIController CIM_PhysicalComponent CIM_PhysicalElement CIM_PhysicalElementLocation CIM_PhysicalFrame CIM_PhysicalMemory CIM_PhysicalPackage CIM_Policy CIM_PolicyAction CIM_PolicyCondition CIM_PolicyInSystem CIM_PolicyRule CIM_PolicyRuleInSystem CIM_PolicySet CIM_PolicySetAppliesToElement CIM_PolicySetInSystem CIM_PowerManagementCapabilities CIM_PowerManagementService CIM_PowerSupply CIM_Privilege CIM_PrivilegeManagementCapabilities CIM_PrivilegeManagementService CIM_ProcessIndication CIM_Processor CIM_ProtocolEndpoint CIM_ProvidesServiceToElement CIM_Realizes CIM_RecordForLog CIM_RecordLog CIM_RedirectionService CIM_ReferencedProfile CIM_RegisteredProfile CIM_RemoteAccessAvailableToElement CIM_RemoteIdentity CIM_RemotePort CIM_RemoteServiceAccessPoint CIM_Role CIM_RoleBasedAuthorizationService CIM_RoleBasedManagementCapabilities CIM_RoleLimitedToTarget CIM_SAPAvailableForElement CIM_SecurityService CIM_Sensor CIM_Service CIM_ServiceAccessBySAP CIM_ServiceAccessPoint CIM_ServiceAffectsElement CIM_ServiceAvailableToElement CIM_ServiceSAPDependency CIM_ServiceServiceDependency CIM_SettingData CIM_SharedCredential CIM_SoftwareElement CIM_SoftwareFeature CIM_SoftwareFeatureSoftwareElements CIM_SoftwareIdentity CIM_StatisticalData CIM_StorageExtent CIM_System CIM_SystemBIOS CIM_SystemComponent CIM_SystemDevice CIM_SystemPackaging CIM_UseOfLog CIM_Watchdog CIM_WiFiEndpoint CIM_WiFiEndpointCapabilities CIM_WiFiEndpointSettings CIM_WiFiPort CIM_WiFiPortCapabilities IPS_AdminProvisioningRecord IPS_ClientProvisioningRecord IPS_HostBasedSetupService IPS_HostIPSettings IPS_HTTPProxyService IPS_HTTPProxyAccessPoint IPS_IderSessionUsingPort IPS_IPv6PortSettings IPS_KVMRedirectionSettingData IPS_KvmSessionUsingPort IPS_ManualProvisioningRecord IPS_OptInService IPS_ProvisioningAuditRecord IPS_ProvisioningRecordLog IPS_RasSessionUsingPort IPS_ScreenConfigurationService IPS_ScreenSettingData IPS_SecIOService IPS_SessionUsingPort IPS_SolSessionUsingPort IPS_TLSProvisioningRecord IPS_WatchDogAction".split(" "),disconnecturl= null,terminal,currentView=0,LoadingHtml="
Loading...
",amtversion=0,amtversionmin=0,amtFirstPull=0,amtwirelessif=-1,desktop,desktopsettings={encoding:1,showfocus:!1,showmouse:!0,showcad:!0,limitFrameRate:!1,noMouseRotate:!1},currentMeshNode=null,webcompilerfeatures="AgentPresence Alarms AuditLog Certificates ComputerSelectorToolbar Desktop DesktopInband DesktopInbandFiles Desktop-Multi DesktopRotation Desktop-Settings EventLog EventSubscriptions FileSaver HardwareInfo IDER IDERDebug IDERStats Inflate Look-MeshCentral Mode-MeshCentral2 NetworkSettings PowerControl PowerControl-Advanced RemoteAccess Scripting Scripting-Editor Storage SystemDefense Terminal Terminal-Enumation-All Terminal-FxEnumation-All TerminalSize VersionWarning Wireless WsmanBrowser".split(" "), @@ -905,7 +907,7 @@ function setUrlVar(b,c){urlvars||(urlvars={});urlvars[b]=c}function cleanup(){c3 function handleKeyUp(b){if(!xxdialogMode){if(14==currentView&&3==desktop.State){if(Q(49).checked)return;if(null!=webRtcDesktop&&null!=webRtcDesktop.softdesktop)webRtcDesktop.softdesktop.m.handleKeyUp(b),desktop.m.sendKeepAlive();else return desktop.m.handleKeyUp(b)}if(13==currentView&&3==terminal.State)return terminal.m.TermHandleKeyUp(b)}} function handleKeyDown(b){if(!xxdialogMode){if(14==currentView&&3==desktop.State){if(Q(49).checked)return;if(null!=webRtcDesktop&&null!=webRtcDesktop.softdesktop)webRtcDesktop.softdesktop.m.handleKeyDown(b),desktop.m.sendKeepAlive();else return desktop.m.handleKeyDown(b)}if(13==currentView&&3==terminal.State)return terminal.m.TermHandleKeyDown(b)}} function handleKeyPress(b){if(!xxdialogMode){if(14==currentView&&3==desktop.State){if(Q(49).checked)return;if(null!=webRtcDesktop&&null!=webRtcDesktop.softdesktop)webRtcDesktop.softdesktop.m.handleKeys(b),desktop.m.sendKeepAlive();else return desktop.m.handleKeys(b)}if(13==currentView&&3==terminal.State)return terminal.m.TermHandleKeys(b)}}var connectFunc=null,connectFuncTag=null; -function connect(b,c,a,d,e,q,k){go(0);fullscreenonly=!1;connectFunc=q;connectFuncTag=k;1==urlvars.kvm&&go(14);if(1==urlvars.kvmfull||1==urlvars.kvmonly)go(14),deskToggleFull(1==urlvars.kvmonly);1==urlvars.sol&&go(13);wsstack=WsmanStackCreateService(b,c,a,d,e);amtstack=AmtStackCreateService(wsstack);amtstack.onProcessChanged=onProcessChanged;for(b=2;25>b;b++)QV("go"+b,!1);QV("go8",!0);QV("go13",!1);QV("go12",!0);QV("go20",!0);QH(30,"");QH(41,"");amtversion=amtversionmin=amtFirstPull= +function connect(b,c,a,d,e,g,l){go(0);fullscreenonly=!1;connectFunc=g;connectFuncTag=l;1==urlvars.kvm&&go(14);if(1==urlvars.kvmfull||1==urlvars.kvmonly)go(14),deskToggleFull(1==urlvars.kvmonly);1==urlvars.sol&&go(13);wsstack=WsmanStackCreateService(b,c,a,d,e);amtstack=AmtStackCreateService(wsstack);amtstack.onProcessChanged=onProcessChanged;for(b=2;25>b;b++)QV("go"+b,!1);QV("go8",!0);QV("go13",!1);QV("go12",!0);QV("go20",!0);QH(30,"");QH(41,"");amtversion=amtversionmin=amtFirstPull= 0;amtsysstate=amtdeltatime=amtlogicalelements=HardwareInventory=void 0;amtPowerBootCapabilities=null;xxAccountFetch=999;QH(17,LoadingHtml);QH(21,LoadingHtml);amtwirelessif=-1;xxWireless=void 0;QH(22,"");QH(18,LoadingHtml);xxAccountAdminName=null;xxAccountRealmInfo={};QH(23,LoadingHtml);eventmessages=null;QH(19,"");QH(20,LoadingHtml);auditLog=null;QH(50,""); QH(51,LoadingHtml);xxCertificates=null;QH(52,LoadingHtml);QH(26,"");iderStop();xxPolicies=xxMPSUserPass=xxRemoteAccessCredentiaLinks=xxUserInitiatedCira=xxCiraServers=xxEnvironementDetection=xxRemoteAccess=null;QH(53,LoadingHtml);QH(55,LoadingHtml);xxSystemDefense=null;xxSystemDefenceLinkedPolicy={};xxUpdatingDefenseStats=!1;xxFilterStatistics=[{},{}];xxFilterStatisticsTimer=null;xxFilterStatisticsTimerActive= !1;QH(54,LoadingHtml);QE(45,!1);QE("DeskWD",!1);QE("deskkeys",!1);urlvars.kvmviewonly&&(QE(49,!1),Q(49).checked=!0);desktopScreenInfo=null;amtstack.BatchEnum("",["CIM_SoftwareIdentity","*AMT_SetupAndConfigurationService"],processSystemVersion);QV(13,!1);fupdatescript()} @@ -920,24 +922,24 @@ function PullSystemStatus(b){refreshButtons(!1);amtstack.AMT_TimeSynchronization b&&PullWireless()}function processSystemTime(b,c,a,d){errcheck(d,b)||200!=d||(b=new Date,c=new Date,b.setTime(1E3*a.Body.Ta0+6E4*b.getTimezoneOffset()),amtdeltatime=b-c,updateSystemStatus())}var amtdeltatime,amtsysstate,amtlogicalelements,amtfeatures={}; function processSystemStatus(b,c,a,d){if(void 0==a.IPS_ScreenConfigurationService||400==a.IPS_ScreenConfigurationService.status)a.IPS_ScreenConfigurationService=null;if(void 0==a.IPS_KVMRedirectionSettingData||400==a.IPS_KVMRedirectionSettingData.status)a.IPS_KVMRedirectionSettingData=null;if(void 0==a.CIM_KVMRedirectionSAP||400==a.CIM_KVMRedirectionSAP.status)a.CIM_KVMRedirectionSAP=null;if(void 0==a.IPS_OptInService||400==a.IPS_OptInService.status)a.IPS_OptInService=null;void 0!=a.AMT_RedirectionService&& 200==a.AMT_RedirectionService.status&&QV("go13",!0);d=0;for(var e in a)null!=a[e]&&a[e].status>d&&(d=a[e].status);400!=d&&errcheck(d,b)||(amtsysstate=a,updateSystemStatus())}var DMTFPowerStates=";;Power on;Light sleep;Deep sleep;Power cycle (Soft off);Off - Hard;Hibernate (Off soft);Soft off;Power cycle (Off-hard);Master bus reset;Diagnostic interrupt (NMI);Not applicable;Off - Soft graceful;Off - Hard graceful;Master bus reset graceful;Power cycle (Off - Soft graceful);Power cycle (Off - Hard graceful);Diagnostic interrupt (INIT)".split(";"); -function updateSystemStatus(){if(amtsysstate&&!(99None":EscapeHtml(c);d+=TableEntry("Name & Domain",addLinkConditional(c,"showEditNameDlg()",xxAccountAdminName));HardwareInventory&&(d+=TableEntry("System ID",guidToStr(HardwareInventory.CIM_ComputerSystemPackage.response.PlatformGUID.toLowerCase())));if(amtlogicalelements){var k="",v=getItem(amtlogicalelements,"CreationClassName","AMT_SetupAndConfigurationService"); -2==v.ProvisioningState&&5 -k.DefaultScreen&&(e=["Primary display","Secondary display","3rd display"][k.DefaultScreen]),e=''+e+"",1==k.Is5900PortEnabled&&(e+=", Port 5900 enabled"),1==k.OptInPolicy&&(e+=", "+k.OptInPolicyTimeout+" second"+(0"+TableEnd("
 "+AddRefreshButton("PullSystemStatus(1)")+" Changing network settings may cause this page to becaume unavailable.");d=d+"

General Settings

"+TableStart();e="";"None"!=c&&(1==q.SharedFQDN&&(e=", shared with OS"),0==q.SharedFQDN&& -(e=", different from OS"));d+=TableEntry("Name & Domain",addLinkConditional(c+e,"showEditNameDlg(1)",xxAccountAdminName));c="Disabled";1==q.DDNSUpdateEnabled?c="Enabled each "+q.DDNSPeriodicUpdateInterval+" minutes, TTL is "+q.DDNSTTL+" minutes":1==q.DDNSUpdateByDHCPServerEnabled&&(c="Update by DHCP server");d+=TableEntry("Dynamic DNS",addLinkConditional(c,"showEditDnsDlg()",xxAccountAdminName));d+=TableEnd();for(a in amtsysstate.AMT_EthernetPortSettings.responses){c=amtsysstate.AMT_EthernetPortSettings.responses[a]; -if(c.WLANLinkProtectionLevel||1==a)amtwirelessif=a;if(0!=a||amtwirelessif==a||"00-00-00-00-00-00"!=c.MACAddress){0==a&&b++;d+="

"+(amtwirelessif==a?"Wireless":"Wired")+" Interface

";d+=TableStart();d+=TableEntry("Link state",1==c.LinkIsUp?"Link is up":"Link is down");"00-00-00-00-00-00"!=c.MACAddress&&(d+=TableEntry("MAC address",c.MACAddress));amtwirelessif==a&&xxWireless&&xxWireless.CIM_WiFiPortCapabilities.response&&(d+=TableEntry("State",addLinkConditional(xxWifiState[xxWireless.CIM_WiFiPort.response.EnabledState], -"showWifiStateDlg()",xxAccountAdminName)),s=xxWireless.CIM_WiFiEndpoint.response.LANID,d+=TableEntry("Radio State",xxRadioState[xxWireless.CIM_WiFiEndpoint.response.EnabledState]+", SSID: "+(s?s:"None")));amtwirelessif!=a&&(d+=TableEntry("Respond to ping",addLinkConditional(["Disabled","ICMP response","RMCP response","ICMP & RMCP response"][q.PingResponseEnabled+(q.RmcpPingResponseEnabled<<1)],"showPingActionDlg()",xxAccountAdminName)),d+=TableEntry("IPv4 state",addLinkConditional(1==c.DHCPEnabled? -"Automatic using DHCP server":"Static IP address","showIPSetupDlg()",xxAccountAdminName)));d+=TableEntry("IPv4 address",isIpAddress(c.IPAddress,"None"));isIpAddress(c.DefaultGateway)&&(d+=TableEntry("IPv4 gateway / Mask",c.DefaultGateway+" / "+isIpAddress(c.SubnetMask,"None")));e=c.PrimaryDNS;isIpAddress(e)&&(c.SecondaryDNS&&(e+=" / "+c.SecondaryDNS),d+=TableEntry("IPv4 domain name server",e));if(200==amtsysstate.IPS_IPv6PortSettings.status&&5Unknown";null!=amtsysstate.CIM_ServiceAvailableToElement&&null!=amtsysstate.CIM_ServiceAvailableToElement.responses&&0None":EscapeHtml(c);d+=TableEntry("Name & Domain",addLinkConditional(c,"showEditNameDlg()",xxAccountAdminName));HardwareInventory&&(d+=TableEntry("System ID",guidToStr(HardwareInventory.CIM_ComputerSystemPackage.response.PlatformGUID.toLowerCase()))); +if(amtlogicalelements){var l="",u=getItem(amtlogicalelements,"CreationClassName","AMT_SetupAndConfigurationService");2==u.ProvisioningState&&5l.DefaultScreen&&(e=["Primary display","Secondary display","3rd display"][l.DefaultScreen]),e=''+e+"",1==l.Is5900PortEnabled&&(e+=", Port 5900 enabled"),1==l.OptInPolicy&& +(e+=", "+l.OptInPolicyTimeout+" second"+(0"+ +TableEnd("
 "+AddRefreshButton("PullSystemStatus(1)")+" Changing network settings may cause this page to becaume unavailable.");d=d+"

General Settings

"+TableStart();e="";"None"!=c&&(1==g.SharedFQDN&&(e=", shared with OS"),0==g.SharedFQDN&&(e=", different from OS"));d+=TableEntry("Name & Domain",addLinkConditional(c+e,"showEditNameDlg(1)",xxAccountAdminName));c="Disabled";1==g.DDNSUpdateEnabled?c="Enabled each "+g.DDNSPeriodicUpdateInterval+" minutes, TTL is "+g.DDNSTTL+ +" minutes":1==g.DDNSUpdateByDHCPServerEnabled&&(c="Update by DHCP server");d+=TableEntry("Dynamic DNS",addLinkConditional(c,"showEditDnsDlg()",xxAccountAdminName));d+=TableEnd();for(a in amtsysstate.AMT_EthernetPortSettings.responses){c=amtsysstate.AMT_EthernetPortSettings.responses[a];if(c.WLANLinkProtectionLevel||1==a)amtwirelessif=a;if(0!=a||amtwirelessif==a||"00-00-00-00-00-00"!=c.MACAddress){0==a&&b++;d+="

"+(amtwirelessif==a?"Wireless":"Wired")+" Interface

";d+=TableStart();d+=TableEntry("Link state", +1==c.LinkIsUp?"Link is up":"Link is down");"00-00-00-00-00-00"!=c.MACAddress&&(d+=TableEntry("MAC address",c.MACAddress));amtwirelessif==a&&xxWireless&&xxWireless.CIM_WiFiPortCapabilities.response&&(d+=TableEntry("State",addLinkConditional(xxWifiState[xxWireless.CIM_WiFiPort.response.EnabledState],"showWifiStateDlg()",xxAccountAdminName)),s=xxWireless.CIM_WiFiEndpoint.response.LANID,d+=TableEntry("Radio State",xxRadioState[xxWireless.CIM_WiFiEndpoint.response.EnabledState]+", SSID: "+(s?s:"None"))); +amtwirelessif!=a&&(d+=TableEntry("Respond to ping",addLinkConditional(["Disabled","ICMP response","RMCP response","ICMP & RMCP response"][g.PingResponseEnabled+(g.RmcpPingResponseEnabled<<1)],"showPingActionDlg()",xxAccountAdminName)),d+=TableEntry("IPv4 state",addLinkConditional(1==c.DHCPEnabled?"Automatic using DHCP server":"Static IP address","showIPSetupDlg()",xxAccountAdminName)));d+=TableEntry("IPv4 address",isIpAddress(c.IPAddress,"None"));isIpAddress(c.DefaultGateway)&&(d+=TableEntry("IPv4 gateway / Mask", +c.DefaultGateway+" / "+isIpAddress(c.SubnetMask,"None")));e=c.PrimaryDNS;isIpAddress(e)&&(c.SecondaryDNS&&(e+=" / "+c.SecondaryDNS),d+=TableEntry("IPv4 domain name server",e));if(200==amtsysstate.IPS_IPv6PortSettings.status&&5",null!=processMessageLog0responses&&(b=1==processMessageLog0responses[0].IsFrozen?AddButton("Un-freeze Log","FreezeLog(0)"):AddButton("Freeze Log","FreezeLog(1)")),c+=TableEnd("
 
 "+AddRefreshButton("PullEventLog(1)")+ AddButton("Clear Log","ClearLog()")+AddButton("Save...","SaveEventLog()")+b),QH(19,c+"
"))}function SaveEventLog(){xxdialogMode||null==eventmessages||SaveJsonFile("IntelAmtEventlog","events","Intel AMT Event Log",eventmessages)}var eventmessages=null; -function processMessageLog1(b,c){eventmessages=c;var a,d=0,e;e="

  EventTimeSourceDescription";for(a in c){d++;var q=1,k=c[a];8<=k.EventSeverity&&(q=2);16<=k.EventSeverity&&(q=3);e+="

"+(parseInt(a)+1)+"
"+k.Time.toLocaleDateString("en",{year:"numeric",month:"2-digit",day:"numeric"})+"
"+k.Time.toLocaleTimeString("en",{hour:"2-digit",minute:"2-digit",second:"2-digit"})+"
"+k.EntityStr.replace("(r)","®")+""+k.Desc}e+=TableEnd(0==d?" ":"");QH(20,e+"
");processMessageLog0()} +function processMessageLog1(b,c){eventmessages=c;var a,d=0,e;e="

  EventTimeSourceDescription";for(a in c){d++;var g=1,l=c[a];8<=l.EventSeverity&&(g=2);16<=l.EventSeverity&&(g=3);e+="

"+(parseInt(a)+1)+"
"+l.Time.toLocaleDateString("en",{year:"numeric",month:"2-digit",day:"numeric"})+"
"+l.Time.toLocaleTimeString("en",{hour:"2-digit",minute:"2-digit",second:"2-digit"})+"
"+l.EntityStr.replace("(r)","®")+""+l.Desc}e+=TableEnd(0==d?" ":"");QH(20,e+"
");processMessageLog0()} function FreezeLog(b){xxdialogMode||amtstack.AMT_MessageLog_FreezeLog(b,function(){amtstack.Enum("AMT_MessageLog",processMessageLog0)})}function ClearLog(b){xxdialogMode||(QH(61,"Clear event log?"),setDialogMode(1,"Event Log",3,ClearLogEx))}function ClearLogEx(){amtstack.AMT_MessageLog_ClearLog(function(b,c,a,d){200!=d?messagebox("Event Log","Unable to clear, Error: "+d):PullEventLog()})} function showEventDetails(b){if(!xxdialogMode){var c=eventmessages[b],a;a="
"+addHtmlValue("Time",c.Time.toLocaleString());a+=addHtmlValue("Source",c.EntityStr.replace("(r)","®"));a+=addHtmlValue("Description",c.Desc);a+=MoreStart();a+=addHtmlValue("Device Address",c.DeviceAddress);a+=addHtmlValue("Entity",c.Entity);a+=addHtmlValue("Entity Instance",c.EntityInstance);var d="",e;for(e in c.EventData)0")}} @@ -974,8 +976,8 @@ function newSubscriptionButtonOk(){var b=0==Q("subuser").value.length?void 0:Q(" function PullAuditLog(b){1==b&&xxdialogMode||(amtFirstPull|=32,amtstack.Enum("AMT_AuditLog",processAuditLog0))}var auditLog=null,auditLogEnabledStates="Unknown;Other;Enabled;Disabled;Shutting Down;Not Applicable;Enabled but Offline;In Test;Deferred;Quiesce;Starting".split(";"); function processAuditLog0(b,c,a,d){200==d&&(QV("go15",!0),c=a[0].AuditState,b=c&1?"Disabled":"Enabled",c&2&&(b+=", Locked"),c&4&&(b+=", Almost Full"),c&8&&(b+=", Full"),c&16&&(b+=", NoKey"),c="

Audit Log Settings

"+TableStart(),c+=TableEntry("State",b),c+=TableEntry("Storage",a[0].CurrentNumberOfRecords+" record(s), "+a[0].PercentageFree+"% free"),c+=TableEntry("Overwrite policy",2==a[0].OverwritePolicy?"Wraps when full":"Never overwrites"),c+=TableEnd(),QH(50,c),amtstack.GetAuditLog(processAuditLog1))} function processAuditLog1(b,c){auditLog=c;var a,d;d=""+(TableEnd("
 
"+AddRefreshButton("PullAuditLog(1)")+AddButton("Save...","SaveAuditLog()")+AddButton("Clear Log","ClearAuditLog()"))+"
");if(0==c.length)d="No audit log events found.";else{var e=0;d+="

  TimeInitiatorAction"; -for(a in c){var q=c[a],k=q.AuditApp,v=q.Initiator;e++;var n="";0  "+q.Time.toLocaleDateString("en",{year:"numeric",month:"2-digit",day:"numeric"})+"
  "+q.Time.toLocaleTimeString("en", -{hour:"2-digit",minute:"2-digit",second:"2-digit"})+"
"+v+n+""+k}d+=TableEnd(0==e?" ":"")+"
"}QH(51,d)}function auditFilter(){var b=Q("auditFilter").value.toLowerCase(),c;for(c in auditLog)QV("xamtaudit"+c,""==b||0<=JSON.stringify(auditLog[c]).toLowerCase().indexOf(b))}function SaveAuditLog(){xxdialogMode||null==auditLog||SaveJsonFile("IntelAmtAuditlog","auditevents","Intel AMT Audit Log",auditLog)} +for(a in c){var g=c[a],l=g.AuditApp,u=g.Initiator;e++;var p="";0
  "+g.Time.toLocaleDateString("en",{year:"numeric",month:"2-digit",day:"numeric"})+"
  "+g.Time.toLocaleTimeString("en", +{hour:"2-digit",minute:"2-digit",second:"2-digit"})+"
"+u+p+""+l}d+=TableEnd(0==e?" ":"")+"
"}QH(51,d)}function auditFilter(){var b=Q("auditFilter").value.toLowerCase(),c;for(c in auditLog)QV("xamtaudit"+c,""==b||0<=JSON.stringify(auditLog[c]).toLowerCase().indexOf(b))}function SaveAuditLog(){xxdialogMode||null==auditLog||SaveJsonFile("IntelAmtAuditlog","auditevents","Intel AMT Audit Log",auditLog)} function ClearAuditLog(b){QH(61,"Clear audit log?");setDialogMode(1,"Audit Log",3,ClearAuditLogEx)}function ClearAuditLogEx(){var b=amtstack.AMT_AuditLog_SetAuditLock(1,0,b,function(){amtstack.AMT_AuditLog_ClearLog(function(){amtstack.AMT_AuditLog_SetAuditLock(0,2,b,function(){setTimeout(PullAuditLog,1E3)})})})}function ShowAuditLogSettings(){xxdialogMode||amtstack.AMT_AuditLog_RequestStateChange(2,0,AuditLogSettingsCompleted)} function AuditLogSettingsCompleted(b,c,a,d){200==d?PullAuditLog():messagebox("Audit Log","Error: "+d)} function showAuditDetails(b){if(!xxdialogMode){var c,a=auditLog[b],d;d="
"+addHtmlValue("Time",a.Time.toLocaleString());""!=a.Initiator&&(d+=addHtmlValue("Initiator",a.Initiator));""!=a.NetAddress&&(d+=addHtmlValue("Address",a.NetAddress));d+=addHtmlValue("Application",a.AuditApp);d+=addHtmlValue("Event",a.Event);if(null!=a.ExStr)d+=addHtmlValue("Extended Data",a.ExStr);else if(0"+xxCertificates[c].XSubject.CN+"");b+="
Certificate
Security
Remote CN's
";setDialogMode(11,"TLS Settings", -3,showSetTlsSecurityDlgOk,b);if(0==xxTLSCredentialContext.length||0==xxTlsSettings[0].Enabled||0==xxTlsSettings[1].Enabled)getSelectElement("tlscert").value=-1;else for(c in b=xxTLSCredentialContext[0].ElementInContext.ReferenceParameters.SelectorSet.Selector.Value,xxCertificates)xxCertificates[c].InstanceID==b&&(getSelectElement("tlscert").value=c);c=1-("Intel(r) AMT LMS TLS Settings"==xxTlsSettings[0].InstanceID?0:1);getSelectElement("tlsremote").value=(1==xxTlsSettings[c].MutualAuthentication? -2:0)+(1==xxTlsSettings[c].AcceptNonSecureConnections?1:0);xxTlsSettings[c].TrustedCN&&(Q("d11_rcn").value=MakeToArray(xxTlsSettings[c].TrustedCN).join(", "));showSetTlsSecurityDlgUpdate()}}function showSetTlsSecurityDlgUpdate(){var b=getSelectElement("tlscert").value;QE("tlsremote",-1!=b);QV("d11rcn",-1!=b&&1/wsman"+amtstack.CompleteName("AMT_PublicKeyCertificate")+''+xxCertificates[b].InstanceID+"",ElementProvidingContext:"/wsman"+amtstack.CompleteName("AMT_TLSProtocolEndpointCollection")+'TLSProtocolEndpointInstances Collection'}, setTlsSecurityResponse);setTlsSecurityPendingCalls++}else 0";b+=TableStart2();b+="

Manage Intel® AMT agent presence watchdogs.

";if(null==xxWatchdog.AMT_AgentPresenceWatchdog.responses|| 0==xxWatchdog.AMT_AgentPresenceWatchdog.responses.length)b+="
No agent presence watchdog found.

";else for(var c in xxWatchdog.AMT_AgentPresenceWatchdog.responses){var a=xxWatchdog.AMT_AgentPresenceWatchdog.responses[c],d=guidToStr(rstr2hex(atob(a.DeviceID)));a.MonitoredEntityDescription&&""!=a.MonitoredEntityDescription&&(d=EscapeHtml(a.MonitoredEntityDescription));b+="
";a.transitions&&(b+="");b+="
"+d+", "+amtstack.WatchdogCurrentStates[a.CurrentState]+"
";var d="",e;for(e in a.transitions){var q=a.transitions[e];""!=d&&(d+="
");d+=getWatchdogTransitionStr(q.OldState)+" → "+getWatchdogTransitionStr(q.NewState);q.actions&&1==q.actions[0].EventOnTransition&&(d+=" : Event to log")}""!=d&&(b+="
"+ +c+")>";a.transitions&&(b+="");b+="
"+d+", "+amtstack.WatchdogCurrentStates[a.CurrentState]+"
";var d="",e;for(e in a.transitions){var g=a.transitions[e];""!=d&&(d+="
");d+=getWatchdogTransitionStr(g.OldState)+" → "+getWatchdogTransitionStr(g.NewState);g.actions&&1==g.actions[0].EventOnTransition&&(d+=" : Event to log")}""!=d&&(b+="
"+ d+"
");b+="
"}b=b+"
"+TableEnd(AddRefreshButton("PullWatchdog()")+AddButton("Add Watchdog...","AddWatchdog()"));b+="
";QH(55,b)}}function getWatchdogTransitionStr(b){if(31==b)return"Any State";var c="",a;for(a in amtstack.WatchdogCurrentStates)0!=(b&a)&&(c+=", "+amtstack.WatchdogCurrentStates[a]);return c.substring(2)} function showWatchdogDetails(b){b=xxWatchdog.AMT_AgentPresenceWatchdog.responses[b];var c="";b.MonitoredEntityDescription&&""!=b.MonitoredEntityDescription&&(c+=addHtmlValue("Description",EscapeHtml(b.MonitoredEntityDescription)));c+=addHtmlValue("Monitored Entity",watchdogMonitoredEntity[b.MonitoredEntity]);c+=addHtmlValue("Current State",amtstack.WatchdogCurrentStates[b.CurrentState]);c+=addHtmlValue("Enabled State",watchdogEnabledStates[b.EnabledState]);c+=addHtmlValue("Startup Interval",b.StartupInterval+ " second(s)");c+=addHtmlValue("Timeout Interval",b.TimeoutInterval+" second(s)");setDialogMode(11,"Watchdog "+guidToStr(rstr2hex(atob(b.DeviceID))),5,showWatchdogDetailsOk,c,b)}function showWatchdogDetailsOk(b,c){2==b&&amtstack.Delete("AMT_AgentPresenceWatchdog",{DeviceID:c.DeviceID},PullWatchdog)} @@ -1042,11 +1044,11 @@ a}b+=TableStart();c="None";xxSystemDefenceLinkedPolicy[0]&&(c=xxSystemDef "
No system defense policies found.

";else for(c in xxSystemDefense.AMT_SystemDefensePolicy.responses)a=xxSystemDefense.AMT_SystemDefensePolicy.responses[c],d="",a.FilterCreationHandles&&(a.FilterCreationHandles=MakeToArray(a.FilterCreationHandles),d=a.FilterCreationHandles.length,d=", "+d+" filter"+(1
"+EscapeHtml(a.PolicyName)+""+d+"
";b+="

Manage Intel® AMT system defense filters.

"; if(0==xxSystemDefense.AMT_Hdr8021Filter.responses.length&&0==xxSystemDefense.AMT_IPHeadersFilter.responses.length)b+="
No system defense filters found.

";else{for(c in xxSystemDefense.AMT_Hdr8021Filter.responses)a=xxSystemDefense.AMT_Hdr8021Filter.responses[c],(d=xxSystemDefenceFilterEthernetTypes[a.HdrProtocolID8021])||(d="All Ethernet Protocol "+a.HdrProtocolID8021),d+=", "+xxSystemDefenceFilterDesc[a.FilterProfile],2==a.FilterProfile&&(d+=" at "+a.FilterProfileData+ " packet / sec"),1==a.ActionEventOnMatch&&(d+=", Event on match"),b+="
"+(0==a.FilterDirection?"← ":"→ ")+EscapeHtml(a.Name)+", "+d+"
";for(c in xxSystemDefense.AMT_IPHeadersFilter.responses){a=xxSystemDefense.AMT_IPHeadersFilter.responses[c];(d=xxSystemDefenceFilterIPTypes[a.HdrIPVersion])||(d="All Ethernet Protocol "+a.HdrIPVersion);d+=", "+xxSystemDefenceFilterDesc[a.FilterProfile];2== -a.FilterProfile&&(d+=" at "+a.FilterProfileData+" packet / sec");1==a.ActionEventOnMatch&&(d+=", Event on match");var q=0;for(e in xxSystemDefenceFilters)a[e]&&q++;0
"+(0==a.FilterDirection?"← ":"→ ")+EscapeHtml(a.Name)+", "+d+"
"}}b+="
"+TableEnd(AddRefreshButton("PullSystemDefense()")+AddButton("Add Filter...","AddDefenseFilter()")+ +a.FilterProfile&&(d+=" at "+a.FilterProfileData+" packet / sec");1==a.ActionEventOnMatch&&(d+=", Event on match");var g=0;for(e in xxSystemDefenceFilters)a[e]&&g++;0
"+(0==a.FilterDirection?"← ":"→ ")+EscapeHtml(a.Name)+", "+d+"
"}}b+="
"+TableEnd(AddRefreshButton("PullSystemDefense()")+AddButton("Add Filter...","AddDefenseFilter()")+ AddButton("Add Policy...","AddDefensePolicy()"));QH(54,b);null==xxFilterStatisticsTimer&&(UpdateDefenseStats(),xxFilterStatisticsTimerActive=!1,urlvars.norefresh||(xxFilterStatisticsTimer=setInterval(UpdateDefenseStats,5E3)))}}function StopDefenseStatsTimer(){null!=xxFilterStatisticsTimer&&(clearInterval(xxFilterStatisticsTimer),xxFilterStatisticsTimer=null);xxFilterStatisticsTimerActive=!1} function UpdateDefenseStats(b){if(b||1!=xxFilterStatisticsTimerActive)xxFilterStatisticsTimerActive=!0,b=b?b:0,xxSystemDefenceLinkedPolicy[b]?amtstack.AMT_SystemDefensePolicy_UpdateStatistics('http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_EthernetPortIntel(r) AMT Ethernet Port '+b+"",!1,UpdateDefenseStats2,b,0,{InstanceID:xxSystemDefenceLinkedPolicy[b].InstanceID}): (xxFilterStatistics[b]={},updateSystemDefense(),StopDefenseStatsTimer())}function UpdateDefenseStats2(b,c,a,d,e){200==d?amtstack.Enum("AMT_ActiveFilterStatistics",UpdateDefenseStats3,e):StopDefenseStatsTimer()} -function UpdateDefenseStats3(b,c,a,d,e){b=0;if(200==d){xxFilterStatistics[e]={};for(var q in a)d=a[q].ReadCount,c=getItem(a[q].Dependent.ReferenceParameters.SelectorSet.Selector[1].Value.EndpointReference.ReferenceParameters.SelectorSet.Selector,"@Name","Name").Value,xxFilterStatistics[e][c]=d,b++;updateSystemDefense()}xxFilterStatisticsTimerActive=!1;0==b&&StopDefenseStatsTimer()} +function UpdateDefenseStats3(b,c,a,d,e){b=0;if(200==d){xxFilterStatistics[e]={};for(var g in a)d=a[g].ReadCount,c=getItem(a[g].Dependent.ReferenceParameters.SelectorSet.Selector[1].Value.EndpointReference.ReferenceParameters.SelectorSet.Selector,"@Name","Name").Value,xxFilterStatistics[e][c]=d,b++;updateSystemDefense()}xxFilterStatisticsTimerActive=!1;0==b&&StopDefenseStatsTimer()} function changeDefaultPolicy(b){if(!xxdialogMode){var c;c="
Default Policy
",b)}} function changeDefaultPolicyOk(b,c){var a=Q("policySelection").value,d=xxSystemDefenceLinkedPolicy[c];d&&amtstack.Delete("AMT_NetworkPortSystemDefensePolicy",'http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymoushttp://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_EthernetPortCIM_EthernetPortIntel(r) AMT Ethernet Port '+c+ @@ -1059,12 +1061,12 @@ function AddDefenseFilter(){if(!xxdialogMode){var b;b="
=Q("filtertype").value){var b=0==Q("filtertype").value?2048:2054,c={"InstanceID ":0,Name:Q("filtername").value,CreationClassName:0,SystemName:0,SystemCreationClassName:0,HdrProtocolID8021:b,FilterProfile:Q("filterprofile").value,FilterDirection:Q("filterdir").value,ActionEventOnMatch:Q("filteraction").value};2==Q("filterprofile").value&&(c.FilterProfileData=Q("filterdata").value);amtstack.Create("AMT_Hdr8021Filter",c,AddDefenseFilterOk2)}else{var b=2==Q("filtertype").value? -4:6,c={"InstanceID ":0,Name:Q("filtername").value,CreationClassName:0,SystemName:0,SystemCreationClassName:0,HdrIPVersion:b,FilterProfile:Q("filterprofile").value,FilterDirection:Q("filterdir").value,ActionEventOnMatch:Q("filteraction").value},a=Q("ipfilter").value.split(","),d;for(d in a){var e=a[d].indexOf("="),q=a[d].substring(0,e),e=a[d].substring(e+1),k=xxSystemDefenceFilters[q];k||(q="Hdr"+q,k=xxSystemDefenceFilters[q]);k&&(2==k&&4==b?(e=e.split("."),4==e.length&&(c[q]=rstr2hex(String.fromCharCode(parseInt(e[0]), -parseInt(e[1]),parseInt(e[2]),parseInt(e[3]))))):c[q]=e)}2==Q("filterprofile").value&&(c.FilterProfileData=Q("filterdata").value);amtstack.Create("AMT_IPHeadersFilter",c,AddDefenseFilterOk2)}}function AddDefenseFilterUpdate(){var b=0b);QE("c48",b);QV("filterdatadiv",2==Q("filterprofile").value);QV("ipfilterdiv",2<=Q("filtertype").value)} +4:6,c={"InstanceID ":0,Name:Q("filtername").value,CreationClassName:0,SystemName:0,SystemCreationClassName:0,HdrIPVersion:b,FilterProfile:Q("filterprofile").value,FilterDirection:Q("filterdir").value,ActionEventOnMatch:Q("filteraction").value},a=Q("ipfilter").value.split(","),d;for(d in a){var e=a[d].indexOf("="),g=a[d].substring(0,e),e=a[d].substring(e+1),l=xxSystemDefenceFilters[g];l||(g="Hdr"+g,l=xxSystemDefenceFilters[g]);l&&(2==l&&4==b?(e=e.split("."),4==e.length&&(c[g]=rstr2hex(String.fromCharCode(parseInt(e[0]), +parseInt(e[1]),parseInt(e[2]),parseInt(e[3]))))):c[g]=e)}2==Q("filterprofile").value&&(c.FilterProfileData=Q("filterdata").value);amtstack.Create("AMT_IPHeadersFilter",c,AddDefenseFilterOk2)}}function AddDefenseFilterUpdate(){var b=0b);QE("c48",b);QV("filterdatadiv",2==Q("filterprofile").value);QV("ipfilterdiv",2<=Q("filtertype").value)} function AddDefenseFilterOk2(b,c,a,d){200!=d?messagebox("Add System Defense Filter","Unable to add filter, error #"+d):PullSystemDefense()} -function showFilterDetails(b,c){if(!xxdialogMode){var a,d,e,q;0==b?(q="AMT_Hdr8021Filter",e="Ethernet Traffic",d=xxSystemDefense[q].responses[c],(a=xxSystemDefenceFilterEthernetTypes[d.HdrProtocolID8021])||(a="All Ethernet Protocol "+d.HdrProtocolID8021)):(q="AMT_IPHeadersFilter",e="IP Traffic",d=xxSystemDefense[q].responses[c],(a=xxSystemDefenceFilterIPTypes[d.HdrIPVersion])||(a="All IP Protocol "+d.HdrIPVersion));var k;k=""+addHtmlValue("Name",EscapeHtml(d.Name));k+=addHtmlValue("Type",e);k+=addHtmlValue("Matching Traffic", -a);k+=addHtmlValue("Direction",0==d.FilterDirection?"Outbound / Transmit":"Inbound / Receive");if(1==b)for(var v in xxSystemDefenceFilters)d[v]&&(a=v,e=d[v],b=xxSystemDefenceFilters[v],2==b&&4==e.length&&(e=hex2rstr(e),e=e.charCodeAt(0)+"."+e.charCodeAt(1)+"."+e.charCodeAt(2)+"."+e.charCodeAt(3)),a.startsWith("Hdr")&&(a=a.substring(3)),k+=addHtmlValue("Filter "+a,e));k+=addHtmlValue("Event on match",1==d.ActionEventOnMatch?"Yes":"No");setDialogMode(11,"Ethernet Filter #"+d.InstanceID,5,showFilterDetailsOk, -k,[q,d])}}function showFilterDetailsOk(b,c){2==b&&amtstack.Delete(c[0],c[1],deleteDefenseFilter)}function deleteDefenseFilter(b,c,a,d){200!=d?messagebox("Remove Filter","Unable to remove filter, make sure it's not in use."):PullSystemDefense()}var xxAddDefensePolicyFilters; +function showFilterDetails(b,c){if(!xxdialogMode){var a,d,e,g;0==b?(g="AMT_Hdr8021Filter",e="Ethernet Traffic",d=xxSystemDefense[g].responses[c],(a=xxSystemDefenceFilterEthernetTypes[d.HdrProtocolID8021])||(a="All Ethernet Protocol "+d.HdrProtocolID8021)):(g="AMT_IPHeadersFilter",e="IP Traffic",d=xxSystemDefense[g].responses[c],(a=xxSystemDefenceFilterIPTypes[d.HdrIPVersion])||(a="All IP Protocol "+d.HdrIPVersion));var l;l=""+addHtmlValue("Name",EscapeHtml(d.Name));l+=addHtmlValue("Type",e);l+=addHtmlValue("Matching Traffic", +a);l+=addHtmlValue("Direction",0==d.FilterDirection?"Outbound / Transmit":"Inbound / Receive");if(1==b)for(var u in xxSystemDefenceFilters)d[u]&&(a=u,e=d[u],b=xxSystemDefenceFilters[u],2==b&&4==e.length&&(e=hex2rstr(e),e=e.charCodeAt(0)+"."+e.charCodeAt(1)+"."+e.charCodeAt(2)+"."+e.charCodeAt(3)),a.startsWith("Hdr")&&(a=a.substring(3)),l+=addHtmlValue("Filter "+a,e));l+=addHtmlValue("Event on match",1==d.ActionEventOnMatch?"Yes":"No");setDialogMode(11,"Ethernet Filter #"+d.InstanceID,5,showFilterDetailsOk, +l,[g,d])}}function showFilterDetailsOk(b,c){2==b&&amtstack.Delete(c[0],c[1],deleteDefenseFilter)}function deleteDefenseFilter(b,c,a,d){200!=d?messagebox("Remove Filter","Unable to remove filter, make sure it's not in use."):PullSystemDefense()}var xxAddDefensePolicyFilters; function AddDefensePolicy(){if(!xxdialogMode){xxAddDefensePolicyFilters=[];var b;b="
Name
Default TX / RX
";b+= "
";if(0
Add Filter
"}setDialogMode(11,"Add System Defense Policy",3,AddDefensePolicyOk,b);AddDefensePolicyUpdate()}}function addFilterButton(){0<=xxAddDefensePolicyFilters.indexOf(Q("xfilter").value)||(xxAddDefensePolicyFilters.push(Q("xfilter").value),AddDefensePolicyUpdate())} @@ -1091,8 +1093,8 @@ function updateWifiDialog(){var b=!0,c=c25.value,a=c26.value;QV(67,4>c);QV(66,3< c28.value)}function PullHardware(){amtstack.BatchEnum("","*CIM_ComputerSystemPackage CIM_SystemPackaging *CIM_Chassis CIM_Chip *CIM_Card *CIM_BIOSElement CIM_Processor CIM_PhysicalMemory CIM_MediaAccessDevice CIM_PhysicalPackage".split(" "),processHardware);amtFirstPull|=1} var DMTFCPUStatus="Unknown;Enabled;Disabled by User;Disabled By BIOS (POST Error);Idle;Other".split(";"),DMTFMemType="Unknown;Other;DRAM;Synchronous DRAM;Cache DRAM;EDO;EDRAM;VRAM;SRAM;RAM;ROM;Flash;EEPROM;FEPROM;EPROM;CDRAM;3DRAM;SDRAM;SGRAM;RDRAM;DDR;DDR-2;BRAM;FB-DIMM;DDR3;FBD2;DDR4;LPDDR;LPDDR2;LPDDR3;LPDDR4".split(";"),DMTFMemFormFactor=";Other;Unknown;SIMM;SIP;Chip;DIP;ZIP;Proprietary Card;DIMM;TSOP;Row of chips;RIMM;SODIMM;SRIMM;FB-DIM".split(";"),DMTFProcFamilly={191:"Intel® Core™ 2 Duo Processor", 192:"Intel® Core™ 2 Solo processor",193:"Intel® Core™ 2 Extreme processor",194:"Intel® Core™ 2 Quad processor",195:"Intel® Core™ 2 Extreme mobile processor",196:"Intel® Core™ 2 Duo mobile processor",197:"Intel® Core™ 2 Solo mobile processor",198:"Intel® Core™ i7 processor",199:"Dual-Core Intel® Celeron® processor"},HardwareInventory; -function processHardware(b,c,a,d){if(200==d){var e;b="";HardwareInventory=a;QV("go2",!0);b+=TableEnd("
 "+AddRefreshButton("PullHardware(1)")+AddButton("Save...","SaveHardwareLog()")+" Hardware information is gathered at system boot time.");c=a.CIM_Chassis.response;d=a.CIM_Card.response;var q=a.CIM_BIOSElement.response.SoftwareElementID;b=b+"

Platform

"+FullTable({"Computer model":c.Model,Manufacturer:c.Manufacturer, -Version:c.Version,"Serial number":c.SerialNumber,"System ID":guidToStr(a.CIM_SystemPackaging.responses[0].PlatformGUID).toLowerCase()},"");b+="

Baseboard

";b+=FullTable({Manufacturer:d.Manufacturer,"Product name":d.Model,Version:d.Version,"Serial number":d.SerialNumber,"Asset tag":d.Tag,"Replaceable?":1==d.CanBeFRUed?"Yes":"No"},"");b+="

BIOS

";b+=FullTable({Vendor:a.CIM_BIOSElement.response.Manufacturer,Version:q,"Release date":(new Date(a.CIM_BIOSElement.response.ReleaseDate.Datetime)).toLocaleDateString("en", +function processHardware(b,c,a,d){if(200==d){var e;b="
";HardwareInventory=a;QV("go2",!0);b+=TableEnd("
 "+AddRefreshButton("PullHardware(1)")+AddButton("Save...","SaveHardwareLog()")+" Hardware information is gathered at system boot time.");c=a.CIM_Chassis.response;d=a.CIM_Card.response;var g=a.CIM_BIOSElement.response.SoftwareElementID;b=b+"

Platform

"+FullTable({"Computer model":c.Model,Manufacturer:c.Manufacturer, +Version:c.Version,"Serial number":c.SerialNumber,"System ID":guidToStr(a.CIM_SystemPackaging.responses[0].PlatformGUID).toLowerCase()},"");b+="

Baseboard

";b+=FullTable({Manufacturer:d.Manufacturer,"Product name":d.Model,Version:d.Version,"Serial number":d.SerialNumber,"Asset tag":d.Tag,"Replaceable?":1==d.CanBeFRUed?"Yes":"No"},"");b+="

BIOS

";b+=FullTable({Vendor:a.CIM_BIOSElement.response.Manufacturer,Version:g,"Release date":(new Date(a.CIM_BIOSElement.response.ReleaseDate.Datetime)).toLocaleDateString("en", {timeZone:"UTC"})},"");b+="
";for(e in a.CIM_Processor.responses)c=a.CIM_Processor.responses[e],d=a.CIM_Chip.responses[e],b+="

Processor "+(parseInt(e)+1)+"

",b+=FullTable({Manufacturer:trademarks(d.Manufacturer),Family:DMTFProcFamilly[c.Family],Version:trademarks(d.Version),"Maximum socket speed":c.MaxClockSpeed+" MHz",Status:DMTFCPUStatus[c.CPUStatus]},"");b+="
";for(e in a.CIM_PhysicalMemory.responses)c=a.CIM_PhysicalMemory.responses[e],b+="

Memory Module "+(+e+1)+"

",b+=FullTable({"Bank Label":c.BankLabel, Manufacturer:c.Manufacturer,"Serial Number":c.SerialNumber,Size:parseInt(c.Capacity/1048576)+" MB","Form factor":DMTFMemFormFactor[c.FormFactor],Type:DMTFMemType[c.MemoryType],"Asset tag":c.Tag,"Part number":c.PartNumber},"");b+="
";for(e in a.CIM_MediaAccessDevice.responses)c=a.CIM_MediaAccessDevice.responses[e],d=a.CIM_PhysicalPackage.responses[+e+1],b+="

Storage Media "+(parseInt(e)+1)+"

",b+=FullTable({Model:d.Model,"Serial number":""==d.SerialNumber?"Unknown":d.SerialNumber,Size:parseInt(Math.round(1E3* c.MaxMediaSize/1048576))+" MB"},"");b+="
";QH(18,b);updateSystemStatus()}}function SaveHardwareLog(){!xxdialogMode&&HardwareInventory&&SaveJsonFile("IntelAmtHardware","hardware","Intel AMT Hardware Information",HardwareInventory)}var AmtSystemPowerSchemes=null;function PullPowerPolicy(){amtstack.Enum("AMT_SystemPowerScheme",powerPolicyResponse)}function powerPolicyResponse(b,c,a,d){AmtSystemPowerSchemes=a;updateSystemStatus()} @@ -1101,18 +1103,18 @@ function showPowerPolicyDlgOk(){for(var b=null,c=0,a=document.getElementsByTagNa function PullUserInfo(){xxAccountFetch=1;delete xxAccountAdminName;xxAccountRealmInfo={};amtstack.AMT_AuthorizationService_GetAdminAclEntry(getAdminAclEntryResponse);amtstack.AMT_AuthorizationService_EnumerateUserAclEntries(1,enumerateUserAclEntriesResponse)}function getAdminAclEntryResponse(b,c,a,d){200==d&&(xxAccountRealmInfo[-1]={AccessPermission:999,DigestUsername:a.Body.Username,Realms:null},xxAccountAdminName=a.Body.Username,updateAccounts())} function enumerateUserAclEntriesResponse(b,c,a,d){if(200==d){methodcheck(a);QV("go11",!0);xxAccountFetch=a.Body.Handles.length;for(var e in a.Body.Handles)b=a.Body.Handles[e],amtstack.AMT_AuthorizationService_GetAclEnabledState(b,getAclEnabledStateResponse,b),amtstack.AMT_AuthorizationService_GetUserAclEntryEx(b,getUserAclEntryExResponse,b);updateAccounts()}} function getUserAclEntryExResponse(b,c,a,d,e){xxAccountFetch--;200==d&&(a.Body.Handle=e,a.Body.Realms?Array.isArray(a.Body.Realms)||(a.Body.Realms=[a.Body.Realms]):a.Body.Realms=[],xxAccountRealmInfo[e]=a.Body,updateAccounts())}function getAclEnabledStateResponse(b,c,a,d,e){200==d&&(xxAccountEnabledInfo[e]=a.Body,updateAccounts())}function setAclEnabledStateResponse(b,c,a,d,e){errcheck(d,b)||(methodcheck(a),amtstack.AMT_AuthorizationService_GetAclEnabledState(e,getAclEnabledStateResponse,e))} -function updateAccounts(){if(!(0

Manage the Intel® AMT user accounts for this computer.

",c;for(c in xxAccountRealmInfo){var a=xxAccountRealmInfo[c],d,e=!1,q=0;a.DigestUsername?(d=a.DigestUsername,e="$"==d[0]&&"$"==d[1]):d=GetSidString(atob(a.KerberosUserSid));xxAccountEnabledInfo[c]&&"$$OsAdmin"!=d&&(q=1==xxAccountEnabledInfo[c].Enabled?1:2);if(showHiddenAccounts||!e){var k="";if(999!=a.AccessPermission){2== -q&&(k+="Disabled, ");var v=0;for(c in a.Realms)""!=amtstack.RealmNames[a.Realms[c]]&&v++;0<=a.Realms.indexOf(20)&&(k+="Auditor, ");k=0<=a.Realms.indexOf(3)?k+"Administrator":1==v?k+"1 realm":k+(v+" realms")}else k+="Administrator",a.Handle=-1;b+="
";0"+d+"
"+k+"
"}}c="
 "+AddRefreshButton("xxAccountFetch=999;PullUserInfo()");xxAccountAdminName&&(c+=AddButton("New Account", +function updateAccounts(){if(!(0

Manage the Intel® AMT user accounts for this computer.

",c;for(c in xxAccountRealmInfo){var a=xxAccountRealmInfo[c],d,e=!1,g=0;a.DigestUsername?(d=a.DigestUsername,e="$"==d[0]&&"$"==d[1]):d=GetSidString(atob(a.KerberosUserSid));xxAccountEnabledInfo[c]&&"$$OsAdmin"!=d&&(g=1==xxAccountEnabledInfo[c].Enabled?1:2);if(showHiddenAccounts||!e){var l="";if(999!=a.AccessPermission){2== +g&&(l+="Disabled, ");var u=0;for(c in a.Realms)""!=amtstack.RealmNames[a.Realms[c]]&&u++;0<=a.Realms.indexOf(20)&&(l+="Auditor, ");l=0<=a.Realms.indexOf(3)?l+"Administrator":1==u?l+"1 realm":l+(u+" realms")}else l+="Administrator",a.Handle=-1;b+="
";0"+d+"
"+l+"
"}}c="
 "+AddRefreshButton("xxAccountFetch=999;PullUserInfo()");xxAccountAdminName&&(c+=AddButton("New Account", "newAccountButton()"));b+="
"+TableEnd(c+"");QH(23,b)}}function toggleAccountButton(){showHiddenAccounts=!showHiddenAccounts;updateAccounts()}function removeUserAclEntryResponse(b,c,a,d,e){methodcheck(a)||PullUserInfo()}function changeAccountStateButton(b,c,a){haltEvent(b);xxdialogMode||amtstack.AMT_AuthorizationService_SetAclEnabledState(c,1==a?!1:!0,setAclEnabledStateResponse,c)} function changeAccountButton(b,c){haltEvent(b);xxdialogMode||(updateRealms(xxAccountRealmInfo[c].Realms),d2username.value=xxAccountRealmInfo[c].DigestUsername?xxAccountRealmInfo[c].DigestUsername:GetSidString(atob(xxAccountRealmInfo[c].KerberosUserSid)),d2password1.value=d2password2.value="",d2permission.value=xxAccountRealmInfo[c].AccessPermission,setDialogMode(2,"Edit Account",-1==c?3:7,function(a){changeAccountButtonEx(c,a)}),updateAccountDialog())} function newAccountButton(){xxdialogMode||(updateRealms([]),d2username.value=d2password1.value=d2password2.value="",d2permission.value=2,setDialogMode(2,"New Account",3,function(){changeAccountButtonEx(null,1)}),updateAccountDialog())} -function changeAccountButtonEx(b,c){if(1==c){var a=[],d=d2username.value,e=d2permission.value,q=d2password1.value,k=GetSidByteArray(Q("d2username").value),v=null;if(0==d.length||q!=d2password2.value){messagebox("Account Error","Invalid Parameters");return}null==k?v=window.btoa(rstr_md5(d+":"+amtsysstate.AMT_GeneralSettings.response.DigestRealm+":"+q)):(d=null,k=btoa(k));if(-1!=b)for(var n in amtstack.RealmNames)(amtstack.RealmNames[n]||3==n)&&Q("rx"+n).checked&&a.push(n);null==b?amtstack.AMT_AuthorizationService_AddUserAclEntryEx(d, -v,k,e,a,userAclEntryExResponse):-1==b?amtstack.AMT_AuthorizationService_SetAdminAclEntryEx(d,v,userAclEntryExResponse):amtstack.AMT_AuthorizationService_UpdateUserAclEntryEx(b,d,v,k,e,a,userAclEntryExResponse)}2==c&&amtstack.AMT_AuthorizationService_RemoveUserAclEntry(b,removeUserAclEntryResponse)}function userAclEntryExResponse(b,c,a,d,e){methodcheck(a)||PullUserInfo()} +function changeAccountButtonEx(b,c){if(1==c){var a=[],d=d2username.value,e=d2permission.value,g=d2password1.value,l=GetSidByteArray(Q("d2username").value),u=null;if(0==d.length||g!=d2password2.value){messagebox("Account Error","Invalid Parameters");return}null==l?u=window.btoa(rstr_md5(d+":"+amtsysstate.AMT_GeneralSettings.response.DigestRealm+":"+g)):(d=null,l=btoa(l));if(-1!=b)for(var p in amtstack.RealmNames)(amtstack.RealmNames[p]||3==p)&&Q("rx"+p).checked&&a.push(p);null==b?amtstack.AMT_AuthorizationService_AddUserAclEntryEx(d, +u,l,e,a,userAclEntryExResponse):-1==b?amtstack.AMT_AuthorizationService_SetAdminAclEntryEx(d,u,userAclEntryExResponse):amtstack.AMT_AuthorizationService_UpdateUserAclEntryEx(b,d,u,l,e,a,userAclEntryExResponse)}2==c&&amtstack.AMT_AuthorizationService_RemoveUserAclEntry(b,removeUserAclEntryResponse)}function userAclEntryExResponse(b,c,a,d,e){methodcheck(a)||PullUserInfo()} function updateRealms(b){QV(62,null!=b);if(null!=b){var c="

  • ",a;for(a in amtstack.RealmNames){var d="";0<=b.indexOf(parseInt(a))&&(d=" checked");amtstack.RealmNames[a]&&(c+="
  • ")}QH(63,c)}} function updateAccountDialog(){var b=!1,c;for(c in amtstack.RealmNames)(amtstack.RealmNames[c]||3==c)&&Q("rx"+c).checked&&(b=!0);b&=0",d,e=c.DigestUsername;e||(e=GetSidString(atob(c.KerberosUserSid)));a+=addHtmlValue("Name",e);xxAccountEnabledInfo[b]&&(a+=addHtmlValue("State",1==xxAccountEnabledInfo[b].Enabled?"Enabled":"Disabled"));if(e==xxAccountAdminName)a+=addHtmlValue("Permission","Administrator");else{var a=a+addHtmlValue("Permission",xxUserPermissions[c.AccessPermission]),q="";if(0<=c.Realms.indexOf(3))q="Administrator", -0<=c.Realms.indexOf(20)&&(q+=", Auditor");else for(d in xxAccountRealmInfo[b].Realms)""!=amtstack.RealmNames[c.Realms[d]]&&(0"+q+""}messagebox("Account "+e,a+"")}} +function showUserDetails(b){if(!xxdialogMode){var c=xxAccountRealmInfo[b],a="
    ",d,e=c.DigestUsername;e||(e=GetSidString(atob(c.KerberosUserSid)));a+=addHtmlValue("Name",e);xxAccountEnabledInfo[b]&&(a+=addHtmlValue("State",1==xxAccountEnabledInfo[b].Enabled?"Enabled":"Disabled"));if(e==xxAccountAdminName)a+=addHtmlValue("Permission","Administrator");else{var a=a+addHtmlValue("Permission",xxUserPermissions[c.AccessPermission]),g="";if(0<=c.Realms.indexOf(3))g="Administrator", +0<=c.Realms.indexOf(20)&&(g+=", Auditor");else for(d in xxAccountRealmInfo[b].Realms)""!=amtstack.RealmNames[c.Realms[d]]&&(0"+g+""}messagebox("Account "+e,a+"
    ")}} function wsmanQuery(){QH(26,"");var b=getSelectedOptions(Q(24)),c=[],a;for(a in b)""==QS("WSB-"+b[a]).display&&c.push(b[a]);0!=c.length&&(QE(25,!1),c&&0"+e+"
    ",b=200==c.status?0==c.responses.length?b+"
    (Empty)":b+ObjectToString(c.responses).replace(/Intel\(r\)/g,"Intel®"):b+("
    Error #"+c.status+"
    "),b+="

    ";QH(26,b)} function wsmanFilter(){var b=c0.value.toLowerCase(),c;for(c in AllWsman)QV("WSB-"+AllWsman[c],""==b||0<=AllWsman[c].toLowerCase().indexOf(b))}function connectTerminal(){terminal&&(0==terminal.State?(terminal.tlsv1only=amtstack.wsman.comm.tlsv1only,terminal.Start(currentMeshNode._id,16994,"*","*",0)):terminal.Stop())} @@ -1148,10 +1150,10 @@ function dmousemove(b){xxdialogMode||Q(49).checked||(null!=webRtcDesktop&&null!= function drotate(b){b=desktop.m.rotation+b;desktop.m.setRotation(b);null!=webRtcDesktop&&null!=webRtcDesktop.softdesktop&&null!=webRtcDesktop.softdesktop.m&&webRtcDesktop.softdesktop.m.setRotation(b);center()}var p24files=null,p24filetree=null,p24targetpath=null,p24filetreelocation=[]; function onFilesControlData(b){if(0"+p24filetreelocation[q]+"";var e=p24filetreelocation.join("/"),k=p24sort_files(p24filetree.dir);for(q in k){var v=k[q],n=v.n,p;p=70'+EscapeHtml(n.substring(0, -70))+"...":EscapeHtml(n);var n=EscapeHtml(n),h="";null!=v.d&&(h=new Date(v.d),h=h.getMonth()+1+"/"+h.getDate()+"/"+h.getFullYear()+" "+h.toLocaleTimeString()+" ");var m="";null!=v.s&&(m=getFileSizeStr(v.s));var w="";3>v.t?w="":(w=p,0'+p+""),w="
     "+h+""+m+"
    "+w+"
    "); -3>v.t?c+=w:a+=w}QH("p24files",c+a);QH("p24currentpath",d);QE("p24FolderUp",0!=p24filetreelocation.length);if(null!=b)for(c=document.getElementsByName("fd"),q=0;q"+p24filetreelocation[g]+"";var e=p24filetreelocation.join("/"),l=p24sort_files(p24filetree.dir);for(g in l){var u=l[g],p=u.n,n;n=70'+EscapeHtml(p.substring(0, +70))+"...":EscapeHtml(p);var p=EscapeHtml(p),w="";null!=u.d&&(w=new Date(u.d),w=w.getMonth()+1+"/"+w.getDate()+"/"+w.getFullYear()+" "+w.toLocaleTimeString()+" ");var m="";null!=u.s&&(m=getFileSizeStr(u.s));var v="";3>u.t?v="":(v=n,0'+n+""),v="
     "+w+""+m+"
    "+v+"
    "); +3>u.t?c+=v:a+=v}QH("p24files",c+a);QH("p24currentpath",d);QE("p24FolderUp",0!=p24filetreelocation.length);if(null!=b)for(c=document.getElementsByName("fd"),g=0;gb;)p24filetreelocation.pop();p24targetpath=p24filetreelocation.join("/");p24files.sendCtrlMsg(JSON.stringify({action:"ls",reqid:1,path:p24targetpath}))}var p24sortorder;function p24sort_filename(b,c){return b.ln>c.ln?1*p24sortorder:b.lnc.d?1*p24sortorder:b.d"+(ider.m.server?"Server ":"")+"IDE-R Session, Connected, "+ider.m.bytesFromAmt+" in, "+ider.m.bytesToAmt+" out.")}var heatMapWidth=600,heatMapDividor={}; -function iderSectorStats(b,c,a,d,e){var q=c?Q("cdromHeatMapCanvas"):Q("floppyHeatMapCanvas"),k=q.getContext("2d");if(0==b){heatMapDividor[c]=1;if(0CDROM, blocks are "+2048*heatMapDividor[c]+" bytes.")):(QV("floppyHeatMap",a),QH("floppyHeatMapText","Floppy, blocks are "+512*heatMapDividor[c]+" bytes."))}c=heatMapDividor[c];a/=c;d/=c;e/=c;if(0==b)q.height=6*(Math.floor(a/(heatMapWidth/ -6))+(a%heatMapWidth?1:0)),k.fillStyle="rgba(225,250,225,1)",k.fillRect(0,0,heatMapWidth,6*Math.floor(a/(heatMapWidth/6))),a%heatMapWidth&&k.fillRect(0,6*Math.floor(a/(heatMapWidth/6)),a%(heatMapWidth/6)*6,6),k.fillStyle="rgba(0,0,0,0.3)";else for(b=d;bCDROM, blocks are "+2048*heatMapDividor[c]+" bytes.")):(QV("floppyHeatMap",a),QH("floppyHeatMapText","Floppy, blocks are "+512*heatMapDividor[c]+" bytes."))}c=heatMapDividor[c];a/=c;d/=c;e/=c;if(0==b)g.height=6*(Math.floor(a/(heatMapWidth/ +6))+(a%heatMapWidth?1:0)),l.fillStyle="rgba(225,250,225,1)",l.fillRect(0,0,heatMapWidth,6*Math.floor(a/(heatMapWidth/6))),a%heatMapWidth&&l.fillRect(0,6*Math.floor(a/(heatMapWidth/6)),a%(heatMapWidth/6)*6,6),l.fillStyle="rgba(0,0,0,0.3)";else for(b=d;bq&&(q="0"+q),c+=", at "+e+":"+q+" daily")}b+=TableEntry("Periodic connection",addLinkConditional(c,'editMpsPolicy("Periodic")',xxAccountAdminName));b+=TableEnd();b=b+"
    "+TableStart2();b+="

    Manage Intel® AMT remote management servers.

    ";if(0==xxCiraServers.length)b+="

    No remote servers found.

    "; +(c+=", "),c+=xxPolicies.Alert[d].AccessInfo,1==xxPolicies.Alert[d].MpsType&&(c+=" (CILA)");b+=TableEntry("Alert initiated connection",addLinkConditional(c,'editMpsPolicy("Alert")',xxAccountAdminName));c="None";if(0g&&(g="0"+g),c+=", at "+e+":"+g+" daily")}b+=TableEntry("Periodic connection",addLinkConditional(c,'editMpsPolicy("Periodic")',xxAccountAdminName));b+=TableEnd();b=b+"
    "+TableStart2();b+="

    Manage Intel® AMT remote management servers.

    ";if(0==xxCiraServers.length)b+="

    No remote servers found.

    "; else for(d in xxCiraServers)c=":"+xxCiraServers[d].Port,xxCiraServers[d].CN&&(c+=", "+xxCiraServers[d].CN),b+="
    "+xxCiraServers[d].AccessInfo+""+EscapeHtml(c)+"
    ";if(a)if(b+="
    Manage HTTP proxies used for management connections.

    ",c=xxRemoteAccess.IPS_HTTPProxyAccessPoint.responses,0==c.length)b+="

    No proxies configured.

    ";else for(d in c)b+="
    "+EscapeHtml(c[d].AccessInfo)+":"+c[d].Port+" / "+EscapeHtml(c[d].NetworkDnsSuffix)+"
    ";d="";xxAccountAdminName&&(d=AddButton("Add Server...","AddRemoteAccessServer()"),a&&(d+=AddButton("Add Proxy...","AddRemoteAccessProxy()")));b+="
    "+TableEnd(AddRefreshButton("PullRemoteAccess()")+d);QH(53,b)}}var xxEditMpsPolicyType; function editMpsPolicy(b){var c="",a=11"); +function editMpsPolicyOk2(b,c,a,d){b=11http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymoushttp://intel.com/wbem/wscim/1/amt-schema/1/AMT_ManagementPresenceRemoteSAP'+ +xxCiraServers[Q("d2server1").value].Name+"");0<=Q("d2server1").value&&1http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymoushttp://intel.com/wbem/wscim/1/amt-schema/1/AMT_ManagementPresenceRemoteSAP'+ +xxCiraServers[Q("d2server2").value].Name+"");d=[];var l=[];b?e&&(0==Q("d2server1cira").value?d.push(e):l.push(e),g&&(0==Q("d2server2cira").value?d.push(g):l.push(g))):e&&(d.push(e),g&&d.push(g));amtstack.AMT_RemoteAccessService_AddRemoteAccessPolicyRule(c,Q("d2lifetime").value,a,d,l,PullRemoteAccess)}}var editEnvironmentDetectionTmp; +function editEnvironmentDetection(b){1!=b&&(editEnvironmentDetectionTmp=xxEnvironementDetection.DetectionStrings?Clone(xxEnvironementDetection.DetectionStrings):[]);var c="";xxAccountAdminName&&(c+="Enter up to 5 intranet domain suffix. If the computer is outside these domains, Intel® AMT local ports will be closed and remote server connections will be active.

    ");0==editEnvironmentDetectionTmp.length&&(c+="No intranet domains, Environemnt detection disabled.
    ");for(var a in editEnvironmentDetectionTmp)c+= +"
    "+AddButton2("Remove","editEnvironmentDetectionRemove("+a+")")+"
    "+editEnvironmentDetectionTmp[a]+"
    ";xxAccountAdminName&&5>editEnvironmentDetectionTmp.length&&(c+="
    "); 1==b?QH(64,c):setDialogMode(11,"Environment Detection",xxAccountAdminName?3:1,editEnvironmentDetectionDlg,c);edInputChg()}function editEnvironmentDetectionDlg(){if(xxAccountAdminName){var b=Clone(xxEnvironementDetection);b.DetectionStrings=editEnvironmentDetectionTmp;amtstack.Put("AMT_EnvironmentDetectionSettingData",b,editEnvironmentDetectionDlg2,0,1)}} -function editEnvironmentDetectionDlg2(b,c,a,d){200!=d?messagebox("Environment Detection","Failed to add server, status "+d):a.Body.ReturnValue&&0!=a.Body.ReturnValue?messagebox("Environment Detection",a.Body.ReturnValueStr.replace(/_/g," ")):PullRemoteAccess()}function edInputChg(){4>editEnvironmentDetectionTmp.length&&QE("edAdd",0editEnvironmentDetectionTmp.length&&QE("edAdd",0"+xxUserInitiatedEnabledState[c]+"
    ";setDialogMode(11,"User Initiated Tunnel",3,editUserInitiatedCiraDlg,b)}} function editUserInitiatedCiraDlg(){amtstack.AMT_UserInitiatedConnectionService_RequestStateChange(document.querySelector("input[name=d11]:checked").value,null,editUserInitiatedCiraDlg2)}function editUserInitiatedCiraDlg2(b,c,a,d){200==d&&amtstack.Get("AMT_UserInitiatedConnectionService",editUserInitiatedCiraDlg3,0,1)}function editUserInitiatedCiraDlg3(b,c,a,d){200==d&&(xxUserInitiatedCira=a.Body,updateRemoteAccess())}var xxShowServerDetailsHandle; function showServerDetails(b){xxShowServerDetailsHandle=b;var c=xxCiraServers[b],a;a=""+addHtmlValue("Access Name",c.AccessInfo);c.Port&&(a+=addHtmlValue("Port",c.Port));c.CN&&(a+=addHtmlValue("Common Name",c.CN));if(c=getElementWithContextSelectorValue(xxRemoteAccessCredentiaLinks,c.Name))c=c.ElementInContext.ReferenceParameters.SelectorSet.Selector.Value,0c;c++){do a=b.length,b=b.replace(String.fromCharCode(c),"");while(a>b.length)}try{xxStorage=JSON.parse(b)}catch(w){return}xxStorageVendors=[];xxStorageApplications=[];b=xxStorage.content;if(Array.isArray(b)){a={};for(c in b){var d=b[c].vendor?b[c].vendor:"";a[d]||(a[d]={});var e=b[c].app?b[c].app:"";a[d][e]||(a[d][e]={});b[c].name&&(a[d][e][b[c].name]=b[c])}xxStorage.content= -b=a}else{if(b["index.htm"]||b["logon.htm"])b[""]={"":{}};b["index.htm"]&&(b[""][""]["index.htm"]=b["index.htm"],delete b["index.htm"]);b["logon.htm"]&&(b[""][""]["logon.htm"]=b["logon.htm"],delete b["logon.htm"])}a=0;var d=TableStart2()+"

    Manage Intel® AMT storage for this computer.

    ",q,k,e="";for(c in b){var v=0,n;for(n in b[c]){v++;var p=0,h;for(h in b[c][n]){p++;if(c!=q||n!=k)""!=e&&(d+=e,e="
    "),q=c,k=n,e=""!=c?e+EscapeHtml(c+" / "+n):e+ -"Root";var m='"'+c+(""!=c?"/":"")+n+(""!=n?"/":"")+h+'"',e=e+('
    "),e=e+(" "+AddButton2("Download","DownloadFromStorage("+m+',"'+h+'",event)')),e=e+("
    "+EscapeHtml(h)+", "+b[c][n][h].size+" bytes
    ");a++;-1==xxStorageVendors.indexOf(c)&&xxStorageVendors.push(c);-1==xxStorageApplications.indexOf(n)&&xxStorageApplications.push(n)}0==p&&(wsstack.comm.PerformAjax("", -function(){},null,0,"/amt-storage/"+c+"/"+n,"DELETE"),wsstack.comm.PerformAjax("",function(){},null,0,"/amt-storage/"+c,"DELETE"))}0==v&&wsstack.comm.PerformAjax("",function(){},null,0,"/amt-storage/"+c,"DELETE")}""!=e&&(d+=e);0==a&&(d+="

    No files found.

    ");d+="
    "+TableEnd(AddRefreshButton("PullStorage()")+AddButton("Upload...","UploadToStorage()"));QH(56,d)}else QH(56,"Unable to load storage data...
    "+ -AddButton("Refresh","PullStorage()"))}function showStorageDetails(b,c,a,d){if(!xxdialogMode){var e="",q=xxStorage.content[b][c][a];""!=b&&(e+=addHtmlValue("Vendor",b));""!=c&&(e+=addHtmlValue("Application",c));e+=addHtmlValue("Name",a);e+=addHtmlValue("Size",q.size+" bytes");q.link&&(e+=addHtmlValue("Link",q.link));setDialogMode(11,"Storage Item",5,showStorageDetailsEx,e,d)}} +function PullStorageResponse(b,c,a){0==amtstack.PendingBatchOperations&&refreshButtons(!0);if(200==c){QV("go21",!0);for(c=0;32>c;c++){do a=b.length,b=b.replace(String.fromCharCode(c),"");while(a>b.length)}try{xxStorage=JSON.parse(b)}catch(v){return}xxStorageVendors=[];xxStorageApplications=[];b=xxStorage.content;if(Array.isArray(b)){a={};for(c in b){var d=b[c].vendor?b[c].vendor:"";a[d]||(a[d]={});var e=b[c].app?b[c].app:"";a[d][e]||(a[d][e]={});b[c].name&&(a[d][e][b[c].name]=b[c])}xxStorage.content= +b=a}else{if(b["index.htm"]||b["logon.htm"])b[""]={"":{}};b["index.htm"]&&(b[""][""]["index.htm"]=b["index.htm"],delete b["index.htm"]);b["logon.htm"]&&(b[""][""]["logon.htm"]=b["logon.htm"],delete b["logon.htm"])}a=0;var d=TableStart2()+"

    Manage Intel® AMT storage for this computer.

    ",g,l,e="";for(c in b){var u=0,p;for(p in b[c]){u++;var n=0,w;for(w in b[c][p]){n++;if(c!=g||p!=l)""!=e&&(d+=e,e="
    "),g=c,l=p,e=""!=c?e+EscapeHtml(c+" / "+p):e+ +"Root";var m='"'+c+(""!=c?"/":"")+p+(""!=p?"/":"")+w+'"',e=e+('
    "),e=e+(" "+AddButton2("Download","DownloadFromStorage("+m+',"'+w+'",event)')),e=e+("
    "+EscapeHtml(w)+", "+b[c][p][w].size+" bytes
    ");a++;-1==xxStorageVendors.indexOf(c)&&xxStorageVendors.push(c);-1==xxStorageApplications.indexOf(p)&&xxStorageApplications.push(p)}0==n&&(wsstack.comm.PerformAjax("", +function(){},null,0,"/amt-storage/"+c+"/"+p,"DELETE"),wsstack.comm.PerformAjax("",function(){},null,0,"/amt-storage/"+c,"DELETE"))}0==u&&wsstack.comm.PerformAjax("",function(){},null,0,"/amt-storage/"+c,"DELETE")}""!=e&&(d+=e);0==a&&(d+="

    No files found.

    ");d+="
    "+TableEnd(AddRefreshButton("PullStorage()")+AddButton("Upload...","UploadToStorage()"));QH(56,d)}else QH(56,"Unable to load storage data...
    "+ +AddButton("Refresh","PullStorage()"))}function showStorageDetails(b,c,a,d){if(!xxdialogMode){var e="",g=xxStorage.content[b][c][a];""!=b&&(e+=addHtmlValue("Vendor",b));""!=c&&(e+=addHtmlValue("Application",c));e+=addHtmlValue("Name",a);e+=addHtmlValue("Size",g.size+" bytes");g.link&&(e+=addHtmlValue("Link",g.link));setDialogMode(11,"Storage Item",5,showStorageDetailsEx,e,d)}} function showStorageDetailsEx(b,c){2==b&&wsstack.comm.PerformAjax("",storageDeleteResponse,null,0,"/amt-storage/"+c,"DELETE")}function storageDeleteResponse(b,c){200!=c?messagebox("Storage","Unable to delete file (ERR"+c+"), check that the computer is powered on."):PullStorage()}function DownloadFromStorage(b,c,a){xxdialogMode||(haltEvent(a),wsstack.comm.PerformAjax("",DownloadFromStorageEx,c,0,"/amt-storage/"+b,"GET"))} function DownloadFromStorageEx(b,c,a){200!=c||null==b?console.log(c,"Data = null"):saveAs(data2blob(b),a)}function OpenFromStorage(b,c){if(!xxdialogMode){haltEvent(c);var a=window.open("http://"+wsstack.comm.host+":"+wsstack.comm.port+"/amt-storage/"+b,"_blank");a.opener=null;a.focus()}}function PushToStorage(b,c,a){var d=null;7E3'+b+''+a+''+d+""+e+ -""}function RemoveAllAlarms(){setDialogMode(1,"Remove all wake alarms",3,RemoveAllAlarmsEx,"Confirm removal of all wake alarms?")}function RemoveAllAlarmsEx(){var b=xxAlarms.length,c;for(c in xxAlarms)amtstack.Delete("IPS_AlarmClockOccurrence",xxAlarms[c],function(a,c,e,q){0==--b&&PullAlarms()})} +""}function RemoveAllAlarms(){setDialogMode(1,"Remove all wake alarms",3,RemoveAllAlarmsEx,"Confirm removal of all wake alarms?")}function RemoveAllAlarmsEx(){var b=xxAlarms.length,c;for(c in xxAlarms)amtstack.Delete("IPS_AlarmClockOccurrence",xxAlarms[c],function(a,c,e,g){0==--b&&PullAlarms()})} function showAddAlarm(b){if(!xxdialogMode){QE("d25alarm_name",!b);if(void 0!=b){var c=xxAlarms[b],a=new Date(c.StartTime.Datetime);Q("d25alarm_name").value=c.ElementName;Q("d25alarm_sdate").value=a.getFullYear()+"-"+_fmttimepad(a.getMonth()+1)+"-"+_fmttimepad(a.getDate());Q("d25alarm_stime").value=a.getHours()+":"+_fmttimepad(a.getMinutes())+":"+_fmttimepad(a.getSeconds());if(c.Interval){var a=c.Interval.Interval.replace("P","").replace("T","").replace("D","D,").replace("H","H,").replace("M","M,").split(","), -d=[0,0,0],e;for(e in a){var q=a[e].length-1;"D"==a[e][q]&&(d[0]=parseInt(a[e].substring(0,q)));"H"==a[e][q]&&(d[1]=parseInt(a[e].substring(0,q)));"M"==a[e][q]&&(d[2]=parseInt(a[e].substring(0,q)))}Q("d25alarm_interval").value=d.join("-")}else Q("d25alarm_interval").value="";Q("d25alarm_doc").value=1==c.DeleteOnCompletion?1:0}else c=new Date,c.setDate((new Date).getDate()+1),Q("d25alarm_name").value="",Q("d25alarm_sdate").value=c.getFullYear()+"-"+_fmttimepad(c.getMonth()+1)+"-"+_fmttimepad(c.getDate()), +d=[0,0,0],e;for(e in a){var g=a[e].length-1;"D"==a[e][g]&&(d[0]=parseInt(a[e].substring(0,g)));"H"==a[e][g]&&(d[1]=parseInt(a[e].substring(0,g)));"M"==a[e][g]&&(d[2]=parseInt(a[e].substring(0,g)))}Q("d25alarm_interval").value=d.join("-")}else Q("d25alarm_interval").value="";Q("d25alarm_doc").value=1==c.DeleteOnCompletion?1:0}else c=new Date,c.setDate((new Date).getDate()+1),Q("d25alarm_name").value="",Q("d25alarm_sdate").value=c.getFullYear()+"-"+_fmttimepad(c.getMonth()+1)+"-"+_fmttimepad(c.getDate()), Q("d25alarm_stime").value=c.getHours()+":"+_fmttimepad(c.getMinutes())+":00",Q("d25alarm_interval").value="",Q("d25alarm_doc").value=0;setDialogMode(25,"Add new alarm",void 0!=b?7:3,showAddAlarmOk,"",b);alertDialogUpdate()}}function alertDialogUpdate(){var b=Q("d25alarm_interval").value.split("-").length,b=0Verify the alarm is for a future time."):0!=c.Body.ReturnValue?messagebox("Add alarm","Failed to add alarm, "+c.Body.ReturnValueStr+".
    Verify the alarm is for a future time."):PullAlarms()}):(a=Clone(xxAlarms[c]), -a.StartTime=''+d+"",a.Interval=''+e+"",a.DeleteOnCompletion=q,amtstack.Put("IPS_AlarmClockOccurrence",a,function(a,b,c,d){200!=d?messagebox("Edit alarm","Failed to change alarm. Status: "+d+".
    Verify the alarm for at a future time."):PullAlarms()},null,null,{InstanceID:a.InstanceID}))}} +"P"+e[0]+"DT"+e[1]+"H"+e[2]+"M",g=1==Q("d25alarm_doc").value,a=prepareAlarmOccurenceTemplate(a,a,d,e,g);void 0==c?wsstack.ExecMethodXml(amtstack.CompleteName("AMT_AlarmClockService"),"AddAlarm",a,function(a,b,c,d){200!=d?messagebox("Add alarm","Failed to add alarm. Status: "+d+".
    Verify the alarm is for a future time."):0!=c.Body.ReturnValue?messagebox("Add alarm","Failed to add alarm, "+c.Body.ReturnValueStr+".
    Verify the alarm is for a future time."):PullAlarms()}):(a=Clone(xxAlarms[c]), +a.StartTime=''+d+"",a.Interval=''+e+"",a.DeleteOnCompletion=g,amtstack.Put("IPS_AlarmClockOccurrence",a,function(a,b,c,d){200!=d?messagebox("Edit alarm","Failed to change alarm. Status: "+d+".
    Verify the alarm for at a future time."):PullAlarms()},null,null,{InstanceID:a.InstanceID}))}} function showAlertDetails(b){if(!xxdialogMode){var c=xxAlarms[b],a=new Date(c.StartTime.Datetime),a="
    "+addHtmlValue("Name",c.ElementName)+addHtmlValue("Wake time",a.toLocaleString().replace(", "," at "));void 0!=c.Interval&&(a+=addHtmlValue("Internal",_fmtinterval(c.Interval.Interval)));a+=addHtmlValue("After wake",1==c.DeleteOnCompletion?"Delete Alarm":"Keep Alarm")+"
    ";messagebox("Alarm "+c.ElementName,a);setDialogMode(11,"Alarm "+c.ElementName,5,showAlertDetailsDelete, -a,b)}}function showAlertDetailsDelete(b,c){2==b&&amtstack.Delete("IPS_AlarmClockOccurrence",xxAlarms[c],function(a,b,c,q){PullAlarms()})}function script_runScriptDlg(){xxdialogMode||scriptstate||setDialogMode(11,"Run Script",3,script_runScriptDlgOk,"
    ")}function script_runScriptDlgOk(b){if(1==b&&(b=Q("scriptopen"),1==b.files.length)){var c=new FileReader;c.onload=script_onScriptRead;c.readAsBinaryString(b.files[0])}} +a,b)}}function showAlertDetailsDelete(b,c){2==b&&amtstack.Delete("IPS_AlarmClockOccurrence",xxAlarms[c],function(a,b,c,g){PullAlarms()})}function script_runScriptDlg(){xxdialogMode||scriptstate||setDialogMode(11,"Run Script",3,script_runScriptDlgOk,"
    ")}function script_runScriptDlgOk(b){if(1==b&&(b=Q("scriptopen"),1==b.files.length)){var c=new FileReader;c.onload=script_onScriptRead;c.readAsBinaryString(b.files[0])}} function script_onScriptRead(b){var c;try{c=JSON.parse(b.target.result)}catch(e){}if(20==currentView){c.scriptText&&(Q("scriptarea").value=c.scriptText);c.mescript&&(Q("compiledarea").value=rstr2hex(atob(c.mescript)));c.blocks?(script_setBuildBlocks(c.blocks),scriptViewButton(1)):(script_setBuildBlocks(),scriptViewButton(0));c.scriptBlocks?script_BlockScript=c.scriptBlocks:script_BuildingBlocks||(script_BlockScript=[]);for(var a in script_BlockScript)if(c=script_BlockScript[a],b=script_BuildingBlocks[c.xname]){b= Clone(b);b.id=c.id;b.xname=c.xname;for(var d in b.vars)c.vars[d]&&(b.vars[d].value=c.vars[d].value);script_BlockScript[a]=b}fupdatescript();delete scriptstate;resetScriptButton()}else a={_interactive:1,_certificates:1,_mode:"Firmware"},c&&c.mescript&&(scriptstate=script_setup(atob(c.mescript),a)),scriptstate?(scriptstate.wsstack=wsstack,scriptstate.amtstack=amtstack,scriptstate.onStep=script_updateScriptState,scriptstate.onConsole=script_console,scriptstate.start(100)):messagebox("Run Script","Invalid script file.")} function script_updateScriptState(){scriptstate&&(QV(11,0");QH("blocks",c);script_fonfilterchanged();scriptViewButton(script_BuildingBlocks?1:0)} function script_faddblock(b){var c=Clone(script_BuildingBlocks[b]);c.id=Math.random();c.xname=b;script_BlockScript.push(c);script_BlockScriptSelectedId=script_BlockScript.length-1;fupdatescript()}function script_feditblock(b){xxdialogMode||setDialogMode(11,"Edit "+script_BuildingBlocks[b].name,3,script_feditblockEx,"Edit this block? This operation will reset the block editor and load the block code into the code editor.",b)} -function script_feditblockEx(b,c){script_newScriptDlgOk();scriptViewButton(0);var a,d=script_BuildingBlocks[c];a=""+("##!BLOCK!##\r\n#id="+c+"\r\n#name="+d.name+"\r\n#desc="+d.desc+"\r\n##!BLOCK!##\r\n");for(var e in d.vars){var q=d.vars[e];a+="##!VAR!##\r\n#id="+e+"\r\n#name="+q.name+"\r\n#desc="+q.desc+"\r\n#type="+q.type+"\r\n";q.maxlength&&(a+="#maxlength="+q.maxlength+"\r\n");if(q.values)for(var k in q.values)a+="#values-"+k+"="+q.values[k]+"\r\n";a+="#value="+q.value+"\r\n##SWAP %%%"+e+"%%% "+ -q.value+"\r\n"}a+="##!VAR!##\r\n##SWAP %%%~%%% 0\r\n\r\n##!BLOCK!##\r\n"+d.code+"\r\n##!BLOCK!##\r\n";Q("scriptarea").value=a} -function script_fConvertScriptToJsonBlock(b){var c={};b=b.split("##!BLOCK!##\n");var a=b[1].split("\n"),d;for(d in a){var e=a[d].split("=");2==e.length&&(c[e[0].substring(1)]=e[1])}c.vars={};scriptvariables=b[2].split("##!VAR!##\n");for(d in scriptvariables){var a=scriptvariables[d].split("\n"),q={},k={},v=0,n;for(n in a)e=a[n].split("="),2==e.length&&e[1]&&e[0]&&0(new Date).getTime()-script_fonclickDblClickDetectTime)return script_foneditclick(script_BlockScriptSelectedId);script_fonclickDblClickDetectIndex=script_BlockScriptSelectedId;script_fonclickDblClickDetectTime=(new Date).getTime()}} function script_fondragstart(b,c){xxdialogMode||(c=fgetParentWithId(c),c.style.opacity="0.4",b.dataTransfer.effectAllowed="move",b.dataTransfer.setData("scriptbuilder/block",c.id))}function script_fondragend(b,c){xxdialogMode||(c=fgetParentWithId(c),c.style.opacity="1.0")}function script_fondragenter(b,c){xxdialogMode||(fgetParentWithId(c).style["border-top"]="solid 2px black")} function script_fondragleave(b,c){if(!xxdialogMode){b=b.originalEvent||b;var a=document.elementFromPoint(b.pageX,b.pageY);c.contains(a)||(fgetParentWithId(c).style["border-top"]="none")}} function script_fondrop(b,c){if(!xxdialogMode){c=fgetParentWithId(c);var a,d=b.dataTransfer.getData("scriptbuilder/block"),e=parseInt(c.id.substring(7));""==d?documentFileSelectHandler(b):(d.startsWith("sblock_")?(a=Clone(script_BuildingBlocks[d.substring(7)]),a.id=Math.random(),a.xname=d.substring(7)):(d=parseInt(d.substring(7)),a=script_BlockScript[d],script_BlockScript.splice(d,1),e>d&&e--),"scriptblocks"==c.id?(a&&script_BlockScript.push(a),script_BlockScriptSelectedId=script_BlockScript.length- 1):(script_BlockScript.splice(e,0,a),script_BlockScriptSelectedId=e),fupdatescript(),haltEvent(b))}} -function script_foneditclick(b){if(!xxdialogMode){var c=script_BlockScript[b];script_BlockScriptSelectedId=b;fupdatescript();if(null!=c){var a=c.vars?7:5,d=c.desc+"

    ";if(c.vars)for(var e in c.vars){var q=c.vars[e].value,k="";c.vars[e].maxlength&&(k+=" maxlength="+c.vars[e].maxlength);2==c.vars[e].type&&(k+=" onkeypress='return numbersOnly(event)'");if(1==c.vars[e].type||2==c.vars[e].type)q=""; -if(3==c.vars[e].type){var q=""}4==c.vars[e].type&&(q="");5==c.vars[e].type&&(q="");6==c.vars[e].type&&(q="");d+='
    '+c.vars[e].name+""+q+"
    ";if(5==c.vars[e].type){var d=d+("
      '),n;for(n in c.vars[e].values)q="",0<=c.vars[e].value.indexOf(n)&&(q=" checked"),d+="
    • ";d+="
    "}}}setDialogMode(11,c.name,a,script_foneditclickEx,d,b)}} -function script_foneditclickEx(b,c){if(!xxdialogMode){if(2==b)script_BlockScript.splice(c,1),script_BlockScriptSelectedId==c&&(script_BlockScriptSelectedId=null);else{var a=script_BlockScript[c];if(a.vars)for(var d in a.vars)if(5==a.vars[d].type){a.vars[d].value=[];for(var e in a.vars[d].values)Q("scriptXvaluex_"+d+"-"+e).checked&&a.vars[d].value.push(e)}else if(6==a.vars[d].type){var q=Q("scriptXvalue_"+d);if(1==q.files.length){var k=new FileReader;k.onload=function(b){a.vars[d].value=btoa(b.target.result); -fupdatescript()};k.readAsBinaryString(q.files[0])}}else a.vars[d].value=Q("scriptXvalue_"+d).value}fupdatescript()}}function fgetParentWithId(b){for(;!b.id;)b=b.parentElement;return b} +function script_foneditclick(b){if(!xxdialogMode){var c=script_BlockScript[b];script_BlockScriptSelectedId=b;fupdatescript();if(null!=c){var a=c.vars?7:5,d=c.desc+"

    ";if(c.vars)for(var e in c.vars){var g=c.vars[e].value,l="";c.vars[e].maxlength&&(l+=" maxlength="+c.vars[e].maxlength);2==c.vars[e].type&&(l+=" onkeypress='return numbersOnly(event)'");if(1==c.vars[e].type||2==c.vars[e].type)g=""; +if(3==c.vars[e].type){var g=""}4==c.vars[e].type&&(g="");5==c.vars[e].type&&(g="");6==c.vars[e].type&&(g="");d+='
    '+c.vars[e].name+""+g+"
    ";if(5==c.vars[e].type){var d=d+("
      '),p;for(p in c.vars[e].values)g="",0<=c.vars[e].value.indexOf(p)&&(g=" checked"),d+="
    • ";d+="
    "}}}setDialogMode(11,c.name,a,script_foneditclickEx,d,b)}} +function script_foneditclickEx(b,c){if(!xxdialogMode){if(2==b)script_BlockScript.splice(c,1),script_BlockScriptSelectedId==c&&(script_BlockScriptSelectedId=null);else{var a=script_BlockScript[c];if(a.vars)for(var d in a.vars)if(5==a.vars[d].type){a.vars[d].value=[];for(var e in a.vars[d].values)Q("scriptXvaluex_"+d+"-"+e).checked&&a.vars[d].value.push(e)}else if(6==a.vars[d].type){var g=Q("scriptXvalue_"+d);if(1==g.files.length){var l=new FileReader;l.onload=function(b){a.vars[d].value=btoa(b.target.result); +fupdatescript()};l.readAsBinaryString(g.files[0])}}else a.vars[d].value=Q("scriptXvalue_"+d).value}fupdatescript()}}function fgetParentWithId(b){for(;!b.id;)b=b.parentElement;return b} function fupdatescript(){var b="",c;for(c in script_BlockScript){b+="
    "+script_BlockScript[c].name+"";if(script_BlockScript[c].vars){var a=0,b=b+"",d;for(d in script_BlockScript[c].vars){var e=script_BlockScript[c].vars[d].value;4==script_BlockScript[c].vars[d].type&&0

    "+script_BlockScript[c].vars[d].name+"

    "+e;a++}b+="
    "}b+= @@ -1351,16 +1353,16 @@ function editscript_updateScriptState(b){var c="";if(b&&null!=b){var a=[],d;for( 50)+"...");QH("EditScriptStatus",c)}function script_toString(b){return"object"==typeof b?JSON.stringify(b):b} function script_saveScript(b){xxdialogMode||scriptstate||(b&&1==b.shiftKey?(setDialogMode(11,"Script Block",1,null,"