LyoKICogKGMpIENvcHlyaWdodCAxOTkzLCBTaWxpY29uIEdyYXBoaWNzLCBJbmMuCiAqIENvcHlyaWdodCCpIDIwMTIgTGluYXJvIExpbWl0ZWQKICoKICogVGhpcyBmaWxlIGlzIHBhcnQgb2YgdGhlIGdsbWFyazIgT3BlbkdMIChFUykgMi4wIGJlbmNobWFyay4KICoKICogZ2xtYXJrMiBpcyBmcmVlIHNvZnR3YXJlOiB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0IHVuZGVyIHRoZQogKiB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyCiAqIHZlcnNpb24uCiAqCiAqIGdsbWFyazIgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwgYnV0IFdJVEhPVVQgQU5ZCiAqIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MKICogRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZQogKiBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhbG9uZyB3aXRoCiAqIGdsbWFyazIuICBJZiBub3QsIHNlZSA8aHR0cDovL3d3dy5nbnUub3JnL2xpY2Vuc2VzLz4uCiAqCiAqIEF1dGhvcnM6CiAqICBKZXNzZSBCYXJrZXIKICovCiNpZm5kZWYgQ0hBUkFDVEVSU19IXwojZGVmaW5lIENIQVJBQ1RFUlNfSF8KCiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlICJ2ZWMuaCIKI2luY2x1ZGUgImdsLWhlYWRlcnMuaCIKCmNsYXNzIFByaW1pdGl2ZVN0YXRlCnsKcHVibGljOgogICAgUHJpbWl0aXZlU3RhdGUodW5zaWduZWQgaW50IHR5cGUsIHVuc2lnbmVkIGludCBjb3VudCwgdW5zaWduZWQgaW50IG9mZnNldCkgOgogICAgICAgIHR5cGVfKHR5cGUpLAogICAgICAgIGNvdW50Xyhjb3VudCksCiAgICAgICAgYnVmZmVyT2Zmc2V0XyhvZmZzZXQpIHt9CiAgICB+UHJpbWl0aXZlU3RhdGUoKSB7fQogICAgdm9pZCBpc3N1ZSgpIGNvbnN0CiAgICB7CiAgICAgICAgZ2xEcmF3RWxlbWVudHModHlwZV8sIGNvdW50XywgR0xfVU5TSUdORURfU0hPUlQsIAogICAgICAgICAgICByZWludGVycHJldF9jYXN0PGNvbnN0IEdMdm9pZCo+KGJ1ZmZlck9mZnNldF8pKTsKICAgIH0KcHJpdmF0ZToKICAgIFByaW1pdGl2ZVN0YXRlKCk7CiAgICB1bnNpZ25lZCBpbnQgdHlwZV87ICAgICAgICAgLy8gUHJpbWl0aXZlIHR5cGUgKGUuZy4gR0xfVFJJQU5HTEVfU1RSSVApCiAgICB1bnNpZ25lZCBpbnQgY291bnRfOyAgICAgICAgLy8gTnVtYmVyIG9mIHByaW1pdGl2ZXMKICAgIHVuc2lnbmVkIGludCBidWZmZXJPZmZzZXRfOyAvLyBPZmZzZXQgaW50byB0aGUgZWxlbWVudCBhcnJheSBidWZmZXIKfTsKCnN0cnVjdCBDaGFyYWN0ZXIKewogICAgdm9pZCBkcmF3KCkKICAgIHsKICAgICAgICBnbEJpbmRCdWZmZXIoR0xfQVJSQVlfQlVGRkVSLCBidWZmZXJPYmplY3RzX1swXSk7CiAgICAgICAgZ2xCaW5kQnVmZmVyKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCBidWZmZXJPYmplY3RzX1sxXSk7CiAgICAgICAgZ2xWZXJ0ZXhBdHRyaWJQb2ludGVyKHZlcnRleEluZGV4XywgMiwgR0xfRkxPQVQsIEdMX0ZBTFNFLCAwLCAwKTsKICAgICAgICBnbEVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHZlcnRleEluZGV4Xyk7CiAgICAgICAgZm9yIChzdGQ6OnZlY3RvcjxQcmltaXRpdmVTdGF0ZT46OmNvbnN0X2l0ZXJhdG9yIHByaW1JdCA9IHByaW1WZWNfLmJlZ2luKCk7CiAgICAgICAgICAgICBwcmltSXQgIT0gcHJpbVZlY18uZW5kKCk7CiAgICAgICAgICAgICBwcmltSXQrKykKICAgICAgICB7CiAgICAgICAgICAgIHByaW1JdC0+aXNzdWUoKTsKICAgICAgICB9CiAgICAgICAgZ2xCaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgMCk7CiAgICAgICAgZ2xCaW5kQnVmZmVyKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCAwKTsKICAgIH0KICAgIHZvaWQgaW5pdChpbnQgdmVydGV4QXR0cmliSW5kZXgpIAogICAgewogICAgICAgIHZlcnRleEluZGV4XyA9IHZlcnRleEF0dHJpYkluZGV4OwoKICAgICAgICAvLyBXZSBuZWVkIDIgYnVmZmVycyBmb3Igb3VyIHdvcmsgaGVyZS4gIE9uZSBmb3IgdGhlIHZlcnRleCBkYXRhLgogICAgICAgIC8vIGFuZCBvbmUgZm9yIHRoZSBpbmRleCBkYXRhLgogICAgICAgIGdsR2VuQnVmZmVycygyLCAmYnVmZmVyT2JqZWN0c19bMF0pOwoKICAgICAgICAvLyBGaXJzdCwgc2V0dXAgdGhlIHZlcnRleCBkYXRhIGJ5IGJpbmRpbmcgdGhlIGZpcnN0IGJ1ZmZlciBvYmplY3QsIAogICAgICAgIC8vIGFsbG9jYXRpbmcgaXRzIGRhdGEgc3RvcmUsIGFuZCBmaWxsaW5nIGl0IGluIHdpdGggb3VyIHZlcnRleCBkYXRhLgogICAgICAgIGdsQmluZEJ1ZmZlcihHTF9BUlJBWV9CVUZGRVIsIGJ1ZmZlck9iamVjdHNfWzBdKTsKICAgICAgICBnbEJ1ZmZlckRhdGEoR0xfQVJSQVlfQlVGRkVSLCB2ZXJ0ZXhEYXRhXy5zaXplKCkgKiBzaXplb2YoTGliTWF0cml4Ojp2ZWMyKSwgCiAgICAgICAgICAgICZ2ZXJ0ZXhEYXRhXy5mcm9udCgpLCBHTF9TVEFUSUNfRFJBVyk7CgogICAgICAgIC8vIEZpbmFsbHksIHNldHVwIHRoZSBwb2ludGVyIHRvIG91ciB2ZXJ0ZXggZGF0YSBhbmQgZW5hYmxlIHRoaXMKICAgICAgICAvLyBhdHRyaWJ1dGUgYXJyYXkuCiAgICAgICAgZ2xWZXJ0ZXhBdHRyaWJQb2ludGVyKHZlcnRleEluZGV4XywgMiwgR0xfRkxPQVQsIEdMX0ZBTFNFLCAwLCAwKTsKICAgICAgICBnbEVuYWJsZVZlcnRleEF0dHJpYkFycmF5KHZlcnRleEluZGV4Xyk7CgogICAgICAgIC8vIE5vdyByZXBlYXQgZm9yIG91ciBpbmRleCBkYXRhLgogICAgICAgIGdsQmluZEJ1ZmZlcihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgYnVmZmVyT2JqZWN0c19bMV0pOwogICAgICAgIGdsQnVmZmVyRGF0YShHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUiwgCiAgICAgICAgICAgIGluZGV4RGF0YV8uc2l6ZSgpICogc2l6ZW9mKHVuc2lnbmVkIHNob3J0KSwgJmluZGV4RGF0YV8uZnJvbnQoKSwgCiAgICAgICAgICAgIEdMX1NUQVRJQ19EUkFXKTsKCiAgICAgICAgLy8gVW5iaW5kIG91ciB2ZXJ0ZXggYnVmZmVyIG9iamVjdHMgc28gdGhhdCB0aGVpciBzdGF0ZSBpc24ndCBhZmZlY3RlZAogICAgICAgIC8vIGJ5IG90aGVyIG9iamVjdHMuCiAgICAgICAgZ2xCaW5kQnVmZmVyKEdMX0FSUkFZX0JVRkZFUiwgMCk7CiAgICAgICAgZ2xCaW5kQnVmZmVyKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSLCAwKTsKICAgIH0KICAgIH5DaGFyYWN0ZXIoKQogICAgewogICAgICAgIGdsRGVsZXRlQnVmZmVycygyLCAmYnVmZmVyT2JqZWN0c19bMF0pOwogICAgfQogICAgQ2hhcmFjdGVyKCkgOgogICAgICAgIHZlcnRleEluZGV4XygwKSwKICAgICAgICB2ZXJ0ZXhBcnJheV8oMCkge30KICAgIHVuc2lnbmVkIGludCBidWZmZXJPYmplY3RzX1syXTsKICAgIHN0ZDo6dmVjdG9yPExpYk1hdHJpeDo6dmVjMj4gdmVydGV4RGF0YV87CiAgICBzdGQ6OnZlY3Rvcjx1bnNpZ25lZCBzaG9ydD4gaW5kZXhEYXRhXzsKICAgIGludCB2ZXJ0ZXhJbmRleF87CiAgICB1bnNpZ25lZCBpbnQgdmVydGV4QXJyYXlfOwogICAgc3RkOjp2ZWN0b3I8UHJpbWl0aXZlU3RhdGU+IHByaW1WZWNfOwp9OwoKc3RydWN0IExldHRlckkgOiBDaGFyYWN0ZXIKewogICAgTGV0dGVySSgpOwp9OwoKc3RydWN0IExldHRlckQgOiBDaGFyYWN0ZXIKewogICAgTGV0dGVyRCgpOwp9OwoKc3RydWN0IExldHRlckUgOiBDaGFyYWN0ZXIKewogICAgTGV0dGVyRSgpOwp9OwoKc3RydWN0IExldHRlckEgOiBDaGFyYWN0ZXIKewogICAgTGV0dGVyQSgpOwp9OwoKc3RydWN0IExldHRlclMgOiBDaGFyYWN0ZXIKewogICAgTGV0dGVyUygpOwp9OwoKc3RydWN0IExldHRlck4gOiBDaGFyYWN0ZXIKewogICAgTGV0dGVyTigpOwp9OwoKc3RydWN0IExldHRlck0gOiBDaGFyYWN0ZXIKewogICAgTGV0dGVyTSgpOwp9OwoKc3RydWN0IExldHRlck8gOiBDaGFyYWN0ZXIKewogICAgTGV0dGVyTygpOwp9OwoKc3RydWN0IExldHRlclQgOiBDaGFyYWN0ZXIKewogICAgTGV0dGVyVCgpOwp9OwoKI2VuZGlmIC8vIENIQVJBQ1RFUlNfSF8K