Fred
0.2.22
OTRS AG
http://otrs.org/
GNU AFFERO GENERAL PUBLIC LICENSE Version 3, November 2007
Testbuild.
Added 2.4 Framework as supported versions.
Fixed broken output when STDERR log contrains html brackets.
Implement a function which show the needed time per sql-statement.
Insert a mult used sql statement finder. Implement a new sort option in DProf. Make some sum rows for the result tables.
Resolve version dependencies because of Config.pm check in revision 1.67, Sat Dec 29 00:44:13 2007.
Fixed bug in STDERRLog feature.
Insert a benchmark function and hardening the activate and deactivate function.
Removed the spaces and insert real html-tags.
Backport Fred to OTRS 2.1.
Improved the code quality. And fixed erorrs cause in consequence of the OTRS recoding.
Improved the styling of the install intro.
Improved the styling of the install intro.
Insert new tags in opm-file for an easier installation.
Design improvements.
Fixed some little bugs.
Insert the config log function.
Insert the DProf profiling function.
Insert the translation debug log.
Improved the handling of the profiler.
Insert a profiling function.
Improved the package settings.
First modular version.
Remove modperl reload informations from the fred log.
Added Database::SlowLog feature.
Improved the config description.
No longer crashes if HTML::Lint is not installed but HTML-checker is active.
Improved output.
First version especially for testing and as proof of concept.
A tool to support the developer by his development.
Ein Entwicklertool welches dem Entwickler zur Laufzeit bei der Entwicklung unterstützen soll.
2.1.x
2.2.x
2.3.x
<br>
Welcome! <br>
<br>
First of all you should install the necessary perl modules <br>
<ul>
<li> Devel::SmallProf </li>
<li> Devel::DProf</li>
<li> HTML::Lint</li>
</ul>
<br>
<br>
What can Fred do?<br>
<br>
To date, Fred has the following features: <br>
<ul>
<li> HTMLCheck: <br>
the HTML output is checked by means of HTML::Lint </li>
<li> STDERRLog: <br>
every entry contained in STDERR is displayed </li>
<li> TranslationDebug: <br>
displays all translation attempts of the current request which failed. </li>
<li> SQLLog: <br>
lists all SQL statements of the current request </li>
<li> ConfigLog: <br>
lists all !ConfigGet requests, indicating their frequency </li>
<li> DProf: <br>
a profiling tool which evaluates the time required for each function to be executed </li>
<li> SmallProf: <br>
a profiling tool performing a line-by-line code evaluation </li>
</ul>
<br>
*Caution* : Please have a look at the possible config settings, which are easily accessible by clicking on "setting". <br>
<br>
<br>
What is Fred's current status?<br>
<br>
<ul>
<li> modular design: <br>
anybody can add a new module at any time </li>
<li> the modules' output is not yet sophisticated <br>
ideas for improving the output or sensible configurations will be very welcome </li>
<li> please extend Fred, if you have good ideas <br>
<li> if you have no time to implement your ideas yourselves, please enter them in dev mailinglist </li>
</ul>
<br>
HTML::Lint
Devel::SmallProf
Devel::DProf
2011-01-09 23:11:11
opms.otrs.com
IyAtLQojIEFBQUZyZWQucG0gLSB0aGUgY29uZmlnIHRvIGJpbmQgU1RERVJSIHRvIGFuIGxvZyBmaWxlIHVzYWJsZSBmb3IgZnJlZAojIENvcHlyaWdodCAoQykgMjAwMS0yMDA5IE9UUlMgQUcsIGh0dHA6Ly9vdHJzLm9yZy8KIyAtLQojICRJZDogQUFBRnJlZC5wbSx2IDEuOSAyMDA5LzA0LzA2IDEwOjI1OjI1IG1oIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCgppZiAoICRFTlZ7SFRUUF9VU0VSX0FHRU5UfSApIHsKCiAgICAjIGNoZWNrIGlmIHRoZSBuZWVkZWQgcGF0aCBpcyBhdmFpbGFibGUKICAgIG15ICRQYXRoID0gJFNlbGYtPntIb21lfSAuICcvdmFyL2ZyZWQnOwogICAgaWYgKCAhLWUgJFBhdGggKSB7CiAgICAgICAgbWtkaXIgJFBhdGg7CiAgICB9CgogICAgbXkgJEZpbGUgPSAkU2VsZi0+e0hvbWV9IC4gJy92YXIvZnJlZC9TVERFUlIubG9nJzsKCiAgICAjIGNoZWNrIGxvZyBmaWxlIHNpemUKICAgIGlmICggLXMgJEZpbGUgPiAyMCAqIDEwMjQgKiAxMDI0ICkgewogICAgICAgIHVubGluayAkRmlsZTsKICAgIH0KCiAgICAjIG1vdmUgU1RET1VUIHRvIHRtcCBmaWxlCiAgICBpZiAoICFvcGVuIFNUREVSUiwgJz4+JywgJEZpbGUgKSB7CiAgICAgICAgcHJpbnQgU1RERVJSICJFUlJPUjogQ2FuJ3Qgd3JpdGUgJEZpbGUhIjsKICAgIH0KfQoKMTsK
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSIgPz4KPG90cnNfY29uZmlnIHZlcnNpb249IjEuMCIgaW5pdD0iQXBwbGljYXRpb24iPgogICAgPENWUz4kSWQ6IEZyZWQueG1sLHYgMS4xOCAyMDA4LzAyLzAzIDA3OjM3OjU3IHRyIEV4cCAkPC9DVlM+CiAgICA8Q29uZmlnSXRlbSBOYW1lPSJGcm9udGVuZDo6T3V0cHV0OjpGaWx0ZXJDb250ZW50IyMjRnJlZCIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZW4iPlN1YnNjcmliZSB0aGUgb3V0cHV0IGZpbHRlciBhdCB0aGUgc3lzdGVtLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImRlIj5NZWxkZXQgZGVuIE91dHB1dEZpbHRlckZyZWQgYW0gU3lzdGVtIGFuLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPEdyb3VwPkZyZWQ8L0dyb3VwPgogICAgICAgIDxTdWJHcm91cD5Db3JlPC9TdWJHcm91cD4KICAgICAgICA8U2V0dGluZz4KICAgICAgICAgICAgPEhhc2g+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9Ik1vZHVsZSI+S2VybmVsOjpPdXRwdXQ6OkhUTUw6Ok91dHB1dEZpbHRlckZyZWQ8L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9IkRlYnVnIj4wPC9JdGVtPgogICAgICAgICAgICA8L0hhc2g+CiAgICAgICAgPC9TZXR0aW5nPgogICAgPC9Db25maWdJdGVtPgogICAgPENvbmZpZ0l0ZW0gTmFtZT0iRnJlZDo6TW9kdWxlIyMjQ29uc29sZSIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZW4iPlR1cm4gb24gaWYgeW91IHdhbnQgdG8gdXNlIHRoZSBmcmVkIGNvbnNvbGUuPC9EZXNjcmlwdGlvbj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZGUiPkhpZXIgYWt0aXZpZXJlbiwgd2VubiBtYW4gZGllIEZyZWQtQ29uc29sZSBudXR6ZW4gbfZjaHRlLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPEdyb3VwPkZyZWQ8L0dyb3VwPgogICAgICAgIDxTdWJHcm91cD5Db3JlPC9TdWJHcm91cD4KICAgICAgICA8U2V0dGluZz4KICAgICAgICAgICAgPEhhc2g+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9IkFjdGl2ZSI+MTwvSXRlbT4KICAgICAgICAgICAgPC9IYXNoPgogICAgICAgIDwvU2V0dGluZz4KICAgIDwvQ29uZmlnSXRlbT4KICAgIDxDb25maWdJdGVtIE5hbWU9IkZyZWQ6Ok1vZHVsZSMjI0JlbmNobWFyayIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZW4iPlR1cm4gb24gaWYgeW91IHdhbnQgdG8gdXNlIHRoZSBmcmVkIGJlbmNobWFyayB0b29sIChvbmx5IGZvciBleHBlcnRzISkuPC9EZXNjcmlwdGlvbj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZGUiPkhpZXIgYWt0aXZpZXJlbiwgd2VubiBtYW4gZGFzIEZyZWQtQmVuY2htYXJrdG9vbCBudXR6ZW4gbfZjaHRlIChudXIgZvxyIEV4cGVydGVuKS48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxHcm91cD5GcmVkPC9Hcm91cD4KICAgICAgICA8U3ViR3JvdXA+Q29yZTwvU3ViR3JvdXA+CiAgICAgICAgPFNldHRpbmc+CiAgICAgICAgICAgIDxIYXNoPgogICAgICAgICAgICAgICAgPEl0ZW0gS2V5PSJBY3RpdmUiPjA8L0l0ZW0+CiAgICAgICAgICAgIDwvSGFzaD4KICAgICAgICA8L1NldHRpbmc+CiAgICA8L0NvbmZpZ0l0ZW0+CiAgICA8Q29uZmlnSXRlbSBOYW1lPSJGcmVkOjpNb2R1bGUjIyNTbWFsbFByb2YiIFJlcXVpcmVkPSIwIiBWYWxpZD0iMSI+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImVuIj5UdXJuIG9uIGlmIHlvdSB3YW50IHRvIHVzZSB0aGUgU21hbGxQcm9mIHByb2ZpbGluZyBmdW5jdGlvbi48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJkZSI+SGllciBha3RpdmllcmVuLCB3ZW5uIG1hbiBkaWUgU21hbGxQcm9mLVByb2ZpbGluZyBGdW5rdGlvbiBudXR6ZW4gbfZjaHRlLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPEdyb3VwPkZyZWQ8L0dyb3VwPgogICAgICAgIDxTdWJHcm91cD5Db3JlPC9TdWJHcm91cD4KICAgICAgICA8U2V0dGluZz4KICAgICAgICAgICAgPEhhc2g+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9IkFjdGl2ZSI+MDwvSXRlbT4KICAgICAgICAgICAgPC9IYXNoPgogICAgICAgIDwvU2V0dGluZz4KICAgIDwvQ29uZmlnSXRlbT4KICAgIDxDb25maWdJdGVtIE5hbWU9IkZyZWQ6Ok1vZHVsZSMjI0RQcm9mIiBSZXF1aXJlZD0iMCIgVmFsaWQ9IjEiPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJlbiI+VHVybiBvbiBpZiB5b3Ugd2FudCB0byB1c2UgdGhlIERQcm9mIHByb2ZpbGluZyBmdW5jdGlvbi48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJkZSI+SGllciBha3RpdmllcmVuLCB3ZW5uIG1hbiBkaWUgRFByb2YtUHJvZmlsaW5nIEZ1bmt0aW9uIG51dHplbiBt9mNodGUuPC9EZXNjcmlwdGlvbj4KICAgICAgICA8R3JvdXA+RnJlZDwvR3JvdXA+CiAgICAgICAgPFN1Ykdyb3VwPkNvcmU8L1N1Ykdyb3VwPgogICAgICAgIDxTZXR0aW5nPgogICAgICAgICAgICA8SGFzaD4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iQWN0aXZlIj4wPC9JdGVtPgogICAgICAgICAgICA8L0hhc2g+CiAgICAgICAgPC9TZXR0aW5nPgogICAgPC9Db25maWdJdGVtPgogICAgPENvbmZpZ0l0ZW0gTmFtZT0iRnJlZDo6TW9kdWxlIyMjU1FMTG9nIiBSZXF1aXJlZD0iMCIgVmFsaWQ9IjEiPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJlbiI+VHVybiBvbiBpZiB5b3Ugd2FudCBhbiByZWFsdGltZSBTUUwgc3RhdGVtZW50IGxvZyBmdW5jdGlvbi48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJkZSI+SGllciBha3RpdmllcmVuLCB3ZW5uIHp1ciBMYXVmemVpdCBkZXIgU1FMLVN0YXRlbWVudC1Mb2dnZXIgZ2VudXR6dCB3ZXJkZW4gc29sbC48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxHcm91cD5GcmVkPC9Hcm91cD4KICAgICAgICA8U3ViR3JvdXA+Q29yZTwvU3ViR3JvdXA+CiAgICAgICAgPFNldHRpbmc+CiAgICAgICAgICAgIDxIYXNoPgogICAgICAgICAgICAgICAgPEl0ZW0gS2V5PSJBY3RpdmUiPjA8L0l0ZW0+CiAgICAgICAgICAgIDwvSGFzaD4KICAgICAgICA8L1NldHRpbmc+CiAgICA8L0NvbmZpZ0l0ZW0+CiAgICA8Q29uZmlnSXRlbSBOYW1lPSJGcmVkOjpNb2R1bGUjIyNIVE1MQ2hlY2siIFJlcXVpcmVkPSIwIiBWYWxpZD0iMSI+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImVuIj5UdXJuIG9uIGlmIHlvdSB3YW50IGFuIHJlYWx0aW1lIEhUTUwtY2hlY2tlci48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJkZSI+SGllciBha3RpdmllcmVuIHdlbm4genVyIExhdWZ6ZWl0IGVpbiBIVE1MLUNoZWNrZXIgYXVzZ2Vm/GhydCB3ZXJkZW4gc29sbC4gV0lDSFRJRzogRGFzIENwYW4tTW9kdWwgSFRNTDo6bGludCBpc3QgaGllcmb8ciBub3R3ZW5kaWcuPC9EZXNjcmlwdGlvbj4KICAgICAgICA8R3JvdXA+RnJlZDwvR3JvdXA+CiAgICAgICAgPFN1Ykdyb3VwPkNvcmU8L1N1Ykdyb3VwPgogICAgICAgIDxTZXR0aW5nPgogICAgICAgICAgICA8SGFzaD4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iQWN0aXZlIj4wPC9JdGVtPgogICAgICAgICAgICA8L0hhc2g+CiAgICAgICAgPC9TZXR0aW5nPgogICAgPC9Db25maWdJdGVtPgogICAgPENvbmZpZ0l0ZW0gTmFtZT0iRnJlZDo6TW9kdWxlIyMjVHJhbnNsYXRpb25EZWJ1ZyIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZW4iPlR1cm4gb24gaWYgeW91IHdhbnQgdGhlIHRyYW5zbGF0aW9uIGRlYnVnZ2VyLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImRlIj5IaWVyIGFrdGl2aWVyZW4gd2VubiB6dXIgTGF1ZnplaXQgZGVyINxiZXJzZXR6dW5nc2RlYnVnZ2VyIGdlbnV0enQgd2VyZGVuIHNvbGwuPC9EZXNjcmlwdGlvbj4KICAgICAgICA8R3JvdXA+RnJlZDwvR3JvdXA+CiAgICAgICAgPFN1Ykdyb3VwPkNvcmU8L1N1Ykdyb3VwPgogICAgICAgIDxTZXR0aW5nPgogICAgICAgICAgICA8SGFzaD4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iQWN0aXZlIj4wPC9JdGVtPgogICAgICAgICAgICA8L0hhc2g+CiAgICAgICAgPC9TZXR0aW5nPgogICAgPC9Db25maWdJdGVtPgogICAgPENvbmZpZ0l0ZW0gTmFtZT0iRnJlZDo6TW9kdWxlIyMjQ29uZmlnTG9nIiBSZXF1aXJlZD0iMCIgVmFsaWQ9IjEiPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJlbiI+VHVybiBvbiBpZiB5b3Ugd2FudCB0byB1c2UgdGhlIGNvbmZpZyBsb2cgbWVjaGFuaXNtLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImRlIj5IaWVyIGFrdGl2aWVyZW4sIHdlbm4gbWFuIHp1ciBMYXVmemVpdCBDb25pZy1Mb2dtZWNoYW5pc211cyBudXR6ZW4gd2lsbC48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxHcm91cD5GcmVkPC9Hcm91cD4KICAgICAgICA8U3ViR3JvdXA+Q29yZTwvU3ViR3JvdXA+CiAgICAgICAgPFNldHRpbmc+CiAgICAgICAgICAgIDxIYXNoPgogICAgICAgICAgICAgICAgPEl0ZW0gS2V5PSJBY3RpdmUiPjA8L0l0ZW0+CiAgICAgICAgICAgIDwvSGFzaD4KICAgICAgICA8L1NldHRpbmc+CiAgICA8L0NvbmZpZ0l0ZW0+CiAgICA8Q29uZmlnSXRlbSBOYW1lPSJGcmVkOjpNb2R1bGUjIyNTVERFUlJMb2ciIFJlcXVpcmVkPSIwIiBWYWxpZD0iMSI+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImVuIj5UdXJuIG9uIGlmIHlvdSB3YW50IHRvIHNlZSB0aGUgU1RERVJSTG9nLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImRlIj5IaWVyIGFrdGl2aWVyZW4gd2VubiBtYW4genVyIExhdWZ6ZWl0IGRhcyBTVERFUlJMb2cgc2VoZW4gd2lsbC48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxHcm91cD5GcmVkPC9Hcm91cD4KICAgICAgICA8U3ViR3JvdXA+Q29yZTwvU3ViR3JvdXA+CiAgICAgICAgPFNldHRpbmc+CiAgICAgICAgICAgIDxIYXNoPgogICAgICAgICAgICAgICAgPEl0ZW0gS2V5PSJBY3RpdmUiPjE8L0l0ZW0+CiAgICAgICAgICAgIDwvSGFzaD4KICAgICAgICA8L1NldHRpbmc+CiAgICA8L0NvbmZpZ0l0ZW0+CiAgICA8Q29uZmlnSXRlbSBOYW1lPSJGcm9udGVuZDo6TW9kdWxlIyMjRGV2ZWxGcmVkIiBSZXF1aXJlZD0iMCIgVmFsaWQ9IjEiPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJlbiI+RnJvbnRlbmQgbW9kdWxlIHJlZ2lzdHJhdGlvbiBmb3IgdGhlIGRldmVsIGZyZWQgb2JqZWN0IGluIHRoZSBhZG1pbiBhcmVhLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImRlIj5Gcm9udGVuZG1vZHVsLVJlZ2lzdHJhdGlvbiBkZXMgRW50d2lja2xlci1PYmpla3RzIEZyZWQgaW0gQWRtaW4tQmVyZWljaC48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxHcm91cD5GcmVkPC9Hcm91cD4KICAgICAgICA8U3ViR3JvdXA+RnJvbnRlbmQ6OkFkbWluOjpNb2R1bGVSZWdpc3RyYXRpb248L1N1Ykdyb3VwPgogICAgICAgIDxTZXR0aW5nPgogICAgICAgICAgICA8RnJvbnRlbmRNb2R1bGVSZWc+CiAgICAgICAgICAgICAgICA8IS0tIDxHcm91cD5hZG1pbjwvR3JvdXA+IC0tPgogICAgICAgICAgICAgICAgPERlc2NyaXB0aW9uPkFkbWluPC9EZXNjcmlwdGlvbj4KICAgICAgICAgICAgICAgIDxUaXRsZT5GcmVkLURldmVsb3BlcnRvb2xzPC9UaXRsZT4KICAgICAgICAgICAgICAgIDxOYXZCYXJOYW1lPkFkbWluPC9OYXZCYXJOYW1lPgogICAgICAgICAgICAgICAgPE5hdkJhck1vZHVsZT4KICAgICAgICAgICAgICAgICAgICA8TW9kdWxlPktlcm5lbDo6T3V0cHV0OjpIVE1MOjpOYXZCYXJNb2R1bGVBZG1pbjwvTW9kdWxlPgogICAgICAgICAgICAgICAgICAgIDxOYW1lPkZyZWQ8L05hbWU+CiAgICAgICAgICAgICAgICAgICAgPEJsb2NrPkJsb2NrNDwvQmxvY2s+CiAgICAgICAgICAgICAgICAgICAgPFByaW8+OTk5PC9QcmlvPgogICAgICAgICAgICAgICAgPC9OYXZCYXJNb2R1bGU+CiAgICAgICAgICAgIDwvRnJvbnRlbmRNb2R1bGVSZWc+CiAgICAgICAgPC9TZXR0aW5nPgogICAgPC9Db25maWdJdGVtPgogICAgPENvbmZpZ0l0ZW0gTmFtZT0iRnJlZDo6U21hbGxQcm9mIyMjU2hvd25MaW5lcyIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZW4iPkhlcmUgeW91IGNhbiBpbnNlcnQgdGhlIG51bWJlciBvZiBzaG93biBwcm9maWxpbmcgbGluZXMuPC9EZXNjcmlwdGlvbj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZGUiPkhpZXIga2FubiBkaWUgQW56YWhsIGRlciBhbmdlemVpZ3RlbiBhdXNnZXdlcnRldGVuIFplaWxlbiBhbmdlZ2ViZW4gd2VyZGVuLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPEdyb3VwPkZyZWQ8L0dyb3VwPgogICAgICAgIDxTdWJHcm91cD5TbWFsbFByb2Y8L1N1Ykdyb3VwPgogICAgICAgIDxTZXR0aW5nPgogICAgICAgICAgICA8U3RyaW5nIFJlZ2V4PSIiPjE1PC9TdHJpbmc+CiAgICAgICAgPC9TZXR0aW5nPgogICAgPC9Db25maWdJdGVtPgogICAgPENvbmZpZ0l0ZW0gTmFtZT0iRnJlZDo6U21hbGxQcm9mIyMjT3JkZXJCeSIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZW4iPldoaWNoIG9yZGVyIHNob3VsZCB0aGUgcHJvZmlsaW5nIGRhdGEgaGF2ZT88L0Rlc2NyaXB0aW9uPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJkZSI+TmFjaCB3ZWxjaGVyIFJlaWhlbmZvbGdlIHNvbGxlbiBkaWUgUHJvZmlsaW5nZGF0ZW4gZ2VvcmRuZXQgd2VyZGVuPzwvRGVzY3JpcHRpb24+CiAgICAgICAgPEdyb3VwPkZyZWQ8L0dyb3VwPgogICAgICAgIDxTdWJHcm91cD5TbWFsbFByb2Y8L1N1Ykdyb3VwPgogICAgICAgIDxTZXR0aW5nPgogICAgICAgICAgICA8T3B0aW9uIFNlbGVjdGVkSUQ9IjQiPgogICAgICAgICAgICAgICAgPEl0ZW0gS2V5PSIxIj5MaW5lPC9JdGVtPgogICAgICAgICAgICAgICAgPEl0ZW0gS2V5PSIyIj5DYWxsczwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iMyI+VGltZSBleGVjdXRpbmc8L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9IjQiPlRpbWUgZXhwZW5kZWQ8L0l0ZW0+CiAgICAgICAgICAgIDwvT3B0aW9uPgogICAgICAgIDwvU2V0dGluZz4KICAgIDwvQ29uZmlnSXRlbT4KICAgIDxDb25maWdJdGVtIE5hbWU9IkZyZWQ6OlNtYWxsUHJvZiMjI1BhY2thZ2VzIiBSZXF1aXJlZD0iMCIgVmFsaWQ9IjAiPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJlbiI+Q2hlY2sgb25seSB0aGUgZm9sbG93aW5nIHBhY2thZ2VzIGluIFNtYWxsUHJvZi48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJkZSI+RXMgc29sbGVuIG51ciBmb2xnZW5kZSBQYWNrYWdlcyB2b24gU21hbGxQcm9mIGdlcHL8ZnQgd2VyZGVuLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPEdyb3VwPkZyZWQ8L0dyb3VwPgogICAgICAgIDxTdWJHcm91cD5TbWFsbFByb2Y8L1N1Ykdyb3VwPgogICAgICAgIDxTZXR0aW5nPgogICAgICAgICAgICA8QXJyYXk+CiAgICAgICAgICAgICAgICA8SXRlbT5LZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0PC9JdGVtPgogICAgICAgICAgICA8L0FycmF5PgogICAgICAgIDwvU2V0dGluZz4KICAgIDwvQ29uZmlnSXRlbT4KICAgIDxDb25maWdJdGVtIE5hbWU9IkZyZWQ6OkRQcm9mIyMjU2hvd25MaW5lcyIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZW4iPkhlcmUgeW91IGNhbiBpbnNlcnQgdGhlIG51bWJlciBvZiBzaG93biBwcm9maWxpbmcgZnVuY3Rpb25zIChtYXggNDApLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImRlIj5IaWVyIGthbm4gZGllIEFuemFobCBkZXIgYW5nZXplaWd0ZW4gYXVzZ2V3ZXJ0ZXRlbiBGdW5rdGlvbmVuIGFuZ2VnZWJlbiB3ZXJkZW4gKG1heGltYWwgNDApLjwvRGVzY3JpcHRpb24+CiAgICAgICAgPEdyb3VwPkZyZWQ8L0dyb3VwPgogICAgICAgIDxTdWJHcm91cD5EUHJvZjwvU3ViR3JvdXA+CiAgICAgICAgPFNldHRpbmc+CiAgICAgICAgICAgIDxTdHJpbmcgUmVnZXg9IiI+MTU8L1N0cmluZz4KICAgICAgICA8L1NldHRpbmc+CiAgICA8L0NvbmZpZ0l0ZW0+CiAgICA8Q29uZmlnSXRlbSBOYW1lPSJGcmVkOjpEUHJvZiMjI09yZGVyQnkiIFJlcXVpcmVkPSIwIiBWYWxpZD0iMSI+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImVuIj5XaGljaCBvcmRlciBzaG91bGQgdGhlIHByb2ZpbGluZyBkYXRhIGhhdmU/PC9EZXNjcmlwdGlvbj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZGUiPk5hY2ggd2VsY2hlciBSZWloZW5mb2xnZSBzb2xsZW4gZGllIFByb2ZpbGluZ2RhdGVuIGdlb3JkbmV0IHdlcmRlbj88L0Rlc2NyaXB0aW9uPgogICAgICAgIDxHcm91cD5GcmVkPC9Hcm91cD4KICAgICAgICA8U3ViR3JvdXA+RFByb2Y8L1N1Ykdyb3VwPgogICAgICAgIDxTZXR0aW5nPgogICAgICAgICAgICA8T3B0aW9uIFNlbGVjdGVkSUQ9IkV4VGltZSI+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9Ik5hbWUiPk5hbWU8L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9IkNhbGxzIj5DYWxsczwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iRXhUaW1lIj5FeGNsVGltZTwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iQ3VUaW1lIj5DdW11bFNUaW1lPC9JdGVtPgogICAgICAgICAgICA8L09wdGlvbj4KICAgICAgICA8L1NldHRpbmc+CiAgICA8L0NvbmZpZ0l0ZW0+CiAgICA8Q29uZmlnSXRlbSBOYW1lPSJGcmVkOjpEUHJvZiMjI0Z1bmN0aW9uVHJlZSIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZW4iPlNob3cgdGhlIGZ1bmN0aW9uIHRyZWUuPC9EZXNjcmlwdGlvbj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZGUiPlplaWdlIGRlbiBGdW5rdGlvbnNiYXVtLiBFcyB6ZWlndCBkaWUgQWJmb2xnZSB1bmQgxGJo5G5naWdrZWl0IGluIHdlbGNoZXIgZGllIEZ1bmt0aW9uZW4gYXVmZ2VydWZlbiB3ZXJkZW4uPC9EZXNjcmlwdGlvbj4KICAgICAgICA8R3JvdXA+RnJlZDwvR3JvdXA+CiAgICAgICAgPFN1Ykdyb3VwPkRQcm9mPC9TdWJHcm91cD4KICAgICAgICA8U2V0dGluZz4KICAgICAgICAgICAgPE9wdGlvbiBTZWxlY3RlZElEPSIwIj4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iMCI+Tm88L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9IjEiPlllczwvSXRlbT4KICAgICAgICAgICAgPC9PcHRpb24+CiAgICAgICAgPC9TZXR0aW5nPgogICAgPC9Db25maWdJdGVtPgogICAgPENvbmZpZ0l0ZW0gTmFtZT0iRnJlZDo6RFByb2YjIyNEaXNhYmxlZFBhY2thZ2VzIiBSZXF1aXJlZD0iMCIgVmFsaWQ9IjAiPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJlbiI+RG9uJ3QgY2hlY2sgdGhlIGZvbGxvd2luZyBwYWNrYWdlcyBpbiBEUHJvZi48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxEZXNjcmlwdGlvbiBMYW5nPSJkZSI+RXMgc29sbGVuIGZvbGdlbmRlIFBhY2thZ2VzIHZvbiBEUHJvZiBuaWNodCBnZXBy/GZ0IHdlcmRlbi48L0Rlc2NyaXB0aW9uPgogICAgICAgIDxHcm91cD5GcmVkPC9Hcm91cD4KICAgICAgICA8U3ViR3JvdXA+RFByb2Y8L1N1Ykdyb3VwPgogICAgICAgIDxTZXR0aW5nPgogICAgICAgICAgICA8QXJyYXk+CiAgICAgICAgICAgICAgICA8SXRlbT5NSU1FOjpFbnRpdHk8L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbT51dGY4PC9JdGVtPgogICAgICAgICAgICAgICAgPEl0ZW0+Q0dJPC9JdGVtPgogICAgICAgICAgICAgICAgPEl0ZW0+QXV0b0xvYWRlcjwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtPkVuY29kZTwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtPkR5bmFMb2FkZXI8L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbT5NYWlsOjpJbnRlcm5ldDwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtPndhcm5pbmdzPC9JdGVtPgogICAgICAgICAgICAgICAgPEl0ZW0+RGF0ZTo6Rm9ybWF0OjpHZW5lcmljPC9JdGVtPgogICAgICAgICAgICAgICAgPEl0ZW0+REJJPC9JdGVtPgogICAgICAgICAgICAgICAgPEl0ZW0+RGF0YTo6RHVtcGVyPC9JdGVtPgogICAgICAgICAgICAgICAgPEl0ZW0+TUlNRTo6SGVhZDwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtPk1JTUU6OlRvb2xzPC9JdGVtPgogICAgICAgICAgICAgICAgPEl0ZW0+REJEOjpteXNxbDo6ZGI8L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbT5NYWlsOjpGaWVsZDo6QWRkckxpc3Q8L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbT5GaWxlOjpHbG9iPC9JdGVtPgogICAgICAgICAgICAgICAgPEl0ZW0+VGltZTo6TG9jYWw8L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbT5NYWlsOjpGaWVsZDo6RGF0ZTwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtPkZpbmRCaW48L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbT5NSU1FOjpQYXJzZXI8L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbT5FeHBvcnRlcjwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtPnN0cmljdDwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtPk1haWw6OkZpZWxkPC9JdGVtPgogICAgICAgICAgICA8L0FycmF5PgogICAgICAgIDwvU2V0dGluZz4KICAgIDwvQ29uZmlnSXRlbT4KICAgIDxDb25maWdJdGVtIE5hbWU9IkZyZWQ6OlNtYWxsUHJvZiMjI0Rpc2FibGVkRmlsZXMiIFJlcXVpcmVkPSIwIiBWYWxpZD0iMCI+CiAgICAgICAgPERlc2NyaXB0aW9uIExhbmc9ImVuIj5Eb24ndCBjaGVjayB0aGUgZm9sbG93aW5nIHBlcmwgZmlsZXMgb3IgcGF0aCBpbiBTbWFsbFByb2YuPC9EZXNjcmlwdGlvbj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZGUiPkVzIHNvbGxlbiBmb2xnZW5kZSBEYXRlaWVuIHVuZCBQZmFkZSBpbiBTbWFsbFByb2YgbmljaHQgZ2VwcvxmdCB3ZXJkZW4uPC9EZXNjcmlwdGlvbj4KICAgICAgICA8R3JvdXA+RnJlZDwvR3JvdXA+CiAgICAgICAgPFN1Ykdyb3VwPlNtYWxsUHJvZjwvU3ViR3JvdXA+CiAgICAgICAgPFNldHRpbmc+CiAgICAgICAgICAgIDxBcnJheT4KICAgICAgICAgICAgICAgIDxJdGVtPi91c3IvbGliL3Blcmw1PC9JdGVtPgogICAgICAgICAgICAgICAgPEl0ZW0+Li4vLi4vL0tlcm5lbC9TeXN0ZW0vRnJlZC88L0l0ZW0+CiAgICAgICAgICAgIDwvQXJyYXk+CiAgICAgICAgPC9TZXR0aW5nPgogICAgPC9Db25maWdJdGVtPgogICAgPENvbmZpZ0l0ZW0gTmFtZT0iRnJlZDo6Q29uZmlnTG9nIyMjT3JkZXJCeSIgUmVxdWlyZWQ9IjAiIFZhbGlkPSIxIj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZW4iPldoaWNoIG9yZGVyIHNob3VsZCB0aGUgY29uZmlnIGxvZyBkYXRhIGhhdmU/PC9EZXNjcmlwdGlvbj4KICAgICAgICA8RGVzY3JpcHRpb24gTGFuZz0iZGUiPk5hY2ggd2VsY2hlciBSZWloZW5mb2xnZSBzb2xsZW4gZGllIENvbmZpZ2xvZ2RhdGVuIGdlb3JkbmV0IHdlcmRlbj88L0Rlc2NyaXB0aW9uPgogICAgICAgIDxHcm91cD5GcmVkPC9Hcm91cD4KICAgICAgICA8U3ViR3JvdXA+Q29uZmlnTG9nPC9TdWJHcm91cD4KICAgICAgICA8U2V0dGluZz4KICAgICAgICAgICAgPE9wdGlvbiBTZWxlY3RlZElEPSIzIj4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iMyI+Q2FsbHM8L0l0ZW0+CiAgICAgICAgICAgICAgICA8SXRlbSBLZXk9IjAiPkNvbmZpZzwvSXRlbT4KICAgICAgICAgICAgICAgIDxJdGVtIEtleT0iMiI+UGFja2FnZTwvSXRlbT4KICAgICAgICAgICAgPC9PcHRpb24+CiAgICAgICAgPC9TZXR0aW5nPgogICAgPC9Db25maWdJdGVtPgo8L290cnNfY29uZmlnPgo=
IyAtLQojIEtlcm5lbC9Nb2R1bGVzL0RldmVsRnJlZC5wbSAtIGEgc3BlY2lhbCBkZXZlbG9wZXIgbW9kdWxlCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBEZXZlbEZyZWQucG0sdiAxLjEzIDIwMDkvMDQvMDYgMTA6MjU6NDQgbWggRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpNb2R1bGVzOjpEZXZlbEZyZWQ7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdygkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjEzICQpIFsxXTsKCiN1c2UgS2VybmVsOjpTeXN0ZW06OlhNTDsKdXNlIEtlcm5lbDo6U3lzdGVtOjpDb25maWc7CnVzZSBLZXJuZWw6OlN5c3RlbTo6RnJlZDsKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgT2JqZWN0cwogICAgT0JKRUNUOgogICAgZm9yIG15ICRPYmplY3QgKAogICAgICAgIHF3KAogICAgICAgIFBhcmFtT2JqZWN0IERCT2JqZWN0ICAgICBMb2dPYmplY3QgQ29uZmlnT2JqZWN0CiAgICAgICAgTWFpbk9iamVjdCAgTGF5b3V0T2JqZWN0IFRpbWVPYmplY3QKICAgICAgICApCiAgICAgICAgKQogICAgewogICAgICAgIGlmICggJFBhcmFteyRPYmplY3R9ICkgewogICAgICAgICAgICAkU2VsZi0+eyRPYmplY3R9ID0gJFBhcmFteyRPYmplY3R9OwogICAgICAgICAgICBuZXh0IE9CSkVDVDsKICAgICAgICB9CiAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5GYXRhbEVycm9yKCBNZXNzYWdlID0+ICJHb3Qgbm8gJE9iamVjdCEiICk7CiAgICB9CgogICAgIyAgICAkU2VsZi0+e1hNTE9iamVjdH0gPSBLZXJuZWw6OlN5c3RlbTo6WE1MLT5uZXcoJXskU2VsZn0pOwogICAgJFNlbGYtPntDb25maWdUb29sT2JqZWN0fSA9IEtlcm5lbDo6U3lzdGVtOjpDb25maWctPm5ldyggJXskU2VsZn0gKTsKICAgICRTZWxmLT57RnJlZE9iamVjdH0gICAgICAgPSBLZXJuZWw6OlN5c3RlbTo6RnJlZC0+bmV3KCAleyRTZWxmfSApOwogICAgJFNlbGYtPntTdWJhY3Rpb259ICAgICAgICA9ICRTZWxmLT57UGFyYW1PYmplY3R9LT5HZXRQYXJhbSggUGFyYW0gPT4gJ1N1YmFjdGlvbicgKTsKICAgIHJldHVybiAkU2VsZjsKfQoKc3ViIFJ1biB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIHNob3cgdGhlIG92ZXJ2aWV3CiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwoKICAgIGlmICggISRTZWxmLT57U3ViYWN0aW9ufSApIHsKICAgICAgICBteSAkVmVyc2lvbiA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdWZXJzaW9uJyk7CiAgICAgICAgaWYgKCAkVmVyc2lvbiA9fiBteyBeMlwuMVwuIH1tc3ggKSB7CiAgICAgICAgICAgIHJldHVybiAkU2VsZi0+X0FjdGl2YXRlRnJlZEZvcjIxKCk7CiAgICAgICAgfQogICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+RmF0YWxFcnJvcigKICAgICAgICAgICAgTWVzc2FnZSA9PiAiU29ycnksIHRoaXMgc2lkZSBpcyBjdXJyZW50bHkgdW5kZXIgZGV2ZWxvcG1lbnQhIgogICAgICAgICk7CiAgICB9CgogICAgIyAgICAgICAgbXkgJE91dHB1dCAgID0gJyc7CiAgICAjCiAgICAjICAgICAgICBteSBAVHJhbnNsYXRpb25XaGl0ZUxpc3QgPSAkU2VsZi0+e1hNTE9iamVjdH0tPlhNTEhhc2hHZXQoCiAgICAjICAgICAgICAgICAgVHlwZSA9PiAnRnJlZC1UcmFuc2xhdGlvbicsCiAgICAjICAgICAgICAgICAgS2V5ICA9PiAxLAogICAgIyAgICAgICAgICAgIENhY2hlID0+IDAsCiAgICAjICAgICAgICApOwogICAgIwogICAgIyAgICAgICAgbXkgJVdoaXRlTGlzdDsKICAgICMgICAgICAgIGZvciBteSAkQ29udGVudCAoQHskVHJhbnNsYXRpb25XaGl0ZUxpc3RbMV17VHJhbnNsYXRpb259fSkgewogICAgIyAgICAgICAgICAgIGlmICgkQ29udGVudC0+e0NvbnRlbnR9KSB7CiAgICAjICAgICAgICAgICAgICAgICMgYWRkIGFkZCBibG9jawogICAgIyAgICAgICAgICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJsb2NrKAogICAgIyAgICAgICAgICAgICAgICAgICAgTmFtZSA9PiAnTGluZScsCiAgICAjICAgICAgICAgICAgICAgICAgICBEYXRhID0+IHsKICAgICMgICAgICAgICAgICAgICAgICAgICAgICBXb3JkID0+ICRDb250ZW50LT57Q29udGVudH0sCiAgICAjICAgICAgICAgICAgICAgICAgICB9LAogICAgIyAgICAgICAgICAgICAgICApOwogICAgIyAgICAgICAgICAgIH0KICAgICMgICAgICAgIH0KICAgICMKICAgICMgICAgICAgICMgYnVpbGQgb3V0cHV0CiAgICAjICAgICAgICAkT3V0cHV0IC49ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+SGVhZGVyKFRpdGxlID0+ICJGcmVkLU92ZXJ2aWV3Iik7CiAgICAjICAgICAgICAkT3V0cHV0IC49ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+TmF2aWdhdGlvbkJhcigpOwogICAgIyAgICAgICAgJE91dHB1dCAuPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPk91dHB1dCgKICAgICMgICAgICAgICAgICBEYXRhID0+IHslUGFyYW19LAogICAgIyAgICAgICAgICAgIFRlbXBsYXRlRmlsZSA9PiAnRGV2ZWxGcmVkJywKICAgICMgICAgICAgICk7CiAgICAjICAgICAgICAkT3V0cHV0IC49ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+Rm9vdGVyKCk7CiAgICAjICAgICAgICByZXR1cm4gJE91dHB1dDsKICAgICMgICAgfQogICAgIyAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgIyAgICAjIGhhbmRsZSB0aGUgdHJhbnNsYXRpb24gbG9nCiAgICAjICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjICAgIGVsc2lmICgkU2VsZi0+e1N1YmFjdGlvbn0gZXEgJ1RyYW5zbGF0aW9uJykgewogICAgIyAgICAgICAgbXkgJFZhbHVlID0gJFNlbGYtPntQYXJhbU9iamVjdH0tPkdldFBhcmFtKFBhcmFtID0+ICdWYWx1ZScpOwogICAgIwogICAgIyAgICAgICAgbXkgQERhdGEgPSAkU2VsZi0+e1hNTE9iamVjdH0tPlhNTEhhc2hHZXQoCiAgICAjICAgICAgICAgICAgVHlwZSA9PiAnRnJlZC1UcmFuc2xhdGlvbicsCiAgICAjICAgICAgICAgICAgS2V5ICA9PiAxLAogICAgIyAgICAgICAgICAgIENhY2hlID0+IDAsCiAgICAjICAgICAgICApOwogICAgIwogICAgIyAgICAgICAgaWYgKCFARGF0YSkgewogICAgIyAgICAgICAgICAgIG15IEBIYXNoOwogICAgIwogICAgIyAgICAgICAgICAgICRIYXNoWzFde1RyYW5zbGF0aW9ufVsxXXtDb250ZW50fSA9ICRWYWx1ZTsKICAgICMgICAgICAgICAgICAkU2VsZi0+e1hNTE9iamVjdH0tPlhNTEhhc2hBZGQoCiAgICAjICAgICAgICAgICAgICAgIFR5cGUgICAgPT4gJ0ZyZWQtVHJhbnNsYXRpb24nLAogICAgIyAgICAgICAgICAgICAgICBLZXkgICAgID0+IDEsCiAgICAjICAgICAgICAgICAgICAgIFhNTEhhc2ggPT4gXEBIYXNoLAogICAgIyAgICAgICAgICAgICk7CiAgICAjICAgICAgICB9CiAgICAjICAgICAgICBlbHNlIHsKICAgICMgICAgICAgICAgICBwdXNoIEB7JERhdGFbMV17VHJhbnNsYXRpb259fSwge0NvbnRlbnQgPT4gJFZhbHVlfTsKICAgICMgICAgICAgICAgICAkU2VsZi0+e1hNTE9iamVjdH0tPlhNTEhhc2hVcGRhdGUoCiAgICAjICAgICAgICAgICAgICAgIFR5cGUgPT4gJ0ZyZWQtVHJhbnNsYXRpb24nLAogICAgIyAgICAgICAgICAgICAgICBLZXkgPT4gJzEnLAogICAgIyAgICAgICAgICAgICAgICBYTUxIYXNoID0+IFxARGF0YSwKICAgICMgICAgICAgICAgICApOwogICAgIwogICAgIyAgICAgICAgfQogICAgIwogICAgIyAgICAgICAgbXkgJFJlZmVyZXIgPSAkRU5We0hUVFBfUkVGRVJFUn07CiAgICAjICAgICAgICBpZiAoJFJlZmVyZXIgPX4gL1w/KC4rKSQvKSB7CiAgICAjICAgICAgICAgICAgJFJlZmVyZXIgPSAkMTsKICAgICMgICAgICAgIH0KICAgICMKICAgICMgICAgICAgIHJldHVybiAkU2VsZi0+e0xheW91dE9iamVjdH0tPlJlZGlyZWN0KE9QID0+ICRSZWZlcmVyKTsKICAgICMgICAgfQogICAgIyAgICBlbHNpZiAoJFNlbGYtPntTdWJhY3Rpb259IGVxICdUcmFuc2xhdGlvbkRlbGV0ZScpIHsKICAgICMgICAgICAgIG15IEBEYXRhID0gJFNlbGYtPntYTUxPYmplY3R9LT5YTUxIYXNoRGVsZXRlKAogICAgIyAgICAgICAgICAgIFR5cGUgPT4gJ0ZyZWQtVHJhbnNsYXRpb24nLAogICAgIyAgICAgICAgICAgIEtleSAgPT4gMSwKICAgICMgICAgICAgICk7CiAgICAjCiAgICAjICAgICAgICBteSAkUmVmZXJlciA9ICRFTlZ7SFRUUF9SRUZFUkVSfTsKICAgICMgICAgICAgIGlmICgkUmVmZXJlciA9fiAvXD8oLispJC8pIHsKICAgICMgICAgICAgICAgICAkUmVmZXJlciA9ICQxOwogICAgIyAgICAgICAgfQogICAgIwogICAgIyAgICAgICAgcmV0dXJuICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+UmVkaXJlY3QoT1AgPT4gJFJlZmVyZXIpOwogICAgIyAgICB9CiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgIyBmYXN0IGhhbmRsZSBmb3IgZnJlZCBzZXR0aW5ncwogICAgIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICMKICAgIGVsc2lmICggJFNlbGYtPntTdWJhY3Rpb259IGVxICdTZXR0aW5nJyApIHsKICAgICAgICBteSAkTW9kdWxlRm9yUmVmID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0ZyZWQ6Ok1vZHVsZScpOwogICAgICAgIGRlbGV0ZSAkTW9kdWxlRm9yUmVmLT57Q29uc29sZX07CiAgICAgICAgZm9yIG15ICRNb2R1bGUgKCBzb3J0IGtleXMgJXskTW9kdWxlRm9yUmVmfSApIHsKICAgICAgICAgICAgbXkgJENoZWNrZWQgPSAnJzsKICAgICAgICAgICAgaWYgKCAkTW9kdWxlRm9yUmVmLT57JE1vZHVsZX0tPntBY3RpdmV9ICkgewogICAgICAgICAgICAgICAgJENoZWNrZWQgPSAnY2hlY2tlZD0iY2hlY2tlZCInOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkJsb2NrKAogICAgICAgICAgICAgICAgTmFtZSA9PiAnRnJlZE1vZHVsZScsCiAgICAgICAgICAgICAgICBEYXRhID0+IHsKICAgICAgICAgICAgICAgICAgICBGcmVkTW9kdWxlID0+ICRNb2R1bGUsCiAgICAgICAgICAgICAgICAgICAgQ2hlY2tlZCAgICA9PiAkQ2hlY2tlZCwKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICk7CgogICAgICAgICAgICBpZiAoICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCJGcmVkOjokTW9kdWxlIikgKSB7CgogICAgICAgICAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jaygKICAgICAgICAgICAgICAgICAgICBOYW1lID0+ICdDb25maWcnLAogICAgICAgICAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgICAgICAgICBNb2R1bGVOYW1lID0+ICRNb2R1bGUsCiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgYnVpbGQgb3V0cHV0CiAgICAgICAgbXkgJE91dHB1dCA9ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+SGVhZGVyKCBUaXRsZSA9PiAiRnJlZC1TZXR0aW5nIiApOwogICAgICAgICRPdXRwdXQgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5PdXRwdXQoCiAgICAgICAgICAgIERhdGEgICAgICAgICA9PiB7JVBhcmFtfSwKICAgICAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdEZXZlbEZyZWRTZXR0aW5nJywKICAgICAgICApOwogICAgICAgIHJldHVybiAkT3V0cHV0OwogICAgfQoKICAgICMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAjCiAgICAjIGZhc3QgaGFuZGxlIGZvciBmcmVkIHNldHRpbmdzCiAgICAjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwogICAgZWxzaWYgKCAkU2VsZi0+e1N1YmFjdGlvbn0gZXEgJ1NldHRpbmdBY3Rpb24nICkgewogICAgICAgIG15ICRNb2R1bGVGb3JSZWYgICAgICAgID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0ZyZWQ6Ok1vZHVsZScpOwogICAgICAgIG15IEBTZWxlY3RlZEZyZWRNb2R1bGVzID0gJFNlbGYtPntQYXJhbU9iamVjdH0tPkdldEFycmF5KCBQYXJhbSA9PiAnRnJlZE1vZHVsZScgKTsKICAgICAgICBteSAlU2VsZWN0ZWRNb2R1bGVzICAgICA9IG1hcCB7ICRfID0+IDE7IH0gQFNlbGVjdGVkRnJlZE1vZHVsZXM7CiAgICAgICAgbXkgJFVwZGF0ZUZsYWc7CiAgICAgICAgZGVsZXRlICRNb2R1bGVGb3JSZWYtPntDb25zb2xlfTsKCiAgICAgICAgZm9yIG15ICRNb2R1bGUgKCBrZXlzICV7JE1vZHVsZUZvclJlZn0gKSB7CgogICAgICAgICAgICAjIHVwZGF0ZSB0aGUgc3lzY29uZmlnIHNldHRpbmdzCiAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICRNb2R1bGVGb3JSZWYtPnskTW9kdWxlfS0+e0FjdGl2ZX0gJiYgISRTZWxlY3RlZE1vZHVsZXN7JE1vZHVsZX0KICAgICAgICAgICAgICAgIHx8CiAgICAgICAgICAgICAgICAhJE1vZHVsZUZvclJlZi0+eyRNb2R1bGV9LT57QWN0aXZlfSAmJiAkU2VsZWN0ZWRNb2R1bGVzeyRNb2R1bGV9CiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICRTZWxmLT57Q29uZmlnVG9vbE9iamVjdH0tPkNvbmZpZ0l0ZW1VcGRhdGUoCiAgICAgICAgICAgICAgICAgICAgVmFsaWQgPT4gMSwKICAgICAgICAgICAgICAgICAgICBLZXkgICA9PiAiRnJlZDo6TW9kdWxlIyMjJE1vZHVsZSIsCiAgICAgICAgICAgICAgICAgICAgVmFsdWUgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAnQWN0aXZlJyA9PiAkU2VsZWN0ZWRNb2R1bGVzeyRNb2R1bGV9IHx8IDAsCgogICAgICAgICAgICAgICAgICAgICAgICAjICAgICAgICAgICAgICAgICAgICAgICAgJ01vZHVsZScgPT4gJE1vZHVsZUZvclJlZi0+eyRNb2R1bGV9LT57TW9kdWxlfQogICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICAgICAgJFVwZGF0ZUZsYWcgPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAjIHRoaXMgZnVuY3Rpb24gaXMgbmVzZWNjYXJ5IHRvIGZpbmlzaCB0aGUgc3lzY29uZmlnIHVwZGF0ZQogICAgICAgIG15ICRWZXJzaW9uID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ1ZlcnNpb24nKTsKICAgICAgICBpZiAoICRVcGRhdGVGbGFnICYmICRWZXJzaW9uID1+IG17IF4yXC5bMDEyXVwuIH1tc3ggKSB7CiAgICAgICAgICAgICRTZWxmLT57Q29uZmlnVG9vbE9iamVjdH0tPkNvbmZpZ0l0ZW1VcGRhdGVGaW5pc2goKTsKICAgICAgICB9CgogICAgICAgICMgZGVhY3RpdmF0ZSBmcmVkbW9kdWxlIHRvZG9zCiAgICAgICAgZm9yIG15ICRNb2R1bGUgKCBrZXlzICV7JE1vZHVsZUZvclJlZn0gKSB7CiAgICAgICAgICAgIGlmICggJE1vZHVsZUZvclJlZi0+eyRNb2R1bGV9LT57QWN0aXZlfSAmJiAhJFNlbGVjdGVkTW9kdWxlc3skTW9kdWxlfSApIHsKCiAgICAgICAgICAgICAgICAjIEVycm9yaGFuZGxpbmcgc2hvdWxkIGJlIGltcHJvdmVkIQogICAgICAgICAgICAgICAgJFNlbGYtPntGcmVkT2JqZWN0fS0+RGVhY3RpdmF0ZU1vZHVsZVRvZG9zKAogICAgICAgICAgICAgICAgICAgIE1vZHVsZU5hbWUgPT4gJE1vZHVsZSwKICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICMgYWN0aXZlIGZyZWQgbW9kdWxlIHRvZG9zCiAgICAgICAgZm9yIG15ICRNb2R1bGUgKCBrZXlzICV7JE1vZHVsZUZvclJlZn0gKSB7CiAgICAgICAgICAgIGlmICggISRNb2R1bGVGb3JSZWYtPnskTW9kdWxlfS0+e0FjdGl2ZX0gJiYgJFNlbGVjdGVkTW9kdWxlc3skTW9kdWxlfSApIHsKCiAgICAgICAgICAgICAgICAjIEVycm9yaGFuZGxpbmcgc2hvdWxkIGJlIGltcHJvdmVkIQogICAgICAgICAgICAgICAgJFNlbGYtPntGcmVkT2JqZWN0fS0+QWN0aXZhdGVNb2R1bGVUb2RvcygKICAgICAgICAgICAgICAgICAgICBNb2R1bGVOYW1lID0+ICRNb2R1bGUsCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5SZWRpcmVjdCggT1AgPT4gIkFjdGlvbj1EZXZlbEZyZWQmU3ViYWN0aW9uPVNldHRpbmciICk7CiAgICB9CiAgICByZXR1cm4gMTsKfQoKc3ViIF9BY3RpdmF0ZUZyZWRGb3IyMSB7CiAgICBteSAkU2VsZiA9IHNoaWZ0OwoKICAgIG15ICRNZXNzYWdlID0gJ0ZpbGUgYWxyZWFkeSBjaGFuZ2VkISc7CgogICAgaWYgKCAkU2VsZi0+e0ZyZWRPYmplY3R9LT5JbnNlcnRMYXlvdXRPYmplY3QyMSgpICkgewogICAgICAgICRNZXNzYWdlID0gJ0ZpbGUgY2hhbmdlZCEnOwogICAgfQoKICAgIG15ICRPdXRwdXQgPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPkhlYWRlcigpOwogICAgJE91dHB1dCAuPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPk5hdmlnYXRpb25CYXIoKTsKICAgICRPdXRwdXQgLj0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5Ob3RpZnkoCiAgICAgICAgSW5mbyAgICAgPT4gJE1lc3NhZ2UsCiAgICAgICAgUHJpb3JpdHkgPT4gJ0Vycm9yJywKICAgICk7CiAgICAkT3V0cHV0IC49ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+Rm9vdGVyKCk7CiAgICByZXR1cm4gJE91dHB1dDsKfQoxOwo=
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9GcmVkQmVuY2htYXJrLnBtIC0gbGF5b3V0IGJhY2tlbmQgbW9kdWxlCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBGcmVkQmVuY2htYXJrLnBtLHYgMS40IDIwMDkvMDQvMDYgMTA6MjU6MTMgbWggRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRCZW5jaG1hcms7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdygkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjQgJCkgWzFdOwoKPWhlYWQxIE5BTUUKCktlcm5lbDo6T3V0cHV0OjpIVE1MOjpGcmVkQmVuY2htYXJrIC0gbGF5b3V0IGJhY2tlbmQgbW9kdWxlCgo9aGVhZDEgU1lOT1BTSVMKCkFsbCBsYXlvdXQgZnVuY3Rpb25zIG9mIHRoZSBiZW5jaG1hcmsgb2JqZWN0Cgo9b3ZlciA0Cgo9Y3V0Cgo9aXRlbSBuZXcoKQoKY3JlYXRlIGFuIG9iamVjdAoKICAgICRCYWNrZW5kT2JqZWN0ID0gS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRCZW5jaG1hcmstPm5ldygKICAgICAgICAlUGFyYW0sCiAgICApOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGNoZWNrIG5lZWRlZCBvYmplY3RzCiAgICBmb3IgbXkgJE9iamVjdCAocXcoQ29uZmlnT2JqZWN0IExvZ09iamVjdCBMYXlvdXRPYmplY3QpKSB7CiAgICAgICAgJFNlbGYtPnskT2JqZWN0fSA9ICRQYXJhbXskT2JqZWN0fSB8fCBkaWUgIkdvdCBubyAkT2JqZWN0ISI7CiAgICB9CgogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBDcmVhdGVGcmVkT3V0cHV0KCkKCmNyZWF0ZSB0aGUgb3V0cHV0IG9mIHRoZSBTVERFUlIgbG9nCgogICAgJExheW91dE9iamVjdC0+Q3JlYXRlRnJlZE91dHB1dCgKICAgICAgICBNb2R1bGVzUmVmID0+ICRNb2R1bGVzUmVmLAogICAgKTsKCj1jdXQKCnN1YiBDcmVhdGVGcmVkT3V0cHV0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtNb2R1bGVSZWZ9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBNb2R1bGVSZWYhJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICByZXR1cm4gaWYgISRQYXJhbXtNb2R1bGVSZWZ9LT57RGF0YX07CiAgICByZXR1cm4gaWYgcmVmICRQYXJhbXtNb2R1bGVSZWZ9LT57RGF0YX0gbmUgJ0FSUkFZJzsKCiAgICBteSAkSFRNTExpbmVzID0gJyc7CiAgICBmb3IgbXkgJExpbmUgKCBAeyAkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9IH0gKSB7CiAgICAgICAgJEhUTUxMaW5lcyAuPSAnPHRyPic7CiAgICAgICAgZm9yIG15ICRDZWxsICggQHskTGluZX0gKSB7CiAgICAgICAgICAgICRIVE1MTGluZXMgLj0gIjx0ZD4kQ2VsbDwvdGQ+IjsKICAgICAgICB9CiAgICAgICAgJEhUTUxMaW5lcyAuPSAnPC90cj4nOwogICAgfQoKICAgIHJldHVybiBpZiAhJEhUTUxMaW5lczsKCiAgICAjIG91dHB1dCB0aGUgaHRtbAogICAgJFBhcmFte01vZHVsZVJlZn0tPntPdXRwdXR9ID0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5PdXRwdXQoCiAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdEZXZlbEZyZWRCZW5jaG1hcmsnLAogICAgICAgIERhdGEgICAgICAgICA9PiB7CiAgICAgICAgICAgIEhUTUxMaW5lcyA9PiAkSFRNTExpbmVzLAogICAgICAgIH0sCiAgICApOwoKICAgIHJldHVybiAxOwp9CgoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBzb2Z0d2FyZSBpcyBwYXJ0IG9mIHRoZSBPVFJTIHByb2plY3QgKGh0dHA6Ly9vdHJzLm9yZy8pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQpkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgoKPWN1dAoKPWhlYWQxIFZFUlNJT04KCiRSZXZpc2lvbjogMS40ICQgJERhdGU6IDIwMDkvMDQvMDYgMTA6MjU6MTMgJAoKPWN1dAo=
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9GcmVkQ29uc29sZS5wbSAtIGxheW91dCBiYWNrZW5kIG1vZHVsZQojIENvcHlyaWdodCAoQykgMjAwMS0yMDA5IE9UUlMgQUcsIGh0dHA6Ly9vdHJzLm9yZy8KIyAtLQojICRJZDogRnJlZENvbnNvbGUucG0sdiAxLjYgMjAwOS8wNC8wNiAxMDoyNToxMyBtaCBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQoKcGFja2FnZSBLZXJuZWw6Ok91dHB1dDo6SFRNTDo6RnJlZENvbnNvbGU7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdyhASVNBICRWRVJTSU9OKTsKJFZFUlNJT04gPSBxdygkUmV2aXNpb246IDEuNiAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRDb25zb2xlIC0gbGF5b3V0IGJhY2tlbmQgbW9kdWxlCgo9aGVhZDEgU1lOT1BTSVMKCkFsbCBsYXlvdXQgZnVuY3Rpb25zIG9mIGNvbnNvbGUgb2JqZWN0Cgo9b3ZlciA0Cgo9Y3V0Cgo9aXRlbSBuZXcoKQoKY3JlYXRlIGFuIG9iamVjdAoKICAgICRCYWNrZW5kT2JqZWN0ID0gS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRDb25zb2xlLT5uZXcoCiAgICAgICAgJVBhcmFtLAogICAgKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgb2JqZWN0cwogICAgZm9yIG15ICRPYmplY3QgKHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QgTGF5b3V0T2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JE9iamVjdH0gPSAkUGFyYW17JE9iamVjdH0gfHwgZGllICJHb3Qgbm8gJE9iamVjdCEiOwogICAgfQoKICAgIHJldHVybiAkU2VsZjsKfQoKPWl0ZW0gQ3JlYXRlRnJlZE91dHB1dCgpCgpjcmVhdGUgdGhlIG91dHB1dCBvZiB0aGUgU1RERVJSIGxvZwoKICAgICRMYXlvdXRPYmplY3QtPkNyZWF0ZUZyZWRPdXRwdXQoCiAgICAgICAgTW9kdWxlc1JlZiA9PiAkTW9kdWxlc1JlZiwKICAgICk7Cgo9Y3V0CgpzdWIgQ3JlYXRlRnJlZE91dHB1dCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRIVE1MTGluZXMgPSAnJzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte01vZHVsZVJlZn0gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIE1vZHVsZVJlZiEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgY3JlYXRlIHRoZSBjb25zb2xlIHRhYmxlCiAgICBteSAkQ29uc29sZQogICAgICAgID0gJ0FjdGl2YXRlZCBtb2R1bGVzOiA8Yj4nIC4gKCBqb2luICcgLSAnLCBAeyAkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9IH0gKSAuICc8L2I+JzsKCiAgICBpZiAoICRQYXJhbXtNb2R1bGVSZWZ9LT57U3RhdHVzfSApIHsKICAgICAgICBpZiAoICRQYXJhbXtNb2R1bGVSZWZ9LT57U2V0dGluZ30gKSB7CiAgICAgICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QmxvY2soCiAgICAgICAgICAgICAgICBOYW1lID0+ICdTZXR0aW5nJywKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgJFBhcmFte01vZHVsZVJlZn0tPntPdXRwdXR9ID0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5PdXRwdXQoCiAgICAgICAgICAgIFRlbXBsYXRlRmlsZSA9PiAnRGV2ZWxGcmVkQ29uc29sZScsCiAgICAgICAgICAgIERhdGEgICAgICAgICA9PiB7CiAgICAgICAgICAgICAgICBUZXh0ID0+ICRDb25zb2xlLAogICAgICAgICAgICB9LAogICAgICAgICk7CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCjE7Cgo9YmFjawoKPWhlYWQxIFRFUk1TIEFORCBDT05ESVRJT05TCgpUaGlzIHNvZnR3YXJlIGlzIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoaHR0cDovL290cnMub3JnLykuCgpUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQp0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCgo9Y3V0Cgo9aGVhZDEgVkVSU0lPTgoKJFJldmlzaW9uOiAxLjYgJCAkRGF0ZTogMjAwOS8wNC8wNiAxMDoyNToxMyAkCgo9Y3V0Cg==
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9GcmVkSFRNTENoZWNrLnBtIC0gbGF5b3V0IGJhY2tlbmQgbW9kdWxlCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBGcmVkSFRNTENoZWNrLnBtLHYgMS41IDIwMDkvMDQvMDYgMTA6MjU6MTMgbWggRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRIVE1MQ2hlY2s7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdyhASVNBICRWRVJTSU9OKTsKJFZFUlNJT04gPSBxdygkUmV2aXNpb246IDEuNSAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRIVE1MQ2hlY2sgLSBsYXlvdXQgYmFja2VuZCBtb2R1bGUKCj1oZWFkMSBTWU5PUFNJUwoKQWxsIGxheW91dCBmdW5jdGlvbnMgb2YgSFRNTCBjaGVjayBvYmplY3QKCj1vdmVyIDQKCj1jdXQKCj1pdGVtIG5ldygpCgpjcmVhdGUgYW4gb2JqZWN0CgogICAgJEJhY2tlbmRPYmplY3QgPSBLZXJuZWw6Ok91dHB1dDo6SFRNTDo6RnJlZFNUREVSUkxvZy0+bmV3KAogICAgICAgICVQYXJhbSwKICAgICk7Cgo9Y3V0CgpzdWIgbmV3IHsKICAgIG15ICggJFR5cGUsICVQYXJhbSApID0gQF87CgogICAgIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CiAgICBteSAkU2VsZiA9IHt9OwogICAgYmxlc3MoICRTZWxmLCAkVHlwZSApOwoKICAgICMgY2hlY2sgbmVlZGVkIG9iamVjdHMKICAgIGZvciBteSAkT2JqZWN0IChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0IExheW91dE9iamVjdCkpIHsKICAgICAgICAkU2VsZi0+eyRPYmplY3R9ID0gJFBhcmFteyRPYmplY3R9IHx8IGRpZSAiR290IG5vICRPYmplY3QhIjsKICAgIH0KCiAgICByZXR1cm4gJFNlbGY7Cn0KCj1pdGVtIENyZWF0ZUZyZWRPdXRwdXQoKQoKY3JlYXRlIHRoZSBvdXRwdXQgb2YgdGhlIFNUREVSUiBsb2cKCiAgICAkTGF5b3V0T2JqZWN0LT5DcmVhdGVGcmVkT3V0cHV0KAogICAgICAgIE1vZHVsZXNSZWYgPT4gJE1vZHVsZXNSZWYsCiAgICApOwoKPWN1dAoKc3ViIENyZWF0ZUZyZWRPdXRwdXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkSFRNTExpbmVzID0gJyc7CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtNb2R1bGVSZWZ9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBNb2R1bGVSZWYhJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoICRQYXJhbXtNb2R1bGVSZWZ9LT57RGF0YX0gKSB7CiAgICAgICAgZm9yIG15ICRMaW5lICggcmV2ZXJzZSBAeyAkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9IH0gKSB7CiAgICAgICAgICAgICRMaW5lID0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5Bc2NpaTJIdG1sKCBUZXh0ID0+ICRMaW5lICk7CiAgICAgICAgICAgICRIVE1MTGluZXMgLj0gIiAgICAgICAgPHRyPjx0ZD4kTGluZTwvdGQ+PC90cj5cbiI7CiAgICAgICAgfQoKICAgICAgICBpZiAoJEhUTUxMaW5lcykgewogICAgICAgICAgICAkUGFyYW17TW9kdWxlUmVmfS0+e091dHB1dH0gPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPk91dHB1dCgKICAgICAgICAgICAgICAgIFRlbXBsYXRlRmlsZSA9PiAnRGV2ZWxGcmVkSFRNTENoZWNrJywKICAgICAgICAgICAgICAgIERhdGEgICAgICAgICA9PiB7CiAgICAgICAgICAgICAgICAgICAgSFRNTExpbmVzID0+ICRIVE1MTGluZXMsCiAgICAgICAgICAgICAgICB9LAogICAgICAgICAgICApOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAxOwp9CgoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBzb2Z0d2FyZSBpcyBwYXJ0IG9mIHRoZSBPVFJTIHByb2plY3QgKGh0dHA6Ly9vdHJzLm9yZy8pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQpkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgoKPWN1dAoKPWhlYWQxIFZFUlNJT04KCiRSZXZpc2lvbjogMS41ICQgJERhdGU6IDIwMDkvMDQvMDYgMTA6MjU6MTMgJAoKPWN1dAo=
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9GcmVkU1RERVJSTG9nLnBtIC0gbGF5b3V0IGJhY2tlbmQgbW9kdWxlCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBGcmVkU1RERVJSTG9nLnBtLHYgMS45IDIwMDkvMDMvMzEgMTI6NDU6MTEgbWggRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRTVERFUlJMb2c7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdygkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjkgJCkgWzFdOwoKPWhlYWQxIE5BTUUKCktlcm5lbDo6T3V0cHV0OjpIVE1MOjpGcmVkU1RERVJSTG9nIC0gbGF5b3V0IGJhY2tlbmQgbW9kdWxlCgo9aGVhZDEgU1lOT1BTSVMKCkFsbCBsYXlvdXQgZnVuY3Rpb25zIG9mIFNUREVSUiBsb2cgb2JqZWN0cwoKPW92ZXIgNAoKPWN1dAoKPWl0ZW0gbmV3KCkKCmNyZWF0ZSBhbiBvYmplY3QKCiAgICAkQmFja2VuZE9iamVjdCA9IEtlcm5lbDo6T3V0cHV0OjpIVE1MOjpGcmVkU1RERVJSTG9nLT5uZXcoCiAgICAgICAgJVBhcmFtLAogICAgKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgb2JqZWN0cwogICAgZm9yIG15ICRPYmplY3QgKHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QgTGF5b3V0T2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JE9iamVjdH0gPSAkUGFyYW17JE9iamVjdH0gfHwgZGllICJHb3Qgbm8gJE9iamVjdCEiOwogICAgfQoKICAgIHJldHVybiAkU2VsZjsKfQoKPWl0ZW0gQ3JlYXRlRnJlZE91dHB1dCgpCgpjcmVhdGUgdGhlIG91dHB1dCBvZiB0aGUgU1RERVJSIGxvZwoKICAgICRMYXlvdXRPYmplY3QtPkNyZWF0ZUZyZWRPdXRwdXQoCiAgICAgICAgTW9kdWxlc1JlZiA9PiAkTW9kdWxlc1JlZiwKICAgICk7Cgo9Y3V0CgpzdWIgQ3JlYXRlRnJlZE91dHB1dCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17TW9kdWxlUmVmfSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgTW9kdWxlUmVmIScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgcmV0dXJuIGlmICEkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9OwogICAgcmV0dXJuIGlmIHJlZiAkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9IG5lICdBUlJBWSc7CgogICAgIyBjcmVhdGUgaHRtbCBzdHJpbmcKICAgIG15ICRIVE1MTGluZXM7CiAgICBmb3IgbXkgJExpbmUgKCByZXZlcnNlIEB7ICRQYXJhbXtNb2R1bGVSZWZ9LT57RGF0YX0gfSApIHsKCiAgICAgICAgIyBjb252ZXJ0IGFzY2lpIHRvIGh0bWwKICAgICAgICAkSFRNTExpbmVzIC49ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QXNjaWkySHRtbCgKICAgICAgICAgICAgVGV4dCAgICAgICAgICAgPT4gJExpbmUsCiAgICAgICAgICAgIEhUTUxSZXN1bHRNb2RlID0+IDEsCiAgICAgICAgICAgIFR5cGUgICAgICAgICAgID0+ICdOb3JtYWwnLAogICAgICAgICk7CiAgICB9CgogICAgcmV0dXJuIGlmICEkSFRNTExpbmVzOwoKICAgICRIVE1MTGluZXMgPSAiPHRyPjx0ZD4kSFRNTExpbmVzPC90ZD48L3RyPiI7CgogICAgIyBvdXRwdXQgdGhlIGh0bWwKICAgICRQYXJhbXtNb2R1bGVSZWZ9LT57T3V0cHV0fSA9ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+T3V0cHV0KAogICAgICAgIFRlbXBsYXRlRmlsZSA9PiAnRGV2ZWxGcmVkU1RERVJSTG9nJywKICAgICAgICBEYXRhICAgICAgICAgPT4gewogICAgICAgICAgICBIVE1MTGluZXMgPT4gJEhUTUxMaW5lcywKICAgICAgICB9LAogICAgKTsKCiAgICByZXR1cm4gMTsKfQoKMTsKCj1iYWNrCgo9aGVhZDEgVEVSTVMgQU5EIENPTkRJVElPTlMKClRoaXMgc29mdHdhcmUgaXMgcGFydCBvZiB0aGUgT1RSUyBwcm9qZWN0IChodHRwOi8vb3Rycy5vcmcvKS4KClRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCnRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KCj1jdXQKCj1oZWFkMSBWRVJTSU9OCgokUmV2aXNpb246IDEuOSAkICREYXRlOiAyMDA5LzAzLzMxIDEyOjQ1OjExICQKCj1jdXQK
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9GcmVkU21hbGxQcm9mLnBtIC0gbGF5b3V0IGJhY2tlbmQgbW9kdWxlCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBGcmVkU21hbGxQcm9mLnBtLHYgMS45IDIwMDkvMDQvMDYgMTA6MjU6MTMgbWggRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRTbWFsbFByb2Y7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdyhASVNBICRWRVJTSU9OKTsKJFZFUlNJT04gPSBxdygkUmV2aXNpb246IDEuOSAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRTbWFsbFByb2YgLSBsYXlvdXQgYmFja2VuZCBtb2R1bGUKCj1oZWFkMSBTWU5PUFNJUwoKQWxsIGxheW91dCBmdW5jdGlvbnMgb2YgU21hbGxQcm9mIG9iamVjdAoKPW92ZXIgNAoKPWN1dAoKPWl0ZW0gbmV3KCkKCmNyZWF0ZSBhbiBvYmplY3QKCiAgICAkQmFja2VuZE9iamVjdCA9IEtlcm5lbDo6T3V0cHV0OjpIVE1MOjpGcmVkU21hbGxQcm9mLT5uZXcoCiAgICAgICAgJVBhcmFtLAogICAgKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgb2JqZWN0cwogICAgZm9yIG15ICRPYmplY3QgKHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QgTGF5b3V0T2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JE9iamVjdH0gPSAkUGFyYW17JE9iamVjdH0gfHwgZGllICJHb3Qgbm8gJE9iamVjdCEiOwogICAgfQoKICAgIHJldHVybiAkU2VsZjsKfQoKPWl0ZW0gQ3JlYXRlRnJlZE91dHB1dCgpCgpjcmVhdGUgdGhlIG91dHB1dCBvZiB0aGUgU21hbGxQcm9mIHByb2ZpbGluZyB0b29sCgogICAgJExheW91dE9iamVjdC0+Q3JlYXRlRnJlZE91dHB1dCgKICAgICAgICBNb2R1bGVzUmVmID0+ICRNb2R1bGVzUmVmLAogICAgKTsKCj1jdXQKCnN1YiBDcmVhdGVGcmVkT3V0cHV0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgbXkgJEhUTUxMaW5lcyA9ICcnOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17TW9kdWxlUmVmfSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgTW9kdWxlUmVmIScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBwcmVwYXJlIHRoZSBwcm9maWxpbmcgZGF0YSBmb3IgYSBiZXR0ZXIgcmVhZGFiaWxpdHkKICAgIGZvciBteSAkTGluZSAoIEB7ICRQYXJhbXtNb2R1bGVSZWZ9LT57RGF0YX0gfSApIHsKICAgICAgICBmb3IgbXkgJFREICggQHskTGluZX0gKSB7CiAgICAgICAgICAgICRURCA9ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QXNjaWkySHRtbCggVGV4dCA9PiAkVEQgKTsKICAgICAgICB9CiAgICAgICAgJEhUTUxMaW5lcyAuPSAiICAgICAgICA8dHI+XG4iCiAgICAgICAgICAgIC4gIiAgICAgICAgICA8dGQgYWxpZ249XCJyaWdodFwiPiRMaW5lLT5bMl08L3RkPlxuIgogICAgICAgICAgICAuICIgICAgICAgICAgPHRkIGFsaWduPVwicmlnaHRcIj4kTGluZS0+WzNdPC90ZD5cbiIKICAgICAgICAgICAgLiAiICAgICAgICAgIDx0ZCBhbGlnbj1cInJpZ2h0XCI+JExpbmUtPls0XTwvdGQ+XG4iCiAgICAgICAgICAgIC4gIiAgICAgICAgICA8dGQ+JExpbmUtPlswXTwvdGQ+XG4iCiAgICAgICAgICAgIC4gIiAgICAgICAgICA8dGQgYWxpZ249XCJyaWdodFwiPiRMaW5lLT5bMV06PC90ZD5cbiIKICAgICAgICAgICAgLiAiICAgICAgICAgIDx0ZD4kTGluZS0+WzVdPC90ZD5cbiIKICAgICAgICAgICAgLiAiICAgICAgICA8L3RyPiI7CiAgICB9CgogICAgIyBnZXQgYWxsIHBhY2thZ2VzIHdoaWNoIFNtYWxsUHJvZiBjaGVja3MKICAgIG15ICRQYWNrYWdlcyA9ICcnOwogICAgaWYgKCAkUGFyYW17TW9kdWxlUmVmfS0+e1BhY2thZ2VzfSApIHsKICAgICAgICAkUGFja2FnZXMgPSBqb2luICcgLSAnLCBAeyAkUGFyYW17TW9kdWxlUmVmfS0+e1BhY2thZ2VzfSB9OwogICAgfQoKICAgICMgc2hvdyB0aGUgcHJvZmlsaW5nIGRhdGEKICAgIGlmICgkSFRNTExpbmVzKSB7CiAgICAgICAgJFBhcmFte01vZHVsZVJlZn0tPntPdXRwdXR9ID0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5PdXRwdXQoCiAgICAgICAgICAgIFRlbXBsYXRlRmlsZSA9PiAnRGV2ZWxGcmVkU21hbGxQcm9mJywKICAgICAgICAgICAgRGF0YSAgICAgICAgID0+IHsKICAgICAgICAgICAgICAgIEhUTUxMaW5lcyA9PiAkSFRNTExpbmVzLAogICAgICAgICAgICAgICAgVG90YWxDYWxsID0+ICRQYXJhbXtNb2R1bGVSZWZ9LT57VG90YWxDYWxsfSwKICAgICAgICAgICAgICAgIFBhY2thZ2VzICA9PiAkUGFja2FnZXMsCiAgICAgICAgICAgIH0sCiAgICAgICAgKTsKICAgIH0KCiAgICByZXR1cm4gMTsKfQoKMTsKCj1iYWNrCgo9aGVhZDEgVEVSTVMgQU5EIENPTkRJVElPTlMKClRoaXMgc29mdHdhcmUgaXMgcGFydCBvZiB0aGUgT1RSUyBwcm9qZWN0IChodHRwOi8vb3Rycy5vcmcvKS4KClRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCnRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KCj1jdXQKCj1oZWFkMSBWRVJTSU9OCgokUmV2aXNpb246IDEuOSAkICREYXRlOiAyMDA5LzA0LzA2IDEwOjI1OjEzICQKCj1jdXQK
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9GcmVkRFByb2YucG0gLSBsYXlvdXQgYmFja2VuZCBtb2R1bGUKIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IEZyZWREUHJvZi5wbSx2IDEuOCAyMDA5LzA0LzA2IDEwOjI1OjEzIG1oIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6T3V0cHV0OjpIVE1MOjpGcmVkRFByb2Y7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdyhASVNBICRWRVJTSU9OKTsKJFZFUlNJT04gPSBxdygkUmV2aXNpb246IDEuOCAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWREUHJvZiAtIGxheW91dCBiYWNrZW5kIG1vZHVsZQoKPWhlYWQxIFNZTk9QU0lTCgpBbGwgbGF5b3V0IGZ1bmN0aW9ucyBvZiBEUHJvZiBvYmplY3QKCj1vdmVyIDQKCj1jdXQKCj1pdGVtIG5ldygpCgpjcmVhdGUgYW4gb2JqZWN0CgogICAgJEJhY2tlbmRPYmplY3QgPSBLZXJuZWw6Ok91dHB1dDo6SFRNTDo6RnJlZERQcm9mLT5uZXcoCiAgICAgICAgJVBhcmFtLAogICAgKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBjaGVjayBuZWVkZWQgb2JqZWN0cwogICAgZm9yIG15ICRPYmplY3QgKHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QgTGF5b3V0T2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JE9iamVjdH0gPSAkUGFyYW17JE9iamVjdH0gfHwgZGllICJHb3Qgbm8gJE9iamVjdCEiOwogICAgfQoKICAgIHJldHVybiAkU2VsZjsKfQoKPWl0ZW0gQ3JlYXRlRnJlZE91dHB1dCgpCgpjcmVhdGUgdGhlIG91dHB1dCBvZiB0aGUgRFByb2YgcHJvZmlsaW5nIHRvb2wKCiAgICAkTGF5b3V0T2JqZWN0LT5DcmVhdGVGcmVkT3V0cHV0KAogICAgICAgIE1vZHVsZXNSZWYgPT4gJE1vZHVsZXNSZWYsCiAgICApOwoKPWN1dAoKc3ViIENyZWF0ZUZyZWRPdXRwdXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkSFRNTExpbmVzID0gJyc7CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtNb2R1bGVSZWZ9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBNb2R1bGVSZWYhJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIHByZXBhcmUgdGhlIHByb2ZpbGluZyBkYXRhIGZvciBhIGJldHRlciByZWFkYWJpbGl0eQogICAgaWYgKCAkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9ICkgewogICAgICAgIGZvciBteSAkTGluZSAoIEB7ICRQYXJhbXtNb2R1bGVSZWZ9LT57RGF0YX0gfSApIHsKICAgICAgICAgICAgZm9yIG15ICRURCAoIEB7JExpbmV9ICkgewogICAgICAgICAgICAgICAgaWYgKCAhZGVmaW5lZCgkVEQpICkgewogICAgICAgICAgICAgICAgICAgICRURCA9ICcnOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgJFREID0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5Bc2NpaTJIdG1sKCBUZXh0ID0+ICRURCApOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkSFRNTExpbmVzIC49ICIgICAgICAgIDx0cj5cbiIKICAgICAgICAgICAgICAgIC4gIiAgICAgICAgICA8dGQgYWxpZ249XCJyaWdodFwiPiRMaW5lLT5bMF08L3RkPlxuIgogICAgICAgICAgICAgICAgLiAiICAgICAgICAgIDx0ZCBhbGlnbj1cInJpZ2h0XCI+JExpbmUtPlsxXTwvdGQ+XG4iCiAgICAgICAgICAgICAgICAuICIgICAgICAgICAgPHRkIGFsaWduPVwicmlnaHRcIj4kTGluZS0+WzJdPC90ZD5cbiIKICAgICAgICAgICAgICAgIC4gIiAgICAgICAgICA8dGQgYWxpZ249XCJyaWdodFwiPiRMaW5lLT5bM108L3RkPlxuIgogICAgICAgICAgICAgICAgLiAiICAgICAgICAgIDx0ZCBhbGlnbj1cInJpZ2h0XCI+JExpbmUtPls0XTwvdGQ+XG4iCiAgICAgICAgICAgICAgICAuICIgICAgICAgICAgPHRkIGFsaWduPVwicmlnaHRcIj4kTGluZS0+WzVdOjwvdGQ+XG4iCiAgICAgICAgICAgICAgICAuICIgICAgICAgICAgPHRkPiRMaW5lLT5bNl08L3RkPlxuIgogICAgICAgICAgICAgICAgLiAiICAgICAgICA8L3RyPlxuIjsKICAgICAgICB9CiAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9LT5CbG9jaygKICAgICAgICAgICAgTmFtZSA9PiAnVGltZVRhYmxlJywKICAgICAgICAgICAgRGF0YSA9PiB7CiAgICAgICAgICAgICAgICBIVE1MTGluZXMgPT4gJEhUTUxMaW5lcywKICAgICAgICAgICAgICAgIFRvdGFsVGltZSA9PiAkUGFyYW17TW9kdWxlUmVmfS0+e1RvdGFsVGltZX0sCiAgICAgICAgICAgICAgICBUb3RhbENhbGwgPT4gJFBhcmFte01vZHVsZVJlZn0tPntUb3RhbENhbGx9LAogICAgICAgICAgICB9LAogICAgICAgICk7CiAgICB9CiAgICBlbHNpZiAoICRQYXJhbXtNb2R1bGVSZWZ9LT57RnVuY3Rpb25UcmVlfSApIHsKICAgICAgICBmb3IgbXkgJExpbmUgKCBAeyAkUGFyYW17TW9kdWxlUmVmfS0+e0Z1bmN0aW9uVHJlZX0gfSApIHsKICAgICAgICAgICAgZm9yIG15ICRURCAoIEB7JExpbmV9ICkgewogICAgICAgICAgICAgICAgJFREID0gJFNlbGYtPntMYXlvdXRPYmplY3R9LT5Bc2NpaTJIdG1sKCBUZXh0ID0+ICRURCApOwogICAgICAgICAgICB9CiAgICAgICAgICAgICRMaW5lLT5bMV0gPX4gcy8gLyZuYnNwOyZuYnNwOy9nOwogICAgICAgICAgICAkSFRNTExpbmVzIC49ICIgICAgICAgIDx0cj5cbiIKICAgICAgICAgICAgICAgIC4gIiAgICAgICAgICA8dGQgYWxpZ249XCJyaWdodFwiPiRMaW5lLT5bMF08L3RkPlxuIgogICAgICAgICAgICAgICAgLiAiICAgICAgICAgIDx0ZD4kTGluZS0+WzFdPC90ZD5cbiIKICAgICAgICAgICAgICAgIC4gIiAgICAgICAgPC90cj5cbiI7CiAgICAgICAgfQogICAgICAgICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QmxvY2soCiAgICAgICAgICAgIE5hbWUgPT4gJ0Z1bmN0aW9uTGlzdCcsCiAgICAgICAgICAgIERhdGEgPT4gewogICAgICAgICAgICAgICAgSFRNTExpbmVzID0+ICRIVE1MTGluZXMsCiAgICAgICAgICAgIH0sCiAgICAgICAgKTsKICAgIH0KCiAgICAjIHNob3cgdGhlIHByb2ZpbGluZyBkYXRhCiAgICBpZiAoJEhUTUxMaW5lcykgewogICAgICAgICRQYXJhbXtNb2R1bGVSZWZ9LT57T3V0cHV0fSA9ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+T3V0cHV0KAogICAgICAgICAgICBUZW1wbGF0ZUZpbGUgPT4gJ0RldmVsRnJlZERQcm9mJywKICAgICAgICApOwogICAgfQoKICAgIHJldHVybiAxOwp9CgoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBzb2Z0d2FyZSBpcyBwYXJ0IG9mIHRoZSBPVFJTIHByb2plY3QgKGh0dHA6Ly9vdHJzLm9yZy8pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQpkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgoKPWN1dAoKPWhlYWQxIFZFUlNJT04KCiRSZXZpc2lvbjogMS44ICQgJERhdGU6IDIwMDkvMDQvMDYgMTA6MjU6MTMgJAoKPWN1dAo=
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9GcmVkVHJhbnNsYXRpb25EZWJ1Zy5wbSAtIGxheW91dCBiYWNrZW5kIG1vZHVsZQojIENvcHlyaWdodCAoQykgMjAwMS0yMDA5IE9UUlMgQUcsIGh0dHA6Ly9vdHJzLm9yZy8KIyAtLQojICRJZDogRnJlZFRyYW5zbGF0aW9uRGVidWcucG0sdiAxLjUgMjAwOS8wNC8wNiAxMDoyNToxMyBtaCBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQoKcGFja2FnZSBLZXJuZWw6Ok91dHB1dDo6SFRNTDo6RnJlZFRyYW5zbGF0aW9uRGVidWc7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdyhASVNBICRWRVJTSU9OKTsKJFZFUlNJT04gPSBxdygkUmV2aXNpb246IDEuNSAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRUcmFuc2xhdGlvbkRlYnVnIC0gbGF5b3V0IGJhY2tlbmQgbW9kdWxlCgo9aGVhZDEgU1lOT1BTSVMKCkFsbCBsYXlvdXQgZnVuY3Rpb25zIG9mIHRyYW5zbGF0aW9uIGRlYnVnIG1vZHVsZQoKPW92ZXIgNAoKPWN1dAoKPWl0ZW0gbmV3KCkKCmNyZWF0ZSBhbiBvYmplY3QKCiAgICAkQmFja2VuZE9iamVjdCA9IEtlcm5lbDo6T3V0cHV0OjpIVE1MOjpGcmVkVHJhbnNsYXRpb25EZWJ1Zy0+bmV3KAogICAgICAgICVQYXJhbSwKICAgICk7Cgo9Y3V0CgpzdWIgbmV3IHsKICAgIG15ICggJFR5cGUsICVQYXJhbSApID0gQF87CgogICAgIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CiAgICBteSAkU2VsZiA9IHt9OwogICAgYmxlc3MoICRTZWxmLCAkVHlwZSApOwoKICAgICMgY2hlY2sgbmVlZGVkIG9iamVjdHMKICAgIGZvciBteSAkT2JqZWN0IChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0IExheW91dE9iamVjdCkpIHsKICAgICAgICAkU2VsZi0+eyRPYmplY3R9ID0gJFBhcmFteyRPYmplY3R9IHx8IGRpZSAiR290IG5vICRPYmplY3QhIjsKICAgIH0KCiAgICByZXR1cm4gJFNlbGY7Cn0KCj1pdGVtIENyZWF0ZUZyZWRPdXRwdXQoKQoKY3JlYXRlIHRoZSBvdXRwdXQgb2YgdGhlIHRyYW5zbGF0aW9uZGVidWdnaW5nIGxvZwoKICAgICRMYXlvdXRPYmplY3QtPkNyZWF0ZUZyZWRPdXRwdXQoCiAgICAgICAgTW9kdWxlc1JlZiA9PiAkTW9kdWxlc1JlZiwKICAgICk7Cgo9Y3V0CgpzdWIgQ3JlYXRlRnJlZE91dHB1dCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRIVE1MTGluZXMgPSAnJzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte01vZHVsZVJlZn0gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIE1vZHVsZVJlZiEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGZvciBteSAkTGluZSAoIEB7ICRQYXJhbXtNb2R1bGVSZWZ9LT57RGF0YX0gfSApIHsKICAgICAgICAkSFRNTExpbmVzIC49ICIgICAgICAgIDx0cj48dGQ+JExpbmU8L3RkPjwvdHI+IjsKICAgIH0KCiAgICBpZiAoJEhUTUxMaW5lcykgewogICAgICAgICRQYXJhbXtNb2R1bGVSZWZ9LT57T3V0cHV0fSA9ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+T3V0cHV0KAogICAgICAgICAgICBUZW1wbGF0ZUZpbGUgPT4gJ0RldmVsRnJlZFRyYW5zbGF0aW9uRGVidWcnLAogICAgICAgICAgICBEYXRhICAgICAgICAgPT4gewogICAgICAgICAgICAgICAgSFRNTExpbmVzID0+ICRIVE1MTGluZXMsCiAgICAgICAgICAgIH0sCiAgICAgICAgKTsKICAgIH0KCiAgICByZXR1cm4gMTsKfQoKMTsKCj1iYWNrCgo9aGVhZDEgVEVSTVMgQU5EIENPTkRJVElPTlMKClRoaXMgc29mdHdhcmUgaXMgcGFydCBvZiB0aGUgT1RSUyBwcm9qZWN0IChodHRwOi8vb3Rycy5vcmcvKS4KClRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCnRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KCj1jdXQKCj1oZWFkMSBWRVJTSU9OCgokUmV2aXNpb246IDEuNSAkICREYXRlOiAyMDA5LzA0LzA2IDEwOjI1OjEzICQKCj1jdXQK
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9GcmVkU1FMTG9nLnBtIC0gbGF5b3V0IGJhY2tlbmQgbW9kdWxlCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBGcmVkU1FMTG9nLnBtLHYgMS44IDIwMDkvMDQvMDYgMTA6MjU6MTMgbWggRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRTUUxMb2c7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdyhASVNBICRWRVJTSU9OKTsKJFZFUlNJT04gPSBxdygkUmV2aXNpb246IDEuOCAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRTUUxMb2cgLSBsYXlvdXQgYmFja2VuZCBtb2R1bGUKCj1oZWFkMSBTWU5PUFNJUwoKQWxsIGxheW91dCBmdW5jdGlvbnMgb2YgU1FMIGxvZyBtb2R1bGUKCj1vdmVyIDQKCj1jdXQKCj1pdGVtIG5ldygpCgpjcmVhdGUgYW4gb2JqZWN0CgogICAgJEJhY2tlbmRPYmplY3QgPSBLZXJuZWw6Ok91dHB1dDo6SFRNTDo6RnJlZFNRTExvZy0+bmV3KAogICAgICAgICVQYXJhbSwKICAgICk7Cgo9Y3V0CgpzdWIgbmV3IHsKICAgIG15ICggJFR5cGUsICVQYXJhbSApID0gQF87CgogICAgIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CiAgICBteSAkU2VsZiA9IHt9OwogICAgYmxlc3MoICRTZWxmLCAkVHlwZSApOwoKICAgICMgY2hlY2sgbmVlZGVkIG9iamVjdHMKICAgIGZvciBteSAkT2JqZWN0IChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0IExheW91dE9iamVjdCkpIHsKICAgICAgICAkU2VsZi0+eyRPYmplY3R9ID0gJFBhcmFteyRPYmplY3R9IHx8IGRpZSAiR290IG5vICRPYmplY3QhIjsKICAgIH0KCiAgICByZXR1cm4gJFNlbGY7Cn0KCj1pdGVtIENyZWF0ZUZyZWRPdXRwdXQoKQoKY3JlYXRlIHRoZSBvdXRwdXQgb2YgdGhlIHRyYW5zbGF0aW9uZGVidWdnaW5nIGxvZwoKICAgICRMYXlvdXRPYmplY3QtPkNyZWF0ZUZyZWRPdXRwdXQoCiAgICAgICAgTW9kdWxlc1JlZiA9PiAkTW9kdWxlc1JlZiwKICAgICk7Cgo9Y3V0CgpzdWIgQ3JlYXRlRnJlZE91dHB1dCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15ICRIVE1MTGluZXMgPSAnJzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte01vZHVsZVJlZn0gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIE1vZHVsZVJlZiEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGZvciBteSAkTGluZSAoIEB7ICRQYXJhbXtNb2R1bGVSZWZ9LT57RGF0YX0gfSApIHsKICAgICAgICBmb3IgbXkgJFREICggQHskTGluZX0gKSB7CiAgICAgICAgICAgICRURCA9ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+QXNjaWkySHRtbCggVGV4dCA9PiAkVEQgKTsKICAgICAgICB9CiAgICAgICAgbXkgJENsYXNzID0gJyc7CiAgICAgICAgaWYgKCAkTGluZS0+WzRdICkgewogICAgICAgICAgICAkQ2xhc3MgPSAnIGNsYXNzPSJjb250ZW50a2V5Iic7CiAgICAgICAgfQoKICAgICAgICAkSFRNTExpbmVzIC49ICIgICAgICAgIDx0ciRDbGFzcz5cbiIKICAgICAgICAgICAgLiAiICAgICAgICAgIDx0ZD4kTGluZS0+WzBdPC90ZD5cbiIKICAgICAgICAgICAgLiAiICAgICAgICAgIDx0ZD4kTGluZS0+WzFdPC90ZD5cbiIKICAgICAgICAgICAgLiAiICAgICAgICAgIDx0ZD4kTGluZS0+WzJdPC90ZD5cbiIKICAgICAgICAgICAgLiAiICAgICAgICAgIDx0ZD4kTGluZS0+WzNdPC90ZD5cbiIKICAgICAgICAgICAgLiAiICAgICAgICAgIDx0ZD4kTGluZS0+WzRdPC90ZD5cbiIKICAgICAgICAgICAgLiAiICAgICAgICA8L3RyPiI7CiAgICB9CgogICAgaWYgKCRIVE1MTGluZXMpIHsKICAgICAgICAkUGFyYW17TW9kdWxlUmVmfS0+e091dHB1dH0gPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPk91dHB1dCgKICAgICAgICAgICAgVGVtcGxhdGVGaWxlID0+ICdEZXZlbEZyZWRTUUxMb2cnLAogICAgICAgICAgICBEYXRhICAgICAgICAgPT4gewogICAgICAgICAgICAgICAgSFRNTExpbmVzICAgICAgICA9PiAkSFRNTExpbmVzLAogICAgICAgICAgICAgICAgQWxsU3RhdGVtZW50cyAgICA9PiAkUGFyYW17TW9kdWxlUmVmfS0+e0FsbFN0YXRlbWVudHN9LAogICAgICAgICAgICAgICAgRG9TdGF0ZW1lbnRzICAgICA9PiAkUGFyYW17TW9kdWxlUmVmfS0+e0RvU3RhdGVtZW50c30sCiAgICAgICAgICAgICAgICBTZWxlY3RTdGF0ZW1lbnRzID0+ICRQYXJhbXtNb2R1bGVSZWZ9LT57U2VsZWN0U3RhdGVtZW50c30sCiAgICAgICAgICAgICAgICBUaW1lICAgICAgICAgICAgID0+ICRQYXJhbXtNb2R1bGVSZWZ9LT57VGltZX0sCiAgICAgICAgICAgIH0sCiAgICAgICAgKTsKICAgIH0KCiAgICByZXR1cm4gMTsKfQoKMTsKCj1iYWNrCgo9aGVhZDEgVEVSTVMgQU5EIENPTkRJVElPTlMKClRoaXMgc29mdHdhcmUgaXMgcGFydCBvZiB0aGUgT1RSUyBwcm9qZWN0IChodHRwOi8vb3Rycy5vcmcvKS4KClRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCnRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KCj1jdXQKCj1oZWFkMSBWRVJTSU9OCgokUmV2aXNpb246IDEuOCAkICREYXRlOiAyMDA5LzA0LzA2IDEwOjI1OjEzICQKCj1jdXQK
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9GcmVkQ29uZmlnTG9nLnBtIC0gbGF5b3V0IGJhY2tlbmQgbW9kdWxlCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBGcmVkQ29uZmlnTG9nLnBtLHYgMS42IDIwMDkvMDQvMDYgMTA6MjU6MTMgbWggRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRDb25maWdMb2c7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdyhASVNBICRWRVJTSU9OKTsKJFZFUlNJT04gPSBxdygkUmV2aXNpb246IDEuNiAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRDb25maWdMb2cgLSBsYXlvdXQgYmFja2VuZCBtb2R1bGUKCj1oZWFkMSBTWU5PUFNJUwoKQWxsIGxheW91dCBmdW5jdGlvbnMgb2YgdGhlIGNvbmZpZyBsb2cgbW9kdWxlCgo9b3ZlciA0Cgo9Y3V0Cgo9aXRlbSBuZXcoKQoKY3JlYXRlIGFuIG9iamVjdAoKICAgICRCYWNrZW5kT2JqZWN0ID0gS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWRDb25maWdMb2ctPm5ldygKICAgICAgICAlUGFyYW0sCiAgICApOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGNoZWNrIG5lZWRlZCBvYmplY3RzCiAgICBmb3IgbXkgJE9iamVjdCAocXcoQ29uZmlnT2JqZWN0IExvZ09iamVjdCBMYXlvdXRPYmplY3QpKSB7CiAgICAgICAgJFNlbGYtPnskT2JqZWN0fSA9ICRQYXJhbXskT2JqZWN0fSB8fCBkaWUgIkdvdCBubyAkT2JqZWN0ISI7CiAgICB9CgogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBDcmVhdGVGcmVkT3V0cHV0KCkKCmNyZWF0ZSB0aGUgb3V0cHV0IG9mIHRoZSB0cmFuc2xhdGlvbmRlYnVnZ2luZyBsb2cKCiAgICAkTGF5b3V0T2JqZWN0LT5DcmVhdGVGcmVkT3V0cHV0KAogICAgICAgIE1vZHVsZXNSZWYgPT4gJE1vZHVsZXNSZWYsCiAgICApOwoKPWN1dAoKc3ViIENyZWF0ZUZyZWRPdXRwdXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkSFRNTExpbmVzID0gJyc7CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtNb2R1bGVSZWZ9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBNb2R1bGVSZWYhJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBmb3IgbXkgJExpbmUgKCBAeyAkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9IH0gKSB7CiAgICAgICAgZm9yIG15ICRURCAoIEB7JExpbmV9ICkgewogICAgICAgICAgICAkVEQgPSAkU2VsZi0+e0xheW91dE9iamVjdH0tPkFzY2lpMkh0bWwoIFRleHQgPT4gJFREICk7CiAgICAgICAgfQogICAgICAgIGlmICggJExpbmUtPlsxXSBlcSAnVHJ1ZScgKSB7CiAgICAgICAgICAgICRMaW5lLT5bMV0gPSAnJzsKICAgICAgICB9CiAgICAgICAgJEhUTUxMaW5lcyAuPSAiICAgICAgICA8dHI+XG4iCiAgICAgICAgICAgIC4gIiAgICAgICAgICA8dGQgYWxpZ249XCJyaWdodFwiPiRMaW5lLT5bM108L3RkPlxuIgogICAgICAgICAgICAuICIgICAgICAgICAgPHRkPiRMaW5lLT5bMF08L3RkPlxuIgogICAgICAgICAgICAuICIgICAgICAgICAgPHRkPiRMaW5lLT5bMV08L3RkPlxuIgogICAgICAgICAgICAuICIgICAgICAgICAgPHRkPiRMaW5lLT5bMl08L3RkPlxuIgogICAgICAgICAgICAuICIgICAgICAgIDwvdHI+IjsKICAgIH0KCiAgICBpZiAoJEhUTUxMaW5lcykgewogICAgICAgICRQYXJhbXtNb2R1bGVSZWZ9LT57T3V0cHV0fSA9ICRTZWxmLT57TGF5b3V0T2JqZWN0fS0+T3V0cHV0KAogICAgICAgICAgICBUZW1wbGF0ZUZpbGUgPT4gJ0RldmVsRnJlZENvbmZpZ0xvZycsCiAgICAgICAgICAgIERhdGEgICAgICAgICA9PiB7CiAgICAgICAgICAgICAgICBIVE1MTGluZXMgPT4gJEhUTUxMaW5lcywKICAgICAgICAgICAgfSwKICAgICAgICApOwogICAgfQoKICAgIHJldHVybiAxOwp9CgoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBzb2Z0d2FyZSBpcyBwYXJ0IG9mIHRoZSBPVFJTIHByb2plY3QgKGh0dHA6Ly9vdHJzLm9yZy8pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQpkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgoKPWN1dAoKPWhlYWQxIFZFUlNJT04KCiRSZXZpc2lvbjogMS42ICQgJERhdGU6IDIwMDkvMDQvMDYgMTA6MjU6MTMgJAoKPWN1dAo=
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9MYXlvdXRGcmVkLnBtIC0gcHJvdmlkZXMgZ2VuZXJpYyBIVE1MIG91dHB1dCBmb3IgZnJlZAojIENvcHlyaWdodCAoQykgMjAwMS0yMDA5IE9UUlMgQUcsIGh0dHA6Ly9vdHJzLm9yZy8KIyAtLQojICRJZDogTGF5b3V0RnJlZC5wbSx2IDEuNSAyMDA5LzA0LzIxIDA5OjM1OjQ2IHRyIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6T3V0cHV0OjpIVE1MOjpMYXlvdXRGcmVkOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIHZhcnMgcXcoQElTQSAkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjUgJCkgWzFdOwoKPWl0ZW0gQ3JlYXRlRnJlZE91dHB1dCgpCgpjcmVhdGUgdGhlIG91dHB1dCBvZiB0aGUgc2V2ZXJhbCBmcmVkIG1vZHVsZXMKCiAgICAkTGF5b3V0T2JqZWN0LT5DcmVhdGVGcmVkT3V0cHV0KAogICAgICAgIEZyZWRNb2R1bGVzUmVmID0+ICRGcmVkTW9kdWxlc1JlZiwKICAgICk7Cgo9Y3V0CgpzdWIgQ3JlYXRlRnJlZE91dHB1dCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17RnJlZE1vZHVsZXNSZWZ9IHx8IHJlZiggJFBhcmFte0ZyZWRNb2R1bGVzUmVmfSApIG5lICdIQVNIJyApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgRnJlZE1vZHVsZXNSZWYhJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBmb3IgbXkgJE1vZHVsZU5hbWUgKCBrZXlzICV7ICRQYXJhbXtGcmVkTW9kdWxlc1JlZn0gfSApIHsKCiAgICAgICAgIyBsb2FkIGJhY2tlbmQKICAgICAgICBteSAkQmFja2VuZE9iamVjdCA9ICRTZWxmLT5fTG9hZExheW91dEJhY2tlbmQoIE1vZHVsZU5hbWUgPT4gJE1vZHVsZU5hbWUgKTsKCiAgICAgICAgIyBnZXQgbW9kdWxlIGRhdGEKICAgICAgICBpZiAoJEJhY2tlbmRPYmplY3QpIHsKICAgICAgICAgICAgJEJhY2tlbmRPYmplY3QtPkNyZWF0ZUZyZWRPdXRwdXQoIE1vZHVsZVJlZiA9PiAkUGFyYW17RnJlZE1vZHVsZXNSZWZ9LT57JE1vZHVsZU5hbWV9ICk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIF9Mb2FkTGF5b3V0QmFja2VuZCgpCgpsb2FkIGEgc3BlY2lhbCBmcmVkIGxheW91dCBiYWNrZW5kcwoKICAgICRCYWNrZW5kT2JqZWN0ID0gJExheW91dE9iamVjdC0+X0xvYWRMYXlvdXRCYWNrZW5kKAogICAgICAgIE1vZHVsZU5hbWUgPT4gJE1vZHVsZU5hbWUsCiAgICApOwoKPWN1dAoKc3ViIF9Mb2FkTGF5b3V0QmFja2VuZCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17TW9kdWxlTmFtZX0gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIE1vZHVsZU5hbWUhJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIGxvYWQgYmFja2VuZAogICAgbXkgJEdlbmVyaWNNb2R1bGUgPSAnS2VybmVsOjpPdXRwdXQ6OkhUTUw6OkZyZWQnIC4gJFBhcmFte01vZHVsZU5hbWV9OwogICAgaWYgKCAkU2VsZi0+e01haW5PYmplY3R9LT5SZXF1aXJlKCRHZW5lcmljTW9kdWxlKSApIHsKICAgICAgICBteSAkQmFja2VuZE9iamVjdCA9ICRHZW5lcmljTW9kdWxlLT5uZXcoCiAgICAgICAgICAgICV7JFNlbGZ9LAogICAgICAgICAgICAlUGFyYW0sCiAgICAgICAgICAgIExheW91dE9iamVjdCA9PiAkU2VsZiwKICAgICAgICApOwoKICAgICAgICByZXR1cm4gJEJhY2tlbmRPYmplY3QgaWYgJEJhY2tlbmRPYmplY3Q7CiAgICB9CiAgICByZXR1cm47Cn0KCjE7Cgo9aGVhZDEgVEVSTVMgQU5EIENPTkRJVElPTlMKClRoaXMgc29mdHdhcmUgaXMgcGFydCBvZiB0aGUgT1RSUyBwcm9qZWN0IChodHRwOi8vb3Rycy5vcmcvKS4KClRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCnRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KCj1jdXQKCj1oZWFkMSBWRVJTSU9OCgokUmV2aXNpb246IDEuNSAkICREYXRlOiAyMDA5LzA0LzIxIDA5OjM1OjQ2ICQKCj1jdXQK
IyAtLQojIEtlcm5lbC9PdXRwdXQvSFRNTC9PdXRwdXRGaWx0ZXJGcmVkLnBtCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBPdXRwdXRGaWx0ZXJGcmVkLnBtLHYgMS4xNyAyMDA5LzA0LzA2IDEwOjI1OjEzIG1oIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6T3V0cHV0OjpIVE1MOjpPdXRwdXRGaWx0ZXJGcmVkOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIEtlcm5lbDo6U3lzdGVtOjpGcmVkOwoKdXNlIHZhcnMgcXcoJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS4xNyAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpPdXRwdXQ6OkhUTUw6Ok91dHB1dEZpbHRlckZyZWQKCj1oZWFkMSBTWU5PUFNJUwoKYSBvdXRwdXQgZmlsdGVyIG1vZHVsZSBzcGVjaWFsbHkgZm9yIGRldmVsb3BlcgoKPWhlYWQxIFBVQkxJQyBJTlRFUkZBQ0UKCj1vdmVyIDQKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBnZXQgbmVlZGVkIG9iamVjdHMKICAgIGZvciBteSAkT2JqZWN0IChxdyhNYWluT2JqZWN0IENvbmZpZ09iamVjdCBMb2dPYmplY3QgKSkgewogICAgICAgICRTZWxmLT57JE9iamVjdH0gPSAkUGFyYW17JE9iamVjdH0gfHwgZGllICJHb3Qgbm8gJE9iamVjdCEiOwogICAgfQoKICAgICRTZWxmLT57RnJlZE9iamVjdH0gPSBLZXJuZWw6OlN5c3RlbTo6RnJlZC0+bmV3KCAleyRTZWxmfSApOwoKICAgIGlmICggJFBhcmFte0xheW91dE9iamVjdH0gKSB7CiAgICAgICAgJFNlbGYtPntMYXlvdXRPYmplY3R9ID0gJFBhcmFte0xheW91dE9iamVjdH07CiAgICB9CiAgICBlbHNlIHsKCiAgICAgICAgIyBpbnNlcnQgTGF5b3V0T2JqZWN0IGVudHJ5IGluIEZpbHRlckNvbnRlbnQgZnVuY3Rpb24gb2YgdGhlIExheW91dC5wbQogICAgICAgICMgdGhpcyBoYXBwZW5zIG9ubHkgaW4gT1RSUyAyLjIKICAgICAgICAkU2VsZi0+e0ZyZWRPYmplY3R9LT5JbnNlcnRMYXlvdXRPYmplY3QyMigpOwogICAgfQoKICAgIHJldHVybiAkU2VsZjsKfQoKc3ViIFJ1biB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgaXMgYSBjaGVjayBiZWNhdXNlIE9UUlMyLjIgZG9uJ3QgZGVsaXZlciBoZXJlIGEgTGF5b3V0T2JqZWN0CiAgICBpZiAoICEkU2VsZi0+e0xheW91dE9iamVjdH0gKSB7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgIyBwZXJoYXBzIG5vIG91dHB1dCBpcyBnZW5lcmF0ZWQKICAgIGlmICggISRQYXJhbXtEYXRhfSApIHsKICAgICAgICBkaWUgJ0ZyZWQ6IEF0IHRoZSBtb21lbnQsIHlvdXIgY29kZSBnZW5lcmF0ZXMgbm8gb3V0cHV0ISc7CiAgICB9CgogICAgIyBkbyBub3RoaW5nIGlmIG91dHB1dCBpcyBhIGF0dGFjaG1lbnQKICAgIGlmICgKICAgICAgICAkeyAkUGFyYW17RGF0YX0gfSA9fiAvXkNvbnRlbnQtRGlzcG9zaXRpb246IGF0dGFjaG1lbnQ7L21pCiAgICAgICAgfHwgJHsgJFBhcmFte0RhdGF9IH0gPX4gL15Db250ZW50LURpc3Bvc2l0aW9uOiBpbmxpbmU7L21pCiAgICAgICAgKQogICAgewogICAgICAgIHByaW50IFNUREVSUiAiQVRUQUNITUVOVCBET1dOTE9BRFxuIjsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICAjIGRvIG5vdGhpbmcgaWYgaXQgaXMgYSByZWRpcmVjdAogICAgaWYgKAogICAgICAgICR7ICRQYXJhbXtEYXRhfSB9ID1+IC9eU3RhdHVzOiAzMDIgTW92ZWQvbWkKICAgICAgICAmJiAkeyAkUGFyYW17RGF0YX0gfSA9fiAvXmxvY2F0aW9uOi9taQogICAgICAgICYmIGxlbmd0aCggJHsgJFBhcmFte0RhdGF9IH0gKSA8IDgwMAogICAgICAgICkKICAgIHsKICAgICAgICBwcmludCBTVERFUlIgIlJFRElSRUNUXG4iOwogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgICMgZG8gbm90aGluZyBpZiBpdCBpcyBmcmVkIGl0IHNlbGYKICAgIGlmICggJHsgJFBhcmFte0RhdGF9IH0gPX4gbXtGcmVkLVNldHRpbmc8XC90aXRsZT59bXN4ICkgewogICAgICAgIHByaW50IFNUREVSUiAiQ0hBTkdFIEZSRUQgU0VUVElOR1xuIjsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICAjIGdldCBkYXRhIG9mIHRoZSBhY3RpdmF0ZWQgbW9kdWxlcwogICAgbXkgJE1vZHVsZUZvclJlZiAgID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0ZyZWQ6Ok1vZHVsZScpOwogICAgbXkgJE1vZHVsZXNEYXRhUmVmID0ge307CiAgICBmb3IgbXkgJE1vZHVsZSAoIGtleXMgJXskTW9kdWxlRm9yUmVmfSApIHsKICAgICAgICBpZiAoICRNb2R1bGVGb3JSZWYtPnskTW9kdWxlfS0+e0FjdGl2ZX0gKSB7CiAgICAgICAgICAgICRNb2R1bGVzRGF0YVJlZi0+eyRNb2R1bGV9ID0ge307CiAgICAgICAgfQogICAgfQoKICAgICMgbG9hZCB0aGUgYWN0aXZhdGVkIG1vZHVsZXMKICAgICRTZWxmLT57RnJlZE9iamVjdH0tPkRhdGFHZXQoCiAgICAgICAgRnJlZE1vZHVsZXNSZWYgPT4gJE1vZHVsZXNEYXRhUmVmLAogICAgICAgIEhUTUxEYXRhUmVmICAgID0+ICRQYXJhbXtEYXRhfSwKICAgICk7CgogICAgIyBjcmVhdGUgZnJlZHMgb3V0cHV0CiAgICAkU2VsZi0+e0xheW91dE9iamVjdH0tPkNyZWF0ZUZyZWRPdXRwdXQoIEZyZWRNb2R1bGVzUmVmID0+ICRNb2R1bGVzRGF0YVJlZiApOwoKICAgICMgYnVpbGQgdGhlIGNvbnRlbnQgc3RyaW5nCiAgICBteSAkT3V0cHV0ID0gJyc7CiAgICBpZiAoICRNb2R1bGVzRGF0YVJlZi0+e0NvbnNvbGV9LT57T3V0cHV0fSApIHsKICAgICAgICAkT3V0cHV0IC49ICRNb2R1bGVzRGF0YVJlZi0+e0NvbnNvbGV9LT57T3V0cHV0fTsKICAgICAgICBkZWxldGUgJE1vZHVsZXNEYXRhUmVmLT57Q29uc29sZX07CiAgICB9CiAgICBmb3IgbXkgJE1vZHVsZSAoIGtleXMgJXskTW9kdWxlc0RhdGFSZWZ9ICkgewogICAgICAgICRPdXRwdXQgLj0gJE1vZHVsZXNEYXRhUmVmLT57JE1vZHVsZX0tPntPdXRwdXR9IHx8ICcnOwogICAgfQoKICAgICMgaW5jbHVkZSB0aGUgZnJlZCBvdXRwdXQgaW4gdGhlIG9yaWdpbmFsIG91dHB1dAogICAgaWYgKCAkeyAkUGFyYW17RGF0YX0gfSAhfiBzLyhcPGJvZHkofC4rPylcPikvJDFcbiRPdXRwdXRcblxuXG5cbi9teCApIHsKICAgICAgICAkeyAkUGFyYW17RGF0YX0gfSA9fiBzL14oLikvXG4kT3V0cHV0XG5cblxuXG4kMS9teDsKICAgIH0KCiAgICByZXR1cm4gMTsKfQoKMTsKCj1iYWNrCgo9aGVhZDEgVEVSTVMgQU5EIENPTkRJVElPTlMKClRoaXMgU29mdHdhcmUgaXMgcGFydCBvZiB0aGUgT1RSUyBwcm9qZWN0IChodHRwOi8vb3Rycy5vcmcvKS4KClRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCnRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEdQTCkuIElmIHlvdQpkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2dwbC0yLjAudHh0LgoKPWN1dAoKPWhlYWQxIFZFUlNJT04KCiRSZXZpc2lvbjogMS4xNyAkICREYXRlOiAyMDA5LzA0LzA2IDEwOjI1OjEzICQKCj1jdXQK
IyAtLQojIERldmVsRnJlZEJlbmNobWFyay5kdGwgLSBhIGZyb250ZW5kIHRvIHNob3cgdGhlIFNUREVSUiBsb2cKIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IERldmVsRnJlZEJlbmNobWFyay5kdGwsdiAxLjIgMjAwOS8wNC8wNiAxMDoyNToxMyBtaCBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQo8dGFibGUgYmdjb2xvcj0iIzAwMDAwMCIgY2VsbHNwYWNpbmc9IjMiIGNlbGxwYWRkaW5nPSIwIiB3aWR0aD0iMTAwJSI+CiAgPHRyPgogICAgPHRkIGJnY29sb3I9ImJhMGYwZiI+CiAgICAgIDx0YWJsZSBiZ2NvbG9yPSIjZmZmZmZmIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjIiIHdpZHRoPSIxMDAlIj4KICAgICAgICA8dHI+CiAgICAgICAgICA8dGQgYmdjb2xvcj0iYmEwZjBmIj4KICAgICAgICAgICAgPGI+PGZvbnQgY29sb3I9IiNmZmZmZmYiPkZyZWQtQmVuY2htYXJrPC9mb250PjwvYj4KICAgICAgICAgIDwvdGQ+CiAgICAgICAgPC90cj4KICAgICAgICA8dHI+CiAgICAgICAgICA8dGQ+CiAgICAgICAgICAgIDx0YWJsZT4KJERhdGF7IkhUTUxMaW5lcyJ9CiAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICA8L3RkPgogICAgICAgIDwvdHI+CiAgICAgIDwvdGFibGU+CiAgICA8L3RkPgogIDwvdHI+CjwvdGFibGU+CiMganVzdCBhIHNtYWxsIHNwYWNlCjx0YWJsZSBjZWxsc3BhY2luZz0iMSIgY2VsbHBhZGRpbmc9IjAiIHdpZHRoPSIxMDAlIj4KICA8dHI+PHRkPjwvdGQ+PC90cj4KPC90YWJsZT4=
IyAtLQojIERldmVsRnJlZENvbnNvbGUuZHRsIC0gYSBodG1sIGNvbnNvbGUgZm9yIGEgYmV0dGVyIGZyZWQgaGFuZGxpbmcKIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IERldmVsRnJlZENvbnNvbGUuZHRsLHYgMS4zIDIwMDkvMDQvMDYgMTA6MjU6MTMgbWggRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgLS0KPHRhYmxlIGJnY29sb3I9IiMwMDAwMDAiIGNlbGxzcGFjaW5nPSIzIiBjZWxscGFkZGluZz0iMCIgd2lkdGg9IjEwMCUiPgogIDx0cj4KICAgIDx0ZCBiZ2NvbG9yPSJiYTBmMGYiPgogICAgICA8dGFibGUgYmdjb2xvcj0iI2ZmZmZmZiIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIyIiB3aWR0aD0iMTAwJSI+CiAgICAgICAgPHRyPgogICAgICAgICAgPHRkIGNvbHNwYW49IjIiIGJnY29sb3I9ImJhMGYwZiI+CiAgICAgICAgICAgIDxiPjxmb250IGNvbG9yPSIjZmZmZmZmIj5GcmVkLUNvbnNvbGU8L2ZvbnQ+PC9iPgogICAgICAgICAgPC90ZD4KICAgICAgICA8L3RyPgogICAgICAgIDx0cj4KICAgICAgICAgIDx0ZD4KICAgICAgICAgICAgJERhdGF7IlRleHQifQogICAgICAgICAgPC90ZD4KICAgICAgICAgIDx0ZCBhbGlnbj0icmlnaHQiPgo8IS0tIGR0bDpibG9jazpTZXR0aW5nIC0tPgogICAgICAgICAgICA8YSBocmVmPSIkRW52eyJCYXNlbGluayJ9QWN0aW9uPURldmVsRnJlZCZTdWJhY3Rpb249U2V0dGluZyIgb25tb3VzZW92ZXI9IndpbmRvdy5zdGF0dXM9J1NldHRpbmcnOyByZXR1cm4gdHJ1ZTsiIG9ubW91c2VvdXQ9IndpbmRvdy5zdGF0dXM9Jyc7IiBvbkNsaWNrPSJ3aW5kb3cub3BlbignJywgJ3NldHRpbmcnLCAndG9vbGJhcj1ubyxsb2NhdGlvbj1ubyxzdGF0dXM9eWVzLHNjcm9sbGJhcnM9eWVzLHJlc2l6YWJsZT15ZXMsd2lkdGg9NTAwLGhlaWdodD00NDAsbGVmdD0zMDAsdG9wPTI1MCcpOyIgdGFyZ2V0PSJzZXR0aW5nIj5zZXR0aW5nPC9hPgo8IS0tIGR0bDpibG9jazpTZXR0aW5nIC0tPgogICAgICAgICAgICAmbmJzcDsKICAgICAgICAgIDwvdGQ+CiAgICAgICAgPC90cj4KICAgICAgPC90YWJsZT4KICAgIDwvdGQ+CiAgPC90cj4KPC90YWJsZT4KIyBqdXN0IGEgc21hbGwgc3BhY2UKPHRhYmxlIGNlbGxzcGFjaW5nPSIxIiBjZWxscGFkZGluZz0iMCIgd2lkdGg9IjEwMCUiPgogIDx0cj48dGQ+PC90ZD48L3RyPgo8L3RhYmxlPg==
IyAtLQojIERldmVsRnJlZEhUTUxDaGVjay5kdGwgLSBhIGZyb250ZW5kIHRvIHNob3cgdGhlIEhUTUwtQ2hlY2sgcmVzdWx0cwojIENvcHlyaWdodCAoQykgMjAwMS0yMDA5IE9UUlMgQUcsIGh0dHA6Ly9vdHJzLm9yZy8KIyAtLQojICRJZDogRGV2ZWxGcmVkSFRNTENoZWNrLmR0bCx2IDEuMyAyMDA5LzA0LzA2IDEwOjI1OjEzIG1oIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCjx0YWJsZSBiZ2NvbG9yPSIjMDAwMDAwIiBjZWxsc3BhY2luZz0iMyIgY2VsbHBhZGRpbmc9IjAiIHdpZHRoPSIxMDAlIj4KICA8dHI+CiAgICA8dGQgYmdjb2xvcj0iYmEwZjBmIj4KICAgICAgPHRhYmxlIGJnY29sb3I9IiNmZmZmZmYiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMiIgd2lkdGg9IjEwMCUiPgogICAgICAgIDx0cj4KICAgICAgICAgIDx0ZCBiZ2NvbG9yPSJiYTBmMGYiPgogICAgICAgICAgICA8Yj48Zm9udCBjb2xvcj0iI2ZmZmZmZiI+RnJlZC1IVE1MQ2hlY2s8L2ZvbnQ+PC9iPgogICAgICAgICAgPC90ZD4KICAgICAgICA8L3RyPgokRGF0YXsiSFRNTExpbmVzIn0KICAgICAgPC90YWJsZT4KICAgIDwvdGQ+CiAgPC90cj4KPC90YWJsZT4KIyBqdXN0IGEgc21hbGwgc3BhY2UKPHRhYmxlIGNlbGxzcGFjaW5nPSIxIiBjZWxscGFkZGluZz0iMCIgd2lkdGg9IjEwMCUiPgogIDx0cj48dGQ+PC90ZD48L3RyPgo8L3RhYmxlPg==
IyAtLQojIERldmVsRnJlZFNUREVSUkxvZy5kdGwgLSBhIGZyb250ZW5kIHRvIHNob3cgdGhlIFNUREVSUiBsb2cKIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IERldmVsRnJlZFNUREVSUkxvZy5kdGwsdiAxLjQgMjAwOS8wNC8wNiAxMDoyNToxMyBtaCBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQo8dGFibGUgYmdjb2xvcj0iIzAwMDAwMCIgY2VsbHNwYWNpbmc9IjMiIGNlbGxwYWRkaW5nPSIwIiB3aWR0aD0iMTAwJSI+CiAgPHRyPgogICAgPHRkIGJnY29sb3I9ImJhMGYwZiI+CiAgICAgIDx0YWJsZSBiZ2NvbG9yPSIjZmZmZmZmIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjIiIHdpZHRoPSIxMDAlIj4KICAgICAgICA8dHI+CiAgICAgICAgICA8dGQgYmdjb2xvcj0iYmEwZjBmIj4KICAgICAgICAgICAgPGI+PGZvbnQgY29sb3I9IiNmZmZmZmYiPkZyZWQtU1RERVJSTG9nPC9mb250PjwvYj4KICAgICAgICAgIDwvdGQ+CiAgICAgICAgPC90cj4KJERhdGF7IkhUTUxMaW5lcyJ9CiAgICAgIDwvdGFibGU+CiAgICA8L3RkPgogIDwvdHI+CjwvdGFibGU+CiMganVzdCBhIHNtYWxsIHNwYWNlCjx0YWJsZSBjZWxsc3BhY2luZz0iMSIgY2VsbHBhZGRpbmc9IjAiIHdpZHRoPSIxMDAlIj4KICA8dHI+PHRkPjwvdGQ+PC90cj4KPC90YWJsZT4K
IyAtLQojIERldmVsRnJlZFNldHRpbmcuZHRsIC0gYSBmcm9udGVuZCBmb3IgYSBmYXN0IGZyZWQgc2V0dGluZyBoYW5kbGluZwojIENvcHlyaWdodCAoQykgMjAwMS0yMDA5IE9UUlMgQUcsIGh0dHA6Ly9vdHJzLm9yZy8KIyAtLQojICRJZDogRGV2ZWxGcmVkU2V0dGluZy5kdGwsdiAxLjggMjAwOS8wNC8wNiAxMDoyNToxMyBtaCBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQo8dGFibGUgYmdjb2xvcj0iIzAwMDAwMCIgY2VsbHNwYWNpbmc9IjMiIGNlbGxwYWRkaW5nPSIwIiB3aWR0aD0iMTAwJSI+CiAgPHRyPgogICAgPHRkIGJnY29sb3I9ImJhMGYwZiI+CiAgICAgIDxmb3JtIGFjdGlvbj0iJEVudnsiQ0dJSGFuZGxlIn0iIG1ldGhvZD0icG9zdCIgZW5jdHlwZT0ibXVsdGlwYXJ0L2Zvcm0tZGF0YSIgbmFtZT0iRGV2ZWxGcmVkU2V0dGluZyI+CiAgICAgICAgPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0iQWN0aW9uIiB2YWx1ZT0iRGV2ZWxGcmVkIj4KICAgICAgICA8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJTdWJhY3Rpb24iIHZhbHVlPSJTZXR0aW5nQWN0aW9uIj4KICAgICAgICA8dGFibGUgYmdjb2xvcj0iI2ZmZmZmZiIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIyIiB3aWR0aD0iMTAwJSI+CiAgICAgICAgICA8dHI+CiAgICAgICAgICAgIDx0ZCBiZ2NvbG9yPSJiYTBmMGYiPgogICAgICAgICAgICAgIDxiPjxmb250IGNvbG9yPSIjZmZmZmZmIj5GcmVkLVNldHRpbmc8L2ZvbnQ+PC9iPgogICAgICAgICAgICA8L3RkPgogICAgICAgICAgPC90cj4KPCEtLSBkdGw6YmxvY2s6RnJlZE1vZHVsZSAtLT4KICAgICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkPgogICAgICAgICAgICAgIDxpbnB1dCB0eXBlPSJjaGVja2JveCIgbmFtZT0iRnJlZE1vZHVsZSIgdmFsdWU9IiRRRGF0YXsiRnJlZE1vZHVsZSJ9IiAkRGF0YXsiQ2hlY2tlZCJ9PgogICAgICAgICAgICAgICRRRGF0YXsiRnJlZE1vZHVsZSJ9CjwhLS0gZHRsOmJsb2NrOkNvbmZpZyAtLT4KICAgICAgICAgICAgICA8YSBocmVmPSIkRW52eyJCYXNlbGluayJ9QWN0aW9uPUFkbWluU3lzQ29uZmlnJlN1YmFjdGlvbj1FZGl0JlN5c0NvbmZpZ1N1Ykdyb3VwPSREYXRheyJNb2R1bGVOYW1lIn0mU3lzQ29uZmlnR3JvdXA9RnJlZCIgIG9ubW91c2VvdmVyPSJ3aW5kb3cuc3RhdHVzPSdTZXR0aW5nJzsgcmV0dXJuIHRydWU7IiBvbm1vdXNlb3V0PSJ3aW5kb3cuc3RhdHVzPScnOyIgb25DbGljaz0id2luZG93LnJlc2l6ZVRvKDkwMCw1MDApIj4oJFRleHR7IkNvbmZpZyJ9KTwvYT4KPCEtLSBkdGw6YmxvY2s6Q29uZmlnIC0tPgogICAgICAgICAgICA8L3RkPgogICAgICAgICAgPC90cj4KPCEtLSBkdGw6YmxvY2s6RnJlZE1vZHVsZSAtLT4KICAgICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkPgogICAgICAgICAgICAgIDxicj4KICAgICAgICAgICAgICAkVGV4dHsiQXR0ZW50aW9uOiBZb3UgY2FuJ3QgdXNlIFNtYWxsUHJvZiBhbmQgRFByb2YgYXQgdGhlIHNhbWUgdGltZSEifQogICAgICAgICAgICA8L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICAgIDx0cj4KICAgICAgICAgICAgPHRkIGFsaWduPSJyaWdodCI+CiAgICAgICAgICAgICAgPGlucHV0IHR5cGU9InN1Ym1pdCIgdmFsdWU9IiRUZXh0eyJTYXZlIn0iIGNsYXNzPSJidXR0b24iPgogICAgICAgICAgICA8L3RkPgogICAgICAgICAgPC90cj4KICAgICAgICA8L3RhYmxlPgogICAgICA8L2Zvcm0+CiAgICA8L3RkPgogIDwvdHI+CjwvdGFibGU+Cg==
IyAtLQojIERldmVsRnJlZFNtYWxsUHJvZi5kdGwgLSBhIGZyb250ZW5kIHRvIHNob3cgdGhlIFNtYWxsUHJvZiByZXN1bHQgdGFibGUKIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IERldmVsRnJlZFNtYWxsUHJvZi5kdGwsdiAxLjUgMjAwOS8wNC8wNiAxMDoyNToxMyBtaCBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQo8dGFibGUgYmdjb2xvcj0iIzAwMDAwMCIgY2VsbHNwYWNpbmc9IjMiIGNlbGxwYWRkaW5nPSIwIiB3aWR0aD0iMTAwJSI+CiAgPHRyPgogICAgPHRkIGJnY29sb3I9ImJhMGYwZiI+CiAgICAgIDx0YWJsZSBiZ2NvbG9yPSIjZmZmZmZmIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjIiIHdpZHRoPSIxMDAlIj4KICAgICAgICA8dHI+CiAgICAgICAgICA8dGQgY29sc3Bhbj0iNiIgYmdjb2xvcj0iYmEwZjBmIj4KICAgICAgICAgICAgPGI+PGZvbnQgY29sb3I9IiNmZmZmZmYiPkZyZWQtU21hbGxQcm9mPC9mb250PjwvYj4KICAgICAgICAgIDwvdGQ+CiAgICAgICAgPC90cj4KICAgICAgICA8dHI+CiAgICAgICAgICA8dGQgY29sc3Bhbj0iNiI+CiAgICAgICAgICAgICRUZXh0eyJQcm9maWxlZCBwYWNrYWdlczoifSAkUURhdGF7IlBhY2thZ2VzIn0KICAgICAgICAgIDwvdGQ+CiAgICAgICAgPC90cj4KICAgICAgICA8dHI+CiAgICAgICAgICA8dGQ+CiAgICAgICAgICAgICRUZXh0eyJDYWxscyJ9CiAgICAgICAgICA8L3RkPgogICAgICAgICAgPHRkPgogICAgICAgICAgICAkVGV4dHsiVGltZSBleGVjdXRpbmcgKG1zKSJ9CiAgICAgICAgICA8L3RkPgogICAgICAgICAgPHRkPgogICAgICAgICAgICAkVGV4dHsiVGltZSBleHBlbmRlZCAobXMpIn0KICAgICAgICAgIDwvdGQ+CiAgICAgICAgICA8dGQ+CiAgICAgICAgICAgICRUZXh0eyJGaWxlIn0KICAgICAgICAgIDwvdGQ+CiAgICAgICAgICA8dGQ+CiAgICAgICAgICAgICRUZXh0eyJMaW5lIn0KICAgICAgICAgIDwvdGQ+CiAgICAgICAgICA8dGQ+CiAgICAgICAgICAgICRUZXh0eyJUZXh0In0KICAgICAgICAgIDwvdGQ+CiAgICAgICAgPC90cj4KJERhdGF7IkhUTUxMaW5lcyJ9CiAgICAgICAgPHRyPgogICAgICAgICAgPHRkIGFsaWduPSJyaWdodCI+JERhdGF7IlRvdGFsQ2FsbCJ9PC90ZD4KICAgICAgICAgIDx0ZCBjb2xzcGFuPSI1Ij4gQ2FsbHM8L3RkPgogICAgICAgIDwvdHI+CiAgICAgICAgPHRyPgogICAgICAgICAgPHRkIGNvbHNwYW49IjYiPgogICAgICAgICAgICAkVGV4dHsiRm9yIG1vcmUgaW5mb3JtYXRpb24sIGVzcGVjaWFsbHkgJ3RpbWUgZXhlY3V0aW9uJyBhbmQgJ3RpbWUgZXhwZW5kZWQnIHJlYWQgcGVybGRvYyBTbWFsbFByb2YhIn0KICAgICAgICAgIDwvdGQ+CiAgICAgICAgPC90cj4KICAgICAgICA8dHI+CiAgICAgICAgICA8dGQgY29sc3Bhbj0iNiI+CiAgICAgICAgICAgICRUZXh0eyJJZiB5b3UgY2hhbmdlIHRoZSBwYWNrYWdlIGNvbmZpZyB5b3UgaGF2ZSB0byByZWxvYWQgdGhpcyBzaWRlIHR3byB0aW1lcyEifQogICAgICAgICAgPC90ZD4KICAgICAgICA8L3RyPgogICAgICA8L3RhYmxlPgogICAgPC90ZD4KICA8L3RyPgo8L3RhYmxlPgojIGp1c3QgYSBzbWFsbCBzcGFjZQo8dGFibGUgY2VsbHNwYWNpbmc9IjEiIGNlbGxwYWRkaW5nPSIwIiB3aWR0aD0iMTAwJSI+CiAgPHRyPjx0ZD48L3RkPjwvdHI+CjwvdGFibGU+
IyAtLQojIERldmVsRnJlZERQcm9mLmR0bCAtIGEgZnJvbnRlbmQgdG8gc2hvdyB0aGUgRFByb2YgcmVzdWx0IHRhYmxlCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBEZXZlbEZyZWREUHJvZi5kdGwsdiAxLjQgMjAwOS8wNC8wNiAxMDoyNToxMyBtaCBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQo8dGFibGUgYmdjb2xvcj0iIzAwMDAwMCIgY2VsbHNwYWNpbmc9IjMiIGNlbGxwYWRkaW5nPSIwIiB3aWR0aD0iMTAwJSI+CiAgPHRyPgogICAgPHRkIGJnY29sb3I9ImJhMGYwZiI+CiAgICAgIDx0YWJsZSBiZ2NvbG9yPSIjZmZmZmZmIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjIiIHdpZHRoPSIxMDAlIj4KICAgICAgICA8dHI+CiAgICAgICAgICA8dGQgY29sc3Bhbj0iNyIgYmdjb2xvcj0iYmEwZjBmIj4KICAgICAgICAgICAgPGI+PGZvbnQgY29sb3I9IiNmZmZmZmYiPkZyZWQtRFByb2Y8L2ZvbnQ+PC9iPgogICAgICAgICAgPC90ZD4KICAgICAgICA8L3RyPgo8IS0tIGR0bDpibG9jazpUaW1lVGFibGUgLS0+CiAgICAgICAgPHRyPgogICAgICAgICAgPHRkIGFsaWduPSJyaWdodCI+JVRpbWU8L3RkPgogICAgICAgICAgPHRkIGFsaWduPSJyaWdodCI+RXhjbFNlYzwvdGQ+CiAgICAgICAgICA8dGQgYWxpZ249InJpZ2h0Ij5DdW11bFM8L3RkPgogICAgICAgICAgPHRkIGFsaWduPSJyaWdodCI+I0NhbGxzPC90ZD4KICAgICAgICAgIDx0ZCBhbGlnbj0icmlnaHQiPnNlYy9jYWxsPC90ZD4KICAgICAgICAgIDx0ZCBhbGlnbj0icmlnaHQiPkNzZWMvYzo8L3RkPgogICAgICAgICAgPHRkPk5hbWU8L3RkPgogICAgICAgIDwvdHI+CiREYXRheyJIVE1MTGluZXMifQogICAgICAgIDx0cj4KICAgICAgICAgIDx0ZCBhbGlnbj0icmlnaHQiPlRvdGFsOjwvdGQ+CiAgICAgICAgICA8dGQgYWxpZ249InJpZ2h0Ij4kRGF0YXsiVG90YWxUaW1lIn08L3RkPgogICAgICAgICAgPHRkPlNlY29uZHM8L3RkPgogICAgICAgICAgPHRkIGFsaWduPSJyaWdodCI+JERhdGF7IlRvdGFsQ2FsbCJ9PC90ZD4KICAgICAgICAgIDx0ZCBjb2xzcGFuPSIzIj4gQ2FsbHM8L3RkPgogICAgICAgIDwvdHI+CjwhLS0gZHRsOmJsb2NrOlRpbWVUYWJsZSAtLT4KPCEtLSBkdGw6YmxvY2s6RnVuY3Rpb25MaXN0IC0tPgogICAgICAgIDx0cj4KICAgICAgICAgIDx0ZCBhbGlnbj0icmlnaHQiPk51bWJlcjwvdGQ+CiAgICAgICAgICA8dGQ+TmFtZTwvdGQ+CiAgICAgICAgPC90cj4KJERhdGF7IkhUTUxMaW5lcyJ9CjwhLS0gZHRsOmJsb2NrOkZ1bmN0aW9uTGlzdCAtLT4KICAgICAgPC90YWJsZT4KICAgIDwvdGQ+CiAgPC90cj4KPC90YWJsZT4KIyBqdXN0IGEgc21hbGwgc3BhY2UKPHRhYmxlIGNlbGxzcGFjaW5nPSIxIiBjZWxscGFkZGluZz0iMCIgd2lkdGg9IjEwMCUiPgogIDx0cj48dGQ+PC90ZD48L3RyPgo8L3RhYmxlPgo=
IyAtLQojIERldmVsRnJlZFRyYW5zbGF0aW9uRGVidWcuZHRsIC0gYSBmcm9udGVuZCB0byBzaG93IHRoZSB0cmFuc2xhdGlvbiBkZWJ1Z2dpbmcKIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IERldmVsRnJlZFRyYW5zbGF0aW9uRGVidWcuZHRsLHYgMS4zIDIwMDkvMDQvMDYgMTA6MjU6MTMgbWggRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgLS0KPHRhYmxlIGJnY29sb3I9IiMwMDAwMDAiIGNlbGxzcGFjaW5nPSIzIiBjZWxscGFkZGluZz0iMCIgd2lkdGg9IjEwMCUiPgogIDx0cj4KICAgIDx0ZCBiZ2NvbG9yPSJiYTBmMGYiPgogICAgICA8dGFibGUgYmdjb2xvcj0iI2ZmZmZmZiIgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIyIiB3aWR0aD0iMTAwJSI+CiAgICAgICAgPHRyPgogICAgICAgICAgPHRkIGJnY29sb3I9ImJhMGYwZiI+CiAgICAgICAgICAgIDxiPjxmb250IGNvbG9yPSIjZmZmZmZmIj5GcmVkLVRyYW5zbGF0aW9uRGVidWc8L2ZvbnQ+PC9iPgogICAgICAgICAgPC90ZD4KICAgICAgICA8L3RyPgokRGF0YXsiSFRNTExpbmVzIn0KICAgICAgPC90YWJsZT4KICAgIDwvdGQ+CiAgPC90cj4KPC90YWJsZT4KIyBqdXN0IGEgc21hbGwgc3BhY2UKPHRhYmxlIGNlbGxzcGFjaW5nPSIxIiBjZWxscGFkZGluZz0iMCIgd2lkdGg9IjEwMCUiPgogIDx0cj48dGQ+PC90ZD48L3RyPgo8L3RhYmxlPg==
IyAtLQojIERldmVsRnJlZFNRTExvZy5kdGwgLSBhIGZyb250ZW5kIHRvIHNob3cgdGhlIHNxbCBsb2cKIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IERldmVsRnJlZFNRTExvZy5kdGwsdiAxLjUgMjAwOS8wNC8wNiAxMDoyNToxMyBtaCBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQo8dGFibGUgYmdjb2xvcj0iIzAwMDAwMCIgY2VsbHNwYWNpbmc9IjMiIGNlbGxwYWRkaW5nPSIwIiB3aWR0aD0iMTAwJSI+CiAgPHRyPgogICAgPHRkIGJnY29sb3I9ImJhMGYwZiI+CiAgICAgIDx0YWJsZSBiZ2NvbG9yPSIjZmZmZmZmIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjIiPgogICAgICAgIDx0cj4KICAgICAgICAgIDx0ZCBjb2xzcGFuPSI1IiBiZ2NvbG9yPSJiYTBmMGYiPgogICAgICAgICAgICA8Yj48Zm9udCBjb2xvcj0iI2ZmZmZmZiI+RnJlZC1TUUwtTG9nPC9mb250PjwvYj4KICAgICAgICAgIDwvdGQ+CiAgICAgICAgPC90cj4KICAgICAgICA8dHIgY2xhc3M9ImNvbnRlbnRrZXkiPgogICAgICAgICAgPHRkPktpbmQ8L3RkPgogICAgICAgICAgPHRkPlN0YXRlbWVudDwvdGQ+CiAgICAgICAgICA8dGQ+UGFja2FnZTwvdGQ+CiAgICAgICAgICA8dGQ+VGltZSAxLzEwMCBzZWM8L3RkPgogICAgICAgICAgPHRkPkVxdWFsIFN0YXRlbWVudHM8L3RkPgogICAgICAgIDwvdHI+CiREYXRheyJIVE1MTGluZXMifQogICAgICAgIDx0ciBjbGFzcz0iY29udGVudGtleSI+CiAgICAgICAgICA8dGQgY29sc3Bhbj0iMyI+JERhdGF7IkFsbFN0YXRlbWVudHMifSBBbGxTdGF0bWVudHMgPSAkRGF0YXsiU2VsZWN0U3RhdGVtZW50cyJ9IFNFTEVDVFMgKyAkRGF0YXsiRG9TdGF0ZW1lbnRzIn0gRE9zPC90ZD4KICAgICAgICAgIDx0ZD4kRGF0YXsiVGltZSJ9PC90ZD4KICAgICAgICAgIDx0ZD5zZWM8L3RkPgogICAgICAgIDwvdHI+CiAgICAgIDwvdGFibGU+CiAgICA8L3RkPgogIDwvdHI+CjwvdGFibGU+CiMganVzdCBhIHNtYWxsIHNwYWNlCjx0YWJsZSBjZWxsc3BhY2luZz0iMSIgY2VsbHBhZGRpbmc9IjAiIHdpZHRoPSIxMDAlIj4KICA8dHI+PHRkPjwvdGQ+PC90cj4KPC90YWJsZT4=
IyAtLQojIERldmVsRnJlZENvbmZpZ0xvZy5kdGwgLSBhIGZyb250ZW5kIHRvIHNob3cgdGhlIGNvbmZpZyBkZWJ1Z2dpbmcKIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IERldmVsRnJlZENvbmZpZ0xvZy5kdGwsdiAxLjUgMjAwOS8wNC8wNiAxMDoyNToxMyBtaCBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQo8dGFibGUgYmdjb2xvcj0iIzAwMDAwMCIgY2VsbHNwYWNpbmc9IjMiIGNlbGxwYWRkaW5nPSIwIiB3aWR0aD0iMTAwJSI+CiAgPHRyPgogICAgPHRkIGJnY29sb3I9ImJhMGYwZiI+CiAgICAgIDx0YWJsZSBiZ2NvbG9yPSIjZmZmZmZmIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjIiIHdpZHRoPSIxMDAlIj4KICAgICAgICA8dHI+CiAgICAgICAgICA8dGQgYmdjb2xvcj0iYmEwZjBmIj4KICAgICAgICAgICAgPGI+PGZvbnQgY29sb3I9IiNmZmZmZmYiPkZyZWQtQ29uZmlnLUxvZzwvZm9udD48L2I+CiAgICAgICAgICA8L3RkPgogICAgICAgIDwvdHI+CiAgICAgICAgPHRyPgogICAgICAgICAgPHRkPgoKICAgICAgICAgICAgPHRhYmxlIGJnY29sb3I9IiNmZmZmZmYiIGNlbGxzcGFjaW5nPSIwIiBjZWxscGFkZGluZz0iMiI+CiAgICAgICAgICAgICAgPHRyIGNsYXNzPSJjb250ZW50a2V5Ij4KICAgICAgICAgICAgICAgIDx0ZCBhbGlnbj0icmlnaHQiPkNhbGxzPC90ZD4KICAgICAgICAgICAgICAgIDx0ZD5Db25maWc8L3RkPgogICAgICAgICAgICAgICAgPHRkPlN0YXR1czwvdGQ+CiAgICAgICAgICAgICAgICA8dGQ+UGFja2FnZTwvdGQ+CiAgICAgICAgICAgICAgPC90cj4KJERhdGF7IkhUTUxMaW5lcyJ9CiAgICAgICAgICAgIDwvdGFibGU+CiAgICAgICAgICA8L3RkPgogICAgICAgIDwvdHI+CiAgICAgIDwvdGFibGU+CiAgICA8L3RkPgogIDwvdHI+CjwvdGFibGU+CiMganVzdCBhIHNtYWxsIHNwYWNlCjx0YWJsZSBjZWxsc3BhY2luZz0iMSIgY2VsbHBhZGRpbmc9IjAiIHdpZHRoPSIxMDAlIj4KICA8dHI+PHRkPjwvdGQ+PC90cj4KPC90YWJsZT4K
IyAtLQojIEtlcm5lbC9TeXN0ZW0vRnJlZC5wbSAtIGFsbCBmcmVkIGNvcmUgZnVuY3Rpb25zCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBGcmVkLnBtLHYgMS4xMCAyMDA5LzA0LzIxIDEwOjEzOjEwIHRyIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpGcmVkOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIHZhcnMgcXcoQElTQSAkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjEwICQpIFsxXTsKCj1oZWFkMSBOQU1FCgpLZXJuZWw6OlN5c3RlbTo6RnJlZCAtIGZyZWQgY29yZSBsaWIKCj1oZWFkMSBTWU5PUFNJUwoKQWxsIGZyZWQgc3RhbmRhcmQgY29yZSBmdW5jdGlvbnMuCgo9aGVhZDEgUFVCTElDIElOVEVSRkFDRQoKPW92ZXIgNAoKPWN1dAoKPWl0ZW0gbmV3KCkKCmNyZWF0ZSBhbiBvYmplY3QKCiAgICB1c2UgS2VybmVsOjpDb25maWc7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkxvZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6TWFpbjsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6RnJlZDsKCiAgICBteSAkQ29uZmlnT2JqZWN0ID0gS2VybmVsOjpDb25maWctPm5ldygpOwogICAgbXkgJExvZ09iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpMb2ctPm5ldygKICAgICAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgICk7CiAgICBteSAkTWFpbk9iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpNYWluLT5uZXcoCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICApOwogICAgbXkgJEZyZWRPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6RnJlZC0+bmV3KAogICAgICAgIExvZ09iamVjdCAgICA9PiAkTG9nT2JqZWN0LAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIE1haW5PYmplY3QgICA9PiAkTWFpbk9iamVjdCwKICAgICk7Cgo9Y3V0CgpzdWIgbmV3IHsKICAgIG15ICggJFR5cGUsICVQYXJhbSApID0gQF87CgogICAgIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CiAgICBteSAkU2VsZiA9IHt9OwogICAgYmxlc3MoICRTZWxmLCAkVHlwZSApOwoKICAgICMgY2hlY2sgbmVlZGVkIG9iamVjdHMKICAgIGZvciBteSAkT2JqZWN0IChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0IE1haW5PYmplY3QpKSB7CiAgICAgICAgJFNlbGYtPnskT2JqZWN0fSA9ICRQYXJhbXskT2JqZWN0fSB8fCBkaWUgIkdvdCBubyAkT2JqZWN0ISI7CiAgICB9CgogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBEYXRhR2V0KCkKCkV2YWx1YXRlIHRoZSBzZXZlcmFsIGRhdGEgb2YgYWxsIGZyZWQgbW9kdWxlcyBhbmQgYWRkIHRoZW0Kb24gdGhlIEZyZWRNb2R1bGVzIHJlZmVyZW5jZS4KCiAgICAkRnJlZE9iamVjdC0+RGF0YUdldCgKICAgICAgICBGcmVkTW9kdWxlc1JlZiA9PiAkRnJlZE1vZHVsZXNSZWYsCiAgICApOwoKPWN1dAoKc3ViIERhdGFHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte0ZyZWRNb2R1bGVzUmVmfSB8fCByZWYoICRQYXJhbXtGcmVkTW9kdWxlc1JlZn0gKSBuZSAnSEFTSCcgKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIEZyZWRNb2R1bGVzUmVmIScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAoICEkUGFyYW17SFRNTERhdGFSZWZ9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBIVE1MRGF0YVJlZiEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGZvciBteSAkTW9kdWxlTmFtZSAoIGtleXMgJXsgJFBhcmFte0ZyZWRNb2R1bGVzUmVmfSB9ICkgewoKICAgICAgICAjIGxvYWQgYmFja2VuZAogICAgICAgIG15ICRCYWNrZW5kT2JqZWN0ID0gJFNlbGYtPl9Mb2FkQmFja2VuZCggTW9kdWxlTmFtZSA9PiAkTW9kdWxlTmFtZSApOwoKICAgICAgICAjIGdldCBtb2R1bGUgZGF0YQogICAgICAgIGlmICgkQmFja2VuZE9iamVjdCkgewogICAgICAgICAgICAkQmFja2VuZE9iamVjdC0+RGF0YUdldCgKICAgICAgICAgICAgICAgIE1vZHVsZVJlZiAgICAgID0+ICRQYXJhbXtGcmVkTW9kdWxlc1JlZn0tPnskTW9kdWxlTmFtZX0sCiAgICAgICAgICAgICAgICBIVE1MRGF0YVJlZiAgICA9PiAkUGFyYW17SFRNTERhdGFSZWZ9LAogICAgICAgICAgICAgICAgRnJlZE1vZHVsZXNSZWYgPT4gJFBhcmFte0ZyZWRNb2R1bGVzUmVmfSwKICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIEFjdGl2YXRlTW9kdWxlVG9kb3MoKQoKRG8gYWxsIGpvYnMgd2hpY2ggYXJlIG5lY2Vzc2FyeSB0byBhY3RpdmF0ZSBhIGZyZWQgbW9kdWxlLgoKICAgICRGcmVkT2JqZWN0LT5BY3RpdmF0ZU1vZHVsZVRvZG9zKAogICAgICAgIE1vZHVsZU5hbWUgPT4gJE1vZHVsZU5hbWUsCiAgICApOwoKPWN1dAoKc3ViIEFjdGl2YXRlTW9kdWxlVG9kb3MgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgaWYgKCAhJFBhcmFte01vZHVsZU5hbWV9ICkgewogICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgICAgICBNZXNzYWdlICA9PiAnTmVlZCBNb2R1bGVOYW1lIScsCiAgICAgICAgKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBsb2FkIGJhY2tlbmQKICAgIG15ICRCYWNrZW5kT2JqZWN0ID0gJFNlbGYtPl9Mb2FkQmFja2VuZCggTW9kdWxlTmFtZSA9PiAkUGFyYW17TW9kdWxlTmFtZX0gKTsKCiAgICAjIGdldCBtb2R1bGUgZGF0YQogICAgaWYgKCRCYWNrZW5kT2JqZWN0KSB7CgogICAgICAgICMgRklYTUUgRXJyb3JoYW5kbGluZwogICAgICAgICRCYWNrZW5kT2JqZWN0LT5BY3RpdmF0ZU1vZHVsZVRvZG9zKCk7CgogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgIHJldHVybjsKfQoKPWl0ZW0gRGVhY3RpdmF0ZU1vZHVsZVRvZG9zKCkKCkRvIGFsbCBqb2JzIHdoaWNoIGFyZSBuZWNlc3NhcnkgdG8gZGVhY3RpdmF0ZSBhIGZyZWQgbW9kdWxlLgoKICAgICRGcmVkT2JqZWN0LT5EZWFjdGl2YXRlTW9kdWxlVG9kb3MoCiAgICAgICAgTW9kdWxlTmFtZSA9PiAkTW9kdWxlTmFtZSwKICAgICk7Cgo9Y3V0CgpzdWIgRGVhY3RpdmF0ZU1vZHVsZVRvZG9zIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtNb2R1bGVOYW1lfSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgTW9kdWxlTmFtZSEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgbG9hZCBiYWNrZW5kCiAgICBteSAkQmFja2VuZE9iamVjdCA9ICRTZWxmLT5fTG9hZEJhY2tlbmQoIE1vZHVsZU5hbWUgPT4gJFBhcmFte01vZHVsZU5hbWV9ICk7CgogICAgIyBnZXQgbW9kdWxlIGRhdGEKICAgIGlmICgkQmFja2VuZE9iamVjdCkgewoKICAgICAgICAjIEZJWE1FIEVycm9yaGFuZGxpbmcKICAgICAgICAkQmFja2VuZE9iamVjdC0+RGVhY3RpdmF0ZU1vZHVsZVRvZG9zKCk7CgogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgIHJldHVybjsKfQoKPWl0ZW0gX0xvYWRCYWNrZW5kKCkKCmxvYWQgYSB4bWwgaXRlbSBtb2R1bGUKCiAgICAkQmFja2VuZE9iamVjdCA9ICRGcmVkT2JqZWN0LT5fTG9hZEJhY2tlbmQoCiAgICAgICAgTW9kdWxlTmFtZSA9PiAkTW9kdWxlTmFtZSwKICAgICk7Cgo9Y3V0CgpzdWIgX0xvYWRCYWNrZW5kIHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGlmICggISRQYXJhbXtNb2R1bGVOYW1lfSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgTW9kdWxlTmFtZSEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgbG9hZCBiYWNrZW5kCiAgICBteSAkR2VuZXJpY01vZHVsZSA9ICdLZXJuZWw6OlN5c3RlbTo6RnJlZDo6JyAuICRQYXJhbXtNb2R1bGVOYW1lfTsKICAgIGlmICggJFNlbGYtPntNYWluT2JqZWN0fS0+UmVxdWlyZSgkR2VuZXJpY01vZHVsZSkgKSB7CiAgICAgICAgbXkgJEJhY2tlbmRPYmplY3QgPSAkR2VuZXJpY01vZHVsZS0+bmV3KCAleyRTZWxmfSwgJVBhcmFtLCApOwoKICAgICAgICBpZiAoJEJhY2tlbmRPYmplY3QpIHsKCiAgICAgICAgICAgICMgcmV0dXJuIG9iamVjdAogICAgICAgICAgICByZXR1cm4gJEJhY2tlbmRPYmplY3Q7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybjsKfQoKPWl0ZW0gSW5zZXJ0TGF5b3V0T2JqZWN0MjIoKQoKRlJBTUVXT1JLLTIuMiBzcGVjaWZpYyBiZWNhdXNlIHRoZXJlIGlzIG5vIExheW91dE9iamVjdCBpbnRlZ3JhdGlvbiBmb3IKRlJFRCBpbiBPVFJTMi4yIExheW91dC5wbQoKICAgICRGcmVkT2JqZWN0LT5JbnNlcnRMYXlvdXRPYmplY3QyMigpOwoKPWN1dAoKc3ViIEluc2VydExheW91dE9iamVjdDIyIHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgbXkgQExpbmVzID0gKCk7CiAgICBteSAkRmlsZSAgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gJy9LZXJuZWwvT3V0cHV0L0hUTUwvTGF5b3V0LnBtJzsKCiAgICBkaWUgIkNhbid0IG1hbmlwdWxhdGUgJEZpbGUgYmVjYXVzZSBpdCBpcyBhIHN5bWxpbmshIiBpZiAtbCAkRmlsZTsKCiAgICAjIHJlYWQgZmlsZQogICAgbXkgJEluU3ViOwogICAgb3BlbiBteSAkRmlsZWhhbmRsZSwgJzwnLCAkRmlsZSB8fCBkaWUgIkNhbid0IG9wZW4gJEZpbGUgIVxuIjsKICAgIHdoaWxlICggbXkgJExpbmUgPSA8JEZpbGVoYW5kbGU+ICkgewogICAgICAgIHB1c2ggQExpbmVzLCAkTGluZTsKICAgICAgICBpZiAoICRMaW5lID1+IC9zdWIgUHJpbnQgey8gKSB7CiAgICAgICAgICAgICRJblN1YiA9IDE7CiAgICAgICAgfQogICAgICAgIGlmICggJEluU3ViICYmICRMaW5lID1+IC9EZWJ1ZyA9PiBcJFNlbGYtPntEZWJ1Z30sLyApIHsKICAgICAgICAgICAgcHVzaCBATGluZXMsICIjIEZSRUQgLSBtYW5pcHVsYXRlZFxuIjsKICAgICAgICAgICAgcHVzaCBATGluZXMsICIgICAgICAgICAgICAgICAgICAgIExheW91dE9iamVjdCA9PiBcJFNlbGYsXG4iOwogICAgICAgICAgICBwdXNoIEBMaW5lcywgIiMgRlJFRCAtIG1hbmlwdWxhdGVkXG4iOwogICAgICAgICAgICAkSW5TdWIgPSAwOwogICAgICAgIH0KICAgIH0KICAgIGNsb3NlICRGaWxlaGFuZGxlOwoKICAgICMgd3JpdGUgZmlsZQogICAgb3BlbiBteSAkRmlsZWhhbmRsZUlJLCAnPicsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgd3JpdGUgJEZpbGUgIVxuIjsKICAgIGZvciBteSAkTGluZSAoQExpbmVzKSB7CiAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAkTGluZTsKICAgIH0KICAgIGNsb3NlICRGaWxlaGFuZGxlSUk7CgogICAgIyBsb2cgdGhlIG1hbmlwdWxhdGlvbgogICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICBNZXNzYWdlICA9PiAiRlJFRCBtYW5pcHVsYXRlZCB0aGUgJEZpbGUhIiwKICAgICk7CiAgICByZXR1cm4gMTsKfQoKPWl0ZW0gSW5zZXJ0TGF5b3V0T2JqZWN0MjEoKQoKRlJBTUVXT1JLLTIuMSBzcGVjaWZpYyBiZWNhdXNlIHRoZXJlIGlzIG5vIExheW91dE9iamVjdCBpbnRlZ3JhdGlvbiBmb3IKRlJFRCBpbiBPVFJTMi4xIEludGVyZmFjZUFnZW50LnBtCgogICAgJEZyZWRPYmplY3QtPkluc2VydExheW91dE9iamVjdDIxKCk7Cgo9Y3V0CgpzdWIgSW5zZXJ0TGF5b3V0T2JqZWN0MjEgewogICAgbXkgJFNlbGYgPSBzaGlmdDsKCiAgICBteSBATGluZXMgICAgICAgPSAoKTsKICAgIG15ICRGaWxlICAgICAgICA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAnL0tlcm5lbC9TeXN0ZW0vV2ViL0ludGVyZmFjZUFnZW50LnBtJzsKICAgIG15ICRGaWxlQ2hhbmdlZCA9IDA7CgogICAgZGllICJDYW4ndCBtYW5pcHVsYXRlICRGaWxlIGJlY2F1c2UgaXQgaXMgYSBzeW1saW5rISIgaWYgLWwgJEZpbGU7CgogICAgIyByZWFkIGZpbGUKICAgIG9wZW4gbXkgJEZpbGVoYW5kbGUsICc8JywgJEZpbGUgfHwgZGllICJDYW4ndCBvcGVuICRGaWxlICFcbiI7CiAgICB3aGlsZSAoIG15ICRMaW5lID0gPCRGaWxlaGFuZGxlPiApIHsKICAgICAgICBpZiAoICRMaW5lID1+IC9eXHMqcHJpbnQgXCRHZW5lcmljT2JqZWN0LT5SdW5cKFwpOy8gKSB7CiAgICAgICAgICAgIG15ICRNYW5pcHVsYXRlZCA9IDw8JyAgICAgICAgICAgIEVORF9NQU5JUFVMQVRFRCc7CiAgICAgICAgICAgICMgRlJFRCAtIG1hbmlwdWxhdGVkCiAgICAgICAgICAgIG15ICRPdXRwdXRSZWYgPSBcJEdlbmVyaWNPYmplY3QtPlJ1bigpOwoKICAgICAgICAgICAgaWYgKCAkU2VsZi0+e01haW5PYmplY3R9LT5SZXF1aXJlKCAnS2VybmVsOjpPdXRwdXQ6OkhUTUw6Ok91dHB1dEZpbHRlckZyZWQnICkgKSB7CiAgICAgICAgICAgICAgICAkU2VsZi0+e0xheW91dE9iamVjdH0gPSBLZXJuZWw6Ok91dHB1dDo6SFRNTDo6TGF5b3V0LT5uZXcoCiAgICAgICAgICAgICAgICAgICAgJXskU2VsZn0sCiAgICAgICAgICAgICAgICAgICAgJVBhcmFtLAogICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICAgICAgICBteSAkT2JqZWN0ID0gS2VybmVsOjpPdXRwdXQ6OkhUTUw6Ok91dHB1dEZpbHRlckZyZWQtPm5ldygKICAgICAgICAgICAgICAgICAgICBDb25maWdPYmplY3QgPT4gJFNlbGYtPntDb25maWdPYmplY3R9LAogICAgICAgICAgICAgICAgICAgIE1haW5PYmplY3QgICA9PiAkU2VsZi0+e01haW5PYmplY3R9LAogICAgICAgICAgICAgICAgICAgIExvZ09iamVjdCAgICA9PiAkU2VsZi0+e0xvZ09iamVjdH0sCiAgICAgICAgICAgICAgICAgICAgRGVidWcgICAgICAgID0+ICRTZWxmLT57RGVidWd9LAogICAgICAgICAgICAgICAgICAgIExheW91dE9iamVjdCA9PiAkU2VsZi0+e0xheW91dE9iamVjdH0sCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAgICAgICAgICMgcnVuIG1vZHVsZQogICAgICAgICAgICAgICAgJE9iamVjdC0+UnVuKCAleyAkU2VsZiB9LCBEYXRhID0+ICRPdXRwdXRSZWYgKTsKCiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJpbnQgJHskT3V0cHV0UmVmfTsKICAgICAgICAgICAgI3ByaW50ICRHZW5lcmljT2JqZWN0LT5SdW4oKTsKICAgICAgICAgICAgIyBGUkVEIC0gbWFuaXB1bGF0ZWQKICAgICAgICAgICAgRU5EX01BTklQVUxBVEVECiAgICAgICAgICAgIHB1c2ggQExpbmVzLCAkTWFuaXB1bGF0ZWQ7CiAgICAgICAgICAgICRGaWxlQ2hhbmdlZCA9IDE7CiAgICAgICAgICAgIG5leHQ7CiAgICAgICAgfQogICAgICAgIHB1c2ggQExpbmVzLCAkTGluZTsKICAgIH0KICAgIGNsb3NlICRGaWxlaGFuZGxlOwoKICAgICMgd3JpdGUgZmlsZQogICAgb3BlbiBteSAkRmlsZWhhbmRsZUlJLCAnPicsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgd3JpdGUgJEZpbGUgIVxuIjsKICAgIGZvciBteSAkTGluZSAoQExpbmVzKSB7CiAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAkTGluZTsKICAgIH0KICAgIGNsb3NlICRGaWxlaGFuZGxlSUk7CgogICAgIyBsb2cgdGhlIG1hbmlwdWxhdGlvbgogICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICBNZXNzYWdlICA9PiAiRlJFRCBtYW5pcHVsYXRlZCB0aGUgJEZpbGUhIiwKICAgICk7CiAgICByZXR1cm4gJEZpbGVDaGFuZ2VkOwp9CgoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBTb2Z0d2FyZSBpcyBwYXJ0IG9mIHRoZSBPVFJTIHByb2plY3QgKGh0dHA6Ly9vdHJzLm9yZy8pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvZ3BsLTIuMC50eHQuCgo9Y3V0Cgo9aGVhZDEgVkVSU0lPTgoKJFJldmlzaW9uOiAxLjEwICQgJERhdGU6IDIwMDkvMDQvMjEgMTA6MTM6MTAgJAoKPWN1dAo=
IyAtLQojIEtlcm5lbC9TeXN0ZW0vRnJlZC9CZW5jaG1hcmsucG0KIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IEJlbmNobWFyay5wbSx2IDEuNiAyMDA5LzA0LzIxIDEwOjEzOjEwIHRyIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpGcmVkOjpCZW5jaG1hcms7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdygkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjYgJCkgWzFdOwoKPWhlYWQxIE5BTUUKCktlcm5lbDo6U3lzdGVtOjpGcmVkOjpCZW5jaG1hcmsKCj1oZWFkMSBTWU5PUFNJUwoKaGFuZGxlIHRoZSBiZW5jaG1hcmsgZGF0YQoKPW92ZXIgNAoKPWN1dAoKPWl0ZW0gbmV3KCkKCmNyZWF0ZSBhbiBvYmplY3QKCiAgICB1c2UgS2VybmVsOjpDb25maWc7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkxvZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6QmVuY2htYXJrOwoKICAgIG15ICRDb25maWdPYmplY3QgPSBLZXJuZWw6OkNvbmZpZy0+bmV3KCk7CiAgICBteSAkTG9nT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkxvZy0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgKTsKICAgIG15ICRTbWFsbFByb2ZPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6QmVuY2htYXJrLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICApOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGdldCBuZWVkZWQgb2JqZWN0cwogICAgZm9yIG15ICRPYmplY3QgKHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QpKSB7CiAgICAgICAgJFNlbGYtPnskT2JqZWN0fSA9ICRQYXJhbXskT2JqZWN0fSB8fCBkaWUgIkdvdCBubyAkT2JqZWN0ISI7CiAgICB9CiAgICByZXR1cm4gJFNlbGY7Cn0KCj1pdGVtIERhdGFHZXQoKQoKR2V0IHRoZSBkYXRhIGZvciB0aGlzIGZyZWQgbW9kdWxlLiBSZXR1cm5zIHRydWUgb3IgZmFsc2UuCkFuZCBhZGQgdGhlIGRhdGEgdG8gdGhlIG1vZHVsZSByZWYuCgogICAgJEJhY2tlbmRPYmplY3QtPkRhdGFHZXQoCiAgICAgICAgTW9kdWxlUmVmID0+ICRNb2R1bGVSZWYsCiAgICApOwoKPWN1dAoKc3ViIERhdGFHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIG15ICROZWVkZWRfUmVmIChxdyggTW9kdWxlUmVmICkpIHsKICAgICAgICBpZiAoICEkUGFyYW17JE5lZWRlZF9SZWZ9ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCAkTmVlZGVkX1JlZiEiLAogICAgICAgICAgICApOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIG15ICRUYWJsZVJlZiA9IFsKICAgICAgICBbCiAgICAgICAgICAgICJDYW4ndCBmaW5kIHRoZSBiZW5jaG1hcmsgdGFibGUsIHBsZWFzZSBjaGVjayB5b3VyIGNvZGUgYW4gcmVhZCB0aGUgSE9XVE8gZm9yIHRoZSBiZW5jaG1hcmsgbW9kdWxlLiIKICAgICAgICBdCiAgICBdOwogICAgaWYgKCAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnQmVuY2htYXJrJykgKSB7CiAgICAgICAgJFRhYmxlUmVmID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0JlbmNobWFyaycpOwogICAgfQogICAgJFBhcmFte01vZHVsZVJlZn0tPntEYXRhfSA9ICRUYWJsZVJlZjsKCiAgICByZXR1cm4gMTsKfQoKPWl0ZW0gQWN0aXZhdGVNb2R1bGVUb2RvcygpCgpEbyBhbGwgam9icyB3aGljaCBhcmUgbmVjZXNzYXJ5IHRvIGFjdGl2YXRlIHRoaXMgc3BlY2lhbCBtb2R1bGUuCgogICAgJEZyZWRPYmplY3QtPkFjdGl2YXRlTW9kdWxlVG9kb3MoCiAgICAgICAgTW9kdWxlTmFtZSA9PiAkTW9kdWxlTmFtZSwKICAgICk7Cgo9Y3V0CgpzdWIgQWN0aXZhdGVNb2R1bGVUb2RvcyB7CiAgICByZXR1cm4gMTsKfQoKPWl0ZW0gRGVhY3RpdmF0ZU1vZHVsZVRvZG9zKCkKCkRvIGFsbCBqb2JzIHdoaWNoIGFyZSBuZWNlc3NhcnkgdG8gZGVhY3RpdmF0ZSB0aGlzIHNwZWNpYWwgbW9kdWxlLgoKICAgICRGcmVkT2JqZWN0LT5EZWFjdGl2YXRlTW9kdWxlVG9kb3MoCiAgICAgICAgTW9kdWxlTmFtZSA9PiAkTW9kdWxlTmFtZSwKICAgICk7Cgo9Y3V0CgpzdWIgRGVhY3RpdmF0ZU1vZHVsZVRvZG9zIHsKICAgIHJldHVybiAxOwp9CgoxOwoKPWJhY2sKCj1oZWFkMSBURVJNUyBBTkQgQ09ORElUSU9OUwoKVGhpcyBzb2Z0d2FyZSBpcyBwYXJ0IG9mIHRoZSBPVFJTIHByb2plY3QgKGh0dHA6Ly9vdHJzLm9yZy8pLgoKVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQpkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgoKPWN1dAoKPWhlYWQxIFZFUlNJT04KCiRSZXZpc2lvbjogMS42ICQgJERhdGU6IDIwMDkvMDQvMjEgMTA6MTM6MTAgJAoKPWN1dAo=
IyAtLQojIEtlcm5lbC9TeXN0ZW0vRnJlZC9Db25zb2xlLnBtCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBDb25zb2xlLnBtLHYgMS44IDIwMDkvMDQvMjEgMTA6MTM6MTAgdHIgRXhwICQKIyAtLQojIFRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCiMgdGhlIGVuY2xvc2VkIGZpbGUgQ09QWUlORyBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbiAoQUdQTCkuIElmIHlvdQojIGRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCiMgLS0KCnBhY2thZ2UgS2VybmVsOjpTeXN0ZW06OkZyZWQ6OkNvbnNvbGU7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdygkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjggJCkgWzFdOwoKPWhlYWQxIE5BTUUKCktlcm5lbDo6U3lzdGVtOjpGcmVkOjpDb25zb2xlCgo9aGVhZDEgU1lOT1BTSVMKCmdpdmVzIHlvdSBhbGwgZnVuY3Rpb25zIHdoaWNoIGFyZSBuZWVkZWQgZm9yIHRoZSBjb25zb2xlCgo9b3ZlciA0Cgo9Y3V0Cgo9aXRlbSBuZXcoKQoKY3JlYXRlIGFuIG9iamVjdAoKICAgIHVzZSBLZXJuZWw6OkNvbmZpZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6TG9nOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpGcmVkOjpDb25zb2xlOwoKICAgIG15ICRDb25maWdPYmplY3QgPSBLZXJuZWw6OkNvbmZpZy0+bmV3KCk7CiAgICBteSAkTG9nT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkxvZy0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgKTsKICAgIG15ICRTbWFsbFByb2ZPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6Q29uc29sZS0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCAgICA9PiAkTG9nT2JqZWN0LAogICAgKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBnZXQgbmVlZGVkIG9iamVjdHMKICAgIGZvciBteSAkT2JqZWN0IChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JE9iamVjdH0gPSAkUGFyYW17JE9iamVjdH0gfHwgZGllICJHb3Qgbm8gJE9iamVjdCEiOwogICAgfQogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBEYXRhR2V0KCkKCkdldCB0aGUgZGF0YSBmb3IgdGhpcyBmcmVkIG1vZHVsZS4gUmV0dXJucyB0cnVlIG9yIGZhbHNlLgpBbmQgYWRkIHRoZSBkYXRhIHRvIHRoZSBtb2R1bGUgcmVmLgoKICAgICRCYWNrZW5kT2JqZWN0LT5EYXRhR2V0KAogICAgICAgIE1vZHVsZVJlZiA9PiAkTW9kdWxlUmVmLAogICAgKTsKCj1jdXQKCnN1YiBEYXRhR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkUmVmIChxdyhNb2R1bGVSZWYgSFRNTERhdGFSZWYgRnJlZE1vZHVsZXNSZWYpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyRSZWZ9ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCAkUmVmISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgbXkgQE1vZHVsZXMgPSAoKTsKICAgIGZvciBteSAkTW9kdWxlICgga2V5cyAleyAkUGFyYW17RnJlZE1vZHVsZXNSZWZ9IH0gKSB7CiAgICAgICAgaWYgKCAkTW9kdWxlIG5lICdDb25zb2xlJyApIHsKICAgICAgICAgICAgcHVzaCBATW9kdWxlcywgJE1vZHVsZTsKICAgICAgICB9CiAgICB9CiAgICAkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9ID0gXEBNb2R1bGVzOwoKICAgIGlmICggJHsgJFBhcmFte0hUTUxEYXRhUmVmfSB9ICF+IC9GcmVkLVNldHRpbmcvICYmICR7ICRQYXJhbXtIVE1MRGF0YVJlZn0gfSA9fiAvXDxib2R5Lio/XD4vICkgewogICAgICAgICRQYXJhbXtNb2R1bGVSZWZ9LT57U3RhdHVzfSA9IDE7CiAgICB9CgogICAgaWYgKCAkeyAkUGFyYW17SFRNTERhdGFSZWZ9IH0gIX4gL25hbWU9IkFjdGlvbiIgdmFsdWU9IkxvZ2luIi8gKSB7CiAgICAgICAgJFBhcmFte01vZHVsZVJlZn0tPntTZXR0aW5nfSA9IDE7CiAgICB9CgogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIEFjdGl2YXRlTW9kdWxlVG9kb3MoKQoKRG8gYWxsIGpvYnMgd2hpY2ggYXJlIG5lY2Vzc2FyeSB0byBhY3RpdmF0ZSB0aGlzIHNwZWNpYWwgbW9kdWxlLgoKICAgICRGcmVkT2JqZWN0LT5BY3RpdmF0ZU1vZHVsZVRvZG9zKAogICAgICAgIE1vZHVsZU5hbWUgPT4gJE1vZHVsZU5hbWUsCiAgICApOwoKPWN1dAoKc3ViIEFjdGl2YXRlTW9kdWxlVG9kb3MgewogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIERlYWN0aXZhdGVNb2R1bGVUb2RvcygpCgpEbyBhbGwgam9icyB3aGljaCBhcmUgbmVjZXNzYXJ5IHRvIGRlYWN0aXZhdGUgdGhpcyBzcGVjaWFsIG1vZHVsZS4KCiAgICAkRnJlZE9iamVjdC0+RGVhY3RpdmF0ZU1vZHVsZVRvZG9zKAogICAgICAgIE1vZHVsZU5hbWUgPT4gJE1vZHVsZU5hbWUsCiAgICApOwoKPWN1dAoKc3ViIERlYWN0aXZhdGVNb2R1bGVUb2RvcyB7CiAgICByZXR1cm4gMTsKfQoKMTsKCj1iYWNrCgo9aGVhZDEgVEVSTVMgQU5EIENPTkRJVElPTlMKClRoaXMgc29mdHdhcmUgaXMgcGFydCBvZiB0aGUgT1RSUyBwcm9qZWN0IChodHRwOi8vb3Rycy5vcmcvKS4KClRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCnRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KCj1jdXQKCj1oZWFkMSBWRVJTSU9OCgokUmV2aXNpb246IDEuOCAkICREYXRlOiAyMDA5LzA0LzIxIDEwOjEzOjEwICQKCj1jdXQK
IyAtLQojIEtlcm5lbC9TeXN0ZW0vRnJlZC9IVE1MQ2hlY2sucG0KIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IEhUTUxDaGVjay5wbSx2IDEuOCAyMDA5LzA0LzIxIDEwOjEzOjEwIHRyIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpGcmVkOjpIVE1MQ2hlY2s7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdygkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjggJCkgWzFdOwoKPWhlYWQxIE5BTUUKCktlcm5lbDo6U3lzdGVtOjpGcmVkOjpIVE1MQ2hlY2sKCj1oZWFkMSBTWU5PUFNJUwoKaGFuZGxlIHRoZSBIVE1MOjogbGludCBjaGVjawoKPW92ZXIgNAoKPWN1dAoKPWl0ZW0gbmV3KCkKCmNyZWF0ZSBhbiBvYmplY3QKCiAgICB1c2UgS2VybmVsOjpDb25maWc7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkxvZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6TWFpbjsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6SFRNTENoZWNrOwoKICAgIG15ICRDb25maWdPYmplY3QgPSBLZXJuZWw6OkNvbmZpZy0+bmV3KCk7CiAgICBteSAkTG9nT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkxvZy0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgKTsKICAgIG15ICRNYWluT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06Ok1haW4tPm5ldygKICAgICAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgICAgICBMb2dPYmplY3QgICAgPT4gJExvZ09iamVjdCwKICAgICk7CiAgICBteSAkU21hbGxQcm9mT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkZyZWQ6OkhUTUxDaGVjay0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCAgICA9PiAkTG9nT2JqZWN0LAogICAgICAgIE1haW5PYmplY3QgICA9PiAkTWFpbk9iamVjdCwKICAgICk7Cgo9Y3V0CgpzdWIgbmV3IHsKICAgIG15ICggJFR5cGUsICVQYXJhbSApID0gQF87CgogICAgIyBhbGxvY2F0ZSBuZXcgaGFzaCBmb3Igb2JqZWN0CiAgICBteSAkU2VsZiA9IHt9OwogICAgYmxlc3MoICRTZWxmLCAkVHlwZSApOwoKICAgICMgZ2V0IG5lZWRlZCBvYmplY3RzCiAgICBmb3IgbXkgJE9iamVjdCAocXcoQ29uZmlnT2JqZWN0IExvZ09iamVjdCBNYWluT2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JE9iamVjdH0gPSAkUGFyYW17JE9iamVjdH0gfHwgZGllICJHb3Qgbm8gJE9iamVjdCEiOwogICAgfQogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBEYXRhR2V0KCkKCkdldCB0aGUgZGF0YSBmb3IgdGhpcyBmcmVkIG1vZHVsZS4gUmV0dXJucyB0cnVlIG9yIGZhbHNlLgpBbmQgYWRkIHRoZSBkYXRhIHRvIHRoZSBtb2R1bGUgcmVmLgoKICAgICRCYWNrZW5kT2JqZWN0LT5EYXRhR2V0KAogICAgICAgIE1vZHVsZVJlZiA9PiAkTW9kdWxlUmVmLAogICAgKTsKCj1jdXQKCnN1YiBEYXRhR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkUGFyYW1SZWYgKHF3KCBNb2R1bGVSZWYgSFRNTERhdGFSZWYgKSkgewogICAgICAgIGlmICggISRQYXJhbXskUGFyYW1SZWZ9ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCAkUGFyYW1SZWYhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIENoZWNrIHRoZSBIVE1MLU91dHB1dCB3aXRoIEhUTUw6OkxpbnQKICAgIGlmICggISRTZWxmLT57TWFpbk9iamVjdH0tPlJlcXVpcmUoJ0hUTUw6OkxpbnQnKSApIHsKICAgICAgICBteSAkVGV4dCA9ICdUaGUgSFRNTC1jaGVja2VyIG9mIEZyZWQgcmVxdWlyZXMgSFRNTDo6TGludCB0byBiZSBpbnN0YWxsZWQhJwogICAgICAgICAgICAuICdQbGVhc2UgaW5zdGFsbCBIVE1MOjpMaW50IHZpYSBDUEFOIG9yIGRlYWN0aXZhdGUgdGhlIEhUTUwtY2hlY2tlciB2aWEgU3lzQ29uZmlnLic7CiAgICAgICAgJFBhcmFte01vZHVsZVJlZn0tPntEYXRhfSA9IFskVGV4dF07CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIEhUTUw6OkxpbnQtPmltcG9ydCgpOwogICAgbXkgJEhUTUxMaW50T2JqZWN0ID0gSFRNTDo6TGludC0+bmV3KCBvbmx5X3R5cGVzID0+IEhUTUw6OkxpbnQ6OkVycm9yLT5TVFJVQ1RVUkUgKTsKICAgICRIVE1MTGludE9iamVjdC0+cGFyc2UoICR7ICRQYXJhbXtIVE1MRGF0YVJlZn0gfSApOwoKICAgIG15ICRFcnJvckNvdW50ZXIgPSAkSFRNTExpbnRPYmplY3QtPmVycm9yczsKICAgIG15IEBIVE1MTGludE1lc3NhZ2VzOwogICAgZm9yIG15ICRFcnJvciAoICRIVE1MTGludE9iamVjdC0+ZXJyb3JzICkgewogICAgICAgIG15ICRTdHJpbmcgLj0gJEVycm9yLT5hc19zdHJpbmc7CiAgICAgICAgaWYgKCAkU3RyaW5nICF+IC9JbnZhbGlkIGNoYXJhY3RlciAuKyBzaG91bGQgYmUgd3JpdHRlbiBhcyAvICkgewogICAgICAgICAgICBwdXNoIEBIVE1MTGludE1lc3NhZ2VzLCAkU3RyaW5nOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoQEhUTUxMaW50TWVzc2FnZXMpIHsKICAgICAgICAkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9ID0gXEBIVE1MTGludE1lc3NhZ2VzOwogICAgfQoKICAgIHJldHVybiAxOwp9Cgo9aXRlbSBBY3RpdmF0ZU1vZHVsZVRvZG9zKCkKCkRvIGFsbCBqb2JzIHdoaWNoIGFyZSBuZWNlc3NhcnkgdG8gYWN0aXZhdGUgdGhpcyBzcGVjaWFsIG1vZHVsZS4KCiAgICAkRnJlZE9iamVjdC0+QWN0aXZhdGVNb2R1bGVUb2RvcygKICAgICAgICBNb2R1bGVOYW1lID0+ICRNb2R1bGVOYW1lLAogICAgKTsKCj1jdXQKCnN1YiBBY3RpdmF0ZU1vZHVsZVRvZG9zIHsKICAgIHJldHVybiAxOwp9Cgo9aXRlbSBEZWFjdGl2YXRlTW9kdWxlVG9kb3MoKQoKRG8gYWxsIGpvYnMgd2hpY2ggYXJlIG5lY2Vzc2FyeSB0byBkZWFjdGl2YXRlIHRoaXMgc3BlY2lhbCBtb2R1bGUuCgogICAgJEZyZWRPYmplY3QtPkRlYWN0aXZhdGVNb2R1bGVUb2RvcygKICAgICAgICBNb2R1bGVOYW1lID0+ICRNb2R1bGVOYW1lLAogICAgKTsKCj1jdXQKCnN1YiBEZWFjdGl2YXRlTW9kdWxlVG9kb3MgewogICAgcmV0dXJuIDE7Cn0KCjE7Cgo9YmFjawoKPWhlYWQxIFRFUk1TIEFORCBDT05ESVRJT05TCgpUaGlzIHNvZnR3YXJlIGlzIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoaHR0cDovL290cnMub3JnLykuCgpUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQp0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCgo9Y3V0Cgo9aGVhZDEgVkVSU0lPTgoKJFJldmlzaW9uOiAxLjggJCAkRGF0ZTogMjAwOS8wNC8yMSAxMDoxMzoxMCAkCgo9Y3V0Cg==
IyAtLQojIEtlcm5lbC9TeXN0ZW0vRnJlZC9TVERFUlJMb2cucG0KIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IFNUREVSUkxvZy5wbSx2IDEuMTQgMjAwOS8wNC8yMSAxMDoxMzoxMCB0ciBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQoKcGFja2FnZSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6U1RERVJSTG9nOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIHZhcnMgcXcoJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS4xNCAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpTeXN0ZW06OkZyZWQ6OlNUREVSUkxvZwoKPWhlYWQxIFNZTk9QU0lTCgpoYW5kbGUgdGhlIFNUREVSUiBsb2cgZGF0YQoKPW92ZXIgNAoKPWN1dAoKPWl0ZW0gbmV3KCkKCmNyZWF0ZSBhbiBvYmplY3QKCiAgICB1c2UgS2VybmVsOjpDb25maWc7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkxvZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6U1RERVJSTG9nOwoKICAgIG15ICRDb25maWdPYmplY3QgPSBLZXJuZWw6OkNvbmZpZy0+bmV3KCk7CiAgICBteSAkTG9nT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkxvZy0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgKTsKICAgIG15ICRTbWFsbFByb2ZPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6U1RERVJSTG9nLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICApOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGdldCBuZWVkZWQgb2JqZWN0cwogICAgZm9yIG15ICRPYmplY3QgKHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QpKSB7CiAgICAgICAgJFNlbGYtPnskT2JqZWN0fSA9ICRQYXJhbXskT2JqZWN0fSB8fCBkaWUgIkdvdCBubyAkT2JqZWN0ISI7CiAgICB9CgogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBEYXRhR2V0KCkKCkdldCB0aGUgZGF0YSBmb3IgdGhpcyBmcmVkIG1vZHVsZS4gUmV0dXJucyB0cnVlIG9yIGZhbHNlLgpBbmQgYWRkIHRoZSBkYXRhIHRvIHRoZSBtb2R1bGUgcmVmLgoKICAgICRCYWNrZW5kT2JqZWN0LT5EYXRhR2V0KAogICAgICAgIE1vZHVsZVJlZiA9PiAkTW9kdWxlUmVmLAogICAgKTsKCj1jdXQKCnN1YiBEYXRhR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkTmVlZGVkX1JlZiAocXcoTW9kdWxlUmVmKSkgewogICAgICAgIGlmICggISRQYXJhbXskTmVlZGVkX1JlZn0gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICROZWVkZWRfUmVmISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBvcGVuIHRoZSBTVERFUlIubG9nIGZpbGUgdG8gZ2V0IHRoZSBTVERFUlIgbWVzc2FnZXMKICAgIG15ICRGaWxlID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICcvdmFyL2ZyZWQvU1RERVJSLmxvZyc7CiAgICBteSAkRmlsZWhhbmRsZTsKICAgIGlmICggIW9wZW4gJEZpbGVoYW5kbGUsICc8JywgJEZpbGUgKSB7CiAgICAgICAgJFBhcmFte01vZHVsZVJlZn0tPntEYXRhfSA9IFsKICAgICAgICAgICAgIlBlcmhhcHMgeW91IGRvbid0IGhhdmUgcGVybWlzc2lvbiBhdCAvdmFyL2ZyZWQvIG9yIC9LZXJuZWwvQ29uZmlnL0ZpbGVzL0FBQUZyZWQucG0uIiwKICAgICAgICAgICAgIkNhbid0IHJlYWQgL3Zhci9mcmVkL1NUREVSUi5sb2ciLAogICAgICAgIF07CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgZ2V0IHRoZSB3aG9sZSBpbmZvcm1hdGlvbgogICAgbXkgQExvZ01lc3NhZ2VzOwogICAgTElORToKICAgIGZvciBteSAkTGluZSAoIHJldmVyc2UgPCRGaWxlaGFuZGxlPiApIHsKICAgICAgICBsYXN0IExJTkUgaWYgJExpbmUgPX4gbXsgXEEgXHMqIEZSRUQgXHMqIFx6fXhtczsKCiAgICAgICAgIyBBdHRlbnRpb246IHRoZSBsYXN0IHR3byBzdHJpbmdzIGFyZSBiZWNhdXNlIG9mIERQcm9mLiBJIGhhdmUgdG8gZm9yY2UgdGhlIHByb2Nlc3MuCiAgICAgICAgIyBTbyBJIGdldCB0aGlzIHdhcm5pbmdzIQogICAgICAgIGlmICgKICAgICAgICAgICAgJExpbmUKICAgICAgICAgICAgIX4gLyhTdWJyb3V0aW5lIC4rPyByZWRlZmluZWQgYXR8aGFzIC4rPyB1bnN0YWNrZWQgY2FsbHN8RmFraW5nIC4rPyBleGl0IHRpbWVzdGFtcCkvCiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIHB1c2ggQExvZ01lc3NhZ2VzLCAkTGluZTsKICAgICAgICB9CiAgICB9CiAgICBjbG9zZSAkRmlsZWhhbmRsZTsKCiAgICBwcmludCBTVERFUlIgIlxuRlJFRFxuIjsKCiAgICAjIHRyaW0gdGhlIGxvZyBtZXNzYWdlIGFycmF5CiAgICBMSU5FOgogICAgZm9yIG15ICRMaW5lIChATG9nTWVzc2FnZXMpIHsKICAgICAgICBsYXN0IExJTkUgaWYgJExpbmUgIX4gbXsgXEEgXHMqIFx6IH14bXM7CiAgICAgICAgc2hpZnQgQExvZ01lc3NhZ2VzOwogICAgfQoKICAgICMgdHJpbSB0aGUgbG9nIG1lc3NhZ2UgYXJyYXkKICAgIExJTkU6CiAgICBmb3IgbXkgJExpbmUgKCByZXZlcnNlIEBMb2dNZXNzYWdlcyApIHsKICAgICAgICBsYXN0IExJTkUgaWYgJExpbmUgIX4gbXsgXEEgXHMqIFx6IH14bXM7CiAgICAgICAgc2hpZnQgQExvZ01lc3NhZ2VzOwogICAgfQoKICAgICRQYXJhbXtNb2R1bGVSZWZ9LT57RGF0YX0gPSBcQExvZ01lc3NhZ2VzOwoKICAgIHJldHVybiAxOwp9Cgo9aXRlbSBBY3RpdmF0ZU1vZHVsZVRvZG9zKCkKCkRvIGFsbCBqb2JzIHdoaWNoIGFyZSBuZWNlc3NhcnkgdG8gYWN0aXZhdGUgdGhpcyBzcGVjaWFsIG1vZHVsZS4KCiAgICAkRnJlZE9iamVjdC0+QWN0aXZhdGVNb2R1bGVUb2RvcygKICAgICAgICBNb2R1bGVOYW1lID0+ICRNb2R1bGVOYW1lLAogICAgKTsKCj1jdXQKCnN1YiBBY3RpdmF0ZU1vZHVsZVRvZG9zIHsKICAgIHJldHVybiAxOwp9Cgo9aXRlbSBEZWFjdGl2YXRlTW9kdWxlVG9kb3MoKQoKRG8gYWxsIGpvYnMgd2hpY2ggYXJlIG5lY2Vzc2FyeSB0byBkZWFjdGl2YXRlIHRoaXMgc3BlY2lhbCBtb2R1bGUuCgogICAgJEZyZWRPYmplY3QtPkRlYWN0aXZhdGVNb2R1bGVUb2RvcygKICAgICAgICBNb2R1bGVOYW1lID0+ICRNb2R1bGVOYW1lLAogICAgKTsKCj1jdXQKCnN1YiBEZWFjdGl2YXRlTW9kdWxlVG9kb3MgewogICAgcmV0dXJuIDE7Cn0KCjE7Cgo9YmFjawoKPWhlYWQxIFRFUk1TIEFORCBDT05ESVRJT05TCgpUaGlzIHNvZnR3YXJlIGlzIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoaHR0cDovL290cnMub3JnLykuCgpUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQp0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCgo9Y3V0Cgo9aGVhZDEgVkVSU0lPTgoKJFJldmlzaW9uOiAxLjE0ICQgJERhdGU6IDIwMDkvMDQvMjEgMTA6MTM6MTAgJAoKPWN1dAo=
IyAtLQojIEtlcm5lbC9TeXN0ZW0vRnJlZC9TbWFsbFByb2YucG0KIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IFNtYWxsUHJvZi5wbSx2IDEuMTMgMjAwOS8wNC8yMSAxMDoxMzoxMCB0ciBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQoKcGFja2FnZSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6U21hbGxQcm9mOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIHZhcnMgcXcoJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS4xMyAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpTeXN0ZW06OkZyZWQ6OlNtYWxsUHJvZgoKPWhlYWQxIFNZTk9QU0lTCgpoYW5kbGUgdGhlIFNtYWxsUHJvZiBwcm9maWxpbmcgZGF0YQoKPW92ZXIgNAoKPWN1dAoKPWl0ZW0gbmV3KCkKCmNyZWF0ZSBhbiBvYmplY3QKCiAgICB1c2UgS2VybmVsOjpDb25maWc7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkxvZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6U21hbGxQcm9mOwoKICAgIG15ICRDb25maWdPYmplY3QgPSBLZXJuZWw6OkNvbmZpZy0+bmV3KCk7CiAgICBteSAkTG9nT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkxvZy0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgKTsKICAgIG15ICRTbWFsbFByb2ZPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6U21hbGxQcm9mLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICApOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGdldCBuZWVkZWQgb2JqZWN0cwogICAgZm9yIG15ICRPYmplY3QgKHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QpKSB7CiAgICAgICAgJFNlbGYtPnskT2JqZWN0fSA9ICRQYXJhbXskT2JqZWN0fSB8fCBkaWUgIkdvdCBubyAkT2JqZWN0ISI7CiAgICB9CiAgICByZXR1cm4gJFNlbGY7Cn0KCj1pdGVtIERhdGFHZXQoKQoKR2V0IHRoZSBkYXRhIGZvciB0aGlzIGZyZWQgbW9kdWxlLiBSZXR1cm5zIHRydWUgb3IgZmFsc2UuCkFuZCBhZGQgdGhlIGRhdGEgdG8gdGhlIG1vZHVsZSByZWYuCgogICAgJEJhY2tlbmRPYmplY3QtPkRhdGFHZXQoCiAgICAgICAgTW9kdWxlUmVmID0+ICRNb2R1bGVSZWYsCiAgICApOwoKPWN1dAoKc3ViIERhdGFHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSAkUGF0aCAgICAgICA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAnL2Jpbi9jZ2ktYmluLyc7CiAgICBteSAkQ29uZmlnX1JlZiA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdGcmVkOjpTbWFsbFByb2YnKTsKICAgIG15IEBMaW5lczsKCiAgICAjIGNoZWNrIG5lZWRlZCBzdHVmZgogICAgZm9yIG15ICROZWVkZWRSZWYgKHF3KEhUTUxEYXRhUmVmIE1vZHVsZVJlZikpIHsKICAgICAgICBpZiAoICEkUGFyYW17JE5lZWRlZFJlZn0gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKAogICAgICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgICAgIE1lc3NhZ2UgID0+ICJOZWVkICROZWVkZWRSZWYhIiwKICAgICAgICAgICAgKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICAjIGluIHRoaXMgdHdvIGNhc2VzIGl0IG1ha2VzIG5vIHNlbnNlIHRvIGdlbmVyYXRlIHRoZSBwcm9maWxpbmcgbGlzdAogICAgaWYgKCAkeyAkUGFyYW17SFRNTERhdGFSZWZ9IH0gIX4gL1w8Ym9keS4qP1w+LyApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ1RoaXMgcGFnZSBkZWxpdmVyIHRoZSBIVE1MIGJ5IG1hbnkgc2VwYXJhdGUgb3V0cHV0IGNhbGxzLicKICAgICAgICAgICAgICAgIC4gJyBQbGVhc2UgdXNlIHRoZSB1c3VhbCB3YXkgdG8gaW50ZXJwcmV0IFNtYWxsUHJvZicsCiAgICAgICAgKTsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICByZXR1cm4gMSBpZiAkeyAkUGFyYW17SFRNTERhdGFSZWZ9IH0gPX4gL0ZyZWQtU2V0dGluZy87CgogICAgIyBmaW5kIG91dCB3aGljaCBwYWNrYWdlcyBhcmUgY2hlY2tlZCBieSBTbWFsbFByb2YKICAgIG15IEBQYWNrYWdlcyAgICAgICAgPSBrZXlzICVEQjo6cGFja2FnZXM7CiAgICBteSAkQ1ZTQ2hlY2tQcm9ibGVtID0gXCVEQjo6cGFja2FnZXM7ICAgICAgICMgc29ycnksIHRoaXMgaXMgYmVjYXVzZSBvZiB0aGUgQ1ZTQ2hlY2tlcgogICAgaWYgKCAhJFBhY2thZ2VzWzBdICkgewogICAgICAgICRQYWNrYWdlc1swXSA9ICdhbGwnOwogICAgfQogICAgJFBhcmFte01vZHVsZVJlZn0tPntQYWNrYWdlc30gPSBcQFBhY2thZ2VzOwoKICAgICMgY2F0Y2ggdGhlIG5lZWRlZCBwcm9maWxpbmcgZGF0YQogICAgc3lzdGVtICJjcCAkUGF0aC9zbWFsbHByb2Yub3V0ICRQYXRoL0ZyZWRTbWFsbFByb2Yub3V0IjsKCiAgICBpZiAoIG9wZW4gbXkgJEZpbGVoYW5kbGUsICc8JywgJFBhdGggLiAnRnJlZFNtYWxsUHJvZi5vdXQnICkgewoKICAgICAgICAjIGNvbnZlcnQgdGhlIGZpbGUgaW4gdXNlYWJsZSBkYXRhCiAgICAgICAgd2hpbGUgKCBteSAkTGluZSA9IDwkRmlsZWhhbmRsZT4gKSB7CiAgICAgICAgICAgIGlmICggJExpbmUgPX4gLyguKz8pOihcZCs/KTooXGQrPyk6KFxkKz8pOihcZCs/KTpccyooLio/KSQvICkgewogICAgICAgICAgICAgICAgcHVzaCBATGluZXMsIFsgJDEsICQyLCAkMywgJDQsICQ1LCAkNiBdOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAjIGRlZmluZSB0aGUgb3JkZXIgb2YgdGhlIHByb2ZpbGluZyBkYXRhCiAgICAgICAgQExpbmVzID0gc29ydCB7ICRiLT5bICRDb25maWdfUmVmLT57T3JkZXJCeX0gXSA8PT4gJGEtPlsgJENvbmZpZ19SZWYtPntPcmRlckJ5fSBdIH0gQExpbmVzOwogICAgICAgIGlmICggJENvbmZpZ19SZWYtPntPcmRlckJ5fSA9PSAxICkgewogICAgICAgICAgICBATGluZXMgPSByZXZlcnNlIEBMaW5lczsKICAgICAgICB9CgogICAgICAgICMgcmVtb3ZlIGRpc2FibGVkIGZpbGVzIG9yIHBhdGggaWYgbmVjZXNzYXJ5CiAgICAgICAgaWYgKCAkQ29uZmlnX1JlZi0+e0Rpc2FibGVkRmlsZXN9ICkgewogICAgICAgICAgICBteSAkRGlzYWJsZWRGaWxlcyA9IGpvaW4gJ3wnLCBAeyAkQ29uZmlnX1JlZi0+e0Rpc2FibGVkRmlsZXN9IH07CiAgICAgICAgICAgIEBMaW5lcyA9IGdyZXAgeyAkXy0+WzBdICF+IG17XigkRGlzYWJsZWRGaWxlcyl9eCB9IEBMaW5lczsKICAgICAgICB9CgogICAgICAgICMgc2hvdyBvbmx5IHNvIG1hbnkgbGluZXMgYXMgd2FudGVkCiAgICAgICAgaWYgKEBMaW5lcykgewogICAgICAgICAgICBzcGxpY2UgQExpbmVzLCAkQ29uZmlnX1JlZi0+e1Nob3duTGluZXN9OwogICAgICAgICAgICAkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9ID0gXEBMaW5lczsKICAgICAgICB9CiAgICAgICAgY2xvc2UgJEZpbGVoYW5kbGU7CiAgICB9CgogICAgIyBjb21wdXRlIHRvdGFsIGNhbGxzCiAgICBteSAkVG90YWxDYWxsID0gMDsKICAgIGZvciBteSAkVGltZSAoQExpbmVzKSB7CiAgICAgICAgaWYgKCAkVGltZS0+WzJdID1+IC9cZC8gKSB7CiAgICAgICAgICAgICRUb3RhbENhbGwgKz0gJFRpbWUtPlsyXTsKICAgICAgICB9CiAgICB9CiAgICAkUGFyYW17TW9kdWxlUmVmfS0+e1RvdGFsQ2FsbH0gPSAkVG90YWxDYWxsOwoKICAgIHJldHVybiAxOwp9Cgo9aXRlbSBBY3RpdmF0ZU1vZHVsZVRvZG9zKCkKCkRvIGFsbCBqb2JzIHdoaWNoIGFyZSBuZWNlc3NhcnkgdG8gYWN0aXZhdGUgdGhpcyBzcGVjaWFsIG1vZHVsZS4KCiAgICAkRnJlZE9iamVjdC0+QWN0aXZhdGVNb2R1bGVUb2RvcygKICAgICAgICBNb2R1bGVOYW1lID0+ICRNb2R1bGVOYW1lLAogICAgKTsKCj1jdXQKCnN1YiBBY3RpdmF0ZU1vZHVsZVRvZG9zIHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgbXkgJEZpbGUgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gJy9iaW4vY2dpLWJpbi9pbmRleC5wbCc7CgogICAgIyBjaGVjayBpZiBpdCBpcyBhbiBzeW1saW5rLCBiZWNhdXNlIGl0IGNhbiBiZSBkZXZlbG9wbWVudCBzeXN0ZW0gd2hpY2ggdXNlIHN5bWxpbmtzCiAgICBkaWUgIkNhbid0IG1hbmlwdWxhdGUgJEZpbGUgYmVjYXVzZSBpdCBpcyBhIHN5bWxpbmshIiBpZiAtbCAkRmlsZTsKCiAgICAjIHRvIHVzZSBTbWFsbFByb2YgSSBoYXZlIHRvIG1hbmlwdWxhdGUgdGhlIGluZGV4LnBsIGZpbGUKICAgIG9wZW4gbXkgJEZpbGVoYW5kbGUsICc8JywgJEZpbGUgfHwgZGllICJDYW4ndCBvcGVuICRGaWxlICFcbiI7CiAgICBteSBATGluZXMgPSA8JEZpbGVoYW5kbGU+OwogICAgY2xvc2UgJEZpbGVoYW5kbGU7CgogICAgb3BlbiBteSAkRmlsZWhhbmRsZUlJLCAnPicsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgd3JpdGUgJEZpbGUgIVxuIjsKICAgIHByaW50ICRGaWxlaGFuZGxlSUkgIiMhL3Vzci9iaW4vcGVybCAtdyAtZDpTbWFsbFByb2ZcbiI7CiAgICBwcmludCAkRmlsZWhhbmRsZUlJICIjIEZSRUQgLSBtYW5pcHVsYXRlZFxuIjsKICAgIGZvciBteSAkTGluZSAoQExpbmVzKSB7CiAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAkTGluZTsKICAgIH0KICAgIGNsb3NlICRGaWxlaGFuZGxlSUk7CgogICAgIyBjcmVhdGUgYSBpbmZvIGZvciB0aGUgdXNlcgogICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICBNZXNzYWdlICA9PiAiRlJFRCBtYW5pcHVsYXRlZCB0aGUgJEZpbGUhIiwKICAgICk7CgogICAgIyBjcmVhdGUgdGhlIGNvbmZpZ3VyYXRpb24gZmlsZSBmb3IgdGhlIFNtYWxsUHJvZiBtb2R1bGUKICAgIG15ICRTbWFsbFByb2ZGaWxlID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICcvYmluL2NnaS1iaW4vLnNtYWxscHJvZic7CiAgICBvcGVuIG15ICRGaWxlaGFuZGxlSUlJLCAnPicsICRTbWFsbFByb2ZGaWxlIHx8IGRpZSAiQ2FuJ3Qgd3JpdGUgJFNtYWxsUHJvZkZpbGUgIVxuIjsKICAgIHByaW50ICRGaWxlaGFuZGxlSUlJICIjIEZSRUQgLSBtYW5pcHVsYXRlZCBkb24ndCBlZGl0IHRoaXMgZmlsZSFcbiI7CiAgICBwcmludCAkRmlsZWhhbmRsZUlJSSAiIyB1c2UgLi4vLi4vIGFzIGxpYiBsb2NhdGlvblxuIjsKICAgIHByaW50ICRGaWxlaGFuZGxlSUlJICJ1c2UgRmluZEJpbiBxdyhcJEJpbik7XG4iOwogICAgcHJpbnQgJEZpbGVoYW5kbGVJSUkgInVzZSBsaWIgXCJcJEJpbi8uLi8uLlwiO1xuIjsKICAgIHByaW50ICRGaWxlaGFuZGxlSUlJICJ1c2UgS2VybmVsOjpDb25maWc7XG4iOwogICAgcHJpbnQgJEZpbGVoYW5kbGVJSUkgIm15IFwkQ29uZmlnT2JqZWN0ID0gS2VybmVsOjpDb25maWctPm5ldygpO1xuIjsKICAgIHByaW50ICRGaWxlaGFuZGxlSUlJICJpZiAoXCRDb25maWdPYmplY3QtPkdldCgnRnJlZDo6U21hbGxQcm9mJyktPntQYWNrYWdlc30pIHtcbiI7CiAgICBwcmludCAkRmlsZWhhbmRsZUlJSQogICAgICAgICIgICAgbXkgXEBBcnJheSA9IFxAeyBcJENvbmZpZ09iamVjdC0+R2V0KCdGcmVkOjpTbWFsbFByb2YnKS0+e1BhY2thZ2VzfSB9O1xuIjsKICAgIHByaW50ICRGaWxlaGFuZGxlSUlJICIgICAgbXkgXCVIYXNoID0gbWFwIHsgXCRfID0+IDE7IH0gXEBBcnJheTtcbiI7CiAgICBwcmludCAkRmlsZWhhbmRsZUlJSSAiICAgIFwlREI6OnBhY2thZ2VzID0gXCVIYXNoO1xuIjsKICAgIHByaW50ICRGaWxlaGFuZGxlSUlJICJ9XG4iOwogICAgcHJpbnQgJEZpbGVoYW5kbGVJSUkgIlwkREI6OmRyb3BfemVyb3MgPSAxO1xuIjsKICAgIHByaW50ICRGaWxlaGFuZGxlSUlJICJcJERCOjpncmVwX2Zvcm1hdCA9IDE7XG4iOwogICAgY2xvc2UgJEZpbGVoYW5kbGVJSUk7CgogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIERlYWN0aXZhdGVNb2R1bGVUb2RvcygpCgpEbyBhbGwgam9icyB3aGljaCBhcmUgbmVjZXNzYXJ5IHRvIGRlYWN0aXZhdGUgdGhpcyBzcGVjaWFsIG1vZHVsZS4KCiAgICAkRnJlZE9iamVjdC0+RGVhY3RpdmF0ZU1vZHVsZVRvZG9zKAogICAgICAgIE1vZHVsZU5hbWUgPT4gJE1vZHVsZU5hbWUsCiAgICApOwoKPWN1dAoKc3ViIERlYWN0aXZhdGVNb2R1bGVUb2RvcyB7CiAgICBteSAkU2VsZiA9IHNoaWZ0OwoKICAgIG15ICRGaWxlID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICcvYmluL2NnaS1iaW4vaW5kZXgucGwnOwoKICAgICMgY2hlY2sgaWYgaXQgaXMgYW4gc3ltbGluaywgYmVjYXVzZSBpdCBjYW4gYmUgZGV2ZWxvcG1lbnQgc3lzdGVtIHdoaWNoIHVzZSBzeW1saW5rcwogICAgZGllICJDYW4ndCBtYW5pcHVsYXRlICRGaWxlIGJlY2F1c2UgaXQgaXMgYSBzeW1saW5rISIgaWYgLWwgJEZpbGU7CgogICAgIyByZWFkIHRoZSBpbmRleC5wbCBmaWxlCiAgICBvcGVuIG15ICRGaWxlaGFuZGxlLCAnPCcsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgb3BlbiAkRmlsZSAhXG4iOwogICAgbXkgQExpbmVzID0gPCRGaWxlaGFuZGxlPjsKICAgIGNsb3NlICRGaWxlaGFuZGxlOwoKICAgICMgcmVtb3ZlIHRoZSBtYW5pcHVsYXRlZCBsaW5lcwogICAgaWYgKCAkTGluZXNbMF0gPX4gLyMhXC91c3JcL2JpblwvcGVybCAtdyAtZDpTbWFsbFByb2YvICkgewogICAgICAgIHNoaWZ0IEBMaW5lczsKICAgIH0KICAgIGlmICggJExpbmVzWzBdID1+IC8jIEZSRUQgLSBtYW5pcHVsYXRlZC8gKSB7CiAgICAgICAgc2hpZnQgQExpbmVzOwogICAgfQoKICAgICMgc2F2ZSB0aGUgaW5kZXgucGwgZmlsZQogICAgb3BlbiBteSAkRmlsZWhhbmRsZUlJLCAnPicsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgd3JpdGUgJEZpbGUgIVxuIjsKICAgIGZvciBteSAkTGluZSAoQExpbmVzKSB7CiAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAkTGluZTsKICAgIH0KICAgIGNsb3NlICRGaWxlaGFuZGxlSUk7CiAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgIE1lc3NhZ2UgID0+ICJGUkVEIG1hbmlwdWxhdGVkIHRoZSAkRmlsZSEiLAogICAgKTsKCiAgICAjIGRlbGV0ZSB0aGUgLnNtYWxscHJvZiBiZWNhdXNlIGl0IGlzIG5vIGxvbmdlciBuZWVkZWQKICAgIG15ICRTbWFsbFByb2ZGaWxlID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICcvYmluL2NnaS1iaW4vLnNtYWxscHJvZic7CiAgICB1bmxpbmsgJFNtYWxsUHJvZkZpbGU7CgogICAgcmV0dXJuIDE7Cn0KCjE7Cgo9YmFjawoKPWhlYWQxIFRFUk1TIEFORCBDT05ESVRJT05TCgpUaGlzIHNvZnR3YXJlIGlzIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoaHR0cDovL290cnMub3JnLykuCgpUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQp0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCgo9Y3V0Cgo9aGVhZDEgVkVSU0lPTgoKJFJldmlzaW9uOiAxLjEzICQgJERhdGU6IDIwMDkvMDQvMjEgMTA6MTM6MTAgJAoKPWN1dAo=
IyAtLQojIEtlcm5lbC9TeXN0ZW0vRnJlZC9EUHJvZi5wbQojIENvcHlyaWdodCAoQykgMjAwMS0yMDA5IE9UUlMgQUcsIGh0dHA6Ly9vdHJzLm9yZy8KIyAtLQojICRJZDogRFByb2YucG0sdiAxLjkgMjAwOS8wNC8yMSAxMDoxMzoxMCB0ciBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQoKcGFja2FnZSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6RFByb2Y7Cgp1c2Ugc3RyaWN0Owp1c2Ugd2FybmluZ3M7Cgp1c2UgdmFycyBxdygkVkVSU0lPTik7CiRWRVJTSU9OID0gcXcoJFJldmlzaW9uOiAxLjkgJCkgWzFdOwoKPWhlYWQxIE5BTUUKCktlcm5lbDo6U3lzdGVtOjpGcmVkOjpEUHJvZgoKPWhlYWQxIFNZTk9QU0lTCgpoYW5kbGUgdGhlIERQcm9mIHByb2ZpbGluZyBkYXRhCgo9b3ZlciA0Cgo9Y3V0Cgo9aXRlbSBuZXcoKQoKY3JlYXRlIGFuIG9iamVjdAoKICAgIHVzZSBLZXJuZWw6OkNvbmZpZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6TG9nOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpGcmVkOjpEUHJvZjsKCiAgICBteSAkQ29uZmlnT2JqZWN0ID0gS2VybmVsOjpDb25maWctPm5ldygpOwogICAgbXkgJExvZ09iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpMb2ctPm5ldygKICAgICAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgICk7CiAgICBteSAkU21hbGxQcm9mT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkZyZWQ6OkRQcm9mLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICApOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGdldCBuZWVkZWQgb2JqZWN0cwogICAgZm9yIG15ICRPYmplY3QgKHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QpKSB7CiAgICAgICAgJFNlbGYtPnskT2JqZWN0fSA9ICRQYXJhbXskT2JqZWN0fSB8fCBkaWUgIkdvdCBubyAkT2JqZWN0ISI7CiAgICB9CiAgICByZXR1cm4gJFNlbGY7Cn0KCj1pdGVtIERhdGFHZXQoKQoKR2V0IHRoZSBkYXRhIGZvciB0aGlzIGZyZWQgbW9kdWxlLiBSZXR1cm5zIHRydWUgb3IgZmFsc2UuCkFuZCBhZGQgdGhlIGRhdGEgdG8gdGhlIG1vZHVsZSByZWYuCgogICAgJEJhY2tlbmRPYmplY3QtPkRhdGFHZXQoCiAgICAgICAgTW9kdWxlUmVmID0+ICRNb2R1bGVSZWYsCiAgICApOwoKPWN1dAoKc3ViIERhdGFHZXQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBteSBATGluZXM7CgogICAgIyBjaGVjayBuZWVkZWQgc3R1ZmYKICAgIGZvciBteSAkTmVlZGVkUmVmIChxdyhIVE1MRGF0YVJlZiBNb2R1bGVSZWYpKSB7CiAgICAgICAgaWYgKCAhJFBhcmFteyROZWVkZWRSZWZ9ICkgewogICAgICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgICAgICBNZXNzYWdlICA9PiAiTmVlZCAkTmVlZGVkUmVmISIsCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgIyBpbiB0aGlzIHR3byBjYXNlcyBpdCBtYWtlcyBubyBzZW5zZSB0byBnZW5lcmF0ZSB0aGUgcHJvZmlsaW5nIGxpc3QKICAgIGlmICggJHsgJFBhcmFte0hUTUxEYXRhUmVmfSB9ICF+IC9cPGJvZHkuKj9cPi8gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdUaGlzIHBhZ2UgZGVsaXZlciB0aGUgSFRNTCBieSBtYW55IHNlcGFyYXRlIG91dHB1dCBjYWxscy4nCiAgICAgICAgICAgICAgICAuICcgUGxlYXNlIHVzZSB0aGUgdXN1YWwgd2F5IHRvIGludGVycHJldCBEUHJvZicsCiAgICAgICAgKTsKICAgICAgICByZXR1cm4gMTsKICAgIH0KICAgIGlmICggJHsgJFBhcmFte0hUTUxEYXRhUmVmfSB9ID1+IC9GcmVkLVNldHRpbmcvICkgewogICAgICAgIHJldHVybiAxOwogICAgfQoKICAgICMgY2F0Y2ggdGhlIG5lZWRlZCBwcm9maWxpbmcgZGF0YQogICAgbXkgJFBhdGggPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gJy9iaW4vY2dpLWJpbi8nOwogICAgc3lzdGVtICJjcCAkUGF0aC90bW9uLm91dCAkUGF0aC9EUHJvZi5vdXQiOwoKICAgIG15ICRDb25maWdfUmVmID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0ZyZWQ6OkRQcm9mJyk7CiAgICBteSBAUHJvZmlsaW5nUmVzdWx0czsKCiAgICAjIHJldHVybnMgdGhlIHRyZWUgcmVzdWx0cyBvZiBjb25maWd1cmVkCiAgICBpZiAoICRDb25maWdfUmVmLT57RnVuY3Rpb25UcmVlfSApIHsKICAgICAgICBpZiAoIG9wZW4gbXkgJEZpbGVoYW5kbGUsICJkcHJvZnBwIC1GVCAkUGF0aC9EUHJvZi5vdXQgfCIgKSB7CiAgICAgICAgICAgIG15ICRDb3VudGVyID0gMDsKICAgICAgICAgICAgd2hpbGUgKCBteSAkTGluZSA9IDwkRmlsZWhhbmRsZT4gKSB7CiAgICAgICAgICAgICAgICAkQ291bnRlcisrOwogICAgICAgICAgICAgICAgcHVzaCBAUHJvZmlsaW5nUmVzdWx0cywgWyAkQ291bnRlciwgJExpbmUgXTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjbG9zZSAkRmlsZWhhbmRsZTsKICAgICAgICB9CiAgICAgICAgJFBhcmFte01vZHVsZVJlZn0tPntGdW5jdGlvblRyZWV9ID0gXEBQcm9maWxpbmdSZXN1bHRzOwoKICAgICAgICByZXR1cm4gMTsKCiAgICB9CgogICAgIyBzaG93IHRoZSBjb21tb24gcGVyZm9ybWFuY2UgcmVzdWx0cwogICAgbXkgJFNob3duTGluZXMgPSAkQ29uZmlnX1JlZi0+e1Nob3duTGluZXN9IDwgNDAgPyAkQ29uZmlnX1JlZi0+e1Nob3duTGluZXN9IDogNDA7CiAgICBteSAkT3B0aW9ucyA9ICItRiAtTyAkU2hvd25MaW5lcyAiOwogICAgJE9wdGlvbnMgLj0gJENvbmZpZ19SZWYtPntPcmRlckJ5fSBlcSAnTmFtZScKICAgICAgICA/ICctYScKICAgICAgICA6ICRDb25maWdfUmVmLT57T3JkZXJCeX0gZXEgJ0NhbGxzJyA/ICctbCcKICAgICAgICA6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcnOwogICAgaWYgKCBvcGVuIG15ICRGaWxlaGFuZGxlLCAiZHByb2ZwcCAkT3B0aW9ucyAkUGF0aC9EUHJvZi5vdXQgfCIgKSB7CiAgICAgICAgd2hpbGUgKCBteSAkTGluZSA9IDwkRmlsZWhhbmRsZT4gKSB7CiAgICAgICAgICAgIGlmICgKICAgICAgICAgICAgICAgICRMaW5lCiAgICAgICAgICAgICAgICA9fiAvXlxzKj8oW15cc10rPylccys/KFteXHNdKz8pXHMrPyhbXlxzXSs/KVxzKz8oW15cc10rPylccys/KFteXHNdKz8pXHMrPyhbXlxzXSs/KVxzKz8oW15cc10rPykkLwogICAgICAgICAgICAgICAgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBwdXNoIEBQcm9maWxpbmdSZXN1bHRzLCBbICQxLCAkMiwgJDMsICQ0LCAkNSwgJDYsICQ3IF07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzaWYgKCAkTGluZSA9fiAvXlxzKj8oW15cc10rPykkLyApIHsKICAgICAgICAgICAgICAgICRQcm9maWxpbmdSZXN1bHRzWy0xXVs2XSAuPSAkMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjbG9zZSAkRmlsZWhhbmRsZTsKICAgIH0KCiAgICBzaGlmdCBAUHJvZmlsaW5nUmVzdWx0czsKCiAgICBpZiAoICRDb25maWdfUmVmLT57T3JkZXJCeX0gZXEgJ0N1VGltZScgKSB7CiAgICAgICAgQFByb2ZpbGluZ1Jlc3VsdHMgPSBzb3J0IHsgJGItPlsyXSA8PT4gJGEtPlsyXSB9IEBQcm9maWxpbmdSZXN1bHRzOwogICAgfQoKICAgICMgcmVtb3ZlIGRpc2FibGVkIHBhY2thZ2VzIGlmIG5lY2Vzc2FyeQogICAgaWYgKCAkQ29uZmlnX1JlZi0+e0Rpc2FibGVkUGFja2FnZXN9ICkgewogICAgICAgIG15ICREaXNhYmxlZFBhY2thZ2VzID0gam9pbiAnfCcsIEB7ICRDb25maWdfUmVmLT57RGlzYWJsZWRQYWNrYWdlc30gfTsKICAgICAgICBAUHJvZmlsaW5nUmVzdWx0cyA9IGdyZXAgeyAkXy0+WzZdICF+IG17XigkRGlzYWJsZWRQYWNrYWdlcyk6On14IH0gQFByb2ZpbGluZ1Jlc3VsdHM7CiAgICB9CgogICAgIyBjb21wdXRlIHRvdGFsIHRpbWUKICAgIG15ICRUb3RhbFRpbWUgPSAwOwogICAgZm9yIG15ICRUaW1lIChAUHJvZmlsaW5nUmVzdWx0cykgewogICAgICAgIGlmICggJFRpbWUtPlsxXSBuZSAnLScgKSB7CiAgICAgICAgICAgICRUb3RhbFRpbWUgKz0gJFRpbWUtPlsxXTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCRUb3RhbFRpbWUpIHsKICAgICAgICBmb3IgbXkgJFRpbWUgKEBQcm9maWxpbmdSZXN1bHRzKSB7CiAgICAgICAgICAgIGlmICggJFRpbWUtPlsxXSBuZSAnLScgKSB7CiAgICAgICAgICAgICAgICAkVGltZS0+WzBdID0gaW50KCAkVGltZS0+WzFdIC8gJFRvdGFsVGltZSAqIDEwMDAwICkgLyAxMDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgIyBjb21wdXRlIHRvdGFsIGNhbGxzCiAgICBteSAkVG90YWxDYWxsID0gMDsKICAgIGZvciBteSAkVGltZSAoQFByb2ZpbGluZ1Jlc3VsdHMpIHsKICAgICAgICBpZiAoICRUaW1lLT5bM10gPX4gL1xkLyApIHsKICAgICAgICAgICAgJFRvdGFsQ2FsbCArPSAkVGltZS0+WzNdOwogICAgICAgIH0KICAgIH0KCiAgICAkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9ICAgICAgPSBcQFByb2ZpbGluZ1Jlc3VsdHM7CiAgICAkUGFyYW17TW9kdWxlUmVmfS0+e1RvdGFsVGltZX0gPSAkVG90YWxUaW1lOwogICAgJFBhcmFte01vZHVsZVJlZn0tPntUb3RhbENhbGx9ID0gJFRvdGFsQ2FsbDsKCiAgICByZXR1cm4gMTsKfQoKPWl0ZW0gQWN0aXZhdGVNb2R1bGVUb2RvcygpCgpEbyBhbGwgam9icyB3aGljaCBhcmUgbmVjZXNzYXJ5IHRvIGFjdGl2YXRlIHRoaXMgc3BlY2lhbCBtb2R1bGUuCgogICAgJEZyZWRPYmplY3QtPkFjdGl2YXRlTW9kdWxlVG9kb3MoCiAgICAgICAgTW9kdWxlTmFtZSA9PiAkTW9kdWxlTmFtZSwKICAgICk7Cgo9Y3V0CgpzdWIgQWN0aXZhdGVNb2R1bGVUb2RvcyB7CiAgICBteSAkU2VsZiA9IHNoaWZ0OwoKICAgIG15IEBMaW5lcyA9ICgpOwogICAgbXkgJEZpbGUgID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICcvYmluL2NnaS1iaW4vaW5kZXgucGwnOwoKICAgICMgY2hlY2sgaWYgaXQgaXMgYW4gc3ltbGluaywgYmVjYXVzZSBpdCBjYW4gYmUgZGV2ZWxvcG1lbnQgc3lzdGVtIHdoaWNoIHVzZSBzeW1saW5rcwogICAgaWYgKCAtbCAiJEZpbGUiICkgewogICAgICAgIGRpZSAiQ2FuJ3QgbWFuaXB1bGF0ZSAkRmlsZSBiZWNhdXNlIGl0IGlzIGEgc3ltbGluayEiOwogICAgfQoKICAgICMgdG8gdXNlIERQcm9mIEkgaGF2ZSB0byBtYW5pcHVsYXRlIHRoZSBpbmRleC5wbCBmaWxlCiAgICBvcGVuIG15ICRGaWxlaGFuZGxlLCAnPCcsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgb3BlbiAkRmlsZSAhXG4iOwogICAgd2hpbGUgKCBteSAkTGluZSA9IDwkRmlsZWhhbmRsZT4gKSB7CiAgICAgICAgcHVzaCBATGluZXMsICRMaW5lOwogICAgfQogICAgY2xvc2UgJEZpbGVoYW5kbGU7CgogICAgb3BlbiBteSAkRmlsZWhhbmRsZUlJLCAnPicsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgd3JpdGUgJEZpbGUgIVxuIjsKICAgIHByaW50ICRGaWxlaGFuZGxlSUkgIiMhL3Vzci9iaW4vcGVybCAtdyAtZDpEUHJvZlxuIjsKICAgIHByaW50ICRGaWxlaGFuZGxlSUkgIiMgRlJFRCAtIG1hbmlwdWxhdGVkXG4iOwogICAgZm9yIG15ICRMaW5lIChATGluZXMpIHsKICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICRMaW5lOwogICAgfQogICAgY2xvc2UgJEZpbGVoYW5kbGVJSTsKCiAgICAjIGNyZWF0ZSBhIGluZm8gZm9yIHRoZSB1c2VyCiAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICBQcmlvcml0eSA9PiAnZXJyb3InLAogICAgICAgIE1lc3NhZ2UgID0+ICJGUkVEIG1hbmlwdWxhdGVkIHRoZSAkRmlsZSEiLAogICAgKTsKCiAgICByZXR1cm4gMTsKfQoKPWl0ZW0gRGVhY3RpdmF0ZU1vZHVsZVRvZG9zKCkKCkRvIGFsbCBqb2JzIHdoaWNoIGFyZSBuZWNlc3NhcnkgdG8gZGVhY3RpdmF0ZSB0aGlzIHNwZWNpYWwgbW9kdWxlLgoKICAgICRGcmVkT2JqZWN0LT5EZWFjdGl2YXRlTW9kdWxlVG9kb3MoCiAgICAgICAgTW9kdWxlTmFtZSA9PiAkTW9kdWxlTmFtZSwKICAgICk7Cgo9Y3V0CgpzdWIgRGVhY3RpdmF0ZU1vZHVsZVRvZG9zIHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgbXkgQExpbmVzID0gKCk7CiAgICBteSAkRmlsZSAgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gJy9iaW4vY2dpLWJpbi9pbmRleC5wbCc7CgogICAgIyBjaGVjayBpZiBpdCBpcyBhbiBzeW1saW5rLCBiZWNhdXNlIGl0IGNhbiBiZSBkZXZlbG9wbWVudCBzeXN0ZW0gd2hpY2ggdXNlIHN5bWxpbmtzCiAgICBpZiAoIC1sICIkRmlsZSIgKSB7CiAgICAgICAgZGllICJDYW4ndCBtYW5pcHVsYXRlICRGaWxlIGJlY2F1c2UgaXQgaXMgYSBzeW1saW5rISI7CiAgICB9CgogICAgIyByZWFkIHRoZSBpbmRleC5wbCBmaWxlCiAgICBvcGVuIG15ICRGaWxlaGFuZGxlLCAnPCcsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgb3BlbiAkRmlsZSAhXG4iOwogICAgd2hpbGUgKCBteSAkTGluZSA9IDwkRmlsZWhhbmRsZT4gKSB7CiAgICAgICAgcHVzaCBATGluZXMsICRMaW5lOwogICAgfQogICAgY2xvc2UgJEZpbGVoYW5kbGU7CgogICAgIyByZW1vdmUgdGhlIG1hbmlwdWxhdGVkIGxpbmVzCiAgICBpZiAoICRMaW5lc1swXSA9fiAvIyFcL3VzclwvYmluXC9wZXJsIC13IC1kOkRQcm9mLyApIHsKICAgICAgICBzaGlmdCBATGluZXM7CiAgICB9CiAgICBpZiAoICRMaW5lc1swXSA9fiAvIyBGUkVEIC0gbWFuaXB1bGF0ZWQvICkgewogICAgICAgIHNoaWZ0IEBMaW5lczsKICAgIH0KCiAgICAjIHNhdmUgdGhlIGluZGV4LnBsIGZpbGUKICAgIG9wZW4gbXkgJEZpbGVoYW5kbGVJSSwgJz4nLCAkRmlsZSB8fCBkaWUgIkNhbid0IHdyaXRlICRGaWxlICFcbiI7CiAgICBmb3IgbXkgJExpbmUgKEBMaW5lcykgewogICAgICAgIHByaW50ICRGaWxlaGFuZGxlSUkgJExpbmU7CiAgICB9CiAgICBjbG9zZSAkRmlsZWhhbmRsZUlJOwogICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICBNZXNzYWdlICA9PiAiRlJFRCBtYW5pcHVsYXRlZCB0aGUgJEZpbGUhIiwKICAgICk7CgogICAgcmV0dXJuIDE7Cn0KCjE7Cgo9YmFjawoKPWhlYWQxIFRFUk1TIEFORCBDT05ESVRJT05TCgpUaGlzIHNvZnR3YXJlIGlzIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoaHR0cDovL290cnMub3JnLykuCgpUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQp0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCgo9Y3V0Cgo9aGVhZDEgVkVSU0lPTgoKJFJldmlzaW9uOiAxLjkgJCAkRGF0ZTogMjAwOS8wNC8yMSAxMDoxMzoxMCAkCgo9Y3V0Cg==
IyAtLQojIEtlcm5lbC9TeXN0ZW0vRnJlZC9UcmFuc2xhdGlvbkRlYnVnLnBtCiMgQ29weXJpZ2h0IChDKSAyMDAxLTIwMDkgT1RSUyBBRywgaHR0cDovL290cnMub3JnLwojIC0tCiMgJElkOiBUcmFuc2xhdGlvbkRlYnVnLnBtLHYgMS4xMiAyMDA5LzA0LzIxIDEwOjEzOjEwIHRyIEV4cCAkCiMgLS0KIyBUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQojIHRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKIyBkaWQgbm90IHJlY2VpdmUgdGhpcyBmaWxlLCBzZWUgaHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzL2FncGwudHh0LgojIC0tCgpwYWNrYWdlIEtlcm5lbDo6U3lzdGVtOjpGcmVkOjpUcmFuc2xhdGlvbkRlYnVnOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIHZhcnMgcXcoJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS4xMiAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpTeXN0ZW06OkZyZWQ6OlRyYW5zbGF0aW9uRGVidWcKCj1oZWFkMSBTWU5PUFNJUwoKaGFuZGxlIHRoZSB0cmFuc2xhdGlvbiBkZWJ1ZyBkYXRhCgo9b3ZlciA0Cgo9Y3V0Cgo9aXRlbSBuZXcoKQoKY3JlYXRlIGFuIG9iamVjdAoKICAgIHVzZSBLZXJuZWw6OkNvbmZpZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6TG9nOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpGcmVkOjpUcmFuc2xhdGlvbkRlYnVnOwoKICAgIG15ICRDb25maWdPYmplY3QgPSBLZXJuZWw6OkNvbmZpZy0+bmV3KCk7CiAgICBteSAkTG9nT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkxvZy0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgKTsKICAgIG15ICRTbWFsbFByb2ZPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6VHJhbnNsYXRpb25EZWJ1Zy0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCAgICA9PiAkTG9nT2JqZWN0LAogICAgKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBnZXQgbmVlZGVkIG9iamVjdHMKICAgIGZvciBteSAkT2JqZWN0IChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JE9iamVjdH0gPSAkUGFyYW17JE9iamVjdH0gfHwgZGllICJHb3Qgbm8gJE9iamVjdCEiOwogICAgfQogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBEYXRhR2V0KCkKCkdldCB0aGUgZGF0YSBmb3IgdGhpcyBmcmVkIG1vZHVsZS4gUmV0dXJucyB0cnVlIG9yIGZhbHNlLgpBbmQgYWRkIHRoZSBkYXRhIHRvIHRoZSBtb2R1bGUgcmVmLgoKICAgICRCYWNrZW5kT2JqZWN0LT5EYXRhR2V0KAogICAgICAgIE1vZHVsZVJlZiA9PiAkTW9kdWxlUmVmLAogICAgKTsKCj1jdXQKCnN1YiBEYXRhR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBvcGVuIHRoZSBUcmFuc2xhdGlvbkRlYnVnLmxvZyBmaWxlIHRvIGdldCB0aGUgdW50cmFuc2xhdGVkIHdvcmRzCiAgICBteSAkRmlsZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAnL3Zhci9mcmVkL1RyYW5zbGF0aW9uRGVidWcubG9nJzsKICAgIG15ICRGaWxlaGFuZGxlOwogICAgaWYgKCAhb3BlbiAkRmlsZWhhbmRsZSwgJzwnLCAkRmlsZSApIHsKICAgICAgICAkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9ID0gWwogICAgICAgICAgICAiUGVyaGFwcyB5b3UgZG9uJ3QgaGF2ZSBwZXJtaXNzaW9uIGF0IC92YXIvZnJlZC8iLAogICAgICAgICAgICAiQ2FuJ3QgcmVhZCAvdmFyL2ZyZWQvVHJhbnNsYXRpb25EZWJ1Zy5sb2ciCiAgICAgICAgXTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBteSBATG9nTWVzc2FnZXM7CgogICAgIyBnZXQgdGhlIHdob2xlIGluZm9ybWF0aW9uCiAgICBMSU5FOgogICAgZm9yIG15ICRMaW5lICggcmV2ZXJzZSA8JEZpbGVoYW5kbGU+ICkgewogICAgICAgIGxhc3QgTElORSBpZiAkTGluZSA9fiAvRlJFRC87CgogICAgICAgIGNob21wICRMaW5lOwogICAgICAgIG5leHQgTElORSBpZiAkTGluZSBlcSAnJzsKCiAgICAgICAgcHVzaCBATG9nTWVzc2FnZXMsICRMaW5lOwogICAgfQogICAgY2xvc2UgJEZpbGVoYW5kbGU7CgogICAgJFNlbGYtPkluc2VydFdvcmQoIFdoYXQgPT4gIkZSRURcbiIgKTsKCiAgICAkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9ID0gXEBMb2dNZXNzYWdlczsKCiAgICByZXR1cm4gMTsKfQoKPWl0ZW0gQWN0aXZhdGVNb2R1bGVUb2RvcygpCgpEbyBhbGwgam9icyB3aGljaCBhcmUgbmVjZXNzYXJ5IHRvIGFjdGl2YXRlIHRoaXMgc3BlY2lhbCBtb2R1bGUuCgogICAgJEZyZWRPYmplY3QtPkFjdGl2YXRlTW9kdWxlVG9kb3MoCiAgICAgICAgTW9kdWxlTmFtZSA9PiAkTW9kdWxlTmFtZSwKICAgICk7Cgo9Y3V0CgpzdWIgQWN0aXZhdGVNb2R1bGVUb2RvcyB7CiAgICBteSAkU2VsZiA9IHNoaWZ0OwoKICAgIG15ICRGaWxlID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICcvS2VybmVsL0xhbmd1YWdlLnBtJzsKCiAgICAjIGNoZWNrIGlmIGl0IGlzIGFuIHN5bWxpbmssIGJlY2F1c2UgaXQgY2FuIGJlIGRldmVsb3BtZW50IHN5c3RlbSB3aGljaCB1c2Ugc3ltbGlua3MKICAgIGRpZSAiQ2FuJ3QgbWFuaXB1bGF0ZSAkRmlsZSBiZWNhdXNlIGl0IGlzIGEgc3ltbGluayEiIGlmIC1sICRGaWxlOwoKICAgICMgdG8gdXNlIFRyYW5zbGF0aW9uRGVidWcgSSBoYXZlIHRvIG1hbmlwdWxhdGUgdGhlIExhbmd1YWdlLnBtIGZpbGUKICAgIG9wZW4gbXkgJEZpbGVoYW5kbGUsICc8JywgJEZpbGUgfHwgZGllICJDYW4ndCBvcGVuICRGaWxlICFcbiI7CiAgICBteSBATGluZXMgPSA8JEZpbGVoYW5kbGU+OwogICAgY2xvc2UgJEZpbGVoYW5kbGU7CgogICAgb3BlbiBteSAkRmlsZWhhbmRsZUlJLCAnPicsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgd3JpdGUgJEZpbGUgIVxuIjsKICAgIGZvciBteSAkTGluZSAoQExpbmVzKSB7CiAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAkTGluZTsKICAgICAgICBpZiAoICRMaW5lID1+IC8jIHdhcm4gaWYgdGhlIHZhbHVlIGlzIG5vdCBkZWYvICkgewogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICIjIEZSRUQgLSBtYW5pcHVsYXRlZFxuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAidXNlIEtlcm5lbDo6U3lzdGVtOjpGcmVkOjpUcmFuc2xhdGlvbkRlYnVnO1xuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSQogICAgICAgICAgICAgICAgIm15IFwkVHJhbnNsYXRpb25EZWJ1Z09iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpGcmVkOjpUcmFuc2xhdGlvbkRlYnVnLT5uZXcoXCV7XCRTZWxmfSk7XG4iOwogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICJcJFRyYW5zbGF0aW9uRGVidWdPYmplY3QtPkluc2VydFdvcmQoV2hhdCA9PiBcJFdoYXQpO1xuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAiIyBGUkVEIC0gbWFuaXB1bGF0ZWRcbiI7CiAgICAgICAgfQogICAgfQogICAgY2xvc2UgJEZpbGVoYW5kbGVJSTsKCiAgICByZXR1cm4gMTsKfQoKPWl0ZW0gRGVhY3RpdmF0ZU1vZHVsZVRvZG9zKCkKCkRvIGFsbCBqb2JzIHdoaWNoIGFyZSBuZWNlc3NhcnkgdG8gZGVhY3RpdmF0ZSB0aGlzIHNwZWNpYWwgbW9kdWxlLgoKICAgICRGcmVkT2JqZWN0LT5EZWFjdGl2YXRlTW9kdWxlVG9kb3MoCiAgICAgICAgTW9kdWxlTmFtZSA9PiAkTW9kdWxlTmFtZSwKICAgICk7Cgo9Y3V0CgpzdWIgRGVhY3RpdmF0ZU1vZHVsZVRvZG9zIHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgbXkgJEZpbGUgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gJy9LZXJuZWwvTGFuZ3VhZ2UucG0nOwoKICAgICMgY2hlY2sgaWYgaXQgaXMgYW4gc3ltbGluaywgYmVjYXVzZSBpdCBjYW4gYmUgZGV2ZWxvcG1lbnQgc3lzdGVtIHdoaWNoIHVzZSBzeW1saW5rcwogICAgZGllICJDYW4ndCBtYW5pcHVsYXRlICRGaWxlIGJlY2F1c2UgaXQgaXMgYSBzeW1saW5rISIgaWYgLWwgJEZpbGU7CgogICAgIyB0byB1c2UgVHJhbnNsYXRpb25EZWJ1Z2dlciBJIGhhdmUgdG8gbWFuaXB1bGF0ZSB0aGUgTGFuZ3VhZ2UucG0gZmlsZQogICAgIyBoZXJlIEkgdW5kbyBteSBtYW5pcHVsYXRpb24KICAgIG9wZW4gbXkgJEZpbGVoYW5kbGUsICc8JywgJEZpbGUgfHwgZGllICJDYW4ndCBvcGVuICRGaWxlICFcbiI7CiAgICBteSBATGluZXMgPSA8JEZpbGVoYW5kbGU+OwogICAgY2xvc2UgJEZpbGVoYW5kbGU7CgogICAgb3BlbiBteSAkRmlsZWhhbmRsZUlJLCAnPicsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgd3JpdGUgJEZpbGUgIVxuIjsKCiAgICBteSAlUmVtb3ZlTGluZSA9ICgKICAgICAgICAiIyBGUkVEIC0gbWFuaXB1bGF0ZWRcbiIgICAgICAgICAgICAgICAgICAgICAgICA9PiAxLAogICAgICAgICJ1c2UgS2VybmVsOjpTeXN0ZW06OkZyZWQ6OlRyYW5zbGF0aW9uRGVidWc7XG4iID0+IDEsCiAgICAgICAgIm15IFwkVHJhbnNsYXRpb25EZWJ1Z09iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpGcmVkOjpUcmFuc2xhdGlvbkRlYnVnLT5uZXcoXCV7XCRTZWxmfSk7XG4iCiAgICAgICAgICAgID0+IDEsCiAgICAgICAgIlwkVHJhbnNsYXRpb25EZWJ1Z09iamVjdC0+SW5zZXJ0V29yZChXaGF0ID0+IFwkV2hhdCk7XG4iID0+IDEsCiAgICApOwoKICAgIGZvciBteSAkTGluZSAoQExpbmVzKSB7CiAgICAgICAgaWYgKCAhJFJlbW92ZUxpbmV7JExpbmV9ICkgewogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICRMaW5lOwogICAgICAgIH0KICAgIH0KICAgIGNsb3NlICRGaWxlaGFuZGxlSUk7CiAgICByZXR1cm4gMTsKfQoKPWl0ZW0gSW5zZXJ0V29yZCgpCgpTYXZlIGEgd29yZCBpbiB0aGUgdHJhbnNsYXRpb24gZGVidWcgbG9nCgogICAgJEJhY2tlbmRPYmplY3QtPkluc2VydFdvcmQoCiAgICAgICAgV2hhdCA9PiAnYSB3b3JkJywKICAgICk7Cgo9Y3V0CgpzdWIgSW5zZXJ0V29yZCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICFkZWZpbmVkKCAkUGFyYW17V2hhdH0gKSApIHsKICAgICAgICAkU2VsZi0+e0xvZ09iamVjdH0tPkxvZygKICAgICAgICAgICAgUHJpb3JpdHkgPT4gJ2Vycm9yJywKICAgICAgICAgICAgTWVzc2FnZSAgPT4gJ05lZWQgV2hhdCEnLAogICAgICAgICk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgICMgc2F2ZSB0aGUgd29yZCBpbiBsb2cgZmlsZQogICAgbXkgJEZpbGUgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gJy92YXIvZnJlZC9UcmFuc2xhdGlvbkRlYnVnLmxvZyc7CiAgICBvcGVuIG15ICRGaWxlaGFuZGxlLCAnPj4nLCAkRmlsZSB8fCBkaWUgIkNhbid0IHdyaXRlICRGaWxlICFcbiI7CiAgICBwcmludCAkRmlsZWhhbmRsZSAkUGFyYW17V2hhdH0gLiAiXG4iOwogICAgY2xvc2UgJEZpbGVoYW5kbGU7CgogICAgcmV0dXJuIDE7Cn0KCjE7Cgo9YmFjawoKPWhlYWQxIFRFUk1TIEFORCBDT05ESVRJT05TCgpUaGlzIHNvZnR3YXJlIGlzIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoaHR0cDovL290cnMub3JnLykuCgpUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQp0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCgo9Y3V0Cgo9aGVhZDEgVkVSU0lPTgoKJFJldmlzaW9uOiAxLjEyICQgJERhdGU6IDIwMDkvMDQvMjEgMTA6MTM6MTAgJAoKPWN1dAo=
IyAtLQojIEtlcm5lbC9TeXN0ZW0vRnJlZC9TUUxMb2cucG0KIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IFNRTExvZy5wbSx2IDEuMTIgMjAwOS8wNC8yMSAxMDoxMzoxMCB0ciBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQoKcGFja2FnZSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6U1FMTG9nOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIHZhcnMgcXcoJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS4xMiAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpTeXN0ZW06OkZyZWQ6OlNRTExvZwoKPWhlYWQxIFNZTk9QU0lTCgpoYW5kbGUgdGhlIHNxbCBsb2cKCj1vdmVyIDQKCj1jdXQKCj1pdGVtIG5ldygpCgpjcmVhdGUgYW4gb2JqZWN0CgogICAgdXNlIEtlcm5lbDo6Q29uZmlnOwogICAgdXNlIEtlcm5lbDo6U3lzdGVtOjpMb2c7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkZyZWQ6OlNRTExvZzsKCiAgICBteSAkQ29uZmlnT2JqZWN0ID0gS2VybmVsOjpDb25maWctPm5ldygpOwogICAgbXkgJExvZ09iamVjdCA9IEtlcm5lbDo6U3lzdGVtOjpMb2ctPm5ldygKICAgICAgICBDb25maWdPYmplY3QgPT4gJENvbmZpZ09iamVjdCwKICAgICk7CiAgICBteSAkU21hbGxQcm9mT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkZyZWQ6OlNRTExvZy0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgICAgIExvZ09iamVjdCAgICA9PiAkTG9nT2JqZWN0LAogICAgKTsKCj1jdXQKCnN1YiBuZXcgewogICAgbXkgKCAkVHlwZSwgJVBhcmFtICkgPSBAXzsKCiAgICAjIGFsbG9jYXRlIG5ldyBoYXNoIGZvciBvYmplY3QKICAgIG15ICRTZWxmID0ge307CiAgICBibGVzcyggJFNlbGYsICRUeXBlICk7CgogICAgIyBnZXQgbmVlZGVkIG9iamVjdHMKICAgIGZvciBteSAkT2JqZWN0IChxdyhDb25maWdPYmplY3QgTG9nT2JqZWN0KSkgewogICAgICAgICRTZWxmLT57JE9iamVjdH0gPSAkUGFyYW17JE9iamVjdH0gfHwgZGllICJHb3Qgbm8gJE9iamVjdCEiOwogICAgfQogICAgcmV0dXJuICRTZWxmOwp9Cgo9aXRlbSBEYXRhR2V0KCkKCkdldCB0aGUgZGF0YSBmb3IgdGhpcyBmcmVkIG1vZHVsZS4gUmV0dXJucyB0cnVlIG9yIGZhbHNlLgpBbmQgYWRkIHRoZSBkYXRhIHRvIHRoZSBtb2R1bGUgcmVmLgoKICAgICRCYWNrZW5kT2JqZWN0LT5EYXRhR2V0KAogICAgICAgIE1vZHVsZVJlZiA9PiAkTW9kdWxlUmVmLAogICAgKTsKCj1jdXQKCnN1YiBEYXRhR2V0IHsKICAgIG15ICggJFNlbGYsICVQYXJhbSApID0gQF87CgogICAgIyBvcGVuIHRoZSBUcmFuc2xhdGlvbkRlYnVnLmxvZyBmaWxlIHRvIGdldCB0aGUgdW50cmFuc2xhdGVkIHdvcmRzCiAgICBteSAkRmlsZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAnL3Zhci9mcmVkL1NRTC5sb2cnOwogICAgbXkgJEZpbGVoYW5kbGU7CiAgICBpZiAoICFvcGVuICRGaWxlaGFuZGxlLCAnPCcsICRGaWxlICkgewogICAgICAgICRQYXJhbXtNb2R1bGVSZWZ9LT57RGF0YX0gPSBbCiAgICAgICAgICAgICJQZXJoYXBzIHlvdSBkb24ndCBoYXZlIHBlcm1pc3Npb24gYXQgL3Zhci9mcmVkLyIsCiAgICAgICAgICAgICJDYW4ndCByZWFkIC92YXIvZnJlZC9TUUwubG9nIgogICAgICAgIF07CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIG15IEBMb2dNZXNzYWdlczsKICAgIG15ICREb1N0YXRlbWVudHMgICAgID0gMDsKICAgIG15ICRTZWxlY3RTdGF0ZW1lbnRzID0gMDsKCiAgICAjIGdldCB0aGUgd2hvbGUgaW5mb3JtYXRpb24KICAgIExJTkU6CiAgICBmb3IgbXkgJExpbmUgKCByZXZlcnNlIDwkRmlsZWhhbmRsZT4gKSB7CiAgICAgICAgbGFzdCBMSU5FIGlmICRMaW5lID1+IC9GUkVELzsKCiAgICAgICAgbXkgQFNwbGl0ZWRMb2cgPSBzcGxpdCAvOy8sICRMaW5lOwogICAgICAgIGlmICggJFNwbGl0ZWRMb2dbMF0gZXEgJ1NRTC1ETycgJiYgJFNwbGl0ZWRMb2dbMV0gPX4gL15TRUxFQ1QvICkgewogICAgICAgICAgICAkU3BsaXRlZExvZ1swXSAuPSAnIC0gUGVyaGFwcyB5b3UgaGF2ZSBhbiBlcnJvciB5b3UgdXNlIERPIGZvciBhIFNFTEVDVC1TdGF0ZW1lbnQ6JzsKICAgICAgICB9CiAgICAgICAgcHVzaCBATG9nTWVzc2FnZXMsIFxAU3BsaXRlZExvZzsKCiAgICAgICAgaWYgKCAkU3BsaXRlZExvZ1swXSBlcSAnU1FMLURPJyApIHsKICAgICAgICAgICAgJERvU3RhdGVtZW50cysrOwogICAgICAgIH0KCiAgICAgICAgIyB0cmFuc2ZlciBpbiAxLzEwMCBzZWMKICAgICAgICBpZiAoICRTcGxpdGVkTG9nWzNdICkgewogICAgICAgICAgICAkUGFyYW17TW9kdWxlUmVmfS0+e1RpbWV9ICs9ICRTcGxpdGVkTG9nWzNdOwogICAgICAgICAgICAkU3BsaXRlZExvZ1szXSAqPSAxMDA7CiAgICAgICAgfQogICAgfQoKICAgIHBvcCBATG9nTWVzc2FnZXM7CiAgICBjbG9zZSAkRmlsZWhhbmRsZTsKCiAgICAjIGZpbmQgbXVsdGkgdXNlZCBzdGF0ZW1lbnRzCiAgICBteSAlTXVsdGlVc2VkOwogICAgZm9yIG15ICRTdGF0ZW1lbnRSZWYgKEBMb2dNZXNzYWdlcykgewogICAgICAgICRNdWx0aVVzZWR7ICRTdGF0ZW1lbnRSZWYtPlsxXSB9Kys7CiAgICB9CiAgICBmb3IgbXkgJFN0YXRlbWVudFJlZiAoQExvZ01lc3NhZ2VzKSB7CiAgICAgICAgcHVzaCBAeyRTdGF0ZW1lbnRSZWZ9LCAoICRNdWx0aVVzZWR7ICRTdGF0ZW1lbnRSZWYtPlsxXSB9IC0gMSApOwogICAgfQoKICAgICRTZWxmLT5JbnNlcnRXb3JkKCBXaGF0ID0+ICJGUkVEXG4iICk7CiAgICAkUGFyYW17TW9kdWxlUmVmfS0+e0RhdGF9ICAgICAgICAgICAgID0gXEBMb2dNZXNzYWdlczsKICAgICRQYXJhbXtNb2R1bGVSZWZ9LT57QWxsU3RhdGVtZW50c30gICAgPSBzY2FsYXIgQExvZ01lc3NhZ2VzOwogICAgJFBhcmFte01vZHVsZVJlZn0tPntEb1N0YXRlbWVudHN9ICAgICA9ICREb1N0YXRlbWVudHM7CiAgICAkUGFyYW17TW9kdWxlUmVmfS0+e1NlbGVjdFN0YXRlbWVudHN9ID0gJFBhcmFte01vZHVsZVJlZn0tPntBbGxTdGF0ZW1lbnRzfSAtICREb1N0YXRlbWVudHM7CgogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIEFjdGl2YXRlTW9kdWxlVG9kb3MoKQoKRG8gYWxsIGpvYnMgd2hpY2ggYXJlIG5lY2Vzc2FyeSB0byBhY3RpdmF0ZSB0aGlzIHNwZWNpYWwgbW9kdWxlLgoKICAgICRGcmVkT2JqZWN0LT5BY3RpdmF0ZU1vZHVsZVRvZG9zKAogICAgICAgIE1vZHVsZU5hbWUgPT4gJE1vZHVsZU5hbWUsCiAgICApOwoKPWN1dAoKc3ViIEFjdGl2YXRlTW9kdWxlVG9kb3MgewogICAgbXkgJFNlbGYgPSBzaGlmdDsKCiAgICBteSAkRmlsZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAnL0tlcm5lbC9TeXN0ZW0vREIucG0nOwoKICAgICMgY2hlY2sgaWYgaXQgaXMgYW4gc3ltbGluaywgYmVjYXVzZSBpdCBjYW4gYmUgZGV2ZWxvcG1lbnQgc3lzdGVtIHdoaWNoIHVzZSBzeW1saW5rcwogICAgZGllICJDYW4ndCBtYW5pcHVsYXRlICRGaWxlIGJlY2F1c2UgaXQgaXMgYSBzeW1saW5rISIgaWYgLWwgJEZpbGU7CgogICAgIyB0byB1c2UgVHJhbnNsYXRpb25EZWJ1ZyBJIGhhdmUgdG8gbWFuaXB1bGF0ZSB0aGUgTGFuZ3VhZ2UucG0gZmlsZQogICAgb3BlbiBteSAkRmlsZWhhbmRsZSwgJzwnLCAkRmlsZSB8fCBkaWUgIkNhbid0IG9wZW4gJEZpbGUgIVxuIjsKICAgIG15IEBMaW5lcyA9IDwkRmlsZWhhbmRsZT47CiAgICBjbG9zZSAkRmlsZWhhbmRsZTsKCiAgICBvcGVuIG15ICRGaWxlaGFuZGxlSUksICc+JywgJEZpbGUgfHwgZGllICJDYW4ndCB3cml0ZSAkRmlsZSAhXG4iOwogICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coIFByaW9yaXR5ID0+ICdub3RpY2UnLCBNZXNzYWdlID0+ICJ3cml0ZSBmaWxlISIgKTsKICAgIG15ICRQcmVwYXJlOwogICAgbXkgJERvU1FMOwogICAgZm9yIG15ICRMaW5lIChATGluZXMpIHsKICAgICAgICBpZiAoCiAgICAgICAgICAgICRMaW5lID1+IG1bXiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBccyoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBccyoKICAgICAgICAgICAgICAgICAgICAgICAgXCggICAgICAgICAgICAgICAgICAgICAgICAgICAgICBccyoKICAgICAgICAgICAgICAgICAgICAgICAgISAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBccyoKICAgICAgICAgICAgICAgICAgICAgICAgXCggICAgICAgICAgICAgICAgICAgICAgICAgICAgICBccyoKICAgICAgICAgICAgICAgICAgICAgICAgXCRTZWxmLT57Q3VycyhlfG8pcn0gICAgICAgICAgICBccyogIyBiZWNhdXNlIG9mIGFuIHR5cG8gYnVnZml4IGluIDIuMwogICAgICAgICAgICAgICAgICAgICAgICA9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxzKgogICAgICAgICAgICAgICAgICAgICAgICBcJFNlbGYtPntkYmh9LT5wcmVwYXJlXChcJFNRTFwpIFxzKgogICAgICAgICAgICAgICAgICAgICAgICBcKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxzKgogICAgICAgICAgICAgICAgICAgICAgICBcKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxzKgogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgIF14CiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnbm90aWNlJywgTWVzc2FnZSA9PiAiaW5zZXJ0IGZyZWQgbG9nIFByZXBhcmUhIiApOwogICAgICAgICAgICAkUHJlcGFyZSA9IDE7CiAgICAgICAgICAgIHByaW50ICRGaWxlaGFuZGxlSUkgIiMgRlJFRCAtIG1hbmlwdWxhdGVkXG4iOwogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICJ1c2UgS2VybmVsOjpTeXN0ZW06OkZyZWQ6OlNRTExvZztcbiI7CiAgICAgICAgICAgIHByaW50ICRGaWxlaGFuZGxlSUkgInVzZSBUaW1lOjpIaVJlcyBxdyhnZXR0aW1lb2ZkYXkgdHZfaW50ZXJ2YWwpO1xuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAibXkgXCR0MCA9IFtnZXR0aW1lb2ZkYXldO1xuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSQogICAgICAgICAgICAgICAgIm15IFwkU1FMTG9nT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkZyZWQ6OlNRTExvZy0+bmV3KFwle1wkU2VsZn0pO1xuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAibXkgXCRDYWxsZXIgPSBjYWxsZXIoKTtcbiI7CiAgICAgICAgICAgIHByaW50ICRGaWxlaGFuZGxlSUkgIiMgRlJFRCAtIG1hbmlwdWxhdGVkXG4iOwoKICAgICAgICB9CiAgICAgICAgaWYgKCAkTGluZSA9fiBte14gICAgIyBzbG93IGxvZyBmZWF0dXJlfSAmJiAkUHJlcGFyZSApIHsKICAgICAgICAgICAgJFByZXBhcmUgPSAwOwogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICIjIEZSRUQgLSBtYW5pcHVsYXRlZFxuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAibXkgXCREaWZmVGltZSA9IHR2X2ludGVydmFsKFwkdDApO1xuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSQogICAgICAgICAgICAgICAgIlwkU1FMTG9nT2JqZWN0LT5JbnNlcnRXb3JkKFdoYXQgPT4gXCJTUUwtU0VMRUNUO1wkU1FMO1wkQ2FsbGVyO1wkRGlmZlRpbWVcIik7XG4iOwogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICIjIEZSRUQgLSBtYW5pcHVsYXRlZFxuIjsKICAgICAgICB9CgogICAgICAgIGlmICggJExpbmUgPX4gL14gICAgIyBzZW5kIHNxbCB0byBkYXRhYmFzZS8gKSB7CiAgICAgICAgICAgICRTZWxmLT57TG9nT2JqZWN0fS0+TG9nKCBQcmlvcml0eSA9PiAnbm90aWNlJywgTWVzc2FnZSA9PiAiaW5zZXJ0IGZyZWQgbG9nIGRvISIgKTsKICAgICAgICAgICAgJERvU1FMID0gMTsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAiIyBGUkVEIC0gbWFuaXB1bGF0ZWRcbiI7CiAgICAgICAgICAgIHByaW50ICRGaWxlaGFuZGxlSUkgInVzZSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6U1FMTG9nO1xuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAidXNlIFRpbWU6OkhpUmVzIHF3KGdldHRpbWVvZmRheSB0dl9pbnRlcnZhbCk7XG4iOwogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICJteSBcJHQwID0gW2dldHRpbWVvZmRheV07XG4iOwogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJCiAgICAgICAgICAgICAgICAibXkgXCRTUUxMb2dPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6U1FMTG9nLT5uZXcoXCV7XCRTZWxmfSk7XG4iOwogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICJteSBcJENhbGxlciA9IGNhbGxlcigpO1xuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAiIyBGUkVEIC0gbWFuaXB1bGF0ZWRcbiI7CiAgICAgICAgfQoKICAgICAgICBpZiAoICRMaW5lID1+IG17XiAgICByZXR1cm4gMTt9ICYmICREb1NRTCApIHsKICAgICAgICAgICAgJERvU1FMID0gMDsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAiIyBGUkVEIC0gbWFuaXB1bGF0ZWRcbiI7CiAgICAgICAgICAgIHByaW50ICRGaWxlaGFuZGxlSUkgIm15IFwkRGlmZlRpbWUgPSB0dl9pbnRlcnZhbChcJHQwKTtcbiI7CiAgICAgICAgICAgIHByaW50ICRGaWxlaGFuZGxlSUkKICAgICAgICAgICAgICAgICJcJFNRTExvZ09iamVjdC0+SW5zZXJ0V29yZChXaGF0ID0+IFwiU1FMLURPO1wkUGFyYW17U1FMfTtcJENhbGxlcjtcJERpZmZUaW1lXCIpO1xuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAiIyBGUkVEIC0gbWFuaXB1bGF0ZWRcbiI7CiAgICAgICAgfQoKICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICRMaW5lOwogICAgfQogICAgY2xvc2UgJEZpbGVoYW5kbGVJSTsKCiAgICByZXR1cm4gMTsKfQoKPWl0ZW0gRGVhY3RpdmF0ZU1vZHVsZVRvZG9zKCkKCkRvIGFsbCBqb2JzIHdoaWNoIGFyZSBuZWNlc3NhcnkgdG8gZGVhY3RpdmF0ZSB0aGlzIHNwZWNpYWwgbW9kdWxlLgoKICAgICRGcmVkT2JqZWN0LT5EZWFjdGl2YXRlTW9kdWxlVG9kb3MoCiAgICAgICAgTW9kdWxlTmFtZSA9PiAkTW9kdWxlTmFtZSwKICAgICk7Cgo9Y3V0CgpzdWIgRGVhY3RpdmF0ZU1vZHVsZVRvZG9zIHsKICAgIG15ICRTZWxmID0gc2hpZnQ7CgogICAgbXkgJEZpbGUgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnSG9tZScpIC4gJy9LZXJuZWwvU3lzdGVtL0RCLnBtJzsKCiAgICAjIGNoZWNrIGlmIGl0IGlzIGFuIHN5bWxpbmssIGJlY2F1c2UgaXQgY2FuIGJlIGRldmVsb3BtZW50IHN5c3RlbSB3aGljaCB1c2Ugc3ltbGlua3MKICAgIGRpZSAiQ2FuJ3QgbWFuaXB1bGF0ZSAkRmlsZSBiZWNhdXNlIGl0IGlzIGEgc3ltbGluayEiIGlmIC1sICRGaWxlOwoKICAgICMgdG8gdXNlIFRyYW5zbGF0aW9uRGVidWdnZXIgSSBoYXZlIHRvIG1hbmlwdWxhdGUgdGhlIExhbmd1YWdlLnBtIGZpbGUKICAgICMgaGVyZSBJIHVuZG8gbXkgbWFuaXB1bGF0aW9uCiAgICBvcGVuIG15ICRGaWxlaGFuZGxlLCAnPCcsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgb3BlbiAkRmlsZSAhXG4iOwogICAgbXkgQExpbmVzID0gPCRGaWxlaGFuZGxlPjsKICAgIGNsb3NlICRGaWxlaGFuZGxlOwoKICAgIG9wZW4gbXkgJEZpbGVoYW5kbGVJSSwgJz4nLCAkRmlsZSB8fCBkaWUgIkNhbid0IHdyaXRlICRGaWxlICFcbiI7CgogICAgbXkgJVJlbW92ZUxpbmUgPSAoCiAgICAgICAgIiMgRlJFRCAtIG1hbmlwdWxhdGVkXG4iICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAxLAogICAgICAgICJ1c2UgS2VybmVsOjpTeXN0ZW06OkZyZWQ6OlNRTExvZztcbiIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gMSwKICAgICAgICAibXkgXCRTUUxMb2dPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6U1FMTG9nLT5uZXcoXCV7XCRTZWxmfSk7XG4iICAgICAgICAgICAgICAgID0+IDEsCiAgICAgICAgIm15IFwkQ2FsbGVyID0gY2FsbGVyKCk7XG4iICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAxLAogICAgICAgICJcJFNRTExvZ09iamVjdC0+SW5zZXJ0V29yZChXaGF0ID0+IFwiU1FMLURPO1wkUGFyYW17U1FMfTtcJENhbGxlclw7XCREaWZmVGltZVwiKTtcbiIgPT4gMSwKICAgICAgICAiXCRTUUxMb2dPYmplY3QtPkluc2VydFdvcmQoV2hhdCA9PiBcIlNRTC1TRUxFQ1Q7XCRTUUw7XCRDYWxsZXJcO1wkRGlmZlRpbWVcIik7XG4iICAgID0+IDEsCiAgICAgICAgInVzZSBUaW1lOjpIaVJlcyBxdyhnZXR0aW1lb2ZkYXkgdHZfaW50ZXJ2YWwpO1xuIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9PiAxLAogICAgICAgICJteSBcJHQwID0gW2dldHRpbWVvZmRheV07XG4iICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gMSwKICAgICAgICAibXkgXCREaWZmVGltZSA9IHR2X2ludGVydmFsKFwkdDApO1xuIiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID0+IDEsCiAgICApOwoKICAgIGZvciBteSAkTGluZSAoQExpbmVzKSB7CiAgICAgICAgaWYgKCAhJFJlbW92ZUxpbmV7JExpbmV9ICkgewogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICRMaW5lOwogICAgICAgIH0KICAgIH0KICAgIGNsb3NlICRGaWxlaGFuZGxlSUk7CiAgICByZXR1cm4gMTsKfQoKPWl0ZW0gSW5zZXJ0V29yZCgpCgpTYXZlIGEgd29yZCBpbiB0aGUgdHJhbnNsYXRpb24gZGVidWcgbG9nCgogICAgJEJhY2tlbmRPYmplY3QtPkluc2VydFdvcmQoCiAgICAgICAgV2hhdCA9PiAnYSB3b3JkJywKICAgICk7Cgo9Y3V0CgpzdWIgSW5zZXJ0V29yZCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgY2hlY2sgbmVlZGVkIHN0dWZmCiAgICBpZiAoICEkUGFyYW17V2hhdH0gKSB7CiAgICAgICAgJFNlbGYtPntMb2dPYmplY3R9LT5Mb2coCiAgICAgICAgICAgIFByaW9yaXR5ID0+ICdlcnJvcicsCiAgICAgICAgICAgIE1lc3NhZ2UgID0+ICdOZWVkIFdoYXQhJywKICAgICAgICApOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAjIHNhdmUgdGhlIHdvcmQgaW4gbG9nIGZpbGUKICAgIG15ICRGaWxlID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICcvdmFyL2ZyZWQvU1FMLmxvZyc7CiAgICBvcGVuIG15ICRGaWxlaGFuZGxlLCAnPj4nLCAkRmlsZSB8fCBkaWUgIkNhbid0IHdyaXRlICRGaWxlICFcbiI7CiAgICBwcmludCAkRmlsZWhhbmRsZSAkUGFyYW17V2hhdH0gLiAiXG4iOwogICAgY2xvc2UgJEZpbGVoYW5kbGU7CgogICAgcmV0dXJuIDE7Cn0KCjE7Cgo9YmFjawoKPWhlYWQxIFRFUk1TIEFORCBDT05ESVRJT05TCgpUaGlzIHNvZnR3YXJlIGlzIHBhcnQgb2YgdGhlIE9UUlMgcHJvamVjdCAoaHR0cDovL290cnMub3JnLykuCgpUaGlzIHNvZnR3YXJlIGNvbWVzIHdpdGggQUJTT0xVVEVMWSBOTyBXQVJSQU5UWS4gRm9yIGRldGFpbHMsIHNlZQp0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CmRpZCBub3QgcmVjZWl2ZSB0aGlzIGZpbGUsIHNlZSBodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvYWdwbC50eHQuCgo9Y3V0Cgo9aGVhZDEgVkVSU0lPTgoKJFJldmlzaW9uOiAxLjEyICQgJERhdGU6IDIwMDkvMDQvMjEgMTA6MTM6MTAgJAoKPWN1dAo=
IyAtLQojIEtlcm5lbC9TeXN0ZW0vRnJlZC9Db25maWdMb2cucG0KIyBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwOSBPVFJTIEFHLCBodHRwOi8vb3Rycy5vcmcvCiMgLS0KIyAkSWQ6IENvbmZpZ0xvZy5wbSx2IDEuMTAgMjAwOS8wNC8yMSAxMDoxMzoxMCB0ciBFeHAgJAojIC0tCiMgVGhpcyBzb2Z0d2FyZSBjb21lcyB3aXRoIEFCU09MVVRFTFkgTk8gV0FSUkFOVFkuIEZvciBkZXRhaWxzLCBzZWUKIyB0aGUgZW5jbG9zZWQgZmlsZSBDT1BZSU5HIGZvciBsaWNlbnNlIGluZm9ybWF0aW9uIChBR1BMKS4gSWYgeW91CiMgZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KIyAtLQoKcGFja2FnZSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6Q29uZmlnTG9nOwoKdXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKdXNlIHZhcnMgcXcoJFZFUlNJT04pOwokVkVSU0lPTiA9IHF3KCRSZXZpc2lvbjogMS4xMCAkKSBbMV07Cgo9aGVhZDEgTkFNRQoKS2VybmVsOjpTeXN0ZW06OkZyZWQ6OkNvbmZpZ0xvZwoKPWhlYWQxIFNZTk9QU0lTCgpoYW5kbGUgdGhlIGNvbmZpZyBsb2cgZGF0YQoKPW92ZXIgNAoKPWN1dAoKPWl0ZW0gbmV3KCkKCmNyZWF0ZSBhbiBvYmplY3QKCiAgICB1c2UgS2VybmVsOjpDb25maWc7CiAgICB1c2UgS2VybmVsOjpTeXN0ZW06OkxvZzsKICAgIHVzZSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6Q29uZmlnTG9nOwoKICAgIG15ICRDb25maWdPYmplY3QgPSBLZXJuZWw6OkNvbmZpZy0+bmV3KCk7CiAgICBteSAkTG9nT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkxvZy0+bmV3KAogICAgICAgIENvbmZpZ09iamVjdCA9PiAkQ29uZmlnT2JqZWN0LAogICAgKTsKICAgIG15ICRTbWFsbFByb2ZPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6Q29uZmlnTG9nLT5uZXcoCiAgICAgICAgQ29uZmlnT2JqZWN0ID0+ICRDb25maWdPYmplY3QsCiAgICAgICAgTG9nT2JqZWN0ICAgID0+ICRMb2dPYmplY3QsCiAgICApOwoKPWN1dAoKc3ViIG5ldyB7CiAgICBteSAoICRUeXBlLCAlUGFyYW0gKSA9IEBfOwoKICAgICMgYWxsb2NhdGUgbmV3IGhhc2ggZm9yIG9iamVjdAogICAgbXkgJFNlbGYgPSB7fTsKICAgIGJsZXNzKCAkU2VsZiwgJFR5cGUgKTsKCiAgICAjIGdldCBuZWVkZWQgb2JqZWN0cwogICAgZm9yIG15ICRPYmplY3QgKHF3KENvbmZpZ09iamVjdCBMb2dPYmplY3QpKSB7CiAgICAgICAgaWYgKCAkUGFyYW17JE9iamVjdH0gKSB7CiAgICAgICAgICAgICRTZWxmLT57JE9iamVjdH0gPSAkUGFyYW17JE9iamVjdH07CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAkU2VsZjsKfQoKPWl0ZW0gRGF0YUdldCgpCgpHZXQgdGhlIGRhdGEgZm9yIHRoaXMgZnJlZCBtb2R1bGUuIFJldHVybnMgdHJ1ZSBvciBmYWxzZS4KQW5kIGFkZCB0aGUgZGF0YSB0byB0aGUgbW9kdWxlIHJlZi4KCiAgICAkQmFja2VuZE9iamVjdC0+RGF0YUdldCgKICAgICAgICBNb2R1bGVSZWYgPT4gJE1vZHVsZVJlZiwKICAgICk7Cgo9Y3V0CgpzdWIgRGF0YUdldCB7CiAgICBteSAoICRTZWxmLCAlUGFyYW0gKSA9IEBfOwoKICAgIG15IEBMb2dNZXNzYWdlczsKCiAgICAjIG9wZW4gdGhlIFRyYW5zbGF0aW9uRGVidWcubG9nIGZpbGUgdG8gZ2V0IHRoZSB1bnRyYW5zbGF0ZWQgd29yZHMKICAgIG15ICRGaWxlID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKSAuICcvdmFyL2ZyZWQvQ29uZmlnLmxvZyc7CiAgICBteSAkRmlsZWhhbmRsZTsKICAgIGlmICggIW9wZW4gJEZpbGVoYW5kbGUsICc8JywgJEZpbGUgKSB7CiAgICAgICAgcHJpbnQgU1RERVJSICJQZXJoYXBzIHlvdSBkb24ndCBoYXZlIHBlcm1pc3Npb24gYXQgL3Zhci9mcmVkL1xuIiAuCiAgICAgICAgICAgICJDYW4ndCByZWFkIC92YXIvZnJlZC9Db25maWcubG9nIjsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgIyBnZXQgdGhlIHdob2xlIGluZm9ybWF0aW9uCiAgICBMSU5FOgogICAgZm9yIG15ICRMaW5lICggcmV2ZXJzZSA8JEZpbGVoYW5kbGU+ICkgewogICAgICAgIGxhc3QgTElORSBpZiAkTGluZSA9fiAvRlJFRC87CiAgICAgICAgcHVzaCBATG9nTWVzc2FnZXMsICRMaW5lOwogICAgfQoKICAgIGNsb3NlICRGaWxlaGFuZGxlOwogICAgcG9wIEBMb2dNZXNzYWdlczsKICAgICRTZWxmLT5JbnNlcnRXb3JkKCBXaGF0ID0+ICJGUkVEXG4iICk7CgogICAgbXkgJUluZGl2aWR1YWxDb25maWcgPSAoKTsKCiAgICBmb3IgbXkgJExpbmUgKEBMb2dNZXNzYWdlcykgewogICAgICAgICRMaW5lID1+IHMvXG4vLzsKICAgICAgICAkSW5kaXZpZHVhbENvbmZpZ3skTGluZX0rKzsKICAgIH0KCiAgICBATG9nTWVzc2FnZXMgPSAoKTsKICAgIGZvciBteSAkTGluZSAoIGtleXMgJUluZGl2aWR1YWxDb25maWcgKSB7CiAgICAgICAgbXkgQFNwbGl0ZWRMaW5lID0gc3BsaXQgLzsvLCAkTGluZTsKICAgICAgICBwdXNoIEBTcGxpdGVkTGluZSwgJEluZGl2aWR1YWxDb25maWd7JExpbmV9OwogICAgICAgIHB1c2ggQExvZ01lc3NhZ2VzLCBcQFNwbGl0ZWRMaW5lOwogICAgfQoKICAgICMgc29ydCB0aGUgZGF0YQogICAgbXkgJENvbmZpZ19SZWYgPSAkU2VsZi0+e0NvbmZpZ09iamVjdH0tPkdldCgnRnJlZDo6Q29uZmlnTG9nJyk7CiAgICBteSAkT3JkZXJCeSA9IGRlZmluZWQoICRDb25maWdfUmVmLT57T3JkZXJCeX0gKSA/ICRDb25maWdfUmVmLT57T3JkZXJCeX0gOiAzOwogICAgaWYgKCAkT3JkZXJCeSA9PSAzICkgewogICAgICAgIEBMb2dNZXNzYWdlcyA9IHNvcnQgeyAkYi0+WyRPcmRlckJ5XSA8PT4gJGEtPlskT3JkZXJCeV0gfSBATG9nTWVzc2FnZXM7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBATG9nTWVzc2FnZXMgPSBzb3J0IHsgJGEtPlskT3JkZXJCeV0gY21wICRiLT5bJE9yZGVyQnldIH0gQExvZ01lc3NhZ2VzOwogICAgfQoKICAgICRQYXJhbXtNb2R1bGVSZWZ9LT57RGF0YX0gPSBcQExvZ01lc3NhZ2VzOwogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIEFjdGl2YXRlTW9kdWxlVG9kb3MoKQoKRG8gYWxsIGpvYnMgd2hpY2ggYXJlIG5lY2Vzc2FyeSB0byBhY3RpdmF0ZSB0aGlzIHNwZWNpYWwgbW9kdWxlLgoKICAgICRGcmVkT2JqZWN0LT5BY3RpdmF0ZU1vZHVsZVRvZG9zKAogICAgICAgIE1vZHVsZU5hbWUgPT4gJE1vZHVsZU5hbWUsCiAgICApOwoKPWN1dAoKc3ViIEFjdGl2YXRlTW9kdWxlVG9kb3MgewogICAgbXkgJFNlbGYgPSBzaGlmdDsKCiAgICBteSBATGluZXMgPSAoKTsKCiAgICBteSAkRmlsZSA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAnL0tlcm5lbC9Db25maWcvRGVmYXVsdHMucG0nOwoKICAgICMgY2hlY2sgaWYgaXQgaXMgYW4gc3ltbGluaywgYmVjYXVzZSBpdCBjYW4gYmUgZGV2ZWxvcG1lbnQgc3lzdGVtIHdoaWNoIHVzZSBzeW1saW5rcwogICAgZGllICJDYW4ndCBtYW5pcHVsYXRlICRGaWxlIGJlY2F1c2UgaXQgaXMgYSBzeW1saW5rISIgaWYgLWwgJEZpbGU7CgogICAgIyB0byB1c2UgVHJhbnNsYXRpb25EZWJ1ZyBJIGhhdmUgdG8gbWFuaXB1bGF0ZSB0aGUgTGFuZ3VhZ2UucG0gZmlsZQogICAgb3BlbiBteSAkRmlsZWhhbmRsZSwgJzwnLCAkRmlsZSB8fCBkaWUgIkNhbid0IG9wZW4gJEZpbGUgIVxuIjsKICAgIEBMaW5lcyA9IDwkRmlsZWhhbmRsZT47CiAgICBjbG9zZSAkRmlsZWhhbmRsZTsKCiAgICBvcGVuIG15ICRGaWxlaGFuZGxlSUksICc+JywgJEZpbGUgfHwgZGllICJDYW4ndCB3cml0ZSAkRmlsZSAhXG4iOwogICAgbXkgJFN1YkdldCA9ICcnOwogICAgZm9yIG15ICRMaW5lIChATGluZXMpIHsKICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICRMaW5lOwogICAgICAgIGlmICggJExpbmUgPX4gL3N1YiBHZXQvICkgewogICAgICAgICAgICAkU3ViR2V0ID0gIkdldCI7CiAgICAgICAgfQogICAgICAgIGlmICggJFN1YkdldCBlcSAnR2V0JyAmJiAkTGluZSA9fiAvbXkgXCRTZWxmID0gc2hpZnQ7LyApIHsKICAgICAgICAgICAgJFN1YkdldCAuPSAnU2VsZic7CiAgICAgICAgfQogICAgICAgIGlmICgKICAgICAgICAgICAgKCAkU3ViR2V0IGVxICdHZXRTZWxmJyAmJiAkTGluZSA9fiAvbXkgXCRXaGF0ID0gc2hpZnQ7LyApICAgICMgT1RSUyAyLjIKICAgICAgICAgICAgfHwgJFN1YkdldCBlcSAnR2V0JyAmJiAkTGluZSA9fiAvbXkgXCggXCRTZWxmLCBcJFdoYXQgXCkgPSBcQF87LwogICAgICAgICAgICApCiAgICAgICAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIE9UUlMgMi4zCiAgICAgICAgICAgIHByaW50ICRGaWxlaGFuZGxlSUkgIiMgRlJFRCAtIG1hbmlwdWxhdGVkXG4iOwogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICJ1c2UgS2VybmVsOjpTeXN0ZW06OkZyZWQ6OkNvbmZpZ0xvZztcbiI7CiAgICAgICAgICAgIHByaW50ICRGaWxlaGFuZGxlSUkgIm15IFwkQ29uZmlnTG9nT2JqZWN0ID0gS2VybmVsOjpTeXN0ZW06OkZyZWQ6OkNvbmZpZ0xvZy0+bmV3KCk7XG4iOwogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICJteSBcJENhbGxlciA9IGNhbGxlcigpO1xuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAiaWYgKFwkU2VsZi0+e1wkV2hhdH0pIHsgIyBGUkVEIC0gbWFuaXB1bGF0ZWRcbiI7CiAgICAgICAgICAgIHByaW50ICRGaWxlaGFuZGxlSUkKICAgICAgICAgICAgICAgICIgICAgXCRDb25maWdMb2dPYmplY3QtPkluc2VydFdvcmQoV2hhdCA9PiBcIlwkV2hhdDtUcnVlO1wkQ2FsbGVyO1wiLCBIb21lID0+IFwkU2VsZi0+e0hvbWV9KTtcbiI7CiAgICAgICAgICAgIHByaW50ICRGaWxlaGFuZGxlSUkgIn0gICAgICAgICAgICAgICAgICAgICAjIEZSRUQgLSBtYW5pcHVsYXRlZFxuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAiZWxzZSB7ICAgICAgICAgICAgICAgICMgRlJFRCAtIG1hbmlwdWxhdGVkXG4iOwogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJCiAgICAgICAgICAgICAgICAiICAgIFwkQ29uZmlnTG9nT2JqZWN0LT5JbnNlcnRXb3JkKFdoYXQgPT4gXCJcJFdoYXQ7RmFsc2U7XCRDYWxsZXI7XCIsIEhvbWUgPT4gXCRTZWxmLT57SG9tZX0pO1xuIjsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAifSAgICAgICAgICAgICAgICAgICAgICMgRlJFRCAtIG1hbmlwdWxhdGVkXG4iOwogICAgICAgICAgICBwcmludCAkRmlsZWhhbmRsZUlJICIjIEZSRUQgLSBtYW5pcHVsYXRlZFxuIjsKICAgICAgICB9CiAgICB9CiAgICBjbG9zZSAkRmlsZWhhbmRsZUlJOwoKICAgIHJldHVybiAxOwp9Cgo9aXRlbSBEZWFjdGl2YXRlTW9kdWxlVG9kb3MoKQoKRG8gYWxsIGpvYnMgd2hpY2ggYXJlIG5lY2Vzc2FyeSB0byBkZWFjdGl2YXRlIHRoaXMgc3BlY2lhbCBtb2R1bGUuCgogICAgJEZyZWRPYmplY3QtPkRlYWN0aXZhdGVNb2R1bGVUb2RvcygKICAgICAgICBNb2R1bGVOYW1lID0+ICRNb2R1bGVOYW1lLAogICAgKTsKCj1jdXQKCnN1YiBEZWFjdGl2YXRlTW9kdWxlVG9kb3MgewogICAgbXkgJFNlbGYgPSBzaGlmdDsKCiAgICBteSBATGluZXMgPSAoKTsKICAgIG15ICRGaWxlICA9ICRTZWxmLT57Q29uZmlnT2JqZWN0fS0+R2V0KCdIb21lJykgLiAnL0tlcm5lbC9Db25maWcvRGVmYXVsdHMucG0nOwoKICAgICMgY2hlY2sgaWYgaXQgaXMgYW4gc3ltbGluaywgYmVjYXVzZSBpdCBjYW4gYmUgZGV2ZWxvcG1lbnQgc3lzdGVtIHdoaWNoIHVzZSBzeW1saW5rcwogICAgaWYgKCAtbCAiJEZpbGUiICkgewogICAgICAgIGRpZSAiQ2FuJ3QgbWFuaXB1bGF0ZSAkRmlsZSBiZWNhdXNlIGl0IGlzIGEgc3ltbGluayEiOwogICAgfQoKICAgICMgdG8gdXNlIFRyYW5zbGF0aW9uRGVidWdnZXIgSSBoYXZlIHRvIG1hbmlwdWxhdGUgdGhlIExhbmd1YWdlLnBtIGZpbGUKICAgICMgaGVyZSBJIHVuZG8gbXkgbWFuaXB1bGF0aW9uCiAgICBvcGVuIG15ICRGaWxlaGFuZGxlLCAnPCcsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgb3BlbiAkRmlsZSAhXG4iOwogICAgd2hpbGUgKCBteSAkTGluZSA9IDwkRmlsZWhhbmRsZT4gKSB7CiAgICAgICAgcHVzaCBATGluZXMsICRMaW5lOwogICAgfQogICAgY2xvc2UgJEZpbGVoYW5kbGU7CgogICAgb3BlbiBteSAkRmlsZWhhbmRsZUlJLCAnPicsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgd3JpdGUgJEZpbGUgIVxuIjsKCiAgICBteSAlUmVtb3ZlTGluZSA9ICgKICAgICAgICAiIyBGUkVEIC0gbWFuaXB1bGF0ZWRcbiIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gMSwKICAgICAgICAidXNlIEtlcm5lbDo6U3lzdGVtOjpGcmVkOjpDb25maWdMb2c7XG4iICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gMSwKICAgICAgICAibXkgXCRDb25maWdMb2dPYmplY3QgPSBLZXJuZWw6OlN5c3RlbTo6RnJlZDo6Q29uZmlnTG9nLT5uZXcoKTtcbiIgPT4gMSwKICAgICAgICAibXkgXCRDYWxsZXIgPSBjYWxsZXIoKTtcbiIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPT4gMSwKICAgICAgICAiaWYgKFwkU2VsZi0+e1wkV2hhdH0pIHsgIyBGUkVEIC0gbWFuaXB1bGF0ZWRcbiIgICAgICAgICAgICAgICAgICAgPT4gMSwKICAgICAgICAiICAgIFwkQ29uZmlnTG9nT2JqZWN0LT5JbnNlcnRXb3JkKFdoYXQgPT4gXCJcJFdoYXQ7VHJ1ZTtcJENhbGxlcjtcIiwgSG9tZSA9PiBcJFNlbGYtPntIb21lfSk7XG4iCiAgICAgICAgICAgID0+IDEsCiAgICAgICAgIn0gICAgICAgICAgICAgICAgICAgICAjIEZSRUQgLSBtYW5pcHVsYXRlZFxuIiA9PiAxLAogICAgICAgICJlbHNlIHsgICAgICAgICAgICAgICAgIyBGUkVEIC0gbWFuaXB1bGF0ZWRcbiIgPT4gMSwKICAgICAgICAiICAgIFwkQ29uZmlnTG9nT2JqZWN0LT5JbnNlcnRXb3JkKFdoYXQgPT4gXCJcJFdoYXQ7RmFsc2U7XCRDYWxsZXI7XCIsIEhvbWUgPT4gXCRTZWxmLT57SG9tZX0pO1xuIgogICAgICAgICAgICA9PiAxLAogICAgKTsKCiAgICBmb3IgbXkgJExpbmUgKEBMaW5lcykgewogICAgICAgIGlmICggISRSZW1vdmVMaW5leyRMaW5lfSApIHsKICAgICAgICAgICAgcHJpbnQgJEZpbGVoYW5kbGVJSSAkTGluZTsKICAgICAgICB9CiAgICB9CiAgICBjbG9zZSAkRmlsZWhhbmRsZUlJOwogICAgcmV0dXJuIDE7Cn0KCj1pdGVtIEluc2VydFdvcmQoKQoKU2F2ZSBhIHdvcmQgaW4gdGhlIHRyYW5zbGF0aW9uIGRlYnVnIGxvZwoKICAgICRCYWNrZW5kT2JqZWN0LT5JbnNlcnRXb3JkKAogICAgICAgIFdoYXQgPT4gJ2Egd29yZCcsCiAgICApOwoKPWN1dAoKc3ViIEluc2VydFdvcmQgewogICAgbXkgKCAkU2VsZiwgJVBhcmFtICkgPSBAXzsKCiAgICBpZiAoICEkUGFyYW17SG9tZX0gKSB7CiAgICAgICAgJFBhcmFte0hvbWV9ID0gJFNlbGYtPntDb25maWdPYmplY3R9LT5HZXQoJ0hvbWUnKTsKICAgIH0KCiAgICAjIHNhdmUgdGhlIHdvcmQgaW4gbG9nIGZpbGUKICAgIG15ICRGaWxlID0gJFBhcmFte0hvbWV9IC4gJy92YXIvZnJlZC9Db25maWcubG9nJzsKICAgIG9wZW4gbXkgJEZpbGVoYW5kbGUsICc+PicsICRGaWxlIHx8IGRpZSAiQ2FuJ3Qgd3JpdGUgJEZpbGUgIVxuIjsKICAgIHByaW50ICRGaWxlaGFuZGxlICRQYXJhbXtXaGF0fSAuICJcbiI7CiAgICBjbG9zZSAkRmlsZWhhbmRsZTsKCiAgICByZXR1cm4gMTsKfQoKMTsKCj1iYWNrCgo9aGVhZDEgVEVSTVMgQU5EIENPTkRJVElPTlMKClRoaXMgc29mdHdhcmUgaXMgcGFydCBvZiB0aGUgT1RSUyBwcm9qZWN0IChodHRwOi8vb3Rycy5vcmcvKS4KClRoaXMgc29mdHdhcmUgY29tZXMgd2l0aCBBQlNPTFVURUxZIE5PIFdBUlJBTlRZLiBGb3IgZGV0YWlscywgc2VlCnRoZSBlbmNsb3NlZCBmaWxlIENPUFlJTkcgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24gKEFHUEwpLiBJZiB5b3UKZGlkIG5vdCByZWNlaXZlIHRoaXMgZmlsZSwgc2VlIGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy9hZ3BsLnR4dC4KCj1jdXQKCj1oZWFkMSBWRVJTSU9OCgokUmV2aXNpb246IDEuMTAgJCAkRGF0ZTogMjAwOS8wNC8yMSAxMDoxMzoxMCAkCgo9Y3V0Cg==