Transaction executed successfully

Transaction Details

Inspect execution, participants, message data, gas usage, events and raw transaction data.

Transaction hash
7EA5D69C9788633B6017629B72C6B26869DE34824B8ED1D746A8E93D68B1C779

Transaction overview

Status
Success
Execution completed
Block
#77270
Included in block
Message Type
m_addpkg
Primary message

Execution summary

TX INDEX
0
Position in block
GAS WANTED
231,999,797
Requested gas limit
GAS USED
193,333,214
Gas consumed
FEE
232000ugnot
Transaction fee

Participants

Sender
Package / Realm
Not available
Memo
None

Message

Message #1
m_addpkg
Caller
Arguments
g1q5tjjv3kkslzwf2na9y9wk7e5a8ugph8xfsk04

Execution log

msg:0,success:true,log:,events:[]

Events

No events emitted by this transaction.

Raw encoded transaction

CqWpCQoML3ZtLm1fYWRkcGtnEpOpCQooZzFxNXRqanYza2tzbHp3ZjJuYTl5OXdrN2U1YTh1Z3BoOHhmc2swNBLlqAkKBnN0YWtlchIgZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9zdGFrZXIvdjEayCgKCVJFQURNRS5tZBK6KCMgR292IFN0YWtlcgoKR292ZXJuYW5jZSBkZWxlZ2F0aW9uIGFuZCB4R05TLWJhc2VkIHZvdGluZyBwb3dlciBtYW5hZ2VtZW50LgoKIyMgT3ZlcnZpZXcKCkdvdiBTdGFrZXIgYWNjZXB0cyBHTlMgc3Rha2luZywgbWludHMgYW5kIGJ1cm5zIHhHTlMsIG1haW50YWlucyBkZWxlZ2F0ZWUgYmFsYW5jZXMgYW5kIHRpbWVzdGFtcGVkIGRlbGVnYXRpb24gaGlzdG9yeSwgdHJhY2tzIHVuZGVsZWdhdGlvbiBsb2NrdXBzLCBhbmQgc2V0dGxlcyB0d28gcmV3YXJkIHN0cmVhbXMgZm9yIHN0YWtlcnM6IEdOUyBlbWlzc2lvbiByZXdhcmRzIGFuZCBwcm90b2NvbC1mZWUgcmV3YXJkcyBpbiBhbnkgcmVnaXN0ZXJlZCB0b2tlbi4KCiMjIENvbmZpZ3VyYXRpb24KCi0gKipVbmRlbGVnYXRpb24gTG9ja3VwKio6IGNvbmZpZ3VyYWJsZTsgdGhlIGRlZmF1bHQgaXMgNyBkYXlzIGJlZm9yZSB1bmRlbGVnYXRlZCBHTlMgY2FuIGJlIGNvbGxlY3RlZC4KLSAqKlJld2FyZCBTb3VyY2VzKio6IEdOUyBlbWlzc2lvbiAoc2luZ2xlIHRva2VuKSBhbmQgcHJvdG9jb2wtZmVlIGRpc3RyaWJ1dGlvbiAob25lIGFjY3VtdWxhdG9yIHBlciBmZWUgdG9rZW4pLgotICoqRGVsZWdhdGlvbiBTdGF0ZSoqOiBwZXItZGVsZWdhdG9yL2RlbGVnYXRlZSByZWNvcmRzLCB0b3RhbCBhbmQgdXNlciB0aW1lc3RhbXAgaGlzdG9yaWVzLCBhbmQgcmV3YXJkIHN0YWtlIGV2ZW50cy4KCiMjIENvcmUgRmVhdHVyZXMKCiMjIyBEZWxlZ2F0aW9uCgotIERlbGVnYXRlIEdOUyB0byBhbnkgdmFsaWQgYWRkcmVzczsgdGhlIGRlbGVnYXRlZCBhbW91bnQgaXMgbWlycm9yZWQgYXMgeEdOUyB2b3RpbmcgcG93ZXIuCi0gUmVkZWxlZ2F0ZSBiZXR3ZWVuIGRlbGVnYXRlZXMgd2l0aG91dCBhIGxvY2t1cC4gUmVkZWxlZ2F0aW9uIHBlcmZvcm1zIGFuIGltbWVkaWF0ZSByZW1vdmUtcGx1cy1hZGQgZm9yIHJld2FyZCBhY2NvdW50aW5nLgotIFRyYWNrIHVuZGVsZWdhdGVkIGJhbGFuY2VzIHVudGlsIHRoZSBjb25maWd1cmVkIGxvY2t1cCBleHBpcmVzOyBjb2xsZWN0aW5nIHRoZW4gYnVybnMgdGhlIGNvcnJlc3BvbmRpbmcgeEdOUyBhbmQgcmV0dXJucyBHTlMuCgojIyMgUmV3YXJkcwoKLSBgQ29sbGVjdFJld2FyZGAgY2xhaW1zIGJvdGggdGhlIGVtaXNzaW9uIHN0cmVhbSBhbmQgYWxsIGtub3duIHByb3RvY29sLWZlZSB0b2tlbnMuCi0gYENvbGxlY3RFbWlzc2lvblJld2FyZGAgY2xhaW1zIG9ubHkgR05TIGVtaXNzaW9uIHJld2FyZHMuCi0gYENvbGxlY3RQcm90b2NvbEZlZVJld2FyZGAgY2xhaW1zIG9uZSBwcm90b2NvbC1mZWUgdG9rZW47IGl0cyBidWNrZXQgYW5kIHN0YWtlLWV2ZW50IHdvcmsgaXMgYm91bmRlZCBwZXIgY2FsbCwgc28gcmVtYWluaW5nIHdvcmsgaXMgY29sbGVjdGVkIGxhdGVyLgotIExhdW5jaHBhZCBjYW4gY29sbGVjdCB0aGUgbWF0Y2hpbmcgZW1pc3Npb24gYW5kIHByb3RvY29sLWZlZSByZXdhcmRzIGZvciBhIHJlZ2lzdGVyZWQgcHJvamVjdCB3YWxsZXQgdGhyb3VnaCBsYXVuY2hwYWQtb25seSBlbnRyeSBwb2ludHMuCgpQcm90b2NvbC1mZWUgcmV3YXJkcyBhcmUgbm90IGNhbGN1bGF0ZWQgYXMgYSBzaW5nbGUgY3VycmVudC1iYWxhbmNlIHNoYXJlLiBFYWNoIHRva2VuJ3MgZmVlIGJ1Y2tldHMgYXJlIGRpdmlkZWQgYnkgdGhlIHRvdGFsIHN0YWtlIGluIGZvcmNlIGR1cmluZyB0aGVpciBhY2NydWFsIGVwb2NocywgYWNjdW11bGF0ZWQgaW4gUTEyOCBmaXhlZCBwb2ludCwgYW5kIHNldHRsZWQgYWNyb3NzIGVhY2ggc3Rha2VyJ3MgdGltZXN0YW1wZWQgc3Rha2UtZXZlbnQgc2VnbWVudHMuIEZyYWN0aW9uYWwgcmVtYWluZGVycyByZW1haW4gaW4gc3RhdGUgZm9yIGxhdGVyIGNvbGxlY3Rpb24uCgojIyMgSGlzdG9yeSBhbmQgU25hcHNob3RzCgotIEhpc3RvcmljYWwgZGVsZWdhdGlvbiBzbmFwc2hvdHMgYXJlIHRpbWVzdGFtcCBsb29rdXBzIHVzZWQgYnkgZ292ZXJuYW5jZSdzIGNvbmZpZ3VyZWQgc21vb3RoaW5nIGNhbGN1bGF0aW9uOyB0aGV5IGFyZSBub3QgYmxvY2staGVpZ2h0IHNuYXBzaG90cy4KLSBDbGVhbnVwIGZ1bmN0aW9ucyBwcmVzZXJ2ZSBoaXN0b3J5IG5lZWRlZCBieSBhY3RpdmUgcHJvcG9zYWxzLgoKIyMgS2V5IEZ1bmN0aW9ucwoKIyMjIGBEZWxlZ2F0ZWAKClRyYW5zZmVycyBHTlMgZnJvbSB0aGUgY2FsbGVyLCBtaW50cyB0aGUgc2FtZSBhbW91bnQgb2YgeEdOUywgYW5kIGFzc2lnbnMgdGhlIGRlbGVnYXRlZCB2b3RpbmcgcG93ZXIgdG8gYSB0YXJnZXQgYWRkcmVzcy4gVGhlIGNhbGxlciBtdXN0IGFwcHJvdmUgdGhlIEdOUyB0cmFuc2ZlciBmaXJzdC4KCiMjIyBgVW5kZWxlZ2F0ZWAKClJlbW92ZXMgdm90aW5nIHBvd2VyIGltbWVkaWF0ZWx5IGFuZCBjcmVhdGVzIGEgd2l0aGRyYXdhbCBzdWJqZWN0IHRvIHRoZSBjb25maWd1cmVkIGxvY2t1cC4KCiMjIyBgUmVkZWxlZ2F0ZWAKCk1vdmVzIGRlbGVnYXRlZCBiYWxhbmNlIGZyb20gb25lIGRlbGVnYXRlZSB0byBhbm90aGVyIGltbWVkaWF0ZWx5LCB3aXRob3V0IGNyZWF0aW5nIGEgdXNlci1mYWNpbmcgbG9ja3VwLgoKIyMjIGBDb2xsZWN0UmV3YXJkYAoKQ2xhaW1zIHRoZSBjYWxsZXIncyBHTlMgZW1pc3Npb24gcmV3YXJkcyBhbmQgYWxsIGtub3duIHByb3RvY29sLWZlZSByZXdhcmRzLiBUaGUgYWxsLXRva2VuIHBhdGggaW50ZW50aW9uYWxseSBncm93cyB3aXRoIHRoZSBudW1iZXIgb2Yga25vd24gZmVlIHRva2Vucy4KCiMjIyBgQ29sbGVjdEVtaXNzaW9uUmV3YXJkYAoKQ2xhaW1zIG9ubHkgdGhlIGNhbGxlcidzIGFjY3VtdWxhdGVkIEdOUyBlbWlzc2lvbiByZXdhcmQuCgojIyMgYENvbGxlY3RQcm90b2NvbEZlZVJld2FyZGAKCkNsYWltcyBvbmUgdG9rZW4gcGF0aCdzIGFjY3VtdWxhdGVkIHByb3RvY29sLWZlZSByZXdhcmQuIEEgbGF0ZXIgY2FsbCBtYXkgYmUgcmVxdWlyZWQgd2hlbiBwZW5kaW5nIGFjY3J1YWwgYnVja2V0cyBvciBzdGFrZSBldmVudHMgZXhjZWVkIHRoZSBwZXItY2FsbCBib3VuZC4KCiMjIyBgQ29sbGVjdFVuZGVsZWdhdGVkR25zYAoKQ29sbGVjdHMgR05TIGFmdGVyIHRoZSBjb25maWd1cmVkIHVuZGVsZWdhdGlvbiBsb2NrdXAgaGFzIHBhc3NlZCBhbmQgYnVybnMgdGhlIGNvcnJlc3BvbmRpbmcgeEdOUy4KCiMjIyBgQ29sbGVjdFJld2FyZEZyb21MYXVuY2hQYWRgCgpDb2xsZWN0cyBib3RoIHJld2FyZCBzdHJlYW1zIGZvciBhIHJlZ2lzdGVyZWQgbGF1bmNocGFkIHByb2plY3Qgd2FsbGV0LiBUaGlzIGVudHJ5IHBvaW50IGlzIGNhbGxhYmxlIG9ubHkgYnkgdGhlIGxhdW5jaHBhZCBjb250cmFjdCBhbmQgc2VuZHMgcmV3YXJkcyB0byB0aGUgc3VwcGxpZWQgcHJvamVjdC13YWxsZXQgYWRkcmVzcy4KCiMjIERlbGVnYXRpb24gTG9naWMKCiMjIyBEZWxlZ2F0aW9uIEZsb3cKCjEuIEFwcHJvdmUgR05TIHNwZW5kaW5nIGJ5IHRoZSBnb3Yvc3Rha2VyIHJlYWxtLgoyLiBEZWxlZ2F0ZSBHTlMgdG8gYSBkZWxlZ2F0ZWU7IHhHTlMgaXMgbWludGVkIGFuZCB0aW1lc3RhbXBlZCBoaXN0b3J5IGlzIHVwZGF0ZWQuCjMuIEdvdmVybmFuY2UgcmVhZHMgdGhlIGRlbGVnYXRlZSdzIGhpc3RvcnkgYXQgcHJvcG9zYWwtZGVmaW5lZCB0aW1lc3RhbXBzIGZvciB2b3RlIHdlaWdodC4KNC4gVW5kZWxlZ2F0ZSB0byBzdGFydCB0aGUgbG9ja3VwLCBvciByZWRlbGVnYXRlIGltbWVkaWF0ZWx5IHRvIGFub3RoZXIgZGVsZWdhdGVlLgo1LiBBZnRlciB0aGUgbG9ja3VwIGV4cGlyZXMsIGNvbGxlY3QgdW5kZWxlZ2F0ZWQgR05TLgoKIyMgVXNhZ2UKClRoZXNlIHNuaXBwZXRzIGNhbGwgdGhlIHB1YmxpYyBkb21haW4gcHJveHkgZnJvbSBhIHJlYWxtIGZ1bmN0aW9uIHdpdGggYSBjdXJyZW50IGBjdXJgIHRva2VuLgpJbXBvcnQgdGhlIHByb3h5IHBhY2thZ2UgYW5kIHF1YWxpZnkgaXRzIGZ1bmN0aW9uIG5hbWVzIGluIGludGVncmF0aW5nIGNvZGUuCgpgYGBnbwovLyBEZWxlZ2F0ZSBHTlMgdG8gYW5vdGhlciBhZGRyZXNzOyB4R05TIHZvdGluZyBwb3dlciBpcyBtaW50ZWQgMToxLgpkZWxlZ2F0ZWRBbW91bnQgOj0gRGVsZWdhdGUoY3Jvc3MoY3VyKSwgZGVsZWdhdGVlLCAxXzAwMF8wMDBfMDAwLCAiZzFyZWZlcnJlci4uLiIpCgovLyBSZWRlbGVnYXRlIHBhcnQgb2YgdGhlIGFjdGl2ZSBiYWxhbmNlIGltbWVkaWF0ZWx5LgpSZWRlbGVnYXRlKGNyb3NzKGN1ciksIGRlbGVnYXRlZSwgbmV3RGVsZWdhdGVlLCA1MDBfMDAwXzAwMCkKCi8vIENsYWltIGJvdGggR05TIGVtaXNzaW9uIGFuZCBhbGwga25vd24gcHJvdG9jb2wtZmVlIHRva2Vucy4KQ29sbGVjdFJld2FyZChjcm9zcyhjdXIpKQoKLy8gT3IgY2xhaW0gb25seSBvbmUgc3RyZWFtL3Rva2VuLgpDb2xsZWN0RW1pc3Npb25SZXdhcmQoY3Jvc3MoY3VyKSkKQ29sbGVjdFByb3RvY29sRmVlUmV3YXJkKGNyb3NzKGN1ciksIHRva2VuUGF0aCkKCi8vIFN0YXJ0IHVuZGVsZWdhdGlvbi4gQ29sbGVjdCBvbmx5IGFmdGVyIHRoZSBjb25maWd1cmVkIGxvY2t1cCAoNyBkYXlzIGJ5IGRlZmF1bHQpLgpVbmRlbGVnYXRlKGNyb3NzKGN1ciksIGRlbGVnYXRlZSwgMjUwXzAwMF8wMDApCi8vIC4uLndhaXQgdW50aWwgdGhlIGxvY2t1cCBoYXMgZXhwaXJlZC4uLgpDb2xsZWN0VW5kZWxlZ2F0ZWRHbnMoY3Jvc3MoY3VyKSkKYGBgCgojIyBTZWN1cml0eQoKLSBUaW1lc3RhbXBlZCBkZWxlZ2F0aW9uIGhpc3RvcnkgYW5kIGNvbmZpZ3VyYWJsZSBzbW9vdGhpbmcgcmVkdWNlIGZsYXNoLWxvYW4tc3R5bGUgdm90aW5nIG1hbmlwdWxhdGlvbjsgdGhleSBkbyBub3QgcHJvdmlkZSBhIGJsb2NrIHNuYXBzaG90LgotIFVuZGVsZWdhdGlvbiByZW1vdmVzIHZvdGluZyBwb3dlciBpbW1lZGlhdGVseSwgd2hpbGUgdGhlIGxvY2t1cCBkZWxheXMgR05TIHdpdGhkcmF3YWwuCi0gUHJvdG9jb2wtZmVlIHN0YWtlIGNoYW5nZXMgbXVzdCByZW1haW4gaW5kZXBlbmRlbnQgb2YgdGhlIG51bWJlciBvZiBmZWUgdG9rZW5zOyBvbmx5IGNvbGxlY3Rpb24gZm9sZHMgZmVlIGJ1Y2tldHMuCi0gTGF1bmNocGFkIHJld2FyZCBlbnRyeSBwb2ludHMgYXJlIHJlc3RyaWN0ZWQgdG8gdGhlIGxhdW5jaHBhZCBjb250cmFjdCBhbmQgcmVnaXN0ZXJlZCBwcm9qZWN0IHdhbGxldHMuCi0gU25hcHNob3QgY2xlYW51cCBtdXN0IHByZXNlcnZlIGRhdGEgc3RpbGwgbmVlZGVkIGJ5IGFjdGl2ZSBwcm9wb3NhbHMuChrXEQoKYXNzZXJ0LmdubxLIEXBhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJImVycm9ycyIKCSJ0aW1lIgoKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9nb3Zlcm5hbmNlIgopCgovLyBhc3NlcnRJc1ZhbGlkRGVsZWdhdGVBbW91bnQgdmFsaWRhdGVzIHRoYXQgdGhlIGRlbGVnYXRpb24gYW1vdW50IG1lZXRzIHN5c3RlbSByZXF1aXJlbWVudHMuCi8vIFRoaXMgZnVuY3Rpb24gY2hlY2tzIG1pbmltdW0gYW1vdW50IGFuZCBtdWx0aXBsZSByZXF1aXJlbWVudHMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBhbW91bnQ6IGFtb3VudCB0byB2YWxpZGF0ZQovLwovLyBSZXR1cm5zOgovLyAgIC0gZXJyb3I6IG5pbCBpZiB2YWxpZCwgZXJyb3IgZGVzY3JpYmluZyB2YWxpZGF0aW9uIGZhaWx1cmUKZnVuYyBhc3NlcnRJc1ZhbGlkRGVsZWdhdGVBbW91bnQoYW1vdW50IGludDY0KSB7CglpZiBhbW91bnQgPCBtaW5pbXVtQW1vdW50IHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJyTGVzc1RoYW5NaW5pbXVtLAoJCQl1Zm10LlNwcmludGYoIm1pbmltdW0gYW1vdW50IHRvIGRlbGVnYXRlIGlzICVkIChyZXF1ZXN0ZWQ6JWQpIiwgbWluaW11bUFtb3VudCwgYW1vdW50KSwKCQkpKQoJfQoKCWlmIGFtb3VudCVtaW5pbXVtQW1vdW50ICE9IDAgewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbnZhbGlkQW1vdW50LAoJCQl1Zm10LlNwcmludGYoImFtb3VudCBtdXN0IGJlIG11bHRpcGxlIG9mICVkIiwgbWluaW11bUFtb3VudCksCgkJKSkKCX0KfQoKZnVuYyBhc3NlcnRJc1ZhbGlkU25hcHNob3RUaW1lKHNuYXBzaG90VGltZSBpbnQ2NCkgewoJaWYgc25hcHNob3RUaW1lIDwgMCB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckludmFsaWRTbmFwc2hvdFRpbWUsCgkJCXVmbXQuU3ByaW50Zigic25hcHNob3QgdGltZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAwIChyZXF1ZXN0ZWQ6JWQpIiwgc25hcHNob3RUaW1lKSwKCQkpKQoJfQoKCWN1cnJlbnRUaW1lIDo9IHRpbWUuTm93KCkuVW5peCgpCgltYXhTbW9vdGhpbmdQZXJpb2QgOj0gZ292ZXJuYW5jZS5HZXRNYXhTbW9vdGhpbmdQZXJpb2QoKQoKCWlmIHNuYXBzaG90VGltZSA+IGN1cnJlbnRUaW1lLW1heFNtb290aGluZ1BlcmlvZCB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckludmFsaWRTbmFwc2hvdFRpbWUsCgkJCXVmbXQuU3ByaW50Zigic25hcHNob3QgdGltZSBtdXN0IGJlIGxlc3MgdGhhbiAlZCAocmVxdWVzdGVkOiVkKSIsIGN1cnJlbnRUaW1lLW1heFNtb290aGluZ1BlcmlvZCwgc25hcHNob3RUaW1lKSwKCQkpKQoJfQp9CgovLyBhc3NlcnRJc0F2YWlsYWJsZUNsZWFudXBTbmFwc2hvdFRpbWUgY2hlY2tzIHRoYXQgbm8gYWN0aXZlIHByb3Bvc2FscyBuZWVkCmZ1bmMgYXNzZXJ0SXNBdmFpbGFibGVDbGVhbnVwU25hcHNob3RUaW1lKGNsZWFudXBTbmFwc2hvdFRpbWUgaW50NjQpIHsKCW9sZGVzdEFjdGl2ZVNuYXBzaG90VGltZSwgaGFzQWN0aXZlUHJvcG9zYWwsIGVyciA6PSBnb3Zlcm5hbmNlLkdldE9sZGVzdEFjdGl2ZVByb3Bvc2FsU25hcHNob3RUaW1lKCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCWlmICFoYXNBY3RpdmVQcm9wb3NhbCB7CgkJLy8gTm8gYWN0aXZlIHByb3Bvc2FscywgY2xlYW51cCBpcyBzYWZlCgkJcmV0dXJuCgl9CgoJaWYgY2xlYW51cFNuYXBzaG90VGltZSA+IG9sZGVzdEFjdGl2ZVNuYXBzaG90VGltZSB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckludmFsaWRTbmFwc2hvdFRpbWUsCgkJCXVmbXQuU3ByaW50ZigKCQkJCSJjYW5ub3QgY2xlYW51cCBkZWxlZ2F0aW9uIGhpc3Rvcnk6IGFjdGl2ZSBwcm9wb3NhbCByZXF1aXJlcyBkYXRhIGZyb20gc25hcHNob3QgdGltZSAlZCwgYnV0IGNsZWFudXAgd291bGQgcmVtb3ZlIGRhdGEgYmVmb3JlICVkIiwKCQkJCW9sZGVzdEFjdGl2ZVNuYXBzaG90VGltZSwKCQkJCWNsZWFudXBTbmFwc2hvdFRpbWUsCgkJCSksCgkJKSkKCX0KfQoKZnVuYyBhc3NlcnROb1NhbWVEZWxlZ2F0ZWUoZGVsZWdhdGVlLCBuZXdEZWxlZ2F0ZWUgYWRkcmVzcykgewoJaWYgZGVsZWdhdGVlID09IG5ld0RlbGVnYXRlZSB7CgkJcGFuaWMoZXJyb3JzLk5ldyhlcnJTYW1lRGVsZWdhdGVlKSkKCX0KfQoKZnVuYyBhc3NlcnROb3RJbXBsZW1lbnRZZXQoKSB7CglwYW5pYygiTm90SW1wbGVtZW50WWV0IikKfQoa2wMKCmNvbnN0cy5nbm8SzANwYWNrYWdlIHN0YWtlcgoKY29uc3QgKAoJbWluaW11bUFtb3VudCA9IDFfMDAwXzAwMCAvLyAxIEdOUwoKCS8vIG1heEFjY3J1YWxCdWNrZXRzUGVyQ29sbGVjdCBib3VuZHMgaG93IG1hbnkgcGVuZGluZyBhY2NydWFsIGJ1Y2tldHMgb25lCgkvLyBzaW5nbGUtdG9rZW4gY29sbGVjdCBmb2xkcy4gV2hhdGV2ZXIgaXMgbGVmdCBzdGF5cyBwZW5kaW5nIGZvciB0aGUgbmV4dCBjb2xsZWN0LgoJbWF4QWNjcnVhbEJ1Y2tldHNQZXJDb2xsZWN0ID0gMjU2CgkvLyBtYXhTdGFrZUV2ZW50c1BlckNvbGxlY3QgYm91bmRzIGhvdyBtYW55IG9mIHRoZSBzdGFrZXIncyBvd24gc3Rha2UgZXZlbnRzIG9uZQoJLy8gc2luZ2xlLXRva2VuIGNvbGxlY3Qgc2V0dGxlcy4gV2hhdGV2ZXIgaXMgbGVmdCBzdGF5cyBwZW5kaW5nIGZvciB0aGUgbmV4dCBjb2xsZWN0LgoJbWF4U3Rha2VFdmVudHNQZXJDb2xsZWN0ID0gMjU2CikKGs4sCg5kZWxlZ2F0aW9uLmdubxK7LHBhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJImVycm9ycyIKCglnbnNtYXRoICJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9zdGFrZXIiCikKCmNvbnN0IGVyckNvbGxlY3RBbW91bnRFeGNlZWRzQ29sbGVjdGFibGUgPSAiYW1vdW50IHRvIGNvbGxlY3QgaXMgZ3JlYXRlciB0aGFuIGNvbGxlY3RhYmxlIGFtb3VudCIKCnR5cGUgRGVsZWdhdGlvblJlc29sdmVyIHN0cnVjdCB7CglkZWxlZ2F0aW9uICpzdGFrZXIuRGVsZWdhdGlvbgp9CgovLyBOZXdEZWxlZ2F0aW9uUmVzb2x2ZXIgd3JhcHMgYSBkZWxlZ2F0aW9uIGluIGEgcmVzb2x2ZXIgZm9yIGRlcml2ZWQgYW1vdW50cyBhbmQgd2l0aGRyYXdhbHMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBkZWxlZ2F0aW9uOiBkZWxlZ2F0aW9uIHN0YXRlIHRvIHJlc29sdmUKLy8KLy8gUmV0dXJuczoKLy8gICAtICpEZWxlZ2F0aW9uUmVzb2x2ZXI6IHJlc29sdmVyIGJhY2tlZCBieSBkZWxlZ2F0aW9uCmZ1bmMgTmV3RGVsZWdhdGlvblJlc29sdmVyKGRlbGVnYXRpb24gKnN0YWtlci5EZWxlZ2F0aW9uKSAqRGVsZWdhdGlvblJlc29sdmVyIHsKCXJldHVybiAmRGVsZWdhdGlvblJlc29sdmVye2RlbGVnYXRpb259Cn0KCi8vIEdldCByZXR1cm5zIHRoZSB1bmRlcmx5aW5nIGRlbGVnYXRpb24gc3RhdGUuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqc3Rha2VyLkRlbGVnYXRpb246IHdyYXBwZWQgZGVsZWdhdGlvbiBpbnN0YW5jZQpmdW5jIChyICpEZWxlZ2F0aW9uUmVzb2x2ZXIpIEdldCgpICpzdGFrZXIuRGVsZWdhdGlvbiB7CglyZXR1cm4gci5kZWxlZ2F0aW9uCn0KCi8vIERlbGVnYXRlZEFtb3VudCByZXR1cm5zIHRvdGFsIGRlbGVnYXRlZCBhbW91bnQgbWludXMgYW1vdW50IGFscmVhZHkgdW5kZWxlZ2F0ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogYW1vdW50IHN0aWxsIGRlbGVnYXRlZApmdW5jIChyICpEZWxlZ2F0aW9uUmVzb2x2ZXIpIERlbGVnYXRlZEFtb3VudCgpIGludDY0IHsKCXJldHVybiBnbnNtYXRoLlNhZmVTdWJJbnQ2NChyLmRlbGVnYXRpb24uVG90YWxEZWxlZ2F0ZWRBbW91bnQoKSwgci5kZWxlZ2F0aW9uLlVuRGVsZWdhdGVkQW1vdW50KCkpCn0KCi8vIExvY2tlZEFtb3VudCByZXR1cm5zIHRvdGFsIGRlbGVnYXRlZCBhbW91bnQgbWludXMgYW1vdW50IGFscmVhZHkgY29sbGVjdGVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IGFtb3VudCBzdGlsbCBsb2NrZWQgaW4gdGhlIGRlbGVnYXRpb24KZnVuYyAociAqRGVsZWdhdGlvblJlc29sdmVyKSBMb2NrZWRBbW91bnQoKSBpbnQ2NCB7CglyZXR1cm4gZ25zbWF0aC5TYWZlU3ViSW50NjQoci5kZWxlZ2F0aW9uLlRvdGFsRGVsZWdhdGVkQW1vdW50KCksIHIuZGVsZWdhdGlvbi5Db2xsZWN0ZWRBbW91bnQoKSkKfQoKLy8gSXNFbXB0eSByZXBvcnRzIHdoZXRoZXIgbm8gbG9ja2VkIGRlbGVnYXRpb24gYW1vdW50IHJlbWFpbnMuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBib29sOiB0cnVlIHdoZW4gTG9ja2VkQW1vdW50IGlzIHplcm8sIG90aGVyd2lzZSBmYWxzZQpmdW5jIChyICpEZWxlZ2F0aW9uUmVzb2x2ZXIpIElzRW1wdHkoKSBib29sIHsKCXJldHVybiByLkxvY2tlZEFtb3VudCgpID09IDAKfQoKLy8gQ29sbGVjdGFibGVBbW91bnQgY2FsY3VsYXRlcyB0aGUgdG90YWwgYW1vdW50IHRoYXQgY2FuIGJlIGNvbGxlY3RlZCBhdCB0aGUgZ2l2ZW4gdGltZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnRUaW1lOiBjdXJyZW50IFVuaXggdGltZXN0YW1wIHVzZWQgdG8gZXZhbHVhdGUgZWFjaCB3aXRoZHJhd2FsJ3MgbG9ja3VwCi8vCi8vIFJldHVybnM6Ci8vICAgLSB0b3RhbDogc3VtIG9mIGFsbCB3aXRoZHJhd2FsIGFtb3VudHMgY3VycmVudGx5IGF2YWlsYWJsZSBmb3IgY29sbGVjdGlvbgpmdW5jIChyICpEZWxlZ2F0aW9uUmVzb2x2ZXIpIENvbGxlY3RhYmxlQW1vdW50KGN1cnJlbnRUaW1lIGludDY0KSAodG90YWwgaW50NjQpIHsKCWZvciBfLCB3aXRoZHJhdyA6PSByYW5nZSByLmRlbGVnYXRpb24uV2l0aGRyYXdzKCkgewoJCXRvdGFsID0gZ25zbWF0aC5TYWZlQWRkSW50NjQodG90YWwsIE5ld0RlbGVnYXRpb25XaXRoZHJhd1Jlc29sdmVyKCZ3aXRoZHJhdykuQ29sbGVjdGFibGVBbW91bnQoY3VycmVudFRpbWUpKQoJfQoKCXJldHVybiB0b3RhbAp9CgovLyBVbkRlbGVnYXRlIHByb2Nlc3NlcyBhbiB1bmRlbGVnYXRpb24gd2l0aCBhIHRpbWUtYmFzZWQgbG9ja3VwIHBlcmlvZC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGFtb3VudDogYW1vdW50IHRvIHVuZGVsZWdhdGUgYW5kIHBsYWNlIGludG8gYSB3aXRoZHJhd2FsCi8vICAgLSBjdXJyZW50SGVpZ2h0OiBibG9jayBoZWlnaHQgYXQgd2hpY2ggdGhlIHVuZGVsZWdhdGlvbiBpcyByZWNvcmRlZAovLyAgIC0gY3VycmVudFRpbWVzdGFtcDogVW5peCB0aW1lc3RhbXAgYXQgd2hpY2ggdGhlIHVuZGVsZWdhdGlvbiBpcyByZWNvcmRlZAovLyAgIC0gdW5EZWxlZ2F0aW9uTG9ja3VwUGVyaW9kOiBsb2NrdXAgZHVyYXRpb24gaW4gc2Vjb25kcyBiZWZvcmUgdGhlIHdpdGhkcmF3YWwgaXMgY29sbGVjdGlibGUKZnVuYyAociAqRGVsZWdhdGlvblJlc29sdmVyKSBVbkRlbGVnYXRlKAoJYW1vdW50LCBjdXJyZW50SGVpZ2h0LCBjdXJyZW50VGltZXN0YW1wLCB1bkRlbGVnYXRpb25Mb2NrdXBQZXJpb2QgaW50NjQsCikgewoJci5kZWxlZ2F0aW9uLlNldFVuRGVsZWdhdGVBbW91bnQoZ25zbWF0aC5TYWZlQWRkSW50NjQoci5kZWxlZ2F0aW9uLlVuRGVsZWdhdGVkQW1vdW50KCksIGFtb3VudCkpCgoJd2l0aGRyYXcgOj0gTmV3RGVsZWdhdGlvbldpdGhkcmF3KAoJCXIuZGVsZWdhdGlvbi5JRCgpLAoJCWFtb3VudCwKCQljdXJyZW50SGVpZ2h0LAoJCWN1cnJlbnRUaW1lc3RhbXAsCgkJdW5EZWxlZ2F0aW9uTG9ja3VwUGVyaW9kLAoJKQoJci5kZWxlZ2F0aW9uLkFkZFdpdGhkcmF3KHdpdGhkcmF3KQp9CgovLyBVbkRlbGVnYXRlV2l0aG91dExvY2t1cCBwcm9jZXNzZXMgYW4gaW1tZWRpYXRlIHVuZGVsZWdhdGlvbiB3aXRob3V0IGxvY2t1cC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGFtb3VudDogYW1vdW50IHRvIHVuZGVsZWdhdGUgYW5kIG1hcmsgYXMgY29sbGVjdGVkIGltbWVkaWF0ZWx5Ci8vICAgLSBjdXJyZW50SGVpZ2h0OiBjdXJyZW50IGJsb2NrIGhlaWdodCBjb250ZXh0OyByZXRhaW5lZCBmb3IgQVBJIHN5bW1ldHJ5IGFuZCB1bnVzZWQgYnkgdGhpcyBpbW1lZGlhdGUgcGF0aAovLyAgIC0gY3VycmVudFRpbWU6IGN1cnJlbnQgVW5peCB0aW1lc3RhbXAgY29udGV4dDsgcmV0YWluZWQgZm9yIEFQSSBzeW1tZXRyeSBhbmQgdW51c2VkIGJ5IHRoaXMgaW1tZWRpYXRlIHBhdGgKZnVuYyAociAqRGVsZWdhdGlvblJlc29sdmVyKSBVbkRlbGVnYXRlV2l0aG91dExvY2t1cCgKCWFtb3VudCwgY3VycmVudEhlaWdodCwgY3VycmVudFRpbWUgaW50NjQsCikgewoJci5kZWxlZ2F0aW9uLlNldFVuRGVsZWdhdGVBbW91bnQoZ25zbWF0aC5TYWZlQWRkSW50NjQoci5kZWxlZ2F0aW9uLlVuRGVsZWdhdGVkQW1vdW50KCksIGFtb3VudCkpCglyLmRlbGVnYXRpb24uU2V0Q29sbGVjdGVkQW1vdW50KGduc21hdGguU2FmZUFkZEludDY0KHIuZGVsZWdhdGlvbi5Db2xsZWN0ZWRBbW91bnQoKSwgYW1vdW50KSkKfQoKLy8gcHJvY2Vzc0NvbGxlY3Rpb24gaGFuZGxlcyB0aGUgYWN0dWFsIGNvbGxlY3Rpb24gbG9naWMKZnVuYyAociAqRGVsZWdhdGlvblJlc29sdmVyKSBwcm9jZXNzQ29sbGVjdGlvbihjdXJyZW50VGltZSBpbnQ2NCkgKGludDY0LCBlcnJvcikgewoJY29sbGVjdGVkQW1vdW50IDo9IGludDY0KDApCgl3aXRoZHJhd3MgOj0gci5kZWxlZ2F0aW9uLldpdGhkcmF3cygpCgoJZm9yIGkgOj0gcmFuZ2Ugd2l0aGRyYXdzIHsKCQlyZXNvbHZlciA6PSBOZXdEZWxlZ2F0aW9uV2l0aGRyYXdSZXNvbHZlcigmd2l0aGRyYXdzW2ldKQoKCQljb2xsZWN0YWJsZUFtb3VudCA6PSByZXNvbHZlci5Db2xsZWN0YWJsZUFtb3VudChjdXJyZW50VGltZSkKCQlpZiBjb2xsZWN0YWJsZUFtb3VudCA8PSAwIHsKCQkJY29udGludWUKCQl9CgoJCWVyciA6PSByZXNvbHZlci5Db2xsZWN0KGNvbGxlY3RhYmxlQW1vdW50LCBjdXJyZW50VGltZSkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIDAsIGVycgoJCX0KCgkJdXBkYXRlZEFtb3VudCwgZXJyIDo9IGFkZFRvQ29sbGVjdGVkQW1vdW50KHIuZGVsZWdhdGlvbi5Db2xsZWN0ZWRBbW91bnQoKSwgY29sbGVjdGFibGVBbW91bnQpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiAwLCBlcnIKCQl9CgoJCXIuZGVsZWdhdGlvbi5TZXRDb2xsZWN0ZWRBbW91bnQodXBkYXRlZEFtb3VudCkKCQljb2xsZWN0ZWRBbW91bnQgPSBnbnNtYXRoLlNhZmVBZGRJbnQ2NChjb2xsZWN0ZWRBbW91bnQsIGNvbGxlY3RhYmxlQW1vdW50KQoJfQoKCS8vIFNraXAgZmlsdGVyaW5nIGlmIG5vdGhpbmcgd2FzIGNvbGxlY3RlZAoJaWYgY29sbGVjdGVkQW1vdW50ID09IDAgewoJCXJldHVybiBjb2xsZWN0ZWRBbW91bnQsIG5pbAoJfQoKCWN1cnJlbnRJbmRleCA6PSAwCgoJZm9yIGkgOj0gcmFuZ2Ugd2l0aGRyYXdzIHsKCQlpZiAhd2l0aGRyYXdzW2ldLklzQ29sbGVjdGVkKCkgewoJCQlyLmRlbGVnYXRpb24uU2V0V2l0aGRyYXcoY3VycmVudEluZGV4LCB3aXRoZHJhd3NbaV0pCgkJCWN1cnJlbnRJbmRleCsrCgkJfQoJfQoKCXIuZGVsZWdhdGlvbi5TZXRXaXRoZHJhd3Mod2l0aGRyYXdzWzpjdXJyZW50SW5kZXhdKQoKCXJldHVybiBjb2xsZWN0ZWRBbW91bnQsIG5pbAp9CgpmdW5jIGFkZFRvQ29sbGVjdGVkQW1vdW50KGNvbGxlY3RlZEFtb3VudCwgYW1vdW50IGludDY0KSAoaW50NjQsIGVycm9yKSB7CglpZiBhbW91bnQgPCAwIHsKCQlyZXR1cm4gMCwgZXJyb3JzLk5ldyhlcnJBbW91bnRNdXN0QmVOb25OZWdhdGl2ZSkKCX0KCXJldHVybiBnbnNtYXRoLlNhZmVBZGRJbnQ2NChjb2xsZWN0ZWRBbW91bnQsIGFtb3VudCksIG5pbAp9CgovLyBOZXdEZWxlZ2F0aW9uIGNyZWF0ZXMgYSBuZXcgZGVsZWdhdGlvbi4KLy8gVGhpcyBpcyBhIGNvbnZlbmllbmNlIHdyYXBwZXIgYXJvdW5kIHN0YWtlci5OZXdEZWxlZ2F0aW9uLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gaWQ6IGRlbGVnYXRpb24gSUQKLy8gICAtIGRlbGVnYXRlRnJvbTogZGVsZWdhdG9yJ3MgYWRkcmVzcwovLyAgIC0gZGVsZWdhdGVUbzogZGVsZWdhdGVlJ3MgYWRkcmVzcwovLyAgIC0gZGVsZWdhdGVBbW91bnQ6IGFtb3VudCB0byBkZWxlZ2F0ZQovLyAgIC0gY3JlYXRlZEhlaWdodDogY3JlYXRpb24gYmxvY2sgaGVpZ2h0Ci8vICAgLSBjcmVhdGVkQXQ6IGNyZWF0aW9uIHRpbWVzdGFtcAovLwovLyBSZXR1cm5zOgovLyAgIC0gKnN0YWtlci5EZWxlZ2F0aW9uOiBuZXcgZGVsZWdhdGlvbiBpbnN0YW5jZQpmdW5jIE5ld0RlbGVnYXRpb24oCglpZCBpbnQ2NCwKCWRlbGVnYXRlRnJvbSwgZGVsZWdhdGVUbyBhZGRyZXNzLAoJZGVsZWdhdGVBbW91bnQsIGNyZWF0ZWRIZWlnaHQsIGNyZWF0ZWRBdCBpbnQ2NCwKKSAqc3Rha2VyLkRlbGVnYXRpb24gewoJcmV0dXJuIHN0YWtlci5OZXdEZWxlZ2F0aW9uKAoJCWlkLAoJCWRlbGVnYXRlRnJvbSwKCQlkZWxlZ2F0ZVRvLAoJCWRlbGVnYXRlQW1vdW50LAoJCWNyZWF0ZWRIZWlnaHQsCgkJY3JlYXRlZEF0LAoJKQp9ChqpHgoWZGVsZWdhdGlvbl9tYW5hZ2VyLmdubxKOHnBhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJImduby5sYW5kL3IvZ25vc3dhcC9nb3Yvc3Rha2VyIgopCgp0eXBlIERlbGVnYXRpb25NYW5hZ2VyUmVzb2x2ZXIgc3RydWN0IHsKCSpzdGFrZXIuRGVsZWdhdGlvbk1hbmFnZXIKfQoKLy8gTmV3RGVsZWdhdGlvbk1hbmFnZXJSZXNvbHZlciBjcmVhdGVzIGEgcmVzb2x2ZXIgb3ZlciBhbiBleGlzdGluZyBkZWxlZ2F0aW9uIG1hbmFnZXIuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBkZWxlZ2F0aW9uTWFuYWdlcjogbWFuYWdlciB3aG9zZSBkb21haW4tb3duZWQgZGVsZWdhdGlvbiB0cmVlcyB3aWxsIGJlIHF1ZXJpZWQgb3IgdXBkYXRlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtICpEZWxlZ2F0aW9uTWFuYWdlclJlc29sdmVyOiByZXNvbHZlciBleHBvc2luZyBhZGRyZXNzLXR5cGVkIGRlbGVnYXRpb24gb3BlcmF0aW9ucy4KZnVuYyBOZXdEZWxlZ2F0aW9uTWFuYWdlclJlc29sdmVyKGRlbGVnYXRpb25NYW5hZ2VyICpzdGFrZXIuRGVsZWdhdGlvbk1hbmFnZXIpICpEZWxlZ2F0aW9uTWFuYWdlclJlc29sdmVyIHsKCXJldHVybiAmRGVsZWdhdGlvbk1hbmFnZXJSZXNvbHZlcntkZWxlZ2F0aW9uTWFuYWdlcn0KfQoKLy8gR2V0VXNlckRlbGVnYXRpb25JRHNXaXRoRGVsZWdhdGVlIHJldHJpZXZlcyBhbGwgZGVsZWdhdGlvbiBJRHMgZm9yIGEgc3BlY2lmaWMgZGVsZWdhdG9yLWRlbGVnYXRlZSBwYWlyLgovLyBUaGlzIG1ldGhvZCBpcyB1c2VkIHRvIGZpbmQgZGVsZWdhdGlvbnMgZnJvbSBhIHNwZWNpZmljIHVzZXIgdG8gYSBzcGVjaWZpYyBkZWxlZ2F0ZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGRlbGVnYXRvcjogYWRkcmVzcyBvZiB0aGUgdXNlciB3aG8gZGVsZWdhdGVkIHRva2VucwovLyAgIC0gZGVsZWdhdGVlOiBhZGRyZXNzIG9mIHRoZSB1c2VyIHdobyByZWNlaXZlZCB0aGUgZGVsZWdhdGlvbgovLwovLyBSZXR1cm5zOgovLyAgIC0gW11pbnQ2NDogbWF0Y2hpbmcgZGVsZWdhdGlvbiBJRHMsIG9yIGFuIGVtcHR5IHNsaWNlIHdoZW4gbm8gcGFpciBpcyBzdG9yZWQuCmZ1bmMgKGRtICpEZWxlZ2F0aW9uTWFuYWdlclJlc29sdmVyKSBHZXRVc2VyRGVsZWdhdGlvbklEc1dpdGhEZWxlZ2F0ZWUoZGVsZWdhdG9yLCBkZWxlZ2F0ZWUgYWRkcmVzcykgW11pbnQ2NCB7CglkZWxlZ2F0b3JBZGRyZXNzIDo9IGRlbGVnYXRvci5TdHJpbmcoKQoJZGVsZWdhdGVlQWRkcmVzcyA6PSBkZWxlZ2F0ZWUuU3RyaW5nKCkKCglpZHMsIGV4aXN0cyA6PSBkbS5HZXREZWxlZ2F0aW9uSURzKGRlbGVnYXRvckFkZHJlc3MsIGRlbGVnYXRlZUFkZHJlc3MpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gW11pbnQ2NHt9Cgl9CglyZXR1cm4gaWRzCn0KCi8vIEdldFVzZXJEZWxlZ2F0aW9uSURzIHJldHJpZXZlcyBhbGwgZGVsZWdhdGlvbiBJRHMgZm9yIGEgc3BlY2lmaWMgZGVsZWdhdG9yIGFjcm9zcyBhbGwgZGVsZWdhdGVlcy4KLy8gVGhpcyBtZXRob2QgaXMgdXNlZCB0byBmaW5kIGFsbCBkZWxlZ2F0aW9ucyBtYWRlIGJ5IGEgc3BlY2lmaWMgdXNlci4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGRlbGVnYXRvcjogYWRkcmVzcyBvZiB0aGUgdXNlciB3aG9zZSBkZWxlZ2F0aW9ucyB0byByZXRyaWV2ZQovLwovLyBSZXR1cm5zOgovLyAgIC0gW11pbnQ2NDogY29uY2F0ZW5hdGVkIGRlbGVnYXRpb24gSURzIGZyb20gZXZlcnkgc3RvcmVkIGRlbGVnYXRlZSBlbnRyeSwgb3IgYW4gZW1wdHkgc2xpY2Ugd2hlbiBhYnNlbnQuCmZ1bmMgKGRtICpEZWxlZ2F0aW9uTWFuYWdlclJlc29sdmVyKSBHZXRVc2VyRGVsZWdhdGlvbklEcyhkZWxlZ2F0b3IgYWRkcmVzcykgW11pbnQ2NCB7CglkZWxlZ2F0b3JBZGRyZXNzIDo9IGRlbGVnYXRvci5TdHJpbmcoKQoJZGVsZWdhdGlvbklEcyA6PSBtYWtlKFtdaW50NjQsIDApCgoJLy8gR2V0IGFsbCBkZWxlZ2F0aW9ucyBmb3IgdGhpcyBkZWxlZ2F0b3IKCWRlbGVnYXRpb25zLCBleGlzdHMgOj0gZG0uR2V0RGVsZWdhdG9yRGVsZWdhdGlvbnMoZGVsZWdhdG9yQWRkcmVzcykKCWlmICFleGlzdHMgewoJCXJldHVybiBkZWxlZ2F0aW9uSURzCgl9CgoJLy8gQ29sbGVjdCBkZWxlZ2F0aW9uIElEcyBmcm9tIGFsbCBkZWxlZ2F0ZWVzIGJ5IGl0ZXJhdGluZyB0aGUgQlBUcmVlCglkZWxlZ2F0aW9ucy5JdGVyYXRlKCIiLCAiIiwgZnVuYyhrZXkgc3RyaW5nLCB2YWx1ZSBpbnRlcmZhY2V7fSkgYm9vbCB7CgkJaWYgdG9EZWxlZ2F0aW9ucywgb2sgOj0gdmFsdWUuKFtdaW50NjQpOyBvayB7CgkJCWRlbGVnYXRpb25JRHMgPSBhcHBlbmQoZGVsZWdhdGlvbklEcywgdG9EZWxlZ2F0aW9ucy4uLikKCQl9CgkJcmV0dXJuIGZhbHNlCgl9KQoKCXJldHVybiBkZWxlZ2F0aW9uSURzCn0KCi8vIGFkZERlbGVnYXRpb24gYWRkcyBhIGRlbGVnYXRpb24gSUQgdG8gdGhlIG1hbmFnZXIncyB0cmFja2luZyBzeXN0ZW0uCi8vIFRoaXMgbWV0aG9kIGNyZWF0ZXMgdGhlIG5lY2Vzc2FyeSBuZXN0ZWQgbWFwIHN0cnVjdHVyZSBpZiBpdCBkb2Vzbid0IGV4aXN0Ci8vIGFuZCBlbnN1cmVzIG5vIGR1cGxpY2F0ZSBkZWxlZ2F0aW9uIElEcyBhcmUgc3RvcmVkLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gZGVsZWdhdG9yOiBhZGRyZXNzIG9mIHRoZSB1c2VyIHdobyBtYWRlIHRoZSBkZWxlZ2F0aW9uCi8vICAgLSBkZWxlZ2F0ZWU6IGFkZHJlc3Mgb2YgdGhlIHVzZXIgd2hvIHJlY2VpdmVkIHRoZSBkZWxlZ2F0aW9uCi8vICAgLSBkZWxlZ2F0aW9uSUQ6IHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgZGVsZWdhdGlvbgpmdW5jIChkbSAqRGVsZWdhdGlvbk1hbmFnZXJSZXNvbHZlcikgYWRkRGVsZWdhdGlvbihkZWxlZ2F0b3IsIGRlbGVnYXRlZSBhZGRyZXNzLCBkZWxlZ2F0aW9uSUQgaW50NjQpIHsKCS8vIERlbGVnYXRlIHRoZSByZWFkLW1vZGlmeS13cml0ZSB0byB0aGUgZG9tYWluIG1ldGhvZCBzbyB0aGUgbmVzdGVkIEJQVHJlZQoJLy8gbXV0YXRpb24gc3RheXMgd2l0aGluIHRoZSBvd25pbmcgcmVhbG07IHNwbGl0dGluZyB0aGUgZ2V0IGFuZCBzZXQgYWNyb3NzCgkvLyB0aGUgcmVhbG0gYm91bmRhcnkgaGVyZSB3b3VsZCB0YWludCB0aGUgcmUtZmV0Y2hlZCBpbm5lciB0cmVlLgoJZG0uQWRkRGVsZWdhdGlvbklEKGRlbGVnYXRvci5TdHJpbmcoKSwgZGVsZWdhdGVlLlN0cmluZygpLCBkZWxlZ2F0aW9uSUQpCn0KCi8vIHJlbW92ZURlbGVnYXRpb24gcmVtb3ZlcyBhIGRlbGVnYXRpb24gSUQgZnJvbSB0aGUgbWFuYWdlcidzIHRyYWNraW5nIHN5c3RlbS4KLy8gVGhpcyBtZXRob2QgZmluZHMgYW5kIHJlbW92ZXMgdGhlIHNwZWNpZmllZCBkZWxlZ2F0aW9uIElEIGZyb20gdGhlIGFwcHJvcHJpYXRlIHNsaWNlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gZGVsZWdhdG9yOiBhZGRyZXNzIG9mIHRoZSB1c2VyIHdobyBtYWRlIHRoZSBkZWxlZ2F0aW9uCi8vICAgLSBkZWxlZ2F0ZWU6IGFkZHJlc3Mgb2YgdGhlIHVzZXIgd2hvIHJlY2VpdmVkIHRoZSBkZWxlZ2F0aW9uCi8vICAgLSBkZWxlZ2F0aW9uSUQ6IHVuaXF1ZSBpZGVudGlmaWVyIGZvciB0aGUgZGVsZWdhdGlvbiB0byByZW1vdmUKZnVuYyAoZG0gKkRlbGVnYXRpb25NYW5hZ2VyUmVzb2x2ZXIpIHJlbW92ZURlbGVnYXRpb24oZGVsZWdhdG9yLCBkZWxlZ2F0ZWUgYWRkcmVzcywgZGVsZWdhdGlvbklEIGludDY0KSB7CgkvLyBEZWxlZ2F0ZSB0aGUgcmVhZC1tb2RpZnktd3JpdGUgdG8gdGhlIGRvbWFpbiBtZXRob2Qgc28gdGhlIG5lc3RlZCBCUFRyZWUKCS8vIG11dGF0aW9uIHN0YXlzIHdpdGhpbiB0aGUgb3duaW5nIHJlYWxtLgoJZG0uUmVtb3ZlRGVsZWdhdGlvbklEKGRlbGVnYXRvci5TdHJpbmcoKSwgZGVsZWdhdGVlLlN0cmluZygpLCBkZWxlZ2F0aW9uSUQpCn0KGsgnChdkZWxlZ2F0aW9uX3dpdGhkcmF3LmdubxKsJ3BhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJImVycm9ycyIKCglnbnNtYXRoICJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9zdGFrZXIiCikKCnR5cGUgRGVsZWdhdGlvbldpdGhkcmF3UmVzb2x2ZXIgc3RydWN0IHsKCXdpdGhkcmF3ICpzdGFrZXIuRGVsZWdhdGlvbldpdGhkcmF3Cn0KCi8vIE5ld0RlbGVnYXRpb25XaXRoZHJhd1Jlc29sdmVyIHdyYXBzIGEgZGVsZWdhdGlvbiB3aXRoZHJhd2FsIGZvciBjb2xsZWN0aW9uCi8vIHN0YXRlIGFuZCBsb2NrdXAgY2FsY3VsYXRpb25zLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gd2l0aGRyYXc6IGRlbGVnYXRpb24gd2l0aGRyYXdhbCBzdGF0ZSB0byByZXNvbHZlCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqRGVsZWdhdGlvbldpdGhkcmF3UmVzb2x2ZXI6IHJlc29sdmVyIHJldGFpbmluZyB0aGUgc3VwcGxpZWQgd2l0aGRyYXdhbCBwb2ludGVyCmZ1bmMgTmV3RGVsZWdhdGlvbldpdGhkcmF3UmVzb2x2ZXIod2l0aGRyYXcgKnN0YWtlci5EZWxlZ2F0aW9uV2l0aGRyYXcpICpEZWxlZ2F0aW9uV2l0aGRyYXdSZXNvbHZlciB7CglyZXR1cm4gJkRlbGVnYXRpb25XaXRoZHJhd1Jlc29sdmVye3dpdGhkcmF3fQp9CgovLyBHZXQgcmV0dXJucyB0aGUgd3JhcHBlZCBkZWxlZ2F0aW9uIHdpdGhkcmF3YWwgdmFsdWUuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqc3Rha2VyLkRlbGVnYXRpb25XaXRoZHJhdzogd3JhcHBlZCB3aXRoZHJhd2FsIHBvaW50ZXIsIG9yIG5pbCB3aGVuIHRoZSByZXNvbHZlciB3YXMgY29uc3RydWN0ZWQgd2l0aCBuaWwKZnVuYyAociAqRGVsZWdhdGlvbldpdGhkcmF3UmVzb2x2ZXIpIEdldCgpICpzdGFrZXIuRGVsZWdhdGlvbldpdGhkcmF3IHsKCXJldHVybiByLndpdGhkcmF3Cn0KCi8vIENvbGxlY3RhYmxlQW1vdW50IGNhbGN1bGF0ZXMgdGhlIGFtb3VudCBhdmFpbGFibGUgZm9yIGNvbGxlY3Rpb24gYXQgdGhlIGdpdmVuIHRpbWUuCi8vIFJldHVybnMgemVybyBpZiB0aGUgd2l0aGRyYXdhbCBpcyBub3QgeWV0IGNvbGxlY3RhYmxlIG9yIGhhcyBiZWVuIGZ1bGx5IGNvbGxlY3RlZC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnRUaW1lOiBjdXJyZW50IHRpbWVzdGFtcCB0byBjaGVjayBjb2xsZWN0YWJpbGl0eSBhZ2FpbnN0Ci8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogYW1vdW50IGF2YWlsYWJsZSBmb3IgY29sbGVjdGlvbgpmdW5jIChyICpEZWxlZ2F0aW9uV2l0aGRyYXdSZXNvbHZlcikgQ29sbGVjdGFibGVBbW91bnQoY3VycmVudFRpbWUgaW50NjQpIGludDY0IHsKCWlmIHIuSXNDb2xsZWN0YWJsZShjdXJyZW50VGltZSkgewoJCXJldHVybiBnbnNtYXRoLlNhZmVTdWJJbnQ2NChyLndpdGhkcmF3LlVuRGVsZWdhdGVBbW91bnQoKSwgci53aXRoZHJhdy5Db2xsZWN0ZWRBbW91bnQoKSkKCX0KCglyZXR1cm4gMAp9CgovLyBJc0NvbGxlY3RhYmxlIGRldGVybWluZXMgd2hldGhlciB0aGUgd2l0aGRyYXdhbCBjYW4gYmUgY29sbGVjdGVkIGF0IHRoZSBnaXZlbiB0aW1lLgovLyBBIHdpdGhkcmF3YWwgaXMgY29sbGVjdGFibGUgaWY6Ci8vIC0gVGhlIHVuZGVsZWdhdGVkIGFtb3VudCBpcyBwb3NpdGl2ZQovLyAtIFRoZXJlIGlzIHJlbWFpbmluZyB1bmNvbGxlY3RlZCBhbW91bnQKLy8gLSBUaGUgY3VycmVudCB0aW1lIGlzIGF0IG9yIGFmdGVyIHRoZSBjb2xsZWN0YWJsZSB0aW1lCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBjdXJyZW50VGltZTogY3VycmVudCB0aW1lc3RhbXAgdG8gY2hlY2sgYWdhaW5zdAovLwovLyBSZXR1cm5zOgovLyAgIC0gYm9vbDogdHJ1ZSBpZiB0aGUgd2l0aGRyYXdhbCBjYW4gYmUgY29sbGVjdGVkLCBmYWxzZSBvdGhlcndpc2UKZnVuYyAociAqRGVsZWdhdGlvbldpdGhkcmF3UmVzb2x2ZXIpIElzQ29sbGVjdGFibGUoY3VycmVudFRpbWUgaW50NjQpIGJvb2wgewoJaWYgci53aXRoZHJhdy5VbkRlbGVnYXRlQW1vdW50KCkgPD0gMCB7CgkJcmV0dXJuIGZhbHNlCgl9CgoJcmVtYWluaW5nIDo9IGduc21hdGguU2FmZVN1YkludDY0KHIud2l0aGRyYXcuVW5EZWxlZ2F0ZUFtb3VudCgpLCByLndpdGhkcmF3LkNvbGxlY3RlZEFtb3VudCgpKQoJaWYgcmVtYWluaW5nIDw9IDAgewoJCXJldHVybiBmYWxzZQoJfQoKCWlmIGN1cnJlbnRUaW1lIDwgci53aXRoZHJhdy5Db2xsZWN0YWJsZVRpbWUoKSB7CgkJcmV0dXJuIGZhbHNlCgl9CgoJcmV0dXJuIHRydWUKfQoKLy8gSXNDb2xsZWN0ZWQgcmV0dXJucyB3aGV0aGVyIHRoZSB3aXRoZHJhd2FsIGhhcyBiZWVuIGZ1bGx5IGNvbGxlY3RlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGJvb2w6IHRydWUgaWYgZnVsbHkgY29sbGVjdGVkLCBmYWxzZSBvdGhlcndpc2UKZnVuYyAociAqRGVsZWdhdGlvbldpdGhkcmF3UmVzb2x2ZXIpIElzQ29sbGVjdGVkKCkgYm9vbCB7CglyZXR1cm4gci53aXRoZHJhdy5Jc0NvbGxlY3RlZCgpCn0KCi8vIGNvbGxlY3QgcHJvY2Vzc2VzIHRoZSBjb2xsZWN0aW9uIG9mIHRoZSBzcGVjaWZpZWQgYW1vdW50IGZyb20gdGhpcyB3aXRoZHJhd2FsLgovLyBUaGlzIG1ldGhvZCB2YWxpZGF0ZXMgY29sbGVjdGFiaWxpdHkgYW5kIHVwZGF0ZXMgdGhlIGNvbGxlY3Rpb24gc3RhdGUuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBhbW91bnQ6IEdOUyBhbW91bnQgdG8gYWRkIHRvIHRoaXMgd2l0aGRyYXdhbCdzIGNvbGxlY3RlZCBhbW91bnQKLy8gICAtIGN1cnJlbnRUaW1lOiBVbml4IHRpbWVzdGFtcCB1c2VkIHRvIGNoZWNrIGxvY2t1cCBleHBpcnkgYW5kIHJlY29yZCBjb2xsZWN0aW9uIHRpbWUKLy8KLy8gUmV0dXJuczoKLy8gICAtIGVycm9yOiBuaWwgYWZ0ZXIgdGhlIGNvbGxlY3Rpb24gc3RhdGUgaXMgdXBkYXRlZDsgZXJyV2l0aGRyYXdOb3RDb2xsZWN0YWJsZSB3aGVuIHRoZSB3aXRoZHJhd2FsIGlzIG5vdCBjb2xsZWN0YWJsZQpmdW5jIChyICpEZWxlZ2F0aW9uV2l0aGRyYXdSZXNvbHZlcikgQ29sbGVjdChhbW91bnQgaW50NjQsIGN1cnJlbnRUaW1lIGludDY0KSBlcnJvciB7CglpZiAhci5Jc0NvbGxlY3RhYmxlKGN1cnJlbnRUaW1lKSB7CgkJcmV0dXJuIGVycm9ycy5OZXcoZXJyV2l0aGRyYXdOb3RDb2xsZWN0YWJsZSkKCX0KCglyLndpdGhkcmF3LlNldENvbGxlY3RlZEFtb3VudChnbnNtYXRoLlNhZmVBZGRJbnQ2NChyLndpdGhkcmF3LkNvbGxlY3RlZEFtb3VudCgpLCBhbW91bnQpKQoKCWlmIHIud2l0aGRyYXcuVW5EZWxlZ2F0ZUFtb3VudCgpID09IHIud2l0aGRyYXcuQ29sbGVjdGVkQW1vdW50KCkgewoJCXIud2l0aGRyYXcuU2V0Q29sbGVjdGVkKHRydWUpCgkJci53aXRoZHJhdy5TZXRDb2xsZWN0ZWRBdChjdXJyZW50VGltZSkKCX0KCglyZXR1cm4gbmlsCn0KCi8vIE5ld0RlbGVnYXRpb25XaXRoZHJhdyBjcmVhdGVzIGEgbmV3IGRlbGVnYXRpb24gd2l0aGRyYXdhbCB3aXRoIGxvY2t1cCBwZXJpb2QuCi8vIFRoaXMgaXMgYSBjb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCBzdGFrZXIuTmV3RGVsZWdhdGlvbldpdGhkcmF3LgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gZGVsZWdhdGlvbklEOiB1bmlxdWUgaWRlbnRpZmllciBvZiB0aGUgYXNzb2NpYXRlZCBkZWxlZ2F0aW9uCi8vICAgLSB1bkRlbGVnYXRlQW1vdW50OiBhbW91bnQgYmVpbmcgd2l0aGRyYXduCi8vICAgLSBjcmVhdGVkSGVpZ2h0OiBoZWlnaHQgd2hlbiB0aGUgd2l0aGRyYXdhbCB3YXMgY3JlYXRlZAovLyAgIC0gY3JlYXRlZEF0OiB0aW1lc3RhbXAgd2hlbiB0aGUgd2l0aGRyYXdhbCB3YXMgY3JlYXRlZAovLyAgIC0gdW5EZWxlZ2F0aW9uTG9ja3VwUGVyaW9kOiBkdXJhdGlvbiBvZiB0aGUgbG9ja3VwIHBlcmlvZCBpbiBzZWNvbmRzCi8vCi8vIFJldHVybnM6Ci8vICAgLSBzdGFrZXIuRGVsZWdhdGlvbldpdGhkcmF3OiBuZXcgd2l0aGRyYXdhbCBpbnN0YW5jZSB3aXRoIGxvY2t1cApmdW5jIE5ld0RlbGVnYXRpb25XaXRoZHJhdygKCWRlbGVnYXRpb25JRCwKCXVuRGVsZWdhdGVBbW91bnQsCgljcmVhdGVkSGVpZ2h0LAoJY3JlYXRlZEF0LAoJdW5EZWxlZ2F0aW9uTG9ja3VwUGVyaW9kIGludDY0LAopIHN0YWtlci5EZWxlZ2F0aW9uV2l0aGRyYXcgewoJcmV0dXJuIHN0YWtlci5OZXdEZWxlZ2F0aW9uV2l0aGRyYXcoCgkJZGVsZWdhdGlvbklELAoJCXVuRGVsZWdhdGVBbW91bnQsCgkJY3JlYXRlZEhlaWdodCwKCQljcmVhdGVkQXQsCgkJdW5EZWxlZ2F0aW9uTG9ja3VwUGVyaW9kLAoJKQp9CgovLyBOZXdEZWxlZ2F0aW9uV2l0aGRyYXdXaXRob3V0TG9ja3VwIGNyZWF0ZXMgYSBuZXcgZGVsZWdhdGlvbiB3aXRoZHJhd2FsIHRoYXQgaXMgaW1tZWRpYXRlbHkgY29sbGVjdGFibGUuCi8vIFRoaXMgaXMgYSBjb252ZW5pZW5jZSB3cmFwcGVyIGFyb3VuZCBzdGFrZXIuTmV3RGVsZWdhdGlvbldpdGhkcmF3V2l0aG91dExvY2t1cC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGRlbGVnYXRpb25JRDogdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGFzc29jaWF0ZWQgZGVsZWdhdGlvbgovLyAgIC0gdW5EZWxlZ2F0ZUFtb3VudDogYW1vdW50IGJlaW5nIHdpdGhkcmF3bgovLyAgIC0gY3JlYXRlZEhlaWdodDogaGVpZ2h0IHdoZW4gdGhlIHdpdGhkcmF3YWwgd2FzIGNyZWF0ZWQKLy8gICAtIGNyZWF0ZWRBdDogdGltZXN0YW1wIHdoZW4gdGhlIHdpdGhkcmF3YWwgd2FzIGNyZWF0ZWQKLy8KLy8gUmV0dXJuczoKLy8gICAtIHN0YWtlci5EZWxlZ2F0aW9uV2l0aGRyYXc6IG5ldyB3aXRoZHJhd2FsIGluc3RhbmNlIHRoYXQgaXMgaW1tZWRpYXRlbHkgY29sbGVjdGFibGUKZnVuYyBOZXdEZWxlZ2F0aW9uV2l0aGRyYXdXaXRob3V0TG9ja3VwKAoJZGVsZWdhdGlvbklELAoJdW5EZWxlZ2F0ZUFtb3VudCwKCWNyZWF0ZWRIZWlnaHQsCgljcmVhdGVkQXQgaW50NjQsCikgc3Rha2VyLkRlbGVnYXRpb25XaXRoZHJhdyB7CglyZXR1cm4gc3Rha2VyLk5ld0RlbGVnYXRpb25XaXRoZHJhd1dpdGhvdXRMb2NrdXAoCgkJZGVsZWdhdGlvbklELAoJCXVuRGVsZWdhdGVBbW91bnQsCgkJY3JlYXRlZEhlaWdodCwKCQljcmVhdGVkQXQsCgkpCn0KGrUCCgdkb2MuZ25vEqkCLy8gUGFja2FnZSB2MSBtYW5hZ2VzIEdOUyBkZWxlZ2F0aW9uIGFuZCB4R05TIGFjY291bnRpbmcuCi8vIEl0IG1haW50YWlucyB0aW1lc3RhbXBlZCBkZWxlZ2F0aW9uIGhpc3RvcnksIGRpc3RyaWJ1dGVzIEdOUyBlbWlzc2lvbiBhbmQKLy8gcHJvdG9jb2wtZmVlIHJld2FyZHMsIGFuZCBlbmZvcmNlcyBhIGNvbmZpZ3VyYWJsZSB1bmRlbGVnYXRpb24gbG9ja3VwCi8vICg3IGRheXMgYnkgZGVmYXVsdDsgeEdOUyBpcyBidXJuZWQgd2hlbiB1bmRlbGVnYXRlZCBHTlMgaXMgY29sbGVjdGVkKS4KcGFja2FnZSBzdGFrZXIKGok/ChtlbWlzc2lvbl9yZXdhcmRfbWFuYWdlci5nbm8S6T5wYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCSJlcnJvcnMiCgkibWF0aCIKCglnbnNtYXRoICJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCXUyNTYgImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgoJImduby5sYW5kL3IvZ25vc3dhcC9nb3Yvc3Rha2VyIgopCgp0eXBlIEVtaXNzaW9uUmV3YXJkTWFuYWdlclJlc29sdmVyIHN0cnVjdCB7Cgkqc3Rha2VyLkVtaXNzaW9uUmV3YXJkTWFuYWdlcgp9CgovLyBOZXdFbWlzc2lvblJld2FyZE1hbmFnZXJSZXNvbHZlciB3cmFwcyBhbiBlbWlzc2lvbiByZXdhcmQgbWFuYWdlciB3aXRoIHJld2FyZAovLyBjYWxjdWxhdGlvbiBhbmQgc3Rha2UtYWNjb3VudGluZyBoZWxwZXJzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gZW1pc3Npb25SZXdhcmRNYW5hZ2VyOiBtYW5hZ2VyIHN0YXRlIHRvIHJlc29sdmUgYW5kIG11dGF0ZS4KLy8KLy8gUmV0dXJuczoKLy8gICAtICpFbWlzc2lvblJld2FyZE1hbmFnZXJSZXNvbHZlcjogcmVzb2x2ZXIgYmFja2VkIGJ5IGVtaXNzaW9uUmV3YXJkTWFuYWdlci4KZnVuYyBOZXdFbWlzc2lvblJld2FyZE1hbmFnZXJSZXNvbHZlcihlbWlzc2lvblJld2FyZE1hbmFnZXIgKnN0YWtlci5FbWlzc2lvblJld2FyZE1hbmFnZXIpICpFbWlzc2lvblJld2FyZE1hbmFnZXJSZXNvbHZlciB7CglyZXR1cm4gJkVtaXNzaW9uUmV3YXJkTWFuYWdlclJlc29sdmVye2VtaXNzaW9uUmV3YXJkTWFuYWdlcn0KfQoKLy8gR2V0Q2xhaW1hYmxlUmV3YXJkQW1vdW50IGNhbGN1bGF0ZXMgdGhlIGNsYWltYWJsZSByZXdhcmQgYW1vdW50IGZvciBhIHNwZWNpZmljIGFkZHJlc3MuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBjdXJyZW50RGlzdHJpYnV0ZWRBbW91bnQ6IHRvdGFsIGVtaXNzaW9uIGFtb3VudCBkaXN0cmlidXRlZCB0byB0aGUgc3Rha2VyCi8vICAgICBtYW5hZ2VyIGF0IHRoZSBjdXJyZW50IG9ic2VydmF0aW9uIHBvaW50LgovLyAgIC0gYWRkcmVzczogcmV3YXJkLXN0YXRlIGlkZW50aWZpZXIgd2hvc2UgY2xhaW1hYmxlIGFtb3VudCBpcyByZXF1ZXN0ZWQuCi8vICAgLSBjdXJyZW50VGltZXN0YW1wOiBVbml4IHRpbWVzdGFtcCB1c2VkIHRvIHNldHRsZSB0aGUgYWRkcmVzcydzIHJld2FyZCBzdGF0ZS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBlbWlzc2lvbiByZXdhcmQgY3VycmVudGx5IGNsYWltYWJsZSBieSBhZGRyZXNzLCBvciB6ZXJvIHdoZW4gbm8KLy8gICAgIHJld2FyZCBzdGF0ZSBleGlzdHMuCi8vICAgLSBlcnJvcjogbmlsIG9uIHN1Y2Nlc3M7IGFuIGVycm9yIGZyb20gYWNjdW11bGF0ZWQtcmV3YXJkIG9yIHJld2FyZC1zdGF0ZQovLyAgICAgcmVzb2x1dGlvbiB3aGVuIGNhbGN1bGF0aW9uIGZhaWxzLgpmdW5jIChzZWxmICpFbWlzc2lvblJld2FyZE1hbmFnZXJSZXNvbHZlcikgR2V0Q2xhaW1hYmxlUmV3YXJkQW1vdW50KAoJY3VycmVudERpc3RyaWJ1dGVkQW1vdW50IGludDY0LAoJYWRkcmVzcyBzdHJpbmcsCgljdXJyZW50VGltZXN0YW1wIGludDY0LAopIChpbnQ2NCwgZXJyb3IpIHsKCXJld2FyZFN0YXRlLCBvaywgZXJyIDo9IHNlbGYuR2V0UmV3YXJkU3RhdGUoYWRkcmVzcykKCWlmICFvayB7CgkJcmV0dXJuIDAsIG5pbAoJfQoKCWFjY3VtdWxhdGVkUmV3YXJkWDEyOFBlclN0YWtlLCBlcnIgOj0gc2VsZi5jYWxjdWxhdGVBY2N1bXVsYXRlZFJld2FyZFgxMjhQZXJTdGFrZSgKCQljdXJyZW50RGlzdHJpYnV0ZWRBbW91bnQsCgkJY3VycmVudFRpbWVzdGFtcCwKCSkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCglyZXNvbHZlZFN0YXRlIDo9IE5ld0VtaXNzaW9uUmV3YXJkU3RhdGVSZXNvbHZlcihyZXdhcmRTdGF0ZSkKCXJldHVybiByZXNvbHZlZFN0YXRlLkdldENsYWltYWJsZVJld2FyZEFtb3VudChhY2N1bXVsYXRlZFJld2FyZFgxMjhQZXJTdGFrZSwgY3VycmVudFRpbWVzdGFtcCkKfQoKLy8gY2FsY3VsYXRlQWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UgY2FsY3VsYXRlcyB0aGUgdXBkYXRlZCBhY2N1bXVsYXRlZCByZXdhcmQgcGVyIHN0YWtlLgpmdW5jIChzZWxmICpFbWlzc2lvblJld2FyZE1hbmFnZXJSZXNvbHZlcikgY2FsY3VsYXRlQWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UoCgljdXJyZW50RGlzdHJpYnV0ZWRBbW91bnQgaW50NjQsCgljdXJyZW50VGltZXN0YW1wIGludDY0LAopICgqdTI1Ni5VaW50LCBlcnJvcikgewoJLy8gSWYgd2UncmUgbG9va2luZyBhdCBhIHBhc3QgdGltZXN0YW1wLCByZXR1cm4gY3VycmVudCBzdGF0ZQoJaWYgY3VycmVudFRpbWVzdGFtcCA8IHNlbGYuR2V0QWNjdW11bGF0ZWRUaW1lc3RhbXAoKSB7CgkJcmV0dXJuIHNlbGYuR2V0QWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UoKSwgbmlsCgl9CgoJLy8gV2l0aCBubyBzdGFrZSB0aGVyZSBpcyBub2JvZHkgdG8gY3JlZGl0LCBzbyB0aGUgZGVsdGEgYWNjcnVlZCBvdmVyIHRoYXQgd2luZG93IGlzCgkvLyBkcm9wcGVkIGFuZCB0aGUgY2FsbGVyIGFkdmFuY2VzIHRoZSBjdXJzb3IgcGFzdCBpdC4gVGhlIHByb3RvY29sIGZlZSBhY2N1bXVsYXRvcgoJLy8gYXBwbGllcyB0aGUgc2FtZSBwb2xpY3ksIHNlZSBQcm90b2NvbEZlZVJld2FyZE1hbmFnZXJSZXNvbHZlci4KCXRvdGFsU3Rha2VkQW1vdW50IDo9IHNlbGYuR2V0VG90YWxTdGFrZWRBbW91bnQoKQoJaWYgdG90YWxTdGFrZWRBbW91bnQgPT0gMCB7CgkJcmV0dXJuIHNlbGYuR2V0QWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UoKSwgbmlsCgl9CgoJLy8gTmV3bHkgZGlzdHJpYnV0ZWQgcmV3YXJkcyBzaW5jZSBsYXN0IHVwZGF0ZQoJZGlzdHJpYnV0ZWRBbW91bnREZWx0YSA6PSBnbnNtYXRoLlNhZmVTdWJJbnQ2NChjdXJyZW50RGlzdHJpYnV0ZWRBbW91bnQsIHNlbGYuR2V0RGlzdHJpYnV0ZWRBbW91bnQoKSkKCWlmIGRpc3RyaWJ1dGVkQW1vdW50RGVsdGEgPD0gMCB7CgkJLy8gTm9uLXBvc2l0aXZlIGRlbHRhLiBub3RoaW5nIHRvIGRvIG1vcmUuCgkJcmV0dXJuIHNlbGYuR2V0QWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UoKSwgbmlsCgl9CgoJLy8gUmV3YXJkIHBlciBzdGFrZSBmb3IgdGhlIG5ldyBkaXN0cmlidXRpb24KCWRpc3RyaWJ1dGVkQW1vdW50RGVsdGFYMTI4UGVyU3Rha2UgOj0gdTI1Ni5aZXJvKCkuRGl2KAoJCXUyNTYuWmVybygpLkxzaCh1MjU2Lk5ld1VpbnRGcm9tSW50NjQoZGlzdHJpYnV0ZWRBbW91bnREZWx0YSksIDEyOCksCgkJdTI1Ni5OZXdVaW50RnJvbUludDY0KHRvdGFsU3Rha2VkQW1vdW50KSwKCSkKCgkvLyBBZGQgdG8gYWNjdW11bGF0ZWQgcmV3YXJkIHBlciBzdGFrZQoJYWNjdW11bGF0ZWRSZXdhcmQgOj0gdTI1Ni5aZXJvKCkuQWRkKHNlbGYuR2V0QWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UoKSwgZGlzdHJpYnV0ZWRBbW91bnREZWx0YVgxMjhQZXJTdGFrZSkKCXJldHVybiBhY2N1bXVsYXRlZFJld2FyZCwgbmlsCn0KCi8vIHVwZGF0ZUFjY3VtdWxhdGVkUmV3YXJkWDEyOFBlclN0YWtlIHVwZGF0ZXMgdGhlIGludGVybmFsIGFjY3VtdWxhdGVkIHJld2FyZCBzdGF0ZS4KLy8gVGhpcyBtZXRob2Qgc2hvdWxkIGJlIGNhbGxlZCBiZWZvcmUgYW55IHN0YWtlIGNoYW5nZXMgdG8gZW5zdXJlIGFjY3VyYXRlIHJld2FyZCBjYWxjdWxhdGlvbnMuCi8vIFVwZGF0ZXMgYWNjdW11bGF0ZWQgcmV3YXJkIHBlciBzdGFrZSB3aXRoIGN1cnJlbnQgZGlzdHJpYnV0aW9uIGRhdGEuCmZ1bmMgKHNlbGYgKkVtaXNzaW9uUmV3YXJkTWFuYWdlclJlc29sdmVyKSB1cGRhdGVBY2N1bXVsYXRlZFJld2FyZFgxMjhQZXJTdGFrZSgKCWN1cnJlbnREaXN0cmlidXRlZEFtb3VudCBpbnQ2NCwKCWN1cnJlbnRUaW1lc3RhbXAgaW50NjQsCikgZXJyb3IgewoJLy8gRE8gTk9UIGFwcGx5IG91dC1vZi1vcmRlciB0aW1lc3RhbXBzCglpZiBjdXJyZW50VGltZXN0YW1wIDwgc2VsZi5HZXRBY2N1bXVsYXRlZFRpbWVzdGFtcCgpIHsKCQlyZXR1cm4gbmlsCgl9CgoJLy8gVXBkYXRlIGFjY3VtdWxhdGVkIHJld2FyZCBzdGF0ZQoJYWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UsIGVyciA6PSBzZWxmLmNhbGN1bGF0ZUFjY3VtdWxhdGVkUmV3YXJkWDEyOFBlclN0YWtlKAoJCWN1cnJlbnREaXN0cmlidXRlZEFtb3VudCwKCQljdXJyZW50VGltZXN0YW1wLAoJKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCXNlbGYuc2V0QWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UoYWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UuQ2xvbmUoKSkKCXNlbGYuc2V0RGlzdHJpYnV0ZWRBbW91bnQoY3VycmVudERpc3RyaWJ1dGVkQW1vdW50KQoJc2VsZi5zZXRBY2N1bXVsYXRlZFRpbWVzdGFtcChjdXJyZW50VGltZXN0YW1wKQoKCXJldHVybiBuaWwKfQoKLy8gYWRkU3Rha2UgYWRkcyBhIHN0YWtlIGZvciBhbiBhZGRyZXNzIGFuZCB1cGRhdGVzIHRoZWlyIHJld2FyZCBzdGF0ZS4KLy8gVGhpcyBtZXRob2QgZW5zdXJlcyByZXdhcmRzIGFyZSBwcm9wZXJseSBjYWxjdWxhdGVkIGJlZm9yZSB0aGUgc3Rha2UgY2hhbmdlLgovLyBBZGRzIHN0YWtlIGZvciBzcGVjaWZpZWQgYWRkcmVzcyBhbmQgdXBkYXRlcyByZXdhcmQgY2FsY3VsYXRpb25zLgpmdW5jIChzZWxmICpFbWlzc2lvblJld2FyZE1hbmFnZXJSZXNvbHZlcikgYWRkU3Rha2UoYWRkcmVzcyBzdHJpbmcsIGFtb3VudCBpbnQ2NCwgY3VycmVudFRpbWVzdGFtcCBpbnQ2NCkgZXJyb3IgewoJaWYgYW1vdW50IDwgMCB7CgkJcmV0dXJuIGVycm9ycy5OZXcoZXJyQW1vdW50TXVzdEJlTm9uTmVnYXRpdmUpCgl9CgoJYWNjdW11bGF0ZWRSZXdhcmQgOj0gc2VsZi5HZXRBY2N1bXVsYXRlZFJld2FyZFgxMjhQZXJTdGFrZSgpCgoJcmV3YXJkU3RhdGUsIG9rLCBlcnIgOj0gc2VsZi5HZXRSZXdhcmRTdGF0ZShhZGRyZXNzKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoJaWYgIW9rIHsKCQlyZXdhcmRTdGF0ZSA9IHN0YWtlci5OZXdFbWlzc2lvblJld2FyZFN0YXRlKGFjY3VtdWxhdGVkUmV3YXJkKQoJfQoKCXJlc29sdmVkU3RhdGUgOj0gTmV3RW1pc3Npb25SZXdhcmRTdGF0ZVJlc29sdmVyKHJld2FyZFN0YXRlKQoJZXJyID0gcmVzb2x2ZWRTdGF0ZS5hZGRTdGFrZVdpdGhVcGRhdGVSZXdhcmREZWJ0WDEyOChhbW91bnQsIGFjY3VtdWxhdGVkUmV3YXJkLCBjdXJyZW50VGltZXN0YW1wKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCXNlbGYuc2V0UmV3YXJkU3RhdGVzKGFkZHJlc3MsIHJld2FyZFN0YXRlKQoKCWN1cnJlbnRUb3RhbCA6PSBzZWxmLkdldFRvdGFsU3Rha2VkQW1vdW50KCkKCWlmIGFtb3VudCA+IDAgJiYgY3VycmVudFRvdGFsID4gbWF0aC5NYXhJbnQ2NC1hbW91bnQgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyclRvdGFsU3Rha2VkQW1vdW50T3ZlcmZsb3cpCgl9CglzZWxmLlNldFRvdGFsU3Rha2VkQW1vdW50KGduc21hdGguU2FmZUFkZEludDY0KGN1cnJlbnRUb3RhbCwgYW1vdW50KSkKCXJldHVybiBuaWwKfQoKLy8gcmVtb3ZlU3Rha2UgcmVtb3ZlcyBhIHN0YWtlIGZvciBhbiBhZGRyZXNzIGFuZCB1cGRhdGVzIHRoZWlyIHJld2FyZCBzdGF0ZS4KLy8gVGhpcyBtZXRob2QgZW5zdXJlcyByZXdhcmRzIGFyZSBwcm9wZXJseSBjYWxjdWxhdGVkIGJlZm9yZSB0aGUgc3Rha2UgY2hhbmdlLgovLyBSZW1vdmVzIHN0YWtlIGZvciBzcGVjaWZpZWQgYWRkcmVzcyBhbmQgdXBkYXRlcyByZXdhcmQgY2FsY3VsYXRpb25zLgpmdW5jIChzZWxmICpFbWlzc2lvblJld2FyZE1hbmFnZXJSZXNvbHZlcikgcmVtb3ZlU3Rha2UoYWRkcmVzcyBzdHJpbmcsIGFtb3VudCBpbnQ2NCwgY3VycmVudFRpbWVzdGFtcCBpbnQ2NCkgZXJyb3IgewoJaWYgYW1vdW50IDwgMCB7CgkJcmV0dXJuIGVycm9ycy5OZXcoZXJyQW1vdW50TXVzdEJlTm9uTmVnYXRpdmUpCgl9CgoJdXBkYXRlZFRvdGFsU3Rha2VkQW1vdW50IDo9IGduc21hdGguU2FmZVN1YkludDY0KHNlbGYuR2V0VG90YWxTdGFrZWRBbW91bnQoKSwgYW1vdW50KQoJaWYgdXBkYXRlZFRvdGFsU3Rha2VkQW1vdW50IDwgMCB7CgkJcmV0dXJuIGVycm9ycy5OZXcoZXJyUmVtb3ZlQW1vdW50RXhjZWVkc1RvdGFsU3Rha2VkKQoJfQoKCWFjY3VtdWxhdGVkUmV3YXJkIDo9IHNlbGYuR2V0QWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UoKQoKCXJld2FyZFN0YXRlLCBvaywgZXJyIDo9IHNlbGYuR2V0UmV3YXJkU3RhdGUoYWRkcmVzcykKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCWlmICFvayB7CgkJcmV3YXJkU3RhdGUgPSBzdGFrZXIuTmV3RW1pc3Npb25SZXdhcmRTdGF0ZShhY2N1bXVsYXRlZFJld2FyZCkKCX0KCglyZXNvbHZlZFN0YXRlIDo9IE5ld0VtaXNzaW9uUmV3YXJkU3RhdGVSZXNvbHZlcihyZXdhcmRTdGF0ZSkKCgllcnIgPSByZXNvbHZlZFN0YXRlLnJlbW92ZVN0YWtlV2l0aFVwZGF0ZVJld2FyZERlYnRYMTI4KGFtb3VudCwgYWNjdW11bGF0ZWRSZXdhcmQsIGN1cnJlbnRUaW1lc3RhbXApCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJLy8gcGVyc2lzdCB1cGRhdGVkIHN0YXRlCglzZWxmLnNldFJld2FyZFN0YXRlcyhhZGRyZXNzLCByZXdhcmRTdGF0ZSkKCglzZWxmLlNldFRvdGFsU3Rha2VkQW1vdW50KHVwZGF0ZWRUb3RhbFN0YWtlZEFtb3VudCkKCglyZXR1cm4gbmlsCn0KCi8vIGNsYWltUmV3YXJkcyBwcm9jZXNzZXMgcmV3YXJkIGNsYWltaW5nIGZvciBhbiBhZGRyZXNzLgovLyBUaGlzIG1ldGhvZCBjYWxjdWxhdGVzIGFuZCByZXR1cm5zIHRoZSBhbW91bnQgb2YgcmV3YXJkcyBjbGFpbWVkLgovLyBDbGFpbXMgYXZhaWxhYmxlIHJld2FyZHMgZm9yIHNwZWNpZmllZCBhZGRyZXNzLgpmdW5jIChzZWxmICpFbWlzc2lvblJld2FyZE1hbmFnZXJSZXNvbHZlcikgY2xhaW1SZXdhcmRzKGFkZHJlc3Mgc3RyaW5nLCBjdXJyZW50VGltZXN0YW1wIGludDY0KSAoY2xhaW1lZFJld2FyZEFtb3VudCBpbnQ2NCwgZXJyIGVycm9yKSB7CglyZXdhcmRTdGF0ZSwgb2ssIGVyciA6PSBzZWxmLkdldFJld2FyZFN0YXRlKGFkZHJlc3MpCglpZiBlcnIgIT0gbmlsIHx8ICFvayB7CgkJcmV0dXJuIDAsIGVycgoJfQoKCXJlc29sdmVkU3RhdGUgOj0gTmV3RW1pc3Npb25SZXdhcmRTdGF0ZVJlc29sdmVyKHJld2FyZFN0YXRlKQoJY2xhaW1lZFJld2FyZEFtb3VudCwgY0VyciA6PSByZXNvbHZlZFN0YXRlLmNsYWltUmV3YXJkc1dpdGhVcGRhdGVSZXdhcmREZWJ0WDEyOChzZWxmLkdldEFjY3VtdWxhdGVkUmV3YXJkWDEyOFBlclN0YWtlKCksIGN1cnJlbnRUaW1lc3RhbXApCglpZiBjRXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGNFcnIKCX0KCglzZWxmLnNldFJld2FyZFN0YXRlcyhhZGRyZXNzLCByZXdhcmRTdGF0ZSkKCXJldHVybiBjbGFpbWVkUmV3YXJkQW1vdW50LCBuaWwKfQoKZnVuYyAoc2VsZiAqRW1pc3Npb25SZXdhcmRNYW5hZ2VyUmVzb2x2ZXIpIHNldFJld2FyZFN0YXRlcyhhZGRyZXNzIHN0cmluZywgcmV3YXJkU3RhdGUgKnN0YWtlci5FbWlzc2lvblJld2FyZFN0YXRlKSB7CglzZWxmLlNldFJld2FyZFN0YXRlKGFkZHJlc3MsIHJld2FyZFN0YXRlKQp9CgpmdW5jIChzZWxmICpFbWlzc2lvblJld2FyZE1hbmFnZXJSZXNvbHZlcikgc2V0QWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UoYWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UgKnUyNTYuVWludCkgewoJc2VsZi5TZXRBY2N1bXVsYXRlZFJld2FyZFgxMjhQZXJTdGFrZShhY2N1bXVsYXRlZFJld2FyZFgxMjhQZXJTdGFrZSkKfQoKZnVuYyAoc2VsZiAqRW1pc3Npb25SZXdhcmRNYW5hZ2VyUmVzb2x2ZXIpIHNldERpc3RyaWJ1dGVkQW1vdW50KGRpc3RyaWJ1dGVkQW1vdW50IGludDY0KSB7CglzZWxmLlNldERpc3RyaWJ1dGVkQW1vdW50KGRpc3RyaWJ1dGVkQW1vdW50KQp9CgpmdW5jIChzZWxmICpFbWlzc2lvblJld2FyZE1hbmFnZXJSZXNvbHZlcikgc2V0QWNjdW11bGF0ZWRUaW1lc3RhbXAoYWNjdW11bGF0ZWRUaW1lc3RhbXAgaW50NjQpIHsKCXNlbGYuU2V0QWNjdW11bGF0ZWRUaW1lc3RhbXAoYWNjdW11bGF0ZWRUaW1lc3RhbXApCn0KGrZDChllbWlzc2lvbl9yZXdhcmRfc3RhdGUuZ25vEphDcGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkiZXJyb3JzIgoKCSJnbm8ubGFuZC9wL2dub3N3YXAvY29uc3RzL3YxIgoJZ25zbWF0aCAiZ25vLmxhbmQvcC9nbm9zd2FwL2duc21hdGgvdjEiCgl1MjU2ICJnbm8ubGFuZC9wL2dub3N3YXAvdWludDI1Ni92MSIKCSJnbm8ubGFuZC9yL2dub3N3YXAvZ292L3N0YWtlciIKKQoKdHlwZSBFbWlzc2lvblJld2FyZFN0YXRlUmVzb2x2ZXIgc3RydWN0IHsKCSpzdGFrZXIuRW1pc3Npb25SZXdhcmRTdGF0ZQp9CgovLyBOZXdFbWlzc2lvblJld2FyZFN0YXRlUmVzb2x2ZXIgd3JhcHMgYW4gb24tY2hhaW4gZW1pc3Npb24gcmV3YXJkIHN0YXRlIGZvcgovLyByZXdhcmQgY2FsY3VsYXRpb24gYW5kIHN0YWtlL2NsYWltIHVwZGF0ZXMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBlbWlzc2lvblJld2FyZFN0YXRlOiBwZXJzaXN0ZWQgcmV3YXJkIHN0YXRlIHRvIGV4cG9zZSB0aHJvdWdoIHRoZSByZXNvbHZlcgovLwovLyBSZXR1cm5zOgovLyAgIC0gKkVtaXNzaW9uUmV3YXJkU3RhdGVSZXNvbHZlcjogcmVzb2x2ZXIgYmFja2VkIGJ5IGVtaXNzaW9uUmV3YXJkU3RhdGUKZnVuYyBOZXdFbWlzc2lvblJld2FyZFN0YXRlUmVzb2x2ZXIoZW1pc3Npb25SZXdhcmRTdGF0ZSAqc3Rha2VyLkVtaXNzaW9uUmV3YXJkU3RhdGUpICpFbWlzc2lvblJld2FyZFN0YXRlUmVzb2x2ZXIgewoJcmV0dXJuICZFbWlzc2lvblJld2FyZFN0YXRlUmVzb2x2ZXJ7ZW1pc3Npb25SZXdhcmRTdGF0ZX0KfQoKLy8gSXNDbGFpbWFibGUgY2hlY2tzIGlmIHJld2FyZHMgY2FuIGJlIGNsYWltZWQgYXQgdGhlIGdpdmVuIHRpbWVzdGFtcC4KLy8gUmV3YXJkcyBhcmUgY2xhaW1hYmxlIG9ubHkgd2hlbiBjdXJyZW50VGltZXN0YW1wIGlzIGxhdGVyIHRoYW4gdGhlIHN0b3JlZAovLyBjbGFpbWVkIHRpbWVzdGFtcC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnRUaW1lc3RhbXA6IHRpbWVzdGFtcCBhdCB3aGljaCBjbGFpbWFiaWxpdHkgaXMgZXZhbHVhdGVkCi8vCi8vIFJldHVybnM6Ci8vICAgLSBib29sOiB0cnVlIHdoZW4gY3VycmVudFRpbWVzdGFtcCBpcyBncmVhdGVyIHRoYW4gdGhlIGxhc3QgY2xhaW1lZCB0aW1lc3RhbXAKZnVuYyAoc2VsZiAqRW1pc3Npb25SZXdhcmRTdGF0ZVJlc29sdmVyKSBJc0NsYWltYWJsZShjdXJyZW50VGltZXN0YW1wIGludDY0KSBib29sIHsKCXJldHVybiBzZWxmLkdldENsYWltZWRUaW1lc3RhbXAoKSA8IGN1cnJlbnRUaW1lc3RhbXAKfQoKLy8gR2V0Q2xhaW1hYmxlUmV3YXJkQW1vdW50IGNhbGN1bGF0ZXMgdGhlIHRvdGFsIGFtb3VudCBvZiByZXdhcmRzIHRoYXQgY2FuIGJlIGNsYWltZWQuCi8vIEl0IGNvbWJpbmVzIG5ld2x5IGVhcm5lZCByZXdhcmRzIHdpdGggYWNjdW11bGF0ZWQgcmV3YXJkcyBub3QgeWV0IGNsYWltZWQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBhY2N1bXVsYXRlZFJld2FyZFgxMjhQZXJTdGFrZTogc3lzdGVtLXdpZGUgYWNjdW11bGF0ZWQgcmV3YXJkIHBlciBzdGFrZSwgc2NhbGVkIGJ5IDJeMTI4Ci8vICAgLSBjdXJyZW50VGltZXN0YW1wOiB0aW1lc3RhbXAgdGhyb3VnaCB3aGljaCBuZXdseSBlYXJuZWQgcmV3YXJkcyBhcmUgY2FsY3VsYXRlZAovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IHRvdGFsIGNsYWltYWJsZSBhbW91bnQsIGluY2x1ZGluZyBhY2N1bXVsYXRlZC1idXQtdW5jbGFpbWVkIGFuZCBuZXdseSBlYXJuZWQgcmV3YXJkcwovLyAgIC0gZXJyb3I6IG5pbCBvbiBzdWNjZXNzOyBhbiBlcnJvciBwcm9wYWdhdGVkIGZyb20gcmV3YXJkIGNhbGN1bGF0aW9uIG90aGVyd2lzZQpmdW5jIChzZWxmICpFbWlzc2lvblJld2FyZFN0YXRlUmVzb2x2ZXIpIEdldENsYWltYWJsZVJld2FyZEFtb3VudCgKCWFjY3VtdWxhdGVkUmV3YXJkWDEyOFBlclN0YWtlICp1MjU2LlVpbnQsCgljdXJyZW50VGltZXN0YW1wIGludDY0LAopIChpbnQ2NCwgZXJyb3IpIHsKCXJld2FyZEFtb3VudCwgZXJyIDo9IHNlbGYuY2FsY3VsYXRlQ2xhaW1hYmxlUmV3YXJkcyhhY2N1bXVsYXRlZFJld2FyZFgxMjhQZXJTdGFrZSwgY3VycmVudFRpbWVzdGFtcCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCglhY2N1bXVsYXRlZFVuY2xhaW1lZFJld2FyZCA6PSBnbnNtYXRoLlNhZmVTdWJJbnQ2NCgKCQlzZWxmLkdldEFjY3VtdWxhdGVkUmV3YXJkQW1vdW50KCksCgkJc2VsZi5HZXRDbGFpbWVkUmV3YXJkQW1vdW50KCksCgkpCgoJcmV0dXJuIGduc21hdGguU2FmZUFkZEludDY0KGFjY3VtdWxhdGVkVW5jbGFpbWVkUmV3YXJkLCByZXdhcmRBbW91bnQpLCBuaWwKfQoKLy8gY2FsY3VsYXRlQ2xhaW1hYmxlUmV3YXJkcyBjYWxjdWxhdGVzIG5ld2x5IGVhcm5lZCByZXdhcmRzIHNpbmNlIHRoZSBsYXN0IHVwZGF0ZS4KLy8gVXNlcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGN1cnJlbnQgYW5kIHN0b3JlZCByZXdhcmQgZGVidCB0byBjYWxjdWxhdGUgZWFybmluZ3MuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBhY2N1bXVsYXRlZFJld2FyZFgxMjhQZXJTdGFrZTogY3VycmVudCBzeXN0ZW0td2lkZSBhY2N1bXVsYXRlZCByZXdhcmQgcGVyIHN0YWtlCi8vICAgLSBjdXJyZW50VGltZXN0YW1wOiBjdXJyZW50IHRpbWVzdGFtcAovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IG5ld2x5IGVhcm5lZCByZXdhcmQgYW1vdW50IHNpbmNlIGxhc3QgdXBkYXRlCi8vICAgLSBlcnJvcjogbmlsIG9uIHN1Y2Nlc3MsIGVycm9yIGlmIGNhbGN1bGF0aW9uIGZhaWxzCmZ1bmMgKHNlbGYgKkVtaXNzaW9uUmV3YXJkU3RhdGVSZXNvbHZlcikgY2FsY3VsYXRlQ2xhaW1hYmxlUmV3YXJkcygKCWFjY3VtdWxhdGVkUmV3YXJkWDEyOFBlclN0YWtlICp1MjU2LlVpbnQsCgljdXJyZW50VGltZXN0YW1wIGludDY0LAopIChpbnQ2NCwgZXJyb3IpIHsKCXN0YWtlZEFtb3VudCA6PSBzZWxmLkdldFN0YWtlZEFtb3VudCgpCgoJLy8gRG9uJ3QgY2FsY3VsYXRlIHJld2FyZHMgZm9yIHBhc3QgdGltZXN0YW1wcyBvciB3aGVuIG5vdGhpbmcgaXMgc3Rha2VkCglpZiBjdXJyZW50VGltZXN0YW1wIDwgc2VsZi5HZXRBY2N1bXVsYXRlZFRpbWVzdGFtcCgpIHx8IHN0YWtlZEFtb3VudCA9PSAwIHsKCQlyZXR1cm4gMCwgbmlsCgl9CgoJLy8gQ2FsY3VsYXRlIHRoZSBkaWZmZXJlbmNlIGluIGFjY3VtdWxhdGVkIHJld2FyZHMgcGVyIHN0YWtlIHNpbmNlIGxhc3QgdXBkYXRlCgkvLyBVc2luZyBtb2R1bGFyIGFyaXRobWV0aWMgZm9yIGFjY3VtdWxhdG9yIHZhbHVlcyAtIHVuZGVyZmxvdyBpcyBhbGxvd2VkIGFuZCBoYW5kbGVkIGNvcnJlY3RseQoJcmV3YXJkRGVidERlbHRhWDEyOCA6PSB1MjU2Llplcm8oKS5TdWIoCgkJYWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UsCgkJc2VsZi5HZXRSZXdhcmREZWJ0WDEyOCgpLAoJKQoKCS8vIENhbGN1bGF0ZSByZXdhcmQgYW1vdW50IGJ5IG11bHRpcGx5aW5nIHJld2FyZCBkZWJ0IGRlbHRhIGJ5IHN0YWtlZCBhbW91bnQgYW5kIGRpdmlkaW5nIGJ5IFExMjgKCS8vIHJld2FyZEFtb3VudCA9IChyZXdhcmREZWJ0RGVsdGFYMTI4ICogc3Rha2VkQW1vdW50KSAvIFExMjgKCXJld2FyZEFtb3VudCA6PSB1MjU2Lk11bERpdigKCQlyZXdhcmREZWJ0RGVsdGFYMTI4LAoJCXUyNTYuTmV3VWludEZyb21JbnQ2NChzdGFrZWRBbW91bnQpLAoJCWNvbnN0cy5RMTI4KCksCgkpCglyZXR1cm4gZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQocmV3YXJkQW1vdW50KSwgbmlsCn0KCi8vIGFkZFN0YWtlIGluY3JlYXNlcyB0aGUgc3Rha2VkIGFtb3VudCBmb3IgdGhpcyBhZGRyZXNzLgovLyBUaGlzIG1ldGhvZCBzaG91bGQgYmUgY2FsbGVkIHdoZW4gYSB1c2VyIGluY3JlYXNlcyB0aGVpciBzdGFrZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGFtb3VudDogYW1vdW50IG9mIHN0YWtlIHRvIGFkZApmdW5jIChzZWxmICpFbWlzc2lvblJld2FyZFN0YXRlUmVzb2x2ZXIpIGFkZFN0YWtlKGFtb3VudCBpbnQ2NCkgZXJyb3IgewoJaWYgYW1vdW50IDwgMCB7CgkJcmV0dXJuIGVycm9ycy5OZXcoZXJyQW1vdW50TXVzdEJlTm9uTmVnYXRpdmUpCgl9CglzZWxmLlNldFN0YWtlZEFtb3VudChnbnNtYXRoLlNhZmVBZGRJbnQ2NChzZWxmLkdldFN0YWtlZEFtb3VudCgpLCBhbW91bnQpKQoJcmV0dXJuIG5pbAp9CgovLyByZW1vdmVTdGFrZSBkZWNyZWFzZXMgdGhlIHN0YWtlZCBhbW91bnQgZm9yIHRoaXMgYWRkcmVzcy4KLy8gVGhpcyBtZXRob2Qgc2hvdWxkIGJlIGNhbGxlZCB3aGVuIGEgdXNlciBkZWNyZWFzZXMgdGhlaXIgc3Rha2UuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBhbW91bnQ6IGFtb3VudCBvZiBzdGFrZSB0byByZW1vdmUKZnVuYyAoc2VsZiAqRW1pc3Npb25SZXdhcmRTdGF0ZVJlc29sdmVyKSByZW1vdmVTdGFrZShhbW91bnQgaW50NjQpIGVycm9yIHsKCWlmIGFtb3VudCA8IDAgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyckFtb3VudE11c3RCZU5vbk5lZ2F0aXZlKQoJfQoJaWYgYW1vdW50ID4gc2VsZi5HZXRTdGFrZWRBbW91bnQoKSB7CgkJcmV0dXJuIGVycm9ycy5OZXcoZXJyUmVtb3ZlQW1vdW50RXhjZWVkc1N0YWtlZCkKCX0KCXNlbGYuU2V0U3Rha2VkQW1vdW50KGduc21hdGguU2FmZVN1YkludDY0KHNlbGYuR2V0U3Rha2VkQW1vdW50KCksIGFtb3VudCkpCglyZXR1cm4gbmlsCn0KCi8vIGNsYWltUmV3YXJkcyBwcm9jZXNzZXMgcmV3YXJkIGNsYWltaW5nIGFuZCB1cGRhdGVzIHRoZSBjbGFpbSBzdGF0ZS4KLy8gVGhpcyBtZXRob2QgdmFsaWRhdGVzIGNsYWltYWJpbGl0eSBhbmQgdHJhbnNmZXJzIGFjY3VtdWxhdGVkIHJld2FyZHMgdG8gY2xhaW1lZCBzdGF0dXMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBjdXJyZW50VGltZXN0YW1wOiBjdXJyZW50IHRpbWVzdGFtcAovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IGFtb3VudCBvZiByZXdhcmRzIGNsYWltZWQgKDAgaWYgYWxyZWFkeSBjbGFpbWVkIGF0IHRoaXMgdGltZXN0YW1wKQovLyAgIC0gZXJyb3I6IGFsd2F5cyBuaWwgaW4gdGhlIGN1cnJlbnQgaW1wbGVtZW50YXRpb24KZnVuYyAoc2VsZiAqRW1pc3Npb25SZXdhcmRTdGF0ZVJlc29sdmVyKSBjbGFpbVJld2FyZHMoY3VycmVudFRpbWVzdGFtcCBpbnQ2NCkgKGludDY0LCBlcnJvcikgewoJaWYgIXNlbGYuSXNDbGFpbWFibGUoY3VycmVudFRpbWVzdGFtcCkgewoJCXJldHVybiAwLCBuaWwKCX0KCglhY2N1bXVsYXRlZFJld2FyZEFtb3VudCA6PSBzZWxmLkdldEFjY3VtdWxhdGVkUmV3YXJkQW1vdW50KCkKCXByZXZpb3VzQ2xhaW1lZEFtb3VudCA6PSBzZWxmLkdldENsYWltZWRSZXdhcmRBbW91bnQoKQoJY2xhaW1hYmxlQW1vdW50IDo9IGduc21hdGguU2FmZVN1YkludDY0KGFjY3VtdWxhdGVkUmV3YXJkQW1vdW50LCBwcmV2aW91c0NsYWltZWRBbW91bnQpCgoJc2VsZi5TZXRDbGFpbWVkUmV3YXJkQW1vdW50KGFjY3VtdWxhdGVkUmV3YXJkQW1vdW50KQoJc2VsZi5TZXRDbGFpbWVkVGltZXN0YW1wKGN1cnJlbnRUaW1lc3RhbXApCgoJcmV0dXJuIGNsYWltYWJsZUFtb3VudCwgbmlsCn0KCi8vIHVwZGF0ZVJld2FyZERlYnRYMTI4IHVwZGF0ZXMgdGhlIHJld2FyZCBkZWJ0IGFuZCBhY2N1bXVsYXRlcyBuZXcgcmV3YXJkcy4KLy8gVGhpcyBtZXRob2Qgc2hvdWxkIGJlIGNhbGxlZCBiZWZvcmUgYW55IHN0YWtlIGNoYW5nZXMgdG8gZW5zdXJlIGFjY3VyYXRlIHJld2FyZCB0cmFja2luZy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGFjY3VtdWxhdGVkUmV3YXJkWDEyOFBlclN0YWtlOiBjdXJyZW50IHN5c3RlbS13aWRlIGFjY3VtdWxhdGVkIHJld2FyZCBwZXIgc3Rha2UKLy8gICAtIGN1cnJlbnRUaW1lc3RhbXA6IGN1cnJlbnQgdGltZXN0YW1wCmZ1bmMgKHNlbGYgKkVtaXNzaW9uUmV3YXJkU3RhdGVSZXNvbHZlcikgdXBkYXRlUmV3YXJkRGVidFgxMjgoCglhY2N1bXVsYXRlZFJld2FyZFgxMjhQZXJTdGFrZSAqdTI1Ni5VaW50LAoJY3VycmVudFRpbWVzdGFtcCBpbnQ2NCwKKSBlcnJvciB7CglyZXdhcmRBbW91bnQsIGVyciA6PSBzZWxmLmNhbGN1bGF0ZUNsYWltYWJsZVJld2FyZHMoYWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UsIGN1cnJlbnRUaW1lc3RhbXApCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJLy8gQWNjdW11bGF0ZSBuZXdseSBlYXJuZWQgcmV3YXJkcwoJaWYgcmV3YXJkQW1vdW50ICE9IDAgewoJCXNlbGYuU2V0QWNjdW11bGF0ZWRSZXdhcmRBbW91bnQoZ25zbWF0aC5TYWZlQWRkSW50NjQoc2VsZi5HZXRBY2N1bXVsYXRlZFJld2FyZEFtb3VudCgpLCByZXdhcmRBbW91bnQpKQoJfQoKCS8vIERlZXAgY29weSB0byBhdm9pZCBhbGlhc2luZyB3aXRoIGV4dGVybmFsIHN0YXRlCglzZWxmLlNldFJld2FyZERlYnRYMTI4KGFjY3VtdWxhdGVkUmV3YXJkWDEyOFBlclN0YWtlLkNsb25lKCkpCglzZWxmLlNldEFjY3VtdWxhdGVkVGltZXN0YW1wKGN1cnJlbnRUaW1lc3RhbXApCglyZXR1cm4gbmlsCn0KCi8vIGFkZFN0YWtlV2l0aFVwZGF0ZVJld2FyZERlYnRYMTI4IGFkZHMgc3Rha2UgYW5kIHVwZGF0ZXMgcmV3YXJkIGRlYnQgaW4gb25lIG9wZXJhdGlvbi4KLy8gVGhpcyBlbnN1cmVzIHJld2FyZHMgYXJlIHByb3Blcmx5IGNhbGN1bGF0ZWQgYmVmb3JlIHRoZSBzdGFrZSBjaGFuZ2UgdGFrZXMgZWZmZWN0LgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gYW1vdW50OiBhbW91bnQgb2Ygc3Rha2UgdG8gYWRkCi8vICAgLSBhY2N1bXVsYXRlZFJld2FyZFgxMjhQZXJTdGFrZTogY3VycmVudCBzeXN0ZW0td2lkZSBhY2N1bXVsYXRlZCByZXdhcmQgcGVyIHN0YWtlCi8vICAgLSBjdXJyZW50VGltZXN0YW1wOiBjdXJyZW50IHRpbWVzdGFtcApmdW5jIChzZWxmICpFbWlzc2lvblJld2FyZFN0YXRlUmVzb2x2ZXIpIGFkZFN0YWtlV2l0aFVwZGF0ZVJld2FyZERlYnRYMTI4KAoJYW1vdW50IGludDY0LAoJYWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UgKnUyNTYuVWludCwKCWN1cnJlbnRUaW1lc3RhbXAgaW50NjQsCikgZXJyb3IgewoJaWYgZXJyIDo9IHNlbGYudXBkYXRlUmV3YXJkRGVidFgxMjgoYWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UsIGN1cnJlbnRUaW1lc3RhbXApOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CglyZXR1cm4gc2VsZi5hZGRTdGFrZShhbW91bnQpCn0KCi8vIHJlbW92ZVN0YWtlV2l0aFVwZGF0ZVJld2FyZERlYnRYMTI4IHJlbW92ZXMgc3Rha2UgYW5kIHVwZGF0ZXMgcmV3YXJkIGRlYnQgaW4gb25lIG9wZXJhdGlvbi4KLy8gVGhpcyBlbnN1cmVzIHJld2FyZHMgYXJlIHByb3Blcmx5IGNhbGN1bGF0ZWQgYmVmb3JlIHRoZSBzdGFrZSBjaGFuZ2UgdGFrZXMgZWZmZWN0LgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gYW1vdW50OiBhbW91bnQgb2Ygc3Rha2UgdG8gcmVtb3ZlCi8vICAgLSBhY2N1bXVsYXRlZFJld2FyZFgxMjhQZXJTdGFrZTogY3VycmVudCBzeXN0ZW0td2lkZSBhY2N1bXVsYXRlZCByZXdhcmQgcGVyIHN0YWtlCi8vICAgLSBjdXJyZW50VGltZXN0YW1wOiBjdXJyZW50IHRpbWVzdGFtcApmdW5jIChzZWxmICpFbWlzc2lvblJld2FyZFN0YXRlUmVzb2x2ZXIpIHJlbW92ZVN0YWtlV2l0aFVwZGF0ZVJld2FyZERlYnRYMTI4KAoJYW1vdW50IGludDY0LAoJYWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UgKnUyNTYuVWludCwKCWN1cnJlbnRUaW1lc3RhbXAgaW50NjQsCikgZXJyb3IgewoJaWYgZXJyIDo9IHNlbGYudXBkYXRlUmV3YXJkRGVidFgxMjgoYWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UsIGN1cnJlbnRUaW1lc3RhbXApOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CglyZXR1cm4gc2VsZi5yZW1vdmVTdGFrZShhbW91bnQpCn0KCi8vIGNsYWltUmV3YXJkc1dpdGhVcGRhdGVSZXdhcmREZWJ0WDEyOCBjbGFpbXMgcmV3YXJkcyBhbmQgdXBkYXRlcyByZXdhcmQgZGVidCBpbiBvbmUgb3BlcmF0aW9uLgovLyBUaGlzIGVuc3VyZXMgYWxsIHJld2FyZHMgYXJlIHByb3Blcmx5IGNhbGN1bGF0ZWQgYmVmb3JlIGNsYWltaW5nLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gYWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2U6IGN1cnJlbnQgc3lzdGVtLXdpZGUgYWNjdW11bGF0ZWQgcmV3YXJkIHBlciBzdGFrZQovLyAgIC0gY3VycmVudFRpbWVzdGFtcDogY3VycmVudCB0aW1lc3RhbXAKLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBhbW91bnQgb2YgcmV3YXJkcyBjbGFpbWVkCi8vICAgLSBlcnJvcjogbmlsIG9uIHN1Y2Nlc3MsIGVycm9yIGlmIGNsYWltaW5nIGZhaWxzCmZ1bmMgKHNlbGYgKkVtaXNzaW9uUmV3YXJkU3RhdGVSZXNvbHZlcikgY2xhaW1SZXdhcmRzV2l0aFVwZGF0ZVJld2FyZERlYnRYMTI4KAoJYWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UgKnUyNTYuVWludCwKCWN1cnJlbnRUaW1lc3RhbXAgaW50NjQsCikgKGludDY0LCBlcnJvcikgewoJaWYgZXJyIDo9IHNlbGYudXBkYXRlUmV3YXJkRGVidFgxMjgoYWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UsIGN1cnJlbnRUaW1lc3RhbXApOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CglyZXR1cm4gc2VsZi5jbGFpbVJld2FyZHMoY3VycmVudFRpbWVzdGFtcCkKfQoatxcKCWVtaXRzLmdubxKpF3BhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJImNoYWluIgoKCSJnbm8ubGFuZC9wL2dub3N3YXAvdXRpbHMvdjEiCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9zdGFrZXIiCikKCi8vIGVtaXRVcGRhdGVFbWlzc2lvblJld2FyZEFjY3VtdWxhdGlvbiBlbWl0cyB0aGUgcGVyc2lzdGVkIGdsb2JhbCBlbWlzc2lvbiByZXdhcmQKLy8gYWNjdW11bGF0aW9uIHN0YXRlIHNvIHRoYXQgb2ZmLWNoYWluIGluZGV4ZXJzIGNhbiBjb25zdW1lIHRoZSBhdXRob3JpdGF0aXZlCi8vIGFjY3VtdWxhdG9yIGluc3RlYWQgb2YgcmUtZGVyaXZpbmcgaXQuIEl0IG11c3QgYmUgZW1pdHRlZCBhZnRlciBldmVyeSBwYXRoIHRoYXQKLy8gY2FsbHMgdXBkYXRlQWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UgKGFkZC9yZW1vdmUvY2xhaW0pLCBvdGhlcndpc2UgdGhlCi8vIG9mZi1jaGFpbiBhY2N1bXVsYXRvciBkcmlmdHMgZnJvbSB0aGUgY29udHJhY3QuCi8vCi8vIEFsbCB2YWx1ZXMgYXJlIHJlYWQgZnJvbSB0aGUgbWFuYWdlcidzIHBlcnNpc3RlZCBzdGF0ZSAocG9zdC11cGRhdGUpOgovLyAgIC0gZGlzdHJpYnV0ZWRBbW91bnQgaXMgR2V0RGlzdHJpYnV0ZWRBbW91bnQoKSAodGhlIHN0b3JlZCBiYXNlbGluZSB0aGUgY29udHJhY3QKLy8gICAgIHdpbGwgdXNlIGZvciB0aGUgbmV4dCBkZWx0YSksIG5vdCB0aGUgbGl2ZSBlbWlzc2lvbiBkaXN0cmlidXRpb24gc25hcHNob3QuCi8vICAgLSB0b3RhbFN0YWtlZEFtb3VudCByZWZsZWN0cyB0aGUgY3VycmVudCB0b3RhbCBhZnRlciB0aGUgc3Rha2UgY2hhbmdlIGFuZCBpcyB0aGUKLy8gICAgIGRpdmlzb3IgZm9yIHRoZSBuZXh0IGFjY3VtdWxhdGlvbiBkZWx0YS4KZnVuYyBlbWl0VXBkYXRlRW1pc3Npb25SZXdhcmRBY2N1bXVsYXRpb24obWFuYWdlciAqc3Rha2VyLkVtaXNzaW9uUmV3YXJkTWFuYWdlcikgewoJY2hhaW4uRW1pdCgKCQkiVXBkYXRlRW1pc3Npb25SZXdhcmRBY2N1bXVsYXRpb24iLAoJCSJ0b3RhbFN0YWtlZEFtb3VudCIsIHV0aWxzLkZvcm1hdEludChtYW5hZ2VyLkdldFRvdGFsU3Rha2VkQW1vdW50KCkpLAoJCSJkaXN0cmlidXRlZEFtb3VudCIsIHV0aWxzLkZvcm1hdEludChtYW5hZ2VyLkdldERpc3RyaWJ1dGVkQW1vdW50KCkpLAoJCSJhY2N1bXVsYXRlZFJld2FyZFgxMjhQZXJTdGFrZSIsIG1hbmFnZXIuR2V0QWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UoKS5Ub1N0cmluZygpLAoJCSJhY2N1bXVsYXRlZFRpbWVzdGFtcCIsIHV0aWxzLkZvcm1hdEludChtYW5hZ2VyLkdldEFjY3VtdWxhdGVkVGltZXN0YW1wKCkpLAoJKQp9CgovLyBlbWl0VXBkYXRlUHJvdG9jb2xGZWVTdGFrZUFjY3J1YWwgZW1pdHMgdGhlIGFjY3J1YWwgZXBvY2ggb3BlbmVkIGJ5IGEgc3Rha2UgY2hhbmdlCi8vIHRvZ2V0aGVyIHdpdGggdGhlIHRvdGFsIHN0YWtlIGluIGZvcmNlIGZyb20gaXQsIHNvIHRoYXQgb2ZmLWNoYWluIGluZGV4ZXJzIGNhbgovLyBhdHRyaWJ1dGUgZmVlcyBidWNrZXRlZCB1bmRlciB0aGF0IGVwb2NoIHdpdGhvdXQgcmUtZGVyaXZpbmcgdGhlIHN0YWtlIGhpc3RvcnkuCmZ1bmMgZW1pdFVwZGF0ZVByb3RvY29sRmVlU3Rha2VBY2NydWFsKG1hbmFnZXIgKnN0YWtlci5Qcm90b2NvbEZlZVJld2FyZE1hbmFnZXIpIHsKCWNoYWluLkVtaXQoCgkJIlVwZGF0ZVByb3RvY29sRmVlU3Rha2VBY2NydWFsIiwKCQkiZXBvY2giLCB1dGlscy5Gb3JtYXRJbnQobWFuYWdlci5HZXRDdXJyZW50RXBvY2goKSksCgkJInRvdGFsU3Rha2VkQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KG1hbmFnZXIuR2V0VG90YWxTdGFrZWRBbW91bnQoKSksCgkpCn0KCi8vIGVtaXRVcGRhdGVQcm90b2NvbEZlZVJld2FyZEFjY3VtdWxhdGlvbiBlbWl0cyB0aGUgcGVyc2lzdGVkIGFjY3VtdWxhdGlvbiBzdGF0ZSBvZgovLyBldmVyeSB0b2tlbiB0aGF0IHdhcyBqdXN0IGZvbGRlZC4gTGlrZSB0aGUgZW1pc3Npb24gdmFyaWFudCBpdCBtdXN0IGJlIGVtaXR0ZWQgYWZ0ZXIKLy8gZXZlcnkgcGF0aCB0aGF0IGZvbGRzIGFjY3J1YWwgYnVja2V0cywgb3RoZXJ3aXNlIHRoZSBvZmYtY2hhaW4gYWNjdW11bGF0b3IgZHJpZnRzCi8vIGZyb20gdGhlIGNvbnRyYWN0LgpmdW5jIGVtaXRVcGRhdGVQcm90b2NvbEZlZVJld2FyZEFjY3VtdWxhdGlvbihtYW5hZ2VyICpzdGFrZXIuUHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyLCB0b2tlblBhdGhzIFtdc3RyaW5nKSB7Cglmb3IgXywgdG9rZW5QYXRoIDo9IHJhbmdlIHRva2VuUGF0aHMgewoJCWFjY3VtdWxhdGVkUHJvdG9jb2xGZWVYMTI4UGVyU3Rha2UgOj0gIjAiCgkJZm9sZGVkRXBvY2ggOj0gaW50NjQoLTEpCgkJaWYgYWNjdW11bGF0b3IsIG9rIDo9IG1hbmFnZXIuR2V0VG9rZW5BY2N1bXVsYXRvcih0b2tlblBhdGgpOyBvayB7CgkJCWFjY3VtdWxhdGVkUHJvdG9jb2xGZWVYMTI4UGVyU3Rha2UgPSBhY2N1bXVsYXRvci5HZXRBY2N1bXVsYXRlZFgxMjhQZXJTdGFrZSgpLlRvU3RyaW5nKCkKCQkJZm9sZGVkRXBvY2ggPSBhY2N1bXVsYXRvci5HZXRGb2xkZWRFcG9jaCgpCgkJfQoKCQljaGFpbi5FbWl0KAoJCQkiVXBkYXRlUHJvdG9jb2xGZWVSZXdhcmRBY2N1bXVsYXRpb24iLAoJCQkidG9rZW5QYXRoIiwgdG9rZW5QYXRoLAoJCQkidG90YWxTdGFrZWRBbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQobWFuYWdlci5HZXRUb3RhbFN0YWtlZEFtb3VudCgpKSwKCQkJInByb3RvY29sRmVlQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KG1hbmFnZXIuR2V0UHJvdG9jb2xGZWVBbW91bnQodG9rZW5QYXRoKSksCgkJCSJhY2N1bXVsYXRlZFByb3RvY29sRmVlWDEyOFBlclN0YWtlIiwgYWNjdW11bGF0ZWRQcm90b2NvbEZlZVgxMjhQZXJTdGFrZSwKCQkJImZvbGRlZEVwb2NoIiwgdXRpbHMuRm9ybWF0SW50KGZvbGRlZEVwb2NoKSwKCQkJImFjY3VtdWxhdGVkVGltZXN0YW1wIiwgdXRpbHMuRm9ybWF0SW50KG1hbmFnZXIuR2V0QWNjdW11bGF0ZWRUaW1lc3RhbXAoKSksCgkJKQoJfQp9Chr3EAoKZXJyb3JzLmdubxLoEHBhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgopCgpjb25zdCAoCgllcnJEYXRhTm90Rm91bmQgICAgICAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtR09WX1NUQUtFUi0wMDFdIHJlcXVlc3RlZCBkYXRhIG5vdCBmb3VuZCIKCWVyckludmFsaWRBbW91bnQgICAgICAgICAgICAgICAgICA9ICJbR05PU1dBUC1HT1ZfU1RBS0VSLTAwMl0gaW52YWxpZCBhbW91bnQiCgllcnJOb0RlbGVnYXRlZEFtb3VudCAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtR09WX1NUQUtFUi0wMDNdIHplcm8gZGVsZWdhdGVkIGFtb3VudCIKCWVyck5vdEVub3VnaERlbGVnYXRlZCAgICAgICAgICAgICA9ICJbR05PU1dBUC1HT1ZfU1RBS0VSLTAwNF0gbm90IGVub3VnaCBkZWxlZ2F0ZWQiCgllcnJJbnZhbGlkQWRkcmVzcyAgICAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtR09WX1NUQUtFUi0wMDVdIGludmFsaWQgYWRkcmVzcyIKCWVyck5vdEVub3VnaEJhbGFuY2UgICAgICAgICAgICAgICA9ICJbR05PU1dBUC1HT1ZfU1RBS0VSLTAwNl0gbm90IGVub3VnaCBiYWxhbmNlIgoJZXJyTGVzc1RoYW5NaW5pbXVtICAgICAgICAgICAgICAgID0gIltHTk9TV0FQLUdPVl9TVEFLRVItMDA3XSBjYW5ub3QgZGVsZWdhdGUgbGVzcyB0aGFuIG1pbmltdW0gYW1vdW50IgoJZXJySW52YWxpZFNuYXBzaG90VGltZSAgICAgICAgICAgID0gIltHTk9TV0FQLUdPVl9TVEFLRVItMDA4XSBpbnZhbGlkIHNuYXBzaG90IHRpbWUiCgllcnJTYW1lRGVsZWdhdGVlICAgICAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtR09WX1NUQUtFUi0wMDldIGNhbm5vdCByZWRlbGVnYXRlIHRvIHNhbWUgYWRkcmVzcyIKCWVycldpdGhkcmF3Tm90Q29sbGVjdGFibGUgICAgICAgICA9ICJbR05PU1dBUC1HT1ZfU1RBS0VSLTAxMF0gd2l0aGRyYXcgaXMgbm90IGNvbGxlY3RhYmxlIgoJZXJyQW1vdW50TXVzdEJlTm9uTmVnYXRpdmUgICAgICAgID0gIltHTk9TV0FQLUdPVl9TVEFLRVItMDExXSBhbW91bnQgbXVzdCBiZSBub24tbmVnYXRpdmUiCgllcnJUb3RhbFN0YWtlZEFtb3VudE92ZXJmbG93ICAgICAgPSAiW0dOT1NXQVAtR09WX1NUQUtFUi0wMTJdIHRvdGFsIHN0YWtlZCBhbW91bnQgd291bGQgb3ZlcmZsb3ciCgllcnJSZW1vdmVBbW91bnRFeGNlZWRzVG90YWxTdGFrZWQgPSAiW0dOT1NXQVAtR09WX1NUQUtFUi0wMTNdIHJlbW92ZSBhbW91bnQgZXhjZWVkcyB0b3RhbCBzdGFrZWQgYW1vdW50IgoJZXJyUmVtb3ZlQW1vdW50RXhjZWVkc1N0YWtlZCAgICAgID0gIltHTk9TV0FQLUdPVl9TVEFLRVItMDE0XSByZW1vdmUgYW1vdW50IGV4Y2VlZHMgc3Rha2VkIGFtb3VudCIKCWVyckFtb3VudE11c3RCZVBvc2l0aXZlICAgICAgICAgICA9ICJbR05PU1dBUC1HT1ZfU1RBS0VSLTAxNV0gYW1vdW50IG11c3QgYmUgcG9zaXRpdmUiCgllcnJSZXdhcmREZWJ0VXBkYXRlUmVxdWlyZWQgICAgICAgPSAiW0dOT1NXQVAtR09WX1NUQUtFUi0wMTZdIG11c3QgdXBkYXRlIHJld2FyZCBkZWJ0IGJlZm9yZSBjbGFpbWluZyByZXdhcmRzIgoJZXJyRGVsZWdhdGVkQW1vdW50TmVnYXRpdmUgICAgICAgID0gIltHTk9TV0FQLUdPVl9TVEFLRVItMDE3XSBkZWxlZ2F0ZWQgYW1vdW50IGNhbm5vdCBiZSBuZWdhdGl2ZSIKCWVyclVuZGVsZWdhdGlvbkFtb3VudE5lZ2F0aXZlICAgICA9ICJbR05PU1dBUC1HT1ZfU1RBS0VSLTAxOF0gdW5kZWxlZ2F0aW9uIGFtb3VudCBjYW5ub3QgYmUgbmVnYXRpdmUiCgllcnJEZWxlZ2F0aW9uTm90Rm91bmQgICAgICAgICAgICAgPSAiW0dOT1NXQVAtR09WX1NUQUtFUi0wMTldIGRlbGVnYXRpb24gbm90IGZvdW5kIgoJZXJySW52YWxpZEFjY3J1YWxFcG9jaCAgICAgICAgICAgID0gIltHTk9TV0FQLUdPVl9TVEFLRVItMDIwXSBhY2NydWFsIGVwb2NoIGlzIG9sZGVyIHRoYW4gdGhlIGVwb2NoIGluIGZvcmNlIgoJZXJySW52YWxpZEFjY3J1YWxCdWNrZXRzICAgICAgICAgID0gIltHTk9TV0FQLUdPVl9TVEFLRVItMDIxXSBpbnZhbGlkIGFjY3J1YWwgYnVja2V0cyIKKQoKZnVuYyBtYWtlRXJyb3JXaXRoRGV0YWlscyhtZXNzYWdlIHN0cmluZywgZGV0YWlsIHN0cmluZykgZXJyb3IgewoJcmV0dXJuIHVmbXQuRXJyb3JmKCIlcyB8fCAlcyIsIG1lc3NhZ2UsIGRldGFpbCkKfQoa9mwKCmdldHRlci5nbm8S52xwYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCSJ0aW1lIgoKCWduc21hdGggImduby5sYW5kL3AvZ25vc3dhcC9nbnNtYXRoL3YxIgoJImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgoJcm90cmVlICJnbm8ubGFuZC9wL250L2JwdHJlZS9yb3RyZWUvdjAiCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgoJImduby5sYW5kL3IvZ25vc3dhcC9lbWlzc2lvbiIKCSJnbm8ubGFuZC9yL2dub3N3YXAvZ292L3N0YWtlciIKCSJnbm8ubGFuZC9yL2dub3N3YXAvZ292L3hnbnMiCikKCi8vIEdldFRvdGFseEduc1N1cHBseSByZXR1cm5zIHRoZSB0b3RhbCBhbW91bnQgb2YgeEdOUyBzdXBwbHksIGluY2x1ZGluZwovLyB4R05TIGhlbGQgYnkgdGhlIGxhdW5jaHBhZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiB0b3RhbCB4R05TIHN1cHBseSwgaW5jbHVkaW5nIHRoZSBsYXVuY2hwYWQgYmFsYW5jZS4KZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBHZXRUb3RhbHhHbnNTdXBwbHkoKSBpbnQ2NCB7CglyZXR1cm4geGducy5Ub3RhbFN1cHBseSgpCn0KCi8vIEdldFRvdGFsRGVsZWdhdGVkIHJldHVybnMgdGhlIHRvdGFsIGFtb3VudCBvZiB4R05TIGRlbGVnYXRlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiB0b3RhbCB4R05TIGFtb3VudCBjdXJyZW50bHkgZGVsZWdhdGVkLgpmdW5jIChncyAqZ292U3Rha2VyVjEpIEdldFRvdGFsRGVsZWdhdGVkKCkgaW50NjQgewoJcmV0dXJuIGdzLnN0b3JlLkdldFRvdGFsRGVsZWdhdGVkQW1vdW50KCkKfQoKLy8gR2V0VG90YWxMb2NrZWRBbW91bnQgcmV0dXJucyB0aGUgdG90YWwgYW1vdW50IG9mIGxvY2tlZCBHTlMuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogdG90YWwgR05TIGFtb3VudCBjdXJyZW50bHkgbG9ja2VkLgpmdW5jIChncyAqZ292U3Rha2VyVjEpIEdldFRvdGFsTG9ja2VkQW1vdW50KCkgaW50NjQgewoJcmV0dXJuIGdzLnN0b3JlLkdldFRvdGFsTG9ja2VkQW1vdW50KCkKfQoKLy8gR2V0VW5EZWxlZ2F0aW9uTG9ja3VwUGVyaW9kIHJldHVybnMgdGhlIHVuZGVsZWdhdGlvbiBsb2NrdXAgcGVyaW9kIGluIHNlY29uZHMuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogbnVtYmVyIG9mIHNlY29uZHMgYW4gdW5kZWxlZ2F0aW9uIHJlbWFpbnMgbG9ja2VkLgpmdW5jIChncyAqZ292U3Rha2VyVjEpIEdldFVuRGVsZWdhdGlvbkxvY2t1cFBlcmlvZCgpIGludDY0IHsKCXJldHVybiBncy5zdG9yZS5HZXRVbkRlbGVnYXRpb25Mb2NrdXBQZXJpb2QoKQp9CgovLyBHZXREZWxlZ2F0aW9ucyByZXR1cm5zIGEgcmVhZC1vbmx5IHZpZXcgb2YgZXZlcnkgZGVsZWdhdGlvbiwga2V5ZWQgYnkgdGhlCi8vIGRlY2ltYWwgc3RyaW5nIGZvcm0gb2YgdGhlIGRlbGVnYXRpb24gSUQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqcm90cmVlLlJlYWRPbmx5VHJlZTogcmVhZC1vbmx5IGRlbGVnYXRpb24gdHJlZSBrZXllZCBieSBkZWNpbWFsIElELgpmdW5jIChncyAqZ292U3Rha2VyVjEpIEdldERlbGVnYXRpb25zKCkgKnJvdHJlZS5SZWFkT25seVRyZWUgewoJcmV0dXJuIHJvdHJlZS5XcmFwKGdzLnN0b3JlLkdldEFsbERlbGVnYXRpb25zKCksIGNsb25lRGVsZWdhdGlvbkVudHJ5KQp9CgovLyBFeGlzdHNEZWxlZ2F0aW9uIGNoZWNrcyBpZiBhIGRlbGVnYXRpb24gZXhpc3RzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gZGVsZWdhdGlvbklEOiBkZWxlZ2F0aW9uIGlkZW50aWZpZXIgdG8gbG9vayB1cC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGJvb2w6IHRydWUgd2hlbiBkZWxlZ2F0aW9uSUQgaXMgc3RvcmVkLCBvdGhlcndpc2UgZmFsc2UuCmZ1bmMgKGdzICpnb3ZTdGFrZXJWMSkgRXhpc3RzRGVsZWdhdGlvbihkZWxlZ2F0aW9uSUQgaW50NjQpIGJvb2wgewoJcmV0dXJuIGdzLnN0b3JlLkhhc0RlbGVnYXRpb24oZGVsZWdhdGlvbklEKQp9CgovLyBHZXREZWxlZ2F0b3JEZWxlZ2F0aW9ucyByZXR1cm5zIGEgcmVhZC1vbmx5IHZpZXcgb2YgYSBkZWxlZ2F0b3IncyBkZWxlZ2F0aW9ucywKLy8ga2V5ZWQgYnkgZGVsZWdhdGVlIGFkZHJlc3Mgd2l0aCB0aGF0IHBhaXIncyBkZWxlZ2F0aW9uIElEcyBhcyB0aGUgdmFsdWUuCi8vIG5pbCBpcyByZXR1cm5lZCB3aGVuIHRoZSBkZWxlZ2F0b3IgaGFzIG5vIGRlbGVnYXRpb25zLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gZGVsZWdhdG9yOiBhZGRyZXNzIHdob3NlIG91dGdvaW5nIGRlbGVnYXRpb25zIGFyZSByZXF1ZXN0ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqcm90cmVlLlJlYWRPbmx5VHJlZTogcmVhZC1vbmx5IHRyZWUga2V5ZWQgYnkgZGVsZWdhdGVlIGFkZHJlc3MsIG9yIG5pbAovLyAgICAgd2hlbiBkZWxlZ2F0b3IgaGFzIG5vIGRlbGVnYXRpb24gZW50cmllcy4KZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBHZXREZWxlZ2F0b3JEZWxlZ2F0aW9ucyhkZWxlZ2F0b3IgYWRkcmVzcykgKnJvdHJlZS5SZWFkT25seVRyZWUgewoJZGVsZWdhdGlvbk1hbmFnZXIgOj0gZ3Muc3RvcmUuR2V0RGVsZWdhdGlvbk1hbmFnZXIoKQoJZGVsZWdhdG9yVHJlZSwgZXhpc3RzIDo9IGRlbGVnYXRpb25NYW5hZ2VyLkdldERlbGVnYXRvckRlbGVnYXRpb25zKGRlbGVnYXRvci5TdHJpbmcoKSkKCWlmICFleGlzdHMgewoJCXJldHVybiBuaWwKCX0KCXJldHVybiByb3RyZWUuV3JhcChkZWxlZ2F0b3JUcmVlLCBjbG9uZURlbGVnYXRpb25JRHNFbnRyeSkKfQoKLy8gR2V0VXNlckRlbGVnYXRpb25JRHMgcmV0dXJucyB0aGUgZGVsZWdhdGlvbiBJRHMgZm9yIGEgc3BlY2lmaWMgZGVsZWdhdG9yIGFuZAovLyBkZWxlZ2F0ZWUuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBkZWxlZ2F0b3I6IGFkZHJlc3MgdGhhdCBjcmVhdGVkIHRoZSBkZWxlZ2F0aW9ucy4KLy8gICAtIGRlbGVnYXRlZTogYWRkcmVzcyByZWNlaXZpbmcgdGhlIGRlbGVnYXRpb25zLgovLwovLyBSZXR1cm5zOgovLyAgIC0gW11pbnQ2NDogZGVsZWdhdGlvbiBJRHMgZm9yIHRoZSBkZWxlZ2F0b3IvZGVsZWdhdGVlIHBhaXIsIG9yIGFuIGVtcHR5Ci8vICAgICBzbGljZSB3aGVuIG5vIHBhaXIgaXMgc3RvcmVkLgpmdW5jIChncyAqZ292U3Rha2VyVjEpIEdldFVzZXJEZWxlZ2F0aW9uSURzKGRlbGVnYXRvciBhZGRyZXNzLCBkZWxlZ2F0ZWUgYWRkcmVzcykgW11pbnQ2NCB7CglkZWxlZ2F0aW9uTWFuYWdlciA6PSBncy5zdG9yZS5HZXREZWxlZ2F0aW9uTWFuYWdlcigpCgoJZGVsZWdhdGlvbklEcywgZXhpc3RzIDo9IGRlbGVnYXRpb25NYW5hZ2VyLkdldERlbGVnYXRpb25JRHMoZGVsZWdhdG9yLlN0cmluZygpLCBkZWxlZ2F0ZWUuU3RyaW5nKCkpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gW11pbnQ2NHt9Cgl9CgoJcmV0dXJuIGRlbGVnYXRpb25JRHMKfQoKLy8gSGFzRGVsZWdhdGlvblNuYXBzaG90c0tleSByZXBvcnRzIHdoZXRoZXIgZGVsZWdhdGlvbiBoaXN0b3J5IGhhcyBiZWVuIHN0b3JlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGJvb2w6IHRydWUgd2hlbiB0aGUgdG90YWwgZGVsZWdhdGlvbiBoaXN0b3J5IHN0b3JhZ2Uga2V5IGV4aXN0cy4KZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBIYXNEZWxlZ2F0aW9uU25hcHNob3RzS2V5KCkgYm9vbCB7CglyZXR1cm4gZ3Muc3RvcmUuSGFzVG90YWxEZWxlZ2F0aW9uSGlzdG9yeVN0b3JlS2V5KCkKfQoKLy8gR2V0VG90YWxEZWxlZ2F0aW9uQW1vdW50QXRTbmFwc2hvdCByZXR1cm5zIHRoZSB0b3RhbCBkZWxlZ2F0aW9uIGFtb3VudCBhdCBhCi8vIFVuaXggdGltZXN0YW1wLiBJdCB1c2VzIFJldmVyc2VJdGVyYXRlIHRvIGZpbmQgdGhlIG1vc3QgcmVjZW50IGhpc3RvcnkgZW50cnkKLy8gYXQgb3IgYmVmb3JlIHRoYXQgdGltZXN0YW1wOyB0aGlzIGlzIGEgdGltZXN0YW1wIGxvb2t1cCwgbm90IGEgYmxvY2sgc25hcHNob3QuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBzbmFwc2hvdFRpbWU6IFVuaXggdGltZXN0YW1wIHRvIHJldHJpZXZlIHRoZSBoaXN0b3J5IHZhbHVlIGZvcgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IHRvdGFsIGRlbGVnYXRpb24gYW1vdW50IGF0IHRoZSBzcGVjaWZpZWQgdGltZQovLyAgIC0gYm9vbDogdHJ1ZSB3aGVuIGEgaGlzdG9yeSBlbnRyeSBleGlzdHMgYXQgb3IgYmVmb3JlIHRoZSB0aW1lc3RhbXAKZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBHZXRUb3RhbERlbGVnYXRpb25BbW91bnRBdFNuYXBzaG90KHNuYXBzaG90VGltZSBpbnQ2NCkgKGludDY0LCBib29sKSB7CgloaXN0b3J5IDo9IGdzLnN0b3JlLkdldFRvdGFsRGVsZWdhdGlvbkhpc3RvcnkoKQoJaWYgaGlzdG9yeS5TaXplKCkgPT0gMCB7CgkJcmV0dXJuIDAsIGZhbHNlCgl9CgoJdmFyICgKCQl0b3RhbEFtb3VudCBpbnQ2NAoJCWV4aXN0cyAgICAgIGJvb2wKCSkKCgkvLyBSZXZlcnNlSXRlcmF0ZSBmcm9tIDAgdG8gc25hcHNob3RUaW1lIHRvIGZpbmQgdGhlIG1vc3QgcmVjZW50IGVudHJ5IGF0IG9yIGJlZm9yZSBzbmFwc2hvdFRpbWUKCWhpc3RvcnkuUmV2ZXJzZUl0ZXJhdGUoMCwgc25hcHNob3RUaW1lLCBmdW5jKGtleSBpbnQ2NCwgdmFsdWUgYW55KSBib29sIHsKCQlhbW91bnRJbnQsIG9rIDo9IHZhbHVlLihpbnQ2NCkKCQlpZiAhb2sgewoJCQlwYW5pYyh1Zm10LlNwcmludGYoImludmFsaWQgYW1vdW50IHR5cGU6ICVUIiwgdmFsdWUpKQoJCX0KCgkJdG90YWxBbW91bnQgPSBhbW91bnRJbnQKCQlleGlzdHMgPSB0cnVlCgoJCXJldHVybiB0cnVlIC8vIHN0b3AgYWZ0ZXIgZmlyc3QgKG1vc3QgcmVjZW50KSBlbnRyeQoJfSkKCglyZXR1cm4gdG90YWxBbW91bnQsIGV4aXN0cwp9CgovLyBHZXRVc2VyRGVsZWdhdGlvbkFtb3VudEF0U25hcHNob3QgcmV0dXJucyBvbmUgdXNlcidzIGRlbGVnYXRpb24gYW1vdW50IGF0IGEKLy8gVW5peCB0aW1lc3RhbXAuIFRoZSBoaXN0b3J5IGlzIGtleWVkIGJ5IGFkZHJlc3MgYW5kIHRpbWVzdGFtcCwgYW5kIHRoZQovLyBsb29rdXAgcmV0dXJucyB0aGUgbW9zdCByZWNlbnQgZW50cnkgYXQgb3IgYmVmb3JlIHRoZSByZXF1ZXN0ZWQgdGltZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHVzZXJBZGRyOiBhZGRyZXNzIG9mIHRoZSB1c2VyCi8vICAgLSBzbmFwc2hvdFRpbWU6IFVuaXggdGltZXN0YW1wIHRvIHJldHJpZXZlCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogdXNlciBkZWxlZ2F0aW9uIGFtb3VudCBhdCB0aGUgc3BlY2lmaWVkIHRpbWUKLy8gICAtIGJvb2w6IHRydWUgd2hlbiBhIGhpc3RvcnkgZW50cnkgZXhpc3RzIGF0IG9yIGJlZm9yZSB0aGUgdGltZXN0YW1wCmZ1bmMgKGdzICpnb3ZTdGFrZXJWMSkgR2V0VXNlckRlbGVnYXRpb25BbW91bnRBdFNuYXBzaG90KHVzZXJBZGRyIGFkZHJlc3MsIHNuYXBzaG90VGltZSBpbnQ2NCkgKGludDY0LCBib29sKSB7CgloaXN0b3J5IDo9IGdzLnN0b3JlLkdldFVzZXJEZWxlZ2F0aW9uSGlzdG9yeSgpCgoJYWRkclN0ciA6PSB1c2VyQWRkci5TdHJpbmcoKQoJbG8sIF8gOj0gdXNlckhpc3RvcnlLZXlSYW5nZShhZGRyU3RyKQoJLy8gSW5jbHVzaXZlIHVwcGVyIGJvdW5kOiBsYXJnZXN0IGtleSBmb3IgdGhpcyBhZGRyZXNzIGF0IG9yIGJlZm9yZSBzbmFwc2hvdFRpbWUuCgloaSA6PSBtYWtlVXNlckhpc3RvcnlLZXkoYWRkclN0ciwgc25hcHNob3RUaW1lKQoKCXZhciAoCgkJdXNlckFtb3VudCBpbnQ2NAoJCWV4aXN0cyAgICAgYm9vbAoJKQoKCS8vIFJldmVyc2VJdGVyYXRlIGZyb20gaGkgZG93biB0byBsbyB0byBmaW5kIHRoZSBtb3N0IHJlY2VudCBlbnRyeSBhdCBvciBiZWZvcmUgc25hcHNob3RUaW1lCgloaXN0b3J5LlJldmVyc2VJdGVyYXRlKGxvLCBoaSwgZnVuYyhfIHN0cmluZywgdmFsdWUgYW55KSBib29sIHsKCQlhbW91bnRJbnQsIG9rIDo9IHZhbHVlLihpbnQ2NCkKCQlpZiAhb2sgewoJCQlwYW5pYyh1Zm10LlNwcmludGYoImludmFsaWQgYW1vdW50IHR5cGU6ICVUIiwgdmFsdWUpKQoJCX0KCgkJdXNlckFtb3VudCA9IGFtb3VudEludAoJCWV4aXN0cyA9IHRydWUKCgkJcmV0dXJuIHRydWUgLy8gc3RvcCBhZnRlciBmaXJzdCAobW9zdCByZWNlbnQpIGVudHJ5Cgl9KQoKCXJldHVybiB1c2VyQW1vdW50LCBleGlzdHMKfQoKLy8gR2V0Q2xhaW1hYmxlUmV3YXJkQnlBZGRyZXNzIHJldHVybnMgdGhlIGNsYWltYWJsZSByZXdhcmRzIGZvciBhbiBhZGRyZXNzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gYWRkcjogc3Rha2VyIGFkZHJlc3Mgd2hvc2UgZW1pc3Npb24gYW5kIHByb3RvY29sIGZlZSByZXdhcmRzIGFyZSByZXF1ZXN0ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogY2xhaW1hYmxlIGVtaXNzaW9uIHJld2FyZCBhbW91bnQuCi8vICAgLSBtYXBbc3RyaW5nXWludDY0OiBjbGFpbWFibGUgcHJvdG9jb2wgZmVlIGFtb3VudHMga2V5ZWQgYnkgdG9rZW4gcGF0aC4KLy8gICAtIGVycm9yOiBuaWwgb24gc3VjY2VzczsgYW4gZXJyb3Igd2hlbiBlbWlzc2lvbiBvciBwcm90b2NvbCBmZWUgcmV3YXJkCi8vICAgICByZXNvbHV0aW9uIGZhaWxzLgpmdW5jIChncyAqZ292U3Rha2VyVjEpIEdldENsYWltYWJsZVJld2FyZEJ5QWRkcmVzcyhhZGRyIGFkZHJlc3MpIChpbnQ2NCwgbWFwW3N0cmluZ11pbnQ2NCwgZXJyb3IpIHsKCXJldHVybiBncy5HZXRDbGFpbWFibGVSZXdhcmRCeVJld2FyZElEKGFkZHIuU3RyaW5nKCkpCn0KCi8vIEdldENsYWltYWJsZVJld2FyZEJ5TGF1bmNocGFkIHJldHVybnMgdGhlIGNsYWltYWJsZSByZXdhcmRzIGZvciBhIGxhdW5jaHBhZAovLyBwcm9qZWN0IGFkZHJlc3MuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBhZGRyOiBsYXVuY2hwYWQgcHJvamVjdCBhZGRyZXNzIHVzZWQgdG8gZGVyaXZlIGl0cyByZXdhcmQgSUQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogY2xhaW1hYmxlIGVtaXNzaW9uIHJld2FyZCBhbW91bnQgZm9yIHRoZSBsYXVuY2hwYWQgcHJvamVjdC4KLy8gICAtIG1hcFtzdHJpbmddaW50NjQ6IGNsYWltYWJsZSBwcm90b2NvbCBmZWUgYW1vdW50cyBrZXllZCBieSB0b2tlbiBwYXRoLgovLyAgIC0gZXJyb3I6IG5pbCBvbiBzdWNjZXNzOyBhbiBlcnJvciB3aGVuIGVtaXNzaW9uIG9yIHByb3RvY29sIGZlZSByZXdhcmQKLy8gICAgIHJlc29sdXRpb24gZmFpbHMuCmZ1bmMgKGdzICpnb3ZTdGFrZXJWMSkgR2V0Q2xhaW1hYmxlUmV3YXJkQnlMYXVuY2hwYWQoYWRkciBhZGRyZXNzKSAoaW50NjQsIG1hcFtzdHJpbmddaW50NjQsIGVycm9yKSB7CglyZXR1cm4gZ3MuR2V0Q2xhaW1hYmxlUmV3YXJkQnlSZXdhcmRJRChncy5tYWtlTGF1bmNocGFkUmV3YXJkSUQoYWRkci5TdHJpbmcoKSkpCn0KCi8vIEdldENsYWltYWJsZVJld2FyZEJ5UmV3YXJkSUQgcmV0dXJucyB0aGUgY2xhaW1hYmxlIHJld2FyZHMgZm9yIGEgcmV3YXJkIElELgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcmV3YXJkSUQ6IGVtaXNzaW9uL3Byb3RvY29sLWZlZSByZXdhcmQgc3RhdGUgaWRlbnRpZmllciB0byBpbnNwZWN0LgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IGNsYWltYWJsZSBlbWlzc2lvbiByZXdhcmQgYW1vdW50LgovLyAgIC0gbWFwW3N0cmluZ11pbnQ2NDogY2xhaW1hYmxlIHByb3RvY29sIGZlZSBhbW91bnRzIGtleWVkIGJ5IHRva2VuIHBhdGguCi8vICAgLSBlcnJvcjogbmlsIG9uIHN1Y2Nlc3M7IGFuIGVycm9yIHdoZW4gZW1pc3Npb24gb3IgcHJvdG9jb2wgZmVlIHJld2FyZAovLyAgICAgcmVzb2x1dGlvbiBmYWlscy4KZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBHZXRDbGFpbWFibGVSZXdhcmRCeVJld2FyZElEKHJld2FyZElEIHN0cmluZykgKGludDY0LCBtYXBbc3RyaW5nXWludDY0LCBlcnJvcikgewoJZW1pc3Npb25EaXN0cmlidXRlZEFtb3VudCA6PSBlbWlzc2lvbi5HZXRBY2N1RGlzdHJpYnV0ZWRUb0dvdlN0YWtlcigpCgllbWlzc2lvblJld2FyZE1hbmFnZXIgOj0gZ3Muc3RvcmUuR2V0RW1pc3Npb25SZXdhcmRNYW5hZ2VyKCkKCWVtaXNzaW9uUmVzb2x2ZXIgOj0gTmV3RW1pc3Npb25SZXdhcmRNYW5hZ2VyUmVzb2x2ZXIoZW1pc3Npb25SZXdhcmRNYW5hZ2VyKQoJZW1pc3Npb25SZXdhcmQsIGVyciA6PSBlbWlzc2lvblJlc29sdmVyLkdldENsYWltYWJsZVJld2FyZEFtb3VudChlbWlzc2lvbkRpc3RyaWJ1dGVkQW1vdW50LCByZXdhcmRJRCwgdGltZS5Ob3coKS5Vbml4KCkpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgbWFrZShtYXBbc3RyaW5nXWludDY0KSwgZXJyCgl9CgoJcHJvdG9jb2xGZWVSZXdhcmRzLCBlcnIgOj0gZ3MuZ2V0Q2xhaW1hYmxlUHJvdG9jb2xGZWVSZXdhcmRzKHJld2FyZElEKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIG1ha2UobWFwW3N0cmluZ11pbnQ2NCksIGVycgoJfQoKCXJldHVybiBlbWlzc2lvblJld2FyZCwgcHJvdG9jb2xGZWVSZXdhcmRzLCBuaWwKfQoKLy8gR2V0TGF1bmNocGFkUHJvamVjdERlcG9zaXQgcmV0dXJucyB0aGUgZGVwb3NpdCBhbW91bnQgZm9yIGEgbGF1bmNocGFkIHByb2plY3QuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwcm9qZWN0QWRkcjogbGF1bmNocGFkIHByb2plY3QgYWRkcmVzcyB1c2VkIHRvIGRlcml2ZSBpdHMgcmV3YXJkIElELgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IHN0b3JlZCBsYXVuY2hwYWQgcHJvamVjdCBkZXBvc2l0IGFtb3VudC4KLy8gICAtIGJvb2w6IHRydWUgd2hlbiBhIGRlcG9zaXQgZXhpc3RzIGZvciBwcm9qZWN0QWRkciwgb3RoZXJ3aXNlIGZhbHNlLgpmdW5jIChncyAqZ292U3Rha2VyVjEpIEdldExhdW5jaHBhZFByb2plY3REZXBvc2l0KHByb2plY3RBZGRyIHN0cmluZykgKGludDY0LCBib29sKSB7CglsYXVuY2hwYWREZXBvc2l0cyA6PSBncy5zdG9yZS5HZXRMYXVuY2hwYWRQcm9qZWN0RGVwb3NpdHMoKQoJcmV0dXJuIGxhdW5jaHBhZERlcG9zaXRzLkdldERlcG9zaXQoZ3MubWFrZUxhdW5jaHBhZFJld2FyZElEKHByb2plY3RBZGRyKSkKfQoKLy8gR2V0RGVsZWdhdGlvbldpdGhkcmF3Q291bnQgcmV0dXJucyB0aGUgdG90YWwgbnVtYmVyIG9mIGRlbGVnYXRpb24gd2l0aGRyYXdzCi8vIGZvciBhIHNwZWNpZmljIGRlbGVnYXRpb24uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBkZWxlZ2F0aW9uSUQ6IGRlbGVnYXRpb24gaWRlbnRpZmllciB3aG9zZSB3aXRoZHJhd2FscyBhcmUgY291bnRlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDogbnVtYmVyIG9mIHdpdGhkcmF3YWxzIHJlY29yZGVkIGZvciBkZWxlZ2F0aW9uSUQsIG9yIHplcm8gd2hlbiB0aGUKLy8gICAgIGRlbGVnYXRpb24gZG9lcyBub3QgZXhpc3QuCmZ1bmMgKGdzICpnb3ZTdGFrZXJWMSkgR2V0RGVsZWdhdGlvbldpdGhkcmF3Q291bnQoZGVsZWdhdGlvbklEIGludDY0KSBpbnQgewoJZGVsZWdhdGlvbiwgZXhpc3RzIDo9IGdzLnN0b3JlLkdldERlbGVnYXRpb24oZGVsZWdhdGlvbklEKQoJaWYgIWV4aXN0cyB7CgkJcmV0dXJuIDAKCX0KCXJldHVybiBsZW4oZGVsZWdhdGlvbi5XaXRoZHJhd3MoKSkKfQoKLy8gR2V0RGVsZWdhdGlvbldpdGhkcmF3cyByZXR1cm5zIGEgcGFnaW5hdGVkIGxpc3Qgb2YgZGVsZWdhdGlvbiB3aXRoZHJhd3MgZm9yIGEKLy8gc3BlY2lmaWMgZGVsZWdhdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGRlbGVnYXRpb25JRDogZGVsZWdhdGlvbiBpZGVudGlmaWVyIHdob3NlIHdpdGhkcmF3YWxzIGFyZSByZXF1ZXN0ZWQuCi8vICAgLSBvZmZzZXQ6IHplcm8tYmFzZWQgaW5kZXggb2YgdGhlIGZpcnN0IHdpdGhkcmF3YWwgdG8gcmV0dXJuLgovLyAgIC0gY291bnQ6IG1heGltdW0gbnVtYmVyIG9mIHdpdGhkcmF3YWxzIHRvIHJldHVybi4KLy8KLy8gUmV0dXJuczoKLy8gICAtIFtdc3Rha2VyLkRlbGVnYXRpb25XaXRoZHJhdzogd2l0aGRyYXdhbHMgaW4gdGhlIHJlcXVlc3RlZCByYW5nZSwgb3IgYW4KLy8gICAgIGVtcHR5IHNsaWNlIHdoZW4gdGhlIGRlbGVnYXRpb24gb3IgcGFnZSBpcyBhYnNlbnQuCi8vICAgLSBlcnJvcjogbmlsOyB0aGlzIGFjY2Vzc29yIGN1cnJlbnRseSBoYXMgbm8gZXJyb3IgcGF0aC4KZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBHZXREZWxlZ2F0aW9uV2l0aGRyYXdzKGRlbGVnYXRpb25JRCBpbnQ2NCwgb2Zmc2V0LCBjb3VudCBpbnQpIChbXXN0YWtlci5EZWxlZ2F0aW9uV2l0aGRyYXcsIGVycm9yKSB7CglkZWxlZ2F0aW9uLCBleGlzdHMgOj0gZ3Muc3RvcmUuR2V0RGVsZWdhdGlvbihkZWxlZ2F0aW9uSUQpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gW11zdGFrZXIuRGVsZWdhdGlvbldpdGhkcmF3e30sIG5pbAoJfQoKCXdpdGhkcmF3cyA6PSBkZWxlZ2F0aW9uLldpdGhkcmF3cygpCglzaXplIDo9IGxlbih3aXRoZHJhd3MpCglpZiBvZmZzZXQgPj0gc2l6ZSB7CgkJcmV0dXJuIFtdc3Rha2VyLkRlbGVnYXRpb25XaXRoZHJhd3t9LCBuaWwKCX0KCgllbmQgOj0gb2Zmc2V0ICsgY291bnQKCWlmIGVuZCA+IHNpemUgewoJCWVuZCA9IHNpemUKCX0KCglyZXR1cm4gd2l0aGRyYXdzW29mZnNldDplbmRdLCBuaWwKfQoKLy8gR2V0Q29sbGVjdGFibGVXaXRoZHJhd0Ftb3VudCByZXR1cm5zIHRoZSBjb2xsZWN0YWJsZSB3aXRoZHJhdyBhbW91bnQgZm9yIGEKLy8gc3BlY2lmaWMgZGVsZWdhdGlvbiBhcyBvZiB0aGUgY3VycmVudCBVbml4IHRpbWUuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBkZWxlZ2F0aW9uSUQ6IGRlbGVnYXRpb24gaWRlbnRpZmllciB3aG9zZSBtYXR1cmVkIHdpdGhkcmF3YWxzIGFyZSBzdW1tZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogdG90YWwgYW1vdW50IGN1cnJlbnRseSBjb2xsZWN0YWJsZSwgb3IgemVybyB3aGVuIHRoZSBkZWxlZ2F0aW9uCi8vICAgICBkb2VzIG5vdCBleGlzdC4KZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBHZXRDb2xsZWN0YWJsZVdpdGhkcmF3QW1vdW50KGRlbGVnYXRpb25JRCBpbnQ2NCkgaW50NjQgewoJZGVsZWdhdGlvbiwgZXhpc3RzIDo9IGdzLnN0b3JlLkdldERlbGVnYXRpb24oZGVsZWdhdGlvbklEKQoJaWYgIWV4aXN0cyB7CgkJcmV0dXJuIDAKCX0KCgl0b3RhbEFtb3VudCA6PSBpbnQ2NCgwKQoJY3VycmVudFRpbWUgOj0gdGltZS5Ob3coKS5Vbml4KCkKCWZvciBfLCB3aXRoZHJhdyA6PSByYW5nZSBkZWxlZ2F0aW9uLldpdGhkcmF3cygpIHsKCQlyZXNvbHZlciA6PSBOZXdEZWxlZ2F0aW9uV2l0aGRyYXdSZXNvbHZlcigmd2l0aGRyYXcpCgkJdG90YWxBbW91bnQgPSBnbnNtYXRoLlNhZmVBZGRJbnQ2NCh0b3RhbEFtb3VudCwgcmVzb2x2ZXIuQ29sbGVjdGFibGVBbW91bnQoY3VycmVudFRpbWUpKQoJfQoKCXJldHVybiB0b3RhbEFtb3VudAp9CgovLyBHZXRQcm90b2NvbEZlZUFjY3VtdWxhdGVkWDEyOFBlclN0YWtlIHJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHByb3RvY29sIGZlZSBwZXIKLy8gc3Rha2UgKFExMjgpIGZvciBhIHRva2VuIHBhdGguCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB0b2tlblBhdGg6IHRva2VuIGlkZW50aWZpZXIvcGF0aCB3aG9zZSBhY2N1bXVsYXRvciBpcyByZXF1ZXN0ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqdWludDI1Ni5VaW50OiBhY2N1bXVsYXRlZCBwcm90b2NvbCBmZWUgcGVyIHN0YWtlIHNjYWxlZCBieSAyXjEyOCwgb3IgYQovLyAgICAgemVybyB2YWx1ZSB3aGVuIG5vIGFjY3VtdWxhdG9yIGV4aXN0cyBmb3IgdG9rZW5QYXRoLgpmdW5jIChncyAqZ292U3Rha2VyVjEpIEdldFByb3RvY29sRmVlQWNjdW11bGF0ZWRYMTI4UGVyU3Rha2UodG9rZW5QYXRoIHN0cmluZykgKnVpbnQyNTYuVWludCB7Cglwcm90b2NvbEZlZVJld2FyZE1hbmFnZXIgOj0gZ3Muc3RvcmUuR2V0UHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKCkKCWFjY3VtdWxhdGVkRmVlIDo9IHByb3RvY29sRmVlUmV3YXJkTWFuYWdlci5HZXRBY2N1bXVsYXRlZFByb3RvY29sRmVlWDEyOFBlclN0YWtlKHRva2VuUGF0aCkKCWlmIGFjY3VtdWxhdGVkRmVlID09IG5pbCB7CgkJcmV0dXJuIHVpbnQyNTYuTmV3VWludCgwKQoJfQoKCXJldHVybiBhY2N1bXVsYXRlZEZlZQp9CgovLyBHZXRQcm90b2NvbEZlZUFtb3VudCByZXR1cm5zIHRoZSBwcm90b2NvbCBmZWUgYW1vdW50IGFjY3VtdWxhdGVkIGZvciBhIHRva2VuCi8vIHBhdGguCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB0b2tlblBhdGg6IHRva2VuIGlkZW50aWZpZXIvcGF0aCB3aG9zZSBmb2xkZWQgZmVlIGFtb3VudCBpcyByZXF1ZXN0ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogYWNjdW11bGF0ZWQgcHJvdG9jb2wgZmVlIGFtb3VudCBmb3IgdG9rZW5QYXRoLgpmdW5jIChncyAqZ292U3Rha2VyVjEpIEdldFByb3RvY29sRmVlQW1vdW50KHRva2VuUGF0aCBzdHJpbmcpIGludDY0IHsKCXByb3RvY29sRmVlUmV3YXJkTWFuYWdlciA6PSBncy5zdG9yZS5HZXRQcm90b2NvbEZlZVJld2FyZE1hbmFnZXIoKQoJcmV0dXJuIHByb3RvY29sRmVlUmV3YXJkTWFuYWdlci5HZXRQcm90b2NvbEZlZUFtb3VudCh0b2tlblBhdGgpCn0KCi8vIEdldFByb3RvY29sRmVlQWNjdW11bGF0ZWRUaW1lc3RhbXAgcmV0dXJucyB0aGUgYWNjdW11bGF0ZWQgdGltZXN0YW1wIGZvcgovLyBwcm90b2NvbCBmZWUgcmV3YXJkcy4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBVbml4IHRpbWVzdGFtcCByZXByZXNlbnRlZCBieSBwcm90b2NvbCBmZWUgYWNjdW11bGF0aW9uIHN0YXRlLgpmdW5jIChncyAqZ292U3Rha2VyVjEpIEdldFByb3RvY29sRmVlQWNjdW11bGF0ZWRUaW1lc3RhbXAoKSBpbnQ2NCB7Cglwcm90b2NvbEZlZVJld2FyZE1hbmFnZXIgOj0gZ3Muc3RvcmUuR2V0UHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKCkKCXJldHVybiBwcm90b2NvbEZlZVJld2FyZE1hbmFnZXIuR2V0QWNjdW11bGF0ZWRUaW1lc3RhbXAoKQp9CgovLyBHZXRFbWlzc2lvbkFjY3VtdWxhdGVkWDEyOFBlclN0YWtlIHJldHVybnMgdGhlIGFjY3VtdWxhdGVkIGVtaXNzaW9uIHBlciBzdGFrZQovLyAoUTEyOCkuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqdWludDI1Ni5VaW50OiBhY2N1bXVsYXRlZCBlbWlzc2lvbiByZXdhcmQgcGVyIHN0YWtlIHNjYWxlZCBieSAyXjEyOC4KZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBHZXRFbWlzc2lvbkFjY3VtdWxhdGVkWDEyOFBlclN0YWtlKCkgKnVpbnQyNTYuVWludCB7CgllbWlzc2lvblJld2FyZE1hbmFnZXIgOj0gZ3Muc3RvcmUuR2V0RW1pc3Npb25SZXdhcmRNYW5hZ2VyKCkKCXJldHVybiBlbWlzc2lvblJld2FyZE1hbmFnZXIuR2V0QWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UoKQp9CgovLyBHZXRFbWlzc2lvbkRpc3RyaWJ1dGVkQW1vdW50IHJldHVybnMgdGhlIHRvdGFsIGRpc3RyaWJ1dGVkIGVtaXNzaW9uIGFtb3VudC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiB0b3RhbCBlbWlzc2lvbiBhbW91bnQgcmVjb3JkZWQgYXMgZGlzdHJpYnV0ZWQgdG8gZ292ZXJuYW5jZSBzdGFrZXJzLgpmdW5jIChncyAqZ292U3Rha2VyVjEpIEdldEVtaXNzaW9uRGlzdHJpYnV0ZWRBbW91bnQoKSBpbnQ2NCB7CgllbWlzc2lvblJld2FyZE1hbmFnZXIgOj0gZ3Muc3RvcmUuR2V0RW1pc3Npb25SZXdhcmRNYW5hZ2VyKCkKCXJldHVybiBlbWlzc2lvblJld2FyZE1hbmFnZXIuR2V0RGlzdHJpYnV0ZWRBbW91bnQoKQp9CgovLyBHZXRFbWlzc2lvbkFjY3VtdWxhdGVkVGltZXN0YW1wIHJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHRpbWVzdGFtcCBmb3IgZW1pc3Npb24KLy8gcmV3YXJkcy4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBVbml4IHRpbWVzdGFtcCByZXByZXNlbnRlZCBieSBlbWlzc2lvbiBhY2N1bXVsYXRpb24gc3RhdGUuCmZ1bmMgKGdzICpnb3ZTdGFrZXJWMSkgR2V0RW1pc3Npb25BY2N1bXVsYXRlZFRpbWVzdGFtcCgpIGludDY0IHsKCWVtaXNzaW9uUmV3YXJkTWFuYWdlciA6PSBncy5zdG9yZS5HZXRFbWlzc2lvblJld2FyZE1hbmFnZXIoKQoJcmV0dXJuIGVtaXNzaW9uUmV3YXJkTWFuYWdlci5HZXRBY2N1bXVsYXRlZFRpbWVzdGFtcCgpCn0KGusGChBnZXR0ZXJfdXRpbHMuZ25vEtYGcGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9zdGFrZXIiCikKCi8vIGNsb25lRGVsZWdhdGlvbkVudHJ5IGlzIHRoZSB0cmFuc2Zvcm1hdGlvbiBmb3IgdGhlIGRlbGVnYXRpb24gdHJlZS4KLy8gRGVsZWdhdGlvbiBpcyBtdXRhYmxlIGFuZCBpdHMgc2V0dGVycyBhcmUgZGVjbGFyZWQgaW4gL3IvZ25vc3dhcC9nb3Yvc3Rha2VyLAovLyBzbyBhbiBleHRlcm5hbCBob2xkZXIgb2YgdGhlIHN0b3JlZCBwb2ludGVyIGNvdWxkIHdyaXRlIHJlYWxtIHN0YXRlIHRocm91Z2gKLy8gaXQuCmZ1bmMgY2xvbmVEZWxlZ2F0aW9uRW50cnkodmFsdWUgYW55KSBhbnkgewoJZGVsZWdhdGlvbiwgb2sgOj0gdmFsdWUuKCpzdGFrZXIuRGVsZWdhdGlvbikKCWlmICFvayB7CgkJcmV0dXJuIG5pbAoJfQoKCXJldHVybiBkZWxlZ2F0aW9uLkNsb25lKCkKfQoKLy8gY2xvbmVEZWxlZ2F0aW9uSURzRW50cnkgaXMgdGhlIHRyYW5zZm9ybWF0aW9uIGZvciBhIGRlbGVnYXRvcidzIGRlbGVnYXRpb24KLy8gdHJlZS4gVGhlIHN0b3JlZCB2YWx1ZSBpcyBhIHNsaWNlLCBzbyBoYW5kIG91dCBhIGNvcHkgcmF0aGVyIHRoYW4gbGV0dGluZyBhCi8vIHJlYWRlciB3cml0ZSB0aHJvdWdoIHRoZSBzaGFyZWQgYmFja2luZyBhcnJheS4KZnVuYyBjbG9uZURlbGVnYXRpb25JRHNFbnRyeSh2YWx1ZSBhbnkpIGFueSB7CglkZWxlZ2F0aW9uSURzLCBvayA6PSB2YWx1ZS4oW11pbnQ2NCkKCWlmICFvayB7CgkJcmV0dXJuIG5pbAoJfQoKCWNsb25lZCA6PSBtYWtlKFtdaW50NjQsIGxlbihkZWxlZ2F0aW9uSURzKSkKCWNvcHkoY2xvbmVkLCBkZWxlZ2F0aW9uSURzKQoKCXJldHVybiBjbG9uZWQKfQoaRwoLZ25vbW9kLnRvbWwSOG1vZHVsZSA9ICJnbm8ubGFuZC9yL2dub3N3YXAvZ292L3N0YWtlci92MSIKZ25vID0gIjAuOSIKGqEXCghpbml0LmdubxKUF3BhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJImduby5sYW5kL3IvZ25vc3dhcC9nb3Yvc3Rha2VyIgopCgpmdW5jIGluaXQoY3VyIHJlYWxtKSB7CglyZWdpc3RlckdvdlN0YWtlclYxKGN1cikKfQoKZnVuYyByZWdpc3RlckdvdlN0YWtlclYxKGN1ciByZWFsbSkgewoJc3Rha2VyLlJlZ2lzdGVySW5pdGlhbGl6ZXIoY3Jvc3MoY3VyKSwgZnVuYyhfIGludCwgcmxtIHJlYWxtLCBzdG9yZSBzdGFrZXIuSUdvdlN0YWtlclN0b3JlKSBzdGFrZXIuSUdvdlN0YWtlciB7CgkJLy8gYHJsbWAgaGVyZSBpcyB0aGUgZ292L3N0YWtlciBwcm94eSByZWFsbSB0aHJlYWRlZCBpbiBieQoJCS8vIHN0YWtlci5SZWdpc3RlckluaXRpYWxpemVyLiBQZXItdmVyc2lvbiBzdG9yZSBib290c3RyYXAgd3JpdGVzCgkJLy8gdGhlcmVmb3JlIHBhc3MgdGhlIHByb3h5J3MgS1Ytc3RvcmUgQUNMLgoJCWVyciA6PSBpbml0U3RvcmVEYXRhKDAsIHJsbSwgc3RvcmUpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXBhbmljKGVycikKCQl9CgoJCXJldHVybiBOZXdHb3ZTdGFrZXJWMShzdG9yZSkKCX0pCn0KCmZ1bmMgaW5pdFN0b3JlRGF0YShfIGludCwgcmxtIHJlYWxtLCBzdG9yZSBzdGFrZXIuSUdvdlN0YWtlclN0b3JlKSBlcnJvciB7CgkvLyBJbml0aWFsaXplIGJhc2ljIGNvbmZpZ3VyYXRpb24KCWlmICFzdG9yZS5IYXNVbkRlbGVnYXRpb25Mb2NrdXBQZXJpb2RTdG9yZUtleSgpIHsKCQllcnIgOj0gc3RvcmUuU2V0VW5EZWxlZ2F0aW9uTG9ja3VwUGVyaW9kKDAsIHJsbSwgaW50NjQoNyoyNCo2MCo2MCkpIC8vIDcgZGF5cyBkZWZhdWx0CgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJaWYgIXN0b3JlLkhhc1RvdGFsRGVsZWdhdGVkQW1vdW50U3RvcmVLZXkoKSB7CgkJZXJyIDo9IHN0b3JlLlNldFRvdGFsRGVsZWdhdGVkQW1vdW50KDAsIHJsbSwgaW50NjQoMCkpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJaWYgIXN0b3JlLkhhc1RvdGFsTG9ja2VkQW1vdW50U3RvcmVLZXkoKSB7CgkJZXJyIDo9IHN0b3JlLlNldFRvdGFsTG9ja2VkQW1vdW50KDAsIHJsbSwgaW50NjQoMCkpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJLy8gSW5pdGlhbGl6ZSBkZWxlZ2F0aW9uIG1hbmFnZW1lbnQKCWlmICFzdG9yZS5IYXNEZWxlZ2F0aW9uQ291bnRlclN0b3JlS2V5KCkgewoJCWVyciA6PSBzdG9yZS5TZXREZWxlZ2F0aW9uQ291bnRlcigwLCBybG0sIHN0YWtlci5OZXdDb3VudGVyKCkpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJaWYgIXN0b3JlLkhhc0RlbGVnYXRpb25zU3RvcmVLZXkoKSB7CgkJZXJyIDo9IHN0b3JlLlNldERlbGVnYXRpb25zKDAsIHJsbSwgc3Rha2VyLk5ld0RlbGVnYXRpb25UcmVlKCkpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJLy8gSW5pdGlhbGl6ZSB0b3RhbCBkZWxlZ2F0aW9uIGhpc3RvcnkgKHRpbWVzdGFtcCAtPiBpbnQ2NCkKCWlmICFzdG9yZS5IYXNUb3RhbERlbGVnYXRpb25IaXN0b3J5U3RvcmVLZXkoKSB7CgkJZXJyIDo9IHN0b3JlLlNldFRvdGFsRGVsZWdhdGlvbkhpc3RvcnkoMCwgcmxtLCBzdGFrZXIuTmV3VWludFRyZWUoKSkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCX0KCgkvLyBJbml0aWFsaXplIHVzZXIgZGVsZWdhdGlvbiBoaXN0b3J5IChhZGRyZXNzIC0+ICpVaW50VHJlZVt0aW1lc3RhbXAgLT4gaW50NjRdKQoJaWYgIXN0b3JlLkhhc1VzZXJEZWxlZ2F0aW9uSGlzdG9yeVN0b3JlS2V5KCkgewoJCWVyciA6PSBzdG9yZS5TZXRVc2VyRGVsZWdhdGlvbkhpc3RvcnkoMCwgcmxtLCBzdGFrZXIuTmV3VXNlckRlbGVnYXRpb25UcmVlKCkpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJLy8gSW5pdGlhbGl6ZSBFbWlzc2lvblJld2FyZE1hbmFnZXIKCWlmICFzdG9yZS5IYXNFbWlzc2lvblJld2FyZE1hbmFnZXJTdG9yZUtleSgpIHsKCQllbWlzc2lvblJld2FyZE1hbmFnZXIgOj0gc3Rha2VyLk5ld0VtaXNzaW9uUmV3YXJkTWFuYWdlcigpCgkJZXJyIDo9IHN0b3JlLlNldEVtaXNzaW9uUmV3YXJkTWFuYWdlcigwLCBybG0sIGVtaXNzaW9uUmV3YXJkTWFuYWdlcikKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCX0KCgkvLyBJbml0aWFsaXplIFByb3RvY29sRmVlUmV3YXJkTWFuYWdlcgoJaWYgIXN0b3JlLkhhc1Byb3RvY29sRmVlUmV3YXJkTWFuYWdlclN0b3JlS2V5KCkgewoJCXByb3RvY29sRmVlUmV3YXJkTWFuYWdlciA6PSBzdGFrZXIuTmV3UHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKCkKCQllcnIgOj0gc3RvcmUuU2V0UHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKDAsIHJsbSwgcHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCS8vIEluaXRpYWxpemUgTGF1bmNocGFkUHJvamVjdERlcG9zaXRzCglpZiAhc3RvcmUuSGFzTGF1bmNocGFkUHJvamVjdERlcG9zaXRzU3RvcmVLZXkoKSB7CgkJbGF1bmNocGFkRGVwb3NpdHMgOj0gc3Rha2VyLk5ld0xhdW5jaHBhZFByb2plY3REZXBvc2l0cygpCgkJZXJyIDo9IHN0b3JlLlNldExhdW5jaHBhZFByb2plY3REZXBvc2l0cygwLCBybG0sIGxhdW5jaHBhZERlcG9zaXRzKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCS8vIEluaXRpYWxpemUgRGVsZWdhdGlvbk1hbmFnZXIKCWlmICFzdG9yZS5IYXNEZWxlZ2F0aW9uTWFuYWdlclN0b3JlS2V5KCkgewoJCWRlbGVnYXRpb25NYW5hZ2VyIDo9IHN0YWtlci5OZXdEZWxlZ2F0aW9uTWFuYWdlcigpCgkJZXJyIDo9IHN0b3JlLlNldERlbGVnYXRpb25NYW5hZ2VyKDAsIHJsbSwgZGVsZWdhdGlvbk1hbmFnZXIpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJcmV0dXJuIG5pbAp9ChrwAwoMaW5zdGFuY2UuZ25vEt8DcGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9zdGFrZXIiCikKCnR5cGUgZ292U3Rha2VyVjEgc3RydWN0IHsKCXN0b3JlIHN0YWtlci5JR292U3Rha2VyU3RvcmUKfQoKLy8gTmV3R292U3Rha2VyVjEgY3JlYXRlcyB0aGUgZ292ZXJuYW5jZSBzdGFrZXIgdjEgaW1wbGVtZW50YXRpb24gYmFja2VkIGJ5IHN0b3JlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gc3RvcmU6IGdvdmVybmFuY2Utc3Rha2VyIHN0b3JhZ2UgaW50ZXJmYWNlIHVzZWQgYnkgdGhlIGltcGxlbWVudGF0aW9uLgovLwovLyBSZXR1cm5zOgovLyAgIC0gc3Rha2VyLklHb3ZTdGFrZXI6IGdvdmVybmFuY2Ugc3Rha2VyIEFQSSBiYWNrZWQgYnkgc3RvcmUuCmZ1bmMgTmV3R292U3Rha2VyVjEoc3RvcmUgc3Rha2VyLklHb3ZTdGFrZXJTdG9yZSkgc3Rha2VyLklHb3ZTdGFrZXIgewoJcmV0dXJuICZnb3ZTdGFrZXJWMXtzdG9yZX0KfQoa7RUKHmxhdW5jaHBhZF9wcm9qZWN0X2RlcG9zaXRzLmdubxLKFXBhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJZ25zbWF0aCAiZ25vLmxhbmQvcC9nbm9zd2FwL2duc21hdGgvdjEiCgoJImduby5sYW5kL3IvZ25vc3dhcC9nb3Yvc3Rha2VyIgopCgp0eXBlIExhdW5jaHBhZFByb2plY3REZXBvc2l0c1Jlc29sdmVyIHN0cnVjdCB7Cgkqc3Rha2VyLkxhdW5jaHBhZFByb2plY3REZXBvc2l0cwp9CgovLyBOZXdMYXVuY2hwYWRQcm9qZWN0RGVwb3NpdHNSZXNvbHZlciB3cmFwcyBsYXVuY2hwYWQgcHJvamVjdCBkZXBvc2l0IHN0YXRlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gbGF1bmNocGFkUHJvamVjdERlcG9zaXRzOiBwcm9qZWN0IGRlcG9zaXQgc3RhdGUgdG8gcmVzb2x2ZSBhbmQgbXV0YXRlCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqTGF1bmNocGFkUHJvamVjdERlcG9zaXRzUmVzb2x2ZXI6IHJlc29sdmVyIHJldGFpbmluZyB0aGUgc3VwcGxpZWQgZGVwb3NpdCBzdGF0ZSBwb2ludGVyCmZ1bmMgTmV3TGF1bmNocGFkUHJvamVjdERlcG9zaXRzUmVzb2x2ZXIobGF1bmNocGFkUHJvamVjdERlcG9zaXRzICpzdGFrZXIuTGF1bmNocGFkUHJvamVjdERlcG9zaXRzKSAqTGF1bmNocGFkUHJvamVjdERlcG9zaXRzUmVzb2x2ZXIgewoJcmV0dXJuICZMYXVuY2hwYWRQcm9qZWN0RGVwb3NpdHNSZXNvbHZlcntsYXVuY2hwYWRQcm9qZWN0RGVwb3NpdHN9Cn0KCi8vIGdldExhdW5jaHBhZFByb2plY3REZXBvc2l0IHJldHJpZXZlcyB0aGUgZGVwb3NpdCBhbW91bnQgZm9yIGEgbGF1bmNocGFkIHByb2plY3QuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBvd25lckFkZHJlc3M6IHByb2plY3Qgb3duZXIncyBhZGRyZXNzIGlkZW50aWZpZXIKLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBkZXBvc2l0IGFtb3VudAovLyAgIC0gYm9vbDogdHJ1ZSBpZiBwcm9qZWN0IGV4aXN0cywgZmFsc2Ugb3RoZXJ3aXNlCmZ1bmMgKGxwZHIgKkxhdW5jaHBhZFByb2plY3REZXBvc2l0c1Jlc29sdmVyKSBnZXRMYXVuY2hwYWRQcm9qZWN0RGVwb3NpdChvd25lckFkZHJlc3Mgc3RyaW5nKSAoaW50NjQsIGJvb2wpIHsKCXJldHVybiBscGRyLkxhdW5jaHBhZFByb2plY3REZXBvc2l0cy5HZXREZXBvc2l0KG93bmVyQWRkcmVzcykKfQoKLy8gc2V0TGF1bmNocGFkUHJvamVjdERlcG9zaXQgc2V0cyB0aGUgZGVwb3NpdCBhbW91bnQgZm9yIGEgbGF1bmNocGFkIHByb2plY3QuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBvd25lckFkZHJlc3M6IHByb2plY3Qgb3duZXIncyBhZGRyZXNzIGlkZW50aWZpZXIKLy8gICAtIGRlcG9zaXQ6IGRlcG9zaXQgYW1vdW50IHRvIHNldAovLwovLyBSZXR1cm5zOgovLyAgIC0gYm9vbDogdHJ1ZSBpZiBzdWNjZXNzZnVsbHkgc2V0CmZ1bmMgKGxwZHIgKkxhdW5jaHBhZFByb2plY3REZXBvc2l0c1Jlc29sdmVyKSBzZXRMYXVuY2hwYWRQcm9qZWN0RGVwb3NpdChvd25lckFkZHJlc3Mgc3RyaW5nLCBkZXBvc2l0IGludDY0KSBib29sIHsKCWxwZHIuTGF1bmNocGFkUHJvamVjdERlcG9zaXRzLlNldERlcG9zaXQob3duZXJBZGRyZXNzLCBkZXBvc2l0KQoJcmV0dXJuIHRydWUKfQoKLy8gYWRkRGVwb3NpdCBhZGRzIHRvIHRoZSBkZXBvc2l0IGFtb3VudCBmb3IgYSBsYXVuY2hwYWQgcHJvamVjdC4KLy8gVGhpcyBtZXRob2QgZW5zdXJlcyB0aGUgZGVwb3NpdCBkb2Vzbid0IGdvIG5lZ2F0aXZlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gb3duZXJBZGRyZXNzOiBwcm9qZWN0IG93bmVyJ3MgYWRkcmVzcyBpZGVudGlmaWVyCi8vICAgLSBhbW91bnQ6IGFtb3VudCB0byBhZGQgdG8gdGhlIGRlcG9zaXQKZnVuYyAobHBkciAqTGF1bmNocGFkUHJvamVjdERlcG9zaXRzUmVzb2x2ZXIpIGFkZERlcG9zaXQob3duZXJBZGRyZXNzIHN0cmluZywgYW1vdW50IGludDY0KSB7CgljdXJyZW50RGVwb3NpdCwgXyA6PSBscGRyLkxhdW5jaHBhZFByb2plY3REZXBvc2l0cy5HZXREZXBvc2l0KG93bmVyQWRkcmVzcykKCW5ld0RlcG9zaXQgOj0gZ25zbWF0aC5TYWZlQWRkSW50NjQoY3VycmVudERlcG9zaXQsIGFtb3VudCkKCWlmIG5ld0RlcG9zaXQgPCAwIHsKCQluZXdEZXBvc2l0ID0gMAoJfQoJbHBkci5MYXVuY2hwYWRQcm9qZWN0RGVwb3NpdHMuU2V0RGVwb3NpdChvd25lckFkZHJlc3MsIG5ld0RlcG9zaXQpCn0KCi8vIHJlbW92ZURlcG9zaXQgcmVtb3ZlcyBmcm9tIHRoZSBkZXBvc2l0IGFtb3VudCBmb3IgYSBsYXVuY2hwYWQgcHJvamVjdC4KLy8gVGhpcyBtZXRob2QgZW5zdXJlcyB0aGUgZGVwb3NpdCBkb2Vzbid0IGdvIG5lZ2F0aXZlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gb3duZXJBZGRyZXNzOiBwcm9qZWN0IG93bmVyJ3MgYWRkcmVzcyBpZGVudGlmaWVyCi8vICAgLSBhbW91bnQ6IGFtb3VudCB0byByZW1vdmUgZnJvbSB0aGUgZGVwb3NpdApmdW5jIChscGRyICpMYXVuY2hwYWRQcm9qZWN0RGVwb3NpdHNSZXNvbHZlcikgcmVtb3ZlRGVwb3NpdChvd25lckFkZHJlc3Mgc3RyaW5nLCBhbW91bnQgaW50NjQpIHsKCWN1cnJlbnREZXBvc2l0LCBleGlzdHMgOj0gbHBkci5MYXVuY2hwYWRQcm9qZWN0RGVwb3NpdHMuR2V0RGVwb3NpdChvd25lckFkZHJlc3MpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4KCX0KCW5ld0RlcG9zaXQgOj0gZ25zbWF0aC5TYWZlU3ViSW50NjQoY3VycmVudERlcG9zaXQsIGFtb3VudCkKCWlmIG5ld0RlcG9zaXQgPCAwIHsKCQluZXdEZXBvc2l0ID0gMAoJfQoJbHBkci5MYXVuY2hwYWRQcm9qZWN0RGVwb3NpdHMuU2V0RGVwb3NpdChvd25lckFkZHJlc3MsIG5ld0RlcG9zaXQpCn0KGr1UCh9wcm90b2NvbF9mZWVfcmV3YXJkX21hbmFnZXIuZ25vEplUcGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkiZXJyb3JzIgoJIm1hdGgiCgoJImduby5sYW5kL3AvZ25vc3dhcC9nbnNtYXRoL3YxIgoJdTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL3VpbnQyNTYvdjEiCgoJImduby5sYW5kL3IvZ25vc3dhcC9nb3Yvc3Rha2VyIgopCgovLyBQcm90b2NvbEZlZVJld2FyZE1hbmFnZXJSZXNvbHZlciBkcml2ZXMgdGhlIFByb3RvY29sRmVlUmV3YXJkTWFuYWdlci4KLy8KLy8gU3Rha2UgY2hhbmdlcyBvbmx5IG1vdmUgdGhlIGVwb2NoLCB0aGUgdG90YWwgc3Rha2UgaGlzdG9yeSBhbmQgdGhlIHN0YWtlcidzIG93bgovLyBldmVudCBsaXN0LiBGZWVzIGFyZSBmb2xkZWQgaW50byBhIHRva2VuJ3MgYWNjdW11bGF0b3Igd2hlbiB0aGF0IHRva2VuIGlzIGNvbGxlY3RlZCwKLy8gZWFjaCBhY2NydWFsIGJ1Y2tldCBhZ2FpbnN0IHRoZSB0b3RhbCBzdGFrZSBpbiBmb3JjZSBkdXJpbmcgaXRzIGVwb2NoLgp0eXBlIFByb3RvY29sRmVlUmV3YXJkTWFuYWdlclJlc29sdmVyIHN0cnVjdCB7Cgkqc3Rha2VyLlByb3RvY29sRmVlUmV3YXJkTWFuYWdlcgp9CgovLyBOZXdQcm90b2NvbEZlZVJld2FyZE1hbmFnZXJSZXNvbHZlciB3cmFwcyB0aGUgc2hhcmVkIHByb3RvY29sLWZlZSByZXdhcmQgbWFuYWdlci4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIG1hbmFnZXI6IFByb3RvY29sLWZlZSByZXdhcmQgc3RhdGUgdG8gcmVzb2x2ZSBhbmQgbXV0YXRlLgovLwovLyBSZXR1cm5zOgovLyAgIC0gKlByb3RvY29sRmVlUmV3YXJkTWFuYWdlclJlc29sdmVyOiByZXNvbHZlciBvcGVyYXRpbmcgb24gbWFuYWdlcidzIGFjY291bnRpbmcgc3RhdGUuCmZ1bmMgTmV3UHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyUmVzb2x2ZXIobWFuYWdlciAqc3Rha2VyLlByb3RvY29sRmVlUmV3YXJkTWFuYWdlcikgKlByb3RvY29sRmVlUmV3YXJkTWFuYWdlclJlc29sdmVyIHsKCXJldHVybiAmUHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyUmVzb2x2ZXJ7CgkJUHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyOiBtYW5hZ2VyLAoJfQp9CgovLyBhZGRTdGFrZSByZWNvcmRzIHRoYXQgcmV3YXJkSUQgc3Rha2VkIGFtb3VudCBtb3JlIGZyb20gZXBvY2ggb24uCi8vCi8vIGVwb2NoIGlzIHRoZSBhY2NydWFsIGVwb2NoIHByb3RvY29sX2ZlZSBqdXN0IG9wZW5lZCBmb3IgdGhpcyBjaGFuZ2UsIHNvIGl0IG11c3Qgbm90Ci8vIGJlIG9sZGVyIHRoYW4gdGhlIGVwb2NoIGluIGZvcmNlLgpmdW5jIChzZWxmICpQcm90b2NvbEZlZVJld2FyZE1hbmFnZXJSZXNvbHZlcikgYWRkU3Rha2UocmV3YXJkSUQgc3RyaW5nLCBhbW91bnQgaW50NjQsIGVwb2NoIGludDY0KSBlcnJvciB7CglpZiBhbW91bnQgPD0gMCB7CgkJcmV0dXJuIGVycm9ycy5OZXcoZXJyQW1vdW50TXVzdEJlUG9zaXRpdmUpCgl9CglpZiBlcG9jaCA8IHNlbGYuR2V0Q3VycmVudEVwb2NoKCkgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyckludmFsaWRBY2NydWFsRXBvY2gpCgl9CgoJY3VycmVudFRvdGFsIDo9IHNlbGYuR2V0VG90YWxTdGFrZWRBbW91bnQoKQoJaWYgY3VycmVudFRvdGFsID4gbWF0aC5NYXhJbnQ2NC1hbW91bnQgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyclRvdGFsU3Rha2VkQW1vdW50T3ZlcmZsb3cpCgl9CgoJcmV3YXJkU3RhdGUsIG9rLCBlcnIgOj0gc2VsZi5HZXRSZXdhcmRTdGF0ZShyZXdhcmRJRCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCWlmICFvayB7CgkJcmV3YXJkU3RhdGUgPSBzdGFrZXIuTmV3UHJvdG9jb2xGZWVSZXdhcmRTdGF0ZSgpCgl9CgoJcmVzb2x2ZWRTdGF0ZSA6PSBOZXdQcm90b2NvbEZlZVJld2FyZFN0YXRlUmVzb2x2ZXIocmV3YXJkU3RhdGUpCglpZiBlcnIgOj0gcmVzb2x2ZWRTdGF0ZS5hZGRTdGFrZShhbW91bnQsIGVwb2NoKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCXNlbGYucmVjb3JkVG90YWxTdGFrZWRBbW91bnQoZXBvY2gsIGduc21hdGguU2FmZUFkZEludDY0KGN1cnJlbnRUb3RhbCwgYW1vdW50KSkKCXNlbGYuU2V0UmV3YXJkU3RhdGUocmV3YXJkSUQsIHJld2FyZFN0YXRlKQoKCXJldHVybiBuaWwKfQoKLy8gcmVtb3ZlU3Rha2UgcmVjb3JkcyB0aGF0IHJld2FyZElEIHN0YWtlZCBhbW91bnQgbGVzcyBmcm9tIGVwb2NoIG9uLgpmdW5jIChzZWxmICpQcm90b2NvbEZlZVJld2FyZE1hbmFnZXJSZXNvbHZlcikgcmVtb3ZlU3Rha2UocmV3YXJkSUQgc3RyaW5nLCBhbW91bnQgaW50NjQsIGVwb2NoIGludDY0KSBlcnJvciB7CglpZiBhbW91bnQgPCAwIHsKCQlyZXR1cm4gZXJyb3JzLk5ldyhlcnJBbW91bnRNdXN0QmVOb25OZWdhdGl2ZSkKCX0KCWlmIGVwb2NoIDwgc2VsZi5HZXRDdXJyZW50RXBvY2goKSB7CgkJcmV0dXJuIGVycm9ycy5OZXcoZXJySW52YWxpZEFjY3J1YWxFcG9jaCkKCX0KCgl1cGRhdGVkVG90YWwgOj0gZ25zbWF0aC5TYWZlU3ViSW50NjQoc2VsZi5HZXRUb3RhbFN0YWtlZEFtb3VudCgpLCBhbW91bnQpCglpZiB1cGRhdGVkVG90YWwgPCAwIHsKCQlyZXR1cm4gZXJyb3JzLk5ldyhlcnJSZW1vdmVBbW91bnRFeGNlZWRzVG90YWxTdGFrZWQpCgl9CgoJcmV3YXJkU3RhdGUsIG9rLCBlcnIgOj0gc2VsZi5HZXRSZXdhcmRTdGF0ZShyZXdhcmRJRCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCWlmICFvayB7CgkJcmV3YXJkU3RhdGUgPSBzdGFrZXIuTmV3UHJvdG9jb2xGZWVSZXdhcmRTdGF0ZSgpCgl9CgoJcmVzb2x2ZWRTdGF0ZSA6PSBOZXdQcm90b2NvbEZlZVJld2FyZFN0YXRlUmVzb2x2ZXIocmV3YXJkU3RhdGUpCglpZiBlcnIgOj0gcmVzb2x2ZWRTdGF0ZS5yZW1vdmVTdGFrZShhbW91bnQsIGVwb2NoKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCXNlbGYucmVjb3JkVG90YWxTdGFrZWRBbW91bnQoZXBvY2gsIHVwZGF0ZWRUb3RhbCkKCXNlbGYuU2V0UmV3YXJkU3RhdGUocmV3YXJkSUQsIHJld2FyZFN0YXRlKQoKCXJldHVybiBuaWwKfQoKZnVuYyAoc2VsZiAqUHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyUmVzb2x2ZXIpIHJlY29yZFRvdGFsU3Rha2VkQW1vdW50KGVwb2NoIGludDY0LCB0b3RhbFN0YWtlZEFtb3VudCBpbnQ2NCkgewoJc2VsZi5TZXRDdXJyZW50RXBvY2goZXBvY2gpCglzZWxmLlNldFRvdGFsU3Rha2VkQW1vdW50KHRvdGFsU3Rha2VkQW1vdW50KQoJc2VsZi5TZXRUb3RhbFN0YWtlZEFtb3VudEF0KGVwb2NoLCB0b3RhbFN0YWtlZEFtb3VudCkKfQoKLy8gYXBwbHlBY2NydWFsQnVja2V0cyBmb2xkcyBjb25zdW1lZCBhY2NydWFsIGJ1Y2tldHMgb2YgdG9rZW5QYXRoIGludG8gaXRzIGFjY3VtdWxhdG9yLgovLwovLyBlcG9jaHMgYW5kIGFtb3VudHMgYXJlIHBhcmFsbGVsIGFuZCBpbiBhc2NlbmRpbmcgZXBvY2ggb3JkZXIuIEVhY2ggYW1vdW50IGlzIGRpdmlkZWQKLy8gYnkgdGhlIHRvdGFsIHN0YWtlIGluIGZvcmNlIGR1cmluZyBpdHMgZXBvY2g7IHdpdGggbm90aGluZyBzdGFrZWQgdGhlIGFtb3VudCBpcwovLyBkcm9wcGVkLCB0aGUgc2FtZSBwb2xpY3kgdGhlIGVtaXNzaW9uIGFjY3VtdWxhdG9yIGFwcGxpZXMuIGV4aGF1c3RlZCByZXBvcnRzIHRoYXQKLy8gbm8gYnVja2V0IGlzIGxlZnQgcGVuZGluZywgd2hpY2ggbGV0cyB0aGUgYWNjdW11bGF0b3IgbWFyayBldmVyeSBjbG9zZWQgZXBvY2ggYXMKLy8gZnVsbHkgZm9sZGVkLgpmdW5jIChzZWxmICpQcm90b2NvbEZlZVJld2FyZE1hbmFnZXJSZXNvbHZlcikgYXBwbHlBY2NydWFsQnVja2V0cygKCXRva2VuUGF0aCBzdHJpbmcsCgllcG9jaHMgW11pbnQ2NCwKCWFtb3VudHMgW11pbnQ2NCwKCWV4aGF1c3RlZCBib29sLAoJY3VycmVudFRpbWVzdGFtcCBpbnQ2NCwKKSBlcnJvciB7CglpZiBsZW4oZXBvY2hzKSAhPSBsZW4oYW1vdW50cykgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyckludmFsaWRBY2NydWFsQnVja2V0cykKCX0KCglhY2N1bXVsYXRvciwgb2sgOj0gc2VsZi5HZXRUb2tlbkFjY3VtdWxhdG9yKHRva2VuUGF0aCkKCWlmICFvayB7CgkJaWYgbGVuKGVwb2NocykgPT0gMCB7CgkJCXJldHVybiBuaWwKCQl9CgkJYWNjdW11bGF0b3IgPSBzdGFrZXIuTmV3UHJvdG9jb2xGZWVUb2tlbkFjY3VtdWxhdG9yKCkKCQlzZWxmLlNldFRva2VuQWNjdW11bGF0b3IodG9rZW5QYXRoLCBhY2N1bXVsYXRvcikKCX0KCgljdXJyZW50WDEyOCA6PSBhY2N1bXVsYXRvci5HZXRBY2N1bXVsYXRlZFgxMjhQZXJTdGFrZSgpLkNsb25lKCkKCWZlZUFtb3VudCA6PSBhY2N1bXVsYXRvci5HZXRQcm90b2NvbEZlZUFtb3VudCgpCglsYXN0RXBvY2ggOj0gaW50NjQoLTEpCgoJZm9yIGksIGVwb2NoIDo9IHJhbmdlIGVwb2NocyB7CgkJaWYgZXBvY2ggPCBsYXN0RXBvY2ggfHwgZXBvY2ggPiBzZWxmLkdldEN1cnJlbnRFcG9jaCgpIHsKCQkJcmV0dXJuIGVycm9ycy5OZXcoZXJySW52YWxpZEFjY3J1YWxCdWNrZXRzKQoJCX0KCQlsYXN0RXBvY2ggPSBlcG9jaAoKCQlhbW91bnQgOj0gYW1vdW50c1tpXQoJCWlmIGFtb3VudCA8IDAgewoJCQlyZXR1cm4gZXJyb3JzLk5ldyhlcnJJbnZhbGlkQWNjcnVhbEJ1Y2tldHMpCgkJfQoJCWZlZUFtb3VudCA9IGduc21hdGguU2FmZUFkZEludDY0KGZlZUFtb3VudCwgYW1vdW50KQoKCQl0b3RhbFN0YWtlZEFtb3VudCA6PSBzZWxmLkdldFRvdGFsU3Rha2VkQW1vdW50QXQoZXBvY2gpCgkJaWYgdG90YWxTdGFrZWRBbW91bnQgPD0gMCB8fCBhbW91bnQgPT0gMCB7CgkJCWNvbnRpbnVlCgkJfQoKCQkvLyBTY2FsZSB0aGUgYW1vdW50IGJ5IDJeMTI4IGJlZm9yZSBkaXZpZGluZyBieSB0aGUgdG90YWwgc3Rha2UuIFRoZSBhbW91bnQKCQkvLyBmaXRzIGluIDYzIGJpdHMsIHNvIHRoZSBwcm9kdWN0IGZpdHMgaW4gMTkxIGJpdHMgYW5kIGNhbm5vdCBvdmVyZmxvdy4KCQlhbW91bnRYMTI4IDo9IHUyNTYuWmVybygpLkxzaCh1MjU2Lk5ld1VpbnRGcm9tSW50NjQoYW1vdW50KSwgMTI4KQoJCXBlclN0YWtlWDEyOCA6PSB1MjU2Llplcm8oKS5EaXYoYW1vdW50WDEyOCwgdTI1Ni5OZXdVaW50RnJvbUludDY0KHRvdGFsU3Rha2VkQW1vdW50KSkKCQljdXJyZW50WDEyOCA9IHUyNTYuWmVybygpLkFkZChjdXJyZW50WDEyOCwgcGVyU3Rha2VYMTI4KQoKCQlhY2N1bXVsYXRvci5TZXRBY2N1bXVsYXRlZFgxMjhQZXJTdGFrZUF0KGVwb2NoLCBjdXJyZW50WDEyOCkKCX0KCglhY2N1bXVsYXRvci5TZXRQcm90b2NvbEZlZUFtb3VudChmZWVBbW91bnQpCgoJLy8gRXZlcnkgZXBvY2ggYmVmb3JlIHRoZSBvbmUgaW4gZm9yY2UgaXMgY2xvc2VkLCBzbyBpdCBpcyBmdWxseSBmb2xkZWQgb25jZSBubyBidWNrZXQKCS8vIGlzIGxlZnQuIE90aGVyd2lzZSBvbmx5IHRoZSBlcG9jaHMgdXAgdG8gdGhlIGxhc3QgY29uc3VtZWQgYnVja2V0IGFyZSBjb21wbGV0ZS4KCWZvbGRlZEVwb2NoIDo9IGFjY3VtdWxhdG9yLkdldEZvbGRlZEVwb2NoKCkKCWlmIGV4aGF1c3RlZCB7CgkJZm9sZGVkRXBvY2ggPSBtYXhJbnQ2NChmb2xkZWRFcG9jaCwgc2VsZi5HZXRDdXJyZW50RXBvY2goKS0xKQoJfSBlbHNlIGlmIGxhc3RFcG9jaCA+PSAwIHsKCQlmb2xkZWRFcG9jaCA9IG1heEludDY0KGZvbGRlZEVwb2NoLCBtaW5JbnQ2NChsYXN0RXBvY2gsIHNlbGYuR2V0Q3VycmVudEVwb2NoKCktMSkpCgl9CglhY2N1bXVsYXRvci5TZXRGb2xkZWRFcG9jaChmb2xkZWRFcG9jaCkKCglzZWxmLlNldEFjY3VtdWxhdGVkVGltZXN0YW1wKGN1cnJlbnRUaW1lc3RhbXApCgoJcmV0dXJuIG5pbAp9CgovLyBhY2N1bXVsYXRvclZpZXcgcmV0dXJucyBhIHJlYWQgdmlldyBvZiB0b2tlblBhdGgncyBhY2N1bXVsYXRvci4KLy8KLy8gV2l0aCBwZW5kaW5nQ29tcGxldGUgZmFsc2UgdGhlIHZpZXcgcmVmbGVjdHMgdGhlIGFjY3VtdWxhdG9yIGV4YWN0bHkgYXMgZm9sZGVkIHNvCi8vIGZhciwgd2hpY2ggaXMgd2hhdCBhIGNvbGxlY3QgbXVzdCBzZXR0bGUgYWdhaW5zdC4gV2l0aCBwZW5kaW5nQ29tcGxldGUgdHJ1ZSB0aGUKLy8gZ2l2ZW4gYnVja2V0cyBhcmUgdGhlIHdob2xlIHBlbmRpbmcgc2V0IG9mIHRoZSB0b2tlbjogdGhleSBhcmUgcHJvamVjdGVkIG9uIHRvcCwgYXMKLy8gYXBwbHlBY2NydWFsQnVja2V0cyB3b3VsZCBmb2xkIHRoZW0sIGFuZCBldmVyeSBjbG9zZWQgZXBvY2ggY291bnRzIGFzIGZvbGRlZCwgd2hpY2gKLy8gaXMgd2hhdCBhbiBleGhhdXN0aXZlIGZvbGQgd291bGQgbGVhdmUgYmVoaW5kLiBBIHF1ZXJ5IHVzZXMgdGhlIGxhdHRlciBzbyB0aGF0IGl0Ci8vIHJlcG9ydHMgd2hhdCBhIGNvbGxlY3Qgd291bGQgcGF5IGV2ZW4gd2hlbiBhIHByZXZpb3VzIGJvdW5kZWQgZm9sZCBjb25zdW1lZCBleGFjdGx5Ci8vIGl0cyBsaW1pdCBhbmQgbGVmdCBmb2xkZWRFcG9jaCBiZWhpbmQgdGhlIGVwb2NoIGluIGZvcmNlLgpmdW5jIChzZWxmICpQcm90b2NvbEZlZVJld2FyZE1hbmFnZXJSZXNvbHZlcikgYWNjdW11bGF0b3JWaWV3KHRva2VuUGF0aCBzdHJpbmcsIHBlbmRpbmdFcG9jaHMgW11pbnQ2NCwgcGVuZGluZ0Ftb3VudHMgW11pbnQ2NCwgcGVuZGluZ0NvbXBsZXRlIGJvb2wpICpwcm90b2NvbEZlZUFjY3VtdWxhdG9yVmlldyB7Cgl2aWV3IDo9ICZwcm90b2NvbEZlZUFjY3VtdWxhdG9yVmlld3sKCQlleHRyYUVwb2NoczogIFtdaW50NjR7fSwKCQlleHRyYVZhbHVlczogIFtdKnUyNTYuVWludHt9LAoJCWN1cnJlbnQ6ICAgICAgdTI1Ni5aZXJvKCksCgkJZmlyc3RFcG9jaDogICAtMSwKCQlmb2xkZWRFcG9jaDogIC0xLAoJCWN1cnJlbnRFcG9jaDogc2VsZi5HZXRDdXJyZW50RXBvY2goKSwKCX0KCglpZiBhY2N1bXVsYXRvciwgb2sgOj0gc2VsZi5HZXRUb2tlbkFjY3VtdWxhdG9yKHRva2VuUGF0aCk7IG9rIHsKCQl2aWV3LmFjY3VtdWxhdG9yID0gYWNjdW11bGF0b3IKCQl2aWV3LmN1cnJlbnQgPSBhY2N1bXVsYXRvci5HZXRBY2N1bXVsYXRlZFgxMjhQZXJTdGFrZSgpLkNsb25lKCkKCQl2aWV3LmZpcnN0RXBvY2ggPSBhY2N1bXVsYXRvci5HZXRGaXJzdEVwb2NoKCkKCQl2aWV3LmZvbGRlZEVwb2NoID0gYWNjdW11bGF0b3IuR2V0Rm9sZGVkRXBvY2goKQoJfQoKCWlmIHBlbmRpbmdDb21wbGV0ZSB7CgkJLy8gUHJvamVjdGluZyB0aGUgd2hvbGUgcGVuZGluZyBzZXQgZm9sZHMgZXZlcnkgY2xvc2VkIGVwb2NoLgoJCXZpZXcuZm9sZGVkRXBvY2ggPSBtYXhJbnQ2NCh2aWV3LmZvbGRlZEVwb2NoLCB2aWV3LmN1cnJlbnRFcG9jaC0xKQoJfQoKCWZvciBpLCBlcG9jaCA6PSByYW5nZSBwZW5kaW5nRXBvY2hzIHsKCQl0b3RhbFN0YWtlZEFtb3VudCA6PSBzZWxmLkdldFRvdGFsU3Rha2VkQW1vdW50QXQoZXBvY2gpCgkJaWYgdG90YWxTdGFrZWRBbW91bnQgPD0gMCB8fCBwZW5kaW5nQW1vdW50c1tpXSA8PSAwIHsKCQkJY29udGludWUKCQl9CgoJCWFtb3VudFgxMjggOj0gdTI1Ni5aZXJvKCkuTHNoKHUyNTYuTmV3VWludEZyb21JbnQ2NChwZW5kaW5nQW1vdW50c1tpXSksIDEyOCkKCQlwZXJTdGFrZVgxMjggOj0gdTI1Ni5aZXJvKCkuRGl2KGFtb3VudFgxMjgsIHUyNTYuTmV3VWludEZyb21JbnQ2NCh0b3RhbFN0YWtlZEFtb3VudCkpCgkJdmlldy5jdXJyZW50ID0gdTI1Ni5aZXJvKCkuQWRkKHZpZXcuY3VycmVudCwgcGVyU3Rha2VYMTI4KQoJCXZpZXcuZXh0cmFFcG9jaHMgPSBhcHBlbmQodmlldy5leHRyYUVwb2NocywgZXBvY2gpCgkJdmlldy5leHRyYVZhbHVlcyA9IGFwcGVuZCh2aWV3LmV4dHJhVmFsdWVzLCB2aWV3LmN1cnJlbnQuQ2xvbmUoKSkKCQlpZiB2aWV3LmZpcnN0RXBvY2ggPCAwIHsKCQkJdmlldy5maXJzdEVwb2NoID0gZXBvY2gKCQl9Cgl9CgoJcmV0dXJuIHZpZXcKfQoKLy8gY2xhaW1Ub2tlblJld2FyZCBzZXR0bGVzIHRva2VuUGF0aCBmb3IgcmV3YXJkSUQgYW5kIHJldHVybnMgdGhlIHJld2FyZCBjb2xsZWN0ZWQuCi8vIFNlZSBQcm90b2NvbEZlZVJld2FyZFN0YXRlUmVzb2x2ZXIuY2xhaW1Ub2tlblJld2FyZCBmb3IgdGhlIG1heEV2ZW50cyBib3VuZC4KZnVuYyAoc2VsZiAqUHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyUmVzb2x2ZXIpIGNsYWltVG9rZW5SZXdhcmQocmV3YXJkSUQgc3RyaW5nLCB0b2tlblBhdGggc3RyaW5nLCBtYXhFdmVudHMgaW50NjQpIChpbnQ2NCwgZXJyb3IpIHsKCXJld2FyZFN0YXRlLCBvaywgZXJyIDo9IHNlbGYuR2V0UmV3YXJkU3RhdGUocmV3YXJkSUQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CglpZiAhb2sgewoJCXJldHVybiAwLCBuaWwKCX0KCglyZXNvbHZlZFN0YXRlIDo9IE5ld1Byb3RvY29sRmVlUmV3YXJkU3RhdGVSZXNvbHZlcihyZXdhcmRTdGF0ZSkKCXJld2FyZCwgZXJyIDo9IHJlc29sdmVkU3RhdGUuY2xhaW1Ub2tlblJld2FyZCh0b2tlblBhdGgsIHNlbGYuYWNjdW11bGF0b3JWaWV3KHRva2VuUGF0aCwgbmlsLCBuaWwsIGZhbHNlKSwgbWF4RXZlbnRzKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoKCXNlbGYuU2V0UmV3YXJkU3RhdGUocmV3YXJkSUQsIHJld2FyZFN0YXRlKQoKCXJldHVybiByZXdhcmQsIG5pbAp9CgovLyBjbGFpbVJld2FyZHMgc2V0dGxlcyBldmVyeSBmb2xkZWQgdG9rZW4gZm9yIHJld2FyZElEIGFuZCByZXR1cm5zIHRoZSByZXdhcmQKLy8gY29sbGVjdGVkIHBlciB0b2tlbi4gSXRzIGNvc3QgZ3Jvd3Mgd2l0aCB0aGUgbnVtYmVyIG9mIHRva2VucyB0aGF0IGV2ZXIgY29sbGVjdGVkIGEKLy8gZmVlOyBjbGFpbVRva2VuUmV3YXJkIGlzIHRoZSBib3VuZGVkIGFsdGVybmF0aXZlLgpmdW5jIChzZWxmICpQcm90b2NvbEZlZVJld2FyZE1hbmFnZXJSZXNvbHZlcikgY2xhaW1SZXdhcmRzKHJld2FyZElEIHN0cmluZywgY3VycmVudFRpbWVzdGFtcCBpbnQ2NCkgKG1hcFtzdHJpbmddaW50NjQsIGVycm9yKSB7CglyZXdhcmRzIDo9IG1ha2UobWFwW3N0cmluZ11pbnQ2NCkKCglyZXdhcmRTdGF0ZSwgb2ssIGVyciA6PSBzZWxmLkdldFJld2FyZFN0YXRlKHJld2FyZElEKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIG5pbCwgZXJyCgl9CglpZiAhb2sgewoJCXJldHVybiByZXdhcmRzLCBuaWwKCX0KCglyZXNvbHZlZFN0YXRlIDo9IE5ld1Byb3RvY29sRmVlUmV3YXJkU3RhdGVSZXNvbHZlcihyZXdhcmRTdGF0ZSkKCWlmICFyZXNvbHZlZFN0YXRlLklzQ2xhaW1hYmxlKGN1cnJlbnRUaW1lc3RhbXApIHsKCQlyZXR1cm4gcmV3YXJkcywgbmlsCgl9CgoJZm9yIF8sIHRva2VuUGF0aCA6PSByYW5nZSBzZWxmLkdldFRva2VuUGF0aHMoKSB7CgkJcmV3YXJkLCBlcnIgOj0gcmVzb2x2ZWRTdGF0ZS5jbGFpbVRva2VuUmV3YXJkKHRva2VuUGF0aCwgc2VsZi5hY2N1bXVsYXRvclZpZXcodG9rZW5QYXRoLCBuaWwsIG5pbCwgZmFsc2UpLCAwKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gbmlsLCBlcnIKCQl9CgkJcmV3YXJkc1t0b2tlblBhdGhdID0gcmV3YXJkCgl9CgoJcmVzb2x2ZWRTdGF0ZS5TZXRDbGFpbWVkVGltZXN0YW1wKGN1cnJlbnRUaW1lc3RhbXApCglzZWxmLlNldFJld2FyZFN0YXRlKHJld2FyZElELCByZXdhcmRTdGF0ZSkKCglyZXR1cm4gcmV3YXJkcywgbmlsCn0KCi8vIEdldENsYWltYWJsZVJld2FyZEFtb3VudCByZXR1cm5zIHdoYXQgY29sbGVjdGluZyB0b2tlblBhdGggZm9yIHJld2FyZElEIHdvdWxkIHBheSwKLy8gd2l0aCB0aGUgZ2l2ZW4gcGVuZGluZyBidWNrZXRzIHByb2plY3RlZCBvbiB0b3Agb2YgdGhlIGFjY3VtdWxhdG9yLgovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcmV3YXJkSUQ6IElkZW50aWZpZXIgb2YgdGhlIHN0YWtlciB3aG9zZSBjbGFpbWFibGUgcmV3YXJkIGlzIHF1b3RlZC4KLy8gICAtIHRva2VuUGF0aDogVG9rZW4gcGF0aCB3aG9zZSBjbGFpbWFibGUgcHJvdG9jb2wtZmVlIHJld2FyZCBpcyBxdW90ZWQuCi8vICAgLSBwZW5kaW5nRXBvY2hzOiBQZW5kaW5nIGJ1Y2tldCBlcG9jaHMgcHJvamVjdGVkIG9uIHRoZSBhY2N1bXVsYXRvci4KLy8gICAtIHBlbmRpbmdBbW91bnRzOiBQZW5kaW5nIGZlZSBhbW91bnRzIHBhcmFsbGVsIHRvIHBlbmRpbmdFcG9jaHMuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogcHJvdG9jb2wtZmVlIGFtb3VudCB0aGF0IGNvbGxlY3RpbmcgdG9rZW5QYXRoIHdvdWxkIHBheSBpbiB0b2tlbiBiYXNlIHVuaXRzLgovLyAgIC0gZXJyb3I6IG5pbCBvbiBzdWNjZXNzOyBub24tbmlsIHdoZW4gcmV3YXJkLXN0YXRlIGxvb2t1cCBvciBwcm9qZWN0aW9uIGZhaWxzLgpmdW5jIChzZWxmICpQcm90b2NvbEZlZVJld2FyZE1hbmFnZXJSZXNvbHZlcikgR2V0Q2xhaW1hYmxlUmV3YXJkQW1vdW50KHJld2FyZElEIHN0cmluZywgdG9rZW5QYXRoIHN0cmluZywgcGVuZGluZ0Vwb2NocyBbXWludDY0LCBwZW5kaW5nQW1vdW50cyBbXWludDY0KSAoaW50NjQsIGVycm9yKSB7CglyZXdhcmRTdGF0ZSwgb2ssIGVyciA6PSBzZWxmLkdldFJld2FyZFN0YXRlKHJld2FyZElEKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoJaWYgIW9rIHsKCQlyZXR1cm4gMCwgbmlsCgl9CgoJcmVzb2x2ZWRTdGF0ZSA6PSBOZXdQcm90b2NvbEZlZVJld2FyZFN0YXRlUmVzb2x2ZXIocmV3YXJkU3RhdGUpCgoJcmV0dXJuIHJlc29sdmVkU3RhdGUuZ2V0Q2xhaW1hYmxlUmV3YXJkKHRva2VuUGF0aCwgc2VsZi5hY2N1bXVsYXRvclZpZXcodG9rZW5QYXRoLCBwZW5kaW5nRXBvY2hzLCBwZW5kaW5nQW1vdW50cywgdHJ1ZSkpLCBuaWwKfQoKZnVuYyBtYXhJbnQ2NChhLCBiIGludDY0KSBpbnQ2NCB7CglpZiBhID4gYiB7CgkJcmV0dXJuIGEKCX0KCXJldHVybiBiCn0KCmZ1bmMgbWluSW50NjQoYSwgYiBpbnQ2NCkgaW50NjQgewoJaWYgYSA8IGIgewoJCXJldHVybiBhCgl9CglyZXR1cm4gYgp9ChqdWAodcHJvdG9jb2xfZmVlX3Jld2FyZF9zdGF0ZS5nbm8S+1dwYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCSJlcnJvcnMiCgoJImduby5sYW5kL3AvZ25vc3dhcC9jb25zdHMvdjEiCgkiZ25vLmxhbmQvcC9nbm9zd2FwL2duc21hdGgvdjEiCgl1MjU2ICJnbm8ubGFuZC9wL2dub3N3YXAvdWludDI1Ni92MSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9zdGFrZXIiCikKCi8vIFByb3RvY29sRmVlUmV3YXJkU3RhdGVSZXNvbHZlciBzZXR0bGVzIG9uZSBzdGFrZXIncyBwcm90b2NvbCBmZWUgcmV3YXJkcy4KLy8KLy8gQSBzdGFrZXIncyByZXdhcmQgZm9yIGEgdG9rZW4gaXMgdGhlIHN1bSwgb3ZlciB0aGUgc2VnbWVudHMgYmV0d2VlbiB0aGVpciBzdGFrZQovLyBldmVudHMsIG9mIHRoZSBzdGFrZSBoZWxkIGR1cmluZyB0aGUgc2VnbWVudCB0aW1lcyB0aGUgZ3Jvd3RoIG9mIHRoZSB0b2tlbidzCi8vIGFjY3VtdWxhdGVkIGZlZSBwZXIgc3Rha2UgYWNyb3NzIGl0LiBTZWdtZW50cyBhcmUgZm9sZGVkIGluIGV2ZW50IG9yZGVyLCBzbyB0aGUgd29yawovLyBvZiBzZXR0bGluZyBhIHRva2VuIGlzIHByb3BvcnRpb25hbCB0byB0aGUgc3Rha2VyJ3Mgb3duIHN0YWtlIGNoYW5nZXMgc2luY2UgdGhlIHRva2VuCi8vIHdhcyBsYXN0IHNldHRsZWQsIG5ldmVyIHRvIHRoZSBudW1iZXIgb2YgdG9rZW5zLgp0eXBlIFByb3RvY29sRmVlUmV3YXJkU3RhdGVSZXNvbHZlciBzdHJ1Y3QgewoJKnN0YWtlci5Qcm90b2NvbEZlZVJld2FyZFN0YXRlCn0KCi8vIE5ld1Byb3RvY29sRmVlUmV3YXJkU3RhdGVSZXNvbHZlciB3cmFwcyBvbmUgc3Rha2VyJ3MgcHJvdG9jb2wgZmVlIHJld2FyZCBzdGF0ZQovLyB3aXRoIHNldHRsZW1lbnQgb3BlcmF0aW9ucy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHByb3RvY29sRmVlUmV3YXJkU3RhdGU6IHN0YWtlciByZXdhcmQgc3RhdGUgdG8gcmVzb2x2ZSBhbmQgbXV0YXRlLgovLwovLyBSZXR1cm5zOgovLyAgIC0gKlByb3RvY29sRmVlUmV3YXJkU3RhdGVSZXNvbHZlcjogcmVzb2x2ZXIgYmFja2VkIGJ5IHByb3RvY29sRmVlUmV3YXJkU3RhdGUuCmZ1bmMgTmV3UHJvdG9jb2xGZWVSZXdhcmRTdGF0ZVJlc29sdmVyKHByb3RvY29sRmVlUmV3YXJkU3RhdGUgKnN0YWtlci5Qcm90b2NvbEZlZVJld2FyZFN0YXRlKSAqUHJvdG9jb2xGZWVSZXdhcmRTdGF0ZVJlc29sdmVyIHsKCXJldHVybiAmUHJvdG9jb2xGZWVSZXdhcmRTdGF0ZVJlc29sdmVyewoJCVByb3RvY29sRmVlUmV3YXJkU3RhdGU6IHByb3RvY29sRmVlUmV3YXJkU3RhdGUsCgl9Cn0KCi8vIHByb3RvY29sRmVlQWNjdW11bGF0b3JWaWV3IHJlYWRzIGEgdG9rZW4gYWNjdW11bGF0b3IgYXMgaXQgc3RhbmRzLCBvcHRpb25hbGx5Ci8vIGV4dGVuZGVkIGluIG1lbW9yeSB3aXRoIGJ1Y2tldHMgdGhhdCBhcmUgc3RpbGwgcGVuZGluZyBvbiB0aGUgcHJvdG9jb2wgZmVlIHJlYWxtLgovLyBUaGUgZXh0ZW5zaW9uIGxldHMgYSBxdWVyeSByZXBvcnQgd2hhdCBhIGNvbGxlY3Qgd291bGQgcGF5IHdpdGhvdXQgZm9sZGluZyBhbnl0aGluZy4KdHlwZSBwcm90b2NvbEZlZUFjY3VtdWxhdG9yVmlldyBzdHJ1Y3QgewoJYWNjdW11bGF0b3IgKnN0YWtlci5Qcm90b2NvbEZlZVRva2VuQWNjdW11bGF0b3IgLy8gbmlsIHdoZW4gdGhlIHRva2VuIHdhcyBuZXZlciBmb2xkZWQKCS8vIGV4dHJhRXBvY2hzIGFuZCBleHRyYVZhbHVlcyBob2xkIHByb2plY3RlZCBoaXN0b3J5IGVudHJpZXMsIGluIGFzY2VuZGluZyBlcG9jaCBvcmRlcgoJZXh0cmFFcG9jaHMgW11pbnQ2NAoJZXh0cmFWYWx1ZXMgW10qdTI1Ni5VaW50CgkvLyBjdXJyZW50IGlzIHRoZSBsYXRlc3QgYWNjdW11bGF0ZWQgdmFsdWUsIHByb2plY3Rpb24gaW5jbHVkZWQKCWN1cnJlbnQgKnUyNTYuVWludAoJLy8gZmlyc3RFcG9jaCBpcyB0aGUgZmlyc3QgZXBvY2ggYSBmZWUgd2FzIGZvbGRlZCBmb3IsIHByb2plY3Rpb24gaW5jbHVkZWQsIG9yIC0xCglmaXJzdEVwb2NoIGludDY0CgkvLyBmb2xkZWRFcG9jaCBpcyB0aGUgbGFzdCBlcG9jaCB3aG9zZSBmZWVzIGFyZSBrbm93biB0byBiZSBmdWxseSBmb2xkZWQsIG9yIC0xCglmb2xkZWRFcG9jaCBpbnQ2NAoJLy8gY3VycmVudEVwb2NoIGlzIHRoZSBhY2NydWFsIGVwb2NoIGluIGZvcmNlIG9uIHRoZSBtYW5hZ2VyCgljdXJyZW50RXBvY2ggaW50NjQKfQoKLy8gYXQgcmV0dXJucyB0aGUgYWNjdW11bGF0ZWQgdmFsdWUgYWZ0ZXIgdGhlIGZlZXMgb2YgdGhlIGxhdGVzdCBrbm93biBlcG9jaCBhdCBvcgovLyBiZWZvcmUgZXBvY2guCmZ1bmMgKHYgKnByb3RvY29sRmVlQWNjdW11bGF0b3JWaWV3KSBhdChlcG9jaCBpbnQ2NCkgKnUyNTYuVWludCB7Cglmb3IgaSA6PSBsZW4odi5leHRyYUVwb2NocykgLSAxOyBpID49IDA7IGktLSB7CgkJaWYgdi5leHRyYUVwb2Noc1tpXSA8PSBlcG9jaCB7CgkJCXJldHVybiB2LmV4dHJhVmFsdWVzW2ldCgkJfQoJfQoKCWlmIHYuYWNjdW11bGF0b3IgPT0gbmlsIHsKCQlyZXR1cm4gdTI1Ni5aZXJvKCkKCX0KCglyZXR1cm4gdi5hY2N1bXVsYXRvci5HZXRBY2N1bXVsYXRlZFgxMjhQZXJTdGFrZUF0KGVwb2NoKQp9CgovLyBwcm90b2NvbEZlZVRva2VuU2V0dGxlbWVudCBpcyB0aGUgaW4tbWVtb3J5IHdvcmtpbmcgY29weSBvZiBhIHRva2VuJ3Mgc2V0dGxlbWVudAovLyBzdGF0ZS4gSXQgaXMgd3JpdHRlbiBiYWNrIG9ubHkgb24gYSBjb2xsZWN0LCBzbyBxdWVyaWVzIG5ldmVyIHRvdWNoIHN0b3JhZ2UuCnR5cGUgcHJvdG9jb2xGZWVUb2tlblNldHRsZW1lbnQgc3RydWN0IHsKCWV2ZW50Q3Vyc29yICAgICAgICAgaW50NjQKCXNlZ21lbnRTdGFrZWRBbW91bnQgaW50NjQKCXNlZ21lbnRTdGFydFgxMjggICAgKnUyNTYuVWludAoJZWFybmVkWDEyOCAgICAgICAgICAqdTI1Ni5VaW50Cn0KCi8vIGxvYWRUb2tlblNldHRsZW1lbnQgcmV0dXJucyB0aGUgc2V0dGxlbWVudCBzdGF0ZSBvZiB0b2tlblBhdGgsIGluaXRpYWxpc2luZyBpdCB3aGVuCi8vIHRoZSB0b2tlbiB3YXMgbmV2ZXIgc2V0dGxlZCBmb3IgdGhpcyBzdGFrZXIuCi8vCi8vIEEgZnJlc2ggc3RhdGUgc2tpcHMgZXZlcnkgc3Rha2UgZXZlbnQgYXQgb3IgYmVmb3JlIHRoZSBhY2N1bXVsYXRvcidzIGZpcnN0IGVwb2NoOgovLyB0aGUgYWNjdW11bGF0b3Igd2FzIHplcm8gdGhyb3VnaG91dCwgc28gdGhvc2Ugc2VnbWVudHMgZWFybmVkIG5vdGhpbmcgYW5kIHRoZSBvcGVuCi8vIHNlZ21lbnQgY2FuIHN0YXJ0IGF0IHRoZSBsYXN0IG9mIHRoZW0uIFdoZW4gbm8gZmVlIHdhcyBmb2xkZWQgYXQgYWxsLCB0aGUgc2tpcAovLyBjb3ZlcnMgZXZlcnkgZXZlbnQsIGJ1dCBvbmx5IG9uY2UgZXZlcnkgY2xvc2VkIGVwb2NoIGlzIGtub3duIHRvIGJlIGZvbGRlZDogYQovLyBidWNrZXQgc3RpbGwgcGVuZGluZyBmcm9tIGEgY2xvc2VkIGVwb2NoIGNvdWxkIGxhdGVyIGNyZWRpdCBvbmUgb2YgdGhvc2UgZXZlbnRzLAovLyBzbyB1bnRpbCB0aGVuIHRoZXkgYXJlIHNldHRsZWQgb25lIGJ5IG9uZSB0aHJvdWdoIHNldHRsZUV2ZW50cywgd2hpY2ggaXMgZ2F0ZWQgYnkKLy8gZm9sZGVkRXBvY2ggYW5kIHlpZWxkcyBub3RoaW5nIHdoaWxlIHRoZSBhY2N1bXVsYXRvciBzdGF5cyBhdCB6ZXJvLgpmdW5jIChwICpQcm90b2NvbEZlZVJld2FyZFN0YXRlUmVzb2x2ZXIpIGxvYWRUb2tlblNldHRsZW1lbnQodG9rZW5QYXRoIHN0cmluZywgdmlldyAqcHJvdG9jb2xGZWVBY2N1bXVsYXRvclZpZXcpICpwcm90b2NvbEZlZVRva2VuU2V0dGxlbWVudCB7CglpZiB0b2tlblN0YXRlLCBvayA6PSBwLkdldFRva2VuU3RhdGUodG9rZW5QYXRoKTsgb2sgewoJCXJldHVybiAmcHJvdG9jb2xGZWVUb2tlblNldHRsZW1lbnR7CgkJCWV2ZW50Q3Vyc29yOiAgICAgICAgIHRva2VuU3RhdGUuR2V0RXZlbnRDdXJzb3IoKSwKCQkJc2VnbWVudFN0YWtlZEFtb3VudDogdG9rZW5TdGF0ZS5HZXRTZWdtZW50U3Rha2VkQW1vdW50KCksCgkJCXNlZ21lbnRTdGFydFgxMjg6ICAgIHRva2VuU3RhdGUuR2V0U2VnbWVudFN0YXJ0WDEyOCgpLkNsb25lKCksCgkJCWVhcm5lZFgxMjg6ICAgICAgICAgIHRva2VuU3RhdGUuR2V0RWFybmVkWDEyOCgpLkNsb25lKCksCgkJfQoJfQoKCXNldHRsZW1lbnQgOj0gJnByb3RvY29sRmVlVG9rZW5TZXR0bGVtZW50ewoJCWV2ZW50Q3Vyc29yOiAgICAgICAgIDAsCgkJc2VnbWVudFN0YWtlZEFtb3VudDogMCwKCQlzZWdtZW50U3RhcnRYMTI4OiAgICB1MjU2Llplcm8oKSwKCQllYXJuZWRYMTI4OiAgICAgICAgICB1MjU2Llplcm8oKSwKCX0KCglldmVudENvdW50IDo9IHAuR2V0U3Rha2VFdmVudENvdW50KCkKCWlmIHZpZXcuZmlyc3RFcG9jaCA8IDAgewoJCWlmIHZpZXcuZm9sZGVkRXBvY2ggPj0gdmlldy5jdXJyZW50RXBvY2gtMSB7CgkJCS8vIE5vIGZlZSB3YXMgZXZlciBmb2xkZWQgYW5kIG5vdGhpbmcgZnJvbSBhIGNsb3NlZCBlcG9jaCBpcyBwZW5kaW5nLCBzbwoJCQkvLyBldmVyeSByZWNvcmRlZCBldmVudCBlYXJuZWQgbm90aGluZy4KCQkJc2V0dGxlbWVudC5ldmVudEN1cnNvciA9IGV2ZW50Q291bnQKCQkJc2V0dGxlbWVudC5zZWdtZW50U3Rha2VkQW1vdW50ID0gcC5HZXRTdGFrZWRBbW91bnQoKQoJCX0KCQlyZXR1cm4gc2V0dGxlbWVudAoJfQoKCS8vIFN0YWtlIGV2ZW50cyBhcmUgYXBwZW5kZWQgaW4gZXBvY2ggb3JkZXIsIHNvIHRoZSBsYXN0IGV2ZW50IGF0IG9yIGJlZm9yZQoJLy8gZmlyc3RFcG9jaCBpcyBmb3VuZCBieSBiaW5hcnkgc2VhcmNoOiB0aGUgbG9va3VwIGNvc3RzIE8obG9nIG4pIHJlYWRzIG5vIG1hdHRlcgoJLy8gaG93IG1hbnkgc3Rha2UgY2hhbmdlcyB0aGUgc3Rha2VyIG1hZGUgc2luY2UgdGhlIHRva2VuJ3MgZmlyc3QgZmVlLgoJbG8sIGhpIDo9IGludDY0KDApLCBldmVudENvdW50Cglmb3IgbG8gPCBoaSB7CgkJbWlkIDo9IGxvICsgKGhpLWxvKS8yCgkJZXZlbnQsIG9rIDo9IHAuR2V0U3Rha2VFdmVudChtaWQpCgkJaWYgIW9rIHsKCQkJYnJlYWsKCQl9CgkJaWYgZXZlbnQuR2V0RXBvY2goKSA8PSB2aWV3LmZpcnN0RXBvY2ggewoJCQlsbyA9IG1pZCArIDEKCQl9IGVsc2UgewoJCQloaSA9IG1pZAoJCX0KCX0KCglpZiBsbyA+IDAgewoJCWlmIGV2ZW50LCBvayA6PSBwLkdldFN0YWtlRXZlbnQobG8gLSAxKTsgb2sgewoJCQlzZXR0bGVtZW50LmV2ZW50Q3Vyc29yID0gbG8KCQkJc2V0dGxlbWVudC5zZWdtZW50U3Rha2VkQW1vdW50ID0gZXZlbnQuR2V0U3Rha2VkQW1vdW50KCkKCQl9Cgl9CgoJcmV0dXJuIHNldHRsZW1lbnQKfQoKLy8gc2V0dGxlRXZlbnRzIGZvbGRzIHVwIHRvIG1heEV2ZW50cyBwZW5kaW5nIHN0YWtlIGV2ZW50cyBpbnRvIHRoZSBzZXR0bGVtZW50LiBBbgovLyBldmVudCBjYW4gb25seSBiZSBmb2xkZWQgb25jZSB0aGUgZXBvY2ggYmVmb3JlIGl0IGlzIGZ1bGx5IGZvbGRlZCBvbiB0aGUKLy8gYWNjdW11bGF0b3IsIGJlY2F1c2UgdGhlIHNlZ21lbnQgaXQgY2xvc2VzIGVuZHMgYXQgdGhhdCBlcG9jaCdzIHZhbHVlLiBBIG1heEV2ZW50cwovLyBvZiB6ZXJvIG9yIGxlc3MgZm9sZHMgZXZlcnkgZXZlbnQgaXQgY2FuLiBSZXR1cm5zIHRydWUgd2hlbiBubyBldmVudCBpcyBsZWZ0IHBlbmRpbmcuCmZ1bmMgKHAgKlByb3RvY29sRmVlUmV3YXJkU3RhdGVSZXNvbHZlcikgc2V0dGxlRXZlbnRzKHNldHRsZW1lbnQgKnByb3RvY29sRmVlVG9rZW5TZXR0bGVtZW50LCB2aWV3ICpwcm90b2NvbEZlZUFjY3VtdWxhdG9yVmlldywgbWF4RXZlbnRzIGludDY0KSBib29sIHsKCWV2ZW50Q291bnQgOj0gcC5HZXRTdGFrZUV2ZW50Q291bnQoKQoJcHJvY2Vzc2VkIDo9IGludDY0KDApCgoJZm9yIHNldHRsZW1lbnQuZXZlbnRDdXJzb3IgPCBldmVudENvdW50IHsKCQlpZiBtYXhFdmVudHMgPiAwICYmIHByb2Nlc3NlZCA+PSBtYXhFdmVudHMgewoJCQlyZXR1cm4gZmFsc2UKCQl9CgoJCWV2ZW50LCBvayA6PSBwLkdldFN0YWtlRXZlbnQoc2V0dGxlbWVudC5ldmVudEN1cnNvcikKCQlpZiAhb2sgewoJCQlyZXR1cm4gZmFsc2UKCQl9CgkJaWYgZXZlbnQuR2V0RXBvY2goKS0xID4gdmlldy5mb2xkZWRFcG9jaCB7CgkJCXJldHVybiBmYWxzZQoJCX0KCgkJc2VnbWVudEVuZFgxMjggOj0gdmlldy5hdChldmVudC5HZXRFcG9jaCgpIC0gMSkKCQlzZXR0bGVtZW50LmVhcm5lZFgxMjggPSB1MjU2Llplcm8oKS5BZGQoCgkJCXNldHRsZW1lbnQuZWFybmVkWDEyOCwKCQkJc2VnbWVudFJld2FyZFgxMjgoc2V0dGxlbWVudC5zZWdtZW50U3Rha2VkQW1vdW50LCBzZXR0bGVtZW50LnNlZ21lbnRTdGFydFgxMjgsIHNlZ21lbnRFbmRYMTI4KSwKCQkpCgkJc2V0dGxlbWVudC5zZWdtZW50U3RhcnRYMTI4ID0gc2VnbWVudEVuZFgxMjguQ2xvbmUoKQoJCXNldHRsZW1lbnQuc2VnbWVudFN0YWtlZEFtb3VudCA9IGV2ZW50LkdldFN0YWtlZEFtb3VudCgpCgkJc2V0dGxlbWVudC5ldmVudEN1cnNvcisrCgkJcHJvY2Vzc2VkKysKCX0KCglyZXR1cm4gdHJ1ZQp9CgovLyBjbG9zZU9wZW5TZWdtZW50IGZvbGRzIHRoZSBvcGVuIHNlZ21lbnQgdXAgdG8gdGhlIGFjY3VtdWxhdG9yJ3MgbGF0ZXN0IHZhbHVlLiBJdCBtYXkKLy8gb25seSBiZSBjYWxsZWQgb25jZSBldmVyeSBzdGFrZSBldmVudCBpcyBzZXR0bGVkLCBzbyB0aGF0IHRoZSBvcGVuIHNlZ21lbnQgcmVhbGx5Ci8vIGVuZHMgYXQgdGhlIHByZXNlbnQuCmZ1bmMgY2xvc2VPcGVuU2VnbWVudChzZXR0bGVtZW50ICpwcm90b2NvbEZlZVRva2VuU2V0dGxlbWVudCwgdmlldyAqcHJvdG9jb2xGZWVBY2N1bXVsYXRvclZpZXcpIHsKCXNldHRsZW1lbnQuZWFybmVkWDEyOCA9IHUyNTYuWmVybygpLkFkZCgKCQlzZXR0bGVtZW50LmVhcm5lZFgxMjgsCgkJc2VnbWVudFJld2FyZFgxMjgoc2V0dGxlbWVudC5zZWdtZW50U3Rha2VkQW1vdW50LCBzZXR0bGVtZW50LnNlZ21lbnRTdGFydFgxMjgsIHZpZXcuY3VycmVudCksCgkpCglzZXR0bGVtZW50LnNlZ21lbnRTdGFydFgxMjggPSB2aWV3LmN1cnJlbnQuQ2xvbmUoKQp9CgovLyB0YWtlUmV3YXJkIHJlbW92ZXMgdGhlIHdob2xlLXVuaXQgcGFydCBvZiB0aGUgZWFybmVkIHJld2FyZCBmcm9tIHRoZSBzZXR0bGVtZW50IGFuZAovLyByZXR1cm5zIGl0LiBUaGUgc3ViLXVuaXQgcmVtYWluZGVyIHN0YXlzIGVhcm5lZCBzbyB0aGF0IG5vIGZlZSBzaGFyZSBpcyBsb3N0LgpmdW5jIHRha2VSZXdhcmQoc2V0dGxlbWVudCAqcHJvdG9jb2xGZWVUb2tlblNldHRsZW1lbnQpIGludDY0IHsKCXJld2FyZFgxMjggOj0gdTI1Ni5aZXJvKCkuUnNoKHNldHRsZW1lbnQuZWFybmVkWDEyOCwgMTI4KQoJcmV3YXJkIDo9IGduc21hdGguU2FmZUNvbnZlcnRUb0ludDY0KHJld2FyZFgxMjgpCglzZXR0bGVtZW50LmVhcm5lZFgxMjggPSB1MjU2Llplcm8oKS5TdWIoc2V0dGxlbWVudC5lYXJuZWRYMTI4LCB1MjU2Llplcm8oKS5Mc2gocmV3YXJkWDEyOCwgMTI4KSkKCglyZXR1cm4gcmV3YXJkCn0KCi8vIHNlZ21lbnRSZXdhcmRYMTI4IHJldHVybnMgc3Rha2VkQW1vdW50IHRpbWVzIHRoZSBhY2N1bXVsYXRvciBncm93dGggYWNyb3NzIGEgc2VnbWVudC4KZnVuYyBzZWdtZW50UmV3YXJkWDEyOChzdGFrZWRBbW91bnQgaW50NjQsIHN0YXJ0WDEyOCwgZW5kWDEyOCAqdTI1Ni5VaW50KSAqdTI1Ni5VaW50IHsKCWlmIHN0YWtlZEFtb3VudCA8PSAwIHx8ICFlbmRYMTI4Lkd0KHN0YXJ0WDEyOCkgewoJCXJldHVybiB1MjU2Llplcm8oKQoJfQoKCWdyb3d0aFgxMjggOj0gdTI1Ni5aZXJvKCkuU3ViKGVuZFgxMjgsIHN0YXJ0WDEyOCkKCglyZXR1cm4gdTI1Ni5aZXJvKCkuTXVsKGdyb3d0aFgxMjgsIHUyNTYuTmV3VWludEZyb21JbnQ2NChzdGFrZWRBbW91bnQpKQp9CgovLyBzdG9yZVRva2VuU2V0dGxlbWVudCB3cml0ZXMgdGhlIHNldHRsZW1lbnQgYmFjayB0byB0aGUgc3Rha2VyJ3Mgc3RhdGUuCmZ1bmMgKHAgKlByb3RvY29sRmVlUmV3YXJkU3RhdGVSZXNvbHZlcikgc3RvcmVUb2tlblNldHRsZW1lbnQodG9rZW5QYXRoIHN0cmluZywgc2V0dGxlbWVudCAqcHJvdG9jb2xGZWVUb2tlblNldHRsZW1lbnQpIHsKCXRva2VuU3RhdGUsIG9rIDo9IHAuR2V0VG9rZW5TdGF0ZSh0b2tlblBhdGgpCglpZiAhb2sgewoJCXRva2VuU3RhdGUgPSBzdGFrZXIuTmV3UHJvdG9jb2xGZWVUb2tlblJld2FyZFN0YXRlKHNldHRsZW1lbnQuZXZlbnRDdXJzb3IsIHNldHRsZW1lbnQuc2VnbWVudFN0YWtlZEFtb3VudCwgc2V0dGxlbWVudC5zZWdtZW50U3RhcnRYMTI4KQoJCXRva2VuU3RhdGUuU2V0RWFybmVkWDEyOChzZXR0bGVtZW50LmVhcm5lZFgxMjgpCgkJcC5TZXRUb2tlblN0YXRlKHRva2VuUGF0aCwgdG9rZW5TdGF0ZSkKCQlyZXR1cm4KCX0KCgl0b2tlblN0YXRlLlNldFNlZ21lbnQoc2V0dGxlbWVudC5ldmVudEN1cnNvciwgc2V0dGxlbWVudC5zZWdtZW50U3Rha2VkQW1vdW50LCBzZXR0bGVtZW50LnNlZ21lbnRTdGFydFgxMjgpCgl0b2tlblN0YXRlLlNldEVhcm5lZFgxMjgoc2V0dGxlbWVudC5lYXJuZWRYMTI4KQp9CgovLyBjbGFpbVRva2VuUmV3YXJkIHNldHRsZXMgdG9rZW5QYXRoIGFuZCByZXR1cm5zIHRoZSByZXdhcmQgY29sbGVjdGVkLgovLwovLyBVcCB0byBtYXhFdmVudHMgc3Rha2UgZXZlbnRzIGFyZSBmb2xkZWQ7IHdoYXRldmVyIGlzIHNldHRsZWQgYnkgdGhlbiBpcyBwYWlkLCBhbmQKLy8gdGhlIHJlc3Qgc3RheXMgcGVuZGluZyBmb3IgYSBsYXRlciBjb2xsZWN0LiBBIG1heEV2ZW50cyBvZiB6ZXJvIG9yIGxlc3MgZm9sZHMKLy8gZXZlcnl0aGluZy4KZnVuYyAocCAqUHJvdG9jb2xGZWVSZXdhcmRTdGF0ZVJlc29sdmVyKSBjbGFpbVRva2VuUmV3YXJkKHRva2VuUGF0aCBzdHJpbmcsIHZpZXcgKnByb3RvY29sRmVlQWNjdW11bGF0b3JWaWV3LCBtYXhFdmVudHMgaW50NjQpIChpbnQ2NCwgZXJyb3IpIHsKCS8vIEEgdG9rZW4gdGhhdCBuZXZlciBjb2xsZWN0ZWQgYSBmZWUgaGFzIG5vdGhpbmcgdG8gc2V0dGxlOyBza2lwcGluZyBpdCBrZWVwcyB0aGUKCS8vIHN0YWtlcidzIHN0YXRlIGZyZWUgb2YgYW4gZW50cnkgcGVyIHRva2VuIG1lcmVseSBxdWVyaWVkLgoJaWYgXywgb2sgOj0gcC5HZXRUb2tlblN0YXRlKHRva2VuUGF0aCk7ICFvayAmJiB2aWV3LmZpcnN0RXBvY2ggPCAwIHsKCQlyZXR1cm4gMCwgbmlsCgl9CgoJc2V0dGxlbWVudCA6PSBwLmxvYWRUb2tlblNldHRsZW1lbnQodG9rZW5QYXRoLCB2aWV3KQoKCWlmIHAuc2V0dGxlRXZlbnRzKHNldHRsZW1lbnQsIHZpZXcsIG1heEV2ZW50cykgewoJCWNsb3NlT3BlblNlZ21lbnQoc2V0dGxlbWVudCwgdmlldykKCX0KCglyZXdhcmQgOj0gdGFrZVJld2FyZChzZXR0bGVtZW50KQoJcC5zdG9yZVRva2VuU2V0dGxlbWVudCh0b2tlblBhdGgsIHNldHRsZW1lbnQpCgoJaWYgcmV3YXJkID4gMCB7CgkJaWYgdG9rZW5TdGF0ZSwgb2sgOj0gcC5HZXRUb2tlblN0YXRlKHRva2VuUGF0aCk7IG9rIHsKCQkJdG9rZW5TdGF0ZS5TZXRDbGFpbWVkUmV3YXJkKGduc21hdGguU2FmZUFkZEludDY0KHRva2VuU3RhdGUuR2V0Q2xhaW1lZFJld2FyZCgpLCByZXdhcmQpKQoJCX0KCX0KCglyZXR1cm4gcmV3YXJkLCBuaWwKfQoKLy8gZ2V0Q2xhaW1hYmxlUmV3YXJkIHJldHVybnMgd2hhdCBhIGNvbGxlY3Qgb2YgdG9rZW5QYXRoIHdvdWxkIHBheSByaWdodCBub3csIHdpdGhvdXQKLy8gY2hhbmdpbmcgYW55IHN0YXRlLgpmdW5jIChwICpQcm90b2NvbEZlZVJld2FyZFN0YXRlUmVzb2x2ZXIpIGdldENsYWltYWJsZVJld2FyZCh0b2tlblBhdGggc3RyaW5nLCB2aWV3ICpwcm90b2NvbEZlZUFjY3VtdWxhdG9yVmlldykgaW50NjQgewoJc2V0dGxlbWVudCA6PSBwLmxvYWRUb2tlblNldHRsZW1lbnQodG9rZW5QYXRoLCB2aWV3KQoKCWlmIHAuc2V0dGxlRXZlbnRzKHNldHRsZW1lbnQsIHZpZXcsIDApIHsKCQljbG9zZU9wZW5TZWdtZW50KHNldHRsZW1lbnQsIHZpZXcpCgl9CgoJcmV0dXJuIGduc21hdGguU2FmZUNvbnZlcnRUb0ludDY0KHUyNTYuWmVybygpLkRpdihzZXR0bGVtZW50LmVhcm5lZFgxMjgsIGNvbnN0cy5RMTI4KCkpKQp9CgovLyBhZGRTdGFrZSBpbmNyZWFzZXMgdGhlIHN0YWtlZCBhbW91bnQgYW5kIHJlY29yZHMgdGhlIGNoYW5nZSBmcm9tIGVwb2NoIG9uLgpmdW5jIChwICpQcm90b2NvbEZlZVJld2FyZFN0YXRlUmVzb2x2ZXIpIGFkZFN0YWtlKGFtb3VudCBpbnQ2NCwgZXBvY2ggaW50NjQpIGVycm9yIHsKCWlmIGFtb3VudCA8PSAwIHsKCQlyZXR1cm4gZXJyb3JzLk5ldyhlcnJBbW91bnRNdXN0QmVQb3NpdGl2ZSkKCX0KCglzdGFrZWRBbW91bnQgOj0gZ25zbWF0aC5TYWZlQWRkSW50NjQocC5HZXRTdGFrZWRBbW91bnQoKSwgYW1vdW50KQoJcC5TZXRTdGFrZWRBbW91bnQoc3Rha2VkQW1vdW50KQoJcC5BcHBlbmRTdGFrZUV2ZW50KGVwb2NoLCBzdGFrZWRBbW91bnQpCgoJcmV0dXJuIG5pbAp9CgovLyByZW1vdmVTdGFrZSBkZWNyZWFzZXMgdGhlIHN0YWtlZCBhbW91bnQgYW5kIHJlY29yZHMgdGhlIGNoYW5nZSBmcm9tIGVwb2NoIG9uLgpmdW5jIChwICpQcm90b2NvbEZlZVJld2FyZFN0YXRlUmVzb2x2ZXIpIHJlbW92ZVN0YWtlKGFtb3VudCBpbnQ2NCwgZXBvY2ggaW50NjQpIGVycm9yIHsKCWlmIGFtb3VudCA8IDAgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyckFtb3VudE11c3RCZU5vbk5lZ2F0aXZlKQoJfQoJaWYgYW1vdW50ID4gcC5HZXRTdGFrZWRBbW91bnQoKSB7CgkJcmV0dXJuIGVycm9ycy5OZXcoZXJyUmVtb3ZlQW1vdW50RXhjZWVkc1N0YWtlZCkKCX0KCglzdGFrZWRBbW91bnQgOj0gZ25zbWF0aC5TYWZlU3ViSW50NjQocC5HZXRTdGFrZWRBbW91bnQoKSwgYW1vdW50KQoJcC5TZXRTdGFrZWRBbW91bnQoc3Rha2VkQW1vdW50KQoJcC5BcHBlbmRTdGFrZUV2ZW50KGVwb2NoLCBzdGFrZWRBbW91bnQpCgoJcmV0dXJuIG5pbAp9CgovLyBJc0NsYWltYWJsZSByZXBvcnRzIHdoZXRoZXIgZXZlcnkgdG9rZW4gbWF5IGJlIGNvbGxlY3RlZCBhdCBvbmNlIGF0IGN1cnJlbnRUaW1lc3RhbXAuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBjdXJyZW50VGltZXN0YW1wOiBjdXJyZW50IFVuaXggdGltZXN0YW1wIHVzZWQgdG8gY29tcGFyZSB0aGUgbGFzdCBjb2xsZWN0aW9uLgovLwovLyBSZXR1cm5zOgovLyAgIC0gYm9vbDogdHJ1ZSB3aGVuIGN1cnJlbnRUaW1lc3RhbXAgaXMgbGF0ZXIgdGhhbiB0aGUgc3RhdGUncyBjbGFpbWVkIHRpbWVzdGFtcC4KZnVuYyAocCAqUHJvdG9jb2xGZWVSZXdhcmRTdGF0ZVJlc29sdmVyKSBJc0NsYWltYWJsZShjdXJyZW50VGltZXN0YW1wIGludDY0KSBib29sIHsKCXJldHVybiBwLkdldENsYWltZWRUaW1lc3RhbXAoKSA8IGN1cnJlbnRUaW1lc3RhbXAKfQoaswgKCnJlbmRlci5nbm8SpAhwYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCSJzdHJpbmdzIgoKCSJnbm8ubGFuZC9wL21vdWwvbWQvdjAiCgkiZ25vLmxhbmQvcC9tb3VsL21kdGFibGUvdjAiCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi9zdGFrZXIiCikKCmZ1bmMgKGcgKmdvdlN0YWtlclYxKSBSZW5kZXIocGF0aCBzdHJpbmcpIHN0cmluZyB7CglpZiBwYXRoICE9ICIiIHsKCQlyZXR1cm4gIjQwNFxuIgoJfQoKCWltcGxlbWVudGF0aW9uIDo9IHN0YWtlci5HZXRJbXBsZW1lbnRhdGlvblBhY2thZ2VQYXRoKCkKCglvdXQgOj0gbWQuSDEoIkdub3N3YXAgR292ZXJuYW5jZSBTdGFrZXIiKQoJb3V0ICs9IG1kLkgyKCJTdGFraW5nIG92ZXJ2aWV3IikKCW92ZXJ2aWV3VGFibGUgOj0gbWR0YWJsZS5UYWJsZXsKCQlIZWFkZXJzOiBbXXN0cmluZ3siRmllbGQiLCAiVmFsdWUifSwKCQlSb3dzOiBbXVtdc3RyaW5newoJCQl7IkFjdGl2ZSBpbXBsZW1lbnRhdGlvbiIsIG1kLkxpbmsoaW1wbGVtZW50YXRpb24sIHN0cmluZ3MuVHJpbVByZWZpeChpbXBsZW1lbnRhdGlvbiwgImduby5sYW5kIikpfSwKCQkJeyJUb3RhbCB4R05TIHN1cHBseSIsIHVmbXQuU3ByaW50ZigiJWQiLCBzdGFrZXIuR2V0VG90YWx4R25zU3VwcGx5KCkpfSwKCQkJeyJUb3RhbCBkZWxlZ2F0ZWQgR05TIiwgdWZtdC5TcHJpbnRmKCIlZCIsIHN0YWtlci5HZXRUb3RhbERlbGVnYXRlZCgpKX0sCgkJCXsiVG90YWwgbG9ja2VkIEdOUyIsIHVmbXQuU3ByaW50ZigiJWQiLCBzdGFrZXIuR2V0VG90YWxMb2NrZWRBbW91bnQoKSl9LAoJCQl7IlVuZGVsZWdhdGlvbiBsb2NrdXAgcGVyaW9kIiwgdWZtdC5TcHJpbnRmKCIlZCIsIHN0YWtlci5HZXRVbkRlbGVnYXRpb25Mb2NrdXBQZXJpb2QoKSl9LAoJCQl7IlByb3RvY29sLWZlZSBhY2N1bXVsYXRpb24gdGltZXN0YW1wIiwgdWZtdC5TcHJpbnRmKCIlZCIsIHN0YWtlci5HZXRQcm90b2NvbEZlZUFjY3VtdWxhdGVkVGltZXN0YW1wKCkpfSwKCQl9LAoJfQoJb3V0ICs9IG92ZXJ2aWV3VGFibGUuU3RyaW5nKCkKCglyZXR1cm4gb3V0Cn0KGv+JAQoTc3Rha2VyX2RlbGVnYXRlLmdubxLmiQFwYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCSJjaGFpbiIKCSJjaGFpbi9ydW50aW1lIgoJImVycm9ycyIKCSJ0aW1lIgoKCWduc21hdGggImduby5sYW5kL3AvZ25vc3dhcC9nbnNtYXRoL3YxIgoJImduby5sYW5kL3AvZ25vc3dhcC91dGlscy92MSIKCSJnbm8ubGFuZC9yL2dub3N3YXAvYWNjZXNzL3YxIgoJImduby5sYW5kL3IvZ25vc3dhcC9lbWlzc2lvbiIKCSJnbm8ubGFuZC9yL2dub3N3YXAvZ25zIgoKCSJnbm8ubGFuZC9yL2dub3N3YXAvZ292L3N0YWtlciIKCSJnbm8ubGFuZC9yL2dub3N3YXAvZ292L3hnbnMiCgkiZ25vLmxhbmQvci9nbm9zd2FwL2hhbHQvdjEiCgkiZ25vLmxhbmQvci9nbm9zd2FwL3JlZmVycmFsL3YxIgopCgovLyBTcG9vZmVkLXJlYWxtIGd1YXJkcyBvbiBlbnRyeSBwb2ludHMgcmVqZWN0IGFueSBjYWxsZXIgdGhhdCBmYWJyaWNhdGVzIGEKLy8gcmVhbG0gdmFsdWUgZGlzdGluY3QgZnJvbSB0aGUgY3VycmVudCBjcm9zc2luZyBmcmFtZS4gVGhlIHByb3h5IGluCi8vIGduby5sYW5kL3IvZ25vc3dhcC9nb3Yvc3Rha2VyIGFsd2F5cyBmb3J3YXJkcyBpdHMgb3duIGBjdXJgLCBzbyBhIG1pc21hdGNoCi8vIGhlcmUgbWVhbnMgc29tZWJvZHkgYnlwYXNzZWQgdGhlIHByb3h5IGFuZCB0aHJlYWRlZCBhIGZha2UgcmVhbG0gZGlyZWN0bHkKLy8gaW50byB0aGUgaW1wbGVtZW50YXRpb24uCgovLyBEZWxlZ2F0ZSBkZWxlZ2F0ZXMgR05TIHRva2VucyB0byBhbiBhZGRyZXNzLgovLwovLyBDb252ZXJ0cyBHTlMgdG8geEdOUyBhbmQgYXNzaWducyB2b3RpbmcgcG93ZXIuCi8vIFByaW1hcnkgbWVjaGFuaXNtIGZvciBwYXJ0aWNpcGF0aW5nIGluIGdvdmVybmFuY2UuCi8vIENhbiBkZWxlZ2F0ZSB0byBzZWxmIG9yIGFueSBvdGhlciBhZGRyZXNzLgovLwovLyBQYXJhbWV0ZXJzOgovLwovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgdW5jaGFuZ2VkIGJ5IHRoZSBnb3Zlcm5hbmNlLXN0YWtlciBwcm94eS4KLy8KLy8gICAtIHRvOiBBZGRyZXNzIHRvIHJlY2VpdmUgdm90aW5nIHBvd2VyIChjYW4gYmUgc2VsZikKLy8KLy8gICAtIGFtb3VudDogQW1vdW50IG9mIEdOUyB0byBzdGFrZSBhbmQgZGVsZWdhdGUKLy8KLy8gICAtIHJlZmVycmVyOiBPcHRpb25hbCByZWZlcnJhbCBhZGRyZXNzIGZvciB0cmFja2luZwovLwovLyBQcm9jZXNzOgovLyAgMS4gVHJhbnNmZXJzIEdOUyBmcm9tIGNhbGxlcgovLyAgMi4gTWludHMgZXF1aXZhbGVudCB4R05TICgxOjEgcmF0aW8pCi8vICAzLiBBc3NpZ25zIHZvdGluZyBwb3dlciB0byB0YXJnZXQgYWRkcmVzcwovLyAgNC4gQ3JlYXRlcyBkZWxlZ2F0aW9uIHNuYXBzaG90IGZvciB2b3RpbmcKLy8KLy8gUmVxdWlyZW1lbnRzOgovLyAgIC0gTWluaW11bSAxIEdOUyBkZWxlZ2F0aW9uCi8vICAgLSBWYWxpZCB0YXJnZXQgYWRkcmVzcwovLyAgIC0gU3VmZmljaWVudCBHTlMgYmFsYW5jZQovLyAgIC0gQXBwcm92YWwgZm9yIEdOUyB0cmFuc2ZlcgovLwovLyBSZXR1cm5zOgovLyAgIC0gZGVsZWdhdGVkQW1vdW50OiBhbW91bnQgb2YgR05TIGRlbGVnYXRlZCBhbmQgbWlycm9yZWQgYXMgeEdOUwpmdW5jIChncyAqZ292U3Rha2VyVjEpIERlbGVnYXRlKAoJXyBpbnQsCglybG0gcmVhbG0sCgl0byBhZGRyZXNzLAoJYW1vdW50IGludDY0LAoJcmVmZXJyZXIgc3RyaW5nLAopIGludDY0IHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRHb3ZTdGFrZXIoKQoKCXByZXYgOj0gcmxtLlByZXZpb3VzKCkKCWFjY2Vzcy5Bc3NlcnRJc1ZhbGlkQWRkcmVzcyh0bykKCglhc3NlcnRJc1ZhbGlkRGVsZWdhdGVBbW91bnQoYW1vdW50KQoKCWNhbGxlciA6PSBwcmV2LkFkZHJlc3MoKQoJZnJvbSA6PSBjYWxsZXIKCWN1cnJlbnRIZWlnaHQgOj0gcnVudGltZS5DaGFpbkhlaWdodCgpCgljdXJyZW50VGltZXN0YW1wIDo9IHRpbWUuTm93KCkuVW5peCgpCgoJZW1pc3Npb24uTWludEFuZERpc3RyaWJ1dGVHbnMoY3Jvc3MocmxtKSkKCglkZWxlZ2F0aW9uLCBlcnIgOj0gZ3MuZGVsZWdhdGUoCgkJMCwKCQlybG0sCgkJZnJvbSwKCQl0bywKCQlhbW91bnQsCgkJY3VycmVudEhlaWdodCwKCQljdXJyZW50VGltZXN0YW1wLAoJKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCWlmIGVyciA6PSBncy5pbmNyZWFzZVRvdGFsRGVsZWdhdGVkQW1vdW50KDAsIHJsbSwgYW1vdW50KTsgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoJaWYgZXJyIDo9IGdzLmluY3JlYXNlVG90YWxMb2NrZWRBbW91bnQoMCwgcmxtLCBhbW91bnQpOyBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJZ25zLlRyYW5zZmVyRnJvbShjcm9zcyhybG0pLCBmcm9tLCBybG0uQWRkcmVzcygpLCBhbW91bnQpCgl4Z25zLk1pbnQoY3Jvc3MocmxtKSwgZnJvbSwgYW1vdW50KQoKCXJlZ2lzdGVyZWRSZWZlcnJlciA6PSByZWZlcnJhbC5UcnlSZWdpc3Rlcihjcm9zcyhybG0pLCBjYWxsZXIsIHJlZmVycmVyKQoKCXJlc29sdmVyIDo9IE5ld0RlbGVnYXRpb25SZXNvbHZlcihkZWxlZ2F0aW9uKQoKCWNoYWluLkVtaXQoCgkJIkRlbGVnYXRlIiwKCQkicHJldkFkZHIiLCBwcmV2LkFkZHJlc3MoKS5TdHJpbmcoKSwKCQkicHJldlJlYWxtIiwgcHJldi5Qa2dQYXRoKCksCgkJImZyb20iLCByZXNvbHZlci5kZWxlZ2F0aW9uLkRlbGVnYXRlRnJvbSgpLlN0cmluZygpLAoJCSJ0byIsIHJlc29sdmVyLmRlbGVnYXRpb24uRGVsZWdhdGVUbygpLlN0cmluZygpLAoJCSJhbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQocmVzb2x2ZXIuRGVsZWdhdGVkQW1vdW50KCkpLAoJCSJ0b3RhbERlbGVnYXRlZEFtb3VudCIsIHV0aWxzLkZvcm1hdEludChncy5zdG9yZS5HZXRUb3RhbERlbGVnYXRlZEFtb3VudCgpKSwKCQkicmVmZXJyZXIiLCByZWdpc3RlcmVkUmVmZXJyZXIsCgkpCgoJcmV0dXJuIGFtb3VudAp9CgovLyBVbmRlbGVnYXRlIHVuZGVsZWdhdGVzIHhHTlMgZnJvbSB0aGUgZXhpc3RpbmcgZGVsZWdhdGUuCi8vCi8vIEluaXRpYXRlcyB3aXRoZHJhd2FsIG9mIHN0YWtlZCBHTlMgd2l0aCBsb2NrdXAgcGVyaW9kLgovLyBWb3RpbmcgcG93ZXIgcmVtb3ZlZCBpbW1lZGlhdGVseSwgdG9rZW5zIGxvY2tlZCBmb3IgY29uZmlndXJhYmxlIHBlcmlvZC4KLy8gUHJldmVudHMgZ292ZXJuYW5jZSBhdHRhY2tzIHRocm91Z2ggdGltZSBkZWxheS4KLy8KLy8gUGFyYW1ldGVyczoKLy8KLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLwovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIHVuY2hhbmdlZCBieSB0aGUgZ292ZXJuYW5jZS1zdGFrZXIgcHJveHkuCi8vCi8vICAgLSBmcm9tOiBBZGRyZXNzIGN1cnJlbnRseSBkZWxlZ2F0ZWQgdG8KLy8KLy8gICAtIGFtb3VudDogQW1vdW50IG9mIHhHTlMgdG8gdW5kZWxlZ2F0ZQovLwovLyBQcm9jZXNzOgovLyAgMS4gUmVtb3ZlcyB2b3RpbmcgcG93ZXIgaW1tZWRpYXRlbHkKLy8gIDIuIENyZWF0ZXMgd2l0aGRyYXdhbCByZXF1ZXN0IHdpdGggdGltZXN0YW1wCi8vICAzLiBMb2NrcyBHTlMgZm9yIGNvbmZpZ3VyYWJsZSBjb29sZG93biBwZXJpb2QKLy8KLy8gUmVxdWlyZW1lbnRzOgovLyAgIC0gTXVzdCBoYXZlIGRlbGVnYXRlZCB0byB0YXJnZXQgYWRkcmVzcwovLyAgIC0gU3VmZmljaWVudCBkZWxlZ2F0ZWQgYW1vdW50Ci8vCi8vIEFmdGVyIGxvY2t1cCBwZXJpb2QgZW5kcywgdXNlIENvbGxlY3RVbmRlbGVnYXRlZEducygpIHRvIGNsYWltIEdOUy4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHVuZGVsZWdhdGVkQW1vdW50OiBhbW91bnQgbW92ZWQgb3V0IG9mIGFjdGl2ZSBkZWxlZ2F0aW9uIGludG8gdW5kZWxlZ2F0aW9uIGxvY2t1cApmdW5jIChncyAqZ292U3Rha2VyVjEpIFVuZGVsZWdhdGUoCglfIGludCwKCXJsbSByZWFsbSwKCWZyb20gYWRkcmVzcywKCWFtb3VudCBpbnQ2NCwKKSBpbnQ2NCB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCgloYWx0LkFzc2VydElzTm90SGFsdGVkV2l0aGRyYXcoKQoKCXByZXYgOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2LkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzVmFsaWRBZGRyZXNzKGZyb20pCgoJYXNzZXJ0SXNWYWxpZERlbGVnYXRlQW1vdW50KGFtb3VudCkKCgljdXJyZW50SGVpZ2h0IDo9IHJ1bnRpbWUuQ2hhaW5IZWlnaHQoKQoJY3VycmVudFRpbWVzdGFtcCA6PSB0aW1lLk5vdygpLlVuaXgoKQoKCWVtaXNzaW9uLk1pbnRBbmREaXN0cmlidXRlR25zKGNyb3NzKHJsbSkpCgoJdW5EZWxlZ2F0aW9uQW1vdW50LCBlcnIgOj0gZ3MudW5EZWxlZ2F0ZSgKCQkwLAoJCXJsbSwKCQljYWxsZXIsCgkJZnJvbSwKCQlhbW91bnQsCgkJY3VycmVudEhlaWdodCwKCQljdXJyZW50VGltZXN0YW1wLAoJKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCWlmIGVyciA6PSBncy5kZWNyZWFzZVRvdGFsRGVsZWdhdGVkQW1vdW50KDAsIHJsbSwgdW5EZWxlZ2F0aW9uQW1vdW50KTsgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCWNoYWluLkVtaXQoCgkJIlVuZGVsZWdhdGUiLAoJCSJwcmV2QWRkciIsIHByZXYuQWRkcmVzcygpLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2LlBrZ1BhdGgoKSwKCQkiZnJvbSIsIGNhbGxlci5TdHJpbmcoKSwKCQkidG8iLCBmcm9tLlN0cmluZygpLAoJCSJhbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQodW5EZWxlZ2F0aW9uQW1vdW50KSwKCQkidG90YWxEZWxlZ2F0ZWRBbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQoZ3Muc3RvcmUuR2V0VG90YWxEZWxlZ2F0ZWRBbW91bnQoKSksCgkpCgoJcmV0dXJuIHVuRGVsZWdhdGlvbkFtb3VudAp9CgovLyBSZWRlbGVnYXRlIHJlZGVsZWdhdGVzIHhHTlMgZnJvbSBhbiBleGlzdGluZyBkZWxlZ2F0ZSB0byBhbm90aGVyLgovLwovLyBBdG9taWMgb3BlcmF0aW9uIHRvIGNoYW5nZSBkZWxlZ2F0aW9uIHRhcmdldC4KLy8gTWFpbnRhaW5zIHZvdGluZyBwb3dlciBjb250aW51aXR5IHdpdGhvdXQgdW5zdGFraW5nLgovLyBVc2VmdWwgZm9yIHZvdGUgZGVsZWdhdGlvbiBzZXJ2aWNlcyBhbmQgREFPIGNvb3JkaW5hdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8KLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLwovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIHVuY2hhbmdlZCBieSB0aGUgZ292ZXJuYW5jZS1zdGFrZXIgcHJveHkuCi8vCi8vICAgLSBkZWxlZ2F0ZWU6IEN1cnJlbnQgYWRkcmVzcyBkZWxlZ2F0ZWQgdG8KLy8KLy8gICAtIG5ld0RlbGVnYXRlZTogTmV3IGFkZHJlc3MgdG8gZGVsZWdhdGUgdG8KLy8KLy8gICAtIGFtb3VudDogQW1vdW50IG9mIHhHTlMgdG8gcmVkZWxlZ2F0ZQovLwovLyBQcm9jZXNzOgovLyAgMS4gVmFsaWRhdGVzIGN1cnJlbnQgZGVsZWdhdGlvbiBleGlzdHMKLy8gIDIuIFJlbW92ZXMgdm90aW5nIHBvd2VyIGZyb20gdGhlIG9sZCBkZWxlZ2F0ZWUgd2l0aG91dCBhIGxvY2t1cAovLyAgMy4gQXNzaWducyB0aGUgc2FtZSBhbW91bnQgdG8gdGhlIG5ldyBkZWxlZ2F0ZWUKLy8gIDQuIFVwZGF0ZXMgZGVsZWdhdGlvbiBoaXN0b3J5IGFuZCByZXdhcmQgc3Rha2UgZXZlbnRzCi8vCi8vIFJlcXVpcmVtZW50czoKLy8gICAtIE11c3QgaGF2ZSBhY3RpdmUgZGVsZWdhdGlvbiB0byBjdXJyZW50IGRlbGVnYXRlZQovLyAgIC0gQm90aCBhZGRyZXNzZXMgbXVzdCBiZSB2YWxpZAovLyAgIC0gQW1vdW50IG11c3Qgbm90IGV4Y2VlZCBjdXJyZW50IGRlbGVnYXRpb24KLy8gICAtIENhbm5vdCByZWRlbGVnYXRlIHRvIHNhbWUgYWRkcmVzcwovLwovLyBObyB1c2VyLWZhY2luZyBsb2NrdXAgcGVyaW9kOyByZXdhcmQgYWNjb3VudGluZyByZWNvcmRzIG9uZSByZW1vdmFsIGFuZCBvbmUKLy8gYWRkaXRpb24gYWNyb3NzIHRoZSBjb3JyZXNwb25kaW5nIGFjY3J1YWwgZXBvY2hzLgovLwovLyBSZXR1cm5zOgovLyAgIC0gcmVkZWxlZ2F0ZWRBbW91bnQ6IGFtb3VudCBtb3ZlZCBmcm9tIHRoZSBjdXJyZW50IGRlbGVnYXRlZSB0byB0aGUgbmV3IGRlbGVnYXRlZQpmdW5jIChncyAqZ292U3Rha2VyVjEpIFJlZGVsZWdhdGUoCglfIGludCwKCXJsbSByZWFsbSwKCWRlbGVnYXRlZSwKCW5ld0RlbGVnYXRlZSBhZGRyZXNzLAoJYW1vdW50IGludDY0LAopIGludDY0IHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRHb3ZTdGFrZXIoKQoKCXByZXYgOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2LkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzVmFsaWRBZGRyZXNzKGRlbGVnYXRlZSkKCWFjY2Vzcy5Bc3NlcnRJc1ZhbGlkQWRkcmVzcyhuZXdEZWxlZ2F0ZWUpCgoJYXNzZXJ0SXNWYWxpZERlbGVnYXRlQW1vdW50KGFtb3VudCkKCWFzc2VydE5vU2FtZURlbGVnYXRlZShkZWxlZ2F0ZWUsIG5ld0RlbGVnYXRlZSkKCgljdXJyZW50SGVpZ2h0IDo9IHJ1bnRpbWUuQ2hhaW5IZWlnaHQoKQoJY3VycmVudFRpbWVzdGFtcCA6PSB0aW1lLk5vdygpLlVuaXgoKQoJZGVsZWdhdG9yIDo9IGNhbGxlcgoKCWVtaXNzaW9uLk1pbnRBbmREaXN0cmlidXRlR25zKGNyb3NzKHJsbSkpCgoJdW5EZWxlZ2F0aW9uQW1vdW50LCBlcnIgOj0gZ3MudW5EZWxlZ2F0ZVdpdGhvdXRMb2NrdXAoCgkJMCwKCQlybG0sCgkJZGVsZWdhdG9yLAoJCWRlbGVnYXRlZSwKCQlhbW91bnQsCgkJY3VycmVudEhlaWdodCwKCQljdXJyZW50VGltZXN0YW1wLAoJKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCWRlbGVnYXRpb24sIGVyciA6PSBncy5kZWxlZ2F0ZSgKCQkwLAoJCXJsbSwKCQlkZWxlZ2F0b3IsCgkJbmV3RGVsZWdhdGVlLAoJCXVuRGVsZWdhdGlvbkFtb3VudCwKCQljdXJyZW50SGVpZ2h0LAoJCWN1cnJlbnRUaW1lc3RhbXAsCgkpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJcmVzb2x2ZXIgOj0gTmV3RGVsZWdhdGlvblJlc29sdmVyKGRlbGVnYXRpb24pCgljaGFpbi5FbWl0KAoJCSJSZWRlbGVnYXRlIiwKCQkicHJldkFkZHIiLCBwcmV2LkFkZHJlc3MoKS5TdHJpbmcoKSwKCQkicHJldlJlYWxtIiwgcHJldi5Qa2dQYXRoKCksCgkJImZyb20iLCBkZWxlZ2F0b3IuU3RyaW5nKCksCgkJInByZXZpb3VzRGVsZWdhdGVlIiwgZGVsZWdhdGVlLlN0cmluZygpLAoJCSJuZXdEZWxlZ2F0ZWUiLCBuZXdEZWxlZ2F0ZWUuU3RyaW5nKCksCgkJImFtb3VudCIsIHV0aWxzLkZvcm1hdEludChyZXNvbHZlci5EZWxlZ2F0ZWRBbW91bnQoKSksCgkpCgoJcmV0dXJuIGFtb3VudAp9CgovLyBDb2xsZWN0VW5kZWxlZ2F0ZWRHbnMgY29sbGVjdHMgdW5kZWxlZ2F0ZWQgR05TIHRva2Vucy4KLy8gQWxsb3dzIHVzZXJzIHRvIGNvbGxlY3QgR05TIHRva2VucyB0aGF0IGNvbXBsZXRlZCB1bmRlbGVnYXRpb24gbG9ja3VwIHBlcmlvZC4KLy8gQnVybnMgeEdOUyBhbmQgcmV0dXJucyBHTlMgdG9rZW5zLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgdW5jaGFuZ2VkIGJ5IHRoZSBnb3Zlcm5hbmNlLXN0YWtlciBwcm94eS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGNvbGxlY3RlZEFtb3VudDogYW1vdW50IG9mIHVuZGVsZWdhdGVkIEdOUyByZWxlYXNlZCB0byB0aGUgY2FsbGVyIGFmdGVyIGxvY2t1cCBleHBpcnkKZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBDb2xsZWN0VW5kZWxlZ2F0ZWRHbnMoXyBpbnQsIHJsbSByZWFsbSkgaW50NjQgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFdpdGhkcmF3KCkKCglwcmV2IDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXIgOj0gcHJldi5BZGRyZXNzKCkKCWN1cnJlbnRUaW1lIDo9IHRpbWUuTm93KCkuVW5peCgpCgoJZW1pc3Npb24uTWludEFuZERpc3RyaWJ1dGVHbnMoY3Jvc3MocmxtKSkKCgljb2xsZWN0ZWRBbW91bnQsIGVyciA6PSBncy5jb2xsZWN0RGVsZWdhdGlvbnMoMCwgcmxtLCBjYWxsZXIsIGN1cnJlbnRUaW1lKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCWlmIGNvbGxlY3RlZEFtb3VudCA9PSAwIHsKCQlyZXR1cm4gMAoJfQoKCWlmIGVyciA6PSBncy5kZWNyZWFzZVRvdGFsTG9ja2VkQW1vdW50KDAsIHJsbSwgY29sbGVjdGVkQW1vdW50KTsgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCXhnbnMuQnVybihjcm9zcyhybG0pLCBjYWxsZXIsIGNvbGxlY3RlZEFtb3VudCkKCWducy5UcmFuc2Zlcihjcm9zcyhybG0pLCBjYWxsZXIsIGNvbGxlY3RlZEFtb3VudCkKCgljaGFpbi5FbWl0KAoJCSJDb2xsZWN0VW5kZWxlZ2F0ZWRHbnMiLAoJCSJwcmV2QWRkciIsIHByZXYuQWRkcmVzcygpLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2LlBrZ1BhdGgoKSwKCQkiZnJvbSIsIHByZXYuQWRkcmVzcygpLlN0cmluZygpLAoJCSJ0byIsIGNhbGxlci5TdHJpbmcoKSwKCQkiY29sbGVjdGVkQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KGNvbGxlY3RlZEFtb3VudCksCgkpCgoJcmV0dXJuIGNvbGxlY3RlZEFtb3VudAp9CgovLyBkZWxlZ2F0ZSBwcm9jZXNzZXMgZGVsZWdhdGlvbiBvcGVyYXRpb25zLgovLyBWYWxpZGF0ZXMgZGVsZWdhdGlvbiBhbW91bnQsIGNyZWF0ZXMgZGVsZWdhdGlvbiByZWNvcmRzLCBhbmQgdXBkYXRlcyByZXdhcmQgdHJhY2tpbmcuCmZ1bmMgKGdzICpnb3ZTdGFrZXJWMSkgZGVsZWdhdGUoCglfIGludCwKCXJsbSByZWFsbSwKCWZyb20gYWRkcmVzcywKCXRvIGFkZHJlc3MsCglhbW91bnQsCgljdXJyZW50SGVpZ2h0LAoJY3VycmVudFRpbWVzdGFtcCBpbnQ2NCwKKSAoKnN0YWtlci5EZWxlZ2F0aW9uLCBlcnJvcikgewoJZGVsZWdhdGlvbklEIDo9IGdzLm5leHREZWxlZ2F0aW9uSUQoKQoJZGVsZWdhdGlvbiA6PSBzdGFrZXIuTmV3RGVsZWdhdGlvbigKCQlkZWxlZ2F0aW9uSUQsCgkJZnJvbSwKCQl0bywKCQlhbW91bnQsCgkJY3VycmVudEhlaWdodCwKCQljdXJyZW50VGltZXN0YW1wLAoJKQoJZGVsZWdhdGlvblJlc29sdmVyIDo9IE5ld0RlbGVnYXRpb25SZXNvbHZlcihkZWxlZ2F0aW9uKQoJZGVsZWdhdGVkQW1vdW50IDo9IGRlbGVnYXRpb25SZXNvbHZlci5EZWxlZ2F0ZWRBbW91bnQoKQoJaWYgZGVsZWdhdGVkQW1vdW50IDwgMCB7CgkJcmV0dXJuIG5pbCwgZXJyb3JzLk5ldyhlcnJEZWxlZ2F0ZWRBbW91bnROZWdhdGl2ZSkKCX0KCglpZiBlcnIgOj0gZ3MuYWRkRGVsZWdhdGlvbigwLCBybG0sIGRlbGVnYXRpb25JRCwgZGVsZWdhdGlvbik7IGVyciAhPSBuaWwgewoJCXJldHVybiBuaWwsIGVycgoJfQoJZ3MuYWRkRGVsZWdhdGlvblJlY29yZCgwLCBybG0sIHRvLCBkZWxlZ2F0ZWRBbW91bnQsIGN1cnJlbnRUaW1lc3RhbXApCglpZiBlcnIgOj0gZ3MuYWRkU3Rha2VFbWlzc2lvblJld2FyZCgwLCBybG0sIGZyb20uU3RyaW5nKCksIGFtb3VudCwgY3VycmVudFRpbWVzdGFtcCk7IGVyciAhPSBuaWwgewoJCXJldHVybiBuaWwsIGVycgoJfQoJaWYgZXJyIDo9IGdzLmFkZFN0YWtlUHJvdG9jb2xGZWVSZXdhcmQoMCwgcmxtLCBmcm9tLlN0cmluZygpLCBhbW91bnQsIGN1cnJlbnRUaW1lc3RhbXApOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBlcnIKCX0KCglyZXR1cm4gZGVsZWdhdGlvbiwgbmlsCn0KCi8vIHVuRGVsZWdhdGUgcHJvY2Vzc2VzIHVuZGVsZWdhdGlvbiBvcGVyYXRpb25zIHdpdGggbG9ja3VwLgovLyBWYWxpZGF0ZXMgdW5kZWxlZ2F0aW9uIGFtb3VudCwgcHJvY2Vzc2VzIHdpdGhkcmF3YWxzLCBhbmQgdXBkYXRlcyByZXdhcmQgdHJhY2tpbmcuCmZ1bmMgKGdzICpnb3ZTdGFrZXJWMSkgdW5EZWxlZ2F0ZSgKCV8gaW50LAoJcmxtIHJlYWxtLAoJZGVsZWdhdG9yLAoJZGVsZWdhdGVlIGFkZHJlc3MsCglhbW91bnQsCgljdXJyZW50SGVpZ2h0LAoJY3VycmVudFRpbWVzdGFtcCBpbnQ2NCwKKSAoaW50NjQsIGVycm9yKSB7CglkZWxlZ2F0aW9uSURzIDo9IGdzLmdldFVzZXJEZWxlZ2F0aW9uSURzV2l0aERlbGVnYXRlZShkZWxlZ2F0b3IsIGRlbGVnYXRlZSkKCWlmIGxlbihkZWxlZ2F0aW9uSURzKSA9PSAwIHsKCQlyZXR1cm4gMCwgbmlsCgl9CgoJdW5EZWxlZ2F0aW9uQW1vdW50IDo9IGFtb3VudAoJbG9ja3VwUGVyaW9kIDo9IGdzLnN0b3JlLkdldFVuRGVsZWdhdGlvbkxvY2t1cFBlcmlvZCgpCgl0b3RhbERlbGVnYXRlZCA6PSBpbnQ2NCgwKQoJZGVsZWdhdGlvbnMgOj0gbWFrZShbXSpzdGFrZXIuRGVsZWdhdGlvbiwgMCwgbGVuKGRlbGVnYXRpb25JRHMpKQoKCWZvciBfLCBpZCA6PSByYW5nZSBkZWxlZ2F0aW9uSURzIHsKCQlkZWxlZ2F0aW9uLCBleGlzdHMgOj0gZ3Muc3RvcmUuR2V0RGVsZWdhdGlvbihpZCkKCQlpZiAhZXhpc3RzIHsKCQkJY29udGludWUKCQl9CgoJCXRvdGFsRGVsZWdhdGVkID0gZ25zbWF0aC5TYWZlQWRkSW50NjQodG90YWxEZWxlZ2F0ZWQsIE5ld0RlbGVnYXRpb25SZXNvbHZlcihkZWxlZ2F0aW9uKS5EZWxlZ2F0ZWRBbW91bnQoKSkKCQlkZWxlZ2F0aW9ucyA9IGFwcGVuZChkZWxlZ2F0aW9ucywgZGVsZWdhdGlvbikKCX0KCglpZiBhbW91bnQgPiB0b3RhbERlbGVnYXRlZCB7CgkJcmV0dXJuIDAsIGVycm9ycy5OZXcoZXJyTm90RW5vdWdoRGVsZWdhdGVkKQoJfQoKCS8vIFByb2Nlc3MgdW5kZWxlZ2F0aW9uIGFjcm9zcyBtdWx0aXBsZSBkZWxlZ2F0aW9uIHJlY29yZHMgaWYgbmVjZXNzYXJ5Cglmb3IgXywgZGVsZWdhdGlvbiA6PSByYW5nZSBkZWxlZ2F0aW9ucyB7CgkJcmVzb2x2ZXIgOj0gTmV3RGVsZWdhdGlvblJlc29sdmVyKGRlbGVnYXRpb24pCgkJaWYgcmVzb2x2ZXIuSXNFbXB0eSgpIHsKCQkJaWYgZXJyIDo9IGdzLnJlbW92ZURlbGVnYXRpb24oMCwgcmxtLCBkZWxlZ2F0aW9uLklEKCkpOyBlcnIgIT0gbmlsIHsKCQkJCXJldHVybiAwLCBlcnIKCQkJfQoJCQljb250aW51ZQoJCX0KCgkJY3VycmVudFVuRGVsZWdhdGlvbkFtb3VudCA6PSB1bkRlbGVnYXRpb25BbW91bnQKCgkJaWYgY3VycmVudFVuRGVsZWdhdGlvbkFtb3VudCA+IHJlc29sdmVyLkRlbGVnYXRlZEFtb3VudCgpIHsKCQkJY3VycmVudFVuRGVsZWdhdGlvbkFtb3VudCA9IHJlc29sdmVyLkRlbGVnYXRlZEFtb3VudCgpCgkJfQoKCQlpZiBjdXJyZW50VW5EZWxlZ2F0aW9uQW1vdW50IDwgMCB7CgkJCXJldHVybiAwLCBlcnJvcnMuTmV3KGVyclVuZGVsZWdhdGlvbkFtb3VudE5lZ2F0aXZlKQoJCX0KCgkJaWYgY3VycmVudFVuRGVsZWdhdGlvbkFtb3VudCA9PSAwIHsKCQkJY29udGludWUKCQl9CgoJCXJlc29sdmVyLlVuRGVsZWdhdGUoCgkJCWN1cnJlbnRVbkRlbGVnYXRpb25BbW91bnQsCgkJCWN1cnJlbnRIZWlnaHQsCgkJCWN1cnJlbnRUaW1lc3RhbXAsCgkJCWxvY2t1cFBlcmlvZCwKCQkpCgoJCWlmIGVyciA6PSBncy5zZXREZWxlZ2F0aW9uKDAsIHJsbSwgZGVsZWdhdGlvbi5JRCgpLCBkZWxlZ2F0aW9uKTsgZXJyICE9IG5pbCB7CgkJCXJldHVybiAwLCBlcnIKCQl9CgkJZ3MuYWRkRGVsZWdhdGlvblJlY29yZCgwLCBybG0sIGRlbGVnYXRlZSwgLWN1cnJlbnRVbkRlbGVnYXRpb25BbW91bnQsIGN1cnJlbnRUaW1lc3RhbXApCgkJaWYgZXJyIDo9IGdzLnJlbW92ZVN0YWtlRW1pc3Npb25SZXdhcmQoMCwgcmxtLCBkZWxlZ2F0b3IuU3RyaW5nKCksIGN1cnJlbnRVbkRlbGVnYXRpb25BbW91bnQsIGN1cnJlbnRUaW1lc3RhbXApOyBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIDAsIGVycgoJCX0KCQlpZiBlcnIgOj0gZ3MucmVtb3ZlU3Rha2VQcm90b2NvbEZlZVJld2FyZCgwLCBybG0sIGRlbGVnYXRvci5TdHJpbmcoKSwgY3VycmVudFVuRGVsZWdhdGlvbkFtb3VudCwgY3VycmVudFRpbWVzdGFtcCk7IGVyciAhPSBuaWwgewoJCQlyZXR1cm4gMCwgZXJyCgkJfQoKCQl1bkRlbGVnYXRpb25BbW91bnQgPSBnbnNtYXRoLlNhZmVTdWJJbnQ2NCh1bkRlbGVnYXRpb25BbW91bnQsIGN1cnJlbnRVbkRlbGVnYXRpb25BbW91bnQpCgkJaWYgdW5EZWxlZ2F0aW9uQW1vdW50IDw9IDAgewoJCQlicmVhawoJCX0KCX0KCglyZXR1cm4gYW1vdW50LCBuaWwKfQoKLy8gdW5EZWxlZ2F0ZVdpdGhvdXRMb2NrdXAgcHJvY2Vzc2VzIHVuZGVsZWdhdGlvbiB3aXRob3V0IGxvY2t1cC4KLy8gVXNlZCBmb3IgcmVkZWxlZ2F0aW9uIHdoZXJlIHRva2VucyBhcmUgaW1tZWRpYXRlbHkgYXZhaWxhYmxlLgpmdW5jIChncyAqZ292U3Rha2VyVjEpIHVuRGVsZWdhdGVXaXRob3V0TG9ja3VwKAoJXyBpbnQsCglybG0gcmVhbG0sCglkZWxlZ2F0b3IsCglkZWxlZ2F0ZWUgYWRkcmVzcywKCWFtb3VudCwKCWN1cnJlbnRIZWlnaHQsCgljdXJyZW50VGltZSBpbnQ2NCwKKSAoaW50NjQsIGVycm9yKSB7CglkZWxlZ2F0aW9uSURzIDo9IGdzLmdldFVzZXJEZWxlZ2F0aW9uSURzV2l0aERlbGVnYXRlZShkZWxlZ2F0b3IsIGRlbGVnYXRlZSkKCWlmIGxlbihkZWxlZ2F0aW9uSURzKSA9PSAwIHsKCQlyZXR1cm4gMCwgZXJyb3JzLk5ldyhlcnJOb3RFbm91Z2hEZWxlZ2F0ZWQpCgl9CgoJdW5EZWxlZ2F0aW9uQW1vdW50IDo9IGFtb3VudAoJdG90YWxEZWxlZ2F0ZWQgOj0gaW50NjQoMCkKCWRlbGVnYXRpb25zIDo9IG1ha2UoW10qc3Rha2VyLkRlbGVnYXRpb24sIDAsIGxlbihkZWxlZ2F0aW9uSURzKSkKCglmb3IgXywgaWQgOj0gcmFuZ2UgZGVsZWdhdGlvbklEcyB7CgkJZGVsZWdhdGlvbiwgZXhpc3RzIDo9IGdzLnN0b3JlLkdldERlbGVnYXRpb24oaWQpCgkJaWYgIWV4aXN0cyB7CgkJCWNvbnRpbnVlCgkJfQoKCQl0b3RhbERlbGVnYXRlZCA9IGduc21hdGguU2FmZUFkZEludDY0KHRvdGFsRGVsZWdhdGVkLCBOZXdEZWxlZ2F0aW9uUmVzb2x2ZXIoZGVsZWdhdGlvbikuRGVsZWdhdGVkQW1vdW50KCkpCgkJZGVsZWdhdGlvbnMgPSBhcHBlbmQoZGVsZWdhdGlvbnMsIGRlbGVnYXRpb24pCgl9CgoJaWYgYW1vdW50ID4gdG90YWxEZWxlZ2F0ZWQgewoJCXJldHVybiAwLCBlcnJvcnMuTmV3KGVyck5vdEVub3VnaERlbGVnYXRlZCkKCX0KCgkvLyBQcm9jZXNzIHVuZGVsZWdhdGlvbiBhY3Jvc3MgbXVsdGlwbGUgZGVsZWdhdGlvbiByZWNvcmRzIGlmIG5lY2Vzc2FyeQoJZm9yIF8sIGRlbGVnYXRpb24gOj0gcmFuZ2UgZGVsZWdhdGlvbnMgewoJCXJlc29sdmVyIDo9IE5ld0RlbGVnYXRpb25SZXNvbHZlcihkZWxlZ2F0aW9uKQoJCWlmIHJlc29sdmVyLklzRW1wdHkoKSB7CgkJCWlmIGVyciA6PSBncy5yZW1vdmVEZWxlZ2F0aW9uKDAsIHJsbSwgZGVsZWdhdGlvbi5JRCgpKTsgZXJyICE9IG5pbCB7CgkJCQlyZXR1cm4gMCwgZXJyCgkJCX0KCQkJY29udGludWUKCQl9CgoJCWN1cnJlbnRVbkRlbGVnYXRpb25BbW91bnQgOj0gdW5EZWxlZ2F0aW9uQW1vdW50CgoJCWlmIGN1cnJlbnRVbkRlbGVnYXRpb25BbW91bnQgPiByZXNvbHZlci5EZWxlZ2F0ZWRBbW91bnQoKSB7CgkJCWN1cnJlbnRVbkRlbGVnYXRpb25BbW91bnQgPSByZXNvbHZlci5EZWxlZ2F0ZWRBbW91bnQoKQoJCX0KCgkJaWYgY3VycmVudFVuRGVsZWdhdGlvbkFtb3VudCA9PSAwIHsKCQkJY29udGludWUKCQl9CgoJCXJlc29sdmVyLlVuRGVsZWdhdGVXaXRob3V0TG9ja3VwKAoJCQljdXJyZW50VW5EZWxlZ2F0aW9uQW1vdW50LAoJCQljdXJyZW50SGVpZ2h0LAoJCQljdXJyZW50VGltZSwKCQkpCgoJCWlmIHJlc29sdmVyLklzRW1wdHkoKSB7CgkJCWlmIGVyciA6PSBncy5yZW1vdmVEZWxlZ2F0aW9uKDAsIHJsbSwgZGVsZWdhdGlvbi5JRCgpKTsgZXJyICE9IG5pbCB7CgkJCQlyZXR1cm4gMCwgZXJyCgkJCX0KCQl9IGVsc2UgaWYgZXJyIDo9IGdzLnNldERlbGVnYXRpb24oMCwgcmxtLCBkZWxlZ2F0aW9uLklEKCksIGRlbGVnYXRpb24pOyBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIDAsIGVycgoJCX0KCQlncy5hZGREZWxlZ2F0aW9uUmVjb3JkKDAsIHJsbSwgZGVsZWdhdGVlLCAtY3VycmVudFVuRGVsZWdhdGlvbkFtb3VudCwgY3VycmVudFRpbWUpCgkJaWYgZXJyIDo9IGdzLnJlbW92ZVN0YWtlRW1pc3Npb25SZXdhcmQoMCwgcmxtLCBkZWxlZ2F0b3IuU3RyaW5nKCksIGN1cnJlbnRVbkRlbGVnYXRpb25BbW91bnQsIGN1cnJlbnRUaW1lKTsgZXJyICE9IG5pbCB7CgkJCXJldHVybiAwLCBlcnIKCQl9CgkJaWYgZXJyIDo9IGdzLnJlbW92ZVN0YWtlUHJvdG9jb2xGZWVSZXdhcmQoMCwgcmxtLCBkZWxlZ2F0b3IuU3RyaW5nKCksIGN1cnJlbnRVbkRlbGVnYXRpb25BbW91bnQsIGN1cnJlbnRUaW1lKTsgZXJyICE9IG5pbCB7CgkJCXJldHVybiAwLCBlcnIKCQl9CgoJCXVuRGVsZWdhdGlvbkFtb3VudCA9IGduc21hdGguU2FmZVN1YkludDY0KHVuRGVsZWdhdGlvbkFtb3VudCwgY3VycmVudFVuRGVsZWdhdGlvbkFtb3VudCkKCQlpZiB1bkRlbGVnYXRpb25BbW91bnQgPD0gMCB7CgkJCWJyZWFrCgkJfQoJfQoKCXJldHVybiBhbW91bnQsIG5pbAp9CgpmdW5jIChncyAqZ292U3Rha2VyVjEpIGluY3JlYXNlVG90YWxEZWxlZ2F0ZWRBbW91bnQoXyBpbnQsIHJsbSByZWFsbSwgYW1vdW50IGludDY0KSBlcnJvciB7CgljdXJyZW50RGVsZWdhdGVkIDo9IGdzLnN0b3JlLkdldFRvdGFsRGVsZWdhdGVkQW1vdW50KCkKCglpZiBlcnIgOj0gZ3Muc3RvcmUuU2V0VG90YWxEZWxlZ2F0ZWRBbW91bnQoMCwgcmxtLCBnbnNtYXRoLlNhZmVBZGRJbnQ2NChjdXJyZW50RGVsZWdhdGVkLCBhbW91bnQpKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCXJldHVybiBuaWwKfQoKZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBkZWNyZWFzZVRvdGFsRGVsZWdhdGVkQW1vdW50KF8gaW50LCBybG0gcmVhbG0sIGFtb3VudCBpbnQ2NCkgZXJyb3IgewoJY3VycmVudERlbGVnYXRlZCA6PSBncy5zdG9yZS5HZXRUb3RhbERlbGVnYXRlZEFtb3VudCgpCgoJbmV3RGVsZWdhdGVkIDo9IGduc21hdGguU2FmZVN1YkludDY0KGN1cnJlbnREZWxlZ2F0ZWQsIGFtb3VudCkKCWlmIG5ld0RlbGVnYXRlZCA8IDAgewoJCW5ld0RlbGVnYXRlZCA9IDAKCX0KCWlmIGVyciA6PSBncy5zdG9yZS5TZXRUb3RhbERlbGVnYXRlZEFtb3VudCgwLCBybG0sIG5ld0RlbGVnYXRlZCk7IGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCglyZXR1cm4gbmlsCn0KCmZ1bmMgKGdzICpnb3ZTdGFrZXJWMSkgaW5jcmVhc2VUb3RhbExvY2tlZEFtb3VudChfIGludCwgcmxtIHJlYWxtLCBhbW91bnQgaW50NjQpIGVycm9yIHsKCWN1cnJlbnRMb2NrZWQgOj0gZ3Muc3RvcmUuR2V0VG90YWxMb2NrZWRBbW91bnQoKQoKCWlmIGVyciA6PSBncy5zdG9yZS5TZXRUb3RhbExvY2tlZEFtb3VudCgwLCBybG0sIGduc21hdGguU2FmZUFkZEludDY0KGN1cnJlbnRMb2NrZWQsIGFtb3VudCkpOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJcmV0dXJuIG5pbAp9CgpmdW5jIChncyAqZ292U3Rha2VyVjEpIGRlY3JlYXNlVG90YWxMb2NrZWRBbW91bnQoXyBpbnQsIHJsbSByZWFsbSwgYW1vdW50IGludDY0KSBlcnJvciB7CgljdXJyZW50TG9ja2VkIDo9IGdzLnN0b3JlLkdldFRvdGFsTG9ja2VkQW1vdW50KCkKCgluZXdMb2NrZWQgOj0gZ25zbWF0aC5TYWZlU3ViSW50NjQoY3VycmVudExvY2tlZCwgYW1vdW50KQoJaWYgbmV3TG9ja2VkIDwgMCB7CgkJbmV3TG9ja2VkID0gMAoJfQoJaWYgZXJyIDo9IGdzLnN0b3JlLlNldFRvdGFsTG9ja2VkQW1vdW50KDAsIHJsbSwgbmV3TG9ja2VkKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCXJldHVybiBuaWwKfQoKLy8gY29sbGVjdERlbGVnYXRpb25zIHByb2Nlc3NlcyBjb2xsZWN0aW9uIG9mIHVuZGVsZWdhdGVkIHRva2Vucy4KLy8gSXRlcmF0ZXMgdGhyb3VnaCB1c2VyIGRlbGVnYXRpb25zIGFuZCBjb2xsZWN0cyBhdmFpbGFibGUgYW1vdW50cy4KZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBjb2xsZWN0RGVsZWdhdGlvbnMoXyBpbnQsIHJsbSByZWFsbSwgdXNlciBhZGRyZXNzLCBjdXJyZW50VGltZSBpbnQ2NCkgKGludDY0LCBlcnJvcikgewoJdG90YWxDb2xsZWN0ZWRBbW91bnQgOj0gaW50NjQoMCkKCglkZWxlZ2F0aW9uVHJlZSA6PSBncy5nZXRVc2VyRGVsZWdhdGlvbnModXNlcikKCgl2YXIgZXJyIGVycm9yCgl2YXIgaWRzVG9SZW1vdmUgW11pbnQ2NAoJYWxsRGVsZWdhdGlvbnMgOj0gZ3Muc3RvcmUuR2V0QWxsRGVsZWdhdGlvbnMoKQoKCS8vIENvbGxlY3QgZnJvbSBhbGwgYXZhaWxhYmxlIGRlbGVnYXRpb25zCglkZWxlZ2F0aW9uVHJlZS5JdGVyYXRlKCIiLCAiIiwgZnVuYyhkZWxlZ2F0ZWUgc3RyaW5nLCB2YWx1ZSBhbnkpIGJvb2wgewoJCWRlbGVnYXRpb25JRHMsIG9rIDo9IHZhbHVlLihbXWludDY0KQoJCWlmICFvayB7CgkJCXJldHVybiBmYWxzZQoJCX0KCgkJaWYgbGVuKGRlbGVnYXRpb25JRHMpID09IDAgewoJCQlyZXR1cm4gZmFsc2UKCQl9CgkJZm9yIF8sIGlkIDo9IHJhbmdlIGRlbGVnYXRpb25JRHMgewoJCQlkZWxlZ2F0aW9uUmF3IDo9IGFsbERlbGVnYXRpb25zLkdldCh1dGlscy5Gb3JtYXRJbnQoaWQpKQoJCQlpZiBkZWxlZ2F0aW9uUmF3ID09IG5pbCB7CgkJCQljb250aW51ZQoJCQl9CgkJCWRlbGVnYXRpb24sIG9rIDo9IGRlbGVnYXRpb25SYXcuKCpzdGFrZXIuRGVsZWdhdGlvbikKCQkJaWYgIW9rIHsKCQkJCWNvbnRpbnVlCgkJCX0KCgkJCXJlc29sdmVyIDo9IE5ld0RlbGVnYXRpb25SZXNvbHZlcihkZWxlZ2F0aW9uKQoKCQkJY29sbGVjdGVkQW1vdW50LCBpRXJyIDo9IHJlc29sdmVyLnByb2Nlc3NDb2xsZWN0aW9uKGN1cnJlbnRUaW1lKQoJCQlpZiBpRXJyICE9IG5pbCB7CgkJCQllcnIgPSBpRXJyCgkJCQlyZXR1cm4gdHJ1ZQoJCQl9CgoJCQkvLyBTaW1wbGUgYWRkaXRpb24gc2luY2UgYWRkVG9Db2xsZWN0ZWRBbW91bnQgd2FzIHJlbW92ZWQKCQkJdG90YWxDb2xsZWN0ZWRBbW91bnQgPSBnbnNtYXRoLlNhZmVBZGRJbnQ2NCh0b3RhbENvbGxlY3RlZEFtb3VudCwgY29sbGVjdGVkQW1vdW50KQoKCQkJLy8gU2F2ZSB1cGRhdGVkIGRlbGVnYXRpb24gc3RhdGUgYWZ0ZXIgY29sbGVjdGlvbgoJCQlpZiByZXNvbHZlci5Jc0VtcHR5KCkgewoJCQkJaWRzVG9SZW1vdmUgPSBhcHBlbmQoaWRzVG9SZW1vdmUsIGRlbGVnYXRpb24uSUQoKSkKCQkJfSBlbHNlIHsKCQkJCWlmIGlFcnIgOj0gZ3Muc2V0RGVsZWdhdGlvbigwLCBybG0sIGRlbGVnYXRpb24uSUQoKSwgZGVsZWdhdGlvbik7IGlFcnIgIT0gbmlsIHsKCQkJCQllcnIgPSBpRXJyCgkJCQkJcmV0dXJuIHRydWUKCQkJCX0KCQkJfQoJCX0KCgkJcmV0dXJuIGZhbHNlCgl9KQoKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiB0b3RhbENvbGxlY3RlZEFtb3VudCwgbWFrZUVycm9yV2l0aERldGFpbHMoZXJySW52YWxpZEFtb3VudCwgZXJyLkVycm9yKCkpCgl9CgoJZm9yIF8sIGlkIDo9IHJhbmdlIGlkc1RvUmVtb3ZlIHsKCQlpZiBlcnIgOj0gZ3MucmVtb3ZlRGVsZWdhdGlvbigwLCBybG0sIGlkKTsgZXJyICE9IG5pbCB7CgkJCXJldHVybiB0b3RhbENvbGxlY3RlZEFtb3VudCwgZXJyCgkJfQoJfQoKCXJldHVybiB0b3RhbENvbGxlY3RlZEFtb3VudCwgbmlsCn0KGscvCh5zdGFrZXJfZGVsZWdhdGlvbl9zbmFwc2hvdC5nbm8SpC9wYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCSJjaGFpbiIKCgkiZ25vLmxhbmQvcC9nbm9zd2FwL3V0aWxzL3YxIgoJImduby5sYW5kL3IvZ25vc3dhcC9hY2Nlc3MvdjEiCgkiZ25vLmxhbmQvci9nbm9zd2FwL2hhbHQvdjEiCikKCi8vIFNldFVuRGVsZWdhdGlvbkxvY2t1cFBlcmlvZEJ5QWRtaW4gc2V0cyB0aGUgdW5kZWxlZ2F0aW9uIGxvY2t1cCBwZXJpb2QuCi8vIFRoaXMgYWRtaW5pc3RyYXRpdmUgZnVuY3Rpb24gY29uZmlndXJlcyB0aGUgdGltZSBwZXJpb2QgdGhhdCB1bmRlbGVnYXRlZCB0b2tlbnMKLy8gbXVzdCB3YWl0IGJlZm9yZSB0aGV5IGNhbiBiZSBjb2xsZWN0ZWQgYnkgdXNlcnMuCi8vCi8vIFRoZSBsb2NrdXAgcGVyaW9kIHNlcnZlcyBhcyBhIHNlY3VyaXR5IG1lY2hhbmlzbSB0bzoKLy8gLSBQcmV2ZW50IHJhcGlkIGRlbGVnYXRpb24vdW5kZWxlZ2F0aW9uIGN5Y2xlcwovLyAtIFByb3ZpZGUgdGltZSBmb3IgZ292ZXJuYW5jZSBkZWNpc2lvbnMgdG8gdGFrZSBlZmZlY3QKLy8gLSBNYWludGFpbiBzeXN0ZW0gc3RhYmlsaXR5IGR1cmluZyB2b2xhdGlsZSBwZXJpb2RzCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBsZWFkaW5nIHJlYWxtLWNhbGwgZGlzY3JpbWluYXRvcjsgY2FsbGVycyBwYXNzIDAgZm9yIHRoZSBmb3J3YXJkZWQgaW1wbGVtZW50YXRpb24gY2FsbAovLyAgIC0gcmxtOiBwcm9wYWdhdGVkIGN1cnJlbnQgcmVhbG0gY29udGV4dCB2YWxpZGF0ZWQgYmVmb3JlIGFkbWluaXN0cmF0aXZlIHN0YXRlIHVwZGF0ZXMKLy8gICAtIHBlcmlvZDogbG9ja3VwIHBlcmlvZCBpbiBzZWNvbmRzIChtdXN0IGJlIG5vbi1uZWdhdGl2ZSkKLy8KLy8gUGFuaWNzOgovLyAgIC0gaWYgY2FsbGVyIGlzIG5vdCBhZG1pbgovLyAgIC0gaWYgcGVyaW9kIGlzIG5lZ2F0aXZlCi8vCi8vIE5vdGU6IFRoaXMgY2hhbmdlIGFmZmVjdHMgYWxsIGZ1dHVyZSB1bmRlbGVnYXRpb24gb3BlcmF0aW9ucwpmdW5jIChncyAqZ292U3Rha2VyVjEpIFNldFVuRGVsZWdhdGlvbkxvY2t1cFBlcmlvZEJ5QWRtaW4oXyBpbnQsIHJsbSByZWFsbSwgcGVyaW9kIGludDY0KSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCgloYWx0LkFzc2VydElzTm90SGFsdGVkR292U3Rha2VyKCkKCglwcmV2IDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXIgOj0gcHJldi5BZGRyZXNzKCkKCWFjY2Vzcy5Bc3NlcnRJc0FkbWluKGNhbGxlcikKCglpZiBwZXJpb2QgPCAwIHsKCQlwYW5pYygicGVyaW9kIG11c3QgYmUgZ3JlYXRlciB0aGFuIDAiKQoJfQoKCWdzLnNldFVuRGVsZWdhdGlvbkxvY2t1cFBlcmlvZCgwLCBybG0sIHBlcmlvZCkKCgljaGFpbi5FbWl0KAoJCSJTZXRVbkRlbGVnYXRpb25Mb2NrdXBQZXJpb2QiLAoJCSJwcmV2QWRkciIsIHByZXYuQWRkcmVzcygpLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2LlBrZ1BhdGgoKSwKCQkicGVyaW9kIiwgdXRpbHMuRm9ybWF0SW50KHBlcmlvZCksCgkpCn0KCi8vIENsZWFuU3Rha2VyRGVsZWdhdGlvblNuYXBzaG90QnlBZG1pbiBjbGVhbnMgb2xkIGRlbGVnYXRpb24gaGlzdG9yeSByZWNvcmRzLgovLyBUaGlzIGFkbWluaXN0cmF0aXZlIGZ1bmN0aW9uIHJlbW92ZXMgZGVsZWdhdGlvbiBoaXN0b3J5IHJlY29yZHMgb2xkZXIgdGhhbiB0aGUgc3BlY2lmaWVkIHRocmVzaG9sZAovLyB0byBwcmV2ZW50IHVubGltaXRlZCBncm93dGggb2YgaGlzdG9yaWNhbCBkYXRhIGFuZCBvcHRpbWl6ZSBzdG9yYWdlIHVzYWdlLgovLwovLyBUaGUgY2xlYW51cCBwcm9jZXNzOgovLyAxLiBWYWxpZGF0ZXMgdGhlIHNuYXBzaG90IHRpbWUgaXMgd2l0aGluIGFsbG93ZWQgcmFuZ2UKLy8gMi4gQ2hlY2tzIHRoYXQgbm8gYWN0aXZlIHByb3Bvc2FscyBuZWVkIGRhdGEgb2xkZXIgdGhhbiB0aGUgY2xlYW51cCB0aHJlc2hvbGQKLy8gMy4gRmlsdGVycyBkZWxlZ2F0aW9uIGhpc3RvcnkgdG8ga2VlcCBvbmx5IHJlY29yZHMgYWZ0ZXIgY3V0b2ZmIHRpbWUKLy8gNC4gVXBkYXRlcyB0aGUgZGVsZWdhdGlvbiBoaXN0b3J5IHdpdGggZmlsdGVyZWQgcmVjb3JkcwovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogbGVhZGluZyByZWFsbS1jYWxsIGRpc2NyaW1pbmF0b3I7IGNhbGxlcnMgcGFzcyAwIGZvciB0aGUgZm9yd2FyZGVkIGltcGxlbWVudGF0aW9uIGNhbGwKLy8gICAtIHJsbTogcHJvcGFnYXRlZCBjdXJyZW50IHJlYWxtIGNvbnRleHQgdmFsaWRhdGVkIGJlZm9yZSBhZG1pbmlzdHJhdGl2ZSBzdGF0ZSB1cGRhdGVzCi8vICAgLSBzbmFwc2hvdFRpbWU6IGN1dG9mZiB0aW1lc3RhbXAgKHJlY29yZHMgb2xkZXIgdGhhbiB0aGlzIHdpbGwgYmUgcmVtb3ZlZCkKLy8gICAtIHRhcmdldDogdGhlIHVzZXIgYWRkcmVzcyB3aG9zZSBkZWxlZ2F0aW9uIGhpc3Rvcnkgc2hvdWxkIGJlIGNsZWFuZWQKLy8KLy8gUGFuaWNzOgovLyAgIC0gaWYgY2FsbGVyIGlzIG5vdCBhZG1pbgovLyAgIC0gaWYgc25hcHNob3RUaW1lIGlzIGludmFsaWQgKG5lZ2F0aXZlIG9yIHRvbyByZWNlbnQpCi8vICAgLSBpZiBhY3RpdmUgcHJvcG9zYWxzIGhhdmUgc25hcHNob3RUaW1lIG9sZGVyIHRoYW4gdGhlIGNsZWFudXAgdGhyZXNob2xkCmZ1bmMgKGdzICpnb3ZTdGFrZXJWMSkgQ2xlYW5TdGFrZXJEZWxlZ2F0aW9uU25hcHNob3RCeUFkbWluKF8gaW50LCBybG0gcmVhbG0sIHNuYXBzaG90VGltZSBpbnQ2NCwgdGFyZ2V0IGFkZHJlc3MpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRHb3ZTdGFrZXIoKQoKCXByZXYgOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2LkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzQWRtaW4oY2FsbGVyKQoKCWFzc2VydElzVmFsaWRTbmFwc2hvdFRpbWUoc25hcHNob3RUaW1lKQoJYXNzZXJ0SXNBdmFpbGFibGVDbGVhbnVwU25hcHNob3RUaW1lKHNuYXBzaG90VGltZSkKCgkvLyBDbGVhbiB0b3RhbCBkZWxlZ2F0aW9uIGhpc3RvcnkKCWdzLmNsZWFuVG90YWxEZWxlZ2F0aW9uSGlzdG9yeSgwLCBybG0sIHNuYXBzaG90VGltZSkKCgkvLyBDbGVhbiB1c2VyIGRlbGVnYXRpb24gaGlzdG9yeQoJZ3MuY2xlYW5Vc2VyRGVsZWdhdGlvbkhpc3RvcnlGb3JBZGRyZXNzKDAsIHJsbSwgdGFyZ2V0LCBzbmFwc2hvdFRpbWUpCgoJY2hhaW4uRW1pdCgKCQkiQ2xlYW5TdGFrZXJEZWxlZ2F0aW9uU25hcHNob3QiLAoJCSJwcmV2QWRkciIsIHByZXYuQWRkcmVzcygpLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2LlBrZ1BhdGgoKSwKCQkic25hcHNob3RUaW1lIiwgdXRpbHMuRm9ybWF0SW50KHNuYXBzaG90VGltZSksCgkJInRhcmdldCIsIHRhcmdldC5TdHJpbmcoKSwKCSkKfQoKLy8gY2xlYW5Ub3RhbERlbGVnYXRpb25IaXN0b3J5IHJlbW92ZXMgdG90YWwgZGVsZWdhdGlvbiBoaXN0b3J5IGVudHJpZXMgb2xkZXIgdGhhbiBjdXRvZmYgdGltZS4KLy8gS2VlcHMgdGhlIG1vc3QgcmVjZW50IGVudHJ5IGJlZm9yZSBjdXRvZmYgdG8gcHJlc2VydmUgc3RhdGUgY29udGludWl0eS4KZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBjbGVhblRvdGFsRGVsZWdhdGlvbkhpc3RvcnkoXyBpbnQsIHJsbSByZWFsbSwgY3V0b2ZmVGltZXN0YW1wIGludDY0KSB7CgloaXN0b3J5IDo9IGdzLnN0b3JlLkdldFRvdGFsRGVsZWdhdGlvbkhpc3RvcnkoKQoKCS8vIEZpcnN0LCBmaW5kIHRoZSBtb3N0IHJlY2VudCBlbnRyeSBiZWZvcmUgY3V0b2ZmIHRvIHByZXNlcnZlIHN0YXRlCgl2YXIgbGFzdFZhbHVlIGFueQoKCWhhc0xhc3RWYWx1ZSA6PSBmYWxzZQoKCWhpc3RvcnkuUmV2ZXJzZUl0ZXJhdGUoMCwgY3V0b2ZmVGltZXN0YW1wLCBmdW5jKHRpbWVzdGFtcCBpbnQ2NCwgdmFsdWUgYW55KSBib29sIHsKCQlsYXN0VmFsdWUgPSB2YWx1ZQoJCWhhc0xhc3RWYWx1ZSA9IHRydWUKCgkJcmV0dXJuIHRydWUgLy8gc3RvcCBhZnRlciBmaXJzdCAobW9zdCByZWNlbnQpCgl9KQoKCS8vIElmIHRoZXJlIHdhcyBhIHZhbHVlIGJlZm9yZSBjdXRvZmYsIHNldCBpdCBhdCBjdXRvZmYgdGltZSB0byBwcmVzZXJ2ZSBjb250aW51aXR5CglpZiBoYXNMYXN0VmFsdWUgJiYgIWhpc3RvcnkuSGFzKGN1dG9mZlRpbWVzdGFtcCkgewoJCWhpc3RvcnkuU2V0KGN1dG9mZlRpbWVzdGFtcCwgbGFzdFZhbHVlKQoJfQoKCS8vIENvbGxlY3Qga2V5cyB0byByZW1vdmUgKGNhbm5vdCBtb2RpZnkgdHJlZSBkdXJpbmcgaXRlcmF0aW9uKQoJdmFyIGtleXNUb1JlbW92ZSBbXWludDY0CgloaXN0b3J5Lkl0ZXJhdGUoMCwgY3V0b2ZmVGltZXN0YW1wLCBmdW5jKHRpbWVzdGFtcCBpbnQ2NCwgXyBhbnkpIGJvb2wgewoJCWtleXNUb1JlbW92ZSA9IGFwcGVuZChrZXlzVG9SZW1vdmUsIHRpbWVzdGFtcCkKCQlyZXR1cm4gZmFsc2UgLy8gY29udGludWUKCX0pCglmb3IgXywga2V5IDo9IHJhbmdlIGtleXNUb1JlbW92ZSB7CgkJaGlzdG9yeS5SZW1vdmUoa2V5KQoJfQoKCWlmIGVyciA6PSBncy5zdG9yZS5TZXRUb3RhbERlbGVnYXRpb25IaXN0b3J5KDAsIHJsbSwgaGlzdG9yeSk7IGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KfQoKLy8gY2xlYW5Vc2VyRGVsZWdhdGlvbkhpc3RvcnlGb3JBZGRyZXNzIHJlbW92ZXMgdXNlciBkZWxlZ2F0aW9uIGhpc3RvcnkgZW50cmllcwovLyBvbGRlciB0aGFuIGN1dG9mZiB0aW1lIGZvciBhIHNpbmdsZSB0YXJnZXQgYWRkcmVzcy4KLy8gS2VlcHMgdGhlIG1vc3QgcmVjZW50IGVudHJ5IHN0cmljdGx5IGJlZm9yZSBjdXRvZmYKLy8gaW4gcGxhY2Ugc28gcmFuZ2UtYmFzZWQgc25hcHNob3QgbG9va3VwcyBjb250aW51ZSB0byByZXNvbHZlIGNvcnJlY3RseS4KZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBjbGVhblVzZXJEZWxlZ2F0aW9uSGlzdG9yeUZvckFkZHJlc3MoXyBpbnQsIHJsbSByZWFsbSwgdGFyZ2V0IGFkZHJlc3MsIGN1dG9mZlRpbWVzdGFtcCBpbnQ2NCkgewoJaWYgY3V0b2ZmVGltZXN0YW1wIDw9IDAgewoJCXJldHVybgoJfQoKCWhpc3RvcnkgOj0gZ3Muc3RvcmUuR2V0VXNlckRlbGVnYXRpb25IaXN0b3J5KCkKCglhZGRyU3RyIDo9IHRhcmdldC5TdHJpbmcoKQoJaXRlcmF0aW9uU3RhcnRLZXksIF8gOj0gdXNlckhpc3RvcnlLZXlSYW5nZShhZGRyU3RyKQoJaXRlcmF0aW9uRW5kS2V5IDo9IG1ha2VVc2VySGlzdG9yeUtleShhZGRyU3RyLCBjdXRvZmZUaW1lc3RhbXApCgoJLy8gRmlyc3QsIGZpbmQgdGhlIG1vc3QgcmVjZW50IGVudHJ5IGJlZm9yZSBjdXRvZmYgdG8gcHJlc2VydmUgc3RhdGUKCXZhciBsYXN0VmFsdWUgYW55CgoJaGFzTGFzdFZhbHVlIDo9IGZhbHNlCgoJaGlzdG9yeS5SZXZlcnNlSXRlcmF0ZShpdGVyYXRpb25TdGFydEtleSwgaXRlcmF0aW9uRW5kS2V5LCBmdW5jKGtleSBzdHJpbmcsIHZhbHVlIGFueSkgYm9vbCB7CgkJbGFzdFZhbHVlID0gdmFsdWUKCQloYXNMYXN0VmFsdWUgPSB0cnVlCgoJCXJldHVybiB0cnVlIC8vIHN0b3AgYWZ0ZXIgZmlyc3QgKG1vc3QgcmVjZW50KQoJfSkKCglpZiBoYXNMYXN0VmFsdWUgJiYgIWhpc3RvcnkuSGFzKGl0ZXJhdGlvbkVuZEtleSkgewoJCWhpc3RvcnkuU2V0KGl0ZXJhdGlvbkVuZEtleSwgbGFzdFZhbHVlKQoJfQoKCS8vIENvbGxlY3QgYWxsIGtleXMgc3RyaWN0bHkgYmVmb3JlIHByZXNlcnZlS2V5IHdpdGhpbiB0aGlzIGFkZHJlc3MgcHJlZml4LgoJLy8gSXRlcmF0ZSdzIGVuZCBpcyBleGNsdXNpdmUsIHNvIFtsbywgcHJlc2VydmVLZXkpIHNraXBzIHRoZSBwcmVzZXJ2ZWQgZW50cnkuCgl2YXIga2V5c1RvUmVtb3ZlIFtdc3RyaW5nCgoJaGlzdG9yeS5JdGVyYXRlKGl0ZXJhdGlvblN0YXJ0S2V5LCBpdGVyYXRpb25FbmRLZXksIGZ1bmMoa2V5IHN0cmluZywgXyBhbnkpIGJvb2wgewoJCWtleXNUb1JlbW92ZSA9IGFwcGVuZChrZXlzVG9SZW1vdmUsIGtleSkKCgkJcmV0dXJuIGZhbHNlCgl9KQoKCWZvciBfLCBrZXkgOj0gcmFuZ2Uga2V5c1RvUmVtb3ZlIHsKCQloaXN0b3J5LlJlbW92ZShrZXkpCgl9CgoJaWYgZXJyIDo9IGdzLnN0b3JlLlNldFVzZXJEZWxlZ2F0aW9uSGlzdG9yeSgwLCBybG0sIGhpc3RvcnkpOyBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9Cn0KGrlsChFzdGFrZXJfcmV3YXJkLmdubxKjbHBhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJImNoYWluIgoJInRpbWUiCgoJcHJiYWMgImduby5sYW5kL3AvZ25vc3dhcC9yYmFjL3YxIgoJImduby5sYW5kL3AvZ25vc3dhcC91dGlscy92MSIKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2FjY2Vzcy92MSIKCSJnbm8ubGFuZC9yL2dub3N3YXAvY29tbW9uIgoJImduby5sYW5kL3IvZ25vc3dhcC9nbnMiCgkiZ25vLmxhbmQvci9nbm9zd2FwL2dvdi94Z25zIgoJImduby5sYW5kL3IvZ25vc3dhcC9oYWx0L3YxIgopCgovLyBDb2xsZWN0UmV3YXJkIGNsYWltcyBhbGwgcmV3YXJkcyBmb3IgdGhlIGNhbGxlci4KLy8KLy8gSXQgc2V0dGxlcyBib3RoIHJld2FyZCBzdHJlYW1zOgovLyAgMS4gR05TIGVtaXNzaW9uIHJld2FyZHMgZnJvbSB0aGUgZW1pc3Npb24gYWNjdW11bGF0b3IuCi8vICAyLiBQcm90b2NvbC1mZWUgcmV3YXJkcyBmb3IgZXZlcnkga25vd24gdG9rZW4gcGF0aC4KLy8KLy8gUHJvdG9jb2wtZmVlIHJld2FyZHMgYXJlIGRpdmlkZWQgYnkgdGhlIHRvdGFsIHN0YWtlIGluIGZvcmNlIGZvciBlYWNoCi8vIGFjY3J1YWwgZXBvY2ggYW5kIHNldHRsZWQgYWNyb3NzIHRoZSBjYWxsZXIncyBzdGFrZS1ldmVudCBzZWdtZW50cy4gVGhleQovLyBhcmUgbm90IGNhbGN1bGF0ZWQgZnJvbSBvbmUgY3VycmVudCB4R05TL3RvdGFsLXhHTlMgcmF0aW8uIFExMjggZnJhY3Rpb25hbAovLyByZW1haW5kZXJzIHJlbWFpbiBpbiBzdGF0ZSBmb3IgbGF0ZXIgY29sbGVjdGlvbi4KLy8KLy8gVGhlIGFsbC10b2tlbiBwYXRoIGludGVudGlvbmFsbHkgZ3Jvd3Mgd2l0aCB0aGUgbnVtYmVyIG9mIGtub3duIGZlZSB0b2tlbnMuCi8vIFVzZSB0aGUgdG9rZW4tc3BlY2lmaWMgZW50cnkgcG9pbnQgd2hlbiBib3VuZGVkIHdvcmsgaXMgcmVxdWlyZWQuCi8vCi8vIE5vIGJ1c2luZXNzIHBhcmFtZXRlcnMgYXJlIHJlcXVpcmVkOyB0aGUgY2FsbGVyJ3MgcmV3YXJkIElEIGlzIHVzZWQuCi8vIFJld2FyZHMgYXJlIHRyYW5zZmVycmVkIGRpcmVjdGx5IHRvIHRoZSBjYWxsZXIuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBOb25jcm9zc2luZyBpbXBsZW1lbnRhdGlvbi1jYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8gICAtIHJsbTogQ3VycmVudCByZWFsbSBjb250ZXh0IGZvcndhcmRlZCBieSB0aGUgZ292ZXJuYW5jZS1zdGFrZXIgcHJveHk7IHZhbGlkYXRlZCBiZWZvcmUgc2V0dGxlbWVudCBhbmQgdHJhbnNmZXJzLgpmdW5jIChncyAqZ292U3Rha2VyVjEpIENvbGxlY3RSZXdhcmQoXyBpbnQsIHJsbSByZWFsbSkgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFdpdGhkcmF3KCkKCglwcmV2IDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXIgOj0gcHJldi5BZGRyZXNzKCkKCWZyb20gOj0gcmxtLkFkZHJlc3MoKQoJY3VycmVudFRpbWVzdGFtcCA6PSB0aW1lLk5vdygpLlVuaXgoKQoKCWVtaXNzaW9uUmV3YXJkLCBwcm90b2NvbEZlZVJld2FyZHMsIGVyciA6PSBncy5jbGFpbVJld2FyZHMoMCwgcmxtLCBjYWxsZXIuU3RyaW5nKCksIGN1cnJlbnRUaW1lc3RhbXApCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJLy8gVHJhbnNmZXIgZW1pc3Npb24gcmV3YXJkcyAoR05TIHRva2VucykgaWYgYW55CglpZiBlbWlzc2lvblJld2FyZCA+IDAgewoJCWducy5UcmFuc2Zlcihjcm9zcyhybG0pLCBjYWxsZXIsIGVtaXNzaW9uUmV3YXJkKQoKCQljaGFpbi5FbWl0KAoJCQkiQ29sbGVjdEVtaXNzaW9uUmV3YXJkIiwKCQkJInByZXZBZGRyIiwgcHJldi5BZGRyZXNzKCkuU3RyaW5nKCksCgkJCSJwcmV2UmVhbG0iLCBwcmV2LlBrZ1BhdGgoKSwKCQkJImZyb20iLCBmcm9tLlN0cmluZygpLAoJCQkidG8iLCBjYWxsZXIuU3RyaW5nKCksCgkJCSJlbWlzc2lvblJld2FyZEFtb3VudCIsIHV0aWxzLkZvcm1hdEludChlbWlzc2lvblJld2FyZCksCgkJKQoJfQoKCS8vIFRyYW5zZmVyIHByb3RvY29sIGZlZSByZXdhcmRzIGZvciBlYWNoIHRva2VuIHR5cGUKCWZvciB0b2tlblBhdGgsIGFtb3VudCA6PSByYW5nZSBwcm90b2NvbEZlZVJld2FyZHMgewoJCWlmIGFtb3VudCA+IDAgewoJCQllcnIgOj0gdHJhbnNmZXJUb2tlbigwLCBybG0sIHRva2VuUGF0aCwgZnJvbSwgY2FsbGVyLCBhbW91bnQpCgkJCWlmIGVyciAhPSBuaWwgewoJCQkJcGFuaWMoZXJyKQoJCQl9CgoJCQljaGFpbi5FbWl0KAoJCQkJIkNvbGxlY3RQcm90b2NvbEZlZVJld2FyZCIsCgkJCQkicHJldkFkZHIiLCBwcmV2LkFkZHJlc3MoKS5TdHJpbmcoKSwKCQkJCSJwcmV2UmVhbG0iLCBwcmV2LlBrZ1BhdGgoKSwKCQkJCSJ0b2tlblBhdGgiLCB0b2tlblBhdGgsCgkJCQkiZnJvbSIsIGZyb20uU3RyaW5nKCksCgkJCQkidG8iLCBjYWxsZXIuU3RyaW5nKCksCgkJCQkiY29sbGVjdGVkQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KGFtb3VudCksCgkJCSkKCQl9Cgl9Cn0KCi8vIENvbGxlY3RFbWlzc2lvblJld2FyZCBjb2xsZWN0cyBhY2N1bXVsYXRlZCBHTlMgZW1pc3Npb24gcmV3YXJkcyBvbmx5LgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgYnkgdGhlIGdvdmVybmFuY2Utc3Rha2VyIHByb3h5OyB2YWxpZGF0ZWQgYmVmb3JlIHNldHRsZW1lbnQgYW5kIHRyYW5zZmVyLgpmdW5jIChncyAqZ292U3Rha2VyVjEpIENvbGxlY3RFbWlzc2lvblJld2FyZChfIGludCwgcmxtIHJlYWxtKSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCgloYWx0LkFzc2VydElzTm90SGFsdGVkV2l0aGRyYXcoKQoKCXByZXYgOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2LkFkZHJlc3MoKQoJZnJvbSA6PSBybG0uQWRkcmVzcygpCgljdXJyZW50VGltZXN0YW1wIDo9IHRpbWUuTm93KCkuVW5peCgpCgoJZW1pc3Npb25SZXdhcmQsIGVyciA6PSBncy5jbGFpbVJld2FyZHNFbWlzc2lvblJld2FyZCgwLCBybG0sIGNhbGxlci5TdHJpbmcoKSwgY3VycmVudFRpbWVzdGFtcCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCglpZiBlbWlzc2lvblJld2FyZCA+IDAgewoJCWducy5UcmFuc2Zlcihjcm9zcyhybG0pLCBjYWxsZXIsIGVtaXNzaW9uUmV3YXJkKQoKCQljaGFpbi5FbWl0KAoJCQkiQ29sbGVjdEVtaXNzaW9uUmV3YXJkIiwKCQkJInByZXZBZGRyIiwgcHJldi5BZGRyZXNzKCkuU3RyaW5nKCksCgkJCSJwcmV2UmVhbG0iLCBwcmV2LlBrZ1BhdGgoKSwKCQkJImZyb20iLCBmcm9tLlN0cmluZygpLAoJCQkidG8iLCBjYWxsZXIuU3RyaW5nKCksCgkJCSJlbWlzc2lvblJld2FyZEFtb3VudCIsIHV0aWxzLkZvcm1hdEludChlbWlzc2lvblJld2FyZCksCgkJKQoJfQp9CgovLyBDb2xsZWN0UHJvdG9jb2xGZWVSZXdhcmQgY29sbGVjdHMgYWNjdW11bGF0ZWQgcHJvdG9jb2wgZmVlIHJld2FyZHMgZm9yIHRoZSBwcm92aWRlZCB0b2tlbiBwYXRoLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgYnkgdGhlIGdvdmVybmFuY2Utc3Rha2VyIHByb3h5OyB2YWxpZGF0ZWQgYmVmb3JlIHNldHRsZW1lbnQgYW5kIHRyYW5zZmVyLgovLyAgIC0gdG9rZW5QYXRoOiByZWdpc3RlcmVkIGZlZS10b2tlbiBwYXRoIHdob3NlIHJld2FyZCBzaG91bGQgYmUgY29sbGVjdGVkCmZ1bmMgKGdzICpnb3ZTdGFrZXJWMSkgQ29sbGVjdFByb3RvY29sRmVlUmV3YXJkKF8gaW50LCBybG0gcmVhbG0sIHRva2VuUGF0aCBzdHJpbmcpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRXaXRoZHJhdygpCgoJcHJldiA6PSBybG0uUHJldmlvdXMoKQoJY2FsbGVyIDo9IHByZXYuQWRkcmVzcygpCglmcm9tIDo9IHJsbS5BZGRyZXNzKCkKCWN1cnJlbnRUaW1lc3RhbXAgOj0gdGltZS5Ob3coKS5Vbml4KCkKCglhbW91bnQsIGVyciA6PSBncy5jbGFpbVJld2FyZFByb3RvY29sRmVlUmV3YXJkQnlUb2tlblBhdGgoMCwgcmxtLCBjYWxsZXIuU3RyaW5nKCksIHRva2VuUGF0aCwgY3VycmVudFRpbWVzdGFtcCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCglpZiBhbW91bnQgPiAwIHsKCQllcnIgOj0gdHJhbnNmZXJUb2tlbigwLCBybG0sIHRva2VuUGF0aCwgZnJvbSwgY2FsbGVyLCBhbW91bnQpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXBhbmljKGVycikKCQl9CgoJCWNoYWluLkVtaXQoCgkJCSJDb2xsZWN0UHJvdG9jb2xGZWVSZXdhcmQiLAoJCQkicHJldkFkZHIiLCBwcmV2LkFkZHJlc3MoKS5TdHJpbmcoKSwKCQkJInByZXZSZWFsbSIsIHByZXYuUGtnUGF0aCgpLAoJCQkidG9rZW5QYXRoIiwgdG9rZW5QYXRoLAoJCQkiZnJvbSIsIGZyb20uU3RyaW5nKCksCgkJCSJ0byIsIGNhbGxlci5TdHJpbmcoKSwKCQkJImNvbGxlY3RlZEFtb3VudCIsIHV0aWxzLkZvcm1hdEludChhbW91bnQpLAoJCSkKCX0KfQoKLy8gQ29sbGVjdFJld2FyZEZyb21MYXVuY2hQYWQgY29sbGVjdHMgcmV3YXJkcyBmb3IgbGF1bmNocGFkIHByb2plY3Qgd2FsbGV0cy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIGJ5IHRoZSBnb3Zlcm5hbmNlLXN0YWtlciBwcm94eTsgdmFsaWRhdGVkIGJlZm9yZSBsYXVuY2hwYWQgcmV3YXJkIHNldHRsZW1lbnQuCi8vICAgLSB0bzogcHJvamVjdCB3YWxsZXQgYWRkcmVzcyByZWNlaXZpbmcgaXRzIGVtaXNzaW9uIGFuZCBwcm90b2NvbC1mZWUgcmV3YXJkcwovLwovLyBPbmx5IGNhbGxhYmxlIGJ5IGxhdW5jaHBhZCBjb250cmFjdC4KZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBDb2xsZWN0UmV3YXJkRnJvbUxhdW5jaFBhZChfIGludCwgcmxtIHJlYWxtLCB0byBhZGRyZXNzKSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCgloYWx0LkFzc2VydElzTm90SGFsdGVkV2l0aGRyYXcoKQoKCXByZXYgOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2LkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzTGF1bmNocGFkKGNhbGxlcikKCglmcm9tIDo9IHJsbS5BZGRyZXNzKCkKCWN1cnJlbnRUaW1lc3RhbXAgOj0gdGltZS5Ob3coKS5Vbml4KCkKCglsYXVuY2hwYWRSZXdhcmRJRCA6PSBncy5tYWtlTGF1bmNocGFkUmV3YXJkSUQodG8uU3RyaW5nKCkpCglfLCBleGlzdHMgOj0gZ3MuZ2V0TGF1bmNocGFkUHJvamVjdERlcG9zaXQobGF1bmNocGFkUmV3YXJkSUQpCglpZiAhZXhpc3RzIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJyTm9EZWxlZ2F0ZWRBbW91bnQsCgkJCXVmbXQuU3ByaW50ZigiJXMgaXMgbm90IHByb2plY3Qgd2FsbGV0IGZyb20gbGF1bmNocGFkIiwgdG8uU3RyaW5nKCkpLAoJCSkpCgl9CgoJZW1pc3Npb25SZXdhcmQsIHByb3RvY29sRmVlUmV3YXJkcywgZXJyIDo9IGdzLmNsYWltUmV3YXJkc0Zyb21MYXVuY2hwYWQoMCwgcmxtLCB0by5TdHJpbmcoKSwgY3VycmVudFRpbWVzdGFtcCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCgkvLyBUcmFuc2ZlciBlbWlzc2lvbiByZXdhcmRzIChHTlMgdG9rZW5zKSB0byBwcm9qZWN0IHdhbGxldCBpZiBhbnkKCWlmIGVtaXNzaW9uUmV3YXJkID4gMCB7CgkJZ25zLlRyYW5zZmVyKGNyb3NzKHJsbSksIHRvLCBlbWlzc2lvblJld2FyZCkKCgkJY2hhaW4uRW1pdCgKCQkJIkNvbGxlY3RFbWlzc2lvbkZyb21MYXVuY2hQYWQiLAoJCQkicHJldkFkZHIiLCBwcmV2LkFkZHJlc3MoKS5TdHJpbmcoKSwKCQkJInByZXZSZWFsbSIsIHByZXYuUGtnUGF0aCgpLAoJCQkiZnJvbSIsIGZyb20uU3RyaW5nKCksCgkJCSJ0byIsIHRvLlN0cmluZygpLAoJCQkiZW1pc3Npb25SZXdhcmRBbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQoZW1pc3Npb25SZXdhcmQpLAoJCSkKCX0KCgkvLyBUcmFuc2ZlciBwcm90b2NvbCBmZWUgcmV3YXJkcyB0byBwcm9qZWN0IHdhbGxldCBmb3IgZWFjaCB0b2tlbiB0eXBlCglmb3IgdG9rZW5QYXRoLCBhbW91bnQgOj0gcmFuZ2UgcHJvdG9jb2xGZWVSZXdhcmRzIHsKCQlpZiBhbW91bnQgPiAwIHsKCQkJZXJyIDo9IHRyYW5zZmVyVG9rZW4oMCwgcmxtLCB0b2tlblBhdGgsIGZyb20sIHRvLCBhbW91bnQpCgkJCWlmIGVyciAhPSBuaWwgewoJCQkJcGFuaWMoZXJyKQoJCQl9CgoJCQljaGFpbi5FbWl0KAoJCQkJIkNvbGxlY3RQcm90b2NvbEZlZUZyb21MYXVuY2hQYWQiLAoJCQkJInByZXZBZGRyIiwgcHJldi5BZGRyZXNzKCkuU3RyaW5nKCksCgkJCQkicHJldlJlYWxtIiwgcHJldi5Qa2dQYXRoKCksCgkJCQkidG9rZW5QYXRoIiwgdG9rZW5QYXRoLAoJCQkJImZyb20iLCBmcm9tLlN0cmluZygpLAoJCQkJInRvIiwgdG8uU3RyaW5nKCksCgkJCQkiY29sbGVjdGVkQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KGFtb3VudCksCgkJCSkKCQl9Cgl9Cn0KCi8vIENvbGxlY3RFbWlzc2lvblJld2FyZEZyb21MYXVuY2hQYWQgY29sbGVjdHMgZW1pc3Npb24gcmV3YXJkcyBvbmx5IGZvciBsYXVuY2hwYWQgcHJvamVjdCB3YWxsZXRzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgYnkgdGhlIGdvdmVybmFuY2Utc3Rha2VyIHByb3h5OyB2YWxpZGF0ZWQgYmVmb3JlIGxhdW5jaHBhZCByZXdhcmQgc2V0dGxlbWVudC4KLy8gICAtIHRvOiBwcm9qZWN0IHdhbGxldCBhZGRyZXNzIHJlY2VpdmluZyBpdHMgZW1pc3Npb24gcmV3YXJkCmZ1bmMgKGdzICpnb3ZTdGFrZXJWMSkgQ29sbGVjdEVtaXNzaW9uUmV3YXJkRnJvbUxhdW5jaFBhZChfIGludCwgcmxtIHJlYWxtLCB0byBhZGRyZXNzKSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCgloYWx0LkFzc2VydElzTm90SGFsdGVkV2l0aGRyYXcoKQoKCXByZXYgOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2LkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzTGF1bmNocGFkKGNhbGxlcikKCglmcm9tIDo9IHJsbS5BZGRyZXNzKCkKCWN1cnJlbnRUaW1lc3RhbXAgOj0gdGltZS5Ob3coKS5Vbml4KCkKCglsYXVuY2hwYWRSZXdhcmRJRCA6PSBncy5tYWtlTGF1bmNocGFkUmV3YXJkSUQodG8uU3RyaW5nKCkpCglfLCBleGlzdHMgOj0gZ3MuZ2V0TGF1bmNocGFkUHJvamVjdERlcG9zaXQobGF1bmNocGFkUmV3YXJkSUQpCglpZiAhZXhpc3RzIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJyTm9EZWxlZ2F0ZWRBbW91bnQsCgkJCXVmbXQuU3ByaW50ZigiJXMgaXMgbm90IHByb2plY3Qgd2FsbGV0IGZyb20gbGF1bmNocGFkIiwgdG8uU3RyaW5nKCkpLAoJCSkpCgl9CgoJZW1pc3Npb25SZXdhcmQsIGVyciA6PSBncy5jbGFpbVJld2FyZHNFbWlzc2lvblJld2FyZCgwLCBybG0sIGxhdW5jaHBhZFJld2FyZElELCBjdXJyZW50VGltZXN0YW1wKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCWlmIGVtaXNzaW9uUmV3YXJkID4gMCB7CgkJZ25zLlRyYW5zZmVyKGNyb3NzKHJsbSksIHRvLCBlbWlzc2lvblJld2FyZCkKCgkJY2hhaW4uRW1pdCgKCQkJIkNvbGxlY3RFbWlzc2lvbkZyb21MYXVuY2hQYWQiLAoJCQkicHJldkFkZHIiLCBwcmV2LkFkZHJlc3MoKS5TdHJpbmcoKSwKCQkJInByZXZSZWFsbSIsIHByZXYuUGtnUGF0aCgpLAoJCQkiZnJvbSIsIGZyb20uU3RyaW5nKCksCgkJCSJ0byIsIHRvLlN0cmluZygpLAoJCQkiZW1pc3Npb25SZXdhcmRBbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQoZW1pc3Npb25SZXdhcmQpLAoJCSkKCX0KfQoKLy8gQ29sbGVjdFByb3RvY29sRmVlUmV3YXJkRnJvbUxhdW5jaFBhZCBjb2xsZWN0cyBvbmUgdG9rZW4gcGF0aCBvZiBwcm90b2NvbCBmZWUgcmV3YXJkcyBmb3IgbGF1bmNocGFkIHByb2plY3Qgd2FsbGV0cy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIGJ5IHRoZSBnb3Zlcm5hbmNlLXN0YWtlciBwcm94eTsgdmFsaWRhdGVkIGJlZm9yZSBsYXVuY2hwYWQgcmV3YXJkIHNldHRsZW1lbnQuCi8vICAgLSB0bzogcHJvamVjdCB3YWxsZXQgYWRkcmVzcyByZWNlaXZpbmcgdGhlIHByb3RvY29sLWZlZSByZXdhcmQKLy8gICAtIHRva2VuUGF0aDogcmVnaXN0ZXJlZCBmZWUtdG9rZW4gcGF0aCB3aG9zZSByZXdhcmQgc2hvdWxkIGJlIGNvbGxlY3RlZApmdW5jIChncyAqZ292U3Rha2VyVjEpIENvbGxlY3RQcm90b2NvbEZlZVJld2FyZEZyb21MYXVuY2hQYWQoXyBpbnQsIHJsbSByZWFsbSwgdG8gYWRkcmVzcywgdG9rZW5QYXRoIHN0cmluZykgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFdpdGhkcmF3KCkKCglwcmV2IDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXIgOj0gcHJldi5BZGRyZXNzKCkKCWFjY2Vzcy5Bc3NlcnRJc0xhdW5jaHBhZChjYWxsZXIpCgoJZnJvbSA6PSBybG0uQWRkcmVzcygpCgljdXJyZW50VGltZXN0YW1wIDo9IHRpbWUuTm93KCkuVW5peCgpCgoJbGF1bmNocGFkUmV3YXJkSUQgOj0gZ3MubWFrZUxhdW5jaHBhZFJld2FyZElEKHRvLlN0cmluZygpKQoJXywgZXhpc3RzIDo9IGdzLmdldExhdW5jaHBhZFByb2plY3REZXBvc2l0KGxhdW5jaHBhZFJld2FyZElEKQoJaWYgIWV4aXN0cyB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyck5vRGVsZWdhdGVkQW1vdW50LAoJCQl1Zm10LlNwcmludGYoIiVzIGlzIG5vdCBwcm9qZWN0IHdhbGxldCBmcm9tIGxhdW5jaHBhZCIsIHRvLlN0cmluZygpKSwKCQkpKQoJfQoKCWFtb3VudCwgZXJyIDo9IGdzLmNsYWltUmV3YXJkUHJvdG9jb2xGZWVSZXdhcmRCeVRva2VuUGF0aCgwLCBybG0sIGxhdW5jaHBhZFJld2FyZElELCB0b2tlblBhdGgsIGN1cnJlbnRUaW1lc3RhbXApCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJaWYgYW1vdW50ID4gMCB7CgkJZXJyIDo9IHRyYW5zZmVyVG9rZW4oMCwgcmxtLCB0b2tlblBhdGgsIGZyb20sIHRvLCBhbW91bnQpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXBhbmljKGVycikKCQl9CgoJCWNoYWluLkVtaXQoCgkJCSJDb2xsZWN0UHJvdG9jb2xGZWVGcm9tTGF1bmNoUGFkIiwKCQkJInByZXZBZGRyIiwgcHJldi5BZGRyZXNzKCkuU3RyaW5nKCksCgkJCSJwcmV2UmVhbG0iLCBwcmV2LlBrZ1BhdGgoKSwKCQkJInRva2VuUGF0aCIsIHRva2VuUGF0aCwKCQkJImZyb20iLCBmcm9tLlN0cmluZygpLAoJCQkidG8iLCB0by5TdHJpbmcoKSwKCQkJImNvbGxlY3RlZEFtb3VudCIsIHV0aWxzLkZvcm1hdEludChhbW91bnQpLAoJCSkKCX0KfQoKLy8gU2V0QW1vdW50QnlQcm9qZWN0V2FsbGV0IHNldHMgdGhlIGFtb3VudCBvZiByZXdhcmQgc3Rha2UgZm9yIHRoZSBwcm9qZWN0IHdhbGxldC4KLy8gVGhpcyBmdW5jdGlvbiBpcyBleGNsdXNpdmVseSBjYWxsYWJsZSBieSB0aGUgbGF1bmNocGFkIGNvbnRyYWN0IHRvIG1hbmFnZQovLyB4R05TIGJhbGFuY2VzIGZvciBwcm9qZWN0IHdhbGxldHMgdGhhdCBwYXJ0aWNpcGF0ZSBpbiBsYXVuY2hwYWQgb2ZmZXJpbmdzLgovLwovLyBUaGUgZnVuY3Rpb24gaGFuZGxlcyBib3RoIGFkZGluZyBhbmQgcmVtb3Zpbmcgc3Rha2VzOgovLyAtIFdoZW4gYWRkaW5nOiBtaW50cyB4R05TIHRvIGxhdW5jaHBhZCBhZGRyZXNzIGFuZCBzdGFydHMgcmV3YXJkIGFjY3VtdWxhdGlvbgovLyAtIFdoZW4gcmVtb3Zpbmc6IGJ1cm5zIHhHTlMgZnJvbSBsYXVuY2hwYWQgYWRkcmVzcyBhbmQgc3RvcHMgcmV3YXJkIGFjY3VtdWxhdGlvbgovLyBBZGp1c3RzIHN0YWtlIGFtb3VudCBmb3IgcHJvamVjdCB3YWxsZXQgYWRkcmVzcy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIGJ5IHRoZSBnb3Zlcm5hbmNlLXN0YWtlciBwcm94eTsgdmFsaWRhdGVkIGJlZm9yZSBsYXVuY2hwYWQgYXV0aG9yaXphdGlvbiBhbmQgc3Rha2luZyBjaGFuZ2VzLgovLyAgIC0gYWRkcjogcHJvamVjdCB3YWxsZXQgYWRkcmVzcyB3aG9zZSBsYXVuY2hwYWQtYmFja2VkIHN0YWtlIHNob3VsZCBiZSBhZGp1c3RlZAovLyAgIC0gYW1vdW50OiBhbW91bnQgb2Ygc3Rha2UgdG8gYWRkIG9yIHJlbW92ZQovLyAgIC0gYWRkOiB0cnVlIHRvIGFkZCBzdGFrZSBhbmQgbWludCB4R05TIHRvIGxhdW5jaHBhZCwgZmFsc2UgdG8gcmVtb3ZlIHN0YWtlIGFuZCBidXJuIHhHTlMgZnJvbSBsYXVuY2hwYWQKLy8KLy8gUGFuaWNzOgovLyAgIC0gaWYgY2FsbGVyIGlzIG5vdCB0aGUgbGF1bmNocGFkIGNvbnRyYWN0Ci8vICAgLSBpZiBzeXN0ZW0gaXMgaGFsdGVkIGZvciB3aXRoZHJhd2FscwovLyAgIC0gaWYgYWNjZXNzIGNvbnRyb2wgb3BlcmF0aW9ucyBmYWlsCmZ1bmMgKGdzICpnb3ZTdGFrZXJWMSkgU2V0QW1vdW50QnlQcm9qZWN0V2FsbGV0KF8gaW50LCBybG0gcmVhbG0sIGFkZHIgYWRkcmVzcywgYW1vdW50IGludDY0LCBhZGQgYm9vbCkgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaWYgYWRkIHsKCQloYWx0LkFzc2VydElzTm90SGFsdGVkR292U3Rha2VyKCkKCX0gZWxzZSB7CgkJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFdpdGhkcmF3KCkKCX0KCglwcmV2IDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXIgOj0gcHJldi5BZGRyZXNzKCkKCWN1cnJlbnRUaW1lc3RhbXAgOj0gdGltZS5Ob3coKS5Vbml4KCkKCglhY2Nlc3MuQXNzZXJ0SXNMYXVuY2hwYWQoY2FsbGVyKQoKCWxhdW5jaHBhZEFkZHIgOj0gYWNjZXNzLk11c3RHZXRBZGRyZXNzKHByYmFjLlJPTEVfTEFVTkNIUEFELlN0cmluZygpKQoKCWlmIGFkZCB7CgkJLy8gQWRkIHN0YWtlIGZvciB0aGUgcHJvamVjdCB3YWxsZXQgYW5kIG1pbnQgeEdOUyB0byBsYXVuY2hwYWQKCQllcnIgOj0gZ3MuYWRkU3Rha2VGcm9tTGF1bmNocGFkKDAsIHJsbSwgYWRkci5TdHJpbmcoKSwgYW1vdW50LCBjdXJyZW50VGltZXN0YW1wKQoJCWlmIGVyciAhPSBuaWwgewoJCQlwYW5pYyhlcnIpCgkJfQoKCQl4Z25zLk1pbnQoY3Jvc3MocmxtKSwgbGF1bmNocGFkQWRkciwgYW1vdW50KQoJfSBlbHNlIHsKCQkvLyBSZW1vdmUgc3Rha2UgZm9yIHRoZSBwcm9qZWN0IHdhbGxldCBhbmQgYnVybiB4R05TIGZyb20gbGF1bmNocGFkCgkJZXJyIDo9IGdzLnJlbW92ZVN0YWtlRnJvbUxhdW5jaHBhZCgwLCBybG0sIGFkZHIuU3RyaW5nKCksIGFtb3VudCwgY3VycmVudFRpbWVzdGFtcCkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcGFuaWMoZXJyKQoJCX0KCgkJeGducy5CdXJuKGNyb3NzKHJsbSksIGxhdW5jaHBhZEFkZHIsIGFtb3VudCkKCX0KfQoKLy8gY2xhaW1SZXdhcmRzIGNsYWltcyBib3RoIGVtaXNzaW9uIGFuZCBwcm90b2NvbCBmZWUgcmV3YXJkcy4KLy8gQ29vcmRpbmF0ZXMgY2xhaW1pbmcgcHJvY2VzcyBmb3IgYm90aCByZXdhcmQgdHlwZXMuCmZ1bmMgKGdzICpnb3ZTdGFrZXJWMSkgY2xhaW1SZXdhcmRzKF8gaW50LCBybG0gcmVhbG0sIHJld2FyZElEIHN0cmluZywgY3VycmVudFRpbWVzdGFtcCBpbnQ2NCkgKGludDY0LCBtYXBbc3RyaW5nXWludDY0LCBlcnJvcikgewoJZW1pc3Npb25SZXdhcmQsIGVyciA6PSBncy5jbGFpbVJld2FyZHNFbWlzc2lvblJld2FyZCgwLCBybG0sIHJld2FyZElELCBjdXJyZW50VGltZXN0YW1wKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIG5pbCwgZXJyCgl9CgoJcHJvdG9jb2xGZWVSZXdhcmRzLCBlcnIgOj0gZ3MuY2xhaW1SZXdhcmRzUHJvdG9jb2xGZWVSZXdhcmQoMCwgcmxtLCByZXdhcmRJRCwgY3VycmVudFRpbWVzdGFtcCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBuaWwsIGVycgoJfQoKCXJldHVybiBlbWlzc2lvblJld2FyZCwgcHJvdG9jb2xGZWVSZXdhcmRzLCBuaWwKfQoKLy8gY2xhaW1SZXdhcmRzRnJvbUxhdW5jaHBhZCBjbGFpbXMgcmV3YXJkcyBmb3IgbGF1bmNocGFkIHByb2plY3Qgd2FsbGV0cy4KLy8gVXNlcyBzcGVjaWFsIHJld2FyZCBJRCBmb3JtYXQgZm9yIGxhdW5jaHBhZCBpbnRlZ3JhdGlvbi4KZnVuYyAoZ3MgKmdvdlN0YWtlclYxKSBjbGFpbVJld2FyZHNGcm9tTGF1bmNocGFkKF8gaW50LCBybG0gcmVhbG0sIGFkZHJlc3Mgc3RyaW5nLCBjdXJyZW50VGltZXN0YW1wIGludDY0KSAoaW50NjQsIG1hcFtzdHJpbmddaW50NjQsIGVycm9yKSB7CglsYXVuY2hwYWRSZXdhcmRJRCA6PSBncy5tYWtlTGF1bmNocGFkUmV3YXJkSUQoYWRkcmVzcykKCglyZXR1cm4gZ3MuY2xhaW1SZXdhcmRzKDAsIHJsbSwgbGF1bmNocGFkUmV3YXJkSUQsIGN1cnJlbnRUaW1lc3RhbXApCn0KCi8vIHRyYW5zZmVyVG9rZW4gdHJhbnNmZXJzIHRva2VucyBmcm9tIHRoZSBzdGFrZXIgY29udHJhY3QgdG8gYSByZWNpcGllbnQgYWRkcmVzcy4KLy8gdHJhbnNmZXJUb2tlbiBoYW5kbGVzIHRva2VuIHRyYW5zZmVycyBmb3IgcmV3YXJkIGRpc3RyaWJ1dGlvbi4KLy8KLy8gTm9uLWNyb3NzaW5nIGhlbHBlcjogdGFrZXMgYF8gaW50LCBybG0gcmVhbG1gIHNvIHRoZSByZWFsbSB0b2tlbiB0aHJlYWRlZAovLyBpbiBieSB0aGUgcHVibGljIHJld2FyZC1jb2xsZWN0aW9uIGVudHJ5IHBvaW50cyByZWFjaGVzIHRoZSB1bmRlcmx5aW5nCi8vIEdSQy0yMCB0cmFuc2ZlciB3aXRob3V0IGZvcmNpbmcgZWFjaCBjYWxsZXIgdG8gcmVjb21wdXRlIGl0LgpmdW5jIHRyYW5zZmVyVG9rZW4oCglfIGludCwKCXJsbSByZWFsbSwKCXRva2VuUGF0aCBzdHJpbmcsCglmcm9tLCB0byBhZGRyZXNzLAoJYW1vdW50IGludDY0LAopIGVycm9yIHsKCWNvbW1vbi5NdXN0UmVnaXN0ZXJlZCh0b2tlblBhdGgpCgoJLy8gVmFsaWRhdGUgcmVjaXBpZW50IGFkZHJlc3MKCWlmICF0by5Jc1ZhbGlkKCkgewoJCXJldHVybiBtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZEFkZHJlc3MsCgkJCXVmbXQuU3ByaW50ZigiaW52YWxpZCBhZGRyZXNzICVzIHRvIHRyYW5zZmVyIHByb3RvY29sIGZlZSIsIHRvLlN0cmluZygpKSwKCQkpCgl9CgoJLy8gVmFsaWRhdGUgdHJhbnNmZXIgYW1vdW50CglpZiBhbW91bnQgPCAwIHsKCQlyZXR1cm4gbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckludmFsaWRBbW91bnQsCgkJCXVmbXQuU3ByaW50ZigiaW52YWxpZCBhbW91bnQgJWQgdG8gdHJhbnNmZXIgcHJvdG9jb2wgZmVlIiwgYW1vdW50KSwKCQkpCgl9CgoJLy8gQ2hlY2sgc3VmZmljaWVudCBiYWxhbmNlCgliYWxhbmNlIDo9IGNvbW1vbi5CYWxhbmNlT2YodG9rZW5QYXRoLCBmcm9tKQoJaWYgYmFsYW5jZSA8IGFtb3VudCB7CgkJcmV0dXJuIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJOb3RFbm91Z2hCYWxhbmNlLAoJCQl1Zm10LlNwcmludGYoIm5vdCBlbm91Z2ggJXMgYmFsYW5jZSglZCkgdG8gY29sbGVjdCglZCkiLCB0b2tlblBhdGgsIGJhbGFuY2UsIGFtb3VudCksCgkJKQoJfQoKCWNvbW1vbi5TYWZlR1JDMjBUcmFuc2ZlcigwLCBybG0sIHRva2VuUGF0aCwgdG8sIGFtb3VudCkKCglyZXR1cm4gbmlsCn0KGuCxAQoJc3RhdGUuZ25vEtGxAXBhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJImVycm9ycyIKCSJtYXRoIgoKCWduc21hdGggImduby5sYW5kL3AvZ25vc3dhcC9nbnNtYXRoL3YxIgoJYnB0cmVlICJnbm8ubGFuZC9wL250L2JwdHJlZS92MCIKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2VtaXNzaW9uIgoJImduby5sYW5kL3IvZ25vc3dhcC9nb3Yvc3Rha2VyIgoJcGYgImduby5sYW5kL3IvZ25vc3dhcC9wcm90b2NvbF9mZWUiCikKCi8vIHNldFVuRGVsZWdhdGlvbkxvY2t1cFBlcmlvZCB1cGRhdGVzIHRoZSB1bmRlbGVnYXRpb24gbG9ja3VwIHBlcmlvZC4KLy8gVGhpcyBhZmZlY3RzIGFsbCBmdXR1cmUgdW5kZWxlZ2F0aW9uIG9wZXJhdGlvbnMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwZXJpb2Q6IG5ldyBsb2NrdXAgcGVyaW9kIGluIHNlY29uZHMKZnVuYyAoZyAqZ292U3Rha2VyVjEpIHNldFVuRGVsZWdhdGlvbkxvY2t1cFBlcmlvZChfIGludCwgcmxtIHJlYWxtLCBwZXJpb2QgaW50NjQpIHsKCWlmIGVyciA6PSBnLnN0b3JlLlNldFVuRGVsZWdhdGlvbkxvY2t1cFBlcmlvZCgwLCBybG0sIHBlcmlvZCk7IGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KfQoKLy8gbmV4dERlbGVnYXRpb25JRCBnZW5lcmF0ZXMgYW5kIHJldHVybnMgdGhlIG5leHQgdW5pcXVlIGRlbGVnYXRpb24gSUQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogbmV4dCBhdmFpbGFibGUgZGVsZWdhdGlvbiBJRApmdW5jIChnICpnb3ZTdGFrZXJWMSkgbmV4dERlbGVnYXRpb25JRCgpIGludDY0IHsKCWNvdW50ZXIgOj0gZy5zdG9yZS5HZXREZWxlZ2F0aW9uQ291bnRlcigpCgoJcmV0dXJuIGNvdW50ZXIuTmV4dCgpCn0KCi8vIGdldERlbGVnYXRpb24gcmV0cmlldmVzIGEgZGVsZWdhdGlvbiBieSBpdHMgSUQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBkZWxlZ2F0aW9uSUQ6IHVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBkZWxlZ2F0aW9uCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqRGVsZWdhdGlvbjogZGVsZWdhdGlvbiBpbnN0YW5jZSBvciBuaWwgaWYgbm90IGZvdW5kCmZ1bmMgKGcgKmdvdlN0YWtlclYxKSBnZXREZWxlZ2F0aW9uKGRlbGVnYXRpb25JRCBpbnQ2NCkgKnN0YWtlci5EZWxlZ2F0aW9uIHsKCWRlbGVnYXRpb24sIGV4aXN0cyA6PSBnLnN0b3JlLkdldERlbGVnYXRpb24oZGVsZWdhdGlvbklEKQoJaWYgIWV4aXN0cyB7CgkJcmV0dXJuIG5pbAoJfQoJcmV0dXJuIGRlbGVnYXRpb24KfQoKLy8gc2V0RGVsZWdhdGlvbiBzdG9yZXMgb3IgdXBkYXRlcyBhIGRlbGVnYXRpb24gaW4gdGhlIHN0b3JhZ2UgdHJlZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGRlbGVnYXRpb25JRDogdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGRlbGVnYXRpb24KLy8gICAtIGRlbGVnYXRpb246IGRlbGVnYXRpb24gaW5zdGFuY2UgdG8gc3RvcmUKLy8KLy8gUmV0dXJuczoKLy8gICAtIGVycm9yOiBuaWwgb24gc3VjY2Vzcywgb3RoZXJ3aXNlIHRoZSBzdG9yYWdlIHdyaXRlIGVycm9yCmZ1bmMgKGcgKmdvdlN0YWtlclYxKSBzZXREZWxlZ2F0aW9uKF8gaW50LCBybG0gcmVhbG0sIGRlbGVnYXRpb25JRCBpbnQ2NCwgZGVsZWdhdGlvbiAqc3Rha2VyLkRlbGVnYXRpb24pIGVycm9yIHsKCXJldHVybiBnLnN0b3JlLlNldERlbGVnYXRpb24oMCwgcmxtLCBkZWxlZ2F0aW9uSUQsIGRlbGVnYXRpb24pCn0KCi8vIGFkZERlbGVnYXRpb24gYWRkcyBhIG5ldyBkZWxlZ2F0aW9uIHRvIHN0b3JhZ2UgYW5kIHVwZGF0ZXMgdGhlIGRlbGVnYXRpb24gbWFuYWdlci4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGRlbGVnYXRpb25JRDogdW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGRlbGVnYXRpb24gdG8gYWRkCi8vICAgLSBkZWxlZ2F0aW9uOiBkZWxlZ2F0aW9uIGluc3RhbmNlIHRvIGFkZAovLwovLyBSZXR1cm5zOgovLyAgIC0gZXJyb3I6IG5pbCBvbiBzdWNjZXNzLCBvdGhlcndpc2UgdGhlIGRlbGVnYXRpb24gb3IgbWFuYWdlciBzdG9yYWdlIGVycm9yCmZ1bmMgKGcgKmdvdlN0YWtlclYxKSBhZGREZWxlZ2F0aW9uKF8gaW50LCBybG0gcmVhbG0sIGRlbGVnYXRpb25JRCBpbnQ2NCwgZGVsZWdhdGlvbiAqc3Rha2VyLkRlbGVnYXRpb24pIGVycm9yIHsKCWlmIGVyciA6PSBnLnNldERlbGVnYXRpb24oMCwgcmxtLCBkZWxlZ2F0aW9uSUQsIGRlbGVnYXRpb24pOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJZGVsZWdhdGlvbk1hbmFnZXIgOj0gZy5zdG9yZS5HZXREZWxlZ2F0aW9uTWFuYWdlcigpCglyZXNvbHZlZE1hbmFnZXIgOj0gTmV3RGVsZWdhdGlvbk1hbmFnZXJSZXNvbHZlcihkZWxlZ2F0aW9uTWFuYWdlcikKCXJlc29sdmVkTWFuYWdlci5hZGREZWxlZ2F0aW9uKAoJCWRlbGVnYXRpb24uRGVsZWdhdGVGcm9tKCksCgkJZGVsZWdhdGlvbi5EZWxlZ2F0ZVRvKCksCgkJZGVsZWdhdGlvbklELAoJKQoKCXJldHVybiBnLnN0b3JlLlNldERlbGVnYXRpb25NYW5hZ2VyKDAsIHJsbSwgZGVsZWdhdGlvbk1hbmFnZXIpCn0KCi8vIHJlbW92ZURlbGVnYXRpb24gcmVtb3ZlcyBhIGRlbGVnYXRpb24gZnJvbSBzdG9yYWdlIGFuZCB1cGRhdGVzIHRoZSBkZWxlZ2F0aW9uIG1hbmFnZXIuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBkZWxlZ2F0aW9uSUQ6IHVuaXF1ZSBpZGVudGlmaWVyIG9mIHRoZSBkZWxlZ2F0aW9uIHRvIHJlbW92ZQovLwovLyBSZXR1cm5zOgovLyAgIC0gZXJyb3I6IG5pbCBvbiBzdWNjZXNzLCBvdGhlcndpc2UgYW4gZXJyb3Igd2hlbiB0aGUgZGVsZWdhdGlvbiBpcyBhYnNlbnQgb3Igc3RvcmFnZSBmYWlscwpmdW5jIChnICpnb3ZTdGFrZXJWMSkgcmVtb3ZlRGVsZWdhdGlvbihfIGludCwgcmxtIHJlYWxtLCBkZWxlZ2F0aW9uSUQgaW50NjQpIGVycm9yIHsKCWRlbGVnYXRpb24gOj0gZy5nZXREZWxlZ2F0aW9uKGRlbGVnYXRpb25JRCkKCWlmIGRlbGVnYXRpb24gPT0gbmlsIHsKCQlyZXR1cm4gZXJyb3JzLk5ldyhlcnJEZWxlZ2F0aW9uTm90Rm91bmQpCgl9CgoJaWYgZXJyIDo9IGcuc3RvcmUuUmVtb3ZlRGVsZWdhdGlvbigwLCBybG0sIGRlbGVnYXRpb25JRCk7IGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCglkZWxlZ2F0aW9uTWFuYWdlciA6PSBnLnN0b3JlLkdldERlbGVnYXRpb25NYW5hZ2VyKCkKCXJlc29sdmVkTWFuYWdlciA6PSBOZXdEZWxlZ2F0aW9uTWFuYWdlclJlc29sdmVyKGRlbGVnYXRpb25NYW5hZ2VyKQoJcmVzb2x2ZWRNYW5hZ2VyLnJlbW92ZURlbGVnYXRpb24oCgkJZGVsZWdhdGlvbi5EZWxlZ2F0ZUZyb20oKSwKCQlkZWxlZ2F0aW9uLkRlbGVnYXRlVG8oKSwKCQlkZWxlZ2F0aW9uSUQsCgkpCgoJcmV0dXJuIGcuc3RvcmUuU2V0RGVsZWdhdGlvbk1hbmFnZXIoMCwgcmxtLCBkZWxlZ2F0aW9uTWFuYWdlcikKfQoKLy8gZ2V0VXNlckRlbGVnYXRpb25zIHJldHJpZXZlcyBhbGwgZGVsZWdhdGlvbnMgZm9yIGEgc3BlY2lmaWMgdXNlci4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHVzZXI6IHVzZXIncyBhZGRyZXNzCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqYnB0cmVlLkJQVHJlZTogdHJlZSBvZiB1c2VyJ3MgZGVsZWdhdGlvbnMKZnVuYyAoZyAqZ292U3Rha2VyVjEpIGdldFVzZXJEZWxlZ2F0aW9ucyh1c2VyIGFkZHJlc3MpICpicHRyZWUuQlBUcmVlIHsKCWRlbGVnYXRpb25NYW5hZ2VyIDo9IGcuc3RvcmUuR2V0RGVsZWdhdGlvbk1hbmFnZXIoKQoKCXVzZXJEZWxlZ2F0aW9ucywgZXhpc3RzIDo9IGRlbGVnYXRpb25NYW5hZ2VyLkdldERlbGVnYXRvckRlbGVnYXRpb25zKHVzZXIuU3RyaW5nKCkpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gc3Rha2VyLk5ld1VzZXJEZWxlZ2F0aW9uVHJlZSgpCgl9CgoJcmV0dXJuIHVzZXJEZWxlZ2F0aW9ucwp9CgovLyBnZXRVc2VyRGVsZWdhdGlvbnNXaXRoRGVsZWdhdGVlIHJldHJpZXZlcyBhbGwgZGVsZWdhdGlvbnMgZnJvbSBhIHVzZXIgdG8gYSBzcGVjaWZpYyBkZWxlZ2F0ZWUuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB1c2VyOiB1c2VyJ3MgYWRkcmVzcwovLyAgIC0gZGVsZWdhdGVlOiBkZWxlZ2F0ZWUncyBhZGRyZXNzCi8vCi8vIFJldHVybnM6Ci8vICAgLSBbXWludDY0OiBsaXN0IG9mIHVzZXIncyBkZWxlZ2F0aW9uIElEcyB0byB0aGUgZGVsZWdhdGVlCmZ1bmMgKGcgKmdvdlN0YWtlclYxKSBnZXRVc2VyRGVsZWdhdGlvbklEc1dpdGhEZWxlZ2F0ZWUodXNlciBhZGRyZXNzLCBkZWxlZ2F0ZWUgYWRkcmVzcykgW11pbnQ2NCB7CglkZWxlZ2F0aW9uTWFuYWdlciA6PSBnLnN0b3JlLkdldERlbGVnYXRpb25NYW5hZ2VyKCkKCgl1c2VyRGVsZWdhdGlvbnMsIGV4aXN0cyA6PSBkZWxlZ2F0aW9uTWFuYWdlci5HZXREZWxlZ2F0b3JEZWxlZ2F0aW9ucyh1c2VyLlN0cmluZygpKQoJaWYgIWV4aXN0cyB7CgkJcmV0dXJuIG5pbAoJfQoKCWRlbGVnYXRlZVN0ciA6PSBkZWxlZ2F0ZWUuU3RyaW5nKCkKCWRlbGVnYXRpb25JRHMgOj0gdXNlckRlbGVnYXRpb25zLkdldChkZWxlZ2F0ZWVTdHIpCglpZiBkZWxlZ2F0aW9uSURzID09IG5pbCB7CgkJcmV0dXJuIG5pbAoJfQoKCWlkcywgb2sgOj0gZGVsZWdhdGlvbklEcy4oW11pbnQ2NCkKCWlmICFvayB7CgkJcmV0dXJuIG5pbAoJfQoKCXJldHVybiBpZHMKfQoKLy8gYWRkRGVsZWdhdGlvblJlY29yZCByZWNvcmRzIGEgZGVsZWdhdGlvbiBjaGFuZ2UgaW4gdGhlIGhpc3RvcnkuCi8vIFVwZGF0ZXMgYm90aCB0b3RhbCBhbmQgdXNlciBkZWxlZ2F0aW9uIGhpc3RvcmllcyB3aXRoIGN1bXVsYXRpdmUgdmFsdWVzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gZGVsZWdhdGVlQWRkcjogYWRkcmVzcyBvZiB0aGUgZGVsZWdhdGVlCi8vICAgLSBhbW91bnQ6IGFtb3VudCBjaGFuZ2UgKHBvc2l0aXZlIGZvciBkZWxlZ2F0ZSwgbmVnYXRpdmUgZm9yIHVuZGVsZWdhdGUpCi8vICAgLSB0aW1lc3RhbXA6IHRpbWVzdGFtcCBvZiB0aGUgZGVsZWdhdGlvbiBjaGFuZ2UKZnVuYyAoZyAqZ292U3Rha2VyVjEpIGFkZERlbGVnYXRpb25SZWNvcmQoXyBpbnQsIHJsbSByZWFsbSwgZGVsZWdhdGVlQWRkciBhZGRyZXNzLCBhbW91bnQgaW50NjQsIHRpbWVzdGFtcCBpbnQ2NCkgewoJLy8gVXBkYXRlIHRvdGFsIGRlbGVnYXRpb24gaGlzdG9yeQoJZy51cGRhdGVUb3RhbERlbGVnYXRpb25IaXN0b3J5KDAsIHJsbSwgYW1vdW50LCB0aW1lc3RhbXApCgoJLy8gVXBkYXRlIHVzZXIgZGVsZWdhdGlvbiBoaXN0b3J5CglnLnVwZGF0ZVVzZXJEZWxlZ2F0aW9uSGlzdG9yeSgwLCBybG0sIGRlbGVnYXRlZUFkZHIsIGFtb3VudCwgdGltZXN0YW1wKQp9CgovLyB1cGRhdGVUb3RhbERlbGVnYXRpb25IaXN0b3J5IHVwZGF0ZXMgdGhlIHRvdGFsIGRlbGVnYXRpb24gaGlzdG9yeSB3aXRoIGN1bXVsYXRpdmUgdmFsdWUuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBhbW91bnQ6IGFtb3VudCBjaGFuZ2UgKHBvc2l0aXZlIGZvciBkZWxlZ2F0ZSwgbmVnYXRpdmUgZm9yIHVuZGVsZWdhdGUpCi8vICAgLSB0aW1lc3RhbXA6IHRpbWVzdGFtcCBvZiB0aGUgY2hhbmdlCmZ1bmMgKGcgKmdvdlN0YWtlclYxKSB1cGRhdGVUb3RhbERlbGVnYXRpb25IaXN0b3J5KF8gaW50LCBybG0gcmVhbG0sIGFtb3VudCBpbnQ2NCwgdGltZXN0YW1wIGludDY0KSB7CgloaXN0b3J5IDo9IGcuc3RvcmUuR2V0VG90YWxEZWxlZ2F0aW9uSGlzdG9yeSgpCgoJLy8gR2V0IGN1cnJlbnQgdG90YWwgZnJvbSB0aGUgbW9zdCByZWNlbnQgZW50cnkKCWN1cnJlbnRUb3RhbCA6PSBnLmdldExhdGVzdFRvdGFsRGVsZWdhdGlvbihoaXN0b3J5KQoJbmV3VG90YWwgOj0gZ25zbWF0aC5TYWZlQWRkSW50NjQoY3VycmVudFRvdGFsLCBhbW91bnQpCgoJaWYgbmV3VG90YWwgPCAwIHsKCQluZXdUb3RhbCA9IDAKCX0KCgloaXN0b3J5LlNldCh0aW1lc3RhbXAsIG5ld1RvdGFsKQoKCWlmIGVyciA6PSBnLnN0b3JlLlNldFRvdGFsRGVsZWdhdGlvbkhpc3RvcnkoMCwgcmxtLCBoaXN0b3J5KTsgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQp9CgovLyB1cGRhdGVVc2VyRGVsZWdhdGlvbkhpc3RvcnkgdXBkYXRlcyB0aGUgdXNlciBkZWxlZ2F0aW9uIGhpc3Rvcnkgd2l0aCBjdW11bGF0aXZlIHZhbHVlcy4KLy8gU3RydWN0dXJlOiBzaW5nbGUgQlBUcmVlIGtleWVkIGJ5IGNvbXBvc2l0ZSBrZXkgImFkZHJTdHJ8cGFkZGVkVGltZXN0YW1wIiAtPiBpbnQ2NAovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gZGVsZWdhdGVlQWRkcjogYWRkcmVzcyBvZiB0aGUgZGVsZWdhdGVlCi8vICAgLSBhbW91bnQ6IGFtb3VudCBjaGFuZ2UgKHBvc2l0aXZlIGZvciBkZWxlZ2F0ZSwgbmVnYXRpdmUgZm9yIHVuZGVsZWdhdGUpCi8vICAgLSB0aW1lc3RhbXA6IHRpbWVzdGFtcCBvZiB0aGUgY2hhbmdlCmZ1bmMgKGcgKmdvdlN0YWtlclYxKSB1cGRhdGVVc2VyRGVsZWdhdGlvbkhpc3RvcnkoXyBpbnQsIHJsbSByZWFsbSwgZGVsZWdhdGVlQWRkciBhZGRyZXNzLCBhbW91bnQgaW50NjQsIHRpbWVzdGFtcCBpbnQ2NCkgewoJaGlzdG9yeSA6PSBnLnN0b3JlLkdldFVzZXJEZWxlZ2F0aW9uSGlzdG9yeSgpCglhZGRyU3RyIDo9IGRlbGVnYXRlZUFkZHIuU3RyaW5nKCkKCgkvLyBHZXQgY3VycmVudCBhbW91bnQgZnJvbSB0aGUgbW9zdCByZWNlbnQgZW50cnkgZm9yIHRoaXMgdXNlcgoJY3VycmVudEFtb3VudCA6PSBnLmdldExhdGVzdFVzZXJEZWxlZ2F0aW9uQnlBZGRyZXNzKGhpc3RvcnksIGFkZHJTdHIpCgluZXdBbW91bnQgOj0gZ25zbWF0aC5TYWZlQWRkSW50NjQoY3VycmVudEFtb3VudCwgYW1vdW50KQoJaWYgbmV3QW1vdW50IDwgMCB7CgkJbmV3QW1vdW50ID0gMAoJfQoKCS8vIFN0b3JlIG5ldyBjdW11bGF0aXZlIHZhbHVlIHVuZGVyIGNvbXBvc2l0ZSBrZXkKCWhpc3RvcnkuU2V0KG1ha2VVc2VySGlzdG9yeUtleShhZGRyU3RyLCB0aW1lc3RhbXApLCBuZXdBbW91bnQpCgoJaWYgZXJyIDo9IGcuc3RvcmUuU2V0VXNlckRlbGVnYXRpb25IaXN0b3J5KDAsIHJsbSwgaGlzdG9yeSk7IGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KfQoKLy8gZ2V0TGF0ZXN0VG90YWxEZWxlZ2F0aW9uIGdldHMgdGhlIGxhdGVzdCB0b3RhbCBkZWxlZ2F0aW9uIGFtb3VudCBmcm9tIGhpc3RvcnkuCmZ1bmMgKGcgKmdvdlN0YWtlclYxKSBnZXRMYXRlc3RUb3RhbERlbGVnYXRpb24oaGlzdG9yeSAqc3Rha2VyLlVpbnRUcmVlKSBpbnQ2NCB7CglpZiBoaXN0b3J5LlNpemUoKSA9PSAwIHsKCQlyZXR1cm4gMAoJfQoKCWxhdGVzdFRvdGFsIDo9IGludDY0KDApCgoJaGlzdG9yeS5SZXZlcnNlSXRlcmF0ZSgwLCBtYXRoLk1heEludDY0LCBmdW5jKGtleSBpbnQ2NCwgdmFsdWUgYW55KSBib29sIHsKCQl0b3RhbEludCwgb2sgOj0gdmFsdWUuKGludDY0KQoJCWlmICFvayB7CgkJCXBhbmljKHVmbXQuU3ByaW50ZigiaW52YWxpZCB0b3RhbCB0eXBlOiAlVCIsIHZhbHVlKSkKCQl9CgoJCWxhdGVzdFRvdGFsID0gdG90YWxJbnQKCgkJcmV0dXJuIHRydWUgLy8gc3RvcCBhZnRlciBmaXJzdCAobW9zdCByZWNlbnQpIGVudHJ5Cgl9KQoKCXJldHVybiBsYXRlc3RUb3RhbAp9CgovLyBnZXRMYXRlc3RVc2VyRGVsZWdhdGlvbkJ5QWRkcmVzcyBnZXRzIHRoZSBsYXRlc3QgZGVsZWdhdGlvbiBhbW91bnQgZm9yIGEgdXNlcgovLyBmcm9tIHRoZSBjb21wb3NpdGUta2V5ZWQgdXNlciBkZWxlZ2F0aW9uIGhpc3RvcnkuCmZ1bmMgKGcgKmdvdlN0YWtlclYxKSBnZXRMYXRlc3RVc2VyRGVsZWdhdGlvbkJ5QWRkcmVzcyhoaXN0b3J5ICpicHRyZWUuQlBUcmVlLCBhZGRyU3RyIHN0cmluZykgaW50NjQgewoJbG8sIGhpIDo9IHVzZXJIaXN0b3J5S2V5UmFuZ2UoYWRkclN0cikKCglsYXRlc3RBbW91bnQgOj0gaW50NjQoMCkKCgloaXN0b3J5LlJldmVyc2VJdGVyYXRlKGxvLCBoaSwgZnVuYyhfIHN0cmluZywgdmFsdWUgYW55KSBib29sIHsKCQlhbW91bnRJbnQsIG9rIDo9IHZhbHVlLihpbnQ2NCkKCQlpZiAhb2sgewoJCQlwYW5pYyh1Zm10LlNwcmludGYoImludmFsaWQgYW1vdW50IHR5cGU6ICVUIiwgdmFsdWUpKQoJCX0KCgkJbGF0ZXN0QW1vdW50ID0gYW1vdW50SW50CgoJCXJldHVybiB0cnVlIC8vIHN0b3AgYWZ0ZXIgZmlyc3QgKG1vc3QgcmVjZW50KSBlbnRyeQoJfSkKCglyZXR1cm4gbGF0ZXN0QW1vdW50Cn0KCi8vIGFkZFN0YWtlRW1pc3Npb25SZXdhcmQgYWRkcyBzdGFrZSB0byBlbWlzc2lvbiByZXdhcmQgdHJhY2tpbmcgZm9yIGFuIGFkZHJlc3MuCi8vIFRoaXMgbWV0aG9kIHVwZGF0ZXMgdGhlIGVtaXNzaW9uIHJld2FyZCBkaXN0cmlidXRpb24gc3RhdGUgYW5kIGFkZHMgc3Rha2UgZm9yIHRoZSBzcGVjaWZpZWQgYWRkcmVzcy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGFkZHJlc3M6IHN0YWtlcidzIGFkZHJlc3MKLy8gICAtIGFtb3VudDogYW1vdW50IG9mIHN0YWtlIHRvIGFkZAovLyAgIC0gY3VycmVudFRpbWVzdGFtcDogY3VycmVudCB0aW1lc3RhbXAKZnVuYyAoZyAqZ292U3Rha2VyVjEpIGFkZFN0YWtlRW1pc3Npb25SZXdhcmQoXyBpbnQsIHJsbSByZWFsbSwgYWRkcmVzcyBzdHJpbmcsIGFtb3VudCBpbnQ2NCwgY3VycmVudFRpbWVzdGFtcCBpbnQ2NCkgZXJyb3IgewoJZGlzdHJpYnV0ZWRBbW91bnQgOj0gZW1pc3Npb24uR2V0QWNjdURpc3RyaWJ1dGVkVG9Hb3ZTdGFrZXIoKQoKCWVtaXNzaW9uUmV3YXJkTWFuYWdlciA6PSBnLnN0b3JlLkdldEVtaXNzaW9uUmV3YXJkTWFuYWdlcigpCglyZXNvbHZlZE1hbmFnZXIgOj0gTmV3RW1pc3Npb25SZXdhcmRNYW5hZ2VyUmVzb2x2ZXIoZW1pc3Npb25SZXdhcmRNYW5hZ2VyKQoKCWlmIGVyciA6PSByZXNvbHZlZE1hbmFnZXIudXBkYXRlQWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UoZGlzdHJpYnV0ZWRBbW91bnQsIGN1cnJlbnRUaW1lc3RhbXApOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJaWYgZXJyIDo9IHJlc29sdmVkTWFuYWdlci5hZGRTdGFrZShhZGRyZXNzLCBhbW91bnQsIGN1cnJlbnRUaW1lc3RhbXApOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJZXJyIDo9IGcuc3RvcmUuU2V0RW1pc3Npb25SZXdhcmRNYW5hZ2VyKDAsIHJsbSwgZW1pc3Npb25SZXdhcmRNYW5hZ2VyKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCS8vIEVtaXQgdGhlIGVtaXNzaW9uIHJld2FyZCBhY2N1bXVsYXRpb24KCWVtaXRVcGRhdGVFbWlzc2lvblJld2FyZEFjY3VtdWxhdGlvbihlbWlzc2lvblJld2FyZE1hbmFnZXIpCgoJcmV0dXJuIG5pbAp9CgovLyByZW1vdmVTdGFrZUVtaXNzaW9uUmV3YXJkIHJlbW92ZXMgc3Rha2UgZnJvbSBlbWlzc2lvbiByZXdhcmQgdHJhY2tpbmcgZm9yIGFuIGFkZHJlc3MuCi8vIFRoaXMgbWV0aG9kIHVwZGF0ZXMgdGhlIGVtaXNzaW9uIHJld2FyZCBkaXN0cmlidXRpb24gc3RhdGUgYW5kIHJlbW92ZXMgc3Rha2UgZm9yIHRoZSBzcGVjaWZpZWQgYWRkcmVzcy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGFkZHJlc3M6IHN0YWtlcidzIGFkZHJlc3MKLy8gICAtIGFtb3VudDogYW1vdW50IG9mIHN0YWtlIHRvIHJlbW92ZQovLyAgIC0gY3VycmVudFRpbWVzdGFtcDogY3VycmVudCB0aW1lc3RhbXAKZnVuYyAoZyAqZ292U3Rha2VyVjEpIHJlbW92ZVN0YWtlRW1pc3Npb25SZXdhcmQoXyBpbnQsIHJsbSByZWFsbSwgYWRkcmVzcyBzdHJpbmcsIGFtb3VudCBpbnQ2NCwgY3VycmVudFRpbWVzdGFtcCBpbnQ2NCkgZXJyb3IgewoJZGlzdHJpYnV0ZWRBbW91bnQgOj0gZW1pc3Npb24uR2V0QWNjdURpc3RyaWJ1dGVkVG9Hb3ZTdGFrZXIoKQoKCWVtaXNzaW9uUmV3YXJkTWFuYWdlciA6PSBnLnN0b3JlLkdldEVtaXNzaW9uUmV3YXJkTWFuYWdlcigpCglyZXNvbHZlZE1hbmFnZXIgOj0gTmV3RW1pc3Npb25SZXdhcmRNYW5hZ2VyUmVzb2x2ZXIoZW1pc3Npb25SZXdhcmRNYW5hZ2VyKQoKCWlmIGVyciA6PSByZXNvbHZlZE1hbmFnZXIudXBkYXRlQWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UoZGlzdHJpYnV0ZWRBbW91bnQsIGN1cnJlbnRUaW1lc3RhbXApOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJaWYgZXJyIDo9IHJlc29sdmVkTWFuYWdlci5yZW1vdmVTdGFrZShhZGRyZXNzLCBhbW91bnQsIGN1cnJlbnRUaW1lc3RhbXApOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJaWYgZXJyIDo9IGcuc3RvcmUuU2V0RW1pc3Npb25SZXdhcmRNYW5hZ2VyKDAsIHJsbSwgZW1pc3Npb25SZXdhcmRNYW5hZ2VyKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCS8vIEVtaXQgdGhlIGVtaXNzaW9uIHJld2FyZCBhY2N1bXVsYXRpb24KCWVtaXRVcGRhdGVFbWlzc2lvblJld2FyZEFjY3VtdWxhdGlvbihlbWlzc2lvblJld2FyZE1hbmFnZXIpCgoJcmV0dXJuIG5pbAp9CgovLyBjbGFpbVJld2FyZHNFbWlzc2lvblJld2FyZCBjbGFpbXMgZW1pc3Npb24gcmV3YXJkcyBmb3IgYW4gYWRkcmVzcy4KLy8gVGhpcyBtZXRob2QgdXBkYXRlcyB0aGUgZW1pc3Npb24gcmV3YXJkIGRpc3RyaWJ1dGlvbiBzdGF0ZSBhbmQgcHJvY2Vzc2VzIHJld2FyZCBjbGFpbWluZy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGFkZHJlc3M6IHN0YWtlcidzIGFkZHJlc3MgY2xhaW1pbmcgcmV3YXJkcwovLyAgIC0gY3VycmVudFRpbWVzdGFtcDogY3VycmVudCB0aW1lc3RhbXAKLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBhbW91bnQgb2YgZW1pc3Npb24gcmV3YXJkcyBjbGFpbWVkCi8vICAgLSBlcnJvcjogbmlsIG9uIHN1Y2Nlc3MsIGVycm9yIGlmIGNsYWltaW5nIGZhaWxzCmZ1bmMgKGcgKmdvdlN0YWtlclYxKSBjbGFpbVJld2FyZHNFbWlzc2lvblJld2FyZChfIGludCwgcmxtIHJlYWxtLCBhZGRyZXNzIHN0cmluZywgY3VycmVudFRpbWVzdGFtcCBpbnQ2NCkgKGludDY0LCBlcnJvcikgewoJZGlzdHJpYnV0ZWRBbW91bnQgOj0gZW1pc3Npb24uR2V0QWNjdURpc3RyaWJ1dGVkVG9Hb3ZTdGFrZXIoKQoKCWVtaXNzaW9uUmV3YXJkTWFuYWdlciA6PSBnLnN0b3JlLkdldEVtaXNzaW9uUmV3YXJkTWFuYWdlcigpCglyZXNvbHZlZE1hbmFnZXIgOj0gTmV3RW1pc3Npb25SZXdhcmRNYW5hZ2VyUmVzb2x2ZXIoZW1pc3Npb25SZXdhcmRNYW5hZ2VyKQoKCWlmIGVyciA6PSByZXNvbHZlZE1hbmFnZXIudXBkYXRlQWNjdW11bGF0ZWRSZXdhcmRYMTI4UGVyU3Rha2UoZGlzdHJpYnV0ZWRBbW91bnQsIGN1cnJlbnRUaW1lc3RhbXApOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CgoJYW1vdW50LCBlcnIgOj0gcmVzb2x2ZWRNYW5hZ2VyLmNsYWltUmV3YXJkcyhhZGRyZXNzLCBjdXJyZW50VGltZXN0YW1wKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoKCWlmIGVyciA6PSBnLnN0b3JlLlNldEVtaXNzaW9uUmV3YXJkTWFuYWdlcigwLCBybG0sIGVtaXNzaW9uUmV3YXJkTWFuYWdlcik7IGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCgkvLyBFbWl0IHRoZSBlbWlzc2lvbiByZXdhcmQgYWNjdW11bGF0aW9uCgllbWl0VXBkYXRlRW1pc3Npb25SZXdhcmRBY2N1bXVsYXRpb24oZW1pc3Npb25SZXdhcmRNYW5hZ2VyKQoKCXJldHVybiBhbW91bnQsIG5pbAp9CgovLyByZW1vdmVMYXVuY2hwYWRQcm9qZWN0RGVwb3NpdCByZW1vdmVzIGEgbGF1bmNocGFkIHByb2plY3QgZGVwb3NpdCByZWNvcmQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBvd25lckFkZHJlc3M6IHByb2plY3Qgb3duZXIncyBhZGRyZXNzIGlkZW50aWZpZXIKLy8KLy8gUmV0dXJuczoKLy8gICAtIGJvb2w6IHRydWUgaWYgc3VjY2Vzc2Z1bGx5IHJlbW92ZWQKZnVuYyAoZyAqZ292U3Rha2VyVjEpIHJlbW92ZUxhdW5jaHBhZFByb2plY3REZXBvc2l0KG93bmVyQWRkcmVzcyBzdHJpbmcpIGJvb2wgewoJbGF1bmNocGFkUHJvamVjdERlcG9zaXRzIDo9IGcuc3RvcmUuR2V0TGF1bmNocGFkUHJvamVjdERlcG9zaXRzKCkKCXJldHVybiBsYXVuY2hwYWRQcm9qZWN0RGVwb3NpdHMuUmVtb3ZlRGVwb3NpdChvd25lckFkZHJlc3MpCn0KCi8vIGFkZFN0YWtlUHJvdG9jb2xGZWVSZXdhcmQgcmVjb3JkcyBhIHN0YWtlIGluY3JlYXNlIGZvciBwcm90b2NvbCBmZWUgcmV3YXJkcy4KLy8KLy8gVGhlIGNoYW5nZSBvbmx5IG9wZW5zIGEgbmV3IGFjY3J1YWwgZXBvY2ggYW5kIGFwcGVuZHMgb25lIHN0YWtlIGV2ZW50LCBzbyBpdHMgY29zdAovLyBkb2VzIG5vdCBkZXBlbmQgb24gaG93IG1hbnkgdG9rZW5zIGNvbGxlY3RlZCBmZWVzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gYWRkcmVzczogc3Rha2VyJ3MgYWRkcmVzcwovLyAgIC0gYW1vdW50OiBhbW91bnQgb2Ygc3Rha2UgdG8gYWRkCi8vICAgLSBjdXJyZW50VGltZXN0YW1wOiBjdXJyZW50IHRpbWVzdGFtcApmdW5jIChnICpnb3ZTdGFrZXJWMSkgYWRkU3Rha2VQcm90b2NvbEZlZVJld2FyZChfIGludCwgcmxtIHJlYWxtLCBhZGRyZXNzIHN0cmluZywgYW1vdW50IGludDY0LCBjdXJyZW50VGltZXN0YW1wIGludDY0KSBlcnJvciB7CgllcG9jaCA6PSBwZi5BZHZhbmNlQWNjcnVhbEVwb2NoKGNyb3NzKHJsbSkpCgoJcHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyIDo9IGcuc3RvcmUuR2V0UHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKCkKCXJlc29sdmVkTWFuYWdlciA6PSBOZXdQcm90b2NvbEZlZVJld2FyZE1hbmFnZXJSZXNvbHZlcihwcm90b2NvbEZlZVJld2FyZE1hbmFnZXIpCgoJaWYgZXJyIDo9IHJlc29sdmVkTWFuYWdlci5hZGRTdGFrZShhZGRyZXNzLCBhbW91bnQsIGVwb2NoKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoJcmVzb2x2ZWRNYW5hZ2VyLlNldEFjY3VtdWxhdGVkVGltZXN0YW1wKGN1cnJlbnRUaW1lc3RhbXApCgoJaWYgZXJyIDo9IGcuc3RvcmUuU2V0UHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKDAsIHJsbSwgcHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCWVtaXRVcGRhdGVQcm90b2NvbEZlZVN0YWtlQWNjcnVhbChwcm90b2NvbEZlZVJld2FyZE1hbmFnZXIpCgoJcmV0dXJuIG5pbAp9CgovLyByZW1vdmVTdGFrZVByb3RvY29sRmVlUmV3YXJkIHJlY29yZHMgYSBzdGFrZSBkZWNyZWFzZSBmb3IgcHJvdG9jb2wgZmVlIHJld2FyZHMuCi8vIExpa2UgYWRkU3Rha2VQcm90b2NvbEZlZVJld2FyZCBpdCBuZXZlciBmb2xkcyBmZWVzLCBzbyBhIHdpdGhkcmF3YWwgbmV2ZXIgcGF5cyBmb3IKLy8gdGhlIHJld2FyZCBjYWxjdWxhdGlvbjsgdGhhdCBoYXBwZW5zIG9uIGNvbGxlY3QsIG9uZSB0b2tlbiBhdCBhIHRpbWUgaWYgbmVlZCBiZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGFkZHJlc3M6IHN0YWtlcidzIGFkZHJlc3MKLy8gICAtIGFtb3VudDogYW1vdW50IG9mIHN0YWtlIHRvIHJlbW92ZQovLyAgIC0gY3VycmVudFRpbWVzdGFtcDogY3VycmVudCB0aW1lc3RhbXAKZnVuYyAoZyAqZ292U3Rha2VyVjEpIHJlbW92ZVN0YWtlUHJvdG9jb2xGZWVSZXdhcmQoXyBpbnQsIHJsbSByZWFsbSwgYWRkcmVzcyBzdHJpbmcsIGFtb3VudCBpbnQ2NCwgY3VycmVudFRpbWVzdGFtcCBpbnQ2NCkgZXJyb3IgewoJZXBvY2ggOj0gcGYuQWR2YW5jZUFjY3J1YWxFcG9jaChjcm9zcyhybG0pKQoKCXByb3RvY29sRmVlUmV3YXJkTWFuYWdlciA6PSBnLnN0b3JlLkdldFByb3RvY29sRmVlUmV3YXJkTWFuYWdlcigpCglyZXNvbHZlZE1hbmFnZXIgOj0gTmV3UHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyUmVzb2x2ZXIocHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKQoKCWlmIGVyciA6PSByZXNvbHZlZE1hbmFnZXIucmVtb3ZlU3Rha2UoYWRkcmVzcywgYW1vdW50LCBlcG9jaCk7IGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCXJlc29sdmVkTWFuYWdlci5TZXRBY2N1bXVsYXRlZFRpbWVzdGFtcChjdXJyZW50VGltZXN0YW1wKQoKCWlmIGVyciA6PSBnLnN0b3JlLlNldFByb3RvY29sRmVlUmV3YXJkTWFuYWdlcigwLCBybG0sIHByb3RvY29sRmVlUmV3YXJkTWFuYWdlcik7IGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCgllbWl0VXBkYXRlUHJvdG9jb2xGZWVTdGFrZUFjY3J1YWwocHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKQoKCXJldHVybiBuaWwKfQoKLy8gZm9sZFByb3RvY29sRmVlQWNjcnVhbCBjb25zdW1lcyB1cCB0byBsaW1pdCBwZW5kaW5nIGFjY3J1YWwgYnVja2V0cyBvZiB0b2tlblBhdGggZnJvbQovLyB0aGUgcHJvdG9jb2wgZmVlIHJlYWxtIGFuZCBmb2xkcyB0aGVtIGludG8gdGhlIHRva2VuJ3MgYWNjdW11bGF0b3IuIEEgbGltaXQgb2YgemVybwovLyBvciBsZXNzIGNvbnN1bWVzIGV2ZXJ5IHBlbmRpbmcgYnVja2V0LgpmdW5jIChnICpnb3ZTdGFrZXJWMSkgZm9sZFByb3RvY29sRmVlQWNjcnVhbChfIGludCwgcmxtIHJlYWxtLCByZXNvbHZlZE1hbmFnZXIgKlByb3RvY29sRmVlUmV3YXJkTWFuYWdlclJlc29sdmVyLCB0b2tlblBhdGggc3RyaW5nLCBsaW1pdCBpbnQsIGN1cnJlbnRUaW1lc3RhbXAgaW50NjQpIGVycm9yIHsKCWVwb2NocywgYW1vdW50cyA6PSBwZi5Db25zdW1lQWNjcnVhbEJ1Y2tldHMoY3Jvc3MocmxtKSwgdG9rZW5QYXRoLCBsaW1pdCkKCWV4aGF1c3RlZCA6PSBsaW1pdCA8PSAwIHx8IGxlbihlcG9jaHMpIDwgbGltaXQKCglyZXR1cm4gcmVzb2x2ZWRNYW5hZ2VyLmFwcGx5QWNjcnVhbEJ1Y2tldHModG9rZW5QYXRoLCBlcG9jaHMsIGFtb3VudHMsIGV4aGF1c3RlZCwgY3VycmVudFRpbWVzdGFtcCkKfQoKLy8gY2xhaW1SZXdhcmRzUHJvdG9jb2xGZWVSZXdhcmQgY2xhaW1zIHByb3RvY29sIGZlZSByZXdhcmRzIGZvciBhbiBhZGRyZXNzIGluIGV2ZXJ5IHRva2VuLgovLyBJdCBmb2xkcyBldmVyeSBwZW5kaW5nIHRva2VuIGZpcnN0LCBzbyBpdHMgY29zdCBncm93cyB3aXRoIHRoZSBudW1iZXIgb2YgdG9rZW5zCi8vIHRoYXQgY29sbGVjdGVkIGEgZmVlLiBjbGFpbVJld2FyZFByb3RvY29sRmVlUmV3YXJkQnlUb2tlblBhdGggaXMgdGhlIGJvdW5kZWQgcGF0aC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGFkZHJlc3M6IHN0YWtlcidzIGFkZHJlc3MgY2xhaW1pbmcgcmV3YXJkcwovLyAgIC0gY3VycmVudFRpbWVzdGFtcDogY3VycmVudCB0aW1lc3RhbXAKLy8KLy8gUmV0dXJuczoKLy8gICAtIG1hcFtzdHJpbmddaW50NjQ6IHByb3RvY29sIGZlZSByZXdhcmRzIGNsYWltZWQgYnkgdG9rZW4KLy8gICAtIGVycm9yOiBuaWwgb24gc3VjY2VzcywgZXJyb3IgaWYgY2xhaW1pbmcgZmFpbHMKZnVuYyAoZyAqZ292U3Rha2VyVjEpIGNsYWltUmV3YXJkc1Byb3RvY29sRmVlUmV3YXJkKF8gaW50LCBybG0gcmVhbG0sIGFkZHJlc3Mgc3RyaW5nLCBjdXJyZW50VGltZXN0YW1wIGludDY0KSAobWFwW3N0cmluZ11pbnQ2NCwgZXJyb3IpIHsKCS8vIENsYWltaW5nIHBheXMgb3V0IG9mIGdvdi9zdGFrZXIncyBvd24gYmFsYW5jZSwgc28gdGhlIHJlc2VydmVkIGZlZXMgYXJlIHB1bGxlZCBpbgoJLy8gZnJvbSB0aGUgcHJvdG9jb2wgZmVlIHJlYWxtIGZpcnN0LgoJcGYuRGlzdHJpYnV0ZVByb3RvY29sRmVlKGNyb3NzKHJsbSkpCgoJcHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyIDo9IGcuc3RvcmUuR2V0UHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKCkKCXJlc29sdmVkTWFuYWdlciA6PSBOZXdQcm90b2NvbEZlZVJld2FyZE1hbmFnZXJSZXNvbHZlcihwcm90b2NvbEZlZVJld2FyZE1hbmFnZXIpCgoJLy8gRXZlcnkgcGVuZGluZyB0b2tlbiBpcyBjb25zdW1lZCBmcm9tIHRoZSBwcm90b2NvbCBmZWUgcmVhbG0uIEEga25vd24gdG9rZW4gd2l0aAoJLy8gbm90aGluZyBwZW5kaW5nIGhhcyBubyBidWNrZXQgaW4gYW55IGVwb2NoIHNpbmNlIGl0cyBsYXN0IGZvbGQsIHNvIGFuIGVtcHR5CgkvLyBleGhhdXN0aXZlIGZvbGQgaXMgZW5vdWdoIHRvIG1hcmsgZXZlcnkgY2xvc2VkIGVwb2NoIGFzIHNldHRsZWQgZm9yIGl0LgoJcGVuZGluZ1Rva2VuUGF0aHMgOj0gcGYuR2V0QWNjcnVhbFBlbmRpbmdUb2tlbnMoKQoJcGVuZGluZyA6PSBtYWtlKG1hcFtzdHJpbmddYm9vbCwgbGVuKHBlbmRpbmdUb2tlblBhdGhzKSkKCWZvciBfLCB0b2tlblBhdGggOj0gcmFuZ2UgcGVuZGluZ1Rva2VuUGF0aHMgewoJCXBlbmRpbmdbdG9rZW5QYXRoXSA9IHRydWUKCQlpZiBlcnIgOj0gZy5mb2xkUHJvdG9jb2xGZWVBY2NydWFsKDAsIHJsbSwgcmVzb2x2ZWRNYW5hZ2VyLCB0b2tlblBhdGgsIDAsIGN1cnJlbnRUaW1lc3RhbXApOyBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIG5pbCwgZXJyCgkJfQoJfQoKCWZvbGRlZFRva2VuUGF0aHMgOj0gcGVuZGluZ1Rva2VuUGF0aHMKCWZvciBfLCB0b2tlblBhdGggOj0gcmFuZ2UgcHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyLkdldFRva2VuUGF0aHMoKSB7CgkJaWYgcGVuZGluZ1t0b2tlblBhdGhdIHsKCQkJY29udGludWUKCQl9CgkJaWYgZXJyIDo9IHJlc29sdmVkTWFuYWdlci5hcHBseUFjY3J1YWxCdWNrZXRzKHRva2VuUGF0aCwgW11pbnQ2NHt9LCBbXWludDY0e30sIHRydWUsIGN1cnJlbnRUaW1lc3RhbXApOyBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIG5pbCwgZXJyCgkJfQoJCWZvbGRlZFRva2VuUGF0aHMgPSBhcHBlbmQoZm9sZGVkVG9rZW5QYXRocywgdG9rZW5QYXRoKQoJfQoKCXJld2FyZHMsIGVyciA6PSByZXNvbHZlZE1hbmFnZXIuY2xhaW1SZXdhcmRzKGFkZHJlc3MsIGN1cnJlbnRUaW1lc3RhbXApCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBlcnIKCX0KCglpZiBlcnIgOj0gZy5zdG9yZS5TZXRQcm90b2NvbEZlZVJld2FyZE1hbmFnZXIoMCwgcmxtLCBwcm90b2NvbEZlZVJld2FyZE1hbmFnZXIpOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBlcnIKCX0KCgllbWl0VXBkYXRlUHJvdG9jb2xGZWVSZXdhcmRBY2N1bXVsYXRpb24ocHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyLCBmb2xkZWRUb2tlblBhdGhzKQoKCXJldHVybiByZXdhcmRzLCBuaWwKfQoKLy8gY2xhaW1SZXdhcmRQcm90b2NvbEZlZVJld2FyZEJ5VG9rZW5QYXRoIGNsYWltcyBvbmUgcHJvdG9jb2wgZmVlIHJld2FyZCB0b2tlbiBmb3IgYW4gYWRkcmVzcy4KLy8KLy8gQm90aCB0aGUgZm9sZCBhbmQgdGhlIHNldHRsZW1lbnQgYXJlIGJvdW5kZWQgcGVyIGNhbGwgKG1heEFjY3J1YWxCdWNrZXRzUGVyQ29sbGVjdCwKLy8gbWF4U3Rha2VFdmVudHNQZXJDb2xsZWN0KTsgYSB0b2tlbiB3aXRoIG1vcmUgcGVuZGluZyB3b3JrIHBheXMgd2hhdCBpcyBzZXR0bGVkIGFuZAovLyBrZWVwcyB0aGUgcmVzdCBmb3IgYSBsYXRlciBjb2xsZWN0LgpmdW5jIChnICpnb3ZTdGFrZXJWMSkgY2xhaW1SZXdhcmRQcm90b2NvbEZlZVJld2FyZEJ5VG9rZW5QYXRoKF8gaW50LCBybG0gcmVhbG0sIGFkZHJlc3Mgc3RyaW5nLCB0b2tlblBhdGggc3RyaW5nLCBjdXJyZW50VGltZXN0YW1wIGludDY0KSAoaW50NjQsIGVycm9yKSB7CglwZi5EaXN0cmlidXRlUHJvdG9jb2xGZWVCeVRva2VuUGF0aChjcm9zcyhybG0pLCB0b2tlblBhdGgpCgoJcHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyIDo9IGcuc3RvcmUuR2V0UHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKCkKCXJlc29sdmVkTWFuYWdlciA6PSBOZXdQcm90b2NvbEZlZVJld2FyZE1hbmFnZXJSZXNvbHZlcihwcm90b2NvbEZlZVJld2FyZE1hbmFnZXIpCgoJaWYgZXJyIDo9IGcuZm9sZFByb3RvY29sRmVlQWNjcnVhbCgwLCBybG0sIHJlc29sdmVkTWFuYWdlciwgdG9rZW5QYXRoLCBtYXhBY2NydWFsQnVja2V0c1BlckNvbGxlY3QsIGN1cnJlbnRUaW1lc3RhbXApOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CgoJcmV3YXJkLCBlcnIgOj0gcmVzb2x2ZWRNYW5hZ2VyLmNsYWltVG9rZW5SZXdhcmQoYWRkcmVzcywgdG9rZW5QYXRoLCBtYXhTdGFrZUV2ZW50c1BlckNvbGxlY3QpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CgoJaWYgZXJyIDo9IGcuc3RvcmUuU2V0UHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKDAsIHJsbSwgcHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoKCWVtaXRVcGRhdGVQcm90b2NvbEZlZVJld2FyZEFjY3VtdWxhdGlvbihwcm90b2NvbEZlZVJld2FyZE1hbmFnZXIsIFtdc3RyaW5ne3Rva2VuUGF0aH0pCgoJcmV0dXJuIHJld2FyZCwgbmlsCn0KCi8vIGdldENsYWltYWJsZVByb3RvY29sRmVlUmV3YXJkcyByZXBvcnRzIHdoYXQgY29sbGVjdGluZyBldmVyeSB0b2tlbiB3b3VsZCBwYXkgZm9yIGEKLy8gcmV3YXJkIElEIHJpZ2h0IG5vdywgcGVuZGluZyBhY2NydWFsIGJ1Y2tldHMgaW5jbHVkZWQsIHdpdGhvdXQgY2hhbmdpbmcgYW55IHN0YXRlLgpmdW5jIChnICpnb3ZTdGFrZXJWMSkgZ2V0Q2xhaW1hYmxlUHJvdG9jb2xGZWVSZXdhcmRzKHJld2FyZElEIHN0cmluZykgKG1hcFtzdHJpbmddaW50NjQsIGVycm9yKSB7Cglwcm90b2NvbEZlZVJld2FyZE1hbmFnZXIgOj0gZy5zdG9yZS5HZXRQcm90b2NvbEZlZVJld2FyZE1hbmFnZXIoKQoJcmVzb2x2ZWRNYW5hZ2VyIDo9IE5ld1Byb3RvY29sRmVlUmV3YXJkTWFuYWdlclJlc29sdmVyKHByb3RvY29sRmVlUmV3YXJkTWFuYWdlcikKCglyZXdhcmRzIDo9IG1ha2UobWFwW3N0cmluZ11pbnQ2NCkKCXRva2VuUGF0aHMgOj0gcHJvdG9jb2xGZWVSZXdhcmRNYW5hZ2VyLkdldFRva2VuUGF0aHMoKQoJZm9yIF8sIHRva2VuUGF0aCA6PSByYW5nZSBwZi5HZXRBY2NydWFsUGVuZGluZ1Rva2VucygpIHsKCQlpZiBfLCBvayA6PSBwcm90b2NvbEZlZVJld2FyZE1hbmFnZXIuR2V0VG9rZW5BY2N1bXVsYXRvcih0b2tlblBhdGgpOyAhb2sgewoJCQl0b2tlblBhdGhzID0gYXBwZW5kKHRva2VuUGF0aHMsIHRva2VuUGF0aCkKCQl9Cgl9CgoJZm9yIF8sIHRva2VuUGF0aCA6PSByYW5nZSB0b2tlblBhdGhzIHsKCQlwZW5kaW5nRXBvY2hzLCBwZW5kaW5nQW1vdW50cyA6PSBwZi5HZXRBY2NydWFsQnVja2V0cyh0b2tlblBhdGgsIDApCgkJcmV3YXJkLCBlcnIgOj0gcmVzb2x2ZWRNYW5hZ2VyLkdldENsYWltYWJsZVJld2FyZEFtb3VudChyZXdhcmRJRCwgdG9rZW5QYXRoLCBwZW5kaW5nRXBvY2hzLCBwZW5kaW5nQW1vdW50cykKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIG5pbCwgZXJyCgkJfQoJCXJld2FyZHNbdG9rZW5QYXRoXSA9IHJld2FyZAoJfQoKCXJldHVybiByZXdhcmRzLCBuaWwKfQoKLy8gZ2V0TGF1bmNocGFkUHJvamVjdERlcG9zaXQgcmV0cmlldmVzIHRoZSBkZXBvc2l0IGFtb3VudCBmb3IgYSBsYXVuY2hwYWQgcHJvamVjdC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIG93bmVyQWRkcmVzczogcHJvamVjdCBvd25lcidzIGFkZHJlc3MgaWRlbnRpZmllcgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IGRlcG9zaXQgYW1vdW50Ci8vICAgLSBib29sOiB0cnVlIGlmIHByb2plY3QgZXhpc3RzLCBmYWxzZSBvdGhlcndpc2UKZnVuYyAoZyAqZ292U3Rha2VyVjEpIGdldExhdW5jaHBhZFByb2plY3REZXBvc2l0KG93bmVyQWRkcmVzcyBzdHJpbmcpIChpbnQ2NCwgYm9vbCkgewoJbGF1bmNocGFkRGVwb3NpdHMgOj0gZy5zdG9yZS5HZXRMYXVuY2hwYWRQcm9qZWN0RGVwb3NpdHMoKQoJcmVzb2x2ZWREZXBvc2l0cyA6PSBOZXdMYXVuY2hwYWRQcm9qZWN0RGVwb3NpdHNSZXNvbHZlcihsYXVuY2hwYWREZXBvc2l0cykKCXJldHVybiByZXNvbHZlZERlcG9zaXRzLmdldExhdW5jaHBhZFByb2plY3REZXBvc2l0KG93bmVyQWRkcmVzcykKfQoKLy8gc2V0TGF1bmNocGFkUHJvamVjdERlcG9zaXQgc2V0cyB0aGUgZGVwb3NpdCBhbW91bnQgZm9yIGEgbGF1bmNocGFkIHByb2plY3QuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBvd25lckFkZHJlc3M6IHByb2plY3Qgb3duZXIncyBhZGRyZXNzIGlkZW50aWZpZXIKLy8gICAtIGRlcG9zaXQ6IGRlcG9zaXQgYW1vdW50IHRvIHNldAovLwovLyBSZXR1cm5zOgovLyAgIC0gZXJyb3I6IG5pbCBvbiBzdWNjZXNzLCBvdGhlcndpc2UgdGhlIHN0b3JhZ2Ugd3JpdGUgZXJyb3IKZnVuYyAoZyAqZ292U3Rha2VyVjEpIHNldExhdW5jaHBhZFByb2plY3REZXBvc2l0KF8gaW50LCBybG0gcmVhbG0sIG93bmVyQWRkcmVzcyBzdHJpbmcsIGRlcG9zaXQgaW50NjQpIGVycm9yIHsKCWxhdW5jaHBhZERlcG9zaXRzIDo9IGcuc3RvcmUuR2V0TGF1bmNocGFkUHJvamVjdERlcG9zaXRzKCkKCXJlc29sdmVkRGVwb3NpdHMgOj0gTmV3TGF1bmNocGFkUHJvamVjdERlcG9zaXRzUmVzb2x2ZXIobGF1bmNocGFkRGVwb3NpdHMpCglyZXNvbHZlZERlcG9zaXRzLnNldExhdW5jaHBhZFByb2plY3REZXBvc2l0KG93bmVyQWRkcmVzcywgZGVwb3NpdCkKCglyZXR1cm4gZy5zdG9yZS5TZXRMYXVuY2hwYWRQcm9qZWN0RGVwb3NpdHMoMCwgcmxtLCBsYXVuY2hwYWREZXBvc2l0cykKfQoKLy8gYWRkU3Rha2VGcm9tTGF1bmNocGFkIGFkZHMgc3Rha2UgZm9yIGEgbGF1bmNocGFkIHByb2plY3QgYW5kIHVwZGF0ZXMgcmV3YXJkIHRyYWNraW5nLgovLyBUaGlzIG1ldGhvZCBjcmVhdGVzIGEgc3BlY2lhbCByZXdhcmQgSUQgZm9yIGxhdW5jaHBhZCBwcm9qZWN0cyBhbmQgbWFuYWdlcyB0aGVpciBkZXBvc2l0IHRyYWNraW5nLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gYWRkcmVzczogcHJvamVjdCB3YWxsZXQgYWRkcmVzcwovLyAgIC0gYW1vdW50OiBhbW91bnQgb2Ygc3Rha2UgdG8gYWRkCi8vICAgLSBjdXJyZW50VGltZXN0YW1wOiBjdXJyZW50IHRpbWVzdGFtcApmdW5jIChnICpnb3ZTdGFrZXJWMSkgYWRkU3Rha2VGcm9tTGF1bmNocGFkKF8gaW50LCBybG0gcmVhbG0sIGFkZHJlc3Mgc3RyaW5nLCBhbW91bnQgaW50NjQsIGN1cnJlbnRUaW1lc3RhbXAgaW50NjQpIGVycm9yIHsKCWxhdW5jaHBhZFJld2FyZElEIDo9IGcubWFrZUxhdW5jaHBhZFJld2FyZElEKGFkZHJlc3MpCgllcnIgOj0gZy5hZGRTdGFrZUVtaXNzaW9uUmV3YXJkKDAsIHJsbSwgbGF1bmNocGFkUmV3YXJkSUQsIGFtb3VudCwgY3VycmVudFRpbWVzdGFtcCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCgllcnIgPSBnLmFkZFN0YWtlUHJvdG9jb2xGZWVSZXdhcmQoMCwgcmxtLCBsYXVuY2hwYWRSZXdhcmRJRCwgYW1vdW50LCBjdXJyZW50VGltZXN0YW1wKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCWRlcG9zaXQsIGV4aXN0cyA6PSBnLmdldExhdW5jaHBhZFByb2plY3REZXBvc2l0KGxhdW5jaHBhZFJld2FyZElEKQoJaWYgIWV4aXN0cyB7CgkJZGVwb3NpdCA9IDAKCX0KCglkZXBvc2l0ID0gZ25zbWF0aC5TYWZlQWRkSW50NjQoZGVwb3NpdCwgYW1vdW50KQoJaWYgZXJyIDo9IGcuc2V0TGF1bmNocGFkUHJvamVjdERlcG9zaXQoMCwgcmxtLCBsYXVuY2hwYWRSZXdhcmRJRCwgZGVwb3NpdCk7IGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCglyZXR1cm4gbmlsCn0KCi8vIHJlbW92ZVN0YWtlRnJvbUxhdW5jaHBhZCByZW1vdmVzIHN0YWtlIGZvciBhIGxhdW5jaHBhZCBwcm9qZWN0IGFuZCB1cGRhdGVzIHJld2FyZCB0cmFja2luZy4KLy8gVGhpcyBtZXRob2QgbWFuYWdlcyBsYXVuY2hwYWQgcHJvamVjdCBkZXBvc2l0IHRyYWNraW5nIGFuZCBlbnN1cmVzIG5vbi1uZWdhdGl2ZSBkZXBvc2l0cy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGFkZHJlc3M6IHByb2plY3Qgd2FsbGV0IGFkZHJlc3MKLy8gICAtIGFtb3VudDogYW1vdW50IG9mIHN0YWtlIHRvIHJlbW92ZQovLyAgIC0gY3VycmVudFRpbWVzdGFtcDogY3VycmVudCB0aW1lc3RhbXAKZnVuYyAoZyAqZ292U3Rha2VyVjEpIHJlbW92ZVN0YWtlRnJvbUxhdW5jaHBhZChfIGludCwgcmxtIHJlYWxtLCBhZGRyZXNzIHN0cmluZywgYW1vdW50IGludDY0LCBjdXJyZW50VGltZXN0YW1wIGludDY0KSBlcnJvciB7CglsYXVuY2hwYWRSZXdhcmRJRCA6PSBnLm1ha2VMYXVuY2hwYWRSZXdhcmRJRChhZGRyZXNzKQoJZXJyIDo9IGcucmVtb3ZlU3Rha2VFbWlzc2lvblJld2FyZCgwLCBybG0sIGxhdW5jaHBhZFJld2FyZElELCBhbW91bnQsIGN1cnJlbnRUaW1lc3RhbXApCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJZXJyID0gZy5yZW1vdmVTdGFrZVByb3RvY29sRmVlUmV3YXJkKDAsIHJsbSwgbGF1bmNocGFkUmV3YXJkSUQsIGFtb3VudCwgY3VycmVudFRpbWVzdGFtcCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCglkZXBvc2l0LCBleGlzdHMgOj0gZy5nZXRMYXVuY2hwYWRQcm9qZWN0RGVwb3NpdChsYXVuY2hwYWRSZXdhcmRJRCkKCWlmICFleGlzdHMgewoJCWRlcG9zaXQgPSAwCgl9CgoJZGVwb3NpdCA9IGduc21hdGguU2FmZVN1YkludDY0KGRlcG9zaXQsIGFtb3VudCkKCWlmIGRlcG9zaXQgPCAwIHsKCQlkZXBvc2l0ID0gMAoJfQoKCWlmIGVyciA6PSBnLnNldExhdW5jaHBhZFByb2plY3REZXBvc2l0KDAsIHJsbSwgbGF1bmNocGFkUmV3YXJkSUQsIGRlcG9zaXQpOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZXJyCgl9CgoJcmV0dXJuIG5pbAp9CgovLyBtYWtlTGF1bmNocGFkUmV3YXJkSUQgY3JlYXRlcyBhIHNwZWNpYWwgcmV3YXJkIGlkZW50aWZpZXIgZm9yIGxhdW5jaHBhZCBwcm9qZWN0cy4KLy8gVGhpcyBlbnN1cmVzIGxhdW5jaHBhZCBwcm9qZWN0IHJld2FyZHMgYXJlIHRyYWNrZWQgc2VwYXJhdGVseSBmcm9tIHJlZ3VsYXIgdXNlciBzdGFrZXMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBhZGRyZXNzOiBwcm9qZWN0IHdhbGxldCBhZGRyZXNzCi8vCi8vIFJldHVybnM6Ci8vICAgLSBzdHJpbmc6IGZvcm1hdHRlZCBsYXVuY2hwYWQgcmV3YXJkIElECmZ1bmMgKGcgKmdvdlN0YWtlclYxKSBtYWtlTGF1bmNocGFkUmV3YXJkSUQoYWRkcmVzcyBzdHJpbmcpIHN0cmluZyB7CglyZXR1cm4gImxhdW5jaHBhZDoiICsgYWRkcmVzcwp9ChreFwoIdXRpbC5nbm8S0RdwYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCSJzdHJjb252IgoKCWduc21hdGggImduby5sYW5kL3AvZ25vc3dhcC9nbnNtYXRoL3YxIgoJYnB0cmVlICJnbm8ubGFuZC9wL250L2JwdHJlZS92MCIKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCSJnbm8ubGFuZC9wL29uYmxvYy9qc29uL3YwIgopCgovLyBtYXJzaGFsIGRhdGEgdG8ganNvbiBzdHJpbmcKZnVuYyBtYXJzaGFsKGRhdGEgKmpzb24uTm9kZSkgc3RyaW5nIHsKCWIsIGVyciA6PSBqc29uLk1hcnNoYWwoZGF0YSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVyci5FcnJvcigpKQoJfQoKCXJldHVybiBzdHJpbmcoYikKfQoKLy8gZ2V0VWludDY0RnJvbVRyZWUgcmV0dXJucyB0aGUgdWludDY0IHZhbHVlIGZyb20gdGhlIHRyZWUKZnVuYyBnZXRVaW50NjRGcm9tVHJlZSh0cmVlICpicHRyZWUuQlBUcmVlLCBrZXkgc3RyaW5nKSB1aW50NjQgewoJdmFsdWUgOj0gdHJlZS5HZXQoa2V5KQoJaWYgdmFsdWUgPT0gbmlsIHsKCQlyZXR1cm4gMAoJfQoKCXYsIG9rIDo9IHZhbHVlLih1aW50NjQpCglpZiAhb2sgewoJCXBhbmljKHVmbXQuU3ByaW50ZigiZmFpbGVkIHRvIGNhc3QgdmFsdWUgdG8gdWludDY0OiAlVCIsIHZhbHVlKSkKCX0KCglyZXR1cm4gdgp9CgovLyB1cGRhdGVVaW50NjRJblRyZWUgdXBkYXRlcyB0aGUgdWludDY0IHZhbHVlIGluIHRoZSB0cmVlCmZ1bmMgdXBkYXRlVWludDY0SW5UcmVlKHRyZWUgKmJwdHJlZS5CUFRyZWUsIGtleSBzdHJpbmcsIGRlbHRhIHVpbnQ2NCwgYWRkIGJvb2wpIHVpbnQ2NCB7CgljdXJyZW50IDo9IGdldFVpbnQ2NEZyb21UcmVlKHRyZWUsIGtleSkKCXZhciBuZXdWYWx1ZSB1aW50NjQKCWlmIGFkZCB7CgkJbmV3VmFsdWUgPSBnbnNtYXRoLlNhZmVBZGRVaW50NjQoY3VycmVudCwgZGVsdGEpCgl9IGVsc2UgewoJCWlmIGN1cnJlbnQgPCBkZWx0YSB7CgkJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQkJZXJyTm90RW5vdWdoQmFsYW5jZSwKCQkJCXVmbXQuU3ByaW50Zigibm90IGVub3VnaCBiYWxhbmNlOiBjdXJyZW50KCVkKSA8IHJlcXVlc3RlZCglZCkiLCBjdXJyZW50LCBkZWx0YSksCgkJCSkpCgkJfQoJCW5ld1ZhbHVlID0gZ25zbWF0aC5TYWZlU3ViVWludDY0KGN1cnJlbnQsIGRlbHRhKQoJfQoKCXRyZWUuU2V0KGtleSwgbmV3VmFsdWUpCgoJcmV0dXJuIG5ld1ZhbHVlCn0KCi8vIG1pbGxpVG9TZWMgY29udmVydHMgbWlsbGlzZWNvbmRzIHRvIHNlY29uZHMKZnVuYyBtaWxsaVRvU2VjKG1zIGludDY0KSBpbnQ2NCB7Cgl2YXIgbXNQZXJTZWMgaW50NjQgPSAxMDAwCglyZXR1cm4gbXMgLyBtc1BlclNlYwp9CgovLyB1c2VySGlzdG9yeUtleVNlcGFyYXRvciBpcyBjaG9zZW4gdG8gYmUgbGV4aWNvZ3JhcGhpY2FsbHkgc21hbGxlciB0aGFuIGFueQpjb25zdCAoCgl1c2VySGlzdG9yeUtleVNlcGFyYXRvciAgICAgICAgID0gInwiCgl1c2VySGlzdG9yeUtleVNlcGFyYXRvck5leHRXb3JkID0gc3RyaW5nKGludDMyKCd8JykgKyAxKQopCgovLyB1c2VySGlzdG9yeVRpbWVzdGFtcFdpZHRoIGlzIHRoZSB6ZXJvLXBhZGRlZCB3aWR0aCB0aGF0IGZpdHMgdGhlIG1heGltdW0KY29uc3QgdXNlckhpc3RvcnlUaW1lc3RhbXBXaWR0aCA9IDIwCgovLyBtYWtlVXNlckhpc3RvcnlLZXkgYnVpbGRzIHRoZSBjb21wb3NpdGUga2V5ICJhZGRyfHBhZGRlZFRpbWVzdGFtcCIgdXNlZCBpbiB0aGUgdXNlciBkZWxlZ2F0aW9uIGhpc3RvcnkgQlBUcmVlLgpmdW5jIG1ha2VVc2VySGlzdG9yeUtleShhZGRyU3RyIHN0cmluZywgdGltZXN0YW1wIGludDY0KSBzdHJpbmcgewoJcmV0dXJuIGFkZHJTdHIgKyB1c2VySGlzdG9yeUtleVNlcGFyYXRvciArIHBhZFRpbWVzdGFtcCh0aW1lc3RhbXApCn0KCi8vIHVzZXJIaXN0b3J5S2V5UmFuZ2UgcmV0dXJucyB0aGUgaGFsZi1vcGVuIHByZWZpeCByYW5nZSB0aGF0IGNvdmVycyBhbGwgY29tcG9zaXRlIGtleXMgYmVsb25naW5nIHRvIGFkZHJTdHIuCmZ1bmMgdXNlckhpc3RvcnlLZXlSYW5nZShhZGRyU3RyIHN0cmluZykgKGxvLCBoaSBzdHJpbmcpIHsKCWxvID0gYWRkclN0ciArIHVzZXJIaXN0b3J5S2V5U2VwYXJhdG9yCgloaSA9IGFkZHJTdHIgKyB1c2VySGlzdG9yeUtleVNlcGFyYXRvck5leHRXb3JkCgoJcmV0dXJuIGxvLCBoaQp9CgovLyBwYWRUaW1lc3RhbXAgbGVmdC1wYWRzIHRpbWVzdGFtcCB3aXRoIHplcm9zIHRvIHVzZXJIaXN0b3J5VGltZXN0YW1wV2lkdGggc28KLy8gdGhhdCBsZXhpY29ncmFwaGljIG9yZGVyaW5nIG9mIHRoZSByZXN1bHRpbmcgc3RyaW5ncyBtYXRjaGVzIG51bWVyaWMgb3JkZXIuCmZ1bmMgcGFkVGltZXN0YW1wKHRpbWVzdGFtcCBpbnQ2NCkgc3RyaW5nIHsKCXMgOj0gc3RyY29udi5Gb3JtYXRJbnQodGltZXN0YW1wLCAxMCkKCWlmIGxlbihzKSA+PSB1c2VySGlzdG9yeVRpbWVzdGFtcFdpZHRoIHsKCQlyZXR1cm4gcwoJfQoKCXBhZCA6PSBtYWtlKFtdYnl0ZSwgdXNlckhpc3RvcnlUaW1lc3RhbXBXaWR0aC1sZW4ocykpCglmb3IgaSA6PSByYW5nZSBwYWQgewoJCXBhZFtpXSA9ICcwJwoJfQoKCXJldHVybiBzdHJpbmcocGFkKSArIHMKfQoKLy8gcGFyc2VVc2VySGlzdG9yeUtleSBzcGxpdHMgYSBjb21wb3NpdGUga2V5IHByb2R1Y2VkIGJ5IG1ha2VVc2VySGlzdG9yeUtleSBiYWNrIGludG8gaXRzIGFkZHJlc3MgYW5kIHRpbWVzdGFtcCBjb21wb25lbnRzLgpmdW5jIHBhcnNlVXNlckhpc3RvcnlLZXkoa2V5IHN0cmluZykgKGFkZHJTdHIgc3RyaW5nLCB0aW1lc3RhbXAgaW50NjQsIG9rIGJvb2wpIHsKCWZvciBpIDo9IGxlbihrZXkpIC0gMTsgaSA+PSAwOyBpLS0gewoJCWlmIGtleVtpXSA9PSB1c2VySGlzdG9yeUtleVNlcGFyYXRvclswXSB7CgkJCXRzLCBlcnIgOj0gc3RyY29udi5QYXJzZUludChrZXlbaSsxOl0sIDEwLCA2NCkKCQkJaWYgZXJyICE9IG5pbCB7CgkJCQlyZXR1cm4gIiIsIDAsIGZhbHNlCgkJCX0KCgkJCXJldHVybiBrZXlbOmldLCB0cywgdHJ1ZQoJCX0KCX0KCglyZXR1cm4gIiIsIDAsIGZhbHNlCn0KIiIKEy9nbm8uTWVtUGFja2FnZVR5cGUSCwoJTVBVc2VyQWxsEhMI6qSg3QESCzIzMjAwMHVnbm90GqgBCjoKEy90bS5QdWJLZXlTZWNwMjU2azESIwohAwSc1QTD4tI6os8LnebKOB+i6fWXOKGBf9lRpSI1wrrhEkAl1Og60F+YplygbyrjgIXV72maH1ulPAktjpCs04FF3E5x7xKvhHb2COjWxZYKvA/zrjoAbyxQodOIykdDO5V/GihnMXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcWx1dXhl

Raw transaction data

Raw JSON data