LyoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqIENvcHlyaWdodCAoQykgMTk5Ni0xOTk5LCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzIENvcnBvcmF0aW9uIGFuZCAgICAqCiogb3RoZXJzLiBBbGwgUmlnaHRzIFJlc2VydmVkLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqLwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vCi8vIEZpbGUgY29sZWl0ci5jcHAKLy8KLy8gCi8vCi8vIENyZWF0ZWQgYnk6IEhlbGVuYSBTaGloCi8vCi8vIE1vZGlmaWNhdGlvbiBIaXN0b3J5OgovLwovLyAgRGF0ZSAgICAgICAgIE5hbWUgICAgICAgICAgRGVzY3JpcHRpb24KLy8KLy8gIDYvMjMvOTcgICAgIGhlbGVuYSAgICAgIEFkZGluZyBjb21tZW50cyB0byBtYWtlIGNvZGUgbW9yZSByZWFkYWJsZS4KLy8gMDgvMDMvOTggICAgIGVybSAgICAgICAgIFN5bmNoZWQgd2l0aCAxLjIgdmVyc2lvbiBvZiBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IuamF2YQovLyAxMi8xMC85OSAgICAgIGFsaXUgICAgICAgICAgUG9ydGVkIFRoYWkgY29sbGF0aW9uIHN1cHBvcnQgZnJvbSBKYXZhLgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojaW5jbHVkZSAidW5pY29kZS9zb3J0a2V5LmgiCiNpbmNsdWRlICJ1bmljb2RlL2NvbGVpdHIuaCIKCiNpbmNsdWRlICJ1bmljb2RlL2NoYXJpdGVyLmgiCiNpbmNsdWRlICJ0YWJsZXMuaCIKI2luY2x1ZGUgInVuaWNvZGUvbm9ybWx6ci5oIgojaW5jbHVkZSAidW5pY29kZS91bmljb2RlLmgiCiNpbmNsdWRlICJ0Y29sZGF0YS5oIgojaW5jbHVkZSAidWNtcDMyLmgiCgoKaW50MzJfdCBjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Ok5VTExPUkRFUiA9IDB4ZmZmZmZmZmY7CmludDMyX3QgY29uc3QgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpVTk1BUFBFRENIQVJWQUxVRSA9IDB4N2ZmZjAwMDA7CgoKLy8gVGhpcyBwcml2YXRlIG1ldGhvZCB3aWxsIG5ldmVyIGJlIGNhbGxlZCwgYnV0IGl0IG1ha2VzIHRoZSBsaW5rZXIgaGFwcHkKCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKCkKOiB0ZXh0KDApLAogIGJ1ZmZlckFsaWFzKDApLAogIG93bkJ1ZmZlcihuZXcgVmVjdG9yT2ZJbnQoMikpLAogIHJlb3JkZXJCdWZmZXIoMCksCiAgZXhwSW5kZXgoMCksCiAgb3JkZXJBbGlhcygwKQp7Cn0KCi8vIFRoaXMgcHJpdmF0ZSBtZXRob2Qgd2lsbCBuZXZlciBiZSBjYWxsZWQsIGJ1dCBpdCBtYWtlcyB0aGUgbGlua2VyIGhhcHB5CgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcihjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogb3JkZXIpCjogdGV4dCgwKSwKICBidWZmZXJBbGlhcygwKSwKICBvd25CdWZmZXIobmV3IFZlY3Rvck9mSW50KDIpKSwKICByZW9yZGVyQnVmZmVyKDApLAogIGV4cEluZGV4KDApLAogIG9yZGVyQWxpYXMob3JkZXIpCnsKfQoKLy8gVGhpcyBpcyB0aGUgInJlYWwiIGNvbnN0cnVjdG9yIGZvciB0aGlzIGNsYXNzOyBpdCBjb25zdHJ1Y3RzIGFuIGl0ZXJhdG9yCi8vIG92ZXIgdGhlIHNvdXJjZSB0ZXh0IHVzaW5nIHRoZSBzcGVjaWZpZWQgY29sbGF0b3IKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IoIGNvbnN0IFVuaWNvZGVTdHJpbmcmIHNvdXJjZVRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogb3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIAo6IHRleHQoTlVMTCksCiAgYnVmZmVyQWxpYXMoTlVMTCksCiAgb3duQnVmZmVyKG5ldyBWZWN0b3JPZkludCgyKSksCiAgcmVvcmRlckJ1ZmZlcigwKSwKICBleHBJbmRleCgwKSwgCiAgb3JkZXJBbGlhcyhvcmRlcikKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICggc291cmNlVGV4dC5sZW5ndGgoKSAhPSAwICkgewogICAgICAgIC8vCiAgICAgICAgLy8gQSBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3IgaXMgcmVhbGx5IGEgdHdvLWxheWVyZWQgYmVhc3QuCiAgICAgICAgLy8gSW50ZXJuYWxseSBpdCB1c2VzIGEgTm9ybWFsaXplciB0byBtdW5nZSB0aGUgc291cmNlIHRleHQKICAgICAgICAvLyBpbnRvIGEgZm9ybSB3aGVyZSBhbGwgImNvbXBvc2VkIiBVbmljb2RlIGNoYXJhY3RlcnMgKHN1Y2ggYXMg/CkgYXJlCiAgICAgICAgLy8gc3BsaXQgaW50byBhIG5vcm1hbCBjaGFyYWN0ZXIgYW5kIGEgY29tYmluaW5nIGFjY2VudCBjaGFyYWN0ZXIuICAKICAgICAgICAvLyBBZnRlcndhcmQsIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBkb2VzIGl0cyBvd24gcHJvY2Vzc2luZyB0byBoYW5kbGUKICAgICAgICAvLyBleHBhbmRpbmcgYW5kIGNvbnRyYWN0aW5nIGNvbGxhdGlvbiBzZXF1ZW5jZXMsIGlnbm9yYWJsZXMsIGFuZCBzbyBvbi4KICAgICAgICAvLwogICAgICBOb3JtYWxpemVyOjpFTW9kZSBkZWNvbXAgPSAob3JkZXItPmdldFN0cmVuZ3RoKCkgPT0gQ29sbGF0b3I6OklERU5USUNBTCkKICAgID8gTm9ybWFsaXplcjo6Tk9fT1AKICAgIDogb3JkZXItPmdldERlY29tcG9zaXRpb24oKTsKICAgICAgCiAgICAgIHRleHQgPSBuZXcgTm9ybWFsaXplcihzb3VyY2VUZXh0LCBkZWNvbXApOwogICAgICBpZiAodGV4dCA9PSBOVUxMKSB7CiAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICB9CiAgICB9Cn0KCgovLyBUaGlzIGlzIHRoZSAicmVhbCIgY29uc3RydWN0b3IgZm9yIHRoaXMgY2xhc3M7IGl0IGNvbnN0cnVjdHMgYW4gaXRlcmF0b3IKLy8gb3ZlciB0aGUgc291cmNlIHRleHQgdXNpbmcgdGhlIHNwZWNpZmllZCBjb2xsYXRvcgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciggY29uc3QgQ2hhcmFjdGVySXRlcmF0b3ImIHNvdXJjZVRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSdWxlQmFzZWRDb2xsYXRvciogb3JkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlJiBzdGF0dXMpIAo6IHRleHQoTlVMTCksCiAgYnVmZmVyQWxpYXMoTlVMTCksCiAgb3duQnVmZmVyKG5ldyBWZWN0b3JPZkludCgyKSksCiAgcmVvcmRlckJ1ZmZlcigwKSwKICBleHBJbmRleCgwKSwgCiAgb3JkZXJBbGlhcyhvcmRlcikKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKSB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vICoqKiogc2hvdWxkIEkganVzdCBkcm9wIHRoaXMgdGVzdD8gKioqKgogICAgaWYgKCBzb3VyY2VUZXh0LmVuZEluZGV4KCkgIT0gMCApCiAgICB7CiAgICAgICAgLy8KICAgICAgICAvLyBBIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciBpcyByZWFsbHkgYSB0d28tbGF5ZXJlZCBiZWFzdC4KICAgICAgICAvLyBJbnRlcm5hbGx5IGl0IHVzZXMgYSBOb3JtYWxpemVyIHRvIG11bmdlIHRoZSBzb3VyY2UgdGV4dAogICAgICAgIC8vIGludG8gYSBmb3JtIHdoZXJlIGFsbCAiY29tcG9zZWQiIFVuaWNvZGUgY2hhcmFjdGVycyAoc3VjaCBhcyD8KSBhcmUKICAgICAgICAvLyBzcGxpdCBpbnRvIGEgbm9ybWFsIGNoYXJhY3RlciBhbmQgYSBjb21iaW5pbmcgYWNjZW50IGNoYXJhY3Rlci4gIAogICAgICAgIC8vIEFmdGVyd2FyZCwgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yIGRvZXMgaXRzIG93biBwcm9jZXNzaW5nIHRvIGhhbmRsZQogICAgICAgIC8vIGV4cGFuZGluZyBhbmQgY29udHJhY3RpbmcgY29sbGF0aW9uIHNlcXVlbmNlcywgaWdub3JhYmxlcywgYW5kIHNvIG9uLgogICAgICAgIC8vCiAgICAgIE5vcm1hbGl6ZXI6OkVNb2RlIGRlY29tcCA9IG9yZGVyLT5nZXRTdHJlbmd0aCgpID09IENvbGxhdG9yOjpJREVOVElDQUwKICAgICAgICA/IE5vcm1hbGl6ZXI6Ok5PX09QCiAgICAgICAgOiBvcmRlci0+Z2V0RGVjb21wb3NpdGlvbigpOwogICAgICAKICAgICAgdGV4dCA9IG5ldyBOb3JtYWxpemVyKHNvdXJjZVRleHQsIGRlY29tcCk7CiAgICAgIGlmICh0ZXh0ID09IE5VTEwpIHsKICAgICAgICBzdGF0dXMgPSBVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SOwogICAgICB9CiAgICB9Cn0KCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Q29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yKGNvbnN0ICAgIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvciYgb3RoZXIpCiAgICA6IG93bkJ1ZmZlcihuZXcgVmVjdG9yT2ZJbnQoMikpLAogICAgICByZW9yZGVyQnVmZmVyKDApLAogICAgICBleHBJbmRleChvdGhlci5leHBJbmRleCksIHRleHQoMCkKewogICAgKnRoaXMgPSBvdGhlcjsKfQoKY29uc3QgICBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6b3BlcmF0b3I9KGNvbnN0ICAgQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yJiBvdGhlcikKewogICAgaWYgKHRoaXMgIT0gJm90aGVyKQogICAgewogICAgICAgIGV4cEluZGV4ID0gb3RoZXIuZXhwSW5kZXg7CgogICAgICAgIGRlbGV0ZSB0ZXh0OwogICAgICAgIHRleHQgPSAoTm9ybWFsaXplciopb3RoZXIudGV4dC0+Y2xvbmUoKTsKCiAgICAgICAgaWYgKG90aGVyLmJ1ZmZlckFsaWFzID09IG90aGVyLm93bkJ1ZmZlcikgewogICAgICAgICAgICAqb3duQnVmZmVyID0gKm90aGVyLm93bkJ1ZmZlcjsKICAgICAgICAgICAgYnVmZmVyQWxpYXMgPSBvd25CdWZmZXI7CiAgICAgICAgfSBlbHNlIGlmIChvdGhlci5idWZmZXJBbGlhcyAhPSBOVUxMICYmCiAgICAgICAgICAgICAgICAgICBvdGhlci5idWZmZXJBbGlhcyA9PSBvdGhlci5yZW9yZGVyQnVmZmVyKSB7CiAgICAgICAgICAgIGlmIChyZW9yZGVyQnVmZmVyID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHJlb3JkZXJCdWZmZXIgPSBuZXcgVmVjdG9yT2ZJbnQoKm90aGVyLnJlb3JkZXJCdWZmZXIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgKnJlb3JkZXJCdWZmZXIgPSAqb3RoZXIucmVvcmRlckJ1ZmZlcjsKICAgICAgICAgICAgfQogICAgICAgICAgICBidWZmZXJBbGlhcyA9IHJlb3JkZXJCdWZmZXI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYnVmZmVyQWxpYXMgPSBvdGhlci5idWZmZXJBbGlhczsKICAgICAgICB9CiAgICAgICAgb3JkZXJBbGlhcyA9IG90aGVyLm9yZGVyQWxpYXM7CiAgICB9CgogICAgcmV0dXJuICp0aGlzOwp9CgpDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6On5Db2xsYXRpb25FbGVtZW50SXRlcmF0b3IoKQp7CiAgICBkZWxldGUgdGV4dDsKICAgIHRleHQgPSBOVUxMOwogICAgYnVmZmVyQWxpYXMgPSBOVUxMOwogICAgb3JkZXJBbGlhcyA9IE5VTEw7CiAgICBkZWxldGUgb3duQnVmZmVyOwogICAgZGVsZXRlIHJlb3JkZXJCdWZmZXI7Cn0KClVCb29sCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6b3BlcmF0b3I9PShjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIHRoYXQpIGNvbnN0CnsKICAgIGlmICh0aGlzID09ICZ0aGF0KQogICAgewogICAgICAgIHJldHVybiBUUlVFOwogICAgfQoKICAgIGlmICgqdGV4dCAhPSAqKHRoYXQudGV4dCkpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICgoKGJ1ZmZlckFsaWFzID09IE5VTEwpICE9ICh0aGF0LmJ1ZmZlckFsaWFzID09IE5VTEwpKSB8fAogICAgICAgIChidWZmZXJBbGlhcyAhPSBOVUxMICYmICpidWZmZXJBbGlhcyAhPSAqKHRoYXQuYnVmZmVyQWxpYXMpKSkKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKGV4cEluZGV4ICE9IHRoYXQuZXhwSW5kZXgpCiAgICB7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChvcmRlckFsaWFzICE9IHRoYXQub3JkZXJBbGlhcykKICAgIHsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KClVCb29sCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6b3BlcmF0b3IhPShjb25zdCBDb2xsYXRpb25FbGVtZW50SXRlcmF0b3ImIG90aGVyKSBjb25zdAp7CiAgICByZXR1cm4gISgqdGhpcyA9PSBvdGhlcik7Cn0KCi8qKgogKiBSZXNldHMgdGhlIGN1cnNvciB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdHJpbmcuCiAqLwp2b2lkIApDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnJlc2V0KCkKewogIGlmICh0ZXh0ICE9IE5VTEwpCiAgICB7CiAgICAgIHRleHQtPnJlc2V0KCk7CiAgICAgIHRleHQtPnNldE1vZGUob3JkZXJBbGlhcy0+Z2V0RGVjb21wb3NpdGlvbigpKTsKICAgIH0KCiAgYnVmZmVyQWxpYXMgPSBOVUxMOwogIGV4cEluZGV4ID0gMDsKfQoKLy8gU2V0cyB0aGUgc291cmNlIHRvIHRoZSBuZXcgc291cmNlIHN0cmluZy4Kdm9pZApDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnNldFRleHQoY29uc3QgVW5pY29kZVN0cmluZyYgIHNvdXJjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmICAgICAgc3RhdHVzKQp7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGJ1ZmZlckFsaWFzID0gMDsKCiAgICBpZiAodGV4dCA9PSBOVUxMKQogICAgewogICAgICAgIHRleHQgPSBuZXcgTm9ybWFsaXplcihzb3VyY2UsIG9yZGVyQWxpYXMtPmdldERlY29tcG9zaXRpb24oKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgdGV4dC0+c2V0VGV4dChzb3VyY2UsIHN0YXR1cyk7CiAgICAgICAgdGV4dC0+c2V0TW9kZShvcmRlckFsaWFzLT5nZXREZWNvbXBvc2l0aW9uKCkpOwogICAgfQp9CgovLyBTZXRzIHRoZSBzb3VyY2UgdG8gdGhlIG5ldyBjaGFyYWN0ZXIgaXRlcmF0b3IuCnZvaWQKQ29sbGF0aW9uRWxlbWVudEl0ZXJhdG9yOjpzZXRUZXh0KENoYXJhY3Rlckl0ZXJhdG9yJiAgc291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSYgICAgICBzdGF0dXMpCnsKICAgIGlmIChVX0ZBSUxVUkUoc3RhdHVzKSkgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBidWZmZXJBbGlhcyA9IDA7CgogICAgaWYgKHRleHQgPT0gTlVMTCkgewogICAgICAgIHRleHQgPSBuZXcgTm9ybWFsaXplcihzb3VyY2UsIG9yZGVyQWxpYXMtPmdldERlY29tcG9zaXRpb24oKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgdGV4dC0+c2V0TW9kZShvcmRlckFsaWFzLT5nZXREZWNvbXBvc2l0aW9uKCkpOwogICAgICAgIHRleHQtPnNldFRleHQoc291cmNlLCBzdGF0dXMpOwogICAgfQp9CgovKioKICogR2V0IHRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgbmV4dCBjaGFyYWN0ZXIgaW4gdGhlIHN0cmluZy4KICogQHJldHVybiB0aGUgbmV4dCBjaGFyYWN0ZXIncyBvcmRlcmluZy4gIFJldHVybnMgTlVMTE9SREVSIGlmCiAqIHRoZSBlbmQgb2Ygc3RyaW5nIGlzIHJlYWNoZWQuCiAqLwppbnQzMl90CkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bmV4dChVRXJyb3JDb2RlJiBzdGF0dXMpCnsKICAgIGlmICh0ZXh0ID09IE5VTEwgfHwgVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIE5VTExPUkRFUjsKICAgIH0KCiAgICAvLyBVcGRhdGUgdGhlIGRlY29tcG9zaXRpb24gbW9kZSBpZiBuZWNlc3NhcnkuCiAgICB0ZXh0LT5zZXRNb2RlKG9yZGVyQWxpYXMtPmdldERlY29tcG9zaXRpb24oKSk7CiAgICAKICAgIGlmIChidWZmZXJBbGlhcyAhPSBOVUxMKQogICAgewogICAgICAgIC8vIGJ1ZmZlckFsaWFzIG5lZWRzIGEgYml0IG9mIGFuIGV4cGxhbmF0aW9uLgogICAgICAgIC8vIFdoZW4gd2UgaGl0IGFuIGV4cGFuZGluZyBjaGFyYWN0ZXIgaW4gdGhlIHRleHQsIHdlIGNhbGwgdGhlIG9yZGVyJ3MKICAgICAgICAvLyBnZXRFeHBhbmRWYWx1ZXMgbWV0aG9kIHRvIHJldHJpZXZlIGFuIGFycmF5IG9mIHRoZSBvcmRlcmluZ3MgZm9yIGFsbAogICAgICAgIC8vIG9mIHRoZSBjaGFyYWN0ZXJzIGluIHRoZSBleHBhbnNpb24gKHNlZSB0aGUgZW5kIG9mIHRoaXMgbWV0aG9kKS4KICAgICAgICAvLyBUaGUgZmlyc3Qgb3JkZXJpbmcgaXMgcmV0dXJuZWQsIGFuZCBhbiBhbGlhcyB0byB0aGUgb3JkZXJpbmdzIGFycmF5CiAgICAgICAgLy8gaXMgc2F2ZWQgc28gdGhhdCB0aGUgcmVtYWluaW5nIG9yZGVyaW5ncyBjYW4gYmUgcmV0dXJuZWQgb24gc3Vic2VxdWVudAogICAgICAgIC8vIGNhbGxzIHRvIG5leHQuICBTbywgaWYgdGhlIGV4cGFuZGluZyBidWZmZXIgaXMgbm90IGV4aGF1c3RlZCwgCiAgICAgICAgLy8gYWxsIHdlIGhhdmUgdG8gZG8gaGVyZSBpcyByZXR1cm4gdGhlIG5leHQgb3JkZXJpbmcgaW4gdGhlIGJ1ZmZlci4gIAogICAgICAgIGlmIChleHBJbmRleCA8IGJ1ZmZlckFsaWFzLT5zaXplKCkpCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gc3RyZW5ndGhPcmRlcihidWZmZXJBbGlhcy0+YXQoZXhwSW5kZXgrKykpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBidWZmZXJBbGlhcyA9IE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIC8vIEdldHMgdGhlIG5leHQgY2hhcmFjdGVyIGZyb20gdGhlIHN0cmluZyB1c2luZyBkZWNvbXBvc2l0aW9uIGl0ZXJhdG9yLgogICAgVUNoYXIzMiBjaCA9IHRleHQtPmN1cnJlbnQoKTsKICAgIHRleHQtPm5leHQoKTsKCiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICB7CiAgICAgICAgcmV0dXJuIE5VTExPUkRFUjsKICAgIH0KCiAgICBpZiAoY2ggPT0gTm9ybWFsaXplcjo6RE9ORSkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTE9SREVSOwogICAgfQogICAgCiAgICAvLyBBc2sgdGhlIGNvbGxhdG9yIGZvciB0aGlzIGNoYXJhY3RlcidzIG9yZGVyaW5nLgogICAgLyogVXNlZCB0byBiZSBSdWxlQmFzZWRDb2xsYXRvci5nZXRVbmljb2RlT3JkZXIoKS4gIEl0IAogICAgICAgY2FuJ3QgYmUgaW5saW5lZCBpbiB0Ymxjb2xsLmggZmlsZSB1bmZvcnR1bmF0ZWx5LiAqLwogICAgaW50MzJfdCB2YWx1ZSA9IHVjbXAzMl9nZXQob3JkZXJBbGlhcy0+ZGF0YS0+bWFwcGluZywgY2gpOwoKICAgIGlmICh2YWx1ZSA9PSBSdWxlQmFzZWRDb2xsYXRvcjo6VU5NQVBQRUQpCiAgICB7CiAgICAgICAgLy8gUmV0dXJuZWQgYW4gInVubWFwcGVkIiBmbGFnIGFuZCBzYXZlIHRoZSBjaGFyYWN0ZXIgc28gaXQgY2FuIGJlIAogICAgICAgIC8vIHJldHVybmVkIG5leHQgdGltZSB0aGlzIG1ldGhvZCBpcyBjYWxsZWQuCiAgICAgICAgaWYgKGNoID09IDB4MDAwMCkgcmV0dXJuIGNoOwogICAgICAgIC8vIFx1MDAwMCBpcyBub3QgdmFsaWQgaW4gQysrJ3MgVW5pY29kZVN0cmluZwogICAgICAgIG93bkJ1ZmZlci0+YXQoMCkgPSBVTk1BUFBFRENIQVJWQUxVRTsKICAgICAgICBvd25CdWZmZXItPmF0KDEpID0gY2ggPDwgMTY7CiAgICAgICAgYnVmZmVyQWxpYXMgPSBvd25CdWZmZXI7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBpZiAodmFsdWUgPj0gUnVsZUJhc2VkQ29sbGF0b3I6OkNPTlRSQUNUQ0hBUklOREVYKSB7CiAgICAgICAgICAgIHZhbHVlID0gbmV4dENvbnRyYWN0Q2hhcihjaCwgc3RhdHVzKTsKICAgICAgICB9CiAgICAgICAgaWYgKHZhbHVlID49IFJ1bGVCYXNlZENvbGxhdG9yOjpFWFBBTkRDSEFSSU5ERVgpIHsKICAgICAgICAgICAgYnVmZmVyQWxpYXMgPSBvcmRlckFsaWFzLT5nZXRFeHBhbmRWYWx1ZUxpc3QodmFsdWUpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoaXNUaGFpUHJlVm93ZWwoY2gpKSB7CiAgICAgICAgICAgIFVDaGFyMzIgY29uc29uYW50ID0gdGV4dC0+Y3VycmVudCgpOwogICAgICAgICAgICB0ZXh0LT5uZXh0KCk7CiAgICAgICAgICAgIGlmIChpc1RoYWlCYXNlQ29uc29uYW50KGNvbnNvbmFudCkpIHsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgYnVmZmVyQWxpYXMgPSBtYWtlUmVvcmRlcmVkQnVmZmVyKChVQ2hhciljb25zb25hbnQsIHZhbHVlLCBidWZmZXJBbGlhcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFLCBzdGF0dXMpOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICB0ZXh0LT5wcmV2aW91cygpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChidWZmZXJBbGlhcyAhPSBOVUxMKSB7CiAgICAgICAgZXhwSW5kZXggPSAxOwogICAgICAgIHZhbHVlID0gYnVmZmVyQWxpYXMtPmF0KDApOwogICAgfQoKICAgIHJldHVybiBzdHJlbmd0aE9yZGVyKHZhbHVlKTsKfQoKIC8qKgogICogR2V0IHRoZSBvcmRlcmluZyBwcmlvcml0eSBvZiB0aGUgcHJldmlvdXMgY29sbGF0aW9uIGVsZW1lbnQgaW4gdGhlIHN0cmluZy4KICAqIEBwYXJhbSBzdGF0dXMgdGhlIGVycm9yIGNvZGUgc3RhdHVzLgogICogQHJldHVybiB0aGUgcHJldmlvdXMgZWxlbWVudCdzIG9yZGVyaW5nLiAgUmV0dXJucyBOVUxMT1JERVIgaWYKICAqIHRoZSBiZWdpbm5pbmcgb2Ygc3RyaW5nIGlzIHJlYWNoZWQuCiAgKi8KaW50MzJfdApDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnByZXZpb3VzKFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgaWYgKHRleHQgPT0gTlVMTCB8fCBVX0ZBSUxVUkUoc3RhdHVzKSkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTE9SREVSOwogICAgfQoKICAgIHRleHQtPnNldE1vZGUob3JkZXJBbGlhcy0+Z2V0RGVjb21wb3NpdGlvbigpKTsKCiAgICBpZiAoYnVmZmVyQWxpYXMgIT0gTlVMTCkKICAgIHsKICAgICAgICBpZiAoZXhwSW5kZXggPiAwKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIHN0cmVuZ3RoT3JkZXIoYnVmZmVyQWxpYXMtPmF0KC0tZXhwSW5kZXgpKTsKICAgICAgICB9CgogICAgICAgIGJ1ZmZlckFsaWFzID0gTlVMTDsKICAgIH0KCiAgICBVQ2hhcjMyIGNoID0gdGV4dC0+cHJldmlvdXMoKTsKCiAgICBpZiAoY2ggPT0gTm9ybWFsaXplcjo6RE9ORSkKICAgIHsKICAgICAgICByZXR1cm4gTlVMTE9SREVSOwogICAgfQogICAgLyogVXNlZCB0byBiZSBSdWxlQmFzZWRDb2xsYXRvci5nZXRVbmljb2RlT3JkZXIoKS4gIEl0IAogICAgICAgY2FuJ3QgYmUgaW5saW5lZCBpbiB0Ymxjb2xsLmggZmlsZSB1bmZvcnR1bmF0ZWx5LiAqLwogICAgaW50MzJfdCB2YWx1ZSA9IHVjbXAzMl9nZXQob3JkZXJBbGlhcy0+ZGF0YS0+bWFwcGluZywgY2gpOwoKICAgIGlmICh2YWx1ZSA9PSBSdWxlQmFzZWRDb2xsYXRvcjo6VU5NQVBQRUQpCiAgICB7CiAgICAgICAgaWYgKGNoID09IDB4MDAwMCkgcmV0dXJuIGNoOwogICAgICAgIG93bkJ1ZmZlci0+YXQoMCkgPSBVTk1BUFBFRENIQVJWQUxVRTsKICAgICAgICBvd25CdWZmZXItPmF0KDEpID0gY2ggPDwgMTY7CiAgICAgICAgYnVmZmVyQWxpYXMgPSBvd25CdWZmZXI7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBpZiAodmFsdWUgPj0gUnVsZUJhc2VkQ29sbGF0b3I6OkNPTlRSQUNUQ0hBUklOREVYKSB7CiAgICAgICAgICAgIHZhbHVlID0gcHJldkNvbnRyYWN0Q2hhcihjaCwgc3RhdHVzKTsKICAgICAgICB9CiAgICAgICAgaWYgKHZhbHVlID49IFJ1bGVCYXNlZENvbGxhdG9yOjpFWFBBTkRDSEFSSU5ERVgpIHsKICAgICAgICAgICAgYnVmZmVyQWxpYXMgPSBvcmRlckFsaWFzLT5nZXRFeHBhbmRWYWx1ZUxpc3QodmFsdWUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGlzVGhhaUJhc2VDb25zb25hbnQoY2gpKSB7CgogICAgICAgICAgICBVQ2hhcjMyIHZvd2VsID0gdGV4dC0+cHJldmlvdXMoKTsKICAgICAgICAgICAgaWYgKGlzVGhhaVByZVZvd2VsKHZvd2VsKSkgewogICAgICAgICAgICAgICAgYnVmZmVyQWxpYXMgPSBtYWtlUmVvcmRlcmVkQnVmZmVyKChVQ2hhcil2b3dlbCwgdmFsdWUsIGJ1ZmZlckFsaWFzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZBTFNFLCBzdGF0dXMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgdGV4dC0+bmV4dCgpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChidWZmZXJBbGlhcyAhPSBOVUxMKSB7CiAgICAgICAgZXhwSW5kZXggPSBidWZmZXJBbGlhcy0+c2l6ZSgpLTE7CiAgICAgICAgdmFsdWUgPSBidWZmZXJBbGlhcy0+YXQoZXhwSW5kZXgpOwogICAgfQoKICAgIHJldHVybiBzdHJlbmd0aE9yZGVyKHZhbHVlKTsKfQoKaW50MzJfdApDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6OnN0cmVuZ3RoT3JkZXIoaW50MzJfdCBvcmRlcikgY29uc3QKewogICAgQ29sbGF0b3I6OkVDb2xsYXRpb25TdHJlbmd0aCBzID0gb3JkZXJBbGlhcy0+Z2V0U3RyZW5ndGgoKTsKICAgIC8vIE1hc2sgb2ZmIHRoZSB1bndhbnRlZCBkaWZmZXJlbmNlcy4KICAgIGlmIChzID09IENvbGxhdG9yOjpQUklNQVJZKQogICAgewogICAgICAgIG9yZGVyICY9IFJ1bGVCYXNlZENvbGxhdG9yOjpQUklNQVJZRElGRkVSRU5DRU9OTFk7CiAgICB9IGVsc2UgaWYgKHMgPT0gQ29sbGF0b3I6OlNFQ09OREFSWSkKICAgIHsKICAgICAgICBvcmRlciAmPSBSdWxlQmFzZWRDb2xsYXRvcjo6U0VDT05EQVJZRElGRkVSRU5DRU9OTFk7CiAgICB9CiAgICByZXR1cm4gb3JkZXI7Cn0KClVUZXh0T2Zmc2V0CkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6Z2V0T2Zmc2V0KCkgY29uc3QKewogICAgLy8gU2luY2UgdGhlIERlY29tcG9zaXRpb25JdGVyYXRvciBpcyBkb2luZyB0aGUgd29yayBvZiBpdGVyYXRpbmcgdGhyb3VnaAogICAgLy8gdGhlIHRleHQgc3RyaW5nLCB3ZSBjYW4ganVzdCBhc2sgaXQgd2hhdCBpdHMgb2Zmc2V0IGlzLgogICAgcmV0dXJuICh0ZXh0ICE9IE5VTEwpID8gdGV4dC0+Z2V0SW5kZXgoKSA6IDA7Cn0KCnZvaWQgCkNvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6c2V0T2Zmc2V0KFVUZXh0T2Zmc2V0IG5ld09mZnNldCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAodGV4dCAhPSBOVUxMKQogICAgewogICAgICAgIHRleHQtPnNldEluZGV4KG5ld09mZnNldCk7CiAgICB9CgogICAgYnVmZmVyQWxpYXMgPSBOVUxMOwp9CgovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBwcml2YXRlcwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKLyoqCiAqIEdldCB0aGUgb3JkZXJpbmcgcHJpb3JpdHkgb2YgdGhlIG5leHQgY29udHJhY3RpbmcgY2hhcmFjdGVyIGluIHRoZQogKiBzdHJpbmcuCiAqIEBwYXJhbSBjaCB0aGUgc3RhcnRpbmcgY2hhcmFjdGVyIG9mIGEgY29udHJhY3RpbmcgY2hhcmFjdGVyIHRva2VuCiAqIEByZXR1cm4gdGhlIG5leHQgY29udHJhY3RpbmcgY2hhcmFjdGVyJ3Mgb3JkZXJpbmcuICBSZXR1cm5zIE5VTExPUkRFUgogKiBpZiB0aGUgZW5kIG9mIHN0cmluZyBpcyByZWFjaGVkLgogKi8KaW50MzJfdApDb2xsYXRpb25FbGVtZW50SXRlcmF0b3I6Om5leHRDb250cmFjdENoYXIoVUNoYXIzMiBjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykKewogICAgLy8gRmlyc3QgZ2V0IHRoZSBvcmRlcmluZyBvZiB0aGlzIHNpbmdsZSBjaGFyYWN0ZXIKICAgIFZlY3Rvck9mUFRvQ29udHJhY3RFbGVtZW50ICpsaXN0ID0gb3JkZXJBbGlhcy0+Z2V0Q29udHJhY3RWYWx1ZXMoKFVDaGFyKWNoKTsKICAgIEVudHJ5UGFpciAqcGFpciA9IChFbnRyeVBhaXIgKilsaXN0LT5hdCgwKTsKICAgIGludDMyX3Qgb3JkZXIgPSBwYWlyLT52YWx1ZTsKCiAgICAvLyBOb3cgaXRlcmF0ZSB0aHJvdWdoIHRoZSBjaGFycyBmb2xsb3dpbmcgaXQgYW5kCiAgICAvLyBsb29rIGZvciB0aGUgbG9uZ2VzdCBtYXRjaAogICAga2V5LnJlbW92ZSgpOwogICAga2V5ICs9IGNoOwoKICAgIHdoaWxlICgoY2ggPSB0ZXh0LT5jdXJyZW50KCkpICE9IE5vcm1hbGl6ZXI6OkRPTkUpCiAgICB7CiAgICAgICAgaWYgKFVfRkFJTFVSRShzdGF0dXMpKQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIE5VTExPUkRFUjsKICAgICAgICB9CgogICAgICAgIGtleSArPSBjaDsKCiAgICAgICAgaW50MzJfdCBuID0gUnVsZUJhc2VkQ29sbGF0b3I6OmdldEVudHJ5KGxpc3QsIGtleSwgVFJVRSk7CgogICAgICAgIGlmIChuID09IFJ1bGVCYXNlZENvbGxhdG9yOjpVTk1BUFBFRCkKICAgICAgICB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICB0ZXh0LT5uZXh0KCk7CgogICAgICAgIHBhaXIgPSAoRW50cnlQYWlyICopbGlzdC0+YXQobik7CiAgICAgICAgb3JkZXIgPSBwYWlyLT52YWx1ZTsKICAgIH0KCiAgICByZXR1cm4gb3JkZXI7Cn0KCi8qKgogKiBHZXQgdGhlIG9yZGVyaW5nIHByaW9yaXR5IG9mIHRoZSBwcmV2aW91cyBjb250cmFjdGluZyBjaGFyYWN0ZXIgaW4gdGhlCiAqIHN0cmluZy4KICogQHBhcmFtIGNoIHRoZSBzdGFydGluZyBjaGFyYWN0ZXIgb2YgYSBjb250cmFjdGluZyBjaGFyYWN0ZXIgdG9rZW4KICogQHJldHVybiB0aGUgbmV4dCBjb250cmFjdGluZyBjaGFyYWN0ZXIncyBvcmRlcmluZy4gIFJldHVybnMgTlVMTE9SREVSCiAqIGlmIHRoZSBlbmQgb2Ygc3RyaW5nIGlzIHJlYWNoZWQuCiAqLwppbnQzMl90IENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6cHJldkNvbnRyYWN0Q2hhcihVQ2hhcjMyIGNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVRXJyb3JDb2RlICZzdGF0dXMpCnsKICAgIC8vIEZpcnN0IGdldCB0aGUgb3JkZXJpbmcgb2YgdGhpcyBzaW5nbGUgY2hhcmFjdGVyCiAgICBWZWN0b3JPZlBUb0NvbnRyYWN0RWxlbWVudCAqbGlzdCA9IG9yZGVyQWxpYXMtPmdldENvbnRyYWN0VmFsdWVzKChVQ2hhciljaCk7CiAgICBFbnRyeVBhaXIgKnBhaXIgPSAoRW50cnlQYWlyICopbGlzdC0+YXQoMCk7CiAgICBpbnQzMl90IG9yZGVyID0gcGFpci0+dmFsdWU7CgogICAgLy8gTm93IGl0ZXJhdGUgdGhyb3VnaCB0aGUgY2hhcnMgZm9sbG93aW5nIGl0IGFuZAogICAgLy8gbG9vayBmb3IgdGhlIGxvbmdlc3QgbWF0Y2gKICAgIGtleS5yZW1vdmUoKTsKICAgIGtleSArPSBjaDsKCiAgICB3aGlsZSAoKGNoID0gdGV4dC0+cHJldmlvdXMoKSkgIT0gTm9ybWFsaXplcjo6RE9ORSkKICAgIHsKICAgICAgICBrZXkgKz0gY2g7CgogICAgICAgIGludDMyX3QgbiA9IFJ1bGVCYXNlZENvbGxhdG9yOjpnZXRFbnRyeShsaXN0LCBrZXksIEZBTFNFKTsKCiAgICAgICAgaWYgKG4gPT0gUnVsZUJhc2VkQ29sbGF0b3I6OlVOTUFQUEVEKQogICAgICAgIHsKICAgICAgICAgICAgY2ggPSB0ZXh0LT5uZXh0KCk7CgogICAgICAgICAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJldHVybiBOVUxMT1JERVI7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgcGFpciA9IChFbnRyeVBhaXIgKilsaXN0LT5hdChuKTsKICAgICAgICBvcmRlciA9IHBhaXItPnZhbHVlOwogICAgfQoKICAgIHJldHVybiBvcmRlcjsKfQoKLyoqCiAqIFRoaXMgbWV0aG9kIHByb2R1Y2VzIGEgYnVmZmVyIHdoaWNoIGNvbnRhaW5zIHRoZSBjb2xsYXRpb24KICogZWxlbWVudHMgZm9yIHRoZSB0d28gY2hhcmFjdGVycywgd2l0aCBjb2xGaXJzdCdzIHZhbHVlcyBwcmVjZWRpbmcKICogYW5vdGhlciBjaGFyYWN0ZXIncy4gIFByZXN1bWFibHksIHRoZSBvdGhlciBjaGFyYWN0ZXIgcHJlY2VkZXMgY29sRmlyc3QKICogaW4gbG9naWNhbAogKiBvcmRlciAob3RoZXJ3aXNlIHlvdSB3b3VsZG4ndCBuZWVkIHRoaXMgbWV0aG9kIHdvdWxkIHlvdT8pLgogKiBUaGUgYXNzdW1wdGlvbiBpcyB0aGF0IHRoZSBvdGhlciBjaGFyJ3MgdmFsdWUocykgaGF2ZSBhbHJlYWR5IGJlZW4KICogY29tcHV0ZWQuICBJZiB0aGlzIGNoYXIgaGFzIGEgc2luZ2xlIGVsZW1lbnQgaXQgaXMgcGFzc2VkIHRvIHRoaXMKICogbWV0aG9kIGFzIGxhc3RWYWx1ZSwgYW5kIGxhc3RFeHBhc2lvbiBpcyBudWxsLiAgSWYgaXQgaGFzIGFuCiAqIGV4cGFzaW9uIGl0IGlzIHBhc3NlZCBpbiBsYXN0RXhwYW5zaW9uLCBhbmQgY29sTGFzdFZhbHVlIGlzIGlnbm9yZWQuCiAqIFRoaXMgbWV0aG9kIG1heSByZXR1cm4gdGhlIG93bkJ1ZmZlciBhcnJheSBhcyBpdHMgdmFsdWUgc28gb3duQnVmZmVyCiAqIGhhZCBiZXR0ZXIgbm90IGJlIGluIHVzZSBhbnl3aGVyZSBlbHNlLgogKi8KVmVjdG9yT2ZJbnQqIENvbGxhdGlvbkVsZW1lbnRJdGVyYXRvcjo6bWFrZVJlb3JkZXJlZEJ1ZmZlcihVQ2hhciBjb2xGaXJzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGxhc3RWYWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBWZWN0b3JPZkludCogbGFzdEV4cGFuc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQm9vbCBmb3J3YXJkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVFcnJvckNvZGUmIHN0YXR1cykgewoKICAgIFZlY3Rvck9mSW50KiByZXN1bHQ7CgogICAgaW50MzJfdCBmaXJzdFZhbHVlID0gdWNtcDMyX2dldChvcmRlckFsaWFzLT5kYXRhLT5tYXBwaW5nLCBjb2xGaXJzdCk7CiAgICBpZiAoZmlyc3RWYWx1ZSA+PSBSdWxlQmFzZWRDb2xsYXRvcjo6Q09OVFJBQ1RDSEFSSU5ERVgpIHsKICAgICAgICBmaXJzdFZhbHVlID0gZm9yd2FyZCA/IG5leHRDb250cmFjdENoYXIoY29sRmlyc3QsIHN0YXR1cykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IHByZXZDb250cmFjdENoYXIoY29sRmlyc3QsIHN0YXR1cyk7CiAgICB9CgogICAgVmVjdG9yT2ZJbnQqIGZpcnN0RXhwYW5zaW9uID0gTlVMTDsKICAgIGlmIChmaXJzdFZhbHVlID49IFJ1bGVCYXNlZENvbGxhdG9yOjpFWFBBTkRDSEFSSU5ERVgpIHsKICAgICAgICBmaXJzdEV4cGFuc2lvbiA9IG9yZGVyQWxpYXMtPmdldEV4cGFuZFZhbHVlTGlzdChmaXJzdFZhbHVlKTsKICAgIH0KCiAgICBpZiAoIWZvcndhcmQpIHsKICAgICAgICBpbnQzMl90IHRlbXAxID0gZmlyc3RWYWx1ZTsKICAgICAgICBmaXJzdFZhbHVlID0gbGFzdFZhbHVlOwogICAgICAgIGxhc3RWYWx1ZSA9IHRlbXAxOwogICAgICAgIFZlY3Rvck9mSW50KiB0ZW1wMiA9IGZpcnN0RXhwYW5zaW9uOwogICAgICAgIGZpcnN0RXhwYW5zaW9uID0gbGFzdEV4cGFuc2lvbjsKICAgICAgICBsYXN0RXhwYW5zaW9uID0gdGVtcDI7CiAgICB9CgogICAgaWYgKGZpcnN0RXhwYW5zaW9uID09IE5VTEwgJiYgbGFzdEV4cGFuc2lvbiA9PSBOVUxMKSB7CiAgICAgICAgb3duQnVmZmVyLT5hdCgwKSA9IGZpcnN0VmFsdWU7CiAgICAgICAgb3duQnVmZmVyLT5hdCgxKSA9IGxhc3RWYWx1ZTsKICAgICAgICByZXN1bHQgPSBvd25CdWZmZXI7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBpbnQzMl90IGZpcnN0TGVuZ3RoID0gZmlyc3RFeHBhbnNpb249PU5VTEw/IDEgOiBmaXJzdEV4cGFuc2lvbi0+c2l6ZSgpOwogICAgICAgIGludDMyX3QgbGFzdExlbmd0aCA9IGxhc3RFeHBhbnNpb249PU5VTEw/IDEgOiBsYXN0RXhwYW5zaW9uLT5zaXplKCk7CiAgICAgICAgaWYgKHJlb3JkZXJCdWZmZXIgPT0gTlVMTCkgewogICAgICAgICAgICByZW9yZGVyQnVmZmVyID0gbmV3IFZlY3Rvck9mSW50KGZpcnN0TGVuZ3RoK2xhc3RMZW5ndGgpOwogICAgICAgIH0KICAgICAgICAvLyByZW9yZGVyZEJ1ZmZlciBnZXRzIHJldXNlZCBmb3IgdGhlIGxpZmUgb2YgdGhpcyBvYmplY3QuCiAgICAgICAgLy8gU2luY2UgaXRzIGludGVybmFsIGJ1ZmZlciBvbmx5IGdyb3dzLCB0aGVyZSBpcyBhIGRhbmdlcgogICAgICAgIC8vIHRoYXQgaXQgd2lsbCBnZXQgcmVhbGx5LCByZWFsbHkgYmlnLCBhbmQgbmV2ZXIgc2hyaW5rLiAgSWYKICAgICAgICAvLyB0aGlzIGlzIGFjdHVhbGx5IGhhcHBlbmluZywgaW5zZXJ0IGNvZGUgaGVyZSB0byBjaGVjayBmb3IKICAgICAgICAvLyB0aGUgY29uZGl0aW9uLiAgU29tZXRoaW5nIGFsb25nIHRoZSBsaW5lcyBvZjoKICAgICAgICAvLyEgZWxzZSBpZiAocmVvcmRlckJ1ZmZlci0+c2l6ZSgpID49IDI1NiAmJgogICAgICAgIC8vISAgICAgICAgICAoZmlyc3RMZW5ndGgrbGFzdExlbmd0aCkgPCAxNikgewogICAgICAgIC8vISAgICAgZGVsZXRlIHJlb3JkZXJCdWZmZXI7CiAgICAgICAgLy8hICAgICByZW9yZGVyQnVmZmVyID0gbmV3IFZlY3Rvck9mSW50KGZpcnN0TGVuZ3RoK2xhc3RMZW5ndGgpOwogICAgICAgIC8vISB9CiAgICAgICAgLy8gVGhlIHNwZWNpZmljIG51bWVyaWMgdmFsdWVzIG5lZWQgdG8gYmUgZGV0ZXJtaW5lZAogICAgICAgIC8vIGVtcGlyaWNhbGx5LiBbYWxpdV0KICAgICAgICByZXN1bHQgPSByZW9yZGVyQnVmZmVyOwoKICAgICAgICBpZiAoZmlyc3RFeHBhbnNpb24gPT0gTlVMTCkgewogICAgICAgICAgICByZXN1bHQtPmF0UHV0KDAsIGZpcnN0VmFsdWUpOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLy8gU3lzdGVtLmFycmF5Y29weShmaXJzdEV4cGFuc2lvbiwgMCwgcmVzdWx0LCAwLCBmaXJzdExlbmd0aCk7CiAgICAgICAgICAgICpyZXN1bHQgPSAqZmlyc3RFeHBhbnNpb247CiAgICAgICAgfQoKICAgICAgICBpZiAobGFzdEV4cGFuc2lvbiA9PSBOVUxMKSB7CiAgICAgICAgICAgIHJlc3VsdC0+YXRQdXQoZmlyc3RMZW5ndGgsIGxhc3RWYWx1ZSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAvLyBTeXN0ZW0uYXJyYXljb3B5KGxhc3RFeHBhbnNpb24sIDAsIHJlc3VsdCwgZmlyc3RMZW5ndGgsIGxhc3RMZW5ndGgpOwogICAgICAgICAgICBmb3IgKGludDMyX3QgaT0wOyBpPGxhc3RMZW5ndGg7ICsraSkgewogICAgICAgICAgICAgICAgcmVzdWx0LT5hdFB1dChmaXJzdExlbmd0aCArIGksIGxhc3RFeHBhbnNpb24tPmF0KGkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXN1bHQtPnNldFNpemUoZmlyc3RMZW5ndGgrbGFzdExlbmd0aCk7CiAgICB9CgogICAgcmV0dXJuIHJlc3VsdDsKfQo=