Ly89PT0tIFNQSVJWTG93ZXJCb29sLmNwcCCWIExvd2VyIGluc3RydWN0aW9ucyB3aXRoIGJvb2wgb3BlcmFuZHMgLS0tLS0tLS0tLT09PS8vCi8vCi8vICAgICAgICAgICAgICAgICAgICAgVGhlIExMVk0vU1BJUlYgVHJhbnNsYXRvcgovLwovLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgovLwovLyBDb3B5cmlnaHQgKGMpIDIwMTQgQWR2YW5jZWQgTWljcm8gRGV2aWNlcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLwovLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQovLyBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAovLyB0byBkZWFsIHdpdGggdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24KLy8gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsCi8vIGFuZC9vciBzZWxsIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZQovLyBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgovLwovLyBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsCi8vIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXJzLgovLyBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsCi8vIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXJzIGluIHRoZSBkb2N1bWVudGF0aW9uCi8vIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgovLyBOZWl0aGVyIHRoZSBuYW1lcyBvZiBBZHZhbmNlZCBNaWNybyBEZXZpY2VzLCBJbmMuLCBub3IgdGhlIG5hbWVzIG9mIGl0cwovLyBjb250cmlidXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzCi8vIFNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgovLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgovLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKLy8gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCi8vIENPTlRSSUJVVE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgovLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAovLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIFdJVEgKLy8gVEhFIFNPRlRXQVJFLgovLwovLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLwovLwovLyBUaGlzIGZpbGUgaW1wbGVtZW50cyBsb3dlcmluZyBpbnN0cnVjdGlvbnMgd2l0aCBib29sIG9wZXJhbmRzLgovLwovLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLwojZGVmaW5lIERFQlVHX1RZUEUgInNwdmJvb2wiCgojaW5jbHVkZSAiU1BJUlZJbnRlcm5hbC5oIgojaW5jbHVkZSAibGx2bS9JUi9JbnN0VmlzaXRvci5oIgojaW5jbHVkZSAibGx2bS9JUi9JbnN0cnVjdGlvbnMuaCIKI2luY2x1ZGUgImxsdm0vSVIvSVJCdWlsZGVyLmgiCiNpbmNsdWRlICJsbHZtL0lSL1ZlcmlmaWVyLmgiCiNpbmNsdWRlICJsbHZtL1Bhc3MuaCIKI2luY2x1ZGUgImxsdm0vUGFzc1N1cHBvcnQuaCIKI2luY2x1ZGUgImxsdm0vU3VwcG9ydC9Db21tYW5kTGluZS5oIgojaW5jbHVkZSAibGx2bS9TdXBwb3J0L0RlYnVnLmgiCiNpbmNsdWRlICJsbHZtL1N1cHBvcnQvcmF3X29zdHJlYW0uaCIKCnVzaW5nIG5hbWVzcGFjZSBsbHZtOwp1c2luZyBuYW1lc3BhY2UgU1BJUlY7CgpuYW1lc3BhY2UgU1BJUlYgewpjbDo6b3B0PGJvb2w+IFNQSVJWTG93ZXJCb29sVmFsaWRhdGUoInNwdmJvb2wtdmFsaWRhdGUiLAogICAgY2w6OmRlc2MoIlZhbGlkYXRlIG1vZHVsZSBhZnRlciBsb3dlcmluZyBib29sZWFuIGluc3RydWN0aW9ucyBmb3IgU1BJUi1WIikpOwoKY2xhc3MgU1BJUlZMb3dlckJvb2w6IHB1YmxpYyBNb2R1bGVQYXNzLAogIHB1YmxpYyBJbnN0VmlzaXRvcjxTUElSVkxvd2VyQm9vbD4gewpwdWJsaWM6CiAgU1BJUlZMb3dlckJvb2woKTpNb2R1bGVQYXNzKElEKSwgQ29udGV4dChudWxscHRyKSB7CiAgICBpbml0aWFsaXplU1BJUlZMb3dlckJvb2xQYXNzKCpQYXNzUmVnaXN0cnk6OmdldFBhc3NSZWdpc3RyeSgpKTsKICB9CiAgdm9pZCByZXBsYWNlKEluc3RydWN0aW9uICpJLCBJbnN0cnVjdGlvbiAqTmV3SSkgewogICAgTmV3SS0+dGFrZU5hbWUoSSk7CiAgICBJLT5yZXBsYWNlQWxsVXNlc1dpdGgoTmV3SSk7CiAgICBJLT5kcm9wQWxsUmVmZXJlbmNlcygpOwogICAgSS0+ZXJhc2VGcm9tUGFyZW50KCk7CiAgfQogIGJvb2wgaXNCb29sVHlwZShUeXBlICpUeSkgewogICAgaWYgKFR5LT5pc0ludGVnZXJUeSgxKSkKICAgICAgcmV0dXJuIHRydWU7CiAgICBpZiAoYXV0byBWVCA9IGR5bl9jYXN0PFZlY3RvclR5cGU+KFR5KSkKICAgICAgcmV0dXJuIGlzQm9vbFR5cGUoVlQtPmdldEVsZW1lbnRUeXBlKCkpOwogICAgcmV0dXJuIGZhbHNlOwogIH0KICB2aXJ0dWFsIHZvaWQgdmlzaXRUcnVuY0luc3QoVHJ1bmNJbnN0ICZJKSB7CiAgICBpZiAoaXNCb29sVHlwZShJLmdldFR5cGUoKSkpIHsKICAgICAgYXV0byBPcCA9IEkuZ2V0T3BlcmFuZCgwKTsKICAgICAgYXV0byBaZXJvID0gZ2V0U2NhbGFyT3JWZWN0b3JDb25zdGFudEludChPcC0+Z2V0VHlwZSgpLCAwLCBmYWxzZSk7CiAgICAgIGF1dG8gQ21wID0gbmV3IElDbXBJbnN0KCZJLCBDbXBJbnN0OjpJQ01QX05FLCBPcCwgWmVybyk7CiAgICAgIHJlcGxhY2UoJkksIENtcCk7CiAgICB9CiAgfQogIHZpcnR1YWwgdm9pZCB2aXNpdFpFeHRJbnN0KFpFeHRJbnN0ICZJKSB7CiAgICBhdXRvIE9wID0gSS5nZXRPcGVyYW5kKDApOwogICAgaWYgKGlzQm9vbFR5cGUoT3AtPmdldFR5cGUoKSkpIHsKICAgICAgYXV0byBUeSA9IEkuZ2V0VHlwZSgpOwogICAgICBhdXRvIFplcm8gPSBnZXRTY2FsYXJPclZlY3RvckNvbnN0YW50SW50KFR5LCAwLCBmYWxzZSk7CiAgICAgIGF1dG8gT25lID0gZ2V0U2NhbGFyT3JWZWN0b3JDb25zdGFudEludChUeSwgMSwgZmFsc2UpOwogICAgICBhdXRvIFNlbCA9IFNlbGVjdEluc3Q6OkNyZWF0ZShPcCwgT25lLCBaZXJvLCAiIiwgJkkpOwogICAgICByZXBsYWNlKCZJLCBTZWwpOwogICAgfQogIH0KICB2aXJ0dWFsIHZvaWQgdmlzaXRTRXh0SW5zdChTRXh0SW5zdCAmSSkgewogICAgYXV0byBPcCA9IEkuZ2V0T3BlcmFuZCgwKTsKICAgIGlmIChpc0Jvb2xUeXBlKE9wLT5nZXRUeXBlKCkpKSB7CiAgICAgIGF1dG8gVHkgPSBJLmdldFR5cGUoKTsKICAgICAgYXV0byBaZXJvID0gZ2V0U2NhbGFyT3JWZWN0b3JDb25zdGFudEludChUeSwgMCwgZmFsc2UpOwogICAgICBhdXRvIE9uZSA9IGdldFNjYWxhck9yVmVjdG9yQ29uc3RhbnRJbnQoVHksIH4wLCBmYWxzZSk7CiAgICAgIGF1dG8gU2VsID0gU2VsZWN0SW5zdDo6Q3JlYXRlKE9wLCBPbmUsIFplcm8sICIiLCAmSSk7CiAgICAgIHJlcGxhY2UoJkksIFNlbCk7CiAgICB9CiAgfQogIHZpcnR1YWwgYm9vbCBydW5Pbk1vZHVsZShNb2R1bGUgJk0pIHsKICAgIENvbnRleHQgPSAmTS5nZXRDb250ZXh0KCk7CiAgICB2aXNpdChNKTsKCiAgICBpZiAoU1BJUlZMb3dlckJvb2xWYWxpZGF0ZSkgewogICAgICBERUJVRyhkYmdzKCkgPDwgIkFmdGVyIFNQSVJWTG93ZXJCb29sOlxuIiA8PCBNKTsKICAgICAgc3RkOjpzdHJpbmcgRXJyOwogICAgICByYXdfc3RyaW5nX29zdHJlYW0gRXJyb3JPUyhFcnIpOwogICAgICBpZiAodmVyaWZ5TW9kdWxlKE0sICZFcnJvck9TKSl7CiAgICAgICAgRXJyID0gc3RkOjpzdHJpbmcoIkZhaWxzIHRvIHZlcmlmeSBtb2R1bGU6ICIpICsgRXJyOwogICAgICAgIHJlcG9ydF9mYXRhbF9lcnJvcihFcnIuY19zdHIoKSwgZmFsc2UpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKICB9CgogIHN0YXRpYyBjaGFyIElEOwpwcml2YXRlOgogIExMVk1Db250ZXh0ICpDb250ZXh0Owp9OwoKY2hhciBTUElSVkxvd2VyQm9vbDo6SUQgPSAwOwp9CgpJTklUSUFMSVpFX1BBU1MoU1BJUlZMb3dlckJvb2wsICJzcHZib29sIiwKICAgICJMb3dlciBpbnN0cnVjdGlvbnMgd2l0aCBib29sIG9wZXJhbmRzIiwgZmFsc2UsIGZhbHNlKQoKTW9kdWxlUGFzcyAqbGx2bTo6Y3JlYXRlU1BJUlZMb3dlckJvb2woKSB7CiAgcmV0dXJuIG5ldyBTUElSVkxvd2VyQm9vbCgpOwp9Cg==