Transaction executed successfully

Transaction Details

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

Transaction hash
A24FEFBD5FE71FA746170BD3D6F50CA715E205D5561A5385EF66ACFC285CB567

Transaction overview

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

Execution summary

TX INDEX
1
Position in block
GAS WANTED
423,732,951
Requested gas limit
GAS USED
353,110,842
Gas consumed
FEE
423733ugnot
Transaction fee

Participants

Sender
Package / Realm
Not available
Memo
None

Message

Message #1
m_addpkg
Caller
Arguments
g1q5tjjv3kkslzwf2na9y9wk7e5a8ugph8xfsk04

Execution log

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

Events

No events emitted by this transaction.

Raw encoded transaction

CpWbEQoML3ZtLm1fYWRkcGtnEoObEQooZzFxNXRqanYza2tzbHp3ZjJuYTl5OXdrN2U1YTh1Z3BoOHhmc2swNBLVmhEKBnN0YWtlchIcZ25vLmxhbmQvci9nbm9zd2FwL3N0YWtlci92MRriSAoJUkVBRE1FLm1kEtRIIyBTdGFrZXIKCkxpcXVpZGl0eSBtaW5pbmcgYW5kIHJld2FyZCBkaXN0cmlidXRpb24gZm9yIExQIHBvc2l0aW9ucy4KCiMjIE92ZXJ2aWV3CgpTdGFrZXIgbWFuYWdlcyBkaXN0cmlidXRpb24gb2YgaW50ZXJuYWwgKEdOUyBlbWlzc2lvbikgYW5kIGV4dGVybmFsIChjYWxsZXItZnVuZGVkKSByZXdhcmRzIHRvIHN0YWtlZCBMUCBwb3NpdGlvbnMsIHdpdGggdGltZS13ZWlnaHRlZCByZXdhcmRzIGFuZCB3YXJtdXAgcGVyaW9kcy4KCiMjIENvbmZpZ3VyYXRpb24KCi0gKipEZXBvc2l0IEdOUyBBbW91bnQqKjogMTAwLDAwMCBHTlMgcGVyIGV4dGVybmFsIGluY2VudGl2ZSAoZGVmYXVsdDsgZ292ZXJuYW5jZS1hZGp1c3RhYmxlKQotICoqTWluaW11bSBSZXdhcmQgQW1vdW50Kio6IDEsMDAwIHRva2VuIHVuaXRzIChkZWZhdWx0IGZvciBleHRlcm5hbCBpbmNlbnRpdmUgY3JlYXRpb24pCi0gKipVbnN0YWtpbmcgRmVlKio6IDElIGRlZmF1bHQgKDEwMCBiYXNpcyBwb2ludHM7IGNvbmZpZ3VyYWJsZSBmcm9tIDAgdG8gMTAlKQotICoqSW50ZXJuYWwgUG9vbCBUaWVycyoqOiAxLCAyLCBvciAzIChhc3NpZ25lZCBwZXIgcG9vbCk7IGV4dGVybmFsLW9ubHkgcG9vbHMgY2FuIGFsc28gYmUgc3Rha2VhYmxlCi0gKipXYXJtdXAgU2NoZWR1bGUqKjogMzAvNTAvNzAvMTAwJSBvdmVyIGRlZmF1bHQgY3VtdWxhdGl2ZSB3aW5kb3dzIG9mIDAtNSwgNS0xNSwgMTUtNDUsIGFuZCA0NSsgZGF5cwotICoqRXh0ZXJuYWwgVG9rZW4gUG9saWN5Kio6IEFwcHJvdmVkIHJld2FyZCB0b2tlbnM7IHBvb2wtcGFpciB0b2tlbnMgYXJlIGFsc28gYWNjZXB0ZWQgZm9yIHRoZWlyIG93biBwb29sIHVubGVzcyBleHBsaWNpdGx5IGRlbmllZAotICoqRXh0ZXJuYWwgSW5jZW50aXZlIFN0YXJ0Kio6IFVUQyBtaWRuaWdodCwgZnJvbSB0aGUgZmlyc3QgZWxpZ2libGUgc3RhcnQgKGF0IGxlYXN0IDI0IGhvdXJzIGFmdGVyIGNyZWF0aW9uKSB0aHJvdWdoIDcgZGF5cyBsYXRlcgoKIyMgQ29yZSBGZWF0dXJlcwoKIyMjIEludGVybmFsIFJld2FyZHMgKEdOUyBFbWlzc2lvbikKLSBBbGxvY2F0ZWQgdG8gdGllcmVkIHBvb2xzICh0aWVycyAxLCAyLCAzKQotIFNwbGl0IGFjcm9zcyB0aWVycyBieSBUaWVyUmF0aW8KLSBEaXN0cmlidXRlZCBwcm9wb3J0aW9uYWxseSB0byBpbi1yYW5nZSBsaXF1aWRpdHkKLSBVbmNsYWltZWQgcmV3YXJkcyBnbyB0byBjb21tdW5pdHkgcG9vbAoKIyMjIEV4dGVybmFsIFJld2FyZHMgKENhbGxlci1GdW5kZWQgSW5jZW50aXZlcykKLSBDcmVhdGVkIGZvciBzcGVjaWZpYyBwb29scyBieSBhbnkgY2FsbGVyIHRoYXQgc2F0aXNmaWVzIHRoZSB0b2tlbiwgZHVyYXRpb24sIHN0YXJ0LXRpbWUsIHJld2FyZC1taW5pbXVtLCBhbmQgR05TLWRlcG9zaXQgY2hlY2tzCi0gQ29uc3RhbnQgcmV3YXJkIHBlciBzZWNvbmQgb3ZlciB0aGUgY29uZmlndXJlZCBpbmNlbnRpdmUgd2luZG93OyB0aGUgc3RvcmVkIHJhdGUgaXMgUTEyOC1zY2FsZWQgYXMgYChyZXdhcmRBbW91bnQgPDwgMTI4KSAvIGR1cmF0aW9uYAotIFByb3BvcnRpb25hbCB0byBzdGFrZWQgbGlxdWlkaXR5Ci0gYEVuZEV4dGVybmFsSW5jZW50aXZlYCBpcyBjcmVhdG9yL2FkbWluLW9ubHkgYW5kIHNlbmRzIG9ubHkgdGhlIHVuY2xhaW1hYmxlL3JlbWFpbmRlciBwb3J0aW9uIHBsdXMgdGhlIEdOUyBkZXBvc2l0IHRvIGl0cyBleHBsaWNpdCBgcmVmdW5kQWRkcmVzc2A7IHJld2FyZHMgc3RpbGwgb3dlZCBieSBsaXZlIHBvc2l0aW9ucyByZW1haW4gY2xhaW1hYmxlCi0gQWNjdW11bGF0ZWQgd2FybXVwIHBlbmFsdGllcyBhcmUgY29sbGVjdGVkIHNlcGFyYXRlbHkgdGhyb3VnaCBgQ29sbGVjdEV4dGVybmFsSW5jZW50aXZlUGVuYWx0eWAgYWZ0ZXIgYEVuZEV4dGVybmFsSW5jZW50aXZlYAoKIyMjIFdhcm11cCBQZXJpb2RzCkV2ZXJ5IHN0YWtlZCBwb3NpdGlvbiBwcm9ncmVzc2VzIHRocm91Z2ggd2FybXVwIHBlcmlvZHMuIFRoZSBkZWZhdWx0IGZpbml0ZSBkdXJhdGlvbnMgYXJlIDUsIDEwLAphbmQgMzAgZGF5cywgZm9sbG93ZWQgYnkgYSBmaW5hbCBgbWF0aC5NYXhJbnQ2NGAgdGllcjoKLSAwLTUgZGF5czogMzAlIG9mIHRoZSBjYWxjdWxhdGVkIHJld2FyZAotIDUtMTUgZGF5czogNTAlIG9mIHRoZSBjYWxjdWxhdGVkIHJld2FyZAotIDE1LTQ1IGRheXM6IDcwJSBvZiB0aGUgY2FsY3VsYXRlZCByZXdhcmQKLSA0NSsgZGF5czogMTAwJSBvZiB0aGUgY2FsY3VsYXRlZCByZXdhcmQKCkdvdmVybmFuY2UgbWF5IGNoYW5nZSB0aGUgZmluaXRlIGR1cmF0aW9ucy4gV2FybXVwIHJhdGlvcyBhcmUgYXBwbGllZCBiZWZvcmUgdGhlIHN0YWtpbmctcmV3YXJkIGZlZToKaW50ZXJuYWwgR05TIHBlbmFsdGllcyBnbyB0byB0aGUgY29tbXVuaXR5IHBvb2wsIHdoaWxlIGV4dGVybmFsIHBlbmFsdGllcyBhY2N1bXVsYXRlIG9uIHRoZQppbmNlbnRpdmUgYW5kIGFyZSBjb2xsZWN0ZWQgc2VwYXJhdGVseSB0byBhbiBleHBsaWNpdCBhZGRyZXNzIGFmdGVyIGBFbmRFeHRlcm5hbEluY2VudGl2ZWAuCgojIyBLZXkgRnVuY3Rpb25zCgojIyMgYFN0YWtlVG9rZW5gClN0YWtlcyBMUCBwb3NpdGlvbiBORlQgdG8gZWFybiByZXdhcmRzLgoKIyMjIGBVblN0YWtlVG9rZW5gCgpVbnN0YWtlcyB0aGUgcG9zaXRpb24gYW5kIGNyZWF0ZXMgYW4gZXhpdCBjaGVja3BvaW50LiBJdCByZXR1cm5zIHRoZSBORlQgYW5kIHRoZSBzdGFrZWQgcG9vbCBwYXRoCndpdGhvdXQgY29sbGVjdGluZyByZXdhcmRzOyB1c2UgYSBgQ29sbGVjdCpgIGVudHJ5IHBvaW50IGFmdGVyd2FyZC4KCiMjIyBgQ29sbGVjdFJld2FyZGAKQ29sbGVjdHMgYWNjdW11bGF0ZWQgcmV3YXJkcyBmb3IgYSBsaXZlIHN0YWtlZCBwb3NpdGlvbiBvciBhbiBleGl0IGNoZWNrcG9pbnQuIExpdmUgY29sbGVjdGlvbgpyZXF1aXJlcyB0aGUgZGVwb3NpdG9yL293bmVyOyBjaGVja3BvaW50IGNvbGxlY3Rpb24gaXMgcGVybWlzc2lvbmxlc3MgYW5kIHBheXMgaXRzIHBpbm5lZCBvd25lci4KCiMjIyBgQ3JlYXRlRXh0ZXJuYWxJbmNlbnRpdmVgCkNyZWF0ZXMgYW4gZXh0ZXJuYWwgcmV3YXJkIHByb2dyYW0gZm9yIGEgc3BlY2lmaWMgcG9vbC4gQ3JlYXRpb24gaXMgcGVybWlzc2lvbmxlc3MgYWZ0ZXIgYWxsCnJld2FyZC10b2tlbiBhbGxvd2xpc3QvZGVuaWFsLCBkdXJhdGlvbiwgc3RhcnQtdGltZSwgcmV3YXJkLW1pbmltdW0sIGFuZCBHTlMtZGVwb3NpdCBjaGVja3MgcGFzcy4KCiMjIyBgRW5kRXh0ZXJuYWxJbmNlbnRpdmVgCkVuZHMgYW4gaW5jZW50aXZlIGFmdGVyIGl0cyBlbmQgdGltZXN0YW1wIGFuZCBmaW5hbGl6ZXMgaXRzIHJlZnVuZGFibGUgdW5jbGFpbWFibGUvcmVtYWluZGVyCmFtb3VudC4gVGhlIHJld2FyZCB0b2tlbnMgYW5kIEdOUyBkZXBvc2l0IGFyZSBzZW50IHRvIHRoZSBjYWxsZXItc3VwcGxpZWQgYHJlZnVuZEFkZHJlc3NgOyBvbmx5CnRoZSBjcmVhdG9yIG9yIGFkbWluIG1heSBjYWxsIGl0LCBhbmQgYW4gb3V0c3RhbmRpbmcgZXhpdCBjaGVja3BvaW50IGZvciB0aGF0IGluY2VudGl2ZSBibG9ja3MgZW5kaW5nLgoKIyMjIGBDb2xsZWN0RXh0ZXJuYWxJbmNlbnRpdmVQZW5hbHR5YApDb2xsZWN0cyBhY2N1bXVsYXRlZCB3YXJtdXAgcGVuYWx0aWVzIGZvciBhbiBpbmNlbnRpdmUgYWZ0ZXIgYEVuZEV4dGVybmFsSW5jZW50aXZlYCBoYXMgZmluYWxpemVkCml0LCBzZW5kaW5nIHRoZSBwZW5hbHR5IHRvIHRoZSBjYWxsZXItc3VwcGxpZWQgYHJlZnVuZEFkZHJlc3NgLiBPbmx5IHRoZSBjcmVhdG9yIG9yIGFkbWluIG1heSBjYWxsLgoKIyMjIGBDYW5jZWxFeHRlcm5hbEluY2VudGl2ZWAKUmVtb3ZlcyBhIG5vdC15ZXQtc3RhcnRlZCBpbmNlbnRpdmUgYW5kIHJlZnVuZHMgaXRzIHJld2FyZCB0b2tlbnMgYW5kIEdOUyBkZXBvc2l0IHRvIHRoZSBjcmVhdG9yLgpDYWxsYWJsZSBieSBhZG1pbiwgZ292ZXJuYW5jZSwgb3IgdGhlIGNyZWF0b3I7IHRoZSByZXdhcmQtdG9rZW4gcmVmdW5kIGlzIGNhcHBlZCBieSB0aGUgc3Rha2VyIGJhbGFuY2UuCgojIyBSZXdhcmQgQ2FsY3VsYXRpb24gTG9naWMKCiMjIyBUaWVyIFJhdGlvIERpc3RyaWJ1dGlvbgoKRW1pc3Npb24gc3BsaXQgYWNyb3NzIHRpZXJzIGJhc2VkIG9uIGFjdGl2ZSBwb29sczoKCmBgYApJZiBvbmx5IHRpZXIgMSBoYXMgcG9vbHM6ICAgIFsxMDAlLCAwJSwgMCVdCklmIHRpZXJzIDEgJiAzIGhhdmUgcG9vbHM6ICAgWzgwJSwgMCUsIDIwJV0KSWYgdGllcnMgMSAmIDIgaGF2ZSBwb29sczogICBbNzAlLCAzMCUsIDAlXQpJZiBhbGwgdGllcnMgaGF2ZSBwb29sczogICAgIFs1MCUsIDMwJSwgMjAlXQpgYGAKCk1hdGhlbWF0aWNhbCByZXByZXNlbnRhdGlvbjoKYGBgbWF0aApUaWVyUmF0aW8odCkgPQogIFsxMDAsIDAsIDBdICBpZiBDb3VudCgyKSA9IDAg4oinIENvdW50KDMpID0gMAogIFs4MCwgMCwgMjBdICBpZiBDb3VudCgyKSA9IDAKICBbNzAsIDMwLCAwXSAgaWYgQ291bnQoMykgPSAwCiAgWzUwLCAzMCwgMjBdIG90aGVyd2lzZQpgYGAKCiMjIyBQb29sIFJld2FyZCBGb3JtdWxhCgpgYGBtYXRoCnBvb2xSZXdhcmQocG9vbCkgPSAoZW1pc3Npb24gw5cgVGllclJhdGlvW3RpZXIocG9vbCldIC8gMTAwKSAvIENvdW50KHRpZXIocG9vbCkpCmBgYAoKV2hlcmUgZW1pc3Npb24gaXMgY2FsY3VsYXRlZCBhczoKYGBgbWF0aAplbWlzc2lvbiA9IEdldFN0YWtlckVtaXNzaW9uQW1vdW50UGVyU2Vjb25kKCkKYGBgCgojIyMgUG9zaXRpb24gUmV3YXJkIENhbGN1bGF0aW9uCgpUaGUgcmV3YXJkIGZvciBlYWNoIHBvc2l0aW9uIGlzIGNhbGN1bGF0ZWQgdGhyb3VnaDoKCjEuICoqUmVzb2x2ZSB0aGUgcGVyc2lzdGVkL2hhbHZpbmcgcGVyLXNlY29uZCByZXdhcmQgc2NoZWR1bGUqKiAocmVhZC1vbmx5KQoyLiAqKlJldHJpZXZlIHBvc2l0aW9uIHN0YXRlKiogZnJvbSBkZXBvc2l0IHJlY29yZHMgb3IgYW4gZXhpdCBjaGVja3BvaW50CjMuICoqQ2FsY3VsYXRlIGludGVybmFsIHJld2FyZHMqKiBpZiB0aGUgcG9vbCBoYXMgYW4gaW50ZXJuYWwgdGllcgo0LiAqKkNhbGN1bGF0ZSBleHRlcm5hbCByZXdhcmRzKiogZm9yIHRoZSBpbmNlbnRpdmUgSURzCjUuICoqQXBwbHkgd2FybXVwIHJhdGlvcyBhbmQgcGVuYWx0aWVzKiogYmFzZWQgb24gc3Rha2UgZHVyYXRpb24KCkNvbGxlY3Rpb24gbWF5IHNlcGFyYXRlbHkgYWR2YW5jZSByZXdhcmQgY2FjaGVzIGFuZCBwZXJzaXN0IG5ld2x5IGRpc2NvdmVyZWQgaW5jZW50aXZlIElEczsgdGhlCnJlYWQtb25seSBjYWxjdWxhdGlvbiBpdHNlbGYgZG9lcyBub3Qgd3JpdGUgdGhvc2UgY2FjaGVzLgoKTWF0aGVtYXRpY2FsIGZvcm11bGEgZm9yIHRvdGFsIHJld2FyZCByYXRpbzoKYGBgbWF0aApUb3RhbFJld2FyZFJhdGlvKHMsZSkgPSDOo1tpPTAgdG8gbS0xXSDOlFJhdyjOseG1oiwgzrLhtaIpIMOXIHLhtaIKCndoZXJlOgogIM6x4bWiID0gbWF4KHMsIEjhtaLigovigoEpCiAgzrLhtaIgPSBtaW4oZSwgSOG1oikKICAKzpRSYXcoYSwgYikgPSBDYWxjUmF3KGIpIC0gQ2FsY1JhdyhhKQoKQ2FsY1JhdyhoKSA9IAogIEwoaCkgLSBVKGgpICAgICAgICAgICBpZiB0aWNrKGgpIDwg4oSTCiAgVShoKSAtIEwoaCkgICAgICAgICAgIGlmIHRpY2soaCkg4omlIHUKICBHKGgpIC0gKEwoaCkgKyBVKGgpKSAgb3RoZXJ3aXNlCgp3aGVyZToKICBMKGgpID0gdGlja0xvd2VyLk91dHNpZGVBY2N1bXVsYXRpb24oaCkKICBVKGgpID0gdGlja1VwcGVyLk91dHNpZGVBY2N1bXVsYXRpb24oaCkKICBHKGgpID0gZ2xvYmFsUmV3YXJkUmF0aW9BY2N1bXVsYXRpb24oaCkKICDihJMgPSB0aWNrTG93ZXIuaWQKICB1ID0gdGlja1VwcGVyLmlkCmBgYAoKRmluYWwgcG9zaXRpb24gcmV3YXJkOgpgYGBtYXRoCmZpbmFsUmV3YXJkID0gVG90YWxSZXdhcmRSYXRpbyDDlyBwb29sUmV3YXJkIMOXIHBvc2l0aW9uTGlxdWlkaXR5CiAgICAgICAgICAgID0g4oirW3MgdG8gZV0gKHBvb2xSZXdhcmQgw5cgcG9zaXRpb25MaXF1aWRpdHkpIC8gVG90YWxTdGFrZWRMaXF1aWRpdHkoaCkgZGgKYGBgCgojIyMgVGljayBDcm9zcyBIb29rCgpXaGVuIHByaWNlIGNyb3NzZXMgYW4gaW5pdGlhbGl6ZWQgdGljayB3aXRoIHN0YWtlZCBwb3NpdGlvbnM6CgoxLiAqKlVwZGF0ZXMgc3Rha2VkIGxpcXVpZGl0eSoqIC0gQWRqdXN0cyB0b3RhbCBzdGFrZWQgbGlxdWlkaXR5CjIuICoqVXBkYXRlcyByZXdhcmQgYWNjdW11bGF0aW9uKiogLSBSZWNhbGN1bGF0ZXMgYGdsb2JhbFJld2FyZFJhdGlvQWNjdW11bGF0aW9uYAozLiAqKk1hbmFnZXMgdW5jbGFpbWFibGUgcGVyaW9kcyoqIC0gU3RhcnRzL2VuZHMgcGVyaW9kcyB3aXRoIG5vIGluLXJhbmdlIGxpcXVpZGl0eQo0LiAqKlVwZGF0ZXMgdGljayBhY2N1bXVsYXRpb24qKiAtIEFkanVzdHMgYEN1cnJlbnRPdXRzaWRlQWNjdW11bGF0aW9uYAoKVGhlIGBnbG9iYWxSZXdhcmRSYXRpb0FjY3VtdWxhdGlvbmAgdHJhY2tzIHRoZSBpbnRlZ3JhbDoKYGBgbWF0aApnbG9iYWxSZXdhcmRSYXRpb0FjY3VtdWxhdGlvbiA9IOKIqyAxL1RvdGFsU3Rha2VkTGlxdWlkaXR5KGgpIGRoCmBgYAoKVGhpcyBpbnRlZ3JhbCBpcyBvbmx5IGNvbXB1dGVkIHdoZW4gYFRvdGFsU3Rha2VkTGlxdWlkaXR5KGgpIOKJoCAwYCwgZW5hYmxpbmcgcHJlY2lzZSByZXdhcmQgY2FsY3VsYXRpb24gZXZlbiBhcyBsaXF1aWRpdHkgY2hhbmdlcy4KCiMjIyBSZXdhcmQgU3RhdGUgVHJhY2tpbmcKClRoZSBzeXN0ZW0gbWFpbnRhaW5zOgotICoqR2xvYmFsIGFjY3VtdWxhdGlvbioqOiBUcmFja3MgcmV3YXJkIHJhdGlvIGFjcm9zcyBhbGwgcG9zaXRpb25zCi0gKipUaWNrIGFjY3VtdWxhdGlvbioqOiBUcmFja3MgcmV3YXJkcyAib3V0c2lkZSIgZWFjaCB0aWNrCi0gKipQb3NpdGlvbiBzdGF0ZSoqOiBJbmRpdmlkdWFsIHJld2FyZCBjYWxjdWxhdGlvbiBwYXJhbWV0ZXJzCgojIyBBcHByb3ZhbCBSZXF1aXJlbWVudHMKCi0gYFN0YWtlVG9rZW5gIG1vdmVzIHRoZSBwb3NpdGlvbiBORlQgdG8gdGhlIHN0YWtlciByZWFsbSB0aHJvdWdoCiAgYGduZnQuVHJhbnNmZXJGcm9tYCwgc28gdGhlIGNhbGxlciBtdXN0IGFwcHJvdmUgdGhlIHN0YWtlciBvbiB0aGF0IE5GVCBmaXJzdAogIHdpdGggYGduZnQuQXBwcm92ZShjcm9zcyhjdXIpLCBzdGFrZXJBZGRyZXNzLCBwb3NpdGlvbklkKWAsIG9yIGdyYW50CiAgYGduZnQuU2V0QXBwcm92YWxGb3JBbGwoY3Jvc3MoY3VyKSwgc3Rha2VyQWRkcmVzcywgdHJ1ZSlgLgotIGBDcmVhdGVFeHRlcm5hbEluY2VudGl2ZWAgcHVsbHMgdHdvIGFtb3VudHMgaW50byB0aGUgc3Rha2VyIHJlYWxtOiB0aGUgcmV3YXJkCiAgdG9rZW4gYW1vdW50IGFuZCB0aGUgR05TIGRlcG9zaXQuIEFwcHJvdmUgdGhlIHN0YWtlciByZWFsbSBmb3IgYm90aCB0b2tlbgogIGNvbnRyYWN0cyBiZWZvcmUgY2FsbGluZy4KLSBgVW5TdGFrZVRva2VuYCwgdGhlIHJld2FyZC1jb2xsZWN0aW9uIGZ1bmN0aW9ucywgYEVuZEV4dGVybmFsSW5jZW50aXZlYCwgYW5kCiAgYENhbmNlbEV4dGVybmFsSW5jZW50aXZlYCBwYXkgb3V0IHRvIHRoZSBjYWxsZXIgb3IgdG8gYSBzdXBwbGllZCBhZGRyZXNzIGFuZAogIHJlcXVpcmUgbm8gYXBwcm92YWwuCgpgYGBnbwovLyBBcHByb3ZlIHRoZSBzdGFrZXIgb24gdGhlIHBvc2l0aW9uIE5GVCwgdGhlbiBzdGFrZQpzdGFrZXJBZGRyZXNzIDo9IGFjY2Vzcy5NdXN0R2V0QWRkcmVzcyhwcmFiYy5ST0xFX1NUQUtFUi5TdHJpbmcoKSkKZ25mdC5BcHByb3ZlKGNyb3NzKGN1ciksIHN0YWtlckFkZHJlc3MsIGdyYzcyMS5Ub2tlbklEKCIxMjMiKSkKU3Rha2VUb2tlbihjcm9zcyhjdXIpLCAxMjMsICIiKQoKLy8gR05TIHBheXMgYm90aCB0aGUgZXh0ZXJuYWwgcmV3YXJkIGFuZCB0aGUgcmVxdWlyZWQgZGVwb3NpdApnbnMuQXBwcm92ZShjcm9zcyhjdXIpLCBzdGFrZXJBZGRyZXNzLCAxXzAwMF8wMDBfMDAwK0dldERlcG9zaXRHbnNBbW91bnQoKSkKYGBgCgojIyBVc2FnZQoKVGhlIHByb3h5IGZ1bmN0aW9ucyByZWNlaXZlIGEgcmVhbG0gYXJndW1lbnQuIEZyb20gYSBjYWxsZXIgcmVhbG0gd2l0aCBgY3VyIHJlYWxtYCwgcGFzcwpgY3Jvc3MoY3VyKWAgYXMgdGhhdCBmaXJzdCBhcmd1bWVudDoKCmBgYGdvCi8vIFN0YWtlIGFuIGV4aXN0aW5nIHBvc2l0aW9uClN0YWtlVG9rZW4oY3Jvc3MoY3VyKSwgMTIzLCAiZzFyZWZlcnJlci4uLiIpCgovLyBDcmVhdGUgYW4gZXh0ZXJuYWwgaW5jZW50aXZlIChyZXdhcmRBbW91bnQgaXMgYW4gaW50NjQgdG9rZW4tdW5pdCBhbW91bnQpCkNyZWF0ZUV4dGVybmFsSW5jZW50aXZlKAogICAgY3Jvc3MoY3VyKSwKICAgICJnbm8ubGFuZC9yL2dub2xhbmQvd3Vnbm90Lnd1Z25vdDpnbm8ubGFuZC9yL2dub3N3YXAvZ25zLkdOUzozMDAwIiwKICAgICJnbm8ubGFuZC9yL2dub3N3YXAvZ25zLkdOUyIsCiAgICAxXzAwMF8wMDBfMDAwLAogICAgc3RhcnRUaW1lLAogICAgZW5kVGltZSwKKQoKLy8gQ29sbGVjdCB3aGlsZSB0aGUgcG9zaXRpb24gaXMgc3Rha2VkCkNvbGxlY3RSZXdhcmQoY3Jvc3MoY3VyKSwgMTIzKQoKLy8gVW5zdGFrZTogdGhpcyByZXR1cm5zIHRoZSBORlQgYW5kIGNyZWF0ZXMgYW4gZXhpdCBjaGVja3BvaW50OyBpdCBkb2VzIG5vdCBjb2xsZWN0ClVuU3Rha2VUb2tlbihjcm9zcyhjdXIpLCAxMjMpCgovLyBDb2xsZWN0IHRoZSBjaGVja3BvaW50LCBlaXRoZXIgcGVyIHNvdXJjZSBvciBhbGwgYXQgb25jZQpDb2xsZWN0RW1pc3Npb25SZXdhcmQoY3Jvc3MoY3VyKSwgMTIzKQpDb2xsZWN0RXh0ZXJuYWxJbmNlbnRpdmVSZXdhcmQoY3Jvc3MoY3VyKSwgMTIzLCBpbmNlbnRpdmVJZCkKCi8vIEVuZCBhbiBpbmNlbnRpdmUgYWZ0ZXIgaXRzIGVuZCB0aW1lc3RhbXAsIHRoZW4gY29sbGVjdCBhY2N1bXVsYXRlZCBwZW5hbHRpZXMKRW5kRXh0ZXJuYWxJbmNlbnRpdmUoY3Jvc3MoY3VyKSwgcG9vbFBhdGgsIGluY2VudGl2ZUlkLCByZWZ1bmRBZGRyZXNzKQpDb2xsZWN0RXh0ZXJuYWxJbmNlbnRpdmVQZW5hbHR5KGNyb3NzKGN1ciksIHBvb2xQYXRoLCBpbmNlbnRpdmVJZCwgcmVmdW5kQWRkcmVzcykKYGBgCgojIyBTZWN1cml0eQoKLSBQb3NpdGlvbnMgbG9ja2VkIGR1cmluZyBzdGFraW5nCi0gRXh0ZXJuYWwgaW5jZW50aXZlIGNyZWF0aW9uIGlzIHBlcm1pc3Npb25sZXNzIGFmdGVyIHZhbGlkYXRpb24KLSBFeHRlcm5hbCBpbmNlbnRpdmVzIHJlcXVpcmUgR05TIGRlcG9zaXQKLSBXYXJtdXAgcGVyaW9kcyBwcmV2ZW50IGdhbWluZwotIFVuY2xhaW1lZCByZXdhcmRzIHByb3Blcmx5IHJlZGlyZWN0ZWQKLSBIb29rIGludGVncmF0aW9uIGVuc3VyZXMgYWNjdXJhdGUgdHJhY2tpbmcKGuVoCgphc3NlcnQuZ25vEtZocGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkibWF0aCIKCSJzdHJjb252IgoJInN0cmluZ3MiCgkidGltZSIKCglwcmJhYyAiZ25vLmxhbmQvcC9nbm9zd2FwL3JiYWMvdjEiCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgoJImduby5sYW5kL3IvZ25vc3dhcC9hY2Nlc3MvdjEiCikKCmNvbnN0ICgKCVRJTUVTVEFNUF85MERBWVMgID0gaW50NjQoNzc3NjAwMCkKCVRJTUVTVEFNUF8xODBEQVlTID0gaW50NjQoMTU1NTIwMDApCglUSU1FU1RBTVBfMzY1REFZUyA9IGludDY0KDMxNTM2MDAwKQoKCW1heEluY2VudGl2ZVN0YXJ0RGVsYXkgPSA3ICogMjQgKiB0aW1lLkhvdXIKCglNQVhfVU5JWF9FUE9DSF9USU1FID0gMjUzNDAyMzAwNzk5IC8vIDk5OTktMTItMzEgMjM6NTk6NTkKCgltYXhVbnN0YWtpbmdGZWUgPSB1aW50NjQoMTAwMCkgLy8gMTAlCikKCi8vIGFzc2VydElzVmFsaWRBbW91bnQgZW5zdXJlcyB0aGUgYW1vdW50IGlzIG5vbi1uZWdhdGl2ZS4KZnVuYyBhc3NlcnRJc1ZhbGlkQW1vdW50KGFtb3VudCBpbnQ2NCkgewoJaWYgYW1vdW50IDwgMCB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckludmFsaWRJbnB1dCwKCQkJdWZtdC5TcHJpbnRmKCJhbW91bnQoJWQpIG11c3QgYmUgcG9zaXRpdmUiLCBhbW91bnQpLAoJCSkpCgl9Cn0KCi8vIGFzc2VydElzVmFsaWRSZXdhcmRBbW91bnRGb3JtYXQgZW5zdXJlcyB0aGUgcmV3YXJkIGFtb3VudCBzdHJpbmcgaXMgZm9ybWF0dGVkIGFzICJ0b2tlblBhdGg6YW1vdW50Ii4KZnVuYyBhc3NlcnRJc1ZhbGlkUmV3YXJkQW1vdW50Rm9ybWF0KHJld2FyZEFtb3VudFN0ciBzdHJpbmcpIHsKCXBhcnRzIDo9IHN0cmluZ3MuU3BsaXROKHJld2FyZEFtb3VudFN0ciwgIjoiLCAyKQoJaWYgbGVuKHBhcnRzKSAhPSAyIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZElucHV0LAoJCQl1Zm10LlNwcmludGYoImludmFsaWQgZm9ybWF0IGZvciBTZXRUb2tlbk1pbmltdW1SZXdhcmRBbW91bnQgcGFyYW1zOiBleHBlY3RlZCAndG9rZW5QYXRoOmFtb3VudCcsIGdvdCAnJXMnIiwgcmV3YXJkQW1vdW50U3RyKSwKCQkpKQoJfQp9CgovLyBhc3NlcnRJc0RlcG9zaXRvciBlbnN1cmVzIHRoZSBjYWxsZXIgaXMgdGhlIG93bmVyIG9mIHRoZSBkZXBvc2l0LgpmdW5jIGFzc2VydElzRGVwb3NpdG9yKHMgKnN0YWtlclYxLCBjYWxsZXIgYWRkcmVzcywgcG9zaXRpb25JZCB1aW50NjQpIHsKCWRlcG9zaXQgOj0gcy5nZXREZXBvc2l0cygpLmdldChwb3NpdGlvbklkKQoJaWYgZGVwb3NpdCA9PSBuaWwgewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJEYXRhTm90Rm91bmQsCgkJCXVmbXQuU3ByaW50ZigicG9zaXRpb25JZCglZCkgbm90IGZvdW5kIiwgcG9zaXRpb25JZCksCgkJKSkKCX0KCglpZiBjYWxsZXIgIT0gZGVwb3NpdC5Pd25lcigpIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJyTm9QZXJtaXNzaW9uLAoJCQl1Zm10LlNwcmludGYoImNhbGxlciglcykgaXMgbm90IGRlcG9zaXRvciglcykiLCBjYWxsZXIuU3RyaW5nKCksIGRlcG9zaXQuT3duZXIoKS5TdHJpbmcoKSksCgkJKSkKCX0KfQoKLy8gYXNzZXJ0SXNJbmNlbnRpdmVPZkRlcG9zaXQgZW5zdXJlcyB0aGUgaW5jZW50aXZlIGV4aXN0cyBhbmQgdGFyZ2V0cyB0aGUgcG9vbCB0aGUgcG9zaXRpb24gaXMgc3Rha2VkCi8vIGluLCBzbyBhIGNhbGxlciBjYW5ub3QgYXNrIGEgZGVwb3NpdCB0byBjb2xsZWN0IGFuIGluY2VudGl2ZSB0aGF0IGNhbiBuZXZlciBwYXkgaXQuCi8vIGFzc2VydElzSW5jZW50aXZlT2ZQb29sIGVuc3VyZXMgdGhlIGluY2VudGl2ZSB0YXJnZXRzIHRoZSBwb29sIHRoZSBwb3NpdGlvbiBpcyBzdGFrZWQgaW4uCmZ1bmMgYXNzZXJ0SXNJbmNlbnRpdmVPZlBvb2wocyAqc3Rha2VyVjEsIHBvb2xQYXRoIHN0cmluZywgcG9zaXRpb25JZCB1aW50NjQsIGluY2VudGl2ZUlkIHN0cmluZykgewoJLy8gZ2V0IHBhbmljcyB3aXRoIGVyckRhdGFOb3RGb3VuZCB3aGVuIHRoZSBpbmNlbnRpdmUgZG9lcyBub3QgZXhpc3QuCglpbmNlbnRpdmUgOj0gcy5nZXRFeHRlcm5hbEluY2VudGl2ZXMoKS5nZXQoaW5jZW50aXZlSWQpCgoJaWYgaW5jZW50aXZlLlRhcmdldFBvb2xQYXRoKCkgIT0gcG9vbFBhdGggewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbnZhbGlkSW5wdXQsCgkJCXVmbXQuU3ByaW50ZigKCQkJCSJpbmNlbnRpdmVJZCglcykgdGFyZ2V0cyBwb29sKCVzKSwgYnV0IHBvc2l0aW9uSWQoJWQpIGlzIHN0YWtlZCBpbiBwb29sKCVzKSIsCgkJCQlpbmNlbnRpdmVJZCwgaW5jZW50aXZlLlRhcmdldFBvb2xQYXRoKCksIHBvc2l0aW9uSWQsIHBvb2xQYXRoLAoJCQkpLAoJCSkpCgl9Cn0KCi8vIGFzc2VydEhhc05vRXhpdENoZWNrcG9pbnQgZW5zdXJlcyB0aGUgcG9zaXRpb24gY2FycmllcyBubyByZXdhcmQgZnJvbSBhIHByZXZpb3VzIHN0YWtlLgovLyBDb2xsZWN0aW5nIGl0IGhlcmUgd291bGQgc211Z2dsZSBhbiB1bmJvdW5kZWQgY2FsY3VsYXRpb24gaW50byBzdGFraW5nLCBhbmQgbGVhdmluZyBpdCB3b3VsZAovLyBsZXQgdGhlIG5leHQgdW5zdGFrZSBvdmVyd3JpdGUgdGhlIGNoZWNrcG9pbnQuCmZ1bmMgYXNzZXJ0SGFzTm9FeGl0Q2hlY2twb2ludChzICpzdGFrZXJWMSwgcG9zaXRpb25JZCB1aW50NjQpIHsKCWlmIHMuSGFzVW5zdGFrZWRQb3NpdGlvbihwb3NpdGlvbklkKSB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyclVuY29sbGVjdGVkUG9zaXRpb24sCgkJCXVmbXQuU3ByaW50ZigicG9zaXRpb25JZCglZCkgY2Fubm90IGJlIHN0YWtlZCB3aGlsZSBpdHMgZXhpdCBjaGVja3BvaW50IG93ZXMgcmV3YXJkczsgY29sbGVjdCBhZnRlciBlbWlzc2lvbiByZXN1bWVzIGlmIGVtaXNzaW9uIGlzIGhhbHRlZCIsIHBvc2l0aW9uSWQpLAoJCSkpCgl9Cn0KCi8vIGFzc2VydEhhc05vVW5jb2xsZWN0ZWRJbmNlbnRpdmUgZW5zdXJlcyBubyB1bnN0YWtlZCBwb3NpdGlvbiBzdGlsbCBvd2VzIGEgcmV3YXJkIGZyb20gdGhpcwovLyBpbmNlbnRpdmUsIHdoaWNoIGhhcyBub3QgYmVlbiBkcmF3biBkb3duIGZyb20gaXQgeWV0LgpmdW5jIGFzc2VydEhhc05vVW5jb2xsZWN0ZWRJbmNlbnRpdmUocyAqc3Rha2VyVjEsIGluY2VudGl2ZUlkIHN0cmluZykgewoJY291bnQgOj0gcy51bmNvbGxlY3RlZEluY2VudGl2ZUNvdW50T2YoaW5jZW50aXZlSWQpCglpZiBjb3VudCA+IDAgewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJVbmNvbGxlY3RlZFBvc2l0aW9uLAoJCQl1Zm10LlNwcmludGYoImluY2VudGl2ZSglcykgaXMgb3dlZCB0byAlZCB1bnN0YWtlZCBwb3NpdGlvbihzKSIsIGluY2VudGl2ZUlkLCBjb3VudCksCgkJKSkKCX0KfQoKLy8gYXNzZXJ0SXNOb3RTdGFrZWQgZW5zdXJlcyB0aGUgcG9zaXRpb24gaXMgbm90IGFscmVhZHkgc3Rha2VkLgpmdW5jIGFzc2VydElzTm90U3Rha2VkKHMgKnN0YWtlclYxLCBwb3NpdGlvbklkIHVpbnQ2NCkgewoJaWYgcy5nZXREZXBvc2l0cygpLkhhcyhwb3NpdGlvbklkKSB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckFscmVhZHlTdGFrZWQsCgkJCXVmbXQuU3ByaW50ZigicG9zaXRpb25JZCglZCkgYWxyZWFkeSBzdGFrZWQiLCBwb3NpdGlvbklkKSwKCQkpKQoJfQp9CgovLyBhc3NlcnRJc1Bvb2xFeGlzdHMgZW5zdXJlcyB0aGUgcG9vbCBleGlzdHMuCmZ1bmMgYXNzZXJ0SXNQb29sRXhpc3RzKHMgKnN0YWtlclYxLCBwb29sUGF0aCBzdHJpbmcpIHsKCWlmICFzLnBvb2xBY2Nlc3Nvci5FeGlzdHNQb29sUGF0aChwb29sUGF0aCkgewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbnZhbGlkUG9vbFBhdGgsCgkJCXVmbXQuU3ByaW50ZigicG9vbCglcykgZG9lcyBub3QgZXhpc3QiLCBwb29sUGF0aCksCgkJKSkKCX0KfQoKLy8gYXNzZXJ0SXNWYWxpZFBvb2xUaWVyIGVuc3VyZXMgdGhlIHRpZXIgaXMgd2l0aGluIHZhbGlkIHJhbmdlLgpmdW5jIGFzc2VydElzVmFsaWRQb29sVGllcih0aWVyIHVpbnQ2NCkgewoJaWYgdGllciA+PSBBbGxUaWVyQ291bnQgewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbnZhbGlkUG9vbFRpZXIsCgkJCXVmbXQuU3ByaW50ZigidGllciglZCkgbXVzdCBiZSBsZXNzIHRoYW4gJWQiLCB0aWVyLCBBbGxUaWVyQ291bnQpLAoJCSkpCgl9Cn0KCi8vIGFzc2VydFRpZXIxSGFzU3BhcmVQb29sIGVuc3VyZXMgdGllciAxIGtlZXBzIGF0IGxlYXN0IG9uZSBwb29sIGFmdGVyIGEgdGllciBjaGFuZ2UuCmZ1bmMgYXNzZXJ0VGllcjFIYXNTcGFyZVBvb2woY3VycmVudFRpZXIsIHRpZXIxQ291bnQgdWludDY0KSB7CglpZiBjdXJyZW50VGllciA9PSBUaWVyMSAmJiB0aWVyMUNvdW50ID09IDEgewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKGVyckludmFsaWRQb29sVGllciwgInRpZXIgMSBtdXN0IGhhdmUgYXQgbGVhc3Qgb25lIHBvb2wiKSkKCX0KfQoKLy8gYXNzZXJ0SXNHcmVhdGVyVGhhbk1pbmltdW1SZXdhcmRBbW91bnQgZW5zdXJlcyB0aGUgcmV3YXJkIGFtb3VudCBtZWV0cyBtaW5pbXVtIHJlcXVpcmVtZW50cy4KZnVuYyBhc3NlcnRJc0dyZWF0ZXJUaGFuTWluaW11bVJld2FyZEFtb3VudChzICpzdGFrZXJWMSwgcmV3YXJkVG9rZW4gc3RyaW5nLCByZXdhcmRBbW91bnQgaW50NjQpIHsKCW1pblJld2FyZCA6PSBzLmdldE1pbmltdW1SZXdhcmRBbW91bnQoKQoKCWlmIG1pblJld2FyZEludDY0LCBmb3VuZCA6PSBzLnN0b3JlLkdldFRva2VuU3BlY2lmaWNNaW5pbXVtUmV3YXJkcygpW3Jld2FyZFRva2VuXTsgZm91bmQgewoJCW1pblJld2FyZCA9IG1pblJld2FyZEludDY0Cgl9CgoJaWYgcmV3YXJkQW1vdW50IDwgbWluUmV3YXJkIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZElucHV0LAoJCQl1Zm10LlNwcmludGYoInJld2FyZEFtb3VudCglZCkgaXMgbGVzcyB0aGFuIG1pbmltdW0gcmVxdWlyZWQgYW1vdW50KCVkKSIsIHJld2FyZEFtb3VudCwgbWluUmV3YXJkKSwKCQkpKQoJfQp9CgovLyBhc3NlcnRJc0FsbG93ZWRGb3JFeHRlcm5hbFJld2FyZCBlbnN1cmVzIHRoZSB0b2tlbiBpcyBhbGxvd2VkIGZvciBleHRlcm5hbCByZXdhcmRzLgpmdW5jIGFzc2VydElzQWxsb3dlZEZvckV4dGVybmFsUmV3YXJkKHMgKnN0YWtlclYxLCBwb29sUGF0aCwgdG9rZW5QYXRoIHN0cmluZykgewoJLy8gT3BlcmF0aW9uYWwgc3RvcCBzd2l0Y2g6IGEgZGVuaWVkIHRva2VuIGNhbiBuZXZlciBzdGFydCBhIE5FVyBpbmNlbnRpdmUsCgkvLyB3aGV0aGVyIGl0IHF1YWxpZmllcyBhcyBhIHBvb2wtcGFpciB0b2tlbiBvciB0aHJvdWdoIHRoZSBnb3Zlcm5hbmNlCgkvLyBhbGxvd2xpc3QuIENvbGxlY3Rpb24gb2YgYWxyZWFkeS1jcmVhdGVkIGluY2VudGl2ZXMgaXMgZGVsaWJlcmF0ZWx5CgkvLyB1bmFmZmVjdGVkOyB0aGUgZGVsaXZlcnkgZ3VhcmQgaW4gZGVsaXZlckV4dGVybmFsSW5jZW50aXZlUmV3YXJkIGJvdW5kcwoJLy8gdGhhdCBibGFzdCByYWRpdXMgaW5zdGVhZC4KCWlmIGNvbnRhaW5zKHMuc3RvcmUuR2V0RGVuaWVkUmV3YXJkVG9rZW5zKCksIHRva2VuUGF0aCkgewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJEZW5pZWRSZXdhcmRUb2tlbiwKCQkJdWZtdC5TcHJpbnRmKCJ0b2tlblBhdGgoJXMpIGlzIGRlbmllZCBhcyBhbiBleHRlcm5hbCByZXdhcmQgdG9rZW4iLCB0b2tlblBhdGgpLAoJCSkpCgl9CgoJdG9rZW4wLCB0b2tlbjEsIF8gOj0gcG9vbFBhdGhEaXZpZGUocG9vbFBhdGgpCgoJaWYgdG9rZW5QYXRoID09IHRva2VuMCB8fCB0b2tlblBhdGggPT0gdG9rZW4xIHsKCQlyZXR1cm4KCX0KCglhbGxvd2VkIDo9IGNvbnRhaW5zKHMuc3RvcmUuR2V0QWxsb3dlZFRva2VucygpLCB0b2tlblBhdGgpCglpZiBhbGxvd2VkIHsKCQlyZXR1cm4KCX0KCglwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQllcnJOb3RBbGxvd2VkRm9yRXh0ZXJuYWxSZXdhcmQsCgkJdWZtdC5TcHJpbnRmKCJ0b2tlblBhdGgoJXMpIGlzIG5vdCBhbGxvd2VkIGZvciBleHRlcm5hbCByZXdhcmQgZm9yIHBvb2xQYXRoKCVzKSIsIHRva2VuUGF0aCwgcG9vbFBhdGgpLAoJKSkKfQoKLy8gYXNzZXJ0SXNFeHRlcm5hbFJld2FyZFRva2VuQXZhaWxhYmxlIGVuc3VyZXMgYSBwb29sIGhhcyBubyB1bmZpbmlzaGVkIGluY2VudGl2ZSBmb3IgdGhlIHRva2VuLgpmdW5jIGFzc2VydElzRXh0ZXJuYWxSZXdhcmRUb2tlbkF2YWlsYWJsZShzICpzdGFrZXJWMSwgcG9vbFBhdGgsIHRva2VuUGF0aCBzdHJpbmcsIGN1cnJlbnRUaW1lIGludDY0KSB7Cglwb29sIDo9IHMuZ2V0UG9vbHMoKS5HZXRQb29sT3JOaWwocG9vbFBhdGgpCglpZiBwb29sID09IG5pbCB8fCBwb29sLkluY2VudGl2ZXMoKSA9PSBuaWwgewoJCXJldHVybgoJfQoKCW1pbmltdW1BY3RpdmVJbmNlbnRpdmVTdGFydFRpbWUgOj0gY3VycmVudFRpbWUgLSBUSU1FU1RBTVBfMzY1REFZUwoJaWYgbWluaW11bUFjdGl2ZUluY2VudGl2ZVN0YXJ0VGltZSA8IDAgewoJCW1pbmltdW1BY3RpdmVJbmNlbnRpdmVTdGFydFRpbWUgPSAwCgl9CgoJcG9vbC5JbmNlbnRpdmVzKCkuSXRlcmF0ZUluY2VudGl2ZUlkc0J5VGltZShtaW5pbXVtQWN0aXZlSW5jZW50aXZlU3RhcnRUaW1lLCBtYXRoLk1heEludDY0LCBmdW5jKGluY2VudGl2ZUlEIHN0cmluZykgYm9vbCB7CgkJaW5jZW50aXZlIDo9IHMuZ2V0RXh0ZXJuYWxJbmNlbnRpdmVzKCkuZ2V0KGluY2VudGl2ZUlEKQoJCWlmIGluY2VudGl2ZSA9PSBuaWwgewoJCQlyZXR1cm4gZmFsc2UKCQl9CgoJCWlmIGluY2VudGl2ZS5SZXdhcmRUb2tlbigpICE9IHRva2VuUGF0aCB8fCBOZXdFeHRlcm5hbEluY2VudGl2ZVJlc29sdmVyKGluY2VudGl2ZSkuSXNFbmRlZChjdXJyZW50VGltZSkgewoJCQlyZXR1cm4gZmFsc2UKCQl9CgoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbmNlbnRpdmVBbHJlYWR5RXhpc3RzLAoJCQl1Zm10LlNwcmludGYoCgkJCQkicmV3YXJkVG9rZW4oJXMpIGFscmVhZHkgaGFzIHVuZmluaXNoZWQgaW5jZW50aXZlKCVzKSBmb3IgcG9vbFBhdGgoJXMpIiwKCQkJCXRva2VuUGF0aCwKCQkJCWluY2VudGl2ZUlELAoJCQkJcG9vbFBhdGgsCgkJCSksCgkJKSkKCX0pCn0KCi8vIGFzc2VydElzVmFsaWRGZWVSYXRlIGVuc3VyZXMgdGhlIGZlZSByYXRlIGlzIHdpdGhpbiB2YWxpZCByYW5nZSAoMC0xMDAwIGJhc2lzIHBvaW50cykuCmZ1bmMgYXNzZXJ0SXNWYWxpZEZlZVJhdGUoZmVlIHVpbnQ2NCkgewoJaWYgZmVlID4gbWF4VW5zdGFraW5nRmVlIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZFVuc3Rha2luZ0ZlZSwKCQkJdWZtdC5TcHJpbnRmKCJmZWUoJWQpIG11c3QgYmUgaW4gcmFuZ2UgMCB+ICVkIiwgZmVlLCBtYXhVbnN0YWtpbmdGZWUpLAoJCSkpCgl9Cn0KCi8vIGFzc2VydElzVmFsaWRJbmNlbnRpdmVTdGFydFRpbWUgZW5zdXJlcyB0aGUgaW5jZW50aXZlIHN0YXJ0cyBhdCBtaWRuaWdodCBubyBlYXJsaWVyIHRoYW4gMjQgaG91cnMgYWZ0ZXIgY3JlYXRpb24KLy8gYW5kIG5vIGxhdGVyIHRoYW4gNyBkYXlzIGFmdGVyIHRoZSBmaXJzdCBlbGlnaWJsZSBtaWRuaWdodC4KZnVuYyBhc3NlcnRJc1ZhbGlkSW5jZW50aXZlU3RhcnRUaW1lKHN0YXJ0VGltZXN0YW1wIGludDY0KSB7CgkvLyBtdXN0IGJlIGluIHNlY29uZHMgZm9ybWF0LCBub3QgbWlsbGlzZWNvbmRzCgkvLyBSRUY6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yMzk4MjAwNQoJbnVtU3RyIDo9IHN0cmNvbnYuSXRvYShpbnQoc3RhcnRUaW1lc3RhbXApKQoKCWlmIGxlbihudW1TdHIpID49IDEzIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZEluY2VudGl2ZVN0YXJ0VGltZSwKCQkJdWZtdC5TcHJpbnRmKCJzdGFydFRpbWVzdGFtcCglZCkgbXVzdCBiZSBpbiBzZWNvbmRzIGZvcm1hdCwgbm90IG1pbGxpc2Vjb25kcyIsIHN0YXJ0VGltZXN0YW1wKSwKCQkpKQoJfQoKCS8vIG11c3QgYmUgYXQgbGVhc3QgMjQgaG91cnMgZnJvbSBub3cKCW1pbmltdW1TdGFydFRpbWVzdGFtcCA6PSBnZXRNaW5pbXVtSW5jZW50aXZlU3RhcnRUaW1lc3RhbXAoKQoJaWYgc3RhcnRUaW1lc3RhbXAgPCBtaW5pbXVtU3RhcnRUaW1lc3RhbXAgewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbnZhbGlkSW5jZW50aXZlU3RhcnRUaW1lLAoJCQl1Zm10LlNwcmludGYoInN0YXJ0VGltZXN0YW1wKCVkKSBtdXN0IGJlIGF0IGxlYXN0IDI0IGhvdXJzIGxhdGVyIiwgc3RhcnRUaW1lc3RhbXApLAoJCSkpCgl9CgoJbWF4aW11bVN0YXJ0VGltZXN0YW1wIDo9IGdldE1heGltdW1JbmNlbnRpdmVTdGFydFRpbWVzdGFtcCgpCglpZiBzdGFydFRpbWVzdGFtcCA+IG1heGltdW1TdGFydFRpbWVzdGFtcCB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckludmFsaWRJbmNlbnRpdmVTdGFydFRpbWUsCgkJCXVmbXQuU3ByaW50Zigic3RhcnRUaW1lc3RhbXAoJWQpIGV4Y2VlZHMgdGhlIG1heGltdW0gc3RhcnQgdGltZSBwb2xpY3kiLCBzdGFydFRpbWVzdGFtcCksCgkJKSkKCX0KCgkvLyBtdXN0IGJlIG1pZG5pZ2h0IG9mIHRoZSBkYXkKCXN0YXJ0VGltZSA6PSB0aW1lLlVuaXgoc3RhcnRUaW1lc3RhbXAsIDApCglpZiAhaXNNaWRuaWdodChzdGFydFRpbWUpIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW52YWxpZEluY2VudGl2ZVN0YXJ0VGltZSwKCQkJdWZtdC5TcHJpbnRmKCJzdGFydFRpbWUoJWQgPSAlcykgbXVzdCBiZSBtaWRuaWdodCBvZiB0aGUgZGF5Iiwgc3RhcnRUaW1lc3RhbXAsIHN0YXJ0VGltZS5TdHJpbmcoKSksCgkJKSkKCX0KfQoKLy8gYXNzZXJ0SXNBZG1pbkdvdmVybmFuY2VPckNyZWF0b3IgZW5zdXJlcyB0aGUgY2FsbGVyIG1heSBhY3Qgb24gYW4gaW5jZW50aXZlOgovLyBhZG1pbiBhbmQgZ292ZXJuYW5jZSBhcmUgdGhlIHByb3RvY29sLWxldmVsIG9wZXJhdG9ycywgYW5kIHRoZSBjcmVhdG9yIGlzIHRoZQovLyBhZGRyZXNzIHRoYXQgZnVuZGVkIHRoZSBpbmNlbnRpdmUgaW4gQ3JlYXRlRXh0ZXJuYWxJbmNlbnRpdmUuCmZ1bmMgYXNzZXJ0SXNBZG1pbkdvdmVybmFuY2VPckNyZWF0b3IoY2FsbGVyLCBjcmVhdG9yIGFkZHJlc3MpIHsKCWlmIGNhbGxlciA9PSBjcmVhdG9yIHsKCQlyZXR1cm4KCX0KCWlmIGFjY2Vzcy5Jc0F1dGhvcml6ZWQocHJiYWMuUk9MRV9BRE1JTi5TdHJpbmcoKSwgY2FsbGVyKSB8fAoJCWFjY2Vzcy5Jc0F1dGhvcml6ZWQocHJiYWMuUk9MRV9HT1ZFUk5BTkNFLlN0cmluZygpLCBjYWxsZXIpIHsKCQlyZXR1cm4KCX0KCglwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQllcnJOb1Blcm1pc3Npb24sCgkJdWZtdC5TcHJpbnRmKAoJCQkiY2FsbGVyKCVzKSBtdXN0IGJlIGFkbWluLCBnb3Zlcm5hbmNlLCBvciB0aGUgaW5jZW50aXZlIGNyZWF0b3IoJXMpIiwKCQkJY2FsbGVyLlN0cmluZygpLCBjcmVhdG9yLlN0cmluZygpLAoJCSksCgkpKQp9CgovLyBhc3NlcnRJc05vdFN0YXJ0ZWRJbmNlbnRpdmUgZW5zdXJlcyB0aGUgaW5jZW50aXZlIGNhbiBzdGlsbCBiZSBjYW5jZWxsZWQsIGkuZS4KLy8gaXQgaGFzIG5vdCBzdGFydGVkIGFuZCBub3RoaW5nIGhhcyBiZWVuIGRpc3RyaWJ1dGVkIGZyb20gaXQuIE9ubHkgc3VjaCBhbgovLyBpbmNlbnRpdmUgbWF5IGJlIHJlbW92ZWQgb3V0cmlnaHQ7IGFueXRoaW5nIHRoYXQgYWxyZWFkeSBlbWl0dGVkIHJld2FyZHMgaGFzCi8vIHRvIGJlIGZpbmFsaXplZCB0aHJvdWdoIEVuZEV4dGVybmFsSW5jZW50aXZlIHNvIHRoZSByZWZ1bmQgYWNjb3VudGluZyBhbmQgdGhlCi8vIHBlbmFsdHkgYmFsYW5jZSBzdGF5IHJlYWNoYWJsZS4KZnVuYyBhc3NlcnRJc05vdFN0YXJ0ZWRJbmNlbnRpdmUoaW5jZW50aXZlUmVzb2x2ZXIgKkV4dGVybmFsSW5jZW50aXZlUmVzb2x2ZXIsIGN1cnJlbnRUaW1lIGludDY0KSB7CglpZiBpbmNlbnRpdmVSZXNvbHZlci5Jc1N0YXJ0ZWQoY3VycmVudFRpbWUpIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJyQ2Fubm90Q2FuY2VsSW5jZW50aXZlLAoJCQl1Zm10LlNwcmludGYoCgkJCQkiaW5jZW50aXZlKCVzKSBhbHJlYWR5IHN0YXJ0ZWQgYXQgJWQsIGN1cnJlbnQoJWQpIiwKCQkJCWluY2VudGl2ZVJlc29sdmVyLkluY2VudGl2ZUlkKCksIGluY2VudGl2ZVJlc29sdmVyLlN0YXJ0VGltZXN0YW1wKCksIGN1cnJlbnRUaW1lLAoJCQkpLAoJCSkpCgl9CgoJaWYgaW5jZW50aXZlUmVzb2x2ZXIuUmVmdW5kZWQoKSB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckNhbm5vdENhbmNlbEluY2VudGl2ZSwKCQkJdWZtdC5TcHJpbnRmKCJpbmNlbnRpdmUoJXMpIGhhcyBhbHJlYWR5IGJlZW4gcmVmdW5kZWQiLCBpbmNlbnRpdmVSZXNvbHZlci5JbmNlbnRpdmVJZCgpKSwKCQkpKQoJfQoKCS8vIERlZmVuc2l2ZTogYSBub3QteWV0LXN0YXJ0ZWQgaW5jZW50aXZlIGNhbiBuZXZlciBoYXZlIGRpc3RyaWJ1dGVkIGEgcmV3YXJkCgkvLyBvciBhY2NydWVkIGEgd2FybXVwIHBlbmFsdHkuIFJlbW92aW5nIGEgcmVjb3JkIHRoYXQgY2FycmllcyBlaXRoZXIgd291bGQKCS8vIHN0cmFuZCB0aG9zZSB0b2tlbnMgaW4gdGhlIHN0YWtlciwgc28gcmVmdXNlIGluc3RlYWQgb2YgZHJvcHBpbmcgaXQuCglpZiBpbmNlbnRpdmVSZXNvbHZlci5EaXN0cmlidXRlZFJld2FyZEFtb3VudCgpICE9IDAgfHwgaW5jZW50aXZlUmVzb2x2ZXIuQWNjdW11bGF0ZWRQZW5hbHR5QW1vdW50KCkgIT0gMCB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckNhbm5vdENhbmNlbEluY2VudGl2ZSwKCQkJdWZtdC5TcHJpbnRmKAoJCQkJImluY2VudGl2ZSglcykgaGFzIGFscmVhZHkgYWNjcnVlZCByZXdhcmRzOiBkaXN0cmlidXRlZCglZCksIHBlbmFsdHkoJWQpIiwKCQkJCWluY2VudGl2ZVJlc29sdmVyLkluY2VudGl2ZUlkKCksCgkJCQlpbmNlbnRpdmVSZXNvbHZlci5EaXN0cmlidXRlZFJld2FyZEFtb3VudCgpLAoJCQkJaW5jZW50aXZlUmVzb2x2ZXIuQWNjdW11bGF0ZWRQZW5hbHR5QW1vdW50KCksCgkJCSksCgkJKSkKCX0KfQoKLy8gZ2V0TWluaW11bUluY2VudGl2ZVN0YXJ0VGltZXN0YW1wIHJldHVybnMgYWZ0ZXIgMjQgaG91cnMgZnJvbSBub3cuCmZ1bmMgZ2V0TWluaW11bUluY2VudGl2ZVN0YXJ0VGltZXN0YW1wKCkgaW50NjQgewoJcmV0dXJuIHRpbWUuTm93KCkuQWRkKDI0ICogdGltZS5Ib3VyKS5Vbml4KCkKfQoKLy8gZ2V0TWF4aW11bUluY2VudGl2ZVN0YXJ0VGltZXN0YW1wIHJldHVybnMgNyBkYXlzIGFmdGVyIHRoZSBmaXJzdCBtaWRuaWdodCB0aGF0IHNhdGlzZmllcwovLyB0aGUgbWluaW11bSAyNC1ob3VyIGRlbGF5LgpmdW5jIGdldE1heGltdW1JbmNlbnRpdmVTdGFydFRpbWVzdGFtcCgpIGludDY0IHsKCW1pbmltdW1TdGFydFRpbWVzdGFtcCA6PSBnZXRNaW5pbXVtSW5jZW50aXZlU3RhcnRUaW1lc3RhbXAoKQoJZmlyc3RFbGlnaWJsZU1pZG5pZ2h0IDo9IHRpbWUuVW5peChtaW5pbXVtU3RhcnRUaW1lc3RhbXAsIDApLlRydW5jYXRlKDI0ICogdGltZS5Ib3VyKQoJaWYgZmlyc3RFbGlnaWJsZU1pZG5pZ2h0LlVuaXgoKSA8IG1pbmltdW1TdGFydFRpbWVzdGFtcCB7CgkJZmlyc3RFbGlnaWJsZU1pZG5pZ2h0ID0gZmlyc3RFbGlnaWJsZU1pZG5pZ2h0LkFkZCgyNCAqIHRpbWUuSG91cikKCX0KCglyZXR1cm4gZmlyc3RFbGlnaWJsZU1pZG5pZ2h0LkFkZChtYXhJbmNlbnRpdmVTdGFydERlbGF5KS5Vbml4KCkKfQoKLy8gYXNzZXJ0SXNWYWxpZEluY2VudGl2ZUVuZFRpbWUgZW5zdXJlcyB0aGUgZW5kIHRpbWVzdGFtcCBpcyB3aXRoaW4gdmFsaWQgZXBvY2ggcmFuZ2UuCmZ1bmMgYXNzZXJ0SXNWYWxpZEluY2VudGl2ZUVuZFRpbWUoZW5kVGltZXN0YW1wIGludDY0KSB7CglpZiBlbmRUaW1lc3RhbXAgPj0gTUFYX1VOSVhfRVBPQ0hfVElNRSB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckludmFsaWRJbnB1dCwKCQkJdWZtdC5TcHJpbnRmKCJlbmRUaW1lc3RhbXAoJWQpIGNhbm5vdCBiZSBsYXRlciB0aGFuIDI1MzQwMjMwMDc5OSAoOTk5OS0xMi0zMSAyMzo1OTo1OSkiLCBlbmRUaW1lc3RhbXApLAoJCSkpCgl9Cn0KCi8vIGFzc2VydElzVmFsaWRJbmNlbnRpdmVEdXJhdGlvbiBlbnN1cmVzIHRoZSBkdXJhdGlvbiBpcyA5MCwgMTgwLCBvciAzNjUgZGF5cy4KZnVuYyBhc3NlcnRJc1ZhbGlkSW5jZW50aXZlRHVyYXRpb24oZXh0ZXJuYWxEdXJhdGlvbiBpbnQ2NCkgewoJc3dpdGNoIGV4dGVybmFsRHVyYXRpb24gewoJY2FzZSBUSU1FU1RBTVBfOTBEQVlTLCBUSU1FU1RBTVBfMTgwREFZUywgVElNRVNUQU1QXzM2NURBWVM6CgkJcmV0dXJuCgl9CgoJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJZXJySW52YWxpZEluY2VudGl2ZUR1cmF0aW9uLAoJCXVmbXQuU3ByaW50ZigiZXh0ZXJuYWxEdXJhdGlvbiglZCkgbXVzdCBiZSA5MCwgMTgwLCAzNjUgZGF5cyIsIGV4dGVybmFsRHVyYXRpb24pLAoJKSkKfQoKLy8gQXNzZXJ0SXNWYWxpZEFkZHJlc3MgcGFuaWNzIGlmIHRoZSBwcm92aWRlZCBhZGRyZXNzIGlzIGludmFsaWQuCmZ1bmMgYXNzZXJ0SXNWYWxpZEFkZHJlc3MoYWRkciBhZGRyZXNzKSB7CglpZiBhZGRyID09ICIiIHx8ICFhZGRyLklzVmFsaWQoKSB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckludmFsaWRBZGRyZXNzLAoJCQl1Zm10LlNwcmludGYoImFkZHJlc3MoJXMpIGlzIGludmFsaWQiLCBhZGRyLlN0cmluZygpKSwKCQkpKQoJfQp9CgovLyBpc01pZG5pZ2h0IGNoZWNrcyBpZiBhIHRpbWUgcmVwcmVzZW50cyBtaWRuaWdodCAoMDA6MDA6MDApLgpmdW5jIGlzTWlkbmlnaHQoc3RhcnRUaW1lIHRpbWUuVGltZSkgYm9vbCB7Cglob3VyIDo9IHN0YXJ0VGltZS5Ib3VyKCkKCW1pbnV0ZSA6PSBzdGFydFRpbWUuTWludXRlKCkKCXNlY29uZCA6PSBzdGFydFRpbWUuU2Vjb25kKCkKCglyZXR1cm4gaG91ciA9PSAwICYmIG1pbnV0ZSA9PSAwICYmIHNlY29uZCA9PSAwCn0KCi8vIGFzc2VydElzUG9zaXRpb25Pd25lciB2YWxpZGF0ZXMgdGhhdCB0aGUgY2FsbGVyIGhhcyBwZXJtaXNzaW9uIHRvIG9wZXJhdGUgdGhlIHRva2VuLgpmdW5jIGFzc2VydElzUG9zaXRpb25Pd25lcihvd25lciwgY2FsbGVyIGFkZHJlc3MpIHsKCWlmIG93bmVyICE9IGNhbGxlciB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyck5vUGVybWlzc2lvbiwKCQkJdWZtdC5TcHJpbnRmKCJjYWxsZXIoJXMpIGlzIG5vdCBvd25lciBvZiBwb3NpdGlvbklkKCVzKSIsIGNhbGxlciwgb3duZXIpLAoJCSkpCgl9Cn0KGpaqAQoiY2FsY3VsYXRlX3Bvb2xfcG9zaXRpb25fcmV3YXJkLmdubxLuqQFwYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCSJ0aW1lIgoKCSJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCglzciAiZ25vLmxhbmQvci9nbm9zd2FwL3N0YWtlciIKKQoKLy8gUmV3YXJkIGlzIGEgc3RydWN0IGZvciBzdG9yaW5nIHJld2FyZCBmb3IgYSBwb3NpdGlvbi4KLy8gSW50ZXJuYWwgcmV3YXJkIGlzIHRoZSBHTlMgcmV3YXJkLCBleHRlcm5hbCByZXdhcmQgaXMgdGhlIHJld2FyZCBmb3Igb3RoZXIgaW5jZW50aXZlcy4KLy8gUGVuYWx0aWVzIGFyZSB0aGUgYW1vdW50IHRoYXQgaXMgZGVkdWN0ZWQgZnJvbSB0aGUgcmV3YXJkIGR1ZSB0byB0aGUgcG9zaXRpb24ncyB3YXJtdXAuCnR5cGUgUmV3YXJkIHN0cnVjdCB7CglJbnRlcm5hbCAgICAgICAgaW50NjQKCUludGVybmFsUGVuYWx0eSBpbnQ2NAoJRXh0ZXJuYWwgICAgICAgIG1hcFtzdHJpbmddaW50NjQgLy8gSW5jZW50aXZlIElEIC0+IFRva2VuQW1vdW50CglFeHRlcm5hbFBlbmFsdHkgbWFwW3N0cmluZ11pbnQ2NCAvLyBJbmNlbnRpdmUgSUQgLT4gVG9rZW5BbW91bnQKfQoKLy8gYWdncmVnYXRlUmV3YXJkcyBzdW1zIHRoZSBwZXItd2FybXVwIHJld2FyZHMvcGVuYWx0aWVzIGludG8gYSBzaW5nbGUgUmV3YXJkLgpmdW5jIGFnZ3JlZ2F0ZVJld2FyZHMocmV3YXJkcyBbXVJld2FyZCkgUmV3YXJkIHsKCWludGVybmFsIDo9IGludDY0KDApCglpbnRlcm5hbFBlbmFsdHkgOj0gaW50NjQoMCkKCglyZXdhcmRMZW4gOj0gbGVuKHJld2FyZHMpCglleHRlcm5hbFJld2FyZCA6PSBtYWtlKG1hcFtzdHJpbmddaW50NjQsIHJld2FyZExlbikKCWV4dGVybmFsUGVuYWx0eSA6PSBtYWtlKG1hcFtzdHJpbmddaW50NjQsIHJld2FyZExlbikKCglmb3IgXywgcmV3YXJkIDo9IHJhbmdlIHJld2FyZHMgewoJCWludGVybmFsID0gZ25zbWF0aC5TYWZlQWRkSW50NjQoaW50ZXJuYWwsIHJld2FyZC5JbnRlcm5hbCkKCQlpbnRlcm5hbFBlbmFsdHkgPSBnbnNtYXRoLlNhZmVBZGRJbnQ2NChpbnRlcm5hbFBlbmFsdHksIHJld2FyZC5JbnRlcm5hbFBlbmFsdHkpCgoJCWZvciBpbmNlbnRpdmUsIGFtb3VudCA6PSByYW5nZSByZXdhcmQuRXh0ZXJuYWwgewoJCQlleHRlcm5hbFJld2FyZFtpbmNlbnRpdmVdID0gZ25zbWF0aC5TYWZlQWRkSW50NjQoZXh0ZXJuYWxSZXdhcmRbaW5jZW50aXZlXSwgYW1vdW50KQoJCX0KCgkJZm9yIGluY2VudGl2ZSwgcGVuYWx0eSA6PSByYW5nZSByZXdhcmQuRXh0ZXJuYWxQZW5hbHR5IHsKCQkJZXh0ZXJuYWxQZW5hbHR5W2luY2VudGl2ZV0gPSBnbnNtYXRoLlNhZmVBZGRJbnQ2NChleHRlcm5hbFBlbmFsdHlbaW5jZW50aXZlXSwgcGVuYWx0eSkKCQl9Cgl9CgoJcmV0dXJuIFJld2FyZHsKCQlJbnRlcm5hbDogICAgICAgIGludGVybmFsLAoJCUludGVybmFsUGVuYWx0eTogaW50ZXJuYWxQZW5hbHR5LAoJCUV4dGVybmFsOiAgICAgICAgZXh0ZXJuYWxSZXdhcmQsCgkJRXh0ZXJuYWxQZW5hbHR5OiBleHRlcm5hbFBlbmFsdHksCgl9Cn0KCi8vIGNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkUGFyYW0gaXMgYSBzdHJ1Y3QgZm9yIGNhbGN1bGF0aW5nIHBvc2l0aW9uIHJld2FyZAp0eXBlIGNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkUGFyYW0gc3RydWN0IHsKCS8vIEVudmlyb25tZW50YWwgdmFyaWFibGVzCglDdXJyZW50SGVpZ2h0IGludDY0CglDdXJyZW50VGltZSAgIGludDY0CglEZXBvc2l0cyAgICAgICpEZXBvc2l0cwoJUG9vbHMgICAgICAgICAqUG9vbHMKCVBvb2xUaWVyICAgICAgKlBvb2xUaWVyCgoJLy8gUG9zaXRpb24gdmFyaWFibGVzCglQb3NpdGlvbklkIHVpbnQ2NAoKCS8vIERlcG9zaXQgb3ZlcnJpZGVzIHRoZSBEZXBvc2l0cyBsb29rdXAgZm9yIGEgZGVwb3NpdCB0aGF0IGlzIG5vIGxvbmdlciBpbiB0aGUgdHJlZS4KCURlcG9zaXQgKnNyLkRlcG9zaXQKCS8vIEV4aXQgcGlucyB0aGUgcG9vbCBzdGF0ZSB0byB0aGUgbW9tZW50IHRoZSBwb3NpdGlvbiBsZWZ0IHRoZSBwb29sOyBuaWwgd2hpbGUgc3Rha2VkLgoJRXhpdCAqc3IuVW5zdGFrZWRQb3NpdGlvbgp9CgovLyBkZXBvc2l0IHJlc29sdmVzIHRoZSBkZXBvc2l0IHRoZSBjYWxjdWxhdGlvbiBydW5zIGFnYWluc3QuCmZ1bmMgKHNlbGYgKmNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkUGFyYW0pIGRlcG9zaXQoKSAqc3IuRGVwb3NpdCB7CglpZiBzZWxmLkRlcG9zaXQgIT0gbmlsIHsKCQlyZXR1cm4gc2VsZi5EZXBvc2l0Cgl9CgoJcmV0dXJuIHNlbGYuRGVwb3NpdHMuZ2V0KHNlbGYuUG9zaXRpb25JZCkKfQoKLy8gcG9zaXRpb25SZXdhcmRVcGRhdGUgY2FycmllcyB0aGUgcGVyc2lzdGVkLXN0YXRlIGNoYW5nZXMgcHJvZHVjZWQgKGJ1dCBub3QgYXBwbGllZCkgYnkgYSBjYWxjdWxhdGlvbi4KLy8gVGhleSBhcmUgYXBwbGllZCBieSB0aGUgdXBkYXRlKiBmdW5jdGlvbnMsIHNvIHRoYXQgb25seSB0aGUgY29sbGVjdCBwYXRoIG11dGF0ZXMgc3RhdGUgd2hpbGUgdGhlCi8vIGNhbGN1bGF0aW9uIHN0YXlzIHB1cmUuCnR5cGUgcG9zaXRpb25SZXdhcmRVcGRhdGUgc3RydWN0IHsKCXBvb2xQYXRoICAgIHN0cmluZwoJcG9vbCAgICAgICAgKnNyLlBvb2wKCXBvb2xFeGlzdGVkIGJvb2wKCgkvLyBFeHRlcm5hbCBpbmNlbnRpdmUgaWRzIGRpc2NvdmVyZWQgYXMgbmV3bHkgY3JlYXRlZCBzaW5jZSB0aGUgZGVwb3NpdCdzIGxhc3QgdXBkYXRlOyB0aGV5IG11c3QgYmUKCS8vIGFkZGVkIHRvIHRoZSBkZXBvc2l0J3MgaW5jZW50aXZlIGluZGV4LgoJbmV3RXh0ZXJuYWxJbmNlbnRpdmVJZHMgW11zdHJpbmcKCS8vIFdoZXRoZXIgdGhlIGRlcG9zaXQncyBMYXN0RXh0ZXJuYWxJbmNlbnRpdmVVcGRhdGVkQXQgY3Vyc29yIHNob3VsZCBiZSBhZHZhbmNlZCB0byBDdXJyZW50VGltZS4KCWFkdmFuY2VFeHRlcm5hbEluY2VudGl2ZUN1cnNvciBib29sCgoJLy8gSW5jZW50aXZlIGlkcyB0aGUgY2FsY3VsYXRpb24gYWN0dWFsbHkgcHJvZHVjZWQgYSByZXdhcmQgZm9yLCBpbiBjYWxjdWxhdGlvbiBvcmRlci4gVGhlIGNvbGxlY3QKCS8vIHBhdGggd2Fsa3MgdGhpcyBpbnN0ZWFkIG9mIGl0ZXJhdGluZyB0aGUgcmV3YXJkIG1hcCwgc28gZGVsaXZlcnkgb3JkZXIgaXMgZGV0ZXJtaW5pc3RpYy4KCWV4dGVybmFsSW5jZW50aXZlSWRzIFtdc3RyaW5nCn0KCi8vIHBvc2l0aW9uUmV3YXJkQ29udGV4dCBjYXJyaWVzIHRoZSBwZXItcG9zaXRpb24gc3RhdGUgdGhhdCBib3RoIHRoZSBpbnRlcm5hbCAoR05TIGVtaXNzaW9uKSBhbmQgdGhlCi8vIGV4dGVybmFsIChpbmNlbnRpdmUpIHJld2FyZCBjYWxjdWxhdGlvbnMgbmVlZC4gUmVzb2x2aW5nIGl0IG9uY2UgbGV0cyBlYWNoIHBhdGggYmUgY2FsY3VsYXRlZCBvbiBpdHMKLy8gb3duIHdpdGhvdXQgZHVwbGljYXRpbmcgdGhlIGRlcG9zaXQvcG9vbC9yZXdhcmQtc3RhdGUgc2V0dXAuCnR5cGUgcG9zaXRpb25SZXdhcmRDb250ZXh0IHN0cnVjdCB7CglkZXBvc2l0ICAgICAgICAgKnNyLkRlcG9zaXQKCWRlcG9zaXRSZXNvbHZlciAqRGVwb3NpdFJlc29sdmVyCglwb29sUmVzb2x2ZXIgICAgKlBvb2xSZXNvbHZlcgoJcmV3YXJkU3RhdGUgICAgICpSZXdhcmRTdGF0ZQoJd2FybXVwTGVuICAgICAgIGludAoKCXVwZGF0ZSBwb3NpdGlvblJld2FyZFVwZGF0ZQp9CgovLyBuZXdQb3NpdGlvblJld2FyZENvbnRleHQgcmVzb2x2ZXMgdGhlIGRlcG9zaXQsIGl0cyBwb29sIGFuZCBhIGZyZXNoIFJld2FyZFN0YXRlIFdJVEhPVVQgbXV0YXRpbmcKLy8gcGVyc2lzdGVkIHN0YXRlLiBBIG1pc3NpbmcgcG9vbCBpcyBjcmVhdGVkIGVwaGVtZXJhbGx5IGFuZCBpdHMgcGVyc2lzdGVuY2UgaXMgZGVmZXJyZWQgdG8gdGhlCi8vIHVwZGF0ZSBwYXRoLgpmdW5jIChzICpzdGFrZXJWMSkgbmV3UG9zaXRpb25SZXdhcmRDb250ZXh0KHBhcmFtICpjYWxjdWxhdGVQb3NpdGlvblJld2FyZFBhcmFtKSAqcG9zaXRpb25SZXdhcmRDb250ZXh0IHsKCWRlcG9zaXQgOj0gcGFyYW0uZGVwb3NpdCgpCglwb29sUGF0aCA6PSBkZXBvc2l0LlRhcmdldFBvb2xQYXRoKCkKCglwb29sLCBwb29sRXhpc3RlZCA6PSBwYXJhbS5Qb29scy5HZXQocG9vbFBhdGgpCglpZiAhcG9vbEV4aXN0ZWQgewoJCS8vIFJlYWQtb25seTogdXNlIGFuIGVwaGVtZXJhbCBwb29sOyBwZXJzaXN0ZW5jZSBpcyBkZWZlcnJlZCB0byB1cGRhdGVQb3NpdGlvblJld2FyZC4KCQlwb29sID0gc3IuTmV3UG9vbChwb29sUGF0aCwgcGFyYW0uQ3VycmVudFRpbWUpCgl9Cglwb29sUmVzb2x2ZXIgOj0gbmV3UG9vbFJlc29sdmVyV2l0aEV4aXQocG9vbCwgcGFyYW0uRXhpdCkKCglyZXR1cm4gJnBvc2l0aW9uUmV3YXJkQ29udGV4dHsKCQlkZXBvc2l0OiAgICAgICAgIGRlcG9zaXQsCgkJZGVwb3NpdFJlc29sdmVyOiBOZXdEZXBvc2l0UmVzb2x2ZXIoZGVwb3NpdCksCgkJcG9vbFJlc29sdmVyOiAgICBwb29sUmVzb2x2ZXIsCgkJcmV3YXJkU3RhdGU6ICAgICBwb29sUmVzb2x2ZXIuUmV3YXJkU3RhdGVPZihkZXBvc2l0KSwKCQl3YXJtdXBMZW46ICAgICAgIGxlbihkZXBvc2l0Lldhcm11cHMoKSksCgkJdXBkYXRlOiBwb3NpdGlvblJld2FyZFVwZGF0ZXsKCQkJcG9vbFBhdGg6ICAgIHBvb2xQYXRoLAoJCQlwb29sOiAgICAgICAgcG9vbCwKCQkJcG9vbEV4aXN0ZWQ6IHBvb2xFeGlzdGVkLAoJCX0sCgl9Cn0KCi8vIG5ld1Jld2FyZHMgYWxsb2NhdGVzIHRoZSBlbXB0eSBwZXItd2FybXVwIHJld2FyZCBzbGljZSB0aGUgY29tcHV0ZSogbWV0aG9kcyB3cml0ZSBpbnRvLgpmdW5jIChzZWxmICpwb3NpdGlvblJld2FyZENvbnRleHQpIG5ld1Jld2FyZHMoKSBbXVJld2FyZCB7CglyZXdhcmRzIDo9IG1ha2UoW11SZXdhcmQsIHNlbGYud2FybXVwTGVuKQoJZm9yIGkgOj0gMDsgaSA8IHNlbGYud2FybXVwTGVuOyBpKysgewoJCXJld2FyZHNbaV0gPSBSZXdhcmR7CgkJCUV4dGVybmFsOiAgICAgICAgbWFrZShtYXBbc3RyaW5nXWludDY0KSwKCQkJRXh0ZXJuYWxQZW5hbHR5OiBtYWtlKG1hcFtzdHJpbmddaW50NjQpLAoJCX0KCX0KCglyZXR1cm4gcmV3YXJkcwp9CgovLyBjb21wdXRlSW50ZXJuYWxSZXdhcmRzIHdyaXRlcyB0aGUgR05TIGVtaXNzaW9uIHJld2FyZCBhbmQgcGVuYWx0eSBvZiBlYWNoIHdhcm11cCBpbnRvIHJld2FyZHMuCi8vCi8vIFRoZSBwZXItc2Vjb25kIGVtaXNzaW9uLXJhdGUgc2NoZWR1bGUgaXMgcmVzb2x2ZWQgdXAtZnJvbnQgKHJlc29sdmVJbnRlcm5hbFJld2FyZFNlZ21lbnRzKSBhbmQgZmVkIHRvCi8vIHRoZSBzaW5nbGUgaW50ZXJuYWwtcmV3YXJkIGNhbGN1bGF0b3IsIHNvIHRoZSBjYWxjdWxhdGlvbiBuZWVkcyBubyByZXdhcmQtY2FjaGUgdXBkYXRlLgpmdW5jIChzZWxmICpwb3NpdGlvblJld2FyZENvbnRleHQpIGNvbXB1dGVJbnRlcm5hbFJld2FyZHMocGFyYW0gKmNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkUGFyYW0sIHJld2FyZHMgW11SZXdhcmQpIGVycm9yIHsKCWxhc3RDb2xsZWN0VGltZSA6PSBzZWxmLmRlcG9zaXRSZXNvbHZlci5JbnRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZSgpCgoJLy8gUmVzb2x2ZSB0aGUgcGVyLXNlY29uZCByZXdhcmQtcmF0ZSBzY2hlZHVsZSAocHVyZSkgYW5kIGNhbGN1bGF0ZSBpbnRlcm5hbCByZXdhcmRzIGZyb20gaXQuCglpbnRlcm5hbFNlZ21lbnRzLCBlcnIgOj0gc2VsZi5wb29sUmVzb2x2ZXIucmVzb2x2ZUludGVybmFsUmV3YXJkU2VnbWVudHMocGFyYW0uUG9vbFRpZXIsIHNlbGYudXBkYXRlLnBvb2xQYXRoLCBsYXN0Q29sbGVjdFRpbWUsIHBhcmFtLkN1cnJlbnRUaW1lKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoJY2FsY3VsYXRlZEludGVybmFsUmV3YXJkcywgY2FsY3VsYXRlZEludGVybmFsUGVuYWx0aWVzIDo9IHNlbGYucmV3YXJkU3RhdGUuY2FsY3VsYXRlSW50ZXJuYWxSZXdhcmQoaW50ZXJuYWxTZWdtZW50cykKCglmb3IgaSA6PSAwOyBpIDwgc2VsZi53YXJtdXBMZW47IGkrKyB7CgkJcmV3YXJkc1tpXS5JbnRlcm5hbCA9IGNhbGN1bGF0ZWRJbnRlcm5hbFJld2FyZHNbaV0KCQlyZXdhcmRzW2ldLkludGVybmFsUGVuYWx0eSA9IGNhbGN1bGF0ZWRJbnRlcm5hbFBlbmFsdGllc1tpXQoJfQoKCXNlbGYucmV3YXJkU3RhdGUucmVzZXQoKQoKCXJldHVybiBuaWwKfQoKLy8gZGlzY292ZXJFeHRlcm5hbEluY2VudGl2ZXMgcmVjb3JkcyB0aGUgaW5jZW50aXZlcyBjcmVhdGVkIHNpbmNlIHRoZSBkZXBvc2l0J3MgbGFzdCB1cGRhdGUgb24gdGhlCi8vIHVwZGF0ZSwgV0lUSE9VVCBtdXRhdGluZyB0aGUgZGVwb3NpdC4gVGhlIGNvbGxlY3QgcGF0aCBhZGRzIHRoZW0gdG8gdGhlIGRlcG9zaXQncyBpbmNlbnRpdmUgaW5kZXguCi8vCi8vIEV4dGVybmFsUmV3YXJkTGFzdENvbGxlY3RUaW1lIGZhbGxzIGJhY2sgdG8gU3Rha2VUaW1lIGZvciBpZHMgbm90IHlldCBwZXJzaXN0ZWQsIHNvIGEgbmV3bHktZGlzY292ZXJlZAovLyBpbmNlbnRpdmUgeWllbGRzIHRoZSBzYW1lIGNhbGN1bGF0aW9uIHdoZXRoZXIgb3Igbm90IGl0IGlzIHdyaXR0ZW4gdG8gdGhlIGRlcG9zaXQuCmZ1bmMgKHNlbGYgKnBvc2l0aW9uUmV3YXJkQ29udGV4dCkgZGlzY292ZXJFeHRlcm5hbEluY2VudGl2ZXMocGFyYW0gKmNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkUGFyYW0pIHsKCWxhc3RFeHRlcm5hbEluY2VudGl2ZVVwZGF0ZWRBdCA6PSBzZWxmLmRlcG9zaXRSZXNvbHZlci5MYXN0RXh0ZXJuYWxJbmNlbnRpdmVVcGRhdGVkQXQoKQoJaWYgbGFzdEV4dGVybmFsSW5jZW50aXZlVXBkYXRlZEF0ID49IHBhcmFtLkN1cnJlbnRUaW1lIHsKCQlyZXR1cm4KCX0KCgkvLyBEaXNjb3ZlciBpbmNlbnRpdmVzIGZyb20gdGhpcyBwb29sJ3Mgb3duIHN0YXJ0LXRpbWUgaW5kZXguIFVzaW5nIHRoZQoJLy8gbG9jYWwgcmVzb2x2ZXIga2VlcHMgY2FsY3VsYXRpb24gcmVhZC1vbmx5IGV2ZW4gZm9yIGFuIGVwaGVtZXJhbCBwb29sCgkvLyB0aGF0IGhhcyBub3QgeWV0IGJlZW4gcGVyc2lzdGVkIGluIHBhcmFtLlBvb2xzLgoJbmV3SWRzIDo9IG1ha2UoW11zdHJpbmcsIDApCglzZWxmLnBvb2xSZXNvbHZlci5JbmNlbnRpdmVzUmVzb2x2ZXIoKS5JdGVyYXRlSW5jZW50aXZlSWRzQnlUaW1lKGxhc3RFeHRlcm5hbEluY2VudGl2ZVVwZGF0ZWRBdCwgcGFyYW0uQ3VycmVudFRpbWUsIGZ1bmMoaW5jZW50aXZlSWQgc3RyaW5nKSBib29sIHsKCQluZXdJZHMgPSBhcHBlbmQobmV3SWRzLCBpbmNlbnRpdmVJZCkKCQlyZXR1cm4gZmFsc2UKCX0pCgoJc2VsZi51cGRhdGUubmV3RXh0ZXJuYWxJbmNlbnRpdmVJZHMgPSBuZXdJZHMKCXNlbGYudXBkYXRlLmFkdmFuY2VFeHRlcm5hbEluY2VudGl2ZUN1cnNvciA9IHRydWUKfQoKLy8gZXh0ZXJuYWxJbmNlbnRpdmVJZHMgcmV0dXJucyB0aGUgZGVwb3NpdCdzIGVmZmVjdGl2ZSBpbmNlbnRpdmUtaWQgc2V0OiB0aGUgaWRzIHN0b3JlZCBvbiB0aGUgZGVwb3NpdAovLyBwbHVzIHRoZSBvbmVzIGRpc2NvdmVyRXh0ZXJuYWxJbmNlbnRpdmVzIGZvdW5kLiBDYWxsIGl0IGFmdGVyIGRpc2NvdmVyRXh0ZXJuYWxJbmNlbnRpdmVzLgpmdW5jIChzZWxmICpwb3NpdGlvblJld2FyZENvbnRleHQpIGV4dGVybmFsSW5jZW50aXZlSWRzKCkgW11zdHJpbmcgewoJc2VlbiA6PSBtYWtlKG1hcFtzdHJpbmddYm9vbCkKCWluY2VudGl2ZUlkcyA6PSBtYWtlKFtdc3RyaW5nLCAwKQoKCXNlbGYuZGVwb3NpdC5JdGVyYXRlRXh0ZXJuYWxJbmNlbnRpdmVJZHMoZnVuYyhpbmNlbnRpdmVJZCBzdHJpbmcpIGJvb2wgewoJCWlmICFzZWVuW2luY2VudGl2ZUlkXSB7CgkJCXNlZW5baW5jZW50aXZlSWRdID0gdHJ1ZQoJCQlpbmNlbnRpdmVJZHMgPSBhcHBlbmQoaW5jZW50aXZlSWRzLCBpbmNlbnRpdmVJZCkKCQl9CgkJcmV0dXJuIGZhbHNlCgl9KQoKCWZvciBfLCBpbmNlbnRpdmVJZCA6PSByYW5nZSBzZWxmLnVwZGF0ZS5uZXdFeHRlcm5hbEluY2VudGl2ZUlkcyB7CgkJaWYgIXNlZW5baW5jZW50aXZlSWRdIHsKCQkJc2VlbltpbmNlbnRpdmVJZF0gPSB0cnVlCgkJCWluY2VudGl2ZUlkcyA9IGFwcGVuZChpbmNlbnRpdmVJZHMsIGluY2VudGl2ZUlkKQoJCX0KCX0KCglyZXR1cm4gaW5jZW50aXZlSWRzCn0KCi8vIGNvbXB1dGVFeHRlcm5hbFJld2FyZCB3cml0ZXMgb25lIGluY2VudGl2ZSdzIGV4dGVybmFsIHJld2FyZCBhbmQgcGVuYWx0eSBvZiBlYWNoIHdhcm11cCBpbnRvIHJld2FyZHMuCi8vIEFuIGluY2VudGl2ZSB0aGF0IGRvZXMgbm90IGV4aXN0IG9uIHRoZSBwb29sIG9yIGhhcyBub3Qgc3RhcnRlZCB5ZXQgY29udHJpYnV0ZXMgbm90aGluZy4KZnVuYyAoc2VsZiAqcG9zaXRpb25SZXdhcmRDb250ZXh0KSBjb21wdXRlRXh0ZXJuYWxSZXdhcmQocGFyYW0gKmNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkUGFyYW0sIHJld2FyZHMgW11SZXdhcmQsIGluY2VudGl2ZUlkIHN0cmluZykgewoJaW5jZW50aXZlLCBvayA6PSBzZWxmLnBvb2xSZXNvbHZlci5JbmNlbnRpdmVzUmVzb2x2ZXIoKS5HZXQoaW5jZW50aXZlSWQpCglpZiAhb2sgewoJCXJldHVybgoJfQoKCWluY2VudGl2ZVJlc29sdmVyIDo9IE5ld0V4dGVybmFsSW5jZW50aXZlUmVzb2x2ZXIoaW5jZW50aXZlKQoKCS8vIENoZWNrIGlmIGluY2VudGl2ZSBpcyBhY3RpdmUgZHVyaW5nIHRoaXMgc3BlY2lmaWMgY29sbGVjdGlvbiBwZXJpb2QKCWlmICFpbmNlbnRpdmVSZXNvbHZlci5Jc1N0YXJ0ZWQocGFyYW0uQ3VycmVudFRpbWUpIHsKCQlyZXR1cm4KCX0KCgkvLyBFeHRlcm5hbCBpbmNlbnRpdml6ZWQgcG9vbC4KCS8vIENhbGN1bGF0ZSByZXdhcmQgZm9yIGVhY2ggd2FybXVwIHVzaW5nIHBlci1pbmNlbnRpdmUgbGFzdENvbGxlY3RUaW1lCglleHRlcm5hbExhc3RDb2xsZWN0VGltZSA6PSBzZWxmLmRlcG9zaXRSZXNvbHZlci5FeHRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZShpbmNlbnRpdmVJZCkKCWV4dGVybmFsUmV3YXJkLCBleHRlcm5hbFBlbmFsdHkgOj0gc2VsZi5yZXdhcmRTdGF0ZS5jYWxjdWxhdGVFeHRlcm5hbFJld2FyZChleHRlcm5hbExhc3RDb2xsZWN0VGltZSwgcGFyYW0uQ3VycmVudFRpbWUsIGluY2VudGl2ZSkKCglmb3IgaSA6PSByYW5nZSBleHRlcm5hbFJld2FyZCB7CgkJaWYgZXh0ZXJuYWxSZXdhcmRbaV0gPiAwIHx8IGV4dGVybmFsUGVuYWx0eVtpXSA+IDAgewoJCQlyZXdhcmRzW2ldLkV4dGVybmFsW2luY2VudGl2ZUlkXSA9IGV4dGVybmFsUmV3YXJkW2ldCgkJCXJld2FyZHNbaV0uRXh0ZXJuYWxQZW5hbHR5W2luY2VudGl2ZUlkXSA9IGV4dGVybmFsUGVuYWx0eVtpXQoJCX0KCX0KCglzZWxmLnVwZGF0ZS5leHRlcm5hbEluY2VudGl2ZUlkcyA9IGFwcGVuZChzZWxmLnVwZGF0ZS5leHRlcm5hbEluY2VudGl2ZUlkcywgaW5jZW50aXZlSWQpCglzZWxmLnJld2FyZFN0YXRlLnJlc2V0KCkKfQoKLy8gY29tcHV0ZUV4dGVybmFsUmV3YXJkcyB3cml0ZXMgZXZlcnkgaW5jZW50aXZlIG9mIHRoZSBkZXBvc2l0IGludG8gcmV3YXJkcy4KZnVuYyAoc2VsZiAqcG9zaXRpb25SZXdhcmRDb250ZXh0KSBjb21wdXRlRXh0ZXJuYWxSZXdhcmRzKHBhcmFtICpjYWxjdWxhdGVQb3NpdGlvblJld2FyZFBhcmFtLCByZXdhcmRzIFtdUmV3YXJkKSB7CglzZWxmLmRpc2NvdmVyRXh0ZXJuYWxJbmNlbnRpdmVzKHBhcmFtKQoKCWZvciBfLCBpbmNlbnRpdmVJZCA6PSByYW5nZSBzZWxmLmV4dGVybmFsSW5jZW50aXZlSWRzKCkgewoJCXNlbGYuY29tcHV0ZUV4dGVybmFsUmV3YXJkKHBhcmFtLCByZXdhcmRzLCBpbmNlbnRpdmVJZCkKCX0KfQoKLy8gY2FsY3VsYXRlQ29sbGVjdGFibGVQb3NpdGlvblJld2FyZCBjYWxjdWxhdGVzIHRoZSBhZ2dyZWdhdGVkIHBvc2l0aW9uIHJld2FyZCBXSVRIT1VUIG11dGF0aW5nIGFueSBwZXJzaXN0ZWQgc3RhdGUuCi8vCi8vIEl0IGlzIHRoZSBzaGFyZWQsIHJlYWQtb25seSBlbnRyeSBwb2ludCB1c2VkIGJ5IHRoZSBDb2xsZWN0YWJsZSogdmlldyBnZXR0ZXJzLgovLyBUaGlzIGtlZXBzIHRoZSBjYWxjdWxhdGlvbiBpZGVudGljYWwgZm9yIGV2ZXJ5IGNhbGxlciBhbmQgZ3VhcmFudGVlcyB2aWV3cyBuZXZlciB3cml0ZS4KZnVuYyAocyAqc3Rha2VyVjEpIGNhbGN1bGF0ZUNvbGxlY3RhYmxlUG9zaXRpb25SZXdhcmQoY3VycmVudEhlaWdodCwgY3VycmVudFRpbWVzdGFtcCBpbnQ2NCwgcG9zaXRpb25JZCB1aW50NjQpIChSZXdhcmQsIGVycm9yKSB7CglwYXJhbSA6PSAmY2FsY3VsYXRlUG9zaXRpb25SZXdhcmRQYXJhbXsKCQlDdXJyZW50SGVpZ2h0OiBjdXJyZW50SGVpZ2h0LAoJCUN1cnJlbnRUaW1lOiAgIGN1cnJlbnRUaW1lc3RhbXAsCgkJRGVwb3NpdHM6ICAgICAgcy5nZXREZXBvc2l0cygpLAoJCVBvb2xzOiAgICAgICAgIHMuZ2V0UG9vbHMoKSwKCQlQb29sVGllcjogICAgICBzLmdldFBvb2xUaWVyKCksCgkJUG9zaXRpb25JZDogICAgcG9zaXRpb25JZCwKCX0KCgkvLyBBbiB1bnN0YWtlZCBwb3NpdGlvbiBxdW90ZXMgYWdhaW5zdCBpdHMgZXhpdCBjaGVja3BvaW50LCBhdCBpdHMgZXhpdCB0aW1lLgoJaWYgY2hlY2twb2ludCA6PSBzLmdldFVuc3Rha2VkUG9zaXRpb25zKCkuZ2V0KHBvc2l0aW9uSWQpOyBjaGVja3BvaW50ICE9IG5pbCB7CgkJcGFyYW0uQ3VycmVudFRpbWUgPSBjaGVja3BvaW50LkV4aXRUaW1lKCkKCQlwYXJhbS5EZXBvc2l0ID0gY2hlY2twb2ludC5EZXBvc2l0KCkKCQlwYXJhbS5FeGl0ID0gY2hlY2twb2ludAoJfQoKCXJld2FyZHMsIF8sIGVyciA6PSBzLmNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkKHBhcmFtKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIFJld2FyZHt9LCBlcnIKCX0KCglyZXR1cm4gYWdncmVnYXRlUmV3YXJkcyhyZXdhcmRzKSwgbmlsCn0KCi8vIGNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkIGNvbXB1dGVzIGEgcG9zaXRpb24ncyBwZXItd2FybXVwIGludGVybmFsIEFORCBleHRlcm5hbCByZXdhcmRzIFdJVEhPVVQKLy8gbXV0YXRpbmcgcGVyc2lzdGVkIHN0YXRlLiBBbGwgd291bGQtYmUgc3RhdGUgY2hhbmdlcyBhcmUgcmV0dXJuZWQgYXMgYSBwb3NpdGlvblJld2FyZFVwZGF0ZSBmb3IgdGhlCi8vIGNhbGxlciB0byBhcHBseSAoY29sbGVjdCBvbmx5KS4KZnVuYyAocyAqc3Rha2VyVjEpIGNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkKHBhcmFtICpjYWxjdWxhdGVQb3NpdGlvblJld2FyZFBhcmFtKSAoW11SZXdhcmQsIHBvc2l0aW9uUmV3YXJkVXBkYXRlLCBlcnJvcikgewoJY3R4IDo9IHMubmV3UG9zaXRpb25SZXdhcmRDb250ZXh0KHBhcmFtKQoJcmV3YXJkcyA6PSBjdHgubmV3UmV3YXJkcygpCgoJaWYgZXJyIDo9IGN0eC5jb21wdXRlSW50ZXJuYWxSZXdhcmRzKHBhcmFtLCByZXdhcmRzKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIG5pbCwgcG9zaXRpb25SZXdhcmRVcGRhdGV7fSwgZXJyCgl9CgljdHguY29tcHV0ZUV4dGVybmFsUmV3YXJkcyhwYXJhbSwgcmV3YXJkcykKCglyZXR1cm4gcmV3YXJkcywgY3R4LnVwZGF0ZSwgbmlsCn0KCi8vIGNhbGN1bGF0ZUV4dGVybmFsUG9zaXRpb25SZXdhcmRzIGNvbXB1dGVzIGFsbCBvZiBhIHBvc2l0aW9uJ3MgZXh0ZXJuYWwgaW5jZW50aXZlIHJld2FyZHMgV0lUSE9VVAovLyBtdXRhdGluZyBwZXJzaXN0ZWQgc3RhdGUuIFVzZWQgYnkgdGhlIGNvbWJpbmVkIGNvbGxlY3QgcGF0aCB3aGlsZSBHTlMgZW1pc3Npb24gaXMgaGFsdGVkLgpmdW5jIChzICpzdGFrZXJWMSkgY2FsY3VsYXRlRXh0ZXJuYWxQb3NpdGlvblJld2FyZHMocGFyYW0gKmNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkUGFyYW0pIChbXVJld2FyZCwgcG9zaXRpb25SZXdhcmRVcGRhdGUpIHsKCWN0eCA6PSBzLm5ld1Bvc2l0aW9uUmV3YXJkQ29udGV4dChwYXJhbSkKCXJld2FyZHMgOj0gY3R4Lm5ld1Jld2FyZHMoKQoKCWN0eC5jb21wdXRlRXh0ZXJuYWxSZXdhcmRzKHBhcmFtLCByZXdhcmRzKQoKCXJldHVybiByZXdhcmRzLCBjdHgudXBkYXRlCn0KCi8vIGNhbGN1bGF0ZUludGVybmFsUG9zaXRpb25SZXdhcmQgY29tcHV0ZXMgb25seSBhIHBvc2l0aW9uJ3MgcGVyLXdhcm11cCBHTlMgZW1pc3Npb24gcmV3YXJkcywgV0lUSE9VVAovLyBtdXRhdGluZyBwZXJzaXN0ZWQgc3RhdGUuIFVzZWQgYnkgdGhlIGVtaXNzaW9uIGNvbGxlY3QgcGF0aC4KZnVuYyAocyAqc3Rha2VyVjEpIGNhbGN1bGF0ZUludGVybmFsUG9zaXRpb25SZXdhcmQocGFyYW0gKmNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkUGFyYW0pIChbXVJld2FyZCwgcG9zaXRpb25SZXdhcmRVcGRhdGUsIGVycm9yKSB7CgljdHggOj0gcy5uZXdQb3NpdGlvblJld2FyZENvbnRleHQocGFyYW0pCglyZXdhcmRzIDo9IGN0eC5uZXdSZXdhcmRzKCkKCglpZiBlcnIgOj0gY3R4LmNvbXB1dGVJbnRlcm5hbFJld2FyZHMocGFyYW0sIHJld2FyZHMpOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBwb3NpdGlvblJld2FyZFVwZGF0ZXt9LCBlcnIKCX0KCglyZXR1cm4gcmV3YXJkcywgY3R4LnVwZGF0ZSwgbmlsCn0KCi8vIGNhbGN1bGF0ZUV4dGVybmFsUG9zaXRpb25SZXdhcmQgY29tcHV0ZXMgYSBwb3NpdGlvbidzIHBlci13YXJtdXAgcmV3YXJkIGZvciBvbmUgZXh0ZXJuYWwgaW5jZW50aXZlLAovLyBXSVRIT1VUIG11dGF0aW5nIHBlcnNpc3RlZCBzdGF0ZS4gVXNlZCBieSB0aGUgZXh0ZXJuYWwgaW5jZW50aXZlIGNvbGxlY3QgcGF0aC4KLy8KLy8gSW5jZW50aXZlIGRpc2NvdmVyeSBzdGlsbCBydW5zIG92ZXIgZXZlcnkgaW5jZW50aXZlLCBzbyB0aGUgZGVwb3NpdCdzIGluY2VudGl2ZSBpbmRleCBzdGF5cyBjb21wbGV0ZQovLyBubyBtYXR0ZXIgd2hpY2ggaW5jZW50aXZlIHRoZSBjYWxsZXIgYXNrZWQgZm9yLgpmdW5jIChzICpzdGFrZXJWMSkgY2FsY3VsYXRlRXh0ZXJuYWxQb3NpdGlvblJld2FyZChwYXJhbSAqY2FsY3VsYXRlUG9zaXRpb25SZXdhcmRQYXJhbSwgaW5jZW50aXZlSWQgc3RyaW5nKSAoW11SZXdhcmQsIHBvc2l0aW9uUmV3YXJkVXBkYXRlKSB7CgljdHggOj0gcy5uZXdQb3NpdGlvblJld2FyZENvbnRleHQocGFyYW0pCglyZXdhcmRzIDo9IGN0eC5uZXdSZXdhcmRzKCkKCgljdHguZGlzY292ZXJFeHRlcm5hbEluY2VudGl2ZXMocGFyYW0pCgljdHguY29tcHV0ZUV4dGVybmFsUmV3YXJkKHBhcmFtLCByZXdhcmRzLCBpbmNlbnRpdmVJZCkKCglyZXR1cm4gcmV3YXJkcywgY3R4LnVwZGF0ZQp9CgovLyBwZXJzaXN0TGF6eVBvb2wgcGVyc2lzdHMgYSBwb29sIHRoYXQgY2FsY3VsYXRpb24gY3JlYXRlZCBlcGhlbWVyYWxseSBiZWNhdXNlIGl0IGRpZCBub3QgZXhpc3QgeWV0LgpmdW5jIChzICpzdGFrZXJWMSkgcGVyc2lzdExhenlQb29sKHBhcmFtICpjYWxjdWxhdGVQb3NpdGlvblJld2FyZFBhcmFtLCB1cGRhdGVQYXJhbXMgcG9zaXRpb25SZXdhcmRVcGRhdGUpIHsKCWlmICF1cGRhdGVQYXJhbXMucG9vbEV4aXN0ZWQgewoJCXBhcmFtLlBvb2xzLnNldCh1cGRhdGVQYXJhbXMucG9vbFBhdGgsIHVwZGF0ZVBhcmFtcy5wb29sKQoJfQp9CgovLyB1cGRhdGVJbnRlcm5hbFJld2FyZENhY2hlIGFkdmFuY2VzIHRoZSByZXdhcmQgY2FjaGUgdXAgdG8gQ3VycmVudFRpbWUgKGhhbHZpbmcgYm91bmRhcmllcykuIFRoZQovLyBjYWxjdWxhdGlvbiBpdHNlbGYgbm8gbG9uZ2VyIG5lZWRzIHRoaXMsIGJ1dCBkb3duc3RyZWFtIHVuY2xhaW1hYmxlIHByb2Nlc3NpbmcgKHdoaWNoIHJlYWRzCi8vIEN1cnJlbnRSZXdhcmQpIGFuZCBvZmYtY2hhaW4gaGlzdG9yeSByZWx5IG9uIHRoZSBjYWNoZSwgc28gaXQgaXMgYWR2YW5jZWQgb24gdGhlIGVtaXNzaW9uIGNvbGxlY3QgcGF0aC4KZnVuYyAocyAqc3Rha2VyVjEpIHVwZGF0ZUludGVybmFsUmV3YXJkQ2FjaGUocGFyYW0gKmNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkUGFyYW0sIHVwZGF0ZVBhcmFtcyBwb3NpdGlvblJld2FyZFVwZGF0ZSkgewoJLy8gQWx3YXlzIGF0IHRoZSBjdXJyZW50IHRpbWUsIG5ldmVyIGF0IHBhcmFtLkN1cnJlbnRUaW1lOiB0aGUgY2FjaGUgYW5kIHRoZSB1bmNsYWltYWJsZQoJLy8gdHJhY2tpbmcgaXQgZHJpdmVzIGFyZSBwb29sLWdsb2JhbCwgYW5kIGEgY2hlY2twb2ludCBjb2xsZWN0IHdvdWxkIHJld2luZCB0aGVtIHRvIGl0cyBleGl0CgkvLyB0aW1lc3RhbXAsIHdoZXJlIHRoZSBwb29sIG1heSBoYXZlIGhhZCBubyBzdGFrZWQgbGlxdWlkaXR5LgoJcGFyYW0uUG9vbFRpZXIuY2FjaGVSZXdhcmRGb3JQb29sKHRpbWUuTm93KCkuVW5peCgpLCBwYXJhbS5Qb29scywgdXBkYXRlUGFyYW1zLnBvb2xQYXRoKQp9CgovLyBhcHBseUV4dGVybmFsSW5jZW50aXZlSW5kZXggcGVyc2lzdHMgdGhlIGRlcG9zaXQgaW5jZW50aXZlLWluZGV4IHVwZGF0ZXMgZGlzY292ZXJlZCBkdXJpbmcgY2FsY3VsYXRpb24uCmZ1bmMgKHMgKnN0YWtlclYxKSBhcHBseUV4dGVybmFsSW5jZW50aXZlSW5kZXgocGFyYW0gKmNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkUGFyYW0sIHVwZGF0ZVBhcmFtcyBwb3NpdGlvblJld2FyZFVwZGF0ZSkgewoJaWYgbGVuKHVwZGF0ZVBhcmFtcy5uZXdFeHRlcm5hbEluY2VudGl2ZUlkcykgPT0gMCAmJiAhdXBkYXRlUGFyYW1zLmFkdmFuY2VFeHRlcm5hbEluY2VudGl2ZUN1cnNvciB7CgkJcmV0dXJuCgl9CgoJZGVwb3NpdCA6PSBwYXJhbS5kZXBvc2l0KCkKCWZvciBfLCBpbmNlbnRpdmVJZCA6PSByYW5nZSB1cGRhdGVQYXJhbXMubmV3RXh0ZXJuYWxJbmNlbnRpdmVJZHMgewoJCWRlcG9zaXQuQWRkRXh0ZXJuYWxJbmNlbnRpdmVJZChpbmNlbnRpdmVJZCkKCX0KCWlmIHVwZGF0ZVBhcmFtcy5hZHZhbmNlRXh0ZXJuYWxJbmNlbnRpdmVDdXJzb3IgewoJCWRlcG9zaXQuU2V0TGFzdEV4dGVybmFsSW5jZW50aXZlVXBkYXRlZEF0KHBhcmFtLkN1cnJlbnRUaW1lKQoJfQp9CgovLyB1cGRhdGVQb3NpdGlvblJld2FyZCBhcHBsaWVzIHRoZSBwZXJzaXN0ZWQtc3RhdGUgY2hhbmdlcyBwcm9kdWNlZCBieSBjYWxjdWxhdGVQb3NpdGlvblJld2FyZC4KLy8gSXQgaXMgY2FsbGVkIE9OTFkgYnkgdGhlIGNvbGxlY3QgcGF0aDsgdGhlIENvbGxlY3RhYmxlKiB2aWV3IGdldHRlcnMgZGlzY2FyZCB0aGUgdXBkYXRlLgpmdW5jIChzICpzdGFrZXJWMSkgdXBkYXRlUG9zaXRpb25SZXdhcmQocGFyYW0gKmNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkUGFyYW0sIHVwZGF0ZVBhcmFtcyBwb3NpdGlvblJld2FyZFVwZGF0ZSkgewoJcy5wZXJzaXN0TGF6eVBvb2wocGFyYW0sIHVwZGF0ZVBhcmFtcykKCXMudXBkYXRlSW50ZXJuYWxSZXdhcmRDYWNoZShwYXJhbSwgdXBkYXRlUGFyYW1zKQoJcy5hcHBseUV4dGVybmFsSW5jZW50aXZlSW5kZXgocGFyYW0sIHVwZGF0ZVBhcmFtcykKfQoKLy8gdXBkYXRlSW50ZXJuYWxQb3NpdGlvblJld2FyZCBhcHBsaWVzIHRoZSBzdGF0ZSBjaGFuZ2VzIGJlbG9uZ2luZyB0byB0aGUgZW1pc3Npb24gY29sbGVjdCBwYXRoIG9ubHkuCmZ1bmMgKHMgKnN0YWtlclYxKSB1cGRhdGVJbnRlcm5hbFBvc2l0aW9uUmV3YXJkKHBhcmFtICpjYWxjdWxhdGVQb3NpdGlvblJld2FyZFBhcmFtLCB1cGRhdGVQYXJhbXMgcG9zaXRpb25SZXdhcmRVcGRhdGUpIHsKCXMucGVyc2lzdExhenlQb29sKHBhcmFtLCB1cGRhdGVQYXJhbXMpCglzLnVwZGF0ZUludGVybmFsUmV3YXJkQ2FjaGUocGFyYW0sIHVwZGF0ZVBhcmFtcykKfQoKLy8gdXBkYXRlRXh0ZXJuYWxQb3NpdGlvblJld2FyZCBhcHBsaWVzIHRoZSBzdGF0ZSBjaGFuZ2VzIGJlbG9uZ2luZyB0byB0aGUgZXh0ZXJuYWwgY29sbGVjdCBwYXRoIG9ubHkuCmZ1bmMgKHMgKnN0YWtlclYxKSB1cGRhdGVFeHRlcm5hbFBvc2l0aW9uUmV3YXJkKHBhcmFtICpjYWxjdWxhdGVQb3NpdGlvblJld2FyZFBhcmFtLCB1cGRhdGVQYXJhbXMgcG9zaXRpb25SZXdhcmRVcGRhdGUpIHsKCXMucGVyc2lzdExhenlQb29sKHBhcmFtLCB1cGRhdGVQYXJhbXMpCglzLmFwcGx5RXh0ZXJuYWxJbmNlbnRpdmVJbmRleChwYXJhbSwgdXBkYXRlUGFyYW1zKQp9CgovLyBpbnRlcm5hbFJld2FyZFNlZ21lbnQgaXMgYSBbc3RhcnQsIGVuZCkgc3BhbiBvdmVyIHdoaWNoIHRoZSBwZXItc2Vjb25kIGVtaXNzaW9uIHJld2FyZCByYXRlIGlzIGNvbnN0YW50Lgp0eXBlIGludGVybmFsUmV3YXJkU2VnbWVudCBzdHJ1Y3QgewoJc3RhcnQgICAgICAgICAgIGludDY0CgllbmQgICAgICAgICAgICAgaW50NjQKCXJld2FyZFBlclNlY29uZCBpbnQ2NAp9CgovLyByZXNvbHZlSW50ZXJuYWxSZXdhcmRTZWdtZW50cyBidWlsZHMgdGhlIHBlci1zZWNvbmQgcmV3YXJkLXJhdGUgc2NoZWR1bGUgb3ZlciBbc3RhcnRUaW1lLCBlbmRUaW1lXQovLyBXSVRIT1VUIG11dGF0aW5nIHN0YXRlLgovLwovLyBQZXJzaXN0ZWQgcmV3YXJkLWNhY2hlIGVudHJpZXMgY292ZXIgdGhlIGhpc3RvcmljYWwgcG9ydGlvbjogdGhleSByZWNvcmQgdGllci9jb3VudCBjaGFuZ2VzIGFuZCBhbnkKLy8gaGFsdmluZ3MgYWxyZWFkeSBtYXRlcmlhbGl6ZWQgYnkgcGFzdCBjb2xsZWN0cywgc28gbm8gdW4tbWF0ZXJpYWxpemVkIGhhbHZpbmcgZXhpc3RzIHN0cmljdGx5IGJldHdlZW4KLy8gdHdvIHBlcnNpc3RlZCBlbnRyaWVzLiBUaGUgdGFpbCBiZXlvbmQgdGhlIGxhc3QgcGVyc2lzdGVkIGVudHJ5IGlzIHNwbGl0IGJ5IGhhbHZpbmdzIHVzaW5nIHRoZSBjdXJyZW50Ci8vIHRpZXIgcmF0aW8vY291bnQsIHdoaWNoIGFyZSBuZWNlc3NhcmlseSBjb25zdGFudCB0aGVyZSAoYSBjaGFuZ2Ugd291bGQgaGF2ZSB3cml0dGVuIGEgY2FjaGUgZW50cnkpLiBUaGUKLy8gdGFpbCByYXRlIGlzIHJlY29tcHV0ZWQgd2l0aCB0aGUgc2FtZSBjYWxjdWxhdGVQb29sUmV3YXJkIGFyaXRobWV0aWMgdGhlIGNhY2hlIHdyaXRlciB1c2VzLCBzbyBhCi8vIHNjaGVkdWxlIHJlc29sdmVkIGZyb20gYSBmdWxseSBtYXRlcmlhbGl6ZWQgY2FjaGUgYW5kIG9uZSByZXNvbHZlZCBmcm9tIHRoZSBlbWlzc2lvbiBoYWx2aW5ncyBhcmUKLy8gaWRlbnRpY2FsLgpmdW5jIChzZWxmICpQb29sUmVzb2x2ZXIpIHJlc29sdmVJbnRlcm5hbFJld2FyZFNlZ21lbnRzKHBvb2xUaWVyICpQb29sVGllciwgcG9vbFBhdGggc3RyaW5nLCBzdGFydFRpbWUsIGVuZFRpbWUgaW50NjQpIChbXWludGVybmFsUmV3YXJkU2VnbWVudCwgZXJyb3IpIHsKCXNlZ21lbnRzIDo9IG1ha2UoW11pbnRlcm5hbFJld2FyZFNlZ21lbnQsIDApCglpZiBzdGFydFRpbWUgPj0gZW5kVGltZSB7CgkJcmV0dXJuIHNlZ21lbnRzLCBuaWwKCX0KCgljdXJyZW50UmV3YXJkIDo9IHNlbGYuQ3VycmVudFJld2FyZChzdGFydFRpbWUpCgljdXJzb3IgOj0gc3RhcnRUaW1lCgoJc2VsZi5SZXdhcmRDYWNoZSgpLkl0ZXJhdGUoc3RhcnRUaW1lLCBlbmRUaW1lLCBmdW5jKGtleSBpbnQ2NCwgdmFsdWUgYW55KSBib29sIHsKCQlyZXdhcmQsIG9rIDo9IHZhbHVlLihpbnQ2NCkKCQlpZiAhb2sgewoJCQlwYW5pYyh1Zm10LlNwcmludGYoImZhaWxlZCB0byBjYXN0IHZhbHVlIHRvIGludDY0OiAlVCIsIHZhbHVlKSkKCQl9CgoJCXNlZ21lbnRzID0gYXBwZW5kKHNlZ21lbnRzLCBpbnRlcm5hbFJld2FyZFNlZ21lbnR7c3RhcnQ6IGN1cnNvciwgZW5kOiBrZXksIHJld2FyZFBlclNlY29uZDogY3VycmVudFJld2FyZH0pCgkJY3Vyc29yID0ga2V5CgkJY3VycmVudFJld2FyZCA9IHJld2FyZAoJCXJldHVybiBmYWxzZQoJfSkKCglpZiBjdXJzb3IgPCBlbmRUaW1lIHsKCQl2YXIgZXJyIGVycm9yCgkJc2VnbWVudHMsIGVyciA9IGFwcGVuZEludGVybmFsUmV3YXJkVGFpbFNlZ21lbnRzKHNlZ21lbnRzLCBwb29sVGllciwgcG9vbFBhdGgsIGN1cnNvciwgZW5kVGltZSwgY3VycmVudFJld2FyZCwgc2VsZi5leGl0KQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gbmlsLCBlcnIKCQl9Cgl9CgoJcmV0dXJuIHNlZ21lbnRzLCBuaWwKfQoKLy8gYXBwZW5kSW50ZXJuYWxSZXdhcmRUYWlsU2VnbWVudHMgYXBwZW5kcyB0aGUgc2NoZWR1bGUgZm9yIHRoZSB0YWlsIFtzdGFydFRpbWUsIGVuZFRpbWVdLCB3aGVyZSBubwovLyBwZXJzaXN0ZWQgY2FjaGUgZW50cnkgZXhpc3RzIGJleW9uZCBzdGFydFRpbWUuIE92ZXIgdGhpcyBzcGFuIHRpZXIvY291bnQgYXJlIGNvbnN0YW50LCBzbyB0aGUgcmF0ZQovLyBjaGFuZ2VzIG9ubHkgYXQgaGFsdmluZyBib3VuZGFyaWVzLgpmdW5jIGFwcGVuZEludGVybmFsUmV3YXJkVGFpbFNlZ21lbnRzKHNlZ21lbnRzIFtdaW50ZXJuYWxSZXdhcmRTZWdtZW50LCBwb29sVGllciAqUG9vbFRpZXIsIHBvb2xQYXRoIHN0cmluZywgc3RhcnRUaW1lLCBlbmRUaW1lLCBiYXNlUmV3YXJkIGludDY0LCBleGl0ICpzci5VbnN0YWtlZFBvc2l0aW9uKSAoW11pbnRlcm5hbFJld2FyZFNlZ21lbnQsIGVycm9yKSB7CgkvLyBBIGNoZWNrcG9pbnQgcmVhZHMgdGhlIHRpZXIgY29udGV4dCBpdCBleGl0ZWQgdW5kZXI6IHRoaXMgd2luZG93IGNsb3NlZCBhdCB0aGUgZXhpdCwgYW5kCgkvLyB0aGUgbGl2ZSBsb29rdXAgaXMgc2tpcHBlZCBzbyBhIGNoZWNrcG9pbnQgY29sbGVjdCBuZXZlciBkZXBlbmRzIG9uIGxpdmUgdGllciBzdGF0ZS4KCXZhciB0aWVyLCByYXRpbywgY291bnQgdWludDY0CglpZiBleGl0ICE9IG5pbCB7CgkJdGllciwgcmF0aW8sIGNvdW50ID0gZXhpdC5UaWVyKCksIGV4aXQuVGllclJhdGlvKCksIGV4aXQuVGllckNvdW50KCkKCX0gZWxzZSB7CgkJdmFyIGVyciBlcnJvcgoJCXRpZXIsIHJhdGlvLCBjb3VudCwgZXJyID0gcG9vbFRpZXIudGllckNvbnRleHRPZihwb29sUGF0aCkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIG5pbCwgZXJyCgkJfQoJfQoKCWlmIHRpZXIgPT0gMCB8fCB0aWVyID49IEFsbFRpZXJDb3VudCB7CgkJLy8gTm90IGN1cnJlbnRseSB0aWVyZWQ6IHRoZSByYXRlIGNhbm5vdCBpbmNyZWFzZTsgdGhlIGJhc2UgaXMgMCBhZnRlciBkZS10aWVyLgoJCXJldHVybiBhcHBlbmQoc2VnbWVudHMsIGludGVybmFsUmV3YXJkU2VnbWVudHtzdGFydDogc3RhcnRUaW1lLCBlbmQ6IGVuZFRpbWUsIHJld2FyZFBlclNlY29uZDogYmFzZVJld2FyZH0pLCBuaWwKCX0KCgl0aWVyUmF0aW9JbnQ2NCA6PSBpbnQ2NChyYXRpbykKCXRpZXJDb3VudCA6PSBpbnQ2NChjb3VudCkKCgloYWx2aW5nVGltZXN0YW1wcywgaGFsdmluZ0VtaXNzaW9ucywgZXJyIDo9IHBvb2xUaWVyLmdldEhhbHZpbmdCbG9ja3NJblJhbmdlKHN0YXJ0VGltZSwgZW5kVGltZSkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBuaWwsIGVycgoJfQoKCXNlZ1N0YXJ0IDo9IHN0YXJ0VGltZQoJcmF0ZSA6PSBiYXNlUmV3YXJkCglmb3IgaSwgaHYgOj0gcmFuZ2UgaGFsdmluZ1RpbWVzdGFtcHMgewoJCWlmIGh2IDw9IHNlZ1N0YXJ0IHsKCQkJLy8gSGFsdmluZyBlZmZlY3RpdmUgYXQvYmVmb3JlIHRoZSBzZWdtZW50IHN0YXJ0OiBvbmx5IHN3aXRjaCB0aGUgcmF0ZS4KCQkJcmF0ZSwgZXJyID0gY2FsY3VsYXRlUG9vbFJld2FyZChoYWx2aW5nRW1pc3Npb25zW2ldLCB0aWVyUmF0aW9JbnQ2NCwgdGllckNvdW50KQoJCQlpZiBlcnIgIT0gbmlsIHsKCQkJCXJldHVybiBuaWwsIGVycgoJCQl9CgkJCWNvbnRpbnVlCgkJfQoJCWlmIGh2ID49IGVuZFRpbWUgewoJCQlicmVhawoJCX0KCgkJc2VnbWVudHMgPSBhcHBlbmQoc2VnbWVudHMsIGludGVybmFsUmV3YXJkU2VnbWVudHtzdGFydDogc2VnU3RhcnQsIGVuZDogaHYsIHJld2FyZFBlclNlY29uZDogcmF0ZX0pCgkJcmF0ZSwgZXJyID0gY2FsY3VsYXRlUG9vbFJld2FyZChoYWx2aW5nRW1pc3Npb25zW2ldLCB0aWVyUmF0aW9JbnQ2NCwgdGllckNvdW50KQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gbmlsLCBlcnIKCQl9CgkJc2VnU3RhcnQgPSBodgoJfQoKCXJldHVybiBhcHBlbmQoc2VnbWVudHMsIGludGVybmFsUmV3YXJkU2VnbWVudHtzdGFydDogc2VnU3RhcnQsIGVuZDogZW5kVGltZSwgcmV3YXJkUGVyU2Vjb25kOiByYXRlfSksIG5pbAp9CgovLyBjYWxjdWxhdGVzIGludGVybmFsIHVuY2xhaW1hYmxlIHJld2FyZCBmb3IgdGhlIHBvb2wKZnVuYyAocyAqc3Rha2VyVjEpIHByb2Nlc3NVbkNsYWltYWJsZVJld2FyZChwb29sUGF0aCBzdHJpbmcsIGVuZFRpbWVzdGFtcCBpbnQ2NCkgaW50NjQgewoJcG9vbCwgb2sgOj0gcy5nZXRQb29scygpLkdldChwb29sUGF0aCkKCWlmICFvayB7CgkJcmV0dXJuIDAKCX0KCXBvb2xSZXNvbHZlciA6PSBOZXdQb29sUmVzb2x2ZXIocG9vbCkKCglyZXR1cm4gcG9vbFJlc29sdmVyLnByb2Nlc3NVbmNsYWltYWJsZVJld2FyZChlbmRUaW1lc3RhbXApCn0KCi8vIHVwZGF0ZSBkZXBvc2l0J3MgaW5jZW50aXZlIGxpc3Qgd2l0aCBuZXcgaW5jZW50aXZlcyBjcmVhdGVkIHNpbmNlIGxhc3QgdXBkYXRlCmZ1bmMgKHMgKnN0YWtlclYxKSBnZXRFeHRlcm5hbEluY2VudGl2ZUlkc0J5KHBvb2xQYXRoIHN0cmluZywgc3RhcnRUaW1lLCBlbmRUaW1lIGludDY0KSBbXXN0cmluZyB7CgljdXJyZW50SW5jZW50aXZlSWRzIDo9IG1ha2UoW11zdHJpbmcsIDApCgoJcG9vbCwgb2sgOj0gcy5nZXRQb29scygpLkdldChwb29sUGF0aCkKCWlmICFvayB7CgkJcmV0dXJuIGN1cnJlbnRJbmNlbnRpdmVJZHMKCX0KCXBvb2xSZXNvbHZlciA6PSBOZXdQb29sUmVzb2x2ZXIocG9vbCkKCgkvLyBMb29rIHVwIHRoZSBwb29sJ3Mgb3duIHN0YXJ0LXRpbWUgaW5kZXggaW5zdGVhZCBvZiBhIGdsb2JhbAoJLy8gY3JlYXRpb24tdGltZSBpbmRleC4gVGhlIGluZGV4IGlzIHNjb3BlZCB0byB0aGlzIHBvb2wncyBpbmNlbnRpdmVzLCBzbwoJLy8gZGlzY292ZXJ5IGNvc3QgaXMgYm91bmRlZCBieSB0aGUgbnVtYmVyIG9mIGluY2VudGl2ZXMgZm9yIHRoaXMgcG9vbAoJLy8gd2l0aGluIHRoZSBxdWVyaWVkIHJhbmdlLCBhbmQgbm8gbG9uZ2VyIGdyb3dzIHdpdGggdGhlIHRvdGFsIG51bWJlciBvZgoJLy8gaW5jZW50aXZlcyBzeXN0ZW0td2lkZS4KCXBvb2xSZXNvbHZlci5JbmNlbnRpdmVzUmVzb2x2ZXIoKS5JdGVyYXRlSW5jZW50aXZlSWRzQnlUaW1lKHN0YXJ0VGltZSwgZW5kVGltZSwgZnVuYyhpbmNlbnRpdmVJZCBzdHJpbmcpIGJvb2wgewoJCWN1cnJlbnRJbmNlbnRpdmVJZHMgPSBhcHBlbmQoY3VycmVudEluY2VudGl2ZUlkcywgaW5jZW50aXZlSWQpCgkJcmV0dXJuIGZhbHNlCgl9KQoKCXJldHVybiBjdXJyZW50SW5jZW50aXZlSWRzCn0KCi8vIGdldEluaXRpYWxDb2xsZWN0VGltZSBkZXRlcm1pbmVzIHRoZSBpbml0aWFsIGNvbGxlY3Rpb24gdGltZSBmb3IgYW4gaW5jZW50aXZlCi8vIGJ5IHRha2luZyB0aGUgbWF4aW11bSBvZiB0aGUgZGVwb3NpdCdzIHN0YWtlIHRpbWUgYW5kIHRoZSBpbmNlbnRpdmUncyBzdGFydCB0aW1lLgovLyBUaGlzIGVuc3VyZXMgcmV3YXJkcyBhcmUgb25seSBjYWxjdWxhdGVkIGZyb20gd2hlbiBib3RoIGNvbmRpdGlvbnMgYXJlIG1ldDoKLy8gLSBUaGUgcG9zaXRpb24gbXVzdCBiZSBzdGFrZWQgKGRlcG9zaXQuc3Rha2VUaW1lKQovLyAtIFRoZSBpbmNlbnRpdmUgbXVzdCBiZSBhY3RpdmUgKGluY2VudGl2ZS5zdGFydFRpbWVzdGFtcCkKLy8KLy8gVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGZvciBsYXp5IGluaXRpYWxpemF0aW9uIHdoZW4gYSBwb3NpdGlvbiBjb2xsZWN0cwovLyBmcm9tIGFuIGluY2VudGl2ZSBmb3IgdGhlIGZpcnN0IHRpbWUsIGF2b2lkaW5nIHRoZSBuZWVkIHRvIGl0ZXJhdGUgdGhyb3VnaAovLyBhbGwgZGVwb3NpdHMgd2hlbiBhIG5ldyBpbmNlbnRpdmUgaXMgY3JlYXRlZC4KZnVuYyBnZXRJbml0aWFsQ29sbGVjdFRpbWUoZGVwb3NpdCAqc3IuRGVwb3NpdCwgaW5jZW50aXZlICpzci5FeHRlcm5hbEluY2VudGl2ZSkgaW50NjQgewoJaWYgZGVwb3NpdC5TdGFrZVRpbWUoKSA+IGluY2VudGl2ZS5TdGFydFRpbWVzdGFtcCgpIHsKCQlyZXR1cm4gZGVwb3NpdC5TdGFrZVRpbWUoKQoJfQoJcmV0dXJuIGluY2VudGl2ZS5TdGFydFRpbWVzdGFtcCgpCn0KGp8BCgpjb25zdHMuZ25vEpABcGFja2FnZSBzdGFrZXIKCmNvbnN0ICgKCUdOU19UT0tFTl9LRVkgICAgc3RyaW5nID0gImduby5sYW5kL3IvZ25vc3dhcC9nbnMuR05TIgoJV1VHTk9UX1RPS0VOX0tFWSBzdHJpbmcgPSAiZ25vLmxhbmQvci9nbm9sYW5kL3d1Z25vdC53dWdub3QiCikKGuEDCgdkb2MuZ25vEtUDLy8gcGFja2FnZSBzdGFrZXIgbWFuYWdlcyBsaXF1aWRpdHkgbWluaW5nIHJld2FyZHMgZm9yIEdub1N3YXAgcG9zaXRpb25zLgovLwovLyBUaGUgc3Rha2VyIGRpc3RyaWJ1dGVzIEdOUyBlbWlzc2lvbnMgYW5kIGV4dGVybmFsIGluY2VudGl2ZXMgdG8gbGlxdWlkaXR5Ci8vIHByb3ZpZGVycyBiYXNlZCBvbiB0aGVpciBwb3NpdGlvbiBzaXplLCBwcmljZSByYW5nZSwgYW5kIHN0YWtpbmcgZHVyYXRpb24uCi8vIEl0IHN1cHBvcnRzIGJvdGggaW50ZXJuYWwgR05TIHJld2FyZHMgYW5kIGV4dGVybmFsIHRva2VuIGluY2VudGl2ZXMuCi8vCi8vIFJld2FyZCBjYWxjdWxhdGlvbnMgY29tYmluZSBlbGFwc2VkLXRpbWUgcmF0ZXMgd2l0aCB0aWNrL3JhbmdlIGFjY3VtdWxhdGlvbiwgYW5kCi8vIGNvbGxlY3Rpb24gZmxvd3MgYXJlIGludGVncmF0ZWQgaW50byB0aGUgc3Rha2luZyBsaWZlY3ljbGUuCnBhY2thZ2Ugc3Rha2VyChqsBwoJZW1pdHMuZ25vEp4HcGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkiY2hhaW4iCgkiY2hhaW4vcnVudGltZSIKCgkiZ25vLmxhbmQvcC9nbm9zd2FwL3V0aWxzL3YxIgopCgpmdW5jIGVtaXRTZXRQb29sVGllcigKCXByZXZBZGRyIHN0cmluZywKCXByZXZSZWFsbSBzdHJpbmcsCglwb29sUGF0aCBzdHJpbmcsCgl0aWVyIHVpbnQ2NCwKCXJld2FyZFBlclNlY29uZCBpbnQ2NCwKCXRpZXJSZXdhcmRzIG1hcFt1aW50NjRdaW50NjQsCgljb3VudHMgW0FsbFRpZXJDb3VudF11aW50NjQsCgljdXJyZW50VGltZSBpbnQ2NCwKKSB7CgljaGFpbi5FbWl0KAoJCSJTZXRQb29sVGllciIsCgkJInByZXZBZGRyIiwgcHJldkFkZHIsCgkJInByZXZSZWFsbSIsIHByZXZSZWFsbSwKCQkicG9vbFBhdGgiLCBwb29sUGF0aCwKCQkidGllciIsIHV0aWxzLkZvcm1hdFVpbnQodGllciksCgkJInJld2FyZFBlclNlY29uZCIsIHV0aWxzLkZvcm1hdEludChyZXdhcmRQZXJTZWNvbmQpLAoJCSJ0aWVyMVJld2FyZFBlclNlY29uZCIsIHV0aWxzLkZvcm1hdEludCh0aWVyUmV3YXJkc1tUaWVyMV0pLAoJCSJ0aWVyMlJld2FyZFBlclNlY29uZCIsIHV0aWxzLkZvcm1hdEludCh0aWVyUmV3YXJkc1tUaWVyMl0pLAoJCSJ0aWVyM1Jld2FyZFBlclNlY29uZCIsIHV0aWxzLkZvcm1hdEludCh0aWVyUmV3YXJkc1tUaWVyM10pLAoJCSJ0aWVyMUNvdW50IiwgdXRpbHMuRm9ybWF0VWludChjb3VudHNbVGllcjFdKSwKCQkidGllcjJDb3VudCIsIHV0aWxzLkZvcm1hdFVpbnQoY291bnRzW1RpZXIyXSksCgkJInRpZXIzQ291bnQiLCB1dGlscy5Gb3JtYXRVaW50KGNvdW50c1tUaWVyM10pLAoJCSJjdXJyZW50VGltZSIsIHV0aWxzLkZvcm1hdEludChjdXJyZW50VGltZSksCgkJImN1cnJlbnRIZWlnaHQiLCB1dGlscy5Gb3JtYXRJbnQocnVudGltZS5DaGFpbkhlaWdodCgpKSwKCSkKfQoasBMKCmVycm9ycy5nbm8SoRNwYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKKQoKY29uc3QgKAoJZXJyTm9QZXJtaXNzaW9uICAgICAgICAgICAgICAgICAgID0gIltHTk9TV0FQLVNUQUtFUi0wMDFdIGNhbGxlciBoYXMgbm8gcGVybWlzc2lvbiIKCWVyclBvb2xOb3RGb3VuZCAgICAgICAgICAgICAgICAgICA9ICJbR05PU1dBUC1TVEFLRVItMDAyXSBwb29sIG5vdCBmb3VuZCIKCWVyck5vdEF2YWlsYWJsZVVwZGF0ZUNvbGxlY3RUaW1lICA9ICJbR05PU1dBUC1TVEFLRVItMDAzXSBub3QgYXZhaWxhYmxlIHRvIHVwZGF0ZSBjb2xsZWN0IHRpbWUiCgllcnJJbnZhbGlkSW5wdXQgICAgICAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAwNF0gaW52YWxpZCBpbnB1dCBkYXRhIgoJZXJySW52YWxpZFVuc3Rha2luZ0ZlZSAgICAgICAgICAgID0gIltHTk9TV0FQLVNUQUtFUi0wMDVdIGludmFsaWQgdW5zdGFraW5nIGZlZSIKCWVyckFscmVhZHlTdGFrZWQgICAgICAgICAgICAgICAgICA9ICJbR05PU1dBUC1TVEFLRVItMDA2XSBhbHJlYWR5IHN0YWtlZCBwb3NpdGlvbiIKCWVyck5vbkluY2VudGl2aXplZFBvb2wgICAgICAgICAgICA9ICJbR05PU1dBUC1TVEFLRVItMDA3XSBwb29sIGlzIG5vdCBpbmNlbnRpdml6ZWQiCgllcnJDYW5ub3RFbmRJbmNlbnRpdmUgICAgICAgICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAwOF0gY2Fubm90IGVuZCBpbmNlbnRpdmUiCgllcnJJbnZhbGlkSW5jZW50aXZlU3RhcnRUaW1lICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAwOV0gaW52YWxpZCBpbmNlbnRpdmUgc3RhcnQgdGltZSIKCWVyckRlZmF1bHRFeHRlcm5hbFRva2VuICAgICAgICAgICA9ICJbR05PU1dBUC1TVEFLRVItMDEwXSBjYW5ub3QgZGVsZXRlIGRlZmF1bHQgZXh0ZXJuYWwgdG9rZW4iCgllcnJJbnZhbGlkUG9vbFBhdGggICAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAxMV0gaW52YWxpZCBwb29sIHBhdGgiCgllcnJJbnZhbGlkUG9vbFRpZXIgICAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAxMl0gaW52YWxpZCBwb29sIHRpZXIiCgllcnJEYXRhTm90Rm91bmQgICAgICAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAxM10gcmVxdWVzdGVkIGRhdGEgbm90IGZvdW5kIgoJZXJyQ2FsY3VsYXRpb25FcnJvciAgICAgICAgICAgICAgID0gIltHTk9TV0FQLVNUQUtFUi0wMTRdIHVuZXhwZWN0ZWQgY2FsY3VsYXRpb24gZXJyb3IiCgllcnJaZXJvTGlxdWlkaXR5ICAgICAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAxNV0gemVybyBsaXF1aWRpdHkiCgllcnJJbnZhbGlkSW5jZW50aXZlRHVyYXRpb24gICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAxNl0gaW52YWxpZCBpbmNlbnRpdmUgZHVyYXRpb24iCgllcnJOb3RBbGxvd2VkRm9yRXh0ZXJuYWxSZXdhcmQgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAxN10gbm90IGFsbG93ZWQgZm9yIGV4dGVybmFsIHJld2FyZCIKCWVyckluY2VudGl2ZUFscmVhZHlFeGlzdHMgICAgICAgICA9ICJbR05PU1dBUC1TVEFLRVItMDE4XSBpbmNlbnRpdmUgYWxyZWFkeSBleGlzdHMiCgllcnJPdmVyZmxvdyAgICAgICAgICAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAxOV0gb3ZlcmZsb3ciCgllcnJBZGRFeGlzdGluZ1Rva2VuICAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAyMF0gY2Fubm90IGFkZCBleGlzdGluZyB0b2tlbiIKCWVyckludmFsaWRBZGRyZXNzICAgICAgICAgICAgICAgICA9ICJbR05PU1dBUC1TVEFLRVItMDIxXSBpbnZhbGlkIGFkZHJlc3MiCgllcnJJc05vdEVuZGVkSW5jZW50aXZlICAgICAgICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAyMl0gaW5jZW50aXZlIGlzIG5vdCBlbmRlZCB5ZXQiCgllcnJDYW5ub3RDYW5jZWxJbmNlbnRpdmUgICAgICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAyM10gY2Fubm90IGNhbmNlbCBpbmNlbnRpdmUiCgllcnJVbmNvbGxlY3RlZFBvc2l0aW9uICAgICAgICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAyNF0gcG9zaXRpb24gaGFzIHVuY29sbGVjdGVkIHJld2FyZHMiCgllcnJEZW5pZWRSZXdhcmRUb2tlbiAgICAgICAgICAgICAgPSAiW0dOT1NXQVAtU1RBS0VSLTAyNV0gZGVuaWVkIHJld2FyZCB0b2tlbiIKCWVyckNhbm5vdERlbnlEZWZhdWx0VG9rZW4gICAgICAgICA9ICJbR05PU1dBUC1TVEFLRVItMDI2XSBjYW5ub3QgZGVueSBkZWZhdWx0IHRva2VuIgoJZXJySW5zdWZmaWNpZW50UmV3YXJkVG9rZW5CYWxhbmNlID0gIltHTk9TV0FQLVNUQUtFUi0wMjddIGluc3VmZmljaWVudCByZXdhcmQgdG9rZW4gYmFsYW5jZSIKKQoKZnVuYyBtYWtlRXJyb3JXaXRoRGV0YWlscyhtZXNzYWdlIHN0cmluZywgZGV0YWlscyBzdHJpbmcpIGVycm9yIHsKCXJldHVybiB1Zm10LkVycm9yZigiJXMgfHwgJXMiLCBtZXNzYWdlLCBkZXRhaWxzKQp9ChreDQoOZXZlbnRfaW5mby5nbm8Syw1wYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCWkyNTYgImduby5sYW5kL3AvZ25vc3dhcC9pbnQyNTYvdjEiCgl1MjU2ICJnbm8ubGFuZC9wL2dub3N3YXAvdWludDI1Ni92MSIKCSJnbm8ubGFuZC9wL2dub3N3YXAvdXRpbHMvdjEiCikKCnR5cGUgdGlja0Nyb3NzRXZlbnRJbmZvIHN0cnVjdCB7Cgl0aWNrSUQgICAgICAgICAgICAgICBpbnQzMgoJc3Rha2VkTGlxdWlkaXR5R3Jvc3MgKnUyNTYuVWludAoJc3Rha2VkTGlxdWlkaXR5RGVsdGEgKmkyNTYuSW50CglvdXRzaWRlQWNjdW11bGF0aW9uICAqdTI1Ni5VaW50Cn0KCi8vIFRvU3RyaW5nIHNlcmlhbGl6ZXMgdGljay1jcm9zcyBpbmZvcm1hdGlvbiBhcyBhIGNvbXBhY3QgSlNPTiBvYmplY3QgZm9yIGV2ZW50IGVtaXNzaW9uLgovLyAtIHQ6IFRpY2sgSUQKLy8gLSBzbGc6IFN0YWtlZCBMaXF1aWRpdHkgR3Jvc3MKLy8gLSBzbGQ6IFN0YWtlZCBMaXF1aWRpdHkgRGVsdGEKLy8gLSBvYTogT3V0c2lkZSBBY2N1bXVsYXRpb24KLy8KLy8gUmV0dXJuczoKLy8gICAtIGpzb246IEpTT04gb2JqZWN0IHN0cmluZyBjb250YWluaW5nIHRoZSB0aWNrIElEIGFuZCB0aGUgdGhyZWUgZW5jb2RlZCBsaXF1aWRpdHkvYWNjdW11bGF0aW9uIHZhbHVlcy4KZnVuYyAodCAqdGlja0Nyb3NzRXZlbnRJbmZvKSBUb1N0cmluZygpIHN0cmluZyB7CglyZXR1cm4gIntcInRcIjoiICsgdXRpbHMuRm9ybWF0SW50KHQudGlja0lEKSArCgkJIixcInNsZ1wiOlwiIiArIHQuc3Rha2VkTGlxdWlkaXR5R3Jvc3MuVG9TdHJpbmcoKSArICJcIiIgKwoJCSIsXCJzbGRcIjpcIiIgKyB0LnN0YWtlZExpcXVpZGl0eURlbHRhLlRvU3RyaW5nKCkgKyAiXCIiICsKCQkiLFwib2FcIjpcIiIgKyB0Lm91dHNpZGVBY2N1bXVsYXRpb24uVG9TdHJpbmcoKSArICJcIn0iCn0KCi8vIE5ld1RpY2tDcm9zc0V2ZW50SW5mbyBjYXB0dXJlcyB0aGUgdmFsdWVzIGVtaXR0ZWQgd2hlbiBhIHN3YXAgY3Jvc3NlcyBhIHRpY2suCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB0aWNrSUQ6IFRpY2sgaW5kZXggY3Jvc3NlZCBkdXJpbmcgdGhlIHN3YXAuCi8vICAgLSBzdGFrZWRMaXF1aWRpdHlHcm9zczogVG90YWwgc3Rha2VkIGxpcXVpZGl0eSBhdCB0aGUgY3Jvc3NlZCB0aWNrLgovLyAgIC0gc3Rha2VkTGlxdWlkaXR5RGVsdGE6IE5ldCBzdGFrZWQgbGlxdWlkaXR5IGNoYW5nZSBhcHBsaWVkIGF0IHRoZSBjcm9zc2VkIHRpY2suCi8vICAgLSBvdXRzaWRlQWNjdW11bGF0aW9uOiBSZXdhcmQtcmF0aW8gYWNjdW11bGF0aW9uIG91dHNpZGUgdGhlIGNyb3NzZWQgdGljay4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGluZm86IEV2ZW50IHBheWxvYWQgY29udGFpbmluZyB0aGUgc3VwcGxpZWQgdGljay1jcm9zcyB2YWx1ZXMuCmZ1bmMgTmV3VGlja0Nyb3NzRXZlbnRJbmZvKHRpY2tJRCBpbnQzMiwgc3Rha2VkTGlxdWlkaXR5R3Jvc3MgKnUyNTYuVWludCwgc3Rha2VkTGlxdWlkaXR5RGVsdGEgKmkyNTYuSW50LCBvdXRzaWRlQWNjdW11bGF0aW9uICp1MjU2LlVpbnQpICp0aWNrQ3Jvc3NFdmVudEluZm8gewoJcmV0dXJuICZ0aWNrQ3Jvc3NFdmVudEluZm97CgkJdGlja0lEOiAgICAgICAgICAgICAgIHRpY2tJRCwKCQlzdGFrZWRMaXF1aWRpdHlHcm9zczogc3Rha2VkTGlxdWlkaXR5R3Jvc3MsCgkJc3Rha2VkTGlxdWlkaXR5RGVsdGE6IHN0YWtlZExpcXVpZGl0eURlbHRhLAoJCW91dHNpZGVBY2N1bXVsYXRpb246ICBvdXRzaWRlQWNjdW11bGF0aW9uLAoJfQp9ChqpMgoYZXh0ZXJuYWxfZGVwb3NpdF9mZWUuZ25vEowycGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkiY2hhaW4iCgkic3RyY29udiIKCSJzdHJpbmdzIgoKCSJnbm8ubGFuZC9wL2dub3N3YXAvdXRpbHMvdjEiCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgoJImduby5sYW5kL3IvZ25vc3dhcC9hY2Nlc3MvdjEiCgkiZ25vLmxhbmQvci9nbm9zd2FwL2hhbHQvdjEiCikKCi8vIEdldERlcG9zaXRHbnNBbW91bnQgcmV0dXJucyB0aGUgY3VycmVudCBHTlMgZGVwb3NpdCBhbW91bnQgcmVxdWlyZWQgZm9yIGVhY2ggZXh0ZXJuYWwgaW5jZW50aXZlLgovLwovLyBSZXR1cm5zOgovLyAgIC0gYW1vdW50OiBHTlMgZGVwb3NpdCBhbW91bnQgcmVxdWlyZWQgcGVyIGV4dGVybmFsIGluY2VudGl2ZSwgaW4gdG9rZW4gc21hbGxlc3QgdW5pdHMuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXREZXBvc2l0R25zQW1vdW50KCkgaW50NjQgewoJcmV0dXJuIHMuc3RvcmUuR2V0RGVwb3NpdEduc0Ftb3VudCgpCn0KCi8vIEdldE1pbmltdW1SZXdhcmRBbW91bnQgcmV0dXJucyB0aGUgZGVmYXVsdCBtaW5pbXVtIHJld2FyZCBhbW91bnQgcmVxdWlyZWQgZm9yIGV4dGVybmFsIGluY2VudGl2ZXMuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBhbW91bnQ6IERlZmF1bHQgbWluaW11bSBleHRlcm5hbC1pbmNlbnRpdmUgcmV3YXJkIGFtb3VudCBpbiB0b2tlbiBzbWFsbGVzdCB1bml0cy4KZnVuYyAocyAqc3Rha2VyVjEpIEdldE1pbmltdW1SZXdhcmRBbW91bnQoKSBpbnQ2NCB7CglyZXR1cm4gcy5zdG9yZS5HZXRNaW5pbXVtUmV3YXJkQW1vdW50KCkKfQoKLy8gR2V0TWluaW11bVJld2FyZEFtb3VudEZvclRva2VuIHJldHVybnMgdGhlIG1pbmltdW0gcmV3YXJkIGFtb3VudCBmb3IgYSBzcGVjaWZpYyB0b2tlbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHRva2VuUGF0aDogVG9rZW4gcGF0aCB3aG9zZSBjb25maWd1cmVkIG1pbmltdW0gcmV3YXJkIGFtb3VudCBzaG91bGQgYmUgcmVhZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGFtb3VudDogVG9rZW4tc3BlY2lmaWMgbWluaW11bSByZXdhcmQgYW1vdW50IHdoZW4gY29uZmlndXJlZCwgb3RoZXJ3aXNlIHRoZSBkZWZhdWx0IG1pbmltdW0gYW1vdW50LgpmdW5jIChzICpzdGFrZXJWMSkgR2V0TWluaW11bVJld2FyZEFtb3VudEZvclRva2VuKHRva2VuUGF0aCBzdHJpbmcpIGludDY0IHsKCWFtb3VudCwgZm91bmQgOj0gcy5zdG9yZS5HZXRUb2tlblNwZWNpZmljTWluaW11bVJld2FyZHMoKVt0b2tlblBhdGhdCglpZiBmb3VuZCB7CgkJcmV0dXJuIGFtb3VudAoJfQoJLy8gRmFsbGJhY2sgdG8gZGVmYXVsdCBpZiBub3QgZm91bmQKCXJldHVybiBzLkdldE1pbmltdW1SZXdhcmRBbW91bnQoKQp9CgovLyBHZXRTcGVjaWZpY1Rva2VuTWluaW11bVJld2FyZEFtb3VudCByZXR1cm5zIHRoZSBleHBsaWNpdGx5IHNldCBtaW5pbXVtIHJld2FyZCBhbW91bnQgZm9yIGEgdG9rZW4uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB0b2tlblBhdGg6IFRva2VuIHBhdGggd2hvc2UgZXhwbGljaXQgbWluaW11bSByZXdhcmQgb3ZlcnJpZGUgc2hvdWxkIGJlIHJlYWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBhbW91bnQ6IEV4cGxpY2l0IG1pbmltdW0gcmV3YXJkIGFtb3VudCBpbiB0b2tlbiBzbWFsbGVzdCB1bml0cywgb3IgMCB3aGVuIG5vIG92ZXJyaWRlIGlzIGNvbmZpZ3VyZWQuCi8vICAgLSBmb3VuZDogVHJ1ZSB3aGVuIHRva2VuUGF0aCBoYXMgYW4gZXhwbGljaXQgb3ZlcnJpZGU7IGZhbHNlIHdoZW4gdGhlIGRlZmF1bHQgd291bGQgYmUgdXNlZC4KZnVuYyAocyAqc3Rha2VyVjEpIEdldFNwZWNpZmljVG9rZW5NaW5pbXVtUmV3YXJkQW1vdW50KHRva2VuUGF0aCBzdHJpbmcpIChpbnQ2NCwgYm9vbCkgewoJYW1vdW50LCBmb3VuZCA6PSBzLnN0b3JlLkdldFRva2VuU3BlY2lmaWNNaW5pbXVtUmV3YXJkcygpW3Rva2VuUGF0aF0KCWlmICFmb3VuZCB7CgkJcmV0dXJuIDAsIGZhbHNlCgl9CglyZXR1cm4gYW1vdW50LCB0cnVlCn0KCi8vIFNldERlcG9zaXRHbnNBbW91bnQgc2V0cyB0aGUgR05TIGRlcG9zaXQgYW1vdW50IHJlcXVpcmVkIGZvciBjcmVhdGluZyBleHRlcm5hbCBpbmNlbnRpdmVzLgovLyBPbmx5IGFkbWluIG9yIGdvdmVybmFuY2UgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIHVuY2hhbmdlZCBieSB0aGUgc3Rha2VyIHByb3h5LgovLyAgIC0gYW1vdW50OiBOb24tbmVnYXRpdmUgR05TIGRlcG9zaXQgYW1vdW50IGluIHRva2VuIHNtYWxsZXN0IHVuaXRzIHRvIHJlcXVpcmUgcGVyIGV4dGVybmFsIGluY2VudGl2ZS4KZnVuYyAocyAqc3Rha2VyVjEpIFNldERlcG9zaXRHbnNBbW91bnQoXyBpbnQsIHJsbSByZWFsbSwgYW1vdW50IGludDY0KSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCgloYWx0LkFzc2VydElzTm90SGFsdGVkU3Rha2VyKCkKCglwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXIgOj0gcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkKCWFjY2Vzcy5Bc3NlcnRJc0FkbWluT3JHb3Zlcm5hbmNlKGNhbGxlcikKCglhc3NlcnRJc1ZhbGlkQW1vdW50KGFtb3VudCkKCglwcmV2RGVwb3NpdEduc0Ftb3VudCA6PSBzLnN0b3JlLkdldERlcG9zaXRHbnNBbW91bnQoKQoJcy5zZXREZXBvc2l0R25zQW1vdW50KDAsIHJsbSwgYW1vdW50KQoKCWNoYWluLkVtaXQoCgkJIlNldERlcG9zaXRHbnNBbW91bnQiLAoJCSJwcmV2QWRkciIsIGNhbGxlci5TdHJpbmcoKSwKCQkicHJldlJlYWxtIiwgcHJldmlvdXNSZWFsbS5Qa2dQYXRoKCksCgkJInByZXZBbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQocHJldkRlcG9zaXRHbnNBbW91bnQpLAoJCSJuZXdBbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQoYW1vdW50KSwKCSkKfQoKLy8gU2V0TWluaW11bVJld2FyZEFtb3VudCBzZXRzIHRoZSBkZWZhdWx0IG1pbmltdW0gcmV3YXJkIGFtb3VudCBmb3IgZXh0ZXJuYWwgaW5jZW50aXZlcy4KLy8gT25seSBhZG1pbiBvciBnb3Zlcm5hbmNlIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBOb25jcm9zc2luZyBpbXBsZW1lbnRhdGlvbi1jYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8gICAtIHJsbTogQ3VycmVudCByZWFsbSBjb250ZXh0IGZvcndhcmRlZCB1bmNoYW5nZWQgYnkgdGhlIHN0YWtlciBwcm94eS4KLy8gICAtIGFtb3VudDogTm9uLW5lZ2F0aXZlIGRlZmF1bHQgbWluaW11bSByZXdhcmQgYW1vdW50IGluIHRva2VuIHNtYWxsZXN0IHVuaXRzIGZvciBleHRlcm5hbCBpbmNlbnRpdmVzLgpmdW5jIChzICpzdGFrZXJWMSkgU2V0TWluaW11bVJld2FyZEFtb3VudChfIGludCwgcmxtIHJlYWxtLCBhbW91bnQgaW50NjQpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRTdGFrZXIoKQoKCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzQWRtaW5PckdvdmVybmFuY2UoY2FsbGVyKQoKCWFzc2VydElzVmFsaWRBbW91bnQoYW1vdW50KQoKCXByZXZNaW5pbXVtUmV3YXJkQW1vdW50IDo9IHMuZ2V0TWluaW11bVJld2FyZEFtb3VudCgpCglzLnNldE1pbmltdW1SZXdhcmRBbW91bnQoMCwgcmxtLCBhbW91bnQpCgoJY2hhaW4uRW1pdCgKCQkiU2V0TWluaW11bVJld2FyZEFtb3VudCIsCgkJInByZXZBZGRyIiwgY2FsbGVyLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2aW91c1JlYWxtLlBrZ1BhdGgoKSwKCQkicHJldkFtb3VudCIsIHV0aWxzLkZvcm1hdEludChwcmV2TWluaW11bVJld2FyZEFtb3VudCksCgkJIm5ld0Ftb3VudCIsIHV0aWxzLkZvcm1hdEludChhbW91bnQpLAoJKQp9CgovLyBTZXRUb2tlbk1pbmltdW1SZXdhcmRBbW91bnQgc2V0cyB0aGUgbWluaW11bSByZXdhcmQgYW1vdW50IGZvciBhIHNwZWNpZmljIHRva2VuLgovLyBPbmx5IGFkbWluIG9yIGdvdmVybmFuY2UgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIHVuY2hhbmdlZCBieSB0aGUgc3Rha2VyIHByb3h5LgovLyAgIC0gcGFyYW1zU3RyOiBSZXdhcmQgb3ZlcnJpZGUgc3BlY2lmaWNhdGlvbiBpbiB0aGUgZm9ybSAidG9rZW5QYXRoOmFtb3VudCI7IGFtb3VudCAwIHJlbW92ZXMgYW4gZXhpc3RpbmcgdG9rZW4tc3BlY2lmaWMgb3ZlcnJpZGUsIHdoaWxlIGEgbm9uemVybyBhbW91bnQgc3RvcmVzIGl0LgpmdW5jIChzICpzdGFrZXJWMSkgU2V0VG9rZW5NaW5pbXVtUmV3YXJkQW1vdW50KF8gaW50LCBybG0gcmVhbG0sIHBhcmFtc1N0ciBzdHJpbmcpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRTdGFrZXIoKQoKCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzQWRtaW5PckdvdmVybmFuY2UoY2FsbGVyKQoKCWFzc2VydElzVmFsaWRSZXdhcmRBbW91bnRGb3JtYXQocGFyYW1zU3RyKQoKCS8vIFBhcnNlIHRoZSBwYXJhbXNTdHIKCXBhcnRzIDo9IHN0cmluZ3MuU3BsaXROKHBhcmFtc1N0ciwgIjoiLCAyKQoJdG9rZW5QYXRoIDo9IHBhcnRzWzBdCglhbW91bnRTdHIgOj0gcGFydHNbMV0KCWFtb3VudDY0LCBlcnIgOj0gc3RyY29udi5QYXJzZUludChhbW91bnRTdHIsIDEwLCA2NCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbnZhbGlkSW5wdXQsCgkJCXVmbXQuU3ByaW50ZigiaW52YWxpZCBhbW91bnQgZm9ybWF0IGluIHBhcmFtcyAnJXMnOiAldiIsIHBhcmFtc1N0ciwgZXJyKSwKCQkpKQoJfQoKCXByZXZBbW91bnQsIGZvdW5kIDo9IHMuc3RvcmUuR2V0VG9rZW5TcGVjaWZpY01pbmltdW1SZXdhcmRzKClbdG9rZW5QYXRoXQoKCS8vIElmIGFtb3VudCBpcyAwLCByZW1vdmUgdGhlIGVudHJ5OyBvdGhlcndpc2UsIHNldCBpdC4KCWlmIGFtb3VudDY0ID09IDAgewoJCS8vIE9ubHkgYXR0ZW1wdCByZW1vdmFsIGlmIGFuIGVudHJ5IGFjdHVhbGx5IGV4aXN0ZWQKCQlpZiBmb3VuZCB7CgkJCWlmIGVyciA6PSBzLnN0b3JlLlJlbW92ZVRva2VuU3BlY2lmaWNNaW5pbXVtUmV3YXJkSXRlbSgwLCBybG0sIHRva2VuUGF0aCk7IGVyciAhPSBuaWwgewoJCQkJcGFuaWMoZXJyKQoJCQl9CgkJfQoJfSBlbHNlIHsKCQlpZiBlcnIgOj0gcy5zdG9yZS5TZXRUb2tlblNwZWNpZmljTWluaW11bVJld2FyZEl0ZW0oMCwgcmxtLCB0b2tlblBhdGgsIGFtb3VudDY0KTsgZXJyICE9IG5pbCB7CgkJCXBhbmljKGVycikKCQl9Cgl9CgoJY2hhaW4uRW1pdCgKCQkiU2V0VG9rZW5NaW5pbXVtUmV3YXJkQW1vdW50IiwKCQkicHJldkFkZHIiLCBjYWxsZXIuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCSJ0b2tlblBhdGgiLCB0b2tlblBhdGgsCgkJInByZXZBbW91bnRGb3VuZCIsIHV0aWxzLkZvcm1hdEJvb2woZm91bmQpLAoJCSJwcmV2QW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KHByZXZBbW91bnQpLCAvLyBXaWxsIGJlIDAgaWYgIWZvdW5kCgkJIm5ld0Ftb3VudCIsIHV0aWxzLkZvcm1hdEludChhbW91bnQ2NCksCgkpCn0KCi8vIHNldERlcG9zaXRHbnNBbW91bnQgaW50ZXJuYWxseSB1cGRhdGVzIHRoZSBkZXBvc2l0IEdOUyBhbW91bnQuCmZ1bmMgKHMgKnN0YWtlclYxKSBzZXREZXBvc2l0R25zQW1vdW50KF8gaW50LCBybG0gcmVhbG0sIGFtb3VudCBpbnQ2NCkgewoJcy5zdG9yZS5TZXREZXBvc2l0R25zQW1vdW50KDAsIHJsbSwgYW1vdW50KQp9CgovLyBzZXRNaW5pbXVtUmV3YXJkQW1vdW50IGludGVybmFsbHkgdXBkYXRlcyB0aGUgbWluaW11bSByZXdhcmQgYW1vdW50LgpmdW5jIChzICpzdGFrZXJWMSkgc2V0TWluaW11bVJld2FyZEFtb3VudChfIGludCwgcmxtIHJlYWxtLCBhbW91bnQgaW50NjQpIHsKCXMuc3RvcmUuU2V0TWluaW11bVJld2FyZEFtb3VudCgwLCBybG0sIGFtb3VudCkKfQoKLy8gZ2V0TWluaW11bVJld2FyZEFtb3VudCBpbnRlcm5hbGx5IHJldHJpZXZlcyB0aGUgbWluaW11bSByZXdhcmQgYW1vdW50LgpmdW5jIChzICpzdGFrZXJWMSkgZ2V0TWluaW11bVJld2FyZEFtb3VudCgpIGludDY0IHsKCXJldHVybiBzLnN0b3JlLkdldE1pbmltdW1SZXdhcmRBbW91bnQoKQp9ChqBlgEKFmV4dGVybmFsX2luY2VudGl2ZS5nbm8S5ZUBcGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkiY2hhaW4iCgkiY2hhaW4vcnVudGltZSIKCSJ0aW1lIgoKCSJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCXByYmFjICJnbm8ubGFuZC9wL2dub3N3YXAvcmJhYy92MSIKCXUyNTYgImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgoJImduby5sYW5kL3AvZ25vc3dhcC91dGlscy92MSIKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2FjY2Vzcy92MSIKCSJnbm8ubGFuZC9yL2dub3N3YXAvY29tbW9uIgoJZW4gImduby5sYW5kL3IvZ25vc3dhcC9lbWlzc2lvbiIKCSJnbm8ubGFuZC9yL2dub3N3YXAvaGFsdC92MSIKCXNyICJnbm8ubGFuZC9yL2dub3N3YXAvc3Rha2VyIgopCgovLyBDcmVhdGVFeHRlcm5hbEluY2VudGl2ZSBjcmVhdGVzIGFuIGV4dGVybmFsIGluY2VudGl2ZSBwcm9ncmFtIGZvciBhIHBvb2wuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBOb25jcm9zc2luZyBpbXBsZW1lbnRhdGlvbi1jYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8gICAtIHJsbTogQ3VycmVudCByZWFsbSBjb250ZXh0IGZvcndhcmRlZCB1bmNoYW5nZWQgYnkgdGhlIHN0YWtlciBwcm94eS4KLy8gICAtIHRhcmdldFBvb2xQYXRoOiBQb29sIHBhdGggdG8gaW5jZW50aXZpemUuCi8vICAgLSByZXdhcmRUb2tlbjogUmVnaXN0ZXJlZCByZXdhcmQtdG9rZW4gcGF0aC4KLy8gICAtIHJld2FyZEFtb3VudDogVG90YWwgcmV3YXJkIGFtb3VudCBkZXBvc2l0ZWQsIGluIHJld2FyZC10b2tlbiB1bml0cy4KLy8gICAtIHN0YXJ0VGltZXN0YW1wOiBJbmNlbnRpdmUgc3RhcnQgdGltZSBhcyBVbml4IHNlY29uZHMuCi8vICAgLSBlbmRUaW1lc3RhbXA6IEluY2VudGl2ZSBlbmQgdGltZSBhcyBVbml4IHNlY29uZHM7IGl0IG11c3QgZm9sbG93IHN0YXJ0VGltZXN0YW1wIGJ5IGEgdmFsaWQgZHVyYXRpb24uCi8vCi8vIEFueSBjYWxsZXIgbWF5IGNyZWF0ZSBhbiBpbmNlbnRpdmUgYWZ0ZXIgc2F0aXNmeWluZyB0b2tlbiwgZHVyYXRpb24sIHN0YXJ0LXRpbWUsIHJld2FyZC1taW5pbXVtLAovLyBhbmQgR05TLWRlcG9zaXQgY2hlY2tzLgpmdW5jIChzICpzdGFrZXJWMSkgQ3JlYXRlRXh0ZXJuYWxJbmNlbnRpdmUoCglfIGludCwKCXJsbSByZWFsbSwKCXRhcmdldFBvb2xQYXRoIHN0cmluZywKCXJld2FyZFRva2VuIHN0cmluZywgLy8gdG9rZW4gcGF0aCBzaG91bGQgYmUgcmVnaXN0ZXJlZAoJcmV3YXJkQW1vdW50IGludDY0LAoJc3RhcnRUaW1lc3RhbXAgaW50NjQsCgllbmRUaW1lc3RhbXAgaW50NjQsCikgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFN0YWtlcigpCgoJcHJldlJlYWxtIDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXIgOj0gcHJldlJlYWxtLkFkZHJlc3MoKQoJY3VycmVudFRpbWUgOj0gdGltZS5Ob3coKS5Vbml4KCkKCglhc3NlcnRJc1Bvb2xFeGlzdHMocywgdGFyZ2V0UG9vbFBhdGgpCgoJYXNzZXJ0SXNHcmVhdGVyVGhhbk1pbmltdW1SZXdhcmRBbW91bnQocywgcmV3YXJkVG9rZW4sIHJld2FyZEFtb3VudCkKCWFzc2VydElzQWxsb3dlZEZvckV4dGVybmFsUmV3YXJkKHMsIHRhcmdldFBvb2xQYXRoLCByZXdhcmRUb2tlbikKCWFzc2VydElzRXh0ZXJuYWxSZXdhcmRUb2tlbkF2YWlsYWJsZShzLCB0YXJnZXRQb29sUGF0aCwgcmV3YXJkVG9rZW4sIGN1cnJlbnRUaW1lKQoJYXNzZXJ0SXNWYWxpZEluY2VudGl2ZVN0YXJ0VGltZShzdGFydFRpbWVzdGFtcCkKCWFzc2VydElzVmFsaWRJbmNlbnRpdmVFbmRUaW1lKGVuZFRpbWVzdGFtcCkKCWFzc2VydElzVmFsaWRJbmNlbnRpdmVEdXJhdGlvbihnbnNtYXRoLlNhZmVTdWJJbnQ2NChlbmRUaW1lc3RhbXAsIHN0YXJ0VGltZXN0YW1wKSkKCS8vIGFzc2VydCB0aGF0IHRoZSB1c2VyIGhhcyBzZW50IHRoZSBjb3JyZWN0IGFtb3VudCBvZiBuYXRpdmUgY29pbgoJY29tbW9uLkFzc2VydElzTm90SGFuZGxlTmF0aXZlQ29pbigpCgoJZW4uTWludEFuZERpc3RyaWJ1dGVHbnMoY3Jvc3MocmxtKSkKCglzdGFrZXJBZGRyIDo9IGFjY2Vzcy5NdXN0R2V0QWRkcmVzcyhwcmJhYy5ST0xFX1NUQUtFUi5TdHJpbmcoKSkKCgkvLyB0cmFuc2ZlciByZXdhcmQgdG9rZW4gZnJvbSB1c2VyIHRvIHN0YWtlcgoJY29tbW9uLlNhZmVHUkMyMFRyYW5zZmVyRnJvbSgwLCBybG0sIHJld2FyZFRva2VuLCBjYWxsZXIsIHN0YWtlckFkZHIsIHJld2FyZEFtb3VudCkKCglkZXBvc2l0R25zQW1vdW50IDo9IHMuc3RvcmUuR2V0RGVwb3NpdEduc0Ftb3VudCgpCgoJLy8gZGVwb3NpdCBnbnMgYW1vdW50Cgljb21tb24uU2FmZUdSQzIwVHJhbnNmZXJGcm9tKDAsIHJsbSwgR05TX1RPS0VOX0tFWSwgY2FsbGVyLCBzdGFrZXJBZGRyLCBkZXBvc2l0R25zQW1vdW50KQoKCWN1cnJlbnRIZWlnaHQgOj0gcnVudGltZS5DaGFpbkhlaWdodCgpCglpbmNlbnRpdmVJZCA6PSBzLnN0b3JlLk5leHRJbmNlbnRpdmVJRChjYWxsZXIsIGN1cnJlbnRUaW1lKQoJcG9vbCA6PSBzLmdldFBvb2xzKCkuR2V0UG9vbE9yTmlsKHRhcmdldFBvb2xQYXRoKQoJaWYgcG9vbCA9PSBuaWwgewoJCXBvb2wgPSBzci5OZXdQb29sKHRhcmdldFBvb2xQYXRoLCBjdXJyZW50VGltZSkKCQlzLmdldFBvb2xzKCkuc2V0KHRhcmdldFBvb2xQYXRoLCBwb29sKQoJfQoKCWluY2VudGl2ZSA6PSBzci5OZXdFeHRlcm5hbEluY2VudGl2ZSgKCQlpbmNlbnRpdmVJZCwKCQl0YXJnZXRQb29sUGF0aCwKCQlyZXdhcmRUb2tlbiwKCQlyZXdhcmRBbW91bnQsCgkJc3RhcnRUaW1lc3RhbXAsCgkJZW5kVGltZXN0YW1wLAoJCWNhbGxlciwKCQlkZXBvc2l0R25zQW1vdW50LAoJCWN1cnJlbnRIZWlnaHQsCgkJY3VycmVudFRpbWUsCgkpCgoJZXh0ZXJuYWxJbmNlbnRpdmVzIDo9IHMuc3RvcmUuR2V0RXh0ZXJuYWxJbmNlbnRpdmVzKCkKCWlmIGV4dGVybmFsSW5jZW50aXZlcy5IYXMoaW5jZW50aXZlSWQpIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySW5jZW50aXZlQWxyZWFkeUV4aXN0cywKCQkJdWZtdC5TcHJpbnRmKCJpbmNlbnRpdmVJZCglcykiLCBpbmNlbnRpdmVJZCksCgkJKSkKCX0KCS8vIHN0b3JlIGV4dGVybmFsIGluY2VudGl2ZSBpbmZvcm1hdGlvbiBmb3IgZWFjaCBpbmNlbnRpdmVJZAoJZXh0ZXJuYWxJbmNlbnRpdmVzLlNldChpbmNlbnRpdmVJZCwgaW5jZW50aXZlKQoKCXBvb2xSZXNvbHZlciA6PSBOZXdQb29sUmVzb2x2ZXIocG9vbCkKCXBvb2xSZXNvbHZlci5JbmNlbnRpdmVzUmVzb2x2ZXIoKS5jcmVhdGUoaW5jZW50aXZlKQoKCWNoYWluLkVtaXQoCgkJIkNyZWF0ZUV4dGVybmFsSW5jZW50aXZlIiwKCQkicHJldkFkZHIiLCBjYWxsZXIuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZSZWFsbS5Qa2dQYXRoKCksCgkJImluY2VudGl2ZUlkIiwgaW5jZW50aXZlSWQsCgkJInRhcmdldFBvb2xQYXRoIiwgdGFyZ2V0UG9vbFBhdGgsCgkJInJld2FyZFRva2VuIiwgcmV3YXJkVG9rZW4sCgkJInJld2FyZEFtb3VudCIsIHV0aWxzLkZvcm1hdEludChyZXdhcmRBbW91bnQpLAoJCSJzdGFydFRpbWVzdGFtcCIsIHV0aWxzLkZvcm1hdEludChzdGFydFRpbWVzdGFtcCksCgkJImVuZFRpbWVzdGFtcCIsIHV0aWxzLkZvcm1hdEludChlbmRUaW1lc3RhbXApLAoJCSJkZXBvc2l0R25zQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KGRlcG9zaXRHbnNBbW91bnQpLAoJCSJjdXJyZW50SGVpZ2h0IiwgdXRpbHMuRm9ybWF0SW50KGN1cnJlbnRIZWlnaHQpLAoJCSJjdXJyZW50VGltZSIsIHV0aWxzLkZvcm1hdEludChjdXJyZW50VGltZSksCgkpCn0KCi8vIEVuZEV4dGVybmFsSW5jZW50aXZlIGVuZHMgYW4gZXh0ZXJuYWwgaW5jZW50aXZlIGFmdGVyIGl0cyBlbmQgdGltZXN0YW1wIGFuZCBmaW5hbGl6ZXMgdGhlCi8vIHJlZnVuZGFibGUgdW5jbGFpbWFibGUvcmVtYWluZGVyIGFtb3VudC4KLy8KLy8gVGhlIHJld2FyZC10b2tlbiByZWZ1bmQgYW5kIEdOUyBkZXBvc2l0IGFyZSBzZW50IHRvIHRoZSBjYWxsZXItc3VwcGxpZWQgcmVmdW5kQWRkcmVzcy4gUmV3YXJkcwovLyBzdGlsbCBvd2VkIGJ5IGxpdmUgcG9zaXRpb25zIHJlbWFpbiBjbGFpbWFibGUsIGFuZCB0aGUgaW5jZW50aXZlIHJlY29yZCBpcyByZXRhaW5lZCBmb3IgdGhhdAovLyBhY2NvdW50aW5nLiBBY2N1bXVsYXRlZCB3YXJtdXAgcGVuYWx0aWVzIGFyZSBjb2xsZWN0ZWQgc2VwYXJhdGVseSB3aXRoCi8vIENvbGxlY3RFeHRlcm5hbEluY2VudGl2ZVBlbmFsdHkgYWZ0ZXIgdGhpcyBmdW5jdGlvbiBzdWNjZWVkcy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIHVuY2hhbmdlZCBieSB0aGUgc3Rha2VyIHByb3h5LgovLyAgIC0gdGFyZ2V0UG9vbFBhdGg6IFBvb2wgY29udGFpbmluZyB0aGUgaW5jZW50aXZlIHRvIGVuZC4KLy8gICAtIGluY2VudGl2ZUlkOiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgaW5jZW50aXZlIHRvIGZpbmFsaXplLgovLyAgIC0gcmVmdW5kQWRkcmVzczogQWRkcmVzcyByZWNlaXZpbmcgdGhlIHJlZnVuZGFibGUgcmV3YXJkIGFtb3VudCBhbmQgR05TIGRlcG9zaXQuCi8vCi8vIFByb2Nlc3M6Ci8vICAxLiBWYWxpZGF0ZXMgdGhhdCB0aGUgaW5jZW50aXZlIGVuZCB0aW1lIGhhcyBiZWVuIHJlYWNoZWQgYW5kIG5vIGV4aXQgY2hlY2twb2ludCBzdGlsbCBvd2VzIGl0LgovLyAgMi4gQ2FsY3VsYXRlcyB1bmNsYWltYWJsZS9yZW1haW5kZXIgcmV3YXJkcy4KLy8gIDMuIE1hcmtzIHRoZSBpbmNlbnRpdmUgcmVmdW5kZWQgYW5kIHJldGFpbnMgaXRzIHJlY29yZC4KLy8gIDQuIFRyYW5zZmVycyB0aGUgcmVmdW5kYWJsZSByZXdhcmRzIGFuZCBkZXBvc2l0ZWQgR05TIHRvIHJlZnVuZEFkZHJlc3MuCi8vCi8vIE9ubHkgY2FsbGFibGUgYnkgdGhlIGluY2VudGl2ZSBjcmVhdG9yIG9yIGFkbWluLgpmdW5jIChzICpzdGFrZXJWMSkgRW5kRXh0ZXJuYWxJbmNlbnRpdmUoXyBpbnQsIHJsbSByZWFsbSwgdGFyZ2V0UG9vbFBhdGgsIGluY2VudGl2ZUlkIHN0cmluZywgcmVmdW5kQWRkcmVzcyBhZGRyZXNzKSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCgloYWx0LkFzc2VydElzTm90SGFsdGVkV2l0aGRyYXcoKQoKCS8vIGNoZWNrcyBwb29sIHJlZ2lzdHJ5Cglhc3NlcnRJc1Bvb2xFeGlzdHMocywgdGFyZ2V0UG9vbFBhdGgpCglhc3NlcnRJc1ZhbGlkQWRkcmVzcyhyZWZ1bmRBZGRyZXNzKQoJYXNzZXJ0SGFzTm9VbmNvbGxlY3RlZEluY2VudGl2ZShzLCBpbmNlbnRpdmVJZCkKCgkvLyBjaGVja3MgaWYgdGhlIHBvb2wgaGFzIGJlZW4gaW5jZW50aXZpemVkCglwb29sLCBvayA6PSBzLmdldFBvb2xzKCkuR2V0KHRhcmdldFBvb2xQYXRoKQoJaWYgIW9rIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJyRGF0YU5vdEZvdW5kLAoJCQl1Zm10LlNwcmludGYoInRhcmdldFBvb2xQYXRoKCVzKSBub3QgZm91bmQiLCB0YXJnZXRQb29sUGF0aCksCgkJKSkKCX0KCglwb29sUmVzb2x2ZXIgOj0gTmV3UG9vbFJlc29sdmVyKHBvb2wpCglpbmNlbnRpdmVzUmVzb2x2ZXIgOj0gcG9vbFJlc29sdmVyLkluY2VudGl2ZXNSZXNvbHZlcigpCgoJLy8gR2V0IGluY2VudGl2ZSB0byBjaGVjayBpZiBHTlMgYWxyZWFkeSByZWZ1bmRlZAoJaW5jZW50aXZlUmVzb2x2ZXIsIGV4aXN0cyA6PSBpbmNlbnRpdmVzUmVzb2x2ZXIuR2V0SW5jZW50aXZlUmVzb2x2ZXIoaW5jZW50aXZlSWQpCglpZiAhZXhpc3RzIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJyQ2Fubm90RW5kSW5jZW50aXZlLAoJCQl1Zm10LlNwcmludGYoImNhbm5vdCBlbmQgbm9uIGV4aXN0ZW50IGluY2VudGl2ZSglcykiLCBpbmNlbnRpdmVJZCksCgkJKSkKCX0KCgkvLyBDaGVjayBpZiBpbmNlbnRpdmUgaGFzIGFscmVhZHkgYmVlbiByZWZ1bmRlZAoJaWYgaW5jZW50aXZlUmVzb2x2ZXIuUmVmdW5kZWQoKSB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckNhbm5vdEVuZEluY2VudGl2ZSwKCQkJdWZtdC5TcHJpbnRmKCJpbmNlbnRpdmUoJXMpIGhhcyBhbHJlYWR5IGJlZW4gcmVmdW5kZWQiLCBpbmNlbnRpdmVJZCksCgkJKSkKCX0KCgljYWxsZXIgOj0gcmxtLlByZXZpb3VzKCkuQWRkcmVzcygpCgoJLy8gUHJvY2VzcyBlbmRpbmcKCWluY2VudGl2ZSwgcmVmdW5kLCBlcnIgOj0gcy5lbmRFeHRlcm5hbEluY2VudGl2ZShwb29sUmVzb2x2ZXIsIGluY2VudGl2ZVJlc29sdmVyLCBjYWxsZXIsIHRpbWUuTm93KCkuVW5peCgpKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCXN0YWtlckFkZHIgOj0gYWNjZXNzLk11c3RHZXRBZGRyZXNzKHByYmFjLlJPTEVfU1RBS0VSLlN0cmluZygpKQoJcG9vbExlZnRFeHRlcm5hbFJld2FyZEFtb3VudCA6PSBjb21tb24uQmFsYW5jZU9mKGluY2VudGl2ZVJlc29sdmVyLlJld2FyZFRva2VuKCksIHN0YWtlckFkZHIpCglpZiBwb29sTGVmdEV4dGVybmFsUmV3YXJkQW1vdW50IDwgcmVmdW5kIHsKCQlwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgkJY2hhaW4uRW1pdCgKCQkJIkVuZEV4dGVybmFsSW5jZW50aXZlU2hvcnRmYWxsIiwKCQkJInByZXZBZGRyIiwgcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkuU3RyaW5nKCksCgkJCSJwcmV2UmVhbG0iLCBwcmV2aW91c1JlYWxtLlBrZ1BhdGgoKSwKCQkJImluY2VudGl2ZUlkIiwgaW5jZW50aXZlSWQsCgkJCSJ0YXJnZXRQb29sUGF0aCIsIHRhcmdldFBvb2xQYXRoLAoJCQkicmVmdW5kZWUiLCByZWZ1bmRBZGRyZXNzLlN0cmluZygpLAoJCQkicmVmdW5kVG9rZW4iLCBpbmNlbnRpdmVSZXNvbHZlci5SZXdhcmRUb2tlbigpLAoJCQkiZXhwZWN0ZWRSZWZ1bmRBbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQocmVmdW5kKSwKCQkJImFjdHVhbFJlZnVuZEFtb3VudCIsIHV0aWxzLkZvcm1hdEludChwb29sTGVmdEV4dGVybmFsUmV3YXJkQW1vdW50KSwKCQkJImNyZWF0b3IiLCBpbmNlbnRpdmVSZXNvbHZlci5DcmVhdG9yKCkuU3RyaW5nKCksCgkJKQoJCXJlZnVuZCA9IHBvb2xMZWZ0RXh0ZXJuYWxSZXdhcmRBbW91bnQKCX0KCgkvLyBNYXJrIGluY2VudGl2ZSBhcyByZWZ1bmRlZCBhbmQgdXBkYXRlCgkvLyBBZnRlciB0aGlzIHVwZGF0ZSwgYXR0ZW1wdHMgdG8gcmUtY2xhaW0gR05TIG9yIHJld2FyZHMgdGhhdCB3ZXJlIGRlcG9zaXRlZAoJLy8gdGhyb3VnaCB0aGUgYGVuZEV4dGVybmFsSW5jZW50aXZlYCBmdW5jdGlvbiB3aWxsIGJlIGJsb2NrZWQuCglpbmNlbnRpdmVSZXNvbHZlci5TZXRSZWZ1bmRlZCh0cnVlKQoJaW5jZW50aXZlUmVzb2x2ZXIuU2V0UmV3YXJkQW1vdW50KGduc21hdGguU2FmZVN1YkludDY0KGluY2VudGl2ZVJlc29sdmVyLlJld2FyZEFtb3VudCgpLCByZWZ1bmQpKQoJaW5jZW50aXZlUmVzb2x2ZXIuYWRkRGlzdHJpYnV0ZWRSZXdhcmRBbW91bnQocmVmdW5kKQoJaW5jZW50aXZlc1Jlc29sdmVyLnVwZGF0ZShpbmNlbnRpdmUpCgoJLy8gcmVmdW5kIHJld2FyZCB0b2tlbiB0byByZWZ1bmRlZQoJY29tbW9uLlNhZmVHUkMyMFRyYW5zZmVyKDAsIHJsbSwgaW5jZW50aXZlUmVzb2x2ZXIuUmV3YXJkVG9rZW4oKSwgcmVmdW5kQWRkcmVzcywgcmVmdW5kKQoKCS8vIFRyYW5zZmVyIEdOUyBkZXBvc2l0IGJhY2sgdG8gcmVmdW5kZWUKCWNvbW1vbi5TYWZlR1JDMjBUcmFuc2ZlcigwLCBybG0sIEdOU19UT0tFTl9LRVksIHJlZnVuZEFkZHJlc3MsIGluY2VudGl2ZVJlc29sdmVyLkRlcG9zaXRHbnNBbW91bnQoKSkKCglwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgljaGFpbi5FbWl0KAoJCSJFbmRFeHRlcm5hbEluY2VudGl2ZSIsCgkJInByZXZBZGRyIiwgcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCSJpbmNlbnRpdmVJZCIsIGluY2VudGl2ZUlkLAoJCSJ0YXJnZXRQb29sUGF0aCIsIHRhcmdldFBvb2xQYXRoLAoJCSJyZWZ1bmRlZSIsIHJlZnVuZEFkZHJlc3MuU3RyaW5nKCksCgkJInJlZnVuZFRva2VuIiwgaW5jZW50aXZlUmVzb2x2ZXIuUmV3YXJkVG9rZW4oKSwKCQkicmVmdW5kQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KHJlZnVuZCksCgkJInJlZnVuZEduc0Ftb3VudCIsIHV0aWxzLkZvcm1hdEludChpbmNlbnRpdmVSZXNvbHZlci5EZXBvc2l0R25zQW1vdW50KCkpLAoJCSJleHRlcm5hbEluY2VudGl2ZUVuZEJ5IiwgcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkuU3RyaW5nKCksCgkJImNyZWF0b3IiLCBpbmNlbnRpdmVSZXNvbHZlci5DcmVhdG9yKCkuU3RyaW5nKCksCgkpCn0KCi8vIGVuZEV4dGVybmFsSW5jZW50aXZlIHByb2Nlc3NlcyB0aGUgZW5kIG9mIGFuIGV4dGVybmFsIGluY2VudGl2ZSBwcm9ncmFtLgpmdW5jIChzICpzdGFrZXJWMSkgZW5kRXh0ZXJuYWxJbmNlbnRpdmUocmVzb2x2ZXIgKlBvb2xSZXNvbHZlciwgaW5jZW50aXZlUmVzb2x2ZXIgKkV4dGVybmFsSW5jZW50aXZlUmVzb2x2ZXIsIGNhbGxlciBhZGRyZXNzLCBjdXJyZW50VGltZSBpbnQ2NCkgKCpzci5FeHRlcm5hbEluY2VudGl2ZSwgaW50NjQsIGVycm9yKSB7CglpZiBjdXJyZW50VGltZSA8IGluY2VudGl2ZVJlc29sdmVyLkVuZFRpbWVzdGFtcCgpIHsKCQlyZXR1cm4gbmlsLCAwLCBtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJyQ2Fubm90RW5kSW5jZW50aXZlLAoJCQl1Zm10LlNwcmludGYoImNhbm5vdCBlbmQgaW5jZW50aXZlIGJlZm9yZSBlbmRUaW1lKCVkKSwgY3VycmVudCglZCkiLCBpbmNlbnRpdmVSZXNvbHZlci5FbmRUaW1lc3RhbXAoKSwgY3VycmVudFRpbWUpLAoJCSkKCX0KCgkvLyBvbmx5IGNyZWF0b3Igb3IgYWRtaW4gY2FuIGVuZCBpbmNlbnRpdmUKCWlmICFhY2Nlc3MuSXNBdXRob3JpemVkKHByYmFjLlJPTEVfQURNSU4uU3RyaW5nKCksIGNhbGxlcikgJiYgY2FsbGVyICE9IGluY2VudGl2ZVJlc29sdmVyLkNyZWF0b3IoKSB7CgkJYWRtaW5BZGRyIDo9IGFjY2Vzcy5NdXN0R2V0QWRkcmVzcyhwcmJhYy5ST0xFX0FETUlOLlN0cmluZygpKQoJCXJldHVybiBuaWwsIDAsIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJOb1Blcm1pc3Npb24sCgkJCXVmbXQuU3ByaW50ZigKCQkJCSJvbmx5IGNyZWF0b3IoJXMpIG9yIGFkbWluKCVzKSBjYW4gZW5kIGluY2VudGl2ZSwgYnV0IGNhbGxlZCBmcm9tICVzIiwKCQkJCWluY2VudGl2ZVJlc29sdmVyLkNyZWF0b3IoKSwgYWRtaW5BZGRyLlN0cmluZygpLCBjYWxsZXIsCgkJCSksCgkJKQoJfQoKCS8vIHJlZnVuZCA9IHVuY2xhaW1hYmxlUmV3YXJkICsgcmVtYWluZGVyLiBBY2N1bXVsYXRlZCB3YXJtdXAgcGVuYWx0aWVzIGFyZSB0cmFja2VkIHNlcGFyYXRlbHkKCS8vIGFuZCBjb2xsZWN0ZWQgdGhyb3VnaCBDb2xsZWN0RXh0ZXJuYWxJbmNlbnRpdmVQZW5hbHR5IGFmdGVyIHRoZSBpbmNlbnRpdmUgaXMgZW5kZWQuCglpbmNlbnRpdmVzUmVzb2x2ZXIgOj0gcmVzb2x2ZXIuSW5jZW50aXZlc1Jlc29sdmVyKCkKCXVuY2xhaW1hYmxlUmV3YXJkIDo9IGluY2VudGl2ZXNSZXNvbHZlci5jYWxjdWxhdGVVbmNsYWltYWJsZVJld2FyZChpbmNlbnRpdmVSZXNvbHZlci5JbmNlbnRpdmVJZCgpKQoJZHVyYXRpb24gOj0gZ25zbWF0aC5TYWZlU3ViSW50NjQoaW5jZW50aXZlUmVzb2x2ZXIuRW5kVGltZXN0YW1wKCksIGluY2VudGl2ZVJlc29sdmVyLlN0YXJ0VGltZXN0YW1wKCkpCglkaXN0cmlidXRhYmxlVTI1NiA6PSB1MjU2Lk11bERpdigKCQlpbmNlbnRpdmVSZXNvbHZlci5SZXdhcmRQZXJTZWNvbmRYMTI4KCksCgkJdTI1Ni5OZXdVaW50RnJvbUludDY0KGR1cmF0aW9uKSwKCQlxMTI4LAoJKQoKCWRpc3RyaWJ1dGFibGUgOj0gZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQoZGlzdHJpYnV0YWJsZVUyNTYpCglyZW1haW5kZXIgOj0gZ25zbWF0aC5TYWZlU3ViSW50NjQoaW5jZW50aXZlUmVzb2x2ZXIuVG90YWxSZXdhcmRBbW91bnQoKSwgZGlzdHJpYnV0YWJsZSkKCglyZWZ1bmQgOj0gZ25zbWF0aC5TYWZlQWRkSW50NjQodW5jbGFpbWFibGVSZXdhcmQsIHJlbWFpbmRlcikKCgltYXhSZWZ1bmQgOj0gaW5jZW50aXZlUmVzb2x2ZXIuUmV3YXJkQW1vdW50KCkKCWlmIHJlZnVuZCA+IG1heFJlZnVuZCB7CgkJcmVmdW5kID0gbWF4UmVmdW5kCgl9CgoJaWYgcmVmdW5kIDwgMCB7CgkJcmV0dXJuIG5pbCwgMCwgbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckNhbGN1bGF0aW9uRXJyb3IsCgkJCXVmbXQuU3ByaW50ZigicmVmdW5kIHNob3VsZCBuZXZlciBiZSBuZWdhdGl2ZTogR290ICVkIiwgcmVmdW5kKSwKCQkpCgl9CgoJcmV0dXJuIGluY2VudGl2ZVJlc29sdmVyLkV4dGVybmFsSW5jZW50aXZlLCByZWZ1bmQsIG5pbAp9CgovLyBDYW5jZWxFeHRlcm5hbEluY2VudGl2ZSBjYW5jZWxzIGFuIGV4dGVybmFsIGluY2VudGl2ZSBiZWZvcmUgaXQgc3RhcnRzIGFuZAovLyByZW1vdmVzIGl0IGVudGlyZWx5LgovLwovLyBFbmRFeHRlcm5hbEluY2VudGl2ZSBpcyB0aGUgY291bnRlcnBhcnQgZm9yIGFuIGluY2VudGl2ZSB3aG9zZSBlbmQgdGltZXN0YW1wCi8vIGhhcyBwYXNzZWQ6IGl0IGtlZXBzIHRoZSByZWNvcmQgc28gdGhlIHBlbmFsdHkgYWNjb3VudGluZyBhbmQgdGhlIGRlcG9zaXRzCi8vIHRoYXQgYWxyZWFkeSBjb2xsZWN0ZWQgZnJvbSBpdCBzdGF5IHJlc29sdmFibGUuIENhbmNlbGxpbmcgaXMgb25seSBhbGxvd2VkCi8vIHN0cmljdGx5IGJlZm9yZSBzdGFydFRpbWVzdGFtcCwgd2hlcmUgbm90aGluZyBoYXMgYWNjcnVlZCB5ZXQgLSBubyBkZXBvc2l0Ci8vIHJlZmVyZW5jZXMgdGhlIGluY2VudGl2ZSAoYm90aCBTdGFrZVRva2VuIGFuZCB0aGUgbGF6eSByZXdhcmQgZGlzY292ZXJ5IG9ubHkKLy8gbG9vayBhdCBpbmNlbnRpdmVzIHdob3NlIHN0YXJ0IHRpbWVzdGFtcCBpcyBhbHJlYWR5IGluIHRoZSBwYXN0KSwgc28gdGhlCi8vIHJlY29yZCBjYW4gYmUgZHJvcHBlZCBmcm9tIHRoZSBpbmNlbnRpdmUgdHJlZSBhbmQgdGhlIHN0YXJ0LXRpbWUgaW5kZXgKLy8gaW5zdGVhZCBvZiBiZWluZyBtYXJrZWQgcmVmdW5kZWQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBOb25jcm9zc2luZyBpbXBsZW1lbnRhdGlvbi1jYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8gICAtIHJsbTogQ3VycmVudCByZWFsbSBjb250ZXh0IGZvcndhcmRlZCB1bmNoYW5nZWQgYnkgdGhlIHN0YWtlciBwcm94eS4KLy8gICAtIHRhcmdldFBvb2xQYXRoOiBQb29sIHBhdGggZm9yIHdoaWNoIHRoZSBpbmNlbnRpdmUgd2FzIGNyZWF0ZWQuCi8vICAgLSBpbmNlbnRpdmVJZDogVW5pcXVlIGlkZW50aWZpZXIgb2YgdGhlIGluY2VudGl2ZSB0byBjYW5jZWwuCi8vCi8vIFByb2Nlc3M6Ci8vICAxLiBWYWxpZGF0ZXMgdGhlIGluY2VudGl2ZSBleGlzdHMgYW5kIGhhcyBub3Qgc3RhcnRlZC4KLy8gIDIuIFJlbW92ZXMgaXQgZnJvbSB0aGUgaW5jZW50aXZlIHRyZWUgYW5kIHRoZSBzdGFydC10aW1lIGluZGV4LgovLyAgMy4gUmVmdW5kcyB0aGUgYXZhaWxhYmxlIHJld2FyZC10b2tlbiBiYWxhbmNlIChjYXBwZWQgYnkgdGhlIHN0YWtlciBiYWxhbmNlKSBhbmQgdGhlIEdOUyBkZXBvc2l0IHRvIHRoZSBjcmVhdG9yLgovLwovLyBPbmx5IGNhbGxhYmxlIGJ5IGFkbWluLCBnb3Zlcm5hbmNlLCBvciB0aGUgaW5jZW50aXZlIGNyZWF0b3IuIFRoZSBwZXJtaXNzaW9uCi8vIGNoZWNrIHJ1bnMgYWZ0ZXIgdGhlIGluY2VudGl2ZSBpcyByZXNvbHZlZCBiZWNhdXNlIHRoZSBjcmVhdG9yIGlkZW50aXR5IGNvbWVzCi8vIGZyb20gdGhlIHN0b3JlZCByZWNvcmQ7IGV2ZXJ5IHN0ZXAgYmVmb3JlIGl0IGlzIHJlYWQtb25seSwgc28gbm8gdW5hdXRob3JpemVkCi8vIHNpZGUgZWZmZWN0IGNhbiBvY2N1ciBhaGVhZCBvZiB0aGUgY2hlY2suCmZ1bmMgKHMgKnN0YWtlclYxKSBDYW5jZWxFeHRlcm5hbEluY2VudGl2ZShfIGludCwgcmxtIHJlYWxtLCB0YXJnZXRQb29sUGF0aCwgaW5jZW50aXZlSWQgc3RyaW5nKSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCgloYWx0LkFzc2VydElzTm90SGFsdGVkV2l0aGRyYXcoKQoKCWFzc2VydElzUG9vbEV4aXN0cyhzLCB0YXJnZXRQb29sUGF0aCkKCglwcmV2UmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2UmVhbG0uQWRkcmVzcygpCgoJcG9vbCwgb2sgOj0gcy5nZXRQb29scygpLkdldCh0YXJnZXRQb29sUGF0aCkKCWlmICFvayB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckRhdGFOb3RGb3VuZCwKCQkJdWZtdC5TcHJpbnRmKCJ0YXJnZXRQb29sUGF0aCglcykgbm90IGZvdW5kIiwgdGFyZ2V0UG9vbFBhdGgpLAoJCSkpCgl9CgoJcG9vbFJlc29sdmVyIDo9IE5ld1Bvb2xSZXNvbHZlcihwb29sKQoJaW5jZW50aXZlc1Jlc29sdmVyIDo9IHBvb2xSZXNvbHZlci5JbmNlbnRpdmVzUmVzb2x2ZXIoKQoKCWluY2VudGl2ZVJlc29sdmVyLCBleGlzdHMgOj0gaW5jZW50aXZlc1Jlc29sdmVyLkdldEluY2VudGl2ZVJlc29sdmVyKGluY2VudGl2ZUlkKQoJaWYgIWV4aXN0cyB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckNhbm5vdENhbmNlbEluY2VudGl2ZSwKCQkJdWZtdC5TcHJpbnRmKCJjYW5ub3QgY2FuY2VsIG5vbiBleGlzdGVudCBpbmNlbnRpdmUoJXMpIiwgaW5jZW50aXZlSWQpLAoJCSkpCgl9CgoJLy8gQWRtaW4sIGdvdmVybmFuY2UsIG9yIHRoZSBpbmNlbnRpdmUgY3JlYXRvciBtYXkgY2FuY2VsIGl0LgoJYXNzZXJ0SXNBZG1pbkdvdmVybmFuY2VPckNyZWF0b3IoY2FsbGVyLCBpbmNlbnRpdmVSZXNvbHZlci5DcmVhdG9yKCkpCgoJY3VycmVudFRpbWUgOj0gdGltZS5Ob3coKS5Vbml4KCkKCWFzc2VydElzTm90U3RhcnRlZEluY2VudGl2ZShpbmNlbnRpdmVSZXNvbHZlciwgY3VycmVudFRpbWUpCgoJcmV3YXJkVG9rZW4gOj0gaW5jZW50aXZlUmVzb2x2ZXIuUmV3YXJkVG9rZW4oKQoJZGVwb3NpdEduc0Ftb3VudCA6PSBpbmNlbnRpdmVSZXNvbHZlci5EZXBvc2l0R25zQW1vdW50KCkKCXJlZnVuZEFtb3VudCA6PSBpbmNlbnRpdmVSZXNvbHZlci5SZXdhcmRBbW91bnQoKQoKCS8vIFRoZSByZXdhcmQgdG9rZW5zIGFuZCB0aGUgR05TIGRlcG9zaXQgYXJlIGFsd2F5cyByZXR1cm5lZCB0byB0aGUgaW5jZW50aXZlCgkvLyBjcmVhdG9yIC0gdGhlIGFkZHJlc3MgdGhhdCBmdW5kZWQgdGhlbSBpbiBDcmVhdGVFeHRlcm5hbEluY2VudGl2ZSAtIHNvIHRoZQoJLy8gcmVmdW5kIGRlc3RpbmF0aW9uIGlzIG5ldmVyIGNhbGxlci1jb250cm9sbGVkLgoJY3JlYXRvciA6PSBpbmNlbnRpdmVSZXNvbHZlci5DcmVhdG9yKCkKCgkvLyBDYXAgdGhlIHJlZnVuZCBieSB0aGUgYmFsYW5jZSBhY3R1YWxseSBoZWxkLCBtaXJyb3JpbmcKCS8vIEVuZEV4dGVybmFsSW5jZW50aXZlOiBhIHNob3J0IGJhbGFuY2UgbXVzdCBub3QgYWJvcnQgdGhlIGNhbmNlbGxhdGlvbiBhbmQKCS8vIHN0cmFuZCB0aGUgR05TIGRlcG9zaXQgYXMgd2VsbC4KCXN0YWtlckFkZHIgOj0gYWNjZXNzLk11c3RHZXRBZGRyZXNzKHByYmFjLlJPTEVfU1RBS0VSLlN0cmluZygpKQoJcmV3YXJkQmFsYW5jZSA6PSBjb21tb24uQmFsYW5jZU9mKHJld2FyZFRva2VuLCBzdGFrZXJBZGRyKQoJaWYgcmV3YXJkQmFsYW5jZSA8IHJlZnVuZEFtb3VudCB7CgkJY2hhaW4uRW1pdCgKCQkJIkNhbmNlbEV4dGVybmFsSW5jZW50aXZlU2hvcnRmYWxsIiwKCQkJInByZXZBZGRyIiwgY2FsbGVyLlN0cmluZygpLAoJCQkicHJldlJlYWxtIiwgcHJldlJlYWxtLlBrZ1BhdGgoKSwKCQkJImluY2VudGl2ZUlkIiwgaW5jZW50aXZlSWQsCgkJCSJ0YXJnZXRQb29sUGF0aCIsIHRhcmdldFBvb2xQYXRoLAoJCQkicmVmdW5kVG9rZW4iLCByZXdhcmRUb2tlbiwKCQkJImV4cGVjdGVkUmVmdW5kQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KHJlZnVuZEFtb3VudCksCgkJCSJhY3R1YWxSZWZ1bmRBbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQocmV3YXJkQmFsYW5jZSksCgkJCSJyZWZ1bmRlZSIsIGNyZWF0b3IuU3RyaW5nKCksCgkJCSJjcmVhdG9yIiwgY3JlYXRvci5TdHJpbmcoKSwKCQkpCgkJcmVmdW5kQW1vdW50ID0gcmV3YXJkQmFsYW5jZQoJfQoKCS8vIEVmZmVjdHMgYmVmb3JlIGludGVyYWN0aW9uczogb25jZSByZW1vdmVkLCBubyBzdGFrZSwgY29sbGVjdCBvciBkaXNjb3ZlcnkKCS8vIHBhdGggY2FuIHJlc29sdmUgdGhlIGluY2VudGl2ZSwgc28gdGhlIHJlZnVuZCBjYW5ub3QgYmUgcmVwbGF5ZWQuCglpbmNlbnRpdmVzUmVzb2x2ZXIucmVtb3ZlKGluY2VudGl2ZVJlc29sdmVyLkV4dGVybmFsSW5jZW50aXZlKQoJcy5nZXRFeHRlcm5hbEluY2VudGl2ZXMoKS5yZW1vdmUoaW5jZW50aXZlSWQpCgoJaWYgcmVmdW5kQW1vdW50ID4gMCB7CgkJLy8gdHJhbnNmZXIgcmV3YXJkIHRva2VuIGJhY2sgdG8gY3JlYXRvcgoJCWNvbW1vbi5TYWZlR1JDMjBUcmFuc2ZlcigwLCBybG0sIHJld2FyZFRva2VuLCBjcmVhdG9yLCByZWZ1bmRBbW91bnQpCgl9CgoJaWYgZGVwb3NpdEduc0Ftb3VudCA+IDAgewoJCS8vIHRyYW5zZmVyIEdOUyBkZXBvc2l0IGJhY2sgdG8gY3JlYXRvcgoJCWNvbW1vbi5TYWZlR1JDMjBUcmFuc2ZlcigwLCBybG0sIEdOU19UT0tFTl9LRVksIGNyZWF0b3IsIGRlcG9zaXRHbnNBbW91bnQpCgl9CgoJY2hhaW4uRW1pdCgKCQkiQ2FuY2VsRXh0ZXJuYWxJbmNlbnRpdmUiLAoJCSJwcmV2QWRkciIsIGNhbGxlci5TdHJpbmcoKSwKCQkicHJldlJlYWxtIiwgcHJldlJlYWxtLlBrZ1BhdGgoKSwKCQkiaW5jZW50aXZlSWQiLCBpbmNlbnRpdmVJZCwKCQkidGFyZ2V0UG9vbFBhdGgiLCB0YXJnZXRQb29sUGF0aCwKCQkicmVmdW5kVG9rZW4iLCByZXdhcmRUb2tlbiwKCQkicmVmdW5kQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KHJlZnVuZEFtb3VudCksCgkJInJlZnVuZEduc0Ftb3VudCIsIHV0aWxzLkZvcm1hdEludChkZXBvc2l0R25zQW1vdW50KSwKCQkic3RhcnRUaW1lc3RhbXAiLCB1dGlscy5Gb3JtYXRJbnQoaW5jZW50aXZlUmVzb2x2ZXIuU3RhcnRUaW1lc3RhbXAoKSksCgkJImVuZFRpbWVzdGFtcCIsIHV0aWxzLkZvcm1hdEludChpbmNlbnRpdmVSZXNvbHZlci5FbmRUaW1lc3RhbXAoKSksCgkJImV4dGVybmFsSW5jZW50aXZlQ2FuY2VsQnkiLCBjYWxsZXIuU3RyaW5nKCksCgkJImNyZWF0b3IiLCBjcmVhdG9yLlN0cmluZygpLAoJCSJjdXJyZW50VGltZSIsIHV0aWxzLkZvcm1hdEludChjdXJyZW50VGltZSksCgkpCn0KCi8vIENvbGxlY3RFeHRlcm5hbEluY2VudGl2ZVBlbmFsdHkgY29sbGVjdHMgYWNjdW11bGF0ZWQgd2FybXVwIHBlbmFsdGllcyBmb3IgYSBzcGVjaWZpYyBlbmRlZAovLyBleHRlcm5hbCBpbmNlbnRpdmUuIFRoZSBpbmNlbnRpdmUgbXVzdCBmaXJzdCBiZSBmaW5hbGl6ZWQgd2l0aCBFbmRFeHRlcm5hbEluY2VudGl2ZS4KLy8gUGVuYWx0aWVzIGFyZSBhY2N1bXVsYXRlZCBkdXJpbmcgQ29sbGVjdFJld2FyZCBhbmQgc3RvcmVkIGluIHRoZSBpbmNlbnRpdmUuCi8vIFRoaXMgZnVuY3Rpb24gdHJhbnNmZXJzIHRoZSBhY2N1bXVsYXRlZCBwZW5hbHR5IHRvIHRoZSBzcGVjaWZpZWQgcmVmdW5kIGFkZHJlc3MuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBOb25jcm9zc2luZyBpbXBsZW1lbnRhdGlvbi1jYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8gICAtIHJsbTogQ3VycmVudCByZWFsbSBjb250ZXh0IGZvcndhcmRlZCB1bmNoYW5nZWQgYnkgdGhlIHN0YWtlciBwcm94eS4KLy8gICAtIHRhcmdldFBvb2xQYXRoOiBQb29sIGNvbnRhaW5pbmcgdGhlIGVuZGVkIGluY2VudGl2ZS4KLy8gICAtIGluY2VudGl2ZUlkOiBVbmlxdWUgaWRlbnRpZmllciBvZiB0aGUgZW5kZWQgaW5jZW50aXZlIHdob3NlIHBlbmFsdHkgaXMgY29sbGVjdGVkLgovLyAgIC0gcmVmdW5kQWRkcmVzczogQWRkcmVzcyByZWNlaXZpbmcgdGhlIHRyYW5zZmVycmVkIHBlbmFsdHkgYW1vdW50LgovLwovLyBSZXR1cm5zOgovLyAgIC0gcGVuYWx0eUFtb3VudDogQWNjdW11bGF0ZWQgd2FybXVwIHBlbmFsdHkgdHJhbnNmZXJyZWQsIGNhcHBlZCBieSB0aGUgc3Rha2VyJ3MgYXZhaWxhYmxlIHJld2FyZC10b2tlbiBiYWxhbmNlLgovLwovLyBPbmx5IGNhbGxhYmxlIGJ5IHRoZSBpbmNlbnRpdmUgY3JlYXRvciBvciBhZG1pbi4KZnVuYyAocyAqc3Rha2VyVjEpIENvbGxlY3RFeHRlcm5hbEluY2VudGl2ZVBlbmFsdHkoCglfIGludCwKCXJsbSByZWFsbSwKCXRhcmdldFBvb2xQYXRoIHN0cmluZywKCWluY2VudGl2ZUlkIHN0cmluZywKCXJlZnVuZEFkZHJlc3MgYWRkcmVzcywKKSBpbnQ2NCB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCgloYWx0LkFzc2VydElzTm90SGFsdGVkV2l0aGRyYXcoKQoKCWFzc2VydElzUG9vbEV4aXN0cyhzLCB0YXJnZXRQb29sUGF0aCkKCWFzc2VydElzVmFsaWRBZGRyZXNzKHJlZnVuZEFkZHJlc3MpCgoJcG9vbCwgb2sgOj0gcy5nZXRQb29scygpLkdldCh0YXJnZXRQb29sUGF0aCkKCWlmICFvayB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckRhdGFOb3RGb3VuZCwKCQkJdWZtdC5TcHJpbnRmKCJ0YXJnZXRQb29sUGF0aCglcykgbm90IGZvdW5kIiwgdGFyZ2V0UG9vbFBhdGgpLAoJCSkpCgl9CgoJcG9vbFJlc29sdmVyIDo9IE5ld1Bvb2xSZXNvbHZlcihwb29sKQoJaW5jZW50aXZlc1Jlc29sdmVyIDo9IHBvb2xSZXNvbHZlci5JbmNlbnRpdmVzUmVzb2x2ZXIoKQoKCWluY2VudGl2ZVJlc29sdmVyLCBleGlzdHMgOj0gaW5jZW50aXZlc1Jlc29sdmVyLkdldEluY2VudGl2ZVJlc29sdmVyKGluY2VudGl2ZUlkKQoJaWYgIWV4aXN0cyB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckRhdGFOb3RGb3VuZCwKCQkJdWZtdC5TcHJpbnRmKCJpbmNlbnRpdmUoJXMpIG5vdCBmb3VuZCIsIGluY2VudGl2ZUlkKSwKCQkpKQoJfQoKCWlmICFpbmNlbnRpdmVSZXNvbHZlci5SZWZ1bmRlZCgpIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJySXNOb3RFbmRlZEluY2VudGl2ZSwKCQkJdWZtdC5TcHJpbnRmKCJpbmNlbnRpdmUoJXMpIG11c3QgYmUgZW5kZWQgZmlyc3QgKGNhbGwgRW5kRXh0ZXJuYWxJbmNlbnRpdmUpIiwgaW5jZW50aXZlSWQpLAoJCSkpCgl9CgoJY2FsbGVyIDo9IHJsbS5QcmV2aW91cygpLkFkZHJlc3MoKQoJaWYgIWFjY2Vzcy5Jc0F1dGhvcml6ZWQocHJiYWMuUk9MRV9BRE1JTi5TdHJpbmcoKSwgY2FsbGVyKSAmJiBjYWxsZXIgIT0gaW5jZW50aXZlUmVzb2x2ZXIuQ3JlYXRvcigpIHsKCQlhZG1pbkFkZHIgOj0gYWNjZXNzLk11c3RHZXRBZGRyZXNzKHByYmFjLlJPTEVfQURNSU4uU3RyaW5nKCkpCgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyck5vUGVybWlzc2lvbiwKCQkJdWZtdC5TcHJpbnRmKCJvbmx5IGNyZWF0b3IoJXMpIG9yIGFkbWluKCVzKSBjYW4gY29sbGVjdCBwZW5hbHR5LCBidXQgY2FsbGVkIGZyb20gJXMiLCBpbmNlbnRpdmVSZXNvbHZlci5DcmVhdG9yKCksIGFkbWluQWRkci5TdHJpbmcoKSwgY2FsbGVyKSwKCQkpKQoJfQoKCXBlbmFsdHlBbW91bnQgOj0gaW5jZW50aXZlUmVzb2x2ZXIuQWNjdW11bGF0ZWRQZW5hbHR5QW1vdW50KCkKCWlmIHBlbmFsdHlBbW91bnQgPT0gMCB7CgkJcmV0dXJuIDAKCX0KCgkvLyBDYXAgYnkgYWN0dWFsIHN0YWtlciBiYWxhbmNlCglzdGFrZXJBZGRyIDo9IGFjY2Vzcy5NdXN0R2V0QWRkcmVzcyhwcmJhYy5ST0xFX1NUQUtFUi5TdHJpbmcoKSkKCWJhbGFuY2UgOj0gY29tbW9uLkJhbGFuY2VPZihpbmNlbnRpdmVSZXNvbHZlci5SZXdhcmRUb2tlbigpLCBzdGFrZXJBZGRyKQoJaWYgYmFsYW5jZSA8IHBlbmFsdHlBbW91bnQgewoJCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCQljaGFpbi5FbWl0KAoJCQkiQ29sbGVjdEV4dGVybmFsSW5jZW50aXZlUGVuYWx0eVNob3J0ZmFsbCIsCgkJCSJwcmV2QWRkciIsIHByZXZpb3VzUmVhbG0uQWRkcmVzcygpLlN0cmluZygpLAoJCQkicHJldlJlYWxtIiwgcHJldmlvdXNSZWFsbS5Qa2dQYXRoKCksCgkJCSJ0YXJnZXRQb29sUGF0aCIsIHRhcmdldFBvb2xQYXRoLAoJCQkiaW5jZW50aXZlSWQiLCBpbmNlbnRpdmVJZCwKCQkJInJlZnVuZEFkZHJlc3MiLCByZWZ1bmRBZGRyZXNzLlN0cmluZygpLAoJCQkicmVmdW5kVG9rZW4iLCBpbmNlbnRpdmVSZXNvbHZlci5SZXdhcmRUb2tlbigpLAoJCQkiZXhwZWN0ZWRQZW5hbHR5QW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KHBlbmFsdHlBbW91bnQpLAoJCQkiYWN0dWFsUGVuYWx0eUFtb3VudCIsIHV0aWxzLkZvcm1hdEludChiYWxhbmNlKSwKCQkJImNyZWF0b3IiLCBpbmNlbnRpdmVSZXNvbHZlci5DcmVhdG9yKCkuU3RyaW5nKCksCgkJKQoJCXBlbmFsdHlBbW91bnQgPSBiYWxhbmNlCgl9CgoJLy8gUmVzZXQgYWNjdW11bGF0ZWQgcGVuYWx0eQoJaW5jZW50aXZlUmVzb2x2ZXIuU2V0QWNjdW11bGF0ZWRQZW5hbHR5QW1vdW50KGduc21hdGguU2FmZVN1YkludDY0KGluY2VudGl2ZVJlc29sdmVyLkFjY3VtdWxhdGVkUGVuYWx0eUFtb3VudCgpLCBwZW5hbHR5QW1vdW50KSkKCWluY2VudGl2ZXNSZXNvbHZlci51cGRhdGUoaW5jZW50aXZlUmVzb2x2ZXIuRXh0ZXJuYWxJbmNlbnRpdmUpCgoJLy8gVHJhbnNmZXIgcGVuYWx0eSB0byByZWZ1bmQgYWRkcmVzcwoJY29tbW9uLlNhZmVHUkMyMFRyYW5zZmVyKDAsIHJsbSwgaW5jZW50aXZlUmVzb2x2ZXIuUmV3YXJkVG9rZW4oKSwgcmVmdW5kQWRkcmVzcywgcGVuYWx0eUFtb3VudCkKCglwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgljaGFpbi5FbWl0KAoJCSJDb2xsZWN0RXh0ZXJuYWxJbmNlbnRpdmVQZW5hbHR5IiwKCQkicHJldkFkZHIiLCBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKS5TdHJpbmcoKSwKCQkicHJldlJlYWxtIiwgcHJldmlvdXNSZWFsbS5Qa2dQYXRoKCksCgkJInRhcmdldFBvb2xQYXRoIiwgdGFyZ2V0UG9vbFBhdGgsCgkJImluY2VudGl2ZUlkIiwgaW5jZW50aXZlSWQsCgkJInJlZnVuZEFkZHJlc3MiLCByZWZ1bmRBZGRyZXNzLlN0cmluZygpLAoJCSJwZW5hbHR5QW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KHBlbmFsdHlBbW91bnQpLAoJKQoKCXJldHVybiBwZW5hbHR5QW1vdW50Cn0KGuAlChdleHRlcm5hbF90b2tlbl9saXN0LmdubxLEJXBhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJImNoYWluIgoKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCSJnbm8ubGFuZC9yL2dub3N3YXAvYWNjZXNzL3YxIgoJImduby5sYW5kL3IvZ25vc3dhcC9jb21tb24iCgkiZ25vLmxhbmQvci9nbm9zd2FwL2hhbHQvdjEiCglzciAiZ25vLmxhbmQvci9nbm9zd2FwL3N0YWtlciIKKQoKLy8gQWRkVG9rZW4gYWRkcyBhIHJlZ2lzdGVyZWQgdG9rZW4ga2V5IHRvIHRoZSBsaXN0IG9mIGFsbG93ZWQgdG9rZW5zLgovLyBPbmx5IGFkbWluIG9yIGdvdmVybmFuY2UgY2FuIGFkZCBhIHRva2VuLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTGVhZGluZyByZWFsbS1jYWxsIGRpc2NyaW1pbmF0b3I7IGNhbGxlcnMgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHN0YWtlciByZWFsbSBjb250ZXh0LCB2YWxpZGF0ZWQgYmVmb3JlIHN0b3JhZ2UgaXMgY2hhbmdlZC4KLy8gICAtIHRva2VuUGF0aDogUmVnaXN0ZXJlZCB0b2tlbiBwYXRoIHRvIGFkZCB0byB0aGUgYWxsb3dlZC10b2tlbiBsaXN0LgovLwovLyBQYW5pY3M6Ci8vICAgLSBJZiB0aGUgY2FsbGVyIGlzIG5vdCBhZG1pbiBvciBnb3Zlcm5hbmNlLCBvciB0aGUgdG9rZW4ga2V5IGlzIG5vdCByZWdpc3RlcmVkLgpmdW5jIChzICpzdGFrZXJWMSkgQWRkVG9rZW4oXyBpbnQsIHJsbSByZWFsbSwgdG9rZW5QYXRoIHN0cmluZykgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFN0YWtlcigpCgoJcHJldmlvdXNSZWFsbSA6PSBybG0uUHJldmlvdXMoKQoJY2FsbGVyIDo9IHByZXZpb3VzUmVhbG0uQWRkcmVzcygpCglhY2Nlc3MuQXNzZXJ0SXNBZG1pbk9yR292ZXJuYW5jZShjYWxsZXIpCgoJaWYgZXJyIDo9IGNoZWNrQ2Fubm90QWRkRGVmYXVsdFRva2VuKHRva2VuUGF0aCk7IGVyciAhPSBuaWwgewoJCXBhbmljKGVyci5FcnJvcigpKQoJfQoKCWNvbW1vbi5NdXN0UmVnaXN0ZXJlZCh0b2tlblBhdGgpCgoJaWYgZXJyIDo9IHMuc3RvcmUuQWRkQWxsb3dlZFRva2VuKDAsIHJsbSwgdG9rZW5QYXRoKTsgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyLkVycm9yKCkpCgl9CgoJY2hhaW4uRW1pdCgKCQkiQWRkVG9rZW4iLAoJCSJwcmV2QWRkciIsIGNhbGxlci5TdHJpbmcoKSwKCQkicHJldlJlYWxtIiwgcHJldmlvdXNSZWFsbS5Qa2dQYXRoKCksCgkJInRva2VuUGF0aCIsIHRva2VuUGF0aCwKCSkKfQoKLy8gUmVtb3ZlVG9rZW4gcmVtb3ZlcyBhIHRva2VuIHBhdGggZnJvbSB0aGUgbGlzdCBvZiBhbGxvd2VkIHRva2Vucy4KLy8gT25seSB0aGUgYWRtaW4gY2FuIHJlbW92ZSBhIHRva2VuLgovLwovLyBEZWZhdWx0IHRva2VucyBjYW5ub3QgYmUgcmVtb3ZlZC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IExlYWRpbmcgcmVhbG0tY2FsbCBkaXNjcmltaW5hdG9yOyBjYWxsZXJzIHBhc3MgMC4KLy8gICAtIHJsbTogQ3VycmVudCBzdGFrZXIgcmVhbG0gY29udGV4dCwgdmFsaWRhdGVkIGJlZm9yZSBzdG9yYWdlIGlzIGNoYW5nZWQuCi8vICAgLSB0b2tlblBhdGg6IFRva2VuIHBhdGggdG8gcmVtb3ZlIGZyb20gdGhlIGFsbG93ZWQtdG9rZW4gbGlzdC4KLy8KLy8gUGFuaWNzOgovLyAgIC0gSWYgdGhlIGNhbGxlciBpcyBub3QgYWRtaW4gb3IgZ292ZXJuYW5jZSwgb3IgdGhlIHRva2VuIHBhdGggaXMgYSBwcm90ZWN0ZWQgZGVmYXVsdCB0b2tlbi4KZnVuYyAocyAqc3Rha2VyVjEpIFJlbW92ZVRva2VuKF8gaW50LCBybG0gcmVhbG0sIHRva2VuUGF0aCBzdHJpbmcpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRTdGFrZXIoKQoKCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzQWRtaW5PckdvdmVybmFuY2UoY2FsbGVyKQoKCWlmIGVyciA6PSBjaGVja0Nhbm5vdFJlbW92ZURlZmF1bHRUb2tlbih0b2tlblBhdGgpOyBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIuRXJyb3IoKSkKCX0KCglpZiBlcnIgOj0gcy5zdG9yZS5SZW1vdmVBbGxvd2VkVG9rZW4oMCwgcmxtLCB0b2tlblBhdGgpOyBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIuRXJyb3IoKSkKCX0KCgljaGFpbi5FbWl0KAoJCSJSZW1vdmVUb2tlbiIsCgkJInByZXZBZGRyIiwgY2FsbGVyLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2aW91c1JlYWxtLlBrZ1BhdGgoKSwKCQkidG9rZW5QYXRoIiwgdG9rZW5QYXRoLAoJKQp9CgpmdW5jIGNoZWNrQ2Fubm90QWRkRGVmYXVsdFRva2VuKHRva2VuUGF0aCBzdHJpbmcpIGVycm9yIHsKCWlmIGNvbnRhaW5zKHNyLkRlZmF1bHRBbGxvd2VkVG9rZW5zKCksIHRva2VuUGF0aCkgewoJCXJldHVybiB1Zm10LkVycm9yZigiJXY6IGNhbm5vdCBhZGQgZXhpc3RpbmcgdG9rZW4oJXMpIiwgZXJyQWRkRXhpc3RpbmdUb2tlbiwgdG9rZW5QYXRoKQoJfQoKCXJldHVybiBuaWwKfQoKZnVuYyBjaGVja0Nhbm5vdFJlbW92ZURlZmF1bHRUb2tlbih0b2tlblBhdGggc3RyaW5nKSBlcnJvciB7CglpZiBjb250YWlucyhzci5EZWZhdWx0QWxsb3dlZFRva2VucygpLCB0b2tlblBhdGgpIHsKCQlyZXR1cm4gdWZtdC5FcnJvcmYoIiV2OiBjYW5ub3QgcmVtb3ZlIGRlZmF1bHQgdG9rZW4oJXMpIiwgZXJyRGVmYXVsdEV4dGVybmFsVG9rZW4sIHRva2VuUGF0aCkKCX0KCglyZXR1cm4gbmlsCn0KCi8vIFNldERlbmllZFJld2FyZFRva2VuIHNldHMgb3IgY2xlYXJzIHRoZSBvcGVyYXRpb25hbCBkZW55IGZsYWcgZm9yIGFuIGV4dGVybmFsCi8vIGluY2VudGl2ZSByZXdhcmQgdG9rZW4uCi8vCi8vIFBvb2wtcGFpciB0b2tlbnMgcXVhbGlmeSBhcyByZXdhcmQgdG9rZW5zIGZvciB0aGVpciBvd24gcG9vbCB3aXRob3V0IHRoZQovLyBnb3Zlcm5hbmNlIGFsbG93bGlzdCAoYSBwcm9kdWN0IHBvbGljeSksIHNvIHRoZSBkZW55IGZsYWcgaXMgdGhlIG9ubHkgbGV2ZXIKLy8gdG8gc3RvcCBORVcgaW5jZW50aXZlcyBpbiBhIHBhaXIgdG9rZW4gd2hvc2UgaXNzdWVyIHR1cm5lZCBob3N0aWxlLiBUaGUgZmxhZwovLyBpcyBjaGVja2VkIGF0IGluY2VudGl2ZSBjcmVhdGlvbiBvbmx5OiBjb2xsZWN0aW9uIG9mIGFscmVhZHktY3JlYXRlZAovLyBpbmNlbnRpdmVzIGlzIGRlbGliZXJhdGVseSB1bmFmZmVjdGVkLCBiZWNhdXNlIHRoZSBsZWRnZXItbGV2ZWwgZGVsaXZlcnkKLy8gZ3VhcmQgaW4gZGVsaXZlckV4dGVybmFsSW5jZW50aXZlUmV3YXJkIGFscmVhZHkgYm91bmRzIHRoZWlyIGJsYXN0IHJhZGl1cyB0bwovLyB0aGUgaG9zdGlsZSB0b2tlbiBpdHNlbGYuCi8vCi8vIERlZmF1bHQgcHJvdG9jb2wgdG9rZW5zIChHTlMsIFdVR05PVCkgY2Fubm90IGJlIGRlbmllZC4KLy8KLy8gT25seSB0aGUgYWRtaW4gb3IgZ292ZXJuYW5jZSBjYW4gc2V0IHRoZSBmbGFnLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTGVhZGluZyByZWFsbS1jYWxsIGRpc2NyaW1pbmF0b3I7IGNhbGxlcnMgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHN0YWtlciByZWFsbSBjb250ZXh0LCB2YWxpZGF0ZWQgYmVmb3JlIHRoZSBkZW55IGxpc3QgaXMgY2hhbmdlZC4KLy8gICAtIHRva2VuUGF0aDogUmV3YXJkLXRva2VuIHBhdGggd2hvc2UgZGVuaWVkIHN0YXR1cyBpcyBiZWluZyBjaGFuZ2VkLgovLyAgIC0gZGVuaWVkOiBUcnVlIHRvIGFkZCB0b2tlblBhdGggdG8gdGhlIGRlbnkgbGlzdCwgZmFsc2UgdG8gcmVtb3ZlIGl0LgpmdW5jIChzICpzdGFrZXJWMSkgU2V0RGVuaWVkUmV3YXJkVG9rZW4oXyBpbnQsIHJsbSByZWFsbSwgdG9rZW5QYXRoIHN0cmluZywgZGVuaWVkIGJvb2wpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRTdGFrZXIoKQoKCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzQWRtaW5PckdvdmVybmFuY2UoY2FsbGVyKQoKCWlmIGRlbmllZCB7CgkJaWYgZXJyIDo9IGNoZWNrQ2Fubm90RGVueURlZmF1bHRUb2tlbih0b2tlblBhdGgpOyBlcnIgIT0gbmlsIHsKCQkJcGFuaWMoZXJyLkVycm9yKCkpCgkJfQoKCQlpZiBlcnIgOj0gcy5zdG9yZS5BZGREZW5pZWRSZXdhcmRUb2tlbigwLCBybG0sIHRva2VuUGF0aCk7IGVyciAhPSBuaWwgewoJCQlwYW5pYyhlcnIuRXJyb3IoKSkKCQl9Cgl9IGVsc2UgewoJCWlmIGVyciA6PSBzLnN0b3JlLlJlbW92ZURlbmllZFJld2FyZFRva2VuKDAsIHJsbSwgdG9rZW5QYXRoKTsgZXJyICE9IG5pbCB7CgkJCXBhbmljKGVyci5FcnJvcigpKQoJCX0KCX0KCglkZW5pZWRTdHIgOj0gImZhbHNlIgoJaWYgZGVuaWVkIHsKCQlkZW5pZWRTdHIgPSAidHJ1ZSIKCX0KCgljaGFpbi5FbWl0KAoJCSJTZXREZW5pZWRSZXdhcmRUb2tlbiIsCgkJInByZXZBZGRyIiwgY2FsbGVyLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2aW91c1JlYWxtLlBrZ1BhdGgoKSwKCQkidG9rZW5QYXRoIiwgdG9rZW5QYXRoLAoJCSJkZW5pZWQiLCBkZW5pZWRTdHIsCgkpCn0KCmZ1bmMgY2hlY2tDYW5ub3REZW55RGVmYXVsdFRva2VuKHRva2VuUGF0aCBzdHJpbmcpIGVycm9yIHsKCWlmIGNvbnRhaW5zKHNyLkRlZmF1bHRBbGxvd2VkVG9rZW5zKCksIHRva2VuUGF0aCkgewoJCXJldHVybiB1Zm10LkVycm9yZigiJXY6IGNhbm5vdCBkZW55IGRlZmF1bHQgdG9rZW4oJXMpIiwgZXJyQ2Fubm90RGVueURlZmF1bHRUb2tlbiwgdG9rZW5QYXRoKQoJfQoKCXJldHVybiBuaWwKfQoauIICCgpnZXR0ZXIuZ25vEqiCAnBhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJImNoYWluL3J1bnRpbWUiCgkiZXJyb3JzIgoJInRpbWUiCgoJcm90cmVlICJnbm8ubGFuZC9wL250L2JwdHJlZS9yb3RyZWUvdjAiCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgoJdTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL3VpbnQyNTYvdjEiCgoJc3IgImduby5sYW5kL3IvZ25vc3dhcC9zdGFrZXIiCikKCi8vIGZpbmRQb29sQnlQb29sUGF0aCByZXRyaWV2ZXMgdGhlIHBvb2wgYnkgaXRzIHBhdGgsIG9yIG5pbCB3aGVuIGl0IGRvZXMgbm90Ci8vIGV4aXN0LiBSZWFkLW9ubHkgdmlld3MgdXNlIGl0IHNvIGEgbWlzc2luZyBwb29sIHJlYWRzIGFzIG5pbCByYXRoZXIgdGhhbgovLyBhYm9ydGluZyB0aGUgY2FsbGVyJ3MgdHJhbnNhY3Rpb24uCmZ1bmMgKHMgKnN0YWtlclYxKSBmaW5kUG9vbEJ5UG9vbFBhdGgocG9vbFBhdGggc3RyaW5nKSAqc3IuUG9vbCB7CglyZXN1bHQgOj0gcy5zdG9yZS5HZXRQb29scygpLkdldChwb29sUGF0aCkKCWlmIHJlc3VsdCA9PSBuaWwgewoJCXJldHVybiBuaWwKCX0KCglwb29sLCBvayA6PSByZXN1bHQuKCpzci5Qb29sKQoJaWYgIW9rIHsKCQlyZXR1cm4gbmlsCgl9CgoJcmV0dXJuIHBvb2wKfQoKLy8gZ2V0UG9vbEJ5UG9vbFBhdGggcmV0cmlldmVzIHRoZSBwb29sIGJ5IGl0cyBwYXRoLgpmdW5jIChzICpzdGFrZXJWMSkgZ2V0UG9vbEJ5UG9vbFBhdGgocG9vbFBhdGggc3RyaW5nKSAoKnNyLlBvb2wsIGVycm9yKSB7CglyZXN1bHQgOj0gcy5zdG9yZS5HZXRQb29scygpLkdldChwb29sUGF0aCkKCWlmIHJlc3VsdCA9PSBuaWwgewoJCXJldHVybiBuaWwsIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJEYXRhTm90Rm91bmQsCgkJCXVmbXQuU3ByaW50ZigicG9vbFBhdGgoJXMpIHBvb2wgZG9lcyBub3QgZXhpc3QiLCBwb29sUGF0aCksCgkJKQoJfQoKCXBvb2wsIG9rIDo9IHJlc3VsdC4oKnNyLlBvb2wpCglpZiAhb2sgewoJCXJldHVybiBuaWwsIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJEYXRhTm90Rm91bmQsCgkJCXVmbXQuU3ByaW50ZigicG9vbFBhdGgoJXMpIHBvb2wgZG9lcyBub3QgZXhpc3QiLCBwb29sUGF0aCksCgkJKQoJfQoKCXJldHVybiBwb29sLCBuaWwKfQoKLy8gR2V0UG9vbCByZXR1cm5zIHRoZSBwb29sIGZvciB0aGUgZ2l2ZW4gcGF0aC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBQb29sIHBhdGggd2hvc2UgcG9vbCBlbnRyeSBpcyBxdWVyaWVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gKnNyLlBvb2w6IFBvb2wgcmVnaXN0ZXJlZCBhdCBwb29sUGF0aCwgb3IgbmlsIHdoZW4gdGhlIGxvb2t1cCBmYWlscy4KLy8gICAtIGVycm9yOiBOb24tbmlsIHdoZW4gcG9vbFBhdGggaGFzIG5vIHZhbGlkIHBvb2wgZW50cnk7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0UG9vbChwb29sUGF0aCBzdHJpbmcpICgqc3IuUG9vbCwgZXJyb3IpIHsKCXBvb2wsIGVyciA6PSBzLmdldFBvb2xCeVBvb2xQYXRoKHBvb2xQYXRoKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIG5pbCwgZXJyCgl9CglyZXR1cm4gcG9vbCwgbmlsCn0KCi8vIGdldEluY2VudGl2ZSByZXRyaWV2ZXMgYW4gZXh0ZXJuYWwgaW5jZW50aXZlIGJ5IElELgpmdW5jIChzICpzdGFrZXJWMSkgZ2V0SW5jZW50aXZlKHBvb2xQYXRoIHN0cmluZywgaW5jZW50aXZlSWQgc3RyaW5nKSAoKnNyLkV4dGVybmFsSW5jZW50aXZlLCBlcnJvcikgewoJcG9vbCwgZXJyIDo9IHMuZ2V0UG9vbEJ5UG9vbFBhdGgocG9vbFBhdGgpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBlcnIKCX0KCglpbmNlbnRpdmVzIDo9IHBvb2wuSW5jZW50aXZlcygpCglpbmNlbnRpdmUgOj0gaW5jZW50aXZlcy5JbmNlbnRpdmVUcmVlcygpLkdldChpbmNlbnRpdmVJZCkKCWlmIGluY2VudGl2ZSA9PSBuaWwgewoJCXJldHVybiBuaWwsIHVmbXQuRXJyb3JmKCJpbmNlbnRpdmVJZCglcykgaW5jZW50aXZlIGRvZXMgbm90IGV4aXN0IiwgaW5jZW50aXZlSWQpCgl9CgoJaWN0diwgb2sgOj0gaW5jZW50aXZlLigqc3IuRXh0ZXJuYWxJbmNlbnRpdmUpCglpZiAhb2sgewoJCXJldHVybiBuaWwsIHVmbXQuRXJyb3JmKCJmYWlsZWQgdG8gY2FzdCBpbmNlbnRpdmUgdG8gKkV4dGVybmFsSW5jZW50aXZlOiAlVCIsIGluY2VudGl2ZSkKCX0KCXJldHVybiBpY3R2LCBuaWwKfQoKLy8gR2V0SW5jZW50aXZlU3RhcnRUaW1lc3RhbXAgcmV0dXJucyB0aGUgc3RhcnQgdGltZXN0YW1wIG9mIGFuIGluY2VudGl2ZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBQb29sIHBhdGggY29udGFpbmluZyB0aGUgaW5jZW50aXZlLgovLyAgIC0gaW5jZW50aXZlSWQ6IEV4dGVybmFsIGluY2VudGl2ZSBpZGVudGlmaWVyIHdob3NlIHN0YXJ0IHRpbWUgaXMgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBJbmNlbnRpdmUgc3RhcnQgdGltZXN0YW1wIGluIFVuaXggc2Vjb25kcy4KLy8gICAtIGVycm9yOiBOb24tbmlsIHdoZW4gcG9vbFBhdGggb3IgaW5jZW50aXZlSWQgY2Fubm90IGJlIHJlc29sdmVkOyBuaWwgb24gc3VjY2Vzcy4KZnVuYyAocyAqc3Rha2VyVjEpIEdldEluY2VudGl2ZVN0YXJ0VGltZXN0YW1wKHBvb2xQYXRoIHN0cmluZywgaW5jZW50aXZlSWQgc3RyaW5nKSAoaW50NjQsIGVycm9yKSB7CglpbmNlbnRpdmUsIGVyciA6PSBzLmdldEluY2VudGl2ZShwb29sUGF0aCwgaW5jZW50aXZlSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CgoJcmV0dXJuIGluY2VudGl2ZS5TdGFydFRpbWVzdGFtcCgpLCBuaWwKfQoKLy8gR2V0SW5jZW50aXZlRW5kVGltZXN0YW1wIHJldHVybnMgdGhlIGVuZCB0aW1lc3RhbXAgb2YgYW4gaW5jZW50aXZlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IFBvb2wgcGF0aCBjb250YWluaW5nIHRoZSBpbmNlbnRpdmUuCi8vICAgLSBpbmNlbnRpdmVJZDogRXh0ZXJuYWwgaW5jZW50aXZlIGlkZW50aWZpZXIgd2hvc2UgZW5kIHRpbWUgaXMgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBJbmNlbnRpdmUgZW5kIHRpbWVzdGFtcCBpbiBVbml4IHNlY29uZHMuCi8vICAgLSBlcnJvcjogTm9uLW5pbCB3aGVuIHBvb2xQYXRoIG9yIGluY2VudGl2ZUlkIGNhbm5vdCBiZSByZXNvbHZlZDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXRJbmNlbnRpdmVFbmRUaW1lc3RhbXAocG9vbFBhdGggc3RyaW5nLCBpbmNlbnRpdmVJZCBzdHJpbmcpIChpbnQ2NCwgZXJyb3IpIHsKCWluY2VudGl2ZSwgZXJyIDo9IHMuZ2V0SW5jZW50aXZlKHBvb2xQYXRoLCBpbmNlbnRpdmVJZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCglyZXR1cm4gaW5jZW50aXZlLkVuZFRpbWVzdGFtcCgpLCBuaWwKfQoKLy8gR2V0VGFyZ2V0UG9vbFBhdGhCeUluY2VudGl2ZUlkIHJldHVybnMgdGhlIHRhcmdldCBwb29sIHBhdGggb2YgYW4gaW5jZW50aXZlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IFBvb2wgcGF0aCBjb250YWluaW5nIHRoZSBpbmNlbnRpdmUuCi8vICAgLSBpbmNlbnRpdmVJZDogRXh0ZXJuYWwgaW5jZW50aXZlIGlkZW50aWZpZXIgd2hvc2UgdGFyZ2V0IHBvb2wgaXMgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHN0cmluZzogUG9vbCBwYXRoIHRhcmdldGVkIGJ5IHRoZSBpbmNlbnRpdmUuCi8vICAgLSBlcnJvcjogTm9uLW5pbCB3aGVuIHBvb2xQYXRoIG9yIGluY2VudGl2ZUlkIGNhbm5vdCBiZSByZXNvbHZlZDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXRUYXJnZXRQb29sUGF0aEJ5SW5jZW50aXZlSWQocG9vbFBhdGggc3RyaW5nLCBpbmNlbnRpdmVJZCBzdHJpbmcpIChzdHJpbmcsIGVycm9yKSB7CglpbmNlbnRpdmUsIGVyciA6PSBzLmdldEluY2VudGl2ZShwb29sUGF0aCwgaW5jZW50aXZlSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsIGVycgoJfQoKCXJldHVybiBpbmNlbnRpdmUuVGFyZ2V0UG9vbFBhdGgoKSwgbmlsCn0KCi8vIEdldENyZWF0ZWRIZWlnaHRPZkluY2VudGl2ZSByZXR1cm5zIHRoZSBjcmVhdGlvbiBoZWlnaHQgb2YgYW4gaW5jZW50aXZlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IFBvb2wgcGF0aCBjb250YWluaW5nIHRoZSBpbmNlbnRpdmUuCi8vICAgLSBpbmNlbnRpdmVJZDogRXh0ZXJuYWwgaW5jZW50aXZlIGlkZW50aWZpZXIgd2hvc2UgY3JlYXRpb24gaGVpZ2h0IGlzIHF1ZXJpZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogQ2hhaW4gaGVpZ2h0IGF0IHdoaWNoIHRoZSBpbmNlbnRpdmUgd2FzIGNyZWF0ZWQuCi8vICAgLSBlcnJvcjogTm9uLW5pbCB3aGVuIHBvb2xQYXRoIG9yIGluY2VudGl2ZUlkIGNhbm5vdCBiZSByZXNvbHZlZDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXRDcmVhdGVkSGVpZ2h0T2ZJbmNlbnRpdmUocG9vbFBhdGggc3RyaW5nLCBpbmNlbnRpdmVJZCBzdHJpbmcpIChpbnQ2NCwgZXJyb3IpIHsKCWluY2VudGl2ZSwgZXJyIDo9IHMuZ2V0SW5jZW50aXZlKHBvb2xQYXRoLCBpbmNlbnRpdmVJZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCglyZXR1cm4gaW5jZW50aXZlLkNyZWF0ZWRIZWlnaHQoKSwgbmlsCn0KCi8vIEdldEluY2VudGl2ZUNyZWF0ZWRUaW1lc3RhbXAgcmV0dXJucyB0aGUgY3JlYXRpb24gdGltZXN0YW1wIG9mIGFuIGluY2VudGl2ZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBQb29sIHBhdGggY29udGFpbmluZyB0aGUgaW5jZW50aXZlLgovLyAgIC0gaW5jZW50aXZlSWQ6IEV4dGVybmFsIGluY2VudGl2ZSBpZGVudGlmaWVyIHdob3NlIGNyZWF0aW9uIHRpbWUgaXMgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBJbmNlbnRpdmUgY3JlYXRpb24gdGltZXN0YW1wIGluIFVuaXggc2Vjb25kcy4KLy8gICAtIGVycm9yOiBOb24tbmlsIHdoZW4gcG9vbFBhdGggb3IgaW5jZW50aXZlSWQgY2Fubm90IGJlIHJlc29sdmVkOyBuaWwgb24gc3VjY2Vzcy4KZnVuYyAocyAqc3Rha2VyVjEpIEdldEluY2VudGl2ZUNyZWF0ZWRUaW1lc3RhbXAocG9vbFBhdGggc3RyaW5nLCBpbmNlbnRpdmVJZCBzdHJpbmcpIChpbnQ2NCwgZXJyb3IpIHsKCWluY2VudGl2ZSwgZXJyIDo9IHMuZ2V0SW5jZW50aXZlKHBvb2xQYXRoLCBpbmNlbnRpdmVJZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCglyZXR1cm4gaW5jZW50aXZlLkNyZWF0ZWRUaW1lc3RhbXAoKSwgbmlsCn0KCi8vIEdldEluY2VudGl2ZVRvdGFsUmV3YXJkQW1vdW50IHJldHVybnMgdGhlIHRvdGFsIHJld2FyZCBhbW91bnQgb2YgYW4gaW5jZW50aXZlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IFBvb2wgcGF0aCBjb250YWluaW5nIHRoZSBpbmNlbnRpdmUuCi8vICAgLSBpbmNlbnRpdmVJZDogRXh0ZXJuYWwgaW5jZW50aXZlIGlkZW50aWZpZXIgd2hvc2UgY29uZmlndXJlZCByZXdhcmQgaXMgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBUb3RhbCByZXdhcmQgYW1vdW50IGNvbmZpZ3VyZWQgZm9yIHRoZSBpbmNlbnRpdmUsIGluIHJld2FyZC10b2tlbiB1bml0cy4KLy8gICAtIGVycm9yOiBOb24tbmlsIHdoZW4gcG9vbFBhdGggb3IgaW5jZW50aXZlSWQgY2Fubm90IGJlIHJlc29sdmVkOyBuaWwgb24gc3VjY2Vzcy4KZnVuYyAocyAqc3Rha2VyVjEpIEdldEluY2VudGl2ZVRvdGFsUmV3YXJkQW1vdW50KHBvb2xQYXRoIHN0cmluZywgaW5jZW50aXZlSWQgc3RyaW5nKSAoaW50NjQsIGVycm9yKSB7CglpbmNlbnRpdmUsIGVyciA6PSBzLmdldEluY2VudGl2ZShwb29sUGF0aCwgaW5jZW50aXZlSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CgoJcmV0dXJuIGluY2VudGl2ZS5Ub3RhbFJld2FyZEFtb3VudCgpLCBuaWwKfQoKLy8gR2V0SW5jZW50aXZlRGlzdHJpYnV0ZWRSZXdhcmRBbW91bnQgcmV0dXJucyB0aGUgZGlzdHJpYnV0ZWQgcmV3YXJkIGFtb3VudCBvZiBhbiBpbmNlbnRpdmUuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogUG9vbCBwYXRoIGNvbnRhaW5pbmcgdGhlIGluY2VudGl2ZS4KLy8gICAtIGluY2VudGl2ZUlkOiBFeHRlcm5hbCBpbmNlbnRpdmUgaWRlbnRpZmllciB3aG9zZSBkaXN0cmlidXRpb24gdG90YWwgaXMgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBSZXdhcmQgYW1vdW50IGFscmVhZHkgZGlzdHJpYnV0ZWQgYnkgdGhlIGluY2VudGl2ZSwgaW4gcmV3YXJkLXRva2VuIHVuaXRzLgovLyAgIC0gZXJyb3I6IE5vbi1uaWwgd2hlbiBwb29sUGF0aCBvciBpbmNlbnRpdmVJZCBjYW5ub3QgYmUgcmVzb2x2ZWQ7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0SW5jZW50aXZlRGlzdHJpYnV0ZWRSZXdhcmRBbW91bnQocG9vbFBhdGggc3RyaW5nLCBpbmNlbnRpdmVJZCBzdHJpbmcpIChpbnQ2NCwgZXJyb3IpIHsKCWluY2VudGl2ZSwgZXJyIDo9IHMuZ2V0SW5jZW50aXZlKHBvb2xQYXRoLCBpbmNlbnRpdmVJZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCglyZXR1cm4gaW5jZW50aXZlLkRpc3RyaWJ1dGVkUmV3YXJkQW1vdW50KCksIG5pbAp9CgovLyBHZXRJbmNlbnRpdmVSZW1haW5pbmdSZXdhcmRBbW91bnQgcmV0dXJucyB0aGUgcmVtYWluaW5nIHJld2FyZCBhbW91bnQgb2YgYW4gaW5jZW50aXZlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IFBvb2wgcGF0aCBjb250YWluaW5nIHRoZSBpbmNlbnRpdmUuCi8vICAgLSBpbmNlbnRpdmVJZDogRXh0ZXJuYWwgaW5jZW50aXZlIGlkZW50aWZpZXIgd2hvc2UgcmVtYWluaW5nIGJhbGFuY2UgaXMgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBSZXdhcmQgYW1vdW50IHN0aWxsIGF2YWlsYWJsZSBmb3IgY29sbGVjdGlvbiwgaW4gcmV3YXJkLXRva2VuIHVuaXRzLgovLyAgIC0gZXJyb3I6IE5vbi1uaWwgd2hlbiBwb29sUGF0aCBvciBpbmNlbnRpdmVJZCBjYW5ub3QgYmUgcmVzb2x2ZWQ7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0SW5jZW50aXZlUmVtYWluaW5nUmV3YXJkQW1vdW50KHBvb2xQYXRoIHN0cmluZywgaW5jZW50aXZlSWQgc3RyaW5nKSAoaW50NjQsIGVycm9yKSB7CglpbmNlbnRpdmUsIGVyciA6PSBzLmdldEluY2VudGl2ZShwb29sUGF0aCwgaW5jZW50aXZlSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CgoJcmV0dXJuIGluY2VudGl2ZS5SZXdhcmRBbW91bnQoKSwgbmlsCn0KCi8vIEdldEluY2VudGl2ZUFjY3VtdWxhdGVkUGVuYWx0eUFtb3VudCByZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB3YXJtdXAgcGVuYWx0eSBhbW91bnQgb2YgYW4gaW5jZW50aXZlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IFBvb2wgcGF0aCBjb250YWluaW5nIHRoZSBpbmNlbnRpdmUuCi8vICAgLSBpbmNlbnRpdmVJZDogRXh0ZXJuYWwgaW5jZW50aXZlIGlkZW50aWZpZXIgd2hvc2UgcGVuYWx0aWVzIGFyZSBxdWVyaWVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IFdhcm0tdXAgcGVuYWx0eSBhY2N1bXVsYXRlZCBmb3IgdGhlIGluY2VudGl2ZSwgaW4gcmV3YXJkLXRva2VuIHVuaXRzLgovLyAgIC0gZXJyb3I6IE5vbi1uaWwgd2hlbiBwb29sUGF0aCBvciBpbmNlbnRpdmVJZCBjYW5ub3QgYmUgcmVzb2x2ZWQ7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0SW5jZW50aXZlQWNjdW11bGF0ZWRQZW5hbHR5QW1vdW50KHBvb2xQYXRoIHN0cmluZywgaW5jZW50aXZlSWQgc3RyaW5nKSAoaW50NjQsIGVycm9yKSB7CglpbmNlbnRpdmUsIGVyciA6PSBzLmdldEluY2VudGl2ZShwb29sUGF0aCwgaW5jZW50aXZlSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CgoJcmV0dXJuIGluY2VudGl2ZS5BY2N1bXVsYXRlZFBlbmFsdHlBbW91bnQoKSwgbmlsCn0KCi8vIEdldEluY2VudGl2ZURlcG9zaXRHbnNBbW91bnQgcmV0dXJucyB0aGUgZGVwb3NpdCBHTlMgYW1vdW50IG9mIGFuIGluY2VudGl2ZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBQb29sIHBhdGggY29udGFpbmluZyB0aGUgaW5jZW50aXZlLgovLyAgIC0gaW5jZW50aXZlSWQ6IEV4dGVybmFsIGluY2VudGl2ZSBpZGVudGlmaWVyIHdob3NlIEdOUyBkZXBvc2l0IGlzIHF1ZXJpZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogR05TIGFtb3VudCBkZXBvc2l0ZWQgd2hlbiB0aGUgaW5jZW50aXZlIHdhcyBjcmVhdGVkLgovLyAgIC0gZXJyb3I6IE5vbi1uaWwgd2hlbiBwb29sUGF0aCBvciBpbmNlbnRpdmVJZCBjYW5ub3QgYmUgcmVzb2x2ZWQ7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0SW5jZW50aXZlRGVwb3NpdEduc0Ftb3VudChwb29sUGF0aCBzdHJpbmcsIGluY2VudGl2ZUlkIHN0cmluZykgKGludDY0LCBlcnJvcikgewoJaW5jZW50aXZlLCBlcnIgOj0gcy5nZXRJbmNlbnRpdmUocG9vbFBhdGgsIGluY2VudGl2ZUlkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoKCXJldHVybiBpbmNlbnRpdmUuRGVwb3NpdEduc0Ftb3VudCgpLCBuaWwKfQoKLy8gR2V0SW5jZW50aXZlUmVmdW5kZWQgcmV0dXJucyB3aGV0aGVyIGFuIGluY2VudGl2ZSBoYXMgYmVlbiByZWZ1bmRlZC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBQb29sIHBhdGggY29udGFpbmluZyB0aGUgaW5jZW50aXZlLgovLyAgIC0gaW5jZW50aXZlSWQ6IEV4dGVybmFsIGluY2VudGl2ZSBpZGVudGlmaWVyIHdob3NlIHJlZnVuZCBzdGF0ZSBpcyBxdWVyaWVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gYm9vbDogdHJ1ZSB3aGVuIHRoZSBpbmNlbnRpdmUgaGFzIGJlZW4gZmluYWxpemVkL3JlZnVuZGVkOyBmYWxzZSB3aGlsZSBpdCByZW1haW5zIHVucmVmdW5kZWQuCi8vICAgLSBlcnJvcjogTm9uLW5pbCB3aGVuIHBvb2xQYXRoIG9yIGluY2VudGl2ZUlkIGNhbm5vdCBiZSByZXNvbHZlZDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXRJbmNlbnRpdmVSZWZ1bmRlZChwb29sUGF0aCBzdHJpbmcsIGluY2VudGl2ZUlkIHN0cmluZykgKGJvb2wsIGVycm9yKSB7CglpbmNlbnRpdmUsIGVyciA6PSBzLmdldEluY2VudGl2ZShwb29sUGF0aCwgaW5jZW50aXZlSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gZmFsc2UsIGVycgoJfQoKCXJldHVybiBpbmNlbnRpdmUuUmVmdW5kZWQoKSwgbmlsCn0KCi8vIElzSW5jZW50aXZlQWN0aXZlIHJlcG9ydHMgd2hldGhlciBhbiB1bnJlZnVuZGVkIGluY2VudGl2ZSBpcyBhY3RpdmUsIGluY2x1ZGluZyBib3RoIHN0YXJ0IGFuZCBlbmQgdGltZXN0YW1wcy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBQb29sIHBhdGggY29udGFpbmluZyB0aGUgaW5jZW50aXZlLgovLyAgIC0gaW5jZW50aXZlSWQ6IEV4dGVybmFsIGluY2VudGl2ZSBpZGVudGlmaWVyIHdob3NlIGFjdGl2aXR5IGlzIHF1ZXJpZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBib29sOiB0cnVlIHdoZW4gdGhlIGN1cnJlbnQgVW5peCB0aW1lIGlzIHdpdGhpbiB0aGUgaW5jZW50aXZlJ3Mgc3RhcnQvZW5kIHdpbmRvdyBhbmQgaXQgaXMgdW5yZWZ1bmRlZDsgZmFsc2Ugb3RoZXJ3aXNlLgovLyAgIC0gZXJyb3I6IE5vbi1uaWwgd2hlbiBwb29sUGF0aCBvciBpbmNlbnRpdmVJZCBjYW5ub3QgYmUgcmVzb2x2ZWQ7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgSXNJbmNlbnRpdmVBY3RpdmUocG9vbFBhdGggc3RyaW5nLCBpbmNlbnRpdmVJZCBzdHJpbmcpIChib29sLCBlcnJvcikgewoJaW5jZW50aXZlLCBlcnIgOj0gcy5nZXRJbmNlbnRpdmUocG9vbFBhdGgsIGluY2VudGl2ZUlkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGZhbHNlLCBlcnIKCX0KCWN1cnJlbnRUaW1lIDo9IHRpbWUuTm93KCkuVW5peCgpCgoJcmVzb2x2ZXIgOj0gTmV3RXh0ZXJuYWxJbmNlbnRpdmVSZXNvbHZlcihpbmNlbnRpdmUpCglyZXR1cm4gcmVzb2x2ZXIuaXNBY3RpdmUoY3VycmVudFRpbWUpICYmICFyZXNvbHZlci5SZWZ1bmRlZCgpLCBuaWwKfQoKLy8gR2V0SW5jZW50aXZlUmV3YXJkVG9rZW4gcmV0dXJucyB0aGUgcmV3YXJkIHRva2VuIG9mIGFuIGluY2VudGl2ZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBQb29sIHBhdGggY29udGFpbmluZyB0aGUgaW5jZW50aXZlLgovLyAgIC0gaW5jZW50aXZlSWQ6IEV4dGVybmFsIGluY2VudGl2ZSBpZGVudGlmaWVyIHdob3NlIHJld2FyZCB0b2tlbiBpcyBxdWVyaWVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gc3RyaW5nOiBSZXdhcmQtdG9rZW4gcGFja2FnZSBwYXRoIGNvbmZpZ3VyZWQgZm9yIHRoZSBpbmNlbnRpdmUuCi8vICAgLSBlcnJvcjogTm9uLW5pbCB3aGVuIHBvb2xQYXRoIG9yIGluY2VudGl2ZUlkIGNhbm5vdCBiZSByZXNvbHZlZDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXRJbmNlbnRpdmVSZXdhcmRUb2tlbihwb29sUGF0aCBzdHJpbmcsIGluY2VudGl2ZUlkIHN0cmluZykgKHN0cmluZywgZXJyb3IpIHsKCWluY2VudGl2ZSwgZXJyIDo9IHMuZ2V0SW5jZW50aXZlKHBvb2xQYXRoLCBpbmNlbnRpdmVJZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgZXJyCgl9CgoJcmV0dXJuIGluY2VudGl2ZS5SZXdhcmRUb2tlbigpLCBuaWwKfQoKLy8gR2V0SW5jZW50aXZlUmV3YXJkQW1vdW50IHJldHVybnMgdGhlIHJlbWFpbmluZyByZXdhcmQgYW1vdW50IG9mIGFuIGluY2VudGl2ZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBQb29sIHBhdGggY29udGFpbmluZyB0aGUgaW5jZW50aXZlLgovLyAgIC0gaW5jZW50aXZlSWQ6IEV4dGVybmFsIGluY2VudGl2ZSBpZGVudGlmaWVyIHdob3NlIHJlbWFpbmluZyByZXdhcmQgaXMgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtICp1MjU2LlVpbnQ6IFJlbWFpbmluZyByZXdhcmQgYW1vdW50IGFzIGEgdWludDI1NiB2YWx1ZSwgb3IgbmlsIHdoZW4gbG9va3VwIGZhaWxzLgovLyAgIC0gZXJyb3I6IE5vbi1uaWwgd2hlbiBwb29sUGF0aCBvciBpbmNlbnRpdmVJZCBjYW5ub3QgYmUgcmVzb2x2ZWQ7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0SW5jZW50aXZlUmV3YXJkQW1vdW50KHBvb2xQYXRoIHN0cmluZywgaW5jZW50aXZlSWQgc3RyaW5nKSAoKnUyNTYuVWludCwgZXJyb3IpIHsKCWluY2VudGl2ZSwgZXJyIDo9IHMuZ2V0SW5jZW50aXZlKHBvb2xQYXRoLCBpbmNlbnRpdmVJZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBuaWwsIGVycgoJfQoKCXJldHVybiB1MjU2Lk5ld1VpbnRGcm9tSW50NjQoaW5jZW50aXZlLlJld2FyZEFtb3VudCgpKSwgbmlsCn0KCi8vIEdldEluY2VudGl2ZVJld2FyZEFtb3VudEFzU3RyaW5nIHJldHVybnMgdGhlIHJlbWFpbmluZyByZXdhcmQgYW1vdW50IG9mIGFuIGluY2VudGl2ZSBhcyBzdHJpbmcuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogUG9vbCBwYXRoIGNvbnRhaW5pbmcgdGhlIGluY2VudGl2ZS4KLy8gICAtIGluY2VudGl2ZUlkOiBFeHRlcm5hbCBpbmNlbnRpdmUgaWRlbnRpZmllciB3aG9zZSByZW1haW5pbmcgcmV3YXJkIGlzIGZvcm1hdHRlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHN0cmluZzogUmVtYWluaW5nIHJld2FyZCBhbW91bnQgZW5jb2RlZCBhcyBhIGRlY2ltYWwgc3RyaW5nLgovLyAgIC0gZXJyb3I6IE5vbi1uaWwgd2hlbiBwb29sUGF0aCBvciBpbmNlbnRpdmVJZCBjYW5ub3QgYmUgcmVzb2x2ZWQ7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0SW5jZW50aXZlUmV3YXJkQW1vdW50QXNTdHJpbmcocG9vbFBhdGggc3RyaW5nLCBpbmNlbnRpdmVJZCBzdHJpbmcpIChzdHJpbmcsIGVycm9yKSB7CglyZXdhcmRBbW91bnQsIGVyciA6PSBzLkdldEluY2VudGl2ZVJld2FyZEFtb3VudChwb29sUGF0aCwgaW5jZW50aXZlSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsIGVycgoJfQoKCXJldHVybiByZXdhcmRBbW91bnQuVG9TdHJpbmcoKSwgbmlsCn0KCi8vIEdldEluY2VudGl2ZVJld2FyZFBlclNlY29uZFgxMjggcmV0dXJucyB0aGUgUTEyOC1zY2FsZWQgcmV3YXJkIHBlciBzZWNvbmQgb2YKLy8gYW4gaW5jZW50aXZlIChpLmUuIGFjdHVhbCByYXRlID0gdmFsdWUgLyAyXjEyOCkuIFRoZSBRMTI4IGZvcm0gcHJlc2VydmVzCi8vIHN1Yi1zZWNvbmQgcHJlY2lzaW9uIHRoYXQgd291bGQgb3RoZXJ3aXNlIGJlIGxvc3QgdG8gaW50NjQgdHJ1bmNhdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBQb29sIHBhdGggY29udGFpbmluZyB0aGUgaW5jZW50aXZlLgovLyAgIC0gaW5jZW50aXZlSWQ6IEV4dGVybmFsIGluY2VudGl2ZSBpZGVudGlmaWVyIHdob3NlIHJld2FyZCByYXRlIGlzIHF1ZXJpZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqdTI1Ni5VaW50OiBRMTI4LXNjYWxlZCByZXdhcmQtcGVyLXNlY29uZCB2YWx1ZTsgZGl2aWRlIGJ5IDJeMTI4IGZvciB0aGUgdW5zY2FsZWQgcmF0ZS4KLy8gICAtIGVycm9yOiBOb24tbmlsIHdoZW4gcG9vbFBhdGggb3IgaW5jZW50aXZlSWQgY2Fubm90IGJlIHJlc29sdmVkOyBuaWwgb24gc3VjY2Vzcy4KZnVuYyAocyAqc3Rha2VyVjEpIEdldEluY2VudGl2ZVJld2FyZFBlclNlY29uZFgxMjgocG9vbFBhdGggc3RyaW5nLCBpbmNlbnRpdmVJZCBzdHJpbmcpICgqdTI1Ni5VaW50LCBlcnJvcikgewoJaW5jZW50aXZlLCBlcnIgOj0gcy5nZXRJbmNlbnRpdmUocG9vbFBhdGgsIGluY2VudGl2ZUlkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIG5pbCwgZXJyCgl9CgoJcmV0dXJuIGluY2VudGl2ZS5SZXdhcmRQZXJTZWNvbmRYMTI4KCksIG5pbAp9CgovLyBHZXRJbmNlbnRpdmVDcmVhdG9yIHJldHVybnMgdGhlIGNyZWF0b3IgYWRkcmVzcyBvZiBhbiBpbmNlbnRpdmUuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogUG9vbCBwYXRoIGNvbnRhaW5pbmcgdGhlIGluY2VudGl2ZS4KLy8gICAtIGluY2VudGl2ZUlkOiBFeHRlcm5hbCBpbmNlbnRpdmUgaWRlbnRpZmllciB3aG9zZSBjcmVhdG9yIGlzIHF1ZXJpZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBhZGRyZXNzOiBBZGRyZXNzIHRoYXQgY3JlYXRlZCB0aGUgaW5jZW50aXZlLgovLyAgIC0gZXJyb3I6IE5vbi1uaWwgd2hlbiBwb29sUGF0aCBvciBpbmNlbnRpdmVJZCBjYW5ub3QgYmUgcmVzb2x2ZWQ7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0SW5jZW50aXZlQ3JlYXRvcihwb29sUGF0aCBzdHJpbmcsIGluY2VudGl2ZUlkIHN0cmluZykgKGFkZHJlc3MsIGVycm9yKSB7CglpbmNlbnRpdmUsIGVyciA6PSBzLmdldEluY2VudGl2ZShwb29sUGF0aCwgaW5jZW50aXZlSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gYWRkcmVzcygiIiksIGVycgoJfQoKCXJldHVybiBpbmNlbnRpdmUuQ3JlYXRvcigpLCBuaWwKfQoKLy8gZ2V0RGVwb3NpdCByZXRyaWV2ZXMgYSBkZXBvc2l0IGJ5IExQIHRva2VuIElELgpmdW5jIChzICpzdGFrZXJWMSkgZ2V0RGVwb3NpdChscFRva2VuSWQgdWludDY0KSAoKnNyLkRlcG9zaXQsIGVycm9yKSB7CglkZXBvc2l0cyA6PSBzLmdldERlcG9zaXRzKCkKCWlmICFkZXBvc2l0cy5IYXMobHBUb2tlbklkKSB7CgkJcmV0dXJuIG5pbCwgbWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckRhdGFOb3RGb3VuZCwKCQkJdWZtdC5TcHJpbnRmKCJscFRva2VuSWQoJWQpIGRlcG9zaXQgZG9lcyBub3QgZXhpc3QiLCBscFRva2VuSWQpLAoJCSkKCX0KCglyZXR1cm4gZGVwb3NpdHMuZ2V0KGxwVG9rZW5JZCksIG5pbAp9CgovLyBhc3NlcnRJc0NvbGxlY3RhYmxlUG9zaXRpb24gZW5zdXJlcyB0aGUgcG9zaXRpb24gaXMgc3Rha2VkIG9yIGhvbGRzIGFuIGV4aXQgY2hlY2twb2ludC4KZnVuYyAocyAqc3Rha2VyVjEpIGFzc2VydElzQ29sbGVjdGFibGVQb3NpdGlvbihwb3NpdGlvbklkIHVpbnQ2NCkgZXJyb3IgewoJaWYgcy5nZXREZXBvc2l0cygpLkhhcyhwb3NpdGlvbklkKSB8fCBzLmdldFVuc3Rha2VkUG9zaXRpb25zKCkuSGFzKHBvc2l0aW9uSWQpIHsKCQlyZXR1cm4gbmlsCgl9CgoJcmV0dXJuIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCWVyckRhdGFOb3RGb3VuZCwKCQl1Zm10LlNwcmludGYoImxwVG9rZW5JZCglZCkgZGVwb3NpdCBkb2VzIG5vdCBleGlzdCIsIHBvc2l0aW9uSWQpLAoJKQp9CgovLyBHZXREZXBvc2l0IHJldHVybnMgdGhlIGRlcG9zaXQgZm9yIHRoZSBnaXZlbiBMUCB0b2tlbiBJRC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGxwVG9rZW5JZDogTFAgcG9zaXRpb24gTkZUIHRva2VuIElEIHdob3NlIGxpdmUgZGVwb3NpdCBpcyBxdWVyaWVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gKnNyLkRlcG9zaXQ6IFN0b3JlZCBsaXZlIGRlcG9zaXQsIG9yIG5pbCB3aGVuIGxvb2t1cCBmYWlscy4KLy8gICAtIGVycm9yOiBOb24tbmlsIGRhdGEtbm90LWZvdW5kIGVycm9yIHdoZW4gbHBUb2tlbklkIGlzIG5vdCBjdXJyZW50bHkgZGVwb3NpdGVkOyBuaWwgb24gc3VjY2Vzcy4KZnVuYyAocyAqc3Rha2VyVjEpIEdldERlcG9zaXQobHBUb2tlbklkIHVpbnQ2NCkgKCpzci5EZXBvc2l0LCBlcnJvcikgewoJcmV0dXJuIHMuZ2V0RGVwb3NpdChscFRva2VuSWQpCn0KCi8vIENvbGxlY3RhYmxlRW1pc3Npb25SZXdhcmQgcmV0dXJucyB0aGUgY2xhaW1hYmxlIGludGVybmFsIHJld2FyZCBhbW91bnQgZm9yIGEgcG9zaXRpb24uCi8vIGNhbGN1bGF0ZUNvbGxlY3RhYmxlUG9zaXRpb25SZXdhcmQgaXMgcmVhZC1vbmx5LCBzbyBxdWVyeWluZyBhIGNvbGxlY3RhYmxlIGFtb3VudCBuZXZlciBtdXRhdGVzIHN0YXRlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9zaXRpb25JZDogTFAgcG9zaXRpb24gTkZUIHRva2VuIElEIG9yIGV4aXQtY2hlY2twb2ludCBJRCB3aG9zZSBhY2NydWVkIEdOUyByZXdhcmQgaXMgZXN0aW1hdGVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IEN1cnJlbnRseSBjb2xsZWN0YWJsZSBHTlMgZW1pc3Npb24gYW1vdW50IGluIEdOUyB1bml0czsgemVybyBtYXkgYmUgYSB2YWxpZCBhY2NydWVkIGFtb3VudC4KLy8gICAtIGVycm9yOiBOb24tbmlsIHdoZW4gcG9zaXRpb25JZCBpcyBub3Qgc3Rha2VkL2NoZWNrZWQgb3V0IG9yIHJld2FyZCBjYWxjdWxhdGlvbiBmYWlsczsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBDb2xsZWN0YWJsZUVtaXNzaW9uUmV3YXJkKHBvc2l0aW9uSWQgdWludDY0KSAoaW50NjQsIGVycm9yKSB7CgljdXJyZW50VGltZSA6PSB0aW1lLk5vdygpLlVuaXgoKQoJY3VycmVudEhlaWdodCA6PSBydW50aW1lLkNoYWluSGVpZ2h0KCkKCWlmIGVyciA6PSBzLmFzc2VydElzQ29sbGVjdGFibGVQb3NpdGlvbihwb3NpdGlvbklkKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoJcmV3YXJkLCBlcnIgOj0gcy5jYWxjdWxhdGVDb2xsZWN0YWJsZVBvc2l0aW9uUmV3YXJkKGN1cnJlbnRIZWlnaHQsIGN1cnJlbnRUaW1lLCBwb3NpdGlvbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoJcmV0dXJuIHJld2FyZC5JbnRlcm5hbCwgbmlsCn0KCi8vIENvbGxlY3RhYmxlRXh0ZXJuYWxJbmNlbnRpdmVSZXdhcmQgcmV0dXJucyB0aGUgY2xhaW1hYmxlIGV4dGVybmFsIHJld2FyZCBhbW91bnQgZm9yIGFuIGluY2VudGl2ZS4KLy8gY2FsY3VsYXRlQ29sbGVjdGFibGVQb3NpdGlvblJld2FyZCBpcyByZWFkLW9ubHksIHNvIHF1ZXJ5aW5nIGEgY29sbGVjdGFibGUgYW1vdW50IG5ldmVyIG11dGF0ZXMgc3RhdGUuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb3NpdGlvbklkOiBMUCBwb3NpdGlvbiBORlQgdG9rZW4gSUQgb3IgZXhpdC1jaGVja3BvaW50IElEIHdob3NlIGV4dGVybmFsIHJld2FyZCBpcyBlc3RpbWF0ZWQuCi8vICAgLSBpbmNlbnRpdmVJZDogRXh0ZXJuYWwgaW5jZW50aXZlIGlkZW50aWZpZXIgdG8gaW5zcGVjdDsgYW4gYWJzZW50IHJld2FyZCBlbnRyeSB5aWVsZHMgemVybyB3aXRob3V0IGVycm9yLgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IEN1cnJlbnRseSBjb2xsZWN0YWJsZSByZXdhcmQgYW1vdW50IGZvciBpbmNlbnRpdmVJZCwgaW4gdGhhdCBpbmNlbnRpdmUncyB0b2tlbiB1bml0cy4KLy8gICAtIGVycm9yOiBOb24tbmlsIHdoZW4gcG9zaXRpb25JZCBpcyBub3Qgc3Rha2VkL2NoZWNrZWQgb3V0IG9yIHJld2FyZCBjYWxjdWxhdGlvbiBmYWlsczsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBDb2xsZWN0YWJsZUV4dGVybmFsSW5jZW50aXZlUmV3YXJkKHBvc2l0aW9uSWQgdWludDY0LCBpbmNlbnRpdmVJZCBzdHJpbmcpIChpbnQ2NCwgZXJyb3IpIHsKCWN1cnJlbnRUaW1lIDo9IHRpbWUuTm93KCkuVW5peCgpCgljdXJyZW50SGVpZ2h0IDo9IHJ1bnRpbWUuQ2hhaW5IZWlnaHQoKQoJaWYgZXJyIDo9IHMuYXNzZXJ0SXNDb2xsZWN0YWJsZVBvc2l0aW9uKHBvc2l0aW9uSWQpOyBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CglyZXdhcmQsIGVyciA6PSBzLmNhbGN1bGF0ZUNvbGxlY3RhYmxlUG9zaXRpb25SZXdhcmQoY3VycmVudEhlaWdodCwgY3VycmVudFRpbWUsIHBvc2l0aW9uSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CglhbW91bnQsIG9rIDo9IHJld2FyZC5FeHRlcm5hbFtpbmNlbnRpdmVJZF0KCWlmICFvayB7CgkJcmV0dXJuIDAsIG5pbAoJfQoJcmV0dXJuIGFtb3VudCwgbmlsCn0KCi8vIEdldERlcG9zaXRPd25lciByZXR1cm5zIHRoZSBvd25lciBvZiBhIGRlcG9zaXQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBscFRva2VuSWQ6IExQIHBvc2l0aW9uIE5GVCB0b2tlbiBJRCB3aG9zZSBvd25lciBpcyBxdWVyaWVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gYWRkcmVzczogQWRkcmVzcyByZWNvcmRlZCBhcyB0aGUgZGVwb3NpdCBvd25lci4KLy8gICAtIGVycm9yOiBOb24tbmlsIGRhdGEtbm90LWZvdW5kIGVycm9yIHdoZW4gbHBUb2tlbklkIGlzIG5vdCBjdXJyZW50bHkgZGVwb3NpdGVkOyBuaWwgb24gc3VjY2Vzcy4KZnVuYyAocyAqc3Rha2VyVjEpIEdldERlcG9zaXRPd25lcihscFRva2VuSWQgdWludDY0KSAoYWRkcmVzcywgZXJyb3IpIHsKCWRlcG9zaXQsIGVyciA6PSBzLmdldERlcG9zaXQobHBUb2tlbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGFkZHJlc3MoIiIpLCBlcnIKCX0KCglyZXR1cm4gZGVwb3NpdC5Pd25lcigpLCBuaWwKfQoKLy8gR2V0RGVwb3NpdFN0YWtlVGltZSByZXR1cm5zIHRoZSBVbml4IHRpbWVzdGFtcCBhdCB3aGljaCBhIHBvc2l0aW9uIHdhcyBzdGFrZWQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBscFRva2VuSWQ6IExQIHBvc2l0aW9uIE5GVCB0b2tlbiBJRCB3aG9zZSBzdGFrZSB0aW1lIGlzIHF1ZXJpZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogVW5peCB0aW1lc3RhbXAgYXQgd2hpY2ggdGhlIHBvc2l0aW9uIHdhcyBzdGFrZWQuCi8vICAgLSBlcnJvcjogTm9uLW5pbCBkYXRhLW5vdC1mb3VuZCBlcnJvciB3aGVuIGxwVG9rZW5JZCBpcyBub3QgY3VycmVudGx5IGRlcG9zaXRlZDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXREZXBvc2l0U3Rha2VUaW1lKGxwVG9rZW5JZCB1aW50NjQpIChpbnQ2NCwgZXJyb3IpIHsKCWRlcG9zaXQsIGVyciA6PSBzLmdldERlcG9zaXQobHBUb2tlbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoKCXJldHVybiBkZXBvc2l0LlN0YWtlVGltZSgpLCBuaWwKfQoKLy8gR2V0RGVwb3NpdFRhcmdldFBvb2xQYXRoIHJldHVybnMgdGhlIHRhcmdldCBwb29sIHBhdGggb2YgYSBkZXBvc2l0LgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gbHBUb2tlbklkOiBMUCBwb3NpdGlvbiBORlQgdG9rZW4gSUQgd2hvc2UgcG9vbCB0YXJnZXQgaXMgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHN0cmluZzogUG9vbCBwYXRoIHRhcmdldGVkIGJ5IHRoZSBkZXBvc2l0LgovLyAgIC0gZXJyb3I6IE5vbi1uaWwgZGF0YS1ub3QtZm91bmQgZXJyb3Igd2hlbiBscFRva2VuSWQgaXMgbm90IGN1cnJlbnRseSBkZXBvc2l0ZWQ7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0RGVwb3NpdFRhcmdldFBvb2xQYXRoKGxwVG9rZW5JZCB1aW50NjQpIChzdHJpbmcsIGVycm9yKSB7CglkZXBvc2l0LCBlcnIgOj0gcy5nZXREZXBvc2l0KGxwVG9rZW5JZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgZXJyCgl9CgoJcmV0dXJuIGRlcG9zaXQuVGFyZ2V0UG9vbFBhdGgoKSwgbmlsCn0KCi8vIEdldERlcG9zaXRUaWNrTG93ZXIgcmV0dXJucyB0aGUgbG93ZXIgdGljayBvZiBhIGRlcG9zaXQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBscFRva2VuSWQ6IExQIHBvc2l0aW9uIE5GVCB0b2tlbiBJRCB3aG9zZSBsb3dlciB0aWNrIGlzIHF1ZXJpZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQzMjogU2lnbmVkIGxvd2VyIHRpY2sgYm91bmRhcnkgcmVjb3JkZWQgYnkgdGhlIGRlcG9zaXQuCi8vICAgLSBlcnJvcjogTm9uLW5pbCBkYXRhLW5vdC1mb3VuZCBlcnJvciB3aGVuIGxwVG9rZW5JZCBpcyBub3QgY3VycmVudGx5IGRlcG9zaXRlZDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXREZXBvc2l0VGlja0xvd2VyKGxwVG9rZW5JZCB1aW50NjQpIChpbnQzMiwgZXJyb3IpIHsKCWRlcG9zaXQsIGVyciA6PSBzLmdldERlcG9zaXQobHBUb2tlbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoKCXJldHVybiBkZXBvc2l0LlRpY2tMb3dlcigpLCBuaWwKfQoKLy8gR2V0RGVwb3NpdFRpY2tVcHBlciByZXR1cm5zIHRoZSB1cHBlciB0aWNrIG9mIGEgZGVwb3NpdC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGxwVG9rZW5JZDogTFAgcG9zaXRpb24gTkZUIHRva2VuIElEIHdob3NlIHVwcGVyIHRpY2sgaXMgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDMyOiBTaWduZWQgdXBwZXIgdGljayBib3VuZGFyeSByZWNvcmRlZCBieSB0aGUgZGVwb3NpdC4KLy8gICAtIGVycm9yOiBOb24tbmlsIGRhdGEtbm90LWZvdW5kIGVycm9yIHdoZW4gbHBUb2tlbklkIGlzIG5vdCBjdXJyZW50bHkgZGVwb3NpdGVkOyBuaWwgb24gc3VjY2Vzcy4KZnVuYyAocyAqc3Rha2VyVjEpIEdldERlcG9zaXRUaWNrVXBwZXIobHBUb2tlbklkIHVpbnQ2NCkgKGludDMyLCBlcnJvcikgewoJZGVwb3NpdCwgZXJyIDo9IHMuZ2V0RGVwb3NpdChscFRva2VuSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CgoJcmV0dXJuIGRlcG9zaXQuVGlja1VwcGVyKCksIG5pbAp9CgovLyBHZXREZXBvc2l0TGlxdWlkaXR5IHJldHVybnMgdGhlIGxpcXVpZGl0eSBvZiBhIGRlcG9zaXQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBscFRva2VuSWQ6IExQIHBvc2l0aW9uIE5GVCB0b2tlbiBJRCB3aG9zZSBsaXF1aWRpdHkgaXMgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtICp1MjU2LlVpbnQ6IFBvc2l0aW9uIGxpcXVpZGl0eSBhcyBhbiB1bnNpZ25lZCAyNTYtYml0IHZhbHVlLCBvciBuaWwgd2hlbiBsb29rdXAgZmFpbHMuCi8vICAgLSBlcnJvcjogTm9uLW5pbCBkYXRhLW5vdC1mb3VuZCBlcnJvciB3aGVuIGxwVG9rZW5JZCBpcyBub3QgY3VycmVudGx5IGRlcG9zaXRlZDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXREZXBvc2l0TGlxdWlkaXR5KGxwVG9rZW5JZCB1aW50NjQpICgqdTI1Ni5VaW50LCBlcnJvcikgewoJZGVwb3NpdCwgZXJyIDo9IHMuZ2V0RGVwb3NpdChscFRva2VuSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBlcnIKCX0KCglyZXR1cm4gZGVwb3NpdC5MaXF1aWRpdHkoKSwgbmlsCn0KCi8vIEdldERlcG9zaXRMaXF1aWRpdHlBc1N0cmluZyByZXR1cm5zIHRoZSBsaXF1aWRpdHkgb2YgYSBkZXBvc2l0IGFzIHN0cmluZy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGxwVG9rZW5JZDogTFAgcG9zaXRpb24gTkZUIHRva2VuIElEIHdob3NlIGxpcXVpZGl0eSBpcyBmb3JtYXR0ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBzdHJpbmc6IFBvc2l0aW9uIGxpcXVpZGl0eSBlbmNvZGVkIGFzIGEgZGVjaW1hbCBzdHJpbmcuCi8vICAgLSBlcnJvcjogTm9uLW5pbCBkYXRhLW5vdC1mb3VuZCBlcnJvciB3aGVuIGxwVG9rZW5JZCBpcyBub3QgY3VycmVudGx5IGRlcG9zaXRlZDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXREZXBvc2l0TGlxdWlkaXR5QXNTdHJpbmcobHBUb2tlbklkIHVpbnQ2NCkgKHN0cmluZywgZXJyb3IpIHsKCWxpcXVpZGl0eSwgZXJyIDo9IHMuR2V0RGVwb3NpdExpcXVpZGl0eShscFRva2VuSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gIiIsIGVycgoJfQoKCXJldHVybiBsaXF1aWRpdHkuVG9TdHJpbmcoKSwgbmlsCn0KCi8vIEdldERlcG9zaXRJbnRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZXN0YW1wIHJldHVybnMgdGhlIGxhc3QgY29sbGVjdCB0aW1lc3RhbXAgb2YgYSBkZXBvc2l0LgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gbHBUb2tlbklkOiBMUCBwb3NpdGlvbiBORlQgdG9rZW4gSUQgd2hvc2UgaW50ZXJuYWwtcmV3YXJkIGN1cnNvciBpcyBxdWVyaWVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IFVuaXggdGltZXN0YW1wIG9mIHRoZSBkZXBvc2l0J3MgbGFzdCBpbnRlcm5hbCBHTlMgcmV3YXJkIGNvbGxlY3Rpb24uCi8vICAgLSBlcnJvcjogTm9uLW5pbCBkYXRhLW5vdC1mb3VuZCBlcnJvciB3aGVuIGxwVG9rZW5JZCBpcyBub3QgY3VycmVudGx5IGRlcG9zaXRlZDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXREZXBvc2l0SW50ZXJuYWxSZXdhcmRMYXN0Q29sbGVjdFRpbWVzdGFtcChscFRva2VuSWQgdWludDY0KSAoaW50NjQsIGVycm9yKSB7CglkZXBvc2l0LCBlcnIgOj0gcy5nZXREZXBvc2l0KGxwVG9rZW5JZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAwLCBlcnIKCX0KCglyZXR1cm4gZGVwb3NpdC5JbnRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZSgpLCBuaWwKfQoKLy8gR2V0RGVwb3NpdENvbGxlY3RlZEludGVybmFsUmV3YXJkIHJldHVybnMgdGhlIGNvbGxlY3RlZCBpbnRlcm5hbCByZXdhcmQgYW1vdW50LgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gbHBUb2tlbklkOiBMUCBwb3NpdGlvbiBORlQgdG9rZW4gSUQgd2hvc2UgY29sbGVjdGVkIEdOUyBhbW91bnQgaXMgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBDdW11bGF0aXZlIGludGVybmFsIEdOUyByZXdhcmQgYWxyZWFkeSBjb2xsZWN0ZWQgZm9yIHRoZSBkZXBvc2l0LgovLyAgIC0gZXJyb3I6IE5vbi1uaWwgZGF0YS1ub3QtZm91bmQgZXJyb3Igd2hlbiBscFRva2VuSWQgaXMgbm90IGN1cnJlbnRseSBkZXBvc2l0ZWQ7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0RGVwb3NpdENvbGxlY3RlZEludGVybmFsUmV3YXJkKGxwVG9rZW5JZCB1aW50NjQpIChpbnQ2NCwgZXJyb3IpIHsKCWRlcG9zaXQsIGVyciA6PSBzLmdldERlcG9zaXQobHBUb2tlbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoKCXJldHVybiBkZXBvc2l0LkNvbGxlY3RlZEludGVybmFsUmV3YXJkKCksIG5pbAp9CgovLyBHZXREZXBvc2l0Q29sbGVjdGVkRXh0ZXJuYWxSZXdhcmQgcmV0dXJucyB0aGUgY29sbGVjdGVkIGV4dGVybmFsIHJld2FyZCBhbW91bnQgZm9yIGFuIGluY2VudGl2ZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGxwVG9rZW5JZDogTFAgcG9zaXRpb24gTkZUIHRva2VuIElEIHdob3NlIGV4dGVybmFsLXJld2FyZCBoaXN0b3J5IGlzIHF1ZXJpZWQuCi8vICAgLSBpbmNlbnRpdmVJZDogRXh0ZXJuYWwgaW5jZW50aXZlIGlkZW50aWZpZXIgd2hvc2UgY29sbGVjdGVkIGFtb3VudCBpcyBxdWVyaWVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IEN1bXVsYXRpdmUgcmV3YXJkIGNvbGxlY3RlZCBmcm9tIGluY2VudGl2ZUlkLCBpbiBpdHMgcmV3YXJkLXRva2VuIHVuaXRzLgovLyAgIC0gZXJyb3I6IE5vbi1uaWwgd2hlbiB0aGUgcG9zaXRpb24gZGVwb3NpdCBvciBpdHMgY2hlY2twb2ludCBkYXRhIGNhbm5vdCBiZSByZXNvbHZlZDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXREZXBvc2l0Q29sbGVjdGVkRXh0ZXJuYWxSZXdhcmQobHBUb2tlbklkIHVpbnQ2NCwgaW5jZW50aXZlSWQgc3RyaW5nKSAoaW50NjQsIGVycm9yKSB7CglkZXBvc2l0UmVzb2x2ZXIsIGVyciA6PSBzLmdldERlcG9zaXRSZXNvbHZlcihscFRva2VuSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CglyZXR1cm4gZGVwb3NpdFJlc29sdmVyLkNvbGxlY3RlZEV4dGVybmFsUmV3YXJkKGluY2VudGl2ZUlkKSwgbmlsCn0KCi8vIEdldERlcG9zaXRFeHRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZXN0YW1wIHJldHVybnMgdGhlIGxhc3QgY29sbGVjdCB0aW1lc3RhbXAgb2YgYSBkZXBvc2l0LgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gbHBUb2tlbklkOiBMUCBwb3NpdGlvbiBORlQgdG9rZW4gSUQgd2hvc2UgZXh0ZXJuYWwtcmV3YXJkIGN1cnNvciBpcyBxdWVyaWVkLgovLyAgIC0gaW5jZW50aXZlSWQ6IEV4dGVybmFsIGluY2VudGl2ZSBpZGVudGlmaWVyIHdob3NlIGNvbGxlY3Rpb24gdGltZSBpcyBxdWVyaWVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IFVuaXggdGltZXN0YW1wIG9mIHRoZSBkZXBvc2l0J3MgbGFzdCBjb2xsZWN0aW9uIGZvciBpbmNlbnRpdmVJZC4KLy8gICAtIGVycm9yOiBOb24tbmlsIHdoZW4gdGhlIHBvc2l0aW9uIGRlcG9zaXQgb3IgaXRzIGNoZWNrcG9pbnQgZGF0YSBjYW5ub3QgYmUgcmVzb2x2ZWQ7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0RGVwb3NpdEV4dGVybmFsUmV3YXJkTGFzdENvbGxlY3RUaW1lc3RhbXAobHBUb2tlbklkIHVpbnQ2NCwgaW5jZW50aXZlSWQgc3RyaW5nKSAoaW50NjQsIGVycm9yKSB7CglkZXBvc2l0UmVzb2x2ZXIsIGVyciA6PSBzLmdldERlcG9zaXRSZXNvbHZlcihscFRva2VuSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgZXJyCgl9CglyZXR1cm4gZGVwb3NpdFJlc29sdmVyLkV4dGVybmFsUmV3YXJkTGFzdENvbGxlY3RUaW1lKGluY2VudGl2ZUlkKSwgbmlsCn0KCi8vIEdldERlcG9zaXRXYXJtVXAgcmV0dXJucyB0aGUgd2FybS11cCByZWNvcmRzIG9mIGEgZGVwb3NpdC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGxwVG9rZW5JZDogTFAgcG9zaXRpb24gTkZUIHRva2VuIElEIHdob3NlIHdhcm0tdXAgcmVjb3JkcyBhcmUgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIFtdc3IuV2FybXVwOiBXYXJtLXVwIHJld2FyZCByZWNvcmRzIGN1cnJlbnRseSBhc3NvY2lhdGVkIHdpdGggdGhlIGRlcG9zaXQuCi8vICAgLSBlcnJvcjogTm9uLW5pbCBkYXRhLW5vdC1mb3VuZCBlcnJvciB3aGVuIGxwVG9rZW5JZCBpcyBub3QgY3VycmVudGx5IGRlcG9zaXRlZDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXREZXBvc2l0V2FybVVwKGxwVG9rZW5JZCB1aW50NjQpIChbXXNyLldhcm11cCwgZXJyb3IpIHsKCWRlcG9zaXQsIGVyciA6PSBzLmdldERlcG9zaXQobHBUb2tlbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIG5pbCwgZXJyCgl9CgoJcmV0dXJuIGRlcG9zaXQuV2FybXVwcygpLCBuaWwKfQoKLy8gR2V0RGVwb3NpdEV4dGVybmFsSW5jZW50aXZlSWRMaXN0IHJldHVybnMgZXh0ZXJuYWwgaW5jZW50aXZlIElEcyBmb3IgYSBkZXBvc2l0LgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gbHBUb2tlbklkOiBMUCBwb3NpdGlvbiBORlQgdG9rZW4gSUQgd2hvc2UgaW5jZW50aXZlIGluZGV4IGlzIHF1ZXJpZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBbXXN0cmluZzogRXh0ZXJuYWwgaW5jZW50aXZlIGlkZW50aWZpZXJzIHRyYWNrZWQgYnkgdGhlIGRlcG9zaXQuCi8vICAgLSBlcnJvcjogTm9uLW5pbCBkYXRhLW5vdC1mb3VuZCBlcnJvciB3aGVuIGxwVG9rZW5JZCBpcyBub3QgY3VycmVudGx5IGRlcG9zaXRlZDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXREZXBvc2l0RXh0ZXJuYWxJbmNlbnRpdmVJZExpc3QobHBUb2tlbklkIHVpbnQ2NCkgKFtdc3RyaW5nLCBlcnJvcikgewoJZGVwb3NpdCwgZXJyIDo9IHMuZ2V0RGVwb3NpdChscFRva2VuSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBlcnIKCX0KCglyZXR1cm4gZGVwb3NpdC5HZXRFeHRlcm5hbEluY2VudGl2ZUlkTGlzdCgpLCBuaWwKfQoKLy8gR2V0UG9vbFRpZXIgcmV0dXJucyB0aGUgdGllciBvZiBhIHBvb2wuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogUG9vbCBwYXRoIHdob3NlIGN1cnJlbnQgZW1pc3Npb24gdGllciBpcyBxdWVyaWVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gdWludDY0OiBDdXJyZW50IHRpZXIgbnVtYmVyOyB6ZXJvIG1lYW5zIHRoZSBwb29sIGlzIG5vdCBhbiBpbnRlcm5hbC1lbWlzc2lvbiB0YXJnZXQuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXRQb29sVGllcihwb29sUGF0aCBzdHJpbmcpIHVpbnQ2NCB7CglyZXR1cm4gcy5nZXRQb29sVGllcigpLkN1cnJlbnRUaWVyKHBvb2xQYXRoKQp9CgovLyBHZXRQb29sVGllclJhdGlvIHJldHVybnMgdGhlIGN1cnJlbnQgcmV3YXJkIHJhdGlvIGZvciBhIHBvb2wncyB0aWVyLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IFBvb2wgcGF0aCB3aG9zZSBjdXJyZW50IHRpZXIgcmF0aW8gaXMgcXVlcmllZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHVpbnQ2NDogQ29uZmlndXJlZCBwZXJjZW50YWdlIHdlaWdodCAoMC0xMDApIGFzc29jaWF0ZWQgd2l0aCB0aGUgcG9vbCdzIGN1cnJlbnQgdGllci4KLy8gICAtIGVycm9yOiBOb24tbmlsIHdoZW4gdGhlIHBvb2wncyBjdXJyZW50IHRpZXIgaGFzIG5vIGNvbmZpZ3VyZWQgcmF0aW87IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0UG9vbFRpZXJSYXRpbyhwb29sUGF0aCBzdHJpbmcpICh1aW50NjQsIGVycm9yKSB7Cgl0aWVyIDo9IHMuR2V0UG9vbFRpZXIocG9vbFBhdGgpCglyYXRpbywgZXJyIDo9IHMuZ2V0UG9vbFRpZXIoKS50aWVyUmF0aW8uR2V0KHRpZXIpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgbWFrZUVycm9yV2l0aERldGFpbHMoZXJySW52YWxpZFBvb2xUaWVyLCBlcnIuRXJyb3IoKSkKCX0KCglyZXR1cm4gcmF0aW8sIG5pbAp9CgovLyBHZXRQb29sVGllckNvdW50IHJldHVybnMgdGhlIG51bWJlciBvZiBwb29scyBpbiBhIHRpZXIuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB0aWVyOiBUaWVyIG51bWJlciB3aG9zZSBjdXJyZW50IHBvb2wgbWVtYmVyc2hpcCBjb3VudCBpcyBxdWVyaWVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gdWludDY0OiBOdW1iZXIgb2YgcG9vbHMgY3VycmVudGx5IGFzc2lnbmVkIHRvIHRpZXI7IHplcm8gaXMgcmV0dXJuZWQgZm9yIHRpZXIgemVyby4KZnVuYyAocyAqc3Rha2VyVjEpIEdldFBvb2xUaWVyQ291bnQodGllciB1aW50NjQpIHVpbnQ2NCB7CglpZiB0aWVyID09IDAgewoJCXJldHVybiAwCgl9CglyZXR1cm4gdWludDY0KHMuZ2V0UG9vbFRpZXIoKS5DdXJyZW50Q291bnQodGllcikpCn0KCi8vIEdldFBvb2xSZXdhcmQgcmV0dXJucyB0aGUgY3VycmVudCByZXdhcmQgYW1vdW50IGZvciBhIHRpZXIuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB0aWVyOiBFbWlzc2lvbiB0aWVyIHdob3NlIGN1cnJlbnQgcGVyLXBvb2wgcmV3YXJkIGlzIHF1ZXJpZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogQ3VycmVudCBHTlMgcmV3YXJkIGFsbG9jYXRpb24gcGVyIHNlY29uZCBmb3Igb25lIHBvb2wgaW4gdGllci4KLy8gICAtIGVycm9yOiBOb24tbmlsIHdoZW4gdGllciBpcyBvdXRzaWRlIHRoZSBjb25maWd1cmVkIHJhbmdlIG9yIHRoZSBlbWlzc2lvbiByYXRlIGNhbm5vdCBiZSByZWFkOyBuaWwgb24gc3VjY2Vzcy4KZnVuYyAocyAqc3Rha2VyVjEpIEdldFBvb2xSZXdhcmQodGllciB1aW50NjQpIChpbnQ2NCwgZXJyb3IpIHsKCWlmIHRpZXIgPT0gMCB8fCB0aWVyID49IEFsbFRpZXJDb3VudCB7CgkJcmV0dXJuIDAsIG1ha2VFcnJvcldpdGhEZXRhaWxzKAoJCQllcnJJbnZhbGlkUG9vbFRpZXIsCgkJCXVmbXQuU3ByaW50ZigidGllciglZCkgbXVzdCBiZSBiZXR3ZWVuIDEgYW5kICVkIiwgdGllciwgQWxsVGllckNvdW50LTEpLAoJCSkKCX0KCXJldHVybiBzLmdldFBvb2xUaWVyKCkuQ3VycmVudFJld2FyZCh0aWVyKQp9CgovLyBHZXRQb29sU3Rha2VkTGlxdWlkaXR5IHJldHVybnMgdGhlIGN1cnJlbnQgdG90YWwgc3Rha2VkIGxpcXVpZGl0eSBvZiBhIHBvb2wuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogUG9vbCBwYXRoIHdob3NlIGN1cnJlbnQgc3Rha2VkIGxpcXVpZGl0eSBpcyBxdWVyaWVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gc3RyaW5nOiBDdXJyZW50IHN0YWtlZCBsaXF1aWRpdHkgZW5jb2RlZCBhcyBhIGRlY2ltYWwgdW5zaWduZWQtaW50ZWdlciBzdHJpbmcuCi8vICAgLSBlcnJvcjogTm9uLW5pbCB3aGVuIHBvb2xQYXRoIGhhcyBubyByZWdpc3RlcmVkIHBvb2w7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0UG9vbFN0YWtlZExpcXVpZGl0eShwb29sUGF0aCBzdHJpbmcpIChzdHJpbmcsIGVycm9yKSB7Cglwb29sLCBlcnIgOj0gcy5nZXRQb29sQnlQb29sUGF0aChwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiAiIiwgZXJyCgl9CglsaXF1aWRpdHkgOj0gTmV3UG9vbFJlc29sdmVyKHBvb2wpLkN1cnJlbnRTdGFrZWRMaXF1aWRpdHkodGltZS5Ob3coKS5Vbml4KCkpCglpZiBsaXF1aWRpdHkgPT0gbmlsIHsKCQlyZXR1cm4gdTI1Ni5aZXJvKCkuVG9TdHJpbmcoKSwgbmlsCgl9CgoJcmV0dXJuIGxpcXVpZGl0eS5Ub1N0cmluZygpLCBuaWwKfQoKLy8gR2V0UG9vbHNCeVRpZXIgcmV0dXJucyB0aGUgbGlzdCBvZiBwb29scyBpbiBhIHRpZXIuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB0aWVyOiBUaWVyIG51bWJlciB3aG9zZSBwb29sIG1lbWJlcnNoaXAgaXMgbGlzdGVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gW11zdHJpbmc6IFBvb2wgcGF0aHMgY3VycmVudGx5IGFzc2lnbmVkIHRvIHRpZXIsIG9yIGFuIGVtcHR5IHNsaWNlIGZvciB0aWVyIHplcm8uCi8vICAgLSBlcnJvcjogTm9uLW5pbCB3aGVuIHN0b3JlZCB0aWVyIG1lbWJlcnNoaXAgY2Fubm90IGJlIGNhc3QgdG8gdWludDY0OyBuaWwgb24gc3VjY2Vzcy4KZnVuYyAocyAqc3Rha2VyVjEpIEdldFBvb2xzQnlUaWVyKHRpZXIgdWludDY0KSAoW11zdHJpbmcsIGVycm9yKSB7CglpZiB0aWVyID09IDAgewoJCXJldHVybiBbXXN0cmluZ3t9LCBuaWwKCX0KCglwb29scyA6PSBtYWtlKFtdc3RyaW5nLCAwKQoJdmFyIGl0ZXJFcnIgZXJyb3IKCXMuZ2V0UG9vbFRpZXIoKS5tZW1iZXJzaGlwLkl0ZXJhdGUoIiIsICIiLCBmdW5jKHBvb2xQYXRoIHN0cmluZywgdmFsdWUgYW55KSBib29sIHsKCQljdXJyZW50VGllciwgb2sgOj0gdmFsdWUuKHVpbnQ2NCkKCQlpZiAhb2sgewoJCQlpdGVyRXJyID0gZXJyb3JzLk5ldygiZmFpbGVkIHRvIGNhc3QgdGllciB0byB1aW50NjQiKQoJCQlyZXR1cm4gdHJ1ZQoJCX0KCQlpZiBjdXJyZW50VGllciA9PSB0aWVyIHsKCQkJcG9vbHMgPSBhcHBlbmQocG9vbHMsIHBvb2xQYXRoKQoJCX0KCQlyZXR1cm4gZmFsc2UKCX0pCglpZiBpdGVyRXJyICE9IG5pbCB7CgkJcmV0dXJuIG5pbCwgaXRlckVycgoJfQoKCXJldHVybiBwb29scywgbmlsCn0KCi8vIEdldFRvdGFsRW1pc3Npb25TZW50IHJldHVybnMgdGhlIHRvdGFsIEdOUyBlbWlzc2lvbiBzZW50LgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IEN1bXVsYXRpdmUgR05TIGVtaXNzaW9uIGFtb3VudCBzZW50IGJ5IHRoZSBzdGFrZXIuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXRUb3RhbEVtaXNzaW9uU2VudCgpIGludDY0IHsKCXJldHVybiBzLnN0b3JlLkdldFRvdGFsRW1pc3Npb25TZW50KCkKfQoKLy8gR2V0QWxsb3dlZFRva2VucyByZXR1cm5zIHRoZSBhbGxvd2VkIGV4dGVybmFsIGluY2VudGl2ZSB0b2tlbiBsaXN0LgovLwovLyBSZXR1cm5zOgovLyAgIC0gW11zdHJpbmc6IFRva2VuIHBhdGhzIGN1cnJlbnRseSBhbGxvd2VkIGZvciBleHRlcm5hbCBpbmNlbnRpdmVzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0QWxsb3dlZFRva2VucygpIFtdc3RyaW5nIHsKCXJldHVybiBzLnN0b3JlLkdldEFsbG93ZWRUb2tlbnMoKQp9CgovLyBHZXREZW5pZWRSZXdhcmRUb2tlbnMgcmV0dXJucyB0aGUgZGVuaWVkIGV4dGVybmFsIGluY2VudGl2ZSByZXdhcmQgdG9rZW4gbGlzdC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIFtdc3RyaW5nOiBUb2tlbiBwYXRocyBjdXJyZW50bHkgZGVuaWVkIGZvciBuZXdseSBjcmVhdGVkIGV4dGVybmFsIGluY2VudGl2ZXMuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXREZW5pZWRSZXdhcmRUb2tlbnMoKSBbXXN0cmluZyB7CglyZXR1cm4gcy5zdG9yZS5HZXREZW5pZWRSZXdhcmRUb2tlbnMoKQp9CgovLyBHZXRXYXJtdXBUZW1wbGF0ZSByZXR1cm5zIHRoZSBjdXJyZW50IHdhcm11cCB0ZW1wbGF0ZS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIFtdc3IuV2FybXVwOiBDdXJyZW50IHdhcm0tdXAgcGVyY2VudGFnZSBhbmQgZHVyYXRpb24gcmVjb3JkcyB1c2VkIGZvciByZXdhcmQgY2FsY3VsYXRpb25zLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0V2FybXVwVGVtcGxhdGUoKSBbXXNyLldhcm11cCB7CglyZXR1cm4gcy5zdG9yZS5HZXRXYXJtdXBUZW1wbGF0ZSgpCn0KCi8vIElzU3Rha2VkIHJldHVybnMgd2hldGhlciBhIHBvc2l0aW9uIGlzIHN0YWtlZC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvc2l0aW9uSWQ6IExQIHBvc2l0aW9uIE5GVCB0b2tlbiBJRCB3aG9zZSBsaXZlLXN0YWtpbmcgc3RhdHVzIGlzIHF1ZXJpZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBib29sOiB0cnVlIHdoZW4gcG9zaXRpb25JZCBoYXMgYSBsaXZlIGRlcG9zaXQ7IGZhbHNlIHdoZW4gaXQgaXMgbm90IHN0YWtlZC4KZnVuYyAocyAqc3Rha2VyVjEpIElzU3Rha2VkKHBvc2l0aW9uSWQgdWludDY0KSBib29sIHsKCXJldHVybiBzLmdldERlcG9zaXRzKCkuSGFzKHBvc2l0aW9uSWQpCn0KCi8vIEdldEV4dGVybmFsSW5jZW50aXZlQnlQb29sUGF0aCByZXR1cm5zIGFsbCBleHRlcm5hbCBpbmNlbnRpdmVzIGZvciBhIHBvb2wuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogUG9vbCBwYXRoIHdob3NlIGV4dGVybmFsIGluY2VudGl2ZXMgYXJlIGxpc3RlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIFtdc3IuRXh0ZXJuYWxJbmNlbnRpdmU6IEV4dGVybmFsIGluY2VudGl2ZXMgdGFyZ2V0aW5nIHBvb2xQYXRoLCBvciBhbiBlbXB0eSBzbGljZSB3aGVuIG5vbmUgZXhpc3QuCi8vICAgLSBlcnJvcjogTm9uLW5pbCB3aGVuIGFuIGV4dGVybmFsLWluY2VudGl2ZSBlbnRyeSBoYXMgYW4gaW5jb21wYXRpYmxlIHN0b3JlZCB0eXBlOyBuaWwgb24gc3VjY2Vzcy4KZnVuYyAocyAqc3Rha2VyVjEpIEdldEV4dGVybmFsSW5jZW50aXZlQnlQb29sUGF0aChwb29sUGF0aCBzdHJpbmcpIChbXXNyLkV4dGVybmFsSW5jZW50aXZlLCBlcnJvcikgewoJaW5jZW50aXZlcyA6PSBtYWtlKFtdc3IuRXh0ZXJuYWxJbmNlbnRpdmUsIDApCgl2YXIgaXRlckVyciBlcnJvcgoKCXMuc3RvcmUuR2V0RXh0ZXJuYWxJbmNlbnRpdmVzKCkuSXRlcmF0ZSgiIiwgIiIsIGZ1bmMoXyBzdHJpbmcsIHZhbHVlIGFueSkgYm9vbCB7CgkJaW5jZW50aXZlLCBvayA6PSB2YWx1ZS4oKnNyLkV4dGVybmFsSW5jZW50aXZlKQoJCWlmICFvayB7CgkJCWl0ZXJFcnIgPSBlcnJvcnMuTmV3KCJmYWlsZWQgdG8gY2FzdCB2YWx1ZSB0byAqRXh0ZXJuYWxJbmNlbnRpdmUiKQoJCQlyZXR1cm4gdHJ1ZQoJCX0KCQlpZiBpbmNlbnRpdmUuVGFyZ2V0UG9vbFBhdGgoKSA9PSBwb29sUGF0aCB7CgkJCWluY2VudGl2ZXMgPSBhcHBlbmQoaW5jZW50aXZlcywgKmluY2VudGl2ZSkKCQl9CgkJcmV0dXJuIGZhbHNlCgl9KQoJaWYgaXRlckVyciAhPSBuaWwgewoJCXJldHVybiBuaWwsIGl0ZXJFcnIKCX0KCglyZXR1cm4gaW5jZW50aXZlcywgbmlsCn0KCi8vIEdldFBvb2xSZXdhcmRDYWNoZXMgcmV0dXJucyBhIHJlYWQtb25seSB2aWV3IG9mIGEgcG9vbCdzIHJld2FyZCBjYWNoZSwga2V5ZWQKLy8gYnkgdGhlIGVuY29kZWQgYmxvY2sgdGltZXN0YW1wLiBuaWwgaXMgcmV0dXJuZWQgd2hlbiB0aGUgcG9vbCBkb2VzIG5vdCBleGlzdC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2xQYXRoOiBQb29sIHBhdGggd2hvc2UgcmV3YXJkLWNhY2hlIHZpZXcgaXMgcmVxdWVzdGVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gKnJvdHJlZS5SZWFkT25seVRyZWU6IFJlYWQtb25seSB0cmVlIGtleWVkIGJ5IGVuY29kZWQgVW5peCB0aW1lc3RhbXBzIHdpdGggaW50NjQgcmV3YXJkIHJhdGVzOyBuaWwgd2hlbiBwb29sUGF0aCBpcyBhYnNlbnQgb3IgbWFsZm9ybWVkLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0UG9vbFJld2FyZENhY2hlcyhwb29sUGF0aCBzdHJpbmcpICpyb3RyZWUuUmVhZE9ubHlUcmVlIHsKCXBvb2wgOj0gcy5maW5kUG9vbEJ5UG9vbFBhdGgocG9vbFBhdGgpCglpZiBwb29sID09IG5pbCB7CgkJcmV0dXJuIG5pbAoJfQoKCXJldHVybiBwb29sLlJld2FyZENhY2hlKCkuUmVhZE9ubHkocmV3YXJkQ2FjaGVFbnRyeSkKfQoKLy8gR2V0UG9vbEluY2VudGl2ZXMgcmV0dXJucyBhIHJlYWQtb25seSB2aWV3IG9mIGEgcG9vbCdzIGV4dGVybmFsIGluY2VudGl2ZXMsCi8vIGtleWVkIGJ5IGluY2VudGl2ZSBJRC4gbmlsIGlzIHJldHVybmVkIHdoZW4gdGhlIHBvb2wgZG9lcyBub3QgZXhpc3QuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogUG9vbCBwYXRoIHdob3NlIGV4dGVybmFsLWluY2VudGl2ZSB2aWV3IGlzIHJlcXVlc3RlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtICpyb3RyZWUuUmVhZE9ubHlUcmVlOiBSZWFkLW9ubHkgdHJlZSBrZXllZCBieSBpbmNlbnRpdmUgSUQgd2l0aCBjbG9uZWQgZXh0ZXJuYWwtaW5jZW50aXZlIHZhbHVlczsgbmlsIHdoZW4gcG9vbFBhdGggaXMgYWJzZW50IG9yIG1hbGZvcm1lZC4KZnVuYyAocyAqc3Rha2VyVjEpIEdldFBvb2xJbmNlbnRpdmVzKHBvb2xQYXRoIHN0cmluZykgKnJvdHJlZS5SZWFkT25seVRyZWUgewoJcG9vbCA6PSBzLmZpbmRQb29sQnlQb29sUGF0aChwb29sUGF0aCkKCWlmIHBvb2wgPT0gbmlsIHsKCQlyZXR1cm4gbmlsCgl9CgoJcmV0dXJuIHJvdHJlZS5XcmFwKHBvb2wuSW5jZW50aXZlcygpLkluY2VudGl2ZVRyZWVzKCksIGNsb25lRXh0ZXJuYWxJbmNlbnRpdmVFbnRyeSkKfQoKLy8gR2V0UG9vbEdsb2JhbFJld2FyZFJhdGlvQWNjdW11bGF0aW9ucyByZXR1cm5zIGEgcmVhZC1vbmx5IHZpZXcgb2YgYSBwb29sJ3MKLy8gZ2xvYmFsIHJld2FyZCByYXRpbyBhY2N1bXVsYXRpb24sIGtleWVkIGJ5IHRoZSBlbmNvZGVkIGJsb2NrIHRpbWVzdGFtcC4KLy8gbmlsIGlzIHJldHVybmVkIHdoZW4gdGhlIHBvb2wgZG9lcyBub3QgZXhpc3QuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogUG9vbCBwYXRoIHdob3NlIGdsb2JhbCByZXdhcmQtcmF0aW8gaGlzdG9yeSBpcyByZXF1ZXN0ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqcm90cmVlLlJlYWRPbmx5VHJlZTogUmVhZC1vbmx5IHRyZWUga2V5ZWQgYnkgZW5jb2RlZCBVbml4IHRpbWVzdGFtcHMgd2l0aCBzdHJpbmctZW5jb2RlZCBhY2N1bXVsYXRpb25zOyBuaWwgd2hlbiBwb29sUGF0aCBpcyBhYnNlbnQgb3IgbWFsZm9ybWVkLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0UG9vbEdsb2JhbFJld2FyZFJhdGlvQWNjdW11bGF0aW9ucyhwb29sUGF0aCBzdHJpbmcpICpyb3RyZWUuUmVhZE9ubHlUcmVlIHsKCXBvb2wgOj0gcy5maW5kUG9vbEJ5UG9vbFBhdGgocG9vbFBhdGgpCglpZiBwb29sID09IG5pbCB7CgkJcmV0dXJuIG5pbAoJfQoKCXJldHVybiBwb29sLkdsb2JhbFJld2FyZFJhdGlvQWNjdW11bGF0aW9uKCkuUmVhZE9ubHkoYWNjdW11bGF0aW9uRW50cnkpCn0KCi8vIEdldFBvb2xIaXN0b3JpY2FsVGlja3MgcmV0dXJucyBhIHJlYWQtb25seSB2aWV3IG9mIGEgcG9vbCdzIGhpc3RvcmljYWwgdGlja3MsCi8vIGtleWVkIGJ5IHRoZSBlbmNvZGVkIGJsb2NrIHRpbWVzdGFtcCB3aXRoIHRoZSBpbnQzMiB0aWNrIGFzIHRoZSB2YWx1ZS4KLy8gbmlsIGlzIHJldHVybmVkIHdoZW4gdGhlIHBvb2wgZG9lcyBub3QgZXhpc3QuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogUG9vbCBwYXRoIHdob3NlIGhpc3RvcmljYWwgdGljayB2aWV3IGlzIHJlcXVlc3RlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtICpyb3RyZWUuUmVhZE9ubHlUcmVlOiBSZWFkLW9ubHkgdHJlZSBrZXllZCBieSBlbmNvZGVkIFVuaXggdGltZXN0YW1wcyB3aXRoIGludDMyIHRpY2sgdmFsdWVzOyBuaWwgd2hlbiBwb29sUGF0aCBpcyBhYnNlbnQgb3IgbWFsZm9ybWVkLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0UG9vbEhpc3RvcmljYWxUaWNrcyhwb29sUGF0aCBzdHJpbmcpICpyb3RyZWUuUmVhZE9ubHlUcmVlIHsKCXBvb2wgOj0gcy5maW5kUG9vbEJ5UG9vbFBhdGgocG9vbFBhdGgpCglpZiBwb29sID09IG5pbCB7CgkJcmV0dXJuIG5pbAoJfQoKCXJldHVybiBwb29sLkhpc3RvcmljYWxUaWNrKCkuUmVhZE9ubHkoaGlzdG9yaWNhbFRpY2tFbnRyeSkKfQoa0goKEGdldHRlcl91dGlscy5nbm8SvQpwYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCXNyICJnbm8ubGFuZC9yL2dub3N3YXAvc3Rha2VyIgopCgovLyBUaGUgZnVuY3Rpb25zIGJlbG93IGFyZSBtYWtlRW50cnlTYWZlRm4gdHJhbnNmb3JtYXRpb25zIGhhbmRlZCB0bwovLyByb3RyZWUuV3JhcC4gVGhleSBydW4gb24gZXZlcnkgcmVhZCB0aHJvdWdoIGEgcmVhZC1vbmx5IHZpZXcsIHNvIGVhY2ggb25lCi8vIHJldHVybnMgYSB2YWx1ZSB0aGUgY2FsbGVyIG1heSBob2xkIHdpdGhvdXQgcmVhY2hpbmcgcmVhbG0tb3duZWQgc3RhdGUuCgovLyBjbG9uZUV4dGVybmFsSW5jZW50aXZlRW50cnkgaXMgdGhlIHRyYW5zZm9ybWF0aW9uIGZvciBhIHBvb2wncyBpbmNlbnRpdmUKLy8gdHJlZS4gRXh0ZXJuYWxJbmNlbnRpdmUgaXMgbXV0YWJsZSBhbmQgaXRzIHNldHRlcnMgYXJlIGRlY2xhcmVkIGluCi8vIC9yL2dub3N3YXAvc3Rha2VyLCBzbyBhbiBleHRlcm5hbCBob2xkZXIgb2YgdGhlIHN0b3JlZCBwb2ludGVyIGNvdWxkIHdyaXRlCi8vIHJlYWxtIHN0YXRlIHRocm91Z2ggaXQuCmZ1bmMgY2xvbmVFeHRlcm5hbEluY2VudGl2ZUVudHJ5KHZhbHVlIGFueSkgYW55IHsKCWluY2VudGl2ZSwgb2sgOj0gdmFsdWUuKCpzci5FeHRlcm5hbEluY2VudGl2ZSkKCWlmICFvayB7CgkJcmV0dXJuIG5pbAoJfQoKCXJldHVybiBpbmNlbnRpdmUuQ2xvbmUoKQp9CgovLyByZXdhcmRDYWNoZUVudHJ5LCBhY2N1bXVsYXRpb25FbnRyeSwgYW5kIGhpc3RvcmljYWxUaWNrRW50cnkgYXJlIHRoZQovLyB0cmFuc2Zvcm1hdGlvbnMgZm9yIHRoZSBVaW50VHJlZS1iYWNrZWQgdmlld3MuIFRoZWlyIHZhbHVlcyBhcmUgaW1tdXRhYmxlCi8vIHNjYWxhcnMsIHNvIG5vdGhpbmcgbmVlZHMgY29weWluZzsgdGhleSB0eXBlLWNoZWNrIGluc3RlYWQsIHdoaWNoIGtlZXBzIHRoZQovLyBmaWx0ZXJpbmcgdGhlIHJlcGxhY2VkIHNsaWNlIGdldHRlcnMgZGlkIHdoZW4gYW4gZW50cnkgZmFpbGVkIGl0cyBjYXN0LgpmdW5jIHJld2FyZENhY2hlRW50cnkodmFsdWUgYW55KSBhbnkgewoJcmV3YXJkLCBvayA6PSB2YWx1ZS4oaW50NjQpCglpZiAhb2sgewoJCXJldHVybiBuaWwKCX0KCglyZXR1cm4gcmV3YXJkCn0KCmZ1bmMgYWNjdW11bGF0aW9uRW50cnkodmFsdWUgYW55KSBhbnkgewoJYWNjdW11bGF0aW9uLCBvayA6PSB2YWx1ZS4oc3RyaW5nKQoJaWYgIW9rIHsKCQlyZXR1cm4gbmlsCgl9CgoJcmV0dXJuIGFjY3VtdWxhdGlvbgp9CgpmdW5jIGhpc3RvcmljYWxUaWNrRW50cnkodmFsdWUgYW55KSBhbnkgewoJdGljaywgb2sgOj0gdmFsdWUuKGludDMyKQoJaWYgIW9rIHsKCQlyZXR1cm4gbmlsCgl9CgoJcmV0dXJuIHRpY2sKfQoaQwoLZ25vbW9kLnRvbWwSNG1vZHVsZSA9ICJnbm8ubGFuZC9yL2dub3N3YXAvc3Rha2VyL3YxIgpnbm8gPSAiMC45IgoasDgKCGluaXQuZ25vEqM4cGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkidGltZSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2FjY2Vzcy92MSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2VtaXNzaW9uIgoKCXNyICJnbm8ubGFuZC9yL2dub3N3YXAvc3Rha2VyIgopCgpjb25zdCAoCglkZWZhdWx0RGVwb3NpdEduc0Ftb3VudCAgICA9IGludDY0KDEwMF8wMDBfMDAwXzAwMCkKCWRlZmF1bHRNaW5pbXVtUmV3YXJkQW1vdW50ID0gaW50NjQoMV8wMDBfMDAwXzAwMCkKCgkvLyB1bnN0YWtpbmdGZWUgaXMgdGhlIGZlZSBjaGFyZ2VkIHdoZW4gdW5zdGFraW5nIHBvc2l0aW9ucy4KCS8vIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBtb2RpZmllZCB0aHJvdWdoIGdvdmVybmFuY2UuCglkZWZhdWx0VW5zdGFraW5nRmVlID0gdWludDY0KDEwMCkgLy8gMSUKKQoKZnVuYyBpbml0KGN1ciByZWFsbSkgewoJcmVnaXN0ZXJTdGFrZXJWMShjdXIpCn0KCmZ1bmMgcmVnaXN0ZXJTdGFrZXJWMShjdXIgcmVhbG0pIHsKCXNyLlJlZ2lzdGVySW5pdGlhbGl6ZXIoY3Jvc3MoY3VyKSwgZnVuYyhfIGludCwgcmxtIHJlYWxtLCBzdGFrZXJTdG9yZSBzci5JU3Rha2VyU3RvcmUsIHBvb2xBY2Nlc3NvciBzci5Qb29sQWNjZXNzb3IsIGVtaXNzaW9uQWNjZXNzb3Igc3IuRW1pc3Npb25BY2Nlc3NvciwgbmZ0QWNjZXNzb3Igc3IuTkZUQWNjZXNzb3IpIHNyLklTdGFrZXIgewoJCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCQllcnIgOj0gaW5pdFN0b3JlRGF0YSgwLCBybG0sIHN0YWtlclN0b3JlLCBlbWlzc2lvbkFjY2Vzc29yKQoJCWlmIGVyciAhPSBuaWwgewoJCQlwYW5pYyhlcnIpCgkJfQoKCQlpbnN0YW5jZSA6PSBOZXdTdGFrZXJWMShzdGFrZXJTdG9yZSwgcG9vbEFjY2Vzc29yLCBlbWlzc2lvbkFjY2Vzc29yLCBuZnRBY2Nlc3NvcikKCQlpbnN0YW5jZS5zZXR1cFN3YXBIb29rcygwLCBybG0pCgkJZW1pc3Npb25BY2Nlc3Nvci5TZXRPbkRpc3RyaWJ1dGlvblBjdENoYW5nZUNhbGxiYWNrKDAsIHJsbSwgaW5zdGFuY2UuZW1pc3Npb25DYWNoZVVwZGF0ZUhvb2spCgoJCXJldHVybiBpbnN0YW5jZQoJfSkKfQoKZnVuYyBpbml0U3RvcmVEYXRhKF8gaW50LCBybG0gcmVhbG0sIHN0YWtlclN0b3JlIHNyLklTdGFrZXJTdG9yZSwgZW1pc3Npb25BY2Nlc3NvciBzci5FbWlzc2lvbkFjY2Vzc29yKSBlcnJvciB7CglpZiAhc3Rha2VyU3RvcmUuSGFzRGVwb3NpdEduc0Ftb3VudFN0b3JlS2V5KCkgewoJCWVyciA6PSBzdGFrZXJTdG9yZS5TZXREZXBvc2l0R25zQW1vdW50KDAsIHJsbSwgZGVmYXVsdERlcG9zaXRHbnNBbW91bnQpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJaWYgIXN0YWtlclN0b3JlLkhhc01pbmltdW1SZXdhcmRBbW91bnRTdG9yZUtleSgpIHsKCQllcnIgOj0gc3Rha2VyU3RvcmUuU2V0TWluaW11bVJld2FyZEFtb3VudCgwLCBybG0sIGRlZmF1bHRNaW5pbXVtUmV3YXJkQW1vdW50KQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFzdGFrZXJTdG9yZS5IYXNEZXBvc2l0c1N0b3JlS2V5KCkgewoJCWVyciA6PSBzdGFrZXJTdG9yZS5TZXREZXBvc2l0cygwLCBybG0sIHNyLk5ld0JQVHJlZU4oMTYpKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFzdGFrZXJTdG9yZS5IYXNFeHRlcm5hbEluY2VudGl2ZXNTdG9yZUtleSgpIHsKCQllcnIgOj0gc3Rha2VyU3RvcmUuU2V0RXh0ZXJuYWxJbmNlbnRpdmVzKDAsIHJsbSwgc3IuTmV3QlBUcmVlTigxNikpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJaWYgIXN0YWtlclN0b3JlLkhhc1RvdGFsRW1pc3Npb25TZW50U3RvcmVLZXkoKSB7CgkJZXJyIDo9IHN0YWtlclN0b3JlLlNldFRvdGFsRW1pc3Npb25TZW50KDAsIHJsbSwgMCkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCX0KCglpZiAhc3Rha2VyU3RvcmUuSGFzQWxsb3dlZFRva2Vuc1N0b3JlS2V5KCkgewoJCS8vIENvcHkgdGhlIHBhY2thZ2UtbGV2ZWwgZGVmYXVsdCBzbGljZSBzbyBlYWNoIHN0b3JlIG93bnMgaXRzIG93bgoJCS8vIGFsbG93ZWQtdG9rZW5zIHNsaWNlLiBTdG9yaW5nIHNyLkRlZmF1bHRBbGxvd2VkVG9rZW5zIGRpcmVjdGx5IHdvdWxkCgkJLy8gYWxpYXMgdGhlIHNoYXJlZCAoc3Itb3duZWQpIHNsaWNlIGFjcm9zcyBldmVyeSBzdG9yZSwgbGVha2luZwoJCS8vIG11dGF0aW9ucyBhbmQgdHJpcHBpbmcgdGhlIHJlYWRvbmx5LXRhaW50IGdhdGUgb24gbGF0ZXIgd3JpdGVzLgoJCWVyciA6PSBzdGFrZXJTdG9yZS5TZXRBbGxvd2VkVG9rZW5zKDAsIHJsbSwgc3IuRGVmYXVsdEFsbG93ZWRUb2tlbnMoKSkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCX0KCglpZiAhc3Rha2VyU3RvcmUuSGFzSW5jZW50aXZlQ291bnRlclN0b3JlS2V5KCkgewoJCWVyciA6PSBzdGFrZXJTdG9yZS5TZXRJbmNlbnRpdmVDb3VudGVyKDAsIHJsbSwgc3IuTmV3Q291bnRlcigpKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFzdGFrZXJTdG9yZS5IYXNUb2tlblNwZWNpZmljTWluaW11bVJld2FyZHNTdG9yZUtleSgpIHsKCQllcnIgOj0gc3Rha2VyU3RvcmUuU2V0VG9rZW5TcGVjaWZpY01pbmltdW1SZXdhcmRzKDAsIHJsbSwgbWFrZShtYXBbc3RyaW5nXWludDY0KSkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcmV0dXJuIGVycgoJCX0KCX0KCglpZiAhc3Rha2VyU3RvcmUuSGFzVW5zdGFraW5nRmVlU3RvcmVLZXkoKSB7CgkJZXJyIDo9IHN0YWtlclN0b3JlLlNldFVuc3Rha2luZ0ZlZSgwLCBybG0sIGRlZmF1bHRVbnN0YWtpbmdGZWUpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJcGVuZGluZ1Byb3RvY29sRmVlcyA6PSBtYWtlKG1hcFtzdHJpbmddaW50NjQpCglpZiBzdGFrZXJTdG9yZS5IYXNQZW5kaW5nUHJvdG9jb2xGZWVzU3RvcmVLZXkoKSB7CgkJcGVuZGluZ1Byb3RvY29sRmVlcyA9IHN0YWtlclN0b3JlLkdldFBlbmRpbmdQcm90b2NvbEZlZXMoKQoJfQoJaWYgZXJyIDo9IHN0YWtlclN0b3JlLlNldFBlbmRpbmdQcm90b2NvbEZlZXMoMCwgcmxtLCBwZW5kaW5nUHJvdG9jb2xGZWVzKTsgZXJyICE9IG5pbCB7CgkJcmV0dXJuIGVycgoJfQoKCWlmICFzdGFrZXJTdG9yZS5IYXNVbnN0YWtlZFBvc2l0aW9uc1N0b3JlS2V5KCkgewoJCWVyciA6PSBzdGFrZXJTdG9yZS5TZXRVbnN0YWtlZFBvc2l0aW9ucygwLCBybG0sIHNyLk5ld0JQVHJlZU4oMTYpKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFzdGFrZXJTdG9yZS5IYXNVbmNvbGxlY3RlZEluY2VudGl2ZUNvdW50c1N0b3JlS2V5KCkgewoJCWVyciA6PSBzdGFrZXJTdG9yZS5TZXRVbmNvbGxlY3RlZEluY2VudGl2ZUNvdW50cygwLCBybG0sIHNyLk5ld0JQVHJlZU4oMTYpKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFzdGFrZXJTdG9yZS5IYXNXYXJtdXBUZW1wbGF0ZVN0b3JlS2V5KCkgewoJCWVyciA6PSBzdGFrZXJTdG9yZS5TZXRXYXJtdXBUZW1wbGF0ZSgwLCBybG0sIHNyLkRlZmF1bHRXYXJtdXBUZW1wbGF0ZSgpKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWluaXRpYWxpemVkUG9vbFRpZXIsIGluaXRpYWxpemVkUG9vbHMsIGluaXRpYWxQb29sVGllclRpbWUsIGluaXRpYWxUaWVyUmV3YXJkcyA6PSBpbml0aWFsaXplUG9vbFRpZXIoc3Rha2VyU3RvcmUpCgoJcHJldmlvdXNSZWFsbSA6PSBybG0uUHJldmlvdXMoKQoJZW1pdFNldFBvb2xUaWVyKAoJCXByZXZpb3VzUmVhbG0uQWRkcmVzcygpLlN0cmluZygpLAoJCXByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCWVtaXNzaW9uLkRlZmF1bHRJbml0aWFsUG9vbFRpZXJQYXRoLAoJCXVpbnQ2NChUaWVyMSksCgkJaW5pdGlhbGl6ZWRQb29sVGllci5jdXJyZW50RW1pc3Npb24sCgkJaW5pdGlhbFRpZXJSZXdhcmRzLAoJCWluaXRpYWxpemVkUG9vbFRpZXIuY291bnRzLAoJCWluaXRpYWxQb29sVGllclRpbWUsCgkpCgoJaWYgIXN0YWtlclN0b3JlLkhhc1Bvb2xzU3RvcmVLZXkoKSB7CgkJZXJyIDo9IHN0YWtlclN0b3JlLlNldFBvb2xzKDAsIHJsbSwgaW5pdGlhbGl6ZWRQb29scy50cmVlKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFzdGFrZXJTdG9yZS5IYXNQb29sVGllck1lbWJlcnNoaXBzU3RvcmVLZXkoKSB7CgkJZXJyIDo9IHN0YWtlclN0b3JlLlNldFBvb2xUaWVyTWVtYmVyc2hpcHMoMCwgcmxtLCBpbml0aWFsaXplZFBvb2xUaWVyLm1lbWJlcnNoaXApCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJaWYgIXN0YWtlclN0b3JlLkhhc1Bvb2xUaWVyUmF0aW9TdG9yZUtleSgpIHsKCQllcnIgOj0gc3Rha2VyU3RvcmUuU2V0UG9vbFRpZXJSYXRpbygwLCBybG0sIGluaXRpYWxpemVkUG9vbFRpZXIudGllclJhdGlvKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFzdGFrZXJTdG9yZS5IYXNQb29sVGllckNvdW50c1N0b3JlS2V5KCkgewoJCWVyciA6PSBzdGFrZXJTdG9yZS5TZXRQb29sVGllckNvdW50cygwLCBybG0sIGluaXRpYWxpemVkUG9vbFRpZXIuY291bnRzKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFzdGFrZXJTdG9yZS5IYXNQb29sVGllckxhc3RSZXdhcmRDYWNoZVRpbWVzdGFtcFN0b3JlS2V5KCkgewoJCWVyciA6PSBzdGFrZXJTdG9yZS5TZXRQb29sVGllckxhc3RSZXdhcmRDYWNoZVRpbWVzdGFtcCgwLCBybG0sIGluaXRpYWxpemVkUG9vbFRpZXIubGFzdFJld2FyZENhY2hlVGltZXN0YW1wKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFzdGFrZXJTdG9yZS5IYXNQb29sVGllckN1cnJlbnRFbWlzc2lvblN0b3JlS2V5KCkgewoJCWVyciA6PSBzdGFrZXJTdG9yZS5TZXRQb29sVGllckN1cnJlbnRFbWlzc2lvbigwLCBybG0sIGluaXRpYWxpemVkUG9vbFRpZXIuY3VycmVudEVtaXNzaW9uKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFzdGFrZXJTdG9yZS5IYXNQb29sVGllckdldEVtaXNzaW9uU3RvcmVLZXkoKSB7CgkJZ2V0RW1pc3Npb25GbiA6PSBmdW5jKCkgKGludDY0LCBlcnJvcikgewoJCQlyZXR1cm4gZW1pc3Npb25BY2Nlc3Nvci5HZXRTdGFrZXJFbWlzc2lvbkFtb3VudFBlclNlY29uZCgpCgkJfQoKCQllcnIgOj0gc3Rha2VyU3RvcmUuU2V0UG9vbFRpZXJHZXRFbWlzc2lvbigwLCBybG0sIGdldEVtaXNzaW9uRm4pCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJaWYgIXN0YWtlclN0b3JlLkhhc1Bvb2xUaWVyR2V0SGFsdmluZ0Jsb2Nrc0luUmFuZ2VTdG9yZUtleSgpIHsKCQlnZXRIYWx2aW5nQmxvY2tzSW5SYW5nZUZuIDo9IGZ1bmMoc3RhcnQsIGVuZCBpbnQ2NCkgKFtdaW50NjQsIFtdaW50NjQsIGVycm9yKSB7CgkJCXJldHVybiBlbWlzc2lvbkFjY2Vzc29yLkdldFN0YWtlckVtaXNzaW9uQW1vdW50UGVyU2Vjb25kSW5SYW5nZShzdGFydCwgZW5kKQoJCX0KCgkJZXJyIDo9IHN0YWtlclN0b3JlLlNldFBvb2xUaWVyR2V0SGFsdmluZ0Jsb2Nrc0luUmFuZ2UoMCwgcmxtLCBnZXRIYWx2aW5nQmxvY2tzSW5SYW5nZUZuKQoJCWlmIGVyciAhPSBuaWwgewoJCQlyZXR1cm4gZXJyCgkJfQoJfQoKCWlmICFzdGFrZXJTdG9yZS5IYXNDdXJyZW50U3dhcEJhdGNoU3RvcmVLZXkoKSB7CgkJZXJyIDo9IHN0YWtlclN0b3JlLlNldEN1cnJlbnRTd2FwQmF0Y2goMCwgcmxtLCBuaWwpCgkJaWYgZXJyICE9IG5pbCB7CgkJCXJldHVybiBlcnIKCQl9Cgl9CgoJcmV0dXJuIG5pbAp9CgovLyBpbml0aWFsaXplUG9vbFRpZXIgc2VlZHMgdGhlIHN0YWtlcidzIHBvb2wgdGllcmluZyBzdGF0ZSBvbiBmaXJzdCBpbml0LgovLwovLyBUaGUgZGVmYXVsdCBwb29sIGlzIHRoZSBjYW5vbmljYWwgV1VHTk9UOkdOUzozMDAwIHBvb2wsIHNvdXJjZWQgZnJvbSB0aGUKLy8gZW1pc3Npb24gcmVhbG0ncyBEZWZhdWx0SW5pdGlhbFBvb2xUaWVyUGF0aCBjb25zdGFudCBzbyB0aGF0IHRoZSBzdGFrZXIncwovLyB0aWVyLTEgYmFzZSBwb29sIGlzIGd1YXJhbnRlZWQgdG8gbWF0Y2ggdGhlIHBvb2wgZW1pc3Npb24gZGlzdHJpYnV0ZXMgdG8uCi8vCi8vIFdoZW4gU2V0RGlzdHJpYnV0aW9uU3RhcnRUaW1lIGV4ZWN1dGVzLCBlbWlzc2lvbiBkaXN0cmlidXRlcyB0byB0aGlzIGRlZmF1bHQKLy8gcG9vbCBhbmQgdGhlIHN0YWtlciB1c2VzIHRoZSBzYW1lIHBhdGggYXMgdGhlIGJhc2UgdGllci0xIHBvb2wgZm9yIHJld2FyZAovLyBhY2NydWFsLiBLZWVwaW5nIGJvdGggc2lkZXMgb24gZW1pc3Npb24ncyBzaW5nbGUgY29uc3RhbnQgc3RydWN0dXJhbGx5Ci8vIGVuZm9yY2VzIHRoYXQgaW52YXJpYW50IGFuZCByZW1vdmVzIGFueSByaXNrIG9mIHRoZSB0d28gcmVhbG1zIGRyaWZ0aW5nCi8vIGFwYXJ0IG9uIHRoZSBjYW5vbmljYWwgZGVmYXVsdCBwb29sIGlkZW50aXR5LgpmdW5jIGluaXRpYWxpemVQb29sVGllcihzdGFrZXJTdG9yZSBzci5JU3Rha2VyU3RvcmUpICgqUG9vbFRpZXIsICpQb29scywgaW50NjQsIG1hcFt1aW50NjRdaW50NjQpIHsKCXBvb2xzIDo9IE5ld1Bvb2xzKCkKCWN1cnJlbnRUaW1lIDo9IHRpbWUuTm93KCkuVW5peCgpCgoJcGwgOj0gTmV3UG9vbHMoKS5HZXRQb29sT3JOaWwoZW1pc3Npb24uRGVmYXVsdEluaXRpYWxQb29sVGllclBhdGgpCglpZiBwbCA9PSBuaWwgewoJCXBsID0gc3IuTmV3UG9vbChlbWlzc2lvbi5EZWZhdWx0SW5pdGlhbFBvb2xUaWVyUGF0aCwgY3VycmVudFRpbWUpCgkJcG9vbHMuc2V0KGVtaXNzaW9uLkRlZmF1bHRJbml0aWFsUG9vbFRpZXJQYXRoLCBwbCkKCX0KCglwb29sVGllciA6PSBOZXdQb29sVGllcigKCQlwb29scywKCQljdXJyZW50VGltZSwKCQllbWlzc2lvbi5EZWZhdWx0SW5pdGlhbFBvb2xUaWVyUGF0aCwKCQllbWlzc2lvbi5HZXRTdGFrZXJFbWlzc2lvbkFtb3VudFBlclNlY29uZCwKCQllbWlzc2lvbi5HZXRTdGFrZXJFbWlzc2lvbkFtb3VudFBlclNlY29uZEluUmFuZ2UsCgkpCgoJcmV0dXJuIHBvb2xUaWVyLCBwb29scywgY3VycmVudFRpbWUsIHBvb2xUaWVyLmNvbXB1dGVUaWVyUmV3YXJkcyhwb29sVGllci5jdXJyZW50RW1pc3Npb24pCn0KGqkWCgxpbnN0YW5jZS5nbm8SmBZwYWNrYWdlIHN0YWtlcgoKaW1wb3J0IHNyICJnbm8ubGFuZC9yL2dub3N3YXAvc3Rha2VyIgoKdHlwZSBzdGFrZXJWMSBzdHJ1Y3QgewoJc3RvcmUgICAgICAgICAgICBzci5JU3Rha2VyU3RvcmUKCXBvb2xBY2Nlc3NvciAgICAgc3IuUG9vbEFjY2Vzc29yCgllbWlzc2lvbkFjY2Vzc29yIHNyLkVtaXNzaW9uQWNjZXNzb3IKCW5mdEFjY2Vzc29yICAgICAgc3IuTkZUQWNjZXNzb3IKfQoKZnVuYyAocyAqc3Rha2VyVjEpIGdldFBvb2xzKCkgKlBvb2xzIHsKCXJldHVybiAmUG9vbHN7CgkJdHJlZTogcy5zdG9yZS5HZXRQb29scygpLAoJfQp9CgpmdW5jIChzICpzdGFrZXJWMSkgZ2V0UG9vbFRpZXIoKSAqUG9vbFRpZXIgewoJcmV0dXJuIE5ld1Bvb2xUaWVyQnkoCgkJcy5zdG9yZS5HZXRQb29sVGllck1lbWJlcnNoaXBzKCksCgkJcy5zdG9yZS5HZXRQb29sVGllclJhdGlvKCksCgkJcy5zdG9yZS5HZXRQb29sVGllckNvdW50cygpLAoJCXMuc3RvcmUuR2V0UG9vbFRpZXJMYXN0UmV3YXJkQ2FjaGVUaW1lc3RhbXAoKSwKCQlzLnN0b3JlLkdldFBvb2xUaWVyQ3VycmVudEVtaXNzaW9uKCksCgkJcy5zdG9yZS5HZXRQb29sVGllckdldEVtaXNzaW9uKCksCgkJcy5zdG9yZS5HZXRQb29sVGllckdldEhhbHZpbmdCbG9ja3NJblJhbmdlKCksCgkpCn0KCmZ1bmMgKHMgKnN0YWtlclYxKSB1cGRhdGVQb29sVGllcihfIGludCwgcmxtIHJlYWxtLCBwb29sVGllciAqUG9vbFRpZXIpIHsKCWVyciA6PSBzLnN0b3JlLlNldFBvb2xUaWVyTWVtYmVyc2hpcHMoMCwgcmxtLCBwb29sVGllci5tZW1iZXJzaGlwKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCWVyciA9IHMuc3RvcmUuU2V0UG9vbFRpZXJSYXRpbygwLCBybG0sIHBvb2xUaWVyLnRpZXJSYXRpbykKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCgllcnIgPSBzLnN0b3JlLlNldFBvb2xUaWVyQ291bnRzKDAsIHJsbSwgcG9vbFRpZXIuY291bnRzKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCWVyciA9IHMuc3RvcmUuU2V0UG9vbFRpZXJMYXN0UmV3YXJkQ2FjaGVUaW1lc3RhbXAoMCwgcmxtLCBwb29sVGllci5sYXN0UmV3YXJkQ2FjaGVUaW1lc3RhbXApCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJZXJyID0gcy5zdG9yZS5TZXRQb29sVGllckN1cnJlbnRFbWlzc2lvbigwLCBybG0sIHBvb2xUaWVyLmN1cnJlbnRFbWlzc2lvbikKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCgllcnIgPSBzLnN0b3JlLlNldFBvb2xUaWVyR2V0RW1pc3Npb24oMCwgcmxtLCBwb29sVGllci5nZXRFbWlzc2lvbikKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCgllcnIgPSBzLnN0b3JlLlNldFBvb2xUaWVyR2V0SGFsdmluZ0Jsb2Nrc0luUmFuZ2UoMCwgcmxtLCBwb29sVGllci5nZXRIYWx2aW5nQmxvY2tzSW5SYW5nZSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KfQoKZnVuYyAocyAqc3Rha2VyVjEpIGdldERlcG9zaXRzKCkgKkRlcG9zaXRzIHsKCXJldHVybiAmRGVwb3NpdHN7CgkJdHJlZTogcy5zdG9yZS5HZXREZXBvc2l0cygpLAoJfQp9CgpmdW5jIChzICpzdGFrZXJWMSkgZ2V0RXh0ZXJuYWxJbmNlbnRpdmVzKCkgKkV4dGVybmFsSW5jZW50aXZlcyB7CglyZXR1cm4gJkV4dGVybmFsSW5jZW50aXZlc3sKCQl0cmVlOiBzLnN0b3JlLkdldEV4dGVybmFsSW5jZW50aXZlcygpLAoJfQp9CgpmdW5jIChzICpzdGFrZXJWMSkgZ2V0RGVwb3NpdFJlc29sdmVyKGxwVG9rZW5JZCB1aW50NjQpICgqRGVwb3NpdFJlc29sdmVyLCBlcnJvcikgewoJZGVwb3NpdCwgZXJyIDo9IHMuZ2V0RGVwb3NpdChscFRva2VuSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gbmlsLCBlcnIKCX0KCXJldHVybiBOZXdEZXBvc2l0UmVzb2x2ZXIoZGVwb3NpdCksIG5pbAp9CgovLyBOZXdTdGFrZXJWMSBjb25zdHJ1Y3RzIGEgdmVyc2lvbiAxIHN0YWtlciBpbXBsZW1lbnRhdGlvbiBiYWNrZWQgYnkgdGhlIHN1cHBsaWVkIGFjY2Vzc29ycy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHN0YWtlclN0b3JlOiBQZXJzaXN0ZW50IHN0b3JhZ2UgYWNjZXNzb3IgZm9yIHBvb2xzLCBkZXBvc2l0cywgaW5jZW50aXZlcywgdGllciBzdGF0ZSwgYW5kIHJld2FyZCBib29ra2VlcGluZy4KLy8gICAtIHBvb2xBY2Nlc3NvcjogQWNjZXNzb3IgZm9yIHBvb2wgc3RhdGUgdXNlZCB3aGlsZSB1cGRhdGluZyBhbmQgcmVzb2x2aW5nIHN0YWtlZCBwb3NpdGlvbnMuCi8vICAgLSBlbWlzc2lvbkFjY2Vzc29yOiBBY2Nlc3NvciBmb3IgR05TIGVtaXNzaW9uIGRhdGEgdXNlZCB0byBjYWxjdWxhdGUgcmV3YXJkcy4KLy8gICAtIG5mdEFjY2Vzc29yOiBBY2Nlc3NvciBmb3IgdGhlIHBvc2l0aW9uIE5GVCBvd25lcnNoaXAgYW5kIHRva2VuIG9wZXJhdGlvbnMuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBzdGFrZXI6IE5ldyBzdGFrZXJWMSBpbXBsZW1lbnRhdGlvbiB3aXJlZCB0byB0aGUgc3VwcGxpZWQgc3RvcmUgYW5kIGFjY2Vzc29ycy4KZnVuYyBOZXdTdGFrZXJWMShzdGFrZXJTdG9yZSBzci5JU3Rha2VyU3RvcmUsIHBvb2xBY2Nlc3NvciBzci5Qb29sQWNjZXNzb3IsIGVtaXNzaW9uQWNjZXNzb3Igc3IuRW1pc3Npb25BY2Nlc3NvciwgbmZ0QWNjZXNzb3Igc3IuTkZUQWNjZXNzb3IpICpzdGFrZXJWMSB7CglyZXR1cm4gJnN0YWtlclYxewoJCXN0b3JlOiAgICAgICAgICAgIHN0YWtlclN0b3JlLAoJCXBvb2xBY2Nlc3NvcjogICAgIHBvb2xBY2Nlc3NvciwKCQllbWlzc2lvbkFjY2Vzc29yOiBlbWlzc2lvbkFjY2Vzc29yLAoJCW5mdEFjY2Vzc29yOiAgICAgIG5mdEFjY2Vzc29yLAoJfQp9Chq9QAofbWFuYWdlX3Bvb2xfdGllcl9hbmRfd2FybXVwLmdubxKZQHBhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJImNoYWluIgoJImNoYWluL3J1bnRpbWUiCgkidGltZSIKCgkiZ25vLmxhbmQvcC9nbm9zd2FwL3V0aWxzL3YxIgoKCSJnbm8ubGFuZC9yL2dub3N3YXAvYWNjZXNzL3YxIgoJImduby5sYW5kL3IvZ25vc3dhcC9oYWx0L3YxIgoJc3IgImduby5sYW5kL3IvZ25vc3dhcC9zdGFrZXIiCikKCmNvbnN0ICgKCU5PVF9FTUlTU0lPTl9UQVJHRVRfVElFUiB1aW50NjQgPSAwCikKCi8vIFNldFBvb2xUaWVyIGFzc2lnbnMgYSB0aWVyIGxldmVsIHRvIGEgcG9vbCBmb3IgaW50ZXJuYWwgR05TIGVtaXNzaW9uIHJld2FyZHMuCi8vIE9ubHkgYWRtaW4gb3IgZ292ZXJuYW5jZSBjYW4gY2FsbCB0aGlzIGZ1bmN0aW9uLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgdW5jaGFuZ2VkIGJ5IHRoZSBzdGFrZXIgcHJveHkuCi8vICAgLSBwb29sUGF0aDogRXhpc3RpbmcgcG9vbCBwYXRoIHdob3NlIGludGVybmFsIEdOUyBlbWlzc2lvbiB0aWVyIGlzIGJlaW5nIGFzc2lnbmVkLgovLyAgIC0gdGllcjogRW1pc3Npb24gdGllciB0byBhc3NpZ247IHZhbGlkIHZhbHVlcyBhcmUgYmVsb3cgQWxsVGllckNvdW50LCBpbmNsdWRpbmcgMCBmb3Igbm8gZW1pc3Npb24gdGFyZ2V0LgpmdW5jIChzICpzdGFrZXJWMSkgU2V0UG9vbFRpZXIoXyBpbnQsIHJsbSByZWFsbSwgcG9vbFBhdGggc3RyaW5nLCB0aWVyIHVpbnQ2NCkgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFN0YWtlcigpCgoJY2FsbGVyIDo9IHJsbS5QcmV2aW91cygpLkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzQWRtaW5PckdvdmVybmFuY2UoY2FsbGVyKQoKCWFzc2VydElzUG9vbEV4aXN0cyhzLCBwb29sUGF0aCkKCWFzc2VydElzVmFsaWRQb29sVGllcih0aWVyKQoKCS8vIElmIHRoZSB0aWVyIGlzIGFscmVhZHkgc2V0LCBkbyBub3RoaW5nCglwb29sVGllciA6PSBzLmdldFBvb2xUaWVyKCkKCXByZXZpb3VzVGllciA6PSBwb29sVGllci5DdXJyZW50VGllcihwb29sUGF0aCkKCWlmIHByZXZpb3VzVGllciA9PSB0aWVyIHsKCQlyZXR1cm4KCX0KCgljdXJyZW50VGltZSA6PSB0aW1lLk5vdygpLlVuaXgoKQoJcmV3YXJkUGVyU2Vjb25kLCB0aWVyUmV3YXJkcyA6PSBzLnNldFBvb2xUaWVyKDAsIHJsbSwgcG9vbFBhdGgsIHRpZXIsIGN1cnJlbnRUaW1lKQoKCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCWVtaXRTZXRQb29sVGllcigKCQlwcmV2aW91c1JlYWxtLkFkZHJlc3MoKS5TdHJpbmcoKSwKCQlwcmV2aW91c1JlYWxtLlBrZ1BhdGgoKSwKCQlwb29sUGF0aCwKCQl0aWVyLAoJCXJld2FyZFBlclNlY29uZCwKCQl0aWVyUmV3YXJkcywKCQlwb29sVGllci5jb3VudHMsCgkJY3VycmVudFRpbWUsCgkpCn0KCi8vIENoYW5nZVBvb2xUaWVyIG1vZGlmaWVzIHRoZSB0aWVyIGxldmVsIG9mIGFuIGV4aXN0aW5nIHBvb2wuCi8vIE9ubHkgYWRtaW4gb3IgZ292ZXJuYW5jZSBjYW4gY2FsbCB0aGlzIGZ1bmN0aW9uLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgdW5jaGFuZ2VkIGJ5IHRoZSBzdGFrZXIgcHJveHkuCi8vICAgLSBwb29sUGF0aDogRXhpc3RpbmcgcG9vbCBwYXRoIHdob3NlIGVtaXNzaW9uIHRpZXIgaXMgYmVpbmcgY2hhbmdlZC4KLy8gICAtIHRpZXI6IFJlcGxhY2VtZW50IGVtaXNzaW9uIHRpZXI7IHZhbHVlcyBhdCBvciBhYm92ZSBBbGxUaWVyQ291bnQgYXJlIHJlamVjdGVkLgpmdW5jIChzICpzdGFrZXJWMSkgQ2hhbmdlUG9vbFRpZXIoXyBpbnQsIHJsbSByZWFsbSwgcG9vbFBhdGggc3RyaW5nLCB0aWVyIHVpbnQ2NCkgewoJYWNjZXNzLkFzc2VydElzUmxtQ3VycmVudCgwLCBybG0pCgoJaGFsdC5Bc3NlcnRJc05vdEhhbHRlZFN0YWtlcigpCgoJcHJldmlvdXNSZWFsbSA6PSBybG0uUHJldmlvdXMoKQoJY2FsbGVyIDo9IHByZXZpb3VzUmVhbG0uQWRkcmVzcygpCglhY2Nlc3MuQXNzZXJ0SXNBZG1pbk9yR292ZXJuYW5jZShjYWxsZXIpCgoJYXNzZXJ0SXNQb29sRXhpc3RzKHMsIHBvb2xQYXRoKQoJYXNzZXJ0SXNWYWxpZFBvb2xUaWVyKHRpZXIpCgoJcG9vbFRpZXIgOj0gcy5nZXRQb29sVGllcigpCgoJLy8gSWYgdGhlIHRpZXIgaXMgYWxyZWFkeSBzZXQsIGRvIG5vdGhpbmcKCXByZXZpb3VzVGllciA6PSBwb29sVGllci5DdXJyZW50VGllcihwb29sUGF0aCkKCWlmIHByZXZpb3VzVGllciA9PSB0aWVyIHsKCQlyZXR1cm4KCX0KCgljdXJyZW50VGltZSA6PSB0aW1lLk5vdygpLlVuaXgoKQoJcHJldmlvdXNUaWVyLCBuZXdUaWVyLCByZXdhcmRQZXJTZWNvbmQsIHRpZXJSZXdhcmRzIDo9IHMuY2hhbmdlUG9vbFRpZXIoMCwgcmxtLCBwb29sUGF0aCwgdGllciwgY3VycmVudFRpbWUpCgoJY2hhaW4uRW1pdCgKCQkiQ2hhbmdlUG9vbFRpZXIiLAoJCSJwcmV2QWRkciIsIGNhbGxlci5TdHJpbmcoKSwKCQkicHJldlJlYWxtIiwgcHJldmlvdXNSZWFsbS5Qa2dQYXRoKCksCgkJInBvb2xQYXRoIiwgcG9vbFBhdGgsCgkJInByZXZUaWVyIiwgdXRpbHMuRm9ybWF0VWludChwcmV2aW91c1RpZXIpLAoJCSJuZXdUaWVyIiwgdXRpbHMuRm9ybWF0VWludChuZXdUaWVyKSwKCQkicmV3YXJkUGVyU2Vjb25kIiwgdXRpbHMuRm9ybWF0SW50KHJld2FyZFBlclNlY29uZCksCgkJInRpZXIxUmV3YXJkUGVyU2Vjb25kIiwgdXRpbHMuRm9ybWF0SW50KHRpZXJSZXdhcmRzW1RpZXIxXSksCgkJInRpZXIyUmV3YXJkUGVyU2Vjb25kIiwgdXRpbHMuRm9ybWF0SW50KHRpZXJSZXdhcmRzW1RpZXIyXSksCgkJInRpZXIzUmV3YXJkUGVyU2Vjb25kIiwgdXRpbHMuRm9ybWF0SW50KHRpZXJSZXdhcmRzW1RpZXIzXSksCgkJInRpZXIxQ291bnQiLCB1dGlscy5Gb3JtYXRVaW50KHBvb2xUaWVyLmNvdW50c1tUaWVyMV0pLAoJCSJ0aWVyMkNvdW50IiwgdXRpbHMuRm9ybWF0VWludChwb29sVGllci5jb3VudHNbVGllcjJdKSwKCQkidGllcjNDb3VudCIsIHV0aWxzLkZvcm1hdFVpbnQocG9vbFRpZXIuY291bnRzW1RpZXIzXSksCgkJImN1cnJlbnRUaW1lIiwgdXRpbHMuRm9ybWF0SW50KGN1cnJlbnRUaW1lKSwKCQkiY3VycmVudEhlaWdodCIsIHV0aWxzLkZvcm1hdEludChydW50aW1lLkNoYWluSGVpZ2h0KCkpLAoJKQp9CgovLyBSZW1vdmVQb29sVGllciByZW1vdmVzIGEgcG9vbCBmcm9tIGludGVybmFsIEdOUyBlbWlzc2lvbiByZXdhcmRzLgovLyBPbmx5IGFkbWluIG9yIGdvdmVybmFuY2UgY2FuIGNhbGwgdGhpcyBmdW5jdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIHVuY2hhbmdlZCBieSB0aGUgc3Rha2VyIHByb3h5LgovLyAgIC0gcG9vbFBhdGg6IEV4aXN0aW5nIHBvb2wgcGF0aCB0byByZW1vdmUgZnJvbSB0aGUgZW1pc3Npb24tdGllciBhY2NvdW50aW5nLgpmdW5jIChzICpzdGFrZXJWMSkgUmVtb3ZlUG9vbFRpZXIoXyBpbnQsIHJsbSByZWFsbSwgcG9vbFBhdGggc3RyaW5nKSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCgloYWx0LkFzc2VydElzTm90SGFsdGVkU3Rha2VyKCkKCglwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXIgOj0gcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkKCWFjY2Vzcy5Bc3NlcnRJc0FkbWluT3JHb3Zlcm5hbmNlKGNhbGxlcikKCglhc3NlcnRJc1Bvb2xFeGlzdHMocywgcG9vbFBhdGgpCgoJcG9vbFRpZXIgOj0gcy5nZXRQb29sVGllcigpCgoJLy8gSWYgdGhlIHRpZXIgaXMgYWxyZWFkeSBzZXQsIGRvIG5vdGhpbmcKCXByZXZpb3VzVGllciA6PSBwb29sVGllci5DdXJyZW50VGllcihwb29sUGF0aCkKCWlmIHByZXZpb3VzVGllciA9PSBOT1RfRU1JU1NJT05fVEFSR0VUX1RJRVIgewoJCXJldHVybgoJfQoKCWN1cnJlbnRUaW1lIDo9IHRpbWUuTm93KCkuVW5peCgpCglyZXdhcmRQZXJTZWNvbmQsIHRpZXJSZXdhcmRzIDo9IHMucmVtb3ZlUG9vbFRpZXIoMCwgcmxtLCBwb29sUGF0aCwgY3VycmVudFRpbWUpCgoJY2hhaW4uRW1pdCgKCQkiUmVtb3ZlUG9vbFRpZXIiLAoJCSJwcmV2QWRkciIsIGNhbGxlci5TdHJpbmcoKSwKCQkicHJldlJlYWxtIiwgcHJldmlvdXNSZWFsbS5Qa2dQYXRoKCksCgkJInBvb2xQYXRoIiwgcG9vbFBhdGgsCgkJInJld2FyZFBlclNlY29uZCIsIHV0aWxzLkZvcm1hdEludChyZXdhcmRQZXJTZWNvbmQpLAoJCSJ0aWVyMVJld2FyZFBlclNlY29uZCIsIHV0aWxzLkZvcm1hdEludCh0aWVyUmV3YXJkc1tUaWVyMV0pLAoJCSJ0aWVyMlJld2FyZFBlclNlY29uZCIsIHV0aWxzLkZvcm1hdEludCh0aWVyUmV3YXJkc1tUaWVyMl0pLAoJCSJ0aWVyM1Jld2FyZFBlclNlY29uZCIsIHV0aWxzLkZvcm1hdEludCh0aWVyUmV3YXJkc1tUaWVyM10pLAoJCSJ0aWVyMUNvdW50IiwgdXRpbHMuRm9ybWF0VWludChwb29sVGllci5jb3VudHNbVGllcjFdKSwKCQkidGllcjJDb3VudCIsIHV0aWxzLkZvcm1hdFVpbnQocG9vbFRpZXIuY291bnRzW1RpZXIyXSksCgkJInRpZXIzQ291bnQiLCB1dGlscy5Gb3JtYXRVaW50KHBvb2xUaWVyLmNvdW50c1tUaWVyM10pLAoJCSJjdXJyZW50VGltZSIsIHV0aWxzLkZvcm1hdEludChjdXJyZW50VGltZSksCgkJImN1cnJlbnRIZWlnaHQiLCB1dGlscy5Gb3JtYXRJbnQocnVudGltZS5DaGFpbkhlaWdodCgpKSwKCSkKfQoKLy8gU2V0V2FybVVwIGNvbmZpZ3VyZXMgdGhlIGR1cmF0aW9uIGZvciB0aGUgd2FybS11cCB0aWVyIHNlbGVjdGVkIGJ5IGl0cyBmaXhlZCByYXRpby4KLy8gRmluaXRlIHRpZXJzIGFyZSBjYXBwZWQgYXQgMzY1IGRheXM7IHRoZSBmaW5hbCAxMDAlIHRpZXIgbXVzdCByZW1haW4gbWF0aC5NYXhJbnQ2NC4KLy8gT25seSBhZG1pbiBvciBnb3Zlcm5hbmNlIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBOb25jcm9zc2luZyBpbXBsZW1lbnRhdGlvbi1jYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8gICAtIHJsbTogQ3VycmVudCByZWFsbSBjb250ZXh0IGZvcndhcmRlZCB1bmNoYW5nZWQgYnkgdGhlIHN0YWtlciBwcm94eS4KLy8gICAtIHBjdDogV2FybS11cCB0aWVyIHBlcmNlbnRhZ2Ugc2VsZWN0aW5nIG9uZSBvZiB0aGUgY29uZmlndXJlZCAzMCUsIDUwJSwgNzAlLCBvciAxMDAlIHRlbXBsYXRlcy4KLy8gICAtIHRpbWVEdXJhdGlvbjogV2FybS11cCBkdXJhdGlvbiBpbiBzZWNvbmRzOyBmaW5pdGUgdGllcnMgYXJlIGNhcHBlZCBhdCAzNjUgZGF5cyB3aGlsZSB0aGUgMTAwJSB0aWVyIHVzZXMgdGhlIG1heGltdW0gaW50NjQgZHVyYXRpb24uCmZ1bmMgKHMgKnN0YWtlclYxKSBTZXRXYXJtVXAoXyBpbnQsIHJsbSByZWFsbSwgcGN0LCB0aW1lRHVyYXRpb24gaW50NjQpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRTdGFrZXIoKQoKCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzQWRtaW5PckdvdmVybmFuY2UoY2FsbGVyKQoKCXMuc2V0V2FybVVwKDAsIHJsbSwgcGN0LCB0aW1lRHVyYXRpb24pCgoJY2hhaW4uRW1pdCgKCQkiU2V0V2FybVVwIiwKCQkicHJldkFkZHIiLCBjYWxsZXIuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCSJwY3QiLCB1dGlscy5Gb3JtYXRJbnQocGN0KSwKCQkidGltZUR1cmF0aW9uIiwgdXRpbHMuRm9ybWF0SW50KHRpbWVEdXJhdGlvbiksCgkpCn0KCi8vIHNldFBvb2xUaWVyIGludGVybmFsbHkgc2V0cyB0aGUgcG9vbCB0aWVyLgpmdW5jIChzICpzdGFrZXJWMSkgc2V0UG9vbFRpZXIoXyBpbnQsIHJsbSByZWFsbSwgcG9vbFBhdGggc3RyaW5nLCB0aWVyIHVpbnQ2NCwgY3VycmVudFRpbWUgaW50NjQpIChpbnQ2NCwgbWFwW3VpbnQ2NF1pbnQ2NCkgewoJcy5lbWlzc2lvbkFjY2Vzc29yLk1pbnRBbmREaXN0cmlidXRlR25zKDAsIHJsbSkKCglwb29sIDo9IHMuZ2V0UG9vbHMoKS5HZXRQb29sT3JOaWwocG9vbFBhdGgpCglpZiBwb29sID09IG5pbCB7CgkJcG9vbCA9IHNyLk5ld1Bvb2wocG9vbFBhdGgsIGN1cnJlbnRUaW1lKQoJCXMuZ2V0UG9vbHMoKS5zZXQocG9vbFBhdGgsIHBvb2wpCgl9Cglwb29sVGllciA6PSBzLmdldFBvb2xUaWVyKCkKCXRpZXJSZXdhcmRzIDo9IHBvb2xUaWVyLmNoYW5nZVRpZXIoY3VycmVudFRpbWUsIHMuZ2V0UG9vbHMoKSwgcG9vbFBhdGgsIHRpZXIpCgoJcy51cGRhdGVQb29sVGllcigwLCBybG0sIHBvb2xUaWVyKQoKCXJldHVybiBwb29sVGllci5jdXJyZW50RW1pc3Npb24sIHRpZXJSZXdhcmRzCn0KCi8vIGNoYW5nZVBvb2xUaWVyIGludGVybmFsbHkgY2hhbmdlcyB0aGUgcG9vbCB0aWVyIGFuZCByZXR1cm5zIG9sZCBhbmQgbmV3IHRpZXJzLgpmdW5jIChzICpzdGFrZXJWMSkgY2hhbmdlUG9vbFRpZXIoXyBpbnQsIHJsbSByZWFsbSwgcG9vbFBhdGggc3RyaW5nLCB0aWVyIHVpbnQ2NCwgY3VycmVudFRpbWUgaW50NjQpICh1aW50NjQsIHVpbnQ2NCwgaW50NjQsIG1hcFt1aW50NjRdaW50NjQpIHsKCXMuZW1pc3Npb25BY2Nlc3Nvci5NaW50QW5kRGlzdHJpYnV0ZUducygwLCBybG0pCglwb29sVGllciA6PSBzLmdldFBvb2xUaWVyKCkKCXByZXZpb3VzVGllciA6PSBwb29sVGllci5DdXJyZW50VGllcihwb29sUGF0aCkKCgl0aWVyUmV3YXJkcyA6PSBwb29sVGllci5jaGFuZ2VUaWVyKGN1cnJlbnRUaW1lLCBzLmdldFBvb2xzKCksIHBvb2xQYXRoLCB0aWVyKQoKCXMudXBkYXRlUG9vbFRpZXIoMCwgcmxtLCBwb29sVGllcikKCglyZXR1cm4gcHJldmlvdXNUaWVyLCB0aWVyLCBwb29sVGllci5jdXJyZW50RW1pc3Npb24sIHRpZXJSZXdhcmRzCn0KCi8vIHJlbW92ZVBvb2xUaWVyIGludGVybmFsbHkgcmVtb3ZlcyB0aGUgcG9vbCBmcm9tIHRpZXIgc3lzdGVtLgpmdW5jIChzICpzdGFrZXJWMSkgcmVtb3ZlUG9vbFRpZXIoXyBpbnQsIHJsbSByZWFsbSwgcG9vbFBhdGggc3RyaW5nLCBjdXJyZW50VGltZSBpbnQ2NCkgKGludDY0LCBtYXBbdWludDY0XWludDY0KSB7CglzLmVtaXNzaW9uQWNjZXNzb3IuTWludEFuZERpc3RyaWJ1dGVHbnMoMCwgcmxtKQoKCXBvb2xUaWVyIDo9IHMuZ2V0UG9vbFRpZXIoKQoJdGllclJld2FyZHMgOj0gcG9vbFRpZXIuY2hhbmdlVGllcihjdXJyZW50VGltZSwgcy5nZXRQb29scygpLCBwb29sUGF0aCwgTk9UX0VNSVNTSU9OX1RBUkdFVF9USUVSKQoJcy51cGRhdGVQb29sVGllcigwLCBybG0sIHBvb2xUaWVyKQoKCXJldHVybiBwb29sVGllci5jdXJyZW50RW1pc3Npb24sIHRpZXJSZXdhcmRzCn0KCi8vIHNldFdhcm1VcCBpbnRlcm5hbGx5IHNldHMgdGhlIHdhcm0tdXAgcGFyYW1ldGVycy4KZnVuYyAocyAqc3Rha2VyVjEpIHNldFdhcm1VcChfIGludCwgcmxtIHJlYWxtLCBwY3QsIHRpbWVEdXJhdGlvbiBpbnQ2NCkgewoJcy5lbWlzc2lvbkFjY2Vzc29yLk1pbnRBbmREaXN0cmlidXRlR25zKDAsIHJsbSkKCgl3YXJtdXBUZW1wbGF0ZSA6PSBzLnN0b3JlLkdldFdhcm11cFRlbXBsYXRlKCkKCXdhcm11cFRlbXBsYXRlID0gbW9kaWZ5V2FybXVwKHdhcm11cFRlbXBsYXRlLCBwY3RUb0luZGV4KHBjdCksIHRpbWVEdXJhdGlvbikKCgllcnIgOj0gcy5zdG9yZS5TZXRXYXJtdXBUZW1wbGF0ZSgwLCBybG0sIHdhcm11cFRlbXBsYXRlKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQp9CgovLyBwY3RUb0luZGV4IGNvbnZlcnRzIHBlcmNlbnRhZ2UgdG8gd2FybXVwIGluZGV4LgpmdW5jIHBjdFRvSW5kZXgocGN0IGludDY0KSBpbnQgewoJc3dpdGNoIHBjdCB7CgljYXNlIDMwOgoJCXJldHVybiAwCgljYXNlIDUwOgoJCXJldHVybiAxCgljYXNlIDcwOgoJCXJldHVybiAyCgljYXNlIDEwMDoKCQlyZXR1cm4gMwoJZGVmYXVsdDoKCQlwYW5pYygic3Rha2VyLmdub19fcGN0VG9JbmRleCgpIHx8IHBjdCBpcyBub3QgdmFsaWQiKQoJfQp9Chq9JAoacHJvdG9jb2xfZmVlX3Vuc3Rha2luZy5nbm8SniRwYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCSJjaGFpbiIKCSJlcnJvcnMiCgoJImduby5sYW5kL3AvZ25vc3dhcC9nbnNtYXRoL3YxIgoJcHJiYWMgImduby5sYW5kL3AvZ25vc3dhcC9yYmFjL3YxIgoJImduby5sYW5kL3AvZ25vc3dhcC91dGlscy92MSIKCSJnbm8ubGFuZC9yL2dub3N3YXAvYWNjZXNzL3YxIgoJImduby5sYW5kL3IvZ25vc3dhcC9jb21tb24iCgkiZ25vLmxhbmQvci9nbm9zd2FwL2hhbHQvdjEiCgoJcGYgImduby5sYW5kL3IvZ25vc3dhcC9wcm90b2NvbF9mZWUiCikKCi8vIEdldFVuc3Rha2luZ0ZlZSByZXR1cm5zIHRoZSBjdXJyZW50IHVuc3Rha2luZyBmZWUgcmF0ZSBpbiBiYXNpcyBwb2ludHMuCi8vCi8vIFJldHVybnM6Ci8vICAgLSB1aW50NjQ6IEN1cnJlbnQgZmVlIHJhdGUgaW4gYmFzaXMgcG9pbnRzOyAxMDAgYmFzaXMgcG9pbnRzIGVxdWFscyAxJS4KZnVuYyAocyAqc3Rha2VyVjEpIEdldFVuc3Rha2luZ0ZlZSgpIHVpbnQ2NCB7IHJldHVybiBzLnN0b3JlLkdldFVuc3Rha2luZ0ZlZSgpIH0KCi8vIGhhbmRsZVN0YWtpbmdSZXdhcmRGZWUgY2FsY3VsYXRlcyBhbmQgYXBwbGllcyB0aGUgdW5zdGFraW5nIGZlZS4KZnVuYyAocyAqc3Rha2VyVjEpIGhhbmRsZVN0YWtpbmdSZXdhcmRGZWUoCglfIGludCwKCXJsbSByZWFsbSwKCXRva2VuUGF0aCBzdHJpbmcsCglhbW91bnQgaW50NjQsCglpbnRlcm5hbCBib29sLAoJdW5zdGFraW5nRmVlIHVpbnQ2NCwKKSAoaW50NjQsIGludDY0LCBlcnJvcikgewoJaWYgaW50ZXJuYWwgewoJCXRva2VuUGF0aCA9IEdOU19UT0tFTl9LRVkKCX0KCglpZiB1bnN0YWtpbmdGZWUgPT0gMCB7CgkJcy5zZXR0bGVQcm90b2NvbEZlZSgwLCBybG0sIHRva2VuUGF0aCwgMCkKCQlyZXR1cm4gYW1vdW50LCAwLCBuaWwKCX0KCgkvLyBEbyBub3QgY2hhbmdlIHRoZSBvcmRlciBvZiB0aGUgb3BlcmF0aW9uLgoJZmVlQW1vdW50IDo9IGduc21hdGguU2FmZU11bERpdkludDY0KGFtb3VudCwgZ25zbWF0aC5TYWZlVWludDY0VG9JbnQ2NCh1bnN0YWtpbmdGZWUpLCAxMDAwMCkKCWlmIGZlZUFtb3VudCA8IDAgewoJCXJldHVybiAwLCAwLCBlcnJvcnMuTmV3KCJmZWUgYW1vdW50IGNhbm5vdCBiZSBuZWdhdGl2ZSIpCgl9CgoJaWYgZmVlQW1vdW50ID09IDAgewoJCXMuc2V0dGxlUHJvdG9jb2xGZWUoMCwgcmxtLCB0b2tlblBhdGgsIDApCgkJcmV0dXJuIGFtb3VudCwgMCwgbmlsCgl9CgoJcy5zZXR0bGVQcm90b2NvbEZlZSgwLCBybG0sIHRva2VuUGF0aCwgZmVlQW1vdW50KQoKCXJldHVybiBnbnNtYXRoLlNhZmVTdWJJbnQ2NChhbW91bnQsIGZlZUFtb3VudCksIGZlZUFtb3VudCwgbmlsCn0KCi8vIEdldFBlbmRpbmdQcm90b2NvbEZlZXMgcmV0dXJucyBwZW5kaW5nIHByb3RvY29sIGZlZSBhbW91bnRzIGtleWVkIGJ5IHJld2FyZC10b2tlbiBwYXRoLgovLwovLyBSZXR1cm5zOgovLyAgIC0gbWFwW3N0cmluZ11pbnQ2NDogUGVuZGluZyBmZWUgYW1vdW50IHBlciB0b2tlbiBwYXRoIGF3YWl0aW5nIGEgbGF0ZXIgc2V0dGxlbWVudC4KZnVuYyAocyAqc3Rha2VyVjEpIEdldFBlbmRpbmdQcm90b2NvbEZlZXMoKSBtYXBbc3RyaW5nXWludDY0IHsKCXJldHVybiBzLnN0b3JlLkdldFBlbmRpbmdQcm90b2NvbEZlZXMoKQp9CgpmdW5jIChzICpzdGFrZXJWMSkgYWRkUGVuZGluZ1Byb3RvY29sRmVlKF8gaW50LCBybG0gcmVhbG0sIHRva2VuUGF0aCBzdHJpbmcsIGFtb3VudCBpbnQ2NCkgewoJaWYgYW1vdW50IDw9IDAgewoJCXJldHVybgoJfQoKCXBlbmRpbmdBbW91bnQgOj0gZ25zbWF0aC5TYWZlQWRkSW50NjQocy5zdG9yZS5HZXRQZW5kaW5nUHJvdG9jb2xGZWUodG9rZW5QYXRoKSwgYW1vdW50KQoJaWYgZXJyIDo9IHMuc3RvcmUuU2V0UGVuZGluZ1Byb3RvY29sRmVlKDAsIHJsbSwgdG9rZW5QYXRoLCBwZW5kaW5nQW1vdW50KTsgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQp9CgovLyBzZXR0bGVQcm90b2NvbEZlZSBmb3J3YXJkcyBhbW91bnQsIHBsdXMgYW55dGhpbmcgYWxyZWFkeSBwZW5kaW5nIGZvciB0b2tlblBhdGgsIHRvCi8vIHRoZSBwcm90b2NvbCBmZWUgcmVhbG0uIFdoZW4gY29sbGVjdGlvbiBpcyBoYWx0ZWQgb3IgdGhlIHRyYW5zZmVyIGZhaWxzLCB0aGUgYW1vdW50Ci8vIGlzIHJlY29yZGVkIGFzIHBlbmRpbmcgaW5zdGVhZCBhbmQgc2V0dGxlZCBieSBhIGxhdGVyIGNhbGwgZm9yIHRoZSBzYW1lIHRva2VuLCB3aGljaAovLyBldmVyeSBmZWUgcGF0aCBtYWtlcyBldmVuIHdoZW4gdGhlIGZlZSBpcyB6ZXJvLgovLwovLyBPbmx5IHRva2VuUGF0aCBpcyB0b3VjaGVkLCBzbyBhbiB1bnJlbGF0ZWQgdG9rZW4gY2FuIG5ldmVyIGJsb2NrIHNldHRsZW1lbnQuIFRoZQovLyBwZW5kaW5nIGVudHJ5IGlzIHdyaXR0ZW4gb25seSB3aGVuIHRoZSBmZWUgY2Fubm90IGJlIGZvcndhcmRlZCwgc28gdGhlIGNvbW1vbiBwYXRoCi8vIHBlcmZvcm1zIG5vIHN0b3JlIHdyaXRlIGF0IGFsbC4KZnVuYyAocyAqc3Rha2VyVjEpIHNldHRsZVByb3RvY29sRmVlKF8gaW50LCBybG0gcmVhbG0sIHRva2VuUGF0aCBzdHJpbmcsIGFtb3VudCBpbnQ2NCkgewoJaWYgaGFsdC5Jc0hhbHRlZFByb3RvY29sRmVlKCkgewoJCXMuYWRkUGVuZGluZ1Byb3RvY29sRmVlKDAsIHJsbSwgdG9rZW5QYXRoLCBhbW91bnQpCgkJcmV0dXJuCgl9CgoJcGVuZGluZ0Ftb3VudCA6PSBzLnN0b3JlLkdldFBlbmRpbmdQcm90b2NvbEZlZSh0b2tlblBhdGgpCgl0b3RhbEFtb3VudCA6PSBnbnNtYXRoLlNhZmVBZGRJbnQ2NChwZW5kaW5nQW1vdW50LCBhbW91bnQpCgoJaWYgdG90YWxBbW91bnQgPiAwIHsKCQlwcm90b2NvbEZlZUFkZHIgOj0gYWNjZXNzLk11c3RHZXRBZGRyZXNzKHByYmFjLlJPTEVfUFJPVE9DT0xfRkVFLlN0cmluZygpKQoJCWNvbW1vbi5TYWZlR1JDMjBBcHByb3ZlKDAsIHJsbSwgdG9rZW5QYXRoLCBwcm90b2NvbEZlZUFkZHIsIHRvdGFsQW1vdW50KQoKCQkvLyBBZGRUb1Byb3RvY29sRmVlIG9ubHkgcmVwb3J0cyBhbiBlcnJvciBmb3IgYSBoYWx0ZWQgcmVhbG0sIHdoaWNoIGlzIGhhbmRsZWQKCQkvLyBhYm92ZS4gVGhlIGJyYW5jaCBrZWVwcyB0aGUgYW1vdW50IHBlbmRpbmcgc2hvdWxkIHRoYXQgZXZlciBjaGFuZ2UsIGFuZAoJCS8vIHdpdGhkcmF3cyB0aGUgYXBwcm92YWwgc28gbm8gdW5zcGVudCBhbGxvd2FuY2Ugb3V0bGl2ZXMgdGhlIGNhbGwuCgkJaWYgZXJyIDo9IHBmLkFkZFRvUHJvdG9jb2xGZWUoY3Jvc3MocmxtKSwgdG9rZW5QYXRoLCB0b3RhbEFtb3VudCk7IGVyciAhPSBuaWwgewoJCQljb21tb24uU2FmZUdSQzIwQXBwcm92ZSgwLCBybG0sIHRva2VuUGF0aCwgcHJvdG9jb2xGZWVBZGRyLCAwKQoJCQlzLmFkZFBlbmRpbmdQcm90b2NvbEZlZSgwLCBybG0sIHRva2VuUGF0aCwgYW1vdW50KQoJCQlyZXR1cm4KCQl9Cgl9CgoJaWYgZXJyIDo9IHMuc3RvcmUuUmVtb3ZlUGVuZGluZ1Byb3RvY29sRmVlKDAsIHJsbSwgdG9rZW5QYXRoKTsgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQp9CgovLyBTZXRVblN0YWtpbmdGZWUgc2V0cyB0aGUgdW5zdGFraW5nIGZlZSByYXRlIGluIGJhc2lzIHBvaW50cy4KLy8gT25seSBhZG1pbiBvciBnb3Zlcm5hbmNlIGNhbiBjYWxsIHRoaXMgZnVuY3Rpb24uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBJbnRlcm5hbCBjYWxsIGRpc2NyaW1pbmF0b3I7IGNhbGxlcnMgcGFzcyAwLgovLyAgIC0gcmxtOiBQcm9wYWdhdGVkIHJlYWxtIGNvbnRleHQ7IGl0IG11c3QgYmUgY3VycmVudCBiZWZvcmUgY2hhbmdpbmcgdGhlIHN0b3JlZCBmZWUuCi8vICAgLSBmZWU6IE5ldyB1bnN0YWtpbmcgZmVlIHJhdGUgaW4gYmFzaXMgcG9pbnRzLCB2YWxpZGF0ZWQgYWdhaW5zdCB0aGUgY29uZmlndXJlZCBtYXhpbXVtLgpmdW5jIChzICpzdGFrZXJWMSkgU2V0VW5TdGFraW5nRmVlKF8gaW50LCBybG0gcmVhbG0sIGZlZSB1aW50NjQpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRTdGFrZXIoKQoKCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCWNhbGxlciA6PSBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKQoJYWNjZXNzLkFzc2VydElzQWRtaW5PckdvdmVybmFuY2UoY2FsbGVyKQoKCWFzc2VydElzVmFsaWRGZWVSYXRlKGZlZSkKCglwcmV2VW5TdGFraW5nRmVlIDo9IHMuR2V0VW5zdGFraW5nRmVlKCkKCgllcnIgOj0gcy5zZXRVblN0YWtpbmdGZWUoMCwgcmxtLCBmZWUpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJY2hhaW4uRW1pdCgKCQkiU2V0VW5TdGFraW5nRmVlIiwKCQkicHJldkFkZHIiLCBjYWxsZXIuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCSJwcmV2RmVlIiwgdXRpbHMuRm9ybWF0VWludChwcmV2VW5TdGFraW5nRmVlKSwKCQkibmV3RmVlIiwgdXRpbHMuRm9ybWF0VWludChmZWUpLAoJKQp9CgovLyBzZXRVblN0YWtpbmdGZWUgaW50ZXJuYWxseSB1cGRhdGVzIHRoZSB1bnN0YWtpbmcgZmVlLgpmdW5jIChzICpzdGFrZXJWMSkgc2V0VW5TdGFraW5nRmVlKF8gaW50LCBybG0gcmVhbG0sIGZlZSB1aW50NjQpIGVycm9yIHsKCXJldHVybiBzLnN0b3JlLlNldFVuc3Rha2luZ0ZlZSgwLCBybG0sIGZlZSkKfQoa1BcKCnJlbmRlci5nbm8SxRdwYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCSJjaGFpbiIKCSJtYXRoIgoJInN0cmluZ3MiCgoJImduby5sYW5kL3AvbW91bC9tZC92MCIKCSJnbm8ubGFuZC9wL21vdWwvbWR0YWJsZS92MCIKCXVmbXQgImduby5sYW5kL3AvbnQvdWZtdC92MCIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2hhbHQvdjEiCglzdGFrZXJSb290ICJnbm8ubGFuZC9yL2dub3N3YXAvc3Rha2VyIgopCgpmdW5jIChzICpzdGFrZXJWMSkgUmVuZGVyKHBhdGggc3RyaW5nKSBzdHJpbmcgewoJaWYgcGF0aCAhPSAiIiB7CgkJcmV0dXJuICI0MDRcbiIKCX0KCgl0aWVyQ291bnRzIDo9IHMuc3RvcmUuR2V0UG9vbFRpZXJDb3VudHMoKQoJdGllclJhdGlvIDo9IHMuc3RvcmUuR2V0UG9vbFRpZXJSYXRpbygpCglpbXBsZW1lbnRhdGlvbiA6PSBzdGFrZXJSb290LkdldEltcGxlbWVudGF0aW9uUGFja2FnZVBhdGgoKQoKCW91dCA6PSBtZC5IMSgiR25vc3dhcCBTdGFrZXIiKQoJb3V0ICs9IG1kLlBhcmFncmFwaCgKCQkiQWxsIEdOUyBhbW91bnRzIHVzZSB0aGUgdG9rZW4ncyBzaXgtZGVjaW1hbCBiYXNlIHVuaXRzLiBFeHRlcm5hbCByZXdhcmQgYW1vdW50cyB1c2VcbiIgKwoJCQkidGhlIHJld2FyZCB0b2tlbidzIG93biBiYXNlIHVuaXRzLiIsCgkpCgoJb3V0ICs9IG1kLkgyKCJJbXBsZW1lbnRhdGlvbiIpCglpbXBsZW1lbnRhdGlvblRhYmxlIDo9IG1kdGFibGUuVGFibGV7CgkJSGVhZGVyczogW11zdHJpbmd7IkZpZWxkIiwgIlZhbHVlIn0sCgkJUm93czogW11bXXN0cmluZ3sKCQkJeyJSZWFsbSBhZGRyZXNzIiwgbWQuSW5saW5lQ29kZShjaGFpbi5QYWNrYWdlQWRkcmVzcygiZ25vLmxhbmQvci9nbm9zd2FwL3N0YWtlciIpLlN0cmluZygpKX0sCgkJCXsiQWN0aXZlIGltcGxlbWVudGF0aW9uIiwgbWQuTGluayhpbXBsZW1lbnRhdGlvbiwgc3RyaW5ncy5UcmltUHJlZml4KGltcGxlbWVudGF0aW9uLCAiZ25vLmxhbmQiKSl9LAoJCQl7IlN0YWtlciBvcGVyYXRpb25zIGhhbHRlZCIsIHVmbXQuU3ByaW50ZigiJXQiLCBoYWx0LklzSGFsdGVkU3Rha2VyKCkpfSwKCQl9LAoJfQoJb3V0ICs9IGltcGxlbWVudGF0aW9uVGFibGUuU3RyaW5nKCkKCglvdXQgKz0gbWQuSDIoIkFjY291bnRpbmcgYW5kIGNvbmZpZ3VyYXRpb24iKQoJYWNjb3VudGluZ1RhYmxlIDo9IG1kdGFibGUuVGFibGV7CgkJSGVhZGVyczogW11zdHJpbmd7IkZpZWxkIiwgIlZhbHVlIn0sCgkJUm93czogW11bXXN0cmluZ3sKCQkJeyJTdG9yZWQgcG9vbCByZWNvcmRzIiwgdWZtdC5TcHJpbnRmKCIlZCIsIHMuc3RvcmUuR2V0UG9vbHMoKS5TaXplKCkpfSwKCQkJeyJBY3RpdmUgc3Rha2VkLXBvc2l0aW9uIHJlY29yZHMiLCB1Zm10LlNwcmludGYoIiVkIiwgcy5zdG9yZS5HZXREZXBvc2l0cygpLlNpemUoKSl9LAoJCQl7IlN0b3JlZCBleHRlcm5hbCBpbmNlbnRpdmUgcmVjb3JkcyIsIHVmbXQuU3ByaW50ZigiJWQiLCBzLnN0b3JlLkdldEV4dGVybmFsSW5jZW50aXZlcygpLlNpemUoKSl9LAoJCQl7IlVuc3Rha2VkIGNoZWNrcG9pbnQgcmVjb3JkcyIsIHVmbXQuU3ByaW50ZigiJWQiLCBzLnN0b3JlLkdldFVuc3Rha2VkUG9zaXRpb25zKCkuU2l6ZSgpKX0sCgkJCXsiQ3VtdWxhdGl2ZSBHTlMgZW1pc3Npb24gc2VudCAoYmFzZSB1bml0czsgNiBkZWNpbWFscykiLCB1Zm10LlNwcmludGYoIiVkIiwgcy5zdG9yZS5HZXRUb3RhbEVtaXNzaW9uU2VudCgpKX0sCgkJCXsiQ2FjaGVkIEdOUyBlbWlzc2lvbiByYXRlIChiYXNlIHVuaXRzL3NlY29uZDsgNiBkZWNpbWFscykiLCB1Zm10LlNwcmludGYoIiVkIiwgcy5zdG9yZS5HZXRQb29sVGllckN1cnJlbnRFbWlzc2lvbigpKX0sCgkJCXsiUmVxdWlyZWQgR05TIGRlcG9zaXQgKEdOUyBiYXNlIHVuaXRzOyA2IGRlY2ltYWxzKSIsIHVmbXQuU3ByaW50ZigiJWQiLCBzLnN0b3JlLkdldERlcG9zaXRHbnNBbW91bnQoKSl9LAoJCQl7IkRlZmF1bHQgbWluaW11bSBleHRlcm5hbCBpbmNlbnRpdmUgcmV3YXJkIChyZXdhcmQtdG9rZW4gYmFzZSB1bml0cykiLCB1Zm10LlNwcmludGYoIiVkIiwgcy5zdG9yZS5HZXRNaW5pbXVtUmV3YXJkQW1vdW50KCkpfSwKCQkJeyJUaWVyIHBvb2wgY291bnRzICh0aWVyIDEgLyB0aWVyIDIgLyB0aWVyIDMpIiwgdWZtdC5TcHJpbnRmKCIlZCAvICVkIC8gJWQiLCB0aWVyQ291bnRzWzFdLCB0aWVyQ291bnRzWzJdLCB0aWVyQ291bnRzWzNdKX0sCgkJCXsiVGllciByZXdhcmQgc3BsaXQgKHRpZXIgMSAvIHRpZXIgMiAvIHRpZXIgMzsgcGVyY2VudCkiLCB1Zm10LlNwcmludGYoIiVkJSUgLyAlZCUlIC8gJWQlJSIsIHRpZXJSYXRpby5UaWVyMSwgdGllclJhdGlvLlRpZXIyLCB0aWVyUmF0aW8uVGllcjMpfSwKCQkJeyJVbnN0YWtpbmcgZmVlIiwgdWZtdC5TcHJpbnRmKCIlZCBicHMgKG1heGltdW0gJWQgYnBzKSIsIHMuc3RvcmUuR2V0VW5zdGFraW5nRmVlKCksIG1heFVuc3Rha2luZ0ZlZSl9LAoJCQl7IkFsbG93ZWQgZXh0ZXJuYWwgaW5jZW50aXZlIGR1cmF0aW9ucyIsICI5MCAvIDE4MCAvIDM2NSBkYXlzIn0sCgkJfSwKCX0KCW91dCArPSBhY2NvdW50aW5nVGFibGUuU3RyaW5nKCkKCglvdXQgKz0gbWQuSDIoIldhcm11cCBzdGFnZXMiKQoJd2FybXVwVGFibGUgOj0gbWR0YWJsZS5UYWJsZXsKCQlIZWFkZXJzOiBbXXN0cmluZ3siUmV3YXJkIHNoYXJlIiwgIkR1cmF0aW9uIHBlciBzdGFnZSJ9LAoJfQoJZm9yIF8sIHdhcm11cCA6PSByYW5nZSBzLnN0b3JlLkdldFdhcm11cFRlbXBsYXRlKCkgewoJCWR1cmF0aW9uIDo9IHVmbXQuU3ByaW50ZigiJWQgc2Vjb25kcyIsIHdhcm11cC5UaW1lRHVyYXRpb24pCgkJaWYgd2FybXVwLlRpbWVEdXJhdGlvbiA9PSBtYXRoLk1heEludDY0IHsKCQkJZHVyYXRpb24gPSAidW5ib3VuZGVkIgoJCX0KCQl3YXJtdXBUYWJsZS5BcHBlbmQoW11zdHJpbmd7CgkJCXVmbXQuU3ByaW50ZigiJWQlJSIsIHdhcm11cC5XYXJtdXBSYXRpbyksCgkJCWR1cmF0aW9uLAoJCX0pCgl9CglvdXQgKz0gd2FybXVwVGFibGUuU3RyaW5nKCkKCglyZXR1cm4gb3V0Cn0KGtFGCiFyZXdhcmRfY2FsY3VsYXRpb25faW5jZW50aXZlcy5nbm8Sq0ZwYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCSJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCXUyNTYgImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgoJYnB0cmVlICJnbm8ubGFuZC9wL250L2JwdHJlZS92MCIKCglzciAiZ25vLmxhbmQvci9nbm9zd2FwL3N0YWtlciIKKQoKdHlwZSBJbmNlbnRpdmVzUmVzb2x2ZXIgc3RydWN0IHsKCSpzci5JbmNlbnRpdmVzCn0KCi8vIE5ld0luY2VudGl2ZXNSZXNvbHZlciB3cmFwcyB0aGUgcGVyc2lzdGVkIGV4dGVybmFsLWluY2VudGl2ZSBzdGF0ZSBmb3IgbG9va3VwIGFuZCBtdXRhdGlvbi4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGluY2VudGl2ZXM6IEV4dGVybmFsIGluY2VudGl2ZSBzdGF0ZSBjb250YWluaW5nIHRoZSBpbmNlbnRpdmUgdHJlZSBhbmQgdW5jbGFpbWFibGUgcGVyaW9kcy4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHJlc29sdmVyOiBSZXNvbHZlciBiYWNrZWQgYnkgaW5jZW50aXZlcy4KZnVuYyBOZXdJbmNlbnRpdmVzUmVzb2x2ZXIoaW5jZW50aXZlcyAqc3IuSW5jZW50aXZlcykgKkluY2VudGl2ZXNSZXNvbHZlciB7CglyZXR1cm4gJkluY2VudGl2ZXNSZXNvbHZlcnsKCQlJbmNlbnRpdmVzOiBpbmNlbnRpdmVzLAoJfQp9CgovLyBHZXQgcmVzb2x2ZXMgYW4gZXh0ZXJuYWwgaW5jZW50aXZlIGJ5IGl0cyBpZGVudGlmaWVyLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gaW5jZW50aXZlSWQ6IEV4dGVybmFsIGluY2VudGl2ZSBpZGVudGlmaWVyIHVzZWQgYXMgdGhlIHRyZWUga2V5LgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW5jZW50aXZlOiBTdG9yZWQgZXh0ZXJuYWwgaW5jZW50aXZlIHBvaW50ZXIgd2hlbiB0aGUgSUQgZXhpc3RzOyBuaWwgd2hlbiBpdCBpcyBhYnNlbnQuCi8vICAgLSBmb3VuZDogVHJ1ZSB3aGVuIGluY2VudGl2ZUlkIGlzIHByZXNlbnQgaW4gdGhlIHRyZWU7IGZhbHNlIG90aGVyd2lzZS4KZnVuYyAoc2VsZiAqSW5jZW50aXZlc1Jlc29sdmVyKSBHZXQoaW5jZW50aXZlSWQgc3RyaW5nKSAoKnNyLkV4dGVybmFsSW5jZW50aXZlLCBib29sKSB7CglyZXR1cm4gcmV0cmlldmVJbmNlbnRpdmUoc2VsZi5JbmNlbnRpdmVUcmVlcygpLCBpbmNlbnRpdmVJZCkKfQoKLy8gR2V0SW5jZW50aXZlUmVzb2x2ZXIgcmVzb2x2ZXMgYW4gaW5jZW50aXZlIElEIHRvIGl0cyBmaWVsZCBhY2Nlc3Nvci4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGluY2VudGl2ZUlkOiBFeHRlcm5hbCBpbmNlbnRpdmUgaWRlbnRpZmllciB0byByZXNvbHZlLgovLwovLyBSZXR1cm5zOgovLyAgIC0gcmVzb2x2ZXI6IFJlc29sdmVyIGZvciB0aGUgc3RvcmVkIGluY2VudGl2ZSB3aGVuIGZvdW5kOyBuaWwgd2hlbiBpbmNlbnRpdmVJZCBpcyBhYnNlbnQuCi8vICAgLSBmb3VuZDogVHJ1ZSB3aGVuIGluY2VudGl2ZUlkIHJlc29sdmVzIHRvIGEgc3RvcmVkIGluY2VudGl2ZTsgZmFsc2Ugb3RoZXJ3aXNlLgpmdW5jIChzZWxmICpJbmNlbnRpdmVzUmVzb2x2ZXIpIEdldEluY2VudGl2ZVJlc29sdmVyKGluY2VudGl2ZUlkIHN0cmluZykgKCpFeHRlcm5hbEluY2VudGl2ZVJlc29sdmVyLCBib29sKSB7CglpZiBpbmNlbnRpdmUsIG9rIDo9IHNlbGYuR2V0KGluY2VudGl2ZUlkKTsgb2sgewoJCXJldHVybiBOZXdFeHRlcm5hbEluY2VudGl2ZVJlc29sdmVyKGluY2VudGl2ZSksIHRydWUKCX0KCXJldHVybiBuaWwsIGZhbHNlCn0KCmZ1bmMgcmV0cmlldmVJbmNlbnRpdmUodHJlZSAqYnB0cmVlLkJQVHJlZSwgaWQgc3RyaW5nKSAoKnNyLkV4dGVybmFsSW5jZW50aXZlLCBib29sKSB7Cgl2YWx1ZSA6PSB0cmVlLkdldChpZCkKCWlmIHZhbHVlID09IG5pbCB7CgkJcmV0dXJuIG5pbCwgZmFsc2UKCX0KCXYsIG9rIDo9IHZhbHVlLigqc3IuRXh0ZXJuYWxJbmNlbnRpdmUpCglpZiAhb2sgewoJCXBhbmljKCJmYWlsZWQgdG8gY2FzdCB2YWx1ZSB0byAqc3IuRXh0ZXJuYWxJbmNlbnRpdmUiKQoJfQoJcmV0dXJuIHYsIHRydWUKfQoKLy8gQ3JlYXRlIGEgbmV3IGV4dGVybmFsIGluY2VudGl2ZQovLyBQYW5pY3MgaWYgdGhlIGluY2VudGl2ZSBhbHJlYWR5IGV4aXN0cy4KZnVuYyAoc2VsZiAqSW5jZW50aXZlc1Jlc29sdmVyKSBjcmVhdGUoaW5jZW50aXZlICpzci5FeHRlcm5hbEluY2VudGl2ZSkgewoJc2VsZi5JbmNlbnRpdmVzLlNldEluY2VudGl2ZShpbmNlbnRpdmUuSW5jZW50aXZlSWQoKSwgaW5jZW50aXZlKQoJc2VsZi5JbmNlbnRpdmVzLkFkZEluY2VudGl2ZUJ5U3RhcnRUaW1lKGluY2VudGl2ZS5TdGFydFRpbWVzdGFtcCgpLCBpbmNlbnRpdmUuSW5jZW50aXZlSWQoKSkKfQoKLy8gdXBkYXRlIHVwZGF0ZXMgYW4gZXhpc3RpbmcgaW5jZW50aXZlIHdpdGggbmV3IGluZm9ybWF0aW9uCmZ1bmMgKHNlbGYgKkluY2VudGl2ZXNSZXNvbHZlcikgdXBkYXRlKGluY2VudGl2ZSAqc3IuRXh0ZXJuYWxJbmNlbnRpdmUpIHsKCXNlbGYuSW5jZW50aXZlcy5TZXRJbmNlbnRpdmUoaW5jZW50aXZlLkluY2VudGl2ZUlkKCksIGluY2VudGl2ZSkKfQoKLy8gcmVtb3ZlIGRyb3BzIGFuIGluY2VudGl2ZSBmcm9tIGJvdGggdGhlIGluY2VudGl2ZSB0cmVlIGFuZCB0aGUgc3RhcnQtdGltZQovLyBkaXNjb3ZlcnkgaW5kZXguIEl0IGlzIG9ubHkgdmFsaWQgZm9yIGFuIGluY2VudGl2ZSB0aGF0IGhhcyBub3Qgc3RhcnRlZDogbm8KLy8gZGVwb3NpdCBjYW4gcmVmZXJlbmNlIGl0IHlldCwgc28gbm90aGluZyBpcyBsZWZ0IHBvaW50aW5nIGF0IGEgbWlzc2luZyByZWNvcmQuCmZ1bmMgKHNlbGYgKkluY2VudGl2ZXNSZXNvbHZlcikgcmVtb3ZlKGluY2VudGl2ZSAqc3IuRXh0ZXJuYWxJbmNlbnRpdmUpIHsKCXNlbGYuSW5jZW50aXZlcy5SZW1vdmVJbmNlbnRpdmUoaW5jZW50aXZlLkluY2VudGl2ZUlkKCkpCglzZWxmLkluY2VudGl2ZXMuUmVtb3ZlSW5jZW50aXZlQnlTdGFydFRpbWUoaW5jZW50aXZlLlN0YXJ0VGltZXN0YW1wKCksIGluY2VudGl2ZS5JbmNlbnRpdmVJZCgpKQp9CgovLyBzdGFydHMgaW5jZW50aXZlIHVuY2xhaW1hYmxlIHBlcmlvZCBmb3IgdGhpcyBwb29sCmZ1bmMgKHNlbGYgKkluY2VudGl2ZXNSZXNvbHZlcikgc3RhcnRVbmNsYWltYWJsZVBlcmlvZChzdGFydFRpbWVzdGFtcCBpbnQ2NCkgewoJc2VsZi5JbmNlbnRpdmVzLlNldFVuY2xhaW1hYmxlUGVyaW9kKHN0YXJ0VGltZXN0YW1wLCBpbnQ2NCgwKSkKfQoKLy8gZW5kcyBpbmNlbnRpdmUgdW5jbGFpbWFibGUgcGVyaW9kIGZvciB0aGlzIHBvb2wKLy8gaWdub3JlcyBpZiBjdXJyZW50bHkgbm90IGluIHVuY2xhaW1hYmxlIHBlcmlvZApmdW5jIChzZWxmICpJbmNlbnRpdmVzUmVzb2x2ZXIpIGVuZFVuY2xhaW1hYmxlUGVyaW9kKGVuZFRpbWVzdGFtcCBpbnQ2NCkgewoJc3RhcnRUaW1lc3RhbXAgOj0gaW50NjQoMCkKCXNlbGYuVW5jbGFpbWFibGVQZXJpb2RzKCkuUmV2ZXJzZUl0ZXJhdGUoMCwgZW5kVGltZXN0YW1wLCBmdW5jKGtleSBpbnQ2NCwgdmFsdWUgYW55KSBib29sIHsKCQl2LCBvayA6PSB2YWx1ZS4oaW50NjQpCgkJaWYgIW9rIHsKCQkJcGFuaWMoImZhaWxlZCB0byBjYXN0IHZhbHVlIHRvIGludDY0IikKCQl9CgkJaWYgdiAhPSAwIHsKCQkJLy8gQWxyZWFkeSBlbmRlZCwgbm8gbmVlZCB0byB1cGRhdGUKCQkJLy8ga2VlcGluZyBzdGFydFRpbWVzdGFtcCBhcyAwIHRvIGluZGljYXRlIHRoaXMKCQkJcmV0dXJuIHRydWUKCQl9CgkJc3RhcnRUaW1lc3RhbXAgPSBrZXkKCQlyZXR1cm4gdHJ1ZQoJfSkKCglpZiBzdGFydFRpbWVzdGFtcCA9PSAwIHsKCQkvLyBObyBvbmdvaW5nIHVuY2xhaW1hYmxlIHBlcmlvZCBmb3VuZAoJCXJldHVybgoJfQoKCWlmIHN0YXJ0VGltZXN0YW1wID09IGVuZFRpbWVzdGFtcCB7CgkJc2VsZi5JbmNlbnRpdmVzLlJlbW92ZVVuY2xhaW1hYmxlUGVyaW9kKHN0YXJ0VGltZXN0YW1wKQoJfSBlbHNlIHsKCQlzZWxmLkluY2VudGl2ZXMuU2V0VW5jbGFpbWFibGVQZXJpb2Qoc3RhcnRUaW1lc3RhbXAsIGVuZFRpbWVzdGFtcCkKCX0KCgkvLyBBY2N1bXVsYXRlIHRoZSBqdXN0LWNsb3NlZCBwZXJpb2QgaW50byBldmVyeSBhY3RpdmUgaW5jZW50aXZlCglzZWxmLmFjY3VtdWxhdGVVbmNsYWltYWJsZVNlY29uZHMoc3RhcnRUaW1lc3RhbXAsIGVuZFRpbWVzdGFtcCkKfQoKLy8gYWNjdW11bGF0ZVVuY2xhaW1hYmxlU2Vjb25kcyBhZGRzIHRoZSB1bmNsYWltYWJsZSBkdXJhdGlvbiBiZXR3ZWVuCi8vIHN0YXJ0VGltZXN0YW1wIGFuZCBlbmRUaW1lc3RhbXAgdG8gZXZlcnkgbm9uLXJlZnVuZGVkIGluY2VudGl2ZSB3aG9zZSB3aW5kb3cKLy8gb3ZlcmxhcHMgdGhlIHBlcmlvZC4gVGhlIGFjY3VtdWxhdG9yIGlzIHVwZGF0ZWQgaW4gcGxhY2Ugb24gdGhlIHN0b3JlZAovLyBpbmNlbnRpdmUgcG9pbnRlcnMsIHNvIG5vIHRyZWUgd3JpdGUgaXMgcmVxdWlyZWQgaGVyZS4KZnVuYyAoc2VsZiAqSW5jZW50aXZlc1Jlc29sdmVyKSBhY2N1bXVsYXRlVW5jbGFpbWFibGVTZWNvbmRzKHN0YXJ0VGltZXN0YW1wLCBlbmRUaW1lc3RhbXAgaW50NjQpIHsKCXNlbGYuSW5jZW50aXZlcy5JdGVyYXRlSW5jZW50aXZlcyhmdW5jKF8gc3RyaW5nLCBpbmNlbnRpdmUgKnNyLkV4dGVybmFsSW5jZW50aXZlKSBib29sIHsKCQlpZiBpbmNlbnRpdmUuUmVmdW5kZWQoKSB7CgkJCXJldHVybiBmYWxzZQoJCX0KCgkJZHVyYXRpb24gOj0gY2FsY3VsYXRlVW5DbGFpbWFibGVEdXJhdGlvbigKCQkJc3RhcnRUaW1lc3RhbXAsCgkJCWVuZFRpbWVzdGFtcCwKCQkJaW5jZW50aXZlLlN0YXJ0VGltZXN0YW1wKCksCgkJCWluY2VudGl2ZS5FbmRUaW1lc3RhbXAoKSwKCQkpCgkJaWYgZHVyYXRpb24gPiAwIHsKCQkJaW5jZW50aXZlLlNldFVuY2xhaW1hYmxlU2Vjb25kcyhnbnNtYXRoLlNhZmVBZGRJbnQ2NChpbmNlbnRpdmUuVW5jbGFpbWFibGVTZWNvbmRzKCksIGR1cmF0aW9uKSkKCQl9CgkJcmV0dXJuIGZhbHNlCgl9KQp9CgovLyBjYWxjdWxhdGUgdW5jbGFpbWFibGUgcmV3YXJkIGZyb20gdGhlIHBlci1pbmNlbnRpdmUgdW5jbGFpbWFibGUgc2Vjb25kcwovLyBhY2N1bXVsYXRvciBpbnN0ZWFkIG9mIHNjYW5uaW5nIHRoZSB1bmJvdW5kZWQgdW5jbGFpbWFibGUgcGVyaW9kcyB0cmVlLgpmdW5jIChzZWxmICpJbmNlbnRpdmVzUmVzb2x2ZXIpIGNhbGN1bGF0ZVVuY2xhaW1hYmxlUmV3YXJkKGluY2VudGl2ZUlkIHN0cmluZykgaW50NjQgewoJaW5jZW50aXZlLCBvayA6PSBzZWxmLkdldChpbmNlbnRpdmVJZCkKCWlmICFvayB7CgkJcmV0dXJuIDAKCX0KCgkvLyBUaGUgYWNjdW11bGF0b3IgaG9sZHMgdGhlIGR1cmF0aW9uIG9mIGV2ZXJ5IGNsb3NlZCB1bmNsYWltYWJsZSBwZXJpb2QKCS8vIHRoYXQgb3ZlcmxhcHMgdGhlIGluY2VudGl2ZSB3aW5kb3cuCgl0aW1lRGlmZiA6PSBpbmNlbnRpdmUuVW5jbGFpbWFibGVTZWNvbmRzKCkKCgkvLyBPbmdvaW5nIHVuY2xhaW1hYmxlIHBlcmlvZHMgKGVuZCA9PSAwKSBhcmUgbm90IHlldCBhY2N1bXVsYXRlZCBiZWNhdXNlCgkvLyB0aGVpciBlbmQgaXMgdW5rbm93bi4gVGhleSBhcmUgcmVzb2x2ZWQgaGVyZSBieSB0cmVhdGluZyB0aGVtIGFzCgkvLyBleHRlbmRpbmcgdG8gdGhlIGluY2VudGl2ZSBlbmQuIFVuY2xhaW1hYmxlIHBlcmlvZHMgbmV2ZXIgb3ZlcmxhcCBhbmQKCS8vIGFyZSByZWNvcmRlZCBpbiBhc2NlbmRpbmcgb3JkZXIsIHNvIGFuIG9uZ29pbmcgcGVyaW9kIGlzIGFsd2F5cyB0aGUKCS8vIG1vc3QgcmVjZW50bHkgc3RhcnRlZCBvbmUgYW5kIHRoZXJlZm9yZSB0aGUgaGlnaGVzdCBrZXkgaW4gdGhlIHRyZWUuCgkvLyBSZXZlcnNlSXRlcmF0ZSB2aXNpdHMgdGhlIGhpZ2hlc3Qga2V5IGZpcnN0LCBzbyBlYWNoIHNjYW4gYmVsb3cgZmluZHMKCS8vIHRoZSBvbmx5IG9uZ29pbmcgcGVyaW9kIHRoYXQgY2FuIGFmZmVjdCB0aGUgcmV3YXJkIChpZiBhbnkpIG9uIGl0cwoJLy8gZmlyc3QgdmlzaXQgYW5kIHN0b3BzIC0gdGhlIHNjYW4gaXMgYm91bmRlZCByZWdhcmRsZXNzIG9mIGhvdyBtYW55CgkvLyBwZXJpb2RzIGV4aXN0IGluIHRoZSB0cmVlLgoJLy8KCS8vIFRhaWwgMTogdGhlIG9uZ29pbmcgcGVyaW9kIHRoYXQgc3RhcnRlZCBiZWZvcmUgdGhlIGluY2VudGl2ZSB3aW5kb3cKCS8vIChlLmcuIHRoZSBpbml0aWFsIHBvb2wtY3JlYXRpb24gcGVyaW9kKS4gSWYgdGhlIGhpZ2hlc3QgcGVyaW9kIHN0YXJ0aW5nCgkvLyBiZWZvcmUgdGhlIHdpbmRvdyBpcyBhbHJlYWR5IGNsb3NlZCwgbm8gb25nb2luZyBwZXJpb2QgY2FuIG92ZXJsYXAgdGhlCgkvLyBpbmNlbnRpdmUgc3RhcnQgYW5kIHRoZXJlIGlzIG5vdGhpbmcgdG8gYWRkLgoJc2VsZi5VbmNsYWltYWJsZVBlcmlvZHMoKS5SZXZlcnNlSXRlcmF0ZSgwLCBpbmNlbnRpdmUuU3RhcnRUaW1lc3RhbXAoKS0xLCBmdW5jKHN0YXJ0VGltZXN0YW1wIGludDY0LCB2YWx1ZSBhbnkpIGJvb2wgewoJCWVuZFRpbWVzdGFtcCwgb2sgOj0gdmFsdWUuKGludDY0KQoJCWlmICFvayB7CgkJCXBhbmljKCJmYWlsZWQgdG8gY2FzdCB2YWx1ZSB0byBpbnQ2NCIpCgkJfQoJCWlmIGVuZFRpbWVzdGFtcCAhPSAwIHsKCQkJLy8gQWxyZWFkeSBjbG9zZWQgLSB0aGUgZHVyYXRpb24gaXMgYWxyZWFkeSBhY2N1bXVsYXRlZCBpbgoJCQkvLyBVbmNsYWltYWJsZVNlY29uZHMoKSwgYW5kIGJlaW5nIHRoZSBoaWdoZXN0IGtleSBpdCBpcyBhbHNvIHRoZQoJCQkvLyBsYXRlc3QgcGVyaW9kLCBzbyBubyBvbmdvaW5nIHBlcmlvZCBjYW4gZXhpc3QgYmVsb3cgaXQuCgkJCXJldHVybiB0cnVlCgkJfQoKCQl0aW1lRGlmZiA9IGduc21hdGguU2FmZUFkZEludDY0KHRpbWVEaWZmLCBjYWxjdWxhdGVVbkNsYWltYWJsZUR1cmF0aW9uKAoJCQlzdGFydFRpbWVzdGFtcCwKCQkJaW5jZW50aXZlLkVuZFRpbWVzdGFtcCgpLAoJCQlpbmNlbnRpdmUuU3RhcnRUaW1lc3RhbXAoKSwKCQkJaW5jZW50aXZlLkVuZFRpbWVzdGFtcCgpLAoJCSkpCgkJcmV0dXJuIHRydWUKCX0pCgoJLy8gVGFpbCAyOiB0aGUgb25nb2luZyBwZXJpb2QgdGhhdCBzdGFydGVkIHdpdGhpbiB0aGUgaW5jZW50aXZlIHdpbmRvdy4KCS8vIFRoZSB1cHBlciBib3VuZCBpcyBlbmRUaW1lLTEgdG8gbWlycm9yIHRoZSBJdGVyYXRlKHN0YXJ0LCBlbmQpCgkvLyBoYWxmLW9wZW4gcmFuZ2UsIHdoaWNoIGV4Y2x1ZGVzIGEgcGVyaW9kIHN0YXJ0aW5nIGV4YWN0bHkgYXQgZW5kVGltZQoJLy8gKGUuZy4gdGhlIGluaXRpYWwgcG9vbC1jcmVhdGlvbiBwZXJpb2QgdGhhdCBjb2luY2lkZXMgd2l0aCBlbmRUaW1lKS4KCXNlbGYuVW5jbGFpbWFibGVQZXJpb2RzKCkuUmV2ZXJzZUl0ZXJhdGUoaW5jZW50aXZlLlN0YXJ0VGltZXN0YW1wKCksIGluY2VudGl2ZS5FbmRUaW1lc3RhbXAoKS0xLCBmdW5jKHN0YXJ0VGltZXN0YW1wIGludDY0LCB2YWx1ZSBhbnkpIGJvb2wgewoJCWVuZFRpbWVzdGFtcCwgb2sgOj0gdmFsdWUuKGludDY0KQoJCWlmICFvayB7CgkJCXBhbmljKCJmYWlsZWQgdG8gY2FzdCB2YWx1ZSB0byBpbnQ2NCIpCgkJfQoJCWlmIGVuZFRpbWVzdGFtcCAhPSAwIHsKCQkJLy8gQWxyZWFkeSBjbG9zZWQgLSB0aGUgZHVyYXRpb24gaXMgYWxyZWFkeSBhY2N1bXVsYXRlZCBpbgoJCQkvLyBVbmNsYWltYWJsZVNlY29uZHMoKSwgYW5kIGJlaW5nIHRoZSBoaWdoZXN0IGtleSBpdCBpcyBhbHNvIHRoZQoJCQkvLyBsYXRlc3QgcGVyaW9kLCBzbyBubyBvbmdvaW5nIHBlcmlvZCBjYW4gZXhpc3QgYmVsb3cgaXQuCgkJCXJldHVybiB0cnVlCgkJfQoKCQl0aW1lRGlmZiA9IGduc21hdGguU2FmZUFkZEludDY0KHRpbWVEaWZmLCBjYWxjdWxhdGVVbkNsYWltYWJsZUR1cmF0aW9uKAoJCQlzdGFydFRpbWVzdGFtcCwKCQkJaW5jZW50aXZlLkVuZFRpbWVzdGFtcCgpLAoJCQlpbmNlbnRpdmUuU3RhcnRUaW1lc3RhbXAoKSwKCQkJaW5jZW50aXZlLkVuZFRpbWVzdGFtcCgpLAoJCSkpCgkJcmV0dXJuIHRydWUKCX0pCgoJLy8gcmV3YXJkUGVyU2Vjb25kWDEyOCA9IHJwcyA8PCAxMjgsIHNvIGRpdmlkaW5nIGJ5IHExMjggaGVyZSByZWNvdmVycyB0aGUKCS8vIGZsb29yIG9mICh0aW1lRGlmZiAqIHJwcykgd2l0aG91dCB0aGUgdHJ1bmNhdGlvbiB0aGF0IGFuIGludDY0IHJwcyB3b3VsZAoJLy8gaGF2ZSBpbnRyb2R1Y2VkIGF0IGluY2VudGl2ZS1jcmVhdGlvbiB0aW1lLgoJdW5jbGFpbWFibGUgOj0gdTI1Ni5NdWxEaXYoCgkJdTI1Ni5OZXdVaW50RnJvbUludDY0KHRpbWVEaWZmKSwKCQlpbmNlbnRpdmUuUmV3YXJkUGVyU2Vjb25kWDEyOCgpLAoJCXExMjgsCgkpCglyZXR1cm4gZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQodW5jbGFpbWFibGUpCn0KCi8vIGNhbGN1bGF0ZVVuQ2xhaW1hYmxlRHVyYXRpb24gY2FsY3VsYXRlcyB0aGUgZHVyYXRpb24gb2Ygb3ZlcmxhcCBiZXR3ZWVuIGFuIHVuY2xhaW1hYmxlIHBlcmlvZCBhbmQgaW5jZW50aXZlIHBlcmlvZApmdW5jIGNhbGN1bGF0ZVVuQ2xhaW1hYmxlRHVyYXRpb24odW5jbGFpbWFibGVTdGFydCwgdW5jbGFpbWFibGVFbmQsIGluY2VudGl2ZVN0YXJ0VGltZXN0YW1wLCBpbmNlbnRpdmVFbmRUaW1lc3RhbXAgaW50NjQpIGludDY0IHsKCS8vIFVzZSBsYXRlciB0aW1lc3RhbXAgYmV0d2VlbiB1bmNsYWltYWJsZSBzdGFydCBhbmQgaW5jZW50aXZlIHN0YXJ0CglzdGFydFRpbWUgOj0gdW5jbGFpbWFibGVTdGFydAoJaWYgc3RhcnRUaW1lIDwgaW5jZW50aXZlU3RhcnRUaW1lc3RhbXAgewoJCXN0YXJ0VGltZSA9IGluY2VudGl2ZVN0YXJ0VGltZXN0YW1wCgl9CgoJLy8gVXNlIGVhcmxpZXIgdGltZXN0YW1wIGJldHdlZW4gdW5jbGFpbWFibGUgZW5kIGFuZCBpbmNlbnRpdmUgZW5kCgllbmRUaW1lIDo9IHVuY2xhaW1hYmxlRW5kCglpZiBlbmRUaW1lID4gaW5jZW50aXZlRW5kVGltZXN0YW1wIHsKCQllbmRUaW1lID0gaW5jZW50aXZlRW5kVGltZXN0YW1wCgl9CgoJLy8gUmV0dXJuIDAgaWYgbm8gb3ZlcmxhcAoJaWYgZW5kVGltZSA8IHN0YXJ0VGltZSB7CgkJcmV0dXJuIDAKCX0KCgkvLyBDYWxjdWxhdGUgb3ZlcmxhcCBkdXJhdGlvbgoJcmV0dXJuIGduc21hdGguU2FmZVN1YkludDY0KGVuZFRpbWUsIHN0YXJ0VGltZSkKfQoajN8BChtyZXdhcmRfY2FsY3VsYXRpb25fcG9vbC5nbm8S694BcGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkiZXJyb3JzIgoJIm1hdGgiCgkidGltZSIKCgkiZ25vLmxhbmQvcC9nbm9zd2FwL2duc21hdGgvdjEiCglicHRyZWUgImduby5sYW5kL3AvbnQvYnB0cmVlL3YwIgoJdWZtdCAiZ25vLmxhbmQvcC9udC91Zm10L3YwIgoKCWkyNTYgImduby5sYW5kL3AvZ25vc3dhcC9pbnQyNTYvdjEiCgl1MjU2ICJnbm8ubGFuZC9wL2dub3N3YXAvdWludDI1Ni92MSIKCXNyICJnbm8ubGFuZC9yL2dub3N3YXAvc3Rha2VyIgopCgp2YXIgcTEyOCA9IHUyNTYuTXVzdEZyb21EZWNpbWFsKCIzNDAyODIzNjY5MjA5Mzg0NjM0NjMzNzQ2MDc0MzE3NjgyMTE0NTYiKQoKLy8gUG9vbHMgcmVwcmVzZW50cyB0aGUgZ2xvYmFsIHBvb2wgc3RvcmFnZQp0eXBlIFBvb2xzIHN0cnVjdCB7Cgl0cmVlICpicHRyZWUuQlBUcmVlIC8vIHN0cmluZyBwb29sUGF0aCAtPiBwb29sCn0KCi8vIE5ld1Bvb2xzIGNyZWF0ZXMgYW4gZW1wdHkgcmVzb2x2ZXIgZm9yIGdsb2JhbCBwb29sIHN0b3JhZ2UuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBwb29sczogUG9vbHMgcmVzb2x2ZXIgYmFja2VkIGJ5IGEgbmV3IEIrIHRyZWUga2V5ZWQgYnkgcG9vbCBwYXRoLgpmdW5jIE5ld1Bvb2xzKCkgKlBvb2xzIHsKCXJldHVybiAmUG9vbHN7CgkJdHJlZTogc3IuTmV3QlBUcmVlTigxNiksCgl9Cn0KCi8vIEdldCByZXR1cm5zIHRoZSBwb29sIHN0b3JlZCB1bmRlciB0aGUgZ2l2ZW4gcG9vbCBwYXRoLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IFBvb2wgcGF0aCB1c2VkIGFzIHRoZSBzdG9yYWdlIGtleS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHBvb2w6IFN0b3JlZCBwb29sIHBvaW50ZXIgd2hlbiBwb29sUGF0aCBleGlzdHM7IG5pbCB3aGVuIGFic2VudC4KLy8gICAtIGZvdW5kOiBUcnVlIHdoZW4gcG9vbFBhdGggcmVzb2x2ZXMgdG8gYSBwb29sOyBmYWxzZSB3aGVuIG5vIGVudHJ5IGV4aXN0cy4KZnVuYyAoc2VsZiAqUG9vbHMpIEdldChwb29sUGF0aCBzdHJpbmcpICgqc3IuUG9vbCwgYm9vbCkgewoJdiA6PSBzZWxmLnRyZWUuR2V0KHBvb2xQYXRoKQoJaWYgdiA9PSBuaWwgewoJCXJldHVybiBuaWwsIGZhbHNlCgl9CglwLCBvayA6PSB2Ligqc3IuUG9vbCkKCWlmICFvayB7CgkJcGFuaWModWZtdC5TcHJpbnRmKCJmYWlsZWQgdG8gY2FzdCB2IHRvICpQb29sOiAlVCIsIHYpKQoJfQoJcmV0dXJuIHAsIHRydWUKfQoKLy8gR2V0UG9vbE9yTmlsIHJldHVybnMgdGhlIHBvb2wgZm9yIHRoZSBnaXZlbiBwb29sIHBhdGgsIG9yIG5pbCB3aGVuIGl0IGRvZXMgbm90IGV4aXN0LgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IFBvb2wgcGF0aCB1c2VkIGFzIHRoZSBzdG9yYWdlIGtleS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHBvb2w6IFN0b3JlZCBwb29sIHBvaW50ZXIsIG9yIG5pbCB3aGVuIHBvb2xQYXRoIGlzIGFic2VudC4KZnVuYyAoc2VsZiAqUG9vbHMpIEdldFBvb2xPck5pbChwb29sUGF0aCBzdHJpbmcpICpzci5Qb29sIHsKCXBvb2wsIG9rIDo9IHNlbGYuR2V0KHBvb2xQYXRoKQoJaWYgIW9rIHsKCQlyZXR1cm4gbmlsCgl9CglyZXR1cm4gcG9vbAp9CgovLyBzZXQgc2V0cyB0aGUgcG9vbCBmb3IgdGhlIGdpdmVuIHBvb2xQYXRoLgpmdW5jIChzZWxmICpQb29scykgc2V0KHBvb2xQYXRoIHN0cmluZywgcG9vbCAqc3IuUG9vbCkgewoJc2VsZi50cmVlLlNldChwb29sUGF0aCwgcG9vbCkKfQoKLy8gSGFzIHJlcG9ydHMgd2hldGhlciBhIHBvb2wgZXhpc3RzIGZvciB0aGUgZ2l2ZW4gcG9vbCBwYXRoLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9vbFBhdGg6IFBvb2wgcGF0aCB1c2VkIGFzIHRoZSBzdG9yYWdlIGtleS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGV4aXN0czogVHJ1ZSB3aGVuIHBvb2xQYXRoIGlzIHByZXNlbnQgaW4gdGhlIHBvb2wgdHJlZTsgZmFsc2Ugb3RoZXJ3aXNlLgpmdW5jIChzZWxmICpQb29scykgSGFzKHBvb2xQYXRoIHN0cmluZykgYm9vbCB7CglyZXR1cm4gc2VsZi50cmVlLkhhcyhwb29sUGF0aCkKfQoKLy8gSXRlcmF0ZUFsbCB2aXNpdHMgZXZlcnkgc3RvcmVkIHBvb2wgdW50aWwgdGhlIGNhbGxiYWNrIHJlcXVlc3RzIHRoYXQgdHJhdmVyc2FsIHN0b3AuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBmbjogQ2FsbGJhY2sgcmVjZWl2aW5nIGVhY2ggcG9vbCBwYXRoIGFuZCBwb29sIHBvaW50ZXI7IHJldHVybiB0cnVlIHRvIHN0b3AgaXRlcmF0aW9uLCBmYWxzZSB0byBjb250aW51ZS4KZnVuYyAoc2VsZiAqUG9vbHMpIEl0ZXJhdGVBbGwoZm4gZnVuYyhrZXkgc3RyaW5nLCBwb29sICpzci5Qb29sKSBib29sKSB7CglzZWxmLnRyZWUuSXRlcmF0ZSgiIiwgIiIsIGZ1bmMoa2V5IHN0cmluZywgdmFsdWUgYW55KSBib29sIHsKCQlwLCBvayA6PSB2YWx1ZS4oKnNyLlBvb2wpCgkJaWYgIW9rIHsKCQkJcGFuaWModWZtdC5TcHJpbnRmKCJmYWlsZWQgdG8gY2FzdCB2YWx1ZSB0byAqUG9vbDogJVQiLCB2YWx1ZSkpCgkJfQoJCXJldHVybiBmbihrZXksIHApCgl9KQp9Cgp0eXBlIFBvb2xSZXNvbHZlciBzdHJ1Y3QgewoJKnNyLlBvb2wKCgkvLyBleGl0IGlzIHNldCBvbmx5IHdoZW4gY29sbGVjdGluZyBhbiBleGl0IGNoZWNrcG9pbnQsIGFuZCBvdmVycmlkZXMgdGhlIHBvb2wgcmVhZHMgdGhhdAoJLy8gd291bGQgb3RoZXJ3aXNlIGNvbWUgZnJvbSBzdGF0ZSB0aGUgcG9zaXRpb24gbm8gbG9uZ2VyIHRha2VzIHBhcnQgaW4uCglleGl0ICpzci5VbnN0YWtlZFBvc2l0aW9uCn0KCi8vIEluY2VudGl2ZXNSZXNvbHZlciByZXR1cm5zIGEgcmVzb2x2ZXIgb3ZlciB0aGUgcG9vbCdzIGV4dGVybmFsLWluY2VudGl2ZSBzdGF0ZS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHJlc29sdmVyOiBJbmNlbnRpdmVzIHJlc29sdmVyIGJhY2tlZCBieSB0aGlzIHBvb2wncyBpbmNlbnRpdmUgdHJlZSBhbmQgdW5jbGFpbWFibGUgcGVyaW9kcy4KZnVuYyAoc2VsZiAqUG9vbFJlc29sdmVyKSBJbmNlbnRpdmVzUmVzb2x2ZXIoKSAqSW5jZW50aXZlc1Jlc29sdmVyIHsKCXJldHVybiBOZXdJbmNlbnRpdmVzUmVzb2x2ZXIoc2VsZi5JbmNlbnRpdmVzKCkpCn0KCi8vIEN1cnJlbnRHbG9iYWxSZXdhcmRSYXRpb0FjY3VtdWxhdGlvbiByZXR1cm5zIHRoZSBsYXRlc3Qgc3RvcmVkIGdsb2JhbCByZXdhcmQtcmF0aW8gY2hlY2twb2ludCBpbiB0aGUgWzAsIGN1cnJlbnRUaW1lXSByYW5nZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnRUaW1lOiBVbml4IHRpbWVzdGFtcCBib3VuZGluZyB0aGUgY2hlY2twb2ludCBsb29rdXAuCi8vCi8vIFJldHVybnM6Ci8vICAgLSB0aW1lOiBUaW1lc3RhbXAgb2YgdGhlIGxhdGVzdCBzdG9yZWQgY2hlY2twb2ludCBhdCBvciBiZWZvcmUgY3VycmVudFRpbWU7IHplcm8gd2hlbiBubyBjaGVja3BvaW50IGV4aXN0cy4KLy8gICAtIGFjYzogRGVjaW1hbC1lbmNvZGVkIFExMjgtc2NhbGVkIGdsb2JhbCByZXdhcmQtcmF0aW8gYWNjdW11bGF0aW9uIGF0IHRpbWUuCmZ1bmMgKHNlbGYgKlBvb2xSZXNvbHZlcikgQ3VycmVudEdsb2JhbFJld2FyZFJhdGlvQWNjdW11bGF0aW9uKGN1cnJlbnRUaW1lIGludDY0KSAodGltZSBpbnQ2NCwgYWNjIHN0cmluZykgewoJYWNjID0gIjAiCgoJc2VsZi5HbG9iYWxSZXdhcmRSYXRpb0FjY3VtdWxhdGlvbigpLlJldmVyc2VJdGVyYXRlKDAsIGN1cnJlbnRUaW1lLCBmdW5jKGtleSBpbnQ2NCwgdmFsdWUgYW55KSBib29sIHsKCQl0aW1lID0ga2V5CgoJCXZhbHVlU3RyLCBvayA6PSB2YWx1ZS4oc3RyaW5nKQoJCWlmICFvayB7CgkJCXBhbmljKHVmbXQuU3ByaW50ZigiZmFpbGVkIHRvIGNhc3QgdmFsdWUgdG8gc3RyaW5nOiAlVCIsIHZhbHVlKSkKCQl9CgoJCWFjYyA9IHZhbHVlU3RyCgoJCXJldHVybiB0cnVlCgl9KQoKCXJldHVybiB0aW1lLCBhY2MKfQoKLy8gQ3VycmVudFRpY2sgcmV0dXJucyB0aGUgbGF0ZXN0IGhpc3RvcmljYWwgdGljayBpbiB0aGUgWzAsIGN1cnJlbnRUaW1lXSByYW5nZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnRUaW1lOiBVbml4IHRpbWVzdGFtcCBib3VuZGluZyB0aGUgaGlzdG9yaWNhbC10aWNrIGxvb2t1cC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHRpY2s6IExhdGVzdCBoaXN0b3JpY2FsIHRpY2sgYXQgb3IgYmVmb3JlIGN1cnJlbnRUaW1lOyBhbiBleGl0IHJlc29sdmVyIHVzZXMgaXRzIHBpbm5lZCBleGl0IHRpY2sgYXQgb3IgYWZ0ZXIgZXhpdCB0aW1lLgpmdW5jIChzZWxmICpQb29sUmVzb2x2ZXIpIEN1cnJlbnRUaWNrKGN1cnJlbnRUaW1lIGludDY0KSAodGljayBpbnQzMikgewoJaWYgc2VsZi5leGl0ICE9IG5pbCAmJiBjdXJyZW50VGltZSA+PSBzZWxmLmV4aXQuRXhpdFRpbWUoKSB7CgkJcmV0dXJuIHNlbGYuZXhpdC5FeGl0VGljaygpCgl9CgoJc2VsZi5IaXN0b3JpY2FsVGljaygpLlJldmVyc2VJdGVyYXRlKDAsIGN1cnJlbnRUaW1lLCBmdW5jKGtleSBpbnQ2NCwgdmFsdWUgYW55KSBib29sIHsKCQlyZXMsIG9rIDo9IHZhbHVlLihpbnQzMikKCQlpZiAhb2sgewoJCQlwYW5pYyh1Zm10LlNwcmludGYoImZhaWxlZCB0byBjYXN0IHZhbHVlIHRvIGludDMyOiAlVCIsIHZhbHVlKSkKCQl9CgkJdGljayA9IHJlcwoJCXJldHVybiB0cnVlCgl9KQoJcmV0dXJuIHRpY2sKfQoKLy8gQ3VycmVudFN0YWtlZExpcXVpZGl0eSByZXR1cm5zIHRoZSBsYXRlc3Qgc3Rha2VkLWxpcXVpZGl0eSBjaGVja3BvaW50IGluIHRoZSBbMCwgY3VycmVudFRpbWVdIHJhbmdlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gY3VycmVudFRpbWU6IFVuaXggdGltZXN0YW1wIGJvdW5kaW5nIHRoZSBzdGFrZWQtbGlxdWlkaXR5IGxvb2t1cC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGxpcXVpZGl0eTogVWludDI1NiBzdGFrZWQgbGlxdWlkaXR5IGVmZmVjdGl2ZSBhdCBvciBiZWZvcmUgY3VycmVudFRpbWU7IHplcm8gd2hlbiBubyBjaGVja3BvaW50IGV4aXN0cy4KZnVuYyAoc2VsZiAqUG9vbFJlc29sdmVyKSBDdXJyZW50U3Rha2VkTGlxdWlkaXR5KGN1cnJlbnRUaW1lIGludDY0KSAobGlxdWlkaXR5ICp1MjU2LlVpbnQpIHsKCWxpcXVpZGl0eSA9IHUyNTYuWmVybygpCgoJc2VsZi5TdGFrZWRMaXF1aWRpdHkoKS5SZXZlcnNlSXRlcmF0ZSgwLCBjdXJyZW50VGltZSwgZnVuYyhrZXkgaW50NjQsIHZhbHVlIGFueSkgYm9vbCB7CgkJcmVzLCBvayA6PSB2YWx1ZS4oKnUyNTYuVWludCkKCQlpZiAhb2sgewoJCQlwYW5pYyh1Zm10LlNwcmludGYoImZhaWxlZCB0byBjYXN0IHZhbHVlIHRvICp1MjU2LlVpbnQ6ICVUIiwgdmFsdWUpKQoJCX0KCQlsaXF1aWRpdHkgPSByZXMKCQlyZXR1cm4gdHJ1ZQoJfSkKCXJldHVybiBsaXF1aWRpdHkKfQoKLy8gR2V0T3JOZXdUaWNrIHJldHVybnMgdGhlIGV4aXN0aW5nIHRpY2sgb3IgYSBuZXcgemVyby12YWx1ZWQgdGljay4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHRpY2tJZDogQm91bmRhcnkgdGljayBpZGVudGlmaWVyIHRvIHJldHJpZXZlIG9yIGluaXRpYWxpemUuCi8vCi8vIFJldHVybnM6Ci8vICAgLSB0aWNrOiBFeGlzdGluZyBzdG9yZWQgdGljaywgb3IgYSB6ZXJvLXZhbHVlZCB0aWNrIHdpdGggdGlja0lkIHdoZW4gbm8gZW50cnkgZXhpc3RzLgovLwovLyBTdWJzdGl0dXRpbmcgYSB6ZXJvLXZhbHVlZCB0aWNrIG9uIGEgcmVhZCBpcyBzYWZlIGJlY2F1c2UgdGlja3MgYXJlIHBydW5lZAovLyBvbmx5IHdoZW4gdGhlaXIgc3Rha2VkIGdyb3NzIGxpcXVpZGl0eSByZWFjaGVzIHplcm8sIGluIHRoZSBzYW1lIGNhbGwgdGhhdAovLyByZW1vdmVzIHRoZSBsYXN0IGRlcG9zaXQgcmVmZXJlbmNpbmcgdGhlbS4KZnVuYyAoc2VsZiAqUG9vbFJlc29sdmVyKSBHZXRPck5ld1RpY2sodGlja0lkIGludDMyKSAqc3IuVGljayB7CglpZiBzZWxmLmV4aXQgIT0gbmlsIHsKCQlpZiBsb3dlclRpY2sgOj0gc2VsZi5leGl0Lkxvd2VyVGljaygpOyBsb3dlclRpY2sgIT0gbmlsICYmIGxvd2VyVGljay5JZCgpID09IHRpY2tJZCB7CgkJCXJldHVybiBsb3dlclRpY2sKCQl9CgkJaWYgdXBwZXJUaWNrIDo9IHNlbGYuZXhpdC5VcHBlclRpY2soKTsgdXBwZXJUaWNrICE9IG5pbCAmJiB1cHBlclRpY2suSWQoKSA9PSB0aWNrSWQgewoJCQlyZXR1cm4gdXBwZXJUaWNrCgkJfQoJfQoKCXRpY2sgOj0gc2VsZi5UaWNrcygpLkdldCh0aWNrSWQpCglpZiB0aWNrID09IG5pbCB7CgkJcmV0dXJuIHNyLk5ld1RpY2sodGlja0lkKQoJfQoJcmV0dXJuIHRpY2sKfQoKLy8gaW5pdGlhbGl6ZU5ld1RpY2tPdXRzaWRlQWNjdW11bGF0aW9uIHNlZWRzIGEganVzdC1jcmVhdGVkIGJvdW5kYXJ5IHRpY2sgc28KLy8gdGhhdCBiZWxvdyh0aWNrKSA9PSBnbG9iYWxBY2N1bXVsYXRpb24gaG9sZHMsIGtlZXBpbmcgdGhlIHRocmVlIGJyYW5jaGVzIG9mCi8vIG91dHNpZGVBY2N1bXVsYXRpb25BdCByZXR1cm5zIGEgYm91bmRhcnkgdGljaydzIG91dHNpZGUgYWNjdW11bGF0aW9uIGF0IGN1cnJlbnRUaW1lLgovLwovLyBBbiBleGl0IGNoZWNrcG9pbnQgYW5zd2VycyBmb3IgaXRzIG93biBleGl0IHRpbWVzdGFtcCBmcm9tIHRoZSB2YWx1ZSBwaW5uZWQgd2hlbiBpdCB3YXMKLy8gd3JpdHRlbjogYSB0aWNrIGNyb3NzIGxhdGVyIGluIHRoZSBzYW1lIGJsb2NrIG92ZXJ3cml0ZXMgdGhlIGVudHJ5IGF0IHRoYXQgdGltZXN0YW1wLCB3aGlsZQovLyBlYXJsaWVyIGVudHJpZXMgY2FuIG5vIGxvbmdlciBjaGFuZ2UuCmZ1bmMgKHNlbGYgKlBvb2xSZXNvbHZlcikgb3V0c2lkZUFjY3VtdWxhdGlvbkF0KHRpY2tJZCBpbnQzMiwgY3VycmVudFRpbWUgaW50NjQpICp1MjU2LlVpbnQgewoJaWYgc2VsZi5leGl0ICE9IG5pbCAmJiBjdXJyZW50VGltZSA9PSBzZWxmLmV4aXQuRXhpdFRpbWUoKSB7CgkJc3dpdGNoIHRpY2tJZCB7CgkJY2FzZSBzZWxmLmV4aXQuRGVwb3NpdCgpLlRpY2tMb3dlcigpOgoJCQlyZXR1cm4gdTI1Ni5NdXN0RnJvbURlY2ltYWwoc2VsZi5leGl0Lkxvd2VyT3V0c2lkZUFjYygpKQoJCWNhc2Ugc2VsZi5leGl0LkRlcG9zaXQoKS5UaWNrVXBwZXIoKToKCQkJcmV0dXJuIHUyNTYuTXVzdEZyb21EZWNpbWFsKHNlbGYuZXhpdC5VcHBlck91dHNpZGVBY2MoKSkKCQl9Cgl9CgoJcmV0dXJuIE5ld1RpY2tSZXNvbHZlcihzZWxmLkdldE9yTmV3VGljayh0aWNrSWQpKS5DdXJyZW50T3V0c2lkZUFjY3VtdWxhdGlvbihjdXJyZW50VGltZSkKfQoKLy8gQ2FsY3VsYXRlUmF3UmV3YXJkRm9yUG9zaXRpb24gY29uc2lzdGVudC4KZnVuYyAoc2VsZiAqUG9vbFJlc29sdmVyKSBpbml0aWFsaXplTmV3VGlja091dHNpZGVBY2N1bXVsYXRpb24oY3VycmVudFRpbWUgaW50NjQsIGN1cnJlbnRUaWNrLCB0aWNrSWQgaW50MzIsIHRpY2sgKnNyLlRpY2spIHsKCWlmIHRpY2tJZCA+IGN1cnJlbnRUaWNrIHsKCQlyZXR1cm4KCX0KCglnbG9iYWxBY2MsIF8gOj0gc2VsZi5nbG9iYWxSZXdhcmRSYXRpb0FjY3VtdWxhdGlvbkF0KGN1cnJlbnRUaW1lKQoJdGljay5TZXRPdXRzaWRlQWNjdW11bGF0aW9uQXQoY3VycmVudFRpbWUsIGdsb2JhbEFjYykKfQoKLy8gSXNFeHRlcm5hbGx5SW5jZW50aXZpemVkUG9vbCByZXBvcnRzIHdoZXRoZXIgdGhlIHBvb2wgaGFzIGFueSBleHRlcm5hbCBpbmNlbnRpdmUgdGhhdCBoYXMgbm90IGVuZGVkLAovLyBpbmNsdWRpbmcgaW5jZW50aXZlcyB3aG9zZSBzdGFydCB0aW1lIGlzIHN0aWxsIGluIHRoZSBmdXR1cmUuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbmNlbnRpdml6ZWQ6IFRydWUgd2hlbiBhdCBsZWFzdCBvbmUgbm9uLWVuZGVkIGV4dGVybmFsIGluY2VudGl2ZSBpcyBpbmRleGVkIGZvciB0aGUgcG9vbDsgZmFsc2Ugd2hlbiBhbGwgYXJlIGVuZGVkIG9yIG5vbmUgZXhpc3QuCmZ1bmMgKHNlbGYgKlBvb2xSZXNvbHZlcikgSXNFeHRlcm5hbGx5SW5jZW50aXZpemVkUG9vbCgpIGJvb2wgewoJY3VycmVudFRpbWUgOj0gdGltZS5Ob3coKS5Vbml4KCkKCWhhc0luY2VudGl2ZSA6PSBmYWxzZQoJLy8gV2l0aCBhIG1heGltdW0gZHVyYXRpb24gb2YgMzY1IGRheXMsIG9sZGVyIHN0YXJ0cyBoYXZlIGFscmVhZHkgZW5kZWQuCgkvLyBLZWVwIGZ1dHVyZSBzdGFydHMgZWxpZ2libGUgYW5kIHJldGFpbiBoaXN0b3JpY2FsIHJlY29yZHMgZm9yIHJld2FyZCBjbGFpbXMuCglzZWxmLkluY2VudGl2ZXMoKS5JdGVyYXRlSW5jZW50aXZlSWRzQnlUaW1lKHN0YWtlU2Nhbkxvd2VyQm91bmQoY3VycmVudFRpbWUpLCBtYXRoLk1heEludDY0LCBmdW5jKGluY2VudGl2ZUlkIHN0cmluZykgYm9vbCB7CgkJaW5jZW50aXZlLCBvayA6PSBzZWxmLkluY2VudGl2ZXMoKS5JbmNlbnRpdmUoaW5jZW50aXZlSWQpCgkJaWYgIW9rIHsKCQkJcGFuaWMoImluY2VudGl2ZSBtaXNzaW5nIGZyb20gcG9vbCBzdGFydC10aW1lIGluZGV4IikKCQl9CgoJCXJlc29sdmVyIDo9IE5ld0V4dGVybmFsSW5jZW50aXZlUmVzb2x2ZXIoaW5jZW50aXZlKQoJCWlmICFyZXNvbHZlci5Jc0VuZGVkKGN1cnJlbnRUaW1lKSB7CgkJCWhhc0luY2VudGl2ZSA9IHRydWUKCQkJcmV0dXJuIHRydWUKCQl9CgoJCXJldHVybiBmYWxzZQoJfSkKCglyZXR1cm4gaGFzSW5jZW50aXZlCn0KCi8vIEN1cnJlbnRSZXdhcmQgcmV0dXJucyB0aGUgbGF0ZXN0IGNhY2hlZCBwZXItcG9vbCByZXdhcmQgcmF0ZSBpbiB0aGUgWzAsIGN1cnJlbnRUaW1lXSByYW5nZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnRUaW1lOiBVbml4IHRpbWVzdGFtcCBib3VuZGluZyB0aGUgcmV3YXJkLWNhY2hlIGxvb2t1cC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHJld2FyZDogTGF0ZXN0IGNhY2hlZCBHTlMgcmV3YXJkIHJhdGUgYXQgb3IgYmVmb3JlIGN1cnJlbnRUaW1lLCBpbiB1bml0cyBwZXIgc2Vjb25kOyB6ZXJvIHdoZW4gbm8gY2hlY2twb2ludCBleGlzdHMuCmZ1bmMgKHNlbGYgKlBvb2xSZXNvbHZlcikgQ3VycmVudFJld2FyZChjdXJyZW50VGltZSBpbnQ2NCkgKHJld2FyZCBpbnQ2NCkgewoJc2VsZi5SZXdhcmRDYWNoZSgpLlJldmVyc2VJdGVyYXRlKDAsIGN1cnJlbnRUaW1lLCBmdW5jKGtleSBpbnQ2NCwgdmFsdWUgYW55KSBib29sIHsKCQlyZXMsIG9rIDo9IHZhbHVlLihpbnQ2NCkKCQlpZiAhb2sgewoJCQlwYW5pYyh1Zm10LlNwcmludGYoImZhaWxlZCB0byBjYXN0IHZhbHVlIHRvIGludDY0OiAlVCIsIHZhbHVlKSkKCQl9CgkJcmV3YXJkID0gcmVzCgkJcmV0dXJuIHRydWUKCX0pCglyZXR1cm4gcmV3YXJkCn0KCmZ1bmMgKHNlbGYgKlBvb2xSZXNvbHZlcikgaXNDaGFuZ2VkVGljayhjdXJyZW50VGltZSBpbnQ2NCwgY3VycmVudFRpY2sgaW50MzIpIGJvb2wgewoJaWYgc2VsZi5IaXN0b3JpY2FsVGljaygpLlNpemUoKSA9PSAwIHsKCQlyZXR1cm4gdHJ1ZQoJfQoKCXByZXZpb3VzVGljayA6PSBzZWxmLkN1cnJlbnRUaWNrKGN1cnJlbnRUaW1lKQoKCXJldHVybiBwcmV2aW91c1RpY2sgIT0gY3VycmVudFRpY2sKfQoKLy8gY2FjaGVSZXdhcmQgc2V0cyB0aGUgY3VycmVudCByZXdhcmQgZm9yIHRoZSBwb29sCi8vIElmIHRoZSBwb29sIGlzIGluIHVuY2xhaW1hYmxlIHBlcmlvZCwgaXQgd2lsbCBlbmQgdGhlIHVuY2xhaW1hYmxlIHBlcmlvZCwgdXBkYXRlcyB0aGUgcmV3YXJkLCBhbmQgc3RhcnQgdGhlIHVuY2xhaW1hYmxlIHBlcmlvZCBhZ2Fpbi4KLy8KLy8gSW1wb3J0YW50IGJlaGF2aW9yIGZvciBpbml0aWFsIHRpZXIgYXNzaWdubWVudDoKLy8gLSBXaGVuIGEgcG9vbCBmaXJzdCByZWNlaXZlcyBhIHRpZXIsIG9sZFRpZXJSZXdhcmQ9MCBhbmQgY3VycmVudFRpZXJSZXdhcmQ+MAovLyAtIElmIHRoZSBwb29sIGhhcyB6ZXJvIGxpcXVpZGl0eSBhdCB0aGlzIHBvaW50LCBzdGFydFVuY2xhaW1hYmxlUGVyaW9kKCkgaXMgY2FsbGVkCi8vIC0gVGhpcyBlbnN1cmVzIHVuY2xhaW1hYmxlIHBlcmlvZCB0cmFja2luZyBiZWdpbnMgZnJvbSB0aGUgbW9tZW50IHJld2FyZHMgc3RhcnQgZW1pdHRpbmcKZnVuYyAoc2VsZiAqUG9vbFJlc29sdmVyKSBjYWNoZVJld2FyZChjdXJyZW50VGltZSBpbnQ2NCwgY3VycmVudFRpZXJSZXdhcmQgaW50NjQpIHsKCW9sZFRpZXJSZXdhcmQgOj0gc2VsZi5DdXJyZW50UmV3YXJkKGN1cnJlbnRUaW1lKQoJaWYgb2xkVGllclJld2FyZCA9PSBjdXJyZW50VGllclJld2FyZCB7CgkJcmV0dXJuCgl9CgoJaXNJblVuY2xhaW1hYmxlIDo9IHNlbGYuQ3VycmVudFN0YWtlZExpcXVpZGl0eShjdXJyZW50VGltZSkuSXNaZXJvKCkKCWlmIGlzSW5VbmNsYWltYWJsZSB7CgkJLy8gRW5kIGFueSBleGlzdGluZyB1bmNsYWltYWJsZSBwZXJpb2QKCQkvLyBOb3RlOiBJZiBsYXN0VW5jbGFpbWFibGVUaW1lIGlzIDAgKG5vdCB5ZXQgdHJhY2tpbmcpLCB0aGlzIGlzIGEgbm8tb3AKCQlzZWxmLmVuZFVuY2xhaW1hYmxlUGVyaW9kKGN1cnJlbnRUaW1lKQoJfQoKCXNlbGYuUG9vbC5TZXRSZXdhcmRDYWNoZUF0KGN1cnJlbnRUaW1lLCBjdXJyZW50VGllclJld2FyZCkKCglpZiBpc0luVW5jbGFpbWFibGUgewoJCS8vIFN0YXJ0L3Jlc3RhcnQgdW5jbGFpbWFibGUgcGVyaW9kIHRyYWNraW5nCgkJLy8gVGhpcyBoYW5kbGVzIGluaXRpYWwgdGllciBhc3NpZ25tZW50IHdoZW4gbGFzdFVuY2xhaW1hYmxlVGltZSBpcyAwCgkJc2VsZi5zdGFydFVuY2xhaW1hYmxlUGVyaW9kKGN1cnJlbnRUaW1lKQoJfQp9CgpmdW5jIChzZWxmICpQb29sUmVzb2x2ZXIpIGNhbGN1bGF0ZUdsb2JhbFJld2FyZFJhdGlvQWNjdW11bGF0aW9uKGN1cnJlbnRUaW1lIGludDY0LCBjdXJyZW50U3Rha2VkTGlxdWlkaXR5ICp1MjU2LlVpbnQpICp1MjU2LlVpbnQgewoJb2xkQWNjVGltZSwgb2xkQWNjU3RyIDo9IHNlbGYuQ3VycmVudEdsb2JhbFJld2FyZFJhdGlvQWNjdW11bGF0aW9uKGN1cnJlbnRUaW1lKQoJdGltZURpZmYgOj0gZ25zbWF0aC5TYWZlU3ViSW50NjQoY3VycmVudFRpbWUsIG9sZEFjY1RpbWUpCglpZiB0aW1lRGlmZiA9PSAwIHsKCQlyZXR1cm4gdTI1Ni5NdXN0RnJvbURlY2ltYWwob2xkQWNjU3RyKQoJfQoJaWYgdGltZURpZmYgPCAwIHsKCQlwYW5pYygidGltZSBjYW5ub3QgZ28gYmFja3dhcmRzIikKCX0KCglpZiBjdXJyZW50U3Rha2VkTGlxdWlkaXR5LklzWmVybygpIHsKCQlyZXR1cm4gdTI1Ni5NdXN0RnJvbURlY2ltYWwob2xkQWNjU3RyKQoJfQoKCW9sZEFjYyA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbChvbGRBY2NTdHIpCglhY2MgOj0gdTI1Ni5NdWxEaXYoCgkJdTI1Ni5OZXdVaW50RnJvbUludDY0KHRpbWVEaWZmKSwKCQlxMTI4LAoJCWN1cnJlbnRTdGFrZWRMaXF1aWRpdHksCgkpCglyZXR1cm4gdTI1Ni5aZXJvKCkuQWRkKG9sZEFjYywgYWNjKQp9CgovLyBnbG9iYWxSZXdhcmRSYXRpb0FjY3VtdWxhdGlvbkF0IHJldHVybnMgdGhlIGdsb2JhbCByZXdhcmQgcmF0aW8gYWNjdW11bGF0aW9uICphdCogY3VycmVudFRpbWUuCi8vCi8vIEN1cnJlbnRHbG9iYWxSZXdhcmRSYXRpb0FjY3VtdWxhdGlvbiByZXR1cm5zIHRoZSBsYXRlc3Qgc3RvcmVkIGNoZWNrcG9pbnQgKDw9IGN1cnJlbnRUaW1lKSwgd2hpY2ggaXMKLy8gb25seSBlcXVhbCB0byB0aGUgYWNjdW11bGF0aW9uIGF0IGN1cnJlbnRUaW1lIHdoZW4gYSBjaGVja3BvaW50IHdhcyB3cml0dGVuIGF0IHRoYXQgdmVyeSB0aW1lc3RhbXAuCi8vIENoZWNrcG9pbnRzIGFyZSB3cml0dGVuIGV4Y2x1c2l2ZWx5IGJ5IG1vZGlmeURlcG9zaXQgKHN0YWtlZCBsaXF1aWRpdHkgY2hhbmdlcyksIHNvIG9uIGFueSBvdGhlciBwYXRoCi8vIHRoZSBzdG9yZWQgdmFsdWUgbGFncyBieSAoY3VycmVudFRpbWUgLSBsYXN0Q2hlY2twb2ludFRpbWUpICogcTEyOCAvIHN0YWtlZExpcXVpZGl0eS4KLy8KLy8gUmV3YXJkIGNhbGN1bGF0aW9uIG5ldmVyIGhhcyB0aGlzIHByb2JsZW0gYmVjYXVzZSBpdCBkZXJpdmVzIHRoZSBhY2N1bXVsYXRpb24gb24gZGVtYW5kCi8vIChDYWxjdWxhdGVSYXdSZXdhcmRGb3JQb3NpdGlvbikuIEV2ZW50IGVtaXNzaW9uIG11c3QgZG8gdGhlIHNhbWUsIG90aGVyd2lzZSBvZmYtY2hhaW4gaW5kZXhlcnMgdGhhdAovLyB0cmVhdCB0aGUgZW1pdHRlZCBhY2N1bXVsYXRvciBhcyBhdXRob3JpdGF0aXZlIGF0IHRoZSBldmVudCB0aW1lc3RhbXAgc2lsZW50bHkgZHJvcCB0aGF0IGludGVydmFsLgpmdW5jIChzZWxmICpQb29sUmVzb2x2ZXIpIGdsb2JhbFJld2FyZFJhdGlvQWNjdW11bGF0aW9uQXQoY3VycmVudFRpbWUgaW50NjQpICgqdTI1Ni5VaW50LCAqdTI1Ni5VaW50KSB7CglzdGFrZWRMaXF1aWRpdHkgOj0gc2VsZi5DdXJyZW50U3Rha2VkTGlxdWlkaXR5KGN1cnJlbnRUaW1lKQoJYWNjdW11bGF0aW9uIDo9IHNlbGYuY2FsY3VsYXRlR2xvYmFsUmV3YXJkUmF0aW9BY2N1bXVsYXRpb24oY3VycmVudFRpbWUsIHN0YWtlZExpcXVpZGl0eSkKCglyZXR1cm4gYWNjdW11bGF0aW9uLCBzdGFrZWRMaXF1aWRpdHkKfQoKLy8gdXBkYXRlR2xvYmFsUmV3YXJkUmF0aW9BY2N1bXVsYXRpb24gdXBkYXRlcyB0aGUgZ2xvYmFsIHJld2FyZCByYXRpbyBhY2N1bXVsYXRpb24gYW5kIHJldHVybnMgdGhlIG5ldyBhY2N1bXVsYXRpb24uCmZ1bmMgKHNlbGYgKlBvb2xSZXNvbHZlcikgdXBkYXRlR2xvYmFsUmV3YXJkUmF0aW9BY2N1bXVsYXRpb24oY3VycmVudFRpbWUgaW50NjQsIGN1cnJlbnRTdGFrZWRMaXF1aWRpdHkgKnUyNTYuVWludCkgKnUyNTYuVWludCB7CgluZXdBY2MgOj0gc2VsZi5jYWxjdWxhdGVHbG9iYWxSZXdhcmRSYXRpb0FjY3VtdWxhdGlvbihjdXJyZW50VGltZSwgY3VycmVudFN0YWtlZExpcXVpZGl0eSkKCgkvLyBQZXJzaXN0IGFzIHN0cmluZyB0byByZWR1Y2Ugc3RvcmVkIG9iamVjdCBjb21wbGV4aXR5LgoJc2VsZi5Qb29sLlNldEdsb2JhbFJld2FyZFJhdGlvQWNjdW11bGF0aW9uQXQoY3VycmVudFRpbWUsIG5ld0FjYy5Ub1N0cmluZygpKQoJcmV0dXJuIG5ld0FjYwp9CgovLyBSZXdhcmRTdGF0ZU9mIGluaXRpYWxpemVzIGEgbmV3IFJld2FyZFN0YXRlIGZvciB0aGUgZ2l2ZW4gZGVwb3NpdCwgYWxsb2NhdGluZyByZXdhcmQgYW5kIHBlbmFsdHkgc2xvdHMgZm9yIGVhY2ggd2FybXVwLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gZGVwb3NpdDogU3Rha2VkIGRlcG9zaXQgd2hvc2UgcG9vbCwgbGlxdWlkaXR5LCBhbmQgd2FybXVwIHNjaGVkdWxlIHdpbGwgYmUgcmVzb2x2ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBzdGF0ZTogUmV3YXJkU3RhdGUgaW5pdGlhbGl6ZWQgd2l0aCB6ZXJvZWQgcGVyLXdhcm11cCByZXdhcmQgYW5kIHBlbmFsdHkgYWNjdW11bGF0b3JzLgpmdW5jIChzZWxmICpQb29sUmVzb2x2ZXIpIFJld2FyZFN0YXRlT2YoZGVwb3NpdCAqc3IuRGVwb3NpdCkgKlJld2FyZFN0YXRlIHsKCXdhcm11cHMgOj0gbGVuKGRlcG9zaXQuV2FybXVwcygpKQoJcmVzdWx0IDo9ICZSZXdhcmRTdGF0ZXsKCQlwb29sOiAgICAgIHNlbGYsCgkJZGVwb3NpdDogICBOZXdEZXBvc2l0UmVzb2x2ZXIoZGVwb3NpdCksCgkJcmV3YXJkczogICBtYWtlKFtdaW50NjQsIHdhcm11cHMpLAoJCXBlbmFsdGllczogbWFrZShbXWludDY0LCB3YXJtdXBzKSwKCX0KCglyZXR1cm4gcmVzdWx0Cn0KCi8vIHJlc2V0IGNsZWFycyBjYWNoZWQgcmV3YXJkcy9wZW5hbHRpZXMgc28gYSBSZXdhcmRTdGF0ZSBjYW4gYmUgcmV1c2VkIHdpdGhvdXQgcmUtYWxsb2NhdGluZy4KZnVuYyAoc2VsZiAqUmV3YXJkU3RhdGUpIHJlc2V0KCkgewoJZm9yIGkgOj0gcmFuZ2Ugc2VsZi5yZXdhcmRzIHsKCQlzZWxmLnJld2FyZHNbaV0gPSAwCgkJc2VsZi5wZW5hbHRpZXNbaV0gPSAwCgl9Cn0KCi8vIE5ld1Bvb2xSZXNvbHZlciB3cmFwcyBhIHBvb2wncyBwZXJzaXN0ZWQgcmV3YXJkLCBsaXF1aWRpdHksIHRpY2ssIGFuZCBpbmNlbnRpdmUgc3RhdGUgZm9yIGNhbGN1bGF0aW9ucy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvb2w6IFBvb2wgc3RhdGUgdG8gcmVzb2x2ZS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHJlc29sdmVyOiBQb29sIHJlc29sdmVyIGJhY2tlZCBieSBwb29sLgpmdW5jIE5ld1Bvb2xSZXNvbHZlcihwb29sICpzci5Qb29sKSAqUG9vbFJlc29sdmVyIHsKCXJldHVybiAmUG9vbFJlc29sdmVyewoJCVBvb2w6IHBvb2wsCgl9Cn0KCi8vIG5ld1Bvb2xSZXNvbHZlcldpdGhFeGl0IGJ1aWxkcyBhIHJlc29sdmVyIHRoYXQgcmVhZHMgdGhlIHBvb2wgdGhyb3VnaCBhbiBleGl0IGNoZWNrcG9pbnQuCmZ1bmMgbmV3UG9vbFJlc29sdmVyV2l0aEV4aXQocG9vbCAqc3IuUG9vbCwgZXhpdCAqc3IuVW5zdGFrZWRQb3NpdGlvbikgKlBvb2xSZXNvbHZlciB7CglyZXR1cm4gJlBvb2xSZXNvbHZlcnsKCQlQb29sOiBwb29sLAoJCWV4aXQ6IGV4aXQsCgl9Cn0KCi8vIFJld2FyZFN0YXRlIGlzIGEgc3RydWN0IGZvciBzdG9yaW5nIHRoZSBpbnRlcm1lZGlhdGUgc3RhdGUgZm9yIHJld2FyZCBjYWxjdWxhdGlvbi4KdHlwZSBSZXdhcmRTdGF0ZSBzdHJ1Y3QgewoJcG9vbCAgICAqUG9vbFJlc29sdmVyCglkZXBvc2l0ICpEZXBvc2l0UmVzb2x2ZXIKCgkvLyBhY2N1bXVsYXRlZCByZXdhcmRzIGZvciBlYWNoIHdhcm11cAoJcmV3YXJkcyAgIFtdaW50NjQKCXBlbmFsdGllcyBbXWludDY0Cn0KCi8vIGNhbGN1bGF0ZUludGVybmFsUmV3YXJkIGNvbXB1dGVzIHRoZSBwb3NpdGlvbidzIHBlci13YXJtdXAgcmV3YXJkcyBhbmQgcGVuYWx0aWVzIGZyb20gYSBwcmUtcmVzb2x2ZWQKLy8gcGVyLXNlY29uZCByZXdhcmQtcmF0ZSBzY2hlZHVsZSAoc2VlIFBvb2xSZXNvbHZlci5yZXNvbHZlSW50ZXJuYWxSZXdhcmRTZWdtZW50cykuCi8vCi8vIEl0IGlzIHB1cmU6IGl0IG5laXRoZXIgcXVlcmllcyBwb29sIHRpZXIvZW1pc3Npb24gc3RhdGUgbm9yIHdyaXRlcyBhbnkgc3RhdGUsIHNvIHRoZSByZWFkLW9ubHkgdmlldwovLyBwYXRoIGFuZCB0aGUgY29sbGVjdCBwYXRoIHVzZSBpdCBpZGVudGljYWxseS4gRWFjaCBzZWdtZW50IFtzdGFydCwgZW5kKSBpcyBhcHBsaWVkIGF0IGl0cyBjb25zdGFudAovLyBwZXItc2Vjb25kIHJhdGU7IHJld2FyZFBlcldhcm11cCBpcyBhIG5vLW9wIGZvciBlbXB0eSBzZWdtZW50cyAoc3RhcnQgPT0gZW5kKS4KZnVuYyAoc2VsZiAqUmV3YXJkU3RhdGUpIGNhbGN1bGF0ZUludGVybmFsUmV3YXJkKHNlZ21lbnRzIFtdaW50ZXJuYWxSZXdhcmRTZWdtZW50KSAoW11pbnQ2NCwgW11pbnQ2NCkgewoJZm9yIF8sIHNlZyA6PSByYW5nZSBzZWdtZW50cyB7CgkJaWYgZXJyIDo9IHNlbGYucmV3YXJkUGVyV2FybXVwKHNlZy5zdGFydCwgc2VnLmVuZCwgc2VnLnJld2FyZFBlclNlY29uZCk7IGVyciAhPSBuaWwgewoJCQlwYW5pYyhlcnIpCgkJfQoJfQoKCXNlbGYuYXBwbHlXYXJtdXAoKQoKCXJldHVybiBzZWxmLnJld2FyZHMsIHNlbGYucGVuYWx0aWVzCn0KCi8vIHVwZGF0ZUV4dGVybmFsUmV3YXJkIHVwZGF0ZXMgdGhlIGV4dGVybmFsIHJld2FyZCBmb3IgdGhlIGRlcG9zaXQuCi8vIEl0IHVwZGF0ZXMgdGhlIGxhc3QgY29sbGVjdCB0aW1lIGZvciB0aGUgZXh0ZXJuYWwgcmV3YXJkIGZvciB0aGUgZ2l2ZW4gaW5jZW50aXZlIElELgovLyBJdCByZXR1cm5zIGFuIGVycm9yIGlmIHRoZSBjdXJyZW50IHRpbWUgaXMgbGVzcyB0aGFuIHRoZSBsYXN0IGNvbGxlY3QgdGltZSBmb3IgdGhlIGV4dGVybmFsIHJld2FyZCBmb3IgdGhlIGdpdmVuIGluY2VudGl2ZSBJRC4KZnVuYyAoc2VsZiAqUmV3YXJkU3RhdGUpIHVwZGF0ZUV4dGVybmFsUmV3YXJkKHN0YXJ0VGltZSwgZW5kVGltZSBpbnQ2NCwgaW5jZW50aXZlICpzci5FeHRlcm5hbEluY2VudGl2ZSkgZXJyb3IgewoJbGFzdENvbGxlY3RUaW1lIDo9IHNlbGYuZGVwb3NpdC5FeHRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZShpbmNlbnRpdmUuSW5jZW50aXZlSWQoKSkKCWlmIHN0YXJ0VGltZSA8IGxhc3RDb2xsZWN0VGltZSB7CgkJLy8gVGhpcyBtdXN0IG5vdCBoYXBwZW4sIGJ1dCBhZGRpbmcgc29tZSBndWFyZHMganVzdCBpbiBjYXNlLgoJCXN0YXJ0VGltZSA9IGxhc3RDb2xsZWN0VGltZQoJfQoKCWljdHZTdGFydCA6PSBpbmNlbnRpdmUuU3RhcnRUaW1lc3RhbXAoKQoJaWYgZW5kVGltZSA8IGljdHZTdGFydCB7CgkJcmV0dXJuIG5pbCAvLyBOb3Qgc3RhcnRlZCB5ZXQKCX0KCglpZiBzdGFydFRpbWUgPCBpY3R2U3RhcnQgewoJCXN0YXJ0VGltZSA9IGljdHZTdGFydAoJfQoKCWljdHZFbmQgOj0gaW5jZW50aXZlLkVuZFRpbWVzdGFtcCgpCglpZiBlbmRUaW1lID4gaWN0dkVuZCB7CgkJZW5kVGltZSA9IGljdHZFbmQKCX0KCglpZiBzdGFydFRpbWUgPiBpY3R2RW5kIHsKCQlyZXR1cm4gbmlsIC8vIEFscmVhZHkgZW5kZWQKCX0KCglyZXR1cm4gc2VsZi5yZXdhcmRQZXJXYXJtdXBYMTI4KHN0YXJ0VGltZSwgZW5kVGltZSwgaW5jZW50aXZlLlJld2FyZFBlclNlY29uZFgxMjgoKSkKfQoKLy8gY2FsY3VsYXRlQ29sbGVjdGFibGVFeHRlcm5hbFJld2FyZCBjYWxjdWxhdGVzIHRoZSBjYWxjdWxhdGVkIGV4dGVybmFsIHJld2FyZCBmb3IgdGhlIGRlcG9zaXQuCi8vIEl0IGNhbGxzIHVwZGF0ZUV4dGVybmFsUmV3YXJkIGZvciB0aGUgaW5jZW50aXZlIHBlcmlvZCwgYXBwbGllcyB3YXJtdXAgYW5kIHJldHVybnMgdGhlIHJld2FyZHMgYW5kIHBlbmFsdGllcy4KLy8gdXNlZCBmb3IgcmV3YXJkIGNhbGN1bGF0aW9uIGZvciBhIGNhbGN1bGF0YWJsZSBpbmNlbnRpdmUKZnVuYyAoc2VsZiAqUmV3YXJkU3RhdGUpIGNhbGN1bGF0ZUNvbGxlY3RhYmxlRXh0ZXJuYWxSZXdhcmQoc3RhcnRUaW1lLCBlbmRUaW1lIGludDY0LCBpbmNlbnRpdmUgKnNyLkV4dGVybmFsSW5jZW50aXZlKSBpbnQ2NCB7CgllcnIgOj0gc2VsZi51cGRhdGVFeHRlcm5hbFJld2FyZChzdGFydFRpbWUsIGVuZFRpbWUsIGluY2VudGl2ZSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCgljdXJyZW50UmV3YXJkIDo9IHUyNTYuWmVybygpCgoJZm9yIGkgOj0gcmFuZ2Ugc2VsZi5yZXdhcmRzIHsKCQljdXJyZW50UmV3YXJkID0gY3VycmVudFJld2FyZC5BZGQoY3VycmVudFJld2FyZCwgdTI1Ni5OZXdVaW50RnJvbUludDY0KHNlbGYucmV3YXJkc1tpXSkpCgl9CgoJcmV0dXJuIGduc21hdGguU2FmZUNvbnZlcnRUb0ludDY0KGN1cnJlbnRSZXdhcmQpCn0KCi8vIGNhbGN1bGF0ZUV4dGVybmFsUmV3YXJkIGNhbGN1bGF0ZXMgdGhlIGV4dGVybmFsIHJld2FyZCBmb3IgdGhlIGRlcG9zaXQuCi8vIEl0IGNhbGxzIHJld2FyZFBlcldhcm11cCBmb3Igc3RhcnRUaW1lIHRvIGVuZFRpbWUoY2xhbXBlZCB0byB0aGUgaW5jZW50aXZlIHBlcmlvZCksIGFwcGxpZXMgd2FybXVwIGFuZCByZXR1cm5zIHRoZSByZXdhcmRzIGFuZCBwZW5hbHRpZXMuCmZ1bmMgKHNlbGYgKlJld2FyZFN0YXRlKSBjYWxjdWxhdGVFeHRlcm5hbFJld2FyZChzdGFydFRpbWUsIGVuZFRpbWUgaW50NjQsIGluY2VudGl2ZSAqc3IuRXh0ZXJuYWxJbmNlbnRpdmUpIChbXWludDY0LCBbXWludDY0KSB7CgllcnIgOj0gc2VsZi51cGRhdGVFeHRlcm5hbFJld2FyZChzdGFydFRpbWUsIGVuZFRpbWUsIGluY2VudGl2ZSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCgkvLyBhcHBseSB3YXJtdXAgdG8gY29sbGVjdCByZXdhcmRzCglzZWxmLmFwcGx5V2FybXVwKCkKCglyZXR1cm4gc2VsZi5yZXdhcmRzLCBzZWxmLnBlbmFsdGllcwp9CgovLyBhcHBseVdhcm11cCBhcHBsaWVzIHRoZSB3YXJtdXAgdG8gdGhlIHJld2FyZHMgYW5kIGNhbGN1bGF0ZSBwZW5hbHRpZXMuCmZ1bmMgKHNlbGYgKlJld2FyZFN0YXRlKSBhcHBseVdhcm11cCgpIHsKCWZvciBpLCB3YXJtdXAgOj0gcmFuZ2Ugc2VsZi5kZXBvc2l0Lldhcm11cHMoKSB7CgkJd2FybXVwUmV3YXJkIDo9IHNlbGYucmV3YXJkc1tpXQoKCQkvLyBjYWxjdWxhdGUgd2FybXVwIHJld2FyZCBhcHBseWluZyB3YXJtdXAgcmF0aW8KCQlzZWxmLnJld2FyZHNbaV0gPSBnbnNtYXRoLlNhZmVNdWxEaXZJbnQ2NCh3YXJtdXBSZXdhcmQsIGludDY0KHdhcm11cC5XYXJtdXBSYXRpbyksIDEwMCkKCgkJLy8gd2FybXVwIHBlbmFsdHkgaXMgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgd2FybXVwIHJld2FyZCBhbmQgdGhlIHdhcm11cCByZXdhcmQgYXBwbHlpbmcgd2FybXVwIHJhdGlvCgkJc2VsZi5wZW5hbHRpZXNbaV0gPSBnbnNtYXRoLlNhZmVTdWJJbnQ2NCh3YXJtdXBSZXdhcmQsIHNlbGYucmV3YXJkc1tpXSkKCX0KfQoKLy8gcmV3YXJkUGVyV2FybXVwIGNhbGN1bGF0ZXMgdGhlIHJld2FyZCBmb3IgZWFjaCB3YXJtdXAsIGFkZHMgdG8gdGhlIFJld2FyZFN0YXRlJ3MgcmV3YXJkcyBhcnJheS4KLy8gVXNlZCBieSB0aGUgaW50ZXJuYWwgcmV3YXJkIHBhdGggd2hlcmUgcmV3YXJkUGVyU2Vjb25kIGlzIGFuIGludDY0IGVtaXNzaW9uIHJhdGUuCmZ1bmMgKHNlbGYgKlJld2FyZFN0YXRlKSByZXdhcmRQZXJXYXJtdXAoc3RhcnRUaW1lLCBlbmRUaW1lIGludDY0LCByZXdhcmRQZXJTZWNvbmQgaW50NjQpIGVycm9yIHsKCS8vIFJldHVybiBlYXJseSBpZiBzdGFydFRpbWUgZXF1YWxzIGVuZFRpbWUgdG8gYXZvaWQgdW5uZWNlc3NhcnkgY29tcHV0YXRpb24KCWlmIHN0YXJ0VGltZSA9PSBlbmRUaW1lIHsKCQlyZXR1cm4gbmlsCgl9CgoJc3RhcnRUaWNrIDo9IHNlbGYucG9vbC5DdXJyZW50VGljayhzdGFydFRpbWUpCglzdGFydFJhdyA6PSBzZWxmLnBvb2wuQ2FsY3VsYXRlUmF3UmV3YXJkRm9yUG9zaXRpb24oc3RhcnRUaW1lLCBzdGFydFRpY2ssIHNlbGYuZGVwb3NpdC5EZXBvc2l0KQoKCWZvciBpLCB3YXJtdXAgOj0gcmFuZ2Ugc2VsZi5kZXBvc2l0Lldhcm11cHMoKSB7CgkJaWYgc3RhcnRUaW1lID49IHdhcm11cC5OZXh0V2FybXVwVGltZSB7CgkJCS8vIHBhc3NlZCB0aGUgd2FybXVwCgkJCWNvbnRpbnVlCgkJfQoKCQlpZiBlbmRUaW1lIDwgd2FybXVwLk5leHRXYXJtdXBUaW1lIHsKCQkJZW5kVGljayA6PSBzZWxmLnBvb2wuQ3VycmVudFRpY2soZW5kVGltZSkKCQkJZW5kUmF3IDo9IHNlbGYucG9vbC5DYWxjdWxhdGVSYXdSZXdhcmRGb3JQb3NpdGlvbihlbmRUaW1lLCBlbmRUaWNrLCBzZWxmLmRlcG9zaXQuRGVwb3NpdCkKCQkJLy8gTW9kdWxhciBieSBkZXNpZ246IGJvdW5kYXJ5IHRpY2tzIGNyZWF0ZWQgYXQgZGlmZmVyZW50IHRpbWVzIGdpdmUgYQoJCQkvLyB3cmFwcGVkIGJhc2UsIHNvIHRoZSBib3Jyb3cgaXMgZXhwZWN0ZWQgYW5kIHRoZSB3cmFwcGVkIGRpZmZlcmVuY2UKCQkJLy8gaXMgdGhlIHRydWUgYWNjdW11bGF0aW9uIChVbmlzd2FwIFYzIHN1YnRyYWN0cyB1bmNoZWNrZWQgdG9vKS4KCQkJcmV3YXJkQWNjIDo9IHUyNTYuWmVybygpLlN1YihlbmRSYXcsIHN0YXJ0UmF3KQoKCQkJcmV3YXJkQWNjLCBvdmVyZmxvdyA6PSB1MjU2Llplcm8oKS5NdWxPdmVyZmxvdyhyZXdhcmRBY2MsIHNlbGYuZGVwb3NpdC5MaXF1aWRpdHkoKSkKCQkJaWYgb3ZlcmZsb3cgewoJCQkJcGFuaWMoZXJyb3JzLk5ldyhlcnJPdmVyZmxvdykpCgkJCX0KCgkJCXJld2FyZEFjYyA9IHUyNTYuTXVsRGl2KHJld2FyZEFjYywgdTI1Ni5OZXdVaW50RnJvbUludDY0KHJld2FyZFBlclNlY29uZCksIHExMjgpCgkJCXNlbGYucmV3YXJkc1tpXSA9IGduc21hdGguU2FmZUFkZEludDY0KHNlbGYucmV3YXJkc1tpXSwgZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQocmV3YXJkQWNjKSkKCgkJCWJyZWFrCgkJfQoKCQllbmRUaWNrIDo9IHNlbGYucG9vbC5DdXJyZW50VGljayh3YXJtdXAuTmV4dFdhcm11cFRpbWUpCgkJZW5kUmF3IDo9IHNlbGYucG9vbC5DYWxjdWxhdGVSYXdSZXdhcmRGb3JQb3NpdGlvbih3YXJtdXAuTmV4dFdhcm11cFRpbWUsIGVuZFRpY2ssIHNlbGYuZGVwb3NpdC5EZXBvc2l0KQoJCS8vIFNlZSB0aGUgbm90ZSBhYm92ZTogdGhlIHN1YnRyYWN0aW9uIGlzIGludGVudGlvbmFsbHkgbW9kdWxhci4KCQlyZXdhcmRBY2MgOj0gdTI1Ni5aZXJvKCkuU3ViKGVuZFJhdywgc3RhcnRSYXcpCgoJCXJld2FyZEFjYywgb3ZlcmZsb3cgOj0gdTI1Ni5aZXJvKCkuTXVsT3ZlcmZsb3cocmV3YXJkQWNjLCBzZWxmLmRlcG9zaXQuTGlxdWlkaXR5KCkpCgkJaWYgb3ZlcmZsb3cgewoJCQlwYW5pYyhlcnJvcnMuTmV3KGVyck92ZXJmbG93KSkKCQl9CgoJCXJld2FyZEFjYyA9IHUyNTYuTXVsRGl2KHJld2FyZEFjYywgdTI1Ni5OZXdVaW50RnJvbUludDY0KHJld2FyZFBlclNlY29uZCksIHExMjgpCgkJc2VsZi5yZXdhcmRzW2ldID0gZ25zbWF0aC5TYWZlQWRkSW50NjQoc2VsZi5yZXdhcmRzW2ldLCBnbnNtYXRoLlNhZmVDb252ZXJ0VG9JbnQ2NChyZXdhcmRBY2MpKQoKCQlzdGFydFRpbWUgPSB3YXJtdXAuTmV4dFdhcm11cFRpbWUKCQlzdGFydFRpY2sgPSBlbmRUaWNrCgkJc3RhcnRSYXcgPSBlbmRSYXcKCX0KCglyZXR1cm4gbmlsCn0KCi8vIHJld2FyZFBlcldhcm11cFgxMjggY2FsY3VsYXRlcyB0aGUgcmV3YXJkIGZvciBlYWNoIHdhcm11cCB1c2luZyBhIFExMjgtc2NhbGVkCi8vIHBlci1zZWNvbmQgcmF0ZS4gVXNlZCBieSB0aGUgZXh0ZXJuYWwgaW5jZW50aXZlIHBhdGg7IHRoZSBwZXItc2Vjb25kIHJhdGUgaXMKLy8gc3RvcmVkIGFzIGAocmV3YXJkQW1vdW50IDw8IDEyOCkgLyBkdXJhdGlvbmAgaW4gRXh0ZXJuYWxJbmNlbnRpdmUsIHNvIGFuCi8vIGV4dHJhIGA+PiAxMjhgIGlzIG5lZWRlZCBhZnRlciB0aGUgc3RhbmRhcmQgYE11bERpdihyZXdhcmRBY2MsIHJwcywgcTEyOClgCi8vIHRvIG1hdGVyaWFsaXplIHRoZSBpbnRlZ2VyIHJlc3VsdC4KZnVuYyAoc2VsZiAqUmV3YXJkU3RhdGUpIHJld2FyZFBlcldhcm11cFgxMjgoc3RhcnRUaW1lLCBlbmRUaW1lIGludDY0LCByZXdhcmRQZXJTZWNvbmRYMTI4ICp1MjU2LlVpbnQpIGVycm9yIHsKCWlmIHN0YXJ0VGltZSA9PSBlbmRUaW1lIHsKCQlyZXR1cm4gbmlsCgl9CgoJc3RhcnRUaWNrIDo9IHNlbGYucG9vbC5DdXJyZW50VGljayhzdGFydFRpbWUpCglzdGFydFJhdyA6PSBzZWxmLnBvb2wuQ2FsY3VsYXRlUmF3UmV3YXJkRm9yUG9zaXRpb24oc3RhcnRUaW1lLCBzdGFydFRpY2ssIHNlbGYuZGVwb3NpdC5EZXBvc2l0KQoKCWZvciBpLCB3YXJtdXAgOj0gcmFuZ2Ugc2VsZi5kZXBvc2l0Lldhcm11cHMoKSB7CgkJaWYgc3RhcnRUaW1lID49IHdhcm11cC5OZXh0V2FybXVwVGltZSB7CgkJCWNvbnRpbnVlCgkJfQoKCQlpZiBlbmRUaW1lIDwgd2FybXVwLk5leHRXYXJtdXBUaW1lIHsKCQkJZW5kVGljayA6PSBzZWxmLnBvb2wuQ3VycmVudFRpY2soZW5kVGltZSkKCQkJZW5kUmF3IDo9IHNlbGYucG9vbC5DYWxjdWxhdGVSYXdSZXdhcmRGb3JQb3NpdGlvbihlbmRUaW1lLCBlbmRUaWNrLCBzZWxmLmRlcG9zaXQuRGVwb3NpdCkKCQkJLy8gTW9kdWxhciBieSBkZXNpZ246IGJvdW5kYXJ5IHRpY2tzIGNyZWF0ZWQgYXQgZGlmZmVyZW50IHRpbWVzIGdpdmUgYQoJCQkvLyB3cmFwcGVkIGJhc2UsIHNvIHRoZSBib3Jyb3cgaXMgZXhwZWN0ZWQgYW5kIHRoZSB3cmFwcGVkIGRpZmZlcmVuY2UKCQkJLy8gaXMgdGhlIHRydWUgYWNjdW11bGF0aW9uIChVbmlzd2FwIFYzIHN1YnRyYWN0cyB1bmNoZWNrZWQgdG9vKS4KCQkJcmV3YXJkQWNjIDo9IHUyNTYuWmVybygpLlN1YihlbmRSYXcsIHN0YXJ0UmF3KQoKCQkJcmV3YXJkQWNjLCBvdmVyZmxvdyA6PSB1MjU2Llplcm8oKS5NdWxPdmVyZmxvdyhyZXdhcmRBY2MsIHNlbGYuZGVwb3NpdC5MaXF1aWRpdHkoKSkKCQkJaWYgb3ZlcmZsb3cgewoJCQkJcGFuaWMoZXJyb3JzLk5ldyhlcnJPdmVyZmxvdykpCgkJCX0KCgkJCXJld2FyZEFjYyA9IHUyNTYuTXVsRGl2KHJld2FyZEFjYywgcmV3YXJkUGVyU2Vjb25kWDEyOCwgcTEyOCkKCQkJcmV3YXJkQWNjID0gdTI1Ni5aZXJvKCkuUnNoKHJld2FyZEFjYywgMTI4KQoJCQlzZWxmLnJld2FyZHNbaV0gPSBnbnNtYXRoLlNhZmVBZGRJbnQ2NChzZWxmLnJld2FyZHNbaV0sIGduc21hdGguU2FmZUNvbnZlcnRUb0ludDY0KHJld2FyZEFjYykpCgoJCQlicmVhawoJCX0KCgkJZW5kVGljayA6PSBzZWxmLnBvb2wuQ3VycmVudFRpY2sod2FybXVwLk5leHRXYXJtdXBUaW1lKQoJCWVuZFJhdyA6PSBzZWxmLnBvb2wuQ2FsY3VsYXRlUmF3UmV3YXJkRm9yUG9zaXRpb24od2FybXVwLk5leHRXYXJtdXBUaW1lLCBlbmRUaWNrLCBzZWxmLmRlcG9zaXQuRGVwb3NpdCkKCQkvLyBTZWUgdGhlIG5vdGUgYWJvdmU6IHRoZSBzdWJ0cmFjdGlvbiBpcyBpbnRlbnRpb25hbGx5IG1vZHVsYXIuCgkJcmV3YXJkQWNjIDo9IHUyNTYuWmVybygpLlN1YihlbmRSYXcsIHN0YXJ0UmF3KQoKCQlyZXdhcmRBY2MsIG92ZXJmbG93IDo9IHUyNTYuWmVybygpLk11bE92ZXJmbG93KHJld2FyZEFjYywgc2VsZi5kZXBvc2l0LkxpcXVpZGl0eSgpKQoJCWlmIG92ZXJmbG93IHsKCQkJcGFuaWMoZXJyb3JzLk5ldyhlcnJPdmVyZmxvdykpCgkJfQoKCQlyZXdhcmRBY2MgPSB1MjU2Lk11bERpdihyZXdhcmRBY2MsIHJld2FyZFBlclNlY29uZFgxMjgsIHExMjgpCgkJcmV3YXJkQWNjID0gdTI1Ni5aZXJvKCkuUnNoKHJld2FyZEFjYywgMTI4KQoJCXNlbGYucmV3YXJkc1tpXSA9IGduc21hdGguU2FmZUFkZEludDY0KHNlbGYucmV3YXJkc1tpXSwgZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQocmV3YXJkQWNjKSkKCgkJc3RhcnRUaW1lID0gd2FybXVwLk5leHRXYXJtdXBUaW1lCgkJc3RhcnRUaWNrID0gZW5kVGljawoJCXN0YXJ0UmF3ID0gZW5kUmF3Cgl9CgoJcmV0dXJuIG5pbAp9CgovLyBtb2RpZnlEZXBvc2l0IHVwZGF0ZXMgdGhlIHBvb2wncyBzdGFrZWQgbGlxdWlkaXR5IGFuZCByZXR1cm5zIHRoZSBuZXcgc3Rha2VkIGxpcXVpZGl0eS4KLy8gdXBkYXRlcyB3aGVuIHRoZXJlIGlzIGEgY2hhbmdlIGluIHRoZSBzdGFrZWQgbGlxdWlkaXR5KHRpY2sgY3Jvc3MsIHN0YWtlLCB1bnN0YWtlKQpmdW5jIChzZWxmICpQb29sUmVzb2x2ZXIpIG1vZGlmeURlcG9zaXQoZGVsdGEgKmkyNTYuSW50LCBjdXJyZW50VGltZSBpbnQ2NCwgbmV4dFRpY2sgaW50MzIpICp1MjU2LlVpbnQgewoJLy8gdXBkYXRlIHN0YWtlciBzaWRlIHBvb2wgaW5mbwoJbGFzdFN0YWtlZExpcXVpZGl0eSA6PSBzZWxmLkN1cnJlbnRTdGFrZWRMaXF1aWRpdHkoY3VycmVudFRpbWUpCglkZWx0YUFwcGxpZWQgOj0gZ25zbWF0aC5MaXF1aWRpdHlNYXRoQWRkRGVsdGEobGFzdFN0YWtlZExpcXVpZGl0eSwgZGVsdGEpCglyZXN1bHQgOj0gc2VsZi51cGRhdGVHbG9iYWxSZXdhcmRSYXRpb0FjY3VtdWxhdGlvbihjdXJyZW50VGltZSwgbGFzdFN0YWtlZExpcXVpZGl0eSkKCgkvLyBoaXN0b3JpY2FsIHRpY2sgZG9lcyBOT1QgYWN0dWFsbHkgcmVmbGVjdCB0aGUgdGljayBhdCB0aGUgdGltZXN0YW1wLCBidXQgaXQgcHJvdmlkZXMgY29ycmVjdCBvcmRlcmluZyBmb3IgdGhlIHN0YWtlZCBwb3NpdGlvbnMKCS8vIGJlY2F1c2UgVGlja0Nyb3NzSG9vayBpcyBhc3N1cmVkIHRvIGJlIGNhbGxlZCBmb3IgdGhlIHN0YWtlZC1pbml0aWFsaXplZCB0aWNrcwoJaWYgc2VsZi5pc0NoYW5nZWRUaWNrKGN1cnJlbnRUaW1lLCBuZXh0VGljaykgewoJCXNlbGYuUG9vbC5TZXRIaXN0b3JpY2FsVGlja0F0KGN1cnJlbnRUaW1lLCBuZXh0VGljaykKCX0KCglzd2l0Y2ggZGVsdGFBcHBsaWVkLlNpZ24oKSB7CgljYXNlIC0xOgoJCXBhbmljKCJzdGFrZWRMaXF1aWRpdHkgaXMgbGVzcyB0aGFuIDAsIHNob3VsZCBub3QgaGFwcGVuIikKCWNhc2UgMDoKCQlpZiBsYXN0U3Rha2VkTGlxdWlkaXR5LlNpZ24oKSA9PSAxIHsKCQkJLy8gU3Rha2VkTGlxdWlkaXR5IG1vdmVkIGZyb20gcG9zaXRpdmUgdG8gemVybywgc3RhcnQgdW5jbGFpbWFibGUgcGVyaW9kCgkJCXNlbGYuc3RhcnRVbmNsYWltYWJsZVBlcmlvZChjdXJyZW50VGltZSkKCQkJc2VsZi5JbmNlbnRpdmVzUmVzb2x2ZXIoKS5zdGFydFVuY2xhaW1hYmxlUGVyaW9kKGN1cnJlbnRUaW1lKQoJCX0KCWNhc2UgMToKCQlpZiBsYXN0U3Rha2VkTGlxdWlkaXR5LlNpZ24oKSA9PSAwIHsKCQkJLy8gU3Rha2VkTGlxdWlkaXR5IG1vdmVkIGZyb20gemVybyB0byBwb3NpdGl2ZSwgZW5kIHVuY2xhaW1hYmxlIHBlcmlvZAoJCQlzZWxmLmVuZFVuY2xhaW1hYmxlUGVyaW9kKGN1cnJlbnRUaW1lKQoJCQlzZWxmLkluY2VudGl2ZXNSZXNvbHZlcigpLmVuZFVuY2xhaW1hYmxlUGVyaW9kKGN1cnJlbnRUaW1lKQoJCX0KCX0KCgkvLyBPbmx5IGFwcGVuZCBhIHN0YWtlZC1saXF1aWRpdHkgZW50cnkgd2hlbiB0aGUgdmFsdWUgYWN0dWFsbHkgY2hhbmdlcyAoZS5nLiBhIHRpY2sgY3Jvc3Mgd2hvc2UKCS8vIG5ldCBkZWx0YSBpcyB6ZXJvIGxlYXZlcyBpdCB1bmNoYW5nZWQpLiBVbmxpa2UgdGhlIGdsb2JhbCByZXdhcmQgcmF0aW8gYWNjdW11bGF0aW9uLCB0aGlzIHRyZWUKCS8vIGNhcnJpZXMgbm8gdGltZS1jaGVja3BvaW50IHNlbWFudGljczogaXQgaXMgcmVhZCBwdXJlbHkgYXMgYSBwb2ludC1pbi10aW1lIHZhbHVlIHZpYQoJLy8gQ3VycmVudFN0YWtlZExpcXVpZGl0eSAobGF0ZXN0IGVudHJ5IDw9IHQpLCBzbyBvbWl0dGluZyBhIGR1cGxpY2F0ZS12YWx1ZWQgZW50cnkgcHJlc2VydmVzCgkvLyBiZWhhdmlvciB3aGlsZSBrZWVwaW5nIHRoaXMgYXBwZW5kLW9ubHkgdHJlZSBmcm9tIGdyb3dpbmcgb24gbm8tb3AgdXBkYXRlcy4KCWlmICFsYXN0U3Rha2VkTGlxdWlkaXR5LkVxKGRlbHRhQXBwbGllZCkgewoJCXNlbGYuUG9vbC5TZXRTdGFrZWRMaXF1aWRpdHlBdChjdXJyZW50VGltZSwgZGVsdGFBcHBsaWVkKQoJfQoKCXJldHVybiByZXN1bHQKfQoKLy8gc3RhcnRVbmNsYWltYWJsZVBlcmlvZCBzdGFydHMgdGhlIHVuY2xhaW1hYmxlIHBlcmlvZC4KZnVuYyAoc2VsZiAqUG9vbFJlc29sdmVyKSBzdGFydFVuY2xhaW1hYmxlUGVyaW9kKGN1cnJlbnRUaW1lIGludDY0KSB7CglpZiBzZWxmLkxhc3RVbmNsYWltYWJsZVRpbWUoKSA9PSAwIHsKCQkvLyBXZSBzZXQgb25seSBpZiBpdCdzIHRoZSBmaXJzdCB0aW1lIGVudGVyaW5nKDAgaW5kaWNhdGVzIG5vdCBzZXQgeWV0KQoJCXNlbGYuU2V0TGFzdFVuY2xhaW1hYmxlVGltZShjdXJyZW50VGltZSkKCX0KfQoKLy8gZW5kVW5jbGFpbWFibGVQZXJpb2QgZW5kcyB0aGUgdW5jbGFpbWFibGUgcGVyaW9kLgovLyBBY2N1bXVsYXRlcyB0byB1bmNsYWltYWJsZUFjYyBhbmQgcmVzZXRzIGxhc3RVbmNsYWltYWJsZVRpbWUgdG8gMC4KZnVuYyAoc2VsZiAqUG9vbFJlc29sdmVyKSBlbmRVbmNsYWltYWJsZVBlcmlvZChjdXJyZW50VGltZSBpbnQ2NCkgewoJaWYgc2VsZi5MYXN0VW5jbGFpbWFibGVUaW1lKCkgPT0gMCB7CgkJLy8gbGFzdFVuY2xhaW1hYmxlVGltZSA9IDAgbWVhbnMgdHJhY2tpbmcgaGFzbid0IHN0YXJ0ZWQgeWV0CgkJLy8gVGhpcyBpcyBub3JtYWwgZHVyaW5nIGluaXRpYWwgcG9vbCBjcmVhdGlvbiBvciB3aGVuIGNhbGxlZCBmcm9tIGNhY2hlUmV3YXJkCgkJLy8gZHVyaW5nIHRpZXIgYXNzaWdubWVudCB3aXRoIHplcm8gbGlxdWlkaXR5CgkJcmV0dXJuCgl9CgoJc2VsZi51cGRhdGVVbmNsYWltYWJsZUFjY3VtdWxhdGVSZXdhcmRzKGN1cnJlbnRUaW1lKQoJc2VsZi5TZXRMYXN0VW5jbGFpbWFibGVUaW1lKDApCn0KCi8vIHVwZGF0ZVVuY2xhaW1hYmxlQWNjdW11bGF0ZVJld2FyZHMgZW5kcyB0aGUgdW5jbGFpbWFibGUgcGVyaW9kLgovLyBBY2N1bXVsYXRlcyB0byB1bmNsYWltYWJsZUFjYyBhbmQgcmVzZXRzIGxhc3RVbmNsYWltYWJsZVRpbWUgdG8gMC4KZnVuYyAoc2VsZiAqUG9vbFJlc29sdmVyKSB1cGRhdGVVbmNsYWltYWJsZUFjY3VtdWxhdGVSZXdhcmRzKGN1cnJlbnRUaW1lIGludDY0KSB7CglpZiBzZWxmLkxhc3RVbmNsYWltYWJsZVRpbWUoKSA+PSBjdXJyZW50VGltZSB7CgkJcmV0dXJuCgl9CgoJdW5jbGFpbWFibGVEdXJhdGlvbiA6PSBnbnNtYXRoLlNhZmVTdWJJbnQ2NChjdXJyZW50VGltZSwgc2VsZi5MYXN0VW5jbGFpbWFibGVUaW1lKCkpCgljdXJyZW50VW5jbGFpbWFibGVSZXdhcmQgOj0gZ25zbWF0aC5TYWZlTXVsSW50NjQodW5jbGFpbWFibGVEdXJhdGlvbiwgc2VsZi5DdXJyZW50UmV3YXJkKHNlbGYuTGFzdFVuY2xhaW1hYmxlVGltZSgpKSkKCXNlbGYuU2V0VW5jbGFpbWFibGVBY2MoZ25zbWF0aC5TYWZlQWRkSW50NjQoc2VsZi5VbmNsYWltYWJsZUFjYygpLCBjdXJyZW50VW5jbGFpbWFibGVSZXdhcmQpKQp9CgovLyBwcm9jZXNzVW5jbGFpbWFibGVSZXdhcmQgcHJvY2Vzc2VzIHRoZSB1bmNsYWltYWJsZSByZXdhcmQgYW5kIHJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHJld2FyZC4KLy8gSXQgcmVzZXRzIHVuY2xhaW1hYmxlQWNjIHRvIDAgYW5kIHByb3Blcmx5IG1hbmFnZXMgbGFzdFVuY2xhaW1hYmxlVGltZSBiYXNlZCBvbiBwb29sIHN0YXRlLgpmdW5jIChzZWxmICpQb29sUmVzb2x2ZXIpIHByb2Nlc3NVbmNsYWltYWJsZVJld2FyZChlbmRUaW1lIGludDY0KSBpbnQ2NCB7CgkvLyBDaGVjayBjdXJyZW50IHBvb2wgbGlxdWlkaXR5IHN0YXRlCglpc1plcm9TdGFrZWRMaXF1aWRpdHkgOj0gc2VsZi5DdXJyZW50U3Rha2VkTGlxdWlkaXR5KGVuZFRpbWUpLklzWmVybygpCgoJaWYgc2VsZi5MYXN0VW5jbGFpbWFibGVUaW1lKCkgPiAwIHsKCQkvLyBXZSBoYXZlIGFuIG9uZ29pbmcgdW5jbGFpbWFibGUgcGVyaW9kIHRyYWNraW5nCgkJc2VsZi51cGRhdGVVbmNsYWltYWJsZUFjY3VtdWxhdGVSZXdhcmRzKGVuZFRpbWUpCgoJCWlmIGlzWmVyb1N0YWtlZExpcXVpZGl0eSB7CgkJCS8vIFN0aWxsIHVuY2xhaW1hYmxlIC0gYWNjdW11bGF0ZSByZXdhcmRzIHVwIHRvIGVuZFRpbWUKCQkJLy8gVXBkYXRlIHRyYWNraW5nIHRpbWUgZm9yIGNvbnRpbnVpbmcgdW5jbGFpbWFibGUgcGVyaW9kCgkJCXNlbGYuU2V0TGFzdFVuY2xhaW1hYmxlVGltZShlbmRUaW1lKQoJCX0gZWxzZSB7CgkJCS8vIFdhcyB1bmNsYWltYWJsZSBidXQgbm93IGhhcyBsaXF1aWRpdHkgLSBwcm9wZXJseSBlbmQgdGhlIHBlcmlvZAoJCQlzZWxmLlNldExhc3RVbmNsYWltYWJsZVRpbWUoMCkKCQl9Cgl9IGVsc2UgewoJCWlmIGlzWmVyb1N0YWtlZExpcXVpZGl0eSB7CgkJCS8vIE5vIHByZXZpb3VzIHRyYWNraW5nIGJ1dCBjdXJyZW50bHkgdW5jbGFpbWFibGUgLSB0aGlzIHNob3VsZG4ndCBub3JtYWxseSBoYXBwZW4KCQkJLy8gYXMgc3RhcnRVbmNsYWltYWJsZVBlcmlvZCBzaG91bGQgaGF2ZSBiZWVuIGNhbGxlZCB3aGVuIGxpcXVpZGl0eSByZWFjaGVkIDAKCQkJLy8gU3RhcnQgdHJhY2tpbmcgZnJvbSBub3cKCQkJc2VsZi5TZXRMYXN0VW5jbGFpbWFibGVUaW1lKGVuZFRpbWUpCgkJfQoJfQoKCS8vIFJldHVybiBhbmQgcmVzZXQgYWNjdW11bGF0ZWQgdW5jbGFpbWFibGUgcmV3YXJkcwoJaW50ZXJuYWxVbkNsYWltYWJsZSA6PSBzZWxmLlVuY2xhaW1hYmxlQWNjKCkKCXNlbGYuU2V0VW5jbGFpbWFibGVBY2MoMCkKCXJldHVybiBpbnRlcm5hbFVuQ2xhaW1hYmxlCn0KCi8vIENhbGN1bGF0ZVJhd1Jld2FyZEZvclBvc2l0aW9uIGNhbGN1bGF0ZXMgdGhlIHRoZW9yZXRpY2FsIHJld2FyZCBhY2N1bXVsYXRvciBmb3IgYSBwb3NpdGlvbiB3aXRob3V0IGRlYnQgb3Igd2FybXVwIGFkanVzdG1lbnRzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gY3VycmVudFRpbWU6IFVuaXggdGltZXN0YW1wIGF0IHdoaWNoIHBvb2wgcmV3YXJkIHN0YXRlIGlzIGV2YWx1YXRlZC4KLy8gICAtIGN1cnJlbnRUaWNrOiBQb29sIHRpY2sgdXNlZCB0byBkZXRlcm1pbmUgd2hldGhlciB0aGUgcG9zaXRpb24gaXMgYmVsb3csIGluc2lkZSwgb3IgYWJvdmUgaXRzIHJhbmdlLgovLyAgIC0gZGVwb3NpdDogUG9zaXRpb24gZGVwb3NpdCB3aG9zZSBsaXF1aWRpdHkgYW5kIGJvdW5kYXJ5IHRpY2tzIGRldGVybWluZSB0aGUgcmF3IHJld2FyZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHJld2FyZDogUTEyOC1zY2FsZWQgcmF3IHJld2FyZCBhY2N1bXVsYXRvciBmb3IgdGhlIHBvc2l0aW9uOyBkZWJ0LCB3YXJtdXAgcmF0aW9zLCBhbmQgZmVlcyBhcmUgbm90IGFwcGxpZWQuCmZ1bmMgKHNlbGYgKlBvb2xSZXNvbHZlcikgQ2FsY3VsYXRlUmF3UmV3YXJkRm9yUG9zaXRpb24oY3VycmVudFRpbWUgaW50NjQsIGN1cnJlbnRUaWNrIGludDMyLCBkZXBvc2l0ICpzci5EZXBvc2l0KSAqdTI1Ni5VaW50IHsKCXZhciByZXdhcmRBY2MgKnUyNTYuVWludAoKCWdsb2JhbEFjYyA6PSBzZWxmLmNhbGN1bGF0ZUdsb2JhbFJld2FyZFJhdGlvQWNjdW11bGF0aW9uKGN1cnJlbnRUaW1lLCBzZWxmLkN1cnJlbnRTdGFrZWRMaXF1aWRpdHkoY3VycmVudFRpbWUpKQoKCWxvd2VyQWNjIDo9IHNlbGYub3V0c2lkZUFjY3VtdWxhdGlvbkF0KGRlcG9zaXQuVGlja0xvd2VyKCksIGN1cnJlbnRUaW1lKQoJdXBwZXJBY2MgOj0gc2VsZi5vdXRzaWRlQWNjdW11bGF0aW9uQXQoZGVwb3NpdC5UaWNrVXBwZXIoKSwgY3VycmVudFRpbWUpCglpZiBjdXJyZW50VGljayA8IGRlcG9zaXQuVGlja0xvd2VyKCkgewoJCXJld2FyZEFjYyA9IHUyNTYuWmVybygpLlN1Yihsb3dlckFjYywgdXBwZXJBY2MpCgl9IGVsc2UgaWYgY3VycmVudFRpY2sgPj0gZGVwb3NpdC5UaWNrVXBwZXIoKSB7CgkJcmV3YXJkQWNjID0gdTI1Ni5aZXJvKCkuU3ViKHVwcGVyQWNjLCBsb3dlckFjYykKCX0gZWxzZSB7CgkJcmV3YXJkQWNjID0gdTI1Ni5aZXJvKCkuU3ViKGdsb2JhbEFjYywgbG93ZXJBY2MpCgkJcmV3YXJkQWNjID0gcmV3YXJkQWNjLlN1YihyZXdhcmRBY2MsIHVwcGVyQWNjKQoJfQoKCXJldHVybiByZXdhcmRBY2MKfQoax3sKIHJld2FyZF9jYWxjdWxhdGlvbl9wb29sX3RpZXIuZ25vEqJ7cGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkiZXJyb3JzIgoKCSJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCWJwdHJlZSAiZ25vLmxhbmQvcC9udC9icHRyZWUvdjAiCgoJc3IgImduby5sYW5kL3IvZ25vc3dhcC9zdGFrZXIiCikKCmNvbnN0ICgKCUFsbFRpZXJDb3VudCA9IDQgLy8gMCwgMSwgMiwgMwoJVGllcjEgICAgICAgID0gMQoJVGllcjIgICAgICAgID0gMgoJVGllcjMgICAgICAgID0gMwopCgovLyBUaWVyUmF0aW9Gcm9tQ291bnRzIGNhbGN1bGF0ZXMgdGhlIHJhdGlvIGRpc3RyaWJ1dGlvbiBmb3IgZWFjaCB0aWVyIGJhc2VkIG9uIHBvb2wgY291bnRzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAtIHRpZXIxQ291bnQgKHVpbnQ2NCk6IE51bWJlciBvZiBwb29scyBpbiB0aWVyIDEuCi8vIC0gdGllcjJDb3VudCAodWludDY0KTogTnVtYmVyIG9mIHBvb2xzIGluIHRpZXIgMi4KLy8gLSB0aWVyM0NvdW50ICh1aW50NjQpOiBOdW1iZXIgb2YgcG9vbHMgaW4gdGllciAzLgovLwovLyBSZXR1cm5zOgovLyAtIFRpZXJSYXRpbzogVGhlIHJhdGlvIGRpc3RyaWJ1dGlvbiBhY3Jvc3MgdGllciAxLCAyLCBhbmQgMywgc2NhbGVkIHVwIGJ5IDEwMC4KZnVuYyBUaWVyUmF0aW9Gcm9tQ291bnRzKHRpZXIxQ291bnQsIHRpZXIyQ291bnQsIHRpZXIzQ291bnQgdWludDY0KSBzci5UaWVyUmF0aW8gewoJLy8gdGllcjEgYWx3YXlzIGV4aXN0cy4KCS8vCgkvLyBUaWVyUmF0aW8gaXMgZGVjbGFyZWQgaW4gL3IvZ25vc3dhcC9zdGFrZXI7IGNvbnN0cnVjdGluZyBpdCB2aWEgYQoJLy8gY29tcG9zaXRlIGxpdGVyYWwgaGVyZSAoL3IvZ25vc3dhcC9zdGFrZXIvdjEpIHRyaXBzIHRoZSBjb25zdHJ1Y3Rpb24tdGltZQoJLy8gY2hlY2sgKCJjYW5ub3QgYWxsb2NhdGUgLi4uIGluIHJlYWxtIC4uLiIpLiBSb3V0ZSB0aHJvdWdoIHRoZSBkb21haW4KCS8vIGNvbnN0cnVjdG9yIHNyLk5ld1RpZXJSYXRpbyBzbyBhbGxvY2F0aW9uIGhhcHBlbnMgaW4gdGhlIGRlY2xhcmluZyByZWFsbS4KCWlmIHRpZXIyQ291bnQgPT0gMCAmJiB0aWVyM0NvdW50ID09IDAgewoJCXJldHVybiBzci5OZXdUaWVyUmF0aW8oMTAwLCAwLCAwKQoJfQoJaWYgdGllcjJDb3VudCA9PSAwIHsKCQlyZXR1cm4gc3IuTmV3VGllclJhdGlvKDgwLCAwLCAyMCkKCX0KCWlmIHRpZXIzQ291bnQgPT0gMCB7CgkJcmV0dXJuIHNyLk5ld1RpZXJSYXRpbyg3MCwgMzAsIDApCgl9CglyZXR1cm4gc3IuTmV3VGllclJhdGlvKDUwLCAzMCwgMjApCn0KCi8vIFBvb2xUaWVyIG1hbmFnZXMgcG9vbCBjb3VudHMsIHJhdGlvcywgYW5kIHJld2FyZHMgZm9yIGRpZmZlcmVudCB0aWVycy4KLy8KLy8gRmllbGRzOgovLyAtIG1lbWJlcnNoaXA6IFRyYWNrcyB3aGljaCB0aWVyIGEgcG9vbCBiZWxvbmdzIHRvIChwb29sUGF0aCAtPiBibG9ja051bWJlciAtPiB0aWVyKS4KLy8KLy8gTWV0aG9kczoKLy8gLSBDdXJyZW50Q291bnQ6IFJldHVybnMgdGhlIGN1cnJlbnQgY291bnQgb2YgcG9vbHMgaW4gYSB0aWVyIGF0IGEgc3BlY2lmaWMgdGltZXN0YW1wLgovLyAtIEN1cnJlbnRSYXRpbzogUmV0dXJucyB0aGUgY3VycmVudCByYXRpbyBmb3IgYSB0aWVyIGF0IGEgc3BlY2lmaWMgdGltZXN0YW1wLgovLyAtIEN1cnJlbnRUaWVyOiBSZXR1cm5zIHRoZSB0aWVyIG9mIGEgc3BlY2lmaWMgcG9vbCBhdCBhIGdpdmVuIHRpbWVzdGFtcC4KLy8gLSBDdXJyZW50UmV3YXJkOiBSZXRyaWV2ZXMgdGhlIHJld2FyZCBmb3IgYSB0aWVyIGF0IGEgc3BlY2lmaWMgdGltZXN0YW1wLgovLyAtIGNoYW5nZVRpZXI6IFVwZGF0ZXMgdGhlIHRpZXIgb2YgYSBwb29sIGFuZCByZWNhbGN1bGF0ZXMgcmF0aW9zLgp0eXBlIFBvb2xUaWVyIHN0cnVjdCB7CgltZW1iZXJzaGlwICpicHRyZWUuQlBUcmVlIC8vIHBvb2xQYXRoIC0+IHRpZXIoMSwgMiwgMykKCgl0aWVyUmF0aW8gc3IuVGllclJhdGlvCgoJY291bnRzIFtBbGxUaWVyQ291bnRddWludDY0CgoJbGFzdFJld2FyZENhY2hlVGltZXN0YW1wIGludDY0CgoJY3VycmVudEVtaXNzaW9uIGludDY0CgoJLy8gcmV0dXJucyBjdXJyZW50IGVtaXNzaW9uLgoJZ2V0RW1pc3Npb24gZnVuYygpIChpbnQ2NCwgZXJyb3IpCgkvLyBSZXR1cm5zIGEgbGlzdCBvZiBoYWx2aW5nIHRpbWVzdGFtcHMgYW5kIHRoZWlyIGVtaXNzaW9uIGFtb3VudHMgd2l0aGluIHRoZSBpbnRlcnZhbCBbc3RhcnQsIGVuZCkgaW4gYXNjZW5kaW5nIG9yZGVyLgoJLy8gVGhlIGZpcnN0IHJldHVybiB2YWx1ZSBpcyBhIGxpc3Qgb2YgdGltZXN0YW1wcyB3aGVyZSBoYWx2aW5nIG9jY3Vycy4KCS8vIFRoZSBzZWNvbmQgcmV0dXJuIHZhbHVlIGlzIGEgbGlzdCBvZiBlbWlzc2lvbiBhbW91bnRzIGNvcnJlc3BvbmRpbmcgdG8gZWFjaCBoYWx2aW5nIHRpbWVzdGFtcC4KCWdldEhhbHZpbmdCbG9ja3NJblJhbmdlIGZ1bmMoc3RhcnQsIGVuZCBpbnQ2NCkgKFtdaW50NjQsIFtdaW50NjQsIGVycm9yKQp9CgovLyBOZXdQb29sVGllciBjcmVhdGVzIGEgbmV3IFBvb2xUaWVyIGluc3RhbmNlIHdpdGggc2luZ2xlIGluaXRpYWwgMSB0aWVyIHBvb2wuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vIC0gcG9vbHM6IFRoZSBwb29sIGNvbGxlY3Rpb24uCi8vIC0gY3VycmVudFRpbWU6IFRoZSBjdXJyZW50IGJsb2NrIHRpbWUuCi8vIC0gaW5pdGlhbFBvb2xQYXRoOiBUaGUgcGF0aCBvZiB0aGUgaW5pdGlhbCBwb29sLgovLyAtIGdldEVtaXNzaW9uOiBBIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgY3VycmVudCBlbWlzc2lvbiB0byB0aGUgc3Rha2VyIGNvbnRyYWN0LgovLyAtIGdldEhhbHZpbmdCbG9ja3NJblJhbmdlOiBBIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhIGxpc3Qgb2YgaGFsdmluZyBibG9ja3Mgd2l0aGluIHRoZSBpbnRlcnZhbCBbc3RhcnQsIGVuZCkgaW4gYXNjZW5kaW5nIG9yZGVyLgovLwovLyBSZXR1cm5zOgovLyAtICpQb29sVGllcjogVGhlIG5ldyBQb29sVGllciBpbnN0YW5jZS4KZnVuYyBOZXdQb29sVGllcihwb29scyAqUG9vbHMsIGN1cnJlbnRUaW1lIGludDY0LCBpbml0aWFsUG9vbFBhdGggc3RyaW5nLCBnZXRFbWlzc2lvbiBmdW5jKCkgKGludDY0LCBlcnJvciksIGdldEhhbHZpbmdCbG9ja3NJblJhbmdlIGZ1bmMoc3RhcnQsIGVuZCBpbnQ2NCkgKFtdaW50NjQsIFtdaW50NjQsIGVycm9yKSkgKlBvb2xUaWVyIHsKCWN1cnJlbnRFbWlzc2lvbiwgZXJyIDo9IGdldEVtaXNzaW9uKCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCglyZXN1bHQgOj0gJlBvb2xUaWVyewoJCW1lbWJlcnNoaXA6ICAgICAgICAgICAgICAgc3IuTmV3QlBUcmVlTigxNiksCgkJdGllclJhdGlvOiAgICAgICAgICAgICAgICBUaWVyUmF0aW9Gcm9tQ291bnRzKDEsIDAsIDApLAoJCWxhc3RSZXdhcmRDYWNoZVRpbWVzdGFtcDogZ25zbWF0aC5TYWZlQWRkSW50NjQoY3VycmVudFRpbWUsIDEpLAoJCWdldEVtaXNzaW9uOiAgICAgICAgICAgICAgZ2V0RW1pc3Npb24sCgkJZ2V0SGFsdmluZ0Jsb2Nrc0luUmFuZ2U6ICBnZXRIYWx2aW5nQmxvY2tzSW5SYW5nZSwKCQljdXJyZW50RW1pc3Npb246ICAgICAgICAgIGN1cnJlbnRFbWlzc2lvbiwKCX0KCglwb29scy5zZXQoaW5pdGlhbFBvb2xQYXRoLCBzci5OZXdQb29sKGluaXRpYWxQb29sUGF0aCwgY3VycmVudFRpbWUrMSkpCglyZXN1bHQuY2hhbmdlVGllcihjdXJyZW50VGltZSsxLCBwb29scywgaW5pdGlhbFBvb2xQYXRoLCAxKQoJcmV0dXJuIHJlc3VsdAp9CgovLyBOZXdQb29sVGllckJ5IHJlY29uc3RydWN0cyBhIFBvb2xUaWVyIGZyb20gcGVyc2lzdGVkIG1lbWJlcnNoaXAsIHJhdGlvcywgY291bnRzLCBhbmQgY2FsbGJhY2tzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gbWVtYmVyc2hpcDogUGVyc2lzdGVkIHBvb2wtcGF0aC10by10aWVyIG1hcHBpbmcuCi8vICAgLSB0aWVyUmF0aW86IFBlcnNpc3RlZCByZXdhcmQtc2hhcmUgcmF0aW8gZm9yIGVhY2ggdGllci4KLy8gICAtIGNvdW50czogUGVyc2lzdGVkIG51bWJlciBvZiBwb29scyBpbiBlYWNoIHRpZXIgaW5kZXguCi8vICAgLSBsYXN0UmV3YXJkQ2FjaGVUaW1lc3RhbXA6IFRpbWVzdGFtcCB0aHJvdWdoIHdoaWNoIHJld2FyZCBjYWNoZXMgaGF2ZSBiZWVuIG1hdGVyaWFsaXplZC4KLy8gICAtIGN1cnJlbnRFbWlzc2lvbjogRW1pc3Npb24gcmF0ZSBjdXJyZW50bHkgdXNlZCBmb3IgcmV3YXJkIGFjY3J1YWwuCi8vICAgLSBnZXRFbWlzc2lvbjogQ2FsbGJhY2sgcmV0dXJuaW5nIHRoZSBjdXJyZW50IHN0YWtlciBlbWlzc2lvbiByYXRlIG9yIGFuIGVycm9yLgovLyAgIC0gZ2V0SGFsdmluZ0Jsb2Nrc0luUmFuZ2U6IENhbGxiYWNrIHJldHVybmluZyBoYWx2aW5nIHRpbWVzdGFtcHMgYW5kIGNvcnJlc3BvbmRpbmcgZW1pc3Npb25zIGluIFtzdGFydCwgZW5kKS4KLy8KLy8gUmV0dXJuczoKLy8gICAtICpQb29sVGllcjogUmVjb25zdHJ1Y3RlZCB0aWVyIG1hbmFnZXIgdXNpbmcgdGhlIHN1cHBsaWVkIHBlcnNpc3RlZCBzdGF0ZSBhbmQgY2FsbGJhY2tzLgpmdW5jIE5ld1Bvb2xUaWVyQnkoCgltZW1iZXJzaGlwICpicHRyZWUuQlBUcmVlLAoJdGllclJhdGlvIHNyLlRpZXJSYXRpbywKCWNvdW50cyBbQWxsVGllckNvdW50XXVpbnQ2NCwKCWxhc3RSZXdhcmRDYWNoZVRpbWVzdGFtcCBpbnQ2NCwKCWN1cnJlbnRFbWlzc2lvbiBpbnQ2NCwKCWdldEVtaXNzaW9uIGZ1bmMoKSAoaW50NjQsIGVycm9yKSwKCWdldEhhbHZpbmdCbG9ja3NJblJhbmdlIGZ1bmMoc3RhcnQsIGVuZCBpbnQ2NCkgKFtdaW50NjQsIFtdaW50NjQsIGVycm9yKSwKKSAqUG9vbFRpZXIgewoJcmV0dXJuICZQb29sVGllcnsKCQltZW1iZXJzaGlwOiAgICAgICAgICAgICAgIG1lbWJlcnNoaXAsCgkJdGllclJhdGlvOiAgICAgICAgICAgICAgICB0aWVyUmF0aW8sCgkJY291bnRzOiAgICAgICAgICAgICAgICAgICBjb3VudHMsCgkJbGFzdFJld2FyZENhY2hlVGltZXN0YW1wOiBsYXN0UmV3YXJkQ2FjaGVUaW1lc3RhbXAsCgkJZ2V0RW1pc3Npb246ICAgICAgICAgICAgICBnZXRFbWlzc2lvbiwKCQlnZXRIYWx2aW5nQmxvY2tzSW5SYW5nZTogIGdldEhhbHZpbmdCbG9ja3NJblJhbmdlLAoJCWN1cnJlbnRFbWlzc2lvbjogICAgICAgICAgY3VycmVudEVtaXNzaW9uLAoJfQp9CgovLyBDdXJyZW50UmV3YXJkIHJldHVybnMgdGhlIGN1cnJlbnQgcGVyLXBvb2wgcmV3YXJkIGZvciB0aGUgZ2l2ZW4gdGllci4KLy8gUGFyYW1ldGVyczoKLy8gICAtIHRpZXI6IFRpZXIgbnVtYmVyIHdob3NlIGN1cnJlbnQgZW1pc3Npb24gcmV3YXJkIGlzIHJlcXVlc3RlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDY0OiBDdXJyZW50IHBlci1wb29sIHJld2FyZCBmb3IgdGhlIHRpZXIsIG9yIHplcm8gd2hlbiB0aGUgY2FsY3VsYXRpb24gY2Fubm90IHByb2R1Y2UgYSByZXdhcmQuCi8vICAgLSBlcnJvcjogRXJyb3IgZnJvbSBlbWlzc2lvbiBsb29rdXAsIGludmFsaWQtdGllciBsb29rdXAsIG9yIHJld2FyZCBjYWxjdWxhdGlvbjsgbmlsIHdoZW4gdGhlIHJld2FyZCBjYWxjdWxhdGlvbiBzdWNjZWVkcy4KZnVuYyAoc2VsZiAqUG9vbFRpZXIpIEN1cnJlbnRSZXdhcmQodGllciB1aW50NjQpIChpbnQ2NCwgZXJyb3IpIHsKCWN1cnJlbnRFbWlzc2lvbiwgZXJyIDo9IHNlbGYuZ2V0RW1pc3Npb24oKQoJaWYgZXJyICE9IG5pbCB7CgkJcmV0dXJuIDAsIGVycgoJfQoJdGllclJhdGlvLCBlcnIgOj0gc2VsZi50aWVyUmF0aW8uR2V0KHRpZXIpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgbWFrZUVycm9yV2l0aERldGFpbHMoZXJySW52YWxpZFBvb2xUaWVyLCBlcnIuRXJyb3IoKSkKCX0KCgl0aWVyUmF0aW9JbnQ2NCA6PSBpbnQ2NCh0aWVyUmF0aW8pCgljb3VudCA6PSBpbnQ2NChzZWxmLkN1cnJlbnRDb3VudCh0aWVyKSkKCglyZXR1cm4gY2FsY3VsYXRlUG9vbFJld2FyZChjdXJyZW50RW1pc3Npb24sIHRpZXJSYXRpb0ludDY0LCBjb3VudCkKfQoKLy8gQ3VycmVudENvdW50IHJldHVybnMgdGhlIGN1cnJlbnQgY291bnQgb2YgcG9vbHMgaW4gdGhlIGdpdmVuIHRpZXIuCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSB0aWVyOiBUaWVyIGluZGV4IHdob3NlIHBvb2wgY291bnQgaXMgcmVxdWVzdGVkOyBvdXQtb2YtcmFuZ2UgaW5kZXhlcyByZXR1cm4gemVyby4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGludDogTnVtYmVyIG9mIHBvb2xzIGN1cnJlbnRseSBhc3NpZ25lZCB0byB0aWVyLgpmdW5jIChzZWxmICpQb29sVGllcikgQ3VycmVudENvdW50KHRpZXIgdWludDY0KSBpbnQgewoJaWYgdGllciA+PSBBbGxUaWVyQ291bnQgewoJCXJldHVybiAwCgl9CglyZXR1cm4gaW50KHNlbGYuY291bnRzW3RpZXJdKQp9CgovLyBDdXJyZW50QWxsVGllckNvdW50cyByZXR1cm5zIHRoZSBjdXJyZW50IGNvdW50IG9mIHBvb2xzIGluIGVhY2ggdGllci4KLy8gUmV0dXJuczoKLy8gICAtIFtddWludDY0OiBTbmFwc2hvdCBvZiBwb29sIGNvdW50cyBmb3IgdGllciBpbmRleGVzIDAgdGhyb3VnaCBBbGxUaWVyQ291bnQtMS4KZnVuYyAoc2VsZiAqUG9vbFRpZXIpIEN1cnJlbnRBbGxUaWVyQ291bnRzKCkgW111aW50NjQgewoJb3V0IDo9IG1ha2UoW111aW50NjQsIEFsbFRpZXJDb3VudCkKCWNvcHkob3V0LCBzZWxmLmNvdW50c1s6XSkKCXJldHVybiBvdXQgLy8gcmV0dXJuaW5nIHNuYXBzaG90Cn0KCi8vIEN1cnJlbnRUaWVyIHJldHVybnMgdGhlIHRpZXIgb2YgdGhlIGdpdmVuIHBvb2wuCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogUG9vbCBwYXRoIHdob3NlIGN1cnJlbnQgdGllciBtZW1iZXJzaGlwIGlzIHJlcXVlc3RlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHRpZXI6IEN1cnJlbnQgdGllciBudW1iZXIsIG9yIHplcm8gd2hlbiB0aGUgcG9vbCBpcyBub3QgaW4gdGhlIG1lbWJlcnNoaXAgdHJlZS4KZnVuYyAoc2VsZiAqUG9vbFRpZXIpIEN1cnJlbnRUaWVyKHBvb2xQYXRoIHN0cmluZykgKHRpZXIgdWludDY0KSB7CglpZiB0aWVySSA6PSBzZWxmLm1lbWJlcnNoaXAuR2V0KHBvb2xQYXRoKTsgdGllckkgPT0gbmlsIHsKCQlyZXR1cm4gMAoJfSBlbHNlIHsKCQl2YXIgb2sgYm9vbAoJCXRpZXIsIG9rID0gdGllckkuKHVpbnQ2NCkKCQlpZiAhb2sgewoJCQlwYW5pYygiZmFpbGVkIHRvIGNhc3QgdGllciB0byB1aW50NjQiKQoJCX0KCQlyZXR1cm4gdGllcgoJfQp9CgovLyBjaGFuZ2VUaWVyIHVwZGF0ZXMgdGhlIHRpZXIgb2YgYSBwb29sLCByZWNhbGN1bGF0ZXMgcmF0aW9zLCBhbmQgYXBwbGllcwovLyB1cGRhdGVkIHBlci1wb29sIHJld2FyZCB0byBlYWNoIG9mIHRoZSBwb29scy4KZnVuYyAoc2VsZiAqUG9vbFRpZXIpIGNoYW5nZVRpZXIoY3VycmVudFRpbWUgaW50NjQsIHBvb2xzICpQb29scywgcG9vbFBhdGggc3RyaW5nLCBuZXh0VGllciB1aW50NjQpIG1hcFt1aW50NjRdaW50NjQgewoJY3VycmVudFRpZXIgOj0gc2VsZi5DdXJyZW50VGllcihwb29sUGF0aCkKCWlmIGN1cnJlbnRUaWVyID09IG5leHRUaWVyIHsKCQkvLyBubyBjaGFuZ2UsIHJldHVybgoJCXJldHVybiBtYWtlKG1hcFt1aW50NjRdaW50NjQpCgl9Cglhc3NlcnRUaWVyMUhhc1NwYXJlUG9vbChjdXJyZW50VGllciwgc2VsZi5jb3VudHNbVGllcjFdKQoKCXNlbGYuY2FjaGVSZXdhcmQoY3VycmVudFRpbWUsIHBvb2xzKQoKCS8vIGRlY3JlbWVudCBjb3VudCBmcm9tIGN1cnJlbnQgdGllciBpZiBpdCBleGlzdHMKCWlmIGN1cnJlbnRUaWVyID4gMCB7CgkJaWYgc2VsZi5jb3VudHNbY3VycmVudFRpZXJdID09IDAgewoJCQlwYW5pYygiY291bnRzIHVuZGVyZmxvdzogcmVtb3ZpbmcgZnJvbSBlbXB0eSB0aWVyIikKCQl9CgkJc2VsZi5jb3VudHNbY3VycmVudFRpZXJdLS0KCX0KCglpZiBuZXh0VGllciA9PSAwIHsKCQkvLyByZW1vdmVkIGZyb20gdGhlIHRpZXIKCQlzZWxmLm1lbWJlcnNoaXAuUmVtb3ZlKHBvb2xQYXRoKQoJCXBvb2wsIG9rIDo9IHBvb2xzLkdldChwb29sUGF0aCkKCQlpZiAhb2sgewoJCQlwYW5pYygiY2hhbmdlVGllcjogcG9vbCBub3QgZm91bmQiKQoJCX0KCQlwb29sUmVzb2x2ZXIgOj0gTmV3UG9vbFJlc29sdmVyKHBvb2wpCgkJLy8gcHJldmVudCBuZXcgcmV3YXJkcyBmcm9tIGFjY3VtdWxhdGluZyBhZnRlciB0aWVyIHJlbW92YWwKCQlwb29sUmVzb2x2ZXIuY2FjaGVSZXdhcmQoY3VycmVudFRpbWUsIDApCgl9IGVsc2UgewoJCS8vIGhhbmRsZSBhbGwgbW92ZS9hZGQgb3BlcmF0aW9ucwoJCXNlbGYubWVtYmVyc2hpcC5TZXQocG9vbFBhdGgsIG5leHRUaWVyKQoJCXNlbGYuY291bnRzW25leHRUaWVyXSsrCgl9CgoJc2VsZi50aWVyUmF0aW8gPSBUaWVyUmF0aW9Gcm9tQ291bnRzKHNlbGYuY291bnRzW1RpZXIxXSwgc2VsZi5jb3VudHNbVGllcjJdLCBzZWxmLmNvdW50c1tUaWVyM10pCgljdXJyZW50RW1pc3Npb24sIGVyciA6PSBzZWxmLmdldEVtaXNzaW9uKCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCXRpZXJSZXdhcmRzIDo9IHNlbGYuY29tcHV0ZVRpZXJSZXdhcmRzKGN1cnJlbnRFbWlzc2lvbikKCgkvLyBDYWNoZSB1cGRhdGVkIHJld2FyZCBmb3IgZWFjaCB0aWVyZWQgcG9vbAoJc2VsZi5tZW1iZXJzaGlwLkl0ZXJhdGUoIiIsICIiLCBmdW5jKGtleSBzdHJpbmcsIHZhbHVlIGFueSkgYm9vbCB7CgkJcG9vbCwgb2sgOj0gcG9vbHMuR2V0KGtleSkKCQlpZiAhb2sgewoJCQlwYW5pYygiY2hhbmdlVGllcjogcG9vbCBub3QgZm91bmQiKQoJCX0KCQl0aWVyLCBvayA6PSB2YWx1ZS4odWludDY0KQoJCWlmICFvayB7CgkJCXBhbmljKCJmYWlsZWQgdG8gY2FzdCB2YWx1ZSB0byB1aW50NjQiKQoJCX0KCgkJcG9vbFJld2FyZCwgb2sgOj0gdGllclJld2FyZHNbdGllcl0KCQlpZiAhb2sgewoJCQlyZXR1cm4gZmFsc2UgLy8gU2tpcCBpZiBubyBwb29scyBpbiB0aWVyCgkJfQoKCQlwb29sUmVzb2x2ZXIgOj0gTmV3UG9vbFJlc29sdmVyKHBvb2wpCgkJcG9vbFJlc29sdmVyLmNhY2hlUmV3YXJkKGN1cnJlbnRUaW1lLCBwb29sUmV3YXJkKQoJCXJldHVybiBmYWxzZQoJfSkKCglzZWxmLmN1cnJlbnRFbWlzc2lvbiA9IGN1cnJlbnRFbWlzc2lvbgoKCXJldHVybiB0aWVyUmV3YXJkcwp9CgovLyBjYWNoZVJld2FyZCBNVVNUIGJlIGNhbGxlZCBiZWZvcmUgY2FsY3VsYXRpbmcgYW55IHBvc2l0aW9uIHJld2FyZC4KLy8gY2FjaGVSZXdhcmQgdXBkYXRlcyB0aGUgcmV3YXJkIGNhY2hlIGZvciBlYWNoIHBvb2wsIGFjY291bnRpbmcgZm9yIGFueSBoYWx2aW5nIGV2ZW50cwovLyB0aGF0IG9jY3VycmVkIGJldHdlZW4gdGhlIGxhc3QgY2FjaGVkIHRpbWVzdGFtcCBhbmQgdGhlIGN1cnJlbnQgdGltZXN0YW1wLgovLyBOb3RlOiBCbG9jayBoZWlnaHQgaXMgdXNlZCBvbmx5IGZvciBldmVudCB0cmFja2luZyBwdXJwb3Nlcy4KLy8gdGllckNvbnRleHRPZiByZXR1cm5zIHRoZSBwb29sJ3MgdGllciBhbmQgdGhlIHJhdGlvL2NvdW50IHNldHRpbmcgaXRzIGN1cnJlbnQgZW1pc3Npb24gcmF0ZS4KZnVuYyAoc2VsZiAqUG9vbFRpZXIpIHRpZXJDb250ZXh0T2YocG9vbFBhdGggc3RyaW5nKSAodWludDY0LCB1aW50NjQsIHVpbnQ2NCwgZXJyb3IpIHsKCXRpZXIgOj0gc2VsZi5DdXJyZW50VGllcihwb29sUGF0aCkKCWlmIHRpZXIgPT0gMCB8fCB0aWVyID49IEFsbFRpZXJDb3VudCB7CgkJcmV0dXJuIHRpZXIsIDAsIDAsIG5pbAoJfQoKCXJhdGlvLCBlcnIgOj0gc2VsZi50aWVyUmF0aW8uR2V0KHRpZXIpCglpZiBlcnIgIT0gbmlsIHsKCQlyZXR1cm4gMCwgMCwgMCwgbWFrZUVycm9yV2l0aERldGFpbHMoZXJySW52YWxpZFBvb2xUaWVyLCBlcnIuRXJyb3IoKSkKCX0KCglyZXR1cm4gdGllciwgcmF0aW8sIHNlbGYuY291bnRzW3RpZXJdLCBuaWwKfQoKZnVuYyAoc2VsZiAqUG9vbFRpZXIpIGNhY2hlUmV3YXJkKGN1cnJlbnRUaW1lc3RhbXAgaW50NjQsIHBvb2xzICpQb29scykgewoJbGFzdFRpbWVzdGFtcCA6PSBzZWxmLmxhc3RSZXdhcmRDYWNoZVRpbWVzdGFtcAoKCWlmIGN1cnJlbnRUaW1lc3RhbXAgPD0gbGFzdFRpbWVzdGFtcCB7CgkJLy8gbm8gbmVlZCB0byBjaGVjawoJCXJldHVybgoJfQoKCS8vIGZpbmQgaGFsdmluZyBibG9ja3MgaW4gcmFuZ2UKCWhhbHZpbmdUaW1lc3RhbXBzLCBoYWx2aW5nRW1pc3Npb25zLCBlcnIgOj0gc2VsZi5nZXRIYWx2aW5nQmxvY2tzSW5SYW5nZShsYXN0VGltZXN0YW1wLCBjdXJyZW50VGltZXN0YW1wKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCWlmIGxlbihoYWx2aW5nVGltZXN0YW1wcykgPT0gMCB7CgkJc2VsZi5hcHBseUNhY2hlVG9BbGxQb29scyhwb29scywgY3VycmVudFRpbWVzdGFtcCwgc2VsZi5jdXJyZW50RW1pc3Npb24pCgkJc2VsZi5sYXN0UmV3YXJkQ2FjaGVUaW1lc3RhbXAgPSBjdXJyZW50VGltZXN0YW1wCgkJcmV0dXJuCgl9CgoJZm9yIGksIGh2VGltZXN0YW1wIDo9IHJhbmdlIGhhbHZpbmdUaW1lc3RhbXBzIHsKCQllbWlzc2lvbiA6PSBoYWx2aW5nRW1pc3Npb25zW2ldCgkJLy8gY2FjaGluZzogW2xhc3RUaW1lc3RhbXAsIGh2VGltZXN0YW1wKQoJCXNlbGYuYXBwbHlDYWNoZVRvQWxsUG9vbHMocG9vbHMsIGh2VGltZXN0YW1wLCBlbWlzc2lvbikKCgkJLy8gaGFsdmUgZW1pc3Npb25zIHdoZW4gaGFsdmluZ0Jsb2NrIGlzIHJlYWNoZWQKCQlzZWxmLmN1cnJlbnRFbWlzc2lvbiA9IGVtaXNzaW9uCgl9CgoJLy8gcmVtYWluaW5nIHJhbmdlIFtsYXN0VGltZXN0YW1wLCBjdXJyZW50VGltZXN0YW1wKQoJc2VsZi5hcHBseUNhY2hlVG9BbGxQb29scyhwb29scywgY3VycmVudFRpbWVzdGFtcCwgc2VsZi5jdXJyZW50RW1pc3Npb24pCgoJc2VsZi5sYXN0UmV3YXJkQ2FjaGVUaW1lc3RhbXAgPSBjdXJyZW50VGltZXN0YW1wCn0KCi8vIGNhY2hlUmV3YXJkRm9yUG9vbCBjYWNoZXMgaW50ZXJuYWwgcmV3YXJkL2FjY3VtdWxhdG9ycyBmb3IgYSBzaW5nbGUgcG9vbCBvbmx5LgovLyBUaGlzIGF2b2lkcyBpdGVyYXRpbmcgYWxsIHRpZXJlZCBwb29scyBvbiBldmVyeSBwb3NpdGlvbiByZXdhcmQgY2FsY3VsYXRpb24uCmZ1bmMgKHNlbGYgKlBvb2xUaWVyKSBjYWNoZVJld2FyZEZvclBvb2woY3VycmVudFRpbWVzdGFtcCBpbnQ2NCwgcG9vbHMgKlBvb2xzLCBwb29sUGF0aCBzdHJpbmcpIHsKCXBvb2wsIG9rIDo9IHBvb2xzLkdldChwb29sUGF0aCkKCWlmICFvayB7CgkJcmV0dXJuCgl9CgoJdGllck51bSA6PSBzZWxmLkN1cnJlbnRUaWVyKHBvb2xQYXRoKQoJLy8gUG9vbCBub3QgaW4gdGhlIGludGVybmFsLWluY2VudGl2ZSBzeXN0ZW0uCglpZiB0aWVyTnVtID09IDAgewoJCXJldHVybgoJfQoKCS8vIEZpbmQgdGhlIGxhdGVzdCByZXdhcmQgY2FjaGUgdGltZXN0YW1wIGZvciB0aGlzIHBvb2wuCglsYXN0VGltZXN0YW1wIDo9IGludDY0KDApCgloYXNMYXN0IDo9IGZhbHNlCglwb29sLlJld2FyZENhY2hlKCkuUmV2ZXJzZUl0ZXJhdGUoMCwgY3VycmVudFRpbWVzdGFtcCwgZnVuYyhrZXkgaW50NjQsIF8gYW55KSBib29sIHsKCQlsYXN0VGltZXN0YW1wID0ga2V5CgkJaGFzTGFzdCA9IHRydWUKCQlyZXR1cm4gdHJ1ZQoJfSkKCglpZiAhaGFzTGFzdCB7CgkJLy8gRmFsbGJhY2sgdG8gZ2xvYmFsIHRpZXIgY2FjaGUgY3Vyc29yLgoJCWxhc3RUaW1lc3RhbXAgPSBzZWxmLmxhc3RSZXdhcmRDYWNoZVRpbWVzdGFtcAoJfQoKCWlmIGN1cnJlbnRUaW1lc3RhbXAgPD0gbGFzdFRpbWVzdGFtcCB7CgkJcmV0dXJuCgl9CgoJLy8gRGV0ZXJtaW5lIGhhbHZpbmcgYm91bmRhcmllcyBzaW5jZSB0aGUgcG9vbCdzIGxhc3QgY2FjaGVkIHJld2FyZCB0aW1lc3RhbXAuCgloYWx2aW5nVGltZXN0YW1wcywgaGFsdmluZ0VtaXNzaW9ucywgZXJyIDo9IHNlbGYuZ2V0SGFsdmluZ0Jsb2Nrc0luUmFuZ2UobGFzdFRpbWVzdGFtcCwgY3VycmVudFRpbWVzdGFtcCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCXBvb2xSZXNvbHZlciA6PSBOZXdQb29sUmVzb2x2ZXIocG9vbCkKCglpZiBsZW4oaGFsdmluZ1RpbWVzdGFtcHMpID09IDAgewoJCS8vIE5vIGVtaXNzaW9uIGNoYW5nZSB3aXRoaW4gdGhlIHJhbmdlID0+IHVzZSB0aGUgbGl2ZSBlbWlzc2lvbi4KCQljdXJyZW50RW1pc3Npb24sIGVyciA6PSBzZWxmLmdldEVtaXNzaW9uKCkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcGFuaWMoZXJyKQoJCX0KCQlzZWxmLmFwcGx5Q2FjaGVUb1Bvb2wocG9vbFJlc29sdmVyLCB0aWVyTnVtLCBjdXJyZW50VGltZXN0YW1wLCBjdXJyZW50RW1pc3Npb24pCgkJcmV0dXJuCgl9CgoJLy8gQXBwbHkgY2FjaGluZyBhdCBldmVyeSBoYWx2aW5nIGJvdW5kYXJ5LgoJY3VycmVudEVtaXNzaW9uIDo9IGludDY0KDApCglmb3IgaSwgaHZUaW1lc3RhbXAgOj0gcmFuZ2UgaGFsdmluZ1RpbWVzdGFtcHMgewoJCWN1cnJlbnRFbWlzc2lvbiA9IGhhbHZpbmdFbWlzc2lvbnNbaV0KCQlzZWxmLmFwcGx5Q2FjaGVUb1Bvb2wocG9vbFJlc29sdmVyLCB0aWVyTnVtLCBodlRpbWVzdGFtcCwgY3VycmVudEVtaXNzaW9uKQoJfQoKCS8vIFJlbWFpbmluZyByYW5nZSBbbGFzdFRpbWVzdGFtcCwgY3VycmVudFRpbWVzdGFtcCkuCglzZWxmLmFwcGx5Q2FjaGVUb1Bvb2wocG9vbFJlc29sdmVyLCB0aWVyTnVtLCBjdXJyZW50VGltZXN0YW1wLCBjdXJyZW50RW1pc3Npb24pCn0KCi8vIGFwcGx5Q2FjaGVUb1Bvb2wgYXBwbGllcyB0aGUgY2FjaGVkIHJld2FyZCB0byBhbGwgdGllcmVkIHBvb2wuCmZ1bmMgKHNlbGYgKlBvb2xUaWVyKSBhcHBseUNhY2hlVG9Qb29sKHBvb2xSZXNvbHZlciAqUG9vbFJlc29sdmVyLCB0aWVyTnVtIHVpbnQ2NCwgY3VycmVudFRpbWVzdGFtcCwgZW1pc3Npb25JblRoaXNJbnRlcnZhbCBpbnQ2NCkgewoJdGllclJld2FyZHMgOj0gc2VsZi5jb21wdXRlVGllclJld2FyZHMoZW1pc3Npb25JblRoaXNJbnRlcnZhbCkKCXBvb2xSZXdhcmQsIG9rIDo9IHRpZXJSZXdhcmRzW3RpZXJOdW1dCglpZiAhb2sgewoJCXJldHVybgoJfQoKCXBvb2xSZXNvbHZlci5jYWNoZVJld2FyZChjdXJyZW50VGltZXN0YW1wLCBwb29sUmV3YXJkKQp9CgovLyBhcHBseUNhY2hlVG9BbGxQb29scyBhcHBsaWVzIHRoZSBjYWNoZWQgcmV3YXJkIHRvIGFsbCB0aWVyZWQgcG9vbHMuCmZ1bmMgKHNlbGYgKlBvb2xUaWVyKSBhcHBseUNhY2hlVG9BbGxQb29scyhwb29scyAqUG9vbHMsIGN1cnJlbnRUaW1lc3RhbXAsIGVtaXNzaW9uSW5UaGlzSW50ZXJ2YWwgaW50NjQpIHsKCS8vIGNhbGN1bGF0ZSBkZW5vbWluYXRvciBhbmQgbnVtYmVyIG9mIHBvb2xzIGluIGVhY2ggdGllcgoJY291bnRzIDo9IHNlbGYuQ3VycmVudEFsbFRpZXJDb3VudHMoKQoJdGllclJld2FyZHMgOj0gc2VsZi5jb21wdXRlVGllclJld2FyZHMoZW1pc3Npb25JblRoaXNJbnRlcnZhbCkKCgkvLyBhcHBseSBjYWNoZSB0byBhbGwgcG9vbHMKCXNlbGYubWVtYmVyc2hpcC5JdGVyYXRlKCIiLCAiIiwgZnVuYyhrZXkgc3RyaW5nLCB2YWx1ZSBhbnkpIGJvb2wgewoJCXBvb2wsIG9rIDo9IHBvb2xzLkdldChrZXkpCgkJaWYgIW9rIHsKCQkJcmV0dXJuIGZhbHNlCgkJfQoKCQl0aWVyTnVtLCBvayA6PSB2YWx1ZS4odWludDY0KQoJCWlmICFvayB7CgkJCXBhbmljKCJmYWlsZWQgdG8gY2FzdCB2YWx1ZSB0byB1aW50NjQiKQoJCX0KCQkvLyBTa2lwIHBvb2xzIHdpdGggdGllciAwIChyZW1vdmVkIGZyb20gdGllciBzeXN0ZW0pCgkJaWYgdGllck51bSA9PSAwIHsKCQkJcmV0dXJuIGZhbHNlCgkJfQoKCQlpZiBjb3VudHNbdGllck51bV0gPT0gMCB7CgkJCXJldHVybiBmYWxzZSAvLyBTa2lwIGlmIG5vIHBvb2xzIGluIHRpZXIKCQl9CgoJCXBvb2xSZXdhcmQsIG9rIDo9IHRpZXJSZXdhcmRzW3RpZXJOdW1dCgkJaWYgIW9rIHsKCQkJcmV0dXJuIGZhbHNlCgkJfQoKCQkvLyBhY2N1bXVsYXRlIHRoZSByZXdhcmQgZm9yIHRoZSBpbnRlcnZhbCAoc3RhcnRCbG9jayB0byBlbmRCbG9jaykgaW4gdGhlIFBvb2wKCQlwb29sUmVzb2x2ZXIgOj0gTmV3UG9vbFJlc29sdmVyKHBvb2wpCgkJcG9vbFJlc29sdmVyLmNhY2hlUmV3YXJkKGN1cnJlbnRUaW1lc3RhbXAsIHBvb2xSZXdhcmQpCgkJcmV0dXJuIGZhbHNlCgl9KQp9CgovLyBJc0ludGVybmFsbHlJbmNlbnRpdml6ZWRQb29sIHJldHVybnMgdHJ1ZSBpZiB0aGUgcG9vbCBpcyBpbiBhIHRpZXIuCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb29sUGF0aDogUG9vbCBwYXRoIHdob3NlIG1lbWJlcnNoaXAgaXMgY2hlY2tlZC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGJvb2w6IFRydWUgd2hlbiBwb29sUGF0aCBiZWxvbmdzIHRvIGEgbm9uemVybyBpbnRlcm5hbC1pbmNlbnRpdmUgdGllcjsgZmFsc2Ugb3RoZXJ3aXNlLgpmdW5jIChzZWxmICpQb29sVGllcikgSXNJbnRlcm5hbGx5SW5jZW50aXZpemVkUG9vbChwb29sUGF0aCBzdHJpbmcpIGJvb2wgewoJcmV0dXJuIHNlbGYuQ3VycmVudFRpZXIocG9vbFBhdGgpID4gMAp9CgovLyBjYWxjdWxhdGVQb29sUmV3YXJkIGNhbGN1bGF0ZXMgdGhlIHJld2FyZCBmb3IgYSBwb29sIGJhc2VkIG9uIHRoZSBlbWlzc2lvbiwgdGllciByYXRpbywgYW5kIHRpZXIgY291bnQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vIC0gZW1pc3Npb246IFRoZSBlbWlzc2lvbiBmb3IgdGhlIHBvb2wuCi8vIC0gdGllclJhdGlvOiBUaGUgdGllciByYXRpbyBmb3IgdGhlIHBvb2wuCi8vIC0gdGllckNvdW50OiBUaGUgdGllciBjb3VudCBmb3IgdGhlIHBvb2wuCi8vCi8vIFJldHVybnM6Ci8vIC0gaW50NjQ6IFRoZSByZXdhcmQgZm9yIHRoZSBwb29sLgovLyAtIGVycm9yOiBBbiBpbnZhbGlkIGNhbGN1bGF0aW9uIGlucHV0LgpmdW5jIGNhbGN1bGF0ZVBvb2xSZXdhcmQoZW1pc3Npb24gaW50NjQsIHRpZXJSYXRpbyBpbnQ2NCwgdGllckNvdW50IGludDY0KSAoaW50NjQsIGVycm9yKSB7CglpZiBlbWlzc2lvbiA8IDAgfHwgdGllclJhdGlvIDwgMCB8fCB0aWVyQ291bnQgPCAwIHsKCQlyZXR1cm4gMCwgZXJyb3JzLk5ldyhlcnJDYWxjdWxhdGlvbkVycm9yKQoJfQoKCWlmIGVtaXNzaW9uID09IDAgfHwgdGllclJhdGlvID09IDAgfHwgdGllckNvdW50ID09IDAgewoJCXJldHVybiAwLCBuaWwKCX0KCgl0aWVyUmV3YXJkIDo9IGduc21hdGguU2FmZU11bERpdkludDY0KGVtaXNzaW9uLCB0aWVyUmF0aW8sIDEwMCkKCglyZXR1cm4gdGllclJld2FyZCAvIHRpZXJDb3VudCwgbmlsCn0KCi8vIGNvbXB1dGVUaWVyUmV3YXJkcyBjYWNoZXMgcGVyLXRpZXIgcG9vbCByZXdhcmRzIHRvIGF2b2lkIHJlY2FsY3VsYXRpbmcgZm9yIGVhY2ggcG9vbCBpdGVyYXRpb24uCmZ1bmMgKHNlbGYgKlBvb2xUaWVyKSBjb21wdXRlVGllclJld2FyZHMoZW1pc3Npb24gaW50NjQpIG1hcFt1aW50NjRdaW50NjQgewoJdGllclJld2FyZHMgOj0gbWFrZShtYXBbdWludDY0XWludDY0LCBBbGxUaWVyQ291bnQtMSkKCglmb3IgdGllck51bSA6PSB1aW50NjQoMSk7IHRpZXJOdW0gPCBBbGxUaWVyQ291bnQ7IHRpZXJOdW0rKyB7CgkJdGllckNvdW50IDo9IGludDY0KHNlbGYuY291bnRzW3RpZXJOdW1dKQoJCWlmIHRpZXJDb3VudCA9PSAwIHsKCQkJY29udGludWUKCQl9CgoJCXRpZXJSYXRpbywgZXJyIDo9IHNlbGYudGllclJhdGlvLkdldCh0aWVyTnVtKQoJCWlmIGVyciAhPSBuaWwgewoJCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscyhlcnJJbnZhbGlkUG9vbFRpZXIsIGVyci5FcnJvcigpKSkKCQl9CgoJCXJld2FyZCwgZXJyIDo9IGNhbGN1bGF0ZVBvb2xSZXdhcmQoZW1pc3Npb24sIGludDY0KHRpZXJSYXRpbyksIHRpZXJDb3VudCkKCQlpZiBlcnIgIT0gbmlsIHsKCQkJcGFuaWMoZXJyKQoJCX0KCQl0aWVyUmV3YXJkc1t0aWVyTnVtXSA9IHJld2FyZAoJfQoKCXJldHVybiB0aWVyUmV3YXJkcwp9ChqtXAobcmV3YXJkX2NhbGN1bGF0aW9uX3RpY2suZ25vEo1ccGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkiY2hhaW4iCgkiZXJyb3JzIgoKCSJnbm8ubGFuZC9wL2dub3N3YXAvZ25zbWF0aC92MSIKCWkyNTYgImduby5sYW5kL3AvZ25vc3dhcC9pbnQyNTYvdjEiCgl1MjU2ICJnbm8ubGFuZC9wL2dub3N3YXAvdWludDI1Ni92MSIKCSJnbm8ubGFuZC9wL2dub3N3YXAvdXRpbHMvdjEiCglzciAiZ25vLmxhbmQvci9nbm9zd2FwL3N0YWtlciIKKQoKdHlwZSBUaWNrUmVzb2x2ZXIgc3RydWN0IHsKCSpzci5UaWNrCn0KCi8vIEN1cnJlbnRPdXRzaWRlQWNjdW11bGF0aW9uIHJldHVybnMgdGhlIGxhdGVzdCBvdXRzaWRlIGFjY3VtdWxhdGlvbiBmb3IgdGhlIHRpY2sKLy8gUGFyYW1ldGVyczoKLy8gICAtIHRpbWVzdGFtcDogVGltZXN0YW1wIHRocm91Z2ggd2hpY2ggdGhlIHRpY2sncyBvdXRzaWRlLWFjY3VtdWxhdGlvbiBoaXN0b3J5IGlzIHF1ZXJpZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqdTI1Ni5VaW50OiBNb3N0IHJlY2VudCBkZWNvZGVkIG91dHNpZGUgYWNjdW11bGF0aW9uIGF0IG9yIGJlZm9yZSB0aW1lc3RhbXAsIG9yIHplcm8gd2hlbiBub25lIGV4aXN0cy4KZnVuYyAoc2VsZiAqVGlja1Jlc29sdmVyKSBDdXJyZW50T3V0c2lkZUFjY3VtdWxhdGlvbih0aW1lc3RhbXAgaW50NjQpICp1MjU2LlVpbnQgewoJdmFyIGFjYyAqdTI1Ni5VaW50CglzZWxmLk91dHNpZGVBY2N1bXVsYXRpb24oKS5SZXZlcnNlSXRlcmF0ZSgwLCB0aW1lc3RhbXAsIGZ1bmMoa2V5IGludDY0LCB2YWx1ZSBhbnkpIGJvb2wgewoJCXYsIG9rIDo9IHZhbHVlLihzdHJpbmcpCgkJaWYgIW9rIHsKCQkJcGFuaWMoImZhaWxlZCB0byBjYXN0IHZhbHVlIHRvIHN0cmluZyIpCgkJfQoJCWFjYyA9IHV0aWxzLkRlY29kZVVpbnQyNTYodikKCQlyZXR1cm4gdHJ1ZQoJfSkKCWlmIGFjYyA9PSBuaWwgewoJCXJldHVybiB1MjU2Llplcm8oKQoJfQoJcmV0dXJuIGFjYwp9CgovLyBtb2RpZnlEZXBvc2l0TG93ZXIgdXBkYXRlcyB0aGUgdGljaydzIGxpcXVpZGl0eSBpbmZvIGJ5IHRyZWF0aW5nIHRoZSBkZXBvc2l0IGFzIGEgbG93ZXIgdGljawpmdW5jIChzZWxmICpUaWNrUmVzb2x2ZXIpIG1vZGlmeURlcG9zaXRMb3dlcihjdXJyZW50VGltZSBpbnQ2NCwgbGlxdWlkaXR5ICppMjU2LkludCkgewoJLy8gdXBkYXRlIHN0YWtlciBzaWRlIHRpY2sgaW5mbwoJc2VsZi5TZXRTdGFrZWRMaXF1aWRpdHlHcm9zcyhnbnNtYXRoLkxpcXVpZGl0eU1hdGhBZGREZWx0YShzZWxmLlN0YWtlZExpcXVpZGl0eUdyb3NzKCksIGxpcXVpZGl0eSkpCglpZiBzZWxmLlN0YWtlZExpcXVpZGl0eUdyb3NzKCkuTHQodTI1Ni5aZXJvKCkpIHsKCQlwYW5pYygic3Rha2VkTGlxdWlkaXR5R3Jvc3MgaXMgbmVnYXRpdmUiKQoJfQoJc2VsZi5TZXRTdGFrZWRMaXF1aWRpdHlEZWx0YShpMjU2Llplcm8oKS5BZGQoc2VsZi5TdGFrZWRMaXF1aWRpdHlEZWx0YSgpLCBsaXF1aWRpdHkpKQp9CgovLyBtb2RpZnlEZXBvc2l0VXBwZXIgdXBkYXRlcyB0aGUgdGljaydzIGxpcXVpZGl0eSBpbmZvIGJ5IHRyZWF0aW5nIHRoZSBkZXBvc2l0IGFzIGFuIHVwcGVyIHRpY2sKZnVuYyAoc2VsZiAqVGlja1Jlc29sdmVyKSBtb2RpZnlEZXBvc2l0VXBwZXIoY3VycmVudFRpbWUgaW50NjQsIGxpcXVpZGl0eSAqaTI1Ni5JbnQpIHsKCXNlbGYuU2V0U3Rha2VkTGlxdWlkaXR5R3Jvc3MoZ25zbWF0aC5MaXF1aWRpdHlNYXRoQWRkRGVsdGEoc2VsZi5TdGFrZWRMaXF1aWRpdHlHcm9zcygpLCBsaXF1aWRpdHkpKQoJaWYgc2VsZi5TdGFrZWRMaXF1aWRpdHlHcm9zcygpLkx0KHUyNTYuWmVybygpKSB7CgkJcGFuaWMoInN0YWtlZExpcXVpZGl0eUdyb3NzIGlzIG5lZ2F0aXZlIikKCX0KCXNlbGYuU2V0U3Rha2VkTGlxdWlkaXR5RGVsdGEoaTI1Ni5aZXJvKCkuU3ViKHNlbGYuU3Rha2VkTGlxdWlkaXR5RGVsdGEoKSwgbGlxdWlkaXR5KSkKfQoKLy8gdXBkYXRlQ3VycmVudE91dHNpZGVBY2N1bXVsYXRpb24gdXBkYXRlcyB0aGUgdGljaydzIG91dHNpZGUgYWNjdW11bGF0aW9uCi8vIEl0ICJmbGlwcyIgdGhlIGFjY3VtdWxhdGlvbidzIGluc2lkZS9vdXRzaWRlIGJ5IHN1YnRyYWN0aW5nIHRoZSBjdXJyZW50IG91dHNpZGUgYWNjdW11bGF0aW9uIGZyb20gdGhlIGdsb2JhbCBhY2N1bXVsYXRpb24uCi8vIEFuIHVuY2hhbmdlZCByZXN1bHQgZG9lcyBub3QgcmVxdWlyZSBhIGNoZWNrcG9pbnQgYmVjYXVzZSBwcmVkZWNlc3NvciBxdWVyaWVzCi8vIHJldHVybiB0aGUgc2FtZSB2YWx1ZSBmb3IgdGhpcyBhbmQgYWxsIHN1YnNlcXVlbnQgdGltZXN0YW1wcy4KZnVuYyAoc2VsZiAqVGlja1Jlc29sdmVyKSB1cGRhdGVDdXJyZW50T3V0c2lkZUFjY3VtdWxhdGlvbih0aW1lc3RhbXAgaW50NjQsIGFjYyAqdTI1Ni5VaW50KSAqdTI1Ni5VaW50IHsKCWN1cnJlbnRPdXRzaWRlQWNjdW11bGF0aW9uIDo9IHNlbGYuQ3VycmVudE91dHNpZGVBY2N1bXVsYXRpb24odGltZXN0YW1wKQoJbmV3T3V0c2lkZUFjY3VtdWxhdGlvbiA6PSB1MjU2Llplcm8oKS5TdWIoYWNjLCBjdXJyZW50T3V0c2lkZUFjY3VtdWxhdGlvbikKCWlmIG5ld091dHNpZGVBY2N1bXVsYXRpb24uRXEoY3VycmVudE91dHNpZGVBY2N1bXVsYXRpb24pIHsKCQlyZXR1cm4gY3VycmVudE91dHNpZGVBY2N1bXVsYXRpb24KCX0KCglzZWxmLlNldE91dHNpZGVBY2N1bXVsYXRpb25BdCh0aW1lc3RhbXAsIG5ld091dHNpZGVBY2N1bXVsYXRpb24pCglyZXR1cm4gbmV3T3V0c2lkZUFjY3VtdWxhdGlvbgp9CgovLyBOZXdUaWNrUmVzb2x2ZXIgd3JhcHMgYSBzdGFrZXIgdGljayB0byBleHBvc2UgcmV3YXJkLWFjY3VtdWxhdGlvbiB1cGRhdGVzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gdGljazogU3Rha2VyIHRpY2sgd2hvc2Ugc3RhdGUgaXMgcmVzb2x2ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqVGlja1Jlc29sdmVyOiBSZXNvbHZlciBiYWNrZWQgYnkgdGljay4KZnVuYyBOZXdUaWNrUmVzb2x2ZXIodGljayAqc3IuVGljaykgKlRpY2tSZXNvbHZlciB7CglyZXR1cm4gJlRpY2tSZXNvbHZlcnsKCQlUaWNrOiB0aWNrLAoJfQp9CgovLyBzd2FwU3RhcnRIb29rIGlzIGNhbGxlZCB3aGVuIGEgc3dhcCBzdGFydHMKLy8gVGhpcyBob29rIGluaXRpYWxpemVzIHRoZSBiYXRjaCBwcm9jZXNzb3IgZm9yIGFjY3VtdWxhdGluZyB0aWNrIGNyb3NzZXMKZnVuYyAocyAqc3Rha2VyVjEpIHN3YXBTdGFydEhvb2soXyBpbnQsIHJsbSByZWFsbSwgcG9vbFBhdGggc3RyaW5nLCB0aW1lc3RhbXAgaW50NjQpIHsKCXBvb2wsIG9rIDo9IHMuZ2V0UG9vbHMoKS5HZXQocG9vbFBhdGgpCglpZiAhb2sgewoJCXJldHVybgoJfQoJaWYgcG9vbC5UaWNrcygpLlRyZWUoKS5TaXplKCkgPT0gMCB7CgkJcmV0dXJuCgl9CgoJLy8gSW5pdGlhbGl6ZSBiYXRjaCBwcm9jZXNzb3IgZm9yIHRoaXMgc3dhcAoJLy8gVGhpcyB3aWxsIGFjY3VtdWxhdGUgYWxsIHRpY2sgY3Jvc3NlcyB1bnRpbCBzd2FwIGNvbXBsZXRpb24KCWN1cnJlbnRTd2FwQmF0Y2ggOj0gc3IuTmV3U3dhcEJhdGNoUHJvY2Vzc29yKHBvb2xQYXRoLCBwb29sLCB0aW1lc3RhbXApCgllcnIgOj0gcy5zdG9yZS5TZXRDdXJyZW50U3dhcEJhdGNoKDAsIHJsbSwgY3VycmVudFN3YXBCYXRjaCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KfQoKLy8gc3dhcEVuZEhvb2sgaXMgY2FsbGVkIHdoZW4gYSBzd2FwIGVuZHMKLy8gVGhpcyBob29rIHByb2Nlc3NlcyBhbGwgYWNjdW11bGF0ZWQgdGljayBjcm9zc2VzIGluIGEgc2luZ2xlIGJhdGNoIG9wZXJhdGlvbgovLyBhbmQgY2xlYW5zIHVwIHRoZSBiYXRjaCBwcm9jZXNzb3IuIFRoZSBiYXRjaCBwcm9jZXNzaW5nIGFwcHJvYWNoIHByb3ZpZGVzOgovLyAxLiBPKDEpIHBvb2wgc3RhdGUgdXBkYXRlcyBpbnN0ZWFkIG9mIE8obikgd2hlcmUgbiA9IG51bWJlciBvZiB0aWNrIGNyb3NzZXMKLy8gMi4gUmVkdWNlZCBjb21wdXRhdGlvbmFsIG92ZXJoZWFkIGZvciByZXdhcmQgY2FsY3VsYXRpb25zCi8vIDMuIEF0b21pYyBwcm9jZXNzaW5nIGVuc3VyaW5nIGNvbnNpc3RlbmN5IGFjcm9zcyBhbGwgdGljayB1cGRhdGVzCmZ1bmMgKHMgKnN0YWtlclYxKSBzd2FwRW5kSG9vayhfIGludCwgcmxtIHJlYWxtLCBwb29sUGF0aCBzdHJpbmcpIGVycm9yIHsKCS8vIFZhbGlkYXRlIGJhdGNoIHByb2Nlc3NvciBzdGF0ZQoJY3VycmVudFN3YXBCYXRjaCA6PSBzLnN0b3JlLkdldEN1cnJlbnRTd2FwQmF0Y2goKQoKCWlmIGN1cnJlbnRTd2FwQmF0Y2ggPT0gbmlsIHx8ICFjdXJyZW50U3dhcEJhdGNoLklzQWN0aXZlKCkgfHwgY3VycmVudFN3YXBCYXRjaC5Qb29sUGF0aCgpICE9IHBvb2xQYXRoIHsKCQlyZXR1cm4gbmlsCgl9CgoJLy8gRGlzYWJsZSBmdXJ0aGVyIGFjY3VtdWxhdGlvbgoJY3VycmVudFN3YXBCYXRjaC5TZXRJc0FjdGl2ZShmYWxzZSkKCgkvLyBQcm9jZXNzIGFsbCBhY2N1bXVsYXRlZCB0aWNrIGNyb3NzZXMgaW4gYSBzaW5nbGUgYmF0Y2gKCS8vIFRoaXMgaXMgd2hlcmUgdGhlIG9wdGltaXphdGlvbiBoYXBwZW5zIC0gaW5zdGVhZCBvZiBwcm9jZXNzaW5nCgkvLyBlYWNoIHRpY2sgY3Jvc3MgaW5kaXZpZHVhbGx5LCB3ZSBjYWxjdWxhdGUgY3VtdWxhdGl2ZSBlZmZlY3RzCgllcnIgOj0gcy5wcm9jZXNzQmF0Y2hlZFRpY2tDcm9zc2VzKDAsIHJsbSkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCgkvLyBDbGVhbiB1cCBiYXRjaCBwcm9jZXNzb3IKCWVyciA9IHMuc3RvcmUuU2V0Q3VycmVudFN3YXBCYXRjaCgwLCBybG0sIG5pbCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCglyZXR1cm4gbmlsCn0KCi8vIHRpY2tDcm9zc0hvb2sgaXMgY2FsbGVkIHdoZW4gYSB0aWNrIGlzIGNyb3NzZWQuCi8vIEFjdGl2ZSBzd2FwcyBhY2N1bXVsYXRlIGNyb3NzZXMgYW5kIHByb2Nlc3MgdGhlaXIgbmV0IGxpcXVpZGl0eSBjaGFuZ2Ugb25jZSBhdAovLyBzd2FwIGVuZC4gQ2FsbHMgd2l0aG91dCBhbiBhY3RpdmUgYmF0Y2ggdXNlIHRoZSBpbW1lZGlhdGUgZmFsbGJhY2ssIHdoaWNoCi8vIG1hdGVyaWFsaXplcyB0aGUgcmV3YXJkIGNhY2hlIGZvciBlYWNoIGluZGl2aWR1YWwgdGljayBjcm9zcy4KZnVuYyAocyAqc3Rha2VyVjEpIHRpY2tDcm9zc0hvb2soXyBpbnQsIHJsbSByZWFsbSwgcG9vbFBhdGggc3RyaW5nLCB0aWNrSWQgaW50MzIsIHplcm9Gb3JPbmUgYm9vbCwgdGltZXN0YW1wIGludDY0KSB7Cglwb29sLCBvayA6PSBzLmdldFBvb2xzKCkuR2V0KHBvb2xQYXRoKQoJaWYgIW9rIHsKCQlyZXR1cm4KCX0KCgkvLyBTa2lwIHRpY2tzIHdpdGhvdXQgc3Rha2luZyBzdGF0ZS4KCXRpY2sgOj0gcG9vbC5UaWNrcygpLkdldCh0aWNrSWQpCglpZiB0aWNrID09IG5pbCB7CgkJcmV0dXJuCgl9CgoJLy8gU2tpcCB0aWNrcyB3aXRob3V0IHN0YWtlZCBib3VuZGFyeSBsaXF1aWRpdHkgKG5vIHJld2FyZCBpbXBhY3QpCglpZiB0aWNrLlN0YWtlZExpcXVpZGl0eUdyb3NzKCkuSXNaZXJvKCkgewoJCXJldHVybgoJfQoKCWN1cnJlbnRTd2FwQmF0Y2ggOj0gcy5zdG9yZS5HZXRDdXJyZW50U3dhcEJhdGNoKCkKCS8vIEJhdGNoIHByb2Nlc3NpbmcgcGF0aDogYWNjdW11bGF0ZSB0aWNrIGNyb3NzZXMgZHVyaW5nIGFjdGl2ZSBzd2FwCglpZiBjdXJyZW50U3dhcEJhdGNoICE9IG5pbCAmJiBjdXJyZW50U3dhcEJhdGNoLklzQWN0aXZlKCkgJiYgY3VycmVudFN3YXBCYXRjaC5Qb29sUGF0aCgpID09IHBvb2xQYXRoIHsKCQkvLyBQcmUtY2FsY3VsYXRlIGxpcXVpZGl0eSBkZWx0YSB3aXRoIGRpcmVjdGlvbiBjb25zaWRlcmF0aW9uCgkJLy8gemVyb0Zvck9uZSBzd2FwOiBsaXF1aWRpdHkgZGVsdGEgaXMgbmVnYXRlZCAobGlxdWlkaXR5IGJlaW5nIHJlbW92ZWQgZnJvbSBjdXJyZW50IHRpY2spCgkJbGlxdWlkaXR5RGVsdGEgOj0gdGljay5TdGFrZWRMaXF1aWRpdHlEZWx0YSgpCgkJaWYgemVyb0Zvck9uZSB7CgkJCWxpcXVpZGl0eURlbHRhID0gaTI1Ni5aZXJvKCkuTmVnKGxpcXVpZGl0eURlbHRhKQoJCX0KCgkJLy8gQWNjdW11bGF0ZSB0aGlzIHRpY2sgY3Jvc3MgZm9yIGJhdGNoIHByb2Nlc3NpbmcKCQljdXJyZW50U3dhcEJhdGNoLkFkZENyb3NzKHNyLk5ld1N3YXBUaWNrQ3Jvc3ModGlja0lkLCB6ZXJvRm9yT25lLCBsaXF1aWRpdHlEZWx0YSkpCgkJcmV0dXJuCgl9CgoJLy8gSW1tZWRpYXRlIGZhbGxiYWNrIGZvciB0aWNrLWNyb3NzIGNhbGxlcnMgd2l0aG91dCBhbiBhY3RpdmUgc3dhcCBiYXRjaC4KCS8vIEN1cnJlbnQgcHJvZHVjdGlvbiB0aWNrIGNyb3NzZXMgb3JpZ2luYXRlIGZyb20gU3dhcCBhbmQgdXNlIGJhdGNoaW5nOyB0aGlzCgkvLyBwYXRoIHByZXNlcnZlcyBjb3JyZWN0IGFjY291bnRpbmcgZm9yIGZ1dHVyZSBub24tc3dhcCBjYWxsZXJzLgoJcy5wcm9jZXNzVGlja0Nyb3NzSW1tZWRpYXRlKHBvb2wsIHRpY2ssIHRpY2tJZCwgemVyb0Zvck9uZSwgdGltZXN0YW1wKQp9CgovLyBwcm9jZXNzVGlja0Nyb3NzSW1tZWRpYXRlIHByb2Nlc3NlcyBvbmUgdW5iYXRjaGVkIHRpY2sgY3Jvc3MuCi8vIEl0IG1hdGVyaWFsaXplcyBlbGFwc2VkIGhhbHZpbmcgYm91bmRhcmllcyB3aGlsZSB0aGUgcHJlLWNyb3NzIGxpcXVpZGl0eSBpcwovLyBzdGlsbCBlZmZlY3RpdmUsIGJlZm9yZSBtb2RpZnlpbmcgdGhlIGRlcG9zaXQgZm9yIHRoYXQgaW5kaXZpZHVhbCBjcm9zcy4KZnVuYyAocyAqc3Rha2VyVjEpIHByb2Nlc3NUaWNrQ3Jvc3NJbW1lZGlhdGUocG9vbCAqc3IuUG9vbCwgdGljayAqc3IuVGljaywgdGlja0lkIGludDMyLCB6ZXJvRm9yT25lIGJvb2wsIHRpbWVzdGFtcCBpbnQ2NCkgewoJLy8gQ2FsY3VsYXRlIHRoZSBlZmZlY3RpdmUgdGljayBwb3NpdGlvbiBhZnRlciBjcm9zc2luZwoJLy8gRm9yIHplcm9Gb3JPbmUgc3dhcHMsIGxpcXVpZGl0eSBiZWNvbWVzIGVmZmVjdGl2ZSBvbmUgdGljayBsb3dlcgoJbmV4dFRpY2sgOj0gdGlja0lkCglpZiB6ZXJvRm9yT25lIHsKCQluZXh0VGljay0tIC8vIE1vdmUgdG8gdGhlIGxvd2VyIHRpY2sgd2hlcmUgbGlxdWlkaXR5IGJlY29tZXMgYWN0aXZlCgl9CgoJLy8gQ2FsY3VsYXRlIGxpcXVpZGl0eSBkZWx0YSB3aXRoIGRpcmVjdGlvbiBjb25zaWRlcmF0aW9uCglsaXF1aWRpdHlEZWx0YSA6PSB0aWNrLlN0YWtlZExpcXVpZGl0eURlbHRhKCkKCWlmIHplcm9Gb3JPbmUgewoJCS8vIE5lZ2F0ZSBkZWx0YSBmb3IgemVyb0Zvck9uZSBkaXJlY3Rpb24gKGxpcXVpZGl0eSBiZWluZyByZW1vdmVkIGZyb20gY3VycmVudCByYW5nZSkKCQlsaXF1aWRpdHlEZWx0YSA9IGkyNTYuWmVybygpLk5lZyhsaXF1aWRpdHlEZWx0YSkKCX0KCgkvLyBVcGRhdGUgcG9vbCdzIGN1bXVsYXRpdmUgZGVwb3NpdCB3aXRoIHRoZSBsaXF1aWRpdHkgY2hhbmdlCglwb29sUmVzb2x2ZXIgOj0gTmV3UG9vbFJlc29sdmVyKHBvb2wpCglzLmdldFBvb2xUaWVyKCkuY2FjaGVSZXdhcmRGb3JQb29sKHRpbWVzdGFtcCwgcy5nZXRQb29scygpLCBwb29sLlBvb2xQYXRoKCkpCgluZXdBY2MgOj0gcG9vbFJlc29sdmVyLm1vZGlmeURlcG9zaXQobGlxdWlkaXR5RGVsdGEsIHRpbWVzdGFtcCwgbmV4dFRpY2spCgoJLy8gVXBkYXRlIHRoZSB0aWNrJ3Mgb3V0c2lkZSBhY2N1bXVsYXRpb24gZm9yIHJld2FyZCBjYWxjdWxhdGlvbnMKCS8vIFRoaXMgZW5zdXJlcyBwcm9wZXIgcmV3YXJkIGRpc3RyaWJ1dGlvbiB0cmFja2luZyBhY3Jvc3MgdGljayBib3VuZGFyaWVzCgl0aWNrUmVzb2x2ZXIgOj0gTmV3VGlja1Jlc29sdmVyKHRpY2spCgl0aWNrUmVzb2x2ZXIudXBkYXRlQ3VycmVudE91dHNpZGVBY2N1bXVsYXRpb24odGltZXN0YW1wLCBuZXdBY2MpCn0KCi8vIHByb2Nlc3NCYXRjaGVkVGlja0Nyb3NzZXMgcHJvY2Vzc2VzIGFsbCBhY2N1bXVsYXRlZCB0aWNrIGNyb3NzZXMgYXQgb25jZQovLyBUaGlzIGlzIHRoZSBjb3JlIG9wdGltaXphdGlvbiBmdW5jdGlvbiB0aGF0IHByb2Nlc3NlcyBtdWx0aXBsZSB0aWNrIGNyb3NzZXMgaW4gYSBzaW5nbGUgb3BlcmF0aW9uLgovLyBJbnN0ZWFkIG9mIHVwZGF0aW5nIHBvb2wgc3RhdGUgZm9yIGVhY2ggdGljayBjcm9zcyBpbmRpdmlkdWFsbHkgKE8obikgb3BlcmF0aW9ucyksCi8vIGl0IGNhbGN1bGF0ZXMgdGhlIGN1bXVsYXRpdmUgZWZmZWN0IGFuZCBhcHBsaWVzIGl0IG9uY2UgKE8oMSkgcG9vbCB1cGRhdGVzICsgTyhuKSB0aWNrIHVwZGF0ZXMpLgpmdW5jIChzICpzdGFrZXJWMSkgcHJvY2Vzc0JhdGNoZWRUaWNrQ3Jvc3NlcyhfIGludCwgcmxtIHJlYWxtKSBlcnJvciB7CgkvLyBFYXJseSBleGl0IGZvciBlbXB0eSBiYXRjaGVzCgljdXJyZW50U3dhcEJhdGNoIDo9IHMuc3RvcmUuR2V0Q3VycmVudFN3YXBCYXRjaCgpCglpZiBjdXJyZW50U3dhcEJhdGNoID09IG5pbCB8fCBsZW4oY3VycmVudFN3YXBCYXRjaC5Dcm9zc2VzKCkpID09IDAgewoJCXJldHVybiBuaWwKCX0KCgkvLyBWYWxpZGF0ZSBwb29sIHJlZmVyZW5jZQoJaWYgY3VycmVudFN3YXBCYXRjaC5Qb29sKCkgPT0gbmlsIHsKCQlyZXR1cm4gZXJyb3JzLk5ldyhlcnJQb29sTm90Rm91bmQpCgl9CgoJYmF0Y2ggOj0gY3VycmVudFN3YXBCYXRjaAoJdGltZXN0YW1wIDo9IGJhdGNoLlRpbWVzdGFtcCgpCgoJLy8gUGhhc2UgMTogQ2FsY3VsYXRlIGN1bXVsYXRpdmUgbGlxdWlkaXR5IGRlbHRhIGFjcm9zcyBhbGwgdGljayBjcm9zc2VzCgkvLyBUaGlzIHJlcGxhY2VzIG11bHRpcGxlIGluZGl2aWR1YWwgcG9vbCB1cGRhdGVzIHdpdGggYSBzaW5nbGUgY3VtdWxhdGl2ZSB1cGRhdGUKCWN1bXVsYXRpdmVEZWx0YSA6PSBpMjU2Llplcm8oKQoJZm9yIF8sIHRpY2tDcm9zcyA6PSByYW5nZSBiYXRjaC5Dcm9zc2VzKCkgewoJCW5ld0RlbHRhIDo9IGN1bXVsYXRpdmVEZWx0YS5BZGQoY3VtdWxhdGl2ZURlbHRhLCB0aWNrQ3Jvc3MuRGVsdGEoKSkKCQljdW11bGF0aXZlRGVsdGEgPSBuZXdEZWx0YQoJfQoKCS8vIFBoYXNlIDI6IERldGVybWluZSB0aGUgZWZmZWN0aXZlIHRpY2sgcG9zaXRpb24gZm9yIHBvb2wgc3RhdGUgdXBkYXRlCgkvLyBVc2UgdGhlIGxhc3QgY3Jvc3NlZCB0aWNrIGFzIHRoZSByZWZlcmVuY2UgcG9pbnQgZm9yIGN1bXVsYXRpdmUgY2hhbmdlcwoJbGFzdENyb3NzIDo9IGJhdGNoLkxhc3RDcm9zcygpCglpZiBsYXN0Q3Jvc3MgPT0gbmlsIHsKCQlyZXR1cm4gbmlsCgl9CgoJbGFzdFRpY2sgOj0gbGFzdENyb3NzLlRpY2tJRCgpCglpZiBsYXN0Q3Jvc3MuWmVyb0Zvck9uZSgpIHsKCQlsYXN0VGljay0tIC8vIEFkanVzdCBmb3IgemVyb0Zvck9uZSBkaXJlY3Rpb24KCX0KCgkvLyBQaGFzZSAzOiBBcHBseSB0aGUgYmF0Y2gncyBjdW11bGF0aXZlIGNoYW5nZSB0byBwb29sIHN0YXRlIG9uY2UuCgkvLyBjYWNoZVJld2FyZEZvclBvb2wgcnVucyBvbmNlIGZvciBlYWNoIG5vbi1lbXB0eSBub3JtYWwgc3dhcCBiYXRjaCwgYmVmb3JlCgkvLyB0aGUgbmV0IGxpcXVpZGl0eSBjaGFuZ2UuIEl0IHNlZXMgdGhlIHByZS1jcm9zcyBsaXF1aWRpdHkgYW5kIHNwbGl0cwoJLy8gdW5jbGFpbWFibGUgaW50ZXJ2YWxzIGF0IGV2ZXJ5IGVsYXBzZWQgaGFsdmluZyBib3VuZGFyeS4KCXBvb2xSZXNvbHZlciA6PSBOZXdQb29sUmVzb2x2ZXIoYmF0Y2guUG9vbCgpKQoJcy5nZXRQb29sVGllcigpLmNhY2hlUmV3YXJkRm9yUG9vbCh0aW1lc3RhbXAsIHMuZ2V0UG9vbHMoKSwgYmF0Y2guUG9vbFBhdGgoKSkKCW5ld0FjYyA6PSBwb29sUmVzb2x2ZXIubW9kaWZ5RGVwb3NpdChjdW11bGF0aXZlRGVsdGEsIHRpbWVzdGFtcCwgbGFzdFRpY2spCgoJLy8gUGhhc2UgNDogVXBkYXRlIGluZGl2aWR1YWwgdGljayBvdXRzaWRlIGFjY3VtdWxhdGlvbnMgZm9yIHJld2FyZCB0cmFja2luZwoJLy8gV2hpbGUgd2Ugb3B0aW1pemUgcG9vbCB1cGRhdGVzLCBlYWNoIHRpY2sgc3RpbGwgbmVlZHMgaXRzIGFjY3VtdWxhdGlvbiB1cGRhdGVkCgkvLyBmb3IgcHJvcGVyIHJld2FyZCBkaXN0cmlidXRpb24gY2FsY3VsYXRpb25zCgoJZm9yIF8sIHRpY2tDcm9zcyA6PSByYW5nZSBiYXRjaC5Dcm9zc2VzKCkgewoJCXRpY2sgOj0gYmF0Y2guUG9vbCgpLlRpY2tzKCkuR2V0KHRpY2tDcm9zcy5UaWNrSUQoKSkKCQlpZiB0aWNrID09IG5pbCB7CgkJCS8vIFBydW5lZCBhZnRlciB0aGUgY3Jvc3Mgd2FzIGFjY3VtdWxhdGVkLCBzbyBpdHMgc3Rha2VkIGdyb3NzCgkJCS8vIGxpcXVpZGl0eSBpcyB6ZXJvIGFuZCBpdCBjYXJyaWVzIG5vIHJld2FyZCB3ZWlnaHQuCgkJCWNvbnRpbnVlCgkJfQoKCQl0aWNrUmVzb2x2ZXIgOj0gTmV3VGlja1Jlc29sdmVyKHRpY2spCgkJb3V0c2lkZUFjY3VtdWxhdGlvbiA6PSB0aWNrUmVzb2x2ZXIudXBkYXRlQ3VycmVudE91dHNpZGVBY2N1bXVsYXRpb24odGltZXN0YW1wLCBuZXdBY2MpCgoJCXRpY2tDcm9zc0V2ZW50SW5mbyA6PSBOZXdUaWNrQ3Jvc3NFdmVudEluZm8oCgkJCXRpY2tDcm9zcy5UaWNrSUQoKSwKCQkJdGljay5TdGFrZWRMaXF1aWRpdHlHcm9zcygpLAoJCQl0aWNrLlN0YWtlZExpcXVpZGl0eURlbHRhKCksCgkJCW91dHNpZGVBY2N1bXVsYXRpb24sCgkJKQoKCQljaGFpbi5FbWl0KAoJCQkiU3Rha2VyVGlja0Nyb3NzIiwKCQkJInBvb2xQYXRoIiwgYmF0Y2guUG9vbFBhdGgoKSwKCQkJInRpY2siLCB0aWNrQ3Jvc3NFdmVudEluZm8uVG9TdHJpbmcoKSwKCQkpCgl9CgoJcHJldmlvdXNSZWFsbSA6PSBybG0uUHJldmlvdXMoKQoJc3Rha2VkTGlxdWlkaXR5IDo9IHBvb2xSZXNvbHZlci5DdXJyZW50U3Rha2VkTGlxdWlkaXR5KHRpbWVzdGFtcCkKCgkvLyBFbWl0IGV2ZW50IHdpdGggc3Rha2VyLXNpZGUgdGljayBjcm9zcyBpbmZvcm1hdGlvbi4KCS8vIGxhc3RUaWNrIOKAlCB0aGUgZWZmZWN0aXZlIHRpY2sgd3JpdHRlbiB0byBIaXN0b3JpY2FsVGljayBieSBtb2RpZnlEZXBvc2l0IGFib3ZlLgoJLy8gUmV3YXJkIGNhbGN1bGF0aW9uIChDYWxjdWxhdGVSYXdSZXdhcmRGb3JQb3NpdGlvbikgcmVhZHMgSGlzdG9yaWNhbFRpY2sgZm9yIHRoZSBmZWVHcm93dGhJbnNpZGUgYnJhbmNoLAoJLy8gc28gb2ZmLWNoYWluIGluZGV4ZXJzIG11c3QgdXNlIHRoaXMgc2FtZSB2YWx1ZSAoTk9UIHRoZSBwb29sJ3MgU2xvdDAgdGljaykgdG8gcmVwcm9kdWNlIGluLXJhbmdlIHN0YXR1cy4KCWNoYWluLkVtaXQoCgkJIkJhdGNoU3Rha2VyVGlja0Nyb3NzIiwKCQkicHJldkFkZHIiLCBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKS5TdHJpbmcoKSwKCQkicHJldlJlYWxtIiwgcHJldmlvdXNSZWFsbS5Qa2dQYXRoKCksCgkJInBvb2xQYXRoIiwgYmF0Y2guUG9vbFBhdGgoKSwKCQkiYmxvY2tUaW1lc3RhbXAiLCB1dGlscy5Gb3JtYXRJbnQodGltZXN0YW1wKSwKCQkic3Rha2VkTGlxdWlkaXR5Iiwgc3Rha2VkTGlxdWlkaXR5LlRvU3RyaW5nKCksCgkJImdsb2JhbFJld2FyZFJhdGlvQWNjWDEyOCIsIG5ld0FjYy5Ub1N0cmluZygpLAoJCSJsYXN0VGljayIsIHV0aWxzLkZvcm1hdEludChsYXN0VGljayksCgkpCgoJcmV0dXJuIG5pbAp9CgpmdW5jIChzICpzdGFrZXJWMSkgc2V0dXBTd2FwSG9va3MoXyBpbnQsIHJsbSByZWFsbSkgewoJLy8gU2V0IHRpY2sgY3Jvc3MgaG9vayBmb3IgcG9vbCBjb250cmFjdAoJcy5wb29sQWNjZXNzb3IuU2V0VGlja0Nyb3NzSG9vaygwLCBybG0sIHMudGlja0Nyb3NzSG9vaykKCgkvLyBTZXQgc3dhcCBzdGFydC9lbmQgaG9va3MgZm9yIGJhdGNoIHByb2Nlc3NpbmcKCXMucG9vbEFjY2Vzc29yLlNldFN3YXBTdGFydEhvb2soMCwgcmxtLCBzLnN3YXBTdGFydEhvb2spCgoJLy8gU2V0IHN3YXAgZW5kIGhvb2sgZm9yIGJhdGNoIHByb2Nlc3NpbmcKCXMucG9vbEFjY2Vzc29yLlNldFN3YXBFbmRIb29rKDAsIHJsbSwgcy5zd2FwRW5kSG9vaykKfQoagRkKHXJld2FyZF9jYWxjdWxhdGlvbl93YXJtdXAuZ25vEt8YcGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkiZXJyb3JzIgoJIm1hdGgiCgoJImduby5sYW5kL3AvZ25vc3dhcC9nbnNtYXRoL3YxIgoJdTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL3VpbnQyNTYvdjEiCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCglzciAiZ25vLmxhbmQvci9nbm9zd2FwL3N0YWtlciIKKQoKY29uc3QgbWF4RHVyYXRpb25PbmVZZWFyID0gaW50NjQoMzY1ICogODY0MDApIC8vIDMxLDUzNiwwMDAgc2Vjb25kcwoKLy8gZXhwZWN0ZWQgdG8gYmUgY2FsbGVkIGJ5IGdvdmVybmFuY2UKZnVuYyBtb2RpZnlXYXJtdXAod2FybXVwVGVtcGxhdGUgW11zci5XYXJtdXAsIGluZGV4IGludCwgdGltZUR1cmF0aW9uIGludDY0KSBbXXNyLldhcm11cCB7CglpZiBpbmRleCA+PSBsZW4od2FybXVwVGVtcGxhdGUpIHsKCQlwYW5pYyh1Zm10LlNwcmludGYoImluZGV4KCVkKSBpcyBvdXQgb2YgcmFuZ2UiLCBpbmRleCkpCgl9CgoJLy8gSGFuZGxlIG5lZ2F0aXZlIGR1cmF0aW9uIC0gcGFuaWMgd2l0aCBlcnJvcgoJaWYgdGltZUR1cmF0aW9uIDwgMCB7CgkJcGFuaWModWZtdC5TcHJpbnRmKCJ3YXJtdXAgZHVyYXRpb24gY2Fubm90IGJlIG5lZ2F0aXZlLCBnb3QgJWQgc2Vjb25kcyIsIHRpbWVEdXJhdGlvbikpCgl9CgoJLy8gRWFybHkgcmV0dXJuIGZvciBsYXN0IHRpZXIgLSBtdXN0IGFsd2F5cyBiZSBtYXRoLk1heEludDY0CglpZiBpbmRleCA9PSBsZW4od2FybXVwVGVtcGxhdGUpLTEgewoJCWlmIHRpbWVEdXJhdGlvbiAhPSBtYXRoLk1heEludDY0IHsKCQkJcGFuaWModWZtdC5TcHJpbnRmKCJsYXN0IHdhcm11cCB0aWVyIG11c3QgaGF2ZSBkdXJhdGlvbiBvZiBtYXRoLk1heEludDY0LCBnb3QgJWQiLCB0aW1lRHVyYXRpb24pKQoJCX0KCQkvLyBObyBtb2RpZmljYXRpb24gbmVlZGVkIGFzIGl0J3MgYWxyZWFkeSBtYXRoLk1heEludDY0CgkJcmV0dXJuIHdhcm11cFRlbXBsYXRlCgl9CgoJLy8gTGltaXQgbm9uLWZpbmFsIHRpZXIgZHVyYXRpb25zIHRvIDEgeWVhciAoMzY1IGRheXMpCglpZiB0aW1lRHVyYXRpb24gPiBtYXhEdXJhdGlvbk9uZVllYXIgewoJCXBhbmljKHVmbXQuU3ByaW50Zigid2FybXVwIGR1cmF0aW9uIGNhbm5vdCBleGNlZWQgMSB5ZWFyICgzNjUgZGF5cyksIGdvdCAlZCBzZWNvbmRzIiwgdGltZUR1cmF0aW9uKSkKCX0KCgl3YXJtdXBUZW1wbGF0ZVtpbmRleF0uU2V0VGltZUR1cmF0aW9uKHRpbWVEdXJhdGlvbikKCglyZXR1cm4gd2FybXVwVGVtcGxhdGUKfQoKZnVuYyBpbnN0YW50aWF0ZVdhcm11cCh3YXJtdXBUZW1wbGF0ZSBbXXNyLldhcm11cCwgY3VycmVudFRpbWUgaW50NjQpIFtdc3IuV2FybXVwIHsKCXdhcm11cHMgOj0gbWFrZShbXXNyLldhcm11cCwgMCwgbGVuKHdhcm11cFRlbXBsYXRlKSkKCWZvciBpLCB3YXJtdXAgOj0gcmFuZ2Ugd2FybXVwVGVtcGxhdGUgewoJCW5leHRXYXJtdXBUaW1lIDo9IHNhZmVBZGRUaW1lKGN1cnJlbnRUaW1lLCB3YXJtdXAuVGltZUR1cmF0aW9uKQoKCQl3YXJtdXBzID0gYXBwZW5kKHdhcm11cHMsIHNyLk5ld1dhcm11cCh3YXJtdXAuVGltZUR1cmF0aW9uLCBuZXh0V2FybXVwVGltZSwgd2FybXVwLldhcm11cFJhdGlvKSkKCgkJLy8gT25seSB1cGRhdGUgY3VycmVudFRpbWUgaWYgbm90IHRoZSBsYXN0IHRpZXIKCQlpZiBpIDwgbGVuKHdhcm11cFRlbXBsYXRlKS0xIHsKCQkJY3VycmVudFRpbWUgPSBzYWZlQWRkVGltZShjdXJyZW50VGltZSwgd2FybXVwLlRpbWVEdXJhdGlvbikKCQl9Cgl9CglyZXR1cm4gd2FybXVwcwp9CgpmdW5jIGFwcGx5V2FybXVwKHdhcm11cCBzci5XYXJtdXAsIHBvb2xSZXdhcmQgaW50NjQsIHBvc2l0aW9uTGlxdWlkaXR5LCBzdGFrZWRMaXF1aWRpdHkgKnUyNTYuVWludCkgKGludDY0LCBpbnQ2NCkgewoJaWYgc3Rha2VkTGlxdWlkaXR5LklzWmVybygpIHsKCQlyZXR1cm4gMCwgMAoJfQoKCWRpdmlzb3IgOj0gdTI1Ni5OZXdVaW50KDEwMCkKCXBvb2xSZXdhcmRVaW50IDo9IHUyNTYuTmV3VWludEZyb21JbnQ2NChwb29sUmV3YXJkKQoJcGVyUG9zaXRpb25SZXdhcmQsIG92ZXJmbG93IDo9IHUyNTYuWmVybygpLk11bE92ZXJmbG93KHBvb2xSZXdhcmRVaW50LCBwb3NpdGlvbkxpcXVpZGl0eSkKCWlmIG92ZXJmbG93IHsKCQlwYW5pYyhlcnJvcnMuTmV3KGVyck92ZXJmbG93KSkKCX0KCXBlclBvc2l0aW9uUmV3YXJkID0gdTI1Ni5aZXJvKCkuRGl2KHBlclBvc2l0aW9uUmV3YXJkLCBzdGFrZWRMaXF1aWRpdHkpCgoJcGVuYWx0eVJhdGlvIDo9IHUyNTYuTmV3VWludCgxMDAgLSB3YXJtdXAuV2FybXVwUmF0aW8pCglyZXdhcmRSYXRpbyA6PSB1MjU2Lk5ld1VpbnQod2FybXVwLldhcm11cFJhdGlvKQoJdG90YWxSZXdhcmQsIG92ZXJmbG93IDo9IHUyNTYuWmVybygpLk11bE92ZXJmbG93KHBlclBvc2l0aW9uUmV3YXJkLCByZXdhcmRSYXRpbykKCWlmIG92ZXJmbG93IHsKCQlwYW5pYyhlcnJvcnMuTmV3KGVyck92ZXJmbG93KSkKCX0KCXRvdGFsUmV3YXJkID0gdTI1Ni5aZXJvKCkuRGl2KHRvdGFsUmV3YXJkLCBkaXZpc29yKQoKCXRvdGFsUGVuYWx0eSwgb3ZlcmZsb3cgOj0gdTI1Ni5aZXJvKCkuTXVsT3ZlcmZsb3cocGVyUG9zaXRpb25SZXdhcmQsIHBlbmFsdHlSYXRpbykKCWlmIG92ZXJmbG93IHsKCQlwYW5pYyhlcnJvcnMuTmV3KGVyck92ZXJmbG93KSkKCX0KCXRvdGFsUGVuYWx0eSA9IHUyNTYuWmVybygpLkRpdih0b3RhbFBlbmFsdHksIGRpdmlzb3IpCglyZXR1cm4gZ25zbWF0aC5TYWZlQ29udmVydFRvSW50NjQodG90YWxSZXdhcmQpLCBnbnNtYXRoLlNhZmVDb252ZXJ0VG9JbnQ2NCh0b3RhbFBlbmFsdHkpCn0KCi8vIHNhZmVBZGRUaW1lIHBlcmZvcm1zIHNhZmUgYWRkaXRpb24gd2l0aCBvdmVyZmxvdyBwcm90ZWN0aW9uCmZ1bmMgc2FmZUFkZFRpbWUoY3VycmVudFRpbWUsIGR1cmF0aW9uIGludDY0KSBpbnQ2NCB7CglpZiBkdXJhdGlvbiA9PSBtYXRoLk1heEludDY0IHsKCQlyZXR1cm4gbWF0aC5NYXhJbnQ2NAoJfQoKCS8vIENoZWNrIGZvciBvdmVyZmxvdyBiZWZvcmUgYWRkaXRpb24KCWlmIGN1cnJlbnRUaW1lID4gMCAmJiBkdXJhdGlvbiA+IG1hdGguTWF4SW50NjQtY3VycmVudFRpbWUgewoJCXJldHVybiBtYXRoLk1heEludDY0Cgl9CgoJcmV0dXJuIGduc21hdGguU2FmZUFkZEludDY0KGN1cnJlbnRUaW1lLCBkdXJhdGlvbikKfQoa3q8DCgpzdGFrZXIuZ25vEs6vA3BhY2thZ2Ugc3Rha2VyCgppbXBvcnQgKAoJImNoYWluIgoJImNoYWluL3J1bnRpbWUiCgkic3RyaW5ncyIKCSJ0aW1lIgoKCWJwdHJlZSAiZ25vLmxhbmQvcC9udC9icHRyZWUvdjAiCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgoJImduby5sYW5kL3AvZ25vc3dhcC9nbnNtYXRoL3YxIgoJcHJiYWMgImduby5sYW5kL3AvZ25vc3dhcC9yYmFjL3YxIgoJImduby5sYW5kL3AvZ25vc3dhcC91dGlscy92MSIKCgkiZ25vLmxhbmQvci9nbm9zd2FwL2FjY2Vzcy92MSIKCV8gImduby5sYW5kL3IvZ25vc3dhcC9yYmFjL3YxIgoKCSJnbm8ubGFuZC9yL2dub3N3YXAvY29tbW9uIgoJImduby5sYW5kL3IvZ25vc3dhcC9oYWx0L3YxIgoJc3IgImduby5sYW5kL3IvZ25vc3dhcC9zdGFrZXIiCgoJImduby5sYW5kL3IvZ25vc3dhcC9nbnMiCgoJZW4gImduby5sYW5kL3IvZ25vc3dhcC9lbWlzc2lvbiIKCXBuICJnbm8ubGFuZC9yL2dub3N3YXAvcG9zaXRpb24iCgoJaTI1NiAiZ25vLmxhbmQvcC9nbm9zd2FwL2ludDI1Ni92MSIKCXUyNTYgImduby5sYW5kL3AvZ25vc3dhcC91aW50MjU2L3YxIgoKCSJnbm8ubGFuZC9yL2dub3N3YXAvcmVmZXJyYWwvdjEiCikKCmNvbnN0IFpFUk9fQUREUkVTUyA9IGFkZHJlc3MoIiIpCgovLyBEZXBvc2l0cyBtYW5hZ2VzIGFsbCBzdGFrZWQgcG9zaXRpb25zLgp0eXBlIERlcG9zaXRzIHN0cnVjdCB7Cgl0cmVlICpicHRyZWUuQlBUcmVlCn0KCi8vIE5ld0RlcG9zaXRzIGNyZWF0ZXMgYSBuZXcgRGVwb3NpdHMgaW5zdGFuY2UuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBkZXBvc2l0czogRW1wdHkgZGVwb3NpdCBjb2xsZWN0aW9uIGJhY2tlZCBieSBhIHBvc2l0aW9uLUlEIHRyZWUuCmZ1bmMgTmV3RGVwb3NpdHMoKSAqRGVwb3NpdHMgewoJcmV0dXJuICZEZXBvc2l0c3sKCQl0cmVlOiBzci5OZXdCUFRyZWVOKDE2KSwgLy8gcG9zaXRpb25JZCAtPiAqRGVwb3NpdAoJfQp9CgovLyBIYXMgY2hlY2tzIGlmIGEgcG9zaXRpb24gSUQgZXhpc3RzIGluIGRlcG9zaXRzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9zaXRpb25JZDogTFAgcG9zaXRpb24gTkZUIElEIHdob3NlIGRlcG9zaXQgcHJlc2VuY2Ugc2hvdWxkIGJlIGNoZWNrZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBleGlzdHM6IFRydWUgd2hlbiBwb3NpdGlvbklkIGlzIHN0b3JlZCBpbiB0aGUgZGVwb3NpdCB0cmVlOyBmYWxzZSBvdGhlcndpc2UuCmZ1bmMgKHNlbGYgKkRlcG9zaXRzKSBIYXMocG9zaXRpb25JZCB1aW50NjQpIGJvb2wgewoJcmV0dXJuIHNlbGYudHJlZS5IYXModXRpbHMuRW5jb2RlVWludDY0KHBvc2l0aW9uSWQpKQp9CgovLyBJdGVyYXRlIHRyYXZlcnNlcyBkZXBvc2l0cyB3aXRoaW4gdGhlIHNwZWNpZmllZCByYW5nZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHN0YXJ0OiBMb3dlciBwb3NpdGlvbi1JRCBib3VuZCBwYXNzZWQgdG8gdGhlIHRyZWUgaXRlcmF0b3IuCi8vICAgLSBlbmQ6IFVwcGVyIHBvc2l0aW9uLUlEIGJvdW5kIHBhc3NlZCB0byB0aGUgdHJlZSBpdGVyYXRvci4KLy8gICAtIGZuOiBDYWxsYmFjayByZWNlaXZpbmcgZWFjaCBkZWNvZGVkIHBvc2l0aW9uIElEIGFuZCBkZXBvc2l0OyByZXR1cm4gdHJ1ZSB0byBzdG9wIGl0ZXJhdGlvbiBvciBmYWxzZSB0byBjb250aW51ZS4KZnVuYyAoc2VsZiAqRGVwb3NpdHMpIEl0ZXJhdGUoc3RhcnQgdWludDY0LCBlbmQgdWludDY0LCBmbiBmdW5jKHBvc2l0aW9uSWQgdWludDY0LCBkZXBvc2l0ICpzci5EZXBvc2l0KSBib29sKSB7CglzZWxmLnRyZWUuSXRlcmF0ZSh1dGlscy5FbmNvZGVVaW50NjQoc3RhcnQpLCB1dGlscy5FbmNvZGVVaW50NjQoZW5kKSwgZnVuYyhwb3NpdGlvbklkIHN0cmluZywgZGVwb3NpdEkgYW55KSBib29sIHsKCQlkcHN0IDo9IHJldHJpZXZlRGVwb3NpdChkZXBvc2l0SSkKCQlyZXR1cm4gZm4odXRpbHMuRGVjb2RlVWludDY0KHBvc2l0aW9uSWQpLCBkcHN0KQoJfSkKfQoKLy8gSXRlcmF0ZUJ5UG9vbFBhdGggdHJhdmVyc2VzIGRlcG9zaXRzIGluIHRoZSBJRCByYW5nZSBhbmQgaW52b2tlcyBmbiBvbmx5IGZvciB0aGUgcmVxdWVzdGVkIHBvb2wuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBzdGFydDogTG93ZXIgcG9zaXRpb24tSUQgYm91bmQgcGFzc2VkIHRvIHRoZSB0cmVlIGl0ZXJhdG9yLgovLyAgIC0gZW5kOiBVcHBlciBwb3NpdGlvbi1JRCBib3VuZCBwYXNzZWQgdG8gdGhlIHRyZWUgaXRlcmF0b3IuCi8vICAgLSBwb29sUGF0aDogUG9vbCBpZGVudGlmaWVyIGRlcG9zaXRzIG11c3QgbWF0Y2ggYmVmb3JlIHRoZSBjYWxsYmFjayBpcyBpbnZva2VkLgovLyAgIC0gZm46IENhbGxiYWNrIHJlY2VpdmluZyBlYWNoIG1hdGNoaW5nIHBvc2l0aW9uIElEIGFuZCBkZXBvc2l0OyByZXR1cm4gdHJ1ZSB0byBzdG9wIGl0ZXJhdGlvbiBvciBmYWxzZSB0byBjb250aW51ZS4KZnVuYyAoc2VsZiAqRGVwb3NpdHMpIEl0ZXJhdGVCeVBvb2xQYXRoKHN0YXJ0LCBlbmQgdWludDY0LCBwb29sUGF0aCBzdHJpbmcsIGZuIGZ1bmMocG9zaXRpb25JZCB1aW50NjQsIGRlcG9zaXQgKnNyLkRlcG9zaXQpIGJvb2wpIHsKCXNlbGYudHJlZS5JdGVyYXRlKHV0aWxzLkVuY29kZVVpbnQ2NChzdGFydCksIHV0aWxzLkVuY29kZVVpbnQ2NChlbmQpLCBmdW5jKHBvc2l0aW9uSWQgc3RyaW5nLCBkZXBvc2l0SSBhbnkpIGJvb2wgewoJCWRlcG9zaXQgOj0gcmV0cmlldmVEZXBvc2l0KGRlcG9zaXRJKQoJCWlmIGRlcG9zaXQuVGFyZ2V0UG9vbFBhdGgoKSAhPSBwb29sUGF0aCB7CgkJCXJldHVybiBmYWxzZQoJCX0KCgkJcmV0dXJuIGZuKHV0aWxzLkRlY29kZVVpbnQ2NChwb3NpdGlvbklkKSwgZGVwb3NpdCkKCX0pCn0KCi8vIFNpemUgcmV0dXJucyB0aGUgbnVtYmVyIG9mIGRlcG9zaXRzLgovLwovLyBSZXR1cm5zOgovLyAgIC0gc2l6ZTogTnVtYmVyIG9mIGRlcG9zaXRzIGN1cnJlbnRseSBzdG9yZWQuCmZ1bmMgKHNlbGYgKkRlcG9zaXRzKSBTaXplKCkgaW50IHsKCXJldHVybiBzZWxmLnRyZWUuU2l6ZSgpCn0KCi8vIGdldCByZXRyaWV2ZXMgYSBkZXBvc2l0IGJ5IHBvc2l0aW9uIElELgpmdW5jIChzZWxmICpEZXBvc2l0cykgZ2V0KHBvc2l0aW9uSWQgdWludDY0KSAqc3IuRGVwb3NpdCB7CglkZXBvc2l0SSA6PSBzZWxmLnRyZWUuR2V0KHV0aWxzLkVuY29kZVVpbnQ2NChwb3NpdGlvbklkKSkKCWlmIGRlcG9zaXRJID09IG5pbCB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckRhdGFOb3RGb3VuZCwKCQkJdWZtdC5TcHJpbnRmKCJwb3NpdGlvbklkKCVkKSBub3QgZm91bmQiLCBwb3NpdGlvbklkKSwKCQkpKQoJfQoJcmV0dXJuIHJldHJpZXZlRGVwb3NpdChkZXBvc2l0SSkKfQoKLy8gcmV0cmlldmVEZXBvc2l0IHNhZmVseSBjYXN0cyBkYXRhIHRvIERlcG9zaXQgdHlwZS4KZnVuYyByZXRyaWV2ZURlcG9zaXQoZGF0YSBhbnkpICpzci5EZXBvc2l0IHsKCWRlcG9zaXQsIG9rIDo9IGRhdGEuKCpzci5EZXBvc2l0KQoJaWYgIW9rIHsKCQlwYW5pYygiZmFpbGVkIHRvIGNhc3QgdmFsdWUgdG8gKkRlcG9zaXQiKQoJfQoJcmV0dXJuIGRlcG9zaXQKfQoKLy8gc2V0IHN0b3JlcyBhIGRlcG9zaXQgZm9yIGEgcG9zaXRpb24gSUQuCmZ1bmMgKHNlbGYgKkRlcG9zaXRzKSBzZXQocG9zaXRpb25JZCB1aW50NjQsIGRlcG9zaXQgKnNyLkRlcG9zaXQpIHsKCXNlbGYudHJlZS5TZXQodXRpbHMuRW5jb2RlVWludDY0KHBvc2l0aW9uSWQpLCBkZXBvc2l0KQp9CgovLyByZW1vdmUgZGVsZXRlcyBhIGRlcG9zaXQgYnkgcG9zaXRpb24gSUQuCmZ1bmMgKHNlbGYgKkRlcG9zaXRzKSByZW1vdmUocG9zaXRpb25JZCB1aW50NjQpIHsKCXNlbGYudHJlZS5SZW1vdmUodXRpbHMuRW5jb2RlVWludDY0KHBvc2l0aW9uSWQpKQp9CgovLyBFeHRlcm5hbEluY2VudGl2ZXMgbWFuYWdlcyBleHRlcm5hbCBpbmNlbnRpdmUgcHJvZ3JhbXMuCnR5cGUgRXh0ZXJuYWxJbmNlbnRpdmVzIHN0cnVjdCB7Cgl0cmVlICpicHRyZWUuQlBUcmVlCn0KCi8vIE5ld0V4dGVybmFsSW5jZW50aXZlcyBjcmVhdGVzIGEgbmV3IEV4dGVybmFsSW5jZW50aXZlcyBpbnN0YW5jZS4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGluY2VudGl2ZXM6IEVtcHR5IGV4dGVybmFsLWluY2VudGl2ZSBjb2xsZWN0aW9uIGJhY2tlZCBieSBhbiBpbmNlbnRpdmUtSUQgdHJlZS4KZnVuYyBOZXdFeHRlcm5hbEluY2VudGl2ZXMoKSAqRXh0ZXJuYWxJbmNlbnRpdmVzIHsKCXJldHVybiAmRXh0ZXJuYWxJbmNlbnRpdmVzewoJCXRyZWU6IHNyLk5ld0JQVHJlZU4oMTYpLAoJfQp9CgovLyBIYXMgY2hlY2tzIGlmIGFuIGluY2VudGl2ZSBJRCBleGlzdHMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBpbmNlbnRpdmVJZDogRXh0ZXJuYWwgaW5jZW50aXZlIElEIHdob3NlIHByZXNlbmNlIHNob3VsZCBiZSBjaGVja2VkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gZXhpc3RzOiBUcnVlIHdoZW4gaW5jZW50aXZlSWQgaXMgc3RvcmVkIGluIHRoZSBpbmNlbnRpdmUgdHJlZTsgZmFsc2Ugb3RoZXJ3aXNlLgpmdW5jIChzZWxmICpFeHRlcm5hbEluY2VudGl2ZXMpIEhhcyhpbmNlbnRpdmVJZCBzdHJpbmcpIGJvb2wgeyByZXR1cm4gc2VsZi50cmVlLkhhcyhpbmNlbnRpdmVJZCkgfQoKLy8gU2l6ZSByZXR1cm5zIHRoZSBudW1iZXIgb2YgZXh0ZXJuYWwgaW5jZW50aXZlcy4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHNpemU6IE51bWJlciBvZiBleHRlcm5hbCBpbmNlbnRpdmVzIGN1cnJlbnRseSBzdG9yZWQuCmZ1bmMgKHNlbGYgKkV4dGVybmFsSW5jZW50aXZlcykgU2l6ZSgpIGludCB7IHJldHVybiBzZWxmLnRyZWUuU2l6ZSgpIH0KCi8vIGdldCByZXRyaWV2ZXMgYW4gZXh0ZXJuYWwgaW5jZW50aXZlIGJ5IElELgpmdW5jIChzZWxmICpFeHRlcm5hbEluY2VudGl2ZXMpIGdldChpbmNlbnRpdmVJZCBzdHJpbmcpICpzci5FeHRlcm5hbEluY2VudGl2ZSB7CglpbmNlbnRpdmVJIDo9IHNlbGYudHJlZS5HZXQoaW5jZW50aXZlSWQpCglpZiBpbmNlbnRpdmVJID09IG5pbCB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckRhdGFOb3RGb3VuZCwKCQkJdWZtdC5TcHJpbnRmKCJpbmNlbnRpdmVJZCglcykgbm90IGZvdW5kIiwgaW5jZW50aXZlSWQpLAoJCSkpCgl9CgoJaW5jZW50aXZlLCBvayA6PSBpbmNlbnRpdmVJLigqc3IuRXh0ZXJuYWxJbmNlbnRpdmUpCglpZiAhb2sgewoJCXBhbmljKCJmYWlsZWQgdG8gY2FzdCB2YWx1ZSB0byAqRXh0ZXJuYWxJbmNlbnRpdmUiKQoJfQoJcmV0dXJuIGluY2VudGl2ZQp9CgovLyBzZXQgc3RvcmVzIGFuIGV4dGVybmFsIGluY2VudGl2ZS4KZnVuYyAoc2VsZiAqRXh0ZXJuYWxJbmNlbnRpdmVzKSBzZXQoaW5jZW50aXZlSWQgc3RyaW5nLCBpbmNlbnRpdmUgKnNyLkV4dGVybmFsSW5jZW50aXZlKSB7CglzZWxmLnRyZWUuU2V0KGluY2VudGl2ZUlkLCBpbmNlbnRpdmUpCn0KCi8vIHJlbW92ZSBkZWxldGVzIGFuIGV4dGVybmFsIGluY2VudGl2ZSBieSBJRC4KZnVuYyAoc2VsZiAqRXh0ZXJuYWxJbmNlbnRpdmVzKSByZW1vdmUoaW5jZW50aXZlSWQgc3RyaW5nKSB7CglzZWxmLnRyZWUuUmVtb3ZlKGluY2VudGl2ZUlkKQp9CgovLyBFbWlzc2lvbkNhY2hlVXBkYXRlSG9vayB1cGRhdGVzIHRoZSBlbWlzc2lvbiBjYWNoZSB3aGVuIGNhbGxlZC4KLy8gVGhpcyBmb2xsb3dzIHRoZSBzYW1lIHBhdHRlcm4gYXMgb3RoZXIgaG9va3MgaW4gdGhlIHN0YWtlciBjb250cmFjdC4KZnVuYyAocyAqc3Rha2VyVjEpIGVtaXNzaW9uQ2FjaGVVcGRhdGVIb29rKF8gaW50LCBybG0gcmVhbG0sIGVtaXNzaW9uQW1vdW50UGVyU2Vjb25kIGludDY0KSB7Cglwb29sVGllciA6PSBzLmdldFBvb2xUaWVyKCkKCWlmIHBvb2xUaWVyICE9IG5pbCB7CgkJY3VycmVudFRpbWUgOj0gdGltZS5Ob3coKS5Vbml4KCkKCQlwb29scyA6PSBzLmdldFBvb2xzKCkKCgkJLy8gRmlyc3QgY2FjaGUgdGhlIGN1cnJlbnQgcmV3YXJkcyBiZWZvcmUgdXBkYXRpbmcgZW1pc3Npb24KCQlwb29sVGllci5jYWNoZVJld2FyZChjdXJyZW50VGltZSwgcG9vbHMpCgoJCS8vIFVwZGF0ZSB0aGUgY3VycmVudCBlbWlzc2lvbiBjYWNoZSB3aXRoIHRoZSBsYXRlc3QgdmFsdWUKCQlwb29sVGllci5jdXJyZW50RW1pc3Npb24gPSBlbWlzc2lvbkFtb3VudFBlclNlY29uZAoKCQkvLyBOb3cgYXBwbHkgdGhlIG5ldyBlbWlzc2lvbiByYXRlIHRvIGVhY2ggcG9vbCBpbmRpdmlkdWFsbHkKCQlwb29sVGllci5hcHBseUNhY2hlVG9BbGxQb29scyhwb29scywgY3VycmVudFRpbWUsIGVtaXNzaW9uQW1vdW50UGVyU2Vjb25kKQoKCQlzLnVwZGF0ZVBvb2xUaWVyKDAsIHJsbSwgcG9vbFRpZXIpCgl9Cn0KCi8vIHN0YWtlU2Nhbkxvd2VyQm91bmQgcmV0dXJucyB0aGUgbG93ZXIgYm91bmQgb2YgdGhlIHN0YWtlLXRpbWUgaW5jZW50aXZlIHNjYW4KLy8gd2luZG93LCBjbGFtcGVkIHRvIDAuIFRoZSBzdGFydC10aW1lIGluZGV4IGVuY29kZXMga2V5cyBhcyB1bnNpZ25lZCwgc28gYQovLyBuZWdhdGl2ZSBib3VuZCBhYm9ydHMgd2hlbiB0aGUgY2hhaW4gdGltZSBpcyB1bmRlciBUSU1FU1RBTVBfMzY1REFZUy4KZnVuYyBzdGFrZVNjYW5Mb3dlckJvdW5kKGN1cnJlbnRUaW1lIGludDY0KSBpbnQ2NCB7CglpZiBjdXJyZW50VGltZSA8IFRJTUVTVEFNUF8zNjVEQVlTIHsKCQlyZXR1cm4gMAoJfQoKCXJldHVybiBjdXJyZW50VGltZSAtIFRJTUVTVEFNUF8zNjVEQVlTCn0KCi8vIFN0YWtlVG9rZW4gc3Rha2VzIGFuIExQIHBvc2l0aW9uIE5GVCB0byBlYXJuIHJld2FyZHMuCi8vCi8vIFRyYW5zZmVycyBwb3NpdGlvbiBORlQgdG8gc3Rha2VyIGFuZCBiZWdpbnMgcmV3YXJkIGFjY3VtdWxhdGlvbi4KLy8gRWxpZ2libGUgZm9yIGludGVybmFsIGluY2VudGl2ZXMgKEdOUyBlbWlzc2lvbikgYW5kIGV4dGVybmFsIHJld2FyZHMuCi8vIEEgcG9vbCBpcyBzdGFrZWFibGUgd2hlbiBpdCBoYXMgYW4gaW50ZXJuYWwgdGllciBvciBhbiBhY3RpdmUvZnV0dXJlIGV4dGVybmFsIGluY2VudGl2ZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIHVuY2hhbmdlZCBieSB0aGUgc3Rha2VyIHByb3h5LgovLyAgIC0gcG9zaXRpb25JZDogTFAgcG9zaXRpb24gTkZUIHRva2VuIElEIHRvIHN0YWtlLgovLyAgIC0gcmVmZXJyZXI6IE9wdGlvbmFsIHJlZmVycmFsIGFkZHJlc3MgZm9yIHRyYWNraW5nLgovLwovLyBSZXR1cm5zOgovLyAgIC0gcG9vbFBhdGg6IFBvb2wgaWRlbnRpZmllciAodG9rZW4wOnRva2VuMTpmZWUpLgovLwovLyBSZXF1aXJlbWVudHM6Ci8vICAgLSBDYWxsZXIgbXVzdCBvd24gdGhlIHBvc2l0aW9uIE5GVC4KLy8gICAtIFBvc2l0aW9uIG11c3QgaGF2ZSBub24temVybyBsaXF1aWRpdHkuCi8vICAgLSBQb29sIG11c3QgaGF2ZSBhbiBpbnRlcm5hbCB0aWVyIG9yIGFuIGFjdGl2ZS9mdXR1cmUgZXh0ZXJuYWwgaW5jZW50aXZlLgovLyAgIC0gUG9zaXRpb24gbm90IGFscmVhZHkgc3Rha2VkLgovLwovLyBOb3RlOiBPdXQtb2YtcmFuZ2UgcG9zaXRpb25zIGVhcm4gbm8gcmV3YXJkcyBidXQgY2FuIGJlIHN0YWtlZC4KZnVuYyAocyAqc3Rha2VyVjEpIFN0YWtlVG9rZW4oXyBpbnQsIHJsbSByZWFsbSwgcG9zaXRpb25JZCB1aW50NjQsIHJlZmVycmVyIHN0cmluZykgc3RyaW5nIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRTdGFrZXIoKQoKCWFzc2VydElzTm90U3Rha2VkKHMsIHBvc2l0aW9uSWQpCglhc3NlcnRIYXNOb0V4aXRDaGVja3BvaW50KHMsIHBvc2l0aW9uSWQpCgoJZW4uTWludEFuZERpc3RyaWJ1dGVHbnMoY3Jvc3MocmxtKSkKCglwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgljYWxsZXIgOj0gcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkKCWN1cnJlbnRUaW1lIDo9IHRpbWUuTm93KCkuVW5peCgpCgoJb3duZXIsIGVyciA6PSBzLm5mdEFjY2Vzc29yLk93bmVyT2YocG9zaXRpb25JZEZyb20ocG9zaXRpb25JZCkpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIuRXJyb3IoKSkKCX0KCWFzc2VydElzUG9zaXRpb25Pd25lcihvd25lciwgY2FsbGVyKQoKCWFjdHVhbFJlZmVycmVyIDo9IHJlZmVycmFsLlRyeVJlZ2lzdGVyKGNyb3NzKHJsbSksIGNhbGxlciwgcmVmZXJyZXIpCgoJaWYgZXJyIDo9IHRva2VuSGFzTGlxdWlkaXR5KHBvc2l0aW9uSWQpOyBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIuRXJyb3IoKSkKCX0KCgkvLyBjaGVjayBwb29sIHBhdGggZnJvbSBwb3NpdGlvbklkCglwb29sUGF0aCwgZXJyIDo9IHBuLkdldFBvc2l0aW9uUG9vbEtleShwb3NpdGlvbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoJcG9vbHMgOj0gcy5nZXRQb29scygpCgoJcG9vbCwgb2sgOj0gcG9vbHMuR2V0KHBvb2xQYXRoKQoJaWYgIW9rIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJyTm9uSW5jZW50aXZpemVkUG9vbCwKCQkJdWZtdC5TcHJpbnRmKCJjYW5ub3Qgc3Rha2UgcG9zaXRpb24gdG8gbm9uIGV4aXN0aW5nIHBvb2woJXMpIiwgcG9vbFBhdGgpLAoJCSkpCgl9CgoJZXJyID0gcy5wb29sSGFzSW5jZW50aXZlcyhwb29sKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyLkVycm9yKCkpCgl9CgoJbGlxdWlkaXR5IDo9IGdldExpcXVpZGl0eShwb3NpdGlvbklkKQoJdGlja0xvd2VyLCB0aWNrVXBwZXIgOj0gZ2V0VGlja09mKHBvc2l0aW9uSWQpCgoJd2FybXVwcyA6PSBzLnN0b3JlLkdldFdhcm11cFRlbXBsYXRlKCkKCWN1cnJlbnRXYXJtdXBzIDo9IGluc3RhbnRpYXRlV2FybXVwKHdhcm11cHMsIGN1cnJlbnRUaW1lKQoKCS8vIHN0YWtlZCBzdGF0dXMKCWRlcG9zaXQgOj0gc3IuTmV3RGVwb3NpdCgKCQljYWxsZXIsCgkJcG9vbFBhdGgsCgkJbGlxdWlkaXR5LAoJCWN1cnJlbnRUaW1lLAoJCXRpY2tMb3dlciwKCQl0aWNrVXBwZXIsCgkJY3VycmVudFdhcm11cHMsCgkpCgoJLy8gd2hlbiBzdGFraW5nLCBhZGQgbmV3IGluY2VudGl2ZXMgdG8gZGVwb3NpdC4KCS8vCgkvLyBJbmNlbnRpdmUgZHVyYXRpb24gaXMgY2FwcGVkIGF0IFRJTUVTVEFNUF8zNjVEQVlTLCBzbyBhbnl0aGluZyBzdGlsbAoJLy8gYWN0aXZlIGF0IGN1cnJlbnRUaW1lIHN0YXJ0cyB3aXRoaW4gW2N1cnJlbnRUaW1lLTM2NWQsIGN1cnJlbnRUaW1lXS4KCS8vIEluY2VudGl2ZXMgc3RhcnRpbmcgYmVmb3JlIHRoYXQgd2luZG93IGhhdmUgZW5kZWQgYW5kIGFyZSBmaWx0ZXJlZCBieQoJLy8gdGhlIEVuZFRpbWVzdGFtcCBjaGVjayBiZWxvdy4KCS8vCgljdXJyZW50SW5jZW50aXZlSWRzIDo9IHMuZ2V0RXh0ZXJuYWxJbmNlbnRpdmVJZHNCeShwb29sUGF0aCwgc3Rha2VTY2FuTG93ZXJCb3VuZChjdXJyZW50VGltZSksIGN1cnJlbnRUaW1lKQoKCWZvciBfLCBpbmNlbnRpdmVJZCA6PSByYW5nZSBjdXJyZW50SW5jZW50aXZlSWRzIHsKCQlpbmNlbnRpdmUgOj0gcy5nZXRFeHRlcm5hbEluY2VudGl2ZXMoKS5nZXQoaW5jZW50aXZlSWQpCgkJLy8gSWYgaW5jZW50aXZlIGlzIGVuZGVkLCBub3QgYXZhaWxhYmxlIHRvIGNvbGxlY3QgcmV3YXJkCgkJaWYgY3VycmVudFRpbWUgPiBpbmNlbnRpdmUuRW5kVGltZXN0YW1wKCkgewoJCQljb250aW51ZQoJCX0KCgkJZGVwb3NpdC5BZGRFeHRlcm5hbEluY2VudGl2ZUlkKGluY2VudGl2ZUlkKQoJfQoKCS8vIHNldCBsYXN0IGV4dGVybmFsIGluY2VudGl2ZSBpZHMgdXBkYXRlZCBhdAoJZGVwb3NpdC5TZXRMYXN0RXh0ZXJuYWxJbmNlbnRpdmVVcGRhdGVkQXQoY3VycmVudFRpbWUpCgoJZGVwb3NpdHMgOj0gcy5nZXREZXBvc2l0cygpCglkZXBvc2l0cy5zZXQocG9zaXRpb25JZCwgZGVwb3NpdCkKCgkvLyB0cmFuc2ZlciBORlQgb3duZXJzaGlwIHRvIHN0YWtlciBjb250cmFjdAoJc3Rha2VyQWRkciA6PSBhY2Nlc3MuTXVzdEdldEFkZHJlc3MocHJiYWMuUk9MRV9TVEFLRVIuU3RyaW5nKCkpCglpZiBlcnIgOj0gcy50cmFuc2ZlckRlcG9zaXQoMCwgcmxtLCBwb3NpdGlvbklkLCBvd25lciwgY2FsbGVyLCBzdGFrZXJBZGRyKTsgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyLkVycm9yKCkpCgl9CgoJLy8gYWZ0ZXIgdHJhbnNmZXIsIHNldCBjYWxsZXIodXNlcikgYXMgcG9zaXRpb24gb3BlcmF0b3IgKHRvIGNvbGxlY3QgZmVlIGFuZCByZXdhcmQpCglwbi5TZXRQb3NpdGlvbk9wZXJhdG9yKGNyb3NzKHJsbSksIHBvc2l0aW9uSWQsIGNhbGxlcikKCglwb29sVGllciA6PSBzLmdldFBvb2xUaWVyKCkKCXBvb2xUaWVyLmNhY2hlUmV3YXJkRm9yUG9vbChjdXJyZW50VGltZSwgcG9vbHMsIHBvb2xQYXRoKQoKCXNpZ25lZExpcXVpZGl0eSA6PSBpMjU2LkZyb21VaW50MjU2KGxpcXVpZGl0eSkKCWN1cnJlbnRUaWNrIDo9IHMucG9vbEFjY2Vzc29yLkdldFNsb3QwVGljayhwb29sUGF0aCkKCglwb29sUmVzb2x2ZXIgOj0gTmV3UG9vbFJlc29sdmVyKHBvb2wpCgoJaXNJblJhbmdlIDo9IGZhbHNlCglpblJhbmdlLCBlcnIgOj0gcG4uSXNJblJhbmdlKHBvc2l0aW9uSWQpCglpZiBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CglpZiBpblJhbmdlIHsKCQlpc0luUmFuZ2UgPSB0cnVlCgkJcG9vbFJlc29sdmVyLm1vZGlmeURlcG9zaXQoc2lnbmVkTGlxdWlkaXR5LCBjdXJyZW50VGltZSwgY3VycmVudFRpY2spCgl9CgkvLyBoaXN0b3JpY2FsIHRpY2sgbXVzdCBiZSBzZXQgcmVnYXJkbGVzcyBvZiB0aGUgZGVwb3NpdCdzIHJhbmdlCglpZiBwb29sUmVzb2x2ZXIuaXNDaGFuZ2VkVGljayhjdXJyZW50VGltZSwgY3VycmVudFRpY2spIHsKCQlwb29sUmVzb2x2ZXIuUG9vbC5TZXRIaXN0b3JpY2FsVGlja0F0KGN1cnJlbnRUaW1lLCBjdXJyZW50VGljaykKCX0KCgkvLyBUaGlzIGNvdWxkIGhhcHBlbiBiZWNhdXNlIG9mIGhvdyBwb3NpdGlvbiBzdG9yZXMgdGhlIHRpY2tzLgoJLy8gVGlja3MgYXJlIG5lZ2F0ZWQgaWYgdGhlIHRva2VuMSA8IHRva2VuMC4KCS8vIEEgdGljayB0aGlzIHN0YWtlIGNyZWF0ZXMgbXVzdCBiZSBzZWVkZWQgYmVmb3JlIGl0IGlzIHBlcnNpc3RlZC4KCXVwcGVyVGljayA6PSBwb29sLlRpY2tzKCkuR2V0KHRpY2tVcHBlcikKCWlmIHVwcGVyVGljayA9PSBuaWwgewoJCXVwcGVyVGljayA9IHNyLk5ld1RpY2sodGlja1VwcGVyKQoJCXBvb2xSZXNvbHZlci5pbml0aWFsaXplTmV3VGlja091dHNpZGVBY2N1bXVsYXRpb24oY3VycmVudFRpbWUsIGN1cnJlbnRUaWNrLCB0aWNrVXBwZXIsIHVwcGVyVGljaykKCX0KCglsb3dlclRpY2sgOj0gcG9vbC5UaWNrcygpLkdldCh0aWNrTG93ZXIpCglpZiBsb3dlclRpY2sgPT0gbmlsIHsKCQlsb3dlclRpY2sgPSBzci5OZXdUaWNrKHRpY2tMb3dlcikKCQlwb29sUmVzb2x2ZXIuaW5pdGlhbGl6ZU5ld1RpY2tPdXRzaWRlQWNjdW11bGF0aW9uKGN1cnJlbnRUaW1lLCBjdXJyZW50VGljaywgdGlja0xvd2VyLCBsb3dlclRpY2spCgl9CgoJdXBwZXJUaWNrUmVzb2x2ZXIgOj0gTmV3VGlja1Jlc29sdmVyKHVwcGVyVGljaykKCWxvd2VyVGlja1Jlc29sdmVyIDo9IE5ld1RpY2tSZXNvbHZlcihsb3dlclRpY2spCgoJdXBwZXJUaWNrUmVzb2x2ZXIubW9kaWZ5RGVwb3NpdFVwcGVyKGN1cnJlbnRUaW1lLCBzaWduZWRMaXF1aWRpdHkpCglsb3dlclRpY2tSZXNvbHZlci5tb2RpZnlEZXBvc2l0TG93ZXIoY3VycmVudFRpbWUsIHNpZ25lZExpcXVpZGl0eSkKCglhbW91bnQwLCBhbW91bnQxIDo9IHMuY2FsY3VsYXRlQW1vdW50cyhwb29sUGF0aCwgdGlja0xvd2VyLCB0aWNrVXBwZXIsIGxpcXVpZGl0eSkKCgkvLyBHZXQgYWNjdW11bGF0b3IgdmFsdWVzIGZvciByZXdhcmQgY2FsY3VsYXRpb24gdHJhY2tpbmcKCWdsb2JhbEFjY1gxMjgsIHN0YWtlZExpcXVpZGl0eSA6PSBwb29sUmVzb2x2ZXIuZ2xvYmFsUmV3YXJkUmF0aW9BY2N1bXVsYXRpb25BdChjdXJyZW50VGltZSkKCWxvd2VyT3V0c2lkZUFjY1gxMjggOj0gbG93ZXJUaWNrUmVzb2x2ZXIuQ3VycmVudE91dHNpZGVBY2N1bXVsYXRpb24oY3VycmVudFRpbWUpCgl1cHBlck91dHNpZGVBY2NYMTI4IDo9IHVwcGVyVGlja1Jlc29sdmVyLkN1cnJlbnRPdXRzaWRlQWNjdW11bGF0aW9uKGN1cnJlbnRUaW1lKQoKCXBvb2wuVGlja3MoKS5TZXRUaWNrKHRpY2tVcHBlciwgdXBwZXJUaWNrKQoJcG9vbC5UaWNrcygpLlNldFRpY2sodGlja0xvd2VyLCBsb3dlclRpY2spCglzLmdldFBvb2xzKCkuc2V0KHBvb2xQYXRoLCBwb29sKQoKCWNoYWluLkVtaXQoCgkJIlN0YWtlVG9rZW4iLAoJCSJwcmV2QWRkciIsIHByZXZpb3VzUmVhbG0uQWRkcmVzcygpLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2aW91c1JlYWxtLlBrZ1BhdGgoKSwKCQkicG9zaXRpb25JZCIsIHV0aWxzLkZvcm1hdFVpbnQocG9zaXRpb25JZCksCgkJInBvb2xQYXRoIiwgcG9vbFBhdGgsCgkJIm93bmVyIiwgb3duZXIuU3RyaW5nKCksCgkJImxpcXVpZGl0eSIsIGxpcXVpZGl0eS5Ub1N0cmluZygpLAoJCSJwb3NpdGlvblVwcGVyVGljayIsIHV0aWxzLkZvcm1hdEludCh0aWNrVXBwZXIpLAoJCSJwb3NpdGlvbkxvd2VyVGljayIsIHV0aWxzLkZvcm1hdEludCh0aWNrTG93ZXIpLAoJCSJjdXJyZW50VGljayIsIHV0aWxzLkZvcm1hdEludChjdXJyZW50VGljayksCgkJImlzSW5SYW5nZSIsIHV0aWxzLkZvcm1hdEJvb2woaXNJblJhbmdlKSwKCQkicmVmZXJyZXIiLCBhY3R1YWxSZWZlcnJlciwKCQkiYW1vdW50MCIsIGFtb3VudDAuVG9TdHJpbmcoKSwKCQkiYW1vdW50MSIsIGFtb3VudDEuVG9TdHJpbmcoKSwKCQkic3Rha2VkTGlxdWlkaXR5Iiwgc3Rha2VkTGlxdWlkaXR5LlRvU3RyaW5nKCksCgkJImdsb2JhbFJld2FyZFJhdGlvQWNjWDEyOCIsIGdsb2JhbEFjY1gxMjguVG9TdHJpbmcoKSwKCQkibG93ZXJUaWNrT3V0c2lkZUFjY1gxMjgiLCBsb3dlck91dHNpZGVBY2NYMTI4LlRvU3RyaW5nKCksCgkJInVwcGVyVGlja091dHNpZGVBY2NYMTI4IiwgdXBwZXJPdXRzaWRlQWNjWDEyOC5Ub1N0cmluZygpLAoJKQoKCXJldHVybiBwb29sUGF0aAp9CgovLyB0cmFuc2ZlckRlcG9zaXQgdHJhbnNmZXJzIGRlcG9zaXQgb3duZXJzaGlwIHRvIGEgbmV3IGFkZHJlc3MuCi8vCi8vIE1hbmFnZXMgTkZUIGN1c3RvZHkgZHVyaW5nIHN0YWtpbmcgb3BlcmF0aW9ucy4KLy8gVHJhbnNmZXJzIG93bmVyc2hpcCB0byBzdGFrZXIgY29udHJhY3QgZm9yIHJld2FyZCBlbGlnaWJpbGl0eS4KLy8gSGFuZGxlcyBjYXNlcyB3aGVyZSB0aGUgc3Rha2VyIGFscmVhZHkgaG9sZHMgY3VzdG9keS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvc2l0aW9uSWQ6IFRoZSBJRCBvZiB0aGUgcG9zaXRpb24gTkZUIHRvIHRyYW5zZmVyCi8vICAgLSBvd25lcjogVGhlIGN1cnJlbnQgb3duZXIgb2YgdGhlIHBvc2l0aW9uCi8vICAgLSBjYWxsZXI6IFRoZSBlbnRpdHkgaW5pdGlhdGluZyB0aGUgdHJhbnNmZXIKLy8gICAtIHRvOiBUaGUgcmVjaXBpZW50IGFkZHJlc3MgKHVzdWFsbHkgc3Rha2VyIGNvbnRyYWN0KQovLwovLyBTZWN1cml0eSBGZWF0dXJlczoKLy8gICAtIFByZXZlbnRzIHNlbGYtdHJhbnNmZXIgZXhwbG9pdHMKLy8gICAtIFZhbGlkYXRlcyBvd25lcnNoaXAgYmVmb3JlIHRyYW5zZmVyCi8vICAgLSBBdG9taWMgb3BlcmF0aW9uIHdpdGggc3Rha2luZwovLyAgIC0gTm8gdHJhbnNmZXIgaWYgb3duZXIgPT0gdG8gKGFscmVhZHkgaW4gY3VzdG9keSkKLy8KLy8gUmV0dXJuczoKLy8gICAtIG5pbDogSWYgb3duZXIgYW5kIHJlY2lwaWVudCBhcmUgc2FtZQovLyAgIC0gZXJyb3I6IElmIGNhbGxlciB1bmF1dGhvcml6ZWQgb3IgdHJhbnNmZXIgZmFpbHMKLy8KLy8gTkZUIHJlbWFpbnMgbG9ja2VkIGluIHN0YWtlciB1bnRpbCB1bnN0YWtpbmcuCi8vIE90aGVyd2lzZSBkZWxlZ2F0ZXMgdGhlIHRyYW5zZmVyIHRvIGBnbmZ0LlRyYW5zZmVyRnJvbWAuCmZ1bmMgKHMgKnN0YWtlclYxKSB0cmFuc2ZlckRlcG9zaXQoXyBpbnQsIHJsbSByZWFsbSwgcG9zaXRpb25JZCB1aW50NjQsIG93bmVyLCBjYWxsZXIsIHRvIGFkZHJlc3MpIGVycm9yIHsKCS8vIElmIHRoZSByZWNpcGllbnQgYWxyZWFkeSBvd25zIHRoZSBORlQsIG5vIHRyYW5zZmVyIGlzIG5lZWRlZC4KCWlmIG93bmVyID09IHRvIHsKCQlyZXR1cm4gbmlsCgl9CgoJaWYgY2FsbGVyID09IHRvIHsKCQlyZXR1cm4gdWZtdC5FcnJvcmYoCgkJCSIldjogb25seSBvd25lciglcykgY2FuIHRyYW5zZmVyIHBvc2l0aW9uSWQoJWQpLCBjYWxsZWQgZnJvbSAlcyIsCgkJCWVyck5vUGVybWlzc2lvbiwgb3duZXIsIHBvc2l0aW9uSWQsIGNhbGxlciwKCQkpCgl9CgoJLy8gdHJhbnNmZXIgTkZUIG93bmVyc2hpcAoJcmV0dXJuIHMubmZ0QWNjZXNzb3IuVHJhbnNmZXJGcm9tKDAsIHJsbSwgb3duZXIsIHRvLCBwb3NpdGlvbklkRnJvbShwb3NpdGlvbklkKSkKfQoKLy8gY29sbGVjdENvbnRleHQgY2FycmllcyB0aGUgdmFsdWVzIGV2ZXJ5IHJld2FyZCBkZWxpdmVyeSBvZiBvbmUgY29sbGVjdCBjYWxsIHNoYXJlczogdGhlIGRlcG9zaXQgYmVpbmcKLy8gY29sbGVjdGVkLCB0aGUgY29sbGVjdCB0aW1lc3RhbXAgYW5kIGhlaWdodCwgdGhlIGNhbGxlciBpZGVudGl0eSB1c2VkIGluIGV2ZW50cywgYW5kIHRoZSBhY2N1bXVsYXRvcgovLyBzbmFwc2hvdCBlbWl0dGVkIHdpdGggZXZlcnkgY29sbGVjdCBldmVudC4KLy8KLy8gUmVzb2x2aW5nIGl0IG9uY2UgaXMgd2hhdCBrZWVwcyBhIGNvbGxlY3QtZXZlcnl0aGluZyBjYWxsIGF0IGEgc2luZ2xlIHNuYXBzaG90OiB0aGUgZW1pc3Npb24gZGVsaXZlcnkKLy8gYW5kIGVhY2ggaW5jZW50aXZlIGRlbGl2ZXJ5IGFsbCByZWFkIHRoZSBzYW1lIGNvbnRleHQuCnR5cGUgY29sbGVjdENvbnRleHQgc3RydWN0IHsKCXBvc2l0aW9uSWQgICAgICB1aW50NjQKCWRlcG9zaXQgICAgICAgICAqc3IuRGVwb3NpdAoJZGVwb3NpdFJlc29sdmVyICpEZXBvc2l0UmVzb2x2ZXIKCgkvLyBjaGVja3BvaW50IGlzIHNldCB3aGVuIHRoZSBwb3NpdGlvbiB3YXMgdW5zdGFrZWQgYmVmb3JlIGNvbGxlY3RpbmcuCgljaGVja3BvaW50ICpzci5VbnN0YWtlZFBvc2l0aW9uCgoJY3VycmVudFRpbWUgaW50NjQKCWJsb2NrSGVpZ2h0IGludDY0CgoJcHJldkFkZHIgIHN0cmluZwoJcHJldlJlYWxtIHN0cmluZwoKCXN0YWtlZExpcXVpZGl0eSAgICAgKnUyNTYuVWludAoJZ2xvYmFsQWNjWDEyOCAgICAgICAqdTI1Ni5VaW50Cglsb3dlck91dHNpZGVBY2NYMTI4ICp1MjU2LlVpbnQKCXVwcGVyT3V0c2lkZUFjY1gxMjggKnUyNTYuVWludAp9CgovLyBuZXdDb2xsZWN0Q29udGV4dCByZXNvbHZlcyB0aGUgZGVwb3NpdCBhbmQgc25hcHNob3RzIHRoZSBhY2N1bXVsYXRvciB2YWx1ZXMgdXNlZCBmb3IgcmV3YXJkCi8vIGNhbGN1bGF0aW9uIHRyYWNraW5nLiBDYWxsIGl0IEFGVEVSIHRoZSBjYWxjdWxhdGlvbidzIHN0YXRlIHVwZGF0ZSBoYXMgYmVlbiBhcHBsaWVkLCBzbyBhIGxhemlseQovLyBjcmVhdGVkIHBvb2wgaXMgYWxyZWFkeSBwZXJzaXN0ZWQuCmZ1bmMgKHMgKnN0YWtlclYxKSBuZXdDb2xsZWN0Q29udGV4dChfIGludCwgcmxtIHJlYWxtLCB0YXJnZXQgKmNvbGxlY3RUYXJnZXQsIGN1cnJlbnRUaW1lLCBibG9ja0hlaWdodCBpbnQ2NCkgKmNvbGxlY3RDb250ZXh0IHsKCXBvc2l0aW9uSWQgOj0gdGFyZ2V0LnBvc2l0aW9uSWQKCWRlcG9zaXQgOj0gdGFyZ2V0LmRlcG9zaXQKCglwb29sLCBfIDo9IHMuZ2V0UG9vbHMoKS5HZXQoZGVwb3NpdC5UYXJnZXRQb29sUGF0aCgpKQoJcG9vbFJlc29sdmVyIDo9IG5ld1Bvb2xSZXNvbHZlcldpdGhFeGl0KHBvb2wsIHRhcmdldC5jaGVja3BvaW50KQoJZ2xvYmFsQWNjWDEyOCwgc3Rha2VkTGlxdWlkaXR5IDo9IHBvb2xSZXNvbHZlci5nbG9iYWxSZXdhcmRSYXRpb0FjY3VtdWxhdGlvbkF0KGN1cnJlbnRUaW1lKQoKCXByZXZpb3VzUmVhbG0gOj0gcmxtLlByZXZpb3VzKCkKCglyZXR1cm4gJmNvbGxlY3RDb250ZXh0ewoJCXBvc2l0aW9uSWQ6ICAgICAgcG9zaXRpb25JZCwKCQlkZXBvc2l0OiAgICAgICAgIGRlcG9zaXQsCgkJZGVwb3NpdFJlc29sdmVyOiBOZXdEZXBvc2l0UmVzb2x2ZXIoZGVwb3NpdCksCgkJY2hlY2twb2ludDogICAgICB0YXJnZXQuY2hlY2twb2ludCwKCgkJY3VycmVudFRpbWU6IGN1cnJlbnRUaW1lLAoJCWJsb2NrSGVpZ2h0OiBibG9ja0hlaWdodCwKCgkJcHJldkFkZHI6ICBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKS5TdHJpbmcoKSwKCQlwcmV2UmVhbG06IHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoKCQlzdGFrZWRMaXF1aWRpdHk6ICAgICBzdGFrZWRMaXF1aWRpdHksCgkJZ2xvYmFsQWNjWDEyODogICAgICAgZ2xvYmFsQWNjWDEyOCwKCQlsb3dlck91dHNpZGVBY2NYMTI4OiBwb29sUmVzb2x2ZXIub3V0c2lkZUFjY3VtdWxhdGlvbkF0KGRlcG9zaXQuVGlja0xvd2VyKCksIGN1cnJlbnRUaW1lKSwKCQl1cHBlck91dHNpZGVBY2NYMTI4OiBwb29sUmVzb2x2ZXIub3V0c2lkZUFjY3VtdWxhdGlvbkF0KGRlcG9zaXQuVGlja1VwcGVyKCksIGN1cnJlbnRUaW1lKSwKCX0KfQoKLy8gdW5zdGFraW5nRmVlIHJldHVybnMgdGhlIGZlZSByYXRlIHRoaXMgY29sbGVjdCBzZXR0bGVzIHVuZGVyOiB0aGUgbGl2ZSByYXRlIHdoaWxlIHN0YWtlZCwKLy8gYW5kIHRoZSByYXRlIHBpbm5lZCBhdCBleGl0IGZvciBhIGNoZWNrcG9pbnQsIHdob3NlIHdpbmRvdyBjbG9zZWQgdW5kZXIgaXQuCmZ1bmMgKHNlbGYgKmNvbGxlY3RDb250ZXh0KSB1bnN0YWtpbmdGZWUocyAqc3Rha2VyVjEpIHVpbnQ2NCB7CglpZiBzZWxmLmNoZWNrcG9pbnQgIT0gbmlsIHsKCQlyZXR1cm4gc2VsZi5jaGVja3BvaW50LlVuc3Rha2luZ0ZlZSgpCgl9CgoJcmV0dXJuIHMuR2V0VW5zdGFraW5nRmVlKCkKfQoKLy8gcGVyc2lzdERlcG9zaXQgd3JpdGVzIHRoZSBkZXBvc2l0IGJhY2ssIHVubGVzcyBpdCBiZWxvbmdzIHRvIGEgY2hlY2twb2ludCBhbmQgaXMgbm90IHRoZXJlLgpmdW5jIChzZWxmICpjb2xsZWN0Q29udGV4dCkgcGVyc2lzdERlcG9zaXQocyAqc3Rha2VyVjEpIHsKCWlmIHNlbGYuY2hlY2twb2ludCAhPSBuaWwgewoJCXJldHVybgoJfQoKCXMuZ2V0RGVwb3NpdHMoKS5zZXQoc2VsZi5wb3NpdGlvbklkLCBzZWxmLmRlcG9zaXQpCn0KCi8vIGV4dGVybmFsRGVsaXZlcnlPdXRjb21lIGlzIHdoYXQgZGVsaXZlckV4dGVybmFsSW5jZW50aXZlUmV3YXJkIGRpZCB3aXRoIG9uZSBpbmNlbnRpdmUuIFRoZQovLyBjaGVja3BvaW50IGJvb2trZWVwaW5nIGtleXMgb2ZmIGl0IGluc3RlYWQgb2YgcmUtZGVyaXZpbmcgdGhlIGRlY2lzaW9uIGZyb20gaW5jZW50aXZlIHN0YXRlLAovLyB3aGljaCBhIHBlcm1pc3Npb25sZXNzIHJlLWVudGVyaW5nIGNvbGxlY3QgbWF5IGFscmVhZHkgaGF2ZSBjaGFuZ2VkLgp0eXBlIGV4dGVybmFsRGVsaXZlcnlPdXRjb21lIGludAoKY29uc3QgKAoJLy8gZXh0ZXJuYWxEZWxpdmVyeVBhaWQ6IHRoZSBpbmNlbnRpdmUgd2FzIGRlYml0ZWQsIHRoZSBjdXJzb3IgYWR2YW5jZWQgYW5kIHRoZSByZXdhcmQgbW92ZWQuCglleHRlcm5hbERlbGl2ZXJ5UGFpZCBleHRlcm5hbERlbGl2ZXJ5T3V0Y29tZSA9IGlvdGEKCS8vIGV4dGVybmFsRGVsaXZlcnlOb3RoaW5nT3dlZDogdGhlIHdpbmRvdyB5aWVsZGVkIG5vIHJld2FyZCBhbmQgbm8gcGVuYWx0eS4KCWV4dGVybmFsRGVsaXZlcnlOb3RoaW5nT3dlZAoJLy8gZXh0ZXJuYWxEZWxpdmVyeUFscmVhZHlEZWxpdmVyZWQ6IGEgY2hlY2twb2ludCBjdXJzb3IgYWxyZWFkeSBhdCB0aGUgd2luZG93J3MgY2xvc2UsIHNvIHRoZQoJLy8gc291cmNlIGlzIHNldHRsZWQgLSBieSBhIGNvbGxlY3QgZWFybGllciBpbiB0aGUgZXhpdCBzZWNvbmQsIG9yIGJ5IGFuIG91dGVyIGNhbGwgd2hvc2UKCS8vIHRyYW5zZmVyIHRoaXMgY2FsbCByZS1lbnRlcmVkIGZyb20uCglleHRlcm5hbERlbGl2ZXJ5QWxyZWFkeURlbGl2ZXJlZAoJLy8gZXh0ZXJuYWxEZWxpdmVyeURlZmVycmVkOiBza2lwcGVkIHdpdGhvdXQgYm9va2tlZXBpbmcgYW5kIHN0aWxsIHBheWFibGUgbGF0ZXIgLSB0aGUgaW5jZW50aXZlCgkvLyBoYXMgbm90IHN0YXJ0ZWQsIG9yIHRoZSBzdGFrZXIgcmVhbG0ncyBiYWxhbmNlIG9mIHRoZSByZXdhcmQgdG9rZW4gaXMgc2hvcnQgd2hpbGUgc3Rha2VkLgoJZXh0ZXJuYWxEZWxpdmVyeURlZmVycmVkCgkvLyBleHRlcm5hbERlbGl2ZXJ5VW5wYXlhYmxlOiBza2lwcGVkIHdpdGhvdXQgYm9va2tlZXBpbmcgYW5kIG5ldmVyIHBheWFibGUgZnJvbSB0aGlzIHJlY29yZCwKCS8vIGJlY2F1c2UgdGhlIGluY2VudGl2ZSdzIHJld2FyZCBhbW91bnQgb25seSBldmVyIGRlY3JlYXNlcy4KCWV4dGVybmFsRGVsaXZlcnlVbnBheWFibGUKKQoKLy8gbWFya0VtaXNzaW9uQ29sbGVjdGVkIHJlY29yZHMgdGhlIGVtaXNzaW9uIGNvbGxlY3Qgb24gdGhlIGNoZWNrcG9pbnQuIElkZW1wb3RlbnQ6IGEKLy8gcmUtZW50ZXJpbmcgY29sbGVjdCBtYXkgaGF2ZSBtYXJrZWQgaXQgYWxyZWFkeS4KZnVuYyAocyAqc3Rha2VyVjEpIG1hcmtFbWlzc2lvbkNvbGxlY3RlZChfIGludCwgcmxtIHJlYWxtLCB0YXJnZXQgKmNvbGxlY3RUYXJnZXQpIHsKCWlmICF0YXJnZXQuaXNDaGVja3BvaW50KCkgfHwgdGFyZ2V0LmNoZWNrcG9pbnQuRW1pc3Npb25Db2xsZWN0ZWQoKSB7CgkJcmV0dXJuCgl9CgoJdGFyZ2V0LmNoZWNrcG9pbnQuTWFya0VtaXNzaW9uQ29sbGVjdGVkKCkKCXMuZW1pdENoZWNrcG9pbnRTb3VyY2VDb2xsZWN0ZWQoMCwgcmxtLCB0YXJnZXQsICJlbWlzc2lvbiIsICIiKQoJcy5kcm9wVW5zdGFrZWRQb3NpdGlvbklmQ29sbGVjdGVkKDAsIHJsbSwgdGFyZ2V0KQp9CgovLyBzZXR0bGVIYWx0ZWRFbWlzc2lvbiBoYW5kbGVzIHRoZSBlbWlzc2lvbiBzb3VyY2Ugb2YgYSBjb2xsZWN0IHRoYXQgcmFuIHdoaWxlIGVtaXNzaW9uIGlzIGhhbHRlZC4KZnVuYyAocyAqc3Rha2VyVjEpIHNldHRsZUhhbHRlZEVtaXNzaW9uKF8gaW50LCBybG0gcmVhbG0sIHRhcmdldCAqY29sbGVjdFRhcmdldCwgcmV3YXJkUGFyYW0gKmNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkUGFyYW0pIHsKCWlmICF0YXJnZXQuaXNDaGVja3BvaW50KCkgfHwgdGFyZ2V0LmNoZWNrcG9pbnQuRW1pc3Npb25Db2xsZWN0ZWQoKSB7CgkJcmV0dXJuCgl9CgoJaW50ZXJuYWxSZXdhcmRzLCBfLCBlcnIgOj0gcy5jYWxjdWxhdGVJbnRlcm5hbFBvc2l0aW9uUmV3YXJkKHJld2FyZFBhcmFtKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCWludGVybmFsUmV3YXJkIDo9IGFnZ3JlZ2F0ZVJld2FyZHMoaW50ZXJuYWxSZXdhcmRzKQoJaWYgaW50ZXJuYWxSZXdhcmQuSW50ZXJuYWwgIT0gMCB8fCBpbnRlcm5hbFJld2FyZC5JbnRlcm5hbFBlbmFsdHkgIT0gMCB7CgkJcmV0dXJuCgl9CgoJLy8gTWFyayB0aGUgY2hlY2twb2ludCdzIGVtaXNzaW9uIHNvdXJjZSBhcyBjb2xsZWN0ZWQuCglzLm1hcmtFbWlzc2lvbkNvbGxlY3RlZCgwLCBybG0sIHRhcmdldCkKfQoKLy8gbWFya0luY2VudGl2ZUNvbGxlY3RlZCByZWNvcmRzIHRoZSBpbmNlbnRpdmUgY29sbGVjdCBvbiB0aGUgY2hlY2twb2ludCBmcm9tIHRoZSBkZWxpdmVyeSdzCi8vIHJlcG9ydGVkIG91dGNvbWUuIEEgcGFpZCwgZW1wdHkgb3IgYWxyZWFkeS1kZWxpdmVyZWQgc291cmNlIGlzIGRvbmUuIEEgZGVmZXJyZWQgb25lIHN0YXlzCi8vIHBlbmRpbmcuIEFuIHVucGF5YWJsZSBvbmUgaXMgZm9yZmVpdGVkOiBrZWVwaW5nIGl0IHBlbmRpbmcgZm9yZXZlciB3b3VsZCBsb2NrIGJvdGggdGhpcwovLyBwb3NpdGlvbidzIHJlLXN0YWtpbmcgYW5kIHRoZSBpbmNlbnRpdmUncyBvd24gcmVmdW5kLCB3aXRoIG5vIGVzY2FwZSBwYXRoLgpmdW5jIChzICpzdGFrZXJWMSkgbWFya0luY2VudGl2ZUNvbGxlY3RlZChfIGludCwgcmxtIHJlYWxtLCB0YXJnZXQgKmNvbGxlY3RUYXJnZXQsIGluY2VudGl2ZUlkIHN0cmluZywgcmV3YXJkQW1vdW50LCByZXdhcmRQZW5hbHR5IGludDY0LCBvdXRjb21lIGV4dGVybmFsRGVsaXZlcnlPdXRjb21lKSB7CglpZiAhdGFyZ2V0LmlzQ2hlY2twb2ludCgpIHx8ICF0YXJnZXQuY2hlY2twb2ludC5IYXNQZW5kaW5nSW5jZW50aXZlSWQoaW5jZW50aXZlSWQpIHsKCQlyZXR1cm4KCX0KCglzd2l0Y2ggb3V0Y29tZSB7CgljYXNlIGV4dGVybmFsRGVsaXZlcnlEZWZlcnJlZDoKCQlyZXR1cm4KCWNhc2UgZXh0ZXJuYWxEZWxpdmVyeVVucGF5YWJsZToKCQlpbmNlbnRpdmVSZXNvbHZlciA6PSBOZXdFeHRlcm5hbEluY2VudGl2ZVJlc29sdmVyKHMuZ2V0RXh0ZXJuYWxJbmNlbnRpdmVzKCkuZ2V0KGluY2VudGl2ZUlkKSkKCQlwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgkJY2hhaW4uRW1pdCgKCQkJIkZvcmZlaXRVbmNvbGxlY3RlZEluY2VudGl2ZVJld2FyZCIsCgkJCSJwcmV2QWRkciIsIHByZXZpb3VzUmVhbG0uQWRkcmVzcygpLlN0cmluZygpLAoJCQkicHJldlJlYWxtIiwgcHJldmlvdXNSZWFsbS5Qa2dQYXRoKCksCgkJCSJwb3NpdGlvbklkIiwgdXRpbHMuRm9ybWF0VWludCh0YXJnZXQucG9zaXRpb25JZCksCgkJCSJpbmNlbnRpdmVJZCIsIGluY2VudGl2ZUlkLAoJCQkicmV3YXJkVG9rZW4iLCBpbmNlbnRpdmVSZXNvbHZlci5SZXdhcmRUb2tlbigpLAoJCQkiZm9yZmVpdGVkQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KHJld2FyZEFtb3VudCksCgkJCSJmb3JmZWl0ZWRQZW5hbHR5IiwgdXRpbHMuRm9ybWF0SW50KHJld2FyZFBlbmFsdHkpLAoJCQkiYXZhaWxhYmxlQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KGluY2VudGl2ZVJlc29sdmVyLlJld2FyZEFtb3VudCgpKSwKCQkJImN1cnJlbnRUaW1lIiwgdXRpbHMuRm9ybWF0SW50KHRpbWUuTm93KCkuVW5peCgpKSwKCQkJImN1cnJlbnRIZWlnaHQiLCB1dGlscy5Gb3JtYXRJbnQocnVudGltZS5DaGFpbkhlaWdodCgpKSwKCQkpCgl9CgoJdGFyZ2V0LmNoZWNrcG9pbnQuTWFya0luY2VudGl2ZUNvbGxlY3RlZChpbmNlbnRpdmVJZCkKCXMuYWRkVW5jb2xsZWN0ZWRJbmNlbnRpdmVDb3VudChpbmNlbnRpdmVJZCwgLTEpCglzLmVtaXRDaGVja3BvaW50U291cmNlQ29sbGVjdGVkKDAsIHJsbSwgdGFyZ2V0LCAiZXh0ZXJuYWwiLCBpbmNlbnRpdmVJZCkKCXMuZHJvcFVuc3Rha2VkUG9zaXRpb25JZkNvbGxlY3RlZCgwLCBybG0sIHRhcmdldCkKfQoKLy8gZW1pdENoZWNrcG9pbnRTb3VyY2VDb2xsZWN0ZWQgcmVwb3J0cyBvbmUgcmV3YXJkIHNvdXJjZSBvZiBhIGNoZWNrcG9pbnQgYXMgc2V0dGxlZCwgc28gYW4KLy8gaW5kZXhlciBjYW4gZm9sbG93IHdoYXQgdGhlIGNoZWNrcG9pbnQgc3RpbGwgb3dlcyB3aXRob3V0IHJlYWRpbmcgcmVhbG0gc3RhdGUuCmZ1bmMgKHMgKnN0YWtlclYxKSBlbWl0Q2hlY2twb2ludFNvdXJjZUNvbGxlY3RlZChfIGludCwgcmxtIHJlYWxtLCB0YXJnZXQgKmNvbGxlY3RUYXJnZXQsIHNvdXJjZSwgaW5jZW50aXZlSWQgc3RyaW5nKSB7CglwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgljaGFpbi5FbWl0KAoJCSJDb2xsZWN0VW5zdGFrZWRQb3NpdGlvblNvdXJjZSIsCgkJInByZXZBZGRyIiwgcHJldmlvdXNSZWFsbS5BZGRyZXNzKCkuU3RyaW5nKCksCgkJInByZXZSZWFsbSIsIHByZXZpb3VzUmVhbG0uUGtnUGF0aCgpLAoJCSJwb3NpdGlvbklkIiwgdXRpbHMuRm9ybWF0VWludCh0YXJnZXQucG9zaXRpb25JZCksCgkJInBvb2xQYXRoIiwgdGFyZ2V0LmRlcG9zaXQuVGFyZ2V0UG9vbFBhdGgoKSwKCQkic291cmNlIiwgc291cmNlLAoJCSJpbmNlbnRpdmVJZCIsIGluY2VudGl2ZUlkLAoJCSJleGl0VGltZSIsIHV0aWxzLkZvcm1hdEludCh0YXJnZXQuY2hlY2twb2ludC5FeGl0VGltZSgpKSwKCQkiZW1pc3Npb25Db2xsZWN0ZWQiLCB1dGlscy5Gb3JtYXRCb29sKHRhcmdldC5jaGVja3BvaW50LkVtaXNzaW9uQ29sbGVjdGVkKCkpLAoJCSJwZW5kaW5nSW5jZW50aXZlQ291bnQiLCB1dGlscy5Gb3JtYXRJbnQoaW50NjQodGFyZ2V0LmNoZWNrcG9pbnQuUGVuZGluZ0luY2VudGl2ZUNvdW50KCkpKSwKCQkiY3VycmVudFRpbWUiLCB1dGlscy5Gb3JtYXRJbnQodGltZS5Ob3coKS5Vbml4KCkpLAoJCSJjdXJyZW50SGVpZ2h0IiwgdXRpbHMuRm9ybWF0SW50KHJ1bnRpbWUuQ2hhaW5IZWlnaHQoKSksCgkpCn0KCi8vIGNvbGxlY3RUYXJnZXQgaXMgdGhlIHJlY29yZCBhIGNvbGxlY3QgcnVucyBhZ2FpbnN0OiB0aGUgbGl2ZSBkZXBvc2l0IHdoaWxlIHN0YWtlZCwgb3IgdGhlCi8vIGV4aXQgY2hlY2twb2ludCBhbiB1bnN0YWtlIGxlZnQgYmVoaW5kLgp0eXBlIGNvbGxlY3RUYXJnZXQgc3RydWN0IHsKCXBvc2l0aW9uSWQgdWludDY0CglkZXBvc2l0ICAgICpzci5EZXBvc2l0CgkvLyBjdXJyZW50VGltZSBpcyBub3cgd2hpbGUgc3Rha2VkLCBhbmQgdGhlIGV4aXQgdGltZSBmb3IgYSBjaGVja3BvaW50LgoJY3VycmVudFRpbWUgaW50NjQKCWNoZWNrcG9pbnQgICpzci5VbnN0YWtlZFBvc2l0aW9uCn0KCi8vIGNoZWNrcG9pbnREZXBvc2l0IHJldHVybnMgdGhlIGRlcG9zaXQgdG8gY2FsY3VsYXRlIGFnYWluc3Qgd2hlbiBpdCBpcyBub3QgaW4gdGhlIHRyZWUuCmZ1bmMgKHNlbGYgKmNvbGxlY3RUYXJnZXQpIGNoZWNrcG9pbnREZXBvc2l0KCkgKnNyLkRlcG9zaXQgewoJaWYgc2VsZi5jaGVja3BvaW50ID09IG5pbCB7CgkJcmV0dXJuIG5pbAoJfQoKCXJldHVybiBzZWxmLmRlcG9zaXQKfQoKLy8gaXNDaGVja3BvaW50IHJlcG9ydHMgd2hldGhlciB0aGUgY29sbGVjdCBydW5zIGFnYWluc3QgYW4gZXhpdCBjaGVja3BvaW50LgpmdW5jIChzZWxmICpjb2xsZWN0VGFyZ2V0KSBpc0NoZWNrcG9pbnQoKSBib29sIHsKCXJldHVybiBzZWxmLmNoZWNrcG9pbnQgIT0gbmlsCn0KCi8vIHJlc29sdmVDb2xsZWN0VGFyZ2V0IHJlc29sdmVzIHdoYXQgYSBjb2xsZWN0IHJ1bnMgYWdhaW5zdCBhbmQgYXNzZXJ0cyB0aGUgY2FsbGVyIG1heS4KZnVuYyAocyAqc3Rha2VyVjEpIHJlc29sdmVDb2xsZWN0VGFyZ2V0KHBvc2l0aW9uSWQgdWludDY0LCBjYWxsZXIgYWRkcmVzcykgKmNvbGxlY3RUYXJnZXQgewoJcG9zaXRpb24gOj0gcy5nZXRVbnN0YWtlZFBvc2l0aW9ucygpLmdldChwb3NpdGlvbklkKQoJaWYgcG9zaXRpb24gPT0gbmlsIHsKCQlhc3NlcnRJc0RlcG9zaXRvcihzLCBjYWxsZXIsIHBvc2l0aW9uSWQpCgoJCXJldHVybiAmY29sbGVjdFRhcmdldHsKCQkJcG9zaXRpb25JZDogIHBvc2l0aW9uSWQsCgkJCWRlcG9zaXQ6ICAgICBzLmdldERlcG9zaXRzKCkuZ2V0KHBvc2l0aW9uSWQpLAoJCQljdXJyZW50VGltZTogdGltZS5Ob3coKS5Vbml4KCksCgkJfQoJfQoKCS8vIEEgY2hlY2twb2ludCBjb2xsZWN0IGlzIHBlcm1pc3Npb25sZXNzOiBpdCBjYW4gb25seSBldmVyIGRlbGl2ZXIgdG8gdGhlIHBvc2l0aW9uJ3Mgb3duZXIsCgkvLyBhbmQgYW4gb3BlbiBlbnRyeSBwb2ludCBpcyB3aGF0IGxldHMgYW55b25lIGNsZWFyIHRoZSBjaGVja3BvaW50cyB0aGF0IGhvbGQgdXAKCS8vIEVuZEV4dGVybmFsSW5jZW50aXZlIG9uIHRoZSBwb29sLgoJcmV0dXJuICZjb2xsZWN0VGFyZ2V0ewoJCXBvc2l0aW9uSWQ6ICBwb3NpdGlvbklkLAoJCWRlcG9zaXQ6ICAgICBwb3NpdGlvbi5EZXBvc2l0KCksCgkJY3VycmVudFRpbWU6IHBvc2l0aW9uLkV4aXRUaW1lKCksCgkJY2hlY2twb2ludDogIHBvc2l0aW9uLAoJfQp9CgovLyBuZXdSZXdhcmRDb2xsZWN0UGFyYW0gYnVpbGRzIHRoZSBjYWxjdWxhdGlvbiBpbnB1dCBmb3IgYSBjb2xsZWN0IG9mIHRoZSBnaXZlbiBwb3NpdGlvbi4KZnVuYyAocyAqc3Rha2VyVjEpIG5ld1Jld2FyZENvbGxlY3RQYXJhbSh0YXJnZXQgKmNvbGxlY3RUYXJnZXQsIGN1cnJlbnRUaW1lLCBibG9ja0hlaWdodCBpbnQ2NCkgKmNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkUGFyYW0gewoJcmV0dXJuICZjYWxjdWxhdGVQb3NpdGlvblJld2FyZFBhcmFtewoJCUN1cnJlbnRIZWlnaHQ6IGJsb2NrSGVpZ2h0LAoJCUN1cnJlbnRUaW1lOiAgIGN1cnJlbnRUaW1lLAoJCURlcG9zaXRzOiAgICAgIHMuZ2V0RGVwb3NpdHMoKSwKCQlQb29sczogICAgICAgICBzLmdldFBvb2xzKCksCgkJUG9vbFRpZXI6ICAgICAgcy5nZXRQb29sVGllcigpLAoJCVBvc2l0aW9uSWQ6ICAgIHRhcmdldC5wb3NpdGlvbklkLAoJCURlcG9zaXQ6ICAgICAgIHRhcmdldC5jaGVja3BvaW50RGVwb3NpdCgpLAoJCUV4aXQ6ICAgICAgICAgIHRhcmdldC5jaGVja3BvaW50LAoJfQp9CgovLyBDb2xsZWN0RW1pc3Npb25SZXdhcmQgaGFydmVzdHMgb25seSB0aGUgR05TIGVtaXNzaW9uIChpbnRlcm5hbCkgcmV3YXJkIGZvciBhIGxpdmUgc3Rha2VkIGRlcG9zaXQKLy8gb3IgYW4gZXhpdCBjaGVja3BvaW50IGxlZnQgYnkgVW5TdGFrZVRva2VuLgovLwovLyBUaGUgZW1pc3Npb24gYW5kIHRoZSBleHRlcm5hbCBpbmNlbnRpdmUgcmV3YXJkcyB0cmFjayB0aGVpciBjb2xsZWN0aW9uIGN1cnNvcnMgaW5kZXBlbmRlbnRseQovLyAoYSBzaW5nbGUgbGFzdENvbGxlY3RUaW1lIG9uIHRoZSBkZXBvc2l0IGZvciBlbWlzc2lvbiwgb25lIHBlciBpbmNlbnRpdmUgaWQgZm9yIGV4dGVybmFsKSwgc28KLy8gY29sbGVjdGluZyBvbmUgc2lkZSBsZWF2ZXMgdGhlIG90aGVyIHNpZGUgZnVsbHkgYWNjcnVhYmxlLgovLwovLyBTdGF0ZSBUcmFuc2l0aW9uOgovLyAgMS4gRW1pc3Npb24gaXMgbWludGVkIGFuZCBkaXN0cmlidXRlZCBzbyB0aGUgc3Rha2VyIGhvbGRzIHRoZSBHTlMgdG8gcGF5IG91dDsgd2hlbiBlbWlzc2lvbiBpcwovLyAgICAgaGFsdGVkLCBjb2xsZWN0aW9uIHJldHVybnMgd2l0aG91dCBjb25zdW1pbmcgdGhlIGFjY3J1ZWQgcmV3YXJkCi8vICAyLiBXYXJtLXVwIHJhdGlvcyBhcmUgYXBwbGllZCBhbmQgdGhlIGVtaXNzaW9uIHJld2FyZCBpcyBzcGxpdCBpbnRvIHVzZXIgLyBwZW5hbHR5IGFtb3VudHMKLy8gIDMuIEdOUyBpcyB0cmFuc2ZlcnJlZCB0byB0aGUgb3duZXIsIHBlbmFsdGllcyBhbmQgdW5jbGFpbWFibGUgYW1vdW50cyB0byB0aGUgY29tbXVuaXR5IHBvb2wKLy8gIDQuIFRoZSBkZXBvc2l0J3MgaW50ZXJuYWwgbGFzdENvbGxlY3RUaW1lIGlzIGFkdmFuY2VkCi8vCi8vIFJlcXVpcmVtZW50czoKLy8gICAtIFdpdGhkcmF3YWxzIG11c3Qgbm90IGJlIGhhbHRlZAovLyAgIC0gQW4gZW1pc3Npb24gaGFsdCByZXR1cm5zIHplcm8gd2l0aG91dCBhZHZhbmNpbmcgaW50ZXJuYWwgcmV3YXJkIHN0YXRlCi8vICAgLSBDYWxsZXIgbXVzdCBiZSB0aGUgcG9zaXRpb24gb3duZXIgZm9yIGEgbGl2ZSBkZXBvc2l0OyBjaGVja3BvaW50IGNvbGxlY3Rpb24gaXMgcGVybWlzc2lvbmxlc3MKLy8gICAtIFBvc2l0aW9uIG11c3QgYmUgc3Rha2VkIG9yIGhhdmUgYW4gZXhpdCBjaGVja3BvaW50Ci8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBfOiBOb25jcm9zc2luZyBpbXBsZW1lbnRhdGlvbi1jYWxsIGRpc2NyaW1pbmF0b3I7IHBhc3MgMC4KLy8gICAtIHJsbTogQ3VycmVudCByZWFsbSBjb250ZXh0IGZvcndhcmRlZCB1bmNoYW5nZWQgYnkgdGhlIHN0YWtlciBwcm94eS4KLy8gICAtIHBvc2l0aW9uSWQ6IExQIHBvc2l0aW9uIE5GVCB0b2tlbiBJRCBvciBwb3NpdGlvbiB3aXRoIGFuIGV4aXQgY2hlY2twb2ludC4KLy8KLy8gUmV0dXJuczoKLy8gICAtIHJld2FyZFRvVXNlcjogR05TIGVtaXNzaW9uIGFtb3VudCBzZW50IHRvIHRoZSBwb3NpdGlvbiBvd25lciwgaW4gdG9rZW4gc21hbGxlc3QgdW5pdHMuCi8vICAgLSByZXdhcmRQZW5hbHR5OiBHTlMgd2FybXVwIHBlbmFsdHkgc2VudCB0byB0aGUgY29tbXVuaXR5IHBvb2wsIGluIHRva2VuIHNtYWxsZXN0IHVuaXRzLgpmdW5jIChzICpzdGFrZXJWMSkgQ29sbGVjdEVtaXNzaW9uUmV3YXJkKF8gaW50LCBybG0gcmVhbG0sIHBvc2l0aW9uSWQgdWludDY0KSAoaW50NjQsIGludDY0KSB7CglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCgloYWx0LkFzc2VydElzTm90SGFsdGVkV2l0aGRyYXcoKQoKCXRhcmdldCA6PSBzLnJlc29sdmVDb2xsZWN0VGFyZ2V0KHBvc2l0aW9uSWQsIHJsbS5QcmV2aW91cygpLkFkZHJlc3MoKSkKCglfLCBlbWlzc2lvbkFjdGl2ZSA6PSBlbi5NaW50QW5kRGlzdHJpYnV0ZUducyhjcm9zcyhybG0pKQoKCWN1cnJlbnRUaW1lIDo9IHRhcmdldC5jdXJyZW50VGltZQoJYmxvY2tIZWlnaHQgOj0gcnVudGltZS5DaGFpbkhlaWdodCgpCglyZXdhcmRQYXJhbSA6PSBzLm5ld1Jld2FyZENvbGxlY3RQYXJhbSh0YXJnZXQsIGN1cnJlbnRUaW1lLCBibG9ja0hlaWdodCkKCglpZiAhZW1pc3Npb25BY3RpdmUgewoJCS8vIERlZmVycmVkOiB0aGUgYWNjcnVlZCByZXdhcmQgc3RheXMgb24gdGhlIGN1cnNvciB1bnRpbCBlbWlzc2lvbiByZXN1bWVzLiBBIGNoZWNrcG9pbnQgdGhhdAoJCS8vIG93ZXMgbm8gZW1pc3Npb24gaXMgc3RpbGwgc2V0dGxlZCBzbyB0aGUgaGFsdCBkb2VzIG5vdCBibG9jayByZS1zdGFraW5nLgoJCXMuc2V0dGxlSGFsdGVkRW1pc3Npb24oMCwgcmxtLCB0YXJnZXQsIHJld2FyZFBhcmFtKQoKCQlyZXR1cm4gMCwgMAoJfQoKCS8vIENhbGN1bGF0aW9uIGlzIHJlYWQtb25seTsgdGhlIHJlc3VsdGluZyBzdGF0ZSB1cGRhdGVzIChyZXdhcmQtY2FjaGUgdXBkYXRlLCBsYXp5IHBvb2wgcGVyc2lzdGVuY2UpCgkvLyBhcmUgYXBwbGllZCB2aWEgdXBkYXRlSW50ZXJuYWxQb3NpdGlvblJld2FyZCwgd2hpY2ggaXMgdGhlIGNvbGxlY3Qtb25seSBjb3VudGVycGFydCB0byB0aGUKCS8vIGNhbGN1bGF0aW9uIHNoYXJlZCB3aXRoIHRoZSBDb2xsZWN0YWJsZSogdmlldyBnZXR0ZXJzLgoJcmV3YXJkcywgcmV3YXJkVXBkYXRlLCBlcnIgOj0gcy5jYWxjdWxhdGVJbnRlcm5hbFBvc2l0aW9uUmV3YXJkKHJld2FyZFBhcmFtKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoJcmV3YXJkIDo9IGFnZ3JlZ2F0ZVJld2FyZHMocmV3YXJkcykKCXMudXBkYXRlSW50ZXJuYWxQb3NpdGlvblJld2FyZChyZXdhcmRQYXJhbSwgcmV3YXJkVXBkYXRlKQoKCWN0eCA6PSBzLm5ld0NvbGxlY3RDb250ZXh0KDAsIHJsbSwgdGFyZ2V0LCBjdXJyZW50VGltZSwgYmxvY2tIZWlnaHQpCgoJcmV3YXJkVG9Vc2VyLCByZXdhcmRQZW5hbHR5IDo9IHMuZGVsaXZlckVtaXNzaW9uUmV3YXJkKDAsIHJsbSwgY3R4LCByZXdhcmQpCgoJcy5tYXJrRW1pc3Npb25Db2xsZWN0ZWQoMCwgcmxtLCB0YXJnZXQpCgoJcmV0dXJuIHJld2FyZFRvVXNlciwgcmV3YXJkUGVuYWx0eQp9CgovLyBDb2xsZWN0RXh0ZXJuYWxJbmNlbnRpdmVSZXdhcmQgaGFydmVzdHMgb25lIGV4dGVybmFsIGluY2VudGl2ZSByZXdhcmQgZm9yIGEgbGl2ZSBzdGFrZWQgZGVwb3NpdAovLyBvciBhbiBleGl0IGNoZWNrcG9pbnQgbGVmdCBieSBVblN0YWtlVG9rZW4uCi8vCi8vIEVhY2ggaW5jZW50aXZlIGtlZXBzIGl0cyBvd24gbGFzdENvbGxlY3RUaW1lLCBzbyB0aGUgZW1pc3Npb24gcmV3YXJkIGFuZCBldmVyeSBpbmNlbnRpdmUgb3RoZXIgdGhhbgovLyB0aGUgcmVxdWVzdGVkIG9uZSBzdGF5IGNvbGxlY3RpYmxlIGFmdGVyd2FyZHMuIEZvciBhIGxpdmUgZGVwb3NpdCwgYSBub3Qtc3RhcnRlZCwgemVyby1yZXdhcmQsIG9yCi8vIHJld2FyZC10b2tlbi1iYWxhbmNlLXNob3J0IGluY2VudGl2ZSByZW1haW5zIGNvbGxlY3RpYmxlIGJlY2F1c2UgaXRzIGN1cnNvciBpcyBub3QgYWR2YW5jZWQuIEZvcgovLyBhbiBleGl0IGNoZWNrcG9pbnQsIGFuIGluY2VudGl2ZS1iYWxhbmNlIHNob3J0ZmFsbCBpcyBmb3JmZWl0ZWQgdG8gcmVsZWFzZSB0aGUgY2hlY2twb2ludCByYXRoZXIKLy8gdGhhbiBsZWZ0IGFzIGFuIHVucGF5YWJsZSBjbGFpbS4KLy8KLy8gU3RhdGUgVHJhbnNpdGlvbjoKLy8gIDEuIEluY2VudGl2ZXMgY3JlYXRlZCBzaW5jZSB0aGUgZGVwb3NpdCdzIGxhc3QgdXBkYXRlIGFyZSBhZGRlZCB0byBpdHMgaW5jZW50aXZlIGluZGV4Ci8vICAyLiBXYXJtLXVwIHJhdGlvcyBhcmUgYXBwbGllZCBhbmQgdGhlIHJld2FyZCBpcyBzcGxpdCBpbnRvIHVzZXIgLyBwZW5hbHR5IGFtb3VudHMKLy8gIDMuIFRoZSByZXdhcmQgdG9rZW4gaXMgdHJhbnNmZXJyZWQgdG8gdGhlIG93bmVyLCB0aGUgcGVuYWx0eSBhY2N1bXVsYXRlcyBvbiB0aGUgaW5jZW50aXZlCi8vICA0LiBUaGUgY29sbGVjdGVkIGluY2VudGl2ZSdzIGxhc3RDb2xsZWN0VGltZSBpcyBhZHZhbmNlZAovLwovLyBSZXF1aXJlbWVudHM6Ci8vICAgLSBDb250cmFjdCBtdXN0IG5vdCBiZSBoYWx0ZWQKLy8gICAtIENhbGxlciBtdXN0IGJlIHRoZSBwb3NpdGlvbiBvd25lciBmb3IgYSBsaXZlIGRlcG9zaXQ7IGNoZWNrcG9pbnQgY29sbGVjdGlvbiBpcyBwZXJtaXNzaW9ubGVzcwovLyAgIC0gUG9zaXRpb24gbXVzdCBiZSBzdGFrZWQgb3IgaGF2ZSBhbiBleGl0IGNoZWNrcG9pbnQKLy8gICAtIEluY2VudGl2ZSBtdXN0IGV4aXN0IGFuZCB0YXJnZXQgdGhlIHBvb2wgdGhlIHBvc2l0aW9uIGlzIHN0YWtlZCBpbgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgdW5jaGFuZ2VkIGJ5IHRoZSBzdGFrZXIgcHJveHkuCi8vICAgLSBwb3NpdGlvbklkOiBMUCBwb3NpdGlvbiBORlQgdG9rZW4gSUQgb3IgcG9zaXRpb24gd2l0aCBhbiBleGl0IGNoZWNrcG9pbnQuCi8vICAgLSBpbmNlbnRpdmVJZDogRXh0ZXJuYWwgaW5jZW50aXZlIHRvIGNvbGxlY3QuCi8vCi8vIFJldHVybnM6Ci8vICAgLSByZXdhcmRBbW91bnQ6IEdyb3NzIGV4dGVybmFsIHJld2FyZCBhbW91bnQgZGVsaXZlcmVkIGJlZm9yZSB0aGUgc3Rha2luZyByZXdhcmQgZmVlLCBpbiB0b2tlbiBzbWFsbGVzdCB1bml0cy4KLy8gICAtIHJld2FyZFBlbmFsdHk6IEV4dGVybmFsIHdhcm11cCBwZW5hbHR5IHJldGFpbmVkIGJ5IHRoZSBpbmNlbnRpdmUsIGluIHRva2VuIHNtYWxsZXN0IHVuaXRzLgpmdW5jIChzICpzdGFrZXJWMSkgQ29sbGVjdEV4dGVybmFsSW5jZW50aXZlUmV3YXJkKF8gaW50LCBybG0gcmVhbG0sIHBvc2l0aW9uSWQgdWludDY0LCBpbmNlbnRpdmVJZCBzdHJpbmcpIChpbnQ2NCwgaW50NjQpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRXaXRoZHJhdygpCgoJdGFyZ2V0IDo9IHMucmVzb2x2ZUNvbGxlY3RUYXJnZXQocG9zaXRpb25JZCwgcmxtLlByZXZpb3VzKCkuQWRkcmVzcygpKQoJYXNzZXJ0SXNJbmNlbnRpdmVPZlBvb2wocywgdGFyZ2V0LmRlcG9zaXQuVGFyZ2V0UG9vbFBhdGgoKSwgcG9zaXRpb25JZCwgaW5jZW50aXZlSWQpCgoJY3VycmVudFRpbWUgOj0gdGFyZ2V0LmN1cnJlbnRUaW1lCglibG9ja0hlaWdodCA6PSBydW50aW1lLkNoYWluSGVpZ2h0KCkKCgkvLyBDYWxjdWxhdGlvbiBpcyByZWFkLW9ubHk7IHRoZSByZXN1bHRpbmcgc3RhdGUgdXBkYXRlcyAobGF6eSBwb29sIHBlcnNpc3RlbmNlLCBkZXBvc2l0CgkvLyBpbmNlbnRpdmUtaW5kZXggdXBkYXRlcykgYXJlIGFwcGxpZWQgdmlhIHVwZGF0ZUV4dGVybmFsUG9zaXRpb25SZXdhcmQsIHdoaWNoIGlzIHRoZSBjb2xsZWN0LW9ubHkKCS8vIGNvdW50ZXJwYXJ0IHRvIHRoZSBjYWxjdWxhdGlvbiBzaGFyZWQgd2l0aCB0aGUgQ29sbGVjdGFibGUqIHZpZXcgZ2V0dGVycy4KCXJld2FyZFBhcmFtIDo9IHMubmV3UmV3YXJkQ29sbGVjdFBhcmFtKHRhcmdldCwgY3VycmVudFRpbWUsIGJsb2NrSGVpZ2h0KQoJcmV3YXJkcywgcmV3YXJkVXBkYXRlIDo9IHMuY2FsY3VsYXRlRXh0ZXJuYWxQb3NpdGlvblJld2FyZChyZXdhcmRQYXJhbSwgaW5jZW50aXZlSWQpCglyZXdhcmQgOj0gYWdncmVnYXRlUmV3YXJkcyhyZXdhcmRzKQoJcy51cGRhdGVFeHRlcm5hbFBvc2l0aW9uUmV3YXJkKHJld2FyZFBhcmFtLCByZXdhcmRVcGRhdGUpCgoJY3R4IDo9IHMubmV3Q29sbGVjdENvbnRleHQoMCwgcmxtLCB0YXJnZXQsIGN1cnJlbnRUaW1lLCBibG9ja0hlaWdodCkKCglfLCByZXdhcmRBbW91bnQsIHJld2FyZFBlbmFsdHksIG91dGNvbWUgOj0gcy5kZWxpdmVyRXh0ZXJuYWxJbmNlbnRpdmVSZXdhcmQoCgkJMCwgcmxtLCBjdHgsIGluY2VudGl2ZUlkLCByZXdhcmQuRXh0ZXJuYWxbaW5jZW50aXZlSWRdLCByZXdhcmQuRXh0ZXJuYWxQZW5hbHR5W2luY2VudGl2ZUlkXSwKCSkKCgkvLyBQZXJzaXN0IHRoZSBkZXBvc2l0IGV2ZW4gd2hlbiBub3RoaW5nIHdhcyBkZWxpdmVyZWQ6IHRoZSBpbmNlbnRpdmUtaW5kZXggdXBkYXRlIGFib3ZlIHN0aWxsIHJhbi4KCWN0eC5wZXJzaXN0RGVwb3NpdChzKQoKCXMubWFya0luY2VudGl2ZUNvbGxlY3RlZCgwLCBybG0sIHRhcmdldCwgaW5jZW50aXZlSWQsIHJld2FyZC5FeHRlcm5hbFtpbmNlbnRpdmVJZF0sIHJld2FyZC5FeHRlcm5hbFBlbmFsdHlbaW5jZW50aXZlSWRdLCBvdXRjb21lKQoKCXJldHVybiByZXdhcmRBbW91bnQsIHJld2FyZFBlbmFsdHkKfQoKLy8gQ29sbGVjdFJld2FyZCBoYXJ2ZXN0cyBhY2N1bXVsYXRlZCByZXdhcmRzIGZvciBhIGxpdmUgc3Rha2VkIGRlcG9zaXQgb3IgYW4gZXhpdCBjaGVja3BvaW50IGxlZnQKLy8gYnkgVW5TdGFrZVRva2VuLiBUaGlzIGluY2x1ZGVzIGJvdGggaW50ZXJuYWwgR05TIGVtaXNzaW9uIGFuZCBleHRlcm5hbCBpbmNlbnRpdmUgcmV3YXJkcy4KLy8KLy8gSXQgaXMgdGhlICJjb2xsZWN0IGV2ZXJ5dGhpbmciIGVudHJ5IHBvaW50IGtlcHQgZm9yIGNhbGxlcnMgdGhhdCBkbyBub3Qgd2FudCB0byBjaG9vc2UgYSBzaWRlLiBJdAovLyBkZWxpdmVycyBlYWNoIGluY2VudGl2ZSwgdGhlbiB0aGUgZW1pc3Npb24gcmV3YXJkLCB0aHJvdWdoIHRoZSBzYW1lIGRlbGl2ZXJ5IGZ1bmN0aW9ucyB0aGUKLy8gc2luZ2xlLXNvdXJjZSBlbnRyeSBwb2ludHMgdXNlLiBEdXJpbmcgYW4gZW1pc3Npb24gaGFsdCwgaXQgc2tpcHMgaW50ZXJuYWwgY2FsY3VsYXRpb24sIHN0YXRlIHVwZGF0ZXMsCi8vIGFuZCBkZWxpdmVyeSB3aGlsZSBjb250aW51aW5nIHRvIHNldHRsZSBleHRlcm5hbCBpbmNlbnRpdmVzLgovLwovLyBSZXF1aXJlbWVudHM6Ci8vICAgLSBXaXRoZHJhd2FscyBtdXN0IG5vdCBiZSBoYWx0ZWQKLy8gICAtIENhbGxlciBtdXN0IGJlIHRoZSBwb3NpdGlvbiBvd25lciBmb3IgYSBsaXZlIGRlcG9zaXQ7IGNoZWNrcG9pbnQgY29sbGVjdGlvbiBpcyBwZXJtaXNzaW9ubGVzcwovLyAgIC0gUG9zaXRpb24gbXVzdCBiZSBzdGFrZWQgb3IgaGF2ZSBhbiBleGl0IGNoZWNrcG9pbnQKLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIF86IE5vbmNyb3NzaW5nIGltcGxlbWVudGF0aW9uLWNhbGwgZGlzY3JpbWluYXRvcjsgcGFzcyAwLgovLyAgIC0gcmxtOiBDdXJyZW50IHJlYWxtIGNvbnRleHQgZm9yd2FyZGVkIHVuY2hhbmdlZCBieSB0aGUgc3Rha2VyIHByb3h5LgovLyAgIC0gcG9zaXRpb25JZDogTFAgcG9zaXRpb24gTkZUIHRva2VuIElEIG9yIHBvc2l0aW9uIHdpdGggYW4gZXhpdCBjaGVja3BvaW50LgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50ZXJuYWxSZXdhcmRUb1VzZXI6IEdOUyBlbWlzc2lvbiBhbW91bnQgc2VudCB0byB0aGUgb3duZXIsIGZvcm1hdHRlZCBhcyBhIGRlY2ltYWwgc3RyaW5nLgovLyAgIC0gaW50ZXJuYWxSZXdhcmRQZW5hbHR5OiBHTlMgd2FybXVwIHBlbmFsdHkgc2VudCB0byB0aGUgY29tbXVuaXR5IHBvb2wsIGZvcm1hdHRlZCBhcyBhIGRlY2ltYWwgc3RyaW5nLgovLyAgIC0gZXh0ZXJuYWxSZXdhcmRzOiBNYXAgZnJvbSByZXdhcmQtdG9rZW4gcGF0aCB0byBncm9zcyBleHRlcm5hbCByZXdhcmQgYW1vdW50cyBiZWZvcmUgc3Rha2luZyBmZWVzLgovLyAgIC0gZXh0ZXJuYWxQZW5hbHRpZXM6IE1hcCBmcm9tIHJld2FyZC10b2tlbiBwYXRoIHRvIGV4dGVybmFsIHdhcm11cCBwZW5hbHR5IGFtb3VudHMuCmZ1bmMgKHMgKnN0YWtlclYxKSBDb2xsZWN0UmV3YXJkKF8gaW50LCBybG0gcmVhbG0sIHBvc2l0aW9uSWQgdWludDY0KSAoc3RyaW5nLCBzdHJpbmcsIG1hcFtzdHJpbmddaW50NjQsIG1hcFtzdHJpbmddaW50NjQpIHsKCWFjY2Vzcy5Bc3NlcnRJc1JsbUN1cnJlbnQoMCwgcmxtKQoKCWhhbHQuQXNzZXJ0SXNOb3RIYWx0ZWRXaXRoZHJhdygpCgoJdGFyZ2V0IDo9IHMucmVzb2x2ZUNvbGxlY3RUYXJnZXQocG9zaXRpb25JZCwgcmxtLlByZXZpb3VzKCkuQWRkcmVzcygpKQoKCV8sIGVtaXNzaW9uQWN0aXZlIDo9IGVuLk1pbnRBbmREaXN0cmlidXRlR25zKGNyb3NzKHJsbSkpCgoJY3VycmVudFRpbWUgOj0gdGFyZ2V0LmN1cnJlbnRUaW1lCglibG9ja0hlaWdodCA6PSBydW50aW1lLkNoYWluSGVpZ2h0KCkKCXJld2FyZFBhcmFtIDo9IHMubmV3UmV3YXJkQ29sbGVjdFBhcmFtKHRhcmdldCwgY3VycmVudFRpbWUsIGJsb2NrSGVpZ2h0KQoKCXZhciAoCgkJcmV3YXJkcyAgICAgIFtdUmV3YXJkCgkJcmV3YXJkVXBkYXRlIHBvc2l0aW9uUmV3YXJkVXBkYXRlCgkpCgoJaWYgZW1pc3Npb25BY3RpdmUgewoJCXZhciBlcnIgZXJyb3IKCgkJcmV3YXJkcywgcmV3YXJkVXBkYXRlLCBlcnIgPSBzLmNhbGN1bGF0ZVBvc2l0aW9uUmV3YXJkKHJld2FyZFBhcmFtKQoJCWlmIGVyciAhPSBuaWwgewoJCQlwYW5pYyhlcnIpCgkJfQoJCXMudXBkYXRlUG9zaXRpb25SZXdhcmQocmV3YXJkUGFyYW0sIHJld2FyZFVwZGF0ZSkKCX0gZWxzZSB7CgkJcmV3YXJkcywgcmV3YXJkVXBkYXRlID0gcy5jYWxjdWxhdGVFeHRlcm5hbFBvc2l0aW9uUmV3YXJkcyhyZXdhcmRQYXJhbSkKCQlzLnVwZGF0ZUV4dGVybmFsUG9zaXRpb25SZXdhcmQocmV3YXJkUGFyYW0sIHJld2FyZFVwZGF0ZSkKCX0KCglyZXdhcmQgOj0gYWdncmVnYXRlUmV3YXJkcyhyZXdhcmRzKQoKCWN0eCA6PSBzLm5ld0NvbGxlY3RDb250ZXh0KDAsIHJsbSwgdGFyZ2V0LCBjdXJyZW50VGltZSwgYmxvY2tIZWlnaHQpCgoJLy8gRXh0ZXJuYWwgcmV3YXJkcyBhcmUgZGVsaXZlcmVkIGZpcnN0LCB0aGUgb3JkZXIgdGhlIHR3byByZXdhcmQgcGF0aHMgcmFuIGluIGJlZm9yZSB0aGV5IHdlcmUgc3BsaXQuCgl0b1VzZXJFeHRlcm5hbFJld2FyZCA6PSBtYWtlKG1hcFtzdHJpbmddaW50NjQpCgl0b1VzZXJFeHRlcm5hbFBlbmFsdHkgOj0gbWFrZShtYXBbc3RyaW5nXWludDY0KQoKCWZvciBfLCBpbmNlbnRpdmVJZCA6PSByYW5nZSByZXdhcmRVcGRhdGUuZXh0ZXJuYWxJbmNlbnRpdmVJZHMgewoJCXJld2FyZFRva2VuLCByZXdhcmRBbW91bnQsIHJld2FyZFBlbmFsdHksIG91dGNvbWUgOj0gcy5kZWxpdmVyRXh0ZXJuYWxJbmNlbnRpdmVSZXdhcmQoCgkJCTAsIHJsbSwgY3R4LCBpbmNlbnRpdmVJZCwgcmV3YXJkLkV4dGVybmFsW2luY2VudGl2ZUlkXSwgcmV3YXJkLkV4dGVybmFsUGVuYWx0eVtpbmNlbnRpdmVJZF0sCgkJKQoKCQlzLm1hcmtJbmNlbnRpdmVDb2xsZWN0ZWQoMCwgcmxtLCB0YXJnZXQsIGluY2VudGl2ZUlkLCByZXdhcmQuRXh0ZXJuYWxbaW5jZW50aXZlSWRdLCByZXdhcmQuRXh0ZXJuYWxQZW5hbHR5W2luY2VudGl2ZUlkXSwgb3V0Y29tZSkKCgkJLy8gQW4gZW1wdHkgcmV3YXJkIHRva2VuIG1lYW5zIHRoZSBpbmNlbnRpdmUgZGVsaXZlcmVkIG5vdGhpbmcgYW5kIHN0YXlzIGNvbGxlY3RpYmxlLgoJCWlmIHJld2FyZFRva2VuID09ICIiIHsKCQkJY29udGludWUKCQl9CgoJCXRvVXNlckV4dGVybmFsUmV3YXJkW3Jld2FyZFRva2VuXSA9IGduc21hdGguU2FmZUFkZEludDY0KHRvVXNlckV4dGVybmFsUmV3YXJkW3Jld2FyZFRva2VuXSwgcmV3YXJkQW1vdW50KQoJCXRvVXNlckV4dGVybmFsUGVuYWx0eVtyZXdhcmRUb2tlbl0gPSBnbnNtYXRoLlNhZmVBZGRJbnQ2NCh0b1VzZXJFeHRlcm5hbFBlbmFsdHlbcmV3YXJkVG9rZW5dLCByZXdhcmRQZW5hbHR5KQoJfQoKCWludGVybmFsUmV3YXJkVG9Vc2VyIDo9IGludDY0KDApCglpbnRlcm5hbFJld2FyZFBlbmFsdHkgOj0gaW50NjQoMCkKCglpZiBlbWlzc2lvbkFjdGl2ZSB7CgkJaW50ZXJuYWxSZXdhcmRUb1VzZXIsIGludGVybmFsUmV3YXJkUGVuYWx0eSA9IHMuZGVsaXZlckVtaXNzaW9uUmV3YXJkKDAsIHJsbSwgY3R4LCByZXdhcmQpCgkJcy5tYXJrRW1pc3Npb25Db2xsZWN0ZWQoMCwgcmxtLCB0YXJnZXQpCgl9IGVsc2UgewoJCXMuc2V0dGxlSGFsdGVkRW1pc3Npb24oMCwgcmxtLCB0YXJnZXQsIHJld2FyZFBhcmFtKQoKCQkvLyBUaGUgaGFsdGVkIHBhdGggZG9lcyBub3QgcmVhY2ggZGVsaXZlckVtaXNzaW9uUmV3YXJkLCB3aGljaCBpcyB3aGVyZSB0aGUgbGl2ZSBkZXBvc2l0J3MKCQkvLyBpbmNlbnRpdmUtaW5kZXggYW5kIGN1cnNvciB1cGRhdGVzIHdlcmUgd3JpdHRlbiBiYWNrLiBBIGNoZWNrcG9pbnQgaXMgbm90IGluIHRoZSB0cmVlLCBzbwoJCS8vIHRoaXMgaXMgYSBuby1vcCBmb3IgaXQuCgkJY3R4LnBlcnNpc3REZXBvc2l0KHMpCgl9CgoJcmV0dXJuIHV0aWxzLkZvcm1hdEludChpbnRlcm5hbFJld2FyZFRvVXNlciksIHV0aWxzLkZvcm1hdEludChpbnRlcm5hbFJld2FyZFBlbmFsdHkpLCB0b1VzZXJFeHRlcm5hbFJld2FyZCwgdG9Vc2VyRXh0ZXJuYWxQZW5hbHR5Cn0KCi8vIGRlbGl2ZXJFeHRlcm5hbEluY2VudGl2ZVJld2FyZCBwYXlzIG91dCBvbmUgaW5jZW50aXZlJ3MgYWxyZWFkeS1jYWxjdWxhdGVkIHJld2FyZDogaXQgZGViaXRzIHRoZQovLyBpbmNlbnRpdmUsIGFkdmFuY2VzIGl0cyBsYXN0Q29sbGVjdFRpbWUsIHRha2VzIHRoZSBzdGFraW5nIHJld2FyZCBmZWUgYW5kIHRyYW5zZmVycyB0aGUgcmVzdC4KLy8KLy8gVGhlIGluY2VudGl2ZSBpcyBza2lwcGVkIFdJVEhPVVQgYWR2YW5jaW5nIGl0cyBsYXN0Q29sbGVjdFRpbWUgd2hlbiBpdCB5aWVsZHMgbm8gdXNlciByZXdhcmQgb3IgZG9lcwovLyBub3QgaG9sZCBlbm91Z2ggcmV3YXJkIHRva2VuLCBzbyB0aGUgYW1vdW50IHN0YXlzIGNvbGxlY3RpYmxlIGxhdGVyLiBBIHNraXBwZWQgaW5jZW50aXZlIGlzIHJlcG9ydGVkCi8vIGJ5IGFuIGVtcHR5IHJld2FyZCB0b2tlbiwgYW5kIHRoZSBvdXRjb21lIHNheXMgd2h5LCBzbyBhIGNoZWNrcG9pbnQgY2FuIHRlbGwgYSBkZWZlcnJhbCBmcm9tIGEgZGVidAovLyBpdCB3aWxsIG5ldmVyIGJlIGFibGUgdG8gcGF5LgovLwovLyBBIHdhcm11cCByYXRpbyBiZWxvdyAxMDAlIGZsb29ycyB0aGUgdXNlciByZXdhcmQsIHNvIGEgc21hbGwgYWNjcnVhbCBjYW4geWllbGQgcmV3YXJkQW1vdW50ID09IDAgd2hpbGUKLy8gZXh0ZXJuYWxQZW5hbHR5ID4gMC4gU3VjaCBhIGNhbGwgaXMgc2tpcHBlZCBhcyBhIHdob2xlOiB0aGUgcGVuYWx0eSBpcyBOT1QgYm9va2VkIGFuZCB0aGUgY3Vyc29yIGlzIE5PVAovLyBhZHZhbmNlZCwgd2hpY2ggbGVhdmVzIHRoZSB1bnRvdWNoZWQgYWNjcnVhbCB0byBiZSByZWNhbGN1bGF0ZWQgb3ZlciB0aGUgd2lkZXIgd2luZG93IG9mIHRoZSBuZXh0Ci8vIGNvbGxlY3QuIE5vdGhpbmcgaXMgbG9zdCBlaXRoZXIgd2F5LCBiZWNhdXNlIGFuIHVuYm9va2VkIHBlbmFsdHkgc3RheXMgaW4gdGhlIGluY2VudGl2ZSdzIHJld2FyZAovLyBhbW91bnQsIGFuZCBlbmRFeHRlcm5hbEluY2VudGl2ZSByZWZ1bmRzIHRoZSByZXdhcmQgYW1vdW50IGFuZCB0aGUgYWNjdW11bGF0ZWQgcGVuYWx0eSB0byB0aGUgc2FtZQovLyBhZGRyZXNzLgovLwovLyBSZXR1cm5zIHRoZSByZXdhcmQgdG9rZW4sIHRoZSBjb2xsZWN0ZWQgcmV3YXJkIGFtb3VudCBiZWZvcmUgdGhlIHN0YWtpbmcgcmV3YXJkIGZlZSwgdGhlIHBlbmFsdHksCi8vIGFuZCB0aGUgZGVsaXZlcnkgb3V0Y29tZS4KZnVuYyAocyAqc3Rha2VyVjEpIGRlbGl2ZXJFeHRlcm5hbEluY2VudGl2ZVJld2FyZCgKCV8gaW50LAoJcmxtIHJlYWxtLAoJY3R4ICpjb2xsZWN0Q29udGV4dCwKCWluY2VudGl2ZUlkIHN0cmluZywKCXJld2FyZEFtb3VudCBpbnQ2NCwKCWV4dGVybmFsUGVuYWx0eSBpbnQ2NCwKKSAoc3RyaW5nLCBpbnQ2NCwgaW50NjQsIGV4dGVybmFsRGVsaXZlcnlPdXRjb21lKSB7CgkvLyBBIGNoZWNrcG9pbnQncyB3aW5kb3cgY2xvc2VzIGF0IGN0eC5jdXJyZW50VGltZSwgc28gYSBjdXJzb3IgYWxyZWFkeSB0aGVyZSBtZWFucyB0aGlzCgkvLyBpbmNlbnRpdmUgd2FzIGRlbGl2ZXJlZC4gVGhlIGNoZWNrcG9pbnQgZW50cnkgcG9pbnRzIGFyZSBwZXJtaXNzaW9ubGVzcywgYW5kIHJld2FyZEFtb3VudAoJLy8gd2FzIGNvbXB1dGVkIGJlZm9yZSB0aGUgZGVsaXZlcmllcyByYW46IHdpdGhvdXQgdGhpcywgYSByZWVudHJhbnQgY29sbGVjdCBiZXR3ZWVuIHRoZW0KCS8vIHdvdWxkIGxldCB0aGUgc3RhbGUgYW1vdW50IGJlIHBhaWQgYSBzZWNvbmQgdGltZS4KCWlmIGN0eC5jaGVja3BvaW50ICE9IG5pbCAmJiBjdHguZGVwb3NpdFJlc29sdmVyLkV4dGVybmFsUmV3YXJkTGFzdENvbGxlY3RUaW1lKGluY2VudGl2ZUlkKSA+PSBjdHguY3VycmVudFRpbWUgewoJCXJldHVybiAiIiwgMCwgMCwgZXh0ZXJuYWxEZWxpdmVyeUFscmVhZHlEZWxpdmVyZWQKCX0KCgkvLyBTa2lwIHdoZW4gdXNlciByZXdhcmQgaXMgemVyby4KCS8vIERvIG5vdCB1cGRhdGUgbGFzdCBjb2xsZWN0IHRpbWUgc28gdGhlIHJld2FyZCBhY2NydWVzIHVudGlsCgkvLyB0aGUgbmV4dCBjb2xsZWN0aW9uIHdoZXJlIGEgbm9uLXplcm8gYW1vdW50IGNhbiBiZSBkZWxpdmVyZWQuCgkvLwoJLy8gQW4gZXhpdCBjaGVja3BvaW50IGhhcyBubyBuZXh0IGNvbGxlY3Rpb246IGl0IHN0b3BwZWQgYWNjcnVpbmcsIHNvIGEgcGVuYWx0eSBsZWZ0IGhlcmUKCS8vIHdvdWxkIG5ldmVyIGJlIGJvb2tlZCBhbmQgd291bGQgYmUgZHJvcHBlZCB3aXRoIHRoZSBjaGVja3BvaW50LgoJaWYgcmV3YXJkQW1vdW50ID09IDAgJiYgKGN0eC5jaGVja3BvaW50ID09IG5pbCB8fCBleHRlcm5hbFBlbmFsdHkgPT0gMCkgewoJCWlmIGV4dGVybmFsUGVuYWx0eSA9PSAwIHsKCQkJcmV0dXJuICIiLCAwLCAwLCBleHRlcm5hbERlbGl2ZXJ5Tm90aGluZ093ZWQKCQl9CgoJCXJldHVybiAiIiwgMCwgMCwgZXh0ZXJuYWxEZWxpdmVyeURlZmVycmVkCgl9CgoJLy8gZ2V0IHBhbmljcyBvbiBhIG1pc3NpbmcgaWQ7IGluY2VudGl2ZXMgYXJlIG5ldmVyIHJlbW92ZWQgZnJvbSB0aGUgdHJlZS4KCWluY2VudGl2ZSA6PSBzLmdldEV4dGVybmFsSW5jZW50aXZlcygpLmdldChpbmNlbnRpdmVJZCkKCglpbmNlbnRpdmVSZXNvbHZlciA6PSBOZXdFeHRlcm5hbEluY2VudGl2ZVJlc29sdmVyKGluY2VudGl2ZSkKCgkvLyBEZWZlbnNpdmUgYmFja3N0b3AsIHVucmVhY2hhYmxlIHRocm91Z2ggdGhlIGN1cnJlbnQgY2FsbGVyczogY29tcHV0ZUV4dGVybmFsUmV3YXJkIGFscmVhZHkgZHJvcHMgYQoJLy8gbm90LXlldC1zdGFydGVkIGluY2VudGl2ZSBhdCB0aGUgc2FtZSBjdXJyZW50VGltZSwgc28gaXRzIHJld2FyZCBpcyB6ZXJvIGFuZCB0aGUgY2hlY2sgYWJvdmUKCS8vIHJldHVybnMgZmlyc3QuIEtlcHQgc28gYSBmdXR1cmUgY2FsbGVyIHRoYXQgc3VwcGxpZXMgYSBub24temVybyBhbW91bnQgY2Fubm90IHBheSBvdXQgb2YgYW4KCS8vIGluY2VudGl2ZSB3aG9zZSBkaXN0cmlidXRpb24gd2luZG93IGhhcyBub3Qgb3BlbmVkLgoJaWYgIWluY2VudGl2ZVJlc29sdmVyLklzU3RhcnRlZChjdHguY3VycmVudFRpbWUpIHsKCQlyZXR1cm4gIiIsIDAsIDAsIGV4dGVybmFsRGVsaXZlcnlEZWZlcnJlZAoJfQoKCXRvdGFsUmV3YXJkQW1vdW50IDo9IGduc21hdGguU2FmZUFkZEludDY0KHJld2FyZEFtb3VudCwgZXh0ZXJuYWxQZW5hbHR5KQoKCWlmIGluY2VudGl2ZVJlc29sdmVyLlJld2FyZEFtb3VudCgpIDwgdG90YWxSZXdhcmRBbW91bnQgewoJCS8vIERvIG5vdCB1cGRhdGUgbGFzdCBjb2xsZWN0IHRpbWUgaGVyZTsgaW5zdWZmaWNpZW50IGZ1bmRzIHNob3VsZAoJCS8vIGxlYXZlIHRoZSBpbmNlbnRpdmUgY29sbGVjdGlibGUgd2hlbiByZWZpbGxlZCBvciBjb3JyZWN0ZWQuCgkJY2hhaW4uRW1pdCgKCQkJIkluc3VmZmljaWVudEV4dGVybmFsUmV3YXJkIiwKCQkJInByZXZBZGRyIiwgY3R4LnByZXZBZGRyLAoJCQkicHJldlJlYWxtIiwgY3R4LnByZXZSZWFsbSwKCQkJInBvc2l0aW9uSWQiLCB1dGlscy5Gb3JtYXRVaW50KGN0eC5wb3NpdGlvbklkKSwKCQkJImluY2VudGl2ZUlkIiwgaW5jZW50aXZlSWQsCgkJCSJyZXF1aXJlZEFtb3VudCIsIHV0aWxzLkZvcm1hdEludCh0b3RhbFJld2FyZEFtb3VudCksCgkJCSJhdmFpbGFibGVBbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQoaW5jZW50aXZlUmVzb2x2ZXIuUmV3YXJkQW1vdW50KCkpLAoJCQkiY3VycmVudFRpbWUiLCB1dGlscy5Gb3JtYXRJbnQoY3R4LmN1cnJlbnRUaW1lKSwKCQkJImN1cnJlbnRIZWlnaHQiLCB1dGlscy5Gb3JtYXRJbnQoY3R4LmJsb2NrSGVpZ2h0KSwKCQkpCgoJCS8vIFRoZSByZXdhcmQgYW1vdW50IG9ubHkgZXZlciBkZWNyZWFzZXMsIHNvIHRoaXMgc2hvcnRmYWxsIGNhbm5vdCBiZSBjb3JyZWN0ZWQgbGF0ZXIuCgkJcmV0dXJuICIiLCAwLCAwLCBleHRlcm5hbERlbGl2ZXJ5VW5wYXlhYmxlCgl9CgoJLy8gcHJvY2VzcyByZXdhcmQgc3RhdGVzCglyZXdhcmRUb2tlbiA6PSBpbmNlbnRpdmUuUmV3YXJkVG9rZW4oKQoKCS8vIExlZGdlci1sZXZlbCBkZWxpdmVyeSBndWFyZCAoYXVkaXQgZmluZGluZyAjNCkuCgkvLwoJLy8gVGhlIGJvb2trZWVwaW5nIGNoZWNrIGFib3ZlIHByb3ZlcyB0aGUgaW5jZW50aXZlIG93ZXMgdGhpcyByZXdhcmQ7IGl0IHNheXMKCS8vIG5vdGhpbmcgYWJvdXQgd2hldGhlciB0aGUgbGVkZ2VyIHRyYW5zZmVycyBiZWxvdyBjYW4gc3VjY2VlZC4gQSBwYW5pYyB0aGVyZQoJLy8gd291bGQgYWJvcnQgdGhlIGNvbGxlY3Q6IHdoaWxlIHN0YWtlZCB0aGF0IG9ubHkgZGVsYXlzIHRoZSBwYXlvdXQsIGJ1dCBvbiBhbgoJLy8gZXhpdCBjaGVja3BvaW50IGl0IHdvdWxkIGxlYXZlIHRoZSBjaGVja3BvaW50IGluIHBsYWNlIGZvcmV2ZXIsIGhvbGRpbmcgdGhlCgkvLyBwb3NpdGlvbidzIHJlLXN0YWtpbmcgYW5kIHRoZSBpbmNlbnRpdmUncyByZWZ1bmQgaG9zdGFnZSB0byBhIHRoaXJkLXBhcnR5IHRva2VuLgoJLy8KCS8vIEdub1N3YXAgdHJhbnNmZXJzIHJlc29sdmUgdGhyb3VnaCBncmMyMHJlZydzIGNvbmNyZXRlICpncmMyMC5Ub2tlbiBzdHJhaWdodAoJLy8gaW50byBQcml2YXRlTGVkZ2VyLCBzbyBubyB0b2tlbi1yZWFsbSBjb2RlIHJ1bnMgaW4gdGhlIHBhdGggYW5kIHRoZQoJLy8gcmVhY2hhYmxlIGZhaWx1cmUgc2V0IGlzIGNsb3NlZC4gQmVjYXVzZSBncmMyMCBNaW50IGVuZm9yY2VzCgkvLyB0b3RhbFN1cHBseSA8PSBNYXhJbnQ2NCBhbmQgZXZlcnkgbGVkZ2VyIG9wZXJhdGlvbiBjb25zZXJ2ZXMKCS8vIHN1bShiYWxhbmNlcykgPT0gdG90YWxTdXBwbHksIGEgcmVjaXBpZW50LWJhbGFuY2Ugb3ZlcmZsb3cgaXMgdW5yZWFjaGFibGU7CgkvLyB0aGUgb25seSByZWFjaGFibGUgZmFpbHVyZSBpcyB0aGUgc2VuZGVyIGJhbGFuY2UgZmFsbGluZyBzaG9ydCBvZiB3aGF0CgkvLyBCT1RIIGxlZ3MgbW92ZSAoaXNzdWVyIGJ1cm4gb2YgdGhlIHN0YWtlcidzIGJhbGFuY2UsIG9yIGFjY291bnRpbmcgZHJpZnQpLgoJLy8gVGhlIGZlZSBsZWcgc2V0dGxlcyBjYXJyaWVkLW92ZXIgcGVuZGluZyBwcm90b2NvbCBmZWVzIG9mIHRoZSBzYW1lIHRva2VuCgkvLyB0b28sIGhlbmNlIHRoZSArcGVuZGluZyB0ZXJtLiBUaGUgZnVsbCBkZXJpdmF0aW9uLCB0aGUgdHJ1c3QgbW9kZWwsIGFuZAoJLy8gdGhlIHJlLWF1ZGl0IHRyaWdnZXIgbGl2ZSBpbiBkb2NzL3N0YWtlci5tZC4KCS8vCgkvLyBTa2lwcGluZyBCRUZPUkUgYW55IGJvb2trZWVwaW5nIG1lYW5zOiB3aGlsZSBzdGFrZWQgdGhlIHJld2FyZCBzaW1wbHkKCS8vIHN0YXlzIHBlbmRpbmcgYW5kIGJlY29tZXMgY29sbGVjdGlibGUgb25jZSB0aGUgYmFsYW5jZSBpcyByZXN0b3JlZC4gQQoJLy8gY2hlY2twb2ludCBhYm9ydHMgaW5zdGVhZDogaXRzIGNsYWltIGlzIGZpeGVkIGFuZCBtdXN0IG5vdCBiZSB3YWl2ZWQgYnkKCS8vIGEgcGVybWlzc2lvbmxlc3MgY2FsbGVyLCBzbyBpdCBzdGF5cyBvd2VkIHVudGlsIHRoZSBiYWxhbmNlIGlzIHJlc3RvcmVkLgoJc3Rha2VyQWRkciA6PSBhY2Nlc3MuTXVzdEdldEFkZHJlc3MocHJiYWMuUk9MRV9TVEFLRVIuU3RyaW5nKCkpCglwZW5kaW5nUHJvdG9jb2xGZWUgOj0gcy5zdG9yZS5HZXRQZW5kaW5nUHJvdG9jb2xGZWVzKClbcmV3YXJkVG9rZW5dCglyZXF1aXJlZEJhbGFuY2UgOj0gZ25zbWF0aC5TYWZlQWRkSW50NjQodG90YWxSZXdhcmRBbW91bnQsIHBlbmRpbmdQcm90b2NvbEZlZSkKCglpZiBjb21tb24uQmFsYW5jZU9mKHJld2FyZFRva2VuLCBzdGFrZXJBZGRyKSA8IHJlcXVpcmVkQmFsYW5jZSB7CgkJY2hhaW4uRW1pdCgKCQkJIlVuZGVsaXZlcmFibGVFeHRlcm5hbFJld2FyZCIsCgkJCSJwcmV2QWRkciIsIGN0eC5wcmV2QWRkciwKCQkJInByZXZSZWFsbSIsIGN0eC5wcmV2UmVhbG0sCgkJCSJwb3NpdGlvbklkIiwgdXRpbHMuRm9ybWF0VWludChjdHgucG9zaXRpb25JZCksCgkJCSJpbmNlbnRpdmVJZCIsIGluY2VudGl2ZUlkLAoJCQkicmV3YXJkVG9rZW4iLCByZXdhcmRUb2tlbiwKCQkJInJlcXVpcmVkQmFsYW5jZSIsIHV0aWxzLkZvcm1hdEludChyZXF1aXJlZEJhbGFuY2UpLAoJCQkic3Rha2VyQmFsYW5jZSIsIHV0aWxzLkZvcm1hdEludChjb21tb24uQmFsYW5jZU9mKHJld2FyZFRva2VuLCBzdGFrZXJBZGRyKSksCgkJCSJjdXJyZW50VGltZSIsIHV0aWxzLkZvcm1hdEludChjdHguY3VycmVudFRpbWUpLAoJCQkiY3VycmVudEhlaWdodCIsIHV0aWxzLkZvcm1hdEludChjdHguYmxvY2tIZWlnaHQpLAoJCSkKCgkJaWYgY3R4LmNoZWNrcG9pbnQgIT0gbmlsIHsKCQkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCQllcnJJbnN1ZmZpY2llbnRSZXdhcmRUb2tlbkJhbGFuY2UsCgkJCQl1Zm10LlNwcmludGYoCgkJCQkJImluY2VudGl2ZSglcykgb3dlcyAlZCBvZiAlcyB0byBwb3NpdGlvbklkKCVkKSBidXQgdGhlIHN0YWtlciBob2xkcyAlZCIsCgkJCQkJaW5jZW50aXZlSWQsIHJlcXVpcmVkQmFsYW5jZSwgcmV3YXJkVG9rZW4sIGN0eC5wb3NpdGlvbklkLCBjb21tb24uQmFsYW5jZU9mKHJld2FyZFRva2VuLCBzdGFrZXJBZGRyKSwKCQkJCSksCgkJCSkpCgkJfQoKCQlyZXR1cm4gIiIsIDAsIDAsIGV4dGVybmFsRGVsaXZlcnlEZWZlcnJlZAoJfQoKCWluY2VudGl2ZS5TZXRSZXdhcmRBbW91bnQoZ25zbWF0aC5TYWZlU3ViSW50NjQoaW5jZW50aXZlLlJld2FyZEFtb3VudCgpLCB0b3RhbFJld2FyZEFtb3VudCkpCglpbmNlbnRpdmVSZXNvbHZlci5hZGREaXN0cmlidXRlZFJld2FyZEFtb3VudChyZXdhcmRBbW91bnQpCglpbmNlbnRpdmVSZXNvbHZlci5hZGRBY2N1bXVsYXRlZFBlbmFsdHlBbW91bnQoZXh0ZXJuYWxQZW5hbHR5KQoJY3R4LmRlcG9zaXRSZXNvbHZlci5hZGRDb2xsZWN0ZWRFeHRlcm5hbFJld2FyZChpbmNlbnRpdmVJZCwgdG90YWxSZXdhcmRBbW91bnQpCgoJLy8gVXBkYXRlIHRoZSBsYXN0IGNvbGxlY3QgdGltZSBPTkxZIGZvciB0aGlzIHNwZWNpZmljIGluY2VudGl2ZQoJLy8gVGhpcyBoYXBwZW5zIG9ubHkgaWYgdGhlIHJld2FyZCB3YXMgc3VjY2Vzc2Z1bGx5IHRyYW5zZmVycmVkLgoJZXJyIDo9IGN0eC5kZXBvc2l0UmVzb2x2ZXIudXBkYXRlRXh0ZXJuYWxSZXdhcmRMYXN0Q29sbGVjdFRpbWUoaW5jZW50aXZlSWQsIGN0eC5jdXJyZW50VGltZSkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCgkvLyBJZiBpbmNlbnRpdmUgZW5kZWQgYW5kIHVzZXIgYWxyZWFkeSBjb2xsZWN0ZWQgYWZ0ZXIgZW5kLCByZW1vdmUgZnJvbSBpbmRleAoJLy8gVGhpcyBlbnN1cmVzIGRlcG9zaXQncyBpbmNlbnRpdmUgbGlzdCBzaHJpbmtzIG92ZXIgdGltZSBhcyBpbmNlbnRpdmVzIGNvbXBsZXRlCglpZiBjdHguZGVwb3NpdFJlc29sdmVyLkV4dGVybmFsUmV3YXJkTGFzdENvbGxlY3RUaW1lKGluY2VudGl2ZUlkKSA+IGluY2VudGl2ZVJlc29sdmVyLkVuZFRpbWVzdGFtcCgpIHsKCQljdHguZGVwb3NpdC5SZW1vdmVFeHRlcm5hbEluY2VudGl2ZUlkKGluY2VudGl2ZUlkKQoJfQoKCS8vIHVwZGF0ZQoJcy5nZXRFeHRlcm5hbEluY2VudGl2ZXMoKS5zZXQoaW5jZW50aXZlSWQsIGluY2VudGl2ZSkKCgl0b1VzZXIsIGZlZUFtb3VudCwgZXJyIDo9IHMuaGFuZGxlU3Rha2luZ1Jld2FyZEZlZSgwLCBybG0sIHJld2FyZFRva2VuLCByZXdhcmRBbW91bnQsIGZhbHNlLCBjdHgudW5zdGFraW5nRmVlKHMpKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyLkVycm9yKCkpCgl9CgoJaWYgdG9Vc2VyID4gMCB7CgkJY29tbW9uLlNhZmVHUkMyMFRyYW5zZmVyKDAsIHJsbSwgcmV3YXJkVG9rZW4sIGN0eC5kZXBvc2l0Lk93bmVyKCksIHRvVXNlcikKCX0KCgljaGFpbi5FbWl0KAoJCSJQcm90b2NvbEZlZUV4dGVybmFsUmV3YXJkIiwKCQkicHJldkFkZHIiLCBjdHgucHJldkFkZHIsCgkJInByZXZSZWFsbSIsIGN0eC5wcmV2UmVhbG0sCgkJImZyb21Qb3NpdGlvbklkIiwgdXRpbHMuRm9ybWF0VWludChjdHgucG9zaXRpb25JZCksCgkJImZyb21Qb29sUGF0aCIsIGluY2VudGl2ZS5UYXJnZXRQb29sUGF0aCgpLAoJCSJmZWVUb2tlblBhdGgiLCByZXdhcmRUb2tlbiwKCQkiZmVlQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KGZlZUFtb3VudCksCgkJImN1cnJlbnRUaW1lIiwgdXRpbHMuRm9ybWF0SW50KGN0eC5jdXJyZW50VGltZSksCgkJImN1cnJlbnRIZWlnaHQiLCB1dGlscy5Gb3JtYXRJbnQoY3R4LmJsb2NrSGVpZ2h0KSwKCSkKCgljaGFpbi5FbWl0KAoJCSJDb2xsZWN0UmV3YXJkIiwKCQkicHJldkFkZHIiLCBjdHgucHJldkFkZHIsCgkJInByZXZSZWFsbSIsIGN0eC5wcmV2UmVhbG0sCgkJInBvc2l0aW9uSWQiLCB1dGlscy5Gb3JtYXRVaW50KGN0eC5wb3NpdGlvbklkKSwKCQkicG9vbFBhdGgiLCBjdHguZGVwb3NpdC5UYXJnZXRQb29sUGF0aCgpLAoJCSJyZWNpcGllbnQiLCBjdHguZGVwb3NpdC5Pd25lcigpLlN0cmluZygpLAoJCSJpbmNlbnRpdmVJZCIsIGluY2VudGl2ZUlkLAoJCSJyZXdhcmRUb2tlbiIsIHJld2FyZFRva2VuLAoJCSJyZXdhcmRBbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQocmV3YXJkQW1vdW50KSwKCQkicmV3YXJkVG9Vc2VyIiwgdXRpbHMuRm9ybWF0SW50KHRvVXNlciksCgkJInJld2FyZFRvRmVlIiwgdXRpbHMuRm9ybWF0SW50KHJld2FyZEFtb3VudC10b1VzZXIpLAoJCSJyZXdhcmRQZW5hbHR5IiwgdXRpbHMuRm9ybWF0SW50KGV4dGVybmFsUGVuYWx0eSksCgkJImN1cnJlbnRUaW1lIiwgdXRpbHMuRm9ybWF0SW50KGN0eC5jdXJyZW50VGltZSksCgkJImN1cnJlbnRIZWlnaHQiLCB1dGlscy5Gb3JtYXRJbnQoY3R4LmJsb2NrSGVpZ2h0KSwKCQkic3Rha2VkTGlxdWlkaXR5IiwgY3R4LnN0YWtlZExpcXVpZGl0eS5Ub1N0cmluZygpLAoJCSJnbG9iYWxSZXdhcmRSYXRpb0FjY1gxMjgiLCBjdHguZ2xvYmFsQWNjWDEyOC5Ub1N0cmluZygpLAoJCSJsb3dlclRpY2tPdXRzaWRlQWNjWDEyOCIsIGN0eC5sb3dlck91dHNpZGVBY2NYMTI4LlRvU3RyaW5nKCksCgkJInVwcGVyVGlja091dHNpZGVBY2NYMTI4IiwgY3R4LnVwcGVyT3V0c2lkZUFjY1gxMjguVG9TdHJpbmcoKSwKCSkKCglyZXR1cm4gcmV3YXJkVG9rZW4sIHJld2FyZEFtb3VudCwgZXh0ZXJuYWxQZW5hbHR5LCBleHRlcm5hbERlbGl2ZXJ5UGFpZAp9CgovLyBkZWxpdmVyRW1pc3Npb25SZXdhcmQgcGF5cyBvdXQgdGhlIGFscmVhZHktY2FsY3VsYXRlZCBHTlMgZW1pc3Npb24gcmV3YXJkOiBpdCB0YWtlcyB0aGUgc3Rha2luZyByZXdhcmQKLy8gZmVlLCBzZXR0bGVzIHRoZSBwb29sJ3MgdW5jbGFpbWFibGUgYWNjdW11bGF0aW9uIHRvIHRoZSBjb21tdW5pdHkgcG9vbCwgYWR2YW5jZXMgdG90YWxFbWlzc2lvblNlbnQgYW5kCi8vIHRoZSBkZXBvc2l0J3MgaW50ZXJuYWwgbGFzdENvbGxlY3RUaW1lLCBhbmQgdHJhbnNmZXJzIHRoZSBHTlMuCi8vCi8vIFdoZW4gdGhlIHBvc2l0aW9uIGhhcyBubyBlbWlzc2lvbiByZXdhcmQgdG8gZGVsaXZlciwgdGhlIGludGVybmFsIGxhc3RDb2xsZWN0VGltZSBpcyBsZWZ0IHVudG91Y2hlZCBzbwovLyB0aGUgYW1vdW50IGtlZXBzIGFjY3J1aW5nOyB0aGUgcG9vbCdzIHVuY2xhaW1hYmxlIGFjY3VtdWxhdGlvbiBpcyBzdGlsbCBzZXR0bGVkLgovLwovLyBSZXR1cm5zIHRoZSBHTlMgYW1vdW50IHNlbnQgdG8gdGhlIHVzZXIgYW5kIHRoZSBwZW5hbHR5IGFtb3VudCBzZW50IHRvIHRoZSBjb21tdW5pdHkgcG9vbC4KZnVuYyAocyAqc3Rha2VyVjEpIGRlbGl2ZXJFbWlzc2lvblJld2FyZChfIGludCwgcmxtIHJlYWxtLCBjdHggKmNvbGxlY3RDb250ZXh0LCByZXdhcmQgUmV3YXJkKSAoaW50NjQsIGludDY0KSB7CgkvLyBTYW1lIHJlZW50cmFuY3kgYmFja3N0b3AgYXMgZGVsaXZlckV4dGVybmFsSW5jZW50aXZlUmV3YXJkOiBhIGNoZWNrcG9pbnQgd2hvc2UgaW50ZXJuYWwKCS8vIGN1cnNvciBhbHJlYWR5IHJlYWNoZWQgaXRzIHdpbmRvdydzIGNsb3NlIGhhcyBoYWQgdGhpcyBkZWxpdmVyeSwgYW5kIHJld2FyZCB3YXMgY29tcHV0ZWQKCS8vIGJlZm9yZSB0aGUgZXh0ZXJuYWwgZGVsaXZlcmllcyByYW4uIFRoZSBzb3VyY2UgY291bnRzIGFzIHNldHRsZWQgZWl0aGVyIHdheS4KCWlmIGN0eC5jaGVja3BvaW50ICE9IG5pbCAmJiBjdHguZGVwb3NpdFJlc29sdmVyLkludGVybmFsUmV3YXJkTGFzdENvbGxlY3RUaW1lKCkgPj0gY3R4LmN1cnJlbnRUaW1lIHsKCQlyZXR1cm4gMCwgMAoJfQoKCWNvbW11bml0eVBvb2xBZGRyIDo9IGFjY2Vzcy5NdXN0R2V0QWRkcmVzcyhwcmJhYy5ST0xFX0NPTU1VTklUWV9QT09MLlN0cmluZygpKQoKCWludGVybmFsUmV3YXJkIDo9IGludDY0KDApCglpbnRlcm5hbFJld2FyZFRvVXNlciA6PSBpbnQ2NCgwKQoJaW50ZXJuYWxSZXdhcmRUb0ZlZSA6PSBpbnQ2NCgwKQoJaW50ZXJuYWxSZXdhcmRQZW5hbHR5IDo9IGludDY0KDApCgoJLy8gU2tpcCBpbnRlcm5hbCByZXdhcmQgc3RhdGUgdXBkYXRlIHdoZW4gdXNlciByZXdhcmQgaXMgemVybyAob25seSBwZW5hbHR5KS4KCS8vIERvIG5vdCB1cGRhdGUgbGFzdCBjb2xsZWN0IHRpbWUgc28gdGhlIHJld2FyZCBhY2NydWVzIHVudGlsIHRoZSBuZXh0CgkvLyBjb2xsZWN0aW9uIHdoZXJlIGEgbm9uLXplcm8gYW1vdW50IGNhbiBiZSBkZWxpdmVyZWQuCgkvLwoJLy8gQW4gZXhpdCBjaGVja3BvaW50IGhhcyBubyBuZXh0IGNvbGxlY3Rpb246IGl0IHN0b3BwZWQgYWNjcnVpbmcsIHNvIGEgcGVuYWx0eSBsZWZ0IGhlcmUKCS8vIHdvdWxkIG5ldmVyIGJlIGRlbGl2ZXJlZCBhbmQgd291bGQgYmUgZHJvcHBlZCB3aXRoIHRoZSBjaGVja3BvaW50LgoJc2tpcEludGVybmFsVXBkYXRlIDo9IHJld2FyZC5JbnRlcm5hbCA9PSAwICYmCgkJKGN0eC5jaGVja3BvaW50ID09IG5pbCB8fCByZXdhcmQuSW50ZXJuYWxQZW5hbHR5ID09IDApCgoJLy8gaW50ZXJuYWwgcmV3YXJkIHRvIHVzZXIKCWlmICFza2lwSW50ZXJuYWxVcGRhdGUgewoJCXRvVXNlciwgZmVlQW1vdW50LCBlcnIgOj0gcy5oYW5kbGVTdGFraW5nUmV3YXJkRmVlKDAsIHJsbSwgR05TX1RPS0VOX0tFWSwgcmV3YXJkLkludGVybmFsLCB0cnVlLCBjdHgudW5zdGFraW5nRmVlKHMpKQoJCWlmIGVyciAhPSBuaWwgewoJCQlwYW5pYyhlcnIuRXJyb3IoKSkKCQl9CgoJCWludGVybmFsUmV3YXJkID0gcmV3YXJkLkludGVybmFsCgkJaW50ZXJuYWxSZXdhcmRUb1VzZXIgPSB0b1VzZXIKCQlpbnRlcm5hbFJld2FyZFRvRmVlID0gZmVlQW1vdW50CgkJaW50ZXJuYWxSZXdhcmRQZW5hbHR5ID0gcmV3YXJkLkludGVybmFsUGVuYWx0eQoKCQljaGFpbi5FbWl0KAoJCQkiUHJvdG9jb2xGZWVJbnRlcm5hbFJld2FyZCIsCgkJCSJwcmV2QWRkciIsIGN0eC5wcmV2QWRkciwKCQkJInByZXZSZWFsbSIsIGN0eC5wcmV2UmVhbG0sCgkJCSJmcm9tUG9zaXRpb25JZCIsIHV0aWxzLkZvcm1hdFVpbnQoY3R4LnBvc2l0aW9uSWQpLAoJCQkiZnJvbVBvb2xQYXRoIiwgY3R4LmRlcG9zaXQuVGFyZ2V0UG9vbFBhdGgoKSwKCQkJImZlZVRva2VuUGF0aCIsIEdOU19UT0tFTl9LRVksCgkJCSJmZWVBbW91bnQiLCB1dGlscy5Gb3JtYXRJbnQoaW50ZXJuYWxSZXdhcmRUb0ZlZSksCgkJCSJjdXJyZW50VGltZSIsIHV0aWxzLkZvcm1hdEludChjdHguY3VycmVudFRpbWUpLAoJCQkiY3VycmVudEhlaWdodCIsIHV0aWxzLkZvcm1hdEludChjdHguYmxvY2tIZWlnaHQpLAoJCSkKCX0KCgl0b3RhbEVtaXNzaW9uU2VudCA6PSBzLnN0b3JlLkdldFRvdGFsRW1pc3Npb25TZW50KCkKCglpZiBpbnRlcm5hbFJld2FyZFRvVXNlciA+IDAgewoJCS8vIGludGVybmFsIHJld2FyZCB0byB1c2VyCgkJdG90YWxFbWlzc2lvblNlbnQgPSBnbnNtYXRoLlNhZmVBZGRJbnQ2NCh0b3RhbEVtaXNzaW9uU2VudCwgaW50ZXJuYWxSZXdhcmRUb1VzZXIpCgkJY3R4LmRlcG9zaXRSZXNvbHZlci5hZGRDb2xsZWN0ZWRJbnRlcm5hbFJld2FyZChyZXdhcmQuSW50ZXJuYWwpCgl9CgoJaWYgaW50ZXJuYWxSZXdhcmRQZW5hbHR5ID4gMCB7CgkJLy8gaW50ZXJuYWwgcGVuYWx0eSB0byBjb21tdW5pdHkgcG9vbAoJCXRvdGFsRW1pc3Npb25TZW50ID0gZ25zbWF0aC5TYWZlQWRkSW50NjQodG90YWxFbWlzc2lvblNlbnQsIGludGVybmFsUmV3YXJkUGVuYWx0eSkKCQljdHguZGVwb3NpdFJlc29sdmVyLmFkZENvbGxlY3RlZEludGVybmFsUmV3YXJkKGludGVybmFsUmV3YXJkUGVuYWx0eSkKCX0KCgkvLyBVbmNsYWltYWJsZSBtdXN0IGJlIHByb2Nlc3NlZCBhZnRlciByZWd1bGFyIHJld2FyZHMgc28gdGhhdCBhY2N1bXVsYXRlZAoJLy8gdW5jbGFpbWFibGUgYW1vdW50cyBhcmUgcmVzZXQgaW4gdGhlIHNhbWUgY29sbGVjdCB3aW5kb3cuCgkvLyBBbHdheXMgYXQgdGhlIGN1cnJlbnQgdGltZSwgbmV2ZXIgYXQgY3R4LmN1cnJlbnRUaW1lOiB0aGlzIGFjY3VtdWxhdG9yIGlzIHBvb2wtZ2xvYmFsLCBhbmQKCS8vIGEgY2hlY2twb2ludCBjb2xsZWN0IHdvdWxkIHJld2luZCBpdCB0byBpdHMgZXhpdCB0aW1lc3RhbXAsIHJlLWNvdW50aW5nIGV2ZXJ5dGhpbmcgc2luY2UgYXMKCS8vIHVuY2xhaW1hYmxlIGFuZCBwYXlpbmcgaXQgb3V0IG9mIHRoZSBzaGFyZWQgcmVzZXJ2ZS4KCXVuQ2xhaW1hYmxlSW50ZXJuYWwgOj0gcy5wcm9jZXNzVW5DbGFpbWFibGVSZXdhcmQoY3R4LmRlcG9zaXRSZXNvbHZlci5UYXJnZXRQb29sUGF0aCgpLCB0aW1lLk5vdygpLlVuaXgoKSkKCWlmIHVuQ2xhaW1hYmxlSW50ZXJuYWwgPiAwIHsKCQl0b3RhbEVtaXNzaW9uU2VudCA9IGduc21hdGguU2FmZUFkZEludDY0KHRvdGFsRW1pc3Npb25TZW50LCB1bkNsYWltYWJsZUludGVybmFsKQoJfQoKCWlmIGVyciA6PSBzLnN0b3JlLlNldFRvdGFsRW1pc3Npb25TZW50KDAsIHJsbSwgdG90YWxFbWlzc2lvblNlbnQpOyBlcnIgIT0gbmlsIHsKCQlwYW5pYyhlcnIpCgl9CgoJaWYgIXNraXBJbnRlcm5hbFVwZGF0ZSB7CgkJLy8gVXBkYXRlIGxhc3RDb2xsZWN0VGltZSBmb3IgaW50ZXJuYWwgcmV3YXJkcyAoR05TIGVtaXNzaW9ucykKCQlpZiBlcnIgOj0gY3R4LmRlcG9zaXRSZXNvbHZlci51cGRhdGVJbnRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZShjdHguY3VycmVudFRpbWUpOyBlcnIgIT0gbmlsIHsKCQkJcGFuaWMoZXJyKQoJCX0KCX0KCgljdHgucGVyc2lzdERlcG9zaXQocykKCglpZiBpbnRlcm5hbFJld2FyZFRvVXNlciA+IDAgewoJCWducy5UcmFuc2Zlcihjcm9zcyhybG0pLCBjdHguZGVwb3NpdC5Pd25lcigpLCBpbnRlcm5hbFJld2FyZFRvVXNlcikKCX0KCglpZiBpbnRlcm5hbFJld2FyZFBlbmFsdHkgPiAwIHsKCQlnbnMuVHJhbnNmZXIoY3Jvc3MocmxtKSwgY29tbXVuaXR5UG9vbEFkZHIsIGludGVybmFsUmV3YXJkUGVuYWx0eSkKCX0KCglpZiB1bkNsYWltYWJsZUludGVybmFsID4gMCB7CgkJZ25zLlRyYW5zZmVyKGNyb3NzKHJsbSksIGNvbW11bml0eVBvb2xBZGRyLCB1bkNsYWltYWJsZUludGVybmFsKQoJfQoKCWlmICFza2lwSW50ZXJuYWxVcGRhdGUgewoJCWNoYWluLkVtaXQoCgkJCSJDb2xsZWN0UmV3YXJkIiwKCQkJInByZXZBZGRyIiwgY3R4LnByZXZBZGRyLAoJCQkicHJldlJlYWxtIiwgY3R4LnByZXZSZWFsbSwKCQkJInBvc2l0aW9uSWQiLCB1dGlscy5Gb3JtYXRVaW50KGN0eC5wb3NpdGlvbklkKSwKCQkJInBvb2xQYXRoIiwgY3R4LmRlcG9zaXRSZXNvbHZlci5UYXJnZXRQb29sUGF0aCgpLAoJCQkicmVjaXBpZW50IiwgY3R4LmRlcG9zaXRSZXNvbHZlci5Pd25lcigpLlN0cmluZygpLAoJCQkicmV3YXJkVG9rZW4iLCBHTlNfVE9LRU5fS0VZLAoJCQkicmV3YXJkQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KGludGVybmFsUmV3YXJkKSwKCQkJInJld2FyZFRvVXNlciIsIHV0aWxzLkZvcm1hdEludChpbnRlcm5hbFJld2FyZFRvVXNlciksCgkJCSJyZXdhcmRUb0ZlZSIsIHV0aWxzLkZvcm1hdEludChpbnRlcm5hbFJld2FyZFRvRmVlKSwKCQkJInJld2FyZFBlbmFsdHkiLCB1dGlscy5Gb3JtYXRJbnQoaW50ZXJuYWxSZXdhcmRQZW5hbHR5KSwKCQkJInJld2FyZFVuQ2xhaW1hYmxlQW1vdW50IiwgdXRpbHMuRm9ybWF0SW50KHVuQ2xhaW1hYmxlSW50ZXJuYWwpLAoJCQkiY3VycmVudFRpbWUiLCB1dGlscy5Gb3JtYXRJbnQoY3R4LmN1cnJlbnRUaW1lKSwKCQkJImN1cnJlbnRIZWlnaHQiLCB1dGlscy5Gb3JtYXRJbnQoY3R4LmJsb2NrSGVpZ2h0KSwKCQkJInN0YWtlZExpcXVpZGl0eSIsIGN0eC5zdGFrZWRMaXF1aWRpdHkuVG9TdHJpbmcoKSwKCQkJImdsb2JhbFJld2FyZFJhdGlvQWNjWDEyOCIsIGN0eC5nbG9iYWxBY2NYMTI4LlRvU3RyaW5nKCksCgkJCSJsb3dlclRpY2tPdXRzaWRlQWNjWDEyOCIsIGN0eC5sb3dlck91dHNpZGVBY2NYMTI4LlRvU3RyaW5nKCksCgkJCSJ1cHBlclRpY2tPdXRzaWRlQWNjWDEyOCIsIGN0eC51cHBlck91dHNpZGVBY2NYMTI4LlRvU3RyaW5nKCksCgkJKQoJfQoKCXJldHVybiBpbnRlcm5hbFJld2FyZFRvVXNlciwgaW50ZXJuYWxSZXdhcmRQZW5hbHR5Cn0KCi8vIFVuU3Rha2VUb2tlbiB3aXRoZHJhd3MgYW4gTFAgdG9rZW4gZnJvbSBzdGFraW5nIGFuZCByZXR1cm5zIHRoZSBORlQgdG8gaXRzIG9yaWdpbmFsIG93bmVyLgovLyBSZXdhcmRzIGFyZSBub3QgY29sbGVjdGVkIGhlcmU6IGFuIGV4aXQgY2hlY2twb2ludCByZWNvcmRzIHdoYXQgdGhlIHBvc2l0aW9uIGlzIHN0aWxsIG93ZWQsCi8vIGFuZCB0aGUgQ29sbGVjdCogZW50cnkgcG9pbnRzIHNldHRsZSBpdCBwZXIgc291cmNlLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gXzogTm9uY3Jvc3NpbmcgaW1wbGVtZW50YXRpb24tY2FsbCBkaXNjcmltaW5hdG9yOyBwYXNzIDAuCi8vICAgLSBybG06IEN1cnJlbnQgcmVhbG0gY29udGV4dCBmb3J3YXJkZWQgdW5jaGFuZ2VkIGJ5IHRoZSBzdGFrZXIgcHJveHkuCi8vICAgLSBwb3NpdGlvbklkOiBMUCBwb3NpdGlvbiBORlQgdG9rZW4gSUQgdG8gdW5zdGFrZS4KLy8KLy8gUHJvY2VzczoKLy8gIDEuIFJlY29yZHMgYW4gZXhpdCBjaGVja3BvaW50IG93aW5nIGV2ZXJ5IHJld2FyZCBzb3VyY2UgKEdOUyArIGV4dGVybmFsKQovLyAgMi4gVHJhbnNmZXJzIE5GVCBvd25lcnNoaXAgYmFjayB0byBvcmlnaW5hbCBvd25lcgovLyAgMy4gQ2xlYXJzIHBvc2l0aW9uIG9wZXJhdG9yIHJpZ2h0cwovLyAgNC4gUmVtb3ZlcyBmcm9tIHJld2FyZCB0cmFja2luZyBzeXN0ZW1zCi8vICA1LiBDbGVhbnMgdXAgYWxsIHN0YWtpbmcgbWV0YWRhdGEKLy8KLy8gUmV0dXJuczoKLy8gICAtIHBvb2xQYXRoOiBQb29sIGlkZW50aWZpZXIgd2hlcmUgcG9zaXRpb24gd2FzIHN0YWtlZC4KLy8KLy8gUmVxdWlyZW1lbnRzOgovLyAgIC0gQ2FsbGVyIG11c3QgYmUgdGhlIGRlcG9zaXRvcgovLyAgIC0gUG9zaXRpb24gbXVzdCBiZSBjdXJyZW50bHkgc3Rha2VkCmZ1bmMgKHMgKnN0YWtlclYxKSBVblN0YWtlVG9rZW4oXyBpbnQsIHJsbSByZWFsbSwgcG9zaXRpb25JZCB1aW50NjQpIHN0cmluZyB7IC8vIHBvb2xQYXRoCglhY2Nlc3MuQXNzZXJ0SXNSbG1DdXJyZW50KDAsIHJsbSkKCgljYWxsZXIgOj0gcmxtLlByZXZpb3VzKCkuQWRkcmVzcygpCgloYWx0LkFzc2VydElzTm90SGFsdGVkV2l0aGRyYXcoKQoJYXNzZXJ0SXNEZXBvc2l0b3IocywgY2FsbGVyLCBwb3NpdGlvbklkKQoKCWRlcG9zaXQgOj0gcy5nZXREZXBvc2l0cygpLmdldChwb3NpdGlvbklkKQoKCS8vIHVuU3Rha2VkIHN0YXR1cwoJcG9vbFBhdGggOj0gZGVwb3NpdC5UYXJnZXRQb29sUGF0aCgpCgoJLy8gcmVjb3JkIHRoZSBleGl0IGNoZWNrcG9pbnQ7IGNvbGxlY3RpbmcgaXMgbGVmdCB0byB0aGUgQ29sbGVjdCogZW50cnkgcG9pbnRzCgljaGVja3BvaW50IDo9IHMucmVjb3JkVW5zdGFrZWRQb3NpdGlvbigwLCBybG0sIHBvc2l0aW9uSWQsIGRlcG9zaXQsIHRpbWUuTm93KCkuVW5peCgpKQoKCWlmIGVyciA6PSBzLmFwcGx5VW5TdGFrZShwb3NpdGlvbklkKTsgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCS8vIHRyYW5zZmVyIE5GVCBvd25lcnNoaXAgdG8gb3JpZ2luIG93bmVyCglzdGFrZXJBZGRyIDo9IGFjY2Vzcy5NdXN0R2V0QWRkcmVzcyhwcmJhYy5ST0xFX1NUQUtFUi5TdHJpbmcoKSkKCXMubmZ0QWNjZXNzb3IuVHJhbnNmZXJGcm9tKDAsIHJsbSwgc3Rha2VyQWRkciwgZGVwb3NpdC5Pd25lcigpLCBwb3NpdGlvbklkRnJvbShwb3NpdGlvbklkKSkKCXBuLlNldFBvc2l0aW9uT3BlcmF0b3IoY3Jvc3MocmxtKSwgcG9zaXRpb25JZCwgWkVST19BRERSRVNTKQoKCS8vIGdldCBwb3NpdGlvbiBpbmZvcm1hdGlvbiBmb3IgZXZlbnQKCWxpcXVpZGl0eSA6PSBnZXRMaXF1aWRpdHkocG9zaXRpb25JZCkKCXRpY2tMb3dlciwgdGlja1VwcGVyIDo9IGdldFRpY2tPZihwb3NpdGlvbklkKQoKCWFtb3VudDAsIGFtb3VudDEgOj0gcy5jYWxjdWxhdGVBbW91bnRzKHBvb2xQYXRoLCB0aWNrTG93ZXIsIHRpY2tVcHBlciwgbGlxdWlkaXR5KQoKCS8vIEdldCBwb29sIGFuZCBhY2N1bXVsYXRvciB2YWx1ZXMgZm9yIHJld2FyZCBjYWxjdWxhdGlvbiB0cmFja2luZwoJY3VycmVudFRpbWUgOj0gdGltZS5Ob3coKS5Vbml4KCkKCXBvb2wsIF8gOj0gcy5nZXRQb29scygpLkdldChwb29sUGF0aCkKCXBvb2xSZXNvbHZlciA6PSBOZXdQb29sUmVzb2x2ZXIocG9vbCkKCWN1cnJlbnRUaWNrIDo9IHMucG9vbEFjY2Vzc29yLkdldFNsb3QwVGljayhwb29sUGF0aCkKCglnbG9iYWxBY2NYMTI4LCBzdGFrZWRMaXF1aWRpdHkgOj0gcG9vbFJlc29sdmVyLmdsb2JhbFJld2FyZFJhdGlvQWNjdW11bGF0aW9uQXQoY3VycmVudFRpbWUpCgoJcHJldmlvdXNSZWFsbSA6PSBybG0uUHJldmlvdXMoKQoJY2hhaW4uRW1pdCgKCQkiVW5TdGFrZVRva2VuIiwKCQkicHJldkFkZHIiLCBwcmV2aW91c1JlYWxtLkFkZHJlc3MoKS5TdHJpbmcoKSwKCQkicHJldlJlYWxtIiwgcHJldmlvdXNSZWFsbS5Qa2dQYXRoKCksCgkJInBvc2l0aW9uSWQiLCB1dGlscy5Gb3JtYXRVaW50KHBvc2l0aW9uSWQpLAoJCSJwb29sUGF0aCIsIHBvb2xQYXRoLAoJCSJvd25lciIsIGRlcG9zaXQuT3duZXIoKS5TdHJpbmcoKSwKCQkibGlxdWlkaXR5IiwgbGlxdWlkaXR5LlRvU3RyaW5nKCksCgkJInBvc2l0aW9uVXBwZXJUaWNrIiwgdXRpbHMuRm9ybWF0SW50KHRpY2tVcHBlciksCgkJInBvc2l0aW9uTG93ZXJUaWNrIiwgdXRpbHMuRm9ybWF0SW50KHRpY2tMb3dlciksCgkJImFtb3VudDAiLCBhbW91bnQwLlRvU3RyaW5nKCksCgkJImFtb3VudDEiLCBhbW91bnQxLlRvU3RyaW5nKCksCgkJImZyb20iLCBzdGFrZXJBZGRyLlN0cmluZygpLAoJCSJ0byIsIGRlcG9zaXQuT3duZXIoKS5TdHJpbmcoKSwKCQkiY3VycmVudFRpY2siLCB1dGlscy5Gb3JtYXRJbnQoY3VycmVudFRpY2spLAoJCSJzdGFrZWRMaXF1aWRpdHkiLCBzdGFrZWRMaXF1aWRpdHkuVG9TdHJpbmcoKSwKCQkiZ2xvYmFsUmV3YXJkUmF0aW9BY2NYMTI4IiwgZ2xvYmFsQWNjWDEyOC5Ub1N0cmluZygpLAoJCSJleGl0VGltZSIsIHV0aWxzLkZvcm1hdEludChjaGVja3BvaW50LkV4aXRUaW1lKCkpLAoJCSJwZW5kaW5nSW5jZW50aXZlSWRzIiwgc3RyaW5ncy5Kb2luKGNoZWNrcG9pbnQuUGVuZGluZ0luY2VudGl2ZUlkTGlzdCgpLCAiLCIpLAoJCSJwZW5kaW5nSW5jZW50aXZlQ291bnQiLCB1dGlscy5Gb3JtYXRJbnQoaW50NjQoY2hlY2twb2ludC5QZW5kaW5nSW5jZW50aXZlQ291bnQoKSkpLAoJKQoKCXJldHVybiBwb29sUGF0aAp9CgpmdW5jIChzICpzdGFrZXJWMSkgYXBwbHlVblN0YWtlKHBvc2l0aW9uSWQgdWludDY0KSBlcnJvciB7CglkZXBvc2l0IDo9IHMuZ2V0RGVwb3NpdHMoKS5nZXQocG9zaXRpb25JZCkKCWRlcG9zaXRSZXNvbHZlciA6PSBOZXdEZXBvc2l0UmVzb2x2ZXIoZGVwb3NpdCkKCXBvb2wsIG9rIDo9IHMuZ2V0UG9vbHMoKS5HZXQoZGVwb3NpdFJlc29sdmVyLlRhcmdldFBvb2xQYXRoKCkpCglwb29sUmVzb2x2ZXIgOj0gTmV3UG9vbFJlc29sdmVyKHBvb2wpCglpZiAhb2sgewoJCXJldHVybiB1Zm10LkVycm9yZigKCQkJIiV2OiBwb29sKCVzKSBkb2VzIG5vdCBleGlzdCIsCgkJCWVyckRhdGFOb3RGb3VuZCwgZGVwb3NpdFJlc29sdmVyLlRhcmdldFBvb2xQYXRoKCksCgkJKQoJfQoKCWN1cnJlbnRUaW1lIDo9IHRpbWUuTm93KCkuVW5peCgpCgljdXJyZW50VGljayA6PSBzLnBvb2xBY2Nlc3Nvci5HZXRTbG90MFRpY2soZGVwb3NpdFJlc29sdmVyLlRhcmdldFBvb2xQYXRoKCkpCglzaWduZWRMaXF1aWRpdHkgOj0gaTI1Ni5aZXJvKCkuTmVnKGkyNTYuRnJvbVVpbnQyNTYoZGVwb3NpdFJlc29sdmVyLkxpcXVpZGl0eSgpKSkKCWluUmFuZ2UsIGVyciA6PSBwbi5Jc0luUmFuZ2UocG9zaXRpb25JZCkKCWlmIGVyciAhPSBuaWwgewoJCXJldHVybiBlcnIKCX0KCWlmIGluUmFuZ2UgewoJCXBvb2xSZXNvbHZlci5tb2RpZnlEZXBvc2l0KHNpZ25lZExpcXVpZGl0eSwgY3VycmVudFRpbWUsIGN1cnJlbnRUaWNrKQoJfQoKCXVwcGVyVGljayA6PSBwb29sUmVzb2x2ZXIuR2V0T3JOZXdUaWNrKGRlcG9zaXRSZXNvbHZlci5UaWNrVXBwZXIoKSkKCU5ld1RpY2tSZXNvbHZlcih1cHBlclRpY2spLm1vZGlmeURlcG9zaXRVcHBlcihjdXJyZW50VGltZSwgc2lnbmVkTGlxdWlkaXR5KQoJcG9vbC5UaWNrcygpLlNldFRpY2soZGVwb3NpdFJlc29sdmVyLlRpY2tVcHBlcigpLCB1cHBlclRpY2spCgoJbG93ZXJUaWNrIDo9IHBvb2xSZXNvbHZlci5HZXRPck5ld1RpY2soZGVwb3NpdFJlc29sdmVyLlRpY2tMb3dlcigpKQoJTmV3VGlja1Jlc29sdmVyKGxvd2VyVGljaykubW9kaWZ5RGVwb3NpdExvd2VyKGN1cnJlbnRUaW1lLCBzaWduZWRMaXF1aWRpdHkpCglwb29sLlRpY2tzKCkuU2V0VGljayhkZXBvc2l0UmVzb2x2ZXIuVGlja0xvd2VyKCksIGxvd2VyVGljaykKCglzLmdldERlcG9zaXRzKCkucmVtb3ZlKHBvc2l0aW9uSWQpCgoJcmV0dXJuIG5pbAp9CgovLyBwb29sSGFzSW5jZW50aXZlcyBjaGVja3MgaWYgdGhlIHBvb2wgaGFzIGFueSBzdGFrZWFibGUgaW5jZW50aXZlcyAoaW50ZXJuYWwgb3IgZXh0ZXJuYWwpLgovLyBFeHRlcm5hbCBlbGlnaWJpbGl0eSBpbmNsdWRlcyBhY3RpdmUgYW5kIGZ1dHVyZSBpbmNlbnRpdmVzLgpmdW5jIChzICpzdGFrZXJWMSkgcG9vbEhhc0luY2VudGl2ZXMocG9vbCAqc3IuUG9vbCkgZXJyb3IgewoJcG9vbFBhdGggOj0gcG9vbC5Qb29sUGF0aCgpCglpZiBzLmdldFBvb2xUaWVyKCkuSXNJbnRlcm5hbGx5SW5jZW50aXZpemVkUG9vbChwb29sUGF0aCkgewoJCXJldHVybiBuaWwKCX0KCglpZiAhTmV3UG9vbFJlc29sdmVyKHBvb2wpLklzRXh0ZXJuYWxseUluY2VudGl2aXplZFBvb2woKSB7CgkJcmV0dXJuIHVmbXQuRXJyb3JmKAoJCQkiJXY6IGNhbm5vdCBzdGFrZSBwb3NpdGlvbiB0byBub24gaW5jZW50aXZpemVkIHBvb2woJXMpIiwKCQkJZXJyTm9uSW5jZW50aXZpemVkUG9vbCwgcG9vbFBhdGgsCgkJKQoJfQoKCXJldHVybiBuaWwKfQoKLy8gdG9rZW5IYXNMaXF1aWRpdHkgY2hlY2tzIGlmIHRoZSB0YXJnZXQgcG9zaXRpb25JZCBoYXMgbm9uLXplcm8gbGlxdWlkaXR5CmZ1bmMgdG9rZW5IYXNMaXF1aWRpdHkocG9zaXRpb25JZCB1aW50NjQpIGVycm9yIHsKCWlmIGdldExpcXVpZGl0eShwb3NpdGlvbklkKS5MdGUodTI1Ni5aZXJvKCkpIHsKCQlyZXR1cm4gdWZtdC5FcnJvcmYoCgkJCSIldjogcG9zaXRpb25JZCglZCkgaGFzIG5vIGxpcXVpZGl0eSIsCgkJCWVyclplcm9MaXF1aWRpdHksIHBvc2l0aW9uSWQsCgkJKQoJfQoJcmV0dXJuIG5pbAp9CgpmdW5jIGdldExpcXVpZGl0eShwb3NpdGlvbklkIHVpbnQ2NCkgKnUyNTYuVWludCB7CglsaXF1aWRpdHksIGVyciA6PSBwbi5HZXRQb3NpdGlvbkxpcXVpZGl0eShwb3NpdGlvbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoKCXJldHVybiB1MjU2Lk11c3RGcm9tRGVjaW1hbChsaXF1aWRpdHkpCn0KCmZ1bmMgZ2V0VGlja09mKHBvc2l0aW9uSWQgdWludDY0KSAoaW50MzIsIGludDMyKSB7Cgl0aWNrTG93ZXIsIGVyciA6PSBwbi5HZXRQb3NpdGlvblRpY2tMb3dlcihwb3NpdGlvbklkKQoJaWYgZXJyICE9IG5pbCB7CgkJcGFuaWMoZXJyKQoJfQoJdGlja1VwcGVyLCBlcnIgOj0gcG4uR2V0UG9zaXRpb25UaWNrVXBwZXIocG9zaXRpb25JZCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCWlmIHRpY2tVcHBlciA8IHRpY2tMb3dlciB7CgkJcGFuaWModWZtdC5TcHJpbnRmKCJ0aWNrVXBwZXIoJWQpIGlzIGxlc3MgdGhhbiB0aWNrTG93ZXIoJWQpIiwgdGlja1VwcGVyLCB0aWNrTG93ZXIpKQoJfQoJcmV0dXJuIHRpY2tMb3dlciwgdGlja1VwcGVyCn0KCi8vIGNhbGN1bGF0ZUFtb3VudHMgY2FsY3VsYXRlcyB0aGUgYW1vdW50cyBvZiB0b2tlbjAgYW5kIHRva2VuMSBmb3IgYSBnaXZlbiBsaXF1aWRpdHkgYW5kIHJhbmdlLgpmdW5jIChzICpzdGFrZXJWMSkgY2FsY3VsYXRlQW1vdW50cyhwb29sUGF0aCBzdHJpbmcsIHRpY2tMb3dlciwgdGlja1VwcGVyIGludDMyLCBsaXF1aWRpdHkgKnUyNTYuVWludCkgKCp1MjU2LlVpbnQsICp1MjU2LlVpbnQpIHsKCXNxcnRQcmljZVg5NiA6PSB1MjU2Lk11c3RGcm9tRGVjaW1hbChzLnBvb2xBY2Nlc3Nvci5HZXRTbG90MFNxcnRQcmljZVg5Nihwb29sUGF0aCkpCglzcXJ0UHJpY2VMb3dlclg5NiA6PSBnbnNtYXRoLlRpY2tNYXRoR2V0U3FydFJhdGlvQXRUaWNrKHRpY2tMb3dlcikKCXNxcnRQcmljZVVwcGVyWDk2IDo9IGduc21hdGguVGlja01hdGhHZXRTcXJ0UmF0aW9BdFRpY2sodGlja1VwcGVyKQoKCXJldHVybiBnbnNtYXRoLkdldEFtb3VudHNGb3JMaXF1aWRpdHkoc3FydFByaWNlWDk2LCBzcXJ0UHJpY2VMb3dlclg5Niwgc3FydFByaWNlVXBwZXJYOTYsIGxpcXVpZGl0eSkKfQoapDoKCHR5cGUuZ25vEpc6cGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkiZ25vLmxhbmQvcC9nbm9zd2FwL2duc21hdGgvdjEiCglzciAiZ25vLmxhbmQvci9nbm9zd2FwL3N0YWtlciIKKQoKdHlwZSBFeHRlcm5hbEluY2VudGl2ZVJlc29sdmVyIHN0cnVjdCB7Cgkqc3IuRXh0ZXJuYWxJbmNlbnRpdmUKfQoKLy8gaXNBY3RpdmUgY2hlY2tzIGlmIHRoZSBpbmNlbnRpdmUgaXMgY3VycmVudGx5IGFjdGl2ZSBhdCB0aGUgZ2l2ZW4gdGltZXN0YW1wCmZ1bmMgKHNlbGYgKkV4dGVybmFsSW5jZW50aXZlUmVzb2x2ZXIpIGlzQWN0aXZlKGN1cnJlbnRUaW1lc3RhbXAgaW50NjQpIGJvb2wgewoJcmV0dXJuIGN1cnJlbnRUaW1lc3RhbXAgPj0gc2VsZi5TdGFydFRpbWVzdGFtcCgpICYmIGN1cnJlbnRUaW1lc3RhbXAgPD0gc2VsZi5FbmRUaW1lc3RhbXAoKQp9CgovLyBJc0VuZGVkIHJlcG9ydHMgd2hldGhlciBhbiBleHRlcm5hbCBpbmNlbnRpdmUncyBkaXN0cmlidXRpb24gd2luZG93IGhhcyBlbmRlZC4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGN1cnJlbnRUaW1lc3RhbXA6IFRpbWVzdGFtcCBpbiBVbml4IHNlY29uZHMgdG8gY29tcGFyZSB3aXRoIHRoZSBpbmNlbnRpdmUgZW5kIHRpbWUuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBlbmRlZDogVHJ1ZSB3aGVuIGN1cnJlbnRUaW1lc3RhbXAgaXMgYWZ0ZXIgdGhlIGluY2x1c2l2ZSBlbmQgdGltZXN0YW1wOyBmYWxzZSBvdGhlcndpc2UuCmZ1bmMgKHNlbGYgKkV4dGVybmFsSW5jZW50aXZlUmVzb2x2ZXIpIElzRW5kZWQoY3VycmVudFRpbWVzdGFtcCBpbnQ2NCkgYm9vbCB7CglyZXR1cm4gY3VycmVudFRpbWVzdGFtcCA+IHNlbGYuRW5kVGltZXN0YW1wKCkKfQoKLy8gSXNTdGFydGVkIHJlcG9ydHMgd2hldGhlciBhbiBleHRlcm5hbCBpbmNlbnRpdmUncyBkaXN0cmlidXRpb24gd2luZG93IGhhcyBvcGVuZWQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBjdXJyZW50VGltZXN0YW1wOiBUaW1lc3RhbXAgaW4gVW5peCBzZWNvbmRzIHRvIGNvbXBhcmUgd2l0aCB0aGUgaW5jZW50aXZlIHN0YXJ0IHRpbWUuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBzdGFydGVkOiBUcnVlIHdoZW4gY3VycmVudFRpbWVzdGFtcCBpcyBhdCBvciBhZnRlciB0aGUgaW5jZW50aXZlIHN0YXJ0IHRpbWVzdGFtcDsgZmFsc2Ugb3RoZXJ3aXNlLgpmdW5jIChzZWxmICpFeHRlcm5hbEluY2VudGl2ZVJlc29sdmVyKSBJc1N0YXJ0ZWQoY3VycmVudFRpbWVzdGFtcCBpbnQ2NCkgYm9vbCB7CglyZXR1cm4gY3VycmVudFRpbWVzdGFtcCA+PSBzZWxmLlN0YXJ0VGltZXN0YW1wKCkKfQoKLy8gYWRkRGlzdHJpYnV0ZWRSZXdhcmRBbW91bnQgYWRkcyB0aGUgZ2l2ZW4gYW1vdW50IHRvIHRoZSBkaXN0cmlidXRlZCByZXdhcmQgYW1vdW50LgovLyBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gYWRkIHRoZSBkaXN0cmlidXRlZCByZXdhcmQgYW1vdW50IHdoZW4gdGhlIGluY2VudGl2ZSBpcyB1bi1zdGFrZWQgYW5kIHJlZnVuZGVkLgpmdW5jIChzZWxmICpFeHRlcm5hbEluY2VudGl2ZVJlc29sdmVyKSBhZGREaXN0cmlidXRlZFJld2FyZEFtb3VudChhbW91bnQgaW50NjQpIHsKCWRpc3RyaWJ1dGVkUmV3YXJkQW1vdW50IDo9IGduc21hdGguU2FmZUFkZEludDY0KHNlbGYuRGlzdHJpYnV0ZWRSZXdhcmRBbW91bnQoKSwgYW1vdW50KQoJc2VsZi5TZXREaXN0cmlidXRlZFJld2FyZEFtb3VudChkaXN0cmlidXRlZFJld2FyZEFtb3VudCkKfQoKLy8gYWRkQWNjdW11bGF0ZWRQZW5hbHR5QW1vdW50IGFkZHMgdGhlIGdpdmVuIGFtb3VudCB0byB0aGUgYWNjdW11bGF0ZWQgcGVuYWx0eSBhbW91bnQuCi8vIENhbGxlZCBkdXJpbmcgQ29sbGVjdFJld2FyZCB0byB0cmFjayB3YXJtdXAgcGVuYWx0aWVzIGZvciBsYXRlciBjb2xsZWN0aW9uLgpmdW5jIChzZWxmICpFeHRlcm5hbEluY2VudGl2ZVJlc29sdmVyKSBhZGRBY2N1bXVsYXRlZFBlbmFsdHlBbW91bnQoYW1vdW50IGludDY0KSB7CglhY2N1bXVsYXRlZFBlbmFsdHlBbW91bnQgOj0gZ25zbWF0aC5TYWZlQWRkSW50NjQoc2VsZi5BY2N1bXVsYXRlZFBlbmFsdHlBbW91bnQoKSwgYW1vdW50KQoJc2VsZi5TZXRBY2N1bXVsYXRlZFBlbmFsdHlBbW91bnQoYWNjdW11bGF0ZWRQZW5hbHR5QW1vdW50KQp9CgovLyBOZXdFeHRlcm5hbEluY2VudGl2ZVJlc29sdmVyIHdyYXBzIGFuIGV4dGVybmFsIGluY2VudGl2ZSB3aXRoIHJlc29sdmVyIG9wZXJhdGlvbnMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBleHRlcm5hbEluY2VudGl2ZTogRXh0ZXJuYWwgaW5jZW50aXZlIHdob3NlIHRpbWVzdGFtcHMgYW5kIGFjY291bnRpbmcgc3RhdGUgdGhlIHJlc29sdmVyIGV4cG9zZXMuCi8vCi8vIFJldHVybnM6Ci8vICAgLSByZXNvbHZlcjogUmVzb2x2ZXIgYmFja2VkIGJ5IGV4dGVybmFsSW5jZW50aXZlLgpmdW5jIE5ld0V4dGVybmFsSW5jZW50aXZlUmVzb2x2ZXIoCglleHRlcm5hbEluY2VudGl2ZSAqc3IuRXh0ZXJuYWxJbmNlbnRpdmUsCikgKkV4dGVybmFsSW5jZW50aXZlUmVzb2x2ZXIgewoJcmV0dXJuICZFeHRlcm5hbEluY2VudGl2ZVJlc29sdmVyewoJCUV4dGVybmFsSW5jZW50aXZlOiBleHRlcm5hbEluY2VudGl2ZSwKCX0KfQoKdHlwZSBEZXBvc2l0UmVzb2x2ZXIgc3RydWN0IHsKCSpzci5EZXBvc2l0Cn0KCi8vIEludGVybmFsUmV3YXJkTGFzdENvbGxlY3RUaW1lIHJldHVybnMgdGhlIGxhc3QgY29sbGVjdCB0aW1lIGZvciB0aGUgaW50ZXJuYWwgcmV3YXJkLgovLyBJZiB0aGUgbGFzdCBjb2xsZWN0IHRpbWUgaXMgMCwgaXQgcmV0dXJucyB0aGUgc3Rha2VkIHRpbWUuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBsYXN0Q29sbGVjdFRpbWU6IExhc3QgaW50ZXJuYWwgcmV3YXJkIGNvbGxlY3Rpb24gdGltZSBpbiBVbml4IHNlY29uZHMsIGZhbGxpbmcgYmFjayB0byBTdGFrZVRpbWUgd2hlbiB0aGUgc3RvcmVkIGN1cnNvciBpcyB6ZXJvLgpmdW5jIChzZWxmICpEZXBvc2l0UmVzb2x2ZXIpIEludGVybmFsUmV3YXJkTGFzdENvbGxlY3RUaW1lKCkgaW50NjQgewoJaWYgc2VsZi5EZXBvc2l0LkludGVybmFsUmV3YXJkTGFzdENvbGxlY3RUaW1lKCkgPT0gMCB7CgkJcmV0dXJuIHNlbGYuRGVwb3NpdC5TdGFrZVRpbWUoKQoJfQoKCXJldHVybiBzZWxmLkRlcG9zaXQuSW50ZXJuYWxSZXdhcmRMYXN0Q29sbGVjdFRpbWUoKQp9CgovLyBFeHRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZSByZXR1cm5zIHRoZSBsYXN0IGNvbGxlY3QgdGltZSBmb3IgdGhlIGV4dGVybmFsIHJld2FyZCBmb3IgdGhlIGdpdmVuIGluY2VudGl2ZSBJRC4KLy8gSWYgdGhlIGxhc3QgY29sbGVjdCB0aW1lIGlzIDAsIGl0IHJldHVybnMgdGhlIHN0YWtlZCB0aW1lLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gaW5jZW50aXZlSUQ6IEV4dGVybmFsIGluY2VudGl2ZSBJRCB3aG9zZSBjb2xsZWN0aW9uIGN1cnNvciBzaG91bGQgYmUgcmVzb2x2ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBsYXN0Q29sbGVjdFRpbWU6IExhc3QgY29sbGVjdGlvbiB0aW1lIGluIFVuaXggc2Vjb25kcywgZmFsbGluZyBiYWNrIHRvIFN0YWtlVGltZSB3aGVuIG5vIG5vbnplcm8gY3Vyc29yIGlzIHN0b3JlZC4KZnVuYyAoc2VsZiAqRGVwb3NpdFJlc29sdmVyKSBFeHRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZShpbmNlbnRpdmVJRCBzdHJpbmcpIGludDY0IHsKCWxhc3RDb2xsZWN0VGltZSwgZXhpc3RzIDo9IHNlbGYuRGVwb3NpdC5HZXRFeHRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZShpbmNlbnRpdmVJRCkKCWlmICFleGlzdHMgfHwgbGFzdENvbGxlY3RUaW1lID09IDAgewoJCXJldHVybiBzZWxmLkRlcG9zaXQuU3Rha2VUaW1lKCkKCX0KCglyZXR1cm4gbGFzdENvbGxlY3RUaW1lCn0KCi8vIENvbGxlY3RlZEV4dGVybmFsUmV3YXJkIHJldHVybnMgdGhlIGFtb3VudCBhbHJlYWR5IGNvbGxlY3RlZCBmb3Igb25lIGV4dGVybmFsIGluY2VudGl2ZS4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIGluY2VudGl2ZUlEOiBFeHRlcm5hbCBpbmNlbnRpdmUgSUQgd2hvc2UgY29sbGVjdGVkIGFtb3VudCBzaG91bGQgYmUgcmVzb2x2ZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBjb2xsZWN0ZWRSZXdhcmQ6IEN1bXVsYXRpdmUgYW1vdW50IGNvbGxlY3RlZCBmb3IgaW5jZW50aXZlSUQsIG9yIDAgd2hlbiBubyBhbW91bnQgaXMgc3RvcmVkLgpmdW5jIChzZWxmICpEZXBvc2l0UmVzb2x2ZXIpIENvbGxlY3RlZEV4dGVybmFsUmV3YXJkKGluY2VudGl2ZUlEIHN0cmluZykgaW50NjQgewoJY29sbGVjdGVkRXh0ZXJuYWxSZXdhcmQsIGV4aXN0cyA6PSBzZWxmLkRlcG9zaXQuR2V0Q29sbGVjdGVkRXh0ZXJuYWxSZXdhcmQoaW5jZW50aXZlSUQpCglpZiAhZXhpc3RzIHsKCQlyZXR1cm4gMAoJfQoKCXJldHVybiBjb2xsZWN0ZWRFeHRlcm5hbFJld2FyZAp9CgpmdW5jIChzZWxmICpEZXBvc2l0UmVzb2x2ZXIpIGFkZENvbGxlY3RlZEludGVybmFsUmV3YXJkKHJld2FyZCBpbnQ2NCkgewoJc2VsZi5TZXRDb2xsZWN0ZWRJbnRlcm5hbFJld2FyZChnbnNtYXRoLlNhZmVBZGRJbnQ2NChzZWxmLkNvbGxlY3RlZEludGVybmFsUmV3YXJkKCksIHJld2FyZCkpCn0KCmZ1bmMgKHNlbGYgKkRlcG9zaXRSZXNvbHZlcikgYWRkQ29sbGVjdGVkRXh0ZXJuYWxSZXdhcmQoaW5jZW50aXZlSUQgc3RyaW5nLCByZXdhcmQgaW50NjQpIHsKCWNvbGxlY3RlZEV4dGVybmFsUmV3YXJkIDo9IGduc21hdGguU2FmZUFkZEludDY0KHNlbGYuQ29sbGVjdGVkRXh0ZXJuYWxSZXdhcmQoaW5jZW50aXZlSUQpLCByZXdhcmQpCglzZWxmLlNldENvbGxlY3RlZEV4dGVybmFsUmV3YXJkKGluY2VudGl2ZUlELCBjb2xsZWN0ZWRFeHRlcm5hbFJld2FyZCkKfQoKLy8gdXBkYXRlSW50ZXJuYWxSZXdhcmRMYXN0Q29sbGVjdFRpbWUgdXBkYXRlcyB0aGUgbGFzdCBjb2xsZWN0IHRpbWUgZm9yIHRoZSBpbnRlcm5hbCByZXdhcmQuCi8vIEl0IHJldHVybnMgYW4gZXJyb3IgaWYgdGhlIGN1cnJlbnQgdGltZSBpcyBsZXNzIHRoYW4gdGhlIGxhc3QgY29sbGVjdCB0aW1lIGZvciB0aGUgaW50ZXJuYWwgcmV3YXJkLgpmdW5jIChzZWxmICpEZXBvc2l0UmVzb2x2ZXIpIHVwZGF0ZUludGVybmFsUmV3YXJkTGFzdENvbGxlY3RUaW1lKGN1cnJlbnRUaW1lIGludDY0KSBlcnJvciB7CglpZiBzZWxmLkludGVybmFsUmV3YXJkTGFzdENvbGxlY3RUaW1lKCkgPiBjdXJyZW50VGltZSB7CgkJcmV0dXJuIG1ha2VFcnJvcldpdGhEZXRhaWxzKGVyck5vdEF2YWlsYWJsZVVwZGF0ZUNvbGxlY3RUaW1lLCAiY3VycmVudFRpbWUgbXVzdCBiZSBncmVhdGVyIHRoYW4gaW50ZXJuYWwgcmV3YXJkIGxhc3QgY29sbGVjdCB0aW1lIikKCX0KCglzZWxmLlNldEludGVybmFsUmV3YXJkTGFzdENvbGxlY3RUaW1lKGN1cnJlbnRUaW1lKQoKCXJldHVybiBuaWwKfQoKLy8gdXBkYXRlRXh0ZXJuYWxSZXdhcmRMYXN0Q29sbGVjdFRpbWUgbGF6aWx5IHVwZGF0ZXMgdGhlIGxhc3QgY29sbGVjdCB0aW1lIGZvciB0aGUgZXh0ZXJuYWwgcmV3YXJkIGZvciB0aGUgZ2l2ZW4gaW5jZW50aXZlIElELgovLyBJdCByZXR1cm5zIGFuIGVycm9yIGlmIHRoZSBjdXJyZW50IHRpbWUgaXMgbGVzcyB0aGFuIHRoZSBsYXN0IGNvbGxlY3QgdGltZSBmb3IgdGhlIGV4dGVybmFsIHJld2FyZCBmb3IgdGhlIGdpdmVuIGluY2VudGl2ZSBJRC4KZnVuYyAoc2VsZiAqRGVwb3NpdFJlc29sdmVyKSB1cGRhdGVFeHRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZShpbmNlbnRpdmVJRCBzdHJpbmcsIGN1cnJlbnRUaW1lIGludDY0KSBlcnJvciB7CglpZiBzZWxmLkV4dGVybmFsUmV3YXJkTGFzdENvbGxlY3RUaW1lcygpID09IG5pbCB7CgkJc2VsZi5TZXRFeHRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZXMobWFrZShtYXBbc3RyaW5nXWludDY0KSkKCX0KCglleHRlcm5hbExhc3RDb2xsZWN0VGltZSwgZXhpc3RzIDo9IHNlbGYuRGVwb3NpdC5HZXRFeHRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZShpbmNlbnRpdmVJRCkKCWlmIGV4aXN0cyAmJiBleHRlcm5hbExhc3RDb2xsZWN0VGltZSA+IGN1cnJlbnRUaW1lIHsKCQlyZXR1cm4gbWFrZUVycm9yV2l0aERldGFpbHMoZXJyTm90QXZhaWxhYmxlVXBkYXRlQ29sbGVjdFRpbWUsICJjdXJyZW50VGltZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiBleHRlcm5hbCByZXdhcmQgbGFzdCBjb2xsZWN0IHRpbWUiKQoJfQoKCXNlbGYuRGVwb3NpdC5TZXRFeHRlcm5hbFJld2FyZExhc3RDb2xsZWN0VGltZShpbmNlbnRpdmVJRCwgY3VycmVudFRpbWUpCgoJcmV0dXJuIG5pbAp9CgovLyBGaW5kV2FybXVwIHJldHVybnMgdGhlIGZpcnN0IHdhcm11cCB0aWVyIHdob3NlIGVuZCB0aW1lIGlzIGFmdGVyIGN1cnJlbnRUaW1lLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gY3VycmVudFRpbWU6IFRpbWVzdGFtcCBpbiBVbml4IHNlY29uZHMgdXNlZCB0byBzZWxlY3QgdGhlIGFjdGl2ZSB3YXJtdXAgdGllci4KLy8KLy8gUmV0dXJuczoKLy8gICAtIGluZGV4OiBJbmRleCBvZiB0aGUgZmlyc3QgdGllciB3aXRoIGEgbGF0ZXIgTmV4dFdhcm11cFRpbWUsIG9yIHRoZSBmaW5hbCB0aWVyJ3MgaW5kZXggd2hlbiBhbGwgdGllcnMgaGF2ZSBlbmRlZC4KZnVuYyAoc2VsZiAqRGVwb3NpdFJlc29sdmVyKSBGaW5kV2FybXVwKGN1cnJlbnRUaW1lIGludDY0KSBpbnQgewoJZm9yIGksIHdhcm11cCA6PSByYW5nZSBzZWxmLldhcm11cHMoKSB7CgkJaWYgY3VycmVudFRpbWUgPCB3YXJtdXAuTmV4dFdhcm11cFRpbWUgewoJCQlyZXR1cm4gaQoJCX0KCX0KCXJldHVybiBsZW4oc2VsZi5XYXJtdXBzKCkpIC0gMQp9CgovLyBHZXRXYXJtdXAgcmV0dXJucyB0aGUgd2FybXVwIHRpZXIgYXQgaW5kZXguCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBpbmRleDogWmVyby1iYXNlZCB3YXJtdXAtdGllciBpbmRleDsgYW4gb3V0LW9mLXJhbmdlIGluZGV4IHBhbmljcyB0aHJvdWdoIHNsaWNlIGluZGV4aW5nLgovLwovLyBSZXR1cm5zOgovLyAgIC0gd2FybXVwOiBXYXJtdXAgdGllciBzdG9yZWQgYXQgaW5kZXguCmZ1bmMgKHNlbGYgKkRlcG9zaXRSZXNvbHZlcikgR2V0V2FybXVwKGluZGV4IGludCkgc3IuV2FybXVwIHsKCXJldHVybiBzZWxmLldhcm11cHMoKVtpbmRleF0KfQoKLy8gTmV3RGVwb3NpdFJlc29sdmVyIHdyYXBzIGEgZGVwb3NpdCB3aXRoIHJld2FyZC1jdXJzb3IgYW5kIHdhcm11cCByZXNvbHV0aW9uIGhlbHBlcnMuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBkZXBvc2l0OiBEZXBvc2l0IHdob3NlIHBlcnNpc3RlZCByZXdhcmQgc3RhdGUgc2hvdWxkIGJlIHJlc29sdmVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gcmVzb2x2ZXI6IFJlc29sdmVyIGJhY2tlZCBieSBkZXBvc2l0LgpmdW5jIE5ld0RlcG9zaXRSZXNvbHZlcigKCWRlcG9zaXQgKnNyLkRlcG9zaXQsCikgKkRlcG9zaXRSZXNvbHZlciB7CglyZXR1cm4gJkRlcG9zaXRSZXNvbHZlcnsKCQlEZXBvc2l0OiBkZXBvc2l0LAoJfQp9ChqlQQoVdW5zdGFrZWRfcG9zaXRpb24uZ25vEotBcGFja2FnZSBzdGFrZXIKCmltcG9ydCAoCgkiY2hhaW4iCgkiY2hhaW4vcnVudGltZSIKCSJ0aW1lIgoKCWJwdHJlZSAiZ25vLmxhbmQvcC9udC9icHRyZWUvdjAiCgl1Zm10ICJnbm8ubGFuZC9wL250L3VmbXQvdjAiCgoJImduby5sYW5kL3AvZ25vc3dhcC9nbnNtYXRoL3YxIgoJImduby5sYW5kL3AvZ25vc3dhcC91dGlscy92MSIKCglzciAiZ25vLmxhbmQvci9nbm9zd2FwL3N0YWtlciIKKQoKLy8gVW5zdGFrZWRQb3NpdGlvbnMgbWFuYWdlcyBleGl0IGNoZWNrcG9pbnRzLgp0eXBlIFVuc3Rha2VkUG9zaXRpb25zIHN0cnVjdCB7Cgl0cmVlICpicHRyZWUuQlBUcmVlCn0KCi8vIE5ld1Vuc3Rha2VkUG9zaXRpb25zIGNyZWF0ZXMgYSBuZXcgVW5zdGFrZWRQb3NpdGlvbnMgaW5zdGFuY2UuCi8vCi8vIFJldHVybnM6Ci8vICAgLSAqVW5zdGFrZWRQb3NpdGlvbnM6IEVtcHR5IGV4aXQtY2hlY2twb2ludCBtYW5hZ2VyIGJhY2tlZCBieSBhIG5ldyBCKyB0cmVlLgpmdW5jIE5ld1Vuc3Rha2VkUG9zaXRpb25zKCkgKlVuc3Rha2VkUG9zaXRpb25zIHsKCXJldHVybiAmVW5zdGFrZWRQb3NpdGlvbnN7CgkJdHJlZTogc3IuTmV3QlBUcmVlTigxNiksIC8vIHBvc2l0aW9uSWQgLT4gKlVuc3Rha2VkUG9zaXRpb24KCX0KfQoKLy8gSGFzIGNoZWNrcyBpZiBhIHBvc2l0aW9uIElEIGhhcyBhbiBleGl0IGNoZWNrcG9pbnQuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb3NpdGlvbklkOiBQb3NpdGlvbiBJRCB3aG9zZSBleGl0LWNoZWNrcG9pbnQgbWVtYmVyc2hpcCBpcyBjaGVja2VkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gYm9vbDogdHJ1ZSB3aGVuIGFuIGV4aXQgY2hlY2twb2ludCBleGlzdHMgZm9yIHBvc2l0aW9uSWQ7IGZhbHNlIG90aGVyd2lzZS4KZnVuYyAoc2VsZiAqVW5zdGFrZWRQb3NpdGlvbnMpIEhhcyhwb3NpdGlvbklkIHVpbnQ2NCkgYm9vbCB7CglyZXR1cm4gc2VsZi50cmVlLkhhcyh1dGlscy5FbmNvZGVVaW50NjQocG9zaXRpb25JZCkpCn0KCi8vIGdldCByZXRyaWV2ZXMgYW4gZXhpdCBjaGVja3BvaW50IGJ5IHBvc2l0aW9uIElELCBvciBuaWwgd2hlbiB0aGVyZSBpcyBub25lLgpmdW5jIChzZWxmICpVbnN0YWtlZFBvc2l0aW9ucykgZ2V0KHBvc2l0aW9uSWQgdWludDY0KSAqc3IuVW5zdGFrZWRQb3NpdGlvbiB7Cgl2YWx1ZSA6PSBzZWxmLnRyZWUuR2V0KHV0aWxzLkVuY29kZVVpbnQ2NChwb3NpdGlvbklkKSkKCWlmIHZhbHVlID09IG5pbCB7CgkJcmV0dXJuIG5pbAoJfQoKCXBvc2l0aW9uLCBvayA6PSB2YWx1ZS4oKnNyLlVuc3Rha2VkUG9zaXRpb24pCglpZiAhb2sgewoJCXBhbmljKHVmbXQuU3ByaW50ZigiZmFpbGVkIHRvIGNhc3QgdmFsdWUgdG8gKlVuc3Rha2VkUG9zaXRpb246ICVUIiwgdmFsdWUpKQoJfQoKCXJldHVybiBwb3NpdGlvbgp9CgovLyBzZXQgc3RvcmVzIGFuIGV4aXQgY2hlY2twb2ludCBmb3IgYSBwb3NpdGlvbiBJRC4KZnVuYyAoc2VsZiAqVW5zdGFrZWRQb3NpdGlvbnMpIHNldChwb3NpdGlvbklkIHVpbnQ2NCwgcG9zaXRpb24gKnNyLlVuc3Rha2VkUG9zaXRpb24pIHsKCXNlbGYudHJlZS5TZXQodXRpbHMuRW5jb2RlVWludDY0KHBvc2l0aW9uSWQpLCBwb3NpdGlvbikKfQoKLy8gcmVtb3ZlIGRlbGV0ZXMgYW4gZXhpdCBjaGVja3BvaW50IGJ5IHBvc2l0aW9uIElELgpmdW5jIChzZWxmICpVbnN0YWtlZFBvc2l0aW9ucykgcmVtb3ZlKHBvc2l0aW9uSWQgdWludDY0KSB7CglzZWxmLnRyZWUuUmVtb3ZlKHV0aWxzLkVuY29kZVVpbnQ2NChwb3NpdGlvbklkKSkKfQoKLy8gZ2V0VW5zdGFrZWRQb3NpdGlvbnMgcmV0dXJucyB0aGUgZXhpdCBjaGVja3BvaW50cyBiYWNrZWQgYnkgdGhlIHN0b3JlLgpmdW5jIChzICpzdGFrZXJWMSkgZ2V0VW5zdGFrZWRQb3NpdGlvbnMoKSAqVW5zdGFrZWRQb3NpdGlvbnMgewoJcmV0dXJuICZVbnN0YWtlZFBvc2l0aW9uc3t0cmVlOiBzLnN0b3JlLkdldFVuc3Rha2VkUG9zaXRpb25zKCl9Cn0KCi8vIHVuY29sbGVjdGVkSW5jZW50aXZlQ291bnRPZiByZXR1cm5zIGhvdyBtYW55IGNoZWNrcG9pbnRzIHN0aWxsIG93ZSB0aGUgaW5jZW50aXZlLgovLwovLyBUaGUgY291bnQgaXMgcGVyIGluY2VudGl2ZSwgbm90IHBlciBwb29sOiBvbmUgY2hlY2twb2ludCB0aGF0IGNhbiBuZXZlciBiZSBmdW5kZWQgd291bGQKLy8gb3RoZXJ3aXNlIGxvY2sgdGhlIHJlZnVuZHMgb2YgZXZlcnkgb3RoZXIgaW5jZW50aXZlIGluIHRoZSBzYW1lIHBvb2wuCmZ1bmMgKHMgKnN0YWtlclYxKSB1bmNvbGxlY3RlZEluY2VudGl2ZUNvdW50T2YoaW5jZW50aXZlSWQgc3RyaW5nKSBpbnQ2NCB7Cgl2YWx1ZSA6PSBzLnN0b3JlLkdldFVuY29sbGVjdGVkSW5jZW50aXZlQ291bnRzKCkuR2V0KGluY2VudGl2ZUlkKQoJaWYgdmFsdWUgPT0gbmlsIHsKCQlyZXR1cm4gMAoJfQoKCWNvdW50LCBvayA6PSB2YWx1ZS4oaW50NjQpCglpZiAhb2sgewoJCXBhbmljKHVmbXQuU3ByaW50ZigiZmFpbGVkIHRvIGNhc3QgdW5jb2xsZWN0ZWQgaW5jZW50aXZlIGNvdW50IHRvIGludDY0OiAlVCIsIHZhbHVlKSkKCX0KCglyZXR1cm4gY291bnQKfQoKLy8gYWRkVW5jb2xsZWN0ZWRJbmNlbnRpdmVDb3VudCBtb3ZlcyB0aGUgaW5jZW50aXZlJ3MgY291bnQgYnkgZGVsdGEsIGRyb3BwaW5nIHRoZSBlbnRyeSBhdCB6ZXJvLgpmdW5jIChzICpzdGFrZXJWMSkgYWRkVW5jb2xsZWN0ZWRJbmNlbnRpdmVDb3VudChpbmNlbnRpdmVJZCBzdHJpbmcsIGRlbHRhIGludDY0KSB7CglhZGRVbmNvbGxlY3RlZEluY2VudGl2ZUNvdW50VG8ocy5zdG9yZS5HZXRVbmNvbGxlY3RlZEluY2VudGl2ZUNvdW50cygpLCBpbmNlbnRpdmVJZCwgZGVsdGEpCn0KCmZ1bmMgYWRkVW5jb2xsZWN0ZWRJbmNlbnRpdmVDb3VudFRvKGNvdW50cyAqYnB0cmVlLkJQVHJlZSwgaW5jZW50aXZlSWQgc3RyaW5nLCBkZWx0YSBpbnQ2NCkgewoJY291bnQgOj0gaW50NjQoMCkKCWlmIHZhbHVlIDo9IGNvdW50cy5HZXQoaW5jZW50aXZlSWQpOyB2YWx1ZSAhPSBuaWwgewoJCWNhc3RlZCwgb2sgOj0gdmFsdWUuKGludDY0KQoJCWlmICFvayB7CgkJCXBhbmljKHVmbXQuU3ByaW50ZigiZmFpbGVkIHRvIGNhc3QgdW5jb2xsZWN0ZWQgaW5jZW50aXZlIGNvdW50IHRvIGludDY0OiAlVCIsIHZhbHVlKSkKCQl9CgkJY291bnQgPSBjYXN0ZWQKCX0KCgluZXh0IDo9IGduc21hdGguU2FmZUFkZEludDY0KGNvdW50LCBkZWx0YSkKCWlmIG5leHQgPCAwIHsKCQlwYW5pYyhtYWtlRXJyb3JXaXRoRGV0YWlscygKCQkJZXJyQ2FsY3VsYXRpb25FcnJvciwKCQkJdWZtdC5TcHJpbnRmKCJ1bmNvbGxlY3RlZCBjb3VudCBvZiBpbmNlbnRpdmUoJXMpIHdlbnQgbmVnYXRpdmUiLCBpbmNlbnRpdmVJZCksCgkJKSkKCX0KCglpZiBuZXh0ID09IDAgewoJCWNvdW50cy5SZW1vdmUoaW5jZW50aXZlSWQpCgkJcmV0dXJuCgl9CgoJY291bnRzLlNldChpbmNlbnRpdmVJZCwgbmV4dCkKfQoKLy8gcmVjb3JkVW5zdGFrZWRQb3NpdGlvbiB3cml0ZXMgdGhlIGV4aXQgY2hlY2twb2ludCBiZWZvcmUgdGhlIHRlYXJkb3duIHRvdWNoZXMgdGhlIHBvb2wuCi8vIFRoZSBkZXBvc2l0J3MgaW5jZW50aXZlIGluZGV4IGlzIGJyb3VnaHQgdXAgdG8gZGF0ZSBmaXJzdCwgc28gdGhlIGNoZWNrcG9pbnQgb3dlcyBleGFjdGx5Ci8vIHRoZSBpbmNlbnRpdmVzIHRoZSBwb3NpdGlvbiBhY2NydWVkIGZyb20uCmZ1bmMgKHMgKnN0YWtlclYxKSByZWNvcmRVbnN0YWtlZFBvc2l0aW9uKF8gaW50LCBybG0gcmVhbG0sIHBvc2l0aW9uSWQgdWludDY0LCBkZXBvc2l0ICpzci5EZXBvc2l0LCBleGl0VGltZSBpbnQ2NCkgKnNyLlVuc3Rha2VkUG9zaXRpb24gewoJcG9vbFBhdGggOj0gZGVwb3NpdC5UYXJnZXRQb29sUGF0aCgpCgoJcG9vbCwgb2sgOj0gcy5nZXRQb29scygpLkdldChwb29sUGF0aCkKCWlmICFvayB7CgkJcGFuaWMobWFrZUVycm9yV2l0aERldGFpbHMoCgkJCWVyckRhdGFOb3RGb3VuZCwKCQkJdWZtdC5TcHJpbnRmKCJwb29sKCVzKSBkb2VzIG5vdCBleGlzdCIsIHBvb2xQYXRoKSwKCQkpKQoJfQoKCXBvb2xSZXNvbHZlciA6PSBOZXdQb29sUmVzb2x2ZXIocG9vbCkKCWRlcG9zaXRSZXNvbHZlciA6PSBOZXdEZXBvc2l0UmVzb2x2ZXIoZGVwb3NpdCkKCglsYXN0VXBkYXRlZEF0IDo9IGRlcG9zaXRSZXNvbHZlci5MYXN0RXh0ZXJuYWxJbmNlbnRpdmVVcGRhdGVkQXQoKQoJaWYgbGFzdFVwZGF0ZWRBdCA8IGV4aXRUaW1lIHsKCQlwb29sUmVzb2x2ZXIuSW5jZW50aXZlc1Jlc29sdmVyKCkuSXRlcmF0ZUluY2VudGl2ZUlkc0J5VGltZShsYXN0VXBkYXRlZEF0LCBleGl0VGltZSwgZnVuYyhpbmNlbnRpdmVJZCBzdHJpbmcpIGJvb2wgewoJCQlkZXBvc2l0LkFkZEV4dGVybmFsSW5jZW50aXZlSWQoaW5jZW50aXZlSWQpCgkJCXJldHVybiBmYWxzZQoJCX0pCgkJZGVwb3NpdC5TZXRMYXN0RXh0ZXJuYWxJbmNlbnRpdmVVcGRhdGVkQXQoZXhpdFRpbWUpCgl9CgoJdGllciwgdGllclJhdGlvLCB0aWVyQ291bnQsIGVyciA6PSBzLmdldFBvb2xUaWVyKCkudGllckNvbnRleHRPZihwb29sUGF0aCkKCWlmIGVyciAhPSBuaWwgewoJCXBhbmljKGVycikKCX0KCglsb3dlclRpY2sgOj0gcG9vbFJlc29sdmVyLkdldE9yTmV3VGljayhkZXBvc2l0LlRpY2tMb3dlcigpKQoJdXBwZXJUaWNrIDo9IHBvb2xSZXNvbHZlci5HZXRPck5ld1RpY2soZGVwb3NpdC5UaWNrVXBwZXIoKSkKCWluY2VudGl2ZUlkcyA6PSBkZXBvc2l0LkdldEV4dGVybmFsSW5jZW50aXZlSWRMaXN0KCkKCglwb3NpdGlvbiA6PSBzci5OZXdVbnN0YWtlZFBvc2l0aW9uKAoJCWRlcG9zaXQsCgkJZXhpdFRpbWUsCgkJcG9vbFJlc29sdmVyLkN1cnJlbnRUaWNrKGV4aXRUaW1lKSwKCQlsb3dlclRpY2ssCgkJdXBwZXJUaWNrLAoJCU5ld1RpY2tSZXNvbHZlcihsb3dlclRpY2spLkN1cnJlbnRPdXRzaWRlQWNjdW11bGF0aW9uKGV4aXRUaW1lKS5Ub1N0cmluZygpLAoJCU5ld1RpY2tSZXNvbHZlcih1cHBlclRpY2spLkN1cnJlbnRPdXRzaWRlQWNjdW11bGF0aW9uKGV4aXRUaW1lKS5Ub1N0cmluZygpLAoJCXRpZXIsCgkJdGllclJhdGlvLAoJCXRpZXJDb3VudCwKCQlzLkdldFVuc3Rha2luZ0ZlZSgpLAoJCWluY2VudGl2ZUlkcywKCSkKCglzLmdldFVuc3Rha2VkUG9zaXRpb25zKCkuc2V0KHBvc2l0aW9uSWQsIHBvc2l0aW9uKQoKCWNvdW50cyA6PSBzLnN0b3JlLkdldFVuY29sbGVjdGVkSW5jZW50aXZlQ291bnRzKCkKCWZvciBfLCBpbmNlbnRpdmVJZCA6PSByYW5nZSBpbmNlbnRpdmVJZHMgewoJCWFkZFVuY29sbGVjdGVkSW5jZW50aXZlQ291bnRUbyhjb3VudHMsIGluY2VudGl2ZUlkLCAxKQoJfQoKCXJldHVybiBwb3NpdGlvbgp9CgovLyBkcm9wVW5zdGFrZWRQb3NpdGlvbklmQ29sbGVjdGVkIHJlbW92ZXMgdGhlIGNoZWNrcG9pbnQgb25jZSBldmVyeSByZXdhcmQgc291cmNlIGlzIGNvbGxlY3RlZC4KZnVuYyAocyAqc3Rha2VyVjEpIGRyb3BVbnN0YWtlZFBvc2l0aW9uSWZDb2xsZWN0ZWQoXyBpbnQsIHJsbSByZWFsbSwgdGFyZ2V0ICpjb2xsZWN0VGFyZ2V0KSB7CglpZiAhdGFyZ2V0LmNoZWNrcG9pbnQuRnVsbHlDb2xsZWN0ZWQoKSB7CgkJcmV0dXJuCgl9CgoJcy5nZXRVbnN0YWtlZFBvc2l0aW9ucygpLnJlbW92ZSh0YXJnZXQucG9zaXRpb25JZCkKCglwcmV2aW91c1JlYWxtIDo9IHJsbS5QcmV2aW91cygpCgljaGFpbi5FbWl0KAoJCSJDbGVhclVuc3Rha2VkUG9zaXRpb24iLAoJCSJwcmV2QWRkciIsIHByZXZpb3VzUmVhbG0uQWRkcmVzcygpLlN0cmluZygpLAoJCSJwcmV2UmVhbG0iLCBwcmV2aW91c1JlYWxtLlBrZ1BhdGgoKSwKCQkicG9zaXRpb25JZCIsIHV0aWxzLkZvcm1hdFVpbnQodGFyZ2V0LnBvc2l0aW9uSWQpLAoJCSJwb29sUGF0aCIsIHRhcmdldC5kZXBvc2l0LlRhcmdldFBvb2xQYXRoKCksCgkJImV4aXRUaW1lIiwgdXRpbHMuRm9ybWF0SW50KHRhcmdldC5jaGVja3BvaW50LkV4aXRUaW1lKCkpLAoJCSJjdXJyZW50VGltZSIsIHV0aWxzLkZvcm1hdEludCh0aW1lLk5vdygpLlVuaXgoKSksCgkJImN1cnJlbnRIZWlnaHQiLCB1dGlscy5Gb3JtYXRJbnQocnVudGltZS5DaGFpbkhlaWdodCgpKSwKCSkKfQoKLy8gSGFzVW5zdGFrZWRQb3NpdGlvbiByZXBvcnRzIHdoZXRoZXIgYSBwb3NpdGlvbiBpcyBzdGFrZWQgbm8gbG9uZ2VyIGJ1dCBzdGlsbCBoYXMgdW5jb2xsZWN0ZWQgcmV3YXJkcy4KLy8KLy8gUGFyYW1ldGVyczoKLy8gICAtIHBvc2l0aW9uSWQ6IFBvc2l0aW9uIElEIHdob3NlIGV4aXQtY2hlY2twb2ludCBtZW1iZXJzaGlwIGlzIGNoZWNrZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBib29sOiB0cnVlIHdoZW4gcG9zaXRpb25JZCBoYXMgYW4gZXhpdCBjaGVja3BvaW50OyBmYWxzZSBvdGhlcndpc2UuCmZ1bmMgKHMgKnN0YWtlclYxKSBIYXNVbnN0YWtlZFBvc2l0aW9uKHBvc2l0aW9uSWQgdWludDY0KSBib29sIHsKCXJldHVybiBzLmdldFVuc3Rha2VkUG9zaXRpb25zKCkuSGFzKHBvc2l0aW9uSWQpCn0KCi8vIEdldFVuc3Rha2VkUG9zaXRpb25FeGl0VGltZSByZXR1cm5zIHdoZW4gYW4gdW5zdGFrZWQgcG9zaXRpb24gc3RvcHBlZCBhY2NydWluZyByZXdhcmRzLgovLwovLyBQYXJhbWV0ZXJzOgovLyAgIC0gcG9zaXRpb25JZDogUG9zaXRpb24gSUQgd2hvc2UgZXhpdCBjaGVja3BvaW50IGlzIHF1ZXJpZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBpbnQ2NDogRXhpdCB0aW1lc3RhbXAgaW4gVW5peCBzZWNvbmRzLgovLyAgIC0gZXJyb3I6IE5vbi1uaWwgd2hlbiBwb3NpdGlvbklkIGhhcyBubyB1bmNvbGxlY3RlZCBleGl0IGNoZWNrcG9pbnQ7IG5pbCBvbiBzdWNjZXNzLgpmdW5jIChzICpzdGFrZXJWMSkgR2V0VW5zdGFrZWRQb3NpdGlvbkV4aXRUaW1lKHBvc2l0aW9uSWQgdWludDY0KSAoaW50NjQsIGVycm9yKSB7Cglwb3NpdGlvbiA6PSBzLmdldFVuc3Rha2VkUG9zaXRpb25zKCkuZ2V0KHBvc2l0aW9uSWQpCglpZiBwb3NpdGlvbiA9PSBuaWwgewoJCXJldHVybiAwLCB1Zm10LkVycm9yZigiJXY6IHBvc2l0aW9uSWQoJWQpIGhhcyBubyB1bmNvbGxlY3RlZCByZXdhcmQiLCBlcnJEYXRhTm90Rm91bmQsIHBvc2l0aW9uSWQpCgl9CgoJcmV0dXJuIHBvc2l0aW9uLkV4aXRUaW1lKCksIG5pbAp9CgovLyBHZXRVbnN0YWtlZFBvc2l0aW9uUGVuZGluZ0luY2VudGl2ZXMgcmV0dXJucyB0aGUgaW5jZW50aXZlcyBhbiB1bnN0YWtlZCBwb3NpdGlvbiBoYXMgeWV0IHRvCi8vIGNvbGxlY3QuCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBwb3NpdGlvbklkOiBQb3NpdGlvbiBJRCB3aG9zZSBwZW5kaW5nIGluY2VudGl2ZSBJRHMgYXJlIHF1ZXJpZWQuCi8vCi8vIFJldHVybnM6Ci8vICAgLSBbXXN0cmluZzogRXh0ZXJuYWwgaW5jZW50aXZlIElEcyB3aXRoIHJld2FyZHMgc3RpbGwgcGVuZGluZyBmb3IgdGhlIGNoZWNrcG9pbnQuCi8vICAgLSBlcnJvcjogTm9uLW5pbCB3aGVuIHBvc2l0aW9uSWQgaGFzIG5vIHVuY29sbGVjdGVkIGV4aXQgY2hlY2twb2ludDsgbmlsIG9uIHN1Y2Nlc3MuCmZ1bmMgKHMgKnN0YWtlclYxKSBHZXRVbnN0YWtlZFBvc2l0aW9uUGVuZGluZ0luY2VudGl2ZXMocG9zaXRpb25JZCB1aW50NjQpIChbXXN0cmluZywgZXJyb3IpIHsKCXBvc2l0aW9uIDo9IHMuZ2V0VW5zdGFrZWRQb3NpdGlvbnMoKS5nZXQocG9zaXRpb25JZCkKCWlmIHBvc2l0aW9uID09IG5pbCB7CgkJcmV0dXJuIG5pbCwgdWZtdC5FcnJvcmYoIiV2OiBwb3NpdGlvbklkKCVkKSBoYXMgbm8gdW5jb2xsZWN0ZWQgcmV3YXJkIiwgZXJyRGF0YU5vdEZvdW5kLCBwb3NpdGlvbklkKQoJfQoKCXJldHVybiBwb3NpdGlvbi5QZW5kaW5nSW5jZW50aXZlSWRMaXN0KCksIG5pbAp9CgovLyBHZXRVbmNvbGxlY3RlZEluY2VudGl2ZUNvdW50IHJldHVybnMgaG93IG1hbnkgdW5zdGFrZWQgcG9zaXRpb25zIHN0aWxsIG93ZSBhIHJld2FyZCBmcm9tIHRoZQovLyBpbmNlbnRpdmU7IEVuZEV4dGVybmFsSW5jZW50aXZlIGlzIHJlZnVzZWQgd2hpbGUgaXQgaXMgbm9uLXplcm8uCi8vCi8vIFBhcmFtZXRlcnM6Ci8vICAgLSBpbmNlbnRpdmVJZDogRXh0ZXJuYWwgaW5jZW50aXZlIGlkZW50aWZpZXIgd2hvc2Ugb3V0c3RhbmRpbmcgY2hlY2twb2ludCBjb3VudCBpcyBxdWVyaWVkLgovLwovLyBSZXR1cm5zOgovLyAgIC0gaW50NjQ6IE51bWJlciBvZiBleGl0IGNoZWNrcG9pbnRzIHN0aWxsIG93aW5nIGluY2VudGl2ZUlkOyB6ZXJvIHBlcm1pdHMgaW5jZW50aXZlIGZpbmFsaXphdGlvbi4KZnVuYyAocyAqc3Rha2VyVjEpIEdldFVuY29sbGVjdGVkSW5jZW50aXZlQ291bnQoaW5jZW50aXZlSWQgc3RyaW5nKSBpbnQ2NCB7CglyZXR1cm4gcy51bmNvbGxlY3RlZEluY2VudGl2ZUNvdW50T2YoaW5jZW50aXZlSWQpCn0KGqUHCgl1dGlscy5nbm8SlwdwYWNrYWdlIHN0YWtlcgoKaW1wb3J0ICgKCSJlcnJvcnMiCgkic3RyY29udiIKCSJzdHJpbmdzIgoKCSJnbm8ubGFuZC9wL250L2dyYzcyMS92MCIKKQoKLy8gcG9vbFBhdGhEaXZpZGUgc3BsaXRzIGEgcG9vbCBwYXRoIGludG8gdG9rZW4gYWRkcmVzc2VzIGFuZCBmZWUgdGllci4KZnVuYyBwb29sUGF0aERpdmlkZShwb29sUGF0aCBzdHJpbmcpIChzdHJpbmcsIHN0cmluZywgc3RyaW5nKSB7CglyZXMgOj0gc3RyaW5ncy5TcGxpdChwb29sUGF0aCwgIjoiKQoJaWYgbGVuKHJlcykgIT0gMyB7CgkJcGFuaWMoZXJyb3JzLk5ldyhlcnJJbnZhbGlkUG9vbFBhdGgpKQoJfQoKCXBUb2tlbjAsIHBUb2tlbjEsIGZlZSA6PSByZXNbMF0sIHJlc1sxXSwgcmVzWzJdCglyZXR1cm4gcFRva2VuMCwgcFRva2VuMSwgZmVlCn0KCi8vIHBvc2l0aW9uSWRGcm9tIGNvbnZlcnRzIGEgdWludDY0IHBvc2l0aW9uIElEIHRvIGdyYzcyMS5Ub2tlbklELgpmdW5jIHBvc2l0aW9uSWRGcm9tKHBvc2l0aW9uSWQgdWludDY0KSBncmM3MjEuVG9rZW5JRCB7CglyZXR1cm4gZ3JjNzIxLlRva2VuSUQoc3RyY29udi5Gb3JtYXRVaW50KHBvc2l0aW9uSWQsIDEwKSkKfQoKLy8gY29udGFpbnMgY2hlY2tzIGlmIGEgc3RyaW5nIGV4aXN0cyBpbiBhIHNsaWNlLgpmdW5jIGNvbnRhaW5zKHNsaWNlIFtdc3RyaW5nLCBpdGVtIHN0cmluZykgYm9vbCB7CgkvLyBXZSBjYW4gdXNlIHN0cmluZ3MuRXF1YWxGb2xkIGhlcmUsIGJ1dCB0aGlzIGZ1bmN0aW9uIHNob3VsZCBiZSBjYXNlLXNlbnNpdGl2ZS4KCS8vIFNvLCBpdCBpcyBiZXR0ZXIgdG8gY29tcGFyZSBzdHJpbmdzIGRpcmVjdGx5LgoJZm9yIF8sIGVsZW1lbnQgOj0gcmFuZ2Ugc2xpY2UgewoJCWlmIGVsZW1lbnQgPT0gaXRlbSB7CgkJCXJldHVybiB0cnVlCgkJfQoJfQoJcmV0dXJuIGZhbHNlCn0KIiIKEy9nbm8uTWVtUGFja2FnZVR5cGUSCwoJTVBVc2VyQWxsEhMIrpuNlAMSCzQyMzczM3Vnbm90GqgBCjoKEy90bS5QdWJLZXlTZWNwMjU2azESIwohAwSc1QTD4tI6os8LnebKOB+i6fWXOKGBf9lRpSI1wrrhEkCmlUnr4cxUJAB/QZhzlwlLkVTq8xizxiS+FrMBa1fKnGzOnr0FgoTp1hIoZuV0+Z9Mqp0CHlL9C5dzpt5YHQHvGihnMXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcXFxcWx1dXhl

Raw transaction data

Raw JSON data