LyoKICogQ29weXJpZ2h0IDIwMDEsIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4KICogQ29weXJpZ2h0IDIwMDIgR3JlZyBUdXJuZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqCiAqIC0tLS0gcnBjc3NfbWFpbi5jOgogKiAgIEluaXRpYWxpemUgYW5kIHN0YXJ0IHNlcnZpbmcgcmVxdWVzdHMuICBCYWlsIGlmIHJwY3NzIGFscmVhZHkgaXMKICogICBydW5uaW5nLgogKgogKiAtLS0tIFJQQ1NTLkVYRToKICogICAKICogICBXaW5lIG5lZWRzIGEgc2VydmVyIHdob3NlIHJvbGUgaXMgc29tZXdoYXQgbGlrZSB0aGF0CiAqICAgb2YgcnBjc3MuZXhlIGluIHdpbmRvd3MuICBUaGlzIGlzIG5vdCBhIGNsb25lIG9mCiAqICAgd2luZG93cyBycGNzcyBhdCBhbGwuICBJdCBoYXMgYmVlbiBnaXZlbiB0aGUgc2FtZSBuYW1lLCBob3dldmVyLAogKiAgIHRvIHByb3ZpZGUgZm9yIHRoZSBwb3NzaWJpbGl0eSB0aGF0IGF0IHNvbWUgcG9pbnQgaW4gdGhlIGZ1dHVyZSwgCiAqICAgaXQgbWF5IGJlY29tZSBpbnRlcmZhY2UgY29tcGF0aWJsZSB3aXRoIHRoZSAicmVhbCIgcnBjc3MuZXhlIG9uCiAqICAgV2luZG93cy4KICoKICogLS0tLSBLTk9XTiBCVUdTIC8gVE9ETzoKICoKICogICBvIFNlcnZpY2UgaG9va3MgYXJlIHVuaW1wbGVtZW50ZWQgKGlmIHlvdSBib3RoZXIgdG8gaW1wbGVtZW50CiAqICAgICB0aGVzZSwgYWxzbyBpbXBsZW1lbnQgbmV0LmV4ZSwgYXQgbGVhc3QgZm9yICJuZXQgc3RhcnQiIGFuZAogKiAgICAgIm5ldCBzdG9wIiAoc2hvdWxkIGJlIHByZXR0eSBlYXN5IEkgZ3Vlc3MsIGFzc3VtaW5nIHRoZSByZXN0CiAqICAgICBvZiB0aGUgc2VydmljZXMgQVBJIGluZnJhc3RydWN0dXJlIHdvcmtzLgogKgogKiAgIG8gVGhlcmUgaXMgYSBsb29taW5nIHByb2JsZW0gcmVnYXJkaW5nIGxpc3RlbmluZyBvbiBwcml2aWxlZ2VkCiAqICAgICBwb3J0cy4gIFdlIHdpbGwgbmVlZCB0byBiZSBhYmxlIHRvIGNvZXhpc3Qgd2l0aCBTQU1CQSwgYW5kIGJlIGFibGUKICogICAgIHRvIGZ1bmN0aW9uIHdpdGhvdXQgcnVubmluZyB3aW5lbGliIGNvZGUgYXMgcm9vdC4gIFRoaXMgbWF5CiAqICAgICB0YWtlIHNvbWUgZG9pbmcsIGluY2x1ZGluZyBzaWduaWZpY2FudCByZWNvbmNlcHR1YWxpemF0aW9uIG9mIHRoZQogKiAgICAgcm9sZSBvZiBycGNzcy5leGUgaW4gd2luZS4KICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPGxpbWl0cy5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CgojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKI2luY2x1ZGUgInJwY3NzLmgiCiNpbmNsdWRlICJ3aW5udC5oIgojaW5jbHVkZSAiaXJvdC5oIgojaW5jbHVkZSAiZXBtLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwob2xlKTsKCnN0YXRpYyBIQU5ETEUgZXhpdF9ldmVudDsKCmV4dGVybiBIQU5ETEUgX193aW5lX21ha2VfcHJvY2Vzc19zeXN0ZW0odm9pZCk7CgpzdGF0aWMgQk9PTCBSUENTU19Jbml0aWFsaXplKHZvaWQpCnsKICBzdGF0aWMgdW5zaWduZWQgc2hvcnQgaXJvdF9wcm90c2VxW10gPSBJUk9UX1BST1RTRVE7CiAgc3RhdGljIHVuc2lnbmVkIHNob3J0IGlyb3RfZW5kcG9pbnRbXSA9IElST1RfRU5EUE9JTlQ7CiAgc3RhdGljIHVuc2lnbmVkIHNob3J0IGVwbV9wcm90c2VxW10gPSB7J24nLCdjJywnYScsJ2MnLCduJywnXycsJ24nLCdwJywwfTsKICBzdGF0aWMgdW5zaWduZWQgc2hvcnQgZXBtX2VuZHBvaW50W10gPSB7J1xcJywncCcsJ2knLCdwJywnZScsJ1xcJywnZScsJ3AnLCdtJywnYScsJ3AnLCdwJywnZScsJ3InLDB9OwogIHN0YXRpYyB1bnNpZ25lZCBzaG9ydCBlcG1fcHJvdHNlcV9scnBjW10gPSB7J24nLCdjJywnYScsJ2wnLCdyJywncCcsJ2MnLDB9OwogIHN0YXRpYyB1bnNpZ25lZCBzaG9ydCBlcG1fZW5kcG9pbnRfbHJwY1tdID0geydlJywncCcsJ20nLCdhJywncCcsJ3AnLCdlJywncicsMH07CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIFdJTkVfVFJBQ0UoIlxuIik7CgogIHN0YXR1cyA9IFJwY1NlcnZlclJlZ2lzdGVySWYoZXBtX3YzXzBfc19pZnNwZWMsIE5VTEwsIE5VTEwpOwogIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgICByZXR1cm4gc3RhdHVzOwogIHN0YXR1cyA9IFJwY1NlcnZlclJlZ2lzdGVySWYoSXJvdF92MF8yX3NfaWZzcGVjLCBOVUxMLCBOVUxMKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogIHsKICAgIFJwY1NlcnZlclVucmVnaXN0ZXJJZihlcG1fdjNfMF9zX2lmc3BlYywgTlVMTCwgRkFMU0UpOwogICAgcmV0dXJuIEZBTFNFOwogIH0KCiAgc3RhdHVzID0gUnBjU2VydmVyVXNlUHJvdHNlcUVwVyhlcG1fcHJvdHNlcSwgUlBDX0NfUFJPVFNFUV9NQVhfUkVRU19ERUZBVUxULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXBtX2VuZHBvaW50LCBOVUxMKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgZ290byBmYWlsOwoKICBzdGF0dXMgPSBScGNTZXJ2ZXJVc2VQcm90c2VxRXBXKGVwbV9wcm90c2VxX2xycGMsIFJQQ19DX1BST1RTRVFfTUFYX1JFUVNfREVGQVVMVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVwbV9lbmRwb2ludF9scnBjLCBOVUxMKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICBnb3RvIGZhaWw7CgogIHN0YXR1cyA9IFJwY1NlcnZlclVzZVByb3RzZXFFcFcoaXJvdF9wcm90c2VxLCBSUENfQ19QUk9UU0VRX01BWF9SRVFTX0RFRkFVTFQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpcm90X2VuZHBvaW50LCBOVUxMKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgZ290byBmYWlsOwoKICBzdGF0dXMgPSBScGNTZXJ2ZXJMaXN0ZW4oMSwgUlBDX0NfTElTVEVOX01BWF9DQUxMU19ERUZBVUxULCBUUlVFKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgZ290byBmYWlsOwoKICBleGl0X2V2ZW50ID0gX193aW5lX21ha2VfcHJvY2Vzc19zeXN0ZW0oKTsKCiAgcmV0dXJuIFRSVUU7CgpmYWlsOgogIFJwY1NlcnZlclVucmVnaXN0ZXJJZihlcG1fdjNfMF9zX2lmc3BlYywgTlVMTCwgRkFMU0UpOwogIFJwY1NlcnZlclVucmVnaXN0ZXJJZihJcm90X3YwXzJfc19pZnNwZWMsIE5VTEwsIEZBTFNFKTsKICByZXR1cm4gRkFMU0U7Cn0KCi8qIHJldHVybnMgZmFsc2UgaWYgd2UgZGlzY292ZXIgYXQgdGhlIGxhc3QgbW9tZW50IHRoYXQgd2UKICAgYXJlbid0IHJlYWR5IHRvIHRlcm1pbmF0ZSAqLwpzdGF0aWMgQk9PTCBSUENTU19TaHV0ZG93bih2b2lkKQp7CiAgUnBjTWdtdFN0b3BTZXJ2ZXJMaXN0ZW5pbmcoTlVMTCk7CiAgUnBjU2VydmVyVW5yZWdpc3RlcklmKGVwbV92M18wX3NfaWZzcGVjLCBOVUxMLCBUUlVFKTsKICBScGNTZXJ2ZXJVbnJlZ2lzdGVySWYoSXJvdF92MF8yX3NfaWZzcGVjLCBOVUxMLCBUUlVFKTsKCiAgQ2xvc2VIYW5kbGUoZXhpdF9ldmVudCk7CgogIHJldHVybiBUUlVFOwp9CgppbnQgbWFpbiggaW50IGFyZ2MsIGNoYXIgKiphcmd2ICkKewogIC8qIAogICAqIFdlIGFyZSBpbnZva2VkIGFzIGEgc3RhbmRhcmQgZXhlY3V0YWJsZTsgd2UgYWN0IGluIGEKICAgKiAibGF6eSIgbWFubmVyLiAgV2UgcmVnaXN0ZXIgb3VyIGludGVyZmFjZXMgYW5kIGVuZHBvaW50cywgYW5kIGhhbmcgYXJvdW5kCiAgICogdW50aWwgd2UgYWxsIHVzZXIgcHJvY2Vzc2VzIGV4aXQsIGFuZCB0aGVuIHNpbGVudGx5IHRlcm1pbmF0ZS4KICAgKi8KCiAgaWYgKFJQQ1NTX0luaXRpYWxpemUoKSkgewogICAgV2FpdEZvclNpbmdsZU9iamVjdChleGl0X2V2ZW50LCBJTkZJTklURSk7CiAgICBSUENTU19TaHV0ZG93bigpOwogIH0KCiAgcmV0dXJuIDA7Cn0K