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+ZmlsdGVyPC90dD4gaXMKICAgICAqIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgaXMgYXBwbGllZC4KICAgICAqLwogICAgVW5pY29kZUZpbHRlciogZmlsdGVyOwoKICAgIGludDMyX3QgbWF4aW11bUNvbnRleHRMZW5ndGg7CgogICAgLyoqCiAgICAgKiBEaWN0aW9uYXJ5IG9mIGtub3duIHRyYW5zbGl0ZXJhdG9ycy4gIEtleXMgYXJlIDxjb2RlPlN0cmluZzwvY29kZT4KICAgICAqIG5hbWVzLCB2YWx1ZXMgYXJlIG9uZSBvZiB0aGUgZm9sbG93aW5nOgogICAgICoKICAgICAqIDx1bD48bGk+PGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+IG9iamVjdHMKICAgICAqCiAgICAgKiA8bGk+PGNvZGU+Q2xhc3M8L2NvZGU+IG9iamVjdHMuICBTdWNoIG9iamVjdHMgbXVzdCByZXByZXNlbnQKICAgICAqIHN1YmNsYXNzZXMgb2YgPGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+LCBhbmQgbXVzdCBzYXRpc2Z5IHRoZQogICAgICogY29uc3RyYWludHMgZGVzY3JpYmVkIGluIDxjb2RlPnJlZ2lzdGVyQ2xhc3MoKTwvY29kZT4KICAgICAqCiAgICAgKiA8bGk+PGNvZGU+UlVMRV9CQVNFRF9QTEFDRUhPTERFUjwvY29kZT4sIGluIHdoaWNoIGNhc2UgdGhlIElECiAgICAgKiB3aWxsIGhhdmUgaXRzIGZpcnN0ICctJyByZW1vdmVkIGFuZCBiZSBhcHBlbmRlZCB0bwogICAgICogUkJfUlVMRV9CQVNFRF9QUkVGSVggdG8gZm9ybSBhIHJlc291cmNlIGJ1bmRsZSBuYW1lIGZyb20gd2hpY2gKICAgICAqIHRoZSBSQl9SVUxFIGtleSBpcyBsb29rZWQgdXAgdG8gb2J0YWluIHRoZSBydWxlLgogICAgICoKICAgICAqIDxsaT48Y29kZT5SRVZFUlNFX1JVTEVfQkFTRURfUExBQ0VIT0xERVI8L2NvZGU+LiAgTGlrZQogICAgICogPGNvZGU+UlVMRV9CQVNFRF9QTEFDRUhPTERFUjwvY29kZT4sIGV4Y2VwdCB0aGUgZW50aXR5IG5hbWVzIGluCiAgICAgKiB0aGUgSUQgYXJlIHJldmVyc2VkLCBhbmQgdGhlIGFyZ3VtZW50CiAgICAgKiBSdWxlQmFzZWRUcmFuc2xpdGVyYXRvci5SRVZFUlNFIGlzIHBhc2VkIHRvIHRoZQogICAgICogUnVsZUJhc2VkVHJhbnNsaXRlcmF0b3IgY29uc3RydWN0b3IuCiAgICAgKiA8L3VsPgogICAgICovCiAgICBzdGF0aWMgSGFzaHRhYmxlKiBjYWNoZTsKCiAgICAvKioKICAgICAqIFRoZSBtdXRleCBjb250cm9sbGluZyBhY2Nlc3MgdG8gdGhlIGNhY2hlLgogICAgICovCiAgICBzdGF0aWMgVU1UWCBjYWNoZU11dGV4OwoKICAgIC8qKgogICAgICogV2hlbiBzZXQgdG8gVFJVRSwgdGhlIGNhY2hlIGhhcyBiZWVuIGluaXRpYWxpemVkLiAgQW55IGNvZGUgbXVzdAogICAgICogY2hlY2sgdGhpcyBib29sZWFuIGJlZm9yZSBhY2Nlc3NpbmcgdGhlIGNhY2hlLCBhbmQgaWYgdGhlIGJvb2xlYW4KICAgICAqIGlzIEZBTFNFLCBpdCBtdXN0IGNhbGwgaW5pdGlhbGl6ZUNhY2hlKCkuICBXZSBkbyB0aGlzIGZvcm0gb2YgbGF6eQogICAgICogZXZhbHVhdGlvbiBmb3IgdHdvIHJlYXNvbnM6ICgxKSBzbyB3ZSBkb24ndCBpbml0aWFsaXplIGlmIHdlIGRvbid0CiAgICAgKiBoYXZlIHRvIChpLmUuLCBpZiBubyBvbmUgaXMgdXNpbmcgVHJhbnNsaXRlcmF0b3IsIGJ1dCBoYXMgaW5jbHVkZWQKICAgICAqIHRoZSBjb2RlIGFzIHBhcnQgb2YgYSBzaGFyZWQgbGlicmFyeSwgYW5kICgyKSB0byBhdm9pZCBzdGF0aWMKICAgICAqIGludGlhbGl6YXRpb24gcHJvYmxlbXMuCiAgICAgKi8KICAgIHN0YXRpYyBVQm9vbCBjYWNoZUluaXRpYWxpemVkOwoKICAgIC8qKgogICAgICogSW4gSmF2YSwgdGhlIGNhY2hlIHN0b3JlcyBvYmplY3RzIG9mIGRpZmZlcmVudCB0eXBlcyBhbmQKICAgICAqIHNpbmdsZXRvbiBvYmplY3RzIGFzIHBsYWNlaG9sZGVycyBmb3IgcnVsZS1iYXNlZAogICAgICogdHJhbnNsaXRlcmF0b3JzIHRvIGJlIGJ1aWx0IGFzIG5lZWRlZC4gIEluIEMrKyB3ZSB1c2UgdGhlCiAgICAgKiBmb2xsb3dpbmcgc3RydWN0IHRvIGFjaGlldmUgdGhlIHNhbWUgcHVycG9zZS4gIEluc3RhbmNlcyBvZgogICAgICogdGhpcyBzdHJ1Y3QgY2FuIGJlIHBsYWNlaG9sZGVycywgY2FuIHJlcHJlc2VudCBwcm90b3R5cGUKICAgICAqIHRyYW5zbGl0ZXJhdG9ycyB0byBiZSBjbG9uZWQsIG9yIGNhbiByZXByZXNlbnQKICAgICAqIFJ1bGVCYXNlZFRyYW5zbGl0ZXJhdG9yOjpEYXRhIG9iamVjdHMuICBXZSBkb24ndCBzdXBwb3J0CiAgICAgKiBzdG9yaW5nIGNsYXNzZXMgaW4gdGhlIGNhY2hlIGJlY2F1c2Ugd2UgZG9uJ3QgaGF2ZSB0aGUgcnR0aQogICAgICogaW5mcmFzdHJ1Y3R1cmUgZm9yIGl0LiAgV2UgY291bGQgZWFzaWx5IGFkZCB0aGlzIGlmIHRoZXJlIGlzIGEKICAgICAqIG5lZWQgZm9yIGl0IGluIHRoZSBmdXR1cmUuICBUaGUgcmJGaWxlIGlzIHRoZSByZXNvdXJjZSBidW5kbGUKICAgICAqIGZpbGUgbmFtZSBmb3IgcnVsZS1iYXNlZCB0cmFuc2xpdGVyYXRvcnMuCiAgICAgKi8KICAgIHN0cnVjdCBDYWNoZUVudHJ5IHsKICAgICAgICBlbnVtIFR5cGUgewogICAgICAgICAgICBSVUxFX0JBU0VEX1BMQUNFSE9MREVSLAogICAgICAgICAgICBSRVZFUlNFX1JVTEVfQkFTRURfUExBQ0VIT0xERVIsCiAgICAgICAgICAgIFBST1RPVFlQRSwKICAgICAgICAgICAgUkJUX0RBVEEsCiAgICAgICAgICAgIE5PTkUgLy8gT25seSB1c2VkIGZvciB1bmluaXRpYWxpemVkIGVudHJpZXMKICAgICAgICB9IGVudHJ5VHlwZTsKICAgICAgICBVbmljb2RlU3RyaW5nIHJiRmlsZTsgLy8gRm9yICpQTEFDRUhPTERFUgogICAgICAgIHVuaW9uIHsKICAgICAgICAgICAgVHJhbnNsaXRlcmF0b3IqIHByb3RvdHlwZTsgLy8gRm9yIFBST1RPVFlQRQogICAgICAgICAgICBUcmFuc2xpdGVyYXRpb25SdWxlRGF0YSogZGF0YTsgLy8gRm9yIFJCVF9EQVRBCiAgICAgICAgfSB1OwogICAgICAgIENhY2hlRW50cnkoKTsKICAgICAgICB+Q2FjaGVFbnRyeSgpOwogICAgICAgIHZvaWQgYWRvcHRQcm90b3R5cGUoVHJhbnNsaXRlcmF0b3IqIGFkb3B0ZWQpOwogICAgfTsKCiAgICAvKioKICAgICAqIFByZWZpeCBmb3IgcmVzb3VyY2UgYnVuZGxlIGtleSBmb3IgdGhlIGRpc3BsYXkgbmFtZSBmb3IgYQogICAgICogdHJhbnNsaXRlcmF0b3IuICBUaGUgSUQgaXMgYXBwZW5kZWQgdG8gdGhpcyB0byBmb3JtIHRoZSBrZXkuCiAgICAgKiBUaGUgcmVzb3VyY2UgYnVuZGxlIHZhbHVlIHNob3VsZCBiZSBhIFN0cmluZy4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IGNoYXIqIFJCX0RJU1BMQVlfTkFNRV9QUkVGSVg7CgogICAgLyoqCiAgICAgKiBQcmVmaXggZm9yIHJlc291cmNlIGJ1bmRsZSBrZXkgZm9yIHRoZSBkaXNwbGF5IG5hbWUgZm9yIGEKICAgICAqIHRyYW5zbGl0ZXJhdG9yIFNDUklQVC4gIFRoZSBJRCBpcyBhcHBlbmRlZCB0byB0aGlzIHRvIGZvcm0gdGhlIGtleS4KICAgICAqIFRoZSByZXNvdXJjZSBidW5kbGUgdmFsdWUgc2hvdWxkIGJlIGEgU3RyaW5nLgogICAgICovCiAgICBzdGF0aWMgY29uc3QgY2hhciogUkJfU0NSSVBUX0RJU1BMQVlfTkFNRV9QUkVGSVg7CgogICAgLyoqCiAgICAgKiBSZXNvdXJjZSBidW5kbGUga2V5IGZvciBkaXNwbGF5IG5hbWUgcGF0dGVybi4KICAgICAqIFRoZSByZXNvdXJjZSBidW5kbGUgdmFsdWUgc2hvdWxkIGJlIGEgU3RyaW5nIGZvcm1pbmcgYQogICAgICogTWVzc2FnZUZvcm1hdCBwYXR0ZXJuLCBlLmcuOgogICAgICogInswLGNob2ljZSwwI3wxI3sxfSBUcmFuc2xpdGVyYXRvcnwyI3sxfSB0byB7Mn0gVHJhbnNsaXRlcmF0b3J9Ii4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IGNoYXIqIFJCX0RJU1BMQVlfTkFNRV9QQVRURVJOOwoKICAgIC8qKgogICAgICogUmVzb3VyY2UgYnVuZGxlIGtleSBmb3IgdGhlIGxpc3Qgb2YgUnVsZUJhc2VkVHJhbnNsaXRlcmF0b3IgSURzLgogICAgICogVGhlIHJlc291cmNlIGJ1bmRsZSB2YWx1ZSBzaG91bGQgYmUgYSBTdHJpbmdbXSB3aXRoIGVhY2ggZWxlbWVudAogICAgICogYmVpbmcgYSB2YWxpZCBJRC4gIFRoZSBJRCB3aWxsIGJlIGFwcGVuZGVkIHRvIFJCX1JVTEVfQkFTRURfUFJFRklYCiAgICAgKiB0byBvYnRhaW4gdGhlIGNsYXNzIG5hbWUgaW4gd2hpY2ggdGhlIFJCX1JVTEUga2V5IHdpbGwgYmUgc291Z2h0LgogICAgICovCiAgICBzdGF0aWMgY29uc3QgY2hhciogUkJfUlVMRV9CQVNFRF9JRFM7CgogICAgLyoqCiAgICAgKiBSZXNvdXJjZSBidW5kbGUga2V5IGZvciB0aGUgUnVsZUJhc2VkVHJhbnNsaXRlcmF0b3IgcnVsZS4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IGNoYXIqIFJCX1JVTEU7Cgpwcm90ZWN0ZWQ6CgogICAgLyoqCiAgICAgKiBEZWZhdWx0IGNvbnN0cnVjdG9yLgogICAgICogQHBhcmFtIElEIHRoZSBzdHJpbmcgaWRlbnRpZmllciBmb3IgdGhpcyB0cmFuc2xpdGVyYXRvcgogICAgICogQHBhcmFtIGFkb3B0ZWRGaWx0ZXIgdGhlIGZpbHRlci4gIEFueSBjaGFyYWN0ZXIgZm9yIHdoaWNoCiAgICAgKiA8dHQ+ZmlsdGVyLmNvbnRhaW5zKCk8L3R0PiByZXR1cm5zIDx0dD5mYWxzZTwvdHQ+IHdpbGwgbm90IGJlCiAgICAgKiBhbHRlcmVkIGJ5IHRoaXMgdHJhbnNsaXRlcmF0b3IuICBJZiA8dHQ+ZmlsdGVyPC90dD4gaXMKICAgICAqIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgaXMgYXBwbGllZC4KICAgICAqLwogICAgVHJhbnNsaXRlcmF0b3IoY29uc3QgVW5pY29kZVN0cmluZyYgSUQsIFVuaWNvZGVGaWx0ZXIqIGFkb3B0ZWRGaWx0ZXIpOwoKICAgIC8qKgogICAgICogQ29weSBjb25zdHJ1Y3Rvci4KICAgICAqLwogICAgVHJhbnNsaXRlcmF0b3IoY29uc3QgVHJhbnNsaXRlcmF0b3ImKTsKCiAgICAvKioKICAgICAqIEFzc2lnbm1lbnQgb3BlcmF0b3IuCiAgICAgKi8KICAgIFRyYW5zbGl0ZXJhdG9yJiBvcGVyYXRvcj0oY29uc3QgVHJhbnNsaXRlcmF0b3ImKTsKCnB1YmxpYzoKCiAgICAvKioKICAgICAqIERlc3RydWN0b3IuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCB+VHJhbnNsaXRlcmF0b3IoKTsKCiAgICAvKioKICAgICAqIEltcGxlbWVudHMgQ2xvbmVhYmxlLgogICAgICogQWxsIHN1YmNsYXNzZXMgYXJlIGVuY291cmFnZWQgdG8gaW1wbGVtZW50IHRoaXMgbWV0aG9kIGlmIGl0IGlzCiAgICAgKiBwb3NzaWJsZSBhbmQgcmVhc29uYWJsZSB0byBkbyBzby4gIFN1YmNsYXNzZXMgdGhhdCBhcmUgdG8gYmUKICAgICAqIHJlZ2lzdGVyZWQgd2l0aCB0aGUgc3lzdGVtIHVzaW5nIDx0dD5yZWdpc3Rlckluc3RhbmNlKCk8dHQ+CiAgICAgKiBhcmUgcmVxdWlyZWQgdG8gaW1wbGVtZW50IHRoaXMgbWV0aG9kLiAgSWYgYSBzdWJjbGFzcyBkb2VzIG5vdAogICAgICogaW1wbGVtZW50IGNsb25lKCkgcHJvcGVybHkgYW5kIGlzIHJlZ2lzdGVyZWQgd2l0aCB0aGUgc3lzdGVtCiAgICAgKiB1c2luZyByZWdpc3Rlckluc3RhbmNlKCksIHRoZW4gdGhlIGRlZmF1bHQgY2xvbmUoKSBpbXBsZW1lbnRhdGlvbgogICAgICogd2lsbCByZXR1cm4gbnVsbCwgYW5kIGNhbGxzIHRvIGNyZWF0ZUluc3RhbmNlKCkgd2lsbCBmYWlsLgogICAgICoKICAgICAqIEBzZWUgI3JlZ2lzdGVySW5zdGFuY2UKICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIFRyYW5zbGl0ZXJhdG9yKiBjbG9uZSgpIGNvbnN0IHsgcmV0dXJuIDA7IH0KCiAgICAvKioKICAgICAqIFRyYW5zbGl0ZXJhdGVzIGEgc2VnbWVudCBvZiBhIHN0cmluZywgd2l0aCBvcHRpb25hbCBmaWx0ZXJpbmcuCiAgICAgKgogICAgICogQHBhcmFtIHRleHQgdGhlIHN0cmluZyB0byBiZSB0cmFuc2xpdGVyYXRlZAogICAgICogQHBhcmFtIHN0YXJ0IHRoZSBiZWdpbm5pbmcgaW5kZXgsIGluY2x1c2l2ZTsgPGNvZGU+MCA8PSBzdGFydAogICAgICogPD0gbGltaXQ8L2NvZGU+LgogICAgICogQHBhcmFtIGxpbWl0IHRoZSBlbmRpbmcgaW5kZXgsIGV4Y2x1c2l2ZTsgPGNvZGU+c3RhcnQgPD0gbGltaXQKICAgICAqIDw9IHRleHQubGVuZ3RoKCk8L2NvZGU+LgogICAgICogQHBhcmFtIGZpbHRlciB0aGUgZmlsdGVyLiAgQW55IGNoYXJhY3RlciBmb3Igd2hpY2gKICAgICAqIDx0dD5maWx0ZXIuY29udGFpbnMoKTwvdHQ+IHJldHVybnMgPHR0PmZhbHNlPC90dD4gd2lsbCBub3QgYmUKICAgICAqIGFsdGVyZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvci4gIElmIDx0dD5maWx0ZXI8L3R0PiBpcwogICAgICogPHR0Pm51bGw8L3R0PiB0aGVuIG5vIGZpbHRlcmluZyBpcyBhcHBsaWVkLgogICAgICogQHJldHVybiBUaGUgbmV3IGxpbWl0IGluZGV4LiAgVGhlIHRleHQgcHJldmlvdXNseSBvY2N1cHlpbmcgPGNvZGU+W3N0YXJ0LAogICAgICogbGltaXQpPC9jb2RlPiBoYXMgYmVlbiB0cmFuc2xpdGVyYXRlZCwgcG9zc2libHkgdG8gYSBzdHJpbmcgb2YgYSBkaWZmZXJlbnQKICAgICAqIGxlbmd0aCwgYXQgPGNvZGU+W3N0YXJ0LCA8L2NvZGU+PGVtPm5ldy1saW1pdDwvZW0+PGNvZGU+KTwvY29kZT4sIHdoZXJlCiAgICAgKiA8ZW0+bmV3LWxpbWl0PC9lbT4gaXMgdGhlIHJldHVybiB2YWx1ZS4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIGludDMyX3QgdHJhbnNsaXRlcmF0ZShSZXBsYWNlYWJsZSYgdGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3Qgc3RhcnQsIGludDMyX3QgbGltaXQpIGNvbnN0OwoKICAgIC8qKgogICAgICogVHJhbnNsaXRlcmF0ZXMgYW4gZW50aXJlIHN0cmluZyBpbiBwbGFjZS4gQ29udmVuaWVuY2UgbWV0aG9kLgogICAgICogQHBhcmFtIHRleHQgdGhlIHN0cmluZyB0byBiZSB0cmFuc2xpdGVyYXRlZAogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgdm9pZCB0cmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlJiB0ZXh0KSBjb25zdDsKCiAgICAvKioKICAgICAqIFRyYW5zbGl0ZXJhdGVzIHRoZSBwb3J0aW9uIG9mIHRoZSB0ZXh0IGJ1ZmZlciB0aGF0IGNhbiBiZQogICAgICogdHJhbnNsaXRlcmF0ZWQgdW5hbWJpZ3Vvc2x5IGFmdGVyIG5ldyB0ZXh0IGhhcyBiZWVuIGluc2VydGVkLAogICAgICogdHlwaWNhbGx5IGFzIGEgcmVzdWx0IG9mIGEga2V5Ym9hcmQgZXZlbnQuICBUaGUgbmV3IHRleHQgaW4KICAgICAqIDxjb2RlPmluc2VydGlvbjwvY29kZT4gd2lsbCBiZSBpbnNlcnRlZCBpbnRvIDxjb2RlPnRleHQ8L2NvZGU+CiAgICAgKiBhdCA8Y29kZT5pbmRleC5saW1pdDwvY29kZT4sIGFkdmFuY2luZwogICAgICogPGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+IGJ5IDxjb2RlPmluc2VydGlvbi5sZW5ndGgoKTwvY29kZT4uCiAgICAgKiBUaGVuIHRoZSB0cmFuc2xpdGVyYXRvciB3aWxsIHRyeSB0byB0cmFuc2xpdGVyYXRlIGNoYXJhY3RlcnMgb2YKICAgICAqIDxjb2RlPnRleHQ8L2NvZGU+IGJldHdlZW4gPGNvZGU+aW5kZXguY3Vyc29yPC9jb2RlPiBhbmQKICAgICAqIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPi4gIENoYXJhY3RlcnMgYmVmb3JlCiAgICAgKiA8Y29kZT5pbmRleC5jdXJzb3I8L2NvZGU+IHdpbGwgbm90IGJlIGNoYW5nZWQuCiAgICAgKgogICAgICogPHA+VXBvbiByZXR1cm4sIHZhbHVlcyBpbiA8Y29kZT5pbmRleDwvY29kZT4gd2lsbCBiZSB1cGRhdGVkLgogICAgICogPGNvZGU+aW5kZXguc3RhcnQ8L2NvZGU+IHdpbGwgYmUgYWR2YW5jZWQgdG8gdGhlIGZpcnN0CiAgICAgKiBjaGFyYWN0ZXIgdGhhdCBmdXR1cmUgY2FsbHMgdG8gdGhpcyBtZXRob2Qgd2lsbCByZWFkLgogICAgICogPGNvZGU+aW5kZXguY3Vyc29yPC9jb2RlPiBhbmQgPGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+IHdpbGwKICAgICAqIGJlIGFkanVzdGVkIHRvIGRlbGltaXQgdGhlIHJhbmdlIG9mIHRleHQgdGhhdCBmdXR1cmUgY2FsbHMgdG8KICAgICAqIHRoaXMgbWV0aG9kIG1heSBjaGFuZ2UuCiAgICAgKgogICAgICogPHA+VHlwaWNhbCB1c2FnZSBvZiB0aGlzIG1ldGhvZCBiZWdpbnMgd2l0aCBhbiBpbml0aWFsIGNhbGwKICAgICAqIHdpdGggPGNvZGU+aW5kZXguc3RhcnQ8L2NvZGU+IGFuZCA8Y29kZT5pbmRleC5saW1pdDwvY29kZT4KICAgICAqIHNldCB0byBpbmRpY2F0ZSB0aGUgcG9ydGlvbiBvZiA8Y29kZT50ZXh0PC9jb2RlPiB0byBiZQogICAgICogdHJhbnNsaXRlcmF0ZWQsIGFuZCA8Y29kZT5pbmRleC5jdXJzb3IgPT0gaW5kZXguc3RhcnQ8L2NvZGU+LgogICAgICogVGhlcmVhZnRlciwgPGNvZGU+aW5kZXg8L2NvZGU+IGNhbiBiZSB1c2VkIHdpdGhvdXQKICAgICAqIG1vZGlmaWNhdGlvbiBpbiBmdXR1cmUgY2FsbHMsIHByb3ZpZGVkIHRoYXQgYWxsIGNoYW5nZXMgdG8KICAgICAqIDxjb2RlPnRleHQ8L2NvZGU+IGFyZSBtYWRlIHZpYSB0aGlzIG1ldGhvZC4KICAgICAqCiAgICAgKiA8cD5UaGlzIG1ldGhvZCBhc3N1bWVzIHRoYXQgZnV0dXJlIGNhbGxzIG1heSBiZSBtYWRlIHRoYXQgd2lsbAogICAgICogaW5zZXJ0IG5ldyB0ZXh0IGludG8gdGhlIGJ1ZmZlci4gIEFzIGEgcmVzdWx0LCBpdCBvbmx5IHBlcmZvcm1zCiAgICAgKiB1bmFtYmlndW91cyB0cmFuc2xpdGVyYXRpb25zLiAgQWZ0ZXIgdGhlIGxhc3QgY2FsbCB0byB0aGlzCiAgICAgKiBtZXRob2QsIHRoZXJlIG1heSBiZSB1bnRyYW5zbGl0ZXJhdGVkIHRleHQgdGhhdCBpcyB3YWl0aW5nIGZvcgogICAgICogbW9yZSBpbnB1dCB0byByZXNvbHZlIGFuIGFtYmlndWl0eS4gIEluIG9yZGVyIHRvIHBlcmZvcm0gdGhlc2UKICAgICAqIHBlbmRpbmcgdHJhbnNsaXRlcmF0aW9ucywgY2xpZW50cyBzaG91bGQgY2FsbCB7QGxpbmsKICAgICAqICNmaW5pc2hUcmFuc2xpdGVyYXRpb259IGFmdGVyIHRoZSBsYXN0IGNhbGwgdG8gdGhpcwogICAgICogbWV0aG9kIGhhcyBiZWVuIG1hZGUuCiAgICAgKiAKICAgICAqIEBwYXJhbSB0ZXh0IHRoZSBidWZmZXIgaG9sZGluZyB0cmFuc2xpdGVyYXRlZCBhbmQgdW50cmFuc2xpdGVyYXRlZCB0ZXh0CiAgICAgKiBAcGFyYW0gaW5kZXggYW4gYXJyYXkgb2YgdGhyZWUgaW50ZWdlcnMuCiAgICAgKgogICAgICogPHVsPjxsaT48Y29kZT5pbmRleC5zdGFydDwvY29kZT46IHRoZSBiZWdpbm5pbmcgaW5kZXgsCiAgICAgKiBpbmNsdXNpdmU7IDxjb2RlPjAgPD0gaW5kZXguc3RhcnQgPD0gaW5kZXgubGltaXQ8L2NvZGU+LgogICAgICoKICAgICAqIDxsaT48Y29kZT5pbmRleC5saW1pdDwvY29kZT46IHRoZSBlbmRpbmcgaW5kZXgsIGV4Y2x1c2l2ZTsKICAgICAqIDxjb2RlPmluZGV4LnN0YXJ0IDw9IGluZGV4LmxpbWl0IDw9IHRleHQubGVuZ3RoKCk8L2NvZGU+LgogICAgICogPGNvZGU+aW5zZXJ0aW9uPC9jb2RlPiBpcyBpbnNlcnRlZCBhdAogICAgICogPGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+LgogICAgICoKICAgICAqIDxsaT48Y29kZT5pbmRleC5jdXJzb3I8L2NvZGU+OiB0aGUgbmV4dCBjaGFyYWN0ZXIgdG8gYmUKICAgICAqIGNvbnNpZGVyZWQgZm9yIHRyYW5zbGl0ZXJhdGlvbjsgPGNvZGU+aW5kZXguc3RhcnQgPD0KICAgICAqIGluZGV4LmN1cnNvciA8PSBpbmRleC5saW1pdDwvY29kZT4uICBDaGFyYWN0ZXJzIGJlZm9yZQogICAgICogPGNvZGU+aW5kZXguY3Vyc29yPC9jb2RlPiB3aWxsIG5vdCBiZSBjaGFuZ2VkIGJ5IGZ1dHVyZSBjYWxscwogICAgICogdG8gdGhpcyBtZXRob2QuPC91bD4KICAgICAqCiAgICAgKiBAcGFyYW0gaW5zZXJ0aW9uIHRleHQgdG8gYmUgaW5zZXJ0ZWQgYW5kIHBvc3NpYmx5CiAgICAgKiB0cmFuc2xpdGVyYXRlZCBpbnRvIHRoZSB0cmFuc2xhdGlvbiBidWZmZXIgYXQKICAgICAqIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPi4gIElmIDxjb2RlPm51bGw8L2NvZGU+IHRoZW4gbm8gdGV4dAogICAgICogaXMgaW5zZXJ0ZWQuCiAgICAgKiBAc2VlICNoYW5kbGVUcmFuc2xpdGVyYXRlCiAgICAgKiBAZXhjZXB0aW9uIElsbGVnYWxBcmd1bWVudEV4Y2VwdGlvbiBpZiA8Y29kZT5pbmRleDwvY29kZT4KICAgICAqIGlzIGludmFsaWQKICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgdHJhbnNsaXRlcmF0ZShSZXBsYWNlYWJsZSYgdGV4dCwgVVRyYW5zUG9zaXRpb24mIGluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVW5pY29kZVN0cmluZyYgaW5zZXJ0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgc3RhdHVzKSBjb25zdDsKCiAgICAvKioKICAgICAqIFRyYW5zbGl0ZXJhdGVzIHRoZSBwb3J0aW9uIG9mIHRoZSB0ZXh0IGJ1ZmZlciB0aGF0IGNhbiBiZQogICAgICogdHJhbnNsaXRlcmF0ZWQgdW5hbWJpZ3Vvc2x5IGFmdGVyIGEgbmV3IGNoYXJhY3RlciBoYXMgYmVlbgogICAgICogaW5zZXJ0ZWQsIHR5cGljYWxseSBhcyBhIHJlc3VsdCBvZiBhIGtleWJvYXJkIGV2ZW50LiAgVGhpcyBpcyBhCiAgICAgKiBjb252ZW5pZW5jZSBtZXRob2Q7IHNlZSB7QGxpbmsKICAgICAqICN0cmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlLCBpbnRbXSwgU3RyaW5nKX0gZm9yIGRldGFpbHMuCiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgYnVmZmVyIGhvbGRpbmcgdHJhbnNsaXRlcmF0ZWQgYW5kCiAgICAgKiB1bnRyYW5zbGl0ZXJhdGVkIHRleHQKICAgICAqIEBwYXJhbSBpbmRleCBhbiBhcnJheSBvZiB0aHJlZSBpbnRlZ2Vycy4gIFNlZSB7QGxpbmsKICAgICAqICN0cmFuc2xpdGVyYXRlKFJlcGxhY2VhYmxlLCBpbnRbXSwgU3RyaW5nKX0uCiAgICAgKiBAcGFyYW0gaW5zZXJ0aW9uIHRleHQgdG8gYmUgaW5zZXJ0ZWQgYW5kIHBvc3NpYmx5CiAgICAgKiB0cmFuc2xpdGVyYXRlZCBpbnRvIHRoZSB0cmFuc2xhdGlvbiBidWZmZXIgYXQKICAgICAqIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPi4KICAgICAqIEBzZWUgI3RyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUsIGludFtdLCBTdHJpbmcpCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHRyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUmIHRleHQsIFVUcmFuc1Bvc2l0aW9uJiBpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDaGFyIGluc2VydGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CiAgICAKICAgIC8qKgogICAgICogVHJhbnNsaXRlcmF0ZXMgdGhlIHBvcnRpb24gb2YgdGhlIHRleHQgYnVmZmVyIHRoYXQgY2FuIGJlCiAgICAgKiB0cmFuc2xpdGVyYXRlZCB1bmFtYmlndW9zbHkuICBUaGlzIGlzIGEgY29udmVuaWVuY2UgbWV0aG9kOyBzZWUKICAgICAqIHtAbGluayAjdHJhbnNsaXRlcmF0ZShSZXBsYWNlYWJsZSwgaW50W10sIFN0cmluZyl9IGZvcgogICAgICogZGV0YWlscy4KICAgICAqIEBwYXJhbSB0ZXh0IHRoZSBidWZmZXIgaG9sZGluZyB0cmFuc2xpdGVyYXRlZCBhbmQKICAgICAqIHVudHJhbnNsaXRlcmF0ZWQgdGV4dAogICAgICogQHBhcmFtIGluZGV4IGFuIGFycmF5IG9mIHRocmVlIGludGVnZXJzLiAgU2VlIHtAbGluawogICAgICogI3RyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUsIGludFtdLCBTdHJpbmcpfS4KICAgICAqIEBzZWUgI3RyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUsIGludFtdLCBTdHJpbmcpCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCB2b2lkIHRyYW5zbGl0ZXJhdGUoUmVwbGFjZWFibGUmIHRleHQsIFVUcmFuc1Bvc2l0aW9uJiBpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgY29uc3Q7CgogICAgLyoqCiAgICAgKiBGaW5pc2hlcyBhbnkgcGVuZGluZyB0cmFuc2xpdGVyYXRpb25zIHRoYXQgd2VyZSB3YWl0aW5nIGZvcgogICAgICogbW9yZSBjaGFyYWN0ZXJzLiAgQ2xpZW50cyBzaG91bGQgY2FsbCB0aGlzIG1ldGhvZCBhcyB0aGUgbGFzdAogICAgICogY2FsbCBhZnRlciBhIHNlcXVlbmNlIG9mIG9uZSBvciBtb3JlIGNhbGxzIHRvCiAgICAgKiA8Y29kZT50cmFuc2xpdGVyYXRlKCk8L2NvZGU+LgogICAgICogQHBhcmFtIHRleHQgdGhlIGJ1ZmZlciBob2xkaW5nIHRyYW5zbGl0ZXJhdGVkIGFuZAogICAgICogdW50cmFuc2xpdGVyYXRlZCB0ZXh0LgogICAgICogQHBhcmFtIGluZGV4IHRoZSBhcnJheSBvZiBpbmRpY2VzIHByZXZpb3VzbHkgcGFzc2VkIHRvIHtAbGluawogICAgICogI3RyYW5zbGl0ZXJhdGV9CiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgdmlydHVhbCB2b2lkIGZpbmlzaFRyYW5zbGl0ZXJhdGlvbihSZXBsYWNlYWJsZSYgdGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVRyYW5zUG9zaXRpb24mIGluZGV4KSBjb25zdDsKCnByaXZhdGU6CgogICAgLyoqCiAgICAgKiBUaGlzIGludGVybmFsIG1ldGhvZCBkb2VzIGluY3JlbWVudGFsIHRyYW5zbGl0ZXJhdGlvbi4gIElmIHRoZQogICAgICogJ2luc2VydGlvbicgaXMgbm9uLW51bGwgdGhlbiB3ZSBhcHBlbmQgaXQgdG8gJ3RleHQnIGJlZm9yZQogICAgICogcHJvY2VlZGluZy4gIFRoaXMgbWV0aG9kIGNhbGxzIHRocm91Z2ggdG8gdGhlIHB1cmUgdmlydHVhbAogICAgICogZnJhbWV3b3JrIG1ldGhvZCBoYW5kbGVUcmFuc2xpdGVyYXRlKCkgdG8gZG8gdGhlIGFjdHVhbAogICAgICogd29yay4KICAgICAqLwogICAgdm9pZCBfdHJhbnNsaXRlcmF0ZShSZXBsYWNlYWJsZSYgdGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgVVRyYW5zUG9zaXRpb24mIGluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBVbmljb2RlU3RyaW5nKiBpbnNlcnRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUgJnN0YXR1cykgY29uc3Q7Cgpwcm90ZWN0ZWQ6CgogICAgLyoqCiAgICAgKiBBYnN0cmFjdCBtZXRob2QgdGhhdCBjb25jcmV0ZSBzdWJjbGFzc2VzIGRlZmluZSB0byBpbXBsZW1lbnQKICAgICAqIGtleWJvYXJkIHRyYW5zbGl0ZXJhdGlvbi4gIFRoaXMgbWV0aG9kIHNob3VsZCB0cmFuc2xpdGVyYXRlIGFsbAogICAgICogY2hhcmFjdGVycyBiZXR3ZWVuIDxjb2RlPmluZGV4LmN1cnNvcjwvY29kZT4gYW5kCiAgICAgKiA8Y29kZT5pbmRleC5saW1pdDwvY29kZT4gdGhhdCBjYW4gYmUgdW5hbWJpZ3VvdXNseQogICAgICogdHJhbnNsaXRlcmF0ZWQsIHJlZ2FyZGxlc3Mgb2YgZnV0dXJlIGluc2VydGlvbnMgb2YgdGV4dCBhdAogICAgICogPGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+LiAgPGNvZGU+aW5kZXguY3Vyc29yPC9jb2RlPiBzaG91bGQKICAgICAqIGJlIGFkdmFuY2VkIHBhc3QgY29tbWl0dGVkIGNoYXJhY3RlcnMgKHRob3NlIHRoYXQgd2lsbCBub3QKICAgICAqIGNoYW5nZSBpbiBmdXR1cmUgY2FsbHMgdG8gdGhpcyBtZXRob2QpLgogICAgICogPGNvZGU+aW5kZXgubGltaXQ8L2NvZGU+IHNob3VsZCBiZSB1cGRhdGVkIHRvIHJlZmxlY3QgdGV4dAogICAgICogcmVwbGFjZW1lbnRzIHRoYXQgc2hvcnRlbiBvciBsZW5ndGhlbiB0aGUgdGV4dCBiZXR3ZWVuCiAgICAgKiA8Y29kZT5pbmRleC5jdXJzb3I8L2NvZGU+IGFuZCA8Y29kZT5pbmRleC5saW1pdDwvY29kZT4uICBVcG9uCiAgICAgKiByZXR1cm4sIG5laXRoZXIgPGNvZGU+aW5kZXguY3Vyc29yPC9jb2RlPiBub3IKICAgICAqIDxjb2RlPmluZGV4LmxpbWl0PC9jb2RlPiBzaG91bGQgYmUgbGVzcyB0aGFuIHRoZSBpbml0aWFsIHZhbHVlCiAgICAgKiBvZiA8Y29kZT5pbmRleC5jdXJzb3I8L2NvZGU+LiAgPGNvZGU+aW5kZXguc3RhcnQ8L2NvZGU+CiAgICAgKiBzaG91bGQgPGVtPm5vdDwvZW0+IGJlIGNoYW5nZWQuCiAgICAgKgogICAgICogQHBhcmFtIHRleHQgdGhlIGJ1ZmZlciBob2xkaW5nIHRyYW5zbGl0ZXJhdGVkIGFuZAogICAgICogdW50cmFuc2xpdGVyYXRlZCB0ZXh0CiAgICAgKiBAcGFyYW0gaW5kZXggYW4gYXJyYXkgb2YgdGhyZWUgaW50ZWdlcnMuICBTZWUge0BsaW5rCiAgICAgKiAjdHJhbnNsaXRlcmF0ZShSZXBsYWNlYWJsZSwgaW50W10sIFN0cmluZyl9LgogICAgICogQHNlZSAjdHJhbnNsaXRlcmF0ZQogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgaGFuZGxlVHJhbnNsaXRlcmF0ZShSZXBsYWNlYWJsZSYgdGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVUcmFuc1Bvc2l0aW9uJiBpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVCb29sIGluY3JlbWVudGFsKSBjb25zdCA9IDA7CgogICAgLy8gQysrIHJlcXVpcmVzIHRoaXMgZnJpZW5kIGRlY2xhcmF0aW9uIHNvIENvbXBvdW5kVHJhbnNsaXRlcmF0b3IKICAgIC8vIGNhbiBhY2Nlc3MgaGFuZGxlVHJhbnNsaXRlcmF0ZS4gIEFsdGVybmF0aXZlbHksIHdlIGNvdWxkCiAgICAvLyBtYWtlIGhhbmRsZVRyYW5zbGl0ZXJhdGUgcHVibGljLgogICAgZnJpZW5kIGNsYXNzIENvbXBvdW5kVHJhbnNsaXRlcmF0b3I7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIGxvbmdlc3QgY29udGV4dCByZXF1aXJlZCBieSB0aGlzIHRyYW5zbGl0ZXJhdG9yLgogICAgICogVGhpcyBpcyA8ZW0+cHJlY2VkaW5nPC9lbT4gY29udGV4dC4gIFRoZSBkZWZhdWx0IGltcGxlbWVudGF0aW9uIHN1cHBsaWVkCiAgICAgKiBieSA8Y29kZT5UcmFuc2xpdGVyYXRvcjwvY29kZT4gcmV0dXJucyB6ZXJvOyBzdWJjbGFzc2VzCiAgICAgKiB0aGF0IHVzZSBwcmVjZWRpbmcgY29udGV4dCBzaG91bGQgb3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gcmV0dXJuIHRoZQogICAgICogY29ycmVjdCB2YWx1ZS4gIEZvciBleGFtcGxlLCBpZiBhIHRyYW5zbGl0ZXJhdG9yIHRyYW5zbGF0ZXMgImRkZCIgKHdoZXJlCiAgICAgKiBkIGlzIGFueSBkaWdpdCkgdG8gIjU1NSIgd2hlbiBwcmVjZWRlZCBieSAiKGRkZCkiLCB0aGVuIHRoZSBwcmVjZWRpbmcKICAgICAqIGNvbnRleHQgbGVuZ3RoIGlzIDUsIHRoZSBsZW5ndGggb2YgIihkZGQpIi4KICAgICAqCiAgICAgKiBAcmV0dXJuIFRoZSBtYXhpbXVtIG51bWJlciBvZiBwcmVjZWRpbmcgY29udGV4dCBjaGFyYWN0ZXJzIHRoaXMKICAgICAqIHRyYW5zbGl0ZXJhdG9yIG5lZWRzIHRvIGV4YW1pbmUKICAgICAqIEBkcmFmdAogICAgICovCiAgICBpbnQzMl90IGdldE1heGltdW1Db250ZXh0TGVuZ3RoKHZvaWQpIGNvbnN0OwoKcHJvdGVjdGVkOgoKICAgIC8qKgogICAgICogTWV0aG9kIGZvciBzdWJjbGFzc2VzIHRvIHVzZSB0byBzZXQgdGhlIG1heGltdW0gY29udGV4dCBsZW5ndGguCiAgICAgKiBAc2VlICNnZXRNYXhpbXVtQ29udGV4dExlbmd0aAogICAgICovCiAgICB2b2lkIHNldE1heGltdW1Db250ZXh0TGVuZ3RoKGludDMyX3QgbWF4Q29udGV4dExlbmd0aCk7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIGEgcHJvZ3JhbW1hdGljIGlkZW50aWZpZXIgZm9yIHRoaXMgdHJhbnNsaXRlcmF0b3IuCiAgICAgKiBJZiB0aGlzIGlkZW50aWZpZXIgaXMgcGFzc2VkIHRvIDxjb2RlPmdldEluc3RhbmNlKCk8L2NvZGU+LCBpdAogICAgICogd2lsbCByZXR1cm4gdGhpcyBvYmplY3QsIGlmIGl0IGhhcyBiZWVuIHJlZ2lzdGVyZWQuCiAgICAgKiBAc2VlICNyZWdpc3Rlckluc3RhbmNlCiAgICAgKiBAc2VlICNyZWdpc3RlckNsYXNzCiAgICAgKiBAc2VlICNnZXRBdmFpbGFibGVJRHMKICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGdldElEKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIG5hbWUgZm9yIHRoaXMgdHJhbnNsaXRlcmF0b3IgdGhhdCBpcyBhcHByb3ByaWF0ZSBmb3IKICAgICAqIGRpc3BsYXkgdG8gdGhlIHVzZXIgaW4gdGhlIGRlZmF1bHQgbG9jYWxlLiAgU2VlIHtAbGluawogICAgICogI2dldERpc3BsYXlOYW1lKExvY2FsZSl9IGZvciBkZXRhaWxzLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHN0YXRpYyBVbmljb2RlU3RyaW5nJiBnZXREaXNwbGF5TmFtZShjb25zdCBVbmljb2RlU3RyaW5nJiBJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nJiByZXN1bHQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIG5hbWUgZm9yIHRoaXMgdHJhbnNsaXRlcmF0b3IgdGhhdCBpcyBhcHByb3ByaWF0ZSBmb3IKICAgICAqIGRpc3BsYXkgdG8gdGhlIHVzZXIgaW4gdGhlIGdpdmVuIGxvY2FsZS4gIFRoaXMgbmFtZSBpcyB0YWtlbgogICAgICogZnJvbSB0aGUgbG9jYWxlIHJlc291cmNlIGRhdGEgaW4gdGhlIHN0YW5kYXJkIG1hbm5lciBvZiB0aGUKICAgICAqIDxjb2RlPmphdmEudGV4dDwvY29kZT4gcGFja2FnZS4KICAgICAqCiAgICAgKiA8cD5JZiBubyBsb2NhbGl6ZWQgbmFtZXMgZXhpc3QgaW4gdGhlIHN5c3RlbSByZXNvdXJjZSBidW5kbGVzLAogICAgICogYSBuYW1lIGlzIHN5bnRoZXNpemVkIHVzaW5nIGEgbG9jYWxpemVkCiAgICAgKiA8Y29kZT5NZXNzYWdlRm9ybWF0PC9jb2RlPiBwYXR0ZXJuIGZyb20gdGhlIHJlc291cmNlIGRhdGEuICBUaGUKICAgICAqIGFyZ3VtZW50cyB0byB0aGlzIHBhdHRlcm4gYXJlIGFuIGludGVnZXIgZm9sbG93ZWQgYnkgb25lIG9yIHR3bwogICAgICogc3RyaW5ncy4gIFRoZSBpbnRlZ2VyIGlzIHRoZSBudW1iZXIgb2Ygc3RyaW5ncywgZWl0aGVyIDEgb3IgMi4KICAgICAqIFRoZSBzdHJpbmdzIGFyZSBmb3JtZWQgYnkgc3BsaXR0aW5nIHRoZSBJRCBmb3IgdGhpcwogICAgICogdHJhbnNsaXRlcmF0b3IgYXQgdGhlIGZpcnN0ICctJy4gIElmIHRoZXJlIGlzIG5vICctJywgdGhlbiB0aGUKICAgICAqIGVudGlyZSBJRCBmb3JtcyB0aGUgb25seSBzdHJpbmcuCiAgICAgKiBAcGFyYW0gaW5Mb2NhbGUgdGhlIExvY2FsZSBpbiB3aGljaCB0aGUgZGlzcGxheSBuYW1lIHNob3VsZCBiZQogICAgICogbG9jYWxpemVkLgogICAgICogQHNlZSBqYXZhLnRleHQuTWVzc2FnZUZvcm1hdAogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHN0YXRpYyBVbmljb2RlU3RyaW5nJiBnZXREaXNwbGF5TmFtZShjb25zdCBVbmljb2RlU3RyaW5nJiBJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBMb2NhbGUmIGluTG9jYWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcmIHJlc3VsdCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBmaWx0ZXIgdXNlZCBieSB0aGlzIHRyYW5zbGl0ZXJhdG9yLCBvciA8dHQ+TlVMTDwvdHQ+CiAgICAgKiBpZiB0aGlzIHRyYW5zbGl0ZXJhdG9yIHVzZXMgbm8gZmlsdGVyLgogICAgICogQGRyYWZ0CiAgICAgKi8KICAgIHZpcnR1YWwgY29uc3QgVW5pY29kZUZpbHRlciogZ2V0RmlsdGVyKHZvaWQpIGNvbnN0OwoKICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgZmlsdGVyIHVzZWQgYnkgdGhpcyB0cmFuc2xpdGVyYXRvciwgb3IgPHR0Pk5VTEw8L3R0PiBpZiB0aGlzCiAgICAgKiB0cmFuc2xpdGVyYXRvciB1c2VzIG5vIGZpbHRlci4gIFRoZSBjYWxsZXIgbXVzdCBldmVudHVhbGx5IGRlbGV0ZSB0aGUKICAgICAqIHJlc3VsdC4gIEFmdGVyIHRoaXMgY2FsbCwgdGhpcyB0cmFuc2xpdGVyYXRvcidzIGZpbHRlciBpcyBzZXQgdG8KICAgICAqIDx0dD5OVUxMPC90dD4uICBDYWxscyBhZG9wdEZpbHRlcigpLgogICAgICovCiAgICBVbmljb2RlRmlsdGVyKiBvcnBoYW5GaWx0ZXIodm9pZCk7CgogICAgLyoqCiAgICAgKiBDaGFuZ2VzIHRoZSBmaWx0ZXIgdXNlZCBieSB0aGlzIHRyYW5zbGl0ZXJhdG9yLiAgSWYgdGhlIGZpbHRlcgogICAgICogaXMgc2V0IHRvIDx0dD5udWxsPC90dD4gdGhlbiBubyBmaWx0ZXJpbmcgd2lsbCBvY2N1ci4KICAgICAqCiAgICAgKiA8cD5DYWxsZXJzIG11c3QgdGFrZSBjYXJlIGlmIGEgdHJhbnNsaXRlcmF0b3IgaXMgaW4gdXNlIGJ5CiAgICAgKiBtdWx0aXBsZSB0aHJlYWRzLiAgVGhlIGZpbHRlciBzaG91bGQgbm90IGJlIGNoYW5nZWQgYnkgb25lCiAgICAgKiB0aHJlYWQgd2hpbGUgYW5vdGhlciB0aHJlYWQgbWF5IGJlIHRyYW5zbGl0ZXJhdGluZy4KICAgICAqIEBkcmFmdAogICAgICovCiAgICB2aXJ0dWFsIHZvaWQgYWRvcHRGaWx0ZXIoVW5pY29kZUZpbHRlciogYWRvcHRlZEZpbHRlcik7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoaXMgdHJhbnNsaXRlcmF0b3IncyBpbnZlcnNlLiAgU2VlIHRoZSBjbGFzcwogICAgICogZG9jdW1lbnRhdGlvbiBmb3IgZGV0YWlscy4gIFRoaXMgaW1wbGVtZW50YXRpb24gc2ltcGx5IGludmVydHMKICAgICAqIHRoZSB0d28gZW50aXRpZXMgaW4gdGhlIElEIGFuZCBhdHRlbXB0cyB0byByZXRyaWV2ZSB0aGUKICAgICAqIHJlc3VsdGluZyB0cmFuc2xpdGVyYXRvci4gIFRoYXQgaXMsIGlmIDxjb2RlPmdldElEKCk8L2NvZGU+CiAgICAgKiByZXR1cm5zICJBLUIiLCB0aGVuIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIHRoZSByZXN1bHQgb2YKICAgICAqIDxjb2RlPmdldEluc3RhbmNlKCJCLUEiKTwvY29kZT4sIG9yIDxjb2RlPm51bGw8L2NvZGU+IGlmIHRoYXQKICAgICAqIGNhbGwgZmFpbHMuCiAgICAgKgogICAgICogPHA+VGhpcyBtZXRob2QgZG9lcyBub3QgdGFrZSBmaWx0ZXJpbmcgaW50byBhY2NvdW50LiAgVGhlCiAgICAgKiByZXR1cm5lZCB0cmFuc2xpdGVyYXRvciB3aWxsIGhhdmUgbm8gZmlsdGVyLgogICAgICoKICAgICAqIDxwPlN1YmNsYXNzZXMgd2l0aCBrbm93bGVkZ2Ugb2YgdGhlaXIgaW52ZXJzZSBtYXkgd2lzaCB0bwogICAgICogb3ZlcnJpZGUgdGhpcyBtZXRob2QuCiAgICAgKgogICAgICogQHJldHVybiBhIHRyYW5zbGl0ZXJhdG9yIHRoYXQgaXMgYW4gaW52ZXJzZSwgbm90IG5lY2Vzc2FyaWx5CiAgICAgKiBleGFjdCwgb2YgdGhpcyB0cmFuc2xpdGVyYXRvciwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm8gc3VjaAogICAgICogdHJhbnNsaXRlcmF0b3IgaXMgcmVnaXN0ZXJlZC4KICAgICAqIEBzZWUgI3JlZ2lzdGVySW5zdGFuY2UKICAgICAqIEBkcmFmdAogICAgICovCiAgICBUcmFuc2xpdGVyYXRvciogY3JlYXRlSW52ZXJzZSh2b2lkKSBjb25zdDsKCiAgICAvKioKICAgICAqIFJldHVybnMgYSA8Y29kZT5UcmFuc2xpdGVyYXRvcjwvY29kZT4gb2JqZWN0IGdpdmVuIGl0cyBJRC4KICAgICAqIFRoZSBJRCBtdXN0IGJlIGVpdGhlciBhIHN5c3RlbSB0cmFuc2xpdGVyYXRvciBJRCBvciBhIElEIHJlZ2lzdGVyZWQKICAgICAqIHVzaW5nIDxjb2RlPnJlZ2lzdGVySW5zdGFuY2UoKTwvY29kZT4uCiAgICAgKgogICAgICogQHBhcmFtIElEIGEgdmFsaWQgSUQsIGFzIGVudW1lcmF0ZWQgYnkgPGNvZGU+Z2V0QXZhaWxhYmxlSURzKCk8L2NvZGU+CiAgICAgKiBAcmV0dXJuIEEgPGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+IG9iamVjdCB3aXRoIHRoZSBnaXZlbiBJRAogICAgICogQGV4Y2VwdGlvbiBJbGxlZ2FsQXJndW1lbnRFeGNlcHRpb24gaWYgdGhlIGdpdmVuIElEIGlzIGludmFsaWQuCiAgICAgKiBAc2VlICNyZWdpc3Rlckluc3RhbmNlCiAgICAgKiBAc2VlICNnZXRBdmFpbGFibGVJRHMKICAgICAqIEBzZWUgI2dldElECiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgc3RhdGljIFRyYW5zbGl0ZXJhdG9yKiBjcmVhdGVJbnN0YW5jZShjb25zdCBVbmljb2RlU3RyaW5nJiBJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVRyYW5zRGlyZWN0aW9uIGRpciA9IFVUUkFOU19GT1JXQVJELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVUGFyc2VFcnJvciogcGFyc2VFcnJvciA9IDApOwoKcHJpdmF0ZToKCiAgICAvKioKICAgICAqIFRoaXMgaXMgdGhlIHBhdGggdG8gdGhlIHN1YmRpcmVjdG9yeSB3aXRoaW4gdGhlIGxvY2FsZSBkYXRhCiAgICAgKiBkaXJlY3RvcnkgdGhhdCBjb250YWlucyB0aGUgcnVsZS1iYXNlZCB0cmFuc2xpdGVyYXRvciByZXNvdXJjZQogICAgICogYnVuZGxlIGZpbGVzLiAgVGhpcyBpcyBjb25zdHJ1Y3RlZCBkeW5hbWljYWxseSB0aGUgZmlyc3QgdGltZQogICAgICogVHJhbnNsaXRlcmF0b3I6OmdldERhdGFEaXJlY3RvcnkoKSBpcyBjYWxsZWQuCiAgICAgKi8KICAgIHN0YXRpYyBjaGFyKiBEQVRBX0RJUjsKICAgIAogICAgLyoqCiAgICAgKiBUaGlzIGlzIHRoZSBuYW1lIG9mIGEgc3ViZGlyZWN0b3J5IHdpdGhpbiB0aGUgbG9jYWxlIGRhdGEgZGlyZWN0b3J5CiAgICAgKiB0aGF0IGNvbnRhaW5zIHRoZSBydWxlLWJhc2VkIHRyYW5zbGl0ZXJhdG9yIHJlc291cmNlIGJ1bmRsZSBmaWxlcy4KICAgICAqLwogICAgc3RhdGljIGNvbnN0IGNoYXIqIFJFU09VUkNFX1NVQl9ESVI7CgogICAgLyoqCiAgICAgKiBSZXR1cm5zIHRoZSBkaXJlY3RvcnkgaW4gd2hpY2ggdGhlIHRyYW5zbGl0ZXJhdG9yIHJlc291cmNlIGJ1bmRsZQogICAgICogZmlsZXMgYXJlIGxvY2F0ZWQuICBUaGlzIGlzIGEgc3ViZGlyZWN0b3J5LCBuYW1lZCBSRVNPVVJDRV9TVUJfRElSLAogICAgICogdW5kZXIgTG9jYWxlOjpnZXREYXRhRGlyZWN0b3J5KCkuICBJdCBlbmRzIGluIGEgcGF0aCBzZXBhcmF0b3IuCiAgICAgKi8KICAgIHN0YXRpYyBjb25zdCBjaGFyKiBnZXREYXRhRGlyZWN0b3J5KHZvaWQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhIHRyYW5zbGl0ZXJhdG9yIG9iamVjdCBnaXZlbiBpdHMgSUQuICBVbmxpa2UgZ2V0SW5zdGFuY2UoKSwKICAgICAqIHRoaXMgbWV0aG9kIHJldHVybnMgbnVsbCBpZiBpdCBjYW5ub3QgbWFrZSB1c2Ugb2YgdGhlIGdpdmVuIElELgogICAgICovCiAgICBzdGF0aWMgVHJhbnNsaXRlcmF0b3IqIF9jcmVhdGVJbnN0YW5jZShjb25zdCBVbmljb2RlU3RyaW5nJiBJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVQYXJzZUVycm9yKiBwYXJzZUVycm9yID0gMCk7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBSZWdpc3RlcnMgYSBpbnN0YW5jZSA8dHQ+b2JqPC90dD4gb2YgYSBzdWJjbGFzcyBvZgogICAgICogPGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+IHdpdGggdGhlIHN5c3RlbS4gIFdoZW4KICAgICAqIDx0dD5jcmVhdGVJbnN0YW5jZSgpPC90dD4gaXMgY2FsbGVkIHdpdGggYW4gSUQgc3RyaW5nIHRoYXQgaXMKICAgICAqIGVxdWFsIHRvIDx0dD5vYmotPmdldElEKCk8L3R0PiwgdGhlbiA8dHQ+b2JqLT5jbG9uZSgpPC90dD4gaXMKICAgICAqIHJldHVybmVkLgogICAgICoKICAgICAqIEFmdGVyIHRoaXMgY2FsbCB0aGUgVHJhbnNsaXRlcmF0b3IgY2xhc3Mgb3ducyB0aGUgYWRvcHRlZE9iagogICAgICogYW5kIHdpbGwgZGVsZXRlIGl0LgogICAgICoKICAgICAqIEBwYXJhbSBvYmogYW4gaW5zdGFuY2Ugb2Ygc3ViY2xhc3Mgb2YKICAgICAqIDxjb2RlPlRyYW5zbGl0ZXJhdG9yPC9jb2RlPiB0aGF0IGRlZmluZXMgPHR0PmNsb25lKCk8L3R0PgogICAgICogQHNlZSAjZ2V0SW5zdGFuY2UKICAgICAqIEBzZWUgI3JlZ2lzdGVyQ2xhc3MKICAgICAqIEBzZWUgI3VucmVnaXN0ZXIKICAgICAqIEBkcmFmdAogICAgICovCiAgICBzdGF0aWMgdm9pZCByZWdpc3Rlckluc3RhbmNlKFRyYW5zbGl0ZXJhdG9yKiBhZG9wdGVkT2JqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpOwoKcHJpdmF0ZToKCiAgICAvKioKICAgICAqIFRoaXMgaW50ZXJuYWwgbWV0aG9kIHJlZ2lzdGVycyBhIHByb3RvdHlwZSBpbnN0YW5jZSBpbiB0aGUgY2FjaGUuCiAgICAgKiBUaGUgQ0FMTEVSIE1VU1QgTVVURVggdXNpbmcgY2FjaGVNdXRleCBiZWZvcmUgY2FsbGluZyB0aGlzIG1ldGhvZC4KICAgICAqLwogICAgc3RhdGljIHZvaWQgX3JlZ2lzdGVySW5zdGFuY2UoVHJhbnNsaXRlcmF0b3IqIGFkb3B0ZWRQcm90b3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpOwoKcHVibGljOgoKICAgIC8qKgogICAgICogVW5yZWdpc3RlcnMgYSB0cmFuc2xpdGVyYXRvciBvciBjbGFzcy4gIFRoaXMgbWF5IGJlIGVpdGhlcgogICAgICogYSBzeXN0ZW0gdHJhbnNsaXRlcmF0b3Igb3IgYSB1c2VyIHRyYW5zbGl0ZXJhdG9yIG9yIGNsYXNzLgogICAgICogCiAgICAgKiBAcGFyYW0gSUQgdGhlIElEIG9mIHRoZSB0cmFuc2xpdGVyYXRvciBvciBjbGFzcwogICAgICogQHJldHVybiB0aGUgPGNvZGU+T2JqZWN0PC9jb2RlPiB0aGF0IHdhcyByZWdpc3RlcmVkIHdpdGgKICAgICAqIDxjb2RlPklEPC9jb2RlPiwgb3IgPGNvZGU+bnVsbDwvY29kZT4gaWYgbm9uZSB3YXMKICAgICAqIEBzZWUgI3JlZ2lzdGVySW5zdGFuY2UKICAgICAqIEBzZWUgI3JlZ2lzdGVyQ2xhc3MKICAgICAqIEBkcmFmdAogICAgICovCiAgICBzdGF0aWMgdm9pZCB1bnJlZ2lzdGVyKGNvbnN0IFVuaWNvZGVTdHJpbmcmIElEKTsKCnByaXZhdGU6CgogICAgLyoqCiAgICAgKiBVbnJlZ2lzdGVycyBhIHRyYW5zbGl0ZXJhdG9yIG9yIGNsYXNzLiAgSW50ZXJuYWwgbWV0aG9kLgogICAgICogUHJlcmVxdWlzaXRlczogVGhlIGNhY2hlIG11c3QgYmUgaW5pdGlhbGl6ZWQsIGFuZCB0aGUKICAgICAqIGNhbGxlciBtdXN0IG93biB0aGUgY2FjaGVNdXRleC4KICAgICAqLwogICAgc3RhdGljIHZvaWQgX3VucmVnaXN0ZXIoY29uc3QgVW5pY29kZVN0cmluZyYgSUQpOwoKICAgIC8qKgogICAgICogUmV0dXJucyBhbiBlbnVtZXJhdGlvbiBvdmVyIHRoZSBwcm9ncmFtbWF0aWMgbmFtZXMgb2YgcmVnaXN0ZXJlZAogICAgICogPGNvZGU+VHJhbnNsaXRlcmF0b3I8L2NvZGU+IG9iamVjdHMuICBUaGlzIGluY2x1ZGVzIGJvdGggc3lzdGVtCiAgICAgKiB0cmFuc2xpdGVyYXRvcnMgYW5kIHVzZXIgdHJhbnNsaXRlcmF0b3JzIHJlZ2lzdGVyZWQgdXNpbmcKICAgICAqIDxjb2RlPnJlZ2lzdGVySW5zdGFuY2UoKTwvY29kZT4uICBUaGUgZW51bWVyYXRlZCBuYW1lcyBtYXkgYmUKICAgICAqIHBhc3NlZCB0byA8Y29kZT5nZXRJbnN0YW5jZSgpPC9jb2RlPi4KICAgICAqCiAgICAgKiBAcmV0dXJuIEFuIDxjb2RlPkVudW1lcmF0aW9uPC9jb2RlPiBvdmVyIDxjb2RlPlN0cmluZzwvY29kZT4gb2JqZWN0cwogICAgICogQHNlZSAjZ2V0SW5zdGFuY2UKICAgICAqIEBzZWUgI3JlZ2lzdGVySW5zdGFuY2UKICAgICAqLwogICAgLy8gdmlydHVhbCBFbnVtZXJhdGlvbiBnZXRBdmFpbGFibGVJRHMoKTsKCiAgICAvKioKICAgICAqIFZlY3RvciBvZiByZWdpc3RlcmVkIElEcy4KICAgICAqLwogICAgc3RhdGljIFVWZWN0b3IgY2FjaGVJRHM7CgpwdWJsaWM6CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIG51bWJlciBvZiBJRHMgY3VycmVudGx5IHJlZ2lzdGVyZWQgd2l0aCB0aGUgc3lzdGVtLgogICAgICogVG8gcmV0cmlldmUgdGhlIGFjdHVhbCBJRHMsIGNhbGwgZ2V0QXZhaWxhYmxlSUQoaSkgd2l0aAogICAgICogaSBmcm9tIDAgdG8gY291bnRBdmFpbGFibGVJRHMoKSAtIDEuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgc3RhdGljIGludDMyX3QgY291bnRBdmFpbGFibGVJRHModm9pZCk7CgogICAgLyoqCiAgICAgKiBSZXR1cm4gdGhlIGluZGV4LXRoIGF2YWlsYWJsZSBJRC4gIGluZGV4IG11c3QgYmUgYmV0d2VlbiAwCiAgICAgKiBhbmQgY291bnRBdmFpbGFibGVJRHMoKSAtIDEsIGluY2x1c2l2ZS4gIElmIGluZGV4IGlzIG91dCBvZgogICAgICogcmFuZ2UsIHRoZSByZXN1bHQgb2YgZ2V0QXZhaWxhYmxlSUQoMCkgaXMgcmV0dXJuZWQuCiAgICAgKiBAZHJhZnQKICAgICAqLwogICAgc3RhdGljIGNvbnN0IFVuaWNvZGVTdHJpbmcmIGdldEF2YWlsYWJsZUlEKGludDMyX3QgaW5kZXgpOwoKcHJvdGVjdGVkOgoKICAgIC8qKgogICAgICogTWV0aG9kIGZvciBzdWJjbGFzc2VzIHRvIHVzZSB0byBvYnRhaW4gYSBjaGFyYWN0ZXIgaW4gdGhlIGdpdmVuCiAgICAgKiBzdHJpbmcsIHdpdGggZmlsdGVyaW5nLgogICAgICovCiAgICBVQ2hhciBmaWx0ZXJlZENoYXJBdChjb25zdCBSZXBsYWNlYWJsZSYgdGV4dCwgaW50MzJfdCBpKSBjb25zdDsKCiAgICAvKioKICAgICAqIFNldCB0aGUgSUQgb2YgdGhpcyB0cmFuc2xpdGVyYXRvcnMuICBTdWJjbGFzc2VzIHNob3VsZG4ndCBkbwogICAgICogdGhpcywgdW5sZXNzIHRoZSB1bmRlcmx5aW5nIHNjcmlwdCBiZWhhdmlvciBoYXMgY2hhbmdlZC4KICAgICAqLwogICAgdm9pZCBzZXRJRChjb25zdCBVbmljb2RlU3RyaW5nJiBpZCk7Cgpwcml2YXRlOgogICAgLyoqCiAgICAgKiBDb21wYXJpc29uIGZ1bmN0aW9uIGZvciBVVmVjdG9yLiAgQ29tcGFyZXMgdHdvIFVuaWNvZGVTdHJpbmcKICAgICAqIG9iamVjdHMgZ2l2ZW4gdm9pZCogcG9pbnRlcnMgdG8gdGhlbS4KICAgICAqLwogICAgc3RhdGljIFVCb29sIGNvbXBhcmVJRHModm9pZCogYSwgdm9pZCogYik7CgogICAgc3RhdGljIHZvaWQgaW5pdGlhbGl6ZUNhY2hlKHZvaWQpOwoKICAgIC8qIElEcyB0YWtlIHRoZSBmb3JtIDxzb3VyY2U+IElEX1NFUCA8dGFyZ2V0Piwgd2hlcmUKICAgICAqIDxzb3VyY2U+IGFuZCA8dGFyZ2V0PiBhcmUgKHVzdWFsbHkpIHNjcmlwdCBuYW1lcy4KICAgICAqIENvbXBvdW5kIElEcyB0YWtlIHRoZSBmb3JtIDxJRD4gKCBJRF9ERUxJTSA8SUQ+ICkrLgogICAgICovCiAgICBzdGF0aWMgY29uc3QgVUNoYXIgSURfU0VQOyAgIC8vICgoVUNoYXIpMHgwMDJEKSAvKi0qLwogICAgc3RhdGljIGNvbnN0IFVDaGFyIElEX0RFTElNOyAvLyAoKFVDaGFyKTB4MDAzQikgLyo7Ki8KfTsKCmlubGluZSBpbnQzMl90IFRyYW5zbGl0ZXJhdG9yOjpnZXRNYXhpbXVtQ29udGV4dExlbmd0aCh2b2lkKSBjb25zdCB7CiAgICByZXR1cm4gbWF4aW11bUNvbnRleHRMZW5ndGg7Cn0KCmlubGluZSB2b2lkIFRyYW5zbGl0ZXJhdG9yOjpzZXRJRChjb25zdCBVbmljb2RlU3RyaW5nJiBpZCkgewogICAgSUQgPSBpZDsKfQoKI2VuZGlmCg==