LyoKKiBDb3B5cmlnaHQgqSB7MTk5Ni0xOTk5fSwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcyBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCioKKiBGaWxlIHRibGNvbGwuaAoqCiogQ3JlYXRlZCBieTogSGVsZW5hIFNoaWgKKgoqIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgoqCiogIERhdGUgICAgICAgIE5hbWUgICAgICAgIERlc2NyaXB0aW9uCiogIDIvNS85NyAgICAgIGFsaXUgICAgICAgIEFkZGVkIHN0cmVhbUluIGFuZCBzdHJlYW1PdXQgbWV0aG9kcy4gIEFkZGVkCiogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yIHdoaWNoIHJlYWRzIFJ1bGVCYXNlZENvbGxhdG9yIG9iamVjdCBmcm9tCiogICAgICAgICAgICAgICAgICAgICAgICAgIGEgYmluYXJ5IGZpbGUuICBBZGRlZCB3cml0ZVRvRmlsZSBtZXRob2Qgd2hpY2ggc3RyZWFtcwoqICAgICAgICAgICAgICAgICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvciBvdXQgdG8gYSBiaW5hcnkgZmlsZS4gIFRoZSBzdHJlYW1JbgoqICAgICAgICAgICAgICAgICAgICAgICAgICBhbmQgc3RyZWFtT3V0IG1ldGhvZHMgdXNlIGlzdHJlYW0gYW5kIG9zdHJlYW0gb2JqZWN0cwoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbiBiaW5hcnkgbW9kZS4KKiAgMi8xMi85NyAgICAgYWxpdSAgICAgICAgTW9kaWZpZWQgdG8gdXNlIFRhYmxlQ29sbGF0aW9uRGF0YSBzdWItb2JqZWN0IHRvCiogICAgICAgICAgICAgICAgICAgICAgICAgIGhvbGQgaW52YXJpYW50IGRhdGEuCiogIDIvMTMvOTcgICAgIGFsaXUgICAgICAgIE1vdmVkIHNldmVyYWwgbWV0aG9kcyBpbnRvIHRoaXMgY2xhc3MgZnJvbSBDb2xsYXRpb24uCiogICAgICAgICAgICAgICAgICAgICAgICAgIEFkZGVkIGEgcHJpdmF0ZSBSdWxlQmFzZWRDb2xsYXRvcihMb2NhbGUmKSBjb25zdHJ1Y3RvciwKKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gYmUgdXNlZCBieSBDb2xsYXRvcjo6Y3JlYXRlRGVmYXVsdCgpLiAgR2VuZXJhbAoqICAgICAgICAgICAgICAgICAgICAgICAgICBjbGVhbiB1cC4KKiAgMi8yMC85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgY2xvbmUsIG9wZXJhdG9yPT0sIG9wZXJhdG9yIT0sIG9wZXJhdG9yPSwgYW5kIGNvcHkKKiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RydWN0b3IgYW5kIGdldER5bmFtaWNDbGFzc0lELgoqICAzLzUvOTcgICAgICBhbGl1ICAgICAgICBNb2RpZmllZCBjb25zdHJ1Y3RGcm9tRmlsZSgpIHRvIGFkZCBwYXJhbWV0ZXIKKiAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlY2lmeWluZyB3aGV0aGVyIG9yIG5vdCBiaW5hcnkgbG9hZGluZyBpcyB0byBiZQoqICAgICAgICAgICAgICAgICAgICAgICAgICBhdHRlbXB0ZWQuICBUaGlzIGlzIHJlcXVpcmVkIGZvciBkeW5hbWljIHJ1bGUgbG9hZGluZy4KKiAwNS8wNy85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgbWVtb3J5IGFsbG9jYXRpb24gZXJyb3IgZGV0ZWN0aW9uLgoqICA2LzE3Lzk3ICAgICBoZWxlbmEgICAgICBBZGRlZCBJREVOVElDQUwgc3RyZW5ndGggZm9yIGNvbXBhcmUsIGNoYW5nZWQgZ2V0UnVsZXMgdG8gCiogICAgICAgICAgICAgICAgICAgICAgICAgIHVzZSBNZXJnZUNvbGxhdGlvbjo6Z2V0UGF0dGVybi4KKiAgNi8yMC85NyAgICAgaGVsZW5hICAgICAgSmF2YSBjbGFzcyBuYW1lIGNoYW5nZS4KKiAgOC8xOC85NyAgICAgaGVsZW5hICAgICAgQWRkZWQgaW50ZXJuYWwgQVBJIGRvY3VtZW50YXRpb24uCiogMDkvMDMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGVkIGNyZWF0ZUNvbGxhdGlvbktleVZhbHVlcygpLgoqIDAyLzEwLzk4ICAgICBkYW1pYmEgICAgICBBZGRlZCBjb21wYXJlIHdpdGggImxlbmd0aCIgcGFyYW1ldGVyCiogMDgvMDUvOTggICAgIGVybSAgICAgICAgIFN5bmNoZWQgd2l0aCAxLjIgdmVyc2lvbiBvZiBSdWxlQmFzZWRDb2xsYXRvci5qYXZhCiogMDQvMjMvOTkgICAgIHN0ZXBoZW4gICAgIFJlbW92ZWQgRURlY29tcG9zaXRpb25Nb2RlLCBtZXJnZWQgd2l0aAoqICAgICAgICAgICAgICAgICAgICAgICAgICBOb3JtYWxpemVyOjpFTW9kZQoqIDA2LzE0Lzk5ICAgICBzdGVwaGVuICAgICBSZW1vdmVkIGtSZXNvdXJjZUJ1bmRsZVN1ZmZpeAoqIDExLzAyLzk5ICAgICBoZWxlbmEgICAgICBDb2xsYXRvciBwZXJmb3JtYW5jZSBlbmhhbmNlbWVudHMuICBFbGltaW5hdGVzIHRoZSAKKiAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBjb25zdHJ1Y3Rpb24gYW5kIHNwZWNpYWwgY2FzZSBmb3IgTk9fT1AuCiogMTEvMjMvOTkgICAgIHNybCAgICAgICAgIE1vcmUgcGVyZm9ybWFuY2UgZW5oYW5jZW1lbnRzLiBVcGRhdGVzIHRvIE5vcm1hbGl6ZXJJdGVyYXRvcgoqICAgICAgICAgICAgICAgICAgICAgICAgICBpbnRlcm5hbCBzdGF0ZSBtYW5hZ2VtZW50LgoqIDEyLzE1Lzk5ICAgICBhbGl1ICAgICAgICBVcGRhdGUgdG8gc3VwcG9ydCBUaGFpIGNvbGxhdGlvbi4gIE1vdmUgTm9ybWFsaXplckl0ZXJhdG9yCiogICAgICAgICAgICAgICAgICAgICAgICAgIHRvIGltcGxlbWVudGF0aW9uIGZpbGUuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKi8KCiNpZm5kZWYgVEJMQ09MTF9ICiNkZWZpbmUgVEJMQ09MTF9ICgojaW5jbHVkZSAidW5pY29kZS91dHlwZXMuaCIKI2luY2x1ZGUgInVuaWNvZGUvY29sbC5oIgojaW5jbHVkZSAidW5pY29kZS9jaGFyaXRlci5oIgojaW5jbHVkZSAidW5pY29kZS91bmlzdHIuaCIKI2luY2x1ZGUgInVuaWNvZGUvc29ydGtleS5oIgojaW5jbHVkZSAidW5pY29kZS9ub3JtbHpyLmgiCgpjbGFzcyBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudDsKY2xhc3MgVmVjdG9yT2ZJbnQ7CmNsYXNzIFZlY3Rvck9mUFRvQ29udHJhY3RUYWJsZTsKY2xhc3MgVmVjdG9yT2ZQVG9FeHBhbmRUYWJsZTsKY2xhc3MgTWVyZ2VDb2xsYXRpb247CmNsYXNzIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjsKY2xhc3MgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjsKY2xhc3MgTm9ybWFsaXplckl0ZXJhdG9yOyAvLyBzZWUgdGJsY29sbC5jcHAKY2xhc3MgQ29sbGF0b3I7CmNsYXNzIFRhYmxlQ29sbGF0aW9uRGF0YTsKCi8qKgogKiBUaGUgUnVsZUJhc2VkQ29sbGF0b3IgY2xhc3MgcHJvdmlkZXMgdGhlIHNpbXBsZSBpbXBsZW1lbnRhdGlvbiBvZiBDb2xsYXRvciwKICogdXNpbmcgZGF0YS1kcml2ZW4gdGFibGVzLiAgVGhlIHVzZXIgY2FuIGNyZWF0ZSBhIGN1c3RvbWl6ZWQgdGFibGUtYmFzZWQKICogY29sbGF0aW9uLgogKiA8UD4KICogUnVsZUJhc2VkQ29sbGF0b3IgbWFwcyBjaGFyYWN0ZXJzIHRvIGNvbGxhdGlvbiBrZXlzLgogKiA8cD4KICogVGFibGUgQ29sbGF0aW9uIGhhcyB0aGUgZm9sbG93aW5nIHJlc3RyaWN0aW9ucyBmb3IgZWZmaWNpZW5jeSAob3RoZXIKICogc3ViY2xhc3NlcyBtYXkgYmUgdXNlZCBmb3IgbW9yZSBjb21wbGV4IGxhbmd1YWdlcykgOgogKiAgICAgICA8cD4xLiBJZiB0aGUgRnJlbmNoIHNlY29uZGFyeSBvcmRlcmluZyBpcyBzcGVjaWZpZWQgaW4gYSBjb2xsYXRpb24gb2JqZWN0LCAKICogICAgICAgICAgICAgaXQgaXMgYXBwbGllZCB0byB0aGUgd2hvbGUgb2JqZWN0LgogKiAgICAgICA8cD4yLiBBbGwgbm9uLW1lbnRpb25lZCBVbmljb2RlIGNoYXJhY3RlcnMgYXJlIGF0IHRoZSBlbmQgb2YgdGhlCiAqICAgICAgICAgICAgIGNvbGxhdGlvbiBvcmRlci4KICogICAgICAgPHA+My4gUHJpdmF0ZSB1c2UgY2hhcmFjdGVycyBhcmUgdHJlYXRlZCBhcyBpZGVudGljYWwuICBUaGUgcHJpdmF0ZQogKiAgICAgICAgICAgICB1c2UgYXJlYSBpbiBVbmljb2RlIGlzIDB4RTgwMC0weEY4RkYuCiAqIDxwPlRoZSBjb2xsYXRpb24gdGFibGUgaXMgY29tcG9zZWQgb2YgYSBsaXN0IG9mIGNvbGxhdGlvbiBydWxlcywgd2hlcmUgZWFjaAogKiBydWxlIGlzIG9mIHRocmVlIGZvcm1zOgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgPG1vZGlmaWVyID4KICogICAgIDxyZWxhdGlvbiA+ICZsdDsgdGV4dC1hcmd1bWVudCA+CiAqICAgICA8cmVzZXQgPiAmbHQ7IHRleHQtYXJndW1lbnQgPgogKiBcZW5kY29kZQogKiA8L3ByZT4KICogVGhlIGZvbGxvd2luZyBkZW1vbnN0cmF0ZXMgaG93IHRvIGNyZWF0ZSB5b3VyIG93biBjb2xsYXRpb24gcnVsZXM6CiAqIDxVTCBUeXBlPXJvdW5kPgogKiAgICA8TEk+PHN0cm9uZz5UZXh0IEFyZ3VtZW50PC9zdHJvbmc+OiBBIHRleHQgYXJndW1lbnQgaXMgYW55IHNlcXVlbmNlIG9mCiAqICAgICAgICBjaGFyYWN0ZXJzLCBleGNsdWRpbmcgc3BlY2lhbCBjaGFyYWN0ZXJzICh0aGF0IGlzLCB3aGl0ZXNwYWNlCiAqICAgICAgICBjaGFyYWN0ZXJzIGFuZCB0aGUgY2hhcmFjdGVycyB1c2VkIGluIG1vZGlmaWVyLCByZWxhdGlvbiBhbmQgcmVzZXQpLgogKiAgICAgICAgSWYgdGhvc2UgY2hhcmFjdGVycyBhcmUgZGVzaXJlZCwgeW91IGNhbiBwdXQgdGhlbSBpbiBzaW5nbGUgcXVvdGVzCiAqICAgICAgICAoZS5nLiBhbXBlcnNhbmQgPT4gJyYnKS48UD4KICogICAgPExJPjxzdHJvbmc+TW9kaWZpZXI8L3N0cm9uZz46IFRoZXJlIGlzIGEgc2luZ2xlIG1vZGlmaWVyLAogKiAgICAgICAgd2hpY2ggaXMgdXNlZCB0byBzcGVjaWZ5IHRoYXQgYWxsIHNlY29uZGFyeSBkaWZmZXJlbmNlcyBhcmUKICogICAgICAgIHNvcnRlZCBiYWNrd2FyZHMuCiAqICAgICAgICA8cD4nQCcgOiBJbmRpY2F0ZXMgdGhhdCBzZWNvbmRhcnkgZGlmZmVyZW5jZXMsIHN1Y2ggYXMgYWNjZW50cywgYXJlIAogKiAgICAgICAgICAgICAgICAgc29ydGVkIGJhY2t3YXJkcywgYXMgaW4gRnJlbmNoLjxQPgogKiAgICA8TEk+PHN0cm9uZz5SZWxhdGlvbjwvc3Ryb25nPjogVGhlIHJlbGF0aW9ucyBhcmUgdGhlIGZvbGxvd2luZzoKICogICAgICAgIDxVTCBUeXBlPXNxdWFyZT4KICogICAgICAgICAgICA8TEk+JyZsdDsnIDogR3JlYXRlciwgYXMgYSBsZXR0ZXIgZGlmZmVyZW5jZSAocHJpbWFyeSkKICogICAgICAgICAgICA8TEk+JzsnIDogR3JlYXRlciwgYXMgYW4gYWNjZW50IGRpZmZlcmVuY2UgKHNlY29uZGFyeSkKICogICAgICAgICAgICA8TEk+JywnIDogR3JlYXRlciwgYXMgYSBjYXNlIGRpZmZlcmVuY2UgKHRlcnRpYXJ5KQogKiAgICAgICAgICAgIDxMST4nPScgOiBFcXVhbAogKiAgICAgICAgPC9VTD48UD4KICogICAgPExJPjxzdHJvbmc+UmVzZXQ8L3N0cm9uZz46IFRoZXJlIGlzIGEgc2luZ2xlIHJlc2V0LAogKiAgICAgICAgd2hpY2ggaXMgdXNlZCBwcmltYXJpbHkgZm9yIGNvbnRyYWN0aW9ucyBhbmQgZXhwYW5zaW9ucywgYnV0IHdoaWNoCiAqICAgICAgICBjYW4gYWxzbyBiZSB1c2VkIHRvIGFkZCBhIG1vZGlmaWNhdGlvbiBhdCB0aGUgZW5kIG9mIGEgc2V0IG9mIHJ1bGVzLgogKiAgICAgICAgPHA+JyYnIDogSW5kaWNhdGVzIHRoYXQgdGhlIG5leHQgcnVsZSBmb2xsb3dzIHRoZSBwb3NpdGlvbiB0byB3aGVyZQogKiAgICAgICAgICAgIHRoZSByZXNldCB0ZXh0LWFyZ3VtZW50IHdvdWxkIGJlIHNvcnRlZC4KICogPC9VTD4KICoKICogPHA+CiAqIFRoaXMgc291bmRzIG1vcmUgY29tcGxpY2F0ZWQgdGhhbiBpdCBpcyBpbiBwcmFjdGljZS4gRm9yIGV4YW1wbGUsIHRoZQogKiBmb2xsb3dpbmcgYXJlIGVxdWl2YWxlbnQgd2F5cyBvZiBleHByZXNzaW5nIHRoZSBzYW1lIHRoaW5nOgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgYSA8IGIgPCBjCiAqICAgICBhIDwgYiAmIGIgIDwgYwogKiAgICAgYSA8IGMgJiBhICA8IGIKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIE5vdGljZSB0aGF0IHRoZSBvcmRlciBpcyBpbXBvcnRhbnQsIGFzIHRoZSBzdWJzZXF1ZW50IGl0ZW0gZ29lcyBpbW1lZGlhdGVseQogKiBhZnRlciB0aGUgdGV4dC1hcmd1bWVudC4gVGhlIGZvbGxvd2luZyBhcmUgbm90IGVxdWl2YWxlbnQ6CiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICBhIDwgIGIgJiBhICA8IGMKICogICAgIGEgPCAgYyAmIGEgIDwgYgogKiBcZW5kY29kZQogKiA8L3ByZT4KICogRWl0aGVyIHRoZSB0ZXh0LWFyZ3VtZW50IG11c3QgYWxyZWFkeSBiZSBwcmVzZW50IGluIHRoZSBzZXF1ZW5jZSwgb3Igc29tZQogKiBpbml0aWFsIHN1YnN0cmluZyBvZiB0aGUgdGV4dC1hcmd1bWVudCBtdXN0IGJlIHByZXNlbnQuIChlLmcuICJhICZsdDsgYiAmIGFlICZsdDsKICogZSIgaXMgdmFsaWQgc2luY2UgImEiIGlzIHByZXNlbnQgaW4gdGhlIHNlcXVlbmNlIGJlZm9yZSAiYWUiIGlzIHJlc2V0KS4gSW4KICogdGhpcyBsYXR0ZXIgY2FzZSwgImFlIiBpcyBub3QgZW50ZXJlZCBhbmQgdHJlYXRlZCBhcyBhIHNpbmdsZSBjaGFyYWN0ZXI7CiAqIGluc3RlYWQsICJlIiBpcyBzb3J0ZWQgYXMgaWYgaXQgd2VyZSBleHBhbmRlZCB0byB0d28gY2hhcmFjdGVyczogImEiCiAqIGZvbGxvd2VkIGJ5IGFuICJlIi4gVGhpcyBkaWZmZXJlbmNlIGFwcGVhcnMgaW4gbmF0dXJhbCBsYW5ndWFnZXM6IGluCiAqIHRyYWRpdGlvbmFsIFNwYW5pc2ggImNoIiBpcyB0cmVhdGVkIGFzIHRob3VnaCBpdCBjb250cmFjdHMgdG8gYSBzaW5nbGUKICogY2hhcmFjdGVyIChleHByZXNzZWQgYXMgImMgJmx0OyBjaCAmbHQ7IGQiKSwgd2hpbGUgaW4gdHJhZGl0aW9uYWwgR2VybWFuICLkIgogKiAoYS11bWxhdXQpIGlzIHRyZWF0ZWQgYXMgdGhvdWdoIGl0IGV4cGFuZHMgdG8gdHdvIGNoYXJhY3RlcnMgKGV4cHJlc3NlZCBhcwogKiAiYSAmIGFlIDsg5CAmbHQ7IGIiKS4KICogPHA+PHN0cm9uZz5JZ25vcmFibGUgQ2hhcmFjdGVyczwvc3Ryb25nPgogKiA8cD5Gb3IgaWdub3JhYmxlIGNoYXJhY3RlcnMsIHRoZSBmaXJzdCBydWxlIG11c3Qgc3RhcnQgd2l0aCBhIHJlbGF0aW9uICh0aGUKICogZXhhbXBsZXMgd2UgaGF2ZSB1c2VkIGFib3ZlIGFyZSByZWFsbHkgZnJhZ21lbnRzOyAiYSAmbHQ7IGIiIHJlYWxseSBzaG91bGQgYmUKICogIiZsdDsgYSAmbHQ7IGIiKS4gSWYsIGhvd2V2ZXIsIHRoZSBmaXJzdCByZWxhdGlvbiBpcyBub3QgIiZsdDsiLCB0aGVuIGFsbCB0aGUgCiAqIHRleHQtYXJndW1lbnRzIHVwIHRvIHRoZSBmaXJzdCAiJmx0OyIgYXJlIGlnbm9yYWJsZS4gRm9yIGV4YW1wbGUsICIsIC0gJmx0OyBhICZsdDsgYiIKICogbWFrZXMgIi0iIGFuIGlnbm9yYWJsZSBjaGFyYWN0ZXIsIGFzIHdlIHNhdyBlYXJsaWVyIGluIHRoZSB3b3JkCiAqICJibGFjay1iaXJkcyIuIEluIHRoZSBzYW1wbGVzIGZvciBkaWZmZXJlbnQgbGFuZ3VhZ2VzLCB5b3Ugc2VlIHRoYXQgbW9zdAogKiBhY2NlbnRzIGFyZSBpZ25vcmFibGUuCiAqIDxwPjxzdHJvbmc+Tm9ybWFsaXphdGlvbiBhbmQgQWNjZW50czwvc3Ryb25nPgogKiA8cD5UaGUgQ29sbGF0b3Igb2JqZWN0IGF1dG9tYXRpY2FsbHkgbm9ybWFsaXplcyB0ZXh0IGludGVybmFsbHkgdG8gc2VwYXJhdGUKICogYWNjZW50cyBmcm9tIGJhc2UgY2hhcmFjdGVycyB3aGVyZSBwb3NzaWJsZS4gVGhpcyBpcyBkb25lIGJvdGggd2hlbgogKiBwcm9jZXNzaW5nIHRoZSBydWxlcywgYW5kIHdoZW4gY29tcGFyaW5nIHR3byBzdHJpbmdzLiBDb2xsYXRvciBhbHNvIHVzZXMKICogdGhlIFVuaWNvZGUgY2Fub25pY2FsIG1hcHBpbmcgdG8gZW5zdXJlIHRoYXQgY29tYmluaW5nIHNlcXVlbmNlcyBhcmUgc29ydGVkCiAqIHByb3Blcmx5IChmb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlIDxBIEhSRUY9Imh0dHA6Ly93d3cuYXcuY29tL2RldnByZXNzIj4KICogVGhlIFVuaWNvZGUgU3RhbmRhcmQsIFZlcnNpb24gMi4wPC9BPi4pPC9QPgogKiA8cD48c3Ryb25nPkVycm9yczwvc3Ryb25nPgogKiA8cD5UaGUgZm9sbG93aW5nIGFyZSBlcnJvcnM6CiAqIDxVTCBUeXBlPXJvdW5kPgogKiAgICAgPExJPkEgdGV4dC1hcmd1bWVudCBjb250YWlucyB1bnF1b3RlZCBwdW5jdHVhdGlvbiBzeW1ib2xzCiAqICAgICAgICAoZS5nLiAiYSAmbHQ7IGItYyAmbHQ7IGQiKS4KICogICAgIDxMST5BIHJlbGF0aW9uIG9yIHJlc2V0IGNoYXJhY3RlciBub3QgZm9sbG93ZWQgYnkgYSB0ZXh0LWFyZ3VtZW50CiAqICAgICAgICAoZS5nLiAiYSAmbHQ7ICwgYiIpLgogKiAgICAgPExJPkEgcmVzZXQgd2hlcmUgdGhlIHRleHQtYXJndW1lbnQgKG9yIGFuIGluaXRpYWwgc3Vic3RyaW5nIG9mIHRoZQogKiAgICAgICAgIHRleHQtYXJndW1lbnQpIGlzIG5vdCBhbHJlYWR5IGluIHRoZSBzZXF1ZW5jZS4KICogICAgICAgICAoZS5nLiAiYSAmbHQ7IGIgJiBlICZsdDsgZiIpCiAqIDwvVUw+CiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICBFeGFtcGxlczoKICogICAgIFNpbXBsZTogICAgICI8IGEgPCBiIDwgYyA8IGQiCiAqICAgICBOb3J3ZWdpYW46ICAiPCBhLEE8IGIsQjwgYyxDPCBkLEQ8IGUsRTwgZixGPCBnLEc8IGgsSDwgaSxJPCBqLEoKICogICAgICAgICAgICAgICAgICA8IGssSzwgbCxMPCBtLE08IG4sTjwgbyxPPCBwLFA8IHEsUTwgcixSPCBzLFM8IHQsVAogKiAgICAgICAgICAgICAgICAgIDwgdSxVPCB2LFY8IHcsVzwgeCxYPCB5LFk8IHosWgogKiAgICAgICAgICAgICAgICAgIDwg5T1hsCzFPUGwCiAqICAgICAgICAgICAgICAgICAgO2FhLEFBPCDmLMY8IPgs2CIKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIDxwPlRvIGNyZWF0ZSBhIHRhYmxlLWJhc2VkIGNvbGxhdGlvbiBvYmplY3QsIHNpbXBseSBzdXBwbHkgdGhlIGNvbGxhdGlvbgogKiBydWxlcyB0byB0aGUgUnVsZUJhc2VkQ29sbGF0b3IgY29udHJ1Y3Rvci4gIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlTaW1wbGUgPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoU2ltcGxlLCBzdGF0dXMpOwogKiBcZW5kY29kZQogKiA8L3ByZT4KICogPHA+QW5vdGhlciBleGFtcGxlOgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlOb3J3ZWdpYW4gPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoTm9yd2VnaWFuLCBzdGF0dXMpOwogKiBcZW5kY29kZQogKiA8L3ByZT4KICogVG8gYWRkIHJ1bGVzIG9uIHRvcCBvZiBhbiBleGlzdGluZyB0YWJsZSwgc2ltcGx5IHN1cHBseSB0aGUgb3JnaW5hbCBydWxlcwogKiBhbmQgbW9kaWZpY2F0aW9ucyB0byBSdWxlQmFzZWRDb2xsYXRvciBjb25zdHJ1Y3Rvci4gIEZvciBleGFtcGxlLAogKiA8cHJlPgogKiBcY29kZQogKiAgICAgIFRyYWRpdGlvbmFsIFNwYW5pc2ggKGZyYWdtZW50KTogLi4uICYgQyA8IGNoICwgY0ggLCBDaCAsIENIIC4uLgogKiAgICAgIEdlcm1hbiAoZnJhZ21lbnQpIDogLi4uPCB5ICwgWSA8IHogLCBaCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAmIEFFLCDEICYgQUUsIOQKICogICAgICAgICAgICAgICAgICAgICAgICAgICYgT0UgLCDWICYgT0UsIPYKICogICAgICAgICAgICAgICAgICAgICAgICAgICYgVUUgLCDcICYgVUUsIPwKICogICAgICBTeW1ib2xzIChmcmFnbWVudCk6IC4uLjwgeSwgWSA8IHogLCBaCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAmIFF1ZXN0aW9uLW1hcmsgOyAnPycKICogICAgICAgICAgICAgICAgICAgICAgICAgICYgQW1wZXJzYW5kIDsgJyYnCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAmIERvbGxhci1zaWduIDsgJyQnCiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiA8cD5UbyBjcmVhdGUgYSBjb2xsYXRpb24gb2JqZWN0IGZvciB0cmFkaXRpb25hbCBTcGFuaXNoLCB0aGUgdXNlciBjYW4gdGFrZQogKiB0aGUgRW5nbGlzaCBjb2xsYXRpb24gcnVsZXMgYW5kIGFkZCB0aGUgYWRkaXRpb25hbCBydWxlcyB0byB0aGUgdGFibGUuCiAqIEZvciBleGFtcGxlOgogKiA8cHJlPgogKiBcY29kZQogKiAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgIFVuaWNvZGVTdHJpbmcgcnVsZXMoREVGQVVMVFJVTEVTKTsKICogICAgICBydWxlcyArPSAiJiBDICZsdDsgY2gsIGNILCBDaCwgQ0giOwogKiAgICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteVNwYW5pc2ggPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3IocnVsZXMsIHN0YXR1cyk7CiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiA8cD5JbiBvcmRlciB0byBzb3J0IHN5bWJvbHMgaW4gdGhlIHNpbWlsaWFyIG9yZGVyIG9mIHNvcnRpbmcgdGhlaXIKICogYWxwaGFiZXRpYyBlcXVpdmFsZW50cywgeW91IGNhbiBkbyB0aGUgZm9sbG93aW5nLAogKiA8cHJlPgogKiBcY29kZQogKiAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgIFVuaWNvZGVTdHJpbmcgcnVsZXMoREVGQVVMVFJVTEVTKTsKICogICAgICBydWxlcyArPSAiJiBRdWVzdGlvbi1tYXJrIDsgJz8nICYgQW1wZXJzYW5kIDsgJyYnICYgRG9sbGFyLXNpZ24gOyAnJCcgIjsKICogICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlUYWJsZSA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvcihydWxlcywgc3RhdHVzKTsKICogXGVuZGNvZGUKICogPC9wcmU+CiAqIDxwPkFub3RoZXIgd2F5IG9mIGNyZWF0aW5nIHRoZSB0YWJsZS1iYXNlZCBjb2xsYXRpb24gb2JqZWN0LCBteVNpbXBsZSwKICogaXM6CiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICAgUnVsZUJhc2VkQ29sbGF0b3IgKm15U2ltcGxlID0gbmV3CiAqICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3IoIiAmbHQ7IGEgJmx0OyBiICYgYiAmbHQ7IGMgJiBjICZsdDsgZCIsIHN0YXR1cyk7CiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiBPciwKICogPHByZT4KICogXGNvZGUKICogICAgICBVRXJyb3JDb2RlIHN0YXR1cyA9IFVfWkVST19FUlJPUjsKICogICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlTaW1wbGUgPSBuZXcKICogICAgICAgICAgICBSdWxlQmFzZWRDb2xsYXRvcigiICZsdDsgYSAmbHQ7IGIgJmx0OyBkICYgYiAmbHQ7IGMiLCBzdGF0dXMpOwogKiBcZW5kY29kZQogKiA8L3ByZT4KICogQmVjYXVzZSAiICZsdDsgYSAmbHQ7IGIgJmx0OyBjICZsdDsgZCIgaXMgdGhlIHNhbWUgYXMgImEgJmx0OyBiICZsdDsgZCAmIGIgJmx0OyBjIiBvcgogKiAiJmx0OyBhICZsdDsgYiAmIGIgJmx0OyBjICYgYyAmbHQ7IGQiLgogKgogKiA8cD5UbyBjb21iaW5lIGNvbGxhdGlvbnMgZnJvbSB0d28gbG9jYWxlcywgKHdpdGhvdXQgZXJyb3IgaGFuZGxpbmcgZm9yIGNsYXJpdHkpCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAvLyBDcmVhdGUgYW4gZW5fVVMgQ29sbGF0b3Igb2JqZWN0CiAqICAgICBMb2NhbGUgbG9jYWxlX2VuX1VTKCJlbiIsICJVUyIsICIiKTsKICogICAgIFJ1bGVCYXNlZENvbGxhdG9yKiBlbl9VU0NvbGxhdG9yID0gKFJ1bGVCYXNlZENvbGxhdG9yKikKICogICAgICAgICBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoIGxvY2FsZV9lbl9VUywgc3VjY2VzcyApOwogKiAKICogICAgIC8vIENyZWF0ZSBhIGRhX0RLIENvbGxhdG9yIG9iamVjdAogKiAgICAgTG9jYWxlIGxvY2FsZV9kYV9ESygiZGEiLCAiREsiLCAiIik7CiAqICAgICBSdWxlQmFzZWRDb2xsYXRvciogZGFfREtDb2xsYXRvciA9IChSdWxlQmFzZWRDb2xsYXRvciopCiAqICAgICAgICAgQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKCBsb2NhbGVfZGFfREssIHN1Y2Nlc3MgKTsKICogCiAqICAgICAvLyBDb21iaW5lIHRoZSB0d28KICogICAgIC8vIEZpcnN0LCBnZXQgdGhlIGNvbGxhdGlvbiBydWxlcyBmcm9tIGVuX1VTQ29sbGF0b3IKICogICAgIFVuaWNvZGVTdHJpbmcgcnVsZXMgPSBlbl9VU0NvbGxhdG9yLT5nZXRSdWxlcygpOwogKiAgICAgLy8gU2Vjb25kLCBnZXQgdGhlIGNvbGxhdGlvbiBydWxlcyBmcm9tIGRhX0RLQ29sbGF0b3IKICogICAgIHJ1bGVzICs9IGRhX0RLQ29sbGF0b3ItPmdldFJ1bGVzKCk7CiAqICAgICBSdWxlQmFzZWRDb2xsYXRvciogbmV3Q29sbGF0b3IgPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3IoIHJ1bGVzLCBzdWNjZXNzICk7CiAqICAgICAvLyBuZXdDb2xsYXRvciBoYXMgdGhlIGNvbWJpbmVkIHJ1bGVzCiAqIFxlbmRjb2RlCiAqIDwvcHJlPgogKiA8cD5Bbm90aGVyIG1vcmUgaW50ZXJlc3RpbmcgZXhhbXBsZSB3b3VsZCBiZSB0byBtYWtlIGNoYW5nZXMgb24gYW4gZXhpc3RpbmcKICogdGFibGUgdG8gY3JlYXRlIGEgbmV3IGNvbGxhdGlvbiBvYmplY3QuICBGb3IgZXhhbXBsZSwgYWRkCiAqICImIEMgJmx0OyBjaCwgY0gsIENoLCBDSCIgdG8gdGhlIGVuX1VTQ29sbGF0aW9uIG9iamVjdCB0byBjcmVhdGUgeW91ciBvd24KICogRW5nbGlzaCBjb2xsYXRpb24gb2JqZWN0LAogKiA8cHJlPgogKiBcY29kZQogKiAgICAgLy8gQ3JlYXRlIGEgbmV3IENvbGxhdG9yIG9iamVjdCB3aXRoIGFkZGl0aW9uYWwgcnVsZXMKICogICAgIHJ1bGVzID0gZW5fVVNDb2xsYXRvci0+Z2V0UnVsZXMoKTsKICogICAgIHJ1bGVzICs9ICImIEMgPCBjaCwgY0gsIENoLCBDSCI7CiAqICAgICBSdWxlQmFzZWRDb2xsYXRvciogbXlDb2xsYXRvciA9IG5ldyBSdWxlQmFzZWRDb2xsYXRvciggcnVsZXMsIHN1Y2Nlc3MgKTsKICogICAgIC8vIG15Q29sbGF0b3IgY29udGFpbnMgdGhlIG5ldyBydWxlcwogKiBcZW5kY29kZQogKiA8L3ByZT4KICoKICogPHA+VGhlIGZvbGxvd2luZyBleGFtcGxlIGRlbW9uc3RyYXRlcyBob3cgdG8gY2hhbmdlIHRoZSBvcmRlciBvZgogKiBub24tc3BhY2luZyBhY2NlbnRzLAogKiA8cHJlPgogKiBcY29kZQogKiAgICAgIFVDaGFyIGNvbnRlbnRzW10gPSB7CiAqICAgICAgICAgICc9JywgMHgwMzAxLCAnOycsIDB4MDMwMCwgJzsnLCAweDAzMDIsCiAqICAgICAgICAgICc7JywgMHgwMzA4LCAnOycsIDB4MDMyNywgJywnLCAweDAzMDMsICAgIC8vIG1haW4gYWNjZW50cwogKiAgICAgICAgICAnOycsIDB4MDMwNCwgJzsnLCAweDAzMDUsICc7JywgMHgwMzA2LCAgICAvLyBtYWluIGFjY2VudHMKICogICAgICAgICAgJzsnLCAweDAzMDcsICc7JywgMHgwMzA5LCAnOycsIDB4MDMwQSwgICAgLy8gbWFpbiBhY2NlbnRzCiAqICAgICAgICAgICc7JywgMHgwMzBCLCAnOycsIDB4MDMwQywgJzsnLCAweDAzMEQsICAgIC8vIG1haW4gYWNjZW50cwogKiAgICAgICAgICAnOycsIDB4MDMwRSwgJzsnLCAweDAzMEYsICc7JywgMHgwMzEwLCAgICAvLyBtYWluIGFjY2VudHMKICogICAgICAgICAgJzsnLCAweDAzMTEsICc7JywgMHgwMzEyLCAgICAgICAgICAgICAgICAgLy8gbWFpbiBhY2NlbnRzCiAqICAgICAgICAgICc8JywgJ2EnLCAnLCcsICdBJywgJzsnLCAnYScsICdlJywgJywnLCAnQScsICdFJywKICogICAgICAgICAgJzsnLCAweDAwZTYsICcsJywgMHgwMGM2LCAnPCcsICdiJywgJywnLCAnQicsCiAqICAgICAgICAgICc8JywgJ2MnLCAnLCcsICdDJywgJzwnLCAnZScsICcsJywgJ0UnLCAnJicsIAogKiAgICAgICAgICAnQycsICc8JywgJ2QnLCAnLCcsICdEJywgMCB9OwogKiAgICAgIFVuaWNvZGVTdHJpbmcgb2xkUnVsZXMoY29udGVudHMpOwogKiAgICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwogKiAgICAgIC8vIGNoYW5nZSB0aGUgb3JkZXIgb2YgYWNjZW50IGNoYXJhY3RlcnMKICogICAgICBVQ2hhciBhZGRPbltdID0geyAnJicsICcsJywgMHgwMzAwLCAnOycsIDB4MDMwOCwgJzsnLCAweDAzMDIsIDAgfTsKICogICAgICBvbGRSdWxlcyArPSBhZGRPbjsKICogICAgICBSdWxlQmFzZWRDb2xsYXRvciAqbXlDb2xsYXRpb24gPSBuZXcgUnVsZUJhc2VkQ29sbGF0b3Iob2xkUnVsZXMsIHN0YXR1cyk7CiAqICBcZW5kY29kZQogKiA8L3ByZT4KICoKICogPHA+IFRoZSBsYXN0IGV4YW1wbGUgc2hvd3MgaG93IHRvIHB1dCBuZXcgcHJpbWFyeSBvcmRlcmluZyBpbiBiZWZvcmUgdGhlCiAqIGRlZmF1bHQgc2V0dGluZy4gRm9yIGV4YW1wbGUsIGluIEphcGFuZXNlIGNvbGxhdGlvbiwgeW91IGNhbiBlaXRoZXIgc29ydAogKiBFbmdsaXNoIGNoYXJhY3RlcnMgYmVmb3JlIG9yIGFmdGVyIEphcGFuZXNlIGNoYXJhY3RlcnMsCiAqIDxwcmU+CiAqIFxjb2RlCiAqICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAqICAgICAgLy8gZ2V0IGVuX1VTIGNvbGxhdGlvbiBydWxlcwogKiAgICAgIFJ1bGVCYXNlZENvbGxhdG9yKiBlbl9VU0NvbGxhdGlvbiA9IAogKiAgICAgICAgICAoUnVsZUJhc2VkQ29sbGF0b3IqKSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICogICAgICAvLyBBbHdheXMgY2hlY2sgdGhlIGVycm9yIGNvZGUgYWZ0ZXIgZWFjaCBjYWxsLgogKiAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogKiAgICAgIC8vIGFkZCBhIGZldyBKYXBhbmVzZSBjaGFyYWN0ZXIgdG8gc29ydCBiZWZvcmUgRW5nbGlzaCBjaGFyYWN0ZXJzCiAqICAgICAgLy8gc3VwcG9zZSB0aGUgbGFzdCBjaGFyYWN0ZXIgYmVmb3JlIHRoZSBmaXJzdCBiYXNlIGxldHRlciAnYScgaW4KICogICAgICAvLyB0aGUgRW5nbGlzaCBjb2xsYXRpb24gcnVsZSBpcyAweDIyMTIKICogICAgICBVQ2hhciBqYVN0cmluZ1tdID0geyAnJicsIDB4MjIxMiwgJyZsdDsnLCAweDMwNDEsICcsJywgMHgzMDQyLCAnJmx0OycsIDB4MzA0MywgJywnLCAweDMwNDQsIDAgfTsKICogICAgICBVbmljb2RlU3RyaW5nIHJ1bGVzKCBlbl9VU0NvbGxhdGlvbi0+Z2V0UnVsZXMoKSApOwogKiAgICAgIHJ1bGVzICs9IGphU3RyaW5nOwogKiAgICAgIFJ1bGVCYXNlZENvbGxhdG9yICpteUphcGFuZXNlQ29sbGF0aW9uID0gbmV3IFJ1bGVCYXNlZENvbGxhdG9yKHJ1bGVzLCBzdGF0dXMpOwogKiBcZW5kY29kZQogKiA8L3ByZT4KICogPHA+PHN0cm9uZz5OT1RFPC9zdHJvbmc+OiBUeXBpY2FsbHksIGEgY29sbGF0aW9uIG9iamVjdCBpcyBjcmVhdGVkIHdpdGgKICogQ29sbGF0b3I6OmNyZWF0ZUluc3RhbmNlKCkuCiAqIDxwPgogKiA8c3Ryb25nPk5vdGU6PC9zdHJvbmc+IDxjb2RlPlJ1bGVCYXNlZENvbGxhdG9yPC9jb2RlPnMgd2l0aCBkaWZmZXJlbnQgTG9jYWxlLAogKiBDb2xsYXRpb25TdHJlbmd0aCBhbmQgRGVjb21wb3NpdGlvbiBtb2RlIHNldHRpbmdzIHdpbGwgcmV0dXJuIGRpZmZlcmVudAogKiBzb3J0IG9yZGVycyBmb3IgdGhlIHNhbWUgc2V0IG9mIHN0cmluZ3MuIExvY2FsZXMgaGF2ZSBzcGVjaWZpYyAKICogY29sbGF0aW9uIHJ1bGVzLCBhbmQgdGhlIHdheSBpbiB3aGljaCBzZWNvbmRhcnkgYW5kIHRlcnRpYXJ5IGRpZmZlcmVuY2VzIAogKiBhcmUgdGFrZW4gaW50byBhY2NvdW50LCBmb3IgZXhhbXBsZSwgd2lsbCByZXN1bHQgaW4gYSBkaWZmZXJlbnQgc29ydGluZyBvcmRlcgogKiBmb3Igc2FtZSBzdHJpbmdzLgogKiA8cD4KICogQHNlZSAgICAgICAgQ29sbGF0b3IKICogQHZlcnNpb24gICAgMS4yNyA0LzgvOTcKICogQGF1dGhvciAgICAgSGVsZW5hIFNoaWgKICovCmNsYXNzIFVfSTE4Tl9BUEkgUnVsZUJhc2VkQ29sbGF0b3IgOiBwdWJsaWMgQ29sbGF0b3IgCnsKcHVibGljOiAKCiAgLy8gY29uc3RydWN0b3IvZGVzdHJ1Y3RvcgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiAgVGhpcyB0YWtlcyB0aGUgdGFibGUgcnVsZXMgYW5kIGJ1aWxkcwogICAqIGEgY29sbGF0aW9uIHRhYmxlIG91dCBvZiB0aGVtLiAgUGxlYXNlIHNlZSBSdWxlQmFzZWRDb2xsYXRvciBjbGFzcwogICAqIGRlc2NyaXB0aW9uIGZvciBtb3JlIGRldGFpbHMgb24gdGhlIGNvbGxhdGlvbiBydWxlIHN5bnRheC4KICAgKiBAc2VlIExvY2FsZQogICAqIEBwYXJhbSBydWxlcyB0aGUgY29sbGF0aW9uIHJ1bGVzIHRvIGJ1aWxkIHRoZSBjb2xsYXRpb24gdGFibGUgZnJvbS4KICAgKiBAc3RhYmxlCiAgICovCglSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBydWxlcywKCQkJVUVycm9yQ29kZSYgc3RhdHVzKTsKCiAgUnVsZUJhc2VkQ29sbGF0b3IoICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpOwoKICBSdWxlQmFzZWRDb2xsYXRvciggIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHJ1bGVzLAogICAgICAgICAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKTsKCiAgUnVsZUJhc2VkQ29sbGF0b3IoICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICBFQ29sbGF0aW9uU3RyZW5ndGggY29sbGF0aW9uU3RyZW5ndGgsCiAgICAgICAgICAgICAgTm9ybWFsaXplcjo6RU1vZGUgIGRlY29tcG9zaXRpb25Nb2RlLAogICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKTsKCiAgLyoqIERlc3RydWN0b3IuCiAgICogQHN0YWJsZQogICAqLwoJdmlydHVhbCB+UnVsZUJhc2VkQ29sbGF0b3IoKTsKCgogIC8qKiBDb3B5IGNvbnN0cnVjdG9yLgogICAqIEBzdGFibGUKICAgKi8KCVJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IFJ1bGVCYXNlZENvbGxhdG9yJiBvdGhlcik7CgogIC8qKgogICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IuCiAgICogQHN0YWJsZQogICAqLwoJUnVsZUJhc2VkQ29sbGF0b3ImIG9wZXJhdG9yPShjb25zdCBSdWxlQmFzZWRDb2xsYXRvciYgb3RoZXIpOwogICAgCiAgLyoqCiAgICogUmV0dXJucyB0cnVlIGlmICJvdGhlciIgaXMgdGhlIHNhbWUgYXMgInRoaXMiLgogICAqIEBzdGFibGUKICAgKi8KICB2aXJ0dWFsIFVCb29sICAgICAgICAgICAgICAgICAgb3BlcmF0b3I9PShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0OwoKICAvKioKICAgKiBSZXR1cm5zIHRydWUgaWYgIm90aGVyIiBpcyBub3QgdGhlIHNhbWUgYXMgInRoaXMiLgogICAqIEBzdGFibGUKICAgKi8KICB2aXJ0dWFsIFVCb29sICAgICAgICAgICAgICAgICAgb3BlcmF0b3IhPShjb25zdCBDb2xsYXRvciYgb3RoZXIpIGNvbnN0OwoKICAvKioKICAgKiBNYWtlcyBhIGRlZXAgY29weSBvZiB0aGUgb2JqZWN0LiAgVGhlIGNhbGxlciBvd25zIHRoZSByZXR1cm5lZCBvYmplY3QuCiAgICogQHJldHVybiB0aGUgY2xvbmVkIG9iamVjdC4KICAgKiBAc3RhYmxlCiAgICovCiAgdmlydHVhbCBDb2xsYXRvciogICAgICAgICAgICAgICBjbG9uZSh2b2lkKSBjb25zdDsKCiAgLyoqCiAgICogQ3JlYXRlcyBhIGNvbGxhdGlvbiBlbGVtZW50IGl0ZXJhdG9yIGZvciB0aGUgc291cmNlIHN0cmluZy4gIFRoZSAKICAgKiBjYWxsZXIgb2YgdGhpcyBtZXRob2QgaXMgcmVzcG9uc2libGUgZm9yIHRoZSBtZW1vcnkgbWFuYWdlbWVudCBvZiAKICAgKiB0aGUgcmV0dXJuIHBvaW50ZXIuCiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc3RyaW5nIG92ZXIgd2hpY2ggdGhlIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciB3aWxsIGl0ZXJhdGUuCiAgICogQHJldHVybiB0aGUgY29sbGF0aW9uIGVsZW1lbnQgaXRlcmF0b3Igb2YgdGhlIHNvdXJjZSBzdHJpbmcgdXNpbmcgdGhpcyBhcwogICAqIHRoZSBiYXNlZCBjb2xsYXRvci4KICAgKiBAc3RhYmxlIAogICAqLwoJdmlydHVhbCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IqIGNyZWF0ZUNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBVbmljb2RlU3RyaW5nJiBzb3VyY2UpIGNvbnN0OwoKICAvKioKICAgKiBDcmVhdGVzIGEgY29sbGF0aW9uIGVsZW1lbnQgaXRlcmF0b3IgZm9yIHRoZSBzb3VyY2UuICBUaGUgCiAgICogY2FsbGVyIG9mIHRoaXMgbWV0aG9kIGlzIHJlc3BvbnNpYmxlIGZvciB0aGUgbWVtb3J5IG1hbmFnZW1lbnQgb2YgCiAgICogdGhlIHJldHVybmVkIHBvaW50ZXIuCiAgICogQHBhcmFtIHNvdXJjZSB0aGUgQ2hhcmFjdGVySXRlcmF0b3Igd2hpY2ggcHJvZHVjZXMgdGhlIGNoYXJhY3RlcnMgb3ZlciB3aGljaCB0aGUKICAgKiBDb2xsYXRpb25FbGVtZW50SXRnZXJhdG9yIHdpbGwgaXRlcmF0ZS4KICAgKiBAcmV0dXJuIHRoZSBjb2xsYXRpb24gZWxlbWVudCBpdGVyYXRvciBvZiB0aGUgc291cmNlIHVzaW5nIHRoaXMgYXMKICAgKiB0aGUgYmFzZWQgY29sbGF0b3IuCiAgICogQHN0YWJsZQogICAqLwogIHZpcnR1YWwgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKiAgICAgICBjcmVhdGVDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoY29uc3QgQ2hhcmFjdGVySXRlcmF0b3ImIHNvdXJjZSkgY29uc3Q7CgogIC8qKgogICAqIENvbXBhcmVzIGEgcmFuZ2Ugb2YgY2hhcmFjdGVyIGRhdGEgc3RvcmVkIGluIHR3byBkaWZmZXJlbnQgc3RyaW5ncwogICAqIGJhc2VkIG9uIHRoZSBjb2xsYXRpb24gcnVsZXMuICBSZXR1cm5zCiAgICogaW5mb3JtYXRpb24gYWJvdXQgd2hldGhlciBhIHN0cmluZyBpcyBsZXNzIHRoYW4sIGdyZWF0ZXIgdGhhbiBvcgogICAqIGVxdWFsIHRvIGFub3RoZXIgc3RyaW5nIGluIGEgbGFuZ3VhZ2UuCiAgICogVGhpcyBjYW4gYmUgb3ZlcnJpZGVuIGluIGEgc3ViY2xhc3MuCiAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcGFyYW0gdGFyZ2V0IHRoZSB0YXJnZXQgc3RyaW5nIHRvIGJlIGNvbXBhcmVkIHdpdGggdGhlIHNvdXJjZSBzdGlybmcuCiAgICogQHJldHVybiB0aGUgY29tcGFyaXNvbiByZXN1bHQuICBHUkVBVEVSIGlmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGdyZWF0ZXIKICAgKiB0aGFuIHRoZSB0YXJnZXQgc3RyaW5nLCBMRVNTIGlmIHRoZSBzb3VyY2UgaXMgbGVzcyB0aGFuIHRoZSB0YXJnZXQuICBPdGhlcndpc2UsCiAgICogcmV0dXJucyBFUVVBTC4KICAgKiBAc3RhYmxlCiAgICovCiAgdmlydHVhbCAgICAgRUNvbXBhcmlzb25SZXN1bHQgICBjb21wYXJlKCAgICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHRhcmdldCkgY29uc3Q7CiAgICAgICAgCiAgICAgICAgCiAgLyoqCiAgICogQ29tcGFyZXMgYSByYW5nZSBvZiBjaGFyYWN0ZXIgZGF0YSBzdG9yZWQgaW4gdHdvIGRpZmZlcmVudCBzdHJpbmdzCiAgICogYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBydWxlcyB1cCB0byB0aGUgc3BlY2lmaWVkIGxlbmd0aC4gIFJldHVybnMKICAgKiBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIGEgc3RyaW5nIGlzIGxlc3MgdGhhbiwgZ3JlYXRlciB0aGFuIG9yCiAgICogZXF1YWwgdG8gYW5vdGhlciBzdHJpbmcgaW4gYSBsYW5ndWFnZS4KICAgKiBUaGlzIGNhbiBiZSBvdmVycmlkZW4gaW4gYSBzdWJjbGFzcy4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nLgogICAqIEBwYXJhbSB0YXJnZXQgdGhlIHRhcmdldCBzdHJpbmcgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcGFyYW0gbGVuZ3RoIGNvbXBhcmVzIHVwIHRvIHRoZSBzcGVjaWZpZWQgbGVuZ3RoCiAgICogQHJldHVybiB0aGUgY29tcGFyaXNvbiByZXN1bHQuICBHUkVBVEVSIGlmIHRoZSBzb3VyY2Ugc3RyaW5nIGlzIGdyZWF0ZXIKICAgKiB0aGFuIHRoZSB0YXJnZXQgc3RyaW5nLCBMRVNTIGlmIHRoZSBzb3VyY2UgaXMgbGVzcyB0aGFuIHRoZSB0YXJnZXQuICBPdGhlcndpc2UsCiAgICogcmV0dXJucyBFUVVBTC4KICAgKiBAZHJhZnQKICAgKi8gCiAgdmlydHVhbCAgICAgRUNvbXBhcmlzb25SZXN1bHQgICBjb21wYXJlKCAgICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGxlbmd0aCkgY29uc3Q7CgogIC8qKgogICAqIFRoZSBjb21wYXJpc29uIGZ1bmN0aW9uIGNvbXBhcmVzIHRoZSBjaGFyYWN0ZXIgZGF0YSBzdG9yZWQgaW4gdHdvCiAgICogZGlmZmVyZW50IHN0cmluZyBhcnJheXMuICBSZXR1cm5zIGluZm9ybWF0aW9uIGFib3V0IHdoZXRoZXIgYSBzdHJpbmcKICAgKiBhcnJheSBpcyBsZXNzIHRoYW4sIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byBhbm90aGVyIHN0cmluZyBhcnJheS4KICAgKiA8cD5FeGFtcGxlIG9mIHVzZToKICAgKiA8cHJlPgogICAqIC4gICAgICAgVUVycm9yQ29kZSBzdGF0dXMgPSBVX1pFUk9fRVJST1I7CiAgICogLiAgICAgICBDb2xsYXRvciAqbXlDb2xsYXRpb24gPSBDb2xsYXRvcjo6Y3JlYXRlSW5zdGFuY2UoTG9jYWxlOjpVUywgc3RhdHVzKTsKICAgKiAuICAgICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgcmV0dXJuOwogICAqIC4gICAgICAgbXlDb2xsYXRpb24tPnNldFN0cmVuZ3RoKENvbGxhdG9yOjpQUklNQVJZKTsKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSBDb2xsYXRvcjo6RVFVQUwgKCJhYmMiID09ICJBQkMiKQogICAqIC4gICAgICAgLy8gKG5vIHByaW1hcnkgZGlmZmVyZW5jZSBiZXR3ZWVuICJhYmMiIGFuZCAiQUJDIikKICAgKiAuICAgICAgIENvbGxhdG9yOjpFQ29tcGFyaXNvblJlc3VsdCByZXN1bHQgPSBteUNvbGxhdGlvbi0+Y29tcGFyZShMImFiYyIsIDMsIEwiQUJDIiwgMyk7CiAgICogLiAgICAgICBteUNvbGxhdGlvbi0+c2V0U3RyZW5ndGgoQ29sbGF0b3I6OlRFUlRJQVJZKTsKICAgKiAuICAgICAgIC8vIHJlc3VsdCB3b3VsZCBiZSBDb2xsYXRvcjo6TEVTUyAoYWJjIiAmbHQ7Jmx0OyZsdDsgIkFCQyIpCiAgICogLiAgICAgICAvLyAod2l0aCB0ZXJ0aWFyeSBkaWZmZXJlbmNlIGJldHdlZW4gImFiYyIgYW5kICJBQkMiKQogICAqIC4gICAgICAgQ29sbGF0b3I6OkVDb21wYXJpc29uUmVzdWx0IHJlc3VsdCA9IG15Q29sbGF0aW9uLT5jb21wYXJlKEwiYWJjIiwgMywgTCJBQkMiLCAzKTsKICAgKiA8L3ByZT4KICAgKiBAcGFyYW0gc291cmNlIHRoZSBzb3VyY2Ugc3RyaW5nIGFycmF5IHRvIGJlIGNvbXBhcmVkIHdpdGguCiAgICogQHBhcmFtIHNvdXJjZUxlbmd0aCB0aGUgbGVuZ3RoIG9mIHRoZSBzb3VyY2Ugc3RyaW5nIGFycmF5LiAgSWYgdGhpcyB2YWx1ZQogICAqICAgICAgICBpcyBlcXVhbCB0byAtMSwgdGhlIHN0cmluZyBhcnJheSBpcyBudWxsLXRlcm1pbmF0ZWQuCiAgICogQHBhcmFtIHRhcmdldCB0aGUgc3RyaW5nIHRoYXQgaXMgdG8gYmUgY29tcGFyZWQgd2l0aCB0aGUgc291cmNlIHN0cmluZy4KICAgKiBAcGFyYW0gdGFyZ2V0TGVuZ3RoIHRoZSBsZW5ndGggb2YgdGhlIHRhcmdldCBzdHJpbmcgYXJyYXkuICBJZiB0aGlzIHZhbHVlCiAgICogICAgICAgIGlzIGVxdWFsIHRvIC0xLCB0aGUgc3RyaW5nIGFycmF5IGlzIG51bGwtdGVybWluYXRlZC4KICAgKiBAcmV0dXJuIFJldHVybnMgYSBieXRlIHZhbHVlLiBHUkVBVEVSIGlmIHNvdXJjZSBpcyBncmVhdGVyCiAgICogdGhhbiB0YXJnZXQ7IEVRVUFMIGlmIHNvdXJjZSBpcyBlcXVhbCB0byB0YXJnZXQ7IExFU1MgaWYgc291cmNlIGlzIGxlc3MKICAgKiB0aGFuIHRhcmdldAogICAqIEBzdGFibGUKICAgKiovCiAgdmlydHVhbCBFQ29tcGFyaXNvblJlc3VsdCAgIGNvbXBhcmUoICAgIGNvbnN0ICAgVUNoYXIqIHNvdXJjZSwgCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHNvdXJjZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVUNoYXIqICB0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHRhcmdldExlbmd0aCkgY29uc3QgOwoKICB2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0ICAgY29tcGFyZUV4KCAgICBjb25zdCAgIFVDaGFyKiBzb3VyY2UsIAogICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCAgIFVDaGFyKiAgdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCB0YXJnZXRMZW5ndGgpIGNvbnN0IDsKCiAgLyoqIFRyYW5zZm9ybXMgYSBzcGVjaWZpZWQgcmVnaW9uIG9mIHRoZSBzdHJpbmcgaW50byBhIHNlcmllcyBvZiBjaGFyYWN0ZXJzCiAgICAgKiB0aGF0IGNhbiBiZSBjb21wYXJlZCB3aXRoIENvbGxhdGlvbktleS5jb21wYXJlLiBVc2UgYSBDb2xsYXRpb25LZXkgd2hlbgogICAgICogeW91IG5lZWQgdG8gZG8gcmVwZWF0ZWQgY29tcGFyaXNpb25zIG9uIHRoZSBzYW1lIHN0cmluZy4gRm9yIGEgc2luZ2xlIGNvbXBhcmlzb24KICAgICAqIHRoZSBjb21wYXJlIG1ldGhvZCB3aWxsIGJlIGZhc3Rlci4KICAgICAqIEBwYXJhbSBzb3VyY2UgdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0ga2V5IHRoZSB0cmFuc2Zvcm1lZCBrZXkgb2YgdGhlIHNvdXJjZSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAgICAqIEByZXR1cm4gdGhlIHRyYW5zZm9ybWVkIGtleS4KICAgICAqIEBzZWUgQ29sbGF0aW9uS2V5CiAgICAgKiBAZHJhZnQKICAgICAqLwogIHZpcnR1YWwgICAgIENvbGxhdGlvbktleSYgICAgICAgZ2V0Q29sbGF0aW9uS2V5KCAgICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBzb3VyY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENvbGxhdGlvbktleSYgICBrZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICBzdGF0dXMpIGNvbnN0OwoKICAvKiogVHJhbnNmb3JtcyBhIHNwZWNpZmllZCByZWdpb24gb2YgdGhlIHN0cmluZyBpbnRvIGEgc2VyaWVzIG9mIGNoYXJhY3RlcnMKICAgICAqIHRoYXQgY2FuIGJlIGNvbXBhcmVkIHdpdGggQ29sbGF0aW9uS2V5LmNvbXBhcmUuIFVzZSBhIENvbGxhdGlvbktleSB3aGVuCiAgICAgKiB5b3UgbmVlZCB0byBkbyByZXBlYXRlZCBjb21wYXJpc2lvbnMgb24gdGhlIHNhbWUgc3RyaW5nLiBGb3IgYSBzaW5nbGUgY29tcGFyaXNvbgogICAgICogdGhlIGNvbXBhcmUgbWV0aG9kIHdpbGwgYmUgZmFzdGVyLgogICAgICogQHBhcmFtIHNvdXJjZSB0aGUgc291cmNlIHN0cmluZy4KICAgICAqIEBwYXJhbSBrZXkgdGhlIHRyYW5zZm9ybWVkIGtleSBvZiB0aGUgc291cmNlIHN0cmluZy4KICAgICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAgICogQHJldHVybiB0aGUgdHJhbnNmb3JtZWQga2V5LgogICAgICogQHNlZSBDb2xsYXRpb25LZXkKICAgICAqIEBkcmFmdAogICAgICovCiAgdmlydHVhbCBDb2xsYXRpb25LZXkmICAgICAgIGdldENvbGxhdGlvbktleShjb25zdCBVQ2hhciAqc291cmNlLAoJCQkJCSAgICAgIGludDMyX3Qgc291cmNlTGVuZ3RoLAoJCQkJCSAgICAgIENvbGxhdGlvbktleSYgICAgICAga2V5LAoJCQkJCSAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKSBjb25zdDsKCiAgdmlydHVhbCBDb2xsYXRpb25LZXkmICAgICAgIGdldENvbGxhdGlvbktleUV4KGNvbnN0IFVDaGFyICpzb3VyY2UsCgkJCQkJICAgICAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCgkJCQkJICAgICAgQ29sbGF0aW9uS2V5JiAgICAgICBrZXksCgkJCQkJICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpIGNvbnN0OwoKICAvKioKICAgKiBHZW5lcmF0ZXMgdGhlIGhhc2ggY29kZSBmb3IgdGhlIHJ1bGUtYmFzZWQgY29sbGF0aW9uIG9iamVjdC4KICAgKiBAcmV0dXJuIHRoZSBoYXNoIGNvZGUuCiAgICogQHN0YWJsZQogICAqLwogIHZpcnR1YWwgICAgIGludDMyX3QgICAgICAgICAgICAgaGFzaENvZGUodm9pZCkgY29uc3Q7CgogIC8qKgogICAqIEdldHMgdGhlIHRhYmxlLWJhc2VkIHJ1bGVzIGZvciB0aGUgY29sbGF0aW9uIG9iamVjdC4KICAgKiBAcmV0dXJuIHJldHVybnMgdGhlIGNvbGxhdGlvbiBydWxlcyB0aGF0IHRoZSB0YWJsZSBjb2xsYXRpb24gb2JqZWN0CiAgICogd2FzIGNyZWF0ZWQgZnJvbS4KICAgKiBAc3RhYmxlCiAgICovCiAgY29uc3QgICAgICAgVW5pY29kZVN0cmluZyYgICAgICBnZXRSdWxlcyh2b2lkKSBjb25zdDsKCiAgLyoqCiAgICogIFJldHVybiB0aGUgbWF4aW11bSBsZW5ndGggb2YgYW55IGV4cGFuc2lvbiBzZXF1ZW5jZXMgdGhhdCBlbmQKICAgKiAgd2l0aCB0aGUgc3BlY2lmaWVkIGNvbXBhcmlzb24gb3JkZXIuCiAgICogCiAgICogIEBwYXJhbSBvcmRlciBhIGNvbGxhdGlvbiBvcmRlciByZXR1cm5lZCBieSBwcmV2aW91cyBvciBuZXh0LgogICAqICBAcmV0dXJuIHRoZSBtYXhpbXVtIGxlbmd0aCBvZiBhbnkgZXhwYW5zaW9uIHNldWVuY2VzIGVuZGluZwogICAqICAgICAgICAgIHdpdGggdGhlIHNwZWNpZmllZCBvcmRlci4KICAgKiAKICAgKiAgQHNlZSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IjZ2V0TWF4RXhwYW5zaW9uCiAgICogQGRyYWZ0ID8gcGVuZGluZyBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OmdldE1heEV4cGFuc2lvbgogICAqLwoJaW50MzJfdCBnZXRNYXhFeHBhbnNpb24oaW50MzJfdCBvcmRlcikgY29uc3Q7CgogIC8qKgogICAqIFJldHVybnMgYSB1bmlxdWUgY2xhc3MgSUQgUE9MWU1PUlBISUNBTExZLiAgUHVyZSB2aXJ0dWFsIG92ZXJyaWRlLgogICAqIFRoaXMgbWV0aG9kIGlzIHRvIGltcGxlbWVudCBhIHNpbXBsZSB2ZXJzaW9uIG9mIFJUVEksIHNpbmNlIG5vdCBhbGwKICAgKiBDKysgY29tcGlsZXJzIHN1cHBvcnQgZ2VudWluZSBSVFRJLiAgUG9seW1vcnBoaWMgb3BlcmF0b3I9PSgpIGFuZAogICAqIGNsb25lKCkgbWV0aG9kcyBjYWxsIHRoaXMgbWV0aG9kLgogICAqCiAgICogQHJldHVybiAgICAgICAgICBUaGUgY2xhc3MgSUQgZm9yIHRoaXMgb2JqZWN0LiBBbGwgb2JqZWN0cyBvZiBhCiAgICogICAgICAgICAgICAgICAgICBnaXZlbiBjbGFzcyBoYXZlIHRoZSBzYW1lIGNsYXNzIElELiAgT2JqZWN0cyBvZgogICAqICAgICAgICAgICAgICAgICAgb3RoZXIgY2xhc3NlcyBoYXZlIGRpZmZlcmVudCBjbGFzcyBJRHMuCiAgICovCiAgdmlydHVhbCBVQ2xhc3NJRCBnZXREeW5hbWljQ2xhc3NJRCh2b2lkKSBjb25zdAogICAgeyByZXR1cm4gUnVsZUJhc2VkQ29sbGF0b3I6OmdldFN0YXRpY0NsYXNzSUQoKTsgfQoKCiAgLyoqCiAgICogUmV0dXJucyB0aGUgY2xhc3MgSUQgZm9yIHRoaXMgY2xhc3MuICBUaGlzIGlzIHVzZWZ1bCBvbmx5IGZvcgogICAqIGNvbXBhcmluZyB0byBhIHJldHVybiB2YWx1ZSBmcm9tIGdldER5bmFtaWNDbGFzc0lEKCkuICBGb3IgZXhhbXBsZToKICAgKgogICAqICAgICAgQmFzZSogcG9seW1vcnBoaWNfcG9pbnRlciA9IGNyZWF0ZVBvbHltb3JwaGljT2JqZWN0KCk7CiAgICogICAgICBpZiAocG9seW1vcnBoaWNfcG9pbnRlci0+Z2V0RHluYW1pY0NsYXNzSUQoKSA9PQogICAqICAgICAgICAgIERlcml2ZWQ6OmdldFN0YXRpY0NsYXNzSUQoKSkgLi4uCiAgICoKICAgKiBAcmV0dXJuICAgICAgICAgIFRoZSBjbGFzcyBJRCBmb3IgYWxsIG9iamVjdHMgb2YgdGhpcyBjbGFzcy4KICAgKi8KICBzdGF0aWMgVUNsYXNzSUQgZ2V0U3RhdGljQ2xhc3NJRCh2b2lkKSB7IHJldHVybiAoVUNsYXNzSUQpJmZnQ2xhc3NJRDsgfQoKCiAgLyoqCiAgICogUmV0dXJucyB0aGUgYmluYXJ5IGZvcm1hdCBvZiB0aGUgY2xhc3MncyBydWxlcy4gIFRoZSBmb3JtYXQgaXMKICAgKiB0aGF0IG9mIC5jb2wgZmlsZXMuICAKICAgKgogICAqIEBwYXJhbSBsZW5ndGggUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBkYXRhLCBpbiBieXRlcwogICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAqIEByZXR1cm4gbWVtb3J5LCBvd25lZCBieSB0aGUgY2FsbGVyLCBvZiBzaXplICdsZW5ndGgnIGJ5dGVzLgogICAqIEBkcmFmdCBJTlRFUk5BTCBVU0UgT05MWQogICAqLwogIHVpbnQ4X3QgKmNsb25lUnVsZURhdGEoaW50MzJfdCAmbGVuZ3RoLCBVRXJyb3JDb2RlICZzdGF0dXMpOwoKCS8qKgoJICogUmV0dXJucyBjdXJyZW50IHJ1bGVzLiBEZWx0YSBkZWZpbmVzIHdoZXRoZXIgZnVsbCBydWxlcyBhcmUgcmV0dXJuZWQgb3IganVzdCB0aGUgdGFpbG9yaW5nLiAKCSAqIEBwYXJhbSBkZWx0YSBvbmUgb2YgCVVDT0xfVEFJTE9SSU5HX09OTFksIFVDT0xfRlVMTF9SVUxFUy4gCgkgKiBAcmV0dXJuIFVuaWNvZGVTdHJpbmcgd2l0aCBydWxlcwoJICovCglVbmljb2RlU3RyaW5nIGdldFJ1bGVzKFVDb2xSdWxlT3B0aW9uIGRlbHRhKTsKCiAgLyogTmV3IEFQSXMgZm9yIDEuNy4gTm90IHlldCBpbXBsZW1lbnRlZCAqLwoKLyoqCiAqIFVuaXZlcnNhbCBhdHRyaWJ1dGUgc2V0dGVyCiAqIEBwYXJhbSBhdHRyIGF0dHJpYnV0ZSB0eXBlIAogKiBAcGFyYW0gdmFsdWUgYXR0cmlidXRlIHZhbHVlCiAqIEBwYXJhbSBzdGF0dXMgdG8gaW5kaWNhdGUgd2hldGhlciB0aGUgb3BlcmF0aW9uIHdlbnQgb24gc21vb3RobHkgb3IgdGhlcmUgd2VyZSBlcnJvcnMKICogQGRyYWZ0IEFQSSAxLjcgZnJlZXplCiAqLwp2aXJ0dWFsIHZvaWQgc2V0QXR0cmlidXRlKFVDb2xBdHRyaWJ1dGUgYXR0ciwgVUNvbEF0dHJpYnV0ZVZhbHVlIHZhbHVlLCBVRXJyb3JDb2RlICZzdGF0dXMpOwoKLyoqCiAqIFVuaXZlcnNhbCBhdHRyaWJ1dGUgZ2V0dGVyCiAqIEBwYXJhbSBhdHRyIGF0dHJpYnV0ZSB0eXBlCiAqIEBwYXJhbSBzdGF0dXMgdG8gaW5kaWNhdGUgd2hldGhlciB0aGUgb3BlcmF0aW9uIHdlbnQgb24gc21vb3RobHkgb3IgdGhlcmUgd2VyZSBlcnJvcnMKICogQHJldHVybiBhdHRyaWJ1dGUgdmFsdWUKICogQGRyYWZ0IEFQSSAxLjcgZnJlZXplCiAqLwp2aXJ0dWFsIFVDb2xBdHRyaWJ1dGVWYWx1ZSBnZXRBdHRyaWJ1dGUoVUNvbEF0dHJpYnV0ZSBhdHRyLCBVRXJyb3JDb2RlICZzdGF0dXMpOwoKLyoqCiAqIFRocmVhZCBzYWZlIGNsb25pbmcgb3BlcmF0aW9uCiAqIEByZXR1cm4gcG9pbnRlciB0byB0aGUgbmV3IGNsb25lLCB1c2VyIHNob3VsZCByZW1vdmUgaXQuCiAqIEBkcmFmdCBBUEkgMS43IGZyZWV6ZQogKi8KdmlydHVhbCBDb2xsYXRvciogc2FmZUNsb25lKHZvaWQpOwoKCi8qKgogKiBTdHJpbmcgY29tcGFyZSB0aGF0IHVzZXMgdXNlciBzdXBwbGllZCBjaGFyYWN0ZXIgaXRlcmF0aW9uLgogKiBUaGUgaWRlYSBpcyB0byBwcmV2ZW50IHVzZXJzIGZyb20gaGF2aW5nIHRvIGNvbnZlcnQgdGhlIHdob2xlIHN0cmluZyBpbnRvIFVDaGFyJ3MgYmVmb3JlIGNvbXBhcmluZwogKiBzaW5jZSBzb21ldGltZXMgc3RyaW5ncyBkaWZmZXIgb24gZmlyc3QgY291cGxlIG9mIGNoYXJhY3RlcnMuCiAqIEBwYXJhbSBjb2xsIGNvbGxhdG9yIHRvIGJlIHVzZWQgZm9yIGNvbXBhcmluZwogKiBAcGFyYW0gc291cmNlIHBvaW50ZXIgdG8gZnVuY3Rpb24gZm9yIGl0ZXJhdGluZyBvdmVyIHRoZSBmaXJzdCBzdHJpbmcKICogQHBhcmFtIHRhcmdldCBwb2ludGVyIHRvIGZ1bmN0aW9uIGZvciBpdGVyYXRpbmcgb3ZlciB0aGUgc2Vjb25kIHN0cmluZwogKiBAcmV0dXJuIFRoZSByZXN1bHQgb2YgY29tcGFyaW5nIHRoZSBzdHJpbmdzOyBvbmUgb2YgVUNPTF9FUVVBTCwKICogVUNPTF9HUkVBVEVSLCBVQ09MX0xFU1MKICogQGRyYWZ0IEFQSSAxLjcgZnJlZXplCiAqLwp2aXJ0dWFsIEVDb21wYXJpc29uUmVzdWx0IGNvbXBhcmUoRm9yd2FyZENoYXJhY3Rlckl0ZXJhdG9yICZzb3VyY2UsCgkJCQkJCQkJIEZvcndhcmRDaGFyYWN0ZXJJdGVyYXRvciAmdGFyZ2V0KTsKCi8qKgogKiBHZXQgdGhlIHNvcnQga2V5IGFzIGFuIGFycmF5IG9mIGJ5dGVzIGZyb20gYW4gVW5pY29kZVN0cmluZy4KICogQHBhcmFtIHNvdXJjZSBzdHJpbmcgdG8gYmUgcHJvY2Vzc2VkLgogKiBAcGFyYW0gcmVzdWx0IGJ1ZmZlciB0byBzdG9yZSByZXN1bHQgaW4uIElmIE5VTEwsIG51bWJlciBvZiBieXRlcyBuZWVkZWQgd2lsbCBiZSByZXR1cm5lZC4KICogQHBhcmFtIHJlc3VsdExlbmd0aCBsZW5ndGggb2YgdGhlIHJlc3VsdCBidWZmZXIuIElmIGlmIG5vdCBlbm91Z2ggdGhlIGJ1ZmZlciB3aWxsIGJlIGZpbGxlZCB0byBjYXBhY2l0eS4gCiAqIEByZXR1cm4gTnVtYmVyIG9mIGJ5dGVzIG5lZWRlZCBmb3Igc3RvcmluZyB0aGUgc29ydCBrZXkKICogQGRyYWZ0IEFQSSAxLjcgZnJlZXplCiAqLwogIHZpcnR1YWwgaW50MzJfdCAgICAgICBnZXRTb3J0S2V5KGNvbnN0ICAgVW5pY29kZVN0cmluZyYgIHNvdXJjZSwKCQkJCQkJICB1aW50OF90ICpyZXN1bHQsCgkJCQkJCSAgaW50MzJfdCByZXN1bHRMZW5ndGgpIGNvbnN0OwoKLyoqCiAqIEdldCB0aGUgc29ydCBrZXkgYXMgYW4gYXJyYXkgb2YgYnl0ZXMgZnJvbSBhbiBVQ2hhciBidWZmZXIuCiAqIEBwYXJhbSBzb3VyY2Ugc3RyaW5nIHRvIGJlIHByb2Nlc3NlZC4KICogQHBhcmFtIHNvdXJjZUxlbmd0aCBsZW5ndGggb2Ygc3RyaW5nIHRvIGJlIHByb2Nlc3NlZC4gCiAqCQkJSWYgLTEsIHRoZSBzdHJpbmcgaXMgMCB0ZXJtaW5hdGVkIGFuZCBsZW5ndGggd2lsbCBiZSBkZWNpZGVkIGJ5IHRoZSBmdW5jdGlvbi4KICogQHBhcmFtIHJlc3VsdCBidWZmZXIgdG8gc3RvcmUgcmVzdWx0IGluLiBJZiBOVUxMLCBudW1iZXIgb2YgYnl0ZXMgbmVlZGVkIHdpbGwgYmUgcmV0dXJuZWQuCiAqIEBwYXJhbSByZXN1bHRMZW5ndGggbGVuZ3RoIG9mIHRoZSByZXN1bHQgYnVmZmVyLiBJZiBpZiBub3QgZW5vdWdoIHRoZSBidWZmZXIgd2lsbCBiZSBmaWxsZWQgdG8gY2FwYWNpdHkuIAogKiBAcmV0dXJuIE51bWJlciBvZiBieXRlcyBuZWVkZWQgZm9yIHN0b3JpbmcgdGhlIHNvcnQga2V5CiAqIEBkcmFmdCBBUEkgMS43IGZyZWV6ZQogKi8KICB2aXJ0dWFsIGludDMyX3QgICAgICAgZ2V0U29ydEtleShjb25zdCAgIFVDaGFyICpzb3VyY2UsCgkJCQkJCSAgaW50MzJfdCBzb3VyY2VMZW5ndGgsCgkJCQkJCSAgdWludDhfdCAqcmVzdWx0LAoJCQkJCQkgIGludDMyX3QgcmVzdWx0TGVuZ3RoKSBjb25zdDsKCgogLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFBSSVZBVEUKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpwcml2YXRlOgogIHN0YXRpYyAgICAgIGNoYXIgICAgICAgICAgICAgICAgZmdDbGFzc0lEOwoKICAgICAgICAvLyBTdHJlYW1lciB1c2VkIHRvIHJlYWQvd3JpdGUgYmluYXJ5IGNvbGxhdGlvbiBkYXRhIGZpbGVzLgogIGZyaWVuZCAgICAgICAgY2xhc3MgICAgICAgICAgICAgICAgUnVsZUJhc2VkQ29sbGF0b3JTdHJlYW1lcjsKCiAgLy8gVXNlZCB0byBpdGVyYXRlIG92ZXIgY29sbGF0aW9uIGVsZW1lbnRzIGluIGEgY2hhcmFjdGVyIHNvdXJjZS4KICBmcmllbmQgICAgICBjbGFzcyAgICAgICAgICAgICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjsKICAgICAgICAKICAvLyBDb2xsYXRvciBPTkxZIG5lZWRzIGFjY2VzcyB0byBSdWxlQmFzZWRDb2xsYXRvcihjb25zdCBMb2NhbGUmLCBVRXJyb3JDb2RlJikKICBmcmllbmQgY2xhc3MgQ29sbGF0b3I7CiAgICAgICAgCi8vIFRoaXMgaXMganVzdCB0ZW1wb3JhcnksIGZvciBwcm90b3R5cGluZy4KICBmcmllbmQgaW50MzJfdCB1Y29sX2dldE5leHRDRShjb25zdCBVQ29sbGF0b3IgKmNvbGwsIGNvbGxJdGVyYXRlICpzb3VyY2UsIFVFcnJvckNvZGUgKnN0YXR1cyk7CiAgZnJpZW5kIGludDMyX3QgdWNvbF9nZXRJbmNyZW1lbnRhbENFKGNvbnN0IFVDb2xsYXRvciAqY29sbCwgaW5jcmVtZW50YWxDb250ZXh0ICpzb3VyY2UsIFVFcnJvckNvZGUgKnN0YXR1cyk7IAogIGZyaWVuZCBpbnQzMl90IGdldENvbXBsaWNhdGVkQ0UoY29uc3QgVUNvbGxhdG9yICpjb2xsLCBjb2xsSXRlcmF0ZSAqc291cmNlLCBVRXJyb3JDb2RlICpzdGF0dXMpOwogIGZyaWVuZCBpbnQzMl90IHVjb2xfY2FsY1NvcnRLZXkoY29uc3QgICAgVUNvbGxhdG9yICAgICpjb2xsLAogICAgICAgIGNvbnN0ICAgIFVDaGFyICAgICAgICAqc291cmNlLAogICAgICAgIGludDMyX3QgICAgICAgIHNvdXJjZUxlbmd0aCwKICAgICAgICB1aW50OF90ICAgICAgICAqKnJlc3VsdCwKICAgICAgICBpbnQzMl90ICAgICAgICByZXN1bHRMZW5ndGgsCiAgICAgICAgVUJvb2wgYWxsb2NhdGVQcmltYXJ5KTsKICBmcmllbmQgVUNvbGxhdGlvblJlc3VsdCB1Y29sX3N0cmNvbGwoICAgIGNvbnN0ICAgIFVDb2xsYXRvciAgICAqY29sbCwKICAgICAgICBjb25zdCAgICBVQ2hhciAgICAgICAgKnNvdXJjZSwKICAgICAgICBpbnQzMl90ICAgICAgICAgICAgc291cmNlTGVuZ3RoLAogICAgICAgIGNvbnN0ICAgIFVDaGFyICAgICAgICAqdGFyZ2V0LAogICAgICAgIGludDMyX3QgICAgICAgICAgICB0YXJnZXRMZW5ndGgpOwogIGZyaWVuZCBpbnQzMl90IHVjb2xfZ2V0U29ydEtleVNpemUoY29uc3QgVUNvbGxhdG9yICpjb2xsLCAKICAgICAgICBjb2xsSXRlcmF0ZSAqcywgCiAgICAgICAgaW50MzJfdCBjdXJyZW50U2l6ZSwgCiAgICAgICAgVUNvbEF0dHJpYnV0ZVZhbHVlIHN0cmVuZ3RoLCAKICAgICAgICBpbnQzMl90IGxlbik7CiAgZnJpZW5kIHZvaWQgKnVjb2xfZ2V0QUJ1ZmZlcihjb25zdCBVQ29sbGF0b3IgKmNvbGwsIHVpbnQzMl90IHNpemUpOwoKCgoKICAvKiogRGVmYXVsdCBjb25zdHJ1Y3RvcgogICAqLwogIFJ1bGVCYXNlZENvbGxhdG9yKCk7CgogIC8qKgogICAqIENyZWF0ZSBhIG5ldyBlbnRyeSBpbiB0aGUgZXhwYW5zaW9uIHRhYmxlIHRoYXQgY29udGFpbnMgdGhlIG9yZGVyaW5ncwogICAqIGZvciB0aGUgZ2l2ZW4gY2hhcmFjZXJzLiAgSWYgYW5PcmRlciBpcyB2YWxpZCwgaXQgaXMgYWRkZWQgdG8gdGhlCiAgICogYmVnaW5uaW5nIG9mIHRoZSBleHBhbmRlZCBsaXN0IG9mIG9yZGVycy4KICAgKi8KICBpbnQzMl90ICAgICAgICAgICAgICAgIGFkZEV4cGFuc2lvbihpbnQzMl90IGFuT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyAmZXhwYW5kQ2hhcnMpOwogIC8qKgogICAqIENyZWF0ZSBhIHRhYmxlLWJhc2VkIGNvbGxhdGlvbiBvYmplY3Qgd2l0aCB0aGUgZ2l2ZW4gcnVsZXMuCiAgICogQHNlZSBSdWxlQmFzZWRDb2xsYXRvciNSdWxlQmFzZWRDb2xsYXRvcgogICAqIEBleGNlcHRpb24gRm9ybWF0RXhjZXB0aW9uIElmIHRoZSBydWxlcyBmb3JtYXQgaXMgaW5jb3JyZWN0LgogICAqLwogIHZvaWQgICAgICAgICAgICAgICAgYnVpbGQoICBjb25zdCAgIFVuaWNvZGVTdHJpbmcmICBydWxlcywKICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdWNjZXNzKTsKCiAgLyoqIEFkZCBleHBhbmRpbmcgZW50cmllcyBmb3IgcHJlLWNvbXBvc2VkIHVuaWNvZGUgY2hhcmFjdGVycyBzbyB0aGF0IHRoaXMKICAgKiBjb2xsYXRvciBjYW4gYmUgdXNlZCByZWFzb25hYmx5IHdlbGwgd2l0aCBkZWNvbXBvc2l0aW9uIHR1cm5lZCBvZmYuCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICBhZGRDb21wb3NlZENoYXJzKHZvaWQpOwoKICAvKioKICAgKiBMb29rIHVwIGZvciB1bm1hcHBlZCB2YWx1ZXMgaW4gdGhlIGV4cGFuZGVkIGNoYXJhY3RlciB0YWJsZS4KICAgKi8KICB2b2lkICAgICAgICAgICAgICAgIGNvbW1pdCh2b2lkKTsKICAvKioKICAgKiBJbmNyZW1lbnQgb2YgdGhlIGxhc3Qgb3JkZXIgYmFzZWQgb24gdGhlIGNvbGxhdGlvbiBzdHJlbmd0aC4KICAgKiBAcGFyYW0gcyB0aGUgY29sbGF0aW9uIHN0cmVuZ3RoLgogICAqIEBwYXJhbSBsYXN0T3JkZXIgdGhlIGxhc3QgY29sbGF0aW9uIG9yZGVyLgogICAqIEByZXR1cm4gdGhlIG5ldyBjb2xsYXRpb24gb3JkZXIuCiAgICovCiAgaW50MzJfdCAgICAgICAgICAgICBpbmNyZW1lbnQoICBDb2xsYXRvcjo6RUNvbGxhdGlvblN0cmVuZ3RoICAgIHMsIAogICAgICAgICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgICAgICAgICAgICAgIGxhc3RPcmRlcik7CiAgLyoqCiAgICogQWRkcyBhIGNoYXJhY3RlciBhbmQgaXRzIGRlc2lnbmF0ZWQgb3JkZXIgaW50byB0aGUgY29sbGF0aW9uIHRhYmxlLgogICAqIEBwYXJhbSBjaCB0aGUgVW5pY29kZSBjaGFyYWN0ZXIsCiAgICogQHBhcmFtIGFuT3JkZXIgdGhlIG9yZGVyLgogICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAqLwogIHZvaWQgICAgICAgICAgICAgICAgYWRkT3JkZXIoICAgVUNoYXIgICAgICAgIGNoLCAKICAgICAgICAgICAgICAgICAgaW50MzJfdCAgICAgICAgYW5PcmRlciwgCiAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICBzdGF0dXMpOwogIC8qKgogICAqIEFkZHMgdGhlIGV4cGFuZGluZyBzdHJpbmcgaW50byB0aGUgY29sbGF0aW9uIHRhYmxlLCBmb3IgZXhhbXBsZSwgYS11bWxhdXQgaW4gR2VybWFuLgogICAqIEBwYXJhbSBncm91cENoYXJzIHRoZSBjb250cmFjdGluZyBjaGFyYWN0ZXJzLgogICAqIEBwYXJhbSBleHBDaGFycyB0aGUgZXhwYW5kaW5nIGNoYXJhY3RlcnMuCiAgICogQHBhcmFtIGFuT3JkZXIgdGhlIG9yZGVyLgogICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICAqLwogIHZvaWQgICAgICAgICAgICAgICAgYWRkRXhwYW5kT3JkZXIoY29uc3QgICAgVW5pY29kZVN0cmluZyYgICAgICAgICAgZ3JvdXBDaGFycywgCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgIFVuaWNvZGVTdHJpbmcmICAgICAgICAgIGV4cENoYXJzLCAKICAgICAgICAgICAgICAgICAgICAgaW50MzJfdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbk9yZGVyLAogICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzKTsKICAvKioKICAgKiBBZGRzIHRoZSBjb250cmFjdGluZyBzdHJpbmcgaW50byB0aGUgY29sbGF0aW9uIHRhYmxlLCBmb3IgZXhhbXBsZSwgY2ggaW4gU3BhbmlzaC4KICAgKiBAcGFyYW0gZ3JvdXBDaGFycyB0aGUgY29udHJhY3RpbmcgY2hhcmFjdGVycy4KICAgKiBAcGFyYW0gYW5PcmRlciB0aGUgb3JkZXIuCiAgICogQHBhcmFtIHN0YXR1cyB0aGUgZXJyb3IgY29kZSBzdGF0dXMuCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICBhZGRDb250cmFjdE9yZGVyKGNvbnN0ICBVbmljb2RlU3RyaW5nJiAgICAgICAgICBncm91cENoYXJzLCAKICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90ICAgICAgICAgICAgICAgICAgICAgICAgYW5PcmRlciwKICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CiAgLyoqCiAgICogQWRkcyB0aGUgY29udHJhY3Rpbmcgc3RyaW5nIGludG8gdGhlIGNvbGxhdGlvbiB0YWJsZSwgZm9yIGV4YW1wbGUsIGNoIGluIFNwYW5pc2guCiAgICogQHBhcmFtIGdyb3VwQ2hhcnMgdGhlIGNvbnRyYWN0aW5nIGNoYXJhY3RlcnMuCiAgICogQHBhcmFtIGFuT3JkZXIgdGhlIG9yZGVyLgogICAqIEBwYXJhbSBmd2QgVFJVRSBpZiB0aGlzIGlzIGZvciB0aGUgZm9yd2FyZCBkaXJlY3Rpb24KICAgKiBAcGFyYW0gc3RhdHVzIHRoZSBlcnJvciBjb2RlIHN0YXR1cy4KICAgKi8KICB2b2lkICAgICAgICAgICAgICAgIGFkZENvbnRyYWN0T3JkZXIoY29uc3QgIFVuaWNvZGVTdHJpbmcmICAgICAgICAgIGdyb3VwQ2hhcnMsIAogICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgICAgICAgICBhbk9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgIFVCb29sICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ3ZCwKICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyk7CiAgLyoqCiAgICogSWYgdGhlIGdpdmVuIHN0cmluZyBoYXMgYmVlbiBzcGVjaWZpZWQgYXMgYSBjb250cmFjdGluZyBzdHJpbmcKICAgKiBpbiB0aGlzIGNvbGxhdGlvbiB0YWJsZSwgcmV0dXJuIGl0cyBvcmRlcmluZywgb3RoZXJ3aXNlIHJldHVybiBVTk1BUFBFRC4KICAgKiBAcGFyYW0gZ3JvdXBDaGFycyB0aGUgc3RyaW5nCiAgICogQHJldHVybiB0aGUgb3JkZXIgb2YgdGhlIGNvbnRyYWN0ZWQgY2hhcmFjdGVyLCBvciBVTk1BUFBFRCBpZgogICAqIHRoZXJlIGlzbid0IG9uZS4KICAgKi8KICBpbnQzMl90ICAgICAgICAgICAgICAgIGdldENvbnRyYWN0T3JkZXIoY29uc3QgICAgVW5pY29kZVN0cmluZyAgICAgICAgICAgICZncm91cENoYXJzKSBjb25zdDsKICAvKioKICAgKiAgR2V0cyB0aGUgZW50cnkgb2YgbGlzdCBvZiB0aGUgY29udHJhY3Rpbmcgc3RyaW5nIGluIHRoZSBjb2xsYXRpb24KICAgKiAgdGFibGUuCiAgICogIEBwYXJhbSBjaCB0aGUgc3RhcnRpbmcgY2hhcmFjdGVyIG9mIHRoZSBjb250cmFjdGluZyBzdHJpbmcKICAgKiAgQHJldHVybiB0aGUgZW50cnkgb2YgY29udHJhY3RpbmcgZWxlbWVudCB3aGljaCBzdGFydHMgd2l0aCB0aGUgc3BlY2lmaWVkCiAgICogIGNoYXJhY3RlciBpbiB0aGUgbGlzdCBvZiBjb250cmFjdGluZyBlbGVtZW50cy4KICAgKi8KICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCogCiAgZ2V0Q29udHJhY3RWYWx1ZXMoVUNoYXIgICAgIGNoKSBjb25zdDsKICAvKioKICAgKiAgR2VzIHRoZSBlbnRyeSBvZiBsaXN0IG9mIHRoZSBjb250cmFjdGluZyBzdHJpbmcgaW4gdGhlIGNvbGxhdGlvbgogICAqICB0YWJsZS4KICAgKiAgQHBhcmFtIGluZGV4IHRoZSBpbmRleCBvZiB0aGUgY29udHJhY3QgY2hhcmFjdGVyIGxpc3QKICAgKiAgQHJldHVybiB0aGUgZW50cnkgb2YgdGhlIGNvbnRyYWN0aW5nIGVsZW1lbnQgb2YgdGhlIHNwZWNpZmllZCBpbmRleCBpbiB0aGUKICAgKiAgbGlzdC4KICAgKi8KICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCogCiAgZ2V0Q29udHJhY3RWYWx1ZXMoaW50MzJfdCAgICAgaW5kZXgpIGNvbnN0OwogIC8qKgogICAqICBHZXRzIHRoZSBlbnRyeSBvZiB2YWx1ZSBsaXN0IG9mIHRoZSBleHBhbmRpbmcgc3RyaW5nIGluIHRoZSBjb2xsYXRpb24KICAgKiAgdGFibGUgYXQgdGhlIHNwZWNpZmllZCBpbmRleC4KICAgKiAgQHBhcmFtIG9yZGVyIHRoZSBvcmRlciBvZiB0aGUgZXhwYW5kaW5nIHN0cmluZyB2YWx1ZSBsaXN0CiAgICogIEByZXR1cm4gdGhlIGVudHJ5IG9mIHRoZSBleHBhbmRpbmctY2hhciBlbGVtZW50IG9mIHRoZSBzcGVjaWZpZWQgaW5kZXggaW4gCiAgICogIHRoZSBsaXN0LgogICAqLwogIFZlY3Rvck9mSW50KiAgICAgICAgZ2V0RXhwYW5kVmFsdWVMaXN0KGludDMyX3QgICAgIG9yZGVyKSBjb25zdDsKCiAgLyoqCiAgICogIEdldHMgdGhlIGNvbWFyaXNvbiBvcmRlciBvZiBhIGNoYXJhY3RlciBmcm9tIHRoZSBjb2xsYXRpb24gdGFibGUuCiAgICogIEBwYXJhbSBjaCB0aGUgVW5pY29kZSBjaGFyYWN0ZXIKICAgKiAgQHJldHVybiB0aGUgY29tcGFyaXNvbiBvcmRlciBvZiBhIGNoYXJhY3Rlci4KICAgKi8KICBpbnQzMl90ICAgICAgICAgICAgICAgIGdldENoYXJPcmRlcihVQ2hhciBjaCkgY29uc3Q7CgogIC8qKgogICAqICBHZXRzIHRoZSBjb21hcmlzb24gb3JkZXIgb2YgYSBjaGFyYWN0ZXIgZnJvbSB0aGUgY29sbGF0aW9uIHRhYmxlLgogICAqICBAcGFyYW0gbGlzdCB0aGUgY29udHJhY3RpbmcgZWxlbWVudCB0YWJsZS4KICAgKiAgQHBhcmFtIG5hbWUgdGhlIGNvbnRyYWN0aW5nIGNoYXIgc3RyaW5nLgogICAqICBAcmV0dXJuIHRoZSBjb21wYXJpc29uIG9yZGVyIG9mIHRoZSBjb250cmFjdGluZyBjaGFyYWN0ZXIuCiAgICovCiAgc3RhdGljICAgICAgICBpbnQzMl90ICAgICAgICAgICAgIGdldEVudHJ5KCAgIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50KiAgICAgbGlzdCwgCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0ICAgVW5pY29kZVN0cmluZyYgICAgICAgICAgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgVUJvb2wgICAgICAgICAgICAgICAgICAgIGZ3ZCk7CgogIC8qKgogICAqIEZsYXR0ZW5zIHRoZSBnaXZlbiBvYmplY3QgcGVyc2lzdGVudGx5IHRvIGEgZmlsZS4gIFRoZSBmaWxlIG5hbWUKICAgKiBhcmd1bWVudCBzaG91bGQgYmUgYSBwYXRoIG5hbWUgdGhhdCBjYW4gYmUgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZQogICAqIHVuZGVybHlpbmcgT1MuICBPbmNlIGEgUnVsZUJhc2VkQ29sbGF0b3IgaGFzIGJlZW4gd3JpdHRlbiB0byBhIGZpbGUsCiAgICogaXQgY2FuIGJlIHJlc3VycmVjdGVkIGJ5IGNhbGxpbmcgdGhlIFJ1bGVCYXNlZENvbGxhdG9yKGNvbnN0IGNoYXIqKQogICAqIGNvbnN0cnVjdG9yLCB3aGljaCBvcGVyYXRlcyB2ZXJ5IHF1aWNrbHkuCiAgICogQHBhcmFtIGZpbGVOYW1lIHRoZSBvdXRwdXQgZmlsZSBuYW1lLgogICAqIEByZXR1cm4gVFJVRSBpZiB3cml0aW5nIHRvIHRoZSBmaWxlIHdhcyBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UuCiAgICovCiAgVUJvb2wgICAgICAgICAgICAgIHdyaXRlVG9GaWxlKGNvbnN0IGNoYXIqIGZpbGVOYW1lKSBjb25zdDsgLy8gVHJ1ZSBvbiBzdWNjZXNzCiAgLyogIFVCb29sICAgICAgICAgICAgICBwcmVwYXJlRm9yQnVuZGxlKCkgY29uc3Q7Ki8KCiAgLyoqCiAgICogQWRkIHRoaXMgdGFibGUgY29sbGF0aW9uIHRvIHRoZSBjYWNoZS4gIFRoaXMgaW52b2x2ZXMgYWRkaW5nIHRoZQogICAqIGVuY2xvc2VkIFRhYmxlQ29sbGF0aW9uRGF0YSB0byB0aGUgY2FjaGUsIGFuZCB0aGVuIG1hcmtpbmcgb3VyCiAgICogcG9pbnRlciBhcyAibm90IG93bmVkIiBieSBzZXR0aW5nIGRhdGFJc093bmVkIHRvIGZhbHNlLgogICAqIEBwYXJhbSBrZXkgdGhlIHVuaXF1ZSB0aGF0IHJlcHJlc2VudHMgdGhpcyBjb2xsYXRpb24gZGF0YSBvYmplY3QuCiAgICovCiAgdm9pZCAgICAgICAgICAgICAgICBhZGRUb0NhY2hlKCAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGtleSk7CgogIC8qKgogICAqIFJ1bGVCYXNlZENvbGxhdG9yIGNvbnN0cnVjdG9yLiAgVGhpcyBjb25zdHJ1Y3RvciB0YWtlcyBhIGxvY2FsZS4gIFRoZSBvbmx5CiAgICogY2FsbGVyIG9mIHRoaXMgY2xhc3Mgc2hvdWxkIGJlIENvbGxhdG9yOjpjcmVhdGVJbnN0YW5jZSgpLiAgSWYgY3JlYXRlSW5zdGFuY2UoKQogICAqIGhhcHBlbnMgdG8ga25vdyB0aGF0IHRoZSByZXF1ZXN0ZWQgbG9jYWxlJ3MgY29sbGF0aW9uIGlzIGltcGxlbWVudGVkIGFzCiAgICogYSBSdWxlQmFzZWRDb2xsYXRvciwgaXQgY2FuIHRoZW4gY2FsbCB0aGlzIGNvbnN0cnVjdG9yLiAgT1RIRVJXSVNFIElUIFNIT1VMRE4nVCwKICAgKiBzaW5jZSB0aGlzIGNvbnN0cnVjdG9yIEFMV0FZUyBSRVRVUk5TIEEgVkFMSUQgQ09MTEFUSU9OIFRBQkxFLiAgSXQgZG9lcyB0aGlzCiAgICogYnkgZmFsbGluZyBiYWNrIHRvIGRlZmF1bHRzLgogICAqLwogIFJ1bGVCYXNlZENvbGxhdG9yKCAgICAgIGNvbnN0IExvY2FsZSYgZGVzaXJlZExvY2FsZSwKICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwogIC8qKgogICAqIEludGVybmFsIGNvbnN0cnVjdEZyb21YeXgoKSBtZXRob2RzLiAgVGhlc2UgbWV0aG9kcyBkbyBvYmplY3QgY29uc3RydWN0aW9uCiAgICogZnJvbSB2YXJpb3VzIHNvdXJjZXMuICBUaGV5IGFjdCBsaWtlIGFzc2lnbm1lbnQgb3BlcmF0b3JzOyB3aGF0ZXZlciB1c2VkCiAgICogdG8gYmUgaW4gdGhpcyBvYmplY3QgaXMgZGlzY2FyZGVkLiAgPFA+RlJPTSBSVUxFUy4gIFRoaXMgY29uc3RydWN0b3IgdHVybnMKICAgKiBhcm91bmQgYW5kIGNhbGxzIGJ1aWxkKCkuICA8UD5GUk9NIENBQ0hFLiAgVGhpcyBjb25zdHJ1Y3RvciB0cmllcyB0byBnZXQgdGhlCiAgICogcmVxdWVzdGVkIGNhY2hlZCBUYWJsZUNvbGxhdGlvbkRhdGEgb2JqZWN0LCBhbmQgd3JhcCB1cyBhcm91bmQgaXQuICA8UD5GUk9NIEZJTEUuCiAgICogVGhlcmUgYXJlIHR3byBjb25zdHJ1Y3RvcnMgbmFtZWQgY29uc3RydWN0RnJvbUZpbGUoKS4gIE9uZSB0YWtlcyBhIGNvbnN0IGNoYXIqOgogICAqIHRoaXMgaXMgYSBwYXRoIG5hbWUgdG8gYmUgcGFzc2VkIGRpcmVjdGx5IHRvIHRoZSBob3N0IE9TLCB3aGVyZSBhIGZsYXR0ZW5lZAogICAqIHRhYmxlIGNvbGxhdGlvbiAocHJvZHVjZWQgYnkgd3JpdGVUb0ZpbGUoKSkgcmVzaWRlcy4gIFRoZSBvdGhlciBtZXRob2QgdGFrZXMKICAgKiBhIExvY2FsZSwgYW5kIGEgVW5pY29kZVN0cmluZyBsb2NhbGUgZmlsZSBuYW1lLiAgVGhlIGRpc3RpbmN0aW9uIGlzIHRoaXM6CiAgICogdGhlIExvY2FsZSBpcyB0aGUgbG9jYWxlIHdlIGFyZSBzZWVraW5nLiAgVGhlIGZpbGUgbmFtZSBpcyB0aGUgbmFtZSBvZiB0aGUKICAgKiBkYXRhIGZpbGUgKGVpdGhlciBiaW5hcnksIGFzIHByb2R1Y2VkIGJ5IHdyaXRlVG9GaWxlKCksIG9yIEFTQ0lJLCBhcyByZWFkCiAgICogYnkgUmVzb3VyY2VCdW5kbGUpLiAgV2l0aGluIHRoZSBmaWxlLCBpZiBpdCBpcyBmb3VuZCwgdGhlIG1ldGhvZCB3aWxsIGxvb2sKICAgKiBmb3IgdGhlIGdpdmVuIExvY2FsZS4KICAgKi8KICB2b2lkICAgICAgICAgICAgICAgIGNvbnN0cnVjdEZyb21SdWxlcyggY29uc3QgVW5pY29kZVN0cmluZyYgcnVsZXMsCiAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwogIHZvaWQgICAgICAgICAgICAgICAgY29uc3RydWN0RnJvbUZpbGUoICBjb25zdCBMb2NhbGUmICAgICAgICAgICBsb2NhbGUsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiAgICBsb2NhbGVGaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgIFVCb29sICAgICAgICAgICAgICAgICAgdHJ5QmluYXJ5RmlsZSwKICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgICAgICAgICBzdGF0dXMpOwogIHZvaWQgICAgICAgICAgICAgICAgY29uc3RydWN0RnJvbUZpbGUoICBjb25zdCBjaGFyKiBmaWxlTmFtZSwKICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgdm9pZCAgICAgICAgICAgICAgICBjb25zdHJ1Y3RGcm9tQ2FjaGUoIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGtleSwKICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7CiAgY29uc3QgY2hhciogICAgICAgICBjb25zdHJ1Y3RGcm9tQnVuZGxlKGNvbnN0IExvY2FsZSYgZmlsZU5hbWUsCgkJCQkJICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIEludGVybmFsIFN0YXRpYyBVdGlsaXR5IE1ldGhvZHMKICAvKioKICAgKiBDcmVhdGVzIHRoZSBwYXRoIG5hbWUgd2l0aCBnaXZlbiBpbmZvcm1hdGlvbi4KICAgKiBAcGFyYW0gcHJlZml4IHRoZSBwcmVmaXggb2YgdGhlIGZpbGUgbmFtZS4KICAgKiBAcGFyYW0gbmFtZSB0aGUgYWN0dWFsIGZpbGUgbmFtZS4KICAgKiBAcGFyYW0gc3VmZml4IHRoZSBzdWZmaXggb2YgdGhlIGZpbGUgbmFtZS4KICAgKiBAcmV0dXJuIHRoZSBnZW5lcmF0ZWQgZmlsZSBuYW1lLgogICAqLwogIHN0YXRpYyAgY2hhciogICAgICAgICAgICAgICBjcmVhdGVQYXRoTmFtZSggY29uc3QgVW5pY29kZVN0cmluZyYgICAgcHJlZml4LAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmICAgIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgICAgc3VmZml4KTsKCiAgc3RhdGljIFVCb29sIGluaXRNdXRleCh2b2lkKTsKCiAgaW50MzJfdCBnZXRTdHJlbmd0aE9yZGVyKE5vcm1hbGl6ZXJJdGVyYXRvciogY3Vyc29yLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSBzdGF0dXMpIGNvbnN0OwogIFZlY3Rvck9mSW50KiBtYWtlUmVvcmRlcmVkQnVmZmVyKE5vcm1hbGl6ZXJJdGVyYXRvciogY3Vyc29yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDaGFyIGNvbEZpcnN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgbGFzdFZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZlY3Rvck9mSW50KiBsYXN0RXhwYW5zaW9uKSBjb25zdDsKICBpbnQzMl90IHN0cmVuZ3RoT3JkZXIoaW50MzJfdCB2YWx1ZSkgY29uc3QgOwogIGludDMyX3QgbmV4dENvbnRyYWN0Q2hhcihOb3JtYWxpemVySXRlcmF0b3IgKmN1cnNvciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDaGFyIGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwogIC8qKgogICAgICogQ2hvcHMgb2ZmIHRoZSBsYXN0IHBvcnRpb24gb2YgdGhlIGxvY2FsZSBuYW1lLiAgRm9yIGV4YW1wbGUsIGZyb20gImVuX1VTX0NBIgogICAgICogdG8gImVuX1VTIiBhbmQgImVuX1VTIiB0byAiZW4iLgogICAgICogQHBhcmFtIGxvY2FsZU5hbWUgdGhlIGxvY2FsZSBuYW1lLgogICAgICovCiAgc3RhdGljICB2b2lkICAgICAgICAgICAgICAgIGNob3BMb2NhbGUoVW5pY29kZVN0cmluZyYgICBsb2NhbGVOYW1lKTsKCiAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vIENvbnN0YW50cwoKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBVTk1BUFBFRDsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBDSEFSSU5ERVg7ICAvLyBuZWVkIGxvb2sgdXAgaW4gLmNvbW1pdCgpCiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgRVhQQU5EQ0hBUklOREVYOyAvLyBFeHBhbmQgaW5kZXggZm9sbG93cwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIENPTlRSQUNUQ0hBUklOREVYOyAgLy8gY29udHJhY3QgaW5kZXhlcyBmb2xsb3cKCiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgUFJJTUFSWU9SREVSSU5DUkVNRU5UOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIE1BWElHTk9SQUJMRTsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBTRUNPTkRBUllPUkRFUklOQ1JFTUVOVDsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBURVJUSUFSWU9SREVSSU5DUkVNRU5UOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFBSSU1BUllPUkRFUk1BU0s7CiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgU0VDT05EQVJZT1JERVJNQVNLOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFRFUlRJQVJZT1JERVJNQVNLOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFNFQ09OREFSWVJFU0VUTUFTSzsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBJR05PUkFCTEVNQVNLOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFBSSU1BUllESUZGRVJFTkNFT05MWTsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBTRUNPTkRBUllESUZGRVJFTkNFT05MWTsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBQUklNQVJZT1JERVJTSElGVDsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBTRUNPTkRBUllPUkRFUlNISUZUOwogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIFNPUlRLRVlPRkZTRVQ7CiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgQ09OVFJBQ1RDSEFST1ZFUkZMT1c7CgogIHN0YXRpYyAgY29uc3QgICBpbnQzMl90ICAgICAgICAgICAgIENPTEVMRU1FTlRTVEFSVDsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBQUklNQVJZTE9XWkVST01BU0s7CiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgUkVTRVRTRUNPTkRBUllURVJUSUFSWTsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBSRVNFVFRFUlRJQVJZOwoKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBJR05PUkFCTEU7CiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgUFJJTUlHTk9SQUJMRTsKICBzdGF0aWMgIGNvbnN0ICAgaW50MzJfdCAgICAgICAgICAgICBTRUNJR05PUkFCTEU7CiAgc3RhdGljICBjb25zdCAgIGludDMyX3QgICAgICAgICAgICAgVEVSSUdOT1JBQkxFOwoKCiAgc3RhdGljIGNvbnN0IGludDE2X3QgICAgICAgICAgICAgICAgRklMRUlEOwoKICBzdGF0aWMgICAgICAgVW5pY29kZVN0cmluZyAgICAgIERFRkFVTFRSVUxFUzsKCiAgc3RhdGljICBjb25zdCBjaGFyKiAgICAgICAgICAgICBrRmlsZW5hbWVTdWZmaXg7CgogIHN0YXRpYyBVQm9vbCBpc011dGV4SW5pdGVkOwogIHN0YXRpYyBVTVRYIGNvbGxNdXRleDsKICBzdGF0aWMgVUNoYXIgY2FjaGVLZXk7CgogICAgICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAvLyBEYXRhIE1lbWJlcnMKCiAgVUJvb2wgICAgICAgICAgICAgIGlzT3Zlcklnbm9yZTsKICBVQ2hhciAgICAgICAgICAgICBsYXN0Q2hhcjsKICBNZXJnZUNvbGxhdGlvbiogICAgIG1QYXR0ZXJuOwogIFVuaWNvZGVTdHJpbmcgICAgICAgc2J1ZmZlcjsKICBVbmljb2RlU3RyaW5nICAgICAgIHRidWZmZXI7CiAgVW5pY29kZVN0cmluZyAgICAgICBrZXk7CiAgTm9ybWFsaXplckl0ZXJhdG9yICAqY3Vyc29yMTsKICBOb3JtYWxpemVySXRlcmF0b3IgICpjdXJzb3IyOwogIFVCb29sICAgICAgICAgICAgICBkYXRhSXNPd25lZDsKICBUYWJsZUNvbGxhdGlvbkRhdGEqIGRhdGE7CiAgTm9ybWFsaXplcjo6RU1vZGUgZkRlZmF1bHREZWNvbXA7CiAgdm9pZCAqKmZTb21lTWVtb3J5OwogIGludDMyX3QgKmZTaXplczsKICBpbnQzMl90IGZBdmFpbGFibGVNZW1vcnk7CiAgaW50MzJfdCBmVXNlZE1lbW9yeTsKCiAgdm9pZCAqZ2V0U29tZU1lbW9yeShpbnQzMl90IHNpemUpOwoKfTsKCgppbmxpbmUgVUJvb2wKUnVsZUJhc2VkQ29sbGF0b3I6Om9wZXJhdG9yIT0oY29uc3QgQ29sbGF0b3ImIG90aGVyKSBjb25zdAp7CiAgcmV0dXJuICEoKnRoaXMgPT0gb3RoZXIpOwp9CgppbmxpbmUgdm9pZApSdWxlQmFzZWRDb2xsYXRvcjo6YWRkQ29udHJhY3RPcmRlcihjb25zdCBVbmljb2RlU3RyaW5nICZncm91cENoYXJzLAogICAgICAgICAgICAgICAgICAgIGludDMyX3QgICAgICAgICAgICAgICAgYW5PcmRlciwKICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICAgICAgICAgICAgJnN0YXR1cykKewogIGFkZENvbnRyYWN0T3JkZXIoZ3JvdXBDaGFycywgYW5PcmRlciwgVFJVRSwgc3RhdHVzKTsKfQoKI2VuZGlmCg==