LyoKKiBDb3B5cmlnaHQgqSB7MTk5OX0sIEludGVybmF0aW9uYWwgQnVzaW5lc3MgTWFjaGluZXMgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgRGF0ZSAgICAgICAgTmFtZSAgICAgICAgRGVzY3JpcHRpb24KKiAgIDExLzE3Lzk5ICAgIGFsaXUgICAgICAgIENyZWF0aW9uLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiovCiNpZm5kZWYgVFJBTlNMSVRfSAojZGVmaW5lIFRSQU5TTElUX0gKCiNpbmNsdWRlICJ1bmljb2RlL3VuaXN0ci5oIgojaW5jbHVkZSAidW5pY29kZS9wYXJzZWVyci5oIgojaW5jbHVkZSAidW5pY29kZS91dHJhbnMuaCIgLy8gVVRyYW5zUG9zaXRpb24sIFVUcmFuc0RpcmVjdGlvbgoKY2xhc3MgUmVwbGFjZWFibGU7CmNsYXNzIFVuaWNvZGVGaWx0ZXI7CmNsYXNzIFRyYW5zbGl0ZXJhdGlvblJ1bGVEYXRhOwpjbGFzcyBIYXNodGFibGU7CmNsYXNzIFVfSTE4Tl9BUEkgVVZlY3RvcjsKY2xhc3MgQ29tcG91bmRUcmFuc2xpdGVyYXRvcjsKCi8qKgogKiA8Y29kZT5UcmFuc2xpdGVyYXRvcjwvY29kZT4gaXMgYW4gYWJzdHJhY3QgY2xhc3MgdGhhdAogKiB0cmFuc2xpdGVyYXRlcyB0ZXh0IGZyb20gb25lIGZvcm1hdCB0byBhbm90aGVyLiAgVGhlIG1vc3QgY29tbW9uCiAqIGtpbmQgb2YgdHJhbnNsaXRlcmF0b3IgaXMgYSBzY3JpcHQsIG9yIGFscGhhYmV0LCB0cmFuc2xpdGVyYXRvci4KICogRm9yIGV4YW1wbGUsIGEgUnVzc2lhbiB0byBMYXRpbiB0cmFuc2xpdGVyYXRvciBjaGFuZ2VzIFJ1c3NpYW4gdGV4dAogKiB3cml0dGVuIGluIEN5cmlsbGljIGNoYXJhY3RlcnMgdG8gcGhvbmV0aWNhbGx5IGVxdWl2YWxlbnQgTGF0aW4KICogY2hhcmFjdGVycy4gIEl0IGRvZXMgbm90IDxlbT50cmFuc2xhdGU8L2VtPiBSdXNzaWFuIHRvIEVuZ2xpc2ghCiAqIFRyYW5zbGl0ZXJhdGlvbiwgdW5saWtlIHRyYW5zbGF0aW9uLCBvcGVyYXRlcyBvbiBjaGFyYWN0ZXJzLCB3aXRob3V0CiAqIHJlZmVyZW5jZSB0byB0aGUgbWVhbmluZ3Mgb2Ygd29yZHMgYW5kIHNlbnRlbmNlcy4KICoKICogPHA+QWx0aG91Z2ggc2NyaXB0IGNvbnZlcnNpb24gaXMgaXRzIG1vc3QgY29tbW9uIHVzZSwgYQogKiB0cmFuc2xpdGVyYXRvciBjYW4gYWN0dWFsbHkgcGVyZm9ybSBhIG1vcmUgZ2VuZXJhbCBjbGFzcyBvZiB0YXNrcy4KICogSW4gZmFjdCwgPGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+IGRlZmluZXMgYSB2ZXJ5IGdlbmVyYWwgQVBJCiAqIHdoaWNoIHNwZWNpZmllcyBvbmx5IHRoYXQgYSBzZWdtZW50IG9mIHRoZSBpbnB1dCB0ZXh0IGlzIHJlcGxhY2VkCiAqIGJ5IG5ldyB0ZXh0LiAgVGhlIHBhcnRpY3VsYXJzIG9mIHRoaXMgY29udmVyc2lvbiBhcmUgZGV0ZXJtaW5lZAogKiBlbnRpcmVseSBieSBzdWJjbGFzc2VzIG9mIDxjb2RlPlRyYW5zbGl0ZXJhdG9yPC9jb2RlPi4KICoKICogPHA+PGI+VHJhbnNsaXRlcmF0b3JzIGFyZSBzdGF0ZWxlc3M8L2I+CiAqCiAqIDxwPjxjb2RlPlRyYW5zbGl0ZXJhdG9yPC9jb2RlPiBvYmplY3RzIGFyZSA8ZW0+c3RhdGVsZXNzPC9lbT47IHRoZXkKICogcmV0YWluIG5vIGluZm9ybWF0aW9uIGJldHdlZW4gY2FsbHMgdG8KICogPGNvZGU+dHJhbnNsaXRlcmF0ZSgpPC9jb2RlPi4gIChIb3dldmVyLCB0aGlzIGRvZXMgPGVtPm5vdDwvZW0+CiAqIG1lYW4gdGhhdCB0aHJlYWRzIG1heSBzaGFyZSB0cmFuc2xpdGVyYXRvcnMgd2l0aG91dCBzeW5jaHJvbml6aW5nCiAqIHRoZW0uICBUcmFuc2xpdGVyYXRvcnMgYXJlIG5vdCBpbW11dGFibGUsIHNvIHRoZXkgbXVzdCBiZQogKiBzeW5jaHJvbml6ZWQgd2hlbiBzaGFyZWQgYmV0d2VlbiB0aHJlYWRzLikgIFRoaXMxIG1pZ2h0IHNlZW0gdG8KICogbGltaXQgdGhlIGNvbXBsZXhpdHkgb2YgdGhlIHRyYW5zbGl0ZXJhdGlvbiBvcGVyYXRpb24uICBJbgogKiBwcmFjdGljZSwgc3ViY2xhc3NlcyBwZXJmb3JtIGNvbXBsZXggdHJhbnNsaXRlcmF0aW9ucyBieSBkZWxheWluZwogKiB0aGUgcmVwbGFjZW1lbnQgb2YgdGV4dCB1bnRpbCBpdCBpcyBrbm93biB0aGF0IG5vIG90aGVyCiAqIHJlcGxhY2VtZW50cyBhcmUgcG9zc2libGUuICBJbiBvdGhlciB3b3JkcywgYWx0aG91Z2ggdGhlCiAqIDxjb2RlPlRyYW5zbGl0ZXJhdG9yPC9jb2RlPiBvYmplY3RzIGFyZSBzdGF0ZWxlc3MsIHRoZSBzb3VyY2UgdGV4dAogKiBpdHNlbGYgZW1ib2RpZXMgYWxsIHRoZSBuZWVkZWQgaW5mb3JtYXRpb24sIGFuZCBkZWxheWVkIG9wZXJhdGlvbgogKiBhbGxvd3MgYXJiaXRyYXJ5IGNvbXBsZXhpdHkuCiAqCiAqIDxwPjxiPkJhdGNoIHRyYW5zbGl0ZXJhdGlvbjwvYj4KICoKICogPHA+VGhlIHNpbXBsZXN0IHdheSB0byBwZXJmb3JtIHRyYW5zbGl0ZXJhdGlvbiBpcyBhbGwgYXQgb25jZSwgb24gYQogKiBzdHJpbmcgb2YgZXhpc3RpbmcgdGV4dC4gIFRoaXMgaXMgcmVmZXJyZWQgdG8gYXMgPGVtPmJhdGNoPC9lbT4KICogdHJhbnNsaXRlcmF0aW9uLiAgRm9yIGV4YW1wbGUsIGdpdmVuIGEgc3RyaW5nIDxjb2RlPmlucHV0PC9jb2RlPgogKiBhbmQgYSB0cmFuc2xpdGVyYXRvciA8Y29kZT50PC9jb2RlPiwgdGhlIGNhbGwKICoKICogPGJsb2NrcXVvdGU+PGNvZGU+U3RyaW5nIHJlc3VsdCA9IHQudHJhbnNsaXRlcmF0ZShpbnB1dCk7CiAqIDwvY29kZT48L2Jsb2NrcXVvdGU+CiAqCiAqIHdpbGwgdHJhbnNsaXRlcmF0ZSBpdCBhbmQgcmV0dXJuIHRoZSByZXN1bHQuICBPdGhlciBtZXRob2RzIGFsbG93CiAqIHRoZSBjbGllbnQgdG8gc3BlY2lmeSBhIHN1YnN0cmluZyB0byBiZSB0cmFuc2xpdGVyYXRlZCBhbmQgdG8gdXNlCiAqIHtAbGluayBSZXBsYWNlYWJsZX0gb2JqZWN0cyBpbnN0ZWFkIG9mIHN0cmluZ3MsIGluIG9yZGVyIHRvCiAqIHByZXNlcnZlIG91dC1vZi1iYW5kIGluZm9ybWF0aW9uIChzdWNoIGFzIHRleHQgc3R5bGVzKS4KICoKICogPHA+PGI+S2V5Ym9hcmQgdHJhbnNsaXRlcmF0aW9uPC9iPgogKgogKiA8cD5Tb21ld2hhdCBtb3JlIGludm9sdmVkIGlzIDxlbT5rZXlib2FyZDwvZW0+LCBvciBpbmNyZW1lbnRhbAogKiB0cmFuc2xpdGVyYXRpb24uICBUaGlzIGlzIHRoZSB0cmFuc2xpdGVyYXRpb24gb2YgdGV4dCB0aGF0IGlzCiAqIGFycml2aW5nIGZyb20gc29tZSBzb3VyY2UgKHR5cGljYWxseSB0aGUgdXNlcidzIGtleWJvYXJkKSBvbmUKICogY2hhcmFjdGVyIGF0IGEgdGltZSwgb3IgaW4gc29tZSBvdGhlciBwaWVjZW1lYWwgZmFzaGlvbi4KICoKICogPHA+SW4ga2V5Ym9hcmQgdHJhbnNsaXRlcmF0aW9uLCBhIDxjb2RlPlJlcGxhY2VhYmxlPC9jb2RlPiBidWZmZXIKICogc3RvcmVzIHRoZSB0ZXh0LiAgQXMgdGV4dCBpcyBpbnNlcnRlZCwgYXMgbXVjaCBhcyBwb3NzaWJsZSBpcwogKiB0cmFuc2xpdGVyYXRlZCBvbiB0aGUgZmx5LiAgVGhpcyBtZWFucyBhIEdVSSB0aGF0IGRpc3BsYXlzIHRoZQogKiBjb250ZW50cyBvZiB0aGUgYnVmZmVyIG1heSBzaG93IHRleHQgYmVpbmcgbW9kaWZpZWQgYXMgZWFjaCBuZXcKICogY2hhcmFjdGVyIGFycml2ZXMuCiAqCiAqIDxwPkNvbnNpZGVyIHRoZSBzaW1wbGUgPGNvZGU+UnVsZUJhc2VkVHJhbnNsaXRlcmF0b3I8L2NvZGU+OgogKgogKiA8YmxvY2txdW90ZT48Y29kZT4KICogdGgmZ3Q7e3RoZXRhfTxicj4KICogdCZndDt7dGF1fQogKiA8L2NvZGU+PC9ibG9ja3F1b3RlPgogKgogKiBXaGVuIHRoZSB1c2VyIHR5cGVzICd0Jywgbm90aGluZyB3aWxsIGhhcHBlbiwgc2luY2UgdGhlCiAqIHRyYW5zbGl0ZXJhdG9yIGlzIHdhaXRpbmcgdG8gc2VlIGlmIHRoZSBuZXh0IGNoYXJhY3RlciBpcyAnaCcuICBUbwogKiByZW1lZHkgdGhpcywgd2UgaW50cm9kdWNlIHRoZSBub3Rpb24gb2YgYSBjdXJzb3IsIG1hcmtlZCBieSBhICd8JwogKiBpbiB0aGUgb3V0cHV0IHN0cmluZzoKICoKICogPGJsb2NrcXVvdGU+PGNvZGU+CiAqIHQmZ3Q7fHt0YXV9PGJyPgogKiB7dGF1fWgmZ3Q7e3RoZXRhfQogKiA8L2NvZGU+PC9ibG9ja3F1b3RlPgogKgogKiBOb3cgd2hlbiB0aGUgdXNlciB0eXBlcyAndCcsIHRhdSBhcHBlYXJzLCBhbmQgaWYgdGhlIG5leHQgY2hhcmFjdGVyCiAqIGlzICdoJywgdGhlIHRhdSBjaGFuZ2VzIHRvIGEgdGhldGEuICBUaGlzIGlzIGFjY29tcGxpc2hlZCBieQogKiBtYWludGFpbmluZyBhIGN1cnNvciBwb3NpdGlvbiAoaW5kZXBlbmRlbnQgb2YgdGhlIGluc2VydGlvbiBwb2ludCwKICogYW5kIGludmlzaWJsZSBpbiB0aGUgR1VJKSBhY3Jvc3MgY2FsbHMgdG8KICogPGNvZGU+dHJhbnNsaXRlcmF0ZSgpPC9jb2RlPi4gIFR5cGljYWxseSwgdGhlIGN1cnNvciB3aWxsCiAqIGJlIGNvaW5jaWRlbnQgd2l0aCB0aGUgaW5zZXJ0aW9uIHBvaW50LCBidXQgaW4gYSBjYXNlIGxpa2UgdGhlIG9uZQogKiBhYm92ZSwgaXQgd2lsbCBwcmVjZWRlIHRoZSBpbnNlcnRpb24gcG9pbnQuCiAqCiAqIDxwPktleWJvYXJkIHRyYW5zbGl0ZXJhdGlvbiBtZXRob2RzIG1haW50YWluIGEgc2V0IG9mIHRocmVlIGluZGljZXMKICogdGhhdCBhcmUgdXBkYXRlZCB3aXRoIGVhY2ggY2FsbCB0bwogKiA8Y29kZT50cmFuc2xpdGVyYXRlKCk8L2NvZGU+LCBpbmNsdWRpbmcgdGhlIGN1cnNvciwgc3RhcnQsCiAqIGFuZCBsaW1pdC4gIFNpbmNlIHRoZXNlIGluZGljZXMgYXJlIGNoYW5nZWQgYnkgdGhlIG1ldGhvZCwgdGhleSBhcmUKICogcGFzc2VkIGluIGFuIDxjb2RlPmludFtdPC9jb2RlPiBhcnJheS4gVGhlIDxjb2RlPlNUQVJUPC9jb2RlPiBpbmRleAogKiBtYXJrcyB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdWJzdHJpbmcgdGhhdCB0aGUgdHJhbnNsaXRlcmF0b3Igd2lsbAogKiBsb29rIGF0LiAgSXQgaXMgYWR2YW5jZWQgYXMgdGV4dCBiZWNvbWVzIGNvbW1pdHRlZCAoYnV0IGl0IGlzIG5vdAogKiB0aGUgY29tbWl0dGVkIGluZGV4OyB0aGF0J3MgdGhlIDxjb2RlPkNVUlNPUjwvY29kZT4pLiAgVGhlCiAqIDxjb2RlPkNVUlNPUjwvY29kZT4gaW5kZXgsIGRlc2NyaWJlZCBhYm92ZSwgbWFya3MgdGhlIHBvaW50IGF0CiAqIHdoaWNoIHRoZSB0cmFuc2xpdGVyYXRvciBsYXN0IHN0b3BwZWQsIGVpdGhlciBiZWNhdXNlIGl0IHJlYWNoZWQKICogdGhlIGVuZCwgb3IgYmVjYXVzZSBpdCByZXF1aXJlZCBtb3JlIGNoYXJhY3RlcnMgdG8gZGlzYW1iaWd1YXRlCiAqIGJldHdlZW4gcG9zc2libGUgaW5wdXRzLiAgVGhlIDxjb2RlPkNVUlNPUjwvY29kZT4gY2FuIGFsc28gYmUKICogZXhwbGljaXRseSBzZXQgYnkgcnVsZXMgaW4gYSA8Y29kZT5SdWxlQmFzZWRUcmFuc2xpdGVyYXRvcjwvY29kZT4uCiAqIEFueSBjaGFyYWN0ZXJzIGJlZm9yZSB0aGUgPGNvZGU+Q1VSU09SPC9jb2RlPiBpbmRleCBhcmUgZnJvemVuOwogKiBmdXR1cmUga2V5Ym9hcmQgdHJhbnNsaXRlcmF0aW9uIGNhbGxzIHdpdGhpbiB0aGlzIGlucHV0IHNlcXVlbmNlCiAqIHdpbGwgbm90IGNoYW5nZSB0aGVtLiAgTmV3IHRleHQgaXMgaW5zZXJ0ZWQgYXQgdGhlCiAqIDxjb2RlPkxJTUlUPC9jb2RlPiBpbmRleCwgd2hpY2ggbWFya3MgdGhlIGVuZCBvZiB0aGUgc3Vic3RyaW5nIHRoYXQKICogdGhlIHRyYW5zbGl0ZXJhdG9yIGxvb2tzIGF0LgogKgogKiA8cD5CZWNhdXNlIGtleWJvYXJkIHRyYW5zbGl0ZXJhdGlvbiBhc3N1bWVzIHRoYXQgbW9yZSBjaGFyYWN0ZXJzCiAqIGFyZSB0byBhcnJpdmUsIGl0IGlzIGNvbnNlcnZhdGl2ZSBpbiBpdHMgb3BlcmF0aW9uLiAgSXQgb25seQogKiB0cmFuc2xpdGVyYXRlcyB3aGVuIGl0IGNhbiBkbyBzbyB1bmFtYmlndW91c2x5LiAgT3RoZXJ3aXNlIGl0IHdhaXRzCiAqIGZvciBtb3JlIGNoYXJhY3RlcnMgdG8gYXJyaXZlLiAgV2hlbiB0aGUgY2xpZW50IGNvZGUga25vd3MgdGhhdCBubwogKiBtb3JlIGNoYXJhY3RlcnMgYXJlIGZvcnRoY29taW5nLCBwZXJoYXBzIGJlY2F1c2UgdGhlIHVzZXIgaGFzCiAqIHBlcmZvcm1lZCBzb21lIGlucHV0IHRlcm1pbmF0aW9uIG9wZXJhdGlvbiwgdGhlbiBpdCBzaG91bGQgY2FsbAogKiA8Y29kZT5maW5pc2hUcmFuc2xpdGVyYXRpb24oKTwvY29kZT4gdG8gY29tcGxldGUgYW55CiAqIHBlbmRpbmcgdHJhbnNsaXRlcmF0aW9ucy4KICoKICogPHA+PGI+SW52ZXJzZXM8L2I+CiAqCiAqIDxwPlBhaXJzIG9mIHRyYW5zbGl0ZXJhdG9ycyBtYXkgYmUgaW52ZXJzZXMgb2Ygb25lIGFub3RoZXIuICBGb3IKICogZXhhbXBsZSwgaWYgdHJhbnNsaXRlcmF0b3IgPGI+QTwvYj4gdHJhbnNsaXRlcmF0ZXMgY2hhcmFjdGVycyBieQogKiBpbmNyZW1lbnRpbmcgdGhlaXIgVW5pY29kZSB2YWx1ZSAoc28gImFiYyIgLT4gImRlZiIpLCBhbmQKICogdHJhbnNsaXRlcmF0b3IgPGI+QjwvYj4gZGVjcmVtZW50cyBjaGFyYWN0ZXIgdmFsdWVzLCB0aGVuIDxiPkE8L2I+CiAqIGlzIGFuIGludmVyc2Ugb2YgPGI+QjwvYj4gYW5kIHZpY2UgdmVyc2EuICBJZiB3ZSBjb21wb3NlIDxiPkE8L2I+CiAqIHdpdGggPGI+QjwvYj4gaW4gYSBjb21wb3VuZCB0cmFuc2xpdGVyYXRvciwgdGhlIHJlc3VsdCBpcyB0aGUKICogaW5kZW50aXR5IHRyYW5zbGl0ZXJhdG9yLCB0aGF0IGlzLCBhIHRyYW5zbGl0ZXJhdG9yIHRoYXQgZG9lcyBub3QKICogY2hhbmdlIGl0cyBpbnB1dCB0ZXh0LgogKgogKiBUaGUgPGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+IG1ldGhvZCA8Y29kZT5nZXRJbnZlcnNlKCk8L2NvZGU+CiAqIHJldHVybnMgYSB0cmFuc2xpdGVyYXRvcidzIGludmVyc2UsIGlmIG9uZSBleGlzdHMsIG9yCiAqIDxjb2RlPm51bGw8L2NvZGU+IG90aGVyd2lzZS4gIEhvd2V2ZXIsIHRoZSByZXN1bHQgb2YKICogPGNvZGU+Z2V0SW52ZXJzZSgpPC9jb2RlPiB1c3VhbGx5IHdpbGwgPGVtPm5vdDwvZW0+IGJlIGEgdHJ1ZQogKiBtYXRoZW1hdGljYWwgaW52ZXJzZS4gIFRoaXMgaXMgYmVjYXVzZSB0cnVlIGludmVyc2UgdHJhbnNsaXRlcmF0b3JzCiAqIGFyZSBkaWZmaWN1bHQgdG8gZm9ybXVsYXRlLiAgRm9yIGV4YW1wbGUsIGNvbnNpZGVyIHR3bwogKiB0cmFuc2xpdGVyYXRvcnM6IDxiPkFCPC9iPiwgd2hpY2ggdHJhbnNsaXRlcmF0ZXMgdGhlIGNoYXJhY3RlciAnQScKICogdG8gJ0InLCBhbmQgPGI+QkE8L2I+LCB3aGljaCB0cmFuc2xpdGVyYXRlcyAnQicgdG8gJ0EnLiAgSXQgbWlnaHQKICogc2VlbSB0aGF0IHRoZXNlIGFyZSBleGFjdCBpbnZlcnNlcywgc2luY2UKICoKICogPGJsb2NrcXVvdGU+IkEiIHggPGI+QUI8L2I+IC0+ICJCIjxicj4KICogIkIiIHggPGI+QkE8L2I+IC0+ICJBIjwvYmxvY2txdW90ZT4KICoKICogd2hlcmUgJ3gnIHJlcHJlc2VudHMgdHJhbnNsaXRlcmF0aW9uLiAgSG93ZXZlciwKICoKICogPGJsb2NrcXVvdGU+IkFCQ0QiIHggPGI+QUI8L2I+IC0+ICJCQkNEIjxicj4KICogIkJCQ0QiIHggPGI+QkE8L2I+IC0+ICJBQUNEIjwvYmxvY2txdW90ZT4KICoKICogc28gPGI+QUI8L2I+IGNvbXBvc2VkIHdpdGggPGI+QkE8L2I+IGlzIG5vdCB0aGUKICogaWRlbnRpdHkuIE5vbmV0aGVsZXNzLCA8Yj5CQTwvYj4gbWF5IGJlIHVzZWZ1bGx5IGNvbnNpZGVyZWQgdG8gYmUKICogPGI+QUI8L2I+J3MgaW52ZXJzZSwgYW5kIGl0IGlzIG9uIHRoaXMgYmFzaXMgdGhhdAogKiA8Yj5BQjwvYj48Y29kZT4uZ2V0SW52ZXJzZSgpPC9jb2RlPiBjb3VsZCBsZWdpdGltYXRlbHkgcmV0dXJuCiAqIDxiPkJBPC9iPi4KICoKICogPHA+PGI+SURzIGFuZCBkaXNwbGF5IG5hbWVzPC9iPgogKgogKiA8cD5BIHRyYW5zbGl0ZXJhdG9yIGlzIGRlc2lnbmF0ZWQgYnkgYSBzaG9ydCBpZGVudGlmaWVyIHN0cmluZyBvcgogKiA8ZW0+SUQ8L2VtPi4gIElEcyBmb2xsb3cgdGhlIGZvcm1hdCA8ZW0+c291cmNlLWRlc3RpbmF0aW9uPC9lbT4sCiAqIHdoZXJlIDxlbT5zb3VyY2U8L2VtPiBkZXNjcmliZXMgdGhlIGVudGl0eSBiZWluZyByZXBsYWNlZCwgYW5kCiAqIDxlbT5kZXN0aW5hdGlvbjwvZW0+IGRlc2NyaWJlcyB0aGUgZW50aXR5IHJlcGxhY2luZwogKiA8ZW0+c291cmNlPC9lbT4uICBUaGUgZW50aXRpZXMgbWF5IGJlIHRoZSBuYW1lcyBvZiBzY3JpcHRzLAogKiBwYXJ0aWN1bGFyIHNlcXVlbmNlcyBvZiBjaGFyYWN0ZXJzLCBvciB3aGF0ZXZlciBlbHNlIGl0IGlzIHRoYXQgdGhlCiAqIHRyYW5zbGl0ZXJhdG9yIGNvbnZlcnRzIHRvIG9yIGZyb20uICBGb3IgZXhhbXBsZSwgYSB0cmFuc2xpdGVyYXRvcgogKiBmcm9tIFJ1c3NpYW4gdG8gTGF0aW4gbWlnaHQgYmUgbmFtZWQgIlJ1c3NpYW4tTGF0aW4iLiAgQQogKiB0cmFuc2xpdGVyYXRvciBmcm9tIGtleWJvYXJkIGVzY2FwZSBzZXF1ZW5jZXMgdG8gTGF0aW4tMSBjaGFyYWN0ZXJzCiAqIG1pZ2h0IGJlIG5hbWVkICJLZXlib2FyZEVzY2FwZS1MYXRpbjEiLiAgQnkgY29udmVudGlvbiwgc3lzdGVtCiAqIGVudGl0eSBuYW1lcyBhcmUgaW4gRW5nbGlzaCwgd2l0aCB0aGUgaW5pdGlhbCBsZXR0ZXJzIG9mIHdvcmRzCiAqIGNhcGl0YWxpemVkOyB1c2VyIGVudGl0eSBuYW1lcyBtYXkgZm9sbG93IGFueSBmb3JtYXQgc28gbG9uZyBhcwogKiB0aGV5IGRvIG5vdCBjb250YWluIGRhc2hlcy4KICoKICogPHA+SW4gYWRkaXRpb24gdG8gcHJvZ3JhbW1hdGljIElEcywgdHJhbnNsaXRlcmF0b3Igb2JqZWN0cyBoYXZlCiAqIGRpc3BsYXkgbmFtZXMgZm9yIHByZXNlbnRhdGlvbiBpbiB1c2VyIGludGVyZmFjZXMsIHJldHVybmVkIGJ5CiAqIHtAbGluayAjZ2V0RGlzcGxheU5hbWV9LgogKgogKiA8cD48Yj5GYWN0b3J5IG1ldGhvZHMgYW5kIHJlZ2lzdHJhdGlvbjwvYj4KICoKICogPHA+SW4gZ2VuZXJhbCwgY2xpZW50IGNvZGUgc2hvdWxkIHVzZSB0aGUgZmFjdG9yeSBtZXRob2QKICogPGNvZGU+Z2V0SW5zdGFuY2UoKTwvY29kZT4gdG8gb2J0YWluIGFuIGluc3RhbmNlIG9mIGEKICogdHJhbnNsaXRlcmF0b3IgZ2l2ZW4gaXRzIElELiAgVmFsaWQgSURzIG1heSBiZSBlbnVtZXJhdGVkIHVzaW5nCiAqIDxjb2RlPmdldEF2YWlsYWJsZUlEcygpPC9jb2RlPi4gIFNpbmNlIHRyYW5zbGl0ZXJhdG9ycyBhcmUgbXV0YWJsZSwKICogbXVsdGlwbGUgY2FsbHMgdG8gPGNvZGU+Z2V0SW5zdGFuY2UoKTwvY29kZT4gd2l0aCB0aGUgc2FtZSBJRCB3aWxsCiAqIHJldHVybiBkaXN0aW5jdCBvYmplY3RzLgogKgogKiA8cD5JbiBhZGRpdGlvbiB0byB0aGUgc3lzdGVtIHRyYW5zbGl0ZXJhdG9ycyByZWdpc3RlcmVkIGF0IHN0YXJ0dXAsCiAqIHVzZXIgdHJhbnNsaXRlcmF0b3JzIG1heSBiZSByZWdpc3RlcmVkIGJ5IGNhbGxpbmcKICogPGNvZGU+cmVnaXN0ZXJJbnN0YW5jZSgpPC9jb2RlPiBhdCBydW4gdGltZS4gIEEgcmVnaXN0ZXJlZCBpbnN0YW5jZQogKiBhY3RzIGEgdGVtcGxhdGU7IGZ1dHVyZSBjYWxscyB0byA8dHQ+Z2V0SW5zdGFuY2UoKTwvdHQ+IHdpdGggdGhlIElECiAqIG9mIHRoZSByZWdpc3RlcmVkIG9iamVjdCByZXR1cm4gY2xvbmVzIG9mIHRoYXQgb2JqZWN0LiAgVGh1cyBhbnkKICogb2JqZWN0IHBhc3NlZCB0byA8dHQ+cmVnaXN0ZXJJbnN0YW5jZSgpPC90dD4gbXVzdCBpbXBsZW1lbnQKICogPHR0PmNsb25lKCk8L3R0PiBwcm9wZXJ0bHkuICBUbyByZWdpc3RlciBhIHRyYW5zbGl0ZXJhdG9yIHN1YmNsYXNzCiAqIHdpdGhvdXQgaW5zdGFudGlhdGluZyBpdCAodW50aWwgaXQgaXMgbmVlZGVkKSwgdXNlcnMgbWF5IGNhbGwKICogPGNvZGU+cmVnaXN0ZXJDbGFzcygpPC9jb2RlPi4gIEluIHRoaXMgY2FzZSwgdGhlIG9iamVjdHMgYXJlCiAqIGluc3RhbnRpYXRlZCBieSBpbnZva2luZyB0aGUgemVyby1hcmd1bWVudCBwdWJsaWMgY29uc3RydWN0b3Igb2YKICogdGhlIGNsYXNzLgogKgogKiA8cD48Yj5TdWJjbGFzc2luZzwvYj4KICoKICogU3ViY2xhc3NlcyBtdXN0IGltcGxlbWVudCB0aGUgYWJzdHJhY3QgbWV0aG9kCiAqIDxjb2RlPmhhbmRsZVRyYW5zbGl0ZXJhdGUoKTwvY29kZT4uICA8cD5TdWJjbGFzc2VzIHNob3VsZCBvdmVycmlkZQogKiB0aGUgPGNvZGU+dHJhbnNsaXRlcmF0ZSgpPC9jb2RlPiBtZXRob2QgdGFraW5nIGEKICogPGNvZGU+UmVwbGFjZWFibGU8L2NvZGU+IGFuZCB0aGUgPGNvZGU+dHJhbnNsaXRlcmF0ZSgpPC9jb2RlPgogKiBtZXRob2QgdGFraW5nIGEgPGNvZGU+U3RyaW5nPC9jb2RlPiBhbmQgPGNvZGU+U3RyaW5nQnVmZmVyPC9jb2RlPgogKiBpZiB0aGUgcGVyZm9ybWFuY2Ugb2YgdGhlc2UgbWV0aG9kcyBjYW4gYmUgaW1wcm92ZWQgb3ZlciB0aGUKICogcGVyZm9ybWFuY2Ugb2J0YWluZWQgYnkgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb25zIGluIHRoaXMgY2xhc3MuCiAqCiAqIEBhdXRob3IgQWxhbiBMaXUKICogQGRyYWZ0CiAqLwpjbGFzcyBVX0kxOE5fQVBJIFRyYW5zbGl0ZXJhdG9yIHsKCnByaXZhdGU6CgogICAgLyoqCiAgICAgKiBQcm9ncmFtbWF0aWMgbmFtZSwgZS5nLiwgIkxhdGluLUFyYWJpYyIuCiAgICAgKi8KICAgIFVuaWNvZGVTdHJpbmcgSUQ7CgogICAgLyoqIAogICAgICogVGhpcyB0cmFuc2xpdGVyYXRvcidzIGZpbHRlci4gIEFueSBjaGFyYWN0ZXIgZm9yIHdoaWNoCiAgICAgKiA8dHQ+ZmlsdGVyLmNvbnRhaW5zKCk8L3R0PiByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+IHdpbGwgbm90IGJlCiAgICAgKiBhbHRlcmVkIGJ5IHRoaXMgdHJhbnNsaXRlcmF0b3IuICBJZiA8dHQ+ZmlsdGVyPC90dD4gaXMKICAgICAqIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgaXMgYXBwbGllZC4KICAgICAqLwogICAgVW5pY29kZUZpbHRlciogZmlsdGVyOwoKICAgIGludDMyX3QgbWF4aW11bUNvbnRleHRMZW5ndGg7CgogICAgLyoqCiAgICAgKiBDYWNoZSBvZiBwdWJsaWMgc3lzdGVtIHRyYW5zbGl0ZXJhdG9ycy4gIEtleXMgYXJlIFVuaWNvZGVTdHJpbmcKICAgICAqIG5hbWVzLCB2YWx1ZXMgYXJlIENhY2hlRW50cnkgb2JqZWN0cy4KICAgICAqLwogICAgc3RhdGljIEhhc2h0YWJsZSogY2FjaGU7CgogICAgLyoqCiAgICAgKiBMaWtlICdjYWNoZScsIGJ1dCBJRHMgYXJlIG5vdCBwdWJsaWMuICBJbnRlcm5hbCB0cmFuc2xpdGVyYXRvcnMKICAgICAqIGFyZSBjb21iaW5lZCB0b2dldGhlciBhbmQgYWxpYXNlZCB0byBwdWJsaWMgSURzLgogICAgICovCiAgICBzdGF0aWMgSGFzaHRhYmxlKiBpbnRlcm5hbENhY2hlOwoKICAgIC8qKgogICAgICogVGhlIG11dGV4IGNvbnRyb2xsaW5nIGFjY2VzcyB0byB0aGUgY2FjaGVzLgogICAgICovCiAgICBzdGF0aWMgVU1UWCBjYWNoZU11dGV4OwoKICAgIC8qKgogICAgICogV2hlbiBzZXQgdG8gVFJVRSwgdGhlIGNhY2hlIGhhcyBiZWVuIGluaXRpYWxpemVkLiAgQW55IGNvZGUgbXVzdAogICAgICogY2hlY2sgdGhpcyBib29sZWFuIGJlZm9yZSBhY2Nlc3NpbmcgdGhlIGNhY2hlLCBhbmQgaWYgdGhlIGJvb2xlYW4KICAgICAqIGlzIEZBTFNFLCBpdCBtdXN0IGNhbGwgaW5pdGlhbGl6ZUNhY2hlKCkuICBXZSBkbyB0aGlzIGZvcm0gb2YgbGF6eQogICAgICogZXZhbHVhdGlvbiBmb3IgdHdvIHJlYXNvbnM6ICgxKSBzbyB3ZSBkb24ndCBpbml0aWFsaXplIGlmIHdlIGRvbid0CiAgICAgKiBoYXZlIHRvIChpLmUuLCBpZiBubyBvbmUgaXMgdXNpbmcgVHJhbnNsaXRlcmF0b3IsIGJ1dCBoYXMgaW5jbHVkZWQKICAgICAqIHRoZSBjb2RlIGFzIHBhcnQgb2YgYSBzaGFyZWQgbGlicmFyeSwgYW5kICgyKSB0byBhdm9pZCBzdGF0aWMKICAgICAqIGludGlhbGl6YXRpb24gcHJvYmxlbXMuCiAgICAgKi8KICAgIHN0YXRpYyBVQm9vbCBjYWNoZUluaXRpYWxpemVkOwoKICAgIC8qKgogICAgICogSW4gSmF2YSwgdGhlIGNhY2hlIHN0b3JlcyBvYmplY3RzIG9mIGRpZmZlcmVudCB0eXBlcyBhbmQKICAgICAqIHNpbmdsZXRvbiBvYmplY3RzIGFzIHBsYWNlaG9sZGVycyBmb3IgcnVsZS1iYXNlZAogICAgICogdHJhbnNsaXRlcmF0b3JzIHRvIGJlIGJ1aWx0IGFzIG5lZWRlZC4gIEluIEMrKyB3ZSB1c2UgdGhlCiAgICAgKiBmb2xsb3dpbmcgc3RydWN0IHRvIGFjaGlldmUgdGhlIHNhbWUgcHVycG9zZS4gIEluc3RhbmNlcyBvZgogICAgICogdGhpcyBzdHJ1Y3QgY2FuIGJlIHBsYWNlaG9sZGVycywgY2FuIHJlcHJlc2VudCBwcm90b3R5cGUKICAgICAqIHRyYW5zbGl0ZXJhdG9ycyB0byBiZSBjbG9uZWQsIG9yIGNhbiByZXByZXNlbnQKICAgICAqIFJ1bGVCYXNlZFRyYW5zbGl0ZXJhdG9yOjpEYXRhIG9iamVjdHMuICBXZSBkb24ndCBzdXBwb3J0CiAgICAgKiBzdG9yaW5nIGNsYXNzZXMgaW4gdGhlIGNhY2hlIGJlY2F1c2Ugd2UgZG9uJ3QgaGF2ZSB0aGUgcnR0aQogICAgICogaW5mcmFzdHJ1Y3R1cmUgZm9yIGl0LiAgV2UgY291bGQgZWFzaWx5IGFkZCB0aGlzIGlmIHRoZXJlIGlzIGEKICAgICAqIG5lZWQgZm9yIGl0IGluIHRoZSBmdXR1cmUuICBUaGUgcmJGaWxlIGlzIHRoZSByZXNvdXJjZSBidW5kbGUKICAgICAqIGZpbGUgbmFtZSBmb3IgcnVsZS1iYXNlZCB0cmFuc2xpdGVyYXRvcnMuCiAgICAgKi8KICAgIHN0cnVjdCBDYWNoZUVudHJ5IHsKICAgICAgICBlbnVtIFR5cGUgewogICAgICAgICAgICBSVUxFU19GT1JXQVJELAogICAgICAgICAgICBSVUxFU19SRVZFUlNFLAogICAgICAgICAgICBQUk9UT1RZUEUsCiAgICAgICAgICAgIFJCVF9EQVRBLAogICAgICAgICAgICBBTElBUywKICAgICAgICAgICAgTk9ORSAvLyBPbmx5IHVzZWQgZm9yIHVuaW5pdGlhbGl6ZWQgZW50cmllcwogICAgICAgIH0gZW50cnlUeXBlOwogICAgICAgIC8vIE5PVEU6IHN0cmluZ0FyZyBjYW5ub3QgZ28gaW5zaWRlIHRoZSB1bmlvbiBiZWNhdXNlCiAgICAgICAgLy8gaXQgaGFzIGEgY29weSBjb25zdHJ1Y3RvcgogICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyaW5nQXJnOyAvLyBGb3IgUlVMRVNfKiwgQUxJQVMKICAgICAgICB1bmlvbiB7CiAgICAgICAgICAgIFRyYW5zbGl0ZXJhdG9yKiBwcm90b3R5cGU7IC8vIEZvciBQUk9UT1RZUEUKICAgICAgICAgICAgVHJhbnNsaXRlcmF0aW9uUnVsZURhdGEqIGRhdGE7IC8vIEZvciBSQlRfREFUQQogICAgICAgIH0gdTsKICAgICAgICBDYWNoZUVudHJ5KCk7CiAgICAgICAgfkNhY2hlRW50cnkoKTsKICAgICAgICB2b2lkIGFkb3B0UHJvdG90eXBlKFRyYW5zbGl0ZXJhdG9yKiBhZG9wdGVkKTsKICAgIH07CgogICAgLyoqCiAgICAgKiBQcmVmaXggZm9yIHJlc291cmNlIGJ1bmRsZSBrZXkgZm9yIHRoZSBkaXNwbGF5IG5hbWUgZm9yIGEKICAgICAqIHRyYW5zbGl0ZXJhdG9yLiAgVGhlIElEIGlzIGFwcGVuZGVkIHRvIHRoaXMgdG8gZm9ybSB0aGUga2V5LgogICAgICogVGhlIHJlc291cmNlIGJ1bmRsZSB2YWx1ZSBzaG91bGQgYmUgYSBTdHJpbmcuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBjaGFyKiBSQl9ESVNQTEFZX05BTUVfUFJFRklYOwoKICAgIC8qKgogICAgICogUHJlZml4IGZvciByZXNvdXJjZSBidW5kbGUga2V5IGZvciB0aGUgZGlzcGxheSBuYW1lIGZvciBhCiAgICAgKiB0cmFuc2xpdGVyYXRvciBTQ1JJUFQuICBUaGUgSUQgaXMgYXBwZW5kZWQgdG8gdGhpcyB0byBmb3JtIHRoZSBrZXkuCiAgICAgKiBUaGUgcmVzb3VyY2UgYnVuZGxlIHZhbHVlIHNob3VsZCBiZSBhIFN0cmluZy4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IGNoYXIqIFJCX1NDUklQVF9ESVNQTEFZX05BTUVfUFJFRklYOwoKICAgIC8qKgogICAgICogUmVzb3VyY2UgYnVuZGxlIGtleSBmb3IgZGlzcGxheSBuYW1lIHBhdHRlcm4uCiAgICAgKiBUaGUgcmVzb3VyY2UgYnVuZGxlIHZhbHVlIHNob3VsZCBiZSBhIFN0cmluZyBmb3JtaW5nIGEKICAgICAqIE1lc3NhZ2VGb3JtYXQgcGF0dGVybiwgZS5nLjoKICAgICAqICJ7MCxjaG9pY2UsMCN8MSN7MX0gVHJhbnNsaXRlcmF0b3J8MiN7MX0gdG8gezJ9IFRyYW5zbGl0ZXJhdG9yfSIuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBjaGFyKiBSQl9ESVNQTEFZX05BTUVfUEFUVEVSTjsKCiAgICAvKioKICAgICAqIFJlc291cmNlIGJ1bmRsZSBrZXkgZm9yIHRoZSBsaXN0IG9mIFJ1bGVCYXNlZFRyYW5zbGl0ZXJhdG9yIElEcy4KICAgICAqIFRoZSByZXNvdXJjZSBidW5kbGUgdmFsdWUgc2hvdWxkIGJlIGEgU3RyaW5nW10gd2l0aCBlYWNoIGVsZW1lbnQKICAgICAqIGJlaW5nIGEgdmFsaWQgSUQuICBUaGUgSUQgd2lsbCBiZSBhcHBlbmRlZCB0byBSQl9SVUxFX0JBU0VEX1BSRUZJWAogICAgICogdG8gb2J0YWluIHRoZSBjbGFzcyBuYW1lIGluIHdoaWNoIHRoZSBSQl9SVUxFIGtleSB3aWxsIGJlIHNvdWdodC4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IGNoYXIqIFJCX1JVTEVfQkFTRURfSURTOwoKICAgIC8qKgogICAgICogUmVzb3VyY2UgYnVuZGxlIGtleSBmb3IgdGhlIFJ1bGVCYXNlZFRyYW5zbGl0ZXJhdG9yIHJ1bGUuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBjaGFyKiBSQl9SVUxFOwoKcHJvdGVjdGVkOgoKICAgIC8qKgogICAgICogRGVmYXVsdCBjb25zdHJ1Y3Rvci4KICAgICAqIEBwYXJhbSBJRCB0aGUgc3RyaW5nIGlkZW50aWZpZXIgZm9yIHRoaXMgdHJhbnNsaXRlcmF0b3IKICAgICAqIEBwYXJhbSBhZG9wdGVkRmlsdGVyIHRoZSBmaWx0ZXIuICBBbnkgY2hhcmFjdGVyIGZvciB3aGljaAogICAgICogPHR0PmZpbHRlci5jb250YWlucygpPC90dD4gcmV0dXJucyA8dHQ+ZmFsc2U8L3R0PiB3aWxsIG5vdCBiZQogICAgICogYWx0ZXJlZCBieSB0aGlzIHRyYW5zbGl0ZXJhdG9yLiAgSWYgPHR0PmZpbHRlcjwvdHQ+IGlzCiAgICAgKiA8dHQ+bnVsbDwvdHQ+IHRoZW4gbm8gZmlsdGVyaW5nIGlzIGFwcGxpZWQuCiAgICAgKi8KICAgIFRyYW5zbGl0ZXJhdG9yKGNvbnN0IFVuaWNvZGVTdHJpbmcmIElELCBVbmljb2RlRmlsdGVyKiBhZG9wdGVkRmlsdGVyKTsKCiAgICAvKioKICAgICAqIENvcHkgY29uc3RydWN0b3IuCiAgICAgKi8KICAgIFRyYW5zbGl0ZXJhdG9yKGNvbnN0IFRyYW5zbGl0ZXJhdG9yJik7CgogICAgLyoqCiAgICAgKiBBc3NpZ25tZW50IG9wZXJhdG9yLgogICAgICovCiAgICBUcmFuc2xpdGVyYXRvciYgb3BlcmF0b3I9KGNvbnN0IFRyYW5zbGl0ZXJhdG9yJik7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBEZXN0cnVjdG9yLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgflRyYW5zbGl0ZXJhdG9yKCk7CgogICAgLyoqCiAgICAgKiBJbXBsZW1lbnRzIENsb25lYWJsZS4KICAgICAqIEFsbCBzdWJjbGFzc2VzIGFyZSBlbmNvdXJhZ2VkIHRvIGltcGxlbWVudCB0aGlzIG1ldGhvZCBpZiBpdCBpcwogICAgICogcG9zc2libGUgYW5kIHJlYXNvbmFibGUgdG8gZG8gc28uICBTdWJjbGFzc2VzIHRoYXQgYXJlIHRvIGJlCiAgICAgKiByZWdpc3RlcmVkIHdpdGggdGhlIHN5c3RlbSB1c2luZyA8dHQ+cmVnaXN0ZXJJbnN0YW5jZSgpPHR0PgogICAgICogYXJlIHJlcXVpcmVkIHRvIGltcGxlbWVudCB0aGlzIG1ldGhvZC4gIElmIGEgc3ViY2xhc3MgZG9lcyBub3QKICAgICAqIGltcGxlbWVudCBjbG9uZSgpIHByb3Blcmx5IGFuZCBpcyByZWdpc3RlcmVkIHdpdGggdGhlIHN5c3RlbQogICAgICogdXNpbmcgcmVnaXN0ZXJJbnN0YW5jZSgpLCB0aGVuIHRoZSBkZWZhdWx0IGNsb25lKCkgaW1wbGVtZW50YXRpb24KICAgICAqIHdpbGwgcmV0dXJuIG51bGwsIGFuZCBjYWxscyB0byBjcmVhdGVJbnN0YW5jZSgpIHdpbGwgZmFpbC4KICAgICAqCiAgICAgKiBAc2VlICNyZWdpc3Rlckluc3RhbmNlCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCBUcmFuc2xpdGVyYXRvciogY2xvbmUoKSBjb25zdCB7IHJldHVybiAwOyB9CgogICAgLyoqCiAgICAgKiBUcmFuc2xpdGVyYXRlcyBhIHNlZ21lbnQgb2YgYSBzdHJpbmcsIHdpdGggb3B0aW9uYWwgZmlsdGVyaW5nLgogICAgICoKICAgICAqIEBwYXJhbSB0ZXh0IHRoZSBzdHJpbmcgdG8gYmUgdHJhbnNsaXRlcmF0ZWQKICAgICAqIEBwYXJhbSBzdGFydCB0aGUgYmVnaW5uaW5nIGluZGV4LCBpbmNsdXNpdmU7IDxjb2RlPjAgPD0gc3RhcnQKICAgICAqIDw9IGxpbWl0PC9jb2RlPi4KICAgICAqIEBwYXJhbSBsaW1pdCB0aGUgZW5kaW5nIGluZGV4LCBleGNsdXNpdmU7IDxjb2RlPnN0YXJ0IDw9IGxpbWl0CiAgICAgKiA8PSB0ZXh0Lmxlbmd0aCgpPC9jb2RlPi4KICAgICAqIEBwYXJhbSBmaWx0ZXIgdGhlIGZpbHRlci4gIEFueSBjaGFyYWN0ZXIgZm9yIHdoaWNoCiAgICAgKiA8dHQ+ZmlsdGVyLmNvbnRhaW5zKCk8L3R0PiByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+IHdpbGwgbm90IGJlCiAgICAgKiBhbHRlcmVkIGJ5IHRoaXMgdHJhbnNsaXRlcmF0b3IuICBJZiA8dHQ+ZmlsdGVyPC90dD4gaXMKICAgICAqIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgaXMgYXBwbGllZC4KICAgICAqIEByZXR1cm4gVGhlIG5ldyBsaW1pdCBpbmRleC4gIFRoZSB0ZXh0IHByZXZpb3VzbHkgb2NjdXB5aW5nIDxjb2RlPltzdGFydCwKICAgICAqIGxpbWl0KTwvY29kZT4gaGFzIGJlZW4gdHJhbnNsaXRlcmF0ZWQsIHBvc3NpYmx5IHRvIGEgc3RyaW5nIG9mIGEgZGlmZmVyZW50CiAgICAgKiBsZW5ndGgsIGF0IDxjb2RlPltzdGFydCwgPC9jb2RlPjxlbT5uZXctbGltaXQ8L2VtPjxjb2RlPik8L2NvZGU+LCB3aGVyZQogICAgICogPGVtPm5ldy1saW1pdDwvZW0+IGlzIHRoZSByZXR1cm4gdmFsdWUuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCBpbnQzMl90IHRyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUmIHRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IHN0YXJ0LCBpbnQzMl90IGxpbWl0KSBjb25zdDsKCiAgICAvKioKICAgICAqIFRyYW5zbGl0ZXJhdGVzIGFuIGVudGlyZSBzdHJpbmcgaW4gcGxhY2UuIENvbnZlbmllbmNlIG1ldGhvZC4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSBzdHJpbmcgdG8gYmUgdHJhbnNsaXRlcmF0ZWQKICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgdHJhbnNsaXRlcmF0ZShSZXBsYWNlYWJsZSYgdGV4dCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBUcmFuc2xpdGVyYXRlcyB0aGUgcG9ydGlvbiBvZiB0aGUgdGV4dCBidWZmZXIgdGhhdCBjYW4gYmUKICAgICAqIHRyYW5zbGl0ZXJhdGVkIHVuYW1iaWd1b3NseSBhZnRlciBuZXcgdGV4dCBoYXMgYmVlbiBpbnNlcnRlZCwKICAgICAqIHR5cGljYWxseSBhcyBhIHJlc3VsdCBvZiBhIGtleWJvYXJkIGV2ZW50LiAgVGhlIG5ldyB0ZXh0IGluCiAgICAgKiA8Y29kZT5pbnNlcnRpb248L2NvZGU+IHdpbGwgYmUgaW5zZXJ0ZWQgaW50byA8Y29kZT50ZXh0PC9jb2RlPgogICAgICogYXQgPGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+LCBhZHZhbmNpbmcKICAgICAqIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPiBieSA8Y29kZT5pbnNlcnRpb24ubGVuZ3RoKCk8L2NvZGU+LgogICAgICogVGhlbiB0aGUgdHJhbnNsaXRlcmF0b3Igd2lsbCB0cnkgdG8gdHJhbnNsaXRlcmF0ZSBjaGFyYWN0ZXJzIG9mCiAgICAgKiA8Y29kZT50ZXh0PC9jb2RlPiBiZXR3ZWVuIDxjb2RlPmluZGV4LmN1cnNvcjwvY29kZT4gYW5kCiAgICAgKiA8Y29kZT5pbmRleC5saW1pdDwvY29kZT4uICBDaGFyYWN0ZXJzIGJlZm9yZQogICAgICogPGNvZGU+aW5kZXguY3Vyc29yPC9jb2RlPiB3aWxsIG5vdCBiZSBjaGFuZ2VkLgogICAgICoKICAgICAqIDxwPlVwb24gcmV0dXJuLCB2YWx1ZXMgaW4gPGNvZGU+aW5kZXg8L2NvZGU+IHdpbGwgYmUgdXBkYXRlZC4KICAgICAqIDxjb2RlPmluZGV4LnN0YXJ0PC9jb2RlPiB3aWxsIGJlIGFkdmFuY2VkIHRvIHRoZSBmaXJzdAogICAgICogY2hhcmFjdGVyIHRoYXQgZnV0dXJlIGNhbGxzIHRvIHRoaXMgbWV0aG9kIHdpbGwgcmVhZC4KICAgICAqIDxjb2RlPmluZGV4LmN1cnNvcjwvY29kZT4gYW5kIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPiB3aWxsCiAgICAgKiBiZSBhZGp1c3RlZCB0byBkZWxpbWl0IHRoZSByYW5nZSBvZiB0ZXh0IHRoYXQgZnV0dXJlIGNhbGxzIHRvCiAgICAgKiB0aGlzIG1ldGhvZCBtYXkgY2hhbmdlLgogICAgICoKICAgICAqIDxwPlR5cGljYWwgdXNhZ2Ugb2YgdGhpcyBtZXRob2QgYmVnaW5zIHdpdGggYW4gaW5pdGlhbCBjYWxsCiAgICAgKiB3aXRoIDxjb2RlPmluZGV4LnN0YXJ0PC9jb2RlPiBhbmQgPGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+CiAgICAgKiBzZXQgdG8gaW5kaWNhdGUgdGhlIHBvcnRpb24gb2YgPGNvZGU+dGV4dDwvY29kZT4gdG8gYmUKICAgICAqIHRyYW5zbGl0ZXJhdGVkLCBhbmQgPGNvZGU+aW5kZXguY3Vyc29yID09IGluZGV4LnN0YXJ0PC9jb2RlPi4KICAgICAqIFRoZXJlYWZ0ZXIsIDxjb2RlPmluZGV4PC9jb2RlPiBjYW4gYmUgdXNlZCB3aXRob3V0CiAgICAgKiBtb2RpZmljYXRpb24gaW4gZnV0dXJlIGNhbGxzLCBwcm92aWRlZCB0aGF0IGFsbCBjaGFuZ2VzIHRvCiAgICAgKiA8Y29kZT50ZXh0PC9jb2RlPiBhcmUgbWFkZSB2aWEgdGhpcyBtZXRob2QuCiAgICAgKgogICAgICogPHA+VGhpcyBtZXRob2QgYXNzdW1lcyB0aGF0IGZ1dHVyZSBjYWxscyBtYXkgYmUgbWFkZSB0aGF0IHdpbGwKICAgICAqIGluc2VydCBuZXcgdGV4dCBpbnRvIHRoZSBidWZmZXIuICBBcyBhIHJlc3VsdCwgaXQgb25seSBwZXJmb3JtcwogICAgICogdW5hbWJpZ3VvdXMgdHJhbnNsaXRlcmF0aW9ucy4gIEFmdGVyIHRoZSBsYXN0IGNhbGwgdG8gdGhpcwogICAgICogbWV0aG9kLCB0aGVyZSBtYXkgYmUgdW50cmFuc2xpdGVyYXRlZCB0ZXh0IHRoYXQgaXMgd2FpdGluZyBmb3IKICAgICAqIG1vcmUgaW5wdXQgdG8gcmVzb2x2ZSBhbiBhbWJpZ3VpdHkuICBJbiBvcmRlciB0byBwZXJmb3JtIHRoZXNlCiAgICAgKiBwZW5kaW5nIHRyYW5zbGl0ZXJhdGlvbnMsIGNsaWVudHMgc2hvdWxkIGNhbGwge0BsaW5rCiAgICAgKiAjZmluaXNoVHJhbnNsaXRlcmF0aW9ufSBhZnRlciB0aGUgbGFzdCBjYWxsIHRvIHRoaXMKICAgICAqIG1ldGhvZCBoYXMgYmVlbiBtYWRlLgogICAgICogCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgYnVmZmVyIGhvbGRpbmcgdHJhbnNsaXRlcmF0ZWQgYW5kIHVudHJhbnNsaXRlcmF0ZWQgdGV4dAogICAgICogQHBhcmFtIGluZGV4IGFuIGFycmF5IG9mIHRocmVlIGludGVnZXJzLgogICAgICoKICAgICAqIDx1bD48bGk+PGNvZGU+aW5kZXguc3RhcnQ8L2NvZGU+OiB0aGUgYmVnaW5uaW5nIGluZGV4LAogICAgICogaW5jbHVzaXZlOyA8Y29kZT4wIDw9IGluZGV4LnN0YXJ0IDw9IGluZGV4LmxpbWl0PC9jb2RlPi4KICAgICAqCiAgICAgKiA8bGk+PGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+OiB0aGUgZW5kaW5nIGluZGV4LCBleGNsdXNpdmU7CiAgICAgKiA8Y29kZT5pbmRleC5zdGFydCA8PSBpbmRleC5saW1pdCA8PSB0ZXh0Lmxlbmd0aCgpPC9jb2RlPi4KICAgICAqIDxjb2RlPmluc2VydGlvbjwvY29kZT4gaXMgaW5zZXJ0ZWQgYXQKICAgICAqIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPi4KICAgICAqCiAgICAgKiA8bGk+PGNvZGU+aW5kZXguY3Vyc29yPC9jb2RlPjogdGhlIG5leHQgY2hhcmFjdGVyIHRvIGJlCiAgICAgKiBjb25zaWRlcmVkIGZvciB0cmFuc2xpdGVyYXRpb247IDxjb2RlPmluZGV4LnN0YXJ0IDw9CiAgICAgKiBpbmRleC5jdXJzb3IgPD0gaW5kZXgubGltaXQ8L2NvZGU+LiAgQ2hhcmFjdGVycyBiZWZvcmUKICAgICAqIDxjb2RlPmluZGV4LmN1cnNvcjwvY29kZT4gd2lsbCBub3QgYmUgY2hhbmdlZCBieSBmdXR1cmUgY2FsbHMKICAgICAqIHRvIHRoaXMgbWV0aG9kLjwvdWw+CiAgICAgKgogICAgICogQHBhcmFtIGluc2VydGlvbiB0ZXh0IHRvIGJlIGluc2VydGVkIGFuZCBwb3NzaWJseQogICAgICogdHJhbnNsaXRlcmF0ZWQgaW50byB0aGUgdHJhbnNsYXRpb24gYnVmZmVyIGF0CiAgICAgKiA8Y29kZT5pbmRleC5saW1pdDwvY29kZT4uICBJZiA8Y29kZT5udWxsPC9jb2RlPiB0aGVuIG5vIHRleHQKICAgICAqIGlzIGluc2VydGVkLgogICAgICogQHNlZSAjaGFuZGxlVHJhbnNsaXRlcmF0ZQogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgPGNvZGU+aW5kZXg8L2NvZGU+CiAgICAgKiBpcyBpbnZhbGlkCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHRyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUmIHRleHQsIFVUcmFuc1Bvc2l0aW9uJiBpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGluc2VydGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBUcmFuc2xpdGVyYXRlcyB0aGUgcG9ydGlvbiBvZiB0aGUgdGV4dCBidWZmZXIgdGhhdCBjYW4gYmUKICAgICAqIHRyYW5zbGl0ZXJhdGVkIHVuYW1iaWd1b3NseSBhZnRlciBhIG5ldyBjaGFyYWN0ZXIgaGFzIGJlZW4KICAgICAqIGluc2VydGVkLCB0eXBpY2FsbHkgYXMgYSByZXN1bHQgb2YgYSBrZXlib2FyZCBldmVudC4gIFRoaXMgaXMgYQogICAgICogY29udmVuaWVuY2UgbWV0aG9kOyBzZWUge0BsaW5rCiAgICAgKiAjdHJhbnNsaXRlcmF0ZShSZXBsYWNlYWJsZSwgaW50W10sIFN0cmluZyl9IGZvciBkZXRhaWxzLgogICAgICogQHBhcmFtIHRleHQgdGhlIGJ1ZmZlciBob2xkaW5nIHRyYW5zbGl0ZXJhdGVkIGFuZAogICAgICogdW50cmFuc2xpdGVyYXRlZCB0ZXh0CiAgICAgKiBAcGFyYW0gaW5kZXggYW4gYXJyYXkgb2YgdGhyZWUgaW50ZWdlcnMuICBTZWUge0BsaW5rCiAgICAgKiAjdHJhbnNsaXRlcmF0ZShSZXBsYWNlYWJsZSwgaW50W10sIFN0cmluZyl9LgogICAgICogQHBhcmFtIGluc2VydGlvbiB0ZXh0IHRvIGJlIGluc2VydGVkIGFuZCBwb3NzaWJseQogICAgICogdHJhbnNsaXRlcmF0ZWQgaW50byB0aGUgdHJhbnNsYXRpb24gYnVmZmVyIGF0CiAgICAgKiA8Y29kZT5pbmRleC5saW1pdDwvY29kZT4uCiAgICAgKiBAc2VlICN0cmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlLCBpbnRbXSwgU3RyaW5nKQogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCB0cmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlJiB0ZXh0LCBVVHJhbnNQb3NpdGlvbiYgaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ2hhciBpbnNlcnRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwogICAgCiAgICAvKioKICAgICAqIFRyYW5zbGl0ZXJhdGVzIHRoZSBwb3J0aW9uIG9mIHRoZSB0ZXh0IGJ1ZmZlciB0aGF0IGNhbiBiZQogICAgICogdHJhbnNsaXRlcmF0ZWQgdW5hbWJpZ3Vvc2x5LiAgVGhpcyBpcyBhIGNvbnZlbmllbmNlIG1ldGhvZDsgc2VlCiAgICAgKiB7QGxpbmsgI3RyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUsIGludFtdLCBTdHJpbmcpfSBmb3IKICAgICAqIGRldGFpbHMuCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgYnVmZmVyIGhvbGRpbmcgdHJhbnNsaXRlcmF0ZWQgYW5kCiAgICAgKiB1bnRyYW5zbGl0ZXJhdGVkIHRleHQKICAgICAqIEBwYXJhbSBpbmRleCBhbiBhcnJheSBvZiB0aHJlZSBpbnRlZ2Vycy4gIFNlZSB7QGxpbmsKICAgICAqICN0cmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlLCBpbnRbXSwgU3RyaW5nKX0uCiAgICAgKiBAc2VlICN0cmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlLCBpbnRbXSwgU3RyaW5nKQogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCB0cmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlJiB0ZXh0LCBVVHJhbnNQb3NpdGlvbiYgaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIGNvbnN0OwoKICAgIC8qKgogICAgICogRmluaXNoZXMgYW55IHBlbmRpbmcgdHJhbnNsaXRlcmF0aW9ucyB0aGF0IHdlcmUgd2FpdGluZyBmb3IKICAgICAqIG1vcmUgY2hhcmFjdGVycy4gIENsaWVudHMgc2hvdWxkIGNhbGwgdGhpcyBtZXRob2QgYXMgdGhlIGxhc3QKICAgICAqIGNhbGwgYWZ0ZXIgYSBzZXF1ZW5jZSBvZiBvbmUgb3IgbW9yZSBjYWxscyB0bwogICAgICogPGNvZGU+dHJhbnNsaXRlcmF0ZSgpPC9jb2RlPi4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSBidWZmZXIgaG9sZGluZyB0cmFuc2xpdGVyYXRlZCBhbmQKICAgICAqIHVudHJhbnNsaXRlcmF0ZWQgdGV4dC4KICAgICAqIEBwYXJhbSBpbmRleCB0aGUgYXJyYXkgb2YgaW5kaWNlcyBwcmV2aW91c2x5IHBhc3NlZCB0byB7QGxpbmsKICAgICAqICN0cmFuc2xpdGVyYXRlfQogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCBmaW5pc2hUcmFuc2xpdGVyYXRpb24oUmVwbGFjZWFibGUmIHRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVUcmFuc1Bvc2l0aW9uJiBpbmRleCkgY29uc3Q7Cgpwcml2YXRlOgoKICAgIC8qKgogICAgICogVGhpcyBpbnRlcm5hbCBtZXRob2QgZG9lcyBpbmNyZW1lbnRhbCB0cmFuc2xpdGVyYXRpb24uICBJZiB0aGUKICAgICAqICdpbnNlcnRpb24nIGlzIG5vbi1udWxsIHRoZW4gd2UgYXBwZW5kIGl0IHRvICd0ZXh0JyBiZWZvcmUKICAgICAqIHByb2NlZWRpbmcuICBUaGlzIG1ldGhvZCBjYWxscyB0aHJvdWdoIHRvIHRoZSBwdXJlIHZpcnR1YWwKICAgICAqIGZyYW1ld29yayBtZXRob2QgaGFuZGxlVHJhbnNsaXRlcmF0ZSgpIHRvIGRvIHRoZSBhY3R1YWwKICAgICAqIHdvcmsuCiAgICAgKi8KICAgIHZvaWQgX3RyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUmIHRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgIFVUcmFuc1Bvc2l0aW9uJiBpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyogaW5zZXJ0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpIGNvbnN0OwoKcHJvdGVjdGVkOgoKICAgIC8qKgogICAgICogQWJzdHJhY3QgbWV0aG9kIHRoYXQgY29uY3JldGUgc3ViY2xhc3NlcyBkZWZpbmUgdG8gaW1wbGVtZW50CiAgICAgKiBrZXlib2FyZCB0cmFuc2xpdGVyYXRpb24uICBUaGlzIG1ldGhvZCBzaG91bGQgdHJhbnNsaXRlcmF0ZSBhbGwKICAgICAqIGNoYXJhY3RlcnMgYmV0d2VlbiA8Y29kZT5pbmRleC5jdXJzb3I8L2NvZGU+IGFuZAogICAgICogPGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+IHRoYXQgY2FuIGJlIHVuYW1iaWd1b3VzbHkKICAgICAqIHRyYW5zbGl0ZXJhdGVkLCByZWdhcmRsZXNzIG9mIGZ1dHVyZSBpbnNlcnRpb25zIG9mIHRleHQgYXQKICAgICAqIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPi4gIDxjb2RlPmluZGV4LmN1cnNvcjwvY29kZT4gc2hvdWxkCiAgICAgKiBiZSBhZHZhbmNlZCBwYXN0IGNvbW1pdHRlZCBjaGFyYWN0ZXJzICh0aG9zZSB0aGF0IHdpbGwgbm90CiAgICAgKiBjaGFuZ2UgaW4gZnV0dXJlIGNhbGxzIHRvIHRoaXMgbWV0aG9kKS4KICAgICAqIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPiBzaG91bGQgYmUgdXBkYXRlZCB0byByZWZsZWN0IHRleHQKICAgICAqIHJlcGxhY2VtZW50cyB0aGF0IHNob3J0ZW4gb3IgbGVuZ3RoZW4gdGhlIHRleHQgYmV0d2VlbgogICAgICogPGNvZGU+aW5kZXguY3Vyc29yPC9jb2RlPiBhbmQgPGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+LiAgVXBvbgogICAgICogcmV0dXJuLCBuZWl0aGVyIDxjb2RlPmluZGV4LmN1cnNvcjwvY29kZT4gbm9yCiAgICAgKiA8Y29kZT5pbmRleC5saW1pdDwvY29kZT4gc2hvdWxkIGJlIGxlc3MgdGhhbiB0aGUgaW5pdGlhbCB2YWx1ZQogICAgICogb2YgPGNvZGU+aW5kZXguY3Vyc29yPC9jb2RlPi4gIDxjb2RlPmluZGV4LnN0YXJ0PC9jb2RlPgogICAgICogc2hvdWxkIDxlbT5ub3Q8L2VtPiBiZSBjaGFuZ2VkLgogICAgICoKICAgICAqIEBwYXJhbSB0ZXh0IHRoZSBidWZmZXIgaG9sZGluZyB0cmFuc2xpdGVyYXRlZCBhbmQKICAgICAqIHVudHJhbnNsaXRlcmF0ZWQgdGV4dAogICAgICogQHBhcmFtIGluZGV4IGFuIGFycmF5IG9mIHRocmVlIGludGVnZXJzLiAgU2VlIHtAbGluawogICAgICogI3RyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUsIGludFtdLCBTdHJpbmcpfS4KICAgICAqIEBzZWUgI3RyYW5zbGl0ZXJhdGUKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGhhbmRsZVRyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUmIHRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVVHJhbnNQb3NpdGlvbiYgaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQm9vbCBpbmNyZW1lbnRhbCkgY29uc3QgPSAwOwoKICAgIC8vIEMrKyByZXF1aXJlcyB0aGlzIGZyaWVuZCBkZWNsYXJhdGlvbiBzbyBDb21wb3VuZFRyYW5zbGl0ZXJhdG9yCiAgICAvLyBjYW4gYWNjZXNzIGhhbmRsZVRyYW5zbGl0ZXJhdGUuICBBbHRlcm5hdGl2ZWx5LCB3ZSBjb3VsZAogICAgLy8gbWFrZSBoYW5kbGVUcmFuc2xpdGVyYXRlIHB1YmxpYy4KICAgIGZyaWVuZCBjbGFzcyBDb21wb3VuZFRyYW5zbGl0ZXJhdG9yOwoKcHVibGljOgoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBsb25nZXN0IGNvbnRleHQgcmVxdWlyZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvci4KICAgICAqIFRoaXMgaXMgPGVtPnByZWNlZGluZzwvZW0+IGNvbnRleHQuICBUaGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBzdXBwbGllZAogICAgICogYnkgPGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+IHJldHVybnMgemVybzsgc3ViY2xhc3NlcwogICAgICogdGhhdCB1c2UgcHJlY2VkaW5nIGNvbnRleHQgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIHJldHVybiB0aGUKICAgICAqIGNvcnJlY3QgdmFsdWUuICBGb3IgZXhhbXBsZSwgaWYgYSB0cmFuc2xpdGVyYXRvciB0cmFuc2xhdGVzICJkZGQiICh3aGVyZQogICAgICogZCBpcyBhbnkgZGlnaXQpIHRvICI1NTUiIHdoZW4gcHJlY2VkZWQgYnkgIihkZGQpIiwgdGhlbiB0aGUgcHJlY2VkaW5nCiAgICAgKiBjb250ZXh0IGxlbmd0aCBpcyA1LCB0aGUgbGVuZ3RoIG9mICIoZGRkKSIuCiAgICAgKgogICAgICogQHJldHVybiBUaGUgbWF4aW11bSBudW1iZXIgb2YgcHJlY2VkaW5nIGNvbnRleHQgY2hhcmFjdGVycyB0aGlzCiAgICAgKiB0cmFuc2xpdGVyYXRvciBuZWVkcyB0byBleGFtaW5lCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgaW50MzJfdCBnZXRNYXhpbXVtQ29udGV4dExlbmd0aCh2b2lkKSBjb25zdDsKCnByb3RlY3RlZDoKCiAgICAvKioKICAgICAqIE1ldGhvZCBmb3Igc3ViY2xhc3NlcyB0byB1c2UgdG8gc2V0IHRoZSBtYXhpbXVtIGNvbnRleHQgbGVuZ3RoLgogICAgICogQHNlZSAjZ2V0TWF4aW11bUNvbnRleHRMZW5ndGgKICAgICAqLwogICAgdm9pZCBzZXRNYXhpbXVtQ29udGV4dExlbmd0aChpbnQzMl90IG1heENvbnRleHRMZW5ndGgpOwoKcHVibGljOgoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHByb2dyYW1tYXRpYyBpZGVudGlmaWVyIGZvciB0aGlzIHRyYW5zbGl0ZXJhdG9yLgogICAgICogSWYgdGhpcyBpZGVudGlmaWVyIGlzIHBhc3NlZCB0byA8Y29kZT5nZXRJbnN0YW5jZSgpPC9jb2RlPiwgaXQKICAgICAqIHdpbGwgcmV0dXJuIHRoaXMgb2JqZWN0LCBpZiBpdCBoYXMgYmVlbiByZWdpc3RlcmVkLgogICAgICogQHNlZSAjcmVnaXN0ZXJJbnN0YW5jZQogICAgICogQHNlZSAjcmVnaXN0ZXJDbGFzcwogICAgICogQHNlZSAjZ2V0QXZhaWxhYmxlSURzCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCBjb25zdCBVbmljb2RlU3RyaW5nJiBnZXRJRCh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBuYW1lIGZvciB0aGlzIHRyYW5zbGl0ZXJhdG9yIHRoYXQgaXMgYXBwcm9wcmlhdGUgZm9yCiAgICAgKiBkaXNwbGF5IHRvIHRoZSB1c2VyIGluIHRoZSBkZWZhdWx0IGxvY2FsZS4gIFNlZSB7QGxpbmsKICAgICAqICNnZXREaXNwbGF5TmFtZShMb2NhbGUpfSBmb3IgZGV0YWlscy4KICAgICAqIEBkcmFmdAogICAgICovCiAgICBzdGF0aWMgVW5pY29kZVN0cmluZyYgZ2V0RGlzcGxheU5hbWUoY29uc3QgVW5pY29kZVN0cmluZyYgSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyYgcmVzdWx0KTsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSBuYW1lIGZvciB0aGlzIHRyYW5zbGl0ZXJhdG9yIHRoYXQgaXMgYXBwcm9wcmlhdGUgZm9yCiAgICAgKiBkaXNwbGF5IHRvIHRoZSB1c2VyIGluIHRoZSBnaXZlbiBsb2NhbGUuICBUaGlzIG5hbWUgaXMgdGFrZW4KICAgICAqIGZyb20gdGhlIGxvY2FsZSByZXNvdXJjZSBkYXRhIGluIHRoZSBzdGFuZGFyZCBtYW5uZXIgb2YgdGhlCiAgICAgKiA8Y29kZT5qYXZhLnRleHQ8L2NvZGU+IHBhY2thZ2UuCiAgICAgKgogICAgICogPHA+SWYgbm8gbG9jYWxpemVkIG5hbWVzIGV4aXN0IGluIHRoZSBzeXN0ZW0gcmVzb3VyY2UgYnVuZGxlcywKICAgICAqIGEgbmFtZSBpcyBzeW50aGVzaXplZCB1c2luZyBhIGxvY2FsaXplZAogICAgICogPGNvZGU+TWVzc2FnZUZvcm1hdDwvY29kZT4gcGF0dGVybiBmcm9tIHRoZSByZXNvdXJjZSBkYXRhLiAgVGhlCiAgICAgKiBhcmd1bWVudHMgdG8gdGhpcyBwYXR0ZXJuIGFyZSBhbiBpbnRlZ2VyIGZvbGxvd2VkIGJ5IG9uZSBvciB0d28KICAgICAqIHN0cmluZ3MuICBUaGUgaW50ZWdlciBpcyB0aGUgbnVtYmVyIG9mIHN0cmluZ3MsIGVpdGhlciAxIG9yIDIuCiAgICAgKiBUaGUgc3RyaW5ncyBhcmUgZm9ybWVkIGJ5IHNwbGl0dGluZyB0aGUgSUQgZm9yIHRoaXMKICAgICAqIHRyYW5zbGl0ZXJhdG9yIGF0IHRoZSBmaXJzdCAnLScuICBJZiB0aGVyZSBpcyBubyAnLScsIHRoZW4gdGhlCiAgICAgKiBlbnRpcmUgSUQgZm9ybXMgdGhlIG9ubHkgc3RyaW5nLgogICAgICogQHBhcmFtIGluTG9jYWxlIHRoZSBMb2NhbGUgaW4gd2hpY2ggdGhlIGRpc3BsYXkgbmFtZSBzaG91bGQgYmUKICAgICAqIGxvY2FsaXplZC4KICAgICAqIEBzZWUgamF2YS50ZXh0Lk1lc3NhZ2VGb3JtYXQKICAgICAqIEBkcmFmdAogICAgICovCiAgICBzdGF0aWMgVW5pY29kZVN0cmluZyYgZ2V0RGlzcGxheU5hbWUoY29uc3QgVW5pY29kZVN0cmluZyYgSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgTG9jYWxlJiBpbkxvY2FsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiByZXN1bHQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZmlsdGVyIHVzZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvciwgb3IgPHR0Pk5VTEw8L3R0PgogICAgICogaWYgdGhpcyB0cmFuc2xpdGVyYXRvciB1c2VzIG5vIGZpbHRlci4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIGNvbnN0IFVuaWNvZGVGaWx0ZXIqIGdldEZpbHRlcih2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgdGhlIGZpbHRlciB1c2VkIGJ5IHRoaXMgdHJhbnNsaXRlcmF0b3IsIG9yIDx0dD5OVUxMPC90dD4gaWYgdGhpcwogICAgICogdHJhbnNsaXRlcmF0b3IgdXNlcyBubyBmaWx0ZXIuICBUaGUgY2FsbGVyIG11c3QgZXZlbnR1YWxseSBkZWxldGUgdGhlCiAgICAgKiByZXN1bHQuICBBZnRlciB0aGlzIGNhbGwsIHRoaXMgdHJhbnNsaXRlcmF0b3IncyBmaWx0ZXIgaXMgc2V0IHRvCiAgICAgKiA8dHQ+TlVMTDwvdHQ+LiAgQ2FsbHMgYWRvcHRGaWx0ZXIoKS4KICAgICAqLwogICAgVW5pY29kZUZpbHRlciogb3JwaGFuRmlsdGVyKHZvaWQpOwoKICAgIC8qKgogICAgICogQ2hhbmdlcyB0aGUgZmlsdGVyIHVzZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvci4gIElmIHRoZSBmaWx0ZXIKICAgICAqIGlzIHNldCB0byA8dHQ+bnVsbDwvdHQ+IHRoZW4gbm8gZmlsdGVyaW5nIHdpbGwgb2NjdXIuCiAgICAgKgogICAgICogPHA+Q2FsbGVycyBtdXN0IHRha2UgY2FyZSBpZiBhIHRyYW5zbGl0ZXJhdG9yIGlzIGluIHVzZSBieQogICAgICogbXVsdGlwbGUgdGhyZWFkcy4gIFRoZSBmaWx0ZXIgc2hvdWxkIG5vdCBiZSBjaGFuZ2VkIGJ5IG9uZQogICAgICogdGhyZWFkIHdoaWxlIGFub3RoZXIgdGhyZWFkIG1heSBiZSB0cmFuc2xpdGVyYXRpbmcuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGFkb3B0RmlsdGVyKFVuaWNvZGVGaWx0ZXIqIGFkb3B0ZWRGaWx0ZXIpOwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGlzIHRyYW5zbGl0ZXJhdG9yJ3MgaW52ZXJzZS4gIFNlZSB0aGUgY2xhc3MKICAgICAqIGRvY3VtZW50YXRpb24gZm9yIGRldGFpbHMuICBUaGlzIGltcGxlbWVudGF0aW9uIHNpbXBseSBpbnZlcnRzCiAgICAgKiB0aGUgdHdvIGVudGl0aWVzIGluIHRoZSBJRCBhbmQgYXR0ZW1wdHMgdG8gcmV0cmlldmUgdGhlCiAgICAgKiByZXN1bHRpbmcgdHJhbnNsaXRlcmF0b3IuICBUaGF0IGlzLCBpZiA8Y29kZT5nZXRJRCgpPC9jb2RlPgogICAgICogcmV0dXJucyAiQS1CIiwgdGhlbiB0aGlzIG1ldGhvZCB3aWxsIHJldHVybiB0aGUgcmVzdWx0IG9mCiAgICAgKiA8Y29kZT5nZXRJbnN0YW5jZSgiQi1BIik8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiB0aGF0CiAgICAgKiBjYWxsIGZhaWxzLgogICAgICoKICAgICAqIDxwPlRoaXMgbWV0aG9kIGRvZXMgbm90IHRha2UgZmlsdGVyaW5nIGludG8gYWNjb3VudC4gIFRoZQogICAgICogcmV0dXJuZWQgdHJhbnNsaXRlcmF0b3Igd2lsbCBoYXZlIG5vIGZpbHRlci4KICAgICAqCiAgICAgKiA8cD5TdWJjbGFzc2VzIHdpdGgga25vd2xlZGdlIG9mIHRoZWlyIGludmVyc2UgbWF5IHdpc2ggdG8KICAgICAqIG92ZXJyaWRlIHRoaXMgbWV0aG9kLgogICAgICoKICAgICAqIEByZXR1cm4gYSB0cmFuc2xpdGVyYXRvciB0aGF0IGlzIGFuIGludmVyc2UsIG5vdCBuZWNlc3NhcmlseQogICAgICogZXhhY3QsIG9mIHRoaXMgdHJhbnNsaXRlcmF0b3IsIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIG5vIHN1Y2gKICAgICAqIHRyYW5zbGl0ZXJhdG9yIGlzIHJlZ2lzdGVyZWQuCiAgICAgKiBAc2VlICNyZWdpc3Rlckluc3RhbmNlCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgVHJhbnNsaXRlcmF0b3IqIGNyZWF0ZUludmVyc2Uodm9pZCkgY29uc3Q7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgPGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+IG9iamVjdCBnaXZlbiBpdHMgSUQuCiAgICAgKiBUaGUgSUQgbXVzdCBiZSBlaXRoZXIgYSBzeXN0ZW0gdHJhbnNsaXRlcmF0b3IgSUQgb3IgYSBJRCByZWdpc3RlcmVkCiAgICAgKiB1c2luZyA8Y29kZT5yZWdpc3Rlckluc3RhbmNlKCk8L2NvZGU+LgogICAgICoKICAgICAqIEBwYXJhbSBJRCBhIHZhbGlkIElELCBhcyBlbnVtZXJhdGVkIGJ5IDxjb2RlPmdldEF2YWlsYWJsZUlEcygpPC9jb2RlPgogICAgICogQHJldHVybiBBIDxjb2RlPlRyYW5zbGl0ZXJhdG9yPC9jb2RlPiBvYmplY3Qgd2l0aCB0aGUgZ2l2ZW4gSUQKICAgICAqIEBleGNlcHRpb24gSWxsZWdhbEFyZ3VtZW50RXhjZXB0aW9uIGlmIHRoZSBnaXZlbiBJRCBpcyBpbnZhbGlkLgogICAgICogQHNlZSAjcmVnaXN0ZXJJbnN0YW5jZQogICAgICogQHNlZSAjZ2V0QXZhaWxhYmxlSURzCiAgICAgKiBAc2VlICNnZXRJRAogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHN0YXRpYyBUcmFuc2xpdGVyYXRvciogY3JlYXRlSW5zdGFuY2UoY29uc3QgVW5pY29kZVN0cmluZyYgSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVUcmFuc0RpcmVjdGlvbiBkaXIgPSBVVFJBTlNfRk9SV0FSRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVBhcnNlRXJyb3IqIHBhcnNlRXJyb3IgPSAwKTsKCnByaXZhdGU6CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgdHJhbnNsaXRlcmF0b3Igb2JqZWN0IGdpdmVuIGl0cyBJRC4gIFVubGlrZSBnZXRJbnN0YW5jZSgpLAogICAgICogdGhpcyBtZXRob2QgcmV0dXJucyBudWxsIGlmIGl0IGNhbm5vdCBtYWtlIHVzZSBvZiB0aGUgZ2l2ZW4gSUQuCiAgICAgKiBAcGFyYW0gYWxpYXNSZXR1cm4gaWYgSUQgaXMgYW4gYWxpYXMgdHJhbnNsaXRlcmF0b3IgdGhpcyBpcyBzZXQKICAgICAqIHRoZSB0aGUgcGFyYW1ldGVyIHRvIGJlIHBhc3NlZCB0byBjcmVhdGVJbnN0YW5jZSgpIGFuZCAwIGlzCiAgICAgKiByZXR1cm5lZDsgb3RoZXJ3aXNlLCB0aGlzIGlzIHVuY2hhbmdlZAogICAgICovCiAgICBzdGF0aWMgVHJhbnNsaXRlcmF0b3IqIF9jcmVhdGVJbnN0YW5jZShjb25zdCBVbmljb2RlU3RyaW5nJiBJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmIGFsaWFzUmV0dXJuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVBhcnNlRXJyb3IqIHBhcnNlRXJyb3IgPSAwKTsKCnB1YmxpYzoKCiAgICAvKioKICAgICAqIFJlZ2lzdGVycyBhIGluc3RhbmNlIDx0dD5vYmo8L3R0PiBvZiBhIHN1YmNsYXNzIG9mCiAgICAgKiA8Y29kZT5UcmFuc2xpdGVyYXRvcjwvY29kZT4gd2l0aCB0aGUgc3lzdGVtLiAgV2hlbgogICAgICogPHR0PmNyZWF0ZUluc3RhbmNlKCk8L3R0PiBpcyBjYWxsZWQgd2l0aCBhbiBJRCBzdHJpbmcgdGhhdCBpcwogICAgICogZXF1YWwgdG8gPHR0Pm9iai0+Z2V0SUQoKTwvdHQ+LCB0aGVuIDx0dD5vYmotPmNsb25lKCk8L3R0PiBpcwogICAgICogcmV0dXJuZWQuCiAgICAgKgogICAgICogQWZ0ZXIgdGhpcyBjYWxsIHRoZSBUcmFuc2xpdGVyYXRvciBjbGFzcyBvd25zIHRoZSBhZG9wdGVkT2JqCiAgICAgKiBhbmQgd2lsbCBkZWxldGUgaXQuCiAgICAgKgogICAgICogQHBhcmFtIG9iaiBhbiBpbnN0YW5jZSBvZiBzdWJjbGFzcyBvZgogICAgICogPGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+IHRoYXQgZGVmaW5lcyA8dHQ+Y2xvbmUoKTwvdHQ+CiAgICAgKiBAc2VlICNnZXRJbnN0YW5jZQogICAgICogQHNlZSAjcmVnaXN0ZXJDbGFzcwogICAgICogQHNlZSAjdW5yZWdpc3RlcgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHN0YXRpYyB2b2lkIHJlZ2lzdGVySW5zdGFuY2UoVHJhbnNsaXRlcmF0b3IqIGFkb3B0ZWRPYmosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cyk7Cgpwcml2YXRlOgoKICAgIC8qKgogICAgICogVGhpcyBpbnRlcm5hbCBtZXRob2QgcmVnaXN0ZXJzIGEgcHJvdG90eXBlIGluc3RhbmNlIGluIHRoZSBjYWNoZS4KICAgICAqIFRoZSBDQUxMRVIgTVVTVCBNVVRFWCB1c2luZyBjYWNoZU11dGV4IGJlZm9yZSBjYWxsaW5nIHRoaXMgbWV0aG9kLgogICAgICovCiAgICBzdGF0aWMgdm9pZCBfcmVnaXN0ZXJJbnN0YW5jZShUcmFuc2xpdGVyYXRvciogYWRvcHRlZFByb3RvdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cyk7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBVbnJlZ2lzdGVycyBhIHRyYW5zbGl0ZXJhdG9yIG9yIGNsYXNzLiAgVGhpcyBtYXkgYmUgZWl0aGVyCiAgICAgKiBhIHN5c3RlbSB0cmFuc2xpdGVyYXRvciBvciBhIHVzZXIgdHJhbnNsaXRlcmF0b3Igb3IgY2xhc3MuCiAgICAgKiAKICAgICAqIEBwYXJhbSBJRCB0aGUgSUQgb2YgdGhlIHRyYW5zbGl0ZXJhdG9yIG9yIGNsYXNzCiAgICAgKiBAcmV0dXJuIHRoZSA8Y29kZT5PYmplY3Q8L2NvZGU+IHRoYXQgd2FzIHJlZ2lzdGVyZWQgd2l0aAogICAgICogPGNvZGU+SUQ8L2NvZGU+LCBvciA8Y29kZT5udWxsPC9jb2RlPiBpZiBub25lIHdhcwogICAgICogQHNlZSAjcmVnaXN0ZXJJbnN0YW5jZQogICAgICogQHNlZSAjcmVnaXN0ZXJDbGFzcwogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHN0YXRpYyB2b2lkIHVucmVnaXN0ZXIoY29uc3QgVW5pY29kZVN0cmluZyYgSUQpOwoKcHJpdmF0ZToKCiAgICAvKioKICAgICAqIFVucmVnaXN0ZXJzIGEgdHJhbnNsaXRlcmF0b3Igb3IgY2xhc3MuICBJbnRlcm5hbCBtZXRob2QuCiAgICAgKiBQcmVyZXF1aXNpdGVzOiBUaGUgY2FjaGUgbXVzdCBiZSBpbml0aWFsaXplZCwgYW5kIHRoZQogICAgICogY2FsbGVyIG11c3Qgb3duIHRoZSBjYWNoZU11dGV4LgogICAgICovCiAgICBzdGF0aWMgdm9pZCBfdW5yZWdpc3Rlcihjb25zdCBVbmljb2RlU3RyaW5nJiBJRCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGFuIGVudW1lcmF0aW9uIG92ZXIgdGhlIHByb2dyYW1tYXRpYyBuYW1lcyBvZiByZWdpc3RlcmVkCiAgICAgKiA8Y29kZT5UcmFuc2xpdGVyYXRvcjwvY29kZT4gb2JqZWN0cy4gIFRoaXMgaW5jbHVkZXMgYm90aCBzeXN0ZW0KICAgICAqIHRyYW5zbGl0ZXJhdG9ycyBhbmQgdXNlciB0cmFuc2xpdGVyYXRvcnMgcmVnaXN0ZXJlZCB1c2luZwogICAgICogPGNvZGU+cmVnaXN0ZXJJbnN0YW5jZSgpPC9jb2RlPi4gIFRoZSBlbnVtZXJhdGVkIG5hbWVzIG1heSBiZQogICAgICogcGFzc2VkIHRvIDxjb2RlPmdldEluc3RhbmNlKCk8L2NvZGU+LgogICAgICoKICAgICAqIEByZXR1cm4gQW4gPGNvZGU+RW51bWVyYXRpb248L2NvZGU+IG92ZXIgPGNvZGU+U3RyaW5nPC9jb2RlPiBvYmplY3RzCiAgICAgKiBAc2VlICNnZXRJbnN0YW5jZQogICAgICogQHNlZSAjcmVnaXN0ZXJJbnN0YW5jZQogICAgICovCiAgICAvLyB2aXJ0dWFsIEVudW1lcmF0aW9uIGdldEF2YWlsYWJsZUlEcygpOwoKICAgIC8qKgogICAgICogVmVjdG9yIG9mIHJlZ2lzdGVyZWQgSURzLgogICAgICovCiAgICBzdGF0aWMgVVZlY3RvciBjYWNoZUlEczsKCnB1YmxpYzoKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgbnVtYmVyIG9mIElEcyBjdXJyZW50bHkgcmVnaXN0ZXJlZCB3aXRoIHRoZSBzeXN0ZW0uCiAgICAgKiBUbyByZXRyaWV2ZSB0aGUgYWN0dWFsIElEcywgY2FsbCBnZXRBdmFpbGFibGVJRChpKSB3aXRoCiAgICAgKiBpIGZyb20gMCB0byBjb3VudEF2YWlsYWJsZUlEcygpIC0gMS4KICAgICAqIEBkcmFmdAogICAgICovCiAgICBzdGF0aWMgaW50MzJfdCBjb3VudEF2YWlsYWJsZUlEcyh2b2lkKTsKCiAgICAvKioKICAgICAqIFJldHVybiB0aGUgaW5kZXgtdGggYXZhaWxhYmxlIElELiAgaW5kZXggbXVzdCBiZSBiZXR3ZWVuIDAKICAgICAqIGFuZCBjb3VudEF2YWlsYWJsZUlEcygpIC0gMSwgaW5jbHVzaXZlLiAgSWYgaW5kZXggaXMgb3V0IG9mCiAgICAgKiByYW5nZSwgdGhlIHJlc3VsdCBvZiBnZXRBdmFpbGFibGVJRCgwKSBpcyByZXR1cm5lZC4KICAgICAqIEBkcmFmdAogICAgICovCiAgICBzdGF0aWMgY29uc3QgVW5pY29kZVN0cmluZyYgZ2V0QXZhaWxhYmxlSUQoaW50MzJfdCBpbmRleCk7Cgpwcm90ZWN0ZWQ6CgogICAgLyoqCiAgICAgKiBNZXRob2QgZm9yIHN1YmNsYXNzZXMgdG8gdXNlIHRvIG9idGFpbiBhIGNoYXJhY3RlciBpbiB0aGUgZ2l2ZW4KICAgICAqIHN0cmluZywgd2l0aCBmaWx0ZXJpbmcuICBJZiB0aGUgY2hhcmFjdGVyIGF0IHRoZSBnaXZlbiBvZmZzZXQKICAgICAqIGlzIGV4Y2x1ZGVkIGJ5IHRoaXMgdHJhbnNsaXRlcmF0b3IncyBmaWx0ZXIsIHRoZW4gVStGRkZFIGlzIHJldHVybmVkLgogICAgICovCiAgICBVQ2hhciBmaWx0ZXJlZENoYXJBdChjb25zdCBSZXBsYWNlYWJsZSYgdGV4dCwgaW50MzJfdCBpKSBjb25zdDsKCiAgICAvKioKICAgICAqIFNldCB0aGUgSUQgb2YgdGhpcyB0cmFuc2xpdGVyYXRvcnMuICBTdWJjbGFzc2VzIHNob3VsZG4ndCBkbwogICAgICogdGhpcywgdW5sZXNzIHRoZSB1bmRlcmx5aW5nIHNjcmlwdCBiZWhhdmlvciBoYXMgY2hhbmdlZC4KICAgICAqLwogICAgdm9pZCBzZXRJRChjb25zdCBVbmljb2RlU3RyaW5nJiBpZCk7Cgpwcml2YXRlOgogICAgLyoqCiAgICAgKiBDb21wYXJpc29uIGZ1bmN0aW9uIGZvciBVVmVjdG9yLiAgQ29tcGFyZXMgdHdvIFVuaWNvZGVTdHJpbmcKICAgICAqIG9iamVjdHMgZ2l2ZW4gdm9pZCogcG9pbnRlcnMgdG8gdGhlbS4KICAgICAqLwogICAgc3RhdGljIFVCb29sIGNvbXBhcmVJRHModm9pZCogYSwgdm9pZCogYik7CgogICAgc3RhdGljIHZvaWQgaW5pdGlhbGl6ZUNhY2hlKHZvaWQpOwoKICAgIC8qIElEcyB0YWtlIHRoZSBmb3JtIDxzb3VyY2U+IElEX1NFUCA8dGFyZ2V0Piwgd2hlcmUKICAgICAqIDxzb3VyY2U+IGFuZCA8dGFyZ2V0PiBhcmUgKHVzdWFsbHkpIHNjcmlwdCBuYW1lcy4KICAgICAqIENvbXBvdW5kIElEcyB0YWtlIHRoZSBmb3JtIDxJRD4gKCBJRF9ERUxJTSA8SUQ+ICkrLgogICAgICovCiAgICBzdGF0aWMgY29uc3QgVUNoYXIgSURfU0VQOyAgIC8vICgoVUNoYXIpMHgwMDJEKSAvKi0qLwogICAgc3RhdGljIGNvbnN0IFVDaGFyIElEX0RFTElNOyAvLyAoKFVDaGFyKTB4MDAzQikgLyo7Ki8KfTsKCmlubGluZSBpbnQzMl90IFRyYW5zbGl0ZXJhdG9yOjpnZXRNYXhpbXVtQ29udGV4dExlbmd0aCh2b2lkKSBjb25zdCB7CiAgICByZXR1cm4gbWF4aW11bUNvbnRleHRMZW5ndGg7Cn0KCmlubGluZSB2b2lkIFRyYW5zbGl0ZXJhdG9yOjpzZXRJRChjb25zdCBVbmljb2RlU3RyaW5nJiBpZCkgewogICAgSUQgPSBpZDsKfQoKI2VuZGlmCg==