/* package whatever; // don't place package name! */
import javafx.concurrent.Task ;
import javafx.event.ActionEvent ;
import java.sql.Connection ;
import java.sql.DriverManager ;
import java.sql.SQLException ;
import java.sql.Statement ;
import java.sql.ResultSet ;
import static com.Ostermiller .util .StringHelper .escapeSQL ;
import static java.
lang .
Math .
abs ;
public class ResultsReader extends Task< Integer>
{
// User settings - adjust for best perfromance
private static int NumberOfResultsThreads = 10 ;
private static int NumberOfResultsContactsToProcessPerThread = 1000 ;
private static int NumberOfRecordsToInsertAtATime = 100 ;
private static String TypeMask
= "1,2,3,5" ; private static String RemoteUser
= "myusername" ; private static String RemotePass
= "mypassword" ; private static String MainUser
= "MainUser" ; private static String MainPass
= "MainPassword" ;
// Alllows different systems to use the same RXDialers
private static int ESID = - 15 ;
private int CurrModValue;
/*private String CurrRemoteIPAddress1 = "aa.aa.a.aaa";
private String CurrRemoteIPAddress2 = "bb.bb.b.bbb";
private String CurrRemoteIPAddress3 = "cc.cc.c.ccc";
private String CurrRemoteIPAddress4 = "dd.dd.d.ddd";
private String CurrRemoteIPAddress5 = "ee.ee.e.eee";
private String CurrRemoteIPAddress6 = "ff.ff.f.fff";
private String CurrRemoteIPAddress7 = "gg.gg.g.ggg";*/
// Task local reference to the controller class to call back to when complete
private EBMExtractorFXMLController QRVC;
public void setQDVC( EBMExtractorFXMLController QRVC)
{
this .QRVC = QRVC;
}
public EBMExtractorFXMLController getQDVC( )
{
return QRVC;
}
public ResultsReader( int CurrModValue)
{
this .CurrModValue = CurrModValue;
}
public void act_StartProcessing( )
{
}
public void act_StopProcessing( )
{
this .cancel ( ) ;
}
{
int iterations = 0 ;
int i = 0 ;
boolean done = false ;
while ( ! done) {
try
{
//Connection connMain = DriverManager.getConnection("jdbc:mysql://" + CurrRemoteIPAddress + ":3306/test",RemoteUser,RemotePass);
RemoteIPAddress[ 0 ] = "aa.aa.a.aaa" ;
RemoteIPAddress[ 1 ] = "bb.bb.b.bbb" ;
RemoteIPAddress[ 2 ] = "cc.cc.c.ccc" ;
RemoteIPAddress[ 3 ] = "dd.dd.d.ddd" ;
RemoteIPAddress[ 4 ] = "ee.ee.e.eee" ;
RemoteIPAddress[ 5 ] = "ff.ff.f.fff" ;
RemoteIPAddress[ 6 ] = "gg.gg.g.ggg" ;
MainConnection
[ 0 ] = DriverManager .
getConnection ( "jdbc:mysql://" + RemoteIPAddress
[ 0 ] + ":3306/test" ,RemoteUser,RemotePass
) ; MainConnection
[ 1 ] = DriverManager .
getConnection ( "jdbc:mysql://" + RemoteIPAddress
[ 1 ] + ":3306/test" ,RemoteUser,RemotePass
) ; MainConnection
[ 2 ] = DriverManager .
getConnection ( "jdbc:mysql://" + RemoteIPAddress
[ 2 ] + ":3306/test" ,RemoteUser,RemotePass
) ; MainConnection
[ 3 ] = DriverManager .
getConnection ( "jdbc:mysql://" + RemoteIPAddress
[ 3 ] + ":3306/test" ,RemoteUser,RemotePass
) ; MainConnection
[ 4 ] = DriverManager .
getConnection ( "jdbc:mysql://" + RemoteIPAddress
[ 4 ] + ":3306/test" ,RemoteUser,RemotePass
) ; MainConnection
[ 5 ] = DriverManager .
getConnection ( "jdbc:mysql://" + RemoteIPAddress
[ 5 ] + ":3306/test" ,RemoteUser,RemotePass
) ; MainConnection
[ 6 ] = DriverManager .
getConnection ( "jdbc:mysql://" + RemoteIPAddress
[ 6 ] + ":3306/test" ,RemoteUser,RemotePass
) ;
String QueryString
= " SELECT " + " RXCallDetailId_int, "
+ " DTSID_int, "
+ " CallDetailsStatusId_ti, "
+ " BatchId_bi, "
+ " PhoneId_int, "
+ " TotalObjectTime_int, "
+ " TotalCallTimeLiveTransfer_int, "
+ " TotalCallTime_int, "
+ " TotalAnswerTime_int, "
+ " UserSpecifiedLineNumber_si, "
+ " NumberOfHoursToRescheduleRedial_si, "
+ " TransferStatusId_ti, "
+ " IsHangUpDetected_ti, "
+ " IsOptOut_ti, "
+ " IsMaxRedialsReached_ti, "
+ " IsRescheduled_ti, "
+ " CallResult_int, "
+ " SixSecondBilling_int, "
+ " SystemBilling_int, "
+ " RXCDLStartTime_dt, "
+ " CallStartTime_dt, "
+ " CallEndTime_dt, "
+ " CallStartTimeLiveTransfer_dt, "
+ " CallEndTimeLiveTransfer_dt, "
+ " CallResultTS_dt, "
+ " PlayFileStartTime_dt, "
+ " PlayFileEndTime_dt, "
+ " HangUpDetectedTS_dt, "
+ " Created_dt, "
+ " DialerName_vch, "
+ " CurrTS_vch, "
+ " CurrVoice_vch, "
+ " CurrTSLiveTransfer_vch, "
+ " CurrVoiceLiveTransfer_vch, "
+ " CurrCDP_vch, "
+ " CurrCDPLiveTransfer_vch, "
+ " DialString_vch, "
+ " RedialNumber_int, "
+ " TimeZone_ti, "
+ " MessageDelivered_si, "
+ " SingleResponseSurvey_si, "
+ " ReplayTotalCallTime_int, "
+ " XMLResultStr_vch, "
+ " TotalConnectTime_int, "
+ " IsOptIn_ti, "
+ " FileSeqNumber_int, "
+ " UserSpecifiedData_vch, "
+ " XMLControlString_vch, "
+ " DTS_UUID_vch, "
+ " MainMessageLengthSeconds_int "
+ " FROM "
+ " calldetail.rxcalldetails_test "
+ " WHERE "
+ " CallDetailsStatusId_ti = " + ESID
+ " AND RXCallDetailId_int MOD " + NumberOfResultsThreads + " = " + CurrModValue
+ " ORDER BY RXCallDetailId_int ASC "
+ " LIMIT " + NumberOfResultsContactsToProcessPerThread ;
//SelectResultsStmt = connMain.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
SelectResultsStmt
= MainConnection
[ i
] .
createStatement ( ResultSet .
TYPE_SCROLL_SENSITIVE ,
ResultSet .
CONCUR_UPDATABLE ) ; SelectResultsRS = SelectResultsStmt.executeQuery ( QueryString) ;
int CurrentBillingAmount = 0 ;
int CurrentRowCount = 0 ;
String QueryStringInsertFromRemote
= "" ;
// Now do something with the ResultSet ....
while ( SelectResultsRS.
next ( ) && ! Thread .
interrupted ( ) ) { // While SelectResultsRS
CurrentRowCount++;
// Allow thread to be canceled
if ( isCancelled( ) )
{
// Do any additional clean up here - maybe update main DB of non-processed?
updateMessage( "Cancelled" ) ;
break ;
}
// When a progress is bound (.bind()) to this task - this will update the progress meter
updateProgress( SelectResultsRS.getRow ( ) , NumberOfResultsContactsToProcessPerThread) ;
updateMessage( "Thread " + CurrModValue + " " + SelectResultsRS.getInt ( "DTSId_int" ) ) ;
// Get Billing amount - need billing method in JAVA
CurrentBillingAmount = 0 ;
// System.out.println(SelectResultsRS.getInt("DTSId_int"));
QueryStringInsertFromRemote = " INSERT INTO SimpleXResults.ContactResults_test "
+ " ( "
+ " MasterRXCallDetailId_int, "
+ " RXCallDetailId_int, "
+ " DTSID_int, "
+ " BatchId_bi, "
+ " PhoneId_int, "
+ " TotalObjectTime_int, "
+ " TotalCallTimeLiveTransfer_int, "
+ " TotalCallTime_int, "
+ " TotalConnectTime_int, "
+ " ReplayTotalCallTime_int, "
+ " TotalAnswerTime_int, "
+ " UserSpecifiedLineNumber_si, "
+ " NumberOfHoursToRescheduleRedial_si, "
+ " TransferStatusId_ti, "
+ " IsHangUpDetected_ti, "
+ " IsOptOut_ti, "
+ " IsMaxRedialsReached_ti, "
+ " IsRescheduled_ti, "
+ " CallResult_int, "
+ " SixSecondBilling_int, "
+ " SystemBilling_int, "
+ " RXCDLStartTime_dt, "
+ " CallStartTime_dt, "
+ " CallEndTime_dt, "
+ " CallStartTimeLiveTransfer_dt, "
+ " CallEndTimeLiveTransfer_dt, "
+ " CallResultTS_dt, "
+ " PlayFileStartTime_dt, "
+ " PlayFileEndTime_dt, "
+ " HangUpDetectedTS_dt, "
+ " Created_dt, "
+ " DialerName_vch, "
+ " DialerIP_vch, "
+ " CurrTS_vch, "
+ " CurrVoice_vch, "
+ " CurrTSLiveTransfer_vch, "
+ " CurrVoiceLiveTransfer_vch, "
+ " CurrCDP_vch, "
+ " CurrCDPLiveTransfer_vch, "
+ " ContactString_vch, "
+ " RedialNumber_int, "
+ " TimeZone_ti, "
+ " MessageDelivered_si, "
+ " SingleResponseSurvey_si, "
+ " XMLResultStr_vch, "
+ " IsOptIn_ti, "
+ " ActualCost_int, "
+ " DTS_UUID_vch, "
+ " XMLControlString_vch, "
+ " UserSpecifiedData_vch, "
+ " FileSeqNumber_int, "
+ " MainMessageLengthSeconds_int "
+ " ) "
+ " VALUES "
+ " ( "
+ " NULL, "
+ " " + SelectResultsRS.getInt ( "RXCallDetailId_int" ) + ", " // #ExtractFromDialer.RXCallDetailId_int#,
+ " " + SelectResultsRS.getInt ( "DTSID_int" ) + ", " //#ExtractFromDialer.DTSID_int#,
+ " " + SelectResultsRS.getInt ( "BatchId_bi" ) + ", " //#ExtractFromDialer.BatchId_bi#,
+ " " + SelectResultsRS.getInt ( "PhoneId_int" ) + ", " //#ExtractFromDialer.PhoneId_int#,
+ " " + SelectResultsRS.getInt ( "TotalObjectTime_int" ) + ", " //#ExtractFromDialer.TotalObjectTime_int#,
+ " " + SelectResultsRS.getInt ( "TotalCallTimeLiveTransfer_int" ) + ", " //#ExtractFromDialer.TotalCallTimeLiveTransfer_int#,
+ " " + SelectResultsRS.getInt ( "TotalCallTime_int" ) + ", " //#ExtractFromDialer.TotalCallTime_int#,
+ " " + SelectResultsRS.getInt ( "TotalConnectTime_int" ) + ", " //#ExtractFromDialer.TotalConnectTime_int#,
+ " " + SelectResultsRS.getInt ( "ReplayTotalCallTime_int" ) + ", " //#ExtractFromDialer.ReplayTotalCallTime_int#,
+ " " + SelectResultsRS.getInt ( "TotalAnswerTime_int" ) + ", " //#ExtractFromDialer.TotalAnswerTime_int#,
+ " " + SelectResultsRS.getInt ( "UserSpecifiedLineNumber_si" ) + ", " //#ExtractFromDialer.UserSpecifiedLineNumber_si#,
+ " " + SelectResultsRS.getInt ( "NumberOfHoursToRescheduleRedial_si" ) + ", " //#ExtractFromDialer.NumberOfHoursToRescheduleRedial_si#,
+ " " + SelectResultsRS.getInt ( "TransferStatusId_ti" ) + ", " //#ExtractFromDialer.TransferStatusId_ti#,
+ " " + SelectResultsRS.getInt ( "IsHangUpDetected_ti" ) + ", " //#ExtractFromDialer.IsHangUpDetected_ti#,
+ " " + SelectResultsRS.getInt ( "IsOptOut_ti" ) + ", " //#ExtractFromDialer.IsOptOut_ti#,
+ " " + SelectResultsRS.getInt ( "IsMaxRedialsReached_ti" ) + ", " //#ExtractFromDialer.IsMaxRedialsReached_ti#,
+ " " + SelectResultsRS.getInt ( "IsRescheduled_ti" ) + ", " //#ExtractFromDialer.IsRescheduled_ti#,
+ " " + SelectResultsRS.getInt ( "CallResult_int" ) + ", " //#ExtractFromDialer.CallResult_int#,
+ " " + SelectResultsRS.getInt ( "SixSecondBilling_int" ) + ", " //#ExtractFromDialer.SixSecondBilling_int#,
+ " " + SelectResultsRS.getInt ( "SystemBilling_int" ) + ", " //#ExtractFromDialer.SystemBilling_int#,
+ " '" + SelectResultsRS.getString ( "RXCDLStartTime_dt" ) + "', " //'#ExtractFromDialer.RXCDLStartTime_dt#',
+ " '" + SelectResultsRS.getString ( "CallStartTime_dt" ) + "', " //'#ExtractFromDialer.CallStartTime_dt#',
+ " '" + SelectResultsRS.getString ( "CallEndTime_dt" ) + "', " //'#ExtractFromDialer.CallEndTime_dt#',
+ " '" + SelectResultsRS.getString ( "CallStartTimeLiveTransfer_dt" ) + "', " //'#ExtractFromDialer.CallStartTimeLiveTransfer_dt#',
+ " '" + SelectResultsRS.getString ( "CallEndTimeLiveTransfer_dt" ) + "', " //'#ExtractFromDialer.CallEndTimeLiveTransfer_dt#',
+ " '" + SelectResultsRS.getString ( "CallResultTS_dt" ) + "', " //'#ExtractFromDialer.CallResultTS_dt#',
+ " '" + SelectResultsRS.getString ( "PlayFileStartTime_dt" ) + "', " //'#ExtractFromDialer.PlayFileStartTime_dt#',
+ " '" + SelectResultsRS.getString ( "PlayFileEndTime_dt" ) + "', " //'#ExtractFromDialer.PlayFileEndTime_dt#',
+ " '" + SelectResultsRS.getString ( "HangUpDetectedTS_dt" ) + "', " //'#ExtractFromDialer.HangUpDetectedTS_dt#',
+ " '" + SelectResultsRS.getString ( "Created_dt" ) + "', " //'#ExtractFromDialer.Created_dt#',
+ " '" + SelectResultsRS.getString ( "DialerName_vch" ) + "', " //'#ExtractFromDialer.DialerName_vch#',
+ " '" + RemoteIPAddress[ i] + "', " //'#inpDialerIPAddr#',
+ " '" + SelectResultsRS.getString ( "CurrTS_vch" ) + "', " //'#ExtractFromDialer.CurrTS_vch#',
+ " '" + SelectResultsRS.getString ( "CurrVoice_vch" ) + "', " //'#ExtractFromDialer.CurrVoice_vch#',
+ " '" + SelectResultsRS.getString ( "CurrTSLiveTransfer_vch" ) + "', " //'#ExtractFromDialer.CurrTSLiveTransfer_vch#',
+ " '" + SelectResultsRS.getString ( "CurrVoiceLiveTransfer_vch" ) + "', " //'#ExtractFromDialer.CurrVoiceLiveTransfer_vch#',
+ " '" + SelectResultsRS.getString ( "CurrCDP_vch" ) + "', " //'#ExtractFromDialer.CurrCDP_vch#',
+ " '" + SelectResultsRS.getString ( "CurrCDPLiveTransfer_vch" ) + "', " //'#ExtractFromDialer.CurrCDPLiveTransfer_vch#',
+ " '" + escapeSQL( SelectResultsRS.getString ( "DialString_vch" ) ) + "', " //'#ExtractFromDialer.DialString_vch#',
+ " " + SelectResultsRS.getInt ( "RedialNumber_int" ) + ", " //#ExtractFromDialer.RedialNumber_int#,
+ " " + SelectResultsRS.getInt ( "TimeZone_ti" ) + ", " //#ExtractFromDialer.TimeZone_ti#,
+ " " + SelectResultsRS.getInt ( "MessageDelivered_si" ) + ", " //#ExtractFromDialer.MessageDelivered_si#,
+ " " + SelectResultsRS.getInt ( "SingleResponseSurvey_si" ) + ", " //#ExtractFromDialer.SingleResponseSurvey_si#,
+ " '" + escapeSQL( SelectResultsRS.getString ( "XMLResultStr_vch" ) ) + "', " //<CFQUERYPARAM CFSQLTYPE="CF_SQL_VARCHAR" VALUE="#ExtractFromDialer.XMLResultStr_vch#">,
+ " " + SelectResultsRS.getInt ( "IsOptIn_ti" ) + ", " //#ExtractFromDialer.IsOptIn_ti#,
+ " " + CurrentBillingAmount + ", " //#CurrentBillingAmount#,
+ " '" + SelectResultsRS.getString ( "DTS_UUID_vch" ) + "', " //'#ExtractFromDialer.DTS_UUID_vch#',
+ " '" + escapeSQL( SelectResultsRS.getString ( "XMLControlString_vch" ) ) + "', " // <CFQUERYPARAM CFSQLTYPE="CF_SQL_VARCHAR" VALUE="#ExtractFromDialer.XMLControlString_vch#">,
+ " '" + escapeSQL( SelectResultsRS.getString ( "UserSpecifiedData_vch" ) ) + "', " // <CFQUERYPARAM CFSQLTYPE="CF_SQL_VARCHAR" VALUE="#ExtractFromDialer.UserSpecifiedData_vch#">,
+ " " + SelectResultsRS.getInt ( "FileSeqNumber_int" ) + ", " // <cfif ExtractFromDialer.FileSeqNumber_int NEQ "">#ExtractFromDialer.FileSeqNumber_int#<cfelse>NULL</cfif>,
+ " " + SelectResultsRS.getInt ( "MainMessageLengthSeconds_int" ) + " " //#ExtractFromDialer.MainMessageLengthSeconds_int#
+ " ) " ;
SelectResultsRS.updateInt ( "CallDetailsStatusId_ti" , abs( ESID) ) ;
InsertRemoteResultsStmt = connRemote.createStatement ( ) ;
InsertRemoteResultsStmt.executeUpdate ( QueryStringInsertFromRemote) ;
// reset string to empty
QueryStringInsertFromRemote = "" ;
SelectResultsRS.updateRow ( ) ;
} // While SelectResultsRS
// Execute Insert on any remainging records
if ( QueryStringInsertFromRemote.length ( ) > 0 )
{
InsertRemoteResultsStmt = connRemote.createStatement ( ) ;
InsertRemoteResultsStmt.executeUpdate ( QueryStringInsertFromRemote) ;
QueryStringInsertFromRemote = "" ;
SelectResultsRS.updateRow ( ) ;
}
if ( CurrentRowCount == 0 )
{
// Write to log that there was nothing to process
System .
out .
println ( "No results found this loop" ) ;
// Only sleep while listening for cancel task/thread calls
try
{
}
{
if ( isCancelled( ) )
{
System .
out .
println ( "QRC Cancelled" ) ; // break;
}
}
}
done = true ;
}
{
// handle any errors
System .
out .
println ( "SQLException: " + ex.
getMessage ( ) ) ; System .
out .
println ( "SQLState: " + ex.
getSQLState ( ) ) ; System .
out .
println ( "VendorError: " + ex.
getErrorCode ( ) ) ; i++;
}
finally
{
// it is a good idea to release
// resources in a finally{} block
// in reverse-order of their creation
// if they are no-longer needed
if ( SelectResultsRS != null )
{
try
{
SelectResultsRS.close ( ) ;
}
{
} // ignore
SelectResultsRS = null ;
}
if ( SelectResultsStmt != null )
{
try
{
SelectResultsStmt.close ( ) ;
}
{
} // ignore
SelectResultsStmt = null ;
}
if ( UpdateResultsStmt != null )
{
try
{
UpdateResultsStmt.close ( ) ;
}
{
} // ignore
UpdateResultsStmt = null ;
}
if ( InsertRemoteResultsStmt != null )
{
try
{
InsertRemoteResultsStmt.close ( ) ;
}
{
} // ignore
InsertRemoteResultsStmt = null ;
}
}
QRVC.ResultsReaderCallBackonComplete ( CurrModValue) ;
return iterations;
}
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKCmltcG9ydCBqYXZhZnguY29uY3VycmVudC5UYXNrOwppbXBvcnQgamF2YWZ4LmV2ZW50LkFjdGlvbkV2ZW50OwoKaW1wb3J0IGphdmEuc3FsLkNvbm5lY3Rpb247CmltcG9ydCBqYXZhLnNxbC5Ecml2ZXJNYW5hZ2VyOwppbXBvcnQgamF2YS5zcWwuU1FMRXhjZXB0aW9uOwppbXBvcnQgamF2YS5zcWwuU3RhdGVtZW50OwppbXBvcnQgamF2YS5zcWwuUmVzdWx0U2V0OwoKCgppbXBvcnQgc3RhdGljIGNvbS5Pc3Rlcm1pbGxlci51dGlsLlN0cmluZ0hlbHBlci5lc2NhcGVTUUw7CmltcG9ydCBzdGF0aWMgamF2YS5sYW5nLk1hdGguYWJzOwoKICAgICAgIAogICAgICAgIAogcHVibGljIGNsYXNzIFJlc3VsdHNSZWFkZXIgZXh0ZW5kcyBUYXNrPEludGVnZXI+IAogewogICAgICAgIC8vIFVzZXIgc2V0dGluZ3MgLSBhZGp1c3QgZm9yIGJlc3QgcGVyZnJvbWFuY2UgCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgaW50IE51bWJlck9mUmVzdWx0c1RocmVhZHMgPSAxMDsKICAgICAgICBwcml2YXRlIHN0YXRpYyBpbnQgTnVtYmVyT2ZSZXN1bHRzQ29udGFjdHNUb1Byb2Nlc3NQZXJUaHJlYWQgPSAxMDAwOwogICAgICAgIHByaXZhdGUgc3RhdGljIGludCBOdW1iZXJPZlJlY29yZHNUb0luc2VydEF0QVRpbWUgPSAxMDA7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIFR5cGVNYXNrID0gIjEsMiwzLDUiOwogICAgICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBSZW1vdGVVc2VyID0gIm15dXNlcm5hbWUiOwogICAgICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBSZW1vdGVQYXNzID0gIm15cGFzc3dvcmQiOwogICAgICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBNYWluVXNlciA9ICJNYWluVXNlciI7CiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgU3RyaW5nIE1haW5QYXNzID0gIk1haW5QYXNzd29yZCI7CiAgICAgICAgCiAgICAgICAgLy8gQWxsbG93cyBkaWZmZXJlbnQgc3lzdGVtcyB0byB1c2UgdGhlIHNhbWUgUlhEaWFsZXJzCiAgICAgICAgcHJpdmF0ZSBzdGF0aWMgaW50IEVTSUQgPSAtMTU7CiAgICAgICAgCiAgICAgICAgCiAgICAgICAgcHJpdmF0ZSBpbnQgQ3Vyck1vZFZhbHVlOwogICAgICAgIHByaXZhdGUgc3RhdGljIFN0cmluZyBJUFtdOwogICAgICAgIC8qcHJpdmF0ZSBTdHJpbmcgQ3VyclJlbW90ZUlQQWRkcmVzczEgPSAiYWEuYWEuYS5hYWEiOwogICAgICAgIHByaXZhdGUgU3RyaW5nIEN1cnJSZW1vdGVJUEFkZHJlc3MyID0gImJiLmJiLmIuYmJiIjsKICAgICAgICBwcml2YXRlIFN0cmluZyBDdXJyUmVtb3RlSVBBZGRyZXNzMyA9ICJjYy5jYy5jLmNjYyI7CiAgICAgICAgcHJpdmF0ZSBTdHJpbmcgQ3VyclJlbW90ZUlQQWRkcmVzczQgPSAiZGQuZGQuZC5kZGQiOwogICAgICAgIHByaXZhdGUgU3RyaW5nIEN1cnJSZW1vdGVJUEFkZHJlc3M1ID0gImVlLmVlLmUuZWVlIjsKICAgICAgICBwcml2YXRlIFN0cmluZyBDdXJyUmVtb3RlSVBBZGRyZXNzNiA9ICJmZi5mZi5mLmZmZiI7CiAgICAgICAgcHJpdmF0ZSBTdHJpbmcgQ3VyclJlbW90ZUlQQWRkcmVzczcgPSAiZ2cuZ2cuZy5nZ2ciOyovCiAgICAgICAgCiAgICAgICAgLy8gVGFzayBsb2NhbCByZWZlcmVuY2UgdG8gdGhlIGNvbnRyb2xsZXIgY2xhc3MgdG8gY2FsbCBiYWNrIHRvIHdoZW4gY29tcGxldGUgICAgICAgCiAgICAgICAgcHJpdmF0ZSBFQk1FeHRyYWN0b3JGWE1MQ29udHJvbGxlciBRUlZDOwogICAgICAgIAogICAgICAgIHB1YmxpYyB2b2lkIHNldFFEVkMoRUJNRXh0cmFjdG9yRlhNTENvbnRyb2xsZXIgUVJWQykKICAgICAgICB7CiAgICAgICAgICAgdGhpcy5RUlZDID0gUVJWQzsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBFQk1FeHRyYWN0b3JGWE1MQ29udHJvbGxlciBnZXRRRFZDKCkKICAgICAgICB7CiAgICAgICAgICAgICAgIHJldHVybiBRUlZDOwogICAgICAgIH0KICAKICAgIAogICAgCiAgICAgICAgcHVibGljIFJlc3VsdHNSZWFkZXIoaW50IEN1cnJNb2RWYWx1ZSkgCiAgICAgICAgewogICAgICAgICAgICB0aGlzLkN1cnJNb2RWYWx1ZSA9IEN1cnJNb2RWYWx1ZTsKICAgICAgICB9CiAgICAgICAgIAogICAgICAgIHB1YmxpYyB2b2lkIGFjdF9TdGFydFByb2Nlc3NpbmcoKSAKICAgICAgICB7CiAgICAgICAgICAgIG5ldyBUaHJlYWQodGhpcykuc3RhcnQoKTsKCiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBhY3RfU3RvcFByb2Nlc3NpbmcoKSAKICAgICAgICB7CiAgICAgICAgICAgIHRoaXMuY2FuY2VsKCk7ICAgICAgICAgICAgICAgICAgCiAgICAgICAgfQogICAgICAKICAgICAgICAgICAgICAgCgogICAgICAgICBAT3ZlcnJpZGUgcHJvdGVjdGVkIEludGVnZXIgY2FsbCgpIHRocm93cyBFeGNlcHRpb24gCiAgICAgICAgIHsKICAgICAgICAgICAgaW50IGl0ZXJhdGlvbnMgPSAwOwogICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICBpbnQgaSA9IDA7CiAgICAgICAgICAgIGJvb2xlYW4gZG9uZSA9IGZhbHNlOyAKICAgICAgICAgICAKICAgICAgICAgICAgU3RhdGVtZW50IFNlbGVjdFJlc3VsdHNTdG10ID0gbnVsbDsKICAgICAgICAgICAgU3RhdGVtZW50IFVwZGF0ZVJlc3VsdHNTdG10ID0gbnVsbDsKICAgICAgICAgICAgU3RhdGVtZW50IEluc2VydFJlbW90ZVJlc3VsdHNTdG10ID0gbnVsbDsKICAgICAgICAgICAgUmVzdWx0U2V0IFNlbGVjdFJlc3VsdHNSUyA9IG51bGw7CgogICAgICAgICAgICB3aGlsZSghZG9uZSkgewogICAgICAgICAgICB0cnkgCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8vQ29ubmVjdGlvbiBjb25uTWFpbiA9IERyaXZlck1hbmFnZXIuZ2V0Q29ubmVjdGlvbigiamRiYzpteXNxbDovLyIgKyBDdXJyUmVtb3RlSVBBZGRyZXNzICsgIjozMzA2L3Rlc3QiLFJlbW90ZVVzZXIsUmVtb3RlUGFzcyk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIENvbm5lY3Rpb25bXSBNYWluQ29ubmVjdGlvbiA9IG5ldyBDb25uZWN0aW9uWzddOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBTdHJpbmdbXSBSZW1vdGVJUEFkZHJlc3MgPSBuZXcgU3RyaW5nWzddOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBSZW1vdGVJUEFkZHJlc3NbMF0gPSAiYWEuYWEuYS5hYWEiOwogICAgICAgICAgICAgICAgUmVtb3RlSVBBZGRyZXNzWzFdID0gImJiLmJiLmIuYmJiIjsKICAgICAgICAgICAgICAgIFJlbW90ZUlQQWRkcmVzc1syXSA9ICJjYy5jYy5jLmNjYyI7CiAgICAgICAgICAgICAgICBSZW1vdGVJUEFkZHJlc3NbM10gPSAiZGQuZGQuZC5kZGQiOwogICAgICAgICAgICAgICAgUmVtb3RlSVBBZGRyZXNzWzRdID0gImVlLmVlLmUuZWVlIjsKICAgICAgICAgICAgICAgIFJlbW90ZUlQQWRkcmVzc1s1XSA9ICJmZi5mZi5mLmZmZiI7CiAgICAgICAgICAgICAgICBSZW1vdGVJUEFkZHJlc3NbNl0gPSAiZ2cuZ2cuZy5nZ2ciOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBNYWluQ29ubmVjdGlvblswXSAgPSBEcml2ZXJNYW5hZ2VyLmdldENvbm5lY3Rpb24oImpkYmM6bXlzcWw6Ly8iICsgUmVtb3RlSVBBZGRyZXNzWzBdICsgIjozMzA2L3Rlc3QiLFJlbW90ZVVzZXIsUmVtb3RlUGFzcyk7CiAgICAgICAgICAgICAgICBNYWluQ29ubmVjdGlvblsxXSAgPSBEcml2ZXJNYW5hZ2VyLmdldENvbm5lY3Rpb24oImpkYmM6bXlzcWw6Ly8iICsgUmVtb3RlSVBBZGRyZXNzWzFdICsgIjozMzA2L3Rlc3QiLFJlbW90ZVVzZXIsUmVtb3RlUGFzcyk7CiAgICAgICAgICAgICAgICBNYWluQ29ubmVjdGlvblsyXSAgPSBEcml2ZXJNYW5hZ2VyLmdldENvbm5lY3Rpb24oImpkYmM6bXlzcWw6Ly8iICsgUmVtb3RlSVBBZGRyZXNzWzJdICsgIjozMzA2L3Rlc3QiLFJlbW90ZVVzZXIsUmVtb3RlUGFzcyk7CiAgICAgICAgICAgICAgICBNYWluQ29ubmVjdGlvblszXSAgPSBEcml2ZXJNYW5hZ2VyLmdldENvbm5lY3Rpb24oImpkYmM6bXlzcWw6Ly8iICsgUmVtb3RlSVBBZGRyZXNzWzNdICsgIjozMzA2L3Rlc3QiLFJlbW90ZVVzZXIsUmVtb3RlUGFzcyk7CiAgICAgICAgICAgICAgICBNYWluQ29ubmVjdGlvbls0XSAgPSBEcml2ZXJNYW5hZ2VyLmdldENvbm5lY3Rpb24oImpkYmM6bXlzcWw6Ly8iICsgUmVtb3RlSVBBZGRyZXNzWzRdICsgIjozMzA2L3Rlc3QiLFJlbW90ZVVzZXIsUmVtb3RlUGFzcyk7CiAgICAgICAgICAgICAgICBNYWluQ29ubmVjdGlvbls1XSAgPSBEcml2ZXJNYW5hZ2VyLmdldENvbm5lY3Rpb24oImpkYmM6bXlzcWw6Ly8iICsgUmVtb3RlSVBBZGRyZXNzWzVdICsgIjozMzA2L3Rlc3QiLFJlbW90ZVVzZXIsUmVtb3RlUGFzcyk7CiAgICAgICAgICAgICAgICBNYWluQ29ubmVjdGlvbls2XSAgPSBEcml2ZXJNYW5hZ2VyLmdldENvbm5lY3Rpb24oImpkYmM6bXlzcWw6Ly8iICsgUmVtb3RlSVBBZGRyZXNzWzZdICsgIjozMzA2L3Rlc3QiLFJlbW90ZVVzZXIsUmVtb3RlUGFzcyk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIENvbm5lY3Rpb24gY29ublJlbW90ZSA9IERyaXZlck1hbmFnZXIuZ2V0Q29ubmVjdGlvbigiamRiYzpteXNxbDovL3h4Lnh4LngueHh4OjMzMDYvdGVzdCIsTWFpblVzZXIsTWFpblBhc3MpOyAKICAgICAgICAgICAgICAgICAKCiAgICAgICAgICAgICAgICBTdHJpbmcgUXVlcnlTdHJpbmcgPSAgICAgICIgU0VMRUNUICIgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBSWENhbGxEZXRhaWxJZF9pbnQsICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgRFRTSURfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIENhbGxEZXRhaWxzU3RhdHVzSWRfdGksICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgQmF0Y2hJZF9iaSwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBQaG9uZUlkX2ludCwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBUb3RhbE9iamVjdFRpbWVfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIFRvdGFsQ2FsbFRpbWVMaXZlVHJhbnNmZXJfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIFRvdGFsQ2FsbFRpbWVfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIFRvdGFsQW5zd2VyVGltZV9pbnQsICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgVXNlclNwZWNpZmllZExpbmVOdW1iZXJfc2ksICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgTnVtYmVyT2ZIb3Vyc1RvUmVzY2hlZHVsZVJlZGlhbF9zaSwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBUcmFuc2ZlclN0YXR1c0lkX3RpLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIElzSGFuZ1VwRGV0ZWN0ZWRfdGksICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgSXNPcHRPdXRfdGksICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgSXNNYXhSZWRpYWxzUmVhY2hlZF90aSwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBJc1Jlc2NoZWR1bGVkX3RpLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIENhbGxSZXN1bHRfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIFNpeFNlY29uZEJpbGxpbmdfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIFN5c3RlbUJpbGxpbmdfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIFJYQ0RMU3RhcnRUaW1lX2R0LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIENhbGxTdGFydFRpbWVfZHQsICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgQ2FsbEVuZFRpbWVfZHQsICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgQ2FsbFN0YXJ0VGltZUxpdmVUcmFuc2Zlcl9kdCwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBDYWxsRW5kVGltZUxpdmVUcmFuc2Zlcl9kdCwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBDYWxsUmVzdWx0VFNfZHQsICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgUGxheUZpbGVTdGFydFRpbWVfZHQsICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgUGxheUZpbGVFbmRUaW1lX2R0LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIEhhbmdVcERldGVjdGVkVFNfZHQsICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgQ3JlYXRlZF9kdCwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBEaWFsZXJOYW1lX3ZjaCwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBDdXJyVFNfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIEN1cnJWb2ljZV92Y2gsICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgQ3VyclRTTGl2ZVRyYW5zZmVyX3ZjaCwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBDdXJyVm9pY2VMaXZlVHJhbnNmZXJfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIEN1cnJDRFBfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIEN1cnJDRFBMaXZlVHJhbnNmZXJfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIERpYWxTdHJpbmdfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIFJlZGlhbE51bWJlcl9pbnQsICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgVGltZVpvbmVfdGksICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgTWVzc2FnZURlbGl2ZXJlZF9zaSwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBTaW5nbGVSZXNwb25zZVN1cnZleV9zaSwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBSZXBsYXlUb3RhbENhbGxUaW1lX2ludCwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBYTUxSZXN1bHRTdHJfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIFRvdGFsQ29ubmVjdFRpbWVfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIElzT3B0SW5fdGksICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgRmlsZVNlcU51bWJlcl9pbnQsICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiAgICAgVXNlclNwZWNpZmllZERhdGFfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIFhNTENvbnRyb2xTdHJpbmdfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIERUU19VVUlEX3ZjaCwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBNYWluTWVzc2FnZUxlbmd0aFNlY29uZHNfaW50ICAgICAgICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBGUk9NICIgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIGNhbGxkZXRhaWwucnhjYWxsZGV0YWlsc190ZXN0ICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBXSEVSRSAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgICAgIENhbGxEZXRhaWxzU3RhdHVzSWRfdGkgPSAiICsgRVNJRCAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiICAgICBBTkQgUlhDYWxsRGV0YWlsSWRfaW50IE1PRCAiICsgTnVtYmVyT2ZSZXN1bHRzVGhyZWFkcyArICIgPSAiICsgIEN1cnJNb2RWYWx1ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAiIE9SREVSIEJZIFJYQ2FsbERldGFpbElkX2ludCBBU0MgICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIiBMSU1JVCAiICsgTnVtYmVyT2ZSZXN1bHRzQ29udGFjdHNUb1Byb2Nlc3NQZXJUaHJlYWQgOwoKCiAgICAgICAgICAgICAgICAvL1NlbGVjdFJlc3VsdHNTdG10ID0gY29ubk1haW4uY3JlYXRlU3RhdGVtZW50KFJlc3VsdFNldC5UWVBFX1NDUk9MTF9TRU5TSVRJVkUsIFJlc3VsdFNldC5DT05DVVJfVVBEQVRBQkxFKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgU2VsZWN0UmVzdWx0c1N0bXQgPSBNYWluQ29ubmVjdGlvbltpXS5jcmVhdGVTdGF0ZW1lbnQoUmVzdWx0U2V0LlRZUEVfU0NST0xMX1NFTlNJVElWRSwgUmVzdWx0U2V0LkNPTkNVUl9VUERBVEFCTEUpOwogICAgICAgICAgICAgICAgU2VsZWN0UmVzdWx0c1JTID0gU2VsZWN0UmVzdWx0c1N0bXQuZXhlY3V0ZVF1ZXJ5KFF1ZXJ5U3RyaW5nKTsKCiAgICAgICAgICAgICAgICBpbnQgQ3VycmVudEJpbGxpbmdBbW91bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGludCBDdXJyZW50Um93Q291bnQgPSAwOwogICAgICAgICAgICAgICAgU3RyaW5nIFF1ZXJ5U3RyaW5nSW5zZXJ0RnJvbVJlbW90ZSA9ICIiOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvLyBOb3cgZG8gc29tZXRoaW5nIHdpdGggdGhlIFJlc3VsdFNldCAuLi4uCiAgICAgICAgICAgICAgICB3aGlsZSAoIFNlbGVjdFJlc3VsdHNSUy5uZXh0KCApICYmICFUaHJlYWQuaW50ZXJydXB0ZWQoKSkgCiAgICAgICAgICAgICAgICB7Ly8gV2hpbGUgU2VsZWN0UmVzdWx0c1JTCiAgICAgICAgICAgICAgICAgICAgQ3VycmVudFJvd0NvdW50Kys7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gQWxsb3cgdGhyZWFkIHRvIGJlIGNhbmNlbGVkIAogICAgICAgICAgICAgICAgICAgIGlmIChpc0NhbmNlbGxlZCgpKSAKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIERvIGFueSBhZGRpdGlvbmFsIGNsZWFuIHVwIGhlcmUgLSBtYXliZSB1cGRhdGUgbWFpbiBEQiBvZiBub24tcHJvY2Vzc2VkPyAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVNZXNzYWdlKCJDYW5jZWxsZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gV2hlbiBhIHByb2dyZXNzIGlzIGJvdW5kICguYmluZCgpKSB0byB0aGlzIHRhc2sgLSB0aGlzIHdpbGwgdXBkYXRlIHRoZSBwcm9ncmVzcyBtZXRlciAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgdXBkYXRlUHJvZ3Jlc3MoU2VsZWN0UmVzdWx0c1JTLmdldFJvdygpLCBOdW1iZXJPZlJlc3VsdHNDb250YWN0c1RvUHJvY2Vzc1BlclRocmVhZCk7CiAgICAgICAgICAgICAgICAgICAgdXBkYXRlTWVzc2FnZSgiVGhyZWFkICIgKyBDdXJyTW9kVmFsdWUgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJEVFNJZF9pbnQiKSk7CiAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIEdldCBCaWxsaW5nIGFtb3VudCAtIG5lZWQgYmlsbGluZyBtZXRob2QgaW4gSkFWQQogICAgICAgICAgICAgICAgICAgIEN1cnJlbnRCaWxsaW5nQW1vdW50ID0gMDsKICAgICAgICAgICAgICAgICAgICAKCiAgICAgICAgICAgICAgICAvLyAgICBTeXN0ZW0ub3V0LnByaW50bG4oU2VsZWN0UmVzdWx0c1JTLmdldEludCgiRFRTSWRfaW50IikpOwogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgIFF1ZXJ5U3RyaW5nSW5zZXJ0RnJvbVJlbW90ZSA9ICAgICAgIiBJTlNFUlQgSU5UTyBTaW1wbGVYUmVzdWx0cy5Db250YWN0UmVzdWx0c190ZXN0ICIKICAgICAgICAgICAgICAgICAgICArICIgKCAiCSAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICArICIgTWFzdGVyUlhDYWxsRGV0YWlsSWRfaW50LCAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgkgICAgICAgICAgICAgICAgKyAiIFJYQ2FsbERldGFpbElkX2ludCwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgRFRTSURfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBCYXRjaElkX2JpLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBQaG9uZUlkX2ludCwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgVG90YWxPYmplY3RUaW1lX2ludCwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgVG90YWxDYWxsVGltZUxpdmVUcmFuc2Zlcl9pbnQsICIKICAgICAgICAgICAgICAgICAgICAgICAgKyAiIFRvdGFsQ2FsbFRpbWVfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBUb3RhbENvbm5lY3RUaW1lX2ludCwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgUmVwbGF5VG90YWxDYWxsVGltZV9pbnQsICIKICAgICAgICAgICAgICAgICAgICAgICAgKyAiIFRvdGFsQW5zd2VyVGltZV9pbnQsICIKICAgICAgICAgICAgICAgICAgICAgICAgKyAiIFVzZXJTcGVjaWZpZWRMaW5lTnVtYmVyX3NpLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBOdW1iZXJPZkhvdXJzVG9SZXNjaGVkdWxlUmVkaWFsX3NpLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBUcmFuc2ZlclN0YXR1c0lkX3RpLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBJc0hhbmdVcERldGVjdGVkX3RpLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBJc09wdE91dF90aSwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgSXNNYXhSZWRpYWxzUmVhY2hlZF90aSwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgSXNSZXNjaGVkdWxlZF90aSwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgQ2FsbFJlc3VsdF9pbnQsICIKICAgICAgICAgICAgICAgICAgICAgICAgKyAiIFNpeFNlY29uZEJpbGxpbmdfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBTeXN0ZW1CaWxsaW5nX2ludCwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgUlhDRExTdGFydFRpbWVfZHQsICIKICAgICAgICAgICAgICAgICAgICAgICAgKyAiIENhbGxTdGFydFRpbWVfZHQsICIKICAgICAgICAgICAgICAgICAgICAgICAgKyAiIENhbGxFbmRUaW1lX2R0LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBDYWxsU3RhcnRUaW1lTGl2ZVRyYW5zZmVyX2R0LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBDYWxsRW5kVGltZUxpdmVUcmFuc2Zlcl9kdCwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgQ2FsbFJlc3VsdFRTX2R0LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBQbGF5RmlsZVN0YXJ0VGltZV9kdCwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgUGxheUZpbGVFbmRUaW1lX2R0LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBIYW5nVXBEZXRlY3RlZFRTX2R0LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBDcmVhdGVkX2R0LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBEaWFsZXJOYW1lX3ZjaCwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgRGlhbGVySVBfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBDdXJyVFNfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBDdXJyVm9pY2VfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBDdXJyVFNMaXZlVHJhbnNmZXJfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBDdXJyVm9pY2VMaXZlVHJhbnNmZXJfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBDdXJyQ0RQX3ZjaCwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgQ3VyckNEUExpdmVUcmFuc2Zlcl92Y2gsICIKICAgICAgICAgICAgICAgICAgICAgICAgKyAiIENvbnRhY3RTdHJpbmdfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBSZWRpYWxOdW1iZXJfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBUaW1lWm9uZV90aSwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgTWVzc2FnZURlbGl2ZXJlZF9zaSwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgU2luZ2xlUmVzcG9uc2VTdXJ2ZXlfc2ksICIKICAgICAgICAgICAgICAgICAgICAgICAgKyAiIFhNTFJlc3VsdFN0cl92Y2gsICIKICAgICAgICAgICAgICAgICAgICAgICAgKyAiIElzT3B0SW5fdGksICIKICAgICAgICAgICAgICAgICAgICAgICAgKyAiIEFjdHVhbENvc3RfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBEVFNfVVVJRF92Y2gsICIKICAgICAgICAgICAgICAgICAgICAgICAgKyAiIFhNTENvbnRyb2xTdHJpbmdfdmNoLCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBVc2VyU3BlY2lmaWVkRGF0YV92Y2gsICIKICAgICAgICAgICAgICAgICAgICAgICAgKyAiIEZpbGVTZXFOdW1iZXJfaW50LCAiCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiBNYWluTWVzc2FnZUxlbmd0aFNlY29uZHNfaW50ICIKICAgICAgICAgICAgICAgICAgICArICIgKSAiCiAgICAgICAgICAgICAgICAgICAgKyAiIFZBTFVFUyAiCiAgICAgICAgICAgICAgICAgICAgKyAiICggIgogICAgICAgICAgICAgICAgICAgICAgICArICIgTlVMTCwgIgogICAgICAgICAgICAgICAgICAgICAgICArICIgIiArIFNlbGVjdFJlc3VsdHNSUy5nZXRJbnQoIlJYQ2FsbERldGFpbElkX2ludCIpICsgIiwgIiAvLwkjRXh0cmFjdEZyb21EaWFsZXIuUlhDYWxsRGV0YWlsSWRfaW50IywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJEVFNJRF9pbnQiKSArICIsICIgLy8jRXh0cmFjdEZyb21EaWFsZXIuRFRTSURfaW50IywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJCYXRjaElkX2JpIikgKyAiLCAiIC8vI0V4dHJhY3RGcm9tRGlhbGVyLkJhdGNoSWRfYmkjLAogICAgICAgICAgICAgICAgICAgICAgICArICIgIiArIFNlbGVjdFJlc3VsdHNSUy5nZXRJbnQoIlBob25lSWRfaW50IikgKyAiLCAiIC8vI0V4dHJhY3RGcm9tRGlhbGVyLlBob25lSWRfaW50IywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJUb3RhbE9iamVjdFRpbWVfaW50IikgKyAiLCAiIC8vI0V4dHJhY3RGcm9tRGlhbGVyLlRvdGFsT2JqZWN0VGltZV9pbnQjLAogICAgICAgICAgICAgICAgICAgICAgICArICIgIiArIFNlbGVjdFJlc3VsdHNSUy5nZXRJbnQoIlRvdGFsQ2FsbFRpbWVMaXZlVHJhbnNmZXJfaW50IikgKyAiLCAiIC8vI0V4dHJhY3RGcm9tRGlhbGVyLlRvdGFsQ2FsbFRpbWVMaXZlVHJhbnNmZXJfaW50IywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJUb3RhbENhbGxUaW1lX2ludCIpICsgIiwgIiAvLyNFeHRyYWN0RnJvbURpYWxlci5Ub3RhbENhbGxUaW1lX2ludCMsCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiAiICsgU2VsZWN0UmVzdWx0c1JTLmdldEludCgiVG90YWxDb25uZWN0VGltZV9pbnQiKSArICIsICIgLy8jRXh0cmFjdEZyb21EaWFsZXIuVG90YWxDb25uZWN0VGltZV9pbnQjLAogICAgICAgICAgICAgICAgICAgICAgICArICIgIiArIFNlbGVjdFJlc3VsdHNSUy5nZXRJbnQoIlJlcGxheVRvdGFsQ2FsbFRpbWVfaW50IikgKyAiLCAiIC8vI0V4dHJhY3RGcm9tRGlhbGVyLlJlcGxheVRvdGFsQ2FsbFRpbWVfaW50IywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJUb3RhbEFuc3dlclRpbWVfaW50IikgKyAiLCAiIC8vI0V4dHJhY3RGcm9tRGlhbGVyLlRvdGFsQW5zd2VyVGltZV9pbnQjLAogICAgICAgICAgICAgICAgICAgICAgICArICIgIiArIFNlbGVjdFJlc3VsdHNSUy5nZXRJbnQoIlVzZXJTcGVjaWZpZWRMaW5lTnVtYmVyX3NpIikgKyAiLCAiIC8vI0V4dHJhY3RGcm9tRGlhbGVyLlVzZXJTcGVjaWZpZWRMaW5lTnVtYmVyX3NpIywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJOdW1iZXJPZkhvdXJzVG9SZXNjaGVkdWxlUmVkaWFsX3NpIikgKyAiLCAiIC8vI0V4dHJhY3RGcm9tRGlhbGVyLk51bWJlck9mSG91cnNUb1Jlc2NoZWR1bGVSZWRpYWxfc2kjLAogICAgICAgICAgICAgICAgICAgICAgICArICIgIiArIFNlbGVjdFJlc3VsdHNSUy5nZXRJbnQoIlRyYW5zZmVyU3RhdHVzSWRfdGkiKSArICIsICIgLy8jRXh0cmFjdEZyb21EaWFsZXIuVHJhbnNmZXJTdGF0dXNJZF90aSMsCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiAiICsgU2VsZWN0UmVzdWx0c1JTLmdldEludCgiSXNIYW5nVXBEZXRlY3RlZF90aSIpICsgIiwgIiAvLyNFeHRyYWN0RnJvbURpYWxlci5Jc0hhbmdVcERldGVjdGVkX3RpIywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJJc09wdE91dF90aSIpICsgIiwgIiAvLyNFeHRyYWN0RnJvbURpYWxlci5Jc09wdE91dF90aSMsCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiAiICsgU2VsZWN0UmVzdWx0c1JTLmdldEludCgiSXNNYXhSZWRpYWxzUmVhY2hlZF90aSIpICsgIiwgIiAvLyNFeHRyYWN0RnJvbURpYWxlci5Jc01heFJlZGlhbHNSZWFjaGVkX3RpIywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJJc1Jlc2NoZWR1bGVkX3RpIikgKyAiLCAiIC8vI0V4dHJhY3RGcm9tRGlhbGVyLklzUmVzY2hlZHVsZWRfdGkjLAogICAgICAgICAgICAgICAgICAgICAgICArICIgIiArIFNlbGVjdFJlc3VsdHNSUy5nZXRJbnQoIkNhbGxSZXN1bHRfaW50IikgKyAiLCAiIC8vI0V4dHJhY3RGcm9tRGlhbGVyLkNhbGxSZXN1bHRfaW50IywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJTaXhTZWNvbmRCaWxsaW5nX2ludCIpICsgIiwgIiAvLyNFeHRyYWN0RnJvbURpYWxlci5TaXhTZWNvbmRCaWxsaW5nX2ludCMsCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiAiICsgU2VsZWN0UmVzdWx0c1JTLmdldEludCgiU3lzdGVtQmlsbGluZ19pbnQiKSArICIsICIgLy8jRXh0cmFjdEZyb21EaWFsZXIuU3lzdGVtQmlsbGluZ19pbnQjLAogICAgICAgICAgICAgICAgICAgICAgICArICIgJyIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0U3RyaW5nKCJSWENETFN0YXJ0VGltZV9kdCIpICsgIicsICIgLy8nI0V4dHJhY3RGcm9tRGlhbGVyLlJYQ0RMU3RhcnRUaW1lX2R0IycsCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiAnIiArIFNlbGVjdFJlc3VsdHNSUy5nZXRTdHJpbmcoIkNhbGxTdGFydFRpbWVfZHQiKSArICInLCAiIC8vJyNFeHRyYWN0RnJvbURpYWxlci5DYWxsU3RhcnRUaW1lX2R0IycsCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiAnIiArIFNlbGVjdFJlc3VsdHNSUy5nZXRTdHJpbmcoIkNhbGxFbmRUaW1lX2R0IikgKyAiJywgIiAvLycjRXh0cmFjdEZyb21EaWFsZXIuQ2FsbEVuZFRpbWVfZHQjJywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICciICsgU2VsZWN0UmVzdWx0c1JTLmdldFN0cmluZygiQ2FsbFN0YXJ0VGltZUxpdmVUcmFuc2Zlcl9kdCIpICsgIicsICIgLy8nI0V4dHJhY3RGcm9tRGlhbGVyLkNhbGxTdGFydFRpbWVMaXZlVHJhbnNmZXJfZHQjJywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICciICsgU2VsZWN0UmVzdWx0c1JTLmdldFN0cmluZygiQ2FsbEVuZFRpbWVMaXZlVHJhbnNmZXJfZHQiKSArICInLCAiIC8vJyNFeHRyYWN0RnJvbURpYWxlci5DYWxsRW5kVGltZUxpdmVUcmFuc2Zlcl9kdCMnLAogICAgICAgICAgICAgICAgICAgICAgICArICIgJyIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0U3RyaW5nKCJDYWxsUmVzdWx0VFNfZHQiKSArICInLCAiIC8vJyNFeHRyYWN0RnJvbURpYWxlci5DYWxsUmVzdWx0VFNfZHQjJywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICciICsgU2VsZWN0UmVzdWx0c1JTLmdldFN0cmluZygiUGxheUZpbGVTdGFydFRpbWVfZHQiKSArICInLCAiIC8vJyNFeHRyYWN0RnJvbURpYWxlci5QbGF5RmlsZVN0YXJ0VGltZV9kdCMnLAogICAgICAgICAgICAgICAgICAgICAgICArICIgJyIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0U3RyaW5nKCJQbGF5RmlsZUVuZFRpbWVfZHQiKSArICInLCAiIC8vJyNFeHRyYWN0RnJvbURpYWxlci5QbGF5RmlsZUVuZFRpbWVfZHQjJywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICciICsgU2VsZWN0UmVzdWx0c1JTLmdldFN0cmluZygiSGFuZ1VwRGV0ZWN0ZWRUU19kdCIpICsgIicsICIgLy8nI0V4dHJhY3RGcm9tRGlhbGVyLkhhbmdVcERldGVjdGVkVFNfZHQjJywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICciICsgU2VsZWN0UmVzdWx0c1JTLmdldFN0cmluZygiQ3JlYXRlZF9kdCIpICsgIicsICIgLy8nI0V4dHJhY3RGcm9tRGlhbGVyLkNyZWF0ZWRfZHQjJywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICciICsgU2VsZWN0UmVzdWx0c1JTLmdldFN0cmluZygiRGlhbGVyTmFtZV92Y2giKSArICInLCAiIC8vJyNFeHRyYWN0RnJvbURpYWxlci5EaWFsZXJOYW1lX3ZjaCMnLAogICAgICAgICAgICAgICAgICAgICAgICArICIgJyIgKyAgUmVtb3RlSVBBZGRyZXNzW2ldICsgIicsICIgLy8nI2lucERpYWxlcklQQWRkciMnLAogICAgICAgICAgICAgICAgICAgICAgICArICIgJyIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0U3RyaW5nKCJDdXJyVFNfdmNoIikgKyAiJywgIiAvLycjRXh0cmFjdEZyb21EaWFsZXIuQ3VyclRTX3ZjaCMnLAogICAgICAgICAgICAgICAgICAgICAgICArICIgJyIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0U3RyaW5nKCJDdXJyVm9pY2VfdmNoIikgKyAiJywgIiAvLycjRXh0cmFjdEZyb21EaWFsZXIuQ3VyclZvaWNlX3ZjaCMnLAogICAgICAgICAgICAgICAgICAgICAgICArICIgJyIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0U3RyaW5nKCJDdXJyVFNMaXZlVHJhbnNmZXJfdmNoIikgKyAiJywgIiAvLycjRXh0cmFjdEZyb21EaWFsZXIuQ3VyclRTTGl2ZVRyYW5zZmVyX3ZjaCMnLAogICAgICAgICAgICAgICAgICAgICAgICArICIgJyIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0U3RyaW5nKCJDdXJyVm9pY2VMaXZlVHJhbnNmZXJfdmNoIikgKyAiJywgIiAvLycjRXh0cmFjdEZyb21EaWFsZXIuQ3VyclZvaWNlTGl2ZVRyYW5zZmVyX3ZjaCMnLAogICAgICAgICAgICAgICAgICAgICAgICArICIgJyIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0U3RyaW5nKCJDdXJyQ0RQX3ZjaCIpICsgIicsICIgLy8nI0V4dHJhY3RGcm9tRGlhbGVyLkN1cnJDRFBfdmNoIycsCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiAnIiArIFNlbGVjdFJlc3VsdHNSUy5nZXRTdHJpbmcoIkN1cnJDRFBMaXZlVHJhbnNmZXJfdmNoIikgKyAiJywgIiAvLycjRXh0cmFjdEZyb21EaWFsZXIuQ3VyckNEUExpdmVUcmFuc2Zlcl92Y2gjJywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICciICsgZXNjYXBlU1FMKFNlbGVjdFJlc3VsdHNSUy5nZXRTdHJpbmcoIkRpYWxTdHJpbmdfdmNoIikpICsgIicsICIgLy8nI0V4dHJhY3RGcm9tRGlhbGVyLkRpYWxTdHJpbmdfdmNoIycsCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiAiICsgU2VsZWN0UmVzdWx0c1JTLmdldEludCgiUmVkaWFsTnVtYmVyX2ludCIpICsgIiwgIiAvLyNFeHRyYWN0RnJvbURpYWxlci5SZWRpYWxOdW1iZXJfaW50IywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJUaW1lWm9uZV90aSIpICsgIiwgIiAvLyNFeHRyYWN0RnJvbURpYWxlci5UaW1lWm9uZV90aSMsCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiAiICsgU2VsZWN0UmVzdWx0c1JTLmdldEludCgiTWVzc2FnZURlbGl2ZXJlZF9zaSIpICsgIiwgIiAvLyNFeHRyYWN0RnJvbURpYWxlci5NZXNzYWdlRGVsaXZlcmVkX3NpIywKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJTaW5nbGVSZXNwb25zZVN1cnZleV9zaSIpICsgIiwgIiAvLyNFeHRyYWN0RnJvbURpYWxlci5TaW5nbGVSZXNwb25zZVN1cnZleV9zaSMsCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiAnIiArIGVzY2FwZVNRTChTZWxlY3RSZXN1bHRzUlMuZ2V0U3RyaW5nKCJYTUxSZXN1bHRTdHJfdmNoIikpICsgIicsICIgLy88Q0ZRVUVSWVBBUkFNIENGU1FMVFlQRT0iQ0ZfU1FMX1ZBUkNIQVIiIFZBTFVFPSIjRXh0cmFjdEZyb21EaWFsZXIuWE1MUmVzdWx0U3RyX3ZjaCMiPiwKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJJc09wdEluX3RpIikgKyAiLCAiIC8vI0V4dHJhY3RGcm9tRGlhbGVyLklzT3B0SW5fdGkjLAogICAgICAgICAgICAgICAgICAgICAgICArICIgIiArIEN1cnJlbnRCaWxsaW5nQW1vdW50ICsgIiwgIiAvLyNDdXJyZW50QmlsbGluZ0Ftb3VudCMsCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiAnIiArIFNlbGVjdFJlc3VsdHNSUy5nZXRTdHJpbmcoIkRUU19VVUlEX3ZjaCIpICsgIicsICIgLy8nI0V4dHJhY3RGcm9tRGlhbGVyLkRUU19VVUlEX3ZjaCMnLAogICAgICAgICAgICAgICAgICAgICAgICArICIgJyIgKyBlc2NhcGVTUUwoU2VsZWN0UmVzdWx0c1JTLmdldFN0cmluZygiWE1MQ29udHJvbFN0cmluZ192Y2giKSkgKyAiJywgIiAvLyA8Q0ZRVUVSWVBBUkFNIENGU1FMVFlQRT0iQ0ZfU1FMX1ZBUkNIQVIiIFZBTFVFPSIjRXh0cmFjdEZyb21EaWFsZXIuWE1MQ29udHJvbFN0cmluZ192Y2gjIj4sCiAgICAgICAgICAgICAgICAgICAgICAgICsgIiAnIiArIGVzY2FwZVNRTChTZWxlY3RSZXN1bHRzUlMuZ2V0U3RyaW5nKCJVc2VyU3BlY2lmaWVkRGF0YV92Y2giKSkgKyAiJywgIiAvLyA8Q0ZRVUVSWVBBUkFNIENGU1FMVFlQRT0iQ0ZfU1FMX1ZBUkNIQVIiIFZBTFVFPSIjRXh0cmFjdEZyb21EaWFsZXIuVXNlclNwZWNpZmllZERhdGFfdmNoIyI+LAogICAgICAgICAgICAgICAgICAgICAgICArICIgIiArIFNlbGVjdFJlc3VsdHNSUy5nZXRJbnQoIkZpbGVTZXFOdW1iZXJfaW50IikgKyAiLCAiIC8vIDxjZmlmIEV4dHJhY3RGcm9tRGlhbGVyLkZpbGVTZXFOdW1iZXJfaW50IE5FUSAiIj4jRXh0cmFjdEZyb21EaWFsZXIuRmlsZVNlcU51bWJlcl9pbnQjPGNmZWxzZT5OVUxMPC9jZmlmPiwKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICIgKyBTZWxlY3RSZXN1bHRzUlMuZ2V0SW50KCJNYWluTWVzc2FnZUxlbmd0aFNlY29uZHNfaW50IikgKyAiICIgLy8jRXh0cmFjdEZyb21EaWFsZXIuTWFpbk1lc3NhZ2VMZW5ndGhTZWNvbmRzX2ludCMgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgKyAiICkgIjsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICBTZWxlY3RSZXN1bHRzUlMudXBkYXRlSW50KCAiQ2FsbERldGFpbHNTdGF0dXNJZF90aSIsIGFicyhFU0lEKSApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgSW5zZXJ0UmVtb3RlUmVzdWx0c1N0bXQgPSBjb25uUmVtb3RlLmNyZWF0ZVN0YXRlbWVudCgpOwogICAgICAgICAgICAgICAgICAgIEluc2VydFJlbW90ZVJlc3VsdHNTdG10LmV4ZWN1dGVVcGRhdGUoUXVlcnlTdHJpbmdJbnNlcnRGcm9tUmVtb3RlKTsKCiAgICAgICAgICAgICAgICAgICAgLy8gcmVzZXQgc3RyaW5nIHRvIGVtcHR5CiAgICAgICAgICAgICAgICAgICAgUXVlcnlTdHJpbmdJbnNlcnRGcm9tUmVtb3RlID0gIiI7CgogICAgICAgICAgICAgICAgICAgIFNlbGVjdFJlc3VsdHNSUy51cGRhdGVSb3coICk7ICAgICAgICAgICAgICAgICAgICAgICAgCgogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgCgogICAgICAgICAgICAgICAgfS8vIFdoaWxlIFNlbGVjdFJlc3VsdHNSUwoKICAgICAgICAgICAgICAgIC8vIEV4ZWN1dGUgSW5zZXJ0IG9uIGFueSByZW1haW5naW5nIHJlY29yZHMKICAgICAgICAgICAgICAgIGlmKFF1ZXJ5U3RyaW5nSW5zZXJ0RnJvbVJlbW90ZS5sZW5ndGgoKSA+IDApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgSW5zZXJ0UmVtb3RlUmVzdWx0c1N0bXQgPSBjb25uUmVtb3RlLmNyZWF0ZVN0YXRlbWVudCgpOwogICAgICAgICAgICAgICAgICAgIEluc2VydFJlbW90ZVJlc3VsdHNTdG10LmV4ZWN1dGVVcGRhdGUoUXVlcnlTdHJpbmdJbnNlcnRGcm9tUmVtb3RlKTsgIAogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIFF1ZXJ5U3RyaW5nSW5zZXJ0RnJvbVJlbW90ZSA9ICIiOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIFNlbGVjdFJlc3VsdHNSUy51cGRhdGVSb3coICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIAoKICAgICAgICAgICAgICAgIGlmKEN1cnJlbnRSb3dDb3VudCA9PSAwKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8vIFdyaXRlIHRvIGxvZyB0aGF0IHRoZXJlIHdhcyBub3RoaW5nIHRvIHByb2Nlc3MKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk5vIHJlc3VsdHMgZm91bmQgdGhpcyBsb29wIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLy8gT25seSBzbGVlcCB3aGlsZSBsaXN0ZW5pbmcgZm9yIGNhbmNlbCB0YXNrL3RocmVhZCBjYWxscwogICAgICAgICAgICAgICAgICAgIHRyeSAKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFRocmVhZC5zbGVlcCgxMDApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXRjaCAoSW50ZXJydXB0ZWRFeGNlcHRpb24gaW50ZXJydXB0ZWQpIAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQ2FuY2VsbGVkKCkpIAogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlFSQyBDYW5jZWxsZWQiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgCgoKICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlOwogICAgICAgICAgICB9IAogICAgICAgICAgICAKICAgICAgICAgICAgY2F0Y2ggKFNRTEV4Y2VwdGlvbiBleCkgCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAvLyBoYW5kbGUgYW55IGVycm9ycwogICAgICAgICAgICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiU1FMRXhjZXB0aW9uOiAiICsgZXguZ2V0TWVzc2FnZSgpKTsKICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIlNRTFN0YXRlOiAiICsgZXguZ2V0U1FMU3RhdGUoKSk7CiAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKCJWZW5kb3JFcnJvcjogIiArIGV4LmdldEVycm9yQ29kZSgpKTsKICAgICAgICAgICAgICAgICBpKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZmluYWxseSAKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLy8gaXQgaXMgYSBnb29kIGlkZWEgdG8gcmVsZWFzZQogICAgICAgICAgICAgICAgLy8gcmVzb3VyY2VzIGluIGEgZmluYWxseXt9IGJsb2NrCiAgICAgICAgICAgICAgICAvLyBpbiByZXZlcnNlLW9yZGVyIG9mIHRoZWlyIGNyZWF0aW9uCiAgICAgICAgICAgICAgICAvLyBpZiB0aGV5IGFyZSBuby1sb25nZXIgbmVlZGVkCgogICAgICAgICAgICAgICAgaWYgKFNlbGVjdFJlc3VsdHNSUyAhPSBudWxsKSAKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0cnkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdFJlc3VsdHNSUy5jbG9zZSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbEV4KSAKICAgICAgICAgICAgICAgICAgICB7IAoKICAgICAgICAgICAgICAgICAgICB9IC8vIGlnbm9yZQoKICAgICAgICAgICAgICAgICAgICBTZWxlY3RSZXN1bHRzUlMgPSBudWxsOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChTZWxlY3RSZXN1bHRzU3RtdCAhPSBudWxsKSAKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0cnkgCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgIFNlbGVjdFJlc3VsdHNTdG10LmNsb3NlKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNhdGNoIChTUUxFeGNlcHRpb24gc3FsRXgpIAogICAgICAgICAgICAgICAgICAgIHsgCgogICAgICAgICAgICAgICAgICAgIH0gLy8gaWdub3JlCgogICAgICAgICAgICAgICAgICAgIFNlbGVjdFJlc3VsdHNTdG10ID0gbnVsbDsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoVXBkYXRlUmVzdWx0c1N0bXQgIT0gbnVsbCkgCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdHJ5IAogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICBVcGRhdGVSZXN1bHRzU3RtdC5jbG9zZSgpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjYXRjaCAoU1FMRXhjZXB0aW9uIHNxbEV4KSAKICAgICAgICAgICAgICAgICAgICB7IAoKICAgICAgICAgICAgICAgICAgICB9IC8vIGlnbm9yZQoKICAgICAgICAgICAgICAgICAgICBVcGRhdGVSZXN1bHRzU3RtdCA9IG51bGw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmIChJbnNlcnRSZW1vdGVSZXN1bHRzU3RtdCAhPSBudWxsKSAKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB0cnkgCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgIEluc2VydFJlbW90ZVJlc3VsdHNTdG10LmNsb3NlKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGNhdGNoIChTUUxFeGNlcHRpb24gc3FsRXgpIAogICAgICAgICAgICAgICAgICAgIHsgCgogICAgICAgICAgICAgICAgICAgIH0gLy8gaWdub3JlCgogICAgICAgICAgICAgICAgICAgIEluc2VydFJlbW90ZVJlc3VsdHNTdG10ID0gbnVsbDsKICAgICAgICAgICAgICAgIH0gICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIAogICAgICAgICAgICB9CgogICAgICAgICAgICAgICAKICAgICAgICAgICAgUVJWQy5SZXN1bHRzUmVhZGVyQ2FsbEJhY2tvbkNvbXBsZXRlKEN1cnJNb2RWYWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICByZXR1cm4gaXRlcmF0aW9uczsKICAgICAgICAgfQogCiAgICAgICAgIH0KICAgICAgICAgCiB9