JIRAPackage
2.0.0
catWorkX GmbH
http://www.catworkx.de/
Commercial
Major rewrite of the OTRS2JIRA fieldmapping.
Added code to transform OTRS-dynamic fields/values to JIRA-custom fields/values and pass them to JIRA.
Added code to pass attachments to JIRA.
Added code to read configured Jira-project and Jira-issue from the 'SysConfig'.
Added ConfigItem to JIRA XML file and made field mapping from OTRS to JIRA configurable.
Added ConfigItem to JIRA XML file and made JIRA-date format configurable.
Added ConfigItem to JIRA XML file and made JIRA-Issue type configurable.
Added ConfigItem to JIRA XML file and made JIRA-project configurable.
Added code to check the OTRS Tickets state prior to any action. States are now configurable.
Added code to fetch the possible transitions of the given JIRA issue before attempting the transition.
Added template for showing an error in case a ticket is closed when one wants to open a JIRA issue.
Added code to pass the last article body to JIRA upon closing.
Added code to pass the article body to JIRA upon creation and comment the closing of a ticket in JIRA appropriately.
Added event code to close the JIRA issue when the ticket is closed.
Added a hyperlink to JIRA.
Fixed the issue creation code.
Cleanup.
Added the options into the XML file.
Added error handling to the installer.
Added debugging to the installer.
Bugifxed the code for adding the JiraIssueID to the searchable and visible fields.
Added code for adding the JiraIssueID to the searchable and visible fields.
Bugfix for REST code for the remote issue links.
Bugfix for REST code for the remote issue links.
Added REST code for the remote issue links.
Uninstaller and Upgrader code done.
Added assignee and reporter. Nicer statuspage.
Updated MD5 dependecy.
New MD5 code in installer.
Updated DTL.
Updated SQL.
Debugging for dynamic field.
Added missing backslashes.
Added dynamic field.
New package.
A module giving the option to escalate tickets into JIRA.
Ein Modul, um Tickets in ein JIRA zu eskalieren.
3.1.x
Thank you for choosing the JIRAPackage module.
Vielen Dank fuer die Auswahl des JIRAPackage Modules.
Digest::MD5
JIRA::Client
JSON
REST::Client
MIME::Base64
Switch
use Digest::MD5 qw(md5_hex);
# Config is taken from: otrs/development/webservices/GenericTicketConnector.yml
my $Config = "---
Debugger:
DebugThreshold: debug
TestMode: 0
Description: Ticket Connector Sample
FrameworkVersion: 3.1.x CVS
Provider:
Operation:
SessionCreate:
Description: Creates a Session
MappingInbound: {}
MappingOutbound: {}
Type: Session::SessionCreate
TicketCreate:
Description: Creates a Ticket
MappingInbound: {}
MappingOutbound: {}
Type: Ticket::TicketCreate
TicketUpdate:
Description: Updates a Ticket
MappingInbound: {}
MappingOutbound: {}
Type: Ticket::TicketUpdate
TicketGet:
Description: Retrieve Ticket data
MappingInbound: {}
MappingOutbound: {}
Type: Ticket::TicketGet
TicketSearch:
Description: Search for Tickets
MappingInbound: {}
MappingOutbound: {}
Type: Ticket::TicketSearch
Transport:
Config:
MaxLength: 100000000
NameSpace: http://www.otrs.org/TicketConnector/
Type: HTTP::SOAP
RemoteSystem: ''
Requester:
Transport:
Type: ''
";
my $Digest = md5_hex($Config);
$Self->{DBObject}->Do(SQL => 'INSERT INTO gi_webservice_config (name, config, config_md5, valid_id, '
. ' create_time, create_by, change_time, change_by)'
. ' VALUES (\'GenericTicketConnector\', ?, ?, 1, current_timestamp, 1, current_timestamp, 1)',
Bind => [ \$Config, \$Digest, ],
); # Errors are ignored
$Config = "---
DefaultValue: ''
Link: 'http://localhost:8080/browse/\$LQData\{\"JIRAIssueID\"}'
";
$Self->{DBObject}->Do(
SQL =>
'INSERT INTO dynamic_field (name, label, field_Order, field_type, object_type,' .
'config, valid_id, create_time, create_by, change_time, change_by)' .
' VALUES (\'JIRAIssueID\', \'Jira Issue ID\', 1, \'Text\', \'Ticket\', ?, 1, current_timestamp, 1, current_timestamp, 1)',
Bind => [ \$Config, ],
); # Errors are ignored
$Self->{DBObject}->Do(SQL => "UPDATE gi_webservice_config SET name = 'GenericTicketConnector' WHERE name = 'JIRA'");
my $Config = "---
DefaultValue: ''
Link: 'http://localhost:8080/browse/\$LQData\{\"JIRAIssueID\"}'
";
$Self->{DBObject}->Do(SQL => "UPDATE dynamic_field SET config = ? WHERE name = 'JIRAIssueID'",
Bind => [ \$Config, ]);
$Self->{DBObject}->Do(SQL => "DELETE FROM dynamic_field WHERE name = 'JIRAIssueID'");
$Self->{DBObject}->Do(SQL => "DELETE FROM gi_webservice_config WHERE name = 'GenericTicketConnector'");
2014-09-05 09:12:00
cat-pc-050.catworkx.de
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiID8+CjxvdHJzX2NvbmZpZyB2ZXJzaW9uPSIxLjAiIGluaXQ9IkFwcGxpY2F0aW9uIj4KCTxDb25maWdJdGVtIE5hbWU9IkZyb250ZW5kOjpNb2R1bGUjIyNBZ2VudFRpY2tldEpJUkEiIFJlcXVpcmVkPSIxIiBWYWxpZD0iMSI+CgkJPERlc2NyaXB0aW9uIExhbmc9ImVuIj5Gcm9udGVuZE1vZHVsZVJlZ2lzdHJhdGlvbiBmb3IgdGhlIFRpY2tldEpJUkEgbW9kdWxlLjwvRGVzY3JpcHRpb24+CgkJPERlc2NyaXB0aW9uIExhbmc9ImRlIj5Gcm9udGVuZE1vZHVsUmVnaXN0cmF0aW9uIGbDvHIgZGFzIFRpY2tldEpJUkEgTW9kdWwuPC9EZXNjcmlwdGlvbj4KCQk8R3JvdXA+VGlja2V0SklSQTwvR3JvdXA+CgkJPFN1Ykdyb3VwPkFnZW50RnJvbnRlbmRNb2R1bGVSZWdpc3RyYXRpb248L1N1Ykdyb3VwPgoJCTxTZXR0aW5nPgoJCQk8RnJvbnRlbmRNb2R1bGVSZWc+CgkJCQk8VGl0bGU+VGlja2V0SklSQTwvVGl0bGU+CgkJCQk8R3JvdXA+dXNlcnM8L0dyb3VwPgoJCQkJPERlc2NyaXB0aW9uPlRpY2tldEpJUkE8L0Rlc2NyaXB0aW9uPgoJCQkJPE5hdkJhck5hbWU+VGlja2V0SklSQTwvTmF2QmFyTmFtZT4KCQkJCTxOYXZCYXI+CgkJCQkJPERlc2NyaXB0aW9uPlRpY2tldEpJUkE8L0Rlc2NyaXB0aW9uPgoJCQkJCTxOYW1lPlRpY2tldEpJUkE8L05hbWU+CgkJCQkJPEltYWdlPm92ZXJ2aWV3LnBuZzwvSW1hZ2U+CgkJCQkJPExpbms+QWN0aW9uPUFnZW50VGlja2V0SklSQTwvTGluaz4KCQkJCQk8TmF2QmFyPlRpY2tldEpJUkE8L05hdkJhcj4KCQkJCQk8VHlwZT5NZW51PC9UeXBlPgoJCQkJCTxQcmlvPjg0MDA8L1ByaW8+CgkJCQkJPEJsb2NrPkl0ZW1BcmVhPC9CbG9jaz4KCQkJCTwvTmF2QmFyPgoJCQk8L0Zyb250ZW5kTW9kdWxlUmVnPgoJCTwvU2V0dGluZz4KCTwvQ29uZmlnSXRlbT4KCTxDb25maWdJdGVtIE5hbWU9IkZyb250ZW5kOjpNb2R1bGUjIyNBZ2VudFRpY2tldEpJUkEiIFJlcXVpcmVkPSIwIiBWYWxpZD0iMSI+CgkJPERlc2NyaXB0aW9uIExhbmc9ImVuIj5Gcm9udGVuZCBtb2R1bGUgcmVnaXN0cmF0aW9uIGZvciB0aGUgYWdlbnQgaW50ZXJmYWNlLjwvRGVzY3JpcHRpb24+CgkJPERlc2NyaXB0aW9uIExhbmc9ImRlIj5Gcm9udGVuZCBtb2R1bGUgcmVnaXN0cmF0aW9uIGbDvHIgZGFzIEFnZW50IEludGVyZmFjZS48L0Rlc2NyaXB0aW9uPgoJCTxHcm91cD5UaWNrZXQ8L0dyb3VwPgoJCTxTdWJHcm91cD5Gcm9udGVuZDo6QWdlbnQ6Ok1vZHVsZVJlZ2lzdHJhdGlvbjwvU3ViR3JvdXA+CgkJPFNldHRpbmc+CgkJCTxGcm9udGVuZE1vZHVsZVJlZz4KCQkJCTxEZXNjcmlwdGlvbj5Fc2NhbGF0ZSB0aGlzIFRpY2tldCB0byBKSVJBPC9EZXNjcmlwdGlvbj4KCQkJCTxUaXRsZT5Fc2NhbGF0ZSB0byBKSVJBPC9UaXRsZT4KCQkJCTxOYXZCYXJOYW1lPlRpY2tldDwvTmF2QmFyTmFtZT4KCQkJPC9Gcm9udGVuZE1vZHVsZVJlZz4KCQk8L1NldHRpbmc+Cgk8L0NvbmZpZ0l0ZW0+Cgk8Q29uZmlnSXRlbSBOYW1lPSJUaWNrZXQ6OkZyb250ZW5kOjpNZW51TW9kdWxlIyMjOTAwLUpJUkEiIFJlcXVpcmVkPSIwIiBWYWxpZD0iMSI+CgkJPERlc2NyaXB0aW9uIExhbmc9ImVuIj5Nb2R1bGUgdG8gc2hvd3MgYSBKSVJBLWxpbmsgaW4gbWVudSBvZiB0aGUgdGlja2V0IHpvb20uPC9EZXNjcmlwdGlvbj4KCQk8RGVzY3JpcHRpb24gTGFuZz0iZGUiPk1pdCBkaWVzZW0gTW9kdWwgd2lyZCBkZXIgSklSQS1MaW5rIGluIGRlciBMaW5rbGVpc3RlIGRlciBUaWNrZXRhbnNpY2h0IGFuZ2V6ZWlndC48L0Rlc2NyaXB0aW9uPgoJCTxHcm91cD5UaWNrZXQ8L0dyb3VwPgoJCTxTdWJHcm91cD5Gcm9udGVuZDo6QWdlbnQ6OlRpY2tldDo6TWVudU1vZHVsZTwvU3ViR3JvdXA+CgkJPFNldHRpbmc+CgkJCTxIYXNoPgoJCQkJPEl0ZW0gS2V5PSJNb2R1bGUiPktlcm5lbDo6T3V0cHV0OjpIVE1MOjpUaWNrZXRNZW51SklSQTwvSXRlbT4KCQkJCTxJdGVtIEtleT0iTmFtZSI+SklSQTwvSXRlbT4KCQkJCTxJdGVtIEtleT0iQWN0aW9uIj5BZ2VudFRpY2tldEpJUkE8L0l0ZW0+CgkJCQk8SXRlbSBLZXk9IlRhcmdldCI+PC9JdGVtPgoJCQk8L0hhc2g+CgkJPC9TZXR0aW5nPgoJPC9Db25maWdJdGVtPgoJPENvbmZpZ0l0ZW0gTmFtZT0iVGlja2V0SklSQSMjI1VSTCIgUmVxdWlyZWQ9IjEiIFZhbGlkPSIxIj4KCQk8RGVzY3JpcHRpb24gTGFuZz0iZW4iPlRoZSBVUkwgb2YgdGhlIEpJUkEgc2VydmVyLCBpbmNsdWRlIHRoZSBwcm90b2NvbCBhbmQgdGhlIHBvcnQgaWYgcmVxdWlyZWQgYSB3ZWxsIGFzIHRoZSBiYXNlIGlmIGFueS48L0Rlc2NyaXB0aW9uPgoJCTxEZXNjcmlwdGlvbiBMYW5nPSJkZSI+RGllIFVSTCBkZXMgSklSQSBTZXJ2ZXJzLCBpbmtsdXNpdmUgUHJvdG9rb2xsIHNvd2llIFBvcnQgdW5kIFBmYWQsIHNvZmVybiB6dXRyZWZmZW5kLjwvRGVzY3JpcHRpb24+CgkJPEdyb3VwPkZyYW1ld29yazwvR3JvdXA+CgkJPFN1Ykdyb3VwPkNvcmU6OlNPQVA8L1N1Ykdyb3VwPgoJCTxTZXR0aW5nPgoJCQk8U3RyaW5nIFJlZ2V4PSIiPmh0dHA6Ly9jYXQtcGMtMDUwOjgwODA8L1N0cmluZz4KCQk8L1NldHRpbmc+Cgk8L0NvbmZpZ0l0ZW0+Cgk8Q29uZmlnSXRlbSBOYW1lPSJUaWNrZXRKSVJBIyMjVXNlciIgUmVxdWlyZWQ9IjEiIFZhbGlkPSIxIj4KCQk8RGVzY3JpcHRpb24gTGFuZz0iZW4iPlRoZSB1c2VybmFtZSB0byB1c2Ugd2hlbiBsb2dnaW5nIGluIGludG8gSklSQSBpc3N1ZXMuPC9EZXNjcmlwdGlvbj4KCQk8RGVzY3JpcHRpb24gTGFuZz0iZGUiPkRlciBCZW51dHplcm5hbWUgbWl0IGRlbSBzaWNoIGJlaW0gSklSQSBhbmdlbWVsZGV0IHdpcmQuPC9EZXNjcmlwdGlvbj4KCQk8R3JvdXA+RnJhbWV3b3JrPC9Hcm91cD4KCQk8U3ViR3JvdXA+Q29yZTo6U09BUDwvU3ViR3JvdXA+CgkJPFNldHRpbmc+CgkJCTxTdHJpbmcgUmVnZXg9IiI+YWRtaW48L1N0cmluZz4KCQk8L1NldHRpbmc+Cgk8L0NvbmZpZ0l0ZW0+Cgk8Q29uZmlnSXRlbSBOYW1lPSJUaWNrZXRKSVJBIyMjUGFzc3dvcmQiIFJlcXVpcmVkPSIxIiBWYWxpZD0iMSI+CgkJPERlc2NyaXB0aW9uIExhbmc9ImVuIj5UaGUgcGFzc3dvcmQgdG8gdXNlIHdoZW4gbG9nZ2luZyBpbiBpbnRvIEpJUkEgaXNzdWVzLjwvRGVzY3JpcHRpb24+CgkJPERlc2NyaXB0aW9uIExhbmc9ImRlIj5EYXMgUGFzc3dvcnQgbWl0IGRlbSBzaWNoIGJlaW0gSklSQSBhbmdlbWVsZGV0IHdpcmQuPC9EZXNjcmlwdGlvbj4KCQk8R3JvdXA+RnJhbWV3b3JrPC9Hcm91cD4KCQk8U3ViR3JvdXA+Q29yZTo6U09BUDwvU3ViR3JvdXA+CgkJPFNldHRpbmc+CgkJCTxTdHJpbmcgUmVnZXg9IiI+YWRtaW48L1N0cmluZz4KCQk8L1NldHRpbmc+Cgk8L0NvbmZpZ0l0ZW0+Cgk8Q29uZmlnSXRlbSBOYW1lPSJUaWNrZXRKSVJBIyMjUmVwb3J0ZXIiIFJlcXVpcmVkPSIxIiBWYWxpZD0iMSI+CgkJPERlc2NyaXB0aW9uIExhbmc9ImVuIj5UaGUgbmFtZSBvZiB0aGUgcmVwb3J0ZXIgdG8gdXNlIGZvciB0aGUgbmV3IEpJUkEgaXNzdWVzLjwvRGVzY3JpcHRpb24+CgkJPERlc2NyaXB0aW9uIExhbmc9ImRlIj5EZXIgTmFtZSBkZXMgUmVwb3J0ZXJzIGbDvHIgbmV1ZSBKSVJBIElzc3Vlcy48L0Rlc2NyaXB0aW9uPgoJCTxHcm91cD5GcmFtZXdvcms8L0dyb3VwPgoJCTxTdWJHcm91cD5Db3JlOjpTT0FQPC9TdWJHcm91cD4KCQk8U2V0dGluZz4KCQkJPFN0cmluZyBSZWdleD0iIj5hZG1pbjwvU3RyaW5nPgoJCTwvU2V0dGluZz4KCTwvQ29uZmlnSXRlbT4KCTxDb25maWdJdGVtIE5hbWU9IlRpY2tldEpJUkEjIyNBc3NpZ25lZSIgUmVxdWlyZWQ9IjEiIFZhbGlkPSIxIj4KCQk8RGVzY3JpcHRpb24gTGFuZz0iZW4iPlRoZSBuYW1lIG9mIHRoZSBhc3NpZ25lZSB0byB1c2UgZm9yIHRoZSBuZXcgSklSQSBpc3N1ZXMuPC9EZXNjcmlwdGlvbj4KCQk8RGVzY3JpcHRpb24gTGFuZz0iZGUiPkRlciBOYW1lIGRlcyBBc3NpZ25lZSBmw7xyIG5ldWUgSklSQSBJc3N1ZXMuPC9EZXNjcmlwdGlvbj4KCQk8R3JvdXA+RnJhbWV3b3JrPC9Hcm91cD4KCQk8U3ViR3JvdXA+Q29yZTo6U09BUDwvU3ViR3JvdXA+CgkJPFNldHRpbmc+CgkJCTxTdHJpbmcgUmVnZXg9IiI+YWRtaW48L1N0cmluZz4KCQk8L1NldHRpbmc+Cgk8L0NvbmZpZ0l0ZW0+Cgk8Q29uZmlnSXRlbSBOYW1lPSJUaWNrZXRKSVJBIyMjV29ya2Zsb3dDbG9zZUFjaW9uTmFtZSIgUmVxdWlyZWQ9IjEiIFZhbGlkPSIxIj4KCQk8RGVzY3JpcHRpb24gTGFuZz0iZW4iPlRoZSBuYW1lIG9mIHRoZSBjbG9zZSBpc3N1ZSB3b3JrZmxvdyBhY3Rpb24gKGRlZmF1bHQ6ICJDbG9zZSBJc3N1ZSIsIHBheSBhdHRlbnRpb24gdG8gdGhlIEpJUkEgbGFuZ3VhZ2Ugb2YgdXNlciBpbiBUaWNrZXRKSVJBIyMjVXNlciwgRW5nbGlzaChVSykgd29ya3MpLjwvRGVzY3JpcHRpb24+CgkJPERlc2NyaXB0aW9uIExhbmc9ImRlIj5EZXIgTmFtZSBkZXIgQWt0aW9uIHp1bSBTY2hsaWXDn2VuIHZvbiBJc3N1ZXMgKFN0YW5kYXJkOiAiQ2xvc2UgSXNzdWUiLCBhY2h0ZW4gU2llIGF1ZiBkaWUgSklSQSBTcHJhY2hlIGRlcyBCZW51dGVycyBpbiBUaWNrZXRKSVJBIyMjVXNlciwgRW5nbGlzaChVSykgaXN0IGVtcGZlaGxlbnN3ZXJ0KS48L0Rlc2NyaXB0aW9uPgoJCTxHcm91cD5GcmFtZXdvcms8L0dyb3VwPgoJCTxTdWJHcm91cD5Db3JlOjpTT0FQPC9TdWJHcm91cD4KCQk8U2V0dGluZz4KCQkJPFN0cmluZz5DbG9zZSBJc3N1ZTwvU3RyaW5nPgoJCTwvU2V0dGluZz4KCTwvQ29uZmlnSXRlbT4KCTxDb25maWdJdGVtIE5hbWU9IlRpY2tldEpJUkEjIyNPVFJTVGlja2V0QWxsb3dlZFN0YXRlczRKaXJhIiBSZXF1aXJlZD0iMSIgVmFsaWQ9IjEiPgoJCTxEZXNjcmlwdGlvbiBMYW5nPSJlbiI+VGhlIG5hbWVzIG9mIHRoZSBPVFJTIFRpY2tldCBzdGF0ZXMgdGhhdCBhbGxvdyB0aGUgY3JlYXRpb24gb2YgYSBKSVJBIElzc3VlLjwvRGVzY3JpcHRpb24+CgkJPERlc2NyaXB0aW9uIExhbmc9ImRlIj5EaWUgTmFtZW4gZGVyIE9UUlMgVGlja2V0IFp1c3TDpG5kZSBkaWUgZGFzIEVyemV1Z2VuIGVpbmVzIEpJUkEgSXNzdWUgenVsYXNzZW4uPC9EZXNjcmlwdGlvbj4KCQk8R3JvdXA+RnJhbWV3b3JrPC9Hcm91cD4KCQk8U3ViR3JvdXA+Q29yZTo6U09BUDwvU3ViR3JvdXA+CgkJPFNldHRpbmc+CgkJCTxTdHJpbmc+bmV3LG9wZW4sbWVyZ2VkLHBlbmRpbmcgcmVtaW5kZXI8L1N0cmluZz4KCQk8L1NldHRpbmc+Cgk8L0NvbmZpZ0l0ZW0+Cgk8Q29uZmlnSXRlbSBOYW1lPSJUaWNrZXRKSVJBIyMjT1RSU1RpY2tldEFsbG93ZWRTdGF0ZXM0Q2xvc2UiIFJlcXVpcmVkPSIxIiBWYWxpZD0iMSI+CgkJPERlc2NyaXB0aW9uIExhbmc9ImVuIj5UaGUgbmFtZXMgb2YgdGhlIE9UUlMgVGlja2V0IHN0YXRlcyB0aGF0IGFsbG93IHRoZSBjbG9zaW5nIG9mIGEgSklSQSBJc3N1ZS48L0Rlc2NyaXB0aW9uPgoJCTxEZXNjcmlwdGlvbiBMYW5nPSJkZSI+RGllIE5hbWVuIGRlciBPVFJTIFRpY2tldCBadXN0w6RuZGUgZGllIGRhcyBTY2hsaWXDn2VuIGVpbmVzIEpJUkEgSXNzdWUgenVsYXNzZW4uPC9EZXNjcmlwdGlvbj4KCQk8R3JvdXA+RnJhbWV3b3JrPC9Hcm91cD4KCQk8U3ViR3JvdXA+Q29yZTo6U09BUDwvU3ViR3JvdXA+CgkJPFNldHRpbmc+CgkJCTxTdHJpbmc+Y2xvc2VkIHN1Y2Nlc3NmdWwsY2xvc2VkIHVuc3VjY2Vzc2Z1bCxyZW1vdmVkPC9TdHJpbmc+CgkJPC9TZXR0aW5nPgoJPC9Db25maWdJdGVtPgoJPENvbmZpZ0l0ZW0gTmFtZT0iVGlja2V0OjpGcm9udGVuZDo6QWdlbnRUaWNrZXRTZWFyY2gjIyNEeW5hbWljRmllbGQiIFJlcXVpcmVkPSIxIiBWYWxpZD0iMSI+CgkJPEdyb3VwPlRpY2tldDwvR3JvdXA+CgkJPFN1Ykdyb3VwPkZyb250ZW5kOjpBZ2VudDo6VGlja2V0OjpWaWV3U2VhcmNoPC9TdWJHcm91cD4KCQk8U2V0dGluZz4KCQkJPEhhc2g+CgkJCQk8SXRlbSBLZXk9IktleSI+SklSQUlzc3VlSUQ8L0l0ZW0+CgkJCQk8SXRlbSBLZXk9IkNvbnRlbnQiPjE8L0l0ZW0+CgkJCTwvSGFzaD4KCQk8L1NldHRpbmc+Cgk8L0NvbmZpZ0l0ZW0+Cgk8Q29uZmlnSXRlbSBOYW1lPSJUaWNrZXQ6OkZyb250ZW5kOjpBZ2VudFRpY2tldFpvb20jIyNEeW5hbWljRmllbGQiIFJlcXVpcmVkPSIxIiBWYWxpZD0iMSI+CgkJPEdyb3VwPlRpY2tldDwvR3JvdXA+CgkJPFN1Ykdyb3VwPkZyb250ZW5kOjpBZ2VudDo6VGlja2V0OjpWaWV3Wm9vbTwvU3ViR3JvdXA+CgkJPFNldHRpbmc+CgkJCTxIYXNoPgoJCQkJPEl0ZW0gS2V5PSJLZXkiPkpJUkFJc3N1ZUlEPC9JdGVtPgoJCQkJPEl0ZW0gS2V5PSJDb250ZW50Ij4xPC9JdGVtPgoJCQk8L0hhc2g+CgkJPC9TZXR0aW5nPgoJPC9Db25maWdJdGVtPgoJPENvbmZpZ0l0ZW0gTmFtZT0iVGlja2V0OjpFdmVudE1vZHVsZVBvc3QjIyMwMDEtVGlja2V0QXJ0aWNsZUNsb3NlSklSQVVwZGF0ZSIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KCQk8RGVzY3JpcHRpb24gVHJhbnNsYXRhYmxlPSIxIj5VcGRhdGUgSklSQSBvbmNlIHRoZSB0aWNrZXQgaXMgY2xvc2VkLjwvRGVzY3JpcHRpb24+CgkJPEdyb3VwPlRpY2tldDwvR3JvdXA+CgkJPFN1Ykdyb3VwPkNvcmU6OlRpY2tldDwvU3ViR3JvdXA+CgkJPFNldHRpbmc+CgkJCTxIYXNoPgoJCQkJPEl0ZW0gS2V5PSJNb2R1bGUiPktlcm5lbDo6U3lzdGVtOjpUaWNrZXQ6OkV2ZW50OjpDbG9zZUpJUkFJc3N1ZTwvSXRlbT4KCQkJCTxJdGVtIEtleT0iRXZlbnQiPlRpY2tldFN0YXRlVXBkYXRlPC9JdGVtPgoJCQk8L0hhc2g+CgkJPC9TZXR0aW5nPgoJPC9Db25maWdJdGVtPgoJPENvbmZpZ0l0ZW0gTmFtZT0iVGlja2V0SklSQSMjI1Byb2plY3QiIFJlcXVpcmVkPSIxIiBWYWxpZD0iMSI+CgkJPERlc2NyaXB0aW9uIExhbmc9ImVuIj5UaGUgbmFtZSBvZiB0aGUgcHJvamVjdCB0byB1c2UgZm9yIHRoZSBuZXcgSklSQSBpc3N1ZXMuPC9EZXNjcmlwdGlvbj4KCQk8RGVzY3JpcHRpb24gTGFuZz0iZGUiPkRlciBOYW1lIGRlcyBQcm9qZWt0ZXMgZsO8ciBuZXVlIEpJUkEgSXNzdWVzLjwvRGVzY3JpcHRpb24+CgkJPEdyb3VwPkZyYW1ld29yazwvR3JvdXA+CgkJPFN1Ykdyb3VwPkNvcmU6OlNPQVA8L1N1Ykdyb3VwPgoJCTxTZXR0aW5nPgoJCQk8U3RyaW5nIFJlZ2V4PSIiPk9UUlM8L1N0cmluZz4KCQk8L1NldHRpbmc+Cgk8L0NvbmZpZ0l0ZW0+Cgk8Q29uZmlnSXRlbSBOYW1lPSJUaWNrZXRKSVJBIyMjSXNzdWVUeXBlIiBSZXF1aXJlZD0iMSIgVmFsaWQ9IjEiPgoJCTxEZXNjcmlwdGlvbiBMYW5nPSJlbiI+VGhlIG5hbWUgb2YgdGhlIHR5cGUgdG8gdXNlIGZvciB0aGUgbmV3IEpJUkEgaXNzdWVzLjwvRGVzY3JpcHRpb24+CgkJPERlc2NyaXB0aW9uIExhbmc9ImRlIj5EZXIgTmFtZSBkZXMgVHlwIGbDvHIgbmV1ZSBKSVJBIElzc3Vlcy48L0Rlc2NyaXB0aW9uPgoJCTxHcm91cD5GcmFtZXdvcms8L0dyb3VwPgoJCTxTdWJHcm91cD5Db3JlOjpTT0FQPC9TdWJHcm91cD4KCQk8U2V0dGluZz4KCQkJPFN0cmluZyBSZWdleD0iIj5CdWc8L1N0cmluZz4KCQk8L1NldHRpbmc+Cgk8L0NvbmZpZ0l0ZW0+Cgk8Q29uZmlnSXRlbSBOYW1lPSJUaWNrZXRKSVJBIyMjSklSQS1EYXRlRm9ybWF0IiBSZXF1aXJlZD0iMSIgVmFsaWQ9IjEiPgoJCTxEZXNjcmlwdGlvbiBMYW5nPSJlbiI+RGF0dW1zIGZvcm1hdCB1c2VkIGluIEpJUkE6IFRULW1tLVlZIEhIOk1NIG9yIFlZWVktbW0tVFQgSEg6TU08L0Rlc2NyaXB0aW9uPgoJCTxEZXNjcmlwdGlvbiBMYW5nPSJkZSI+RGFzIHZvbiBKSVJBIGFremVwdGllcnRlIERhdHVtc2Zvcm1hdDogVFQtbW0tSkogSEg6TU0gb2RlciBKSkpKLW1tLVRUIEhIOk1NPC9EZXNjcmlwdGlvbj4KCQk8R3JvdXA+RnJhbWV3b3JrPC9Hcm91cD4KCQk8U3ViR3JvdXA+Q29yZTo6U09BUDwvU3ViR3JvdXA+CgkJPFNldHRpbmc+CgkJCTxTdHJpbmcgUmVnZXg9IiI+VFQtbW0tWVkgSEg6TU08L1N0cmluZz4KCQk8L1NldHRpbmc+Cgk8L0NvbmZpZ0l0ZW0+Cgk8Q29uZmlnSXRlbSBOYW1lPSJUaWNrZXRKSVJBIyMjT1RSUy1KSVJBLUZpZWxkTWFwcGluZyIgUmVxdWlyZWQ9IjEiIFZhbGlkPSIxIj4KCQk8RGVzY3JpcHRpb24gTGFuZz0iZW4iPk1hcHBpbmcgZnJvbSBPVFJTIGZpZWxkcyB0byBKSVJBIEZpZWxkcy4gS2V5OiBPVFJTOyBDb250ZW50OiBKSVJBLiBQcmVmaXhlczogInN0ZDoiID0gc3RhbmRhcmQgZmllbGQ7ICJkeW46IiA9IE9UUlMgZHluYW1pYyBmaWVsZDsgImN1c3Q6IiA9IEpJUkEgY3VzdG9tIGZpZWxkOyAiY2FsbDoiID0gT1RSUy9KSVJBIG1hcHBpbmcgY2FsbCB3aXRoIGZ1bGwgUGVybCBtb2R1bGVwYXRoIChQa2c6OlN1Yjo6ZnVuYykuPC9EZXNjcmlwdGlvbj4KCQk8RGVzY3JpcHRpb24gTGFuZz0iZGUiPkFiYmlsZHVuZyBkZXIgT1RSUyBGZWxkZXJuIHp1IGRlbiBKSVJBIEZlbGRlcm4uIFNjaGzDvHNzZWw6IE9UUlM7IEluaGFsdDogSklSQS4gUHLDpGZpeGU6ICJzdGQ6IiA9IFN0YW5kYXJkIEZlbGQ7ICJkeW46IiA9IE9UUlMgRHluYW1pYyBGZWxkOyAiY3VzdDoiID0gSklSQSBDdXN0b20gRmVsZDsgImNhbGw6IiA9IE9UUlMvSklSQSBNYXBwaW5nLUZ1bmt0aW9uc2F1ZnJ1ZiBtaXQgdm9sbGVtIFBlcmwgTW9kdWxlcGZhZCAoUGtnOjpTdWI6OmZ1bmMpLjwvRGVzY3JpcHRpb24+CgkJPEdyb3VwPkZyYW1ld29yazwvR3JvdXA+CgkJPFN1Ykdyb3VwPkNvcmU6OlNPQVA8L1N1Ykdyb3VwPgoJCTxTZXR0aW5nPgoJCQk8SGFzaD4KCQkJCTxJdGVtIEtleT0iZHluOmR5bmFtaWNGaWVsZDEiPmN1c3Q6Y3VzdG9tRmllbGQxPC9JdGVtPgoJCQkJPEl0ZW0gS2V5PSJkeW46amlyYV9wcmlvIj5zdGQ6cHJpb3JpdHk8L0l0ZW0+CgkJCQk8SXRlbSBLZXk9InN0ZDpUaXRsZSI+c3RkOnN1bW1hcnk8L0l0ZW0+CgkJCQk8SXRlbSBLZXk9InN0ZDpRdWV1ZSI+Y3VzdDpxdWV1ZTwvSXRlbT4KCQkJCTxJdGVtIEtleT0ibWFwOk1vZDo6U3ViTW9kOjpmdW5jIj5jdXN0OmZpZWxkMTwvSXRlbT4KCQkJCTxJdGVtIEtleT0iZHluOmR5bmFtaWNGaWVsZDIiPm1hcDpNb2Q6OlN1Yk1vZDo6ZnVuYzI8L0l0ZW0+CgkJCQk8SXRlbSBLZXk9Im1hcDpNb2Q6OlN1Yk1vZDo6ZnVuYzMiPm1hcDpNb2Q6OlN1Yk1vZDo6ZnVuYzQ8L0l0ZW0+CgkJCTwvSGFzaD4KCQk8L1NldHRpbmc+Cgk8L0NvbmZpZ0l0ZW0+Cjwvb3Ryc19jb25maWc+Cg==
IyAgLS0KIyAgS2VybmVsL1N5c3RlbS9UaWNrZXRKSVJBLnBtIC0gY29yZSBtb2R1bAojICBDb3B5cmlnaHQgKEMpICh5ZWFyKSAobmFtZSBvZiBhdXRob3IpIChlbWFpbCBvZiBhdXRob3IpCiMgIC0tCiMgICRJZDogd3JpdGluZy1vdHJzLWFwcGxpY2F0aW9uLnhtbCx2IDEuMSAyMDEwLzA4LzEzIDA4OjU5OjI4IG1nIEV4cCAkCiMgIC0tCiMgIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyAgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAgLS0KcGFja2FnZSBLZXJuZWw6OlN5c3RlbTo6VGlja2V0SklSQTsKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwp1c2UgU3dpdGNoOwp1c2UgS2VybmVsOjpTeXN0ZW06OlRpY2tldDsKdXNlIEtlcm5lbDo6U3lzdGVtOjpWYXJpYWJsZUNoZWNrIHF3KDphbGwpOwp1c2UgS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZDsKdXNlIEtlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGRWYWx1ZTsKdXNlIEtlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQ6OkJhY2tlbmQ6OkJhY2tlbmRDb21tb247CnVzZSBSRVNUOjpDbGllbnQ7CnVzZSBKSVJBOjpDbGllbnQ7CnVzZSBNSU1FOjpCYXNlNjQ7CgpzdWIgbmV3IHsKCW15ICggJFR5cGUsICVQYXJhbSApID0gQF87CgoJIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CglteSAkU2VsZiA9IHt9OwoJYmxlc3MoICRTZWxmLCAkVHlwZSApOwoKCSMgY2hlY2sgbmVlZGVkIG9iamVjdHMKCWZvciBteSAkT2JqZWN0ICgKCQlxdyhDb25maWdPYmplY3QgRW5jb2RlT2JqZWN0IExvZ09iamVjdCBUaW1lT2JqZWN0IE1haW5PYmplY3QgVGlja2V0T2JqZWN0IERCT2JqZWN0KQoJICApCgl7CgkJJFNlbGYtPnskT2JqZWN0fSA9ICRQYXJhbXskT2JqZWN0fSB8fCBkaWUgIkdvdCBubyAkT2JqZWN0ISI7Cgl9CgoJIyBjcmVhdGUgYWRkaXRpb25hbCBvYmplY3RzCgkkU2VsZi0+e0R5bmFtaWNGaWVsZE9iamVjdH0gPSBLZXJuZWw6OlN5c3RlbTo6RHluYW1pY0ZpZWxkLT5uZXcoICV7JFNlbGZ9ICk7CgkkU2VsZi0+e0R5bmFtaWNGaWVsZFZhbHVlT2JqZWN0fSA9CgkgIEtlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGRWYWx1ZS0+bmV3KCAleyRTZWxmfSApOwoJJFNlbGYtPntCYWNrZW5kQ29tbW9uT2JqZWN0fSA9CgkgIEtlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQ6OkJhY2tlbmQ6OkJhY2tlbmRDb21tb24tPm5ldyggJXskU2VsZn0gKTsKCXJldHVybiAkU2VsZjsKfQoKPWl0ZW0gQ3JlYXRlSklSQUlzc3VlKCkKCmNyZWF0ZXMgYW4gaXNzdWUgaW4gdGhlIGNvbmZpZ3VyZWQgSklSQSBzeXN0ZW0gdXNpbmcgU09BUAoKICAgIG15ICRpc3N1ZSA9ICRUaWNrZXRKSVJBT2JqZWN0LT5DcmVhdGVKSVJBSXNzdWUoCiAgICAgICAgVGlja2V0SUQgICAgICAgPT4gJFRpY2tldElELCAgICAgICAgICAgICAgICAgICMgdGhlIFRpY2tldElELCBtYW5kYXRvcnkKICAgICk7CgogICAgcmV0dXJuczoKCiAgICAkaXNzdWUgPSB7CiAgICAgICAgaWQgPT4gMTAwMDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgaXNzdWUgaWQgaW4gSklSQSwgc3RhcnRzIGZyb20gMTAwMDAKICAgICAgICBrZXkgPT4gUFJPSi0xLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBpc3N1ZSBrZXkgYXMgdXNlZCBpbiB0aGUgd2ViaW50ZXJmYWNlLCA8UHJvaj4tPE51bWJlcj4sIHN0YXJ0cyBmcm9tIDEKICAgICAgICBbLi4uXSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBwbGVudHkgb2Ygb3RoZXIgZmllbGRzIGFzIGRlZmluZWQgaW4gdGhlIEFQSQogICAgfQo9Y3V0CgpzdWIgQ3JlYXRlSklSQUlzc3VlIHsKCW15ICggJFNlbGYsICRUaWNrZXRJRCwgJFVzZXJJRCApID0gQF87CglteSAlVGlja2V0ID0gJFNlbGYtPntUaWNrZXRPYmplY3R9LT5UaWNrZXRHZXQoCgkJVGlja2V0SUQgICAgICA9PiAkVGlja2V0SUQsCgkJRHluYW1pY0ZpZWxkcyA9PiAxCgkpOwoJbXkgJUFydGljbGUgPSAkU2VsZi0+e1RpY2tldE9iamVjdH0tPkFydGljbGVGaXJzdEFydGljbGUoCgkJVGlja2V0SUQgICAgICA9PiAkVGlja2V0SUQsCgkJRHluYW1pY0ZpZWxkcyA9PiAwLAoJKTsKCSRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAoJCVByaW9yaXR5ID0+ICdpbmZvJywKCQlNZXNzYWdlID0+CiJLZXJuZWw6OlN5c3RlbTo6VGlja2V0SklSQTo6Q3JlYXRlSklSQUlzc3VlOiBUaWNrZXRJRDogJFRpY2tldElEID09ICRUaWNrZXR7VGlja2V0SUR9IFRpdGxlOiAkVGlja2V0e1RpdGxlfSBUZXh0OiAkQXJ0aWNsZXtCb2R5fSIKCSk7CglteSAkdXJsICAgICAgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnVGlja2V0SklSQScpLT57VVJMfTsKCW15ICR1c2VyICAgICA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdUaWNrZXRKSVJBJyktPntVc2VyfTsKCW15ICRwYXNzd29yZCA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdUaWNrZXRKSVJBJyktPntQYXNzd29yZH07CglteSAkcmVwb3J0ZXIgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnVGlja2V0SklSQScpLT57UmVwb3J0ZXJ9OwoJbXkgJGFzc2lnbmVlID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ1RpY2tldEpJUkEnKS0+e0Fzc2lnbmVlfTsKCgkjIHJlYWQgJ1Byb2plY3QnIGZlbGQgZnJvbSAgIlN5c0NvbmZpZyIgaW4gT1RSUwoJbXkgJHByb2plY3QgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnVGlja2V0SklSQScpLT57UHJvamVjdH07CgoJIyByZWFkICdJc3N1ZVR5cGUnIGZlbGQgZnJvbSAgIlN5c0NvbmZpZyIgaW4gT1RSUwoJbXkgJGlzc3VlVHlwZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdUaWNrZXRKSVJBJyktPntJc3N1ZVR5cGV9OwoJbXkgJGppcmEgPSBKSVJBOjpDbGllbnQtPm5ldyggJHVybCwgJHVzZXIsICRwYXNzd29yZCApOwoJbXkgJER5bmFtaWNGaWVsZCA9CgkgICRTZWxmLT57RHluYW1pY0ZpZWxkT2JqZWN0fS0+RHluYW1pY0ZpZWxkR2V0KCBOYW1lID0+ICdKSVJBSXNzdWVJRCcgKTsKCW15ICRqaXJhSXNzdWVJZCA9ICRTZWxmLT57RHluYW1pY0ZpZWxkVmFsdWVPYmplY3R9LT5WYWx1ZUdldCgKCQlGaWVsZElEICA9PiAkRHluYW1pY0ZpZWxkLT57SUR9LAoJCU9iamVjdElEID0+ICRUaWNrZXR7VGlja2V0SUR9LAoJKTsKCSRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAoJCVByaW9yaXR5ID0+ICdpbmZvJywKCQlNZXNzYWdlID0+CiJLZXJuZWw6OlN5c3RlbTo6VGlja2V0SklSQTo6Q3JlYXRlSklSQUlzc3VlOiBKSVJBSXNzdWVJRChwcmUpOiAnJGppcmFJc3N1ZUlkJyAvLyAnJGppcmFJc3N1ZUlkLT5bMF0nIC8vICckamlyYUlzc3VlSWQtPlswXS0+e1ZhbHVlVGV4dH0nIER5bmFtaWNGaWVsZElEOiAkRHluYW1pY0ZpZWxkLT57SUR9ICIKCSk7CglteSAkaXNzdWUgPSB7fTsKCglpZiAoICAgICRqaXJhSXNzdWVJZAoJCWFuZCAkamlyYUlzc3VlSWQtPlswXQoJCWFuZCBkZWZpbmVkKCAkamlyYUlzc3VlSWQtPlswXS0+e1ZhbHVlVGV4dH0gKQoJCWFuZCAkamlyYUlzc3VlSWQtPlswXS0+e1ZhbHVlVGV4dH0gbmUgIiIgKQoJewoJCSRpc3N1ZSA9IGV2YWwgeyAkamlyYS0+Z2V0SXNzdWUoICRqaXJhSXNzdWVJZC0+WzBdLT57VmFsdWVUZXh0fSApIH07ICMgd2VpcmQgYnV0IGZvdW5kIGluIHRoZSBQT0QKCX0gZWxzZSB7CgkJIyBGSVhNRTogc2VwYXJhdGUgc3RhbmRhcmQgYW5kIGR5bmFtaWMgZmllbGRzIGFzIHdlbGwgYXMgY2FsbHMKCQlteSAkamlyYUNyZWF0ZVBhcmFtcyA9IHsKCQkJCXByb2plY3QgICAgICAgPT4gJHByb2plY3QsCgkJCQl0eXBlICAgICAgICAgID0+ICRpc3N1ZVR5cGUsCgkJCQlzdW1tYXJ5ICAgICAgID0+ICRUaWNrZXR7VGl0bGV9LAoJCQkJZGVzY3JpcHRpb24gICA9PiAkQXJ0aWNsZXtCb2R5fSwKCQkJCWFzc2lnbmVlICAgICAgPT4gJHJlcG9ydGVyLAoJCQkJcmVwb3J0ZXIgICAgICA9PiAkYXNzaWduZWUsCgkJCQljdXN0b21fZmllbGRzID0+IHtPVFJTVGlja2V0SUQgPT4gJFRpY2tldElEfSwJCQkJCgkJfTsKCQkkamlyYUNyZWF0ZVBhcmFtcyA9ICRTZWxmLT5tYXBGaWVsZHMoJGppcmFDcmVhdGVQYXJhbXMsJVRpY2tldCk7CgkJCgkJJGlzc3VlID0gJGppcmEtPmNyZWF0ZV9pc3N1ZSggJGppcmFDcmVhdGVQYXJhbXMgKTsKCiAgICAgICAgIyBUaGUgZm9sbG93aW5nIGNvZGUgZnJhZ2VtZW50IHRyYW5zcG9ydHMgYXR0YWNobWVudHMgYWxvbmcgd2l0aCB0aGUgaXNzdWUKICAgICAgICAjIGdldCB0aGUgbGlzdCBvZiB0aGUgYXR0YWNobWVudHMKCQlteSAlSW5kZXggPSAkU2VsZi0+e1RpY2tldE9iamVjdH0tPkFydGljbGVBdHRhY2htZW50SW5kZXgoCgkJCUFydGljbGVJRCA9PiAkQXJ0aWNsZXtBcnRpY2xlSUR9LAoJCQlVc2VySUQgICAgPT4gJFVzZXJJRCwKCQkpOwoKCQkjIGdldCBJRCBvZiBlYWNoIGF0dGFjaG1lbnQgZmlsZSwgdGhlbiB0aGUgY29ycmVzcG9uZGluZyBhdHRhY2htZW50IGZpbGUKCQl3aGlsZSAoIG15ICggJEZpbGVJRCwgJGF0dGFjaEggKSA9IGVhY2ggJUluZGV4ICkgewoJCQkjIHJldHJpZXZlIHRoZSBuYW1lIGFuZCBjb250ZW50IG9mIGVhY2ggYXR0YWNobWVudCBmaWxlLAoJCQkjIHN0b3JlIHRoZW0gaW50byBAZmlsZW5hbWVzIGFuZCBAYXR0YWNobWVudHMgcmVzcGVjdGl2ZWx5LgoJCQlteSBAZmlsZW5hbWVzOwoJCQlteSBAYXR0YWNobWVudHM7CgoJCQlteSAlQXR0YWNobWVudCA9ICRTZWxmLT57VGlja2V0T2JqZWN0fS0+QXJ0aWNsZUF0dGFjaG1lbnQoCgkJCQlBcnRpY2xlSUQgPT4gJEFydGljbGV7QXJ0aWNsZUlEfSwKCQkJCUZpbGVJRCAgICA9PiAkRmlsZUlELAoJCQkJVXNlcklEICAgID0+ICRVc2VySUQsCgkJCSk7CgkJCXB1c2ggQGZpbGVuYW1lcywgJEF0dGFjaG1lbnR7RmlsZW5hbWV9OwoKCQkJIyBlbmNvZGUgZmlsZSBjb250ZW50cyB0byBCYXNlNjQuCgkJCXJlcXVpcmUgTUlNRTo6QmFzZTY0OwoJCQlwdXNoIEBhdHRhY2htZW50cywKCQkJICBNSU1FOjpCYXNlNjQ6OmVuY29kZV9iYXNlNjQoICRBdHRhY2htZW50e0NvbnRlbnR9ICk7CgoJCQkjIHNlbmQgdGhlIGF0dGFjaG1lbnRzIGFsb25nIHdpdGggdGhlIGlzc3VlCgkJCSRqaXJhLT5hZGRCYXNlNjRFbmNvZGVkQXR0YWNobWVudHNUb0lzc3VlKCAkaXNzdWUsIFxAZmlsZW5hbWVzLAlcQGF0dGFjaG1lbnRzICk7CgkJfQoKCQkjIGVuZCBvZiB0cmFuc3BvcnRpbmcgYXR0YWNobWVudHMKCQlteSAkU3VjY2VzcyA9ICRTZWxmLT57RHluYW1pY0ZpZWxkVmFsdWVPYmplY3R9LT5WYWx1ZVNldCgKCQkJRmllbGRJRCAgPT4gJER5bmFtaWNGaWVsZC0+e0lEfSwKCQkJT2JqZWN0SUQgPT4gJFRpY2tldHtUaWNrZXRJRH0sCgkJCVZhbHVlICAgID0+IFsgeyBWYWx1ZVRleHQgPT4gJGlzc3VlLT57a2V5fSB9LCBdLAoJCQlVc2VySUQgICA9PiAkVXNlcklELAoJCSk7CgkJJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCgkJCVByaW9yaXR5ID0+ICdpbmZvJywKCQkJTWVzc2FnZSA9PgoiS2VybmVsOjpTeXN0ZW06OlRpY2tldEpJUkE6OkNyZWF0ZUpJUkFJc3N1ZTogSklSQUlzc3VlSUQocG9zdCk6ICRpc3N1ZS0+e2tleX0gRHluYW1pY0ZpZWxkSUQ6ICREeW5hbWljRmllbGQtPntJRH0gIgoJCSk7CgkJJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCgkJCVByaW9yaXR5ID0+ICdpbmZvJywKCQkJTWVzc2FnZSA9PgoJCQkgICJLZXJuZWw6OlN5c3RlbTo6VGlja2V0SklSQTo6Q3JlYXRlSklSQUlzc3VlOiBTdWNjZXNzOiAkU3VjY2VzcyIKCQkpOwoJCW15ICRoZWFkZXJzID0gewoJCQlBY2NlcHQgICAgICAgID0+ICdhcHBsaWNhdGlvbi9qc29uJywKCQkJQXV0aG9yaXphdGlvbiA9PiAnQmFzaWMgJwoJCQkgIC4gZW5jb2RlX2Jhc2U2NCggJHVzZXIgLiAnOicgLiAkcGFzc3dvcmQgKSwKCQkJIkNvbnRlbnQtdHlwZSIgPT4gJ2FwcGxpY2F0aW9uL2pzb24nCgkJfTsKCQlteSAkY2xpZW50ID0gUkVTVDo6Q2xpZW50LT5uZXcoKTsKCQlteSAkYm9keSA9CgkJICAgICd7ICJvYmplY3QiOiB7ICAidXJsIjoiJwoJCSAgLiAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSHR0cFR5cGUnKSAuICI6Ly8iCgkJICAuICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdGUUROJykKCQkgIC4gJy9vdHJzL2luZGV4LnBsP0FjdGlvbj1BZ2VudFRpY2tldFpvb207VGlja2V0SUQ9JwoJCSAgLiAkVGlja2V0SUQKCQkgIC4gJyIsICAidGl0bGUiOiJPVFJTIFRpY2tldCMnCgkJICAuICRUaWNrZXR7VGlja2V0TnVtYmVyfSAuICcgKCcKCQkgIC4gJFRpY2tldElECgkJICAuICcpIiAgfSB9JzsKCQlteSAoICRwcm90bywgJG5pbCwgJGhvc3QsIEBiYXNldXJsICkgPSBzcGxpdCggJy8nLCAkdXJsICk7CgkJbXkgJHBvc3R1cmwgPSAnLycKCQkgIC4gam9pbiggJy8nLCBAYmFzZXVybCApCgkJICAuICcvcmVzdC9hcGkvbGF0ZXN0L2lzc3VlLycKCQkgIC4gJGlzc3VlLT57a2V5fQoJCSAgLiAnL3JlbW90ZWxpbmsnOwoJCSRwb3N0dXJsID1+IHMvXC9cLy9cLy9nOwoJCSRjbGllbnQtPnNldEhvc3QoIiRwcm90by8vJGhvc3QiKTsKCQkkY2xpZW50LT5QT1NUKCAkcG9zdHVybCwgJGJvZHksICRoZWFkZXJzICk7CgkJJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCgkJCVByaW9yaXR5ID0+ICdpbmZvJywKCQkJTWVzc2FnZSA9PgoiS2VybmVsOjpTeXN0ZW06OlRpY2tldEpJUkE6OkNyZWF0ZUpJUkFJc3N1ZTogUkVTVDogaG9zdCAkcHJvdG8vLyRob3N0IHBvc3R1cmwgJHBvc3R1cmwga2V5ICRpc3N1ZS0+e2tleX0gaWQgJFRpY2tldElEIgoJCSk7CgkJJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCgkJCVByaW9yaXR5ID0+ICdpbmZvJywKCQkJTWVzc2FnZSA9PgoJCQkgICJLZXJuZWw6OlN5c3RlbTo6VGlja2V0SklSQTo6Q3JlYXRlSklSQUlzc3VlOiBSRVNUOiBib2R5ICRib2R5IgoJCSk7CgkJJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCgkJCVByaW9yaXR5ID0+ICdpbmZvJywKCQkJTWVzc2FnZSA9PgoJCQkgICJLZXJuZWw6OlN5c3RlbTo6VGlja2V0SklSQTo6Q3JlYXRlSklSQUlzc3VlOiBSRVNUOiByZXNwb25zZUNvZGUgIgoJCQkgIC4gJGNsaWVudC0+cmVzcG9uc2VDb2RlKCkKCQkJICAuICIgcmVzcG9uc2VDb250ZW50ICIKCQkJICAuICRjbGllbnQtPnJlc3BvbnNlQ29udGVudCgpCgkJKTsKCX0KCXJldHVybiAkaXNzdWU7Cn0KCj1pdGVtIG1hcEZpZWxkcwpNYXBzIHRoZSBPVFJTIHRvIHRoZSBKSVJBIGN1c3RvbSBmaWVsZHMgYXMgZGVmaW5lZCBpbiB0aGUgY29uZmlndXJhdGlvbi4KUmV0dXJucyBhIGhhc2ggbWFwLgoKbXkgJGZpZWxkcyA9IG1hcEZpZWxkcyAoJFNlbGYsICRmaWVsZHMsICVUaWNrZXQpCgkKcmV0dXJuOgoKJGZpZWxkcyA9IHsKCXN0YW5kYXJkRmllbGQxID0+IHZhbHVlMSwKCXN0YW5kYXJkRmllbGQyID0+IHZhbHVlMiwKCVsuLi5dCgljdXN0b21maWVsZHMgPT4gewoJCWNmMSA9PiB2YWx1ZTMsCgkJY2YyID0+IHZhbHVlNCwKCQlbLi4uXQoJfQp9Cgo9Y3V0CgpzdWIgbWFwRmllbGRzIHsKCW15ICggJFNlbGYsICRmaWVsZHMsICVUaWNrZXQgKSA9IEBfOwoJIyByZXRyaWV2ZXMgZHluYW1pYy1jdXN0b20gZmllbGQgbWFwcGluZwoJbXkgJGN1c3RvbUZpZWxkcyA9IHt9OwoJbXkgJG1hcHBpbmcgICAgICA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdUaWNrZXRKSVJBJyktPnsnT1RSUy1KSVJBLUZpZWxkTWFwcGluZyd9OwoJbXkgJGRhdGVGb3JtYXQgICA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdUaWNrZXRKSVJBJyktPnsnSklSQS1EYXRlZm9ybWF0J307CgkKCWlmICggZGVmaW5lZCAkbWFwcGluZyApIHsKCQkKCQl3aGlsZSAoIG15ICgka2V5LCAkdmFsKSA9IGVhY2ggJG1hcHBpbmcgKSB7CgkJCW15ICgka3ByZWZpeCwkdnByZWZpeCwkZGJ2YWwpID0gKCIiLCIiLHVuZGVmKTsKCQkJbXkgJGlzQURhdGUgPSAwOwoJCQkoJGtwcmVmaXgsJGtleSkgPSBzcGxpdCgvOi8sJGtleSwyKTsKCQkJKCR2cHJlZml4LCR2YWwpID0gc3BsaXQoLzovLCR2YWwsMik7CgkJCXN3aXRjaCAoJGtwcmVmaXgpIHsKCQkJCWNhc2UgL15zdGQ6LyAgeyAKCQkJCQkkZGJ2YWwgPSAkVGlja2V0eyRrZXl9OwoJCQkJCXN3aXRjaCAoJGtleSkgewoJCQkJCQljYXNlICJDcmVhdGVkIiB7ICRpc0FEYXRlID0gMTsgfQoJCQkJCQljYXNlICJDaGFuZ2VkIiB7ICRpc0FEYXRlID0gMTsgfQoJCQkJCQljYXNlIC9EYXRlJC8gICB7ICRpc0FEYXRlID0gMTsgfQoJCQkJCX0KCQkJCX0KCQkJCWNhc2UgL15keW46LyAgewoJCQkJCW15ICRkeW5GaWVsZCAgPSAkU2VsZi0+e0R5bmFtaWNGaWVsZE9iamVjdH0tPkR5bmFtaWNGaWVsZEdldCggTmFtZSA9PiAka2V5ICk7CgkJCQkJbXkgJGZpZWxkVHlwZSA9ICRTZWxmLT57RHluYW1pY0ZpZWxkT2JqZWN0fS0+RHluYW1pY0ZpZWxkR2V0KCBOYW1lID0+ICRrZXkgKS0+e0ZpZWxkVHlwZX07CgkJCQkJJGRidmFsID0gJFNlbGYtPntEeW5hbWljRmllbGRWYWx1ZU9iamVjdH0tPlZhbHVlR2V0KCBGaWVsZElEID0+ICRkeW5GaWVsZC0+e0lEfSwgT2JqZWN0SUQgPT4gJFRpY2tldHtUaWNrZXRJRH0gKTsKCQkJCQlzd2l0Y2ggKCRmaWVsZFR5cGUpIHsKCQkJCQkgCWNhc2UgIkRhdGUiICAgICAgeyAkaXNBRGF0ZSA9IDE7IH0KCQkJCQkgCWNhc2UgIkRhdGUvVGltZSIgeyAkaXNBRGF0ZSA9IDE7IH0KCQkJCQl9CgkJCQl9CgkJCQljYXNlIC9eY2FsbDovIHsgCgkJCQkJbXkgKCRtb2R1bGUsJGZ1bmN0aW9uKSA9IHNwbGl0ICgvLC8sJGtwcmVmaXgpOyAjIGNhbGxzIG11c3QgYmUgc3BlY2lmaWVkIGFzIHRoaXM6IGUuZy4gIk1JTUU6OkJhc2U2NCxlbmNvZGVfYmFzZTY0IgoJCQkJCWV2YWwoInVzZSAkbW9kdWxlOyIpOwoJCQkJCSRkYnZhbCA9IGV2YWwoIiRmdW5jdGlvbigkU2VsZiwka2V5KSIpOwoJCQkJfQoJCQl9CgkJCWlmICggJGlzQURhdGUgPT0gMSApIHsKCQkJCSRkYnZhbCA9ICRTZWxmLT5kYXRlRm9ybWF0VHJhbnNmb3JtKCAkZGF0ZUZvcm1hdCwgJGRidmFsICk7CgkJCX0KCQkJc3dpdGNoICgkdnByZWZpeCkgewoJCQkJY2FzZSAvXnN0ZDovICB7ICRmaWVsZHMtPnskdmFsfSA9ICRkYnZhbDsgfQoJCQkJY2FzZSAvXmN1c3Q6LyB7ICRmaWVsZHMtPntjdXN0b21fZmllbGRzfS0+eyR2YWx9ID0gJGRidmFsOyB9CgkJCQljYXNlIC9eY2FsbDovIHsgCgkJCQkJbXkgKCRtb2R1bGUsJGZ1bmN0aW9uKSA9IHNwbGl0ICgvLC8sJHZwcmVmaXgpOyAjIGNhbGxzIG11c3QgYmUgc3BlY2lmaWVkIGFzIHRoaXM6IGUuZy4gIk1JTUU6OkJhc2U2NCxlbmNvZGVfYmFzZTY0IgoJCQkJCWV2YWwoInVzZSAkbW9kdWxlOyIpOwoJCQkJCSRkYnZhbCA9IGV2YWwoIiRmdW5jdGlvbigkU2VsZiwkdmFsKSIpOwoJCQkJfQoJCQl9CgkJfQoJfQoJcmV0dXJuICRmaWVsZHM7Cn0KCj1pdGVtOiBUaGlzIGZ1bmN0aW9uIHRyYW5zZm9ybXMgdGhlIGRhdGUgdmFsdWUgb2YgYSBvdHJzLWN1c3RvbSBmaWVsZCB0byB0aGUgSmlyYSBmb3JtYXQKaXQgY2FuIHRyYW5zZm9ybSB0byBvbmUgb2YgdGhyZWUgZm9ybWF0czogVFQtbW0tWVkgSEg6TU0nLCAnWVlZWS1tbS1UVCBISDpNTScgYW5kICdkZC9NTS95eSBoaDptbScuCgpIb3dldmVyLCBpdCBzZWVtcyB0aGF0IHRoZXJlIGlzIGEgcHJvYmxlbSBpbiBKaXJhIGFib3V0IHRoZSB2YWxpZGF0aW9uIG9mIHRoZSBkYXRlIGZvcm1hdC4KV2hlbiBzZW5kaW5nIGEgZGF0ZSB3aXRoIGFueSBvZiB0aGVzZSBmb3JtYXRzICggYW5kIEkgYWxzbyB0cnkgYSBsb2Ygb2Ygb3RoZXIgZm9ybWF0cyksIAplYWNoIHRpbWUgSmlyYSByZXR1cm5zIGEgbWVzc2FnZTogIkdlYmVuIFNpZSBkYXMgRGF0dW0gaW0gRm9ybWF0ICdkZC9NTU0veXkgaDptbSBhJyBlaW4uIgpJIGV2ZW4gc2VuZCBzb21lIGRhdGUgdmFsdWVzIHdpdGggc3VjaCBmb3JtYXQsIGFuZCBKSVJBIHJldHVybnMgdGhlIHNhbWUgaW1lc3NhZ2UuCgpteSAkdmFsdWUxID0gZGF0ZUZvcm1hdFRyYW5zZm9ybSgkU2VsZiwgJ1RULW1tLVlZIEhIOk1NJywgICAnMjAwNC0wOC0xNCAyMjo0NTowMCcpCgpyZXR1cm5zICcxNC0wOC0wNCAyMjowNScKCj1jdXQKCnN1YiBkYXRlRm9ybWF0VHJhbnNmb3JtIHsKCW15ICggJFNlbGYsICRkYXRlRm9ybWF0LCAkdmFsdWUgKSA9IEBfOwoJaWYgKCAhZGVmaW5lZCgkdmFsdWUpIHx8ICggJHZhbHVlIGVxICIiICkgKSB7CgkJcmV0dXJuICIiOwoJfQoJbXkgJGZvcm1hdDEgPSAnZGRcL01NXC95eSBoaDptbSc7ICAgICMgZGQvTU0veXkgaGg6bW0KCW15ICRmb3JtYXQyID0gJ1RULW1tLVlZIEhIOk1NJzsKCW15ICRmb3JtYXQzID0gJ1lZWVktbW0tVFQgSEg6TU0nOwoJaWYgKCAgICEoICRkYXRlRm9ybWF0ID1+IC8kZm9ybWF0MS8gKQoJCSYmICEoICRkYXRlRm9ybWF0ID1+IC8kZm9ybWF0Mi8gKQoJCSYmICEoICRkYXRlRm9ybWF0ID1+IC8kZm9ybWF0My8gKSApCgl7CgkJJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCgkJCVByaW9yaXR5ID0+ICdpbmZvJywKCQkJTWVzc2FnZSA9PgoiU3lzQ29uZmlnLT5GcmFtZXdvcmstPkNvcmU6OlNPQVAtPlRpY2tldEpJUkEjIyNKSVJBLURhdGVmb3JtYXQgc2hvdWxkIGJlIFRULW1tLVlZIEhIOk1NIG9yIFlZWVktbW0tVFQgSEg6TU0iLAoJCSk7CgkJcmV0dXJuICIiOwoJfQoKCSMgZGF0ZSBmb3JtYXQ6IDIwMDQtMDgtMTQgb3IgMjAxMC8xMi8wMQoJbXkgJHZmMCA9ICdccz8oXGRcZFxkXGQpXHM/KC18XC8pXHM/KFxkXGQpXHM/KC18XC8pXHM/KFxkXGQpXHMrJzsKCgkjIGRhdGUgZm9ybWF0OiAyMDA0LTA4LTE0IDIyOjQ1OjAwLCAyMDEwLzEyLzAxIDEzOjQxOjA3CglteSAkdmYxID0gJHZmMCAuICcoXGRcZClccz86XHM/KFxkXGQpLj8nOwoJbXkgKCAkeWVhciwgJG1vbnRoLCAkZGF5LCAkaG91ciwgJG1pbnV0ZSApOwoJaWYgKCAkdmFsdWUgPX4gLyR2ZjEvICkgewoJCSR5ZWFyICAgPSAkMTsKCQkkbW9udGggID0gJDM7CgkJJGRheSAgICA9ICQ1OwoJCSRob3VyICAgPSAkNjsKCQkkbWludXRlID0gJDc7Cgl9IGVsc2UgewoJCSRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAoJCQlQcmlvcml0eSA9PiAnaW5mbycsCgkJCU1lc3NhZ2UgPT4KIkEgVGltZSBzaG91bGQgYmUgaW4gYSBmb3JtYXQgbGlrZSAyMDA0LTA4LTE0IDIyOjQ1OjAwIG9yIDIwMTAvMTIvMDEgMTM6NDE6MDciLAoJCSk7CgkJcmV0dXJuICIiOwoJfQoJaWYgKCAkZGF0ZUZvcm1hdCA9fiAvJGZvcm1hdDIvICkgewoJCSR5ZWFyID0gc3Vic3RyKCAkeWVhciwgMiApOwoJCXJldHVybiAkZGF5IC4gJy0nIC4gJG1vbnRoIC4gJy0nIC4gJHllYXIgLiAnICcgLiAkaG91ciAuICc6JyAuICRtaW51dGU7Cgl9CglpZiAoICRkYXRlRm9ybWF0ID1+IC8kZm9ybWF0My8gKSB7CgkJcmV0dXJuICR5ZWFyIC4gJy0nIC4gJG1vbnRoIC4gJy0nIC4gJGRheSAuICcgJyAuICRob3VyIC4gJzonIC4gJG1pbnV0ZTsKCX0KCWlmICggJGRhdGVGb3JtYXQgPX4gLyRmb3JtYXQxLyApIHsKCQlyZXR1cm4gJGRheSAuICcvJyAuICRtb250aCAuICcvJyAuICRkYXkgLiAnICcgLiAkaG91ciAuICc6JyAuICRtaW51dGU7Cgl9Cn0KMTsK
IyAgLS0KIyAgS2VybmVsL01vZHVsZXMvQWdlbnRUaWNrZXRKSVJBLnBtIC0gZnJvbnRlbmQgbW9kdWwKIyAgQ29weXJpZ2h0IChDKSAoeWVhcikgKG5hbWUgb2YgYXV0aG9yKSAoZW1haWwgb2YgYXV0aG9yKQojICAtLQojICAkSWQ6IHdyaXRpbmctb3Rycy1hcHBsaWNhdGlvbi54bWwsdiAxLjEgMjAxMC8wOC8xMyAwODo1OToyOCBtZyBFeHAgJAojICAtLQojICBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojICB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgIC0tCnBhY2thZ2UgS2VybmVsOjpNb2R1bGVzOjpBZ2VudFRpY2tldEpJUkE7CnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKdXNlIEtlcm5lbDo6U3lzdGVtOjpUaWNrZXRKSVJBOwpzdWIgbmV3IHsKICAgICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKICAgICAgIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CiAgICAgIG15ICRTZWxmID0geyVQYXJhbX07CiAgICAgIGJsZXNzICgkU2VsZiwgJFR5cGUpOwogICAgICAjIGNoZWNrIG5lZWRlZCBvYmplY3RzCiAgICAgIGZvciAocXcoUGFyYW1PYmplY3QgREJPYmplY3QgVGlja2V0T2JqZWN0IExheW91dE9iamVjdCBMb2dPYmplY3QgUXVldWVPYmplY3QgQ29uZmlnT2JqZWN0IEVuY29kZU9iamVjdCBNYWluT2JqZWN0IFN1YmFjdGlvbiBUaWNrZXRJRCkpIHsKICAgICAgICAgIGlmICggISRTZWxmLT57JF99ICkgewogICAgICAgICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+RmF0YWxFcnJvciggTWVzc2FnZSA9PiAiR290IG5vICRfISIgKTsKICAgICAgICAgIH0KICAgICAgfQogICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnaW5mbycsCiAgICAgICAgICAgICAgTWVzc2FnZSA9PiAnS2VybmVsOjpNb2R1bGVzOjpBZ2VudFRpY2tldEpJUkE6Om5ldygpOiBTdWJhY3Rpb249JyAuICRQYXJhbXtTdWJhY3Rpb259IC4gJyBUaWNrZXRJRD0nIC4gJFBhcmFte1RpY2tldElEfQogICAgICApOwogICAgICAjIGNyZWF0ZSBuZWVkZWQgb2JqZWN0cwogICAgICAkU2VsZi0+e1RpY2tldEpJUkFPYmplY3R9ID0gS2VybmVsOjpTeXN0ZW06OlRpY2tldEpJUkEtPm5ldyglUGFyYW0pOwogICAgICByZXR1cm4gJFNlbGY7Cn0Kc3ViIFJ1biB7CiAgICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CiAgICAgIG15ICVEYXRhID0gKCk7CiAgICAgIG15ICRUZW1wbGF0ZUZpbGUgPSAnQWdlbnRUaWNrZXRKSVJBJzsKICAgICAgIyBTdWJhY3Rpb24gPSBKSVJBMk9UUlMgfHwgT1RSUzJKSVJBCiAgICAgIG15ICVUaWNrZXQgPSAkU2VsZi0+e1RpY2tldE9iamVjdH0tPlRpY2tldEdldCgKICAgICAgICBUaWNrZXRJRCAgICAgID0+ICRTZWxmLT57VGlja2V0SUR9LAogICAgICAgIFVzZXJJRCAgICAgICAgPT4gJFNlbGYtPntVc2VySUR9LAogICAgICApOwogICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgIFByaW9yaXR5ID0+ICdpbmZvJywKICAgICAgICAgIE1lc3NhZ2UgPT4gIktlcm5lbDo6TW9kdWxlczo6QWdlbnRUaWNrZXRKSVJBOjpSdW4oKTogVGlja2V0SUQ6ICRUaWNrZXR7VGlja2V0SUR9IFRpdGxlOiAkVGlja2V0e1RpdGxlfSBTdGF0ZTogJFRpY2tldHtTdGF0ZX0iCiAgICAgICk7CiAgICAgIG15ICRhbGxvd2VkU3RhdGVzTmFtZXMgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnVGlja2V0SklSQScpLT57T1RSU1RpY2tldEFsbG93ZWRTdGF0ZXM0SmlyYX07CiAgICAgIG15IEBhbGxvd2VkU3RhdGVzTGlzdCA9IHNwbGl0KC8sLywkYWxsb3dlZFN0YXRlc05hbWVzKTsKCSAgaWYgKCBncmVwIHsgJF8gZXEgJFRpY2tldHtTdGF0ZX0gfSBAYWxsb3dlZFN0YXRlc0xpc3QgKSB7CgkgICAgICBteSAkSklSQUlzc3VlID0gJFNlbGYtPntUaWNrZXRKSVJBT2JqZWN0fS0+Q3JlYXRlSklSQUlzc3VlKCRTZWxmLT57VGlja2V0SUR9LCRTZWxmLT57VXNlcklEfSk7CgkgICAgICBteSAkdXJsID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ1RpY2tldEpJUkEnKS0+e1VSTH07CgkgICAgICAKCSAgICAgICREYXRhe2lkfSA9ICRKSVJBSXNzdWUtPntpZH07CgkgICAgICAkRGF0YXtrZXl9ID0gJEpJUkFJc3N1ZS0+e2tleX07CgkgICAgICAkRGF0YXt1cmx9ID0gIiR1cmwvYnJvd3NlLyIgLiAkSklSQUlzc3VlLT57a2V5fTsKCSAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgCVByaW9yaXR5ID0+ICdpbmZvJywKICAgICAgICAgIAlNZXNzYWdlID0+ICJLZXJuZWw6Ok1vZHVsZXM6OkFnZW50VGlja2V0SklSQTo6UnVuKCk6IFRpY2tldC0+U3RhdGUgJFRpY2tldHtTdGF0ZX0gYWxsb3dzIGZldGNoaW5nIG9mIHRoZSBKSVJBSXNzdWUtPmtleTogIiAuICRKSVJBSXNzdWUtPntrZXl9CiAgICAgICAgICApOwoJICB9IGVsc2UgewoJICAJICAkVGVtcGxhdGVGaWxlID0gJ0FnZW50VGlja2V0SklSQUVycm9yJzsKCSAgCSAgJERhdGF7ZXJyb3J9ID0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT57TGFuZ3VhZ2VPYmplY3R9LT5HZXQoIlRpY2tldCBub3QgaW4gJGFsbG93ZWRTdGF0ZXNOYW1lczogIiAuICRUaWNrZXR7U3RhdGV9IC4gIi4iKTsKCSAgCSAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2luZm8nLAogICAgICAgICAgICAgIE1lc3NhZ2UgPT4gIktlcm5lbDo6U3lzdGVtOjpUaWNrZXQ6OkV2ZW50OjpDbG9zZUpJUkFJc3N1ZTo6UnVuKCk6IE9UUlMgVGlja2V0IG5vdCBpbiAkYWxsb3dlZFN0YXRlc05hbWVzOiAiIC4gJFRpY2tldHtTdGF0ZX0KICAgCQkgICk7CgkgIH0KICAgICAgJERhdGF7VGlja2V0SUR9ID0gJFNlbGYtPntUaWNrZXRJRH07CiAgICAgICREYXRhe1RpY2tldE51bWJlcn0gPSAkVGlja2V0e1RpY2tldE51bWJlcn07CiAgICAgICMgYnVpbGQgb3V0cHV0CiAgICAgIG15ICRPdXRwdXQgPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPkhlYWRlcihUaXRsZSA9PiAiVGlja2V0SklSQSIpOwogICAgICAkT3V0cHV0ICAgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5OYXZpZ2F0aW9uQmFyKCk7CiAgICAgICRPdXRwdXQgICAuPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPk91dHB1dCgKICAgICAgICAgRGF0YSA9PiBcJURhdGEsCiAgICAgICAgIFRlbXBsYXRlRmlsZSA9PiAkVGVtcGxhdGVGaWxlLAogICAgICApOwogICAgICAkT3V0cHV0ICAgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5Gb290ZXIoKTsKICAgICAgcmV0dXJuICRPdXRwdXQ7Cn0KMTsK
cGFja2FnZSBLZXJuZWw6Okxhbmd1YWdlOjpkZV9BZ2VudFRpY2tldEpJUkE7CnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKc3ViIERhdGEgewogICAgbXkgJFNlbGYgPSBzaGlmdDsKICAgJFNlbGYtPntUcmFuc2xhdGlvbn0tPnsnQSBuZXcgSklSQSBJc3N1ZSBoYXMgYmVlbiBjcmVhdGVkJ30gPSAnRWluIG5ldWVzIEpJUkEgSXNzdWUgd3VyZGUgZXJzdGVsbHQnOwogICAkU2VsZi0+e1RyYW5zbGF0aW9ufS0+eydBIEpJUkEgSXNzdWUgY291bGQgbm90IGJlIGNyZWF0ZWQnfSA9ICdFaW4gSklSQSBJc3N1ZSBrb25udGUgbmljaHQgZXJzdGVsbHQgd2VyZGVuJzsKICAgJFNlbGYtPntUcmFuc2xhdGlvbn0tPnsnVG8gdGhlIGlzc3VlIChKSVJBKSd9ID0gJ1p1bSBKSVJBIElzc3VlJzsKICAgJFNlbGYtPntUcmFuc2xhdGlvbn0tPnsnQmFjayB0byB0aGUgdGlja2V0IChPVFJTKSd9ID0gJ1p1csO8Y2sgenVtIE9UUlMgVGlja2V0JzsKICAgJFNlbGYtPntUcmFuc2xhdGlvbn0tPnsnVGlja2V0IG5vdCBvcGVuLid9ID0gJ1RpY2tldCBuaWNodCBpbSBvZmZlbmVuIFp1c3RhbmQuJzsKICAgJFNlbGYtPntUcmFuc2xhdGlvbn0tPnsnSklSQSB0byBPVFJTJ30gPSAnSklSQSBuYWNoIE9UUlMnOwogICAkU2VsZi0+e1RyYW5zbGF0aW9ufS0+eydUYWtlIHRoaXMgdGlja2V0IGJhY2sgZnJvbSBKSVJBJ30gPSAnRGllc2VzIFRpY2tldCBhdXMgSklSQSB6dXLDvGNraG9sZW4nOwogICAkU2VsZi0+e1RyYW5zbGF0aW9ufS0+eydPVFJTIHRvIEpJUkEnfSA9ICdPVFJTIG5hY2ggSklSQSc7CiAgICRTZWxmLT57VHJhbnNsYXRpb259LT57J0VzY2FsYXRlIHRoaXMgdGlja2V0IHRvIEpJUkEnfSA9ICdEaWVzZXMgVGlja2V0IG5hY2ggSklSQSBlc2thbGllcmVuJzsKICAgIyRTZWxmLT57VHJhbnNsYXRpb259LT57Jyd9ID0gJyc7CiAgIHJldHVybiAxOwp9CjE7Cg==
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9TdGFuZGFyZC9BZ2VudFRpY2tldEpJUkEuZHRsIC0gb3ZlcnZpZXcKIyBDb3B5cmlnaHQgKEMpICh5ZWFyKSAobmFtZSBvZiBhdXRob3IpIChlbWFpbCBvZiBhdXRob3IpCiMgLS0KIyAkSWQ6IHdyaXRpbmctb3Rycy1hcHBsaWNhdGlvbi54bWwsdiAxLjEgMjAxMC8wOC8xMyAwODo1OToyOCBtZyBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQo8ZGl2IGNsYXNzPSJNYWluQm94IEFSSUFSb2xlTWFpbiI+CiAgPGRpdiBjbGFzcz0iQ2xlYXJMZWZ0Ij48L2Rpdj4KICA8ZGl2IGNsYXNzPSJDb250ZW50Ij4KICAgIDwhLS0gc3RhcnQgZm9ybSAtLT4KICAgIDx0YWJsZSBib3JkZXI9IjAiIHdpZHRoPSIxMDAlIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjMiIHN0eWxlPSJwYWRkaW5nLWxlZnQ6IDFjbTtwYWRkaW5nLXRvcDogMWNtOyI+CiAgICAgIDx0cj4KICAgICAgICA8dGggY2xhc3M9Im1haW5oZWFkIj4KICAgICAgICAgIDxoMT4kRW52eyJCb3gwIn0kVGV4dHsiQSBuZXcgSklSQSBJc3N1ZSBoYXMgYmVlbiBjcmVhdGVkIn0hJEVudnsiQm94MCJ9PC9oMT4KICAgICAgICA8L3RoPgogICAgICA8L3RyPgogICAgICA8dHI+CiAgICAgICAgPHRkIGNsYXNzPSJtYWluYm9keSI+CiAgICAgICAgICAkVGV4dHsiVG8gdGhlIGlzc3VlIChKSVJBKSJ9OiA8YSBocmVmPSIkUURhdGF7InVybCJ9Ij4kUURhdGF7ImtleSJ9ICgkUURhdGF7ImlkIn0pPC9hPgogICAgICAgIDwvdGQ+CiAgICAgIDwvdHI+CiAgICAgIDx0cj4KICAgICAgICA8dGQgY2xhc3M9Im1haW5ib2R5Ij4KICAgICAgICAgICRUZXh0eyJCYWNrIHRvIHRoZSB0aWNrZXQgKE9UUlMpIn06IDxhIGhyZWY9IiRFbnZ7IkJhc2VsaW5rIn1BY3Rpb249QWdlbnRUaWNrZXRab29tJlRpY2tldElEPSRRRGF0YXsiVGlja2V0SUQifSI+JFFEYXRheyJUaWNrZXROdW1iZXIifSAoJFFEYXRheyJUaWNrZXRJRCJ9KTwvYT4KICAgICAgICA8L3RkPgogICAgICA8L3RyPgogICAgPC90YWJsZT4KICAgIDwhLS0gZW5kIGZvcm0gLS0+CiAgPC9kaXY+CjwvZGl2Pgo=
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9TdGFuZGFyZC9BZ2VudFRpY2tldEpJUkFFcnJvci5kdGwgLSBvdmVydmlldwojIENvcHlyaWdodCAoQykgKHllYXIpIChuYW1lIG9mIGF1dGhvcikgKGVtYWlsIG9mIGF1dGhvcikKIyAtLQojICRJZDogd3JpdGluZy1vdHJzLWFwcGxpY2F0aW9uLnhtbCx2IDEuMSAyMDEwLzA4LzEzIDA4OjU5OjI4IG1nIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCjxkaXYgY2xhc3M9Ik1haW5Cb3ggQVJJQVJvbGVNYWluIj4KICA8ZGl2IGNsYXNzPSJDbGVhckxlZnQiPjwvZGl2PgogIDxkaXYgY2xhc3M9IkNvbnRlbnQiPgogICAgPCEtLSBzdGFydCBmb3JtIC0tPgogICAgPHRhYmxlIGJvcmRlcj0iMCIgd2lkdGg9IjEwMCUiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMyIgc3R5bGU9InBhZGRpbmctbGVmdDogMWNtO3BhZGRpbmctdG9wOiAxY207Ij4KICAgICAgPHRyPgogICAgICAgIDx0aCBjbGFzcz0ibWFpbmhlYWQiPgogICAgICAgICAgPGgxPiRFbnZ7IkJveDAifSRUZXh0eyJBIEpJUkEgSXNzdWUgY291bGQgbm90IGJlIGNyZWF0ZWQifSEkRW52eyJCb3gwIn08L2gxPgogICAgICAgIDwvdGg+CiAgICAgIDwvdHI+CiAgICAgIDx0cj4KICAgICAgICA8dGQgY2xhc3M9Im1haW5ib2R5Ij4KICAgICAgICAgICRFbnZ7IkJveDAifSRRRGF0YXsiZXJyb3IifSRFbnZ7IkJveDAifQogICAgICAgIDwvdGQ+CiAgICAgIDwvdHI+CiAgICAgIDx0cj4KICAgICAgICA8dGQgY2xhc3M9Im1haW5ib2R5Ij4KICAgICAgICAgICRUZXh0eyJCYWNrIHRvIHRoZSB0aWNrZXQgKE9UUlMpIn06IDxhIGhyZWY9IiRFbnZ7IkJhc2VsaW5rIn1BY3Rpb249QWdlbnRUaWNrZXRab29tJlRpY2tldElEPSRRRGF0YXsiVGlja2V0SUQifSI+JFFEYXRheyJUaWNrZXROdW1iZXIifSAoJFFEYXRheyJUaWNrZXRJRCJ9KTwvYT4KICAgICAgICA8L3RkPgogICAgICA8L3RyPgogICAgPC90YWJsZT4KICAgIDwhLS0gZW5kIGZvcm0gLS0+CiAgPC9kaXY+CjwvZGl2Pgo=
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9UaWNrZXRNZW51SklSQS5wbQojIENvcHlyaWdodCAoQykgMjAwMS0yMDEwIE9UUlMgQUcsIGh0dHA6Ly9vdHJzLm9yZy8KIyAtLQojIElkOiBUaWNrZXRNZW51SklSQS5wbSx2IDEuMTcgMjAxMC8wNC8xMiAyMTozNDowNiBtYXJ0aW4gRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgLS0KcGFja2FnZSBLZXJuZWw6Ok91dHB1dDo6SFRNTDo6VGlja2V0TWVudUpJUkE7CnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKdXNlIHZhcnMgcXcoJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS4xICQpIFsxXTsKc3ViIG5ldyB7CiAgICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKICAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgICBteSAkU2VsZiA9IHt9OwogICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKICAgICAjIGdldCBuZWVkZWQgb2JqZWN0cwogICAgIGZvciBteSAkT2JqZWN0IChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0IERCT2JqZWN0IExheW91dE9iamVjdCBVc2VySUQgVGlja2V0T2JqZWN0KSkgewogICAgICAgICAkU2VsZi0+eyRPYmplY3R9ID0gJFBhcmFteyRPYmplY3R9IHx8IGRpZSAiR290IG5vICRPYmplY3QhIjsKICAgICB9CiAgICAgcmV0dXJuICRTZWxmOwp9CnN1YiBSdW4gewogICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CiAgICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgICBpZiAoICEkUGFyYW17VGlja2V0fSApIHsKICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICBNZXNzYWdlID0+ICdOZWVkIFRpY2tldCEnCiAgICAgICAgICk7CiAgICAgICAgIHJldHVybjsKICAgICB9CiAgICAgIyBjaGVjayBpZiBmcm9udGVuZCBtb2R1bGUgcmVnaXN0ZXJlZCwgaWYgbm90LCBkbyBub3Qgc2hvdyBhY3Rpb24KICAgICBpZiAoICRQYXJhbXtDb25maWd9LT57QWN0aW9ufSApIHsKICAgICAgICAgbXkgJE1vZHVsZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdGcm9udGVuZDo6TW9kdWxlJyktPnsgJFBhcmFte0NvbmZpZ30tPntBY3Rpb259IH07CiAgICAgICAgIHJldHVybiBpZiAhJE1vZHVsZTsKICAgICB9CiAgICAgIyBjaGVjayBwZXJtaXNzaW9uCiAgICAgbXkgJEFjY2Vzc09rID0gJFNlbGYtPntUaWNrZXRPYmplY3R9LT5QZXJtaXNzaW9uKAogICAgICAgICBUeXBlICAgICAgPT4gJ3J3JywKICAgICAgICAgVGlja2V0SUQgPT4gJFBhcmFte1RpY2tldH0tPntUaWNrZXRJRH0sCiAgICAgICAgIFVzZXJJRCAgICA9PiAkU2VsZi0+e1VzZXJJRH0sCiAgICAgICAgIExvZ05vICAgICA9PiAxLAogICAgICk7CiAgICAgcmV0dXJuIGlmICEkQWNjZXNzT2s7CiAgICAgIyBjaGVjayBwZXJtaXNzaW9uCiAgICBpZiAoICRTZWxmLT57VGlja2V0T2JqZWN0fS0+VGlja2V0TG9ja0dldCggVGlja2V0SUQgPT4gJFBhcmFte1RpY2tldH0tPntUaWNrZXRJRH0gKSApIHsKICAgICAgICBteSAkQWNjZXNzT2sgPSAkU2VsZi0+e1RpY2tldE9iamVjdH0tPk93bmVyQ2hlY2soCiAgICAgICAgICAgIFRpY2tldElEID0+ICRQYXJhbXtUaWNrZXR9LT57VGlja2V0SUR9LAogICAgICAgICAgICBPd25lcklEICA9PiAkU2VsZi0+e1VzZXJJRH0sCiAgICAgICAgKTsKICAgICAgICByZXR1cm4gaWYgISRBY2Nlc3NPazsKICAgIH0KICAgICAjIGNoZWNrIGFjbAogICAgIHJldHVybgogICAgICAgICBpZiBkZWZpbmVkICRQYXJhbXtBQ0x9LT57ICRQYXJhbXtDb25maWd9LT57QWN0aW9ufSB9CiAgICAgICAgICAgICAgJiYgISRQYXJhbXtBQ0x9LT57ICRQYXJhbXtDb25maWd9LT57QWN0aW9ufSB9OwogICAgICMgaWYgdGlja2V0IGlzIGV4Y2FsYXRlZAogICAgIGlmICggJFBhcmFte1RpY2tldH0tPntKSVJBfSBlcSAnbG9jaycgKSB7CiAgICAgICAgICMgaWYgaXQgaXMgbG9ja2VkIGZvciBzb21lYm9keSBlbHNlCiAgICAgICAgIHJldHVybiBpZiAkUGFyYW17VGlja2V0fS0+e093bmVySUR9IG5lICRTZWxmLT57VXNlcklEfTsKICAgICAgICAgIyBzaG93IGN1c3RvbSBhY3Rpb24KICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAleyAkUGFyYW17Q29uZmlnfSB9LAogICAgICAgICAgICAgICV7ICRQYXJhbXtUaWNrZXR9IH0sCiAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICAgIE5hbWUgICAgICAgID0+ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+e0xhbmd1YWdlT2JqZWN0fS0+R2V0KCdKSVJBIHRvIE9UUlMnKSwKICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAkU2VsZi0+e0xheW91dE9iamVjdH0tPntMYW5ndWFnZU9iamVjdH0tPkdldCgnVGFrZSB0aGlzIHRpY2tldCBiYWNrIGZyb20gSklSQScpLAogICAgICAgICAgICAgIExpbmsgICAgICAgID0+ICdBY3Rpb249QWdlbnRUaWNrZXRKSVJBO1N1YmFjdGlvbj1KSVJBMk9UUlM7VGlja2V0SUQ9JFFEYXRheyJUaWNrZXRJRCJ9JywKICAgICAgICAgfTsKICAgICB9CiAgICAgIyBpZiB0aWNrZXQgaXMgZXhjYWxhdGVkCiAgICAgcmV0dXJuIHsKICAgICAgICAgJXsgJFBhcmFte0NvbmZpZ30gfSwKICAgICAgICAgJXsgJFBhcmFte1RpY2tldH0gfSwKICAgICAgICAgJVBhcmFtLAogICAgICAgICBOYW1lICAgICAgICAgPT4gJFNlbGYtPntMYXlvdXRPYmplY3R9LT57TGFuZ3VhZ2VPYmplY3R9LT5HZXQoJ09UUlMgdG8gSklSQScpLAogICAgICAgICBEZXNjcmlwdGlvbiAgPT4gJFNlbGYtPntMYXlvdXRPYmplY3R9LT57TGFuZ3VhZ2VPYmplY3R9LT5HZXQoJ0VzY2FsYXRlIHRoaXMgdGlja2V0IHRvIEpJUkEnKSwKICAgICAgICAgTGluayAgICAgICAgID0+ICdBY3Rpb249QWdlbnRUaWNrZXRKSVJBO1N1YmFjdGlvbj1PVFJTMkpJUkE7VGlja2V0SUQ9JFFEYXRheyJUaWNrZXRJRCJ9JywKICAgICB9Owp9CjE7Cg==
IyAtLQ0KIyBLZXJuZWwvU3lzdGVtL1RpY2tldC9FdmVudC9DbG9zZUpJUkFJc3N1ZS5wbSAtIGV2ZW50IG1vZHVsZQ0KIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAxMCBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvDQojIC0tDQojICRJZDogQ2xvc2VKSVJBSXNzdWUucG0sdiAxLjEgMjAxMC8wNS8xMCAxNzo1NjoyMCBzYiBFeHAgJA0KIyAtLQ0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQ0KIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91DQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuDQojIC0tDQoNCnBhY2thZ2UgS2VybmVsOjpTeXN0ZW06OlRpY2tldDo6RXZlbnQ6OkNsb3NlSklSQUlzc3VlOw0KDQp1c2Ugc3RyaWN0Ow0KdXNlIHdhcm5pbmdzOw0KdXNlIEtlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQ7DQp1c2UgS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZFZhbHVlOw0KdXNlIEtlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQ6OkJhY2tlbmQ6OkJhY2tlbmRDb21tb247DQp1c2UgSklSQTo6Q2xpZW50Ow0KdXNlIFJFU1Q6OkNsaWVudDsNCnVzZSBKU09OOw0KdXNlIE1JTUU6OkJhc2U2NDsNCnVzZSBEYXRhOjpEdW1wZXI7DQp1c2UgdmFycyBxdygkVkVSU0lPTik7DQokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS4xICQpIFsxXTsNCg0Kc3ViIG5ldyB7DQogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsNCg0KICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdA0KICAgIG15ICRTZWxmID0ge307DQogICAgYmxlc3MoICRTZWxmLCAkVHlwZSApOw0KDQogICAgIyBnZXQgbmVlZGVkIG9iamVjdHMNCiAgICBmb3IgKA0KICAgICAgICBxdygNCiAgICAgICAgQ29uZmlnT2JqZWN0IEVuY29kZU9iamVjdCBMb2dPYmplY3QgVGltZU9iamVjdCBNYWluT2JqZWN0IFRpY2tldE9iamVjdCBEQk9iamVjdA0KICAgICAgICApDQogICAgICAgICkNCiAgICB7DQogICAgICAgICRTZWxmLT57JF99ID0gJFBhcmFteyRffSB8fCBkaWUgIkdvdCBubyAkXyEiOw0KICAgIH0NCgkjIGNyZWF0ZSBhZGRpdGlvbmFsIG9iamVjdHMNCiAgICAkU2VsZi0+e0R5bmFtaWNGaWVsZE9iamVjdH0gICAgICA9IEtlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGQtPm5ldyggJXskU2VsZn0gKTsNCiAgICAkU2VsZi0+e0R5bmFtaWNGaWVsZFZhbHVlT2JqZWN0fSA9IEtlcm5lbDo6U3lzdGVtOjpEeW5hbWljRmllbGRWYWx1ZS0+bmV3KCAleyRTZWxmfSApOw0KICAgICRTZWxmLT57QmFja2VuZENvbW1vbk9iamVjdH0gICAgID0gS2VybmVsOjpTeXN0ZW06OkR5bmFtaWNGaWVsZDo6QmFja2VuZDo6QmFja2VuZENvbW1vbi0+bmV3KCAleyRTZWxmfSApOw0KCQ0KICAgIHJldHVybiAkU2VsZjsNCn0NCg0Kc3ViIFJ1biB7DQogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsNCg0KICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmDQogICAgZm9yIChxdyhUaWNrZXRJRCBFdmVudCBDb25maWcpKSB7DQogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7DQogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7DQogICAgICAgICAgICByZXR1cm47DQogICAgICAgIH0NCiAgICB9DQoNCgkkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygNCiAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2RlYnVnJywNCiAgICAgICAgICAgICAgTWVzc2FnZSA9PiAiS2VybmVsOjpTeXN0ZW06OlRpY2tldDo6RXZlbnQ6OkNsb3NlSklSQUlzc3VlOjpSdW4oKTogVGlja2V0SUQ6ICRQYXJhbXtUaWNrZXRJRH0gRXZlbnQ6ICRQYXJhbXtFdmVudH0iDQogICAgKTsNCiAgICByZXR1cm4gMSBpZiAkUGFyYW17RXZlbnR9IG5lICdUaWNrZXRTdGF0ZVVwZGF0ZSc7DQoNCiAgICBteSAlVGlja2V0ID0gJFNlbGYtPntUaWNrZXRPYmplY3R9LT5UaWNrZXRHZXQoDQogICAgICAgIFRpY2tldElEID0+ICRQYXJhbXtUaWNrZXRJRH0sDQogICAgICAgIFVzZXJJRCAgID0+IDEsDQogICAgKTsNCiAgICByZXR1cm4gMSBpZiAhJVRpY2tldDsNCiAgICANCiAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygNCiAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2RlYnVnJywNCiAgICAgICAgICAgICAgTWVzc2FnZSA9PiAiS2VybmVsOjpTeXN0ZW06OlRpY2tldDo6RXZlbnQ6OkNsb3NlSklSQUlzc3VlOjpSdW4oKTogVGlja2V0SUQ6ICRUaWNrZXR7VGlja2V0SUR9IFRpdGxlOiAkVGlja2V0e1RpdGxlfSBTdGF0ZTogJFRpY2tldHtTdGF0ZX0iDQogICAgKTsNCiAgICBteSAkYWxsb3dlZFN0YXRlc05hbWVzID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ1RpY2tldEpJUkEnKS0+e09UUlNUaWNrZXRBbGxvd2VkU3RhdGVzNENsb3NlfTsNCiAgICBteSBAYWxsb3dlZFN0YXRlc0xpc3QgPSBzcGxpdCgvLC8sJGFsbG93ZWRTdGF0ZXNOYW1lcyk7DQoJaWYgKCAhIGdyZXAgeyAkXyBlcSAkVGlja2V0e1N0YXRlfSB9IEBhbGxvd2VkU3RhdGVzTGlzdCApIHsNCgkJJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coDQogICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdpbmZvJywNCiAgICAgICAgICAgICAgTWVzc2FnZSA9PiAiS2VybmVsOjpTeXN0ZW06OlRpY2tldDo6RXZlbnQ6OkNsb3NlSklSQUlzc3VlOjpSdW4oKTogT1RSUyBUaWNrZXQgbm90IGluICRhbGxvd2VkU3RhdGVzTmFtZXM6ICIgLiAkVGlja2V0e1N0YXRlfQ0KICAgCQkpOw0KICAgCQlyZXR1cm4gMTsNCgl9DQogICAgDQogICAgbXkgJHVybCA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdUaWNrZXRKSVJBJyktPntVUkx9Ow0KICAgIG15ICR1c2VyID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ1RpY2tldEpJUkEnKS0+e1VzZXJ9Ow0KICAgIG15ICRwYXNzd29yZCA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdUaWNrZXRKSVJBJyktPntQYXNzd29yZH07DQogICAgbXkgJHJlcG9ydGVyID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ1RpY2tldEpJUkEnKS0+e1JlcG9ydGVyfTsNCiAgICBteSAkYXNzaWduZWUgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnVGlja2V0SklSQScpLT57QXNzaWduZWV9Ow0KICAgIG15ICRjbG9zZUFjdGlvbk5hbWUgID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ1RpY2tldEpJUkEnKS0+e1dvcmtmbG93Q2xvc2VBY2lvbk5hbWV9Ow0KICAgIG15ICRqaXJhID0gSklSQTo6Q2xpZW50LT5uZXcoJHVybCwgJHVzZXIsICRwYXNzd29yZCk7DQogICAgbXkgJER5bmFtaWNGaWVsZCA9ICRTZWxmLT57RHluYW1pY0ZpZWxkT2JqZWN0fS0+RHluYW1pY0ZpZWxkR2V0KE5hbWUgPT4gJ0pJUkFJc3N1ZUlEJyk7DQogICAgbXkgJGppcmFJc3N1ZUlkID0gJFNlbGYtPntEeW5hbWljRmllbGRWYWx1ZU9iamVjdH0tPlZhbHVlR2V0KA0KICAgICAgICBGaWVsZElEICA9PiAkRHluYW1pY0ZpZWxkLT57SUR9LA0KICAgICAgICBPYmplY3RJRCA9PiAkVGlja2V0e1RpY2tldElEfSwNCiAgICApOw0KICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKA0KICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZGVidWcnLA0KICAgICAgICAgICAgICBNZXNzYWdlID0+ICJLZXJuZWw6OlN5c3RlbTo6VGlja2V0OjpFdmVudDo6Q2xvc2VKSVJBSXNzdWU6OlJ1bigpOiAnJGppcmFJc3N1ZUlkJyAvLyAnJGppcmFJc3N1ZUlkLT5bMF0nIC8vICckamlyYUlzc3VlSWQtPlswXS0+e1ZhbHVlVGV4dH0nIER5bmFtaWNGaWVsZElEOiAkRHluYW1pY0ZpZWxkLT57SUR9ICINCiAgICApOw0KCWlmICggJGppcmFJc3N1ZUlkIGFuZCAkamlyYUlzc3VlSWQtPlswXSBhbmQgZGVmaW5lZCgkamlyYUlzc3VlSWQtPlswXS0+e1ZhbHVlVGV4dH0pIGFuZCAkamlyYUlzc3VlSWQtPlswXS0+e1ZhbHVlVGV4dH0gbmUgIiIgKSB7DQogICAgCW15ICRpc3N1ZSA9IGV2YWwgeyAkamlyYS0+Z2V0SXNzdWUoJGppcmFJc3N1ZUlkLT5bMF0tPntWYWx1ZVRleHR9KSB9OyAjIHdlaXJkIGJ1dCBmb3VuZCBpbiB0aGUgUE9EDQogICAgCXJldHVybiAxIGlmICEkaXNzdWU7DQogICAgCSRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKA0KICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZGVidWcnLA0KICAgICAgICAgICAgICBNZXNzYWdlID0+ICJLZXJuZWw6OlN5c3RlbTo6VGlja2V0OjpFdmVudDo6Q2xvc2VKSVJBSXNzdWU6OlJ1bigpOiBpc3N1ZSBleGlzdHMiDQogICAJCSk7DQogICAJCW15IEBBcnRpY2xlSW5kZXggPSAkU2VsZi0+e1RpY2tldE9iamVjdH0tPkFydGljbGVHZXQoDQoJICAgICAgICBUaWNrZXRJRCA9PiAkVGlja2V0e1RpY2tldElEfSwNCgkgICAgICAgIFVzZXJJRCAgID0+IDEsDQoJICAgICAgICBPcmRlciAgICA9PiAnREVTQycsICMgREVTQyxBU0MgLSBkZWZhdWx0IGlzIEFTQw0KCSAgICAgICAgTGltaXQgICAgPT4gMSwNCiAgICAgICAgKTsNCiAgIAkJJGppcmEtPmFkZENvbW1lbnQoJGppcmFJc3N1ZUlkLT5bMF0tPntWYWx1ZVRleHR9LCJPVFJTOiAkVGlja2V0e1N0YXRlfVxuXG4tLS0tLS0tLVxuIiAuICRBcnRpY2xlSW5kZXhbMF0tPntCb2R5fSk7DQogICAJCQ0KCSAgICBteSAkY2xpZW50ID0gUkVTVDo6Q2xpZW50LT5uZXcoKTsNCgkgICAgJGNsaWVudC0+c2V0Rm9sbG93KDEpOw0KCSAgICBteSAoJHByb3RvLCRuaWwsJGhvc3QsQGJhc2V1cmwpID0gc3BsaXQoJy8nLCR1cmwpOw0KCSAgICBteSAkZ2V0dXJsID0gJy8nLiBqb2luKCcvJyxAYmFzZXVybCkgLiAnL3Jlc3QvYXBpL2xhdGVzdC9pc3N1ZS8nIC4gJGlzc3VlLT57a2V5fSAuICcvdHJhbnNpdGlvbnM/ZXhwYW5kPXRyYW5zaXRpb25zLmZpZWxkcy4nOw0KCSAgICAkZ2V0dXJsID1+IHMvXC9cLy9cLy9nOyANCgkgICAgJGNsaWVudC0+c2V0SG9zdCgiJHByb3RvLy8kaG9zdCIpOw0KCSAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygNCgkgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdkZWJ1ZycsDQoJICAgICAgICAgICAgICBNZXNzYWdlID0+ICJlcm5lbDo6U3lzdGVtOjpUaWNrZXQ6OkV2ZW50OjpDbG9zZUpJUkFJc3N1ZTogUkVTVDogdXJsICRnZXR1cmwiDQoJICAgICk7DQoJICAgICRjbGllbnQtPkdFVCgkZ2V0dXJsLCB7QWNjZXB0ID0+ICdhcHBsaWNhdGlvbi9qc29uJywgQXV0aG9yaXphdGlvbiA9PiAnQmFzaWMgJyAuIGVuY29kZV9iYXNlNjQoJHVzZXIgLiAnOicgLiAkcGFzc3dvcmQpLCAiQ29udGVudC10eXBlIiA9PiAnYXBwbGljYXRpb24vanNvbid9KTsNCiAgIAkJaWYgKCAkY2xpZW50LT5yZXNwb25zZUNvZGUoKSA+PSAyMDAgYW5kICRjbGllbnQtPnJlc3BvbnNlQ29kZSgpIDw9IDI5OSApIHsNCgkJICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKA0KCQkgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdkZWJ1ZycsDQoJCSAgICAgICAgICAgICAgTWVzc2FnZSA9PiAiZXJuZWw6OlN5c3RlbTo6VGlja2V0OjpFdmVudDo6Q2xvc2VKSVJBSXNzdWU6IFJFU1Q6IHJlc3BvbnNlQ29kZSAiIC4gJGNsaWVudC0+cmVzcG9uc2VDb2RlKCkgLiAiIHJlc3BvbnNlQ29udGVudCAiIC4gRHVtcGVyKGZyb21fanNvbigkY2xpZW50LT5yZXNwb25zZUNvbnRlbnQoKSkpDQoJCSAgICApOw0KCQkgICAgbXkgJHRyYW5zaXRpb25zID0gZnJvbV9qc29uKCRjbGllbnQtPnJlc3BvbnNlQ29udGVudCgpKTsNCgkJICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKA0KCSAgICAgICAgCVByaW9yaXR5ID0+ICdkZWJ1ZycsDQoJICAgICAgICAgICAgTWVzc2FnZSA9PiAiS2VybmVsOjpTeXN0ZW06OlRpY2tldDo6RXZlbnQ6OkNsb3NlSklSQUlzc3VlOjpSdW4oKTogaXNzdWUgdHJhbnNpdGlvbnM6ICckdHJhbnNpdGlvbnMnICciIC4gRHVtcGVyKCR0cmFuc2l0aW9ucykgLiAiJyINCgkgICAJCSk7DQoJCSAgICAkdHJhbnNpdGlvbnMgPSAkdHJhbnNpdGlvbnMtPnt0cmFuc2l0aW9uc307DQoJCSAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygNCgkgICAgICAgICAgICBQcmlvcml0eSA9PiAnZGVidWcnLA0KCSAgICAgICAgICAgIE1lc3NhZ2UgPT4gIktlcm5lbDo6U3lzdGVtOjpUaWNrZXQ6OkV2ZW50OjpDbG9zZUpJUkFJc3N1ZTo6UnVuKCk6IGlzc3VlIHRyYW5zaXRpb25zOiAnJHRyYW5zaXRpb25zJyAnIiAuIER1bXBlcigkdHJhbnNpdGlvbnMpIC4gIiciDQoJICAgCQkpOw0KCQkgICAgbXkgJHRyYW5zaXRpb25Eb25lTmFtZSA9IHVuZGVmOw0KCQkgICAgZm9yIG15ICR0cmFuc2l0aW9uIChAeyR0cmFuc2l0aW9uc30pew0KCQkgICAgCSRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKA0KCSAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2RlYnVnJywNCgkgICAgICAgICAgICAgIE1lc3NhZ2UgPT4gIktlcm5lbDo6U3lzdGVtOjpUaWNrZXQ6OkV2ZW50OjpDbG9zZUpJUkFJc3N1ZTo6UnVuKCk6IGlzc3VlIHRyYW5zaXRpb246ICckdHJhbnNpdGlvbicgJyIgLiBEdW1wZXIoJHRyYW5zaXRpb24pIC4gIiciDQoJICAgCQkJKTsNCgkJICAgIAlteSAkdHJhbnNpdGlvbk5hbWUgPSAkdHJhbnNpdGlvbi0+e25hbWV9Ow0KCQkgICAgCW15ICR0cmFuc2l0aW9uSUQgPSAkdHJhbnNpdGlvbi0+e2lkfTsNCgkJICAgIAkkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygNCgkgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdkZWJ1ZycsDQoJICAgICAgICAgICAgICBNZXNzYWdlID0+ICJLZXJuZWw6OlN5c3RlbTo6VGlja2V0OjpFdmVudDo6Q2xvc2VKSVJBSXNzdWU6OlJ1bigpOiBpc3N1ZSB0cmFuc2l0aW9uOiAnJHRyYW5zaXRpb24nICckdHJhbnNpdGlvbk5hbWUnICckdHJhbnNpdGlvbklEJyINCgkgICAJCQkpOw0KCQkgICAgCWlmICggJHRyYW5zaXRpb25OYW1lIGFuZCAiJHRyYW5zaXRpb25OYW1lIiBlcSAiJGNsb3NlQWN0aW9uTmFtZSIgKSB7DQoJCQkJCSR0cmFuc2l0aW9uRG9uZU5hbWUgPSAiJHRyYW5zaXRpb25OYW1lICggJHRyYW5zaXRpb25JRCApIjsJCQ0KCQkJICAgIAlteSAkcnZhbCA9IGV2YWwgeyAkamlyYS0+cHJvZ3Jlc3Nfd29ya2Zsb3dfYWN0aW9uX3NhZmVseSgkaXNzdWUsICR0cmFuc2l0aW9uSUQpOyB9OyAjIGRlZmF1bHQ6IDIgPSBDbG9zZSBJc3N1ZQ0KCQkJICAgIAkkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygNCgkJCSAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywNCgkJCSAgICAgICAgICAgICAgTWVzc2FnZSA9PiAiS2VybmVsOjpTeXN0ZW06OlRpY2tldDo6RXZlbnQ6OkNsb3NlSklSQUlzc3VlOjpSdW4oKTogaXNzdWUgY29ubm90IGJlIGNsb3NlZDogJEAiDQoJCQkgICAJCSkgaWYgJEAgOw0KCQkgICAgCX0NCgkJICAgIH0NCgkJICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKA0KCSAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2RlYnVnJywNCgkgICAgICAgICAgICAgIE1lc3NhZ2UgPT4gIktlcm5lbDo6U3lzdGVtOjpUaWNrZXQ6OkV2ZW50OjpDbG9zZUpJUkFJc3N1ZTo6UnVuKCk6IGlzc3VlIHRyYW5zaXRpb246ICR0cmFuc2l0aW9uRG9uZU5hbWUiDQoJICAgCQkpIGlmICR0cmFuc2l0aW9uRG9uZU5hbWU7DQogICAJCX0gZWxzZSB7DQoJCSAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygNCgkJICAgICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLA0KCQkgICAgICAgICAgICAgIE1lc3NhZ2UgPT4gImVybmVsOjpTeXN0ZW06OlRpY2tldDo6RXZlbnQ6OkNsb3NlSklSQUlzc3VlOiBSRVNUOiByZXNwb25zZUNvZGUgIiAuICRjbGllbnQtPnJlc3BvbnNlQ29kZSgpIC4gIiByZXNwb25zZUNvbnRlbnQgIiAuICRjbGllbnQtPnJlc3BvbnNlQ29udGVudCgpDQoJCSAgICApOw0KICAgCQl9DQogICAgfQ0KICAgIHJldHVybiAxOw0KfQ0KDQoxOw==