LyoKICoJUlBDIE1hbmFnZXIKICoKICogQ29weXJpZ2h0IDIwMDEgIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAyICBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDIwMDUgIE1pa2UgSGVhcm4sIFJvYiBTaGVhcm1hbiBmb3IgQ29kZVdlYXZlcnMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbnN2Yy5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAib2xlMi5oIgojaW5jbHVkZSAicnBjLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3dHlwZXMuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgoKI2luY2x1ZGUgImNvbXBvYmpfcHJpdmF0ZS5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7CgpzdGF0aWMgdm9pZCBfX1JQQ19TVFVCIGRpc3BhdGNoX3JwYyhSUENfTUVTU0FHRSAqbXNnKTsKCi8qIHdlIG9ubHkgdXNlIG9uZSBmdW5jdGlvbiB0byBkaXNwYXRjaCBjYWxscyBmb3IgYWxsIG1ldGhvZHMgLSB3ZSB1c2UgdGhlCiAqIFJQQ19JRl9PTEUgZmxhZyB0byB0ZWxsIHRoZSBSUEMgcnVudGltZSB0aGF0IHRoaXMgaXMgdGhlIGNhc2UgKi8Kc3RhdGljIFJQQ19ESVNQQVRDSF9GVU5DVElPTiBycGNfZGlzcGF0Y2hfdGFibGVbMV0gPSB7IGRpc3BhdGNoX3JwYyB9OyAvKiAoUk8pICovCnN0YXRpYyBSUENfRElTUEFUQ0hfVEFCTEUgcnBjX2Rpc3BhdGNoID0geyAxLCBycGNfZGlzcGF0Y2hfdGFibGUgfTsgLyogKFJPKSAqLwoKc3RhdGljIHN0cnVjdCBsaXN0IHJlZ2lzdGVyZWRfaW50ZXJmYWNlcyA9IExJU1RfSU5JVChyZWdpc3RlcmVkX2ludGVyZmFjZXMpOyAvKiAoQ1MgY3NSZWdJZikgKi8Kc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gY3NSZWdJZjsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT05fREVCVUcgY3NSZWdJZl9kZWJ1ZyA9CnsKICAgIDAsIDAsICZjc1JlZ0lmLAogICAgeyAmY3NSZWdJZl9kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0LCAmY3NSZWdJZl9kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAgIDAsIDAsIHsgMCwgKERXT1JEKShfX0ZJTEVfXyAiOiBkY29tIHJlZ2lzdGVyZWQgc2VydmVyIGludGVyZmFjZXMiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGNzUmVnSWYgPSB7ICZjc1JlZ0lmX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKc3RhdGljIFdDSEFSIHdzelBpcGVUcmFuc3BvcnRbXSA9IHsnbicsJ2MnLCdhJywnYycsJ24nLCdfJywnbicsJ3AnLDB9OwoKCnN0cnVjdCByZWdpc3RlcmVkX2lmCnsKICAgIHN0cnVjdCBsaXN0IGVudHJ5OwogICAgRFdPUkQgcmVmczsgLyogcmVmIGNvdW50ICovCiAgICBSUENfU0VSVkVSX0lOVEVSRkFDRSBJZjsgLyogaW50ZXJmYWNlIHJlZ2lzdGVyZWQgd2l0aCB0aGUgUlBDIHJ1bnRpbWUgKi8KfTsKCi8qIGdldCB0aGUgcGlwZSBlbmRwb2ludCBzcGVjaWZpZWQgb2YgdGhlIHNwZWNpZmllZCBhcGFydG1lbnQgKi8Kc3RhdGljIGlubGluZSB2b2lkIGdldF9ycGNfZW5kcG9pbnQoTFBXU1RSIGVuZHBvaW50LCBjb25zdCBPWElEICpveGlkKQp7CiAgICAvKiBGSVhNRTogc2hvdWxkIGdldCBlbmRwb2ludCBmcm9tIHJwY3NzICovCiAgICBzdGF0aWMgY29uc3QgV0NIQVIgd3N6RW5kcG9pbnRGb3JtYXRbXSA9IHsnXFwnLCdwJywnaScsJ3AnLCdlJywnXFwnLCdPJywnTCcsJ0UnLCdfJywnJScsJzAnLCc4JywnbCcsJ3gnLCclJywnMCcsJzgnLCdsJywneCcsMH07CiAgICB3c3ByaW50ZlcoZW5kcG9pbnQsIHdzekVuZHBvaW50Rm9ybWF0LCAoRFdPUkQpKCpveGlkID4+IDMyKSwoRFdPUkQpKm94aWQpOwp9Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBjb25zdCBJUnBjQ2hhbm5lbEJ1ZmZlclZ0YmwgKmxwVnRibDsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgcmVmczsKfSBScGNDaGFubmVsQnVmZmVyOwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgUnBjQ2hhbm5lbEJ1ZmZlciAgICAgICBzdXBlcjsgLyogc3VwZXJjbGFzcyAqLwoKICAgIFJQQ19CSU5ESU5HX0hBTkRMRSAgICAgYmluZDsgLyogaGFuZGxlIHRvIHRoZSByZW1vdGUgc2VydmVyICovCn0gQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcjsKCnN0cnVjdCBkaXNwYXRjaF9wYXJhbXMKewogICAgUlBDT0xFTUVTU0FHRSAgICAgKm1zZzsgLyogbWVzc2FnZSAqLwogICAgSVJwY1N0dWJCdWZmZXIgICAgKnN0dWI7IC8qIHN0dWIgYnVmZmVyLCBpZiBhcHBsaWNhYmxlICovCiAgICBJUnBjQ2hhbm5lbEJ1ZmZlciAqY2hhbjsgLyogc2VydmVyIGNoYW5uZWwgYnVmZmVyLCBpZiBhcHBsaWNhYmxlICovCiAgICBIQU5ETEUgICAgICAgICAgICAgaGFuZGxlOyAvKiBoYW5kbGUgdGhhdCB3aWxsIGJlY29tZSBzaWduYWxlZCB3aGVuIGNhbGwgZmluaXNoZXMgKi8KICAgIFJQQ19TVEFUVVMgICAgICAgICBzdGF0dXM7IC8qIHN0YXR1cyAob3V0KSAqLwp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJwY0NoYW5uZWxCdWZmZXJfUXVlcnlJbnRlcmZhY2UoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpCnsKICAgICpwcHYgPSBOVUxMOwogICAgaWYgKElzRXF1YWxJSUQocmlpZCwmSUlEX0lScGNDaGFubmVsQnVmZmVyKSB8fCBJc0VxdWFsSUlEKHJpaWQsJklJRF9JVW5rbm93bikpCiAgICB7CiAgICAgICAgKnBwdiA9IChMUFZPSUQpaWZhY2U7CiAgICAgICAgSVVua25vd25fQWRkUmVmKGlmYWNlKTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJwY0NoYW5uZWxCdWZmZXJfQWRkUmVmKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSkKewogICAgUnBjQ2hhbm5lbEJ1ZmZlciAqVGhpcyA9IChScGNDaGFubmVsQnVmZmVyICopaWZhY2U7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZnMpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZShMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UpCnsKICAgIFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMgPSAoUnBjQ2hhbm5lbEJ1ZmZlciAqKWlmYWNlOwogICAgVUxPTkcgcmVmOwoKICAgIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWZzKTsKICAgIGlmIChyZWYpCiAgICAgICAgcmV0dXJuIHJlZjsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIENsaWVudFJwY0NoYW5uZWxCdWZmZXJfUmVsZWFzZShMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UpCnsKICAgIENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKlRoaXMgPSAoQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlciAqKWlmYWNlOwogICAgVUxPTkcgcmVmOwoKICAgIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5zdXBlci5yZWZzKTsKICAgIGlmIChyZWYpCiAgICAgICAgcmV0dXJuIHJlZjsKCiAgICBScGNCaW5kaW5nRnJlZSgmVGhpcy0+YmluZCk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlLCBSUENPTEVNRVNTQUdFKiBvbGVtc2csIFJFRklJRCByaWlkKQp7CiAgICBScGNDaGFubmVsQnVmZmVyICpUaGlzID0gKFJwY0NoYW5uZWxCdWZmZXIgKilpZmFjZTsKICAgIFJQQ19NRVNTQUdFICptc2cgPSAoUlBDX01FU1NBR0UgKilvbGVtc2c7CiAgICBSUENfU1RBVFVTIHN0YXR1czsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVzKVxuIiwgVGhpcywgb2xlbXNnLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpKTsKCiAgICBzdGF0dXMgPSBJX1JwY0dldEJ1ZmZlcihtc2cpOwoKICAgIFRSQUNFKCItLSAlbGRcbiIsIHN0YXR1cyk7CgogICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihzdGF0dXMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIoTFBSUENDSEFOTkVMQlVGRkVSIGlmYWNlLCBSUENPTEVNRVNTQUdFKiBvbGVtc2csIFJFRklJRCByaWlkKQp7CiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyICpUaGlzID0gKENsaWVudFJwY0NoYW5uZWxCdWZmZXIgKilpZmFjZTsKICAgIFJQQ19NRVNTQUdFICptc2cgPSAoUlBDX01FU1NBR0UgKilvbGVtc2c7CiAgICBSUENfQ0xJRU5UX0lOVEVSRkFDRSAqY2lmOwogICAgUlBDX1NUQVRVUyBzdGF0dXM7CgogICAgVFJBQ0UoIiglcCktPiglcCwlcylcbiIsIFRoaXMsIG9sZW1zZywgZGVidWdzdHJfZ3VpZChyaWlkKSk7CgogICAgY2lmID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihSUENfQ0xJRU5UX0lOVEVSRkFDRSkpOwogICAgaWYgKCFjaWYpCiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgY2lmLT5MZW5ndGggPSBzaXplb2YoUlBDX0NMSUVOVF9JTlRFUkZBQ0UpOwogICAgLyogUlBDIGludGVyZmFjZSBJRCA9IENPTSBpbnRlcmZhY2UgSUQgKi8KICAgIGNpZi0+SW50ZXJmYWNlSWQuU3ludGF4R1VJRCA9ICpyaWlkOwogICAgLyogQ09NIG9iamVjdHMgYWx3YXlzIGhhdmUgYSB2ZXJzaW9uIG9mIDAuMCAqLwogICAgY2lmLT5JbnRlcmZhY2VJZC5TeW50YXhWZXJzaW9uLk1ham9yVmVyc2lvbiA9IDA7CiAgICBjaWYtPkludGVyZmFjZUlkLlN5bnRheFZlcnNpb24uTWlub3JWZXJzaW9uID0gMDsKICAgIG1zZy0+UnBjSW50ZXJmYWNlSW5mb3JtYXRpb24gPSBjaWY7CiAgICBtc2ctPkhhbmRsZSA9IFRoaXMtPmJpbmQ7CiAgICAKICAgIHN0YXR1cyA9IElfUnBjR2V0QnVmZmVyKG1zZyk7CgogICAgVFJBQ0UoIi0tICVsZFxuIiwgc3RhdHVzKTsKCiAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKHN0YXR1cyk7Cn0KCi8qIHRoaXMgdGhyZWFkIHJ1bnMgYW4gb3V0Z29pbmcgUlBDICovCnN0YXRpYyBEV09SRCBXSU5BUEkgcnBjX3NlbmRyZWNlaXZlX3RocmVhZChMUFZPSUQgcGFyYW0pCnsKICAgIHN0cnVjdCBkaXNwYXRjaF9wYXJhbXMgKmRhdGEgPSAoc3RydWN0IGRpc3BhdGNoX3BhcmFtcyAqKSBwYXJhbTsKICAgIAogICAgLyogRklYTUU6IHRyYXAgYW5kIHJldGhyb3cgUlBDIGV4Y2VwdGlvbnMgaW4gYXBwIHRocmVhZCAqLwogICAgZGF0YS0+c3RhdHVzID0gSV9ScGNTZW5kUmVjZWl2ZSgoUlBDX01FU1NBR0UgKilkYXRhLT5tc2cpOwoKICAgIFRSQUNFKCJjb21wbGV0ZWQgd2l0aCBzdGF0dXMgMHglbHhcbiIsIGRhdGEtPnN0YXR1cyk7CiAgICAKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUnBjQ2hhbm5lbEJ1ZmZlcl9TZW5kUmVjZWl2ZShMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UgKm9sZW1zZywgVUxPTkcgKnBzdGF0dXMpCnsKICAgIEhSRVNVTFQgaHIgPSBTX09LOwogICAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgICBEV09SRCBpbmRleDsKICAgIHN0cnVjdCBkaXNwYXRjaF9wYXJhbXMgKnBhcmFtczsKICAgIERXT1JEIHRpZDsKICAgIAogICAgVFJBQ0UoIiglcCkgaU1ldGhvZD0lbGRcbiIsIG9sZW1zZywgb2xlbXNnLT5pTWV0aG9kKTsKCiAgICBwYXJhbXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpwYXJhbXMpKTsKICAgIGlmICghcGFyYW1zKSByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIAogICAgcGFyYW1zLT5tc2cgPSBvbGVtc2c7CiAgICBwYXJhbXMtPnN0YXR1cyA9IFJQQ19TX09LOwoKICAgIC8qIHdlIHVzZSBhIHNlcGFyYXRlIHRocmVhZCBoZXJlIGJlY2F1c2Ugd2UgbmVlZCB0byBiZSBhYmxlIHRvCiAgICAgKiBwdW1wIHRoZSBtZXNzYWdlIGxvb3AgaW4gdGhlIGFwcGxpY2F0aW9uIHRocmVhZDogaWYgd2UgZG8gbm90LAogICAgICogYW55IHdpbmRvd3MgY3JlYXRlZCBieSB0aGlzIHRocmVhZCB3aWxsIGhhbmcgYW5kIFJQQ3MgdGhhdCB0cnkKICAgICAqIGFuZCByZS1lbnRlciB0aGlzIFNUQSBmcm9tIGFuIGluY29taW5nIHNlcnZlciB0aHJlYWQgd2lsbAogICAgICogZGVhZGxvY2suIEluc3RhbGxTaGllbGQgaXMgYW4gZXhhbXBsZSBvZiB0aGF0LgogICAgICovCiAgICBwYXJhbXMtPmhhbmRsZSA9IENyZWF0ZVRocmVhZChOVUxMLCAwLCBycGNfc2VuZHJlY2VpdmVfdGhyZWFkLCBwYXJhbXMsIDAsICZ0aWQpOwogICAgaWYgKCFwYXJhbXMtPmhhbmRsZSkKICAgIHsKICAgICAgICBFUlIoIkNvdWxkIG5vdCBjcmVhdGUgUnBjU2VuZFJlY2VpdmUgdGhyZWFkLCBlcnJvciAlbHhcbiIsIEdldExhc3RFcnJvcigpKTsKICAgICAgICBociA9IEVfVU5FWFBFQ1RFRDsKICAgIH0KCiAgICBpZiAoaHIgPT0gU19PSykKICAgICAgICBociA9IENvV2FpdEZvck11bHRpcGxlSGFuZGxlcygwLCBJTkZJTklURSwgMSwgJnBhcmFtcy0+aGFuZGxlLCAmaW5kZXgpOwogICAgQ2xvc2VIYW5kbGUocGFyYW1zLT5oYW5kbGUpOwoKICAgIHN0YXR1cyA9IHBhcmFtcy0+c3RhdHVzOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGFyYW1zKTsKICAgIHBhcmFtcyA9IE5VTEw7CgogICAgaWYgKGhyKSByZXR1cm4gaHI7CiAgICAKICAgIGlmIChwc3RhdHVzKSAqcHN0YXR1cyA9IHN0YXR1czsKCiAgICBUUkFDRSgiUlBDIGNhbGwgc3RhdHVzOiAweCVseFxuIiwgc3RhdHVzKTsKICAgIGlmIChzdGF0dXMgPT0gUlBDX1NfT0spCiAgICAgICAgaHIgPSBTX09LOwogICAgZWxzZSBpZiAoc3RhdHVzID09IFJQQ19TX0NBTExfRkFJTEVEKQogICAgICAgIGhyID0gKihIUkVTVUxUICopb2xlbXNnLT5CdWZmZXI7CiAgICBlbHNlCiAgICAgICAgaHIgPSBIUkVTVUxUX0ZST01fV0lOMzIoc3RhdHVzKTsKCiAgICBUUkFDRSgiLS0gMHglMDhseFxuIiwgaHIpOwoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJfRnJlZUJ1ZmZlcihMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIFJQQ09MRU1FU1NBR0UqIG9sZW1zZykKewogICAgUlBDX01FU1NBR0UgKm1zZyA9IChSUENfTUVTU0FHRSAqKW9sZW1zZzsKICAgIFJQQ19TVEFUVVMgc3RhdHVzOwoKICAgIFRSQUNFKCIoJXApXG4iLCBtc2cpOwoKICAgIHN0YXR1cyA9IElfUnBjRnJlZUJ1ZmZlcihtc2cpOwoKICAgIFRSQUNFKCItLSAlbGRcbiIsIHN0YXR1cyk7CgogICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihzdGF0dXMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyKExQUlBDQ0hBTk5FTEJVRkZFUiBpZmFjZSwgUlBDT0xFTUVTU0FHRSogb2xlbXNnKQp7CiAgICBSUENfTUVTU0FHRSAqbXNnID0gKFJQQ19NRVNTQUdFICopb2xlbXNnOwogICAgUlBDX1NUQVRVUyBzdGF0dXM7CgogICAgVFJBQ0UoIiglcClcbiIsIG1zZyk7CgogICAgc3RhdHVzID0gSV9ScGNGcmVlQnVmZmVyKG1zZyk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbik7CiAgICBtc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uID0gTlVMTDsKCiAgICBUUkFDRSgiLS0gJWxkXG4iLCBzdGF0dXMpOwoKICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoc3RhdHVzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJwY0NoYW5uZWxCdWZmZXJfR2V0RGVzdEN0eChMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UsIERXT1JEKiBwZHdEZXN0Q29udGV4dCwgdm9pZCoqIHBwdkRlc3RDb250ZXh0KQp7CiAgICBGSVhNRSgiKCVwLCVwKSwgc3R1YiFcbiIsIHBkd0Rlc3RDb250ZXh0LCBwcHZEZXN0Q29udGV4dCk7CiAgICByZXR1cm4gRV9GQUlMOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUnBjQ2hhbm5lbEJ1ZmZlcl9Jc0Nvbm5lY3RlZChMUFJQQ0NIQU5ORUxCVUZGRVIgaWZhY2UpCnsKICAgIFRSQUNFKCIoKVxuIik7CiAgICAvKiBuYXRpdmUgZG9lcyBub3RoaW5nIHRvbyAqLwogICAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBjb25zdCBJUnBjQ2hhbm5lbEJ1ZmZlclZ0YmwgQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlclZ0YmwgPQp7CiAgICBScGNDaGFubmVsQnVmZmVyX1F1ZXJ5SW50ZXJmYWNlLAogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9BZGRSZWYsCiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyX1JlbGVhc2UsCiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyX0dldEJ1ZmZlciwKICAgIFJwY0NoYW5uZWxCdWZmZXJfU2VuZFJlY2VpdmUsCiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyX0ZyZWVCdWZmZXIsCiAgICBScGNDaGFubmVsQnVmZmVyX0dldERlc3RDdHgsCiAgICBScGNDaGFubmVsQnVmZmVyX0lzQ29ubmVjdGVkCn07CgpzdGF0aWMgY29uc3QgSVJwY0NoYW5uZWxCdWZmZXJWdGJsIFNlcnZlclJwY0NoYW5uZWxCdWZmZXJWdGJsID0KewogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9RdWVyeUludGVyZmFjZSwKICAgIFJwY0NoYW5uZWxCdWZmZXJfQWRkUmVmLAogICAgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9SZWxlYXNlLAogICAgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9HZXRCdWZmZXIsCiAgICBScGNDaGFubmVsQnVmZmVyX1NlbmRSZWNlaXZlLAogICAgU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlcl9GcmVlQnVmZmVyLAogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9HZXREZXN0Q3R4LAogICAgUnBjQ2hhbm5lbEJ1ZmZlcl9Jc0Nvbm5lY3RlZAp9OwoKLyogcmV0dXJucyBhIGNoYW5uZWwgYnVmZmVyIGZvciBwcm94aWVzICovCkhSRVNVTFQgUlBDX0NyZWF0ZUNsaWVudENoYW5uZWwoY29uc3QgT1hJRCAqb3hpZCwgY29uc3QgSVBJRCAqaXBpZCwgSVJwY0NoYW5uZWxCdWZmZXIgKipjaGFuKQp7CiAgICBDbGllbnRScGNDaGFubmVsQnVmZmVyICpUaGlzOwogICAgV0NIQVIgICAgICAgICAgICAgICAgICAgZW5kcG9pbnRbMjAwXTsKICAgIFJQQ19CSU5ESU5HX0hBTkRMRSAgICAgIGJpbmQ7CiAgICBSUENfU1RBVFVTICAgICAgICAgICAgICBzdGF0dXM7CiAgICBMUFdTVFIgICAgICAgICAgICAgICAgICBzdHJpbmdfYmluZGluZzsKCiAgICAvKiBjb25uZWN0IHRvIHRoZSBhcGFydG1lbnQgbGlzdGVuZXIgdGhyZWFkICovCiAgICBnZXRfcnBjX2VuZHBvaW50KGVuZHBvaW50LCBveGlkKTsKCiAgICBUUkFDRSgicHJveHkgcGlwZTogY29ubmVjdGluZyB0byBlbmRwb2ludDogJXNcbiIsIGRlYnVnc3RyX3coZW5kcG9pbnQpKTsKCiAgICBzdGF0dXMgPSBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZVcoCiAgICAgICAgTlVMTCwKICAgICAgICB3c3pQaXBlVHJhbnNwb3J0LAogICAgICAgIE5VTEwsCiAgICAgICAgZW5kcG9pbnQsCiAgICAgICAgTlVMTCwKICAgICAgICAmc3RyaW5nX2JpbmRpbmcpOwogICAgICAgIAogICAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgIHsKICAgICAgICBzdGF0dXMgPSBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdXKHN0cmluZ19iaW5kaW5nLCAmYmluZCk7CgogICAgICAgIGlmIChzdGF0dXMgPT0gUlBDX1NfT0spCiAgICAgICAgewogICAgICAgICAgICBJUElEIGlwaWQyID0gKmlwaWQ7IC8qIHdoeSBjYW4ndCBScGNCaW5kaW5nU2V0T2JqZWN0IHRha2UgYSBjb25zdD8gKi8KICAgICAgICAgICAgc3RhdHVzID0gUnBjQmluZGluZ1NldE9iamVjdChiaW5kLCAmaXBpZDIpOwogICAgICAgICAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICAgICAgICAgICAgUnBjQmluZGluZ0ZyZWUoJmJpbmQpOwogICAgICAgIH0KCiAgICAgICAgUnBjU3RyaW5nRnJlZVcoJnN0cmluZ19iaW5kaW5nKTsKICAgIH0KCiAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgewogICAgICAgIEVSUigiQ291bGRuJ3QgZ2V0IGJpbmRpbmcgZm9yIGVuZHBvaW50ICVzLCBzdGF0dXMgPSAlbGRcbiIsIGRlYnVnc3RyX3coZW5kcG9pbnQpLCBzdGF0dXMpOwogICAgICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoc3RhdHVzKTsKICAgIH0KCiAgICBUaGlzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqVGhpcykpOwogICAgaWYgKCFUaGlzKQogICAgewogICAgICAgIFJwY0JpbmRpbmdGcmVlKCZiaW5kKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICBUaGlzLT5zdXBlci5scFZ0YmwgPSAmQ2xpZW50UnBjQ2hhbm5lbEJ1ZmZlclZ0Ymw7CiAgICBUaGlzLT5zdXBlci5yZWZzID0gMTsKICAgIFRoaXMtPmJpbmQgPSBiaW5kOwoKICAgICpjaGFuID0gKElScGNDaGFubmVsQnVmZmVyKilUaGlzOwoKICAgIHJldHVybiBTX09LOwp9CgpIUkVTVUxUIFJQQ19DcmVhdGVTZXJ2ZXJDaGFubmVsKElScGNDaGFubmVsQnVmZmVyICoqY2hhbikKewogICAgUnBjQ2hhbm5lbEJ1ZmZlciAqVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKlRoaXMpKTsKICAgIGlmICghVGhpcykKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBUaGlzLT5scFZ0YmwgPSAmU2VydmVyUnBjQ2hhbm5lbEJ1ZmZlclZ0Ymw7CiAgICBUaGlzLT5yZWZzID0gMTsKICAgIAogICAgKmNoYW4gPSAoSVJwY0NoYW5uZWxCdWZmZXIqKVRoaXM7CgogICAgcmV0dXJuIFNfT0s7Cn0KCgpIUkVTVUxUIFJQQ19FeGVjdXRlQ2FsbChzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zICpwYXJhbXMpCnsKICAgIEhSRVNVTFQgaHIgPSBJUnBjU3R1YkJ1ZmZlcl9JbnZva2UocGFyYW1zLT5zdHViLCBwYXJhbXMtPm1zZywgcGFyYW1zLT5jaGFuKTsKICAgIElScGNTdHViQnVmZmVyX1JlbGVhc2UocGFyYW1zLT5zdHViKTsKICAgIGlmIChwYXJhbXMtPmhhbmRsZSkgU2V0RXZlbnQocGFyYW1zLT5oYW5kbGUpOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgdm9pZCBfX1JQQ19TVFVCIGRpc3BhdGNoX3JwYyhSUENfTUVTU0FHRSAqbXNnKQp7CiAgICBzdHJ1Y3QgZGlzcGF0Y2hfcGFyYW1zICpwYXJhbXM7CiAgICBJUnBjU3R1YkJ1ZmZlciAgICAgKnN0dWI7CiAgICBBUEFSVE1FTlQgICAgICAgICAgKmFwdDsKICAgIElQSUQgICAgICAgICAgICAgICAgaXBpZDsKCiAgICBScGNCaW5kaW5nSW5xT2JqZWN0KG1zZy0+SGFuZGxlLCAmaXBpZCk7CgogICAgVFJBQ0UoImlwaWQgPSAlcywgaU1ldGhvZCA9ICVkXG4iLCBkZWJ1Z3N0cl9ndWlkKCZpcGlkKSwgbXNnLT5Qcm9jTnVtKTsKCiAgICBwYXJhbXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpwYXJhbXMpKTsKICAgIGlmICghcGFyYW1zKSByZXR1cm4gUnBjUmFpc2VFeGNlcHRpb24oRV9PVVRPRk1FTU9SWSk7CgogICAgc3R1YiA9IGlwaWRfdG9fYXB0X2FuZF9zdHViYnVmZmVyKCZpcGlkLCAmYXB0KTsKICAgIGlmICghYXB0IHx8ICFzdHViKQogICAgewogICAgICAgIGlmIChhcHQpIGFwYXJ0bWVudF9yZWxlYXNlKGFwdCk7CiAgICAgICAgLyogaXBpZF90b19hcHRfYW5kX3N0dWJidWZmZXIgd2lsbCBhbHJlYWR5IGhhdmUgbG9nZ2VkIHRoZSBlcnJvciAqLwogICAgICAgIHJldHVybiBScGNSYWlzZUV4Y2VwdGlvbihSUENfRV9ESVNDT05ORUNURUQpOwogICAgfQoKICAgIHBhcmFtcy0+bXNnID0gKFJQQ09MRU1FU1NBR0UgKiltc2c7CiAgICBwYXJhbXMtPnN0dWIgPSBzdHViOwogICAgcGFyYW1zLT5jaGFuID0gTlVMTDsgLyogRklYTUU6IHBhc3Mgc2VydmVyIGNoYW5uZWwgKi8KICAgIHBhcmFtcy0+c3RhdHVzID0gUlBDX1NfT0s7CgogICAgLyogTm90ZTogdGhpcyBpcyB0aGUgaW1wb3J0YW50IGRpZmZlcmVuY2UgYmV0d2VlbiBTVEFzIGFuZCBNVEFzIC0gd2UKICAgICAqIGFsd2F5cyBleGVjdXRlIFJQQ3MgdG8gU1RBcyBpbiB0aGUgdGhyZWFkIHRoYXQgb3JpZ2luYWxseSBjcmVhdGVkIHRoZQogICAgICogYXBhcnRtZW50IChpLmUuIHRoZSBvbmUgdGhhdCBwdW1wcyBtZXNzYWdlcyB0byB0aGUgd2luZG93KSAqLwogICAgaWYgKGFwdC0+bW9kZWwgJiBDT0lOSVRfQVBBUlRNRU5UVEhSRUFERUQpCiAgICB7CiAgICAgICAgcGFyYW1zLT5oYW5kbGUgPSBDcmVhdGVFdmVudFcoTlVMTCwgRkFMU0UsIEZBTFNFLCBOVUxMKTsKCiAgICAgICAgVFJBQ0UoIkNhbGxpbmcgYXBhcnRtZW50IHRocmVhZCAweCUwOGx4Li4uXG4iLCBhcHQtPnRpZCk7CgogICAgICAgIFBvc3RNZXNzYWdlVyhhcHQtPndpbiwgRE1fRVhFQ1VURVJQQywgMCwgKExQQVJBTSlwYXJhbXMpOwogICAgICAgIFdhaXRGb3JTaW5nbGVPYmplY3QocGFyYW1zLT5oYW5kbGUsIElORklOSVRFKTsKICAgICAgICBDbG9zZUhhbmRsZShwYXJhbXMtPmhhbmRsZSk7CiAgICB9CiAgICBlbHNlCiAgICAgICAgUlBDX0V4ZWN1dGVDYWxsKHBhcmFtcyk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGFyYW1zKTsKCiAgICBhcGFydG1lbnRfcmVsZWFzZShhcHQpOwp9CgovKiBzdHViIHJlZ2lzdHJhdGlvbiAqLwpIUkVTVUxUIFJQQ19SZWdpc3RlckludGVyZmFjZShSRUZJSUQgcmlpZCkKewogICAgc3RydWN0IHJlZ2lzdGVyZWRfaWYgKnJpZjsKICAgIEJPT0wgZm91bmQgPSBGQUxTRTsKICAgIEhSRVNVTFQgaHIgPSBTX09LOwogICAgCiAgICBUUkFDRSgiKCVzKVxuIiwgZGVidWdzdHJfZ3VpZChyaWlkKSk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmNzUmVnSWYpOwogICAgTElTVF9GT1JfRUFDSF9FTlRSWShyaWYsICZyZWdpc3RlcmVkX2ludGVyZmFjZXMsIHN0cnVjdCByZWdpc3RlcmVkX2lmLCBlbnRyeSkKICAgIHsKICAgICAgICBpZiAoSXNFcXVhbEdVSUQoJnJpZi0+SWYuSW50ZXJmYWNlSWQuU3ludGF4R1VJRCwgcmlpZCkpCiAgICAgICAgewogICAgICAgICAgICByaWYtPnJlZnMrKzsKICAgICAgICAgICAgZm91bmQgPSBUUlVFOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICBpZiAoIWZvdW5kKQogICAgewogICAgICAgIFRSQUNFKCJDcmVhdGluZyBuZXcgaW50ZXJmYWNlXG4iKTsKCiAgICAgICAgcmlmID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZigqcmlmKSk7CiAgICAgICAgaWYgKHJpZikKICAgICAgICB7CiAgICAgICAgICAgIFJQQ19TVEFUVVMgc3RhdHVzOwoKICAgICAgICAgICAgcmlmLT5yZWZzID0gMTsKICAgICAgICAgICAgcmlmLT5JZi5MZW5ndGggPSBzaXplb2YoUlBDX1NFUlZFUl9JTlRFUkZBQ0UpOwogICAgICAgICAgICAvKiBSUEMgaW50ZXJmYWNlIElEID0gQ09NIGludGVyZmFjZSBJRCAqLwogICAgICAgICAgICByaWYtPklmLkludGVyZmFjZUlkLlN5bnRheEdVSUQgPSAqcmlpZDsKICAgICAgICAgICAgcmlmLT5JZi5EaXNwYXRjaFRhYmxlID0gJnJwY19kaXNwYXRjaDsKICAgICAgICAgICAgLyogYWxsIG90aGVyIGZpZWxkcyBhcmUgMCwgaW5jbHVkaW5nIHRoZSB2ZXJzaW9uIGFzQ09NIG9iamVjdHMKICAgICAgICAgICAgICogYWx3YXlzIGhhdmUgYSB2ZXJzaW9uIG9mIDAuMCAqLwogICAgICAgICAgICBzdGF0dXMgPSBScGNTZXJ2ZXJSZWdpc3RlcklmRXgoCiAgICAgICAgICAgICAgICAoUlBDX0lGX0hBTkRMRSkmcmlmLT5JZiwKICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwsCiAgICAgICAgICAgICAgICBSUENfSUZfT0xFIHwgUlBDX0lGX0FVVE9MSVNURU4sCiAgICAgICAgICAgICAgICBSUENfQ19MSVNURU5fTUFYX0NBTExTX0RFRkFVTFQsCiAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICAgICAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgICAgICAgICAgICAgIGxpc3RfYWRkX3RhaWwoJnJlZ2lzdGVyZWRfaW50ZXJmYWNlcywgJnJpZi0+ZW50cnkpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEVSUigiUnBjU2VydmVyUmVnaXN0ZXJJZkV4IGZhaWxlZCB3aXRoIGVycm9yICVsZFxuIiwgc3RhdHVzKTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHJpZik7CiAgICAgICAgICAgICAgICBociA9IEhSRVNVTFRfRlJPTV9XSU4zMihzdGF0dXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgICAgaHIgPSBFX09VVE9GTUVNT1JZOwogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNzUmVnSWYpOwogICAgcmV0dXJuIGhyOwp9CgovKiBzdHViIHVucmVnaXN0cmF0aW9uICovCnZvaWQgUlBDX1VucmVnaXN0ZXJJbnRlcmZhY2UoUkVGSUlEIHJpaWQpCnsKICAgIHN0cnVjdCByZWdpc3RlcmVkX2lmICpyaWY7CiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY3NSZWdJZik7CiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKHJpZiwgJnJlZ2lzdGVyZWRfaW50ZXJmYWNlcywgc3RydWN0IHJlZ2lzdGVyZWRfaWYsIGVudHJ5KQogICAgewogICAgICAgIGlmIChJc0VxdWFsR1VJRCgmcmlmLT5JZi5JbnRlcmZhY2VJZC5TeW50YXhHVUlELCByaWlkKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmICghLS1yaWYtPnJlZnMpCiAgICAgICAgICAgIHsKI2lmIDAgLyogdGhpcyBpcyBhIHN0dWIgaW4gYnVpbHRpbiBhbmQgc3BhbXMgdGhlIGNvbnNvbGUgd2l0aCBGSVhNRSdzICovCiAgICAgICAgICAgICAgICBJSUQgaWlkID0gKnJpaWQ7IC8qIFJwY1NlcnZlclVucmVnaXN0ZXJJZiBkb2Vzbid0IHRha2UgY29uc3QgSUlEICovCiAgICAgICAgICAgICAgICBScGNTZXJ2ZXJVbnJlZ2lzdGVySWYoKFJQQ19JRl9IQU5ETEUpJnJpZi0+SWYsICZpaWQsIDApOwogICAgICAgICAgICAgICAgbGlzdF9yZW1vdmUoJnJpZi0+ZW50cnkpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmlmKTsKI2VuZGlmCiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNzUmVnSWYpOwp9CgovKiBtYWtlIHRoZSBhcGFydG1lbnQgcmVhY2hhYmxlIGJ5IG90aGVyIHRocmVhZHMgYW5kIHByb2Nlc3NlcyBhbmQgY3JlYXRlIHRoZQogKiBJUmVtVW5rbm93biBvYmplY3QgKi8Kdm9pZCBSUENfU3RhcnRSZW1vdGluZyhzdHJ1Y3QgYXBhcnRtZW50ICphcHQpCnsKICAgIGlmICghSW50ZXJsb2NrZWRFeGNoYW5nZSgmYXB0LT5yZW1vdGluZ19zdGFydGVkLCBUUlVFKSkKICAgIHsKICAgICAgICBXQ0hBUiBlbmRwb2ludFsyMDBdOwogICAgICAgIFJQQ19TVEFUVVMgc3RhdHVzOwoKICAgICAgICBnZXRfcnBjX2VuZHBvaW50KGVuZHBvaW50LCAmYXB0LT5veGlkKTsKICAgIAogICAgICAgIHN0YXR1cyA9IFJwY1NlcnZlclVzZVByb3RzZXFFcFcoCiAgICAgICAgICAgIHdzelBpcGVUcmFuc3BvcnQsCiAgICAgICAgICAgIFJQQ19DX1BST1RTRVFfTUFYX1JFUVNfREVGQVVMVCwKICAgICAgICAgICAgZW5kcG9pbnQsCiAgICAgICAgICAgIE5VTEwpOwogICAgICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgICAgICAgICAgIEVSUigiQ291bGRuJ3QgcmVnaXN0ZXIgZW5kcG9pbnQgJXNcbiIsIGRlYnVnc3RyX3coZW5kcG9pbnQpKTsKCiAgICAgICAgLyogRklYTUU6IG1vdmUgcmVtb3RlIHVua25vd24gZXhwb3J0aW5nIGludG8gdGhpcyBmdW5jdGlvbiAqLwogICAgfQogICAgc3RhcnRfYXBhcnRtZW50X3JlbW90ZV91bmtub3duKCk7Cn0KCgpzdGF0aWMgSFJFU1VMVCBjcmVhdGVfc2VydmVyKFJFRkNMU0lEIHJjbHNpZCkKewogICAgc3RhdGljIGNvbnN0IFdDSEFSICBlbWJlZGRpbmdbXSA9IHsgJyAnLCAnLScsJ0UnLCdtJywnYicsJ2UnLCdkJywnZCcsJ2knLCduJywnZycsMCB9OwogICAgSEtFWSAgICAgICAgICAgICAgICBrZXk7CiAgICBjaGFyICAgICAgICAgICAgICAgIGJ1ZlsyMDBdOwogICAgSFJFU1VMVCAgICAgICAgICAgICBocmVzID0gRV9VTkVYUEVDVEVEOwogICAgY2hhciAgICAgICAgICAgICAgICB4Y2xzaWRbODBdOwogICAgV0NIQVIgICAgICAgICAgICAgICBleGVbTUFYX1BBVEgrMV07CiAgICBEV09SRCAgICAgICAgICAgICAgIGV4ZWxlbiA9IHNpemVvZihleGUpOwogICAgV0NIQVIgICAgICAgICAgICAgICBjb21tYW5kW01BWF9QQVRIK3NpemVvZihlbWJlZGRpbmcpL3NpemVvZihXQ0hBUildOwogICAgU1RBUlRVUElORk9XICAgICAgICBzaW5mbzsKICAgIFBST0NFU1NfSU5GT1JNQVRJT04gcGluZm87CgogICAgV0lORV9TdHJpbmdGcm9tQ0xTSUQoKExQQ0xTSUQpcmNsc2lkLHhjbHNpZCk7CgogICAgc3ByaW50ZihidWYsIkNMU0lEXFwlc1xcTG9jYWxTZXJ2ZXIzMiIseGNsc2lkKTsKICAgIGhyZXMgPSBSZWdPcGVuS2V5RXhBKEhLRVlfQ0xBU1NFU19ST09ULCBidWYsIDAsIEtFWV9SRUFELCAma2V5KTsKCiAgICBpZiAoaHJlcyAhPSBFUlJPUl9TVUNDRVNTKSB7CiAgICAgICAgV0FSTigiQ0xTSUQgJXMgbm90IHJlZ2lzdGVyZWQgYXMgTG9jYWxTZXJ2ZXIzMlxuIiwgeGNsc2lkKTsKICAgICAgICByZXR1cm4gUkVHREJfRV9SRUFEUkVHREI7IC8qIFByb2JhYmx5ICovCiAgICB9CgogICAgbWVtc2V0KGV4ZSwwLHNpemVvZihleGUpKTsKICAgIGhyZXM9IFJlZ1F1ZXJ5VmFsdWVFeFcoa2V5LCBOVUxMLCBOVUxMLCBOVUxMLCAoTFBCWVRFKWV4ZSwgJmV4ZWxlbik7CiAgICBSZWdDbG9zZUtleShrZXkpOwogICAgaWYgKGhyZXMpIHsKICAgICAgICBXQVJOKCJObyBkZWZhdWx0IHZhbHVlIGZvciBMb2NhbFNlcnZlcjMyIGtleVxuIik7CiAgICAgICAgcmV0dXJuIFJFR0RCX0VfQ0xBU1NOT1RSRUc7IC8qIEZJWE1FOiBjaGVjayByZXR2YWwgKi8KICAgIH0KCiAgICBtZW1zZXQoJnNpbmZvLDAsc2l6ZW9mKHNpbmZvKSk7CiAgICBzaW5mby5jYiA9IHNpemVvZihzaW5mbyk7CgogICAgLyogRVhFIHNlcnZlcnMgYXJlIHN0YXJ0ZWQgd2l0aCB0aGUgLUVtYmVkZGluZyBzd2l0Y2guIE1TRE4gYWxzbyBjbGFpbXMgL0VtYmVkZGluZyBpcyB1c2VkLAogICAgICogOXggZG9lcyAtRW1iZWRkaW5nLCBwZXJoYXBzIGFuIDl4L05UIGRpZmZlcmVuY2U/CiAgICAgKi8KCiAgICBzdHJjcHlXKGNvbW1hbmQsIGV4ZSk7CiAgICBzdHJjYXRXKGNvbW1hbmQsIGVtYmVkZGluZyk7CgogICAgVFJBQ0UoImFjdGl2YXRpbmcgbG9jYWwgc2VydmVyICclcycgZm9yICVzXG4iLCBkZWJ1Z3N0cl93KGNvbW1hbmQpLCB4Y2xzaWQpOwoKICAgIGlmICghQ3JlYXRlUHJvY2Vzc1coZXhlLCBjb21tYW5kLCBOVUxMLCBOVUxMLCBGQUxTRSwgMCwgTlVMTCwgTlVMTCwgJnNpbmZvLCAmcGluZm8pKSB7CiAgICAgICAgV0FSTigiZmFpbGVkIHRvIHJ1biBsb2NhbCBzZXJ2ZXIgJXNcbiIsIGRlYnVnc3RyX3coZXhlKSk7CiAgICAgICAgcmV0dXJuIEhSRVNVTFRfRlJPTV9XSU4zMihHZXRMYXN0RXJyb3IoKSk7CiAgICB9CiAgICBDbG9zZUhhbmRsZShwaW5mby5oUHJvY2Vzcyk7CiAgICBDbG9zZUhhbmRsZShwaW5mby5oVGhyZWFkKTsKCiAgICByZXR1cm4gU19PSzsKfQoKLyoKICogc3RhcnRfbG9jYWxfc2VydmljZSgpICAtIHN0YXJ0IGEgc2VydmljZSBnaXZlbiBpdHMgbmFtZSBhbmQgcGFyYW1ldGVycwogKi8Kc3RhdGljIERXT1JEIHN0YXJ0X2xvY2FsX3NlcnZpY2UoTFBDV1NUUiBuYW1lLCBEV09SRCBudW0sIExQV1NUUiAqcGFyYW1zKQp7CiAgICBTQ19IQU5ETEUgaGFuZGxlLCBoc3ZjOwogICAgRFdPUkQgICAgIHIgPSBFUlJPUl9GVU5DVElPTl9GQUlMRUQ7CgogICAgVFJBQ0UoIlN0YXJ0aW5nIHNlcnZpY2UgJXMgJWxkIHBhcmFtc1xuIiwgZGVidWdzdHJfdyhuYW1lKSwgbnVtKTsKCiAgICBoYW5kbGUgPSBPcGVuU0NNYW5hZ2VyVyhOVUxMLCBOVUxMLCBTQ19NQU5BR0VSX0FMTF9BQ0NFU1MpOwogICAgaWYgKCFoYW5kbGUpCiAgICAgICAgcmV0dXJuIHI7CiAgICBoc3ZjID0gT3BlblNlcnZpY2VXKGhhbmRsZSwgbmFtZSwgU0NfTUFOQUdFUl9BTExfQUNDRVNTKTsKICAgIGlmIChoc3ZjKQogICAgewogICAgICAgIGlmKFN0YXJ0U2VydmljZVcoaHN2YywgbnVtLCAoTFBDV1NUUiopcGFyYW1zKSkKICAgICAgICAgICAgciA9IEVSUk9SX1NVQ0NFU1M7CiAgICAgICAgZWxzZQogICAgICAgICAgICByID0gR2V0TGFzdEVycm9yKCk7CiAgICAgICAgaWYgKHIgPT0gRVJST1JfU0VSVklDRV9BTFJFQURZX1JVTk5JTkcpCiAgICAgICAgICAgIHIgPSBFUlJPUl9TVUNDRVNTOwogICAgICAgIENsb3NlU2VydmljZUhhbmRsZShoc3ZjKTsKICAgIH0KICAgIENsb3NlU2VydmljZUhhbmRsZShoYW5kbGUpOwoKICAgIFRSQUNFKCJTdGFydFNlcnZpY2UgcmV0dXJuZWQgZXJyb3IgJWxkICglcylcbiIsIHIsIHI/Im9rIjoiZmFpbGVkIik7CgogICAgcmV0dXJuIHI7Cn0KCi8qCiAqIGNyZWF0ZV9sb2NhbF9zZXJ2aWNlKCkgIC0gc3RhcnQgYSBDT00gc2VydmVyIGluIGEgc2VydmljZQogKgogKiAgIFRvIHN0YXJ0IGEgTG9jYWwgU2VydmljZSwgd2UgcmVhZCB0aGUgQXBwSUQgdmFsdWUgdW5kZXIKICogdGhlIGNsYXNzJ3MgQ0xTSUQga2V5LCB0aGVuIG9wZW4gdGhlIEhLQ1JcXEFwcElkIGtleSBzcGVjaWZpZWQKICogdGhlcmUgYW5kIGNoZWNrIGZvciBhIExvY2FsU2VydmljZSB2YWx1ZS4KICoKICogTm90ZTogIExvY2FsIFNlcnZpY2VzIGFyZSBub3Qgc3VwcG9ydGVkIHVuZGVyIFdpbmRvd3MgOXgKICovCnN0YXRpYyBIUkVTVUxUIGNyZWF0ZV9sb2NhbF9zZXJ2aWNlKFJFRkNMU0lEIHJjbHNpZCkKewogICAgSFJFU1VMVCBocmVzID0gUkVHREJfRV9SRUFEUkVHREI7CiAgICBXQ0hBUiBidWZbNDBdLCBrZXluYW1lWzUwXTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzekNsc0lkW10gPSB7ICdDJywnTCcsJ1MnLCdJJywnRCcsJ1xcJywwIH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3pBcHBJZFtdID0geyAnQScsJ3AnLCdwJywnSScsJ2QnLDAgfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzekFwcElkS2V5W10gPSB7ICdBJywncCcsJ3AnLCdJJywnZCcsJ1xcJywwIH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3pMb2NhbFNlcnZpY2VbXSA9IHsgJ0wnLCdvJywnYycsJ2EnLCdsJywnUycsJ2UnLCdyJywndicsJ2knLCdjJywnZScsMCB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6U2VydmljZVBhcmFtc1tdID0geydTJywnZScsJ3InLCd2JywnaScsJ2MnLCdlJywnUCcsJ2EnLCdyJywnYScsJ20nLCdzJywwfTsKICAgIEhLRVkgaGtleTsKICAgIExPTkcgcjsKICAgIERXT1JEIHR5cGUsIHN6OwoKICAgIFRSQUNFKCJBdHRlbXB0aW5nIHRvIHN0YXJ0IExvY2FsIHNlcnZpY2UgZm9yICVzXG4iLCBkZWJ1Z3N0cl9ndWlkKHJjbHNpZCkpOwoKICAgIC8qIHJlYWQgdGhlIEFwcElEIHZhbHVlIHVuZGVyIHRoZSBjbGFzcydzIGtleSAqLwogICAgc3RyY3B5VyhrZXluYW1lLHN6Q2xzSWQpOwogICAgU3RyaW5nRnJvbUdVSUQyKHJjbHNpZCwma2V5bmFtZVs2XSwzOSk7CiAgICByID0gUmVnT3BlbktleUV4VyhIS0VZX0NMQVNTRVNfUk9PVCwga2V5bmFtZSwgMCwgS0VZX1JFQUQsICZoa2V5KTsKICAgIGlmIChyIT1FUlJPUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBocmVzOwogICAgc3ogPSBzaXplb2YgYnVmOwogICAgciA9IFJlZ1F1ZXJ5VmFsdWVFeFcoaGtleSwgc3pBcHBJZCwgTlVMTCwgJnR5cGUsIChMUEJZVEUpYnVmLCAmc3opOwogICAgUmVnQ2xvc2VLZXkoaGtleSk7CiAgICBpZiAociE9RVJST1JfU1VDQ0VTUyB8fCB0eXBlIT1SRUdfU1opCiAgICAgICAgcmV0dXJuIGhyZXM7CgogICAgLyogcmVhZCB0aGUgTG9jYWxTZXJ2aWNlIGFuZCBTZXJ2aWNlUGFyYW1ldGVycyB2YWx1ZXMgZnJvbSB0aGUgQXBwSUQga2V5ICovCiAgICBzdHJjcHlXKGtleW5hbWUsIHN6QXBwSWRLZXkpOwogICAgc3RyY2F0VyhrZXluYW1lLCBidWYpOwogICAgciA9IFJlZ09wZW5LZXlFeFcoSEtFWV9DTEFTU0VTX1JPT1QsIGtleW5hbWUsIDAsIEtFWV9SRUFELCAmaGtleSk7CiAgICBpZiAociE9RVJST1JfU1VDQ0VTUykKICAgICAgICByZXR1cm4gaHJlczsKICAgIHN6ID0gc2l6ZW9mIGJ1ZjsKICAgIHIgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIHN6TG9jYWxTZXJ2aWNlLCBOVUxMLCAmdHlwZSwgKExQQllURSlidWYsICZzeik7CiAgICBpZiAocj09RVJST1JfU1VDQ0VTUyAmJiB0eXBlPT1SRUdfU1opCiAgICB7CiAgICAgICAgRFdPUkQgbnVtX2FyZ3MgPSAwOwogICAgICAgIExQV1NUUiBhcmdzWzFdID0geyBOVUxMIH07CgogICAgICAgIC8qCiAgICAgICAgICogRklYTUU6IEknbSBub3QgcmVhbGx5IHN1cmUgaG93IHRvIGRlYWwgd2l0aCB0aGUgc2VydmljZSBwYXJhbWV0ZXJzLgogICAgICAgICAqICAgICAgICBJIHN1c3BlY3QgdGhhdCB0aGUgc3RyaW5nIHJldHVybmVkIGZyb20gUmVnUXVlcnlWYWx1ZUV4VwogICAgICAgICAqICAgICAgICBzaG91bGQgYmUgc3BsaXQgaW50byBhIG51bWJlciBvZiBhcmd1bWVudHMgYnkgc3BhY2VzLgogICAgICAgICAqICAgICAgICBJdCB3b3VsZCBtYWtlIG1vcmUgc2Vuc2UgaWYgU2VydmljZVBhcmFtcyBjb250YWluZWQgYQogICAgICAgICAqICAgICAgICBSRUdfTVVMVElfU1ogaGVyZSwgYnV0IGl0J3MgYSBSRUdfU1ogZm9yIHRoZSBzZXJ2aWNlcwogICAgICAgICAqICAgICAgICB0aGF0IEknbSBpbnRlcmVzdGVkIGluIGZvciB0aGUgbW9tZW50LgogICAgICAgICAqLwogICAgICAgIHIgPSBSZWdRdWVyeVZhbHVlRXhXKGhrZXksIHN6U2VydmljZVBhcmFtcywgTlVMTCwgJnR5cGUsIE5VTEwsICZzeik7CiAgICAgICAgaWYgKHIgPT0gRVJST1JfU1VDQ0VTUyAmJiB0eXBlID09IFJFR19TWiAmJiBzeikKICAgICAgICB7CiAgICAgICAgICAgIGFyZ3NbMF0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHN6KTsKICAgICAgICAgICAgbnVtX2FyZ3MrKzsKICAgICAgICAgICAgUmVnUXVlcnlWYWx1ZUV4Vyhoa2V5LCBzelNlcnZpY2VQYXJhbXMsIE5VTEwsICZ0eXBlLCAoTFBCWVRFKWFyZ3NbMF0sICZzeik7CiAgICAgICAgfQogICAgICAgIHIgPSBzdGFydF9sb2NhbF9zZXJ2aWNlKGJ1ZiwgbnVtX2FyZ3MsIGFyZ3MpOwogICAgICAgIGlmIChyPT1FUlJPUl9TVUNDRVNTKQogICAgICAgICAgICBocmVzID0gU19PSzsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLDAsYXJnc1swXSk7CiAgICB9CiAgICBSZWdDbG9zZUtleShoa2V5KTsKICAgICAgICAKICAgIHJldHVybiBocmVzOwp9CgojZGVmaW5lIFBJUEVQUkVGICJcXFxcLlxccGlwZVxcIgoKLyogRklYTUU6IHNob3VsZCBjYWxsIHRvIHJwY3NzIGluc3RlYWQgKi8KSFJFU1VMVCBSUENfR2V0TG9jYWxDbGFzc09iamVjdChSRUZDTFNJRCByY2xzaWQsIFJFRklJRCBpaWQsIExQVk9JRCAqcHB2KQp7CiAgICBIUkVTVUxUICAgICAgICBocmVzOwogICAgSEFORExFICAgICAgICAgaFBpcGU7CiAgICBjaGFyICAgICAgICAgICBwaXBlZm5bMjAwXTsKICAgIERXT1JEICAgICAgICAgIHJlcywgYnVmZmVybGVuOwogICAgY2hhciAgICAgICAgICAgbWFyc2hhbGJ1ZmZlclsyMDBdOwogICAgSVN0cmVhbSAgICAgICAqcFN0bTsKICAgIExBUkdFX0lOVEVHRVIgIHNlZWt0bzsKICAgIFVMQVJHRV9JTlRFR0VSIG5ld3BvczsKICAgIGludCAgICAgICAgICAgIHRyaWVzID0gMDsKCiAgICBzdGF0aWMgY29uc3QgaW50IE1BWFRSSUVTID0gMzA7IC8qIDMwIHNlY29uZHMgKi8KCiAgICBUUkFDRSgicmNsc2lkPSVzLCBpaWQ9JXNcbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSwgZGVidWdzdHJfZ3VpZChpaWQpKTsKCiAgICBzdHJjcHkocGlwZWZuLFBJUEVQUkVGKTsKICAgIFdJTkVfU3RyaW5nRnJvbUNMU0lEKHJjbHNpZCxwaXBlZm4rc3RybGVuKFBJUEVQUkVGKSk7CgogICAgd2hpbGUgKHRyaWVzKysgPCBNQVhUUklFUykgewogICAgICAgIFRSQUNFKCJ3YWl0aW5nIGZvciAlc1xuIiwgcGlwZWZuKTsKICAgICAgCiAgICAgICAgV2FpdE5hbWVkUGlwZUEoIHBpcGVmbiwgTk1QV0FJVF9XQUlUX0ZPUkVWRVIgKTsKICAgICAgICBoUGlwZSA9IENyZWF0ZUZpbGVBKHBpcGVmbiwgR0VORVJJQ19SRUFEIHwgR0VORVJJQ19XUklURSwgMCwgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCk7CiAgICAgICAgaWYgKGhQaXBlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSB7CiAgICAgICAgICAgIGlmICh0cmllcyA9PSAxKSB7CiAgICAgICAgICAgICAgICBpZiAoIChocmVzID0gY3JlYXRlX3NlcnZlcihyY2xzaWQpKSAmJgogICAgICAgICAgICAgICAgICAgICAoaHJlcyA9IGNyZWF0ZV9sb2NhbF9zZXJ2aWNlKHJjbHNpZCkpICkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHJlczsKICAgICAgICAgICAgICAgIFNsZWVwKDEwMDApOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgV0FSTigiQ29ubmVjdGluZyB0byAlcywgbm8gcmVzcG9uc2UgeWV0LCByZXRyeWluZzogbGUgaXMgJWx4XG4iLHBpcGVmbixHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgICAgICAgICBTbGVlcCgxMDAwKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgYnVmZmVybGVuID0gMDsKICAgICAgICBpZiAoIVJlYWRGaWxlKGhQaXBlLG1hcnNoYWxidWZmZXIsc2l6ZW9mKG1hcnNoYWxidWZmZXIpLCZidWZmZXJsZW4sTlVMTCkpIHsKICAgICAgICAgICAgRklYTUUoIkZhaWxlZCB0byByZWFkIG1hcnNoYWwgaWQgZnJvbSBjbGFzc2ZhY3Rvcnkgb2YgJXMuXG4iLGRlYnVnc3RyX2d1aWQocmNsc2lkKSk7CiAgICAgICAgICAgIFNsZWVwKDEwMDApOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoInJlYWQgbWFyc2hhbCBpZCBmcm9tIHBpcGVcbiIpOwogICAgICAgIENsb3NlSGFuZGxlKGhQaXBlKTsKICAgICAgICBicmVhazsKICAgIH0KICAgIAogICAgaWYgKHRyaWVzID49IE1BWFRSSUVTKQogICAgICAgIHJldHVybiBFX05PSU5URVJGQUNFOwogICAgCiAgICBocmVzID0gQ3JlYXRlU3RyZWFtT25IR2xvYmFsKDAsVFJVRSwmcFN0bSk7CiAgICBpZiAoaHJlcykgcmV0dXJuIGhyZXM7CiAgICBocmVzID0gSVN0cmVhbV9Xcml0ZShwU3RtLG1hcnNoYWxidWZmZXIsYnVmZmVybGVuLCZyZXMpOwogICAgaWYgKGhyZXMpIGdvdG8gb3V0OwogICAgc2Vla3RvLnUuTG93UGFydCA9IDA7c2Vla3RvLnUuSGlnaFBhcnQgPSAwOwogICAgaHJlcyA9IElTdHJlYW1fU2VlayhwU3RtLHNlZWt0byxTRUVLX1NFVCwmbmV3cG9zKTsKICAgIAogICAgVFJBQ0UoInVubWFyc2hhbGxpbmcgY2xhc3NmYWN0b3J5XG4iKTsKICAgIGhyZXMgPSBDb1VubWFyc2hhbEludGVyZmFjZShwU3RtLCZJSURfSUNsYXNzRmFjdG9yeSxwcHYpOwpvdXQ6CiAgICBJU3RyZWFtX1JlbGVhc2UocFN0bSk7CiAgICByZXR1cm4gaHJlczsKfQoKCnN0cnVjdCBsb2NhbF9zZXJ2ZXJfcGFyYW1zCnsKICAgIENMU0lEIGNsc2lkOwogICAgSVN0cmVhbSAqc3RyZWFtOwp9OwoKLyogRklYTUU6IHNob3VsZCBjYWxsIHRvIHJwY3NzIGluc3RlYWQgKi8Kc3RhdGljIERXT1JEIFdJTkFQSSBsb2NhbF9zZXJ2ZXJfdGhyZWFkKExQVk9JRCBwYXJhbSkKewogICAgc3RydWN0IGxvY2FsX3NlcnZlcl9wYXJhbXMgKiBsc3AgPSAoc3RydWN0IGxvY2FsX3NlcnZlcl9wYXJhbXMgKilwYXJhbTsKICAgIEhBTkRMRQkJaFBpcGU7CiAgICBjaGFyIAkJcGlwZWZuWzIwMF07CiAgICBIUkVTVUxUCQlocmVzOwogICAgSVN0cmVhbQkJKnBTdG0gPSBsc3AtPnN0cmVhbTsKICAgIFNUQVRTVEcJCXN0c3RnOwogICAgdW5zaWduZWQgY2hhcgkqYnVmZmVyOwogICAgaW50IAkJYnVmbGVuOwogICAgTEFSR0VfSU5URUdFUglzZWVrdG87CiAgICBVTEFSR0VfSU5URUdFUgluZXdwb3M7CiAgICBVTE9ORwkJcmVzOwoKICAgIFRSQUNFKCJTdGFydGluZyB0aHJlYWRlciBmb3IgJXMuXG4iLGRlYnVnc3RyX2d1aWQoJmxzcC0+Y2xzaWQpKTsKCiAgICBzdHJjcHkocGlwZWZuLFBJUEVQUkVGKTsKICAgIFdJTkVfU3RyaW5nRnJvbUNMU0lEKCZsc3AtPmNsc2lkLHBpcGVmbitzdHJsZW4oUElQRVBSRUYpKTsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBsc3ApOwoKICAgIGhQaXBlID0gQ3JlYXRlTmFtZWRQaXBlQSggcGlwZWZuLCBQSVBFX0FDQ0VTU19EVVBMRVgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBJUEVfVFlQRV9CWVRFfFBJUEVfV0FJVCwgUElQRV9VTkxJTUlURURfSU5TVEFOQ0VTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICA0MDk2LCA0MDk2LCA1MDAgLyogMC41IHNlY29uZCB0aW1lb3V0ICovLCBOVUxMICk7CiAgICAKICAgIGlmIChoUGlwZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkKICAgIHsKICAgICAgICBGSVhNRSgicGlwZSBjcmVhdGlvbiBmYWlsZWQgZm9yICVzLCBsZSBpcyAlbGRcbiIscGlwZWZuLEdldExhc3RFcnJvcigpKTsKICAgICAgICByZXR1cm4gMTsKICAgIH0KICAgIAogICAgd2hpbGUgKDEpIHsKICAgICAgICBpZiAoIUNvbm5lY3ROYW1lZFBpcGUoaFBpcGUsTlVMTCkpIHsKICAgICAgICAgICAgRVJSKCJGYWlsdXJlIGR1cmluZyBDb25uZWN0TmFtZWRQaXBlICVsZCwgQUJPUlQhXG4iLEdldExhc3RFcnJvcigpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgibWFyc2hhbGxpbmcgSUNsYXNzRmFjdG9yeSB0byBjbGllbnRcbiIpOwogICAgICAgIAogICAgICAgIGhyZXMgPSBJU3RyZWFtX1N0YXQocFN0bSwmc3RzdGcsMCk7CiAgICAgICAgaWYgKGhyZXMpIHJldHVybiBocmVzOwoKICAgICAgICBidWZsZW4gPSBzdHN0Zy5jYlNpemUudS5Mb3dQYXJ0OwogICAgICAgIGJ1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLDAsYnVmbGVuKTsKICAgICAgICBzZWVrdG8udS5Mb3dQYXJ0ID0gMDsKICAgICAgICBzZWVrdG8udS5IaWdoUGFydCA9IDA7CiAgICAgICAgaHJlcyA9IElTdHJlYW1fU2VlayhwU3RtLHNlZWt0byxTRUVLX1NFVCwmbmV3cG9zKTsKICAgICAgICBpZiAoaHJlcykgewogICAgICAgICAgICBGSVhNRSgiSVN0cmVhbV9TZWVrIGZhaWxlZCwgJWx4XG4iLGhyZXMpOwogICAgICAgICAgICByZXR1cm4gaHJlczsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaHJlcyA9IElTdHJlYW1fUmVhZChwU3RtLGJ1ZmZlcixidWZsZW4sJnJlcyk7CiAgICAgICAgaWYgKGhyZXMpIHsKICAgICAgICAgICAgRklYTUUoIlN0cmVhbSBSZWFkIGZhaWxlZCwgJWx4XG4iLGhyZXMpOwogICAgICAgICAgICByZXR1cm4gaHJlczsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgV3JpdGVGaWxlKGhQaXBlLGJ1ZmZlcixidWZsZW4sJnJlcyxOVUxMKTsKICAgICAgICBGbHVzaEZpbGVCdWZmZXJzKGhQaXBlKTsKICAgICAgICBEaXNjb25uZWN0TmFtZWRQaXBlKGhQaXBlKTsKCiAgICAgICAgVFJBQ0UoImRvbmUgbWFyc2hhbGxpbmcgSUNsYXNzRmFjdG9yeVxuIik7CiAgICB9CiAgICBDbG9zZUhhbmRsZShoUGlwZSk7CiAgICBJU3RyZWFtX1JlbGVhc2UocFN0bSk7CiAgICByZXR1cm4gMDsKfQoKdm9pZCBSUENfU3RhcnRMb2NhbFNlcnZlcihSRUZDTFNJRCBjbHNpZCwgSVN0cmVhbSAqc3RyZWFtKQp7CiAgICBEV09SRCB0aWQ7CiAgICBIQU5ETEUgdGhyZWFkOwogICAgc3RydWN0IGxvY2FsX3NlcnZlcl9wYXJhbXMgKmxzcCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKmxzcCkpOwoKICAgIGxzcC0+Y2xzaWQgPSAqY2xzaWQ7CiAgICBsc3AtPnN0cmVhbSA9IHN0cmVhbTsKCiAgICB0aHJlYWQgPSBDcmVhdGVUaHJlYWQoTlVMTCwgMCwgbG9jYWxfc2VydmVyX3RocmVhZCwgbHNwLCAwLCAmdGlkKTsKICAgIENsb3NlSGFuZGxlKHRocmVhZCk7CiAgICAvKiBGSVhNRTogZmFpbHVyZSBoYW5kbGluZyAqLwp9Cg==