Support
0.1.11
OTRS GmbH
http://otrs.org/
GNU GENERAL PUBLIC LICENSE Version 2, June 1991
Code review and fix oracle and psql bugs.
Complete Win32 compat.
Fixed bug in Hardware.pm.
Fixed Bug in Support.xml.
Support Modul review.
Add new database checks.
Added more database checks.
Improved notifications.
Added init apache checks.
Added init mysql and oracle checks.
Add new admin checks and quote xml input.
Fixed xml and formatting bug.
Init release.
A admin support tool.
Ein Admin Support Tool.
2.1.x
2.2.x
The Support application will be found at the admin navigation bar in the fourth column and can be used for system checks to find setup errors.
Die Support Applikation ist in der Admin-Navigationsleiste, in der vierten Spalte zu finden. Mit ihr koennen System-Checks ausgeführt werden um Fehler im Setup zu finden.
2007-11-22 14:07:57
opms.otrs.com
IyAtLQojIEFkbWluU3VwcG9ydC5kdGwgLSBwcm92aWRlcyBIVE1MIGZvcm0gZm9yIEFkbWluU3VwcG9ydAojIENvcHlyaWdodCAoQykgMjAwMS0yMDA3IE9UUlMgR21iSCwgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBBZG1pblN1cHBvcnQuZHRsLHYgMS4zIDIwMDcvMDYvMTIgMTM6MDE6NTkgbWFydGluIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLnR4dC4KIyAtLQoKPCEtLSBkdGw6YmxvY2s6T3ZlcnZpZXcgLS0+Cjx0YWJsZSBib3JkZXI9IjAiIHdpZHRoPSIxMDAlIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjMiPgogIDx0cj4KICAgIDx0ZCBjbGFzcz0ibWFpbmhlYWQiPiRFbnZ7IkJveDAifSRUZXh0eyJBZG1pbiBTdXBwb3J0IEluZm8ifSRFbnZ7IkJveDEifTwvdGQ+CiAgPC90cj4KICA8dHI+CiAgICA8dGQgY2xhc3M9Im1lbnUiPgogICAgICA8YSBocmVmPSIkRW52eyJCYXNlbGluayJ9QWN0aW9uPSRFbnZ7IkFjdGlvbiJ9JlN1YmFjdGlvbj1HZXRSZXF1aXJlZEluZm8iPkNyZWF0ZSBTdXBwb3J0IFBhY2thZ2U8L2E+CiAgICA8L3RkPgogIDwvdHI+CiAgPHRyPgogICAgPHRkIGNsYXNzPSJtYWluYm9keSIgYWxpZ249ImNlbnRlciI+CiAgICAgIDxicj4KPCEtLSBkdGw6YmxvY2s6T3ZlcnZpZXdNb2R1bGUgLS0+CiAgICAgIDx0YWJsZSB3aWR0aD0iODAwIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjQiPgogICAgICAgIDx0cj4KICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGhlYWQiPiRRRGF0YXsiTW9kdWxlIn08L3RkPgogICAgICAgIDwvdHI+CiAgICAgICAgPHRyPgogICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50Ym9keSI+CiAgICAgICAgICAgIDx0YWJsZSB3aWR0aD0iMTAwJSIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjMiPgogICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGtleSIgd2lkdGg9IjE1MCI+JFRleHR7IkNoZWNrIn08L3RkPgogICAgICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50a2V5IiB3aWR0aD0iMjUwIj4kVGV4dHsiRGVzY3JpcHRpb24ifTwvdGQ+CiAgICAgICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnRrZXkiPiRUZXh0eyJDb21tZW50In08L3RkPgogICAgICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50a2V5IiB3aWR0aD0iNTAiPiRUZXh0eyJTdGF0ZSJ9PC90ZD4KICAgICAgICAgICAgICA8L3RyPgo8IS0tIGR0bDpibG9jazpPdmVydmlld01vZHVsZVJvdyAtLT4KICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICA8dGQgY2xhc3M9IiRRRGF0YXsiQ3NzQ2xhc3MifSI+JFFEYXRheyJOYW1lIn08L3RkPgogICAgICAgICAgICAgICAgPHRkIGNsYXNzPSIkUURhdGF7IkNzc0NsYXNzIn0iPiREYXRheyJEZXNjcmlwdGlvbiJ9PC90ZD4KICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz0iJFFEYXRheyJDc3NDbGFzcyJ9Ij4kRGF0YXsiQ29tbWVudCJ9PC90ZD4KICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz0iJFFEYXRheyJDc3NDbGFzcyJ9Ij48Zm9udCBjb2xvcj0iJFFEYXRheyJGb250Q29sb3IifSI+JFFEYXRheyJDaGVjayJ9PC9mb250PjwvdGQ+CiAgICAgICAgICAgICAgPC90cj4KPCEtLSBkdGw6YmxvY2s6T3ZlcnZpZXdNb2R1bGVSb3cgLS0+CiAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICA8L3RkPgogICAgICAgIDwvdHI+CiAgICAgICAgPHRyPgogICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50Zm9vdGVyIj4KICAgICAgICAgICAgJm5ic3A7CiAgICAgICAgICA8L3RkPgogICAgICAgIDwvdHI+CiAgICAgIDwvdGFibGU+CiAgICAgIDxicj4KPCEtLSBkdGw6YmxvY2s6T3ZlcnZpZXdNb2R1bGUgLS0+CiAgICAgIDxicj4KICAgIDwvdGQ+CiAgPC90cj4KPC90YWJsZT4KPCEtLSBkdGw6YmxvY2s6T3ZlcnZpZXcgLS0+CjwhLS0gZHRsOmJsb2NrOlJlcXVpcmVkIC0tPgo8dGFibGUgYm9yZGVyPSIwIiB3aWR0aD0iMTAwJSIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIwIj4KICA8dHI+CiAgICA8dGQgY2xhc3M9Im1haW5oZWFkIj4kRW52eyJCb3gwIn0kVGV4dHsiQWRtaW4gU3VwcG9ydCBJbmZvIn0kRW52eyJCb3gxIn08L3RkPgogIDwvdHI+CiAgPHRyPgogICAgPHRkIGNsYXNzPSJtYWluYm9keSIgYWxpZ249ImNlbnRlciI+CiAgICAgIDxicj4KICAgICAgPGZvcm0gYWN0aW9uPSIkRW52eyJDR0lIYW5kbGUifSIgbWV0aG9kPSJwb3N0Ij4KICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJBY3Rpb24iIHZhbHVlPSIkRW52eyJBY3Rpb24ifSI+CiAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iU3ViYWN0aW9uIiB2YWx1ZT0iQ29uZmlkZW50aWFsIj4KICAgICAgICA8dGFibGUgYm9yZGVyPSIwIiB3aWR0aD0iODAwcHgiIGFsaWduPSJjZW50ZXIiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMyI+CjwhLS0gZHRsOmJsb2NrOlJlcXVpcmVkSW5mbyAtLT4KICAgICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkIGNvbHNwYW49IjMiIGNsYXNzPSJjb250ZW50aGVhZCI+JFFEYXRheyJDb25maWdNb2R1bGUifTwvdGQ+CiAgICAgICAgICA8L3RyPgogICAgICAgICAgPHRyPgogICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnRib2R5Ij4KICAgICAgICAgICAgICA8dGFibGUgd2lkdGg9IjgwMHB4IiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjMiPgo8IS0tIGR0bDpibG9jazpSZXF1aXJlZEluZm9Sb3cgLS0+CjwhLS0gZHRsOmJsb2NrOlJlcXVpcmVkSW5mb1Jvd1RleHQgLS0+CiAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGtleSIgd2lkdGg9IjI1JSI+JFFEYXRheyJOYW1lIn06PC90ZD4KICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50dmFsdWUiIHdpZHRoPSIzNSUiPjxpbnB1dCB0eXBlPSJ0ZXh0IiBuYW1lPSIkUURhdGF7IktleSJ9IiB2YWx1ZT0iJFFEYXRheyJWYWx1ZSJ9IiBzaXplPSIkUURhdGF7IlNpemUifSI+PC90ZD4KICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50dmFsdWUiPjxmb250IGNvbG9yPSJyZWQiIHNpemU9Ii0yIj4gKCogJFFEYXRheyJEZXNjcmlwdGlvbiJ9PC9mb250PjwvdGQ+CiAgICAgICAgICAgICAgICA8L3RyPgo8IS0tIGR0bDpibG9jazpSZXF1aXJlZEluZm9Sb3dUZXh0IC0tPgo8IS0tIGR0bDpibG9jazpSZXF1aXJlZEluZm9Sb3dTZWxlY3QgLS0+CiAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGtleSIgd2lkdGg9IjI1JSI+JFFEYXRheyJOYW1lIn06PC90ZD4KICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50dmFsdWUiIHdpZHRoPSIzNSUiPiREYXRheyJTZWxlY3RTdHJnIn08L3RkPgogICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnR2YWx1ZSI+PGZvbnQgY29sb3I9InJlZCIgc2l6ZT0iLTIiPiAoKiAkUURhdGF7IkRlc2NyaXB0aW9uIn08L2ZvbnQ+PC90ZD4KICAgICAgICAgICAgICAgIDwvdHI+CjwhLS0gZHRsOmJsb2NrOlJlcXVpcmVkSW5mb1Jvd1NlbGVjdCAtLT4KPCEtLSBkdGw6YmxvY2s6UmVxdWlyZWRJbmZvUm93IC0tPgogICAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICA8L3RyPgo8IS0tIGR0bDpibG9jazpSZXF1aXJlZEluZm8gLS0+CiAgICAgICAgICA8dHI+CiAgICAgICAgICAgIDx0ZCBjbGFzcz0iY29udGVudGZvb3RlciI+CiAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPSJidXR0b24iIHR5cGU9InN1Ym1pdCIgdmFsdWU9IiRUZXh0eyJOZXh0Li4uIn0iPgogICAgICAgICAgICA8L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICA8L3RhYmxlPgogICAgICA8L2Zvcm0+CiAgICAgIDxicj4KICAgIDwvdGQ+CiAgPC90cj4KPC90YWJsZT4KPCEtLSBkdGw6YmxvY2s6UmVxdWlyZWQgLS0+CjwhLS0gZHRsOmJsb2NrOkNvbmZpZGVudGlhbCAtLT4KPHRhYmxlIGJvcmRlcj0iMCIgd2lkdGg9IjEwMCUiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMCI+CiAgPHRyPgogICAgPHRkIGNsYXNzPSJtYWluaGVhZCI+JEVudnsiQm94MCJ9JFRleHR7IkFkbWluIFN1cHBvcnQgSW5mbyJ9JEVudnsiQm94MSJ9PC90ZD4KICA8L3RyPgogIDx0cj4KICAgIDx0ZCBjbGFzcz0ibWFpbmJvZHkiIGFsaWduPSJjZW50ZXIiPgogICAgICA8YnI+CiAgICAgIDxmb3JtIGFjdGlvbj0iJEVudnsiQ0dJSGFuZGxlIn0iIG1ldGhvZD0icG9zdCI+CiAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iQWN0aW9uIiB2YWx1ZT0iJEVudnsiQWN0aW9uIn0iPgogICAgICAgIDxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9IlN1YmFjdGlvbiIgdmFsdWU9IlVwbG9hZFN1cHBvcnRJbmZvIj4KICAgICAgICA8dGFibGUgYm9yZGVyPSIwIiB3aWR0aD0iODAwcHgiIGFsaWduPSJjZW50ZXIiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMyI+CiAgICAgICAgICA8dHI+CiAgICAgICAgICAgIDx0ZCBjb2xzcGFuPSIzIiBjbGFzcz0iY29udGVudGhlYWQiPiRUZXh0eyJDb25maWRlbnRpYWwgaW5mb3JtYXRpb24ifTwvdGQ+CiAgICAgICAgICA8L3RyPgogICAgICAgICAgPHRyPgogICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnRib2R5Ij4KCjwhLS0gZHRsOmJsb2NrOkNvbmZpZGVudGlhbEhpZGRlbiAtLT4KICAgICAgICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSIkUURhdGF7Ik5hbWUifSIgdmFsdWU9IiRRRGF0YXsiVmFsdWUifSI+CjwhLS0gZHRsOmJsb2NrOkNvbmZpZGVudGlhbEhpZGRlbiAtLT4KCiAgICAgICAgICAgICAgPHRhYmxlIHdpZHRoPSI4MDBweCIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIzIj4KICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50a2V5IiB3aWR0aD0iMTUwIj4kVGV4dHsiQ29uZmlkZW50aWFsIn06PC90ZD4KICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50Ym9keSIgY29sc3Bhbj0iMiI+CiAgICAgICAgICAgICAgICAgIDx0ZXh0YXJlYSBuYW1lPSJDb25maWRlbnRpYWwiIHJvd3M9IjQiIGNvbHM9Ijc4Ij4KQW55IGFuZCBhbGwgaW5mb3JtYXRpb24gZGlzY2xvc2VkIHRvIE9UUlMgd2lsbCBiZSBrZXB0IHN0cmljdGx5IGNvbmZpZGVudGlhbCBhbmQgYXJlIG9ubHkgdXNlZCBmb3IgcHJvdmlkaW5nIGJldHRlciBzdXBwb3J0IHNlcnZpY2VzIHRvIG91ciBjdXN0b21lcnMuCiAgICAgICAgICAgICAgICAgIDwvdGV4dGFyZWE+CiAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgICAgPHRyPgogICAgICAgICAgICAgICAgICA8dGQgY29sc3Bhbj0iMyIgY2xhc3M9ImNvbnRlbnRoZWFkIj4kVGV4dHsiQ29tbWVyY2lhbCBzdXBwb3J0In08L3RkPgogICAgICAgICAgICAgICAgPC90cj4KICAgICAgICAgICAgICAgIDx0cj4KICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50a2V5IiB3aWR0aD0iMTUwIj4kVGV4dHsiQ29tbWVyY2lhbCBzdXBwb3J0IElEIn06PC90ZD4KICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPSJjb250ZW50dmFsdWUiPjxpbnB1dCB0eXBlPSJUZXh0IiBuYW1lPSJTdXBwb3J0SUQiIHZhbHVlPSIiIHNpemU9IjQwIj48L3RkPgogICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnR2YWx1ZSI+PGZvbnQgY29sb3I9InJlZCIgc2l6ZT0iLTIiPiAoKiAkVGV4dHsiaWYgeW91IGFyZSBhbHJlYWR5IGEgY29tbWVyY2lhbCBzdXBwb3J0IGN1c3RvbWVyLCBwbGVhc2UgYWRkIHlvdXIgc3VwcG9ydCBpZC4gKG5vdCByZXF1aXJlZCEpIn0pPC9mb250PjwvdGQ+CiAgICAgICAgICAgICAgICA8L3RyPgogICAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICA8L3RyPgogICAgICAgICAgPHRyPgogICAgICAgICAgICA8dGQgY2xhc3M9ImNvbnRlbnRmb290ZXIiPgogICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz0iYnV0dG9uIiB0eXBlPSJzdWJtaXQiIG5hbWU9IkRvd25sb2FkIiB2YWx1ZT0iJFRleHR7IkRvd25sb2FkIn0iPgogICAgICAgICAgICAgIDxpbnB1dCBjbGFzcz0iYnV0dG9uIiB0eXBlPSJzdWJtaXQiIG5hbWU9IlNlbmQiIHZhbHVlPSIkVGV4dHsiU2VuZCJ9Ij4KICAgICAgICAgICAgPC90ZD4KICAgICAgICAgIDwvdHI+CiAgICAgICAgPC90YWJsZT4KICAgICAgPC9mb3JtPgogICAgICA8YnI+CiAgICA8L3RkPgogIDwvdHI+CjwvdGFibGU+CjwhLS0gZHRsOmJsb2NrOkNvbmZpZGVudGlhbCAtLT4K
IyAtLQojIEtlcm5lbC9TeXN0ZW0vU3VwcG9ydC5wbSAtIGFsbCByZXF1aXJlZCBzeXN0ZW0gaW5mb3JtYXRpb25zCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDcgT1RSUyBHbWJILCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IFN1cHBvcnQucG0sdiAxLjggMjAwNy8xMS8yMiAxMTo0OTo0MCBzciBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpTeXN0ZW06OlN1cHBvcnQ7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgS2VybmVsOjpTeXN0ZW06OlhNTDsKdXNlIEtlcm5lbDo6U3lzdGVtOjpEQjsKdXNlIEtlcm5lbDo6U3lzdGVtOjpFbWFpbDsKdXNlIEtlcm5lbDo6U3lzdGVtOjpUaW1lOwp1c2UgTUlNRTo6QmFzZTY0Owp1c2UgQXJjaGl2ZTo6VGFyOwoKdXNlIHZhcnMgcXcoQElTQSAkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjggJCkgWzFdOwoKPWhlYWQxIE5BTUUKCktlcm5lbDo6U3lzdGVtOjpTdXBwb3J0IC0gZ2xvYmFsIHN5c3RlbSBpbmZvcm1hdGlvbnMKCj1oZWFkMSBTWU5PUFNJUwoKQWxsIHJlcXVpcmVkIHN1cHBvcnQgaW5mb3JtYXRpb25zIHRvIGEgcnVubmluZyBPVFJTIHN5c3RlbS4KCj1oZWFkMSBQVUJMSUMgSU5URVJGQUNFCgo9b3ZlciA0Cgo9Y3V0Cgo9aXRlbSBuZXcoKQoKY3JlYXRlIFN1cHBvcnQgb2JqZWN0Cgp1c2UgS2VybmVsOjpDb25maWc7CnVzZSBLZXJuZWw6OlN5c3RlbTo6TG9nOwpteSAkQ29uZmlnT2JqZWN0ID0gS2VybmVsOjpDb25maWctPm5ldygpOwpteSAkTG9nT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkxvZy0+bmV3KAogICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCik7CgokU3VwcG9ydE9iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpTdXBwb3J0LT5uZXcoCiAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgIExvZ09iamVjdCA9PiAkTG9nT2JqZWN0LAopOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGNoZWNrIG5lZWRlZCBvYmplY3RzCiAgICBmb3IgKHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QgTWFpbk9iamVjdCkpIHsKICAgICAgICAkU2VsZi0+eyRffSA9ICRQYXJhbXskX30gfHwgZGllICJHb3Qgbm8gJF8hIjsKICAgIH0KICAgICRTZWxmLT57WE1MT2JqZWN0fSA9IEtlcm5lbDo6U3lzdGVtOjpYTUwtPm5ldyglUGFyYW0pOwogICAgJFNlbGYtPntEQk9iamVjdH0gID0gS2VybmVsOjpTeXN0ZW06OkRCLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRTZWxmLT57Q29uZmlnT2JqZWN0fSwKICAgICAgICBNYWluT2JqZWN0ICAgPT4gJFNlbGYtPntNYWluT2JqZWN0fSwKICAgICAgICBMb2dPYmplY3QgICAgPT4gJFNlbGYtPntMb2dPYmplY3R9LAoKICAgICk7CiAgICAkU2VsZi0+e1RpbWVPYmplY3R9ICA9IEtlcm5lbDo6U3lzdGVtOjpUaW1lLT5uZXcoJVBhcmFtKTsKICAgICRTZWxmLT57RW1haWxPYmplY3R9ID0gS2VybmVsOjpTeXN0ZW06OkVtYWlsLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRTZWxmLT57Q29uZmlnT2JqZWN0fSwKICAgICAgICBNYWluT2JqZWN0ICAgPT4gJFNlbGYtPntNYWluT2JqZWN0fSwKICAgICAgICBMb2dPYmplY3QgICAgPT4gJFNlbGYtPntMb2dPYmplY3R9LAogICAgICAgIERCT2JqZWN0ICAgICA9PiAkU2VsZi0+e0RCT2JqZWN0fSwKICAgICAgICBUaW1lT2JqZWN0ICAgPT4gJFNlbGYtPntUaW1lT2JqZWN0fSwKICAgICk7CgogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBTdXBwb3J0Q29uZmlnSGFzaEdldCgpCgpnZXQgYSBoYXNoIHJlZmVyZW5jZSB3aXRoIHJlcXVpcmVkIGNvbmZpZyBpbmZvcm1hdGlvbi4KCiAgICAkU3VwcG9ydC0+U3VwcG9ydENvbmZpZ0hhc2hHZXQoCiAgICAgICAgQ29uZmlnSGFzaCA9PiAkSGFzaFJlZiwKICAgICk7Cgo9Y3V0CgpzdWIgU3VwcG9ydENvbmZpZ0hhc2hHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIChxdyhDb25maWdIYXNoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGNoZWNrIGlmICRDb25maWdIYXNoIG5lIGEgSGFzaFJlZgogICAgaWYgKCByZWYoICRQYXJhbXtDb25maWdIYXNofSApIG5lICdIQVNIJyApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0KICAgICAgICAgICAgLT5Mb2coIFByaW9yaXR5ID0+ICdlcnJvcicsIE1lc3NhZ2UgPT4gIkNvbmZpZ0hhc2ggbXVzdCBiZSBhIGhhc2ggcmVmZXJlbmNlISIgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBnZXQgdGhlIGRpcmVjdG9yeSBuYW1lCiAgICBteSAkRGlyTmFtZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAnL0tlcm5lbC9TeXN0ZW0vU3VwcG9ydC8nOwoKICAgICMgcmVhZCBhbGwgYXZhaWxpYmxlIG1vZHVsZXMgaW4gQExpc3QKICAgIG15IEBMaXN0ID0gZ2xvYiggJERpck5hbWUgLiAiLyoucG0iICk7CiAgICBmb3IgbXkgJEZpbGUgKEBMaXN0KSB7CgogICAgICAgICMgcmVtb3ZlIC5wbQogICAgICAgICRGaWxlID1+IHMvXi4qXC8oLis/KVwucG0kLyQxLzsKICAgICAgICBteSAkR2VuZXJpY01vZHVsZSA9ICJLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6JEZpbGUiOwoKICAgICAgICAjIGxvYWQgbW9kdWxlICRHZW5lcmljTW9kdWxlIGFuZCBjaGVjayBpZiBsb2FkYWJsZQogICAgICAgIGlmICggJFNlbGYtPntNYWluT2JqZWN0fS0+UmVxdWlyZSgkR2VuZXJpY01vZHVsZSkgKSB7CgogICAgICAgICAgICAjIGNyZWF0ZSBuZXcgb2JqZWN0CiAgICAgICAgICAgIG15ICRTdXBwb3J0T2JqZWN0ID0gJEdlbmVyaWNNb2R1bGUtPm5ldyggJXskU2VsZn0gKTsKICAgICAgICAgICAgaWYgKCRTdXBwb3J0T2JqZWN0KSB7CiAgICAgICAgICAgICAgICBteSAkQXJyYXlSZWYgPSAkU3VwcG9ydE9iamVjdC0+U3VwcG9ydENvbmZpZ0FycmF5R2V0KCk7CiAgICAgICAgICAgICAgICBpZiAoICRBcnJheVJlZiAmJiByZWYoJEFycmF5UmVmKSBlcSAnQVJSQVknICkgewogICAgICAgICAgICAgICAgICAgICRQYXJhbXtDb25maWdIYXNofS0+eyRGaWxlfSA9ICRBcnJheVJlZjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAxOwp9Cgo9aXRlbSBTdXBwb3J0SW5mb0dldCgpCgpnZXQgYSBoYXNoIHJlZmVyZW5jZSB3aXRoIHN1cHBvcnQgaW5mb3JtYXRpb24uCgogICAgJFN1cHBvcnQtPlN1cHBvcnRJbmZvR2V0KAogICAgICAgIERhdGFIYXNoID0+ICREYXRhSGFzaCwKICAgICAgICBJbnB1dEhhc2ggPT4gJElucHV0SGFzaCwKICAgICk7Cgo9Y3V0CgpzdWIgU3VwcG9ydEluZm9HZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIChxdyhEYXRhSGFzaCBJbnB1dEhhc2gpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRffSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coIFByaW9yaXR5ID0+ICdlcnJvcicsIE1lc3NhZ2UgPT4gIk5lZWQgJF8hIiApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgY2hlY2sgaWYgJERhdGFIYXNoIGFuZCAkSW5wdXRIYXNoIG5lIGEgSGFzaFJlZgogICAgaWYgKCByZWYoICRQYXJhbXtEYXRhSGFzaH0gKSBuZSAnSEFTSCcgfHwgcmVmKCAkUGFyYW17SW5wdXRIYXNofSApIG5lICdIQVNIJyApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gIkRhdGFIYXNoIGFuZCBJbnB1dEhhc2ggbXVzdCBiZSBhIGhhc2ggcmVmZXJlbmNlISIKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGdldCB0aGUgZGlyZWN0b3J5IG5hbWUKICAgIG15ICREaXJOYW1lID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICcvS2VybmVsL1N5c3RlbS9TdXBwb3J0Lyc7CgogICAgIyByZWFkIGFsbCBhdmFpbGlibGUgbW9kdWxlcyBpbiBATGlzdAogICAgbXkgQExpc3QgPSBnbG9iKCAkRGlyTmFtZSAuICIvKi5wbSIgKTsKICAgIGZvciBteSAkRmlsZSAoQExpc3QpIHsKCiAgICAgICAgIyByZW1vdmUgLnBtCiAgICAgICAgJEZpbGUgPX4gcy9eLipcLyguKz8pXC5wbSQvJDEvOwogICAgICAgIG15ICRHZW5lcmljTW9kdWxlID0gIktlcm5lbDo6U3lzdGVtOjpTdXBwb3J0OjokRmlsZSI7CgogICAgICAgICMgbG9hZCBtb2R1bGUgJEdlbmVyaWNNb2R1bGUgYW5kIGNoZWNrIGlmIGxvYWRhYmxlCiAgICAgICAgaWYgKCAkU2VsZi0+e01haW5PYmplY3R9LT5SZXF1aXJlKCRHZW5lcmljTW9kdWxlKSApIHsKCiAgICAgICAgICAgICMgY3JlYXRlIG5ldyBvYmplY3QKICAgICAgICAgICAgbXkgJFN1cHBvcnRPYmplY3QgPSAkR2VuZXJpY01vZHVsZS0+bmV3KCAleyRTZWxmfSApOwogICAgICAgICAgICBpZiAoICRTdXBwb3J0T2JqZWN0ICYmICRQYXJhbXtJbnB1dEhhc2h9LT57JEZpbGV9ICkgewogICAgICAgICAgICAgICAgbXkgJEFycmF5UmVmCiAgICAgICAgICAgICAgICAgICAgPSAkU3VwcG9ydE9iamVjdC0+U3VwcG9ydEluZm9HZXQoIE1vZHVsZUlucHV0SGFzaCA9PiAkUGFyYW17SW5wdXRIYXNofS0+eyRGaWxlfSwKICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICMgY2hlY2sgaWYgcmV0dXJuIHZhbHVlIGlzIGEgdmFsaWQgYXJyYXlyZWYKICAgICAgICAgICAgICAgIGlmICggQHskQXJyYXlSZWZ9ICkgewogICAgICAgICAgICAgICAgICAgIG15ICRTdHJ1Y3R1cmVPSyA9IDE7CgogICAgICAgICAgICAgICAgICAgICMgY2hlY2sgaWYgdGhlIGFycmF5cmVmIGluY2x1ZGVzIG9ubHkgdmFsaWQgaGFzaHJlZnMKICAgICAgICAgICAgICAgICAgICBmb3IgbXkgJEVsZW1lbnQgKCBAeyRBcnJheVJlZn0gKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggcmVmKCRFbGVtZW50KSBuZSAnSEFTSCcgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkU3RydWN0dXJlT0sgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICggJFN0cnVjdHVyZU9LIGVxICIxIiApIHsKICAgICAgICAgICAgICAgICAgICAgICAgJFBhcmFte0RhdGFIYXNofS0+eyRGaWxlfSA9ICRBcnJheVJlZjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gMTsKfQoKPWl0ZW0gQWRtaW5DaGVja3NHZXQoKQoKZ2V0IGEgaGFzaCByZWZlcmVuY2Ugd2l0aCBwb3NzaWJpbGl0eSBjaGVja3MuCgogICAgbXkgJExpc3QgPSAkU3VwcG9ydC0+QWRtaW5DaGVja3NHZXQoRGF0YUhhc2ggPT4gJERhdGFIYXNoKTsKCj1jdXQKCnN1YiBBZG1pbkNoZWNrc0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgKHF3KERhdGFIYXNoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGNoZWNrIGlmICREYXRhSGFzaCBuZSBhIEhhc2hSZWYKICAgIGlmICggcmVmKCAkUGFyYW17RGF0YUhhc2h9ICkgbmUgJ0hBU0gnICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fQogICAgICAgICAgICAtPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiRGF0YUhhc2ggbXVzdCBiZSBhIGhhc2ggcmVmZXJlbmNlISIgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBnZXQgdGhlIGRpcmVjdG9yeSBuYW1lCiAgICBteSAkRGlyTmFtZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAnL0tlcm5lbC9TeXN0ZW0vU3VwcG9ydC8nOwoKICAgICMgcmVhZCBhbGwgYXZhaWxpYmxlIG1vZHVsZXMgaW4gQExpc3QKICAgIG15IEBMaXN0ID0gZ2xvYiggJERpck5hbWUgLiAiLyoucG0iICk7CgogICAgTU9EVUxFOgogICAgZm9yIG15ICRGaWxlIChATGlzdCkgewoKICAgICAgICAjIHJlbW92ZSAucG0KICAgICAgICAkRmlsZSA9fiBzL14uKlwvKC4rPylcLnBtJC8kMS87CiAgICAgICAgbXkgJEdlbmVyaWNNb2R1bGUgPSAiS2VybmVsOjpTeXN0ZW06OlN1cHBvcnQ6OiRGaWxlIjsKCiAgICAgICAgIyBsb2FkIG1vZHVsZSAkR2VuZXJpY01vZHVsZSBhbmQgY2hlY2sgaWYgbG9hZGFibGUKICAgICAgICBpZiAoICEkU2VsZi0+e01haW5PYmplY3R9LT5SZXF1aXJlKCRHZW5lcmljTW9kdWxlKSApIHsKCiAgICAgICAgICAgICMgVE9ETyBMb2cKICAgICAgICAgICAgbmV4dCBNT0RVTEU7CiAgICAgICAgfQoKICAgICAgICAjIGNyZWF0ZSBuZXcgb2JqZWN0CiAgICAgICAgbXkgJFN1cHBvcnRPYmplY3QgPSAkR2VuZXJpY01vZHVsZS0+bmV3KCAleyRTZWxmfSApOwoKICAgICAgICAjIHJldHVybiBpZiBpbnN0YW5jZSBjYW4gbm90IGNyZWF0ZQogICAgICAgIGlmICggISRTdXBwb3J0T2JqZWN0ICkgewoKICAgICAgICAgICAgIyBUT0RPIExvZwogICAgICAgICAgICBuZXh0IE1PRFVMRTsKICAgICAgICB9CgogICAgICAgICMgZ2V0IGFkbWluIGNoZWNrIGRhdGEKICAgICAgICBteSAkQWRtaW5DaGVja1JlZiA9ICRTdXBwb3J0T2JqZWN0LT5BZG1pbkNoZWNrc0dldCgpOwoKICAgICAgICAjIGNoZWNrIGlmIHJldHVybiB2YWx1ZSBpcyBhIHZhbGlkIGFycmF5IHJlZmVyZW5jZQogICAgICAgIGlmICggISRBZG1pbkNoZWNrUmVmIHx8IHJlZiAkQWRtaW5DaGVja1JlZiBuZSAnQVJSQVknIHx8ICFAeyRBZG1pbkNoZWNrUmVmfSApIHsKCiAgICAgICAgICAgICMgVE9ETyBMb2cKICAgICAgICAgICAgbmV4dCBNT0RVTEU7CiAgICAgICAgfQoKICAgICAgICAjIGV4dHJhY3QgYWxsIHZhbGlkIGVsZW1lbnRzCiAgICAgICAgbXkgQENsZWFuZEFkbWluQ2hlY2tSZWYgPSBncmVwIHsgcmVmKCRfKSBlcSAnSEFTSCcgfSBAeyRBZG1pbkNoZWNrUmVmfTsKCiAgICAgICAgIyBhdHRhY2ggdGhlIGNsZWFuZWQgZWxlbWVudCBhcnJheQogICAgICAgICRQYXJhbXtEYXRhSGFzaH0tPnskRmlsZX0gPSBcQENsZWFuZEFkbWluQ2hlY2tSZWY7CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIFhNTFN0cmluZ0NyZWF0ZSgpCgpyZXR1cm5zIGEgc3RyaW5nIHdpdGggeG1sLgoKICAgIG15ICRMaXN0ID0gJFN1cHBvcnQtPlhNTFN0cmluZ0NyZWF0ZShEYXRhID0+ICREYXRhKTsKCjw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9Imlzby04ODU5LTEiPz4KPFN1cHBvcnRJbmZvPgogICAgPEhhcmR3YXJlPgogICAgICAgIDxNZW1vcnlTd2FwQ2hlY2s+CiAgICAgICAgICAgIDxDaGVjaz5PSzwvQ2hlY2s+CiAgICAgICAgICAgIDxDb21tZW50PlRoZSBIb3N0IFN5c3RlbSBoYXMgMTAxMSBNQiBNZW1vcnkgdG90YWwuIDEwOCBNQiBNZW1vcnkgZnJlZS4gNjQzIE1CIFN3YXAgdG90YWwuIDY0MyBNQiBTd2FwIGZyZWUuIDwvQ29tbWVudD4KICAgICAgICAgICAgPERlc2NyaXB0aW9uPkEgTWVtb3J5IENoZWNrLiBXZSB0cnkgdG8gZmluZCBvdXQgaWYgU3dhcEZyZWUgOiBTd2FwVG90YWwgJmx0OyA2MCAlIG9yIGlmIG1vcmUgdGhhbiAyMDAgTUIgU3dhcCBpcyB1c2VkLjwvRGVzY3JpcHRpb24+CiAgICAgICAgICAgIDxOYW1lPk1lbW9yeSBTd2FwIENoZWNrPC9OYW1lPgogICAgICAgICAgICA8S2V5Pk1lbW9yeVN3YXBDaGVjazwvS2V5PgogICAgICAgIDwvTWVtb3J5U3dhcENoZWNrPgogICAgPC9IYXJkd2FyZT4KPC9TdXBwb3J0SW5mbz4KCj1jdXQKCnN1YiBYTUxTdHJpbmdDcmVhdGUgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIChxdyhEYXRhSGFzaCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JF99ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CiAgICBpZiAoIHJlZiggJFBhcmFte0RhdGFIYXNofSApIG5lICdIQVNIJyApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0KICAgICAgICAgICAgLT5Mb2coIFByaW9yaXR5ID0+ICdlcnJvcicsIE1lc3NhZ2UgPT4gIkRhdGFIYXNoIG11c3QgYmUgYSBoYXNoIHJlZmVyZW5jZSEiICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIG15ICRYTUxIYXNoID0gW107CiAgICBmb3IgbXkgJE1vZHVsZSAoIGtleXMgJXsgJFBhcmFte0RhdGFIYXNofSB9ICkgewogICAgICAgIGZvciBteSAkRGF0YUhhc2hSb3cgKCBAeyAkUGFyYW17RGF0YUhhc2h9LT57JE1vZHVsZX0gfSApIHsKICAgICAgICAgICAgbXkgJERhdGEgPSB7fTsKICAgICAgICAgICAgZm9yIG15ICRFbGVtZW50ICgga2V5cyAleyREYXRhSGFzaFJvd30gKSB7CiAgICAgICAgICAgICAgICBpZiAoICRFbGVtZW50IGVxICdLZXknICkgewogICAgICAgICAgICAgICAgICAgIG5leHQ7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgIyByZW1vdmUgbmV3bGluZXMKICAgICAgICAgICAgICAgICREYXRhSGFzaFJvdy0+eyRFbGVtZW50fSA9fiBzL1wwMTVcMDEyfFwwMTJ8XDAxNS8vZzsKICAgICAgICAgICAgICAgICREYXRhLT57JEVsZW1lbnR9LT5bMV0tPntDb250ZW50fSA9ICREYXRhSGFzaFJvdy0+eyRFbGVtZW50fTsKICAgICAgICAgICAgfQogICAgICAgICAgICAkWE1MSGFzaC0+WzFdLT57U3VwcG9ydEluZm99LT5bMV0tPnskTW9kdWxlfS0+WzFdLT57ICREYXRhSGFzaFJvdy0+e0tleX0gfS0+WzFdID0gJERhdGE7CiAgICAgICAgfQogICAgfQoKICAgIG15ICRYTUxTdHJpbmcgPSAkU2VsZi0+e1hNTE9iamVjdH0tPlhNTEhhc2gyWE1MKCBAeyRYTUxIYXNofSApOwoKICAgIHJldHVybiAkWE1MU3RyaW5nOwp9CgpzdWIgVGFyUGFja2FnZVdyaXRlIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoT3V0cHV0TmFtZSBPdXRwdXRQYXRoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICBta2RpciggJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICIvdmFyL3RtcC9zdXBwb3J0IiApOwoKICAgICRTZWxmLT57VGFyT2JqZWN0fSA9IEFyY2hpdmU6OlRhci0+bmV3KCk7CgogICAgaWYgKCAkUGFyYW17RGlyTmFtZX0gKSB7CgogICAgICAgICMgYWRkIGZpbGVzIHRvIHRoZSB0YXIgYXJjaGl2ZQogICAgICAgICRTZWxmLT57VGFyT2JqZWN0fS0+YWRkX2ZpbGVzKCAkU2VsZi0+UmVhZFRyZWUoIFRyZWUgPT4gJFBhcmFte0Rpck5hbWV9ICkgKSBvciByZXR1cm47CiAgICB9CiAgICBlbHNpZiAoICRQYXJhbXtGaWxlTmFtZX0gKSB7CgogICAgICAgICMgYWRkIGZpbGVzIHRvIHRoZSB0YXIgYXJjaGl2ZQogICAgICAgICRTZWxmLT57VGFyT2JqZWN0fS0+YWRkX2ZpbGVzKCAkUGFyYW17RmlsZU5hbWV9ICkgb3IgcmV0dXJuOwogICAgfQoKICAgICMgd3JpdGUgdGFyIGFyY2hpdiB0byBPVFJTX0hPTUUvdmFyL3RtcC9vdHJza2VybmVsLnRhcgogICAgJFNlbGYtPntUYXJPYmplY3R9LT53cml0ZSggJFBhcmFte091dHB1dFBhdGh9IC4gJFBhcmFte091dHB1dE5hbWV9LCAwICkKICAgICAgICBvciByZXR1cm47ICAgICMgQXJjaGl2ZSBzY2hyZWliZW4KCiAgICByZXR1cm4gJFBhcmFte091dHB1dE5hbWV9Owp9CgpzdWIgUmVhZFRyZWUgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIChxdyhUcmVlKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KICAgIG15ICRha3RkaXIgPSAkUGFyYW17VHJlZX07CiAgICBsb2NhbCAqRElSOwogICAgbXkgQGZsaXN0ID0gKCk7CgogICAgb3BlbmRpciggRElSLCAkYWt0ZGlyICkgb3IgZG8gewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCAiRXJyb3IgcmVhZGluZyBkaXJlY3RvcnkgJyRha3RkaXInOiAkXyEiICk7CiAgICAgICAgcmV0dXJuOwogICAgfTsKCiAgICB3aGlsZSAoIG15ICRlbnRyeSA9IHJlYWRkaXIoRElSKSApIHsKICAgICAgICBuZXh0IGlmICRlbnRyeSBlcSAiLiIgfHwgJGVudHJ5IGVxICIuLiI7CgogICAgICAgIGlmICggLWQgJGFrdGRpciAuICIvIiAuICRlbnRyeSApIHsKICAgICAgICAgICAgcHVzaCBAZmxpc3QsICRTZWxmLT5SZWFkVHJlZSggVHJlZSA9PiAkYWt0ZGlyIC4gIi8iIC4gJGVudHJ5ICk7CiAgICAgICAgICAgIG5leHQ7CiAgICAgICAgfQoKICAgICAgICBwdXNoIEBmbGlzdCwgJGFrdGRpciAuICIvIiAuICRlbnRyeTsKICAgIH0KCiAgICBjbG9zZWRpcihESVIpOwoKICAgIHJldHVybiBAZmxpc3Q7Cn0KCnN1YiBDcmVhdGVQYWNrYWdlVG9TZW5kIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoRGF0YUhhc2gpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRffSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coIFByaW9yaXR5ID0+ICdlcnJvcicsIE1lc3NhZ2UgPT4gIk5lZWQgJF8hIiApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQogICAgbXkgJFhNTFN0cmluZyA9ICRTZWxmLT5YTUxTdHJpbmdDcmVhdGUoIERhdGFIYXNoID0+ICRQYXJhbXtEYXRhSGFzaH0sICk7CiAgICBteSAkVG1wWE1MOwogICAgb3BlbiggJFRtcFhNTCwgJz4nLCAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gIi92YXIvdG1wL3N1cHBvcnQvY2hlY2sueG1sIiApOwogICAgcHJpbnQgJFRtcFhNTCAkWE1MU3RyaW5nOwogICAgY2xvc2UoJFRtcFhNTCk7CgogICAgIyBhZGQgZmlsZXMgdG8gdGhlIHRhciBhcmNoaXZlCiAgICAkU2VsZi0+e1Rhck9iamVjdH0gPSBBcmNoaXZlOjpUYXItPm5ldygpOwogICAgJFNlbGYtPntUYXJPYmplY3R9LT5hZGRfZmlsZXMoCiAgICAgICAgJFNlbGYtPlJlYWRUcmVlKCBUcmVlID0+ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAiL3Zhci90bXAvc3VwcG9ydC8iICkgKQogICAgICAgIG9yIGRpZSAiQ291bGQgbm90IGFkZDogJF8hIjsKICAgICRTZWxmLT57VGFyT2JqZWN0fS0+d3JpdGUoICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAiL3Zhci90bXAvc3VwcG9ydC50YXIiLCAwICkKICAgICAgICBvciBkaWUgIkNvdWxkIG5vdCB3cml0ZTogJF8hIjsgICAgIyBBcmNoaXZlIHNjaHJlaWJlbgoKICAgIG15ICRHemlwOwogICAgb3BlbiggJEd6aXAsICc8JywgJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICIvdmFyL3RtcC9zdXBwb3J0LnRhciIgKTsKICAgIGJpbm1vZGUoJEd6aXApOwoKICAgIG15ICRUbXBHemlwID0gJyc7CiAgICB3aGlsZSAoPCRHemlwPikgewogICAgICAgICRUbXBHemlwIC49ICRfOwogICAgfQogICAgY2xvc2UoJEd6aXApOwogICAgaWYgKCAkU2VsZi0+e01haW5PYmplY3R9LT5SZXF1aXJlKCJDb21wcmVzczo6WmxpYiIpICkgewogICAgICAgIG15ICRHekNvbnRlbnQgPSBDb21wcmVzczo6WmxpYjo6bWVtR3ppcCgkVG1wR3ppcCk7CiAgICAgICAgcmV0dXJuICRHekNvbnRlbnQ7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICByZXR1cm4gJFRtcEd6aXA7CiAgICB9Cn0KCnN1YiBTdXBwb3J0U2VuZEluZm8gewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkTWVzc2FnZSA9ICIiOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgKHF3KFN1cHBvcnRTdHJpbmcpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRffSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coIFByaW9yaXR5ID0+ICdlcnJvcicsIE1lc3NhZ2UgPT4gIk5lZWQgJF8hIiApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgc2VuZCBtYWlsIHRvIGdhdGV3YXkKICAgIGlmICgkU2VsZi0+e0VtYWlsT2JqZWN0fS0+U2VuZCgKICAgICAgICAgICAgRnJvbSAgICAgICA9PiAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnQWRtaW5FbWFpbCcpLAogICAgICAgICAgICBUbyAgICAgICAgID0+ICdzdXBwb3J0QG90cnMuY29tJywKICAgICAgICAgICAgU3ViamVjdCAgICA9PiAnQ3VzdG9tZXIgU3lzdGVtSW5mbyBmcm9tJywKICAgICAgICAgICAgVHlwZSAgICAgICA9PiAndGV4dC9wbGFpbicsCiAgICAgICAgICAgIENoYXJzZXQgICAgPT4gJ3V0Zi04JywKICAgICAgICAgICAgQm9keSAgICAgICA9PiAnQ3VzdG9tZXIgU3VwcG9ydEluZm8nLAogICAgICAgICAgICBMb29wICAgICAgID0+IDEsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBub3QgcmVxdWlyZWQsIHJlbW92ZXMgc210cCBmcm9tCiAgICAgICAgICAgIEF0dGFjaG1lbnQgPT4gWwogICAgICAgICAgICAgICAgeyAgIEZpbGVuYW1lICAgID0+ICIkUGFyYW17U3VwcG9ydElEfSIsCiAgICAgICAgICAgICAgICAgICAgQ29udGVudCAgICAgPT4gIiRQYXJhbXtTdXBwb3J0U3RyaW5nfSIsCiAgICAgICAgICAgICAgICAgICAgQ29udGVudFR5cGUgPT4gImFwcGxpY2F0aW9uL3Rhci5neiIsCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIF0sCiAgICAgICAgKQogICAgICAgICkKICAgIHsKICAgICAgICAkTWVzc2FnZSA9ICJFbWFpbCBzZW50IHRvIHRoZSAoKG90cnMpKSBzdXBwb3J0IHRlYW0uXG4iOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgJE1lc3NhZ2UKICAgICAgICAgICAgPSAnQ2FuXCd0IHNlbmQgZW1haWwgdG8gdGhlICgob3RycykpIHN1cHBvcnQgdGVhbSEnIC4gIlxuXG4iCiAgICAgICAgICAgIC4gIllvdSB3aWxsIGZvdW5kIHRoZSBvdHJzIHN5c3RlbSBpbmZvcm1hdGlvbiBwYWNrYWdlIGF0XG4iCiAgICAgICAgICAgIC4gIklmIHlvdSB3b3VsZCBsaWtlIHRvIHVzZSBPVFJTIHN1cHBvcnQgc2VydmljZXMgcGxlYXNlIHNlbmQgdGhlIHBhY2thZ2UgdG8gc3VwcG9ydFxAb3Rycy5jb20gb3IgY2FsbFxuIgogICAgICAgICAgICAuICJvdXIgc3VwcG9ydCB0ZWFtIHBlciBwaG9uZSB0byByZXZpZXcgdGhlIG5leHQgc3RlcFxuXG4iCiAgICAgICAgICAgIC4gIiBNb3JlIGFib3V0IE9UUlMgc3VwcG9ydCBvciBmYWNlLXRvLWZhY2UgY29udGFjdCBpbmZvcm1hdGlvbiB5b3Ugd2lsbCBmb3VuZCBhdFxuIgogICAgICAgICAgICAuICdodHRwOi8vd3d3Lm90cnMuY29tLycgLiAiXG5cbiI7CiAgICB9CiAgICByZXR1cm4gJE1lc3NhZ2U7Cn0KCjE7Cgo9YmFjawoKPWhlYWQxIFRFUk1TIEFORCBDT05ESVRJT05TCgpUaGlzIHNvZnR3YXJlIGlzIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoaHR0cDovL290cnMub3JnLykuCgpUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQp0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChHUEwpLiBJZiB5b3UKZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwudHh0LgoKPWN1dAoKPWhlYWQxIFZFUlNJT04KCiRSZXZpc2lvbjogMS44ICQgJERhdGU6IDIwMDcvMTEvMjIgMTE6NDk6NDAgJAoKPWN1dAo=
IyAtLQojIEtlcm5lbC9TeXN0ZW0vU3VwcG9ydC9EYXRhYmFzZS5wbSAtIGFsbCByZXF1aXJlZCBzeXN0ZW0gaW5mb3JtYXRpb25zCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDcgT1RSUyBHbWJILCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IERhdGFiYXNlLnBtLHYgMS44IDIwMDcvMTEvMjIgMTI6MTY6Mzkgc3IgRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpTdXBwb3J0OjpEYXRhYmFzZTsKCnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKCnVzZSB2YXJzIHF3KEBJU0EgJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS44ICQpIFsxXTsKCj1oZWFkMSBOQU1FCgpLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6RGF0YWJhc2UgLSBnbG9iYWwgc3lzdGVtIGluZm9ybWF0aW9ucwoKPWhlYWQxIFNZTk9QU0lTCgpBbGwgcmVxdWlyZWQgc3lzdGVtIGluZm9ybWF0aW9ucyB0byBhIHJ1bm5pbmcgT1RSUyBob3N0LgoKPWhlYWQxIFBVQkxJQyBJTlRFUkZBQ0UKCj1vdmVyIDQKCj1jdXQKCj1pdGVtIG5ldygpCgpjcmVhdGUgRGF0YWJhc2UgaW5mbyBvYmplY3QKCiAgICB1c2UgS2VybmVsOjpDb25maWc7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkxvZzsKICAgIG15ICRDb25maWdPYmplY3QgPSBLZXJuZWw6OkNvbmZpZy0+bmV3KCk7CiAgICBteSAkTG9nT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkxvZy0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgKTsKCiAgICAkU3lzdGVtSW5mb09iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpTdXBwb3J0OjpEYXRhYmFzZS0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCA9PiAkTG9nT2JqZWN0LAogICAgKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgb2JqZWN0cwogICAgZm9yIChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0IE1haW5PYmplY3QgREJPYmplY3QpKSB7CiAgICAgICAgJFNlbGYtPnskX30gPSAkUGFyYW17JF99IHx8IGRpZSAiR290IG5vICRfISI7CiAgICB9CgogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBTdXBwb3J0Q29uZmlnQXJyYXlHZXQoKQoKcmV0dXJuIGFuIGFycmF5IHJlZmVyZW5jZSB3aXRoIHJlcXVpcmVkIGNvbmZpZyBpbmZvcm1hdGlvbi4KCiAgICAkQXJyYXlSZWYgPSAkU3VwcG9ydC0+U3VwcG9ydENvbmZpZ0FycmF5R2V0KCk7CgogICAgbXkgJENvbmZpZ0FycmF5ID0gWwogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0+ICdUaWNrZXREdW1wJywKICAgICAgICAgICAgTmFtZSA9PiAnRHVtcCBUaWNrZXRzJywKICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSB0ZWxsIG1lIGhvdyBtYW55IGxhdGVzdCBUaWNrZXRzIHdlIHNodXQgZHVtcD8nLAogICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAgICAgICAgICAgICBUeXBlID0+ICdTZWxlY3QnLAogICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgQWxsID0+ICdBbGwnLAogICAgICAgICAgICAgICAgICAgIDAgPT4gJzAnLAogICAgICAgICAgICAgICAgICAgIDEwID0+ICdMYXN0IDEwJywKICAgICAgICAgICAgICAgICAgICAxMDAgPT4gJ0xhc3QgMTAwJywKICAgICAgICAgICAgICAgICAgICAxMDAwID0+ICdMYXN0IDEwMDAnLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgfSwKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0+ICdBcGFjaGVIb21lJywKICAgICAgICAgICAgTmFtZSA9PiAnQXBhY2hlIEhvbWUgRGlyZWN0b3J5JywKICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSB0ZWxsIG1lIHRoZSBwYXRoIHRvIHRoZSBBcGFjaGUgaG9tZSBkaXJlY3RvcnkgKC9ldGMvYXBhY2hlMiknLAogICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAgICAgICAgICAgICBUeXBlID0+ICdUZXh0JywKICAgICAgICAgICAgICAgIFNpemUgPT4gNDAsCiAgICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgIF07Cgo9Y3V0CgpzdWIgU3VwcG9ydENvbmZpZ0FycmF5R2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIEdldCBpbmZvcm1hdGlvbiBhYm91dCBhbGwgZGF0YWJhc2VzCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCgogICAgIyBjcmVhdGUgY29uZmlnIGFycmF5CiAgICBteSAkQ29uZmlnQXJyYXkgPSBbXTsKCiAgICAjICAgIG15ICRDb25maWdBcnJheSA9IFsKICAgICMgICAgICAgIHsKICAgICMgICAgICAgICAgICBLZXkgPT4gJ1RpY2tldER1bXAnLAogICAgIyAgICAgICAgICAgIE5hbWUgPT4gJ0R1bXAgVGlja2V0cycsCiAgICAjICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSB0ZWxsIG1lIGhvdyBtYW55IGxhdGVzdCBUaWNrZXRzIHdlIHNodXQgZHVtcD8nLAogICAgIyAgICAgICAgICAgSW5wdXQgPT4gewogICAgIyAgICAgICAgICAgICAgICBUeXBlID0+ICdTZWxlY3QnLAogICAgIyAgICAgICAgICAgICAgICBEYXRhID0+IHsKICAgICMgICAgICAgICAgICAgICAgICBBbGwgPT4gJ0FsbCcsCiAgICAjICAgICAgICAgICAgICAgICAgIDAgPT4gJzAnLAogICAgIyAgICAgICAgICAgICAgICAgICAgMTAgPT4gJ0xhc3QgMTAnLAogICAgIyAgICAgICAgICAgICAgICAgICAgMTAwID0+ICdMYXN0IDEwMCcsCiAgICAjICAgICAgICAgICAgICAgICAgIDEwMDAgPT4gJ0xhc3QgMTAwMCcsCiAgICAjICAgICAgICAgICAgICAgIH0sCiAgICAjICAgICAgICAgICAgfSwKICAgICMgICAgICAgIH0sCiAgICAjICAgIF07CgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgIyBHZXQgaW5mb3JtYXRpb24gYWJvdXQgdXNlZCBkYXRhYmFzZQogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwoKICAgICMgdHJ5IHRvIGZpbmQgb3V0IHdoaWNoIHRpY2tldCBkYXRhYmFzZSBpcyBjb25maWd1cmVkCiAgICBteSAkRGF0YWJhc2VUeXBlID0gJFNlbGYtPntEQk9iamVjdH0tPnsnREI6OlR5cGUnfTsKCiAgICAjIHRyeSB0byBnZXQgYXZhaWxpYmxlIG1vZHVsZXMgYW5kIHRoZSBkaXJlY3RvcnkgbmFtZQogICAgbXkgJERpck5hbWUgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gIi9LZXJuZWwvU3lzdGVtL1N1cHBvcnQvRGF0YWJhc2UiOwoKICAgICMgcmVhZCBhbGwgYXZhaWxpYmxlIG1vZHVsZXMgaW4gQExpc3QKICAgIG15IEBMaXN0ID0gZ2xvYiggJERpck5hbWUgLiAiLyoucG0iICk7CiAgICBmb3IgbXkgJEZpbGUgKEBMaXN0KSB7CgogICAgICAgICMgcmVtb3ZlIC5wbQogICAgICAgICRGaWxlID1+IHMvXi4qXC8oLis/KVwucG0kLyQxLzsKICAgICAgICBpZiAoICREYXRhYmFzZVR5cGUgPX4gL09EQkMvaSApIHsKICAgICAgICAgICAgJERhdGFiYXNlVHlwZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdEYXRhYmFzZTo6VHlwZScpOwogICAgICAgIH0KICAgICAgICBpZiAoICREYXRhYmFzZVR5cGUgZXEgJEZpbGUgKSB7CiAgICAgICAgICAgIG15ICRHZW5lcmljTW9kdWxlID0gIktlcm5lbDo6U3lzdGVtOjpTdXBwb3J0OjpEYXRhYmFzZTo6JEZpbGUiOwoKICAgICAgICAgICAgIyBsb2FkIG1vZHVsZSAkR2VuZXJpY01vZHVsZSBhbmQgY2hlY2sgaWYgbG9hZGFibGUKICAgICAgICAgICAgaWYgKCAkU2VsZi0+e01haW5PYmplY3R9LT5SZXF1aXJlKCRHZW5lcmljTW9kdWxlKSApIHsKCiAgICAgICAgICAgICAgICAjIGNyZWF0ZSBuZXcgb2JqZWN0CiAgICAgICAgICAgICAgICBteSAkU3VwcG9ydE9iamVjdCA9ICRHZW5lcmljTW9kdWxlLT5uZXcoICV7JFNlbGZ9ICk7CiAgICAgICAgICAgICAgICBpZiAoJFN1cHBvcnRPYmplY3QpIHsKICAgICAgICAgICAgICAgICAgICBteSAkQXJyYXlSZWYgPSAkU3VwcG9ydE9iamVjdC0+U3VwcG9ydENvbmZpZ0FycmF5R2V0KCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCAkQXJyYXlSZWYgJiYgcmVmKCRBcnJheVJlZikgZXEgJ0FSUkFZJyApIHsKICAgICAgICAgICAgICAgICAgICAgICAgcHVzaCggQHskQ29uZmlnQXJyYXl9LCBAeyRBcnJheVJlZn0gKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgIyByZXR1cm4gY29uZmlnIGFycmF5CiAgICByZXR1cm4gJENvbmZpZ0FycmF5Owp9Cgo9aXRlbSBTdXBwb3J0SW5mb0dldCgpCgpyZXR1cm5zIGEgYXJyYXkgcmVmZXJlbmNlIHdpdGggc3VwcG9ydCBpbmZvcm1hdGlvbi4KCiREYXRhYmFzZUFycmF5ID0+IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0+ICdQbGF0dGZvcm0nLAogICAgICAgICAgICAgICAgTmFtZSA9PiAnUGxhdHRmb3JtJywKICAgICAgICAgICAgICAgIENvbW1lbnQgPT4gJ0xpbnV4JywKICAgICAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgYWRkIG1vcmUgbWVtb3J5LicsCiAgICAgICAgICAgICAgICBDaGVjayA9PiAnT0snLAogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPT4gJ1ZlcnNpb24nLAogICAgICAgICAgICAgICAgTmFtZSA9PiAnVmVyc2lvbicsCiAgICAgICAgICAgICAgICBDb21tZW50ID0+ICdvcGVuU1VTRSAxMC4yJywKICAgICAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgYWRkIG1vcmUgbWVtb3J5LicsCiAgICAgICAgICAgICAgICBDaGVjayA9PiAnT0snLAogICAgICAgICAgICB9LAogICAgICAgIF07Cgo9Y3V0CgpzdWIgU3VwcG9ydEluZm9HZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkRGF0YUFycmF5ID0gW107CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoTW9kdWxlSW5wdXRIYXNoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KICAgIGlmICggcmVmKCAkUGFyYW17TW9kdWxlSW5wdXRIYXNofSApIG5lICdIQVNIJyApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0KICAgICAgICAgICAgLT5Mb2coIFByaW9yaXR5ID0+ICdlcnJvcicsIE1lc3NhZ2UgPT4gIk1vZHVsZUlucHV0SGFzaCBtdXN0IGJlIGEgaGFzaCByZWZlcmVuY2UhIiApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIEdldCBpbmZvcm1hdGlvbiBhYm91dCBhbGwgZGF0YWJhc2VzCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCgogICAgIyBwbGVhc2UgYWRkIGZvciBlYWNoIG5ldyBjaGVjayBhIHBhcnQgbGlrZSB0aGlzCiAgICAjICAgIG15ICRPbmVDaGVjayA9ICRTZWxmLT5DaGVjaygKICAgICMgICAgICAgIFR5cGUgPT4gJFBhcmFte01vZHVsZUlucHV0SGFzaH0tPntUeXBlfSB8fCAnJywKICAgICMgICAgKTsKICAgICMgICAgcHVzaCAoQHskRGF0YUFycmF5fSwgJE9uZUNoZWNrKTsKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIEdldCBpbmZvcm1hdGlvbiBhYm91dCB1c2VkIGRhdGFiYXNlCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCgogICAgIyB0cnkgdG8gZmluZCBvdXQgd2hpY2ggdGlja2V0IGRhdGFiYXNlIGlzIGNvbmZpZ3VyZWQKICAgIG15ICREYXRhYmFzZVR5cGUgPSAkU2VsZi0+e0RCT2JqZWN0fS0+eydEQjo6VHlwZSd9OwoKICAgICMgdHJ5IHRvIGdldCBhdmFpbGlibGUgbW9kdWxlcyBhbmQgdGhlIGRpcmVjdG9yeSBuYW1lCiAgICBteSAkRGlyTmFtZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAiL0tlcm5lbC9TeXN0ZW0vU3VwcG9ydC9EYXRhYmFzZSI7CgogICAgIyByZWFkIGFsbCBhdmFpbGlibGUgbW9kdWxlcyBpbiBATGlzdAogICAgbXkgQExpc3QgPSBnbG9iKCAkRGlyTmFtZSAuICIvKi5wbSIgKTsKICAgIGZvciBteSAkRmlsZSAoQExpc3QpIHsKCiAgICAgICAgIyByZW1vdmUgLnBtCiAgICAgICAgJEZpbGUgPX4gcy9eLipcLyguKz8pXC5wbSQvJDEvOwogICAgICAgIGlmICggJERhdGFiYXNlVHlwZSA9fiAvT0RCQy9pICkgewogICAgICAgICAgICAkRGF0YWJhc2VUeXBlID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0RhdGFiYXNlOjpUeXBlJyk7CiAgICAgICAgfQogICAgICAgIGlmICggJERhdGFiYXNlVHlwZSBlcSAkRmlsZSApIHsKICAgICAgICAgICAgbXkgJEdlbmVyaWNNb2R1bGUgPSAiS2VybmVsOjpTeXN0ZW06OlN1cHBvcnQ6OkRhdGFiYXNlOjokRmlsZSI7CgogICAgICAgICAgICAjIGxvYWQgbW9kdWxlICRHZW5lcmljTW9kdWxlIGFuZCBjaGVjayBpZiBsb2FkYWJsZQogICAgICAgICAgICBpZiAoICRTZWxmLT57TWFpbk9iamVjdH0tPlJlcXVpcmUoJEdlbmVyaWNNb2R1bGUpICkgewoKICAgICAgICAgICAgICAgICMgY3JlYXRlIG5ldyBvYmplY3QKICAgICAgICAgICAgICAgIG15ICRTdXBwb3J0T2JqZWN0ID0gJEdlbmVyaWNNb2R1bGUtPm5ldyggJXskU2VsZn0gKTsKICAgICAgICAgICAgICAgIGlmICgkU3VwcG9ydE9iamVjdCkgewogICAgICAgICAgICAgICAgICAgIG15ICRBcnJheVJlZiA9ICRTdXBwb3J0T2JqZWN0LT5TdXBwb3J0SW5mb0dldCgKICAgICAgICAgICAgICAgICAgICAgICAgTW9kdWxlSW5wdXRIYXNoID0+ICRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9LCApOwogICAgICAgICAgICAgICAgICAgIGlmICggJEFycmF5UmVmICYmIHJlZigkQXJyYXlSZWYpIGVxICdBUlJBWScgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2goIEB7JERhdGFBcnJheX0sIEB7JEFycmF5UmVmfSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gJERhdGFBcnJheTsKfQoKPWl0ZW0gQWRtaW5DaGVja3NHZXQoKQoKcmV0dXJucyBhIGFycmF5IHJlZmVyZW5jZSB3aXRoIEFkbWluQ2hlY2tzIGluZm9ybWF0aW9uLgoKJERhdGFiYXNlQXJyYXkgPT4gWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPT4gJ1BsYXR0Zm9ybScsCiAgICAgICAgICAgICAgICBOYW1lID0+ICdQbGF0dGZvcm0nLAogICAgICAgICAgICAgICAgQ29tbWVudCA9PiAnTGludXgnLAogICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSBhZGQgbW9yZSBtZW1vcnkuJywKICAgICAgICAgICAgICAgIENoZWNrID0+ICdPSycsCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9PiAnVmVyc2lvbicsCiAgICAgICAgICAgICAgICBOYW1lID0+ICdWZXJzaW9uJywKICAgICAgICAgICAgICAgIENvbW1lbnQgPT4gJ29wZW5TVVNFIDEwLjInLAogICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSBhZGQgbW9yZSBtZW1vcnkuJywKICAgICAgICAgICAgICAgIENoZWNrID0+ICdPSycsCiAgICAgICAgICAgIH0sCiAgICAgICAgXTsKCj1jdXQKCnN1YiBBZG1pbkNoZWNrc0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICREYXRhQXJyYXkgPSBbXTsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIChxdygpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRffSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coIFByaW9yaXR5ID0+ICdlcnJvcicsIE1lc3NhZ2UgPT4gIk5lZWQgJF8hIiApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgICMgR2V0IGluZm9ybWF0aW9uIGFib3V0IGFsbCBkYXRhYmFzZXMKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKCiAgICAjIHBsZWFzZSBhZGQgZm9yIGVhY2ggbmV3IGNoZWNrIGEgcGFydCBsaWtlIHRoaXMKICAgICMgICAgbXkgJE9uZUNoZWNrID0gJFNlbGYtPkNoZWNrKCk7CiAgICAjICAgIHB1c2ggKEB7JERhdGFBcnJheX0sICRPbmVDaGVjayk7CgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgIyBHZXQgaW5mb3JtYXRpb24gYWJvdXQgdXNlZCBkYXRhYmFzZQogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwoKICAgICMgdHJ5IHRvIGZpbmQgb3V0IHdoaWNoIHRpY2tldCBkYXRhYmFzZSBpcyBjb25maWd1cmVkCiAgICBteSAkRGF0YWJhc2VUeXBlID0gJFNlbGYtPntEQk9iamVjdH0tPnsnREI6OlR5cGUnfTsKCiAgICAjIHRyeSB0byBnZXQgYXZhaWxpYmxlIG1vZHVsZXMgYW5kIHRoZSBkaXJlY3RvcnkgbmFtZQogICAgbXkgJERpck5hbWUgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gIi9LZXJuZWwvU3lzdGVtL1N1cHBvcnQvRGF0YWJhc2UiOwoKICAgICMgcmVhZCBhbGwgYXZhaWxpYmxlIG1vZHVsZXMgaW4gQExpc3QKICAgIG15IEBMaXN0ID0gZ2xvYiggJERpck5hbWUgLiAiLyoucG0iICk7CiAgICBmb3IgbXkgJEZpbGUgKEBMaXN0KSB7CgogICAgICAgICMgcmVtb3ZlIC5wbQogICAgICAgICRGaWxlID1+IHMvXi4qXC8oLis/KVwucG0kLyQxLzsKICAgICAgICBpZiAoICREYXRhYmFzZVR5cGUgPX4gL09EQkMvaSApIHsKICAgICAgICAgICAgJERhdGFiYXNlVHlwZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdEYXRhYmFzZTo6VHlwZScpOwogICAgICAgIH0KICAgICAgICBpZiAoICREYXRhYmFzZVR5cGUgPX4gL14kRmlsZS9pICkgewogICAgICAgICAgICBteSAkR2VuZXJpY01vZHVsZSA9ICJLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6RGF0YWJhc2U6OiRGaWxlIjsKCiAgICAgICAgICAgICMgbG9hZCBtb2R1bGUgJEdlbmVyaWNNb2R1bGUgYW5kIGNoZWNrIGlmIGxvYWRhYmxlCiAgICAgICAgICAgIGlmICggJFNlbGYtPntNYWluT2JqZWN0fS0+UmVxdWlyZSgkR2VuZXJpY01vZHVsZSkgKSB7CgogICAgICAgICAgICAgICAgIyBjcmVhdGUgbmV3IG9iamVjdAogICAgICAgICAgICAgICAgbXkgJFN1cHBvcnRPYmplY3QgPSAkR2VuZXJpY01vZHVsZS0+bmV3KCAleyRTZWxmfSApOwogICAgICAgICAgICAgICAgaWYgKCRTdXBwb3J0T2JqZWN0KSB7CiAgICAgICAgICAgICAgICAgICAgbXkgJEFycmF5UmVmID0gJFN1cHBvcnRPYmplY3QtPkFkbWluQ2hlY2tzR2V0KCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCAkQXJyYXlSZWYgJiYgcmVmKCRBcnJheVJlZikgZXEgJ0FSUkFZJyApIHsKICAgICAgICAgICAgICAgICAgICAgICAgcHVzaCggQHskRGF0YUFycmF5fSwgQHskQXJyYXlSZWZ9ICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgIH0KCiAgICByZXR1cm4gJERhdGFBcnJheTsKfQoKPWl0ZW0gX0NoZWNrKCkKCnJldHVybnMgYSBoYXNoIHJlZmVyZW5jZSB3aXRoIENoZWNrIGluZm9ybWF0aW9uLgoKJENoZWNrSGFzaCA9PgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPT4gJ1BsYXR0Zm9ybScsCiAgICAgICAgICAgICAgICBOYW1lID0+ICdQbGF0dGZvcm0nLAogICAgICAgICAgICAgICAgQ29tbWVudCA9PiAnTGludXgnLAogICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSBhZGQgbW9yZSBtZW1vcnkuJywKICAgICAgICAgICAgICAgIENoZWNrID0+ICdPSycsCiAgICAgICAgICAgIH07CgojIGNoZWNrIGlmIGNvbmZpZyB2YWx1ZSBhdmFpbGlibGUKaWYgKCRQYXJhbXtUeXBlfSkgewogICAgcHJpbnQgU1RERVJSICJUWVBFOiAiIC4gJFBhcmFte1R5cGV9Owp9Cgo9Y3V0CgpzdWIgX0NoZWNrIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgbXkgJFJldHVybkhhc2ggPSB7fTsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIChxdygpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRffSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coIFByaW9yaXR5ID0+ICdlcnJvcicsIE1lc3NhZ2UgPT4gIk5lZWQgJF8hIiApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgSWYgdXNlZCBPUyBpcyBhIGxpbnV4IHN5c3RlbQogICAgaWYgKCAkXk8gPX4gL2xpbnV4LyB8fCAvdW5peC8gfHwgL25ldGJzZC8gfHwgL2ZyZWVic2QvIHx8IC9EYXJ3aW4vICkgewoKICAgIH0KICAgIGVsc2lmICggJF5PID1+IC93aW4vaSApIHsKCiAgICB9CiAgICByZXR1cm4gJFJldHVybkhhc2g7Cn0KCjE7Cgo9YmFjawoKPWhlYWQxIFRFUk1TIEFORCBDT05ESVRJT05TCgpUaGlzIHNvZnR3YXJlIGlzIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoaHR0cDovL290cnMub3JnLykuCgpUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQp0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChHUEwpLiBJZiB5b3UKZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwudHh0LgoKPWN1dAoKPWhlYWQxIFZFUlNJT04KCiRSZXZpc2lvbjogMS44ICQgJERhdGU6IDIwMDcvMTEvMjIgMTI6MTY6MzkgJAoKPWN1dAo=
IyAtLQojIEtlcm5lbC9TeXN0ZW0vU3VwcG9ydC9PUy5wbSAtIGFsbCByZXF1aXJlZCBzeXN0ZW0gaW5mb3JtYXRpb25zCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDcgT1RSUyBHbWJILCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IE9TLnBtLHYgMS42IDIwMDcvMTEvMjIgMTI6Mjk6MDIgc3IgRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpTdXBwb3J0OjpPUzsKCnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKCnVzZSB2YXJzIHF3KEBJU0EgJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS42ICQpIFsxXTsKCj1oZWFkMSBOQU1FCgpLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6T1MgLSBnbG9iYWwgc3lzdGVtIGluZm9ybWF0aW9ucwoKPWhlYWQxIFNZTk9QU0lTCgpBbGwgcmVxdWlyZWQgc3lzdGVtIGluZm9ybWF0aW9ucyB0byBhIHJ1bm5pbmcgT1RSUyBob3N0LgoKPWhlYWQxIFBVQkxJQyBJTlRFUkZBQ0UKCj1vdmVyIDQKCj1jdXQKCj1pdGVtIG5ldygpCgpjcmVhdGUgT1MgaW5mbyBvYmplY3QKCnVzZSBLZXJuZWw6OkNvbmZpZzsKdXNlIEtlcm5lbDo6U3lzdGVtOjpMb2c7Cm15ICRDb25maWdPYmplY3QgPSBLZXJuZWw6OkNvbmZpZy0+bmV3KCk7Cm15ICRMb2dPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6TG9nLT5uZXcoCiAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKKTsKCiRTeXN0ZW1JbmZvT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OlN1cHBvcnQ6Ok9TLT5uZXcoCiAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgIExvZ09iamVjdCA9PiAkTG9nT2JqZWN0LAopOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGNoZWNrIG5lZWRlZCBvYmplY3RzCiAgICBmb3IgKHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QpKSB7CiAgICAgICAgJFNlbGYtPnskX30gPSAkUGFyYW17JF99IHx8IGRpZSAiR290IG5vICRfISI7CiAgICB9CgogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBTdXBwb3J0Q29uZmlnQXJyYXlHZXQoKQoKcmV0dXJuIGFuIGFycmF5IHJlZmVyZW5jZSB3aXRoIHJlcXVpcmVkIGNvbmZpZyBpbmZvcm1hdGlvbi4KCiAgICAkQXJyYXlSZWYgPSAkU3VwcG9ydC0+U3VwcG9ydENvbmZpZ0FycmF5R2V0KCk7CgogICAgbXkgJENvbmZpZ0FycmF5ID0gWwogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0+ICdUaWNrZXREdW1wJywKICAgICAgICAgICAgTmFtZSA9PiAnRHVtcCBUaWNrZXRzJywKICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSB0ZWxsIG1lIGhvdyBtYW55IGxhdGVzdCBUaWNrZXRzIHdlIHNodXQgZHVtcD8nLAogICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAgICAgICAgICAgICBUeXBlID0+ICdTZWxlY3QnLAogICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgQWxsID0+ICdBbGwnLAogICAgICAgICAgICAgICAgICAgIDAgPT4gJzAnLAogICAgICAgICAgICAgICAgICAgIDEwID0+ICdMYXN0IDEwJywKICAgICAgICAgICAgICAgICAgICAxMDAgPT4gJ0xhc3QgMTAwJywKICAgICAgICAgICAgICAgICAgICAxMDAwID0+ICdMYXN0IDEwMDAnLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgfSwKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0+ICdBcGFjaGVIb21lJywKICAgICAgICAgICAgTmFtZSA9PiAnQXBhY2hlIEhvbWUgRGlyZWN0b3J5JywKICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSB0ZWxsIG1lIHRoZSBwYXRoIHRvIHRoZSBBcGFjaGUgaG9tZSBkaXJlY3RvcnkgKC9ldGMvYXBhY2hlMiknLAogICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAgICAgICAgICAgICBUeXBlID0+ICdUZXh0JywKICAgICAgICAgICAgICAgIFNpemUgPT4gNDAsCiAgICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgIF07Cgo9Y3V0CgpzdWIgU3VwcG9ydENvbmZpZ0FycmF5R2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGNyZWF0ZSBjb25maWcgYXJyYXkKICAgIG15ICRDb25maWdBcnJheSA9IFsKCiAgICBdOwoKICAgICMgcmV0dXJuIGNvbmZpZyBhcnJheQogICAgcmV0dXJuICRDb25maWdBcnJheTsKfQoKPWl0ZW0gU3VwcG9ydEluZm9HZXQoKQoKcmV0dXJucyBhIGFycmF5IHJlZmVyZW5jZSB3aXRoIHN1cHBvcnQgaW5mb3JtYXRpb24uCgokT1NBcnJheSA9PiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9PiAnUGxhdHRmb3JtJywKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1BsYXR0Zm9ybScsCiAgICAgICAgICAgICAgICBDb21tZW50ID0+ICdMaW51eCcsCiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAnUGxlYXNlIGFkZCBtb3JlIG1lbW9yeS4nLAogICAgICAgICAgICAgICAgQ2hlY2sgPT4gJ09LJywKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0+ICdWZXJzaW9uJywKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1ZlcnNpb24nLAogICAgICAgICAgICAgICAgQ29tbWVudCA9PiAnb3BlblNVU0UgMTAuMicsCiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAnUGxlYXNlIGFkZCBtb3JlIG1lbW9yeS4nLAogICAgICAgICAgICAgICAgQ2hlY2sgPT4gJ09LJywKICAgICAgICAgICAgfSwKICAgICAgICBdOwoKPWN1dAoKc3ViIFN1cHBvcnRJbmZvR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoIHJlZiggJFBhcmFte01vZHVsZUlucHV0SGFzaH0gKSBuZSAnSEFTSCcgKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9CiAgICAgICAgICAgIC0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJNb2R1bGVJbnB1dEhhc2ggbXVzdCBiZSBhIGhhc2ggcmVmZXJlbmNlISIgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBhZGQgbmV3IGZ1bmN0aW9uIG5hbWUgaGVyZQogICAgbXkgQE1vZHVsZUxpc3QgPSAoCiAgICAgICAgJ19EaXN0cmlidXRpb25DaGVjaycsICdfS2VybmVsSW5mb0NoZWNrJywKICAgICk7CgogICAgbXkgQERhdGFBcnJheTsKCiAgICBGVU5DVElPTk5BTUU6CiAgICBmb3IgbXkgJEZ1bmN0aW9uTmFtZSAoQE1vZHVsZUxpc3QpIHsKCiAgICAgICAgIyBydW4gZnVuY3Rpb24gYW5kIGdldCBjaGVjayBkYXRhCiAgICAgICAgbXkgJENoZWNrID0gJFNlbGYtPiRGdW5jdGlvbk5hbWUoIFR5cGUgPT4gJFBhcmFte01vZHVsZUlucHV0SGFzaH0tPntUeXBlfSB8fCAnJywgKTsKCiAgICAgICAgbmV4dCBGVU5DVElPTk5BTUUgaWYgISRDaGVjazsKCiAgICAgICAgIyBhdHRhY2ggY2hlY2sgZGF0YSBpZiB2YWxpZAogICAgICAgIHB1c2ggQERhdGFBcnJheSwgJENoZWNrOwogICAgfQoKICAgIHJldHVybiBcQERhdGFBcnJheTsKfQoKPWl0ZW0gQWRtaW5DaGVja3NHZXQoKQoKcmV0dXJucyBhIGFycmF5IHJlZmVyZW5jZSB3aXRoIEFkbWluQ2hlY2tzIGluZm9ybWF0aW9uLgoKJE9TQXJyYXkgPT4gWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPT4gJ1BsYXR0Zm9ybScsCiAgICAgICAgICAgICAgICBOYW1lID0+ICdQbGF0dGZvcm0nLAogICAgICAgICAgICAgICAgQ29tbWVudCA9PiAnTGludXgnLAogICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSBhZGQgbW9yZSBtZW1vcnkuJywKICAgICAgICAgICAgICAgIENoZWNrID0+ICdPSycsCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9PiAnVmVyc2lvbicsCiAgICAgICAgICAgICAgICBOYW1lID0+ICdWZXJzaW9uJywKICAgICAgICAgICAgICAgIENvbW1lbnQgPT4gJ29wZW5TVVNFIDEwLjInLAogICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSBhZGQgbW9yZSBtZW1vcnkuJywKICAgICAgICAgICAgICAgIENoZWNrID0+ICdPSycsCiAgICAgICAgICAgIH0sCiAgICAgICAgXTsKCj1jdXQKCnN1YiBBZG1pbkNoZWNrc0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWRkIG5ldyBmdW5jdGlvbiBuYW1lIGhlcmUKICAgIG15IEBNb2R1bGVMaXN0ID0gKAogICAgICAgICdfRGlzdHJpYnV0aW9uQ2hlY2snLCAnX0tlcm5lbEluZm9DaGVjaycsCiAgICApOwoKICAgIG15IEBEYXRhQXJyYXk7CgogICAgRlVOQ1RJT05OQU1FOgogICAgZm9yIG15ICRGdW5jdGlvbk5hbWUgKEBNb2R1bGVMaXN0KSB7CgogICAgICAgICMgcnVuIGZ1bmN0aW9uIGFuZCBnZXQgY2hlY2sgZGF0YQogICAgICAgIG15ICRDaGVjayA9ICRTZWxmLT4kRnVuY3Rpb25OYW1lKCk7CgogICAgICAgIG5leHQgRlVOQ1RJT05OQU1FIGlmICEkQ2hlY2s7CgogICAgICAgICMgYXR0YWNoIGNoZWNrIGRhdGEgaWYgdmFsaWQKICAgICAgICBwdXNoIEBEYXRhQXJyYXksICRDaGVjazsKICAgIH0KCiAgICByZXR1cm4gXEBEYXRhQXJyYXk7Cn0KCnN1YiBfRGlzdHJpYnV0aW9uQ2hlY2sgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkUmV0dXJuSGFzaCA9IHt9OwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgKHF3KCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JF99ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBJZiB1c2VkIE9TIGlzIGEgbGludXggc3lzdGVtCiAgICBpZiAoICReTyA9fiAvKGxpbnV4fHVuaXh8bmV0YnNkfGZyZWVic2R8ZGFyd2luKS9pICkgewogICAgICAgIG15ICRUbXBMaW5lID0gIiI7CiAgICAgICAgbXkgJERpc3RyaWJ1dGlvbjsKICAgICAgICBpZiAoIG9wZW4oICREaXN0cmlidXRpb24sICc8JywgIi9ldGMvaXNzdWUiICkgKSB7CiAgICAgICAgICAgIHdoaWxlICg8JERpc3RyaWJ1dGlvbj4pIHsKICAgICAgICAgICAgICAgICRUbXBMaW5lIC49ICRfOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNsb3NlKCREaXN0cmlidXRpb24pOwogICAgICAgICAgICBpZiAoJFRtcExpbmUpIHsKICAgICAgICAgICAgICAgICRUbXBMaW5lID1+IHMvXFwuKi8vOwogICAgICAgICAgICAgICAgJFRtcExpbmUgPX4gcy9cbi8vZzsKICAgICAgICAgICAgICAgICRSZXR1cm5IYXNoID0gewogICAgICAgICAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdEaXN0cmlidXRpb25DaGVjaycsCiAgICAgICAgICAgICAgICAgICAgTmFtZSAgICAgICAgPT4gJ0Rpc3RyaWJ1dGlvbicsCiAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gIlNob3dzIHRoZSB1c2VkIGRpc3RyaWJ1dGlvbi4gXG4iLAogICAgICAgICAgICAgICAgICAgIENvbW1lbnQgICAgID0+ICJcIiRUbXBMaW5lXCIgaXMgdXNlZC4iLAogICAgICAgICAgICAgICAgICAgIENoZWNrICAgICAgID0+ICdPSycsCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAkUmV0dXJuSGFzaCA9IHsKICAgICAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdEaXN0cmlidXRpb25DaGVjaycsCiAgICAgICAgICAgICAgICBOYW1lICAgICAgICA9PiAnRGlzdHJpYnV0aW9uJywKICAgICAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICJTaG93cyB0aGUgdXNlZCBkaXN0cmlidXRpb24uIFxuIiwKICAgICAgICAgICAgICAgIENvbW1lbnQgICAgID0+ICJDYW60XCd0IGZpbmQgL2V0Yy9pc3N1ZS4uLiBcbiIsCiAgICAgICAgICAgICAgICBDaGVjayAgICAgICA9PiAnRmFpbGVkJywKICAgICAgICAgICAgfTsKICAgICAgICB9CiAgICB9CiAgICBlbHNpZiAoICReTyA9fiAvd2luL2kgKSB7CiAgICAgICAgJFJldHVybkhhc2ggPSB7CiAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdEaXN0cmlidXRpb25DaGVjaycsCiAgICAgICAgICAgIE5hbWUgICAgICAgID0+ICdEaXN0cmlidXRpb24nLAogICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAiU2hvd3MgdGhlIHVzZWQgZGlzdHJpYnV0aW9uLiBcbiIsCiAgICAgICAgICAgIENvbW1lbnQgICAgID0+ICIkXk8gaXMgdXNlZC4iLAogICAgICAgICAgICBDaGVjayAgICAgICA9PiAnT0snLAogICAgICAgIH07CiAgICB9CiAgICByZXR1cm4gJFJldHVybkhhc2g7Cn0KCnN1YiBfS2VybmVsSW5mb0NoZWNrIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgbXkgJFJldHVybkhhc2ggPSB7fTsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIChxdygpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRffSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coIFByaW9yaXR5ID0+ICdlcnJvcicsIE1lc3NhZ2UgPT4gIk5lZWQgJF8hIiApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgICMgSWYgdXNlZCBPUyBpcyBhIGxpbnV4IHN5c3RlbQogICAgaWYgKCAkXk8gPX4gLyhsaW51eHx1bml4fG5ldGJzZHxmcmVlYnNkfGRhcndpbikvaSApIHsKICAgICAgICBteSAkVG1wTGluZSA9ICIiOwogICAgICAgIG15ICRLZXJuZWxJbmZvOwogICAgICAgIGlmICggb3BlbiggJEtlcm5lbEluZm8sICJ1bmFtZSAtYSB8IiApICkgewogICAgICAgICAgICB3aGlsZSAoPCRLZXJuZWxJbmZvPikgewogICAgICAgICAgICAgICAgJFRtcExpbmUgLj0gJF87CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2xvc2UoJEtlcm5lbEluZm8pOwogICAgICAgICAgICBpZiAoJFRtcExpbmUpIHsKICAgICAgICAgICAgICAgICRUbXBMaW5lID1+IHMvXHMrJC8vZzsKICAgICAgICAgICAgICAgICRUbXBMaW5lID1+IHMvXlxzKy8vZzsKICAgICAgICAgICAgICAgICRSZXR1cm5IYXNoID0gewogICAgICAgICAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdLZXJuZWxWZXJzaW9uQ2hlY2snLAogICAgICAgICAgICAgICAgICAgIE5hbWUgICAgICAgID0+ICdLZXJuZWwgVmVyc2lvbicsCiAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gIlNob3dzIHRoZSB1c2VkIEtlcm5lbCB2ZXJzaW9uLiBcbiIsCiAgICAgICAgICAgICAgICAgICAgQ29tbWVudCAgICAgPT4gIlwiJFRtcExpbmVcIiBpcyB1c2VkLiIsCiAgICAgICAgICAgICAgICAgICAgQ2hlY2sgICAgICAgPT4gJ09LJywKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRSZXR1cm5IYXNoID0gewogICAgICAgICAgICAgICAgS2V5ICAgICAgICAgPT4gJ0tlcm5lbFZlcnNpb25DaGVjaycsCiAgICAgICAgICAgICAgICBOYW1lICAgICAgICA9PiAnS2VybmVsIFZlcnNpb24nLAogICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gIlNob3dzIHRoZSB1c2VkIEtlcm5lbCB2ZXJzaW9uLiBcbiIsCiAgICAgICAgICAgICAgICBDb21tZW50ICAgICA9PiAiQ2FutFwndCBleGVjdXRlIHVuYW1lIC1hLi4uIFxuIiwKICAgICAgICAgICAgICAgIENoZWNrICAgICAgID0+ICdGYWlsZWQnLAogICAgICAgICAgICB9OwogICAgICAgIH0KICAgIH0KICAgIGVsc2lmICggJF5PID1+IC93aW4vaSApIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICByZXR1cm4gJFJldHVybkhhc2g7Cn0KCjE7Cgo9YmFjawoKPWhlYWQxIFRFUk1TIEFORCBDT05ESVRJT05TCgpUaGlzIHNvZnR3YXJlIGlzIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoaHR0cDovL290cnMub3JnLykuCgpUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQp0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChHUEwpLiBJZiB5b3UKZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwudHh0LgoKPWN1dAoKPWhlYWQxIFZFUlNJT04KCiRSZXZpc2lvbjogMS42ICQgJERhdGU6IDIwMDcvMTEvMjIgMTI6Mjk6MDIgJAoKPWN1dAo=
IyAtLQojIEtlcm5lbC9TeXN0ZW0vU3VwcG9ydC9Dcm9uLnBtIC0gYWxsIHJlcXVpcmVkIHN5c3RlbSBpbmZvcm1hdGlvbnMKIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwNyBPVFJTIEdtYkgsIGh0dHA6Ly9vdHJzLm9yZy8KIyAtLQojICRJZDogQ3Jvbi5wbSx2IDEuMiAyMDA3LzExLzIyIDEyOjE0OjE5IHNyIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLnR4dC4KIyAtLQoKcGFja2FnZSBLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6Q3JvbjsKCnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKCnVzZSB2YXJzIHF3KEBJU0EgJFZFUlNJT04pOwokVkVSU0lPTiA9ICckUmV2aXNpb246IDEuMiAkJzsKCj1oZWFkMSBOQU1FCgpLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6Q3JvbiAtIGdsb2JhbCBzeXN0ZW0gaW5mb3JtYXRpb25zCgo9aGVhZDEgU1lOT1BTSVMKCkFsbCByZXF1aXJlZCBzeXN0ZW0gaW5mb3JtYXRpb25zIHRvIGEgcnVubmluZyBPVFJTIGhvc3QuCgo9aGVhZDEgUFVCTElDIElOVEVSRkFDRQoKPW92ZXIgNAoKPWN1dAoKPWl0ZW0gbmV3KCkKCmNyZWF0ZSBDcm9uIGluZm8gb2JqZWN0CgogICAgdXNlIEtlcm5lbDo6Q29uZmlnOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpMb2c7CiAgICBteSAkQ29uZmlnT2JqZWN0ID0gS2VybmVsOjpDb25maWctPm5ldygpOwogICAgbXkgJExvZ09iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpMb2ctPm5ldygKICAgICAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgICk7CgogICAgJFN5c3RlbUluZm9PYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6Q3Jvbi0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCA9PiAkTG9nT2JqZWN0LAogICAgKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgb2JqZWN0cwogICAgZm9yIChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JF99ID0gJFBhcmFteyRffSB8fCBkaWUgIkdvdCBubyAkXyEiOwogICAgfQoKICAgIHJldHVybiAkU2VsZjsKfQoKPWl0ZW0gU3VwcG9ydENvbmZpZ0FycmF5R2V0KCkKCnJldHVybiBhbiBhcnJheSByZWZlcmVuY2Ugd2l0aCByZXF1aXJlZCBjb25maWcgaW5mb3JtYXRpb24uCgogICAgJEFycmF5UmVmID0gJFN1cHBvcnQtPlN1cHBvcnRDb25maWdBcnJheUdldCgpOwoKICAgIG15ICRDb25maWdBcnJheSA9IFsKICAgICAgICB7CiAgICAgICAgICAgIEtleSA9PiAnVGlja2V0RHVtcCcsCiAgICAgICAgICAgIE5hbWUgPT4gJ0R1bXAgVGlja2V0cycsCiAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgdGVsbCBtZSBob3cgbWFueSBsYXRlc3QgVGlja2V0cyB3ZSBzaHV0IGR1bXA/JywKICAgICAgICAgICAgSW5wdXQgPT4gewogICAgICAgICAgICAgICAgVHlwZSA9PiAnU2VsZWN0JywKICAgICAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgICAgIEFsbCA9PiAnQWxsJywKICAgICAgICAgICAgICAgICAgICAwID0+ICcwJywKICAgICAgICAgICAgICAgICAgICAxMCA9PiAnTGFzdCAxMCcsCiAgICAgICAgICAgICAgICAgICAgMTAwID0+ICdMYXN0IDEwMCcsCiAgICAgICAgICAgICAgICAgICAgMTAwMCA9PiAnTGFzdCAxMDAwJywKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgIEtleSA9PiAnQXBhY2hlSG9tZScsCiAgICAgICAgICAgIE5hbWUgPT4gJ0FwYWNoZSBIb21lIERpcmVjdG9yeScsCiAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgdGVsbCBtZSB0aGUgcGF0aCB0byB0aGUgQXBhY2hlIGhvbWUgZGlyZWN0b3J5ICgvZXRjL2FwYWNoZTIpJywKICAgICAgICAgICAgSW5wdXQgPT4gewogICAgICAgICAgICAgICAgVHlwZSA9PiAnVGV4dCcsCiAgICAgICAgICAgICAgICBTaXplID0+IDQwLAogICAgICAgICAgICB9LAogICAgICAgIH0sCiAgICBdOwoKPWN1dAoKc3ViIFN1cHBvcnRDb25maWdBcnJheUdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgKHF3KCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JF99ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBjcmVhdGUgY29uZmlnIGFycmF5CiAgICBteSAkQ29uZmlnQXJyYXkgPSBbCgogICAgXTsKCiAgICAjIHJldHVybiBjb25maWcgYXJyYXkKICAgIHJldHVybiAkQ29uZmlnQXJyYXk7Cn0KCj1pdGVtIFN1cHBvcnRJbmZvR2V0KCkKCnJldHVybnMgYSBhcnJheSByZWZlcmVuY2Ugd2l0aCBzdXBwb3J0IGluZm9ybWF0aW9uLgoKJENyb25BcnJheSA9PiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9PiAnUGxhdHRmb3JtJywKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1BsYXR0Zm9ybScsCiAgICAgICAgICAgICAgICBDb21tZW50ID0+ICdMaW51eCcsCiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAnUGxlYXNlIGFkZCBtb3JlIG1lbW9yeS4nLAogICAgICAgICAgICAgICAgQ2hlY2sgPT4gJ09LJywKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0+ICdWZXJzaW9uJywKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1ZlcnNpb24nLAogICAgICAgICAgICAgICAgQ29tbWVudCA9PiAnb3BlblNVU0UgMTAuMicsCiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAnUGxlYXNlIGFkZCBtb3JlIG1lbW9yeS4nLAogICAgICAgICAgICAgICAgQ2hlY2sgPT4gJ09LJywKICAgICAgICAgICAgfSwKICAgICAgICBdOwoKPWN1dAoKc3ViIFN1cHBvcnRJbmZvR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoIHJlZiggJFBhcmFte01vZHVsZUlucHV0SGFzaH0gKSBuZSAnSEFTSCcgKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9CiAgICAgICAgICAgIC0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJNb2R1bGVJbnB1dEhhc2ggbXVzdCBiZSBhIGhhc2ggcmVmZXJlbmNlISIgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBhZGQgbmV3IGZ1bmN0aW9uIG5hbWUgaGVyZQogICAgbXkgQE1vZHVsZUxpc3QgPSAoKTsKCiAgICBteSBARGF0YUFycmF5OwoKICAgIEZVTkNUSU9OTkFNRToKICAgIGZvciBteSAkRnVuY3Rpb25OYW1lIChATW9kdWxlTGlzdCkgewoKICAgICAgICAjIHJ1biBmdW5jdGlvbiBhbmQgZ2V0IGNoZWNrIGRhdGEKICAgICAgICBteSAkQ2hlY2sgPSAkU2VsZi0+JEZ1bmN0aW9uTmFtZSggVHlwZSA9PiAkUGFyYW17TW9kdWxlSW5wdXRIYXNofS0+e1R5cGV9IHx8ICcnLCApOwoKICAgICAgICBuZXh0IEZVTkNUSU9OTkFNRSBpZiAhJENoZWNrOwoKICAgICAgICAjIGF0dGFjaCBjaGVjayBkYXRhIGlmIHZhbGlkCiAgICAgICAgcHVzaCBARGF0YUFycmF5LCAkQ2hlY2s7CiAgICB9CgogICAgcmV0dXJuIFxARGF0YUFycmF5Owp9Cgo9aXRlbSBBZG1pbkNoZWNrc0dldCgpCgpyZXR1cm5zIGEgYXJyYXkgcmVmZXJlbmNlIHdpdGggQWRtaW5DaGVja3MgaW5mb3JtYXRpb24uCgokQ3JvbkFycmF5ID0+IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0+ICdQbGF0dGZvcm0nLAogICAgICAgICAgICAgICAgTmFtZSA9PiAnUGxhdHRmb3JtJywKICAgICAgICAgICAgICAgIENvbW1lbnQgPT4gJ0xpbnV4JywKICAgICAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgYWRkIG1vcmUgbWVtb3J5LicsCiAgICAgICAgICAgICAgICBDaGVjayA9PiAnT0snLAogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPT4gJ1ZlcnNpb24nLAogICAgICAgICAgICAgICAgTmFtZSA9PiAnVmVyc2lvbicsCiAgICAgICAgICAgICAgICBDb21tZW50ID0+ICdvcGVuU1VTRSAxMC4yJywKICAgICAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgYWRkIG1vcmUgbWVtb3J5LicsCiAgICAgICAgICAgICAgICBDaGVjayA9PiAnT0snLAogICAgICAgICAgICB9LAogICAgICAgIF07Cgo9Y3V0CgpzdWIgQWRtaW5DaGVja3NHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFkZCBuZXcgZnVuY3Rpb24gbmFtZSBoZXJlCiAgICBteSBATW9kdWxlTGlzdCA9ICgpOwoKICAgIG15IEBEYXRhQXJyYXk7CgogICAgRlVOQ1RJT05OQU1FOgogICAgZm9yIG15ICRGdW5jdGlvbk5hbWUgKEBNb2R1bGVMaXN0KSB7CgogICAgICAgICMgcnVuIGZ1bmN0aW9uIGFuZCBnZXQgY2hlY2sgZGF0YQogICAgICAgIG15ICRDaGVjayA9ICRTZWxmLT4kRnVuY3Rpb25OYW1lKCk7CgogICAgICAgIG5leHQgRlVOQ1RJT05OQU1FIGlmICEkQ2hlY2s7CgogICAgICAgICMgYXR0YWNoIGNoZWNrIGRhdGEgaWYgdmFsaWQKICAgICAgICBwdXNoIEBEYXRhQXJyYXksICRDaGVjazsKICAgIH0KCiAgICByZXR1cm4gXEBEYXRhQXJyYXk7Cn0KCj1pdGVtIF9DaGVjaygpCgpyZXR1cm5zIGEgaGFzaCByZWZlcmVuY2Ugd2l0aCBDaGVjayBpbmZvcm1hdGlvbi4KCiRDaGVja0hhc2ggPT4KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0+ICdQbGF0dGZvcm0nLAogICAgICAgICAgICAgICAgTmFtZSA9PiAnUGxhdHRmb3JtJywKICAgICAgICAgICAgICAgIENvbW1lbnQgPT4gJ0xpbnV4JywKICAgICAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgYWRkIG1vcmUgbWVtb3J5LicsCiAgICAgICAgICAgICAgICBDaGVjayA9PiAnT0snLAogICAgICAgICAgICB9OwoKIyBjaGVjayBpZiBjb25maWcgdmFsdWUgYXZhaWxpYmxlCmlmICgkUGFyYW17VHlwZX0pIHsKICAgIHByaW50IFNUREVSUiAiVFlQRTogIiAuICRQYXJhbXtUeXBlfTsKfQoKPWN1dAoKc3ViIF9DaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRSZXR1cm5IYXNoID0ge307CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIElmIHVzZWQgT1MgaXMgYSBsaW51eCBzeXN0ZW0KICAgIGlmICggJF5PID1+IC9saW51eC8gfHwgL3VuaXgvIHx8IC9uZXRic2QvIHx8IC9mcmVlYnNkLyB8fCAvRGFyd2luLyApIHsKCiAgICB9CiAgICBlbHNpZiAoICReTyA9fiAvd2luL2kgKSB7ICAgICMgVE9ETyAvIEF1c2dhYmUgdW50ZXIgV2luZG93cyBub2NoIHBydWVmZW4KCiAgICB9CiAgICByZXR1cm4gJFJldHVybkhhc2g7Cn0KCjE7Cg==
IyAtLQojIEtlcm5lbC9TeXN0ZW0vU3VwcG9ydC9IYXJkd2FyZS5wbSAtIGFsbCByZXF1aXJlZCBzeXN0ZW0gaW5mb3JtYXRpb25zCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDcgT1RSUyBHbWJILCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IEhhcmR3YXJlLnBtLHYgMS4xMCAyMDA3LzExLzIyIDEyOjI1OjE4IHNyIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLnR4dC4KIyAtLQoKcGFja2FnZSBLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6SGFyZHdhcmU7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdyhASVNBICRWRVJTSU9OKTsKJFZFUlNJT04gPSBxdygkUmV2aXNpb246IDEuMTAgJCkgWzFdOwoKPWhlYWQxIE5BTUUKCktlcm5lbDo6U3lzdGVtOjpTdXBwb3J0OjpIYXJkd2FyZSAtIGdsb2JhbCBzeXN0ZW0gaW5mb3JtYXRpb25zCgo9aGVhZDEgU1lOT1BTSVMKCkFsbCByZXF1aXJlZCBzeXN0ZW0gaW5mb3JtYXRpb25zIHRvIGEgcnVubmluZyBPVFJTIGhvc3QuCgo9aGVhZDEgUFVCTElDIElOVEVSRkFDRQoKPW92ZXIgNAoKPWN1dAoKPWl0ZW0gbmV3KCkKCmNyZWF0ZSBoYXJkd2FyZSBpbmZvIG9iamVjdAoKdXNlIEtlcm5lbDo6Q29uZmlnOwp1c2UgS2VybmVsOjpTeXN0ZW06OkxvZzsKbXkgJENvbmZpZ09iamVjdCA9IEtlcm5lbDo6Q29uZmlnLT5uZXcoKTsKbXkgJExvZ09iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpMb2ctPm5ldygKICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAopOwoKJFN5c3RlbUluZm9PYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6SGFyZHdhcmUtPm5ldygKICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgTG9nT2JqZWN0ID0+ICRMb2dPYmplY3QsCik7Cgo9Y3V0CgpzdWIgbmV3IHsKICAgIG15ICggJFR5cGUsICVQYXJhbSApID0gQF87CgogICAgIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CiAgICBteSAkU2VsZiA9IHt9OwogICAgYmxlc3MoICRTZWxmLCAkVHlwZSApOwoKICAgICMgY2hlY2sgbmVlZGVkIG9iamVjdHMKICAgIGZvciAocXcoQ29uZmlnT2JqZWN0IExvZ09iamVjdCkpIHsKICAgICAgICAkU2VsZi0+eyRffSA9ICRQYXJhbXskX30gfHwgZGllICJHb3Qgbm8gJF8hIjsKICAgIH0KCiAgICByZXR1cm4gJFNlbGY7Cn0KCj1pdGVtIFN1cHBvcnRDb25maWdBcnJheUdldCgpCgpyZXR1cm4gYW4gYXJyYXkgcmVmZXJlbmNlIHdpdGggcmVxdWlyZWQgY29uZmlnIGluZm9ybWF0aW9uLgoKJEFycmF5UmVmID0gJFN1cHBvcnQtPlN1cHBvcnRDb25maWdBcnJheUdldCgpOwoKbXkgJENvbmZpZ0FycmF5ID0gWwogICAgewogICAgICAgIEtleSA9PiAnVGlja2V0RHVtcCcsCiAgICAgICAgTmFtZSA9PiAnRHVtcCBUaWNrZXRzJywKICAgICAgICBEZXNjcmlwdGlvbiA9PiAnUGxlYXNlIHRlbGwgbWUgaG93IG1hbnkgbGF0ZXN0IFRpY2tldHMgd2Ugc2h1dCBkdW1wPycsCiAgICAgICAgICAgIElucHV0ID0+IHsKICAgICAgICAgICAgVHlwZSA9PiAnU2VsZWN0JywKICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICBBbGwgPT4gJ0FsbCcsCiAgICAgICAgICAgICAgICAwID0+ICcwJywKICAgICAgICAgICAgICAgIDEwID0+ICdMYXN0IDEwJywKICAgICAgICAgICAgICAgIDEwMCA9PiAnTGFzdCAxMDAnLAogICAgICAgICAgICAgICAgMTAwMCA9PiAnTGFzdCAxMDAwJywKICAgICAgICAgICAgfSwKICAgICAgICB9LAogICAgfSwKICAgIHsKICAgICAgICBLZXkgPT4gJ0FwYWNoZUhvbWUnLAogICAgICAgIE5hbWUgPT4gJ0FwYWNoZSBIb21lIERpcmVjdG9yeScsCiAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSB0ZWxsIG1lIHRoZSBwYXRoIHRvIHRoZSBBcGFjaGUgaG9tZSBkaXJlY3RvcnkgKC9ldGMvYXBhY2hlMiknLAogICAgICAgIElucHV0ID0+IHsKICAgICAgICAgICAgVHlwZSA9PiAnVGV4dCcsCiAgICAgICAgICAgIFNpemUgPT4gNDAsCiAgICAgICAgfSwKICAgIH0sCl07Cgo9Y3V0CgpzdWIgU3VwcG9ydENvbmZpZ0FycmF5R2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGNyZWF0ZSBjb25maWcgYXJyYXkKICAgIG15ICRDb25maWdBcnJheSA9IFtdOwoKICAgICMgcmV0dXJuIGNvbmZpZyBhcnJheQogICAgcmV0dXJuICRDb25maWdBcnJheTsKfQoKPWl0ZW0gU3VwcG9ydEluZm9HZXQoKQoKcmV0dXJucyBhIGFycmF5IHJlZmVyZW5jZSB3aXRoIHN1cHBvcnQgaW5mb3JtYXRpb24uCgokSGFyZHdhcmVBcnJheSA9PiBbCiAgICB7CiAgICAgICAgS2V5ID0+ICdQbGF0dGZvcm0nLAogICAgICAgIE5hbWUgPT4gJ1BsYXR0Zm9ybScsCiAgICAgICAgQ29tbWVudCA9PiAnTGludXgnLAogICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgYWRkIG1vcmUgbWVtb3J5LicsCiAgICAgICAgQ2hlY2sgPT4gJ09LJywKICAgIH0sCiAgICB7CiAgICAgICAgS2V5ID0+ICdWZXJzaW9uJywKICAgICAgICBOYW1lID0+ICdWZXJzaW9uJywKICAgICAgICBDb21tZW50ID0+ICdvcGVuU1VTRSAxMC4yJywKICAgICAgICBEZXNjcmlwdGlvbiA9PiAnUGxlYXNlIGFkZCBtb3JlIG1lbW9yeS4nLAogICAgICAgIENoZWNrID0+ICdPSycsCiAgICB9LApdOwoKPWN1dAoKc3ViIFN1cHBvcnRJbmZvR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoIHJlZiggJFBhcmFte01vZHVsZUlucHV0SGFzaH0gKSBuZSAnSEFTSCcgKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9CiAgICAgICAgICAgIC0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJNb2R1bGVJbnB1dEhhc2ggbXVzdCBiZSBhIGhhc2ggcmVmZXJlbmNlISIgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBhZGQgbmV3IGZ1bmN0aW9uIG5hbWUgaGVyZQogICAgbXkgQE1vZHVsZUxpc3QgPSAoCiAgICAgICAgJ19DUFVMb2FkQ2hlY2snLCAnX0Rpc2tVc2FnZUNoZWNrJywKICAgICAgICAnX01lbW9yeVN3YXBDaGVjaycsCiAgICApOwoKICAgIG15IEBEYXRhQXJyYXk7CgogICAgRlVOQ1RJT05OQU1FOgogICAgZm9yIG15ICRGdW5jdGlvbk5hbWUgKEBNb2R1bGVMaXN0KSB7CgogICAgICAgICMgcnVuIGZ1bmN0aW9uIGFuZCBnZXQgY2hlY2sgZGF0YQogICAgICAgIG15ICRDaGVjayA9ICRTZWxmLT4kRnVuY3Rpb25OYW1lKCBUeXBlID0+ICRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9LT57VHlwZX0gfHwgJycsICk7CgogICAgICAgIG5leHQgRlVOQ1RJT05OQU1FIGlmICEkQ2hlY2s7CgogICAgICAgICMgYXR0YWNoIGNoZWNrIGRhdGEgaWYgdmFsaWQKICAgICAgICBwdXNoIEBEYXRhQXJyYXksICRDaGVjazsKICAgIH0KCiAgICByZXR1cm4gXEBEYXRhQXJyYXk7Cn0KCj1pdGVtIEFkbWluQ2hlY2tzR2V0KCkKCnJldHVybnMgYSBhcnJheSByZWZlcmVuY2Ugd2l0aCBBZG1pbkNoZWNrcyBpbmZvcm1hdGlvbi4KCiRIYXJkd2FyZUFycmF5ID0+IFsKICAgIHsKICAgICAgICBLZXkgPT4gJ1BsYXR0Zm9ybScsCiAgICAgICAgTmFtZSA9PiAnUGxhdHRmb3JtJywKICAgICAgICBDb21tZW50ID0+ICdMaW51eCcsCiAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSBhZGQgbW9yZSBtZW1vcnkuJywKICAgICAgICBDaGVjayA9PiAnT0snLAogICAgfSwKICAgIHsKICAgICAgICBLZXkgPT4gJ1ZlcnNpb24nLAogICAgICAgIE5hbWUgPT4gJ1ZlcnNpb24nLAogICAgICAgIENvbW1lbnQgPT4gJ29wZW5TVVNFIDEwLjInLAogICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgYWRkIG1vcmUgbWVtb3J5LicsCiAgICAgICAgQ2hlY2sgPT4gJ09LJywKICAgIH0sCl07Cgo9Y3V0CgpzdWIgQWRtaW5DaGVja3NHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFkZCBuZXcgZnVuY3Rpb24gbmFtZSBoZXJlCiAgICBteSBATW9kdWxlTGlzdCA9ICgKICAgICAgICAnX0NQVUxvYWRDaGVjaycsICdfRGlza1VzYWdlQ2hlY2snLAogICAgICAgICdfTWVtb3J5U3dhcENoZWNrJywKICAgICk7CgogICAgbXkgQERhdGFBcnJheTsKCiAgICBGVU5DVElPTk5BTUU6CiAgICBmb3IgbXkgJEZ1bmN0aW9uTmFtZSAoQE1vZHVsZUxpc3QpIHsKCiAgICAgICAgIyBydW4gZnVuY3Rpb24gYW5kIGdldCBjaGVjayBkYXRhCiAgICAgICAgbXkgJENoZWNrID0gJFNlbGYtPiRGdW5jdGlvbk5hbWUoKTsKCiAgICAgICAgbmV4dCBGVU5DVElPTk5BTUUgaWYgISRDaGVjazsKCiAgICAgICAgIyBhdHRhY2ggY2hlY2sgZGF0YSBpZiB2YWxpZAogICAgICAgIHB1c2ggQERhdGFBcnJheSwgJENoZWNrOwogICAgfQoKICAgIHJldHVybiBcQERhdGFBcnJheTsKfQoKPWl0ZW0gX01lbW9yeVN3YXBDaGVjaygpCgpyZXR1cm5zIGEgaGFzaCByZWZlcmVuY2Ugd2l0aCBNZW1vcnlTd2FwQ2hlY2sgaW5mb3JtYXRpb24uCgokTWVtb3J5U3dhcENoZWNrSGFzaCA9PgogICAgewogICAgICAgIEtleSA9PiAnUGxhdHRmb3JtJywKICAgICAgICBOYW1lID0+ICdQbGF0dGZvcm0nLAogICAgICAgIENvbW1lbnQgPT4gJ0xpbnV4JywKICAgICAgICBEZXNjcmlwdGlvbiA9PiAnUGxlYXNlIGFkZCBtb3JlIG1lbW9yeS4nLAogICAgICAgIENoZWNrID0+ICdPSycsCiAgICB9OwoKIyBjaGVjayBpZiBjb25maWcgdmFsdWUgYXZhaWxpYmxlCmlmICgkUGFyYW17VHlwZX0pIHsKICAgIHByaW50IFNUREVSUiAiVFlQRTogIiAuICRQYXJhbXtUeXBlfTsKfQoKPWN1dApzdWIgX01lbW9yeVN3YXBDaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwogICAgbXkgJFJldHVybkhhc2ggPSB7fTsKCiAgICBteSAkTWVtSW5mb0ZpbGU7CiAgICBteSAkTWVtVG90YWw7CiAgICBteSAkTWVtRnJlZTsKICAgIG15ICRTd2FwVG90YWw7CiAgICBteSAkU3dhcEZyZWU7CgogICAgIyBJZiB1c2VkIE9TIGlzIGEgbGludXggc3lzdGVtCiAgICBpZiAoICReTyA9fiAvKGxpbnV4fHVuaXh8bmV0YnNkfGZyZWVic2R8ZGFyd2luKS9pICkgewogICAgICAgIGlmICggb3BlbiggJE1lbUluZm9GaWxlLCAnPCcsICIvcHJvYy9tZW1pbmZvIiApICkgewogICAgICAgICAgICB3aGlsZSAoPCRNZW1JbmZvRmlsZT4pIHsKICAgICAgICAgICAgICAgIG15ICRUbXBMaW5lID0gJF87CiAgICAgICAgICAgICAgICBpZiAoICRUbXBMaW5lID1+IC9NZW1Ub3RhbC8gKSB7CiAgICAgICAgICAgICAgICAgICAgJFRtcExpbmUgPX4gcy9eLio/KFxkKykuKiQvJDEvOwogICAgICAgICAgICAgICAgICAgICRNZW1Ub3RhbCA9IGludCgkVG1wTGluZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNpZiAoICRUbXBMaW5lID1+IC9NZW1GcmVlLyApIHsKICAgICAgICAgICAgICAgICAgICAkVG1wTGluZSA9fiBzL14uKj8oXGQrKS4qJC8kMS87CiAgICAgICAgICAgICAgICAgICAgJE1lbUZyZWUgPSBpbnQoJFRtcExpbmUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzaWYgKCAkVG1wTGluZSA9fiAvU3dhcFRvdGFsLyApIHsKICAgICAgICAgICAgICAgICAgICAkVG1wTGluZSA9fiBzL14uKj8oXGQrKS4qJC8kMS87CiAgICAgICAgICAgICAgICAgICAgJFN3YXBUb3RhbCA9IGludCgkVG1wTGluZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNpZiAoICRUbXBMaW5lID1+IC9Td2FwRnJlZS8gKSB7CiAgICAgICAgICAgICAgICAgICAgJFRtcExpbmUgPX4gcy9eLio/KFxkKykuKiQvJDEvOwogICAgICAgICAgICAgICAgICAgICRTd2FwRnJlZSA9IGludCgkVG1wTGluZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2xvc2UoJE1lbUluZm9GaWxlKTsKCiAgICAgICAgICAgICMgYnVpbGQgcmV0dXJuIGhhc2gKICAgICAgICAgICAgbXkgJERlc2NyaWJ0aW9uCiAgICAgICAgICAgICAgICA9ICJUaGUgSG9zdCBTeXN0ZW0gaGFzOiBcbiIKICAgICAgICAgICAgICAgIC4gaW50KCAkTWVtVG90YWwgLyAxMDI0ICkKICAgICAgICAgICAgICAgIC4gIiBNQiBNZW1vcnkgdG90YWwgXG4iCiAgICAgICAgICAgICAgICAuIGludCggJE1lbUZyZWUgLyAxMDI0ICkKICAgICAgICAgICAgICAgIC4gIiBNQiBNZW1vcnkgZnJlZSBcbiIKICAgICAgICAgICAgICAgIC4gaW50KCAkU3dhcFRvdGFsIC8gMTAyNCApCiAgICAgICAgICAgICAgICAuICIgTUIgU3dhcCB0b3RhbCBcbiIKICAgICAgICAgICAgICAgIC4gaW50KCAkU3dhcEZyZWUgLyAxMDI0ICkKICAgICAgICAgICAgICAgIC4gIiBNQiBTd2FwIGZyZWUgIjsKCiAgICAgICAgICAgIGlmICggISRTd2FwVG90YWwgKSB7CiAgICAgICAgICAgICAgICAkUmV0dXJuSGFzaCA9IHsKICAgICAgICAgICAgICAgICAgICBLZXkgICAgICAgICA9PiAnTWVtb3J5U3dhcENoZWNrJywKICAgICAgICAgICAgICAgICAgICBOYW1lICAgICAgICA9PiAnTWVtb3J5IFN3YXAgQ2hlY2snLAogICAgICAgICAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICJBIE1lbW9yeSBDaGVjay4gV2UgdHJ5IHRvIGZpbmQgb3V0IGlmIFxuIgogICAgICAgICAgICAgICAgICAgICAgICAuICJTd2FwRnJlZSA6IFN3YXBUb3RhbCA8IDYwICUgXG4iCiAgICAgICAgICAgICAgICAgICAgICAgIC4gIiBvciBpZiBtb3JlIHRoYW4gMjAwIE1CIFN3YXAgaXMgdXNlZC4iLAogICAgICAgICAgICAgICAgICAgIENvbW1lbnQgPT4gIk5vIFN3YXAgZW5hYmxlZCEiLAogICAgICAgICAgICAgICAgICAgIENoZWNrICAgPT4gJ0ZhaWxlZCcsCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2lmICgoICgkU3dhcEZyZWUpIC8gKCRTd2FwVG90YWwpIDwgNjAgKQogICAgICAgICAgICAgICAgfHwgKCAoJFN3YXBUb3RhbCkgLSAoJFN3YXBGcmVlKSA+IDIwMDAwICkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAkUmV0dXJuSGFzaCA9IHsKICAgICAgICAgICAgICAgICAgICBLZXkgICAgICAgICA9PiAnTWVtb3J5U3dhcENoZWNrJywKICAgICAgICAgICAgICAgICAgICBOYW1lICAgICAgICA9PiAnTWVtb3J5IFN3YXAgQ2hlY2snLAogICAgICAgICAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICJBIE1lbW9yeSBDaGVjay4gV2UgdHJ5IHRvIGZpbmQgb3V0IGlmIFxuIgogICAgICAgICAgICAgICAgICAgICAgICAuICJTd2FwRnJlZSA6IFN3YXBUb3RhbCA8IDYwICUgXG4iCiAgICAgICAgICAgICAgICAgICAgICAgIC4gIiBvciBpZiBtb3JlIHRoYW4gMjAwIE1CIFN3YXAgaXMgdXNlZC4iLAogICAgICAgICAgICAgICAgICAgIENvbW1lbnQgPT4gIiREZXNjcmlidGlvbiIsCiAgICAgICAgICAgICAgICAgICAgQ2hlY2sgICA9PiAnT0snLAogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICRSZXR1cm5IYXNoID0gewogICAgICAgICAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdNZW1vcnlTd2FwQ2hlY2snLAogICAgICAgICAgICAgICAgICAgIE5hbWUgICAgICAgID0+ICdNZW1vcnkgU3dhcCBDaGVjaycsCiAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gIkEgTWVtb3J5IENoZWNrLiBXZSB0cnkgdG8gZmluZCBvdXQgaWYgXG4iCiAgICAgICAgICAgICAgICAgICAgICAgIC4gIlN3YXBGcmVlIDogU3dhcFRvdGFsIDwgNjAgJSBcbiIKICAgICAgICAgICAgICAgICAgICAgICAgLiAiIG9yIGlmIG1vcmUgdGhhbiAyMDAgTUIgU3dhcCBpcyB1c2VkLiIsCiAgICAgICAgICAgICAgICAgICAgQ29tbWVudCA9PiAiJERlc2NyaWJ0aW9uIiwKICAgICAgICAgICAgICAgICAgICBDaGVjayAgID0+ICdGYWlsZWQnLAogICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGVsc2lmICggJF5PID1+IC93aW4vaSApIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgcmV0dXJuICRSZXR1cm5IYXNoOwp9CgpzdWIgX0NQVUxvYWRDaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRSZXR1cm5IYXNoID0ge307CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KICAgIG15IEBTcGxpdEFycmF5ID0ge307CgogICAgIyBJZiB1c2VkIE9TIGlzIGEgbGludXggc3lzdGVtCiAgICBpZiAoICReTyA9fiAvKGxpbnV4fHVuaXh8bmV0YnNkfGZyZWVic2R8ZGFyd2luKS9pICkgewogICAgICAgIGlmICggLWUgIi9wcm9jL2xvYWRhdmciICkgewogICAgICAgICAgICBteSAkTG9hZEZpbGU7CiAgICAgICAgICAgIG9wZW4oICRMb2FkRmlsZSwgJzwnLCAiL3Byb2MvbG9hZGF2ZyIgKTsKICAgICAgICAgICAgd2hpbGUgKDwkTG9hZEZpbGU+KSB7CiAgICAgICAgICAgICAgICBAU3BsaXRBcnJheSA9IHNwbGl0KCAiICIsICRfICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2xvc2UoJExvYWRGaWxlKTsKCiAgICAgICAgICAgICMgYnVpbGQgcmV0dXJuIGhhc2gKICAgICAgICAgICAgbXkgJERlc2NyaWJ0aW9uCiAgICAgICAgICAgICAgICA9ICJUaGUgSG9zdCBTeXN0ZW0gaGFzIGEgbG9hZDogXG4iCiAgICAgICAgICAgICAgICAuICRTcGxpdEFycmF5WzBdCiAgICAgICAgICAgICAgICAuICIgaW4gdGhlIGxhc3QgMSBtaW51dGUgXG4iCiAgICAgICAgICAgICAgICAuICRTcGxpdEFycmF5WzFdCiAgICAgICAgICAgICAgICAuICIgaW4gdGhlIGxhc3QgNSBtaW51dGVzIFxuIgogICAgICAgICAgICAgICAgLiAkU3BsaXRBcnJheVsyXQogICAgICAgICAgICAgICAgLiAiIGluIHRoZSBsYXN0IDE1IG1pbnV0ZXMiOwoKICAgICAgICAgICAgaWYgKCAkU3BsaXRBcnJheVsyXSA8ICcxLjAwJyApIHsKICAgICAgICAgICAgICAgICRSZXR1cm5IYXNoID0gewogICAgICAgICAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdDUFVMb2FkQ2hlY2snLAogICAgICAgICAgICAgICAgICAgIE5hbWUgICAgICAgID0+ICdDUFUgTG9hZCcsCiAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gIkEgQ1BVIGxvYWQgY2hlY2suIFdlIHRyeSB0byBmaW5kIG91dCBpZiBcbiIKICAgICAgICAgICAgICAgICAgICAgICAgLiAidGhlIHN5c3RlbSBsb2FkIGluIHRoZSBsYXN0IDE1IG1pbnV0ZXMgPiAxLiBcbiIsCiAgICAgICAgICAgICAgICAgICAgQ29tbWVudCA9PiAiJERlc2NyaWJ0aW9uIiwKICAgICAgICAgICAgICAgICAgICBDaGVjayAgID0+ICdPSycsCiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJFJldHVybkhhc2ggPSB7CiAgICAgICAgICAgICAgICAgICAgS2V5ICAgICAgICAgPT4gJ0NQVUxvYWRDaGVjaycsCiAgICAgICAgICAgICAgICAgICAgTmFtZSAgICAgICAgPT4gJ0NQVSBMb2FkJywKICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAiQSBDUFUgbG9hZCBjaGVjay4gV2UgdHJ5IHRvIGZpbmQgb3V0IGlmIFxuIgogICAgICAgICAgICAgICAgICAgICAgICAuICJ0aGUgc3lzdGVtIGxvYWQgaW4gdGhlIGxhc3QgMTUgbWludXRlcyA8IDEgXG4iLAogICAgICAgICAgICAgICAgICAgIENvbW1lbnQgPT4gIiREZXNjcmlidGlvbiIsCiAgICAgICAgICAgICAgICAgICAgQ2hlY2sgICA9PiAnRmFpbGVkJywKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBlbHNpZiAoICReTyA9fiAvd2luL2kgKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgcmV0dXJuICRSZXR1cm5IYXNoOwp9CgpzdWIgX0Rpc2tVc2FnZUNoZWNrIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgbXkgJERhdGEgICAgPSB7fTsKICAgIG15ICRDaGVjayAgID0gJ09LJzsKICAgIG15ICRNZXNzYWdlID0gJyc7CgogICAgIyBJZiB1c2VkIE9TIGlzIGEgbGludXggc3lzdGVtCiAgICBpZiAoICReTyA9fiAvKGxpbnV4fHVuaXh8bmV0YnNkfGZyZWVic2R8ZGFyd2luKS9pICkgewogICAgICAgIG15ICRJbjsKICAgICAgICBpZiAoIG9wZW4oICRJbiwgImRmIC1sIHwiICkgKSB7CiAgICAgICAgICAgIHdoaWxlICg8JEluPikgewogICAgICAgICAgICAgICAgaWYgKCAkXyA9fiAvXiguKz8pXHMuKlxzKFxkXGRcZHxcZFxkfFxkKSUuKz8kLyApIHsKICAgICAgICAgICAgICAgICAgICBpZiAoICQyID4gOTAgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRDaGVjayA9ICdGYWlsZWQnOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoICRDaGVjayBuZSAnRmFpbGVkJyAmJiAkMiA+IDg1ICkgewogICAgICAgICAgICAgICAgICAgICAgICAkQ2hlY2sgPSAnQ3JpdGljYWwnOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoJE1lc3NhZ2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJE1lc3NhZ2UgLj0gIiwiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAkTWVzc2FnZSAuPSAiJDFcWyQyJVxdIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBjbG9zZSgkSW4pOwogICAgICAgICAgICBpZiAoICRDaGVjayBlcSAnRmFpbGVkJyApIHsKICAgICAgICAgICAgICAgICRNZXNzYWdlID0gIkRpc2sgaXN0IGZ1bGwgKCRNZXNzYWdlKS4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJE1lc3NhZ2UgPSAiRGlzayB1c2FnZSAoJE1lc3NhZ2UpLiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJERhdGEgPSB7CiAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdkaXNrIHVzYWdlJywKICAgICAgICAgICAgTmFtZSAgICAgICAgPT4gJ2Rpc2sgdXNhZ2UnLAogICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAiQ2hlY2sgZGlzayB1c2FnZS4iLAogICAgICAgICAgICBDb21tZW50ICAgICA9PiAkTWVzc2FnZSwKICAgICAgICAgICAgQ2hlY2sgICAgICAgPT4gJENoZWNrLAogICAgICAgIH07CiAgICB9CgogICAgcmV0dXJuICREYXRhOwp9CgoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBzb2Z0d2FyZSBpcyBwYXJ0IG9mIHRoZSBPVFJTIHByb2plY3QgKGh0dHA6Ly9vdHJzLm9yZy8pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLnR4dC4KCj1jdXQKCj1oZWFkMSBWRVJTSU9OCgokUmV2aXNpb246IDEuMTAgJCAkRGF0ZTogMjAwNy8xMS8yMiAxMjoyNToxOCAkCgo9Y3V0Cg==
IyAtLQojIEtlcm5lbC9TeXN0ZW0vU3VwcG9ydC9PVFJTLnBtIC0gYWxsIHJlcXVpcmVkIG90cnMgaW5mb3JtYXRpb25zCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDcgT1RSUyBHbWJILCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IE9UUlMucG0sdiAxLjEwIDIwMDcvMTEvMjIgMTM6MDQ6MDMgc3IgRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpTdXBwb3J0OjpPVFJTOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIEtlcm5lbDo6U3lzdGVtOjpTdXBwb3J0Owp1c2UgS2VybmVsOjpTeXN0ZW06OlRpY2tldDsKCnVzZSB2YXJzIHF3KEBJU0EgJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS4xMCAkKSBbMV07CgpzdWIgbmV3IHsKICAgIG15ICggJFR5cGUsICVQYXJhbSApID0gQF87CgogICAgIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CiAgICBteSAkU2VsZiA9IHt9OwogICAgYmxlc3MoICRTZWxmLCAkVHlwZSApOwoKICAgICMgY2hlY2sgbmVlZGVkIG9iamVjdHMKICAgIGZvciAocXcoQ29uZmlnT2JqZWN0IExvZ09iamVjdCBNYWluT2JqZWN0IERCT2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JF99ID0gJFBhcmFteyRffSB8fCBkaWUgIkdvdCBubyAkXyEiOwogICAgfQoKICAgICRTZWxmLT57U3VwcG9ydE9iamVjdH0gPSBLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydC0+bmV3KCVQYXJhbSk7CiAgICAkU2VsZi0+e1RpY2tldE9iamVjdH0gID0gS2VybmVsOjpTeXN0ZW06OlRpY2tldC0+bmV3KCVQYXJhbSk7CgogICAgcmV0dXJuICRTZWxmOwp9CgpzdWIgU3VwcG9ydENvbmZpZ0FycmF5R2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGNyZWF0ZSBjb25maWcgYXJyYXkKICAgIG15ICRDb25maWdBcnJheSA9IFsKCiAgICBdOwoKICAgICMgcmV0dXJuIGNvbmZpZyBhcnJheQogICAgcmV0dXJuICRDb25maWdBcnJheTsKfQoKc3ViIFN1cHBvcnRJbmZvR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoIHJlZiggJFBhcmFte01vZHVsZUlucHV0SGFzaH0gKSBuZSAnSEFTSCcgKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9CiAgICAgICAgICAgIC0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJNb2R1bGVJbnB1dEhhc2ggbXVzdCBiZSBhIGhhc2ggcmVmZXJlbmNlISIgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBhZGQgbmV3IGZ1bmN0aW9uIG5hbWUgaGVyZQogICAgbXkgQE1vZHVsZUxpc3QgPSAoCiAgICAgICAgJ19PVFJTTG9nR2V0JywgJ19PVFJTS2VybmVsR2V0JywKICAgICAgICAnX09UUlNDaGVja1N1bUdldCcsICdfT1RSU0NoZWNrTW9kdWxlc0dldCcsCiAgICAgICAgJ19PcGVuVGlja2V0Q2hlY2snLCAnX1RpY2tldEluZGV4TW9kdWxlQ2hlY2snLAogICAgICAgICdfRlFETkNvbmZpZ0NoZWNrJywgJ19Mb2dDaGVjaycsCiAgICApOwoKICAgIG15IEBEYXRhQXJyYXk7CgogICAgRlVOQ1RJT05OQU1FOgogICAgZm9yIG15ICRGdW5jdGlvbk5hbWUgKEBNb2R1bGVMaXN0KSB7CgogICAgICAgICMgcnVuIGZ1bmN0aW9uIGFuZCBnZXQgY2hlY2sgZGF0YQogICAgICAgIG15ICRDaGVjayA9ICRTZWxmLT4kRnVuY3Rpb25OYW1lKCBUeXBlID0+ICRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9LT57VHlwZX0gfHwgJycsICk7CgogICAgICAgIG5leHQgRlVOQ1RJT05OQU1FIGlmICEkQ2hlY2s7CgogICAgICAgICMgYXR0YWNoIGNoZWNrIGRhdGEgaWYgdmFsaWQKICAgICAgICBwdXNoIEBEYXRhQXJyYXksICRDaGVjazsKICAgIH0KCiAgICByZXR1cm4gXEBEYXRhQXJyYXk7Cn0KCnN1YiBBZG1pbkNoZWNrc0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWRkIG5ldyBmdW5jdGlvbiBuYW1lIGhlcmUKICAgIG15IEBNb2R1bGVMaXN0ID0gKAogICAgICAgICdfT3BlblRpY2tldENoZWNrJywgJ19UaWNrZXRJbmRleE1vZHVsZUNoZWNrJywKICAgICAgICAnX0ZRRE5Db25maWdDaGVjaycsICdfTG9nQ2hlY2snLAogICAgKTsKCiAgICBteSBARGF0YUFycmF5OwoKICAgIEZVTkNUSU9OTkFNRToKICAgIGZvciBteSAkRnVuY3Rpb25OYW1lIChATW9kdWxlTGlzdCkgewoKICAgICAgICAjIHJ1biBmdW5jdGlvbiBhbmQgZ2V0IGNoZWNrIGRhdGEKICAgICAgICBteSAkQ2hlY2sgPSAkU2VsZi0+JEZ1bmN0aW9uTmFtZSgpOwoKICAgICAgICBuZXh0IEZVTkNUSU9OTkFNRSBpZiAhJENoZWNrOwoKICAgICAgICAjIGF0dGFjaCBjaGVjayBkYXRhIGlmIHZhbGlkCiAgICAgICAgcHVzaCBARGF0YUFycmF5LCAkQ2hlY2s7CiAgICB9CgogICAgcmV0dXJuIFxARGF0YUFycmF5Owp9CgpzdWIgX09UUlNMb2dHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkUmV0dXJuSGFzaCA9IHt9OwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgKHF3KCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JF99ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CiAgICBteSAkTG9nU3RyaW5nID0gJFNlbGYtPntMb2dPYmplY3R9LT5HZXRMb2coIExpbWl0ID0+IDEwMDAgKTsKICAgIG15ICRUbXBMb2c7CiAgICBvcGVuKCAkVG1wTG9nLCAnPicsICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAiL3Zhci90bXAvdG1wbG9nIiApOwogICAgcHJpbnQgJFRtcExvZyAkTG9nU3RyaW5nOwogICAgY2xvc2UoJFRtcExvZyk7CgogICAgbXkgJEZpbGVuYW1lID0gJFNlbGYtPntTdXBwb3J0T2JqZWN0fS0+VGFyUGFja2FnZVdyaXRlKAogICAgICAgIEZpbGVOYW1lICAgPT4gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICIvdmFyL3RtcC90bXBsb2ciLAogICAgICAgIE91dHB1dFBhdGggPT4gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICIvdmFyL3RtcC9zdXBwb3J0LyIsCiAgICAgICAgT3V0cHV0TmFtZSA9PiAnb3Rycy5sb2cudGFyJywKICAgICk7CgogICAgIyByZW1vdmUgdG1wIGZpbGUKICAgIHVubGluayAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gIi92YXIvdG1wL3RtcGxvZyI7CgogICAgaWYgKCRGaWxlbmFtZSkgewogICAgICAgICRSZXR1cm5IYXNoID0gewogICAgICAgICAgICBLZXkgICAgICAgICA9PiAnT1RSU0xvZycsCiAgICAgICAgICAgIE5hbWUgICAgICAgID0+ICdPVFJTTG9nJywKICAgICAgICAgICAgQ29tbWVudCAgICAgPT4gJ1RoZSBPVFJTIExvZycsCiAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICRGaWxlbmFtZSwKICAgICAgICAgICAgQ2hlY2sgICAgICAgPT4gJ1BhY2thZ2UnLAogICAgICAgIH07CiAgICB9CiAgICByZXR1cm4gJFJldHVybkhhc2g7Cn0KCnN1YiBfT1RSU0tlcm5lbEdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRSZXR1cm5IYXNoID0ge307CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGdldCB0aGUgZGlyZWN0b3J5IG5hbWUKICAgIG15ICREaXJOYW1lID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICcvS2VybmVsLyc7CgogICAgbXkgJEZpbGVuYW1lID0gJFNlbGYtPntTdXBwb3J0T2JqZWN0fS0+VGFyUGFja2FnZVdyaXRlKAogICAgICAgIERpck5hbWUgICAgPT4gJERpck5hbWUsCiAgICAgICAgT3V0cHV0UGF0aCA9PiAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gIi92YXIvdG1wL3N1cHBvcnQvIiwKICAgICAgICBPdXRwdXROYW1lID0+ICdrZXJuZWwudGFyJywKICAgICk7CgogICAgaWYgKCRGaWxlbmFtZSkgewogICAgICAgICRSZXR1cm5IYXNoID0gewogICAgICAgICAgICBLZXkgICAgICAgICA9PiAnT1RSU0tlcm5lbCcsCiAgICAgICAgICAgIE5hbWUgICAgICAgID0+ICdPVFJTS2VybmVsJywKICAgICAgICAgICAgQ29tbWVudCAgICAgPT4gJ1RoZSBPVFJTIEtlcm5lbCAnLAogICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAkRmlsZW5hbWUsCiAgICAgICAgICAgIENoZWNrICAgICAgID0+ICdQYWNrYWdlJywKICAgICAgICB9OwogICAgfQogICAgcmV0dXJuICRSZXR1cm5IYXNoOwp9CgpzdWIgX09UUlNDaGVja1N1bUdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRSZXR1cm5IYXNoID0ge307CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICBteSAkVG1wU3VtU3RyaW5nOwogICAgbXkgJFRtcExvZzsKICAgIG9wZW4oICRUbXBTdW1TdHJpbmcsICJwZXJsICIgLiAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gIi9iaW4vQ2hlY2tTdW0ucGwgfCIgKTsKICAgIG9wZW4oICRUbXBMb2csICc+JywgJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICIvdmFyL3RtcC9DaGVja1N1bS5sb2ciICk7CgogICAgd2hpbGUgKDwkVG1wU3VtU3RyaW5nPikgewogICAgICAgIHByaW50ICRUbXBMb2cgJF87CiAgICB9CiAgICBjbG9zZSgkVG1wU3VtU3RyaW5nKTsKICAgIGNsb3NlKCRUbXBMb2cpOwoKICAgIG15ICRGaWxlbmFtZSA9ICRTZWxmLT57U3VwcG9ydE9iamVjdH0tPlRhclBhY2thZ2VXcml0ZSgKICAgICAgICBGaWxlTmFtZSAgID0+ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAiL3Zhci90bXAvQ2hlY2tTdW0ubG9nIiwKICAgICAgICBPdXRwdXRQYXRoID0+ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAiL3Zhci90bXAvc3VwcG9ydC8iLAogICAgICAgIE91dHB1dE5hbWUgPT4gJ0NoZWNrU3VtLmxvZy50YXInLAogICAgKTsKCiAgICAjIHJlbW92ZSB0bXAgZmlsZQogICAgdW5saW5rICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAiL3Zhci90bXAvQ2hlY2tTdW0ubG9nIjsKCiAgICBpZiAoJEZpbGVuYW1lKSB7CiAgICAgICAgJFJldHVybkhhc2ggPSB7CiAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdPVFJTQ2hlY2tTdW0nLAogICAgICAgICAgICBOYW1lICAgICAgICA9PiAnT1RSU0NoZWNrU3VtJywKICAgICAgICAgICAgQ29tbWVudCAgICAgPT4gJ1RoZSBPVFJTIENoZWNrU3VtLicsCiAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICRGaWxlbmFtZSwKICAgICAgICAgICAgQ2hlY2sgICAgICAgPT4gJ1BhY2thZ2UnLAogICAgICAgIH07CiAgICB9CiAgICByZXR1cm4gJFJldHVybkhhc2g7Cn0KCnN1YiBfT1RSU0NoZWNrTW9kdWxlc0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRSZXR1cm5IYXNoID0ge307CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICBteSAkVG1wU3VtU3RyaW5nOwogICAgbXkgJFRtcExvZzsKICAgIG9wZW4oICRUbXBTdW1TdHJpbmcsCiAgICAgICAgInBlcmwgIiAuICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAiL2Jpbi9vdHJzLmNoZWNrTW9kdWxlcyB8IiApOwogICAgb3BlbiggJFRtcExvZywgJz4nLCAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gIi92YXIvdG1wL0NoZWNrTW9kdWxlcy5sb2ciICk7CgogICAgd2hpbGUgKDwkVG1wU3VtU3RyaW5nPikgewogICAgICAgIHByaW50ICRUbXBMb2cgJF87CiAgICB9CiAgICBjbG9zZSgkVG1wU3VtU3RyaW5nKTsKICAgIGNsb3NlKCRUbXBMb2cpOwoKICAgIG15ICRGaWxlbmFtZSA9ICRTZWxmLT57U3VwcG9ydE9iamVjdH0tPlRhclBhY2thZ2VXcml0ZSgKICAgICAgICBGaWxlTmFtZSAgID0+ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAiL3Zhci90bXAvQ2hlY2tNb2R1bGVzLmxvZyIsCiAgICAgICAgT3V0cHV0UGF0aCA9PiAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gIi92YXIvdG1wL3N1cHBvcnQvIiwKICAgICAgICBPdXRwdXROYW1lID0+ICdDaGVja01vZHVsZXMubG9nLnRhcicsCiAgICApOwoKICAgICMgcmVtb3ZlIHRtcCBmaWxlCiAgICB1bmxpbmsgJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICIvdmFyL3RtcC9DaGVja01vZHVsZXMubG9nIjsKCiAgICBpZiAoJEZpbGVuYW1lKSB7CiAgICAgICAgJFJldHVybkhhc2ggPSB7CiAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdPVFJTQ2hlY2tTdW0nLAogICAgICAgICAgICBOYW1lICAgICAgICA9PiAnT1RSU0NoZWNrU3VtJywKICAgICAgICAgICAgQ29tbWVudCAgICAgPT4gJ1RoZSBPVFJTIENoZWNrU3VtLicsCiAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICRGaWxlbmFtZSwKICAgICAgICAgICAgQ2hlY2sgICAgICAgPT4gJ1BhY2thZ2UnLAogICAgICAgIH07CiAgICB9CiAgICByZXR1cm4gJFJldHVybkhhc2g7Cn0KCiMgY2hlY2sgaWYgZXJyb3IgbG9nIGVudHJpZXMgYXJlIGF2YWlsYWJsZQpzdWIgX0xvZ0NoZWNrIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgbXkgJERhdGEgPSB7fTsKCiAgICAjIFRpY2tldDo6SW5kZXhNb2R1bGUgY2hlY2sKICAgIG15ICRDaGVjayAgID0gJ09LJzsKICAgIG15ICRNZXNzYWdlID0gJyc7CiAgICBteSAkRXJyb3IgICA9ICcnOwoKICAgIG15IEBMaW5lcyA9IHNwbGl0KCAvXG4vLCAkU2VsZi0+e0xvZ09iamVjdH0tPkdldExvZygpICk7CiAgICBmb3IgKEBMaW5lcykgewogICAgICAgIG15IEBSb3cgPSBzcGxpdCggLzs7LywgJF8gKTsKICAgICAgICBpZiAoICRSb3dbM10gKSB7CiAgICAgICAgICAgIGlmICggJFJvd1sxXSA9fiAvZXJyb3IvaSApIHsKICAgICAgICAgICAgICAgICRDaGVjayA9ICdGYWlsZWQnOwogICAgICAgICAgICAgICAgaWYgKCRNZXNzYWdlKSB7CiAgICAgICAgICAgICAgICAgICAgJE1lc3NhZ2UgPSAnWW91IGhhdmUgbW9yZSBlcnJvciBsb2cgZW50cmllczogJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICRNZXNzYWdlID0gJ1RoZXJlIGlzIG9uZSBlcnJvciBsb2cgZW50cnk6ICc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoJEVycm9yKSB7CiAgICAgICAgICAgICAgICAgICAgJEVycm9yIC49ICIsICI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAkRXJyb3IgLj0gJFJvd1szXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAkRGF0YSA9IHsKICAgICAgICBLZXkgICAgICAgICA9PiAnTG9nQ2hlY2snLAogICAgICAgIE5hbWUgICAgICAgID0+ICdMb2dDaGVjaycsCiAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIGxvZyBmb3IgZXJyb3IgbG9nIGVudGllcy4iLAogICAgICAgIENvbW1lbnQgICAgID0+ICRNZXNzYWdlIC4gJEVycm9yLAogICAgICAgIENoZWNrICAgICAgID0+ICRDaGVjaywKICAgICAgICB9LAogICAgICAgIHJldHVybiAkRGF0YTsKfQoKc3ViIF9UaWNrZXRJbmRleE1vZHVsZUNoZWNrIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgbXkgJERhdGEgPSB7fTsKCiAgICAjIFRpY2tldDo6SW5kZXhNb2R1bGUgY2hlY2sKICAgIG15ICRDaGVjayAgID0gJ0ZhaWxlZCc7CiAgICBteSAkTWVzc2FnZSA9ICcnOwogICAgbXkgJE1vZHVsZSAgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnVGlja2V0OjpJbmRleE1vZHVsZScpOwogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoIFNRTCA9PiAiU0VMRUNUIGNvdW50KCopIGZyb20gdGlja2V0IiApOwogICAgd2hpbGUgKCBteSBAUm93ID0gJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICBpZiAoICRSb3dbMF0gPiA4MDAwMCApIHsKICAgICAgICAgICAgaWYgKCAkTW9kdWxlID1+IC9SdW50aW1lREIvICkgewogICAgICAgICAgICAgICAgJENoZWNrID0gJ0ZhaWxlZCc7CiAgICAgICAgICAgICAgICAkTWVzc2FnZQogICAgICAgICAgICAgICAgICAgID0gIllvdSBzaG91bGQgdXNlIHRoZSBTdGF0aWNEQiBiYWNrZW5kLiBTZWUgYWRtaW4gbWFudWFsIChQZXJmb3JtYW5jZSBUdW5pbmcpIGZvciBtb3JlIGluZm9ybWF0aW9uLiI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkQ2hlY2sgICA9ICdPSyc7CiAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICIiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2lmICggJFJvd1swXSA+IDYwMDAwICkgewogICAgICAgICAgICBpZiAoICRNb2R1bGUgPX4gL1J1bnRpbWVEQi8gKSB7CiAgICAgICAgICAgICAgICAkQ2hlY2sgPSAnQ3JpdGljYWwnOwogICAgICAgICAgICAgICAgJE1lc3NhZ2UKICAgICAgICAgICAgICAgICAgICA9ICJZb3Ugc2hvdWxkIHVzZSB0aGUgU3RhdGljREIgYmFja2VuZC4gU2VlIGFkbWluIG1hbnVhbCAoUGVyZm9ybWFuY2UgVHVuaW5nKSBmb3IgbW9yZSBpbmZvcm1hdGlvbi4iOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJENoZWNrICAgPSAnT0snOwogICAgICAgICAgICAgICAgJE1lc3NhZ2UgPSAiIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJENoZWNrICAgPSAnT0snOwogICAgICAgICAgICAkTWVzc2FnZSA9ICJZb3UgYXJlIHVzaW5nICRNb2R1bGUsIHRoYXQncyBmaW5lIGZvciAkUm93WzBdIHRpY2tldHMgaW4geW91ciBzeXN0ZW0uIjsKICAgICAgICB9CiAgICB9CiAgICAkRGF0YSA9IHsKICAgICAgICBLZXkgICAgICAgICA9PiAnVGlja2V0OjpJbmRleE1vZHVsZScsCiAgICAgICAgTmFtZSAgICAgICAgPT4gJ1RpY2tldDo6SW5kZXhNb2R1bGUnLAogICAgICAgIERlc2NyaXB0aW9uID0+ICJDaGVjayBUaWNrZXQ6OkluZGV4TW9kdWxlIHNldHRpbmcuIiwKICAgICAgICBDb21tZW50ICAgICA9PiAkTWVzc2FnZSwKICAgICAgICBDaGVjayAgICAgICA9PiAkQ2hlY2ssCiAgICAgICAgfSwKICAgICAgICByZXR1cm4gJERhdGE7Cn0KCiMgT3BlblRpY2tldENoZWNrIGNoZWNrCnN1YiBfT3BlblRpY2tldENoZWNrIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgbXkgJERhdGEgPSB7fTsKCiAgICBteSAkQ2hlY2sgICAgID0gJ0ZhaWxlZCc7CiAgICBteSAkTWVzc2FnZSAgID0gJyc7CiAgICBteSBAVGlja2V0SURzID0gJFNlbGYtPntUaWNrZXRPYmplY3R9LT5UaWNrZXRTZWFyY2goCiAgICAgICAgUmVzdWx0ICAgICA9PiAnQVJSQVknLAogICAgICAgIFN0YXRlVHlwZSAgPT4gJ09wZW4nLAogICAgICAgIFVzZXJJRCAgICAgPT4gMSwKICAgICAgICBQZXJtaXNzaW9uID0+ICdybycsCiAgICAgICAgTGltaXQgICAgICA9PiA5OTk5OTk5OSwKICAgICk7CiAgICBpZiAoICQjVGlja2V0SURzID4gMTAwMDAgKSB7CiAgICAgICAgJENoZWNrID0gJ0ZhaWxlZCc7CiAgICAgICAgJE1lc3NhZ2UKICAgICAgICAgICAgPSAiWW91IHNob3VsZCBub3QgaGF2ZSBtb3JlIHRoZW4gODAwMCBvcGVuIHRpY2tldHMgaW4geW91ciBzeXN0ZW0uIFlvdSBjdXJyZW50bHkgaGF2ZSAiCiAgICAgICAgICAgIC4gJCNUaWNrZXRJRHMKICAgICAgICAgICAgLiAiLiBJbiBjYXNlIHlvdSB3YW50IHRvIGltcHJvdmUgeW91ciBwZXJmb3JtYW5jZSwgY2xvc2Ugbm90IG5lZWRlZCBvcGVuIHRpY2tldHMuIjsKCiAgICB9CiAgICBlbHNpZiAoICQjVGlja2V0SURzID4gODAwMCApIHsKICAgICAgICAkQ2hlY2sgPSAnQ3JpdGljYWwnOwogICAgICAgICRNZXNzYWdlCiAgICAgICAgICAgID0gIllvdSBzaG91bGQgbm90IGhhdmUgbW9yZSB0aGVuIDgwMDAgb3BlbiB0aWNrZXRzIGluIHlvdXIgc3lzdGVtLiBZb3UgY3VycmVudGx5IGhhdmUgIgogICAgICAgICAgICAuICQjVGlja2V0SURzCiAgICAgICAgICAgIC4gIi4gSW4gY2FzZSB5b3Ugd2FudCB0byBpbXByb3ZlIHlvdXIgcGVyZm9ybWFuY2UsIGNsb3NlIG5vdCBuZWVkZWQgb3BlbiB0aWNrZXRzLiI7CgogICAgfQogICAgZWxzZSB7CiAgICAgICAgJENoZWNrICAgPSAnT0snOwogICAgICAgICRNZXNzYWdlID0gIllvdSBoYXZlICIgLiAkI1RpY2tldElEcyAuICIgb3BlbiB0aWNrZXRzIGluIHlvdXIgc3lzdGVtLiI7CiAgICB9CiAgICAkRGF0YSA9IHsKICAgICAgICBLZXkgICAgICAgICA9PiAnT3BlblRpY2tldENoZWNrJywKICAgICAgICBOYW1lICAgICAgICA9PiAnT3BlblRpY2tldENoZWNrJywKICAgICAgICBEZXNjcmlwdGlvbiA9PiAiQ2hlY2sgb3BlbiB0aWNrZXRzIGluIHlvdXIgc3lzdGVtLiIsCiAgICAgICAgQ29tbWVudCAgICAgPT4gJE1lc3NhZ2UsCiAgICAgICAgQ2hlY2sgICAgICAgPT4gJENoZWNrLAogICAgICAgIH0sCiAgICAgICAgcmV0dXJuICREYXRhOwp9CgojIENoZWNrIGlmIHRoZSBjb25maWd1cmVkIEZRRE4gaXMgdmFsaWQuCnN1YiBfRlFETkNvbmZpZ0NoZWNrIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CiAgICBteSAkRGF0YSA9IHsKICAgICAgICBLZXkgICAgICAgICA9PiAnRlFETkNvbmZpZ0NoZWNrJywKICAgICAgICBOYW1lICAgICAgICA9PiAnRlFETkNvbmZpZ0NoZWNrJywKICAgICAgICBEZXNjcmlwdGlvbiA9PiAiQ2hlY2sgaWYgdGhlIGNvbmZpZ3VyZWQgZnVsbHkgcXVhbGlmaWVkIGhvc3QgbmFtZSBpcyB2YWxpZC4iLAogICAgICAgIENoZWNrICAgICAgID0+ICdGYWlsZWQnLAogICAgICAgIENvbW1lbnQgICAgID0+ICcnLAogICAgfTsKCiAgICAjIEdldCB0aGUgY29uZmlndXJlZCBGUUROCiAgICBteSAkRlFETiA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdGUUROJyk7CgogICAgIyBEbyB3ZSBoYXZlIHNldCBvdXIgRlFETj8KICAgIGlmICggJEZRRE4gZXEgJ3lvdXJob3N0LmV4YW1wbGUuY29tJyApIHsKICAgICAgICAkRGF0YS0+e0NoZWNrfSAgID0gJ0ZhaWxlZCc7CiAgICAgICAgJERhdGEtPntDb21tZW50fSA9ICdQbGVhc2UgY29uZmlndXJlIHlvdXIgRlFETi4nOwogICAgfQoKICAgICMgRlFETiBzeW50YXggY2hlY2suCiAgICBlbHNpZiAoICRGUUROID1+IC9cLlwufFxzfFteYS16QS1aMC05LS5dL2cgKSB7CiAgICAgICAgJERhdGEtPntDaGVja30gICA9ICdGYWlsZWQnOwogICAgICAgICREYXRhLT57Q29tbWVudH0gPSAiSW52YWxpZCBGUUROICckRlFETicuIjsKICAgIH0KCiAgICAjIE5vdGhpbmcgdG8gY29tcGxhaW4uIDotKAogICAgZWxzZSB7CiAgICAgICAgJERhdGEtPntDaGVja30gICA9ICdPSyc7CiAgICAgICAgJERhdGEtPntDb21tZW50fSA9ICJGUUROICckRlFETicgbG9va3MgZ29vZC4iOwogICAgfQogICAgcmV0dXJuICREYXRhOwp9CjE7Cg==
IyAtLQojIEtlcm5lbC9TeXN0ZW0vU3VwcG9ydC9XZWJzZXJ2ZXIvSUlTLnBtIC0gYWxsIHJlcXVpcmVkIHN5c3RlbSBpbmZvcm1hdGlvbnMKIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwNyBPVFJTIEdtYkgsIGh0dHA6Ly9vdHJzLm9yZy8KIyAtLQojICRJZDogSUlTLnBtLHYgMS4yIDIwMDcvMDUvMjMgMTg6MTI6MDIgc3IgRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpTdXBwb3J0OjpXZWJzZXJ2ZXI6OklJUzsKCnVzZSBzdHJpY3Q7Cgp1c2UgdmFycyBxdyhASVNBICRWRVJTSU9OKTsKJFZFUlNJT04gPSAnJFJldmlzaW9uOiAxLjIgJCc7CiRWRVJTSU9OID1+IHMvXlwkLio6XFcoLiopXFcuKz8kLyQxLzsKCj1oZWFkMSBOQU1FCgpLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6V2Vic2VydmVyOjpJSVMgLSBJSVMgaW5mb3JtYXRpb24KCj1oZWFkMSBTWU5PUFNJUwoKQWxsIHJlcXVpcmVkIHN5c3RlbSBpbmZvcm1hdGlvbnMgdG8gYSBydW5uaW5nIE9UUlMgaG9zdC4KCj1oZWFkMSBQVUJMSUMgSU5URVJGQUNFCgo9b3ZlciA0Cgo9Y3V0Cgo9aXRlbSBuZXcoKQoKY3JlYXRlIFdlYnNlcnZlciBpbmZvIG9iamVjdAoKICAgIHVzZSBLZXJuZWw6OkNvbmZpZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6TG9nOwogICAgbXkgJENvbmZpZ09iamVjdCA9IEtlcm5lbDo6Q29uZmlnLT5uZXcoKTsKICAgIG15ICRMb2dPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6TG9nLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICApOwoKICAgICRTeXN0ZW1JbmZvT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OlN1cHBvcnQ6OldlYnNlcnZlci0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCA9PiAkTG9nT2JqZWN0LAogICAgKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgJFR5cGUgPSBzaGlmdDsKICAgIG15ICVQYXJhbSA9IEBfOwogICAgIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CiAgICBteSAkU2VsZiA9IHt9OwogICAgYmxlc3MgKCRTZWxmLCAkVHlwZSk7CiAgICAjIGNoZWNrIG5lZWRlZCBvYmplY3RzCiAgICBmb3JlYWNoIChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JF99ID0gJFBhcmFteyRffSB8fCBkaWUgIkdvdCBubyAkXyEiOwogICAgfQoKICAgIHJldHVybiAkU2VsZjsKfQoKPWl0ZW0gU3VwcG9ydENvbmZpZ0FycmF5R2V0KCkKCnJldHVybiBhbiBhcnJheSByZWZlcmVuY2Ugd2l0aCByZXF1aXJlZCBjb25maWcgaW5mb3JtYXRpb24uCgogICAgJEFycmF5UmVmID0gJFN1cHBvcnQtPlN1cHBvcnRDb25maWdBcnJheUdldCgpOwoKICAgIG15ICRDb25maWdBcnJheSA9IFsKICAgICAgICB7CiAgICAgICAgICAgIEtleSA9PiAnVGlja2V0RHVtcCcsCiAgICAgICAgICAgIE5hbWUgPT4gJ0R1bXAgVGlja2V0cycsCiAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgdGVsbCBtZSBob3cgbWFueSBsYXRlc3QgVGlja2V0cyB3ZSBzaHV0IGR1bXA/JywKICAgICAgICAgICAgSW5wdXQgPT4gewogICAgICAgICAgICAgICAgVHlwZSA9PiAnU2VsZWN0JywKICAgICAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgICAgIEFsbCA9PiAnQWxsJywKICAgICAgICAgICAgICAgICAgICAwID0+ICcwJywKICAgICAgICAgICAgICAgICAgICAxMCA9PiAnTGFzdCAxMCcsCiAgICAgICAgICAgICAgICAgICAgMTAwID0+ICdMYXN0IDEwMCcsCiAgICAgICAgICAgICAgICAgICAgMTAwMCA9PiAnTGFzdCAxMDAwJywKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgICAgICB7CiAgICAgICAgICAgIEtleSA9PiAnQXBhY2hlSG9tZScsCiAgICAgICAgICAgIE5hbWUgPT4gJ0FwYWNoZSBIb21lIERpcmVjdG9yeScsCiAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgdGVsbCBtZSB0aGUgcGF0aCB0byB0aGUgQXBhY2hlIGhvbWUgZGlyZWN0b3J5ICgvZXRjL2FwYWNoZTIpJywKICAgICAgICAgICAgSW5wdXQgPT4gewogICAgICAgICAgICAgICAgVHlwZSA9PiAnVGV4dCcsCiAgICAgICAgICAgICAgICBTaXplID0+IDQwLAogICAgICAgICAgICB9LAogICAgICAgIH0sCiAgICBdOwoKPWN1dAoKc3ViIFN1cHBvcnRDb25maWdBcnJheUdldCB7CiAgICBteSAkU2VsZiA9IHNoaWZ0OwogICAgbXkgJVBhcmFtID0gQF87CiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yZWFjaCAocXcoKSkgewogICAgICAgIGlmICghJFBhcmFteyRffSkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyhQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQp9Cgo9aXRlbSBTdXBwb3J0SW5mb0dldCgpCgpyZXR1cm5zIGEgYXJyYXkgcmVmZXJlbmNlIHdpdGggc3VwcG9ydCBpbmZvcm1hdGlvbi4KCiRXZWJzZXJ2ZXJBcnJheSA9PiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9PiAnUGxhdHRmb3JtJywKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1BsYXR0Zm9ybScsCiAgICAgICAgICAgICAgICBDb21tZW50ID0+ICdMaW51eCcsCiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAnUGxlYXNlIGFkZCBtb3JlIG1lbW9yeS4nLAogICAgICAgICAgICAgICAgQ2hlY2sgPT4gJ09LJywKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0+ICdWZXJzaW9uJywKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1ZlcnNpb24nLAogICAgICAgICAgICAgICAgQ29tbWVudCA9PiAnb3BlblNVU0UgMTAuMicsCiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAnUGxlYXNlIGFkZCBtb3JlIG1lbW9yeS4nLAogICAgICAgICAgICAgICAgQ2hlY2sgPT4gJ09LJywKICAgICAgICAgICAgfSwKICAgICAgICBdOwoKPWN1dAoKc3ViIFN1cHBvcnRJbmZvR2V0IHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CiAgICBteSAlUGFyYW0gPSBAXzsKICAgIG15ICREYXRhQXJyYXkgPSBbXTsKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3JlYWNoIChxdyhNb2R1bGVJbnB1dEhhc2gpKSB7CiAgICAgICAgaWYgKCEkUGFyYW17JF99KSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKFByaW9yaXR5ID0+ICdlcnJvcicsIE1lc3NhZ2UgPT4gIk5lZWQgJF8hIik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CiAgICBpZiAocmVmKCRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9KSBuZSAnSEFTSCcpIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyhQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJNb2R1bGVJbnB1dEhhc2ggbXVzdCBiZSBhIGhhc2ggcmVmZXJlbmNlISIpOwogICAgICAgIHJldHVybjsKICAgIH0KIyAgICAjIHBsZWFzZSBhZGQgZm9yIGVhY2ggbmV3IGNoZWNrIGEgcGFydCBsaWtlIHRoaXMKIyAgICBteSAkT25lQ2hlY2sgPSAkU2VsZi0+Q2hlY2soCiMgICAgICAgIFR5cGUgPT4gJFBhcmFte01vZHVsZUlucHV0SGFzaH0tPntUeXBlfSB8fCAnJywKIyAgICApOwojICAgIHB1c2ggKEB7JERhdGFBcnJheX0sICRPbmVDaGVjayk7CgogICAgcmV0dXJuICREYXRhQXJyYXk7Cn0KCj1pdGVtIEFkbWluQ2hlY2tzR2V0KCkKCnJldHVybnMgYSBhcnJheSByZWZlcmVuY2Ugd2l0aCBBZG1pbkNoZWNrcyBpbmZvcm1hdGlvbi4KCiRXZWJzZXJ2ZXJBcnJheSA9PiBbCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9PiAnUGxhdHRmb3JtJywKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1BsYXR0Zm9ybScsCiAgICAgICAgICAgICAgICBDb21tZW50ID0+ICdMaW51eCcsCiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAnUGxlYXNlIGFkZCBtb3JlIG1lbW9yeS4nLAogICAgICAgICAgICAgICAgQ2hlY2sgPT4gJ09LJywKICAgICAgICAgICAgfSwKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0+ICdWZXJzaW9uJywKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1ZlcnNpb24nLAogICAgICAgICAgICAgICAgQ29tbWVudCA9PiAnb3BlblNVU0UgMTAuMicsCiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAnUGxlYXNlIGFkZCBtb3JlIG1lbW9yeS4nLAogICAgICAgICAgICAgICAgQ2hlY2sgPT4gJ09LJywKICAgICAgICAgICAgfSwKICAgICAgICBdOwoKPWN1dAoKc3ViIEFkbWluQ2hlY2tzR2V0IHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CiAgICBteSAlUGFyYW0gPSBAXzsKICAgIG15ICREYXRhQXJyYXkgPSBbXTsKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3JlYWNoIChxdygpKSB7CiAgICAgICAgaWYgKCEkUGFyYW17JF99KSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKFByaW9yaXR5ID0+ICdlcnJvcicsIE1lc3NhZ2UgPT4gIk5lZWQgJF8hIik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CiMgICAgIyBwbGVhc2UgYWRkIGZvciBlYWNoIG5ldyBjaGVjayBhIHBhcnQgbGlrZSB0aGlzCiMgICAgbXkgJE9uZUNoZWNrID0gJFNlbGYtPkNoZWNrKCk7CiMgICAgcHVzaCAoQHskRGF0YUFycmF5fSwgJE9uZUNoZWNrKTsKCiAgICByZXR1cm4gJERhdGFBcnJheTsKfQoKPWl0ZW0gQ2hlY2soKQoKcmV0dXJucyBhIGhhc2ggcmVmZXJlbmNlIHdpdGggQ2hlY2sgaW5mb3JtYXRpb24uCgokQ2hlY2tIYXNoID0+CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9PiAnUGxhdHRmb3JtJywKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1BsYXR0Zm9ybScsCiAgICAgICAgICAgICAgICBDb21tZW50ID0+ICdMaW51eCcsCiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAnUGxlYXNlIGFkZCBtb3JlIG1lbW9yeS4nLAogICAgICAgICAgICAgICAgQ2hlY2sgPT4gJ09LJywKICAgICAgICAgICAgfTsKCiMgY2hlY2sgaWYgY29uZmlnIHZhbHVlIGF2YWlsaWJsZQppZiAoJFBhcmFte1R5cGV9KSB7CiAgICBwcmludCBTVERFUlIgIlRZUEU6ICIgLiAkUGFyYW17VHlwZX07Cn0KCj1jdXQKCnN1YiBDaGVjayB7CiAgICBteSAkU2VsZiA9IHNoaWZ0OwogICAgbXkgJVBhcmFtID0gQF87CiAgICBteSAkUmV0dXJuSGFzaCA9IHt9OwogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvcmVhY2ggKHF3KCkpIHsKICAgICAgICBpZiAoISRQYXJhbXskX30pIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIElmIHVzZWQgT1MgaXMgYSBsaW51eCBzeXN0ZW0KICAgIGlmICgkXk8gPX4gL2xpbnV4LyB8fCAvdW5peC8gfHwgL25ldGJzZC8gfHwgL2ZyZWVic2QvIHx8IC9EYXJ3aW4vKSB7CgogICAgfQogICAgZWxzaWYgKCReTyA9fiAvd2luL2kpIHsjIFRPRE8gLyBBdXNnYWJlIHVudGVyIFdpbmRvd3Mgbm9jaCBwcnVlZmVuCgogICAgfQogICAgcmV0dXJuICRSZXR1cm5IYXNoOwp9CgoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBzb2Z0d2FyZSBpcyBwYXJ0IG9mIHRoZSBPVFJTIHByb2plY3QgKGh0dHA6Ly9vdHJzLm9yZy8pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLnR4dC4KCj1jdXQKCj1oZWFkMSBWRVJTSU9OCgokUmV2aXNpb246IDEuMiAkICREYXRlOiAyMDA3LzA1LzIzIDE4OjEyOjAyICQKCj1jdXQK
IyAtLQojIEtlcm5lbC9TeXN0ZW0vU3VwcG9ydC9XZWJzZXJ2ZXIvQXBhY2hlLnBtIC0gYWxsIHJlcXVpcmVkIHN5c3RlbSBpbmZvcm1hdGlvbnMKIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwNyBPVFJTIEdtYkgsIGh0dHA6Ly9vdHJzLm9yZy8KIyAtLQojICRJZDogQXBhY2hlLnBtLHYgMS42IDIwMDcvMTEvMjIgMTI6MDI6MzEgc3IgRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpTdXBwb3J0OjpXZWJzZXJ2ZXI6OkFwYWNoZTsKCnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKCnVzZSB2YXJzIHF3KEBJU0EgJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS42ICQpIFsxXTsKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgb2JqZWN0cwogICAgZm9yIChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JF99ID0gJFBhcmFteyRffSB8fCBkaWUgIkdvdCBubyAkXyEiOwogICAgfQoKICAgIHJldHVybiAkU2VsZjsKfQoKc3ViIFN1cHBvcnRDb25maWdBcnJheUdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgKHF3KCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JF99ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9Cn0KCnN1YiBTdXBwb3J0SW5mb0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17TW9kdWxlSW5wdXRIYXNofSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKCByZWYoICRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9ICkgbmUgJ0hBU0gnICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fQogICAgICAgICAgICAtPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTW9kdWxlSW5wdXRIYXNoIG11c3QgYmUgYSBoYXNoIHJlZmVyZW5jZSEiICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgYWRkIG5ldyBmdW5jdGlvbiBuYW1lIGhlcmUKICAgIG15IEBNb2R1bGVMaXN0ID0gKAogICAgICAgICdfQXBhY2hlREJJQ2hlY2snLCAnX0FwYWNoZVJlbG9hZENoZWNrJywKICAgICAgICAnX01vZFBlcmxWZXJzaW9uQ2hlY2snLAogICAgKTsKCiAgICBteSBARGF0YUFycmF5OwoKICAgIEZVTkNUSU9OTkFNRToKICAgIGZvciBteSAkRnVuY3Rpb25OYW1lIChATW9kdWxlTGlzdCkgewoKICAgICAgICAjIHJ1biBmdW5jdGlvbiBhbmQgZ2V0IGNoZWNrIGRhdGEKICAgICAgICBteSAkQ2hlY2sgPSAkU2VsZi0+JEZ1bmN0aW9uTmFtZSggVHlwZSA9PiAkUGFyYW17TW9kdWxlSW5wdXRIYXNofS0+e1R5cGV9IHx8ICcnLCApOwoKICAgICAgICBuZXh0IEZVTkNUSU9OTkFNRSBpZiAhJENoZWNrOwoKICAgICAgICAjIGF0dGFjaCBjaGVjayBkYXRhIGlmIHZhbGlkCiAgICAgICAgcHVzaCBARGF0YUFycmF5LCAkQ2hlY2s7CiAgICB9CgogICAgcmV0dXJuIFxARGF0YUFycmF5Owp9CgpzdWIgQWRtaW5DaGVja3NHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFkZCBuZXcgZnVuY3Rpb24gbmFtZSBoZXJlCiAgICBteSBATW9kdWxlTGlzdCA9ICgKICAgICAgICAnX0FwYWNoZURCSUNoZWNrJywgJ19BcGFjaGVSZWxvYWRDaGVjaycsCiAgICAgICAgJ19Nb2RQZXJsVmVyc2lvbkNoZWNrJywKICAgICk7CgogICAgbXkgQERhdGFBcnJheTsKCiAgICBGVU5DVElPTk5BTUU6CiAgICBmb3IgbXkgJEZ1bmN0aW9uTmFtZSAoQE1vZHVsZUxpc3QpIHsKCiAgICAgICAgIyBydW4gZnVuY3Rpb24gYW5kIGdldCBjaGVjayBkYXRhCiAgICAgICAgbXkgJENoZWNrID0gJFNlbGYtPiRGdW5jdGlvbk5hbWUoKTsKCiAgICAgICAgbmV4dCBGVU5DVElPTk5BTUUgaWYgISRDaGVjazsKCiAgICAgICAgIyBhdHRhY2ggY2hlY2sgZGF0YSBpZiB2YWxpZAogICAgICAgIHB1c2ggQERhdGFBcnJheSwgJENoZWNrOwogICAgfQoKICAgIHJldHVybiBcQERhdGFBcnJheTsKfQoKc3ViIF9BcGFjaGVEQklDaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICREYXRhID0ge307CgogICAgIyBjaGVjayBpZiBBcGFjaGU6OkRCSSBpcyBsb2FkZWQKICAgIG15ICRBcGFjaGVEQkkgPSAwOwogICAgbXkgJENoZWNrICAgICA9ICcnOwogICAgbXkgJE1lc3NhZ2UgICA9ICcnOwogICAgZm9yIG15ICRNb2R1bGUgKCBrZXlzICVJTkMgKSB7CiAgICAgICAgJE1vZHVsZSA9fiBzL1wvLzo6L2c7CiAgICAgICAgJE1vZHVsZSA9fiBzL1wucG0kLy9nOwogICAgICAgIGlmICggJE1vZHVsZSBlcSAnQXBhY2hlOjpEQkknIHx8ICRNb2R1bGUgZXEgJ0FwYWNoZTI6OkRCSScgKSB7CiAgICAgICAgICAgICRBcGFjaGVEQkkgPSAkTW9kdWxlOwogICAgICAgIH0KICAgIH0KICAgIGlmICggISRBcGFjaGVEQkkgKSB7CiAgICAgICAgJENoZWNrID0gJ0NyaXRpY2FsJzsKICAgICAgICAkTWVzc2FnZQogICAgICAgICAgICA9ICdBcGFjaGU6OkRCSSBzaG91bGQgYmUgdXNlZCB0byBnZXQgYSBiZXR0ZXIgcGVyZm9ybWFuY2UgKHByZSBlc3RhYmxpc2ggZGF0YWJhYmFzZSBjb25uZWN0aW9ucykuJzsKICAgIH0KICAgIGVsc2UgewogICAgICAgICRDaGVjayAgID0gJ09LJzsKICAgICAgICAkTWVzc2FnZSA9ICIkQXBhY2hlREJJIjsKICAgIH0KICAgICREYXRhID0gewogICAgICAgIEtleSAgICAgICAgID0+ICdBcGFjaGU6OkRCSScsCiAgICAgICAgTmFtZSAgICAgICAgPT4gJ0FwYWNoZTo6REJJJywKICAgICAgICBEZXNjcmlwdGlvbiA9PiAiQ2hlY2sgdXNlZCBBcGFjaGU6OkRCSS4iLAogICAgICAgIENvbW1lbnQgICAgID0+ICRNZXNzYWdlLAogICAgICAgIENoZWNrICAgICAgID0+ICRDaGVjaywKICAgICAgICB9LAogICAgICAgIHJldHVybiAkRGF0YTsKfQoKc3ViIF9BcGFjaGVSZWxvYWRDaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICREYXRhID0ge307CgogICAgIyByZWxvYWQgY2hlY2sKICAgIG15ICRDaGVjayAgID0gJ0ZhaWxlZCc7CiAgICBteSAkTWVzc2FnZSA9ICcnOwogICAgaWYgKCAkRU5We01PRF9QRVJMfSApIHsKICAgICAgICBldmFsICJyZXF1aXJlIG1vZF9wZXJsIjsKICAgICAgICBpZiAoIGRlZmluZWQgJG1vZF9wZXJsOjpWRVJTSU9OICkgewogICAgICAgICAgICBpZiAoICRtb2RfcGVybDo6VkVSU0lPTiA+PSAxLjk5ICkgewoKICAgICAgICAgICAgICAgICMgY2hlY2sgaWYgQXBhY2hlOjpSZWxvYWQgaXMgbG9hZGVkCiAgICAgICAgICAgICAgICBteSAkQXBhY2hlUmVsb2FkID0gMDsKICAgICAgICAgICAgICAgIGZvciBteSAkTW9kdWxlICgga2V5cyAlSU5DICkgewogICAgICAgICAgICAgICAgICAgICRNb2R1bGUgPX4gcy9cLy86Oi9nOwogICAgICAgICAgICAgICAgICAgICRNb2R1bGUgPX4gcy9cLnBtJC8vZzsKICAgICAgICAgICAgICAgICAgICBpZiAoICRNb2R1bGUgZXEgJ0FwYWNoZTo6UmVsb2FkJyB8fCAkTW9kdWxlIGVxICdBcGFjaGUyOjpSZWxvYWQnICkgewogICAgICAgICAgICAgICAgICAgICAgICAkQXBhY2hlUmVsb2FkID0gJE1vZHVsZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoICEkQXBhY2hlUmVsb2FkICkgewogICAgICAgICAgICAgICAgICAgICRDaGVjayA9ICdDcml0aWNhbCc7CiAgICAgICAgICAgICAgICAgICAgJE1lc3NhZ2UKICAgICAgICAgICAgICAgICAgICAgICAgPSAnQXBhY2hlOjpSZWxvYWQgb3IgQXBhY2hlMjo6UmVsb2FkIHNob3VsZCBiZSB1c2VkIGFzIFBlcmxNb2R1bGUgYW5kIFBlcmxJbml0SGFuZGxlciBpbiBBcGFjaGUgY29uZmlnIGZpbGUuJzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICRDaGVjayAgID0gJ09LJzsKICAgICAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICIkQXBhY2hlUmVsb2FkIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICAgICRDaGVjayAgID0gJ0NyaXRpY2FsJzsKICAgICAgICAkTWVzc2FnZSA9ICdZb3Ugc2hvdWxkIHVzZSBtb2RfcGVybCB0byBpbmNyZWFzZSB5b3VyIHBlcmZvcm1hbmNlIHZlcnkgc3Ryb25nISc7CiAgICB9CiAgICAkRGF0YSA9IHsKICAgICAgICBLZXkgICAgICAgICA9PiAnQXBhY2hlOjpSZWxvYWQnLAogICAgICAgIE5hbWUgICAgICAgID0+ICdBcGFjaGU6OlJlbG9hZCcsCiAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIHVzZWQgQXBhY2hlOjpSZWxvYWQvQXBhY2hlMjo6UmVsb2FkLiIsCiAgICAgICAgQ29tbWVudCAgICAgPT4gJE1lc3NhZ2UsCiAgICAgICAgQ2hlY2sgICAgICAgPT4gJENoZWNrLAogICAgICAgIH0sCiAgICAgICAgcmV0dXJuICREYXRhOwp9CgpzdWIgX01vZFBlcmxWZXJzaW9uQ2hlY2sgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkRGF0YSA9IHt9OwoKICAgICMgY2hlY2sgbW9kX3BlcmwgdmVyc2lvbgogICAgbXkgJENoZWNrICAgPSAnRmFpbGVkJzsKICAgIG15ICRNZXNzYWdlID0gJyc7CiAgICBpZiAoICRFTlZ7TU9EX1BFUkx9ICkgewogICAgICAgIGlmICggJEVOVntNT0RfUEVSTH0gPX4gL1wvMS45OS8gKSB7CiAgICAgICAgICAgICRDaGVjayA9ICdDcml0aWNhbCc7CiAgICAgICAgICAgICRNZXNzYWdlCiAgICAgICAgICAgICAgICA9ICJZb3UgdXNlIGEgYmV0YSB2ZXJzaW9uIG9mIG1vZF9wZXJsICgkRU5We01PRF9QRVJMfSksIHlvdSBzaG91bGQgdXBncmFkZSB0byBhIHN0YWJsZSB2ZXJzaW9uLiI7CiAgICAgICAgfQogICAgICAgIGVsc2lmICggJEVOVntNT0RfUEVSTH0gPX4gL1wvMS8gKSB7CiAgICAgICAgICAgICRDaGVjayAgID0gJ0NyaXRpY2FsJzsKICAgICAgICAgICAgJE1lc3NhZ2UgPSAiWW91IHNob3VsZCB1cGRhdGUgbW9kX3BlcmwgdG8gMi54ICgkRU5We01PRF9QRVJMfSkuIjsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRDaGVjayAgID0gJ09LJzsKICAgICAgICAgICAgJE1lc3NhZ2UgPSAiJEVOVntNT0RfUEVSTH0iOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICAgICRDaGVjayAgID0gJ0NyaXRpY2FsJzsKICAgICAgICAkTWVzc2FnZSA9ICdZb3Ugc2hvdWxkIHVzZSBtb2RfcGVybCB0byBpbmNyZWFzZSB5b3VyIHBlcmZvcm1hbmNlLic7CiAgICB9CiAgICAkRGF0YSA9IHsKICAgICAgICBLZXkgICAgICAgICA9PiAnbW9kX3BlcmwgdmVyc2lvbicsCiAgICAgICAgTmFtZSAgICAgICAgPT4gJ21vZF9wZXJsIHZlcnNpb24nLAogICAgICAgIERlc2NyaXB0aW9uID0+ICJDaGVjayB1c2VkIG1vZF9wZXJsIHZlcnNpb24uIiwKICAgICAgICBDb21tZW50ICAgICA9PiAkTWVzc2FnZSwKICAgICAgICBDaGVjayAgICAgICA9PiAkQ2hlY2ssCiAgICAgICAgfSwKICAgICAgICByZXR1cm4gJERhdGE7Cn0KCjE7Cg==
IyAtLQojIEtlcm5lbC9TeXN0ZW0vU3VwcG9ydC9EYXRhYmFzZS9vcmFjbGUucG0gLSBhbGwgcmVxdWlyZWQgc3lzdGVtIGluZm9ybWF0aW9ucwojIENvcHlyaWdodCAoQykgMjAwMS0yMDA3IE9UUlMgR21iSCwgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBvcmFjbGUucG0sdiAxLjggMjAwNy8xMS8yMiAxMTo1Mzo1NCBzciBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpTeXN0ZW06OlN1cHBvcnQ6OkRhdGFiYXNlOjpvcmFjbGU7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgS2VybmVsOjpTeXN0ZW06OlhNTDsKCnVzZSB2YXJzIHF3KEBJU0EgJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS44ICQpIFsxXTsKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgb2JqZWN0cwogICAgZm9yIChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0IERCT2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JF99ID0gJFBhcmFteyRffSB8fCBkaWUgIkdvdCBubyAkXyEiOwogICAgfQoKICAgICRTZWxmLT57WE1MT2JqZWN0fSA9IEtlcm5lbDo6U3lzdGVtOjpYTUwtPm5ldyglUGFyYW0pOwoKICAgIHJldHVybiAkU2VsZjsKfQoKc3ViIFN1cHBvcnRDb25maWdBcnJheUdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgKHF3KCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JF99ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9Cn0KCnN1YiBTdXBwb3J0SW5mb0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17TW9kdWxlSW5wdXRIYXNofSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKCByZWYoICRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9ICkgbmUgJ0hBU0gnICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fQogICAgICAgICAgICAtPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTW9kdWxlSW5wdXRIYXNoIG11c3QgYmUgYSBoYXNoIHJlZmVyZW5jZSEiICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgYWRkIG5ldyBmdW5jdGlvbiBuYW1lIGhlcmUKICAgIG15IEBNb2R1bGVMaXN0ID0gKAogICAgICAgICdfVGFibGVDaGVjaycsICdfTkxTRGF0ZUZvcm1hdENoZWNrJywKICAgICAgICAnX09yYWNsZUhvbWVDaGVjaycsICdfTkxTTGFuZ0NoZWNrJywKICAgICk7CgogICAgbXkgQERhdGFBcnJheTsKCiAgICBGVU5DVElPTk5BTUU6CiAgICBmb3IgbXkgJEZ1bmN0aW9uTmFtZSAoQE1vZHVsZUxpc3QpIHsKCiAgICAgICAgIyBydW4gZnVuY3Rpb24gYW5kIGdldCBjaGVjayBkYXRhCiAgICAgICAgbXkgJENoZWNrID0gJFNlbGYtPiRGdW5jdGlvbk5hbWUoIFR5cGUgPT4gJFBhcmFte01vZHVsZUlucHV0SGFzaH0tPntUeXBlfSB8fCAnJywgKTsKCiAgICAgICAgbmV4dCBGVU5DVElPTk5BTUUgaWYgISRDaGVjazsKCiAgICAgICAgIyBhdHRhY2ggY2hlY2sgZGF0YSBpZiB2YWxpZAogICAgICAgIHB1c2ggQERhdGFBcnJheSwgJENoZWNrOwogICAgfQoKICAgIHJldHVybiBcQERhdGFBcnJheTsKfQoKc3ViIEFkbWluQ2hlY2tzR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBhZGQgbmV3IGZ1bmN0aW9uIG5hbWUgaGVyZQogICAgbXkgQE1vZHVsZUxpc3QgPSAoCiAgICAgICAgJ19UYWJsZUNoZWNrJywgJ19OTFNEYXRlRm9ybWF0Q2hlY2snLAogICAgICAgICdfT3JhY2xlSG9tZUNoZWNrJywgJ19OTFNMYW5nQ2hlY2snLAogICAgKTsKCiAgICBteSBARGF0YUFycmF5OwoKICAgIEZVTkNUSU9OTkFNRToKICAgIGZvciBteSAkRnVuY3Rpb25OYW1lIChATW9kdWxlTGlzdCkgewoKICAgICAgICAjIHJ1biBmdW5jdGlvbiBhbmQgZ2V0IGNoZWNrIGRhdGEKICAgICAgICBteSAkQ2hlY2sgPSAkU2VsZi0+JEZ1bmN0aW9uTmFtZSgpOwoKICAgICAgICBuZXh0IEZVTkNUSU9OTkFNRSBpZiAhJENoZWNrOwoKICAgICAgICAjIGF0dGFjaCBjaGVjayBkYXRhIGlmIHZhbGlkCiAgICAgICAgcHVzaCBARGF0YUFycmF5LCAkQ2hlY2s7CiAgICB9CgogICAgcmV0dXJuIFxARGF0YUFycmF5Owp9CgpzdWIgX09yYWNsZUhvbWVDaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICREYXRhID0ge307CgogICAgIyBjaGVjayBPUkFDTEVfSE9NRQogICAgbXkgJENoZWNrICAgPSAnRmFpbGVkJzsKICAgIG15ICRNZXNzYWdlID0gJ05vIE9SQUNMRV9IT01FIGZvdW5kISc7CiAgICBpZiAoICRFTlZ7T1JBQ0xFX0hPTUV9ICkgewogICAgICAgIGlmICggIS1lICRFTlZ7T1JBQ0xFX0hPTUV9ICkgewogICAgICAgICAgICAkTWVzc2FnZSA9ICJPUkFDTEVfSE9NRSBkb24ndCBleGlzdHMgKCRFTlZ7T1JBQ0xFX0hPTUV9KSI7CiAgICAgICAgICAgICRDaGVjayAgID0gJ0ZhaWxlZCc7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAkTWVzc2FnZSA9ICIkRU5We09SQUNMRV9IT01FfSI7CiAgICAgICAgICAgICRDaGVjayAgID0gJ09LJzsKICAgICAgICB9CiAgICB9CiAgICAkRGF0YSA9IHsKICAgICAgICBLZXkgICAgICAgICA9PiAnT1JBQ0xFX0hPTUUnLAogICAgICAgIE5hbWUgICAgICAgID0+ICdPUkFDTEVfSE9NRScsCiAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIE9SQUNMRV9IT01FLiIsCiAgICAgICAgQ29tbWVudCAgICAgPT4gJE1lc3NhZ2UsCiAgICAgICAgQ2hlY2sgICAgICAgPT4gJENoZWNrLAogICAgICAgIH0sCiAgICAgICAgcmV0dXJuICREYXRhOwp9CgpzdWIgX05MU0xhbmdDaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICREYXRhID0ge307CgogICAgIyBjaGVjayBOTFNfTEFORwogICAgbXkgJENoZWNrICAgPSAnRmFpbGVkJzsKICAgIG15ICRNZXNzYWdlID0gJ05vIE5MU19MQU5HIGZvdW5kISc7CiAgICBpZiAoICRFTlZ7TkxTX0xBTkd9ICkgewogICAgICAgIGlmICggJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0RlZmF1bHRDaGFyc2V0JykgPX4gL3V0ZihcLTh8OCkvaSApIHsKICAgICAgICAgICAgaWYgKCAkRU5We05MU19MQU5HfSAhfiAvdXRmKFwtOHw4KS8gKSB7CiAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICIkRU5We05MU19MQU5HfSwgbmVlZCAudXRmOCBpbiBOTFNfTEFORyAoZS4gZy4gZ2VybWFuX2dlcm1hbnkudXRmOCkiOwogICAgICAgICAgICAgICAgJENoZWNrICAgPSAnRmFpbGVkJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICRNZXNzYWdlID0gIiRFTlZ7TkxTX0xBTkd9IjsKICAgICAgICAgICAgICAgICRDaGVjayAgID0gJ09LJzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJE1lc3NhZ2UgPSAiJEVOVntOTFNfTEFOR30iOwogICAgICAgICAgICAkQ2hlY2sgICA9ICdPSyc7CiAgICAgICAgfQogICAgfQogICAgJERhdGEgPSB7CiAgICAgICAgS2V5ICAgICAgICAgPT4gJ05MU19MQU5HJywKICAgICAgICBOYW1lICAgICAgICA9PiAnTkxTX0xBTkcnLAogICAgICAgIERlc2NyaXB0aW9uID0+ICJDaGVjayBOTFNfTEFORy4iLAogICAgICAgIENvbW1lbnQgICAgID0+ICRNZXNzYWdlLAogICAgICAgIENoZWNrICAgICAgID0+ICRDaGVjaywKICAgICAgICB9LAogICAgICAgIHJldHVybiAkRGF0YTsKfQoKc3ViIF9OTFNEYXRlRm9ybWF0Q2hlY2sgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkRGF0YSA9IHt9OwoKICAgICMgY2hlY2sgTkxTX0RBVEVfRk9STUFUCiAgICBteSAkQ2hlY2sgICA9ICdGYWlsZWQnOwogICAgbXkgJE1lc3NhZ2UgPSAnTm8gTkxTX0RBVEVfRk9STUFUIGZvdW5kISc7CiAgICBpZiAoICRFTlZ7TkxTX0RBVEVfRk9STUFUfSApIHsKICAgICAgICBpZiAoICRFTlZ7TkxTX0RBVEVfRk9STUFUfSBuZSAiWVlZWS1NTS1ERCBISDI0Ok1JOlNTIiApIHsKICAgICAgICAgICAgJE1lc3NhZ2UKICAgICAgICAgICAgICAgID0gIiRFTlZ7TkxTX0RBVEVfRk9STUFUfSwgbmVlZCAnWVlZWS1NTS1ERCBISDI0Ok1JOlNTJyBmb3IgTkxTX0RBVEVfRk9STUFUIChub3QgJEVOVntOTFNfREFURV9GT1JNQVR9KSI7CiAgICAgICAgICAgICRDaGVjayA9ICdGYWlsZWQnOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJE1lc3NhZ2UgPSAiJEVOVntOTFNfREFURV9GT1JNQVR9IjsKICAgICAgICAgICAgJENoZWNrICAgPSAnT0snOwogICAgICAgIH0KICAgIH0KICAgICREYXRhID0gewogICAgICAgIEtleSAgICAgICAgID0+ICdOTFNfREFURV9GT1JNQVQnLAogICAgICAgIE5hbWUgICAgICAgID0+ICdOTFNfREFURV9GT1JNQVQnLAogICAgICAgIERlc2NyaXB0aW9uID0+ICJDaGVjayBOTFNfREFURV9GT1JNQVQuIiwKICAgICAgICBDb21tZW50ICAgICA9PiAkTWVzc2FnZSwKICAgICAgICBDaGVjayAgICAgICA9PiAkQ2hlY2ssCiAgICAgICAgfSwKICAgICAgICByZXR1cm4gJERhdGE7Cn0KCnN1YiBfVGFibGVDaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICREYXRhID0ge307CgogICAgIyB0YWJsZSBjaGVjawogICAgbXkgJEZpbGUgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gIi9zY3JpcHRzL2RhdGFiYXNlL290cnMtc2NoZW1hLnhtbCI7CiAgICBpZiAoIC1mICRGaWxlICkgewogICAgICAgIG15ICRDb3VudCAgID0gMDsKICAgICAgICBteSAkQ2hlY2sgICA9ICdGYWlsZWQnOwogICAgICAgIG15ICRNZXNzYWdlID0gJyc7CiAgICAgICAgbXkgJENvbnRlbnQgPSAnJzsKICAgICAgICBteSAkSW47CiAgICAgICAgaWYgKCBvcGVuKCAkSW4sICc8JywgIiRGaWxlIiApICkgewogICAgICAgICAgICB3aGlsZSAoPCRJbj4pIHsKICAgICAgICAgICAgICAgICRDb250ZW50IC49ICRfOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNsb3NlKCRJbik7CiAgICAgICAgICAgIG15IEBYTUxIYXNoID0gJFNlbGYtPntYTUxPYmplY3R9LT5YTUxQYXJzZTJYTUxIYXNoKCBTdHJpbmcgPT4gJENvbnRlbnQgKTsKICAgICAgICAgICAgZm9yIG15ICRUYWJsZSAoIEB7ICRYTUxIYXNoWzFdLT57ZGF0YWJhc2V9LT5bMV0tPntUYWJsZX0gfSApIHsKICAgICAgICAgICAgICAgIGlmICgkVGFibGUpIHsKICAgICAgICAgICAgICAgICAgICAkQ291bnQrKzsKICAgICAgICAgICAgICAgICAgICBpZiAoICRTZWxmLT57REJPYmplY3R9CiAgICAgICAgICAgICAgICAgICAgICAgIC0+UHJlcGFyZSggU1FMID0+ICJzZWxlY3QgKiBmcm9tICRUYWJsZS0+e05hbWV9IiwgTGltaXQgPT4gMSApICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRNZXNzYWdlIC49ICIkVGFibGUtPntOYW1lfSwgIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRNZXNzYWdlKSB7CiAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICJUYWJsZSBkb3NuJ3QgZXhpc3RzOiAkTWVzc2FnZSI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkQ2hlY2sgICA9ICdPSyc7CiAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICIkQ291bnQgVGFibGVzIjsKICAgICAgICAgICAgfQogICAgICAgICAgICAkRGF0YSA9IHsKICAgICAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdUYWJsZScsCiAgICAgICAgICAgICAgICBOYW1lICAgICAgICA9PiAnVGFibGUnLAogICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIGV4aXN0aW5nIGZyYW1ld29yayB0YWJsZXMuIiwKICAgICAgICAgICAgICAgIENvbW1lbnQgICAgID0+ICRNZXNzYWdlLAogICAgICAgICAgICAgICAgQ2hlY2sgICAgICAgPT4gJENoZWNrLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIDsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICREYXRhID0gewogICAgICAgICAgICAgICAgS2V5ICAgICAgICAgPT4gJ1RhYmxlJywKICAgICAgICAgICAgICAgIE5hbWUgICAgICAgID0+ICdUYWJsZScsCiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAiQ2hlY2sgZXhpc3RpbmcgZnJhbWV3b3JrIHRhYmxlcy4iLAogICAgICAgICAgICAgICAgQ29tbWVudCAgICAgPT4gIkNhbid0IG9wZW4gZmlsZSAkRmlsZTogJCEiLAogICAgICAgICAgICAgICAgQ2hlY2sgICAgICAgPT4gJENoZWNrLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIDsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgICAkRGF0YSA9IHsKICAgICAgICAgICAgS2V5ICAgICAgICAgPT4gJ1RhYmxlJywKICAgICAgICAgICAgTmFtZSAgICAgICAgPT4gJ1RhYmxlJywKICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIGV4aXN0aW5nIGZyYW1ld29yayB0YWJsZXMuIiwKICAgICAgICAgICAgQ29tbWVudCAgICAgPT4gIkNhbid0IGZpbmQgZmlsZSAkRmlsZSEiLAogICAgICAgICAgICBDaGVjayAgICAgICA9PiAnRmFpbGVkJywKICAgICAgICAgICAgfSwKICAgICAgICAgICAgOwogICAgfQogICAgcmV0dXJuICREYXRhOwp9CgoxOwo=
IyAtLQojIEtlcm5lbC9TeXN0ZW0vU3VwcG9ydC9EYXRhYmFzZS9tc3NxbC5wbSAtIGFsbCByZXF1aXJlZCBzeXN0ZW0gaW5mb3JtYXRpb25zCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDcgT1RSUyBHbWJILCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IG1zc3FsLnBtLHYgMS40IDIwMDcvMTEvMjIgMTE6NTQ6MjYgc3IgRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9ncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpTdXBwb3J0OjpEYXRhYmFzZTo6bXNzcWw7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgS2VybmVsOjpTeXN0ZW06OlhNTDsKCnVzZSB2YXJzIHF3KEBJU0EgJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS40ICQpIFsxXTsKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgb2JqZWN0cwogICAgZm9yIChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0IERCT2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JF99ID0gJFBhcmFteyRffSB8fCBkaWUgIkdvdCBubyAkXyEiOwogICAgfQoKICAgICRTZWxmLT57WE1MT2JqZWN0fSA9IEtlcm5lbDo6U3lzdGVtOjpYTUwtPm5ldyglUGFyYW0pOwoKICAgIHJldHVybiAkU2VsZjsKfQoKc3ViIFN1cHBvcnRDb25maWdBcnJheUdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgKHF3KCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JF99ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9Cn0KCnN1YiBTdXBwb3J0SW5mb0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17TW9kdWxlSW5wdXRIYXNofSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKCByZWYoICRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9ICkgbmUgJ0hBU0gnICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fQogICAgICAgICAgICAtPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTW9kdWxlSW5wdXRIYXNoIG11c3QgYmUgYSBoYXNoIHJlZmVyZW5jZSEiICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgYWRkIG5ldyBmdW5jdGlvbiBuYW1lIGhlcmUKICAgIG15IEBNb2R1bGVMaXN0ID0gKAogICAgICAgICdfVGFibGVDaGVjaycsCiAgICApOwoKICAgIG15IEBEYXRhQXJyYXk7CgogICAgRlVOQ1RJT05OQU1FOgogICAgZm9yIG15ICRGdW5jdGlvbk5hbWUgKEBNb2R1bGVMaXN0KSB7CgogICAgICAgICMgcnVuIGZ1bmN0aW9uIGFuZCBnZXQgY2hlY2sgZGF0YQogICAgICAgIG15ICRDaGVjayA9ICRTZWxmLT4kRnVuY3Rpb25OYW1lKCBUeXBlID0+ICRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9LT57VHlwZX0gfHwgJycsICk7CgogICAgICAgIG5leHQgRlVOQ1RJT05OQU1FIGlmICEkQ2hlY2s7CgogICAgICAgICMgYXR0YWNoIGNoZWNrIGRhdGEgaWYgdmFsaWQKICAgICAgICBwdXNoIEBEYXRhQXJyYXksICRDaGVjazsKICAgIH0KCiAgICByZXR1cm4gXEBEYXRhQXJyYXk7Cn0KCnN1YiBBZG1pbkNoZWNrc0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWRkIG5ldyBmdW5jdGlvbiBuYW1lIGhlcmUKICAgIG15IEBNb2R1bGVMaXN0ID0gKAogICAgICAgICdfVGFibGVDaGVjaycsCiAgICApOwoKICAgIG15IEBEYXRhQXJyYXk7CgogICAgRlVOQ1RJT05OQU1FOgogICAgZm9yIG15ICRGdW5jdGlvbk5hbWUgKEBNb2R1bGVMaXN0KSB7CgogICAgICAgICMgcnVuIGZ1bmN0aW9uIGFuZCBnZXQgY2hlY2sgZGF0YQogICAgICAgIG15ICRDaGVjayA9ICRTZWxmLT4kRnVuY3Rpb25OYW1lKCk7CgogICAgICAgIG5leHQgRlVOQ1RJT05OQU1FIGlmICEkQ2hlY2s7CgogICAgICAgICMgYXR0YWNoIGNoZWNrIGRhdGEgaWYgdmFsaWQKICAgICAgICBwdXNoIEBEYXRhQXJyYXksICRDaGVjazsKICAgIH0KCiAgICByZXR1cm4gXEBEYXRhQXJyYXk7Cn0KCnN1YiBfVGFibGVDaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICREYXRhID0ge307CgogICAgIyB0YWJsZSBjaGVjawogICAgbXkgJEZpbGUgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gIi9zY3JpcHRzL2RhdGFiYXNlL290cnMtc2NoZW1hLnhtbCI7CiAgICBpZiAoIC1mICRGaWxlICkgewogICAgICAgIG15ICRDb3VudCAgID0gMDsKICAgICAgICBteSAkQ2hlY2sgICA9ICdGYWlsZWQnOwogICAgICAgIG15ICRNZXNzYWdlID0gJyc7CiAgICAgICAgbXkgJENvbnRlbnQgPSAnJzsKICAgICAgICBteSAkSW47CiAgICAgICAgaWYgKCBvcGVuKCAkSW4sICc8JywgIiRGaWxlIiApICkgewogICAgICAgICAgICB3aGlsZSAoPCRJbj4pIHsKICAgICAgICAgICAgICAgICRDb250ZW50IC49ICRfOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNsb3NlKCRJbik7CiAgICAgICAgICAgIG15IEBYTUxIYXNoID0gJFNlbGYtPntYTUxPYmplY3R9LT5YTUxQYXJzZTJYTUxIYXNoKCBTdHJpbmcgPT4gJENvbnRlbnQgKTsKICAgICAgICAgICAgZm9yIG15ICRUYWJsZSAoIEB7ICRYTUxIYXNoWzFdLT57ZGF0YWJhc2V9LT5bMV0tPntUYWJsZX0gfSApIHsKICAgICAgICAgICAgICAgIGlmICgkVGFibGUpIHsKICAgICAgICAgICAgICAgICAgICAkQ291bnQrKzsKICAgICAgICAgICAgICAgICAgICBpZiAoICRTZWxmLT57REJPYmplY3R9CiAgICAgICAgICAgICAgICAgICAgICAgIC0+UHJlcGFyZSggU1FMID0+ICJzZWxlY3QgKiBmcm9tICRUYWJsZS0+e05hbWV9IiwgTGltaXQgPT4gMSApICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRNZXNzYWdlIC49ICIkVGFibGUtPntOYW1lfSwgIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRNZXNzYWdlKSB7CiAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICJUYWJsZSBkb3NuJ3QgZXhpc3RzOiAkTWVzc2FnZSI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkQ2hlY2sgICA9ICdPSyc7CiAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICIkQ291bnQgVGFibGVzIjsKICAgICAgICAgICAgfQogICAgICAgICAgICAkRGF0YSA9IHsKICAgICAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdUYWJsZScsCiAgICAgICAgICAgICAgICBOYW1lICAgICAgICA9PiAnVGFibGUnLAogICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIGV4aXN0aW5nIGZyYW1ld29yayB0YWJsZXMuIiwKICAgICAgICAgICAgICAgIENvbW1lbnQgICAgID0+ICRNZXNzYWdlLAogICAgICAgICAgICAgICAgQ2hlY2sgICAgICAgPT4gJENoZWNrLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIDsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICREYXRhID0gewogICAgICAgICAgICAgICAgS2V5ICAgICAgICAgPT4gJ1RhYmxlJywKICAgICAgICAgICAgICAgIE5hbWUgICAgICAgID0+ICdUYWJsZScsCiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAiQ2hlY2sgZXhpc3RpbmcgZnJhbWV3b3JrIHRhYmxlcy4iLAogICAgICAgICAgICAgICAgQ29tbWVudCAgICAgPT4gIkNhbid0IG9wZW4gZmlsZSAkRmlsZTogJCEiLAogICAgICAgICAgICAgICAgQ2hlY2sgICAgICAgPT4gJENoZWNrLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIDsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgICAkRGF0YSA9IHsKICAgICAgICAgICAgS2V5ICAgICAgICAgPT4gJ1RhYmxlJywKICAgICAgICAgICAgTmFtZSAgICAgICAgPT4gJ1RhYmxlJywKICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIGV4aXN0aW5nIGZyYW1ld29yayB0YWJsZXMuIiwKICAgICAgICAgICAgQ29tbWVudCAgICAgPT4gIkNhbid0IGZpbmQgZmlsZSAkRmlsZSEiLAogICAgICAgICAgICBDaGVjayAgICAgICA9PiAnRmFpbGVkJywKICAgICAgICAgICAgfSwKICAgICAgICAgICAgOwogICAgfQogICAgcmV0dXJuICREYXRhOwp9CjE7Cg==
IyAtLQojIEtlcm5lbC9TeXN0ZW0vU3VwcG9ydC9EYXRhYmFzZS9wb3N0Z3Jlc3FsLnBtIC0gYWxsIHJlcXVpcmVkIHN5c3RlbSBpbmZvcm1hdGlvbnMKIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwNyBPVFJTIEdtYkgsIGh0dHA6Ly9vdHJzLm9yZy8KIyAtLQojICRJZDogcG9zdGdyZXNxbC5wbSx2IDEuNSAyMDA3LzExLzIyIDExOjU4OjM4IHNyIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLnR4dC4KIyAtLQoKcGFja2FnZSBLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6RGF0YWJhc2U6OnBvc3RncmVzcWw7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgS2VybmVsOjpTeXN0ZW06OlhNTDsKCnVzZSB2YXJzIHF3KEBJU0EgJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS41ICQpIFsxXTsKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgb2JqZWN0cwogICAgZm9yIChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0IERCT2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JF99ID0gJFBhcmFteyRffSB8fCBkaWUgIkdvdCBubyAkXyEiOwogICAgfQoKICAgICRTZWxmLT57WE1MT2JqZWN0fSA9IEtlcm5lbDo6U3lzdGVtOjpYTUwtPm5ldyglUGFyYW0pOwoKICAgIHJldHVybiAkU2VsZjsKfQoKc3ViIFN1cHBvcnRDb25maWdBcnJheUdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgKHF3KCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JF99ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9Cn0KCnN1YiBTdXBwb3J0SW5mb0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17TW9kdWxlSW5wdXRIYXNofSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKCByZWYoICRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9ICkgbmUgJ0hBU0gnICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fQogICAgICAgICAgICAtPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTW9kdWxlSW5wdXRIYXNoIG11c3QgYmUgYSBoYXNoIHJlZmVyZW5jZSEiICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgYWRkIG5ldyBmdW5jdGlvbiBuYW1lIGhlcmUKICAgIG15IEBNb2R1bGVMaXN0ID0gKAogICAgICAgICdfRGF0ZXN0eWxlQ2hlY2snLCAnX1VURjhTZXJ2ZXJDaGVjaycsCiAgICAgICAgJ19UYWJsZUNoZWNrJywgJ19VVEY4Q2xpZW50Q2hlY2snLAogICAgICAgICdfVmVyc2lvbkNoZWNrJywKICAgICk7CgogICAgbXkgQERhdGFBcnJheTsKCiAgICBGVU5DVElPTk5BTUU6CiAgICBmb3IgbXkgJEZ1bmN0aW9uTmFtZSAoQE1vZHVsZUxpc3QpIHsKCiAgICAgICAgIyBydW4gZnVuY3Rpb24gYW5kIGdldCBjaGVjayBkYXRhCiAgICAgICAgbXkgJENoZWNrID0gJFNlbGYtPiRGdW5jdGlvbk5hbWUoIFR5cGUgPT4gJFBhcmFte01vZHVsZUlucHV0SGFzaH0tPntUeXBlfSB8fCAnJywgKTsKCiAgICAgICAgbmV4dCBGVU5DVElPTk5BTUUgaWYgISRDaGVjazsKCiAgICAgICAgIyBhdHRhY2ggY2hlY2sgZGF0YSBpZiB2YWxpZAogICAgICAgIHB1c2ggQERhdGFBcnJheSwgJENoZWNrOwogICAgfQoKICAgIHJldHVybiBcQERhdGFBcnJheTsKfQoKc3ViIEFkbWluQ2hlY2tzR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBhZGQgbmV3IGZ1bmN0aW9uIG5hbWUgaGVyZQogICAgbXkgQE1vZHVsZUxpc3QgPSAoCiAgICAgICAgJ19EYXRlc3R5bGVDaGVjaycsICdfVVRGOFNlcnZlckNoZWNrJywKICAgICAgICAnX1RhYmxlQ2hlY2snLCAnX1VURjhDbGllbnRDaGVjaycsCiAgICAgICAgJ19WZXJzaW9uQ2hlY2snLAogICAgKTsKCiAgICBteSBARGF0YUFycmF5OwoKICAgIEZVTkNUSU9OTkFNRToKICAgIGZvciBteSAkRnVuY3Rpb25OYW1lIChATW9kdWxlTGlzdCkgewoKICAgICAgICAjIHJ1biBmdW5jdGlvbiBhbmQgZ2V0IGNoZWNrIGRhdGEKICAgICAgICBteSAkQ2hlY2sgPSAkU2VsZi0+JEZ1bmN0aW9uTmFtZSgpOwoKICAgICAgICBuZXh0IEZVTkNUSU9OTkFNRSBpZiAhJENoZWNrOwoKICAgICAgICAjIGF0dGFjaCBjaGVjayBkYXRhIGlmIHZhbGlkCiAgICAgICAgcHVzaCBARGF0YUFycmF5LCAkQ2hlY2s7CiAgICB9CgogICAgcmV0dXJuIFxARGF0YUFycmF5Owp9CgpzdWIgX1RhYmxlQ2hlY2sgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkRGF0YSA9IHt9OwoKICAgICMgdGFibGUgY2hlY2sKICAgIG15ICRGaWxlID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICIvc2NyaXB0cy9kYXRhYmFzZS9vdHJzLXNjaGVtYS54bWwiOwogICAgaWYgKCAtZiAkRmlsZSApIHsKICAgICAgICBteSAkQ291bnQgICA9IDA7CiAgICAgICAgbXkgJENoZWNrICAgPSAnRmFpbGVkJzsKICAgICAgICBteSAkTWVzc2FnZSA9ICcnOwogICAgICAgIG15ICRDb250ZW50ID0gJyc7CiAgICAgICAgbXkgJEluOwogICAgICAgIGlmICggb3BlbiggJEluLCAnPCcsICIkRmlsZSIgKSApIHsKICAgICAgICAgICAgd2hpbGUgKDwkSW4+KSB7CiAgICAgICAgICAgICAgICAkQ29udGVudCAuPSAkXzsKICAgICAgICAgICAgfQogICAgICAgICAgICBjbG9zZSgkSW4pOwogICAgICAgICAgICBteSBAWE1MSGFzaCA9ICRTZWxmLT57WE1MT2JqZWN0fS0+WE1MUGFyc2UyWE1MSGFzaCggU3RyaW5nID0+ICRDb250ZW50ICk7CiAgICAgICAgICAgIGZvciBteSAkVGFibGUgKCBAeyAkWE1MSGFzaFsxXS0+e2RhdGFiYXNlfS0+WzFdLT57VGFibGV9IH0gKSB7CiAgICAgICAgICAgICAgICBpZiAoJFRhYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgJENvdW50Kys7CiAgICAgICAgICAgICAgICAgICAgaWYgKCAkU2VsZi0+e0RCT2JqZWN0fQogICAgICAgICAgICAgICAgICAgICAgICAtPlByZXBhcmUoIFNRTCA9PiAic2VsZWN0ICogZnJvbSAkVGFibGUtPntOYW1lfSIsIExpbWl0ID0+IDEgKSApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAkTWVzc2FnZSAuPSAiJFRhYmxlLT57TmFtZX0sICI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICgkTWVzc2FnZSkgewogICAgICAgICAgICAgICAgJE1lc3NhZ2UgPSAiVGFibGUgZG9zbid0IGV4aXN0czogJE1lc3NhZ2UiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJENoZWNrICAgPSAnT0snOwogICAgICAgICAgICAgICAgJE1lc3NhZ2UgPSAiJENvdW50IFRhYmxlcyI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgJERhdGEgPSB7CiAgICAgICAgICAgICAgICBLZXkgICAgICAgICA9PiAnVGFibGUnLAogICAgICAgICAgICAgICAgTmFtZSAgICAgICAgPT4gJ1RhYmxlJywKICAgICAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICJDaGVjayBleGlzdGluZyBmcmFtZXdvcmsgdGFibGVzLiIsCiAgICAgICAgICAgICAgICBDb21tZW50ICAgICA9PiAkTWVzc2FnZSwKICAgICAgICAgICAgICAgIENoZWNrICAgICAgID0+ICRDaGVjaywKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICA7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAkRGF0YSA9IHsKICAgICAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdUYWJsZScsCiAgICAgICAgICAgICAgICBOYW1lICAgICAgICA9PiAnVGFibGUnLAogICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIGV4aXN0aW5nIGZyYW1ld29yayB0YWJsZXMuIiwKICAgICAgICAgICAgICAgIENvbW1lbnQgICAgID0+ICJDYW4ndCBvcGVuIGZpbGUgJEZpbGU6ICQhIiwKICAgICAgICAgICAgICAgIENoZWNrICAgICAgID0+ICRDaGVjaywKICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICA7CiAgICAgICAgfQogICAgfQogICAgZWxzZSB7CiAgICAgICAgJERhdGEgPSB7CiAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdUYWJsZScsCiAgICAgICAgICAgIE5hbWUgICAgICAgID0+ICdUYWJsZScsCiAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICJDaGVjayBleGlzdGluZyBmcmFtZXdvcmsgdGFibGVzLiIsCiAgICAgICAgICAgIENvbW1lbnQgICAgID0+ICJDYW4ndCBmaW5kIGZpbGUgJEZpbGUhIiwKICAgICAgICAgICAgQ2hlY2sgICAgICAgPT4gJ0ZhaWxlZCcsCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIDsKICAgIH0KICAgIHJldHVybiAkRGF0YTsKfQoKc3ViIF9EYXRlc3R5bGVDaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICREYXRhID0ge307CgogICAgIyBEYXRlc3R5bGUgY2hlY2sKICAgIG15ICRDaGVjayAgID0gJ0ZhaWxlZCc7CiAgICBteSAkTWVzc2FnZSA9ICdObyBEYXRlU3R5bGUgZm91bmQhJzsKICAgICRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKCBTUUwgPT4gInNob3cgYWxsIiApOwogICAgd2hpbGUgKCBteSBAUm93ID0gJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICBpZiAoICRSb3dbMF0gPX4gL15EYXRlU3R5bGUvaSApIHsKICAgICAgICAgICAgaWYgKCAkUm93WzFdID1+IC9eSVNPL2kgKSB7CiAgICAgICAgICAgICAgICAkQ2hlY2sgICA9ICdPSyc7CiAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICIkUm93WzFdIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICRDaGVjayAgID0gJ0ZhaWxlZCc7CiAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICJVbmtvd24gRGF0ZVN0eWxlICgkUm93WzFdKSBuZWVkIElTTy4iOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgJERhdGEgPSB7CiAgICAgICAgS2V5ICAgICAgICAgPT4gJ0RhdGVTdHlsZScsCiAgICAgICAgTmFtZSAgICAgICAgPT4gJ0RhdGVTdHlsZScsCiAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIERhdGVTdHlsZS4iLAogICAgICAgIENvbW1lbnQgICAgID0+ICRNZXNzYWdlLAogICAgICAgIENoZWNrICAgICAgID0+ICRDaGVjaywKICAgICAgICB9LAogICAgICAgIHJldHVybiAkRGF0YTsKfQoKc3ViIF9VVEY4U2VydmVyQ2hlY2sgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkRGF0YSA9IHt9OwoKICAgICMgdXRmLTggc2VydmVyIGNoZWNrCiAgICBpZiAoICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdEZWZhdWx0Q2hhcnNldCcpID1+IC91dGYoXC04fDgpL2kgKSB7CiAgICAgICAgbXkgJENoZWNrICAgPSAnRmFpbGVkJzsKICAgICAgICBteSAkTWVzc2FnZSA9ICdObyBzZXJ2ZXJfZW5jb2RpbmcgZm91bmQhJzsKICAgICAgICAkU2VsZi0+e0RCT2JqZWN0fS0+UHJlcGFyZSggU1FMID0+ICJzaG93IGFsbCIgKTsKICAgICAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgICAgICBpZiAoICRSb3dbMF0gPX4gL15zZXJ2ZXJfZW5jb2RpbmcvaSApIHsKICAgICAgICAgICAgICAgICRNZXNzYWdlID0gInNlcnZlcl9lbmNvZGluZyBmb3VuZCBidXQgaXQncyBzZXQgdG8gJFJvd1sxXSAobmVlZCB0byBiZSBVTklDT0RFKSI7CiAgICAgICAgICAgICAgICBpZiAoICRSb3dbMV0gPX4gL1VOSUNPREUvaSApIHsKICAgICAgICAgICAgICAgICAgICAkQ2hlY2sgICA9ICdPSyc7CiAgICAgICAgICAgICAgICAgICAgJE1lc3NhZ2UgPSAiJFJvd1sxXSI7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgJERhdGEgPSB7CiAgICAgICAgICAgIEtleSAgICAgICAgID0+ICd1dGY4IHNlcnZlciBjb25uZWN0aW9uJywKICAgICAgICAgICAgTmFtZSAgICAgICAgPT4gJ3V0Zjggc2VydmVyIGNvbm5lY3Rpb24nLAogICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAiQ2hlY2sgdGhlIHV0Zjggc2VydmVyIGNvbm5lY3Rpb24uIiwKICAgICAgICAgICAgQ29tbWVudCAgICAgPT4gJE1lc3NhZ2UsCiAgICAgICAgICAgIENoZWNrICAgICAgID0+ICRDaGVjaywKICAgICAgICAgICAgfSwKICAgICAgICAgICAgOwogICAgfQogICAgcmV0dXJuICREYXRhOwp9CgpzdWIgX1VURjhDbGllbnRDaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICREYXRhID0ge307CgogICAgIyB1dGYtOCBjbGllbnQgY2hlY2sKICAgIGlmICggJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0RlZmF1bHRDaGFyc2V0JykgPX4gL3V0ZihcLTh8OCkvaSApIHsKICAgICAgICBteSAkQ2hlY2sgICA9ICdGYWlsZWQnOwogICAgICAgIG15ICRNZXNzYWdlID0gJ05vIGNsaWVudF9lbmNvZGluZyBmb3VuZCEnOwogICAgICAgICRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKCBTUUwgPT4gInNob3cgYWxsIiApOwogICAgICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CiAgICAgICAgICAgIGlmICggJFJvd1swXSA9fiAvXmNsaWVudF9lbmNvZGluZy9pICkgewogICAgICAgICAgICAgICAgJE1lc3NhZ2UgPSAiY2xpZW50X2VuY29kaW5nIGZvdW5kIGJ1dCBpdCdzIHNldCB0byAkUm93WzFdIChuZWVkIHRvIGJlIFVOSUNPREUpIjsKICAgICAgICAgICAgICAgIGlmICggJFJvd1sxXSA9fiAvVU5JQ09ERS9pICkgewogICAgICAgICAgICAgICAgICAgICRDaGVjayAgID0gJ09LJzsKICAgICAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICIkUm93WzFdIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAkRGF0YSA9IHsKICAgICAgICAgICAgS2V5ICAgICAgICAgPT4gJ3V0ZjggY2xpZW50IGNvbm5lY3Rpb24nLAogICAgICAgICAgICBOYW1lICAgICAgICA9PiAndXRmOCBjbGllbnQgY29ubmVjdGlvbicsCiAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICJDaGVjayB0aGUgdXRmOCBjbGllbnQgY29ubmVjdGlvbi4iLAogICAgICAgICAgICBDb21tZW50ICAgICA9PiAkTWVzc2FnZSwKICAgICAgICAgICAgQ2hlY2sgICAgICAgPT4gJENoZWNrLAogICAgICAgICAgICB9LAogICAgICAgICAgICA7CiAgICB9CiAgICByZXR1cm4gJERhdGE7Cn0KCnN1YiBfVmVyc2lvbkNoZWNrIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgbXkgJERhdGEgPSB7fTsKCiAgICAjIHZlcnNpb24gY2hlY2sKICAgIG15ICRDaGVjayAgID0gJ0ZhaWxlZCc7CiAgICBteSAkTWVzc2FnZSA9ICdObyB2ZXJzaW9uIGZvdW5kISc7CiAgICAkU2VsZi0+e0RCT2JqZWN0fS0+UHJlcGFyZSggU1FMID0+ICJzaG93IGFsbCIgKTsKICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CiAgICAgICAgaWYgKCAkUm93WzBdID1+IC9ec2VydmVyX3ZlcnNpb24vaSApIHsKICAgICAgICAgICAgaWYgKCAkUm93WzFdID1+IC9eKFxkezEsM30pLiokLyApIHsKICAgICAgICAgICAgICAgIGlmICggJDEgPiA3ICkgewogICAgICAgICAgICAgICAgICAgICRDaGVjayAgID0gJ09LJzsKICAgICAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICIkUm93WzFdIjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICRDaGVjayAgID0gJ0ZhaWxlZCc7CiAgICAgICAgICAgICAgICAgICAgJE1lc3NhZ2UgPSAiSXRzIHZlcnNpb24gJFJvd1sxXSwgeW91IHNob3VsZCB1c2UgOC54IG9yIGhpZ25lci4iOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJENoZWNrICAgPSAnRmFpbGVkJzsKICAgICAgICAgICAgICAgICRNZXNzYWdlID0gIlVua293biB2ZXJzaW9uICRSb3dbMV0iOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgJERhdGEgPSB7CiAgICAgICAgS2V5ICAgICAgICAgPT4gJ3ZlcnNpb24nLAogICAgICAgIE5hbWUgICAgICAgID0+ICd2ZXJzaW9uJywKICAgICAgICBEZXNjcmlwdGlvbiA9PiAiQ2hlY2sgdmVyc2lvbi4iLAogICAgICAgIENvbW1lbnQgICAgID0+ICRNZXNzYWdlLAogICAgICAgIENoZWNrICAgICAgID0+ICRDaGVjaywKICAgICAgICB9LAogICAgICAgIHJldHVybiAkRGF0YTsKfQoKMTsK
IyAtLQojIEtlcm5lbC9TeXN0ZW0vU3VwcG9ydC9EYXRhYmFzZS9teXNxbC5wbSAtIGFsbCByZXF1aXJlZCBzeXN0ZW0gaW5mb3JtYXRpb25zCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDcgT1RSUyBHbWJILCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IG15c3FsLnBtLHYgMS4xMiAyMDA3LzExLzIyIDExOjUwOjA1IHNyIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLnR4dC4KIyAtLQoKcGFja2FnZSBLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6RGF0YWJhc2U6Om15c3FsOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIEtlcm5lbDo6U3lzdGVtOjpYTUw7Cgp1c2UgdmFycyBxdyhASVNBICRWRVJTSU9OKTsKJFZFUlNJT04gPSBxdygkUmV2aXNpb246IDEuMTIgJCkgWzFdOwoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGNoZWNrIG5lZWRlZCBvYmplY3RzCiAgICBmb3IgKHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QgREJPYmplY3QpKSB7CiAgICAgICAgJFNlbGYtPnskX30gPSAkUGFyYW17JF99IHx8IGRpZSAiR290IG5vICRfISI7CiAgICB9CgogICAgJFNlbGYtPntYTUxPYmplY3R9ID0gS2VybmVsOjpTeXN0ZW06OlhNTC0+bmV3KCVQYXJhbSk7CgogICAgcmV0dXJuICRTZWxmOwp9CgpzdWIgU3VwcG9ydENvbmZpZ0FycmF5R2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KfQoKc3ViIFN1cHBvcnRJbmZvR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoIHJlZiggJFBhcmFte01vZHVsZUlucHV0SGFzaH0gKSBuZSAnSEFTSCcgKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9CiAgICAgICAgICAgIC0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJNb2R1bGVJbnB1dEhhc2ggbXVzdCBiZSBhIGhhc2ggcmVmZXJlbmNlISIgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBhZGQgbmV3IGZ1bmN0aW9uIG5hbWUgaGVyZQogICAgbXkgQE1vZHVsZUxpc3QgPSAoCiAgICAgICAgJ19NYXhBbGxvd2VkUGFja2FnZUNoZWNrJywgJ19RdWVyeUNhY2hlU2l6ZUNoZWNrJywKICAgICAgICAnX1RhYmxlQ2hlY2snLCAgICAgICAgICAgICAnX1VURjhDbGllbnRDaGVjaycsCiAgICAgICAgJ19VVEY4RGF0YWJhc2VDaGVjaycsICAgICAgJ19VVEY4U3VwcG9ydENoZWNrJywKICAgICAgICAnX1VURjhUYWJsZUNoZWNrJywgICAgICAgICAnX1ZlcnNpb25DaGVjaycsCiAgICApOwoKICAgIG15IEBEYXRhQXJyYXk7CgogICAgRlVOQ1RJT05OQU1FOgogICAgZm9yIG15ICRGdW5jdGlvbk5hbWUgKEBNb2R1bGVMaXN0KSB7CgogICAgICAgICMgcnVuIGZ1bmN0aW9uIGFuZCBnZXQgY2hlY2sgZGF0YQogICAgICAgIG15ICRDaGVjayA9ICRTZWxmLT4kRnVuY3Rpb25OYW1lKCBUeXBlID0+ICRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9LT57VHlwZX0gfHwgJycsICk7CgogICAgICAgIG5leHQgRlVOQ1RJT05OQU1FIGlmICEkQ2hlY2s7CgogICAgICAgICMgYXR0YWNoIGNoZWNrIGRhdGEgaWYgdmFsaWQKICAgICAgICBwdXNoIEBEYXRhQXJyYXksICRDaGVjazsKICAgIH0KCiAgICByZXR1cm4gXEBEYXRhQXJyYXk7Cn0KCnN1YiBBZG1pbkNoZWNrc0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWRkIG5ldyBmdW5jdGlvbiBuYW1lIGhlcmUKICAgIG15IEBNb2R1bGVMaXN0ID0gKAogICAgICAgICdfTWF4QWxsb3dlZFBhY2thZ2VDaGVjaycsICdfUXVlcnlDYWNoZVNpemVDaGVjaycsCiAgICAgICAgJ19UYWJsZUNoZWNrJywgICAgICAgICAgICAgJ19VVEY4Q2xpZW50Q2hlY2snLAogICAgICAgICdfVVRGOERhdGFiYXNlQ2hlY2snLCAgICAgICdfVVRGOFN1cHBvcnRDaGVjaycsCiAgICAgICAgJ19VVEY4VGFibGVDaGVjaycsICAgICAgICAgJ19WZXJzaW9uQ2hlY2snLAogICAgKTsKCiAgICBteSBARGF0YUFycmF5OwoKICAgIEZVTkNUSU9OTkFNRToKICAgIGZvciBteSAkRnVuY3Rpb25OYW1lIChATW9kdWxlTGlzdCkgewoKICAgICAgICAjIHJ1biBmdW5jdGlvbiBhbmQgZ2V0IGNoZWNrIGRhdGEKICAgICAgICBteSAkQ2hlY2sgPSAkU2VsZi0+JEZ1bmN0aW9uTmFtZSgpOwoKICAgICAgICBuZXh0IEZVTkNUSU9OTkFNRSBpZiAhJENoZWNrOwoKICAgICAgICAjIGF0dGFjaCBjaGVjayBkYXRhIGlmIHZhbGlkCiAgICAgICAgcHVzaCBARGF0YUFycmF5LCAkQ2hlY2s7CiAgICB9CgogICAgcmV0dXJuIFxARGF0YUFycmF5Owp9CgpzdWIgX1ZlcnNpb25DaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgdmVyc2lvbiBjaGVjawogICAgbXkgJENoZWNrICAgPSAnRmFpbGVkJzsKICAgIG15ICRNZXNzYWdlID0gJ05vIHZlcnNpb24gZm91bmQhJzsKICAgICRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKCBTUUwgPT4gInNob3cgdmFyaWFibGVzIiApOwogICAgd2hpbGUgKCBteSBAUm93ID0gJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKCiAgICAgICAgIyBpZiByb3cgbm90IHZlcnNpb24gcm93LCBuZXh0LgogICAgICAgIGlmICggJFJvd1swXSAhfiAvXnZlcnNpb24kL2kgKSB7CiAgICAgICAgICAgIG5leHQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoICRSb3dbMV0gPX4gL14oXGR7MSwzfSlcLihcZHsxLDN9KS4qJC8gKSB7CiAgICAgICAgICAgIGlmICggJDEgPiA0IHx8ICggJDEgPiAzICYmICQyID4gMCApICkgewogICAgICAgICAgICAgICAgJENoZWNrICAgPSAnT0snOwogICAgICAgICAgICAgICAgJE1lc3NhZ2UgPSAiTXlTUUwgJFJvd1sxXSI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkQ2hlY2sgICA9ICdGYWlsZWQnOwogICAgICAgICAgICAgICAgJE1lc3NhZ2UgPSAiVmVyc2lvbiAkUm93WzFdLCB5b3Ugc2hvdWxkIHVzZSA0LjEgb3IgaGlnbmVyLiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICRDaGVjayAgID0gJ0ZhaWxlZCc7CiAgICAgICAgICAgICRNZXNzYWdlID0gIlVua293biB2ZXJzaW9uICRSb3dbMV0iOwogICAgICAgIH0KICAgIH0KICAgIG15ICREYXRhID0gewogICAgICAgIEtleSAgICAgICAgID0+ICd2ZXJzaW9uJywKICAgICAgICBOYW1lICAgICAgICA9PiAndmVyc2lvbicsCiAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIHZlcnNpb24uIiwKICAgICAgICBDb21tZW50ICAgICA9PiAkTWVzc2FnZSwKICAgICAgICBDaGVjayAgICAgICA9PiAkQ2hlY2ssCiAgICB9OwogICAgcmV0dXJuICREYXRhOwp9CgpzdWIgX1VURjhTdXBwb3J0Q2hlY2sgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIHV0Zi04IHN1cHBvcnQgY2hlY2sKICAgIGlmICggJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0RlZmF1bHRDaGFyc2V0JykgIX4gL3V0ZihcLTh8OCkvaSApIHsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgbXkgJERhdGEgPSB7CiAgICAgICAgS2V5ICAgICAgICAgPT4gJ3V0Zjggc3VwcG9ydCcsCiAgICAgICAgTmFtZSAgICAgICAgPT4gJ3V0Zjggc3VwcG9ydCcsCiAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIGRhdGFiYXNlIHV0Zjggc3VwcG9ydC4iLAogICAgICAgIENvbW1lbnQgICAgID0+ICdObyB2ZXJzaW9uIGZvdW5kIScsCiAgICAgICAgQ2hlY2sgICAgICAgPT4gJ0ZhaWxlZCcsCiAgICB9OwoKICAgICMgYXNrIHRoZSBkYXRhYmFzZQogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoIFNRTCA9PiAnc2hvdyB2YXJpYWJsZXMnICk7CgogICAgIyBmZXRjaCB0aGUgcmVzdWx0CiAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewoKICAgICAgICAjIG5leHQgcm93IGlmIG5vdCB2ZXJzaW9uCiAgICAgICAgbmV4dCBpZiAkUm93WzBdICF+IC9edmVyc2lvbiQvaTsKCiAgICAgICAgIyBmaW5kIHRoZSB2ZXJzaW9uIG51bWJlcgogICAgICAgIGlmICggJFJvd1sxXSA9fiAvXig0XC4oMXwyfDMpfDVcLnw2XC4pLyApIHsKICAgICAgICAgICAgJERhdGEtPntDb21tZW50fSA9ICJNeVNRTCAkUm93WzFdIjsKICAgICAgICAgICAgJERhdGEtPntDaGVja30gICA9ICdPSyc7CgogICAgICAgICAgICBuZXh0OwogICAgICAgIH0KCiAgICAgICAgJERhdGEtPntDb21tZW50fSA9ICJ1dGY4IG5vdCBzdXBwb3J0ZWQgKE15U1FMICRSb3dbMV0pIjsKICAgIH0KCiAgICByZXR1cm4gJERhdGE7Cn0KCnN1YiBfVVRGOENsaWVudENoZWNrIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CiAgICBteSAkRGF0YSA9IHt9OwoKICAgICMgdXRmLTggY2xpZW50IGNoZWNrCiAgICBpZiAoICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdEZWZhdWx0Q2hhcnNldCcpICF+IC91dGYoXC04fDgpL2kgKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICREYXRhID0gewogICAgICAgIEtleSAgICAgICAgID0+ICd1dGY4IGNsaWVudCBjb25uZWN0aW9uJywKICAgICAgICBOYW1lICAgICAgICA9PiAndXRmOCBjbGllbnQgY29ubmVjdGlvbicsCiAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIHRoZSB1dGY4IGNsaWVudCBjb25uZWN0aW9uLiIsCiAgICAgICAgQ29tbWVudCAgICAgPT4gJ0ZhaWxlZCcsCiAgICAgICAgQ2hlY2sgICAgICAgPT4gJ05vIGNoYXJhY3Rlcl9zZXRfY2xpZW50IGZvdW5kIScsCiAgICB9OwoKICAgICMgYXNrIHRoZSBkYXRhYmFzZQogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoIFNRTCA9PiAic2hvdyB2YXJpYWJsZXMiICk7CiAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewoKICAgICAgICAjbmV4dCBpZiByb3cgbm90IGNoYXJhY3Rlcl9zZXRfY2xpZW50CiAgICAgICAgbmV4dCBpZiAkUm93WzBdICF+IC9eY2hhcmFjdGVyX3NldF9jbGllbnQvaTsKCiAgICAgICAgaWYgKCAkUm93WzFdID1+IC91dGY4LyApIHsKICAgICAgICAgICAgJERhdGEtPntDaGVja30gICA9ICdPSyc7CiAgICAgICAgICAgICREYXRhLT57TWVzc2FnZX0gPSAiJFJvd1sxXSI7CgogICAgICAgICAgICBuZXh0OwogICAgICAgIH0KICAgICAgICAkRGF0YS0+e01lc3NhZ2V9ID0gImNoYXJhY3Rlcl9zZXRfY2xpZW50IGZvdW5kIGJ1dCBpdCdzIHNldCB0byAkUm93WzFdIChuZWVkIHRvIGJlIHV0ZjgpIjsKICAgIH0KCiAgICByZXR1cm4gJERhdGE7Cn0KCnN1YiBfVVRGOERhdGFiYXNlQ2hlY2sgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIHV0Zi04IGRhdGFiYXNlIGNoZWNrCiAgICBpZiAoICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdEZWZhdWx0Q2hhcnNldCcpICF+IC91dGYoXC04fDgpL2kgKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgbXkgJENoZWNrICAgPSAnRmFpbGVkJzsKICAgIG15ICRNZXNzYWdlID0gJ05vIGNoYXJhY3Rlcl9zZXRfZGF0YWJzZSBmb3VuZCEnOwogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoIFNRTCA9PiAic2hvdyB2YXJpYWJsZXMiICk7CiAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgIGlmICggJFJvd1swXSA9fiAvXmNoYXJhY3Rlcl9zZXRfZGF0YWJhc2UvaSApIHsKICAgICAgICAgICAgJE1lc3NhZ2UgPSAiY2hhcmFjdGVyX3NldF9kYXRhYmFzZSBmb3VuZCBidXQgaXQncyBzZXQgdG8gJFJvd1sxXSAobmVlZCB0byBiZSB1dGY4KSI7CiAgICAgICAgICAgIGlmICggJFJvd1sxXSA9fiAvdXRmOC8gKSB7CiAgICAgICAgICAgICAgICAkQ2hlY2sgICA9ICdPSyc7CiAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICIkUm93WzFdIjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBteSAkRGF0YSA9IHsKICAgICAgICBLZXkgICAgICAgICA9PiAndXRmOCBkYXRhYmFzZSBjaGFyYWN0ZXInLAogICAgICAgIE5hbWUgICAgICAgID0+ICd1dGY4IGRhdGFiYXNlIGNoYXJhY3RlcicsCiAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIHRoZSB1dGY4IGRhdGFiYXNlIGNoYXJhY3Rlci4iLAogICAgICAgIENvbW1lbnQgICAgID0+ICRNZXNzYWdlLAogICAgICAgIENoZWNrICAgICAgID0+ICRDaGVjaywKICAgICAgICB9LAogICAgICAgIHJldHVybiAkRGF0YTsKfQoKc3ViIF9VVEY4VGFibGVDaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwogICAgbXkgJERhdGEgPSB7fTsKCiAgICAjIHV0Zi04IHRhYmxlIGNoZWNrCiAgICBpZiAoICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdEZWZhdWx0Q2hhcnNldCcpID1+IC91dGYoXC04fDgpL2kgKSB7CiAgICAgICAgbXkgJENoZWNrICAgID0gJ0ZhaWxlZCc7CiAgICAgICAgbXkgJE1lc3NhZ2UgID0gJyc7CiAgICAgICAgbXkgJE1lc3NhZ2UyID0gJyc7CiAgICAgICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoIFNRTCA9PiAic2hvdyB0YWJsZSBzdGF0dXMiICk7CiAgICAgICAgd2hpbGUgKCBteSBAUm93ID0gJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICAgICAgaWYgKCAkUm93WzE0XSAhfiAvXnV0ZjgvaSApIHsKICAgICAgICAgICAgICAgICRNZXNzYWdlIC49ICIkUm93WzBdWyRSb3dbMTRdXSwiOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgJE1lc3NhZ2UyID0gJFJvd1sxNF07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCRNZXNzYWdlKSB7CiAgICAgICAgICAgICRDaGVjayAgID0gJ0ZhaWxlZCc7CiAgICAgICAgICAgICRNZXNzYWdlID0gIkludmFsaWQgY29sbGF0aW9uIGZvcjogJE1lc3NhZ2UiOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgJENoZWNrICAgPSAnT0snOwogICAgICAgICAgICAkTWVzc2FnZSA9ICRNZXNzYWdlMjsKICAgICAgICB9CiAgICAgICAgJERhdGEgPSB7CiAgICAgICAgICAgIEtleSAgICAgICAgID0+ICd1dGY4IHRhYmxlIGNvbGxhdGlvbicsCiAgICAgICAgICAgIE5hbWUgICAgICAgID0+ICd1dGY4IHRhYmxlIGNvbGxhdGlvbicsCiAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICJDaGVjayB0aGUgdXRmOCB0YWJsZSBjb2xsYXRpb24uIiwKICAgICAgICAgICAgQ29tbWVudCAgICAgPT4gJE1lc3NhZ2UsCiAgICAgICAgICAgIENoZWNrICAgICAgID0+ICRDaGVjaywKICAgICAgICAgICAgfSwKICAgICAgICAgICAgcmV0dXJuICREYXRhOwogICAgfQogICAgcmV0dXJuOwp9CgpzdWIgX01heEFsbG93ZWRQYWNrYWdlQ2hlY2sgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKICAgIG15ICREYXRhID0ge307CgogICAgIyBtYXhfYWxsb3dlZF9wYWNrZXQgY2hlY2sKICAgIG15ICRDaGVjayAgID0gJ0ZhaWxlZCc7CiAgICBteSAkTWVzc2FnZSA9ICdObyBtYXhfYWxsb3dlZF9wYWNrZXQgZm91bmQhJzsKICAgICRTZWxmLT57REJPYmplY3R9LT5QcmVwYXJlKCBTUUwgPT4gInNob3cgdmFyaWFibGVzIiApOwogICAgd2hpbGUgKCBteSBAUm93ID0gJFNlbGYtPntEQk9iamVjdH0tPkZldGNocm93QXJyYXkoKSApIHsKICAgICAgICBpZiAoICRSb3dbMF0gPX4gL15tYXhfYWxsb3dlZF9wYWNrZXQvaSApIHsKICAgICAgICAgICAgaWYgKCAkUm93WzFdIDwgMTAyNCAqIDEwMjQgKiA3ICkgewogICAgICAgICAgICAgICAgJFJvd1sxXSAgPSBpbnQoICRSb3dbMV0gLyAxMDI0ICk7CiAgICAgICAgICAgICAgICAkQ2hlY2sgICA9ICdGYWlsZWQnOwogICAgICAgICAgICAgICAgJE1lc3NhZ2UgPSAibWF4X2FsbG93ZWRfcGFja2V0IHNob3VsZCBiZSBoaWdoZXIgdGhlIDcwMDAgS0IgKGl0cyAkUm93WzFdIEtCKSI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkUm93WzFdICA9IGludCggJFJvd1sxXSAvIDEwMjQgKTsKICAgICAgICAgICAgICAgICRDaGVjayAgID0gJ09LJzsKICAgICAgICAgICAgICAgICRNZXNzYWdlID0gIiRSb3dbMV0gS0IiOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgJERhdGEgPSB7CiAgICAgICAgS2V5ICAgICAgICAgPT4gJ21heF9hbGxvd2VkX3BhY2tldCcsCiAgICAgICAgTmFtZSAgICAgICAgPT4gJ21heF9hbGxvd2VkX3BhY2tldCcsCiAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIG1heF9hbGxvd2VkX3BhY2tldCBzZXR0aW5nLiIsCiAgICAgICAgQ29tbWVudCAgICAgPT4gJE1lc3NhZ2UsCiAgICAgICAgQ2hlY2sgICAgICAgPT4gJENoZWNrLAogICAgICAgIH0sCiAgICAgICAgcmV0dXJuICREYXRhOwp9CgpzdWIgX1F1ZXJ5Q2FjaGVTaXplQ2hlY2sgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKICAgIG15ICREYXRhID0ge307CgogICAgIyBxdWVyeV9jYWNoZV9zaXplIGNoZWNrCiAgICBteSAkQ2hlY2sgICA9ICdGYWlsZWQnOwogICAgbXkgJE1lc3NhZ2UgPSAnTm8gcXVlcnlfY2FjaGVfc2l6ZSBmb3VuZCEnOwogICAgJFNlbGYtPntEQk9iamVjdH0tPlByZXBhcmUoIFNRTCA9PiAic2hvdyB2YXJpYWJsZXMiICk7CiAgICB3aGlsZSAoIG15IEBSb3cgPSAkU2VsZi0+e0RCT2JqZWN0fS0+RmV0Y2hyb3dBcnJheSgpICkgewogICAgICAgIGlmICggJFJvd1swXSA9fiAvXnF1ZXJ5X2NhY2hlX3NpemUvaSApIHsKICAgICAgICAgICAgaWYgKCAhJFJvd1sxXSApIHsKICAgICAgICAgICAgICAgICRDaGVjayA9ICdGYWlsZWQnOwogICAgICAgICAgICAgICAgJE1lc3NhZ2UKICAgICAgICAgICAgICAgICAgICA9ICJxdWVyeV9jYWNoZV9zaXplIHNob3VsZCBiZSB1c2VkLCB5b3Ugd2lsbCBnZXQgaW1wcm92ZW1lbnRzIGJldHdlZW4gMTAgYW5kIDMwICUgb2Ygc3BlZWQhIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNpZiAoICRSb3dbMV0gPCAxMDI0ICogMTAyNCAqIDggKSB7CiAgICAgICAgICAgICAgICAkUm93WzFdICA9IGludCggJFJvd1sxXSAvIDEwMjQgKTsKICAgICAgICAgICAgICAgICRDaGVjayAgID0gJ0NyaXRpY2FsJzsKICAgICAgICAgICAgICAgICRNZXNzYWdlID0gInF1ZXJ5X2NhY2hlX3NpemUgc2hvdWxkIGJlIGhpZ2hlciB0aGUgODAwMCBLQiAoaXRzICRSb3dbMV0gS0IpIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICRSb3dbMV0gID0gaW50KCAkUm93WzFdIC8gMTAyNCApOwogICAgICAgICAgICAgICAgJENoZWNrICAgPSAnT0snOwogICAgICAgICAgICAgICAgJE1lc3NhZ2UgPSAiJFJvd1sxXSBLQiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAkRGF0YSA9IHsKICAgICAgICBLZXkgICAgICAgICA9PiAncXVlcnlfY2FjaGVfc2l6ZScsCiAgICAgICAgTmFtZSAgICAgICAgPT4gJ3F1ZXJ5X2NhY2hlX3NpemUnLAogICAgICAgIERlc2NyaXB0aW9uID0+ICJDaGVjayBxdWVyeV9jYWNoZV9zaXplIHNldHRpbmcuIiwKICAgICAgICBDb21tZW50ICAgICA9PiAkTWVzc2FnZSwKICAgICAgICBDaGVjayAgICAgICA9PiAkQ2hlY2ssCiAgICAgICAgfSwKICAgICAgICByZXR1cm4gJERhdGE7Cn0KCnN1YiBfVGFibGVDaGVjayB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwogICAgbXkgJERhdGEgPSB7fTsKCiAgICAjIHRhYmxlIGNoZWNrCiAgICBteSAkRmlsZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAiL3NjcmlwdHMvZGF0YWJhc2Uvb3Rycy1zY2hlbWEueG1sIjsKICAgIGlmICggLWYgJEZpbGUgKSB7CiAgICAgICAgbXkgJENvdW50ICAgPSAwOwogICAgICAgIG15ICRDaGVjayAgID0gJ0ZhaWxlZCc7CiAgICAgICAgbXkgJE1lc3NhZ2UgPSAnJzsKICAgICAgICBteSAkQ29udGVudCA9ICcnOwogICAgICAgIG15ICRJbjsKICAgICAgICBpZiAoIG9wZW4oICRJbiwgJzwnLCAiJEZpbGUiICkgKSB7CiAgICAgICAgICAgIHdoaWxlICg8JEluPikgewogICAgICAgICAgICAgICAgJENvbnRlbnQgLj0gJF87CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2xvc2UoJEluKTsKICAgICAgICAgICAgbXkgQFhNTEhhc2ggPSAkU2VsZi0+e1hNTE9iamVjdH0tPlhNTFBhcnNlMlhNTEhhc2goIFN0cmluZyA9PiAkQ29udGVudCApOwoKICAgICAgICAgICAgZm9yIG15ICRUYWJsZSAoIEB7ICRYTUxIYXNoWzFdLT57ZGF0YWJhc2V9LT5bMV0tPntUYWJsZX0gfSApIHsKICAgICAgICAgICAgICAgIGlmICgkVGFibGUpIHsKICAgICAgICAgICAgICAgICAgICAkQ291bnQrKzsKICAgICAgICAgICAgICAgICAgICBpZiAoICRTZWxmLT57REJPYmplY3R9CiAgICAgICAgICAgICAgICAgICAgICAgIC0+UHJlcGFyZSggU1FMID0+ICJzZWxlY3QgKiBmcm9tICRUYWJsZS0+e05hbWV9IiwgTGltaXQgPT4gMSApICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlICggbXkgQFJvdyA9ICRTZWxmLT57REJPYmplY3R9LT5GZXRjaHJvd0FycmF5KCkgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICRNZXNzYWdlIC49ICIkVGFibGUtPntOYW1lfSwgIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCRNZXNzYWdlKSB7CiAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICJUYWJsZSBkb3NuJ3QgZXhpc3RzOiAkTWVzc2FnZSI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAkQ2hlY2sgICA9ICdPSyc7CiAgICAgICAgICAgICAgICAkTWVzc2FnZSA9ICIkQ291bnQgVGFibGVzIjsKICAgICAgICAgICAgfQogICAgICAgICAgICAkRGF0YSA9IHsKICAgICAgICAgICAgICAgIEtleSAgICAgICAgID0+ICdUYWJsZScsCiAgICAgICAgICAgICAgICBOYW1lICAgICAgICA9PiAnVGFibGUnLAogICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIGV4aXN0aW5nIGZyYW1ld29yayB0YWJsZXMuIiwKICAgICAgICAgICAgICAgIENvbW1lbnQgICAgID0+ICRNZXNzYWdlLAogICAgICAgICAgICAgICAgQ2hlY2sgICAgICAgPT4gJENoZWNrLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIDsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICREYXRhID0gewogICAgICAgICAgICAgICAgS2V5ICAgICAgICAgPT4gJ1RhYmxlJywKICAgICAgICAgICAgICAgIE5hbWUgICAgICAgID0+ICdUYWJsZScsCiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAiQ2hlY2sgZXhpc3RpbmcgZnJhbWV3b3JrIHRhYmxlcy4iLAogICAgICAgICAgICAgICAgQ29tbWVudCAgICAgPT4gIkNhbid0IG9wZW4gZmlsZSAkRmlsZTogJCEiLAogICAgICAgICAgICAgICAgQ2hlY2sgICAgICAgPT4gJENoZWNrLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgIDsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgICAkRGF0YSA9IHsKICAgICAgICAgICAgS2V5ICAgICAgICAgPT4gJ1RhYmxlJywKICAgICAgICAgICAgTmFtZSAgICAgICAgPT4gJ1RhYmxlJywKICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gIkNoZWNrIGV4aXN0aW5nIGZyYW1ld29yayB0YWJsZXMuIiwKICAgICAgICAgICAgQ29tbWVudCAgICAgPT4gIkNhbid0IGZpbmQgZmlsZSAkRmlsZSEiLAogICAgICAgICAgICBDaGVjayAgICAgICA9PiAnRmFpbGVkJywKICAgICAgICAgICAgfSwKICAgICAgICAgICAgOwogICAgfQogICAgcmV0dXJuICREYXRhOwp9CgoxOwo=
IyAtLQojIEtlcm5lbC9TeXN0ZW0vU3VwcG9ydC9XZWJzZXJ2ZXIucG0gLSBhbGwgcmVxdWlyZWQgc3lzdGVtIGluZm9ybWF0aW9ucwojIENvcHlyaWdodCAoQykgMjAwMS0yMDA3IE9UUlMgR21iSCwgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBXZWJzZXJ2ZXIucG0sdiAxLjUgMjAwNy8xMS8yMiAxMzowNToxMCBzciBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpTeXN0ZW06OlN1cHBvcnQ6OldlYnNlcnZlcjsKCnVzZSBzdHJpY3Q7CnVzZSB3YXJuaW5nczsKCnVzZSB2YXJzIHF3KEBJU0EgJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS41ICQpIFsxXTsKCj1oZWFkMSBOQU1FCgpLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6V2Vic2VydmVyIC0gZ2xvYmFsIHN5c3RlbSBpbmZvcm1hdGlvbnMKCj1oZWFkMSBTWU5PUFNJUwoKQWxsIHJlcXVpcmVkIHN5c3RlbSBpbmZvcm1hdGlvbnMgdG8gYSBydW5uaW5nIE9UUlMgaG9zdC4KCj1oZWFkMSBQVUJMSUMgSU5URVJGQUNFCgo9b3ZlciA0Cgo9Y3V0Cgo9aXRlbSBuZXcoKQoKY3JlYXRlIFdlYnNlcnZlciBpbmZvIG9iamVjdAoKICAgIHVzZSBLZXJuZWw6OkNvbmZpZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6TG9nOwogICAgbXkgJENvbmZpZ09iamVjdCA9IEtlcm5lbDo6Q29uZmlnLT5uZXcoKTsKICAgIG15ICRMb2dPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6TG9nLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICApOwoKICAgICRTeXN0ZW1JbmZvT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OlN1cHBvcnQ6OldlYnNlcnZlci0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCA9PiAkTG9nT2JqZWN0LAogICAgKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgb2JqZWN0cwogICAgZm9yIChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0IE1haW5PYmplY3QpKSB7CiAgICAgICAgJFNlbGYtPnskX30gPSAkUGFyYW17JF99IHx8IGRpZSAiR290IG5vICRfISI7CiAgICB9CgogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBTdXBwb3J0Q29uZmlnQXJyYXlHZXQoKQoKcmV0dXJuIGFuIGFycmF5IHJlZmVyZW5jZSB3aXRoIHJlcXVpcmVkIGNvbmZpZyBpbmZvcm1hdGlvbi4KCiAgICAkQXJyYXlSZWYgPSAkU3VwcG9ydC0+U3VwcG9ydENvbmZpZ0FycmF5R2V0KCk7CgogICAgbXkgJENvbmZpZ0FycmF5ID0gWwogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0+ICdUaWNrZXREdW1wJywKICAgICAgICAgICAgTmFtZSA9PiAnRHVtcCBUaWNrZXRzJywKICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSB0ZWxsIG1lIGhvdyBtYW55IGxhdGVzdCBUaWNrZXRzIHdlIHNodXQgZHVtcD8nLAogICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAgICAgICAgICAgICBUeXBlID0+ICdTZWxlY3QnLAogICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgQWxsID0+ICdBbGwnLAogICAgICAgICAgICAgICAgICAgIDAgPT4gJzAnLAogICAgICAgICAgICAgICAgICAgIDEwID0+ICdMYXN0IDEwJywKICAgICAgICAgICAgICAgICAgICAxMDAgPT4gJ0xhc3QgMTAwJywKICAgICAgICAgICAgICAgICAgICAxMDAwID0+ICdMYXN0IDEwMDAnLAogICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgfSwKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICAgS2V5ID0+ICdBcGFjaGVIb21lJywKICAgICAgICAgICAgTmFtZSA9PiAnQXBhY2hlIEhvbWUgRGlyZWN0b3J5JywKICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSB0ZWxsIG1lIHRoZSBwYXRoIHRvIHRoZSBBcGFjaGUgaG9tZSBkaXJlY3RvcnkgKC9ldGMvYXBhY2hlMiknLAogICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAgICAgICAgICAgICBUeXBlID0+ICdUZXh0JywKICAgICAgICAgICAgICAgIFNpemUgPT4gNDAsCiAgICAgICAgICAgIH0sCiAgICAgICAgfSwKICAgIF07Cgo9Y3V0CgpzdWIgU3VwcG9ydENvbmZpZ0FycmF5R2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIEdldCBpbmZvcm1hdGlvbiBhYm91dCBhbGwgV2Vic2VydmVycwogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwoKICAgICMgY3JlYXRlIGNvbmZpZyBhcnJheQogICAgbXkgJENvbmZpZ0FycmF5ID0gW107CgogICAgIyAgICBteSAkQ29uZmlnQXJyYXkgPSBbCiAgICAjICAgICAgICB7CiAgICAjICAgICAgICAgICAgS2V5ID0+ICdBcGFjaGVIb21lJywKICAgICMgICAgICAgICAgICBOYW1lID0+ICdBcGFjaGUgSG9tZSBEaXJlY3RvcnknLAogICAgIyAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgdGVsbCBtZSB0aGUgcGF0aCB0byB0aGUgQXBhY2hlIGhvbWUgZGlyZWN0b3J5ICgvZXRjL2FwYWNoZTIpJywKICAgICMgICAgICAgICAgICBJbnB1dCA9PiB7CiAgICAjICAgICAgICAgICAgICAgIFR5cGUgPT4gJ1RleHQnLAogICAgIyAgICAgICAgICAgICAgICBTaXplID0+IDQwLAogICAgIyAgICAgICAgICAgIH0sCiAgICAjICAgICAgICB9LAogICAgIyAgICBdOwoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgICMgR2V0IGluZm9ybWF0aW9uIGFib3V0IHVzZWQgV2Vic2VydmVyCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCgogICAgIyB0cnkgdG8gZmluZCBvdXQgd2hpY2ggV2Vic2VydmVyIGlzIGNvbmZpZ3VyZWQKICAgIG15ICRXZWJzZXJ2ZXJUeXBlID0gJyc7CiAgICBpZiAoICRFTlZ7U0VSVkVSX1NPRlRXQVJFfSA9fiAvXi4qQXBhY2hlLiokL2kgKSB7CiAgICAgICAgJFdlYnNlcnZlclR5cGUgPSAnQXBhY2hlLnBtJzsKICAgIH0KICAgIGVsc2UgewogICAgICAgICRXZWJzZXJ2ZXJUeXBlID0gJ0lJUy5wbSc7CiAgICB9CgogICAgIyB0cnkgdG8gZ2V0IGF2YWlsaWJsZSBtb2R1bGVzIGFuZCB0aGUgZGlyZWN0b3J5IG5hbWUKICAgIG15ICREaXJOYW1lID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICIvS2VybmVsL1N5c3RlbS9TdXBwb3J0L1dlYnNlcnZlciI7CgogICAgIyByZWFkIGFsbCBhdmFpbGlibGUgbW9kdWxlcyBpbiBATGlzdAogICAgbXkgQExpc3QgPSBnbG9iKCAkRGlyTmFtZSAuICIvKi5wbSIgKTsKICAgIGZvciBteSAkRmlsZSAoQExpc3QpIHsKCiAgICAgICAgIyByZW1vdmUgLnBtCiAgICAgICAgJEZpbGUgPX4gcy9eLipcLyguKz8pXC5wbSQvJDEvOwogICAgICAgIGlmICggJFdlYnNlcnZlclR5cGUgZXEgJEZpbGUgKSB7CiAgICAgICAgICAgIG15ICRHZW5lcmljTW9kdWxlID0gIktlcm5lbDo6U3lzdGVtOjpTdXBwb3J0OjpXZWJzZXJ2ZXI6OiRGaWxlIjsKCiAgICAgICAgICAgICMgbG9hZCBtb2R1bGUgJEdlbmVyaWNNb2R1bGUgYW5kIGNoZWNrIGlmIGxvYWRhYmxlCiAgICAgICAgICAgIGlmICggJFNlbGYtPntNYWluT2JqZWN0fS0+UmVxdWlyZSgkR2VuZXJpY01vZHVsZSkgKSB7CgogICAgICAgICAgICAgICAgIyBjcmVhdGUgbmV3IG9iamVjdAogICAgICAgICAgICAgICAgbXkgJFN1cHBvcnRPYmplY3QgPSAkR2VuZXJpY01vZHVsZS0+bmV3KCAleyRTZWxmfSApOwogICAgICAgICAgICAgICAgaWYgKCRTdXBwb3J0T2JqZWN0KSB7CiAgICAgICAgICAgICAgICAgICAgbXkgJEFycmF5UmVmID0gJFN1cHBvcnRPYmplY3QtPlN1cHBvcnRDb25maWdBcnJheUdldCgpOwogICAgICAgICAgICAgICAgICAgIGlmICggJEFycmF5UmVmICYmIHJlZigkQXJyYXlSZWYpIGVxICdBUlJBWScgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2goIEB7JENvbmZpZ0FycmF5fSwgQHskQXJyYXlSZWZ9ICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgICMgcmV0dXJuIGNvbmZpZyBhcnJheQogICAgcmV0dXJuICRDb25maWdBcnJheTsKfQoKPWl0ZW0gU3VwcG9ydEluZm9HZXQoKQoKcmV0dXJucyBhIGFycmF5IHJlZmVyZW5jZSB3aXRoIHN1cHBvcnQgaW5mb3JtYXRpb24uCgokV2Vic2VydmVyQXJyYXkgPT4gWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPT4gJ1BsYXR0Zm9ybScsCiAgICAgICAgICAgICAgICBOYW1lID0+ICdQbGF0dGZvcm0nLAogICAgICAgICAgICAgICAgQ29tbWVudCA9PiAnTGludXgnLAogICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSBhZGQgbW9yZSBtZW1vcnkuJywKICAgICAgICAgICAgICAgIENoZWNrID0+ICdPSycsCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9PiAnVmVyc2lvbicsCiAgICAgICAgICAgICAgICBOYW1lID0+ICdWZXJzaW9uJywKICAgICAgICAgICAgICAgIENvbW1lbnQgPT4gJ29wZW5TVVNFIDEwLjInLAogICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJ1BsZWFzZSBhZGQgbW9yZSBtZW1vcnkuJywKICAgICAgICAgICAgICAgIENoZWNrID0+ICdPSycsCiAgICAgICAgICAgIH0sCiAgICAgICAgXTsKCj1jdXQKCnN1YiBTdXBwb3J0SW5mb0dldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICREYXRhQXJyYXkgPSBbXTsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIChxdyhNb2R1bGVJbnB1dEhhc2gpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRffSApIHsKICAgICAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coIFByaW9yaXR5ID0+ICdlcnJvcicsIE1lc3NhZ2UgPT4gIk5lZWQgJF8hIiApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQogICAgaWYgKCByZWYoICRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9ICkgbmUgJ0hBU0gnICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fQogICAgICAgICAgICAtPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTW9kdWxlSW5wdXRIYXNoIG11c3QgYmUgYSBoYXNoIHJlZmVyZW5jZSEiICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgICMgR2V0IGluZm9ybWF0aW9uIGFib3V0IGFsbCBXZWJzZXJ2ZXJzCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCgogICAgIyBwbGVhc2UgYWRkIGZvciBlYWNoIG5ldyBjaGVjayBhIHBhcnQgbGlrZSB0aGlzCiAgICAjICAgIG15ICRPbmVDaGVjayA9ICRTZWxmLT5DaGVjaygKICAgICMgICAgICAgIFR5cGUgPT4gJFBhcmFte01vZHVsZUlucHV0SGFzaH0tPntUeXBlfSB8fCAnJywKICAgICMgICAgKTsKICAgICMgICAgcHVzaCAoQHskRGF0YUFycmF5fSwgJE9uZUNoZWNrKTsKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIEdldCBpbmZvcm1hdGlvbiBhYm91dCB1c2VkIFdlYnNlcnZlcgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwoKICAgICMgdHJ5IHRvIGZpbmQgb3V0IHdoaWNoIFdlYnNlcnZlciBpcyBjb25maWd1cmVkCiAgICBteSAkV2Vic2VydmVyVHlwZSA9ICcnOwogICAgaWYgKCAkRU5We1NFUlZFUl9TT0ZUV0FSRX0gPX4gL14uKkFwYWNoZS4qJC9pICkgewogICAgICAgICRXZWJzZXJ2ZXJUeXBlID0gJ0FwYWNoZSc7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICAkV2Vic2VydmVyVHlwZSA9ICdJSVMnOwogICAgfQoKICAgICMgdHJ5IHRvIGdldCBhdmFpbGlibGUgbW9kdWxlcyBhbmQgdGhlIGRpcmVjdG9yeSBuYW1lCiAgICBteSAkRGlyTmFtZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAiL0tlcm5lbC9TeXN0ZW0vU3VwcG9ydC9XZWJzZXJ2ZXIiOwoKICAgICMgcmVhZCBhbGwgYXZhaWxpYmxlIG1vZHVsZXMgaW4gQExpc3QKICAgIG15IEBMaXN0ID0gZ2xvYiggJERpck5hbWUgLiAiLyoucG0iICk7CiAgICBmb3IgbXkgJEZpbGUgKEBMaXN0KSB7CgogICAgICAgICMgcmVtb3ZlIC5wbQogICAgICAgICRGaWxlID1+IHMvXi4qXC8oLis/KVwucG0kLyQxLzsKICAgICAgICBpZiAoICRXZWJzZXJ2ZXJUeXBlIGVxICRGaWxlICkgewogICAgICAgICAgICBteSAkR2VuZXJpY01vZHVsZSA9ICJLZXJuZWw6OlN5c3RlbTo6U3VwcG9ydDo6V2Vic2VydmVyOjokRmlsZSI7CgogICAgICAgICAgICAjIGxvYWQgbW9kdWxlICRHZW5lcmljTW9kdWxlIGFuZCBjaGVjayBpZiBsb2FkYWJsZQogICAgICAgICAgICBpZiAoICRTZWxmLT57TWFpbk9iamVjdH0tPlJlcXVpcmUoJEdlbmVyaWNNb2R1bGUpICkgewoKICAgICAgICAgICAgICAgICMgY3JlYXRlIG5ldyBvYmplY3QKICAgICAgICAgICAgICAgIG15ICRTdXBwb3J0T2JqZWN0ID0gJEdlbmVyaWNNb2R1bGUtPm5ldyggJXskU2VsZn0gKTsKICAgICAgICAgICAgICAgIGlmICgkU3VwcG9ydE9iamVjdCkgewogICAgICAgICAgICAgICAgICAgIG15ICRBcnJheVJlZiA9ICRTdXBwb3J0T2JqZWN0LT5TdXBwb3J0SW5mb0dldCgKICAgICAgICAgICAgICAgICAgICAgICAgTW9kdWxlSW5wdXRIYXNoID0+ICRQYXJhbXtNb2R1bGVJbnB1dEhhc2h9LCApOwogICAgICAgICAgICAgICAgICAgIGlmICggJEFycmF5UmVmICYmIHJlZigkQXJyYXlSZWYpIGVxICdBUlJBWScgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHB1c2goIEB7JERhdGFBcnJheX0sIEB7JEFycmF5UmVmfSApOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gJERhdGFBcnJheTsKfQoKPWl0ZW0gQWRtaW5DaGVja3NHZXQoKQoKcmV0dXJucyBhIGFycmF5IHJlZmVyZW5jZSB3aXRoIEFkbWluQ2hlY2tzIGluZm9ybWF0aW9uLgoKJFdlYnNlcnZlckFycmF5ID0+IFsKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgS2V5ID0+ICdQbGF0dGZvcm0nLAogICAgICAgICAgICAgICAgTmFtZSA9PiAnUGxhdHRmb3JtJywKICAgICAgICAgICAgICAgIENvbW1lbnQgPT4gJ0xpbnV4JywKICAgICAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgYWRkIG1vcmUgbWVtb3J5LicsCiAgICAgICAgICAgICAgICBDaGVjayA9PiAnT0snLAogICAgICAgICAgICB9LAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBLZXkgPT4gJ1ZlcnNpb24nLAogICAgICAgICAgICAgICAgTmFtZSA9PiAnVmVyc2lvbicsCiAgICAgICAgICAgICAgICBDb21tZW50ID0+ICdvcGVuU1VTRSAxMC4yJywKICAgICAgICAgICAgICAgIERlc2NyaXB0aW9uID0+ICdQbGVhc2UgYWRkIG1vcmUgbWVtb3J5LicsCiAgICAgICAgICAgICAgICBDaGVjayA9PiAnT0snLAogICAgICAgICAgICB9LAogICAgICAgIF07Cgo9Y3V0CgpzdWIgQWRtaW5DaGVja3NHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkRGF0YUFycmF5ID0gW107CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciAocXcoKSkgewogICAgICAgIGlmICggISRQYXJhbXskX30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnZXJyb3InLCBNZXNzYWdlID0+ICJOZWVkICRfISIgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIEdldCBpbmZvcm1hdGlvbiBhYm91dCBhbGwgV2Vic2VydmVycwogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwoKICAgICMgcGxlYXNlIGFkZCBmb3IgZWFjaCBuZXcgY2hlY2sgYSBwYXJ0IGxpa2UgdGhpcwogICAgIyAgICBteSAkT25lQ2hlY2sgPSAkU2VsZi0+Q2hlY2soKTsKICAgICMgICAgcHVzaCAoQHskRGF0YUFycmF5fSwgJE9uZUNoZWNrKTsKCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIEdldCBpbmZvcm1hdGlvbiBhYm91dCB1c2VkIFdlYnNlcnZlcgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwoKICAgICMgdHJ5IHRvIGZpbmQgb3V0IHdoaWNoIFdlYnNlcnZlciBpcyBjb25maWd1cmVkCiAgICBteSAkV2Vic2VydmVyVHlwZSA9ICcnOwogICAgaWYgKCAkRU5We1NFUlZFUl9TT0ZUV0FSRX0gPX4gL14uKkFwYWNoZS4qJC9pICkgewogICAgICAgICRXZWJzZXJ2ZXJUeXBlID0gJ0FwYWNoZS5wbSc7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICAkV2Vic2VydmVyVHlwZSA9ICdJSVMucG0nOwogICAgfQoKICAgICMgdHJ5IHRvIGdldCBhdmFpbGlibGUgbW9kdWxlcyBhbmQgdGhlIGRpcmVjdG9yeSBuYW1lCiAgICBteSAkRGlyTmFtZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAiL0tlcm5lbC9TeXN0ZW0vU3VwcG9ydC9XZWJzZXJ2ZXIiOwoKICAgICMgcmVhZCBhbGwgYXZhaWxpYmxlIG1vZHVsZXMgaW4gQExpc3QKICAgIG15IEBMaXN0ID0gZ2xvYiggJERpck5hbWUgLiAiLyoucG0iICk7CiAgICBmb3IgbXkgJEZpbGUgKEBMaXN0KSB7CgogICAgICAgICMgcmVtb3ZlIC5wbQogICAgICAgICRGaWxlID1+IHMvXi4qXC8oLis/KVwucG0kLyQxLzsKICAgICAgICBpZiAoICRXZWJzZXJ2ZXJUeXBlID1+IC9eJEZpbGUvaSApIHsKICAgICAgICAgICAgbXkgJEdlbmVyaWNNb2R1bGUgPSAiS2VybmVsOjpTeXN0ZW06OlN1cHBvcnQ6OldlYnNlcnZlcjo6JEZpbGUiOwoKICAgICAgICAgICAgIyBsb2FkIG1vZHVsZSAkR2VuZXJpY01vZHVsZSBhbmQgY2hlY2sgaWYgbG9hZGFibGUKICAgICAgICAgICAgaWYgKCAkU2VsZi0+e01haW5PYmplY3R9LT5SZXF1aXJlKCRHZW5lcmljTW9kdWxlKSApIHsKCiAgICAgICAgICAgICAgICAjIGNyZWF0ZSBuZXcgb2JqZWN0CiAgICAgICAgICAgICAgICBteSAkU3VwcG9ydE9iamVjdCA9ICRHZW5lcmljTW9kdWxlLT5uZXcoICV7JFNlbGZ9ICk7CiAgICAgICAgICAgICAgICBpZiAoJFN1cHBvcnRPYmplY3QpIHsKICAgICAgICAgICAgICAgICAgICBteSAkQXJyYXlSZWYgPSAkU3VwcG9ydE9iamVjdC0+QWRtaW5DaGVja3NHZXQoKTsKICAgICAgICAgICAgICAgICAgICBpZiAoICRBcnJheVJlZiAmJiByZWYoJEFycmF5UmVmKSBlcSAnQVJSQVknICkgewogICAgICAgICAgICAgICAgICAgICAgICBwdXNoKCBAeyREYXRhQXJyYXl9LCBAeyRBcnJheVJlZn0gKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgfQoKICAgIHJldHVybiAkRGF0YUFycmF5Owp9Cgo9aXRlbSBfQ2hlY2soKQoKcmV0dXJucyBhIGhhc2ggcmVmZXJlbmNlIHdpdGggQ2hlY2sgaW5mb3JtYXRpb24uCgokQ2hlY2tIYXNoID0+CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEtleSA9PiAnUGxhdHRmb3JtJywKICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1BsYXR0Zm9ybScsCiAgICAgICAgICAgICAgICBDb21tZW50ID0+ICdMaW51eCcsCiAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAnUGxlYXNlIGFkZCBtb3JlIG1lbW9yeS4nLAogICAgICAgICAgICAgICAgQ2hlY2sgPT4gJ09LJywKICAgICAgICAgICAgfTsKCiMgY2hlY2sgaWYgY29uZmlnIHZhbHVlIGF2YWlsaWJsZQppZiAoJFBhcmFte1R5cGV9KSB7CiAgICBwcmludCBTVERFUlIgIlRZUEU6ICIgLiAkUGFyYW17VHlwZX07Cn0KCj1jdXQKCnN1YiBfQ2hlY2sgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkUmV0dXJuSGFzaCA9IHt9OwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBmb3IgKHF3KCkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JF99ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZyggUHJpb3JpdHkgPT4gJ2Vycm9yJywgTWVzc2FnZSA9PiAiTmVlZCAkXyEiICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBJZiB1c2VkIE9TIGlzIGEgbGludXggc3lzdGVtCiAgICBpZiAoICReTyA9fiAvbGludXgvIHx8IC91bml4LyB8fCAvbmV0YnNkLyB8fCAvZnJlZWJzZC8gfHwgL0Rhcndpbi8gKSB7CgogICAgfQogICAgZWxzaWYgKCAkXk8gPX4gL3dpbi9pICkgewoKICAgIH0KICAgIHJldHVybiAkUmV0dXJuSGFzaDsKfQoKMTsKCj1iYWNrCgo9aGVhZDEgVEVSTVMgQU5EIENPTkRJVElPTlMKClRoaXMgc29mdHdhcmUgaXMgcGFydCBvZiB0aGUgT1RSUyBwcm9qZWN0IChodHRwOi8vb3Rycy5vcmcvKS4KClRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCnRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQpkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC50eHQuCgo9Y3V0Cgo9aGVhZDEgVkVSU0lPTgoKJFJldmlzaW9uOiAxLjUgJCAkRGF0ZTogMjAwNy8xMS8yMiAxMzowNToxMCAkCgo9Y3V0Cg==
cGFja2FnZSBBcmNoaXZlOjpUYXI6OkNvbnN0YW50OwoKQkVHSU4gewogICAgcmVxdWlyZSBFeHBvcnRlcjsKICAgICRWRVJTSU9OPSAnMC4wMic7CiAgICBASVNBICAgID0gcXdbRXhwb3J0ZXJdOwogICAgQEVYUE9SVCA9IHF3WwogICAgICAgICAgICAgICAgRklMRSBIQVJETElOSyBTWU1MSU5LIENIQVJERVYgQkxPQ0tERVYgRElSIEZJRk8gU09DS0VUIFVOS05PV04KICAgICAgICAgICAgICAgIEJVRkZFUiBIRUFEIFJFQURfT05MWSBXUklURV9PTkxZIFVOUEFDSyBQQUNLIFRJTUVfT0ZGU0VUIFpMSUIKICAgICAgICAgICAgICAgIEJMT0NLX1NJWkUgVEFSX1BBRCBUQVJfRU5EIE9OX1VOSVggQkxPQ0sgQ0FOX1JFQURMSU5LIE1BR0lDIAogICAgICAgICAgICAgICAgVEFSX1ZFUlNJT04gVU5BTUUgR05BTUUgQ0FOX0NIT1dOIE1PREUgQ0hFQ0tfU1VNIFVJRCBHSUQgCiAgICAgICAgICAgICAgICBHWklQX01BR0lDX05VTSBNT0RFX1JFQUQgTE9OR0xJTksgTE9OR0xJTktfTkFNRSBQUkVGSVhfTEVOR1RICiAgICAgICAgICAgICAgICBMQUJFTCBOQU1FX0xFTkdUSCBTVFJJUF9NT0RFCiAgICAgICAgICAgIF07CgogICAgcmVxdWlyZSBUaW1lOjpMb2NhbCBpZiAkXk8gZXEgIk1hY09TIjsKfQoKdXNlIGNvbnN0YW50IEZJTEUgICAgICAgICAgID0+IDA7CnVzZSBjb25zdGFudCBIQVJETElOSyAgICAgICA9PiAxOwp1c2UgY29uc3RhbnQgU1lNTElOSyAgICAgICAgPT4gMjsKdXNlIGNvbnN0YW50IENIQVJERVYgICAgICAgID0+IDM7CnVzZSBjb25zdGFudCBCTE9DS0RFViAgICAgICA9PiA0Owp1c2UgY29uc3RhbnQgRElSICAgICAgICAgICAgPT4gNTsKdXNlIGNvbnN0YW50IEZJRk8gICAgICAgICAgID0+IDY7CnVzZSBjb25zdGFudCBTT0NLRVQgICAgICAgICA9PiA4Owp1c2UgY29uc3RhbnQgVU5LTk9XTiAgICAgICAgPT4gOTsKdXNlIGNvbnN0YW50IExPTkdMSU5LICAgICAgID0+ICdMJzsKdXNlIGNvbnN0YW50IExBQkVMICAgICAgICAgID0+ICdWJzsKCnVzZSBjb25zdGFudCBCVUZGRVIgICAgICAgICA9PiA0MDk2Owp1c2UgY29uc3RhbnQgSEVBRCAgICAgICAgICAgPT4gNTEyOwp1c2UgY29uc3RhbnQgQkxPQ0sgICAgICAgICAgPT4gNTEyOwoKdXNlIGNvbnN0YW50IEJMT0NLX1NJWkUgICAgID0+IHN1YiB7IG15ICRuID0gaW50KCRfWzBdL0JMT0NLKTsgJG4rKyBpZiAkX1swXSAlIEJMT0NLOyAkbiAqIEJMT0NLIH07CnVzZSBjb25zdGFudCBUQVJfUEFEICAgICAgICA9PiBzdWIgeyBteSAkeCA9IHNoaWZ0IHx8IHJldHVybjsgcmV0dXJuICJcMCIgeCAoQkxPQ0sgLSAoJHggJSBCTE9DSykgKSB9Owp1c2UgY29uc3RhbnQgVEFSX0VORCAgICAgICAgPT4gIlwwIiB4IEJMT0NLOwoKdXNlIGNvbnN0YW50IFJFQURfT05MWSAgICAgID0+IHN1YiB7IHNoaWZ0KCkgPyAncmInIDogJ3InIH07CnVzZSBjb25zdGFudCBXUklURV9PTkxZICAgICA9PiBzdWIgeyAkX1swXSA/ICd3YicgLiBzaGlmdCA6ICd3JyB9Owp1c2UgY29uc3RhbnQgTU9ERV9SRUFEICAgICAgPT4gc3ViIHsgJF9bMF0gPX4gL15yLyA/IDEgOiAwIH07CgojIFBvaW50bGVzcyBhc3NpZ25tZW50IHRvIG1ha2UgLXcgc2h1dCB1cApteSAkZ2V0cHd1aWQ7ICRnZXRwd3VpZCA9ICd1bmtub3duJyB1bmxlc3MgZXZhbCB7IG15ICRmID0gZ2V0cHd1aWQgKDApOyB9OwpteSAkZ2V0Z3JnaWQ7ICRnZXRncmdpZCA9ICd1bmtub3duJyB1bmxlc3MgZXZhbCB7IG15ICRmID0gZ2V0Z3JnaWQgKDApOyB9Owp1c2UgY29uc3RhbnQgVU5BTUUgICAgICAgICAgPT4gc3ViIHsgJGdldHB3dWlkIHx8IHNjYWxhciBnZXRwd3VpZCggc2hpZnQoKSApIHx8ICcnIH07CnVzZSBjb25zdGFudCBHTkFNRSAgICAgICAgICA9PiBzdWIgeyAkZ2V0Z3JnaWQgfHwgc2NhbGFyIGdldGdyZ2lkKCBzaGlmdCgpICkgfHwgJycgfTsKdXNlIGNvbnN0YW50IFVJRCAgICAgICAgICAgID0+ICQ+Owp1c2UgY29uc3RhbnQgR0lEICAgICAgICAgICAgPT4gKHNwbGl0ICcgJywgJCkgKVswXTsKCnVzZSBjb25zdGFudCBNT0RFICAgICAgICAgICA9PiBkbyB7IDA2NjYgJiAoMDc3NyAmIH51bWFzaykgfTsKdXNlIGNvbnN0YW50IFNUUklQX01PREUgICAgID0+IHN1YiB7IHNoaWZ0KCkgJiAwNzc3IH07CnVzZSBjb25zdGFudCBDSEVDS19TVU0gICAgICA9PiAiICAgICAgIjsKCnVzZSBjb25zdGFudCBVTlBBQ0sgICAgICAgICA9PiAnQTEwMCBBOCBBOCBBOCBBMTIgQTEyIEE4IEExIEExMDAgQTYgQTIgQTMyIEEzMiBBOCBBOCBBMTU1IHgxMic7CnVzZSBjb25zdGFudCBQQUNLICAgICAgICAgICA9PiAnYTEwMCBhOCBhOCBhOCBhMTIgYTEyIEE4IGExIGExMDAgYTYgYTIgYTMyIGEzMiBhOCBhOCBhMTU1IHgxMic7CnVzZSBjb25zdGFudCBOQU1FX0xFTkdUSCAgICA9PiAxMDA7CnVzZSBjb25zdGFudCBQUkVGSVhfTEVOR1RIICA9PiAxNTU7Cgp1c2UgY29uc3RhbnQgVElNRV9PRkZTRVQgICAgPT4gKCReTyBlcSAiTWFjT1MiKSA/IFRpbWU6OkxvY2FsOjp0aW1lbG9jYWwoMCwwLDAsMSwwLDcwKSA6IDA7ICAgIAp1c2UgY29uc3RhbnQgTUFHSUMgICAgICAgICAgPT4gInVzdGFyIjsKdXNlIGNvbnN0YW50IFRBUl9WRVJTSU9OICAgID0+ICIwMCI7CnVzZSBjb25zdGFudCBMT05HTElOS19OQU1FICA9PiAnLi8uL0BMb25nTGluayc7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIGFsbG93IFpMSUIgdG8gYmUgdHVybmVkIG9mZiB1c2luZyBFTlYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyBERUJVRyBvbmx5CnVzZSBjb25zdGFudCBaTElCICAgICAgICAgICA9PiBkbyB7ICEkRU5WeydQRVJMNV9BVF9OT19aTElCJ30gYW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmFsIHsgcmVxdWlyZSBJTzo6WmxpYiB9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkRU5WeydQRVJMNV9BVF9OT19aTElCJ30gfHwgJEAgPyAwIDogMSB9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKdXNlIGNvbnN0YW50IEdaSVBfTUFHSUNfTlVNID0+IHFyL14oPzpcMDM3XDIxM3xcMDM3XDIzNSkvOwoKdXNlIGNvbnN0YW50IENBTl9DSE9XTiAgICAgID0+IGRvIHsgKCQ+ID09IDAgYW5kICReTyBuZSAiTWFjT1MiIGFuZCAkXk8gbmUgIk1TV2luMzIiKSB9Owp1c2UgY29uc3RhbnQgQ0FOX1JFQURMSU5LICAgPT4gKCReTyBuZSAnTVNXaW4zMicgYW5kICReTyAhfiAvUklTQyg/OlsgX10pP09TL2kgYW5kICReTyBuZSAnVk1TJyk7CnVzZSBjb25zdGFudCBPTl9VTklYICAgICAgICA9PiAoJF5PIG5lICdNU1dpbjMyJyBhbmQgJF5PIG5lICdNYWNPUycgYW5kICReTyBuZSAnVk1TJyk7CgoxOwo=
cGFja2FnZSBBcmNoaXZlOjpUYXI6OkZpbGU7CnVzZSBzdHJpY3Q7Cgp1c2UgSU86OkZpbGU7CnVzZSBGaWxlOjpTcGVjOjpVbml4ICAgICgpOwp1c2UgRmlsZTo6U3BlYyAgICAgICAgICAoKTsKdXNlIEZpbGU6OkJhc2VuYW1lICAgICAgKCk7Cgp1c2UgQXJjaGl2ZTo6VGFyOjpDb25zdGFudDsKCnVzZSB2YXJzIHF3W0BJU0EgJFZFUlNJT05dOwpASVNBICAgICAgICA9IHF3W0FyY2hpdmU6OlRhcl07CiRWRVJTSU9OICAgID0gJzAuMDInOwoKIyMjIHNldCB2YWx1ZSB0byAxIHRvIG9jdCgpIGl0IGR1cmluZyB0aGUgdW5wYWNrICMjIwpteSAkdG1wbCA9IFsKICAgICAgICBuYW1lICAgICAgICA9PiAwLCAgICMgc3RyaW5nCiAgICAgICAgbW9kZSAgICAgICAgPT4gMSwgICAjIG9jdGFsCiAgICAgICAgdWlkICAgICAgICAgPT4gMSwgICAjIG9jdGFsCiAgICAgICAgZ2lkICAgICAgICAgPT4gMSwgICAjIG9jdGFsCiAgICAgICAgc2l6ZSAgICAgICAgPT4gMSwgICAjIG9jdGFsCiAgICAgICAgbXRpbWUgICAgICAgPT4gMSwgICAjIG9jdGFsCiAgICAgICAgY2hrc3VtICAgICAgPT4gMSwgICAjIG9jdGFsCiAgICAgICAgdHlwZSAgICAgICAgPT4gMCwgICAjIGNoYXJhY3RlcgogICAgICAgIGxpbmtuYW1lICAgID0+IDAsICAgIyBzdHJpbmcKICAgICAgICBtYWdpYyAgICAgICA9PiAwLCAgICMgc3RyaW5nCiAgICAgICAgdmVyc2lvbiAgICAgPT4gMCwgICAjIDIgYnl0ZXMKICAgICAgICB1bmFtZSAgICAgICA9PiAwLCAgICMgc3RyaW5nCiAgICAgICAgZ25hbWUgICAgICAgPT4gMCwgICAjIHN0cmluZwogICAgICAgIGRldm1ham9yICAgID0+IDEsICAgIyBvY3RhbAogICAgICAgIGRldm1pbm9yICAgID0+IDEsICAgIyBvY3RhbAogICAgICAgIHByZWZpeCAgICAgID0+IDAsCgojIyMgZW5kIFVOUEFDSyBpdGVtcyAjIyMKICAgICAgICByYXcgICAgICAgICA9PiAwLCAgICMgdGhlIHJhdyBkYXRhIGNodW5rCiAgICAgICAgZGF0YSAgICAgICAgPT4gMCwgICAjIHRoZSBkYXRhIGFzc29jaWF0ZWQgd2l0aCB0aGUgZmlsZSAtLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIyBUaGlzICBtaWdodCBiZSB2ZXJ5IG1lbW9yeSBpbnRlbnNpdmUKXTsKCiMjIyBpbnN0YWxsIGdldC9zZXQgYWNjZXNzb3JzIGZvciB0aGlzIG9iamVjdC4KZm9yICggbXkgJGk9MDsgJGk8c2NhbGFyIEAkdG1wbCA7ICRpKz0yICkgewogICAgbXkgJGtleSA9ICR0bXBsLT5bJGldOwogICAgbm8gc3RyaWN0ICdyZWZzJzsKICAgICp7X19QQUNLQUdFX18uIjo6JGtleSJ9ID0gc3ViIHsKICAgICAgICBteSAkc2VsZiA9IHNoaWZ0OwogICAgICAgICRzZWxmLT57JGtleX0gPSAkX1swXSBpZiBAXzsKCiAgICAgICAgIyMjIGp1c3QgaW4gY2FzZSB0aGUga2V5IGlzIG5vdCB0aGVyZSBvciB1bmRlZiBvciBzb21ldGhpbmcgIyMjCiAgICAgICAgeyAgIGxvY2FsICReVyA9IDA7CiAgICAgICAgICAgIHJldHVybiAkc2VsZi0+eyRrZXl9OwogICAgICAgIH0KICAgIH0KfQoKPWhlYWQxIE5BTUUKCkFyY2hpdmU6OlRhcjo6RmlsZSAtIGEgc3ViY2xhc3MgZm9yIGluLW1lbW9yeSBleHRyYWN0ZWQgZmlsZSBmcm9tIEFyY2hpdmU6OlRhcgoKPWhlYWQxIFNZTk9QU0lTCgogICAgbXkgQGl0ZW1zID0gJHRhci0+Z2V0X2ZpbGVzOwoKICAgIHByaW50ICRfLT5uYW1lLCAnICcsICRfLT5zaXplLCAiXG4iIGZvciBAaXRlbXM7CgogICAgcHJpbnQgJG9iamVjdC0+Z2V0X2NvbnRlbnQ7CiAgICAkb2JqZWN0LT5yZXBsYWNlX2NvbnRlbnQoJ25ldyBjb250ZW50Jyk7CgogICAgJG9iamVjdC0+cmVuYW1lKCAnbmV3L2Z1bGwvcGF0aC90by9maWxlLmMnICk7Cgo9aGVhZDEgREVTQ1JJUFRJT04KCkFyY2hpdmU6OlRhcjo6RmlsZXMgcHJvdmlkZXMgYSBuZWF0IGxpdHRsZSBvYmplY3QgbGF5ZXIgZm9yIGluLW1lbW9yeQpleHRyYWN0ZWQgZmlsZXMuIEl0J3MgbW9zdGx5IHVzZWQgaW50ZXJuYWxseSBpbiBBcmNoaXZlOjpUYXIgdG8gdGlkeQp1cCB0aGUgY29kZSwgYnV0IHRoZXJlJ3Mgbm8gcmVhc29uIHVzZXJzIHNob3VsZG4ndCB1c2UgdGhpcyBBUEkgYXMKd2VsbC4KCj1oZWFkMiBBY2Nlc3NvcnMKCkEgbG90IG9mIHRoZSBtZXRob2RzIGluIHRoaXMgcGFja2FnZSBhcmUgYWNjZXNzb3JzIHRvIHRoZSB2YXJpb3VzCmZpZWxkcyBpbiB0aGUgdGFyIGhlYWRlcjoKCj1vdmVyIDQKCj1pdGVtIG5hbWUKClRoZSBmaWxlJ3MgbmFtZQoKPWl0ZW0gbW9kZQoKVGhlIGZpbGUncyBtb2RlCgo9aXRlbSB1aWQKClRoZSB1c2VyIGlkIG93bmluZyB0aGUgZmlsZQoKPWl0ZW0gZ2lkCgpUaGUgZ3JvdXAgaWQgb3duaW5nIHRoZSBmaWxlCgo9aXRlbSBzaXplCgpGaWxlIHNpemUgaW4gYnl0ZXMKCj1pdGVtIG10aW1lCgpNb2RpZmljYXRpb24gdGltZS4gQWRqdXN0ZWQgdG8gbWFjLXRpbWUgb24gTWFjT1MgaWYgcmVxdWlyZWQKCj1pdGVtIGNoa3N1bQoKQ2hlY2tzdW0gZmllbGQgZm9yIHRoZSB0YXIgaGVhZGVyCgo9aXRlbSB0eXBlCgpGaWxlIHR5cGUgLS0gbnVtZXJpYywgYnV0IGNvbXBhcmFibGUgdG8gZXhwb3J0ZWQgY29uc3RhbnRzIC0tIHNlZQpBcmNoaXZlOjpUYXIncyBkb2N1bWVudGF0aW9uCgo9aXRlbSBsaW5rbmFtZQoKSWYgdGhlIGZpbGUgaXMgYSBzeW1saW5rLCB0aGUgZmlsZSBpdCdzIHBvaW50aW5nIHRvCgo9aXRlbSBtYWdpYwoKVGFyIG1hZ2ljIHN0cmluZyAtLSBub3QgdXNlZnVsIGZvciBtb3N0IHVzZXJzCgo9aXRlbSB2ZXJzaW9uCgpUYXIgdmVyc2lvbiBzdHJpbmcgLS0gbm90IHVzZWZ1bCBmb3IgbW9zdCB1c2VycwoKPWl0ZW0gdW5hbWUKClRoZSB1c2VyIG5hbWUgdGhhdCBvd25zIHRoZSBmaWxlCgo9aXRlbSBnbmFtZQoKVGhlIGdyb3VwIG5hbWUgdGhhdCBvd25zIHRoZSBmaWxlCgo9aXRlbSBkZXZtYWpvcgoKRGV2aWNlIG1ham9yIG51bWJlciBpbiBjYXNlIG9mIGEgc3BlY2lhbCBmaWxlCgo9aXRlbSBkZXZtaW5vcgoKRGV2aWNlIG1pbm9yIG51bWJlciBpbiBjYXNlIG9mIGEgc3BlY2lhbCBmaWxlCgo9aXRlbSBwcmVmaXgKCkFueSBkaXJlY3RvcnkgdG8gcHJlZml4IHRvIHRoZSBleHRyYWN0aW9uIHBhdGgsIGlmIGFueQoKPWl0ZW0gcmF3CgpSYXcgdGFyIGhlYWRlciAtLSBub3QgdXNlZnVsIGZvciBtb3N0IHVzZXJzCgo9YmFjawoKPWhlYWQxIE1ldGhvZHMKCj1oZWFkMiBuZXcoIGZpbGUgPT4gJHBhdGggKQoKUmV0dXJucyBhIG5ldyBBcmNoaXZlOjpUYXI6OkZpbGUgb2JqZWN0IGZyb20gYW4gZXhpc3RpbmcgZmlsZS4KClJldHVybnMgdW5kZWYgb24gZmFpbHVyZS4KCj1oZWFkMiBuZXcoIGRhdGEgPT4gJHBhdGgsICRkYXRhLCAkb3B0ICkKClJldHVybnMgYSBuZXcgQXJjaGl2ZTo6VGFyOjpGaWxlIG9iamVjdCBmcm9tIGRhdGEuCgpDPCRwYXRoPiBkZWZpbmVzIHRoZSBmaWxlIG5hbWUgKHdoaWNoIG5lZWQgbm90IGV4aXN0KSwgQzwkZGF0YT4gdGhlCmZpbGUgY29udGVudHMsIGFuZCBDPCRvcHQ+IGlzIGEgcmVmZXJlbmNlIHRvIGEgaGFzaCBvZiBhdHRyaWJ1dGVzCndoaWNoIG1heSBiZSB1c2VkIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IGF0dHJpYnV0ZXMgKGZpZWxkcyBpbiB0aGUKdGFyIGhlYWRlciksIHdoaWNoIGFyZSBkZXNjcmliZWQgYWJvdmUgaW4gdGhlIEFjY2Vzc29ycyBzZWN0aW9uLgoKUmV0dXJucyB1bmRlZiBvbiBmYWlsdXJlLgoKPWhlYWQyIG5ldyggY2h1bmsgPT4gJGNodW5rICkKClJldHVybnMgYSBuZXcgQXJjaGl2ZTo6VGFyOjpGaWxlIG9iamVjdCBmcm9tIGEgcmF3IDUxMi1ieXRlIHRhcgphcmNoaXZlIGNodW5rLgoKUmV0dXJucyB1bmRlZiBvbiBmYWlsdXJlLgoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAkY2xhc3MgICA9IHNoaWZ0OwogICAgbXkgJHdoYXQgICAgPSBzaGlmdDsKCiAgICBteSAkb2JqID0gICAoJHdoYXQgZXEgJ2NodW5rJykgPyBfX1BBQ0tBR0VfXy0+X25ld19mcm9tX2NodW5rKCBAXyApIDoKICAgICAgICAgICAgICAgICgkd2hhdCBlcSAnZmlsZScgKSA/IF9fUEFDS0FHRV9fLT5fbmV3X2Zyb21fZmlsZSggQF8gKSA6CiAgICAgICAgICAgICAgICAoJHdoYXQgZXEgJ2RhdGEnICkgPyBfX1BBQ0tBR0VfXy0+X25ld19mcm9tX2RhdGEoIEBfICkgOgogICAgICAgICAgICAgICAgdW5kZWY7CgogICAgcmV0dXJuICRvYmo7Cn0KCiMjIyBjb3BpZXMgdGhlIGRhdGEsIGNyZWF0ZXMgYSBjbG9uZSAjIyMKc3ViIGNsb25lIHsKICAgIG15ICRzZWxmID0gc2hpZnQ7CiAgICByZXR1cm4gYmxlc3MgeyAlJHNlbGYgfSwgcmVmICRzZWxmOwp9CgpzdWIgX25ld19mcm9tX2NodW5rIHsKICAgIG15ICRjbGFzcyA9IHNoaWZ0OwogICAgbXkgJGNodW5rID0gc2hpZnQgb3IgcmV0dXJuOyAgICAjIDUxMiBieXRlcyBvZiB0YXIgaGVhZGVyCiAgICBteSAlaGFzaCAgPSBAXzsKCiAgICAjIyMgZmlsdGVyIGFueSBhcmd1bWVudHMgb24gZGVmaW5lZC1uZXNzIG9mIHZhbHVlcy4KICAgICMjIyB0aGlzIGFsbG93cyBvdmVycmlkaW5nIGZyb20gd2hhdCB0aGUgdGFyLWhlYWRlciBpcyBzYXlpbmcKICAgICMjIyBhYm91dCB0aGlzIHRhci1lbnRyeS4gUGFydGljdWxhcmx5IHVzZWZ1bCBmb3IgQExvbmdMaW5rIGZpbGVzCiAgICBteSAlYXJncyAgPSBtYXAgeyAkXyA9PiAkaGFzaHskX30gfSBncmVwIHsgZGVmaW5lZCAkaGFzaHskX30gfSBrZXlzICVoYXNoOwoKICAgICMjIyBtYWtlcyBpdCBzdGFydCBhdCAwIGFjdHVhbGx5Li4uIDopICMjIwogICAgbXkgJGkgPSAtMTsKICAgIG15ICVlbnRyeSA9IG1hcCB7CiAgICAgICAgJHRtcGwtPlsrKyRpXSA9PiAkdG1wbC0+WysrJGldID8gb2N0ICRfIDogJF8KICAgIH0gbWFwIHsgL14oW15cMF0qKS8gfSB1bnBhY2soIFVOUEFDSywgJGNodW5rICk7CgogICAgbXkgJG9iaiA9IGJsZXNzIHsgJWVudHJ5LCAlYXJncyB9LCAkY2xhc3M7CgoJIyMjIG1hZ2ljIGlzIGEgZmlsZXR5cGUgc3RyaW5nLi4gaXQgc2hvdWxkIGhhdmUgc29tZXRoaW5nIGxpa2UgJ3VzdGFyJyBvcgoJIyMjIHNvbWV0aGluZyBzaW1pbGFyLi4uIGlmIHRoZSBjaHVuayBpcyBnYXJiYWdlLCBza2lwIGl0CglyZXR1cm4gdW5sZXNzICRvYmotPm1hZ2ljICF+IC9cVy87CgogICAgIyMjIHN0b3JlIHRoZSBvcmlnaW5hbCBjaHVuayAjIyMKICAgICRvYmotPnJhdyggJGNodW5rICk7CgogICAgJG9iai0+dHlwZShGSUxFKSBpZiAoICghbGVuZ3RoICRvYmotPnR5cGUpIG9yICgkb2JqLT50eXBlID1+IC9cVy8pICk7CiAgICAkb2JqLT50eXBlKERJUikgIGlmICggKCRvYmotPmlzX2ZpbGUpICYmICgkb2JqLT5uYW1lID1+IG18LyR8KSApOwoKCiAgICByZXR1cm4gJG9iajsKCn0KCnN1YiBfbmV3X2Zyb21fZmlsZSB7CiAgICBteSAkY2xhc3MgICAgICAgPSBzaGlmdDsKICAgIG15ICRwYXRoICAgICAgICA9IHNoaWZ0OyAgICAgICAgCiAgICAKICAgICMjIyBwYXRoIGhhcyB0byBhdCBsZWFzdCBleGlzdAogICAgcmV0dXJuIHVubGVzcyBkZWZpbmVkICRwYXRoOwogICAgCiAgICBteSAkdHlwZSAgICAgICAgPSBfX1BBQ0tBR0VfXy0+X2ZpbGV0eXBlKCRwYXRoKTsKICAgIG15ICRkYXRhICAgICAgICA9ICcnOwoKICAgIFJFQUQ6IHsgCiAgICAgICAgdW5sZXNzICgkdHlwZSA9PSBESVIgKSB7CiAgICAgICAgICAgIG15ICRmaCA9IElPOjpGaWxlLT5uZXc7CiAgICAgICAgCiAgICAgICAgICAgIHVubGVzcyggJGZoLT5vcGVuKCRwYXRoKSApIHsKICAgICAgICAgICAgICAgICMjIyBkYW5nbGluZyBzeW1saW5rcyBhcmUgZmluZSwgc3RvcCByZWFkaW5nIGJ1dCBjb250aW51ZQogICAgICAgICAgICAgICAgIyMjIGNyZWF0aW5nIHRoZSBvYmplY3QKICAgICAgICAgICAgICAgIGxhc3QgUkVBRCBpZiAkdHlwZSA9PSBTWU1MSU5LOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAjIyMgb3RoZXJ3aXNlLCByZXR1cm4gZnJvbSB0aGlzIGZ1bmN0aW9uIC0tCiAgICAgICAgICAgICAgICAjIyMgYW55dGhpbmcgdGhhdCdzICpub3QqIGEgc3ltbGluayBzaG91bGQgYmUKICAgICAgICAgICAgICAgICMjIyByZXNvbHZhYmxlCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICMjIyBiaW5tb2RlIG5lZWRlZCB0byByZWFkIGZpbGVzIHByb3Blcmx5IG9uIHdpbjMyICMjIwogICAgICAgICAgICBiaW5tb2RlICRmaDsKICAgICAgICAgICAgJGRhdGEgPSBkbyB7IGxvY2FsICQvOyA8JGZoPiB9OwogICAgICAgICAgICBjbG9zZSAkZmg7CiAgICAgICAgfQogICAgfQoKICAgIG15IEBpdGVtcyAgICAgICA9IHF3W21vZGUgdWlkIGdpZCBzaXplIG10aW1lXTsKICAgIG15ICVoYXNoICAgICAgICA9IG1hcCB7IHNoaWZ0KEBpdGVtcyksICRfIH0gKGxzdGF0ICRwYXRoKVsyLDQsNSw3LDldOwoKICAgICMjIyB5b3UgKm11c3QqIHNldCBzaXplID09IDAgb24gc3ltbGlua3MsIG9yIHRoZSBuZXh0IGVudHJ5IHdpbGwgYmUKICAgICMjIyB0aG91Z2ggb2YgYXMgdGhlIGNvbnRlbnRzIG9mIHRoZSBzeW1saW5rLCB3aGljaCBpcyB3cm9uZy4KICAgICMjIyB0aGlzIGZpeGVzIGJ1ZyAjNzkzNwogICAgJGhhc2h7c2l6ZX0gICAgID0gMCBpZiAoJHR5cGUgPT0gRElSIG9yICR0eXBlID09IFNZTUxJTkspOwogICAgJGhhc2h7bXRpbWV9ICAgIC09IFRJTUVfT0ZGU0VUOwoKICAgICMjIyBzdHJpcCB0aGUgaGlnaCBiaXRzIG9mZiB0aGUgbW9kZSwgd2hpY2ggd2UgZG9uJ3QgbmVlZCB0byBzdG9yZQogICAgJGhhc2h7bW9kZX0gICAgID0gU1RSSVBfTU9ERS0+KCAkaGFzaHttb2RlfSApOwoKCiAgICAjIyMgcHJvYmFibHkgcmVxdWlyZXMgc29tZSBmaWxlIHBhdGggbXVuZ2luZyBoZXJlIC4uLiAjIyMKICAgICMjIyBuYW1lIGFuZCBwcmVmaXggYXJlIHNldCBsYXRlcgogICAgbXkgJG9iaiA9IHsKICAgICAgICAlaGFzaCwKICAgICAgICBuYW1lICAgICAgICA9PiAnJywKICAgICAgICBjaGtzdW0gICAgICA9PiBDSEVDS19TVU0sCiAgICAgICAgdHlwZSAgICAgICAgPT4gJHR5cGUsCiAgICAgICAgbGlua25hbWUgICAgPT4gKCR0eXBlID09IFNZTUxJTksgYW5kIENBTl9SRUFETElOSykKICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gcmVhZGxpbmsgJHBhdGgKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogJycsCiAgICAgICAgbWFnaWMgICAgICAgPT4gTUFHSUMsCiAgICAgICAgdmVyc2lvbiAgICAgPT4gVEFSX1ZFUlNJT04sCiAgICAgICAgdW5hbWUgICAgICAgPT4gVU5BTUUtPiggJGhhc2h7dWlkfSApLAogICAgICAgIGduYW1lICAgICAgID0+IEdOQU1FLT4oICRoYXNoe2dpZH0gKSwKICAgICAgICBkZXZtYWpvciAgICA9PiAwLCAgICMgbm90IGhhbmRsZWQKICAgICAgICBkZXZtaW5vciAgICA9PiAwLCAgICMgbm90IGhhbmRsZWQKICAgICAgICBwcmVmaXggICAgICA9PiAnJywKICAgICAgICBkYXRhICAgICAgICA9PiAkZGF0YSwKICAgIH07CgogICAgYmxlc3MgJG9iaiwgJGNsYXNzOwoKICAgICMjIyBmaXggdXAgdGhlIHByZWZpeCBhbmQgZmlsZSBmcm9tIHRoZSBwYXRoCiAgICBteSgkcHJlZml4LCRmaWxlKSA9ICRvYmotPl9wcmVmaXhfYW5kX2ZpbGUoICRwYXRoICk7CiAgICAkb2JqLT5wcmVmaXgoICRwcmVmaXggKTsKICAgICRvYmotPm5hbWUoICRmaWxlICk7CgogICAgcmV0dXJuICRvYmo7Cn0KCnN1YiBfbmV3X2Zyb21fZGF0YSB7CiAgICBteSAkY2xhc3MgICA9IHNoaWZ0OwogICAgbXkgJHBhdGggICAgPSBzaGlmdDsgICAgcmV0dXJuIHVubGVzcyBkZWZpbmVkICRwYXRoOwogICAgbXkgJGRhdGEgICAgPSBzaGlmdDsgICAgcmV0dXJuIHVubGVzcyBkZWZpbmVkICRkYXRhOwogICAgbXkgJG9wdCAgICAgPSBzaGlmdDsKCiAgICBteSAkb2JqID0gewogICAgICAgIGRhdGEgICAgICAgID0+ICRkYXRhLAogICAgICAgIG5hbWUgICAgICAgID0+ICcnLAogICAgICAgIG1vZGUgICAgICAgID0+IE1PREUsCiAgICAgICAgdWlkICAgICAgICAgPT4gVUlELAogICAgICAgIGdpZCAgICAgICAgID0+IEdJRCwKICAgICAgICBzaXplICAgICAgICA9PiBsZW5ndGggJGRhdGEsCiAgICAgICAgbXRpbWUgICAgICAgPT4gdGltZSAtIFRJTUVfT0ZGU0VULAogICAgICAgIGNoa3N1bSAgICAgID0+IENIRUNLX1NVTSwKICAgICAgICB0eXBlICAgICAgICA9PiBGSUxFLAogICAgICAgIGxpbmtuYW1lICAgID0+ICcnLAogICAgICAgIG1hZ2ljICAgICAgID0+IE1BR0lDLAogICAgICAgIHZlcnNpb24gICAgID0+IFRBUl9WRVJTSU9OLAogICAgICAgIHVuYW1lICAgICAgID0+IFVOQU1FLT4oIFVJRCApLAogICAgICAgIGduYW1lICAgICAgID0+IEdOQU1FLT4oIEdJRCApLAogICAgICAgIGRldm1pbm9yICAgID0+IDAsCiAgICAgICAgZGV2bWFqb3IgICAgPT4gMCwKICAgICAgICBwcmVmaXggICAgICA9PiAnJywKICAgIH07CgogICAgIyMjIG92ZXJ3cml0ZSB3aXRoIHVzZXIgb3B0aW9ucywgaWYgcHJvdmlkZWQgIyMjCiAgICBpZiggJG9wdCBhbmQgcmVmICRvcHQgZXEgJ0hBU0gnICkgewogICAgICAgIGZvciBteSAka2V5ICgga2V5cyAlJG9wdCApIHsKCiAgICAgICAgICAgICMjIyBkb24ndCB3cml0ZSBib2d1cyBvcHRpb25zICMjIwogICAgICAgICAgICBuZXh0IHVubGVzcyBleGlzdHMgJG9iai0+eyRrZXl9OwogICAgICAgICAgICAkb2JqLT57JGtleX0gPSAkb3B0LT57JGtleX07CiAgICAgICAgfQogICAgfQoKICAgIGJsZXNzICRvYmosICRjbGFzczsKCiAgICAjIyMgZml4IHVwIHRoZSBwcmVmaXggYW5kIGZpbGUgZnJvbSB0aGUgcGF0aAogICAgbXkoJHByZWZpeCwkZmlsZSkgPSAkb2JqLT5fcHJlZml4X2FuZF9maWxlKCAkcGF0aCApOwogICAgJG9iai0+cHJlZml4KCAkcHJlZml4ICk7CiAgICAkb2JqLT5uYW1lKCAkZmlsZSApOwoKICAgIHJldHVybiAkb2JqOwp9CgpzdWIgX3ByZWZpeF9hbmRfZmlsZSB7CiAgICBteSAkc2VsZiA9IHNoaWZ0OwogICAgbXkgJHBhdGggPSBzaGlmdDsKCiAgICBteSAoJHZvbCwgJGRpcnMsICRmaWxlKSA9IEZpbGU6OlNwZWMtPnNwbGl0cGF0aCggJHBhdGgsICRzZWxmLT5pc19kaXIgKTsKICAgIG15IEBkaXJzID0gRmlsZTo6U3BlYy0+c3BsaXRkaXIoICRkaXJzICk7CgogICAgIyMjIHNvIHNvbWV0aW1lcyB0aGUgbGFzdCBlbGVtZW50IGlzICcnIC0tIHByb2JhYmx5IHdoZW4gdHJhaWxpbmcKICAgICMjIyBkaXIgc2xhc2hlcyBhcmUgZW5jb3VudGVyZWQuLi4gdGhpcyBpcyBpcyBvZiBjb3Vyc2UgcG9pbnRsZXNzLAogICAgIyMjIHNvIHJlbW92ZSBpdAogICAgcG9wIEBkaXJzIHdoaWxlIEBkaXJzIGFuZCBub3QgbGVuZ3RoICRkaXJzWy0xXTsKCiAgICAjIyMgaWYgaXQncyBhIGRpcmVjdG9yeSwgdGhlbiAkZmlsZSBtaWdodCBiZSBlbXB0eQogICAgJGZpbGUgPSBwb3AgQGRpcnMgaWYgJHNlbGYtPmlzX2RpciBhbmQgbm90IGxlbmd0aCAkZmlsZTsKCiAgICBteSAkcHJlZml4ID0gRmlsZTo6U3BlYzo6VW5peC0+Y2F0ZGlyKAogICAgICAgICAgICAgICAgICAgICAgICBncmVwIHsgbGVuZ3RoIH0gJHZvbCwgQGRpcnMKICAgICAgICAgICAgICAgICAgICApOwogICAgcmV0dXJuKCAkcHJlZml4LCAkZmlsZSApOwp9CgpzdWIgX2ZpbGV0eXBlIHsKICAgIG15ICRzZWxmID0gc2hpZnQ7CiAgICBteSAkZmlsZSA9IHNoaWZ0OwogICAgCiAgICByZXR1cm4gdW5sZXNzIGRlZmluZWQgJGZpbGU7CgogICAgcmV0dXJuIFNZTUxJTksgIGlmICgtbCAkZmlsZSk7CSMgU3ltbGluawoKICAgIHJldHVybiBGSUxFICAgICBpZiAoLWYgXyk7CQkjIFBsYWluIGZpbGUKCiAgICByZXR1cm4gRElSICAgICAgaWYgKC1kIF8pOwkJIyBEaXJlY3RvcnkKCiAgICByZXR1cm4gRklGTyAgICAgaWYgKC1wIF8pOwkJIyBOYW1lZCBwaXBlCgogICAgcmV0dXJuIFNPQ0tFVCAgIGlmICgtUyBfKTsJCSMgU29ja2V0CgogICAgcmV0dXJuIEJMT0NLREVWIGlmICgtYiBfKTsJCSMgQmxvY2sgc3BlY2lhbAoKICAgIHJldHVybiBDSEFSREVWICBpZiAoLWMgXyk7CQkjIENoYXJhY3RlciBzcGVjaWFsCgogICAgIyMjIHNob3VsZG4ndCBoYXBwZW4sIHRoaXMgaXMgd2hlbiBtYWtpbmcgYXJjaGl2ZXMsIG5vdCByZWFkaW5nICMjIwogICAgcmV0dXJuIExPTkdMSU5LIGlmICggJGZpbGUgZXEgTE9OR0xJTktfTkFNRSApOwoKICAgIHJldHVybiBVTktOT1dOOwkJICAgICAgICAgICAgIyBTb21ldGhpbmcgZWxzZSAobGlrZSB3aGF0PykKCn0KCiMjIyB0aGlzIG1ldGhvZCAnZG93bmdyYWRlcycgYSBmaWxlIHRvIHBsYWluIGZpbGUgLS0gdGhpcyBpcyB1c2VkIGZvcgojIyMgc3ltbGlua3Mgd2hlbiBGT0xMT1dfU1lNTElOS1MgaXMgdHJ1ZS4Kc3ViIF9kb3duZ3JhZGVfdG9fcGxhaW5maWxlIHsKICAgIG15ICRlbnRyeSA9IHNoaWZ0OwogICAgJGVudHJ5LT50eXBlKCBGSUxFICk7CiAgICAkZW50cnktPm1vZGUoIE1PREUgKTsKICAgICRlbnRyeS0+bGlua25hbWUoJycpOwoKICAgIHJldHVybiAxOwp9Cgo9aGVhZDIgZnVsbF9wYXRoCgpSZXR1cm5zIHRoZSBmdWxsIHBhdGggZnJvbSB0aGUgdGFyIGhlYWRlcjsgdGhpcyBpcyBiYXNpY2FsbHkgYQpjb25jYXRlbmF0aW9uIG9mIHRoZSBDPHByZWZpeD4gYW5kIEM8bmFtZT4gZmllbGRzLgoKPWN1dAoKc3ViIGZ1bGxfcGF0aCB7CiAgICBteSAkc2VsZiA9IHNoaWZ0OwoKICAgICMjIyBpZiBwcmVmaXggZmllbGQgaXMgZW10cHkKICAgIHJldHVybiAkc2VsZi0+bmFtZSB1bmxlc3MgZGVmaW5lZCAkc2VsZi0+cHJlZml4IGFuZCBsZW5ndGggJHNlbGYtPnByZWZpeDsKCiAgICAjIyMgb3Igb3RoZXJ3aXNlLCBjYXRmaWxlJ2QKICAgIHJldHVybiBGaWxlOjpTcGVjOjpVbml4LT5jYXRmaWxlKCAkc2VsZi0+cHJlZml4LCAkc2VsZi0+bmFtZSApOwp9CgoKPWhlYWQyIHZhbGlkYXRlCgpEb25lIGJ5IEFyY2hpdmU6OlRhciBpbnRlcm5hbGx5IHdoZW4gcmVhZGluZyB0aGUgdGFyIGZpbGU6CnZhbGlkYXRlIHRoZSBoZWFkZXIgYWdhaW5zdCB0aGUgY2hlY2tzdW0gdG8gZW5zdXJlIGludGVnZXIgdGFyIGZpbGUuCgpSZXR1cm5zIHRydWUgb24gc3VjY2VzcywgZmFsc2Ugb24gZmFpbHVyZQoKPWN1dAoKc3ViIHZhbGlkYXRlIHsKICAgIG15ICRzZWxmID0gc2hpZnQ7CgogICAgbXkgJHJhdyA9ICRzZWxmLT5yYXc7CgogICAgIyMjIGRvbid0IGtub3cgd2h5IHRoaXMgb25lIGlzIGRpZmZlcmVudCBmcm9tIHRoZSBvbmUgd2UgL3dyaXRlLyAjIyMKICAgIHN1YnN0ciAoJHJhdywgMTQ4LCA4KSA9ICIgICAgICAgICI7CglyZXR1cm4gdW5wYWNrICgiJTE2QyoiLCAkcmF3KSA9PSAkc2VsZi0+Y2hrc3VtID8gMSA6IDA7Cn0KCj1oZWFkMiBoYXNfY29udGVudAoKUmV0dXJucyBhIGJvb2xlYW4gdG8gaW5kaWNhdGUgd2hldGhlciB0aGUgY3VycmVudCBvYmplY3QgaGFzIGNvbnRlbnQuClNvbWUgc3BlY2lhbCBmaWxlcyBsaWtlIGRpcmVjdG9yaWVzIGFuZCBzbyBvbiBuZXZlciB3aWxsIGhhdmUgYW55CmNvbnRlbnQuIFRoaXMgbWV0aG9kIGlzIG1haW5seSB0byBtYWtlIHN1cmUgeW91IGRvbid0IGdldCB3YXJuaW5ncwpmb3IgdXNpbmcgdW5pbml0aWFsaXplZCB2YWx1ZXMgd2hlbiBsb29raW5nIGF0IGFuIG9iamVjdCdzIGNvbnRlbnQuCgo9Y3V0CgpzdWIgaGFzX2NvbnRlbnQgewogICAgbXkgJHNlbGYgPSBzaGlmdDsKICAgIHJldHVybiBkZWZpbmVkICRzZWxmLT5kYXRhKCkgJiYgbGVuZ3RoICRzZWxmLT5kYXRhKCkgPyAxIDogMDsKfQoKPWhlYWQyIGdldF9jb250ZW50CgpSZXR1cm5zIHRoZSBjdXJyZW50IGNvbnRlbnQgZm9yIHRoZSBpbi1tZW1vcnkgZmlsZQoKPWN1dAoKc3ViIGdldF9jb250ZW50IHsKICAgIG15ICRzZWxmID0gc2hpZnQ7CiAgICAkc2VsZi0+ZGF0YSggKTsKfQoKPWhlYWQyIGdldF9jb250ZW50X2J5X3JlZgoKUmV0dXJucyB0aGUgY3VycmVudCBjb250ZW50IGZvciB0aGUgaW4tbWVtb3J5IGZpbGUgYXMgYSBzY2FsYXIKcmVmZXJlbmNlLiBOb3JtYWwgdXNlcnMgd29uJ3QgbmVlZCB0aGlzLCBidXQgaXQgd2lsbCBzYXZlIG1lbW9yeSBpZgp5b3UgYXJlIGRlYWxpbmcgd2l0aCB2ZXJ5IGxhcmdlIGRhdGEgZmlsZXMgaW4geW91ciB0YXIgYXJjaGl2ZSwgc2luY2UKaXQgd2lsbCBwYXNzIHRoZSBjb250ZW50cyBieSByZWZlcmVuY2UsIHJhdGhlciB0aGFuIG1ha2UgYSBjb3B5IG9mIGl0CmZpcnN0LgoKPWN1dAoKc3ViIGdldF9jb250ZW50X2J5X3JlZiB7CiAgICBteSAkc2VsZiA9IHNoaWZ0OwoKICAgIHJldHVybiBcJHNlbGYtPntkYXRhfTsKfQoKPWhlYWQyIHJlcGxhY2VfY29udGVudCggJGNvbnRlbnQgKQoKUmVwbGFjZSB0aGUgY3VycmVudCBjb250ZW50IG9mIHRoZSBmaWxlIHdpdGggdGhlIG5ldyBjb250ZW50LiBUaGlzCm9ubHkgYWZmZWN0cyB0aGUgaW4tbWVtb3J5IGFyY2hpdmUsIG5vdCB0aGUgb24tZGlzayB2ZXJzaW9uIHVudGlsCnlvdSB3cml0ZSBpdC4KClJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgoKPWN1dAoKc3ViIHJlcGxhY2VfY29udGVudCB7CiAgICBteSAkc2VsZiA9IHNoaWZ0OwogICAgbXkgJGRhdGEgPSBzaGlmdCB8fCAnJzsKCiAgICAkc2VsZi0+ZGF0YSggJGRhdGEgKTsKICAgICRzZWxmLT5zaXplKCBsZW5ndGggJGRhdGEgKTsKICAgIHJldHVybiAxOwp9Cgo9aGVhZDIgcmVuYW1lKCAkbmV3X25hbWUgKQoKUmVuYW1lIHRoZSBjdXJyZW50IGZpbGUgdG8gJG5ld19uYW1lLgoKTm90ZSB0aGF0IHlvdSBtdXN0IHNwZWNpZnkgYSBVbml4IHBhdGggZm9yICRuZXdfbmFtZSwgc2luY2UgcGVyIHRhcgpzdGFuZGFyZCwgYWxsIGZpbGVzIGluIHRoZSBhcmNoaXZlIG11c3QgYmUgVW5peCBwYXRocy4KClJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzIGFuZCBmYWxzZSBvbiBmYWlsdXJlLgoKPWN1dAoKc3ViIHJlbmFtZSB7CiAgICBteSAkc2VsZiA9IHNoaWZ0OwogICAgbXkgJHBhdGggPSBzaGlmdDsKICAgIAogICAgcmV0dXJuIHVubGVzcyBkZWZpbmVkICRwYXRoOwoKICAgIG15ICgkcHJlZml4LCRmaWxlKSA9ICRzZWxmLT5fcHJlZml4X2FuZF9maWxlKCAkcGF0aCApOwoKICAgICRzZWxmLT5uYW1lKCAkZmlsZSApOwogICAgJHNlbGYtPnByZWZpeCggJHByZWZpeCApOwoKCXJldHVybiAxOwp9Cgo9aGVhZDEgQ29udmVuaWVuY2UgbWV0aG9kcwoKVG8gcXVpY2tseSBjaGVjayB0aGUgdHlwZSBvZiBhIEM8QXJjaGl2ZTo6VGFyOjpGaWxlPiBvYmplY3QsIHlvdSBjYW4KdXNlIHRoZSBmb2xsb3dpbmcgbWV0aG9kczoKCj1vdmVyIDQKCj1pdGVtIGlzX2ZpbGUKClJldHVybnMgdHJ1ZSBpZiB0aGUgZmlsZSBpcyBvZiB0eXBlIEM8ZmlsZT4KCj1pdGVtIGlzX2RpcgoKUmV0dXJucyB0cnVlIGlmIHRoZSBmaWxlIGlzIG9mIHR5cGUgQzxkaXI+Cgo9aXRlbSBpc19oYXJkbGluawoKUmV0dXJucyB0cnVlIGlmIHRoZSBmaWxlIGlzIG9mIHR5cGUgQzxoYXJkbGluaz4KCj1pdGVtIGlzX3N5bWxpbmsKClJldHVybnMgdHJ1ZSBpZiB0aGUgZmlsZSBpcyBvZiB0eXBlIEM8c3ltbGluaz4KCj1pdGVtIGlzX2NoYXJkZXYKClJldHVybnMgdHJ1ZSBpZiB0aGUgZmlsZSBpcyBvZiB0eXBlIEM8Y2hhcmRldj4KCj1pdGVtIGlzX2Jsb2NrZGV2CgpSZXR1cm5zIHRydWUgaWYgdGhlIGZpbGUgaXMgb2YgdHlwZSBDPGJsb2NrZGV2PgoKPWl0ZW0gaXNfZmlmbwoKUmV0dXJucyB0cnVlIGlmIHRoZSBmaWxlIGlzIG9mIHR5cGUgQzxmaWZvPgoKPWl0ZW0gaXNfc29ja2V0CgpSZXR1cm5zIHRydWUgaWYgdGhlIGZpbGUgaXMgb2YgdHlwZSBDPHNvY2tldD4KCj1pdGVtIGlzX2xvbmdsaW5rCgpSZXR1cm5zIHRydWUgaWYgdGhlIGZpbGUgaXMgb2YgdHlwZSBDPExvbmdMaW5rPi4KU2hvdWxkIG5vdCBoYXBwZW4gYWZ0ZXIgYSBzdWNjZXNzZnVsIEM8cmVhZD4uCgo9aXRlbSBpc19sYWJlbAoKUmV0dXJucyB0cnVlIGlmIHRoZSBmaWxlIGlzIG9mIHR5cGUgQzxMYWJlbD4uClNob3VsZCBub3QgaGFwcGVuIGFmdGVyIGEgc3VjY2Vzc2Z1bCBDPHJlYWQ+LgoKPWl0ZW0gaXNfdW5rbm93bgoKUmV0dXJucyB0cnVlIGlmIHRoZSBmaWxlIHR5cGUgaXMgQzx1bmtub3duPgoKPWJhY2sKCj1jdXQKCiNzdHVwaWQgcGVybDUuNS4zIG5lZWRzIHRvIHdhcm4gaWYgaXQncyBub3QgbnVtZXJpYwpzdWIgaXNfZmlsZSAgICAgeyBsb2NhbCAkXlc7ICAgIEZJTEUgICAgICA9PSAkX1swXS0+dHlwZSB9CnN1YiBpc19kaXIgICAgICB7IGxvY2FsICReVzsgICAgRElSICAgICAgID09ICRfWzBdLT50eXBlIH0Kc3ViIGlzX2hhcmRsaW5rIHsgbG9jYWwgJF5XOyAgICBIQVJETElOSyAgPT0gJF9bMF0tPnR5cGUgfQpzdWIgaXNfc3ltbGluayAgeyBsb2NhbCAkXlc7ICAgIFNZTUxJTksgICA9PSAkX1swXS0+dHlwZSB9CnN1YiBpc19jaGFyZGV2ICB7IGxvY2FsICReVzsgICAgQ0hBUkRFViAgID09ICRfWzBdLT50eXBlIH0Kc3ViIGlzX2Jsb2NrZGV2IHsgbG9jYWwgJF5XOyAgICBCTE9DS0RFViAgPT0gJF9bMF0tPnR5cGUgfQpzdWIgaXNfZmlmbyAgICAgeyBsb2NhbCAkXlc7ICAgIEZJRk8gICAgICA9PSAkX1swXS0+dHlwZSB9CnN1YiBpc19zb2NrZXQgICB7IGxvY2FsICReVzsgICAgU09DS0VUICAgID09ICRfWzBdLT50eXBlIH0Kc3ViIGlzX3Vua25vd24gIHsgbG9jYWwgJF5XOyAgICBVTktOT1dOICAgPT0gJF9bMF0tPnR5cGUgfQpzdWIgaXNfbG9uZ2xpbmsgeyBsb2NhbCAkXlc7ICAgIExPTkdMSU5LICBlcSAkX1swXS0+dHlwZSB9CnN1YiBpc19sYWJlbCAgICB7IGxvY2FsICReVzsgICAgTEFCRUwgICAgIGVxICRfWzBdLT50eXBlIH0KCjE7Cg==
IyMjIHRoZSBnbnUgdGFyIHNwZWNpZmljYXRpb246CiMjIyBodHRwOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvdGFyL21hbnVhbC90YXIuaHRtbAojIyMKIyMjIGFuZCB0aGUgcGF4IGZvcm1hdCBzcGVjLCB3aGljaCB0YXIgZGVyaXZlcyBmcm9tOgojIyMgaHR0cDovL3d3dy5vcGVuZ3JvdXAub3JnL29ubGluZXB1YnMvMDA3OTA0OTc1L3V0aWxpdGllcy9wYXguaHRtbAoKcGFja2FnZSBBcmNoaXZlOjpUYXI7CnJlcXVpcmUgNS4wMDVfMDM7Cgp1c2Ugc3RyaWN0Owp1c2UgdmFycyBxd1skREVCVUcgJGVycm9yICRWRVJTSU9OICRXQVJOICRGT0xMT1dfU1lNTElOSyAkQ0hPV04gJENITU9ECiAgICAgICAgICAgICRET19OT1RfVVNFX1BSRUZJWCAkSEFTX1BFUkxJTyAkSEFTX0lPX1NUUklOR107CgokREVCVUcgICAgICAgICAgICAgID0gMDsKJFdBUk4gICAgICAgICAgICAgICA9IDE7CiRGT0xMT1dfU1lNTElOSyAgICAgPSAwOwokVkVSU0lPTiAgICAgICAgICAgID0gIjEuMzQiOwokQ0hPV04gICAgICAgICAgICAgID0gMTsKJENITU9EICAgICAgICAgICAgICA9IDE7CiRET19OT1RfVVNFX1BSRUZJWCAgPSAwOwoKQkVHSU4gewogICAgdXNlIENvbmZpZzsKICAgICRIQVNfUEVSTElPID0gJENvbmZpZzo6Q29uZmlne3VzZXBlcmxpb307CgogICAgIyMjIHRyeSBhbmQgbG9hZCBJTzo6U3RyaW5nIGFueXdheSwgc28geW91IGNhbiBkeW5hbWljYWxseQogICAgIyMjIHN3aXRjaCBiZXR3ZWVuIHBlcmxpbyBhbmQgSU86OlN0cmluZwogICAgZXZhbCB7CiAgICAgICAgcmVxdWlyZSBJTzo6U3RyaW5nOwogICAgICAgIGltcG9ydCBJTzo6U3RyaW5nOwogICAgfTsKICAgICRIQVNfSU9fU1RSSU5HID0gJEAgPyAwIDogMTsKCn0KCnVzZSBDd2Q7CnVzZSBJTzo6RmlsZTsKdXNlIENhcnAgICAgICAgICAgICAgICAgcXcoY2FycCBjcm9hayk7CnVzZSBGaWxlOjpTcGVjICAgICAgICAgICgpOwp1c2UgRmlsZTo6U3BlYzo6VW5peCAgICAoKTsKdXNlIEZpbGU6OlBhdGggICAgICAgICAgKCk7Cgp1c2UgQXJjaGl2ZTo6VGFyOjpGaWxlOwp1c2UgQXJjaGl2ZTo6VGFyOjpDb25zdGFudDsKCj1oZWFkMSBOQU1FCgpBcmNoaXZlOjpUYXIgLSBtb2R1bGUgZm9yIG1hbmlwdWxhdGlvbnMgb2YgdGFyIGFyY2hpdmVzCgo9aGVhZDEgU1lOT1BTSVMKCiAgICB1c2UgQXJjaGl2ZTo6VGFyOwogICAgbXkgJHRhciA9IEFyY2hpdmU6OlRhci0+bmV3OwoKICAgICR0YXItPnJlYWQoJ29yaWdpbi50Z3onLDEpOwogICAgJHRhci0+ZXh0cmFjdCgpOwoKICAgICR0YXItPmFkZF9maWxlcygnZmlsZS9mb28ucGwnLCAnZG9jcy9SRUFETUUnKTsKICAgICR0YXItPmFkZF9kYXRhKCdmaWxlL2Jhei50eHQnLCAnVGhpcyBpcyB0aGUgY29udGVudHMgbm93Jyk7CgogICAgJHRhci0+cmVuYW1lKCdvbGRuYW1lJywgJ25ldy9maWxlL25hbWUnKTsKCiAgICAkdGFyLT53cml0ZSgnZmlsZXMudGFyJyk7Cgo9aGVhZDEgREVTQ1JJUFRJT04KCkFyY2hpdmU6OlRhciBwcm92aWRlcyBhbiBvYmplY3Qgb3JpZW50ZWQgbWVjaGFuaXNtIGZvciBoYW5kbGluZyB0YXIKZmlsZXMuICBJdCBwcm92aWRlcyBjbGFzcyBtZXRob2RzIGZvciBxdWljayBhbmQgZWFzeSBmaWxlcyBoYW5kbGluZwp3aGlsZSBhbHNvIGFsbG93aW5nIGZvciB0aGUgY3JlYXRpb24gb2YgdGFyIGZpbGUgb2JqZWN0cyBmb3IgY3VzdG9tCm1hbmlwdWxhdGlvbi4gIElmIHlvdSBoYXZlIHRoZSBJTzo6WmxpYiBtb2R1bGUgaW5zdGFsbGVkLApBcmNoaXZlOjpUYXIgd2lsbCBhbHNvIHN1cHBvcnQgY29tcHJlc3NlZCBvciBnemlwcGVkIHRhciBmaWxlcy4KCkFuIG9iamVjdCBvZiBjbGFzcyBBcmNoaXZlOjpUYXIgcmVwcmVzZW50cyBhIC50YXIoLmd6KSBhcmNoaXZlIGZ1bGwKb2YgZmlsZXMgYW5kIHRoaW5ncy4KCj1oZWFkMSBPYmplY3QgTWV0aG9kcwoKPWhlYWQyIEFyY2hpdmU6OlRhci0+bmV3KCBbJGZpbGUsICRjb21wcmVzc2VkXSApCgpSZXR1cm5zIGEgbmV3IFRhciBvYmplY3QuIElmIGdpdmVuIGFueSBhcmd1bWVudHMsIEM8bmV3KCk+IGNhbGxzIHRoZQpDPHJlYWQoKT4gbWV0aG9kIGF1dG9tYXRpY2FsbHksIHBhc3Npbmcgb24gdGhlIGFyZ3VtZW50cyBwcm92aWRlZCB0bwp0aGUgQzxyZWFkKCk+IG1ldGhvZC4KCklmIEM8bmV3KCk+IGlzIGludm9rZWQgd2l0aCBhcmd1bWVudHMgYW5kIHRoZSBDPHJlYWQoKT4gbWV0aG9kIGZhaWxzCmZvciBhbnkgcmVhc29uLCBDPG5ldygpPiByZXR1cm5zIHVuZGVmLgoKPWN1dAoKbXkgJHRtcGwgPSB7CiAgICBfZGF0YSAgID0+IFsgXSwKICAgIF9maWxlICAgPT4gJ1Vua25vd24nLAp9OwoKIyMjIGluc3RhbGwgZ2V0L3NldCBhY2Nlc3NvcnMgZm9yIHRoaXMgb2JqZWN0Lgpmb3IgbXkgJGtleSAoIGtleXMgJSR0bXBsICkgewogICAgbm8gc3RyaWN0ICdyZWZzJzsKICAgICp7X19QQUNLQUdFX18uIjo6JGtleSJ9ID0gc3ViIHsKICAgICAgICBteSAkc2VsZiA9IHNoaWZ0OwogICAgICAgICRzZWxmLT57JGtleX0gPSAkX1swXSBpZiBAXzsKICAgICAgICByZXR1cm4gJHNlbGYtPnska2V5fTsKICAgIH0KfQoKc3ViIG5ldyB7CiAgICBteSAkY2xhc3MgPSBzaGlmdDsKICAgICRjbGFzcyA9IHJlZiAkY2xhc3MgaWYgcmVmICRjbGFzczsKCiAgICAjIyMgY29weWluZyAkdG1wbCBoZXJlIHNpbmNlIGEgc2hhbGxvdyBjb3B5IG1ha2VzIGl0IHVzZSB0aGUKICAgICMjIyBzYW1lIGFyZWYsIGNhdXNpbmcgZm9yIGZpbGVzIHRvIHJlbWFpbiBpbiBtZW1vcnkgYWx3YXlzLgogICAgbXkgJG9iaiA9IGJsZXNzIHsgX2RhdGEgPT4gWyBdLCBfZmlsZSA9PiAnVW5rbm93bicgfSwgJGNsYXNzOwoKICAgIGlmIChAXykgewogICAgICAgIHVubGVzcyAoICRvYmotPnJlYWQoIEBfICkgKSB7CiAgICAgICAgICAgICRvYmotPl9lcnJvcihxcVtObyBkYXRhIGNvdWxkIGJlIHJlYWQgZnJvbSBmaWxlXSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuICRvYmo7Cn0KCj1oZWFkMiAkdGFyLT5yZWFkICggJGZpbGVuYW1lfCRoYW5kbGUsICRjb21wcmVzc2VkLCB7b3B0ID0+ICd2YWwnfSApCgpSZWFkIHRoZSBnaXZlbiB0YXIgZmlsZSBpbnRvIG1lbW9yeS4KVGhlIGZpcnN0IGFyZ3VtZW50IGNhbiBlaXRoZXIgYmUgdGhlIG5hbWUgb2YgYSBmaWxlIG9yIGEgcmVmZXJlbmNlIHRvCmFuIGFscmVhZHkgb3BlbiBmaWxlaGFuZGxlIChvciBhbiBJTzo6WmxpYiBvYmplY3QgaWYgaXQncyBjb21wcmVzc2VkKQpUaGUgc2Vjb25kIGFyZ3VtZW50IGluZGljYXRlcyB3aGV0aGVyIHRoZSBmaWxlIHJlZmVyZW5jZWQgYnkgdGhlIGZpcnN0CmFyZ3VtZW50IGlzIGNvbXByZXNzZWQuCgpUaGUgQzxyZWFkPiB3aWxsIEk8cmVwbGFjZT4gYW55IHByZXZpb3VzIGNvbnRlbnQgaW4gQzwkdGFyPiEKClRoZSBzZWNvbmQgYXJndW1lbnQgbWF5IGJlIGNvbnNpZGVyZWQgb3B0aW9uYWwgaWYgSU86OlpsaWIgaXMKaW5zdGFsbGVkLCBzaW5jZSBpdCB3aWxsIHRyYW5zcGFyZW50bHkgRG8gVGhlIFJpZ2h0IFRoaW5nLgpBcmNoaXZlOjpUYXIgd2lsbCB3YXJuIGlmIHlvdSB0cnkgdG8gcGFzcyBhIGNvbXByZXNzZWQgZmlsZSBpZgpJTzo6WmxpYiBpcyBub3QgYXZhaWxhYmxlIGFuZCBzaW1wbHkgcmV0dXJuLgoKTm90ZSB0aGF0IHlvdSBjYW4gY3VycmVudGx5IEI8bm90PiBwYXNzIGEgQzxnemlwPiBjb21wcmVzc2VkCmZpbGVoYW5kbGUsIHdoaWNoIGlzIG5vdCBvcGVuZWQgd2l0aCBDPElPOjpabGliPiwgbm9yIGEgc3RyaW5nCmNvbnRhaW5pbmcgdGhlIGZ1bGwgYXJjaGl2ZSBpbmZvcm1hdGlvbiAoZWl0aGVyIGNvbXByZXNzZWQgb3IKdW5jb21wcmVzc2VkKS4gVGhlc2UgYXJlIHdvcnRoIHdoaWxlIGZlYXR1cmVzLCBidXQgbm90IGN1cnJlbnRseQppbXBsZW1lbnRlZC4gU2VlIHRoZSBDPFRPRE8+IHNlY3Rpb24uCgpUaGUgdGhpcmQgYXJndW1lbnQgY2FuIGJlIGEgaGFzaCByZWZlcmVuY2Ugd2l0aCBvcHRpb25zLiBOb3RlIHRoYXQKYWxsIG9wdGlvbnMgYXJlIGNhc2Utc2Vuc2l0aXZlLgoKPW92ZXIgNAoKPWl0ZW0gbGltaXQKCkRvIG5vdCByZWFkIG1vcmUgdGhhbiBDPGxpbWl0PiBmaWxlcy4gVGhpcyBpcyB1c2VmdWwgaWYgeW91IGhhdmUKdmVyeSBiaWcgYXJjaGl2ZXMsIGFuZCBhcmUgb25seSBpbnRlcmVzdGVkIGluIHRoZSBmaXJzdCBmZXcgZmlsZXMuCgo9aXRlbSBleHRyYWN0CgpJZiBzZXQgdG8gdHJ1ZSwgaW1tZWRpYXRlbHkgZXh0cmFjdCBlbnRyaWVzIHdoZW4gcmVhZGluZyB0aGVtLiBUaGlzCmdpdmVzIHlvdSB0aGUgc2FtZSBtZW1vcnkgYnJlYWsgYXMgdGhlIEM8ZXh0cmFjdF9hcmNoaXZlPiBmdW5jdGlvbi4KTm90ZSBob3dldmVyIHRoYXQgZW50cmllcyB3aWxsIG5vdCBiZSByZWFkIGludG8gbWVtb3J5LCBidXQgd3JpdHRlbgpzdHJhaWdodCB0byBkaXNrLgoKPWJhY2sKCkFsbCBmaWxlcyBhcmUgc3RvcmVkIGludGVybmFsbHkgYXMgQzxBcmNoaXZlOjpUYXI6OkZpbGU+IG9iamVjdHMuClBsZWFzZSBjb25zdWx0IHRoZSBMPEFyY2hpdmU6OlRhcjo6RmlsZT4gZG9jdW1lbnRhdGlvbiBmb3IgZGV0YWlscy4KClJldHVybnMgdGhlIG51bWJlciBvZiBmaWxlcyByZWFkIGluIHNjYWxhciBjb250ZXh0LCBhbmQgYSBsaXN0IG9mCkM8QXJjaGl2ZTo6VGFyOjpGaWxlPiBvYmplY3RzIGluIGxpc3QgY29udGV4dC4KCj1jdXQKCnN1YiByZWFkIHsKICAgIG15ICRzZWxmID0gc2hpZnQ7CiAgICBteSAkZmlsZSA9IHNoaWZ0OwogICAgbXkgJGd6aXAgPSBzaGlmdCB8fCAwOwogICAgbXkgJG9wdHMgPSBzaGlmdCB8fCB7fTsKCiAgICB1bmxlc3MoIGRlZmluZWQgJGZpbGUgKSB7CiAgICAgICAgJHNlbGYtPl9lcnJvciggcXFbTm8gZmlsZSB0byByZWFkIGZyb20hXSApOwogICAgICAgIHJldHVybjsKICAgIH0gZWxzZSB7CiAgICAgICAgJHNlbGYtPl9maWxlKCAkZmlsZSApOwogICAgfQoKICAgIG15ICRoYW5kbGUgPSAkc2VsZi0+X2dldF9oYW5kbGUoJGZpbGUsICRnemlwLCBSRUFEX09OTFktPiggWkxJQiApICkKICAgICAgICAgICAgICAgICAgICBvciByZXR1cm47CgogICAgbXkgJGRhdGEgPSAkc2VsZi0+X3JlYWRfdGFyKCAkaGFuZGxlLCAkb3B0cyApIG9yIHJldHVybjsKCiAgICAkc2VsZi0+X2RhdGEoICRkYXRhICk7CgogICAgcmV0dXJuIHdhbnRhcnJheSA/IEAkZGF0YSA6IHNjYWxhciBAJGRhdGE7Cn0KCnN1YiBfZ2V0X2hhbmRsZSB7CiAgICBteSAkc2VsZiA9IHNoaWZ0OwogICAgbXkgJGZpbGUgPSBzaGlmdDsgICByZXR1cm4gdW5sZXNzIGRlZmluZWQgJGZpbGU7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAkZmlsZSBpZiByZWYgJGZpbGU7CgogICAgbXkgJGd6aXAgPSBzaGlmdCB8fCAwOwogICAgbXkgJG1vZGUgPSBzaGlmdCB8fCBSRUFEX09OTFktPiggWkxJQiApOyAjIGRlZmF1bHQgdG8gcmVhZCBvbmx5CgogICAgbXkgJGZoOyBteSAkYmluOwoKICAgICMjIyBvbmx5IGRlZmF1bHQgdG8gWkxJQiBpZiB3ZSdyZSBub3QgdHJ5aW5nIHRvIC93cml0ZS8gdG8gYSBoYW5kbGUgIyMjCiAgICBpZiggWkxJQiBhbmQgJGd6aXAgfHwgTU9ERV9SRUFELT4oICRtb2RlICkgKSB7CgogICAgICAgICMjIyBJTzo6WmxpYiB3aWxsIERvIFRoZSBSaWdodCBUaGluZywgZXZlbiB3aGVuIHBhc3NlZAogICAgICAgICMjIyBhIHBsYWluIGZpbGUgIyMjCiAgICAgICAgJGZoID0gbmV3IElPOjpabGliOwoKICAgIH0gZWxzZSB7CiAgICAgICAgaWYoICRnemlwICkgewogICAgICAgICAgICAkc2VsZi0+X2Vycm9yKHFxW0NvbXByZXNzaW9uIG5vdCBhdmFpbGFibGUgLSBJbnN0YWxsIElPOjpabGliIV0pOwogICAgICAgICAgICByZXR1cm47CgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICRmaCA9IG5ldyBJTzo6RmlsZTsKICAgICAgICAgICAgJGJpbisrOwogICAgICAgIH0KICAgIH0KCiAgICB1bmxlc3MoICRmaC0+b3BlbiggJGZpbGUsICRtb2RlICkgKSB7CiAgICAgICAgJHNlbGYtPl9lcnJvciggcXFbQ291bGQgbm90IGNyZWF0ZSBmaWxlaGFuZGxlIGZvciAnJGZpbGUnOiAkISFdICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGJpbm1vZGUgJGZoIGlmICRiaW47CgogICAgcmV0dXJuICRmaDsKfQoKc3ViIF9yZWFkX3RhciB7CiAgICBteSAkc2VsZiAgICA9IHNoaWZ0OwogICAgbXkgJGhhbmRsZSAgPSBzaGlmdCBvciByZXR1cm47CiAgICBteSAkb3B0cyAgICA9IHNoaWZ0IHx8IHt9OwoKICAgIG15ICRjb3VudCAgID0gJG9wdHMtPntsaW1pdH0gICAgfHwgMDsKICAgIG15ICRleHRyYWN0ID0gJG9wdHMtPntleHRyYWN0fSAgfHwgMDsKCiAgICAjIyMgc2V0IGEgY2FwIG9uIHRoZSBhbW91bnQgb2YgZmlsZXMgdG8gZXh0cmFjdCAjIyMKICAgIG15ICRsaW1pdCAgID0gMDsKICAgICRsaW1pdCA9IDEgaWYgJGNvdW50ID4gMDsKCiAgICBteSAkdGFyZmlsZSA9IFsgXTsKICAgIG15ICRjaHVuazsKICAgIG15ICRyZWFkID0gMDsKICAgIG15ICRyZWFsX25hbWU7ICAjIHRvIHNldCB0aGUgbmFtZSBvZiBhIGZpbGUgd2hlbgogICAgICAgICAgICAgICAgICAgICMgd2UncmUgZW5jb3VudGVyaW5nIEBsb25nbGluawogICAgbXkgJGRhdGE7CgogICAgTE9PUDoKICAgIHdoaWxlKCAkaGFuZGxlLT5yZWFkKCAkY2h1bmssIEhFQUQgKSApIHsKICAgICAgICAjIyMgSU86OlpsaWIgZG9lc24ndCBzdXBwb3J0IHRoaXMgeWV0CiAgICAgICAgbXkgJG9mZnNldCA9IGV2YWwgeyB0ZWxsICRoYW5kbGUgfSB8fCAndW5rbm93bic7CgogICAgICAgIHVubGVzcyggJHJlYWQrKyApIHsKICAgICAgICAgICAgbXkgJGd6aXAgPSBHWklQX01BR0lDX05VTTsKICAgICAgICAgICAgaWYoICRjaHVuayA9fiAvJGd6aXAvICkgewogICAgICAgICAgICAgICAgJHNlbGYtPl9lcnJvciggcXFbQ2Fubm90IHJlYWQgY29tcHJlc3NlZCBmb3JtYXQgaW4gdGFyLW1vZGVdICk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMjIyBpZiB3ZSBjYW4ndCByZWFkIGluIGFsbCBieXRlcy4uLiAjIyMKICAgICAgICBsYXN0IGlmIGxlbmd0aCAkY2h1bmsgIT0gSEVBRDsKCiAgICAgICAgIyMjIEFwcGFyZW50bHkgdGhpcyBzaG91bGQgcmVhbGx5IGJlIHR3byBibG9ja3Mgb2YgNTEyIHplcm9lcywKICAgICAgICAjIyMgYnV0IEdOVSB0YXIgc29tZXRpbWVzIGdldHMgaXQgd3JvbmcuIFNlZSBjb21tZW50IGluIHRoZQogICAgICAgICMjIyBzb3VyY2UgY29kZSAodGFyLmMpIHRvIEdOVSBjcGlvLgogICAgICAgIG5leHQgaWYgJGNodW5rIGVxIFRBUl9FTkQ7CgogICAgICAgICMjIyBhY2NvcmRpbmcgdG8gdGhlIHBvc2l4IHNwZWMsIHRoZSBsYXN0IDEyIGJ5dGVzIG9mIHRoZSBoZWFkZXIgYXJlCiAgICAgICAgIyMjIG51bGwgYnl0ZXMsIHRvIHBhZCBpdCB0byBhIDUxMiBieXRlIGJsb2NrLiBUaGF0IG1lYW5zIGlmIHRoZXNlCiAgICAgICAgIyMjIGJ5dGVzIGFyZSBOT1QgbnVsbCBieXRlcywgaXQncyBhIGNvcnJydXB0IGhlYWRlci4gU2VlOgogICAgICAgICMjIyB3d3cua29kZXJzLmNvbS9jL2ZpZENFNDczQUQzRDlGODM1RDY5MDI1OUQ2MEFENTY1NDU5MUQ5MUQ1QkEuYXNweAogICAgICAgICMjIyBsaW5lIDExMQogICAgICAgIHsgICBteSAkbnVsbHMgPSBqb2luICcnLCAiXDAiIHggMTI7CiAgICAgICAgICAgIHVubGVzcyggJG51bGxzIGVxIHN1YnN0ciggJGNodW5rLCA1MDAsIDEyICkgKSB7CiAgICAgICAgICAgICAgICAkc2VsZi0+X2Vycm9yKCBxcVtJbnZhbGlkIGhlYWRlciBibG9jayBhdCBvZmZzZXQgJG9mZnNldF0gKTsKICAgICAgICAgICAgICAgIG5leHQgTE9PUDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyMjIHBhc3MgdGhlIHJlYWxuYW1lLCBzbyB3ZSBjYW4gc2V0IGl0ICdwcm9wZXInIHJpZ2h0IGF3YXkKICAgICAgICAjIyMgc29tZSBvZiB0aGUgaGV1cmlzdGljcyBhcmUgZG9uZSBvbiB0aGUgbmFtZSwgc28gaW1wb3J0YW50CiAgICAgICAgIyMjIHRvIHNldCBpdCBBU0FQCiAgICAgICAgbXkgJGVudHJ5OwogICAgICAgIHsgICBteSAlZXh0cmFfYXJncyA9ICgpOwogICAgICAgICAgICAkZXh0cmFfYXJnc3snbmFtZSd9ID0gJCRyZWFsX25hbWUgaWYgZGVmaW5lZCAkcmVhbF9uYW1lOwogICAgICAgICAgICAKICAgICAgICAgICAgdW5sZXNzKCAkZW50cnkgPSBBcmNoaXZlOjpUYXI6OkZpbGUtPm5ldyggICBjaHVuayA9PiAkY2h1bmssIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICVleHRyYV9hcmdzICkgCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgJHNlbGYtPl9lcnJvciggcXFbQ291bGRuJ3QgcmVhZCBjaHVuayBhdCBvZmZzZXQgJG9mZnNldF0gKTsKICAgICAgICAgICAgICAgIG5leHQgTE9PUDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgIyMjIGlnbm9yZSBsYWJlbHM6CiAgICAgICAgIyMjIGh0dHA6Ly93d3cuZ251Lm9yZy9tYW51YWwvdGFyL2h0bWxfbm9kZS90YXJfMTM5Lmh0bWwKICAgICAgICBuZXh0IGlmICRlbnRyeS0+aXNfbGFiZWw7CgogICAgICAgIGlmKCBsZW5ndGggJGVudHJ5LT50eXBlIGFuZCAoJGVudHJ5LT5pc19maWxlIHx8ICRlbnRyeS0+aXNfbG9uZ2xpbmspICkgewoKICAgICAgICAgICAgaWYgKCAkZW50cnktPmlzX2ZpbGUgJiYgISRlbnRyeS0+dmFsaWRhdGUgKSB7CiAgICAgICAgICAgICAgICAjIyMgc29tZXRpbWVzIHRoZSBjaHVuayBpcyByYXRoZXIgZnV4MHIzZCBhbmQgYSB3aG9sZSA1MTIKICAgICAgICAgICAgICAgICMjIyBieXRlcyBlbmRzIHVwIGluIHRoZSAtPm5hbWUgYXJlYS4KICAgICAgICAgICAgICAgICMjIyBjbGVhbiBpdCB1cCwgaWYgbmVlZCBiZQogICAgICAgICAgICAgICAgbXkgJG5hbWUgPSAkZW50cnktPm5hbWU7CiAgICAgICAgICAgICAgICAkbmFtZSA9IHN1YnN0cigkbmFtZSwgMCwgMTAwKSBpZiBsZW5ndGggJG5hbWUgPiAxMDA7CiAgICAgICAgICAgICAgICAkbmFtZSA9fiBzL1xuLyAvZzsKCiAgICAgICAgICAgICAgICAkc2VsZi0+X2Vycm9yKCAkbmFtZSAuIHFxWzogY2hlY2tzdW0gZXJyb3JdICk7CiAgICAgICAgICAgICAgICBuZXh0IExPT1A7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIG15ICRibG9jayA9IEJMT0NLX1NJWkUtPiggJGVudHJ5LT5zaXplICk7CgogICAgICAgICAgICAkZGF0YSA9ICRlbnRyeS0+Z2V0X2NvbnRlbnRfYnlfcmVmOwoKICAgICAgICAgICAgIyMjIGp1c3QgcmVhZCBldmVyeXRoaW5nIGludG8gbWVtb3J5CiAgICAgICAgICAgICMjIyBjYW4ndCBkbyBsYXp5IGxvYWRpbmcgc2luY2UgSU86OlpsaWIgZG9lc24ndCBzdXBwb3J0ICdzZWVrJwogICAgICAgICAgICAjIyMgdGhpcyBpcyBiZWNhdXNlIENvbXByZXNzOjpabGliIGRvZXNuJ3Qgc3VwcG9ydCBpdCA9LwogICAgICAgICAgICAjIyMgdGhpcyByZWFkcyBpbiB0aGUgd2hvbGUgZGF0YSBpbiBvbmUgcmVhZCgpIGNhbGwuCiAgICAgICAgICAgIGlmKCAkaGFuZGxlLT5yZWFkKCAkJGRhdGEsICRibG9jayApIDwgJGJsb2NrICkgewogICAgICAgICAgICAgICAgJHNlbGYtPl9lcnJvciggcXFbUmVhZCBlcnJvciBvbiB0YXJmaWxlIChtaXNzaW5nIGRhdGEpICddLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZW50cnktPmZ1bGxfcGF0aCAuIicgYXQgb2Zmc2V0ICRvZmZzZXQiICk7CiAgICAgICAgICAgICAgICBuZXh0IExPT1A7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICMjIyB0aHJvdyBhd2F5IHRyYWlsaW5nIGdhcmJhZ2UgIyMjCiAgICAgICAgICAgIHN1YnN0ciAoJCRkYXRhLCAkZW50cnktPnNpemUpID0gIiIgaWYgZGVmaW5lZCAkJGRhdGE7CgogICAgICAgICAgICAjIyMgcGFydCBJSSBvZiB0aGUgQExvbmdMaW5rIG11bmdpbmcgLS0gbmVlZCB0byBkbyAvYWZ0ZXIvCiAgICAgICAgICAgICMjIyB0aGUgY2hlY2tzdW0gY2hlY2suCiAgICAgICAgICAgIGlmKCAkZW50cnktPmlzX2xvbmdsaW5rICkgewogICAgICAgICAgICAgICAgIyMjIHdlaXJkIHRoaW5nIGluIHRhcmZpbGVzIC0tIGlmIHRoZSBmaWxlIGlzIGFjdHVhbGx5IGEKICAgICAgICAgICAgICAgICMjIyBATG9uZ0xpbmssIHRoZSBkYXRhIHBhcnQgc2VlbXMgdG8gaGF2ZSBhIHRyYWlsaW5nIF5ACiAgICAgICAgICAgICAgICAjIyMgKHVucHJpbnRhYmxlKSBjaGFyLiB0byBkaXNwbGF5LCBwaXBlIG91dHB1dCB0aHJvdWdoIGxlc3MuCiAgICAgICAgICAgICAgICAjIyMgYnV0IHRoYXQgZG9lc24ndCAqYWx3YXlzKiBoYXBwZW4uLiBzbyBjaGVjayBpZiB0aGUgbGFzdAogICAgICAgICAgICAgICAgIyMjIGNoYXJhY3RlciBpcyBhIGNvbnRyb2wgY2hhcmFjdGVyLCBhbmQgaWYgc28gcmVtb3ZlIGl0CiAgICAgICAgICAgICAgICAjIyMgYXQgYW55IHJhdGUsIHdlIGJldHRlciByZW1vdmUgdGhhdCBjaGFyYWN0ZXIgaGVyZSwgb3IgdGVzdHMKICAgICAgICAgICAgICAgICMjIyBsaWtlICdlcScgYW5kIGhhc2hsb29rIHVwcyBiYXNlZCBvbiBuYW1lcyB3aWxsIFNPIG5vdCB3b3JrCiAgICAgICAgICAgICAgICAjIyMgcmVtb3ZlIGl0IGJ5IGNhbGN1bGF0aW5nIHRoZSBwcm9wZXIgc2l6ZSwgYW5kIHRoZW4KICAgICAgICAgICAgICAgICMjIyB0b3NzaW5nIG91dCBldmVyeXRoaW5nIHRoYXQncyBsb25nZXIgdGhhbiB0aGF0IHNpemUuCgogICAgICAgICAgICAgICAgIyMjIGNvdW50IG51bWJlciBvZiBudWxscwogICAgICAgICAgICAgICAgbXkgJG51bGxzID0gJCRkYXRhID1+IHRyL1wwL1wwLzsKCiAgICAgICAgICAgICAgICAjIyMgY3V0IGRhdGEgKyBzaXplIGJ5IHRoYXQgbWFueSBieXRlcwogICAgICAgICAgICAgICAgJGVudHJ5LT5zaXplKCAkZW50cnktPnNpemUgLSAkbnVsbHMgKTsKICAgICAgICAgICAgICAgIHN1YnN0ciAoJCRkYXRhLCAkZW50cnktPnNpemUpID0gIiI7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMjIyBjbGVhbiB1cCBvZiB0aGUgZW50cmllcy4uIHBvc2l4IHRhciAvYXBwYXJlbnRseS8gaGFzIHNvbWUKICAgICAgICAjIyMgd2VpcmQgJ2ZlYXR1cmUnIHRoYXQgYWxsb3dzIGZvciBmaWxlbmFtZXMgPiAyNTUgY2hhcmFjdGVycwogICAgICAgICMjIyB0aGV5J2xsIHB1dCBhIGhlYWRlciBpbiB3aXRoIGFzIG5hbWUgJy4vLi9ATG9uZ0xpbmsnIGFuZCB0aGUKICAgICAgICAjIyMgY29udGVudHMgd2lsbCBiZSB0aGUgbmFtZSBvZiB0aGUgL25leHQvIGZpbGUgaW4gdGhlIGFyY2hpdmUKICAgICAgICAjIyMgcHJldHR5IGNyYXBweSBhbmQga2x1ZGd5IGlmIHlvdSBhc2sgbWUKCiAgICAgICAgIyMjIHNldCB0aGUgbmFtZSBmb3IgdGhlIG5leHQgZW50cnkgaWYgdGhpcyBpcyBhIEBMb25nTGluazsKICAgICAgICAjIyMgdGhpcyBpcyBvbmUgdWdseSBoYWNrID0vIGJ1dCBuZWVkZWQgZm9yIGRpcmVjdCBleHRyYWN0aW9uCiAgICAgICAgaWYoICRlbnRyeS0+aXNfbG9uZ2xpbmsgKSB7CiAgICAgICAgICAgICRyZWFsX25hbWUgPSAkZGF0YTsKICAgICAgICAgICAgbmV4dCBMT09QOwogICAgICAgIH0gZWxzaWYgKCBkZWZpbmVkICRyZWFsX25hbWUgKSB7CiAgICAgICAgICAgICRlbnRyeS0+bmFtZSggJCRyZWFsX25hbWUgKTsKICAgICAgICAgICAgJGVudHJ5LT5wcmVmaXgoJycpOwogICAgICAgICAgICB1bmRlZiAkcmVhbF9uYW1lOwogICAgICAgIH0KCiAgICAgICAgJHNlbGYtPl9leHRyYWN0X2ZpbGUoICRlbnRyeSApIGlmICRleHRyYWN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgISRlbnRyeS0+aXNfbG9uZ2xpbmsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiAhJGVudHJ5LT5pc191bmtub3duCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJiYgISRlbnRyeS0+aXNfbGFiZWw7CgogICAgICAgICMjIyBHdWFyZCBhZ2FpbnN0IHRhcmZpbGVzIHdpdGggZ2FyYmFnZSBhdCB0aGUgZW5kCgkgICAgbGFzdCBMT09QIGlmICRlbnRyeS0+bmFtZSBlcSAnJzsKCiAgICAgICAgIyMjIHB1c2ggb25seSB0aGUgbmFtZSBvbiB0aGUgcnYgaWYgd2UncmUgZXh0cmFjdGluZwogICAgICAgICMjIyAtLSBmb3IgZXh0cmFjdF9hcmNoaXZlCiAgICAgICAgcHVzaCBAJHRhcmZpbGUsICgkZXh0cmFjdCA/ICRlbnRyeS0+bmFtZSA6ICRlbnRyeSk7CgogICAgICAgIGlmKCAkbGltaXQgKSB7CiAgICAgICAgICAgICRjb3VudC0tIHVubGVzcyAkZW50cnktPmlzX2xvbmdsaW5rIHx8ICRlbnRyeS0+aXNfZGlyOwogICAgICAgICAgICBsYXN0IExPT1AgdW5sZXNzICRjb3VudDsKICAgICAgICB9CiAgICB9IGNvbnRpbnVlIHsKICAgICAgICB1bmRlZiAkZGF0YTsKICAgIH0KCiAgICByZXR1cm4gJHRhcmZpbGU7Cn0KCj1oZWFkMiAkdGFyLT5jb250YWluc19maWxlKCAkZmlsZW5hbWUgKQoKQ2hlY2sgaWYgdGhlIGFyY2hpdmUgY29udGFpbnMgYSBjZXJ0YWluIGZpbGUuCkl0IHdpbGwgcmV0dXJuIHRydWUgaWYgdGhlIGZpbGUgaXMgaW4gdGhlIGFyY2hpdmUsIGZhbHNlIG90aGVyd2lzZS4KCk5vdGUgaG93ZXZlciwgdGhhdCB0aGlzIGZ1bmN0aW9uIGRvZXMgYW4gZXhhY3QgbWF0Y2ggdXNpbmcgQzxlcT4Kb24gdGhlIGZ1bGwgcGF0aC4gU28gaXQgY2Fubm90IGNvbXBlbnNhdGUgZm9yIGNhc2UtaW5zZW5zaXRpdmUgZmlsZS0Kc3lzdGVtcyBvciBjb21wYXJlIDIgcGF0aHMgdG8gc2VlIGlmIHRoZXkgd291bGQgcG9pbnQgdG8gdGhlIHNhbWUKdW5kZXJseWluZyBmaWxlLgoKPWN1dAoKc3ViIGNvbnRhaW5zX2ZpbGUgewogICAgbXkgJHNlbGYgPSBzaGlmdDsKICAgIG15ICRmdWxsID0gc2hpZnQ7CiAgICAKICAgIHJldHVybiB1bmxlc3MgZGVmaW5lZCAkZnVsbDsKCiAgICAjIyMgZG9uJ3Qgd2FybiBpZiB0aGUgZW50cnkgaXNuJ3QgdGhlcmUuLiB0aGF0J3Mgd2hhdCB0aGlzIGZ1bmN0aW9uCiAgICAjIyMgaXMgZm9yIGFmdGVyIGFsbC4KICAgIGxvY2FsICRXQVJOID0gMDsKICAgIHJldHVybiAxIGlmICRzZWxmLT5fZmluZF9lbnRyeSgkZnVsbCk7CiAgICByZXR1cm47Cn0KCj1oZWFkMiAkdGFyLT5leHRyYWN0KCBbQGZpbGVuYW1lc10gKQoKV3JpdGUgZmlsZXMgd2hvc2UgbmFtZXMgYXJlIGVxdWl2YWxlbnQgdG8gYW55IG9mIHRoZSBuYW1lcyBpbgpDPEBmaWxlbmFtZXM+IHRvIGRpc2ssIGNyZWF0aW5nIHN1YmRpcmVjdG9yaWVzIGFzIG5lY2Vzc2FyeS4gVGhpcwptaWdodCBub3Qgd29yayB0b28gd2VsbCB1bmRlciBWTVMuClVuZGVyIE1hY1BlcmwsIHRoZSBmaWxlJ3MgbW9kaWZpY2F0aW9uIHRpbWUgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gdGhlCk1hY09TIHplcm8gb2YgdGltZSwgYW5kIGFwcHJvcHJpYXRlIGNvbnZlcnNpb25zIHdpbGwgYmUgZG9uZSB0byB0aGUKcGF0aC4gIEhvd2V2ZXIsIHRoZSBsZW5ndGggb2YgZWFjaCBlbGVtZW50IG9mIHRoZSBwYXRoIGlzIG5vdAppbnNwZWN0ZWQgdG8gc2VlIHdoZXRoZXIgaXQncyBsb25nZXIgdGhhbiBNYWNPUyBjdXJyZW50bHkgYWxsb3dzICgzMgpjaGFyYWN0ZXJzKS4KCklmIEM8ZXh0cmFjdD4gaXMgY2FsbGVkIHdpdGhvdXQgYSBsaXN0IG9mIGZpbGUgbmFtZXMsIHRoZSBlbnRpcmUKY29udGVudHMgb2YgdGhlIGFyY2hpdmUgYXJlIGV4dHJhY3RlZC4KClJldHVybnMgYSBsaXN0IG9mIGZpbGVuYW1lcyBleHRyYWN0ZWQuCgo9Y3V0CgpzdWIgZXh0cmFjdCB7CiAgICBteSAkc2VsZiAgICA9IHNoaWZ0OwogICAgbXkgQGFyZ3MgICAgPSBAXzsKICAgIG15IEBmaWxlczsKCiAgICAjIHVzZSB0aGUgc3BlZWQgb3B0aW1pemF0aW9uIGZvciBhbGwgZXh0cmFjdGVkIGZpbGVzCiAgICBsb2NhbCgkc2VsZi0+e2N3ZH0pID0gY3dkKCkgdW5sZXNzICRzZWxmLT57Y3dkfTsKCiAgICAjIyMgeW91IHJlcXVlc3RlZCB0aGUgZXh0cmFjdGlvbiBvZiBvbmx5IGNlcnRpYW4gZmlsZXMKICAgIGlmKCBAYXJncyApIHsKICAgICAgICBmb3IgbXkgJGZpbGUgKCBAYXJncyApIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICMjIyBpdCdzIGFscmVhZHkgYW4gb2JqZWN0PwogICAgICAgICAgICBpZiggVU5JVkVSU0FMOjppc2EoICRmaWxlLCAnQXJjaGl2ZTo6VGFyOjpGaWxlJyApICkgewogICAgICAgICAgICAgICAgcHVzaCBAZmlsZXMsICRmaWxlOwogICAgICAgICAgICAgICAgbmV4dDsKCiAgICAgICAgICAgICMjIyBnbyBmaW5kIGl0IHRoZW4KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBteSAkZm91bmQ7CiAgICAgICAgICAgICAgICBmb3IgbXkgJGVudHJ5ICggQHskc2VsZi0+X2RhdGF9ICkgewogICAgICAgICAgICAgICAgICAgIG5leHQgdW5sZXNzICRmaWxlIGVxICRlbnRyeS0+ZnVsbF9wYXRoOwogICAgCiAgICAgICAgICAgICAgICAgICAgIyMjIHdlIGZvdW5kIHRoZSBmaWxlIHlvdSdyZSBsb29raW5nIGZvcgogICAgICAgICAgICAgICAgICAgIHB1c2ggQGZpbGVzLCAkZW50cnk7CiAgICAgICAgICAgICAgICAgICAgJGZvdW5kKys7CiAgICAgICAgICAgICAgICB9CiAgICAKICAgICAgICAgICAgICAgIHVubGVzcyggJGZvdW5kICkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAkc2VsZi0+X2Vycm9yKCAKICAgICAgICAgICAgICAgICAgICAgICAgcXFbQ291bGQgbm90IGZpbmQgJyRmaWxlJyBpbiBhcmNoaXZlXSApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICMjIyBqdXN0IGdyYWIgYWxsIHRoZSBmaWxlIGl0ZW1zCiAgICB9IGVsc2UgewogICAgICAgIEBmaWxlcyA9ICRzZWxmLT5nZXRfZmlsZXM7CiAgICB9CgogICAgIyMjIG5vdGhpbmcgZm91bmQ/IHRoYXQncyBhbiBlcnJvcgogICAgdW5sZXNzKCBzY2FsYXIgQGZpbGVzICkgewogICAgICAgICRzZWxmLT5fZXJyb3IoIHFxW05vIGZpbGVzIGZvdW5kIGZvciBdIC4gJHNlbGYtPl9maWxlICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMjIyBub3cgZXh0cmFjdCB0aGVtCiAgICBmb3IgbXkgJGVudHJ5ICggQGZpbGVzICkgewogICAgICAgIHVubGVzcyggJHNlbGYtPl9leHRyYWN0X2ZpbGUoICRlbnRyeSApICkgewogICAgICAgICAgICAkc2VsZi0+X2Vycm9yKHFbQ291bGQgbm90IGV4dHJhY3QgJ10uICRlbnRyeS0+ZnVsbF9wYXRoIC5xWyddICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIEBmaWxlczsKfQoKPWhlYWQyICR0YXItPmV4dHJhY3RfZmlsZSggJGZpbGUsIFskZXh0cmFjdF9wYXRoXSApCgpXcml0ZSBhbiBlbnRyeSwgd2hvc2UgbmFtZSBpcyBlcXVpdmFsZW50IHRvIHRoZSBmaWxlIG5hbWUgcHJvdmlkZWQgdG8KZGlzay4gT3B0aW9uYWxseSB0YWtlcyBhIHNlY29uZCBwYXJhbWV0ZXIsIHdoaWNoIGlzIHRoZSBmdWxsICh1bml4KQpwYXRoIChpbmNsdWRpbmcgZmlsZW5hbWUpIHRoZSBlbnRyeSB3aWxsIGJlIHdyaXR0ZW4gdG8uCgpGb3IgZXhhbXBsZToKCiAgICAkdGFyLT5leHRyYWN0X2ZpbGUoICduYW1lL2luL2FyY2hpdmUnLCAnbmFtZS9pL3dhbnQvdG8vZ2l2ZS9pdCcgKTsKCiAgICAkdGFyLT5leHRyYWN0X2ZpbGUoICRhdF9maWxlX29iamVjdCwgICAnbmFtZS9pL3dhbnQvdG8vZ2l2ZS9pdCcgKTsKClJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzLCBmYWxzZSBvbiBmYWlsdXJlLgoKPWN1dAoKc3ViIGV4dHJhY3RfZmlsZSB7CiAgICBteSAkc2VsZiA9IHNoaWZ0OwogICAgbXkgJGZpbGUgPSBzaGlmdDsgICByZXR1cm4gdW5sZXNzIGRlZmluZWQgJGZpbGU7CiAgICBteSAkYWx0ICA9IHNoaWZ0OwoKICAgIG15ICRlbnRyeSA9ICRzZWxmLT5fZmluZF9lbnRyeSggJGZpbGUgKQogICAgICAgIG9yICRzZWxmLT5fZXJyb3IoIHFxW0NvdWxkIG5vdCBmaW5kIGFuIGVudHJ5IGZvciAnJGZpbGUnXSApLCByZXR1cm47CgogICAgcmV0dXJuICRzZWxmLT5fZXh0cmFjdF9maWxlKCAkZW50cnksICRhbHQgKTsKfQoKc3ViIF9leHRyYWN0X2ZpbGUgewogICAgbXkgJHNlbGYgICAgPSBzaGlmdDsKICAgIG15ICRlbnRyeSAgID0gc2hpZnQgb3IgcmV0dXJuOwogICAgbXkgJGFsdCAgICAgPSBzaGlmdDsKCiAgICAjIyMgeW91IHdhbnRlZCBhbiBhbHRlcm5hdGUgZXh0cmFjdGlvbiBsb2NhdGlvbiAjIyMKICAgIG15ICRuYW1lID0gZGVmaW5lZCAkYWx0ID8gJGFsdCA6ICRlbnRyeS0+ZnVsbF9wYXRoOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyBzcGxpdHBhdGggdGFrZXMgYSBib29sIGF0IHRoZSBlbmQgdG8gaW5kaWNhdGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyB0aGF0IGl0J3Mgc3BsaXR0aW5nIGEgZGlyCiAgICBteSAoJHZvbCwkZGlycywkZmlsZSk7CiAgICBpZiAoIGRlZmluZWQgJGFsdCApIHsgIyBJdCdzIGEgbG9jYWwtT1MgcGF0aAogICAgICAgICgkdm9sLCRkaXJzLCRmaWxlKSA9IEZpbGU6OlNwZWMtPnNwbGl0cGF0aCggICAgICAgJGFsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRlbnRyeS0+aXNfZGlyICk7CiAgICB9IGVsc2UgewogICAgICAgICgkdm9sLCRkaXJzLCRmaWxlKSA9IEZpbGU6OlNwZWM6OlVuaXgtPnNwbGl0cGF0aCggJG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZW50cnktPmlzX2RpciApOwogICAgfQoKICAgIG15ICRkaXI7CiAgICAjIyMgaXMgJG5hbWUgYW4gYWJzb2x1dGUgcGF0aD8gIyMjCiAgICBpZiggRmlsZTo6U3BlYy0+ZmlsZV9uYW1lX2lzX2Fic29sdXRlKCAkZGlycyApICkgewogICAgICAgICRkaXIgPSAkZGlyczsKCiAgICAjIyMgaXQncyBhIHJlbGF0aXZlIHBhdGggIyMjCiAgICB9IGVsc2UgewogICAgICAgIG15ICRjd2QgICAgID0gKGRlZmluZWQgJHNlbGYtPntjd2R9ID8gJHNlbGYtPntjd2R9IDogY3dkKCkpOwogICAgICAgIG15IEBkaXJzICAgID0gRmlsZTo6U3BlYzo6VW5peC0+c3BsaXRkaXIoICRkaXJzICk7CiAgICAgICAgbXkgQGN3ZCAgICAgPSBGaWxlOjpTcGVjLT5zcGxpdGRpciggJGN3ZCApOwogICAgICAgICRkaXIgICAgICAgID0gRmlsZTo6U3BlYy0+Y2F0ZGlyKCBAY3dkLCBAZGlycyApOwoKICAgICAgICAjIGNhdGRpcigpIHJldHVybnMgdW5kZWYgaWYgdGhlIHBhdGggaXMgbG9uZ2VyIHRoYW4gMjU1IGNoYXJzIG9uIFZNUwogICAgICAgIHVubGVzcyAoIGRlZmluZWQgJGRpciApIHsKICAgICAgICAgICAgJF5XICYmICRzZWxmLT5fZXJyb3IoIHFxW0NvdWxkIG5vdCBjb21wb3NlIGEgcGF0aCBmb3IgJyRkaXJzJ1xuXSApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgIH0KCiAgICBpZiggLWUgJGRpciAmJiAhLWQgXyApIHsKICAgICAgICAkXlcgJiYgJHNlbGYtPl9lcnJvciggcXFbJyRkaXInIGV4aXN0cywgYnV0IGl0J3Mgbm90IGEgZGlyZWN0b3J5IVxuXSApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICB1bmxlc3MgKCAtZCBfICkgewogICAgICAgIGV2YWwgeyBGaWxlOjpQYXRoOjpta3BhdGgoICRkaXIsIDAsIDA3NzcgKSB9OwogICAgICAgIGlmKCAkQCApIHsKICAgICAgICAgICAgJHNlbGYtPl9lcnJvciggcXFbQ291bGQgbm90IGNyZWF0ZSBkaXJlY3RvcnkgJyRkaXInOiAkQF0gKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAjIyMgWFhYIGNob3duIGhlcmU/IHRoYXQgbWlnaHQgbm90IGJlIHRoZSBzYW1lIGFzIGluIHRoZSBhcmNoaXZlCiAgICAgICAgIyMjIGFzIHdlJ3JlIG9ubHkgY2hvd24naW5nIHRvIHRoZSBvd25lciBvZiB0aGUgZmlsZSB3ZSdyZSBleHRyYWN0aW5nCiAgICAgICAgIyMjIG5vdCB0byB0aGUgb3duZXIgb2YgdGhlIGRpcmVjdG9yeSBpdHNlbGYsIHdoaWNoIG1heSBvciBtYXkgbm90CiAgICAgICAgIyMjIGJlIGFub3RoZXIgZW50cnkgaW4gdGhlIGFyY2hpdmUKICAgICAgICAjIyMgQW5zd2VyOiBubywgZ251IHRhciBkb2Vzbid0IGRvIGl0IGVpdGhlciwgaXQnZCBiZSB0aGUgd3JvbmcKICAgICAgICAjIyMgd2F5IHRvIGdvLgogICAgICAgICNpZiggJENIT1dOICYmIENBTl9DSE9XTiApIHsKICAgICAgICAjICAgIGNob3duICRlbnRyeS0+dWlkLCAkZW50cnktPmdpZCwgJGRpciBvcgogICAgICAgICMgICAgICAgICRzZWxmLT5fZXJyb3IoIHFxW0NvdWxkIG5vdCBzZXQgdWlkL2dpZCBvbiAnJGRpciddICk7CiAgICAgICAgI30KICAgIH0KCiAgICAjIyMgd2UncmUgZG9uZSBpZiB3ZSBqdXN0IG5lZWRlZCB0byBjcmVhdGUgYSBkaXIgIyMjCiAgICByZXR1cm4gMSBpZiAkZW50cnktPmlzX2RpcjsKCiAgICBteSAkZnVsbCA9IEZpbGU6OlNwZWMtPmNhdGZpbGUoICRkaXIsICRmaWxlICk7CgogICAgaWYoICRlbnRyeS0+aXNfdW5rbm93biApIHsKICAgICAgICAkc2VsZi0+X2Vycm9yKCBxcVtVbmtub3duIGZpbGUgdHlwZSBmb3IgZmlsZSAnJGZ1bGwnXSApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiggbGVuZ3RoICRlbnRyeS0+dHlwZSAmJiAkZW50cnktPmlzX2ZpbGUgKSB7CiAgICAgICAgbXkgJGZoID0gSU86OkZpbGUtPm5ldzsKICAgICAgICAkZmgtPm9wZW4oICc+JyAuICRmdWxsICkgb3IgKAogICAgICAgICAgICAkc2VsZi0+X2Vycm9yKCBxcVtDb3VsZCBub3Qgb3BlbiBmaWxlICckZnVsbCc6ICQhXSApLAogICAgICAgICAgICByZXR1cm4KICAgICAgICApOwoKICAgICAgICBpZiggJGVudHJ5LT5zaXplICkgewogICAgICAgICAgICBiaW5tb2RlICRmaDsKICAgICAgICAgICAgc3lzd3JpdGUgJGZoLCAkZW50cnktPmRhdGEgb3IgKAogICAgICAgICAgICAgICAgJHNlbGYtPl9lcnJvciggcXFbQ291bGQgbm90IHdyaXRlIGRhdGEgdG8gJyRmdWxsJ10gKSwKICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgY2xvc2UgJGZoIG9yICgKICAgICAgICAgICAgJHNlbGYtPl9lcnJvciggcXFbQ291bGQgbm90IGNsb3NlIGZpbGUgJyRmdWxsJ10gKSwKICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgKTsKCiAgICB9IGVsc2UgewogICAgICAgICRzZWxmLT5fbWFrZV9zcGVjaWFsX2ZpbGUoICRlbnRyeSwgJGZ1bGwgKSBvciByZXR1cm47CiAgICB9CgogICAgdXRpbWUgdGltZSwgJGVudHJ5LT5tdGltZSAtIFRJTUVfT0ZGU0VULCAkZnVsbCBvcgogICAgICAgICRzZWxmLT5fZXJyb3IoIHFxW0NvdWxkIG5vdCB1cGRhdGUgdGltZXN0YW1wXSApOwoKICAgIGlmKCAkQ0hPV04gJiYgQ0FOX0NIT1dOICkgewogICAgICAgIGNob3duICRlbnRyeS0+dWlkLCAkZW50cnktPmdpZCwgJGZ1bGwgb3IKICAgICAgICAgICAgJHNlbGYtPl9lcnJvciggcXFbQ291bGQgbm90IHNldCB1aWQvZ2lkIG9uICckZnVsbCddICk7CiAgICB9CgogICAgIyMjIG9ubHkgY2htb2QgaWYgd2UncmUgYWxsb3dlZCB0bywgYnV0IG5ldmVyIGNobW9kIHN5bWxpbmtzLCBzaW5jZSB0aGV5J2xsCiAgICAjIyMgY2hhbmdlIHRoZSBwZXJtcyBvbiB0aGUgZmlsZSB0aGV5J3JlIGxpbmtpbmcgdG9vLi4uCiAgICBpZiggJENITU9EIGFuZCBub3QgLWwgJGZ1bGwgKSB7CiAgICAgICAgY2htb2QgJGVudHJ5LT5tb2RlLCAkZnVsbCBvcgogICAgICAgICAgICAkc2VsZi0+X2Vycm9yKCBxcVtDb3VsZCBub3QgY2hvd24gJyRmdWxsJyB0byBdIC4gJGVudHJ5LT5tb2RlICk7CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCnN1YiBfbWFrZV9zcGVjaWFsX2ZpbGUgewogICAgbXkgJHNlbGYgICAgPSBzaGlmdDsKICAgIG15ICRlbnRyeSAgID0gc2hpZnQgICAgIG9yIHJldHVybjsKICAgIG15ICRmaWxlICAgID0gc2hpZnQ7ICAgIHJldHVybiB1bmxlc3MgZGVmaW5lZCAkZmlsZTsKCiAgICBteSAkZXJyOwoKICAgIGlmKCAkZW50cnktPmlzX3N5bWxpbmsgKSB7CiAgICAgICAgbXkgJGZhaWw7CiAgICAgICAgaWYoIE9OX1VOSVggKSB7CiAgICAgICAgICAgIHN5bWxpbmsoICRlbnRyeS0+bGlua25hbWUsICRmaWxlICkgb3IgJGZhaWwrKzsKCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgJHNlbGYtPl9leHRyYWN0X3NwZWNpYWxfZmlsZV9hc19wbGFpbl9maWxlKCAkZW50cnksICRmaWxlICkKICAgICAgICAgICAgICAgIG9yICRmYWlsKys7CiAgICAgICAgfQoKICAgICAgICAkZXJyID0gIHFxW01ha2luZyBzeW1ib2xpbmsgbGluayBmcm9tICddIC4gJGVudHJ5LT5saW5rbmFtZSAuCiAgICAgICAgICAgICAgICBxcVsnIHRvICckZmlsZScgZmFpbGVkXSBpZiAkZmFpbDsKCiAgICB9IGVsc2lmICggJGVudHJ5LT5pc19oYXJkbGluayApIHsKICAgICAgICBteSAkZmFpbDsKICAgICAgICBpZiggT05fVU5JWCApIHsKICAgICAgICAgICAgbGluayggJGVudHJ5LT5saW5rbmFtZSwgJGZpbGUgKSBvciAkZmFpbCsrOwoKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAkc2VsZi0+X2V4dHJhY3Rfc3BlY2lhbF9maWxlX2FzX3BsYWluX2ZpbGUoICRlbnRyeSwgJGZpbGUgKQogICAgICAgICAgICAgICAgb3IgJGZhaWwrKzsKICAgICAgICB9CgogICAgICAgICRlcnIgPSAgcXFbTWFraW5nIGhhcmQgbGluayBmcm9tICddIC4gJGVudHJ5LT5saW5rbmFtZSAuCiAgICAgICAgICAgICAgICBxcVsnIHRvICckZmlsZScgZmFpbGVkXSBpZiAkZmFpbDsKCiAgICB9IGVsc2lmICggJGVudHJ5LT5pc19maWZvICkgewogICAgICAgIE9OX1VOSVggJiYgIXN5c3RlbSgnbWtub2QnLCAkZmlsZSwgJ3AnKSBvcgogICAgICAgICAgICAkZXJyID0gcXFbTWFraW5nIGZpZm8gJ10uICRlbnRyeS0+bmFtZSAucXFbJyBmYWlsZWRdOwoKICAgIH0gZWxzaWYgKCAkZW50cnktPmlzX2Jsb2NrZGV2IG9yICRlbnRyeS0+aXNfY2hhcmRldiApIHsKICAgICAgICBteSAkbW9kZSA9ICRlbnRyeS0+aXNfYmxvY2tkZXYgPyAnYicgOiAnYyc7CgogICAgICAgIE9OX1VOSVggJiYgIXN5c3RlbSgnbWtub2QnLCAkZmlsZSwgJG1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAkZW50cnktPmRldm1ham9yLCAkZW50cnktPmRldm1pbm9yKSBvcgogICAgICAgICAgICAkZXJyID0gIHFxW01ha2luZyBibG9jayBkZXZpY2UgJ10uICRlbnRyeS0+bmFtZSAucXFbJyAobWFqPV0gLgogICAgICAgICAgICAgICAgICAgICRlbnRyeS0+ZGV2bWFqb3IgLiBxcVsgbWluPV0gLiAkZW50cnktPmRldm1pbm9yIC4KICAgICAgICAgICAgICAgICAgICBxcVspIGZhaWxlZC5dOwoKICAgIH0gZWxzaWYgKCAkZW50cnktPmlzX3NvY2tldCApIHsKICAgICAgICAjIyMgdGhlIG9yaWdpbmFsIGRvZXNuJ3QgZG8gYW55dGhpbmcgc3BlY2lhbCBmb3Igc29ja2V0cy4uLi4gIyMjCiAgICAgICAgMTsKICAgIH0KCiAgICByZXR1cm4gJGVyciA/ICRzZWxmLT5fZXJyb3IoICRlcnIgKSA6IDE7Cn0KCiMjIyBkb24ndCBrbm93IGhvdyB0byBtYWtlIHN5bWxpbmtzLCBsZXQncyBqdXN0IGV4dHJhY3QgdGhlIGZpbGUgYXMKIyMjIGEgcGxhaW4gZmlsZQpzdWIgX2V4dHJhY3Rfc3BlY2lhbF9maWxlX2FzX3BsYWluX2ZpbGUgewogICAgbXkgJHNlbGYgICAgPSBzaGlmdDsKICAgIG15ICRlbnRyeSAgID0gc2hpZnQgICAgIG9yIHJldHVybjsKICAgIG15ICRmaWxlICAgID0gc2hpZnQ7ICAgIHJldHVybiB1bmxlc3MgZGVmaW5lZCAkZmlsZTsKCiAgICBteSAkZXJyOwogICAgVFJZOiB7CiAgICAgICAgbXkgJG9yaWcgPSAkc2VsZi0+X2ZpbmRfZW50cnkoICRlbnRyeS0+bGlua25hbWUgKTsKCiAgICAgICAgdW5sZXNzKCAkb3JpZyApIHsKICAgICAgICAgICAgJGVyciA9ICBxcVtDb3VsZCBub3QgZmluZCBmaWxlICddIC4gJGVudHJ5LT5saW5rbmFtZSAuCiAgICAgICAgICAgICAgICAgICAgcXFbJyBpbiBtZW1vcnkuXTsKICAgICAgICAgICAgbGFzdCBUUlk7CiAgICAgICAgfQoKICAgICAgICAjIyMgY2xvbmUgdGhlIGVudHJ5LCBtYWtlIGl0IGFwcGVhciBhcyBhIG5vcm1hbCBmaWxlICMjIwogICAgICAgIG15ICRjbG9uZSA9ICRlbnRyeS0+Y2xvbmU7CiAgICAgICAgJGNsb25lLT5fZG93bmdyYWRlX3RvX3BsYWluZmlsZTsKICAgICAgICAkc2VsZi0+X2V4dHJhY3RfZmlsZSggJGNsb25lLCAkZmlsZSApIG9yIGxhc3QgVFJZOwoKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICByZXR1cm4gJHNlbGYtPl9lcnJvcigkZXJyKTsKfQoKPWhlYWQyICR0YXItPmxpc3RfZmlsZXMoIFtcQHByb3BlcnRpZXNdICkKClJldHVybnMgYSBsaXN0IG9mIHRoZSBuYW1lcyBvZiBhbGwgdGhlIGZpbGVzIGluIHRoZSBhcmNoaXZlLgoKSWYgQzxsaXN0X2ZpbGVzKCk+IGlzIHBhc3NlZCBhbiBhcnJheSByZWZlcmVuY2UgYXMgaXRzIGZpcnN0IGFyZ3VtZW50Cml0IHJldHVybnMgYSBsaXN0IG9mIGhhc2ggcmVmZXJlbmNlcyBjb250YWluaW5nIHRoZSByZXF1ZXN0ZWQKcHJvcGVydGllcyBvZiBlYWNoIGZpbGUuICBUaGUgZm9sbG93aW5nIGxpc3Qgb2YgcHJvcGVydGllcyBpcwpzdXBwb3J0ZWQ6IG5hbWUsIHNpemUsIG10aW1lIChsYXN0IG1vZGlmaWVkIGRhdGUpLCBtb2RlLCB1aWQsIGdpZCwKbGlua25hbWUsIHVuYW1lLCBnbmFtZSwgZGV2bWFqb3IsIGRldm1pbm9yLCBwcmVmaXguCgpQYXNzaW5nIGFuIGFycmF5IHJlZmVyZW5jZSBjb250YWluaW5nIG9ubHkgb25lIGVsZW1lbnQsICduYW1lJywgaXMKc3BlY2lhbCBjYXNlZCB0byByZXR1cm4gYSBsaXN0IG9mIG5hbWVzIHJhdGhlciB0aGFuIGEgbGlzdCBvZiBoYXNoCnJlZmVyZW5jZXMsIG1ha2luZyBpdCBlcXVpdmFsZW50IHRvIGNhbGxpbmcgQzxsaXN0X2ZpbGVzPiB3aXRob3V0CmFyZ3VtZW50cy4KCj1jdXQKCnN1YiBsaXN0X2ZpbGVzIHsKICAgIG15ICRzZWxmID0gc2hpZnQ7CiAgICBteSAkYXJlZiA9IHNoaWZ0IHx8IFsgXTsKCiAgICB1bmxlc3MoICRzZWxmLT5fZGF0YSApIHsKICAgICAgICAkc2VsZi0+cmVhZCgpIG9yIHJldHVybjsKICAgIH0KCiAgICBpZiggQCRhcmVmID09IDAgb3IgKCBAJGFyZWYgPT0gMSBhbmQgJGFyZWYtPlswXSBlcSAnbmFtZScgKSApIHsKICAgICAgICByZXR1cm4gbWFwIHsgJF8tPmZ1bGxfcGF0aCB9IEB7JHNlbGYtPl9kYXRhfTsKICAgIH0gZWxzZSB7CgogICAgICAgICNteSBAcnY7CiAgICAgICAgI2ZvciBteSAkb2JqICggQHskc2VsZi0+X2RhdGF9ICkgewogICAgICAgICMgICAgcHVzaCBAcnYsIHsgbWFwIHsgJF8gPT4gJG9iai0+JF8oKSB9IEAkYXJlZiB9OwogICAgICAgICN9CiAgICAgICAgI3JldHVybiBAcnY7CgogICAgICAgICMjIyB0aGlzIGRvZXMgdGhlIHNhbWUgYXMgdGhlIGFib3ZlLi4ganVzdCBuZWVkcyBhICt7IH0KICAgICAgICAjIyMgdG8gbWFrZSBzdXJlIHBlcmwgZG9lc24ndCBjb25mdXNlIGl0IGZvciBhIGJsb2NrCiAgICAgICAgcmV0dXJuIG1hcCB7ICAgIG15ICRvPSRfOwogICAgICAgICAgICAgICAgICAgICAgICAreyBtYXAgeyAkXyA9PiAkby0+JF8oKSB9IEAkYXJlZiB9CiAgICAgICAgICAgICAgICAgICAgfSBAeyRzZWxmLT5fZGF0YX07CiAgICB9Cn0KCnN1YiBfZmluZF9lbnRyeSB7CiAgICBteSAkc2VsZiA9IHNoaWZ0OwogICAgbXkgJGZpbGUgPSBzaGlmdDsKCiAgICB1bmxlc3MoIGRlZmluZWQgJGZpbGUgKSB7CiAgICAgICAgJHNlbGYtPl9lcnJvciggcXFbTm8gZmlsZSBzcGVjaWZpZWRdICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMjIyBpdCdzIGFuIG9iamVjdCBhbHJlYWR5CiAgICByZXR1cm4gJGZpbGUgaWYgVU5JVkVSU0FMOjppc2EoICRmaWxlLCAnQXJjaGl2ZTo6VGFyOjpGaWxlJyApOwoKICAgIGZvciBteSAkZW50cnkgKCBAeyRzZWxmLT5fZGF0YX0gKSB7CiAgICAgICAgbXkgJHBhdGggPSAkZW50cnktPmZ1bGxfcGF0aDsKICAgICAgICByZXR1cm4gJGVudHJ5IGlmICRwYXRoIGVxICRmaWxlOwogICAgfQoKICAgICRzZWxmLT5fZXJyb3IoIHFxW05vIHN1Y2ggZmlsZSBpbiBhcmNoaXZlOiAnJGZpbGUnXSApOwogICAgcmV0dXJuOwp9Cgo9aGVhZDIgJHRhci0+Z2V0X2ZpbGVzKCBbQGZpbGVuYW1lc10gKQoKUmV0dXJucyB0aGUgQzxBcmNoaXZlOjpUYXI6OkZpbGU+IG9iamVjdHMgbWF0Y2hpbmcgdGhlIGZpbGVuYW1lcwpwcm92aWRlZC4gSWYgbm8gZmlsZW5hbWUgbGlzdCB3YXMgcGFzc2VkLCBhbGwgQzxBcmNoaXZlOjpUYXI6OkZpbGU+Cm9iamVjdHMgaW4gdGhlIGN1cnJlbnQgVGFyIG9iamVjdCBhcmUgcmV0dXJuZWQuCgpQbGVhc2UgcmVmZXIgdG8gdGhlIEM8QXJjaGl2ZTo6VGFyOjpGaWxlPiBkb2N1bWVudGF0aW9uIG9uIGhvdyB0bwpoYW5kbGUgdGhlc2Ugb2JqZWN0cy4KCj1jdXQKCnN1YiBnZXRfZmlsZXMgewogICAgbXkgJHNlbGYgPSBzaGlmdDsKCiAgICByZXR1cm4gQHsgJHNlbGYtPl9kYXRhIH0gdW5sZXNzIEBfOwoKICAgIG15IEBsaXN0OwogICAgZm9yIG15ICRmaWxlICggQF8gKSB7CiAgICAgICAgcHVzaCBAbGlzdCwgZ3JlcCB7IGRlZmluZWQgfSAkc2VsZi0+X2ZpbmRfZW50cnkoICRmaWxlICk7CiAgICB9CgogICAgcmV0dXJuIEBsaXN0Owp9Cgo9aGVhZDIgJHRhci0+Z2V0X2NvbnRlbnQoICRmaWxlICkKClJldHVybiB0aGUgY29udGVudCBvZiB0aGUgbmFtZWQgZmlsZS4KCj1jdXQKCnN1YiBnZXRfY29udGVudCB7CiAgICBteSAkc2VsZiA9IHNoaWZ0OwogICAgbXkgJGVudHJ5ID0gJHNlbGYtPl9maW5kX2VudHJ5KCBzaGlmdCApIG9yIHJldHVybjsKCiAgICByZXR1cm4gJGVudHJ5LT5kYXRhOwp9Cgo9aGVhZDIgJHRhci0+cmVwbGFjZV9jb250ZW50KCAkZmlsZSwgJGNvbnRlbnQgKQoKTWFrZSB0aGUgc3RyaW5nICRjb250ZW50IGJlIHRoZSBjb250ZW50IGZvciB0aGUgZmlsZSBuYW1lZCAkZmlsZS4KCj1jdXQKCnN1YiByZXBsYWNlX2NvbnRlbnQgewogICAgbXkgJHNlbGYgPSBzaGlmdDsKICAgIG15ICRlbnRyeSA9ICRzZWxmLT5fZmluZF9lbnRyeSggc2hpZnQgKSBvciByZXR1cm47CgogICAgcmV0dXJuICRlbnRyeS0+cmVwbGFjZV9jb250ZW50KCBzaGlmdCApOwp9Cgo9aGVhZDIgJHRhci0+cmVuYW1lKCAkZmlsZSwgJG5ld19uYW1lICkKClJlbmFtZSB0aGUgZmlsZSBvZiB0aGUgaW4tbWVtb3J5IGFyY2hpdmUgdG8gJG5ld19uYW1lLgoKTm90ZSB0aGF0IHlvdSBtdXN0IHNwZWNpZnkgYSBVbml4IHBhdGggZm9yICRuZXdfbmFtZSwgc2luY2UgcGVyIHRhcgpzdGFuZGFyZCwgYWxsIGZpbGVzIGluIHRoZSBhcmNoaXZlIG11c3QgYmUgVW5peCBwYXRocy4KClJldHVybnMgdHJ1ZSBvbiBzdWNjZXNzIGFuZCBmYWxzZSBvbiBmYWlsdXJlLgoKPWN1dAoKc3ViIHJlbmFtZSB7CiAgICBteSAkc2VsZiA9IHNoaWZ0OwogICAgbXkgJGZpbGUgPSBzaGlmdDsgcmV0dXJuIHVubGVzcyBkZWZpbmVkICRmaWxlOwogICAgbXkgJG5ldyAgPSBzaGlmdDsgcmV0dXJuIHVubGVzcyBkZWZpbmVkICRuZXc7CgogICAgbXkgJGVudHJ5ID0gJHNlbGYtPl9maW5kX2VudHJ5KCAkZmlsZSApIG9yIHJldHVybjsKCiAgICByZXR1cm4gJGVudHJ5LT5yZW5hbWUoICRuZXcgKTsKfQoKPWhlYWQyICR0YXItPnJlbW92ZSAoQGZpbGVuYW1lbGlzdCkKClJlbW92ZXMgYW55IGVudHJpZXMgd2l0aCBuYW1lcyBtYXRjaGluZyBhbnkgb2YgdGhlIGdpdmVuIGZpbGVuYW1lcwpmcm9tIHRoZSBpbi1tZW1vcnkgYXJjaGl2ZS4gUmV0dXJucyBhIGxpc3Qgb2YgQzxBcmNoaXZlOjpUYXI6OkZpbGU+Cm9iamVjdHMgdGhhdCByZW1haW4uCgo9Y3V0CgpzdWIgcmVtb3ZlIHsKICAgIG15ICRzZWxmID0gc2hpZnQ7CiAgICBteSBAbGlzdCA9IEBfOwoKICAgIG15ICVzZWVuID0gbWFwIHsgJF8tPmZ1bGxfcGF0aCA9PiAkXyB9IEB7JHNlbGYtPl9kYXRhfTsKICAgIGRlbGV0ZSAkc2VlbnsgJF8gfSBmb3IgQGxpc3Q7CgogICAgJHNlbGYtPl9kYXRhKCBbdmFsdWVzICVzZWVuXSApOwoKICAgIHJldHVybiB2YWx1ZXMgJXNlZW47Cn0KCj1oZWFkMiAkdGFyLT5jbGVhcgoKQzxjbGVhcj4gY2xlYXJzIHRoZSBjdXJyZW50IGluLW1lbW9yeSBhcmNoaXZlLiBUaGlzIGVmZmVjdGl2ZWx5IGdpdmVzCnlvdSBhICdibGFuaycgb2JqZWN0LCByZWFkeSB0byBiZSBmaWxsZWQgYWdhaW4uIE5vdGUgdGhhdCBDPGNsZWFyPgpvbmx5IGhhcyBlZmZlY3Qgb24gdGhlIG9iamVjdCwgbm90IHRoZSB1bmRlcmx5aW5nIHRhcmZpbGUuCgo9Y3V0CgpzdWIgY2xlYXIgewogICAgbXkgJHNlbGYgPSBzaGlmdCBvciByZXR1cm47CgogICAgJHNlbGYtPl9kYXRhKCBbXSApOwogICAgJHNlbGYtPl9maWxlKCAnJyApOwoKICAgIHJldHVybiAxOwp9CgoKPWhlYWQyICR0YXItPndyaXRlICggWyRmaWxlLCAkY29tcHJlc3NlZCwgJHByZWZpeF0gKQoKV3JpdGUgdGhlIGluLW1lbW9yeSBhcmNoaXZlIHRvIGRpc2suICBUaGUgZmlyc3QgYXJndW1lbnQgY2FuIGVpdGhlcgpiZSB0aGUgbmFtZSBvZiBhIGZpbGUgb3IgYSByZWZlcmVuY2UgdG8gYW4gYWxyZWFkeSBvcGVuIGZpbGVoYW5kbGUgKGEKR0xPQiByZWZlcmVuY2UpLiBJZiB0aGUgc2Vjb25kIGFyZ3VtZW50IGlzIHRydWUsIHRoZSBtb2R1bGUgd2lsbCB1c2UKSU86OlpsaWIgdG8gd3JpdGUgdGhlIGZpbGUgaW4gYSBjb21wcmVzc2VkIGZvcm1hdC4gIElmIElPOjpabGliIGlzCm5vdCBhdmFpbGFibGUsIHRoZSBDPHdyaXRlPiBtZXRob2Qgd2lsbCBmYWlsIGFuZCByZXR1cm4uCgpOb3RlIHRoYXQgd2hlbiB5b3UgcGFzcyBpbiBhIGZpbGVoYW5kbGUsIHRoZSBjb21wcmVzc2lvbiBhcmd1bWVudAppcyBpZ25vcmVkLCBhcyBhbGwgZmlsZXMgYXJlIHByaW50ZWQgdmVyYmF0aW0gdG8geW91ciBmaWxlaGFuZGxlLgpJZiB5b3Ugd2lzaCB0byBlbmFibGUgY29tcHJlc3Npb24gd2l0aCBmaWxlaGFuZGxlcywgdXNlIGFuCkM8SU86OlpsaWI+IGZpbGVoYW5kbGUgaW5zdGVhZC4KClNwZWNpZmljIGxldmVscyBvZiBjb21wcmVzc2lvbiBjYW4gYmUgY2hvc2VuIGJ5IHBhc3NpbmcgdGhlIHZhbHVlcyAyCnRocm91Z2ggOSBhcyB0aGUgc2Vjb25kIHBhcmFtZXRlci4KClRoZSB0aGlyZCBhcmd1bWVudCBpcyBhbiBvcHRpb25hbCBwcmVmaXguIEFsbCBmaWxlcyB3aWxsIGJlIHR1Y2tlZAphd2F5IGluIHRoZSBkaXJlY3RvcnkgeW91IHNwZWNpZnkgYXMgcHJlZml4LiBTbyBpZiB5b3UgaGF2ZSBmaWxlcwonYScgYW5kICdiJyBpbiB5b3VyIGFyY2hpdmUsIGFuZCB5b3Ugc3BlY2lmeSAnZm9vJyBhcyBwcmVmaXgsIHRoZXkKd2lsbCBiZSB3cml0dGVuIHRvIHRoZSBhcmNoaXZlIGFzICdmb28vYScgYW5kICdmb28vYicuCgpJZiBubyBhcmd1bWVudHMgYXJlIGdpdmVuLCBDPHdyaXRlPiByZXR1cm5zIHRoZSBlbnRpcmUgZm9ybWF0dGVkCmFyY2hpdmUgYXMgYSBzdHJpbmcsIHdoaWNoIGNvdWxkIGJlIHVzZWZ1bCBpZiB5b3UnZCBsaWtlIHRvIHN0dWZmIHRoZQphcmNoaXZlIGludG8gYSBzb2NrZXQgb3IgYSBwaXBlIHRvIGd6aXAgb3Igc29tZXRoaW5nLgoKPWN1dAoKc3ViIHdyaXRlIHsKICAgIG15ICRzZWxmICAgICAgICA9IHNoaWZ0OwogICAgbXkgJGZpbGUgICAgICAgID0gc2hpZnQ7ICRmaWxlID0gJycgdW5sZXNzIGRlZmluZWQgJGZpbGU7CiAgICBteSAkZ3ppcCAgICAgICAgPSBzaGlmdCB8fCAwOwogICAgbXkgJGV4dF9wcmVmaXggID0gc2hpZnQ7ICRleHRfcHJlZml4ID0gJycgdW5sZXNzIGRlZmluZWQgJGV4dF9wcmVmaXg7CiAgICBteSAkZHVtbXkgICAgICAgPSAnJzsKICAgIAogICAgIyMjIG9ubHkgbmVlZCBhIGhhbmRsZSBpZiB3ZSBoYXZlIGEgZmlsZSB0byBwcmludCB0byAjIyMKICAgIG15ICRoYW5kbGUgPSBsZW5ndGgoJGZpbGUpCiAgICAgICAgICAgICAgICAgICAgPyAoICRzZWxmLT5fZ2V0X2hhbmRsZSgkZmlsZSwgJGd6aXAsIFdSSVRFX09OTFktPigkZ3ppcCkgKQogICAgICAgICAgICAgICAgICAgICAgICBvciByZXR1cm4gKQogICAgICAgICAgICAgICAgICAgIDogJEhBU19QRVJMSU8gICAgPyBkbyB7IG9wZW4gbXkgJGgsICc+JywgXCRkdW1teTsgJGggfQogICAgICAgICAgICAgICAgICAgIDogJEhBU19JT19TVFJJTkcgPyBJTzo6U3RyaW5nLT5uZXcgCiAgICAgICAgICAgICAgICAgICAgOiBfX1BBQ0tBR0VfXy0+bm9fc3RyaW5nX3N1cHBvcnQoKTsKCgoKICAgIGZvciBteSAkZW50cnkgKCBAeyRzZWxmLT5fZGF0YX0gKSB7CiAgICAgICAgIyMjIGVudHJpZXMgdG8gYmUgd3JpdHRlbiB0byB0aGUgdGFyZmlsZSAjIyMKICAgICAgICBteSBAd3JpdGVfbWU7CgogICAgICAgICMjIyBvbmx5IG5vdyB3aWxsIHdlIGNoYW5nZSB0aGUgb2JqZWN0IHRvIHJlZmxlY3QgdGhlIGN1cnJlbnQgc3RhdGUKICAgICAgICAjIyMgb2YgdGhlIG5hbWUgYW5kIHByZWZpeCBmaWVsZHMgLS0gdGhpcyBuZWVkcyB0byBiZSBsaW1pdGVkIHRvCiAgICAgICAgIyMjIHdyaXRlKCkgb25seSEKICAgICAgICBteSAkY2xvbmUgPSAkZW50cnktPmNsb25lOwoKCiAgICAgICAgIyMjIHNvLCBpZiB5b3UgZG9uJ3Qgd2FudCB1c2UgdG8gdXNlIHRoZSBwcmVmaXgsIHdlJ2xsIHN0dWZmIAogICAgICAgICMjIyBldmVyeXRoaW5nIGluIHRoZSBuYW1lIGZpZWxkIGluc3RlYWQKICAgICAgICBpZiggJERPX05PVF9VU0VfUFJFRklYICkgewoKICAgICAgICAgICAgIyMjIHlvdSBtaWdodCBoYXZlIGFuIGV4dGVuZGVkIHByZWZpeCwgaWYgc28sIHNldCBpdCBpbiB0aGUgY2xvbmUKICAgICAgICAgICAgIyMjIFhYWCBpcyA6OlVuaXggcmlnaHQ/CiAgICAgICAgICAgICRjbG9uZS0+bmFtZSggbGVuZ3RoICRleHRfcHJlZml4CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IEZpbGU6OlNwZWM6OlVuaXgtPmNhdGRpciggJGV4dF9wcmVmaXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNsb25lLT5mdWxsX3BhdGgpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICRjbG9uZS0+ZnVsbF9wYXRoICk7CiAgICAgICAgICAgICRjbG9uZS0+cHJlZml4KCAnJyApOwoKICAgICAgICAjIyMgb3RoZXJ3aXNlLCB3ZSdsbCBoYXZlIHRvIHNldCBpdCBwcm9wZXJseSAtLSBwcmVmaXggcGFydCBpbiB0aGUKICAgICAgICAjIyMgcHJlZml4IGFuZCBuYW1lIHBhcnQgaW4gdGhlIG5hbWUgZmllbGQuCiAgICAgICAgfSBlbHNlIHsKCiAgICAgICAgICAgICMjIyBzcGxpdCB0aGVtIGhlcmUsIG5vdCBiZWZvcmUhCiAgICAgICAgICAgIG15ICgkcHJlZml4LCRuYW1lKSA9ICRjbG9uZS0+X3ByZWZpeF9hbmRfZmlsZSggJGNsb25lLT5mdWxsX3BhdGggKTsKCiAgICAgICAgICAgICMjIyB5b3UgbWlnaHQgaGF2ZSBhbiBleHRlbmRlZCBwcmVmaXgsIGlmIHNvLCBzZXQgaXQgaW4gdGhlIGNsb25lCiAgICAgICAgICAgICMjIyBYWFggaXMgOjpVbml4IHJpZ2h0PwogICAgICAgICAgICAkcHJlZml4ID0gRmlsZTo6U3BlYzo6VW5peC0+Y2F0ZGlyKCAkZXh0X3ByZWZpeCwgJHByZWZpeCApCiAgICAgICAgICAgICAgICBpZiBsZW5ndGggJGV4dF9wcmVmaXg7CgogICAgICAgICAgICAkY2xvbmUtPnByZWZpeCggJHByZWZpeCApOwogICAgICAgICAgICAkY2xvbmUtPm5hbWUoICRuYW1lICk7CiAgICAgICAgfQoKICAgICAgICAjIyMgbmFtZXMgYXJlIHRvbyBsb25nLCBhbmQgd2lsbCBnZXQgdHJ1bmNhdGVkIGlmIHdlIGRvbid0IGFkZCBhCiAgICAgICAgIyMjICdATG9uZ0xpbmsnIGZpbGUuLi4KICAgICAgICBteSAkbWFrZV9sb25nbGluayA9ICggICBsZW5ndGgoJGNsb25lLT5uYW1lKSAgICA+IE5BTUVfTEVOR1RIIG9yCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoKCRjbG9uZS0+cHJlZml4KSAgPiBQUkVGSVhfTEVOR1RICiAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHx8IDA7CgogICAgICAgICMjIyBwZXJoYXBzIHdlIG5lZWQgdG8gbWFrZSBhIGxvbmdsaW5rIGZpbGU/CiAgICAgICAgaWYoICRtYWtlX2xvbmdsaW5rICkgewogICAgICAgICAgICBteSAkbG9uZ2xpbmsgPSBBcmNoaXZlOjpUYXI6OkZpbGUtPm5ldygKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPT4gTE9OR0xJTktfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjbG9uZS0+ZnVsbF9wYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgeyB0eXBlID0+IExPTkdMSU5LIH0KICAgICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgIHVubGVzcyggJGxvbmdsaW5rICkgewogICAgICAgICAgICAgICAgJHNlbGYtPl9lcnJvciggIHFxW0NvdWxkIG5vdCBjcmVhdGUgJ0xvbmdMaW5rJyBlbnRyeSBmb3IgXSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXFbb3ZlcnNpemUgZmlsZSAnXSAuICRjbG9uZS0+ZnVsbF9wYXRoIC4iJyIgKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfTsKCiAgICAgICAgICAgIHB1c2ggQHdyaXRlX21lLCAkbG9uZ2xpbms7CiAgICAgICAgfQoKICAgICAgICBwdXNoIEB3cml0ZV9tZSwgJGNsb25lOwoKICAgICAgICAjIyMgd3JpdGUgdGhlIG9uZSwgb3B0aW9uYWxseSAyIGE6OnQ6OmZpbGUgb2JqZWN0cyB0byB0aGUgaGFuZGxlCiAgICAgICAgZm9yIG15ICRjbG9uZSAoQHdyaXRlX21lKSB7CgogICAgICAgICAgICAjIyMgaWYgdGhlIGZpbGUgaXMgYSBzeW1saW5rLCB0aGVyZSBhcmUgMiBvcHRpb25zOgogICAgICAgICAgICAjIyMgZWl0aGVyIHdlIGxlYXZlIHRoZSBzeW1saW5rIGludGFjdCwgYnV0IHRoZW4gd2UgZG9uJ3Qgd3JpdGUgYW55CiAgICAgICAgICAgICMjIyBkYXRhIE9SIHdlIGZvbGxvdyB0aGUgc3ltbGluaywgd2hpY2ggbWVhbnMgd2UgYWN0dWFsbHkgbWFrZSBhCiAgICAgICAgICAgICMjIyBjb3B5LiBpZiB3ZSBkbyB0aGUgbGF0dGVyLCB3ZSBoYXZlIHRvIGNoYW5nZSB0aGUgVFlQRSBvZiB0aGUKICAgICAgICAgICAgIyMjIGNsb25lIHRvICdGSUxFJwogICAgICAgICAgICBteSAkbGlua19vayA9ICAkY2xvbmUtPmlzX3N5bWxpbmsgJiYgJEFyY2hpdmU6OlRhcjo6Rk9MTE9XX1NZTUxJTks7CiAgICAgICAgICAgIG15ICRkYXRhX29rID0gISRjbG9uZS0+aXNfc3ltbGluayAmJiAkY2xvbmUtPmhhc19jb250ZW50OwoKICAgICAgICAgICAgIyMjIGRvd25ncmFkZSB0byBhICdub3JtYWwnIGZpbGUgaWYgaXQncyBhIHN5bWxpbmsgd2UncmUgZ29pbmcgdG8KICAgICAgICAgICAgIyMjIHRyZWF0IGFzIGEgcmVndWxhciBmaWxlCiAgICAgICAgICAgICRjbG9uZS0+X2Rvd25ncmFkZV90b19wbGFpbmZpbGUgaWYgJGxpbmtfb2s7CgogICAgICAgICAgICAjIyMgZ2V0IHRoZSBoZWFkZXIgZm9yIHRoaXMgYmxvY2sKICAgICAgICAgICAgbXkgJGhlYWRlciA9ICRzZWxmLT5fZm9ybWF0X3Rhcl9lbnRyeSggJGNsb25lICk7CiAgICAgICAgICAgIHVubGVzcyggJGhlYWRlciApIHsKICAgICAgICAgICAgICAgICRzZWxmLT5fZXJyb3IocVtDb3VsZCBub3QgZm9ybWF0IGhlYWRlciBmb3I6IF0gLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAkY2xvbmUtPmZ1bGxfcGF0aCApOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CgogICAgICAgICAgICB1bmxlc3MoIHByaW50ICRoYW5kbGUgJGhlYWRlciApIHsKICAgICAgICAgICAgICAgICRzZWxmLT5fZXJyb3IocVtDb3VsZCBub3Qgd3JpdGUgaGVhZGVyIGZvcjogXSAuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICRjbG9uZS0+ZnVsbF9wYXRoKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYoICRsaW5rX29rIG9yICRkYXRhX29rICkgewogICAgICAgICAgICAgICAgdW5sZXNzKCBwcmludCAkaGFuZGxlICRjbG9uZS0+ZGF0YSApIHsKICAgICAgICAgICAgICAgICAgICAkc2VsZi0+X2Vycm9yKHFbQ291bGQgbm90IHdyaXRlIGRhdGEgZm9yOiBdIC4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJGNsb25lLT5mdWxsX3BhdGgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAjIyMgcGFkIHRoZSBlbmQgb2YgdGhlIGNsb25lIGlmIHJlcXVpcmVkICMjIwogICAgICAgICAgICAgICAgcHJpbnQgJGhhbmRsZSBUQVJfUEFELT4oICRjbG9uZS0+c2l6ZSApIGlmICRjbG9uZS0+c2l6ZSAlIEJMT0NLCiAgICAgICAgICAgIH0KCiAgICAgICAgfSAjIyMgZG9uZSB3cml0aW5nIHRoZXNlIGVudHJpZXMKICAgIH0KCiAgICAjIyMgd3JpdGUgdGhlIGVuZCBtYXJrZXJzICMjIwogICAgcHJpbnQgJGhhbmRsZSBUQVJfRU5EIHggMiBvcgogICAgICAgICAgICByZXR1cm4gJHNlbGYtPl9lcnJvciggcXFbQ291bGQgbm90IHdyaXRlIHRhciBlbmQgbWFya2Vyc10gKTsKCiAgICAjIyMgZGlkIHlvdSB3YW50IGl0IHdyaXR0ZW4gdG8gYSBmaWxlLCBvciByZXR1cm5lZCBhcyBhIHN0cmluZz8gIyMjCiAgICBteSAkcnYgPSAgbGVuZ3RoKCRmaWxlKSA/IDEKICAgICAgICAgICAgICAgICAgICAgICAgOiAkSEFTX1BFUkxJTyA/ICRkdW1teQogICAgICAgICAgICAgICAgICAgICAgICA6IGRvIHsgc2VlayAkaGFuZGxlLCAwLCAwOyBsb2NhbCAkLzsgPCRoYW5kbGU+IH07CgogICAgIyMjIG1ha2Ugc3VyZSB0byBjbG9zZSB0aGUgaGFuZGxlOwogICAgY2xvc2UgJGhhbmRsZTsKICAgIAogICAgcmV0dXJuICRydjsKfQoKc3ViIF9mb3JtYXRfdGFyX2VudHJ5IHsKICAgIG15ICRzZWxmICAgICAgICA9IHNoaWZ0OwogICAgbXkgJGVudHJ5ICAgICAgID0gc2hpZnQgb3IgcmV0dXJuOwogICAgbXkgJGV4dF9wcmVmaXggID0gc2hpZnQ7ICRleHRfcHJlZml4ID0gJycgdW5sZXNzIGRlZmluZWQgJGV4dF9wcmVmaXg7CiAgICBteSAkbm9fcHJlZml4ICAgPSBzaGlmdCB8fCAwOwoKICAgIG15ICRmaWxlICAgID0gJGVudHJ5LT5uYW1lOwogICAgbXkgJHByZWZpeCAgPSAkZW50cnktPnByZWZpeDsgJHByZWZpeCA9ICcnIHVubGVzcyBkZWZpbmVkICRwcmVmaXg7CgogICAgIyMjIHJlbW92ZSB0aGUgcHJlZml4IGZyb20gdGhlIGZpbGUgbmFtZQogICAgIyMjIG5vdCBzdXJlIGlmIHRoaXMgaXMgc3RpbGwgbmVlZWRlZCAtLWthbmUKICAgICMjIyBubyBpdCdzIG5vdCAtLSBBcmNoaXZlOjpUYXI6OkZpbGUtPl9uZXdfZnJvbV9maWxlIHdpbGwgdGFrZSBjYXJlIG9mCiAgICAjIyMgdGhpcyBmb3IgdXMuIEV2ZW4gd29yc2UsIHRoaXMgd291bGQgYnJlYWsgaWYgd2UgdHJpZWQgdG8gYWRkIGEgZmlsZQogICAgIyMjIGxpa2UgeC94LgogICAgI2lmKCBsZW5ndGggJHByZWZpeCApIHsKICAgICMgICAgJGZpbGUgPX4gcy9eJG1hdGNoLy87CiAgICAjfQoKICAgICRwcmVmaXggPSBGaWxlOjpTcGVjOjpVbml4LT5jYXRkaXIoJGV4dF9wcmVmaXgsICRwcmVmaXgpCiAgICAgICAgICAgICAgICBpZiBsZW5ndGggJGV4dF9wcmVmaXg7CgogICAgIyMjIG5vdCBzdXJlIHdoeSB0aGlzIGlzLi4uICMjIwogICAgbXkgJGwgPSBQUkVGSVhfTEVOR1RIOyAjIGlzIGFtYmlndW91cyBvdGhlcndpc2UuLi4KICAgIHN1YnN0ciAoJHByZWZpeCwgMCwgLSRsKSA9ICIiIGlmIGxlbmd0aCAkcHJlZml4ID49IFBSRUZJWF9MRU5HVEg7CgogICAgbXkgJGYxID0gIiUwNm8iOyBteSAkZjIgID0gIiUxMW8iOwoKICAgICMjIyB0aGlzIG1pZ2h0IGJlIG9wdGltaXphYmxlIHdpdGggYSAnY2hhbmdlZCcgZmxhZyBpbiB0aGUgZmlsZSBvYmplY3RzICMjIwogICAgbXkgJHRhciA9IHBhY2sgKAogICAgICAgICAgICAgICAgUEFDSywKICAgICAgICAgICAgICAgICRmaWxlLAoKICAgICAgICAgICAgICAgIChtYXAgeyBzcHJpbnRmKCAkZjEsICRlbnRyeS0+JF8oKSApIH0gcXdbbW9kZSB1aWQgZ2lkXSksCiAgICAgICAgICAgICAgICAobWFwIHsgc3ByaW50ZiggJGYyLCAkZW50cnktPiRfKCkgKSB9IHF3W3NpemUgbXRpbWVdKSwKCiAgICAgICAgICAgICAgICAiIiwgICMgY2hlY2tzdW0gZmllbGQgLSBzcGFjZSBwYWRkZWQgYSBiaXQgZG93bgoKICAgICAgICAgICAgICAgIChtYXAgeyAkZW50cnktPiRfKCkgfSAgICAgICAgICAgICAgICAgcXdbdHlwZSBsaW5rbmFtZSBtYWdpY10pLAoKICAgICAgICAgICAgICAgICRlbnRyeS0+dmVyc2lvbiB8fCBUQVJfVkVSU0lPTiwKCiAgICAgICAgICAgICAgICAobWFwIHsgJGVudHJ5LT4kXygpIH0gICAgICAgICAgICAgICAgIHF3W3VuYW1lIGduYW1lXSksCiAgICAgICAgICAgICAgICAobWFwIHsgc3ByaW50ZiggJGYxLCAkZW50cnktPiRfKCkgKSB9IHF3W2Rldm1ham9yIGRldm1pbm9yXSksCgogICAgICAgICAgICAgICAgKCRub19wcmVmaXggPyAnJyA6ICRwcmVmaXgpCiAgICApOwoKICAgICMjIyBhZGQgdGhlIGNoZWNrc3VtICMjIwogICAgc3Vic3RyKCR0YXIsMTQ4LDcpID0gc3ByaW50ZigiJTZvXDAiLCB1bnBhY2soIiUxNkMqIiwkdGFyKSk7CgogICAgcmV0dXJuICR0YXI7Cn0KCj1oZWFkMiAkdGFyLT5hZGRfZmlsZXMoIEBmaWxlbmFtZWxpc3QgKQoKVGFrZXMgYSBsaXN0IG9mIGZpbGVuYW1lcyBhbmQgYWRkcyB0aGVtIHRvIHRoZSBpbi1tZW1vcnkgYXJjaGl2ZS4KClRoZSBwYXRoIHRvIHRoZSBmaWxlIGlzIGF1dG9tYXRpY2FsbHkgY29udmVydGVkIHRvIGEgVW5peCBsaWtlCmVxdWl2YWxlbnQgZm9yIHVzZSBpbiB0aGUgYXJjaGl2ZSwgYW5kLCBpZiBvbiBNYWNPUywgdGhlIGZpbGUncwptb2RpZmljYXRpb24gdGltZSBpcyBjb252ZXJ0ZWQgZnJvbSB0aGUgTWFjT1MgZXBvY2ggdG8gdGhlIFVuaXggZXBvY2guClNvIHRhciBhcmNoaXZlcyBjcmVhdGVkIG9uIE1hY09TIHdpdGggQjxBcmNoaXZlOjpUYXI+IGNhbiBiZSByZWFkCmJvdGggd2l0aCBJPHRhcj4gb24gVW5peCBhbmQgYXBwbGljYXRpb25zIGxpa2UgSTxzdW50YXI+IG9yCkk8U3R1ZmZpdCBFeHBhbmRlcj4gb24gTWFjT1MuCgpCZSBhd2FyZSB0aGF0IHRoZSBmaWxlJ3MgdHlwZS9jcmVhdG9yIGFuZCByZXNvdXJjZSBmb3JrIHdpbGwgYmUgbG9zdCwKd2hpY2ggaXMgdXN1YWxseSB3aGF0IHlvdSB3YW50IGluIGNyb3NzLXBsYXRmb3JtIGFyY2hpdmVzLgoKUmV0dXJucyBhIGxpc3Qgb2YgQzxBcmNoaXZlOjpUYXI6OkZpbGU+IG9iamVjdHMgdGhhdCB3ZXJlIGp1c3QgYWRkZWQuCgo9Y3V0CgpzdWIgYWRkX2ZpbGVzIHsKICAgIG15ICRzZWxmICAgID0gc2hpZnQ7CiAgICBteSBAZmlsZXMgICA9IEBfIG9yIHJldHVybjsKCiAgICBteSBAcnY7CiAgICBmb3IgbXkgJGZpbGUgKCBAZmlsZXMgKSB7CiAgICAgICAgdW5sZXNzKCAtZSAkZmlsZSB8fCAtbCAkZmlsZSApIHsKICAgICAgICAgICAgJHNlbGYtPl9lcnJvciggcXFbTm8gc3VjaCBmaWxlOiAnJGZpbGUnXSApOwogICAgICAgICAgICBuZXh0OwogICAgICAgIH0KCiAgICAgICAgbXkgJG9iaiA9IEFyY2hpdmU6OlRhcjo6RmlsZS0+bmV3KCBmaWxlID0+ICRmaWxlICk7CiAgICAgICAgdW5sZXNzKCAkb2JqICkgewogICAgICAgICAgICAkc2VsZi0+X2Vycm9yKCBxcVtVbmFibGUgdG8gYWRkIGZpbGU6ICckZmlsZSddICk7CiAgICAgICAgICAgIG5leHQ7CiAgICAgICAgfQoKICAgICAgICBwdXNoIEBydiwgJG9iajsKICAgIH0KCiAgICBwdXNoIEB7JHNlbGYtPntfZGF0YX19LCBAcnY7CgogICAgcmV0dXJuIEBydjsKfQoKPWhlYWQyICR0YXItPmFkZF9kYXRhICggJGZpbGVuYW1lLCAkZGF0YSwgWyRvcHRoYXNocmVmXSApCgpUYWtlcyBhIGZpbGVuYW1lLCBhIHNjYWxhciBmdWxsIG9mIGRhdGEgYW5kIG9wdGlvbmFsbHkgYSByZWZlcmVuY2UgdG8KYSBoYXNoIHdpdGggc3BlY2lmaWMgb3B0aW9ucy4KCldpbGwgYWRkIGEgZmlsZSB0byB0aGUgaW4tbWVtb3J5IGFyY2hpdmUsIHdpdGggbmFtZSBDPCRmaWxlbmFtZT4gYW5kCmNvbnRlbnQgQzwkZGF0YT4uIFNwZWNpZmljIHByb3BlcnRpZXMgY2FuIGJlIHNldCB1c2luZyBDPCRvcHRoYXNocmVmPi4KVGhlIGZvbGxvd2luZyBsaXN0IG9mIHByb3BlcnRpZXMgaXMgc3VwcG9ydGVkOiBuYW1lLCBzaXplLCBtdGltZQoobGFzdCBtb2RpZmllZCBkYXRlKSwgbW9kZSwgdWlkLCBnaWQsIGxpbmtuYW1lLCB1bmFtZSwgZ25hbWUsCmRldm1ham9yLCBkZXZtaW5vciwgcHJlZml4LCB0eXBlLiAgKE9uIE1hY09TLCB0aGUgZmlsZSdzIHBhdGggYW5kCm1vZGlmaWNhdGlvbiB0aW1lcyBhcmUgY29udmVydGVkIHRvIFVuaXggZXF1aXZhbGVudHMuKQoKVmFsaWQgdmFsdWVzIGZvciB0aGUgZmlsZSB0eXBlIGFyZSB0aGUgZm9sbG93aW5nIGNvbnN0YW50cyBkZWZpbmVkIGluCkFyY2hpdmU6OlRhcjo6Q29uc3RhbnRzOgoKPW92ZXIgNAoKPWl0ZW0gRklMRQoKUmVndWxhciBmaWxlLgoKPWl0ZW0gSEFSRExJTksKCj1pdGVtIFNZTUxJTksKCkhhcmQgYW5kIHN5bWJvbGljICgic29mdCIpIGxpbmtzOyBsaW5rbmFtZSBzaG91bGQgc3BlY2lmeSB0YXJnZXQuCgo9aXRlbSBDSEFSREVWCgo9aXRlbSBCTE9DS0RFVgoKQ2hhcmFjdGVyIGFuZCBibG9jayBkZXZpY2VzLiBkZXZtYWpvciBhbmQgZGV2bWlub3Igc2hvdWxkIHNwZWNpZnkgdGhlIG1ham9yCmFuZCBtaW5vciBkZXZpY2UgbnVtYmVycy4KCj1pdGVtIERJUgoKRGlyZWN0b3J5LgoKPWl0ZW0gRklGTwoKRklGTyAobmFtZWQgcGlwZSkuCgo9aXRlbSBTT0NLRVQKClNvY2tldC4KCj1iYWNrCgpSZXR1cm5zIHRoZSBDPEFyY2hpdmU6OlRhcjo6RmlsZT4gb2JqZWN0IHRoYXQgd2FzIGp1c3QgYWRkZWQsIG9yCkM8dW5kZWY+IG9uIGZhaWx1cmUuCgo9Y3V0CgpzdWIgYWRkX2RhdGEgewogICAgbXkgJHNlbGYgICAgPSBzaGlmdDsKICAgIG15ICgkZmlsZSwgJGRhdGEsICRvcHQpID0gQF87CgogICAgbXkgJG9iaiA9IEFyY2hpdmU6OlRhcjo6RmlsZS0+bmV3KCBkYXRhID0+ICRmaWxlLCAkZGF0YSwgJG9wdCApOwogICAgdW5sZXNzKCAkb2JqICkgewogICAgICAgICRzZWxmLT5fZXJyb3IoIHFxW1VuYWJsZSB0byBhZGQgZmlsZTogJyRmaWxlJ10gKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgcHVzaCBAeyRzZWxmLT57X2RhdGF9fSwgJG9iajsKCiAgICByZXR1cm4gJG9iajsKfQoKPWhlYWQyICR0YXItPmVycm9yKCBbJEJPT0xdICkKClJldHVybnMgdGhlIGN1cnJlbnQgZXJyb3JzdHJpbmcgKHVzdWFsbHksIHRoZSBsYXN0IGVycm9yIHJlcG9ydGVkKS4KSWYgYSB0cnVlIHZhbHVlIHdhcyBzcGVjaWZpZWQsIGl0IHdpbGwgZ2l2ZSB0aGUgQzxDYXJwOjpsb25nbWVzcz4KZXF1aXZhbGVudCBvZiB0aGUgZXJyb3IsIGluIGVmZmVjdCBnaXZpbmcgeW91IGEgc3RhY2t0cmFjZS4KCkZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSwgdGhpcyBlcnJvciBpcyBhbHNvIGF2YWlsYWJsZSBhcwpDPCRBcmNoaXZlOjpUYXI6OmVycm9yPiBhbHRob3VnaCBpdCBpcyBtdWNoIHJlY29tbWVuZGVkIHlvdSB1c2UgdGhlCm1ldGhvZCBjYWxsIGluc3RlYWQuCgo9Y3V0Cgp7CiAgICAkZXJyb3IgPSAnJzsKICAgIG15ICRsb25nbWVzczsKCiAgICBzdWIgX2Vycm9yIHsKICAgICAgICBteSAkc2VsZiAgICA9IHNoaWZ0OwogICAgICAgIG15ICRtc2cgICAgID0gJGVycm9yID0gc2hpZnQ7CiAgICAgICAgJGxvbmdtZXNzICAgPSBDYXJwOjpsb25nbWVzcygkZXJyb3IpOwoKICAgICAgICAjIyMgc2V0IEFyY2hpdmU6OlRhcjo6V0FSTiB0byAwIHRvIGRpc2FibGUgcHJpbnRpbmcKICAgICAgICAjIyMgb2YgZXJyb3JzCiAgICAgICAgaWYoICRXQVJOICkgewogICAgICAgICAgICBjYXJwICRERUJVRyA/ICRsb25nbWVzcyA6ICRtc2c7CiAgICAgICAgfQoKICAgICAgICByZXR1cm47CiAgICB9CgogICAgc3ViIGVycm9yIHsKICAgICAgICBteSAkc2VsZiA9IHNoaWZ0OwogICAgICAgIHJldHVybiBzaGlmdCgpID8gJGxvbmdtZXNzIDogJGVycm9yOwogICAgfQp9Cgo9aGVhZDIgJHRhci0+c2V0Y3dkKCAkY3dkICk7CgpDPEFyY2hpdmU6OlRhcj4gbmVlZHMgdG8ga25vdyB0aGUgY3VycmVudCBkaXJlY3RvcnksIGFuZCBpdCB3aWxsIHJ1bgpDPEN3ZDo6Y3dkKCk+IEk8ZXZlcnk+IHRpbWUgaXQgZXh0cmFjdHMgYSBJPHJlbGF0aXZlPiBlbnRyeSBmcm9tIHRoZSAKdGFyZmlsZSBhbmQgc2F2ZXMgaXQgaW4gdGhlIGZpbGUgc3lzdGVtLiAoQXMgb2YgdmVyc2lvbiAxLjMwLCBob3dldmVyLApDPEFyY2hpdmU6OlRhcj4gd2lsbCB1c2UgdGhlIHNwZWVkIG9wdGltaXphdGlvbiBkZXNjcmliZWQgYmVsb3cgCmF1dG9tYXRpY2FsbHksIHNvIGl0J3Mgb25seSByZWxldmFudCBpZiB5b3UncmUgdXNpbmcgQzxleHRyYWN0X2ZpbGUoKT4pLgoKU2luY2UgQzxBcmNoaXZlOjpUYXI+IGRvZXNuJ3QgY2hhbmdlIHRoZSBjdXJyZW50IGRpcmVjdG9yeSBpbnRlcm5hbGx5CndoaWxlIGl0IGlzIGV4dHJhY3RpbmcgdGhlIGl0ZW1zIGluIGEgdGFyYmFsbCwgYWxsIGNhbGxzIHRvIEM8Q3dkOjpjd2QoKT4KY2FuIGJlIGF2b2lkZWQgaWYgd2UgY2FuIGd1YXJhbnRlZSB0aGF0IHRoZSBjdXJyZW50IGRpcmVjdG9yeSBkb2Vzbid0CmdldCBjaGFuZ2VkIGV4dGVybmFsbHkuCgpUbyB1c2UgdGhpcyBwZXJmb3JtYW5jZSBib29zdCwgc2V0IHRoZSBjdXJyZW50IGRpcmVjdG9yeSB2aWEKCiAgICB1c2UgQ3dkOwogICAgJHRhci0+c2V0Y3dkKCBjd2QoKSApOwoKb25jZSBiZWZvcmUgY2FsbGluZyBhIGZ1bmN0aW9uIGxpa2UgQzxleHRyYWN0X2ZpbGU+IGFuZApDPEFyY2hpdmU6OlRhcj4gd2lsbCB1c2UgdGhlIGN1cnJlbnQgZGlyZWN0b3J5IHNldHRpbmcgZnJvbSB0aGVuIG9uCmFuZCB3b24ndCBjYWxsIEM8Q3dkOjpjd2QoKT4gaW50ZXJuYWxseS4gCgpUbyBzd2l0Y2ggYmFjayB0byB0aGUgZGVmYXVsdCBiZWhhdmlvdXIsIHVzZQoKICAgICR0YXItPnNldGN3ZCggdW5kZWYgKTsKCmFuZCBDPEFyY2hpdmU6OlRhcj4gd2lsbCBjYWxsIEM8Q3dkOjpjd2QoKT4gaW50ZXJuYWxseSBhZ2Fpbi4KCklmIHlvdSdyZSB1c2luZyBDPEFyY2hpdmU6OlRhcj4ncyBDPGV4cmFjdCgpPiBtZXRob2QsIEM8c2V0Y3dkKCk+IHdpbGwKYmUgY2FsbGVkIGZvciB5b3UuCgo9Y3V0IAoKc3ViIHNldGN3ZCB7CiAgICBteSAkc2VsZiAgICAgPSBzaGlmdDsKICAgIG15ICRjd2QgICAgICA9IHNoaWZ0OwoKICAgICRzZWxmLT57Y3dkfSA9ICRjd2Q7Cn0KCj1oZWFkMiAkYm9vbCA9ICR0YXItPmhhc19pb19zdHJpbmcKClJldHVybnMgdHJ1ZSBpZiB3ZSBjdXJyZW50bHkgaGF2ZSBDPElPOjpTdHJpbmc+IHN1cHBvcnQgbG9hZGVkLgoKRWl0aGVyIEM8SU86OlN0cmluZz4gb3IgQzxwZXJsaW8+IHN1cHBvcnQgaXMgbmVlZGVkIHRvIHN1cHBvcnQgd3JpdGluZyAKc3RyaW5naWZpZWQgYXJjaGl2ZXMuIEN1cnJlbnRseSwgQzxwZXJsaW8+IGlzIHRoZSBwcmVmZXJyZWQgbWV0aG9kLCBpZgphdmFpbGFibGUuCgpTZWUgdGhlIEM8R0xPQkFMIFZBUklBQkxFUz4gc2VjdGlvbiB0byBzZWUgaG93IHRvIGNoYW5nZSB0aGlzIHByZWZlcmVuY2UuCgo9Y3V0CgpzdWIgaGFzX2lvX3N0cmluZyB7IHJldHVybiAkSEFTX0lPX1NUUklORzsgfQoKPWhlYWQyICRib29sID0gJHRhci0+aGFzX3BlcmxpbwoKUmV0dXJucyB0cnVlIGlmIHdlIGN1cnJlbnRseSBoYXZlIEM8cGVybGlvPiBzdXBwb3J0IGxvYWRlZC4KClRoaXMgcmVxdWlyZXMgQzxwZXJsLTUuOD4gb3IgaGlnaGVyLCBjb21waWxlZCB3aXRoIEM8cGVybGlvPiAKCkVpdGhlciBDPElPOjpTdHJpbmc+IG9yIEM8cGVybGlvPiBzdXBwb3J0IGlzIG5lZWRlZCB0byBzdXBwb3J0IHdyaXRpbmcgCnN0cmluZ2lmaWVkIGFyY2hpdmVzLiBDdXJyZW50bHksIEM8cGVybGlvPiBpcyB0aGUgcHJlZmVycmVkIG1ldGhvZCwgaWYKYXZhaWxhYmxlLgoKU2VlIHRoZSBDPEdMT0JBTCBWQVJJQUJMRVM+IHNlY3Rpb24gdG8gc2VlIGhvdyB0byBjaGFuZ2UgdGhpcyBwcmVmZXJlbmNlLgoKPWN1dAoKc3ViIGhhc19wZXJsaW8geyByZXR1cm4gJEhBU19QRVJMSU87IH0KCgo9aGVhZDEgQ2xhc3MgTWV0aG9kcwoKPWhlYWQyIEFyY2hpdmU6OlRhci0+Y3JlYXRlX2FyY2hpdmUoJGZpbGUsICRjb21wcmVzc2lvbiwgQGZpbGVsaXN0KQoKQ3JlYXRlcyBhIHRhciBmaWxlIGZyb20gdGhlIGxpc3Qgb2YgZmlsZXMgcHJvdmlkZWQuICBUaGUgZmlyc3QKYXJndW1lbnQgY2FuIGVpdGhlciBiZSB0aGUgbmFtZSBvZiB0aGUgdGFyIGZpbGUgdG8gY3JlYXRlIG9yIGEKcmVmZXJlbmNlIHRvIGFuIG9wZW4gZmlsZSBoYW5kbGUgKGUuZy4gYSBHTE9CIHJlZmVyZW5jZSkuCgpUaGUgc2Vjb25kIGFyZ3VtZW50IHNwZWNpZmllcyB0aGUgbGV2ZWwgb2YgY29tcHJlc3Npb24gdG8gYmUgdXNlZCwgaWYKYW55LiAgQ29tcHJlc3Npb24gb2YgdGFyIGZpbGVzIHJlcXVpcmVzIHRoZSBpbnN0YWxsYXRpb24gb2YgdGhlCklPOjpabGliIG1vZHVsZS4gIFNwZWNpZmljIGxldmVscyBvZiBjb21wcmVzc2lvbiBtYXkgYmUKcmVxdWVzdGVkIGJ5IHBhc3NpbmcgYSB2YWx1ZSBiZXR3ZWVuIDIgYW5kIDkgYXMgdGhlIHNlY29uZCBhcmd1bWVudC4KQW55IG90aGVyIHZhbHVlIGV2YWx1YXRpbmcgYXMgdHJ1ZSB3aWxsIHJlc3VsdCBpbiB0aGUgZGVmYXVsdApjb21wcmVzc2lvbiBsZXZlbCBiZWluZyB1c2VkLgoKTm90ZSB0aGF0IHdoZW4geW91IHBhc3MgaW4gYSBmaWxlaGFuZGxlLCB0aGUgY29tcHJlc3Npb24gYXJndW1lbnQKaXMgaWdub3JlZCwgYXMgYWxsIGZpbGVzIGFyZSBwcmludGVkIHZlcmJhdGltIHRvIHlvdXIgZmlsZWhhbmRsZS4KSWYgeW91IHdpc2ggdG8gZW5hYmxlIGNvbXByZXNzaW9uIHdpdGggZmlsZWhhbmRsZXMsIHVzZSBhbgpDPElPOjpabGliPiBmaWxlaGFuZGxlIGluc3RlYWQuCgpUaGUgcmVtYWluaW5nIGFyZ3VtZW50cyBsaXN0IHRoZSBmaWxlcyB0byBiZSBpbmNsdWRlZCBpbiB0aGUgdGFyIGZpbGUuClRoZXNlIGZpbGVzIG11c3QgYWxsIGV4aXN0LiBBbnkgZmlsZXMgd2hpY2ggZG9uJ3QgZXhpc3Qgb3IgY2FuJ3QgYmUKcmVhZCBhcmUgc2lsZW50bHkgaWdub3JlZC4KCklmIHRoZSBhcmNoaXZlIGNyZWF0aW9uIGZhaWxzIGZvciBhbnkgcmVhc29uLCBDPGNyZWF0ZV9hcmNoaXZlPiB3aWxsCnJldHVybiBmYWxzZS4gUGxlYXNlIHVzZSB0aGUgQzxlcnJvcj4gbWV0aG9kIHRvIGZpbmQgdGhlIGNhdXNlIG9mIHRoZQpmYWlsdXJlLgoKTm90ZSB0aGF0IHRoaXMgbWV0aG9kIGRvZXMgbm90IHdyaXRlIEM8b24gdGhlIGZseT4gYXMgaXQgd2VyZTsgaXQKc3RpbGwgcmVhZHMgYWxsIHRoZSBmaWxlcyBpbnRvIG1lbW9yeSBiZWZvcmUgd3JpdGluZyBvdXQgdGhlIGFyY2hpdmUuCkNvbnN1bHQgdGhlIEZBUSBiZWxvdyBpZiB0aGlzIGlzIGEgcHJvYmxlbS4KCj1jdXQKCnN1YiBjcmVhdGVfYXJjaGl2ZSB7CiAgICBteSAkY2xhc3MgPSBzaGlmdDsKCiAgICBteSAkZmlsZSAgICA9IHNoaWZ0OyByZXR1cm4gdW5sZXNzIGRlZmluZWQgJGZpbGU7CiAgICBteSAkZ3ppcCAgICA9IHNoaWZ0IHx8IDA7CiAgICBteSBAZmlsZXMgICA9IEBfOwoKICAgIHVubGVzcyggQGZpbGVzICkgewogICAgICAgIHJldHVybiAkY2xhc3MtPl9lcnJvciggcXFbQ293YXJkbHkgcmVmdXNpbmcgdG8gY3JlYXRlIGVtcHR5IGFyY2hpdmUhXSApOwogICAgfQoKICAgIG15ICR0YXIgPSAkY2xhc3MtPm5ldzsKICAgICR0YXItPmFkZF9maWxlcyggQGZpbGVzICk7CiAgICByZXR1cm4gJHRhci0+d3JpdGUoICRmaWxlLCAkZ3ppcCApOwp9Cgo9aGVhZDIgQXJjaGl2ZTo6VGFyLT5saXN0X2FyY2hpdmUgKCRmaWxlLCAkY29tcHJlc3NlZCwgW1xAcHJvcGVydGllc10pCgpSZXR1cm5zIGEgbGlzdCBvZiB0aGUgbmFtZXMgb2YgYWxsIHRoZSBmaWxlcyBpbiB0aGUgYXJjaGl2ZS4gIFRoZQpmaXJzdCBhcmd1bWVudCBjYW4gZWl0aGVyIGJlIHRoZSBuYW1lIG9mIHRoZSB0YXIgZmlsZSB0byBsaXN0IG9yIGEKcmVmZXJlbmNlIHRvIGFuIG9wZW4gZmlsZSBoYW5kbGUgKGUuZy4gYSBHTE9CIHJlZmVyZW5jZSkuCgpJZiBDPGxpc3RfYXJjaGl2ZSgpPiBpcyBwYXNzZWQgYW4gYXJyYXkgcmVmZXJlbmNlIGFzIGl0cyB0aGlyZAphcmd1bWVudCBpdCByZXR1cm5zIGEgbGlzdCBvZiBoYXNoIHJlZmVyZW5jZXMgY29udGFpbmluZyB0aGUgcmVxdWVzdGVkCnByb3BlcnRpZXMgb2YgZWFjaCBmaWxlLiAgVGhlIGZvbGxvd2luZyBsaXN0IG9mIHByb3BlcnRpZXMgaXMKc3VwcG9ydGVkOiBmdWxsX3BhdGgsIG5hbWUsIHNpemUsIG10aW1lIChsYXN0IG1vZGlmaWVkIGRhdGUpLCBtb2RlLCAKdWlkLCBnaWQsIGxpbmtuYW1lLCB1bmFtZSwgZ25hbWUsIGRldm1ham9yLCBkZXZtaW5vciwgcHJlZml4LgoKU2VlIEM8QXJjaGl2ZTo6VGFyOjpGaWxlPiBmb3IgZGV0YWlscyBhYm91dCBzdXBwb3J0ZWQgcHJvcGVydGllcy4KClBhc3NpbmcgYW4gYXJyYXkgcmVmZXJlbmNlIGNvbnRhaW5pbmcgb25seSBvbmUgZWxlbWVudCwgJ25hbWUnLCBpcwpzcGVjaWFsIGNhc2VkIHRvIHJldHVybiBhIGxpc3Qgb2YgbmFtZXMgcmF0aGVyIHRoYW4gYSBsaXN0IG9mIGhhc2gKcmVmZXJlbmNlcy4KCj1jdXQKCnN1YiBsaXN0X2FyY2hpdmUgewogICAgbXkgJGNsYXNzICAgPSBzaGlmdDsKICAgIG15ICRmaWxlICAgID0gc2hpZnQ7IHJldHVybiB1bmxlc3MgZGVmaW5lZCAkZmlsZTsKICAgIG15ICRnemlwICAgID0gc2hpZnQgfHwgMDsKCiAgICBteSAkdGFyID0gJGNsYXNzLT5uZXcoJGZpbGUsICRnemlwKTsKICAgIHJldHVybiB1bmxlc3MgJHRhcjsKCiAgICByZXR1cm4gJHRhci0+bGlzdF9maWxlcyggQF8gKTsKfQoKPWhlYWQyIEFyY2hpdmU6OlRhci0+ZXh0cmFjdF9hcmNoaXZlICgkZmlsZSwgJGd6aXApCgpFeHRyYWN0cyB0aGUgY29udGVudHMgb2YgdGhlIHRhciBmaWxlLiAgVGhlIGZpcnN0IGFyZ3VtZW50IGNhbiBlaXRoZXIKYmUgdGhlIG5hbWUgb2YgdGhlIHRhciBmaWxlIHRvIGNyZWF0ZSBvciBhIHJlZmVyZW5jZSB0byBhbiBvcGVuIGZpbGUKaGFuZGxlIChlLmcuIGEgR0xPQiByZWZlcmVuY2UpLiAgQWxsIHJlbGF0aXZlIHBhdGhzIGluIHRoZSB0YXIgZmlsZSB3aWxsCmJlIGNyZWF0ZWQgdW5kZXJuZWF0aCB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeS4KCkM8ZXh0cmFjdF9hcmNoaXZlPiB3aWxsIHJldHVybiBhIGxpc3Qgb2YgZmlsZXMgaXQgZXh0cmFjdGVkLgpJZiB0aGUgYXJjaGl2ZSBleHRyYWN0aW9uIGZhaWxzIGZvciBhbnkgcmVhc29uLCBDPGV4dHJhY3RfYXJjaGl2ZT4Kd2lsbCByZXR1cm4gZmFsc2UuICBQbGVhc2UgdXNlIHRoZSBDPGVycm9yPiBtZXRob2QgdG8gZmluZCB0aGUgY2F1c2UKb2YgdGhlIGZhaWx1cmUuCgo9Y3V0CgpzdWIgZXh0cmFjdF9hcmNoaXZlIHsKICAgIG15ICRjbGFzcyAgID0gc2hpZnQ7CiAgICBteSAkZmlsZSAgICA9IHNoaWZ0OyByZXR1cm4gdW5sZXNzIGRlZmluZWQgJGZpbGU7CiAgICBteSAkZ3ppcCAgICA9IHNoaWZ0IHx8IDA7CgogICAgbXkgJHRhciA9ICRjbGFzcy0+bmV3KCApIG9yIHJldHVybjsKCiAgICByZXR1cm4gJHRhci0+cmVhZCggJGZpbGUsICRnemlwLCB7IGV4dHJhY3QgPT4gMSB9ICk7Cn0KCj1oZWFkMiBBcmNoaXZlOjpUYXItPmNhbl9oYW5kbGVfY29tcHJlc3NlZF9maWxlcwoKQSBzaW1wbGUgY2hlY2tpbmcgcm91dGluZSwgd2hpY2ggd2lsbCByZXR1cm4gdHJ1ZSBpZiBDPEFyY2hpdmU6OlRhcj4KaXMgYWJsZSB0byB1bmNvbXByZXNzIGNvbXByZXNzZWQgYXJjaGl2ZXMgb24gdGhlIGZseSB3aXRoIEM8SU86OlpsaWI+LApvciBmYWxzZSBpZiBDPElPOjpabGliPiBpcyBub3QgaW5zdGFsbGVkLgoKWW91IGNhbiB1c2UgdGhpcyBhcyBhIHNob3J0Y3V0IHRvIGRldGVybWluZSB3aGV0aGVyIEM8QXJjaGl2ZTo6VGFyPgp3aWxsIGRvIHdoYXQgeW91IHRoaW5rIGJlZm9yZSBwYXNzaW5nIGNvbXByZXNzZWQgYXJjaGl2ZXMgdG8gaXRzCkM8cmVhZD4gbWV0aG9kLgoKPWN1dAoKc3ViIGNhbl9oYW5kbGVfY29tcHJlc3NlZF9maWxlcyB7IHJldHVybiBaTElCID8gMSA6IDAgfQoKc3ViIG5vX3N0cmluZ19zdXBwb3J0IHsKICAgIGNyb2FrKCJZb3UgaGF2ZSB0byBpbnN0YWxsIElPOjpTdHJpbmcgdG8gc3VwcG9ydCB3cml0aW5nIGFyY2hpdmVzIHRvIHN0cmluZ3MiKTsKfQoKMTsKCl9fRU5EX18KCj1oZWFkMSBHTE9CQUwgVkFSSUFCTEVTCgo9aGVhZDIgJEFyY2hpdmU6OlRhcjo6Rk9MTE9XX1NZTUxJTksKClNldCB0aGlzIHZhcmlhYmxlIHRvIEM8MT4gdG8gbWFrZSBDPEFyY2hpdmU6OlRhcj4gZWZmZWN0aXZlbHkgbWFrZSBhCmNvcHkgb2YgdGhlIGZpbGUgd2hlbiBleHRyYWN0aW5nLiBEZWZhdWx0IGlzIEM8MD4sIHdoaWNoCm1lYW5zIHRoZSBzeW1saW5rIHN0YXlzIGludGFjdC4gT2YgY291cnNlLCB5b3Ugd2lsbCBoYXZlIHRvIHBhY2sgdGhlCmZpbGUgbGlua2VkIHRvIGFzIHdlbGwuCgpUaGlzIG9wdGlvbiBpcyBjaGVja2VkIHdoZW4geW91IHdyaXRlIG91dCB0aGUgdGFyZmlsZSB1c2luZyBDPHdyaXRlPgpvciBDPGNyZWF0ZV9hcmNoaXZlPi4KClRoaXMgd29ya3MganVzdCBsaWtlIEM8L2Jpbi90YXI+J3MgQzwtaD4gb3B0aW9uLgoKPWhlYWQyICRBcmNoaXZlOjpUYXI6OkNIT1dOCgpCeSBkZWZhdWx0LCBDPEFyY2hpdmU6OlRhcj4gd2lsbCB0cnkgdG8gQzxjaG93bj4geW91ciBmaWxlcyBpZiBpdCBpcwphYmxlIHRvLiBJbiBzb21lIGNhc2VzLCB0aGlzIG1heSBub3QgYmUgZGVzaXJlZC4gSW4gdGhhdCBjYXNlLCBzZXQKdGhpcyB2YXJpYWJsZSB0byBDPDA+IHRvIGRpc2FibGUgQzxjaG93bj4taW5nLCBldmVuIGlmIGl0IHdlcmUKcG9zc2libGUuCgpUaGUgZGVmYXVsdCBpcyBDPDE+LgoKPWhlYWQyICRBcmNoaXZlOjpUYXI6OkNITU9ECgpCeSBkZWZhdWx0LCBDPEFyY2hpdmU6OlRhcj4gd2lsbCB0cnkgdG8gQzxjaG1vZD4geW91ciBmaWxlcyB0bwp3aGF0ZXZlciBtb2RlIHdhcyBzcGVjaWZpZWQgZm9yIHRoZSBwYXJ0aWN1bGFyIGZpbGUgaW4gdGhlIGFyY2hpdmUuCkluIHNvbWUgY2FzZXMsIHRoaXMgbWF5IG5vdCBiZSBkZXNpcmVkLiBJbiB0aGF0IGNhc2UsIHNldCB0aGlzCnZhcmlhYmxlIHRvIEM8MD4gdG8gZGlzYWJsZSBDPGNobW9kPi1pbmcuCgpUaGUgZGVmYXVsdCBpcyBDPDE+LgoKPWhlYWQyICRBcmNoaXZlOjpUYXI6OkRPX05PVF9VU0VfUFJFRklYCgpCeSBkZWZhdWx0LCBDPEFyY2hpdmU6OlRhcj4gd2lsbCB0cnkgdG8gcHV0IHBhdGhzIHRoYXQgYXJlIG92ZXIgCjEwMCBjaGFyYWN0ZXJzIGluIHRoZSBDPHByZWZpeD4gZmllbGQgb2YgeW91ciB0YXIgaGVhZGVyLCBhcwpkZWZpbmVkIHBlciBQT1NJWC1zdGFuZGFyZC4gSG93ZXZlciwgc29tZSAob2xkZXIpIHRhciBwcm9ncmFtcyAKZG8gbm90IGltcGxlbWVudCB0aGlzIHNwZWMuIFRvIHJldGFpbiBjb21wYXRpYmlsaXR5IHdpdGggdGhlc2Ugb2xkZXIgCm9yIG5vbi1QT1NJWCBjb21wbGlhbnQgdmVyc2lvbnMsIHlvdSBjYW4gc2V0IHRoZSBDPCRET19OT1RfVVNFX1BSRUZJWD4gCnZhcmlhYmxlIHRvIGEgdHJ1ZSB2YWx1ZSwgYW5kIEM8QXJjaGl2ZTo6VGFyPiB3aWxsIHVzZSBhbiBhbHRlcm5hdGUgCndheSBvZiBkZWFsaW5nIHdpdGggcGF0aHMgb3ZlciAxMDAgY2hhcmFjdGVycyBieSB1c2luZyB0aGUgCkM8R05VIEV4dGVuZGVkIEhlYWRlcj4gZmVhdHVyZS4KCk5vdGUgdGhhdCBjbGllbnRzIHdobyBkbyBub3Qgc3VwcG9ydCB0aGUgQzxHTlUgRXh0ZW5kZWQgSGVhZGVyPgpmZWF0dXJlIHdpbGwgbm90IGJlIGFibGUgdG8gcmVhZCB0aGVzZSBhcmNoaXZlcy4gU3VjaCBjbGllbnRzIGluY2x1ZGUKdGFycyBvbiBDPFNvbGFyaXM+LCBDPElyaXg+IGFuZCBDPEFJWD4uCgpUaGUgZGVmYXVsdCBpcyBDPDA+LgoKPWhlYWQyICRBcmNoaXZlOjpUYXI6OkRFQlVHCgpTZXQgdGhpcyB2YXJpYWJsZSB0byBDPDE+IHRvIGFsd2F5cyBnZXQgdGhlIEM8Q2FycDo6bG9uZ21lc3M+IG91dHB1dApvZiB0aGUgd2FybmluZ3MsIGluc3RlYWQgb2YgdGhlIHJlZ3VsYXIgQzxjYXJwPi4gVGhpcyBpcyB0aGUgc2FtZQptZXNzYWdlIHlvdSB3b3VsZCBnZXQgYnkgZG9pbmc6CgogICAgJHRhci0+ZXJyb3IoMSk7CgpEZWZhdWx0cyB0byBDPDA+LgoKPWhlYWQyICRBcmNoaXZlOjpUYXI6OldBUk4KClNldCB0aGlzIHZhcmlhYmxlIHRvIEM8MD4gaWYgeW91IGRvIG5vdCB3YW50IGFueSB3YXJuaW5ncyBwcmludGVkLgpQZXJzb25hbGx5IEkgcmVjb21tZW5kIGFnYWluc3QgZG9pbmcgdGhpcywgYnV0IHBlb3BsZSBhc2tlZCBmb3IgdGhlCm9wdGlvbi4gQWxzbywgYmUgYWR2aXNlZCB0aGF0IHRoaXMgaXMgb2YgY291cnNlIG5vdCB0aHJlYWRzYWZlLgoKRGVmYXVsdHMgdG8gQzwxPi4KCj1oZWFkMiAkQXJjaGl2ZTo6VGFyOjplcnJvcgoKSG9sZHMgdGhlIGxhc3QgcmVwb3J0ZWQgZXJyb3IuIEtlcHQgZm9yIGhpc3RvcmljYWwgcmVhc29ucywgYnV0IGl0cwp1c2UgaXMgdmVyeSBtdWNoIGRpc2NvdXJhZ2VkLiBVc2UgdGhlIEM8ZXJyb3IoKT4gbWV0aG9kIGluc3RlYWQ6CgogICAgd2FybiAkdGFyLT5lcnJvciB1bmxlc3MgJHRhci0+ZXh0cmFjdDsKCj1oZWFkMiAkQXJjaGl2ZTo6VGFyOjpIQVNfUEVSTElPCgpUaGlzIHZhcmlhYmxlIGhvbGRzIGEgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIHdlIGN1cnJlbnRseSBoYXZlIApDPHBlcmxpbz4gc3VwcG9ydCBsb2FkZWQuIFRoaXMgd2lsbCBiZSBlbmFibGVkIGZvciBhbnkgcGVybApncmVhdGVyIHRoYW4gQzw1Ljg+IGNvbXBpbGVkIHdpdGggQzxwZXJsaW8+LiAKCklmIHlvdSBmZWVsIHN0cm9uZ2x5IGFib3V0IGRpc2FibGluZyBpdCwgc2V0IHRoaXMgdmFyaWFibGUgdG8KQzxmYWxzZT4uIE5vdGUgdGhhdCB5b3Ugd2lsbCB0aGVuIG5lZWQgQzxJTzo6U3RyaW5nPiBpbnN0YWxsZWQKdG8gc3VwcG9ydCB3cml0aW5nIHN0cmluZ2lmaWVkIGFyY2hpdmVzLgoKRG9uJ3QgY2hhbmdlIHRoaXMgdmFyaWFibGUgdW5sZXNzIHlvdSBCPHJlYWxseT4ga25vdyB3aGF0IHlvdSdyZQpkb2luZy4KCj1oZWFkMiAkQXJjaGl2ZTo6VGFyOjpIQVNfSU9fU1RSSU5HCgpUaGlzIHZhcmlhYmxlIGhvbGRzIGEgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIHdlIGN1cnJlbnRseSBoYXZlIApDPElPOjpTdHJpbmc+IHN1cHBvcnQgbG9hZGVkLiBUaGlzIHdpbGwgYmUgZW5hYmxlZCBmb3IgYW55IHBlcmwKdGhhdCBoYXMgYSBsb2FkYWJsZSBDPElPOjpTdHJpbmc+IG1vZHVsZS4KCklmIHlvdSBmZWVsIHN0cm9uZ2x5IGFib3V0IGRpc2FibGluZyBpdCwgc2V0IHRoaXMgdmFyaWFibGUgdG8KQzxmYWxzZT4uIE5vdGUgdGhhdCB5b3Ugd2lsbCB0aGVuIG5lZWQgQzxwZXJsaW8+IHN1cHBvcnQgZnJvbQp5b3VyIHBlcmwgdG8gYmUgYWJsZSB0byAgd3JpdGUgc3RyaW5naWZpZWQgYXJjaGl2ZXMuCgpEb24ndCBjaGFuZ2UgdGhpcyB2YXJpYWJsZSB1bmxlc3MgeW91IEI8cmVhbGx5PiBrbm93IHdoYXQgeW91J3JlCmRvaW5nLgoKPWhlYWQxIEZBUQoKPW92ZXIgNAoKPWl0ZW0gV2hhdCdzIHRoZSBtaW5pbXVtIHBlcmwgdmVyc2lvbiByZXF1aXJlZCB0byBydW4gQXJjaGl2ZTo6VGFyPwoKWW91IHdpbGwgbmVlZCBwZXJsIHZlcnNpb24gNS4wMDVfMDMgb3IgbmV3ZXIuCgo9aXRlbSBJc24ndCBBcmNoaXZlOjpUYXIgc2xvdz8KClllcyBpdCBpcy4gSXQncyBwdXJlIHBlcmwsIHNvIGl0J3MgYSBsb3Qgc2xvd2VyIHRoZW4geW91ciBDPC9iaW4vdGFyPgpIb3dldmVyLCBpdCdzIHZlcnkgcG9ydGFibGUuIElmIHNwZWVkIGlzIGFuIGlzc3VlLCBjb25zaWRlciB1c2luZwpDPC9iaW4vdGFyPiBpbnN0ZWFkLgoKPWl0ZW0gSXNuJ3QgQXJjaGl2ZTo6VGFyIGhlYXZpZXIgb24gbWVtb3J5IHRoYW4gL2Jpbi90YXI/CgpZZXMgaXQgaXMsIHNlZSBwcmV2aW91cyBhbnN3ZXIuIFNpbmNlIEM8Q29tcHJlc3M6OlpsaWI+IGFuZCB0aGVyZWZvcmUKQzxJTzo6WmxpYj4gZG9lc24ndCBzdXBwb3J0IEM8c2Vlaz4gb24gdGhlaXIgZmlsZWhhbmRsZXMsIHRoZXJlIGlzIGxpdHRsZQpjaG9pY2UgYnV0IHRvIHJlYWQgdGhlIGFyY2hpdmUgaW50byBtZW1vcnkuClRoaXMgaXMgb2sgaWYgeW91IHdhbnQgdG8gZG8gaW4tbWVtb3J5IG1hbmlwdWxhdGlvbiBvZiB0aGUgYXJjaGl2ZS4KSWYgeW91IGp1c3Qgd2FudCB0byBleHRyYWN0LCB1c2UgdGhlIEM8ZXh0cmFjdF9hcmNoaXZlPiBjbGFzcyBtZXRob2QKaW5zdGVhZC4gSXQgd2lsbCBvcHRpbWl6ZSBhbmQgd3JpdGUgdG8gZGlzayBpbW1lZGlhdGVseS4KCj1pdGVtIENhbid0IHlvdSBsYXp5LWxvYWQgZGF0YSBpbnN0ZWFkPwoKTm8sIG5vdCBlYXNpbHkuIFNlZSBwcmV2aW91cyBxdWVzdGlvbi4KCj1pdGVtIEhvdyBtdWNoIG1lbW9yeSB3aWxsIGFuIFgga2IgdGFyIGZpbGUgbmVlZD8KClByb2JhYmx5IG1vcmUgdGhhbiBYIGtiLCBzaW5jZSBpdCB3aWxsIGFsbCBiZSByZWFkIGludG8gbWVtb3J5LiBJZgp0aGlzIGlzIGEgcHJvYmxlbSwgYW5kIHlvdSBkb24ndCBuZWVkIHRvIGRvIGluIG1lbW9yeSBtYW5pcHVsYXRpb24Kb2YgdGhlIGFyY2hpdmUsIGNvbnNpZGVyIHVzaW5nIEM8L2Jpbi90YXI+IGluc3RlYWQuCgo9aXRlbSBXaGF0IGRvIHlvdSBkbyB3aXRoIHVuc3VwcG9ydGVkIGZpbGV0eXBlcyBpbiBhbiBhcmNoaXZlPwoKQzxVbml4PiBoYXMgYSBmZXcgZmlsZXR5cGVzIHRoYXQgYXJlbid0IHN1cHBvcnRlZCBvbiBvdGhlciBwbGF0Zm9ybXMsCmxpa2UgQzxXaW4zMj4uIElmIHdlIGVuY291bnRlciBhIEM8aGFyZGxpbms+IG9yIEM8c3ltbGluaz4gd2UnbGwganVzdAp0cnkgdG8gbWFrZSBhIGNvcHkgb2YgdGhlIG9yaWdpbmFsIGZpbGUsIHJhdGhlciB0aGFuIHRocm93aW5nIGFuIGVycm9yLgoKVGhpcyBkb2VzIHJlcXVpcmUgeW91IHRvIHJlYWQgdGhlIGVudGlyZSBhcmNoaXZlIGluIHRvIG1lbW9yeSBmaXJzdCwKc2luY2Ugb3RoZXJ3aXNlIHdlIHdvdWxkbid0IGtub3cgd2hhdCBkYXRhIHRvIGZpbGwgdGhlIGNvcHkgd2l0aC4KKFRoaXMgbWVhbnMgdGhhdCB5b3UgY2Fubm90IHVzZSB0aGUgY2xhc3MgbWV0aG9kcyBvbiBhcmNoaXZlcyB0aGF0CmhhdmUgaW5jb21wYXRpYmxlIGZpbGV0eXBlcyBhbmQgc3RpbGwgZXhwZWN0IHRoaW5ncyB0byB3b3JrKS4KCkZvciBvdGhlciBmaWxldHlwZXMsIGxpa2UgQzxjaGFyZGV2cz4gYW5kIEM8YmxvY2tkZXZzPiB3ZSdsbCB3YXJuIHRoYXQKdGhlIGV4dHJhY3Rpb24gb2YgdGhpcyBwYXJ0aWN1bGFyIGl0ZW0gZGlkbid0IHdvcmsuCgo9aXRlbSBJJ20gdXNpbmcgV2luWmlwLCBvciBzb21lIG90aGVyIG5vbi1QT1NJWCBjbGllbnQsIGFuZCBmaWxlcyBhcmUgbm90IGJlaW5nIGV4dHJhY3RlZCBwcm9wZXJseSEKCkJ5IGRlZmF1bHQsIEM8QXJjaGl2ZTo6VGFyPiBpcyBpbiBhIGNvbXBsZXRlbHkgUE9TSVgtY29tcGF0aWJsZQptb2RlLCB3aGljaCB1c2VzIHRoZSBQT1NJWC1zcGVjaWZpY2F0aW9uIG9mIEM8dGFyPiB0byBzdG9yZSBmaWxlcy4KRm9yIHBhdGhzIGdyZWF0aGVyIHRoYW4gMTAwIGNoYXJhY3RlcnMsIHRoaXMgaXMgZG9uZSB1c2luZyB0aGUKQzxQT1NJWCBoZWFkZXIgcHJlZml4Pi4gTm9uLVBPU0lYLWNvbXBhdGlibGUgY2xpZW50cyBtYXkgbm90IHN1cHBvcnQKdGhpcyBwYXJ0IG9mIHRoZSBzcGVjaWZpY2F0aW9uLCBhbmQgbWF5IG9ubHkgc3VwcG9ydCB0aGUgQzxHTlUgRXh0ZW5kZWQKSGVhZGVyPiBmdW5jdGlvbmFsaXR5LiBUbyBmYWNpbGl0YXRlIHRob3NlIGNsaWVudHMsIHlvdSBjYW4gc2V0IHRoZQpDPCRBcmNoaXZlOjpUYXI6OkRPX05PVF9VU0VfUFJFRklYPiB2YXJpYWJsZSB0byBDPHRydWU+LiBTZWUgdGhlIApDPEdMT0JBTCBWQVJJQUJMRVM+IHNlY3Rpb24gZm9yIGRldGFpbHMgb24gdGhpcyB2YXJpYWJsZS4KCk5vdGUgdGhhdCBHTlUgdGFyIGVhcmxpZXIgdGhhbiB2ZXJzaW9uIDEuMTQgZG9lcyBub3QgY29wZSB3ZWxsIHdpdGgKdGhlIEM8UE9TSVggaGVhZGVyIHByZWZpeD4uIElmIHlvdSB1c2Ugc3VjaCBhIHZlcnNpb24sIGNvbnNpZGVyIHNldHRpbmcKdGhlIEM8JEFyY2hpdmU6OlRhcjo6RE9fTk9UX1VTRV9QUkVGSVg+IHZhcmlhYmxlIHRvIEM8dHJ1ZT4uCgo9aXRlbSBIb3cgZG8gSSBleHRyYWN0IG9ubHkgZmlsZXMgdGhhdCBoYXZlIHByb3BlcnR5IFggZnJvbSBhbiBhcmNoaXZlPwoKU29tZXRpbWVzLCB5b3UgbWlnaHQgbm90IHdpc2ggdG8gZXh0cmFjdCBhIGNvbXBsZXRlIGFyY2hpdmUsIGp1c3QKdGhlIGZpbGVzIHRoYXQgYXJlIHJlbGV2YW50IHRvIHlvdSwgYmFzZWQgb24gc29tZSBjcml0ZXJpYS4KCllvdSBjYW4gZG8gdGhpcyBieSBmaWx0ZXJpbmcgYSBsaXN0IG9mIEM8QXJjaGl2ZTo6VGFyOjpGaWxlPiBvYmplY3RzCmJhc2VkIG9uIHlvdXIgY3JpdGVyaWEuIEZvciBleGFtcGxlLCB0byBleHRyYWN0IG9ubHkgZmlsZXMgdGhhdCBoYXZlCnRoZSBzdHJpbmcgQzxmb28+IGluIHRoZWlyIHRpdGxlLCB5b3Ugd291bGQgdXNlOgoKICAgICR0YXItPmV4dHJhY3QoIAogICAgICAgIGdyZXAgeyAkXy0+ZnVsbF9wYXRoID1+IC9mb28vIH0gJHRhci0+Z2V0X2ZpbGVzCiAgICApOyAKClRoaXMgd2F5LCB5b3UgY2FuIGZpbHRlciBvbiBhbnkgYXR0cmlidXRlIG9mIHRoZSBmaWxlcyBpbiB0aGUgYXJjaGl2ZS4KQ29uc3VsdCB0aGUgQzxBcmNoaXZlOjpUYXI6OkZpbGU+IGRvY3VtZW50YXRpb24gb24gaG93IHRvIHVzZSB0aGVzZQpvYmplY3RzLgoKPWl0ZW0gSG93IGRvIEkgYWNjZXNzIC50YXIuWiBmaWxlcz8KClRoZSBDPEFyY2hpdmU6OlRhcj4gbW9kdWxlIGNhbiBvcHRpb25hbGx5IHVzZSBDPENvbXByZXNzOjpabGliPiAodmlhCnRoZSBDPElPOjpabGliPiBtb2R1bGUpIHRvIGFjY2VzcyB0YXIgZmlsZXMgdGhhdCBoYXZlIGJlZW4gY29tcHJlc3NlZAp3aXRoIEM8Z3ppcD4uIFVuZm9ydHVuYXRlbHkgdGFyIGZpbGVzIGNvbXByZXNzZWQgd2l0aCB0aGUgVW5peCBDPGNvbXByZXNzPgp1dGlsaXR5IGNhbm5vdCBiZSByZWFkIGJ5IEM8Q29tcHJlc3M6OlpsaWI+IGFuZCBzbyBjYW5ub3QgYmUgZGlyZWN0bHkKYWNjZXNzZXMgYnkgQzxBcmNoaXZlOjpUYXI+LgoKSWYgdGhlIEM8dW5jb21wcmVzcz4gb3IgQzxndW56aXA+IHByb2dyYW1zIGFyZSBhdmFpbGFibGUsIHlvdSBjYW4gdXNlCm9uZSBvZiB0aGVzZSB3b3JrYXJvdW5kcyB0byByZWFkIEM8LnRhci5aPiBmaWxlcyBmcm9tIEM8QXJjaGl2ZTo6VGFyPgoKRmlyc3RseSB3aXRoIEM8dW5jb21wcmVzcz4KCiAgICB1c2UgQXJjaGl2ZTo6VGFyOwoKICAgIG9wZW4gRiwgInVuY29tcHJlc3MgLWMgJGZpbGVuYW1lIHwiOwogICAgbXkgJHRhciA9IEFyY2hpdmU6OlRhci0+bmV3KCpGKTsKICAgIC4uLgoKYW5kIHRoaXMgd2l0aCBDPGd1bnppcD4KCiAgICB1c2UgQXJjaGl2ZTo6VGFyOwoKICAgIG9wZW4gRiwgImd1bnppcCAtYyAkZmlsZW5hbWUgfCI7CiAgICBteSAkdGFyID0gQXJjaGl2ZTo6VGFyLT5uZXcoKkYpOwogICAgLi4uCgpTaW1pbGFybHksIGlmIHRoZSBDPGNvbXByZXNzPiBwcm9ncmFtIGlzIGF2YWlsYWJsZSwgeW91IGNhbiB1c2UgdGhpcyB0bwp3cml0ZSBhIEM8LnRhci5aPiBmaWxlCgogICAgdXNlIEFyY2hpdmU6OlRhcjsKICAgIHVzZSBJTzo6RmlsZTsKCiAgICBteSAkZmggPSBuZXcgSU86OkZpbGUgInwgY29tcHJlc3MgLWMgPiRmaWxlbmFtZSI7CiAgICBteSAkdGFyID0gQXJjaGl2ZTo6VGFyLT5uZXcoKTsKICAgIC4uLgogICAgJHRhci0+d3JpdGUoJGZoKTsKICAgICRmaC0+Y2xvc2UgOwoKPWl0ZW0gSG93IGRvIEkgaGFuZGxlIFVuaWNvZGUgc3RyaW5ncz8KCkM8QXJjaGl2ZTo6VGFyPiB1c2VzIGJ5dGUgc2VtYW50aWNzIGZvciBhbnkgZmlsZXMgaXQgcmVhZHMgZnJvbSBvciB3cml0ZXMKdG8gZGlzay4gVGhpcyBpcyBub3QgYSBwcm9ibGVtIGlmIHlvdSBvbmx5IGRlYWwgd2l0aCBmaWxlcyBhbmQgbmV2ZXIKbG9vayBhdCB0aGVpciBjb250ZW50IG9yIHdvcmsgc29sZWx5IHdpdGggYnl0ZSBzdHJpbmdzLiBCdXQgaWYgeW91IHVzZQpVbmljb2RlIHN0cmluZ3Mgd2l0aCBjaGFyYWN0ZXIgc2VtYW50aWNzLCBzb21lIGFkZGl0aW9uYWwgc3RlcHMgbmVlZAp0byBiZSB0YWtlbi4KCkZvciBleGFtcGxlLCBpZiB5b3UgYWRkIGEgVW5pY29kZSBzdHJpbmcgbGlrZQoKICAgICMgUHJvYmxlbQogICAgJHRhci0+YWRkX2RhdGEoJ2ZpbGUudHh0JywgIkV1cm86IFx4ezIwQUN9Iik7Cgp0aGVuIHRoZXJlIHdpbGwgYmUgYSBwcm9ibGVtIGxhdGVyIHdoZW4gdGhlIHRhcmZpbGUgZ2V0cyB3cml0dGVuIG91dAp0byBkaXNrIHZpYSBDPCR0YXItPndyaXRlKCk+OgoKICAgIFdpZGUgY2hhcmFjdGVyIGluIHByaW50IGF0IC4uLi9BcmNoaXZlL1Rhci5wbSBsaW5lIDEwMTQuCgpUaGUgZGF0YSB3YXMgYWRkZWQgYXMgYSBVbmljb2RlIHN0cmluZyBhbmQgd2hlbiB3cml0aW5nIGl0IG91dCB0byBkaXNrLAp0aGUgQzw6dXRmOD4gbGluZSBkaXNjaXBsaW5lIHdhc24ndCBzZXQgYnkgQzxBcmNoaXZlOjpUYXI+LCBzbyBQZXJsCnRyaWVkIHRvIGNvbnZlcnQgdGhlIHN0cmluZyB0byBJU08tODg1OSBhbmQgZmFpbGVkLiBUaGUgd3JpdHRlbiBmaWxlCm5vdyBjb250YWlucyBnYXJiYWdlLgoKRm9yIHRoaXMgcmVhc29uLCBVbmljb2RlIHN0cmluZ3MgbmVlZCB0byBiZSBjb252ZXJ0ZWQgdG8gVVRGLTgtZW5jb2RlZApieXRlc3RyaW5ncyBiZWZvcmUgdGhleSBhcmUgaGFuZGVkIG9mZiB0byBDPGFkZF9kYXRhKCk+OgoKICAgIHVzZSBFbmNvZGU7CiAgICBteSAkZGF0YSA9ICJBY2NlbnRlZCBjaGFyYWN0ZXI6IFx4ezIwQUN9IjsKICAgICRkYXRhID0gZW5jb2RlKCd1dGY4JywgJGRhdGEpOwoKICAgICR0YXItPmFkZF9kYXRhKCdmaWxlLnR4dCcsICRkYXRhKTsKCkEgb3Bwb3NpdGUgcHJvYmxlbSBvY2N1cnMgaWYgeW91IGV4dHJhY3QgYSBVVEY4LWVuY29kZWQgZmlsZSBmcm9tIGEgCnRhcmJhbGwuIFVzaW5nIEM8Z2V0X2NvbnRlbnQoKT4gb24gdGhlIEM8QXJjaGl2ZTo6VGFyOjpGaWxlPiBvYmplY3QKd2lsbCByZXR1cm4gaXRzIGNvbnRlbnQgYXMgYSBieXRlc3RyaW5nLCBub3QgYXMgYSBVbmljb2RlIHN0cmluZy4KCklmIHlvdSB3YW50IGl0IHRvIGJlIGEgVW5pY29kZSBzdHJpbmcgKGJlY2F1c2UgeW91IHdhbnQgY2hhcmFjdGVyCnNlbWFudGljcyB3aXRoIG9wZXJhdGlvbnMgbGlrZSByZWd1bGFyIGV4cHJlc3Npb24gbWF0Y2hpbmcpLCB5b3UgbmVlZAp0byBkZWNvZGUgdGhlIFVURjgtZW5jb2RlZCBjb250ZW50IGFuZCBoYXZlIFBlcmwgY29udmVydCBpdCBpbnRvIAphIFVuaWNvZGUgc3RyaW5nOgoKICAgIHVzZSBFbmNvZGU7CiAgICBteSAkZGF0YSA9ICR0YXItPmdldF9jb250ZW50KCk7CiAgICAKICAgICMgTWFrZSBpdCBhIFVuaWNvZGUgc3RyaW5nCiAgICAkZGF0YSA9IGRlY29kZSgndXRmOCcsICRkYXRhKTsKClRoZXJlIGlzIG5vIGVhc3kgd2F5IHRvIHByb3ZpZGUgdGhpcyBmdW5jdGlvbmFsaXR5IGluIEM8QXJjaGl2ZTo6VGFyPiwgCmJlY2F1c2UgYSB0YXJiYWxsIGNhbiBjb250YWluIG1hbnkgZmlsZXMsIGFuZCBlYWNoIG9mIHdoaWNoIGNvdWxkIGJlCmVuY29kZWQgaW4gYSBkaWZmZXJlbnQgd2F5LgoKPWJhY2sKCj1oZWFkMSBUT0RPCgo9b3ZlciA0Cgo9aXRlbSBDaGVjayBpZiBwYXNzZWQgaW4gaGFuZGxlcyBhcmUgb3BlbiBmb3IgcmVhZC93cml0ZQoKQ3VycmVudGx5IEkgZG9uJ3Qga25vdyBvZiBhbnkgcG9ydGFibGUgcHVyZSBwZXJsIHdheSB0byBkbyB0aGlzLgpTdWdnZXN0aW9ucyB3ZWxjb21lLgoKPWl0ZW0gQWxsb3cgYXJjaGl2ZXMgdG8gYmUgcGFzc2VkIGluIGFzIHN0cmluZwoKQ3VycmVudGx5LCB3ZSBvbmx5IGFsbG93IG9wZW5lZCBmaWxlaGFuZGxlcyBvciBmaWxlbmFtZXMsIGJ1dApub3Qgc3RyaW5ncy4gVGhlIGludGVybmFscyB3b3VsZCBuZWVkIHNvbWUgcmV3b3JraW5nIHRvIGZhY2lsaXRhdGUKc3RyaW5naWZpZWQgYXJjaGl2ZXMuCgo9aXRlbSBGYWNpbGl0YXRlIHByb2Nlc3NpbmcgYW4gb3BlbmVkIGZpbGVoYW5kbGUgb2YgYSBjb21wcmVzc2VkIGFyY2hpdmUKCkN1cnJlbnRseSwgd2Ugb25seSBzdXBwb3J0IHRoaXMgaWYgdGhlIGZpbGVoYW5kbGUgaXMgYW4gSU86OlpsaWIgb2JqZWN0LgpFbnZpcm9ubWVudHMsIGxpa2UgYXBhY2hlLCB3aWxsIHByZXNlbnQgeW91IHdpdGggYW4gb3BlbmVkIGZpbGVoYW5kbGUKdG8gYW4gdXBsb2FkZWQgZmlsZSwgd2hpY2ggbWlnaHQgYmUgYSBjb21wcmVzc2VkIGFyY2hpdmUuCgo9YmFjawoKPWhlYWQxIFNFRSBBTFNPCgo9b3ZlciA0Cgo9aXRlbSBUaGUgR05VIHRhciBzcGVjaWZpY2F0aW9uCgpDPGh0dHA6Ly93d3cuZ251Lm9yZy9zb2Z0d2FyZS90YXIvbWFudWFsL3Rhci5odG1sPgoKPWl0ZW0gVGhlIFBBWCBmb3JtYXQgc3BlY2ljYXRpb24KClRoZSBzcGVjaWZjYXRpb24gd2hpY2ggdGFyIGRlcml2ZXMgZnJvbTsgQzwgaHR0cDovL3d3dy5vcGVuZ3JvdXAub3JnL29ubGluZXB1YnMvMDA3OTA0OTc1L3V0aWxpdGllcy9wYXguaHRtbD4KCj1pdGVtIEEgY29tcGFyaXNvbiBvZiBHTlUgYW5kIFBPU0lYIHRhciBzdGFuZGFyZHM7IEM8aHR0cDovL3d3dy5kZWxvcmllLmNvbS9nbnUvZG9jcy90YXIvdGFyXzExNC5odG1sPgoKPWl0ZW0gR05VIHRhciBpbnRlbmRzIHRvIHN3aXRjaCB0byBQT1NJWCBjb21wYXRpYmlsaXR5CgpHTlUgVGFyIGF1dGhvcnMgaGF2ZSBleHByZXNzZWQgdGhlaXIgaW50ZW50aW9uIHRvIGJlY29tZSBjb21wbGV0ZWx5ClBPU0lYLWNvbXBhdGlibGU7IEM8aHR0cDovL3d3dy5nbnUub3JnL3NvZnR3YXJlL3Rhci9tYW51YWwvaHRtbF9ub2RlL0Zvcm1hdHMuaHRtbD4KCj1pdGVtIEEgQ29tcGFyaXNvbiBiZXR3ZWVuIHZhcmlvdXMgdGFyIGltcGxlbWVudGF0aW9ucwoKTGlzdHMga25vd24gaXNzdWVzIGFuZCBpbmNvbXBhdGliaWxpdGllczsgQzxodHRwOi8vZ2QudHV3aWVuLmFjLmF0L3V0aWxzL2FyY2hpdmVycy9zdGFyL1JFQURNRS5vdGhlcmJ1Z3M+Cgo9YmFjawoKPWhlYWQxIEFVVEhPUgoKVGhpcyBtb2R1bGUgYnkgSm9zIEJvdW1hbnMgRTxsdD5rYW5lQGNwYW4ub3JnRTxndD4uCgpQbGVhc2UgcmVwb3J0cyBidWdzIHRvIEU8bHQ+YnVnLWFyY2hpdmUtdGFyQHJ0LmNwYW4ub3JnRTxndD4uCgo9aGVhZDEgQUNLTk9XTEVER0VNRU5UUwoKVGhhbmtzIHRvIFNlYW4gQnVya2UsIENocmlzIE5hbmRvciwgQ2hpcCBTYWx6ZW5iZXJnLCBUaW0gSGVhbmV5IGFuZAplc3BlY2lhbGx5IEFuZHJldyBTYXZpZ2UgZm9yIHRoZWlyIGhlbHAgYW5kIHN1Z2dlc3Rpb25zLgoKPWhlYWQxIENPUFlSSUdIVAoKVGhpcyBtb2R1bGUgaXMgY29weXJpZ2h0IChjKSAyMDAyIC0gMjAwNyBKb3MgQm91bWFucyAKRTxsdD5rYW5lQGNwYW4ub3JnRTxndD4uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgpUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IG1heSByZWRpc3RyaWJ1dGUgYW5kL29yIG1vZGlmeSAKaXQgdW5kZXIgdGhlIHNhbWUgdGVybXMgYXMgUGVybCBpdHNlbGYuCgo9Y3V0Cg==
IyAtLQojIEtlcm5lbC9Nb2R1bGVzL0FkbWluU3VwcG9ydC5wbSAtIHNob3cgc3VwcG9ydCBpbmZvcm1hdGlvbgojIENvcHlyaWdodCAoQykgMjAwMS0yMDA3IE9UUlMgR21iSCwgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBBZG1pblN1cHBvcnQucG0sdiAxLjYgMjAwNy8xMC8wNCAwODozMjo1OCBzciBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpNb2R1bGVzOjpBZG1pblN1cHBvcnQ7Cgp1c2Ugc3RyaWN0Owp1c2UgS2VybmVsOjpTeXN0ZW06OlN1cHBvcnQ7Cgp1c2UgdmFycyBxdygkVkVSU0lPTik7CiRWRVJTSU9OID0gJyRSZXZpc2lvbjogMS42ICQnOwokVkVSU0lPTiA9fiBzL15cJC4qOlxXKC4qKVxXLis/JC8kMS87CgpzdWIgbmV3IHsKICAgIG15ICRUeXBlID0gc2hpZnQ7CiAgICBteSAlUGFyYW0gPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyAoJFNlbGYsICRUeXBlKTsKCiAgICBmb3JlYWNoIChrZXlzICVQYXJhbSkgewogICAgICAgICRTZWxmLT57JF99ID0gJFBhcmFteyRffTsKICAgIH0KCiAgICAjIGNoZWNrIG5lZWRlZCBPYmplY3RzCiAgICBmb3JlYWNoIChxdyhQYXJhbU9iamVjdCBMYXlvdXRPYmplY3QgTG9nT2JqZWN0IENvbmZpZ09iamVjdCBUaW1lT2JqZWN0KSkgewogICAgICAgIGlmICghJFNlbGYtPnskX30pIHsKICAgICAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5GYXRhbEVycm9yKE1lc3NhZ2UgPT4gIkdvdCBubyAkXyEiKTsKICAgICAgICB9CiAgICB9CiAgICAkU2VsZi0+e1N1cHBvcnRPYmplY3R9ID0gS2VybmVsOjpTeXN0ZW06OlN1cHBvcnQtPm5ldyglUGFyYW0pOwoKICAgIHJldHVybiAkU2VsZjsKfQoKc3ViIFJ1biB7CiAgICBteSAkU2VsZiA9IHNoaWZ0OwogICAgbXkgJVBhcmFtID0gQF87CiAgICBteSAkQ29uZmlnSGFzaCA9IHt9OwoKICAgICMgY3JlYXRlIGNvbmZpZyBoYXNoIHJlZmVyZW5jZQogICAgJFNlbGYtPntTdXBwb3J0T2JqZWN0fS0+U3VwcG9ydENvbmZpZ0hhc2hHZXQoCiAgICAgICAgQ29uZmlnSGFzaCA9PiAkQ29uZmlnSGFzaCwKICAgICk7CgogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgIyBHZXQgcmVxdWlyZWQgaW5mb3JtYXRpb24KICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKCiAgICBpZiAoJFNlbGYtPntTdWJhY3Rpb259IGVxICdHZXRSZXF1aXJlZEluZm8nKSB7CiAgICAgICAgIyBmaXJzdCBsZXZlbCBIYXNocmVmIChlYWNoIG1vZHVsZSBuYW1lKQogICAgICAgIG15ICRDb250ZW50Q2hlY2sgPSAnMCc7CiAgICAgICAgZm9yZWFjaCBteSAkQ29uZmlnTW9kdWxlIChzb3J0IGtleXMgJXskQ29uZmlnSGFzaH0pIHsKICAgICAgICAgICAgaWYgKCEkQ29uZmlnSGFzaC0+eyRDb25maWdNb2R1bGV9LT5bMF0pIHsKICAgICAgICAgICAgICAgIG5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZXsKICAgICAgICAgICAgICAgICRDb250ZW50Q2hlY2sgPSAnMSc7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCRDb250ZW50Q2hlY2sgZXEgJzEnKSB7CiAgICAgICAgICAgICMgY3JlYXRlICYgcmV0dXJuIG91dHB1dAogICAgICAgICAgICBteSAkT3V0cHV0ID0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5IZWFkZXIoKTsKICAgICAgICAgICAgJE91dHB1dCAuPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPk5hdmlnYXRpb25CYXIoKTsKCiAgICAgICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QmxvY2soCiAgICAgICAgICAgICAgICBOYW1lID0+ICdSZXF1aXJlZCcsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICMgZmlyc3QgbGV2ZWwgSGFzaHJlZiAoZWFjaCBtb2R1bGUgbmFtZSkKICAgICAgICAgICAgZm9yZWFjaCBteSAkQ29uZmlnTW9kdWxlIChzb3J0IGtleXMgJXskQ29uZmlnSGFzaH0pIHsKICAgICAgICAgICAgICAgIGlmICghJENvbmZpZ0hhc2gtPnskQ29uZmlnTW9kdWxlfS0+WzBdKSB7CiAgICAgICAgICAgICAgICAgICAgbmV4dDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QmxvY2soCiAgICAgICAgICAgICAgICAgICAgTmFtZSA9PiAnUmVxdWlyZWRJbmZvJywKICAgICAgICAgICAgICAgICAgICBEYXRhID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgQ29uZmlnTW9kdWxlID0+ICRDb25maWdNb2R1bGUsCiAgICAgICAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAjIHNlY29uZCBsZXZlbCBhcnJheSByZWZlcmVuY2UgKGVhY2ggbW9kdWxlKQogICAgICAgICAgICAgICAgZm9yZWFjaCBteSAkQ29uZmlnSGFzaFJvdyAoQHskQ29uZmlnSGFzaC0+eyRDb25maWdNb2R1bGV9fSkgewogICAgICAgICAgICAgICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QmxvY2soCiAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1JlcXVpcmVkSW5mb1JvdycsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAjIGNyZWF0ZSBhIG5ldyB0ZXh0ZmllbGQKICAgICAgICAgICAgICAgICAgICBpZiAoJENvbmZpZ0hhc2hSb3ctPntJbnB1dH0tPntUeXBlfSBlcSAiVGV4dCIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jaygKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1JlcXVpcmVkSW5mb1Jvd1RleHQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgS2V5ID0+ICRDb25maWdNb2R1bGUgLiAnOjonIC4gJENvbmZpZ0hhc2hSb3ctPntLZXl9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgPT4gJENvbmZpZ0hhc2hSb3ctPntOYW1lfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWYWx1ZSA9PiAkQ29uZmlnSGFzaFJvdy0+e1ZhbHVlfSB8fCAnJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTaXplID0+ICRDb25maWdIYXNoUm93LT57SW5wdXR9LT57U2l6ZX0gfHwgJzQwJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXNjcmlwdGlvbiA9PiAkQ29uZmlnSGFzaFJvdy0+e0Rlc2NyaXB0aW9ufSB8fCAnJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICMgY3JlYXRlIGEgbmV3IGRyb3Bkb3duIGZpZWxkCiAgICAgICAgICAgICAgICAgICAgZWxzaWYgKCRDb25maWdIYXNoUm93LT57SW5wdXR9LT57VHlwZX0gZXEgIlNlbGVjdCIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgbXkgJFNlbGVjdFN0cmcgPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJ1aWxkU2VsZWN0aW9uKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YSA9PiAkQ29uZmlnSGFzaFJvdy0+e0lucHV0fS0+e0RhdGF9IHx8IHt9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZSA9PiAkQ29uZmlnTW9kdWxlIC4gJzo6JyAuICRDb25maWdIYXNoUm93LT57S2V5fSwKICAgICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jaygKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgPT4gJ1JlcXVpcmVkSW5mb1Jvd1NlbGVjdCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lID0+ICRDb25maWdIYXNoUm93LT57TmFtZX0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzY3JpcHRpb24gPT4gJENvbmZpZ0hhc2hSb3ctPntEZXNjcmlwdGlvbn0gfHwgJycsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VsZWN0U3RyZyA9PiAkU2VsZWN0U3RyZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5PdXRwdXQoCiAgICAgICAgICAgICAgICBUZW1wbGF0ZUZpbGUgPT4gJ0FkbWluU3VwcG9ydCcsCiAgICAgICAgICAgICAgICBEYXRhID0+IHsgfSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgJE91dHB1dCAuPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPkZvb3RlcigpOwogICAgICAgICAgICByZXR1cm4gJE91dHB1dDsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICMgbmV4dCBzaWRlLi4uCiAgICAgICAgICAgICRTZWxmLT57U3ViYWN0aW9ufSA9ICdDb25maWRlbnRpYWwnOwogICAgICAgIH0KICAgIH0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIENvbmZpZGVudGlhbCBhbmQgU3VwcG9ydElECiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCgogICAgaWYgKCRTZWxmLT57U3ViYWN0aW9ufSBlcSAnQ29uZmlkZW50aWFsJykgewogICAgICAgICMgY3JlYXRlICYgcmV0dXJuIG91dHB1dAogICAgICAgIG15ICRPdXRwdXQgPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPkhlYWRlcigpOwogICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5OYXZpZ2F0aW9uQmFyKCk7CgogICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QmxvY2soCiAgICAgICAgICAgIE5hbWUgPT4gJ0NvbmZpZGVudGlhbCcsCiAgICAgICAgKTsKICAgICAgICAjIGNyZWF0ZSBoaWRkZW4gZmllbGRzLCBjYXVzZSB3ZSBuZWVkIHRoZSBpbmZvcm1hdGlvbiBhZ2Fpbi4KICAgICAgICBmb3JlYWNoIG15ICRDb25maWdNb2R1bGUgKGtleXMgJXskQ29uZmlnSGFzaH0pIHsKICAgICAgICAgICAgZm9yZWFjaCBteSAkQ29uZmlnSGFzaFJvdyAoQHskQ29uZmlnSGFzaC0+eyRDb25maWdNb2R1bGV9fSkgewogICAgICAgICAgICAgICAgbXkgJFZhbHVlID0gJFNlbGYtPntQYXJhbU9iamVjdH0tPkdldFBhcmFtKFBhcmFtID0+ICRDb25maWdNb2R1bGUgLiAnOjonIC4gJENvbmZpZ0hhc2hSb3ctPntLZXl9KTsKCiAgICAgICAgICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJsb2NrKAogICAgICAgICAgICAgICAgICAgIE5hbWUgPT4gJ0NvbmZpZGVudGlhbEhpZGRlbicsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUgPT4gJENvbmZpZ01vZHVsZSAuICc6OicgLiAkQ29uZmlnSGFzaFJvdy0+e0tleX0sCiAgICAgICAgICAgICAgICAgICAgICAgIFZhbHVlID0+ICRWYWx1ZSB8fCAnJywKICAgICAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgJE91dHB1dCAuPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPk91dHB1dCgKICAgICAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdBZG1pblN1cHBvcnQnLAogICAgICAgICAgICBEYXRhID0+IHsgfSwKICAgICAgICApOwogICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5Gb290ZXIoKTsKICAgICAgICByZXR1cm4gJE91dHB1dDsKICAgIH0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIFVwbG9hZFN1cHBvcnRJbmZvCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCgogICAgZWxzaWYgKCRTZWxmLT57U3ViYWN0aW9ufSBlcSAnVXBsb2FkU3VwcG9ydEluZm8nKSB7CiAgICAgICAgbXkgJERhdGFIYXNoID0ge307CiAgICAgICAgbXkgJElucHV0SGFzaCA9IHt9OwoKICAgICAgICAjIGNyZWF0ZSAmIHJldHVybiBvdXRwdXQKICAgICAgICBteSAkT3V0cHV0ID0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5IZWFkZXIoKTsKICAgICAgICAkT3V0cHV0IC49ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+TmF2aWdhdGlvbkJhcigpOwoKICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJsb2NrKAogICAgICAgICAgICBOYW1lID0+ICdDb25maWRlbnRpYWwnLAogICAgICAgICk7CgogICAgICAgICMgZ2V0IGhpZGRlbiBmaWVsZHMsIGNhdXNlIHdlIG5lZWQgdGhlIGluZm9ybWF0aW9uIGFnYWluLgogICAgICAgIGZvcmVhY2ggbXkgJENvbmZpZ01vZHVsZSAoa2V5cyAleyRDb25maWdIYXNofSkgewogICAgICAgICAgICBteSAkTW9kdWxlSW5wdXREYXRhID0ge307CiAgICAgICAgICAgIGZvcmVhY2ggbXkgJENvbmZpZ0hhc2hSb3cgKEB7JENvbmZpZ0hhc2gtPnskQ29uZmlnTW9kdWxlfX0pIHsKICAgICAgICAgICAgICAgICRNb2R1bGVJbnB1dERhdGEtPnskQ29uZmlnSGFzaFJvdy0+e0tleX19ID0KICAgICAgICAgICAgICAgICAgICAkU2VsZi0+e1BhcmFtT2JqZWN0fS0+R2V0UGFyYW0oUGFyYW0gPT4gJENvbmZpZ01vZHVsZSAuICc6OicgLiAkQ29uZmlnSGFzaFJvdy0+e0tleX0pIHx8ICcnOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRJbnB1dEhhc2gtPnskQ29uZmlnTW9kdWxlfSA9ICRNb2R1bGVJbnB1dERhdGE7CiAgICAgICAgfQogICAgICAgICMgY3JlYXRlIGRhdGEgaGFzaCByZWZlcmVuY2UKICAgICAgICAkU2VsZi0+e1N1cHBvcnRPYmplY3R9LT5TdXBwb3J0SW5mb0dldCgKICAgICAgICAgICAgRGF0YUhhc2ggPT4gJERhdGFIYXNoLAogICAgICAgICAgICBJbnB1dEhhc2ggPT4gJElucHV0SGFzaCwKICAgICAgICApOwoKICAgICAgICBteSAkU3VwcG9ydFN0cmluZyA9ICRTZWxmLT57U3VwcG9ydE9iamVjdH0tPkNyZWF0ZVBhY2thZ2VUb1NlbmQoCiAgICAgICAgICAgIERhdGFIYXNoID0+ICREYXRhSGFzaCwKICAgICAgICApOwoKICAgICAgICAjIGlmIHRoZSBidXR0b24gc2VuZCBiZWNvbWVzIHRoZSBzdWJtaXQKICAgICAgICBpZiAoJFNlbGYtPntQYXJhbU9iamVjdH0tPkdldFBhcmFtKFBhcmFtID0+ICJTZW5kIikpIHsKICAgICAgICAgICAgbXkgKCRzLCRtLCRoLCAkRCwkTSwkWSwgJHdkLCR5ZCwkZHN0KSA9ICRTZWxmLT57VGltZU9iamVjdH0tPlN5c3RlbVRpbWUyRGF0ZSgKICAgICAgICAgICAgU3lzdGVtVGltZSA9PiAkU2VsZi0+e1RpbWVPYmplY3R9LT5TeXN0ZW1UaW1lKCksCiAgICAgICAgICAgICk7CiAgICAgICAgICAgICRNID0gc3ByaW50ZigiJTAyZCIsICRNKTsKICAgICAgICAgICAgJEQgPSBzcHJpbnRmKCIlMDJkIiwgJEQpOwogICAgICAgICAgICAkaCA9IHNwcmludGYoIiUwMmQiLCAkaCk7CiAgICAgICAgICAgICRtID0gc3ByaW50ZigiJTAyZCIsICRtKTsKICAgICAgICAgICAgbXkgJFNlbmRNZXNzYWdlOwogICAgICAgICAgICBpZiAobGVuZ3RoKCRTdXBwb3J0U3RyaW5nKSA8IDk5NjE0NzIpIHsKICAgICAgICAgICAgICAgICMgc2VuZCBpbmZvIHRvICgob3RycykpCiAgICAgICAgICAgICAgICAkU2VuZE1lc3NhZ2UgPSAkU2VsZi0+e1N1cHBvcnRPYmplY3R9LT5TdXBwb3J0U2VuZEluZm8oCiAgICAgICAgICAgICAgICAgICAgU3VwcG9ydFN0cmluZyA9PiAkU3VwcG9ydFN0cmluZywKICAgICAgICAgICAgICAgICAgICBTdXBwb3J0SUQgPT4gIlN1cHBvcnRJbmZvXyIuIiRZLSRNLSREIi4iXyRoLSRtIi4iXyIuIlN1cHBvcnQtSURfIi4kU2VsZi0+e1BhcmFtT2JqZWN0fS0+R2V0UGFyYW0oUGFyYW0gPT4gIlN1cHBvcnRJRCIpLid0YXIuZ3onLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5Ob3RpZnkoCiAgICAgICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ3dhcm5pbmcnLAogICAgICAgICAgICAgICAgICAgIEluZm8gPT4gJFNlbmRNZXNzYWdlLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5Ob3RpZnkoCiAgICAgICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ3dhcm5pbmcnLAogICAgICAgICAgICAgICAgICAgIEluZm8gPT4gJ0NhblwndCBzZW5kIGVtYWlsIHRvIHRoZSAoKG90cnMpKSBzdXBwb3J0IHRlYW0hJy4iXG5cbiIuCiAgICAgICAgICAgICAgICAgICAgICAgICJZb3Ugd2lsbCBmb3VuZCB0aGUgb3RycyBzeXN0ZW0gaW5mb3JtYXRpb24gcGFja2FnZSBhdFxuIi4KICAgICAgICAgICAgICAgICAgICAgICAgIklmIHlvdSB3b3VsZCBsaWtlIHRvIHVzZSBPVFJTIHN1cHBvcnQgc2VydmljZXMgcGxlYXNlIHNlbmQgdGhlIHBhY2thZ2UgdG8gc3VwcG9ydFxAb3Rycy5jb20gb3IgY2FsbFxuIi4KICAgICAgICAgICAgICAgICAgICAgICAgIm91ciBzdXBwb3J0IHRlYW0gcGVyIHBob25lIHRvIHJldmlldyB0aGUgbmV4dCBzdGVwXG5cbiIuCiAgICAgICAgICAgICAgICAgICAgICAgICIgTW9yZSBhYm91dCBPVFJTIHN1cHBvcnQgb3IgZmFjZS10by1mYWNlIGNvbnRhY3QgaW5mb3JtYXRpb24geW91IHdpbGwgZm91bmQgYXRcbiIuCiAgICAgICAgICAgICAgICAgICAgICAgICdodHRwOi8vd3d3Lm90cnMuY29tLycuIlxuXG4iLAogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAjIGlmIHRoZSBidXR0b24gZG93bmxvYWQgYmVjb21lcyB0aGUgc3VibWl0CiAgICAgICAgZWxzaWYgKCRTZWxmLT57UGFyYW1PYmplY3R9LT5HZXRQYXJhbShQYXJhbSA9PiAiRG93bmxvYWQiKSkgewogICAgICAgICAgICBteSAoJHMsJG0sJGgsICRELCRNLCRZLCAkd2QsJHlkLCRkc3QpID0gJFNlbGYtPntUaW1lT2JqZWN0fS0+U3lzdGVtVGltZTJEYXRlKAogICAgICAgICAgICBTeXN0ZW1UaW1lID0+ICRTZWxmLT57VGltZU9iamVjdH0tPlN5c3RlbVRpbWUoKSwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgJE0gPSBzcHJpbnRmKCIlMDJkIiwgJE0pOwogICAgICAgICAgICAkRCA9IHNwcmludGYoIiUwMmQiLCAkRCk7CiAgICAgICAgICAgICRoID0gc3ByaW50ZigiJTAyZCIsICRoKTsKICAgICAgICAgICAgJG0gPSBzcHJpbnRmKCIlMDJkIiwgJG0pOwogICAgICAgICAgICAjIHJldHVybiBmaWxlCiAgICAgICAgICAgIHJldHVybiAkU2VsZi0+e0xheW91dE9iamVjdH0tPkF0dGFjaG1lbnQoCiAgICAgICAgICAgICAgICBDb250ZW50VHlwZSA9PiAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJywKICAgICAgICAgICAgICAgIENvbnRlbnQgPT4gJFN1cHBvcnRTdHJpbmcsCiAgICAgICAgICAgICAgICBGaWxlbmFtZSA9PiAiU3VwcG9ydEluZm8iLiJfIi4iJFktJE0tJEQiLiJfJGgtJG0iLAogICAgICAgICAgICAgICAgVHlwZSA9PiAnYXR0YWNoZWQnLAogICAgICAgICAgICApOwogICAgICAgIH0KCiAgICAgICAgJE91dHB1dCAuPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPk91dHB1dCgKICAgICAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdBZG1pblN1cHBvcnQnLAogICAgICAgICAgICBEYXRhID0+IHsgfSwKICAgICAgICApOwogICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5Gb290ZXIoKTsKICAgICAgICByZXR1cm4gJE91dHB1dDsKICAgIH0KCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIG92ZXJ2aWV3CiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCgogICAgZWxzZSB7CiAgICAgICAgbXkgJERhdGFIYXNoID0ge307CiAgICAgICAgIyBjcmVhdGUgZGF0YSBoYXNoIHJlZmVyZW5jZQogICAgICAgICRTZWxmLT57U3VwcG9ydE9iamVjdH0tPkFkbWluQ2hlY2tzR2V0KAogICAgICAgICAgICBEYXRhSGFzaCA9PiAkRGF0YUhhc2gsCiAgICAgICAgKTsKCiAgICAgICAgIyBjcmVhdGUgJiByZXR1cm4gb3V0cHV0CiAgICAgICAgbXkgJE91dHB1dCA9ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+SGVhZGVyKCk7CiAgICAgICAgJE91dHB1dCAuPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPk5hdmlnYXRpb25CYXIoKTsKCiAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jaygKICAgICAgICAgICAgTmFtZSA9PiAnT3ZlcnZpZXcnLAogICAgICAgICk7CgogICAgICAgIGZvcmVhY2ggbXkgJE1vZHVsZSAoc29ydCBrZXlzICV7JERhdGFIYXNofSkgewogICAgICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJsb2NrKAogICAgICAgICAgICAgICAgTmFtZSA9PiAnT3ZlcnZpZXdNb2R1bGUnLAogICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgTW9kdWxlID0+ICRNb2R1bGUsCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApOwogICAgICAgICAgICAjIGNoZWNrIGNzcyByb3RhdG9yeQogICAgICAgICAgICBteSAkQ3NzQ2xhc3M7CiAgICAgICAgICAgIGZvcmVhY2ggbXkgJFJvd0hhc2ggKEB7JERhdGFIYXNoLT57JE1vZHVsZX19KSB7CiAgICAgICAgICAgICAgICAjIHNldCBvdXRwdXQgY2xhc3MKICAgICAgICAgICAgICAgIGlmICgkQ3NzQ2xhc3MgJiYgJENzc0NsYXNzIGVxICdzZWFyY2hhY3RpdmUnKSB7CiAgICAgICAgICAgICAgICAgICAgJENzc0NsYXNzID0gJ3NlYXJjaHBhc3NpdmUnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgJENzc0NsYXNzID0gJ3NlYXJjaGFjdGl2ZSc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBteSAkRm9udENvbG9yID0gInJlZCI7CiAgICAgICAgICAgICAgICBpZiAoJFJvd0hhc2gtPntDaGVja30pIHsKICAgICAgICAgICAgICAgICAgICBpZiAoJFJvd0hhc2gtPntDaGVja30gZXEgIk9LIikgewogICAgICAgICAgICAgICAgICAgICAgICAkRm9udENvbG9yID0gImdyZWVuIjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzaWYgKCRSb3dIYXNoLT57Q2hlY2t9IGVxICJDcml0aWNhbCIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgJEZvbnRDb2xvciA9ICJvcmFuZ2UiOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkUm93SGFzaC0+e0Rlc2NyaXB0aW9ufSkgewogICAgICAgICAgICAgICAgICAgICRSb3dIYXNoLT57RGVzY3JpcHRpb259ID0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5Bc2NpaTJIdG1sKAogICAgICAgICAgICAgICAgICAgICAgICBUZXh0ID0+ICRSb3dIYXNoLT57RGVzY3JpcHRpb259LAogICAgICAgICAgICAgICAgICAgICAgICBIVE1MUmVzdWx0TW9kZSA9PiAnMScsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICgkUm93SGFzaC0+e0NvbW1lbnR9KSB7CiAgICAgICAgICAgICAgICAgICAgJFJvd0hhc2gtPntDb21tZW50fSA9ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QXNjaWkySHRtbCgKICAgICAgICAgICAgICAgICAgICAgICAgVGV4dCA9PiAkUm93SGFzaC0+e0NvbW1lbnR9LAogICAgICAgICAgICAgICAgICAgICAgICBIVE1MUmVzdWx0TW9kZSA9PiAnMScsCiAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICMgY3JlYXRlIG5ldyBibG9jayB3aXRoIHJvdGF0b3J5IGNzcwogICAgICAgICAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jaygKICAgICAgICAgICAgICAgICAgICBOYW1lID0+ICdPdmVydmlld01vZHVsZVJvdycsCiAgICAgICAgICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICV7JFJvd0hhc2h9LAogICAgICAgICAgICAgICAgICAgICAgICBDc3NDbGFzcyA9PiAkQ3NzQ2xhc3MsCiAgICAgICAgICAgICAgICAgICAgICAgIEZvbnRDb2xvciA9PiAkRm9udENvbG9yLAogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5PdXRwdXQoCiAgICAgICAgICAgIFRlbXBsYXRlRmlsZSA9PiAnQWRtaW5TdXBwb3J0JywKICAgICAgICAgICAgRGF0YSA9PiB7IH0sCiAgICAgICAgKTsKICAgICAgICAkT3V0cHV0IC49ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+Rm9vdGVyKCk7CiAgICAgICAgcmV0dXJuICRPdXRwdXQ7CiAgICB9Cn0KCjE7Cg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8b3Ryc19jb25maWcgdmVyc2lvbj0iMS4wIiBpbml0PSJBcHBsaWNhdGlvbiI+CiAgICA8Q1ZTPiRJZDogU3VwcG9ydC54bWwsdiAxLjEuMS4xIDIwMDcvMDUvMDcgMTg6NDc6NTUgc3IgRXhwICQ8L0NWUz4KICAgIDxDb25maWdJdGVtIE5hbWU9IkZyb250ZW5kOjpNb2R1bGUjIyNBZG1pblN1cHBvcnQiIFJlcXVpcmVkPSIxIiBWYWxpZD0iMSI+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImVuIj5Gcm9udGVuZCBtb2R1bGUgcmVnaXN0cmF0aW9uIGZvciB0aGUgQWRtaW5TeXN0ZW1TdGF0dXMgb2JqZWN0ICBpbiB0aGUgYWRtaW4gYXJlYS48L0Rlc2NyaXB0aW9uPkRlc2NyaXB0aW9uPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJkZSI+RnJvbnRlbmRtb2R1bC1SZWdpc3RyYXRpb24gZGVzIEFkbWluU3lzdGVtU3RhdHVzLU9iamVrdHMgaW0gQWRtaW4tQmVyZWljaC48L0Rlc2NyaXB0aW9uPkRlc2NyaXB0aW9uPgogICAgICAgIDxHcm91cD5TeXN0ZW1TdGF0dXM8L0dyb3VwPgogICAgICAgIDxTdWJHcm91cD5Gcm9udGVuZDo6QWRtaW46Ok1vZHVsZVJlZ2lzdHJhdGlvbjwvU3ViR3JvdXA+CiAgICAgICAgPFNldHRpbmc+CiAgICAgICAgICAgIDxGcm9udGVuZE1vZHVsZVJlZz4KICAgICAgICAgICAgICAgIDxUaXRsZT5TdXBwb3J0IEluZm88L1RpdGxlPgogICAgICAgICAgICAgICAgPEdyb3VwPmFkbWluPC9Hcm91cD4KICAgICAgICAgICAgICAgIDxEZXNjcmlwdGlvbj5BZG1pbi1TdXBwb3J0IE92ZXJ2aWV3PC9EZXNjcmlwdGlvbj4KICAgICAgICAgICAgICAgIDxOYXZCYXJOYW1lPkFkbWluPC9OYXZCYXJOYW1lPgogICAgICAgICAgICAgICAgPE5hdkJhck1vZHVsZT4KICAgICAgICAgICAgICAgICAgICA8TW9kdWxlPktlcm5lbDo6T3V0cHV0OjpIVE1MOjpOYXZCYXJNb2R1bGVBZG1pbjwvTW9kdWxlPgogICAgICAgICAgICAgICAgICAgIDxOYW1lPlN1cHBvcnQ8L05hbWU+CiAgICAgICAgICAgICAgICAgICAgPEJsb2NrPkJsb2NrNDwvQmxvY2s+CiAgICAgICAgICAgICAgICAgICAgPFByaW8+MjAwMDwvUHJpbz4KICAgICAgICAgICAgICAgIDwvTmF2QmFyTW9kdWxlPgogICAgICAgICAgICA8L0Zyb250ZW5kTW9kdWxlUmVnPgogICAgICAgIDwvU2V0dGluZz4KICAgIDwvQ29uZmlnSXRlbT4KPC9vdHJzX2NvbmZpZz4=