Transaction executed successfully
Transaction Details
Inspect execution, participants, message data, gas usage, events and raw transaction data.
Transaction hash
52C5F96177339E5B1F49DAF17C4447E417D077EA282E5113CE1CB6CD372BB25A
Transaction overview
Execution summary
TX INDEX
0
Position in block
GAS WANTED
100,000,000
Requested gas limit
GAS USED
61,442,425
Gas consumed
FEE
200000ugnot
Transaction fee
Participants
Message
Message #1
m_addpkg
Arguments
g136j0m08pkm2lwwde9dmlx8uee26llent9s5cpf20000000ugnot
Execution log
msg:0,success:true,log:,events:[]
Events
No events emitted by this transaction.
Raw encoded transaction
CsnUAgoML3ZtLm1fYWRkcGtnErfUAgooZzEzNmowbTA4cGttMmx3d2RlOWRtbHg4dWVlMjZsbGVudDlzNWNwZhL60wIKEW1lbWJhX2ZlZWRiYWNrX3YyEiRnbm8ubGFuZC9yL3NhbWNyZXcvbWVtYmFfZmVlZGJhY2tfdjIaSwoLZ25vbW9kLnRvbWwSPG1vZHVsZSA9ICJnbm8ubGFuZC9yL3NhbWNyZXcvbWVtYmFfZmVlZGJhY2tfdjIiCmdubyA9ICIwLjkiChrM0gIKFW1lbWJhX2ZlZWRiYWNrX3YyLmdubxKx0gJwYWNrYWdlIG1lbWJhX2ZlZWRiYWNrX3YyCgovLyBtZW1iYV9kYW9fY2hhbm5lbHMg4oCUIFNvY2lhbCBmZWVkIHJlYWxtIGZvciBNZW1iYURBTy4KLy8KLy8gUHJvdmlkZXMgRGlzY29yZC1saWtlIGNoYW5uZWxzIHdpdGggdGhyZWFkcywgcmVwbGllcywgYW5kIG1vZGVyYXRpb24uCi8vIFRoZSBSZW5kZXIoKSBvdXRwdXQgTVVTVCBtYXRjaCB0aGUgcmVnZXggcGF0dGVybnMgaW4gcGFyc2VyLnRzIChmcm9udGVuZCkuCi8vCi8vIFJlbmRlcigpIGNvbnRyYWN0IChmcm9tIHBhcnNlci50cyk6Ci8vCi8vICAgSG9tZSDigJQgUmVuZGVyKCIiKToKLy8gICAgICMgQm9hcmROYW1lCi8vICAgICBkZXNjcmlwdGlvbgovLyAgICAgIyMgQ2hhbm5lbHMKLy8gICAgIC0gWyNuYW1lXSg6X2NoYW5uZWwvbmFtZSkg8J+ToiAoTiB0aHJlYWRzKQovLwovLyAgIENoYW5uZWwg4oCUIFJlbmRlcigiY2hhbm5lbE5hbWUiKToKLy8gICAgICMgI2NoYW5uZWxOYW1lCi8vICAgICAjIyMgW1RpdGxlXSg6Y2hhbm5lbC9pZCkKLy8gICAgIGJ5IGcxYWRkci4uLiB8IE4gcmVwbGllcyB8IGJsb2NrIEgKLy8KLy8gICBUaHJlYWQg4oCUIFJlbmRlcigiY2hhbm5lbC9pZCIpOgovLyAgICAgIyBUaXRsZQovLyAgICAgYm9keQovLyAgICAgLS0tCi8vICAgICAqUG9zdGVkIGJ5IGcxYWRkciBhdCBibG9jayBIKgovLyAgICAgIyMgUmVwbGllcwovLyAgICAgKipnMWFkZHIuLi4qKiAoYmxvY2sgSCkKLy8gICAgIHJlcGx5IGJvZHkKLy8gICAgIC0tLQovLwovLyAgIEFDTCDigJQgUmVuZGVyKCJfX2FjbC9jaGFubmVsIik6Ci8vICAgICByZWFkOnJvbGUxLHJvbGUyCi8vICAgICB3cml0ZTpyb2xlMSxyb2xlMixyb2xlMwovLyAgICAgdHlwZTp0ZXh0Ci8vCi8vIFNlY3VyaXR5OgovLyAgIC0gQWxsIHdyaXRlIG9wZXJhdGlvbnMgcmVxdWlyZSBtZW1iZXJzaGlwIChBZGRNZW1iZXIgYnkgb3duZXIpCi8vICAgLSBQb3N0VGhyZWFkL1Bvc3RSZXBseSBjaGVjayBjYWxsZXIncyByb2xlcyBhZ2FpbnN0IGNoYW5uZWwgV3JpdGVSb2xlcwovLyAgIC0gQ3JlYXRlQ2hhbm5lbC9SZW1vdmVUaHJlYWQgcmVzdHJpY3RlZCB0byBvd25lciBvbmx5Ci8vICAgLSBGbGFnVGhyZWFkIHJlcXVpcmVzIG1lbWJlcnNoaXAgKHByZXZlbnRzIHN5YmlsIGZsYWdnaW5nIGJ5IG5vbi1tZW1iZXJzKQovLyAgIC0gRWRpdFRocmVhZC9EZWxldGVUaHJlYWQgcmVxdWlyZSBtZW1iZXJzaGlwICsgb3JpZ2luYWwgYXV0aG9yIGNoZWNrCi8vCi8vIE1vZGVyYXRpb246IGZsYWcg4oaSIHRocmVzaG9sZCAoMykg4oaSIGF1dG8taGlkZSDihpIgREFPIHZvdGUg4oaSIHJlbW92ZQoKaW1wb3J0ICgKCSJjaGFpbiIKCSJjaGFpbi9ydW50aW1lIgoJImNoYWluL3J1bnRpbWUvdW5zYWZlIgoJInN0cmNvbnYiCgkic3RyaW5ncyIKCgkiZ25vLmxhbmQvcC9zYW1jcmV3L2F2bCIKCSJnbm8ubGFuZC9wL250L3VmbXQvdjAiCikKCi8vIOKUgOKUgCBDb25zdGFudHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgpjb25zdCAoCglNYXhQb3N0TGVuICAgICAgICA9IDUwMDAKCU1heFRpdGxlTGVuICAgICAgID0gMjAwCglNYXhDaGFubmVscyAgICAgICA9IDIwCglNYXhUaHJlYWRzUGVyQ2hhbiA9IDUwMAoJRmxhZ1RocmVzaG9sZCAgICAgPSAzIC8vIGZsYWdzIGJlZm9yZSBhdXRvLWhpZGUKCgkvLyBBQUEtMSBCMSDigJQgcmVuZGVyLURvUyBib3VuZHMgZm9yIHJlcGxpZXMgKG1pcnJvcnMgTWF4VGhyZWFkc1BlckNoYW4pLgoJLy8gcmVuZGVyVGhyZWFkIG11c3QgbmV2ZXIgaXRlcmF0ZSB0aGUgbW9ub3RvbmljIHJlcGx5IGNvdW50ZXIgKHBvc3QrZGVsZXRlCgkvLyByZXBseSBzcGFtIHdvdWxkIGluZmxhdGUgaXQgd2l0aG91dCBib3VuZCDihpIgdW5ib3VuZGVkIHJlbmRlciBzY2FuIOKGkgoJLy8gdGhyZWFkIHBlcm1hbmVudGx5IHVucmVuZGVyYWJsZSBwYXN0IG1heEdhc1F1ZXJ5KS4gVGhlIGxpdmUtcmVwbHkgaW5kZXgKCS8vIChyZXBseUxpdmUvcmVwbHlMaXZlSURzKSBjYXBzIHRoZSBsaXZlIHNldCwgYW5kIHJlbmRlclRocmVhZCBwYWdpbmF0ZXMgYQoJLy8gZml4ZWQgd2luZG93IG92ZXIgaXQsIHNvIHJlbmRlciBjb3N0IGlzIGJvdW5kZWQgcmVnYXJkbGVzcyBvZiBjaHVybi4KCU1heFJlcGxpZXNQZXJUaHJlYWQgPSA1MDAgLy8gbGl2ZSAobm9uLWRlbGV0ZWQpIHJlcGxpZXMgcGVyIHRocmVhZAoJUmVwbHlQYWdlU2l6ZSAgICAgICA9IDUwICAvLyByZXBsaWVzIHJlbmRlcmVkIHBlciBwYWdlCikKCi8vIOKUgOKUgCBUeXBlcyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCnR5cGUgQ2hhbm5lbFR5cGUgc3RyaW5nCgpjb25zdCAoCglDaGFubmVsVGV4dCAgICAgICAgICBDaGFubmVsVHlwZSA9ICJ0ZXh0IgoJQ2hhbm5lbEFubm91bmNlbWVudHMgQ2hhbm5lbFR5cGUgPSAiYW5ub3VuY2VtZW50cyIKCUNoYW5uZWxSZWFkb25seSAgICAgIENoYW5uZWxUeXBlID0gInJlYWRvbmx5IgopCgp0eXBlIENoYW5uZWwgc3RydWN0IHsKCU5hbWUgICAgICAgIHN0cmluZwoJRGVzY3JpcHRpb24gc3RyaW5nCglUeXBlICAgICAgICBDaGFubmVsVHlwZQoJQXJjaGl2ZWQgICAgYm9vbAoJUmVhZFJvbGVzICAgW11zdHJpbmcgLy8gcm9sZXMgdGhhdCBjYW4gcmVhZAoJV3JpdGVSb2xlcyAgW11zdHJpbmcgLy8gcm9sZXMgdGhhdCBjYW4gd3JpdGUKfQoKdHlwZSBUaHJlYWQgc3RydWN0IHsKCUlEICAgICAgICB1aW50NjQKCUNoYW5uZWwgICBzdHJpbmcKCVRpdGxlICAgICBzdHJpbmcKCUJvZHkgICAgICBzdHJpbmcKCUF1dGhvciAgICBhZGRyZXNzCglCbG9ja0ggICAgaW50NjQKCUVkaXRlZCAgICBib29sCglFZGl0ZWRBdCAgaW50NjQKCURlbGV0ZWQgICBib29sCglGbGFnQ291bnQgaW50CglIaWRkZW4gICAgYm9vbAp9Cgp0eXBlIFJlcGx5IHN0cnVjdCB7CglJRCAgICAgICB1aW50NjQKCVRocmVhZElEIHVpbnQ2NAoJQ2hhbm5lbCAgc3RyaW5nCglCb2R5ICAgICBzdHJpbmcKCUF1dGhvciAgIGFkZHJlc3MKCUJsb2NrSCAgIGludDY0CglFZGl0ZWQgICBib29sCn0KCi8vIOKUgOKUgCBTdGF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCnZhciAoCgljaGFubmVscyAgICAgICphdmwuVHJlZSAvLyBuYW1lIC0+ICpDaGFubmVsCgl0aHJlYWRzICAgICAgICphdmwuVHJlZSAvLyAiY2hhbm5lbC9pZCIgLT4gKlRocmVhZAoJcmVwbGllcyAgICAgICAqYXZsLlRyZWUgLy8gImNoYW5uZWwvdGhyZWFkSWQvcmVwbHlJZCIgLT4gKlJlcGx5Cgl0aHJlYWRDb3VudCAgICphdmwuVHJlZSAvLyBjaGFubmVsIC0+IHVpbnQ2NCAobmV4dCB0aHJlYWQgSUQsIG1vbm90b25pYykKCXRocmVhZExpdmUgICAgKmF2bC5UcmVlIC8vIGNoYW5uZWwgLT4gdWludDY0IChjdXJyZW50bHkgbGl2ZSAobm9uLWRlbGV0ZWQpIHRocmVhZHMpCgl0aHJlYWRMaXZlSURzICphdmwuVHJlZSAvLyBjaGFubmVsIC0+IFtddWludDY0IChsaXZlIHRocmVhZCBJRHMsIGFzY2VuZGluZykg4oCUIGJvdW5kcyByZW5kZXJDaGFubmVsCglyZXBseUNvdW50ICAgICphdmwuVHJlZSAvLyAiY2hhbm5lbC90aHJlYWRJZCIgLT4gdWludDY0IChuZXh0IHJlcGx5IElELCBtb25vdG9uaWMpCglyZXBseUxpdmUgICAgICphdmwuVHJlZSAvLyAiY2hhbm5lbC90aHJlYWRJZCIgLT4gdWludDY0IChjdXJyZW50bHkgbGl2ZSAobm9uLWRlbGV0ZWQpIHJlcGxpZXMpCglyZXBseUxpdmVJRHMgICphdmwuVHJlZSAvLyAiY2hhbm5lbC90aHJlYWRJZCIgLT4gW111aW50NjQgKGxpdmUgcmVwbHkgSURzLCBhc2NlbmRpbmcpIOKAlCBib3VuZHMgcmVuZGVyVGhyZWFkCgl0aHJlYWRUb21iICAgICphdmwuVHJlZSAvLyBjaGFubmVsIC0+IFtddWludDY0IChzb2Z0LWRlbGV0ZWQgdGhyZWFkIElEcyBhd2FpdGluZyBoYXJkLUdDIHZpYSBTd2VlcFRvbWJzdG9uZXMpIOKAlCBCMgoJZmxhZ3MgICAgICAgICAqYXZsLlRyZWUgLy8gImNoYW5uZWwvdGhyZWFkSWQiIC0+ICphdmwuVHJlZSAoZmxhZ2dlciBhZGRyIC0+IGJvb2wpCgljaGFubmVsT3JkZXIgIFtdc3RyaW5nICAvLyBvcmRlcmVkIGNoYW5uZWwgbmFtZXMKCgkvLyBNZW1iZXJzaGlwOiBhZGRyZXNzIC0+IGNvbW1hLXNlcGFyYXRlZCByb2xlcyAoZS5nLiwgImFkbWluLGRldiIpCgltZW1iZXJzICphdmwuVHJlZQoJbWVtYmVyc2hpcFJldmlzaW9uIHVpbnQ2NAoJcGF1c2VkICBib29sCgkvLyBvd25lciBpcyB0aGUgcHVibGlzaGluZyB0cmFuc2FjdGlvbidzIHNpZ25lciwgY2FwdHVyZWQgYXQgcGFja2FnZSBsb2FkIChvbgoJLy8gZ25vbGFuZC0xIHRoZSBzYW1jcmV3IG5hbWVzcGFjZSBtdWx0aXNpZywgdGhlIHN0YW1wZWQgY3JlYXRvciBhdCBlbmFibGUKCS8vIHRpbWUpLiBwZW5kaW5nT3duZXIgaXMgdGhlIHN0YWdlZCBzdWNjZXNzb3Igb2YgYSB0d28tc3RlcCBoYW5kb2ZmLCBvciBlbXB0eS4KCW93bmVyICAgICAgICA9IHVuc2FmZS5PcmlnaW5DYWxsZXIoKQoJcGVuZGluZ093bmVyIGFkZHJlc3MKKQoKZnVuYyBpbml0KCkgewoJY2hhbm5lbHMgPSBhdmwuTmV3VHJlZSgpCgl0aHJlYWRzID0gYXZsLk5ld1RyZWUoKQoJcmVwbGllcyA9IGF2bC5OZXdUcmVlKCkKCXRocmVhZENvdW50ID0gYXZsLk5ld1RyZWUoKQoJdGhyZWFkTGl2ZSA9IGF2bC5OZXdUcmVlKCkKCXRocmVhZExpdmVJRHMgPSBhdmwuTmV3VHJlZSgpCglyZXBseUNvdW50ID0gYXZsLk5ld1RyZWUoKQoJcmVwbHlMaXZlID0gYXZsLk5ld1RyZWUoKQoJcmVwbHlMaXZlSURzID0gYXZsLk5ld1RyZWUoKQoJdGhyZWFkVG9tYiA9IGF2bC5OZXdUcmVlKCkKCWZsYWdzID0gYXZsLk5ld1RyZWUoKQoJY2hhbm5lbE9yZGVyID0gW11zdHJpbmd7fQoJbWVtYmVycyA9IGF2bC5OZXdUcmVlKCkKCW1lbWJlcnMuU2V0KG93bmVyLlN0cmluZygpLCAiYWRtaW4iKQoKCS8vIFB1YmxpYyBmZWVkYmFjayBib2FyZDogYW55b25lIGNhbiBwb3N0IGluIHRoZSBvcGVuIGNoYW5uZWxzIChXcml0ZVJvbGVzCgkvLyAiKiIpOyB0aGUgZnJvbnRlbmQgcmVhZHMgdGhlICJnZW5lcmFsIiBjaGFubmVsLiAiYW5ub3VuY2VtZW50cyIgc3RheXMKCS8vIGFkbWluLXdyaXRlLW9ubHkgZm9yIG9mZmljaWFsIHJlc3BvbnNlcy4gUmVhZCBpcyBvcGVuIGV2ZXJ5d2hlcmUuCglhZGRDaGFubmVsKCJnZW5lcmFsIiwgIkNvbW11bml0eSBmZWVkYmFjayDigJQgYW55b25lIGNhbiBwb3N0IiwgQ2hhbm5lbFRleHQsCgkJW11zdHJpbmd7IioifSwgW11zdHJpbmd7IioifSkKCWFkZENoYW5uZWwoImZlYXR1cmUtcmVxdWVzdHMiLCAiUHJvcG9zZSBhbmQgZGlzY3VzcyBuZXcgZmVhdHVyZXMiLCBDaGFubmVsVGV4dCwKCQlbXXN0cmluZ3siKiJ9LCBbXXN0cmluZ3siKiJ9KQoJYWRkQ2hhbm5lbCgiYnVncyIsICJSZXBvcnQgYnVncyBhbmQgaXNzdWVzIiwgQ2hhbm5lbFRleHQsCgkJW11zdHJpbmd7IioifSwgW11zdHJpbmd7IioifSkKCWFkZENoYW5uZWwoImFubm91bmNlbWVudHMiLCAiT2ZmaWNpYWwgTWVtYmEgYW5ub3VuY2VtZW50cyDigJQgYWRtaW4td3JpdGUtb25seSIsIENoYW5uZWxBbm5vdW5jZW1lbnRzLAoJCVtdc3RyaW5neyIqIn0sIFtdc3RyaW5neyJhZG1pbiJ9KQp9CgovLyDilIDilIAgQ2hhbm5lbCBNYW5hZ2VtZW50IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAoKZnVuYyBhZGRDaGFubmVsKG5hbWUsIGRlc2NyaXB0aW9uIHN0cmluZywgY3R5cGUgQ2hhbm5lbFR5cGUsIHJlYWRSb2xlcywgd3JpdGVSb2xlcyBbXXN0cmluZykgewoJY2ggOj0gJkNoYW5uZWx7CgkJTmFtZTogICAgICAgIG5hbWUsCgkJRGVzY3JpcHRpb246IGRlc2NyaXB0aW9uLAoJCVR5cGU6ICAgICAgICBjdHlwZSwKCQlBcmNoaXZlZDogICAgZmFsc2UsCgkJUmVhZFJvbGVzOiAgIHJlYWRSb2xlcywKCQlXcml0ZVJvbGVzOiAgd3JpdGVSb2xlcywKCX0KCWNoYW5uZWxzLlNldChuYW1lLCBjaCkKCXRocmVhZENvdW50LlNldChuYW1lLCB1aW50NjQoMCkpCgl0aHJlYWRMaXZlLlNldChuYW1lLCB1aW50NjQoMCkpCgljaGFubmVsT3JkZXIgPSBhcHBlbmQoY2hhbm5lbE9yZGVyLCBuYW1lKQp9CgovLyDilIDilIAgTWVtYmVyc2hpcCBNYW5hZ2VtZW50IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAoKLy8gQWRkTWVtYmVyIGFkZHMgYW4gYWRkcmVzcyB3aXRoIHNwZWNpZmllZCByb2xlcy4gT25seSB0aGUgb3duZXIgY2FuIGNhbGwgdGhpcy4KLy8gcm9sZXMgaXMgYSBjb21tYS1zZXBhcmF0ZWQgbGlzdCAoZS5nLiwgImFkbWluLGRldiIgb3IgIm1lbWJlciIpLgpmdW5jIEFkZE1lbWJlcihjdXIgcmVhbG0sIGFkZHIgYWRkcmVzcywgcm9sZXMgc3RyaW5nKSB7Cglhc3NlcnRDYWxsZXJJc093bmVyKCkKCWlmIGFkZHIgPT0gIiIgewoJCXBhbmljKCJhZGRyZXNzIGNhbm5vdCBiZSBlbXB0eSIpCgl9CglpZiBsZW4ocm9sZXMpID09IDAgewoJCXBhbmljKCJyb2xlcyBjYW5ub3QgYmUgZW1wdHkiKQoJfQoJaWYgIWlzVmFsaWRSb2xlcyhyb2xlcykgewoJCXBhbmljKCJpbnZhbGlkIHJvbGVzOiBtdXN0IGJlIGNvbW1hLXNlcGFyYXRlZCBhbHBoYW51bWVyaWMgb25seSIpCgl9CgltZW1iZXJzLlNldChhZGRyLlN0cmluZygpLCByb2xlcykKCW1lbWJlcnNoaXBSZXZpc2lvbisrCgoJY2hhaW4uRW1pdCgiTWVtYmVyQWRkZWQiLAoJCSJhZGRyZXNzIiwgYWRkci5TdHJpbmcoKSwKCQkicm9sZXMiLCByb2xlcywKCSkKfQoKLy8gUmVtb3ZlTWVtYmVyIHJlbW92ZXMgYW4gYWRkcmVzcyBmcm9tIHRoZSBtZW1iZXJzaGlwLiBPbmx5IHRoZSBvd25lciBjYW4gY2FsbCB0aGlzLgpmdW5jIFJlbW92ZU1lbWJlcihjdXIgcmVhbG0sIGFkZHIgYWRkcmVzcykgewoJYXNzZXJ0Q2FsbGVySXNPd25lcigpCglpZiBhZGRyID09IG93bmVyIHsKCQlwYW5pYygiY2Fubm90IHJlbW92ZSBvd25lciIpCgl9CglpZiBfLCBleGlzdHMgOj0gbWVtYmVycy5HZXQoYWRkci5TdHJpbmcoKSk7ICFleGlzdHMgewoJCXBhbmljKCJhZGRyZXNzIGlzIG5vdCBhIG1lbWJlcjogIiArIGFkZHIuU3RyaW5nKCkpCgl9CgltZW1iZXJzLlJlbW92ZShhZGRyLlN0cmluZygpKQoJbWVtYmVyc2hpcFJldmlzaW9uKysKCgljaGFpbi5FbWl0KCJNZW1iZXJSZW1vdmVkIiwgImFkZHJlc3MiLCBhZGRyLlN0cmluZygpKQp9CgovLyBVcGRhdGVNZW1iZXJSb2xlcyB1cGRhdGVzIHRoZSByb2xlcyBmb3IgYW4gZXhpc3RpbmcgbWVtYmVyLiBPbmx5IHRoZSBvd25lciBjYW4gY2FsbCB0aGlzLgpmdW5jIFVwZGF0ZU1lbWJlclJvbGVzKGN1ciByZWFsbSwgYWRkciBhZGRyZXNzLCBuZXdSb2xlcyBzdHJpbmcpIHsKCWFzc2VydENhbGxlcklzT3duZXIoKQoJaWYgXywgZXhpc3RzIDo9IG1lbWJlcnMuR2V0KGFkZHIuU3RyaW5nKCkpOyAhZXhpc3RzIHsKCQlwYW5pYygiYWRkcmVzcyBpcyBub3QgYSBtZW1iZXI6ICIgKyBhZGRyLlN0cmluZygpKQoJfQoJaWYgbGVuKG5ld1JvbGVzKSA9PSAwIHsKCQlwYW5pYygicm9sZXMgY2Fubm90IGJlIGVtcHR5IikKCX0KCWlmICFpc1ZhbGlkUm9sZXMobmV3Um9sZXMpIHsKCQlwYW5pYygiaW52YWxpZCByb2xlczogbXVzdCBiZSBjb21tYS1zZXBhcmF0ZWQgYWxwaGFudW1lcmljIG9ubHkiKQoJfQoJbWVtYmVycy5TZXQoYWRkci5TdHJpbmcoKSwgbmV3Um9sZXMpCgltZW1iZXJzaGlwUmV2aXNpb24rKwoKCWNoYWluLkVtaXQoIk1lbWJlclJvbGVzVXBkYXRlZCIsICJhZGRyZXNzIiwgYWRkci5TdHJpbmcoKSwgInJvbGVzIiwgbmV3Um9sZXMpCn0KCi8vIFRyYW5zZmVyT3duZXJzaGlwIHN0YWdlcyBhIHN1Y2Nlc3NvciBvd25lci4gTm90aGluZyBtb3ZlcyB1bnRpbCB0aGF0IGFkZHJlc3MKLy8gY2FsbHMgQWNjZXB0T3duZXJzaGlwIHdpdGggaXRzIG93biB0cmFuc2FjdGlvbiwgc28gb3duZXJzaGlwIGNhbiBuZXZlciBsYW5kIG9uCi8vIGFuIGFkZHJlc3MgdGhhdCBjYW5ub3QgYWN0LiBBIGxhdGVyIGNhbGwgcmVwbGFjZXMgdGhlIHN0YWdlZCBhZGRyZXNzOwovLyBDYW5jZWxPd25lcnNoaXBUcmFuc2ZlciB3aXRoZHJhd3MgaXQuCmZ1bmMgVHJhbnNmZXJPd25lcnNoaXAoY3VyIHJlYWxtLCBuZXdPd25lciBhZGRyZXNzKSB7Cglhc3NlcnRDYWxsZXJJc093bmVyKCkKCWlmIG5ld093bmVyID09ICIiIHsKCQlwYW5pYygiYWRkcmVzcyBjYW5ub3QgYmUgZW1wdHkiKQoJfQoJaWYgIW5ld093bmVyLklzVmFsaWQoKSB7CgkJcGFuaWMoImludmFsaWQgYWRkcmVzczogIiArIG5ld093bmVyLlN0cmluZygpKQoJfQoJaWYgbmV3T3duZXIgPT0gb3duZXIgewoJCXBhbmljKCJuZXcgb3duZXIgaXMgdGhlIHNhbWUgYXMgY3VycmVudCBvd25lciIpCgl9CglwZW5kaW5nT3duZXIgPSBuZXdPd25lcgoJY2hhaW4uRW1pdCgiT3duZXJzaGlwVHJhbnNmZXJTdGFydGVkIiwgInBlbmRpbmciLCBuZXdPd25lci5TdHJpbmcoKSkKfQoKLy8gQ2FuY2VsT3duZXJzaGlwVHJhbnNmZXIgd2l0aGRyYXdzIGEgc3RhZ2VkIGhhbmRvZmYuIE93bmVyIG9ubHkuCmZ1bmMgQ2FuY2VsT3duZXJzaGlwVHJhbnNmZXIoY3VyIHJlYWxtKSB7Cglhc3NlcnRDYWxsZXJJc093bmVyKCkKCWlmIHBlbmRpbmdPd25lciA9PSAiIiB7CgkJcGFuaWMoIm5vIHBlbmRpbmcgb3duZXJzaGlwIHRyYW5zZmVyIikKCX0KCWNhbmNlbGxlZCA6PSBwZW5kaW5nT3duZXIKCXBlbmRpbmdPd25lciA9ICIiCgljaGFpbi5FbWl0KCJPd25lcnNoaXBUcmFuc2ZlckNhbmNlbGxlZCIsICJwZW5kaW5nIiwgY2FuY2VsbGVkLlN0cmluZygpKQp9CgovLyBBY2NlcHRPd25lcnNoaXAgY29tcGxldGVzIHRoZSBoYW5kb2ZmLiBPbmx5IHRoZSBzdGFnZWQgcGVuZGluZ093bmVyIG1heSBjYWxsCi8vIGl0LiBUaGUgbmV3IG93bmVyIGdldHMgImFkbWluIiBhZGRlZCB0byB0aGVpciBleGlzdGluZyByb2xlcyAobm90Ci8vIG92ZXJ3cml0dGVuKTsgdGhlIG9sZCBvd25lciBpcyBkZW1vdGVkIGZyb20gImFkbWluIiB0byB0aGVpciBvdGhlciByb2xlcywgb3IKLy8gdG8gIm1lbWJlciIgd2hlbiBub25lIHJlbWFpbi4KZnVuYyBBY2NlcHRPd25lcnNoaXAoY3VyIHJlYWxtKSB7CglpZiAhY3VyLklzQ3VycmVudCgpIHsKCQlwYW5pYygic3Bvb2ZlZCByZWFsbSIpCgl9CgljYWxsZXIgOj0gY3VyLlByZXZpb3VzKCkuQWRkcmVzcygpCglpZiBwZW5kaW5nT3duZXIgPT0gIiIgfHwgY2FsbGVyICE9IHBlbmRpbmdPd25lciB7CgkJcGFuaWMoInVuYXV0aG9yaXplZDogY2FsbGVyICIgKyBjYWxsZXIuU3RyaW5nKCkgKyAiIGlzIG5vdCB0aGUgcGVuZGluZyBvd25lciIpCgl9CglwcmV2T3duZXIgOj0gb3duZXIKCS8vIFByZXNlcnZlIGV4aXN0aW5nIHJvbGVzIGZvciB0aGUgbmV3IG93bmVyLCBlbnN1cmUgdGhleSBoYXZlIGFkbWluCglleGlzdGluZ1JvbGVzIDo9IEdldE1lbWJlclJvbGVzKGNhbGxlcikKCWlmIGV4aXN0aW5nUm9sZXMgPT0gIiIgewoJCW1lbWJlcnMuU2V0KGNhbGxlci5TdHJpbmcoKSwgImFkbWluIikKCX0gZWxzZSBpZiAhaGFzUm9sZShjYWxsZXIsICJhZG1pbiIpIHsKCQltZW1iZXJzLlNldChjYWxsZXIuU3RyaW5nKCksIGV4aXN0aW5nUm9sZXMrIixhZG1pbiIpCgl9CgkvLyBSZW1vdmUgImFkbWluIiBmcm9tIHRoZSBvbGQgb3duZXIncyByb2xlcywga2VlcCBvdGhlciByb2xlcy4KCS8vIElmIG5vIHJvbGVzIHJlbWFpbiwgc2V0IHRvICJtZW1iZXIiLgoJb2xkUm9sZXMgOj0gR2V0TWVtYmVyUm9sZXMocHJldk93bmVyKQoJdmFyIGtlcHQgW11zdHJpbmcKCWZvciBfLCByIDo9IHJhbmdlIHN0cmluZ3MuU3BsaXQob2xkUm9sZXMsICIsIikgewoJCXIgPSBzdHJpbmdzLlRyaW1TcGFjZShyKQoJCWlmIHIgIT0gImFkbWluIiAmJiByICE9ICIiIHsKCQkJa2VwdCA9IGFwcGVuZChrZXB0LCByKQoJCX0KCX0KCWlmIGxlbihrZXB0KSA9PSAwIHsKCQltZW1iZXJzLlNldChwcmV2T3duZXIuU3RyaW5nKCksICJtZW1iZXIiKQoJfSBlbHNlIHsKCQltZW1iZXJzLlNldChwcmV2T3duZXIuU3RyaW5nKCksIHN0cmluZ3MuSm9pbihrZXB0LCAiLCIpKQoJfQoJb3duZXIgPSBjYWxsZXIKCXBlbmRpbmdPd25lciA9ICIiCgltZW1iZXJzaGlwUmV2aXNpb24rKwoKCWNoYWluLkVtaXQoIk93bmVyc2hpcFRyYW5zZmVycmVkIiwKCQkicHJldmlvdXNPd25lciIsIHByZXZPd25lci5TdHJpbmcoKSwKCQkibmV3T3duZXIiLCBjYWxsZXIuU3RyaW5nKCksCgkpCn0KCi8vIEdldFBlbmRpbmdPd25lciByZXR1cm5zIHRoZSBzdGFnZWQgc3VjY2Vzc29yLCBvciB0aGUgZW1wdHkgYWRkcmVzcy4KZnVuYyBHZXRQZW5kaW5nT3duZXIoKSBhZGRyZXNzIHsgcmV0dXJuIHBlbmRpbmdPd25lciB9CgovLyBTeW5jTWVtYmVycyBhbGxvd3MgdGhlIG93bmVyIHRvIGJhdGNoLXN5bmMgbWVtYmVyc2hpcCBmcm9tIHRoZSBEQU8uCi8vIGFkZHJlc3NlcyBhbmQgcm9sZXNMaXN0IGFyZSBjb21tYS1zZXBhcmF0ZWQsIHdpdGggcm9sZXMgcGlwZS1kZWxpbWl0ZWQgcGVyIGFkZHJlc3MuCi8vIEV4YW1wbGU6IFN5bmNNZW1iZXJzKCJnMWEsZzFiIiwgImFkbWluLGRldnxtZW1iZXIiKQpmdW5jIFN5bmNNZW1iZXJzKGN1ciByZWFsbSwgYWRkcmVzc2VzIHN0cmluZywgcm9sZXNMaXN0IHN0cmluZykgewoJYXNzZXJ0Q2FsbGVySXNPd25lcigpCglhZGRycyA6PSBzdHJpbmdzLlNwbGl0KGFkZHJlc3NlcywgIiwiKQoJcm9sZXMgOj0gc3RyaW5ncy5TcGxpdChyb2xlc0xpc3QsICJ8IikKCWlmIGxlbihhZGRycykgIT0gbGVuKHJvbGVzKSB7CgkJcGFuaWMoImFkZHJlc3NlcyBhbmQgcm9sZXMgY291bnQgbWlzbWF0Y2giKQoJfQoJc3luY2VkIDo9IDAKCWZvciBpLCBhZGRyIDo9IHJhbmdlIGFkZHJzIHsKCQlhZGRyID0gc3RyaW5ncy5UcmltU3BhY2UoYWRkcikKCQlpZiBhZGRyID09ICIiIHsKCQkJY29udGludWUKCQl9CgkJcm9sZSA6PSBzdHJpbmdzLlRyaW1TcGFjZShyb2xlc1tpXSkKCQlpZiAhaXNWYWxpZFJvbGVzKHJvbGUpIHsKCQkJcGFuaWMoImludmFsaWQgcm9sZXMgaW4gZW50cnkgIiArIHN0cmNvbnYuSXRvYShpKSkKCQl9CgkJbWVtYmVycy5TZXQoYWRkciwgcm9sZSkKCQlzeW5jZWQrKwoJfQoJbWVtYmVyc2hpcFJldmlzaW9uKysKCgljaGFpbi5FbWl0KCJNZW1iZXJzU3luY2VkIiwgImNvdW50Iiwgc3RyY29udi5JdG9hKHN5bmNlZCkpCn0KCi8vIFB1cmdlTm9uTWVtYmVycyByZW1vdmVzIGFsbCBtZW1iZXJzIG5vdCBpbiB0aGUgcHJvdmlkZWQgY29tbWEtc2VwYXJhdGVkIGxpc3QuCi8vIFRoZSBvd25lciBpcyBuZXZlciBwdXJnZWQuCmZ1bmMgUHVyZ2VOb25NZW1iZXJzKGN1ciByZWFsbSwga2VlcEFkZHJlc3NlcyBzdHJpbmcpIHsKCWFzc2VydENhbGxlcklzT3duZXIoKQoJa2VlcCA6PSBtYWtlKG1hcFtzdHJpbmddYm9vbCkKCWZvciBfLCBhZGRyIDo9IHJhbmdlIHN0cmluZ3MuU3BsaXQoa2VlcEFkZHJlc3NlcywgIiwiKSB7CgkJa2VlcFtzdHJpbmdzLlRyaW1TcGFjZShhZGRyKV0gPSB0cnVlCgl9CglrZWVwW293bmVyLlN0cmluZygpXSA9IHRydWUgLy8gb3duZXIgaXMgbmV2ZXIgcHVyZ2VkCgl2YXIgdG9SZW1vdmUgW11zdHJpbmcKCW1lbWJlcnMuSXRlcmF0ZSgiIiwgIiIsIGZ1bmMoa2V5IHN0cmluZywgXyBpbnRlcmZhY2V7fSkgYm9vbCB7CgkJaWYgIWtlZXBba2V5XSB7CgkJCXRvUmVtb3ZlID0gYXBwZW5kKHRvUmVtb3ZlLCBrZXkpCgkJfQoJCXJldHVybiBmYWxzZQoJfSkKCWZvciBfLCBhZGRyIDo9IHJhbmdlIHRvUmVtb3ZlIHsKCQltZW1iZXJzLlJlbW92ZShhZGRyKQoJfQoJbWVtYmVyc2hpcFJldmlzaW9uKysKCgljaGFpbi5FbWl0KCJNZW1iZXJzUHVyZ2VkIiwgImNvdW50Iiwgc3RyY29udi5JdG9hKGxlbih0b1JlbW92ZSkpKQp9CgovLyBJc01lbWJlciByZXR1cm5zIHdoZXRoZXIgYW4gYWRkcmVzcyBpcyBhIG1lbWJlci4KZnVuYyBJc01lbWJlcihhZGRyIGFkZHJlc3MpIGJvb2wgewoJXywgZXhpc3RzIDo9IG1lbWJlcnMuR2V0KGFkZHIuU3RyaW5nKCkpCglyZXR1cm4gZXhpc3RzCn0KCi8vIEdldE1lbWJlclJvbGVzIHJldHVybnMgdGhlIHJvbGVzIGZvciBhIG1lbWJlciAoY29tbWEtc2VwYXJhdGVkKSBvciBlbXB0eSBzdHJpbmcuCmZ1bmMgR2V0TWVtYmVyUm9sZXMoYWRkciBhZGRyZXNzKSBzdHJpbmcgewoJdmFsLCBleGlzdHMgOj0gbWVtYmVycy5HZXQoYWRkci5TdHJpbmcoKSkKCWlmICFleGlzdHMgewoJCXJldHVybiAiIgoJfQoJcmV0dXJuIHZhbC4oc3RyaW5nKQp9CgpmdW5jIEdldE1lbWJlckNvdW50KCkgaW50IHsgcmV0dXJuIG1lbWJlcnMuU2l6ZSgpIH0KZnVuYyBHZXRNZW1iZXJzaGlwUmV2aXNpb24oKSB1aW50NjQgeyByZXR1cm4gbWVtYmVyc2hpcFJldmlzaW9uIH0KCi8vIEdldE93bmVyIHJldHVybnMgdGhlIGN1cnJlbnQgcmVhbG0gb3duZXIgYWRkcmVzcy4KZnVuYyBHZXRPd25lcigpIGFkZHJlc3MgewoJcmV0dXJuIG93bmVyCn0KCi8vIOKUgOKUgCBFbWVyZ2VuY3kgUGF1c2Ug4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACi8vCi8vIFBhdXNlIHBvbGljeSAoQUFBLTEgQjMg4oCUIG9uZSBwb2xpY3ksIGVuZm9yY2VkIGV2ZXJ5d2hlcmUpOgovLyAgIFdoaWxlIHBhdXNlZCwgZXZlcnkgbWVtYmVyLWZhY2luZyBjb250ZW50IHdyaXRlIGlzIGJsb2NrZWQgdmlhCi8vICAgYXNzZXJ0Tm90UGF1c2VkKCkg4oCUIFBvc3RUaHJlYWQsIFBvc3RSZXBseSwgRWRpdFRocmVhZCwgRGVsZXRlVGhyZWFkL1JlcGx5LAovLyAgIEZsYWdUaHJlYWQsIFJlbW92ZVRocmVhZC9SZXBseSwgYW5kIFN3ZWVwVG9tYnN0b25lcy4KLy8KLy8gICBPd25lci1vbmx5IGdvdmVybmFuY2UgKEFkZE1lbWJlci9SZW1vdmVNZW1iZXIvVXBkYXRlTWVtYmVyUm9sZXMvU3luY01lbWJlcnMvCi8vICAgUHVyZ2VOb25NZW1iZXJzL1RyYW5zZmVyT3duZXJzaGlwL0NyZWF0ZUNoYW5uZWwpIGlzIGludGVudGlvbmFsbHkgTk9UIGdhdGVkOgovLyAgIHBhdXNlIGhhbHRzIHVzZXIgYWN0aXZpdHkgZHVyaW5nIGFuIGluY2lkZW50LCBidXQgdGhlIG93bmVyIG11c3Qgc3RheSBhYmxlIHRvCi8vICAgZml4IG1lbWJlcnNoaXAvb3duZXJzaGlwIHdoaWxlIHBhdXNlZC4gVGhpcyByZWFsbSBob2xkcyBubyBmdW5kcywgc28gdGhlcmUgaXMKLy8gICBubyB2YWx1ZS1leGl0IGV4ZW1wdGlvbiB0byBjYXJ2ZSBvdXQuCgpmdW5jIGFzc2VydE5vdFBhdXNlZCgpIHsKCWlmIHBhdXNlZCB7CgkJcGFuaWMoInJlYWxtIGlzIHBhdXNlZCDigJQgZW1lcmdlbmN5IG1haW50ZW5hbmNlIikKCX0KfQoKZnVuYyBQYXVzZVJlYWxtKGN1ciByZWFsbSkgewoJYXNzZXJ0Q2FsbGVySXNPd25lcigpCglwYXVzZWQgPSB0cnVlCgljaGFpbi5FbWl0KCJSZWFsbVBhdXNlZCIsICJieSIsIG93bmVyLlN0cmluZygpKQp9CgpmdW5jIFVucGF1c2VSZWFsbShjdXIgcmVhbG0pIHsKCWFzc2VydENhbGxlcklzT3duZXIoKQoJcGF1c2VkID0gZmFsc2UKCWNoYWluLkVtaXQoIlJlYWxtVW5wYXVzZWQiLCAiYnkiLCBvd25lci5TdHJpbmcoKSkKfQoKZnVuYyBJc1BhdXNlZCgpIGJvb2wgeyByZXR1cm4gcGF1c2VkIH0KCi8vIFZhbHVlLW9ubHkgcmVhZGJhY2sgbGV0cyBhIGZpeGVkIERBTyBhY3Rpb24gdmVyaWZ5IGV4YWN0IGNoYW5uZWwgY3JlYXRpb24uCmZ1bmMgR2V0Q2hhbm5lbFN0YXRlKG5hbWUgc3RyaW5nKSAoaW50LCBib29sLCBzdHJpbmcsIHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHsKCXZhbHVlLCBleGlzdHMgOj0gY2hhbm5lbHMuR2V0KG5hbWUpCglpZiAhZXhpc3RzIHsgcmV0dXJuIGxlbihjaGFubmVsT3JkZXIpLCBmYWxzZSwgIiIsICIiLCAiIiwgIiIgfQoJY2hhbm5lbCA6PSB2YWx1ZS4oKkNoYW5uZWwpCglyZXR1cm4gbGVuKGNoYW5uZWxPcmRlciksIHRydWUsIGNoYW5uZWwuRGVzY3JpcHRpb24sIHN0cmluZyhjaGFubmVsLlR5cGUpLCBzdHJpbmdzLkpvaW4oY2hhbm5lbC5SZWFkUm9sZXMsICIsIiksIHN0cmluZ3MuSm9pbihjaGFubmVsLldyaXRlUm9sZXMsICIsIikKfQoKLy8g4pSA4pSAIENoYW5uZWwgTWFuYWdlbWVudCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCi8vIENyZWF0ZUNoYW5uZWwgYWRkcyBhIG5ldyBjaGFubmVsLiBPbmx5IHRoZSBvd25lciAoYWRtaW4pIGNhbiBjcmVhdGUgY2hhbm5lbHMuCmZ1bmMgQ3JlYXRlQ2hhbm5lbChjdXIgcmVhbG0sIG5hbWUsIGRlc2NyaXB0aW9uIHN0cmluZywgY3R5cGUgc3RyaW5nKSB7Cglhc3NlcnRDYWxsZXJJc093bmVyKCkKCglpZiBsZW4oY2hhbm5lbE9yZGVyKSA+PSBNYXhDaGFubmVscyB7CgkJcGFuaWModWZtdC5TcHJpbnRmKCJtYXggY2hhbm5lbHMgcmVhY2hlZDogJWQiLCBNYXhDaGFubmVscykpCgl9CglpZiBfLCBleGlzdHMgOj0gY2hhbm5lbHMuR2V0KG5hbWUpOyBleGlzdHMgewoJCXBhbmljKCJjaGFubmVsIGFscmVhZHkgZXhpc3RzOiAiICsgbmFtZSkKCX0KCWlmICFpc1ZhbGlkQ2hhbm5lbE5hbWUobmFtZSkgewoJCXBhbmljKCJpbnZhbGlkIGNoYW5uZWwgbmFtZTogbXVzdCBiZSAxLTUwIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBvciBoeXBoZW5zLCBubyBsZWFkaW5nIHVuZGVyc2NvcmUiKQoJfQoKCWN0IDo9IENoYW5uZWxUZXh0Cglzd2l0Y2ggY3R5cGUgewoJY2FzZSAiYW5ub3VuY2VtZW50cyI6CgkJY3QgPSBDaGFubmVsQW5ub3VuY2VtZW50cwoJY2FzZSAicmVhZG9ubHkiOgoJCWN0ID0gQ2hhbm5lbFJlYWRvbmx5Cgl9CgoJYWRkQ2hhbm5lbChuYW1lLCBkZXNjcmlwdGlvbiwgY3QsCgkJW11zdHJpbmd7ImFkbWluIiwgImRldiIsICJvcHMiLCAibWVtYmVyIn0sCgkJW11zdHJpbmd7ImFkbWluIiwgImRldiIsICJvcHMiLCAibWVtYmVyIn0pCgoJY2hhaW4uRW1pdCgiQ2hhbm5lbENyZWF0ZWQiLCAibmFtZSIsIG5hbWUsICJ0eXBlIiwgc3RyaW5nKGN0KSkKfQoKLy8g4pSA4pSAIFBvc3QgTWFuYWdlbWVudCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCi8vIFBvc3RUaHJlYWQgY3JlYXRlcyBhIG5ldyB0aHJlYWQgaW4gYSBjaGFubmVsLgovLyBDYWxsZXIgbXVzdCBiZSBhIG1lbWJlciB3aXRoIGEgcm9sZSBsaXN0ZWQgaW4gdGhlIGNoYW5uZWwncyBXcml0ZVJvbGVzLgpmdW5jIFBvc3RUaHJlYWQoY3VyIHJlYWxtLCBjaGFubmVsLCB0aXRsZSwgYm9keSBzdHJpbmcpIHVpbnQ2NCB7Cglhc3NlcnROb3RQYXVzZWQoKQoJY2FsbGVyIDo9IHVuc2FmZS5QcmV2aW91c1JlYWxtKCkuQWRkcmVzcygpCgoJLy8gVmFsaWRhdGUgbWVtYmVyc2hpcCBhbmQgY2hhbm5lbCB3cml0ZSBhY2Nlc3MKCWNoIDo9IGdldENoYW5uZWwoY2hhbm5lbCkKCWFzc2VydENhbGxlckhhc1dyaXRlQWNjZXNzKGNhbGxlciwgY2gpCglpZiBjaC5BcmNoaXZlZCB7CgkJcGFuaWMoImNoYW5uZWwgaXMgYXJjaGl2ZWQiKQoJfQoJLy8gQ2FwIG9uIExJVkUgKG5vbi1kZWxldGVkKSB0aHJlYWRzIHNvIGRlbGV0ZWQgdGhyZWFkcyBmcmVlIHVwIHNsb3RzLgoJaWYgZ2V0TGl2ZVRocmVhZENvdW50KGNoYW5uZWwpID49IE1heFRocmVhZHNQZXJDaGFuIHsKCQlwYW5pYyh1Zm10LlNwcmludGYoImNoYW5uZWwgbGl2ZSB0aHJlYWQgbGltaXQgcmVhY2hlZDogJWQg4oCUIGRlbGV0ZSBvbGQgdGhyZWFkcyB0byBtYWtlIHJvb20iLCBNYXhUaHJlYWRzUGVyQ2hhbikpCgl9CglpZiBsZW4odGl0bGUpID09IDAgfHwgbGVuKHRpdGxlKSA+IE1heFRpdGxlTGVuIHsKCQlwYW5pYyh1Zm10LlNwcmludGYoInRpdGxlIG11c3QgYmUgMS0lZCBjaGFyYWN0ZXJzIiwgTWF4VGl0bGVMZW4pKQoJfQoJaWYgbGVuKGJvZHkpID4gTWF4UG9zdExlbiB7CgkJcGFuaWModWZtdC5TcHJpbnRmKCJib2R5IHRvbyBsb25nOiAlZC8lZCBjaGFycyIsIGxlbihib2R5KSwgTWF4UG9zdExlbikpCgl9CgoJLy8gR2V0IG5leHQgSUQKCW5leHRJRCA6PSBnZXRUaHJlYWRDb3VudChjaGFubmVsKQoJa2V5IDo9IGNoYW5uZWwgKyAiLyIgKyBzdHJjb252LkZvcm1hdFVpbnQobmV4dElELCAxMCkKCgl0IDo9ICZUaHJlYWR7CgkJSUQ6ICAgICAgbmV4dElELAoJCUNoYW5uZWw6IGNoYW5uZWwsCgkJVGl0bGU6ICAgdGl0bGUsCgkJQm9keTogICAgYm9keSwKCQlBdXRob3I6ICBjYWxsZXIsCgkJQmxvY2tIOiAgcnVudGltZS5DaGFpbkhlaWdodCgpLAoJfQoJdGhyZWFkcy5TZXQoa2V5LCB0KQoJdGhyZWFkQ291bnQuU2V0KGNoYW5uZWwsIG5leHRJRCsxKQoJdGhyZWFkTGl2ZS5TZXQoY2hhbm5lbCwgZ2V0TGl2ZVRocmVhZENvdW50KGNoYW5uZWwpKzEpCglhZGRMaXZlVGhyZWFkSUQoY2hhbm5lbCwgbmV4dElEKQoJcmVwbHlDb3VudC5TZXQoa2V5LCB1aW50NjQoMCkpCgoJY2hhaW4uRW1pdCgiVGhyZWFkUG9zdGVkIiwKCQkiY2hhbm5lbCIsIGNoYW5uZWwsCgkJInRocmVhZElkIiwgc3RyY29udi5Gb3JtYXRVaW50KG5leHRJRCwgMTApLAoJCSJhdXRob3IiLCBjYWxsZXIuU3RyaW5nKCksCgkpCgoJcmV0dXJuIG5leHRJRAp9CgovLyBQb3N0UmVwbHkgYWRkcyBhIHJlcGx5IHRvIGEgdGhyZWFkLgovLyBDYWxsZXIgbXVzdCBiZSBhIG1lbWJlciB3aXRoIGEgcm9sZSBsaXN0ZWQgaW4gdGhlIGNoYW5uZWwncyBXcml0ZVJvbGVzLgpmdW5jIFBvc3RSZXBseShjdXIgcmVhbG0sIGNoYW5uZWwgc3RyaW5nLCB0aHJlYWRJRCB1aW50NjQsIGJvZHkgc3RyaW5nKSB7Cglhc3NlcnROb3RQYXVzZWQoKQoJY2FsbGVyIDo9IHVuc2FmZS5QcmV2aW91c1JlYWxtKCkuQWRkcmVzcygpCgoJLy8gVmFsaWRhdGUgbWVtYmVyc2hpcCBhbmQgY2hhbm5lbCB3cml0ZSBhY2Nlc3MKCWNoIDo9IGdldENoYW5uZWwoY2hhbm5lbCkKCWFzc2VydENhbGxlckhhc1dyaXRlQWNjZXNzKGNhbGxlciwgY2gpCgoJdGhyZWFkS2V5IDo9IGNoYW5uZWwgKyAiLyIgKyBzdHJjb252LkZvcm1hdFVpbnQodGhyZWFkSUQsIDEwKQoJdHZhbCwgdGV4aXN0cyA6PSB0aHJlYWRzLkdldCh0aHJlYWRLZXkpCglpZiAhdGV4aXN0cyB7CgkJcGFuaWMoInRocmVhZCBub3QgZm91bmQiKQoJfQoJdGhyZWFkIDo9IHR2YWwuKCpUaHJlYWQpCglpZiB0aHJlYWQuRGVsZXRlZCB7CgkJcGFuaWMoImNhbm5vdCByZXBseSB0byBhIGRlbGV0ZWQgdGhyZWFkIikKCX0KCWlmIHRocmVhZC5IaWRkZW4gewoJCXBhbmljKCJjYW5ub3QgcmVwbHkgdG8gYSBoaWRkZW4gdGhyZWFkIikKCX0KCglpZiBsZW4oYm9keSkgPT0gMCB8fCBsZW4oYm9keSkgPiBNYXhQb3N0TGVuIHsKCQlwYW5pYyh1Zm10LlNwcmludGYoInJlcGx5IG11c3QgYmUgMS0lZCBjaGFyYWN0ZXJzIiwgTWF4UG9zdExlbikpCgl9CgoJLy8gQjE6IGJvdW5kIHRoZSBMSVZFIHJlcGx5IHNldCBzbyByZW5kZXJUaHJlYWQgc3RheXMgdW5kZXIgdGhlIGdhcyBidWRnZXQuCgkvLyBEZWxldGluZyByZXBsaWVzIGZyZWVzIHNsb3RzIChtaXJyb3JzIE1heFRocmVhZHNQZXJDaGFuIC8gZ2V0TGl2ZVRocmVhZENvdW50KS4KCWlmIGdldExpdmVSZXBseUNvdW50KHRocmVhZEtleSkgPj0gTWF4UmVwbGllc1BlclRocmVhZCB7CgkJcGFuaWModWZtdC5TcHJpbnRmKCJ0aHJlYWQgcmVwbHkgbGltaXQgcmVhY2hlZDogJWQg4oCUIG9sZGVyIHJlcGxpZXMgbXVzdCBiZSByZW1vdmVkIiwgTWF4UmVwbGllc1BlclRocmVhZCkpCgl9CgoJbmV4dFJlcGx5SUQgOj0gZ2V0UmVwbHlDb3VudCh0aHJlYWRLZXkpCglyZXBseUtleSA6PSB0aHJlYWRLZXkgKyAiLyIgKyBzdHJjb252LkZvcm1hdFVpbnQobmV4dFJlcGx5SUQsIDEwKQoKCXIgOj0gJlJlcGx5ewoJCUlEOiAgICAgICBuZXh0UmVwbHlJRCwKCQlUaHJlYWRJRDogdGhyZWFkSUQsCgkJQ2hhbm5lbDogIGNoYW5uZWwsCgkJQm9keTogICAgIGJvZHksCgkJQXV0aG9yOiAgIGNhbGxlciwKCQlCbG9ja0g6ICAgcnVudGltZS5DaGFpbkhlaWdodCgpLAoJfQoJcmVwbGllcy5TZXQocmVwbHlLZXksIHIpCglyZXBseUNvdW50LlNldCh0aHJlYWRLZXksIG5leHRSZXBseUlEKzEpCgkvLyBUcmFjayB0aGUgbGl2ZSByZXBseSBzbyByZW5kZXJUaHJlYWQgaXRlcmF0ZXMgb25seSBsaXZlIElEcyAoYm91bmRlZCBzZXQpLAoJLy8gbmV2ZXIgdGhlIG1vbm90b25pYyBjb3VudGVyLgoJYWRkTGl2ZVJlcGx5SUQodGhyZWFkS2V5LCBuZXh0UmVwbHlJRCkKCXJlcGx5TGl2ZS5TZXQodGhyZWFkS2V5LCBnZXRMaXZlUmVwbHlDb3VudCh0aHJlYWRLZXkpKzEpCgoJY2hhaW4uRW1pdCgiUmVwbHlQb3N0ZWQiLAoJCSJjaGFubmVsIiwgY2hhbm5lbCwKCQkidGhyZWFkSWQiLCBzdHJjb252LkZvcm1hdFVpbnQodGhyZWFkSUQsIDEwKSwKCQkicmVwbHlJZCIsIHN0cmNvbnYuRm9ybWF0VWludChuZXh0UmVwbHlJRCwgMTApLAoJCSJhdXRob3IiLCBjYWxsZXIuU3RyaW5nKCksCgkpCn0KCi8vIGRyb3BSZXBseSBoYXJkLXJlbW92ZXMgYSByZXBseTogZGVsZXRlcyB0aGUgbm9kZSAoc3RvcmFnZSByZWNsYWltZWQg4oCUIEIyKSwKLy8gZHJvcHMgaXQgZnJvbSB0aGUgbGl2ZSBpbmRleCwgYW5kIGRlY3JlbWVudHMgdGhlIGxpdmUgY291bnQuIFNoYXJlZCBieQovLyBEZWxldGVSZXBseSBhbmQgUmVtb3ZlUmVwbHkuIHJlbmRlclRocmVhZCBvbmx5IHdhbGtzIHRoZSBsaXZlIGluZGV4LCBzbyBhCi8vIHJlbW92ZWQgcmVwbHkgaXMgbmV2ZXIgbG9va2VkIHVwIOKAlCBubyB0b21ic3RvbmUgaXMgbmVlZGVkLgpmdW5jIGRyb3BSZXBseSh0aHJlYWRLZXksIHJlcGx5S2V5IHN0cmluZywgcmVwbHlJRCB1aW50NjQpIHsKCXJlcGxpZXMuUmVtb3ZlKHJlcGx5S2V5KQoJcmVtb3ZlTGl2ZVJlcGx5SUQodGhyZWFkS2V5LCByZXBseUlEKQoJaWYgbGl2ZSA6PSBnZXRMaXZlUmVwbHlDb3VudCh0aHJlYWRLZXkpOyBsaXZlID4gMCB7CgkJcmVwbHlMaXZlLlNldCh0aHJlYWRLZXksIGxpdmUtMSkKCX0KfQoKLy8gRGVsZXRlUmVwbHkgbGV0cyB0aGUgcmVwbHkncyBhdXRob3IgZGVsZXRlIGl0LiBDYWxsZXIgbXVzdCBiZSBhIG1lbWJlciBhbmQgdGhlCi8vIG9yaWdpbmFsIGF1dGhvci4gVGhlIHJlcGx5IG5vZGUgaXMgaGFyZC1yZW1vdmVkIChCMiBzdGF0ZS1zaHJpbmspIGFuZCBhIHNsb3QgaXMKLy8gZnJlZWQgdW5kZXIgTWF4UmVwbGllc1BlclRocmVhZCAoQjEpLgpmdW5jIERlbGV0ZVJlcGx5KGN1ciByZWFsbSwgY2hhbm5lbCBzdHJpbmcsIHRocmVhZElELCByZXBseUlEIHVpbnQ2NCkgewoJYXNzZXJ0Tm90UGF1c2VkKCkKCWNhbGxlciA6PSB1bnNhZmUuUHJldmlvdXNSZWFsbSgpLkFkZHJlc3MoKQoJYXNzZXJ0Q2FsbGVySXNNZW1iZXIoY2FsbGVyKQoKCXRocmVhZEtleSA6PSBjaGFubmVsICsgIi8iICsgc3RyY29udi5Gb3JtYXRVaW50KHRocmVhZElELCAxMCkKCXJlcGx5S2V5IDo9IHRocmVhZEtleSArICIvIiArIHN0cmNvbnYuRm9ybWF0VWludChyZXBseUlELCAxMCkKCXJ2YWwsIGV4aXN0cyA6PSByZXBsaWVzLkdldChyZXBseUtleSkKCWlmICFleGlzdHMgewoJCXBhbmljKCJyZXBseSBub3QgZm91bmQiKQoJfQoJaWYgcnZhbC4oKlJlcGx5KS5BdXRob3IgIT0gY2FsbGVyIHsKCQlwYW5pYygib25seSB0aGUgYXV0aG9yIGNhbiBkZWxldGUiKQoJfQoKCWRyb3BSZXBseSh0aHJlYWRLZXksIHJlcGx5S2V5LCByZXBseUlEKQoKCWNoYWluLkVtaXQoIlJlcGx5RGVsZXRlZCIsCgkJImNoYW5uZWwiLCBjaGFubmVsLAoJCSJ0aHJlYWRJZCIsIHN0cmNvbnYuRm9ybWF0VWludCh0aHJlYWRJRCwgMTApLAoJCSJyZXBseUlkIiwgc3RyY29udi5Gb3JtYXRVaW50KHJlcGx5SUQsIDEwKSwKCQkiYXV0aG9yIiwgY2FsbGVyLlN0cmluZygpLAoJKQp9CgovLyBSZW1vdmVSZXBseSBwZXJtYW5lbnRseSByZW1vdmVzIGEgcmVwbHkgKG1vZGVyYXRpb24g4oCUIGFkbWluIHJvbGUgb25seSkuIEhhcmQtCi8vIHJlbW92ZXMgdGhlIG5vZGUgbGlrZSBEZWxldGVSZXBseSwgYm91bmRpbmcgcmVuZGVyVGhyZWFkIChCMSkgKyByZWNsYWltaW5nCi8vIHN0b3JhZ2UgKEIyKS4KZnVuYyBSZW1vdmVSZXBseShjdXIgcmVhbG0sIGNoYW5uZWwgc3RyaW5nLCB0aHJlYWRJRCwgcmVwbHlJRCB1aW50NjQpIHsKCWFzc2VydENhbGxlcklzQWRtaW5Sb2xlKCkKCWNhbGxlciA6PSB1bnNhZmUuUHJldmlvdXNSZWFsbSgpLkFkZHJlc3MoKQoKCXRocmVhZEtleSA6PSBjaGFubmVsICsgIi8iICsgc3RyY29udi5Gb3JtYXRVaW50KHRocmVhZElELCAxMCkKCXJlcGx5S2V5IDo9IHRocmVhZEtleSArICIvIiArIHN0cmNvbnYuRm9ybWF0VWludChyZXBseUlELCAxMCkKCWlmIF8sIGV4aXN0cyA6PSByZXBsaWVzLkdldChyZXBseUtleSk7ICFleGlzdHMgewoJCXBhbmljKCJyZXBseSBub3QgZm91bmQiKQoJfQoKCWRyb3BSZXBseSh0aHJlYWRLZXksIHJlcGx5S2V5LCByZXBseUlEKQoKCWNoYWluLkVtaXQoIlJlcGx5UmVtb3ZlZCIsCgkJImNoYW5uZWwiLCBjaGFubmVsLAoJCSJ0aHJlYWRJZCIsIHN0cmNvbnYuRm9ybWF0VWludCh0aHJlYWRJRCwgMTApLAoJCSJyZXBseUlkIiwgc3RyY29udi5Gb3JtYXRVaW50KHJlcGx5SUQsIDEwKSwKCQkiYWRtaW4iLCBjYWxsZXIuU3RyaW5nKCksCgkpCn0KCi8vIEVkaXRUaHJlYWQgYWxsb3dzIHRoZSBvcmlnaW5hbCBhdXRob3IgdG8gZWRpdCB0aGVpciB0aHJlYWQuIENhbGxlciBtdXN0IGJlIGEgbWVtYmVyLgpmdW5jIEVkaXRUaHJlYWQoY3VyIHJlYWxtLCBjaGFubmVsIHN0cmluZywgdGhyZWFkSUQgdWludDY0LCBuZXdCb2R5IHN0cmluZykgewoJYXNzZXJ0Tm90UGF1c2VkKCkKCWNhbGxlciA6PSB1bnNhZmUuUHJldmlvdXNSZWFsbSgpLkFkZHJlc3MoKQoJYXNzZXJ0Q2FsbGVySXNNZW1iZXIoY2FsbGVyKQoKCXRocmVhZEtleSA6PSBjaGFubmVsICsgIi8iICsgc3RyY29udi5Gb3JtYXRVaW50KHRocmVhZElELCAxMCkKCXZhbCwgZXhpc3RzIDo9IHRocmVhZHMuR2V0KHRocmVhZEtleSkKCWlmICFleGlzdHMgewoJCXBhbmljKCJ0aHJlYWQgbm90IGZvdW5kIikKCX0KCgl0IDo9IHZhbC4oKlRocmVhZCkKCWlmIHQuQXV0aG9yICE9IGNhbGxlciB7CgkJcGFuaWMoIm9ubHkgdGhlIGF1dGhvciBjYW4gZWRpdCIpCgl9CglpZiB0LkRlbGV0ZWQgewoJCXBhbmljKCJjYW5ub3QgZWRpdCBhIGRlbGV0ZWQgdGhyZWFkIikKCX0KCWlmIHQuSGlkZGVuIHsKCQlwYW5pYygiY2Fubm90IGVkaXQgYSBoaWRkZW4gdGhyZWFkIikKCX0KCWlmIGxlbihuZXdCb2R5KSA+IE1heFBvc3RMZW4gewoJCXBhbmljKCJib2R5IHRvbyBsb25nIikKCX0KCgl0LkJvZHkgPSBuZXdCb2R5Cgl0LkVkaXRlZCA9IHRydWUKCXQuRWRpdGVkQXQgPSBydW50aW1lLkNoYWluSGVpZ2h0KCkKCXRocmVhZHMuU2V0KHRocmVhZEtleSwgdCkKCgljaGFpbi5FbWl0KCJUaHJlYWRFZGl0ZWQiLAoJCSJjaGFubmVsIiwgY2hhbm5lbCwKCQkidGhyZWFkSWQiLCBzdHJjb252LkZvcm1hdFVpbnQodGhyZWFkSUQsIDEwKSwKCQkiYXV0aG9yIiwgY2FsbGVyLlN0cmluZygpLAoJKQp9CgovLyBEZWxldGVUaHJlYWQgc29mdC1kZWxldGVzIGEgdGhyZWFkIChtYXJrcyBhcyBkZWxldGVkKS4gQ2FsbGVyIG11c3QgYmUgYSBtZW1iZXIgYW5kIHRoZSBvcmlnaW5hbCBhdXRob3IuCmZ1bmMgRGVsZXRlVGhyZWFkKGN1ciByZWFsbSwgY2hhbm5lbCBzdHJpbmcsIHRocmVhZElEIHVpbnQ2NCkgewoJYXNzZXJ0Tm90UGF1c2VkKCkKCWNhbGxlciA6PSB1bnNhZmUuUHJldmlvdXNSZWFsbSgpLkFkZHJlc3MoKQoJYXNzZXJ0Q2FsbGVySXNNZW1iZXIoY2FsbGVyKQoKCXRocmVhZEtleSA6PSBjaGFubmVsICsgIi8iICsgc3RyY29udi5Gb3JtYXRVaW50KHRocmVhZElELCAxMCkKCXZhbCwgZXhpc3RzIDo9IHRocmVhZHMuR2V0KHRocmVhZEtleSkKCWlmICFleGlzdHMgewoJCXBhbmljKCJ0aHJlYWQgbm90IGZvdW5kIikKCX0KCgl0IDo9IHZhbC4oKlRocmVhZCkKCWlmIHQuQXV0aG9yICE9IGNhbGxlciB7CgkJcGFuaWMoIm9ubHkgdGhlIGF1dGhvciBjYW4gZGVsZXRlIikKCX0KCWlmIHQuRGVsZXRlZCB7CgkJcGFuaWMoInRocmVhZCBhbHJlYWR5IGRlbGV0ZWQiKQoJfQoKCXQuRGVsZXRlZCA9IHRydWUKCXQuVGl0bGUgPSAiW0RlbGV0ZWRdIgoJdC5Cb2R5ID0gIiIKCXRocmVhZHMuU2V0KHRocmVhZEtleSwgdCkKCS8vIEZyZWUgYSBzbG90IGZvciBuZXcgdGhyZWFkcwoJbGl2ZSA6PSBnZXRMaXZlVGhyZWFkQ291bnQoY2hhbm5lbCkKCWlmIGxpdmUgPiAwIHsKCQl0aHJlYWRMaXZlLlNldChjaGFubmVsLCBsaXZlLTEpCgl9CglyZW1vdmVMaXZlVGhyZWFkSUQoY2hhbm5lbCwgdGhyZWFkSUQpCgllbnF1ZXVlVGhyZWFkVG9tYihjaGFubmVsLCB0aHJlYWRJRCkgLy8gQjI6IHF1ZXVlIGZvciBoYXJkLUdDIHZpYSBTd2VlcFRvbWJzdG9uZXMKCgljaGFpbi5FbWl0KCJUaHJlYWREZWxldGVkIiwKCQkiY2hhbm5lbCIsIGNoYW5uZWwsCgkJInRocmVhZElkIiwgc3RyY29udi5Gb3JtYXRVaW50KHRocmVhZElELCAxMCksCgkJImF1dGhvciIsIGNhbGxlci5TdHJpbmcoKSwKCSkKfQoKLy8g4pSA4pSAIE1vZGVyYXRpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACgovLyBGbGFnVGhyZWFkIGZsYWdzIGEgdGhyZWFkIGZvciBtb2RlcmF0aW9uIHJldmlldy4KLy8gQWZ0ZXIgRmxhZ1RocmVzaG9sZCBmbGFncywgdGhlIHRocmVhZCBpcyBhdXRvLWhpZGRlbi4KLy8gQ2FsbGVyIG11c3QgYmUgYSBtZW1iZXIgKGFueSByb2xlKSB0byBmbGFnIGNvbnRlbnQuCmZ1bmMgRmxhZ1RocmVhZChjdXIgcmVhbG0sIGNoYW5uZWwgc3RyaW5nLCB0aHJlYWRJRCB1aW50NjQpIHsKCWFzc2VydE5vdFBhdXNlZCgpCgljYWxsZXIgOj0gdW5zYWZlLlByZXZpb3VzUmVhbG0oKS5BZGRyZXNzKCkKCWFzc2VydENhbGxlcklzTWVtYmVyKGNhbGxlcikKCXRocmVhZEtleSA6PSBjaGFubmVsICsgIi8iICsgc3RyY29udi5Gb3JtYXRVaW50KHRocmVhZElELCAxMCkKCgl2YWwsIGV4aXN0cyA6PSB0aHJlYWRzLkdldCh0aHJlYWRLZXkpCglpZiAhZXhpc3RzIHsKCQlwYW5pYygidGhyZWFkIG5vdCBmb3VuZCIpCgl9CgoJdCA6PSB2YWwuKCpUaHJlYWQpCglpZiB0LkRlbGV0ZWQgewoJCXBhbmljKCJjYW5ub3QgZmxhZyBhIGRlbGV0ZWQgdGhyZWFkIikKCX0KCWlmIHQuSGlkZGVuIHsKCQlwYW5pYygidGhyZWFkIGlzIGFscmVhZHkgaGlkZGVuIikKCX0KCgkvLyBUcmFjayB1bmlxdWUgZmxhZ2dlcnMKCXZhciBmbGFnVHJlZSAqYXZsLlRyZWUKCWlmIGZ2YWwsIGZleGlzdHMgOj0gZmxhZ3MuR2V0KHRocmVhZEtleSk7IGZleGlzdHMgewoJCWZsYWdUcmVlID0gZnZhbC4oKmF2bC5UcmVlKQoJfSBlbHNlIHsKCQlmbGFnVHJlZSA9IGF2bC5OZXdUcmVlKCkKCX0KCglpZiBfLCBhbHJlYWR5IDo9IGZsYWdUcmVlLkdldChjYWxsZXIuU3RyaW5nKCkpOyBhbHJlYWR5IHsKCQlwYW5pYygiYWxyZWFkeSBmbGFnZ2VkIikKCX0KCWZsYWdUcmVlLlNldChjYWxsZXIuU3RyaW5nKCksIHRydWUpCglmbGFncy5TZXQodGhyZWFkS2V5LCBmbGFnVHJlZSkKCgkvLyBVcGRhdGUgdGhyZWFkIGZsYWcgY291bnQgYW5kIGF1dG8taGlkZS4KCS8vIER5bmFtaWMgdGhyZXNob2xkOiBtYXgoRmxhZ1RocmVzaG9sZCwgNSUgb2YgbWVtYmVycyksIHNjYWxlcyB3aXRoIERBTyBzaXplLgoJdC5GbGFnQ291bnQgPSBmbGFnVHJlZS5TaXplKCkKCWR5bmFtaWNUaHJlc2hvbGQgOj0gRmxhZ1RocmVzaG9sZAoJZml2ZVBjdCA6PSBtZW1iZXJzLlNpemUoKSAvIDIwCglpZiBmaXZlUGN0ID4gZHluYW1pY1RocmVzaG9sZCB7CgkJZHluYW1pY1RocmVzaG9sZCA9IGZpdmVQY3QKCX0KCXdhc0hpZGRlbiA6PSB0LkhpZGRlbgoJaWYgdC5GbGFnQ291bnQgPj0gZHluYW1pY1RocmVzaG9sZCB7CgkJdC5IaWRkZW4gPSB0cnVlCgl9Cgl0aHJlYWRzLlNldCh0aHJlYWRLZXksIHQpCgoJY2hhaW4uRW1pdCgiVGhyZWFkRmxhZ2dlZCIsCgkJImNoYW5uZWwiLCBjaGFubmVsLAoJCSJ0aHJlYWRJZCIsIHN0cmNvbnYuRm9ybWF0VWludCh0aHJlYWRJRCwgMTApLAoJCSJmbGFnZ2VyIiwgY2FsbGVyLlN0cmluZygpLAoJCSJmbGFnQ291bnQiLCBzdHJjb252Lkl0b2EodC5GbGFnQ291bnQpLAoJKQoJaWYgIXdhc0hpZGRlbiAmJiB0LkhpZGRlbiB7CgkJY2hhaW4uRW1pdCgiVGhyZWFkQXV0b0hpZGRlbiIsCgkJCSJjaGFubmVsIiwgY2hhbm5lbCwKCQkJInRocmVhZElkIiwgc3RyY29udi5Gb3JtYXRVaW50KHRocmVhZElELCAxMCksCgkJKQoJfQp9CgovLyBVbmhpZGVUaHJlYWQgYWxsb3dzIHRoZSBvd25lciBvciBhbiBhZG1pbiB0byBjbGVhciBmbGFncyBhbmQgdW4taGlkZSBhIHRocmVhZC4KZnVuYyBVbmhpZGVUaHJlYWQoY3VyIHJlYWxtLCBjaGFubmVsIHN0cmluZywgdGhyZWFkSUQgdWludDY0KSB7Cglhc3NlcnRDYWxsZXJJc0FkbWluUm9sZSgpCgljYWxsZXIgOj0gdW5zYWZlLlByZXZpb3VzUmVhbG0oKS5BZGRyZXNzKCkKCXRocmVhZEtleSA6PSBjaGFubmVsICsgIi8iICsgc3RyY29udi5Gb3JtYXRVaW50KHRocmVhZElELCAxMCkKCgl2YWwsIGV4aXN0cyA6PSB0aHJlYWRzLkdldCh0aHJlYWRLZXkpCglpZiAhZXhpc3RzIHsKCQlwYW5pYygidGhyZWFkIG5vdCBmb3VuZCIpCgl9Cgl0IDo9IHZhbC4oKlRocmVhZCkKCXQuSGlkZGVuID0gZmFsc2UKCXQuRmxhZ0NvdW50ID0gMAoJdGhyZWFkcy5TZXQodGhyZWFkS2V5LCB0KQoJLy8gQ2xlYXIgZmxhZyB0cmVlCglmbGFncy5SZW1vdmUodGhyZWFkS2V5KQoKCWNoYWluLkVtaXQoIlRocmVhZFVuaGlkZGVuIiwKCQkiY2hhbm5lbCIsIGNoYW5uZWwsCgkJInRocmVhZElkIiwgc3RyY29udi5Gb3JtYXRVaW50KHRocmVhZElELCAxMCksCgkJImFkbWluIiwgY2FsbGVyLlN0cmluZygpLAoJKQp9CgovLyBSZW1vdmVUaHJlYWQgcGVybWFuZW50bHkgcmVtb3ZlcyBhIHRocmVhZCAobW9kZXJhdGlvbiBhY3Rpb24g4oCUIGFkbWluIHJvbGUgb25seSkuCmZ1bmMgUmVtb3ZlVGhyZWFkKGN1ciByZWFsbSwgY2hhbm5lbCBzdHJpbmcsIHRocmVhZElEIHVpbnQ2NCkgewoJYXNzZXJ0Q2FsbGVySXNBZG1pblJvbGUoKQoJY2FsbGVyIDo9IHVuc2FmZS5QcmV2aW91c1JlYWxtKCkuQWRkcmVzcygpCgl0aHJlYWRLZXkgOj0gY2hhbm5lbCArICIvIiArIHN0cmNvbnYuRm9ybWF0VWludCh0aHJlYWRJRCwgMTApCgl2YWwsIGV4aXN0cyA6PSB0aHJlYWRzLkdldCh0aHJlYWRLZXkpCglpZiAhZXhpc3RzIHsKCQlwYW5pYygidGhyZWFkIG5vdCBmb3VuZCIpCgl9CgoJdCA6PSB2YWwuKCpUaHJlYWQpCglpZiAhdC5EZWxldGVkIHsKCQlsaXZlIDo9IGdldExpdmVUaHJlYWRDb3VudChjaGFubmVsKQoJCWlmIGxpdmUgPiAwIHsKCQkJdGhyZWFkTGl2ZS5TZXQoY2hhbm5lbCwgbGl2ZS0xKQoJCX0KCQlyZW1vdmVMaXZlVGhyZWFkSUQoY2hhbm5lbCwgdGhyZWFkSUQpCgkJZW5xdWV1ZVRocmVhZFRvbWIoY2hhbm5lbCwgdGhyZWFkSUQpIC8vIEIyOiBxdWV1ZSBmb3IgaGFyZC1HQyAoc2tpcCBpZiBhbHJlYWR5IHRvbWJzdG9uZWQpCgl9Cgl0LkRlbGV0ZWQgPSB0cnVlCgl0LkhpZGRlbiA9IHRydWUKCXQuVGl0bGUgPSAiW1JlbW92ZWQgYnkgbW9kZXJhdGlvbl0iCgl0LkJvZHkgPSAiIgoJdGhyZWFkcy5TZXQodGhyZWFkS2V5LCB0KQoKCWNoYWluLkVtaXQoIlRocmVhZFJlbW92ZWQiLAoJCSJjaGFubmVsIiwgY2hhbm5lbCwKCQkidGhyZWFkSWQiLCBzdHJjb252LkZvcm1hdFVpbnQodGhyZWFkSUQsIDEwKSwKCQkiYWRtaW4iLCBjYWxsZXIuU3RyaW5nKCksCgkpCn0KCi8vIFN3ZWVwVG9tYnN0b25lcyBoYXJkLXJlbW92ZXMgdXAgdG8gYGxpbWl0YCBzb2Z0LWRlbGV0ZWQgdGhyZWFkcyBpbiBhIGNoYW5uZWwKLy8gKGFuZCBhbGwgb2YgdGhlaXIgcmVtYWluaW5nIHJlcGx5IHN0YXRlKSwgcmVjbGFpbWluZyBBVkwgc3RvcmFnZSBzbyB0aGF0Ci8vIHBvc3QrZGVsZXRlIHNwYW0gY2FuIG5vIGxvbmdlciBhY2NyZXRlIHBlcm1hbmVudCBzdGF0ZSAoQjIpLgovLwovLyBQZXJtaXNzaW9ubGVzcyBHQyBieSBkZXNpZ246IGFueW9uZSBtYXkgY2FsbCBpdC4gUmVsZWFzZWQgc3RvcmFnZSBkZXBvc2l0cyBnbwovLyB0byB0aGUgY2FsbGluZyB0eCBwZXIgdGhlIGNoYWluJ3MgZGVwb3NpdCBwb2xpY3kgKGFuIGV4cGxpY2l0IGNhbGxlciBib3VudHkpOwovLyBvbiByZXN0cmljdGVkLWRlbm9tIGNoYWlucyAoZS5nLiB0ZXN0MTIvdGVzdDEzIGByZXN0cmljdGVkX2Rlbm9tcz1bInVnbm90Il1gKQovLyB0aGV5IHJvdXRlIHRvIHRoZSBTdG9yYWdlRmVlQ29sbGVjdG9yIGluc3RlYWQg4oCUIHNvIHRoaXMgaXMgYSBzdGF0ZS1zaHJpbmsvCi8vIGh5Z2llbmUgcHJpbWl0aXZlLCBub3QgYSB1c2VyLXJlZnVuZCBwYXRoIChzZWUgcGxhbiBCMiAvIFExMSkuCi8vCi8vIEJvdW5kZWQgKyBpZGVtcG90ZW50OiBlYWNoIHNvZnQtZGVsZXRlZCB0aHJlYWQgaG9sZHMgYXQgbW9zdAovLyBNYXhSZXBsaWVzUGVyVGhyZWFkIHJlcGx5IG5vZGVzLCBzbyBrZWVwIGBsaW1pdGAgc21hbGwgKDHigJM1KSB0byBzdGF5IHdlbGwKLy8gd2l0aGluIGJsb2NrIGdhczsgcmUtcnVubmluZyBkcmFpbnMgdGhlIG5leHQgYmF0Y2ggYW5kIHN0b3BzIGF0IDAuCi8vIFJldHVybnMgdGhlIG51bWJlciBvZiB0aHJlYWRzIHN3ZXB0LgpmdW5jIFN3ZWVwVG9tYnN0b25lcyhjdXIgcmVhbG0sIGNoYW5uZWwgc3RyaW5nLCBsaW1pdCBpbnQpIGludCB7Cglhc3NlcnROb3RQYXVzZWQoKQoJaWYgbGltaXQgPD0gMCB7CgkJcmV0dXJuIDAKCX0KCgl0b21iIDo9IGdldFRocmVhZFRvbWIoY2hhbm5lbCkKCW4gOj0gbGltaXQKCWlmIG4gPiBsZW4odG9tYikgewoJCW4gPSBsZW4odG9tYikKCX0KCglmb3IgaSA6PSAwOyBpIDwgbjsgaSsrIHsKCQl0aHJlYWRLZXkgOj0gY2hhbm5lbCArICIvIiArIHN0cmNvbnYuRm9ybWF0VWludCh0b21iW2ldLCAxMCkKCQkvLyBDb2xsZWN0LXRoZW4tcmVtb3ZlOiByZWFkIHRoZSBsaXZlIHJlcGx5IElEcyAoYSBzdG9yZWQgc2xpY2UpIGFuZCByZW1vdmUKCQkvLyBlYWNoIHJlcGx5IG5vZGUg4oCUIHdlIG5ldmVyIGl0ZXJhdGUgdGhlIHRyZWUgd2UgbXV0YXRlIChBVkwgZm9vdGd1bikuCgkJZm9yIF8sIHJpZCA6PSByYW5nZSBnZXRMaXZlUmVwbHlJRHModGhyZWFkS2V5KSB7CgkJCXJlcGxpZXMuUmVtb3ZlKHRocmVhZEtleSArICIvIiArIHN0cmNvbnYuRm9ybWF0VWludChyaWQsIDEwKSkKCQl9CgkJcmVwbHlMaXZlSURzLlJlbW92ZSh0aHJlYWRLZXkpCgkJcmVwbHlMaXZlLlJlbW92ZSh0aHJlYWRLZXkpCgkJcmVwbHlDb3VudC5SZW1vdmUodGhyZWFkS2V5KQoJCWZsYWdzLlJlbW92ZSh0aHJlYWRLZXkpCgkJdGhyZWFkcy5SZW1vdmUodGhyZWFkS2V5KQoJfQoKCS8vIERyb3AgdGhlIHByb2Nlc3NlZCBwcmVmaXg7IGNvcHkgdGhlIHRhaWwgaW50byBhIGZyZXNoIHNsaWNlIHRvIGF2b2lkIGFsaWFzaW5nLgoJcmVtYWluaW5nIDo9IGFwcGVuZChbXXVpbnQ2NHt9LCB0b21iW246XS4uLikKCWlmIGxlbihyZW1haW5pbmcpID09IDAgewoJCXRocmVhZFRvbWIuUmVtb3ZlKGNoYW5uZWwpCgl9IGVsc2UgewoJCXRocmVhZFRvbWIuU2V0KGNoYW5uZWwsIHJlbWFpbmluZykKCX0KCglpZiBuID4gMCB7CgkJY2hhaW4uRW1pdCgiVG9tYnN0b25lc1N3ZXB0IiwKCQkJImNoYW5uZWwiLCBjaGFubmVsLAoJCQkiY291bnQiLCBzdHJjb252Lkl0b2EobiksCgkJKQoJfQoJcmV0dXJuIG4KfQoKLy8gR2V0VG9tYnN0b25lQ291bnQgcmV0dXJucyBob3cgbWFueSBzb2Z0LWRlbGV0ZWQgdGhyZWFkcyBpbiBhIGNoYW5uZWwgYXJlIHN0aWxsCi8vIGF3YWl0aW5nIGhhcmQtR0MgKHJlYWQtb25seTsgbGV0cyBvcHMvaW5kZXhlcnMgZGVjaWRlIHdoZW4gdG8gY2FsbCBTd2VlcFRvbWJzdG9uZXMpLgpmdW5jIEdldFRvbWJzdG9uZUNvdW50KGNoYW5uZWwgc3RyaW5nKSBpbnQgewoJcmV0dXJuIGxlbihnZXRUaHJlYWRUb21iKGNoYW5uZWwpKQp9CgovLyDilIDilIAgUmVuZGVyIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAovLyBDUklUSUNBTDogT3V0cHV0IGZvcm1hdCBNVVNUIG1hdGNoIHBhcnNlci50cyByZWdleCBwYXR0ZXJucy4KCmZ1bmMgUmVuZGVyKHBhdGggc3RyaW5nKSBzdHJpbmcgewoJaWYgcGF0aCA9PSAiIiB7CgkJcmV0dXJuIHJlbmRlckhvbWUoKQoJfQoJaWYgc3RyaW5ncy5IYXNQcmVmaXgocGF0aCwgIl9fYWNsLyIpIHsKCQljaGFubmVsTmFtZSA6PSBzdHJpbmdzLlRyaW1QcmVmaXgocGF0aCwgIl9fYWNsLyIpCgkJcmV0dXJuIHJlbmRlckFDTChjaGFubmVsTmFtZSkKCX0KCWlmIHN0cmluZ3MuSGFzUHJlZml4KHBhdGgsICJfX21lbWJlci8iKSB7CgkJYWRkciA6PSBzdHJpbmdzLlRyaW1QcmVmaXgocGF0aCwgIl9fbWVtYmVyLyIpCgkJcm9sZXMgOj0gR2V0TWVtYmVyUm9sZXMoYWRkcmVzcyhhZGRyKSkKCQlpZiByb2xlcyA9PSAiIiB7CgkJCXJldHVybiAibm90IGZvdW5kIgoJCX0KCQlyZXR1cm4gInJvbGVzOiIgKyByb2xlcwoJfQoJaWYgc3RyaW5ncy5IYXNQcmVmaXgocGF0aCwgIl9jaGFubmVsLyIpIHsKCQljaGFubmVsTmFtZSA6PSBzdHJpbmdzLlRyaW1QcmVmaXgocGF0aCwgIl9jaGFubmVsLyIpCgkJcmV0dXJuIHJlbmRlckNoYW5uZWwoY2hhbm5lbE5hbWUpCgl9CgoJLy8gQ2hlY2sgZm9yICJjaGFubmVsL3RocmVhZElkIiBwYXR0ZXJuLCBvcHRpb25hbGx5IHdpdGggYSAiP3BhZ2U9TiIgc3VmZml4CgkvLyBmb3IgcmVwbHkgcGFnaW5hdGlvbiAoQjEpLgoJcGFydHMgOj0gc3RyaW5ncy5TcGxpdE4ocGF0aCwgIi8iLCAyKQoJaWYgbGVuKHBhcnRzKSA9PSAyIHsKCQlpZFBhcnQgOj0gcGFydHNbMV0KCQlwYWdlIDo9IHVpbnQ2NCgwKQoJCWlmIHFpIDo9IHN0cmluZ3MuSW5kZXhCeXRlKGlkUGFydCwgJz8nKTsgcWkgPj0gMCB7CgkJCXBhZ2UgPSBwYXJzZVBhZ2VRdWVyeShpZFBhcnRbcWkrMTpdKQoJCQlpZFBhcnQgPSBpZFBhcnRbOnFpXQoJCX0KCQl0aHJlYWRJRCwgZXJyIDo9IHN0cmNvbnYuUGFyc2VVaW50KGlkUGFydCwgMTAsIDY0KQoJCWlmIGVyciA9PSBuaWwgewoJCQlyZXR1cm4gcmVuZGVyVGhyZWFkKHBhcnRzWzBdLCB0aHJlYWRJRCwgcGFnZSkKCQl9Cgl9CgoJLy8gVHJ5IGFzIGNoYW5uZWwgbmFtZSBkaXJlY3RseQoJaWYgXywgZXhpc3RzIDo9IGNoYW5uZWxzLkdldChwYXRoKTsgZXhpc3RzIHsKCQlyZXR1cm4gcmVuZGVyQ2hhbm5lbChwYXRoKQoJfQoKCXJldHVybiAiIyA0MDRcblBhZ2Ugbm90IGZvdW5kOiAiICsgcGF0aAp9CgovLyByZW5kZXJIb21lIHByb2R1Y2VzIHRoZSBib2FyZCBob21lIHBhZ2UuCi8vIEZvcm1hdDogcGFyc2VyLnRzIHBhcnNlQm9hcmRIb21lKCkgZXhwZWN0czoKLy8gICAtIFsjbmFtZV0oOl9jaGFubmVsL25hbWUpIPCfk6IgKE4gdGhyZWFkcykKZnVuYyByZW5kZXJIb21lKCkgc3RyaW5nIHsKCXZhciBzYiBzdHJpbmdzLkJ1aWxkZXIKCXNiLldyaXRlU3RyaW5nKCIjIE1lbWJhREFPIENoYW5uZWxzXG5cbiIpCglzYi5Xcml0ZVN0cmluZygiQ29tbXVuaXR5IGRpc2N1c3Npb24gY2hhbm5lbHMgZm9yIHRoZSBNZW1iYSBlY29zeXN0ZW0uXG5cbiIpCglzYi5Xcml0ZVN0cmluZyh1Zm10LlNwcmludGYoIioqT3duZXI6KiogJXMgfCAqKk1lbWJlcnM6KiogJWRcblxuIiwgb3duZXIsIG1lbWJlcnMuU2l6ZSgpKSkKCXNiLldyaXRlU3RyaW5nKCIjIyBDaGFubmVsc1xuXG4iKQoKCWZvciBfLCBuYW1lIDo9IHJhbmdlIGNoYW5uZWxPcmRlciB7CgkJdmFsLCBleGlzdHMgOj0gY2hhbm5lbHMuR2V0KG5hbWUpCgkJaWYgIWV4aXN0cyB7CgkJCWNvbnRpbnVlCgkJfQoJCWNoIDo9IHZhbC4oKkNoYW5uZWwpCgkJaWYgY2guQXJjaGl2ZWQgewoJCQljb250aW51ZQoJCX0KCgkJY291bnQgOj0gZ2V0VGhyZWFkQ291bnQobmFtZSkKCQl0eXBlSWNvbiA6PSAiIgoJCXN3aXRjaCBjaC5UeXBlIHsKCQljYXNlIENoYW5uZWxBbm5vdW5jZW1lbnRzOgoJCQl0eXBlSWNvbiA9ICIg8J+ToiIKCQljYXNlIENoYW5uZWxSZWFkb25seToKCQkJdHlwZUljb24gPSAiIPCflJIiCgkJfQoKCQlzYi5Xcml0ZVN0cmluZyh1Zm10LlNwcmludGYoIi0gWyMlc10oOl9jaGFubmVsLyVzKSVzICglZCB0aHJlYWRzKVxuIiwKCQkJbmFtZSwgbmFtZSwgdHlwZUljb24sIGNvdW50KSkKCX0KCglyZXR1cm4gc2IuU3RyaW5nKCkKfQoKLy8gcmVuZGVyQ2hhbm5lbCBwcm9kdWNlcyBhIGNoYW5uZWwncyB0aHJlYWQgbGlzdC4KLy8gRm9ybWF0OiBwYXJzZXIudHMgcGFyc2VUaHJlYWRMaXN0KCkgZXhwZWN0czoKLy8gICAjIyMgW1RpdGxlXSg6Y2hhbm5lbC9pZCkKLy8gICBieSBnMWFkZHIuLi4gfCBOIHJlcGxpZXMgfCBibG9jayBICmZ1bmMgcmVuZGVyQ2hhbm5lbChjaGFubmVsTmFtZSBzdHJpbmcpIHN0cmluZyB7CglpZiBfLCBleGlzdHMgOj0gY2hhbm5lbHMuR2V0KGNoYW5uZWxOYW1lKTsgIWV4aXN0cyB7CgkJcmV0dXJuICIjIDQwNFxuQ2hhbm5lbCBub3QgZm91bmQ6ICIgKyBjaGFubmVsTmFtZQoJfQoKCXZhciBzYiBzdHJpbmdzLkJ1aWxkZXIKCXNiLldyaXRlU3RyaW5nKHVmbXQuU3ByaW50ZigiIyAjJXNcblxuIiwgY2hhbm5lbE5hbWUpKQoKCS8vIEl0ZXJhdGUgdGhlIExJVkUgdGhyZWFkLUlEIGluZGV4IChib3VuZGVkIGJ5IGdldExpdmVUaHJlYWRDb3VudCksIG5ld2VzdAoJLy8gZmlyc3QuIE5ldmVyIGxvb3Agb3ZlciB0aGUgbW9ub3RvbmljIHRocmVhZENvdW50IOKAlCBhIHBvc3QrZGVsZXRlIHNwYW0KCS8vIGxvb3AgaW5mbGF0ZXMgaXQgd2l0aG91dCBib3VuZCAoZ2FzIERvUyk7IGRlbGV0ZWQgSURzIGFyZSBub3QgaW4gdGhpcyBpbmRleC4KCWlkcyA6PSBnZXRMaXZlVGhyZWFkSURzKGNoYW5uZWxOYW1lKQoJaWYgbGVuKGlkcykgPT0gMCB7CgkJc2IuV3JpdGVTdHJpbmcoIipObyB0aHJlYWRzIHlldC4gQmUgdGhlIGZpcnN0IHRvIHBvc3QhKlxuIikKCQlyZXR1cm4gc2IuU3RyaW5nKCkKCX0KCglmb3IgaSA6PSBsZW4oaWRzKSAtIDE7IGkgPj0gMDsgaS0tIHsKCQl0aHJlYWRLZXkgOj0gY2hhbm5lbE5hbWUgKyAiLyIgKyBzdHJjb252LkZvcm1hdFVpbnQoaWRzW2ldLCAxMCkKCQl2YWwsIGV4aXN0cyA6PSB0aHJlYWRzLkdldCh0aHJlYWRLZXkpCgkJaWYgIWV4aXN0cyB7CgkJCWNvbnRpbnVlCgkJfQoJCXQgOj0gdmFsLigqVGhyZWFkKQoJCWlmIHQuSGlkZGVuIHx8IHQuRGVsZXRlZCB7CgkJCWNvbnRpbnVlCgkJfQoKCQkvLyBDb3VudCBsaXZlIChub24tZGVsZXRlZCkgcmVwbGllcyDigJQgbWF0Y2hlcyB3aGF0IHJlbmRlclRocmVhZCBzaG93cy4KCQlyQ291bnQgOj0gZ2V0TGl2ZVJlcGx5Q291bnQodGhyZWFkS2V5KQoJCWF1dGhvclN0ciA6PSB0cnVuY0FkZHIodC5BdXRob3IpCgoJCXNiLldyaXRlU3RyaW5nKHVmbXQuU3ByaW50ZigiIyMjIFslc10oOiVzLyVkKVxuIiwgc2FuaXRpemVGb3JSZW5kZXIodC5UaXRsZSksIGNoYW5uZWxOYW1lLCB0LklEKSkKCQlzYi5Xcml0ZVN0cmluZyh1Zm10LlNwcmludGYoImJ5ICVzIHwgJWQgcmVwbGllcyB8IGJsb2NrICVkXG5cbiIsIGF1dGhvclN0ciwgckNvdW50LCB0LkJsb2NrSCkpCgl9CgoJcmV0dXJuIHNiLlN0cmluZygpCn0KCi8vIHJlbmRlclRocmVhZCBwcm9kdWNlcyBhIHNpbmdsZSB0aHJlYWQgd2l0aCByZXBsaWVzLgovLyBGb3JtYXQ6IHBhcnNlci50cyBwYXJzZVRocmVhZERldGFpbCgpIGV4cGVjdHM6Ci8vICAgIyBUaXRsZQovLyAgIGJvZHkKLy8gICAtLS0KLy8gICAqUG9zdGVkIGJ5IGcxYWRkciBhdCBibG9jayBIKiAqKGVkaXRlZCBhdCBibG9jayBNKSoKLy8gICAjIyBSZXBsaWVzCi8vICAgKipnMWFkZHIuLi4qKiAoYmxvY2sgSCkgKihlZGl0ZWQpKgovLyAgIHJlcGx5IGJvZHkKLy8gICAtLS0KZnVuYyByZW5kZXJUaHJlYWQoY2hhbm5lbE5hbWUgc3RyaW5nLCB0aHJlYWRJRCwgcGFnZSB1aW50NjQpIHN0cmluZyB7Cgl0aHJlYWRLZXkgOj0gY2hhbm5lbE5hbWUgKyAiLyIgKyBzdHJjb252LkZvcm1hdFVpbnQodGhyZWFkSUQsIDEwKQoJdmFsLCBleGlzdHMgOj0gdGhyZWFkcy5HZXQodGhyZWFkS2V5KQoJaWYgIWV4aXN0cyB7CgkJcmV0dXJuICIjIDQwNFxuVGhyZWFkIG5vdCBmb3VuZCIKCX0KCgl0IDo9IHZhbC4oKlRocmVhZCkKCgkvLyBTdXBwcmVzcyBjb250ZW50IGZvciBoaWRkZW4gKGZsYWctYXV0by1oaWRkZW4gb3IgYWRtaW4taGlkZGVuKSBhbmQKCS8vIHNvZnQtZGVsZXRlZCB0aHJlYWRzLiByZW5kZXJDaGFubmVsIG9taXRzIHRoZXNlIGZyb20gdGhlIGxpc3QsIGJ1dCB0aGUKCS8vIGRpcmVjdCBwYXRoIFJlbmRlcigiY2hhbm5lbC9pZCIpIG11c3Qgbm90IGxlYWsgdGhlIG9yaWdpbmFsIHRpdGxlL2JvZHkuCglpZiB0LkhpZGRlbiB8fCB0LkRlbGV0ZWQgewoJCXJldHVybiAiIyBUaHJlYWQgdW5hdmFpbGFibGVcblxuKlRoaXMgdGhyZWFkIGhhcyBiZWVuIGhpZGRlbiBvciByZW1vdmVkLipcbiIKCX0KCgl2YXIgc2Igc3RyaW5ncy5CdWlsZGVyCglzYi5Xcml0ZVN0cmluZyh1Zm10LlNwcmludGYoIiMgJXNcblxuIiwgc2FuaXRpemVGb3JSZW5kZXIodC5UaXRsZSkpKQoJc2IuV3JpdGVTdHJpbmcoc2FuaXRpemVGb3JSZW5kZXIodC5Cb2R5KSArICJcblxuIikKCXNiLldyaXRlU3RyaW5nKCItLS1cblxuIikKCXNiLldyaXRlU3RyaW5nKHVmbXQuU3ByaW50ZigiKlBvc3RlZCBieSAlcyBhdCBibG9jayAlZCoiLCBzdHJpbmcodC5BdXRob3IpLCB0LkJsb2NrSCkpCglpZiB0LkVkaXRlZCB7CgkJc2IuV3JpdGVTdHJpbmcodWZtdC5TcHJpbnRmKCIgKihlZGl0ZWQgYXQgYmxvY2sgJWQpKiIsIHQuRWRpdGVkQXQpKQoJfQoJc2IuV3JpdGVTdHJpbmcoIlxuXG4iKQoKCS8vIEIxOiByZW5kZXIgb25seSBMSVZFIHJlcGxpZXMgKGJvdW5kZWQgYnkgTWF4UmVwbGllc1BlclRocmVhZCksIHBhZ2luYXRlZCB0bwoJLy8gYSBmaXhlZCB3aW5kb3cgc28gcmVuZGVyIGNvc3QgaXMgTyhSZXBseVBhZ2VTaXplKSByZWdhcmRsZXNzIG9mIHRvdGFsIGNodXJuLgoJLy8gTmV2ZXIgaXRlcmF0ZSB0aGUgbW9ub3RvbmljIHJlcGx5Q291bnQg4oCUIHRoYXQgaXMgdGhlIHJlbmRlci1Eb1Mgc3VyZmFjZS4KCWxpdmVJRHMgOj0gZ2V0TGl2ZVJlcGx5SURzKHRocmVhZEtleSkgLy8gYXNjZW5kaW5nIChvbGRlc3TihpJuZXdlc3QpLCA8PSBNYXhSZXBsaWVzUGVyVGhyZWFkCgl0b3RhbCA6PSB1aW50NjQobGVuKGxpdmVJRHMpKQoJaWYgdG90YWwgPiAwIHsKCQl0b3RhbFBhZ2VzIDo9ICh0b3RhbCArIFJlcGx5UGFnZVNpemUgLSAxKSAvIFJlcGx5UGFnZVNpemUKCQkvLyBwYWdlIDEgPSBvbGRlc3Qgd2luZG93IOKApiB0b3RhbFBhZ2VzID0gbmV3ZXN0LiBEZWZhdWx0ICgwKSBhbmQgYW55CgkJLy8gb3V0LW9mLXJhbmdlIHZhbHVlIHNuYXAgdG8gdGhlIG5ld2VzdCBwYWdlIChtb3N0LXJlY2VudCByZXBsaWVzKS4KCQlpZiBwYWdlID09IDAgfHwgcGFnZSA+IHRvdGFsUGFnZXMgewoJCQlwYWdlID0gdG90YWxQYWdlcwoJCX0KCQlzdGFydCA6PSAocGFnZSAtIDEpICogUmVwbHlQYWdlU2l6ZQoJCWVuZCA6PSBzdGFydCArIFJlcGx5UGFnZVNpemUKCQlpZiBlbmQgPiB0b3RhbCB7CgkJCWVuZCA9IHRvdGFsCgkJfQoKCQlzYi5Xcml0ZVN0cmluZygiIyMgUmVwbGllc1xuXG4iKQoJCWlmIHRvdGFsUGFnZXMgPiAxIHsKCQkJc2IuV3JpdGVTdHJpbmcodWZtdC5TcHJpbnRmKAoJCQkJIipTaG93aW5nICVk4oCTJWQgb2YgJWQg4oCiIHBhZ2UgJWQvJWQg4oCUIG9sZGVyOiBgP3BhZ2U9JWRgLCBuZXdlcjogYD9wYWdlPSVkYCpcblxuIiwKCQkJCXN0YXJ0KzEsIGVuZCwgdG90YWwsIHBhZ2UsIHRvdGFsUGFnZXMsIHBhZ2VDbGFtcChwYWdlLTEsIHRvdGFsUGFnZXMpLCBwYWdlQ2xhbXAocGFnZSsxLCB0b3RhbFBhZ2VzKSkpCgkJfQoKCQlmb3IgaSA6PSBzdGFydDsgaSA8IGVuZDsgaSsrIHsKCQkJcmVwbHlLZXkgOj0gdGhyZWFkS2V5ICsgIi8iICsgc3RyY29udi5Gb3JtYXRVaW50KGxpdmVJRHNbaV0sIDEwKQoJCQlydmFsLCByZXhpc3RzIDo9IHJlcGxpZXMuR2V0KHJlcGx5S2V5KQoJCQlpZiAhcmV4aXN0cyB7CgkJCQljb250aW51ZSAvLyBsaXZlIGluZGV4IG5ldmVyIHBvaW50cyBhdCBhIHJlbW92ZWQgcmVwbHksIGJ1dCBzdGF5IHNhZmUKCQkJfQoJCQlyIDo9IHJ2YWwuKCpSZXBseSkKCQkJYXV0aG9yU3RyIDo9IHRydW5jQWRkcihyLkF1dGhvcikKCQkJZWRpdFN0ciA6PSAiIgoJCQlpZiByLkVkaXRlZCB7CgkJCQllZGl0U3RyID0gIiAqKGVkaXRlZCkqIgoJCQl9CgkJCXNiLldyaXRlU3RyaW5nKHVmbXQuU3ByaW50ZigiKiolcyoqIChibG9jayAlZCklc1xuXG4iLCBhdXRob3JTdHIsIHIuQmxvY2tILCBlZGl0U3RyKSkKCQkJc2IuV3JpdGVTdHJpbmcoc2FuaXRpemVGb3JSZW5kZXIoci5Cb2R5KSArICJcblxuIikKCQkJc2IuV3JpdGVTdHJpbmcoIi0tLVxuXG4iKQoJCX0KCX0KCglyZXR1cm4gc2IuU3RyaW5nKCkKfQoKLy8gcGFyc2VQYWdlUXVlcnkgZXh0cmFjdHMgdGhlIHBhZ2UgbnVtYmVyIGZyb20gYSAiP3BhZ2U9TiIgcXVlcnkgc3RyaW5nIChhbHNvCi8vIHRvbGVyYXRlcyBleHRyYSAmLXNlcGFyYXRlZCBwYXJhbXMpLiBSZXR1cm5zIDAgKD0gZGVmYXVsdC9uZXdlc3QpIG9uIGFic2VuY2UKLy8gb3IgcGFyc2UgZXJyb3IuCmZ1bmMgcGFyc2VQYWdlUXVlcnkocSBzdHJpbmcpIHVpbnQ2NCB7Cglmb3IgXywga3YgOj0gcmFuZ2Ugc3RyaW5ncy5TcGxpdChxLCAiJiIpIHsKCQlpZiBzdHJpbmdzLkhhc1ByZWZpeChrdiwgInBhZ2U9IikgewoJCQlpZiBuLCBlcnIgOj0gc3RyY29udi5QYXJzZVVpbnQoc3RyaW5ncy5UcmltUHJlZml4KGt2LCAicGFnZT0iKSwgMTAsIDY0KTsgZXJyID09IG5pbCB7CgkJCQlyZXR1cm4gbgoJCQl9CgkJfQoJfQoJcmV0dXJuIDAKfQoKLy8gcGFnZUNsYW1wIGtlZXBzIGEgcGFnZSBsaW5rIHdpdGhpbiBbMSwgdG90YWxQYWdlc10uCmZ1bmMgcGFnZUNsYW1wKHAsIHRvdGFsUGFnZXMgdWludDY0KSB1aW50NjQgewoJaWYgcCA8IDEgewoJCXJldHVybiAxCgl9CglpZiBwID4gdG90YWxQYWdlcyB7CgkJcmV0dXJuIHRvdGFsUGFnZXMKCX0KCXJldHVybiBwCn0KCi8vIHJlbmRlckFDTCBwcm9kdWNlcyB0aGUgQUNMIHJlc3BvbnNlIGZvciBhIGNoYW5uZWwuCi8vIEZvcm1hdDogcGFyc2VyLnRzIHBhcnNlQUNMKCkgZXhwZWN0czoKLy8gICByZWFkOnJvbGUxLHJvbGUyCi8vICAgd3JpdGU6cm9sZTEscm9sZTIscm9sZTMKLy8gICB0eXBlOnRleHQKZnVuYyByZW5kZXJBQ0woY2hhbm5lbE5hbWUgc3RyaW5nKSBzdHJpbmcgewoJdmFsLCBleGlzdHMgOj0gY2hhbm5lbHMuR2V0KGNoYW5uZWxOYW1lKQoJaWYgIWV4aXN0cyB7CgkJcmV0dXJuICJub3QgZm91bmQiCgl9CgljaCA6PSB2YWwuKCpDaGFubmVsKQoKCXZhciBzYiBzdHJpbmdzLkJ1aWxkZXIKCXNiLldyaXRlU3RyaW5nKCJyZWFkOiIgKyBzdHJpbmdzLkpvaW4oY2guUmVhZFJvbGVzLCAiLCIpICsgIlxuIikKCXNiLldyaXRlU3RyaW5nKCJ3cml0ZToiICsgc3RyaW5ncy5Kb2luKGNoLldyaXRlUm9sZXMsICIsIikgKyAiXG4iKQoJc2IuV3JpdGVTdHJpbmcoInR5cGU6IiArIHN0cmluZyhjaC5UeXBlKSArICJcbiIpCgoJcmV0dXJuIHNiLlN0cmluZygpCn0KCi8vIOKUgOKUgCBIZWxwZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgAoKZnVuYyBnZXRDaGFubmVsKG5hbWUgc3RyaW5nKSAqQ2hhbm5lbCB7Cgl2YWwsIGV4aXN0cyA6PSBjaGFubmVscy5HZXQobmFtZSkKCWlmICFleGlzdHMgewoJCXBhbmljKCJjaGFubmVsIG5vdCBmb3VuZDogIiArIG5hbWUpCgl9CglyZXR1cm4gdmFsLigqQ2hhbm5lbCkKfQoKZnVuYyBnZXRUaHJlYWRDb3VudChjaGFubmVsIHN0cmluZykgdWludDY0IHsKCXZhbCwgZXhpc3RzIDo9IHRocmVhZENvdW50LkdldChjaGFubmVsKQoJaWYgIWV4aXN0cyB7CgkJcmV0dXJuIDAKCX0KCXJldHVybiB2YWwuKHVpbnQ2NCkKfQoKLy8gZ2V0TGl2ZVRocmVhZENvdW50IHJldHVybnMgdGhlIG51bWJlciBvZiBub24tZGVsZXRlZCB0aHJlYWRzIGluIGEgY2hhbm5lbC4KLy8gVW5saWtlIGdldFRocmVhZENvdW50IChtb25vdG9uaWMgSUQgY291bnRlciksIHRoaXMgZGVjcmVhc2VzIHdoZW4gdGhyZWFkcwovLyBhcmUgZGVsZXRlZCwgc28gZGVsZXRlZCB0aHJlYWRzIGZyZWUgdXAgc2xvdHMgdW5kZXIgTWF4VGhyZWFkc1BlckNoYW4uCmZ1bmMgZ2V0TGl2ZVRocmVhZENvdW50KGNoYW5uZWwgc3RyaW5nKSB1aW50NjQgewoJdmFsLCBleGlzdHMgOj0gdGhyZWFkTGl2ZS5HZXQoY2hhbm5lbCkKCWlmICFleGlzdHMgewoJCXJldHVybiAwCgl9CglyZXR1cm4gdmFsLih1aW50NjQpCn0KCi8vIOKUgOKUgCBMaXZlIHRocmVhZC1JRCBpbmRleCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKLy8gcmVuZGVyQ2hhbm5lbCBtdXN0IGl0ZXJhdGUgb25seSBsaXZlIChub24tZGVsZXRlZCkgdGhyZWFkIElEcywgbmV2ZXIgdGhlCi8vIG1vbm90b25pYyB0aHJlYWRDb3VudDogYSBtZW1iZXIgY2FuIHBvc3QrZGVsZXRlIGluIGEgbG9vcCB0byBpbmZsYXRlCi8vIHRocmVhZENvdW50IHdpdGhvdXQgYm91bmQgKHRoZSBsaXZlIGNhcCBvbmx5IGxpbWl0cyBsaXZlIHRocmVhZHMpLCB0dXJuaW5nCi8vIHJlbmRlckNoYW5uZWwgaW50byBhbiB1bmJvdW5kZWQgTyh0aHJlYWRDb3VudCkgc2NhbiAoZ2FzIERvUykuIFRoaXMgaW5kZXgKLy8gc3RheXMgYm91bmRlZCBieSBnZXRMaXZlVGhyZWFkQ291bnQgKDw9IE1heFRocmVhZHNQZXJDaGFuKS4KCmZ1bmMgZ2V0TGl2ZVRocmVhZElEcyhjaGFubmVsIHN0cmluZykgW111aW50NjQgewoJaWYgdmFsLCBleGlzdHMgOj0gdGhyZWFkTGl2ZUlEcy5HZXQoY2hhbm5lbCk7IGV4aXN0cyB7CgkJcmV0dXJuIHZhbC4oW111aW50NjQpCgl9CglyZXR1cm4gbmlsCn0KCmZ1bmMgYWRkTGl2ZVRocmVhZElEKGNoYW5uZWwgc3RyaW5nLCBpZCB1aW50NjQpIHsKCXRocmVhZExpdmVJRHMuU2V0KGNoYW5uZWwsIGFwcGVuZChnZXRMaXZlVGhyZWFkSURzKGNoYW5uZWwpLCBpZCkpCn0KCmZ1bmMgcmVtb3ZlTGl2ZVRocmVhZElEKGNoYW5uZWwgc3RyaW5nLCBpZCB1aW50NjQpIHsKCWlkcyA6PSBnZXRMaXZlVGhyZWFkSURzKGNoYW5uZWwpCglmb3IgaSwgeCA6PSByYW5nZSBpZHMgewoJCWlmIHggPT0gaWQgewoJCQl0aHJlYWRMaXZlSURzLlNldChjaGFubmVsLCBhcHBlbmQoaWRzWzppXSwgaWRzW2krMTpdLi4uKSkKCQkJcmV0dXJuCgkJfQoJfQp9CgovLyDilIDilIAgTGl2ZSByZXBseS1JRCBpbmRleCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKLy8gU2FtZSByYXRpb25hbGUgYXMgdGhlIHRocmVhZCBpbmRleCwgb25lIGxldmVsIGRvd246IHJlbmRlclRocmVhZCBtdXN0IGl0ZXJhdGUKLy8gb25seSBsaXZlIHJlcGx5IElEcyAoYm91bmRlZCBieSBNYXhSZXBsaWVzUGVyVGhyZWFkKSwgbmV2ZXIgdGhlIG1vbm90b25pYwovLyByZXBseUNvdW50LCBvciBhIG1lbWJlciBjYW4gcG9zdCtkZWxldGUgcmVwbGllcyBpbiBhIGxvb3AgdG8gbWFrZSBhIHRocmVhZAovLyB1bnJlbmRlcmFibGUuIEtleWVkIGJ5ICJjaGFubmVsL3RocmVhZElkIi4KCmZ1bmMgZ2V0TGl2ZVJlcGx5Q291bnQodGhyZWFkS2V5IHN0cmluZykgdWludDY0IHsKCWlmIHZhbCwgZXhpc3RzIDo9IHJlcGx5TGl2ZS5HZXQodGhyZWFkS2V5KTsgZXhpc3RzIHsKCQlyZXR1cm4gdmFsLih1aW50NjQpCgl9CglyZXR1cm4gMAp9CgpmdW5jIGdldExpdmVSZXBseUlEcyh0aHJlYWRLZXkgc3RyaW5nKSBbXXVpbnQ2NCB7CglpZiB2YWwsIGV4aXN0cyA6PSByZXBseUxpdmVJRHMuR2V0KHRocmVhZEtleSk7IGV4aXN0cyB7CgkJcmV0dXJuIHZhbC4oW111aW50NjQpCgl9CglyZXR1cm4gbmlsCn0KCmZ1bmMgYWRkTGl2ZVJlcGx5SUQodGhyZWFkS2V5IHN0cmluZywgaWQgdWludDY0KSB7CglyZXBseUxpdmVJRHMuU2V0KHRocmVhZEtleSwgYXBwZW5kKGdldExpdmVSZXBseUlEcyh0aHJlYWRLZXkpLCBpZCkpCn0KCmZ1bmMgcmVtb3ZlTGl2ZVJlcGx5SUQodGhyZWFkS2V5IHN0cmluZywgaWQgdWludDY0KSB7CglpZHMgOj0gZ2V0TGl2ZVJlcGx5SURzKHRocmVhZEtleSkKCWZvciBpLCB4IDo9IHJhbmdlIGlkcyB7CgkJaWYgeCA9PSBpZCB7CgkJCXJlcGx5TGl2ZUlEcy5TZXQodGhyZWFkS2V5LCBhcHBlbmQoaWRzWzppXSwgaWRzW2krMTpdLi4uKSkKCQkJcmV0dXJuCgkJfQoJfQp9CgovLyDilIDilIAgVGhyZWFkIHRvbWJzdG9uZSBxdWV1ZSAoQjIgaGFyZC1HQykg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSACi8vIFNvZnQtZGVsZXRlZCB0aHJlYWQgSURzIGF3YWl0aW5nIHBlcm1hbmVudCByZW1vdmFsIGJ5IFN3ZWVwVG9tYnN0b25lcy4gQSBxdWV1ZQovLyAobm90IGEgc2NhbiBvZiB0aGUgdGhyZWFkcyB0cmVlKSBrZWVwcyB0aGUgc3dlZXAgTyhsaW1pdCkg4oCUIGl0IG5ldmVyIHdhbGtzIHRoZQovLyB1bmJvdW5kZWQgc2V0IG9mIHBhc3QgdG9tYnN0b25lcy4KCmZ1bmMgZ2V0VGhyZWFkVG9tYihjaGFubmVsIHN0cmluZykgW111aW50NjQgewoJaWYgdmFsLCBleGlzdHMgOj0gdGhyZWFkVG9tYi5HZXQoY2hhbm5lbCk7IGV4aXN0cyB7CgkJcmV0dXJuIHZhbC4oW111aW50NjQpCgl9CglyZXR1cm4gbmlsCn0KCmZ1bmMgZW5xdWV1ZVRocmVhZFRvbWIoY2hhbm5lbCBzdHJpbmcsIGlkIHVpbnQ2NCkgewoJdGhyZWFkVG9tYi5TZXQoY2hhbm5lbCwgYXBwZW5kKGdldFRocmVhZFRvbWIoY2hhbm5lbCksIGlkKSkKfQoKZnVuYyBnZXRSZXBseUNvdW50KHRocmVhZEtleSBzdHJpbmcpIHVpbnQ2NCB7Cgl2YWwsIGV4aXN0cyA6PSByZXBseUNvdW50LkdldCh0aHJlYWRLZXkpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gMAoJfQoJcmV0dXJuIHZhbC4odWludDY0KQp9CgpmdW5jIHRydW5jQWRkcihhZGRyIGFkZHJlc3MpIHN0cmluZyB7CglzIDo9IHN0cmluZyhhZGRyKQoJaWYgbGVuKHMpID4gMTMgewoJCXJldHVybiBzWzoxMF0gKyAiLi4uIgoJfQoJcmV0dXJuIHMKfQoKLy8gaXNWYWxpZFJvbGVzIHZhbGlkYXRlcyBhIGNvbW1hLXNlcGFyYXRlZCByb2xlIGxpc3QgY29udGFpbnMgb25seSBzYWZlIGNoYXJhY3RlcnMuCi8vIEFsbG93ZWQ6IGEteiwgQS1aLCAwLTksIGh5cGhlbiwgY29tbWEuIE5vIHNwYWNlcywgbm8gbWFya2Rvd24gY2hhcnMsIG5vIG51bGwgYnl0ZXMuCmZ1bmMgaXNWYWxpZFJvbGVzKHMgc3RyaW5nKSBib29sIHsKCWlmIGxlbihzKSA+IDIwMCB7CgkJcmV0dXJuIGZhbHNlCgl9Cglmb3IgXywgYyA6PSByYW5nZSBzIHsKCQlpZiAhKChjID49ICdhJyAmJiBjIDw9ICd6JykgfHwgKGMgPj0gJ0EnICYmIGMgPD0gJ1onKSB8fCAoYyA+PSAnMCcgJiYgYyA8PSAnOScpIHx8IGMgPT0gJy0nIHx8IGMgPT0gJywnKSB7CgkJCXJldHVybiBmYWxzZQoJCX0KCX0KCXJldHVybiB0cnVlCn0KCi8vIHNhbml0aXplRm9yUmVuZGVyIHN0cmlwcyBtYXJrZG93bi1zZW5zaXRpdmUgY2hhcmFjdGVycyB0byBwcmV2ZW50IGluamVjdGlvbi4KZnVuYyBzYW5pdGl6ZUZvclJlbmRlcihzIHN0cmluZykgc3RyaW5nIHsKCXZhciBvdXQgc3RyaW5ncy5CdWlsZGVyCglmb3IgXywgYyA6PSByYW5nZSBzIHsKCQlzd2l0Y2ggYyB7CgkJY2FzZSAnWycsICddJywgJygnLCAnKScsICcjJywgJyonLCAnYCcsICchJywgJzwnLCAnPicsICd8JywgJ1xcJywgJ18nLCAnficsICdcbicsICdccicsICdcdCc6CgkJCWNvbnRpbnVlCgkJZGVmYXVsdDoKCQkJb3V0LldyaXRlUnVuZShjKQoJCX0KCX0KCXJldHVybiBvdXQuU3RyaW5nKCkKfQoKLy8g4pSA4pSAIEFDTCBFbmZvcmNlbWVudCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAKCmZ1bmMgYXNzZXJ0Q2FsbGVySXNPd25lcigpIHsKCWNhbGxlciA6PSB1bnNhZmUuUHJldmlvdXNSZWFsbSgpLkFkZHJlc3MoKQoJaWYgY2FsbGVyICE9IG93bmVyIHsKCQlwYW5pYygidW5hdXRob3JpemVkOiBjYWxsZXIgIiArIGNhbGxlci5TdHJpbmcoKSArICIgaXMgbm90IHRoZSBvd25lciIpCgl9Cn0KCmZ1bmMgYXNzZXJ0Q2FsbGVySXNNZW1iZXIoY2FsbGVyIGFkZHJlc3MpIHsKCWlmIF8sIGV4aXN0cyA6PSBtZW1iZXJzLkdldChjYWxsZXIuU3RyaW5nKCkpOyAhZXhpc3RzIHsKCQlwYW5pYygidW5hdXRob3JpemVkOiBjYWxsZXIgIiArIGNhbGxlci5TdHJpbmcoKSArICIgaXMgbm90IGEgbWVtYmVyIikKCX0KfQoKLy8gYXNzZXJ0Q2FsbGVySGFzV3JpdGVBY2Nlc3MgY2hlY2tzIHRoYXQgdGhlIGNhbGxlciBpcyBhIG1lbWJlciBBTkQgaGFzIGF0IGxlYXN0Ci8vIG9uZSByb2xlIHRoYXQgbWF0Y2hlcyB0aGUgY2hhbm5lbCdzIFdyaXRlUm9sZXMuCmZ1bmMgYXNzZXJ0Q2FsbGVySGFzV3JpdGVBY2Nlc3MoY2FsbGVyIGFkZHJlc3MsIGNoICpDaGFubmVsKSB7CgkvLyBQdWJsaWMgY2hhbm5lbHMgKFdyaXRlUm9sZXMgY29udGFpbnMgIioiKSBhY2NlcHQgcG9zdHMgZnJvbSBhbnkgY2FsbGVyIOKAlAoJLy8gdGhpcyBpcyBhIHB1YmxpYyBmZWVkYmFjayBib2FyZC4gTm9uLXB1YmxpYyBjaGFubmVscyBrZWVwIHJvbGUtYmFzZWQgY29udHJvbAoJLy8gKGUuZy4gYW5ub3VuY2VtZW50cyBzdGF5cyBhZG1pbi1vbmx5KS4gTWFpbm5ldCBzaG91bGQgYWRkIHJhdGUtbGltaXRpbmcuCglmb3IgXywgd3IgOj0gcmFuZ2UgY2guV3JpdGVSb2xlcyB7CgkJaWYgd3IgPT0gIioiIHsKCQkJcmV0dXJuCgkJfQoJfQoJcm9sZXNTdHIsIGV4aXN0cyA6PSBtZW1iZXJzLkdldChjYWxsZXIuU3RyaW5nKCkpCglpZiAhZXhpc3RzIHsKCQlwYW5pYygidW5hdXRob3JpemVkOiBjYWxsZXIgIiArIGNhbGxlci5TdHJpbmcoKSArICIgaXMgbm90IGEgbWVtYmVyIikKCX0KCgljYWxsZXJSb2xlcyA6PSBzdHJpbmdzLlNwbGl0KHJvbGVzU3RyLihzdHJpbmcpLCAiLCIpCglmb3IgXywgY3IgOj0gcmFuZ2UgY2FsbGVyUm9sZXMgewoJCWNyID0gc3RyaW5ncy5UcmltU3BhY2UoY3IpCgkJZm9yIF8sIHdyIDo9IHJhbmdlIGNoLldyaXRlUm9sZXMgewoJCQlpZiBjciA9PSB3ciB7CgkJCQlyZXR1cm4gLy8gQWNjZXNzIGdyYW50ZWQKCQkJfQoJCX0KCX0KCglwYW5pYygidW5hdXRob3JpemVkOiBjYWxsZXIgIiArIGNhbGxlci5TdHJpbmcoKSArICIgbGFja3Mgd3JpdGUgYWNjZXNzIHRvIGNoYW5uZWwgIiArIGNoLk5hbWUpCn0KCmZ1bmMgaGFzUm9sZShjYWxsZXIgYWRkcmVzcywgcm9sZSBzdHJpbmcpIGJvb2wgewoJcm9sZXNTdHIsIGV4aXN0cyA6PSBtZW1iZXJzLkdldChjYWxsZXIuU3RyaW5nKCkpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gZmFsc2UKCX0KCWNhbGxlclJvbGVzIDo9IHN0cmluZ3MuU3BsaXQocm9sZXNTdHIuKHN0cmluZyksICIsIikKCWZvciBfLCBjciA6PSByYW5nZSBjYWxsZXJSb2xlcyB7CgkJaWYgc3RyaW5ncy5UcmltU3BhY2UoY3IpID09IHJvbGUgewoJCQlyZXR1cm4gdHJ1ZQoJCX0KCX0KCXJldHVybiBmYWxzZQp9CgovLyBhc3NlcnRDYWxsZXJJc0FkbWluUm9sZSBjaGVja3MgdGhhdCB0aGUgY2FsbGVyIGlzIGEgbWVtYmVyIHdpdGggdGhlICJhZG1pbiIgcm9sZS4KLy8gVXNlZCBmb3IgbW9kZXJhdGlvbiBhY3Rpb25zIChSZW1vdmVUaHJlYWQsIFVuaGlkZVRocmVhZCkgc28gYW55IGFkbWluIGNhbiBtb2RlcmF0ZSwKLy8gbm90IGp1c3QgdGhlIHNpbmdsZSBvd25lci4KZnVuYyBhc3NlcnRDYWxsZXJJc0FkbWluUm9sZSgpIHsKCWNhbGxlciA6PSB1bnNhZmUuUHJldmlvdXNSZWFsbSgpLkFkZHJlc3MoKQoJaWYgIWhhc1JvbGUoY2FsbGVyLCAiYWRtaW4iKSB7CgkJcGFuaWMoInVuYXV0aG9yaXplZDogY2FsbGVyICIgKyBjYWxsZXIuU3RyaW5nKCkgKyAiIGRvZXMgbm90IGhhdmUgYWRtaW4gcm9sZSIpCgl9Cn0KCi8vIGlzVmFsaWRDaGFubmVsTmFtZSB2YWxpZGF0ZXMgdGhhdCBhIGNoYW5uZWwgbmFtZSBjb250YWlucyBvbmx5Ci8vIGxvd2VyY2FzZSBhbHBoYW51bWVyaWMgY2hhcmFjdGVycyBhbmQgaHlwaGVucywgYW5kIGRvZXMgbm90IHN0YXJ0IHdpdGggdW5kZXJzY29yZS4KZnVuYyBpc1ZhbGlkQ2hhbm5lbE5hbWUobmFtZSBzdHJpbmcpIGJvb2wgewoJaWYgbGVuKG5hbWUpID09IDAgfHwgbGVuKG5hbWUpID4gNTAgewoJCXJldHVybiBmYWxzZQoJfQoJaWYgbmFtZVswXSA9PSAnXycgewoJCXJldHVybiBmYWxzZSAvLyBQcmV2ZW50IGNvbGxpc2lvbiB3aXRoIF9fYWNsLywgX19tZW1iZXIvIHBhdGhzCgl9Cglmb3IgXywgYyA6PSByYW5nZSBuYW1lIHsKCQlpZiAhKChjID49ICdhJyAmJiBjIDw9ICd6JykgfHwgKGMgPj0gJzAnICYmIGMgPD0gJzknKSB8fCBjID09ICctJykgewoJCQlyZXR1cm4gZmFsc2UKCQl9Cgl9CglyZXR1cm4gdHJ1ZQp9CiIiChMvZ25vLk1lbVBhY2thZ2VUeXBlEgsKCU1QVXNlckFsbCINMjAwMDAwMDB1Z25vdBISCICEr18SCzIwMDAwMHVnbm90GogDCs0BChIvdG0uUHViS2V5TXVsdGlzaWcStgEIAhI6ChMvdG0uUHViS2V5U2VjcDI1NmsxEiMKIQNdTsrzjy2oA1bKxxCiASBMVUReZbe8FQo/n1GUQS9f7RI6ChMvdG0uUHViS2V5U2VjcDI1NmsxEiMKIQMo44neuGQmEOBJpWfwt5YFd/18PcgdS1Pidavq3ZGmeBI6ChMvdG0uUHViS2V5U2VjcDI1NmsxEiMKIQMg5X9eKuwtmgamq/0K8oenVUfVQAsVWVenzmjN1+WBABKLAQoFCAMSAaASQDgsjRnV0a1XLEx1FXNE2gbtQoYVjx4tq1tt8gdB3kOSJ/pYDh3yrsFmuvltiuEimY3stp/ThUwV3DhfVsjzgNISQMm/iN4UFGM4ZwfyHar2MWIea5MZGjC2WRsAWgWaMxTnclwg5tg+6s3sQUrq9Pb45snjNth4S5nda3mCSfBtJ2kaKGcxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxbHV1eGU=