Transaction executed successfully
Transaction Details
Inspect execution, participants, message data, gas usage, events and raw transaction data.
Transaction hash
BFF90BAA75D8819C7A6BFB0A0380E929BE67686DD25C692A508CDB7E8D45717E
Transaction overview
Execution summary
TX INDEX
0
Position in block
GAS WANTED
131,212,022
Requested gas limit
GAS USED
109,343,391
Gas consumed
FEE
131213ugnot
Transaction fee
Participants
Message
Message #1
m_addpkg
Arguments
g1q5tjjv3kkslzwf2na9y9wk7e5a8ugph8xfsk04
Execution log
msg:0,success:true,log:,events:[]
Events
No events emitted by this transaction.
Raw encoded transaction
CoiwBQoML3ZtLm1fYWRkcGtnEvavBQooZzFxNXRqanYza2tzbHp3ZjJuYTl5OXdrN2U1YTh1Z3BoOHhmc2swNBLIrwUKCHBvc2l0aW9uEh5nbm8ubGFuZC9yL2dub3N3YXAvcG9zaXRpb24vdjEa0TMKCVJFQURNRS5tZBLDMyMgUG9zaXRpb24KCk5GVC1iYXNlZCBsaXF1aWRpdHkgcG9zaXRpb24gbWFuYWdlbWVudCBmb3IgY29uY2VudHJhdGVkIGxpcXVpZGl0eS4KCiMjIE92ZXJ2aWV3CgpFYWNoIGxpcXVpZGl0eSBwb3NpdGlvbiBpcyBhIHVuaXF1ZSBHUkM3MjEgTkZULiBTdG9yZWQgc3RhdGUgaW5jbHVkZXMgdGhlIHBvb2wKa2V5LCBwcmljZSByYW5nZSwgbGlxdWlkaXR5LCBmZWUtZ3Jvd3RoIGNoZWNrcG9pbnRzLCB0b2tlbnMgb3dlZCwgYnVybmVkIG1hcmtlciwKYW5kIG9wZXJhdG9yLiBDdXJyZW50IHRva2VuIGJhbGFuY2VzIGFyZSBkZXJpdmVkIGZyb20gdGhlIGN1cnJlbnQgcG9vbCBwcmljZSwKcmFuZ2UsIGFuZCBsaXF1aWRpdHk7IHRoZXkgYXJlIG5vdCBwZXJtYW5lbnRseSBzdG9yZWQgYmFsYW5jZXMuCgpUaGUgcG9vbCBhY2NvdW50aW5nIGtleSBlbmNvZGVzIG9ubHkgdGhlIGxvd2VyL3VwcGVyIHRpY2sgcGFpciBhbmQgaXMgc2NvcGVkIGJ5CnBvb2wuIE5GVHMgd2l0aCB0aGUgc2FtZSByYW5nZSBpbiBvbmUgcG9vbCBzaGFyZSB0aGUgcG9vbC1sZXZlbCBhY2NvdW50aW5nIGVudHJ5LgoKIyMgQ29uZmlndXJhdGlvbgoKLSAqKldpdGhkcmF3YWwgRmVlKio6IDElIGJ5IGRlZmF1bHQgb24gZmVlLWJlYXJpbmcgc3dhcC1mZWUgY29sbGVjdGlvbgotICoqTWF4IFBvc2l0aW9uIFNpemUqKjogTm8gc2VwYXJhdGUgcG9zaXRpb24tbGV2ZWwgY2FwOyBwb29sIHRpY2sgbGltaXRzIGFwcGx5Ci0gKipUcmFuc2ZlcnMqKjogVW5zdGFrZWQgTkZUcyBmb2xsb3cgR1JDNzIxIG93bmVyL2FwcHJvdmFsL29wZXJhdG9yIHJ1bGVzOwogIHN0YWtlZCBORlRzIGFyZSBsb2NrZWQgdG8gc3Rha2VyLW1lZGlhdGVkIHRyYW5zZmVycwoKIyMgQ29yZSBGdW5jdGlvbnMKCiMjIyBgTWludGAKCkNyZWF0ZXMgbmV3IHBvc2l0aW9uIE5GVCB3aXRoIGluaXRpYWwgbGlxdWlkaXR5LgoKLSBWYWxpZGF0ZXMgdGljayByYW5nZSBhbGlnbm1lbnQKLSBDYWxjdWxhdGVzIG9wdGltYWwgdG9rZW4gcmF0aW8KLSBSZXR1cm5zIGFjdHVhbCBhbW91bnRzIHVzZWQKCiMjIyBgSW5jcmVhc2VMaXF1aWRpdHlgCgpBZGRzIGxpcXVpZGl0eSB0byBhbiBleGlzdGluZyBwb3NpdGlvbi4KCi0gTWFpbnRhaW5zIHRoZSBleGlzdGluZyBwcmljZSByYW5nZQotIFVzZXMgdGhlIGN1cnJlbnQtcHJpY2UgdG9rZW4gcmF0aW8KLSBDYW4gY2xlYXIgYSBidXJuZWQgbWFya2VyIHdoZW4gdGhlIHBvc2l0aW9uIGlzIHVzZWQgYWdhaW4KCiMjIyBgRGVjcmVhc2VMaXF1aWRpdHlgCgpSZW1vdmVzIGxpcXVpZGl0eSB3aGlsZSBrZWVwaW5nIHRoZSBORlQuCgotIE9uZSBhdG9taWMgcHVibGljIG9wZXJhdGlvbjogaW50ZXJuYWxseSBjb2xsZWN0cyBzd2FwIGZlZXMsIGJ1cm5zIGxpcXVpZGl0eSwKICB0aGVuIGNvbGxlY3RzIHByaW5jaXBhbCB0aHJvdWdoIHRoZSBwb29sJ3MgZmVlLWZyZWUgYENvbGxlY3RgIHBhdGgKLSBSZXR1cm5zIGZlZSBhbW91bnRzIG5ldCBvZiB0aGUgd2l0aGRyYXdhbCBmZWUgYW5kIGNvbGxlY3RlZCBwcmluY2lwYWwKLSBBbW91bnQtbWluaW11bSBjaGVja3MgYXBwbHkgdG8gdGhlIHByaW5jaXBhbCBhY3R1YWxseSBjb2xsZWN0ZWQKCiMjIyBgQ29sbGVjdEZlZWAKCkNsYWltcyBhY2N1bXVsYXRlZCBzd2FwIGZlZXMgd2l0aG91dCByZW1vdmluZyBsaXF1aWRpdHkuCgotIE5vIGxpcXVpZGl0eSByZW1vdmFsIHJlcXVpcmVkCi0gUmV0dXJucyBuZXQgY29sbGVjdGVkIGFtb3VudHMgcGx1cyB0aGUgcmF3IHByZS13aXRoZHJhd2FsLWZlZSBhbW91bnRzCi0gVGhlIGNvbmZpZ3VyZWQgd2l0aGRyYXdhbCBmZWUgYXBwbGllcyBvbmx5IHRvIHRoaXMgZmVlLWJlYXJpbmcgcGF0aAoKIyMjIGBSZXBvc2l0aW9uYAoKVXBkYXRlcyBhbiBleGlzdGluZyBwb3NpdGlvbidzIHByaWNlIHJhbmdlLgoKLSBSZXF1aXJlcyB0aGUgcG9zaXRpb24gdG8gYmUgY2xlYXIgZmlyc3QgKHplcm8gbGlxdWlkaXR5IGFuZCB0b2tlbnMgb3dlZCkKLSBSZXVzZXMgdGhlIHNhbWUgcG9zaXRpb24gSUQgYW5kIE5GVAotIEFkZHMgbmV3IGxpcXVpZGl0eSB0byB0aGUgdXBkYXRlZCByYW5nZSBhbmQgY2xlYXJzIHRoZSBidXJuZWQgbWFya2VyCgojIyBUZWNobmljYWwgRGV0YWlscwoKIyMjIFRpY2sgQWxpZ25tZW50CgpUaWNrcyBtdXN0IGFsaWduIHdpdGggcG9vbCdzIHRpY2sgc3BhY2luZzoKCmBgYAowLjAxJSBmZWU6IGV2ZXJ5IDEgdGljawowLjA1JSBmZWU6IGV2ZXJ5IDEwIHRpY2tzCjAuMyUgZmVlOiBldmVyeSA2MCB0aWNrcwoxJSBmZWU6IGV2ZXJ5IDIwMCB0aWNrcwpgYGAKCiMjIyBPcHRpbWFsIFJhbmdlIFdpZHRoCgoqKlN0YWJsZSBQYWlycyAoVVNEQy9VU0RUKSoqOgoKLSBOYXJyb3c6IMKxMC4wNSUgKG1heCBlZmZpY2llbmN5KQotIE1lZGl1bTogwrEwLjElIChiYWxhbmNlZCkKLSBXaWRlOiDCsTAuNSUgKHNhZmV0eSkKCioqQ29ycmVsYXRlZCBQYWlycyAoV0VUSC9zdEVUSCkqKjoKCi0gTmFycm93OiDCsTAuNSUKLSBNZWRpdW06IMKxMSUKLSBXaWRlOiDCsTIlCgoqKlZvbGF0aWxlIFBhaXJzIChXRVRIL1VTREMpKio6CgotIE5hcnJvdzogwrE1JQotIE1lZGl1bTogwrExMCUKLSBXaWRlOiDCsTI1JQoKIyMjIENhcGl0YWwgRWZmaWNpZW5jeQoKQ29uY2VudHJhdGlvbiBmYWN0b3IgdnMgaW5maW5pdGUgcmFuZ2U6CgpgYGAKUmFuZ2UgwrEwLjElICDihpIgMjAwMHggZWZmaWNpZW50ClJhbmdlIMKxMSUgICAg4oaSIDIwMHggZWZmaWNpZW50ClJhbmdlIMKxMTAlICAg4oaSIDIweCBlZmZpY2llbnQKUmFuZ2UgwrE1MCUgICDihpIgNHggZWZmaWNpZW50CmBgYAoKIyMjIFRva2VuIENhbGN1bGF0aW9ucwoKRm9yIGxpcXVpZGl0eSBgTGAgYW5kIHNxdWFyZS1yb290IHByaWNlcyBgc3FydExvd2VyYCwgYHNxcnRDdXJyZW50YCwgYW5kCmBzcXJ0VXBwZXJgOgoKKipCZWxvdyByYW5nZSAoYGN1cnJlbnQgPCBsb3dlcmAsIHRva2VuMCBvbmx5KSoqOgoKYGBgCmFtb3VudDAgPSBMICogKHNxcnRVcHBlciAtIHNxcnRMb3dlcikgLyAoc3FydFVwcGVyICogc3FydExvd2VyKQphbW91bnQxID0gMApgYGAKCioqSW4gcmFuZ2UgKGBsb3dlciA8PSBjdXJyZW50IDwgdXBwZXJgLCBib3RoIHRva2VucykqKjoKCmBgYAphbW91bnQwID0gTCAqIChzcXJ0VXBwZXIgLSBzcXJ0Q3VycmVudCkgLyAoc3FydFVwcGVyICogc3FydEN1cnJlbnQpCmFtb3VudDEgPSBMICogKHNxcnRDdXJyZW50IC0gc3FydExvd2VyKQpgYGAKCioqQWJvdmUgcmFuZ2UgKGBjdXJyZW50ID49IHVwcGVyYCwgdG9rZW4xIG9ubHkpKio6CgpgYGAKYW1vdW50MCA9IDAKYW1vdW50MSA9IEwgKiAoc3FydFVwcGVyIC0gc3FydExvd2VyKQpgYGAKCiMjIEFwcHJvdmFsIGFuZCBUcmFuc2ZlciBSZXF1aXJlbWVudHMKCmBNaW50YCwgYEluY3JlYXNlTGlxdWlkaXR5YCwgYW5kIGBSZXBvc2l0aW9uYCBwdWxsIHRva2VuMCBhbmQgdG9rZW4xIGZyb20gdGhlCmNhbGxlciBpbnNpZGUgdGhlICoqcG9vbCoqIHJlYWxtLCBzbyB0aGUgYXBwcm92ZWQgc3BlbmRlciBpcyB0aGUgcG9vbCByZWFsbQphZGRyZXNzLCBub3QgdGhlIHBvc2l0aW9uIHJlYWxtLgoKLSBBcHByb3ZlIHRoZSBwb29sIHJlYWxtIGZvciBib3RoIHRva2VuIGNvbnRyYWN0cyBiZWZvcmUgY2FsbGluZyBhCiAgbGlxdWlkaXR5LWFkZGluZyBmdW5jdGlvbi4KLSBBcHByb3ZpbmcgdGhlIHBvc2l0aW9uIHJlYWxtIGFsb25lIGlzIG5vdCBzdWZmaWNpZW50OyB0aGUgcG9zaXRpb24gcmVhbG0gbmV2ZXIKICBob2xkcyBvciBwdWxscyB0aGUgcGFpciB0b2tlbnMgaXRzZWxmLgotIEFwcHJvdmUgYXQgbGVhc3QgYGFtb3VudDBEZXNpcmVkYCAvIGBhbW91bnQxRGVzaXJlZGAuIEFueSBkZXNpcmVkIGFtb3VudCB0aGUKICBwb29sIGRvZXMgbm90IGNvbnN1bWUgc3RheXMgd2l0aCB0aGUgY2FsbGVyLgotIGBEZWNyZWFzZUxpcXVpZGl0eWAgYW5kIGBDb2xsZWN0RmVlYCBwYXkgb3V0IHRvIHRoZSBjYWxsZXIgYW5kIHJlcXVpcmUgbm8KICBhcHByb3ZhbC4KCmBgYGdvCi8vIEFwcHJvdmUgdGhlIHBvb2wgcmVhbG0gZm9yIGJvdGggcGFpciB0b2tlbnMgYmVmb3JlIG1pbnRpbmcKcG9vbEFkZHJlc3MgOj0gYWNjZXNzLk11c3RHZXRBZGRyZXNzKHByYWJjLlJPTEVfUE9PTC5TdHJpbmcoKSkKd2V0aC5BcHByb3ZlKGNyb3NzKGN1ciksIHBvb2xBZGRyZXNzLCAxMDAwMDAwKQp1c2RjLkFwcHJvdmUoY3Jvc3MoY3VyKSwgcG9vbEFkZHJlc3MsIDIwMDAwMDAwMDApCmBgYAoKIyMgVXNhZ2UKClRoZXNlIHNuaXBwZXRzIGNhbGwgdGhlIHB1YmxpYyBkb21haW4gcHJveHkgZnJvbSBhIHJlYWxtIGZ1bmN0aW9uIHdpdGggYSBjdXJyZW50IGBjdXJgIHRva2VuLgpJbXBvcnQgdGhlIHByb3h5IHBhY2thZ2UgYW5kIHF1YWxpZnkgaXRzIGZ1bmN0aW9uIG5hbWVzIGluIGludGVncmF0aW5nIGNvZGUuCgpgYGBnbwovLyBNaW50IGEgbmV3IHBvc2l0aW9uIHRocm91Z2ggdGhlIGRvbWFpbiBwcm94eQp0b2tlbklkLCBsaXF1aWRpdHksIGFtb3VudDAsIGFtb3VudDEgOj0gTWludCgKICAgIGNyb3NzKGN1ciksCiAgICAiZ25vLmxhbmQvci9nbm9sYW5kL3d1Z25vdC53dWdub3QiLCAvLyB0b2tlbjAKICAgICJnbm8ubGFuZC9yL2dub3N3YXAvZ25zLkdOUyIsICAgLy8gdG9rZW4xCiAgICAzMDAwLCAgICAgICAgICAgICAgICAgICAgICAvLyBmZWUKICAgIC04ODcyMjAsICAgICAgICAgICAgICAgICAgIC8vIHRpY2tMb3dlcgogICAgODg3MjIwLCAgICAgICAgICAgICAgICAgICAgLy8gdGlja1VwcGVyCiAgICAiMTAwMDAwMCIsICAgICAgICAgICAgICAgICAvLyBhbW91bnQwRGVzaXJlZAogICAgIjIwMDAwMDAwMDAiLCAgICAgICAgICAgICAgLy8gYW1vdW50MURlc2lyZWQKICAgICI5NTAwMDAiLCAgICAgICAgICAgICAgICAgIC8vIGFtb3VudDBNaW4KICAgICIxOTAwMDAwMDAwIiwgICAgICAgICAgICAgIC8vIGFtb3VudDFNaW4KICAgIGRlYWRsaW5lLAogICAgcmVjaXBpZW50LCAgICAgICAgICAgICAgICAgLy8gbWludFRvCiAgICAiIiwgICAgICAgICAgICAgICAgICAgICAgICAvLyByZWZlcnJlcgopCgovLyBBZGQgbGlxdWlkaXR5CnBvc2l0aW9uSWQsIGxpcXVpZGl0eSwgYW1vdW50MCwgYW1vdW50MSwgcG9vbFBhdGggOj0gSW5jcmVhc2VMaXF1aWRpdHkoCiAgICBjcm9zcyhjdXIpLAogICAgdG9rZW5JZCwKICAgICI1MDAwMDAiLAogICAgIjEwMDAwMDAwMDAiLAogICAgIjQ3NTAwMCIsCiAgICAiOTUwMDAwMDAwIiwKICAgIGRlYWRsaW5lLAopCgovLyBDb2xsZWN0IHN3YXAgZmVlcwpwb3NpdGlvbklkLCBjb2xsZWN0ZWQwLCBjb2xsZWN0ZWQxLCBwb29sUGF0aCwgcmF3QW1vdW50MCwgcmF3QW1vdW50MSA6PSBDb2xsZWN0RmVlKAogICAgY3Jvc3MoY3VyKSwKICAgIHRva2VuSWQsCikKCi8vIFJlcG9zaXRpb24gdG8gYSBuZXcgcmFuZ2UgKHJlcXVpcmVzIGEgY2xlYXIgcG9zaXRpb24pCnBvc2l0aW9uSWQsIGxpcXVpZGl0eSwgdGlja0xvd2VyLCB0aWNrVXBwZXIsIGFtb3VudDAsIGFtb3VudDEgOj0gUmVwb3NpdGlvbigKICAgIGNyb3NzKGN1ciksCiAgICB0b2tlbklkLAogICAgLTQ0MzYxMCwgICAgICAgICAgICAgICAgICAgLy8gbmV3IHRpY2tMb3dlcgogICAgNDQzNjEwLCAgICAgICAgICAgICAgICAgICAgLy8gbmV3IHRpY2tVcHBlcgogICAgIjEwMDAwMDAiLCAgICAgICAgICAgICAgICAgLy8gYW1vdW50MERlc2lyZWQKICAgICIyMDAwMDAwMDAwIiwgICAgICAgICAgICAgIC8vIGFtb3VudDFEZXNpcmVkCiAgICAiOTUwMDAwIiwgICAgICAgICAgICAgICAgICAvLyBhbW91bnQwTWluCiAgICAiMTkwMDAwMDAwMCIsICAgICAgICAgICAgICAvLyBhbW91bnQxTWluCiAgICBkZWFkbGluZSwKKQpgYGAKCiMjIExpZmVjeWNsZQoKQSBmdWxsIGRlY3JlYXNlIHRoYXQgbGVhdmVzIHplcm8gbGlxdWlkaXR5IGFuZCB6ZXJvIHRva2VucyBvd2VkIHNldHMgdGhlCmBidXJuZWRgIG1hcmtlciBidXQgZG9lcyBub3QgZGVzdHJveSB0aGUgTkZULiBgSW5jcmVhc2VMaXF1aWRpdHlgIGFuZApgUmVwb3NpdGlvbmAgY2xlYXIgdGhlIG1hcmtlciB3aGVuIHRoZSBwb3NpdGlvbiBpcyB1c2VkIGFnYWluOyB0aGUgbWFya2VyIGRvZXMKbm90IGJ5IGl0c2VsZiBibG9jayBhbiBpbmNyZWFzZS4KCiMjIFNlY3VyaXR5CgotIFRpY2sgcmFuZ2UgdmFsaWRhdGlvbiBwcmV2ZW50cyBpbnZhbGlkIHBvc2l0aW9ucwotIFNsaXBwYWdlIHByb3RlY3Rpb24gYXBwbGllcyB0byBsaXF1aWRpdHktY2hhbmdpbmcgb3BlcmF0aW9uczsgZmVlIGNvbGxlY3Rpb24KICBoYXMgbm8gYW1vdW50LW1pbmltdW0gcGFyYW1ldGVyCi0gRGVhZGxpbmVzIHByZXZlbnQgc3RhbGUgbGlxdWlkaXR5LWNoYW5naW5nIHRyYW5zYWN0aW9ucwotIFVuc3Rha2VkIE5GVHMgZm9sbG93IHN0YW5kYXJkIEdSQzcyMSB0cmFuc2ZlciBhdXRob3JpemF0aW9uOyBzdGFrZWQgTkZUcwogIGNhbiBtb3ZlIG9ubHkgdGhyb3VnaCBzdGFrZXItbWVkaWF0ZWQgZmxvd3MKLSBMaXF1aWRpdHkgY2hhbmdlcyBhbmQgcmVwb3NpdGlvbmluZyByZXF1aXJlIHRoZSBvd25lcjsgZmVlIGNvbGxlY3Rpb24gYWxzbwogIHBlcm1pdHMgdGhlIHBvc2l0aW9uJ3MgYXBwcm92ZWQgb3BlcmF0b3Igd2hlcmUgYXBwbGljYWJsZQoajhoKCmFzc2VydC5nbm8S/xlwYWNrYWdlIHBvc2l0aW9uCgppbXBvcnQgKAoJImVycm9ycyIKCSJ0aW1lIgoKCXUyNTYgImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoKCXByYmFjICJnbm8ubGFuZC9wL2dub3N3YXAvcmJhYy92MSIKCSJnbm8ubGFuZC9yL2dub3N3YXAvYWNjZXNzL3YxIgopCgovLyBhc3NlcnRJc05vdEV4cGlyZWQgcGFuaWNzIGlmIHRoZSBkZWFkbGluZSBpcyBleHBpcmVkLgpmdW5jIGFzc2VydElzTm90RXhwaXJlZChkZWFkbGluZSBpbnQ2NCkgewoJbm93IDo9IHRpbWUuTm93KCkuVW5peCgpCgoJaWYgbm93ID4gZGVhZGxpbmUgewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJFeHBpcmVkLAoJCQl1Zm10LlNwcmludGYoInRyYW5zYWN0aW9uIHRvbyBvbGQsIG5vdyglZCkgPiBkZWFkbGluZSglZCkiLCBub3csIGRlYWRsaW5lKSwKCQkpKQoJfQp9CgovLyBhc3NlcnRWYWxpZE51bWJlclN0cmluZyBwYW5pY3MgaWYgdGhlIGlucHV0IHN0cmluZyBkb2VzIG5vdCByZXByZXNlbnQgYSB2YWxpZCBpbnRlZ2VyLgpmdW5jIGFzc2VydFZhbGlkTnVtYmVyU3RyaW5nKGlucHV0IHN0cmluZykgewoJaWYgbGVuKGlucHV0KSA9PSAwIHsKCQlwYW5pYyhuZXdFcnJvcldpdGhEZXRhaWwoZXJySW52YWxpZElucHV0LCAiaW5wdXQgaXMgZW1wdHkiKSkKCX0KCglieXRlcyA6PSBbXWJ5dGUoaW5wdXQpCglmb3IgaSwgYiA6PSByYW5nZSBieXRlcyB7CgkJaWYgaSA9PSAwICYmIGIgPT0gJy0nIHsKCQkJY29udGludWUgLy8gQWxsb3cgaWYgdGhlIGZpcnN0IGNoYXJhY3RlciBpcyBhIG5lZ2F0aXZlIHNpZ24gKC0pCgkJfQoJCWlmIGIgPCAnMCcgfHwgYiA+ICc5JyB7CgkJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbCgKCQkJCWVyckludmFsaWRJbnB1dCwKCQkJCXVmbXQuU3ByaW50ZigiaW5wdXQgc3RyaW5nIDogJXMiLCBpbnB1dCkpKQoJCX0KCX0KfQoKLy8gYXNzZXJ0VmFsaWRMaXF1aWRpdHlBbW91bnQgcGFuaWNzIGlmIHRoZSBsaXF1aWRpdHkgYW1vdW50IGlzIHplcm8uCmZ1bmMgYXNzZXJ0VmFsaWRMaXF1aWRpdHlBbW91bnQobGlxdWlkaXR5IHN0cmluZykgewoJaWYgdTI1Ni5NdXN0RnJvbURlY2ltYWwobGlxdWlkaXR5KS5Jc1plcm8oKSB7CgkJcGFuaWMobmV3RXJyb3JXaXRoRGV0YWlsKAoJCQllcnJaZXJvTGlxdWlkaXR5LAoJCQl1Zm10LlNwcmludGYoImxpcXVpZGl0eSBhbW91bnQgbXVzdCBiZSBncmVhdGVyIHRoYW4gMCwgZ290ICVzIiwgbGlxdWlkaXR5KSwKCQkpKQoJfQp9CgovLyBhc3NlcnRFeGlzdHNQb3NpdGlvbiBwYW5pY3MgaWYgdGhlIHBvc2l0aW9uIGRvZXMgbm90IGV4aXN0LgpmdW5jIGFzc2VydEV4aXN0c1Bvc2l0aW9uKHAgKnBvc2l0aW9uVjEsIHBvc2l0aW9uSWQgdWludDY0KSB7CglpZiAhcC5leGlzdHMocG9zaXRpb25JZCkgewoJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbCgKCQkJZXJyUG9zaXRpb25Eb2VzTm90RXhpc3QsCgkJCXVmbXQuU3ByaW50ZigicG9zaXRpb24gd2l0aCBwb3NpdGlvbiBJRCglZCkgZG9lc24ndCBleGlzdCIsIHBvc2l0aW9uSWQpLAoJCSkpCgl9Cn0KCi8vIGFzc2VydElzT3duZXJGb3JUb2tlbiBwYW5pY3MgaWYgY2FsbGVyIGlzIG5vdCB0aGUgb3duZXIgb2YgdGhlIHBvc2l0aW9uLgpmdW5jIGFzc2VydElzT3duZXJGb3JUb2tlbihwICpwb3NpdGlvblYxLCBwb3NpdGlvbklkIHVpbnQ2NCwgY2FsbGVyIGFkZHJlc3MpIHsKCWFzc2VydEV4aXN0c1Bvc2l0aW9uKHAsIHBvc2l0aW9uSWQpCgoJaWYgIXAuaXNPd25lcihwb3NpdGlvbklkLCBjYWxsZXIpIHsKCQlwYW5pYyhuZXdFcnJvcldpdGhEZXRhaWwoCgkJCWVyck5vUGVybWlzc2lvbiwKCQkJdWZtdC5TcHJpbnRmKCJjYWxsZXIoJXMpIGlzIG5vdCBvd25lciBvZiBwb3NpdGlvbklkKCVkKSIsIGNhbGxlciwgcG9zaXRpb25JZCksCgkJKSkKCX0KfQoKLy8gYXNzZXJ0SXNPd25lck9yT3BlcmF0b3JGb3JUb2tlbiBwYW5pY3MgaWYgY2FsbGVyIGlzIG5vdCB0aGUgb3duZXIgb3Igb3BlcmF0b3Igb2YgdGhlIHBvc2l0aW9uLgpmdW5jIGFzc2VydElzT3duZXJPck9wZXJhdG9yRm9yVG9rZW4ocCAqcG9zaXRpb25WMSwgcG9zaXRpb25JZCB1aW50NjQsIGNhbGxlciBhZGRyZXNzKSB7Cglhc3NlcnRFeGlzdHNQb3NpdGlvbihwLCBwb3NpdGlvbklkKQoKCWlmICFwLmlzT3duZXJPck9wZXJhdG9yKHBvc2l0aW9uSWQsIGNhbGxlcikgewoJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbCgKCQkJZXJyTm9QZXJtaXNzaW9uLAoJCQl1Zm10LlNwcmludGYoImNhbGxlciglcykgaXMgbm90IG93bmVyIG9yIGFwcHJvdmVkIG9wZXJhdG9yIG9mIHBvc2l0aW9uSWQoJWQpIiwgY2FsbGVyLCBwb3NpdGlvbklkKSwKCQkpKQoJfQp9CgovLyBhc3NlcnRFcXVhbHNBZGRyZXNzIHBhbmljcyBpZiBhZGRyZXNzZXMgYXJlIGludmFsaWQgb3Igbm90IGVxdWFsLgpmdW5jIGFzc2VydEVxdWFsc0FkZHJlc3MocHJldkFkZHIsIG90aGVyQWRkciBhZGRyZXNzKSB7CglhY2Nlc3MuQXNzZXJ0SXNWYWxpZEFkZHJlc3MocHJldkFkZHIpCglhY2Nlc3MuQXNzZXJ0SXNWYWxpZEFkZHJlc3Mob3RoZXJBZGRyKQoKCWlmIHByZXZBZGRyICE9IG90aGVyQWRkciB7CgkJcGFuaWMobmV3RXJyb3JXaXRoRGV0YWlsKAoJCQllcnJJbnZhbGlkQWRkcmVzcywKCQkJdWZtdC5TcHJpbnRmKCIoJXMsICVzKSIsIHByZXZBZGRyLCBvdGhlckFkZHIpLAoJCSkpCgl9Cn0KCi8vIGFzc2VydFZhbGlkT3BlcmF0b3JBZGRyZXNzIHZhbGlkYXRlcyBvcGVyYXRvciBhZGRyZXNzLgovLyBFbXB0eSBhZGRyZXNzIGlzIGFsbG93ZWQgKGZvciBvcGVyYXRvciByZW1vdmFsKSwgYnV0IG5vbi1lbXB0eSBhZGRyZXNzZXMgbXVzdCBiZSB2YWxpZC4KZnVuYyBhc3NlcnRWYWxpZE9wZXJhdG9yQWRkcmVzcyhvcGVyYXRvciBhZGRyZXNzKSB7CglpZiBvcGVyYXRvciAhPSBhZGRyZXNzKCIiKSAmJiAhb3BlcmF0b3IuSXNWYWxpZCgpIHsKCQlwYW5pYyhuZXdFcnJvcldpdGhEZXRhaWwoZXJySW52YWxpZEFkZHJlc3MsIHVmbXQuU3ByaW50Zigib3BlcmF0b3IoJXMpIiwgb3BlcmF0b3IpKSkKCX0KfQoKLy8gYXNzZXJ0SXNOb3RNaW50VG9TdGFrZXIgcGFuaWNzIGlmIHRoZSBtaW50VG8gYWRkcmVzcyBpcyBzdGFrZXIuCmZ1bmMgYXNzZXJ0SXNOb3RNaW50VG9TdGFrZXIobWludFRvIGFkZHJlc3MpIHsKCXN0YWtlckFkZHIgOj0gYWNjZXNzLk11c3RHZXRBZGRyZXNzKHByYmFjLlJPTEVfU1RBS0VSLlN0cmluZygpKQoJaWYgbWludFRvID09IHN0YWtlckFkZHIgewoJCXBhbmljKGVycm9ycy5OZXcoZXJyQ2Fubm90TWludFRvU3Rha2VyKSkKCX0KfQoa1C4KCGJ1cm4uZ25vEscucGFja2FnZSBwb3NpdGlvbgoKaW1wb3J0ICgKCSJlcnJvcnMiCgoJImduby5sYW5kL3AvZ25vc3dhcC9jb25zdHMvdjEiCgkiZ25vLmxhbmQvcC9nbm9zd2FwL2duc21hdGgvdjEiCgl1MjU2ICJnbm8ubGFuZC9wL2dub3N3YXAvdWludDI1Ni92MSIKCSJnbm8ubGFuZC9wL2dub3N3YXAvdXRpbHMvdjEiCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgoJcGwgImduby5sYW5kL3IvZ25vc3dhcC9wb29sIgoJImduby5sYW5kL3IvZ25vc3dhcC9wb3NpdGlvbiIKKQoKLy8gZGVjcmVhc2VMaXF1aWRpdHkgcmVkdWNlcyBwb3NpdGlvbiBsaXF1aWRpdHkgYW5kIGNvbGxlY3RzIGZlZXMuCi8vIFJldHVybnMgcG9zaXRpb25JZCwgbGlxdWlkaXR5LCBmZWUwLCBmZWUxLCBhbW91bnQwLCBhbW91bnQxLCBwb29sUGF0aC4KZnVuYyAocCAqcG9zaXRpb25WMSkgZGVjcmVhc2VMaXF1aWRpdHkoXyBpbnQsIHJsbSByZWFsbSwgcGFyYW1zIERlY3JlYXNlTGlxdWlkaXR5UGFyYW1zKSAodWludDY0LCBzdHJpbmcsIHN0cmluZywgc3RyaW5nLCBzdHJpbmcsIHN0cmluZywgc3RyaW5nLCBlcnJvcikgewoJY2FsbGVyIDo9IHBhcmFtcy5jYWxsZXIKCgkvLyBiZWZvcmUgZGVjcmVhc2UgbGlxdWlkaXR5LCBjb2xsZWN0IGZlZSBmaXJzdAoJXywgZmVlMFN0ciwgZmVlMVN0ciwgXywgXywgXyA6PSBwLmNvbGxlY3RGZWUoMCwgcmxtLCBwYXJhbXMucG9zaXRpb25JZCwgcGFyYW1zLmNhbGxlcikKCglwb3NpdGlvbiA6PSBwLm11c3RHZXRQb3NpdGlvbihwYXJhbXMucG9zaXRpb25JZCkKCXBvc2l0aW9uTGlxdWlkaXR5IDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKHBvc2l0aW9uLkxpcXVpZGl0eSgpKQoJaWYgcG9zaXRpb25MaXF1aWRpdHkuSXNaZXJvKCkgewoJCXJldHVybiBwYXJhbXMucG9zaXRpb25JZCwKCQkJIiIsCgkJCWZlZTBTdHIsCgkJCWZlZTFTdHIsCgkJCSIiLCAiIiwKCQkJcG9zaXRpb24uUG9vbEtleSgpLAoJCQltYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJCWVyclplcm9MaXF1aWRpdHksCgkJCQl1Zm10LlNwcmludGYoInBvc2l0aW9uKHBvc2l0aW9uIElEOiVkKSBoYXMgMCBsaXF1aWRpdHkiLCBwYXJhbXMucG9zaXRpb25JZCksCgkJCSkKCX0KCglsaXF1aWRpdHlUb1JlbW92ZSA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbChwYXJhbXMubGlxdWlkaXR5KQoKCWlmIGxpcXVpZGl0eVRvUmVtb3ZlLkd0KHBvc2l0aW9uTGlxdWlkaXR5KSB7CgkJcmV0dXJuIHBhcmFtcy5wb3NpdGlvbklkLAoJCQlsaXF1aWRpdHlUb1JlbW92ZS5Ub1N0cmluZygpLAoJCQlmZWUwU3RyLAoJCQlmZWUxU3RyLAoJCQkiIiwgIiIsCgkJCXBvc2l0aW9uLlBvb2xLZXkoKSwKCQkJbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCQllcnJJbnZhbGlkTGlxdWlkaXR5LAoJCQkJdWZtdC5TcHJpbnRmKCJMaXF1aWRpdHkgcmVxdWVzdGVkKCVzKSBpcyBncmVhdGVyIHRoYW4gbGlxdWlkaXR5IGhlbGQoJXMpIiwgbGlxdWlkaXR5VG9SZW1vdmUuVG9TdHJpbmcoKSwgcG9zaXRpb25MaXF1aWRpdHkuVG9TdHJpbmcoKSksCgkJCSkKCX0KCglwVG9rZW4wLCBwVG9rZW4xLCBwRmVlIDo9IHNwbGl0T2YocG9zaXRpb24uUG9vbEtleSgpKQoJYnVybjAsIGJ1cm4xIDo9IHBsLkJ1cm4oY3Jvc3MocmxtKSwgcFRva2VuMCwgcFRva2VuMSwgcEZlZSwgcG9zaXRpb24uVGlja0xvd2VyKCksIHBvc2l0aW9uLlRpY2tVcHBlcigpLCBsaXF1aWRpdHlUb1JlbW92ZS5Ub1N0cmluZygpLCBjYWxsZXIpCgoJYnVybmVkQW1vdW50MCA6PSB1dGlscy5TYWZlUGFyc2VJbnQ2NChidXJuMCkKCWJ1cm5lZEFtb3VudDEgOj0gdXRpbHMuU2FmZVBhcnNlSW50NjQoYnVybjEpCgoJaWYgYnVybmVkQW1vdW50MCA8IDAgfHwgYnVybmVkQW1vdW50MSA8IDAgewoJCXBhbmljKGVycm9ycy5OZXcoZXJyVW5kZXJmbG93KSkKCX0KCglwb3NpdGlvbktleSA6PSBjb21wdXRlUG9zaXRpb25LZXkocG9zaXRpb24uVGlja0xvd2VyKCksIHBvc2l0aW9uLlRpY2tVcHBlcigpKQoJZmVlR3Jvd3RoSW5zaWRlMExhc3RYMTI4U3RyLCBmZWVHcm93dGhJbnNpZGUxTGFzdFgxMjhTdHIsIGVyciA6PSBwbC5HZXRQb3NpdGlvbkZlZUdyb3d0aEluc2lkZUxhc3RYMTI4KHBvc2l0aW9uLlBvb2xLZXkoKSwgcG9zaXRpb25LZXkpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgIiIsICIiLCAiIiwgIiIsICIiLCBwb3NpdGlvbi5Qb29sS2V5KCksIGVycgoJfQoKCS8vIEFkZCBvbmx5IGJ1cm5lZCBhbW91bnRzIHRvIHRva2Vuc093ZWQgc2luY2UgZmVlcyB3ZXJlIGFscmVhZHkgY29sbGVjdGVkIGFuZCBwcm9jZXNzZWQgaW4gY29sbGVjdEZlZQoJdG9rZW5zT3dlZDAgOj0gZ25zbWF0aC5TYWZlQWRkSW50NjQocG9zaXRpb24uVG9rZW5zT3dlZDAoKSwgYnVybmVkQW1vdW50MCkKCXRva2Vuc093ZWQxIDo9IGduc21hdGguU2FmZUFkZEludDY0KHBvc2l0aW9uLlRva2Vuc093ZWQxKCksIGJ1cm5lZEFtb3VudDEpCgoJbmV3TGlxdWlkaXR5LCB1bmRlcmZsb3cgOj0gdTI1Ni5aZXJvKCkuU3ViT3ZlcmZsb3cocG9zaXRpb25MaXF1aWRpdHksIGxpcXVpZGl0eVRvUmVtb3ZlKQoJaWYgdW5kZXJmbG93IHsKCQlwYW5pYyhuZXdFcnJvcldpdGhEZXRhaWwoZXJyVW5kZXJmbG93LCAicG9zaXRpb25MaXF1aWRpdHkgLSBsaXF1aWRpdHlUb1JlbW92ZSB1bmRlcmZsb3ciKSkKCX0KCglwb3NpdGlvbi5TZXRUb2tlbnNPd2VkMCh0b2tlbnNPd2VkMCkKCXBvc2l0aW9uLlNldFRva2Vuc093ZWQxKHRva2Vuc093ZWQxKQoJcG9zaXRpb24uU2V0RmVlR3Jvd3RoSW5zaWRlMExhc3RYMTI4KGZlZUdyb3d0aEluc2lkZTBMYXN0WDEyOFN0cikKCXBvc2l0aW9uLlNldEZlZUdyb3d0aEluc2lkZTFMYXN0WDEyOChmZWVHcm93dGhJbnNpZGUxTGFzdFgxMjhTdHIpCglwb3NpdGlvbi5TZXRMaXF1aWRpdHkobmV3TGlxdWlkaXR5LlRvU3RyaW5nKCkpCgoJcC5tdXN0VXBkYXRlUG9zaXRpb24oMCwgcmxtLCBwYXJhbXMucG9zaXRpb25JZCwgKnBvc2l0aW9uKQoKCWNvbGxlY3QwLCBjb2xsZWN0MSA6PSBwbC5Db2xsZWN0KAoJCWNyb3NzKHJsbSksCgkJcFRva2VuMCwKCQlwVG9rZW4xLAoJCXBGZWUsCgkJY2FsbGVyLAoJCXBvc2l0aW9uLlRpY2tMb3dlcigpLAoJCXBvc2l0aW9uLlRpY2tVcHBlcigpLAoJCWJ1cm4wLAoJCWJ1cm4xLAoJKQoKCWNvbGxlY3RBbW91bnQwIDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKGNvbGxlY3QwKQoJY29sbGVjdEFtb3VudDEgOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwoY29sbGVjdDEpCgoJLy8gU2xpcHBhZ2UgY2hlY2sgb24gYWN0dWFsbHkgY29sbGVjdGVkIGFtb3VudHMgdG8gZW5zdXJlIHVzZXIgcmVjZWl2ZXMgbWluaW11bSBleHBlY3RlZCB0b2tlbnMKCWlmIGlzU2xpcHBhZ2VFeGNlZWRlZChjb2xsZWN0QW1vdW50MCwgY29sbGVjdEFtb3VudDEsIHBhcmFtcy5hbW91bnQwTWluLCBwYXJhbXMuYW1vdW50MU1pbikgewoJCXJldHVybiBwYXJhbXMucG9zaXRpb25JZCwKCQkJbGlxdWlkaXR5VG9SZW1vdmUuVG9TdHJpbmcoKSwKCQkJZmVlMFN0ciwKCQkJZmVlMVN0ciwKCQkJY29sbGVjdDAsCgkJCWNvbGxlY3QxLAoJCQlwb3NpdGlvbi5Qb29sS2V5KCksCgkJCW1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQkJZXJyU2xpcHBhZ2UsCgkJCQl1Zm10LlNwcmludGYoImNvbGxlY3RBbW91bnQwKCVzKSA+PSBhbW91bnQwTWluKCVzKSAmJiBjb2xsZWN0QW1vdW50MSglcykgPj0gYW1vdW50MU1pbiglcykiLAoJCQkJCWNvbGxlY3RBbW91bnQwLlRvU3RyaW5nKCksCgkJCQkJcGFyYW1zLmFtb3VudDBNaW4uVG9TdHJpbmcoKSwKCQkJCQljb2xsZWN0QW1vdW50MS5Ub1N0cmluZygpLAoJCQkJCXBhcmFtcy5hbW91bnQxTWluLlRvU3RyaW5nKCksCgkJCQkpLAoJCQkpCgl9CgoJLy8gQ2hlY2sgZm9yIHVuZGVyZmxvdyB3aGVuIHN1YnRyYWN0aW5nIGNvbGxlY3RlZCBhbW91bnRzIGZyb20gdG9rZW5zIG93ZWQKCWNvbGxlY3RBbW91bnQwSW50NjQgOj0gZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQoY29sbGVjdEFtb3VudDApCgljb2xsZWN0QW1vdW50MUludDY0IDo9IGduc21hdGguU2FmZUNvbnZlcnRUb0ludDY0KGNvbGxlY3RBbW91bnQxKQoKCWlmIHBvc2l0aW9uLlRva2Vuc093ZWQwKCkgPCBjb2xsZWN0QW1vdW50MEludDY0IHsKCQlwYW5pYyh1Zm10LlNwcmludGYoIltQT1NJVElPTl0gYnVybi5nbm8gfCBjb2xsZWN0KCkgfCB0b2tlbnNPd2VkMCglZCkgPCBjb2xsZWN0QW1vdW50MCglZCkiLCBwb3NpdGlvbi5Ub2tlbnNPd2VkMCgpLCBjb2xsZWN0QW1vdW50MEludDY0KSkKCX0KCXBvc2l0aW9uLlNldFRva2Vuc093ZWQwKGduc21hdGguU2FmZVN1YkludDY0KHBvc2l0aW9uLlRva2Vuc093ZWQwKCksIGNvbGxlY3RBbW91bnQwSW50NjQpKQoKCWlmIHBvc2l0aW9uLlRva2Vuc093ZWQxKCkgPCBjb2xsZWN0QW1vdW50MUludDY0IHsKCQlwYW5pYyh1Zm10LlNwcmludGYoIltQT1NJVElPTl0gYnVybi5nbm8gfCBjb2xsZWN0KCkgfCB0b2tlbnNPd2VkMSglZCkgPCBjb2xsZWN0QW1vdW50MSglZCkiLCBwb3NpdGlvbi5Ub2tlbnNPd2VkMSgpLCBjb2xsZWN0QW1vdW50MUludDY0KSkKCX0KCXBvc2l0aW9uLlNldFRva2Vuc093ZWQxKGduc21hdGguU2FmZVN1YkludDY0KHBvc2l0aW9uLlRva2Vuc093ZWQxKCksIGNvbGxlY3RBbW91bnQxSW50NjQpKQoKCWlmIHBvc2l0aW9uLklzQ2xlYXIoKSB7CgkJcG9zaXRpb24uU2V0QnVybmVkKHRydWUpIC8vIGp1c3QgdXBkYXRlIGZsYWcgKHdlIGRvbid0IHdhbnQgdG8gYnVybiBhY3R1YWwgcG9zaXRpb24pCgl9CgoJcC5tdXN0VXBkYXRlUG9zaXRpb24oMCwgcmxtLCBwYXJhbXMucG9zaXRpb25JZCwgKnBvc2l0aW9uKQoKCXJldHVybiBwYXJhbXMucG9zaXRpb25JZCwgbGlxdWlkaXR5VG9SZW1vdmUuVG9TdHJpbmcoKSwgZmVlMFN0ciwgZmVlMVN0ciwgY29sbGVjdDAsIGNvbGxlY3QxLCBwb3NpdGlvbi5Qb29sS2V5KCksIG5pbAp9CgovLyBjYWxjdWxhdGVGZWVzIGNhbGN1bGF0ZXMgdGhlIGZlZXMgZm9yIHRoZSBjdXJyZW50IHBvc2l0aW9uLgpmdW5jIChwICpwb3NpdGlvblYxKSBjYWxjdWxhdGVGZWVzKHBvc2l0aW9uICpwb3NpdGlvbi5Qb3NpdGlvbiwgY3VycmVudEZlZUdyb3d0aCBGZWVHcm93dGhJbnNpZGUpIChpbnQ2NCwgaW50NjQpIHsKCXBvc0xpcXVpZGl0eSA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbChwb3NpdGlvbi5MaXF1aWRpdHkoKSkKCWZlZTAgOj0gY2FsY3VsYXRlVG9rZW5zT3dlZCgKCQljdXJyZW50RmVlR3Jvd3RoLmZlZUdyb3d0aEluc2lkZTBMYXN0WDEyOCwKCQl1MjU2Lk11c3RGcm9tRGVjaW1hbChwb3NpdGlvbi5GZWVHcm93dGhJbnNpZGUwTGFzdFgxMjgoKSksCgkJcG9zTGlxdWlkaXR5LAoJKQoKCWZlZTEgOj0gY2FsY3VsYXRlVG9rZW5zT3dlZCgKCQljdXJyZW50RmVlR3Jvd3RoLmZlZUdyb3d0aEluc2lkZTFMYXN0WDEyOCwKCQl1MjU2Lk11c3RGcm9tRGVjaW1hbChwb3NpdGlvbi5GZWVHcm93dGhJbnNpZGUxTGFzdFgxMjgoKSksCgkJcG9zTGlxdWlkaXR5LAoJKQoKCXJldHVybiBnbnNtYXRoLlNhZmVBZGRJbnQ2NChwb3NpdGlvbi5Ub2tlbnNPd2VkMCgpLCBnbnNtYXRoLlNhZmVDb252ZXJ0VG9JbnQ2NChmZWUwKSksIGduc21hdGguU2FmZUFkZEludDY0KHBvc2l0aW9uLlRva2Vuc093ZWQxKCksIGduc21hdGguU2FmZUNvbnZlcnRUb0ludDY0KGZlZTEpKQp9CgpmdW5jIGNhbGN1bGF0ZVRva2Vuc093ZWQoCglmZWVHcm93dGhJbnNpZGVMYXN0WDEyOCAqdTI1Ni5VaW50LAoJcG9zaXRpb25GZWVHcm93dGhJbnNpZGVMYXN0WDEyOCAqdTI1Ni5VaW50LAoJcG9zaXRpb25MaXF1aWRpdHkgKnUyNTYuVWludCwKKSAqdTI1Ni5VaW50IHsKCWRpZmYgOj0gdTI1Ni5aZXJvKCkuU3ViKGZlZUdyb3d0aEluc2lkZUxhc3RYMTI4LCBwb3NpdGlvbkZlZUdyb3d0aEluc2lkZUxhc3RYMTI4KQoJcmV0dXJuIHUyNTYuTXVsRGl2KGRpZmYsIHBvc2l0aW9uTGlxdWlkaXR5LCBjb25zdHMuUTEyOCgpKQp9ChqrAwoHZG9jLmdubxKfAy8vIHBhY2thZ2UgdjEgbWFuYWdlcyBsaXF1aWRpdHkgcG9zaXRpb25zIGFzIE5GVHMgaW4gR25vU3dhcCBwb29scy4KLy8KLy8gRWFjaCBwb3NpdGlvbiBpcyByZXByZXNlbnRlZCBhcyBhIEdSQzcyMSBORlQgd2l0aCBjb25jZW50cmF0ZWQgbGlxdWlkaXR5Ci8vIHdpdGhpbiBhIHNwZWNpZmljIHRpY2sgcmFuZ2UuIFVuc3Rha2VkIE5GVHMgZm9sbG93IEdSQzcyMSBvd25lci9hcHByb3ZhbC8KLy8gb3BlcmF0b3IgdHJhbnNmZXIgcnVsZXM7IHN0YWtlZCBORlRzIGFyZSBsb2NrZWQgdG8gc3Rha2VyLW1lZGlhdGVkIHRyYW5zZmVycy4KLy8gVGhlIHBhY2thZ2UgaGFuZGxlcyBtaW50aW5nLCBsaXF1aWRpdHkgYWRqdXN0bWVudHMsIGZlZSBjb2xsZWN0aW9uLCBhbmQKLy8gcmVwb3NpdGlvbmluZy4KcGFja2FnZSBwb3NpdGlvbgoahg0KCmVycm9ycy5nbm8S9wxwYWNrYWdlIHBvc2l0aW9uCgppbXBvcnQgKAoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgopCgpjb25zdCAoCgllcnJOb1Blcm1pc3Npb24gICAgICAgICA9ICJbR05PU1dBUC1QT1NJVElPTi0wMDFdIGNhbGxlciBoYXMgbm8gcGVybWlzc2lvbiIKCWVyclNsaXBwYWdlICAgICAgICAgICAgID0gIltHTk9TV0FQLVBPU0lUSU9OLTAwMl0gc2xpcHBhZ2UgZmFpbGVkIgoJZXJySW52YWxpZFRva2VuUGF0aCAgICAgPSAiW0dOT1NXQVAtUE9TSVRJT04tMDAzXSBpbnZhbGlkIHRva2VuIGFkZHJlc3MiCgllcnJJbnZhbGlkSW5wdXQgICAgICAgICA9ICJbR05PU1dBUC1QT1NJVElPTi0wMDRdIGludmFsaWQgaW5wdXQgZGF0YSIKCWVyckRhdGFOb3RGb3VuZCAgICAgICAgID0gIltHTk9TV0FQLVBPU0lUSU9OLTAwNV0gcmVxdWVzdGVkIGRhdGEgbm90IGZvdW5kIgoJZXJyRXhwaXJlZCAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtUE9TSVRJT04tMDA2XSB0cmFuc2FjdGlvbiBleHBpcmVkIgoJZXJySW52YWxpZExpcXVpZGl0eSAgICAgPSAiW0dOT1NXQVAtUE9TSVRJT04tMDA3XSBpbnZhbGlkIGxpcXVpZGl0eSIKCWVyck5vdENsZWFyICAgICAgICAgICAgID0gIltHTk9TV0FQLVBPU0lUSU9OLTAwOF0gcG9zaXRpb24gaXMgbm90IGNsZWFyIgoJZXJyWmVyb0xpcXVpZGl0eSAgICAgICAgPSAiW0dOT1NXQVAtUE9TSVRJT04tMDA5XSB6ZXJvIGxpcXVpZGl0eSIKCWVyclBvc2l0aW9uRXhpc3QgICAgICAgID0gIltHTk9TV0FQLVBPU0lUSU9OLTAxMF0gcG9zaXRpb24gd2l0aCBzYW1lIHBvc2l0aW9uSWQgYWxyZWFkeSBleGlzdHMiCgllcnJJbnZhbGlkQWRkcmVzcyAgICAgICA9ICJbR05PU1dBUC1QT1NJVElPTi0wMTFdIGludmFsaWQgYWRkcmVzcyIKCWVyclBvc2l0aW9uRG9lc05vdEV4aXN0ID0gIltHTk9TV0FQLVBPU0lUSU9OLTAxMl0gcG9zaXRpb24gZG9lcyBub3QgZXhpc3QiCgllcnJVbmRlcmZsb3cgICAgICAgICAgICA9ICJbR05PU1dBUC1QT1NJVElPTi0wMTNdIHVuZGVyZmxvdyIKCWVyck92ZXJmbG93ICAgICAgICAgICAgID0gIltHTk9TV0FQLVBPU0lUSU9OLTAxNF0gb3ZlcmZsb3ciCgllcnJDYW5ub3RNaW50VG9TdGFrZXIgICA9ICJbR05PU1dBUC1QT1NJVElPTi0wMTVdIGNhbm5vdCBtaW50IHRvIHN0YWtlciIKCWVyclNwb29mZWRSZWFsbSAgICAgICAgID0gIltHTk9TV0FQLVBPU0lUSU9OLTAxNl0gcmxtIGRvZXMgbm90IG1hdGNoIHRoZSBjdXJyZW50IGNyb3NzaW5nIGZyYW1lIgopCgovLyBuZXdFcnJvcldpdGhEZXRhaWwgYXBwZW5kcyBhZGRpdGlvbmFsIGNvbnRleHQgb3IgZGV0YWlscyB0byBhbiBleGlzdGluZyBlcnJvciBtZXNzYWdlLgpmdW5jIG5ld0Vycm9yV2l0aERldGFpbChtZXNzYWdlIHN0cmluZywgZGV0YWlsIHN0cmluZykgc3RyaW5nIHsKCXJldHVybiB1Zm10LkVycm9yZigiJXMgfHwgJXMiLCBtZXNzYWdlLCBkZXRhaWwpLkVycm9yKCkKfQoKLy8gbWFrZUVycm9yV2l0aERldGFpbHMgY3JlYXRlcyBhbiBlcnJvciB3aXRoIGFkZGl0aW9uYWwgY29udGV4dC4KZnVuYyBtYWtlRXJyb3JXaXRoRGV0YWlscyhtZXNzYWdlIHN0cmluZywgZGV0YWlscyBzdHJpbmcpIGVycm9yIHsKCXJldHVybiB1Zm10LkVycm9yZigiJXMgfHwgJXMiLCBtZXNzYWdlLCBkZXRhaWxzKQp9ChrTdwoKZ2V0dGVyLmdubxLEd3BhY2thZ2UgcG9zaXRpb24KCmltcG9ydCAoCgkiZXJyb3JzIgoKCSJnbm8ubGFuZC9wL2dub3N3YXAvY29uc3RzL3YxIgoJdTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL3VpbnQyNTYvdjEiCglyb3RyZWUgImduby5sYW5kL3AvbnQvYnB0cmVlL3JvdHJlZS92MCIKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCglwbCAiZ25vLmxhbmQvci9nbm9zd2FwL3Bvb2wiCgkiZ25vLmxhbmQvci9nbm9zd2FwL3Bvc2l0aW9uIgopCgovLyBnZXRQb3NpdGlvbiByZXR1cm5zIGEgcG9zaXRpb24gZm9yIGEgZ2l2ZW4gcG9zaXRpb24gSUQuCi8vIFJldHVybnMgYW4gZXJyb3IgaWYgdGhlIHBvc2l0aW9uIGRvZXNuJ3QgZXhpc3QuCmZ1bmMgKHAgKnBvc2l0aW9uVjEpIGdldFBvc2l0aW9uKHBvc2l0aW9uSWQgdWludDY0KSAocG9zaXRpb24uUG9zaXRpb24sIGVycm9yKSB7Cglwb3MsIGV4aXN0cyA6PSBwLnN0b3JlLkdldFBvc2l0aW9uKHBvc2l0aW9uSWQpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gcG9zLCBlcnJvcnMuTmV3KG5ld0Vycm9yV2l0aERldGFpbCgKCQkJZXJyUG9zaXRpb25Eb2VzTm90RXhpc3QsCgkJCXVmbXQuU3ByaW50ZigicG9zaXRpb24gd2l0aCBwb3NpdGlvbiBJRCglZCkgZG9lc24ndCBleGlzdCIsIHBvc2l0aW9uSWQpLAoJCSkpCgl9CgoJcmV0dXJuIHBvcywgbmlsCn0KCi8vIG11c3RHZXRQb3NpdGlvbiByZXR1cm5zIGEgcG9zaXRpb24gZm9yIGEgZ2l2ZW4gcG9zaXRpb24gSUQuCi8vIHBhbmljcyBpZiBwb3NpdGlvbiBkb2Vzbid0IGV4aXN0CmZ1bmMgKHAgKnBvc2l0aW9uVjEpIG11c3RHZXRQb3NpdGlvbihwb3NpdGlvbklkIHVpbnQ2NCkgKnBvc2l0aW9uLlBvc2l0aW9uIHsKCXBvc2l0aW9uLCBlcnIgOj0gcC5nZXRQb3NpdGlvbihwb3NpdGlvbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyLkVycm9yKCkpCgl9CgoJcmV0dXJuICZwb3NpdGlvbgp9CgovLyBHZXRQb3NpdGlvbnMgcmV0dXJucyBhIHJlYWQtb25seSB2aWV3IG9mIGV2ZXJ5IHBvc2l0aW9uLCBrZXllZCBieSB0aGUgZGVjaW1hbAovLyBzdHJpbmcgZm9ybSBvZiB0aGUgcG9zaXRpb24gSUQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBwb3NpdGlvbnM6IHJlYWQtb25seSB0cmVlIGV4cG9zaW5nIHRoZSBwb3NpdGlvbiBzdG9yZSB3aXRob3V0IG11dGF0aW9uIG1ldGhvZHMKZnVuYyAocCAqcG9zaXRpb25WMSkgR2V0UG9zaXRpb25zKCkgKnJvdHJlZS5SZWFkT25seVRyZWUgewoJLy8gbWFrZUVudHJ5U2FmZUZuIGlzIGEgZnVuY3Rpb24gdGhhdCBtYWtlcyBhbiBlbnRyeSBzYWZlIHRvIHJlYWQuCgkvLyBCdXQgUG9zaXRpb24gaXMgaW1tdXRhYmxlLCBzbyB3ZSBjYW4ganVzdCByZXR1cm4gdGhlIGVudHJ5IGFzIGlzLgoJcmV0dXJuIHJvdHJlZS5XcmFwKHAuc3RvcmUuR2V0UG9zaXRpb25zKCksIG5pbCkKfQoKLy8gRXhpc3RQb3NpdGlvbiByZXBvcnRzIHdoZXRoZXIgYSBwb3NpdGlvbiBleGlzdHMgZm9yIGEgZ2l2ZW4gcG9zaXRpb24gSUQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb3NpdGlvbklkOiBudW1lcmljIElEIHRvIHRlc3QgaW4gdGhlIHBvc2l0aW9uIHN0b3JlCi8vCi8vIFJldHVybnM6Ci8vICAgLSBleGlzdHM6IHRydWUgd2hlbiB0aGUgcG9zaXRpb24gc3RvcmUgY29udGFpbnMgcG9zaXRpb25JZApmdW5jIChwICpwb3NpdGlvblYxKSBFeGlzdFBvc2l0aW9uKHBvc2l0aW9uSWQgdWludDY0KSBib29sIHsKCXJldHVybiBwLnN0b3JlLkhhc1Bvc2l0aW9uKHBvc2l0aW9uSWQpCn0KCi8vIElzQnVybmVkIHJlcG9ydHMgdGhlIGVtcHR5LXBvc2l0aW9uIG1hcmtlciBzdG9yZWQgZm9yIGEgcG9zaXRpb24uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb3NpdGlvbklkOiBudW1lcmljIElEIHdob3NlIGJ1cm5lZCBtYXJrZXIgaXMgcmVxdWVzdGVkCi8vCi8vIFJldHVybnM6Ci8vICAgLSBidXJuZWQ6IHRydWUgd2hlbiB0aGUgcG9zaXRpb24gaXMgbWFya2VkIGVtcHR5OyB0aGUgTkZUIHJlY29yZCBpdHNlbGYgbWF5IHN0aWxsIGV4aXN0Ci8vICAgLSBlcnI6IG5pbCBvbiBsb29rdXAgc3VjY2VzczsgZXJyUG9zaXRpb25Eb2VzTm90RXhpc3Qgd2hlbiB0aGUgcG9zaXRpb24gaXMgYWJzZW50CmZ1bmMgKHAgKnBvc2l0aW9uVjEpIElzQnVybmVkKHBvc2l0aW9uSWQgdWludDY0KSAoYm9vbCwgZXJyb3IpIHsKCXBvc2l0aW9uLCBlcnIgOj0gcC5nZXRQb3NpdGlvbihwb3NpdGlvbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGZhbHNlLCBlcnIKCX0KCglyZXR1cm4gcG9zaXRpb24uQnVybmVkKCksIG5pbAp9CgovLyBJc0luUmFuZ2UgcmVwb3J0cyB3aGV0aGVyIHRoZSBwb29sJ3MgY3VycmVudCB0aWNrIGlzIGluc2lkZSBhIHBvc2l0aW9uJ3MgcmFuZ2UuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb3NpdGlvbklkOiBudW1lcmljIElEIHdob3NlIHRpY2sgcmFuZ2UgYW5kIHBvb2wgYXJlIGluc3BlY3RlZAovLwovLyBSZXR1cm5zOgovLyAgIC0gaW5SYW5nZTogdHJ1ZSB3aGVuIHRpY2tMb3dlciA8PSBjdXJyZW50IHBvb2wgdGljayA8IHRpY2tVcHBlcgovLyAgIC0gZXJyOiBuaWwgb24gc3VjY2VzczsgYW4gZXJyb3Igd2hlbiB0aGUgcG9zaXRpb24gb3IgaXRzIHBvb2wgdGljayBjYW5ub3QgYmUgcmVhZApmdW5jIChwICpwb3NpdGlvblYxKSBJc0luUmFuZ2UocG9zaXRpb25JZCB1aW50NjQpIChib29sLCBlcnJvcikgewoJcG9zaXRpb24sIGVyciA6PSBwLmdldFBvc2l0aW9uKHBvc2l0aW9uSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZmFsc2UsIGVycgoJfQoKCXBvb2xQYXRoIDo9IHBvc2l0aW9uLlBvb2xLZXkoKQoJcG9vbEN1cnJlbnRUaWNrLCBlcnIgOj0gcGwuR2V0U2xvdDBUaWNrKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGZhbHNlLCBlcnIKCX0KCglyZXR1cm4gcG9zaXRpb24uVGlja0xvd2VyKCkgPD0gcG9vbEN1cnJlbnRUaWNrICYmIHBvb2xDdXJyZW50VGljayA8IHBvc2l0aW9uLlRpY2tVcHBlcigpLCBuaWwKfQoKLy8gR2V0UG9zaXRpb25PcGVyYXRvciByZXR1cm5zIHRoZSBhZGRyZXNzIGFwcHJvdmVkIHRvIG9wZXJhdGUgb24gYSBwb3NpdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvc2l0aW9uSWQ6IG51bWVyaWMgSUQgd2hvc2Ugb3BlcmF0b3IgaXMgcmVxdWVzdGVkCi8vCi8vIFJldHVybnM6Ci8vICAgLSBvcGVyYXRvcjogYXBwcm92ZWQgb3BlcmF0b3IgYWRkcmVzcywgb3IgdGhlIGVtcHR5IGFkZHJlc3Mgd2hlbiBub25lIGlzIHNldAovLyAgIC0gZXJyOiBuaWwgb24gbG9va3VwIHN1Y2Nlc3M7IGVyclBvc2l0aW9uRG9lc05vdEV4aXN0IHdoZW4gdGhlIHBvc2l0aW9uIGlzIGFic2VudApmdW5jIChwICpwb3NpdGlvblYxKSBHZXRQb3NpdGlvbk9wZXJhdG9yKHBvc2l0aW9uSWQgdWludDY0KSAoYWRkcmVzcywgZXJyb3IpIHsKCXBvc2l0aW9uLCBlcnIgOj0gcC5nZXRQb3NpdGlvbihwb3NpdGlvbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGFkZHJlc3MoIiIpLCBlcnIKCX0KCglyZXR1cm4gcG9zaXRpb24uT3BlcmF0b3IoKSwgbmlsCn0KCi8vIEdldFBvc2l0aW9uUG9vbEtleSByZXR1cm5zIHRoZSBwb29sIGlkZW50aWZpZXIgc3RvcmVkIG9uIGEgcG9zaXRpb24uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb3NpdGlvbklkOiBudW1lcmljIElEIHdob3NlIHBvb2wga2V5IGlzIHJlcXVlc3RlZAovLwovLyBSZXR1cm5zOgovLyAgIC0gcG9vbEtleTogcG9vbCBrZXkgZW5jb2RpbmcgdGhlIHBvc2l0aW9uJ3MgdG9rZW4gcGFpciBhbmQgZmVlIHRpZXIKLy8gICAtIGVycjogbmlsIG9uIGxvb2t1cCBzdWNjZXNzOyBlcnJQb3NpdGlvbkRvZXNOb3RFeGlzdCB3aGVuIHRoZSBwb3NpdGlvbiBpcyBhYnNlbnQKZnVuYyAocCAqcG9zaXRpb25WMSkgR2V0UG9zaXRpb25Qb29sS2V5KHBvc2l0aW9uSWQgdWludDY0KSAoc3RyaW5nLCBlcnJvcikgewoJcG9zaXRpb24sIGVyciA6PSBwLmdldFBvc2l0aW9uKHBvc2l0aW9uSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsIGVycgoJfQoKCXJldHVybiBwb3NpdGlvbi5Qb29sS2V5KCksIG5pbAp9CgovLyBHZXRQb3NpdGlvblRpY2tMb3dlciByZXR1cm5zIHRoZSBsb3dlciB0aWNrIGJvdW5kYXJ5IHN0b3JlZCBvbiBhIHBvc2l0aW9uLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9zaXRpb25JZDogbnVtZXJpYyBJRCB3aG9zZSBsb3dlciB0aWNrIGlzIHJlcXVlc3RlZAovLwovLyBSZXR1cm5zOgovLyAgIC0gdGlja0xvd2VyOiBsb3dlciB0aWNrIGJvdW5kYXJ5LCBpbmNsdXNpdmUgaW4gcmFuZ2UgY2hlY2tzCi8vICAgLSBlcnI6IG5pbCBvbiBsb29rdXAgc3VjY2VzczsgZXJyUG9zaXRpb25Eb2VzTm90RXhpc3Qgd2hlbiB0aGUgcG9zaXRpb24gaXMgYWJzZW50CmZ1bmMgKHAgKnBvc2l0aW9uVjEpIEdldFBvc2l0aW9uVGlja0xvd2VyKHBvc2l0aW9uSWQgdWludDY0KSAoaW50MzIsIGVycm9yKSB7Cglwb3NpdGlvbiwgZXJyIDo9IHAuZ2V0UG9zaXRpb24ocG9zaXRpb25JZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCglyZXR1cm4gcG9zaXRpb24uVGlja0xvd2VyKCksIG5pbAp9CgovLyBHZXRQb3NpdGlvblRpY2tVcHBlciByZXR1cm5zIHRoZSB1cHBlciB0aWNrIGJvdW5kYXJ5IHN0b3JlZCBvbiBhIHBvc2l0aW9uLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9zaXRpb25JZDogbnVtZXJpYyBJRCB3aG9zZSB1cHBlciB0aWNrIGlzIHJlcXVlc3RlZAovLwovLyBSZXR1cm5zOgovLyAgIC0gdGlja1VwcGVyOiB1cHBlciB0aWNrIGJvdW5kYXJ5LCBleGNsdXNpdmUgaW4gcmFuZ2UgY2hlY2tzCi8vICAgLSBlcnI6IG5pbCBvbiBsb29rdXAgc3VjY2VzczsgZXJyUG9zaXRpb25Eb2VzTm90RXhpc3Qgd2hlbiB0aGUgcG9zaXRpb24gaXMgYWJzZW50CmZ1bmMgKHAgKnBvc2l0aW9uVjEpIEdldFBvc2l0aW9uVGlja1VwcGVyKHBvc2l0aW9uSWQgdWludDY0KSAoaW50MzIsIGVycm9yKSB7Cglwb3NpdGlvbiwgZXJyIDo9IHAuZ2V0UG9zaXRpb24ocG9zaXRpb25JZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCglyZXR1cm4gcG9zaXRpb24uVGlja1VwcGVyKCksIG5pbAp9CgovLyBHZXRQb3NpdGlvbkxpcXVpZGl0eSByZXR1cm5zIHRoZSBkZWNpbWFsLWVuY29kZWQgbGlxdWlkaXR5IHN0b3JlZCBvbiBhIHBvc2l0aW9uLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9zaXRpb25JZDogbnVtZXJpYyBJRCB3aG9zZSBsaXF1aWRpdHkgaXMgcmVxdWVzdGVkCi8vCi8vIFJldHVybnM6Ci8vICAgLSBsaXF1aWRpdHk6IGRlY2ltYWwgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgcG9zaXRpb24ncyBjdXJyZW50IGxpcXVpZGl0eQovLyAgIC0gZXJyOiBuaWwgb24gbG9va3VwIHN1Y2Nlc3M7IGVyclBvc2l0aW9uRG9lc05vdEV4aXN0IHdoZW4gdGhlIHBvc2l0aW9uIGlzIGFic2VudApmdW5jIChwICpwb3NpdGlvblYxKSBHZXRQb3NpdGlvbkxpcXVpZGl0eShwb3NpdGlvbklkIHVpbnQ2NCkgKHN0cmluZywgZXJyb3IpIHsKCXBvc2l0aW9uLCBlcnIgOj0gcC5nZXRQb3NpdGlvbihwb3NpdGlvbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuICIiLCBlcnIKCX0KCglyZXR1cm4gcG9zaXRpb24uTGlxdWlkaXR5KCksIG5pbAp9CgovLyBHZXRQb3NpdGlvblRva2VuQmFsYW5jZXMgcmV0dXJucyBiYWxhbmNlcyBkZXJpdmVkIGZyb20gY3VycmVudCBwb29sIHByaWNlLAovLyBwb3NpdGlvbiByYW5nZSwgYW5kIGxpcXVpZGl0eTsgdG9rZW4gYmFsYW5jZXMgYXJlIG5vdCBzdG9yZWQgc25hcHNob3RzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9zaXRpb25JZDogbnVtZXJpYyBJRCB3aG9zZSBjdXJyZW50IHRva2VuIGJhbGFuY2VzIGFyZSBjYWxjdWxhdGVkCi8vCi8vIFJldHVybnM6Ci8vICAgLSB0b2tlbjBCYWxhbmNlOiBjdXJyZW50IHRva2VuMCBhbW91bnQgcmVwcmVzZW50ZWQgYnkgdGhlIHBvc2l0aW9uJ3MgbGlxdWlkaXR5IGFuZCByYW5nZQovLyAgIC0gdG9rZW4xQmFsYW5jZTogY3VycmVudCB0b2tlbjEgYW1vdW50IHJlcHJlc2VudGVkIGJ5IHRoZSBwb3NpdGlvbidzIGxpcXVpZGl0eSBhbmQgcmFuZ2UKLy8gICAtIGVycjogbmlsIHdoZW4gdGhlIHBvc2l0aW9uIGV4aXN0czsgZXJyUG9zaXRpb25Eb2VzTm90RXhpc3Qgd2hlbiBpdCBpcyBhYnNlbnQgKHBvb2wgcHJpY2UgbG9va3VwIGZhaWx1cmVzIHBhbmljIGR1cmluZyBjYWxjdWxhdGlvbikKZnVuYyAocCAqcG9zaXRpb25WMSkgR2V0UG9zaXRpb25Ub2tlbkJhbGFuY2VzKHBvc2l0aW9uSWQgdWludDY0KSAoaW50NjQsIGludDY0LCBlcnJvcikgewoJcG9zaXRpb24sIGVyciA6PSBwLmdldFBvc2l0aW9uKHBvc2l0aW9uSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgMCwgZXJyCgl9CgoJYmFsYW5jZTAsIGJhbGFuY2UxIDo9IGNhbGN1bGF0ZVBvc2l0aW9uQmFsYW5jZXMoJnBvc2l0aW9uKQoJcmV0dXJuIGJhbGFuY2UwLCBiYWxhbmNlMSwgbmlsCn0KCi8vIEdldFBvc2l0aW9uRmVlR3Jvd3RoSW5zaWRlMExhc3RYMTI4IHJldHVybnMgdGhlIHRva2VuMCBmZWUtZ3Jvd3RoIGNoZWNrcG9pbnQKLy8gc3RvcmVkIG9uIGEgcG9zaXRpb24uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb3NpdGlvbklkOiBudW1lcmljIElEIHdob3NlIHRva2VuMCBmZWUtZ3Jvd3RoIGNoZWNrcG9pbnQgaXMgcmVxdWVzdGVkCi8vCi8vIFJldHVybnM6Ci8vICAgLSBmZWVHcm93dGhJbnNpZGUwTGFzdFgxMjg6IGRlY2ltYWwtZW5jb2RlZCBRMTI4IHRva2VuMCBmZWUgZ3Jvd3RoIGluc2lkZSB0aGUgcG9zaXRpb24ncyByYW5nZSBhdCBpdHMgbGFzdCB1cGRhdGUKLy8gICAtIGVycjogbmlsIG9uIGxvb2t1cCBzdWNjZXNzOyBlcnJQb3NpdGlvbkRvZXNOb3RFeGlzdCB3aGVuIHRoZSBwb3NpdGlvbiBpcyBhYnNlbnQKZnVuYyAocCAqcG9zaXRpb25WMSkgR2V0UG9zaXRpb25GZWVHcm93dGhJbnNpZGUwTGFzdFgxMjgocG9zaXRpb25JZCB1aW50NjQpIChzdHJpbmcsIGVycm9yKSB7Cglwb3NpdGlvbiwgZXJyIDo9IHAuZ2V0UG9zaXRpb24ocG9zaXRpb25JZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgZXJyCgl9CgoJcmV0dXJuIHBvc2l0aW9uLkZlZUdyb3d0aEluc2lkZTBMYXN0WDEyOCgpLCBuaWwKfQoKLy8gR2V0UG9zaXRpb25GZWVHcm93dGhJbnNpZGUxTGFzdFgxMjggcmV0dXJucyB0aGUgdG9rZW4xIGZlZS1ncm93dGggY2hlY2twb2ludAovLyBzdG9yZWQgb24gYSBwb3NpdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvc2l0aW9uSWQ6IG51bWVyaWMgSUQgd2hvc2UgdG9rZW4xIGZlZS1ncm93dGggY2hlY2twb2ludCBpcyByZXF1ZXN0ZWQKLy8KLy8gUmV0dXJuczoKLy8gICAtIGZlZUdyb3d0aEluc2lkZTFMYXN0WDEyODogZGVjaW1hbC1lbmNvZGVkIFExMjggdG9rZW4xIGZlZSBncm93dGggaW5zaWRlIHRoZSBwb3NpdGlvbidzIHJhbmdlIGF0IGl0cyBsYXN0IHVwZGF0ZQovLyAgIC0gZXJyOiBuaWwgb24gbG9va3VwIHN1Y2Nlc3M7IGVyclBvc2l0aW9uRG9lc05vdEV4aXN0IHdoZW4gdGhlIHBvc2l0aW9uIGlzIGFic2VudApmdW5jIChwICpwb3NpdGlvblYxKSBHZXRQb3NpdGlvbkZlZUdyb3d0aEluc2lkZTFMYXN0WDEyOChwb3NpdGlvbklkIHVpbnQ2NCkgKHN0cmluZywgZXJyb3IpIHsKCXBvc2l0aW9uLCBlcnIgOj0gcC5nZXRQb3NpdGlvbihwb3NpdGlvbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuICIiLCBlcnIKCX0KCglyZXR1cm4gcG9zaXRpb24uRmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4KCksIG5pbAp9CgovLyBHZXRQb3NpdGlvbkZlZUdyb3d0aEluc2lkZUxhc3RYMTI4IHJldHVybnMgYm90aCBmZWUtZ3Jvd3RoIGNoZWNrcG9pbnRzIHN0b3JlZAovLyBvbiBhIHBvc2l0aW9uLCBpbiB0b2tlbjAgdGhlbiB0b2tlbjEgb3JkZXIuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb3NpdGlvbklkOiBudW1lcmljIElEIHdob3NlIGZlZS1ncm93dGggY2hlY2twb2ludHMgYXJlIHJlcXVlc3RlZAovLwovLyBSZXR1cm5zOgovLyAgIC0gZmVlR3Jvd3RoSW5zaWRlMExhc3RYMTI4OiBkZWNpbWFsLWVuY29kZWQgUTEyOCB0b2tlbjAgZmVlIGdyb3d0aCBjaGVja3BvaW50Ci8vICAgLSBmZWVHcm93dGhJbnNpZGUxTGFzdFgxMjg6IGRlY2ltYWwtZW5jb2RlZCBRMTI4IHRva2VuMSBmZWUgZ3Jvd3RoIGNoZWNrcG9pbnQKLy8gICAtIGVycjogbmlsIG9uIGxvb2t1cCBzdWNjZXNzOyBlcnJQb3NpdGlvbkRvZXNOb3RFeGlzdCB3aGVuIHRoZSBwb3NpdGlvbiBpcyBhYnNlbnQKZnVuYyAocCAqcG9zaXRpb25WMSkgR2V0UG9zaXRpb25GZWVHcm93dGhJbnNpZGVMYXN0WDEyOChwb3NpdGlvbklkIHVpbnQ2NCkgKHN0cmluZywgc3RyaW5nLCBlcnJvcikgewoJcG9zaXRpb24sIGVyciA6PSBwLmdldFBvc2l0aW9uKHBvc2l0aW9uSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsICIiLCBlcnIKCX0KCglyZXR1cm4gcG9zaXRpb24uRmVlR3Jvd3RoSW5zaWRlMExhc3RYMTI4KCksIHBvc2l0aW9uLkZlZUdyb3d0aEluc2lkZTFMYXN0WDEyOCgpLCBuaWwKfQoKLy8gR2V0UG9zaXRpb25UaWNrcyByZXR1cm5zIGJvdGggdGljayBib3VuZGFyaWVzIHN0b3JlZCBvbiBhIHBvc2l0aW9uLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9zaXRpb25JZDogbnVtZXJpYyBJRCB3aG9zZSB0aWNrIGJvdW5kYXJpZXMgYXJlIHJlcXVlc3RlZAovLwovLyBSZXR1cm5zOgovLyAgIC0gdGlja0xvd2VyOiBsb3dlciB0aWNrIGJvdW5kYXJ5LCBpbmNsdXNpdmUgaW4gcmFuZ2UgY2hlY2tzCi8vICAgLSB0aWNrVXBwZXI6IHVwcGVyIHRpY2sgYm91bmRhcnksIGV4Y2x1c2l2ZSBpbiByYW5nZSBjaGVja3MKLy8gICAtIGVycjogbmlsIG9uIGxvb2t1cCBzdWNjZXNzOyBlcnJQb3NpdGlvbkRvZXNOb3RFeGlzdCB3aGVuIHRoZSBwb3NpdGlvbiBpcyBhYnNlbnQKZnVuYyAocCAqcG9zaXRpb25WMSkgR2V0UG9zaXRpb25UaWNrcyhwb3NpdGlvbklkIHVpbnQ2NCkgKGludDMyLCBpbnQzMiwgZXJyb3IpIHsKCXBvc2l0aW9uLCBlcnIgOj0gcC5nZXRQb3NpdGlvbihwb3NpdGlvbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIDAsIGVycgoJfQoKCXJldHVybiBwb3NpdGlvbi5UaWNrTG93ZXIoKSwgcG9zaXRpb24uVGlja1VwcGVyKCksIG5pbAp9CgovLyBHZXRQb3NpdGlvblRva2Vuc093ZWQwIHJldHVybnMgdGhlIHN0b3JlZCB0b2tlbjAgYW1vdW50IG93ZWQgdG8gYSBwb3NpdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvc2l0aW9uSWQ6IG51bWVyaWMgSUQgd2hvc2UgdG9rZW4wIG93ZWQgYW1vdW50IGlzIHJlcXVlc3RlZAovLwovLyBSZXR1cm5zOgovLyAgIC0gdG9rZW5zT3dlZDA6IGFjY3J1ZWQgdG9rZW4wIGFtb3VudCBhd2FpdGluZyBjb2xsZWN0aW9uLCBpbiB0b2tlbiB1bml0cwovLyAgIC0gZXJyOiBuaWwgb24gbG9va3VwIHN1Y2Nlc3M7IGVyclBvc2l0aW9uRG9lc05vdEV4aXN0IHdoZW4gdGhlIHBvc2l0aW9uIGlzIGFic2VudApmdW5jIChwICpwb3NpdGlvblYxKSBHZXRQb3NpdGlvblRva2Vuc093ZWQwKHBvc2l0aW9uSWQgdWludDY0KSAoaW50NjQsIGVycm9yKSB7Cglwb3NpdGlvbiwgZXJyIDo9IHAuZ2V0UG9zaXRpb24ocG9zaXRpb25JZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCglyZXR1cm4gcG9zaXRpb24uVG9rZW5zT3dlZDAoKSwgbmlsCn0KCi8vIEdldFBvc2l0aW9uVG9rZW5zT3dlZDEgcmV0dXJucyB0aGUgc3RvcmVkIHRva2VuMSBhbW91bnQgb3dlZCB0byBhIHBvc2l0aW9uLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9zaXRpb25JZDogbnVtZXJpYyBJRCB3aG9zZSB0b2tlbjEgb3dlZCBhbW91bnQgaXMgcmVxdWVzdGVkCi8vCi8vIFJldHVybnM6Ci8vICAgLSB0b2tlbnNPd2VkMTogYWNjcnVlZCB0b2tlbjEgYW1vdW50IGF3YWl0aW5nIGNvbGxlY3Rpb24sIGluIHRva2VuIHVuaXRzCi8vICAgLSBlcnI6IG5pbCBvbiBsb29rdXAgc3VjY2VzczsgZXJyUG9zaXRpb25Eb2VzTm90RXhpc3Qgd2hlbiB0aGUgcG9zaXRpb24gaXMgYWJzZW50CmZ1bmMgKHAgKnBvc2l0aW9uVjEpIEdldFBvc2l0aW9uVG9rZW5zT3dlZDEocG9zaXRpb25JZCB1aW50NjQpIChpbnQ2NCwgZXJyb3IpIHsKCXBvc2l0aW9uLCBlcnIgOj0gcC5nZXRQb3NpdGlvbihwb3NpdGlvbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoKCXJldHVybiBwb3NpdGlvbi5Ub2tlbnNPd2VkMSgpLCBuaWwKfQoKLy8gR2V0UG9zaXRpb25Ub2tlbnNPd2VkIHJldHVybnMgYm90aCBzdG9yZWQgdG9rZW4gYW1vdW50cyBvd2VkIHRvIGEgcG9zaXRpb24sCi8vIGluIHRva2VuMCB0aGVuIHRva2VuMSBvcmRlci4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvc2l0aW9uSWQ6IG51bWVyaWMgSUQgd2hvc2Ugb3dlZCBhbW91bnRzIGFyZSByZXF1ZXN0ZWQKLy8KLy8gUmV0dXJuczoKLy8gICAtIHRva2Vuc093ZWQwOiBhY2NydWVkIHRva2VuMCBhbW91bnQgYXdhaXRpbmcgY29sbGVjdGlvbiwgaW4gdG9rZW4gdW5pdHMKLy8gICAtIHRva2Vuc093ZWQxOiBhY2NydWVkIHRva2VuMSBhbW91bnQgYXdhaXRpbmcgY29sbGVjdGlvbiwgaW4gdG9rZW4gdW5pdHMKLy8gICAtIGVycjogbmlsIG9uIGxvb2t1cCBzdWNjZXNzOyBlcnJQb3NpdGlvbkRvZXNOb3RFeGlzdCB3aGVuIHRoZSBwb3NpdGlvbiBpcyBhYnNlbnQKZnVuYyAocCAqcG9zaXRpb25WMSkgR2V0UG9zaXRpb25Ub2tlbnNPd2VkKHBvc2l0aW9uSWQgdWludDY0KSAoaW50NjQsIGludDY0LCBlcnJvcikgewoJcG9zaXRpb24sIGVyciA6PSBwLmdldFBvc2l0aW9uKHBvc2l0aW9uSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgMCwgZXJyCgl9CgoJcmV0dXJuIHBvc2l0aW9uLlRva2Vuc093ZWQwKCksIHBvc2l0aW9uLlRva2Vuc093ZWQxKCksIG5pbAp9CgovLyBHZXRQb3NpdGlvbk93bmVyIHJldHVybnMgdGhlIGFkZHJlc3MgdGhhdCBvd25zIHRoZSBwb3NpdGlvbiBORlQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb3NpdGlvbklkOiBudW1lcmljIElEIHdob3NlIE5GVCBvd25lcnNoaXAgaXMgcmVxdWVzdGVkCi8vCi8vIFJldHVybnM6Ci8vICAgLSBvd25lcjogY3VycmVudCBvd25lciBhZGRyZXNzIHJlcG9ydGVkIGJ5IHRoZSBORlQgYWNjZXNzb3IKLy8gICAtIGVycjogbmlsIHdoZW4gdGhlIE5GVCBhY2Nlc3NvciBmaW5kcyB0aGUgdG9rZW47IG90aGVyd2lzZSBpdHMgb3duZXJzaGlwIGxvb2t1cCBlcnJvcgpmdW5jIChwICpwb3NpdGlvblYxKSBHZXRQb3NpdGlvbk93bmVyKHBvc2l0aW9uSWQgdWludDY0KSAoYWRkcmVzcywgZXJyb3IpIHsKCW93bmVyLCBlcnIgOj0gcC5uZnRBY2Nlc3Nvci5Pd25lck9mKHBvc2l0aW9uSWRGcm9tKHBvc2l0aW9uSWQpKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGFkZHJlc3MoIiIpLCBlcnIKCX0KCglyZXR1cm4gb3duZXIsIG5pbAp9CgovLyBHZXRVbmNsYWltZWRGZWUgY2FsY3VsYXRlcyB1bmNsYWltZWQgdG9rZW4gZmVlcyBmcm9tIGN1cnJlbnQgaW4tcmFuZ2UKLy8gZmVlIGdyb3d0aCwgdGhlIHBvc2l0aW9uJ3MgY2hlY2twb2ludHMsIGFuZCBpdHMgbGlxdWlkaXR5LgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9zaXRpb25JZDogbnVtZXJpYyBJRCB3aG9zZSB1bmNsYWltZWQgdG9rZW4gZmVlcyBhcmUgY2FsY3VsYXRlZAovLwovLyBSZXR1cm5zOgovLyAgIC0gdW5jbGFpbWVkRmVlMDogdG9rZW4wIGZlZXMgYWNjcnVlZCBzaW5jZSB0aGUgc3RvcmVkIGNoZWNrcG9pbnQsIHNjYWxlZCBieSBwb3NpdGlvbiBsaXF1aWRpdHkKLy8gICAtIHVuY2xhaW1lZEZlZTE6IHRva2VuMSBmZWVzIGFjY3J1ZWQgc2luY2UgdGhlIHN0b3JlZCBjaGVja3BvaW50LCBzY2FsZWQgYnkgcG9zaXRpb24gbGlxdWlkaXR5Ci8vICAgLSBlcnI6IG5pbCBvbiBzdWNjZXNzOyBuaWwgZmVlIHBvaW50ZXJzIGFuZCB0aGUgdW5kZXJseWluZyBsb29rdXAgZXJyb3Igd2hlbiBwb3NpdGlvbiBvciBwb29sIGRhdGEgaXMgdW5hdmFpbGFibGUKZnVuYyAocCAqcG9zaXRpb25WMSkgR2V0VW5jbGFpbWVkRmVlKHBvc2l0aW9uSWQgdWludDY0KSAoKnUyNTYuVWludCwgKnUyNTYuVWludCwgZXJyb3IpIHsKCS8vIHJlZjogaHR0cHM6Ly9ibG9nLnVuaXN3YXAub3JnL3VuaXN3YXAtdjMtbWF0aC1wcmltZXItMiNjYWxjdWxhdGluZy11bmNvbGxlY3RlZC1mZWVzCglwb3NpdGlvbiwgZXJyIDo9IHAuZ2V0UG9zaXRpb24ocG9zaXRpb25JZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBuaWwsIG5pbCwgZXJyCgl9CgoJbGlxdWlkaXR5IDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKHBvc2l0aW9uLkxpcXVpZGl0eSgpKQoJdGlja0xvd2VyIDo9IHBvc2l0aW9uLlRpY2tMb3dlcigpCgl0aWNrVXBwZXIgOj0gcG9zaXRpb24uVGlja1VwcGVyKCkKCglwb29sS2V5IDo9IHBvc2l0aW9uLlBvb2xLZXkoKQoKCWN1cnJlbnRUaWNrLCBlcnIgOj0gcGwuR2V0U2xvdDBUaWNrKHBvb2xLZXkpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBuaWwsIGVycgoJfQoKCWZlZUdyb3d0aEdsb2JhbDBYMTI4U3RyLCBmZWVHcm93dGhHbG9iYWwxWDEyOFN0ciwgZXJyIDo9IHBsLkdldEZlZUdyb3d0aEdsb2JhbFgxMjgocG9vbEtleSkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBuaWwsIG5pbCwgZXJyCgl9CglmZWVHcm93dGhHbG9iYWwwWDEyOCA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbChmZWVHcm93dGhHbG9iYWwwWDEyOFN0cikKCWZlZUdyb3d0aEdsb2JhbDFYMTI4IDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKGZlZUdyb3d0aEdsb2JhbDFYMTI4U3RyKQoKCXRpY2tVcHBlckZlZUdyb3d0aE91dHNpZGUwWDEyOFN0ciwgdGlja1VwcGVyRmVlR3Jvd3RoT3V0c2lkZTFYMTI4U3RyLCBlcnIgOj0gcGwuR2V0VGlja0ZlZUdyb3d0aE91dHNpZGVYMTI4KHBvb2xLZXksIHRpY2tVcHBlcikKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBuaWwsIG5pbCwgZXJyCgl9Cgl0aWNrVXBwZXJGZWVHcm93dGhPdXRzaWRlMFgxMjggOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwodGlja1VwcGVyRmVlR3Jvd3RoT3V0c2lkZTBYMTI4U3RyKQoJdGlja1VwcGVyRmVlR3Jvd3RoT3V0c2lkZTFYMTI4IDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKHRpY2tVcHBlckZlZUdyb3d0aE91dHNpZGUxWDEyOFN0cikKCgl0aWNrTG93ZXJGZWVHcm93dGhPdXRzaWRlMFgxMjhTdHIsIHRpY2tMb3dlckZlZUdyb3d0aE91dHNpZGUxWDEyOFN0ciwgZXJyIDo9IHBsLkdldFRpY2tGZWVHcm93dGhPdXRzaWRlWDEyOChwb29sS2V5LCB0aWNrTG93ZXIpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBuaWwsIGVycgoJfQoJdGlja0xvd2VyRmVlR3Jvd3RoT3V0c2lkZTBYMTI4IDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKHRpY2tMb3dlckZlZUdyb3d0aE91dHNpZGUwWDEyOFN0cikKCXRpY2tMb3dlckZlZUdyb3d0aE91dHNpZGUxWDEyOCA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbCh0aWNrTG93ZXJGZWVHcm93dGhPdXRzaWRlMVgxMjhTdHIpCgoJZmVlR3Jvd3RoSW5zaWRlMExhc3RYMTI4IDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKHBvc2l0aW9uLkZlZUdyb3d0aEluc2lkZTBMYXN0WDEyOCgpKQoJZmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4IDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKHBvc2l0aW9uLkZlZUdyb3d0aEluc2lkZTFMYXN0WDEyOCgpKQoKCXZhciB0aWNrTG93ZXJGZWVHcm93dGhCZWxvdzAsIHRpY2tMb3dlckZlZUdyb3d0aEJlbG93MSwgdGlja1VwcGVyRmVlR3Jvd3RoQWJvdmUwLCB0aWNrVXBwZXJGZWVHcm93dGhBYm92ZTEgKnUyNTYuVWludAoKCWlmIGN1cnJlbnRUaWNrID49IHRpY2tVcHBlciB7CgkJdGlja1VwcGVyRmVlR3Jvd3RoQWJvdmUwID0gdTI1Ni5aZXJvKCkuU3ViKGZlZUdyb3d0aEdsb2JhbDBYMTI4LCB0aWNrVXBwZXJGZWVHcm93dGhPdXRzaWRlMFgxMjgpCgkJdGlja1VwcGVyRmVlR3Jvd3RoQWJvdmUxID0gdTI1Ni5aZXJvKCkuU3ViKGZlZUdyb3d0aEdsb2JhbDFYMTI4LCB0aWNrVXBwZXJGZWVHcm93dGhPdXRzaWRlMVgxMjgpCgl9IGVsc2UgewoJCXRpY2tVcHBlckZlZUdyb3d0aEFib3ZlMCA9IHRpY2tVcHBlckZlZUdyb3d0aE91dHNpZGUwWDEyOAoJCXRpY2tVcHBlckZlZUdyb3d0aEFib3ZlMSA9IHRpY2tVcHBlckZlZUdyb3d0aE91dHNpZGUxWDEyOAoJfQoKCWlmIGN1cnJlbnRUaWNrID49IHRpY2tMb3dlciB7CgkJdGlja0xvd2VyRmVlR3Jvd3RoQmVsb3cwID0gdGlja0xvd2VyRmVlR3Jvd3RoT3V0c2lkZTBYMTI4CgkJdGlja0xvd2VyRmVlR3Jvd3RoQmVsb3cxID0gdGlja0xvd2VyRmVlR3Jvd3RoT3V0c2lkZTFYMTI4Cgl9IGVsc2UgewoJCXRpY2tMb3dlckZlZUdyb3d0aEJlbG93MCA9IHUyNTYuWmVybygpLlN1YihmZWVHcm93dGhHbG9iYWwwWDEyOCwgdGlja0xvd2VyRmVlR3Jvd3RoT3V0c2lkZTBYMTI4KQoJCXRpY2tMb3dlckZlZUdyb3d0aEJlbG93MSA9IHUyNTYuWmVybygpLlN1YihmZWVHcm93dGhHbG9iYWwxWDEyOCwgdGlja0xvd2VyRmVlR3Jvd3RoT3V0c2lkZTFYMTI4KQoJfQoKCWZlZUdyb3d0aEluc2lkZTBYMTI4IDo9IHUyNTYuWmVybygpLlN1YihmZWVHcm93dGhHbG9iYWwwWDEyOCwgdGlja0xvd2VyRmVlR3Jvd3RoQmVsb3cwKQoJZmVlR3Jvd3RoSW5zaWRlMFgxMjggPSB1MjU2Llplcm8oKS5TdWIoZmVlR3Jvd3RoSW5zaWRlMFgxMjgsIHRpY2tVcHBlckZlZUdyb3d0aEFib3ZlMCkKCglmZWVHcm93dGhJbnNpZGUxWDEyOCA6PSB1MjU2Llplcm8oKS5TdWIoZmVlR3Jvd3RoR2xvYmFsMVgxMjgsIHRpY2tMb3dlckZlZUdyb3d0aEJlbG93MSkKCWZlZUdyb3d0aEluc2lkZTFYMTI4ID0gdTI1Ni5aZXJvKCkuU3ViKGZlZUdyb3d0aEluc2lkZTFYMTI4LCB0aWNrVXBwZXJGZWVHcm93dGhBYm92ZTEpCgoJZGlmZkdyb3d0aEluc2lkZTBYMTI4IDo9IHUyNTYuWmVybygpLlN1YihmZWVHcm93dGhJbnNpZGUwWDEyOCwgZmVlR3Jvd3RoSW5zaWRlMExhc3RYMTI4KQoJdW5jbGFpbWVkRmVlMCA6PSB1MjU2Lk11bERpdihkaWZmR3Jvd3RoSW5zaWRlMFgxMjgsIGxpcXVpZGl0eSwgY29uc3RzLlExMjgoKSkKCglkaWZmR3Jvd3RoSW5zaWRlMVgxMjggOj0gdTI1Ni5aZXJvKCkuU3ViKGZlZUdyb3d0aEluc2lkZTFYMTI4LCBmZWVHcm93dGhJbnNpZGUxTGFzdFgxMjgpCgl1bmNsYWltZWRGZWUxIDo9IHUyNTYuTXVsRGl2KGRpZmZHcm93dGhJbnNpZGUxWDEyOCwgbGlxdWlkaXR5LCBjb25zdHMuUTEyOCgpKQoJcmV0dXJuIHVuY2xhaW1lZEZlZTAsIHVuY2xhaW1lZEZlZTEsIG5pbAp9ChpFCgtnbm9tb2QudG9tbBI2bW9kdWxlID0gImduby5sYW5kL3IvZ25vc3dhcC9wb3NpdGlvbi92MSIKZ25vID0gIjAuOSIKGpoHCghpbml0LmdubxKNB3BhY2thZ2UgcG9zaXRpb24KCmltcG9ydCAoCgkiZ25vLmxhbmQvci9nbm9zd2FwL2FjY2Vzcy92MSIKCSJnbm8ubGFuZC9yL2dub3N3YXAvcG9zaXRpb24iCikKCmZ1bmMgaW5pdChjdXIgcmVhbG0pIHsKCXJlZ2lzdGVyUG9zaXRpb25WMShjdXIpCn0KCmZ1bmMgcmVnaXN0ZXJQb3NpdGlvblYxKGN1ciByZWFsbSkgewoJcG9zaXRpb24uUmVnaXN0ZXJJbml0aWFsaXplcigKCQljcm9zcyhjdXIpLAoJCWZ1bmMoXyBpbnQsIHJsbSByZWFsbSwgcG9zaXRpb25TdG9yZSBwb3NpdGlvbi5JUG9zaXRpb25TdG9yZSkgcG9zaXRpb24uSVBvc2l0aW9uIHsKCQkJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJCQllcnIgOj0gaW5pdFN0b3JlRGF0YSgwLCBybG0sIHBvc2l0aW9uU3RvcmUpCgkJCWlmIGVyciAhPSBuaWwgewoJCQkJcGFuaWMoZXJyKQoJCQl9CgoJCQlyZXR1cm4gTmV3UG9zaXRpb25WMShwb3NpdGlvblN0b3JlLCBuZXdHTkZUQWNjZXNzb3IoKSkKCQl9LAoJKQp9CgpmdW5jIGluaXRTdG9yZURhdGEoXyBpbnQsIHJsbSByZWFsbSwgcG9zaXRpb25TdG9yZSBwb3NpdGlvbi5JUG9zaXRpb25TdG9yZSkgZXJyb3IgewoJaWYgIXBvc2l0aW9uU3RvcmUuSGFzUG9zaXRpb25OZXh0SURTdG9yZUtleSgpIHsKCQllcnIgOj0gcG9zaXRpb25TdG9yZS5TZXRQb3NpdGlvbk5leHRJRCgwLCBybG0sIHVpbnQ2NCgxKSkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCX0KCglpZiAhcG9zaXRpb25TdG9yZS5IYXNQb3NpdGlvbnNTdG9yZUtleSgpIHsKCQllcnIgOj0gcG9zaXRpb25TdG9yZS5TZXRQb3NpdGlvbnMoMCwgcmxtLCBwb3NpdGlvbi5OZXdQb3NpdGlvbnNUcmVlKCkpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJcmV0dXJuIG5pbAp9ChryLQoMaW5zdGFuY2UuZ25vEuEtcGFja2FnZSBwb3NpdGlvbgoKaW1wb3J0ICgKCSJlcnJvcnMiCgoJImduby5sYW5kL3AvbnQvZ3JjNzIxL3YwIgoJImduby5sYW5kL3IvZ25vc3dhcC9hY2Nlc3MvdjEiCgkiZ25vLmxhbmQvci9nbm9zd2FwL2duZnQiCgkiZ25vLmxhbmQvci9nbm9zd2FwL3Bvc2l0aW9uIgopCgp0eXBlIHBvc2l0aW9uVjEgc3RydWN0IHsKCXN0b3JlICAgICAgIHBvc2l0aW9uLklQb3NpdGlvblN0b3JlCgluZnRBY2Nlc3NvciBORlRBY2Nlc3Nvcgp9CgovLyBOZXdQb3NpdGlvblYxIGNvbnN0cnVjdHMgYSBwb3NpdGlvbiBpbXBsZW1lbnRhdGlvbiBiYWNrZWQgYnkgdGhlIHN1cHBsaWVkCi8vIHBvc2l0aW9uIHN0b3JlIGFuZCBORlQgYWNjZXNzb3IuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb3NpdGlvblN0b3JlOiBzdG9yYWdlIGludGVyZmFjZSB1c2VkIHRvIHJlYWQgYW5kIHVwZGF0ZSBwb3NpdGlvbiByZWNvcmRzCi8vICAgLSBhY2Nlc3NvcjogTkZUIGludGVyZmFjZSB1c2VkIGZvciBwb3NpdGlvbiB0b2tlbiBtaW50aW5nLCBidXJuaW5nLCBhcHByb3ZhbCwgYW5kIG93bmVyc2hpcAovLwovLyBSZXR1cm5zOgovLyAgIC0gcG9zaXRpb246IElQb3NpdGlvbiBpbXBsZW1lbnRhdGlvbiBjb25uZWN0ZWQgdG8gcG9zaXRpb25TdG9yZSBhbmQgYWNjZXNzb3IKZnVuYyBOZXdQb3NpdGlvblYxKHBvc2l0aW9uU3RvcmUgcG9zaXRpb24uSVBvc2l0aW9uU3RvcmUsIGFjY2Vzc29yIE5GVEFjY2Vzc29yKSBwb3NpdGlvbi5JUG9zaXRpb24gewoJcmV0dXJuICZwb3NpdGlvblYxewoJCXN0b3JlOiAgICAgICBwb3NpdGlvblN0b3JlLAoJCW5mdEFjY2Vzc29yOiBhY2Nlc3NvciwKCX0KfQoKdHlwZSBORlRBY2Nlc3NvciBpbnRlcmZhY2UgewoJLy8gQXBwcm92ZSBmb3J3YXJkcyBhbiBvcGVyYXRvciBhcHByb3ZhbCBmb3IgYSBwb3NpdGlvbiBORlQuCgkvLwoJLy8gUGFyYW1ldGVyczoKCS8vICAgLSBfOiBsZWFkaW5nIHJlYWxtLWNhbGwgZGlzY3JpbWluYXRvciBmb3IgdGhlIGZvcndhcmRlZCBORlQgb3BlcmF0aW9uOyBjYWxsZXJzIHBhc3MgMAoJLy8gICAtIHJsbTogcHJvcGFnYXRlZCByZWFsbSBjb250ZXh0IHZhbGlkYXRlZCBieSB0aGUgY29uY3JldGUgYWNjZXNzb3IgYmVmb3JlIGNyb3NzaW5nIGludG8gdGhlIE5GVCByZWFsbQoJLy8gICAtIGFwcHJvdmVkOiBhZGRyZXNzIHRvIGFwcHJvdmUgZm9yIHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gTkZUOyB0aGUgZW1wdHkgYWRkcmVzcyByZXZva2VzIGFwcHJvdmFsCgkvLyAgIC0gdGlkOiBwb3NpdGlvbiBORlQgdG9rZW4gSUQgd2hvc2Ugb3BlcmF0b3IgYXBwcm92YWwgaXMgY2hhbmdlZAoJLy8KCS8vIFJldHVybnM6CgkvLyAgIC0gZXJyOiBuaWwgd2hlbiBhcHByb3ZhbCBzdWNjZWVkczsgb3RoZXJ3aXNlIHRoZSBORlQgYWNjZXNzb3Igb3IgcmVhbG0tdmFsaWRhdGlvbiBlcnJvcgoJQXBwcm92ZShfIGludCwgcmxtIHJlYWxtLCBhcHByb3ZlZCBhZGRyZXNzLCB0aWQgZ3JjNzIxLlRva2VuSUQpIGVycm9yCgkvLyBNaW50IGNyZWF0ZXMgYSBwb3NpdGlvbiBORlQgZm9yIGFuIGFkZHJlc3MgYW5kIHRva2VuIElELgoJLy8KCS8vIFBhcmFtZXRlcnM6CgkvLyAgIC0gXzogbGVhZGluZyByZWFsbS1jYWxsIGRpc2NyaW1pbmF0b3IgZm9yIHRoZSBmb3J3YXJkZWQgTkZUIG9wZXJhdGlvbjsgY2FsbGVycyBwYXNzIDAKCS8vICAgLSBybG06IHByb3BhZ2F0ZWQgcmVhbG0gY29udGV4dCB1c2VkIHRvIGNyb3NzIGludG8gdGhlIE5GVCByZWFsbQoJLy8gICAtIHRvOiBhZGRyZXNzIHRoYXQgcmVjZWl2ZXMgdGhlIG5ld2x5IG1pbnRlZCBwb3NpdGlvbiBORlQKCS8vICAgLSB0aWQ6IHJlcXVlc3RlZCBwb3NpdGlvbiBORlQgdG9rZW4gSUQKCS8vCgkvLyBSZXR1cm5zOgoJLy8gICAtIG1pbnRlZFRpZDogdG9rZW4gSUQgcmV0dXJuZWQgYnkgdGhlIE5GVCByZWFsbSBhZnRlciBtaW50aW5nCglNaW50KF8gaW50LCBybG0gcmVhbG0sIHRvIGFkZHJlc3MsIHRpZCBncmM3MjEuVG9rZW5JRCkgZ3JjNzIxLlRva2VuSUQKCS8vIEJ1cm4gcmVtb3ZlcyBhIHBvc2l0aW9uIE5GVCBmcm9tIHRoZSBORlQgbGVkZ2VyLgoJLy8KCS8vIFBhcmFtZXRlcnM6CgkvLyAgIC0gXzogbGVhZGluZyByZWFsbS1jYWxsIGRpc2NyaW1pbmF0b3IgZm9yIHRoZSBmb3J3YXJkZWQgTkZUIG9wZXJhdGlvbjsgY2FsbGVycyBwYXNzIDAKCS8vICAgLSBybG06IHByb3BhZ2F0ZWQgcmVhbG0gY29udGV4dCB1c2VkIHRvIGNyb3NzIGludG8gdGhlIE5GVCByZWFsbQoJLy8gICAtIHRpZDogcG9zaXRpb24gTkZUIHRva2VuIElEIHRvIGJ1cm4KCUJ1cm4oXyBpbnQsIHJsbSByZWFsbSwgdGlkIGdyYzcyMS5Ub2tlbklEKQoJLy8gVG90YWxTdXBwbHkgcmV0dXJucyB0aGUgbnVtYmVyIG9mIE5GVHMgY3VycmVudGx5IHJlY29yZGVkIGJ5IHRoZSBsZWRnZXIuCgkvLwoJLy8gUmV0dXJuczoKCS8vICAgLSB0b3RhbFN1cHBseTogY3VycmVudCBudW1iZXIgb2YgcG9zaXRpb24gTkZUcyBpbiB0aGUgbGVkZ2VyCglUb3RhbFN1cHBseSgpIGludDY0CgkvLyBFeGlzdHMgcmVwb3J0cyB3aGV0aGVyIHRoZSBORlQgbGVkZ2VyIGNvbnRhaW5zIGEgdG9rZW4gSUQuCgkvLwoJLy8gUGFyYW1ldGVyczoKCS8vICAgLSB0aWQ6IHBvc2l0aW9uIE5GVCB0b2tlbiBJRCB0byB0ZXN0CgkvLwoJLy8gUmV0dXJuczoKCS8vICAgLSBleGlzdHM6IHRydWUgd2hlbiB0aGUgTkZUIGxlZGdlciBjb250YWlucyB0aWQKCUV4aXN0cyh0aWQgZ3JjNzIxLlRva2VuSUQpIGJvb2wKCS8vIE93bmVyT2YgcmV0dXJucyB0aGUgY3VycmVudCBvd25lciBvZiBhIHBvc2l0aW9uIE5GVC4KCS8vCgkvLyBQYXJhbWV0ZXJzOgoJLy8gICAtIHRpZDogcG9zaXRpb24gTkZUIHRva2VuIElEIHdob3NlIG93bmVyIGlzIHJlcXVlc3RlZAoJLy8KCS8vIFJldHVybnM6CgkvLyAgIC0gb3duZXI6IGFkZHJlc3MgcmVjb3JkZWQgYXMgdGhlIHRva2VuIG93bmVyCgkvLyAgIC0gZXJyOiBuaWwgd2hlbiB0aGUgdG9rZW4gZXhpc3RzOyBvdGhlcndpc2UgdGhlIE5GVCBsZWRnZXIncyBvd25lcnNoaXAgbG9va3VwIGVycm9yCglPd25lck9mKHRpZCBncmM3MjEuVG9rZW5JRCkgKGFkZHJlc3MsIGVycm9yKQp9Cgp0eXBlIGduZnRBY2Nlc3NvciBzdHJ1Y3R7fQoKLy8gQXBwcm92ZSBmb3J3YXJkcyBhbiBvcGVyYXRvciBhcHByb3ZhbCB0byB0aGUgR05GVCByZWFsbS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IGxlYWRpbmcgcmVhbG0tY2FsbCBkaXNjcmltaW5hdG9yIGZvciB0aGUgZm9yd2FyZGVkIE5GVCBvcGVyYXRpb247IGNhbGxlcnMgcGFzcyAwCi8vICAgLSBybG06IHByb3BhZ2F0ZWQgcmVhbG0gY29udGV4dCB0aGF0IG11c3QgYmUgY3VycmVudCBiZWZvcmUgY3Jvc3NpbmcgaW50byBHTkZUCi8vICAgLSBhcHByb3ZlZDogYWRkcmVzcyB0byBhcHByb3ZlIGZvciB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uIE5GVDsgdGhlIGVtcHR5IGFkZHJlc3MgcmV2b2tlcyBhcHByb3ZhbAovLyAgIC0gdGlkOiBwb3NpdGlvbiBORlQgdG9rZW4gSUQgd2hvc2Ugb3BlcmF0b3IgYXBwcm92YWwgaXMgY2hhbmdlZAovLwovLyBSZXR1cm5zOgovLyAgIC0gZXJyOiBuaWwgd2hlbiBHTkZUIGFjY2VwdHMgdGhlIGFwcHJvdmFsOyBlcnJTcG9vZmVkUmVhbG0gd2hlbiBybG0gaXMgbm90IGN1cnJlbnQsIG90aGVyd2lzZSB0aGUgdW5kZXJseWluZyBHTkZUIGVycm9yCmZ1bmMgKG4gKmduZnRBY2Nlc3NvcikgQXBwcm92ZShfIGludCwgcmxtIHJlYWxtLCBhcHByb3ZlZCBhZGRyZXNzLCB0aWQgZ3JjNzIxLlRva2VuSUQpIGVycm9yIHsKCWlmICFybG0uSXNDdXJyZW50KCkgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyclNwb29mZWRSZWFsbSkKCX0KCglyZXR1cm4gZ25mdC5BcHByb3ZlKGNyb3NzKHJsbSksIGFwcHJvdmVkLCB0aWQpCn0KCi8vIE1pbnQgZm9yd2FyZHMgcG9zaXRpb24gTkZUIGNyZWF0aW9uIHRvIHRoZSBHTkZUIHJlYWxtLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogbGVhZGluZyByZWFsbS1jYWxsIGRpc2NyaW1pbmF0b3IgZm9yIHRoZSBmb3J3YXJkZWQgTkZUIG9wZXJhdGlvbjsgY2FsbGVycyBwYXNzIDAKLy8gICAtIHJsbTogcHJvcGFnYXRlZCByZWFsbSBjb250ZXh0IGFzc2VydGVkIGN1cnJlbnQgYmVmb3JlIGNyb3NzaW5nIGludG8gR05GVAovLyAgIC0gdG86IGFkZHJlc3MgdGhhdCByZWNlaXZlcyB0aGUgbmV3bHkgbWludGVkIHBvc2l0aW9uIE5GVAovLyAgIC0gdGlkOiByZXF1ZXN0ZWQgcG9zaXRpb24gTkZUIHRva2VuIElECi8vCi8vIFJldHVybnM6Ci8vICAgLSBtaW50ZWRUaWQ6IHRva2VuIElEIHJldHVybmVkIGJ5IEdORlQgYWZ0ZXIgbWludGluZwpmdW5jIChuICpnbmZ0QWNjZXNzb3IpIE1pbnQoXyBpbnQsIHJsbSByZWFsbSwgdG8gYWRkcmVzcywgdGlkIGdyYzcyMS5Ub2tlbklEKSBncmM3MjEuVG9rZW5JRCB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCglyZXR1cm4gZ25mdC5NaW50KGNyb3NzKHJsbSksIHRvLCB0aWQpCn0KCi8vIEJ1cm4gZm9yd2FyZHMgcG9zaXRpb24gTkZUIGRlc3RydWN0aW9uIHRvIHRoZSBHTkZUIHJlYWxtLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogbGVhZGluZyByZWFsbS1jYWxsIGRpc2NyaW1pbmF0b3IgZm9yIHRoZSBmb3J3YXJkZWQgTkZUIG9wZXJhdGlvbjsgY2FsbGVycyBwYXNzIDAKLy8gICAtIHJsbTogcHJvcGFnYXRlZCByZWFsbSBjb250ZXh0IGFzc2VydGVkIGN1cnJlbnQgYmVmb3JlIGNyb3NzaW5nIGludG8gR05GVAovLyAgIC0gdGlkOiBwb3NpdGlvbiBORlQgdG9rZW4gSUQgdG8gYnVybgpmdW5jIChuICpnbmZ0QWNjZXNzb3IpIEJ1cm4oXyBpbnQsIHJsbSByZWFsbSwgdGlkIGdyYzcyMS5Ub2tlbklEKSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCglnbmZ0LkJ1cm4oY3Jvc3MocmxtKSwgdGlkKQp9CgovLyBUb3RhbFN1cHBseSByZXR1cm5zIHRoZSBHTkZUIGxlZGdlcidzIGN1cnJlbnQgdG9rZW4gY291bnQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSB0b3RhbFN1cHBseTogbnVtYmVyIG9mIE5GVHMgY3VycmVudGx5IHJlY29yZGVkIGJ5IEdORlQKZnVuYyAobiAqZ25mdEFjY2Vzc29yKSBUb3RhbFN1cHBseSgpIGludDY0IHsKCXJldHVybiBnbmZ0LlRvdGFsU3VwcGx5KCkKfQoKLy8gRXhpc3RzIHJlcG9ydHMgd2hldGhlciBHTkZUIGNvbnRhaW5zIGEgcG9zaXRpb24gTkZUIHRva2VuIElELgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gdGlkOiBwb3NpdGlvbiBORlQgdG9rZW4gSUQgdG8gdGVzdAovLwovLyBSZXR1cm5zOgovLyAgIC0gZXhpc3RzOiB0cnVlIHdoZW4gR05GVCBjb250YWlucyB0aWQKZnVuYyAobiAqZ25mdEFjY2Vzc29yKSBFeGlzdHModGlkIGdyYzcyMS5Ub2tlbklEKSBib29sIHsKCXJldHVybiBnbmZ0LkV4aXN0cyh0aWQpCn0KCi8vIE93bmVyT2YgcmV0dXJucyB0aGUgb3duZXIgcmVjb3JkZWQgYnkgR05GVCBmb3IgYSBwb3NpdGlvbiBORlQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB0aWQ6IHBvc2l0aW9uIE5GVCB0b2tlbiBJRCB3aG9zZSBvd25lciBpcyByZXF1ZXN0ZWQKLy8KLy8gUmV0dXJuczoKLy8gICAtIG93bmVyOiBhZGRyZXNzIHJlY29yZGVkIGFzIHRoZSB0b2tlbiBvd25lcgovLyAgIC0gZXJyOiBuaWwgd2hlbiBHTkZUIGZpbmRzIHRoZSB0b2tlbjsgb3RoZXJ3aXNlIEdORlQncyBvd25lcnNoaXAgbG9va3VwIGVycm9yCmZ1bmMgKG4gKmduZnRBY2Nlc3NvcikgT3duZXJPZih0aWQgZ3JjNzIxLlRva2VuSUQpIChhZGRyZXNzLCBlcnJvcikgewoJcmV0dXJuIGduZnQuT3duZXJPZih0aWQpCn0KCmZ1bmMgbmV3R05GVEFjY2Vzc29yKCkgTkZUQWNjZXNzb3IgewoJcmV0dXJuICZnbmZ0QWNjZXNzb3J7fQp9ChroEAoYbGlxdWlkaXR5X21hbmFnZW1lbnQuZ25vEssQcGFja2FnZSBwb3NpdGlvbgoKaW1wb3J0ICgKCSJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCXUyNTYgImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoJcGwgImduby5sYW5kL3IvZ25vc3dhcC9wb29sIgopCgp0eXBlIEFkZExpcXVpZGl0eVBhcmFtcyBzdHJ1Y3QgewoJcG9vbEtleSAgICAgICAgc3RyaW5nICAgICAvLyBwb29sUGF0aCBvZiB0aGUgcG9vbCB3aGljaCBoYXMgdGhlIHBvc2l0aW9uCgl0aWNrTG93ZXIgICAgICBpbnQzMiAgICAgIC8vIGxvd2VyIGVuZCBvZiB0aGUgdGljayByYW5nZSBmb3IgdGhlIHBvc2l0aW9uCgl0aWNrVXBwZXIgICAgICBpbnQzMiAgICAgIC8vIHVwcGVyIGVuZCBvZiB0aGUgdGljayByYW5nZSBmb3IgdGhlIHBvc2l0aW9uCglhbW91bnQwRGVzaXJlZCAqdTI1Ni5VaW50IC8vIGRlc2lyZWQgYW1vdW50IG9mIHRva2VuMCB0byBiZSBtaW50ZWQKCWFtb3VudDFEZXNpcmVkICp1MjU2LlVpbnQgLy8gZGVzaXJlZCBhbW91bnQgb2YgdG9rZW4xIHRvIGJlIG1pbnRlZAoJYW1vdW50ME1pbiAgICAgKnUyNTYuVWludCAvLyBtaW5pbXVtIGFtb3VudCBvZiB0b2tlbjAgdG8gYmUgbWludGVkCglhbW91bnQxTWluICAgICAqdTI1Ni5VaW50IC8vIG1pbmltdW0gYW1vdW50IG9mIHRva2VuMSB0byBiZSBtaW50ZWQKCWNhbGxlciAgICAgICAgIGFkZHJlc3MgICAgLy8gYWRkcmVzcyB0byBjYWxsIHRoZSBmdW5jdGlvbgp9CgovLyBhZGRMaXF1aWRpdHkgY2FsY3VsYXRlcyBsaXF1aWRpdHkgYW1vdW50cyBhbmQgbWludHMgcG9zaXRpb24gdG9rZW5zIHRvIGEgcG9vbC4KZnVuYyAocCAqcG9zaXRpb25WMSkgYWRkTGlxdWlkaXR5KF8gaW50LCBybG0gcmVhbG0sIHBhcmFtcyBBZGRMaXF1aWRpdHlQYXJhbXMpICgqdTI1Ni5VaW50LCAqdTI1Ni5VaW50LCAqdTI1Ni5VaW50KSB7CglzcXJ0UHJpY2VYOTZTdHJpbmcsIGVyciA6PSBwbC5HZXRTbG90MFNxcnRQcmljZVg5NihwYXJhbXMucG9vbEtleSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCXNxcnRQcmljZVg5NiA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbChzcXJ0UHJpY2VYOTZTdHJpbmcpCglzcXJ0UmF0aW9BWDk2IDo9IGduc21hdGguVGlja01hdGhHZXRTcXJ0UmF0aW9BdFRpY2socGFyYW1zLnRpY2tMb3dlcikKCXNxcnRSYXRpb0JYOTYgOj0gZ25zbWF0aC5UaWNrTWF0aEdldFNxcnRSYXRpb0F0VGljayhwYXJhbXMudGlja1VwcGVyKQoKCWxpcXVpZGl0eSA6PSBnbnNtYXRoLkdldExpcXVpZGl0eUZvckFtb3VudHMoCgkJc3FydFByaWNlWDk2LAoJCXNxcnRSYXRpb0FYOTYsCgkJc3FydFJhdGlvQlg5NiwKCQlwYXJhbXMuYW1vdW50MERlc2lyZWQsCgkJcGFyYW1zLmFtb3VudDFEZXNpcmVkLAoJKQoKCXRva2VuMCwgdG9rZW4xLCBmZWUgOj0gc3BsaXRPZihwYXJhbXMucG9vbEtleSkKCWFtb3VudDBTdHIsIGFtb3VudDFTdHIgOj0gcGwuTWludCgKCQljcm9zcyhybG0pLAoJCXRva2VuMCwKCQl0b2tlbjEsCgkJZmVlLAoJCXBhcmFtcy50aWNrTG93ZXIsCgkJcGFyYW1zLnRpY2tVcHBlciwKCQlsaXF1aWRpdHkuVG9TdHJpbmcoKSwKCQlwYXJhbXMuY2FsbGVyLAoJKQoKCWFtb3VudDAgOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwoYW1vdW50MFN0cikKCWFtb3VudDEgOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwoYW1vdW50MVN0cikKCglhbW91bnQwQ29uZCA6PSBhbW91bnQwLkd0ZShwYXJhbXMuYW1vdW50ME1pbikKCWFtb3VudDFDb25kIDo9IGFtb3VudDEuR3RlKHBhcmFtcy5hbW91bnQxTWluKQoKCWlmICEoYW1vdW50MENvbmQgJiYgYW1vdW50MUNvbmQpIHsKCQlwYW5pYyhuZXdFcnJvcldpdGhEZXRhaWwoCgkJCWVyclNsaXBwYWdlLAoJCQl1Zm10LlNwcmludGYoCgkJCQkiUHJpY2UgU2xpcHBhZ2UgQ2hlY2soYW1vdW50MCglcykgPj0gYW1vdW50ME1pbiglcyksIGFtb3VudDEoJXMpID49IGFtb3VudDFNaW4oJXMpKSIsCgkJCQlhbW91bnQwU3RyLCBwYXJhbXMuYW1vdW50ME1pbi5Ub1N0cmluZygpLCBhbW91bnQxU3RyLCBwYXJhbXMuYW1vdW50MU1pbi5Ub1N0cmluZygpKSwKCQkpKQoJfQoKCXJldHVybiBsaXF1aWRpdHksIGFtb3VudDAsIGFtb3VudDEKfQoanQcKC21hbmFnZXIuZ25vEo0HcGFja2FnZSBwb3NpdGlvbgoKaW1wb3J0ICgKCSJnbm8ubGFuZC9yL2dub3N3YXAvcG9zaXRpb24iCikKCi8vIEdldE5leHRJZCBpcyB0aGUgbmV4dCBwb3NpdGlvbiBJRCB0byBiZSBtaW50ZWQKZnVuYyAocCAqcG9zaXRpb25WMSkgZ2V0TmV4dElkKCkgdWludDY0IHsKCXJldHVybiBwLnN0b3JlLkdldFBvc2l0aW9uTmV4dElEKCkKfQoKLy8gaW5jcmVtZW50TmV4dElkIGluY3JlbWVudHMgdGhlIG5leHQgcG9zaXRpb24gSUQgdG8gYmUgbWludGVkCmZ1bmMgKHAgKnBvc2l0aW9uVjEpIGluY3JlbWVudE5leHRJZChfIGludCwgcmxtIHJlYWxtKSBlcnJvciB7CglyZXR1cm4gcC5zdG9yZS5TZXRQb3NpdGlvbk5leHRJRCgwLCBybG0sIHAuZ2V0TmV4dElkKCkrMSkKfQoKLy8gc2V0UG9zaXRpb24gc2V0cyBhIHBvc2l0aW9uIGZvciBhIGdpdmVuIHBvc2l0aW9uIElELgovLyBSZXR1cm5zIGZhbHNlIGlmIHBvc2l0aW9uIGlzIG5ld2x5IGNyZWF0ZWQsIHRydWUgaWYgcG9zaXRpb24gYWxyZWFkeSBleGlzdGVkIGFuZCB3YXMgdXBkYXRlZC4KZnVuYyAocCAqcG9zaXRpb25WMSkgc2V0UG9zaXRpb24oXyBpbnQsIHJsbSByZWFsbSwgaWQgdWludDY0LCBwb3MgcG9zaXRpb24uUG9zaXRpb24pIGVycm9yIHsKCXJldHVybiBwLnN0b3JlLlNldFBvc2l0aW9uKDAsIHJsbSwgaWQsIHBvcykKfQoKLy8gbXVzdFVwZGF0ZVBvc2l0aW9uIHVwZGF0ZXMgYSBwb3NpdGlvbiBmb3IgYSBnaXZlbiBwb3NpdGlvbiBJRC4KZnVuYyAocCAqcG9zaXRpb25WMSkgbXVzdFVwZGF0ZVBvc2l0aW9uKF8gaW50LCBybG0gcmVhbG0sIGlkIHVpbnQ2NCwgcG9zIHBvc2l0aW9uLlBvc2l0aW9uKSB7CgllcnIgOj0gcC5zZXRQb3NpdGlvbigwLCBybG0sIGlkLCBwb3MpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9Cn0KGq4wCghtaW50LmdubxKhMHBhY2thZ2UgcG9zaXRpb24KCmltcG9ydCAoCgkiZXJyb3JzIgoKCXUyNTYgImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoKCSJnbm8ubGFuZC9yL2dub3N3YXAvY29tbW9uIgoJcGwgImduby5sYW5kL3IvZ25vc3dhcC9wb29sIgoJImduby5sYW5kL3IvZ25vc3dhcC9wb3NpdGlvbiIKKQoKLy8gbWludCBjcmVhdGVzIGEgbmV3IGxpcXVpZGl0eSBwb3NpdGlvbiBieSBhZGRpbmcgbGlxdWlkaXR5IHRvIGEgcG9vbCBhbmQgbWludGluZyBhbiBORlQuCi8vIFBhbmljcyBpZiBwb3NpdGlvbiBJRCBhbHJlYWR5IGV4aXN0cyBvciBhZGRpbmcgbGlxdWlkaXR5IGZhaWxzLgpmdW5jIChwICpwb3NpdGlvblYxKSBtaW50KF8gaW50LCBybG0gcmVhbG0sIHBhcmFtcyBNaW50UGFyYW1zKSAodWludDY0LCAqdTI1Ni5VaW50LCAqdTI1Ni5VaW50LCAqdTI1Ni5VaW50KSB7Cglwb29sS2V5IDo9IHBsLkdldFBvb2xQYXRoKHBhcmFtcy50b2tlbjAsIHBhcmFtcy50b2tlbjEsIHBhcmFtcy5mZWUpCglsaXF1aWRpdHksIGFtb3VudDAsIGFtb3VudDEgOj0gcC5hZGRMaXF1aWRpdHkoCgkJMCwKCQlybG0sCgkJQWRkTGlxdWlkaXR5UGFyYW1zewoJCQlwb29sS2V5OiAgICAgICAgcG9vbEtleSwKCQkJdGlja0xvd2VyOiAgICAgIHBhcmFtcy50aWNrTG93ZXIsCgkJCXRpY2tVcHBlcjogICAgICBwYXJhbXMudGlja1VwcGVyLAoJCQlhbW91bnQwRGVzaXJlZDogcGFyYW1zLmFtb3VudDBEZXNpcmVkLAoJCQlhbW91bnQxRGVzaXJlZDogcGFyYW1zLmFtb3VudDFEZXNpcmVkLAoJCQlhbW91bnQwTWluOiAgICAgcGFyYW1zLmFtb3VudDBNaW4sCgkJCWFtb3VudDFNaW46ICAgICBwYXJhbXMuYW1vdW50MU1pbiwKCQkJY2FsbGVyOiAgICAgICAgIHBhcmFtcy5jYWxsZXIsCgkJfSwKCSkKCS8vIEVuc3VyZSBsaXF1aWRpdHkgaXMgbm90IHplcm8gYmVmb3JlIG1pbnRpbmcgTkZUCglpZiBsaXF1aWRpdHkuSXNaZXJvKCkgewoJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbCgKCQkJZXJyWmVyb0xpcXVpZGl0eSwKCQkJIkxpcXVpZGl0eSBpcyB6ZXJvLCBjYW5ub3QgbWludCBwb3NpdGlvbi4iLAoJCSkpCgl9CgoJaWQgOj0gcC5nZXROZXh0SWQoKQoKCWlmIHAuRXhpc3RQb3NpdGlvbihpZCkgewoJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbCgKCQkJZXJyUG9zaXRpb25FeGlzdCwKCQkJdWZtdC5TcHJpbnRmKCJwb3NpdGlvbklkKCVkKSIsIGlkKSwKCQkpKQoJfQoKCXAubmZ0QWNjZXNzb3IuTWludCgwLCBybG0sIHBhcmFtcy5taW50VG8sIHBvc2l0aW9uSWRGcm9tKGlkKSkKCglwb3NpdGlvbktleSA6PSBjb21wdXRlUG9zaXRpb25LZXkocGFyYW1zLnRpY2tMb3dlciwgcGFyYW1zLnRpY2tVcHBlcikKCWZlZUdyb3d0aEluc2lkZTBMYXN0WDEyOCwgZmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4LCBlcnIgOj0gcGwuR2V0UG9zaXRpb25GZWVHcm93dGhJbnNpZGVMYXN0WDEyOChwb29sS2V5LCBwb3NpdGlvbktleSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCglwb3NpdGlvbiA6PSBwb3NpdGlvbi5OZXdQb3NpdGlvbigKCQlwb29sS2V5LAoJCXBhcmFtcy50aWNrTG93ZXIsCgkJcGFyYW1zLnRpY2tVcHBlciwKCQlsaXF1aWRpdHkuVG9TdHJpbmcoKSwKCQlmZWVHcm93dGhJbnNpZGUwTGFzdFgxMjgsCgkJZmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4LAoJCTAsCgkJMCwKCQlmYWxzZSwKCQl6ZXJvQWRkcmVzcywKCSkKCgkvLyBUaGUgcG9zaXRpb24gSUQgc2hvdWxkIG5vdCBleGlzdCBhdCB0aGUgdGltZSBvZiBtaW50aW5nCglwLm11c3RVcGRhdGVQb3NpdGlvbigwLCBybG0sIGlkLCAqcG9zaXRpb24pCglwLmluY3JlbWVudE5leHRJZCgwLCBybG0pCgoJcmV0dXJuIGlkLCBsaXF1aWRpdHksIGFtb3VudDAsIGFtb3VudDEKfQoKLy8gcHJvY2Vzc01pbnRJbnB1dCBwcm9jZXNzZXMgYW5kIHZhbGlkYXRlcyB1c2VyIGlucHV0IGZvciBtaW50aW5nIGxpcXVpZGl0eS4KLy8gSXQgaGFuZGxlcyB0b2tlbiBvcmRlcmluZyBhbmQgYW1vdW50IHZhbGlkYXRpb24uCmZ1bmMgKHAgKnBvc2l0aW9uVjEpIHByb2Nlc3NNaW50SW5wdXQoaW5wdXQgTWludElucHV0KSAoUHJvY2Vzc2VkTWludElucHV0LCBlcnJvcikgewoJdG9rZW4wLCB0b2tlbjEgOj0gaW5wdXQudG9rZW4wLCBpbnB1dC50b2tlbjEKCWlmIGVyciA6PSB2YWxpZGF0ZVRva2VuUGF0aCh0b2tlbjAsIHRva2VuMSk7IGVyciAhPSBuaWwgewoJCXJldHVybiBQcm9jZXNzZWRNaW50SW5wdXR7fSwgbWFrZUVycm9yV2l0aERldGFpbHMoZXJyLkVycm9yKCksIHVmbXQuU3ByaW50ZigidG9rZW4wKCVzKSwgdG9rZW4xKCVzKSIsIHRva2VuMCwgdG9rZW4xKSkKCX0KCglwYWlyIDo9IFRva2VuUGFpcnsKCQl0b2tlbjA6IHRva2VuMCwKCQl0b2tlbjE6IHRva2VuMSwKCX0KCgkvLyBwYXJzZSBhbW91bnRzCglhbW91bnQwRGVzaXJlZCwgYW1vdW50MURlc2lyZWQsIGFtb3VudDBNaW4sIGFtb3VudDFNaW4gOj0gcGFyc2VBbW91bnRzKGlucHV0LmFtb3VudDBEZXNpcmVkLCBpbnB1dC5hbW91bnQxRGVzaXJlZCwgaW5wdXQuYW1vdW50ME1pbiwgaW5wdXQuYW1vdW50MU1pbikKCgl0aWNrTG93ZXIsIHRpY2tVcHBlciA6PSBpbnB1dC50aWNrTG93ZXIsIGlucHV0LnRpY2tVcHBlcgoKCS8vIHN3YXAgaWYgdG9rZW4xIDwgdG9rZW4wCglpZiB0b2tlbjEgPCB0b2tlbjAgewoJCXBhaXIudG9rZW4wLCBwYWlyLnRva2VuMSA9IHBhaXIudG9rZW4xLCBwYWlyLnRva2VuMAoJCWFtb3VudDBEZXNpcmVkLCBhbW91bnQxRGVzaXJlZCA9IGFtb3VudDFEZXNpcmVkLCBhbW91bnQwRGVzaXJlZAoJCWFtb3VudDBNaW4sIGFtb3VudDFNaW4gPSBhbW91bnQxTWluLCBhbW91bnQwTWluCgkJdGlja0xvd2VyLCB0aWNrVXBwZXIgPSAtdGlja1VwcGVyLCAtdGlja0xvd2VyCgl9CgoJcmV0dXJuIFByb2Nlc3NlZE1pbnRJbnB1dHsKCQl0b2tlblBhaXI6ICAgICAgcGFpciwKCQlhbW91bnQwRGVzaXJlZDogYW1vdW50MERlc2lyZWQsCgkJYW1vdW50MURlc2lyZWQ6IGFtb3VudDFEZXNpcmVkLAoJCWFtb3VudDBNaW46ICAgICBhbW91bnQwTWluLAoJCWFtb3VudDFNaW46ICAgICBhbW91bnQxTWluLAoJCXRpY2tMb3dlcjogICAgICB0aWNrTG93ZXIsCgkJdGlja1VwcGVyOiAgICAgIHRpY2tVcHBlciwKCQlwb29sUGF0aDogICAgICAgcGwuR2V0UG9vbFBhdGgocGFpci50b2tlbjAsIHBhaXIudG9rZW4xLCBpbnB1dC5mZWUpLAoJfSwgbmlsCn0KCi8vIGluY3JlYXNlTGlxdWlkaXR5IGluY3JlYXNlcyB0aGUgbGlxdWlkaXR5IG9mIGFuIGV4aXN0aW5nIHBvc2l0aW9uLgpmdW5jIChwICpwb3NpdGlvblYxKSBpbmNyZWFzZUxpcXVpZGl0eShfIGludCwgcmxtIHJlYWxtLCBwYXJhbXMgSW5jcmVhc2VMaXF1aWRpdHlQYXJhbXMpICh1aW50NjQsICp1MjU2LlVpbnQsICp1MjU2LlVpbnQsICp1MjU2LlVpbnQsIHN0cmluZywgZXJyb3IpIHsKCWNhbGxlciA6PSBwYXJhbXMuY2FsbGVyCglwb3NpdGlvbiA6PSBwLm11c3RHZXRQb3NpdGlvbihwYXJhbXMucG9zaXRpb25JZCkKCglsaXF1aWRpdHksIGFtb3VudDAsIGFtb3VudDEgOj0gcC5hZGRMaXF1aWRpdHkoCgkJMCwKCQlybG0sCgkJQWRkTGlxdWlkaXR5UGFyYW1zewoJCQlwb29sS2V5OiAgICAgICAgcG9zaXRpb24uUG9vbEtleSgpLAoJCQl0aWNrTG93ZXI6ICAgICAgcG9zaXRpb24uVGlja0xvd2VyKCksCgkJCXRpY2tVcHBlcjogICAgICBwb3NpdGlvbi5UaWNrVXBwZXIoKSwKCQkJYW1vdW50MERlc2lyZWQ6IHBhcmFtcy5hbW91bnQwRGVzaXJlZCwKCQkJYW1vdW50MURlc2lyZWQ6IHBhcmFtcy5hbW91bnQxRGVzaXJlZCwKCQkJYW1vdW50ME1pbjogICAgIHBhcmFtcy5hbW91bnQwTWluLAoJCQlhbW91bnQxTWluOiAgICAgcGFyYW1zLmFtb3VudDFNaW4sCgkJCWNhbGxlcjogICAgICAgICBjYWxsZXIsCgkJfSwKCSkKCglwb3NpdGlvbktleSA6PSBjb21wdXRlUG9zaXRpb25LZXkocG9zaXRpb24uVGlja0xvd2VyKCksIHBvc2l0aW9uLlRpY2tVcHBlcigpKQoJZmVlR3Jvd3RoSW5zaWRlMExhc3RYMTI4U3RyLCBmZWVHcm93dGhJbnNpZGUxTGFzdFgxMjhTdHIsIGVyciA6PSBwbC5HZXRQb3NpdGlvbkZlZUdyb3d0aEluc2lkZUxhc3RYMTI4KHBvc2l0aW9uLlBvb2xLZXkoKSwgcG9zaXRpb25LZXkpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgbmlsLCBuaWwsIG5pbCwgIiIsIGVycgoJfQoKCWZlZUdyb3d0aCA6PSBGZWVHcm93dGhJbnNpZGV7CgkJZmVlR3Jvd3RoSW5zaWRlMExhc3RYMTI4OiB1MjU2Lk11c3RGcm9tRGVjaW1hbChmZWVHcm93dGhJbnNpZGUwTGFzdFgxMjhTdHIpLAoJCWZlZUdyb3d0aEluc2lkZTFMYXN0WDEyODogdTI1Ni5NdXN0RnJvbURlY2ltYWwoZmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4U3RyKSwKCX0KCXRva2Vuc093ZWQwLCB0b2tlbnNPd2VkMSA6PSBwLmNhbGN1bGF0ZUZlZXMocG9zaXRpb24sIGZlZUdyb3d0aCkKCglwb3NMaXF1aWRpdHkgOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwocG9zaXRpb24uTGlxdWlkaXR5KCkpCglsaXF1aWRpdHlBbW91bnQsIG92ZXJmbG93IDo9IHUyNTYuWmVybygpLkFkZE92ZXJmbG93KHBvc0xpcXVpZGl0eSwgbGlxdWlkaXR5KQoJaWYgb3ZlcmZsb3cgewoJCXJldHVybiAwLCBuaWwsIG5pbCwgbmlsLCAiIiwgZXJyb3JzLk5ldyhlcnJPdmVyZmxvdykKCX0KCglwb3NpdGlvbi5TZXRUb2tlbnNPd2VkMCh0b2tlbnNPd2VkMCkKCXBvc2l0aW9uLlNldFRva2Vuc093ZWQxKHRva2Vuc093ZWQxKQoKCXBvc2l0aW9uLlNldEZlZUdyb3d0aEluc2lkZTBMYXN0WDEyOChmZWVHcm93dGhJbnNpZGUwTGFzdFgxMjhTdHIpCglwb3NpdGlvbi5TZXRGZWVHcm93dGhJbnNpZGUxTGFzdFgxMjgoZmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4U3RyKQoKCXBvc2l0aW9uLlNldExpcXVpZGl0eShsaXF1aWRpdHlBbW91bnQuVG9TdHJpbmcoKSkKCXBvc2l0aW9uLlNldEJ1cm5lZChmYWxzZSkKCgllcnIgPSBwLnNldFBvc2l0aW9uKDAsIHJsbSwgcGFyYW1zLnBvc2l0aW9uSWQsICpwb3NpdGlvbikKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBuaWwsIG5pbCwgbmlsLCAiIiwgbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyclBvc2l0aW9uRG9lc05vdEV4aXN0LAoJCQl1Zm10LlNwcmludGYoImNhbm5vdCBpbmNyZWFzZSBsaXF1aWRpdHkgZm9yIG5vbi1leGlzdGVudCBwb3NpdGlvbiglZCkiLCBwYXJhbXMucG9zaXRpb25JZCksCgkJKQoJfQoKCXJldHVybiBwYXJhbXMucG9zaXRpb25JZCwgbGlxdWlkaXR5LCBhbW91bnQwLCBhbW91bnQxLCBwb3NpdGlvbi5Qb29sS2V5KCksIG5pbAp9CgovLyB2YWxpZGF0ZVRva2VuUGF0aCB2YWxpZGF0ZXMgdG9rZW4gcGF0aHMgYXJlIG5vdCBpZGVudGljYWwsIG5vdCBjb25mbGljdGluZywgYW5kIGluIHZhbGlkIGZvcm1hdC4KZnVuYyB2YWxpZGF0ZVRva2VuUGF0aCh0b2tlbjAsIHRva2VuMSBzdHJpbmcpIGVycm9yIHsKCWlmIHRva2VuMCA9PSB0b2tlbjEgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyckludmFsaWRUb2tlblBhdGgpCgl9CglpZiAhaXNWYWxpZFRva2VuUGF0aCh0b2tlbjApIHx8ICFpc1ZhbGlkVG9rZW5QYXRoKHRva2VuMSkgewoJCXJldHVybiBlcnJvcnMuTmV3KGVyckludmFsaWRUb2tlblBhdGgpCgl9CglyZXR1cm4gbmlsCn0KCi8vIGlzVmFsaWRUb2tlblBhdGggY2hlY2tzIGlmIHRoZSB0b2tlbiBwYXRoIGlzIHJlZ2lzdGVyZWQgaW4gdGhlIHN5c3RlbS4KZnVuYyBpc1ZhbGlkVG9rZW5QYXRoKHRva2VuUGF0aCBzdHJpbmcpIGJvb2wgewoJcmV0dXJuIGNvbW1vbi5Jc1JlZ2lzdGVyZWQodG9rZW5QYXRoKSA9PSBuaWwKfQoKLy8gcGFyc2VBbW91bnRzIGNvbnZlcnRzIGFtb3VudCBzdHJpbmdzIHRvIHUyNTYuVWludCB2YWx1ZXMuCmZ1bmMgcGFyc2VBbW91bnRzKGFtb3VudDBEZXNpcmVkLCBhbW91bnQxRGVzaXJlZCwgYW1vdW50ME1pbiwgYW1vdW50MU1pbiBzdHJpbmcpICgqdTI1Ni5VaW50LCAqdTI1Ni5VaW50LCAqdTI1Ni5VaW50LCAqdTI1Ni5VaW50KSB7CglyZXR1cm4gdTI1Ni5NdXN0RnJvbURlY2ltYWwoYW1vdW50MERlc2lyZWQpLCB1MjU2Lk11c3RGcm9tRGVjaW1hbChhbW91bnQxRGVzaXJlZCksIHUyNTYuTXVzdEZyb21EZWNpbWFsKGFtb3VudDBNaW4pLCB1MjU2Lk11c3RGcm9tRGVjaW1hbChhbW91bnQxTWluKQp9ChrFmQEKDHBvc2l0aW9uLmdubxKzmQFwYWNrYWdlIHBvc2l0aW9uCgppbXBvcnQgKAoJImNoYWluIgoKCSJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCXUyNTYgImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgoJImduby5sYW5kL3AvZ25vc3dhcC91dGlscy92MSIKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCSJnbm8ubGFuZC9yL2dub3N3YXAvYWNjZXNzL3YxIgoJImduby5sYW5kL3IvZ25vc3dhcC9jb21tb24iCgkiZ25vLmxhbmQvci9nbm9zd2FwL2VtaXNzaW9uIgoJImduby5sYW5kL3IvZ25vc3dhcC9oYWx0L3YxIgoJcGwgImduby5sYW5kL3IvZ25vc3dhcC9wb29sIgoJcG9zICJnbm8ubGFuZC9yL2dub3N3YXAvcG9zaXRpb24iCgkiZ25vLmxhbmQvci9nbm9zd2FwL3JlZmVycmFsL3YxIgoJImduby5sYW5kL3IvZ25vc3dhcC9zdGFrZXIiCikKCi8vIE1pbnQgY3JlYXRlcyBhIG5ldyBsaXF1aWRpdHkgcG9zaXRpb24gTkZULgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgdW5jaGFuZ2VkIGJ5IHRoZSBwb3NpdGlvbiBwcm94eS4KLy8gICAtIHRva2VuMDogdG9rZW4wIGNvbnRyYWN0IHBhdGggZm9yIHRoZSBwb29sCi8vICAgLSB0b2tlbjE6IHRva2VuMSBjb250cmFjdCBwYXRoIGZvciB0aGUgcG9vbAovLyAgIC0gZmVlOiBwb29sIGZlZSB0aWVyIHVzZWQgdG8gc2VsZWN0IHRoZSBwb29sCi8vICAgLSB0aWNrTG93ZXI6IGxvd2VyIHRpY2sgYm91bmRhcnkgb2YgdGhlIHBvc2l0aW9uJ3MgcmFuZ2UKLy8gICAtIHRpY2tVcHBlcjogdXBwZXIgdGljayBib3VuZGFyeSBvZiB0aGUgcG9zaXRpb24ncyByYW5nZQovLyAgIC0gYW1vdW50MERlc2lyZWQ6IGRlc2lyZWQgdG9rZW4wIGFtb3VudCwgc3VwcGxpZWQgYXMgYSBkZWNpbWFsIHN0cmluZwovLyAgIC0gYW1vdW50MURlc2lyZWQ6IGRlc2lyZWQgdG9rZW4xIGFtb3VudCwgc3VwcGxpZWQgYXMgYSBkZWNpbWFsIHN0cmluZwovLyAgIC0gYW1vdW50ME1pbjogbWluaW11bSBhY2NlcHRhYmxlIHRva2VuMCBhbW91bnQgZm9yIHNsaXBwYWdlIHByb3RlY3Rpb24KLy8gICAtIGFtb3VudDFNaW46IG1pbmltdW0gYWNjZXB0YWJsZSB0b2tlbjEgYW1vdW50IGZvciBzbGlwcGFnZSBwcm90ZWN0aW9uCi8vICAgLSBkZWFkbGluZTogVW5peCB0aW1lc3RhbXAgYWZ0ZXIgd2hpY2ggdGhlIHRyYW5zYWN0aW9uIGlzIHJlamVjdGVkCi8vICAgLSBtaW50VG86IGFkZHJlc3MgdGhhdCByZWNlaXZlcyB0aGUgbmV3bHkgbWludGVkIHBvc2l0aW9uIE5GVAovLyAgIC0gcmVmZXJyZXI6IHJlZmVycmFsIHZhbHVlIHN1Ym1pdHRlZCBmb3IgcmVnaXN0cmF0aW9uIHdpdGggdGhlIGNhbGxlcgovLwovLyBSZXR1cm5zOgovLyAgIC0gcG9zaXRpb25JZDogbmV3bHkgbWludGVkIHBvc2l0aW9uIE5GVCBJRAovLyAgIC0gbGlxdWlkaXR5OiBsaXF1aWRpdHkgYW1vdW50IG1pbnRlZCBmb3IgdGhlIHBvc2l0aW9uCi8vICAgLSBhbW91bnQwOiB0b2tlbjAgYW1vdW50IGFjdHVhbGx5IGRlcG9zaXRlZCBpbnRvIHRoZSBwb29sCi8vICAgLSBhbW91bnQxOiB0b2tlbjEgYW1vdW50IGFjdHVhbGx5IGRlcG9zaXRlZCBpbnRvIHRoZSBwb29sCi8vCi8vIE5vdGU6IFNsaXBwYWdlIHByb3RlY3Rpb24gdmlhIGFtb3VudDBNaW4vYW1vdW50MU1pbi4KZnVuYyAocCAqcG9zaXRpb25WMSkgTWludCgKCV8gaW50LAoJcmxtIHJlYWxtLAoJdG9rZW4wIHN0cmluZywKCXRva2VuMSBzdHJpbmcsCglmZWUgdWludDMyLAoJdGlja0xvd2VyIGludDMyLAoJdGlja1VwcGVyIGludDMyLAoJYW1vdW50MERlc2lyZWQgc3RyaW5nLAoJYW1vdW50MURlc2lyZWQgc3RyaW5nLAoJYW1vdW50ME1pbiBzdHJpbmcsCglhbW91bnQxTWluIHN0cmluZywKCWRlYWRsaW5lIGludDY0LAoJbWludFRvIGFkZHJlc3MsCglyZWZlcnJlciBzdHJpbmcsCikgKHVpbnQ2NCwgc3RyaW5nLCBzdHJpbmcsIHN0cmluZykgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFBvc2l0aW9uKCkKCWFjY2Vzcy5Bc3NlcnRJc1ZhbGlkQWRkcmVzcyhtaW50VG8pCgoJcHJldmlvdXNSZWFsbSA6PSBybG0uUHJldmlvdXMoKQoJY2FsbGVyIDo9IHByZXZpb3VzUmVhbG0uQWRkcmVzcygpCgoJYXNzZXJ0SXNOb3RNaW50VG9TdGFrZXIobWludFRvKQoJYXNzZXJ0VmFsaWROdW1iZXJTdHJpbmcoYW1vdW50MERlc2lyZWQpCglhc3NlcnRWYWxpZE51bWJlclN0cmluZyhhbW91bnQxRGVzaXJlZCkKCWFzc2VydFZhbGlkTnVtYmVyU3RyaW5nKGFtb3VudDBNaW4pCglhc3NlcnRWYWxpZE51bWJlclN0cmluZyhhbW91bnQxTWluKQoKCS8vIGFzc2VydCB0aGF0IHRoZSB1c2VyIGhhcyBzZW50IHRoZSBjb3JyZWN0IGFtb3VudCBvZiBuYXRpdmUgY29pbgoJY29tbW9uLkFzc2VydElzTm90SGFuZGxlTmF0aXZlQ29pbigpCglhc3NlcnRJc05vdEV4cGlyZWQoZGVhZGxpbmUpCgoJYWN0dWFsUmVmZXJyZXIgOj0gcmVmZXJyYWwuVHJ5UmVnaXN0ZXIoY3Jvc3MocmxtKSwgY2FsbGVyLCByZWZlcnJlcikKCgllbWlzc2lvbi5NaW50QW5kRGlzdHJpYnV0ZUducyhjcm9zcyhybG0pKQoKCW1pbnRJbnB1dCA6PSBNaW50SW5wdXR7CgkJdG9rZW4wOiAgICAgICAgIHRva2VuMCwKCQl0b2tlbjE6ICAgICAgICAgdG9rZW4xLAoJCWZlZTogICAgICAgICAgICBmZWUsCgkJdGlja0xvd2VyOiAgICAgIHRpY2tMb3dlciwKCQl0aWNrVXBwZXI6ICAgICAgdGlja1VwcGVyLAoJCWFtb3VudDBEZXNpcmVkOiBhbW91bnQwRGVzaXJlZCwKCQlhbW91bnQxRGVzaXJlZDogYW1vdW50MURlc2lyZWQsCgkJYW1vdW50ME1pbjogICAgIGFtb3VudDBNaW4sCgkJYW1vdW50MU1pbjogICAgIGFtb3VudDFNaW4sCgkJZGVhZGxpbmU6ICAgICAgIGRlYWRsaW5lLAoJCW1pbnRUbzogICAgICAgICBtaW50VG8sCgkJY2FsbGVyOiAgICAgICAgIGNhbGxlciwKCX0KCglwcm9jZXNzZWRJbnB1dCwgZXJyIDo9IHAucHJvY2Vzc01pbnRJbnB1dChtaW50SW5wdXQpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhuZXdFcnJvcldpdGhEZXRhaWwoZXJySW52YWxpZElucHV0LCBlcnIuRXJyb3IoKSkpCgl9CgoJLy8gbWludCBsaXF1aWRpdHkKCXBhcmFtcyA6PSBuZXdNaW50UGFyYW1zKHByb2Nlc3NlZElucHV0LCBtaW50SW5wdXQpCglpZCwgbGlxdWlkaXR5LCBhbW91bnQwLCBhbW91bnQxIDo9IHAubWludCgwLCBybG0sIHBhcmFtcykKCglwb29sIDo9IG11c3RHZXRQb29sKHByb2Nlc3NlZElucHV0LnBvb2xQYXRoKQoJcG9zaXRpb25MaXF1aWRpdHksIGVyciA6PSBwLkdldFBvc2l0aW9uTGlxdWlkaXR5KGlkKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoJdGlja0N1bXVsYXRpdmUsIHNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOCwgb2JzZXJ2YXRpb25UaW1lc3RhbXAsIGVyciA6PSBjdXJyZW50UG9vbE9ic2VydmF0aW9uKHByb2Nlc3NlZElucHV0LnBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCWNoYWluLkVtaXQoCgkJIk1pbnQiLAoJCSJwcmV2QWRkciIsIGNhbGxlci5TdHJpbmcoKSwKCQkicHJldlJlYWxtIiwgcHJldmlvdXNSZWFsbS5Qa2dQYXRoKCksCgkJInRpY2tMb3dlciIsIHV0aWxzLkZvcm1hdEludChwcm9jZXNzZWRJbnB1dC50aWNrTG93ZXIpLAoJCSJ0aWNrVXBwZXIiLCB1dGlscy5Gb3JtYXRJbnQocHJvY2Vzc2VkSW5wdXQudGlja1VwcGVyKSwKCQkicG9vbFBhdGgiLCBwcm9jZXNzZWRJbnB1dC5wb29sUGF0aCwKCQkibWludFRvIiwgbWludFRvLlN0cmluZygpLAoJCSJjYWxsZXIiLCBjYWxsZXIuU3RyaW5nKCksCgkJImxwUG9zaXRpb25JZCIsIHV0aWxzLkZvcm1hdFVpbnQoaWQpLAoJCSJsaXF1aWRpdHlEZWx0YSIsIGxpcXVpZGl0eS5Ub1N0cmluZygpLAoJCSJhbW91bnQwIiwgYW1vdW50MC5Ub1N0cmluZygpLAoJCSJhbW91bnQxIiwgYW1vdW50MS5Ub1N0cmluZygpLAoJCSJzcXJ0UHJpY2VYOTYiLCBwb29sLlNsb3QwU3FydFByaWNlWDk2KCkuVG9TdHJpbmcoKSwKCQkicG9zaXRpb25MaXF1aWRpdHkiLCBwb3NpdGlvbkxpcXVpZGl0eSwKCQkicG9vbExpcXVpZGl0eSIsIHBvb2wuTGlxdWlkaXR5KCkuVG9TdHJpbmcoKSwKCQkidG9rZW4wQmFsYW5jZSIsIHV0aWxzLkZvcm1hdEludChwb29sLkJhbGFuY2VUb2tlbjAoKSksCgkJInRva2VuMUJhbGFuY2UiLCB1dGlscy5Gb3JtYXRJbnQocG9vbC5CYWxhbmNlVG9rZW4xKCkpLAoJCSJ0aWNrQ3VtdWxhdGl2ZSIsIHV0aWxzLkZvcm1hdEludCh0aWNrQ3VtdWxhdGl2ZSksCgkJInNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOCIsIHNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOCwKCQkib2JzZXJ2YXRpb25UaW1lc3RhbXAiLCB1dGlscy5Gb3JtYXRJbnQob2JzZXJ2YXRpb25UaW1lc3RhbXApLAoJCSJyZWZlcnJlciIsIGFjdHVhbFJlZmVycmVyLAoJKQoKCXJldHVybiBpZCwgbGlxdWlkaXR5LlRvU3RyaW5nKCksIGFtb3VudDAuVG9TdHJpbmcoKSwgYW1vdW50MS5Ub1N0cmluZygpCn0KCi8vIEluY3JlYXNlTGlxdWlkaXR5IGluY3JlYXNlcyBsaXF1aWRpdHkgb2YgYW4gZXhpc3RpbmcgcG9zaXRpb24uCi8vCi8vIEFkZHMgbW9yZSBsaXF1aWRpdHkgdG8gZXhpc3RpbmcgTkZUIHBvc2l0aW9uLgovLyBNYWludGFpbnMgc2FtZSBwcmljZSByYW5nZSBhcyBvcmlnaW5hbCBwb3NpdGlvbi4KLy8gQ2FsY3VsYXRlcyBvcHRpbWFsIHRva2VuIHJhdGlvIGZvciBjdXJyZW50IHByaWNlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgdW5jaGFuZ2VkIGJ5IHRoZSBwb3NpdGlvbiBwcm94eS4KLy8gICAtIHBvc2l0aW9uSWQ6IE5GVCB0b2tlbiBJRCB0byBpbmNyZWFzZQovLyAgIC0gYW1vdW50MERlc2lyZWRTdHI6IGRlc2lyZWQgdG9rZW4wIGFtb3VudCwgc3VwcGxpZWQgYXMgYSBkZWNpbWFsIHN0cmluZwovLyAgIC0gYW1vdW50MURlc2lyZWRTdHI6IGRlc2lyZWQgdG9rZW4xIGFtb3VudCwgc3VwcGxpZWQgYXMgYSBkZWNpbWFsIHN0cmluZwovLyAgIC0gYW1vdW50ME1pblN0cjogbWluaW11bSBhY2NlcHRhYmxlIHRva2VuMCBhbW91bnQgZm9yIHNsaXBwYWdlIHByb3RlY3Rpb24KLy8gICAtIGFtb3VudDFNaW5TdHI6IG1pbmltdW0gYWNjZXB0YWJsZSB0b2tlbjEgYW1vdW50IGZvciBzbGlwcGFnZSBwcm90ZWN0aW9uCi8vICAgLSBkZWFkbGluZTogVW5peCB0aW1lc3RhbXAgYWZ0ZXIgd2hpY2ggdGhlIHRyYW5zYWN0aW9uIGlzIHJlamVjdGVkCi8vCi8vIFJldHVybnM6Ci8vICAgLSBwb3NpdGlvbklkOiBzYW1lIE5GVCBJRAovLyAgIC0gbGlxdWlkaXR5OiBsaXF1aWRpdHkgYW1vdW50IGFkZGVkICh0aGUgZGVsdGEsIG5vdCB0b3RhbCkKLy8gICAtIGFtb3VudDA6IHRva2VuMCBhbW91bnQgYWN0dWFsbHkgZGVwb3NpdGVkCi8vICAgLSBhbW91bnQxOiB0b2tlbjEgYW1vdW50IGFjdHVhbGx5IGRlcG9zaXRlZAovLyAgIC0gcG9vbFBhdGg6IHBvb2wgaWRlbnRpZmllciBmb3IgdGhlIHBvc2l0aW9uCi8vCi8vIFJlcXVpcmVtZW50czoKLy8gICAtIENhbGxlciBtdXN0IG93biB0aGUgcG9zaXRpb24gTkZUCi8vICAgLSBTdWZmaWNpZW50IHRva2VuIGJhbGFuY2VzIGFuZCBhcHByb3ZhbHMKZnVuYyAocCAqcG9zaXRpb25WMSkgSW5jcmVhc2VMaXF1aWRpdHkoCglfIGludCwKCXJsbSByZWFsbSwKCXBvc2l0aW9uSWQgdWludDY0LAoJYW1vdW50MERlc2lyZWRTdHIgc3RyaW5nLAoJYW1vdW50MURlc2lyZWRTdHIgc3RyaW5nLAoJYW1vdW50ME1pblN0ciBzdHJpbmcsCglhbW91bnQxTWluU3RyIHN0cmluZywKCWRlYWRsaW5lIGludDY0LAopICh1aW50NjQsIHN0cmluZywgc3RyaW5nLCBzdHJpbmcsIHN0cmluZykgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFBvc2l0aW9uKCkKCglwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXIgOj0gcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkKCWFzc2VydElzT3duZXJGb3JUb2tlbihwLCBwb3NpdGlvbklkLCBjYWxsZXIpCgoJYXNzZXJ0VmFsaWROdW1iZXJTdHJpbmcoYW1vdW50MERlc2lyZWRTdHIpCglhc3NlcnRWYWxpZE51bWJlclN0cmluZyhhbW91bnQxRGVzaXJlZFN0cikKCWFzc2VydFZhbGlkTnVtYmVyU3RyaW5nKGFtb3VudDBNaW5TdHIpCglhc3NlcnRWYWxpZE51bWJlclN0cmluZyhhbW91bnQxTWluU3RyKQoJYXNzZXJ0SXNOb3RFeHBpcmVkKGRlYWRsaW5lKQoKCWVtaXNzaW9uLk1pbnRBbmREaXN0cmlidXRlR25zKGNyb3NzKHJsbSkpCgoJcG9zaXRpb24gOj0gcC5tdXN0R2V0UG9zaXRpb24ocG9zaXRpb25JZCkKCXRva2VuMCwgdG9rZW4xLCBfIDo9IHNwbGl0T2YocG9zaXRpb24uUG9vbEtleSgpKQoKCWNvbW1vbi5Bc3NlcnRJc05vdEhhbmRsZU5hdGl2ZUNvaW4oKQoKCWVyciA6PSB2YWxpZGF0ZVRva2VuUGF0aCh0b2tlbjAsIHRva2VuMSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbChlcnIuRXJyb3IoKSwgdWZtdC5TcHJpbnRmKCJ0b2tlbjAoJXMpLCB0b2tlbjEoJXMpIiwgdG9rZW4wLCB0b2tlbjEpKSkKCX0KCglhbW91bnQwRGVzaXJlZCwgYW1vdW50MURlc2lyZWQsIGFtb3VudDBNaW4sIGFtb3VudDFNaW4gOj0gcGFyc2VBbW91bnRzKGFtb3VudDBEZXNpcmVkU3RyLCBhbW91bnQxRGVzaXJlZFN0ciwgYW1vdW50ME1pblN0ciwgYW1vdW50MU1pblN0cikKCWluY3JlYXNlTGlxdWlkaXR5UGFyYW1zIDo9IEluY3JlYXNlTGlxdWlkaXR5UGFyYW1zewoJCXBvc2l0aW9uSWQ6ICAgICBwb3NpdGlvbklkLAoJCWFtb3VudDBEZXNpcmVkOiBhbW91bnQwRGVzaXJlZCwKCQlhbW91bnQxRGVzaXJlZDogYW1vdW50MURlc2lyZWQsCgkJYW1vdW50ME1pbjogICAgIGFtb3VudDBNaW4sCgkJYW1vdW50MU1pbjogICAgIGFtb3VudDFNaW4sCgkJZGVhZGxpbmU6ICAgICAgIGRlYWRsaW5lLAoJCWNhbGxlcjogICAgICAgICBjYWxsZXIsCgl9CgoJXywgbGlxdWlkaXR5LCBhbW91bnQwLCBhbW91bnQxLCBwb29sUGF0aCwgZXJyIDo9IHAuaW5jcmVhc2VMaXF1aWRpdHkoMCwgcmxtLCBpbmNyZWFzZUxpcXVpZGl0eVBhcmFtcykKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCglwb29sIDo9IG11c3RHZXRQb29sKHBvb2xQYXRoKQoJcG9zaXRpb25MaXF1aWRpdHksIGVyciA6PSBwLkdldFBvc2l0aW9uTGlxdWlkaXR5KHBvc2l0aW9uSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9Cgl0aWNrQ3VtdWxhdGl2ZSwgc2Vjb25kc1BlckxpcXVpZGl0eUN1bXVsYXRpdmVYMTI4LCBvYnNlcnZhdGlvblRpbWVzdGFtcCwgZXJyIDo9IGN1cnJlbnRQb29sT2JzZXJ2YXRpb24ocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgljaGFpbi5FbWl0KAoJCSJJbmNyZWFzZUxpcXVpZGl0eSIsCgkJInByZXZBZGRyIiwgcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCSJwb29sUGF0aCIsIHBvb2xQYXRoLAoJCSJ0aWNrTG93ZXIiLCB1dGlscy5Gb3JtYXRJbnQocG9zaXRpb24uVGlja0xvd2VyKCkpLAoJCSJ0aWNrVXBwZXIiLCB1dGlscy5Gb3JtYXRJbnQocG9zaXRpb24uVGlja1VwcGVyKCkpLAoJCSJjYWxsZXIiLCBjYWxsZXIuU3RyaW5nKCksCgkJImxwUG9zaXRpb25JZCIsIHV0aWxzLkZvcm1hdFVpbnQocG9zaXRpb25JZCksCgkJImxpcXVpZGl0eURlbHRhIiwgbGlxdWlkaXR5LlRvU3RyaW5nKCksCgkJImFtb3VudDAiLCBhbW91bnQwLlRvU3RyaW5nKCksCgkJImFtb3VudDEiLCBhbW91bnQxLlRvU3RyaW5nKCksCgkJInNxcnRQcmljZVg5NiIsIHBvb2wuU2xvdDBTcXJ0UHJpY2VYOTYoKS5Ub1N0cmluZygpLAoJCSJwb3NpdGlvbkxpcXVpZGl0eSIsIHBvc2l0aW9uTGlxdWlkaXR5LAoJCSJwb29sTGlxdWlkaXR5IiwgcG9vbC5MaXF1aWRpdHkoKS5Ub1N0cmluZygpLAoJCSJ0b2tlbjBCYWxhbmNlIiwgdXRpbHMuRm9ybWF0SW50KHBvb2wuQmFsYW5jZVRva2VuMCgpKSwKCQkidG9rZW4xQmFsYW5jZSIsIHV0aWxzLkZvcm1hdEludChwb29sLkJhbGFuY2VUb2tlbjEoKSksCgkJInRpY2tDdW11bGF0aXZlIiwgdXRpbHMuRm9ybWF0SW50KHRpY2tDdW11bGF0aXZlKSwKCQkic2Vjb25kc1BlckxpcXVpZGl0eUN1bXVsYXRpdmVYMTI4Iiwgc2Vjb25kc1BlckxpcXVpZGl0eUN1bXVsYXRpdmVYMTI4LAoJCSJvYnNlcnZhdGlvblRpbWVzdGFtcCIsIHV0aWxzLkZvcm1hdEludChvYnNlcnZhdGlvblRpbWVzdGFtcCksCgkpCgoJcmV0dXJuIHBvc2l0aW9uSWQsIGxpcXVpZGl0eS5Ub1N0cmluZygpLCBhbW91bnQwLlRvU3RyaW5nKCksIGFtb3VudDEuVG9TdHJpbmcoKSwgcG9vbFBhdGgKfQoKLy8gRGVjcmVhc2VMaXF1aWRpdHkgZGVjcmVhc2VzIGxpcXVpZGl0eSBvZiBhbiBleGlzdGluZyBwb3NpdGlvbi4KLy8KLy8gUmVtb3ZlcyBsaXF1aWRpdHkgYnV0IGtlZXBzIE5GVCBvd25lcnNoaXAuIFRoaXMgaXMgb25lIGF0b21pYyBwdWJsaWMKLy8gb3BlcmF0aW9uOiBhY2NydWVkIHN3YXAgZmVlcyBhcmUgY29sbGVjdGVkIGZpcnN0LCB0aGVuIGxpcXVpZGl0eSBpcyBidXJuZWQsCi8vIGFuZCBwcmluY2lwYWwgaXMgY29sbGVjdGVkIHRocm91Z2ggdGhlIHBvb2wncyBmZWUtZnJlZSBgQ29sbGVjdGAgcGF0aC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIHVuY2hhbmdlZCBieSB0aGUgcG9zaXRpb24gcHJveHkuCi8vICAgLSBwb3NpdGlvbklkOiBORlQgdG9rZW4gSUQKLy8gICAtIGxpcXVpZGl0eVN0cjogYW1vdW50IG9mIGxpcXVpZGl0eSB0byByZW1vdmUsIHN1cHBsaWVkIGFzIGEgZGVjaW1hbCBzdHJpbmcKLy8gICAtIGFtb3VudDBNaW5TdHI6IG1pbmltdW0gdG9rZW4wIHByaW5jaXBhbCB0byByZWNlaXZlLCBmb3Igc2xpcHBhZ2UgcHJvdGVjdGlvbgovLyAgIC0gYW1vdW50MU1pblN0cjogbWluaW11bSB0b2tlbjEgcHJpbmNpcGFsIHRvIHJlY2VpdmUsIGZvciBzbGlwcGFnZSBwcm90ZWN0aW9uCi8vICAgLSBkZWFkbGluZTogVW5peCB0aW1lc3RhbXAgYWZ0ZXIgd2hpY2ggdGhlIHRyYW5zYWN0aW9uIGlzIHJlamVjdGVkCi8vCi8vIFJldHVybnM6Ci8vICAgLSBwb3NpdGlvbklkOiBzYW1lIE5GVCBJRAovLyAgIC0gbGlxdWlkaXR5OiBhbW91bnQgb2YgbGlxdWlkaXR5IHJlbW92ZWQgKHRoZSBkZWx0YSkKLy8gICAtIGZlZTA6IHRva2VuMCBmZWUgYW1vdW50IHJldHVybmVkIG5ldCBvZiB0aGUgd2l0aGRyYXdhbCBmZWUKLy8gICAtIGZlZTE6IHRva2VuMSBmZWUgYW1vdW50IHJldHVybmVkIG5ldCBvZiB0aGUgd2l0aGRyYXdhbCBmZWUKLy8gICAtIGFtb3VudDA6IHRva2VuMCBwcmluY2lwYWwgY29sbGVjdGVkIHdpdGhvdXQgYSB3aXRoZHJhd2FsIGZlZQovLyAgIC0gYW1vdW50MTogdG9rZW4xIHByaW5jaXBhbCBjb2xsZWN0ZWQgd2l0aG91dCBhIHdpdGhkcmF3YWwgZmVlCi8vICAgLSBwb29sUGF0aDogcG9vbCBpZGVudGlmaWVyCi8vCi8vIEFtb3VudC1taW5pbXVtIGNoZWNrcyBhcHBseSB0byB0aGUgcHJpbmNpcGFsIGFjdHVhbGx5IGNvbGxlY3RlZC4KZnVuYyAocCAqcG9zaXRpb25WMSkgRGVjcmVhc2VMaXF1aWRpdHkoCglfIGludCwKCXJsbSByZWFsbSwKCXBvc2l0aW9uSWQgdWludDY0LAoJbGlxdWlkaXR5U3RyIHN0cmluZywKCWFtb3VudDBNaW5TdHIgc3RyaW5nLAoJYW1vdW50MU1pblN0ciBzdHJpbmcsCglkZWFkbGluZSBpbnQ2NCwKKSAodWludDY0LCBzdHJpbmcsIHN0cmluZywgc3RyaW5nLCBzdHJpbmcsIHN0cmluZywgc3RyaW5nKSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCgloYWx0LkFzc2VydElzTm90SGFsdGVkV2l0aGRyYXcoKQoKCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKQoJYXNzZXJ0SXNPd25lckZvclRva2VuKHAsIHBvc2l0aW9uSWQsIGNhbGxlcikKCWFzc2VydElzTm90RXhwaXJlZChkZWFkbGluZSkKCWFzc2VydFZhbGlkTGlxdWlkaXR5QW1vdW50KGxpcXVpZGl0eVN0cikKCgllbWlzc2lvbi5NaW50QW5kRGlzdHJpYnV0ZUducyhjcm9zcyhybG0pKQoKCWFtb3VudDBNaW4gOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwoYW1vdW50ME1pblN0cikKCWFtb3VudDFNaW4gOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwoYW1vdW50MU1pblN0cikKCWRlY3JlYXNlTGlxdWlkaXR5UGFyYW1zIDo9IERlY3JlYXNlTGlxdWlkaXR5UGFyYW1zewoJCXBvc2l0aW9uSWQ6IHBvc2l0aW9uSWQsCgkJbGlxdWlkaXR5OiAgbGlxdWlkaXR5U3RyLAoJCWFtb3VudDBNaW46IGFtb3VudDBNaW4sCgkJYW1vdW50MU1pbjogYW1vdW50MU1pbiwKCQlkZWFkbGluZTogICBkZWFkbGluZSwKCQljYWxsZXI6ICAgICBjYWxsZXIsCgl9CgoJcG9zaXRpb24gOj0gcC5tdXN0R2V0UG9zaXRpb24ocG9zaXRpb25JZCkKCXRpY2tMb3dlciA6PSBwb3NpdGlvbi5UaWNrTG93ZXIoKQoJdGlja1VwcGVyIDo9IHBvc2l0aW9uLlRpY2tVcHBlcigpCgoJcG9zaXRpb25JZCwgbGlxdWlkaXR5LCBmZWUwLCBmZWUxLCBhbW91bnQwLCBhbW91bnQxLCBwb29sUGF0aCwgZXJyIDo9IHAuZGVjcmVhc2VMaXF1aWRpdHkoMCwgcmxtLCBkZWNyZWFzZUxpcXVpZGl0eVBhcmFtcykKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCglwb29sIDo9IG11c3RHZXRQb29sKHBvb2xQYXRoKQoJcG9zaXRpb25MaXF1aWRpdHksIGVyciA6PSBwLkdldFBvc2l0aW9uTGlxdWlkaXR5KHBvc2l0aW9uSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9Cgl0aWNrQ3VtdWxhdGl2ZSwgc2Vjb25kc1BlckxpcXVpZGl0eUN1bXVsYXRpdmVYMTI4LCBvYnNlcnZhdGlvblRpbWVzdGFtcCwgZXJyIDo9IGN1cnJlbnRQb29sT2JzZXJ2YXRpb24ocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgljaGFpbi5FbWl0KAoJCSJEZWNyZWFzZUxpcXVpZGl0eSIsCgkJInByZXZBZGRyIiwgcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCSJscFBvc2l0aW9uSWQiLCB1dGlscy5Gb3JtYXRVaW50KHBvc2l0aW9uSWQpLAoJCSJwb29sUGF0aCIsIHBvb2xQYXRoLAoJCSJ0aWNrTG93ZXIiLCB1dGlscy5Gb3JtYXRJbnQodGlja0xvd2VyKSwKCQkidGlja1VwcGVyIiwgdXRpbHMuRm9ybWF0SW50KHRpY2tVcHBlciksCgkJImxpcXVpZGl0eURlbHRhIiwgbGlxdWlkaXR5LAoJCSJmZWVBbW91bnQwIiwgZmVlMCwKCQkiZmVlQW1vdW50MSIsIGZlZTEsCgkJImFtb3VudDAiLCBhbW91bnQwLAoJCSJhbW91bnQxIiwgYW1vdW50MSwKCQkic3FydFByaWNlWDk2IiwgcG9vbC5TbG90MFNxcnRQcmljZVg5NigpLlRvU3RyaW5nKCksCgkJInBvc2l0aW9uTGlxdWlkaXR5IiwgcG9zaXRpb25MaXF1aWRpdHksCgkJInBvb2xMaXF1aWRpdHkiLCBwb29sLkxpcXVpZGl0eSgpLlRvU3RyaW5nKCksCgkJInRva2VuMEJhbGFuY2UiLCB1dGlscy5Gb3JtYXRJbnQocG9vbC5CYWxhbmNlVG9rZW4wKCkpLAoJCSJ0b2tlbjFCYWxhbmNlIiwgdXRpbHMuRm9ybWF0SW50KHBvb2wuQmFsYW5jZVRva2VuMSgpKSwKCQkidGlja0N1bXVsYXRpdmUiLCB1dGlscy5Gb3JtYXRJbnQodGlja0N1bXVsYXRpdmUpLAoJCSJzZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjgiLCBzZWNvbmRzUGVyTGlxdWlkaXR5Q3VtdWxhdGl2ZVgxMjgsCgkJIm9ic2VydmF0aW9uVGltZXN0YW1wIiwgdXRpbHMuRm9ybWF0SW50KG9ic2VydmF0aW9uVGltZXN0YW1wKSwKCSkKCglyZXR1cm4gcG9zaXRpb25JZCwgbGlxdWlkaXR5LCBmZWUwLCBmZWUxLCBhbW91bnQwLCBhbW91bnQxLCBwb29sUGF0aAp9CgovLyBDb2xsZWN0RmVlIGNvbGxlY3RzIHN3YXAgZmVlIGZyb20gdGhlIHBvc2l0aW9uLgovLwovLyBDbGFpbXMgYWNjdW11bGF0ZWQgZmVlcyB3aXRob3V0IHJlbW92aW5nIGxpcXVpZGl0eS4KLy8gVXNlZnVsIGZvciBhY3RpdmUgcG9zaXRpb25zIGVhcm5pbmcgb25nb2luZyBmZWVzLgovLyBBcHBsaWVzIHRoZSBjb25maWd1cmVkIHdpdGhkcmF3YWwgZmVlIHRvIHRoZSBjb2xsZWN0ZWQgc3dhcCBmZWVzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgdW5jaGFuZ2VkIGJ5IHRoZSBwb3NpdGlvbiBwcm94eS4KLy8gICAtIHBvc2l0aW9uSWQ6IE5GVCB0b2tlbiBJRCB3aG9zZSBhY2NydWVkIHN3YXAgZmVlcyBhcmUgY29sbGVjdGVkCi8vCi8vIFJldHVybnM6Ci8vICAgLSBwb3NpdGlvbklkOiBzYW1lIE5GVCBJRAovLyAgIC0gdG9rZW5zQ29sbGVjdGVkMDogdG9rZW4wIGFtb3VudCBzZW50IHRvIGNhbGxlciBhZnRlciB0aGUgd2l0aGRyYXdhbCBmZWUKLy8gICAtIHRva2Vuc0NvbGxlY3RlZDE6IHRva2VuMSBhbW91bnQgc2VudCB0byBjYWxsZXIgYWZ0ZXIgdGhlIHdpdGhkcmF3YWwgZmVlCi8vICAgLSBwb29sUGF0aDogcG9vbCBpZGVudGlmaWVyCi8vICAgLSB0b3RhbEFtb3VudDA6IHJhdyB0b2tlbjAgYW1vdW50IGNvbGxlY3RlZCBiZWZvcmUgdGhlIHdpdGhkcmF3YWwgZmVlCi8vICAgLSB0b3RhbEFtb3VudDE6IHJhdyB0b2tlbjEgYW1vdW50IGNvbGxlY3RlZCBiZWZvcmUgdGhlIHdpdGhkcmF3YWwgZmVlCi8vCi8vIFJlcXVpcmVtZW50czoKLy8gICAtIENhbGxlciBtdXN0IG93biBhbiB1bnN0YWtlZCBORlQ7IGEgc3Rha2VkIHBvc2l0aW9uIHVzZXMgaXRzIGNvbmZpZ3VyZWQgb3BlcmF0b3IKLy8gICAtIElmIG5vIGZlZXMgYXJlIG93ZWQsIHRoZSBmZWUgYW1vdW50cyByZXR1cm5lZCBhcmUgemVybwpmdW5jIChwICpwb3NpdGlvblYxKSBDb2xsZWN0RmVlKF8gaW50LCBybG0gcmVhbG0sIHBvc2l0aW9uSWQgdWludDY0KSAodWludDY0LCBzdHJpbmcsIHN0cmluZywgc3RyaW5nLCBzdHJpbmcsIHN0cmluZykgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFdpdGhkcmF3KCkKCgljYWxsZXIgOj0gcmxtLlByZXZpb3VzKCkuQWRkcmVzcygpCglhc3NlcnRJc093bmVyT3JPcGVyYXRvckZvclRva2VuKHAsIHBvc2l0aW9uSWQsIGNhbGxlcikKCgllbWlzc2lvbi5NaW50QW5kRGlzdHJpYnV0ZUducyhjcm9zcyhybG0pKQoKCXJldHVybiBwLmNvbGxlY3RGZWUoMCwgcmxtLCBwb3NpdGlvbklkLCBjYWxsZXIpCn0KCi8vIGNvbGxlY3RGZWUgcGVyZm9ybXMgZmVlIGNvbGxlY3Rpb24gYW5kIHdpdGhkcmF3YWwgZmVlIGNhbGN1bGF0aW9uLgpmdW5jIChwICpwb3NpdGlvblYxKSBjb2xsZWN0RmVlKF8gaW50LCBybG0gcmVhbG0sIHBvc2l0aW9uSWQgdWludDY0LCBjYWxsZXIgYWRkcmVzcykgKHVpbnQ2NCwgc3RyaW5nLCBzdHJpbmcsIHN0cmluZywgc3RyaW5nLCBzdHJpbmcpIHsKCS8vIHZlcmlmeSBwb3NpdGlvbgoJcG9zaXRpb24gOj0gcC5tdXN0R2V0UG9zaXRpb24ocG9zaXRpb25JZCkKCXRva2VuMCwgdG9rZW4xLCBmZWUgOj0gc3BsaXRPZihwb3NpdGlvbi5Qb29sS2V5KCkpCgoJcGwuQnVybigKCQljcm9zcyhybG0pLAoJCXRva2VuMCwKCQl0b2tlbjEsCgkJZmVlLAoJCXBvc2l0aW9uLlRpY2tMb3dlcigpLAoJCXBvc2l0aW9uLlRpY2tVcHBlcigpLAoJCSIwIiwgLy8gYnVybiAnMCcgbGlxdWlkaXR5IHRvIGNvbGxlY3QgZmVlCgkJY2FsbGVyLAoJKQoKCWN1cnJlbnRGZWVHcm93dGgsIGVyciA6PSBwLmdldEN1cnJlbnRGZWVHcm93dGgocG9zaXRpb24sIGNhbGxlcikKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbChlcnIuRXJyb3IoKSwgImZhaWxlZCB0byBnZXQgY3VycmVudCBmZWUgZ3Jvd3RoIikpCgl9CgoJdG9rZW5zT3dlZDAsIHRva2Vuc093ZWQxIDo9IHAuY2FsY3VsYXRlRmVlcyhwb3NpdGlvbiwgY3VycmVudEZlZUdyb3d0aCkKCglwb3NpdGlvbi5TZXRGZWVHcm93dGhJbnNpZGUwTGFzdFgxMjgoY3VycmVudEZlZUdyb3d0aC5mZWVHcm93dGhJbnNpZGUwTGFzdFgxMjguVG9TdHJpbmcoKSkKCXBvc2l0aW9uLlNldEZlZUdyb3d0aEluc2lkZTFMYXN0WDEyOChjdXJyZW50RmVlR3Jvd3RoLmZlZUdyb3d0aEluc2lkZTFMYXN0WDEyOC5Ub1N0cmluZygpKQoKCS8vIENvbGxlY3QgdGhlIGZlZS4gVGhlIHBvb2wgd2l0aGhvbGRzIHRoZSB3aXRoZHJhd2FsIGZlZSBhbmQgcGF5cyB0aGUKCS8vIHJlbWFpbmRlciBzdHJhaWdodCB0byB0aGUgY2FsbGVyLgoJYW1vdW50MCwgYW1vdW50MSwgZmVlMFN0ciwgZmVlMVN0ciA6PSBwbC5Db2xsZWN0U3dhcEZlZSgKCQljcm9zcyhybG0pLAoJCXRva2VuMCwgdG9rZW4xLCBmZWUsCgkJY2FsbGVyLAoJCXBvc2l0aW9uLlRpY2tMb3dlcigpLCBwb3NpdGlvbi5UaWNrVXBwZXIoKSwKCQl1dGlscy5Gb3JtYXRJbnQodG9rZW5zT3dlZDApLCB1dGlscy5Gb3JtYXRJbnQodG9rZW5zT3dlZDEpLAoJKQoJYW1vdW50MFVpbnQyNTYgOj0gdTI1Ni5NdXN0RnJvbURlY2ltYWwoYW1vdW50MCkKCWFtb3VudDFVaW50MjU2IDo9IHUyNTYuTXVzdEZyb21EZWNpbWFsKGFtb3VudDEpCglhbW91bnQwSW50NjQgOj0gZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQoYW1vdW50MFVpbnQyNTYpCglhbW91bnQxSW50NjQgOj0gZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQoYW1vdW50MVVpbnQyNTYpCgoJLy8gc29tZXRpbWVzIHRoZXJlIHdpbGwgYmUgYSBmZXcgbGVzcyB1QmFzZSBhbW91bnQgdGhhbiBleHBlY3RlZCBkdWUgdG8gcm91bmRpbmcgZG93biBpbiBjb3JlLCBidXQgd2UganVzdCBzdWJ0cmFjdCB0aGUgZnVsbCBhbW91bnQgZXhwZWN0ZWQKCS8vIGluc3RlYWQgb2YgdGhlIGFjdHVhbCBhbW91bnQgc28gd2UgY2FuIGJ1cm4gdGhlIHRva2VuCglpZiB0b2tlbnNPd2VkMCA8IGFtb3VudDBJbnQ2NCB7CgkJcGFuaWMobmV3RXJyb3JXaXRoRGV0YWlsKGVyclVuZGVyZmxvdywgInRva2Vuc093ZWQwIC0gYW1vdW50MCB1bmRlcmZsb3ciKSkKCX0KCXBvc2l0aW9uLlNldFRva2Vuc093ZWQwKGduc21hdGguU2FmZVN1YkludDY0KHRva2Vuc093ZWQwLCBhbW91bnQwSW50NjQpKQoKCWlmIHRva2Vuc093ZWQxIDwgYW1vdW50MUludDY0IHsKCQlwYW5pYyhuZXdFcnJvcldpdGhEZXRhaWwoZXJyVW5kZXJmbG93LCAidG9rZW5zT3dlZDEgLSBhbW91bnQxIHVuZGVyZmxvdyIpKQoJfQoJcG9zaXRpb24uU2V0VG9rZW5zT3dlZDEoZ25zbWF0aC5TYWZlU3ViSW50NjQodG9rZW5zT3dlZDEsIGFtb3VudDFJbnQ2NCkpCglwLm11c3RVcGRhdGVQb3NpdGlvbigwLCBybG0sIHBvc2l0aW9uSWQsICpwb3NpdGlvbikKCgkvLyBUaGUgcG9vbCBhbHJlYWR5IHBhaWQgdGhlc2Ugb3V0OyByZWNvbXB1dGluZyB0aGVtIGhlcmUgb25seSBmZWVkcyB0aGUKCS8vIGV2ZW50cyBhbmQgdGhlIHJldHVybiB2YWx1ZS4KCWFtb3VudDBXaXRob3V0RmVlU3RyIDo9IHV0aWxzLkZvcm1hdEludChnbnNtYXRoLlNhZmVTdWJJbnQ2NChhbW91bnQwSW50NjQsIHV0aWxzLlNhZmVQYXJzZUludDY0KGZlZTBTdHIpKSkKCWFtb3VudDFXaXRob3V0RmVlU3RyIDo9IHV0aWxzLkZvcm1hdEludChnbnNtYXRoLlNhZmVTdWJJbnQ2NChhbW91bnQxSW50NjQsIHV0aWxzLlNhZmVQYXJzZUludDY0KGZlZTFTdHIpKSkKCglwb29sUGF0aCA6PSBwb3NpdGlvbi5Qb29sS2V5KCkKCglwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgljaGFpbi5FbWl0KAoJCSJDb2xsZWN0U3dhcEZlZSIsCgkJInByZXZBZGRyIiwgcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCSJscFBvc2l0aW9uSWQiLCB1dGlscy5Gb3JtYXRVaW50KHBvc2l0aW9uSWQpLAoJCSJmZWVBbW91bnQwIiwgYW1vdW50MFdpdGhvdXRGZWVTdHIsCgkJImZlZUFtb3VudDEiLCBhbW91bnQxV2l0aG91dEZlZVN0ciwKCQkicG9vbFBhdGgiLCBwb29sUGF0aCwKCQkicG9vbFRpZXIiLCB1dGlscy5Gb3JtYXRVaW50KHN0YWtlci5HZXRQb29sVGllcihwb29sUGF0aCkpLAoJCSJmZWVHcm93dGhJbnNpZGUwTGFzdFgxMjgiLCBwb3NpdGlvbi5GZWVHcm93dGhJbnNpZGUwTGFzdFgxMjgoKSwKCQkiZmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4IiwgcG9zaXRpb24uRmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4KCksCgkpCgoJY2hhaW4uRW1pdCgKCQkiV2l0aGRyYXdhbEZlZSIsCgkJInByZXZBZGRyIiwgcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCSJscFRva2VuSWQiLCB1dGlscy5Gb3JtYXRVaW50KHBvc2l0aW9uSWQpLAoJCSJwb29sUGF0aCIsIHBvb2xQYXRoLAoJCSJmZWVBbW91bnQwIiwgZmVlMFN0ciwKCQkiZmVlQW1vdW50MSIsIGZlZTFTdHIsCgkJImFtb3VudDBXaXRob3V0RmVlIiwgYW1vdW50MFdpdGhvdXRGZWVTdHIsCgkJImFtb3VudDFXaXRob3V0RmVlIiwgYW1vdW50MVdpdGhvdXRGZWVTdHIsCgkpCgoJcmV0dXJuIHBvc2l0aW9uSWQsIGFtb3VudDBXaXRob3V0RmVlU3RyLCBhbW91bnQxV2l0aG91dEZlZVN0ciwgcG9zaXRpb24uUG9vbEtleSgpLCBhbW91bnQwLCBhbW91bnQxCn0KCi8vIFNldFBvc2l0aW9uT3BlcmF0b3Igc2V0cyBhbiBvcGVyYXRvciBmb3IgYSBwb3NpdGlvbi4KLy8gT25seSBzdGFrZXIgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIHVuY2hhbmdlZCBieSB0aGUgcG9zaXRpb24gcHJveHkuCi8vICAgLSBpZDogcG9zaXRpb24gTkZUIElEIHdob3NlIG9wZXJhdG9yIGlzIGNoYW5nZWQKLy8gICAtIG9wZXJhdG9yOiB2YWxpZCBhZGRyZXNzIHRvIGFwcHJvdmUsIG9yIHRoZSBlbXB0eSBhZGRyZXNzIHRvIHJlbW92ZSB0aGUgb3BlcmF0b3IKZnVuYyAocCAqcG9zaXRpb25WMSkgU2V0UG9zaXRpb25PcGVyYXRvcihfIGludCwgcmxtIHJlYWxtLCBpZCB1aW50NjQsIG9wZXJhdG9yIGFkZHJlc3MpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCWFjY2Vzcy5Bc3NlcnRJc1N0YWtlcihwcmV2aW91c1JlYWxtLkFkZHJlc3MoKSkKCglhc3NlcnRWYWxpZE9wZXJhdG9yQWRkcmVzcyhvcGVyYXRvcikKCglwb3NpdGlvbiA6PSBwLm11c3RHZXRQb3NpdGlvbihpZCkKCXByZXZPcGVyYXRvciA6PSBwb3NpdGlvbi5PcGVyYXRvcigpCglwb3NpdGlvbi5TZXRPcGVyYXRvcihvcGVyYXRvcikKCglwLm11c3RVcGRhdGVQb3NpdGlvbigwLCBybG0sIGlkLCAqcG9zaXRpb24pCgoJY2hhaW4uRW1pdCgKCQkiU2V0UG9zaXRpb25PcGVyYXRvciIsCgkJInByZXZBZGRyIiwgcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCSJscFBvc2l0aW9uSWQiLCB1dGlscy5Gb3JtYXRVaW50KGlkKSwKCQkicHJldk9wZXJhdG9yIiwgcHJldk9wZXJhdG9yLlN0cmluZygpLAoJCSJuZXdPcGVyYXRvciIsIG9wZXJhdG9yLlN0cmluZygpLAoJKQp9CgovLyBnZXRDdXJyZW50RmVlR3Jvd3RoIHJldHJpZXZlcyBjdXJyZW50IGZlZSBncm93dGggdmFsdWVzIGZvciBhIHBvc2l0aW9uLgpmdW5jIChwICpwb3NpdGlvblYxKSBnZXRDdXJyZW50RmVlR3Jvd3RoKHBvc2l0aW9uICpwb3MuUG9zaXRpb24sIG93bmVyIGFkZHJlc3MpIChGZWVHcm93dGhJbnNpZGUsIGVycm9yKSB7Cglwb3NpdGlvbktleSA6PSBjb21wdXRlUG9zaXRpb25LZXkocG9zaXRpb24uVGlja0xvd2VyKCksIHBvc2l0aW9uLlRpY2tVcHBlcigpKQoJZmVlR3Jvd3RoSW5zaWRlMExhc3RYMTI4LCBmZWVHcm93dGhJbnNpZGUxTGFzdFgxMjgsIGVyciA6PSBwbC5HZXRQb3NpdGlvbkZlZUdyb3d0aEluc2lkZUxhc3RYMTI4KHBvc2l0aW9uLlBvb2xLZXkoKSwgcG9zaXRpb25LZXkpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gRmVlR3Jvd3RoSW5zaWRle30sIGVycgoJfQoKCWZlZUdyb3d0aEluc2lkZSA6PSBGZWVHcm93dGhJbnNpZGV7CgkJZmVlR3Jvd3RoSW5zaWRlMExhc3RYMTI4OiB1MjU2Lk11c3RGcm9tRGVjaW1hbChmZWVHcm93dGhJbnNpZGUwTGFzdFgxMjgpLAoJCWZlZUdyb3d0aEluc2lkZTFMYXN0WDEyODogdTI1Ni5NdXN0RnJvbURlY2ltYWwoZmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4KSwKCX0KCglyZXR1cm4gZmVlR3Jvd3RoSW5zaWRlLCBuaWwKfQoKLy8gY29tcHV0ZVBvc2l0aW9uS2V5IGdlbmVyYXRlcyBhIGNvbXBhY3QgZGV0ZXJtaW5pc3RpYyBrZXkgZm9yIGEgbGlxdWlkaXR5IHBvc2l0aW9uLgpmdW5jIGNvbXB1dGVQb3NpdGlvbktleSh0aWNrTG93ZXIsIHRpY2tVcHBlciBpbnQzMikgc3RyaW5nIHsKCXJldHVybiBwbC5FbmNvZGVQb3NpdGlvbktleSh0aWNrTG93ZXIsIHRpY2tVcHBlcikKfQoKLy8gY2FsY3VsYXRlUG9zaXRpb25CYWxhbmNlcyBjb21wdXRlcyB0b2tlbiBiYWxhbmNlcyBmb3IgYSBwb3NpdGlvbiBhdCBjdXJyZW50IHByaWNlLgovLyBSZXR1cm5zIGNhbGN1bGF0ZWQgdG9rZW4wIGFuZCB0b2tlbjEgYmFsYW5jZXMgYmFzZWQgb24gcG9zaXRpb24gbGlxdWlkaXR5IGFuZCBwcmljZSByYW5nZS4KZnVuYyBjYWxjdWxhdGVQb3NpdGlvbkJhbGFuY2VzKHBvc2l0aW9uICpwb3MuUG9zaXRpb24pIChpbnQ2NCwgaW50NjQpIHsKCWxpcXVpZGl0eSA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbChwb3NpdGlvbi5MaXF1aWRpdHkoKSkKCWlmIGxpcXVpZGl0eS5Jc1plcm8oKSB7CgkJcmV0dXJuIDAsIDAKCX0KCglzcXJ0UHJpY2VYOTYsIGVyciA6PSBwbC5HZXRTbG90MFNxcnRQcmljZVg5Nihwb3NpdGlvbi5Qb29sS2V5KCkpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9Cgl0b2tlbjBCYWxhbmNlLCB0b2tlbjFCYWxhbmNlIDo9IGduc21hdGguR2V0QW1vdW50c0ZvckxpcXVpZGl0eSgKCQl1MjU2Lk11c3RGcm9tRGVjaW1hbChzcXJ0UHJpY2VYOTYpLCAvLyBjdXJyZW50U3FydFByaWNlWDk2CgkJZ25zbWF0aC5UaWNrTWF0aEdldFNxcnRSYXRpb0F0VGljayhwb3NpdGlvbi5UaWNrTG93ZXIoKSksCgkJZ25zbWF0aC5UaWNrTWF0aEdldFNxcnRSYXRpb0F0VGljayhwb3NpdGlvbi5UaWNrVXBwZXIoKSksCgkJbGlxdWlkaXR5LAoJKQoKCXJldHVybiBnbnNtYXRoLlNhZmVDb252ZXJ0VG9JbnQ2NCh0b2tlbjBCYWxhbmNlKSwgZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQodG9rZW4xQmFsYW5jZSkKfQoaoSkKCnJlbmRlci5nbm8SkilwYWNrYWdlIHBvc2l0aW9uCgppbXBvcnQgKAoJImNoYWluIgoJInN0cmNvbnYiCgkic3RyaW5ncyIKCgkiZ25vLmxhbmQvcC9tb3VsL21kL3YwIgoJImduby5sYW5kL3AvbW91bC9tZHRhYmxlL3YwIgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoKCSJnbm8ubGFuZC9yL2dub3N3YXAvaGFsdC92MSIKCXBvc2l0aW9uUm9vdCAiZ25vLmxhbmQvci9nbm9zd2FwL3Bvc2l0aW9uIgopCgpmdW5jIChwICpwb3NpdGlvblYxKSBSZW5kZXIocGF0aCBzdHJpbmcpIHN0cmluZyB7CglpZiBwYXRoID09ICIiIHsKCQlyZXR1cm4gcC5yZW5kZXJTdW1tYXJ5KCkKCX0KCglwb3NpdGlvbklELCBvayA6PSBwYXJzZVBvc2l0aW9uUmVuZGVyUGF0aChwYXRoKQoJaWYgIW9rIHsKCQlyZXR1cm4gIjQwNFxuIgoJfQoKCXN0b3JlZFBvc2l0aW9uLCBleGlzdHMgOj0gcC5zdG9yZS5HZXRQb3NpdGlvbihwb3NpdGlvbklEKQoJaWYgIWV4aXN0cyB7CgkJcmV0dXJuICI0MDRcbiIKCX0KCglyZXR1cm4gcC5yZW5kZXJQb3NpdGlvbkRldGFpbChwb3NpdGlvbklELCBzdG9yZWRQb3NpdGlvbikKfQoKZnVuYyAocCAqcG9zaXRpb25WMSkgcmVuZGVyU3VtbWFyeSgpIHN0cmluZyB7CglvdXQgOj0gbWQuSDEoIkdub3N3YXAgUG9zaXRpb24iKQoJb3V0ICs9IG1kLlBhcmFncmFwaCgKCQkiUG9zaXRpb24gcmVjb3JkcyByZW1haW4gc3RvcmVkIGFmdGVyIGJ1cm5pbmcuIFRoZSByZWNvcmQgY291bnQgaW5jbHVkZXMgYnVybmVkICIgKwoJCQkicG9zaXRpb25zIGFuZCBpcyBub3QgYSBjb3VudCBvZiBhY3RpdmUgbGlxdWlkaXR5IHBvc2l0aW9ucy4gVXNlICIgKwoJCQltZC5JbmxpbmVDb2RlKCJpZC88aWQ+IikgKyAiIGZvciBvbmUgc3RvcmVkIHJlY29yZCwgZm9yIGV4YW1wbGUgIiArCgkJCW1kLkxpbmsoImlkLzEiLCAiL3IvZ25vc3dhcC9wb3NpdGlvbjppZC8xIikgKwoJCQkiLiBUaGUgZGV0YWlsIHJvdXRlIHBlcmZvcm1zIG9uZSBrZXllZCBsb29rdXAgYW5kIGRvZXMgbm90IGVudW1lcmF0ZSBwb3NpdGlvbnMgb3IgcmVjb21wdXRlIGNsYWltYWJsZSB2YWx1ZXMuIiwKCSkKCXJ1bnRpbWVUYWJsZSA6PSBtZHRhYmxlLlRhYmxlewoJCUhlYWRlcnM6IFtdc3RyaW5neyJGaWVsZCIsICJWYWx1ZSJ9LAoJCVJvd3M6IFtdW11zdHJpbmd7CgkJCXsiUmVhbG0gYWRkcmVzcyIsIG1kLklubGluZUNvZGUoY2hhaW4uUGFja2FnZUFkZHJlc3MoImduby5sYW5kL3IvZ25vc3dhcC9wb3NpdGlvbiIpLlN0cmluZygpKX0sCgkJCXsiQWN0aXZlIGltcGxlbWVudGF0aW9uIiwgcmVuZGVyUGFja2FnZUxpbmsocG9zaXRpb25Sb290LkdldEltcGxlbWVudGF0aW9uUGFja2FnZVBhdGgoKSl9LAoJCQl7IlBvc2l0aW9uIG9wZXJhdGlvbnMgaGFsdGVkIiwgdWZtdC5TcHJpbnRmKCIldCIsIGhhbHQuSXNIYWx0ZWRQb3NpdGlvbigpKX0sCgkJCXsiV2l0aGRyYXdhbHMgaGFsdGVkIiwgdWZtdC5TcHJpbnRmKCIldCIsIGhhbHQuSXNIYWx0ZWRXaXRoZHJhdygpKX0sCgkJfSwKCX0KCW91dCArPSBtZC5IMigiUnVudGltZSIpICsgcnVudGltZVRhYmxlLlN0cmluZygpCgoJcmVjb3JkcyA6PSBtZHRhYmxlLlRhYmxlewoJCUhlYWRlcnM6IFtdc3RyaW5neyJGaWVsZCIsICJWYWx1ZSJ9LAoJCVJvd3M6IFtdW11zdHJpbmd7CgkJCXsiU3RvcmVkIHBvc2l0aW9uIHJlY29yZHMgKGluY2x1ZGluZyBidXJuZWQpIiwgdWZtdC5TcHJpbnRmKCIlZCIsIHAuc3RvcmUuR2V0UG9zaXRpb25zKCkuU2l6ZSgpKX0sCgkJCXsiTmV4dCBwb3NpdGlvbiBJRCIsIHVmbXQuU3ByaW50ZigiJWQiLCBwLnN0b3JlLkdldFBvc2l0aW9uTmV4dElEKCkpfSwKCQl9LAoJfQoJcmV0dXJuIG91dCArIG1kLkgyKCJTdG9yZWQgcmVjb3JkcyIpICsgcmVjb3Jkcy5TdHJpbmcoKQp9CgpmdW5jIChwICpwb3NpdGlvblYxKSByZW5kZXJQb3NpdGlvbkRldGFpbChwb3NpdGlvbklEIHVpbnQ2NCwgc3RvcmVkIHBvc2l0aW9uUm9vdC5Qb3NpdGlvbikgc3RyaW5nIHsKCXN0YXR1cyA6PSAiQWN0aXZlIgoJaWYgc3RvcmVkLkJ1cm5lZCgpIHsKCQlzdGF0dXMgPSAiQnVybmVkIChyZWNvcmQgcmV0YWluZWQpIgoJfQoKCW93bmVyIDo9ICJ1bmF2YWlsYWJsZSIKCW93bmVyQWRkcmVzcywgZXJyIDo9IHAubmZ0QWNjZXNzb3IuT3duZXJPZihwb3NpdGlvbklkRnJvbShwb3NpdGlvbklEKSkKCWlmIGVyciA9PSBuaWwgJiYgb3duZXJBZGRyZXNzICE9ICIiIHsKCQlvd25lciA9IG93bmVyQWRkcmVzcy5TdHJpbmcoKQoJfQoKCXRva2VuMCwgdG9rZW4xLCBwb29sRmVlLCB2YWxpZFBvb2xLZXkgOj0gc3BsaXRQb29sS2V5Rm9yUmVuZGVyKHN0b3JlZC5Qb29sS2V5KCkpCgl0b2tlbjBSZWZlcmVuY2UgOj0gInVuYXZhaWxhYmxlIChzdG9yZWQgcG9vbCBrZXkgaXMgbm90IHRva2VuMDp0b2tlbjE6ZmVlKSIKCXRva2VuMVJlZmVyZW5jZSA6PSB0b2tlbjBSZWZlcmVuY2UKCWlmIHZhbGlkUG9vbEtleSB7CgkJdG9rZW4wUmVmZXJlbmNlID0gcmVuZGVyUGFja2FnZUxpbmsodG9rZW4wKQoJCXRva2VuMVJlZmVyZW5jZSA9IHJlbmRlclBhY2thZ2VMaW5rKHRva2VuMSkKCX0KCglvdXQgOj0gbWQuSDEodWZtdC5TcHJpbnRmKCJHbm9zd2FwIFBvc2l0aW9uICVkIiwgcG9zaXRpb25JRCkpCglvdXQgKz0gbWQuUGFyYWdyYXBoKAoJCSJUaGlzIHBhZ2UgcmVhZHMgb25lIHBlcnNpc3RlZCBwb3NpdGlvbiByZWNvcmQuIFN0b3JlZCBhY2NvdW50aW5nIGZpZWxkcyBhcmUgIiArCgkJCSJzaG93biBhcyBzdG9yZWQ7IGNsYWltYWJsZSBmZWVzIGFuZCBjdXJyZW50IHRva2VuIGJhbGFuY2VzIGFyZSByZWNvbXB1dGVkICIgKwoJCQkidmFsdWVzIGFuZCBhcmUgaW50ZW50aW9uYWxseSBub3QgcXVlcmllZCBoZXJlLiIsCgkpCglpZGVudGl0eSA6PSBtZHRhYmxlLlRhYmxlewoJCUhlYWRlcnM6IFtdc3RyaW5neyJGaWVsZCIsICJWYWx1ZSJ9LAoJCVJvd3M6IFtdW11zdHJpbmd7CgkJCXsiUG9zaXRpb24gSUQiLCB1Zm10LlNwcmludGYoIiVkIiwgcG9zaXRpb25JRCl9LAoJCQl7IlN0YXR1cyIsIHN0YXR1c30sCgkJCXsiT3duZXIiLCBvd25lcn0sCgkJfSwKCX0KCW91dCArPSBtZC5IMigiSWRlbnRpdHkiKSArIGlkZW50aXR5LlN0cmluZygpCgoJcG9vbEFuZFJhbmdlIDo9IG1kdGFibGUuVGFibGV7CgkJSGVhZGVyczogW11zdHJpbmd7IkZpZWxkIiwgIlZhbHVlIn0sCgkJUm93czogW11bXXN0cmluZ3sKCQkJeyJQb29sIGtleSIsIG1kLklubGluZUNvZGUoc3RvcmVkLlBvb2xLZXkoKSl9LAoJCQl7IlRva2VuIDAgcmVmZXJlbmNlIiwgdG9rZW4wUmVmZXJlbmNlfSwKCQkJeyJUb2tlbiAxIHJlZmVyZW5jZSIsIHRva2VuMVJlZmVyZW5jZX0sCgkJCXsiUG9vbCBmZWUgKGZyb20gc3RvcmVkIGtleSkiLCBwb29sRmVlfSwKCQkJeyJMb3dlciB0aWNrIChzdG9yZWQpIiwgdWZtdC5TcHJpbnRmKCIlZCIsIHN0b3JlZC5UaWNrTG93ZXIoKSl9LAoJCQl7IlVwcGVyIHRpY2sgKHN0b3JlZCkiLCB1Zm10LlNwcmludGYoIiVkIiwgc3RvcmVkLlRpY2tVcHBlcigpKX0sCgkJfSwKCX0KCW91dCArPSBtZC5IMigiUG9vbCBhbmQgcmFuZ2UiKSArIHBvb2xBbmRSYW5nZS5TdHJpbmcoKQoKCWFjY291bnRpbmcgOj0gbWR0YWJsZS5UYWJsZXsKCQlIZWFkZXJzOiBbXXN0cmluZ3siRmllbGQiLCAiVmFsdWUifSwKCQlSb3dzOiBbXVtdc3RyaW5newoJCQl7IkxpcXVpZGl0eSAoc3RvcmVkKSIsIHN0b3JlZC5MaXF1aWRpdHkoKX0sCgkJCXsiRmVlIGdyb3d0aCB0b2tlbiAwIGluc2lkZSwgbGFzdCBYMTI4IChzdG9yZWQpIiwgc3RvcmVkLkZlZUdyb3d0aEluc2lkZTBMYXN0WDEyOCgpfSwKCQkJeyJGZWUgZ3Jvd3RoIHRva2VuIDEgaW5zaWRlLCBsYXN0IFgxMjggKHN0b3JlZCkiLCBzdG9yZWQuRmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4KCl9LAoJCQl7IlRva2VuIDAgb3dlZCAoc3RvcmVkIGFjY291bnRpbmcpIiwgdWZtdC5TcHJpbnRmKCIlZCIsIHN0b3JlZC5Ub2tlbnNPd2VkMCgpKX0sCgkJCXsiVG9rZW4gMSBvd2VkIChzdG9yZWQgYWNjb3VudGluZykiLCB1Zm10LlNwcmludGYoIiVkIiwgc3RvcmVkLlRva2Vuc093ZWQxKCkpfSwKCQkJeyJDbGFpbWFibGUgZmVlcyAvIGN1cnJlbnQgdG9rZW4gYmFsYW5jZXMiLCAiTm90IHJlbmRlcmVkOyB3b3VsZCByZXF1aXJlIHJlY29tcHV0YXRpb24ifSwKCQl9LAoJfQoJcmV0dXJuIG91dCArIG1kLkgyKCJTdG9yZWQgYWNjb3VudGluZyIpICsgYWNjb3VudGluZy5TdHJpbmcoKQp9CgpmdW5jIHBhcnNlUG9zaXRpb25SZW5kZXJQYXRoKHBhdGggc3RyaW5nKSAodWludDY0LCBib29sKSB7Cgljb25zdCBwcmVmaXggPSAiaWQvIgoJaWYgbGVuKHBhdGgpIDw9IGxlbihwcmVmaXgpIHx8IHBhdGhbOmxlbihwcmVmaXgpXSAhPSBwcmVmaXggewoJCXJldHVybiAwLCBmYWxzZQoJfQoKCWlkIDo9IHBhdGhbbGVuKHByZWZpeCk6XQoJZm9yIGkgOj0gMDsgaSA8IGxlbihpZCk7IGkrKyB7CgkJaWYgaWRbaV0gPCAnMCcgfHwgaWRbaV0gPiAnOScgewoJCQlyZXR1cm4gMCwgZmFsc2UKCQl9Cgl9CgoJcG9zaXRpb25JRCwgZXJyIDo9IHN0cmNvbnYuUGFyc2VVaW50KGlkLCAxMCwgNjQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZmFsc2UKCX0KCglyZXR1cm4gcG9zaXRpb25JRCwgdHJ1ZQp9CgpmdW5jIHNwbGl0UG9vbEtleUZvclJlbmRlcihwb29sS2V5IHN0cmluZykgKHN0cmluZywgc3RyaW5nLCBzdHJpbmcsIGJvb2wpIHsKCXBhcnRzIDo9IHN0cmluZ3MuU3BsaXQocG9vbEtleSwgIjoiKQoJaWYgbGVuKHBhcnRzKSAhPSAzIHx8IHBhcnRzWzBdID09ICIiIHx8IHBhcnRzWzFdID09ICIiIHx8IHBhcnRzWzJdID09ICIiIHsKCQlyZXR1cm4gIiIsICIiLCAiIiwgZmFsc2UKCX0KCglyZXR1cm4gcGFydHNbMF0sIHBhcnRzWzFdLCBwYXJ0c1syXSwgdHJ1ZQp9CgpmdW5jIHJlbmRlclBhY2thZ2VMaW5rKHBhdGggc3RyaW5nKSBzdHJpbmcgewoJaWYgc3RyaW5ncy5IYXNQcmVmaXgocGF0aCwgImduby5sYW5kLyIpIHsKCQlkZXN0aW5hdGlvbiA6PSBzdHJpbmdzLlRyaW1QcmVmaXgocGF0aCwgImduby5sYW5kIikKCQkvLyBUb2tlbiByZWZlcmVuY2VzIGFwcGVuZCAuU1lNQk9MOyBsaW5rIHRvIHRoZSBkZWZpbmluZyByZWFsbS4KCQlpZiBzZXBhcmF0b3IgOj0gc3RyaW5ncy5JbmRleChkZXN0aW5hdGlvbiwgIi4iKTsgc2VwYXJhdG9yID49IDAgewoJCQlkZXN0aW5hdGlvbiA9IGRlc3RpbmF0aW9uWzpzZXBhcmF0b3JdCgkJfQoJCXJldHVybiBtZC5MaW5rKHBhdGgsIGRlc3RpbmF0aW9uKQoJfQoKCXJldHVybiBtZC5JbmxpbmVDb2RlKHBhdGgpCn0KGpsrCg5yZXBvc2l0aW9uLmdubxKIK3BhY2thZ2UgcG9zaXRpb24KCmltcG9ydCAoCgkiY2hhaW4iCgoJImduby5sYW5kL3IvZ25vc3dhcC9hY2Nlc3MvdjEiCgoJdTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL3VpbnQyNTYvdjEiCgkiZ25vLmxhbmQvcC9nbm9zd2FwL3V0aWxzL3YxIgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoKCSJnbm8ubGFuZC9yL2dub3N3YXAvY29tbW9uIgoJImduby5sYW5kL3IvZ25vc3dhcC9lbWlzc2lvbiIKCSJnbm8ubGFuZC9yL2dub3N3YXAvaGFsdC92MSIKKQoKLy8gUmVwb3NpdGlvbiBhZGp1c3RzIHRoZSBwcmljZSByYW5nZSBhbmQgbGlxdWlkaXR5IG9mIGFuIGV4aXN0aW5nIHBvc2l0aW9uLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogbGVhZGluZyBpbnRlZ2VyIGRpc2NyaW1pbmF0b3I7IGNhbGxlcnMgcGFzcyAwCi8vICAgLSBybG06IGN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgZnJvbSB0aGUgcHVibGljIHdyYXBwZXI7IHRoZSBpbXBsZW1lbnRhdGlvbiB2YWxpZGF0ZXMgaXQgYXMgY3VycmVudAovLyAgIC0gcG9zaXRpb25JZDogTkZUIHRva2VuIElEIHRvIHJlcG9zaXRpb24KLy8gICAtIHRpY2tMb3dlcjogbmV3IGxvd2VyIHRpY2sgYm91bmRhcnkgb2YgdGhlIHBvc2l0aW9uJ3MgcHJpY2UgcmFuZ2UKLy8gICAtIHRpY2tVcHBlcjogbmV3IHVwcGVyIHRpY2sgYm91bmRhcnkgb2YgdGhlIHBvc2l0aW9uJ3MgcHJpY2UgcmFuZ2UKLy8gICAtIGFtb3VudDBEZXNpcmVkU3RyOiBkZXNpcmVkIHRva2VuMCBhbW91bnQgZm9yIHRoZSBuZXcgcG9zaXRpb24sIHJlcHJlc2VudGVkIGFzIGEgZGVjaW1hbCBzdHJpbmcKLy8gICAtIGFtb3VudDFEZXNpcmVkU3RyOiBkZXNpcmVkIHRva2VuMSBhbW91bnQgZm9yIHRoZSBuZXcgcG9zaXRpb24sIHJlcHJlc2VudGVkIGFzIGEgZGVjaW1hbCBzdHJpbmcKLy8gICAtIGFtb3VudDBNaW5TdHI6IG1pbmltdW0gYWNjZXB0YWJsZSB0b2tlbjAgYW1vdW50IGZvciBzbGlwcGFnZSBwcm90ZWN0aW9uCi8vICAgLSBhbW91bnQxTWluU3RyOiBtaW5pbXVtIGFjY2VwdGFibGUgdG9rZW4xIGFtb3VudCBmb3Igc2xpcHBhZ2UgcHJvdGVjdGlvbgovLyAgIC0gZGVhZGxpbmU6IHRyYW5zYWN0aW9uIGV4cGlyYXRpb24gdGltZXN0YW1wCi8vCi8vIFJldHVybnM6Ci8vICAgLSBwb3NpdGlvbklkOiBORlQgdG9rZW4gSUQgdGhhdCB3YXMgcmVwb3NpdGlvbmVkCi8vICAgLSBsaXF1aWRpdHk6IG5ldyBsaXF1aWRpdHkgYW1vdW50LCByZXByZXNlbnRlZCBhcyBhIGRlY2ltYWwgc3RyaW5nCi8vICAgLSB0aWNrTG93ZXI6IGxvd2VyIHRpY2sgYm91bmRhcnkgYXBwbGllZCB0byB0aGUgcG9zaXRpb24KLy8gICAtIHRpY2tVcHBlcjogdXBwZXIgdGljayBib3VuZGFyeSBhcHBsaWVkIHRvIHRoZSBwb3NpdGlvbgovLyAgIC0gYW1vdW50MDogYWN0dWFsIHRva2VuMCBhbW91bnQgYWRkZWQgdG8gdGhlIG5ldyByYW5nZSwgcmVwcmVzZW50ZWQgYXMgYSBkZWNpbWFsIHN0cmluZwovLyAgIC0gYW1vdW50MTogYWN0dWFsIHRva2VuMSBhbW91bnQgYWRkZWQgdG8gdGhlIG5ldyByYW5nZSwgcmVwcmVzZW50ZWQgYXMgYSBkZWNpbWFsIHN0cmluZwpmdW5jIChwICpwb3NpdGlvblYxKSBSZXBvc2l0aW9uKAoJXyBpbnQsCglybG0gcmVhbG0sCglwb3NpdGlvbklkIHVpbnQ2NCwKCXRpY2tMb3dlciBpbnQzMiwKCXRpY2tVcHBlciBpbnQzMiwKCWFtb3VudDBEZXNpcmVkU3RyIHN0cmluZywKCWFtb3VudDFEZXNpcmVkU3RyIHN0cmluZywKCWFtb3VudDBNaW5TdHIgc3RyaW5nLAoJYW1vdW50MU1pblN0ciBzdHJpbmcsCglkZWFkbGluZSBpbnQ2NCwKKSAodWludDY0LCBzdHJpbmcsIGludDMyLCBpbnQzMiwgc3RyaW5nLCBzdHJpbmcpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRQb3NpdGlvbigpCgoJcHJldmlvdXNSZWFsbSA6PSBybG0uUHJldmlvdXMoKQoJY2FsbGVyIDo9IHByZXZpb3VzUmVhbG0uQWRkcmVzcygpCglhc3NlcnRJc093bmVyRm9yVG9rZW4ocCwgcG9zaXRpb25JZCwgY2FsbGVyKQoJYXNzZXJ0SXNOb3RFeHBpcmVkKGRlYWRsaW5lKQoKCWVtaXNzaW9uLk1pbnRBbmREaXN0cmlidXRlR25zKGNyb3NzKHJsbSkpCgoJLy8gVGhlIHBvc2l0aW9uIG11c3QgYmUgY2xlYXIgKHplcm8gbGlxdWlkaXR5IGFuZCB6ZXJvIHRva2VucyBvd2VkKSBiZWZvcmUKCS8vIGl0IGNhbiBiZSByZXBvc2l0aW9uZWQuCglwb3NpdGlvbiA6PSBwLm11c3RHZXRQb3NpdGlvbihwb3NpdGlvbklkKQoKCXRva2VuMCwgdG9rZW4xLCBfIDo9IHNwbGl0T2YocG9zaXRpb24uUG9vbEtleSgpKQoJY29tbW9uLkFzc2VydElzTm90SGFuZGxlTmF0aXZlQ29pbigpCgoJb2xkVGlja0xvd2VyIDo9IHBvc2l0aW9uLlRpY2tMb3dlcigpCglvbGRUaWNrVXBwZXIgOj0gcG9zaXRpb24uVGlja1VwcGVyKCkKCglpZiAhcG9zaXRpb24uSXNDbGVhcigpIHsKCQlwYW5pYyhuZXdFcnJvcldpdGhEZXRhaWwoCgkJCWVyck5vdENsZWFyLAoJCQl1Zm10LlNwcmludGYoCgkJCQkicG9zaXRpb24oJWQpIGlzbid0IGNsZWFyKGxpcXVpZGl0eTolcywgdG9rZW5zT3dlZDA6JWQsIHRva2Vuc093ZWQxOiVkKSIsCgkJCQlwb3NpdGlvbklkLAoJCQkJcG9zaXRpb24uTGlxdWlkaXR5KCksCgkJCQlwb3NpdGlvbi5Ub2tlbnNPd2VkMCgpLAoJCQkJcG9zaXRpb24uVG9rZW5zT3dlZDEoKSwKCQkJKSwKCQkpKQoJfQoKCWlmIGVyciA6PSB2YWxpZGF0ZVRva2VuUGF0aCh0b2tlbjAsIHRva2VuMSk7IGVyciAhPSBuaWwgewoJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbChlcnIuRXJyb3IoKSwgdWZtdC5TcHJpbnRmKCJ0b2tlbjAoJXMpLCB0b2tlbjEoJXMpIiwgdG9rZW4wLCB0b2tlbjEpKSkKCX0KCglwb29sS2V5IDo9IHBvc2l0aW9uLlBvb2xLZXkoKQoKCWxpcXVpZGl0eSwgYW1vdW50MCwgYW1vdW50MSA6PSBwLmFkZExpcXVpZGl0eSgKCQkwLAoJCXJsbSwKCQlBZGRMaXF1aWRpdHlQYXJhbXN7CgkJCXBvb2xLZXk6ICAgICAgICBwb29sS2V5LAoJCQl0aWNrTG93ZXI6ICAgICAgdGlja0xvd2VyLAoJCQl0aWNrVXBwZXI6ICAgICAgdGlja1VwcGVyLAoJCQlhbW91bnQwRGVzaXJlZDogdTI1Ni5NdXN0RnJvbURlY2ltYWwoYW1vdW50MERlc2lyZWRTdHIpLAoJCQlhbW91bnQxRGVzaXJlZDogdTI1Ni5NdXN0RnJvbURlY2ltYWwoYW1vdW50MURlc2lyZWRTdHIpLAoJCQlhbW91bnQwTWluOiAgICAgdTI1Ni5NdXN0RnJvbURlY2ltYWwoYW1vdW50ME1pblN0ciksCgkJCWFtb3VudDFNaW46ICAgICB1MjU2Lk11c3RGcm9tRGVjaW1hbChhbW91bnQxTWluU3RyKSwKCQkJY2FsbGVyOiAgICAgICAgIGNhbGxlciwKCQl9LAoJKQoKCS8vIHVwZGF0ZSBwb3NpdGlvbiB0aWNrTG93ZXIsIHRpY2tVcHBlciB0byBuZXcgdmFsdWUKCS8vIGJlY2F1c2UgZ2V0Q3VycmVudEZlZUdyb3d0aCgpIHVzZXMgdGlja0xvd2VyLCB0aWNrVXBwZXIKCXBvc2l0aW9uLlNldFRpY2tMb3dlcih0aWNrTG93ZXIpCglwb3NpdGlvbi5TZXRUaWNrVXBwZXIodGlja1VwcGVyKQoKCWN1cnJlbnRGZWVHcm93dGgsIGVyciA6PSBwLmdldEN1cnJlbnRGZWVHcm93dGgocG9zaXRpb24sIGNhbGxlcikKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKG5ld0Vycm9yV2l0aERldGFpbChlcnIuRXJyb3IoKSwgImZhaWxlZCB0byBnZXQgY3VycmVudCBmZWUgZ3Jvd3RoIikpCgl9Cglwb3NpdGlvbi5TZXRGZWVHcm93dGhJbnNpZGUwTGFzdFgxMjgoY3VycmVudEZlZUdyb3d0aC5mZWVHcm93dGhJbnNpZGUwTGFzdFgxMjguVG9TdHJpbmcoKSkKCXBvc2l0aW9uLlNldEZlZUdyb3d0aEluc2lkZTFMYXN0WDEyOChjdXJyZW50RmVlR3Jvd3RoLmZlZUdyb3d0aEluc2lkZTFMYXN0WDEyOC5Ub1N0cmluZygpKQoKCXBvc2l0aW9uLlNldExpcXVpZGl0eShsaXF1aWRpdHkuVG9TdHJpbmcoKSkKCgkvLyBEbyBub3QgcmVzZXQgdGhlIGZlZS1ncm93dGggY2hlY2twb2ludHM6IGEgZnVsbCBkZWNyZWFzZSBmb2xsb3dlZCBieQoJLy8gcmVwb3NpdGlvbmluZyBtdXN0IG5vdCBjcmVhdGUgYW4gdW5pbnRlbmRlZCB1bmNsYWltZWQtZmVlIGJhbGFuY2UuCglwb3NpdGlvbi5TZXRUb2tlbnNPd2VkMCgwKQoJcG9zaXRpb24uU2V0VG9rZW5zT3dlZDEoMCkKCXBvc2l0aW9uLlNldEJ1cm5lZChmYWxzZSkKCXAubXVzdFVwZGF0ZVBvc2l0aW9uKDAsIHJsbSwgcG9zaXRpb25JZCwgKnBvc2l0aW9uKQoKCXBvb2wgOj0gbXVzdEdldFBvb2wocG9vbEtleSkKCXBvc2l0aW9uTGlxdWlkaXR5LCBlcnIgOj0gcC5HZXRQb3NpdGlvbkxpcXVpZGl0eShwb3NpdGlvbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoJdGlja0N1bXVsYXRpdmUsIHNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOCwgb2JzZXJ2YXRpb25UaW1lc3RhbXAsIGVyciA6PSBjdXJyZW50UG9vbE9ic2VydmF0aW9uKHBvb2xLZXkpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJY2hhaW4uRW1pdCgKCQkiUmVwb3NpdGlvbiIsCgkJInByZXZBZGRyIiwgcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCSJscFBvc2l0aW9uSWQiLCB1dGlscy5Gb3JtYXRVaW50KHBvc2l0aW9uSWQpLAoJCSJ0aWNrTG93ZXIiLCB1dGlscy5Gb3JtYXRJbnQodGlja0xvd2VyKSwKCQkidGlja1VwcGVyIiwgdXRpbHMuRm9ybWF0SW50KHRpY2tVcHBlciksCgkJImxpcXVpZGl0eURlbHRhIiwgbGlxdWlkaXR5LlRvU3RyaW5nKCksCgkJImFtb3VudDAiLCBhbW91bnQwLlRvU3RyaW5nKCksCgkJImFtb3VudDEiLCBhbW91bnQxLlRvU3RyaW5nKCksCgkJInByZXZUaWNrTG93ZXIiLCB1dGlscy5Gb3JtYXRJbnQob2xkVGlja0xvd2VyKSwKCQkicHJldlRpY2tVcHBlciIsIHV0aWxzLkZvcm1hdEludChvbGRUaWNrVXBwZXIpLAoJCSJwb29sUGF0aCIsIHBvb2xLZXksCgkJInNxcnRQcmljZVg5NiIsIHBvb2wuU2xvdDBTcXJ0UHJpY2VYOTYoKS5Ub1N0cmluZygpLAoJCSJwb3NpdGlvbkxpcXVpZGl0eSIsIHBvc2l0aW9uTGlxdWlkaXR5LAoJCSJwb29sTGlxdWlkaXR5IiwgcG9vbC5MaXF1aWRpdHkoKS5Ub1N0cmluZygpLAoJCSJ0b2tlbjBCYWxhbmNlIiwgdXRpbHMuRm9ybWF0SW50KHBvb2wuQmFsYW5jZVRva2VuMCgpKSwKCQkidG9rZW4xQmFsYW5jZSIsIHV0aWxzLkZvcm1hdEludChwb29sLkJhbGFuY2VUb2tlbjEoKSksCgkJInRpY2tDdW11bGF0aXZlIiwgdXRpbHMuRm9ybWF0SW50KHRpY2tDdW11bGF0aXZlKSwKCQkic2Vjb25kc1BlckxpcXVpZGl0eUN1bXVsYXRpdmVYMTI4Iiwgc2Vjb25kc1BlckxpcXVpZGl0eUN1bXVsYXRpdmVYMTI4LAoJCSJvYnNlcnZhdGlvblRpbWVzdGFtcCIsIHV0aWxzLkZvcm1hdEludChvYnNlcnZhdGlvblRpbWVzdGFtcCksCgkpCgoJcmV0dXJuIHBvc2l0aW9uSWQsIGxpcXVpZGl0eS5Ub1N0cmluZygpLCB0aWNrTG93ZXIsIHRpY2tVcHBlciwgYW1vdW50MC5Ub1N0cmluZygpLCBhbW91bnQxLlRvU3RyaW5nKCkKfQoavxsKCHR5cGUuZ25vErIbcGFja2FnZSBwb3NpdGlvbgoKaW1wb3J0ICgKCXUyNTYgImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgopCgovLyBQcmV2aW91c2x5LCB3ZSB1c2VkIGEgZGlmZmVyZW50IHplcm8gYWRkcmVzcyAoImcxMDAwMDAwLi4uIiksCi8vIGJ1dCB3ZSBjaGFuZ2VkIHRoZSB2YWx1ZSBiZWNhdXNlIHVzaW5nIHRoZSBhZGRyZXNzCi8vIGJlbG93IGFwcGVhcnMgdG8gaGF2ZSBiZWNvbWUgdGhlIGRlIGZhY3RvIHN0YW5kYXJkIHByYWN0aWNlLgpjb25zdCB6ZXJvQWRkcmVzcyBhZGRyZXNzID0gYWRkcmVzcygiIikKCnR5cGUgTWludFBhcmFtcyBzdHJ1Y3QgewoJdG9rZW4wICAgICAgICAgc3RyaW5nICAgICAvLyB0b2tlbjAgcGF0aCBmb3IgYSBzcGVjaWZpYyBwb29sCgl0b2tlbjEgICAgICAgICBzdHJpbmcgICAgIC8vIHRva2VuMSBwYXRoIGZvciBhIHNwZWNpZmljIHBvb2wKCWZlZSAgICAgICAgICAgIHVpbnQzMiAgICAgLy8gZmVlIGZvciBhIHNwZWNpZmljIHBvb2wKCXRpY2tMb3dlciAgICAgIGludDMyICAgICAgLy8gbG93ZXIgZW5kIG9mIHRoZSB0aWNrIHJhbmdlIGZvciB0aGUgcG9zaXRpb24KCXRpY2tVcHBlciAgICAgIGludDMyICAgICAgLy8gdXBwZXIgZW5kIG9mIHRoZSB0aWNrIHJhbmdlIGZvciB0aGUgcG9zaXRpb24KCWFtb3VudDBEZXNpcmVkICp1MjU2LlVpbnQgLy8gZGVzaXJlZCBhbW91bnQgb2YgdG9rZW4wIHRvIGJlIG1pbnRlZAoJYW1vdW50MURlc2lyZWQgKnUyNTYuVWludCAvLyBkZXNpcmVkIGFtb3VudCBvZiB0b2tlbjEgdG8gYmUgbWludGVkCglhbW91bnQwTWluICAgICAqdTI1Ni5VaW50IC8vIG1pbmltdW0gYW1vdW50IG9mIHRva2VuMCB0byBiZSBtaW50ZWQKCWFtb3VudDFNaW4gICAgICp1MjU2LlVpbnQgLy8gbWluaW11bSBhbW91bnQgb2YgdG9rZW4xIHRvIGJlIG1pbnRlZAoJZGVhZGxpbmUgICAgICAgaW50NjQgICAgICAvLyB0aW1lIGJ5IHdoaWNoIHRoZSB0cmFuc2FjdGlvbiBtdXN0IGJlIGluY2x1ZGVkIHRvIGVmZmVjdCB0aGUgY2hhbmdlCgltaW50VG8gICAgICAgICBhZGRyZXNzICAgIC8vIGFkZHJlc3MgdG8gbWludCBscFRva2VuCgljYWxsZXIgICAgICAgICBhZGRyZXNzICAgIC8vIGFkZHJlc3MgdG8gY2FsbCB0aGUgZnVuY3Rpb24KfQoKLy8gbmV3TWludFBhcmFtcyBjcmVhdGVzIGBNaW50UGFyYW1zYCBmcm9tIHByb2Nlc3NlZCBpbnB1dCBkYXRhLgpmdW5jIG5ld01pbnRQYXJhbXMoaW5wdXQgUHJvY2Vzc2VkTWludElucHV0LCBtaW50SW5wdXQgTWludElucHV0KSBNaW50UGFyYW1zIHsKCXJldHVybiBNaW50UGFyYW1zewoJCXRva2VuMDogICAgICAgICBpbnB1dC50b2tlblBhaXIudG9rZW4wLAoJCXRva2VuMTogICAgICAgICBpbnB1dC50b2tlblBhaXIudG9rZW4xLAoJCWZlZTogICAgICAgICAgICBtaW50SW5wdXQuZmVlLAoJCXRpY2tMb3dlcjogICAgICBpbnB1dC50aWNrTG93ZXIsCgkJdGlja1VwcGVyOiAgICAgIGlucHV0LnRpY2tVcHBlciwKCQlhbW91bnQwRGVzaXJlZDogaW5wdXQuYW1vdW50MERlc2lyZWQsCgkJYW1vdW50MURlc2lyZWQ6IGlucHV0LmFtb3VudDFEZXNpcmVkLAoJCWFtb3VudDBNaW46ICAgICBpbnB1dC5hbW91bnQwTWluLAoJCWFtb3VudDFNaW46ICAgICBpbnB1dC5hbW91bnQxTWluLAoJCWRlYWRsaW5lOiAgICAgICBtaW50SW5wdXQuZGVhZGxpbmUsCgkJbWludFRvOiAgICAgICAgIG1pbnRJbnB1dC5taW50VG8sCgkJY2FsbGVyOiAgICAgICAgIG1pbnRJbnB1dC5jYWxsZXIsCgl9Cn0KCnR5cGUgSW5jcmVhc2VMaXF1aWRpdHlQYXJhbXMgc3RydWN0IHsKCXBvc2l0aW9uSWQgICAgIHVpbnQ2NCAgICAgLy8gcG9zaXRpb25JZCBvZiB0aGUgcG9zaXRpb24gdG8gaW5jcmVhc2UgbGlxdWlkaXR5CglhbW91bnQwRGVzaXJlZCAqdTI1Ni5VaW50IC8vIGRlc2lyZWQgYW1vdW50IG9mIHRva2VuMCB0byBiZSBtaW50ZWQKCWFtb3VudDFEZXNpcmVkICp1MjU2LlVpbnQgLy8gZGVzaXJlZCBhbW91bnQgb2YgdG9rZW4xIHRvIGJlIG1pbnRlZAoJYW1vdW50ME1pbiAgICAgKnUyNTYuVWludCAvLyBtaW5pbXVtIGFtb3VudCBvZiB0b2tlbjAgdG8gYmUgbWludGVkCglhbW91bnQxTWluICAgICAqdTI1Ni5VaW50IC8vIG1pbmltdW0gYW1vdW50IG9mIHRva2VuMSB0byBiZSBtaW50ZWQKCWRlYWRsaW5lICAgICAgIGludDY0ICAgICAgLy8gdGltZSBieSB3aGljaCB0aGUgdHJhbnNhY3Rpb24gbXVzdCBiZSBpbmNsdWRlZCB0byBlZmZlY3QgdGhlIGNoYW5nZQoJY2FsbGVyICAgICAgICAgYWRkcmVzcyAgICAvLyBhZGRyZXNzIHRvIGNhbGwgdGhlIGZ1bmN0aW9uCn0KCnR5cGUgRGVjcmVhc2VMaXF1aWRpdHlQYXJhbXMgc3RydWN0IHsKCXBvc2l0aW9uSWQgdWludDY0ICAgICAvLyBwb3NpdGlvbklkIG9mIHRoZSBwb3NpdGlvbiB0byBkZWNyZWFzZSBsaXF1aWRpdHkKCWxpcXVpZGl0eSAgc3RyaW5nICAgICAvLyBhbW91bnQgb2YgbGlxdWlkaXR5IHRvIGRlY3JlYXNlCglhbW91bnQwTWluICp1MjU2LlVpbnQgLy8gbWluaW11bSBhbW91bnQgb2YgdG9rZW4wIHRvIGJlIG1pbnRlZAoJYW1vdW50MU1pbiAqdTI1Ni5VaW50IC8vIG1pbmltdW0gYW1vdW50IG9mIHRva2VuMSB0byBiZSBtaW50ZWQKCWRlYWRsaW5lICAgaW50NjQgICAgICAvLyB0aW1lIGJ5IHdoaWNoIHRoZSB0cmFuc2FjdGlvbiBtdXN0IGJlIGluY2x1ZGVkIHRvIGVmZmVjdCB0aGUgY2hhbmdlCgljYWxsZXIgICAgIGFkZHJlc3MgICAgLy8gYWRkcmVzcyB0byBjYWxsIHRoZSBmdW5jdGlvbgp9Cgp0eXBlIE1pbnRJbnB1dCBzdHJ1Y3QgewoJdG9rZW4wICAgICAgICAgc3RyaW5nCgl0b2tlbjEgICAgICAgICBzdHJpbmcKCWZlZSAgICAgICAgICAgIHVpbnQzMgoJdGlja0xvd2VyICAgICAgaW50MzIKCXRpY2tVcHBlciAgICAgIGludDMyCglhbW91bnQwRGVzaXJlZCBzdHJpbmcKCWFtb3VudDFEZXNpcmVkIHN0cmluZwoJYW1vdW50ME1pbiAgICAgc3RyaW5nCglhbW91bnQxTWluICAgICBzdHJpbmcKCWRlYWRsaW5lICAgICAgIGludDY0CgltaW50VG8gICAgICAgICBhZGRyZXNzCgljYWxsZXIgICAgICAgICBhZGRyZXNzCn0KCnR5cGUgVG9rZW5QYWlyIHN0cnVjdCB7Cgl0b2tlbjAgc3RyaW5nCgl0b2tlbjEgc3RyaW5nCn0KCnR5cGUgUHJvY2Vzc2VkTWludElucHV0IHN0cnVjdCB7Cgl0b2tlblBhaXIgICAgICBUb2tlblBhaXIKCWFtb3VudDBEZXNpcmVkICp1MjU2LlVpbnQKCWFtb3VudDFEZXNpcmVkICp1MjU2LlVpbnQKCWFtb3VudDBNaW4gICAgICp1MjU2LlVpbnQKCWFtb3VudDFNaW4gICAgICp1MjU2LlVpbnQKCXRpY2tMb3dlciAgICAgIGludDMyCgl0aWNrVXBwZXIgICAgICBpbnQzMgoJcG9vbFBhdGggICAgICAgc3RyaW5nCn0KCi8vIEZlZUdyb3d0aEluc2lkZSByZXByZXNlbnRzIGZlZSBncm93dGggaW5zaWRlIHRpY2tzCnR5cGUgRmVlR3Jvd3RoSW5zaWRlIHN0cnVjdCB7CglmZWVHcm93dGhJbnNpZGUwTGFzdFgxMjggKnUyNTYuVWludAoJZmVlR3Jvd3RoSW5zaWRlMUxhc3RYMTI4ICp1MjU2LlVpbnQKfQoazCIKCXV0aWxzLmdubxK+InBhY2thZ2UgcG9zaXRpb24KCmltcG9ydCAoCgkic3RyY29udiIKCSJzdHJpbmdzIgoKCXByYWJjICJnbm8ubGFuZC9wL2dub3N3YXAvcmJhYy92MSIKCXUyNTYgImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgoJImduby5sYW5kL3AvbnQvZ3JjNzIxL3YwIgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoJImduby5sYW5kL3IvZ25vc3dhcC9hY2Nlc3MvdjEiCglwbCAiZ25vLmxhbmQvci9nbm9zd2FwL3Bvb2wiCikKCmNvbnN0IE1BWF9VSU5UMjU2IHN0cmluZyA9ICIxMTU3OTIwODkyMzczMTYxOTU0MjM1NzA5ODUwMDg2ODc5MDc4NTMyNjk5ODQ2NjU2NDA1NjQwMzk0NTc1ODQwMDc5MTMxMjk2Mzk5MzUiCgpmdW5jIG11c3RHZXRTdGFrZXJBZGRyZXNzKCkgYWRkcmVzcyB7CglyZXR1cm4gYWNjZXNzLk11c3RHZXRBZGRyZXNzKHByYWJjLlJPTEVfU1RBS0VSLlN0cmluZygpKQp9CgovLyBtdXN0R2V0UG9vbCByZXR1cm5zIHRoZSByZWFkLW9ubHkgc25hcHNob3QgZm9yIHBvb2xQYXRoLgovLyBJdCBwYW5pY3Mgd2hlbiBwb29sUGF0aCBkb2VzIG5vdCBpZGVudGlmeSBhIHBvb2wuCmZ1bmMgbXVzdEdldFBvb2wocG9vbFBhdGggc3RyaW5nKSAqcGwuUG9vbCB7Cglwb29sLCBvayA6PSBwbC5HZXRQb29scygpLkdldChwb29sUGF0aCkuKCpwbC5Qb29sKQoJaWYgIW9rIHx8IHBvb2wgPT0gbmlsIHsKCQlwYW5pYyh1Zm10LlNwcmludGYoImV4cGVjdGVkIHBvb2xQYXRoKCVzKSB0byBleGlzdCIsIHBvb2xQYXRoKSkKCX0KCXJldHVybiBwb29sCn0KCi8vIHBvc2l0aW9uSWRGcm9tIGNvbnZlcnRzIHBvc2l0aW9uSWQgdG8gZ3JjNzIxLlRva2VuSUQgdHlwZQovLyBpbnB1dDogcG9zaXRpb25JZCB1aW50NjQKLy8gb3V0cHV0OiBncmM3MjEuVG9rZW5JRApmdW5jIHBvc2l0aW9uSWRGcm9tKHBvc2l0aW9uSWQgdWludDY0KSBncmM3MjEuVG9rZW5JRCB7CglyZXR1cm4gZ3JjNzIxLlRva2VuSUQoc3RyY29udi5Gb3JtYXRVaW50KHBvc2l0aW9uSWQsIDEwKSkKfQoKLy8gZXhpc3RzIGNoZWNrcyB3aGV0aGVyIHBvc2l0aW9uSWQgZXhpc3RzCi8vIElmIHBvc2l0aW9uSWQgZG9lc24ndCBleGlzdCwgcmV0dXJuIGZhbHNlLCBvdGhlcndpc2UgcmV0dXJuIHRydWUKLy8gaW5wdXQ6IHBvc2l0aW9uSWQgdWludDY0Ci8vIG91dHB1dDogYm9vbApmdW5jIChwICpwb3NpdGlvblYxKSBleGlzdHMocG9zaXRpb25JZCB1aW50NjQpIGJvb2wgewoJcmV0dXJuIHAubmZ0QWNjZXNzb3IuRXhpc3RzKHBvc2l0aW9uSWRGcm9tKHBvc2l0aW9uSWQpKQp9CgovLyBpc093bmVyIGNoZWNrcyB3aGV0aGVyIHRoZSBjYWxsZXIgaXMgdGhlIG93bmVyIG9mIHRoZSBwb3NpdGlvbklkCi8vIElmIHRoZSBjYWxsZXIgaXMgdGhlIG93bmVyIG9mIHRoZSBwb3NpdGlvbklkLCByZXR1cm4gdHJ1ZSwgb3RoZXJ3aXNlIHJldHVybiBmYWxzZQovLyBpbnB1dDogcG9zaXRpb25JZCB1aW50NjQsIGFkZHIgc3RkLkFkZHJlc3MKLy8gb3V0cHV0OiBib29sCmZ1bmMgKHAgKnBvc2l0aW9uVjEpIGlzT3duZXIocG9zaXRpb25JZCB1aW50NjQsIGFkZHIgYWRkcmVzcykgYm9vbCB7Cglvd25lciwgZXJyIDo9IHAubmZ0QWNjZXNzb3IuT3duZXJPZihwb3NpdGlvbklkRnJvbShwb3NpdGlvbklkKSkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBmYWxzZQoJfQoJcmV0dXJuIG93bmVyID09IGFkZHIKfQoKLy8gaXNPcGVyYXRvciBjaGVja3Mgd2hldGhlciB0aGUgY2FsbGVyIGlzIHRoZSBhcHByb3ZlZCBvcGVyYXRvciBvZiB0aGUgcG9zaXRpb25JZAovLyBJZiB0aGUgY2FsbGVyIGlzIHRoZSBhcHByb3ZlZCBvcGVyYXRvciBvZiB0aGUgcG9zaXRpb25JZCwgcmV0dXJuIHRydWUsIG90aGVyd2lzZSByZXR1cm4gZmFsc2UKLy8gaW5wdXQ6IHBvc2l0aW9uSWQgdWludDY0LCBhZGRyIHN0ZC5BZGRyZXNzCi8vIG91dHB1dDogYm9vbApmdW5jIChwICpwb3NpdGlvblYxKSBpc09wZXJhdG9yKHBvc2l0aW9uSWQgdWludDY0LCBhZGRyIGFkZHJlc3MpIGJvb2wgewoJb3BlcmF0b3IsIGVyciA6PSBwLkdldFBvc2l0aW9uT3BlcmF0b3IocG9zaXRpb25JZCkKCXJldHVybiBlcnIgPT0gbmlsICYmIG9wZXJhdG9yID09IGFkZHIKfQoKLy8gaXNTdGFrZWQgY2hlY2tzIHdoZXRoZXIgcG9zaXRpb25JZCBpcyBzdGFrZWQKLy8gSWYgcG9zaXRpb25JZCBpcyBzdGFrZWQsIG93bmVyIG9mIHBvc2l0aW9uSWQgaXMgc3Rha2VyIGNvbnRyYWN0Ci8vIElmIHBvc2l0aW9uSWQgaXMgc3Rha2VkLCByZXR1cm4gdHJ1ZSwgb3RoZXJ3aXNlIHJldHVybiBmYWxzZQovLyBpbnB1dDogcG9zaXRpb25JZCBncmM3MjEuVG9rZW5JRAovLyBvdXRwdXQ6IGJvb2wKZnVuYyAocCAqcG9zaXRpb25WMSkgaXNTdGFrZWQocG9zaXRpb25JZCBncmM3MjEuVG9rZW5JRCkgYm9vbCB7CglleGlzdCA6PSBwLm5mdEFjY2Vzc29yLkV4aXN0cyhwb3NpdGlvbklkKQoJaWYgIWV4aXN0IHsKCQlyZXR1cm4gZmFsc2UKCX0KCW93bmVyLCBlcnIgOj0gcC5uZnRBY2Nlc3Nvci5Pd25lck9mKHBvc2l0aW9uSWQpCglpZiBlcnIgPT0gbmlsICYmIG93bmVyID09IG11c3RHZXRTdGFrZXJBZGRyZXNzKCkgewoJCXJldHVybiB0cnVlCgl9CglyZXR1cm4gZmFsc2UKfQoKLy8gaXNPd25lck9yT3BlcmF0b3IgY2hlY2tzIHdoZXRoZXIgdGhlIGNhbGxlciBpcyB0aGUgb3duZXIgb3IgYXBwcm92ZWQgb3BlcmF0b3Igb2YgdGhlIHBvc2l0aW9uSWQKLy8gSWYgdGhlIGNhbGxlciBpcyB0aGUgb3duZXIgb3IgYXBwcm92ZWQgb3BlcmF0b3Igb2YgdGhlIHBvc2l0aW9uSWQsIHJldHVybiB0cnVlLCBvdGhlcndpc2UgcmV0dXJuIGZhbHNlCi8vIGlucHV0OiBhZGRyIHN0ZC5BZGRyZXNzLCBwb3NpdGlvbklkIHVpbnQ2NAovLyBvdXRwdXQ6IGJvb2wKZnVuYyAocCAqcG9zaXRpb25WMSkgaXNPd25lck9yT3BlcmF0b3IocG9zaXRpb25JZCB1aW50NjQsIGFkZHIgYWRkcmVzcykgYm9vbCB7CglpZiAhYWRkci5Jc1ZhbGlkKCkgfHwgIXAuZXhpc3RzKHBvc2l0aW9uSWQpIHsKCQlyZXR1cm4gZmFsc2UKCX0KCglpZiBwLmlzU3Rha2VkKHBvc2l0aW9uSWRGcm9tKHBvc2l0aW9uSWQpKSB7CgkJcmV0dXJuIHAuaXNPcGVyYXRvcihwb3NpdGlvbklkLCBhZGRyKQoJfQoKCXJldHVybiBwLmlzT3duZXIocG9zaXRpb25JZCwgYWRkcikKfQoKLy8gc3BsaXRPZiBkaXZpZGVzIHBvb2xLZXkgaW50byBwVG9rZW4wLCBwVG9rZW4xLCBhbmQgcEZlZQovLyBJZiBwb29sS2V5IGlzIGludmFsaWQsIGl0IHdpbGwgcGFuaWMKLy8KLy8gaW5wdXQ6IHBvb2xLZXkgc3RyaW5nCi8vIG91dHB1dDoKLy8gLSB0b2tlbjBQYXRoIHN0cmluZwovLyAtIHRva2VuMVBhdGggc3RyaW5nCi8vIC0gZmVlIHVpbnQzMgpmdW5jIHNwbGl0T2YocG9vbEtleSBzdHJpbmcpIChzdHJpbmcsIHN0cmluZywgdWludDMyKSB7CglyZXMgOj0gc3RyaW5ncy5TcGxpdChwb29sS2V5LCAiOiIpCglpZiBsZW4ocmVzKSAhPSAzIHsKCQlwYW5pYyhuZXdFcnJvcldpdGhEZXRhaWwoZXJySW52YWxpZElucHV0LCB1Zm10LlNwcmludGYoImludmFsaWQgcG9vbEtleSglcykiLCBwb29sS2V5KSkpCgl9CgoJcFRva2VuMCwgcFRva2VuMSwgcEZlZVN0ciA6PSByZXNbMF0sIHJlc1sxXSwgcmVzWzJdCgoJcEZlZSwgZXJyIDo9IHN0cmNvbnYuQXRvaShwRmVlU3RyKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMobmV3RXJyb3JXaXRoRGV0YWlsKGVyckludmFsaWRJbnB1dCwgdWZtdC5TcHJpbnRmKCJpbnZhbGlkIGZlZSglcykiLCBwRmVlU3RyKSkpCgl9CgoJcmV0dXJuIHBUb2tlbjAsIHBUb2tlbjEsIHVpbnQzMihwRmVlKQp9CgpmdW5jIGlzU2xpcHBhZ2VFeGNlZWRlZChhbW91bnQwLCBhbW91bnQxLCBhbW91bnQwTWluLCBhbW91bnQxTWluICp1MjU2LlVpbnQpIGJvb2wgewoJcmV0dXJuICEoYW1vdW50MC5HdGUoYW1vdW50ME1pbikgJiYgYW1vdW50MS5HdGUoYW1vdW50MU1pbikpCn0KCi8vIGN1cnJlbnRQb29sT2JzZXJ2YXRpb24gZGVyaXZlcyB0aGUgbGF0ZXN0IHN0b3JlZCBvYnNlcnZhdGlvbiBmcm9tIHRoZQovLyBVbmlzd2FwLVYzLWFsaWduZWQgU2xvdDAgYW5kIG9ic2VydmF0aW9ucyBzdXJmYWNlcy4KZnVuYyBjdXJyZW50UG9vbE9ic2VydmF0aW9uKHBvb2xQYXRoIHN0cmluZykgKGludDY0LCBzdHJpbmcsIGludDY0LCBlcnJvcikgewoJc2xvdDAgOj0gcGwuR2V0U2xvdDAocG9vbFBhdGgpCglvYnNlcnZhdGlvbiwgZXJyIDo9IHBsLkdldE9ic2VydmF0aW9uQXQocG9vbFBhdGgsIHNsb3QwLk9ic2VydmF0aW9uSW5kZXgoKSkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCAiIiwgMCwgZXJyCgl9CgoJcmV0dXJuIG9ic2VydmF0aW9uLlRpY2tDdW11bGF0aXZlKCksIG9ic2VydmF0aW9uLlNlY29uZHNQZXJMaXF1aWRpdHlDdW11bGF0aXZlWDEyOCgpLCBvYnNlcnZhdGlvbi5CbG9ja1RpbWVzdGFtcCgpLCBuaWwKfQoiIgoTL2duby5NZW1QYWNrYWdlVHlwZRILCglNUFVzZXJBbGwSEgjsi5F9EgsxMzEyMTN1Z25vdBqoAQo6ChMvdG0uUHViS2V5U2VjcDI1NmsxEiMKIQMEnNUEw+LSOqLPC53myjgfoun1lzihgX/ZUaUiNcK64RJA0o4lTX1MYEeQG4o5fYnL/mXweJeukhYyNfDPqKLTa9B48E3PbkMFkzTbAym6CwRkbr1MwzO+TGuWruLBdnR6RBooZzFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFsdXV4ZQ==