LyoKKiBDb3B5cmlnaHQgqSB7MTk5OX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDExLzE3Lzk5ICAgIGFsaXUgICAgICAgIENyZWF0aW9uLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCiNpZm5kZWYgVFJBTlNMSVRfSAojZGVmaW5lIFRSQU5TTElUX0gKCiNpbmNsdWRlICJ1bmljb2RlL3VuaXN0ci5oIgoKY2xhc3MgUmVwbGFjZWFibGU7CmNsYXNzIFVuaWNvZGVGaWx0ZXI7CmNsYXNzIFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhOwpzdHJ1Y3QgVUhhc2h0YWJsZTsKY2xhc3MgVV9JMThOX0FQSSBVVmVjdG9yOwpjbGFzcyBDb21wb3VuZFRyYW5zbGl0ZXJhdG9yOwoKLyoqCiAqIDxjb2RlPlRyYW5zbGl0ZXJhdG9yPC9jb2RlPiBpcyBhbiBhYnN0cmFjdCBjbGFzcyB0aGF0CiAqIHRyYW5zbGl0ZXJhdGVzIHRleHQgZnJvbSBvbmUgZm9ybWF0IHRvIGFub3RoZXIuICBUaGUgbW9zdCBjb21tb24KICoga2luZCBvZiB0cmFuc2xpdGVyYXRvciBpcyBhIHNjcmlwdCwgb3IgYWxwaGFiZXQsIHRyYW5zbGl0ZXJhdG9yLgogKiBGb3IgZXhhbXBsZSwgYSBSdXNzaWFuIHRvIExhdGluIHRyYW5zbGl0ZXJhdG9yIGNoYW5nZXMgUnVzc2lhbiB0ZXh0CiAqIHdyaXR0ZW4gaW4gQ3lyaWxsaWMgY2hhcmFjdGVycyB0byBwaG9uZXRpY2FsbHkgZXF1aXZhbGVudCBMYXRpbgogKiBjaGFyYWN0ZXJzLiAgSXQgZG9lcyBub3QgPGVtPnRyYW5zbGF0ZTwvZW0+IFJ1c3NpYW4gdG8gRW5nbGlzaCEKICogVHJhbnNsaXRlcmF0aW9uLCB1bmxpa2UgdHJhbnNsYXRpb24sIG9wZXJhdGVzIG9uIGNoYXJhY3RlcnMsIHdpdGhvdXQKICogcmVmZXJlbmNlIHRvIHRoZSBtZWFuaW5ncyBvZiB3b3JkcyBhbmQgc2VudGVuY2VzLgogKgogKiA8cD5BbHRob3VnaCBzY3JpcHQgY29udmVyc2lvbiBpcyBpdHMgbW9zdCBjb21tb24gdXNlLCBhCiAqIHRyYW5zbGl0ZXJhdG9yIGNhbiBhY3R1YWxseSBwZXJmb3JtIGEgbW9yZSBnZW5lcmFsIGNsYXNzIG9mIHRhc2tzLgogKiBJbiBmYWN0LCA8Y29kZT5UcmFuc2xpdGVyYXRvcjwvY29kZT4gZGVmaW5lcyBhIHZlcnkgZ2VuZXJhbCBBUEkKICogd2hpY2ggc3BlY2lmaWVzIG9ubHkgdGhhdCBhIHNlZ21lbnQgb2YgdGhlIGlucHV0IHRleHQgaXMgcmVwbGFjZWQKICogYnkgbmV3IHRleHQuICBUaGUgcGFydGljdWxhcnMgb2YgdGhpcyBjb252ZXJzaW9uIGFyZSBkZXRlcm1pbmVkCiAqIGVudGlyZWx5IGJ5IHN1YmNsYXNzZXMgb2YgPGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+LgogKgogKiA8cD48Yj5UcmFuc2xpdGVyYXRvcnMgYXJlIHN0YXRlbGVzczwvYj4KICoKICogPHA+PGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+IG9iamVjdHMgYXJlIDxlbT5zdGF0ZWxlc3M8L2VtPjsgdGhleQogKiByZXRhaW4gbm8gaW5mb3JtYXRpb24gYmV0d2VlbiBjYWxscyB0bwogKiA8Y29kZT50cmFuc2xpdGVyYXRlKCk8L2NvZGU+LiAgKEhvd2V2ZXIsIHRoaXMgZG9lcyA8ZW0+bm90PC9lbT4KICogbWVhbiB0aGF0IHRocmVhZHMgbWF5IHNoYXJlIHRyYW5zbGl0ZXJhdG9ycyB3aXRob3V0IHN5bmNocm9uaXppbmcKICogdGhlbS4gIFRyYW5zbGl0ZXJhdG9ycyBhcmUgbm90IGltbXV0YWJsZSwgc28gdGhleSBtdXN0IGJlCiAqIHN5bmNocm9uaXplZCB3aGVuIHNoYXJlZCBiZXR3ZWVuIHRocmVhZHMuKSAgVGhpczEgbWlnaHQgc2VlbSB0bwogKiBsaW1pdCB0aGUgY29tcGxleGl0eSBvZiB0aGUgdHJhbnNsaXRlcmF0aW9uIG9wZXJhdGlvbi4gIEluCiAqIHByYWN0aWNlLCBzdWJjbGFzc2VzIHBlcmZvcm0gY29tcGxleCB0cmFuc2xpdGVyYXRpb25zIGJ5IGRlbGF5aW5nCiAqIHRoZSByZXBsYWNlbWVudCBvZiB0ZXh0IHVudGlsIGl0IGlzIGtub3duIHRoYXQgbm8gb3RoZXIKICogcmVwbGFjZW1lbnRzIGFyZSBwb3NzaWJsZS4gIEluIG90aGVyIHdvcmRzLCBhbHRob3VnaCB0aGUKICogPGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+IG9iamVjdHMgYXJlIHN0YXRlbGVzcywgdGhlIHNvdXJjZSB0ZXh0CiAqIGl0c2VsZiBlbWJvZGllcyBhbGwgdGhlIG5lZWRlZCBpbmZvcm1hdGlvbiwgYW5kIGRlbGF5ZWQgb3BlcmF0aW9uCiAqIGFsbG93cyBhcmJpdHJhcnkgY29tcGxleGl0eS4KICoKICogPHA+PGI+QmF0Y2ggdHJhbnNsaXRlcmF0aW9uPC9iPgogKgogKiA8cD5UaGUgc2ltcGxlc3Qgd2F5IHRvIHBlcmZvcm0gdHJhbnNsaXRlcmF0aW9uIGlzIGFsbCBhdCBvbmNlLCBvbiBhCiAqIHN0cmluZyBvZiBleGlzdGluZyB0ZXh0LiAgVGhpcyBpcyByZWZlcnJlZCB0byBhcyA8ZW0+YmF0Y2g8L2VtPgogKiB0cmFuc2xpdGVyYXRpb24uICBGb3IgZXhhbXBsZSwgZ2l2ZW4gYSBzdHJpbmcgPGNvZGU+aW5wdXQ8L2NvZGU+CiAqIGFuZCBhIHRyYW5zbGl0ZXJhdG9yIDxjb2RlPnQ8L2NvZGU+LCB0aGUgY2FsbAogKgogKiA8YmxvY2txdW90ZT48Y29kZT5TdHJpbmcgcmVzdWx0ID0gdC50cmFuc2xpdGVyYXRlKGlucHV0KTsKICogPC9jb2RlPjwvYmxvY2txdW90ZT4KICoKICogd2lsbCB0cmFuc2xpdGVyYXRlIGl0IGFuZCByZXR1cm4gdGhlIHJlc3VsdC4gIE90aGVyIG1ldGhvZHMgYWxsb3cKICogdGhlIGNsaWVudCB0byBzcGVjaWZ5IGEgc3Vic3RyaW5nIHRvIGJlIHRyYW5zbGl0ZXJhdGVkIGFuZCB0byB1c2UKICoge0BsaW5rIFJlcGxhY2VhYmxlfSBvYmplY3RzIGluc3RlYWQgb2Ygc3RyaW5ncywgaW4gb3JkZXIgdG8KICogcHJlc2VydmUgb3V0LW9mLWJhbmQgaW5mb3JtYXRpb24gKHN1Y2ggYXMgdGV4dCBzdHlsZXMpLgogKgogKiA8cD48Yj5LZXlib2FyZCB0cmFuc2xpdGVyYXRpb248L2I+CiAqCiAqIDxwPlNvbWV3aGF0IG1vcmUgaW52b2x2ZWQgaXMgPGVtPmtleWJvYXJkPC9lbT4sIG9yIGluY3JlbWVudGFsCiAqIHRyYW5zbGl0ZXJhdGlvbi4gIFRoaXMgaXMgdGhlIHRyYW5zbGl0ZXJhdGlvbiBvZiB0ZXh0IHRoYXQgaXMKICogYXJyaXZpbmcgZnJvbSBzb21lIHNvdXJjZSAodHlwaWNhbGx5IHRoZSB1c2VyJ3Mga2V5Ym9hcmQpIG9uZQogKiBjaGFyYWN0ZXIgYXQgYSB0aW1lLCBvciBpbiBzb21lIG90aGVyIHBpZWNlbWVhbCBmYXNoaW9uLgogKgogKiA8cD5JbiBrZXlib2FyZCB0cmFuc2xpdGVyYXRpb24sIGEgPGNvZGU+UmVwbGFjZWFibGU8L2NvZGU+IGJ1ZmZlcgogKiBzdG9yZXMgdGhlIHRleHQuICBBcyB0ZXh0IGlzIGluc2VydGVkLCBhcyBtdWNoIGFzIHBvc3NpYmxlIGlzCiAqIHRyYW5zbGl0ZXJhdGVkIG9uIHRoZSBmbHkuICBUaGlzIG1lYW5zIGEgR1VJIHRoYXQgZGlzcGxheXMgdGhlCiAqIGNvbnRlbnRzIG9mIHRoZSBidWZmZXIgbWF5IHNob3cgdGV4dCBiZWluZyBtb2RpZmllZCBhcyBlYWNoIG5ldwogKiBjaGFyYWN0ZXIgYXJyaXZlcy4KICoKICogPHA+Q29uc2lkZXIgdGhlIHNpbXBsZSA8Y29kZT5SdWxlQmFzZWRUcmFuc2xpdGVyYXRvcjwvY29kZT46CiAqCiAqIDxibG9ja3F1b3RlPjxjb2RlPgogKiB0aCZndDt7dGhldGF9PGJyPgogKiB0Jmd0O3t0YXV9CiAqIDwvY29kZT48L2Jsb2NrcXVvdGU+CiAqCiAqIFdoZW4gdGhlIHVzZXIgdHlwZXMgJ3QnLCBub3RoaW5nIHdpbGwgaGFwcGVuLCBzaW5jZSB0aGUKICogdHJhbnNsaXRlcmF0b3IgaXMgd2FpdGluZyB0byBzZWUgaWYgdGhlIG5leHQgY2hhcmFjdGVyIGlzICdoJy4gIFRvCiAqIHJlbWVkeSB0aGlzLCB3ZSBpbnRyb2R1Y2UgdGhlIG5vdGlvbiBvZiBhIGN1cnNvciwgbWFya2VkIGJ5IGEgJ3wnCiAqIGluIHRoZSBvdXRwdXQgc3RyaW5nOgogKgogKiA8YmxvY2txdW90ZT48Y29kZT4KICogdCZndDt8e3RhdX08YnI+CiAqIHt0YXV9aCZndDt7dGhldGF9CiAqIDwvY29kZT48L2Jsb2NrcXVvdGU+CiAqCiAqIE5vdyB3aGVuIHRoZSB1c2VyIHR5cGVzICd0JywgdGF1IGFwcGVhcnMsIGFuZCBpZiB0aGUgbmV4dCBjaGFyYWN0ZXIKICogaXMgJ2gnLCB0aGUgdGF1IGNoYW5nZXMgdG8gYSB0aGV0YS4gIFRoaXMgaXMgYWNjb21wbGlzaGVkIGJ5CiAqIG1haW50YWluaW5nIGEgY3Vyc29yIHBvc2l0aW9uIChpbmRlcGVuZGVudCBvZiB0aGUgaW5zZXJ0aW9uIHBvaW50LAogKiBhbmQgaW52aXNpYmxlIGluIHRoZSBHVUkpIGFjcm9zcyBjYWxscyB0bwogKiA8Y29kZT50cmFuc2xpdGVyYXRlKCk8L2NvZGU+LiAgVHlwaWNhbGx5LCB0aGUgY3Vyc29yIHdpbGwKICogYmUgY29pbmNpZGVudCB3aXRoIHRoZSBpbnNlcnRpb24gcG9pbnQsIGJ1dCBpbiBhIGNhc2UgbGlrZSB0aGUgb25lCiAqIGFib3ZlLCBpdCB3aWxsIHByZWNlZGUgdGhlIGluc2VydGlvbiBwb2ludC4KICoKICogPHA+S2V5Ym9hcmQgdHJhbnNsaXRlcmF0aW9uIG1ldGhvZHMgbWFpbnRhaW4gYSBzZXQgb2YgdGhyZWUgaW5kaWNlcwogKiB0aGF0IGFyZSB1cGRhdGVkIHdpdGggZWFjaCBjYWxsIHRvCiAqIDxjb2RlPnRyYW5zbGl0ZXJhdGUoKTwvY29kZT4sIGluY2x1ZGluZyB0aGUgY3Vyc29yLCBzdGFydCwKICogYW5kIGxpbWl0LiAgU2luY2UgdGhlc2UgaW5kaWNlcyBhcmUgY2hhbmdlZCBieSB0aGUgbWV0aG9kLCB0aGV5IGFyZQogKiBwYXNzZWQgaW4gYW4gPGNvZGU+aW50W108L2NvZGU+IGFycmF5LiBUaGUgPGNvZGU+U1RBUlQ8L2NvZGU+IGluZGV4CiAqIG1hcmtzIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN1YnN0cmluZyB0aGF0IHRoZSB0cmFuc2xpdGVyYXRvciB3aWxsCiAqIGxvb2sgYXQuICBJdCBpcyBhZHZhbmNlZCBhcyB0ZXh0IGJlY29tZXMgY29tbWl0dGVkIChidXQgaXQgaXMgbm90CiAqIHRoZSBjb21taXR0ZWQgaW5kZXg7IHRoYXQncyB0aGUgPGNvZGU+Q1VSU09SPC9jb2RlPikuICBUaGUKICogPGNvZGU+Q1VSU09SPC9jb2RlPiBpbmRleCwgZGVzY3JpYmVkIGFib3ZlLCBtYXJrcyB0aGUgcG9pbnQgYXQKICogd2hpY2ggdGhlIHRyYW5zbGl0ZXJhdG9yIGxhc3Qgc3RvcHBlZCwgZWl0aGVyIGJlY2F1c2UgaXQgcmVhY2hlZAogKiB0aGUgZW5kLCBvciBiZWNhdXNlIGl0IHJlcXVpcmVkIG1vcmUgY2hhcmFjdGVycyB0byBkaXNhbWJpZ3VhdGUKICogYmV0d2VlbiBwb3NzaWJsZSBpbnB1dHMuICBUaGUgPGNvZGU+Q1VSU09SPC9jb2RlPiBjYW4gYWxzbyBiZQogKiBleHBsaWNpdGx5IHNldCBieSBydWxlcyBpbiBhIDxjb2RlPlJ1bGVCYXNlZFRyYW5zbGl0ZXJhdG9yPC9jb2RlPi4KICogQW55IGNoYXJhY3RlcnMgYmVmb3JlIHRoZSA8Y29kZT5DVVJTT1I8L2NvZGU+IGluZGV4IGFyZSBmcm96ZW47CiAqIGZ1dHVyZSBrZXlib2FyZCB0cmFuc2xpdGVyYXRpb24gY2FsbHMgd2l0aGluIHRoaXMgaW5wdXQgc2VxdWVuY2UKICogd2lsbCBub3QgY2hhbmdlIHRoZW0uICBOZXcgdGV4dCBpcyBpbnNlcnRlZCBhdCB0aGUKICogPGNvZGU+TElNSVQ8L2NvZGU+IGluZGV4LCB3aGljaCBtYXJrcyB0aGUgZW5kIG9mIHRoZSBzdWJzdHJpbmcgdGhhdAogKiB0aGUgdHJhbnNsaXRlcmF0b3IgbG9va3MgYXQuCiAqCiAqIDxwPkJlY2F1c2Uga2V5Ym9hcmQgdHJhbnNsaXRlcmF0aW9uIGFzc3VtZXMgdGhhdCBtb3JlIGNoYXJhY3RlcnMKICogYXJlIHRvIGFycml2ZSwgaXQgaXMgY29uc2VydmF0aXZlIGluIGl0cyBvcGVyYXRpb24uICBJdCBvbmx5CiAqIHRyYW5zbGl0ZXJhdGVzIHdoZW4gaXQgY2FuIGRvIHNvIHVuYW1iaWd1b3VzbHkuICBPdGhlcndpc2UgaXQgd2FpdHMKICogZm9yIG1vcmUgY2hhcmFjdGVycyB0byBhcnJpdmUuICBXaGVuIHRoZSBjbGllbnQgY29kZSBrbm93cyB0aGF0IG5vCiAqIG1vcmUgY2hhcmFjdGVycyBhcmUgZm9ydGhjb21pbmcsIHBlcmhhcHMgYmVjYXVzZSB0aGUgdXNlciBoYXMKICogcGVyZm9ybWVkIHNvbWUgaW5wdXQgdGVybWluYXRpb24gb3BlcmF0aW9uLCB0aGVuIGl0IHNob3VsZCBjYWxsCiAqIDxjb2RlPmZpbmlzaFRyYW5zbGl0ZXJhdGlvbigpPC9jb2RlPiB0byBjb21wbGV0ZSBhbnkKICogcGVuZGluZyB0cmFuc2xpdGVyYXRpb25zLgogKgogKiA8cD48Yj5JbnZlcnNlczwvYj4KICoKICogPHA+UGFpcnMgb2YgdHJhbnNsaXRlcmF0b3JzIG1heSBiZSBpbnZlcnNlcyBvZiBvbmUgYW5vdGhlci4gIEZvcgogKiBleGFtcGxlLCBpZiB0cmFuc2xpdGVyYXRvciA8Yj5BPC9iPiB0cmFuc2xpdGVyYXRlcyBjaGFyYWN0ZXJzIGJ5CiAqIGluY3JlbWVudGluZyB0aGVpciBVbmljb2RlIHZhbHVlIChzbyAiYWJjIiAtPiAiZGVmIiksIGFuZAogKiB0cmFuc2xpdGVyYXRvciA8Yj5CPC9iPiBkZWNyZW1lbnRzIGNoYXJhY3RlciB2YWx1ZXMsIHRoZW4gPGI+QTwvYj4KICogaXMgYW4gaW52ZXJzZSBvZiA8Yj5CPC9iPiBhbmQgdmljZSB2ZXJzYS4gIElmIHdlIGNvbXBvc2UgPGI+QTwvYj4KICogd2l0aCA8Yj5CPC9iPiBpbiBhIGNvbXBvdW5kIHRyYW5zbGl0ZXJhdG9yLCB0aGUgcmVzdWx0IGlzIHRoZQogKiBpbmRlbnRpdHkgdHJhbnNsaXRlcmF0b3IsIHRoYXQgaXMsIGEgdHJhbnNsaXRlcmF0b3IgdGhhdCBkb2VzIG5vdAogKiBjaGFuZ2UgaXRzIGlucHV0IHRleHQuCiAqCiAqIFRoZSA8Y29kZT5UcmFuc2xpdGVyYXRvcjwvY29kZT4gbWV0aG9kIDxjb2RlPmdldEludmVyc2UoKTwvY29kZT4KICogcmV0dXJucyBhIHRyYW5zbGl0ZXJhdG9yJ3MgaW52ZXJzZSwgaWYgb25lIGV4aXN0cywgb3IKICogPGNvZGU+bnVsbDwvY29kZT4gb3RoZXJ3aXNlLiAgSG93ZXZlciwgdGhlIHJlc3VsdCBvZgogKiA8Y29kZT5nZXRJbnZlcnNlKCk8L2NvZGU+IHVzdWFsbHkgd2lsbCA8ZW0+bm90PC9lbT4gYmUgYSB0cnVlCiAqIG1hdGhlbWF0aWNhbCBpbnZlcnNlLiAgVGhpcyBpcyBiZWNhdXNlIHRydWUgaW52ZXJzZSB0cmFuc2xpdGVyYXRvcnMKICogYXJlIGRpZmZpY3VsdCB0byBmb3JtdWxhdGUuICBGb3IgZXhhbXBsZSwgY29uc2lkZXIgdHdvCiAqIHRyYW5zbGl0ZXJhdG9yczogPGI+QUI8L2I+LCB3aGljaCB0cmFuc2xpdGVyYXRlcyB0aGUgY2hhcmFjdGVyICdBJwogKiB0byAnQicsIGFuZCA8Yj5CQTwvYj4sIHdoaWNoIHRyYW5zbGl0ZXJhdGVzICdCJyB0byAnQScuICBJdCBtaWdodAogKiBzZWVtIHRoYXQgdGhlc2UgYXJlIGV4YWN0IGludmVyc2VzLCBzaW5jZQogKgogKiA8YmxvY2txdW90ZT4iQSIgeCA8Yj5BQjwvYj4gLT4gIkIiPGJyPgogKiAiQiIgeCA8Yj5CQTwvYj4gLT4gIkEiPC9ibG9ja3F1b3RlPgogKgogKiB3aGVyZSAneCcgcmVwcmVzZW50cyB0cmFuc2xpdGVyYXRpb24uICBIb3dldmVyLAogKgogKiA8YmxvY2txdW90ZT4iQUJDRCIgeCA8Yj5BQjwvYj4gLT4gIkJCQ0QiPGJyPgogKiAiQkJDRCIgeCA8Yj5CQTwvYj4gLT4gIkFBQ0QiPC9ibG9ja3F1b3RlPgogKgogKiBzbyA8Yj5BQjwvYj4gY29tcG9zZWQgd2l0aCA8Yj5CQTwvYj4gaXMgbm90IHRoZQogKiBpZGVudGl0eS4gTm9uZXRoZWxlc3MsIDxiPkJBPC9iPiBtYXkgYmUgdXNlZnVsbHkgY29uc2lkZXJlZCB0byBiZQogKiA8Yj5BQjwvYj4ncyBpbnZlcnNlLCBhbmQgaXQgaXMgb24gdGhpcyBiYXNpcyB0aGF0CiAqIDxiPkFCPC9iPjxjb2RlPi5nZXRJbnZlcnNlKCk8L2NvZGU+IGNvdWxkIGxlZ2l0aW1hdGVseSByZXR1cm4KICogPGI+QkE8L2I+LgogKgogKiA8cD48Yj5JRHMgYW5kIGRpc3BsYXkgbmFtZXM8L2I+CiAqCiAqIDxwPkEgdHJhbnNsaXRlcmF0b3IgaXMgZGVzaWduYXRlZCBieSBhIHNob3J0IGlkZW50aWZpZXIgc3RyaW5nIG9yCiAqIDxlbT5JRDwvZW0+LiAgSURzIGZvbGxvdyB0aGUgZm9ybWF0IDxlbT5zb3VyY2UtZGVzdGluYXRpb248L2VtPiwKICogd2hlcmUgPGVtPnNvdXJjZTwvZW0+IGRlc2NyaWJlcyB0aGUgZW50aXR5IGJlaW5nIHJlcGxhY2VkLCBhbmQKICogPGVtPmRlc3RpbmF0aW9uPC9lbT4gZGVzY3JpYmVzIHRoZSBlbnRpdHkgcmVwbGFjaW5nCiAqIDxlbT5zb3VyY2U8L2VtPi4gIFRoZSBlbnRpdGllcyBtYXkgYmUgdGhlIG5hbWVzIG9mIHNjcmlwdHMsCiAqIHBhcnRpY3VsYXIgc2VxdWVuY2VzIG9mIGNoYXJhY3RlcnMsIG9yIHdoYXRldmVyIGVsc2UgaXQgaXMgdGhhdCB0aGUKICogdHJhbnNsaXRlcmF0b3IgY29udmVydHMgdG8gb3IgZnJvbS4gIEZvciBleGFtcGxlLCBhIHRyYW5zbGl0ZXJhdG9yCiAqIGZyb20gUnVzc2lhbiB0byBMYXRpbiBtaWdodCBiZSBuYW1lZCAiUnVzc2lhbi1MYXRpbiIuICBBCiAqIHRyYW5zbGl0ZXJhdG9yIGZyb20ga2V5Ym9hcmQgZXNjYXBlIHNlcXVlbmNlcyB0byBMYXRpbi0xIGNoYXJhY3RlcnMKICogbWlnaHQgYmUgbmFtZWQgIktleWJvYXJkRXNjYXBlLUxhdGluMSIuICBCeSBjb252ZW50aW9uLCBzeXN0ZW0KICogZW50aXR5IG5hbWVzIGFyZSBpbiBFbmdsaXNoLCB3aXRoIHRoZSBpbml0aWFsIGxldHRlcnMgb2Ygd29yZHMKICogY2FwaXRhbGl6ZWQ7IHVzZXIgZW50aXR5IG5hbWVzIG1heSBmb2xsb3cgYW55IGZvcm1hdCBzbyBsb25nIGFzCiAqIHRoZXkgZG8gbm90IGNvbnRhaW4gZGFzaGVzLgogKgogKiA8cD5JbiBhZGRpdGlvbiB0byBwcm9ncmFtbWF0aWMgSURzLCB0cmFuc2xpdGVyYXRvciBvYmplY3RzIGhhdmUKICogZGlzcGxheSBuYW1lcyBmb3IgcHJlc2VudGF0aW9uIGluIHVzZXIgaW50ZXJmYWNlcywgcmV0dXJuZWQgYnkKICoge0BsaW5rICNnZXREaXNwbGF5TmFtZX0uCiAqCiAqIDxwPjxiPkZhY3RvcnkgbWV0aG9kcyBhbmQgcmVnaXN0cmF0aW9uPC9iPgogKgogKiA8cD5JbiBnZW5lcmFsLCBjbGllbnQgY29kZSBzaG91bGQgdXNlIHRoZSBmYWN0b3J5IG1ldGhvZAogKiA8Y29kZT5nZXRJbnN0YW5jZSgpPC9jb2RlPiB0byBvYnRhaW4gYW4gaW5zdGFuY2Ugb2YgYQogKiB0cmFuc2xpdGVyYXRvciBnaXZlbiBpdHMgSUQuICBWYWxpZCBJRHMgbWF5IGJlIGVudW1lcmF0ZWQgdXNpbmcKICogPGNvZGU+Z2V0QXZhaWxhYmxlSURzKCk8L2NvZGU+LiAgU2luY2UgdHJhbnNsaXRlcmF0b3JzIGFyZSBtdXRhYmxlLAogKiBtdWx0aXBsZSBjYWxscyB0byA8Y29kZT5nZXRJbnN0YW5jZSgpPC9jb2RlPiB3aXRoIHRoZSBzYW1lIElEIHdpbGwKICogcmV0dXJuIGRpc3RpbmN0IG9iamVjdHMuCiAqCiAqIDxwPkluIGFkZGl0aW9uIHRvIHRoZSBzeXN0ZW0gdHJhbnNsaXRlcmF0b3JzIHJlZ2lzdGVyZWQgYXQgc3RhcnR1cCwKICogdXNlciB0cmFuc2xpdGVyYXRvcnMgbWF5IGJlIHJlZ2lzdGVyZWQgYnkgY2FsbGluZwogKiA8Y29kZT5yZWdpc3Rlckluc3RhbmNlKCk8L2NvZGU+IGF0IHJ1biB0aW1lLiAgQSByZWdpc3RlcmVkIGluc3RhbmNlCiAqIGFjdHMgYSB0ZW1wbGF0ZTsgZnV0dXJlIGNhbGxzIHRvIDx0dD5nZXRJbnN0YW5jZSgpPC90dD4gd2l0aCB0aGUgSUQKICogb2YgdGhlIHJlZ2lzdGVyZWQgb2JqZWN0IHJldHVybiBjbG9uZXMgb2YgdGhhdCBvYmplY3QuICBUaHVzIGFueQogKiBvYmplY3QgcGFzc2VkIHRvIDx0dD5yZWdpc3Rlckluc3RhbmNlKCk8L3R0PiBtdXN0IGltcGxlbWVudAogKiA8dHQ+Y2xvbmUoKTwvdHQ+IHByb3BlcnRseS4gIFRvIHJlZ2lzdGVyIGEgdHJhbnNsaXRlcmF0b3Igc3ViY2xhc3MKICogd2l0aG91dCBpbnN0YW50aWF0aW5nIGl0ICh1bnRpbCBpdCBpcyBuZWVkZWQpLCB1c2VycyBtYXkgY2FsbAogKiA8Y29kZT5yZWdpc3RlckNsYXNzKCk8L2NvZGU+LiAgSW4gdGhpcyBjYXNlLCB0aGUgb2JqZWN0cyBhcmUKICogaW5zdGFudGlhdGVkIGJ5IGludm9raW5nIHRoZSB6ZXJvLWFyZ3VtZW50IHB1YmxpYyBjb25zdHJ1Y3RvciBvZgogKiB0aGUgY2xhc3MuCiAqCiAqIDxwPjxiPlN1YmNsYXNzaW5nPC9iPgogKgogKiBTdWJjbGFzc2VzIG11c3QgaW1wbGVtZW50IHRoZSBhYnN0cmFjdCBtZXRob2QKICogPGNvZGU+aGFuZGxlVHJhbnNsaXRlcmF0ZSgpPC9jb2RlPi4gIDxwPlN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlCiAqIHRoZSA8Y29kZT50cmFuc2xpdGVyYXRlKCk8L2NvZGU+IG1ldGhvZCB0YWtpbmcgYQogKiA8Y29kZT5SZXBsYWNlYWJsZTwvY29kZT4gYW5kIHRoZSA8Y29kZT50cmFuc2xpdGVyYXRlKCk8L2NvZGU+CiAqIG1ldGhvZCB0YWtpbmcgYSA8Y29kZT5TdHJpbmc8L2NvZGU+IGFuZCA8Y29kZT5TdHJpbmdCdWZmZXI8L2NvZGU+CiAqIGlmIHRoZSBwZXJmb3JtYW5jZSBvZiB0aGVzZSBtZXRob2RzIGNhbiBiZSBpbXByb3ZlZCBvdmVyIHRoZQogKiBwZXJmb3JtYW5jZSBvYnRhaW5lZCBieSB0aGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbnMgaW4gdGhpcyBjbGFzcy4KICoKICogQGF1dGhvciBBbGFuIExpdQogKi8KY2xhc3MgVV9JMThOX0FQSSBUcmFuc2xpdGVyYXRvciB7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBEaXJlY3Rpb24gY29uc3RhbnQgaW5kaWNhdGluZyB0aGUgZGlyZWN0aW9uIGluIGEgdHJhbnNsaXRlcmF0b3IsIGUuZy4sCiAgICAgKiB0aGUgZm9yd2FyZCBvciByZXZlcnNlIHJ1bGVzIG9mIGEgUnVsZUJhc2VkVHJhbnNsaXRlcmF0b3IuICBBbiAiQS1CIgogICAgICogdHJhbnNsaXRlcmF0b3IgdHJhbnNsaXRlcmF0ZXMgQSB0byBCIHdoZW4gb3BlcmF0aW5nIGluIHRoZSBmb3J3YXJkCiAgICAgKiBkaXJlY3Rpb24sIGFuZCBCIHRvIEEgd2hlbiBvcGVyYXRpbmcgaW4gdGhlIHJldmVyc2UgZGlyZWN0aW9uLgogICAgICovCiAgICBlbnVtIERpcmVjdGlvbiB7CiAgICAgICAgRk9SV0FSRCwKICAgICAgICBSRVZFUlNFCiAgICB9OwoKICAgIGNsYXNzIFBvc2l0aW9uIHsKICAgIHB1YmxpYzoKICAgICAgICAvKioKICAgICAgICAgKiBJbiA8Y29kZT50cmFuc2xpdGVyYXRlKCk8L2NvZGU+LCB0aGUgYmVnaW5uaW5nIGluZGV4LCBpbmNsdXNpdmUKICAgICAgICAgKi8KICAgICAgICBpbnQzMl90IHN0YXJ0OwoKICAgICAgICAvKioKICAgICAgICAgKiBJbiA8Y29kZT50cmFuc2xpdGVyYXRlKCk8L2NvZGU+LCB0aGUgZW5kaW5nIGluZGV4LCBleGNsdXNpdmUKICAgICAgICAgKi8KICAgICAgICBpbnQzMl90IGxpbWl0OwoKICAgICAgICAvKioKICAgICAgICAgKiBJbiA8Y29kZT50cmFuc2xpdGVyYXRlKCk8L2NvZGU+LCB0aGUgbmV4dCBjaGFyYWN0ZXIgdG8gYmUKICAgICAgICAgKiBjb25zaWRlcmVkIGZvciB0cmFuc2xpdGVyYXRpb24KICAgICAgICAgKi8KICAgICAgICBpbnQzMl90IGN1cnNvcjsKICAgIH07Cgpwcml2YXRlOgoKICAgIC8qKgogICAgICogUHJvZ3JhbW1hdGljIG5hbWUsIGUuZy4sICJMYXRpbi1BcmFiaWMiLgogICAgICovCiAgICBVbmljb2RlU3RyaW5nIElEOwoKICAgIC8qKiAKICAgICAqIFRoaXMgdHJhbnNsaXRlcmF0b3IncyBmaWx0ZXIuICBBbnkgY2hhcmFjdGVyIGZvciB3aGljaAogICAgICogPHR0PmZpbHRlci5jb250YWlucygpPC90dD4gcmV0dXJucyA8dHQ+ZmFsc2U8L3R0PiB3aWxsIG5vdCBiZQogICAgICogYWx0ZXJlZCBieSB0aGlzIHRyYW5zbGl0ZXJhdG9yLiAgSWYgPHR0PmZpbHRlcjwvdHQ+IGlzCiAgICAgKiA8dHQ+bnVsbDwvdHQ+IHRoZW4gbm8gZmlsdGVyaW5nIGlzIGFwcGxpZWQuCiAgICAgKi8KICAgIFVuaWNvZGVGaWx0ZXIqIGZpbHRlcjsKCiAgICBpbnQzMl90IG1heGltdW1Db250ZXh0TGVuZ3RoOwoKICAgIC8qKgogICAgICogRGljdGlvbmFyeSBvZiBrbm93biB0cmFuc2xpdGVyYXRvcnMuICBLZXlzIGFyZSA8Y29kZT5TdHJpbmc8L2NvZGU+CiAgICAgKiBuYW1lcywgdmFsdWVzIGFyZSBvbmUgb2YgdGhlIGZvbGxvd2luZzoKICAgICAqCiAgICAgKiA8dWw+PGxpPjxjb2RlPlRyYW5zbGl0ZXJhdG9yPC9jb2RlPiBvYmplY3RzCiAgICAgKgogICAgICogPGxpPjxjb2RlPkNsYXNzPC9jb2RlPiBvYmplY3RzLiAgU3VjaCBvYmplY3RzIG11c3QgcmVwcmVzZW50CiAgICAgKiBzdWJjbGFzc2VzIG9mIDxjb2RlPlRyYW5zbGl0ZXJhdG9yPC9jb2RlPiwgYW5kIG11c3Qgc2F0aXNmeSB0aGUKICAgICAqIGNvbnN0cmFpbnRzIGRlc2NyaWJlZCBpbiA8Y29kZT5yZWdpc3RlckNsYXNzKCk8L2NvZGU+CiAgICAgKgogICAgICogPGxpPjxjb2RlPlJVTEVfQkFTRURfUExBQ0VIT0xERVI8L2NvZGU+LCBpbiB3aGljaCBjYXNlIHRoZSBJRAogICAgICogd2lsbCBoYXZlIGl0cyBmaXJzdCAnLScgcmVtb3ZlZCBhbmQgYmUgYXBwZW5kZWQgdG8KICAgICAqIFJCX1JVTEVfQkFTRURfUFJFRklYIHRvIGZvcm0gYSByZXNvdXJjZSBidW5kbGUgbmFtZSBmcm9tIHdoaWNoCiAgICAgKiB0aGUgUkJfUlVMRSBrZXkgaXMgbG9va2VkIHVwIHRvIG9idGFpbiB0aGUgcnVsZS4KICAgICAqCiAgICAgKiA8bGk+PGNvZGU+UkVWRVJTRV9SVUxFX0JBU0VEX1BMQUNFSE9MREVSPC9jb2RlPi4gIExpa2UKICAgICAqIDxjb2RlPlJVTEVfQkFTRURfUExBQ0VIT0xERVI8L2NvZGU+LCBleGNlcHQgdGhlIGVudGl0eSBuYW1lcyBpbgogICAgICogdGhlIElEIGFyZSByZXZlcnNlZCwgYW5kIHRoZSBhcmd1bWVudAogICAgICogUnVsZUJhc2VkVHJhbnNsaXRlcmF0b3IuUkVWRVJTRSBpcyBwYXNlZCB0byB0aGUKICAgICAqIFJ1bGVCYXNlZFRyYW5zbGl0ZXJhdG9yIGNvbnN0cnVjdG9yLgogICAgICogPC91bD4KICAgICAqLwogICAgc3RhdGljIFVIYXNodGFibGUqIGNhY2hlOwoKICAgIC8qKgogICAgICogVGhlIG11dGV4IGNvbnRyb2xsaW5nIGFjY2VzcyB0byB0aGUgY2FjaGUuCiAgICAgKi8KICAgIHN0YXRpYyBVTVRYIGNhY2hlTXV0ZXg7CgogICAgLyoqCiAgICAgKiBXaGVuIHNldCB0byBUUlVFLCB0aGUgY2FjaGUgaGFzIGJlZW4gaW5pdGlhbGl6ZWQuICBBbnkgY29kZSBtdXN0CiAgICAgKiBjaGVjayB0aGlzIGJvb2xlYW4gYmVmb3JlIGFjY2Vzc2luZyB0aGUgY2FjaGUsIGFuZCBpZiB0aGUgYm9vbGVhbgogICAgICogaXMgRkFMU0UsIGl0IG11c3QgY2FsbCBpbml0aWFsaXplQ2FjaGUoKS4gIFdlIGRvIHRoaXMgZm9ybSBvZiBsYXp5CiAgICAgKiBldmFsdWF0aW9uIGZvciB0d28gcmVhc29uczogKDEpIHNvIHdlIGRvbid0IGluaXRpYWxpemUgaWYgd2UgZG9uJ3QKICAgICAqIGhhdmUgdG8gKGkuZS4sIGlmIG5vIG9uZSBpcyB1c2luZyBUcmFuc2xpdGVyYXRvciwgYnV0IGhhcyBpbmNsdWRlZAogICAgICogdGhlIGNvZGUgYXMgcGFydCBvZiBhIHNoYXJlZCBsaWJyYXJ5LCBhbmQgKDIpIHRvIGF2b2lkIHN0YXRpYwogICAgICogaW50aWFsaXphdGlvbiBwcm9ibGVtcy4KICAgICAqLwogICAgc3RhdGljIGJvb2xfdCBjYWNoZUluaXRpYWxpemVkOwoKICAgIC8qKgogICAgICogSW4gSmF2YSwgdGhlIGNhY2hlIHN0b3JlcyBvYmplY3RzIG9mIGRpZmZlcmVudCB0eXBlcyBhbmQKICAgICAqIHNpbmdsZXRvbiBvYmplY3RzIGFzIHBsYWNlaG9sZGVycyBmb3IgcnVsZS1iYXNlZAogICAgICogdHJhbnNsaXRlcmF0b3JzIHRvIGJlIGJ1aWx0IGFzIG5lZWRlZC4gIEluIEMrKyB3ZSB1c2UgdGhlCiAgICAgKiBmb2xsb3dpbmcgc3RydWN0IHRvIGFjaGlldmUgdGhlIHNhbWUgcHVycG9zZS4gIEluc3RhbmNlcyBvZgogICAgICogdGhpcyBzdHJ1Y3QgY2FuIGJlIHBsYWNlaG9sZGVycywgY2FuIHJlcHJlc2VudCBwcm90b3R5cGUKICAgICAqIHRyYW5zbGl0ZXJhdG9ycyB0byBiZSBjbG9uZWQsIG9yIGNhbiByZXByZXNlbnQKICAgICAqIFJ1bGVCYXNlZFRyYW5zbGl0ZXJhdG9yOjpEYXRhIG9iamVjdHMuICBXZSBkb24ndCBzdXBwb3J0CiAgICAgKiBzdG9yaW5nIGNsYXNzZXMgaW4gdGhlIGNhY2hlIGJlY2F1c2Ugd2UgZG9uJ3QgaGF2ZSB0aGUgcnR0aQogICAgICogaW5mcmFzdHJ1Y3R1cmUgZm9yIGl0LiAgV2UgY291bGQgZWFzaWx5IGFkZCB0aGlzIGlmIHRoZXJlIGlzIGEKICAgICAqIG5lZWQgZm9yIGl0IGluIHRoZSBmdXR1cmUuICBUaGUgcmJGaWxlIGlzIHRoZSByZXNvdXJjZSBidW5kbGUKICAgICAqIGZpbGUgbmFtZSBmb3IgcnVsZS1iYXNlZCB0cmFuc2xpdGVyYXRvcnMuCiAgICAgKi8KICAgIHN0cnVjdCBDYWNoZUVudHJ5IHsKICAgICAgICBlbnVtIFR5cGUgewogICAgICAgICAgICBSVUxFX0JBU0VEX1BMQUNFSE9MREVSLAogICAgICAgICAgICBSRVZFUlNFX1JVTEVfQkFTRURfUExBQ0VIT0xERVIsCiAgICAgICAgICAgIFBST1RPVFlQRSwKICAgICAgICAgICAgUkJUX0RBVEEsCiAgICAgICAgICAgIE5PTkUgLy8gT25seSB1c2VkIGZvciB1bmluaXRpYWxpemVkIGVudHJpZXMKICAgICAgICB9IGVudHJ5VHlwZTsKICAgICAgICBVbmljb2RlU3RyaW5nIHJiRmlsZTsgLy8gRm9yICpQTEFDRUhPTERFUgogICAgICAgIHVuaW9uIHsKICAgICAgICAgICAgVHJhbnNsaXRlcmF0b3IqIHByb3RvdHlwZTsgLy8gRm9yIFBST1RPVFlQRQogICAgICAgICAgICBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YSogZGF0YTsgLy8gRm9yIFJCVF9EQVRBCiAgICAgICAgfSB1OwogICAgICAgIENhY2hlRW50cnkoKTsKICAgICAgICB+Q2FjaGVFbnRyeSgpOwogICAgICAgIHZvaWQgYWRvcHRQcm90b3R5cGUoVHJhbnNsaXRlcmF0b3IqIGFkb3B0ZWQpOwogICAgfTsKCiAgICAvKioKICAgICAqIFByZWZpeCBmb3IgcmVzb3VyY2UgYnVuZGxlIGtleSBmb3IgdGhlIGRpc3BsYXkgbmFtZSBmb3IgYQogICAgICogdHJhbnNsaXRlcmF0b3IuICBUaGUgSUQgaXMgYXBwZW5kZWQgdG8gdGhpcyB0byBmb3JtIHRoZSBrZXkuCiAgICAgKiBUaGUgcmVzb3VyY2UgYnVuZGxlIHZhbHVlIHNob3VsZCBiZSBhIFN0cmluZy4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IGNoYXIqIFJCX0RJU1BMQVlfTkFNRV9QUkVGSVg7CgogICAgLyoqCiAgICAgKiBQcmVmaXggZm9yIHJlc291cmNlIGJ1bmRsZSBrZXkgZm9yIHRoZSBkaXNwbGF5IG5hbWUgZm9yIGEKICAgICAqIHRyYW5zbGl0ZXJhdG9yIFNDUklQVC4gIFRoZSBJRCBpcyBhcHBlbmRlZCB0byB0aGlzIHRvIGZvcm0gdGhlIGtleS4KICAgICAqIFRoZSByZXNvdXJjZSBidW5kbGUgdmFsdWUgc2hvdWxkIGJlIGEgU3RyaW5nLgogICAgICovCiAgICBzdGF0aWMgY29uc3QgY2hhciogUkJfU0NSSVBUX0RJU1BMQVlfTkFNRV9QUkVGSVg7CgogICAgLyoqCiAgICAgKiBSZXNvdXJjZSBidW5kbGUga2V5IGZvciBkaXNwbGF5IG5hbWUgcGF0dGVybi4KICAgICAqIFRoZSByZXNvdXJjZSBidW5kbGUgdmFsdWUgc2hvdWxkIGJlIGEgU3RyaW5nIGZvcm1pbmcgYQogICAgICogTWVzc2FnZUZvcm1hdCBwYXR0ZXJuLCBlLmcuOgogICAgICogInswLGNob2ljZSwwI3wxI3sxfSBUcmFuc2xpdGVyYXRvcnwyI3sxfSB0byB7Mn0gVHJhbnNsaXRlcmF0b3J9Ii4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IGNoYXIqIFJCX0RJU1BMQVlfTkFNRV9QQVRURVJOOwoKICAgIC8qKgogICAgICogUmVzb3VyY2UgYnVuZGxlIGtleSBmb3IgdGhlIGxpc3Qgb2YgUnVsZUJhc2VkVHJhbnNsaXRlcmF0b3IgSURzLgogICAgICogVGhlIHJlc291cmNlIGJ1bmRsZSB2YWx1ZSBzaG91bGQgYmUgYSBTdHJpbmdbXSB3aXRoIGVhY2ggZWxlbWVudAogICAgICogYmVpbmcgYSB2YWxpZCBJRC4gIFRoZSBJRCB3aWxsIGJlIGFwcGVuZGVkIHRvIFJCX1JVTEVfQkFTRURfUFJFRklYCiAgICAgKiB0byBvYnRhaW4gdGhlIGNsYXNzIG5hbWUgaW4gd2hpY2ggdGhlIFJCX1JVTEUga2V5IHdpbGwgYmUgc291Z2h0LgogICAgICovCiAgICBzdGF0aWMgY29uc3QgY2hhciogUkJfUlVMRV9CQVNFRF9JRFM7CgogICAgLyoqCiAgICAgKiBSZXNvdXJjZSBidW5kbGUga2V5IGZvciB0aGUgUnVsZUJhc2VkVHJhbnNsaXRlcmF0b3IgcnVsZS4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IGNoYXIqIFJCX1JVTEU7Cgpwcm90ZWN0ZWQ6CgogICAgLyoqCiAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLgogICAgICogQHBhcmFtIElEIHRoZSBzdHJpbmcgaWRlbnRpZmllciBmb3IgdGhpcyB0cmFuc2xpdGVyYXRvcgogICAgICogQHBhcmFtIGFkb3B0ZWRGaWx0ZXIgdGhlIGZpbHRlci4gIEFueSBjaGFyYWN0ZXIgZm9yIHdoaWNoCiAgICAgKiA8dHQ+ZmlsdGVyLmNvbnRhaW5zKCk8L3R0PiByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+IHdpbGwgbm90IGJlCiAgICAgKiBhbHRlcmVkIGJ5IHRoaXMgdHJhbnNsaXRlcmF0b3IuICBJZiA8dHQ+ZmlsdGVyPC90dD4gaXMKICAgICAqIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgaXMgYXBwbGllZC4KICAgICAqLwogICAgVHJhbnNsaXRlcmF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgSUQsIFVuaWNvZGVGaWx0ZXIqIGFkb3B0ZWRGaWx0ZXIpOwoKICAgIC8qKgogICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICAqLwogICAgVHJhbnNsaXRlcmF0b3IoY29uc3QgVHJhbnNsaXRlcmF0b3ImKTsKCiAgICAvKioKICAgICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IuCiAgICAgKi8KICAgIFRyYW5zbGl0ZXJhdG9yJiBvcGVyYXRvcj0oY29uc3QgVHJhbnNsaXRlcmF0b3ImKTsKCnB1YmxpYzoKCiAgICAvKioKICAgICAqIERlc3RydWN0b3IuCiAgICAgKi8KICAgIHZpcnR1YWwgflRyYW5zbGl0ZXJhdG9yKCk7CgogICAgLyoqCiAgICAgKiBJbXBsZW1lbnRzIENsb25lYWJsZS4KICAgICAqIEFsbCBzdWJjbGFzc2VzIGFyZSBlbmNvdXJhZ2VkIHRvIGltcGxlbWVudCB0aGlzIG1ldGhvZCBpZiBpdCBpcwogICAgICogcG9zc2libGUgYW5kIHJlYXNvbmFibGUgdG8gZG8gc28uICBTdWJjbGFzc2VzIHRoYXQgYXJlIHRvIGJlCiAgICAgKiByZWdpc3RlcmVkIHdpdGggdGhlIHN5c3RlbSB1c2luZyA8dHQ+cmVnaXN0ZXJJbnN0YW5jZSgpPHR0PgogICAgICogYXJlIHJlcXVpcmVkIHRvIGltcGxlbWVudCB0aGlzIG1ldGhvZC4gIElmIGEgc3ViY2xhc3MgZG9lcyBub3QKICAgICAqIGltcGxlbWVudCBjbG9uZSgpIHByb3Blcmx5IGFuZCBpcyByZWdpc3RlcmVkIHdpdGggdGhlIHN5c3RlbQogICAgICogdXNpbmcgcmVnaXN0ZXJJbnN0YW5jZSgpLCB0aGVuIHRoZSBkZWZhdWx0IGNsb25lKCkgaW1wbGVtZW50YXRpb24KICAgICAqIHdpbGwgcmV0dXJuIG51bGwsIGFuZCBjYWxscyB0byBjcmVhdGVJbnN0YW5jZSgpIHdpbGwgZmFpbC4KICAgICAqCiAgICAgKiBAc2VlICNyZWdpc3Rlckluc3RhbmNlCiAgICAgKi8KICAgIHZpcnR1YWwgVHJhbnNsaXRlcmF0b3IqIGNsb25lKCkgY29uc3QgeyByZXR1cm4gMDsgfQoKICAgIC8qKgogICAgICogVHJhbnNsaXRlcmF0ZXMgYSBzZWdtZW50IG9mIGEgc3RyaW5nLCB3aXRoIG9wdGlvbmFsIGZpbHRlcmluZy4KICAgICAqCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgc3RyaW5nIHRvIGJlIHRyYW5zbGl0ZXJhdGVkCiAgICAgKiBAcGFyYW0gc3RhcnQgdGhlIGJlZ2lubmluZyBpbmRleCwgaW5jbHVzaXZlOyA8Y29kZT4wIDw9IHN0YXJ0CiAgICAgKiA8PSBsaW1pdDwvY29kZT4uCiAgICAgKiBAcGFyYW0gbGltaXQgdGhlIGVuZGluZyBpbmRleCwgZXhjbHVzaXZlOyA8Y29kZT5zdGFydCA8PSBsaW1pdAogICAgICogPD0gdGV4dC5sZW5ndGgoKTwvY29kZT4uCiAgICAgKiBAcGFyYW0gZmlsdGVyIHRoZSBmaWx0ZXIuICBBbnkgY2hhcmFjdGVyIGZvciB3aGljaAogICAgICogPHR0PmZpbHRlci5jb250YWlucygpPC90dD4gcmV0dXJucyA8dHQ+ZmFsc2U8L3R0PiB3aWxsIG5vdCBiZQogICAgICogYWx0ZXJlZCBieSB0aGlzIHRyYW5zbGl0ZXJhdG9yLiAgSWYgPHR0PmZpbHRlcjwvdHQ+IGlzCiAgICAgKiA8dHQ+bnVsbDwvdHQ+IHRoZW4gbm8gZmlsdGVyaW5nIGlzIGFwcGxpZWQuCiAgICAgKiBAcmV0dXJuIFRoZSBuZXcgbGltaXQgaW5kZXguICBUaGUgdGV4dCBwcmV2aW91c2x5IG9jY3VweWluZyA8Y29kZT5bc3RhcnQsCiAgICAgKiBsaW1pdCk8L2NvZGU+IGhhcyBiZWVuIHRyYW5zbGl0ZXJhdGVkLCBwb3NzaWJseSB0byBhIHN0cmluZyBvZiBhIGRpZmZlcmVudAogICAgICogbGVuZ3RoLCBhdCA8Y29kZT5bc3RhcnQsIDwvY29kZT48ZW0+bmV3LWxpbWl0PC9lbT48Y29kZT4pPC9jb2RlPiwgd2hlcmUKICAgICAqIDxlbT5uZXctbGltaXQ8L2VtPiBpcyB0aGUgcmV0dXJuIHZhbHVlLgogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgdHJhbnNsaXRlcmF0ZShSZXBsYWNlYWJsZSYgdGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc3RhcnQsIGludDMyX3QgbGltaXQpIGNvbnN0OwoKICAgIC8qKgogICAgICogVHJhbnNsaXRlcmF0ZXMgYW4gZW50aXJlIHN0cmluZyBpbiBwbGFjZS4gQ29udmVuaWVuY2UgbWV0aG9kLgogICAgICogQHBhcmFtIHRleHQgdGhlIHN0cmluZyB0byBiZSB0cmFuc2xpdGVyYXRlZAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgdHJhbnNsaXRlcmF0ZShSZXBsYWNlYWJsZSYgdGV4dCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBUcmFuc2xpdGVyYXRlcyB0aGUgcG9ydGlvbiBvZiB0aGUgdGV4dCBidWZmZXIgdGhhdCBjYW4gYmUKICAgICAqIHRyYW5zbGl0ZXJhdGVkIHVuYW1iaWd1b3NseSBhZnRlciBuZXcgdGV4dCBoYXMgYmVlbiBpbnNlcnRlZCwKICAgICAqIHR5cGljYWxseSBhcyBhIHJlc3VsdCBvZiBhIGtleWJvYXJkIGV2ZW50LiAgVGhlIG5ldyB0ZXh0IGluCiAgICAgKiA8Y29kZT5pbnNlcnRpb248L2NvZGU+IHdpbGwgYmUgaW5zZXJ0ZWQgaW50byA8Y29kZT50ZXh0PC9jb2RlPgogICAgICogYXQgPGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+LCBhZHZhbmNpbmcKICAgICAqIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPiBieSA8Y29kZT5pbnNlcnRpb24ubGVuZ3RoKCk8L2NvZGU+LgogICAgICogVGhlbiB0aGUgdHJhbnNsaXRlcmF0b3Igd2lsbCB0cnkgdG8gdHJhbnNsaXRlcmF0ZSBjaGFyYWN0ZXJzIG9mCiAgICAgKiA8Y29kZT50ZXh0PC9jb2RlPiBiZXR3ZWVuIDxjb2RlPmluZGV4LmN1cnNvcjwvY29kZT4gYW5kCiAgICAgKiA8Y29kZT5pbmRleC5saW1pdDwvY29kZT4uICBDaGFyYWN0ZXJzIGJlZm9yZQogICAgICogPGNvZGU+aW5kZXguY3Vyc29yPC9jb2RlPiB3aWxsIG5vdCBiZSBjaGFuZ2VkLgogICAgICoKICAgICAqIDxwPlVwb24gcmV0dXJuLCB2YWx1ZXMgaW4gPGNvZGU+aW5kZXg8L2NvZGU+IHdpbGwgYmUgdXBkYXRlZC4KICAgICAqIDxjb2RlPmluZGV4LnN0YXJ0PC9jb2RlPiB3aWxsIGJlIGFkdmFuY2VkIHRvIHRoZSBmaXJzdAogICAgICogY2hhcmFjdGVyIHRoYXQgZnV0dXJlIGNhbGxzIHRvIHRoaXMgbWV0aG9kIHdpbGwgcmVhZC4KICAgICAqIDxjb2RlPmluZGV4LmN1cnNvcjwvY29kZT4gYW5kIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPiB3aWxsCiAgICAgKiBiZSBhZGp1c3RlZCB0byBkZWxpbWl0IHRoZSByYW5nZSBvZiB0ZXh0IHRoYXQgZnV0dXJlIGNhbGxzIHRvCiAgICAgKiB0aGlzIG1ldGhvZCBtYXkgY2hhbmdlLgogICAgICoKICAgICAqIDxwPlR5cGljYWwgdXNhZ2Ugb2YgdGhpcyBtZXRob2QgYmVnaW5zIHdpdGggYW4gaW5pdGlhbCBjYWxsCiAgICAgKiB3aXRoIDxjb2RlPmluZGV4LnN0YXJ0PC9jb2RlPiBhbmQgPGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+CiAgICAgKiBzZXQgdG8gaW5kaWNhdGUgdGhlIHBvcnRpb24gb2YgPGNvZGU+dGV4dDwvY29kZT4gdG8gYmUKICAgICAqIHRyYW5zbGl0ZXJhdGVkLCBhbmQgPGNvZGU+aW5kZXguY3Vyc29yID09IGluZGV4LnN0YXJ0PC9jb2RlPi4KICAgICAqIFRoZXJlYWZ0ZXIsIDxjb2RlPmluZGV4PC9jb2RlPiBjYW4gYmUgdXNlZCB3aXRob3V0CiAgICAgKiBtb2RpZmljYXRpb24gaW4gZnV0dXJlIGNhbGxzLCBwcm92aWRlZCB0aGF0IGFsbCBjaGFuZ2VzIHRvCiAgICAgKiA8Y29kZT50ZXh0PC9jb2RlPiBhcmUgbWFkZSB2aWEgdGhpcyBtZXRob2QuCiAgICAgKgogICAgICogPHA+VGhpcyBtZXRob2QgYXNzdW1lcyB0aGF0IGZ1dHVyZSBjYWxscyBtYXkgYmUgbWFkZSB0aGF0IHdpbGwKICAgICAqIGluc2VydCBuZXcgdGV4dCBpbnRvIHRoZSBidWZmZXIuICBBcyBhIHJlc3VsdCwgaXQgb25seSBwZXJmb3JtcwogICAgICogdW5hbWJpZ3VvdXMgdHJhbnNsaXRlcmF0aW9ucy4gIEFmdGVyIHRoZSBsYXN0IGNhbGwgdG8gdGhpcwogICAgICogbWV0aG9kLCB0aGVyZSBtYXkgYmUgdW50cmFuc2xpdGVyYXRlZCB0ZXh0IHRoYXQgaXMgd2FpdGluZyBmb3IKICAgICAqIG1vcmUgaW5wdXQgdG8gcmVzb2x2ZSBhbiBhbWJpZ3VpdHkuICBJbiBvcmRlciB0byBwZXJmb3JtIHRoZXNlCiAgICAgKiBwZW5kaW5nIHRyYW5zbGl0ZXJhdGlvbnMsIGNsaWVudHMgc2hvdWxkIGNhbGwge0BsaW5rCiAgICAgKiAjZmluaXNoVHJhbnNsaXRlcmF0aW9ufSBhZnRlciB0aGUgbGFzdCBjYWxsIHRvIHRoaXMKICAgICAqIG1ldGhvZCBoYXMgYmVlbiBtYWRlLgogICAgICogCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgYnVmZmVyIGhvbGRpbmcgdHJhbnNsaXRlcmF0ZWQgYW5kIHVudHJhbnNsaXRlcmF0ZWQgdGV4dAogICAgICogQHBhcmFtIGluZGV4IGFuIGFycmF5IG9mIHRocmVlIGludGVnZXJzLgogICAgICoKICAgICAqIDx1bD48bGk+PGNvZGU+aW5kZXguc3RhcnQ8L2NvZGU+OiB0aGUgYmVnaW5uaW5nIGluZGV4LAogICAgICogaW5jbHVzaXZlOyA8Y29kZT4wIDw9IGluZGV4LnN0YXJ0IDw9IGluZGV4LmxpbWl0PC9jb2RlPi4KICAgICAqCiAgICAgKiA8bGk+PGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+OiB0aGUgZW5kaW5nIGluZGV4LCBleGNsdXNpdmU7CiAgICAgKiA8Y29kZT5pbmRleC5zdGFydCA8PSBpbmRleC5saW1pdCA8PSB0ZXh0Lmxlbmd0aCgpPC9jb2RlPi4KICAgICAqIDxjb2RlPmluc2VydGlvbjwvY29kZT4gaXMgaW5zZXJ0ZWQgYXQKICAgICAqIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPi4KICAgICAqCiAgICAgKiA8bGk+PGNvZGU+aW5kZXguY3Vyc29yPC9jb2RlPjogdGhlIG5leHQgY2hhcmFjdGVyIHRvIGJlCiAgICAgKiBjb25zaWRlcmVkIGZvciB0cmFuc2xpdGVyYXRpb247IDxjb2RlPmluZGV4LnN0YXJ0IDw9CiAgICAgKiBpbmRleC5jdXJzb3IgPD0gaW5kZXgubGltaXQ8L2NvZGU+LiAgQ2hhcmFjdGVycyBiZWZvcmUKICAgICAqIDxjb2RlPmluZGV4LmN1cnNvcjwvY29kZT4gd2lsbCBub3QgYmUgY2hhbmdlZCBieSBmdXR1cmUgY2FsbHMKICAgICAqIHRvIHRoaXMgbWV0aG9kLjwvdWw+CiAgICAgKgogICAgICogQHBhcmFtIGluc2VydGlvbiB0ZXh0IHRvIGJlIGluc2VydGVkIGFuZCBwb3NzaWJseQogICAgICogdHJhbnNsaXRlcmF0ZWQgaW50byB0aGUgdHJhbnNsYXRpb24gYnVmZmVyIGF0CiAgICAgKiA8Y29kZT5pbmRleC5saW1pdDwvY29kZT4uICBJZiA8Y29kZT5udWxsPC9jb2RlPiB0aGVuIG5vIHRleHQKICAgICAqIGlzIGluc2VydGVkLgogICAgICogQHNlZSAjaGFuZGxlVHJhbnNsaXRlcmF0ZQogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgPGNvZGU+aW5kZXg8L2NvZGU+CiAgICAgKiBpcyBpbnZhbGlkCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCB0cmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlJiB0ZXh0LCBQb3NpdGlvbiYgaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nJiBpbnNlcnRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwoKICAgIC8qKgogICAgICogVHJhbnNsaXRlcmF0ZXMgdGhlIHBvcnRpb24gb2YgdGhlIHRleHQgYnVmZmVyIHRoYXQgY2FuIGJlCiAgICAgKiB0cmFuc2xpdGVyYXRlZCB1bmFtYmlndW9zbHkgYWZ0ZXIgYSBuZXcgY2hhcmFjdGVyIGhhcyBiZWVuCiAgICAgKiBpbnNlcnRlZCwgdHlwaWNhbGx5IGFzIGEgcmVzdWx0IG9mIGEga2V5Ym9hcmQgZXZlbnQuICBUaGlzIGlzIGEKICAgICAqIGNvbnZlbmllbmNlIG1ldGhvZDsgc2VlIHtAbGluawogICAgICogI3RyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUsIGludFtdLCBTdHJpbmcpfSBmb3IgZGV0YWlscy4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSBidWZmZXIgaG9sZGluZyB0cmFuc2xpdGVyYXRlZCBhbmQKICAgICAqIHVudHJhbnNsaXRlcmF0ZWQgdGV4dAogICAgICogQHBhcmFtIGluZGV4IGFuIGFycmF5IG9mIHRocmVlIGludGVnZXJzLiAgU2VlIHtAbGluawogICAgICogI3RyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUsIGludFtdLCBTdHJpbmcpfS4KICAgICAqIEBwYXJhbSBpbnNlcnRpb24gdGV4dCB0byBiZSBpbnNlcnRlZCBhbmQgcG9zc2libHkKICAgICAqIHRyYW5zbGl0ZXJhdGVkIGludG8gdGhlIHRyYW5zbGF0aW9uIGJ1ZmZlciBhdAogICAgICogPGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+LgogICAgICogQHNlZSAjdHJhbnNsaXRlcmF0ZShSZXBsYWNlYWJsZSwgaW50W10sIFN0cmluZykKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHRyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUmIHRleHQsIFBvc2l0aW9uJiBpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDaGFyIGluc2VydGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CiAgICAKICAgIC8qKgogICAgICogVHJhbnNsaXRlcmF0ZXMgdGhlIHBvcnRpb24gb2YgdGhlIHRleHQgYnVmZmVyIHRoYXQgY2FuIGJlCiAgICAgKiB0cmFuc2xpdGVyYXRlZCB1bmFtYmlndW9zbHkuICBUaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kOyBzZWUKICAgICAqIHtAbGluayAjdHJhbnNsaXRlcmF0ZShSZXBsYWNlYWJsZSwgaW50W10sIFN0cmluZyl9IGZvcgogICAgICogZGV0YWlscy4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSBidWZmZXIgaG9sZGluZyB0cmFuc2xpdGVyYXRlZCBhbmQKICAgICAqIHVudHJhbnNsaXRlcmF0ZWQgdGV4dAogICAgICogQHBhcmFtIGluZGV4IGFuIGFycmF5IG9mIHRocmVlIGludGVnZXJzLiAgU2VlIHtAbGluawogICAgICogI3RyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUsIGludFtdLCBTdHJpbmcpfS4KICAgICAqIEBzZWUgI3RyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUsIGludFtdLCBTdHJpbmcpCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCB0cmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlJiB0ZXh0LCBQb3NpdGlvbiYgaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwoKICAgIC8qKgogICAgICogRmluaXNoZXMgYW55IHBlbmRpbmcgdHJhbnNsaXRlcmF0aW9ucyB0aGF0IHdlcmUgd2FpdGluZyBmb3IKICAgICAqIG1vcmUgY2hhcmFjdGVycy4gIENsaWVudHMgc2hvdWxkIGNhbGwgdGhpcyBtZXRob2QgYXMgdGhlIGxhc3QKICAgICAqIGNhbGwgYWZ0ZXIgYSBzZXF1ZW5jZSBvZiBvbmUgb3IgbW9yZSBjYWxscyB0bwogICAgICogPGNvZGU+dHJhbnNsaXRlcmF0ZSgpPC9jb2RlPi4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSBidWZmZXIgaG9sZGluZyB0cmFuc2xpdGVyYXRlZCBhbmQKICAgICAqIHVudHJhbnNsaXRlcmF0ZWQgdGV4dC4KICAgICAqIEBwYXJhbSBpbmRleCB0aGUgYXJyYXkgb2YgaW5kaWNlcyBwcmV2aW91c2x5IHBhc3NlZCB0byB7QGxpbmsKICAgICAqICN0cmFuc2xpdGVyYXRlfQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgZmluaXNoVHJhbnNsaXRlcmF0aW9uKFJlcGxhY2VhYmxlJiB0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb3NpdGlvbiYgaW5kZXgpIGNvbnN0OwoKcHJpdmF0ZToKCiAgICAvKioKICAgICAqIFRoaXMgaW50ZXJuYWwgbWV0aG9kIGRvZXMgaW5jcmVtZW50YWwgdHJhbnNsaXRlcmF0aW9uLiAgSWYgdGhlCiAgICAgKiAnaW5zZXJ0aW9uJyBpcyBub24tbnVsbCB0aGVuIHdlIGFwcGVuZCBpdCB0byAndGV4dCcgYmVmb3JlCiAgICAgKiBwcm9jZWVkaW5nLiAgVGhpcyBtZXRob2QgY2FsbHMgdGhyb3VnaCB0byB0aGUgcHVyZSB2aXJ0dWFsCiAgICAgKiBmcmFtZXdvcmsgbWV0aG9kIGhhbmRsZVRyYW5zbGl0ZXJhdGUoKSB0byBkbyB0aGUgYWN0dWFsCiAgICAgKiB3b3JrLgogICAgICovCiAgICB2b2lkIF90cmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlJiB0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICBQb3NpdGlvbiYgaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcqIGluc2VydGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSAmc3RhdHVzKSBjb25zdDsKCnByb3RlY3RlZDoKCiAgICAvKioKICAgICAqIEFic3RyYWN0IG1ldGhvZCB0aGF0IGNvbmNyZXRlIHN1YmNsYXNzZXMgZGVmaW5lIHRvIGltcGxlbWVudAogICAgICoga2V5Ym9hcmQgdHJhbnNsaXRlcmF0aW9uLiAgVGhpcyBtZXRob2Qgc2hvdWxkIHRyYW5zbGl0ZXJhdGUgYWxsCiAgICAgKiBjaGFyYWN0ZXJzIGJldHdlZW4gPGNvZGU+aW5kZXguY3Vyc29yPC9jb2RlPiBhbmQKICAgICAqIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPiB0aGF0IGNhbiBiZSB1bmFtYmlndW91c2x5CiAgICAgKiB0cmFuc2xpdGVyYXRlZCwgcmVnYXJkbGVzcyBvZiBmdXR1cmUgaW5zZXJ0aW9ucyBvZiB0ZXh0IGF0CiAgICAgKiA8Y29kZT5pbmRleC5saW1pdDwvY29kZT4uICA8Y29kZT5pbmRleC5jdXJzb3I8L2NvZGU+IHNob3VsZAogICAgICogYmUgYWR2YW5jZWQgcGFzdCBjb21taXR0ZWQgY2hhcmFjdGVycyAodGhvc2UgdGhhdCB3aWxsIG5vdAogICAgICogY2hhbmdlIGluIGZ1dHVyZSBjYWxscyB0byB0aGlzIG1ldGhvZCkuCiAgICAgKiA8Y29kZT5pbmRleC5saW1pdDwvY29kZT4gc2hvdWxkIGJlIHVwZGF0ZWQgdG8gcmVmbGVjdCB0ZXh0CiAgICAgKiByZXBsYWNlbWVudHMgdGhhdCBzaG9ydGVuIG9yIGxlbmd0aGVuIHRoZSB0ZXh0IGJldHdlZW4KICAgICAqIDxjb2RlPmluZGV4LmN1cnNvcjwvY29kZT4gYW5kIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPi4gIFVwb24KICAgICAqIHJldHVybiwgbmVpdGhlciA8Y29kZT5pbmRleC5jdXJzb3I8L2NvZGU+IG5vcgogICAgICogPGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+IHNob3VsZCBiZSBsZXNzIHRoYW4gdGhlIGluaXRpYWwgdmFsdWUKICAgICAqIG9mIDxjb2RlPmluZGV4LmN1cnNvcjwvY29kZT4uICA8Y29kZT5pbmRleC5zdGFydDwvY29kZT4KICAgICAqIHNob3VsZCA8ZW0+bm90PC9lbT4gYmUgY2hhbmdlZC4KICAgICAqCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgYnVmZmVyIGhvbGRpbmcgdHJhbnNsaXRlcmF0ZWQgYW5kCiAgICAgKiB1bnRyYW5zbGl0ZXJhdGVkIHRleHQKICAgICAqIEBwYXJhbSBpbmRleCBhbiBhcnJheSBvZiB0aHJlZSBpbnRlZ2Vycy4gIFNlZSB7QGxpbmsKICAgICAqICN0cmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlLCBpbnRbXSwgU3RyaW5nKX0uCiAgICAgKiBAc2VlICN0cmFuc2xpdGVyYXRlCiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBoYW5kbGVUcmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlJiB0ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9zaXRpb24mIGluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbF90IGluY3JlbWVudGFsKSBjb25zdCA9IDA7CgogICAgLy8gQysrIHJlcXVpcmVzIHRoaXMgZnJpZW5kIGRlY2xhcmF0aW9uIHNvIENvbXBvdW5kVHJhbnNsaXRlcmF0b3IKICAgIC8vIGNhbiBhY2Nlc3MgaGFuZGxlVHJhbnNsaXRlcmF0ZS4gIEFsdGVybmF0aXZlbHksIHdlIGNvdWxkCiAgICAvLyBtYWtlIGhhbmRsZVRyYW5zbGl0ZXJhdGUgcHVibGljLgogICAgZnJpZW5kIGNsYXNzIENvbXBvdW5kVHJhbnNsaXRlcmF0b3I7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIGxvbmdlc3QgY29udGV4dCByZXF1aXJlZCBieSB0aGlzIHRyYW5zbGl0ZXJhdG9yLgogICAgICogVGhpcyBpcyA8ZW0+cHJlY2VkaW5nPC9lbT4gY29udGV4dC4gIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHN1cHBsaWVkCiAgICAgKiBieSA8Y29kZT5UcmFuc2xpdGVyYXRvcjwvY29kZT4gcmV0dXJucyB6ZXJvOyBzdWJjbGFzc2VzCiAgICAgKiB0aGF0IHVzZSBwcmVjZWRpbmcgY29udGV4dCBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcmV0dXJuIHRoZQogICAgICogY29ycmVjdCB2YWx1ZS4gIEZvciBleGFtcGxlLCBpZiBhIHRyYW5zbGl0ZXJhdG9yIHRyYW5zbGF0ZXMgImRkZCIgKHdoZXJlCiAgICAgKiBkIGlzIGFueSBkaWdpdCkgdG8gIjU1NSIgd2hlbiBwcmVjZWRlZCBieSAiKGRkZCkiLCB0aGVuIHRoZSBwcmVjZWRpbmcKICAgICAqIGNvbnRleHQgbGVuZ3RoIGlzIDUsIHRoZSBsZW5ndGggb2YgIihkZGQpIi4KICAgICAqCiAgICAgKiBAcmV0dXJuIFRoZSBtYXhpbXVtIG51bWJlciBvZiBwcmVjZWRpbmcgY29udGV4dCBjaGFyYWN0ZXJzIHRoaXMKICAgICAqIHRyYW5zbGl0ZXJhdG9yIG5lZWRzIHRvIGV4YW1pbmUKICAgICAqLwogICAgaW50MzJfdCBnZXRNYXhpbXVtQ29udGV4dExlbmd0aCh2b2lkKSBjb25zdDsKCnByb3RlY3RlZDoKCiAgICAvKioKICAgICAqIE1ldGhvZCBmb3Igc3ViY2xhc3NlcyB0byB1c2UgdG8gc2V0IHRoZSBtYXhpbXVtIGNvbnRleHQgbGVuZ3RoLgogICAgICogQHNlZSAjZ2V0TWF4aW11bUNvbnRleHRMZW5ndGgKICAgICAqLwogICAgdm9pZCBzZXRNYXhpbXVtQ29udGV4dExlbmd0aChpbnQzMl90IG1heENvbnRleHRMZW5ndGgpOwoKcHVibGljOgoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHByb2dyYW1tYXRpYyBpZGVudGlmaWVyIGZvciB0aGlzIHRyYW5zbGl0ZXJhdG9yLgogICAgICogSWYgdGhpcyBpZGVudGlmaWVyIGlzIHBhc3NlZCB0byA8Y29kZT5nZXRJbnN0YW5jZSgpPC9jb2RlPiwgaXQKICAgICAqIHdpbGwgcmV0dXJuIHRoaXMgb2JqZWN0LCBpZiBpdCBoYXMgYmVlbiByZWdpc3RlcmVkLgogICAgICogQHNlZSAjcmVnaXN0ZXJJbnN0YW5jZQogICAgICogQHNlZSAjcmVnaXN0ZXJDbGFzcwogICAgICogQHNlZSAjZ2V0QXZhaWxhYmxlSURzCiAgICAgKi8KICAgIHZpcnR1YWwgY29uc3QgVW5pY29kZVN0cmluZyYgZ2V0SUQodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgbmFtZSBmb3IgdGhpcyB0cmFuc2xpdGVyYXRvciB0aGF0IGlzIGFwcHJvcHJpYXRlIGZvcgogICAgICogZGlzcGxheSB0byB0aGUgdXNlciBpbiB0aGUgZGVmYXVsdCBsb2NhbGUuICBTZWUge0BsaW5rCiAgICAgKiAjZ2V0RGlzcGxheU5hbWUoTG9jYWxlKX0gZm9yIGRldGFpbHMuCiAgICAgKi8KICAgIHN0YXRpYyBVbmljb2RlU3RyaW5nJiBnZXREaXNwbGF5TmFtZShjb25zdCBVbmljb2RlU3RyaW5nJiBJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiByZXN1bHQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIG5hbWUgZm9yIHRoaXMgdHJhbnNsaXRlcmF0b3IgdGhhdCBpcyBhcHByb3ByaWF0ZSBmb3IKICAgICAqIGRpc3BsYXkgdG8gdGhlIHVzZXIgaW4gdGhlIGdpdmVuIGxvY2FsZS4gIFRoaXMgbmFtZSBpcyB0YWtlbgogICAgICogZnJvbSB0aGUgbG9jYWxlIHJlc291cmNlIGRhdGEgaW4gdGhlIHN0YW5kYXJkIG1hbm5lciBvZiB0aGUKICAgICAqIDxjb2RlPmphdmEudGV4dDwvY29kZT4gcGFja2FnZS4KICAgICAqCiAgICAgKiA8cD5JZiBubyBsb2NhbGl6ZWQgbmFtZXMgZXhpc3QgaW4gdGhlIHN5c3RlbSByZXNvdXJjZSBidW5kbGVzLAogICAgICogYSBuYW1lIGlzIHN5bnRoZXNpemVkIHVzaW5nIGEgbG9jYWxpemVkCiAgICAgKiA8Y29kZT5NZXNzYWdlRm9ybWF0PC9jb2RlPiBwYXR0ZXJuIGZyb20gdGhlIHJlc291cmNlIGRhdGEuICBUaGUKICAgICAqIGFyZ3VtZW50cyB0byB0aGlzIHBhdHRlcm4gYXJlIGFuIGludGVnZXIgZm9sbG93ZWQgYnkgb25lIG9yIHR3bwogICAgICogc3RyaW5ncy4gIFRoZSBpbnRlZ2VyIGlzIHRoZSBudW1iZXIgb2Ygc3RyaW5ncywgZWl0aGVyIDEgb3IgMi4KICAgICAqIFRoZSBzdHJpbmdzIGFyZSBmb3JtZWQgYnkgc3BsaXR0aW5nIHRoZSBJRCBmb3IgdGhpcwogICAgICogdHJhbnNsaXRlcmF0b3IgYXQgdGhlIGZpcnN0ICctJy4gIElmIHRoZXJlIGlzIG5vICctJywgdGhlbiB0aGUKICAgICAqIGVudGlyZSBJRCBmb3JtcyB0aGUgb25seSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gaW5Mb2NhbGUgdGhlIExvY2FsZSBpbiB3aGljaCB0aGUgZGlzcGxheSBuYW1lIHNob3VsZCBiZQogICAgICogbG9jYWxpemVkLgogICAgICogQHNlZSBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdAogICAgICovCiAgICBzdGF0aWMgVW5pY29kZVN0cmluZyYgZ2V0RGlzcGxheU5hbWUoY29uc3QgVW5pY29kZVN0cmluZyYgSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYWxlJiBpbkxvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiByZXN1bHQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZmlsdGVyIHVzZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvciwgb3IgPHR0Pm51bGw8L3R0PgogICAgICogaWYgdGhpcyB0cmFuc2xpdGVyYXRvciB1c2VzIG5vIGZpbHRlci4KICAgICAqLwogICAgdmlydHVhbCBjb25zdCBVbmljb2RlRmlsdGVyKiBnZXRGaWx0ZXIodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBDaGFuZ2VzIHRoZSBmaWx0ZXIgdXNlZCBieSB0aGlzIHRyYW5zbGl0ZXJhdG9yLiAgSWYgdGhlIGZpbHRlcgogICAgICogaXMgc2V0IHRvIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgd2lsbCBvY2N1ci4KICAgICAqCiAgICAgKiA8cD5DYWxsZXJzIG11c3QgdGFrZSBjYXJlIGlmIGEgdHJhbnNsaXRlcmF0b3IgaXMgaW4gdXNlIGJ5CiAgICAgKiBtdWx0aXBsZSB0aHJlYWRzLiAgVGhlIGZpbHRlciBzaG91bGQgbm90IGJlIGNoYW5nZWQgYnkgb25lCiAgICAgKiB0aHJlYWQgd2hpbGUgYW5vdGhlciB0aHJlYWQgbWF5IGJlIHRyYW5zbGl0ZXJhdGluZy4KICAgICAqLwogICAgdmlydHVhbCB2b2lkIGFkb3B0RmlsdGVyKFVuaWNvZGVGaWx0ZXIqIGFkb3B0ZWRGaWx0ZXIpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGlzIHRyYW5zbGl0ZXJhdG9yJ3MgaW52ZXJzZS4gIFNlZSB0aGUgY2xhc3MKICAgICAqIGRvY3VtZW50YXRpb24gZm9yIGRldGFpbHMuICBUaGlzIGltcGxlbWVudGF0aW9uIHNpbXBseSBpbnZlcnRzCiAgICAgKiB0aGUgdHdvIGVudGl0aWVzIGluIHRoZSBJRCBhbmQgYXR0ZW1wdHMgdG8gcmV0cmlldmUgdGhlCiAgICAgKiByZXN1bHRpbmcgdHJhbnNsaXRlcmF0b3IuICBUaGF0IGlzLCBpZiA8Y29kZT5nZXRJRCgpPC9jb2RlPgogICAgICogcmV0dXJucyAiQS1CIiwgdGhlbiB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiB0aGUgcmVzdWx0IG9mCiAgICAgKiA8Y29kZT5nZXRJbnN0YW5jZSgiQi1BIik8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGF0CiAgICAgKiBjYWxsIGZhaWxzLgogICAgICoKICAgICAqIDxwPlRoaXMgbWV0aG9kIGRvZXMgbm90IHRha2UgZmlsdGVyaW5nIGludG8gYWNjb3VudC4gIFRoZQogICAgICogcmV0dXJuZWQgdHJhbnNsaXRlcmF0b3Igd2lsbCBoYXZlIG5vIGZpbHRlci4KICAgICAqCiAgICAgKiA8cD5TdWJjbGFzc2VzIHdpdGgga25vd2xlZGdlIG9mIHRoZWlyIGludmVyc2UgbWF5IHdpc2ggdG8KICAgICAqIG92ZXJyaWRlIHRoaXMgbWV0aG9kLgogICAgICoKICAgICAqIEByZXR1cm4gYSB0cmFuc2xpdGVyYXRvciB0aGF0IGlzIGFuIGludmVyc2UsIG5vdCBuZWNlc3NhcmlseQogICAgICogZXhhY3QsIG9mIHRoaXMgdHJhbnNsaXRlcmF0b3IsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vIHN1Y2gKICAgICAqIHRyYW5zbGl0ZXJhdG9yIGlzIHJlZ2lzdGVyZWQuCiAgICAgKiBAc2VlICNyZWdpc3Rlckluc3RhbmNlCiAgICAgKi8KICAgIFRyYW5zbGl0ZXJhdG9yKiBjcmVhdGVJbnZlcnNlKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIDxjb2RlPlRyYW5zbGl0ZXJhdG9yPC9jb2RlPiBvYmplY3QgZ2l2ZW4gaXRzIElELgogICAgICogVGhlIElEIG11c3QgYmUgZWl0aGVyIGEgc3lzdGVtIHRyYW5zbGl0ZXJhdG9yIElEIG9yIGEgSUQgcmVnaXN0ZXJlZAogICAgICogdXNpbmcgPGNvZGU+cmVnaXN0ZXJJbnN0YW5jZSgpPC9jb2RlPi4KICAgICAqCiAgICAgKiBAcGFyYW0gSUQgYSB2YWxpZCBJRCwgYXMgZW51bWVyYXRlZCBieSA8Y29kZT5nZXRBdmFpbGFibGVJRHMoKTwvY29kZT4KICAgICAqIEByZXR1cm4gQSA8Y29kZT5UcmFuc2xpdGVyYXRvcjwvY29kZT4gb2JqZWN0IHdpdGggdGhlIGdpdmVuIElECiAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiB0aGUgZ2l2ZW4gSUQgaXMgaW52YWxpZC4KICAgICAqIEBzZWUgI3JlZ2lzdGVySW5zdGFuY2UKICAgICAqIEBzZWUgI2dldEF2YWlsYWJsZUlEcwogICAgICogQHNlZSAjZ2V0SUQKICAgICAqLwogICAgc3RhdGljIFRyYW5zbGl0ZXJhdG9yKiBjcmVhdGVJbnN0YW5jZShjb25zdCBVbmljb2RlU3RyaW5nJiBJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGlyZWN0aW9uIGRpciA9IEZPUldBUkQpOwoKcHJpdmF0ZToKCiAgICAvKioKICAgICAqIFRoaXMgaXMgdGhlIHBhdGggdG8gdGhlIHN1YmRpcmVjdG9yeSB3aXRoaW4gdGhlIGxvY2FsZSBkYXRhCiAgICAgKiBkaXJlY3RvcnkgdGhhdCBjb250YWlucyB0aGUgcnVsZS1iYXNlZCB0cmFuc2xpdGVyYXRvciByZXNvdXJjZQogICAgICogYnVuZGxlIGZpbGVzLiAgVGhpcyBpcyBjb25zdHJ1Y3RlZCBkeW5hbWljYWxseSB0aGUgZmlyc3QgdGltZQogICAgICogVHJhbnNsaXRlcmF0b3I6OmdldERhdGFEaXJlY3RvcnkoKSBpcyBjYWxsZWQuCiAgICAgKi8KICAgIHN0YXRpYyBjaGFyKiBEQVRBX0RJUjsKICAgIAogICAgLyoqCiAgICAgKiBUaGlzIGlzIHRoZSBuYW1lIG9mIGEgc3ViZGlyZWN0b3J5IHdpdGhpbiB0aGUgbG9jYWxlIGRhdGEgZGlyZWN0b3J5CiAgICAgKiB0aGF0IGNvbnRhaW5zIHRoZSBydWxlLWJhc2VkIHRyYW5zbGl0ZXJhdG9yIHJlc291cmNlIGJ1bmRsZSBmaWxlcy4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IGNoYXIqIFJFU09VUkNFX1NVQl9ESVI7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkaXJlY3RvcnkgaW4gd2hpY2ggdGhlIHRyYW5zbGl0ZXJhdG9yIHJlc291cmNlIGJ1bmRsZQogICAgICogZmlsZXMgYXJlIGxvY2F0ZWQuICBUaGlzIGlzIGEgc3ViZGlyZWN0b3J5LCBuYW1lZCBSRVNPVVJDRV9TVUJfRElSLAogICAgICogdW5kZXIgTG9jYWxlOjpnZXREYXRhRGlyZWN0b3J5KCkuICBJdCBlbmRzIGluIGEgcGF0aCBzZXBhcmF0b3IuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBjaGFyKiBnZXREYXRhRGlyZWN0b3J5KHZvaWQpOwoKICAgIHN0YXRpYyBpbnQzMl90IGhhc2goY29uc3QgVW5pY29kZVN0cmluZyYgc3RyKTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSB0cmFuc2xpdGVyYXRvciBvYmplY3QgZ2l2ZW4gaXRzIElELiAgVW5saWtlIGdldEluc3RhbmNlKCksCiAgICAgKiB0aGlzIG1ldGhvZCByZXR1cm5zIG51bGwgaWYgaXQgY2Fubm90IG1ha2UgdXNlIG9mIHRoZSBnaXZlbiBJRC4KICAgICAqLwogICAgc3RhdGljIFRyYW5zbGl0ZXJhdG9yKiBfY3JlYXRlSW5zdGFuY2UoY29uc3QgVW5pY29kZVN0cmluZyYgSUQpOwoKcHVibGljOgoKICAgIC8qKgogICAgICogUmVnaXN0ZXJzIGEgaW5zdGFuY2UgPHR0Pm9iajwvdHQ+IG9mIGEgc3ViY2xhc3Mgb2YKICAgICAqIDxjb2RlPlRyYW5zbGl0ZXJhdG9yPC9jb2RlPiB3aXRoIHRoZSBzeXN0ZW0uICBXaGVuCiAgICAgKiA8dHQ+Y3JlYXRlSW5zdGFuY2UoKTwvdHQ+IGlzIGNhbGxlZCB3aXRoIGFuIElEIHN0cmluZyB0aGF0IGlzCiAgICAgKiBlcXVhbCB0byA8dHQ+b2JqLT5nZXRJRCgpPC90dD4sIHRoZW4gPHR0Pm9iai0+Y2xvbmUoKTwvdHQ+IGlzCiAgICAgKiByZXR1cm5lZC4KICAgICAqCiAgICAgKiBBZnRlciB0aGlzIGNhbGwgdGhlIFRyYW5zbGl0ZXJhdG9yIGNsYXNzIG93bnMgdGhlIGFkb3B0ZWRPYmoKICAgICAqIGFuZCB3aWxsIGRlbGV0ZSBpdC4KICAgICAqCiAgICAgKiBAcGFyYW0gb2JqIGFuIGluc3RhbmNlIG9mIHN1YmNsYXNzIG9mCiAgICAgKiA8Y29kZT5UcmFuc2xpdGVyYXRvcjwvY29kZT4gdGhhdCBkZWZpbmVzIDx0dD5jbG9uZSgpPC90dD4KICAgICAqIEBzZWUgI2dldEluc3RhbmNlCiAgICAgKiBAc2VlICNyZWdpc3RlckNsYXNzCiAgICAgKiBAc2VlICN1bnJlZ2lzdGVyCiAgICAgKi8KICAgIHN0YXRpYyB2b2lkIHJlZ2lzdGVySW5zdGFuY2UoVHJhbnNsaXRlcmF0b3IqIGFkb3B0ZWRPYmosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7Cgpwcml2YXRlOgoKICAgIC8qKgogICAgICogVGhpcyBpbnRlcm5hbCBtZXRob2QgcmVnaXN0ZXJzIGEgcHJvdG90eXBlIGluc3RhbmNlIGluIHRoZSBjYWNoZS4KICAgICAqIFRoZSBDQUxMRVIgTVVTVCBNVVRFWCB1c2luZyBjYWNoZU11dGV4IGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kLgogICAgICovCiAgICBzdGF0aWMgdm9pZCBfcmVnaXN0ZXJJbnN0YW5jZShUcmFuc2xpdGVyYXRvciogYWRvcHRlZFByb3RvdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cyk7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBVbnJlZ2lzdGVycyBhIHRyYW5zbGl0ZXJhdG9yIG9yIGNsYXNzLiAgVGhpcyBtYXkgYmUgZWl0aGVyCiAgICAgKiBhIHN5c3RlbSB0cmFuc2xpdGVyYXRvciBvciBhIHVzZXIgdHJhbnNsaXRlcmF0b3Igb3IgY2xhc3MuCiAgICAgKiAKICAgICAqIEBwYXJhbSBJRCB0aGUgSUQgb2YgdGhlIHRyYW5zbGl0ZXJhdG9yIG9yIGNsYXNzCiAgICAgKiBAcmV0dXJuIHRoZSA8Y29kZT5PYmplY3Q8L2NvZGU+IHRoYXQgd2FzIHJlZ2lzdGVyZWQgd2l0aAogICAgICogPGNvZGU+SUQ8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBub25lIHdhcwogICAgICogQHNlZSAjcmVnaXN0ZXJJbnN0YW5jZQogICAgICogQHNlZSAjcmVnaXN0ZXJDbGFzcwogICAgICovCiAgICBzdGF0aWMgdm9pZCB1bnJlZ2lzdGVyKGNvbnN0IFVuaWNvZGVTdHJpbmcmIElEKTsKCnByaXZhdGU6CgogICAgLyoqCiAgICAgKiBVbnJlZ2lzdGVycyBhIHRyYW5zbGl0ZXJhdG9yIG9yIGNsYXNzLiAgSW50ZXJuYWwgbWV0aG9kLgogICAgICogUHJlcmVxdWlzaXRlczogVGhlIGNhY2hlIG11c3QgYmUgaW5pdGlhbGl6ZWQsIGFuZCB0aGUKICAgICAqIGNhbGxlciBtdXN0IG93biB0aGUgY2FjaGVNdXRleC4KICAgICAqLwogICAgc3RhdGljIHZvaWQgX3VucmVnaXN0ZXIoY29uc3QgVW5pY29kZVN0cmluZyYgSUQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBlbnVtZXJhdGlvbiBvdmVyIHRoZSBwcm9ncmFtbWF0aWMgbmFtZXMgb2YgcmVnaXN0ZXJlZAogICAgICogPGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+IG9iamVjdHMuICBUaGlzIGluY2x1ZGVzIGJvdGggc3lzdGVtCiAgICAgKiB0cmFuc2xpdGVyYXRvcnMgYW5kIHVzZXIgdHJhbnNsaXRlcmF0b3JzIHJlZ2lzdGVyZWQgdXNpbmcKICAgICAqIDxjb2RlPnJlZ2lzdGVySW5zdGFuY2UoKTwvY29kZT4uICBUaGUgZW51bWVyYXRlZCBuYW1lcyBtYXkgYmUKICAgICAqIHBhc3NlZCB0byA8Y29kZT5nZXRJbnN0YW5jZSgpPC9jb2RlPi4KICAgICAqCiAgICAgKiBAcmV0dXJuIEFuIDxjb2RlPkVudW1lcmF0aW9uPC9jb2RlPiBvdmVyIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0cwogICAgICogQHNlZSAjZ2V0SW5zdGFuY2UKICAgICAqIEBzZWUgI3JlZ2lzdGVySW5zdGFuY2UKICAgICAqLwogICAgLy8gdmlydHVhbCBFbnVtZXJhdGlvbiBnZXRBdmFpbGFibGVJRHMoKTsKCiAgICAvKioKICAgICAqIFZlY3RvciBvZiByZWdpc3RlcmVkIElEcy4KICAgICAqLwogICAgc3RhdGljIFVWZWN0b3IgY2FjaGVJRHM7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBJRHMgY3VycmVudGx5IHJlZ2lzdGVyZWQgd2l0aCB0aGUgc3lzdGVtLgogICAgICogVG8gcmV0cmlldmUgdGhlIGFjdHVhbCBJRHMsIGNhbGwgZ2V0QXZhaWxhYmxlSUQoaSkgd2l0aAogICAgICogaSBmcm9tIDAgdG8gY291bnRBdmFpbGFibGVJRHMoKSAtIDEuCiAgICAgKi8KICAgIHN0YXRpYyBpbnQzMl90IGNvdW50QXZhaWxhYmxlSURzKHZvaWQpOwoKICAgIC8qKgogICAgICogUmV0dXJuIHRoZSBpbmRleC10aCBhdmFpbGFibGUgSUQuICBpbmRleCBtdXN0IGJlIGJldHdlZW4gMAogICAgICogYW5kIGNvdW50QXZhaWxhYmxlSURzKCkgLSAxLCBpbmNsdXNpdmUuICBJZiBpbmRleCBpcyBvdXQgb2YKICAgICAqIHJhbmdlLCB0aGUgcmVzdWx0IG9mIGdldEF2YWlsYWJsZUlEKDApIGlzIHJldHVybmVkLgogICAgICovCiAgICBzdGF0aWMgY29uc3QgVW5pY29kZVN0cmluZyYgZ2V0QXZhaWxhYmxlSUQoaW50MzJfdCBpbmRleCk7Cgpwcm90ZWN0ZWQ6CgogICAgLyoqCiAgICAgKiBNZXRob2QgZm9yIHN1YmNsYXNzZXMgdG8gdXNlIHRvIG9idGFpbiBhIGNoYXJhY3RlciBpbiB0aGUgZ2l2ZW4KICAgICAqIHN0cmluZywgd2l0aCBmaWx0ZXJpbmcuCiAgICAgKi8KICAgIFVDaGFyIGZpbHRlcmVkQ2hhckF0KGNvbnN0IFJlcGxhY2VhYmxlJiB0ZXh0LCBpbnQzMl90IGkpIGNvbnN0OwoKcHJpdmF0ZToKICAgIC8qKgogICAgICogQ29tcGFyaXNvbiBmdW5jdGlvbiBmb3IgVVZlY3Rvci4gIENvbXBhcmVzIHR3byBVbmljb2RlU3RyaW5nCiAgICAgKiBvYmplY3RzIGdpdmVuIHZvaWQqIHBvaW50ZXJzIHRvIHRoZW0uCiAgICAgKi8KICAgIHN0YXRpYyBib29sX3QgY29tcGFyZUlEcyh2b2lkKiBhLCB2b2lkKiBiKTsKCiAgICBzdGF0aWMgdm9pZCBpbml0aWFsaXplQ2FjaGUodm9pZCk7Cn07CgppbmxpbmUgaW50MzJfdCBUcmFuc2xpdGVyYXRvcjo6Z2V0TWF4aW11bUNvbnRleHRMZW5ndGgodm9pZCkgY29uc3QgewogICAgcmV0dXJuIG1heGltdW1Db250ZXh0TGVuZ3RoOwp9CgojZW5kaWYK