LyohIFxmaWxlIGdpbV9ib3hfc2V0LmgKXGF1dGhvciBGcmFuY2lzY28gTGV/biBO32plcmEKKi8KLyoKVGhpcyBzb3VyY2UgZmlsZSBpcyBwYXJ0IG9mIEdJTVBBQ1QgTGlicmFyeS4KCkZvciB0aGUgbGF0ZXN0IGluZm8sIHNlZSBodHRwOi8vZ2ltcGFjdC5zb3VyY2Vmb3JnZS5uZXQvCgpDb3B5cmlnaHQgKGMpIDIwMDcgRnJhbmNpc2NvIExlb24gTmFqZXJhLiBDLkMuIDgwMDg3MzcxLgplbWFpbDogcHJvamVjdGlsZW1hbkB5YWhvby5jb20KCgpUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMgYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCmluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXQgZnJlZWx5LApzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOgoKMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3QgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuCjIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4KMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KKi8KCiNpbmNsdWRlICJCdWxsZXRDb2xsaXNpb24vR2ltcGFjdC9idEdJbXBhY3RRdWFudGl6ZWRCdmguaCIKI2luY2x1ZGUgIkxpbmVhck1hdGgvYnRRdWlja3Byb2YuaCIKCiNpZmRlZiBUUklfQ09MTElTSU9OX1BST0ZJTElORwpidENsb2NrIGdfcV90cmVlX2Nsb2NrOwoKCmZsb2F0IGdfcV9hY2N1bV90cmVlX2NvbGxpc2lvbl90aW1lID0gMDsKaW50IGdfcV9jb3VudF90cmF2ZXJzaW5nID0gMDsKCgp2b2lkIGJ0X2JlZ2luX2dpbTAyX3FfdHJlZV90aW1lKCkKewoJZ19xX3RyZWVfY2xvY2sucmVzZXQoKTsKfQoKdm9pZCBidF9lbmRfZ2ltMDJfcV90cmVlX3RpbWUoKQp7CglnX3FfYWNjdW1fdHJlZV9jb2xsaXNpb25fdGltZSArPSBnX3FfdHJlZV9jbG9jay5nZXRUaW1lTWljcm9zZWNvbmRzKCk7CglnX3FfY291bnRfdHJhdmVyc2luZysrOwp9CgoKLy8hIEdldHMgdGhlIGF2ZXJhZ2UgdGltZSBpbiBtaWxpc2Vjb25kcyBvZiB0cmVlIGNvbGxpc2lvbnMKZmxvYXQgYnRHSW1wYWN0UXVhbnRpemVkQnZoOjpnZXRBdmVyYWdlVHJlZUNvbGxpc2lvblRpbWUoKQp7CglpZihnX3FfY291bnRfdHJhdmVyc2luZyA9PSAwKSByZXR1cm4gMDsKCglmbG9hdCBhdmd0aW1lID0gZ19xX2FjY3VtX3RyZWVfY29sbGlzaW9uX3RpbWU7Cglhdmd0aW1lIC89IChmbG9hdClnX3FfY291bnRfdHJhdmVyc2luZzsKCglnX3FfYWNjdW1fdHJlZV9jb2xsaXNpb25fdGltZSA9IDA7CglnX3FfY291bnRfdHJhdmVyc2luZyA9IDA7CglyZXR1cm4gYXZndGltZTsKCi8vCWZsb2F0IGF2Z3RpbWUgPSBnX3FfY291bnRfdHJhdmVyc2luZzsKLy8JZ19xX2NvdW50X3RyYXZlcnNpbmcgPSAwOwovLwlyZXR1cm4gYXZndGltZTsKCn0KCiNlbmRpZiAvL1RSSV9DT0xMSVNJT05fUFJPRklMSU5HCgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLyBidFF1YW50aXplZEJ2aFRyZWUgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgp2b2lkIGJ0UXVhbnRpemVkQnZoVHJlZTo6Y2FsY19xdWFudGl6YXRpb24oCglHSU1fQlZIX0RBVEFfQVJSQVkgJiBwcmltaXRpdmVfYm94ZXMsIGJ0U2NhbGFyIGJvdW5kTWFyZ2luKQp7CgkvL2NhbGMgZ2xvYmEgYm94CglidEFBQkIgZ2xvYmFsX2JvdW5kOwoJZ2xvYmFsX2JvdW5kLmludmFsaWRhdGUoKTsKCglmb3IgKGludCBpPTA7aTxwcmltaXRpdmVfYm94ZXMuc2l6ZSgpIDtpKysgKQoJewoJCWdsb2JhbF9ib3VuZC5tZXJnZShwcmltaXRpdmVfYm94ZXNbaV0ubV9ib3VuZCk7Cgl9CgoJYnRfY2FsY19xdWFudGl6YXRpb25fcGFyYW1ldGVycygKCQltX2dsb2JhbF9ib3VuZC5tX21pbixtX2dsb2JhbF9ib3VuZC5tX21heCxtX2J2aFF1YW50aXphdGlvbixnbG9iYWxfYm91bmQubV9taW4sZ2xvYmFsX2JvdW5kLm1fbWF4LGJvdW5kTWFyZ2luKTsKCn0KCgoKaW50IGJ0UXVhbnRpemVkQnZoVHJlZTo6X2NhbGNfc3BsaXR0aW5nX2F4aXMoCglHSU1fQlZIX0RBVEFfQVJSQVkgJiBwcmltaXRpdmVfYm94ZXMsIGludCBzdGFydEluZGV4LCAgaW50IGVuZEluZGV4KQp7CgoJaW50IGk7CgoJYnRWZWN0b3IzIG1lYW5zKGJ0U2NhbGFyKDAuKSxidFNjYWxhcigwLiksYnRTY2FsYXIoMC4pKTsKCWJ0VmVjdG9yMyB2YXJpYW5jZShidFNjYWxhcigwLiksYnRTY2FsYXIoMC4pLGJ0U2NhbGFyKDAuKSk7CglpbnQgbnVtSW5kaWNlcyA9IGVuZEluZGV4LXN0YXJ0SW5kZXg7CgoJZm9yIChpPXN0YXJ0SW5kZXg7aTxlbmRJbmRleDtpKyspCgl7CgkJYnRWZWN0b3IzIGNlbnRlciA9IGJ0U2NhbGFyKDAuNSkqKHByaW1pdGl2ZV9ib3hlc1tpXS5tX2JvdW5kLm1fbWF4ICsKCQkJCQkgcHJpbWl0aXZlX2JveGVzW2ldLm1fYm91bmQubV9taW4pOwoJCW1lYW5zKz1jZW50ZXI7Cgl9CgltZWFucyAqPSAoYnRTY2FsYXIoMS4pLyhidFNjYWxhciludW1JbmRpY2VzKTsKCglmb3IgKGk9c3RhcnRJbmRleDtpPGVuZEluZGV4O2krKykKCXsKCQlidFZlY3RvcjMgY2VudGVyID0gYnRTY2FsYXIoMC41KSoocHJpbWl0aXZlX2JveGVzW2ldLm1fYm91bmQubV9tYXggKwoJCQkJCSBwcmltaXRpdmVfYm94ZXNbaV0ubV9ib3VuZC5tX21pbik7CgkJYnRWZWN0b3IzIGRpZmYyID0gY2VudGVyLW1lYW5zOwoJCWRpZmYyID0gZGlmZjIgKiBkaWZmMjsKCQl2YXJpYW5jZSArPSBkaWZmMjsKCX0KCXZhcmlhbmNlICo9IChidFNjYWxhcigxLikvCSgoYnRTY2FsYXIpbnVtSW5kaWNlcy0xKQkpOwoKCXJldHVybiB2YXJpYW5jZS5tYXhBeGlzKCk7Cn0KCgppbnQgYnRRdWFudGl6ZWRCdmhUcmVlOjpfc29ydF9hbmRfY2FsY19zcGxpdHRpbmdfaW5kZXgoCglHSU1fQlZIX0RBVEFfQVJSQVkgJiBwcmltaXRpdmVfYm94ZXMsIGludCBzdGFydEluZGV4LAoJaW50IGVuZEluZGV4LCBpbnQgc3BsaXRBeGlzKQp7CglpbnQgaTsKCWludCBzcGxpdEluZGV4ID1zdGFydEluZGV4OwoJaW50IG51bUluZGljZXMgPSBlbmRJbmRleCAtIHN0YXJ0SW5kZXg7CgoJLy8gYXZlcmFnZSBvZiBjZW50ZXJzCglidFNjYWxhciBzcGxpdFZhbHVlID0gMC4wZjsKCglidFZlY3RvcjMgbWVhbnMoYnRTY2FsYXIoMC4pLGJ0U2NhbGFyKDAuKSxidFNjYWxhcigwLikpOwoJZm9yIChpPXN0YXJ0SW5kZXg7aTxlbmRJbmRleDtpKyspCgl7CgkJYnRWZWN0b3IzIGNlbnRlciA9IGJ0U2NhbGFyKDAuNSkqKHByaW1pdGl2ZV9ib3hlc1tpXS5tX2JvdW5kLm1fbWF4ICsKCQkJCQkgcHJpbWl0aXZlX2JveGVzW2ldLm1fYm91bmQubV9taW4pOwoJCW1lYW5zKz1jZW50ZXI7Cgl9CgltZWFucyAqPSAoYnRTY2FsYXIoMS4pLyhidFNjYWxhciludW1JbmRpY2VzKTsKCglzcGxpdFZhbHVlID0gbWVhbnNbc3BsaXRBeGlzXTsKCgoJLy9zb3J0IGxlYWZOb2RlcyBzbyBhbGwgdmFsdWVzIGxhcmdlciB0aGVuIHNwbGl0VmFsdWUgY29tZXMgZmlyc3QsIGFuZCBzbWFsbGVyIHZhbHVlcyBzdGFydCBmcm9tICdzcGxpdEluZGV4Jy4KCWZvciAoaT1zdGFydEluZGV4O2k8ZW5kSW5kZXg7aSsrKQoJewoJCWJ0VmVjdG9yMyBjZW50ZXIgPSBidFNjYWxhcigwLjUpKihwcmltaXRpdmVfYm94ZXNbaV0ubV9ib3VuZC5tX21heCArCgkJCQkJIHByaW1pdGl2ZV9ib3hlc1tpXS5tX2JvdW5kLm1fbWluKTsKCQlpZiAoY2VudGVyW3NwbGl0QXhpc10gPiBzcGxpdFZhbHVlKQoJCXsKCQkJLy9zd2FwCgkJCXByaW1pdGl2ZV9ib3hlcy5zd2FwKGksc3BsaXRJbmRleCk7CgkJCS8vc3dhcExlYWZOb2RlcyhpLHNwbGl0SW5kZXgpOwoJCQlzcGxpdEluZGV4Kys7CgkJfQoJfQoKCS8vaWYgdGhlIHNwbGl0SW5kZXggY2F1c2VzIHVuYmFsYW5jZWQgdHJlZXMsIGZpeCB0aGlzIGJ5IHVzaW5nIHRoZSBjZW50ZXIgaW4gYmV0d2VlbiBzdGFydEluZGV4IGFuZCBlbmRJbmRleAoJLy9vdGhlcndpc2UgdGhlIHRyZWUtYnVpbGRpbmcgbWlnaHQgZmFpbCBkdWUgdG8gc3RhY2stb3ZlcmZsb3dzIGluIGNlcnRhaW4gY2FzZXMuCgkvL3VuYmFsYW5jZWQxIGlzIHVuc2FmZTogaXQgY2FuIGNhdXNlIHN0YWNrIG92ZXJmbG93cwoJLy9ib29sIHVuYmFsYW5jZWQxID0gKChzcGxpdEluZGV4PT1zdGFydEluZGV4KSB8fCAoc3BsaXRJbmRleCA9PSAoZW5kSW5kZXgtMSkpKTsKCgkvL3VuYmFsYW5jZWQyIHNob3VsZCB3b3JrIHRvbzogYWx3YXlzIHVzZSBjZW50ZXIgKHBlcmZlY3QgYmFsYW5jZWQgdHJlZXMpCgkvL2Jvb2wgdW5iYWxhbmNlZDIgPSB0cnVlOwoKCS8vdGhpcyBzaG91bGQgYmUgc2FmZSB0b286CglpbnQgcmFuZ2VCYWxhbmNlZEluZGljZXMgPSBudW1JbmRpY2VzLzM7Cglib29sIHVuYmFsYW5jZWQgPSAoKHNwbGl0SW5kZXg8PShzdGFydEluZGV4K3JhbmdlQmFsYW5jZWRJbmRpY2VzKSkgfHwgKHNwbGl0SW5kZXggPj0oZW5kSW5kZXgtMS1yYW5nZUJhbGFuY2VkSW5kaWNlcykpKTsKCglpZiAodW5iYWxhbmNlZCkKCXsKCQlzcGxpdEluZGV4ID0gc3RhcnRJbmRleCsgKG51bUluZGljZXM+PjEpOwoJfQoKCWJ0QXNzZXJ0KCEoKHNwbGl0SW5kZXg9PXN0YXJ0SW5kZXgpIHx8IChzcGxpdEluZGV4ID09IChlbmRJbmRleCkpKSk7CgoJcmV0dXJuIHNwbGl0SW5kZXg7Cgp9CgoKdm9pZCBidFF1YW50aXplZEJ2aFRyZWU6Ol9idWlsZF9zdWJfdHJlZShHSU1fQlZIX0RBVEFfQVJSQVkgJiBwcmltaXRpdmVfYm94ZXMsIGludCBzdGFydEluZGV4LCAgaW50IGVuZEluZGV4KQp7CglpbnQgY3VySW5kZXggPSBtX251bV9ub2RlczsKCW1fbnVtX25vZGVzKys7CgoJYnRBc3NlcnQoKGVuZEluZGV4LXN0YXJ0SW5kZXgpPjApOwoKCWlmICgoZW5kSW5kZXgtc3RhcnRJbmRleCk9PTEpCgl7CgkgICAgLy9XZSBoYXZlIGEgbGVhZiBub2RlCgkgICAgc2V0Tm9kZUJvdW5kKGN1ckluZGV4LHByaW1pdGl2ZV9ib3hlc1tzdGFydEluZGV4XS5tX2JvdW5kKTsKCQltX25vZGVfYXJyYXlbY3VySW5kZXhdLnNldERhdGFJbmRleChwcmltaXRpdmVfYm94ZXNbc3RhcnRJbmRleF0ubV9kYXRhKTsKCgkJcmV0dXJuOwoJfQoJLy9jYWxjdWxhdGUgQmVzdCBTcGxpdHRpbmcgQXhpcyBhbmQgd2hlcmUgdG8gc3BsaXQgaXQuIFNvcnQgdGhlIGluY29taW5nICdsZWFmTm9kZXMnIGFycmF5IHdpdGhpbiByYW5nZSAnc3RhcnRJbmRleC9lbmRJbmRleCcuCgoJLy9zcGxpdCBheGlzCglpbnQgc3BsaXRJbmRleCA9IF9jYWxjX3NwbGl0dGluZ19heGlzKHByaW1pdGl2ZV9ib3hlcyxzdGFydEluZGV4LGVuZEluZGV4KTsKCglzcGxpdEluZGV4ID0gX3NvcnRfYW5kX2NhbGNfc3BsaXR0aW5nX2luZGV4KAoJCQlwcmltaXRpdmVfYm94ZXMsc3RhcnRJbmRleCxlbmRJbmRleCwKCQkJc3BsaXRJbmRleC8vc3BsaXQgYXhpcwoJCQkpOwoKCgkvL2NhbGMgdGhpcyBub2RlIGJvdW5kaW5nIGJveAoKCWJ0QUFCQiBub2RlX2JvdW5kOwoJbm9kZV9ib3VuZC5pbnZhbGlkYXRlKCk7CgoJZm9yIChpbnQgaT1zdGFydEluZGV4O2k8ZW5kSW5kZXg7aSsrKQoJewoJCW5vZGVfYm91bmQubWVyZ2UocHJpbWl0aXZlX2JveGVzW2ldLm1fYm91bmQpOwoJfQoKCXNldE5vZGVCb3VuZChjdXJJbmRleCxub2RlX2JvdW5kKTsKCgoJLy9idWlsZCBsZWZ0IGJyYW5jaAoJX2J1aWxkX3N1Yl90cmVlKHByaW1pdGl2ZV9ib3hlcywgc3RhcnRJbmRleCwgc3BsaXRJbmRleCApOwoKCgkvL2J1aWxkIHJpZ2h0IGJyYW5jaAoJIF9idWlsZF9zdWJfdHJlZShwcmltaXRpdmVfYm94ZXMsIHNwbGl0SW5kZXggLGVuZEluZGV4KTsKCgltX25vZGVfYXJyYXlbY3VySW5kZXhdLnNldEVzY2FwZUluZGV4KG1fbnVtX25vZGVzIC0gY3VySW5kZXgpOwoKCn0KCi8vISBzdGFja2xlc3MgYnVpbGQgdHJlZQp2b2lkIGJ0UXVhbnRpemVkQnZoVHJlZTo6YnVpbGRfdHJlZSgKCUdJTV9CVkhfREFUQV9BUlJBWSAmIHByaW1pdGl2ZV9ib3hlcykKewoJY2FsY19xdWFudGl6YXRpb24ocHJpbWl0aXZlX2JveGVzKTsKCS8vIGluaXRpYWxpemUgbm9kZSBjb3VudCB0byAwCgltX251bV9ub2RlcyA9IDA7CgkvLyBhbGxvY2F0ZSBub2RlcwoJbV9ub2RlX2FycmF5LnJlc2l6ZShwcmltaXRpdmVfYm94ZXMuc2l6ZSgpKjIpOwoKCV9idWlsZF9zdWJfdHJlZShwcmltaXRpdmVfYm94ZXMsIDAsIHByaW1pdGl2ZV9ib3hlcy5zaXplKCkpOwp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9jbGFzcyBidEdJbXBhY3RRdWFudGl6ZWRCdmgKCnZvaWQgYnRHSW1wYWN0UXVhbnRpemVkQnZoOjpyZWZpdCgpCnsKCWludCBub2RlY291bnQgPSBnZXROb2RlQ291bnQoKTsKCXdoaWxlKG5vZGVjb3VudC0tKQoJewoJCWlmKGlzTGVhZk5vZGUobm9kZWNvdW50KSkKCQl7CgkJCWJ0QUFCQiBsZWFmYm94OwoJCQltX3ByaW1pdGl2ZV9tYW5hZ2VyLT5nZXRfcHJpbWl0aXZlX2JveChnZXROb2RlRGF0YShub2RlY291bnQpLGxlYWZib3gpOwoJCQlzZXROb2RlQm91bmQobm9kZWNvdW50LGxlYWZib3gpOwoJCX0KCQllbHNlCgkJewoJCQkvL2NvbnN0IEdJTV9CVkhfVFJFRV9OT0RFICogbm9kZXBvaW50ZXIgPSBnZXRfbm9kZV9wb2ludGVyKG5vZGVjb3VudCk7CgkJCS8vZ2V0IGxlZnQgYm91bmQKCQkJYnRBQUJCIGJvdW5kOwoJCQlib3VuZC5pbnZhbGlkYXRlKCk7CgoJCQlidEFBQkIgdGVtcF9ib3g7CgoJCQlpbnQgY2hpbGRfbm9kZSA9IGdldExlZnROb2RlKG5vZGVjb3VudCk7CgkJCWlmKGNoaWxkX25vZGUpCgkJCXsKCQkJCWdldE5vZGVCb3VuZChjaGlsZF9ub2RlLHRlbXBfYm94KTsKCQkJCWJvdW5kLm1lcmdlKHRlbXBfYm94KTsKCQkJfQoKCQkJY2hpbGRfbm9kZSA9IGdldFJpZ2h0Tm9kZShub2RlY291bnQpOwoJCQlpZihjaGlsZF9ub2RlKQoJCQl7CgkJCQlnZXROb2RlQm91bmQoY2hpbGRfbm9kZSx0ZW1wX2JveCk7CgkJCQlib3VuZC5tZXJnZSh0ZW1wX2JveCk7CgkJCX0KCgkJCXNldE5vZGVCb3VuZChub2RlY291bnQsYm91bmQpOwoJCX0KCX0KfQoKLy8hIHRoaXMgcmVidWlsZCB0aGUgZW50aXJlIHNldAp2b2lkIGJ0R0ltcGFjdFF1YW50aXplZEJ2aDo6YnVpbGRTZXQoKQp7CgkvL29idGFpbiBwcmltaXRpdmUgYm94ZXMKCUdJTV9CVkhfREFUQV9BUlJBWSBwcmltaXRpdmVfYm94ZXM7CglwcmltaXRpdmVfYm94ZXMucmVzaXplKG1fcHJpbWl0aXZlX21hbmFnZXItPmdldF9wcmltaXRpdmVfY291bnQoKSk7CgoJZm9yIChpbnQgaSA9IDA7aTxwcmltaXRpdmVfYm94ZXMuc2l6ZSgpIDtpKysgKQoJewoJCSBtX3ByaW1pdGl2ZV9tYW5hZ2VyLT5nZXRfcHJpbWl0aXZlX2JveChpLHByaW1pdGl2ZV9ib3hlc1tpXS5tX2JvdW5kKTsKCQkgcHJpbWl0aXZlX2JveGVzW2ldLm1fZGF0YSA9IGk7Cgl9CgoJbV9ib3hfdHJlZS5idWlsZF90cmVlKHByaW1pdGl2ZV9ib3hlcyk7Cn0KCi8vISByZXR1cm5zIHRoZSBpbmRpY2VzIG9mIHRoZSBwcmltaXRpdmVzIGluIHRoZSBtX3ByaW1pdGl2ZV9tYW5hZ2VyCmJvb2wgYnRHSW1wYWN0UXVhbnRpemVkQnZoOjpib3hRdWVyeShjb25zdCBidEFBQkIgJiBib3gsIGJ0QWxpZ25lZE9iamVjdEFycmF5PGludD4gJiBjb2xsaWRlZF9yZXN1bHRzKSBjb25zdAp7CglpbnQgY3VySW5kZXggPSAwOwoJaW50IG51bU5vZGVzID0gZ2V0Tm9kZUNvdW50KCk7CgoJLy9xdWFudGl6ZSBib3gKCgl1bnNpZ25lZCBzaG9ydCBxdWFudGl6ZWRNaW5bM107Cgl1bnNpZ25lZCBzaG9ydCBxdWFudGl6ZWRNYXhbM107CgoJbV9ib3hfdHJlZS5xdWFudGl6ZVBvaW50KHF1YW50aXplZE1pbixib3gubV9taW4pOwoJbV9ib3hfdHJlZS5xdWFudGl6ZVBvaW50KHF1YW50aXplZE1heCxib3gubV9tYXgpOwoKCgl3aGlsZSAoY3VySW5kZXggPCBudW1Ob2RlcykKCXsKCgkJLy9jYXRjaCBidWdzIGluIHRyZWUgZGF0YQoKCQlib29sIGFhYmJPdmVybGFwID0gbV9ib3hfdHJlZS50ZXN0UXVhbnRpemVkQm94T3ZlcmxhcHAoY3VySW5kZXgsIHF1YW50aXplZE1pbixxdWFudGl6ZWRNYXgpOwoJCWJvb2wgaXNsZWFmbm9kZSA9IGlzTGVhZk5vZGUoY3VySW5kZXgpOwoKCQlpZiAoaXNsZWFmbm9kZSAmJiBhYWJiT3ZlcmxhcCkKCQl7CgkJCWNvbGxpZGVkX3Jlc3VsdHMucHVzaF9iYWNrKGdldE5vZGVEYXRhKGN1ckluZGV4KSk7CgkJfQoKCQlpZiAoYWFiYk92ZXJsYXAgfHwgaXNsZWFmbm9kZSkKCQl7CgkJCS8vbmV4dCBzdWJub2RlCgkJCWN1ckluZGV4Kys7CgkJfQoJCWVsc2UKCQl7CgkJCS8vc2tpcCBub2RlCgkJCWN1ckluZGV4Kz0gZ2V0RXNjYXBlTm9kZUluZGV4KGN1ckluZGV4KTsKCQl9Cgl9CglpZihjb2xsaWRlZF9yZXN1bHRzLnNpemUoKT4wKSByZXR1cm4gdHJ1ZTsKCXJldHVybiBmYWxzZTsKfQoKCgovLyEgcmV0dXJucyB0aGUgaW5kaWNlcyBvZiB0aGUgcHJpbWl0aXZlcyBpbiB0aGUgbV9wcmltaXRpdmVfbWFuYWdlcgpib29sIGJ0R0ltcGFjdFF1YW50aXplZEJ2aDo6cmF5UXVlcnkoCgljb25zdCBidFZlY3RvcjMgJiByYXlfZGlyLGNvbnN0IGJ0VmVjdG9yMyAmIHJheV9vcmlnaW4gLAoJYnRBbGlnbmVkT2JqZWN0QXJyYXk8aW50PiAmIGNvbGxpZGVkX3Jlc3VsdHMpIGNvbnN0CnsKCWludCBjdXJJbmRleCA9IDA7CglpbnQgbnVtTm9kZXMgPSBnZXROb2RlQ291bnQoKTsKCgl3aGlsZSAoY3VySW5kZXggPCBudW1Ob2RlcykKCXsKCQlidEFBQkIgYm91bmQ7CgkJZ2V0Tm9kZUJvdW5kKGN1ckluZGV4LGJvdW5kKTsKCgkJLy9jYXRjaCBidWdzIGluIHRyZWUgZGF0YQoKCQlib29sIGFhYmJPdmVybGFwID0gYm91bmQuY29sbGlkZV9yYXkocmF5X29yaWdpbixyYXlfZGlyKTsKCQlib29sIGlzbGVhZm5vZGUgPSBpc0xlYWZOb2RlKGN1ckluZGV4KTsKCgkJaWYgKGlzbGVhZm5vZGUgJiYgYWFiYk92ZXJsYXApCgkJewoJCQljb2xsaWRlZF9yZXN1bHRzLnB1c2hfYmFjayhnZXROb2RlRGF0YSggY3VySW5kZXgpKTsKCQl9CgoJCWlmIChhYWJiT3ZlcmxhcCB8fCBpc2xlYWZub2RlKQoJCXsKCQkJLy9uZXh0IHN1Ym5vZGUKCQkJY3VySW5kZXgrKzsKCQl9CgkJZWxzZQoJCXsKCQkJLy9za2lwIG5vZGUKCQkJY3VySW5kZXgrPSBnZXRFc2NhcGVOb2RlSW5kZXgoY3VySW5kZXgpOwoJCX0KCX0KCWlmKGNvbGxpZGVkX3Jlc3VsdHMuc2l6ZSgpPjApIHJldHVybiB0cnVlOwoJcmV0dXJuIGZhbHNlOwp9CgoKU0lNRF9GT1JDRV9JTkxJTkUgYm9vbCBfcXVhbnRpemVkX25vZGVfY29sbGlzaW9uKAoJYnRHSW1wYWN0UXVhbnRpemVkQnZoICogYm94c2V0MCwgYnRHSW1wYWN0UXVhbnRpemVkQnZoICogYm94c2V0MSwKCWNvbnN0IEJUX0JPWF9CT1hfVFJBTlNGT1JNX0NBQ0hFICYgdHJhbnNfY2FjaGVfMXRvMCwKCWludCBub2RlMCAsaW50IG5vZGUxLCBib29sIGNvbXBsZXRlX3ByaW1pdGl2ZV90ZXN0cykKewoJYnRBQUJCIGJveDA7Cglib3hzZXQwLT5nZXROb2RlQm91bmQobm9kZTAsYm94MCk7CglidEFBQkIgYm94MTsKCWJveHNldDEtPmdldE5vZGVCb3VuZChub2RlMSxib3gxKTsKCglyZXR1cm4gYm94MC5vdmVybGFwcGluZ190cmFuc19jYWNoZShib3gxLHRyYW5zX2NhY2hlXzF0bzAsY29tcGxldGVfcHJpbWl0aXZlX3Rlc3RzICk7Ci8vCWJveDEuYXBweV90cmFuc2Zvcm1fdHJhbnNfY2FjaGUodHJhbnNfY2FjaGVfMXRvMCk7Ci8vCXJldHVybiBib3gwLmhhc19jb2xsaXNpb24oYm94MSk7Cgp9CgoKLy9zdGFja2xlc3MgcmVjdXJzaXZlIGNvbGxpc2lvbiByb3V0aW5lCnN0YXRpYyB2b2lkIF9maW5kX3F1YW50aXplZF9jb2xsaXNpb25fcGFpcnNfcmVjdXJzaXZlKAoJYnRHSW1wYWN0UXVhbnRpemVkQnZoICogYm94c2V0MCwgYnRHSW1wYWN0UXVhbnRpemVkQnZoICogYm94c2V0MSwKCWJ0UGFpclNldCAqIGNvbGxpc2lvbl9wYWlycywKCWNvbnN0IEJUX0JPWF9CT1hfVFJBTlNGT1JNX0NBQ0hFICYgdHJhbnNfY2FjaGVfMXRvMCwKCWludCBub2RlMCwgaW50IG5vZGUxLCBib29sIGNvbXBsZXRlX3ByaW1pdGl2ZV90ZXN0cykKewoKCgoJaWYoIF9xdWFudGl6ZWRfbm9kZV9jb2xsaXNpb24oCgkJYm94c2V0MCxib3hzZXQxLHRyYW5zX2NhY2hlXzF0bzAsCgkJbm9kZTAsbm9kZTEsY29tcGxldGVfcHJpbWl0aXZlX3Rlc3RzKSA9PWZhbHNlKSByZXR1cm47Ly9hdm9pZCBjb2xsaWRpbmcgaW50ZXJuYWwgbm9kZXMKCglpZihib3hzZXQwLT5pc0xlYWZOb2RlKG5vZGUwKSkKCXsKCQlpZihib3hzZXQxLT5pc0xlYWZOb2RlKG5vZGUxKSkKCQl7CgkJCS8vIGNvbGxpc2lvbiByZXN1bHQKCQkJY29sbGlzaW9uX3BhaXJzLT5wdXNoX3BhaXIoCgkJCQlib3hzZXQwLT5nZXROb2RlRGF0YShub2RlMCksYm94c2V0MS0+Z2V0Tm9kZURhdGEobm9kZTEpKTsKCQkJcmV0dXJuOwoJCX0KCQllbHNlCgkJewoKCQkJLy9jb2xsaWRlIGxlZnQgcmVjdXJzaXZlCgoJCQlfZmluZF9xdWFudGl6ZWRfY29sbGlzaW9uX3BhaXJzX3JlY3Vyc2l2ZSgKCQkJCQkJCQlib3hzZXQwLGJveHNldDEsCgkJCQkJCQkJY29sbGlzaW9uX3BhaXJzLHRyYW5zX2NhY2hlXzF0bzAsCgkJCQkJCQkJbm9kZTAsYm94c2V0MS0+Z2V0TGVmdE5vZGUobm9kZTEpLGZhbHNlKTsKCgkJCS8vY29sbGlkZSByaWdodCByZWN1cnNpdmUKCQkJX2ZpbmRfcXVhbnRpemVkX2NvbGxpc2lvbl9wYWlyc19yZWN1cnNpdmUoCgkJCQkJCQkJYm94c2V0MCxib3hzZXQxLAoJCQkJCQkJCWNvbGxpc2lvbl9wYWlycyx0cmFuc19jYWNoZV8xdG8wLAoJCQkJCQkJCW5vZGUwLGJveHNldDEtPmdldFJpZ2h0Tm9kZShub2RlMSksZmFsc2UpOwoKCgkJfQoJfQoJZWxzZQoJewoJCWlmKGJveHNldDEtPmlzTGVhZk5vZGUobm9kZTEpKQoJCXsKCgkJCS8vY29sbGlkZSBsZWZ0IHJlY3Vyc2l2ZQoJCQlfZmluZF9xdWFudGl6ZWRfY29sbGlzaW9uX3BhaXJzX3JlY3Vyc2l2ZSgKCQkJCQkJCQlib3hzZXQwLGJveHNldDEsCgkJCQkJCQkJY29sbGlzaW9uX3BhaXJzLHRyYW5zX2NhY2hlXzF0bzAsCgkJCQkJCQkJYm94c2V0MC0+Z2V0TGVmdE5vZGUobm9kZTApLG5vZGUxLGZhbHNlKTsKCgoJCQkvL2NvbGxpZGUgcmlnaHQgcmVjdXJzaXZlCgoJCQlfZmluZF9xdWFudGl6ZWRfY29sbGlzaW9uX3BhaXJzX3JlY3Vyc2l2ZSgKCQkJCQkJCQlib3hzZXQwLGJveHNldDEsCgkJCQkJCQkJY29sbGlzaW9uX3BhaXJzLHRyYW5zX2NhY2hlXzF0bzAsCgkJCQkJCQkJYm94c2V0MC0+Z2V0UmlnaHROb2RlKG5vZGUwKSxub2RlMSxmYWxzZSk7CgoKCQl9CgkJZWxzZQoJCXsKCQkJLy9jb2xsaWRlIGxlZnQwIGxlZnQxCgoKCgkJCV9maW5kX3F1YW50aXplZF9jb2xsaXNpb25fcGFpcnNfcmVjdXJzaXZlKAoJCQkJYm94c2V0MCxib3hzZXQxLAoJCQkJY29sbGlzaW9uX3BhaXJzLHRyYW5zX2NhY2hlXzF0bzAsCgkJCQlib3hzZXQwLT5nZXRMZWZ0Tm9kZShub2RlMCksYm94c2V0MS0+Z2V0TGVmdE5vZGUobm9kZTEpLGZhbHNlKTsKCgkJCS8vY29sbGlkZSBsZWZ0MCByaWdodDEKCgkJCV9maW5kX3F1YW50aXplZF9jb2xsaXNpb25fcGFpcnNfcmVjdXJzaXZlKAoJCQkJYm94c2V0MCxib3hzZXQxLAoJCQkJY29sbGlzaW9uX3BhaXJzLHRyYW5zX2NhY2hlXzF0bzAsCgkJCQlib3hzZXQwLT5nZXRMZWZ0Tm9kZShub2RlMCksYm94c2V0MS0+Z2V0UmlnaHROb2RlKG5vZGUxKSxmYWxzZSk7CgoKCQkJLy9jb2xsaWRlIHJpZ2h0MCBsZWZ0MQoKCQkJX2ZpbmRfcXVhbnRpemVkX2NvbGxpc2lvbl9wYWlyc19yZWN1cnNpdmUoCgkJCQlib3hzZXQwLGJveHNldDEsCgkJCQljb2xsaXNpb25fcGFpcnMsdHJhbnNfY2FjaGVfMXRvMCwKCQkJCWJveHNldDAtPmdldFJpZ2h0Tm9kZShub2RlMCksYm94c2V0MS0+Z2V0TGVmdE5vZGUobm9kZTEpLGZhbHNlKTsKCgkJCS8vY29sbGlkZSByaWdodDAgcmlnaHQxCgoJCQlfZmluZF9xdWFudGl6ZWRfY29sbGlzaW9uX3BhaXJzX3JlY3Vyc2l2ZSgKCQkJCWJveHNldDAsYm94c2V0MSwKCQkJCWNvbGxpc2lvbl9wYWlycyx0cmFuc19jYWNoZV8xdG8wLAoJCQkJYm94c2V0MC0+Z2V0UmlnaHROb2RlKG5vZGUwKSxib3hzZXQxLT5nZXRSaWdodE5vZGUobm9kZTEpLGZhbHNlKTsKCgkJfS8vIGVsc2UgaWYgbm9kZTEgaXMgbm90IGEgbGVhZgoJfS8vIGVsc2UgaWYgbm9kZTAgaXMgbm90IGEgbGVhZgp9CgoKdm9pZCBidEdJbXBhY3RRdWFudGl6ZWRCdmg6OmZpbmRfY29sbGlzaW9uKGJ0R0ltcGFjdFF1YW50aXplZEJ2aCAqIGJveHNldDAsIGNvbnN0IGJ0VHJhbnNmb3JtICYgdHJhbnMwLAoJCWJ0R0ltcGFjdFF1YW50aXplZEJ2aCAqIGJveHNldDEsIGNvbnN0IGJ0VHJhbnNmb3JtICYgdHJhbnMxLAoJCWJ0UGFpclNldCAmIGNvbGxpc2lvbl9wYWlycykKewoKCWlmKGJveHNldDAtPmdldE5vZGVDb3VudCgpPT0wIHx8IGJveHNldDEtPmdldE5vZGVDb3VudCgpPT0wICkgcmV0dXJuOwoKCUJUX0JPWF9CT1hfVFJBTlNGT1JNX0NBQ0hFIHRyYW5zX2NhY2hlXzF0bzA7CgoJdHJhbnNfY2FjaGVfMXRvMC5jYWxjX2Zyb21faG9tb2dlbmljKHRyYW5zMCx0cmFuczEpOwoKI2lmZGVmIFRSSV9DT0xMSVNJT05fUFJPRklMSU5HCglidF9iZWdpbl9naW0wMl9xX3RyZWVfdGltZSgpOwojZW5kaWYgLy9UUklfQ09MTElTSU9OX1BST0ZJTElORwoKCV9maW5kX3F1YW50aXplZF9jb2xsaXNpb25fcGFpcnNfcmVjdXJzaXZlKAoJCWJveHNldDAsYm94c2V0MSwKCQkmY29sbGlzaW9uX3BhaXJzLHRyYW5zX2NhY2hlXzF0bzAsMCwwLHRydWUpOwojaWZkZWYgVFJJX0NPTExJU0lPTl9QUk9GSUxJTkcKCWJ0X2VuZF9naW0wMl9xX3RyZWVfdGltZSgpOwojZW5kaWYgLy9UUklfQ09MTElTSU9OX1BST0ZJTElORwoKfQoKCg==