LyoKICogTGljZW5zZWQgdG8gdGhlIEFwYWNoZSBTb2Z0d2FyZSBGb3VuZGF0aW9uIChBU0YpIHVuZGVyIG9uZSBvciBtb3JlCiAqIGNvbnRyaWJ1dG9yIGxpY2Vuc2UgYWdyZWVtZW50cy4gIFNlZSB0aGUgTk9USUNFIGZpbGUgZGlzdHJpYnV0ZWQgd2l0aAogKiB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIGNvcHlyaWdodCBvd25lcnNoaXAuCiAqIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlIHRvIFlvdSB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wCiAqICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoCiAqIHRoZSBMaWNlbnNlLiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqIAogKiAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAogKiAKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICovCgovKgogKiAkSWQkCiAqLwoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICBJbmNsdWRlcwovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KI2luY2x1ZGUgPHhlcmNlc2MvdXRpbC9YTUxGbG9hdC5ocHA+CiNpbmNsdWRlIDxtYXRoLmg+CgpYRVJDRVNfQ1BQX05BTUVTUEFDRV9CRUdJTgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICBjdG9yL2R0b3IKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClhNTEZsb2F0OjpYTUxGbG9hdChjb25zdCBYTUxDaCogY29uc3Qgc3RyVmFsdWUsCiAgICAgICAgICAgICAgICAgICBNZW1vcnlNYW5hZ2VyKiBjb25zdCBtYW5hZ2VyKQo6WE1MQWJzdHJhY3REb3VibGVGbG9hdChtYW5hZ2VyKQp7CiAgICBpbml0KHN0clZhbHVlKTsKfQoKWE1MRmxvYXQ6On5YTUxGbG9hdCgpCnsKfQoKdm9pZCBYTUxGbG9hdDo6Y2hlY2tCb3VuZGFyeShjaGFyKiBjb25zdCBzdHJWYWx1ZSkKewogICAgY29udmVydChzdHJWYWx1ZSk7CgogICAgaWYgKGZEYXRhQ29udmVydGVkID09IGZhbHNlKQogICAgewogICAgICAgIC8qKgogICAgICAgICAqICBmbG9hdCByZWxhdGVkIGNoZWNraW5nCiAgICAgICAgICovCgogICAgICAgIC8vIDMuMi40IFRoZSBiYXNpYyB2YWx1ZSBzcGFjZSBvZiBmbG9hdCBjb25zaXN0cyBvZiB0aGUgdmFsdWVzIG0g1yAyXmUsIHdoZXJlIAogICAgICAgIC8vICAgIG0gaXMgYW4gaW50ZWdlciB3aG9zZSBhYnNvbHV0ZSB2YWx1ZSBpcyBsZXNzIHRoYW4gMl4yNCwgCiAgICAgICAgLy8gICAgYW5kIGUgaXMgYW4gaW50ZWdlciBiZXR3ZWVuIC0xNDkgYW5kIDEwNCwgaW5jbHVzaXZlCiAgICAgICAgc3RhdGljIGNvbnN0IGRvdWJsZSBmbHRNaW4gPSBwb3coMi4wLC0xNDkpOwogICAgICAgIHN0YXRpYyBjb25zdCBkb3VibGUgZmx0TWF4ID0gcG93KDIuMCwyNCkgKiBwb3coMi4wLDEwNCk7CiAgICAgICAgaWYgKGZWYWx1ZSA8ICgtMSkgKiBmbHRNYXgpCiAgICAgICAgewogICAgICAgICAgICBmVHlwZSA9IE5lZ0lORjsKICAgICAgICAgICAgZkRhdGFDb252ZXJ0ZWQgPSB0cnVlOwogICAgICAgICAgICBmRGF0YU92ZXJmbG93ZWQgPSB0cnVlOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChmVmFsdWUgPiAoLTEpKmZsdE1pbiAmJiBmVmFsdWUgPCAwKQogICAgICAgIHsKICAgICAgICAgICAgZkRhdGFDb252ZXJ0ZWQgPSB0cnVlOwogICAgICAgICAgICBmVmFsdWUgPSAwOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChmVmFsdWUgPiAwICYmIGZWYWx1ZSA8IGZsdE1pbiApCiAgICAgICAgewogICAgICAgICAgICBmRGF0YUNvbnZlcnRlZCA9IHRydWU7CiAgICAgICAgICAgIGZWYWx1ZSA9IDA7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgIChmVmFsdWUgPiBmbHRNYXgpCiAgICAgICAgewogICAgICAgICAgICBmVHlwZSA9IFBvc0lORjsKICAgICAgICAgICAgZkRhdGFDb252ZXJ0ZWQgPSB0cnVlOwogICAgICAgICAgICBmRGF0YU92ZXJmbG93ZWQgPSB0cnVlOwogICAgICAgIH0KICAgIH0KfQoKLyoqKgogKiBTdXBwb3J0IGZvciBTZXJpYWxpemF0aW9uL0RlLXNlcmlhbGl6YXRpb24KICoqKi8KCklNUExfWFNFUklBTElaQUJMRV9UT0NSRUFURShYTUxGbG9hdCkKClhNTEZsb2F0OjpYTUxGbG9hdChNZW1vcnlNYW5hZ2VyKiBjb25zdCBtYW5hZ2VyKQo6WE1MQWJzdHJhY3REb3VibGVGbG9hdChtYW5hZ2VyKQp7Cn0KCnZvaWQgWE1MRmxvYXQ6OnNlcmlhbGl6ZShYU2VyaWFsaXplRW5naW5lJiBzZXJFbmcpCnsKICAgIFhNTEFic3RyYWN0RG91YmxlRmxvYXQ6OnNlcmlhbGl6ZShzZXJFbmcpOwp9CgpYRVJDRVNfQ1BQX05BTUVTUEFDRV9FTkQK