LyohIFxmaWxlIGdpbV9ib3hfc2V0LmgKXGF1dGhvciBGcmFuY2lzY28gTGV/biBO32plcmEKKi8KLyoKVGhpcyBzb3VyY2UgZmlsZSBpcyBwYXJ0IG9mIEdJTVBBQ1QgTGlicmFyeS4KCkZvciB0aGUgbGF0ZXN0IGluZm8sIHNlZSBodHRwOi8vZ2ltcGFjdC5zb3VyY2Vmb3JnZS5uZXQvCgpDb3B5cmlnaHQgKGMpIDIwMDcgRnJhbmNpc2NvIExlb24gTmFqZXJhLiBDLkMuIDgwMDg3MzcxLgplbWFpbDogcHJvamVjdGlsZW1hbkB5YWhvby5jb20KCgpUaGlzIHNvZnR3YXJlIGlzIHByb3ZpZGVkICdhcy1pcycsIHdpdGhvdXQgYW55IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KSW4gbm8gZXZlbnQgd2lsbCB0aGUgYXV0aG9ycyBiZSBoZWxkIGxpYWJsZSBmb3IgYW55IGRhbWFnZXMgYXJpc2luZyBmcm9tIHRoZSB1c2Ugb2YgdGhpcyBzb2Z0d2FyZS4KUGVybWlzc2lvbiBpcyBncmFudGVkIHRvIGFueW9uZSB0byB1c2UgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UsCmluY2x1ZGluZyBjb21tZXJjaWFsIGFwcGxpY2F0aW9ucywgYW5kIHRvIGFsdGVyIGl0IGFuZCByZWRpc3RyaWJ1dGUgaXQgZnJlZWx5LApzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgcmVzdHJpY3Rpb25zOgoKMS4gVGhlIG9yaWdpbiBvZiB0aGlzIHNvZnR3YXJlIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkOyB5b3UgbXVzdCBub3QgY2xhaW0gdGhhdCB5b3Ugd3JvdGUgdGhlIG9yaWdpbmFsIHNvZnR3YXJlLiBJZiB5b3UgdXNlIHRoaXMgc29mdHdhcmUgaW4gYSBwcm9kdWN0LCBhbiBhY2tub3dsZWRnbWVudCBpbiB0aGUgcHJvZHVjdCBkb2N1bWVudGF0aW9uIHdvdWxkIGJlIGFwcHJlY2lhdGVkIGJ1dCBpcyBub3QgcmVxdWlyZWQuCjIuIEFsdGVyZWQgc291cmNlIHZlcnNpb25zIG11c3QgYmUgcGxhaW5seSBtYXJrZWQgYXMgc3VjaCwgYW5kIG11c3Qgbm90IGJlIG1pc3JlcHJlc2VudGVkIGFzIGJlaW5nIHRoZSBvcmlnaW5hbCBzb2Z0d2FyZS4KMy4gVGhpcyBub3RpY2UgbWF5IG5vdCBiZSByZW1vdmVkIG9yIGFsdGVyZWQgZnJvbSBhbnkgc291cmNlIGRpc3RyaWJ1dGlvbi4KKi8KI2luY2x1ZGUgIkJ1bGxldENvbGxpc2lvbi9HaW1wYWN0L2J0R0ltcGFjdEJ2aC5oIgojaW5jbHVkZSAiTGluZWFyTWF0aC9idFF1aWNrcHJvZi5oIgoKI2lmZGVmIFRSSV9DT0xMSVNJT05fUFJPRklMSU5HCgpidENsb2NrIGdfdHJlZV9jbG9jazsKCmZsb2F0IGdfYWNjdW1fdHJlZV9jb2xsaXNpb25fdGltZSA9IDA7CmludCBnX2NvdW50X3RyYXZlcnNpbmcgPSAwOwoKCnZvaWQgYnRfYmVnaW5fZ2ltMDJfdHJlZV90aW1lKCkKewoJZ190cmVlX2Nsb2NrLnJlc2V0KCk7Cn0KCnZvaWQgYnRfZW5kX2dpbTAyX3RyZWVfdGltZSgpCnsKCWdfYWNjdW1fdHJlZV9jb2xsaXNpb25fdGltZSArPSBnX3RyZWVfY2xvY2suZ2V0VGltZU1pY3Jvc2Vjb25kcygpOwoJZ19jb3VudF90cmF2ZXJzaW5nKys7Cn0KCi8vISBHZXRzIHRoZSBhdmVyYWdlIHRpbWUgaW4gbWlsaXNlY29uZHMgb2YgdHJlZSBjb2xsaXNpb25zCmZsb2F0IGJ0R0ltcGFjdEJ2aDo6Z2V0QXZlcmFnZVRyZWVDb2xsaXNpb25UaW1lKCkKewoJaWYoZ19jb3VudF90cmF2ZXJzaW5nID09IDApIHJldHVybiAwOwoKCWZsb2F0IGF2Z3RpbWUgPSBnX2FjY3VtX3RyZWVfY29sbGlzaW9uX3RpbWU7Cglhdmd0aW1lIC89IChmbG9hdClnX2NvdW50X3RyYXZlcnNpbmc7CgoJZ19hY2N1bV90cmVlX2NvbGxpc2lvbl90aW1lID0gMDsKCWdfY291bnRfdHJhdmVyc2luZyA9IDA7CglyZXR1cm4gYXZndGltZTsKCi8vCWZsb2F0IGF2Z3RpbWUgPSBnX2NvdW50X3RyYXZlcnNpbmc7Ci8vCWdfY291bnRfdHJhdmVyc2luZyA9IDA7Ci8vCXJldHVybiBhdmd0aW1lOwoKfQoKI2VuZGlmIC8vVFJJX0NPTExJU0lPTl9QUk9GSUxJTkcKCi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vIGJ0QnZoVHJlZSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCmludCBidEJ2aFRyZWU6Ol9jYWxjX3NwbGl0dGluZ19heGlzKAoJR0lNX0JWSF9EQVRBX0FSUkFZICYgcHJpbWl0aXZlX2JveGVzLCBpbnQgc3RhcnRJbmRleCwgIGludCBlbmRJbmRleCkKewoKCWludCBpOwoKCWJ0VmVjdG9yMyBtZWFucyhidFNjYWxhcigwLiksYnRTY2FsYXIoMC4pLGJ0U2NhbGFyKDAuKSk7CglidFZlY3RvcjMgdmFyaWFuY2UoYnRTY2FsYXIoMC4pLGJ0U2NhbGFyKDAuKSxidFNjYWxhcigwLikpOwoJaW50IG51bUluZGljZXMgPSBlbmRJbmRleC1zdGFydEluZGV4OwoKCWZvciAoaT1zdGFydEluZGV4O2k8ZW5kSW5kZXg7aSsrKQoJewoJCWJ0VmVjdG9yMyBjZW50ZXIgPSBidFNjYWxhcigwLjUpKihwcmltaXRpdmVfYm94ZXNbaV0ubV9ib3VuZC5tX21heCArCgkJCQkJIHByaW1pdGl2ZV9ib3hlc1tpXS5tX2JvdW5kLm1fbWluKTsKCQltZWFucys9Y2VudGVyOwoJfQoJbWVhbnMgKj0gKGJ0U2NhbGFyKDEuKS8oYnRTY2FsYXIpbnVtSW5kaWNlcyk7CgoJZm9yIChpPXN0YXJ0SW5kZXg7aTxlbmRJbmRleDtpKyspCgl7CgkJYnRWZWN0b3IzIGNlbnRlciA9IGJ0U2NhbGFyKDAuNSkqKHByaW1pdGl2ZV9ib3hlc1tpXS5tX2JvdW5kLm1fbWF4ICsKCQkJCQkgcHJpbWl0aXZlX2JveGVzW2ldLm1fYm91bmQubV9taW4pOwoJCWJ0VmVjdG9yMyBkaWZmMiA9IGNlbnRlci1tZWFuczsKCQlkaWZmMiA9IGRpZmYyICogZGlmZjI7CgkJdmFyaWFuY2UgKz0gZGlmZjI7Cgl9Cgl2YXJpYW5jZSAqPSAoYnRTY2FsYXIoMS4pLwkoKGJ0U2NhbGFyKW51bUluZGljZXMtMSkJKTsKCglyZXR1cm4gdmFyaWFuY2UubWF4QXhpcygpOwp9CgoKaW50IGJ0QnZoVHJlZTo6X3NvcnRfYW5kX2NhbGNfc3BsaXR0aW5nX2luZGV4KAoJR0lNX0JWSF9EQVRBX0FSUkFZICYgcHJpbWl0aXZlX2JveGVzLCBpbnQgc3RhcnRJbmRleCwKCWludCBlbmRJbmRleCwgaW50IHNwbGl0QXhpcykKewoJaW50IGk7CglpbnQgc3BsaXRJbmRleCA9c3RhcnRJbmRleDsKCWludCBudW1JbmRpY2VzID0gZW5kSW5kZXggLSBzdGFydEluZGV4OwoKCS8vIGF2ZXJhZ2Ugb2YgY2VudGVycwoJYnRTY2FsYXIgc3BsaXRWYWx1ZSA9IDAuMGY7CgoJYnRWZWN0b3IzIG1lYW5zKGJ0U2NhbGFyKDAuKSxidFNjYWxhcigwLiksYnRTY2FsYXIoMC4pKTsKCWZvciAoaT1zdGFydEluZGV4O2k8ZW5kSW5kZXg7aSsrKQoJewoJCWJ0VmVjdG9yMyBjZW50ZXIgPSBidFNjYWxhcigwLjUpKihwcmltaXRpdmVfYm94ZXNbaV0ubV9ib3VuZC5tX21heCArCgkJCQkJIHByaW1pdGl2ZV9ib3hlc1tpXS5tX2JvdW5kLm1fbWluKTsKCQltZWFucys9Y2VudGVyOwoJfQoJbWVhbnMgKj0gKGJ0U2NhbGFyKDEuKS8oYnRTY2FsYXIpbnVtSW5kaWNlcyk7CgoJc3BsaXRWYWx1ZSA9IG1lYW5zW3NwbGl0QXhpc107CgoKCS8vc29ydCBsZWFmTm9kZXMgc28gYWxsIHZhbHVlcyBsYXJnZXIgdGhlbiBzcGxpdFZhbHVlIGNvbWVzIGZpcnN0LCBhbmQgc21hbGxlciB2YWx1ZXMgc3RhcnQgZnJvbSAnc3BsaXRJbmRleCcuCglmb3IgKGk9c3RhcnRJbmRleDtpPGVuZEluZGV4O2krKykKCXsKCQlidFZlY3RvcjMgY2VudGVyID0gYnRTY2FsYXIoMC41KSoocHJpbWl0aXZlX2JveGVzW2ldLm1fYm91bmQubV9tYXggKwoJCQkJCSBwcmltaXRpdmVfYm94ZXNbaV0ubV9ib3VuZC5tX21pbik7CgkJaWYgKGNlbnRlcltzcGxpdEF4aXNdID4gc3BsaXRWYWx1ZSkKCQl7CgkJCS8vc3dhcAoJCQlwcmltaXRpdmVfYm94ZXMuc3dhcChpLHNwbGl0SW5kZXgpOwoJCQkvL3N3YXBMZWFmTm9kZXMoaSxzcGxpdEluZGV4KTsKCQkJc3BsaXRJbmRleCsrOwoJCX0KCX0KCgkvL2lmIHRoZSBzcGxpdEluZGV4IGNhdXNlcyB1bmJhbGFuY2VkIHRyZWVzLCBmaXggdGhpcyBieSB1c2luZyB0aGUgY2VudGVyIGluIGJldHdlZW4gc3RhcnRJbmRleCBhbmQgZW5kSW5kZXgKCS8vb3RoZXJ3aXNlIHRoZSB0cmVlLWJ1aWxkaW5nIG1pZ2h0IGZhaWwgZHVlIHRvIHN0YWNrLW92ZXJmbG93cyBpbiBjZXJ0YWluIGNhc2VzLgoJLy91bmJhbGFuY2VkMSBpcyB1bnNhZmU6IGl0IGNhbiBjYXVzZSBzdGFjayBvdmVyZmxvd3MKCS8vYm9vbCB1bmJhbGFuY2VkMSA9ICgoc3BsaXRJbmRleD09c3RhcnRJbmRleCkgfHwgKHNwbGl0SW5kZXggPT0gKGVuZEluZGV4LTEpKSk7CgoJLy91bmJhbGFuY2VkMiBzaG91bGQgd29yayB0b286IGFsd2F5cyB1c2UgY2VudGVyIChwZXJmZWN0IGJhbGFuY2VkIHRyZWVzKQoJLy9ib29sIHVuYmFsYW5jZWQyID0gdHJ1ZTsKCgkvL3RoaXMgc2hvdWxkIGJlIHNhZmUgdG9vOgoJaW50IHJhbmdlQmFsYW5jZWRJbmRpY2VzID0gbnVtSW5kaWNlcy8zOwoJYm9vbCB1bmJhbGFuY2VkID0gKChzcGxpdEluZGV4PD0oc3RhcnRJbmRleCtyYW5nZUJhbGFuY2VkSW5kaWNlcykpIHx8IChzcGxpdEluZGV4ID49KGVuZEluZGV4LTEtcmFuZ2VCYWxhbmNlZEluZGljZXMpKSk7CgoJaWYgKHVuYmFsYW5jZWQpCgl7CgkJc3BsaXRJbmRleCA9IHN0YXJ0SW5kZXgrIChudW1JbmRpY2VzPj4xKTsKCX0KCglidEFzc2VydCghKChzcGxpdEluZGV4PT1zdGFydEluZGV4KSB8fCAoc3BsaXRJbmRleCA9PSAoZW5kSW5kZXgpKSkpOwoKCXJldHVybiBzcGxpdEluZGV4OwoKfQoKCnZvaWQgYnRCdmhUcmVlOjpfYnVpbGRfc3ViX3RyZWUoR0lNX0JWSF9EQVRBX0FSUkFZICYgcHJpbWl0aXZlX2JveGVzLCBpbnQgc3RhcnRJbmRleCwgIGludCBlbmRJbmRleCkKewoJaW50IGN1ckluZGV4ID0gbV9udW1fbm9kZXM7CgltX251bV9ub2RlcysrOwoKCWJ0QXNzZXJ0KChlbmRJbmRleC1zdGFydEluZGV4KT4wKTsKCglpZiAoKGVuZEluZGV4LXN0YXJ0SW5kZXgpPT0xKQoJewoJICAgIC8vV2UgaGF2ZSBhIGxlYWYgbm9kZQoJICAgIHNldE5vZGVCb3VuZChjdXJJbmRleCxwcmltaXRpdmVfYm94ZXNbc3RhcnRJbmRleF0ubV9ib3VuZCk7CgkJbV9ub2RlX2FycmF5W2N1ckluZGV4XS5zZXREYXRhSW5kZXgocHJpbWl0aXZlX2JveGVzW3N0YXJ0SW5kZXhdLm1fZGF0YSk7CgoJCXJldHVybjsKCX0KCS8vY2FsY3VsYXRlIEJlc3QgU3BsaXR0aW5nIEF4aXMgYW5kIHdoZXJlIHRvIHNwbGl0IGl0LiBTb3J0IHRoZSBpbmNvbWluZyAnbGVhZk5vZGVzJyBhcnJheSB3aXRoaW4gcmFuZ2UgJ3N0YXJ0SW5kZXgvZW5kSW5kZXgnLgoKCS8vc3BsaXQgYXhpcwoJaW50IHNwbGl0SW5kZXggPSBfY2FsY19zcGxpdHRpbmdfYXhpcyhwcmltaXRpdmVfYm94ZXMsc3RhcnRJbmRleCxlbmRJbmRleCk7CgoJc3BsaXRJbmRleCA9IF9zb3J0X2FuZF9jYWxjX3NwbGl0dGluZ19pbmRleCgKCQkJcHJpbWl0aXZlX2JveGVzLHN0YXJ0SW5kZXgsZW5kSW5kZXgsCgkJCXNwbGl0SW5kZXgvL3NwbGl0IGF4aXMKCQkJKTsKCgoJLy9jYWxjIHRoaXMgbm9kZSBib3VuZGluZyBib3gKCglidEFBQkIgbm9kZV9ib3VuZDsKCW5vZGVfYm91bmQuaW52YWxpZGF0ZSgpOwoKCWZvciAoaW50IGk9c3RhcnRJbmRleDtpPGVuZEluZGV4O2krKykKCXsKCQlub2RlX2JvdW5kLm1lcmdlKHByaW1pdGl2ZV9ib3hlc1tpXS5tX2JvdW5kKTsKCX0KCglzZXROb2RlQm91bmQoY3VySW5kZXgsbm9kZV9ib3VuZCk7CgoKCS8vYnVpbGQgbGVmdCBicmFuY2gKCV9idWlsZF9zdWJfdHJlZShwcmltaXRpdmVfYm94ZXMsIHN0YXJ0SW5kZXgsIHNwbGl0SW5kZXggKTsKCgoJLy9idWlsZCByaWdodCBicmFuY2gKCSBfYnVpbGRfc3ViX3RyZWUocHJpbWl0aXZlX2JveGVzLCBzcGxpdEluZGV4ICxlbmRJbmRleCk7CgoJbV9ub2RlX2FycmF5W2N1ckluZGV4XS5zZXRFc2NhcGVJbmRleChtX251bV9ub2RlcyAtIGN1ckluZGV4KTsKCgp9CgovLyEgc3RhY2tsZXNzIGJ1aWxkIHRyZWUKdm9pZCBidEJ2aFRyZWU6OmJ1aWxkX3RyZWUoCglHSU1fQlZIX0RBVEFfQVJSQVkgJiBwcmltaXRpdmVfYm94ZXMpCnsKCS8vIGluaXRpYWxpemUgbm9kZSBjb3VudCB0byAwCgltX251bV9ub2RlcyA9IDA7CgkvLyBhbGxvY2F0ZSBub2RlcwoJbV9ub2RlX2FycmF5LnJlc2l6ZShwcmltaXRpdmVfYm94ZXMuc2l6ZSgpKjIpOwoKCV9idWlsZF9zdWJfdHJlZShwcmltaXRpdmVfYm94ZXMsIDAsIHByaW1pdGl2ZV9ib3hlcy5zaXplKCkpOwp9CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9jbGFzcyBidEdJbXBhY3RCdmgKCnZvaWQgYnRHSW1wYWN0QnZoOjpyZWZpdCgpCnsKCWludCBub2RlY291bnQgPSBnZXROb2RlQ291bnQoKTsKCXdoaWxlKG5vZGVjb3VudC0tKQoJewoJCWlmKGlzTGVhZk5vZGUobm9kZWNvdW50KSkKCQl7CgkJCWJ0QUFCQiBsZWFmYm94OwoJCQltX3ByaW1pdGl2ZV9tYW5hZ2VyLT5nZXRfcHJpbWl0aXZlX2JveChnZXROb2RlRGF0YShub2RlY291bnQpLGxlYWZib3gpOwoJCQlzZXROb2RlQm91bmQobm9kZWNvdW50LGxlYWZib3gpOwoJCX0KCQllbHNlCgkJewoJCQkvL2NvbnN0IEdJTV9CVkhfVFJFRV9OT0RFICogbm9kZXBvaW50ZXIgPSBnZXRfbm9kZV9wb2ludGVyKG5vZGVjb3VudCk7CgkJCS8vZ2V0IGxlZnQgYm91bmQKCQkJYnRBQUJCIGJvdW5kOwoJCQlib3VuZC5pbnZhbGlkYXRlKCk7CgoJCQlidEFBQkIgdGVtcF9ib3g7CgoJCQlpbnQgY2hpbGRfbm9kZSA9IGdldExlZnROb2RlKG5vZGVjb3VudCk7CgkJCWlmKGNoaWxkX25vZGUpCgkJCXsKCQkJCWdldE5vZGVCb3VuZChjaGlsZF9ub2RlLHRlbXBfYm94KTsKCQkJCWJvdW5kLm1lcmdlKHRlbXBfYm94KTsKCQkJfQoKCQkJY2hpbGRfbm9kZSA9IGdldFJpZ2h0Tm9kZShub2RlY291bnQpOwoJCQlpZihjaGlsZF9ub2RlKQoJCQl7CgkJCQlnZXROb2RlQm91bmQoY2hpbGRfbm9kZSx0ZW1wX2JveCk7CgkJCQlib3VuZC5tZXJnZSh0ZW1wX2JveCk7CgkJCX0KCgkJCXNldE5vZGVCb3VuZChub2RlY291bnQsYm91bmQpOwoJCX0KCX0KfQoKLy8hIHRoaXMgcmVidWlsZCB0aGUgZW50aXJlIHNldAp2b2lkIGJ0R0ltcGFjdEJ2aDo6YnVpbGRTZXQoKQp7CgkvL29idGFpbiBwcmltaXRpdmUgYm94ZXMKCUdJTV9CVkhfREFUQV9BUlJBWSBwcmltaXRpdmVfYm94ZXM7CglwcmltaXRpdmVfYm94ZXMucmVzaXplKG1fcHJpbWl0aXZlX21hbmFnZXItPmdldF9wcmltaXRpdmVfY291bnQoKSk7CgoJZm9yIChpbnQgaSA9IDA7aTxwcmltaXRpdmVfYm94ZXMuc2l6ZSgpIDtpKysgKQoJewoJCSBtX3ByaW1pdGl2ZV9tYW5hZ2VyLT5nZXRfcHJpbWl0aXZlX2JveChpLHByaW1pdGl2ZV9ib3hlc1tpXS5tX2JvdW5kKTsKCQkgcHJpbWl0aXZlX2JveGVzW2ldLm1fZGF0YSA9IGk7Cgl9CgoJbV9ib3hfdHJlZS5idWlsZF90cmVlKHByaW1pdGl2ZV9ib3hlcyk7Cn0KCi8vISByZXR1cm5zIHRoZSBpbmRpY2VzIG9mIHRoZSBwcmltaXRpdmVzIGluIHRoZSBtX3ByaW1pdGl2ZV9tYW5hZ2VyCmJvb2wgYnRHSW1wYWN0QnZoOjpib3hRdWVyeShjb25zdCBidEFBQkIgJiBib3gsIGJ0QWxpZ25lZE9iamVjdEFycmF5PGludD4gJiBjb2xsaWRlZF9yZXN1bHRzKSBjb25zdAp7CglpbnQgY3VySW5kZXggPSAwOwoJaW50IG51bU5vZGVzID0gZ2V0Tm9kZUNvdW50KCk7CgoJd2hpbGUgKGN1ckluZGV4IDwgbnVtTm9kZXMpCgl7CgkJYnRBQUJCIGJvdW5kOwoJCWdldE5vZGVCb3VuZChjdXJJbmRleCxib3VuZCk7CgoJCS8vY2F0Y2ggYnVncyBpbiB0cmVlIGRhdGEKCgkJYm9vbCBhYWJiT3ZlcmxhcCA9IGJvdW5kLmhhc19jb2xsaXNpb24oYm94KTsKCQlib29sIGlzbGVhZm5vZGUgPSBpc0xlYWZOb2RlKGN1ckluZGV4KTsKCgkJaWYgKGlzbGVhZm5vZGUgJiYgYWFiYk92ZXJsYXApCgkJewoJCQljb2xsaWRlZF9yZXN1bHRzLnB1c2hfYmFjayhnZXROb2RlRGF0YShjdXJJbmRleCkpOwoJCX0KCgkJaWYgKGFhYmJPdmVybGFwIHx8IGlzbGVhZm5vZGUpCgkJewoJCQkvL25leHQgc3Vibm9kZQoJCQljdXJJbmRleCsrOwoJCX0KCQllbHNlCgkJewoJCQkvL3NraXAgbm9kZQoJCQljdXJJbmRleCs9IGdldEVzY2FwZU5vZGVJbmRleChjdXJJbmRleCk7CgkJfQoJfQoJaWYoY29sbGlkZWRfcmVzdWx0cy5zaXplKCk+MCkgcmV0dXJuIHRydWU7CglyZXR1cm4gZmFsc2U7Cn0KCgoKLy8hIHJldHVybnMgdGhlIGluZGljZXMgb2YgdGhlIHByaW1pdGl2ZXMgaW4gdGhlIG1fcHJpbWl0aXZlX21hbmFnZXIKYm9vbCBidEdJbXBhY3RCdmg6OnJheVF1ZXJ5KAoJY29uc3QgYnRWZWN0b3IzICYgcmF5X2Rpcixjb25zdCBidFZlY3RvcjMgJiByYXlfb3JpZ2luICwKCWJ0QWxpZ25lZE9iamVjdEFycmF5PGludD4gJiBjb2xsaWRlZF9yZXN1bHRzKSBjb25zdAp7CglpbnQgY3VySW5kZXggPSAwOwoJaW50IG51bU5vZGVzID0gZ2V0Tm9kZUNvdW50KCk7CgoJd2hpbGUgKGN1ckluZGV4IDwgbnVtTm9kZXMpCgl7CgkJYnRBQUJCIGJvdW5kOwoJCWdldE5vZGVCb3VuZChjdXJJbmRleCxib3VuZCk7CgoJCS8vY2F0Y2ggYnVncyBpbiB0cmVlIGRhdGEKCgkJYm9vbCBhYWJiT3ZlcmxhcCA9IGJvdW5kLmNvbGxpZGVfcmF5KHJheV9vcmlnaW4scmF5X2Rpcik7CgkJYm9vbCBpc2xlYWZub2RlID0gaXNMZWFmTm9kZShjdXJJbmRleCk7CgoJCWlmIChpc2xlYWZub2RlICYmIGFhYmJPdmVybGFwKQoJCXsKCQkJY29sbGlkZWRfcmVzdWx0cy5wdXNoX2JhY2soZ2V0Tm9kZURhdGEoIGN1ckluZGV4KSk7CgkJfQoKCQlpZiAoYWFiYk92ZXJsYXAgfHwgaXNsZWFmbm9kZSkKCQl7CgkJCS8vbmV4dCBzdWJub2RlCgkJCWN1ckluZGV4Kys7CgkJfQoJCWVsc2UKCQl7CgkJCS8vc2tpcCBub2RlCgkJCWN1ckluZGV4Kz0gZ2V0RXNjYXBlTm9kZUluZGV4KGN1ckluZGV4KTsKCQl9Cgl9CglpZihjb2xsaWRlZF9yZXN1bHRzLnNpemUoKT4wKSByZXR1cm4gdHJ1ZTsKCXJldHVybiBmYWxzZTsKfQoKClNJTURfRk9SQ0VfSU5MSU5FIGJvb2wgX25vZGVfY29sbGlzaW9uKAoJYnRHSW1wYWN0QnZoICogYm94c2V0MCwgYnRHSW1wYWN0QnZoICogYm94c2V0MSwKCWNvbnN0IEJUX0JPWF9CT1hfVFJBTlNGT1JNX0NBQ0hFICYgdHJhbnNfY2FjaGVfMXRvMCwKCWludCBub2RlMCAsaW50IG5vZGUxLCBib29sIGNvbXBsZXRlX3ByaW1pdGl2ZV90ZXN0cykKewoJYnRBQUJCIGJveDA7Cglib3hzZXQwLT5nZXROb2RlQm91bmQobm9kZTAsYm94MCk7CglidEFBQkIgYm94MTsKCWJveHNldDEtPmdldE5vZGVCb3VuZChub2RlMSxib3gxKTsKCglyZXR1cm4gYm94MC5vdmVybGFwcGluZ190cmFuc19jYWNoZShib3gxLHRyYW5zX2NhY2hlXzF0bzAsY29tcGxldGVfcHJpbWl0aXZlX3Rlc3RzICk7Ci8vCWJveDEuYXBweV90cmFuc2Zvcm1fdHJhbnNfY2FjaGUodHJhbnNfY2FjaGVfMXRvMCk7Ci8vCXJldHVybiBib3gwLmhhc19jb2xsaXNpb24oYm94MSk7Cgp9CgoKLy9zdGFja2xlc3MgcmVjdXJzaXZlIGNvbGxpc2lvbiByb3V0aW5lCnN0YXRpYyB2b2lkIF9maW5kX2NvbGxpc2lvbl9wYWlyc19yZWN1cnNpdmUoCglidEdJbXBhY3RCdmggKiBib3hzZXQwLCBidEdJbXBhY3RCdmggKiBib3hzZXQxLAoJYnRQYWlyU2V0ICogY29sbGlzaW9uX3BhaXJzLAoJY29uc3QgQlRfQk9YX0JPWF9UUkFOU0ZPUk1fQ0FDSEUgJiB0cmFuc19jYWNoZV8xdG8wLAoJaW50IG5vZGUwLCBpbnQgbm9kZTEsIGJvb2wgY29tcGxldGVfcHJpbWl0aXZlX3Rlc3RzKQp7CgoKCglpZiggX25vZGVfY29sbGlzaW9uKAoJCWJveHNldDAsYm94c2V0MSx0cmFuc19jYWNoZV8xdG8wLAoJCW5vZGUwLG5vZGUxLGNvbXBsZXRlX3ByaW1pdGl2ZV90ZXN0cykgPT1mYWxzZSkgcmV0dXJuOy8vYXZvaWQgY29sbGlkaW5nIGludGVybmFsIG5vZGVzCgoJaWYoYm94c2V0MC0+aXNMZWFmTm9kZShub2RlMCkpCgl7CgkJaWYoYm94c2V0MS0+aXNMZWFmTm9kZShub2RlMSkpCgkJewoJCQkvLyBjb2xsaXNpb24gcmVzdWx0CgkJCWNvbGxpc2lvbl9wYWlycy0+cHVzaF9wYWlyKAoJCQkJYm94c2V0MC0+Z2V0Tm9kZURhdGEobm9kZTApLGJveHNldDEtPmdldE5vZGVEYXRhKG5vZGUxKSk7CgkJCXJldHVybjsKCQl9CgkJZWxzZQoJCXsKCgkJCS8vY29sbGlkZSBsZWZ0IHJlY3Vyc2l2ZQoKCQkJX2ZpbmRfY29sbGlzaW9uX3BhaXJzX3JlY3Vyc2l2ZSgKCQkJCQkJCQlib3hzZXQwLGJveHNldDEsCgkJCQkJCQkJY29sbGlzaW9uX3BhaXJzLHRyYW5zX2NhY2hlXzF0bzAsCgkJCQkJCQkJbm9kZTAsYm94c2V0MS0+Z2V0TGVmdE5vZGUobm9kZTEpLGZhbHNlKTsKCgkJCS8vY29sbGlkZSByaWdodCByZWN1cnNpdmUKCQkJX2ZpbmRfY29sbGlzaW9uX3BhaXJzX3JlY3Vyc2l2ZSgKCQkJCQkJCQlib3hzZXQwLGJveHNldDEsCgkJCQkJCQkJY29sbGlzaW9uX3BhaXJzLHRyYW5zX2NhY2hlXzF0bzAsCgkJCQkJCQkJbm9kZTAsYm94c2V0MS0+Z2V0UmlnaHROb2RlKG5vZGUxKSxmYWxzZSk7CgoKCQl9Cgl9CgllbHNlCgl7CgkJaWYoYm94c2V0MS0+aXNMZWFmTm9kZShub2RlMSkpCgkJewoKCQkJLy9jb2xsaWRlIGxlZnQgcmVjdXJzaXZlCgkJCV9maW5kX2NvbGxpc2lvbl9wYWlyc19yZWN1cnNpdmUoCgkJCQkJCQkJYm94c2V0MCxib3hzZXQxLAoJCQkJCQkJCWNvbGxpc2lvbl9wYWlycyx0cmFuc19jYWNoZV8xdG8wLAoJCQkJCQkJCWJveHNldDAtPmdldExlZnROb2RlKG5vZGUwKSxub2RlMSxmYWxzZSk7CgoKCQkJLy9jb2xsaWRlIHJpZ2h0IHJlY3Vyc2l2ZQoKCQkJX2ZpbmRfY29sbGlzaW9uX3BhaXJzX3JlY3Vyc2l2ZSgKCQkJCQkJCQlib3hzZXQwLGJveHNldDEsCgkJCQkJCQkJY29sbGlzaW9uX3BhaXJzLHRyYW5zX2NhY2hlXzF0bzAsCgkJCQkJCQkJYm94c2V0MC0+Z2V0UmlnaHROb2RlKG5vZGUwKSxub2RlMSxmYWxzZSk7CgoKCQl9CgkJZWxzZQoJCXsKCQkJLy9jb2xsaWRlIGxlZnQwIGxlZnQxCgoKCgkJCV9maW5kX2NvbGxpc2lvbl9wYWlyc19yZWN1cnNpdmUoCgkJCQlib3hzZXQwLGJveHNldDEsCgkJCQljb2xsaXNpb25fcGFpcnMsdHJhbnNfY2FjaGVfMXRvMCwKCQkJCWJveHNldDAtPmdldExlZnROb2RlKG5vZGUwKSxib3hzZXQxLT5nZXRMZWZ0Tm9kZShub2RlMSksZmFsc2UpOwoKCQkJLy9jb2xsaWRlIGxlZnQwIHJpZ2h0MQoKCQkJX2ZpbmRfY29sbGlzaW9uX3BhaXJzX3JlY3Vyc2l2ZSgKCQkJCWJveHNldDAsYm94c2V0MSwKCQkJCWNvbGxpc2lvbl9wYWlycyx0cmFuc19jYWNoZV8xdG8wLAoJCQkJYm94c2V0MC0+Z2V0TGVmdE5vZGUobm9kZTApLGJveHNldDEtPmdldFJpZ2h0Tm9kZShub2RlMSksZmFsc2UpOwoKCgkJCS8vY29sbGlkZSByaWdodDAgbGVmdDEKCgkJCV9maW5kX2NvbGxpc2lvbl9wYWlyc19yZWN1cnNpdmUoCgkJCQlib3hzZXQwLGJveHNldDEsCgkJCQljb2xsaXNpb25fcGFpcnMsdHJhbnNfY2FjaGVfMXRvMCwKCQkJCWJveHNldDAtPmdldFJpZ2h0Tm9kZShub2RlMCksYm94c2V0MS0+Z2V0TGVmdE5vZGUobm9kZTEpLGZhbHNlKTsKCgkJCS8vY29sbGlkZSByaWdodDAgcmlnaHQxCgoJCQlfZmluZF9jb2xsaXNpb25fcGFpcnNfcmVjdXJzaXZlKAoJCQkJYm94c2V0MCxib3hzZXQxLAoJCQkJY29sbGlzaW9uX3BhaXJzLHRyYW5zX2NhY2hlXzF0bzAsCgkJCQlib3hzZXQwLT5nZXRSaWdodE5vZGUobm9kZTApLGJveHNldDEtPmdldFJpZ2h0Tm9kZShub2RlMSksZmFsc2UpOwoKCQl9Ly8gZWxzZSBpZiBub2RlMSBpcyBub3QgYSBsZWFmCgl9Ly8gZWxzZSBpZiBub2RlMCBpcyBub3QgYSBsZWFmCn0KCgp2b2lkIGJ0R0ltcGFjdEJ2aDo6ZmluZF9jb2xsaXNpb24oYnRHSW1wYWN0QnZoICogYm94c2V0MCwgY29uc3QgYnRUcmFuc2Zvcm0gJiB0cmFuczAsCgkJYnRHSW1wYWN0QnZoICogYm94c2V0MSwgY29uc3QgYnRUcmFuc2Zvcm0gJiB0cmFuczEsCgkJYnRQYWlyU2V0ICYgY29sbGlzaW9uX3BhaXJzKQp7CgoJaWYoYm94c2V0MC0+Z2V0Tm9kZUNvdW50KCk9PTAgfHwgYm94c2V0MS0+Z2V0Tm9kZUNvdW50KCk9PTAgKSByZXR1cm47CgoJQlRfQk9YX0JPWF9UUkFOU0ZPUk1fQ0FDSEUgdHJhbnNfY2FjaGVfMXRvMDsKCgl0cmFuc19jYWNoZV8xdG8wLmNhbGNfZnJvbV9ob21vZ2VuaWModHJhbnMwLHRyYW5zMSk7CgojaWZkZWYgVFJJX0NPTExJU0lPTl9QUk9GSUxJTkcKCWJ0X2JlZ2luX2dpbTAyX3RyZWVfdGltZSgpOwojZW5kaWYgLy9UUklfQ09MTElTSU9OX1BST0ZJTElORwoKCV9maW5kX2NvbGxpc2lvbl9wYWlyc19yZWN1cnNpdmUoCgkJYm94c2V0MCxib3hzZXQxLAoJCSZjb2xsaXNpb25fcGFpcnMsdHJhbnNfY2FjaGVfMXRvMCwwLDAsdHJ1ZSk7CiNpZmRlZiBUUklfQ09MTElTSU9OX1BST0ZJTElORwoJYnRfZW5kX2dpbTAyX3RyZWVfdGltZSgpOwojZW5kaWYgLy9UUklfQ09MTElTSU9OX1BST0ZJTElORwoKfQoK