ServiceImportExport
1.0.3
c.a.p.e. IT GmbH
http://www.cape-it.de/
GNU AFFERO GENERAL PUBLIC LICENSE Version 3, November 2007
CR: set required ImportExport to version 3.0.1, removed html-version of pod documentation, added custom SLAPreferences to SLA import export mappings, removed \"export with labels\" (now included in ImportExport-framework.
Bugfix: removed uncommenntation of some code.
CR: added custom ServicePreferences to service import export mappings, moved usage information to pod-file in <OTRS_HOME>/doc/en; Bugfix: fixed bug installation if GeneralCatalog is installed but not ITSMCore.
CR: first official release for OTRS 3.0.x; added file USAGE_serviceimportexport for documentation purpose.
CR: changes for use with OTRS 3.0.x, added some error handlings in package setup method.
Provides ImportExportBackend for Service, SLA and Service2CustomerUsers.
Stellt ImportExport-Backend fuer Service, SLA und Service2Kundennutzer-eintraege zur Verfuegung.
3.0.x
<br>
<b>Welcome:</b><br><br>
<br>
You are about to install the OTRS module ServiceImportExport.<br>
<br>
<b>Required OTRS packages:</b><br><br>
<ul>
<li>ImportExport 3.0.1 or higher</li>
</ul>
<br>
<br>
c.a.p.e. IT ...easy.<br>
<br>
<br>
The package has been installed. Your import-/export configuration has been changed.<br>
<br>
Please see file OTRS_HOME/USAGE_serviceimportexport for further documentation.<br>
<br>
ImportExport
my $FunctionName = 'CodeInstall';
my $CodeModule = 'var::packagesetup::' . $Param{Structure}->{Name}->{Content};
if ( $Self->{MainObject}->Require($CodeModule) ) {
my $CodeObject = $CodeModule->new( %{$Self} );
if ($CodeObject) {
if ( !$CodeObject->$FunctionName(%{$Self}) ) {
$Self->{LogObject}->Log(
Priority => 'error',
Message => "Could not call method $FunctionName() on $CodeModule.pm."
);
}
}
else {
$Self->{LogObject}->Log(
Priority => 'error',
Message => "Could not call method new() on $CodeModule.pm."
);
}
}
my $FunctionName = 'CodeUpgrade';
my $CodeModule = 'var::packagesetup::' . $Param{Structure}->{Name}->{Content};
if ( $Self->{MainObject}->Require($CodeModule) ) {
my $CodeObject = $CodeModule->new( %{$Self} );
if ($CodeObject) {
if ( !$CodeObject->$FunctionName(%{$Self}) ) {
$Self->{LogObject}->Log(
Priority => 'error',
Message => "Could not call method $FunctionName() on $CodeModule.pm."
);
}
}
else {
$Self->{LogObject}->Log(
Priority => 'error',
Message => "Could not call method new() on $CodeModule.pm."
);
}
}
my $FunctionName = 'CodeUninstall';
my $CodeModule = 'var::packagesetup::' . $Param{Structure}->{Name}->{Content};
if ( $Self->{MainObject}->Require($CodeModule) ) {
my $CodeObject = $CodeModule->new( %{$Self} );
if ($CodeObject) {
if ( !$CodeObject->$FunctionName(%{$Self}) ) {
$Self->{LogObject}->Log(
Priority => 'error',
Message => "Could not call method $FunctionName() on $CodeModule.pm."
);
}
}
else {
$Self->{LogObject}->Log(
Priority => 'error',
Message => "Could not call method new() on $CodeModule.pm."
);
}
}
my $FunctionName = 'CodeReinstall';
my $CodeModule = 'var::packagesetup::' . $Param{Structure}->{Name}->{Content};
if ( $Self->{MainObject}->Require($CodeModule) ) {
my $CodeObject = $CodeModule->new( %{$Self} );
if ($CodeObject) {
if ( !$CodeObject->$FunctionName(%{$Self}) ) {
$Self->{LogObject}->Log(
Priority => 'error',
Message => "Could not call method $FunctionName() on $CodeModule.pm."
);
}
}
else {
$Self->{LogObject}->Log(
Priority => 'error',
Message => "Could not call method new() on $CodeModule.pm."
);
}
}
2011-11-29 11:47:35
cvs.intra.cape-it.de
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPG90cnNfY29uZmlnIHZlcnNpb249IjEuMCIgaW5pdD0iQXBwbGljYXRpb24iPgogICAgPENWUz4kSWQ6IFNlcnZpY2VJbXBvcnRFeHBvcnQueG1sLHYgMS4xIDIwMTAtMDQtMDkgMTU6MjA6MzggdHRvIEV4cCAkPC9DVlM+CgogICAgPENvbmZpZ0l0ZW0gTmFtZT0iSW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kUmVnaXN0cmF0aW9uIyMjU2VydmljZTJDdXN0b21lclVzZXIiIFJlcXVpcmVkPSIwIiBWYWxpZD0iMSI+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImVuIj5PYmplY3QgYmFja2VuZCBtb2R1bGUgcmVnaXN0cmF0aW9uIGZvciB0aGUgaW1wb3J0L2V4cG9ydCBtb2R1bC48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJkZSI+T2JqZWt0LUJhY2tlbmQgTW9kdWwgUmVnaXN0cmF0aW9uIGRlcyBJbXBvcnQvRXhwb3J0IE1vZHVscy48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxHcm91cD5JbXBvcnRFeHBvcnQ8L0dyb3VwPgogICAgICAgIDxTdWJHcm91cD5PYmplY3RCYWNrZW5kOjpNb2R1bGVSZWdpc3RyYXRpb248L1N1Ykdyb3VwPgogICAgICAgIDxTZXR0aW5nPgogICAgICAgICAgICA8SGFzaD4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iTW9kdWxlIj5LZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kOjpTZXJ2aWNlMkN1c3RvbWVyVXNlcjwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iTmFtZSI+U2VydmljZTJDdXN0b21lclVzZXI8L0l0ZW0+CiAgICAgICAgICAgIDwvSGFzaD4KICAgICAgICA8L1NldHRpbmc+CiAgICA8L0NvbmZpZ0l0ZW0+CgogICAgPENvbmZpZ0l0ZW0gTmFtZT0iSW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kUmVnaXN0cmF0aW9uIyMjU2VydmljZSIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZW4iPk9iamVjdCBiYWNrZW5kIG1vZHVsZSByZWdpc3RyYXRpb24gZm9yIHRoZSBpbXBvcnQvZXhwb3J0IG1vZHVsLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImRlIj5PYmpla3QtQmFja2VuZCBNb2R1bCBSZWdpc3RyYXRpb24gZGVzIEltcG9ydC9FeHBvcnQgTW9kdWxzLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPEdyb3VwPkltcG9ydEV4cG9ydDwvR3JvdXA+CiAgICAgICAgPFN1Ykdyb3VwPk9iamVjdEJhY2tlbmQ6Ok1vZHVsZVJlZ2lzdHJhdGlvbjwvU3ViR3JvdXA+CiAgICAgICAgPFNldHRpbmc+CiAgICAgICAgICAgIDxIYXNoPgogICAgICAgICAgICAgICAgPEl0ZW0gS2V5PSJNb2R1bGUiPktlcm5lbDo6U3lzdGVtOjpJbXBvcnRFeHBvcnQ6Ok9iamVjdEJhY2tlbmQ6OlNlcnZpY2U8L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9Ik5hbWUiPlNlcnZpY2U8L0l0ZW0+CiAgICAgICAgICAgIDwvSGFzaD4KICAgICAgICA8L1NldHRpbmc+CiAgICA8L0NvbmZpZ0l0ZW0+CgogICAgPENvbmZpZ0l0ZW0gTmFtZT0iSW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kUmVnaXN0cmF0aW9uIyMjU0xBIiBSZXF1aXJlZD0iMCIgVmFsaWQ9IjEiPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJlbiI+T2JqZWN0IGJhY2tlbmQgbW9kdWxlIHJlZ2lzdHJhdGlvbiBmb3IgdGhlIGltcG9ydC9leHBvcnQgbW9kdWwuPC9EZXNjcmlwdGlvbj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZGUiPk9iamVrdC1CYWNrZW5kIE1vZHVsIFJlZ2lzdHJhdGlvbiBkZXMgSW1wb3J0L0V4cG9ydCBNb2R1bHMuPC9EZXNjcmlwdGlvbj4KICAgICAgICA8R3JvdXA+SW1wb3J0RXhwb3J0PC9Hcm91cD4KICAgICAgICA8U3ViR3JvdXA+T2JqZWN0QmFja2VuZDo6TW9kdWxlUmVnaXN0cmF0aW9uPC9TdWJHcm91cD4KICAgICAgICA8U2V0dGluZz4KICAgICAgICAgICAgPEhhc2g+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9Ik1vZHVsZSI+S2VybmVsOjpTeXN0ZW06OkltcG9ydEV4cG9ydDo6T2JqZWN0QmFja2VuZDo6U0xBPC9JdGVtPgogICAgICAgICAgICAgICAgPEl0ZW0gS2V5PSJOYW1lIj5TTEE8L0l0ZW0+CiAgICAgICAgICAgIDwvSGFzaD4KICAgICAgICA8L1NldHRpbmc+CiAgICA8L0NvbmZpZ0l0ZW0+CgoKPC9vdHJzX2NvbmZpZz4K
IyAtLQojIEtlcm5lbC9TeXN0ZW0vSW1wb3J0RXhwb3J0L09iamVjdEJhY2tlbmQvU2VydmljZS5wbQojCiMtIGltcG9ydC9leHBvcnQgYmFja2VuZCBmb3Igc2VydmljZSBkZWZpbml0aW9ucwojCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMTEgYy5hLnAuZS4gSVQgR21iSCwgaHR0cDovL3d3dy5jYXBlLWl0LmRlCiMKIyAtLQojICRJZDogU2VydmljZS5wbSx2IDEuMTEgMjAxMS0xMS0yOSAxMDoyODo1NyB0dG8gRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtMi4wLnR4dC4KIyAtLQpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpJbXBvcnRFeHBvcnQ6Ok9iamVjdEJhY2tlbmQ6OlNlcnZpY2U7CnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKCnVzZSBLZXJuZWw6OlN5c3RlbTo6UXVldWU7CnVzZSBLZXJuZWw6OlN5c3RlbTo6U2VydmljZTsKdXNlIEtlcm5lbDo6U3lzdGVtOjpUeXBlOwp1c2UgS2VybmVsOjpTeXN0ZW06OlZhbGlkOwoKdXNlIHZhcnMgcXcoJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS4xMSAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpTeXN0ZW06OkltcG9ydEV4cG9ydDo6T2JqZWN0QmFja2VuZDo6Q3VzdG9tZXJVc2VyIC0gaW1wb3J0L2V4cG9ydCBiYWNrZW5kIGZvciBDdXN0b21lclVzZXIKCj1oZWFkMSBTWU5PUFNJUwoKQWxsIGZ1bmN0aW9ucyB0byBpbXBvcnQgYW5kIGV4cG9ydCBDdXN0b21lclVzZXIgZW50cmllcwoKPW92ZXIgNAoKPWN1dAoKPWl0ZW0gbmV3KCkKCmNyZWF0ZSBhbiBvYmplY3QKCiAgICB1c2UgS2VybmVsOjpDb25maWc7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkRCOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpMb2c7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06Ok1haW47CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkltcG9ydEV4cG9ydDo6T2JqZWN0QmFja2VuZDo6Q3VzdG9tZXJVc2VyOwoKICAgIG15ICRDb25maWdPYmplY3QgPSBLZXJuZWw6OkNvbmZpZy0+bmV3KCk7CiAgICBteSAkTG9nT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkxvZy0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgKTsKICAgIG15ICRNYWluT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06Ok1haW4tPm5ldygKICAgICAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgICAgICBMb2dPYmplY3QgICAgPT4gJExvZ09iamVjdCwKICAgICk7CiAgICBteSAkREJPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6REItPm5ldygKICAgICAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgICAgICBMb2dPYmplY3QgICAgPT4gJExvZ09iamVjdCwKICAgICAgICBNYWluT2JqZWN0ICAgPT4gJE1haW5PYmplY3QsCiAgICApOwogICAgbXkgJEJhY2tlbmRPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kOjpDdXN0b21lclVzZXItPm5ldygKICAgICAgICBDb25maWdPYmplY3QgICAgICAgPT4gJENvbmZpZ09iamVjdCwKICAgICAgICBMb2dPYmplY3QgICAgICAgICAgPT4gJExvZ09iamVjdCwKICAgICAgICBEQk9iamVjdCAgICAgICAgICAgPT4gJERCT2JqZWN0LAogICAgICAgIE1haW5PYmplY3QgICAgICAgICA9PiAkTWFpbk9iamVjdCwKICAgICAgICBJbXBvcnRFeHBvcnRPYmplY3QgPT4gJEltcG9ydEV4cG9ydE9iamVjdCwKICAgICk7Cgo9Y3V0CgpzdWIgbmV3IHsKICAgIG15ICggJFR5cGUsICVQYXJhbSApID0gQF87CgogICAgIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CiAgICBteSAkU2VsZiA9IHt9OwogICAgYmxlc3MoICRTZWxmLCAkVHlwZSApOwoKICAgICNjaGVjayByZXF1aXJlZCBvYmplY3RzLi4uCiAgICBmb3IgbXkgJE9iamVjdCAoCiAgICAgICAgcXcoQ29uZmlnT2JqZWN0IExvZ09iamVjdCBEQk9iamVjdCBNYWluT2JqZWN0IEltcG9ydEV4cG9ydE9iamVjdCBFbmNvZGVPYmplY3QpCiAgICAgICAgKQogICAgewogICAgICAgICRTZWxmLT57JE9iamVjdH0gPSAkUGFyYW17JE9iamVjdH0gfHwgZGllICJHb3Qgbm8gJE9iamVjdCEiOwogICAgfQogICAgaWYgKCAhJFNlbGYtPntTZXJ2aWNlT2JqZWN0fSApIHsKICAgICAgICAkU2VsZi0+e1NlcnZpY2VPYmplY3R9ID0gS2VybmVsOjpTeXN0ZW06OlNlcnZpY2UtPm5ldyggJXskU2VsZn0gKTsKICAgIH0KICAgIGlmICggISRTZWxmLT57VmFsaWRPYmplY3R9ICkgewogICAgICAgICRTZWxmLT57VmFsaWRPYmplY3R9ID0gS2VybmVsOjpTeXN0ZW06OlZhbGlkLT5uZXcoICV7JFNlbGZ9ICk7CiAgICB9CgogICAgaWYgKCAhJFNlbGYtPntRdWV1ZU9iamVjdH0gKSB7CiAgICAgICAgJFNlbGYtPntRdWV1ZU9iamVjdH0gPSBLZXJuZWw6OlN5c3RlbTo6UXVldWUtPm5ldyggJXskU2VsZn0gKTsKICAgIH0KCiAgICBpZiAoICEkU2VsZi0+e1R5cGVPYmplY3R9ICkgewogICAgICAgICRTZWxmLT57VHlwZU9iamVjdH0gPSBLZXJuZWw6OlN5c3RlbTo6VHlwZS0+bmV3KCAleyRTZWxmfSApOwogICAgfQoKICAgIGlmICggJFNlbGYtPntNYWluT2JqZWN0fS0+UmVxdWlyZSgnS2VybmVsOjpTeXN0ZW06OkdlbmVyYWxDYXRhbG9nJykgKSB7CiAgICAgICAgJFNlbGYtPntHZW5lcmFsQ2F0YWxvZ09iamVjdH0gPSBLZXJuZWw6OlN5c3RlbTo6R2VuZXJhbENhdGFsb2ctPm5ldyggJXskU2VsZn0gKTsKICAgICAgICBpZiAoICRTZWxmLT57R2VuZXJhbENhdGFsb2dPYmplY3R9ICkgewoKICAgICAgICAgICAgIyBnZXQgc2VydmljZSB0eXBlIGxpc3QKICAgICAgICAgICAgJFNlbGYtPntTZXJ2aWNlVHlwZUxpc3R9ID0gJFNlbGYtPntHZW5lcmFsQ2F0YWxvZ09iamVjdH0tPkl0ZW1MaXN0KAogICAgICAgICAgICAgICAgQ2xhc3MgPT4gJ0lUU006OlNlcnZpY2U6OlR5cGUnLAogICAgICAgICAgICApOwogICAgICAgICAgICBteSAlVG1wSGFzaCA9IHJldmVyc2UoICV7ICRTZWxmLT57U2VydmljZVR5cGVMaXN0fSB9ICk7CiAgICAgICAgICAgICRTZWxmLT57UmV2ZXJzZVNlcnZpY2VUeXBlTGlzdH0gPSBcJVRtcEhhc2g7CgogICAgICAgICAgICAjIGdldCBjcml0aWNhbGl0eSBsaXN0CiAgICAgICAgICAgICRTZWxmLT57Q3JpdGljYWxpdHlMaXN0fSA9ICRTZWxmLT57R2VuZXJhbENhdGFsb2dPYmplY3R9LT5JdGVtTGlzdCgKICAgICAgICAgICAgICAgIENsYXNzID0+ICdJVFNNOjpDb3JlOjpDcml0aWNhbGl0eScsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIG15ICVUbXBIYXNoMiA9IHJldmVyc2UoICV7ICRTZWxmLT57Q3JpdGljYWxpdHlMaXN0fSB9ICk7CiAgICAgICAgICAgICRTZWxmLT57UmV2ZXJzZUNyaXRpY2FsaXR5TGlzdH0gPSBcJVRtcEhhc2gyOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAkU2VsZjsKfQoKPWl0ZW0gT2JqZWN0QXR0cmlidXRlc0dldCgpCgpnZXQgdGhlIG9iamVjdCBhdHRyaWJ1dGVzIG9mIGFuIG9iamVjdCBhcyBhcnJheS9oYXNoIHJlZmVyZW5jZQoKICAgIG15ICRBdHRyaWJ1dGVzID0gJE9iamVjdEJhY2tlbmQtPk9iamVjdEF0dHJpYnV0ZXNHZXQoCiAgICAgICAgVXNlcklEID0+IDEsCiAgICApOwoKPWN1dAoKc3ViIE9iamVjdEF0dHJpYnV0ZXNHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBvYmplY3QKICAgIGlmICggISRQYXJhbXtVc2VySUR9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fQogICAgICAgICAgICAtPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAnTmVlZCBVc2VySUQhJyApOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIG15ICVWYWxpZGxpc3QgID0gJFNlbGYtPntWYWxpZE9iamVjdH0tPlZhbGlkTGlzdCgpOwogICAgbXkgJEF0dHJpYnV0ZXMgPSBbCiAgICAgICAgewogICAgICAgICAgICBLZXkgICA9PiAnRGVmYXVsdFZhbGlkJywKICAgICAgICAgICAgTmFtZSAgPT4gJ0RlZmF1bHQgVmFsaWRpdHknLAogICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAgICAgICAgICAgICBUeXBlICAgICAgICAgPT4gJ1NlbGVjdGlvbicsCiAgICAgICAgICAgICAgICBEYXRhICAgICAgICAgPT4gXCVWYWxpZGxpc3QsCiAgICAgICAgICAgICAgICBSZXF1aXJlZCAgICAgPT4gMSwKICAgICAgICAgICAgICAgIFRyYW5zbGF0aW9uICA9PiAxLAogICAgICAgICAgICAgICAgUG9zc2libGVOb25lID0+IDAsCiAgICAgICAgICAgICAgICBWYWx1ZURlZmF1bHQgPT4gMSwKICAgICAgICAgICAgfSwKICAgICAgICB9LAogICAgXTsKICAgIGlmICggJFNlbGYtPntTZXJ2aWNlVHlwZUxpc3R9ICkgewogICAgICAgIG15ICRTZXJ2aWNlVHlwZURlZmF1bHQgPSB7CiAgICAgICAgICAgIEtleSAgID0+ICdEZWZhdWx0U2VydmljZVR5cGVJRCcsCiAgICAgICAgICAgIE5hbWUgID0+ICdEZWZhdWx0IFNlcnZpY2UgVHlwZScsCiAgICAgICAgICAgIElucHV0ID0+IHsKICAgICAgICAgICAgICAgIFR5cGUgICAgICAgICA9PiAnU2VsZWN0aW9uJywKICAgICAgICAgICAgICAgIERhdGEgICAgICAgICA9PiAkU2VsZi0+e1NlcnZpY2VUeXBlTGlzdH0sCiAgICAgICAgICAgICAgICBSZXF1aXJlZCAgICAgPT4gMSwKICAgICAgICAgICAgICAgIFRyYW5zbGF0aW9uICA9PiAwLAogICAgICAgICAgICAgICAgUG9zc2libGVOb25lID0+IDAsCiAgICAgICAgICAgIH0sCiAgICAgICAgfTsKICAgICAgICBwdXNoKCBAeyRBdHRyaWJ1dGVzfSwgJFNlcnZpY2VUeXBlRGVmYXVsdCApOwogICAgfQogICAgaWYgKCAkU2VsZi0+e0NyaXRpY2FsaXR5TGlzdH0gKSB7CiAgICAgICAgbXkgJENyaXRpY2FsaXR5RGVmYXVsdCA9IHsKICAgICAgICAgICAgS2V5ICAgPT4gJ0RlZmF1bHRDcml0aWNhbGl0eUlEJywKICAgICAgICAgICAgTmFtZSAgPT4gJ0RlZmF1bHQgQ3JpdGljYWxpdHknLAogICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAgICAgICAgICAgICBUeXBlICAgICAgICAgPT4gJ1NlbGVjdGlvbicsCiAgICAgICAgICAgICAgICBEYXRhICAgICAgICAgPT4gJFNlbGYtPntDcml0aWNhbGl0eUxpc3R9LAogICAgICAgICAgICAgICAgUmVxdWlyZWQgICAgID0+IDEsCiAgICAgICAgICAgICAgICBUcmFuc2xhdGlvbiAgPT4gMCwKICAgICAgICAgICAgICAgIFBvc3NpYmxlTm9uZSA9PiAwLAogICAgICAgICAgICB9LAogICAgICAgIH07CiAgICAgICAgcHVzaCggQHskQXR0cmlidXRlc30sICRDcml0aWNhbGl0eURlZmF1bHQgKTsKICAgIH0KICAgIHJldHVybiAkQXR0cmlidXRlczsKfQoKPWl0ZW0gTWFwcGluZ09iamVjdEF0dHJpYnV0ZXNHZXQoKQoKZ2V0IHRoZSBtYXBwaW5nIGF0dHJpYnV0ZXMgb2YgYW4gb2JqZWN0IGFzIGFycmF5L2hhc2ggcmVmZXJlbmNlCgogICAgbXkgJEF0dHJpYnV0ZXMgPSAkT2JqZWN0QmFja2VuZC0+TWFwcGluZ09iamVjdEF0dHJpYnV0ZXNHZXQoCiAgICAgICAgVGVtcGxhdGVJRCA9PiAxMjMsCiAgICAgICAgVXNlcklEICAgICA9PiAxLAogICAgKTsKCj1jdXQKCnN1YiBNYXBwaW5nT2JqZWN0QXR0cmlidXRlc0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgbXkgJEFyZ3VtZW50IChxdyhUZW1wbGF0ZUlEIFVzZXJJRCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JEFyZ3VtZW50fSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJEFyZ3VtZW50ISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBnZXQgb2JqZWN0IGRhdGEKICAgIG15ICRPYmplY3REYXRhID0gJFNlbGYtPntJbXBvcnRFeHBvcnRPYmplY3R9LT5PYmplY3REYXRhR2V0KAogICAgICAgIFRlbXBsYXRlSUQgPT4gJFBhcmFte1RlbXBsYXRlSUR9LAogICAgICAgIFVzZXJJRCAgICAgPT4gJFBhcmFte1VzZXJJRH0sCiAgICApOwogICAgbXkgJEVsZW1lbnRMaXN0ID0gWwogICAgICAgIHsKICAgICAgICAgICAgS2V5ICAgPT4gJ1NlcnZpY2VJRCcsCiAgICAgICAgICAgIFZhbHVlID0+ICdTZXJ2aWNlIElEJywKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgS2V5ICAgPT4gJ05hbWUnLAogICAgICAgICAgICBWYWx1ZSA9PiAnRnVsbCBTZXJ2aWNlIE5hbWUnLAogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICBLZXkgICA9PiAnTmFtZVNob3J0JywKICAgICAgICAgICAgVmFsdWUgPT4gJ1Nob3J0IFNlcnZpY2UgTmFtZScsCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgIEtleSAgID0+ICdWYWxpZCcsCiAgICAgICAgICAgIFZhbHVlID0+ICdWYWxpZGl0eScsCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgIEtleSAgID0+ICdDb21tZW50JywKICAgICAgICAgICAgVmFsdWUgPT4gJ0NvbW1lbnQnLAogICAgICAgIH0sCiAgICBdOwoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgZ2V0IHByZWZlcmVuY2VzLi4uCiAgICBteSAlUHJlZmVyZW5jZXMgPSAoKTsKICAgIGlmICggJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ1NlcnZpY2VQcmVmZXJlbmNlcycpICkgewogICAgICAgICVQcmVmZXJlbmNlcyA9ICV7ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdTZXJ2aWNlUHJlZmVyZW5jZXMnKSB9OwogICAgfQogICAgZm9yIG15ICRJdGVtICggc29ydCBrZXlzICVQcmVmZXJlbmNlcyApIHsKICAgICAgICBpZiAoCiAgICAgICAgICAgICRQcmVmZXJlbmNlc3skSXRlbX0tPntTZWxlY3Rpb25Tb3VyY2V9CiAgICAgICAgICAgICYmICRQcmVmZXJlbmNlc3skSXRlbX0tPntQcmVmS2V5fSA9fiAvXiguKylJRCQvCiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIG15ICROYW1lUGFydCA9ICQxOwogICAgICAgICAgICBwdXNoKAogICAgICAgICAgICAgICAgQHskRWxlbWVudExpc3R9LAogICAgICAgICAgICAgICAgeyBLZXkgPT4gJE5hbWVQYXJ0LCBWYWx1ZSA9PiAkUHJlZmVyZW5jZXN7JEl0ZW19LT57TGFiZWx9IH0KICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIGlmICggJFByZWZlcmVuY2VzeyRJdGVtfS0+e1ByZWZLZXl9ID1+IC9eKC4rKUlEJC8gKSB7CiAgICAgICAgICAgIG15ICROYW1lUGFydCA9ICQxOwogICAgICAgICAgICBwdXNoKAogICAgICAgICAgICAgICAgQHskRWxlbWVudExpc3R9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSAgID0+ICRQcmVmZXJlbmNlc3skSXRlbX0tPntQcmVmS2V5fSwKICAgICAgICAgICAgICAgICAgICBWYWx1ZSA9PiAkUHJlZmVyZW5jZXN7JEl0ZW19LT57TGFiZWx9IC4gIiAoSUQpIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcHVzaCgKICAgICAgICAgICAgICAgIEB7JEVsZW1lbnRMaXN0fSwKICAgICAgICAgICAgICAgIHsgS2V5ID0+ICRQcmVmZXJlbmNlc3skSXRlbX0tPntQcmVmS2V5fSwgVmFsdWUgPT4gJFByZWZlcmVuY2VzeyRJdGVtfS0+e0xhYmVsfSB9CiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgIH0KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIHVzaW5nIGNpcml0Y2FsaXR5L3NlcnZpY2V0eXBlLWxpc3QgYXMgaW5kaWNhdG9yIGZvciBJVFNNLWluc3RhbGxhdGlvbi4uLgogICAgaWYgKCAkU2VsZi0+e0NyaXRpY2FsaXR5TGlzdH0gJiYgJFNlbGYtPntTZXJ2aWNlVHlwZUxpc3R9ICkgewogICAgICAgIG15ICRFbGVtZW50TGlzdElUU00gPSBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSAgID0+ICdUeXBlJywKICAgICAgICAgICAgICAgIFZhbHVlID0+ICdTZXJ2aWNlIFR5cGUgKElUU00gb25seSknLAogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgICA9PiAnQ3JpdGljYWxpdHknLAogICAgICAgICAgICAgICAgVmFsdWUgPT4gJ0NyaXRpY2FsaXR5IChJVFNNIG9ubHkpJywKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ICAgPT4gJ0N1ckluY2lTdGF0ZScsCiAgICAgICAgICAgICAgICBWYWx1ZSA9PiAnQ3VycmVudCBJbmNpZGVudCBTdGF0ZSAoSVRTTSBvbmx5KScsCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSAgID0+ICdDdXJJbmNpU3RhdGVUeXBlJywKICAgICAgICAgICAgICAgIFZhbHVlID0+ICdDdXJyZW50IEluY2lkZW50IFN0YXRlIFR5cGUgKElUU00gb25seSknLAogICAgICAgICAgICB9LAogICAgICAgIF07CiAgICAgICAgbXkgQFRtcEFycmF5ID0gKCBAeyRFbGVtZW50TGlzdH0sIEB7JEVsZW1lbnRMaXN0SVRTTX0gKTsKICAgICAgICAkRWxlbWVudExpc3QgPSBcQFRtcEFycmF5OwogICAgfQogICAgbXkgJEF0dHJpYnV0ZXMgPSBbCiAgICAgICAgewogICAgICAgICAgICBLZXkgICA9PiAnS2V5JywKICAgICAgICAgICAgTmFtZSAgPT4gJ0tleScsCiAgICAgICAgICAgIElucHV0ID0+IHsKICAgICAgICAgICAgICAgIFR5cGUgICAgICAgICA9PiAnU2VsZWN0aW9uJywKICAgICAgICAgICAgICAgIERhdGEgICAgICAgICA9PiAkRWxlbWVudExpc3QsCiAgICAgICAgICAgICAgICBSZXF1aXJlZCAgICAgPT4gMSwKICAgICAgICAgICAgICAgIFRyYW5zbGF0aW9uICA9PiAxLAogICAgICAgICAgICAgICAgUG9zc2libGVOb25lID0+IDEsCiAgICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgIEtleSAgID0+ICdJZGVudGlmaWVyJywKICAgICAgICAgICAgTmFtZSAgPT4gJ0lkZW50aWZpZXInLAogICAgICAgICAgICBJbnB1dCA9PiB7IFR5cGUgPT4gJ0NoZWNrYm94JywgfSwKICAgICAgICB9LAogICAgXTsKfQoKPWl0ZW0gU2VhcmNoQXR0cmlidXRlc0dldCgpCgpnZXQgdGhlIHNlYXJjaCBvYmplY3QgYXR0cmlidXRlcyBvZiBhbiBvYmplY3QgYXMgYXJyYXkvaGFzaCByZWZlcmVuY2UKCiAgICBteSAkQXR0cmlidXRlTGlzdCA9ICRPYmplY3RCYWNrZW5kLT5TZWFyY2hBdHRyaWJ1dGVzR2V0KAogICAgICAgIFRlbXBsYXRlSUQgPT4gMTIzLAogICAgICAgIFVzZXJJRCAgICAgPT4gMSwKICAgICk7Cgo9Y3V0CgpzdWIgU2VhcmNoQXR0cmlidXRlc0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgbXkgJEFyZ3VtZW50IChxdyhUZW1wbGF0ZUlEIFVzZXJJRCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JEFyZ3VtZW50fSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJEFyZ3VtZW50ISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CiAgICBteSAkQXR0cmlidXRlTGlzdCA9IFsKICAgICAgICB7CiAgICAgICAgICAgIEtleSAgID0+ICdTZXJ2aWNlTmFtZScsCiAgICAgICAgICAgIE5hbWUgID0+ICdTZXJ2aWNlIE5hbWUnLAogICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAgICAgICAgICAgICBUeXBlICAgICAgPT4gJ1RleHQnLAogICAgICAgICAgICAgICAgU2l6ZSAgICAgID0+IDgwLAogICAgICAgICAgICAgICAgTWF4TGVuZ3RoID0+IDI1NSwKICAgICAgICAgICAgfSwKICAgICAgICB9LAogICAgXTsKICAgIHJldHVybiAkQXR0cmlidXRlTGlzdDsKfQoKPWl0ZW0gRXhwb3J0RGF0YUdldCgpCgpnZXQgZXhwb3J0IGRhdGEgYXMgMkQtYXJyYXktaGFzaCByZWZlcmVuY2UKCiAgICBteSAkRXhwb3J0RGF0YSA9ICRPYmplY3RCYWNrZW5kLT5FeHBvcnREYXRhR2V0KAogICAgICAgIFRlbXBsYXRlSUQgPT4gMTIzLAogICAgICAgIFVzZXJJRCAgICAgPT4gMSwKICAgICk7Cgo9Y3V0CgpzdWIgRXhwb3J0RGF0YUdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgbXkgJEFyZ3VtZW50IChxdyhUZW1wbGF0ZUlEIFVzZXJJRCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JEFyZ3VtZW50fSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJEFyZ3VtZW50ISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBnZXQgb2JqZWN0IGRhdGEKICAgIG15ICRPYmplY3REYXRhID0gJFNlbGYtPntJbXBvcnRFeHBvcnRPYmplY3R9LT5PYmplY3REYXRhR2V0KAogICAgICAgIFRlbXBsYXRlSUQgPT4gJFBhcmFte1RlbXBsYXRlSUR9LAogICAgICAgIFVzZXJJRCAgICAgPT4gJFBhcmFte1VzZXJJRH0sCiAgICApOwoKICAgICMgY2hlY2sgb2JqZWN0IGRhdGEKICAgIGlmICggISRPYmplY3REYXRhIHx8IHJlZiAkT2JqZWN0RGF0YSBuZSAnSEFTSCcgKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJObyBvYmplY3QgZGF0YSBmb3VuZCBmb3IgdGhlIHRlbXBsYXRlIGlkICRQYXJhbXtUZW1wbGF0ZUlEfSIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBnZXQgdGhlIG1hcHBpbmcgbGlzdAogICAgbXkgJE1hcHBpbmdMaXN0ID0gJFNlbGYtPntJbXBvcnRFeHBvcnRPYmplY3R9LT5NYXBwaW5nTGlzdCgKICAgICAgICBUZW1wbGF0ZUlEID0+ICRQYXJhbXtUZW1wbGF0ZUlEfSwKICAgICAgICBVc2VySUQgICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgKTsKCiAgICAjIGNoZWNrIHRoZSBtYXBwaW5nIGxpc3QKICAgIGlmICggISRNYXBwaW5nTGlzdCB8fCByZWYgJE1hcHBpbmdMaXN0IG5lICdBUlJBWScgfHwgIUB7JE1hcHBpbmdMaXN0fSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5vIHZhbGlkIG1hcHBpbmcgbGlzdCBmb3VuZCBmb3IgdGhlIHRlbXBsYXRlIGlkICRQYXJhbXtUZW1wbGF0ZUlEfSIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBjcmVhdGUgdGhlIG1hcHBpbmcgb2JqZWN0IGxpc3QKICAgIG15IEBNYXBwaW5nT2JqZWN0TGlzdDsKICAgIGZvciBteSAkTWFwcGluZ0lEICggQHskTWFwcGluZ0xpc3R9ICkgewoKICAgICAgICAjIGdldCBtYXBwaW5nIG9iamVjdCBkYXRhCiAgICAgICAgbXkgJE1hcHBpbmdPYmplY3REYXRhID0KICAgICAgICAgICAgJFNlbGYtPntJbXBvcnRFeHBvcnRPYmplY3R9LT5NYXBwaW5nT2JqZWN0RGF0YUdldCgKICAgICAgICAgICAgTWFwcGluZ0lEID0+ICRNYXBwaW5nSUQsCiAgICAgICAgICAgIFVzZXJJRCAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICAgICAgICAgKTsKCiAgICAgICAgIyBjaGVjayBtYXBwaW5nIG9iamVjdCBkYXRhCiAgICAgICAgaWYgKCAhJE1hcHBpbmdPYmplY3REYXRhIHx8IHJlZiAkTWFwcGluZ09iamVjdERhdGEgbmUgJ0hBU0gnICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTm8gdmFsaWQgbWFwcGluZyBsaXN0IGZvdW5kIGZvciB0aGUgdGVtcGxhdGUgaWQgJFBhcmFte1RlbXBsYXRlSUR9IiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBwdXNoKCBATWFwcGluZ09iamVjdExpc3QsICRNYXBwaW5nT2JqZWN0RGF0YSApOwogICAgfQoKICAgICMgZ2V0IHNlYXJjaCBkYXRhCiAgICBteSAkU2VhcmNoRGF0YSA9ICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fS0+U2VhcmNoRGF0YUdldCgKICAgICAgICBUZW1wbGF0ZUlEID0+ICRQYXJhbXtUZW1wbGF0ZUlEfSwKICAgICAgICBVc2VySUQgICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgKTsKICAgIGlmICggJFNlYXJjaERhdGEgJiYgcmVmKCRTZWFyY2hEYXRhKSBuZSAnSEFTSCcgKSB7CiAgICAgICAgJFNlYXJjaERhdGEgPSAwOwogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlID0+CiAgICAgICAgICAgICAgICAiU2VydmljZTJDdXN0b21lclVzZXI6IHNlYXJjaCBkYXRhIGlzIG5vdCBhIGhhc2ggcmVmIC0gaWdub3Jpbmcgc2VhcmNoIGxpbWl0YXRpb24uIiwKICAgICAgICApOwogICAgfQogICAgbXkgQFNlcnZpY2VMaXN0ID0gJFNlbGYtPntTZXJ2aWNlT2JqZWN0fS0+U2VydmljZVNlYXJjaCgKICAgICAgICBOYW1lICA9PiAkU2VhcmNoRGF0YS0+e1NlcnZpY2VOYW1lfSB8fCAnJywKICAgICAgICBMaW1pdCA9PiAkU2VhcmNoRGF0YS0+e0xpbWl0fSAgICAgICB8fCAnMCcsCiAgICAgICAgVXNlcklEID0+IDEsCgogICAgICAgICMgbm8gZnVydGhlciByZXN0cmljdGlvbiB5ZXQuLi4KICAgICAgICAjVHlwZUlEcyAgICAgICAgPT4gMiwKICAgICAgICAjQ3JpdGljYWxpdHlJRHMgPT4gMSwKICAgICk7CgogICAgIyBleHBvcnQgZGF0YS4uLgogICAgbXkgQEV4cG9ydERhdGE7CgogICAgIyBnZXQgcHJlZmVyZW5jZXMgY29uZmlndXJhdGlvbi4uLgogICAgbXkgJVByZWZlcmVuY2VzID0gKCk7CiAgICBpZiAoICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdTZXJ2aWNlUHJlZmVyZW5jZXMnKSApIHsKICAgICAgICBteSAlUHJlZkNvbmZpZyA9ICV7ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdTZXJ2aWNlUHJlZmVyZW5jZXMnKSB9OwogICAgICAgIGZvciBteSAkQ3VycktleSAoIGtleXMoJVByZWZDb25maWcpICkgewogICAgICAgICAgICBteSAlQ3VyclByZWZzID0gKCk7CiAgICAgICAgICAgICRDdXJyUHJlZnN7TGFiZWx9ICAgICAgICAgICAgICAgPSAkUHJlZkNvbmZpZ3skQ3VycktleX0tPntMYWJlbH07CiAgICAgICAgICAgICRDdXJyUHJlZnN7U2VsZWN0aW9uU291cmNlfSAgICAgPSAkUHJlZkNvbmZpZ3skQ3VycktleX0tPntTZWxlY3Rpb25Tb3VyY2V9OwogICAgICAgICAgICAkQ3VyclByZWZze0dlbmVyYWxDYXRhbG9nQ2xhc3N9ID0gJFByZWZDb25maWd7JEN1cnJLZXl9LT57R2VuZXJhbENhdGFsb2dDbGFzc307CiAgICAgICAgICAgICRQcmVmZXJlbmNlc3sgJFByZWZDb25maWd7JEN1cnJLZXl9LT57UHJlZktleX0gfSA9IFwlQ3VyclByZWZzOwogICAgICAgIH0KICAgIH0KCgogICAgZm9yIG15ICRTZXJ2aWNlSUQgKEBTZXJ2aWNlTGlzdCkgewogICAgICAgIG15ICVTZXJ2aWNlRGF0YSA9ICRTZWxmLT57U2VydmljZU9iamVjdH0tPlNlcnZpY2VHZXQoCiAgICAgICAgICAgIFNlcnZpY2VJRCA9PiAkU2VydmljZUlELAogICAgICAgICAgICBVc2VySUQgICAgPT4gMSwgICAgICAgICAgICAjIG5vIHBlcm1pc3Npb24gcmVzdHJpY3Rpb24gZm9yIHRoaXMgZXhwb3J0CiAgICAgICAgKTsKCiAgICAgICAgI2V4cG9ydCB2YWxpZCBzdHJpbmcgaW5zdGVhZCBvZiBJRC4uLgogICAgICAgICRTZXJ2aWNlRGF0YXtWYWxpZH0gPSAkU2VsZi0+e1ZhbGlkT2JqZWN0fS0+VmFsaWRMb29rdXAoCiAgICAgICAgICAgIFZhbGlkSUQgPT4gJFNlcnZpY2VEYXRhe1ZhbGlkSUR9LAogICAgICAgICk7CgogICAgICAgIFBSRUZFUkVOQ0VDSEVDSzoKICAgICAgICBmb3IgbXkgJEN1cnJLZXkgKCBrZXlzKCVTZXJ2aWNlRGF0YSkgKSB7CgogICAgICAgICAgICAjIGNoZWNrIGlmIHRoaXMgaXMgYSBwcmVmZXJlbmNlLi4uCiAgICAgICAgICAgIG5leHQgUFJFRkVSRU5DRUNIRUNLIGlmICggISRQcmVmZXJlbmNlc3skQ3VycktleX0gKTsKCiAgICAgICAgICAgICMgY2hlY2sgaWYgdGhpcyBpcyBhbiBJRC1hdHRyaWJ1dGUuLi4KICAgICAgICAgICAgbmV4dCBQUkVGRVJFTkNFQ0hFQ0sgaWYgKCAkQ3VycktleSAhfiAvXiguKylJRCQvICk7CiAgICAgICAgICAgIG15ICROYW1lUGFydCA9ICQxOwoKICAgICAgICAgICAgIyBza2lwIGlmIGFuIGF0dHJpYnV0ZSB3aXRoIGEgc2ltaWxhciBuYW1lIGJ1dCBubyAiSUQiIHN1ZmZpeCBleGlzdHMuLi4KICAgICAgICAgICAgbmV4dCBQUkVGRVJFTkNFQ0hFQ0sgaWYgKCAkU2VydmljZURhdGF7JE5hbWVQYXJ0fSApOwoKICAgICAgICAgICAgIyBjaGVjayBmb3Igc291cmNlIG9mIHByZWZlcmVuY2UuLi4KICAgICAgICAgICAgbXkgJVNlbGVjdGlvbkxpc3QgPSAoKTsKICAgICAgICAgICAgaWYgKAogICAgICAgICAgICAgICAgJFByZWZlcmVuY2VzeyRDdXJyS2V5fS0+e1NlbGVjdGlvblNvdXJjZX0KICAgICAgICAgICAgICAgICYmICRQcmVmZXJlbmNlc3skQ3VycktleX0tPntTZWxlY3Rpb25Tb3VyY2V9IGVxICdRdWV1ZUxpc3QnCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICVTZWxlY3Rpb25MaXN0ID0gJFNlbGYtPntRdWV1ZU9iamVjdH0tPlF1ZXVlTGlzdCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2lmICgKICAgICAgICAgICAgICAgICRQcmVmZXJlbmNlc3skQ3VycktleX0tPntTZWxlY3Rpb25Tb3VyY2V9CiAgICAgICAgICAgICAgICAmJiAkUHJlZmVyZW5jZXN7JEN1cnJLZXl9LT57U2VsZWN0aW9uU291cmNlfSBlcSAnVHlwZUxpc3QnCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICVTZWxlY3Rpb25MaXN0ID0gJFNlbGYtPntUeXBlT2JqZWN0fS0+VHlwZUxpc3QoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNpZiAoCiAgICAgICAgICAgICAgICAoICRQcmVmZXJlbmNlc3skQ3VycktleX0tPntTZWxlY3Rpb25Tb3VyY2V9ICkKICAgICAgICAgICAgICAgICYmCiAgICAgICAgICAgICAgICAoICRQcmVmZXJlbmNlc3skQ3VycktleX0tPntTZWxlY3Rpb25Tb3VyY2V9IGVxICdHZW5lcmFsQ2F0YWxvZycgKQogICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICggJFByZWZlcmVuY2VzeyRDdXJyS2V5fS0+e0dlbmVyYWxDYXRhbG9nQ2xhc3N9ICkgJiYKICAgICAgICAgICAgICAgICRTZWxmLT57R2VuZXJhbENhdGFsb2dPYmplY3R9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIG15ICRJdGVtTGlzdFJlZiA9ICRTZWxmLT57R2VuZXJhbENhdGFsb2dPYmplY3R9LT5JdGVtTGlzdCgKICAgICAgICAgICAgICAgICAgICBDbGFzcyA9PiAkUHJlZmVyZW5jZXN7JEN1cnJLZXl9LT57R2VuZXJhbENhdGFsb2dDbGFzc30sCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgaWYgKCAkSXRlbUxpc3RSZWYgJiYgcmVmKCRJdGVtTGlzdFJlZikgZXEgJ0hBU0gnICkgewogICAgICAgICAgICAgICAgICAgICVTZWxlY3Rpb25MaXN0ID0gJXskSXRlbUxpc3RSZWZ9OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAjIGNyZWF0ZSBub24tSUQgdmFsdWUgZm9yIGV4cG9ydC4uLgogICAgICAgICAgICAkU2VydmljZURhdGF7JE5hbWVQYXJ0fSA9ICRTZWxlY3Rpb25MaXN0eyAkU2VydmljZURhdGF7JEN1cnJLZXl9IH0KICAgICAgICAgICAgICAgIHx8ICRTZXJ2aWNlRGF0YXskQ3VycktleX07CgogICAgICAgIH0KCiAgICAgICAgbXkgQEN1cnJSb3cgPSBxd3t9OwogICAgICAgIGZvciBteSAkTWFwcGluZ09iamVjdCAoQE1hcHBpbmdPYmplY3RMaXN0KSB7CiAgICAgICAgICAgIG15ICRLZXkgPSAkTWFwcGluZ09iamVjdC0+e0tleX07CiAgICAgICAgICAgIGlmICggJE1hcHBpbmdPYmplY3QtPntLZXl9ICYmICRTZXJ2aWNlRGF0YXsgJE1hcHBpbmdPYmplY3QtPntLZXl9IH0gKSB7CiAgICAgICAgICAgICAgICBwdXNoKCBAQ3VyclJvdywgJFNlcnZpY2VEYXRheyAkTWFwcGluZ09iamVjdC0+e0tleX0gfSApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcHVzaCggQEN1cnJSb3csICctJyApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHB1c2ggQEV4cG9ydERhdGEsIFxAQ3VyclJvdzsKICAgIH0KICAgIHJldHVybiBcQEV4cG9ydERhdGE7Cn0KCj1pdGVtIEltcG9ydERhdGFTYXZlKCkKCmltcG9ydCBvbmUgcm93IG9mIHRoZSBpbXBvcnQgZGF0YQoKICAgIG15ICRDb25maWdJdGVtSUQgPSAkT2JqZWN0QmFja2VuZC0+SW1wb3J0RGF0YVNhdmUoCiAgICAgICAgVGVtcGxhdGVJRCAgICA9PiAxMjMsCiAgICAgICAgSW1wb3J0RGF0YVJvdyA9PiAkQXJyYXlSZWYsCiAgICAgICAgVXNlcklEICAgICAgICA9PiAxLAogICAgKTsKCj1jdXQKCnN1YiBJbXBvcnREYXRhU2F2ZSB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgbXkgJEFyZ3VtZW50IChxdyhUZW1wbGF0ZUlEIEltcG9ydERhdGFSb3cgVXNlcklEKSkgewogICAgICAgIGlmICggISRQYXJhbXskQXJndW1lbnR9ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCAkQXJndW1lbnQhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGNoZWNrIGltcG9ydCBkYXRhIHJvdwogICAgaWYgKCByZWYgJFBhcmFte0ltcG9ydERhdGFSb3d9IG5lICdBUlJBWScgKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdJbXBvcnREYXRhUm93IG11c3QgYmUgYW4gYXJyYXkgcmVmZXJlbmNlJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGdldCBvYmplY3QgZGF0YQogICAgbXkgJE9iamVjdERhdGEgPSAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPk9iamVjdERhdGFHZXQoCiAgICAgICAgVGVtcGxhdGVJRCA9PiAkUGFyYW17VGVtcGxhdGVJRH0sCiAgICAgICAgVXNlcklEICAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICk7CgogICAgIyBjaGVjayBvYmplY3QgZGF0YQogICAgaWYgKCAhJE9iamVjdERhdGEgfHwgcmVmICRPYmplY3REYXRhIG5lICdIQVNIJyApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5vIG9iamVjdCBkYXRhIGZvdW5kIGZvciB0aGUgdGVtcGxhdGUgaWQgJFBhcmFte1RlbXBsYXRlSUR9IiwKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGdldCB0aGUgbWFwcGluZyBsaXN0CiAgICBteSAkTWFwcGluZ0xpc3QgPSAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPk1hcHBpbmdMaXN0KAogICAgICAgIFRlbXBsYXRlSUQgPT4gJFBhcmFte1RlbXBsYXRlSUR9LAogICAgICAgIFVzZXJJRCAgICAgPT4gJFBhcmFte1VzZXJJRH0sCiAgICApOwoKICAgICMgY2hlY2sgdGhlIG1hcHBpbmcgbGlzdAogICAgaWYgKCAhJE1hcHBpbmdMaXN0IHx8IHJlZiAkTWFwcGluZ0xpc3QgbmUgJ0FSUkFZJyB8fCAhQHskTWFwcGluZ0xpc3R9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAiTm8gdmFsaWQgbWFwcGluZyBsaXN0IGZvdW5kIGZvciB0aGUgdGVtcGxhdGUgaWQgJFBhcmFte1RlbXBsYXRlSUR9IiwKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGNyZWF0ZSB0aGUgbWFwcGluZyBvYmplY3QgbGlzdAogICAgbXkgQE1hcHBpbmdPYmplY3RMaXN0OwogICAgbXkgJUlkZW50aWZpZXI7CiAgICBteSAkQ291bnRlciAgICAgICAgICAgICAgPSAwOwogICAgbXkgJU5ld1NlcnZpY2VEYXRhICAgICAgID0gcXd7fTsKICAgIG15ICRTZXJ2aWNlSWRlbnRpZmllcktleSA9ICIiOwoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgI0JVSUxEIE1BUFBJTkcgVEFCTEUuLi4KICAgIGZvciBteSAkTWFwcGluZ0lEICggQHskTWFwcGluZ0xpc3R9ICkgewoKICAgICAgICAjIGdldCBtYXBwaW5nIG9iamVjdCBkYXRhCiAgICAgICAgbXkgJE1hcHBpbmdPYmplY3REYXRhID0KICAgICAgICAgICAgJFNlbGYtPntJbXBvcnRFeHBvcnRPYmplY3R9LT5NYXBwaW5nT2JqZWN0RGF0YUdldCgKICAgICAgICAgICAgTWFwcGluZ0lEID0+ICRNYXBwaW5nSUQsCiAgICAgICAgICAgIFVzZXJJRCAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICAgICAgICAgKTsKCiAgICAgICAgIyBjaGVjayBtYXBwaW5nIG9iamVjdCBkYXRhCiAgICAgICAgaWYgKCAhJE1hcHBpbmdPYmplY3REYXRhIHx8IHJlZiAkTWFwcGluZ09iamVjdERhdGEgbmUgJ0hBU0gnICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTm8gdmFsaWQgbWFwcGluZyBsaXN0IGZvdW5kIGZvciB0ZW1wbGF0ZSBpZCAkUGFyYW17VGVtcGxhdGVJRH0iLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIHB1c2goIEBNYXBwaW5nT2JqZWN0TGlzdCwgJE1hcHBpbmdPYmplY3REYXRhICk7CiAgICAgICAgaWYgKAogICAgICAgICAgICAkTWFwcGluZ09iamVjdERhdGEtPntJZGVudGlmaWVyfQogICAgICAgICAgICAmJiAkSWRlbnRpZmllcnsgJE1hcHBpbmdPYmplY3REYXRhLT57S2V5fSB9CiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJDYW4ndCBpbXBvcnQgdGhpcyBlbnRpdHkuICIKICAgICAgICAgICAgICAgICAgICAuICInJE1hcHBpbmdPYmplY3REYXRhLT57S2V5fScgaGFzIGJlZW4gdXNlZCBtdWx0aXBsZSAiCiAgICAgICAgICAgICAgICAgICAgLiAidGltZXMgYXMgaWRlbnRpZmllciAobGluZSAkUGFyYW17Q291bnRlcn0pLiEiLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGVsc2lmICggJE1hcHBpbmdPYmplY3REYXRhLT57SWRlbnRpZmllcn0gKSB7CiAgICAgICAgICAgICRJZGVudGlmaWVyeyAkTWFwcGluZ09iamVjdERhdGEtPntLZXl9IH0gPQogICAgICAgICAgICAgICAgJFBhcmFte0ltcG9ydERhdGFSb3d9LT5bJENvdW50ZXJdOwogICAgICAgICAgICAkU2VydmljZUlkZW50aWZpZXJLZXkgPSAkTWFwcGluZ09iamVjdERhdGEtPntLZXl9OwogICAgICAgIH0KICAgICAgICAkTmV3U2VydmljZURhdGF7ICRNYXBwaW5nT2JqZWN0RGF0YS0+e0tleX0gfSA9CiAgICAgICAgICAgICRQYXJhbXtJbXBvcnREYXRhUm93fS0+WyRDb3VudGVyXTsKCiAgICAgICAgI0VPIHNwZWNpYWwgdHJlYXRtZW50CiAgICAgICAgJENvdW50ZXIrKzsKICAgIH0KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgRE8gVEhFIElNUE9SVC4uLgogICAgIygwKSBQcmVwcm9jZXNzIGRhdGEuLi4KICAgIGlmICggISROZXdTZXJ2aWNlRGF0YXtGdWxsTmFtZX0gKSB7CiAgICAgICAgJE5ld1NlcnZpY2VEYXRhe0Z1bGxOYW1lfSA9ICROZXdTZXJ2aWNlRGF0YXtOYW1lfTsKICAgIH0KCiAgICAjIGxvb2t1cCBWYWxpZC1JRC4uLgogICAgaWYgKCAhJE5ld1NlcnZpY2VEYXRhe1ZhbGlkSUR9ICYmICROZXdTZXJ2aWNlRGF0YXtWYWxpZH0gKSB7CiAgICAgICAgJE5ld1NlcnZpY2VEYXRhe1ZhbGlkSUR9ID0gJFNlbGYtPntWYWxpZE9iamVjdH0tPlZhbGlkTG9va3VwKAogICAgICAgICAgICBWYWxpZCA9PiAkTmV3U2VydmljZURhdGF7VmFsaWR9CiAgICAgICAgKTsKICAgIH0KCiAgICAjIGRlZmF1bHQgdmFsaWRpdHkuLi4KICAgIGlmICggISROZXdTZXJ2aWNlRGF0YXtWYWxpZElEfSApIHsKICAgICAgICAkTmV3U2VydmljZURhdGF7VmFsaWRJRH0gPSAkT2JqZWN0RGF0YS0+e0RlZmF1bHRWYWxpZH0gfHwgMTsKICAgIH0KCiAgICAjIGxvb2t1cCBjcml0aWNhbGl0eS1JRC4uLgogICAgaWYgKAogICAgICAgICRTZWxmLT57UmV2ZXJzZUNyaXRpY2FsaXR5TGlzdH0KICAgICAgICAmJiAkTmV3U2VydmljZURhdGF7Q3JpdGljYWxpdHl9CiAgICAgICAgJiYgJFNlbGYtPntSZXZlcnNlQ3JpdGljYWxpdHlMaXN0fS0+eyAkTmV3U2VydmljZURhdGF7Q3JpdGljYWxpdHl9IH0KICAgICAgICApCiAgICB7CiAgICAgICAgJE5ld1NlcnZpY2VEYXRhe0NyaXRpY2FsaXR5SUR9ID0KICAgICAgICAgICAgJFNlbGYtPntSZXZlcnNlQ3JpdGljYWxpdHlMaXN0fS0+eyAkTmV3U2VydmljZURhdGF7Q3JpdGljYWxpdHl9IH07CiAgICB9CiAgICBpZiAoICEkTmV3U2VydmljZURhdGF7Q3JpdGljYWxpdHlJRH0gKSB7CiAgICAgICAgJE5ld1NlcnZpY2VEYXRhe0NyaXRpY2FsaXR5SUR9ID0gJE9iamVjdERhdGEtPntEZWZhdWx0Q3JpdGljYWxpdHlJRH07CiAgICB9CgogICAgIyBsb29rdXAgdHlwZS1JRC4uLgogICAgaWYgKAogICAgICAgICRTZWxmLT57UmV2ZXJzZVNlcnZpY2VUeXBlTGlzdH0KICAgICAgICAmJiAkTmV3U2VydmljZURhdGF7VHlwZX0KICAgICAgICAmJiAkU2VsZi0+e1JldmVyc2VTZXJ2aWNlVHlwZUxpc3R9LT57ICROZXdTZXJ2aWNlRGF0YXtUeXBlfSB9CiAgICAgICAgKQogICAgewogICAgICAgICROZXdTZXJ2aWNlRGF0YXtUeXBlSUR9ID0gJFNlbGYtPntSZXZlcnNlU2VydmljZVR5cGVMaXN0fS0+eyAkTmV3U2VydmljZURhdGF7VHlwZX0gfTsKICAgIH0KICAgIGlmICggISROZXdTZXJ2aWNlRGF0YXtUeXBlSUR9ICkgewogICAgICAgICROZXdTZXJ2aWNlRGF0YXtUeXBlSUR9ID0gJE9iamVjdERhdGEtPntEZWZhdWx0U2VydmljZVR5cGVJRH07CiAgICB9CiAgICBpZiAoICROZXdTZXJ2aWNlRGF0YXtOYW1lfSAmJiAkTmV3U2VydmljZURhdGF7TmFtZX0gPX4gLzo6LyApIHsKICAgICAgICBteSBATmFtZVBhcnRzQXJyID0gc3BsaXQoICI6OiIsICROZXdTZXJ2aWNlRGF0YXtOYW1lfSApOwogICAgICAgICROZXdTZXJ2aWNlRGF0YXtOYW1lfSAgICAgPSBwb3AoQE5hbWVQYXJ0c0Fycik7CiAgICAgICAgJE5ld1NlcnZpY2VEYXRhe1BhcmVudElEfSA9ICRTZWxmLT57U2VydmljZU9iamVjdH0tPlNlcnZpY2VMb29rdXAoCiAgICAgICAgICAgIE5hbWUgPT4gam9pbiggIjo6IiwgQE5hbWVQYXJ0c0FyciApLAogICAgICAgICk7CiAgICB9CgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBwcmVwYXJlIHByZWZlcmVuY2VzLi4uCgogICAgIyBnZXQgcHJlZmVyZW5jZXMgY29uZmlndXJhdGlvbi4uLgogICAgbXkgJVByZWZlcmVuY2VzID0gKCk7CiAgICBpZiAoICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdTZXJ2aWNlUHJlZmVyZW5jZXMnKSApIHsKICAgICAgICBteSAlUHJlZkNvbmZpZyA9ICV7ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdTZXJ2aWNlUHJlZmVyZW5jZXMnKSB9OwogICAgICAgIGZvciBteSAkQ3VycktleSAoIGtleXMoJVByZWZDb25maWcpICkgewogICAgICAgICAgICBteSAlQ3VyclByZWZzID0gKCk7CiAgICAgICAgICAgICRDdXJyUHJlZnN7TGFiZWx9ICAgICAgICAgICAgICAgPSAkUHJlZkNvbmZpZ3skQ3VycktleX0tPntMYWJlbH07CiAgICAgICAgICAgICRDdXJyUHJlZnN7U2VsZWN0aW9uU291cmNlfSAgICAgPSAkUHJlZkNvbmZpZ3skQ3VycktleX0tPntTZWxlY3Rpb25Tb3VyY2V9OwogICAgICAgICAgICAkQ3VyclByZWZze0dlbmVyYWxDYXRhbG9nQ2xhc3N9ID0gJFByZWZDb25maWd7JEN1cnJLZXl9LT57R2VuZXJhbENhdGFsb2dDbGFzc307CiAgICAgICAgICAgICRQcmVmZXJlbmNlc3sgJFByZWZDb25maWd7JEN1cnJLZXl9LT57UHJlZktleX0gfSA9IFwlQ3VyclByZWZzOwogICAgICAgIH0KICAgIH0KCiAgICBQUkVGRVJFTkNFQ0hFQ0s6CiAgICBmb3IgbXkgJEN1cnJLZXkgKCBrZXlzKCVOZXdTZXJ2aWNlRGF0YSkgKSB7CiAgICAgICAgbXkgJEN1cnJVc2VkS2V5ID0gIiI7CiAgICAgICAgbXkgJE5hbWVQYXJ0ICAgID0gJEN1cnJLZXk7CiAgICAgICAgaWYgKCAkQ3VycktleSA9fiAvXiguKylJRCQvICkgewogICAgICAgICAgICAkTmFtZVBhcnQgICAgPSAkMTsKICAgICAgICAgICAgJEN1cnJVc2VkS2V5ID0gJEN1cnJLZXk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAkQ3VyclVzZWRLZXkgPSAkQ3VycktleSAuICJJRCI7CiAgICAgICAgfQoKICAgICAgICAjIHNraXAgaWYgbm8gcHJlZmVyZW5jZSB3aXRoIHNhbWUgbmFtZSBidXQgc3VmZml4ICJJRCIgZXhpc3RzLi4uCiAgICAgICAgbmV4dCBQUkVGRVJFTkNFQ0hFQ0sgaWYgKCAhJFByZWZlcmVuY2VzeyRDdXJyVXNlZEtleX0gKTsKCiAgICAgICAgIyBza2lwIGlmIG5vIFNlbGVjdGlvblNvdXJjZSBzcGVjaWZpZWQuLgogICAgICAgIG5leHQgUFJFRkVSRU5DRUNIRUNLIGlmICggISRQcmVmZXJlbmNlc3skQ3VyclVzZWRLZXl9LT57U2VsZWN0aW9uU291cmNlfSApOwoKICAgICAgICAjIGNoZWNrIGZvciBzb3VyY2Ugb2YgcHJlZmVyZW5jZS4uLgogICAgICAgIG15ICVTZWxlY3Rpb25MaXN0ID0gKCk7CiAgICAgICAgaWYgKCAkUHJlZmVyZW5jZXN7JEN1cnJVc2VkS2V5fS0+e1NlbGVjdGlvblNvdXJjZX0gZXEgJ1F1ZXVlTGlzdCcgKSB7CiAgICAgICAgICAgICVTZWxlY3Rpb25MaXN0ID0gJFNlbGYtPntRdWV1ZU9iamVjdH0tPlF1ZXVlTGlzdCgpOwogICAgICAgIH0KICAgICAgICBlbHNpZiAoICRQcmVmZXJlbmNlc3skQ3VyclVzZWRLZXl9LT57U2VsZWN0aW9uU291cmNlfSBlcSAnVHlwZUxpc3QnICkgewogICAgICAgICAgICAlU2VsZWN0aW9uTGlzdCA9ICRTZWxmLT57VHlwZU9iamVjdH0tPlR5cGVMaXN0KCk7CiAgICAgICAgfQogICAgICAgIGVsc2lmICgKICAgICAgICAgICAgKCAkUHJlZmVyZW5jZXN7JEN1cnJVc2VkS2V5fS0+e1NlbGVjdGlvblNvdXJjZX0gZXEgJ0dlbmVyYWxDYXRhbG9nJyApCiAgICAgICAgICAgICYmCiAgICAgICAgICAgICggJFByZWZlcmVuY2VzeyRDdXJyVXNlZEtleX0tPntHZW5lcmFsQ2F0YWxvZ0NsYXNzfSApICYmCiAgICAgICAgICAgICRTZWxmLT57R2VuZXJhbENhdGFsb2dPYmplY3R9CiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIG15ICRJdGVtTGlzdFJlZiA9ICRTZWxmLT57R2VuZXJhbENhdGFsb2dPYmplY3R9LT5JdGVtTGlzdCgKICAgICAgICAgICAgICAgIENsYXNzID0+ICRQcmVmZXJlbmNlc3skQ3VyclVzZWRLZXl9LT57R2VuZXJhbENhdGFsb2dDbGFzc30sCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIGlmICggJEl0ZW1MaXN0UmVmICYmIHJlZigkSXRlbUxpc3RSZWYpIGVxICdIQVNIJyApIHsKICAgICAgICAgICAgICAgICVTZWxlY3Rpb25MaXN0ID0gJXskSXRlbUxpc3RSZWZ9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIG15ICVSZXZlcnNlU2VsZWN0aW9uTGlzdCA9IHJldmVyc2UoJVNlbGVjdGlvbkxpc3QpOwoKICAgICAgICAjIGlmIG9ubHkgeHh4SUQgaXMgZ2l2ZW4sIHNldCB4eHguLi4KICAgICAgICBpZiAoCiAgICAgICAgICAgICROZXdTZXJ2aWNlRGF0YXskQ3VyclVzZWRLZXl9CiAgICAgICAgICAgICYmICggISROZXdTZXJ2aWNlRGF0YXskTmFtZVBhcnR9IHx8ICROYW1lUGFydCBlcSAkQ3VyclVzZWRLZXkgKQogICAgICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICAkTmV3U2VydmljZURhdGF7JE5hbWVQYXJ0fSA9ICRTZWxlY3Rpb25MaXN0eyAkTmV3U2VydmljZURhdGF7JEN1cnJVc2VkS2V5fSB9OwogICAgICAgIH0KCiAgICAgICAgIyBpZiB4eHhJRCBBTkQgeHh4IGFyZSBnaXZlbiByZXF1aXJlIHVuaXFlbmVzcy4uLgogICAgICAgIGVsc2lmICggJE5ld1NlcnZpY2VEYXRheyRDdXJyVXNlZEtleX0gJiYgJE5ld1NlcnZpY2VEYXRheyROYW1lUGFydH0gKSB7CiAgICAgICAgICAgIG15ICRDb21wYXJlVmFsdWUgPSAkU2VsZWN0aW9uTGlzdHsgJE5ld1NlcnZpY2VEYXRheyRDdXJyVXNlZEtleX0gfTsKICAgICAgICAgICAgaWYgKCAkQ29tcGFyZVZhbHVlIG5lICROZXdTZXJ2aWNlRGF0YXskTmFtZVBhcnR9ICkgewogICAgICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiQ2FuJ3QgaW1wb3J0IHRoaXMgZW50aXR5LiAiCiAgICAgICAgICAgICAgICAgICAgICAgIC4gIkFtYmlnb3VzIGRlZmluaXRpb24gb2YgYXR0cmlidXRlIHZhbHVlcyAiCiAgICAgICAgICAgICAgICAgICAgICAgIC4gIiAoJE5hbWVQYXJ0IDwkTmV3U2VydmljZURhdGF7JE5hbWVQYXJ0fT4gZG9lcyBub3QiCiAgICAgICAgICAgICAgICAgICAgICAgIC4gIm1hdGNoICRDdXJyVXNlZEtleSA8JE5ld1NlcnZpY2VEYXRheyRDdXJyVXNlZEtleX0+KSEiLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyBpZiBvbmx5IHh4eCBpcyBnaXZlbiBhbmQgSUQgY2FuIGJlIGZvdW5kIC0gZ2V0IHRoZSBJRC4uLgogICAgICAgIGVsc2lmICggISROZXdTZXJ2aWNlRGF0YXskQ3VyclVzZWRLZXl9CiAgICAgICAgICAgICYmICROZXdTZXJ2aWNlRGF0YXskTmFtZVBhcnR9CiAgICAgICAgICAgICYmICRSZXZlcnNlU2VsZWN0aW9uTGlzdHsgJE5ld1NlcnZpY2VEYXRheyROYW1lUGFydH0gfSApCiAgICAgICAgewogICAgICAgICAgICAkTmV3U2VydmljZURhdGF7JEN1cnJVc2VkS2V5fSA9ICRSZXZlcnNlU2VsZWN0aW9uTGlzdHsgJE5ld1NlcnZpY2VEYXRheyROYW1lUGFydH0gfTsKICAgICAgICB9CgogICAgICAgICMgaWYgb25seSB4eHggaXMgZ2l2ZW4gYW5kIG5vIElEIGNhbiBiZSBmb3VuZCAtIHJlamVjdCBpbXBvcnQuLi4KICAgICAgICBlbHNpZiAoICEkTmV3U2VydmljZURhdGF7JEN1cnJVc2VkS2V5fQogICAgICAgICAgICAmJiAkTmV3U2VydmljZURhdGF7JE5hbWVQYXJ0fQogICAgICAgICAgICAmJiAhJFJldmVyc2VTZWxlY3Rpb25MaXN0eyAkTmV3U2VydmljZURhdGF7JE5hbWVQYXJ0fSB9ICkKICAgICAgICB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJDYW4ndCBpbXBvcnQgdGhpcyBlbnRpdHkuICIKICAgICAgICAgICAgICAgICAgICAuICJCYWQgZGVmaW5pdGlvbiBvZiBhdHRyaWJ1dGUgdmFsdWUgIgogICAgICAgICAgICAgICAgICAgIC4gIiAoJE5hbWVQYXJ0IDwkTmV3U2VydmljZURhdGF7JE5hbWVQYXJ0fT4gZG9lcyBub3QiCiAgICAgICAgICAgICAgICAgICAgLiAibWF0Y2ggYW55IGV4aXN0aW5nIHZhbHVlIGluIHNlbGVjdGlvbikhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICB9CgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIygxKSBzZWFyY2ggc2VydmljZS4uLgogICAgbXkgJVNlcnZpY2VEYXRhID0gKCk7CiAgICBteSAkTmV3U2VydmljZSAgPSAxOwogICAgbXkgJFNlcnZpY2VJRCAgID0gJE5ld1NlcnZpY2VEYXRheyRTZXJ2aWNlSWRlbnRpZmllcktleX0gfHwgMDsKICAgIGlmICgKICAgICAgICAhJFNlcnZpY2VJZGVudGlmaWVyS2V5CiAgICAgICAgfHwgJFNlcnZpY2VJZGVudGlmaWVyS2V5IGVxICdOYW1lJwogICAgICAgIHx8ICEkTmV3U2VydmljZURhdGF7JFNlcnZpY2VJZGVudGlmaWVyS2V5fQogICAgICAgICkKICAgIHsKICAgICAgICBpZiAoICROZXdTZXJ2aWNlRGF0YXtGdWxsTmFtZX0gKSB7CiAgICAgICAgICAgICRTZXJ2aWNlSUQgPSAkU2VsZi0+e1NlcnZpY2VPYmplY3R9LT5TZXJ2aWNlTG9va3VwKAogICAgICAgICAgICAgICAgTmFtZSA9PiAkTmV3U2VydmljZURhdGF7RnVsbE5hbWV9LAogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KICAgIGlmICgkU2VydmljZUlEKSB7CiAgICAgICAgJVNlcnZpY2VEYXRhID0gJFNlbGYtPntTZXJ2aWNlT2JqZWN0fS0+U2VydmljZUdldCgKICAgICAgICAgICAgU2VydmljZUlEID0+ICRTZXJ2aWNlSUQsCiAgICAgICAgICAgIFVzZXJJRCAgICA9PiAxLAogICAgICAgICk7CiAgICB9CiAgICBpZiAoIHNjYWxhcigga2V5cyglU2VydmljZURhdGEpICkgKSB7CiAgICAgICAgJE5ld1NlcnZpY2UgPSAwOwogICAgfQogICAgZm9yIG15ICRLZXkgKCBrZXlzKCVOZXdTZXJ2aWNlRGF0YSkgKSB7CiAgICAgICAgbmV4dCBpZiAoICEkTmV3U2VydmljZURhdGF7JEtleX0gKTsKICAgICAgICAkU2VydmljZURhdGF7JEtleX0gPSAkTmV3U2VydmljZURhdGF7JEtleX07CiAgICB9CgogICAgIygyKSBpZiBzZXJ2aWNlIERPRVMgTk9UIGV4aXN0cyA9PiBjcmVhdGUgbmV3Li4uCiAgICBteSAkUmVzdWx0ID0gMDsKICAgIGlmICggJE5ld1NlcnZpY2UgJiYgJFNlcnZpY2VEYXRhe05hbWV9ICYmICRTZXJ2aWNlRGF0YXtWYWxpZElEfSApIHsKICAgICAgICAkU2VydmljZUlEID0gJFNlbGYtPntTZXJ2aWNlT2JqZWN0fS0+U2VydmljZUFkZCgKICAgICAgICAgICAgJVNlcnZpY2VEYXRhLAogICAgICAgICAgICBVc2VySUQgPT4gJFBhcmFte1VzZXJJRH0sCiAgICAgICAgKTsKICAgICAgICBpZiAoICEkU2VydmljZUlEICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAnSW1wb3J0RGF0YVNhdmU6IGFkZGluZyBzZXJ2aWNlIDwnCiAgICAgICAgICAgICAgICAgICAgLiAkU2VydmljZURhdGF7TmFtZX0KICAgICAgICAgICAgICAgICAgICAuICc+IGZhaWxlZCAobGluZSAkUGFyYW17Q291bnRlcn0pLicsCiAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgfQoKICAgICMoMykgaWYgc2VydmljZSBET0VTIGV4aXN0cyA9PiB1cGRhdGUuLi4KICAgIGlmICggISROZXdTZXJ2aWNlICYmICRTZXJ2aWNlRGF0YXtOYW1lfSAmJiAkU2VydmljZURhdGF7VmFsaWRJRH0gKSB7CiAgICAgICAgJFJlc3VsdCA9ICRTZWxmLT57U2VydmljZU9iamVjdH0tPlNlcnZpY2VVcGRhdGUoCiAgICAgICAgICAgICVTZXJ2aWNlRGF0YSwKICAgICAgICAgICAgVXNlcklEID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgICk7CiAgICAgICAgaWYgKCAhJFJlc3VsdCApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ0ltcG9ydERhdGFTYXZlOiB1cGRhdGluZyBzZXJ2aWNlIDwnCiAgICAgICAgICAgICAgICAgICAgLiAkU2VydmljZURhdGF7TmFtZX0KICAgICAgICAgICAgICAgICAgICAuICc+IChJRCAnCiAgICAgICAgICAgICAgICAgICAgLiAkU2VydmljZURhdGF7U2VydmljZUlEfQogICAgICAgICAgICAgICAgICAgIC4gJykgZmFpbGVkIChsaW5lICRQYXJhbXtDb3VudGVyfSkuJywKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgIyg0KSBzZXQgcHJlZmVyZW5jZXMuLi4KICAgIGlmICgkU2VydmljZUlEKSB7CiAgICAgICAgZm9yIG15ICRDdXJyS2V5ICgga2V5cyglUHJlZmVyZW5jZXMpICkgewogICAgICAgICAgICBuZXh0IGlmICggISROZXdTZXJ2aWNlRGF0YXskQ3VycktleX0gKTsKICAgICAgICAgICAgJFNlbGYtPntTZXJ2aWNlT2JqZWN0fS0+U2VydmljZVByZWZlcmVuY2VzU2V0KAogICAgICAgICAgICAgICAgU2VydmljZUlEID0+ICRTZXJ2aWNlSUQsCiAgICAgICAgICAgICAgICBLZXkgICAgICAgPT4gJEN1cnJLZXksCiAgICAgICAgICAgICAgICBWYWx1ZSAgICAgPT4gJE5ld1NlcnZpY2VEYXRheyRDdXJyS2V5fSwKICAgICAgICAgICAgICAgIFVzZXJJRCAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgIwogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICByZXR1cm4gJFJlc3VsdDsKfQoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBzb2Z0d2FyZSBpcyBhIGRlcml2YXRpdmUgcGFydCBvZiB0aGUgT1RSUyBwcm9qZWN0IChodHRwOi8vb3Rycy5vcmcvKS4KClRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCnRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQpkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0yLjAudHh0LgoKPWN1dAoKPWhlYWQxIFZFUlNJT04KCiRSZXZpc2lvbjogMS4xMSAkICREYXRlOiAyMDExLTExLTI5IDEwOjI4OjU3ICQKCj1jdXQK
IyAtLQojIEtlcm5lbC9TeXN0ZW0vSW1wb3J0RXhwb3J0L09iamVjdEJhY2tlbmQvU2VydmljZTJDdXN0b21lclVzZXIucG0KIwojLSBpbXBvcnQvZXhwb3J0IGJhY2tlbmQgZm9yIFNlcnZpY2UyQ3VzdG9tZXJVc2VyLW1hcHBpbmcKIwojIENvcHlyaWdodCAoQykgMjAwNi0yMDEwIGMuYS5wLmUuIElUIEdtYkgsIGh0dHA6Ly93d3cuY2FwZS1pdC5kZQojCiMgLS0KIyAkSWQ6IFNlcnZpY2UyQ3VzdG9tZXJVc2VyLnBtLHYgMS44IDIwMTAtMDctMzAgMTc6NDc6MTIgdHRvIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTIuMC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpTeXN0ZW06OkltcG9ydEV4cG9ydDo6T2JqZWN0QmFja2VuZDo6U2VydmljZTJDdXN0b21lclVzZXI7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7CnVzZSBLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJVc2VyOwp1c2UgS2VybmVsOjpTeXN0ZW06OlNlcnZpY2U7Cgp1c2UgdmFycyBxdygkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjggJCkgWzFdOwoKPWhlYWQxIE5BTUUKCktlcm5lbDo6U3lzdGVtOjpJbXBvcnRFeHBvcnQ6Ok9iamVjdEJhY2tlbmQ6OkN1c3RvbWVyVXNlciAtIGltcG9ydC9leHBvcnQgYmFja2VuZCBmb3IgQ3VzdG9tZXJVc2VyCgo9aGVhZDEgU1lOT1BTSVMKCkFsbCBmdW5jdGlvbnMgdG8gaW1wb3J0IGFuZCBleHBvcnQgQ3VzdG9tZXJVc2VyIGVudHJpZXMKCj1vdmVyIDQKCj1jdXQKCj1pdGVtIG5ldygpCgpjcmVhdGUgYW4gb2JqZWN0CgogICAgdXNlIEtlcm5lbDo6Q29uZmlnOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpEQjsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6TG9nOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpNYWluOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpJbXBvcnRFeHBvcnQ6Ok9iamVjdEJhY2tlbmQ6OkN1c3RvbWVyVXNlcjsKCiAgICBteSAkQ29uZmlnT2JqZWN0ID0gS2VybmVsOjpDb25maWctPm5ldygpOwogICAgbXkgJExvZ09iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpMb2ctPm5ldygKICAgICAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgICk7CiAgICBteSAkTWFpbk9iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpNYWluLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICApOwogICAgbXkgJERCT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkRCLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICAgICAgTWFpbk9iamVjdCAgID0+ICRNYWluT2JqZWN0LAogICAgKTsKICAgIG15ICRCYWNrZW5kT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkltcG9ydEV4cG9ydDo6T2JqZWN0QmFja2VuZDo6Q3VzdG9tZXJVc2VyLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ICAgICAgID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgICAgICAgID0+ICRMb2dPYmplY3QsCiAgICAgICAgREJPYmplY3QgICAgICAgICAgID0+ICREQk9iamVjdCwKICAgICAgICBNYWluT2JqZWN0ICAgICAgICAgPT4gJE1haW5PYmplY3QsCiAgICAgICAgSW1wb3J0RXhwb3J0T2JqZWN0ID0+ICRJbXBvcnRFeHBvcnRPYmplY3QsCiAgICApOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjY2hlY2sgcmVxdWlyZWQgb2JqZWN0cy4uLgogICAgZm9yIG15ICRPYmplY3QgKAogICAgICAgIHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QgREJPYmplY3QgTWFpbk9iamVjdCBJbXBvcnRFeHBvcnRPYmplY3QgRW5jb2RlT2JqZWN0KQogICAgICAgICkKICAgIHsKICAgICAgICAkU2VsZi0+eyRPYmplY3R9ID0gJFBhcmFteyRPYmplY3R9IHx8IGRpZSAiR290IG5vICRPYmplY3QhIjsKICAgIH0KCiAgICBpZiAoICEkU2VsZi0+e0N1c3RvbWVyVXNlck9iamVjdH0gKSB7CiAgICAgICAgJFNlbGYtPntDdXN0b21lclVzZXJPYmplY3R9ID0KICAgICAgICAgICAgS2VybmVsOjpTeXN0ZW06OkN1c3RvbWVyVXNlci0+bmV3KCAleyRTZWxmfSApOwogICAgfQoKICAgIGlmICggISRTZWxmLT57U2VydmljZU9iamVjdH0gKSB7CiAgICAgICAgJFNlbGYtPntTZXJ2aWNlT2JqZWN0fSA9CiAgICAgICAgICAgIEtlcm5lbDo6U3lzdGVtOjpTZXJ2aWNlLT5uZXcoICV7JFNlbGZ9ICk7CiAgICB9CgogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBPYmplY3RBdHRyaWJ1dGVzR2V0KCkKCmdldCB0aGUgb2JqZWN0IGF0dHJpYnV0ZXMgb2YgYW4gb2JqZWN0IGFzIGFycmF5L2hhc2ggcmVmZXJlbmNlCgogICAgbXkgJEF0dHJpYnV0ZXMgPSAkT2JqZWN0QmFja2VuZC0+T2JqZWN0QXR0cmlidXRlc0dldCgKICAgICAgICBVc2VySUQgPT4gMSwKICAgICk7Cgo9Y3V0CgpzdWIgT2JqZWN0QXR0cmlidXRlc0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIG9iamVjdAogICAgaWYgKCAhJFBhcmFte1VzZXJJRH0gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9CiAgICAgICAgICAgIC0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICdOZWVkIFVzZXJJRCEnICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIG15ICRBdHRyaWJ1dGVzID0gWwogICAgICAgIHsKICAgICAgICAgICAgS2V5ICAgPT4gJ0xhYmVsRXhwb3J0JywKICAgICAgICAgICAgTmFtZSAgPT4gJ0V4cG9ydCB3aXRoIGxhYmVscycsCiAgICAgICAgICAgIElucHV0ID0+IHsKICAgICAgICAgICAgICAgIFR5cGUgPT4gJ1NlbGVjdGlvbicsCiAgICAgICAgICAgICAgICBEYXRhID0+IHsKICAgICAgICAgICAgICAgICAgICAnMCcgPT4gJ05vJywKICAgICAgICAgICAgICAgICAgICAnMScgPT4gJ1llcycsCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgUmVxdWlyZWQgICAgID0+IDAsCiAgICAgICAgICAgICAgICBUcmFuc2xhdGlvbiAgPT4gMSwKICAgICAgICAgICAgICAgIFBvc3NpYmxlTm9uZSA9PiAwLAogICAgICAgICAgICAgICAgVmFsdWVEZWZhdWx0ID0+IDAsCiAgICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgIF07CgogICAgcmV0dXJuICRBdHRyaWJ1dGVzOwp9Cgo9aXRlbSBNYXBwaW5nT2JqZWN0QXR0cmlidXRlc0dldCgpCgpnZXQgdGhlIG1hcHBpbmcgYXR0cmlidXRlcyBvZiBhbiBvYmplY3QgYXMgYXJyYXkvaGFzaCByZWZlcmVuY2UKCiAgICBteSAkQXR0cmlidXRlcyA9ICRPYmplY3RCYWNrZW5kLT5NYXBwaW5nT2JqZWN0QXR0cmlidXRlc0dldCgKICAgICAgICBUZW1wbGF0ZUlEID0+IDEyMywKICAgICAgICBVc2VySUQgICAgID0+IDEsCiAgICApOwoKPWN1dAoKc3ViIE1hcHBpbmdPYmplY3RBdHRyaWJ1dGVzR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkQXJndW1lbnQgKHF3KFRlbXBsYXRlSUQgVXNlcklEKSkgewogICAgICAgIGlmICggISRQYXJhbXskQXJndW1lbnR9ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCAkQXJndW1lbnQhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGdldCBvYmplY3QgZGF0YQogICAgbXkgJE9iamVjdERhdGEgPSAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPk9iamVjdERhdGFHZXQoCiAgICAgICAgVGVtcGxhdGVJRCA9PiAkUGFyYW17VGVtcGxhdGVJRH0sCiAgICAgICAgVXNlcklEICAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICk7CgogICAgbXkgJEVsZW1lbnRMaXN0ID0gWwogICAgICAgIHsKICAgICAgICAgICAgS2V5ICAgPT4gJ0N1c3RvbWVyVXNlckxvZ2luJywKICAgICAgICAgICAgVmFsdWUgPT4gJ0N1c3RvbWVyIFVzZXIgTG9naW4nLAogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICBLZXkgICA9PiAnU2VydmljZU5hbWUnLAogICAgICAgICAgICBWYWx1ZSA9PiAnU2VydmljZSBOYW1lJywKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgS2V5ICAgPT4gJ1NlcnZpY2VJRCcsCiAgICAgICAgICAgIFZhbHVlID0+ICdTZXJ2aWNlIElEJywKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgS2V5ICAgPT4gJ0Fzc2lnbm1lbnRBY3RpdmUnLAogICAgICAgICAgICBWYWx1ZSA9PiAnVmFsaWRpdHkgb2Ygc2VydmljZSBhc3NpZ25tZW50IGZvciBDVScsCiAgICAgICAgfSwKCiAgICBdOwoKICAgIG15ICRBdHRyaWJ1dGVzID0gWwogICAgICAgIHsKICAgICAgICAgICAgS2V5ICAgPT4gJ0tleScsCiAgICAgICAgICAgIE5hbWUgID0+ICdLZXknLAogICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAgICAgICAgICAgICBUeXBlICAgICAgICAgPT4gJ1NlbGVjdGlvbicsCiAgICAgICAgICAgICAgICBEYXRhICAgICAgICAgPT4gJEVsZW1lbnRMaXN0LAogICAgICAgICAgICAgICAgUmVxdWlyZWQgICAgID0+IDEsCiAgICAgICAgICAgICAgICBUcmFuc2xhdGlvbiAgPT4gMCwKICAgICAgICAgICAgICAgIFBvc3NpYmxlTm9uZSA9PiAxLAogICAgICAgICAgICB9LAogICAgICAgIH0sCgogICAgICAgICMgY3VycmVudGx5LCB0aGVyZSBhcmUgbm8gYWRkaXRpb25hbCBhdHRyaWJ1dGVzCiAgICAgICAgIyAgICAgICAgewogICAgICAgICMgICAgICAgICAgICBLZXkgICA9PiAnSWRlbnRpZmllcicsCiAgICAgICAgIyAgICAgICAgICAgIE5hbWUgID0+ICdJZGVudGlmaWVyJywKICAgICAgICAjICAgICAgICAgICAgSW5wdXQgPT4geyBUeXBlID0+ICdDaGVja2JveCcsIH0sCiAgICAgICAgIyAgICAgICAgfSwKICAgIF07CgogICAgcmV0dXJuICRBdHRyaWJ1dGVzOwp9Cgo9aXRlbSBTZWFyY2hBdHRyaWJ1dGVzR2V0KCkKCmdldCB0aGUgc2VhcmNoIG9iamVjdCBhdHRyaWJ1dGVzIG9mIGFuIG9iamVjdCBhcyBhcnJheS9oYXNoIHJlZmVyZW5jZQoKICAgIG15ICRBdHRyaWJ1dGVMaXN0ID0gJE9iamVjdEJhY2tlbmQtPlNlYXJjaEF0dHJpYnV0ZXNHZXQoCiAgICAgICAgVGVtcGxhdGVJRCA9PiAxMjMsCiAgICAgICAgVXNlcklEICAgICA9PiAxLAogICAgKTsKCj1jdXQKCnN1YiBTZWFyY2hBdHRyaWJ1dGVzR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkQXJndW1lbnQgKHF3KFRlbXBsYXRlSUQgVXNlcklEKSkgewogICAgICAgIGlmICggISRQYXJhbXskQXJndW1lbnR9ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCAkQXJndW1lbnQhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICBteSAkQXR0cmlidXRlTGlzdCA9IFsKICAgICAgICB7CiAgICAgICAgICAgIEtleSAgID0+ICdDdXN0b21lclVzZXJMb2dpbicsCiAgICAgICAgICAgIE5hbWUgID0+ICdDdXN0b21lciBVc2VyIExvZ2luJywKICAgICAgICAgICAgSW5wdXQgPT4gewogICAgICAgICAgICAgICAgVHlwZSAgICAgID0+ICdUZXh0JywKICAgICAgICAgICAgICAgIFNpemUgICAgICA9PiA4MCwKICAgICAgICAgICAgICAgIE1heExlbmd0aCA9PiAyNTUsCiAgICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgIEtleSAgID0+ICdTZXJ2aWNlTmFtZScsCiAgICAgICAgICAgIE5hbWUgID0+ICdTZXJ2aWNlIE5hbWUnLAogICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAgICAgICAgICAgICBUeXBlICAgICAgPT4gJ1RleHQnLAogICAgICAgICAgICAgICAgU2l6ZSAgICAgID0+IDgwLAogICAgICAgICAgICAgICAgTWF4TGVuZ3RoID0+IDI1NSwKICAgICAgICAgICAgfSwKICAgICAgICB9LAogICAgXTsKCiAgICByZXR1cm4gJEF0dHJpYnV0ZUxpc3Q7Cn0KCj1pdGVtIEV4cG9ydERhdGFHZXQoKQoKZ2V0IGV4cG9ydCBkYXRhIGFzIDJELWFycmF5LWhhc2ggcmVmZXJlbmNlCgogICAgbXkgJEV4cG9ydERhdGEgPSAkT2JqZWN0QmFja2VuZC0+RXhwb3J0RGF0YUdldCgKICAgICAgICBUZW1wbGF0ZUlEID0+IDEyMywKICAgICAgICBVc2VySUQgICAgID0+IDEsCiAgICApOwoKPWN1dAoKc3ViIEV4cG9ydERhdGFHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIG15ICRBcmd1bWVudCAocXcoVGVtcGxhdGVJRCBVc2VySUQpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRBcmd1bWVudH0gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICRBcmd1bWVudCEiLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgZ2V0IG9iamVjdCBkYXRhCiAgICBteSAkT2JqZWN0RGF0YSA9ICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fS0+T2JqZWN0RGF0YUdldCgKICAgICAgICBUZW1wbGF0ZUlEID0+ICRQYXJhbXtUZW1wbGF0ZUlEfSwKICAgICAgICBVc2VySUQgICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgKTsKCiAgICAjIGNoZWNrIG9iamVjdCBkYXRhCiAgICBpZiAoICEkT2JqZWN0RGF0YSB8fCByZWYgJE9iamVjdERhdGEgbmUgJ0hBU0gnICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAiTm8gb2JqZWN0IGRhdGEgZm91bmQgZm9yIHRoZSB0ZW1wbGF0ZSBpZCAkUGFyYW17VGVtcGxhdGVJRH0iLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgZ2V0IHRoZSBtYXBwaW5nIGxpc3QKICAgIG15ICRNYXBwaW5nTGlzdCA9ICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fS0+TWFwcGluZ0xpc3QoCiAgICAgICAgVGVtcGxhdGVJRCA9PiAkUGFyYW17VGVtcGxhdGVJRH0sCiAgICAgICAgVXNlcklEICAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICk7CgogICAgIyBjaGVjayB0aGUgbWFwcGluZyBsaXN0CiAgICBpZiAoICEkTWFwcGluZ0xpc3QgfHwgcmVmICRNYXBwaW5nTGlzdCBuZSAnQVJSQVknIHx8ICFAeyRNYXBwaW5nTGlzdH0gKSB7CgogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAiTm8gdmFsaWQgbWFwcGluZyBsaXN0IGZvdW5kIGZvciB0aGUgdGVtcGxhdGUgaWQgJFBhcmFte1RlbXBsYXRlSUR9IiwKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGNyZWF0ZSB0aGUgbWFwcGluZyBvYmplY3QgbGlzdAogICAgbXkgQE1hcHBpbmdPYmplY3RMaXN0OwogICAgZm9yIG15ICRNYXBwaW5nSUQgKCBAeyRNYXBwaW5nTGlzdH0gKSB7CgogICAgICAgICMgZ2V0IG1hcHBpbmcgb2JqZWN0IGRhdGEKICAgICAgICBteSAkTWFwcGluZ09iamVjdERhdGEgPQogICAgICAgICAgICAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPk1hcHBpbmdPYmplY3REYXRhR2V0KAogICAgICAgICAgICBNYXBwaW5nSUQgPT4gJE1hcHBpbmdJRCwKICAgICAgICAgICAgVXNlcklEICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgICAgICApOwoKICAgICAgICAjIGNoZWNrIG1hcHBpbmcgb2JqZWN0IGRhdGEKICAgICAgICBpZiAoICEkTWFwcGluZ09iamVjdERhdGEgfHwgcmVmICRNYXBwaW5nT2JqZWN0RGF0YSBuZSAnSEFTSCcgKSB7CgogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTm8gdmFsaWQgbWFwcGluZyBsaXN0IGZvdW5kIGZvciB0aGUgdGVtcGxhdGUgaWQgJFBhcmFte1RlbXBsYXRlSUR9IiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgcHVzaCggQE1hcHBpbmdPYmplY3RMaXN0LCAkTWFwcGluZ09iamVjdERhdGEgKTsKICAgIH0KCiAgICAjIGdldCBzZWFyY2ggZGF0YQogICAgbXkgJFNlYXJjaERhdGEgPSAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPlNlYXJjaERhdGFHZXQoCiAgICAgICAgVGVtcGxhdGVJRCA9PiAkUGFyYW17VGVtcGxhdGVJRH0sCiAgICAgICAgVXNlcklEICAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICk7CgogICAgaWYgKCAkU2VhcmNoRGF0YSAmJiByZWYoJFNlYXJjaERhdGEpIG5lICdIQVNIJyApIHsKICAgICAgICAkU2VhcmNoRGF0YSA9IDA7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgPT4KICAgICAgICAgICAgICAgICJTZXJ2aWNlMkN1c3RvbWVyVXNlcjogc2VhcmNoIGRhdGEgaXMgbm90IGEgaGFzaCByZWYgLSBpZ25vcmluZyBzZWFyY2ggbGltaXRhdGlvbi4iLAogICAgICAgICk7CiAgICB9CgogICAgaWYgKCAkU2VhcmNoRGF0YSAmJiAkU2VhcmNoRGF0YS0+e1NlcnZpY2VOYW1lfSAmJiAkU2VhcmNoRGF0YS0+e1NlcnZpY2VOYW1lfSA9fiAvXCovICkgewogICAgICAgICRTZWFyY2hEYXRhLT57U2VydmljZU5hbWV9ID1+IHMvXCovLiovZzsKICAgIH0KICAgIGlmICgKICAgICAgICAkU2VhcmNoRGF0YQogICAgICAgICYmICRTZWFyY2hEYXRhLT57Q3VzdG9tZXJVc2VyTG9naW59CiAgICAgICAgJiYgJFNlYXJjaERhdGEtPntDdXN0b21lclVzZXJMb2dpbn0gPX4gL1wqLwogICAgICAgICkKICAgIHsKICAgICAgICAkU2VhcmNoRGF0YS0+e0N1c3RvbWVyVXNlckxvZ2lufSA9fiBzL1wqLy4qL2c7CiAgICB9CgogICAgI3NlYXJjaCBhbGwgc2VydmljZXMuLi4KICAgIG15ICVTZXJ2aWNlRGF0YSA9ICRTZWxmLT57U2VydmljZU9iamVjdH0tPlNlcnZpY2VMaXN0KAogICAgICAgIFZhbGlkICA9PiAwLAogICAgICAgIFVzZXJJRCA9PiAxLAogICAgKTsKCiAgICAjIGV4cG9ydCBkYXRhLi4uCiAgICBteSBARXhwb3J0RGF0YTsKCiAgICAjIGV4cG9ydCBoZWFkbGluZS9sYWJlbHMgLi4uCiAgICBpZiAoICRPYmplY3REYXRhLT57TGFiZWxFeHBvcnR9ICkgewogICAgICAgIG15IEBDdXJyUm93ID0gcXd7fTsKICAgICAgICBmb3IgbXkgJE1hcHBpbmdPYmplY3QgKEBNYXBwaW5nT2JqZWN0TGlzdCkgewogICAgICAgICAgICBwdXNoKCBAQ3VyclJvdywgJE1hcHBpbmdPYmplY3QtPntLZXl9IHx8ICctJyApOwogICAgICAgIH0KICAgICAgICBwdXNoIEBFeHBvcnREYXRhLCBcQEN1cnJSb3c7CiAgICB9CgogICAgZm9yIG15ICRTZXJ2aWNlSUQgKCBrZXlzKCVTZXJ2aWNlRGF0YSkgKSB7CgogICAgICAgICNjaGVjayBmb3IgU2VydmljZU5hbWUgZXhwb3J0IGZpbHRlci4uLgogICAgICAgIGlmICggJFNlYXJjaERhdGEgJiYgJFNlYXJjaERhdGEtPntTZXJ2aWNlTmFtZX0gKSB7CiAgICAgICAgICAgIGlmICggJFNlYXJjaERhdGEtPntTZXJ2aWNlTmFtZX0gPX4gL1wqLyApIHsKICAgICAgICAgICAgICAgIG5leHQgaWYgKCAkU2VydmljZURhdGF7JFNlcnZpY2VJRH0gIX4gLyRTZWFyY2hEYXRhLT57U2VydmljZU5hbWV9LyApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgbmV4dCBpZiAoICRTZXJ2aWNlRGF0YXskU2VydmljZUlEfSBuZSAkU2VhcmNoRGF0YS0+e1NlcnZpY2VOYW1lfSApOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAjc2VhcmNoIGFsbCBjdXN0b21lcnMgc2V0IGZvciBjdXJyZW50IHNlcnZpY2UuLi4KICAgICAgICBteSAlQ3VzdG9tZXJTZXJ2aWNlSGFzaCA9ICRTZWxmLT57U2VydmljZU9iamVjdH0tPkN1c3RvbWVyVXNlclNlcnZpY2VNZW1iZXJMaXN0KAogICAgICAgICAgICBTZXJ2aWNlSUQgICAgICAgPT4gJFNlcnZpY2VJRCwKICAgICAgICAgICAgUmVzdWx0ICAgICAgICAgID0+ICdIQVNIJywKICAgICAgICAgICAgRGVmYXVsdFNlcnZpY2VzID0+IDAsCiAgICAgICAgKTsKCiAgICAgICAgZm9yIG15ICRDdXJyZW50Q1VMICgga2V5cyglQ3VzdG9tZXJTZXJ2aWNlSGFzaCkgKSB7CiAgICAgICAgICAgIG15IEBDdXJyUm93ID0gcXd7fTsKCiAgICAgICAgICAgICNjaGVjayBmb3IgQ3VzdG9tZXJVc2VyTG9naW4gZXhwb3J0IGZpbHRlci4uLgogICAgICAgICAgICBpZiAoICRTZWFyY2hEYXRhICYmICRTZWFyY2hEYXRhLT57Q3VzdG9tZXJVc2VyTG9naW59ICkgewogICAgICAgICAgICAgICAgaWYgKCAkU2VhcmNoRGF0YS0+e0N1c3RvbWVyVXNlckxvZ2lufSA9fiAvXCovICkgewogICAgICAgICAgICAgICAgICAgIG5leHQgaWYgKCAkQ3VycmVudENVTCAhfiAvJFNlYXJjaERhdGEtPntDdXN0b21lclVzZXJMb2dpbn0vICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBuZXh0IGlmICggJEN1cnJlbnRDVUwgbmUgJFNlYXJjaERhdGEtPntTZXJ2aWNlTmFtZX0gKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgZm9yIG15ICRNYXBwaW5nT2JqZWN0IChATWFwcGluZ09iamVjdExpc3QpIHsKICAgICAgICAgICAgICAgIG15ICRLZXkgPSAkTWFwcGluZ09iamVjdC0+e0tleX07CgogICAgICAgICAgICAgICAgaWYgKCAkTWFwcGluZ09iamVjdC0+e0tleX0gJiYgJE1hcHBpbmdPYmplY3QtPntLZXl9IGVxICdDdXN0b21lclVzZXJMb2dpbicgKSB7CiAgICAgICAgICAgICAgICAgICAgcHVzaCggQEN1cnJSb3csICRDdXJyZW50Q1VMICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNpZiAoICRNYXBwaW5nT2JqZWN0LT57S2V5fSAmJiAkTWFwcGluZ09iamVjdC0+e0tleX0gZXEgJ1NlcnZpY2VOYW1lJyApIHsKICAgICAgICAgICAgICAgICAgICBwdXNoKCBAQ3VyclJvdywgJFNlcnZpY2VEYXRheyRTZXJ2aWNlSUR9IHx8ICcnICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNpZiAoICRNYXBwaW5nT2JqZWN0LT57S2V5fSAmJiAkTWFwcGluZ09iamVjdC0+e0tleX0gZXEgJ1NlcnZpY2VJRCcgKSB7CiAgICAgICAgICAgICAgICAgICAgcHVzaCggQEN1cnJSb3csICRTZXJ2aWNlSUQgfHwgJycgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2lmICggJE1hcHBpbmdPYmplY3QtPntLZXl9ICYmICRNYXBwaW5nT2JqZWN0LT57S2V5fSBlcSAnQXNzaWdubWVudEFjdGl2ZScgKSB7CiAgICAgICAgICAgICAgICAgICAgcHVzaCggQEN1cnJSb3csICd2YWxpZCcgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIHB1c2goIEBDdXJyUm93LCAnLScgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHVzaCBARXhwb3J0RGF0YSwgXEBDdXJyUm93OwoKICAgICAgICB9CgogICAgfQoKICAgIHJldHVybiBcQEV4cG9ydERhdGE7Cn0KCj1pdGVtIEltcG9ydERhdGFTYXZlKCkKCmltcG9ydCBvbmUgcm93IG9mIHRoZSBpbXBvcnQgZGF0YQoKICAgIG15ICRDb25maWdJdGVtSUQgPSAkT2JqZWN0QmFja2VuZC0+SW1wb3J0RGF0YVNhdmUoCiAgICAgICAgVGVtcGxhdGVJRCAgICA9PiAxMjMsCiAgICAgICAgSW1wb3J0RGF0YVJvdyA9PiAkQXJyYXlSZWYsCiAgICAgICAgVXNlcklEICAgICAgICA9PiAxLAogICAgKTsKCj1jdXQKCnN1YiBJbXBvcnREYXRhU2F2ZSB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgbXkgJEFyZ3VtZW50IChxdyhUZW1wbGF0ZUlEIEltcG9ydERhdGFSb3cgVXNlcklEKSkgewogICAgICAgIGlmICggISRQYXJhbXskQXJndW1lbnR9ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCAkQXJndW1lbnQhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGNoZWNrIGltcG9ydCBkYXRhIHJvdwogICAgaWYgKCByZWYgJFBhcmFte0ltcG9ydERhdGFSb3d9IG5lICdBUlJBWScgKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdJbXBvcnREYXRhUm93IG11c3QgYmUgYW4gYXJyYXkgcmVmZXJlbmNlJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGdldCBvYmplY3QgZGF0YQogICAgbXkgJE9iamVjdERhdGEgPSAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPk9iamVjdERhdGFHZXQoCiAgICAgICAgVGVtcGxhdGVJRCA9PiAkUGFyYW17VGVtcGxhdGVJRH0sCiAgICAgICAgVXNlcklEICAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICk7CgogICAgIyBjaGVjayBvYmplY3QgZGF0YQogICAgaWYgKCAhJE9iamVjdERhdGEgfHwgcmVmICRPYmplY3REYXRhIG5lICdIQVNIJyApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5vIG9iamVjdCBkYXRhIGZvdW5kIGZvciB0aGUgdGVtcGxhdGUgaWQgJFBhcmFte1RlbXBsYXRlSUR9IiwKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGdldCB0aGUgbWFwcGluZyBsaXN0CiAgICBteSAkTWFwcGluZ0xpc3QgPSAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPk1hcHBpbmdMaXN0KAogICAgICAgIFRlbXBsYXRlSUQgPT4gJFBhcmFte1RlbXBsYXRlSUR9LAogICAgICAgIFVzZXJJRCAgICAgPT4gJFBhcmFte1VzZXJJRH0sCiAgICApOwoKICAgICMgY2hlY2sgdGhlIG1hcHBpbmcgbGlzdAogICAgaWYgKCAhJE1hcHBpbmdMaXN0IHx8IHJlZiAkTWFwcGluZ0xpc3QgbmUgJ0FSUkFZJyB8fCAhQHskTWFwcGluZ0xpc3R9ICkgewoKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5vIHZhbGlkIG1hcHBpbmcgbGlzdCBmb3VuZCBmb3IgdGhlIHRlbXBsYXRlIGlkICRQYXJhbXtUZW1wbGF0ZUlEfSIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBjcmVhdGUgdGhlIG1hcHBpbmcgb2JqZWN0IGxpc3QKICAgIG15IEBNYXBwaW5nT2JqZWN0TGlzdDsKICAgIG15ICVJZGVudGlmaWVyOwogICAgbXkgJENvdW50ZXIgICAgICAgICA9IDA7CiAgICBteSAlSW1wb3J0RGF0YSAgICAgID0gcXd7fTsKICAgIG15ICRDdXN0b21lclVzZXJLZXkgPSAiIjsKCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICNCVUlMRCBNQVBQSU5HIFRBQkxFLi4uCiAgICBmb3IgbXkgJE1hcHBpbmdJRCAoIEB7JE1hcHBpbmdMaXN0fSApIHsKCiAgICAgICAgIyBnZXQgbWFwcGluZyBvYmplY3QgZGF0YQogICAgICAgIG15ICRNYXBwaW5nT2JqZWN0RGF0YSA9CiAgICAgICAgICAgICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fS0+TWFwcGluZ09iamVjdERhdGFHZXQoCiAgICAgICAgICAgIE1hcHBpbmdJRCA9PiAkTWFwcGluZ0lELAogICAgICAgICAgICBVc2VySUQgICAgPT4gJFBhcmFte1VzZXJJRH0sCiAgICAgICAgICAgICk7CgogICAgICAgICMgY2hlY2sgbWFwcGluZyBvYmplY3QgZGF0YQogICAgICAgIGlmICggISRNYXBwaW5nT2JqZWN0RGF0YSB8fCByZWYgJE1hcHBpbmdPYmplY3REYXRhIG5lICdIQVNIJyApIHsKCiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJObyB2YWxpZCBtYXBwaW5nIGxpc3QgZm91bmQgZm9yIHRlbXBsYXRlIGlkICRQYXJhbXtUZW1wbGF0ZUlEfSIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHB1c2goIEBNYXBwaW5nT2JqZWN0TGlzdCwgJE1hcHBpbmdPYmplY3REYXRhICk7CgogICAgICAgICRJbXBvcnREYXRheyAkTWFwcGluZ09iamVjdERhdGEtPntLZXl9IH0gPQogICAgICAgICAgICAkUGFyYW17SW1wb3J0RGF0YVJvd30tPlskQ291bnRlcl07CgogICAgICAgICRDb3VudGVyKys7CgogICAgfQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgI0RPIFRIRSBJTVBPUlQuLi4KCiAgICAjKDEpIHNlYXJjaCBzZXJ2aWNlLi4uCiAgICBpZiAoICRJbXBvcnREYXRhe1NlcnZpY2VOYW1lfSApIHsKICAgICAgICBteSAkQ3VycmVudFNJRCA9ICRTZWxmLT57U2VydmljZU9iamVjdH0tPlNlcnZpY2VMb29rdXAoCiAgICAgICAgICAgIE5hbWUgPT4gJEltcG9ydERhdGF7U2VydmljZU5hbWV9LAogICAgICAgICkgfHwgMDsKCiAgICAgICAgaWYgKCAhJEltcG9ydERhdGF7U2VydmljZUlEfSApIHsKICAgICAgICAgICAgJEltcG9ydERhdGF7U2VydmljZUlEfSA9ICRDdXJyZW50U0lEOwogICAgICAgIH0KICAgICAgICBpZiAoICEkQ3VycmVudFNJRCB8fCAkSW1wb3J0RGF0YXtTZXJ2aWNlSUR9ICE9ICRDdXJyZW50U0lEICkgewoKICAgICAgICAgICAgI3NlcnZpY2UgbmFtZSBkb2VzIG5vdCBleGlzdCBvciBkb2VzIG5vdCBmaXQgdG8gU2VydmljZUlEIC0gZHJvcCBsaW5lLi4uCiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJTZXJ2aWNlMkN1c3RvbWVyVXNlcjogc2VydmljZSA8IgogICAgICAgICAgICAgICAgICAgIC4gJEltcG9ydERhdGF7U2VydmljZU5hbWV9CiAgICAgICAgICAgICAgICAgICAgLiAiPiBkb2VzIG5vdCBleGlzdCBvciBkb2VzIG5vdCBtYXRjaCBnaXZlbiBTZXJ2aWNlSUQgPCIKICAgICAgICAgICAgICAgICAgICAuICggJEltcG9ydERhdGF7U2VydmljZUlEfSB8fCAnJyApCiAgICAgICAgICAgICAgICAgICAgLiAiPi4iLAogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KCiAgICAjKDIpIHNlYXJjaCBjdXN0b21lciB1c2VyLi4uCiAgICBpZiAoICRJbXBvcnREYXRhe0N1c3RvbWVyVXNlckxvZ2lufSAmJiAkSW1wb3J0RGF0YXtDdXN0b21lclVzZXJMb2dpbn0gIX4gL0RFRkFVTFQvICkgewogICAgICAgIG15ICVDdXN0b21lclVzZXJEYXRhID0gJFNlbGYtPntDdXN0b21lclVzZXJPYmplY3R9LT5DdXN0b21lclVzZXJEYXRhR2V0KAogICAgICAgICAgICBVc2VyID0+ICRJbXBvcnREYXRhe0N1c3RvbWVyVXNlckxvZ2lufQogICAgICAgICk7CiAgICAgICAgaWYgKCAhJUN1c3RvbWVyVXNlckRhdGEgKSB7CgogICAgICAgICAgICAjY3VzdG9tZXIgdXNlciBsb2dpbiBkb2VzIG5vdCBleGlzdCAtIGRyb3AgbGluZS4uLgogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiU2VydmljZTJDdXN0b21lclVzZXI6IGN1c3RvbWVyIGxvZ2luIDwiCiAgICAgICAgICAgICAgICAgICAgLiAiJEltcG9ydERhdGF7Q3VzdG9tZXJVc2VyTG9naW59PiBkb2VzIG5vdCBleGlzdC4iLAogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KCiAgICAjKDMpIG5vcm1hbGl6ZSBBc3NpZ25tZW50QWN0aXZlIHZhbHVlLi4uCiAgICBpZiAoICRJbXBvcnREYXRhe0Fzc2lnbm1lbnRBY3RpdmV9ICYmICRJbXBvcnREYXRhe0Fzc2lnbm1lbnRBY3RpdmV9ID1+IC9pbnZhbGlkLyApIHsKICAgICAgICAkSW1wb3J0RGF0YXtBc3NpZ25tZW50QWN0aXZlfSA9IDA7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICAkSW1wb3J0RGF0YXtBc3NpZ25tZW50QWN0aXZlfSA9IDE7CiAgICB9CgogICAgIyg0KSBkaXMvZW5hYmxlIGN1c3RvbWVyIHVzZXIgLSBzZXJ2aWNlIG1hcHBpbmcuLi4KICAgIGlmICggJEltcG9ydERhdGF7Q3VzdG9tZXJVc2VyTG9naW59ICF+IC9ERUZBVUxULyApIHsKICAgICAgICAkU2VsZi0+e1NlcnZpY2VPYmplY3R9LT5DdXN0b21lclVzZXJTZXJ2aWNlTWVtYmVyQWRkKAogICAgICAgICAgICBDdXN0b21lclVzZXJMb2dpbiA9PiAkSW1wb3J0RGF0YXtDdXN0b21lclVzZXJMb2dpbn0sCiAgICAgICAgICAgIFNlcnZpY2VJRCAgICAgICAgID0+ICRJbXBvcnREYXRhe1NlcnZpY2VJRH0sCiAgICAgICAgICAgIEFjdGl2ZSAgICAgICAgICAgID0+ICRJbXBvcnREYXRhe0Fzc2lnbm1lbnRBY3RpdmV9IHx8IDAsCiAgICAgICAgICAgIFVzZXJJRCAgICAgICAgICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgICk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICAkU2VsZi0+e1NlcnZpY2VPYmplY3R9LT5DdXN0b21lclVzZXJTZXJ2aWNlTWVtYmVyQWRkKAogICAgICAgICAgICBDdXN0b21lclVzZXJMb2dpbiA9PiAnPERFRkFVTFQ+JywKICAgICAgICAgICAgU2VydmljZUlEICAgICAgICAgPT4gJEltcG9ydERhdGF7U2VydmljZUlEfSwKICAgICAgICAgICAgQWN0aXZlICAgICAgICAgICAgPT4gJEltcG9ydERhdGF7QXNzaWdubWVudEFjdGl2ZX0gfHwgMCwKICAgICAgICAgICAgVXNlcklEICAgICAgICAgICAgPT4gJFBhcmFte1VzZXJJRH0sCiAgICAgICAgKTsKICAgIH0KCiAgICAjCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiAgICByZXR1cm4gMTsKfQoKMTsKCj1iYWNrCgo9aGVhZDEgVEVSTVMgQU5EIENPTkRJVElPTlMKClRoaXMgc29mdHdhcmUgaXMgYSBkZXJpdmF0aXZlIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoaHR0cDovL290cnMub3JnLykuCgpUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQp0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChHUEwpLiBJZiB5b3UKZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtMi4wLnR4dC4KCj1jdXQKCj1oZWFkMSBWRVJTSU9OCgokUmV2aXNpb246IDEuOCAkICREYXRlOiAyMDEwLTA3LTMwIDE3OjQ3OjEyICQKCj1jdXQKCg==
IyAtLQojIEtlcm5lbC9TeXN0ZW0vSW1wb3J0RXhwb3J0L09iamVjdEJhY2tlbmQvU0xBLnBtCiMKIy0gaW1wb3J0L2V4cG9ydCBiYWNrZW5kIGZvciBTTEEgZGVmaW5pdGlvbnMKIwojIENvcHlyaWdodCAoQykgMjAwNi0yMDExIGMuYS5wLmUuIElUIEdtYkgsIGh0dHA6Ly93d3cuY2FwZS1pdC5kZQojCiMgLS0KIyAkSWQ6IFNMQS5wbSx2IDEuMTAgMjAxMS0xMS0yOSAxMDoyODo1NyB0dG8gRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtMi4wLnR4dC4KIyAtLQoKcGFja2FnZSBLZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kOjpTTEE7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7CnVzZSBLZXJuZWw6OlN5c3RlbTo6U2VydmljZTsKdXNlIEtlcm5lbDo6U3lzdGVtOjpTTEE7CnVzZSBLZXJuZWw6OlN5c3RlbTo6VmFsaWQ7Cgp1c2UgdmFycyBxdygkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjEwICQpIFsxXTsKCj1oZWFkMSBOQU1FCgpLZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kOjpDdXN0b21lclVzZXIgLSBpbXBvcnQvZXhwb3J0IGJhY2tlbmQgZm9yIEN1c3RvbWVyVXNlcgoKPWhlYWQxIFNZTk9QU0lTCgpBbGwgZnVuY3Rpb25zIHRvIGltcG9ydCBhbmQgZXhwb3J0IEN1c3RvbWVyVXNlciBlbnRyaWVzCgo9b3ZlciA0Cgo9Y3V0Cgo9aXRlbSBuZXcoKQoKY3JlYXRlIGFuIG9iamVjdAoKICAgIHVzZSBLZXJuZWw6OkNvbmZpZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6REI7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkxvZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6TWFpbjsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kOjpDdXN0b21lclVzZXI7CgogICAgbXkgJENvbmZpZ09iamVjdCA9IEtlcm5lbDo6Q29uZmlnLT5uZXcoKTsKICAgIG15ICRMb2dPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6TG9nLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICApOwogICAgbXkgJE1haW5PYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6TWFpbi0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCAgICA9PiAkTG9nT2JqZWN0LAogICAgKTsKICAgIG15ICREQk9iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpEQi0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCAgICA9PiAkTG9nT2JqZWN0LAogICAgICAgIE1haW5PYmplY3QgICA9PiAkTWFpbk9iamVjdCwKICAgICk7CiAgICBteSAkQmFja2VuZE9iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpJbXBvcnRFeHBvcnQ6Ok9iamVjdEJhY2tlbmQ6OkN1c3RvbWVyVXNlci0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCAgICAgICA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCAgICAgICAgICA9PiAkTG9nT2JqZWN0LAogICAgICAgIERCT2JqZWN0ICAgICAgICAgICA9PiAkREJPYmplY3QsCiAgICAgICAgTWFpbk9iamVjdCAgICAgICAgID0+ICRNYWluT2JqZWN0LAogICAgICAgIEltcG9ydEV4cG9ydE9iamVjdCA9PiAkSW1wb3J0RXhwb3J0T2JqZWN0LAogICAgKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgI2NoZWNrIHJlcXVpcmVkIG9iamVjdHMuLi4KICAgIGZvciBteSAkT2JqZWN0ICgKICAgICAgICBxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0IERCT2JqZWN0IE1haW5PYmplY3QgSW1wb3J0RXhwb3J0T2JqZWN0IEVuY29kZU9iamVjdCkKICAgICAgICApCiAgICB7CiAgICAgICAgJFNlbGYtPnskT2JqZWN0fSA9ICRQYXJhbXskT2JqZWN0fSB8fCBkaWUgIkdvdCBubyAkT2JqZWN0ISI7CiAgICB9CgogICAgaWYgKCAhJFNlbGYtPntWYWxpZE9iamVjdH0gKSB7CiAgICAgICAgJFNlbGYtPntWYWxpZE9iamVjdH0gPSBLZXJuZWw6OlN5c3RlbTo6VmFsaWQtPm5ldyggJXskU2VsZn0gKTsKICAgIH0KCiAgICBpZiAoICEkU2VsZi0+e1NlcnZpY2VPYmplY3R9ICkgewogICAgICAgICRTZWxmLT57U2VydmljZU9iamVjdH0gPQogICAgICAgICAgICBLZXJuZWw6OlN5c3RlbTo6U2VydmljZS0+bmV3KCAleyRTZWxmfSApOwogICAgfQoKICAgIGlmICggISRTZWxmLT57U0xBT2JqZWN0fSApIHsKICAgICAgICAkU2VsZi0+e1NMQU9iamVjdH0gPQogICAgICAgICAgICBLZXJuZWw6OlN5c3RlbTo6U0xBLT5uZXcoICV7JFNlbGZ9ICk7CiAgICB9CgogICAgbXkgJENhbGVuZGFySW5kZXggICAgPSAxOwogICAgbXkgJUNhbGVuZGFyTmFtZUxpc3QgPSBxd3t9OwogICAgd2hpbGUgKCAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCggIlRpbWVab25lOjpDYWxlbmRhciIgLiAkQ2FsZW5kYXJJbmRleCAuICJOYW1lIiApICkgewogICAgICAgICRDYWxlbmRhck5hbWVMaXN0eyRDYWxlbmRhckluZGV4fSA9CiAgICAgICAgICAgICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCAiVGltZVpvbmU6OkNhbGVuZGFyIiAuICRDYWxlbmRhckluZGV4IC4gIk5hbWUiICk7CiAgICAgICAgJENhbGVuZGFySW5kZXgrKzsKICAgIH0KICAgIG15ICVUbXBIYXNoID0gcmV2ZXJzZSglQ2FsZW5kYXJOYW1lTGlzdCk7CiAgICAkU2VsZi0+e0NhbGVuZGFyTmFtZUxpc3R9ICAgICAgICA9IFwlQ2FsZW5kYXJOYW1lTGlzdDsKICAgICRTZWxmLT57UmV2ZXJzZUNhbGVuZGFyTmFtZUxpc3R9ID0gXCVUbXBIYXNoOwoKICAgIGlmICggJFNlbGYtPntNYWluT2JqZWN0fS0+UmVxdWlyZSgnS2VybmVsOjpTeXN0ZW06OkdlbmVyYWxDYXRhbG9nJykgKSB7CiAgICAgICAgJFNlbGYtPntHZW5lcmFsQ2F0YWxvZ09iamVjdH0gPSBLZXJuZWw6OlN5c3RlbTo6R2VuZXJhbENhdGFsb2ctPm5ldyggJXskU2VsZn0gKTsKICAgICAgICBpZiAoICRTZWxmLT57R2VuZXJhbENhdGFsb2dPYmplY3R9ICkgewoKICAgICAgICAgICAgIyBnZXQgU0xBIHR5cGUgbGlzdAogICAgICAgICAgICAkU2VsZi0+e1NMQVR5cGVMaXN0fSA9ICRTZWxmLT57R2VuZXJhbENhdGFsb2dPYmplY3R9LT5JdGVtTGlzdCgKICAgICAgICAgICAgICAgIENsYXNzID0+ICdJVFNNOjpTTEE6OlR5cGUnLAogICAgICAgICAgICApOwogICAgICAgICAgICBteSAlVG1wSGFzaCA9IHJldmVyc2UoICV7ICRTZWxmLT57U0xBVHlwZUxpc3R9IH0gKTsKICAgICAgICAgICAgJFNlbGYtPntSZXZlcnNlU0xBVHlwZUxpc3R9ID0gXCVUbXBIYXNoOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gJFNlbGY7Cn0KCj1pdGVtIE9iamVjdEF0dHJpYnV0ZXNHZXQoKQoKZ2V0IHRoZSBvYmplY3QgYXR0cmlidXRlcyBvZiBhbiBvYmplY3QgYXMgYXJyYXkvaGFzaCByZWZlcmVuY2UKCiAgICBteSAkQXR0cmlidXRlcyA9ICRPYmplY3RCYWNrZW5kLT5PYmplY3RBdHRyaWJ1dGVzR2V0KAogICAgICAgIFVzZXJJRCA9PiAxLAogICAgKTsKCj1jdXQKCnN1YiBPYmplY3RBdHRyaWJ1dGVzR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgb2JqZWN0CiAgICBpZiAoICEkUGFyYW17VXNlcklEfSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0KICAgICAgICAgICAgLT5Mb2coIFByaW9yaXR5ID0+ICdlcnJvcicsIE1lc3NhZ2UgPT4gJ05lZWQgVXNlcklEIScgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBteSAlVmFsaWRsaXN0ID0gJFNlbGYtPntWYWxpZE9iamVjdH0tPlZhbGlkTGlzdCgpOwoKICAgIG15ICRBdHRyaWJ1dGVzID0gWwogICAgICAgIHsKICAgICAgICAgICAgS2V5ICAgPT4gJ0RlZmF1bHRWYWxpZCcsCiAgICAgICAgICAgIE5hbWUgID0+ICdEZWZhdWx0IFZhbGlkaXR5JywKICAgICAgICAgICAgSW5wdXQgPT4gewogICAgICAgICAgICAgICAgVHlwZSAgICAgICAgID0+ICdTZWxlY3Rpb24nLAogICAgICAgICAgICAgICAgRGF0YSAgICAgICAgID0+IFwlVmFsaWRsaXN0LAogICAgICAgICAgICAgICAgUmVxdWlyZWQgICAgID0+IDEsCiAgICAgICAgICAgICAgICBUcmFuc2xhdGlvbiAgPT4gMSwKICAgICAgICAgICAgICAgIFBvc3NpYmxlTm9uZSA9PiAwLAogICAgICAgICAgICAgICAgVmFsdWVEZWZhdWx0ID0+IDEsCiAgICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgIEtleSAgID0+ICdOdW1iZXJPZkFzc2lnbmFibGVTZXJ2aWNlcycsCiAgICAgICAgICAgIE5hbWUgID0+ICdNYXguIG51bWJlciBvZiBhc3NpZ25lZCBzZXJ2aWNlcyBjb2x1bW5zJywKICAgICAgICAgICAgSW5wdXQgPT4gewogICAgICAgICAgICAgICAgVHlwZSAgICAgICAgID0+ICdUZXh0JywKICAgICAgICAgICAgICAgIFJlcXVpcmVkICAgICA9PiAxLAogICAgICAgICAgICAgICAgU2l6ZSAgICAgICAgID0+IDMsCiAgICAgICAgICAgICAgICBNYXhMZW5ndGggICAgPT4gMywKICAgICAgICAgICAgICAgIFZhbHVlRGVmYXVsdCA9PiAnNTAnLAogICAgICAgICAgICB9LAogICAgICAgIH0sCgogICAgXTsKCiAgICAjdXNlIHRoZSBhdmFpbGFiaWxpdHkgb2YgU0xBVHlwZUxpc3QgdG8gZGlzcGxheSBJVFNNLXJlbGV2YW50IGNvbmZpZy4uLgogICAgaWYgKCAkU2VsZi0+e1NMQVR5cGVMaXN0fSApIHsKICAgICAgICBteSAkU0xBVHlwZURlZmF1bHQgPSB7CiAgICAgICAgICAgIEtleSAgID0+ICdEZWZhdWx0U0xBVHlwZUlEJywKICAgICAgICAgICAgTmFtZSAgPT4gJ0RlZmF1bHQgU0xBIFR5cGUnLAogICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAgICAgICAgICAgICBUeXBlICAgICAgICAgPT4gJ1NlbGVjdGlvbicsCiAgICAgICAgICAgICAgICBEYXRhICAgICAgICAgPT4gJFNlbGYtPntTTEFUeXBlTGlzdH0sCiAgICAgICAgICAgICAgICBSZXF1aXJlZCAgICAgPT4gMSwKICAgICAgICAgICAgICAgIFRyYW5zbGF0aW9uICA9PiAxLAogICAgICAgICAgICAgICAgUG9zc2libGVOb25lID0+IDAsCiAgICAgICAgICAgIH0sCiAgICAgICAgfTsKICAgICAgICBwdXNoKCBAeyRBdHRyaWJ1dGVzfSwgJFNMQVR5cGVEZWZhdWx0ICk7CgogICAgICAgIG15ICRNaW5UaW1lQmV0d2VlbkluY2lkZW50c0RlZmF1bHQgPSB7CiAgICAgICAgICAgIEtleSAgID0+ICdEZWZhdWx0TWluVGltZUJldHdlZW5JbmNpZGVudHMnLAogICAgICAgICAgICBOYW1lICA9PiAnRGVmYXVsdCBNaW5pbXVtIFRpbWUgQmV0d2VlbiBJbmNpZGVudHMnLAogICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAgICAgICAgICAgICBUeXBlICAgICAgPT4gJ1RleHQnLAogICAgICAgICAgICAgICAgUmVxdWlyZWQgID0+IDAsCiAgICAgICAgICAgICAgICBTaXplICAgICAgPT4gMTAsCiAgICAgICAgICAgICAgICBNYXhMZW5ndGggPT4gMTAsCiAgICAgICAgICAgIH0sCiAgICAgICAgfTsKICAgICAgICBwdXNoKCBAeyRBdHRyaWJ1dGVzfSwgJE1pblRpbWVCZXR3ZWVuSW5jaWRlbnRzRGVmYXVsdCApOwoKICAgIH0KCiAgICByZXR1cm4gJEF0dHJpYnV0ZXM7Cn0KCj1pdGVtIE1hcHBpbmdPYmplY3RBdHRyaWJ1dGVzR2V0KCkKCmdldCB0aGUgbWFwcGluZyBhdHRyaWJ1dGVzIG9mIGFuIG9iamVjdCBhcyBhcnJheS9oYXNoIHJlZmVyZW5jZQoKICAgIG15ICRBdHRyaWJ1dGVzID0gJE9iamVjdEJhY2tlbmQtPk1hcHBpbmdPYmplY3RBdHRyaWJ1dGVzR2V0KAogICAgICAgIFRlbXBsYXRlSUQgPT4gMTIzLAogICAgICAgIFVzZXJJRCAgICAgPT4gMSwKICAgICk7Cgo9Y3V0CgpzdWIgTWFwcGluZ09iamVjdEF0dHJpYnV0ZXNHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIG15ICRBcmd1bWVudCAocXcoVGVtcGxhdGVJRCBVc2VySUQpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRBcmd1bWVudH0gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICRBcmd1bWVudCEiLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgZ2V0IG9iamVjdCBkYXRhCiAgICBteSAkT2JqZWN0RGF0YSA9ICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fS0+T2JqZWN0RGF0YUdldCgKICAgICAgICBUZW1wbGF0ZUlEID0+ICRQYXJhbXtUZW1wbGF0ZUlEfSwKICAgICAgICBVc2VySUQgICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgKTsKCiAgICBteSAkRWxlbWVudExpc3QgPSBbCiAgICAgICAgewogICAgICAgICAgICBLZXkgICA9PiAnU0xBSUQnLAogICAgICAgICAgICBWYWx1ZSA9PiAnU0xBIElEJywKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgS2V5ICAgPT4gJ05hbWUnLAogICAgICAgICAgICBWYWx1ZSA9PiAnU0xBIE5hbWUnLAogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICBLZXkgICA9PiAnQ2FsZW5kYXInLAogICAgICAgICAgICBWYWx1ZSA9PiAnQ2FsZW5kYXIgTmFtZScsCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgIEtleSAgID0+ICdWYWxpZCcsCiAgICAgICAgICAgIFZhbHVlID0+ICdWYWxpZGl0eScsCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgIEtleSAgID0+ICdDb21tZW50JywKICAgICAgICAgICAgVmFsdWUgPT4gJ0NvbW1lbnQnLAogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICBLZXkgICA9PiAnRmlyc3RSZXNwb25zZVRpbWUnLAogICAgICAgICAgICBWYWx1ZSA9PiAnRmlyc3RSZXNwb25zZVRpbWUgKGJ1c2luZXNzIG1pbnV0ZXMpJywKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgS2V5ICAgPT4gJ0ZpcnN0UmVzcG9uc2VOb3RpZnknLAogICAgICAgICAgICBWYWx1ZSA9PiAnRmlyc3RSZXNwb25zZU5vdGlmeSAocGVyY2VudCknLAogICAgICAgIH0sCiAgICAgICAgewogICAgICAgICAgICBLZXkgICA9PiAnVXBkYXRlVGltZScsCiAgICAgICAgICAgIFZhbHVlID0+ICdVcGRhdGVUaW1lIChidXNpbmVzcyBtaW51dGVzKScsCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgIEtleSAgID0+ICdVcGRhdGVOb3RpZnknLAogICAgICAgICAgICBWYWx1ZSA9PiAnVXBkYXRlTm90aWZ5IChwZXJjZW50KScsCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgIEtleSAgID0+ICdTb2x1dGlvblRpbWUnLAogICAgICAgICAgICBWYWx1ZSA9PiAnU29sdXRpb25UaW1lIChidXNpbmVzcyBtaW51dGVzKScsCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgIEtleSAgID0+ICdTb2x1dGlvbk5vdGlmeScsCiAgICAgICAgICAgIFZhbHVlID0+ICdTb2x1dGlvbk5vdGlmeSAocGVyY2VudCknLAogICAgICAgIH0KICAgIF07CgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBnZXQgcHJlZmVyZW5jZXMuLi4KICAgIG15ICVQcmVmZXJlbmNlcyA9ICgpOwogICAgaWYgKCAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnU0xBUHJlZmVyZW5jZXMnKSApIHsKICAgICAgICAlUHJlZmVyZW5jZXMgPSAleyAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnU0xBUHJlZmVyZW5jZXMnKSB9OwogICAgfQogICAgZm9yIG15ICRJdGVtICggc29ydCBrZXlzICVQcmVmZXJlbmNlcyApIHsKICAgICAgICBpZiAoCiAgICAgICAgICAgICRQcmVmZXJlbmNlc3skSXRlbX0tPntTZWxlY3Rpb25Tb3VyY2V9CiAgICAgICAgICAgICYmICRQcmVmZXJlbmNlc3skSXRlbX0tPntQcmVmS2V5fSA9fiAvXiguKylJRCQvCiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIG15ICROYW1lUGFydCA9ICQxOwogICAgICAgICAgICBwdXNoKAogICAgICAgICAgICAgICAgQHskRWxlbWVudExpc3R9LAogICAgICAgICAgICAgICAgeyBLZXkgPT4gJE5hbWVQYXJ0LCBWYWx1ZSA9PiAkUHJlZmVyZW5jZXN7JEl0ZW19LT57TGFiZWx9IH0KICAgICAgICAgICAgKTsKICAgICAgICB9CgogICAgICAgIGlmICggJFByZWZlcmVuY2VzeyRJdGVtfS0+e1ByZWZLZXl9ID1+IC9eKC4rKUlEJC8gKSB7CiAgICAgICAgICAgIG15ICROYW1lUGFydCA9ICQxOwogICAgICAgICAgICBwdXNoKAogICAgICAgICAgICAgICAgQHskRWxlbWVudExpc3R9LAogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEtleSAgID0+ICRQcmVmZXJlbmNlc3skSXRlbX0tPntQcmVmS2V5fSwKICAgICAgICAgICAgICAgICAgICBWYWx1ZSA9PiAkUHJlZmVyZW5jZXN7JEl0ZW19LT57TGFiZWx9IC4gIiAoSUQpIgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcHVzaCgKICAgICAgICAgICAgICAgIEB7JEVsZW1lbnRMaXN0fSwKICAgICAgICAgICAgICAgIHsgS2V5ID0+ICRQcmVmZXJlbmNlc3skSXRlbX0tPntQcmVmS2V5fSwgVmFsdWUgPT4gJFByZWZlcmVuY2VzeyRJdGVtfS0+e0xhYmVsfSB9CiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgIH0KCiAgICAjIHVzaW5nIFNMQVR5cGVMaXN0IGFzIGluZGljYXRvciBmb3IgSVRTTS1pbnN0YWxsYXRpb24uLi4KICAgIGlmICggJFNlbGYtPntTTEFUeXBlTGlzdH0gKSB7CiAgICAgICAgbXkgJEVsZW1lbnRMaXN0SVRTTSA9IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ICAgPT4gJ1R5cGUnLAogICAgICAgICAgICAgICAgVmFsdWUgPT4gJ1NMQSBUeXBlIChJVFNNIG9ubHkpJywKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ICAgPT4gJ01pblRpbWVCZXR3ZWVuSW5jaWRlbnRzJywKICAgICAgICAgICAgICAgIFZhbHVlID0+ICdNaW4uIFRpbWUgQmV0d2VlbiBJbmNpZGVudHMgKElUU00gb25seSknLAogICAgICAgICAgICB9LAogICAgICAgIF07CiAgICAgICAgbXkgQFRtcEFycmF5ID0gKCBAeyRFbGVtZW50TGlzdH0sIEB7JEVsZW1lbnRMaXN0SVRTTX0gKTsKICAgICAgICAkRWxlbWVudExpc3QgPSBcQFRtcEFycmF5OwogICAgfQoKICAgICMgY29sdW1ucyBmb3IgYXNzaWduZWQgc2VydmljZXMuLi4KICAgIG15ICROdW1iZXJPZkFzc2lnbmFibGVTZXJ2aWNlcyA9ICRPYmplY3REYXRhLT57TnVtYmVyT2ZBc3NpZ25hYmxlU2VydmljZXN9IHx8IDA7CiAgICBteSAkQ3VyckluZGV4ID0gMDsKICAgIHdoaWxlICggJEN1cnJJbmRleCA8ICROdW1iZXJPZkFzc2lnbmFibGVTZXJ2aWNlcyApIHsKCiAgICAgICAgcHVzaCgKICAgICAgICAgICAgQHskRWxlbWVudExpc3R9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgICA9PiAnQXNzaWduZWRTZXJ2aWNlJyAuIHNwcmludGYoICIlMDNkIiwgJEN1cnJJbmRleCApLAogICAgICAgICAgICAgICAgVmFsdWUgPT4gJ0Fzc2lnbmVkU2VydmljZScgLiBzcHJpbnRmKCAiJTAzZCIsICRDdXJySW5kZXggKSwKICAgICAgICAgICAgfQogICAgICAgICk7CgogICAgICAgICRDdXJySW5kZXgrKzsKICAgIH0KCiAgICBteSAkQXR0cmlidXRlcyA9IFsKICAgICAgICB7CiAgICAgICAgICAgIEtleSAgID0+ICdLZXknLAogICAgICAgICAgICBOYW1lICA9PiAnS2V5JywKICAgICAgICAgICAgSW5wdXQgPT4gewogICAgICAgICAgICAgICAgVHlwZSAgICAgICAgID0+ICdTZWxlY3Rpb24nLAogICAgICAgICAgICAgICAgRGF0YSAgICAgICAgID0+ICRFbGVtZW50TGlzdCwKICAgICAgICAgICAgICAgIFJlcXVpcmVkICAgICA9PiAxLAogICAgICAgICAgICAgICAgVHJhbnNsYXRpb24gID0+IDEsCiAgICAgICAgICAgICAgICBQb3NzaWJsZU5vbmUgPT4gMSwKICAgICAgICAgICAgfSwKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgS2V5ICAgPT4gJ0lkZW50aWZpZXInLAogICAgICAgICAgICBOYW1lICA9PiAnSWRlbnRpZmllcicsCiAgICAgICAgICAgIElucHV0ID0+IHsgVHlwZSA9PiAnQ2hlY2tib3gnLCB9LAogICAgICAgIH0sCiAgICBdOwoKICAgIHJldHVybiAkQXR0cmlidXRlczsKfQoKPWl0ZW0gU2VhcmNoQXR0cmlidXRlc0dldCgpCgpnZXQgdGhlIHNlYXJjaCBvYmplY3QgYXR0cmlidXRlcyBvZiBhbiBvYmplY3QgYXMgYXJyYXkvaGFzaCByZWZlcmVuY2UKCiAgICBteSAkQXR0cmlidXRlTGlzdCA9ICRPYmplY3RCYWNrZW5kLT5TZWFyY2hBdHRyaWJ1dGVzR2V0KAogICAgICAgIFRlbXBsYXRlSUQgPT4gMTIzLAogICAgICAgIFVzZXJJRCAgICAgPT4gMSwKICAgICk7Cgo9Y3V0CgpzdWIgU2VhcmNoQXR0cmlidXRlc0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgbXkgJEFyZ3VtZW50IChxdyhUZW1wbGF0ZUlEIFVzZXJJRCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JEFyZ3VtZW50fSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJEFyZ3VtZW50ISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgbXkgJEF0dHJpYnV0ZUxpc3QgPSBbCiAgICAgICAgewogICAgICAgICAgICBLZXkgICA9PiAnTmFtZScsCiAgICAgICAgICAgIE5hbWUgID0+ICdTTEEgTmFtZScsCiAgICAgICAgICAgIElucHV0ID0+IHsKICAgICAgICAgICAgICAgIFR5cGUgICAgICA9PiAnVGV4dCcsCiAgICAgICAgICAgICAgICBTaXplICAgICAgPT4gODAsCiAgICAgICAgICAgICAgICBNYXhMZW5ndGggPT4gMjU1LAogICAgICAgICAgICB9LAogICAgICAgIH0sCiAgICBdOwoKICAgIHJldHVybiAkQXR0cmlidXRlTGlzdDsKfQoKPWl0ZW0gRXhwb3J0RGF0YUdldCgpCgpnZXQgZXhwb3J0IGRhdGEgYXMgMkQtYXJyYXktaGFzaCByZWZlcmVuY2UKCiAgICBteSAkRXhwb3J0RGF0YSA9ICRPYmplY3RCYWNrZW5kLT5FeHBvcnREYXRhR2V0KAogICAgICAgIFRlbXBsYXRlSUQgPT4gMTIzLAogICAgICAgIFVzZXJJRCAgICAgPT4gMSwKICAgICk7Cgo9Y3V0CgpzdWIgRXhwb3J0RGF0YUdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgbXkgJEFyZ3VtZW50IChxdyhUZW1wbGF0ZUlEIFVzZXJJRCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JEFyZ3VtZW50fSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5lZWQgJEFyZ3VtZW50ISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBnZXQgb2JqZWN0IGRhdGEKICAgIG15ICRPYmplY3REYXRhID0gJFNlbGYtPntJbXBvcnRFeHBvcnRPYmplY3R9LT5PYmplY3REYXRhR2V0KAogICAgICAgIFRlbXBsYXRlSUQgPT4gJFBhcmFte1RlbXBsYXRlSUR9LAogICAgICAgIFVzZXJJRCAgICAgPT4gJFBhcmFte1VzZXJJRH0sCiAgICApOwoKICAgICMgY2hlY2sgb2JqZWN0IGRhdGEKICAgIGlmICggISRPYmplY3REYXRhIHx8IHJlZiAkT2JqZWN0RGF0YSBuZSAnSEFTSCcgKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJObyBvYmplY3QgZGF0YSBmb3VuZCBmb3IgdGhlIHRlbXBsYXRlIGlkICRQYXJhbXtUZW1wbGF0ZUlEfSIsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBnZXQgdGhlIG1hcHBpbmcgbGlzdAogICAgbXkgJE1hcHBpbmdMaXN0ID0gJFNlbGYtPntJbXBvcnRFeHBvcnRPYmplY3R9LT5NYXBwaW5nTGlzdCgKICAgICAgICBUZW1wbGF0ZUlEID0+ICRQYXJhbXtUZW1wbGF0ZUlEfSwKICAgICAgICBVc2VySUQgICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgKTsKCiAgICAjIGNoZWNrIHRoZSBtYXBwaW5nIGxpc3QKICAgIGlmICggISRNYXBwaW5nTGlzdCB8fCByZWYgJE1hcHBpbmdMaXN0IG5lICdBUlJBWScgfHwgIUB7JE1hcHBpbmdMaXN0fSApIHsKCiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJObyB2YWxpZCBtYXBwaW5nIGxpc3QgZm91bmQgZm9yIHRoZSB0ZW1wbGF0ZSBpZCAkUGFyYW17VGVtcGxhdGVJRH0iLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgZ2V0IHNlYXJjaCBkYXRhCiAgICBteSAkU2VhcmNoRGF0YSA9ICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fS0+U2VhcmNoRGF0YUdldCgKICAgICAgICBUZW1wbGF0ZUlEID0+ICRQYXJhbXtUZW1wbGF0ZUlEfSwKICAgICAgICBVc2VySUQgICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgKTsKCiAgICBpZiAoICRTZWFyY2hEYXRhICYmIHJlZigkU2VhcmNoRGF0YSkgbmUgJ0hBU0gnICkgewogICAgICAgICRTZWFyY2hEYXRhID0gMDsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSA9PgogICAgICAgICAgICAgICAgIlNMQTogc2VhcmNoIGRhdGEgaXMgbm90IGEgaGFzaCByZWYgLSBpZ25vcmluZyBzZWFyY2ggbGltaXRhdGlvbi4iLAogICAgICAgICk7CiAgICB9CgogICAgaWYgKCAkU2VhcmNoRGF0YSAmJiAkU2VhcmNoRGF0YS0+e05hbWV9ICYmICRTZWFyY2hEYXRhLT57TmFtZX0gPX4gL1wqLyApIHsKICAgICAgICAkU2VhcmNoRGF0YS0+e05hbWV9ID1+IHMvXCovLiovZzsKICAgIH0KCiAgICAjIGNyZWF0ZSB0aGUgbWFwcGluZyBvYmplY3QgbGlzdAogICAgbXkgQE1hcHBpbmdPYmplY3RMaXN0OwogICAgZm9yIG15ICRNYXBwaW5nSUQgKCBAeyRNYXBwaW5nTGlzdH0gKSB7CgogICAgICAgICMgZ2V0IG1hcHBpbmcgb2JqZWN0IGRhdGEKICAgICAgICBteSAkTWFwcGluZ09iamVjdERhdGEgPQogICAgICAgICAgICAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPk1hcHBpbmdPYmplY3REYXRhR2V0KAogICAgICAgICAgICBNYXBwaW5nSUQgPT4gJE1hcHBpbmdJRCwKICAgICAgICAgICAgVXNlcklEICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgICAgICApOwoKICAgICAgICAjIGNoZWNrIG1hcHBpbmcgb2JqZWN0IGRhdGEKICAgICAgICBpZiAoICEkTWFwcGluZ09iamVjdERhdGEgfHwgcmVmICRNYXBwaW5nT2JqZWN0RGF0YSBuZSAnSEFTSCcgKSB7CgogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTm8gdmFsaWQgbWFwcGluZyBsaXN0IGZvdW5kIGZvciB0aGUgdGVtcGxhdGUgaWQgJFBhcmFte1RlbXBsYXRlSUR9IiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgcHVzaCggQE1hcHBpbmdPYmplY3RMaXN0LCAkTWFwcGluZ09iamVjdERhdGEgKTsKICAgIH0KCiAgICAjIGV4cG9ydCBkYXRhLi4uCiAgICBteSBARXhwb3J0RGF0YTsKCiAgICAjIGdldCBwcmVmZXJlbmNlcyBjb25maWd1cmF0aW9uLi4uCiAgICBteSAlUHJlZmVyZW5jZXMgPSAoKTsKICAgIGlmICggJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ1NMQVByZWZlcmVuY2VzJykgKSB7CiAgICAgICAgbXkgJVByZWZDb25maWcgPSAleyAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnU0xBUHJlZmVyZW5jZXMnKSB9OwogICAgICAgIGZvciBteSAkQ3VycktleSAoIGtleXMoJVByZWZDb25maWcpICkgewogICAgICAgICAgICBteSAlQ3VyclByZWZzID0gKCk7CiAgICAgICAgICAgICRDdXJyUHJlZnN7TGFiZWx9ICAgICAgICAgICAgICAgPSAkUHJlZkNvbmZpZ3skQ3VycktleX0tPntMYWJlbH07CiAgICAgICAgICAgICRDdXJyUHJlZnN7U2VsZWN0aW9uU291cmNlfSAgICAgPSAkUHJlZkNvbmZpZ3skQ3VycktleX0tPntTZWxlY3Rpb25Tb3VyY2V9OwogICAgICAgICAgICAkQ3VyclByZWZze0dlbmVyYWxDYXRhbG9nQ2xhc3N9ID0gJFByZWZDb25maWd7JEN1cnJLZXl9LT57R2VuZXJhbENhdGFsb2dDbGFzc307CiAgICAgICAgICAgICRQcmVmZXJlbmNlc3sgJFByZWZDb25maWd7JEN1cnJLZXl9LT57UHJlZktleX0gfSA9IFwlQ3VyclByZWZzOwogICAgICAgIH0KICAgIH0KCiAgICAjIHNlYXJjaCB0aGUgU0xBcy4uLgogICAgbXkgJVNMQUxpc3QgPSAkU2VsZi0+e1NMQU9iamVjdH0tPlNMQUxpc3QoCiAgICAgICAgVmFsaWQgID0+IDAsCiAgICAgICAgVXNlcklEID0+IDEsCiAgICApOwoKICAgIGZvciBteSAkQ3VyclNMQUlEICgga2V5cyglU0xBTGlzdCkgKSB7CgogICAgICAgICNjaGVjayBmb3IgbmFtZSAoU0xBKSBleHBvcnQgZmlsdGVyLi4uCiAgICAgICAgaWYgKCAkU2VhcmNoRGF0YSAmJiAkU2VhcmNoRGF0YS0+e05hbWV9ICkgewogICAgICAgICAgICBpZiAoICRTZWFyY2hEYXRhLT57TmFtZX0gPX4gL1wqLyApIHsKICAgICAgICAgICAgICAgIG5leHQgaWYgKCAkU0xBTGlzdHskQ3VyclNMQUlEfSAhfiAvJFNlYXJjaERhdGEtPntOYW1lfS8gKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIG5leHQgaWYgKCAkU0xBTGlzdHskQ3VyclNMQUlEfSBuZSAkU2VhcmNoRGF0YS0+e05hbWV9ICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIG15ICVTTEFEYXRhID0gJFNlbGYtPntTTEFPYmplY3R9LT5TTEFHZXQoCiAgICAgICAgICAgIFNMQUlEICA9PiAkQ3VyclNMQUlELAogICAgICAgICAgICBVc2VySUQgPT4gMSwgICAgICAgICAgICAjIG5vIHBlcm1pc3Npb24gcmVzdHJpY3Rpb24gZm9yIHRoaXMgZXhwb3J0CiAgICAgICAgKTsKCiAgICAgICAgI2V4cG9ydCB2YWxpZCBzdHJpbmcgaW5zdGVhZCBvZiBJRC4uLgogICAgICAgICRTTEFEYXRhe1ZhbGlkfSA9ICRTZWxmLT57VmFsaWRPYmplY3R9LT5WYWxpZExvb2t1cCgKICAgICAgICAgICAgVmFsaWRJRCA9PiAkU0xBRGF0YXtWYWxpZElEfSwKICAgICAgICApOwoKICAgICAgICBQUkVGRVJFTkNFQ0hFQ0s6CiAgICAgICAgZm9yIG15ICRDdXJyS2V5ICgga2V5cyglU0xBRGF0YSkgKSB7CgogICAgICAgICAgICAjIGNoZWNrIGlmIHRoaXMgaXMgYSBwcmVmZXJlbmNlLi4uCiAgICAgICAgICAgIG5leHQgUFJFRkVSRU5DRUNIRUNLIGlmICggISRQcmVmZXJlbmNlc3skQ3VycktleX0gKTsKCiAgICAgICAgICAgICMgY2hlY2sgaWYgdGhpcyBpcyBhbiBJRC1hdHRyaWJ1dGUuLi4KICAgICAgICAgICAgbmV4dCBQUkVGRVJFTkNFQ0hFQ0sgaWYgKCAkQ3VycktleSAhfiAvXiguKylJRCQvICk7CiAgICAgICAgICAgIG15ICROYW1lUGFydCA9ICQxOwoKICAgICAgICAgICAgIyBza2lwIGlmIGFuIGF0dHJpYnV0ZSB3aXRoIGEgc2ltaWxhciBuYW1lIGJ1dCBubyAiSUQiIHN1ZmZpeCBleGlzdHMuLi4KICAgICAgICAgICAgbmV4dCBQUkVGRVJFTkNFQ0hFQ0sgaWYgKCAkU0xBRGF0YXskTmFtZVBhcnR9ICk7CgogICAgICAgICAgICAjIGNoZWNrIGZvciBzb3VyY2Ugb2YgcHJlZmVyZW5jZS4uLgogICAgICAgICAgICBteSAlU2VsZWN0aW9uTGlzdCA9ICgpOwogICAgICAgICAgICBpZiAoCiAgICAgICAgICAgICAgICAkUHJlZmVyZW5jZXN7JEN1cnJLZXl9LT57U2VsZWN0aW9uU291cmNlfQogICAgICAgICAgICAgICAgJiYgJFByZWZlcmVuY2VzeyRDdXJyS2V5fS0+e1NlbGVjdGlvblNvdXJjZX0gZXEgJ1F1ZXVlTGlzdCcKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgJVNlbGVjdGlvbkxpc3QgPSAkU2VsZi0+e1F1ZXVlT2JqZWN0fS0+UXVldWVMaXN0KCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzaWYgKAogICAgICAgICAgICAgICAgJFByZWZlcmVuY2VzeyRDdXJyS2V5fS0+e1NlbGVjdGlvblNvdXJjZX0KICAgICAgICAgICAgICAgICYmICRQcmVmZXJlbmNlc3skQ3VycktleX0tPntTZWxlY3Rpb25Tb3VyY2V9IGVxICdUeXBlTGlzdCcKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgJVNlbGVjdGlvbkxpc3QgPSAkU2VsZi0+e1R5cGVPYmplY3R9LT5UeXBlTGlzdCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2lmICgKICAgICAgICAgICAgICAgICggJFByZWZlcmVuY2VzeyRDdXJyS2V5fS0+e1NlbGVjdGlvblNvdXJjZX0gKQogICAgICAgICAgICAgICAgJiYKICAgICAgICAgICAgICAgICggJFByZWZlcmVuY2VzeyRDdXJyS2V5fS0+e1NlbGVjdGlvblNvdXJjZX0gZXEgJ0dlbmVyYWxDYXRhbG9nJyApCiAgICAgICAgICAgICAgICAmJgogICAgICAgICAgICAgICAgKCAkUHJlZmVyZW5jZXN7JEN1cnJLZXl9LT57R2VuZXJhbENhdGFsb2dDbGFzc30gKSAmJgogICAgICAgICAgICAgICAgJFNlbGYtPntHZW5lcmFsQ2F0YWxvZ09iamVjdH0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgbXkgJEl0ZW1MaXN0UmVmID0gJFNlbGYtPntHZW5lcmFsQ2F0YWxvZ09iamVjdH0tPkl0ZW1MaXN0KAogICAgICAgICAgICAgICAgICAgIENsYXNzID0+ICRQcmVmZXJlbmNlc3skQ3VycktleX0tPntHZW5lcmFsQ2F0YWxvZ0NsYXNzfSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICBpZiAoICRJdGVtTGlzdFJlZiAmJiByZWYoJEl0ZW1MaXN0UmVmKSBlcSAnSEFTSCcgKSB7CiAgICAgICAgICAgICAgICAgICAgJVNlbGVjdGlvbkxpc3QgPSAleyRJdGVtTGlzdFJlZn07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICMgY3JlYXRlIG5vbi1JRCB2YWx1ZSBmb3IgZXhwb3J0Li4uCiAgICAgICAgICAgICRTTEFEYXRheyROYW1lUGFydH0gPSAkU2VsZWN0aW9uTGlzdHsgJFNMQURhdGF7JEN1cnJLZXl9IH0KICAgICAgICAgICAgICAgIHx8ICRTTEFEYXRheyRDdXJyS2V5fTsKCiAgICAgICAgfQoKICAgICAgICAjIHByZXBhcmVkIEFzc2lnbmVkU2VydmljZXMuLi4KICAgICAgICBpZiAoICRTTEFEYXRhe1NlcnZpY2VJRHN9ICYmIHJlZiggJFNMQURhdGF7U2VydmljZUlEc30gKSBlcSAnQVJSQVknICkgewogICAgICAgICAgICBteSBAU2VydmljZUlETGlzdCA9IHNvcnQgQHsgJFNMQURhdGF7U2VydmljZUlEc30gfTsKICAgICAgICAgICAgbXkgJEN1cnJJbmRleCAgICAgPSAwOwogICAgICAgICAgICBmb3IgbXkgJEN1cnJTZXJ2aWNlSUQgKEBTZXJ2aWNlSURMaXN0KSB7CiAgICAgICAgICAgICAgICBteSAkQ3VycktleU5hbWUgPSAnQXNzaWduZWRTZXJ2aWNlJyAuIHNwcmludGYoICIlMDNkIiwgJEN1cnJJbmRleCApOwogICAgICAgICAgICAgICAgbXkgJEN1cnJTZXJ2aWNlID0gJFNlbGYtPntTZXJ2aWNlT2JqZWN0fS0+U2VydmljZUxvb2t1cCgKICAgICAgICAgICAgICAgICAgICBTZXJ2aWNlSUQgPT4gJEN1cnJTZXJ2aWNlSUQsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgJFNMQURhdGF7JEN1cnJLZXlOYW1lfSA9ICRDdXJyU2VydmljZTsKICAgICAgICAgICAgICAgICRDdXJySW5kZXgrKzsKICAgICAgICAgICAgfQoKICAgICAgICB9CgogICAgICAgICMgcHJlcGFyZSBjYWxlbmRhciBuYW1lCiAgICAgICAgaWYgKCAkU0xBRGF0YXtDYWxlbmRhcn0gJiYgJFNlbGYtPntDYWxlbmRhck5hbWVMaXN0fS0+eyAkU0xBRGF0YXtDYWxlbmRhcn0gfSApIHsKICAgICAgICAgICAgJFNMQURhdGF7Q2FsZW5kYXJ9ID0gJFNlbGYtPntDYWxlbmRhck5hbWVMaXN0fS0+eyAkU0xBRGF0YXtDYWxlbmRhcn0gfTsKICAgICAgICB9CgogICAgICAgICMgY3JlYXRlIGV4cG9ydCByb3cuLi4KICAgICAgICBteSBAQ3VyclJvdyA9IHF3e307CiAgICAgICAgZm9yIG15ICRNYXBwaW5nT2JqZWN0IChATWFwcGluZ09iamVjdExpc3QpIHsKICAgICAgICAgICAgaWYgKCAkTWFwcGluZ09iamVjdC0+e0tleX0gJiYgJFNMQURhdGF7ICRNYXBwaW5nT2JqZWN0LT57S2V5fSB9ICkgewogICAgICAgICAgICAgICAgcHVzaCggQEN1cnJSb3csICRTTEFEYXRheyAkTWFwcGluZ09iamVjdC0+e0tleX0gfSApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgcHVzaCggQEN1cnJSb3csICctJyApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHB1c2ggQEV4cG9ydERhdGEsIFxAQ3VyclJvdzsKCiAgICB9CgogICAgcmV0dXJuIFxARXhwb3J0RGF0YTsKfQoKPWl0ZW0gSW1wb3J0RGF0YVNhdmUoKQoKaW1wb3J0IG9uZSByb3cgb2YgdGhlIGltcG9ydCBkYXRhCgogICAgbXkgJENvbmZpZ0l0ZW1JRCA9ICRPYmplY3RCYWNrZW5kLT5JbXBvcnREYXRhU2F2ZSgKICAgICAgICBUZW1wbGF0ZUlEICAgID0+IDEyMywKICAgICAgICBJbXBvcnREYXRhUm93ID0+ICRBcnJheVJlZiwKICAgICAgICBVc2VySUQgICAgICAgID0+IDEsCiAgICApOwoKPWN1dAoKc3ViIEltcG9ydERhdGFTYXZlIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkQXJndW1lbnQgKHF3KFRlbXBsYXRlSUQgSW1wb3J0RGF0YVJvdyBVc2VySUQpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRBcmd1bWVudH0gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICRBcmd1bWVudCEiLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgY2hlY2sgaW1wb3J0IGRhdGEgcm93CiAgICBpZiAoIHJlZiAkUGFyYW17SW1wb3J0RGF0YVJvd30gbmUgJ0FSUkFZJyApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ0ltcG9ydERhdGFSb3cgbXVzdCBiZSBhbiBhcnJheSByZWZlcmVuY2UnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgZ2V0IG9iamVjdCBkYXRhCiAgICBteSAkT2JqZWN0RGF0YSA9ICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fS0+T2JqZWN0RGF0YUdldCgKICAgICAgICBUZW1wbGF0ZUlEID0+ICRQYXJhbXtUZW1wbGF0ZUlEfSwKICAgICAgICBVc2VySUQgICAgID0+ICRQYXJhbXtVc2VySUR9LAogICAgKTsKCiAgICAjIGNoZWNrIG9iamVjdCBkYXRhCiAgICBpZiAoICEkT2JqZWN0RGF0YSB8fCByZWYgJE9iamVjdERhdGEgbmUgJ0hBU0gnICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAiTm8gb2JqZWN0IGRhdGEgZm91bmQgZm9yIHRoZSB0ZW1wbGF0ZSBpZCAkUGFyYW17VGVtcGxhdGVJRH0iLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgZ2V0IHRoZSBtYXBwaW5nIGxpc3QKICAgIG15ICRNYXBwaW5nTGlzdCA9ICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fS0+TWFwcGluZ0xpc3QoCiAgICAgICAgVGVtcGxhdGVJRCA9PiAkUGFyYW17VGVtcGxhdGVJRH0sCiAgICAgICAgVXNlcklEICAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICk7CgogICAgIyBjaGVjayB0aGUgbWFwcGluZyBsaXN0CiAgICBpZiAoICEkTWFwcGluZ0xpc3QgfHwgcmVmICRNYXBwaW5nTGlzdCBuZSAnQVJSQVknIHx8ICFAeyRNYXBwaW5nTGlzdH0gKSB7CgogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAiTm8gdmFsaWQgbWFwcGluZyBsaXN0IGZvdW5kIGZvciB0aGUgdGVtcGxhdGUgaWQgJFBhcmFte1RlbXBsYXRlSUR9IiwKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGNyZWF0ZSB0aGUgbWFwcGluZyBvYmplY3QgbGlzdAogICAgbXkgQE1hcHBpbmdPYmplY3RMaXN0OwogICAgbXkgJUlkZW50aWZpZXI7CiAgICBteSAkQ291bnRlciAgICAgICAgICA9IDA7CiAgICBteSAlTmV3U0xBRGF0YSAgICAgICA9IHF3e307CiAgICBteSAkU0xBSWRlbnRpZmllcktleSA9ICIiOwoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgI0JVSUxEIE1BUFBJTkcgVEFCTEUuLi4KICAgIGZvciBteSAkTWFwcGluZ0lEICggQHskTWFwcGluZ0xpc3R9ICkgewoKICAgICAgICAjIGdldCBtYXBwaW5nIG9iamVjdCBkYXRhCiAgICAgICAgbXkgJE1hcHBpbmdPYmplY3REYXRhID0KICAgICAgICAgICAgJFNlbGYtPntJbXBvcnRFeHBvcnRPYmplY3R9LT5NYXBwaW5nT2JqZWN0RGF0YUdldCgKICAgICAgICAgICAgTWFwcGluZ0lEID0+ICRNYXBwaW5nSUQsCiAgICAgICAgICAgIFVzZXJJRCAgICA9PiAkUGFyYW17VXNlcklEfSwKICAgICAgICAgICAgKTsKCiAgICAgICAgIyBjaGVjayBtYXBwaW5nIG9iamVjdCBkYXRhCiAgICAgICAgaWYgKCAhJE1hcHBpbmdPYmplY3REYXRhIHx8IHJlZiAkTWFwcGluZ09iamVjdERhdGEgbmUgJ0hBU0gnICkgewoKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIk5vIHZhbGlkIG1hcHBpbmcgbGlzdCBmb3VuZCBmb3IgdGVtcGxhdGUgaWQgJFBhcmFte1RlbXBsYXRlSUR9IiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgcHVzaCggQE1hcHBpbmdPYmplY3RMaXN0LCAkTWFwcGluZ09iamVjdERhdGEgKTsKCiAgICAgICAgaWYgKAogICAgICAgICAgICAkTWFwcGluZ09iamVjdERhdGEtPntJZGVudGlmaWVyfQogICAgICAgICAgICAmJiAkSWRlbnRpZmllcnsgJE1hcHBpbmdPYmplY3REYXRhLT57S2V5fSB9CiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJDYW4ndCBpbXBvcnQgdGhpcyBlbnRpdHkuICIKICAgICAgICAgICAgICAgICAgICAuICInJE1hcHBpbmdPYmplY3REYXRhLT57S2V5fScgaGFzIGJlZW4gdXNlZCBtdWx0aXBsZSAiCiAgICAgICAgICAgICAgICAgICAgLiAidGltZXMgYXMgaWRlbnRpZmllci4hIiwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgZWxzaWYgKCAkTWFwcGluZ09iamVjdERhdGEtPntJZGVudGlmaWVyfSApIHsKICAgICAgICAgICAgJElkZW50aWZpZXJ7ICRNYXBwaW5nT2JqZWN0RGF0YS0+e0tleX0gfSA9CiAgICAgICAgICAgICAgICAkUGFyYW17SW1wb3J0RGF0YVJvd30tPlskQ291bnRlcl07CiAgICAgICAgICAgICRTTEFJZGVudGlmaWVyS2V5ID0gJE1hcHBpbmdPYmplY3REYXRhLT57S2V5fTsKICAgICAgICB9CgogICAgICAgICROZXdTTEFEYXRheyAkTWFwcGluZ09iamVjdERhdGEtPntLZXl9IH0gPQogICAgICAgICAgICAkUGFyYW17SW1wb3J0RGF0YVJvd30tPlskQ291bnRlcl07CgogICAgICAgICRDb3VudGVyKys7CiAgICB9CgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjRE8gVEhFIElNUE9SVC4uLgogICAgIygwKSBQcmVwcm9jZXNzIGRhdGEuLi4KCiAgICAjIHByZXBhcmUgY2FsZW5kYXIgbmFtZS4uLgogICAgaWYgKCAkTmV3U0xBRGF0YXtDYWxlbmRhcn0gJiYgJFNlbGYtPntSZXZlcnNlQ2FsZW5kYXJOYW1lTGlzdH0tPnsgJE5ld1NMQURhdGF7Q2FsZW5kYXJ9IH0gKSB7CiAgICAgICAgJE5ld1NMQURhdGF7Q2FsZW5kYXJ9ID0gJFNlbGYtPntSZXZlcnNlQ2FsZW5kYXJOYW1lTGlzdH0tPnsgJE5ld1NMQURhdGF7Q2FsZW5kYXJ9IH07CiAgICB9CgogICAgIyBsb29rdXAgVmFsaWQtSUQuLi4KICAgIGlmICggISROZXdTTEFEYXRhe1ZhbGlkSUR9ICYmICROZXdTTEFEYXRhe1ZhbGlkfSApIHsKICAgICAgICAkTmV3U0xBRGF0YXtWYWxpZElEfSA9ICRTZWxmLT57VmFsaWRPYmplY3R9LT5WYWxpZExvb2t1cCgKICAgICAgICAgICAgVmFsaWQgPT4gJE5ld1NMQURhdGF7VmFsaWR9CiAgICAgICAgKTsKICAgIH0KICAgIGlmICggISROZXdTTEFEYXRhe1ZhbGlkSUR9ICkgewogICAgICAgICROZXdTTEFEYXRhe1ZhbGlkSUR9ID0gJE9iamVjdERhdGEtPntEZWZhdWx0VmFsaWR9IHx8IDE7CiAgICB9CgogICAgIyBsb29rdXAgdHlwZS1JRC4uLgogICAgaWYgKAogICAgICAgICRTZWxmLT57UmV2ZXJzZVNMQVR5cGVMaXN0fQogICAgICAgICYmICROZXdTTEFEYXRhe1R5cGV9CiAgICAgICAgJiYgJFNlbGYtPntSZXZlcnNlU0xBVHlwZUxpc3R9LT57ICROZXdTTEFEYXRhe1R5cGV9IH0KICAgICAgICApCiAgICB7CiAgICAgICAgJE5ld1NMQURhdGF7VHlwZUlEfSA9ICRTZWxmLT57UmV2ZXJzZVNMQVR5cGVMaXN0fS0+eyAkTmV3U0xBRGF0YXtUeXBlfSB9OwogICAgfQogICAgaWYgKCAhJE5ld1NMQURhdGF7VHlwZUlEfSApIHsKICAgICAgICAkTmV3U0xBRGF0YXtUeXBlSUR9ID0gJE9iamVjdERhdGEtPntEZWZhdWx0U0xBVHlwZUlEfTsKICAgIH0KCiAgICAjIGxvb2t1cCBhc3NpZ25lZCBTZXJ2aWNlSURzCiAgICBteSAkTnVtYmVyT2ZBc3NpZ25hYmxlU2VydmljZXMgPSAkT2JqZWN0RGF0YS0+e051bWJlck9mQXNzaWduYWJsZVNlcnZpY2VzfSB8fCAwOwogICAgbXkgJEN1cnJJbmRleCAgICAgICAgICAgICAgICAgID0gMDsKICAgIG15IEBOZXdTZXJ2aWNlSURzICAgICAgICAgICAgICA9IHF3e307CiAgICB3aGlsZSAoICRDdXJySW5kZXggPCAkTnVtYmVyT2ZBc3NpZ25hYmxlU2VydmljZXMgKSB7CiAgICAgICAgbXkgJEN1cnJLZXlOYW1lID0gJ0Fzc2lnbmVkU2VydmljZScgLiBzcHJpbnRmKCAiJTAzZCIsICRDdXJySW5kZXggKTsKCiAgICAgICAgaWYgKCAkTmV3U0xBRGF0YXskQ3VycktleU5hbWV9ICYmICROZXdTTEFEYXRheyRDdXJyS2V5TmFtZX0gbmUgJy0nICkgewogICAgICAgICAgICBteSAkQ3VyclNlcnZpY2VJRCA9ICRTZWxmLT57U2VydmljZU9iamVjdH0tPlNlcnZpY2VMb29rdXAoCiAgICAgICAgICAgICAgICBOYW1lID0+ICROZXdTTEFEYXRheyRDdXJyS2V5TmFtZX0sCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIGlmICgkQ3VyclNlcnZpY2VJRCkgewogICAgICAgICAgICAgICAgcHVzaCggQE5ld1NlcnZpY2VJRHMsICRDdXJyU2VydmljZUlEICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICRDdXJySW5kZXgrKzsKICAgIH0KCiAgICAjLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAjIHByZXBhcmUgcHJlZmVyZW5jZXMuLi4KCiAgICAjIGdldCBwcmVmZXJlbmNlcyBjb25maWd1cmF0aW9uLi4uCiAgICBteSAlUHJlZmVyZW5jZXMgPSAoKTsKICAgIGlmICggJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ1NMQVByZWZlcmVuY2VzJykgKSB7CiAgICAgICAgbXkgJVByZWZDb25maWcgPSAleyAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnU0xBUHJlZmVyZW5jZXMnKSB9OwogICAgICAgIGZvciBteSAkQ3VycktleSAoIGtleXMoJVByZWZDb25maWcpICkgewogICAgICAgICAgICBteSAlQ3VyclByZWZzID0gKCk7CiAgICAgICAgICAgICRDdXJyUHJlZnN7TGFiZWx9ICAgICAgICAgICAgICAgPSAkUHJlZkNvbmZpZ3skQ3VycktleX0tPntMYWJlbH07CiAgICAgICAgICAgICRDdXJyUHJlZnN7U2VsZWN0aW9uU291cmNlfSAgICAgPSAkUHJlZkNvbmZpZ3skQ3VycktleX0tPntTZWxlY3Rpb25Tb3VyY2V9OwogICAgICAgICAgICAkQ3VyclByZWZze0dlbmVyYWxDYXRhbG9nQ2xhc3N9ID0gJFByZWZDb25maWd7JEN1cnJLZXl9LT57R2VuZXJhbENhdGFsb2dDbGFzc307CiAgICAgICAgICAgICRQcmVmZXJlbmNlc3sgJFByZWZDb25maWd7JEN1cnJLZXl9LT57UHJlZktleX0gfSA9IFwlQ3VyclByZWZzOwogICAgICAgIH0KICAgIH0KCiAgICBQUkVGRVJFTkNFQ0hFQ0s6CiAgICBmb3IgbXkgJEN1cnJLZXkgKCBrZXlzKCVOZXdTTEFEYXRhKSApIHsKICAgICAgICBteSAkQ3VyclVzZWRLZXkgPSAiIjsKICAgICAgICBteSAkTmFtZVBhcnQgICAgPSAkQ3VycktleTsKICAgICAgICBpZiAoICRDdXJyS2V5ID1+IC9eKC4rKUlEJC8gKSB7CiAgICAgICAgICAgICROYW1lUGFydCAgICA9ICQxOwogICAgICAgICAgICAkQ3VyclVzZWRLZXkgPSAkQ3VycktleTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRDdXJyVXNlZEtleSA9ICRDdXJyS2V5IC4gIklEIjsKICAgICAgICB9CgogICAgICAgICMgc2tpcCBpZiBubyBwcmVmZXJlbmNlIHdpdGggc2FtZSBuYW1lIGJ1dCBzdWZmaXggIklEIiBleGlzdHMuLi4KICAgICAgICBuZXh0IFBSRUZFUkVOQ0VDSEVDSyBpZiAoICEkUHJlZmVyZW5jZXN7JEN1cnJVc2VkS2V5fSApOwoKICAgICAgICAjIHNraXAgaWYgbm8gU2VsZWN0aW9uU291cmNlIHNwZWNpZmllZC4uCiAgICAgICAgbmV4dCBQUkVGRVJFTkNFQ0hFQ0sgaWYgKCAhJFByZWZlcmVuY2VzeyRDdXJyVXNlZEtleX0tPntTZWxlY3Rpb25Tb3VyY2V9ICk7CgogICAgICAgICMgY2hlY2sgZm9yIHNvdXJjZSBvZiBwcmVmZXJlbmNlLi4uCiAgICAgICAgbXkgJVNlbGVjdGlvbkxpc3QgPSAoKTsKICAgICAgICBpZiAoICRQcmVmZXJlbmNlc3skQ3VyclVzZWRLZXl9LT57U2VsZWN0aW9uU291cmNlfSBlcSAnUXVldWVMaXN0JyApIHsKICAgICAgICAgICAgJVNlbGVjdGlvbkxpc3QgPSAkU2VsZi0+e1F1ZXVlT2JqZWN0fS0+UXVldWVMaXN0KCk7CiAgICAgICAgfQogICAgICAgIGVsc2lmICggJFByZWZlcmVuY2VzeyRDdXJyVXNlZEtleX0tPntTZWxlY3Rpb25Tb3VyY2V9IGVxICdUeXBlTGlzdCcgKSB7CiAgICAgICAgICAgICVTZWxlY3Rpb25MaXN0ID0gJFNlbGYtPntUeXBlT2JqZWN0fS0+VHlwZUxpc3QoKTsKICAgICAgICB9CiAgICAgICAgZWxzaWYgKAogICAgICAgICAgICAoICRQcmVmZXJlbmNlc3skQ3VyclVzZWRLZXl9LT57U2VsZWN0aW9uU291cmNlfSBlcSAnR2VuZXJhbENhdGFsb2cnICkKICAgICAgICAgICAgJiYKICAgICAgICAgICAgKCAkUHJlZmVyZW5jZXN7JEN1cnJVc2VkS2V5fS0+e0dlbmVyYWxDYXRhbG9nQ2xhc3N9ICkgJiYKICAgICAgICAgICAgJFNlbGYtPntHZW5lcmFsQ2F0YWxvZ09iamVjdH0KICAgICAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgbXkgJEl0ZW1MaXN0UmVmID0gJFNlbGYtPntHZW5lcmFsQ2F0YWxvZ09iamVjdH0tPkl0ZW1MaXN0KAogICAgICAgICAgICAgICAgQ2xhc3MgPT4gJFByZWZlcmVuY2VzeyRDdXJyVXNlZEtleX0tPntHZW5lcmFsQ2F0YWxvZ0NsYXNzfSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgaWYgKCAkSXRlbUxpc3RSZWYgJiYgcmVmKCRJdGVtTGlzdFJlZikgZXEgJ0hBU0gnICkgewogICAgICAgICAgICAgICAgJVNlbGVjdGlvbkxpc3QgPSAleyRJdGVtTGlzdFJlZn07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgbXkgJVJldmVyc2VTZWxlY3Rpb25MaXN0ID0gcmV2ZXJzZSglU2VsZWN0aW9uTGlzdCk7CgogICAgICAgICMgaWYgb25seSB4eHhJRCBpcyBnaXZlbiwgc2V0IHh4eC4uLgogICAgICAgIGlmICgKICAgICAgICAgICAgJE5ld1NMQURhdGF7JEN1cnJVc2VkS2V5fQogICAgICAgICAgICAmJiAoICEkTmV3U0xBRGF0YXskTmFtZVBhcnR9IHx8ICROYW1lUGFydCBlcSAkQ3VyclVzZWRLZXkgKQogICAgICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICAkTmV3U0xBRGF0YXskTmFtZVBhcnR9ID0gJFNlbGVjdGlvbkxpc3R7ICROZXdTTEFEYXRheyRDdXJyVXNlZEtleX0gfTsKICAgICAgICB9CgogICAgICAgICMgaWYgeHh4SUQgQU5EIHh4eCBhcmUgZ2l2ZW4gcmVxdWlyZSB1bmlxZW5lc3MuLi4KICAgICAgICBlbHNpZiAoICROZXdTTEFEYXRheyRDdXJyVXNlZEtleX0gJiYgJE5ld1NMQURhdGF7JE5hbWVQYXJ0fSApIHsKICAgICAgICAgICAgbXkgJENvbXBhcmVWYWx1ZSA9ICRTZWxlY3Rpb25MaXN0eyAkTmV3U0xBRGF0YXskQ3VyclVzZWRLZXl9IH07CiAgICAgICAgICAgIGlmICggJENvbXBhcmVWYWx1ZSBuZSAkTmV3U0xBRGF0YXskTmFtZVBhcnR9ICkgewogICAgICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiQ2FuJ3QgaW1wb3J0IHRoaXMgZW50aXR5LiAiCiAgICAgICAgICAgICAgICAgICAgICAgIC4gIkFtYmlnb3VzIGRlZmluaXRpb24gb2YgYXR0cmlidXRlIHZhbHVlcyAiCiAgICAgICAgICAgICAgICAgICAgICAgIC4gIiAoJE5hbWVQYXJ0IDwkTmV3U0xBRGF0YXskTmFtZVBhcnR9PiBkb2VzIG5vdCIKICAgICAgICAgICAgICAgICAgICAgICAgLiAibWF0Y2ggJEN1cnJVc2VkS2V5IDwkTmV3U0xBRGF0YXskQ3VyclVzZWRLZXl9PikhIiwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgaWYgb25seSB4eHggaXMgZ2l2ZW4gYW5kIElEIGNhbiBiZSBmb3VuZCAtIGdldCB0aGUgSUQuLi4KICAgICAgICBlbHNpZiAoCiAgICAgICAgICAgICEkTmV3U0xBRGF0YXskQ3VyclVzZWRLZXl9CiAgICAgICAgICAgICYmICROZXdTTEFEYXRheyROYW1lUGFydH0KICAgICAgICAgICAgJiYgJFJldmVyc2VTZWxlY3Rpb25MaXN0eyAkTmV3U0xBRGF0YXskTmFtZVBhcnR9IH0KICAgICAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgJE5ld1NMQURhdGF7JEN1cnJVc2VkS2V5fSA9ICRSZXZlcnNlU2VsZWN0aW9uTGlzdHsgJE5ld1NMQURhdGF7JE5hbWVQYXJ0fSB9OwogICAgICAgIH0KCiAgICAgICAgIyBpZiBvbmx5IHh4eCBpcyBnaXZlbiBhbmQgbm8gSUQgY2FuIGJlIGZvdW5kIC0gcmVqZWN0IGltcG9ydC4uLgogICAgICAgIGVsc2lmICgKICAgICAgICAgICAgISROZXdTTEFEYXRheyRDdXJyVXNlZEtleX0KICAgICAgICAgICAgJiYgJE5ld1NMQURhdGF7JE5hbWVQYXJ0fQogICAgICAgICAgICAmJiAhJFJldmVyc2VTZWxlY3Rpb25MaXN0eyAkTmV3U0xBRGF0YXskTmFtZVBhcnR9IH0KICAgICAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIkNhbid0IGltcG9ydCB0aGlzIGVudGl0eS4gIgogICAgICAgICAgICAgICAgICAgIC4gIkJhZCBkZWZpbml0aW9uIG9mIGF0dHJpYnV0ZSB2YWx1ZSAiCiAgICAgICAgICAgICAgICAgICAgLiAiICgkTmFtZVBhcnQgPCROZXdTTEFEYXRheyROYW1lUGFydH0+IGRvZXMgbm90IgogICAgICAgICAgICAgICAgICAgIC4gIm1hdGNoIGFueSBleGlzdGluZyB2YWx1ZSBpbiBzZWxlY3Rpb24pISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgfQoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMoMSkgc2VhcmNoIFNMQS4uLgogICAgbXkgJVNMQURhdGEgPSAoKTsKICAgIG15ICROZXdTTEEgID0gMTsKICAgIG15ICRTTEFJRCAgID0gJE5ld1NMQURhdGF7JFNMQUlkZW50aWZpZXJLZXl9IHx8IDA7CgogICAgaWYgKAogICAgICAgICggISRTTEFJZGVudGlmaWVyS2V5IHx8ICRTTEFJZGVudGlmaWVyS2V5IGVxICdOYW1lJyB8fCAhJE5ld1NMQURhdGF7JFNMQUlkZW50aWZpZXJLZXl9ICkKICAgICAgICAmJiAkTmV3U0xBRGF0YXtOYW1lfQogICAgICAgICkKICAgIHsKICAgICAgICAkU0xBSUQgPSAkU2VsZi0+e1NMQU9iamVjdH0tPlNMQUxvb2t1cCgKICAgICAgICAgICAgTmFtZSA9PiAkTmV3U0xBRGF0YXtOYW1lfSwKICAgICAgICApOwogICAgfQoKICAgIGlmICggJFNMQUlEICYmICRTTEFJRCA9fiAvXGQrLyApIHsKICAgICAgICAlU0xBRGF0YSA9ICRTZWxmLT57U0xBT2JqZWN0fS0+U0xBR2V0KAogICAgICAgICAgICBTTEFJRCAgPT4gJFNMQUlELAogICAgICAgICAgICBVc2VySUQgPT4gMSwKICAgICAgICApOwogICAgfQogICAgZWxzaWYgKCRTTEFJRCkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnbm90aWNlJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ0ltcG9ydERhdGFTYXZlOiBTTEFJRCA8JyAuICRTTEFJRCAuICc+IGlzIG5vdCBhIG51bWJlciAnCiAgICAgICAgICAgICAgICAuICcobWF5YmUgbGFiZWwgb3IgaGVhZGxpbmUpLicsCiAgICAgICAgKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoIHNjYWxhcigga2V5cyglU0xBRGF0YSkgKSApIHsKICAgICAgICAkTmV3U0xBID0gMDsKICAgIH0KCiAgICBmb3IgbXkgJEtleSAoIGtleXMoJU5ld1NMQURhdGEpICkgewogICAgICAgIG5leHQgaWYgKCAhJE5ld1NMQURhdGF7JEtleX0gKTsKICAgICAgICAkU0xBRGF0YXskS2V5fSA9ICROZXdTTEFEYXRheyRLZXl9OwogICAgfQoKICAgIGZvciBteSAkQ3VycktleSAoCiAgICAgICAgcXcoIEZpcnN0UmVzcG9uc2VUaW1lIEZpcnN0UmVzcG9uc2VOb3RpZnkgVXBkYXRlVGltZQogICAgICAgIFVwZGF0ZU5vdGlmeSBTb2x1dGlvblRpbWUgU29sdXRpb25Ob3RpZnkgTWluVGltZUJldHdlZW5JbmNpZGVudHMpCiAgICAgICAgKQogICAgewogICAgICAgIGlmICggJFNMQURhdGF7JEN1cnJLZXl9ICYmICRTTEFEYXRheyRDdXJyS2V5fSBlcSAnLScgKSB7CiAgICAgICAgICAgIGRlbGV0ZSggJFNMQURhdGF7JEN1cnJLZXl9ICk7CiAgICAgICAgfQogICAgfQoKICAgICRTTEFEYXRhe1NlcnZpY2VJRHN9ID0gXEBOZXdTZXJ2aWNlSURzOwoKICAgICMoMikgaWYgU0xBIERPRVMgTk9UIGV4aXN0cyA9PiBjcmVhdGUgbmV3Li4uCiAgICBteSAkUmVzdWx0ID0gMDsKICAgIGlmICgkTmV3U0xBKSB7CiAgICAgICAgJFJlc3VsdCA9ICRTZWxmLT57U0xBT2JqZWN0fS0+U0xBQWRkKAogICAgICAgICAgICAlU0xBRGF0YSwKICAgICAgICAgICAgVXNlcklEID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgICk7CgogICAgICAgIGlmICggISRSZXN1bHQgKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdJbXBvcnREYXRhU2F2ZTogYWRkaW5nIFNMQSA8JwogICAgICAgICAgICAgICAgICAgIC4gJFNMQURhdGF7TmFtZX0KICAgICAgICAgICAgICAgICAgICAuICc+IGZhaWxlZC4nLAogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KCiAgICAjKDMpIGlmIFNMQSBET0VTIGV4aXN0cyA9PiB1cGRhdGUuLi4KICAgIGlmICggISROZXdTTEEgKSB7CiAgICAgICAgJFJlc3VsdCA9ICRTZWxmLT57U0xBT2JqZWN0fS0+U0xBVXBkYXRlKAogICAgICAgICAgICAlU0xBRGF0YSwKICAgICAgICAgICAgVXNlcklEID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgICk7CgogICAgICAgIGlmICggISRSZXN1bHQgKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdJbXBvcnREYXRhU2F2ZTogdXBkYXRpbmcgU0xBIDwnCiAgICAgICAgICAgICAgICAgICAgLiAkU0xBRGF0YXtOYW1lfQogICAgICAgICAgICAgICAgICAgIC4gJz4gKElEICcKICAgICAgICAgICAgICAgICAgICAuICRTTEFEYXRhe1NMQUlEfQogICAgICAgICAgICAgICAgICAgIC4gJykgZmFpbGVkLicsCiAgICAgICAgICAgICk7CiAgICAgICAgfQoKICAgIH0KCiAgICAjKDQpIHNldCBwcmVmZXJlbmNlcy4uLgogICAgaWYgKCRTTEFJRCkgewogICAgICAgIGZvciBteSAkQ3VycktleSAoIGtleXMoJVByZWZlcmVuY2VzKSApIHsKICAgICAgICAgICAgbmV4dCBpZiAoICEkTmV3U0xBRGF0YXskQ3VycktleX0gKTsKICAgICAgICAgICAgJFNlbGYtPntTTEFPYmplY3R9LT5TTEFQcmVmZXJlbmNlc1NldCgKICAgICAgICAgICAgICAgIFNMQUlEICA9PiAkU0xBSUQsCiAgICAgICAgICAgICAgICBLZXkgICAgPT4gJEN1cnJLZXksCiAgICAgICAgICAgICAgICBWYWx1ZSAgPT4gJE5ld1NMQURhdGF7JEN1cnJLZXl9LAogICAgICAgICAgICAgICAgVXNlcklEID0+ICRQYXJhbXtVc2VySUR9LAogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAkUmVzdWx0Owp9CgoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBzb2Z0d2FyZSBpcyBhIGRlcml2YXRpdmUgcGFydCBvZiB0aGUgT1RSUyBwcm9qZWN0IChodHRwOi8vb3Rycy5vcmcvKS4KClRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCnRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQpkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0yLjAudHh0LgoKPWN1dAoKPWhlYWQxIFZFUlNJT04KCiRSZXZpc2lvbjogMS4xMCAkICREYXRlOiAyMDExLTExLTI5IDEwOjI4OjU3ICQKCj1jdXQKCg==
IyAtLQojIEtlcm5lbC9MYW5ndWFnZS9kZV9TZXJ2aWNlSW1wb3J0RXhwb3J0IC0gcHJvdmlkZXMgZ2VybWFuIGxhbmd1YWdlCiMgdHJhbnNsYXRpb24gZm9yIFNlcnZpY2VJbXBvcnRFeHBvcnQgbW9kdWxlCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMTEgYy5hLnAuZS4gSVQgR21iSCwgaHR0cDovL3d3dy5jYXBlLWl0LmRlCiMKIwojIC0tCiMgJElkOiBkZV9TZXJ2aWNlSW1wb3J0RXhwb3J0LnBtLHYgMS4zIDIwMTEtMDMtMDggMTE6MTU6NTYgdHRvIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCnBhY2thZ2UgS2VybmVsOjpMYW5ndWFnZTo6ZGVfU2VydmljZUltcG9ydEV4cG9ydDsKCnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKCnVzZSB2YXJzIHF3KCRWRVJTSU9OKTsKJFZFUlNJT04gPSAnJFJldmlzaW9uOiAxLjMgJCc7CiRWRVJTSU9OID1+IHMvXlwkLio6XFcoLiopXFcuKz8kLyQxLzsKCiMgLS0Kc3ViIERhdGEgewogICAgbXkgJFNlbGYgPSBzaGlmdDsKCiAgICBteSAkTGFuZyA9ICRTZWxmLT57VHJhbnNsYXRpb259OwoKICAgIHJldHVybiBpZiByZWYgJExhbmcgbmUgJ0hBU0gnOwoKICAgICMgJCRTVEFSVCQkCgogICAgIyB0cmFuc2xhdGlvbnMgbWlzc2luZyBpbiBJbXBvcnRFeHBvcnQuLi4KICAgICRMYW5nLT57J0NvbHVtbiBTZXBlcmF0b3InfSAgICAgICAgICAgPSAnU3BhbHRlbnRyZW5uZXInOwogICAgJExhbmctPnsnQ2hhcnNldCd9ICAgICAgICAgICAgICAgICAgICA9ICdaZWljaGVuc2F0eic7CiAgICAkTGFuZy0+eydSZXN0cmljdCBleHBvcnQgcGVyIHNlYXJjaCd9ID0gJ0V4cG9ydCBtaXR0ZWxzIFN1Y2hlIGVpbnNjaHLkbmtlbic7CgogICAgIyBzZXJ2aWNlMmN1c3RvbWVydXNlciBleC0vaW1wb3J0Li4uCiAgICAkTGFuZy0+eydTZXJ2aWNlIGF2YWlsYWJsZSBmb3IgQ1UnfSA9ICdTZXJ2aWNlIGb8ciBLdW5kZW5udXR6ZXIgdmVyZvxnYmFyJzsKICAgICRMYW5nLT57J0N1c3RvbWVyIFVzZXIgTG9naW4nfSAgICAgID0gJ0t1bmRlbm51dHplcmxvZ2luJzsKICAgICRMYW5nLT57J1ZhbGlkaXR5IG9mIHNlcnZpY2UgYXNzaWdubWVudCBmb3IgQ1UnfSA9CiAgICAgICAgJ0f8bHRpZ2tlaXQgZGVyIFNlcnZpY2V6dW9yZG51bmcgenUgS3VuZGVubnV0emVyJzsKCiAgICAjIHNlcnZpY2UgZXgtL2ltcG9ydC4uLgogICAgJExhbmctPnsnRnVsbCBTZXJ2aWNlIE5hbWUnfSAgICAgICAgICAgICAgICAgID0gJ1ZvbGxzdORuZGlnZXIgU2VydmljZW5hbWUnOwogICAgJExhbmctPnsnU2hvcnQgU2VydmljZSBOYW1lJ30gICAgICAgICAgICAgICAgID0gJ0t1cnpzZXJ2aWNlbmFtZSc7CiAgICAkTGFuZy0+eydTZXJ2aWNlIFR5cGUgKElUU00gb25seSknfSAgICAgICAgICAgPSAnU2VydmljZXR5cCAobnVyIElUU00pJzsKICAgICRMYW5nLT57J0NyaXRpY2FsaXR5IChJVFNNIG9ubHkpJ30gICAgICAgICAgICA9ICdLcml0aWthbGl05HQgKG51ciBJVFNNKSc7CiAgICAkTGFuZy0+eydDdXJyZW50IEluY2lkZW50IFN0YXRlIChJVFNNIG9ubHkpJ30gPSAnQWt0LiBTdPZydW5nc3N0YXR1cyAobnVyIElUU00pJzsKICAgICRMYW5nLT57J0N1cnJlbnQgSW5jaWRlbnQgU3RhdGUgVHlwZSAoSVRTTSBvbmx5KSd9CiAgICAgICAgPSAnQWt0LiBTdPZydW5nc3N0YXR1c3R5cCAobnVyIElUU00pJzsKICAgICRMYW5nLT57J0RlZmF1bHQgU2VydmljZSBUeXBlJ30gPSAnU3RhbmRhcmQtU2VydmljZXR5cCc7CiAgICAkTGFuZy0+eydWYWxpZGl0eSd9ICAgICAgICAgICAgID0gJ0f8bHRpZ2tlaXQnOwogICAgJExhbmctPnsnRGVmYXVsdCBWYWxpZGl0eSd9ICAgICA9ICdTdGFuZGFyZC1H/Gx0aWdrZWl0JzsKICAgICRMYW5nLT57J0RlZmF1bHQgQ3JpdGljYWxpdHknfSAgPSAnU3RhbmRhcmQtS3JpdGlrYWxpdOR0JzsKCiAgICAjIFNMQSBleC0vaW1wb3J0Li4uCiAgICAkTGFuZy0+eydEZWZhdWx0IFNMQSBUeXBlJ30gICAgICAgICAgICAgICAgICAgICAgID0gJ1N0YW5kYXJkLVNMQS1UeXAnOwogICAgJExhbmctPnsnRGVmYXVsdCBNaW5pbXVtIFRpbWUgQmV0d2VlbiBJbmNpZGVudHMnfSA9ICdTdGFuZGFyZCBNaW5pbXVtemVpdCB6d2lzY2hlbiBTdPZydW5nZW4nOwogICAgJExhbmctPnsnTWF4LiBudW1iZXIgb2YgY29sdW1ucyB3aGljaCBtYXkgY29udGFpbiBhc3NpZ25lZCBzZXJ2aWNlcyd9CiAgICAgICAgPSAnTWF4LiBBbnphaGwgdm9uIFNwYWx0ZW4gZGllIHp1Z2V3aWVzZW5lIFNlcnZpY2VzIGVudGhhbHRlbiBr9m5uZW4nOwogICAgJExhbmctPnsnTWF4LiBudW1iZXIgb2YgYXNzaWduZWQgc2VydmljZXMgY29sdW1ucyd9ID0gJ01heC4gU3BhbHRlbmFuemFobCB6dWdldy4gU2VydmljZXMnOwoKICAgICRMYW5nLT57J1NMQSBUeXBlIChJVFNNIG9ubHkpJ30gPSAnU0xBIFR5cCAobnVyIElUU00pJzsKICAgICRMYW5nLT57J01pbi4gVGltZSBCZXR3ZWVuIEluY2lkZW50cyAoSVRTTSBvbmx5KSd9CiAgICAgICAgPSAnU3RhbmRhcmQgTWluaW11bXplaXQgendpc2NoZW4gU3T2cnVuZ2VuIChudXIgSVRTTSknOwogICAgJExhbmctPnsnU29sdXRpb25Ob3RpZnkgKHBlcmNlbnQpJ30gICAgICAgID0gJ1NvbHV0aW9uTm90aWZ5IChQcm96ZW50KSc7CiAgICAkTGFuZy0+eydTb2x1dGlvblRpbWUgKGJ1c2luZXNzIG1pbnV0ZXMpJ30gPSAnU29sdXRpb25UaW1lIChHZXNjaORmdHNtaW51dGVuKSc7CiAgICAkTGFuZy0+eydVcGRhdGVOb3RpZnkgKHBlcmNlbnQpJ30gICAgICAgICAgPSAnVXBkYXRlTm90aWZ5IChQcm96ZW50KSc7CiAgICAkTGFuZy0+eydVcGRhdGVUaW1lIChidXNpbmVzcyBtaW51dGVzKSd9ICAgPSAnVXBkYXRlVGltZSAoR2VzY2jkZnRzbWludXRlbiknOwogICAgJExhbmctPnsnRmlyc3RSZXNwb25zZU5vdGlmeSAocGVyY2VudCknfSAgID0gJ0ZpcnN0UmVzcG9uc2VOb3RpZnkgKFByb3plbnQpJzsKICAgICRMYW5nLT57J0ZpcnN0UmVzcG9uc2VUaW1lIChidXNpbmVzcyBtaW51dGVzKSd9CiAgICAgICAgPSAnRmlyc3RSZXNwb25zZVRpbWUgKEdlc2No5GZ0c21pbnV0ZW4pJzsKICAgICRMYW5nLT57J0NhbGVuZGFyIE5hbWUnfSA9ICdLYWxlbmRlcm5hbWUnOwoKICAgICRMYW5nLT57J0V4cG9ydCB3aXRoIGxhYmVscyd9ID0gJ01pdCBCZXNjaHJpZnR1bmcgZXhwb3J0aWVyZW4nOwogICAgJExhbmctPnsnJ30gICAgICAgICAgICAgICAgICAgPSAnJzsKCiAgICByZXR1cm4gMDsKCiAgICAjICQkU1RPUCQkCn0KCiMgLS0KMTsK
IyAtLQojIFNlcnZpY2VJbXBvcnRFeHBvcnQucG0gLSBjb2RlIHJ1biBkdXJpbmcgcGFja2FnZSBkZS0vaW5zdGFsbGF0aW9uCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMTEgYy5hLnAuZS4gSVQgR21iSCwgaHR0cDovL3d3dy5jYXBlLWl0LmRlCiMKIyB3cml0dGVuL2VkaXRlZCBieToKIyAgIFRvcnN0ZW4oZG90KVRoYXUoYXQpY2FwZS1pdC5kZQojICAgTWFydGluKGRvdClCYWx6YXJlayhhdCljYXBlLWl0LmRlCiMKIyAtLQojICRJZDogU2VydmljZUltcG9ydEV4cG9ydC5wbSx2IDEuMTQgMjAxMS0xMS0yOSAxMDoyODo1NyB0dG8gRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtMi4wLnR4dC4KIyAtLQoKcGFja2FnZSB2YXI6OnBhY2thZ2VzZXR1cDo6U2VydmljZUltcG9ydEV4cG9ydDsKCnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKCnVzZSBLZXJuZWw6OkNvbmZpZzsKdXNlIEtlcm5lbDo6U3lzdGVtOjpTeXNDb25maWc7CnVzZSBLZXJuZWw6OlN5c3RlbTo6TG9nOwp1c2UgS2VybmVsOjpTeXN0ZW06OkRCOwp1c2UgS2VybmVsOjpTeXN0ZW06Ok1haW47CnVzZSBLZXJuZWw6OlN5c3RlbTo6RW5jb2RlOwp1c2UgS2VybmVsOjpTeXN0ZW06OkltcG9ydEV4cG9ydDsKdXNlIEtlcm5lbDo6U3lzdGVtOjpTZXJ2aWNlOwp1c2UgS2VybmVsOjpTeXN0ZW06OlNMQTsKdXNlIEtlcm5lbDo6U3lzdGVtOjpWYWxpZDsKdXNlIEtlcm5lbDo6U3lzdGVtOjpDU1Y7CnVzZSBLZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kOjpTTEE7CnVzZSBLZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kOjpTZXJ2aWNlOwp1c2UgS2VybmVsOjpTeXN0ZW06OkltcG9ydEV4cG9ydDo6T2JqZWN0QmFja2VuZDo6U2VydmljZTJDdXN0b21lclVzZXI7Cgp1c2UgdmFycyBxdyhASVNBICRWRVJTSU9OKTsKJFZFUlNJT04gPSBxdygkUmV2aXNpb246IDEuMTQgJCkgWzFdOwoKPWhlYWQxIE5BTUUKCk9UUlNfQ2lDUy5wbSAtIGNvZGUgdG8gZXhjZWN1dGUgZHVyaW5nIHBhY2thZ2UgaW5zdGFsbGF0aW9uCgo9aGVhZDEgU1lOT1BTSVMKCkFsbCBmdW5jdGlvbnMKCj1oZWFkMSBQVUJMSUMgSU5URVJGQUNFCgo9b3ZlciA0Cgo9Y3V0Cgo9aXRlbSBuZXcoKQoKY3JlYXRlIGFuIG9iamVjdAoKICAgIHVzZSBLZXJuZWw6OkNvbmZpZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6TG9nOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpNYWluOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpUaW1lOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpEQjsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6WE1MOwoKICAgIG15ICRDb25maWdPYmplY3QgPSBLZXJuZWw6OkNvbmZpZy0+bmV3KCk7CiAgICBteSAkTG9nT2JqZWN0ICAgID0gS2VybmVsOjpTeXN0ZW06OkxvZy0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgKTsKICAgIG15ICRNYWluT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06Ok1haW4tPm5ldygKICAgICAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgICAgICBMb2dPYmplY3QgICAgPT4gJExvZ09iamVjdCwKICAgICk7CiAgICBteSAkVGltZU9iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpUaW1lLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICApOwogICAgbXkgJERCT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkRCLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICAgICAgTWFpbk9iamVjdCAgID0+ICRNYWluT2JqZWN0LAogICAgKTsKICAgIG15ICRYTUxPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6WE1MLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICAgICAgREJPYmplY3QgICAgID0+ICREQk9iamVjdCwKICAgICAgICBNYWluT2JqZWN0ICAgPT4gJE1haW5PYmplY3QsCiAgICApOwogICAgbXkgJENvZGVPYmplY3QgPSB2YXI6OnBhY2thZ2VzZXR1cDo6T1RSUy1DaUNTLUlUU00ucG0tPm5ldygKICAgICAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgICAgICBMb2dPYmplY3QgICAgPT4gJExvZ09iamVjdCwKICAgICAgICBNYWluT2JqZWN0ICAgPT4gJE1haW5PYmplY3QsCiAgICAgICAgVGltZU9iamVjdCAgID0+ICRUaW1lT2JqZWN0LAogICAgICAgIERCT2JqZWN0ICAgICA9PiAkREJPYmplY3QsCiAgICAgICAgWE1MT2JqZWN0ICAgID0+ICRYTUxPYmplY3QsCiAgICApOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgI2NoZWNrIHJlcXVpcmVkIHBhcmFtcy4uLgogICAgZm9yIG15ICRPYmplY3QgKAogICAgICAgIHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QgTWFpbk9iamVjdCBUaW1lT2JqZWN0IERCT2JqZWN0IEVuY29kZU9iamVjdCBYTUxPYmplY3QpCiAgICAgICAgKQogICAgewogICAgICAgICRTZWxmLT57JE9iamVjdH0gPSAkUGFyYW17JE9iamVjdH0gfHwgZGllICJHb3Qgbm8gJE9iamVjdCEiOwogICAgfQoKICAgICRTZWxmLT57Q29uZmlnSXRlbU9iamVjdH0gICA9IEtlcm5lbDo6U3lzdGVtOjpTeXNDb25maWctPm5ldyggJXskU2VsZn0gKTsKICAgICRTZWxmLT57Q29uZmlnT2JqZWN0fSAgICAgICA9IEtlcm5lbDo6Q29uZmlnLT5uZXcoKTsKICAgICRTZWxmLT57TG9nT2JqZWN0fSAgICAgICAgICA9IEtlcm5lbDo6U3lzdGVtOjpMb2ctPm5ldyggJXskU2VsZn0gKTsKICAgICRTZWxmLT57TWFpbk9iamVjdH0gICAgICAgICA9IEtlcm5lbDo6U3lzdGVtOjpNYWluLT5uZXcoICV7JFNlbGZ9ICk7CiAgICAkU2VsZi0+e0VuY29kZU9iamVjdH0gICAgICAgPSBLZXJuZWw6OlN5c3RlbTo6RW5jb2RlLT5uZXcoICV7JFNlbGZ9ICk7CiAgICAkU2VsZi0+e0RCT2JqZWN0fSAgICAgICAgICAgPSBLZXJuZWw6OlN5c3RlbTo6REItPm5ldyggJXskU2VsZn0gKTsKICAgICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fSA9IEtlcm5lbDo6U3lzdGVtOjpJbXBvcnRFeHBvcnQtPm5ldyggJXskU2VsZn0gKTsKICAgICRTZWxmLT57VmFsaWRPYmplY3R9ICAgICAgICA9IEtlcm5lbDo6U3lzdGVtOjpWYWxpZC0+bmV3KCAleyRTZWxmfSApOwogICAgJFNlbGYtPntPYmplY3RCYWNrZW5kT2JqZWN0fSA9CiAgICAgICAgS2VybmVsOjpTeXN0ZW06OkltcG9ydEV4cG9ydDo6T2JqZWN0QmFja2VuZDo6U0xBLT5uZXcoICV7JFNlbGZ9ICk7CiAgICAkU2VsZi0+e09iamVjdEJhY2tlbmRPYmplY3R9ID0KICAgICAgICBLZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kOjpTZXJ2aWNlLT5uZXcoICV7JFNlbGZ9ICk7CiAgICAkU2VsZi0+e09iamVjdEJhY2tlbmRPYmplY3R9ID0KICAgICAgICBLZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kOjpTZXJ2aWNlMkN1c3RvbWVyVXNlci0+bmV3KCAleyRTZWxmfSApOwoKICAgIHJldHVybiAkU2VsZjsKfQoKPWl0ZW0gQ29kZUluc3RhbGwoKQoKcnVuIHRoZSBjb2RlIGluc3RhbGwgcGFydAoKICAgIG15ICRSZXN1bHQgPSAkQ29kZU9iamVjdC0+Q29kZUluc3RhbGwoKTsKCj1jdXQKCnN1YiBDb2RlSW5zdGFsbCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICRTZWxmLT5fQ3JlYXRlTWFwcGluZ3MoKTsKCiAgICByZXR1cm4gMTsKfQoKPWl0ZW0gQ29kZVJlaW5zdGFsbCgpCgpydW4gdGhlIGNvZGUgcmVpbnN0YWxsIHBhcnQKCiAgICBteSAkUmVzdWx0ID0gJENvZGVPYmplY3QtPkNvZGVSZWluc3RhbGwoKTsKCj1jdXQKCnN1YiBDb2RlUmVpbnN0YWxsIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgJFNlbGYtPl9DcmVhdGVNYXBwaW5ncygpOwoKICAgIHJldHVybiAxOwp9Cgo9aXRlbSBDb2RlVXBncmFkZSgpCgpydW4gdGhlIGNvZGUgdXBncmFkZSBwYXJ0CgogICAgbXkgJFJlc3VsdCA9ICRDb2RlT2JqZWN0LT5Db2RlVXBncmFkZSgpOwoKPWN1dAoKc3ViIENvZGVVcGdyYWRlIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIENvZGVVbmluc3RhbGwoKQoKcnVuIHRoZSBjb2RlIHVuaW5zdGFsbCBwYXJ0CgogICAgbXkgJFJlc3VsdCA9ICRDb2RlT2JqZWN0LT5Db2RlVW5pbnN0YWxsKCk7Cgo9Y3V0CgpzdWIgQ29kZVVuaW5zdGFsbCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICRTZWxmLT5fUmVtb3ZlUmVsYXRlZE1hcHBpbmdzKCk7CgogICAgcmV0dXJuIDE7Cn0KCnN1YiBfUmVtb3ZlUmVsYXRlZE1hcHBpbmdzICgpIHsKCiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRUZW1wbGF0ZUxpc3Q7CiAgICBteSBAVGVtcGxhdGVPYmplY3RzID0gKCAnU2VydmljZScsICdTTEEnLCAnU2VydmljZTJDdXN0b21lclVzZXInICk7CiAgICBteSBAVGVtcGxhdGVPYmplY3RzU3VtOwogICAgZm9yZWFjaCBteSAkVGVtcGxhdGVPYmplY3QgKEBUZW1wbGF0ZU9iamVjdHMpIHsKICAgICAgICAkVGVtcGxhdGVMaXN0ID0gJFNlbGYtPntJbXBvcnRFeHBvcnRPYmplY3R9LT5UZW1wbGF0ZUxpc3QoCiAgICAgICAgICAgIE9iamVjdCA9PiAkVGVtcGxhdGVPYmplY3QsCiAgICAgICAgICAgIEZvcm1hdCA9PiAnQ1NWJywKICAgICAgICAgICAgVXNlcklEID0+IDEsCiAgICAgICAgKTsKICAgICAgICBAVGVtcGxhdGVPYmplY3RzU3VtID0gKCBAVGVtcGxhdGVPYmplY3RzU3VtLCBAeyRUZW1wbGF0ZUxpc3R9ICk7CiAgICB9CgogICAgIyBkZWxldGUgdGhlIHRlbXBsYXRlcwogICAgaWYgKCByZWYoJFRlbXBsYXRlTGlzdCkgZXEgJ0FSUkFZJyAmJiBAeyRUZW1wbGF0ZUxpc3R9ICkgewogICAgICAgICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fS0+VGVtcGxhdGVEZWxldGUoCiAgICAgICAgICAgIFRlbXBsYXRlSUQgPT4gXEBUZW1wbGF0ZU9iamVjdHNTdW0sCiAgICAgICAgICAgIFVzZXJJRCAgICAgPT4gMSwKICAgICAgICApOwogICAgfQoKICAgIHJldHVybiAxOwp9CgpzdWIgX0NyZWF0ZU1hcHBpbmdzICgpIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgbXkgJEltcG9ydEV4cG9ydE1hcHBpbmdIYXNoID0gdW5kZWY7CgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBTTEEgLi4uCiAgICBteSAlU0xBUHJlZmVyZW5jZXMgICAgID0gKCk7CiAgICBteSAlU0xBTWFwcGluZ1ByZWZzICAgID0gKCk7CiAgICBteSBAU0xBUHJlZmVyZW5jZXNLZXlzID0gcXd7fTsKICAgIG15IEBNYXBwaW5nS2V5c1NMQSAgICAgPSAoCiAgICAgICAgJ05hbWUnLCAgICAgICAgICAgICAgJ0NhbGVuZGFyJywKICAgICAgICAnVmFsaWQnLCAgICAgICAgICAgICAnQ29tbWVudCcsCiAgICAgICAgJ0ZpcnN0UmVzcG9uc2VUaW1lJywgJ0ZpcnN0UmVzcG9uc2VOb3RpZnknLAogICAgICAgICdVcGRhdGVUaW1lJywgICAgICAgICdVcGRhdGVOb3RpZnknLAogICAgICAgICdTb2x1dGlvblRpbWUnLCAgICAgICdTb2x1dGlvbk5vdGlmeScsCiAgICAgICAgJ1R5cGUnLCAgICAgICAgICAgICAgJ01pblRpbWVCZXR3ZWVuSW5jaWRlbnRzJwogICAgKTsKCiAgICBpZiAoICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdTTEFQcmVmZXJlbmNlcycpICkgewogICAgICAgICVTTEFQcmVmZXJlbmNlcyA9ICV7ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdTTEFQcmVmZXJlbmNlcycpIH07CiAgICB9CiAgICBmb3IgbXkgJEl0ZW0gKCBzb3J0IGtleXMgJVNMQVByZWZlcmVuY2VzICkgewogICAgICAgIGlmICgKICAgICAgICAgICAgJFNMQVByZWZlcmVuY2VzeyRJdGVtfS0+e1NlbGVjdGlvblNvdXJjZX0KICAgICAgICAgICAgJiYgJFNMQVByZWZlcmVuY2VzeyRJdGVtfS0+e1ByZWZLZXl9ID1+IC9eKC4rKUlEJC8KICAgICAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgbXkgJE5hbWVQYXJ0ID0gJDE7CiAgICAgICAgICAgICRTTEFNYXBwaW5nUHJlZnN7JE5hbWVQYXJ0fSA9IDE7CiAgICAgICAgfQogICAgICAgICRTTEFNYXBwaW5nUHJlZnN7ICRTTEFQcmVmZXJlbmNlc3skSXRlbX0tPntQcmVmS2V5fSB9ID0gMTsKICAgIH0KCiAgICBpZiAoIGtleXMoJVNMQU1hcHBpbmdQcmVmcykgKSB7CiAgICAgICAgQE1hcHBpbmdLZXlzU0xBID0gKCBATWFwcGluZ0tleXNTTEEsIGtleXMoJVNMQU1hcHBpbmdQcmVmcykgKTsKICAgIH0KCiAgICBwdXNoKCBATWFwcGluZ0tleXNTTEEsICdBc3NpZ25lZFNlcnZpY2UnICk7CgogICAgJEltcG9ydEV4cG9ydE1hcHBpbmdIYXNoLT57U0xBfSA9IFxATWFwcGluZ0tleXNTTEE7CgogICAgIy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgIyBTZXJ2aWNlIC4uLgogICAgbXkgJVNlcnZpY2VQcmVmZXJlbmNlcyAgICAgPSAoKTsKICAgIG15ICVTZXJ2aWNlTWFwcGluZ1ByZWZzICAgID0gKCk7CiAgICBteSBAU2VydmljZVByZWZlcmVuY2VzS2V5cyA9IHF3e307CiAgICBteSBATWFwcGluZ0tleXNTZXJ2aWNlICAgICA9ICgKICAgICAgICAnU2VydmljZUlEJywgJ05hbWUnLCAnTmFtZVNob3J0JywgICAnVmFsaWQnLAogICAgICAgICdDb21tZW50JywgICAnVHlwZScsICdDcml0aWNhbGl0eScsICdDdXJJbmNpU3RhdGUnCiAgICApOwoKICAgIGlmICggJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ1NlcnZpY2VQcmVmZXJlbmNlcycpICkgewogICAgICAgICVTZXJ2aWNlUHJlZmVyZW5jZXMgPSAleyAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnU2VydmljZVByZWZlcmVuY2VzJykgfTsKICAgIH0KICAgIGZvciBteSAkSXRlbSAoIHNvcnQga2V5cyAlU2VydmljZVByZWZlcmVuY2VzICkgewogICAgICAgIGlmICgKICAgICAgICAgICAgJFNlcnZpY2VQcmVmZXJlbmNlc3skSXRlbX0tPntTZWxlY3Rpb25Tb3VyY2V9CiAgICAgICAgICAgICYmICRTZXJ2aWNlUHJlZmVyZW5jZXN7JEl0ZW19LT57UHJlZktleX0gPX4gL14oLispSUQkLwogICAgICAgICAgICApCiAgICAgICAgewogICAgICAgICAgICBteSAkTmFtZVBhcnQgPSAkMTsKICAgICAgICAgICAgJFNlcnZpY2VNYXBwaW5nUHJlZnN7JE5hbWVQYXJ0fSA9IDE7CiAgICAgICAgfQogICAgICAgICRTZXJ2aWNlTWFwcGluZ1ByZWZzeyAkU2VydmljZVByZWZlcmVuY2VzeyRJdGVtfS0+e1ByZWZLZXl9IH0gPSAxOwogICAgfQoKICAgIGlmICgga2V5cyglU2VydmljZU1hcHBpbmdQcmVmcykgKSB7CiAgICAgICAgQE1hcHBpbmdLZXlzU2VydmljZSA9ICggQE1hcHBpbmdLZXlzU2VydmljZSwga2V5cyglU2VydmljZU1hcHBpbmdQcmVmcykgKTsKICAgIH0KCiAgICAkSW1wb3J0RXhwb3J0TWFwcGluZ0hhc2gtPntTZXJ2aWNlfSA9IFxATWFwcGluZ0tleXNTZXJ2aWNlOwoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgU2VydmljZTJDdXN0b21lclVzZXIgLi4uCiAgICAkSW1wb3J0RXhwb3J0TWFwcGluZ0hhc2gtPntTZXJ2aWNlMkN1c3RvbWVyVXNlcn0gPQogICAgICAgIFsgJ0N1c3RvbWVyVXNlckxvZ2luJywgJ1NlcnZpY2VOYW1lJywgJ1NlcnZpY2VJRCcsICdBc3NpZ25tZW50QWN0aXZlJyBdOwoKICAgICMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICMgY3JlYXRlIG1hcHBpbmdzLi4uCiAgICBmb3IgbXkgJE9iamVjdE1hcHBpbmdLZXkgKCBrZXlzICV7JEltcG9ydEV4cG9ydE1hcHBpbmdIYXNofSApIHsKCiAgICAgICAgIyBhZGQgYSB0ZW1wbGF0ZSBjdXN0b21lciBjb21wYW55CiAgICAgICAgbXkgJFRlbXBsYXRlSUQgPSAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPlRlbXBsYXRlQWRkKAogICAgICAgICAgICBPYmplY3QgID0+ICRPYmplY3RNYXBwaW5nS2V5LAogICAgICAgICAgICBGb3JtYXQgID0+ICdDU1YnLAogICAgICAgICAgICBOYW1lICAgID0+ICRPYmplY3RNYXBwaW5nS2V5IC4gJyAoYXV0by1jcmVhdGVkIG1hcCknLAogICAgICAgICAgICBDb21tZW50ID0+ICdBdXRvbWF0aWNhbGx5IGNyZWF0ZWQgZHVyaW5nIFNlcnZpY2VJbXBvcnRFeHBvcnQgaW5zdGFsbGF0aW9uJywKICAgICAgICAgICAgVmFsaWRJRCA9PiAxLAogICAgICAgICAgICBVc2VySUQgID0+IDEsCiAgICAgICAgKTsKICAgICAgICBpZiAoICEkVGVtcGxhdGVJRCApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSAgPT4gIkNvdWxkIG5vdCBhZGQgbWFwcGluZyBmb3Igb2JqZWN0ICRPYmplY3RNYXBwaW5nS2V5IiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgbmV4dDsKICAgICAgICB9CgogICAgICAgIG15ICRTZXJ2aWNlTWFwcGluZ0RhdGEgPSB7CiAgICAgICAgICAgIFNvdXJjZVNlcnZpY2VEYXRhID0+IHsKICAgICAgICAgICAgICAgIEZvcm1hdERhdGEgPT4gewogICAgICAgICAgICAgICAgICAgIENvbHVtblNlcGFyYXRvciA9PiAnU2VtaWNvbG9uJywKICAgICAgICAgICAgICAgICAgICBDaGFyc2V0ICAgICAgICAgPT4gJ1VURi04JywKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICBTZXJ2aWNlRGF0YUdldCA9PiB7CiAgICAgICAgICAgICAgICAgICAgVGVtcGxhdGVJRCA9PiAkVGVtcGxhdGVJRCwKICAgICAgICAgICAgICAgICAgICBVc2VySUQgICAgID0+IDEsCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICB9LAogICAgICAgIH07CgogICAgICAgICMgZ2V0IG9iamVjdCBhdHRyaWJ1dGVzCiAgICAgICAgbXkgJE9iamVjdEF0dHJpYnV0ZUxpc3QgPSAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPk9iamVjdEF0dHJpYnV0ZXNHZXQoCiAgICAgICAgICAgIFRlbXBsYXRlSUQgPT4gJFNlcnZpY2VNYXBwaW5nRGF0YS0+e1NvdXJjZVNlcnZpY2VEYXRhfS0+e1NlcnZpY2VEYXRhR2V0fQogICAgICAgICAgICAgICAgLT57VGVtcGxhdGVJRH0sCiAgICAgICAgICAgIFVzZXJJRCA9PiAxLAogICAgICAgICk7CgogICAgICAgIG15ICRBdHRyaWJ1dGVWYWx1ZXM7CgogICAgICAgIGZvciBteSAkRGVmYXVsdCAoIEB7JE9iamVjdEF0dHJpYnV0ZUxpc3R9ICkgewoKICAgICAgICAgICAgIyBzZXQgc2xhIHR5cGVzCiAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICRPYmplY3RNYXBwaW5nS2V5ICBlcSAnU0xBJwogICAgICAgICAgICAgICAgJiYgJERlZmF1bHQtPntLZXl9IGVxICdEZWZhdWx0U0xBVHlwZUlEJwogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoICRTZWxmLT57TWFpbk9iamVjdH0tPlJlcXVpcmUoJ0tlcm5lbDo6U3lzdGVtOjpHZW5lcmFsQ2F0YWxvZycpICkgewogICAgICAgICAgICAgICAgICAgICRTZWxmLT57R2VuZXJhbENhdGFsb2dPYmplY3R9ID0gS2VybmVsOjpTeXN0ZW06OkdlbmVyYWxDYXRhbG9nLT5uZXcoICV7JFNlbGZ9ICk7CgogICAgICAgICAgICAgICAgICAgIGlmICggJFNlbGYtPntHZW5lcmFsQ2F0YWxvZ09iamVjdH0gKSB7CgogICAgICAgICAgICAgICAgICAgICAgICAjIGdldCBTTEEgdHlwZSBsaXN0CiAgICAgICAgICAgICAgICAgICAgICAgICRTZWxmLT57U0xBVHlwZUxpc3R9ID0gJFNlbGYtPntHZW5lcmFsQ2F0YWxvZ09iamVjdH0tPkl0ZW1MaXN0KAogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgPT4gJ0lUU006OlNMQTo6VHlwZScsCiAgICAgICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoICRTZWxmLT57U0xBVHlwZUxpc3R9ICYmIHJlZiggJFNlbGYtPntTTEFUeXBlTGlzdH0gKSBlcSAnSEFTSCcgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBteSAlVG1wSGFzaCA9IHJldmVyc2UoICV7ICRTZWxmLT57U0xBVHlwZUxpc3R9IH0gKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRTZWxmLT57UmV2ZXJzZVNMQVR5cGVMaXN0fSA9IFwlVG1wSGFzaDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG15ICRTTEFUeXBlSUQ7CiAgICAgICAgICAgICAgICBmb3IgbXkgJElEICgga2V5cyAleyAkU2VsZi0+e1NMQVR5cGVMaXN0fSB9ICkgewogICAgICAgICAgICAgICAgICAgICRTTEFUeXBlSUQgPSAkU2VsZi0+e1NMQVR5cGVMaXN0fS0+eyRJRH07CiAgICAgICAgICAgICAgICAgICAgaWYgKCAkU2VsZi0+e1NMQVR5cGVMaXN0fS0+eyRJRH0gZXEgJ090aGVyJyApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJFNMQVR5cGVJRCA9ICRJRDsKICAgICAgICAgICAgICAgICAgICAgICAgbGFzdDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgJEF0dHJpYnV0ZVZhbHVlcy0+eyAkRGVmYXVsdC0+e0tleX0gfSA9ICRTTEFUeXBlSUQ7CiAgICAgICAgICAgICAgICBuZXh0OwogICAgICAgICAgICB9CgogICAgICAgICAgICAjIHNldCBzZXJ2aWNlIHR5cGVzCiAgICAgICAgICAgIGlmICggJE9iamVjdE1hcHBpbmdLZXkgZXEgJ1NlcnZpY2UnICkgewogICAgICAgICAgICAgICAgbXkgJENyaXRpY2FsaXR5SUQ7CiAgICAgICAgICAgICAgICBteSAkU2VydmljZVR5cGVJRDsKICAgICAgICAgICAgICAgIGlmICggJFNlbGYtPntHZW5lcmFsQ2F0YWxvZ09iamVjdH0gKSB7CgogICAgICAgICAgICAgICAgICAgICMgZ2V0IHNlcnZpY2UgdHlwZSBsaXN0CiAgICAgICAgICAgICAgICAgICAgJFNlbGYtPntTZXJ2aWNlVHlwZUxpc3R9ID0gJFNlbGYtPntHZW5lcmFsQ2F0YWxvZ09iamVjdH0tPkl0ZW1MaXN0KAogICAgICAgICAgICAgICAgICAgICAgICBDbGFzcyA9PiAnSVRTTTo6U2VydmljZTo6VHlwZScsCiAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCAkU2VsZi0+e1NlcnZpY2VUeXBlTGlzdH0gJiYgKCByZWYoICRTZWxmLT57U2VydmljZVR5cGVMaXN0fSApIGVxICdIQVNIJyApICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG15ICVUbXBIYXNoID0gcmV2ZXJzZSggJXsgJFNlbGYtPntTZXJ2aWNlVHlwZUxpc3R9IH0gKTsKICAgICAgICAgICAgICAgICAgICAgICAgJFNlbGYtPntSZXZlcnNlU2VydmljZVR5cGVMaXN0fSA9IFwlVG1wSGFzaDsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICMgZ2V0IGNyaXRpY2FsaXR5IGxpc3QKICAgICAgICAgICAgICAgICAgICAkU2VsZi0+e0NyaXRpY2FsaXR5TGlzdH0gPSAkU2VsZi0+e0dlbmVyYWxDYXRhbG9nT2JqZWN0fS0+SXRlbUxpc3QoCiAgICAgICAgICAgICAgICAgICAgICAgIENsYXNzID0+ICdJVFNNOjpDb3JlOjpDcml0aWNhbGl0eScsCiAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCAkU2VsZi0+e0NyaXRpY2FsaXR5TGlzdH0gJiYgKCByZWYoICRTZWxmLT57Q3JpdGljYWxpdHlMaXN0fSApIGVxICdIQVNIJyApICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIG15ICVUbXBIYXNoMiA9IHJldmVyc2UoICV7ICRTZWxmLT57Q3JpdGljYWxpdHlMaXN0fSB9ICk7CiAgICAgICAgICAgICAgICAgICAgICAgICRTZWxmLT57UmV2ZXJzZUNyaXRpY2FsaXR5TGlzdH0gPSBcJVRtcEhhc2gyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBpZiAoICREZWZhdWx0LT57S2V5fSBlcSAnRGVmYXVsdENyaXRpY2FsaXR5SUQnICkgewogICAgICAgICAgICAgICAgICAgIGZvciBteSAkSUQgKCBrZXlzICV7ICRTZWxmLT57Q3JpdGljYWxpdHlMaXN0fSB9ICkgewoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAkU2VsZi0+e0NyaXRpY2FsaXR5TGlzdH0tPnskSUR9ID1+IC9ub3JtYWwvICkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJENyaXRpY2FsaXR5SUQgPSAkSUQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXN0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAkQXR0cmlidXRlVmFsdWVzLT57ICREZWZhdWx0LT57S2V5fSB9ID0gJENyaXRpY2FsaXR5SUQ7CiAgICAgICAgICAgICAgICAgICAgbmV4dDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICggJERlZmF1bHQtPntLZXl9IGVxICdEZWZhdWx0U2VydmljZVR5cGVJRCcgKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIG15ICRJRCAoIGtleXMgJXsgJFNlbGYtPntTZXJ2aWNlVHlwZUxpc3R9IH0gKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRTZXJ2aWNlVHlwZUlEID0gJFNlbGYtPntTZXJ2aWNlVHlwZUxpc3R9LT57JElEfTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAkU2VsZi0+e1NlcnZpY2VUeXBlTGlzdH0tPnskSUR9IGVxICdPdGhlcicgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkU2VydmljZVR5cGVJRCA9ICRJRDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3Q7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICRBdHRyaWJ1dGVWYWx1ZXMtPnsgJERlZmF1bHQtPntLZXl9IH0gPSAkU2VydmljZVR5cGVJRDsKICAgICAgICAgICAgICAgICAgICBuZXh0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRBdHRyaWJ1dGVWYWx1ZXMtPnsgJERlZmF1bHQtPntLZXl9IH0gPSAkRGVmYXVsdC0+e0lucHV0fS0+e1ZhbHVlRGVmYXVsdH07CiAgICAgICAgfQoKICAgICAgICAkU2VydmljZU1hcHBpbmdEYXRhLT57U291cmNlU2VydmljZURhdGF9LT57T2JqZWN0RGF0YX0gPSAkQXR0cmlidXRlVmFsdWVzOwoKICAgICAgICBteSAkRGVmYXVsdE51bWJlck9mQXNzaWduYWJsZVNlcnZpY2VzID0KICAgICAgICAgICAgJFNlcnZpY2VNYXBwaW5nRGF0YS0+e1NvdXJjZVNlcnZpY2VEYXRhfS0+e09iamVjdERhdGF9CiAgICAgICAgICAgIC0+e051bWJlck9mQXNzaWduYWJsZVNlcnZpY2VzfTsKCiAgICAgICAgbXkgJGkgPSAwOwogICAgICAgIG15IEBNYXBwaW5nT2JqRGF0YTsKICAgICAgICBmb3IgbXkgJEtleSAoIEB7ICRJbXBvcnRFeHBvcnRNYXBwaW5nSGFzaC0+eyRPYmplY3RNYXBwaW5nS2V5fSB9ICkgewoKICAgICAgICAgICAgbXkgJU1hcHBpbmdPYmplY3REYXRhSGFzaDsKICAgICAgICAgICAgJE1hcHBpbmdPYmplY3REYXRhSGFzaHtLZXl9ID0KICAgICAgICAgICAgICAgICRJbXBvcnRFeHBvcnRNYXBwaW5nSGFzaC0+eyRPYmplY3RNYXBwaW5nS2V5fS0+WyRpXTsKICAgICAgICAgICAgaWYgKCAkaSA9PSAwICkgewogICAgICAgICAgICAgICAgJE1hcHBpbmdPYmplY3REYXRhSGFzaHtJZGVudGlmaWVyfSA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCAkS2V5IGVxICdWYWxpZCcgJiYgISRBdHRyaWJ1dGVWYWx1ZXMtPntEZWZhdWx0VmFsaWR9ICkgewogICAgICAgICAgICAgICAgbmV4dDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKCAkS2V5IGVxICdBc3NpZ25lZFNlcnZpY2UnICkgewogICAgICAgICAgICAgICAgZm9yICgKICAgICAgICAgICAgICAgICAgICBteSAkQ291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICRDb3VudCA8ICREZWZhdWx0TnVtYmVyT2ZBc3NpZ25hYmxlU2VydmljZXM7CiAgICAgICAgICAgICAgICAgICAgJENvdW50KysKICAgICAgICAgICAgICAgICAgICApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgbXkgJU1hcHBpbmdPYmplY3REYXRhSGFzaExvY2FsID0gKCk7CiAgICAgICAgICAgICAgICAgICAgJE1hcHBpbmdPYmplY3REYXRhSGFzaExvY2Fse0tleX0gPQogICAgICAgICAgICAgICAgICAgICAgICAnQXNzaWduZWRTZXJ2aWNlJyAuIHNwcmludGYoICclMDNzJywgJENvdW50ICk7CiAgICAgICAgICAgICAgICAgICAgcHVzaCggQE1hcHBpbmdPYmpEYXRhLCBcJU1hcHBpbmdPYmplY3REYXRhSGFzaExvY2FsICk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBwdXNoKCBATWFwcGluZ09iakRhdGEsIFwlTWFwcGluZ09iamVjdERhdGFIYXNoICk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICRpKys7CiAgICAgICAgfQoKICAgICAgICAkU2VydmljZU1hcHBpbmdEYXRhLT57U291cmNlU2VydmljZURhdGF9LT57TWFwcGluZ09iamVjdERhdGF9ID0KICAgICAgICAgICAgXEBNYXBwaW5nT2JqRGF0YTsKCiAgICAgICAgaWYgKAogICAgICAgICAgICAhJFNlcnZpY2VNYXBwaW5nRGF0YQogICAgICAgICAgICB8fCByZWYgJFNlcnZpY2VNYXBwaW5nRGF0YSBuZSAnSEFTSCcKICAgICAgICAgICAgKQogICAgICAgIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICAgICAgTWVzc2FnZSA9PgogICAgICAgICAgICAgICAgICAgICJObyB2YWxpZCBtYXBwaW5nIGxpc3QgZm91bmQgZm9yIHRlbXBsYXRlIGlkICRUZW1wbGF0ZUlEIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgIyBzZXQgdGhlIG9iamVjdCBkYXRhCiAgICAgICAgaWYgKAogICAgICAgICAgICAkU2VydmljZU1hcHBpbmdEYXRhLT57U291cmNlU2VydmljZURhdGF9LT57T2JqZWN0RGF0YX0KICAgICAgICAgICAgJiYgcmVmICRTZXJ2aWNlTWFwcGluZ0RhdGEtPntTb3VyY2VTZXJ2aWNlRGF0YX0tPntPYmplY3REYXRhfSBlcSAnSEFTSCcKICAgICAgICAgICAgJiYgJFNlcnZpY2VNYXBwaW5nRGF0YS0+e1NvdXJjZVNlcnZpY2VEYXRhfS0+e1NlcnZpY2VEYXRhR2V0fQogICAgICAgICAgICAtPntUZW1wbGF0ZUlEfQogICAgICAgICAgICApCiAgICAgICAgewoKICAgICAgICAgICAgIyBzYXZlIG9iamVjdCBkYXRhCiAgICAgICAgICAgICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fS0+T2JqZWN0RGF0YVNhdmUoCiAgICAgICAgICAgICAgICBUZW1wbGF0ZUlEID0+CiAgICAgICAgICAgICAgICAgICAgJFNlcnZpY2VNYXBwaW5nRGF0YS0+e1NvdXJjZVNlcnZpY2VEYXRhfS0+e1NlcnZpY2VEYXRhR2V0fQogICAgICAgICAgICAgICAgICAgIC0+e1RlbXBsYXRlSUR9LAogICAgICAgICAgICAgICAgT2JqZWN0RGF0YSA9PgogICAgICAgICAgICAgICAgICAgICRTZXJ2aWNlTWFwcGluZ0RhdGEtPntTb3VyY2VTZXJ2aWNlRGF0YX0tPntPYmplY3REYXRhfSwKICAgICAgICAgICAgICAgIFVzZXJJRCA9PiAxLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgIyBzZXQgdGhlIGZvcm1hdCBkYXRhCiAgICAgICAgaWYgKAogICAgICAgICAgICAkU2VydmljZU1hcHBpbmdEYXRhLT57U291cmNlU2VydmljZURhdGF9LT57Rm9ybWF0RGF0YX0KICAgICAgICAgICAgJiYgcmVmICRTZXJ2aWNlTWFwcGluZ0RhdGEtPntTb3VyY2VTZXJ2aWNlRGF0YX0tPntGb3JtYXREYXRhfSBlcSAnSEFTSCcKICAgICAgICAgICAgJiYgJFNlcnZpY2VNYXBwaW5nRGF0YS0+e1NvdXJjZVNlcnZpY2VEYXRhfS0+e1NlcnZpY2VEYXRhR2V0fQogICAgICAgICAgICAtPntUZW1wbGF0ZUlEfQogICAgICAgICAgICApCiAgICAgICAgewoKICAgICAgICAgICAgIyBzYXZlIGZvcm1hdCBkYXRhCiAgICAgICAgICAgICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fS0+Rm9ybWF0RGF0YVNhdmUoCiAgICAgICAgICAgICAgICBUZW1wbGF0ZUlEID0+CiAgICAgICAgICAgICAgICAgICAgJFNlcnZpY2VNYXBwaW5nRGF0YS0+e1NvdXJjZVNlcnZpY2VEYXRhfS0+e1NlcnZpY2VEYXRhR2V0fQogICAgICAgICAgICAgICAgICAgIC0+e1RlbXBsYXRlSUR9LAogICAgICAgICAgICAgICAgRm9ybWF0RGF0YSA9PgogICAgICAgICAgICAgICAgICAgICRTZXJ2aWNlTWFwcGluZ0RhdGEtPntTb3VyY2VTZXJ2aWNlRGF0YX0tPntGb3JtYXREYXRhfSwKICAgICAgICAgICAgICAgIFVzZXJJRCA9PiAxLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgIyBzZXQgdGhlIG1hcHBpbmcgb2JqZWN0IGRhdGEKICAgICAgICBpZiAoCiAgICAgICAgICAgICRTZXJ2aWNlTWFwcGluZ0RhdGEtPntTb3VyY2VTZXJ2aWNlRGF0YX0tPntPYmplY3REYXRhfQoKICAgICAgICAgICAgIyYmIHJlZiAkU2VydmljZU1hcHBpbmdEYXRhLT57TWFwcGluZ09iamVjdERhdGF9IGVxICdBUlJBWScKICAgICAgICAgICAgJiYgJFNlcnZpY2VNYXBwaW5nRGF0YS0+e1NvdXJjZVNlcnZpY2VEYXRhfS0+e1NlcnZpY2VEYXRhR2V0fQogICAgICAgICAgICAtPntUZW1wbGF0ZUlEfQogICAgICAgICAgICApCiAgICAgICAgewoKICAgICAgICAgICAgIyBkZWxldGUgYWxsIGV4aXN0aW5nIG1hcHBpbmcgZGF0YQogICAgICAgICAgICAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPk1hcHBpbmdEZWxldGUoCiAgICAgICAgICAgICAgICBUZW1wbGF0ZUlEID0+CiAgICAgICAgICAgICAgICAgICAgJFNlcnZpY2VNYXBwaW5nRGF0YS0+e1NvdXJjZVNlcnZpY2VEYXRhfS0+e1NlcnZpY2VEYXRhR2V0fQogICAgICAgICAgICAgICAgICAgIC0+e1RlbXBsYXRlSUR9LAogICAgICAgICAgICAgICAgVXNlcklEID0+IDEsCiAgICAgICAgICAgICk7CgogICAgICAgICAgICAjIGFkZCB0aGUgbWFwcGluZyBvYmplY3Qgcm93cwoKICAgICAgICAgICAgZm9yIG15ICRNYXBwaW5nT2JqZWN0RGF0YSAoCiAgICAgICAgICAgICAgICBAeyAkU2VydmljZU1hcHBpbmdEYXRhLT57U291cmNlU2VydmljZURhdGF9LT57TWFwcGluZ09iamVjdERhdGF9IH0KICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgICMgYWRkIGEgbmV3IG1hcHBpbmcgcm93CiAgICAgICAgICAgICAgICBteSAkTWFwcGluZ0lEID0gJFNlbGYtPntJbXBvcnRFeHBvcnRPYmplY3R9LT5NYXBwaW5nQWRkKAogICAgICAgICAgICAgICAgICAgIFRlbXBsYXRlSUQgPT4KICAgICAgICAgICAgICAgICAgICAgICAgJFNlcnZpY2VNYXBwaW5nRGF0YS0+e1NvdXJjZVNlcnZpY2VEYXRhfS0+e1NlcnZpY2VEYXRhR2V0fQogICAgICAgICAgICAgICAgICAgICAgICAtPntUZW1wbGF0ZUlEfSwKICAgICAgICAgICAgICAgICAgICBVc2VySUQgPT4gMSwKICAgICAgICAgICAgICAgICk7CgogICAgICAgICAgICAgICAgIyBhZGQgdGhlIG1hcHBpbmcgb2JqZWN0IGRhdGEKICAgICAgICAgICAgICAgICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fS0+TWFwcGluZ09iamVjdERhdGFTYXZlKAogICAgICAgICAgICAgICAgICAgIE1hcHBpbmdJRCAgICAgICAgID0+ICRNYXBwaW5nSUQsCiAgICAgICAgICAgICAgICAgICAgTWFwcGluZ09iamVjdERhdGEgPT4gJE1hcHBpbmdPYmplY3REYXRhLAogICAgICAgICAgICAgICAgICAgIFVzZXJJRCAgICAgICAgICAgID0+IDEsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAxOwp9CgoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBTb2Z0d2FyZSBpcyBwYXJ0IG9mIHRoZSBPVFJTIHByb2plY3QgKGh0dHA6Ly9vdHJzLm9yZy8pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTIuMC50eHQuCgo9Y3V0Cgo9aGVhZDEgVkVSU0lPTgokUmV2aXNpb246IDEuMTQgJCAkRGF0ZTogMjAxMS0xMS0yOSAxMDoyODo1NyAkCj1jdXQK
IyAtLQojIENIQU5HRVNfc2VydmljZWltcG9ydGV4cG9ydC0gY2hhbmdlIGxvZyBvZiBzZXJ2aWNlaW1wb3J0ZXhwb3J0CiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMTAgYy5hLnAuZS4gSVQgR21iSCwgaHR0cDovL3d3dy5jYXBlLWl0LmRlLwojCiMgLS0KIyAkSWQ6IENIQU5HRVNfc2VydmljZWltcG9ydGV4cG9ydCx2IDEuMzEgMjAxMS0xMS0yOSAxMDozMDo0MCB0dG8gRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwtMi4wLnR4dC4KIyAtLQojCiMtLS0tLS0tLS0tLS0tLS0tLS0tLSAxLjEuMCAoMjAxMS8/Py8/PykgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgKiArKysrKysrKysrKysrKysrKysrKysrKysrKysgVE8gRE8gKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCiMgKiAoMjAxMi8/Py8/PykgLSBDUjogdGhlIGJpZyBvcGVuIHRvIGRvOiB1bml0IHRlc3RzCiMgKiArKysrKysrKysrKysrKysrKysrKysrKysrKysgVE8gRE8gKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrCiMKIy0tLS0tLS0tLS0tLS0tLS0tLS0tIDEuMC40ICgyMDExLzEyLz8/KSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyAqICgyMDExLzEyLz8/KSAtIEJ1Z2ZpeDogKExPR0lOKQojICogKDIwMTEvMTIvPz8pIC0gQ1I6IChMT0dJTikKIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0gMS4wLjMgKDIwMTEvMTEvMjkpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojICogKDIwMTEvMTEvMjkpIC0gQ1I6IHNldCByZXF1aXJlZCBJbXBvcnRFeHBvcnQgdG8gdmVyc2lvbiAzLjAuMSAodHRvKQojICogKDIwMTEvMTEvMjkpIC0gQ1I6IHJlbW92ZWQgaHRtbC12ZXJzaW9uIG9mIHBvZCBkb2N1bWVudGF0aW9uICh0dG8pCiMgKiAoMjAxMS8xMS8yOSkgLSBDUjogYWRkZWQgY3VzdG9tIFNMQVByZWZlcmVuY2VzIHRvIFNMQSBpbXBvcnQgZXhwb3J0IG1hcHBpbmdzICh0dG8pCiMgKiAoMjAxMS8xMS8yOSkgLSBDUjogcmVtb3ZlZCAiZXhwb3J0IHdpdGggbGFiZWxzIiAobm93IGluY2x1ZGVkIGluIEltcG9ydEV4cG9ydC1mcmFtZXdvcmsgKHR0bykKIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0gMS4wLjIgKDIwMTEvMDQvMDcpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojICogKDIwMTEvMDcvMDQpIC0gQnVnZml4OiByZW1vdmVkIHVuY29tbWVudGF0aW9uIG9mIHNvbWUgY29kZSAodHRvKQojCiMtLS0tLS0tLS0tLS0tLS0tLS0tLSAxLjAuMSAoMjAxMS8wNC8wNykgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgKiAoMjAxMS8wNy8wNCkgLSBDUjogYWRkZWQgY3VzdG9tIFNlcnZpY2VQcmVmZXJlbmNlcyB0byBzZXJ2aWNlIGltcG9ydCBleHBvcnQgbWFwcGluZ3MgKHR0bykKIyAqICgyMDExLzAzLzIwKSAtIENSOiBtb3ZlZCB1c2FnZSBpbmZvcm1hdGlvbiB0byBwb2QtZmlsZSBpbiA8T1RSU19IT01FPi9kb2MvZW4KIyAqICgyMDExLzAzLzE5KSAtIEJ1Z2ZpeDogZml4ZWQgYnVnIGluc3RhbGxhdGlvbiBpZiBHZW5lcmFsQ2F0YWxvZyBpcyBpbnN0YWxsZWQgYnV0IG5vdCBJVFNNQ29yZQojCiMtLS0tLS0tLS0tLS0tLS0tLS0tLSAwLjEuMCAoMjAxMS8wMy8wOCkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgKiAoMjAxMS8wMy8wOCkgLSBDUjogZmlsZSBVU0FHRV9zZXJ2aWNlaW1wb3J0ZXhwb3J0IGZvciBkb2N1bWVudGF0aW9uIHB1cnBvc2UuCiMKIy0tLS0tLS0tLS0tLS0tLS0tLS0tIDAuNi4wICgyMDExLzAxLzIxKSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyAqICgyMDExLzAyLzA5KSAtIENSOiBhZGRlZCBzb21lIGVycm9yIGhhbmRsaW5ncyBpbiBwYWNrYWdlIHNldHVwIG1ldGhvZAojICogKDIwMTEvMDEvMjEpIC0gQ1I6IGNoYW5nZXMgZm9yIHVzZSB3aXRoIE9UUlMgMy4wLngKIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0gMC41LjggKDIwMTAvMDcvMzApIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojICogKDIwMTAvMDcvMzApIC0gQnVnZml4OiBmaXhlZCB1c2Ugb2YgdW5pbml0aWFsaXplZCB2YWx1ZSBpbiBjb21wYXJpc29uCiMKIy0tLS0tLS0tLS0tLS0tLS0tLS0tIDAuNS43ICgyMDEwLzA3LzMwKSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyAqICgyMDEwLzA3LzMwKSAtIEJ1Z2ZpeDogZml4ZWQgdXNlIG9mIHdyb25nIGhhc2gga2V5IGluIFNlcnZpY2UtQmFja2VuZAojCiMtLS0tLS0tLS0tLS0tLS0tLS0tLSAwLjUuNiAoMjAxMC8wNy8zMCkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgKiAoMjAxMC8wNy8zMCkgLSBCdWdmaXg6IGNvbHVtbiBzZXBhcmF0b3Igbm90IHNldCBjb3JyZWN0bHkKIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0gMC41LjUgKDIwMTAvMDQvMjcpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojICogKDIwMTAvMDQvMjcpIC0gQnVnZml4OiBhdXRvLWNyZWF0ZWQgbWFwcGluZyBmb3IgQXNzaWduZWRTZXJ2aWNlLgojCiMtLS0tLS0tLS0tLS0tLS0tLS0tLSAwLjUuNCAoMjAxMC8wNC8yMikgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMgKiAoMjAxMC8wNC8yMikgLSBCdWdmaXg6IG1pc3NpbmcgdmFyaWFibGUgZGVjbGFyYXRpb24uCiMKIy0tLS0tLS0tLS0tLS0tLS0tLS0tIDAuNS4zICgyMDEwLzA0LzIxKSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyAqICgyMDEwLzA0LzIxKSAtIEJ1Z2ZpeDogbWlzc2luZyB2YXJpYWJsZSBkZWNsYXJhdGlvbi4KIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0gMC41LjIgKDIwMTAvMDQvMjEpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojICogKDIwMTAvMDQvMjEpIC0gQnVnZml4OiByZW1vdmVkICJteSIgZnJvbSBwYWNrYWdlIGluc3RhbGxhdGlvbi4KIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0gMC41LjEgKDIwMTAvMDQvMjEpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojICogKDIwMTAvMDQvMjApIC0gQ1I6IGZpbmFsaXplZCBtYXBwaW5nIGNyZWF0aW9uIGR1cmluZyBpbnN0YWxsYXRpb24KIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0gMC41LjAgKDIwMTAvMDQvMTcpIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojICogKDIwMTAvMDQvMTcpIC0gQ1I6IEZpcnN0IHByZS1wcm9kdWN0aXZlIHJlbGVhc2Ugb2YgZ2VuZXJhbCBzZXJ2aWNlIGltcG9ydC0vZXhwb3J0IGJhY2tlbmQuCiMgKiAoMjAxMC8wNC8xNikgLSBDUjogYXV0b21hdGljIGV4LS9pbXBvcnQtbWFwcGluZyBjcmVhdGlvbiBvbiBwYWNrYWdlIGluc3RhbGxhdGlvbgojICogKDIwMTAvMDQvMTUpIC0gQ1I6IGFkZGVkIHVuaXQtdGVzdCBmaWxlcyAocHJlcGFyYXRpb25zIG9ubHkpCiMgKiAoMjAxMC8wNC8xNSkgLSBDUjogYWRkZWQgZXgtL2ltcG9ydCBiYWNrZW5kIGZ1ciBTTEEgZGVmaW5pdGlvbgojICogKDIwMTAvMDQvMTMpIC0gQ1I6IGFkZGVkIGV4LS9pbXBvcnQgYmFja2VuZCBmdXIgU2VydmljZQojICogKDIwMTAvMDQvMTIpIC0gQ1I6IGFkZGVkIGV4LS9pbXBvcnQgYmFja2VuZCBmdXIgU2VydmljZTJDdXN0b21lclVzZXIKIyAqICgyMDEwLzA0LzA5KSAtIENSOiBpbml0aWFsIHBhY2thZ2Ugc2V0dXAKIwojLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSA=
IyAkSWQ6IFVTQUdFX3NlcnZpY2VpbXBvcnRleHBvcnQucG9kLHYgMS4xIDIwMTEtMDMtMjEgMDg6MDI6MzkgdHRvIEV4cCAkCgo9aGVhZDEgR2VuZXJhbAoKVGhpcyBwYWNrYWdlIHByb3ZpZGVzIGFuIENTVi1iYXNlZCBpbXBvcnQvZXhwb3J0IGJhY2tlbmQgZm9yIGl0ZW1zIGRlc2NyaWJlZCBpbiBmb2xsb3dpbmcgc2VjdGlvbnMuCgpPZiBjb3Vyc2UsIHlvdSBtYXkgY3JlYXRlZCB5b3VyIG93biBpbXBvcnQtL2V4cG9ydCBtYXBwaW5ncy4gVG8gZWFzZSB0aGUgdXNlIGFuZCBpbiBvcmRlciB0byBwcm92aWRlIGFuIGluaXRpYWwgZnVuY3Rpb25hbGl0eSBtYXBwaW5ncyBhcmUgYXV0b21hdGljYWxseSBjcmVhdGVkIHVwb24gcmUtL2luc3RhbGxhdGlvbiBvZiB0aGlzIHBhY2thZ2UuIFRoZXJlZm9yZSBpdCdzIGNoZWNrZWQgaWYgbWFwcGluZ3Mgd2l0aCB0aGUgZ2l2ZW4gZGVmYXVsdCBuYW1lcyBhcmUgYWxyZWFkeSBhdmFpbGFibGUuIElmIHNvLCBubyBuZXcgbWFwcGluZyB3aWxsIGJlIGNyZWF0ZWQuIElmIG5vdCwgYSBkZWZhdWx0IG1hcHBpbmcgd2lsbCBiZSBjcmVhdGVkLiBCZWZvcmUgYWN0dWFsbHkgdXNpbmcgdGhlc2UgZGVmYXVsdCBtYXBwaW5ncywgcGxlYXNlIGNoZWNrIHRoZWlyIGNvbmZpZ3VyYXRpb25zLgoKPW92ZXIgNCAKCj1pdGVtICogIkV4cG9ydCB3aXRoIGxhYmVscyI6IAoKICAgICAgICBpZiBlbmFibGVkLCB0aGUgZmlyc3QgbGluZSBvZiB0aGUgZXhwb3J0IGZpbGUgd2lsbCBjb250YWluIHNvbWUgc29ydCBvZiBoZWFkbGluZSBjb250YWluaW5nIHRoZSBPVFJTLWludGVybmFsIGtleS4gV2hpY2ggbWF5IG5vdCBiZSB0aGUgcGVyZmVjdCBsYWJlbCBidXQgaGVscHMgdG8gdW5kZXJzdGFuZC4gVGhlIGZpcnN0IGxpbmUgb2YgYW4gaW1wb3J0IGZpbGUgaXMgc2tpcHBlZCBpZiBpdCBjb250YWlucyBvbmx5IHZhbHVlcyB3aGljaCBhcmUgdXNlZCBhcyBPVFJTLWludGVybmFsIGtleXMuIFRodXMgeW91IG1heSBpbXBvcnQgdGhpcyBmaWxlIHdpdGhvdXQgYW55IHByb2JsZW1zLgoKPWl0ZW0gKiAiRGVmYXVsdCBWYWxpZGl0eSIKCiAgICAgICAgaWYgbm8gdmFsaWQgaW5mb3JtYXRpb24gaXMgcHJvdmlkZWQgaW4gaW1wb3J0IGRhdGEsIHRoaXMgdmFsaWQgaW5mb3JtYXRpb24gaXMgdXNlZAoKPWJhY2sKCj1oZWFkMiBTZXJ2aWNlLUltcG9ydC9FeHBvcnQKCj1vdmVyIDQgCgo9aXRlbSAqIGRlZmF1bHQgbWFwcGluZyBuYW1lICJTZXJ2aWNlIChhdXRvLWNyZWF0ZWQgbWFwKSIKCj1pdGVtICogRGVmYXVsdCBTZXJ2aWNldHlwZQoKPW92ZXIgOAoKRGVwZW5kaW5nIG9uIGF2YWlsYWJpbGl0eSBvZiBHZW5lcmFsQ2F0YWxvZyBjbGFzcyAiSVRTTTo6U2VydmljZTo6VHlwZSIgeW91IG1heSBkZWZpbmUgYW4gZGVmYXVsdCBTZXJ2aWNlLVR5cGUgZm9yIGEgc2VydmljZSB0byBiZSBpbXBvcnRlZCAoaWYgbm90IHNwZWNpZmllZCBpbiBwcm92aWRlZCBkYXRhKQoKPWJhY2sKCj1pdGVtICogRGVmYXVsdCBDcml0aWNhbGl0eQoKPW92ZXIgOAoKRGVwZW5kaW5nIG9uIGF2YWlsYWJpbGl0eSBvZiBHZW5lcmFsQ2F0YWxvZyBjbGFzcyAiSVRTTTo6Q29yZTo6Q3JpdGljYWxpdHkiIHlvdSBtYXkgZGVmaW5lIGFuIGRlZmF1bHQgY3JpdGljYWxpdHkgZm9yIGEgc2VydmljZSB0byBiZSBpbXBvcnRlZCAoaWYgbm90IHNwZWNpZmllZCBpbiBwcm92aWRlZCBkYXRhKQoKPWJhY2sKCj1pdGVtICogQ1NWLVJvdyB3aXRoIFNlcnZpY2UtSUQKCj1vdmVyIDgKCklmIHRoZSBTZXJ2aWNlSUQgaXMgc3BlY2lmaWVkLCB5b3UgbWF5IHVwZGF0ZSB0aGUgbmFtZSBvZiB0aGUgc2VydmljZSwgaWYgdGhlIFNlcnZpY2VOYW1lIGlzIG5vdCB1c2VkIGFzIGlkZW50aWZpZXIKCj1iYWNrCgo9YmFjawoKPWhlYWQyIFNMQS1JbXBvcnQvRXhwb3J0Cgo9b3ZlciA0IAoKPWl0ZW0gKiBkZWZhdWx0IG1hcHBpbmcgbmFtZSAiU0xBIChhdXRvLWNyZWF0ZWQgbWFwKSIKCj1pdGVtICogRGVmYXVsdC1TTEEtVHlwZQoKPW92ZXIgOCAKCkRlcGVuZGluZyBvbiBhdmFpbGFiaWxpdHkgb2YgR2VuZXJhbENhdGFsb2cgY2xhc3MgIklUU006OlNMQTo6VHlwZSIgeW91IG1heSBkZWZpbmUgYW4gZGVmYXVsdCBTTEEtVHlwZSBmb3IgYSBzZXJ2aWNlIHRvIGJlIGltcG9ydGVkIChpZiBub3Qgc3BlY2lmaWVkIGluIHByb3ZpZGVkIGRhdGEpCgo9YmFjawoKPWl0ZW0gKiBOdW1iZXIgb2YgYXNzaWduZWQgc2VydmljZXM6IAoKPW92ZXIgOCAKCkFuIFNMQSBtYXkgYmUgYXNzaWduZWQgdG8gbWFueSBzZXJ2aWNlcywgZm9yIGEgc3RhcnQgaXQgaXMgYXNzdW1lZCB0aGF0IDUwIHNlcnZpY2VzIGlzIGVub3VnaC4gaWYgeW91IHJlcXVpcmUgbW9yZSBBc3NpZ25lZFNlcnZpY2VzIHlvdSBjYW4gaW5jcmVhc2UgdGhpcyBudW1iZXIgaW4gdGhlIG1hcHBpbmcgY29uZmlndXJhdGlvbi4gSXQgbGltaXRzIHRoZSBudW1iZXIgb2YgIkFzc2lnbmVkU2VydmljZSIgc2VsZWN0aW9uIGluIHN0ZXAgNCBvZiB0aGUgbWFwcGluZyBjb25maWd1cmF0aW9uLgoKPWJhY2sKCj1iYWNrCgo9aGVhZDIgU2VydmljZTJDdXN0b21lclVzZXItSW1wb3J0L0V4cG9ydAoKPW92ZXIgNAoKPWl0ZW0gKiBkZWZhdWx0IG1hcHBpbmcgbmFtZSAiU2VydmljZTJDdXN0b21lclVzZXIgKGF1dG8tY3JlYXRlZCBtYXApIgoKPWJhY2sKClRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KCj1jdXQK
IyAtLQojIEltcG9ydEV4cG9ydE9iamVjdFNlcnZpY2UudCAtIGFsbCBpbXBvcnQgZXhwb3J0IHRlc3RzIGZvciB0aGUgU2VydmljZSBvYmplY3QgYmFja2VuZAojIENvcHlyaWdodCAoQykgMjAwNi0yMDEwIGMuYS5wLmUuIElUIEdtYkgsIGh0dHA6Ly93d3cuY2FwZS1pdC5kZS8KIwojIHdyaXR0ZW4vZWRpdGVkIGJ5OgojICogVG9yc3Rlbihkb3QpVGhhdShhdCljYXBlKGRhc2gpaXQoZG90KWRlCiMKIyAtLQojICRJZDogSW1wb3J0RXhwb3J0T2JqZWN0U2VydmljZS50LHYgMS4xIDIwMTAtMDQtMTUgMDg6NTc6MTcgdHRvIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7CnVzZSB1dGY4OwoKdXNlIHZhcnMgcXcoJFNlbGYpOwoKdXNlIERhdGE6OkR1bXBlcjsKdXNlIEtlcm5lbDo6U3lzdGVtOjpFbmNvZGU7CnVzZSBLZXJuZWw6OlN5c3RlbTo6R2VuZXJhbENhdGFsb2c7CnVzZSBLZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0Owp1c2UgS2VybmVsOjpTeXN0ZW06OkltcG9ydEV4cG9ydDo6T2JqZWN0QmFja2VuZDo6U2VydmljZTsKdXNlIEtlcm5lbDo6U3lzdGVtOjpTZXJ2aWNlOwp1c2UgS2VybmVsOjpTeXN0ZW06OlhNTDsKCiRTZWxmLT57RW5jb2RlT2JqZWN0fSAgICAgICAgID0gS2VybmVsOjpTeXN0ZW06OkVuY29kZS0+bmV3KCAleyRTZWxmfSApOwokU2VsZi0+e0dlbmVyYWxDYXRhbG9nT2JqZWN0fSA9IEtlcm5lbDo6U3lzdGVtOjpHZW5lcmFsQ2F0YWxvZy0+bmV3KCAleyRTZWxmfSApOwokU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0gICA9IEtlcm5lbDo6U3lzdGVtOjpJbXBvcnRFeHBvcnQtPm5ldyggJXskU2VsZn0gKTsKJFNlbGYtPntPYmplY3RCYWNrZW5kT2JqZWN0fSAgPSBLZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kOjpTZXJ2aWNlLT5uZXcoICV7JFNlbGZ9ICk7CiRTZWxmLT57U2VydmljZU9iamVjdH0gICAgICAgID0gS2VybmVsOjpTeXN0ZW06OlNlcnZpY2UtPm5ldyggJXskU2VsZn0gKTsgICAgCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiMgbWFrZSBwcmVwYXJhdGlvbnMKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwoKIyBhZGQgc29tZSB0ZXN0IHRlbXBsYXRlcyBmb3IgbGF0ZXIgY2hlY2tzCm15IEBUZW1wbGF0ZUlEczsKZm9yICggMSAuLiAzMCApIHsKCiAgICAjIGFkZCBhIHRlc3QgdGVtcGxhdGUgZm9yIGxhdGVyIGNoZWNrcwogICAgbXkgJFRlbXBsYXRlSUQgPSAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPlRlbXBsYXRlQWRkKAogICAgICAgIE9iamVjdCAgPT4gJ1NlcnZpY2UnLAogICAgICAgIEZvcm1hdCAgPT4gJ1VuaXRUZXN0JyAuIGludCByYW5kIDFfMDAwXzAwMCwKICAgICAgICBOYW1lICAgID0+ICdVbml0VGVzdCcgLiBpbnQgcmFuZCAxXzAwMF8wMDAsCiAgICAgICAgVmFsaWRJRCA9PiAxLAogICAgICAgIFVzZXJJRCAgPT4gMSwKICAgICk7CgogICAgcHVzaCBAVGVtcGxhdGVJRHMsICRUZW1wbGF0ZUlEOwp9CgpteSAkVGVzdENvdW50ID0gMTsKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiMgT2JqZWN0TGlzdCB0ZXN0IDEgKGNoZWNrIENTViBpdGVtKQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCgojIGdldCBvYmplY3QgbGlzdApteSAkT2JqZWN0TGlzdDEgPSAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPk9iamVjdExpc3QoKTsKCiMgY2hlY2sgb2JqZWN0IGxpc3QKJFNlbGYtPlRydWUoCiAgICAkT2JqZWN0TGlzdDEgJiYgcmVmICRPYmplY3RMaXN0MSBlcSAnSEFTSCcgJiYgJE9iamVjdExpc3QxLT57U2VydmljZX0sCiAgICAiVGVzdCAkVGVzdENvdW50OiBPYmplY3RMaXN0KCkgLSBTZXJ2aWNlIGV4aXN0cyIsCik7CgokVGVzdENvdW50Kys7CgoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwojIE9iamVjdEF0dHJpYnV0ZXNHZXQgdGVzdCAxIChjaGVjayBhdHRyaWJ1dGUgaGFzaCkKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwoKIwojCiMgVE8gRE8gCiMKIwoKCg==
IyAtLQojIEltcG9ydEV4cG9ydE9iamVjdFNMQS50IC0gYWxsIGltcG9ydCBleHBvcnQgdGVzdHMgZm9yIHRoZSBTTEEgb2JqZWN0IGJhY2tlbmQKIyBDb3B5cmlnaHQgKEMpIDIwMDYtMjAxMCBjLmEucC5lLiBJVCBHbWJILCBodHRwOi8vd3d3LmNhcGUtaXQuZGUvCiMKIyB3cml0dGVuL2VkaXRlZCBieToKIyAqIFRvcnN0ZW4oZG90KVRoYXUoYXQpY2FwZShkYXNoKWl0KGRvdClkZQojCiMgLS0KIyAkSWQ6IEltcG9ydEV4cG9ydE9iamVjdFNMQS50LHYgMS4xIDIwMTAtMDQtMTUgMDg6NTc6MTcgdHRvIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7CnVzZSB1dGY4OwoKdXNlIHZhcnMgcXcoJFNlbGYpOwoKdXNlIERhdGE6OkR1bXBlcjsKdXNlIEtlcm5lbDo6U3lzdGVtOjpFbmNvZGU7CnVzZSBLZXJuZWw6OlN5c3RlbTo6R2VuZXJhbENhdGFsb2c7CnVzZSBLZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0Owp1c2UgS2VybmVsOjpTeXN0ZW06OkltcG9ydEV4cG9ydDo6T2JqZWN0QmFja2VuZDo6U0xBOwp1c2UgS2VybmVsOjpTeXN0ZW06OlNlcnZpY2U7CnVzZSBLZXJuZWw6OlN5c3RlbTo6U0xBOwp1c2UgS2VybmVsOjpTeXN0ZW06OlhNTDsKCiRTZWxmLT57RW5jb2RlT2JqZWN0fSAgICAgICAgID0gS2VybmVsOjpTeXN0ZW06OkVuY29kZS0+bmV3KCAleyRTZWxmfSApOwokU2VsZi0+e0dlbmVyYWxDYXRhbG9nT2JqZWN0fSA9IEtlcm5lbDo6U3lzdGVtOjpHZW5lcmFsQ2F0YWxvZy0+bmV3KCAleyRTZWxmfSApOwokU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0gICA9IEtlcm5lbDo6U3lzdGVtOjpJbXBvcnRFeHBvcnQtPm5ldyggJXskU2VsZn0gKTsKJFNlbGYtPntPYmplY3RCYWNrZW5kT2JqZWN0fSAgPSBLZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0OjpPYmplY3RCYWNrZW5kOjpTTEEtPm5ldyggJXskU2VsZn0gKTsKJFNlbGYtPntTZXJ2aWNlT2JqZWN0fSAgICAgICAgPSBLZXJuZWw6OlN5c3RlbTo6U2VydmljZS0+bmV3KCAleyRTZWxmfSApOwokU2VsZi0+e1NMQU9iamVjdH0gICAgICAgICAgICA9IEtlcm5lbDo6U3lzdGVtOjpTTEEtPm5ldyggJXskU2VsZn0gKTsKICAgIAoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwojIG1ha2UgcHJlcGFyYXRpb25zCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKCiMgYWRkIHNvbWUgdGVzdCB0ZW1wbGF0ZXMgZm9yIGxhdGVyIGNoZWNrcwpteSBAVGVtcGxhdGVJRHM7CmZvciAoIDEgLi4gMzAgKSB7CgogICAgIyBhZGQgYSB0ZXN0IHRlbXBsYXRlIGZvciBsYXRlciBjaGVja3MKICAgIG15ICRUZW1wbGF0ZUlEID0gJFNlbGYtPntJbXBvcnRFeHBvcnRPYmplY3R9LT5UZW1wbGF0ZUFkZCgKICAgICAgICBPYmplY3QgID0+ICdTTEEnLAogICAgICAgIEZvcm1hdCAgPT4gJ1VuaXRUZXN0JyAuIGludCByYW5kIDFfMDAwXzAwMCwKICAgICAgICBOYW1lICAgID0+ICdVbml0VGVzdCcgLiBpbnQgcmFuZCAxXzAwMF8wMDAsCiAgICAgICAgVmFsaWRJRCA9PiAxLAogICAgICAgIFVzZXJJRCAgPT4gMSwKICAgICk7CgogICAgcHVzaCBAVGVtcGxhdGVJRHMsICRUZW1wbGF0ZUlEOwp9CgpteSAkVGVzdENvdW50ID0gMTsKCgojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiMgT2JqZWN0TGlzdCB0ZXN0IDEgKGNoZWNrIENTViBpdGVtKQojIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCgojIGdldCBvYmplY3QgbGlzdApteSAkT2JqZWN0TGlzdDEgPSAkU2VsZi0+e0ltcG9ydEV4cG9ydE9iamVjdH0tPk9iamVjdExpc3QoKTsKCiMgY2hlY2sgb2JqZWN0IGxpc3QKJFNlbGYtPlRydWUoCiAgICAkT2JqZWN0TGlzdDEgJiYgcmVmICRPYmplY3RMaXN0MSBlcSAnSEFTSCcgJiYgJE9iamVjdExpc3QxLT57U0xBfSwKICAgICJUZXN0ICRUZXN0Q291bnQ6IE9iamVjdExpc3QoKSAtIFNMQSBleGlzdHMiLAopOwoKJFRlc3RDb3VudCsrOwoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKIyBPYmplY3RBdHRyaWJ1dGVzR2V0IHRlc3QgMSAoY2hlY2sgYXR0cmlidXRlIGhhc2gpCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKCiMKIwojIFRPIERPIAojCiMKCgo=
IyAtLQojIEltcG9ydEV4cG9ydE9iamVjdFNlcnZpY2UyQ3VzdG9tZXJVc2VyLnQgLSBhbGwgaW1wb3J0IGV4cG9ydCB0ZXN0cyBmb3IgdGhlIFNlcnZpY2UyQ3VzdG9tZXJVc2VyIG9iamVjdCBiYWNrZW5kCiMgQ29weXJpZ2h0IChDKSAyMDA2LTIwMTAgYy5hLnAuZS4gSVQgR21iSCwgaHR0cDovL3d3dy5jYXBlLWl0LmRlLwojCiMgd3JpdHRlbi9lZGl0ZWQgYnk6CiMgKiBUb3JzdGVuKGRvdClUaGF1KGF0KWNhcGUoZGFzaClpdChkb3QpZGUKIwojIC0tCiMgJElkOiBJbXBvcnRFeHBvcnRPYmplY3RTZXJ2aWNlMkN1c3RvbWVyVXNlci50LHYgMS4xIDIwMTAtMDQtMTUgMDg6NTc6MTcgdHRvIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7CnVzZSB1dGY4OwoKdXNlIHZhcnMgcXcoJFNlbGYpOwoKdXNlIERhdGE6OkR1bXBlcjsKdXNlIEtlcm5lbDo6U3lzdGVtOjpFbmNvZGU7CnVzZSBLZXJuZWw6OlN5c3RlbTo6R2VuZXJhbENhdGFsb2c7CnVzZSBLZXJuZWw6OlN5c3RlbTo6SW1wb3J0RXhwb3J0Owp1c2UgS2VybmVsOjpTeXN0ZW06OkltcG9ydEV4cG9ydDo6T2JqZWN0QmFja2VuZDo6U2VydmljZTJDdXN0b21lclVzZXI7CnVzZSBLZXJuZWw6OlN5c3RlbTo6U2VydmljZTsKdXNlIEtlcm5lbDo6U3lzdGVtOjpDdXN0b21lclVzZXI7CnVzZSBLZXJuZWw6OlN5c3RlbTo6WE1MOwoKJFNlbGYtPntFbmNvZGVPYmplY3R9ICAgICAgICAgPSBLZXJuZWw6OlN5c3RlbTo6RW5jb2RlLT5uZXcoICV7JFNlbGZ9ICk7CiRTZWxmLT57R2VuZXJhbENhdGFsb2dPYmplY3R9ID0gS2VybmVsOjpTeXN0ZW06OkdlbmVyYWxDYXRhbG9nLT5uZXcoICV7JFNlbGZ9ICk7CiRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fSAgID0gS2VybmVsOjpTeXN0ZW06OkltcG9ydEV4cG9ydC0+bmV3KCAleyRTZWxmfSApOwokU2VsZi0+e09iamVjdEJhY2tlbmRPYmplY3R9ICA9IEtlcm5lbDo6U3lzdGVtOjpJbXBvcnRFeHBvcnQ6Ok9iamVjdEJhY2tlbmQ6OlNlcnZpY2UyQ3VzdG9tZXJVc2VyLT5uZXcoICV7JFNlbGZ9ICk7CiRTZWxmLT57U2VydmljZU9iamVjdH0gICAgICAgID0gS2VybmVsOjpTeXN0ZW06OlNlcnZpY2UtPm5ldyggJXskU2VsZn0gKTsKJFNlbGYtPntDdXN0b21lclVzZXJPYmplY3R9ICAgPSBLZXJuZWw6OlN5c3RlbTo6Q3VzdG9tZXJVc2VyLT5uZXcoICV7JFNlbGZ9ICk7ICAgIAoKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwojIG1ha2UgcHJlcGFyYXRpb25zCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKCiMgYWRkIHNvbWUgdGVzdCB0ZW1wbGF0ZXMgZm9yIGxhdGVyIGNoZWNrcwpteSBAVGVtcGxhdGVJRHM7CmZvciAoIDEgLi4gMzAgKSB7CgogICAgIyBhZGQgYSB0ZXN0IHRlbXBsYXRlIGZvciBsYXRlciBjaGVja3MKICAgIG15ICRUZW1wbGF0ZUlEID0gJFNlbGYtPntJbXBvcnRFeHBvcnRPYmplY3R9LT5UZW1wbGF0ZUFkZCgKICAgICAgICBPYmplY3QgID0+ICdTZXJ2aWNlMkN1c3RvbWVyVXNlcicsCiAgICAgICAgRm9ybWF0ICA9PiAnVW5pdFRlc3QnIC4gaW50IHJhbmQgMV8wMDBfMDAwLAogICAgICAgIE5hbWUgICAgPT4gJ1VuaXRUZXN0JyAuIGludCByYW5kIDFfMDAwXzAwMCwKICAgICAgICBWYWxpZElEID0+IDEsCiAgICAgICAgVXNlcklEICA9PiAxLAogICAgKTsKCiAgICBwdXNoIEBUZW1wbGF0ZUlEcywgJFRlbXBsYXRlSUQ7Cn0KCm15ICRUZXN0Q291bnQgPSAxOwoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKIyBPYmplY3RMaXN0IHRlc3QgMSAoY2hlY2sgQ1NWIGl0ZW0pCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKCiMgZ2V0IG9iamVjdCBsaXN0Cm15ICRPYmplY3RMaXN0MSA9ICRTZWxmLT57SW1wb3J0RXhwb3J0T2JqZWN0fS0+T2JqZWN0TGlzdCgpOwoKIyBjaGVjayBvYmplY3QgbGlzdAokU2VsZi0+VHJ1ZSgKICAgICRPYmplY3RMaXN0MSAmJiByZWYgJE9iamVjdExpc3QxIGVxICdIQVNIJyAmJiAkT2JqZWN0TGlzdDEtPntTZXJ2aWNlMkN1c3RvbWVyVXNlcn0sCiAgICAiVGVzdCAkVGVzdENvdW50OiBPYmplY3RMaXN0KCkgLSBTZXJ2aWNlMkN1c3RvbWVyVXNlciBleGlzdHMiLAopOwoKJFRlc3RDb3VudCsrOwoKCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKIyBPYmplY3RBdHRyaWJ1dGVzR2V0IHRlc3QgMSAoY2hlY2sgYXR0cmlidXRlIGhhc2gpCiMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKCiMKIwojIFRPIERPIAojCiMKCgo=